diff --git a/alexa/plugin.yaml b/alexa/plugin.yaml new file mode 100755 index 000000000..8da197034 --- /dev/null +++ b/alexa/plugin.yaml @@ -0,0 +1,25 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: web # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Plugin zur Ansteuerung von SmartHomeNG via Amazon Echo / Alexa, **seit SmartHomeNG v1.3**' + en: '' + maintainer: hotzen + tester: psilo909 +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page + support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1021150-amazon-alexa-plugin + + version: 1.3.0.9.0 # Plugin version + sh_minversion: 1.3 # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: False # plugin supports multi instance + classname: Alexa # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/apcups/README.md b/apcups/README.md index 68b1d5dbd..5ca32912b 100644 --- a/apcups/README.md +++ b/apcups/README.md @@ -2,8 +2,16 @@ ## Requirements -A running apcupsd with configured netserver (NIS). The plugin retrieves the information via network from the netserver. No local apcupsd is required. -The apcupsd package must be installed also on the local system (running daemon is not required). The plugin uses the "apcaccess" helper tool from the package. +A running **apcupsd** with configured netserver (NIS). The plugin retrieves the information via network from the netserver. No local apcupsd is required. +The apcupsd package must be installed also on the local system (running daemon is not required). The plugin uses the **apcaccess** helper tool from the package. + +If running the daemon locally and using the netserver, then the ``/etc/apcupsd/apcupsd.conf`` should contain additionally the following entries: + +``` +NETSERVER on +NISPORT 3551 +NISIP 127.0.0.1 +``` ## Supported Hardware @@ -13,7 +21,7 @@ Should work on all APC UPS devices. Tested only on a "smartUPS". ### plugin.conf -Please provide a plugin.yaml snippet for your plugin with ever option your plugin supports. Optional attributes should be commented out. +Add the following lines to activate the plugin: ```yaml ApcUps: @@ -23,9 +31,9 @@ ApcUps: port: 3551 ``` -If you use the old plugin.conf config file format add the following lines to activate the plugin: +or the same for deprecated *.conf file format: -``` +```ini [apcups] class_name = APCUPS class_path = plugins.apcups @@ -42,13 +50,97 @@ Description of the attributes: ### items.conf -There is only one attribute: apcups +There is only one attribute: **apcups** + +For a list of values for this attribute call "apcaccess" on the command line. This command will give back a text block containing a list of ``statusname : value`` entries like the following: -For a list of values for this attribute call "apcaccess" on the command line. The plugin returns strings (status "online") or floats (235 = 235 Volt). +``` +APC : 001,050,1127 +DATE : 2017-11-02 07:59:15 +0100 +HOSTNAME : sh11 +VERSION : 3.14.12 (29 March 2014) debian +UPSNAME : UPS_IDEN +CABLE : Ethernet Link +DRIVER : PCNET UPS Driver +UPSMODE : Stand Alone +STARTTIME: 2017-11-02 07:59:11 +0100 +MODEL : Smart-UPS 1400 RM +STATUS : ONLINE +LINEV : 227.5 Volts +LOADPCT : 31.2 Percent +BCHARGE : 100.0 Percent +TIMELEFT : 30.0 Minutes +MBATTCHG : 10 Percent +MINTIMEL : 5 Minutes +MAXTIME : 0 Seconds +MAXLINEV : 227.5 Volts +MINLINEV : 226.0 Volts +OUTPUTV : 227.5 Volts +SENSE : High +DWAKE : 0 Seconds +DSHUTD : 120 Seconds +DLOWBATT : 2 Minutes +LOTRANS : 208.0 Volts +HITRANS : 253.0 Volts +RETPCT : 0.0 Percent +ITEMP : 25.6 C +ALARMDEL : Low Battery +BATTV : 27.7 Volts +LINEFREQ : 49.8 Hz +LASTXFER : Line voltage notch or spike +NUMXFERS : 0 +TONBATT : 0 Seconds +CUMONBATT: 0 Seconds +XOFFBATT : N/A +SELFTEST : NO +STESTI : 336 +STATFLAG : 0x05000008 +REG1 : 0x00 +REG2 : 0x00 +REG3 : 0x00 +MANDATE : 08/16/00 +SERIALNO : GS0034003173 +BATTDATE : 06/20/15 +NOMOUTV : 230 Volts +NOMBATTV : 24.0 Volts +EXTBATTS : 0 +FIRMWARE : 162.3.I +END APC : 2017-11-02 08:00:39 +0100 +``` + +The plugin will check the items type. If the type is a string, then the value will we returned as a string (e.g. status "ONLINE"). +If it is of type num, then the item will be set to a float. To convert to a float, the returned string will be cut after first space and the converted (e.g. 235 Volt = 235). ### Example +The example below will read the keys **LINEV**, **STATUS** and **TIMELEFT** and returns their values. + +```yaml +# items/apcups.yaml +serverroom: + + apcups: + + linev: + visu_acl: ro + type: num + apcups: linev + + status: + # will be 'ONLINE', 'ONBATT', or in case of a problem simply empty + visu_acl: ro + type: str + apcups: status + + timeleft: + visu_acl: ro + type: num + apcups: timeleft ``` + +or in (deprecated) *.conf format: + +```ini # items/apcups.conf [serverroom] [[apcups]] @@ -58,8 +150,9 @@ For a list of values for this attribute call "apcaccess" on the command line. Th apcups = linev [[[status]]] + # will be 'ONLINE', 'ONBATT', or in case of a problem simply empty visu_acl = ro - type = str + type = str apcups = status [[[timeleft]]] @@ -67,5 +160,134 @@ For a list of values for this attribute call "apcaccess" on the command line. Th type = num apcups = timeleft ``` -"type" depends on the values. +**type** depends on the values. + +### Status Report Fields + +Due to a look into this http://apcupsd.org/manual/manual.html#configuration-examples file the meaning of the above variables are as follows + +``` +APC + Header record indicating the STATUS format revision level, the number of records that follow the APC statement, and the number of bytes that follow the record. +DATE + The date and time that the information was last obtained from the UPS. +HOSTNAME + The name of the machine that collected the UPS data. +UPSNAME + The name of the UPS as stored in the EEPROM or in the UPSNAME directive in the configuration file. +VERSION + The apcupsd release number, build date, and platform. +CABLE + The cable as specified in the configuration file (UPSCABLE). +MODEL + The UPS model as derived from information from the UPS. +UPSMODE + The mode in which apcupsd is operating as specified in the configuration file (UPSMODE) +STARTTIME + The time/date that apcupsd was started. +STATUS + The current status of the UPS (ONLINE, ONBATT, etc.) +LINEV + The current line voltage as returned by the UPS. +LOADPCT + The percentage of load capacity as estimated by the UPS. +BCHARGE + The percentage charge on the batteries. +TIMELEFT + The remaining runtime left on batteries as estimated by the UPS. +MBATTCHG + If the battery charge percentage (BCHARGE) drops below this value, apcupsd will shutdown your system. Value is set in the configuration file (BATTERYLEVEL) +MINTIMEL + apcupsd will shutdown your system if the remaining runtime equals or is below this point. Value is set in the configuration file (MINUTES) +MAXTIME + apcupsd will shutdown your system if the time on batteries exceeds this value. A value of zero disables the feature. Value is set in the configuration file (TIMEOUT) +MAXLINEV + The maximum line voltage since the UPS was started, as reported by the UPS +MINLINEV + The minimum line voltage since the UPS was started, as returned by the UPS +OUTPUTV + The voltage the UPS is supplying to your equipment +SENSE + The sensitivity level of the UPS to line voltage fluctuations. +DWAKE + The amount of time the UPS will wait before restoring power to your equipment after a power off condition when the power is restored. +DSHUTD + The grace delay that the UPS gives after receiving a power down command from apcupsd before it powers off your equipment. +DLOWBATT + The remaining runtime below which the UPS sends the low battery signal. At this point apcupsd will force an immediate emergency shutdown. +LOTRANS + The line voltage below which the UPS will switch to batteries. +HITRANS + The line voltage above which the UPS will switch to batteries. +RETPCT + The percentage charge that the batteries must have after a power off condition before the UPS will restore power to your equipment. +ITEMP + Internal UPS temperature as supplied by the UPS. +ALARMDEL + The delay period for the UPS alarm. +BATTV + Battery voltage as supplied by the UPS. +LINEFREQ + Line frequency in hertz as given by the UPS. +LASTXFER + The reason for the last transfer to batteries. +NUMXFERS + The number of transfers to batteries since apcupsd startup. +XONBATT + Time and date of last transfer to batteries, or N/A. +TONBATT + Time in seconds currently on batteries, or 0. +CUMONBATT + Total (cumulative) time on batteries in seconds since apcupsd startup. +XOFFBATT + Time and date of last transfer from batteries, or N/A. +SELFTEST + The results of the last self test, and may have the following values: + + OK: self test indicates good battery + BT: self test failed due to insufficient battery capacity + NG: self test failed due to overload + NO: No results (i.e. no self test performed in the last 5 minutes) + +STESTI + The interval in hours between automatic self tests. +STATFLAG + Status flag. English version is given by STATUS. +DIPSW + The current dip switch settings on UPSes that have them. +REG1 + The value from the UPS fault register 1. +REG2 + The value from the UPS fault register 2. +REG3 + The value from the UPS fault register 3. +MANDATE + The date the UPS was manufactured. +SERIALNO + The UPS serial number. +BATTDATE + The date that batteries were last replaced. +NOMOUTV + The output voltage that the UPS will attempt to supply when on battery power. +NOMINV + The input voltage that the UPS is configured to expect. +NOMBATTV + The nominal battery voltage. +NOMPOWER + The maximum power in Watts that the UPS is designed to supply. +HUMIDITY + The humidity as measured by the UPS. +AMBTEMP + The ambient temperature as measured by the UPS. +EXTBATTS + The number of external batteries as defined by the user. A correct number here helps the UPS compute the remaining runtime more accurately. +BADBATTS + The number of bad battery packs. +FIRMWARE + The firmware revision number as reported by the UPS. +APCMODEL + The old APC model identification code. +END APC + The time and date that the STATUS record was written. +``` diff --git a/apcups/__init__.py b/apcups/__init__.py old mode 100755 new mode 100644 index be6179a51..46903a7f8 --- a/apcups/__init__.py +++ b/apcups/__init__.py @@ -46,7 +46,7 @@ def stop(self): def parse_item(self, item): if self.has_iattr(item.conf, ITEM_TAG[0]): - apcups_key = (self.get_iattr_value(ITEM_TAG[0])).lower() + apcups_key = (self.get_iattr_value(item.conf, ITEM_TAG[0])).lower() self._items[apcups_key]=item logger.debug("item {0} added with apcupd_key {1}".format(item,apcups_key)) return self.update_item @@ -58,7 +58,10 @@ def update_item(self, item, caller=None, source=None, dest=None): logger.debug("update item: {0}".format(item.id())) def update_status(self): - # go and grab + """ + Start **apcaccess** on a shell, capture the output and parse it. + The items attribut parameter will be matched against the shell output + """ command = '/sbin/apcaccess status {0}:{1}'.format(self._host, self._port) # the command goes here output = subprocess.check_output(command.split(), shell=False) # decode byte string to string diff --git a/apcups/plugin.yaml b/apcups/plugin.yaml new file mode 100755 index 000000000..39edf735e --- /dev/null +++ b/apcups/plugin.yaml @@ -0,0 +1,25 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: interface # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Unterstützung für smartUPS Geräte der Firma APC' + en: '' + maintainer: cmalo + tester: Sandman60 +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page +# support: https://knx-user-forum.de/forum/supportforen/smarthome-py + + version: 1.3.1 # Plugin version + sh_minversion: 1.3 # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: True # plugin supports multi instance + classname: APCUPS # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/artnet/README.md b/artnet/README.md index 869dac899..3f3cbeb99 100644 --- a/artnet/README.md +++ b/artnet/README.md @@ -12,7 +12,7 @@ OLA supports most USB -> DMX Adapters available at the moment. ## Configuration -### plugin.conf +### plugin.conf (deprecated) / .yaml ``` [dmx1] @@ -25,6 +25,17 @@ OLA supports most USB -> DMX Adapters available at the moment. port = 6454 ``` +``` +dmx1: + class_name: ArtNet + class_path: plugins.artnet + artnet_subnet: 0 + artnet_net: 0 + artnet_universe: 0 + ip: 192.168.1.123 + port: 6454 +``` + ### items.conf Not needed yet. diff --git a/artnet/__init__.py b/artnet/__init__.py index 6424b7b39..a7966feee 100755 --- a/artnet/__init__.py +++ b/artnet/__init__.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -# coding=utf-8 -# -# Copyright 2013 KNX-User-Forum e.V. http://knx-user-forum.de/ -# Author mode@gmx.co.uk -# -# This file is part of SmartHomeNG. https://github.com/smarthomeNG// +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab +######################################################################### +# Copyright 2013- mode2k mode@gmx.co.uk +######################################################################### +# This file is part of SmartHomeNG +# https://github.com/smarthomeNG/smarthome +# http://knx-user-forum.de/ # # SmartHomeNG is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,27 +19,32 @@ # # You should have received a copy of the GNU General Public License # along with SmartHomeNG. If not, see . -# +######################################################################### import logging import socket import struct -logger = logging.getLogger('Artnet') +from lib.model.smartplugin import SmartPlugin + + +class ArtNet(SmartPlugin): + ALLOW_MULTIINSTANCE = False + PLUGIN_VERSION = '1.3.0' -class ArtNet(): packet_counter = 1 dmxdata = [0, 0] def __init__(self, smarthome, artnet_net, artnet_subnet, artnet_universe, ip, port): + self.logger = logging.getLogger(__name__) self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.net = int(artnet_net) self.subnet = int(artnet_subnet) self.universe = int(artnet_universe) self.ip = ip self.port = int(port) - logger.debug("Init ArtNet Plugin done") + self.logger.debug("Init ArtNet Plugin done") def run(self): pass @@ -56,7 +62,7 @@ def __call__(self, var1=None, var2=None): def send_single_value(self, adr, value): if adr < 1 or adr > 512: - logger.error("DMX address %s invalid" % adr) + self.logger.error("DMX address %s invalid" % adr) return while len(self.dmxdata) < adr: @@ -66,7 +72,7 @@ def send_single_value(self, adr, value): def send_frame_starting_at(self, adr, values): if adr < 1 or adr > (512 - len(values) + 1): - logger.error("DMX address %s with length %s invalid" % + self.logger.error("DMX address %s with length %s invalid" % (adr, len(values))) return @@ -80,13 +86,13 @@ def send_frame_starting_at(self, adr, values): def send_frame(self, dmxframe): if len(dmxframe) < 2: - logger.error("Send at least 2 channels") + self.logger.error("Send at least 2 channels") return self.dmxdata = dmxframe self.__ArtDMX_broadcast() def __ArtDMX_broadcast(self): -# logger.info("Incomming DMX: %s"%self.dmxdata) +# self.logger.info("Incomming DMX: %s"%self.dmxdata) # New Array data = [] # Fix ID 7byte + 0x00 @@ -119,7 +125,7 @@ def __ArtDMX_broadcast(self): result = result + token # data = "".join(data) # debug -# logger.info("Outgoing Artnet:%s"%(':'.join(x.encode('hex') for x in data))) +# self.logger.info("Outgoing Artnet:%s"%(':'.join(x.encode('hex') for x in data))) # send over ethernet self.s.sendto(result, (self.ip, self.port)) diff --git a/artnet/plugin.yaml b/artnet/plugin.yaml new file mode 100755 index 000000000..a3d06f74c --- /dev/null +++ b/artnet/plugin.yaml @@ -0,0 +1,25 @@ +# Metadata for the classic-plugin +plugin: + # Global plugin attributes + type: gateway # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Ansteuerung der meisten USB DMX Adapter' + en: '' + maintainer: mode2k + tester: ohinckel + keywords: dmx +# documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md # url of documentation (wiki) page + +# Following entries are for Smart-Plugins: +# version: 1.3.3 # Plugin version +# sh_minversion: 1.3 # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) +# multi_instance: False + classname: ArtNet # class containing the plugin + +#parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +#item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/asterisk/plugin.yaml b/asterisk/plugin.yaml new file mode 100755 index 000000000..e861aaeb0 --- /dev/null +++ b/asterisk/plugin.yaml @@ -0,0 +1,25 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: interface # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Ansteuerung einer Asterisk Telefonanlage' + en: '' + maintainer: '? (mknx)' +# tester: # Who tests this plugin? +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page +# support: https://knx-user-forum.de/forum/supportforen/smarthome-py + + version: 1.3.0 # Plugin version + sh_minversion: 1.3 # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: False # plugin supports multi instance + classname: Asterisk # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/avdevice/AVDeviceInit.py b/avdevice/AVDeviceInit.py new file mode 100755 index 000000000..869e8fc3d --- /dev/null +++ b/avdevice/AVDeviceInit.py @@ -0,0 +1,458 @@ +#!/usr/bin/env python3 +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab +######################################################################### +# Copyright 2016 +######################################################################### +# This file is part of SmartHomeNG. +# +# Plugin to control AV Devices via TCP and/or RS232 +# Tested with Pioneer AV Receivers. +# +# SmartHomeNG is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SmartHomeNG is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SmartHomeNG. If not, see . +# +######################################################################### + +import logging + +import codecs +import re +import threading +VERBOSE1 = logging.DEBUG - 1 +VERBOSE2 = logging.DEBUG - 2 +logging.addLevelName(logging.DEBUG - 1, 'VERBOSE1') +logging.addLevelName(logging.DEBUG - 2, 'VERBOSE2') + + +class Init(): + + def __init__(self, smarthome, name, model, items): + self._items = items + self._name = name + self._model = model + self._sh = smarthome + self._ignoreresponse = [] + + self.logger = logging.getLogger(__name__) + self.logger.log(VERBOSE1, "Initializing {}: Started".format(self._name)) + self._threadlock_standard = threading.Lock() + self._lock = threading.Condition(self._threadlock_standard) + + self._functions = {'zone0': {}, 'zone1': {}, 'zone2': {}, 'zone3': {}, 'zone4': {}} + self._query_zonecommands = {'zone0': [], 'zone1': [], 'zone2': [], 'zone3': [], 'zone4': []} + self._query_commands = [] + self._power_commands = [] + self._response_commands = {} + self._number_of_zones = 0 + self._special_commands = {} + + def _addstatusupdate(self): + if 'statusupdate' not in self._items['zone0'].keys(): + self._items['zone0']['statusupdate'] = {'Item': ['self._statusupdate'], 'Value': False} + self.logger.debug("Initializing {}: No statusupdate Item set, creating dummy item.".format(self._name)) + return self._items + + def _process_variables(self, value, vartype): + self.logger.debug("Initializing Serial {}: Converting {} as type {}.".format(self._name, value, vartype)) + if vartype == 'rs232': + try: + rs232 = re.sub('[ ]', '', value[0]) + if rs232 == 'None' or rs232 == '': + rs232 = baud = serial_timeout = None + self.logger.debug("Initializing Serial {}: Serialport is {}.".format(self._name, rs232)) + except Exception as err: + rs232 = baud = serial_timeout = None + self.logger.warning("Initializing Serial {}: Serial Port is {}. Error: {}.".format(self._name, baud, err)) + if rs232 is not None: + try: + baud = int(value[1]) + self.logger.debug("Initializing Serial {}: Baudrate is {}.".format(self._name, baud)) + except Exception as err: + baud = 9600 + self.logger.debug("Initializing Serial {}: Using standard baudrate {} because: {}.".format(self._name, baud, err)) + try: + serial_timeout = float(value[2]) + self.logger.debug("Initializing Serial {}: Timeout is {}.".format(self._name, serial_timeout)) + except Exception as err: + serial_timeout = 0.1 + self.logger.debug("Initializing Serial {}: Using standard timeout {}. Because: {}.".format(self._name, serial_timeout, err)) + return rs232, baud, serial_timeout + elif vartype == 'tcp': + try: + tcp = re.sub('[ ]', '', value[0]) + if tcp == 'None' or tcp == '' or tcp == '0.0.0.0': + tcp = port = tcp_timeout = None + self.logger.debug("Initializing TCP {}: IP is {}.".format(self._name, tcp)) + except Exception as err: + tcp = port = tcp_timeout = None + self.logger.warning("Initializing TCP {}: Problem setting IP: {}.".format(self._name, err)) + if tcp is not None: + try: + port = int(value[1]) + self.logger.debug("Initializing TCP {}: Port is {}.".format(self._name, port)) + except Exception as err: + port = None + self.logger.warning("Initializing TCP {}: Port is {} because: {}.".format(self._name, port, err)) + try: + tcp_timeout = int(value[2]) + self.logger.debug("Initializing TCP {}: Timeoout is {}.".format(self._name, tcp_timeout)) + except Exception as err: + tcp_timeout = 1 + self.logger.warning("Initializing TCP {}: Timeout is set to standard (1) because: {}.".format(self._name, err)) + return tcp, port, tcp_timeout + + elif vartype == 'dependson': + try: + dependson = re.sub('[ ]', '', value[0]) + if dependson == 'None' or dependson == '': + dependson = None + if dependson is None: + dependson_value = None + else: + if re.sub('[ ]', '', str(value[1])).lower() in ['1', 'yes', 'true', 'on']: + dependson_value = True + elif re.sub('[ ]', '', str(value[1])).lower() in ['0', 'no', 'false', 'off']: + dependson_value = False + self.logger.debug("Initializing {}: Dependson Item: {}. Value: {}".format(self._name, dependson, dependson_value)) + except Exception: + if dependson is not None: + dependson_value = True + self.logger.debug("Initializing {}: Dependson Item: {}. No value for item given, assuming True.".format(self._name, dependson)) + else: + dependson_value = None + self.logger.debug("Initializing {}: No Dependson Item.".format(self._name)) + if dependson is not None: + if re.sub('[ ]', '', str(value[2])).lower() in ['1', 'yes', 'true', 'on'] and dependson: + depend0_power0 = True + elif re.sub('[ ]', '', str(value[2])).lower() in ['0', 'no', 'false', 'off'] or not dependson: + depend0_power0 = False + if re.sub('[ ]', '', str(value[3])).lower() in ['1', 'yes', 'true', 'on'] and dependson: + depend0_volume0 = True + elif re.sub('[ ]', '', str(value[3])).lower() in ['0', 'no', 'false', 'off'] or not dependson: + depend0_volume0 = False + self.logger.debug("Initializing {}: Resetting volume after dependson is off: {}. Resetting power: {}.".format(self._name, depend0_volume0, depend0_power0)) + else: + depend0_power0 = depend0_volume0 = None + return dependson, dependson_value, depend0_power0, depend0_volume0 + + elif vartype == 'responsebuffer': + if str(value).lower() in ['1', 'yes', 'true', 'on']: + response_buffer = True + elif str(value).lower() in ['0', 'no', 'false', 'off']: + response_buffer = False + else: + response_buffer = abs(int(value)) * -1 + return response_buffer + + elif vartype == 'resetonerror': + if str(value).lower() in ['1', 'yes', 'true', 'on']: + reset_onerror = True + elif str(value).lower() in ['0', 'no', 'false', 'off']: + reset_onerror = False + return reset_onerror + + elif vartype == 'responses': + ignoreresponse = self._ignoreresponse = re.sub('[ ]', '', value[0]).split(",") + errorresponse = re.sub('[ ]', '', value[1]).split(",") + force_buffer = re.sub('[ ]', '', value[2]).split(",") + ignoredisplay = re.sub('[ ]', '', value[3]).split(",") + self.logger.debug("Initializing {}: Special Settings: Ignoring responses {}.".format(self._name, ignoreresponse)) + self.logger.debug("Initializing {}: Special Settings: Error responses {}.".format(self._name, errorresponse)) + self.logger.debug("Initializing {}: Special Settings: Force buffer {}.".format(self._name, force_buffer)) + self.logger.debug("Initializing {}: Special Settings: Ignore Display {}".format(self._name, ignoredisplay)) + return ignoreresponse, errorresponse, force_buffer, ignoredisplay + + def _create_querycommands(self): + if not self._lock.acquire(timeout=2): + return + try: + self.logger.debug("Initializing {}: Starting to create query commands. Lock is {}".format( + self._name, self._threadlock_standard.locked())) + displaycommand = '' + length = 0 + for zone in range(0, self._number_of_zones + 1): + for command in self._functions['zone{}'.format(zone)]: + try: + querycommand = self._functions['zone{}'.format(zone)][command][3] + valuetype = self._functions['zone{}'.format(zone)][command][8] + responselist = [] + splitresponse = self._functions['zone{}'.format(zone)][command][4].split("|") + for split in splitresponse: + if split.count('*') > 0 or 'R' in self._functions['zone{}'.format(zone)][command][5]: + responselist.append(split.strip()) + responsestring = "|".join(responselist) + responsecommand = re.sub('[*]', '', responsestring) + if not '{},{},{},{}'.format(querycommand, querycommand, responsecommand, valuetype) in self._query_zonecommands['zone{}'.format(zone)] \ + and not responsecommand == '' and not responsecommand == ' ' and not responsecommand == 'none' and not querycommand == '' \ + and not self._functions['zone{}'.format(zone)][command][4] in self._ignoreresponse: + if not re.sub('[*]', '', self._functions['zone{}'.format(zone)][command][4]) in self._special_commands['Display']['Command']: + self._query_zonecommands['zone{}'.format(zone)].append('{},{},{},{}'.format( + querycommand, querycommand, responsecommand, valuetype)) + else: + displaycommand = '{},{},{},{}'.format(querycommand, querycommand, responsecommand, valuetype) + self.logger.debug("Initializing {}: Displaycommand: {}".format(self._name, displaycommand)) + if not '{},{},{},{}'.format(querycommand, querycommand, responsecommand, valuetype) in self._query_commands \ + and not responsecommand == '' and not responsecommand == ' ' and not responsecommand == 'none' \ + and not querycommand == '' and not self._functions['zone{}'.format(zone)][command][4] in self._ignoreresponse: + if not re.sub('[*]', '', self._functions['zone{}'.format(zone)][command][4]) in self._special_commands['Display']['Command']: + self._query_commands.append('{},{},{},{}'.format(querycommand, querycommand, responsecommand, valuetype)) + else: + displaycommand = '{},{},{},{}'.format(querycommand, querycommand, responsecommand, self._functions['zone{}'.format(zone)][command][8]) + self.logger.log(VERBOSE1, "Initializing {}: Displaycommand: {}".format(self._name, displaycommand)) + except Exception as err: + self.logger.error("Initializing {}: Problems adding query commands for command {}. Error: {}".format( + self._name, command, err)) + length += len(self._query_zonecommands['zone{}'.format(zone)]) + if not displaycommand == '': + self._query_commands.append(displaycommand) + length += 1 + except Exception as err: + self.logger.error("Initializing {}: Problems searching for query commands. Error: {}".format(self._name, err)) + finally: + if self._threadlock_standard.locked(): + self._lock.release() + self.logger.info("Initializing {}: Created query commands, including {} entries.".format(self._name, length)) + return self._query_commands, self._query_zonecommands + + def _create_powercommands(self): + if not self._lock.acquire(timeout=2): + return + try: + self.logger.debug("Initializing {}: Starting to create power commands. Lock is {}".format( + self._name, self._threadlock_standard.locked())) + for zone in range(0, self._number_of_zones + 1): + for command in self._functions['zone{}'.format(zone)]: + try: + if command.startswith('power on'): + if '**' in self._functions['zone{}'.format(zone)][command][4]: + value = re.sub('\*\*', 'ON', self._functions['zone{}'.format(zone)][command][4]) + else: + if self._functions['zone{}'.format(zone)][command][6] == 'yes': + value = re.sub('[*]', '0', self._functions['zone{}'.format(zone)][command][4]) + else: + value = re.sub('[*]', '1', self._functions['zone{}'.format(zone)][command][4]) + combined = '{},{},{},{}'.format(self._functions['zone{}'.format(zone)][command][2], self._functions['zone{}'.format(zone)][command][3], value, self._functions['zone{}'.format(zone)][command][8]) + self._power_commands.append(combined) + except Exception as err: + self.logger.warning("Initializing {}: Problems searching power commands for {} in zone {}. Error: {}".format(self._name, command, zone, err)) + except Exception as err: + self.logger.warning("Initializing {}: Problems creating power commands. Error: {}".format(self._name, err)) + finally: + if self._threadlock_standard.locked(): + self._lock.release() + self.logger.info("Initializing {}: Created power commands, including {} entries.".format(self._name, len(self._power_commands))) + + return self._power_commands + + def _create_responsecommands(self): + if not self._lock.acquire(timeout=2): + return + try: + self.logger.debug("Initializing {}: Starting to create response commands. Lock is {}".format( + self._name, self._threadlock_standard.locked())) + for zone in range(0, self._number_of_zones + 1): + for command in self._functions['zone{}'.format(zone)]: + try: + response_to_split = self._functions['zone{}'.format(zone)][command][4].split("|") + for response in response_to_split: + valuelength = response.count('*') + if response.count('*') == 1 and self._functions['zone{}'.format(zone)][command][8].startswith('str'): + valuelength = 30 + + if response.find('*') >= 0: + position = response.index('*') + else: + position = 0 + response = re.sub('[*]', '', response) + commandlength = len(response) + try: + inverse = self._functions['zone{}'.format(zone)][command][6] + except Exception: + inverse = 'no' + try: + expectedtype = self._functions['zone{}'.format(zone)][command][8] + except Exception: + expectedtype = '' + function = self._functions['zone{}'.format(zone)][command][1].split(" ")[0] + try: + functiontype = self._functions['zone{}'.format(zone)][command][1].split(" ")[1] + except Exception: + functiontype = '' + item = self._items['zone{}'.format(zone)][function]['Item'] + self.logger.log(VERBOSE2, "Initializing {}: Response: {}, Function: {}, Item: {}, Type: {}".format( + self._name, response, function, item, expectedtype)) + if self._functions['zone{}'.format(zone)][command][5].lower() in ['r', 'rw']: + try: + if function == 'display': + if response in self._ignoreresponse and '' not in self._ignoreresponse: + self._special_commands['Display'] = {'Command': response, 'Ignore': 1} + else: + self._special_commands['Display'] = {'Command': response, 'Ignore': 0} + self.logger.log(VERBOSE1, "Initializing {}: Found Display Command and updated it: {}".format(self._name, self._special_commands)) + elif function == 'input': + if 'Input' not in self._special_commands: + self._special_commands['Input'] = {'Command': [response], 'Ignore': [0]} + else: + self._special_commands['Input']['Command'].append(response) + self._special_commands['Input']['Ignore'].append(0) + self.logger.log(VERBOSE1, "Initializing {}: Found Input Command and added it to display commands.".format(self._name)) + elif (function == 'title' or function == 'station' or function == 'genre'): + if 'Nowplaying' not in self._special_commands: + self._special_commands['Nowplaying'] = {'Command': [response]} + else: + self._special_commands['Nowplaying']['Command'].append(response) + self.logger.log(VERBOSE1, "Initializing {}: Found Now Playing Command and updated it: {}".format(self._name, self._special_commands)) + elif (function == 'speakers'): + if 'Speakers' not in self._special_commands: + self._special_commands['Speakers'] = {'Command': [response]} + else: + self._special_commands['Speakers']['Command'].append(response) + self.logger.log(VERBOSE1, "Initializing {}: Found Speakers Command and updated it: {}".format(self._name, self._special_commands)) + except Exception as err: + self.logger.debug("Initializing {}: No Special Commands set. Message: {}".format(self._name, err)) + + try: + toadd = len(self._response_commands[response]) + for entry in self._response_commands[response]: + if (item not in entry and expectedtype in entry and valuelength == entry[0]) and function == entry[4]: + entry[3].append(item[0]) + self.logger.log(VERBOSE1, "Initializing {}: Appending Item to response {} for function {} with response {}.".format( + self._name, response, function, entry)) + elif expectedtype not in entry or not valuelength == entry[0] or not function == entry[4]: + toadd -= 1 + else: + pass + self.logger.log(VERBOSE1, "Initializing {}: Ignoring response {} for function {} because it is already in list.".format( + self._name, response, function, entry)) + if toadd < len(self._response_commands[response]): + self._response_commands[response].append([ + valuelength, commandlength, position, item, function, 'zone{}'.format(zone), inverse, expectedtype, functiontype]) + self.logger.log(VERBOSE1, "Initializing {}: Adding additional list to function {} for response {} with value {}.".format( + self._name, function, response, self._response_commands[response])) + except Exception as err: + self.logger.log(VERBOSE1, "Initializing {}: Creating response command for: {}. Message: {}".format(self._name, response, err)) + self._response_commands[response] = [[ + valuelength, commandlength, position, item, function, 'zone{}'.format(zone), inverse, expectedtype, functiontype]] + self._response_commands[response] = sorted(self._response_commands[response], key=lambda x: x[0], reverse=True) + except Exception as err: + self.logger.warning("Initializing {}: Problems searching functions for {} in zone {}. Either it is not in the textfile or wrong instance name defined. Error: {}".format(self._name, command, zone, err)) + except Exception as err: + self.logger.error( + "Initializing {}: Problems creating response commands. Error: {}".format(self._name, err)) + finally: + if 'Display' not in self._special_commands: + self._special_commands['Display'] = {'Command': '', 'Ignore': 1} + if 'Input' not in self._special_commands: + self._special_commands['Input'] = {'Command': '', 'Ignore': 1} + if 'Nowplaying' not in self._special_commands: + self._special_commands['Nowplaying'] = {'Command': ''} + if 'Speakers' not in self._special_commands: + self._special_commands['Speakers'] = {'Command': ''} + self.logger.debug("Initializing {}: Special commands for solving Display issues: {}".format( + self._name, self._special_commands)) + self.logger.info("Initializing {}: Created response commands, including {} entries.".format( + self._name, len(self._response_commands))) + if self._threadlock_standard.locked(): + self._lock.release() + return self._response_commands, self._special_commands + + def _read_commandfile(self): + if not self._lock.acquire(timeout=2): + return + try: + self.logger.debug("Initializing {}: Starting to read file {}. Lock is {}".format( + self._name, self._model, self._threadlock_standard.locked())) + filename = '{}/plugins/avdevice/{}.txt'.format( + self._sh.base_dir, self._model) + + commands = codecs.open(filename, 'r', 'utf-8') + zones = [0] + for line in commands: + try: + line = re.sub('[!@#$\\n\\r]', '', line) + line = re.sub('; ', ';', line) + line = re.sub(' ;', ';', line) + if line == '': + function = '' + else: + row = line.split(";") + if row[0] == '': + row[0] = '0' + if row[2] == '': + row[1:3] = [''.join(row[1:3])] + else: + row[1:3] = [' '.join(row[1:3])] + function = row[1] + itemtest = re.sub(' set| on| off| increase| decrease', '', function) + for i in range(0, 9): + try: + test = row[i] + except IndexError: + if i == 5: + row.append('RW') + if i == 6: + row.append('no') + if i == 8 and "set" in function: + row.append('int,float') + elif i == 8 and ("on" in function or "off" in function): + row.append('bool') + elif i == 8 and ("increase" in function or "decrease" in function): + row.append('int,float') + else: + row.append('') + try: + row[8] = row[8].replace('string', 'str') + row[8] = row[8].replace('num', 'int,float') + if row[8] == '': + row[8] = 'bool,int,str' + except Exception: + pass + try: + itemkeys = self._items['zone{}'.format(row[0])].keys() + except Exception: + itemkeys = [] + if function == "FUNCTION" or function == '' or function == "FUNCTION FUNCTIONTYPE": + pass + elif itemtest in itemkeys: + if row[0] == '0' or row[0] == '': + self._functions['zone0'][function] = row + elif row[0] == '1': + self._functions['zone1'][function] = row + elif row[0] == '2': + self._functions['zone2'][function] = row + elif row[0] == '3': + self._functions['zone3'][function] = row + elif row[0] == '4': + self._functions['zone4'][function] = row + else: + self.logger.error("Initializing {}: Error in Commandfile on line: {}".format(self._name, line)) + if not int(row[0]) in zones: + zones.append(int(row[0])) + else: + self.logger.warning("Initializing {}: Function {} for zone {} not used by any item. Re-visit items and config file!".format( + self._name, function, row[0])) + except Exception as err: + self.logger.error("Initializing {}: Problems parsing command file. Error: {}".format(self._name, err)) + self._number_of_zones = max(zones) + self.logger.debug("Initializing {}: Number of zones: {}".format(self._name, self._number_of_zones)) + commands.close() + except Exception as err: + self.logger.error("Initializing {}: Problems loading command file. Error: {}".format(self._name, err)) + finally: + self._functions['zone0']['statusupdate'] = ['0', 'statusupdate', '', '', '', 'W', '', '', 'bool'] + self.logger.info("Initializing {}: Created functions list, including entries for {} zones.".format(self._name, self._number_of_zones)) + if self._threadlock_standard.locked(): + self._lock.release() + self.logger.log(VERBOSE1, "Initializing {}: Finishing reading file. Lock is released. Lock is now {}".format( + self._name, self._threadlock_standard.locked())) + return self._functions, self._number_of_zones diff --git a/avdevice/README.md b/avdevice/README.md old mode 100644 new mode 100755 index e024a58d6..07a5f475d --- a/avdevice/README.md +++ b/avdevice/README.md @@ -22,13 +22,18 @@ avdevice: class_name: AVDevice class_path: plugins.avdevice model: sc-lx86 - instance: pioneer_one - tcp: 10.0.0.130, 9009 - rs232: /dev/ttyUSB1, 9600, 0.1, 0.2 - #ignoreresponse: - #forcebuffer: - #inputignoredisplay: Source values - #dependson: item, value + #instance: pioneer_one + tcp_ip: 10.0.0.130 + #tcp_port: 23 + #tcp_timeout: 1 + rs232_port: /dev/ttyUSB1 + #rs232_baudrate: 9600 + #rs232_timeout: 0.1 + #ignoreresponse: 'RGB,RGC,RGD,GBH,GHH,LM0,VTA,AUA,AUB' + #forcebuffer: 'GEH01020, GEH04022, GEH05024' + #inputignoredisplay: '' + #dependson_item: '' + #dependson_value: True #errorresponse: E02, E04, E06 #resetonerror: False #depend0_power0: False @@ -38,7 +43,7 @@ avdevice: #reconnectretries: 13 #reconnectcycle: 10 #secondstokeep: 50 - #responsebuffer: -5 + #responsebuffer: 5 #autoreconnect: false ``` @@ -47,12 +52,17 @@ avdevice: * `model`: string. name of AV device. Has to correspond to a text file with the same name in the folder plugins/avdevice. * `instance`: string. define instance name, each device needs an individual instance name! -* `tcp`: list of values. if you use TCP connection define IP address and port, separated by a "," -* `rs232`: list of values. if you use a RS232 cable to communicate with your device (highly recommended!) define port, baudrate, timeout and write timeout separated by "," +* `tcp_ip`: IP address +* `tcp_port`: TCP/IP port +* `tcp_timeout`: TCP/IP timeout +* `rs232_port`: If you use a RS232 cable to communicate with your device (highly recommended!) define the interface port +* `rs232_baudrate`: baudrate for RS232 +* `rs232_timeout`: timeout for RS232 * `ignoreresponse`: list of values. the plugin doesn't care about responses from the device starting with the given values. List responses for menu navigation, etc. For Pioneer receivers the following list is recommended: RGB, RGC, RGD, GBH, GHH, LM0, VTA, AUA, AUB * `forcedbuffer`: list of strings. If for whatever reason you don't want to buffer the response from your device you can still define specific responses that should get buffered. This is important for responses that change or get sent very quickly. Artist, title, radio station, etc. are examples that should be put here. For Pioneer receivers the following list is recommended: GEH01020, GEH04022, GEH05024 * `inputignoredisplay`: list of int. The value of the LCD display on your receiver might get updated very often, e.g. when it shows song titles as a scrolling text. To avoid constant display updates and therefore possible confusion with relevant answers of your device listing source inputs like internet radio, LAN streaming, etc. here is highly recommended. For Pioneer receivers the following list is recommended: 26,38,40,41,44,17,02,48,0 -* `dependson`: item, value. If given item has given value the commands are sent to the device, otherwise they are not. Relevant if you have your device connected to a power socket that can be turned off. +* `dependson_item`: item. If given item has given value the commands are sent to the device, otherwise they are not. Relevant if you have your device connected to a power socket that can be turned off. +* `dependson_value`: boolean. If given item has given value the commands are sent to the device, otherwise they are not. Relevant if you have your device connected to a power socket that can be turned off. * `errorresponse`: list of strings. The standard error responses from your device. For Pioneer receivers they are "E" followed by a number. If no values are provided error answers from your device might get recognized much slower but actually should still get recognized. * `resetonerror`: boolean. Reset the value of the item that could not be updated. E.g. you set the volume of zone 2 to "100". If either the dependson item is off or the device sends an error response or after several connection and send retries the expected response is not received, the volume item gets set to value it had before you sent the command. That way you avoid having a wrong value displayed in your Visu. * `depend0_power0`: boolean. If the dependson item is off the power off all zones are set to off. This is especially relevant for a correct representation in your Visu when you have a powered on device but turn off the power socket. @@ -60,12 +70,10 @@ avdevice: * `sendretries`: integer. This value defines how often a command should be sent when receiving a wrong answer from the device. * `resendwait`: float. Seconds the plugin should wait between each resend retry. * `reconnectretries`: integer. If the plugin can not connect to the device it retries this often. This is especially useful for TCP connections on devices that are plugged into a switchable socket as most receivers need about 40-50 seconds to boot their network device. -* `reconnectcycle`: integer. Seconds the plugin should wait between each reconnect retry. * `secondstokeep`: integer. Seconds the plugin should temporarily save a command to retry later on after establishing a connection. This is especially useful for TCP connections on devices that are plugged into a switchable socket as most receivers need about 40-50 seconds to boot their network device. -* `responsebuffer`: integer or boolean. Set this to a negative number to collect quickly received responses in a buffer and evaluate them collectively. The standard value should be fine and prevent responses getting lost. Some receivers might first respond to a command with an update of the display and then with the actual value. The buffer ensures the correct evaluation of the response. +* `responsebuffer`: integer or boolean. Set this to a number to collect quickly received responses in a buffer and evaluate them collectively. The standard value should be fine and prevent responses getting lost. Some receivers might first respond to a command with an update of the display and then with the actual value. The buffer ensures the correct evaluation of the response. * `autoreconnect`: boolean. Automatically tries to reconnect if no response is received or connection is lost. This should not be necessary as the plugin always tries to reconnect before sending a command. - ### items.yaml #### avdevice_zone[0-4]@[instance]: [command] @@ -160,7 +168,7 @@ Pioneer: ### model.txt -#### ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE;TYPE +#### ZONE;FUNCTION;FUNCTIONTYPE;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE;RESPONSETYPE Configure your commands depending on your model and manufacturer. You have to name the file the same as configured in the plugin.yaml as "model". E.g. if you've configured "model: vsx-923" you name the file "vsx-923.txt" @@ -168,13 +176,15 @@ Each line holds one specific command that should be sent to the device. You also * `zone`: Number of zone. Has to correspond to the attribute in item.yaml. E.g. for zone 1 use "avdevice_zone1: command". Zone 0 holds special commands like navigating in the menu, display reponse, information about currently playing songs, etc. -* `function`: name of the function. You can name them whatever you like but keep in mind the following scheme: for boolean functions add a " on" or " off" to the function name. For commands setting a specific value like source, input mode, volume, etc. add a " set" +* `function`: name of the function. You can name them whatever you like. You reference this value in the item using avdevice_zoneX: function. + +* `functiontype`: for boolean functions use "on" or "off". For commands setting a specific value like source, input mode, volume, etc. use "set". To increase ot decrease a value use the corresponding "increase" or "decrease". For everything else leave empty! * `send`: the command to be sent, e.g. power off is "PF" for Pioneer receivers. You can use a pipe "|" if more than one command should be sent. That might be necessary for power on commands via RS232, e.g. for Pioneer receivers to power on "PO|PO" forces the plugin to send the "PO" command twice. Use stars "\*" to specify the format of the value to be sent. Let's say your device expects the value for volume as 3 digits, a "\*\*\*VL" ensures that even setting the volume to "5" sends the command as "005VL" -* `query`: Query command. This is usually useful after setting up the connection or turning on the power. This command gets also used if the plugin doesn't receive the correct answer after sending a command. +* `query`: Query command. This is usually useful after setting up the connection or turning on the power. This command gets also used if the plugin doesn't receive the correct answer after sending a command. It is recommended to leave this value empty for all functions except on, off and set. -* `response`: The expected response after sending a command. Use "none" if you don't want to wait for the correct response. You can use stars "\*" again to ensure that the exact correct value is set. Example: You set the volume to 100. If you want to ensure that the device responds with any value for volume just use "VOL" here (or whatever response your device sends). If you want to ensure that the device is set to a volume of 100, use stars as placeholders, e.g. "VOL\*\*\*" for 3 digits. +* `response`: The expected response after sending a command. Use "none" if you don't want to wait for the correct response. You can use stars "\*" again to ensure that the exact correct value is set. Example: You set the volume to 100. If you want to ensure that the device responds with any value for volume just use "VOL" here (or whatever response your device sends). If you want to ensure that the device is set to a volume of 100, use stars as placeholders, e.g. "VOL\*\*\*" for 3 digits. You can even specify multiple response possibilities separated by "|". * `readwrite`: R for read only, W for write only, RW for Read and Write. E.g. display values are read only whereas turning the volume up might be a write operation only. Setting this correctly ensures a fast and reliable plugin operation @@ -182,51 +192,40 @@ Each line holds one specific command that should be sent to the device. You also * `maxvalue`: You can define the maximum value for setting a specific function. This might be most relevant for setting the volume. If you configure this with "100" and set the volume to "240" (via Visu or CLI) the value will get clamped by the plugin and set to "100". -* `type`: If you want to force a function to deal with boolean values, use "bool" here. This might be necessary when your device responds in a weird way like an Epson projector does. It responds with "PWR=01" or "PWR=02" when turned on.. depending on it's mood ;) +* `responsetype`: Defines the type of the response value and can be set to "bool", "num" or "string" or a mixture of them. Most response types are set automatically on startup but you can force specific type using this value. It is recommended to use the values suggested in the txt files that come with the plugin. #### Example ``` -# plugins/avdevice/model.txt -ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE -1;power on;PO|PO;?P;PWR*;RW;yes -1;power off;PF;?P;PWR*;RW;yes -1;volume+;VU;?V;VOL;W -1;volume-;VD;?V;VOL;W -1;volumehigh;150VL;?V;VOL150;W -1;volumelow;110VL;?V;VOL110;W -1;volume set;***VL;?V;VOL***;RW;;161 -1;mute on;MO;?M;MUT*;RW;yes -1;mute off;MF;?M;MUT*;RW;yes -1;mode set;****SR;?S;SR****;RW -1;input set;**FN;?F;FN**;RW -2;power on;APO|APO;?AP;APR*;RW;yes -2;power off;APF;?AP;APR*;RW;yes -2;volume+;ZU;?ZV;ZV;W -2;volume-;ZD;?ZV;ZV;W -2;volumehigh;70ZV;?ZV;ZV70;W -2;volumelow;45ZV;?ZV;ZV45;W -2;volume set;**ZV;?ZV;ZV**;RW;;81 -2;mute on;Z2MO;?Z2M;Z2MUT*;RW;yes -2;mute off;Z2MF;?Z2M;Z2MUT*;RW;yes -2;input set;**ZS;?ZS;Z2F**;RW -3;power on;BPO|BPO;?BP;BPR*;RW;yes -3;power off;BPF;?BP;BPR*;RW;yes -3;volume+;YU;?YV;YV;W -3;volume-;YD;?YV;YV;W -3;volumehigh;75YV;?YV;YV75;W -3;volumelow;45YV;?YV;YV45;W -3;volume set;**YV;?YV;YV**;RW;;81 -3;mute on;Z3MO;?Z3M;Z3MUT*;RW;yes -3;mute off;Z3MF;?Z3M;Z3MUT*;RW;yes -3;input set;**ZT;?ZT;Z3F**;RW -4;power on;ZEO;?ZEP;ZEP*;RW;yes -4;power off;ZEF;?ZEP;ZEP*;RW;yes -4;input set;**ZEA;?ZEA;ZEA**;RW -0;title;;;GEH01020;R -0;station;;;GEH04022;R -0;genre;;;GEH05024;R -0;statusupdate;;;;W -0;display;?FL;?FL;FL******************************;R - -``` \ No newline at end of file +# plugins/avdevice/pioneer.txt +ZONE; FUNCTION; FUNCTIONTYPE; SEND; QUERY; RESPONSE; READWRITE; INVERTRESPONSE; MAXVALUE; RESPONSETYPE +1; power; on; PO|PO; ?P; PWR*; RW; yes +1; power; off; PF; ?P; PWR*; RW; yes +1; volume+; VU; ; VOL; W +1; volume-; VD; ; VOL; W +1; volumehigh; 150VL; ?V; VOL150; W +1; volumelow; 110VL; ?V; VOL110; W +1; volume; set; ***VL; ?V; VOL***; RW; ; 185 +1; mute; on; MO; ?M; MUT*; RW; yes +1; mute; off; MF; ?M; MUT*; RW; yes +1; input; set; **FN; ?F; FN**; RW +2; power; on; APO|APO; ?AP; APR*; RW; yes +2; power; off; APF; ?AP; APR*; RW; yes +2; volume+; ZU; ; ZV; W +2; volume-; ZD; ; ZV; W +2; volumehigh; 75ZV; ?ZV; ZV75; W +2; volumelow; 45ZV; ?ZV; ZV45; W +2; volume; set; **ZV; ?ZV; ZV**; RW; ; 81 +2; mute; on; Z2MO; ?Z2M; Z2MUT*; RW; yes +2; mute; off; Z2MF; ?Z2M; Z2MUT*; RW; yes +2; input; set; **ZS; ?ZS; Z2F**; RW +0; title; ; ; GEH01020; R +0; station; ; ; GEH04022; R +0; genre; ; ; GEH05024; R +0; display; ?FL; ?FL; FL******************************; R +1; speakers; set; *SPK; ?SPK; SPK*; RW +``` + +### Debugging + +You can use level 9 (VERBOSE1) and 8 (VERBOSE2) as debugging levels in logging.yaml diff --git a/avdevice/__init__.py b/avdevice/__init__.py old mode 100755 new mode 100644 index 0fac50127..34842cd8e --- a/avdevice/__init__.py +++ b/avdevice/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab ######################################################################### -# Copyright 2016 +# Copyright 2016 ######################################################################### # This file is part of SmartHomeNG. # @@ -15,7 +15,7 @@ # # SmartHomeNG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License @@ -25,6 +25,7 @@ import logging from lib.model.smartplugin import SmartPlugin +from itertools import groupby import threading import os import io @@ -32,1888 +33,1814 @@ import re import codecs import errno -from itertools import groupby - import serial import socket +from .AVDeviceInit import Init + +VERBOSE1 = logging.DEBUG - 1 +VERBOSE2 = logging.DEBUG - 2 +logging.addLevelName(logging.DEBUG - 1, 'VERBOSE1') +logging.addLevelName(logging.DEBUG - 2, 'VERBOSE2') class AVDevice(SmartPlugin): - ALLOW_MULTIINSTANCE = True - PLUGIN_VERSION = "1.3.0" - - def __init__(self, - smarthome, - model, - manufacturer='', - ignoreresponse='', - forcebuffer='', - inputignoredisplay='', - dependson=None, - rs232=None, - tcp=None, - errorresponse='E02,E04,E06', - resetonerror=False, - depend0_power0=False, - depend0_volume0=False, - sendretries=10, - resendwait=1.0, - reconnectretries=13, - secondstokeep=50, - reconnectcycle=10, - responsebuffer='-5', - autoreconnect=False - ): - self.logger = logging.getLogger(__name__) - self._sh = smarthome - self._model = model - self._manufacturer = manufacturer - self._name = self.get_instance_name() - self._serialwrapper = None - self._serial = None - - try: - self._rs232 = re.sub('[ ]', '', str(rs232)).split(",")[0] - if self._rs232 == 'None': self._rs232 = None - self.logger.debug("Initializing Serial {}: Serialport is {}.".format(self._name,self._rs232)) - except: - self._rs232 = None - self.logger.warning("Initializing Serial {}: Serial Port is {}. Error: {}.".format(self._name,self._baud,err)) - if self._rs232 is not None: - try: - self._baud = int(re.sub('[ ]', '', str(rs232)).split(",")[1]) - self.logger.debug("Initializing Serial {}: Baudrate is {}.".format(self._name,self._baud)) - except Exception as err: - self._baud = 9600 - self.logger.debug("Initializing Serial {}: Using standard Baudrate {}. Because: {}.".format(self._name,self._baud,err)) - try: - self._timeout = re.sub('[ ]', '', str(rs232)).split(",")[2] - self.logger.debug("Initializing Serial {}: Timeout is {}.".format(self._name,self._timeout)) - except Exception as err: - self._timeout = 0.1 - self.logger.debug("Initializing Serial {}: Using standard timeout {}. Because: {}.".format(self._name,self._timeout,err)) - try: - self._writetimeout = re.sub('[ ]', '', str(rs232)).split(",")[3] - self.logger.debug("Initializing Serial {}: write_timeout is {}.".format(self._name,self._writetimeout)) - except Exception as err: - self._writetimeout = 0.1 - self.logger.debug("Initializing Serial {}: Using standard write_timeout {}. Because: {}.".format(self._name,self._writetimeout,err)) - - - try: - self._tcp = re.sub('[ ]', '', str(tcp)).split(",")[0] - if self._tcp == 'None': self._tcp = None - self.logger.debug("Initializing TCP {}: IP is {}.".format(self._name,self._tcp)) - except Exception as err: - self._tcp = None - self.logger.warning("Initializing TCP {}: Host is {}. Because: {}.".format(self._name,self._baud,err)) - if self._tcp is not None: - try: - self._port = int(re.sub('[ ]', '', str(tcp)).split(",")[1]) - self.logger.debug("Initializing TCP {}: Port is {}.".format(self._name,self._port)) - except Exception as err: - self._port = None - self.logger.warning("Initializing TCP {}: Port is {}. Because: {}.".format(self._name,self._port,err)) - - - self._threadlock_standard = threading.Lock() - self._threadlock_send = threading.Lock() - self._threadlock_buffer = threading.Lock() - self._threadlock_dict = threading.Lock() - self._threadlock_parse = threading.Lock() - self._threadlock_reset = threading.Lock() - self._threadlock_update = threading.Lock() - self._lock = threading.Condition(self._threadlock_standard) - self._sendlock = threading.Condition(self._threadlock_send) - self._bufferlock = threading.Condition(self._threadlock_buffer) - self._dictlock = threading.Condition(self._threadlock_dict) - self._parselock = threading.Condition(self._threadlock_parse) - self._resetlock = threading.Condition(self._threadlock_reset) - self._updatelock = threading.Condition(self._threadlock_update) - self.alive = False - self._functions = {'zone0': {}, 'zone1': {}, 'zone2': {}, 'zone3': {}, 'zone4': {}} - self._items = {'zone0': {}, 'zone1': {}, 'zone2': {}, 'zone3': {}, 'zone4': {}} - self._query_zonecommands = {'zone0': [], 'zone1': [], 'zone2': [], 'zone3': [], 'zone4': []} - self._items_speakers = {'zone1': {}, 'zone2': {}, 'zone3': {}} - self._send_commands = [] - self._keep_commands = {} - self._query_commands = [] - self._power_commands = [] - self._response_commands = {} - self._number_of_zones = 0 - self._trigger_reconnect = True - self._reconnect_counter = 0 - self._resend_counter = 0 - self._resend_wait = float(resendwait) - self._secondstokeep = int(secondstokeep) - self._requery_counter = 0 - self._sendingcommand = 'done' - self._auto_reconnect = autoreconnect - self._resend_retries = int(sendretries) - self._reconnect_retries = int(reconnectretries) - self._specialcommands = {} - self._is_connected = [] - - try: - self._dependson = re.sub('[ ]', '', dependson).split(",")[0] - self.logger.debug("Initializing {}: Dependson Item: {}.".format(self._name, self._dependson)) - except: - self._dependson = dependson - self.logger.debug("Initializing {}: Dependson Item: {}. No value for item given, assuming True.".format(self._name, self._dependson)) - try: - self._dependson_value = re.sub('[ ]', '', dependson).split(",")[1] - if str(self._dependson_value).lower() in ['1', 'yes', 'true', 'on']: - self._dependson_value = True - elif str(self._dependson_value).lower() in ['0', 'no', 'false', 'off']: - self._dependson_value = False - except: - self._dependson_value = True - - if str(depend0_power0).lower() in ['1', 'yes', 'true', 'on'] and self._dependson: - self._depend0_power0 = True - elif str(depend0_power0).lower() in ['0', 'no', 'false', 'off'] or not self._dependson: - self._depend0_power0 = False - if str(depend0_volume0).lower() in ['1', 'yes', 'true', 'on'] and self._dependson: - self._depend0_volume0 = True - elif str(depend0_volume0).lower() in ['0', 'no', 'false', 'off'] or not self._dependson: - self._depend0_volume0 = False - - - if str(responsebuffer).lower() in ['1', 'yes', 'true', 'on']: - self._response_buffer = True - elif str(responsebuffer).lower() in ['0', 'no', 'false', 'off']: - self._response_buffer = False - elif responsebuffer.lstrip("-").isdigit(): - self._response_buffer = int(responsebuffer) - if str(resetonerror).lower() in ['1', 'yes', 'true', 'on']: - self._reset_onerror = True - elif str(resetonerror).lower() in ['0', 'no', 'false', 'off']: - self._reset_onerror = False - self._ignoreresponse = re.sub('[ ]', '', ignoreresponse).split(",") - self._errorresponse = re.sub('[ ]', '', errorresponse).split(",") - self._force_buffer = re.sub('[ ]', '', forcebuffer).split(",") - self._ignoredisplay = re.sub('[ ]', '', inputignoredisplay).split(",") - self.logger.debug("Initializing {}: Special Settings: Ignoring responses {}.".format(self._name, self._ignoreresponse)) - self.logger.debug("Initializing {}: Special Settings: Error responses {}.".format(self._name, self._errorresponse)) - self.logger.debug("Initializing {}: Special Settings: Force buffer {}.".format(self._name, self._force_buffer)) - self.logger.debug("Initializing {}: Special Settings: Ignore Display {}".format(self._name, self._ignoredisplay)) - - smarthome.scheduler.add('avdevice-serial-reconnect',self.connect_serial, cycle=reconnectcycle) - smarthome.scheduler.change('avdevice-serial-reconnect', active=False) - smarthome.scheduler.add('avdevice-tcp-reconnect',self.connect_tcp, cycle=reconnectcycle) - smarthome.scheduler.change('avdevice-tcp-reconnect', active=False) - - - def _create_querycommands(self): - if not self._lock.acquire(timeout=2): - return - try: - self.logger.debug("Initializing {}: Starting to create query commands. Lock is {}".format( - self._name, self._threadlock_standard.locked())) - displaycommand = '' - length = 0 - for zone in range(0, self._number_of_zones+1): - for command in self._functions['zone{}'.format(zone)]: - try: - querycommand = self._functions['zone{}'.format(zone)][command][3] - responselist = [] - splitresponse = self._functions['zone{}'.format(zone)][command][4].split("|") - for split in splitresponse: - if split.count('*') > 0: - responselist.append(split.strip()) - responsestring = "|".join(responselist) - responsecommand = re.sub('[*]', '', responsestring) - if not '{},{},{}'.format(querycommand, querycommand, responsecommand) in self._query_zonecommands['zone{}'.format(zone)] and not responsecommand == '' and not responsecommand == ' ' and not responsecommand == 'none' and not querycommand == '' and not self._functions['zone{}'.format(zone)][command][4] in self._ignoreresponse: - if not re.sub('[*]', '', self._functions['zone{}'.format(zone)][command][4]) in self._specialcommands['Display']['Command']: - self._query_zonecommands['zone{}'.format(zone)].append('{},{},{}'.format( - querycommand, querycommand, responsecommand)) - else: - displaycommand = '{},{},{}'.format(querycommand, querycommand, responsecommand) - self.logger.debug("Initializing {}: Displaycommand: {}".format(self._name, displaycommand)) - if not '{},{},{}'.format(querycommand, querycommand, responsecommand) in self._query_commands and not responsecommand == '' and not responsecommand == ' ' and not responsecommand == 'none' and not querycommand == '' and not self._functions['zone{}'.format(zone)][command][4] in self._ignoreresponse: - if not re.sub('[*]', '', self._functions['zone{}'.format(zone)][command][4]) in self._specialcommands['Display']['Command']: - self._query_commands.append('{},{},{}'.format( - querycommand, querycommand, responsecommand)) - else: - displaycommand = '{},{},{}'.format(querycommand, querycommand, responsecommand) - #self.logger.debug("Initializing {}: Displaycommand: {}".format(self._name, displaycommand)) - except Exception as err: - self.logger.error("Initializing {}: Problems adding query commands for command {}. Error: {}".format( - self._name, command, err)) - length += len(self._query_zonecommands['zone{}'.format(zone)]) - if not displaycommand == '': - self._query_commands.append(displaycommand) - length += 1 - except Exception as err: - self.logger.error( - "Initializing {}: Problems searching for query commands. Error: {}".format(self._name, err)) - finally: - if self._threadlock_standard.locked(): self._lock.release() - self._query_commands_count = length - self.logger.debug("Initializing {}: Created query commands: {}. Created query zone commands: {}. Lock is now {}".format( - self._name, self._query_commands, self._query_zonecommands, self._threadlock_standard.locked())) - self.logger.info("Initializing {}: Created query commands, including {} entries.".format( - self._name, self._query_commands_count)) - self.connect() - - def _create_powercommands(self): - if not self._lock.acquire(timeout=2): - return - try: - self.logger.debug("Initializing {}: Starting to create power commands. Lock is {}".format( - self._name, self._threadlock_standard.locked())) - for zone in range(0, self._number_of_zones+1): - for command in self._functions['zone{}'.format(zone)]: - try: - if command.startswith('power on'): - try: - value = re.sub('\*\*', 'ON', self._functions['zone{}'.format(zone)][command][4]) - except: - if self._functions['zone{}'.format(zone)][command][6] == 'yes': - value = re.sub('[*]', '0', self._functions['zone{}'.format(zone)][command][4]) - else: - value = re.sub('[*]', '1', self._functions['zone{}'.format(zone)][command][4]) - - combined = '{},{},{}'.format(self._functions['zone{}'.format(zone)][command][2], self._functions['zone{}'.format(zone)][command][3], value) - self._power_commands.append(combined) - except Exception as err: - self.logger.warning("Initializing {}: Problems searching power commands for {} in zone {}. Error: {}".format(self._name, command, zone, err)) - except Exception as err: - self.logger.warning("Initializing {}: Problems creating power commands. Error: {}".format(self._name, err)) - finally: - if self._threadlock_standard.locked(): self._lock.release() - self.logger.debug("Initializing {}: Finished creating power commands: {}. Lock is released. Lock is now {}".format( - self._name, self._power_commands, self._threadlock_standard.locked())) - self._create_querycommands() - - def _create_responsecommands(self): - if not self._lock.acquire(timeout=2): - return - try: - self.logger.debug("Initializing {}: Starting to create response commands. Lock is {}".format( - self._name, self._threadlock_standard.locked())) - for zone in range(0, self._number_of_zones+1): - for command in self._functions['zone{}'.format(zone)]: - try: - response_to_split = self._functions['zone{}'.format(zone)][command][4].split("|") - for response in response_to_split: - valuelength = response.count('*') - - if response.find('*') >= 0: - position = response.index('*') - else: - position = 0 - response = re.sub('[*]', '', response) - commandlength = len(response) - try: - inverse = self._functions['zone{}'.format(zone)][command][6] - except: - inverse = 'no' - try: - type = self._functions['zone{}'.format(zone)][command][8] - except: - type = '' - function = self._functions['zone{}'.format(zone)][command][1].split(" ")[0] - item = self._items['zone{}'.format(zone)][function]['Item'] - self.logger.debug("Initializing {}: Response: {}, Function: {}, Item: {}, Type: {}".format(self._name, response, function, item, type)) - if self._functions['zone{}'.format(zone)][command][5].lower() in ['r', 'rw']: - try: - if function == 'display': - if response in self._ignoreresponse and not '' in self._ignoreresponse: - self._specialcommands['Display'] = {'Command': response, 'Ignore': 1} - else: - self._specialcommands['Display'] = {'Command': response, 'Ignore': 0} - #self.logger.debug("Initializing {}: Found Display Command and updated it: {}".format(self._name, self._specialcommands)) - elif function == 'input': - if 'Input' not in self._specialcommands: - self._specialcommands['Input'] = {'Command': [response], 'Ignore': [0]} - else: - self._specialcommands['Input']['Command'].append(response) - self._specialcommands['Input']['Ignore'].append(0) - #self.logger.debug("Initializing {}: Found Input Command and added it to display commands.".format(self._name)) - elif (function == 'title' or function == 'station' or function == 'genre'): - if 'Nowplaying' not in self._specialcommands: - self._specialcommands['Nowplaying'] = {'Command': [response]} - else: - self._specialcommands['Nowplaying']['Command'].append(response) - #self.logger.debug("Initializing {}: Found Now Playing Command and updated it: {}".format(self._name, self._specialcommands)) - elif (function == 'speakers'): - if 'Speakers' not in self._specialcommands: - self._specialcommands['Speakers'] = {'Command': [response]} - else: - self._specialcommands['Speakers']['Command'].append(response) - #self.logger.debug("Initializing {}: Found Speakers Command and updated it: {}".format(self._name, self._specialcommands)) - except Exception as err: - self.logger.debug("Initializing {}: No Special Commands set. Message: {}".format(self._name, err)) - try: - if not item in self._response_commands[response]: - self._response_commands[response][3].append(item[0]) - except Exception as err: - self._response_commands[response] = [ - valuelength, commandlength, position, item, function, 'zone{}'.format(zone), inverse, type] - else: - #self.logger.debug("Initializing {}: Item {} is not set to readable, ignoring.".format(self._name, item)) - pass - except Exception as err: - self.logger.warning("Initializing {}: Problems searching functions for {} in zone {}. Either it is not in the textfile or wrong instance name defined. Error: {}".format(self._name, command, zone, err)) - except Exception as err: - self.logger.error( - "Initializing {}: Problems creating response commands. Error: {}".format(self._name, err)) - finally: - self.logger.debug("Initializing {}: Response commands: {}".format( - self._name, self._response_commands)) - if not 'Display' in self._specialcommands: - self._specialcommands['Display'] = {'Command': '', 'Ignore': 1} - if not 'Input' in self._specialcommands: - self._specialcommands['Input'] = {'Command': '', 'Ignore': 1} - if not 'Nowplaying' in self._specialcommands: - self._specialcommands['Nowplaying'] = {'Command': ''} - if not 'Speakers' in self._specialcommands: - self._specialcommands['Speakers'] = {'Command': ''} - self.logger.debug("Initializing {}: Special commands for solving Display issues: {}".format( - self._name, self._specialcommands)) - self.logger.info("Initializing {}: Created response commands, including {} entries.".format( - self._name, len(self._response_commands))) - if self._threadlock_standard.locked(): self._lock.release() - self.logger.debug("Initializing {}: Finished creating response commands. Lock is released. Lock is now {}".format( - self._name, self._threadlock_standard.locked())) - self._create_powercommands() - - - def _read_commandfile(self): - if not self._lock.acquire(timeout=2): - return - try: - self.logger.debug("Initializing {}: Starting to read file for model {}. Lock is {}".format( - self._name, self._model, self._threadlock_standard.locked())) - filename = '{}/plugins/avdevice/{}.txt'.format( - self._sh.base_dir, self._model) - - commands = codecs.open(filename, 'r', 'utf-8') - zones = [0] - for line in commands: - try: - line = re.sub('[!@#$\\n\\r]', '', line) - if line == '': - function = '' - else: - row = line.split(";") - if row[0] == '': row[0] = '0' - function = row[1] - itemtest = re.sub(' set| on| off','', function) - for i in range(0,9): - try: - test = row[i] - except IndexError: - if i == 5: - row.append('RW') - if i == 6: - row.append('no') - if i == 8 and "set" in function: - row.append('num') - elif i == 8 and ("on" in function or "off" in function): - row.append('bool') - elif i == 8 and ("+" in function or "-" in function): - row.append('bool') - else: - row.append('') - try: - itemkeys = self._items['zone{}'.format(row[0])].keys() - except: - itemkeys = [] - if (function == "FUNCTION") or function == '': - pass - elif itemtest in itemkeys: - if row[0] == '0' or row[0] == '': - self._functions['zone0'][function] = row - elif row[0] == '1': - self._functions['zone1'][function] = row - elif row[0] == '2': - self._functions['zone2'][function] = row - elif row[0] == '3': - self._functions['zone3'][function] = row - elif row[0] == '4': - self._functions['zone4'][function] = row - else: - self.logger.error( - "Initializing {}: Error in Commandfile on line: {}".format(self._name, line)) - if not int(row[0]) in zones: - zones.append(int(row[0])) - else: - self.logger.warning("Initializing {}: Function {} for zone {} not used by any item. Re-visit items and config file!".format(self._name, function, row[0])) - except Exception as err: - self.logger.error( - "Initializing {}: Problems parsing command file. Error: {}".format(self._name, err)) - self._number_of_zones = max(zones) - self.logger.debug("Initializing {}: Number of zones: {}".format( - self._name, self._number_of_zones)) - commands.close() - except Exception as err: - self.logger.error( - "Initializing {}: Problems loading command file. Error: {}".format(self._name, err)) - finally: - self.logger.info("Initializing {}: Created functions list, including entries for {} zones.".format( - self._name, self._number_of_zones)) - self.logger.debug("Initializing {}: Functions: {}".format( - self._name, self._functions)) - if self._threadlock_standard.locked(): self._lock.release() - self.logger.debug("Initializing {}: Finishing reading file. Lock is released. Lock is now {}".format( - self._name, self._threadlock_standard.locked())) - self._create_responsecommands() - - def _wait(self, time_lapse): - time_start = time.time() - time_end = (time_start + time_lapse) - - while time_end > time.time(): - pass - - def _resetitem(self): - self._resetlock.acquire(timeout=2) - try: - resetting = None - try: - response = self._sendingcommand.split(",")[2].split("|") - self.logger.debug("Resetting {}: Searching for suiting command for sendingcommand response: {}.".format(self._name, response)) - except Exception as e: - response = self._send_commands[0].split(",")[2].split("|") - self.logger.warning("Resetting {}: Cannot find Sendingcommand. Using first Command in queue: {}.".format(self._name, response)) - for key in self._response_commands: - #self.logger.debug("Resetting {}: Trying to reset Item. Comparing: {} with {}".format(self._name, key,response)) - for resp in response: - if resp.startswith(key, 0, self._response_commands[key][1]): - keyfound = True - else: - keyfound = False - if keyfound == True: - zone = self._response_commands[key][5] - previousvalue = self._items[zone][self._response_commands[key][4]]['Value'] - for item in self._response_commands[key][3]: - self.logger.info("Resetting {}: Resetting Item {} to {}".format( - self._name, item, previousvalue)) - item(previousvalue, 'AVDevice', self._tcp) - if key in self._specialcommands['Speakers']['Command']: - for speaker in self._items_speakers[zone]: - previousvalue = self._items_speakers[zone][speaker]['Value'] - for item in self._items_speakers[zone][speaker]['Item']: - item(previousvalue, 'AVDevice', self._tcp) - self.logger.info("Resetting {}: Resetting additional speaker item {} to value {}".format(self._name, item, previousvalue)) - resetting = self._response_commands[key][3] - return resetting - if self._threadlock_reset.locked(): self._resetlock.notify() - break - self._trigger_reconnect = False - return resetting - self.logger.debug("Resetting {}: Deleted first entry of Send Commands. They are now: {}".format( - self._name, self._send_commands)) - except Exception as err: - self.logger.error( - "Resetting {}: Problem resetting Item. Error: {}".format(self._name, err)) - return 'ERROR' - finally: - if self._threadlock_reset.locked(): self._resetlock.release() - - def _resetondisconnect(self, caller): - self._resetlock.acquire(timeout=2) - self.logger.debug('Resetting {}: Starting to reset. Called by {}'.format(self._name, caller)) - try: - for zone in self._items: - if 'power' in self._items[zone].keys() and self._depend0_power0 == True: - self._items[zone]['power']['Value'] = 0 - for singleitem in self._items[zone]['power']['Item']: - singleitem(0, 'AVDevice', self._tcp) - self.logger.debug('Resetting {}: Power to 0 for item {}'.format(self._name, singleitem)) - if 'speakers' in self._items[zone].keys() and self._depend0_power0 == True: - self._items[zone]['speakers']['Value'] = 0 - for item in self._items_speakers[zone].keys(): - self._items_speakers[zone][item]['Value'] = 0 - for singleitem in self._items_speakers[zone][item]['Item']: - singleitem(0, 'AVDevice', self._tcp) - self.logger.debug('Resetting {}: Speakers to 0 for item {}'.format(self._name, singleitem)) - for singleitem in self._items[zone]['speakers']['Item']: - singleitem(0, 'AVDevice', self._tcp) - self.logger.debug('Resetting {}: Speakers to 0 for item {}'.format(self._name, singleitem)) - if 'volume' in self._items[zone].keys() and self._depend0_volume0 == True: - self._items[zone]['volume']['Value'] = 0 - for singleitem in self._items[zone]['volume']['Item']: - singleitem(0, 'AVDevice', self._tcp) - self.logger.debug('Resetting {}: Volume to 0 for item {}'.format(self._name, singleitem)) - self.logger.debug('Resetting {}: Done.'.format(self._name)) - except Exception as err: - self.logger.warning( - 'Resetting {}: Problem resetting Item. Error: {}'.format(self._name, err)) - return None - finally: - if self._threadlock_reset.locked(): self._resetlock.release() - - def _write_itemsdict(self, data): - self._dictlock.acquire(timeout=2) - try: - self.logger.debug("Storing Values {}: Starting to store value in dictionary. Lock is: {}.".format(self._name, self._threadlock_dict.locked())) - for command in self._response_commands.keys(): - if self._response_commands[command][1] == self._response_commands[command][2]: - commandstart = 0 - commandend = self._response_commands[command][2] - else: - commandstart = self._response_commands[command][0] - commandend = self._response_commands[command][0] + self._response_commands[command][1] - - valuestart = self._response_commands[command][2] - valueend = self._response_commands[command][2] + self._response_commands[command][0] - function = self._response_commands[command][4] - - if data[commandstart:commandend] == command: - zone = self._response_commands[command][5] - value = receivedvalue = data[valuestart:valueend] - if self._response_commands[command][7] == 'bool' and not value == '': - self.logger.debug("Storing Values {}: Limiting bool value for received data.".format(self._name)) - if self._manufacturer.lower() == 'epson': - try: - value = max(min(int(value), 1), 0) - self.logger.debug("Parsing Input {}: Limiting bool value for {} with received value {} to {}.".format( - self._name, self._items[zone][function], receivedvalue, value)) - except: - pass - if receivedvalue.lower() == 'on' or receivedvalue == 1: - value = True - if receivedvalue.lower() == 'off' or receivedvalue == 0: - value = False - - if self._response_commands[command][6].lower() in ['1', 'true', 'yes', 'on']: - value = False if int(receivedvalue) > 0 else True - - self._items[zone][function]['Value'] = value - self.logger.debug("Storing Values {}: Found writeable dict key: {}. Zone: {}. Value: {}. Function: {}.".format(self._name, command, zone, value, function)) - return self._items[zone][function], value - if self._threadlock_dict.locked(): self._dictlock.notify() - break - except Exception as err: - self.logger.error( - "Storing Values {}: Problems creating items dictionary. Error: {}".format(self._name, err)) - finally: - if self._threadlock_dict.locked(): self._dictlock.release() - self.logger.debug("Storing Values {}: Finished. Lock is: {}.".format(self._name, self._threadlock_dict.locked())) - - def parse_item(self, item): - if self._tcp is not None or self._rs232 is not None: - #self.logger.debug("Initializing {}: Parsing item: {}. Dependson: {}".format(self._name, item, self._dependson)) - if self.has_iattr(item.conf, 'avdevice'): - info = self.get_iattr_value(item.conf, 'avdevice') - if (info is None): - return None - else: - self._items['zone0'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone0'): - info = self.get_iattr_value(item.conf, 'avdevice_zone0') - if (info is None): - return None - else: - self._items['zone0'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone1'): - info = self.get_iattr_value(item.conf, 'avdevice_zone1') - if (info is None): - return None - else: - self._items['zone1'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone2'): - info = self.get_iattr_value(item.conf, 'avdevice_zone2') - if (info is None): - return None - else: - self._items['zone2'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone3'): - info = self.get_iattr_value(item.conf, 'avdevice_zone3') - if (info is None): - return None - else: - self._items['zone3'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone4'): - info = self.get_iattr_value(item.conf, 'avdevice_zone4') - if (info is None): - return None - else: - self._items_['zone4'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone1_speakers'): - info = self.get_iattr_value(item.conf, 'avdevice_zone1_speakers') - if (info is None): - return None - else: - self._items_speakers['zone1'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone2_speakers'): - info = self.get_iattr_value(item.conf, 'avdevice_zone2_speakers') - if (info is None): - return None - else: - self._items_speakers['zone2'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif self.has_iattr(item.conf, 'avdevice_zone3_speakers'): - info = self.get_iattr_value(item.conf, 'avdevice_zone3_speakers') - if (info is None): - return None - else: - self._items_speakers['zone3'][info] = {'Item': [item], 'Value': item()} - return self.update_item - elif str(item) == self._dependson: - self._items['zone0']['dependson'] = {'Item': self._dependson, 'Value': self._dependson_value} - self.logger.debug("Initializing {}: Dependson Item found: {}".format(self._name, item, self._dependson)) - return self.update_item - else: - return None - self.logger.warning( - "Parsing Items {}: No items parsed".format(self._name)) - - - def _processing_response(self, socket): - self._bufferlock.acquire(timeout=2) - try: - buffer = '' - bufferlist = [] - tidy = lambda c: re.sub( - r'(^\s*[\r\n]+|^\s*\Z)|(\s*\Z|\s*[\r\n]+)', - lambda m: '\r\n' if m.lastindex == 2 else '', - c) - try: - if self._rs232 and (socket == self._serialwrapper or socket == self._serial): - #self.logger.debug("Processing Response {}: Starting to read RS232".format(self._name)) - if socket == self._serial: - buffer = socket.readline().decode('utf-8') - else: - buffer = socket.read() - if self._tcp and socket == self._socket: - buffer = socket.recv(4096).decode('utf-8') - #self.logger.debug("Processing Response {}: Starting to read TCP".format(self._name)) - buffering = False - buffer = tidy(buffer) - if not buffer == '' and (not self._response_buffer == False or not self._response_buffer == 0): - buffering = True - elif buffer == '' and not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup': - self._resend_counter +=1 - self._wait(0.1) - sending = self._send(self._sendingcommand, 'responseprocess') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - self.logger.debug("Processing Response {}: Received empty response while sending command: {}. Return from send is {}. Retry: {}".format(self._name, self._sendingcommand, sending, self._resend_counter)) - if self._resend_counter >= 2: - self.logger.debug("Processing Response {}: Stop resending command {} and sending back error.".format(self._name, self._sendingcommand)) - self._resend_counter = 0 - yield 'ERROR' - if self._threadlock_buffer.locked(): self._bufferlock.notify() - - except Exception as err: - buffering = False - try: - if not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup' and not (self._sendingcommand.split(",")[2] == '' or self._sendingcommand.split(",")[2] == ' ' or self._sendingcommand.split(",")[2] == 'none'): - buffering = True - self.logger.debug("Processing Response {}: Error reading.. Error: {}. Sending Command: {}. RS232: {}, Host: {}, Socket: {}".format(self._name, err, self._sendingcommand, self._rs232, self._tcp, socket)) - if self._rs232 and (socket == self._serialwrapper or socket == self._serial): - self.logger.warning("Processing Response {}: Problems buffering RS232 response. Error: {}. Increasing timeout temporarily.".format(self._name, err)) - self._wait(1) - socket.timeout = 2 - sending = self._send(self._sendingcommand, 'getresponse') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - if socket == self._serial: - buffer = socket.readline().decode('utf-8') - else: - buffer = socket.read() - socket.timeout = 0.3 - self.logger.debug("Processing Response {}: Error reading.. Return from send is {}. Error: {}".format(self._name, sending, err)) - if self._tcp and socket == self._socket: - self.logger.warning("Processing Response {}: Problems buffering TCP response. Error: {}. Increasing timeout temporarily.".format(self._name, err)) - self._wait(1) - socket.settimeout(4) - sending = self._send(self._sendingcommand, 'getresponse') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - self.logger.debug("Processing Response {}: Error reading.. Return from send is {}. Error: {}".format(self._name, sending, err)) - buffer = socket.recv(4096).decode('utf-8') - socket.settimeout(1) - except Exception as err: - buffering = False - self.logger.error("Processing Response {}: Connection error. Error: {} Resend Counter: {}. Resend Max: {}".format( - self._name, err, self._resend_counter, self._resend_retries)) - yield 'ERROR' - if self._threadlock_buffer.locked(): self._bufferlock.notify() - - while buffering: - if '\r\n' in buffer: - (line, buffer) = buffer.split("\r\n", 1) - #self.logger.debug("Processing Response {}: \r\nBuffer: {}Line: {}. Response buffer: {}, force buffer: {}".format(self._name, buffer, line,self._response_buffer, self._force_buffer)) - if not ('' in self._force_buffer and len(self._force_buffer) == 1) and (self._response_buffer == False or self._response_buffer == 0): - if not re.sub('[ ]','', buffer) == '' and not re.sub('[ ]','', line) == '': - bufferlist = [] - for buf in self._force_buffer: - try: - if buf in buffer and not buf.startswith(tuple(self._ignoreresponse)) and not '' in self._ignoreresponse: - start = buffer.index(buf) - #self.logger.debug("Processing Response {}: Testing forcebuffer {}. Bufferlist: {}. Start: {}".format(self._name, buf,bufferlist, start)) - if not buffer.find('\r\n', start) == -1: - end = buffer.index('\r\n', start) - if not buffer[start:end] in bufferlist and not buffer[start:end] in line: - bufferlist.append(buffer[start:end]) - else: - if not buffer[start:] in bufferlist and not buffer[start:] in line: - bufferlist.append(buffer[start:]) - self.logger.debug("Processing Response {}: Forcebuffer {} FOUND in buffer. Bufferlist: {}. Buffer: {}".format( - self._name, buf, bufferlist, buffer)) - except Exception as err: - self.logger.warning( - "Processing Response {}: Problems while buffering. Error: {}".format(self._name, err)) - if bufferlist: - buffer = '\r\n'.join(bufferlist) - buffer = tidy(buffer) - else: - self.logger.debug("Processing Response {}: No forced buffer found.".format(self._name)) - pass - # Delete consecutive duplicates - buffer = '\r\n'.join([x[0] for x in groupby(buffer.split("\r\n"))]) - if '{}\r\n'.format(line) == buffer: - buffer = '' - self.logger.debug( - "Processing Response {}: Clearing buffer because it's the same as Line: {}".format(self._name, line)) - line = re.sub('[\\n\\r]', '', line).strip() - if not line.startswith(tuple(self._response_commands)) and not line.startswith(tuple(self._errorresponse)) and not '' in self._errorresponse: - #self.logger.debug("Processing Response {}: Response {} is not in possible responses for items. Sending Command: {}".format(self._name, line, self._sendingcommand)) - pass - elif line.startswith(tuple(self._ignoreresponse)) and not '' in self._ignoreresponse: - try: - compare = self._send_commands[0].split(",")[2].split("|") - for comp in compare: - if line.startswith(comp): - keyfound = True - else: - keyfound = False - if keyfound == True: - self._send_commands.pop(0) - self._sendingcommand = 'done' - self.logger.debug("Processing Response {}: Response {} is same as expected {}. Removing command from send list. It is now: {}. Ignore responses are: {}".format(self._name, line, compare, self._send_commands, self._ignoreresponse)) - sending = self._send('command', 'commandremoval') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - #self.logger.debug("Processing Response {}: Return from send is {}.".format(self._name, sending)) - except Exception as err: - #self.logger.debug("Processing Response {}: Response {} is ignored. Command list is now: {}. Error: {}".format(self._name, line, self._send_commands, err)) - pass - elif not line.startswith(tuple(self._ignoreresponse)) and line.startswith(self._specialcommands['Display']['Command']) and not self._response_buffer == False and not '' in self._ignoreresponse and not self._specialcommands['Display']['Command'] == '': - #self.logger.debug( - # "Processing Response {}: Detected Display info {}. buffer: \r\n{}".format(self._name, line, buffer)) - buffering = False - buffer += '\r\n{}\r\n'.format(line) - buffer = tidy(buffer) - #self.logger.debug( - # "Processing Response {}: Append Display info {} to buffer: \r\n{}".format(self._name, line, buffer)) - else: - if self._response_buffer == False and not buffer.startswith(tuple(self._force_buffer)) and not '' in self._force_buffer: - buffering = False - self.logger.debug( - "Processing Response {}: Clearing buffer: {}".format(self._name, buffer)) - buffer = '\r\n' - #self.logger.debug("Processing Response {}: Sending back line: {}. Display Command: {}".format(self._name, line, self._specialcommands['Display']['Command'])) - yield "{}".format(line) - if self._threadlock_buffer.locked(): self._bufferlock.notify() - else: - try: - if self._rs232 and (socket == self._serialwrapper or socket == self._serial): - if socket == self._serial: - more = socket.readline().decode('utf-8') - else: - more = socket.read() - if self._tcp and socket == self._tcp: - more = socket.recv(4096).decode('utf-8') - morelist = more.split("\r\n") - if buffer.find('\r\n') == -1 and len(buffer) > 0: - buffer += '\r\n' - buffer += '\r\n'.join([x[0] for x in groupby(morelist)]) - except Exception as err: - buffering = False - finally: - buffering = False - #self.logger.debug("Processing Response {}: Buffering false.".format(self._name)) - - if not buffer == '\r\n' and self._response_buffer == True or type(self._response_buffer) is int: - buffer = tidy(buffer) - bufferlist = buffer.split('\r\n') - # Removing everything except last x lines - maximum = abs(self._response_buffer) if type(self._response_buffer) is int else 11 - multiplier = 1 if self._response_buffer >= 0 else -1 - #if len(bufferlist) > 1: self.logger.debug("Bufferlist before: {}. Max: {}, Multiply: {}".format(bufferlist, maximum, multiplier)) - while '' in bufferlist: bufferlist.remove('') - newbuffer = [] - for buf in bufferlist: - if not buf.startswith(tuple(self._ignoreresponse)) and not '' in self._ignoreresponse and buf.startswith(tuple(self._response_commands)): - newbuffer.append(buf) - bufferlist = newbuffer[-1 * max(min(len(newbuffer), maximum), 0):] - - if len(bufferlist) > 1: self.logger.debug("Bufferlist after: {}".format(bufferlist)) - buffering = False - for buf in bufferlist: - if not re.sub('[ ]','',buf) == '' and not buf.startswith(tuple(self._ignoreresponse)) and not '' in self._ignoreresponse: - self.logger.debug( - "Processing Response {}: Sending back {} from buffer because Responsebuffer is activated.".format(self._name, buf)) - if self._threadlock_buffer.locked(): self._bufferlock.notify() - self._wait(0.2) - yield buf - - elif not buffer == '\r\n': # and self._force_buffer: - buffer = tidy(buffer) - bufferlist = buffer.split('\r\n') - # Removing everything except last 3 lines - maximum = abs(self._response_buffer) if type(self._response_buffer) is int else 11 - multiplier = 1 if self._response_buffer >= 0 else -1 - bufferlist = bufferlist[multiplier * max(min(len(bufferlist), maximum), 0):] - buffering = False - for buf in bufferlist: - if not re.sub('[ ]','',buf) == '' and not buf.startswith(tuple(self._ignoreresponse)) and not '' in self._ignoreresponse: - self.logger.debug( - "Processing Response {}: Sending back {} from filtered buffer: {}.".format(self._name, buf, buffer)) - if self._threadlock_buffer.locked(): self._bufferlock.notify() - self._wait(0.2) - yield buf - except Exception as err: - self.logger.error( - "Processing Response {}: Problems occured. Message: {}".format(self._name, err)) - finally: - if self._threadlock_buffer.locked(): self._bufferlock.release() - - - def run(self): - if self._tcp is None and self._rs232 is None: - self.logger.error("Initializing {}: Neither IP address nor RS232 port given. Not running.".format(self._name)) - else: - if not self._lock.acquire(timeout=2): - return - try: - try: - self._dependson = self._sh.return_item(self._dependson) - self.logger.debug("Initializing {}: Dependson Item: {}.".format(self._name, self._dependson)) - except: - self._dependson = None - self.logger.warning("Initializing {}: Dependson Item {} is no valid item.".format(self._name, self._dependson)) - self.logger.debug("Initializing {}: Running. Lock is {}".format( - self._name, self._threadlock_standard.locked())) - self.alive = True - self.logger.debug("Initializing {}: Items: {}".format(self._name, self._items)) - self.logger.debug("Initializing {}: Speaker Items: {}".format(self._name, self._items_speakers)) - except Exception as err: - self.logger.error( - "Initializing {}: Problem running and creating items. Error: {}".format(self._name, err)) - finally: - if self._threadlock_standard.locked(): self._lock.release() - self.logger.debug("Initializing {}: Running. Lock is released. Now it is {}".format( - self._name, self._threadlock_standard.locked())) - if not self._tcp is None or not self._rs232 is None: - self._read_commandfile() - - - def connect(self): - self._trigger_reconnect = True - self.logger.debug("Connecting {}: Starting to connect. Current Connections: {}".format(self._name, self._is_connected)) - if not self._lock.acquire(timeout=2): - return - try: - dependsvalue = self._dependson() - - if dependsvalue == self._dependson_value: depending = False - else: - depending = True - self._is_connected = [] - self.logger.debug("Connecting {}: Connection depends on {}. It's value is {}, has to be {}. Connections are {}".format(self._name, self._dependson, dependsvalue, self._dependson_value, self._is_connected)) - except Exception as e: - depending = False - self.logger.debug("Connecting {}: Depending is false. Message: {}".format(self._name, e)) - finally: - if self._threadlock_standard.locked(): self._lock.release() - if depending == False: - if self._tcp is not None and 'TCP' not in self._is_connected: - self._sh.scheduler.change('avdevice-tcp-reconnect', active=True) - self._sh.scheduler.trigger('avdevice-tcp-reconnect') - self._trigger_reconnect = False - if self._rs232 is not None and 'Serial' not in self._is_connected: - self._sh.scheduler.change('avdevice-serial-reconnect', active=True) - self._sh.scheduler.trigger('avdevice-serial-reconnect') - self._trigger_reconnect = False - - def connect_tcp(self): - if not self._lock.acquire(timeout=2): - return - try: - if self._tcp is not None and 'TCP' not in self._is_connected: - self.logger.debug("Connecting TCP {}: Starting to connect to {}.".format(self._name, self._tcp)) - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.setblocking(0) - self._socket.settimeout(6) - self._socket.connect(('{}'.format(self._tcp), int(self._port))) - self._socket.settimeout(1) - self._is_connected.append('TCP') - self.logger.info("Connecting TCP {}: Connected to {}:{}".format( - self._name, self._tcp, self._port)) - - except Exception as err: - if 'TCP' in self._is_connected: - self._is_connected.remove('TCP') - self.logger.warning("Connecting TCP {}: Could not connect to {}:{}. Error:{}. Counter: {}/{}".format( - self._name, self._tcp, self._port, err, self._reconnect_counter, self._reconnect_retries)) - - finally: - if self._threadlock_standard.locked(): self._lock.release() - if ('TCP' not in self._is_connected and self._tcp is not None) and str(self._auto_reconnect.lower()) in ['1', 'yes', 'true', 'on']: - #self._sh.scheduler.change('avdevice-tcp-reconnect', active=True) - self.connect() - self._trigger_reconnect = False - self.logger.warning("Connecting TCP {}: Reconnecting. Command list while connecting: {}.".format( - self._name, self._send_commands)) - elif ('TCP' in self._is_connected and self._tcp is not None) or self._reconnect_counter >= self._reconnect_retries: - self._sh.scheduler.change('avdevice-tcp-reconnect', active=False) - self._reconnect_counter = 0 - self._trigger_reconnect = True - keeptemp = [] - for zeit in self._keep_commands: - keeping = False - if time.time() - zeit <= self._secondstokeep and self._keep_commands[zeit] not in keeptemp: - keeptemp.append(self._keep_commands[zeit]) - keeping = True - self.logger.info("Connecting TCP {}: Age {}s of command {}. Secondstokeep: {}. Keeping command: {}".format( - self._name, int(time.time()-zeit), self._keep_commands[zeit], self._secondstokeep, keeping)) - self._send_commands = list(set(keeptemp)) + self._send_commands - seen = set() - self._send_commands = [x for x in self._send_commands if x not in seen and not seen.add(x)] - self.keep_commands = {} - keeptemp = [] - self.logger.debug("Connecting TCP {}: Deactivating reconnect scheduler. Command list while connecting: {}. Keep Commands: {}".format( - self._name, self._send_commands, self.keep_commands)) - self._reconnect_counter += 1 - if 'TCP' in self._is_connected: - self._wait(1) - self._items['zone0']['statusupdate']['Item'][0](1, 'Init', self._tcp) - self.logger.debug("Connecting TCP {}: Updated Item after connection: {} with value 1. Commandlist: {}".format( - self._name, self._items['zone0']['statusupdate']['Item'][0], self._send_commands)) - self.parse_input() - - - def connect_serial(self): - if not self._lock.acquire(timeout=2): - return - try: - if self._rs232 is not None and 'Serial' not in self._is_connected: - self.logger.debug("Connecting Serial {}: Starting to connect to {}.".format(self._name, self._rs232)) - ser = serial.serial_for_url('{}'.format(self._rs232), baudrate=int(self._baud), timeout=float(self._timeout), write_timeout=float(self._writetimeout)) - i = 0 - while ser.in_waiting == 0: - i += 1 - self._wait(1) - ser.write(bytes('?P\r', 'utf-8')) - buffer = bytes() - buffer = ser.read().decode('utf-8') - self.logger.warning("Connecting Serial {}: Reconnecting Retry: {}".format(self._name, i)) - if i >= self._reconnect_retries or (i >= 4 and self._trigger_reconnect == False): - ser.close() - break - if ser.isOpen(): - self._serialwrapper = io.TextIOWrapper(io.BufferedRWPair(ser, ser), newline='\r\n', encoding='utf-8', line_buffering=True, write_through=True) - self._serialwrapper.timeout = 0.1 - self._serial = ser - self._trigger_reconnect = False - self._is_connected.append('Serial') - self.logger.info("Connecting Serial {}: Connected to {} with baudrate {}.".format( - self._name, ser, self._baud)) - else: - self.logger.warning("Connecting Serial {}: Serial port is not open. Connection status: {}. Reconnect Counter: {}".format(self._name, self._is_connected, self._reconnect_counter)) - except Exception as err: - if 'Serial' in self._is_connected: - self._is_connected.remove('Serial') - self.logger.warning("Connecting Serial {}: Could not connect to {}, baudrate {}. Error:{}".format( - self._name, self._rs232, self._baud, err)) - - finally: - if self._threadlock_standard.locked(): self._lock.release() - if ('Serial' not in self._is_connected and self._rs232 is not None) and str(self._auto_reconnect.lower()) in ['1', 'yes', 'true', 'on']: - #self._sh.scheduler.change('avdevice-serial-reconnect', active=True) - self.connect() - self._trigger_reconnect = False - self.logger.debug("Connecting Serial {}: Activating reconnect scheduler. Command list while connecting: {}.".format( - self._name, self._send_commands)) - elif ('Serial' in self._is_connected and self._rs232 is not None) or self._reconnect_counter >= self._reconnect_retries: - self._sh.scheduler.change('avdevice-serial-reconnect', active=False) - self._reconnect_counter = 0 - self._trigger_reconnect = True - keeptemp = [] - for zeit in self._keep_commands: - keeping = False - if time.time() - zeit <= self._secondstokeep and self._keep_commands[zeit] not in keeptemp: - keeptemp.append(self._keep_commands[zeit]) - keeping = True - self.logger.info("Connecting Serial {}: Age {}s of command {}. Secondstokeep: {}. Keeping command: {}".format( - self._name, int(time.time()-zeit), self._keep_commands[zeit], self._secondstokeep, keeping)) - self._send_commands = list(set(keeptemp)) + self._send_commands - seen = set() - self._send_commands = [x for x in self._send_commands if x not in seen and not seen.add(x)] - self.keep_commands = {} - keeptemp = [] - self.logger.debug("Connecting Serial {}: Deactivating reconnect scheduler. Command list while connecting: {}. Keep commands: {}".format( - self._name, self._send_commands, self.keep_commands)) - #self.logger.debug("Connecting {}: Tried to connect. Lock is released. Now it is {}. Reconnect Retries: {}".format(self._name, self._threadlock_standard.locked(), self._reconnect_counter)) - self._reconnect_counter += 1 - if 'Serial' in self._is_connected: - self._wait(1) - self._items['zone0']['statusupdate']['Item'][0](1, 'Init', self._rs232) - self.logger.debug("Connecting Serial {}: Updated Item after connection: {} with value 1. Sendcommands: {}".format( - self._name, self._items['zone0']['statusupdate']['Item'][0], self._send_commands)) - self.parse_input() - - - def parse_input(self): - while self.alive and not self._is_connected == []: - if not self._parselock.acquire(timeout=2): - return - #self.logger.debug("Parsing Input {}: Starting to parse input. Lock is: {}. Alive: {}. Connected: {}. Sendcommand:{}".format( - # self._name, self._threadlock_standard.locked(), self.alive, self._is_connected, self._sendingcommand)) - to_send = 'command' - try: - data = 'waiting' - databuffer = [] - if 'Serial' in self._is_connected: - try: - databuffer = self._processing_response(self._serialwrapper) - while databuffer is None: - self._bufferlock.wait(2) - self.logger.warning("Waiting for databuffer") - except Exception as err: - self.logger.error( - "Parsing Input {}: Problem receiving Serial data {}.".format(self._name, err)) - elif 'TCP' in self._is_connected: - try: - databuffer = self._processing_response(self._socket) - while databuffer is None: - self._bufferlock.wait(2) - self.logger.warning("Waiting for databuffer") - except Exception as err: - self.logger.error( - "Parsing Input {}: Problem receiving TCP data {}.".format(self._name, err)) - #self.logger.warning('DATABUFFER: {}. Data: {}'.format(databuffer, data)) - for data in databuffer: - data = data.strip() - if data == '' and not self._sendingcommand == '' and not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup': - self.logger.warning('Problem') - if data == 'ERROR' and not self._sendingcommand == 'gaveup' and not self._sendingcommand == 'done': - if self._resend_counter >= self._resend_retries: - self.logger.warning("Parsing Input {}: Giving up Sending {} and removing from list. Received Data: {}. Original Commandlist: {}".format( - self._name, self._sendingcommand, data, self._send_commands)) - self._resend_counter = 0 - self._requery_counter = 0 - # Resetting Item if Send not successful - if self._reset_onerror == True: - resetting = self._resetitem() - while resetting is None: - self._resetlock.wait(2) - self.logger.warning("Waiting for resetting") - self.logger.warning("Parsing Input {}: Connection Error: {}. Resetting Item: {}.".format( - self._name, data, resetting)) - try: - if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._specialcommands['Display']['Command']: - self._keep_commands[time.time()] = self._send_commands[0] - self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) - self._send_commands.pop(0) - if not self._send_commands == []: - sending = self._send('command', 'parseinput') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - self.logger.debug("Parsing Input {}: Command List is now: {}. Sending return is {}.".format( - self._name, self._send_commands, sending)) - except Exception as err: - self.logger.debug( - "Parsing Input {}: Nothing to remove from Send Command List. Error: {}".format(self._name, err)) - self._sendingcommand = 'gaveup' - if self._trigger_reconnect == True: - self.connect() - self.logger.debug("Parsing Input {}: Trying to connect while parsing item".format(self._name)) - else: - self._resend_counter += 1 - - sorted_response_commands = sorted(self._response_commands, key=len, reverse=True) - self.logger.debug("Parsing Input {}: Response: {}.".format(self._name, data)) - if not self._send_commands == []: - expectedresponse = [] - self.logger.debug("Parsing Input {}: Parsing input while waiting for response. Lock is: {}".format(self._name, self._threadlock_parse.locked())) - try: - for response in self._send_commands: - if not response.split(",")[2] == '': expectedresponse.append(response.split(",")[2]) - self.logger.debug("Parsing Input {}: Expected response while parsing: {}.".format(self._name, expectedresponse)) - except Exception as err: - self.logger.error("Parsing Input {}: Problems creating expected response list. Error: {}".format(self._name, err)) - try: - to_send = 'command' - updatedcommands = [] - for expected in expectedresponse: - expectedlist = expected.split("|") - - if self._manufacturer == 'epson' and (data == ':PWR=02' or data == 'PWR=02'): - data = 'PWR=01' - data = re.sub('ON$', '1', data) - data = re.sub('OFF$', '0', data) - - if data.startswith(tuple(expectedlist)): - entry, value = self._write_itemsdict(data) - self.logger.debug("Parsing Input {}: got entry {}. Value: {}".format( - self._name, entry, value)) - while value is None or entry is None: - self.logger.debug("Parsing Input {}: waiting for dict writing.".format(self._name)) - self._dictlock.wait(2) - self.logger.debug("Parsing Input {}: FOUND {}. Written to dict: {}".format( - self._name, expectedlist, entry)) - self._sendingcommand = 'done' - self._requery_counter = 0 - self._resend_counter = 0 - elif expectedlist[0] == '' or expectedlist[0] == ' ' or expectedlist[0] == 'none': - self._sendingcommand = 'done' - self._requery_counter = 0 - self._resend_counter = 0 - self.logger.debug( - "Parsing Input {}: No response expected".format(self._name)) - elif expectedlist[0].lower() == 'string': - value = data - self.logger.debug( - "Parsing Input {}: String found and testing... ".format(self._name)) - if value.startswith(tuple(self._response_commands.keys())): - self.logger.debug( - "Parsing Input {}: Found string but ignored because it is a legit response for another command.".format(self._name)) - else: - entry, value = self._write_itemsdict(data) - self.logger.debug( - "Parsing Input {}: String FOUND. Written to dict: {}.".format(self._name, entry)) - self._sendingcommand = 'done' - self._requery_counter = 0 - self._resend_counter = 0 - else: - expectedindex = expectedresponse.index(expected) - updatedcommands.append(self._send_commands[expectedindex]) - - self._send_commands = updatedcommands - #self.logger.debug("Parsing Input {}: Sendcommands: {}. Sendingcommand: {}".format(self._name, self._send_commands, self._sendingcommand)) - - if not self._send_commands == [] and not self._sendingcommand == 'done': - self._requery_counter += 1 - try: - dependsvalue = self._dependson() - self.logger.debug("Parsing Input {}: Parsing depends on {}. It's value is {}, has to be {}.".format(self._name, self._dependson, dependsvalue, self._dependson_value)) - if dependsvalue == self._dependson_value: - depending = False - else: - depending = True - self._resetondisconnect('parseinput') - except Exception as err: - depending = False - self.logger.debug("Parsing Input {}: Depending is false. Message {}.".format(self._name, err)) - - if self._requery_counter >= self._resend_retries: - self._requery_counter = 0 - self._resend_counter = 0 - if not self._send_commands[0] in self._query_commands and not self._send_commands == []: - self._sendingcommand = self._send_commands[0] - self.logger.warning("Parsing Input {}: Going to reset item {}.".format(self._name, self._sendingcommand)) - resetting = self._resetitem() - while resetting is None: - self.logger.warning("Parsing Input {}: Waiting for resetting".format(self._name)) - self._resetlock.wait(2) - self.logger.debug("Parsing Input {}: Giving up Re-Query: {}. Resetting Item: {}".format( - self._name, self._sendingcommand, resetting)) - self._sendingcommand = 'gaveup' - if data == 'ERROR': - if 'Serial' in self._is_connected: - self._is_connected.remove('Serial') - self._trigger_reconnect = True - if 'TCP' in self._is_connected: - self._is_connected.remove('TCP') - self._trigger_reconnect = True - if self._trigger_reconnect == True: - self.connect() - self.logger.debug("Parsing Input {}: Trying to connect while parsing item".format(self._name)) - if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._specialcommands['Display']['Command']: - self._keep_commands[time.time()] = self._send_commands[0] - self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) - self._send_commands.pop(0) - #self.logger.debug("Parsing Input {}: Send commands are now: {}".format(self._name, self._send_commands)) - elif depending == True: - self._requery_counter = 0 - self._resend_counter = 0 - if not self._send_commands[0] in self._query_commands and not self._send_commands == []: - self._sendingcommand = self._send_commands[0] - self.logger.warning("Parsing Input {}: Reset item {} because dependency not fulfilled.".format(self._name, self._sendingcommand)) - resetting = self._resetitem() - while resetting is None: - self.logger.warning("Parsing Input {}: Waiting for resetting".format(self._name)) - self._resetlock.wait(2) - self.logger.debug("Parsing Input {}: Giving up Re-Query: {}. Resetting Item: {}".format( - self._name, self._sendingcommand, resetting)) - self._sendingcommand = 'gaveup' - if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._specialcommands['Display']['Command']: - self._keep_commands[time.time()] = self._send_commands[0] - self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) - self._send_commands.pop(0) - self.logger.debug("Parsing Input {}: Keepcommands: {}. Sendcommands: {}".format( - self._name, self._keep_commands, self._send_commands)) - elif not self._sendingcommand == 'gaveup': - # self._send(self._send_commands[0].split(",")[1]) - # self._send('query','parseinput') - to_send = 'query' if self._requery_counter % 2 == 1 else 'command' - self._wait(self._resend_wait) - self.logger.debug("Parsing Input {}: Requesting {} from {} because response was {}. Requery Counter: {}".format(self._name, to_send, self._send_commands[0], data, self._requery_counter)) - except Exception as err: - self.logger.warning("Parsing Input {}: Problems with checking for expected response. Error: {}".format(self._name, err)) - - #self.logger.debug("Parsing Input {}: Starting comparing values".format(self._name)) - for key in sorted_response_commands: - commandlength = self._response_commands[key][1] - valuelength = self._response_commands[key][0] - item = self._response_commands[key][3] - title = '' - station = '' - index = data.find(key) - if not index == -1: - inputcommands = self._specialcommands['Input']['Command'] - function = self._response_commands[key][4] - zone = self._response_commands[key][5] - if data.startswith(self._specialcommands['Display']['Command']) and not self._specialcommands['Display']['Command'] == '': - self.logger.debug( - "Parsing Input {}: Displaycommand found in response {}.".format(self._name, data)) - try: - content = data[2:][:28] - self.logger.debug("AVDevice {}: Display Data {}. Item: {}".format( - self._name, content, item)) - tempvalue = "".join( - list(map(lambda i: chr(int(content[2 * i:][: 2], 0x10)), range(14)))).strip() - receivedvalue = re.sub(r'^[^A-Z0-9]*', '', tempvalue) - self.logger.debug("AVDevice {}: Display Output {}".format( - self._name, receivedvalue)) - except Exception as err: - self.logger.warning("AVDevice {}: Problems getting display info. Error: {}".format(self._name, err)) - - elif data.startswith(tuple(self._specialcommands['Nowplaying']['Command'])) and not self._specialcommands['Nowplaying']['Command'] == '': - self.logger.debug("AVDevice {}: Now playing info found in response {}.".format(self._name, data)) - try: - m = re.search('"(.+?)"', data) - if m: - receivedvalue = m.group(1) - else: - receivedvalue = '' - except Exception as err: - self.logger.debug("AVDevice {}: Problems reading Now Playing info. Error:{}".format(self._name, err)) - elif data.startswith(tuple(self._specialcommands['Speakers']['Command'])) and not self._specialcommands['Speakers']['Command'] == '': - self.logger.debug("AVDevice {}: Speakers info found in response {}. Command: {}".format(self._name, data, self._specialcommands['Speakers']['Command'])) - receivedvalue = data[index + commandlength:index + commandlength + valuelength] - try: - for speakercommand in self._specialcommands['Speakers']['Command']: - for zone in self._items_speakers: - for speakerlist in self._items_speakers[zone]: - speakerAB = sum(map(int, self._items_speakers[zone].keys())) - self.logger.debug("AVDevice {}: Received value: {}. Speaker {}. SpeakerAB: {}".format( - self._name, receivedvalue, speakerlist, speakerAB)) - if receivedvalue == '{}'.format(speakerlist) or receivedvalue == '{}'.format(speakerAB): - for speaker in self._items_speakers[zone][speakerlist]['Item']: - self.logger.info("AVDevice {}: Speaker {} is on.".format(self._name, speaker)) - speaker(1, 'AVDevice', self._tcp) - else: - for speaker in self._items_speakers[zone][speakerlist]['Item']: - self.logger.info("AVDevice {}: Speaker {} is off.".format(self._name, speaker)) - speaker(0, 'AVDevice', self._tcp) - - except Exception as err: - self.logger.warning("AVDevice {}: Problems reading Speakers info. Error:{}".format(self._name, err)) - else: - if self._manufacturer == 'pioneer': - receivedvalue = data[index + commandlength:index + commandlength + valuelength] - else: - receivedvalue = data[index + commandlength:] - self.logger.debug("Parsing Input {}: Neither Display nor Now Playing in response. receivedvalue: {}.".format(self._name, receivedvalue)) - if not receivedvalue.isdigit() and self._response_commands[key][7] == 'num': - self.logger.warning("Parsing Input {}: Receivedvalue {} is not num as defined in the txt-file.".format(self._name, receivedvalue)) - - - if data.startswith(tuple(inputcommands)) and receivedvalue in self._ignoredisplay and not '' in self. _ignoredisplay: - for i in range(0,len(inputcommands)): - if data.startswith(inputcommands[i]): - self._specialcommands['Input']['Ignore'][i] = 1 - if not self._specialcommands['Display']['Command'] in self._ignoreresponse and not self._specialcommands['Display']['Command'] == '' and not '' in self._ignoreresponse: - self._ignoreresponse.append(self._specialcommands['Display']['Command']) - self.logger.error("Parsing Input {}: Data {} has value in ignoredisplay {}. Ignorecommands are now: {}. Display Ignore is {}. Input Ignore is {}".format(self._name, data, self._ignoredisplay, self._ignoreresponse, self._specialcommands['Display']['Ignore'], self._specialcommands['Input']['Ignore'])) - elif data.startswith(tuple(inputcommands)) and not receivedvalue in self._ignoredisplay and not '' in self. _ignoredisplay: - for i in range(0,len(inputcommands)): - if data.startswith(inputcommands[i]): - self._specialcommands['Input']['Ignore'][i] = 0 - #self.logger.debug("Parsing Input {}: Data {} has NO value in ignoredisplay {}. Ignorecommands are now: {}. Display Ignore is {}. Input Ignore is {}".format(self._name, data, self._ignoredisplay, self._ignoreresponse, self._specialcommands['Display']['Ignore'], self._specialcommands['Input']['Ignore'])) - if self._specialcommands['Display']['Ignore'] == 0 and not 1 in self._specialcommands['Input']['Ignore']: - while self._specialcommands['Display']['Command'] in self._ignoreresponse: - self._ignoreresponse.remove(self._specialcommands['Display']['Command']) - #self.logger.warning("Parsing Input {}: Removing {} from ignore.".format(self._name, self._specialcommands['Display']['Command'])) - value = receivedvalue - if self._response_commands[key][6].lower() in ['1', 'true', 'yes', 'on']: - value = False if int(receivedvalue) > 0 else True - self.logger.debug("Parsing Input {}: Inverting value for item {}. Original Value: {}, New Value: {}".format( - self._name, item, receivedvalue, value)) - - self.logger.debug("Parsing Input {}: Found key {} in response at position {} with value {}.".format( - self._name, key, index, value)) - # for weird situations where the device sends back a higher value than 1 even it is bool. - if self._response_commands[key][7] == 'bool': - if self._manufacturer.lower() == 'epson': - try: - value = max(min(int(value), 1), 0) - self.logger.debug("Parsing Input {}: Limiting bool value for {} with received value {} to {}.".format( - self._name, self._items[zone][function], receivedvalue, value)) - except: - pass - if receivedvalue.lower() == 'on' or receivedvalue == 1: - value = True - if receivedvalue.lower() == 'off' or receivedvalue == 0: - value = False - - - if function in self._items[zone].keys(): - if self._response_commands[key][7] == 'bool' and (value == True or value == False): - self._items[zone][function]['Value'] = value - if self._response_commands[key][7] == 'num' and value.isdigit(): - self._items[zone][function]['Value'] = value - if self._response_commands[key][7] == 'string' and isinstance(value, str): - self._items[zone][function]['Value'] = value - - for singleitem in item: - if self._response_commands[key][7] == 'bool' and (value == True or value == False): - singleitem(value, 'AVDevice', self._tcp) - self.logger.debug("Parsing Input {}: Updating Item {} with Boolean Value: {}.".format( - self._name, item, value)) - self._wait(0.15) - elif self._response_commands[key][7] == 'num' and value.isdigit(): - singleitem(value, 'AVDevice', self._tcp) - self.logger.debug("Parsing Input {}: Updating Item {} with number Value: {}.".format( - self._name, item, value)) - self._wait(0.15) - elif self._response_commands[key][7] == 'string' and isinstance(value, str): - singleitem(value, 'AVDevice', self._tcp) - self.logger.debug("Parsing Input {}: Updating Item {} with string Value: {}.".format( - self._name, item, value)) - self._wait(0.15) - - break - elif key.lower() == 'string': - value = data - if value.startswith(tuple(sorted_response_commands)): - self.logger.debug("Parsing Input {}: Found string for Item {} with Value {} but ignored because it is a legit response for another command.".format( - self._name, item, value)) - pass - else: - for singleitem in item: - singleitem(value, 'AVDevice', self._tcp) - self._wait(0.15) - self.logger.debug("Parsing Input {}: Updating item {} with value {}".format( - self._name, singleitem, value)) - break - #self.logger.debug("Parsing Input {}: Finished comparing values".format(self._name)) - except Exception as err: - self.logger.error( - "Parsing Input {}: Problems parsing input. Error: {}".format(self._name, err)) - finally: - if self._threadlock_parse.locked(): self._parselock.release() - if not self._send_commands == [] and data == 'waiting': - pass - #self.logger.warning('Vermutlich ein Verbindungsproblem!') - if not self._send_commands == [] and not data == 'waiting': - reorderlist = [] - index = 0 - for command in self._send_commands: - if command in self._query_commands: - reorderlist.append(command) - elif command in self._power_commands: - self.logger.debug("Parsing Input {}: Ordering power command {} to first position.".format( - self._name, command)) - reorderlist.insert(0,command) - index +=1 - else: - reorderlist.insert(index,command) - index +=1 - self._send_commands = reorderlist - - self.logger.debug('Parsing Input {}: Newly sorted send commands at end of parsing: {}'.format(self._name, self._send_commands)) - if self._is_connected == []: - for command in self._send_commands: - self.logger.warning("Parsing Input {}: Going to reset {}.".format(self._name, command)) - if command not in self._query_commands and not command in self._specialcommands['Display']['Command']: - self._keep_commands[time.time()] = self._sendingcommand = command - self.logger.debug("Parsing Input {}: Removing item {} from send command because not connected, storing in keep commands: {}.".format( - self._name, command, self._keep_commands)) - resetting = self._resetitem() - while resetting is None: - self._resetlock.wait(2) - self.logger.warning("Waiting for resetting") - self._send_commands.pop(0) - else: - sending = self._send('{}'.format(to_send),'parseinput_final') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - self.logger.debug("Parsing Input {}: Sending again because list is not empty yet. Sending return is {}. Lock is released. Now it is {}.".format( - self._name, sending, self._threadlock_parse.locked())) - - def update_item(self, item, caller=None, source=None, dest=None): - if self.alive: - if caller != 'AVDevice': - if not self._updatelock.acquire(timeout=2): - return - try: - emptycommand = False - self.logger.debug("Updating Item for avdevice_{}: Starting to update item {}. Lock is: {}. Reconnectrigger is {}".format( - self._name.lower(), item.id(), self._threadlock_update.locked(), self._trigger_reconnect)) - # connect if necessary - if self._trigger_reconnect == True: - self.logger.debug("Updating Item for avdevice_{}: Trying to connect while updating item".format(self._name.lower())) - self.connect() - - if 'a' == 'a': - self.logger.debug("Updating Item for avdevice_{}: {} trying to update {}".format( - self._name.lower(), caller, item.id())) - # looping through all zones and testing for keyword avdevice_zone[n] - if item == self._dependson: - try: - dependsvalue = self._dependson() - if dependsvalue == self._dependson_value: depending = False - else: depending = True - except Exception as e: - depending = False - if depending == False: - self._items['zone0']['statusupdate']['Item'][0](1, 'Depending', self._rs232) - self.logger.debug("Updating Item for avdevice_{}: Depend value is same as set up, statusupdate starting {}.".format(self._name.lower(), self._items['zone0']['statusupdate']['Item'][0])) - elif depending == True: - self.logger.debug("Updating Item for avdevice_{}: Depend value is false.".format(self._name.lower())) - self._resetondisconnect('updateitem') - for zone in range(0, self._number_of_zones+1): - if self.has_iattr(item.conf, 'avdevice'): - command = self.get_iattr_value(item.conf, 'avdevice') - zoneX = True - elif self.has_iattr(item.conf, 'avdevice_zone{}_speakers'.format(zone)): - command = 'speakers' - zoneX = True - self.logger.debug("Updating Item for avdevice_{}: Command is {}. Zone is {}".format(self._name.lower(), command, zone)) - else: - zoneX = False - if self.has_iattr(item.conf, 'avdevice_zone{}'.format(zone)) or zoneX == True: - if zoneX == False: - command = self.get_iattr_value(item.conf, 'avdevice_zone{}'.format(zone)) - command_on = '{} on'.format(command) - command_off = '{} off'.format(command) - command_set = '{} set'.format(command) - value = item() - updating = True - sending = True - - try: - if command is None: - command = '{} on'.format(command) - if command is None or command == 'None on': - command = '{} off'.format(command) - if command is None or command == 'None off': - command = '{} set'.format(command) - if self._functions['zone{}'.format(zone)][command][2] == '': - emptycommand = True - self.logger.debug("Updating Item for avdevice_{}: Function is empty. Sending nothing. Command: {} value: {}".format( - self._name.lower(), command, item())) - if command == 'statusupdate': - if (item() == True or caller == 'Init') and not self._specialcommands['Display']['Ignore'] >= 5: - if not self._is_connected == []: - keeptemp = [] - for zeit in self._keep_commands: - keeping = False - if time.time() - zeit <= self._secondstokeep and not self._keep_commands[zeit] in keeptemp: - keeptemp.append(self._keep_commands[zeit]) - keeping = True - self.logger.debug("Updating Item for avdevice_{}: Age {}s of command {}. Secondstokeep: {}. Keeping command: {}".format( - self._name.lower(), int(time.time()-zeit), self._keep_commands[zeit], self._secondstokeep, keeping)) - self._send_commands = list(set(keeptemp)) + self._send_commands - seen = set() - self._send_commands = [x for x in self._send_commands if x not in seen and not seen.add(x)] - self._keep_commands = {} - keeptemp = [] - for query in self._query_commands: - if not query in self._send_commands: - self._send_commands.append(query) - self._reconnect_counter = 0 - self._requery_counter = 0 - self._trigger_reconnect = True - self.logger.debug("Updating Item for avdevice_{}: Updating status. Querycommands: {}. Reconnecttrigger: {}. Display Ignore: {}".format(self._name.lower(), self._send_commands, self._trigger_reconnect, self._specialcommands['Display']['Ignore'])) - elif item() == False and not self._specialcommands['Display']['Ignore'] >= 5: - try: - dependsvalue = self._dependson() - self.logger.debug("Updating Item for avdevice_{}: Connection depends on {}. It's value is {}, has to be {}. Connections are {}".format(self._name.lower(), self._dependson, dependsvalue, self._dependson_value, self._is_connected)) - if dependsvalue == self._dependson_value: depending = False - else: depending = True - except Exception as e: - depending = False - self.logger.debug("Updating Item for avdevice_{}: Depending is false. Message: {}".format(self._name.lower(), e)) - if depending == True or self._is_connected == []: - self._resetondisconnect('statusupdate') - elif self._specialcommands['Display']['Ignore'] >= 5: - sending = False - - updating = False - - elif self._functions['zone{}'.format(zone)][command][5].lower() == 'r': - self.logger.warning("Updating Item for avdevice_{}: Function is read only. Not updating. Command: {}".format( - self._name.lower(), command)) - updating = False - # Re-query Item to update value - commandinfo = self._functions['zone{}'.format(zone)][command] - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4])) - - except Exception as err: - self.logger.debug("Updating Item for avdevice_{}: Command {} is a standard command. Message: {}".format( - self._name.lower(), command, err)) - - if updating == True: - self.logger.debug("Updating Item for avdevice_{}: {} set {} to {} for {} in zone {}".format( - self._name.lower(), caller, command, value, item.id(), zone)) - self._trigger_reconnect = True - if command in self._functions['zone{}'.format(zone)] and isinstance(value, bool): - commandinfo = self._functions['zone{}'.format(zone)][command] - if commandinfo[2] in self._send_commands: - self.logger.debug("Updating Item for avdevice_{}: Command {} already in Commandlist. Ignoring.".format( - self._name.lower(), commandinfo[2])) - else: - self.logger.debug("Updating Item for avdevice_{}: Updating Zone {} Commands {} for {}".format( - self._name.lower(), zone, self._send_commands, item)) - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4])) - elif command_on in self._functions['zone{}'.format(zone)] and isinstance(value, bool) and value == 1: - commandinfo = self._functions['zone{}'.format(zone)][command_on] - if commandinfo[2] in self._send_commands: - self.logger.debug("Updating Item for avdevice_{}: Command On {} already in Commandlist {}. Ignoring.".format( - self._name.lower(), commandinfo[2], self._send_commands)) - else: - try: - replacedvalue = '1' - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('**', replacedvalue))) - self._sendingcommand = '{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('**', replacedvalue)) - except: - if commandinfo[6].lower() in ['1', 'true', 'yes', 'on']: - replacedvalue = '0' - else: - replacedvalue = '1' - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('*', replacedvalue))) - self._sendingcommand = '{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('*', replacedvalue)) - self.logger.debug("Updating Item for avdevice_{}: Update Zone {} Command On {} for {}".format( - self._name.lower(), zone, commandinfo[2], item)) - if command_on == 'power on': - self.logger.debug("Updating Item for avdevice_{}: Command Power On for zone: {}. Appending relevant query commands: {}".format( - self._name.lower(), zone, self._query_zonecommands['zone{}'.format(zone)])) - for query in self._query_zonecommands['zone{}'.format(zone)]: - if not query in self._send_commands: - self._send_commands.append(query) - - elif command_off in self._functions['zone{}'.format(zone)] and isinstance(value, bool) and value == 0: - commandinfo = self._functions['zone{}'.format(zone)][command_off] - if commandinfo[2] in self._send_commands: - self.logger.debug("Updating Item for avdevice_{}: Command Off {} already in Commandlist {}. Ignoring.".format( - self._name.lower(), commandinfo[2], self._send_commands)) - #self._send_commands[self._send_commands.index(sendcommand)] = commandinfo - else: - try: - replacedvalue = '0' - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('***', replacedvalue))) - self._sendingcommand = '{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('***', replacedvalue)) - except: - if commandinfo[6].lower() in ['1', 'true', 'yes', 'on']: - replacedvalue = '1' - else: - replacedvalue = '0' - self._send_commands.append('{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('*', replacedvalue))) - self._sendingcommand = '{},{},{}'.format( - commandinfo[2], commandinfo[3], commandinfo[4].replace('*', replacedvalue)) - self.logger.debug("Updating Item for avdevice_{}: Update Zone {} Command Off {} for {}".format( - self._name.lower(), zone, commandinfo[2], item)) - elif command_set in self._functions['zone{}'.format(zone)] and isinstance(value, int): - commandinfo = self._functions['zone{}'.format(zone)][command_set] - try: - value = max(min(value, int(commandinfo[7])), 0) - self.logger.debug("Updating Item for avdevice_{}: value limited to {}.".format( - self._name.lower(), commandinfo[7])) - except: - self.logger.debug( - "Updating Item for avdevice_{}: Value limited to specific number of digits".format(self._name.lower())) - if commandinfo[2].count('*') > 1: - anzahl = commandinfo[2].count('*') - self.logger.debug( - "Updating Item for avdevice_{}: Value has to be {} digits.".format(self._name.lower(), anzahl)) - value = max(min(value, int(re.sub('[^0-9]', '', re.sub('\*', '9', commandinfo[2])))), 0) - command_re = re.sub(r'(\*)\1+', '{0:0{1}d}'.format(value, anzahl), commandinfo[2]) - response = re.sub(r'(\*)\1+', '{0:0{1}d}'.format(value, anzahl), commandinfo[4]) - elif commandinfo[2].count('*') == 1: - if command.startswith('speakers'): - currentvalue = int(self._items['zone{}'.format(zone)]['speakers']['Item'][0]()) - multiply = -1 if item() == 0 else 1 - value = abs(int(self.get_iattr_value(item.conf, 'avdevice_zone{}_speakers'.format(zone)))) - powercommands = self._functions['zone{}'.format(zone)]['power on'] - self.logger.debug( - "Updating Item for avdevice_{}: Speaker current value is {}. Multiply: {}. Value: {}".format(self._name.lower(), currentvalue, multiply, value)) - if not currentvalue == value or multiply == -1: - value = currentvalue + (value * multiply) - if value > 0: - if powercommands[6].lower() in ['1', 'true', 'yes', 'on']: - replacedvalue = '0' - else: - replacedvalue = '1' - self._send_commands.insert(0, '{},{},{}'.format(powercommands[2],powercommands[3],powercommands[4].replace('*', replacedvalue))) - self._sendingcommand = '{},{},{}'.format(powercommands[2],powercommands[3],powercommands[4].replace('*', replacedvalue)) - self.logger.debug("Updating Item for avdevice_{}: Turning power on. powercommands is: {}".format(self._name.lower(), powercommands)) - - else: - value = max(min(value, 9), 0) - command_re = commandinfo[2].replace('*', '{0:01d}'.format(value)) - response = commandinfo[4].replace('*', '{0:01d}'.format(value)) - self.logger.debug( - "Updating Item for avdevice_{}: Value has to be 1 digit. Value is {}".format(self._name.lower(), value)) - - elif commandinfo[2].count('*') == 0: - self.logger.error("Updating Item for avdevice_{}: Set command {} does not have any placeholder *.".format(self._name.lower(), commandinfo)) - - if not self._send_commands == []: - appending = True - for sendcommand in self._send_commands: - self.logger.debug("Updating Item for avdevice_{}: Testing send command: {}".format( - self._name.lower(), sendcommand)) - if commandinfo[3] in sendcommand: - self._send_commands[self._send_commands.index(sendcommand)] = self._sendingcommand = '{},{},{}'.format( - command_re, commandinfo[3], response) - self._requery_counter = 0 - self.logger.debug("Updating Item for avdevice_{}: Command Set {} already in Commandlist {}. Replaced. Sendingcommand: {}".format( - self._name.lower(), command, self._send_commands, self._sendingcommand)) - appending = False - break - if appending == True: - self._send_commands.append('{},{},{}'.format(command_re, commandinfo[3], response)) - self._sendingcommand = '{},{},{}'.format(command_re, commandinfo[3], response) - self._requery_counter = 0 - self.logger.debug("Updating Item for avdevice_{}: Update Zone {} Command Set {} for {}. Command: {}".format( - self._name.lower(), zone, commandinfo[2], item, command_re)) - else: - self._send_commands.append('{},{},{}'.format( - command_re, commandinfo[3], response)) - self._requery_counter = 0 - self.logger.debug("Updating Item for avdevice_{}: Update Zone {} Command Set, adding to empty Commandlist {} for {}. Command: {}".format( - self._name.lower(), zone, self._send_commands, item, command_re)) - else: - self.logger.error("Updating Item for avdevice_{}: Command {} not in text file!".format( - self._name.lower(), command)) - updating = False - except Exception as err: - self.logger.error("Updating Item for avdevice_{}: Problem updating item. Error: {}".format( - self._name.lower(), err)) - finally: - if self._threadlock_update.locked(): self._updatelock.release() - if not self._send_commands == []: - reorderlist = [] - index = 0 - for command in self._send_commands: - if command in self._query_commands: - reorderlist.append(command) - else: - reorderlist.insert(index,command) - index +=1 - self._send_commands = reorderlist - self._sendingcommand = self._send_commands[0] - self.logger.debug("Updating Item for avdevice_{}: Updating item. Command list is {}. Sendingcommand: {}. Lock is released. Now it is {}".format( - self._name.lower(), self._send_commands, self._sendingcommand, self._threadlock_update.locked())) - try: - if not self._is_connected == [] and not self._send_commands == []: # and sending == True: - sending = self._send('command', 'updateitem') - while sending is None: - self._sendlock.wait(2) - self.logger.warning("Waiting for sending") - self.logger.debug("Updating Item for avdevice_{}: Updating item. Command list is {}. Return from send is {}. Lock is released. Now it is {}".format( - self._name.lower(), self._send_commands, sending, self._threadlock_update.locked())) - - - if self._reset_onerror == True and emptycommand == False and not self._send_commands == [] and not self._sendingcommand == 'done' and self._is_connected == []: #and self._trigger_reconnect == True and updating == True and self._is_connected == []: - self.logger.warning("Updating Item for avdevice_{}: Sending command {}. Starting to reset".format(self._name.lower(),self._sendingcommand)) - resetting = self._resetitem() - - while resetting is None: - self._resetlock.wait(2) - self.logger.warning("Waiting for resetting") - befehle=[] - for eintrag in self._send_commands: - befehle.append(eintrag.split(',')[0]) - try: - index = self._send_commands.index(self._sendingcommand) - except: - index = befehle.index(self._sendingcommand) - self.logger.debug("Updating Item for avdevice_{}: Sending command {} not in Sendcommands {} list, but found in {}".format(self._name.lower(),self._sendingcommand, self._send_commands, befehle)) - if self._send_commands[index] not in self._query_commands and not self._send_commands[index] in self._specialcommands['Display']['Command']: - self._keep_commands[time.time()] = self._send_commands[index] - self._send_commands.pop(index) - self._resetondisconnect('update_end') - self.logger.info("Updating Item for avdevice_{}: Connection error. Resetting Item {}. Keepcommands: {}. Sendcommands: {} Sendingcommand: {}".format( - self._name.lower(), resetting, self._keep_commands, self._send_commands, self._sendingcommand)) - self._sendingcommand = 'done' - - except Exception as err: - if not self._is_connected == []: - self.logger.warning("Updating Item for avdevice_{}: Problem sending command. It is most likely not in the text file! Error: {}".format(self._name.lower(), err)) - else: - self.logger.warning( - "Updating Item for avdevice_{}: Problem sending command - not connected! Error: {}".format(self._name.lower(), err)) - - def _send(self, command, caller): - if not self._sendlock.acquire(timeout=2): - return - try: - if not self._send_commands == []: - if command == 'command': - to_send = self._send_commands[0].split(",")[0] - elif command == 'query': - to_send = self._send_commands[0].split(",")[1] - else: - to_send = command - command = 'Resendcommand' - commandlist = to_send.split("|") - self.logger.debug("Sending {}: Starting to send {} {} from list {}. Caller: {}. Lock is: {}".format(self._name, command, to_send, self._send_commands, caller, self._threadlock_send.locked())) - try: - self._sendingcommand = self._send_commands[0] - except: - self._sendingcommand = to_send - response = self._send_commands[0].split(",")[2].split("|") - for resp in response: - if resp in self._specialcommands['Display']['Command']: - keyfound = True - else: - keyfound = False - if self._send_commands[0] in self._query_commands and len(self._send_commands) >1 and not keyfound == True and self._specialcommands['Display']['Ignore'] < 5: - self._specialcommands['Display']['Ignore'] = self._specialcommands['Display']['Ignore'] + 5 - if self._specialcommands['Display']['Command'] not in self._ignoreresponse and not '' in self._ignoreresponse and not self._specialcommands['Display']['Command'] == '': - self._ignoreresponse.append(self._specialcommands['Display']['Command']) - #self.logger.debug("Sending {}: Querycommand. Command: {}. Querycommand: {}, Display Ignore: {}, Input Ignore: {}".format(self._name, self._send_commands[0],self._query_commands, self._specialcommands['Display']['Ignore'], self._specialcommands['Input']['Ignore'])) - - elif self._send_commands[0] not in self._query_commands or len(self._send_commands) <=1 or keyfound == True: - if self._specialcommands['Display']['Ignore'] >= 5: - self._specialcommands['Display']['Ignore'] = self._specialcommands['Display']['Ignore'] - 5 - #self.logger.debug("Sending {}: No Querycommand. Command: {}. Querycommand: {}. Display Ignore: {}. Input Ignore:{}".format(self._name, self._send_commands[0],self._query_commands,self._specialcommands['Display']['Ignore'],self._specialcommands['Input']['Ignore'])) - - if self._specialcommands['Display']['Ignore'] == 0 and not 1 in self._specialcommands['Input']['Ignore']: - while self._specialcommands['Display']['Command'] in self._ignoreresponse: - self._ignoreresponse.remove(self._specialcommands['Display']['Command']) - #self.logger.debug("Sending {}: Removing {} from ignore. Ignored responses are now: {}".format(self._name, self._specialcommands['Display']['Command'], self._ignoreresponse)) - - if self._trigger_reconnect == True: - self.logger.debug("Sending {}: Trying to connect while sending command".format(self._name)) - self.connect() - cmd = 0 - for multicommand in commandlist: - cmd += 1 - if not self._rs232 is None: - #result = self._serial.write(bytes('{}\r'.format(multicommand), 'utf-8')) - result = self._serialwrapper.write(u'{}\r'.format(multicommand)) - self._serialwrapper.flush() - self.logger.debug("Sending Serial {}: {} was sent {} from Multicommand-List {}. Returns {}. Sending command: {}".format(self._name, command, multicommand, commandlist, result, self._sendingcommand)) - self._wait(0.2) - if cmd >= len(commandlist) and self._threadlock_send.locked(): - self._sendlock.notify() - return result - - - elif not self._tcp is None: - result = self._socket.send(bytes('{}\r'.format(multicommand), 'utf-8')) - self.logger.debug("Sending TCP {}: {} was sent {} from Multicommand-List {}. Returns {}".format(self._name, command, multicommand, commandlist, result)) - self._wait(0.2) - if cmd >= len(commandlist) and self._threadlock_send.locked(): - self._sendlock.notify() - return result - - else: - self.logger.error("Sending {}: Neither IP address nor Serial device definition found".format(self._name)) - except IOError as err: - if err.errno == 32: - self.logger.warning( - "Sending {}: Problem sending multicommand {}, not connected. Message: {}".format(self._name, self._send_commands[0], err)) - try: - self._socket.shutdown(2) - self._socket.close() - self.logger.debug("Sending {}: TCP socket closed".format(self._name)) - except: - self.logger.debug( - "Sending {}: No TCP socket to close.".format(self._name)) - try: - self._is_connected.remove('TCP') - self.connect() - self.logger.debug("Sending {}: reconnect TCP started.".format(self._name)) - except: - self.logger.debug( - "Sending {}: Cannot reconnect TCP.".format(self._name)) - try: - self._serialwrapper.close() - self.logger.debug("Sending {}: Serial socket closed".format(self._name)) - except: - self.logger.debug( - "Sending {}: No Serial socket to close.".format(self._name)) - try: - self._is_connected.remove('Serial') - self.connect() - self.logger.debug("Sending {}: reconnect Serial started.".format(self._name)) - except: - self.logger.debug( - "Sending {}: Cannot reconnect Serial.".format(self._name)) - - - except Exception as err: - try: - self.logger.warning( - "Sending {}: Problem sending multicommand {}. Message: {}".format(self._name, self._send_commands[0], err)) - except: - self.logger.warning( - "Sending {}: Problem sending multicommand {}. Message: {}".format(self._name, self._send_commands, err)) - finally: - if self._threadlock_send.locked(): self._sendlock.release() - #self.logger.debug("Sending {}: Finished sending command. Lock is released. Now it is {}".format(self._name, self._threadlock_send.locked())) - - # Close connection to receiver and set alive to false - def stop(self): - self.alive = False - self._sh.scheduler.change('avdevice-tcp-reconnect', active=False) - self._sh.scheduler.remove('avdevice-tcp-reconnect') - self._sh.scheduler.change('avdevice-serial-reconnect', active=False) - self._sh.scheduler.remove('avdevice-serial-reconnect') - - try: - self._socket.shutdown(2) - self._socket.close() - self.logger.debug("Stopping {}: closed".format(self._name)) - except: - self.logger.debug( - "Stopping {}: No TCP socket to close.".format(self._name)) - try: - self._serialwrapper.close() - except: - self.logger.debug( - "Stopping {}: No Serial socket to close.".format(self._name)) + ALLOW_MULTIINSTANCE = True + PLUGIN_VERSION = "1.3.2" + + def __init__(self, smarthome, + model='', + ignoreresponse='RGB,RGC,RGD,GBH,GHH,LM0,VTA,AUA,AUB', + errorresponse='E02,E04,E06', + forcebuffer='GEH01020, GEH04022, GEH05024', + inputignoredisplay='', + dependson_item='', + dependson_value=True, + rs232_port='', + rs232_baudrate=9600, + rs232_timeout=0.1, + tcp_ip='', + tcp_port=23, + tcp_timeout=1, + resetonerror=False, + depend0_power0=False, + depend0_volume0=False, + sendretries=10, + resendwait=1.0, + reconnectretries=13, + secondstokeep=50, + responsebuffer='5', + autoreconnect=False): + self.logger = logging.getLogger(__name__) + self._sh = smarthome + self.alive = False + self._name = self.get_instance_name() + self._serialwrapper = None + self._serial = None + self._tcpsocket = None + self._functions = {'zone0': {}, 'zone1': {}, 'zone2': {}, 'zone3': {}, 'zone4': {}} + self._items = {'zone0': {}, 'zone1': {}, 'zone2': {}, 'zone3': {}, 'zone4': {}} + self._query_zonecommands = {'zone0': [], 'zone1': [], 'zone2': [], 'zone3': [], 'zone4': []} + self._items_speakers = {'zone1': {}, 'zone2': {}, 'zone3': {}} + self._send_commands = [] + self._keep_commands = {} + self._query_commands = [] + self._power_commands = [] + self._response_commands = {} + self._number_of_zones = 0 + self._trigger_reconnect = True + self._reconnect_counter = 0 + self._resend_counter = 0 + self._resend_on_empty_counter = 0 + self._sendingcommand = 'done' + self._special_commands = {} + self._is_connected = [] + self._parsinginput = [] + + try: + self._model = self.get_parameter_value('model') + self._resend_wait = float(self.get_parameter_value('resendwait')) + self._secondstokeep = int(self.get_parameter_value('secondstokeep')) + self._auto_reconnect = self.get_parameter_value('autoreconnect') + self._resend_retries = int(self.get_parameter_value('sendretries')) + self._reconnect_retries = int(self.get_parameter_value('reconnectretries')) + ignoreresponse = self.get_parameter_value('ignoreresponse') + errorresponse = self.get_parameter_value('errorresponse') + forcebuffer = self.get_parameter_value('forcebuffer') + inputignoredisplay = self.get_parameter_value('inputignoredisplay') + resetonerror = self.get_parameter_value('resetonerror') + responsebuffer = self.get_parameter_value('responsebuffer') + depend0_power0 = self.get_parameter_value('depend0_power0') + depend0_volume0 = self.get_parameter_value('depend0_volume0') + dependson_item = self.get_parameter_value('dependson_item') + dependson_value = self.get_parameter_value('dependson_value') + tcp_ip = self.get_parameter_value('tcp_ip') + tcp_port = self.get_parameter_value('tcp_port') + tcp_timeout = self.get_parameter_value('tcp_timeout') + rs232_port = self.get_parameter_value('rs232_port') + rs232_baudrate = self.get_parameter_value('rs232_baudrate') + rs232_timeout = self.get_parameter_value('rs232_timeout') + except: + self._model = model + self._resend_wait = float(resendwait) + self._secondstokeep = int(secondstokeep) + self._auto_reconnect = autoreconnect + self._resend_retries = int(sendretries) + self._reconnect_retries = int(reconnectretries) + + # Initializing all variables + self.logger.debug("Initializing {}: Resendwait: {}. Seconds to keep: {}.".format(self._name, self._resend_wait, self._secondstokeep)) + self.init = Init(self._sh, self._name, self._model, self._items) + self._rs232, self._baud, self._timeout = self.init._process_variables([rs232_port, rs232_baudrate, rs232_timeout], 'rs232') + self._tcp, self._port, self._tcp_timeout = self.init._process_variables([tcp_ip, tcp_port, tcp_timeout], 'tcp') + self._dependson, self._dependson_value, self._depend0_power0, self._depend0_volume0 = self.init._process_variables([dependson_item, dependson_value, depend0_power0, depend0_volume0], 'dependson') + + self._response_buffer = self.init._process_variables(responsebuffer, 'responsebuffer') + self._reset_onerror = self.init._process_variables(resetonerror, 'resetonerror') + self._ignore_response, self._error_response, self._force_buffer, self._ignoredisplay = self.init._process_variables([ignoreresponse, errorresponse, forcebuffer, inputignoredisplay], 'responses') + + # Non-blocking wait function + def _wait(self, time_lapse): + time_start = time.time() + time_end = (time_start + time_lapse) + + while time_end > time.time(): + pass + + # Resetting items when send command failed + def _resetitem(self): + try: + resetting = None + try: + response = self._sendingcommand.split(",")[2].split("|") + sendcommand = self._sendingcommand + self.logger.debug("Resetting {}: Searching for suiting command for sendingcommand response: {}.".format(self._name, response)) + except Exception as e: + response = self._send_commands[0].split(",")[2].split("|") + sendcommand = self._send_commands[0] + self.logger.log(VERBOSE1, "Resetting {}: Cannot find Sendingcommand. Using first Command in queue: {}. Message: {}".format(self._name, response, e)) + sorted_response_commands = sorted(self._response_commands, key=len, reverse=True) + for key in sorted_response_commands: + self.logger.log(VERBOSE1, "Resetting {}: Trying to reset Item. Comparing: {} with {}".format(self._name, key, response)) + for resp in response: + for entry in self._response_commands[key]: + try: + if resp.startswith(key, 0, entry[1]): + valuetype = sendcommand.split(',') + try: + valuetype[3:] = [','.join(valuetype[3:])] + testvalue = valuetype[3] + except Exception: + testvalue = '' + self.logger.log(VERBOSE1, "Resetting {}: Comparing value {} with type {} and expected type {}.".format( + self._name, entry, testvalue, entry[7])) + if testvalue == entry[7]: + keyfound = entry + self.logger.log(VERBOSE1, "Resetting {}: Found correct entry: {}".format(self._name, keyfound)) + break + else: + keyfound = '' + else: + keyfound = '' + except Exception as err: + keyfound = '' + self.logger.debug("Resetting {}: Problem comparing response: {}. Error: {}".format(self._name, resp, err)) + if not keyfound == '': + self.logger.debug("Resetting {}: Entry: {}".format(self._name, keyfound)) + zone = keyfound[5] + previousvalue = self._items[zone][keyfound[4]]['Value'] + for item in keyfound[3]: + self.logger.info("Resetting {}: Resetting Item {} to {}".format( + self._name, item, previousvalue)) + item(previousvalue, 'AVDevice', self._tcp) + if key in self._special_commands['Speakers']['Command']: + for speaker in self._items_speakers[zone]: + previousvalue = self._items_speakers[zone][speaker]['Value'] + for item in self._items_speakers[zone][speaker]['Item']: + item(previousvalue, 'AVDevice', self._tcp) + self.logger.info("Resetting {}: Resetting additional speaker item {} to value {}".format( + self._name, item, previousvalue)) + resetting = keyfound[3] + return resetting + self._trigger_reconnect = False + self.logger.debug("Resetting {}: Deleted first entry of Send Commands. They are now: {}".format( + self._name, self._send_commands)) + return resetting + + except Exception as err: + self.logger.error( + "Resetting {}: Problem resetting Item. Error: {}".format(self._name, err)) + return 'ERROR' + + # Resetting items if no connection available + def _resetondisconnect(self, caller): + if self._depend0_volume0 is True or self._depend0_power0 is True: + self.logger.debug('Resetting {}: Starting to reset on disconnect. Called by {}'.format(self._name, caller)) + try: + for zone in self._items: + if 'power' in self._items[zone].keys() and self._depend0_power0 is True: + self._items[zone]['power']['Value'] = 0 + for singleitem in self._items[zone]['power']['Item']: + singleitem(0, 'AVDevice', self._tcp) + self.logger.log(VERBOSE1, 'Resetting {}: Power to 0 for item {}'.format(self._name, singleitem)) + if 'speakers' in self._items[zone].keys() and self._depend0_power0 is True: + self._items[zone]['speakers']['Value'] = 0 + for item in self._items_speakers[zone].keys(): + self._items_speakers[zone][item]['Value'] = 0 + for singleitem in self._items_speakers[zone][item]['Item']: + singleitem(0, 'AVDevice', self._tcp) + self.logger.log(VERBOSE1, 'Resetting {}: Speakers to 0 for item {}'.format(self._name, singleitem)) + for singleitem in self._items[zone]['speakers']['Item']: + singleitem(0, 'AVDevice', self._tcp) + self.logger.log(VERBOSE1, 'Resetting {}: Speakers to 0 for item {}'.format(self._name, singleitem)) + if 'volume' in self._items[zone].keys() and self._depend0_volume0 is True: + self._items[zone]['volume']['Value'] = 0 + for singleitem in self._items[zone]['volume']['Item']: + singleitem(0, 'AVDevice', self._tcp) + self.logger.log(VERBOSE1, 'Resetting {}: Volume to 0 for item {}'.format(self._name, singleitem)) + self.logger.debug('Resetting {}: Done.'.format(self._name)) + except Exception as err: + self.logger.warning('Resetting {}: Problem resetting Item. Error: {}'.format(self._name, err)) + else: + self.logger.log(VERBOSE1, 'Resetting {}: Not resetting on disconnect because this feature is disabled in the plugin config.'.format(self._name)) + + # Converting received values to bool, string or int to compare the responses with the expected response + def _convertvalue(self, receivedvalue, expectedtype, invert): + self.logger.debug("Converting Values {}: Received Value is: {} with expected type {}. Invert: {}".format(self._name, receivedvalue, expectedtype, invert)) + if 'bool' in expectedtype and not receivedvalue == '': + try: + if invert is True: + if (int(receivedvalue) == 1 and len(str(receivedvalue)) <= 1): + receivedvalue = False + elif (int(receivedvalue) == 0 and len(str(receivedvalue)) <= 1): + receivedvalue = True + self.logger.log(VERBOSE1, "Converting Values {}: Receivedvalue {} reversed".format(self._name, receivedvalue)) + else: + if (int(receivedvalue) == 1 and len(str(receivedvalue)) <= 1): + receivedvalue = True + self.logger.log(VERBOSE1, "Converting Values {}: Receivedvalue {} converted to bool.".format(self._name, receivedvalue)) + elif (int(receivedvalue) == 0 and len(str(receivedvalue)) <= 1): + receivedvalue = False + self.logger.log(VERBOSE1, "Converting Values {}: Receivedvalue {} converted to bool.".format(self._name, receivedvalue)) + except Exception as err: + self.logger.log(VERBOSE2, "Converting Values {}: Receivedvalue {} not converted further. Message: {}.".format(self._name, receivedvalue, err)) + pass + if 'bool' in expectedtype: + try: + if int(receivedvalue) == 1 and len(str(receivedvalue)) <= 1: + receivedvalue = True + elif int(receivedvalue) == 0 and len(str(receivedvalue)) <= 1: + receivedvalue = False + except Exception: + pass + if 'int' in expectedtype: + try: + if str(receivedvalue).lower() == 'on': + receivedvalue = 1 + elif str(receivedvalue).lower() == 'off' or str(receivedvalue).lower() == 'standby': + receivedvalue = 0 + except Exception: + pass + elif not (('bool' in expectedtype and 'int' in expectedtype) or ('str' in expectedtype and 'bool' in expectedtype)): + try: + if str(receivedvalue).lower() == 'on': + receivedvalue = True + elif str(receivedvalue).lower() == 'off' or str(receivedvalue).lower() == 'standby': + receivedvalue = False + except Exception: + pass + try: + receivedvalue = eval(receivedvalue.lstrip('0')) + except Exception: + try: + receivedvalue = eval(receivedvalue) + except Exception: + pass + try: + receivedvalue = float(receivedvalue) if '.' in receivedvalue else int(receivedvalue) + except Exception: + pass + self.logger.debug("Converting Values {}: Received Value is now: {} with type {}.".format(self._name, receivedvalue, type(receivedvalue))) + return receivedvalue + + # Store actual value to a temporary dict for resetting purposes + def _write_itemsdict(self, data): + try: + self.logger.debug("Storing Values {}: Starting to store value for data {} in dictionary.".format(self._name, data)) + sorted_response_commands = sorted(self._response_commands, key=len, reverse=True) + updated = 0 + for command in sorted_response_commands: + self.logger.log(VERBOSE1, "Storing Values {}: Comparing command {}.".format(self._name, command)) + if data == command: + self.logger.debug("Storing Values {}: Response is identical to expected response. Skipping Storing: {}".format(self._name, data)) + break + for entry in self._response_commands[command]: + self.logger.log(VERBOSE1, "Storing Values {}: Comparing entry {}.".format(self._name, entry)) + if entry[1] == entry[2]: + commandstart = 0 + commandend = entry[2] + else: + commandstart = entry[0] + commandend = entry[0] + entry[1] + + valuestart = entry[2] + valueend = entry[2] + entry[0] + function = entry[4] + expectedtype = entry[7] + + if data[commandstart:commandend] == command: + zone = entry[5] + value = receivedvalue = data[valuestart:valueend] + invert = True if entry[6].lower() in ['1', 'true', 'yes', 'on'] else False + receivedvalue = self._convertvalue(value, expectedtype, invert) + + if isinstance(receivedvalue, eval(expectedtype)): + self._items[zone][function]['Value'] = receivedvalue + self.logger.debug("Storing Values {}: Found writeable dict key: {}. Zone: {}. Value {} with type {}. Function: {}.".format(self._name, command, zone, receivedvalue, expectedtype, function)) + updated = 1 + return self._items[zone][function], receivedvalue, expectedtype + break + else: + self.logger.debug("Storing Values {}: Found writeable dict key: {} with type {}, but received value {} is type {}. Not writing value!".format(self._name, command, expectedtype, receivedvalue, type(receivedvalue))) + if updated == 1: + self.logger.log(VERBOSE1, "Storing Values {}: Stored all relevant items from function {}. step 1".format(self._name, function)) + break + if updated == 1: + self.logger.log(VERBOSE1, "Storing Values {}: Stored all relevant items from function {}. step 2".format(self._name, function)) + break + if updated == 1: + self.logger.log(VERBOSE1, "Storing Values {}: Stored all relevant items from function {}. step 3".format(self._name, function)) + break + except Exception as err: + self.logger.error("Storing Values {}: Problems creating items dictionary. Error: {}".format(self._name, err)) + finally: + self.logger.log(VERBOSE1, "Storing Values {}: Finished. Send Commands: {}".format(self._name, self._send_commands)) + if updated == 1: + return self._items[zone][function], receivedvalue, expectedtype + else: + return 'empty', 'empty', 'empty' + + # Finding relevant items for the plugin based on the avdevice keyword + def parse_item(self, item): + if self._tcp is not None or self._rs232 is not None: + if self.has_iattr(item.conf, 'avdevice'): + info = self.get_iattr_value(item.conf, 'avdevice') + if (info is None): + return None + else: + self._items['zone0'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone0'): + info = self.get_iattr_value(item.conf, 'avdevice_zone0') + if (info is None): + return None + else: + self._items['zone0'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone1'): + info = self.get_iattr_value(item.conf, 'avdevice_zone1') + if (info is None): + return None + else: + self._items['zone1'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone2'): + info = self.get_iattr_value(item.conf, 'avdevice_zone2') + if (info is None): + return None + else: + self._items['zone2'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone3'): + info = self.get_iattr_value(item.conf, 'avdevice_zone3') + if (info is None): + return None + else: + self._items['zone3'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone4'): + info = self.get_iattr_value(item.conf, 'avdevice_zone4') + if (info is None): + return None + else: + self._items_['zone4'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone1_speakers'): + info = self.get_iattr_value(item.conf, 'avdevice_zone1_speakers') + if (info is None): + return None + else: + self._items_speakers['zone1'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone2_speakers'): + info = self.get_iattr_value(item.conf, 'avdevice_zone2_speakers') + if (info is None): + return None + else: + self._items_speakers['zone2'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif self.has_iattr(item.conf, 'avdevice_zone3_speakers'): + info = self.get_iattr_value(item.conf, 'avdevice_zone3_speakers') + if (info is None): + return None + else: + self._items_speakers['zone3'][info] = {'Item': [item], 'Value': item()} + return self.update_item + elif str(item) == self._dependson: + self._items['zone0']['dependson'] = {'Item': self._dependson, 'Value': self._dependson_value} + self.logger.debug("Initializing {}: Dependson Item found: {}".format(self._name, item, self._dependson)) + return self.update_item + else: + return None + self.logger.warning( + "Parsing Items {}: No items parsed".format(self._name)) + + # Processing the response from the AV device, dealing with buffers, etc. + def _processing_response(self, socket): + try: + buffer = '' + bufferlist = [] + tidy = lambda c: re.sub( + r'(^\s*[\r\n]+|^\s*\Z)|(\s*\Z|\s*[\r\n]+)', + lambda m: '\r\n' if m.lastindex == 2 else '', + c) + try: + if self._rs232 and (socket == self._serialwrapper or socket == self._serial): + if socket == self._serial: + buffer = socket.readline().decode('utf-8') + else: + buffer = socket.read() + if self._tcp and socket == self._tcpsocket: + buffer = socket.recv(4096).decode('utf-8') + buffering = False + buffer = tidy(buffer) + if not buffer == '' and (self._response_buffer is not False or self._response_buffer is not 0): + buffering = True + elif buffer == '' and not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup': + self._resend_on_empty_counter += 1 + self._wait(0.1) + sending = self._send(self._sendingcommand, 'responseprocess') + self.logger.log(VERBOSE1, "Processing Response {}: Received empty response while sending command: {}. Return from send is {}. Retry: {}".format(self._name, self._sendingcommand, sending, self._resend_counter)) + if self._resend_on_empty_counter >= 2: + self.logger.debug("Processing Response {}: Stop resending command {} and sending back error.".format(self._name, self._sendingcommand)) + self._resend_on_empty_counter = 0 + yield 'ERROR' + + except Exception as err: + buffering = False + try: + if not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup' and not (self._sendingcommand.split(",")[2] == '' or self._sendingcommand.split(",")[2] == ' ' or self._sendingcommand.split(",")[2] == 'none'): + buffering = True + self.logger.log(VERBOSE1, "Processing Response {}: Error reading.. Error: {}. Sending Command: {}. RS232: {}, Host: {}, Socket: {}".format(self._name, err, self._sendingcommand, self._rs232, self._tcp, socket)) + if self._rs232 and (socket == self._serialwrapper or socket == self._serial): + self.logger.log(VERBOSE1, "Processing Response {}: Problems buffering RS232 response. Error: {}. Increasing timeout temporarily.".format(self._name, err)) + self._wait(1) + socket.timeout = 2 + sending = self._send(self._sendingcommand, 'getresponse') + if socket == self._serial: + buffer = socket.readline().decode('utf-8') + else: + buffer = socket.read() + socket.timeout = 0.3 + self.logger.log(VERBOSE1, "Processing Response {}: Error reading.. Return from send is {}. Error: {}".format(self._name, sending, err)) + if self._tcp and socket == self._tcpsocket: + self.logger.log(VERBOSE1, "Processing Response {}: Problems buffering TCP response. Error: {}. Increasing timeout temporarily.".format(self._name, err)) + self._wait(1) + socket.settimeout(self._tcp_timeout * 3) + sending = self._send(self._sendingcommand, 'getresponse') + self.logger.debug("Processing Response {}: Error reading.. Return from send is {}. Error: {}".format(self._name, sending, err)) + buffer = socket.recv(4096).decode('utf-8') + socket.settimeout(self._tcp_timeout) + except Exception as err: + buffering = False + self.logger.error("Processing Response {}: Connection error. Error: {} Resend Counter: {}. Resend Max: {}".format( + self._name, err, self._resend_counter, self._resend_retries)) + yield 'ERROR' + + while buffering: + if '\r\n' in buffer: + self.logger.log(VERBOSE2, "Processing Response {}: Buffer before removing duplicates: {}".format(self._name, re.sub('[\r\n]', ' ', buffer))) + # remove duplicates + buffer = '\r\n'.join(sorted(set(buffer.split('\r\n')), key=buffer.split('\r\n').index)) + (line, buffer) = buffer.split("\r\n", 1) + self.logger.log(VERBOSE2, "Processing Response {}: \r\nBuffer: {} Line: {}. Response buffer: {}, force buffer: {}".format(self._name, buffer, line, self._response_buffer, self._force_buffer)) + if not ('' in self._force_buffer and len(self._force_buffer) == 1) and (self._response_buffer is False or self._response_buffer == 0): + if not re.sub('[ ]', '', buffer) == '' and not re.sub('[ ]', '', line) == '': + bufferlist = [] + for buf in self._force_buffer: + try: + if buf in buffer and not buf.startswith(tuple(self._ignore_response)) and '' not in self._ignore_response: + start = buffer.index(buf) + self.logger.log(VERBOSE2, "Processing Response {}: Testing forcebuffer {}. Bufferlist: {}. Start: {}".format(self._name, buf, bufferlist, start)) + if not buffer.find('\r\n', start) == -1: + end = buffer.index('\r\n', start) + if not buffer[start:end] in bufferlist and not buffer[start:end] in line: + bufferlist.append(buffer[start:end]) + else: + if not buffer[start:] in bufferlist and not buffer[start:] in line: + bufferlist.append(buffer[start:]) + self.logger.debug("Processing Response {}: Forcebuffer {} FOUND in buffer. Bufferlist: {}. Buffer: {}".format( + self._name, buf, bufferlist, buffer)) + except Exception as err: + self.logger.warning("Processing Response {}: Problems while buffering. Error: {}".format(self._name, err)) + if bufferlist: + buffer = '\r\n'.join(bufferlist) + buffer = tidy(buffer) + else: + self.logger.log(VERBOSE2, "Processing Response {}: No forced buffer found.".format(self._name)) + # Delete consecutive duplicates + # buffer = '\r\n'.join([x[0] for x in groupby(buffer.split('\r\n'))]) + + if '{}\r\n'.format(line) == buffer: + buffer = '' + self.logger.log(VERBOSE1, "Processing Response {}: Clearing buffer because it's the same as Line: {}".format(self._name, line)) + line = re.sub('[\\n\\r]', '', line).strip() + if not line.startswith(tuple(self._response_commands)) and line not in self._error_response: + self.logger.log(VERBOSE1, "Processing Response {}: Response {} is not in possible responses for items. Sending Command: {}".format(self._name, line, self._sendingcommand)) + elif line in self._error_response and '' not in self._error_response: + self.logger.debug("Processing Response {}: Response {} is in Error responses.".format(self._name, line)) + yield "{}".format(line) + elif line.startswith(tuple(self._ignore_response)) and '' not in self._ignore_response: + try: + compare = self._send_commands[0].split(",")[2].split("|") + for comp in compare: + if line.startswith(comp): + keyfound = True + else: + keyfound = False + if keyfound is True: + self.logger.log(VERBOSE1, "ERROR Processing Response {}: Sending Command: {} Keep command {}".format(self._name, self._send_commands, self._keep_commands)) + for entry in self._keep_commands: + if self._send_commands[0] in self._keep_commands.get(entry): + self._keep_commands.pop(entry) + self.logger.log(VERBOSE1, "ERROR Processing Response {}: Removed Keep command {} from {} because command sent successfully".format( + self._name, entry, self._keep_commands)) + break + self._send_commands.pop(0) + self._sendingcommand = 'done' + self.logger.debug("Processing Response {}: Response {} is same as expected {}. Removing command from send list. It is now: {}. Ignore responses are: {}".format( + self._name, line, compare, self._send_commands, self._ignore_response)) + sending = self._send('command', 'commandremoval') + except Exception as err: + self.logger.log(VERBOSE2, "Processing Response {}: Response {} is ignored. Command list is now: {}. Message: {}".format(self._name, line, self._send_commands, err)) + elif not line.startswith(tuple(self._ignore_response)) and line.startswith(self._special_commands['Display']['Command']) and \ + self._response_buffer is not False and '' not in self._ignore_response and not self._special_commands['Display']['Command'] == '': + self.logger.log(VERBOSE1, "Processing Response {}: Detected Display info {}. buffer: \r\n{}".format(self._name, line, buffer)) + buffering = False + buffer += '\r\n{}\r\n'.format(line) + buffer = tidy(buffer) + self.logger.log(VERBOSE1, "Processing Response {}: Append Display info {} to buffer: \r\n{}".format(self._name, line, buffer)) + else: + if self._response_buffer is False and not buffer.startswith(tuple(self._force_buffer)) and '' not in self._force_buffer: + buffering = False + self.logger.log(VERBOSE1, "Processing Response {}: Clearing buffer: {}".format(self._name, buffer)) + buffer = '\r\n' + self.logger.log(VERBOSE1, "Processing Response {}: Sending back line: {}. Display Command: {}".format( + self._name, line, self._special_commands['Display']['Command'])) + yield "{}".format(line) + else: + try: + if self._rs232 and (socket == self._serialwrapper or socket == self._serial): + if socket == self._serial: + more = socket.readline().decode('utf-8') + else: + more = socket.read() + if self._tcp and socket == self._tcp: + more = socket.recv(4096).decode('utf-8') + morelist = more.split("\r\n") + if buffer.find('\r\n') == -1 and len(buffer) > 0: + buffer += '\r\n' + buffer += '\r\n'.join([x[0] for x in groupby(morelist)]) + except Exception as err: + buffering = False + finally: + buffering = False + self.logger.log(VERBOSE1, "Processing Response {}: Buffering false.".format(self._name)) + + if not buffer == '\r\n' and self._response_buffer is True or type(self._response_buffer) is int: + buffer = tidy(buffer) + bufferlist = buffer.split('\r\n') + # Removing everything except last x lines + maximum = abs(self._response_buffer) if type(self._response_buffer) is int else 11 + multiplier = 1 if self._response_buffer >= 0 else -1 + while '' in bufferlist: + bufferlist.remove('') + newbuffer = [] + for buf in bufferlist: + if not buf.startswith(tuple(self._ignore_response)) and '' not in self._ignore_response and buf.startswith(tuple(self._response_commands)): + newbuffer.append(buf) + bufferlist = newbuffer[-1 * max(min(len(newbuffer), maximum), 0):] + + if len(bufferlist) > 1: + self.logger.log(VERBOSE1, "Bufferlist after: {}".format(bufferlist)) + buffering = False + for buf in bufferlist: + if not re.sub('[ ]', '', buf) == '' and not buf.startswith(tuple(self._ignore_response)) and '' not in self._ignore_response: + self.logger.log(VERBOSE1, "Processing Response {}: Sending back {} from buffer because Responsebuffer is activated.".format(self._name, buf)) + self._wait(0.2) + yield buf + + elif not buffer == '\r\n': + buffer = tidy(buffer) + bufferlist = buffer.split('\r\n') + # Removing everything except last x lines + maximum = abs(self._response_buffer) if type(self._response_buffer) is int else 11 + multiplier = 1 if self._response_buffer >= 0 else -1 + bufferlist = bufferlist[multiplier * max(min(len(bufferlist), maximum), 0):] + buffering = False + for buf in bufferlist: + if not re.sub('[ ]', '', buf) == '' and not buf.startswith(tuple(self._ignore_response)) and '' not in self._ignore_response: + self.logger.debug("Processing Response {}: Sending back {} from filtered buffer: {}.".format(self._name, buf, buffer)) + self._wait(0.2) + yield buf + except Exception as err: + self.logger.error("Processing Response {}: Problems occured. Message: {}".format(self._name, err)) + + # Run function + def run(self): + if self._tcp is None and self._rs232 is None: + self.logger.error("Initializing {}: Neither IP address nor RS232 port given. Not running.".format(self._name)) + else: + self._functions, self._number_of_zones = self.init._read_commandfile() + self._items = self.init._addstatusupdate() + self._response_commands, self._special_commands = self.init._create_responsecommands() + self._power_commands = self.init._create_powercommands() + self._query_commands, self._query_zonecommands = self.init._create_querycommands() + self.logger.log(VERBOSE1, "Initializing {}: Functions: {}, Number of Zones: {}".format(self._name, self._functions, self._number_of_zones)) + self.logger.log(VERBOSE1, "Initializing {}: Responsecommands: {}.".format(self._name, self._response_commands)) + self.logger.log(VERBOSE1, "Initializing {}: Special Commands: {}".format(self._name, self._special_commands)) + self.logger.log(VERBOSE1, "Initializing {}: Powercommands: {}".format(self._name, self._power_commands)) + self.logger.log(VERBOSE1, "Initializing {}: Querycommands: {}, Query Zone: {}".format(self._name, self._query_commands, self._query_zonecommands)) + self.logger.log(VERBOSE1, "Initializing {}: Items: {}".format(self._name, self._items)) + self.logger.log(VERBOSE1, "Initializing {}: Speaker Items: {}".format(self._name, self._items_speakers)) + self.logger.log(VERBOSE1, "Initializing {}: done".format(self._name)) + + try: + try: + self._dependson = self._sh.return_item(self._dependson) + self.logger.debug("Initializing {}: Dependson Item: {}.".format(self._name, self._dependson)) + except Exception: + self._dependson = None + self.logger.warning("Initializing {}: Dependson Item {} is no valid item.".format(self._name, self._dependson)) + self.logger.debug("Initializing {}: Running".format(self._name)) + self.alive = True + if 'statusupdate' not in self._items['zone0'].keys(): + self._items['zone0']['statusupdate'] = {'Item': ['self._statusupdate'], 'Value': False} + self.logger.debug("Initializing {}: No statusupdate Item set, creating dummy item.".format(self._name)) + except Exception as err: + self.logger.error("Initializing {}: Problem running and creating items. Error: {}".format(self._name, err)) + finally: + if self._tcp is not None or self._rs232 is not None: + self.connect('run') + + # Triggering TCP or RS232 connection schedulers + def connect(self, trigger): + self._trigger_reconnect = True + if self._is_connected == []: + self._parsinginput = [] + self._is_connected.append('Connecting') + self.logger.log(VERBOSE1, "Connecting {}: Starting to connect. Triggered by {}. Current Connections: {}".format(self._name, trigger, self._is_connected)) + try: + dependsvalue = self._dependson() + if dependsvalue == self._dependson_value: + depending = False + else: + depending = True + self._is_connected = [] + self._parsinginput = [] + self.logger.debug("Connecting {}: Connection depends on {}. It's value is {}, has to be {}. Connections are {}".format(self._name, self._dependson, dependsvalue, self._dependson_value, self._is_connected)) + except Exception as e: + depending = False + self.logger.log(VERBOSE1, "Connecting {}: Depending is false. Message: {}".format(self._name, e)) + finally: + if depending is False: + if self._tcp is not None and 'TCP' not in self._is_connected: + self.logger.log(VERBOSE1, "Connecting {}: Starting TCP scheduler".format(self._name)) + self._sh.scheduler.add('avdevice-tcp-reconnect', self.connect_tcp, cycle=7) + self._sh.scheduler.change('avdevice-tcp-reconnect', active=True) + self._sh.scheduler.trigger('avdevice-tcp-reconnect') + self._trigger_reconnect = False + if self._rs232 is not None and 'Serial' not in self._is_connected: + self.logger.log(VERBOSE1, "Connecting {}: Starting RS232 scheduler".format(self._name)) + self._sh.scheduler.add('avdevice-serial-reconnect', self.connect_serial, cycle=7) + self._sh.scheduler.change('avdevice-serial-reconnect', active=True) + self._sh.scheduler.trigger('avdevice-serial-reconnect') + self._trigger_reconnect = False + + # Connect to TCP IP + def connect_tcp(self): + try: + if self._tcp is not None and 'TCP' not in self._is_connected: + self.logger.log(VERBOSE1, "Connecting TCP {}: Starting to connect to {}.".format(self._name, self._tcp)) + self._tcpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._tcpsocket.setblocking(0) + self._tcpsocket.settimeout(6) + self._tcpsocket.connect(('{}'.format(self._tcp), int(self._port))) + self._tcpsocket.settimeout(self._tcp_timeout) + self._is_connected.append('TCP') + try: + self._is_connected.remove('Connecting') + except Exception: + pass + self.logger.info("Connecting TCP {}: Connected to {}:{}".format( + self._name, self._tcp, self._port)) + + except Exception as err: + if 'TCP' in self._is_connected: + self._is_connected.remove('TCP') + self.logger.warning("Connecting TCP {}: Could not connect to {}:{}. Error:{}. Counter: {}/{}".format( + self._name, self._tcp, self._port, err, self._reconnect_counter, self._reconnect_retries)) + + finally: + if ('TCP' not in self._is_connected and self._tcp is not None) and str(self._auto_reconnect).lower() in ['1', 'yes', 'true', 'on']: + self._trigger_reconnect = False + self.logger.warning("Connecting TCP {}: Reconnecting. Command list while connecting: {}.".format( + self._name, self._send_commands)) + elif ('TCP' in self._is_connected and self._tcp is not None) or self._reconnect_counter >= self._reconnect_retries: + self._sh.scheduler.change('avdevice-tcp-reconnect', active=False) + self._reconnect_counter = 0 + self._trigger_reconnect = True + self._addkeepcommands('connect_tcp', 'all') + self.logger.debug("Connecting TCP {}: Deactivating reconnect scheduler. Command list while connecting: {}. Keep Commands: {}".format( + self._name, self._send_commands, self._keep_commands)) + self._reconnect_counter += 1 + if 'TCP' in self._is_connected: + self.logger.debug("Connecting TCP {}: TCP is connected.".format(self._name)) + if self._parsinginput == []: + self.logger.debug("Connecting TCP {}: Starting Parse Input.".format(self._name)) + self._parse_input_init('tcpconnect') + + # Connect to RS232 + def connect_serial(self): + try: + if self._rs232 is not None and 'Serial' not in self._is_connected: + ser = serial.serial_for_url('{}'.format(self._rs232), baudrate=int(self._baud), timeout=float(self._timeout), write_timeout=float(self._timeout)) + i = 0 + try: + command = self._power_commands[0].split(',')[1] + self.logger.debug("Connecting Serial {}: Starting to connect to {} with init command {}.".format(self._name, self._rs232, command)) + except Exception as err: + self.logger.warning("Connecting Serial {}: No power commands found. Please check your config files!".format(self._name)) + command = '?P' + while ser.in_waiting == 0: + i += 1 + self._wait(1) + ser.write(bytes('{}\r'.format(command), 'utf-8')) + buffer = bytes() + buffer = ser.read().decode('utf-8') + self.logger.log(VERBOSE1, "Connecting Serial {}: Buffer: {}. Reconnecting Retry: {}.".format(self._name, buffer, i)) + if i >= 4: + ser.close() + self.logger.log(VERBOSE1, "Connecting Serial {}: Ran through several retries.".format(self._name)) + break + if ser.isOpen(): + self._serialwrapper = io.TextIOWrapper(io.BufferedRWPair(ser, ser), newline='\r\n', encoding='utf-8', line_buffering=True, write_through=True) + self._serialwrapper.timeout = 0.1 + self._serial = ser + self._trigger_reconnect = False + if 'Serial' not in self._is_connected: + self._is_connected.append('Serial') + try: + self._is_connected.remove('Connecting') + except Exception: + pass + self.logger.info("Connecting Serial {}: Connected to {} with baudrate {}.".format( + self._name, ser, self._baud)) + else: + self.logger.warning("Connecting Serial {}: Serial port is not open. Connection status: {}. Reconnect Counter: {}".format(self._name, self._is_connected, self._reconnect_counter)) + except Exception as err: + if 'Serial' in self._is_connected: + self._is_connected.remove('Serial') + self.logger.warning("Connecting Serial {}: Could not connect to {}, baudrate {}. Error:{}, Counter: {}/{}".format( + self._name, self._rs232, self._baud, err, self._reconnect_counter, self._reconnect_retries)) + + finally: + if ('Serial' not in self._is_connected and self._rs232 is not None) and str(self._auto_reconnect).lower() in ['1', 'yes', 'true', 'on']: + self._trigger_reconnect = False + self.logger.log(VERBOSE1, "Connecting Serial {}: Activating reconnect scheduler. Command list while connecting: {}.".format( + self._name, self._send_commands)) + elif ('Serial' in self._is_connected and self._rs232 is not None) or self._reconnect_counter >= self._reconnect_retries: + self._sh.scheduler.change('avdevice-serial-reconnect', active=False) + self._reconnect_counter = 0 + self._trigger_reconnect = True + self._addkeepcommands('connect_serial', 'all') + self.logger.debug("Connecting Serial {}: Deactivating reconnect scheduler. Command list while connecting: {}. Keep commands: {}".format( + self._name, self._send_commands, self._keep_commands)) + self._reconnect_counter += 1 + if 'Serial' in self._is_connected: + self.logger.debug("Connecting Serial {}: Serial is connected.".format(self._name)) + if self._parsinginput == []: + self.logger.debug("Connecting Serial {}: Starting Parse Input.".format(self._name)) + self._parse_input_init('serialconnect') + + # Updating Status even if no statusupdate is defined in device text file + def _statusupdate(self, value, trigger, caller): + self.logger.debug("Statusupdate {}: Value: {}. Trigger from {}. Caller: {}".format(self._name, value, trigger, caller)) + self.update_item('statusupdate', 'Init') + + # Adding Keep Commands to Send Commands + def _addkeepcommands(self, trigger, zone): + self.logger.log(VERBOSE1, "Keep Commands {}: Trigger from {} for zone {}. Send Commands: {}".format(self._name, trigger, zone, self._send_commands)) + keeptemp = [] + for zeit in self._keep_commands: + keeping = False + if time.time() - zeit <= self._secondstokeep and not self._keep_commands[zeit] in keeptemp: + try: + for item in self._query_zonecommands['{}'.format(zone)]: + if item.split(',')[1] == self._keep_commands[zeit].split(',')[1]: + keeping = True + except: + self.logger.log(VERBOSE2, "Keep Commands {}: Zone is set to all.".format(self._name)) + if zone == 'all' or keeping == True or trigger == 'powercommand': + keeping = True + keeptemp.append(self._keep_commands[zeit]) + self.logger.debug("Keep Commands {}: Age {}s of command {}. Secondstokeep: {}. Keeping command: {}".format( + self._name.lower(), int(time.time() - zeit), self._keep_commands[zeit], self._secondstokeep, keeping)) + self._send_commands = self._send_commands + list(set(keeptemp)) + seen = set() + self._send_commands = [x for x in self._send_commands if x not in seen and not seen.add(x)] + self._keep_commands = {} + keeptemp = [] + + # Parsing the response and comparing it with expected response + def _parse_input_init(self, trigger): + if not self._is_connected == [] and not self._is_connected == ['Connecting']: + self._parsinginput.append(trigger) + else: + self._parsinginput = [] + self.logger.log(VERBOSE1, "Parsing Input {}: Init Triggerd by these functions so far: {}".format(self._name, self._parsinginput)) + if trigger == 'tcpconnect' or trigger == 'serialconnect': + try: + eval(self._items['zone0']['statusupdate']['Item'][0])(1, 'Init', self._tcp) + self.logger.debug("Parsing Input {}: Updated Item after connection: {} with value 1. Commandlist: {}".format( + self._name, self._items['zone0']['statusupdate']['Item'][0], self._send_commands)) + except Exception: + try: + self._items['zone0']['statusupdate']['Item'][0](1, 'Init', self._tcp) + self.logger.debug("Parsing Input {}: Updated Item after connection: {} with value 1. Commandlist: {}".format( + self._name, self._items['zone0']['statusupdate']['Item'][0], self._send_commands)) + except Exception as err: + self.logger.log(VERBOSE1, "Parsing Input {}: No statusupdate defined, not querying status after {}. Message: {}".format(self._name, trigger, err)) + if len(self._parsinginput) == 1: + self._parse_input(trigger) + + # Parsing the response and comparing it with expected response + def _parse_input(self, trigger): + self.logger.log(VERBOSE1, "Parsing Input {}: Triggerd by {}".format(self._name, trigger)) + def _duplicateindex(seq,item): + start_at = -1 + locs = [] + while True: + try: + loc = seq.index(item,start_at+1) + except ValueError: + break + else: + locs.append(loc) + start_at = loc + return locs + + while self.alive and not self._parsinginput == [] and not self._is_connected == [] and not self._is_connected == ['Connecting']: + connectionproblem = False + if not self._sendingcommand == '' and not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup': + self.logger.log(VERBOSE1, "Parsing Input {}: Starting to parse input. Alive: {}. Connected: {}. Parsinginput: {}. Sendcommand: {}".format( + self._name, self.alive, self._is_connected, self._parsinginput, self._sendingcommand)) + to_send = 'command' + try: + data = 'waiting' + databuffer = [] + if 'Serial' in self._is_connected: + try: + databuffer = self._processing_response(self._serialwrapper) + except Exception as err: + self.logger.error("Parsing Input {}: Problem receiving Serial data {}.".format(self._name, err)) + elif 'TCP' in self._is_connected: + try: + databuffer = self._processing_response(self._tcpsocket) + except Exception as err: + self.logger.error("Parsing Input {}: Problem receiving TCP data {}.".format(self._name, err)) + for data in databuffer: + data = data.strip() + if data == '' and not self._sendingcommand == '' and not self._sendingcommand == 'done' and not self._sendingcommand == 'gaveup': + self.logger.log(VERBOSE1, "Parsing Input {}: Problem with empty response.".format(self._name)) + if data == 'ERROR' and not self._sendingcommand == 'gaveup' and not self._sendingcommand == 'done': + if self._resend_counter >= self._resend_retries: + self.logger.warning("Parsing Input {}: Giving up Sending {} and removing from list. Received Data: {}. Original Commandlist: {}".format( + self._name, self._sendingcommand, data, self._send_commands)) + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter because maximum retries exceeded.".format(self._name)) + # Resetting Item if Send not successful + if self._reset_onerror is True: + self._resetitem() + try: + if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._special_commands['Display']['Command']: + self._keep_commands[time.time()] = self._send_commands[0] + self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) + elif self._send_commands[0] in self._query_commands: + self.logger.warning("Parsing Input {}: Giving up {}, because no answer received 1.".format(self._name, self._sendingcommand)) + self._send_commands.pop(0) + if not self._send_commands == []: + sending = self._send('command', 'parseinput') + self.logger.log(VERBOSE1, "Parsing Input {}: Command List is now: {}. Sending return is {}.".format( + self._name, self._send_commands, sending)) + except Exception as err: + self.logger.debug("Parsing Input {}: Nothing to remove from Send Command List. Error: {}".format(self._name, err)) + self._sendingcommand = 'gaveup' + if self._trigger_reconnect is True: + self.logger.log(VERBOSE1, "Parsing Input {}: Trying to connect while parsing item".format(self._name)) + self.connect('parse_input') + + + sorted_response_commands = sorted(self._response_commands, key=len, reverse=True) + self.logger.debug("Parsing Input {}: Response: {}.".format(self._name, data)) + if not self._send_commands == []: + expectedresponse = [] + try: + for response in self._send_commands: + if not response.split(",")[2] == '': + expectedresponse.append(response.split(",")[2]) + self.logger.debug("Parsing Input {}: Expected response while parsing: {}.".format(self._name, expectedresponse)) + except Exception as err: + self.logger.error("Parsing Input {}: Problems creating expected response list. Error: {}".format(self._name, err)) + self.logger.log(VERBOSE1, "Parsing Input {}: Parsing input while waiting for response {}.".format(self._name, expectedresponse)) + try: + to_send = 'command' + updatedcommands = [] + runthrough = [] + if not expectedresponse == []: + for expected in expectedresponse: + if expected not in runthrough: + runthrough.append(expected) + found = [] + expectedlist = expected.split("|") + try: + for expectedpart in expectedlist: + try: + datalength = self._response_commands[expectedpart][0][1] + if data[:datalength].startswith(expectedpart) and len(data[:datalength]) == len(expectedpart): + found.append(expectedpart) + self.logger.log(VERBOSE1, "Parsing Input {}: Expected response edited: {}.".format(self._name, found)) + except Exception as err: + found.append(expectedpart) + self.logger.log(VERBOSE1, "Parsing Input {}: Expected response edited: {}. Message: {}".format(self._name, found, err)) + except Exception as err: + found.append(expected) + self.logger.debug("Parsing Input {}: Expected response after exception: {}. Problem: {}".format(self._name, found, err)) + try: + valuetype = 'empty' + if data.startswith(tuple(found)): + entry, value, valuetype = self._write_itemsdict(data) + self._sendingcommand = 'done' + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter because data is same as expected.".format(self._name)) + self.logger.log(VERBOSE1, "Parsing Input {}: Data {} found in {}. Entry: {}, Value: {}. Expected Type: {}".format(self._name, data, found, entry, value, valuetype)) + elif expectedlist[0] == '' or expectedlist[0] == ' ' or expectedlist[0] == 'none': + self._sendingcommand = 'done' + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: No response expected. Resend Counter reset.".format(self._name)) + elif expectedlist[0].lower() == 'string': + value = data + self.logger.log(VERBOSE1, "Parsing Input {}: String found and testing... ".format(self._name)) + if value.startswith(tuple(self._response_commands.keys())): + self.logger.log( + VERBOSE1, "Parsing Input {}: Found string but ignored because it is a legit response for another command.".format(self._name)) + else: + entry, value, valuetype = self._write_itemsdict(data) + self.logger.debug("Parsing Input {}: String FOUND. Written to dict: {}. Resend Counter reset.".format(self._name, entry)) + self._sendingcommand = 'done' + self._resend_counter = 0 + + expectedindices = _duplicateindex(expectedresponse, expected) + for expectedindex in expectedindices: + if self._send_commands[expectedindex] not in updatedcommands: + expectedtype = self._send_commands[expectedindex].split(',') + try: + expectedtype[3:] = [','.join(expectedtype[3:])] + testvalue = expectedtype[3] + except Exception: + testvalue = '' + if not valuetype == testvalue: + updatedcommands.append(self._send_commands[expectedindex]) + self.logger.log(VERBOSE2, "Parsing Input {}: Test Value is not same as Valuetype: {}. Adding to Sendcommands again.".format(self._name, testvalue, valuetype)) + else: + self.logger.log(VERBOSE2, "Parsing Input {}: Test Value is same as Valuetype: {}. Not adding to Sendcommands again.".format(self._name, testvalue, valuetype)) + except Exception as err: + self.logger.log(VERBOSE1, "Parsing Input {}: Write to dict problems: {}".format(self._name, err)) + + self.logger.log(VERBOSE2, "Parsing Input {}: Updated Command list {}.".format(self._name, updatedcommands)) + self._send_commands = updatedcommands + self.logger.log(VERBOSE1, "Parsing Input {}: Sendcommands: {}. Sendingcommand: {}".format(self._name, self._send_commands, self._sendingcommand)) + if not self._send_commands == [] and not self._sendingcommand == 'done': + self._resend_counter += 1 + try: + dependsvalue = self._dependson() + self.logger.debug("Parsing Input {}: Parsing depends on {}. It's value is {}, has to be {}.".format(self._name, self._dependson, dependsvalue, self._dependson_value)) + if dependsvalue == self._dependson_value: + depending = False + else: + depending = True + if self._depend0_volume0 is True or self._depend0_power0 is True: + self._resetondisconnect('parseinput') + except Exception as err: + depending = False + self.logger.log(VERBOSE1, "Parsing Input {}: Depending is false. Message {}.".format(self._name, err)) + if self._resend_counter >= self._resend_retries: + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter because maximum retries exceeded.".format(self._name)) + if not self._send_commands[0] in self._query_commands and not self._send_commands == []: + self._sendingcommand = self._send_commands[0] + self.logger.warning("Parsing Input {}: Going to reset item {}.".format(self._name, self._sendingcommand)) + self._resetitem() + temp_sendcommand = self._sendingcommand + self._sendingcommand = 'gaveup' + if data == 'ERROR': + connectionproblem = True + else: + connectionproblem = False + + if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._special_commands['Display']['Command']: + self._keep_commands[time.time()] = self._send_commands[0] + self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) + elif self._send_commands[0] in self._query_commands: + self.logger.warning("Parsing Input {}: Giving up {}, because no answer received.".format(self._name, temp_sendcommand)) + self._send_commands.pop(0) + self.logger.log(VERBOSE1, "Parsing Input {}: Send commands are now: {}".format(self._name, self._send_commands)) + elif depending is True: + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter because dependency not fulfilled.".format(self._name)) + try: + if not self._send_commands[0] in self._query_commands and not self._send_commands == []: + self._sendingcommand = self._send_commands[0] + self.logger.warning("Parsing Input {}: Reset item {} because dependency not fulfilled.".format(self._name, self._sendingcommand)) + self._resetitem() + self._sendingcommand = 'gaveup' + if self._send_commands[0] not in self._query_commands and not self._send_commands[0] in self._special_commands['Display']['Command'] and not self._sendingcommand == 'gaveup': + self._keep_commands[time.time()] = self._send_commands[0] + self.logger.debug("Parsing Input {}: Removing item from send command, storing in keep commands: {}.".format(self._name, self._keep_commands)) + elif self._send_commands[0] in self._query_commands: + self.logger.debug("Parsing Input {}: Giving up {}, because no answer received.".format(self._name, self._sendingcommand)) + self._send_commands.pop(0) + self.logger.log(VERBOSE1, "Parsing Input {}: Keepcommands: {}. Sendcommands: {}".format( + self._name, self._keep_commands, self._send_commands)) + except Exception as err: + self.logger.log(VERBOSE1, "Parsing Input {}: Nothing to reset as send commands is empty: {}. Message: {}".format(self._name, self._send_commands, err)) + if not self._sendingcommand == 'gaveup': + to_send = 'query' if (self._resend_counter % 2 == 1 and not self._send_commands[0].split(',')[1] == '') else 'command' + self.logger.debug("Parsing Input {}: Requesting {} from {} because response was {}. Resend Counter: {}".format( + self._name, to_send, self._send_commands[0], data, self._resend_counter)) + self._wait(self._resend_wait) + except Exception as err: + self.logger.warning("Parsing Input {}: Problems with checking for expected response. Error: {}".format(self._name, err)) + + updated = 0 + if not data == 'ERROR' and data not in self._error_response: + self.logger.log(VERBOSE1, "Parsing Input {}: Starting to compare values for data {}.".format(self._name, data)) + for key in sorted_response_commands: + self.logger.log(VERBOSE1, "Parsing Input {}: Starting to compare values for data {} with key: {}.".format(self._name, data, key)) + if data == key: + tempcommands = [] + for entry in self._send_commands: + if key not in entry: + tempcommands.append(entry) + self._send_commands = tempcommands + if self._sendingcommand not in self._send_commands and not self._send_commands == []: + self._sendingcommand = self._send_commands[0] + self.logger.debug("Parsing Input {}: Response is identical to expected response. Cleaned Send Commands: {}".format(self._name, self._send_commands)) + break + else: + for entry in self._response_commands[key]: + commandlength = entry[1] + valuelength = entry[0] + item = entry[3] + expectedtype = entry[7] + index = data.find(key) + self.logger.log(VERBOSE2, "Parsing Input {}: Entry: {}, Valuelength: {}, Expected Type: {}. ".format( + self._name, entry, valuelength, expectedtype)) + if not index == -1: + sametype = False + inputcommands = self._special_commands['Input']['Command'] + function = entry[4] + zone = entry[5] + if data.startswith(self._special_commands['Display']['Command']) and not self._special_commands['Display']['Command'] == '': + self.logger.debug("Parsing Input {}: Displaycommand found in response {}.".format(self._name, data)) + try: + content = data[2:][:28] + self.logger.log(VERBOSE1, "AVDevice {}: Display Data {}. Item: {}".format(self._name, content, item)) + tempvalue = "".join( + list(map(lambda i: chr(int(content[2 * i:][: 2], 0x10)), range(14)))).strip() + receivedvalue = re.sub(r'^[^A-Z0-9]*', '', tempvalue) + self.logger.debug("AVDevice {}: Display Output {}".format(self._name, receivedvalue)) + except Exception as err: + self.logger.warning("AVDevice {}: Problems getting display info. Error: {}".format(self._name, err)) + + elif data.startswith(tuple(self._special_commands['Nowplaying']['Command'])) and not self._special_commands['Nowplaying']['Command'] == '': + self.logger.debug("AVDevice {}: Now playing info found in response {}.".format(self._name, data)) + try: + m = re.search('"(.+?)"', data) + if m: + receivedvalue = m.group(1) + else: + receivedvalue = '' + except Exception as err: + self.logger.debug("AVDevice {}: Problems reading Now Playing info. Error:{}".format(self._name, err)) + elif data.startswith(tuple(self._special_commands['Speakers']['Command'])) and not self._special_commands['Speakers']['Command'] == '': + self.logger.debug("AVDevice {}: Speakers info found in response {}. Command: {}".format( + self._name, data, self._special_commands['Speakers']['Command'])) + receivedvalue = self._convertvalue(data[index + commandlength:index + commandlength + valuelength], expectedtype, False) + try: + for speakercommand in self._special_commands['Speakers']['Command']: + for zone in self._items_speakers: + for speakerlist in self._items_speakers[zone]: + speakerAB = sum(map(int, self._items_speakers[zone].keys())) + self.logger.debug("AVDevice {}: Received value: {}. Speaker {}. SpeakerAB: {}".format( + self._name, receivedvalue, speakerlist, speakerAB)) + if receivedvalue == int(speakerlist) or receivedvalue == speakerAB: + for speaker in self._items_speakers[zone][speakerlist]['Item']: + self.logger.info("AVDevice {}: Speaker {} is on.".format(self._name, speaker)) + speaker(1, 'AVDevice', self._tcp) + else: + for speaker in self._items_speakers[zone][speakerlist]['Item']: + self.logger.info("AVDevice {}: Speaker {} is off.".format(self._name, speaker)) + speaker(0, 'AVDevice', self._tcp) + + except Exception as err: + self.logger.warning("AVDevice {}: Problems reading Speakers info. Error:{}".format(self._name, err)) + else: + value = receivedvalue = data[index + commandlength:index + commandlength + valuelength] + self.logger.log(VERBOSE1, "Parsing Input {}: Neither Display nor Now Playing in response. receivedvalue: {}.".format( + self._name, receivedvalue)) + + invert = True if entry[6].lower() in ['1', 'true', 'yes', 'on'] else False + receivedvalue = self._convertvalue(value, expectedtype, invert) + + if isinstance(receivedvalue, eval(expectedtype)): + sametype = True + else: + sametype = False + + if sametype is False: + self.logger.log(VERBOSE1, "Parsing Input {}: Receivedvalue {} does not match type {} - ignoring it.".format(self._name, receivedvalue, expectedtype)) + else: + self.logger.log(VERBOSE1, "Parsing Input {}: Receivedvalue {} does match type {} - going on.".format(self._name, receivedvalue, expectedtype)) + if data.startswith(tuple(inputcommands)) and receivedvalue in self._ignoredisplay and '' not in self. _ignoredisplay: + for i in range(0, len(inputcommands)): + if data.startswith(inputcommands[i]): + self._special_commands['Input']['Ignore'][i] = 1 + if self._special_commands['Display']['Command'] not in self._ignore_response and not self._special_commands['Display']['Command'] == '' and '' not in self._ignore_response: + self._ignore_response.append(self._special_commands['Display']['Command']) + self.logger.error("Parsing Input {}: Data {} has value in ignoredisplay {}. Ignorecommands are now: {}. Display Ignore is {}. Input Ignore is {}".format(self._name, data, self._ignoredisplay, self._ignore_response, self._special_commands['Display']['Ignore'], self._special_commands['Input']['Ignore'])) + elif data.startswith(tuple(inputcommands)) and receivedvalue not in self._ignoredisplay and '' not in self. _ignoredisplay: + for i in range(0, len(inputcommands)): + if data.startswith(inputcommands[i]): + self._special_commands['Input']['Ignore'][i] = 0 + self.logger.log(VERBOSE2, "Parsing Input {}: Data {} has NO value in ignoredisplay {}. Ignorecommands are now: {}. Display Ignore is {}. Input Ignore is {}".format(self._name, data, self._ignoredisplay, self._ignore_response, self._special_commands['Display']['Ignore'], self._special_commands['Input']['Ignore'])) + if self._special_commands['Display']['Ignore'] == 0 and 1 not in self._special_commands['Input']['Ignore']: + while self._special_commands['Display']['Command'] in self._ignore_response: + self._ignore_response.remove(self._special_commands['Display']['Command']) + self.logger.log(VERBOSE2, "Parsing Input {}: Removing {} from ignore.".format(self._name, self._special_commands['Display']['Command'])) + value = receivedvalue + self.logger.debug("Parsing Input {}: Found key {} in response at position {} with value {}.".format( + self._name, key, index, value)) + + for entry in self._keep_commands: + self.logger.log(VERBOSE1, "Parsing Input {}: Testing Keep Command entry {}".format( + self._name, entry, self._keep_commands.get(entry))) + if data in self._keep_commands.get(entry).split(",")[2].split("|"): + self.logger.debug("Parsing Input {}: Removing {} from Keep Commands {} because corresponding value received.".format( + self._name, entry, self._keep_commands.get(entry), self._keep_commands)) + self._keep_commands.pop(entry) + break + if function in self._items[zone].keys(): + self._items[zone][function]['Value'] = value + self.logger.log(VERBOSE1, "Parsing Input {}: Updated Item dict {}".format(self._name, self._items[zone][function])) + + for singleitem in item: + singleitem(value, 'AVDevice', self._tcp) + self.logger.debug("Parsing Input {}: Updating Item {} with {} Value: {}.".format( + self._name, singleitem, expectedtype, value)) + updated = 1 + self._wait(0.15) + + if updated == 1: + self.logger.log(VERBOSE1, "Parsing Input {}: Updated all relevant items from item {}. step 1".format(self._name, item)) + break + if updated == 1: + self.logger.log(VERBOSE1, "Parsing Input {}: Updated all relevant items from {}. step 2".format(self._name, item)) + break + elif key.lower() == 'string': + value = data + if value.startswith(tuple(sorted_response_commands)): + self.logger.log(VERBOSE1, "Parsing Input {}: Found string for Item {} with Value {} but ignored because it is a legit response for another command.".format( + self._name, item, value)) + pass + else: + for singleitem in item: + singleitem(value, 'AVDevice', self._tcp) + self._wait(0.15) + self.logger.debug("Parsing Input {}: Updating item {} with value {}".format(self._name, singleitem, value)) + break + if updated == 1: + self.logger.log(VERBOSE1, "Parsing Input {}: Updated all relevant items from {}. step 3".format(self._name, item)) + break + if updated == 1: + self.logger.log(VERBOSE1, "Parsing Input {}: Updated all relevant items from {}. step 4".format(self._name, item)) + break + if self._send_commands == []: + self._sendingcommand = 'done' + self.logger.log(VERBOSE1, "Parsing Input {}: Finished. Send Commands: {}, sending Command: {}. Data: {}".format( + self._name, self._send_commands, self._sendingcommand, data)) + except Exception as err: + self.logger.error("Parsing Input {}: Problems parsing input. Error: {}".format(self._name, err)) + finally: + if not self._send_commands == [] and data == 'waiting': + self.logger.log(VERBOSE2, "Parsing Input {}: Waiting for response..".format(self._name)) + if not self._send_commands == [] and not data == 'waiting': + reorderlist = [] + index = 0 + for command in self._send_commands: + if command in self._query_commands: + reorderlist.append(command) + elif command in self._power_commands: + self.logger.log(VERBOSE1, "Parsing Input {}: Ordering power command {} to first position.".format(self._name, command)) + reorderlist.insert(0, command) + index += 1 + else: + reorderlist.insert(index, command) + index += 1 + self._send_commands = reorderlist + self.logger.debug('Parsing Input {}: Newly sorted send commands at end of parsing: {}'.format(self._name, self._send_commands)) + if self._is_connected == []: + for command in self._send_commands: + self.logger.log(VERBOSE1, "Parsing Input {}: Going to reset in the end because connection is lost: {}.".format(self._name, command)) + if command not in self._query_commands and command not in self._special_commands['Display']['Command'] and not self._sendingcommand == 'gaveup': + self._keep_commands[time.time()] = self._sendingcommand = command + self.logger.debug("Parsing Input {}: Removing item {} from send command because not connected, storing in keep commands: {}.".format( + self._name, command, self._keep_commands)) + self._resetitem() + self._send_commands.pop(0) + self.logger.debug('Parsing Input {}: First entry from send_commands removed. Send commands are now: {}'.format( + self._name, self._send_commands)) + else: + sending = self._send('{}'.format(to_send), 'parseinput_final') + self.logger.log(VERBOSE1, "Parsing Input {}: Sending again because list is not empty yet. Sending return is {}.".format( + self._name, sending)) + if 'Serial' in self._is_connected and connectionproblem is True: + self._is_connected.remove('Serial') + try: + self._is_connected.remove('Connecting') + except Exception: + pass + self._trigger_reconnect = True + if 'TCP' in self._is_connected and connectionproblem is True: + self._is_connected.remove('TCP') + try: + self._is_connected.remove('Connecting') + except Exception: + pass + self._trigger_reconnect = True + if self._trigger_reconnect is True and self._is_connected == []: + self.logger.log(VERBOSE1, "Parsing Input {}: Trying to connect while parsing item".format(self._name)) + self.connect('parse_dataerror') + + + + # Updating items based on value changes via Visu, CLI, etc. + def update_item(self, item, caller=None, source=None, dest=None): + if self.alive: + if caller != 'AVDevice': + try: + emptycommand = False + depending = True + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Starting to update item {}. Caller: {}, Source: {}. Destination: {}. Reconnectrigger is {}".format( + self._name.lower(), item, caller, source, dest, self._trigger_reconnect)) + # connect if necessary + if self._trigger_reconnect is True: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Trying to connect while updating item".format(self._name.lower())) + self.connect('update_item') + self.logger.debug("Updating Item for avdevice_{}: {} trying to update {}".format( + self._name.lower(), caller, item)) + if item == self._dependson: + try: + dependsvalue = self._dependson() + if dependsvalue == self._dependson_value: + depending = False + else: + depending = True + except Exception as e: + depending = False + if depending is False: + try: + eval(self._items['zone0']['statusupdate']['Item'][0])(1, 'Depending', self._rs232) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Depend value is same as set up, statusupdate starting {}.".format( + self._name.lower(), self._items['zone0']['statusupdate']['Item'][0])) + except Exception: + try: + self._items['zone0']['statusupdate']['Item'][0](1, 'Depending', self._rs232) + self.logger.debug("Updating Item for avdevice_{}: Updated Item after connection: {} with value 1. Commandlist: {}".format( + self._name, self._items['zone0']['statusupdate']['Item'][0], self._send_commands)) + except Exception as err: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: No statusupdate defined, not querying status after {}. Message: {}".format(self._name, caller, err)) + elif depending is True: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Depend value is false. No update of items.".format(self._name.lower())) + if self._depend0_volume0 is True or self._depend0_power0 is True: + self._resetondisconnect('updateitem') + if depending is True: + for zone in range(0, self._number_of_zones + 1): + command = '' + letsgo = False + try: + if self.has_iattr(item.conf, 'avdevice'): + command = self.get_iattr_value(item.conf, 'avdevice') + zoneX = True + elif self.has_iattr(item.conf, 'avdevice_zone{}_speakers'.format(zone)): + command = 'speakers' + zoneX = True + self.logger.debug("Updating Item for avdevice_{}: Command is {}. Zone is {}".format(self._name.lower(), command, zone)) + else: + zoneX = False + except Exception: + zoneX = False + try: + if self.has_iattr(item.conf, 'avdevice_zone{}'.format(zone)) or zoneX is True: + letsgo = True + except Exception: + if item == 'statusupdate' and zone == 0: + letsgo = True + else: + letsgo = False + if letsgo is True: + value = item() + if zoneX is False: + try: + command = self.get_iattr_value(item.conf, 'avdevice_zone{}'.format(zone)) + value = item() + except Exception: + command = 'statusupdate' + value = True + command_on = '{} on'.format(command) + command_off = '{} off'.format(command) + command_set = '{} set'.format(command) + command_increase = '{} increase'.format(command) + command_decrease = '{} decrease'.format(command) + updating = True + sending = True + + try: + if command is None: + command = '{} on'.format(command) + if command is None or command == 'None on': + command = '{} off'.format(command) + if command is None or command == 'None off': + command = '{} set'.format(command) + if command is None or command == 'None set': + command = '{} increase'.format(command) + if command is None or command == 'None increase': + command = '{} decrease'.format(command) + if self._functions['zone{}'.format(zone)][command][2] == '': + emptycommand = True + if not self._is_connected == []: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Function is empty. Sending nothing. Command: {} Item: {}".format( + self._name.lower(), command, item)) + if command == 'statusupdate': + try: + checkvalue = item() + except Exception: + checkvalue = True + if (checkvalue is True or caller == 'Init') and not self._special_commands['Display']['Ignore'] >= 5: + if not self._is_connected == []: + self._addkeepcommands('statusupdate', 'all') + for query in self._query_commands: + if query not in self._send_commands: + self._send_commands.append(query) + self._reconnect_counter = 0 + self._trigger_reconnect = True + if not self._is_connected == []: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Updating status. Sendcommands: {}. Reconnecttrigger: {}. Display Ignore: {}".format(self._name.lower(), self._send_commands, self._trigger_reconnect, self._special_commands['Display']['Ignore'])) + elif checkvalue is False and not self._special_commands['Display']['Ignore'] >= 5: + try: + dependsvalue = self._dependson() + self.logger.debug("Updating Item for avdevice_{}: Connection depends on {}. It's value is {}, has to be {}. Connections are {}".format(self._name.lower(), self._dependson, dependsvalue, self._dependson_value, self._is_connected)) + if dependsvalue == self._dependson_value: + depending = False + else: + depending = True + except Exception as e: + depending = False + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Depending is false. Message: {}".format(self._name.lower(), e)) + if depending is True or self._is_connected == [] or self._is_connected == ['Connecting'] and (self._depend0_volume0 is True or self._depend0_power0 is True): + self._resetondisconnect('statusupdate') + elif self._special_commands['Display']['Ignore'] >= 5: + sending = False + + updating = False + + elif self._functions['zone{}'.format(zone)][command][5].lower() == 'r': + self.logger.warning("Updating Item for avdevice_{}: Function is read only. Not updating. Command: {}".format( + self._name.lower(), command)) + updating = False + # Re-query Item to update value + commandinfo = self._functions['zone{}'.format(zone)][command] + self._send_commands.append('{},{},{},{}'.format(commandinfo[2], commandinfo[3], commandinfo[4], commandinfo[8])) + + except Exception as err: + self.logger.log(VERBOSE2, "Updating Item for avdevice_{}: Command {} is a standard command. Message: {}".format( + self._name.lower(), command, err)) + + if updating is True: + self.logger.debug("Updating Item for avdevice_{}: {} set {} to {} for {} in zone {}".format( + self._name.lower(), caller, command, value, item, zone)) + self._trigger_reconnect = True + setting = False + if command in self._functions['zone{}'.format(zone)]: + commandinfo = self._functions['zone{}'.format(zone)][command] + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], commandinfo[4], commandinfo[8]) + if appendcommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Command {} already in Commandlist. Ignoring.".format( + self._name.lower(), appendcommand)) + else: + self.logger.debug("Updating Item for avdevice_{}: Updating Zone {} Commands {} for {}".format( + self._name.lower(), zone, self._send_commands, item)) + self._send_commands.append(appendcommand) + elif command_increase in self._functions['zone{}'.format(zone)]: + commandinfo = self._functions['zone{}'.format(zone)][command_increase] + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], commandinfo[4], commandinfo[8]) + if appendcommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Increase Command {} already in Commandlist. Ignoring.".format( + self._name.lower(), appendcommand)) + else: + self.logger.debug("Updating Item for avdevice_{}: Updating Zone {} Command Increase {} for {}".format( + self._name.lower(), zone, self._send_commands, item)) + self._send_commands.append(appendcommand) + elif command_decrease in self._functions['zone{}'.format(zone)]: + commandinfo = self._functions['zone{}'.format(zone)][command_decrease] + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], commandinfo[4], commandinfo[8]) + if appendcommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Decrease Command {} already in Commandlist. Ignoring.".format( + self._name.lower(), appendcommand)) + else: + self._send_commands.append(appendcommand) + self.logger.debug("Updating Item for avdevice_{}: Updating Zone {} Command Decrease {} for {}".format( + self._name.lower(), zone, self._send_commands, item)) + elif command_on in self._functions['zone{}'.format(zone)] and isinstance(value, bool) and value == 1: + commandinfo = self._functions['zone{}'.format(zone)][command_on] + reverseinfo = self._functions['zone{}'.format(zone)][command_off] + try: + replacedcommand = commandinfo[4].replace('**', 'ON') + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], replacedcommand, commandinfo[8]) + replacedreverse = reverseinfo[4].replace('***', 'OFF') + reversecommand = '{},{},{},{}'.format(reverseinfo[2], reverseinfo[3], replacedreverse, commandinfo[8]) + if commandinfo[6].lower() in ['1', 'true', 'yes', 'on']: + replacedvalue = '0' + reversevalue = '1' + else: + replacedvalue = '1' + reversevalue = '0' + replacedcommand = replacedcommand.replace('*', replacedvalue) + reversecommand = reversecommand.replace('*', reversevalue) + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], replacedcommand, commandinfo[8]) + except Exception as err: + self.logger.debug("Updating Item for avdevice_{}: Problems replacing *: {}".format( + self._name.lower(), err)) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Appendcommand on: {}, Send Commands: {}".format( + self._name.lower(), appendcommand, self._send_commands)) + if appendcommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Command On {} already in Commandlist {}. Ignoring.".format( + self._name.lower(), appendcommand, self._send_commands)) + elif reversecommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Command Off {} already in Commandlist {}. Replacing with Command On {}.".format( + self._name.lower(), reversecommand, self._send_commands, appendcommand)) + self._send_commands[self._send_commands.index(reversecommand)] = self._sendingcommand = appendcommand + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: New Commandlist {}.".format( + self._name.lower(), self._send_commands)) + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter due to new command.".format(self._name)) + else: + self._send_commands.append(appendcommand) + self._sendingcommand = appendcommand + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Update Zone {} Command On {} for {}".format( + self._name.lower(), zone, commandinfo[2], item)) + if command_on == 'power on': + self._addkeepcommands('powercommand', 'zone{}'.format(zone)) + self.logger.debug("Updating Item for avdevice_{}: Command Power On for zone: {}. Appending relevant query commands: {}".format( + self._name.lower(), zone, self._query_zonecommands['zone{}'.format(zone)])) + for query in self._query_zonecommands['zone{}'.format(zone)]: + if query not in self._send_commands: + self._send_commands.append(query) + + elif command_off in self._functions['zone{}'.format(zone)] and isinstance(value, bool) and value == 0: + commandinfo = self._functions['zone{}'.format(zone)][command_off] + reverseinfo = self._functions['zone{}'.format(zone)][command_on] + try: + replacedcommand = commandinfo[4].replace('*******', 'STANDBY') + replacedcommand = replacedcommand.replace('***', 'OFF') + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], replacedcommand, commandinfo[8]) + replacedreverse = reverseinfo[4].replace('**', 'ON') + reversecommand = '{},{},{},{}'.format(reverseinfo[2], reverseinfo[3], replacedreverse, commandinfo[8]) + if commandinfo[6].lower() in ['1', 'true', 'yes', 'on']: + replacedvalue = '1' + reversevalue = '0' + else: + replacedvalue = '0' + reversevalue = '1' + replacedcommand = replacedcommand.replace('*', replacedvalue) + reversecommand = reversecommand.replace('*', reversevalue) + appendcommand = '{},{},{},{}'.format(commandinfo[2], commandinfo[3], replacedcommand, commandinfo[8]) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: replacedcommand: {} appendcommand: {}, replacedreverse: {}, reversecommand {}".format(self._name.lower(), replacedcommand, appendcommand, replacedreverse, reversecommand)) + except Exception as err: + self.logger.debug("Updating Item for avdevice_{}: Problems replacing *: {}".format( + self._name.lower(), err)) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Appendcommand off: {}. Reversecommand: {} Send Commands: {}".format( + self._name.lower(), appendcommand, reversecommand, self._send_commands)) + if appendcommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Command Off {} already in Commandlist {}. Ignoring.".format( + self._name.lower(), appendcommand, self._send_commands)) + elif reversecommand in self._send_commands: + self.logger.debug("Updating Item for avdevice_{}: Command On {} already in Commandlist {}. Replacing with Command Off {}.".format( + self._name.lower(), reversecommand, self._send_commands, appendcommand)) + self._send_commands[self._send_commands.index(reversecommand)] = self._sendingcommand = appendcommand + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: New Commandlist {}.".format( + self._name.lower(), self._send_commands)) + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter due to new command.".format(self._name)) + else: + self._send_commands.append(appendcommand) + self._sendingcommand = appendcommand + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Update Zone {} Command Off {} for {}".format( + self._name.lower(), zone, commandinfo[2], item)) + elif command_set in self._functions['zone{}'.format(zone)]: + commandinfo = self._functions['zone{}'.format(zone)][command_set] + if value == 0 and 'bool' in commandinfo[8]: + setting = True + value = 'OFF' + try: + command_re = re.sub('\*+', '{}'.format(value), commandinfo[2]) + response = re.sub('\*+', '{}'.format(value), commandinfo[4]) + except Exception: + command_re = commandinfo[2] + response = commandinfo[4] + self.logger.debug("Updating Item for avdevice_{}: Value 0 is converted to OFF. command_re: {}, response: {}".format(self._name.lower(), command_re, response)) + + elif (isinstance(value, int) and 'int' in commandinfo[8]) or (isinstance(value, float) and 'float' in commandinfo[8]): + setting = True + try: + value = max(min(value, int(commandinfo[7])), 0) + self.logger.debug("Updating Item for avdevice_{}: value limited to {}.".format( + self._name.lower(), commandinfo[7])) + except Exception: + self.logger.debug( + "Updating Item for avdevice_{}: Value limited to specific number of digits".format(self._name.lower())) + if commandinfo[2].count('*') > 1: + anzahl = commandinfo[2].count('*') + self.logger.log( + VERBOSE1, "Updating Item for avdevice_{}: Value has to be {} digits.".format(self._name.lower(), anzahl)) + value = max(min(value, int(re.sub('[^0-9]', '', re.sub('\*', '9', commandinfo[2])))), 0) + command_re = re.sub(r'(\*)\1+', '{0:0{1}d}'.format(value, anzahl), commandinfo[2]) + response = re.sub(r'(\*)\1+', '{0:0{1}d}'.format(value, anzahl), commandinfo[4]) + elif commandinfo[2].count('*') == 1: + if command.lower().startswith('speakers'): + currentvalue = int(self._items['zone{}'.format(zone)]['speakers']['Item'][0]()) + multiply = -1 if item() == 0 else 1 + multiply = 0 if (currentvalue == 0 and item() == 0) else multiply + value = abs(int(self.get_iattr_value(item.conf, 'avdevice_zone{}_speakers'.format(zone)))) + powercommands = self._functions['zone{}'.format(zone)]['power on'] + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Speaker {} current value is {}. Item: {} with value {}. Multiply: {}. Value: {}".format(self._name.lower(), self._items['zone{}'.format(zone)]['speakers']['Item'][0], currentvalue, item, item(), multiply, value)) + if not currentvalue == value or multiply == -1: + value = currentvalue + (value * multiply) + if value > 0: + if powercommands[6].lower() in ['1', 'true', 'yes', 'on']: + replacedvalue = '0' + else: + replacedvalue = '1' + self._send_commands.insert(0, '{},{},{},{}'.format( + powercommands[2], powercommands[3], powercommands[4].replace('*', replacedvalue), powercommands[8])) + self._sendingcommand = '{},{},{},{}'.format( + powercommands[2], powercommands[3], powercommands[4].replace('*', replacedvalue), powercommands[8]) + self.logger.debug("Updating Item for avdevice_{}: Turning power on. powercommands is: {}".format(self._name.lower(), powercommands)) + + else: + value = max(min(value, 9), 0) + command_re = commandinfo[2].replace('*', '{0:01d}'.format(value)) + response = commandinfo[4].replace('*', '{0:01d}'.format(value)) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Value has to be 1 digit. Value is {}".format(self._name.lower(), value)) + + elif commandinfo[2].count('*') == 0: + self.logger.error("Updating Item for avdevice_{}: Set command {} does not have any placeholder *.".format(self._name.lower(), commandinfo)) + + elif isinstance(value, str) and 'str' in commandinfo[8]: + setting = True + value = value.upper() + self.logger.debug("Updating Item for avdevice_{}: Value has to be string. Value is {}".format(self._name.lower(), value)) + try: + command_re = commandinfo[2].replace('*', '{}'.format(value)) + response = commandinfo[4].replace('*', '{}'.format(value)) + except Exception: + command_re = commandinfo[2] + response = commandinfo[4] + else: + setting = False + + else: + self.logger.error("Updating Item for avdevice_{}: Command {} not in text file!".format( + self._name.lower(), command)) + updating = False + + if not self._send_commands == [] and setting is True: + appending = True + setting = False + for sendcommand in self._send_commands: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Testing send command: {}".format(self._name.lower(), sendcommand)) + if commandinfo[3] in sendcommand: + valuetype = sendcommand.split(',') + try: + valuetype[3:] = [','.join(valuetype[3:])] + testvalue = valuetype[3] + except Exception: + testvalue = '' + if testvalue == commandinfo[8]: + self._sendingcommand = '{},{},{},{}'.format(command_re, commandinfo[3], response, commandinfo[8]) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Command Set {} already in Commandlist {}. Value type: {}, expected type: {}. Replaced. Sendingcommand: {}".format(self._name.lower(), command, self._send_commands, type(value), commandinfo[8], self._sendingcommand)) + self._send_commands[self._send_commands.index(sendcommand)] = '{},{},{},{}'.format(command_re, commandinfo[3], response, commandinfo[8]) + self._resend_counter = 0 + appending = False + self.logger.log(VERBOSE1, "Parsing Input {}: Resetting Resend Counter due to replaced command.".format(self._name)) + break + else: + self.logger.log(VERBOSE2, "Updating Item for avdevice_{}: Command Set {} already in Commandlist {} but value is not same type. Continue...".format( + self._name.lower(), command, self._send_commands)) + if appending is True: + self._send_commands.append('{},{},{},{}'.format(command_re, commandinfo[3], response, commandinfo[8])) + self._sendingcommand = '{},{},{},{}'.format(command_re, commandinfo[3], response, commandinfo[8]) + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Resetting Resend Counter because appending new set command.".format(self._name)) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Update Zone {} Command Set {} for {}. Command: {}".format( + self._name.lower(), zone, commandinfo[2], item, command_re)) + elif setting is True: + self._send_commands.append('{},{},{},{}'.format(command_re, commandinfo[3], response, commandinfo[8])) + self._resend_counter = 0 + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Resetting Resend Counter because adding new set command.".format(self._name)) + self.logger.debug("Updating Item for avdevice_{}: Update Zone {} Command Set, adding to empty Commandlist {} for {}. Command: {}".format( + self._name.lower(), zone, self._send_commands, item, command_re)) + + except Exception as err: + self.logger.error("Updating Item for avdevice_{}: Problem updating item. Error: {}. Does the item exist?".format( + self._name.lower(), err)) + finally: + if not self._send_commands == []: + reorderlist = [] + index = 0 + for command in self._send_commands: + if command in self._query_commands: + reorderlist.append(command) + else: + reorderlist.insert(index, command) + index += 1 + self._send_commands = reorderlist + self._sendingcommand = self._send_commands[0] + + try: + if not self._is_connected == [] and not self._send_commands == [] and not self._is_connected == ['Connecting']: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Updating item. Command list is {}. Sendingcommand: {}. ".format( + self._name.lower(), self._send_commands, self._sendingcommand)) + sending = self._send('command', 'updateitem') + + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Updating item. Command list is {}. Return from send is {}".format( + self._name.lower(), self._send_commands, sending)) + + if self._reset_onerror is True and emptycommand is False and not self._send_commands == [] and not self._sendingcommand == 'done' and self._is_connected == []: + if not self._send_commands[0].split(',')[0] == self._send_commands[0].split(',')[1]: + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Sending command {}. Starting to reset".format(self._name.lower(), self._sendingcommand)) + resetting = self._resetitem() + else: + resetting = '' + befehle = [] + for eintrag in self._send_commands: + befehle.append(eintrag.split(',')[0]) + try: + index = self._send_commands.index(self._sendingcommand) + except Exception: + index = befehle.index(self._sendingcommand) + self.logger.log(VERBOSE1, "Updating Item for avdevice_{}: Sending command {} not in Sendcommands {} list, but found in {}".format(self._name.lower(), self._sendingcommand, self._send_commands, befehle)) + if self._send_commands[index] not in self._query_commands and not self._send_commands[index] in self._special_commands['Display']['Command']: + self._keep_commands[time.time()] = self._send_commands[index] + self._send_commands.pop(index) + if self._depend0_volume0 is True or self._depend0_power0 is True: + self._resetondisconnect('update_end') + if resetting == '': + self.logger.debug("Updating Item for avdevice_{}: Connection error while trying to query info.".format(self._name.lower())) + else: + self.logger.info("Updating Item for avdevice_{}: Connection error. Resetting Item {}. Keepcommands: {}. Sendcommands: {} Sendingcommand: {}".format( + self._name.lower(), resetting, self._keep_commands, self._send_commands, self._sendingcommand)) + self._sendingcommand = 'done' + + except Exception as err: + if not self._is_connected == []: + self.logger.warning("Updating Item for avdevice_{}: Problem sending command. It is most likely not in the text file! Error: {}".format(self._name.lower(), err)) + else: + self.logger.warning( + "Updating Item for avdevice_{}: Problem sending command - not connected! Error: {}".format(self._name.lower(), err)) + + # Sending commands to the device + def _send(self, command, caller): + self.logger.log(VERBOSE1, "Sending {}: Sending function called by: {}. Command: {}.".format(self._name, caller, command)) + try: + if not self._send_commands == []: + if command == 'command': + to_send = self._send_commands[0].split(",")[0] + elif command == 'query': + to_send = self._send_commands[0].split(",")[1] + else: + to_send = command + command = 'Resendcommand' + commandlist = to_send.split("|") + self.logger.log(VERBOSE1, "Sending {}: Starting to send {} {} from list {}. Caller: {}.".format(self._name, command, to_send, self._send_commands, caller)) + try: + self._sendingcommand = self._send_commands[0] + except Exception: + self._sendingcommand = to_send + response = self._send_commands[0].split(",")[2].split("|") + if self._parsinginput == []: + self.logger.log(VERBOSE1, "Sending {}: Starting Parse Input. Expected response: {}".format(self._name, response)) + self._parse_input_init('sending') + + for resp in response: + if resp in self._special_commands['Display']['Command']: + keyfound = True + else: + keyfound = False + if self._send_commands[0] in self._query_commands and len(self._send_commands) > 1 and keyfound is not True and self._special_commands['Display']['Ignore'] < 5: + self._special_commands['Display']['Ignore'] = self._special_commands['Display']['Ignore'] + 5 + if self._special_commands['Display']['Command'] not in self._ignore_response and '' not in self._ignore_response and not self._special_commands['Display']['Command'] == '': + self._ignore_response.append(self._special_commands['Display']['Command']) + self.logger.log(VERBOSE2, "Sending {}: Querycommand. Command: {}. Querycommand: {}, Display Ignore: {}, Input Ignore: {}".format( + self._name, self._send_commands[0], self._query_commands, self._special_commands['Display']['Ignore'], self._special_commands['Input']['Ignore'])) + + elif self._send_commands[0] not in self._query_commands or len(self._send_commands) <= 1 or keyfound is True: + if self._special_commands['Display']['Ignore'] >= 5: + self._special_commands['Display']['Ignore'] = self._special_commands['Display']['Ignore'] - 5 + if self._special_commands['Display']['Ignore'] == 0 and 1 not in self._special_commands['Input']['Ignore']: + while self._special_commands['Display']['Command'] in self._ignore_response: + self._ignore_response.remove(self._special_commands['Display']['Command']) + self.logger.log(VERBOSE1, "Sending {}: Removing {} from ignore. Ignored responses are now: {}".format(self._name, self._special_commands['Display']['Command'], self._ignore_response)) + + if self._trigger_reconnect is True: + self.logger.log(VERBOSE1, "Sending {}: Trying to connect while sending command".format(self._name)) + self.connect('send') + cmd = 0 + for multicommand in commandlist: + cmd += 1 + if self._rs232 is not None: + # result = self._serial.write(bytes('{}\r'.format(multicommand), 'utf-8')) + result = self._serialwrapper.write(u'{}\r'.format(multicommand)) + self._serialwrapper.flush() + self.logger.debug("Sending Serial {}: {} was sent {} from Multicommand-List {}. Returns {}. Sending command: {}".format(self._name, command, multicommand, commandlist, result, self._sendingcommand)) + self._wait(0.2) + return result + + elif self._tcp is not None: + result = self._tcpsocket.send(bytes('{}\r'.format(multicommand), 'utf-8')) + self.logger.debug("Sending TCP {}: {} was sent {} from Multicommand-List {}. Returns {}".format(self._name, command, multicommand, commandlist, result)) + self._wait(0.2) + return result + + else: + self.logger.error("Sending {}: Neither IP address nor Serial device definition found".format(self._name)) + except IOError as err: + if err.errno == 32: + self.logger.warning( + "Sending {}: Problem sending multicommand {}, not connected. Message: {}".format(self._name, self._send_commands[0], err)) + try: + self._tcpsocket.shutdown(2) + self._tcpsocket.close() + self.logger.debug("Sending {}: TCP socket closed".format(self._name)) + except Exception: + self.logger.log(VERBOSE1, "Sending {}: No TCP socket to close.".format(self._name)) + try: + self._is_connected.remove('TCP') + self._is_connected.remove('Connecting') + self.logger.log(VERBOSE1, "Sending {}: reconnect TCP started.".format(self._name)) + self.connect('send_IOError_TCP') + + except Exception: + self.logger.debug("Sending {}: Cannot reconnect TCP.".format(self._name)) + try: + self._serialwrapper.close() + self.logger.debug("Sending {}: Serial socket closed".format(self._name)) + except Exception: + self.logger.log(VERBOSE1, "Sending {}: No Serial socket to close.".format(self._name)) + try: + self._is_connected.remove('Serial') + self._is_connected.remove('Connecting') + self.logger.log(VERBOSE1, "Sending {}: reconnect Serial started.".format(self._name)) + self.connect('send_IOError_RS232') + except Exception: + self.logger.debug("Sending {}: Cannot reconnect Serial.".format(self._name)) + + except Exception as err: + try: + self.logger.warning("Sending {}: Problem sending multicommand {}. Message: {}".format(self._name, self._send_commands[0], err)) + except Exception: + self.logger.warning("Sending {}: Problem sending multicommand {}. Message: {}".format(self._name, self._send_commands, err)) + + # Stopping function when SmarthomeNG is stopped + def stop(self): + self.alive = False + self._sh.scheduler.change('avdevice-tcp-reconnect', active=False) + self._sh.scheduler.remove('avdevice-tcp-reconnect') + self._sh.scheduler.change('avdevice-serial-reconnect', active=False) + self._sh.scheduler.remove('avdevice-serial-reconnect') + + try: + self._tcpsocket.shutdown(2) + self._tcpsocket.close() + self.logger.debug("Stopping {}: closed".format(self._name)) + except Exception: + self.logger.log(VERBOSE1, "Stopping {}: No TCP socket to close.".format(self._name)) + try: + self._serialwrapper.close() + except Exception: + self.logger.log(VERBOSE1, "Stopping {}: No Serial socket to close.".format(self._name)) if __name__ == '__main__': - logging.basicConfig( - level=logging.DEBUG, format='%(relativeCreated)6d %(threadName)s %(message)s') - # todo - # change PluginClassName appropriately - PluginClassName(Arduino).run() + logging.basicConfig( + level=logging.DEBUG, format='%(relativeCreated)6d %(threadName)s %(message)s') + PluginClassName(AVDevice).run() diff --git a/avdevice/denon-avr6300.txt b/avdevice/denon-avr6300.txt old mode 100755 new mode 100644 index fd1f7cbb6..1676ba907 --- a/avdevice/denon-avr6300.txt +++ b/avdevice/denon-avr6300.txt @@ -1,16 +1,52 @@ -ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE;TYPE -0;power on;PWON|PWON;PW?;PW**;RW -0;power off;PWOFF;PW?;PW***;RW -1;power on;ZMON;ZM?;ZM**;RW -1;power off;ZMOFF;ZM?;ZM***;RW -1;mute on;MUON;MU?;MU**;RW -1;mute off;MUOFF;MU?;MU***;RW -1;volume set;MV**;MV?;MV**;RW -1;volume+;MVUP;MV?;MV;W -1;volume-;MVDOWN;MV?;MV;W -1;volumemax;;MV?;MVMAX **;R -2;power on;Z2ON;Z2?;Z2**;RW -2;power off;Z2OFF;Z2?;Z2***;RW -3;power on;Z3ON;Z3?;Z3**;RW -3;power off;Z3OFF;Z3?;Z3***;RW -0;statusupdate;;;;W \ No newline at end of file +ZONE; FUNCTION; FUNCTIONTYPE; SEND; QUERY; RESPONSE; READWRITE; INVERTRESPONSE; MAXVALUE; RESPONSETYPE +0; power; on; PWON|PWON; PW?; PW**; RW +0; power; off; PWSTANDBY; PW?; PW*******; RW +0; eco; set; ECO*; ECO?; ECO*; RW; ; ; string,bool +1; power; on; ZMON; ZM?; ZM**; RW +1; power; off; ZMOFF; ZM?; ZM***; RW +1; mute; on; MUON; MU?; MU**; RW +1; mute; off; MUOFF; MU?; MU***; RW +1; sleep; set; SLP***; SLP?; SLP***; RW; ; 120; num,bool +1; standby; set; STBY*; STBY?; STBY*; RW; ; ; string +1; volume; set; MV**; MV?; MV**; RW; ; 90 +1; volume+; increase; MVUP; ; MV; W +1; volume-; decrease; MVDOWN; ; MV; W +1; volumefl; set; CVFL **; CV?; CVFL **|CVEND; RW; ; 62 +1; volumefl+; increase; CVFL UP; CV?; CVFL|CVEND; W +1; volumefl-; decrease; CVFL DOWN; CV?; CVFL|CVEND; W +1; volumefr; set; CVFR **; CV?; CVFR **|CVEND; RW; ; 62 +1; volumefr+; increase; CVFL UP; CV?; CVFR|CVEND; W +1; volumefr-; decrease; CVFR DOWN; CV?; CVFR|CVEND; W +1; volumelow; ; MV50; MV?; MV50; W; ; ; num +1; volumehigh; ; MV75; MV?; MV75; W; ; ; num +1; volumemax; ; MVMAX **; MV?; MVMAX **; RW +1; input; set; SI*; SI?; SI*; RW; ; ; string +1; mode; set; MS*; MS?; MS*; RW; ; ; string +1; audioinput; set; SD*; SD?; SD*; RW; ; ; string,bool +1; videoinput; set; SV*; SV?; SV*; RW; ; ; string,bool +1; digitalinput; set; DC*; DC?; DC*; RW; ; ; string +1; video; set; VS*; ; VS*; RW; ; ; string +2; power; on; Z2ON; Z2?; Z2**; RW +2; power; off; Z2OFF; Z2?; Z2***; RW +2; input; set; Z2*; Z2?; Z2*; RW; ; ; string +2; mute; on; Z2MUON; Z2MU?; Z2MU**; RW +2; mute; off; Z2MUOFF; Z2MU?; Z2MU***; RW +2; volume+; increase; Z2UP; ; Z2; W +2; volume-; decrease; Z2DOWN; ; Z2; W +2; volumelow; ; Z250; MV?; Z250; W; ; ; num +2; volumehigh; ; Z275; MV?; Z275; W; ; ; num +2; volume; set; Z2**; Z2?; Z2**; RW; ; 90 +2; standby; set; Z2STBY*; Z2STBY?; Z2STBY*; RW; ; ; string +2; sleep; set; Z2SLP***; Z2SLP?; Z2SLP***; RW; ; 120; num,bool +3; power; on; Z3ON; Z3?; Z3**; RW +3; power; off; Z3OFF; Z3?; Z3***; RW +3; input; set; Z3*; Z3?; Z3*; RW; ; ; string +3; mute; on; Z3MUON; Z3MU?; Z3MU**; RW +3; mute; off; Z3MUOFF; Z3MU?; Z3MU***; RW +3; volume+; increase; Z3UP; ; Z3; W +3; volume-; decrease; Z3DOWN; ; Z3; W +3; volumelow; ; Z350; MV?; Z350; W; ; ; num +3; volumehigh; ; Z375; MV?; Z375; W; ; ; num +3; volume; set; Z3**; Z3?; Z3**; RW; ; 90 +3; standby; set; Z3STBY*; Z3STBY?; Z3STBY*; RW; ; ; string +3; sleep; set; Z3SLP***; Z3SLP?; Z3SLP***; RW; ; 120; num,bool \ No newline at end of file diff --git a/avdevice/epson-tw5000.txt b/avdevice/epson-tw5000.txt index ee7ec7436..437dd236a 100755 --- a/avdevice/epson-tw5000.txt +++ b/avdevice/epson-tw5000.txt @@ -1,4 +1,3 @@ -ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE;TYPE -0;power on;PWR ON;PWR?;:PWR=0*|:WR=0*|PWR=0*;RW;no;1;bool -0;power off;PWR OFF;PWR?;:PWR=0*|:WR=0*|PWR=0*;RW;no;1;bool -0;statusupdate;;;;W \ No newline at end of file +ZONE; FUNCTION; FUNCTIONTYPE; SEND; QUERY; RESPONSE; READWRITE; INVERTRESPONSE; MAXVALUE; TYPE +0; power; on; PWR ON; PWR?; :PWR=0*|:WR=0*|PWR=0*; RW; no; 1; bool +0; power; off; PWR OFF; PWR?; :PWR=0*|:WR=0*|PWR=0*; RW; no; 1; bool \ No newline at end of file diff --git a/avdevice/plugin.yaml b/avdevice/plugin.yaml new file mode 100755 index 000000000..ed20e3bc3 --- /dev/null +++ b/avdevice/plugin.yaml @@ -0,0 +1,183 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: interface # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Steuerung von diversen AV Geräten über TCP/IP und RS232 Schnittstelle, **seit SmartHomeNG v1.3**' + en: 'Controlling AV devices via TCP/IP and RS232' + maintainer: onkelandy + tester: Foxi352 # Who tests this plugin? + keywords: av denon pioneer epson amp receiver projector rs232 telnet tcpip +# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page + support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1097870-neues-plugin-av-device-f%C3%BCr-yamaha-pioneer-denon-etc + + version: 1.3.2 # Plugin version + sh_minversion: 1.3 # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: True # plugin supports multi instance + classname: AVDevice # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + model: + type: str + default: '' + mandatory: True + description: + de: 'Name des Geräts. Muss mit dem Namen der Textdatei unter plugins/avdevice korrelieren, die sämtliche Befehle beinhaltet.' + en: 'Name of AV device. Has to correspond to a text file with the same name in the folder plugins/avdevice including all commands.' + + tcp_ip: + type: ip + default: 0.0.0.0 + description: + de: 'Beim Nutzen der TCP Verbindungen ist die IP Adresse des Endgeräts anzugeben.' + en: 'If you use TCP connection define IP address of your device.' + + tcp_port: + type: int + default: 23 + description: + de: 'Beim Nutzen der TCP Verbindungen ist der Port anzugeben, auf dem das Gerät Verbindungen zulässt. Für Denon: 23, für Pioneer: 8002.' + en: 'If you use TCP connection define the port where your device accepts TCPIP connections. For Denon use 23, for Pioneer 8002.' + + tcp_timeout: + type: int + default: 1 + description: + de: 'Beim Nutzen der TCP Verbindungen kann ein Timeout angegeben werden.' + en: 'If you use TCP connection you can define a connection timeout.' + + rs232_port: + type: str + default: '' + description: + de: "Beim Nutzen einer RS232 Schnittstelle (empfohlen!) ist die serielle Schnittstelle anzugeben." + en: "If you use a RS232 cable to communicate with your device (highly recommended!) define the serial port." + + rs232_baudrate: + type: int + default: 9600 + description: + de: "Beim Nutzen einer RS232 Schnittstelle ist die benötigte Baudrate anzugeben." + en: "If you use a RS232 interface define the baudrate." + + rs232_timeout: + type: float + default: 0.1 + description: + de: "Beim Nutzen einer RS232 Schnittstelle kann ein Timeout zum Lesen und Schreiben definiert werden." + en: "If you use a RS232 interface you can define read and write timeout." + + ignoreresponse: + type: str + default: 'RGB,RGC,RGD,GBH,GHH,LM0,VTA,AUA,AUB' + description: + de: "Das Plugin ignoriert Antworten die mit den hier angegebenen Werten starten, beispielsweise Rückmeldungen für die Menünavigation, etc. Der Defaultwert ist für Pioneer Receiver empfohlen." + en: "The plugin doesn't care about responses from the device starting with the given values. List responses for menu navigation, etc. The default value is recommended for Pioneer receivers." + + forcebuffer: + type: str + default: 'GEH01020,GEH04022,GEH05024' + description: + de: "Wenn aus irgendeinem Grund die Antworten nicht gepuffert werden sollen, können hier dennoch Antworten definiert werden, die sehr wohl gepuffert werden. Dies ist besonders wichtig bei Informationen, die schnell hintereinander gesendet werden bzw. wechseln wie Künstler, Musiktitel, Radiostation, etc. Der Defaultwert ist für Pioneer Receiver empfohlen." + en: "If for whatever reason you don't want to buffer the response from your device you can still define specific responses that should get buffered. This is important for responses that change or get sent very quickly. Artist, title, radio station, etc. are examples that should be put here. The default value is recommended for Pioneer receivers." + + inputignoredisplay: + type: str + default: '' + description: + de: "Die LCD Anzeige auf dem Gerät wird mitunter sehr häufig aktualisiert, zB bei einem scrollenden Text bei Songtiteln. Um ein ständiges Update und dadurch Konflikte mit tatsächlich relevanten Rückmeldungen zu vermeiden, können hier Source Typen hinterlegt werden. Internet Radio, LAN Streaming, etc. werden empfohlen. Für Pioneer-Receiver werden empfohlen: 26,38,40,41,44,17,02,48,0" + en: "The value of the LCD display on your receiver might get updated very often, e.g. when it shows song titles as a scrolling text. To avoid constant display updates and therefore possible confusion with relevant answers of your device listing source inputs like internet radio, LAN streaming, etc. here is highly recommended. For Pioneer receivers use: 26,38,40,41,44,17,02,48,0" + + dependson_item: + type: str + default: '' + description: + de: "Wenn das angegebene Item den angegebenen Wert erhält, werden die Befehle gesendet, ansonsten nicht. Das ist insbesondere dann sinnvoll, wenn das Gerät an einer schaltbaren Steckdose hängt." + en: " If given item has given value the commands are sent to the device, otherwise they are not. Relevant if you have your device connected to a power socket that can be turned off." + + dependson_value: + type: bool + default: True + description: + de: "Wenn das angegebene Item den angegebenen Wert erhält, werden die Befehle gesendet, ansonsten nicht. Das ist insbesondere dann sinnvoll, wenn das Gerät an einer schaltbaren Steckdose hängt." + en: " If given item has given value the commands are sent to the device, otherwise they are not. Relevant if you have your device connected to a power socket that can be turned off." + + errorresponse: + type: str + default: 'E02,E04,E06' + description: + de: "Standard Fehlermeldungen des Geräts, bei Pioneer beispielsweise ein 'E' gefolgt von einer Nummer. Werden diese Antworten hier nicht angegeben, werden Rückmeldungen unter Umständen deutlich langsamer verarbeitet, aber voraussichtlich trotzdem erkannt." + en: "The standard error responses from your device. For Pioneer receivers they are 'E' followed by a number. If no values are provided error answers from your device might get recognized much slower but actually should still get recognized." + + resetonerror: + type: bool + default: False + description: + de: "Zurücksetzen des Items auf den vorigen Wert, wenn kein Update durchgeführt werden konnte, zB das Setzen der Lautstärke in einer abgeschalteten Zone. Sobald das dependson Item ausgeschaltet wird oder mehrere Verbindungs- und Sendeversuche fehlgeschlagen sind, wird das Item zurückgesetzt, damit keine falschen Werte in der Visu angezeigt werden." + en: "Reset the value of the item that could not be updated. E.g. you set the volume of zone 2 when it is not powered on. If either the dependson item is off or the device sends an error response or after several connection and send retries the expected response is not received, the item gets set to the value it had before you sent the command. That way you avoid having a wrong value displayed in your Visu." + + depend0_power0: + type: bool + default: False + description: + de: "Wenn das dependson Item abgeschaltet ist, werden alle Poweritems ebenfalls auf 0 gesetzt. Das ist dann relevant, wenn beispielsweise das Gerät eingeschaltet ist, die Steckdose aber ausgeschaltet wird. Durch Aktivieren dieser Funktion werden automatisch die Poweritems auf 0 gesetzt." + en: "If the dependson item is off the power off all zones are set to off. This is especially relevant for a correct representation in your Visu when you have a powered on device but turn off the power socket." + + depend0_volume0: + type: bool + default: False + description: + de: "Wie beim obigen Attribut dient auch diese Funktion zum korrekten Update der Visu auf den Lautstärkewert 0, sobald das dependson Item deaktiviert wird (zB Ausschalten der Steckdose)." + en: "Same as above but in this case the volume is set to 0 for all zones. This is for Visu purposes only." + + sendretries: + type: int + default: 10 + description: + de: "Dieser Wert definiert, wie oft bei einer falschen Antwort versucht werden soll, den Befehl nochmals zu senden." + en: "This value defines how often a command should be sent when receiving a wrong answer from the device." + + resendwait: + type: float + default: 1.0 + description: + de: "Angabe der Pause zwischen Resend Versuchen in Sekunden" + en: "Seconds the plugin should wait between each resend retry." + + reconnectretries: + type: int + default: 13 + description: + de: "Anzahl der Verbindungsversuche bei Verbindungsproblemen. Das ist insbesondere bei TCP Verbindungen von Geräten relevant, die an schaltbaren Steckdosen hängen, da diese oftmals 30-40 Sekunden zum Hochfahren benötigen." + en: "If the plugin can not connect to the device it retries this often. This is especially useful for TCP connections on devices that are plugged into a switchable socket as most receivers need about 40-50 seconds to boot their network device." + + secondstokeep: + type: int + default: 50 + description: + de: "Dauer in Sekunden, wie lange ein Kommando, das nicht erfolgreich war in einem Zwischenspeicher aufbewahrt werden soll. Dies ist besonders bei TCP Verbindungen mit Geräten an schaltbaren Steckdosen relevant, da diese ofmals 30-40 Sekunden zum Hochfahren benötigen." + en: "Seconds the plugin should temporarily save a command to retry later on after establishing a connection. This is especially useful for TCP connections on devices that are plugged into a switchable socket as most receivers need about 40-50 seconds to boot their network device." + + responsebuffer: + type: int + default: 5 + description: + de: "Schnell hintereinander empfangene Werte werden bei einer negativen Attributangabe im Puffer gespeichert und gemeinsam verarbeitet. Der Standardwert sollte dafür sorgen, dass keine Antworten verloren gehen. Einige Receiver antworten unter Umständen immer zuerst mit der Angabe zum auf dem Display gezeigten Wert. Der Puffer sorgt dafür, dass auch eine nachfolgende Rückmeldung evaluiert wird." + en: "Set this to a number to collect quickly received responses in a buffer and evaluate them collectively. The standard value should be fine and prevent responses getting lost. Some receivers might first respond to a command with an update of the display and then with the actual value. The buffer ensures the correct evaluation of the response." + + autoreconnect: + type: bool + default: False + description: + de: "Automatischer Versuch, sich mit dem Gerät zu verbinden, wenn keine Rückmeldung kommt oder die Verbindung verloren wurde. Dies sollte nicht notwendig sein, da das Plugin ohnehin bei jedem neuen Senden eines Befehls einen Verbindungsaufbauversuch startet." + en: "Automatically tries to reconnect if no response is received or connection is lost. This should not be necessary as the plugin always tries to reconnect before sending a command." + +item_attributes: + avdevice_zone[0-4]: + type: str + description: + de: 'Obiges Attribut muss mit dem Kommando ergänzt werden, das in der Text Datei hinterlegt ist, zB power oder volume' + en: 'This attribute has to be followed by one of the commands declared in the device text file like power or volume' + diff --git a/avdevice/sc-lx86.txt b/avdevice/sc-lx86.txt index 67387cf28..7206df569 100755 --- a/avdevice/sc-lx86.txt +++ b/avdevice/sc-lx86.txt @@ -1,40 +1,39 @@ -ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE -1;power on;PO|PO;?P;PWR*;RW;yes -1;power off;PF;?P;PWR*;RW;yes -1;volume+;VU;?V;VOL;W -1;volume-;VD;?V;VOL;W -1;volumehigh;150VL;?V;VOL150;W -1;volumelow;110VL;?V;VOL110;W -1;volume set;***VL;?V;VOL***;RW;;161 -1;mute on;MO;?M;MUT*;RW;yes -1;mute off;MF;?M;MUT*;RW;yes -1;mode set;****SR;?S;SR****;RW -1;input set;**FN;?F;FN**;RW -2;power on;APO|APO;?AP;APR*;RW;yes -2;power off;APF;?AP;APR*;RW;yes -2;volume+;ZU;?ZV;ZV;W -2;volume-;ZD;?ZV;ZV;W -2;volumehigh;70ZV;?ZV;ZV70;W -2;volumelow;45ZV;?ZV;ZV45;W -2;volume set;**ZV;?ZV;ZV**;RW;;81 -2;mute on;Z2MO;?Z2M;Z2MUT*;RW;yes -2;mute off;Z2MF;?Z2M;Z2MUT*;RW;yes -2;input set;**ZS;?ZS;Z2F**;RW -3;power on;BPO|BPO;?BP;BPR*;RW;yes -3;power off;BPF;?BP;BPR*;RW;yes -3;volume+;YU;?YV;YV;W -3;volume-;YD;?YV;YV;W -3;volumehigh;75YV;?YV;YV75;W -3;volumelow;45YV;?YV;YV45;W -3;volume set;**YV;?YV;YV**;RW;;81 -3;mute on;Z3MO;?Z3M;Z3MUT*;RW;yes -3;mute off;Z3MF;?Z3M;Z3MUT*;RW;yes -3;input set;**ZT;?ZT;Z3F**;RW -4;power on;ZEO;?ZEP;ZEP*;RW;yes -4;power off;ZEF;?ZEP;ZEP*;RW;yes -4;input set;**ZEA;?ZEA;ZEA**;RW -0;title;;;GEH01020;R -0;station;;;GEH04022;R -0;genre;;;GEH05024;R -0;statusupdate;;;;W -0;display;?FL;?FL;FL******************************;R +ZONE; FUNCTION; FUNCTIONTYPE; SEND; QUERY; RESPONSE; READWRITE; INVERTRESPONSE; MAXVALUE; RESPONSETYPE +1; power; on; PO|PO; ?P; PWR*; RW; yes +1; power; off; PF; ?P; PWR*; RW; yes +1; volume+; ; VU; ; VOL; W +1; volume-; ; VD; ; VOL; W +1; volumehigh; ; 150VL; ?V; VOL150; W +1; volumelow; ; 110VL; ?V; VOL110; W +1; volume; set; ***VL; ?V; VOL***; RW; ; 161 +1; mute; on; MO; ?M; MUT*; RW; yes +1; mute; off; MF; ?M; MUT*; RW; yes +1; mode; set; ****SR; ?S; SR****; RW +1; input; set; **FN; ?F; FN**; RW +2; power; on; APO|APO; ?AP; APR*; RW; yes +2; power; off; APF; ?AP; APR*; RW; yes +2; volume+; ; ZU; ; ZV; W +2; volume-; ; ZD; ; ZV; W +2; volumehigh; ; 70ZV; ?ZV; ZV70; W +2; volumelow; ; 45ZV; ?ZV; ZV45; W +2; volume; set; **ZV; ?ZV; ZV**; RW; ; 81 +2; mute; on; Z2MO; ?Z2M; Z2MUT*; RW; yes +2; mute; off; Z2MF; ?Z2M; Z2MUT*; RW; yes +2; input; set; **ZS; ?ZS; Z2F**; RW +3; power; on; BPO|BPO; ?BP; BPR*; RW; yes +3; power; off; BPF; ?BP; BPR*; RW; yes +3; volume+; ; YU; ; YV; W +3; volume-; ; YD; ; YV; W +3; volumehigh; ; 75YV; ?YV; YV75; W +3; volumelow; ; 45YV; ?YV; YV45; W +3; volume; set; **YV; ?YV; YV**; RW; ; 81 +3; mute; on; Z3MO; ?Z3M; Z3MUT*; RW; yes +3; mute; off; Z3MF; ?Z3M; Z3MUT*; RW; yes +3; input; set; **ZT; ?ZT; Z3F**; RW +4; power; on; ZEO; ?ZEP; ZEP*; RW; yes +4; power; off; ZEF; ?ZEP; ZEP*; RW; yes +4; input; set; **ZEA; ?ZEA; ZEA**; RW +0; title; ; ; ; GEH01020; R +0; station; ; ; ; GEH04022; R +0; genre; ; ; ; GEH05024; R +0; display; ; ?FL; ?FL; FL******************************; R diff --git a/avdevice/vsx-923.txt b/avdevice/vsx-923.txt index 855d07502..148f4656b 100755 --- a/avdevice/vsx-923.txt +++ b/avdevice/vsx-923.txt @@ -1,27 +1,26 @@ -ZONE;FUNCTION;SEND;QUERY;RESPONSE;READWRITE;INVERTRESPONSE;MAXVALUE -1;power on;PO|PO;?P;PWR*;RW;yes -1;power off;PF;?P;PWR*;RW;yes -1;volume+;VU;?V;VOL;W -1;volume-;VD;?V;VOL;W -1;volumehigh;150VL;?V;VOL150;W -1;volumelow;110VL;?V;VOL110;W -1;volume set;***VL;?V;VOL***;RW;;185 -1;mute on;MO;?M;MUT*;RW;yes -1;mute off;MF;?M;MUT*;RW;yes -1;input set;**FN;?F;FN**;RW -2;power on;APO|APO;?AP;APR*;RW;yes -2;power off;APF;?AP;APR*;RW;yes -2;volume+;ZU;?ZV;ZV;W -2;volume-;ZD;?ZV;ZV;W -2;volumehigh;75ZV;?ZV;ZV75;W -2;volumelow;45ZV;?ZV;ZV45;W -2;volume set;**ZV;?ZV;ZV**;RW;;81 -2;mute on;Z2MO;?Z2M;Z2MUT*;RW;yes -2;mute off;Z2MF;?Z2M;Z2MUT*;RW;yes -2;input set;**ZS;?ZS;Z2F**;RW -0;title;;;GEH01020;R -0;station;;;GEH04022;R -0;genre;;;GEH05024;R -0;statusupdate;;;;W -0;display;?FL;?FL;FL******************************;R -1;speakers set;*SPK;?SPK;SPK*;RW +ZONE; FUNCTION; FUNCTIONTYPE; SEND; QUERY; RESPONSE; READWRITE; INVERTRESPONSE; MAXVALUE; RESPONSETYPE +1; power; on; PO|PO; ?P; PWR*; RW; yes +1; power; off; PF; ?P; PWR*; RW; yes +1; volume+; ; VU; ; VOL; W +1; volume-; ; VD; ; VOL; W +1; volumehigh; ; 150VL; ?V; VOL150; W +1; volumelow; ; 110VL; ?V; VOL110; W +1; volume; set; ***VL; ?V; VOL***; RW; ; 185 +1; mute; on; MO; ?M; MUT*; RW; yes +1; mute; off; MF; ?M; MUT*; RW; yes +1; input; set; **FN; ?F; FN**; RW +2; power; on; APO|APO; ?AP; APR*; RW; yes +2; power; off; APF; ?AP; APR*; RW; yes +2; volume+; ; ZU; ; ZV; W +2; volume-; ; ZD; ; ZV; W +2; volumehigh; ; 75ZV; ?ZV; ZV75; W +2; volumelow; ; 45ZV; ?ZV; ZV45; W +2; volume; set; **ZV; ?ZV; ZV**; RW; ; 81 +2; mute; on; Z2MO; ?Z2M; Z2MUT*; RW; yes +2; mute; off; Z2MF; ?Z2M; Z2MUT*; RW; yes +2; input; set; **ZS; ?ZS; Z2F**; RW +0; title; ; ; ; GEH01020; R +0; station; ; ; ; GEH04022; R +0; genre; ; ; ; GEH05024; R +0; display; ; ?FL; ?FL; FL******************************; R +1; speakers; set; *SPK; ?SPK; SPK*; RW diff --git a/avm/__init__.py b/avm/__init__.py index 34de05b4e..f8212e5f3 100644 --- a/avm/__init__.py +++ b/avm/__init__.py @@ -70,8 +70,10 @@ def connect(self): self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.conn.connect((self._host, self._port)) +# self._listen_thread = threading.Thread(target=self._listen, +# name="MonitoringService_%s" % self._plugin_instance.get_instance_name()).start() self._listen_thread = threading.Thread(target=self._listen, - name="MonitoringService_%s" % self._plugin_instance.get_instance_name()).start() + name="MonitoringService_{}".format(self._plugin_instance.get_fullname())).start() except Exception as e: self.conn = None self.logger.error("MonitoringService: Cannot connect to " + self._host + " on port: " + str( @@ -438,7 +440,7 @@ class AVM(SmartPlugin): Main class of the Plugin. Does all plugin specific stuff and provides the update functions for the different TR-064 services on the FritzDevice """ ALLOW_MULTIINSTANCE = True - PLUGIN_VERSION = "1.2.3" + PLUGIN_VERSION = "1.4.3" _header = {'SOAPACTION': '', 'CONTENT-TYPE': 'text/xml; charset="utf-8"'} _envelope = """ @@ -519,7 +521,8 @@ def run(self): """ Run method for the plugin """ - self._sh.scheduler.add(__name__, self._update_loop, prio=5, cycle=self._cycle, offset=2) +# self._sh.scheduler.add(__name__, self._update_loop, prio=5, cycle=self._cycle, offset=2) + self.scheduler_add('update', self._update_loop, prio=5, cycle=self._cycle, offset=2) self.alive = True def stop(self): diff --git a/avm/plugin.yaml b/avm/plugin.yaml new file mode 100755 index 000000000..4569eebae --- /dev/null +++ b/avm/plugin.yaml @@ -0,0 +1,25 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: interface # plugin type (gateway, interface, protocol, system, web) + description: + de: 'Ansteuerung von AVM FRITZ!Boxen, WLAN-Repeatern, DECT Steckdosen, etc.' + en: '' + maintainer: psilo909 + tester: Sandman60, cmalo +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin # url of documentation (wiki) page + support: https://knx-user-forum.de/forum/supportforen/smarthome-py/934835-avm-plugin + + version: 1.4.3 # Plugin version + sh_minversion: 1.3c # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: True # plugin supports multi instance + classname: AVM # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/backend/BackendItems.py b/backend/BackendItems.py new file mode 100755 index 000000000..75aef066d --- /dev/null +++ b/backend/BackendItems.py @@ -0,0 +1,368 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy +import platform +import collections +import datetime +import pwd +import html +import subprocess +import socket +import sys +import threading +import os +import lib.config +from lib.logic import Logics +import lib.logic # zum Test (für generate bytecode -> durch neues API ersetzen) +from lib.model.smartplugin import SmartPlugin +from .utils import * + +import lib.item_conversion + +class BackendItems: + + + # ----------------------------------------------------------------------------------- + # ITEMS + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def items_html(self): + """ + display a list of items + """ + return self.render_template('items.html', item_count=self._sh.item_count, + items=sorted(self._sh.return_items(), key=lambda k: str.lower(k['_path']), reverse=False) ) + + + @cherrypy.expose + def items_json(self, mode="tree"): + """ + returns a list of items as json structure + + :param mode: tree (default) or list structure + """ + items_sorted = sorted(self._sh.return_items(), key=lambda k: str.lower(k['_path']), reverse=False) + + if mode == 'tree': + parent_items_sorted = [] + for item in items_sorted: + if "." not in item._path: + parent_items_sorted.append(item) + + item_data = self._build_item_tree(parent_items_sorted) + return json.dumps(item_data) + else: + item_list = [] + for item in items_sorted: + item_list.append(item._path) + return json.dumps(item_list) + + + @cherrypy.expose + def cache_check_json_html(self): + """ + returns a list of items as json structure + """ + cache_path = "%s/var/cache/" % self._sh_dir + from os import listdir + from os.path import isfile, join + onlyfiles = [f for f in listdir(cache_path) if isfile(join(cache_path, f))] + unused_cache_files = [] + for file in onlyfiles: + if not file.find(".") == 0: # filter .gitignore etc. + item = self._sh.return_item(file) + no_cache_file = False; + if item is None: + no_cache_file = True + elif not item._cache: + no_cache_file = True + + if no_cache_file: + file_data = {} + file_data['last_modified'] = datetime.datetime.fromtimestamp( + int(os.path.getmtime(cache_path + file)) + ).strftime('%Y-%m-%d %H:%M:%S') + file_data['created'] = datetime.datetime.fromtimestamp( + int(os.path.getctime(cache_path + file)) + ).strftime('%Y-%m-%d %H:%M:%S') + file_data['filename'] = file + file_data['filename'] = file + unused_cache_files.append(file_data) + + return json.dumps(unused_cache_files) + + @cherrypy.expose + def cache_file_delete_html(self, filename=''): + """ + deletes a file from cache + """ + if len(filename) > 0: + file_path = "%s/var/cache/%s" % (self._sh_dir, filename) + os.remove(file_path); + + return + + @cherrypy.expose + def item_change_value_html(self, item_path, value): + """ + Is called by items.html when an item value has been changed + """ + item_data = [] + item = self._sh.return_item(item_path) + if self.updates_allowed: + if 'num' in item.type(): + if "." in value or "," in value: + value = float(value) + else: + value = int(value) + item(value, caller='Backend') + + return + + def disp_str(self, val): + s = str(val) + if s == 'False': + s = '-' + elif s == 'None': + s = '-' + return s + + def age_to_string(self, days, hours, minutes, seconds): + s = '' + if days > 0: + s += str(int(days)) + ' ' + if days == 1: + s += translate('Tag') + else: + s += translate('Tage') + s += ', ' + if (hours > 0) or (s != ''): + s += str(int(hours)) + ' ' + if hours == 1: + s += translate('Stunde') + else: + s += translate('Stunden') + s += ', ' + if (minutes > 0) or (s != ''): + s += str(int(minutes)) + ' ' + if minutes == 1: + s += translate('Minute') + else: + s += translate('Minuten') + s += ', ' + if days > 0: + s += str(int(seconds)) + else: + s += str("%.2f" % seconds) + s += ' ' + translate('Sekunden') + return s + + def disp_age(self, age): + days = 0 + hours = 0 + minutes = 0 + seconds = age + if seconds >= 60: + minutes = int(seconds / 60) + seconds = seconds - 60 * minutes + if minutes > 59: + hours = int(minutes / 60) + minutes = minutes - 60 * hours + if hours > 23: + days = int(hours / 24) + hours = hours - 24 * days + return self.age_to_string(days, hours, minutes, seconds) + + + def list_to_displaystring(self, l): + """ + """ + if type(l) is str: + return l + + edit_string = '' + for entry in l: + if edit_string != '': + edit_string += ' | ' + edit_string += str(entry) + if edit_string == '': + edit_string = '-' +# self.logger.info("list_to_displaystring: >{}< --> >{}<".format(l, edit_string)) + return edit_string + + + def build_on_list(self, on_dest_list, on_eval_list): + """ + build on_xxx data + """ + on_list = [] + if on_dest_list is not None: + if isinstance(on_dest_list, list): + for on_dest, on_eval in zip(on_dest_list, on_eval_list): + if on_dest != '': + on_list.append( on_dest + ' = ' + on_eval ) + else: + on_list.append( on_eval ) + else: + if on_dest_list != '': + on_list.append( on_dest_list + ' = ' + on_eval_list ) + else: + on_list.append( on_eval_list ) + return on_list + + + @cherrypy.expose + def item_detail_json_html(self, item_path): + """ + returns a list of items as json structure + """ + item_data = [] + item = self._sh.return_item(item_path) + if item is not None: + if item.type() is None or item.type() is '': + prev_value = '' + value = '' + else: + prev_value = item.prev_value() + value = item._value + + if isinstance(prev_value, datetime.datetime): + prev_value = str(prev_value) + + if 'str' in item.type(): + value = html.escape(value) + prev_value = html.escape(prev_value) + + cycle = '' + crontab = '' + for entry in self._sh.scheduler._scheduler: + if entry == item._path: + if self._sh.scheduler._scheduler[entry]['cycle']: + cycle = self._sh.scheduler._scheduler[entry]['cycle'] + if self._sh.scheduler._scheduler[entry]['cron']: + crontab = html.escape(str(self._sh.scheduler._scheduler[entry]['cron'])) + break + if cycle == '': + cycle = '-' + if crontab == '': + crontab = '-' + + changed_by = item.changed_by() + if changed_by[-5:] == ':None': + changed_by = changed_by[:-5] + + if item.prev_age() < 0: + prev_age = '' + else: + prev_age = self.disp_age(item.prev_update_age()) + if item.prev_update_age() < 0: + prev_update_age = '' + else: + prev_update_age = self.disp_age(item.prev_update_age()) + + if str(item._cache) == 'False': + cache = 'off' + else: + cache = 'on' + if str(item._enforce_updates) == 'False': + enforce_updates = 'off' + else: + enforce_updates = 'on' + + item_conf_sorted = collections.OrderedDict(sorted(item.conf.items(), key=lambda t: str.lower(t[0]))) + if item_conf_sorted.get('sv_widget', '') != '': + item_conf_sorted['sv_widget'] = html.escape(item_conf_sorted['sv_widget']) + + logics = [] + for trigger in item.get_logic_triggers(): + logics.append(html.escape(format(trigger))) + triggers = [] + for trigger in item.get_method_triggers(): + trig = format(trigger) + trig = trig[1:len(trig) - 27] + triggers.append(html.escape(format(trig.replace("<", "")))) + + try: + upd_age = item.update_age() + except: + # if used lib.items doesn't support update_age() function + upd_age = item.age() + + # build on_update and on_change data + on_update_list = self.build_on_list(item._on_update_dest_var, item._on_update) + on_change_list = self.build_on_list(item._on_change_dest_var, item._on_change) + + data_dict = {'path': item._path, + 'name': item._name, + 'type': item.type(), + 'value': value, + 'age': self.disp_age(item.age()), + 'update_age': self.disp_age(item.update_age()), + 'last_update': str(item.last_update()), + 'last_change': str(item.last_change()), + 'changed_by': changed_by, + 'previous_value': prev_value, + 'previous_age': prev_age, + 'previous_update_age': prev_update_age, + 'previous_update': str(item.prev_update()), + 'previous_change': str(item.prev_change()), + 'enforce_updates': enforce_updates, + 'cache': cache, + 'eval': html.escape(self.disp_str(item._eval)), + 'eval_trigger': self.disp_str(item._eval_trigger), + 'on_update': html.escape(self.list_to_displaystring(on_update_list)), + 'on_change': html.escape(self.list_to_displaystring(on_change_list)), + 'cycle': str(cycle), + 'crontab': str(crontab), + 'autotimer': self.disp_str(item._autotimer), + 'threshold': self.disp_str(item._threshold), + 'config': json.dumps(item_conf_sorted), + 'logics': json.dumps(logics), + 'triggers': json.dumps(triggers), + } + + # cast raw data to a string + if item.type() in ['foo', 'list', 'dict']: + data_dict['value'] = str(item._value) + data_dict['previous_value'] = str(prev_value) + + item_data.append(data_dict) + return json.dumps(item_data) + else: + self.logger.error("Requested item %s is None, check if item really exists." % item_path) + return + + def _build_item_tree(self, parent_items_sorted): + item_data = [] + + for item in parent_items_sorted: + nodes = self._build_item_tree(item.return_children()) + tags = [] + tags.append(len(nodes)) + item_data.append({'path': item._path, 'name': item._name, 'tags': tags, 'nodes': nodes}) + + return item_data + diff --git a/backend/BackendLogging.py b/backend/BackendLogging.py new file mode 100755 index 000000000..c6cb819e6 --- /dev/null +++ b/backend/BackendLogging.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +import logging +import os +import html + +class BackendLogging: + + # ----------------------------------------------------------------------------------- + # LOGGING + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def logging_html(self): + """ + display a list of all loggers + """ + loggerDict = {} + # Filter to get only active loggers + for l in logging.Logger.manager.loggerDict: + if (logging.getLogger(l).level > 0) or (logging.getLogger(l).handlers != []): + loggerDict[l] = logging.Logger.manager.loggerDict[l] + + + # get information about active loggers + loggerList_sorted = sorted(loggerDict) + loggerList_sorted.insert(0, "root") # Insert information about root logger at the beginning of the list + loggers = [] + for ln in loggerList_sorted: + if ln == 'root': + logger = logging.root + else: + logger = logging.getLogger(ln) + l = dict() + l['name'] = logger.name + l['disabled'] = logger.disabled + + # get information about loglevels + if logger.level == 0: + l['level'] = '' + elif logger.level in logging._levelToName: + l['level'] = logging._levelToName[logger.level] + else: + l['level'] = logger.level + + l['filters'] = logger.filters + + # get information about handlers and filenames + l['handlers'] = list() + l['filenames'] = list() + for h in logger.handlers: + l['handlers'].append(h.__class__.__name__) + try: + fn = str(h.baseFilename) + except: + fn = '' + l['filenames'].append(fn) + + loggers.append(l) + + return self.render_template('logging.html', loggers=loggers) + + + @cherrypy.expose + def log_view_html(self, text_filter='', log_level_filter='ALL', page=1, logfile='smarthome.log'): + """ + returns the smarthomeNG logfile as view + """ + log = '/var/log/' + os.path.basename(logfile) + log_name = self._sh_dir + log + fobj = open(log_name) + log_lines = [] + start = (int(page) - 1) * 1000 + end = start + 1000 + counter = 0 + log_level_hit = False + total_counter = 0 + for line in fobj: + line_text = html.escape(line) + if log_level_filter != "ALL" and not self.validate_date(line_text[0:10]) and log_level_hit: + if start <= counter < end: + log_lines.append(line_text) + counter += 1 + else: + log_level_hit = False + if (log_level_filter == "ALL" or line_text.find(log_level_filter) in [19, 20, 21, 22, + 23]) and text_filter in line_text: + if start <= counter < end: + log_lines.append(line_text) + log_level_hit = True + counter += 1 + fobj.close() + num_pages = -(-counter // 1000) + if num_pages == 0: + num_pages = 1 + return self.render_template('log_view.html', + current_page=int(page), pages=num_pages, log_level_filter=log_level_filter, + logfile=os.path.basename(log_name), log_lines=log_lines, text_filter=text_filter) + + + @cherrypy.expose + def log_dump_html(self, logfile='smarthome.log'): + """ + returns the smarthomeNG logfile as download + """ + log = '/var/log/' + os.path.basename(logfile) + log_name = self._sh_dir + log + mime = 'application/octet-stream' + return cherrypy.lib.static.serve_file(log_name, mime, log_name) + + diff --git a/backend/BackendLogics.py b/backend/BackendLogics.py new file mode 100755 index 000000000..52d26b1de --- /dev/null +++ b/backend/BackendLogics.py @@ -0,0 +1,455 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy +import platform +#import collections +import datetime +import pwd +import html +import subprocess +import socket +import sys +import threading +import os + +import lib.config +from lib.logic import Logics +import lib.logic # zum Test (für generate bytecode -> durch neues API ersetzen) +from lib.utils import Utils + +from lib.model.smartplugin import SmartPlugin + +from .utils import * + +import lib.item_conversion + +class BackendLogics: + + logics = None + _logicname_prefix = 'logics.' # prefix for scheduler names + + def __init__(self): + + self.logics = Logics.get_instance() + self.logger.warning("BackendLogics __init__ self.logics = {}".format(str(self.logics))) + + + def logics_initialize(self): + """ + Initialize access to logics API and test if Blockly plugin is loaded + + This can't be done during __init__, since not all components are loaded/initialized + at that time. + """ + if self.logics is not None: + return + + self.logics = Logics.get_instance() + self.yaml_updates=(self.logics.return_config_type() == '.yaml') + + # find out if blockly plugin is loaded + if self.blockly_plugin_loaded == None: + self.blockly_plugin_loaded = False + for x in self._sh._plugins: + try: + if x.get_shortname() == 'blockly': + self.blockly_plugin_loaded = True + except: + pass + return + + + # ----------------------------------------------------------------------------------- + # LOGICS + # ----------------------------------------------------------------------------------- + + def fill_logicdict(self, logicname): + """ + Returns a dict filled with information of the specified loaded logic + """ + mylogic = dict() + loaded_logic = self.logics.return_logic(logicname) + if loaded_logic is not None: + mylogic['name'] = loaded_logic.name + mylogic['enabled'] = loaded_logic.enabled + mylogic['logictype'] = self.logics.return_logictype(loaded_logic.name) + mylogic['userlogic'] = self.logics.is_userlogic(loaded_logic.name) + mylogic['filename'] = loaded_logic.filename + mylogic['pathname'] = loaded_logic.pathname + mylogic['cycle'] = '' + if hasattr(self.logics.return_logic(logicname), 'cycle'): + mylogic['cycle'] = loaded_logic.cycle + if mylogic['cycle'] == None: + mylogic['cycle'] = '' + + mylogic['crontab'] = '' + if hasattr(loaded_logic, 'crontab'): + if loaded_logic.crontab is not None: +# mylogic['crontab'] = Utils.strip_quotes_fromlist(str(loaded_logic.crontab)) + mylogic['crontab'] = Utils.strip_quotes_fromlist(self.list_to_editstring(loaded_logic.crontab)) + + mylogic['crontab'] = Utils.strip_square_brackets(mylogic['crontab']) + + mylogic['watch_item'] = '' + mylogic['watch_item_list'] = [] + if hasattr(loaded_logic, 'watch_item'): + # Attention: watch_items are always stored as a list in logic object + mylogic['watch_item'] = Utils.strip_quotes_fromlist(str(loaded_logic.watch_item)) + mylogic['watch_item_list'] = loaded_logic.watch_item + + mylogic['next_exec'] = '' + if self._sh.scheduler.return_next(self._logicname_prefix+loaded_logic.name): + mylogic['next_exec'] = self._sh.scheduler.return_next(self._logicname_prefix+loaded_logic.name).strftime('%Y-%m-%d %H:%M:%S%z') + + mylogic['last_run'] = '' + if loaded_logic.last_run(): + mylogic['last_run'] = loaded_logic.last_run().strftime('%Y-%m-%d %H:%M:%S%z') + + mylogic['visu_acl'] = '' + if hasattr(loaded_logic, 'visu_acl'): + if loaded_logic.visu_acl != 'None': + mylogic['visu_acl'] = Utils.strip_quotes_fromlist(str(loaded_logic.visu_acl)) + + return mylogic + + + @cherrypy.expose + def logics_html(self, logic=None, trigger=None, reload=None, enable=None, disable=None, unload=None, add=None, delete=None): + """ + returns information to display a list of all known logics + """ + self.logics_initialize() + + # process actions triggerd by buttons on the web page + logicname=logic + if trigger is not None: + self.logics.trigger_logic(logicname) + elif reload is not None: + self.logics.load_logic(logicname) # implies unload_logic() + self.logics.trigger_logic(logicname) + elif enable is not None: + self.logics.enable_logic(logicname) + elif disable is not None: + self.logics.disable_logic(logicname) + elif unload is not None: + self.logics.unload_logic(logicname) + + elif add is not None: + self.logics.load_logic(logicname) + + elif delete is not None: + self.logics.delete_logic(logicname) + + # create a list of dicts, where each dict contains the information for one logic + logics_list = [] + import time + for ln in self.logics.return_loaded_logics(): + logic = self.fill_logicdict(ln) + if logic['logictype'] == 'Blockly': + logic['pathname'] = os.path.splitext(logic['pathname'])[0] + '.blockly' + logics_list.append(logic) + self.logger.debug("Backend: logics_html: - logic = {}, enabled = {}, , logictype = {}, filename = {}, userlogic = {}, watch_item = {}".format(str(logic['name']), str(logic['enabled']), str(logic['logictype']), str(logic['filename']), str(logic['userlogic']), str(logic['watch_item'])) ) + + newlogics = sorted(self.logic_findnew(logics_list), key=lambda k: k['name']) + logics_sorted = sorted(logics_list, key=lambda k: k['name']) + return self.render_template('logics.html', updates=self.updates_allowed, yaml_updates=self.yaml_updates, logics=logics_sorted, newlogics=newlogics, + blockly_loaded=self.blockly_plugin_loaded) + + + def logic_findnew(self, loadedlogics): + """ + Find new logics (logics defined in /etc/logic.yaml but not loaded) + """ + _config = {} + _config.update(self._sh._logics._read_logics(self._sh._logic_conf_basename, self._sh._logic_dir)) + + self.logger.info("logic_findnew: _config = '{}'".format(_config)) + newlogics = [] + for configlogic in _config: + found = False + for l in loadedlogics: + if configlogic == str(l['name']): + found = True + if not found: + self.logger.info("Backend (logic_findnew): name = {}".format(configlogic)) + if _config[configlogic] != 'None': + mylogic = {} + mylogic['name'] = configlogic + mylogic['userlogic'] = True + mylogic['logictype'] = self.logics.return_logictype(mylogic['name']) + if mylogic['logictype'] == 'Python': + mylogic['filename'] = _config[configlogic]['filename'] + mylogic['pathname'] = self.logics.get_logics_dir() + mylogic['filename'] + elif mylogic['logictype'] == 'Blockly': + mylogic['filename'] = _config[configlogic]['filename'] + mylogic['pathname'] = os.path.splitext(self.logics.get_logics_dir() + _config[configlogic]['filename'])[0] + '.blockly' +# mylogic['pathname'] = os.path.splitext(_config[configlogic]['filename'])[0] + '.blockly' + else: + mylogic['filename'] = '' + + newlogics.append(mylogic) +# self.logger.info("Backend (logic_findnew): newlogics = '{}'".format(newlogics)) + return newlogics + + + # ----------------------------------------------------------------------------------- + # LOGICS - VIEW + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def logics_view_html(self, file_path, logicname, + trigger=None, enable=None, disable=None, save=None, savereload=None, savereloadtrigger=None, + logics_code=None, cycle=None, crontab=None, watch=None, visu_acl=None): + """ + returns information to display a logic in an editor window + """ + self.logics_initialize() + +# self.logger.info("logics_view_html: logicname = {}, trigger = {}, enable = {}, disable = {}, save = {}, savereload = {}, savereloadtrigger = {}".format( logicname, trigger, enable, disable, save, savereload, savereloadtrigger )) +# self.logger.info("logics_view_html: logicname = {}, cycle = {}, crontab = {}, watch = {}".format( logicname, cycle, crontab, watch )) + + # process actions triggerd by buttons on the web page + if trigger is not None: + self.logics.trigger_logic(logicname) + elif enable is not None: + self.logics.enable_logic(logicname) + elif disable is not None: + self.logics.disable_logic(logicname) + elif save is not None: + self.logic_save_code(logicname, logics_code) + self.logic_save_config(logicname, cycle, crontab, watch, visu_acl) + elif savereload is not None: + self.logic_save_code(logicname, logics_code) + self.logic_save_config(logicname, cycle, crontab, watch, visu_acl) + self.logics.load_logic(logicname) + elif savereloadtrigger is not None: + self.logic_save_code(logicname, logics_code) + self.logic_save_config(logicname, cycle, crontab, watch, visu_acl) + self.logics.load_logic(logicname) + self.logics.trigger_logic(logicname) + + # assemble data for displaying/editing of a logic + mylogic = self.fill_logicdict(logicname) + + config_list = self.logics.read_config_section(logicname) + for config in config_list: + if config[0] == 'cycle': + mylogic['cycle'] = config[1] + if config[0] == 'crontab': +# mylogic['crontab'] = config[1] + self.logger.info("logics_view_html: crontab = >{}<".format(config[1])) + edit_string = self.list_to_editstring(config[1]) + mylogic['crontab'] = Utils.strip_quotes_fromlist(edit_string) + if config[0] == 'watch_item': + # Attention: watch_items are always stored as a list in logic object + edit_string = self.list_to_editstring(config[1]) + mylogic['watch'] = Utils.strip_quotes_fromlist(edit_string) + mylogic['watch_item'] = Utils.strip_quotes_fromlist(edit_string) + mylogic['watch_item_list'] = config[1] + if config[0] == 'visu_acl': + mylogic['visu_acl'] = config[1] + + if os.path.splitext(file_path)[1] == '.blockly': + mode = 'xml' + updates = False + else: + mode = 'python' + updates=self.updates_allowed + if not 'userlogic' in mylogic: + mylogic['userlogic'] = True + if mylogic['userlogic'] == False: + updates = False + file_lines = [] + if mylogic != {}: + file_lines = self.logic_load_code(logicname, os.path.splitext(file_path)[1]) + + return self.render_template('logics_view.html', logicname=logicname, thislogic=mylogic, logic_lines=file_lines, file_path=file_path, + updates=updates, yaml_updates=self.yaml_updates, mode=mode) + + + # ----------------------------------------------------------------------------------- + # LOGICS - NEW + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def logics_new_html(self, create=None, filename='', logicname=''): + """ + returns information to display a logic in an editor window + """ + self.logics_initialize() + + self.logger.info("logics_new_html: create = {}, filename = '{}', logicname = '{}'".format(create, filename, logicname)) + + # process actions triggerd by buttons on the web page + message = '' + if create is not None: + if filename != '': + if logicname == '': + logicname = filename + filename = filename.lower() + '.py' + + if logicname in self.logics.return_defined_logics(): + message = translate("Der Logikname wird bereits verwendet") + else: + logics_code = '#!/usr/bin/env python3\n' + '# ' + filename + '\n\n' + if self.logic_create_codefile(filename, logics_code): + self.logic_create_config(logicname, filename) + self.logics.load_logic(logicname) +# self.logics.disable_logic(logicname) + redir = ''.format(self.logics.get_logics_dir()+filename, logicname) + return redir + + else: + message = translate("Logik-Datei")+" '"+filename+"' "+translate("existiert bereits") + else: + message = translate('Bitte Dateinamen angeben') + + filename = os.path.splitext(filename)[0] + return self.render_template('logics_new.html', message=message, filename=filename, logicname=logicname, + updates=self.updates_allowed, yaml_updates=self.yaml_updates) + + + # ----------------------------------------------------------------------------------- + + + def list_to_editstring(self, l): + """ + """ + if type(l) is str: + self.logger.info("list_to_editstring: >{}< --> >{}<".format(l, l)) + return l + + edit_string = '' + for entry in l: + if edit_string != '': + edit_string += ' | ' + edit_string += str(entry) + self.logger.info("list_to_editstring: >{}< --> >{}<".format(l, edit_string)) + return edit_string + + + def editstring_to_list(self, param_string): + + if param_string is None: + return '' + else: + l1 = param_string.split('|') + if len(l1) > 1: + # string contains a list + l2 = [] + for s in l1: + l2.append(Utils.strip_quotes(s.strip())) + param_string = l2 + else: + # string contains a single entry + param_string = Utils.strip_quotes(param_string) + return param_string + + + def logic_create_config(self, logicname, filename): + """ + Create a new configuration for a logic + """ + config_list = [] + config_list.append(['filename', filename, '']) + config_list.append(['enabled', False, '']) + self.logics.update_config_section(True, logicname, config_list) +# self.logics.set_config_section_key(logicname, 'visu_acl', False) + return + + + def logic_save_config(self, logicname, cycle, crontab, watch, visu_acl): + """ + Save configuration data of a logic + + Convert input strings to lists (if necessary) and write configuration to /etc/logic.yaml + """ + config_list = [] + thislogic = self.logics.return_logic(logicname) + config_list.append(['filename', thislogic.filename, '']) + if Utils.is_int(cycle): + cycle = int(cycle) + if cycle > 0: + config_list.append(['cycle', cycle, '']) + + crontab = self.editstring_to_list(crontab) + if crontab != '': + config_list.append(['crontab', str(crontab), '']) + + watch = self.editstring_to_list(watch) + if watch != '': + config_list.append(['watch_item', str(watch), '']) + + self.logics.update_config_section(True, logicname, config_list) + if visu_acl == '': + visu_acl = None +# visu_acl = 'false' + self.logics.set_config_section_key(logicname, 'visu_acl', visu_acl) + return + + + def logic_load_code(self, logicname, code_type='.python'): + + file_lines = [] + if logicname in self.logics.return_loaded_logics(): + mylogic = self.logics.return_logic(logicname) + + if code_type == '.blockly': + pathname = os.path.splitext(mylogic.pathname)[0] + '.blockly' + else: + pathname = mylogic.pathname + + fobj = open(pathname) + for line in fobj: + file_lines.append(html.escape(line)) + fobj.close() + return file_lines + + + def logic_save_code(self, logicname, logics_code): + + self.logger.info("logic_save_code: type(logics_code) = {}".format(str(type(logics_code)))) + if self.updates_allowed: + if logicname in self.logics.return_loaded_logics(): + mylogic = self.logics.return_logic(logicname) + + f = open(mylogic.pathname, 'w') + f.write(logics_code) + f.close() + return + + + def logic_create_codefile(self, filename, logics_code): + + pathname = self.logics.get_logics_dir() + filename + if os.path.isfile(pathname): + return False + + f = open(pathname, 'w') + f.write(logics_code) + f.close() + + return True + diff --git a/backend/BackendPlugins.py b/backend/BackendPlugins.py new file mode 100755 index 000000000..3befaaa5b --- /dev/null +++ b/backend/BackendPlugins.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +import lib.config +from lib.model.smartplugin import SmartPlugin + +from .utils import * + +#import lib.item_conversion + +class BackendPlugins: + + + # ----------------------------------------------------------------------------------- + # PLUGINS + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def plugins_html(self): + """ + display a list of all known plugins + """ + conf_plugins = {} + _conf = lib.config.parse(self._sh._plugin_conf) + for plugin in _conf: + conf_plugins[plugin] = {} + conf_plugins[plugin] = _conf[plugin] + + plugins = [] + for x in self._sh._plugins: + plugin = dict() + if bool(x._parameters): + plugin['attributes'] = x._parameters + else: + plugin['attributes'] = conf_plugins[x._config_section] + plugin['metadata'] = x._metadata + if isinstance(x, SmartPlugin): + plugin['smartplugin'] = True + plugin['instancename'] = x.get_instance_name() + plugin['multiinstance'] = x.is_multi_instance_capable() + plugin['version'] = x.get_version() + plugin['shortname'] = x.get_shortname() + plugin['classpath'] = x._classpath + plugin['classname'] = x.get_classname() + else: + plugin['smartplugin'] = False + plugin['shortname'] = x._shortname + plugin['classpath'] = x._classpath + plugin['classname'] = x._classname + plugins.append(plugin) + plugins_sorted = sorted(plugins, key=lambda k: k['classpath']) + + return self.render_template('plugins.html', plugins=plugins_sorted, lang=get_translation_lang(), mod_http=self._bs.mod_http) + + diff --git a/backend/BackendScenes.py b/backend/BackendScenes.py new file mode 100755 index 000000000..1895f51e4 --- /dev/null +++ b/backend/BackendScenes.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +class BackendScenes: + + + # ----------------------------------------------------------------------------------- + # SCENES + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def scenes_html(self): + + from lib.scene import Scenes + get_param_func = getattr(Scenes, "get_instance", None) + if callable(get_param_func): + supported = True + self.scenes = Scenes.get_instance() + scene_list = self.scenes.get_loaded_scenes() + + disp_scene_list = [] + for scene in scene_list: + scene_dict = {} + scene_dict['path'] = scene + scene_dict['name'] = str(self._sh.return_item(scene)) + + action_list = self.scenes.get_scene_actions(scene) + scene_dict['value_list'] = action_list + scene_dict[scene] = action_list + + disp_action_list = [] + for value in action_list: + action_dict = {} + action_dict['action'] = value + action_dict['action_name'] = self.scenes.get_scene_action_name(scene, value) + action_list = self.scenes.return_scene_value_actions(scene, value) + for action in action_list: + if not isinstance(action[0], str): + action[0] = action[0].id() + action_dict['action_list'] = sorted(action_list) + + disp_action_list.append(action_dict) + scene_dict['values'] = disp_action_list + self.logger.info("scenes_html: disp_action_list for scene {} = {}".format(scene, disp_action_list)) + + disp_scene_list.append(scene_dict) + else: + supported = False + return self.render_template('scenes.html', supported=supported, scene_list=disp_scene_list) + + + diff --git a/backend/BackendSchedulers.py b/backend/BackendSchedulers.py new file mode 100755 index 000000000..ee2b0e9d7 --- /dev/null +++ b/backend/BackendSchedulers.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +class BackendSchedulers: + + + # ----------------------------------------------------------------------------------- + # SCHEDULERS + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def schedules_html(self): + """ + display a list of all known schedules + """ + + schedule_list = [] + for entry in self._sh.scheduler._scheduler: + schedule = dict() + s = self._sh.scheduler._scheduler[entry] + if s['next'] != None and s['cycle'] != '' and s['cron'] != '': + schedule['fullname'] = entry + schedule['name'] = entry + schedule['group'] = '' + schedule['next'] = s['next'].strftime('%Y-%m-%d %H:%M:%S%z') + schedule['cycle'] = s['cycle'] + schedule['cron'] = s['cron'] + + if schedule['cycle'] == None: + schedule['cycle'] = '' + if schedule['cron'] == None: + schedule['cron'] = '' + + nl = entry.split('.') + if nl[0].lower() in ['items','logics','plugins']: + schedule['group'] = nl[0].lower() + del nl[0] + schedule['name'] = '.'.join(nl) + + schedule_list.append(schedule) + + schedule_list_sorted = sorted(schedule_list, key=lambda k: k['fullname'].lower()) + return self.render_template('schedules.html', schedule_list=schedule_list_sorted) + + + diff --git a/backend/BackendServices.py b/backend/BackendServices.py new file mode 100755 index 000000000..390fda316 --- /dev/null +++ b/backend/BackendServices.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy +import platform +import collections +import datetime +import pwd +import html +import subprocess +import socket +import sys +import threading +import os +import lib.config +from lib.logic import Logics +import lib.logic # zum Test (für generate bytecode -> durch neues API ersetzen) +from lib.model.smartplugin import SmartPlugin +from .utils import * + +import lib.item_conversion + +class BackendServices: + + + # ----------------------------------------------------------------------------------- + # SERVICES + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def services_html(self): + """ + shows a page with info about some services needed by smarthome + """ + knxd_service = self.get_process_info("systemctl status knxd.service") + smarthome_service = self.get_process_info("systemctl status smarthome.service") + knxd_socket = self.get_process_info("systemctl status knxd.socket") + + knxdeamon = '' + if self.get_process_info("ps cax|grep eibd") != '': + knxdeamon = 'eibd' + if self.get_process_info("ps cax|grep knxd") != '': + if knxdeamon != '': + knxdeamon += ' and ' + knxdeamon += 'knxd' + + sql_plugin = False + database_plugin = [] + + for x in self._sh._plugins: + if x.__class__.__name__ == "SQL": + sql_plugin = True + break + elif x.__class__.__name__ == "Database": + database_plugin.append(x.get_instance_name()) + + return self.render_template('services.html', + knxd_service=knxd_service, knxd_socket=knxd_socket, knxdeamon=knxdeamon, + smarthome_service=smarthome_service, lang=get_translation_lang(), + sql_plugin=sql_plugin, database_plugin=database_plugin) + + + @cherrypy.expose + def reload_translation_html(self, lang=''): + if lang != '': + load_translation(lang) + else: + load_translation(get_translation_lang()) + return self.index() + + @cherrypy.expose + def reboot(self): + passwd = request.form['password'] + rbt1 = subprocess.Popen(["echo", passwd], stdout=subprocess.PIPE) + rbt2 = subprocess.Popen(["sudo", "-S", "reboot"], stdin=rbt1. + stdout, stdout=subprocess.PIPE) + print(rbt2.communicate()[0]) + return redirect('/services.html') + + def validate_date(self, date_text): + try: + datetime.datetime.strptime(date_text, '%Y-%m-%d') + return True + except ValueError: + return False + + @cherrypy.expose + def db_dump_html(self, plugin): + """ + returns the smarthomeNG sqlite database as download + """ + if (plugin == "sqlite_old"): + self._sh.sql.dump('%s/var/db/smarthomedb.dump' % self._sh_dir) + mime = 'application/octet-stream' + return cherrypy.lib.static.serve_file("%s/var/db/smarthomedb.dump" % self._sh_dir, mime, + "%s/var/db/" % self._sh_dir) + elif plugin != "": + for x in self._sh._plugins: + if isinstance(x, SmartPlugin): + if x.get_instance_name() == plugin: + x.dump('%s/var/db/smarthomedb_%s.dump' % (self._sh_dir, plugin)) + mime = 'application/octet-stream' + return cherrypy.lib.static.serve_file("%s/var/db/smarthomedb_%s.dump" % (self._sh_dir, plugin), + mime, "%s/var/db/" % self._sh_dir) + return + + # ----------------------------------------------------------------------------------- + + def strip_empty_lines(self, txt): + """ + Remove \r from text and remove exessive empty lines from end + """ + txt = txt.replace('\r','').rstrip() + while txt.endswith('\n'): + txt = txt[:-1].rstrip() + txt += '\n\n' +# self.logger.warning("strip_empty_lines: txt = {}".format(txt)) + return txt + + + def append_empty_lines(self, txt, lines): + """ + Append empty lines until text is 'lines' long + """ + if len(txt.split('\n')) < lines: + txt += '\n' * (lines - len(txt.split('\n')) +1) + return txt + + + @cherrypy.expose + def conf_yaml_converter_html(self, convert=None, conf_code=None, yaml_code=None): + if convert is not None: + conf_code = self.strip_empty_lines(conf_code) + yaml_code = '' + ydata = lib.item_conversion.parse_for_convert(conf_code=conf_code) + if ydata != None: + yaml_code = lib.item_conversion.convert_yaml(ydata) + + conf_code = self.append_empty_lines(conf_code, 15) + yaml_code = self.append_empty_lines(yaml_code, 15) + else: + conf_code = self.append_empty_lines('', 15) + yaml_code = self.append_empty_lines('', 15) + return self.render_template('conf_yaml_converter.html', conf_code=conf_code, yaml_code=yaml_code) + + + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def yaml_syntax_checker_html(self, check=None, check2=None, yaml_code=None, check_result=None): + check_result = '' + output_format = 'yaml' + if check is not None: + yaml_code = self.strip_empty_lines(yaml_code) + + import lib.shyaml as shyaml + ydata, estr = shyaml.yaml_load_fromstring(yaml_code, True) + + if estr != '': + check_result = 'ERROR: \n\n'+ estr + if ydata != None: + check_result += lib.item_conversion.convert_yaml(ydata).replace('\n\n', '\n') + + yaml_code = self.append_empty_lines(yaml_code, 15) + check_result = self.append_empty_lines(check_result, 15) + elif check2 is not None: + yaml_code = self.strip_empty_lines(yaml_code) + + import lib.shyaml as shyaml + ydata, estr = shyaml.yaml_load_fromstring(yaml_code, False) + + if estr != '': + check_result = 'ERROR: \n\n'+ estr + if ydata != None: + import pprint + check_result += pprint.pformat(ydata) + + yaml_code = self.append_empty_lines(yaml_code, 15) + check_result = self.append_empty_lines(check_result, 15) + output_format = 'python' + else: + yaml_code = self.append_empty_lines('', 15) + check_result = self.append_empty_lines('', 15) + return self.render_template('yaml_syntax_checker.html', yaml_code=yaml_code, check_result=check_result, output_format=output_format) + + + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def eval_syntax_checker_html(self, check=None, eval_code=None, relative_to=''): + expanded_code = '' + if check is not None: + sh = self._sh + eval_code = eval_code.replace('\r', '').replace('\n', ' ').replace(' ', ' ').strip() + if relative_to == '': + expanded_code = eval_code + else: + rel_to_item = sh.return_item(relative_to) + if rel_to_item is not None: + expanded_code = rel_to_item.get_stringwithabsolutepathes(eval_code, 'sh.', '(') + else: + expanded_code = "Error: Item {} does not exist!".format(relative_to) + try: + value = eval(expanded_code) + except Exception as e: + check_result = "Problem evaluating {}:   {}".format(expanded_code, e) + else: + check_result = value + eval_code = self.append_empty_lines(eval_code, 5) + else: + eval_code = self.append_empty_lines('', 5) + check_result = '' + return self.render_template('eval_syntax_checker.html', eval_code=eval_code, expanded_code=expanded_code, relative_to=relative_to, check_result=check_result) + + + @cherrypy.expose + def create_hash_json_html(self, plaintext): + return json.dumps(create_hash(plaintext)) + diff --git a/backend/BackendSysteminfo.py b/backend/BackendSysteminfo.py new file mode 100755 index 000000000..89f16a449 --- /dev/null +++ b/backend/BackendSysteminfo.py @@ -0,0 +1,655 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy +import platform +#import collections +import datetime +import time +import pwd +#import html +#import subprocess +import socket +import sys +#import threading +import os +import psutil + +import bin.shngversion as shngversion +import lib.config +#from lib.logic import Logics +#from lib.model.smartplugin import SmartPlugin +from lib.utils import Utils +from .utils import * + +#import lib.item_conversion + +class BackendSysteminfo: + + # ----------------------------------------------------------------------------------- + # SYSTEMINFO + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def system_html(self): + now = datetime.datetime.now().strftime('%d.%m.%Y %H:%M') + system = platform.system() + vers = platform.version() + # node = platform.node() + node = socket.getfqdn() + arch = platform.machine() + user = pwd.getpwuid(os.geteuid()).pw_name # os.getlogin() + + ip = Utils.get_local_ipv4_address() + ipv6 = Utils.get_local_ipv6_address() + + space = os.statvfs(self._sh_dir) + freespace = space.f_frsize * space.f_bavail / 1024 / 1024 + + # return host uptime + uptime = time.mktime(datetime.datetime.now().timetuple()) - psutil.boot_time() + days = uptime // (24 * 3600) + uptime = uptime % (24 * 3600) + hours = uptime // 3600 + uptime %= 3600 + minutes = uptime // 60 + uptime %= 60 + seconds = uptime + uptime = self.age_to_string(days, hours, minutes, seconds) + + # return SmarthomeNG runtime + rt = str(self._sh.runtime()) + daytest = rt.split(' ') + if len(daytest) == 3: + days = int(daytest[0]) + hours, minutes, seconds = [float(val) for val in str(daytest[2]).split(':')] + else: + days = 0 + hours, minutes, seconds = [float(val) for val in str(daytest[0]).split(':')] + sh_uptime = self.age_to_string(days, hours, minutes, seconds) + + pyversion = "{0}.{1}.{2} {3}".format(sys.version_info[0], sys.version_info[1], sys.version_info[2], + sys.version_info[3]) + + #python_packages = self.getpackages() + #req_dict = self.get_requirements_info() + + return self.render_template('system.html', + now=now, system=system, sh_vers=shngversion.get_shng_version(), plg_vers=shngversion.get_plugins_version(), sh_dir=self._sh_dir, + vers=vers, node=node, arch=arch, user=user, freespace=freespace, + uptime=uptime, sh_uptime=sh_uptime, pyversion=pyversion, + ip=ip, ipv6=ipv6) + + + def get_process_info(self, command): + """ + returns output from executing a given command via the shell. + """ + self.find_visu_plugin() + ## get subprocess module + import subprocess + + ## call date command ## + p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) + + # Talk with date command i.e. read data from stdout and stderr. Store this info in tuple ## + # Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. + # Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child. + (result, err) = p.communicate() + + ## Wait for date to terminate. Get return returncode ## + p_status = p.wait() + return str(result, encoding='utf-8', errors='strict') + + + # ----------------------------------------------------------------------------------- + # SYSTEMINFO: PyPI Check + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def pypi_json(self): + """ + returns a list of python package information dicts as json structure: + + The json response contains the following information: + + name str Name of package + vers_installed str Installed version of that package + is_required bool is package required by SmartHomeNG? + is_required_for_testsuite bool is package required for the testsuite? + is_required_for_docbuild bool is package required for building documentation with Sphinx? + vers_req_source str requirements as defined inrequirements.txt + vers_req_min str required minimum version + vers_req_max str required maximum version +- vers_req_msg str + vers_ok bool installed version meets requirements + vers_recent bool installed version is the req_max or the newest on PyPI + + pypi_version str newest package version on PyPI + pypi_version_ok bool is newest package version on PyPI ok for install on SmartHomeNG? + pypi_version_not_available_msg str error message or empty + pypi_doc_url str url of the package's documentation on PyPI + + sort str string for sorting (is_required + name) + + + :return: information about packahge requirements including PyPI information + :rtype: json structure + """ + self.logger.info("pypi_json") + + # check if pypi service is reachable + if self.pypi_timeout <= 0: + pypi_available = False + pypi_unavailable_message = translate('PyPI Prüfung deaktiviert') + else: + pypi_available = True + try: + import socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(self.pypi_timeout) + sock.connect(('pypi.python.org', 443)) + sock.close() + except: + pypi_available = False + pypi_unavailable_message = translate('PyPI nicht erreichbar') + + import pip + import xmlrpc + installed_packages = pip.get_installed_distributions() + pypi = xmlrpc.client.ServerProxy('https://pypi.python.org/pypi') + + req_dict = self.get_requirements_info('base') + req_test_dict = self.get_requirements_info('test') + req_doc_dict = self.get_requirements_info('doc') + self.logger.info("pypi_json: req_doc_dict {}".format(req_doc_dict)) + + package_list = [] + + for dist in installed_packages: + package = dict() + package['name'] = dist.key + package['vers_installed'] = dist.version + package['is_required'] = False + package['is_required_for_testsuite'] = False + package['is_required_for_docbuild'] = False + + package['vers_req_min'] = '' + package['vers_req_max'] = '' + package['vers_req_msg'] = '' + package['vers_req_source'] = '' + + package['vers_ok'] = False + package['vers_recent'] = False + package['pypi_version'] = '' + package['pypi_version_ok'] = True + package['pypi_version_not_available_msg'] = '' + package['pypi_doc_url'] = '' + + if pypi_available: + try: + available = pypi.package_releases(dist.project_name) + self.logger.info("pypi_json: pypi package: project_name {}, availabe = {}".format(dist.project_name, available)) + try: + package['pypi_version'] = available[0] + except: + package['pypi_version_not_available_msg'] = '?' + except: + package['pypi_version'] = '--' + package['pypi_version_not_available_msg'] = [translate('Keine Antwort von PyPI')] + else: + package['pypi_version_not_available_msg'] = pypi_unavailable_message + package['pypi_doc_url'] = 'https://pypi.python.org/pypi/' + dist.project_name + + if package['name'].startswith('url'): + self.logger.info("pypi_json: urllib: package['name'] = >{}<, req_dict.get(package['name'] = >{}<".format(package['name'], req_dict.get(package['name']))) + + # test if package belongs to to SmartHomeNG requirements + if req_dict.get(package['name'], '') != '': + package['is_required'] = True + # tests for min, max versions + rmin, rmax, rtxt = self.check_requirement(package['name'], req_dict.get(package['name'], '')) + package['vers_req_source'] = req_dict.get(package['name'], '') + package['vers_req_min'] = rmin + package['vers_req_max'] = rmax + package['vers_req_msg'] = rtxt + + if req_doc_dict.get(package['name'], '') != '': + package['is_required_for_docbuild'] = True + # tests for min, max versions + rmin, rmax, rtxt = self.check_requirement(package['name'], req_doc_dict.get(package['name'], '')) + package['vers_req_source'] = req_doc_dict.get(package['name'], '') + package['vers_req_min'] = rmin + package['vers_req_max'] = rmax + package['vers_req_msg'] = rtxt + + if req_test_dict.get(package['name'], '') != '': + package['is_required_for_testsuite'] = True + # tests for min, max versions + rmin, rmax, rtxt = self.check_requirement(package['name'], req_test_dict.get(package['name'], '')) + package['vers_req_source'] = req_test_dict.get(package['name'], '') + package['vers_req_min'] = rmin + package['vers_req_max'] = rmax + package['vers_req_msg'] = rtxt + + if package['is_required']: + package['sort'] = '1' + elif package['is_required_for_testsuite']: + package['sort'] = '2' + elif package['is_required_for_docbuild']: + package['sort'] = '3' + else: + package['sort'] = '4' + self.logger.info("pypi_json: sort=4, package['name'] = >{}<".format(package['name'])) + + package['sort'] += package['name'] + + # check if installed verison is recent (compared to PyPI) + if package['is_required']: + self.logger.info("compare PyPI package {}:".format(package['name'])) + if self.compare_versions(package['vers_installed'], package['pypi_version'], '>='): + package['vers_recent'] = True + else: + self.logger.info("compare PyPI package {} (for non required):".format(package['name'])) + if package['pypi_version'] != '': + if self.compare_versions(package['vers_installed'], package['pypi_version'], '>='): + package['vers_recent'] = True + + # check if installed verison is ok + if package['is_required'] or package['is_required_for_testsuite'] or package['is_required_for_docbuild']: + self.logger.info("required package {}:".format(package['name'])) + package['vers_ok'] = True + if self.compare_versions(package['vers_req_min'], package['vers_installed'], '>'): + package['vers_ok'] = False + max = package['vers_req_max'] + if max == '': + max = '99999' + if self.compare_versions(max, package['vers_installed'], '<'): + package['vers_ok'] = False + package['vers_recent'] = False + if self.compare_versions(max, package['vers_installed'], '=='): + package['vers_recent'] = True + if package['pypi_version'] != '': + if self.compare_versions(package['pypi_version'], package['vers_installed'], '<') or self.compare_versions(package['pypi_version'], max, '>'): + package['pypi_version_ok'] = False + + package_list.append(package) + + +# sorted_package_list = sorted([(i['name'], i['version_installed'], i['version_available']) for i in package_list]) + sorted_package_list = sorted(package_list, key=lambda k: k['sort'], reverse=False) + self.logger.info("pypi_json: sorted_package_list = {}".format(sorted_package_list)) + self.logger.info("pypi_json: json.dumps(sorted_package_list) = {}".format(json.dumps(sorted_package_list))) + + return json.dumps(sorted_package_list) + + + def get_requirements_info(self, req_group='base'): + """ + """ + req_dict = {} + if req_group == 'base': +# req_dict_base = parse_requirements("%s/requirements/base.txt" % self._sh_dir) + req_dict_base = parse_requirements(os.path.join(self._sh_dir, 'requirements', 'base.txt')) + elif req_group == 'test': + req_dict_base = parse_requirements(os.path.join(self._sh_dir, 'tests', 'requirements.txt')) + self.logger.info("get_requirements_info: filepath = {}".format(os.path.join(self._sh_dir, 'tests', 'requirements.txt'))) + elif req_group == 'doc': + req_dict_base = parse_requirements(os.path.join(self._sh_dir, 'doc', 'requirements.txt')) + self.logger.info("get_requirements_info: filepath = {}".format(os.path.join(self._sh_dir, 'doc', 'requirements.txt'))) + else: + self.logger.error("get_requirements_info: Unknown requirements group '{}' requested".format(req_group)) + + if req_group == 'base': + # parse loaded plugins and look for requirements + _conf = lib.config.parse(self._sh._plugin_conf) + plugin_names = [] + for plugin in _conf: + plugin_name = _conf[plugin].get('class_path', '').strip() + if plugin_name == '': + plugin_name = 'plugins.' + _conf[plugin].get('plugin_name', '').strip() + if not plugin_name in plugin_names: # only unique plugin names, e.g. if multiinstance is used + plugin_names.append(plugin_name) + self.logger.info("get_requirements_info: len(_conf) = {}, len(plugin_names) = {}, plugin_names = {}".format(len(_conf), len(plugin_names), plugin_names)) + + req_dict = req_dict_base.copy() + for plugin_name in plugin_names: + file_path = "%s/%s/requirements.txt" % (self._sh_dir, plugin_name.replace("plugins.", "plugins/")) + if os.path.isfile(file_path): + plugin_dict = parse_requirements(file_path) + for key in plugin_dict: + if key not in req_dict: + req_dict[key] = plugin_dict[key] + ' (' + plugin_name.replace('plugins.', '') + ')' + else: + req_dict[key] = req_dict[key] + '
' + plugin_dict[key] + ' (' + plugin_name.replace( + 'plugins.', '') + ')' + + if req_group in ['doc','test']: + req_dict = req_dict_base.copy() + + self.logger.info("get_requirements_info: req_dict for group {} = {}".format(req_group, req_dict)) + return req_dict + + + def compare_versions(self, vers1, vers2, operator): + """ + Compare two version numbers and return if the condition is met + """ + v1s = vers1.split('.') + while len(v1s) < 4: + v1s.append('0') + v1 = [] + for v in v1s: + vi = 0 + try: + vi = int(v) + except: pass + v1.append(vi) + + v2s = vers2.split('.') + while len(v2s) < 4: + v2s.append('0') + v2 = [] + for v in v2s: + vi = 0 + try: + vi = int(v) + except: pass + v2.append(vi) + + result = False + if v1 == v2 and operator in ['>=','==','<=']: + result = True + if v1 < v2 and operator in ['<','<=']: + result = True + if v1 > v2 and operator in ['>','>=']: + result = True + + self.logger.debug("compare_versions: - - - v1 = {}, v2 = {}, operator = '{}', result = {}".format(v1, v2, operator, result)) + return result + + + def strip_operator(self, string, operator): + """ + Strip a leading operator from a string and remove quotes, if they exist + + :param string: string to remove the operator from + :param operator: operator to remove + :type string: str + :type operator: str + + :return: string without the operator + :rtype: str + """ + if string.startswith(operator): + return Utils.strip_quotes(string[len(operator):].strip()) + else: + return Utils.strip_quotes(string.strip()) + + + def split_operator(self, reqstring): + """ + split operator and version from string + + :param reqstring: string containing operator and version + :type reqstring: str + + :return: operator, version + :rtype: str, str + """ + if reqstring.startswith('=='): + operator = '==' + version = self.strip_operator(reqstring, operator) + elif reqstring.startswith('<='): + operator = '<=' + version = self.strip_operator(reqstring, operator) + elif reqstring.startswith('>='): + operator = '>=' + version = self.strip_operator(reqstring, operator) + elif reqstring.startswith('<'): + operator = '<' + version = self.strip_operator(reqstring, operator) + elif reqstring.startswith('>'): + operator = '>=' + version = self.strip_operator(reqstring, operator) + else: + operator = '' + version = reqstring + + return operator.strip(), version.strip() + + + def req_is_pyversion_req_relevant(self, pyreq, package=''): + """ + Test if requirement has a Python version restriction and if so, test if the restriction + is relevant. + """ + pyversion = "{0}.{1}".format(sys.version_info[0], sys.version_info[1]) + + pyreq = pyreq.strip().replace('python_version', '') + pyv_operator = '' + if pyreq != '': + self.logger.debug("req_is_pyversion_req_relevant: - - package {}, py_version {}".format(package, pyreq)) + if pyreq.startswith('=='): + pyv_operator = '==' + pyreq = self.strip_operator(pyreq, pyv_operator) + result = self.compare_versions(pyversion, pyreq, pyv_operator) + elif pyreq.startswith('<='): + pyv_operator = '<=' + pyreq = self.strip_operator(pyreq, pyv_operator) + result = self.compare_versions(pyversion, pyreq, pyv_operator) + elif pyreq.startswith('>='): + pyv_operator = '>=' + pyreq = self.strip_operator(pyreq, pyv_operator) + result = self.compare_versions(pyversion, pyreq, pyv_operator) + elif pyreq.startswith('<'): + pyv_operator = '<' + pyreq = self.strip_operator(pyreq, pyv_operator) + result = self.compare_versions(pyversion, pyreq, pyv_operator) + elif pyreq.startswith('>'): + pyv_operator = '>' + result = pyreq = self.strip_operator(pyreq, pyv_operator) + self.compare_versions(pyversion, pyreq, pyv_operator) + else: + pyv_operator = '' + self.logger.error("req_is_pyversion_req_relevant: no operator in front of Python version found - package {}, pyreq = {}".format(package, pyreq)) + result = False + + self.logger.debug("req_is_pyversion_req_relevant: - - - package {}, py_version_operator {}, py_version {}".format(package, pyv_operator, pyreq)) + return result + + +# operator: <, <=, ==, >=, >> +# source: or 'core' +# version_relation: +# pyversion_relation: +# version_relations: , +# py_vers_requirement: ; +# py_vers_requirements: | +# requirement_string: () + + def req_split_source(self, req, package=''): + """ + Splits the requirement source from the requirement string + """ + self.logger.debug("req_split_source: package {}, req = '{}'".format(package, req)) + req = req.lower().strip() + + # seperate requirement from source + source = 'core' + req1 = req + if '(' in req: + wrk = req.split('(') + source = wrk[1][0:wrk[1].find(")")].strip() + req1 = wrk[0].strip() + self.logger.debug("req_split_source: - source {}, req1 = '{}'".format(source, req1)) + + # seperate requirements for different Python versions + req2 = req1.split('|') + reql = [] + for r in req2: + reql.append(r.strip()) + self.logger.debug("req_split_source: - source {}, reql = {}".format(source, reql)) + + req_result = [] + for req in reql: + # isolate and handle Python version + wrk = req.split(';') + sreq = wrk[0].strip() + if len(wrk) > 1: + valid = self.req_is_pyversion_req_relevant(wrk[1], package) + else: + valid = True + +# self.logger.info("req_split_source: - - - source {}, py_version_operator {}, py_version {}, sreq = {}".format(source, pyv_operator, pyreq, sreq)) + + if valid: + # check and handle version requirements + wrkl = sreq.split(',') + if len(wrkl) > 2: + self.logger.error("req_split_source: More that two requirements for package {} req = {}".format(package, reql)) + rmin = '' + rmax = '' + for r in wrkl: + if r.find('<') != -1 or r.find('<=') != -1: + rmax = r + if r.find('>') != -1 or r.find('>=') != -1: + rmin = r + if r.find('==') != -1: + rmin = r + rmax = r + req_result.append([source, rmin, rmax]) + + self.logger.debug("req_split_source: - package {} req_result = {}".format(package, req_result)) + if len(req_result) > 1: + self.logger.warning("req_split_source: Cannot reconcile multiple version requirements for package {} for running Python version".format(package)) + else: + req_result = req_result[0] + return req_result + + + def check_requirement(self, package, req_str): + """ + """ + pyversion = "{0}.{1}".format(sys.version_info[0], sys.version_info[1]) + req_min = '' + req_max = '' + # split requirements + req_templist = req_str.split('
') # split up requirements from different plugins and the core + + req_result = [] + for req in req_templist: + req_result.append( self.req_split_source(req, package) ) + self.logger.info("check_requirement: package {}, len(req_result)={}, req_result = '{}'".format(package, len(req_result), req_result)) + + # Check if requirements from all sources are the same + if len(req_result) > 1: + are_equal = True + for req in req_result: + if req[1] != req_result[0][1]: + are_equal = False + if req[2] != req_result[0][2]: + are_equal = False + if are_equal: + req_result = [req_result[0]] + + req_txt = req_result + # Now we have a list of [ requirement_source, min_version (with operator), max_version (with operator) ] + if len(req_result) == 1: + result = req_result[0] + self.logger.info("check_requirement: package {}, req_result = >{}<, result = >{}<".format(package, req_result, result)) + #handle min + op, req_min = self.split_operator(result[1]) + if req_min == '*': + req_min = '' + req_txt = '' + else: + if op == '>': + req_min += '.0' + + #handle max + op, req_max = self.split_operator(result[2]) + if req_max == '*': + req_max = '' + req_txt = '' +# else: +# if op == '<': +# req_max = ? + + + self.logger.info("check_requirement: package {} ({}), req_result = '{}'".format(package, len(req_result), req_result)) + if req_min != '' or req_max != '': + req_txt = '' + + return req_min, req_max, req_txt + + + def getpackages(self): + """ + returns a list with the installed python packages and its versions + """ + self.find_visu_plugin() + + # check if pypi service is reachable + if self.pypi_timeout <= 0: + pypi_available = False + pypi_unavailable_message = translate('PyPI Prüfung deaktiviert') + else: + pypi_available = True + try: + import socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(self.pypi_timeout) + sock.connect(('pypi.python.org', 443)) + sock.close() + except: + pypi_available = False + pypi_unavailable_message = translate('PyPI nicht erreichbar') + + import pip + import xmlrpc + installed_packages = pip.get_installed_distributions() + pypi = xmlrpc.client.ServerProxy('https://pypi.python.org/pypi') + packages = [] + for dist in installed_packages: + package = {} + package['key'] = dist.key + package['version_installed'] = dist.version + if pypi_available: + try: + available = pypi.package_releases(dist.project_name) + try: + package['version_available'] = available[0] + except: + package['version_available'] = '-' + except: + package['version_available'] = [translate('Keine Antwort von PyPI')] + else: + package['version_available'] = pypi_unavailable_message + packages.append(package) + + sorted_packages = sorted([(i['key'], i['version_installed'], i['version_available']) for i in packages]) + return sorted_packages + + diff --git a/backend/BackendThreads.py b/backend/BackendThreads.py new file mode 100755 index 000000000..f7514de00 --- /dev/null +++ b/backend/BackendThreads.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +import threading + +class BackendThreads: + + + # ----------------------------------------------------------------------------------- + # THREADS + # ----------------------------------------------------------------------------------- + + def thread_sum(self, name, count): + thread = dict() + if count > 0: + thread['name'] = name + thread['sort'] = str(thread['name']).lower() + thread['id'] = "(" + str(count) + " threads" + ")" + thread['alive'] = 'Ja' + return thread + + @cherrypy.expose + def threads_html(self): + """ + display a list of all threads + """ + threads_count = 0 + cp_threads = 0 + http_threads = 0 + idle_threads = 0 + for thread in threading.enumerate(): + if thread.name.find("CP Server") == 0: + cp_threads += 1 + if thread.name.find("HTTPServer") == 0: + http_threads +=1 + if thread.name.find("idle") == 0: + idle_threads +=1 + + threads = [] + for t in threading.enumerate(): + if t.name.find("CP Server") != 0 and t.name.find("HTTPServer") != 0 and t.name.find("idle") != 0: + thread = dict() + thread['name'] = t.name + thread['sort'] = str(t.name).lower() + thread['id'] = t.ident + try: + if t.is_alive(): + thread['alive'] = 'Ja' + else: + thread['alive'] = 'Nein' + except AssertionError: + thread['alive'] = 'AssertionError' + + threads.append(thread) + threads_count += 1 + + if cp_threads > 0: + threads.append(self.thread_sum("CP Server", cp_threads)) + threads_count += cp_threads + if http_threads > 0: + threads.append(self.thread_sum("HTTPServer", http_threads)) + threads_count += http_threads + if idle_threads > 0: + threads.append(self.thread_sum("idle", idle_threads)) + threads_count += idle_threads + + threads_sorted = sorted(threads, key=lambda k: k['sort']) + return self.render_template('threads.html', threads=threads_sorted, threads_count=threads_count) + + diff --git a/backend/BackendVisu.py b/backend/BackendVisu.py new file mode 100755 index 000000000..a548ba7bf --- /dev/null +++ b/backend/BackendVisu.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy + +class BackendVisu: + + + # ----------------------------------------------------------------------------------- + # VISU + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def visu_html(self): + """ + display a list of all connected visu clients + """ + clients = [] + if self.visu_plugin is not None: + if self.visu_plugin_build == '2': + for c in self.visu_plugin.return_clients(): + client = dict() + deli = c.find(':') + client['ip'] = c[0:c.find(':')] + client['port'] = c[c.find(':') + 1:] + try: + client['name'] = socket.gethostbyaddr(client['ip'])[0] + except: + client['name'] = client['ip'] + clients.append(client) + + if self.visu_plugin_build > '2': + # self.logger.warning("BackendServer: Language '{0}' not found, using standard language instead".format(language)) + # yield client.addr, client.sw, client.swversion, client.hostname, client.browser, client.browserversion + # for c, sw, swv, ch in self.visu_plugin.return_clients(): + for clientinfo in self.visu_plugin.return_clients(): + c = clientinfo.get('addr', '') + client = dict() + deli = c.find(':') + client['ip'] = c[0:c.find(':')] + client['port'] = c[c.find(':') + 1:] + try: + client['name'] = socket.gethostbyaddr(client['ip'])[0] + except: + client['name'] = client['ip'] + client['sw'] = clientinfo.get('sw', '') + client['swversion'] = clientinfo.get('swversion', '') + client['hostname'] = clientinfo.get('hostname', '') + client['browser'] = clientinfo.get('browser', '') + client['browserversion'] = clientinfo.get('browserversion', '') + clients.append(client) + + clients_sorted = sorted(clients, key=lambda k: k['name']) + + self.find_visu_plugin() + return self.render_template('visu.html', + visu_plugin_build=self.visu_plugin_build, + clients=clients_sorted) + + diff --git a/backend/README.md b/backend/README.md old mode 100644 new mode 100755 index 9dfb59de9..f79587da9 --- a/backend/README.md +++ b/backend/README.md @@ -21,7 +21,9 @@ Support is provided trough the support thread within the smarthomeNG forum: ## Requirements -This plugin is running under Python >= 3.4 as well as the libs cherrypy and jinja2. You can install them with: +This version of the plugin needs **SmartHomeNG v1.4 or newer**. + +This plugin is running under **Python >= 3.4** as well as the libs cherrypy and jinja2. You can install them with: ``` (sudo apt-get install python-cherrypy) sudo pip3 install cherrypy @@ -33,87 +35,39 @@ And please pay attention that the libs are installed for Python3 and not an olde The log level filter in the log file view will only work with "%(asctime)s %(levelname)-8s" in the beginning of the configured format! Dateformat needs to be datefmt: '%Y-%m-%d %H:%M:%S' -### Running this plugin under Python 3.2 -If you really need to run this plugin under Python 3.2 you may not use the newest version of all packages. The packages **Jinja2** and **MarkupSafe** have dropped support for Python 3.2. Make sure to install the following older versions into your Phython3.2 environment, as newer versions are not compatible with Python 3.2 any more: - -``` -- Jinja2 v2.6 -- MarkupSafe v0.15 -``` - - +> Note: This plugin needs the SmartHomeNG loadable module `http` to be installed/configured. To support visualization, the visu_websocket plugin has to be used. It has to be PLUGIN_VERSION >= "1.1.2". ## Configuration -### plugin.conf (deprecated) / plugin.yaml +### plugin.yaml / plugin.conf (deprecated) + +```yaml +# /etc/plugin.yaml +BackendServer: + plugin_name: backend + #updates_allowed: 'True' + #developer_mode: 'on' + #pypi_timeout: 5 +``` ``` +# /etc/plugin.conf [BackendServer] class_name = BackendServer class_path = plugins.backend - #ip = xxx.xxx.xxx.xxx - #port = 8383 #updates_allowed = True - #threads = 8 - #user = admin - #password = very_secure_password - #hashed_password = 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d - #language = en #developer_mode = on #pypi_timeout = 5 ``` -```yaml -BackendServer: - class_name: BackendServer - class_path: plugins.backend - #ip: xxx.xxx.xxx.xxx - #port: 8383 - #updates_allowed: 'True' - #threads: 8 - #user: admin - #password: very_secure_password - #hashed_password: 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d - #language: en - #developer_mode: 'on' - #pypi_timeout: 5 -``` - -#### ip -IP address to start the backend server. Usually it doesnot need to be configured. - -If not configured the standard ip address of the system is used. If you like to restrict the usage of the BackendServer to the system itself (the browser ist running on the smarthomeNG system itself), you can configure the ip to 127.0.0.1. In this case, the BackendServer is only available through the localhost address. - -#### port -The port on which the backend server listens. By default port **`8383`** is used. #### updates_allowed By default, the backend server allows updates to the running smarthomeNG instance. For instance, it is possible to trigger or to reload a logic. Setting **`updates_allowed`** to **`False`**, you can disable these features. -#### threads - -Number of worker threads to start by cherrypy (default 8, which may be too much for slow CPUs) - -#### user (optional) - -The user for basic authentication. If left out, the user name is set as "admin" - -#### password (optional) - -The plaintext password for basic authentication. If you want to store your password as hash, use 'hashed_password' instead. If both "password" and "hashed_password" are left out, basic authentication is disabled. - -#### hashed_password (optional) - -The password for basic authentication as hash value. Can be used instead of "password" if you do not want a plaintext password in your config file. If both "password" and "hashed_password" are left out, basic authentication is disabled. Currently hashed_password is the SHA-512 hash value of the password. To create the hash for your password, you can use function "Create password hash" on page "Services" in the backend. - -#### language (optional) - -You can specify a language to use for the plugin. Besides the standard language (german) which is used, if this parameter isn't set, you can specify english (for the time being). The language is specified by **``en``** - #### developer_mode (optional) You may specify develper_mode = on, if you are developiing within the backend plugin. At the moment, the only thing that changes is an additional button **``reload translation``** on the services page diff --git a/backend/__init__.py b/backend/__init__.py old mode 100644 new mode 100755 index 28157b769..8896cd413 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# -*- coding: utf8 -*- +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab ######################################################################### # Copyright 2016- René Frieß rene.friess@gmail.com # Martin Sinn m.sinn@gmx.de @@ -8,208 +8,304 @@ ######################################################################### # Backend plugin for SmartHomeNG # +# It runs with SmartHomeNG version 1.4 and upwards. +# # This plugin is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # -# This plugin is distributed in the hope that it will be useful, +# SmartHomeNG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this plugin. If not, see . +# along with SmartHomeNG. If not, see . +# ######################################################################### -import cherrypy import logging -import platform -import collections -import datetime -import pwd -import html -import os -import json -import subprocess -import socket -import sys -import threading -import lib.config + from lib.model.smartplugin import SmartPlugin -from lib.utils import Utils -from jinja2 import Environment, FileSystemLoader -from .BackendCore import Backend as BackendCore -from .BackendBlockly import BackendBlocklyLogics from .utils import * +from .BackendSysteminfo import BackendSysteminfo +from .BackendServices import BackendServices +from .BackendItems import BackendItems +from .BackendLogics import BackendLogics +from .BackendSchedulers import BackendSchedulers +from .BackendPlugins import BackendPlugins +from .BackendScenes import BackendScenes +from .BackendThreads import BackendThreads +from .BackendLogging import BackendLogging +from .BackendVisu import BackendVisu -class BackendServer(SmartPlugin): - ALLOW_MULTIINSTANCE = False - PLUGIN_VERSION='1.3.5' - def my_to_bool(self, value, attr='', default=False): - try: - result = self.to_bool(value) - except: - result = default - self.logger.error("BackendServer: Invalid value '"+str(value)+"' configured for attribute "+attr+" in plugin.conf, using '"+str(result)+"' instead") - return result +class BackendServer(SmartPlugin): + """ + Main class of the Plugin. Does all plugin specific stuff and provides + the update functions for the items + """ + + PLUGIN_VERSION='1.4.8' + + + def __init__(self, sh, updates_allowed='True', developer_mode="no", pypi_timeout=5): + """ + Initalizes the plugin. The parameters describe for this method are pulled from the entry in plugin.conf. + + :param sh: **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! + :param *args: **Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! + :param **kwargs:**Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! + + If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for + a reference to the sh object any more. + + The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are imlemented + to support oder plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values: + use the SmartPlugin method get_parameter_value(parameter_name) instead. Anywhere within the Plugin you can get + the configured (and checked) value for a parameter by calling self.get_parameter_value(parameter_name). It + returns the value in the datatype that is defined in the metadata. + """ + self.logger = logging.getLogger(__name__) - def get_local_ip_address(self): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect(("10.10.10.10", 80)) - return s.getsockname()[0] + self.updates_allowed = self.get_parameter_value('updates_allowed') + self.developer_mode = self.get_parameter_value('developer_mode') + self.pypi_timeout = self.get_parameter_value('pypi_timeout') + + self.language = self.get_sh().get_defaultlanguage() + if self.language != '': + if not load_translation(self.language): + self.logger.warning("Language '{}' not found, using standard language instead".format(self.language)) - def __init__(self, sh, port=None, threads=8, ip='', updates_allowed='True', user="admin", password="", hashed_password="", language="", developer_mode="no", pypi_timeout=5): - self.logger = logging.getLogger(__name__) - self._user = user - self._password = password - self._hashed_password = hashed_password - - if self._password is not None and self._password != "" and self._hashed_password is not None and self._hashed_password != "": - self.logger.warning("BackendServer: Both 'password' and 'hashed_password' given. Ignoring 'password' and using 'hashed_password'!") - self._password = None - - if self._password is not None and self._password != "" and (self._hashed_password is None or self._hashed_password == ""): - self.logger.warning("BackendServer: Giving plaintext password in configuration is insecure. Consider using 'hashed_password' instead!") - self._hashed_password = None - - if (self._password is not None and self._password != "") or (self._hashed_password is not None and self._hashed_password != ""): - self._basic_auth = True - else: - self._basic_auth = False - self._sh = sh - - if self.is_int(port): - self.port = int(port) - else: - self.port = 8383 - if port is not None: - self.logger.error("BackendServer: Invalid value '"+str(port)+"' configured for attribute 'port' in plugin.conf, using '"+str(self.port)+"' instead") - - if self.is_int(threads): - self.threads = int(threads) - else: - self.threads = 8 - self.logger.error("BackendServer: Invalid value '"+str(threads)+"' configured for attribute 'thread' in plugin.conf, using '"+str(self.threads)+"' instead") - - if ip == '': - ip = self.get_local_ip_address() - self.logger.debug("BackendServer: Using local ip address '{0}'".format(ip)) - else: - pass - # if not self.is_ip(ip): - # self.logger.error("BackendServer: Invalid value '"+str(ip)+"' configured for attribute ip in plugin.conf, using '"+str('0.0.0.0')+"' instead") - # ip = '0.0.0.0' - language = language.lower() - if language != '': - if not load_translation(language): - self.logger.warning("BackendServer: Language '{0}' not found, using standard language instead".format(language)) - self.developer_mode = self.my_to_bool(developer_mode, 'developer_mode', False) - - self.updates_allowed = self.my_to_bool(updates_allowed, 'updates_allowed', True) - - if self.is_int(pypi_timeout): - self.pypi_timeout = int(pypi_timeout) - else: - self.pypi_timeout = 5 - if pypi_timeout is not None: - self.logger.error("BackendServer: Invalid value '" + str(pypi_timeout) + "' configured for attribute 'pypi_timeout' in plugin.conf, using '" + str(self.pypi_timeout) + "' instead") - - current_dir = os.path.dirname(os.path.abspath(__file__)) - self.logger.debug("BackendServer running from '{}'".format(current_dir)) - - config = {'global': { - 'engine.autoreload.on': False, - 'tools.staticdir.debug': True, - 'tools.trailing_slash.on': False, - 'log.screen': False - }, - '/': { - 'tools.auth_basic.on': self._basic_auth, - 'tools.auth_basic.realm': 'earth', - 'tools.auth_basic.checkpassword': self.validate_password, - 'tools.staticdir.root': current_dir, - }, - '/static': { - 'tools.staticdir.on': True, - 'tools.staticdir.dir': os.path.join(current_dir, 'static') - } - } - from cherrypy._cpserver import Server - self._server = Server() - self._server.socket_host = ip - self._server.socket_port = int(self.port) - self._server.thread_pool = self.threads - self._server.subscribe() + if not self.init_webinterface(): + self._init_complete = False + + return - self._cherrypy = cherrypy - self._cherrypy.config.update(config) - self._cherrypy.tree.mount(Backend(self, self.updates_allowed, language, self.developer_mode, self.pypi_timeout), '/', config = config) def run(self): - self.logger.debug("BackendServer: rest run") - self._server.start() - #self._cherrypy.engine.start() - self.logger.debug("BackendServer: engine started") - #cherrypy.engine.block() + """ + Run method for the plugin + """ + self.logger.debug("Plugin '{}': run method called".format(self.get_fullname())) self.alive = True + # if you want to create child threads, do not make them daemon = True! + # They will not shutdown properly. (It's a python bug) + def stop(self): - self.logger.debug("BackendServer: shutting down") - self._server.stop() - #self._cherrypy.engine.exit() - self.logger.debug("BackendServer: engine exited") + """ + Stop method for the plugin + """ + self.logger.debug("Plugin '{}': stop method called".format(self.get_fullname())) self.alive = False + def parse_item(self, item): + """ + Default plugin parse_item method. Is called when the plugin is initialized. + The plugin can, corresponding to its attribute keywords, decide what to do with + the item in future, like adding it to an internal array for future reference + :param item: The item to process. + :return: If the plugin needs to be informed of an items change you should return a call back function + like the function update_item down below. An example when this is needed is the knx plugin + where parse_item returns the update_item function when the attribute knx_send is found. + This means that when the items value is about to be updated, the call back function is called + with the item, caller, source and dest as arguments and in case of the knx plugin the value + can be sent to the knx with a knx write function within the knx plugin. + """ pass + def parse_logic(self, logic): + """ + Default plugin parse_logic method + """ pass + def update_item(self, item, caller=None, source=None, dest=None): + """ + Write items values + :param item: item to be updated towards the plugin + :param caller: if given it represents the callers name + :param source: if given it represents the source + :param dest: if given it represents the dest + """ pass - def validate_password(self, realm, username, password): - if username != self._user or password is None or password == "": + + def init_webinterface(self): + """" + Initialize the web interface for this plugin + + This method is only needed if the plugin is implementing a web interface + """ + try: + self.mod_http = self.get_module('http') # try/except to handle running in a core version that does not support modules + except: + self.mod_http = None + + if self.mod_http == None: + self.logger.error("Plugin '{}': Not initializing the web interface".format(self.get_fullname())) return False + + # set application configuration for cherrypy + webif_dir = self.path_join(self.get_plugin_dir(), 'webif') + config = { + '/': { + 'tools.staticdir.root': webif_dir, + }, + '/static': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': 'static' + } + } + + # Register the web interface as a cherrypy app + self.mod_http.register_webif(WebInterface(webif_dir, self), + self.get_shortname(), + config, + self.get_classname(), self.get_instance_name(), + description='Administrationsoberfläche für SmartHomeNG', + webifname='') + + return True + + +# ------------------------------------------ +# Webinterface of the plugin +# ------------------------------------------ - if self._hashed_password is not None: - return Utils.check_hashed_password(password, self._hashed_password) - elif self._password is not None: - return password == self._password +import os - return False +import cherrypy +from jinja2 import Environment, FileSystemLoader - +from lib.logic import Logics +import lib.item_conversion -class Backend(BackendCore, BackendBlocklyLogics): - env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__))+'/templates')) - env.globals['get_basename'] = get_basename - env.globals['is_userlogic'] = is_userlogic - env.globals['_'] = translate - - def __init__(self, backendserver=None, updates_allowed=True, language='', developer_mode=False, pypi_timeout = 5): +class WebInterface(BackendSysteminfo, BackendServices, BackendItems, BackendLogics, + BackendSchedulers, BackendPlugins, BackendScenes, BackendThreads, + BackendLogging, BackendVisu): + + blockly_plugin_loaded = None # None = load state is unknown + + def __init__(self, webif_dir, plugin): + """ + Initialization of instance of class WebInterface + + :param webif_dir: directory where the webinterface of the plugin resides + :param plugin: instance of the plugin + :type webif_dir: str + :type plugin: object + """ self.logger = logging.getLogger(__name__) - self._bs = backendserver - self._sh = backendserver._sh - self.language = language - self.updates_allowed = updates_allowed - self.developer_mode = developer_mode - self.pypi_timeout = pypi_timeout + + self.webif_dir = webif_dir + self.plugin = plugin + self.logger.info("{}: Running from '{}'".format(self.__class__.__name__, self.webif_dir)) + + self.tplenv = Environment(loader=FileSystemLoader(self.plugin.path_join( self.webif_dir, 'templates' ) )) + from os.path import basename as get_basename + self.tplenv.globals['get_basename'] = get_basename + self.tplenv.globals['is_userlogic'] = Logics.is_userlogic + self.tplenv.globals['_'] = translate + + self.env = self.tplenv # because the new naming isn't globally implemented + + self.logger = logging.getLogger(__name__) + self._bs = plugin + self._sh = plugin.get_sh() + self.language = plugin.language + self.updates_allowed = plugin.updates_allowed + self.developer_mode = plugin.developer_mode + self.pypi_timeout = plugin.pypi_timeout self._sh_dir = self._sh.base_dir self.visu_plugin = None self.visu_plugin_version = '1.0.0' + def html_escape(self, str): + """ + escape characters in html + """ return html_escape(str) -#if __name__ == "__main__": -# server = BackendServer( None, port=8080, ip='0.0.0.0') -# server.run() + def find_visu_plugin(self): + """ + look for the configured instance of the visu protocol plugin. + """ + if self.visu_plugin is not None: + return + + for p in self._sh._plugins: + if p.__class__.__name__ == "WebSocket": + self.visu_plugin = p + if self.visu_plugin is not None: + try: + self.visu_plugin_version = self.visu_plugin.get_version() + except: + self.visu_plugin_version = '1.0.0' + self.visu_plugin_build = self.visu_plugin_version[4:] + if self.visu_plugin_build < '2': + self.visu_plugin = None + self.logger.warning( + "Visu protocol plugin v{} is too old to support backend, please update".format( + self.visu_plugin_version)) + + + def render_template(self, tmpl_name, **kwargs): + """ + + Render a template and add vars needed gobally (for navigation, etc.) + + :param tmpl_name: Name of the template file to be rendered + :param **kwargs: keyworded arguments to use while rendering + + :return: contents of the template after beeing rendered + + """ + self.find_visu_plugin() + tmpl = self.tplenv.get_template(tmpl_name) + return tmpl.render(develop=self.developer_mode, + smarthome=self._sh, + visu_plugin=(self.visu_plugin is not None), + yaml_converter=lib.item_conversion.is_ruamelyaml_installed(), + **kwargs) + + + # ----------------------------------------------------------------------------------- + # MAIN + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def index(self): + """ + display index page + """ + return self.render_template('index.html') + + @cherrypy.expose + def main_html(self): + + return self.render_template('main.html') + + + # ----------------------------------------------------------------------------------- + # DISCLOSURE + # ----------------------------------------------------------------------------------- + + @cherrypy.expose + def disclosure_html(self): + """ + display disclosure + """ + return self.render_template('disclosure.html') + diff --git a/backend/BackendBlockly.py b/backend/_pv_1_3_5/BackendBlockly.py old mode 100644 new mode 100755 similarity index 100% rename from backend/BackendBlockly.py rename to backend/_pv_1_3_5/BackendBlockly.py diff --git a/backend/BackendCore.py b/backend/_pv_1_3_5/BackendCore.py old mode 100644 new mode 100755 similarity index 97% rename from backend/BackendCore.py rename to backend/_pv_1_3_5/BackendCore.py index 9f18d0160..5b0d962e9 --- a/backend/BackendCore.py +++ b/backend/_pv_1_3_5/BackendCore.py @@ -821,14 +821,16 @@ def plugins_html(self): _conf = lib.config.parse(self._sh._plugin_conf) for plugin in _conf: # self.logger.warning("plugins_html: class_name='{0}', class_path='{1}'".format(_conf[plugin]['class_name'], _conf[plugin]['class_path'])) - conf_plugins[_conf[plugin]['class_name']] = _conf[plugin]['class_path'] + conf_plugins[_conf[plugin]['class_name']] = {} + conf_plugins[_conf[plugin]['class_name']] = _conf[plugin] # self.logger.warning("plugins_html: conf_plugins='{0}'".format(conf_plugins)) plugins = [] for x in self._sh._plugins: plugin = dict() plugin['classname'] = x.__class__.__name__ - plugin['classpath'] = conf_plugins[x.__class__.__name__] + plugin['classpath'] = conf_plugins[x.__class__.__name__]['class_path'] + plugin['attributes'] = conf_plugins[x.__class__.__name__] if isinstance(x, SmartPlugin): plugin['smartplugin'] = True plugin['instancename'] = x.get_instance_name() diff --git a/backend/_pv_1_3_5/README.md b/backend/_pv_1_3_5/README.md new file mode 100755 index 000000000..9d06592c8 --- /dev/null +++ b/backend/_pv_1_3_5/README.md @@ -0,0 +1,123 @@ +# Backend GUI v1.3.5 (up to shNG v1.3) + +This plugin delivers information about the current SmartHomeNG installation. Right now it serves as a support tool for helping other users with an installation that does not run properly. Some highlights: + +* a list of installed python modules is shown versus the available versions from PyPI +* a list of items and their attributes is shown +* a list of logics and their next execution time +* a list of current schedulers and their next execution time +* direct download of sqlite database (if plugin is used) and smarthome.log +* some information about frequently used daemons like knxd/eibd is included +* supports basic authentication +* multi-language support + +There is however only basic protection against unauthorized access or use of the plugin so be careful when enabling it with your network. + +Call the backend-webserver: **```http://:8383```** + +Support is provided trough the support thread within the smarthomeNG forum: + +[knx-user-forum.de/forum/supportforen/smarthome-py/959964-support-thread-f%C3%BCr-das-backend-plugin](https://knx-user-forum.de/forum/supportforen/smarthome-py/959964-support-thread-für-das-backend-plugin) + +## Requirements + +This plugin is running under Python >= 3.4 as well as the libs cherrypy and jinja2. You can install them with: +``` +(sudo apt-get install python-cherrypy) +sudo pip3 install cherrypy +(sudo apt-get install python-jinja2) +sudo pip3 install jinja2 +``` + +And please pay attention that the libs are installed for Python3 and not an older Python 2.7 that is probably installed on your system. + +The log level filter in the log file view will only work with "%(asctime)s %(levelname)-8s" in the beginning of the configured format! Dateformat needs to be datefmt: '%Y-%m-%d %H:%M:%S' + +### Running this plugin under Python 3.2 +If you really need to run this plugin under Python 3.2 you may not use the newest version of all packages. The packages **Jinja2** and **MarkupSafe** have dropped support for Python 3.2. Make sure to install the following older versions into your Phython3.2 environment, as newer versions are not compatible with Python 3.2 any more: + +``` +- Jinja2 v2.6 +- MarkupSafe v0.15 +``` + + + +To support visualization, the visu_websocket plugin has to be used. It has to be PLUGIN_VERSION >= "1.1.2". + + +## Configuration + +### plugin.conf (deprecated) / plugin.yaml + +``` +[BackendServer] + class_name = BackendServer + class_path = plugins.backend + #ip = xxx.xxx.xxx.xxx + #port = 8383 + #updates_allowed = True + #threads = 8 + #user = admin + #password = very_secure_password + #hashed_password = 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d + #language = en + #developer_mode = on + #pypi_timeout = 5 +``` + +```yaml +BackendServer: + class_name: BackendServer + class_path: plugins.backend + #ip: xxx.xxx.xxx.xxx + #port: 8383 + #updates_allowed: 'True' + #threads: 8 + #user: admin + #password: very_secure_password + #hashed_password: 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d + #language: en + #developer_mode: 'on' + #pypi_timeout: 5 +``` + +#### ip +IP address to start the backend server. Usually it doesnot need to be configured. + +If not configured the standard ip address of the system is used. If you like to restrict the usage of the BackendServer to the system itself (the browser ist running on the smarthomeNG system itself), you can configure the ip to 127.0.0.1. In this case, the BackendServer is only available through the localhost address. + +#### port +The port on which the backend server listens. By default port **`8383`** is used. + +#### updates_allowed + +By default, the backend server allows updates to the running smarthomeNG instance. For instance, it is possible to trigger or to reload a logic. Setting **`updates_allowed`** to **`False`**, you can disable these features. + +#### threads + +Number of worker threads to start by cherrypy (default 8, which may be too much for slow CPUs) + +#### user (optional) + +The user for basic authentication. If left out, the user name is set as "admin" + +#### password (optional) + +The plaintext password for basic authentication. If you want to store your password as hash, use 'hashed_password' instead. If both "password" and "hashed_password" are left out, basic authentication is disabled. + +#### hashed_password (optional) + +The password for basic authentication as hash value. Can be used instead of "password" if you do not want a plaintext password in your config file. If both "password" and "hashed_password" are left out, basic authentication is disabled. Currently hashed_password is the SHA-512 hash value of the password. To create the hash for your password, you can use function "Create password hash" on page "Services" in the backend. + +#### language (optional) + +You can specify a language to use for the plugin. Besides the standard language (german) which is used, if this parameter isn't set, you can specify english (for the time being). The language is specified by **``en``** + +#### developer_mode (optional) + +You may specify develper_mode = on, if you are developiing within the backend plugin. At the moment, the only thing that changes is an additional button **``reload translation``** on the services page + +#### pypi_timeout (optional) + +Timeout for PyPI accessibility check (seconds). PyPI is queried on page "Systeminfo" to compare installed python module versions with current versions if accessible. If you receive the message "PyPI inaccessible" on systems with internet access you may increase the value. On systems where PyPI can not be reached (no/restricted internet access) you may set the timeout to 0 which disables the PyPI queries. diff --git a/backend/_pv_1_3_5/__init__.py b/backend/_pv_1_3_5/__init__.py new file mode 100755 index 000000000..28157b769 --- /dev/null +++ b/backend/_pv_1_3_5/__init__.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016- René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +# Bernd Meiners +# Christian Strassburg c.strassburg@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import cherrypy +import logging +import platform +import collections +import datetime +import pwd +import html +import os +import json +import subprocess +import socket +import sys +import threading +import lib.config +from lib.model.smartplugin import SmartPlugin +from lib.utils import Utils +from jinja2 import Environment, FileSystemLoader + +from .BackendCore import Backend as BackendCore +from .BackendBlockly import BackendBlocklyLogics +from .utils import * + + + +class BackendServer(SmartPlugin): + ALLOW_MULTIINSTANCE = False + PLUGIN_VERSION='1.3.5' + + def my_to_bool(self, value, attr='', default=False): + try: + result = self.to_bool(value) + except: + result = default + self.logger.error("BackendServer: Invalid value '"+str(value)+"' configured for attribute "+attr+" in plugin.conf, using '"+str(result)+"' instead") + return result + + def get_local_ip_address(self): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("10.10.10.10", 80)) + return s.getsockname()[0] + + def __init__(self, sh, port=None, threads=8, ip='', updates_allowed='True', user="admin", password="", hashed_password="", language="", developer_mode="no", pypi_timeout=5): + self.logger = logging.getLogger(__name__) + self._user = user + self._password = password + self._hashed_password = hashed_password + + if self._password is not None and self._password != "" and self._hashed_password is not None and self._hashed_password != "": + self.logger.warning("BackendServer: Both 'password' and 'hashed_password' given. Ignoring 'password' and using 'hashed_password'!") + self._password = None + + if self._password is not None and self._password != "" and (self._hashed_password is None or self._hashed_password == ""): + self.logger.warning("BackendServer: Giving plaintext password in configuration is insecure. Consider using 'hashed_password' instead!") + self._hashed_password = None + + if (self._password is not None and self._password != "") or (self._hashed_password is not None and self._hashed_password != ""): + self._basic_auth = True + else: + self._basic_auth = False + self._sh = sh + + if self.is_int(port): + self.port = int(port) + else: + self.port = 8383 + if port is not None: + self.logger.error("BackendServer: Invalid value '"+str(port)+"' configured for attribute 'port' in plugin.conf, using '"+str(self.port)+"' instead") + + if self.is_int(threads): + self.threads = int(threads) + else: + self.threads = 8 + self.logger.error("BackendServer: Invalid value '"+str(threads)+"' configured for attribute 'thread' in plugin.conf, using '"+str(self.threads)+"' instead") + + if ip == '': + ip = self.get_local_ip_address() + self.logger.debug("BackendServer: Using local ip address '{0}'".format(ip)) + else: + pass + # if not self.is_ip(ip): + # self.logger.error("BackendServer: Invalid value '"+str(ip)+"' configured for attribute ip in plugin.conf, using '"+str('0.0.0.0')+"' instead") + # ip = '0.0.0.0' + language = language.lower() + if language != '': + if not load_translation(language): + self.logger.warning("BackendServer: Language '{0}' not found, using standard language instead".format(language)) + self.developer_mode = self.my_to_bool(developer_mode, 'developer_mode', False) + + self.updates_allowed = self.my_to_bool(updates_allowed, 'updates_allowed', True) + + if self.is_int(pypi_timeout): + self.pypi_timeout = int(pypi_timeout) + else: + self.pypi_timeout = 5 + if pypi_timeout is not None: + self.logger.error("BackendServer: Invalid value '" + str(pypi_timeout) + "' configured for attribute 'pypi_timeout' in plugin.conf, using '" + str(self.pypi_timeout) + "' instead") + + current_dir = os.path.dirname(os.path.abspath(__file__)) + self.logger.debug("BackendServer running from '{}'".format(current_dir)) + + config = {'global': { + 'engine.autoreload.on': False, + 'tools.staticdir.debug': True, + 'tools.trailing_slash.on': False, + 'log.screen': False + }, + '/': { + 'tools.auth_basic.on': self._basic_auth, + 'tools.auth_basic.realm': 'earth', + 'tools.auth_basic.checkpassword': self.validate_password, + 'tools.staticdir.root': current_dir, + }, + '/static': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': os.path.join(current_dir, 'static') + } + } + from cherrypy._cpserver import Server + self._server = Server() + self._server.socket_host = ip + self._server.socket_port = int(self.port) + self._server.thread_pool = self.threads + self._server.subscribe() + + self._cherrypy = cherrypy + self._cherrypy.config.update(config) + self._cherrypy.tree.mount(Backend(self, self.updates_allowed, language, self.developer_mode, self.pypi_timeout), '/', config = config) + + def run(self): + self.logger.debug("BackendServer: rest run") + self._server.start() + #self._cherrypy.engine.start() + self.logger.debug("BackendServer: engine started") + #cherrypy.engine.block() + self.alive = True + + def stop(self): + self.logger.debug("BackendServer: shutting down") + self._server.stop() + #self._cherrypy.engine.exit() + self.logger.debug("BackendServer: engine exited") + self.alive = False + + def parse_item(self, item): + pass + + def parse_logic(self, logic): + pass + + def update_item(self, item, caller=None, source=None, dest=None): + pass + + def validate_password(self, realm, username, password): + if username != self._user or password is None or password == "": + return False + + if self._hashed_password is not None: + return Utils.check_hashed_password(password, self._hashed_password) + elif self._password is not None: + return password == self._password + + return False + + + +class Backend(BackendCore, BackendBlocklyLogics): + env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__))+'/templates')) + env.globals['get_basename'] = get_basename + env.globals['is_userlogic'] = is_userlogic + env.globals['_'] = translate + + def __init__(self, backendserver=None, updates_allowed=True, language='', developer_mode=False, pypi_timeout = 5): + self.logger = logging.getLogger(__name__) + self._bs = backendserver + self._sh = backendserver._sh + self.language = language + self.updates_allowed = updates_allowed + self.developer_mode = developer_mode + self.pypi_timeout = pypi_timeout + + self._sh_dir = self._sh.base_dir + self.visu_plugin = None + self.visu_plugin_version = '1.0.0' + + def html_escape(self, str): + return html_escape(str) + + +#if __name__ == "__main__": +# server = BackendServer( None, port=8080, ip='0.0.0.0') +# server.run() diff --git a/backend/_pv_1_3_5/locale/de.json b/backend/_pv_1_3_5/locale/de.json new file mode 100755 index 000000000..7124515ad --- /dev/null +++ b/backend/_pv_1_3_5/locale/de.json @@ -0,0 +1,194 @@ +{ + "Scheduler": "Scheduler", + "Logik": "Logik", + "Systemlogiken": "Systemlogiken", + "Neue Logiken (nicht geladen)": "Neue Logiken (nicht geladen)", + "nächste Ausführung": "nächste Ausführung", + "Cycle": "Cycle", + "Crontab": "Crontab", + "Dateiname": "Dateiname", + "Aktionen": "Aktionen", + "Items": "Items", + "Item": "Item", + "gesamt": "gesamt", + "Suchen": "Suchen", + "Suche zurücksetzen": "Zurücksetzen", + "Alle aufklappen": "Alle aufklappen", + "Alle zuklappen": "Alle zuklappen", + "Itempfad suchen...": "Itempfad suchen...", + "Item im Baum auswählen um Details einzusehen!": "Item im Baum auswählen um Details einzusehen!", + "Item-Informationen": "Item-Informationen", + "Attribut": "Attribut", + "Wert": "Wert", + "Pfad": "Pfad", + "Name": "Name", + "Typ": "Typ", + + "Änderungsinformationen": "Änderungsinformationen", + "Letztes Update": "Letztes Update", + "Letzte Änderung": "Letzte Änderung", + "Geändert durch": "Geändert durch", + "age": "Alter", + "vorheriger Wert": "vorheriger Wert", + "previous change": "vorherige Änderung", + "previous age": "vorheriges Alter", + + "Evaluation und Trigger": "Initialisierungs-, Evaluations- und Trigger-Konfiguration", + "Plugin spezifische Attribute": "Plugin spezifische Konfigurationen", + "Verbundene Logiken": "Verbundene Logiken", + "Verbundene Trigger": "Verbundene Trigger", + "Willkommen im Backend von": "Willkommen im Backend von", + "Eigenschaft": "Eigenschaft", + "IP": "IP Adresse", + "Betriebssystem": "Betriebssystem", + "Architektur": "Architektur", + "Benutzer": "Benutzer", + "Freier Speicher": "Freier Speicher", + "Datum": "Datum", + "Zeit": "Zeit", + "Tag": "Tag", + "Tage": "Tage", + "Stunde": "Stunde", + "Stunden": "Stunden", + "Minute": "Minute", + "Minuten": "Minuten", + "Sekunden": "Sekunden", + "Betriebszeit": "Betriebszeit", + "Python Version": "Python Version", + "in": "in", + "installierte Version": "installierte Version", + "Neuste Version": "Neuste Version", + "Keine Antwort von PyPI": "Keine Antwort von PyPI", + "PyPI nicht erreichbar": "PyPI nicht erreichbar", + "PyPI Prüfung deaktiviert": "PyPI Prüfung deaktiviert", + "Dienst": "Dienst", + "Status": "Status", + "Aktion": "Aktion", + "Root-Passwort": "Root-Passwort", + "Neu starten": "System neu starten", + "Dienst für die KNX Unterstützung": "Dienst für die KNX Unterstützung", + "Nicht aktiv": "Nicht aktiv", + "Sprache des Backends": "Sprache des Backends", + "Logfile speichern": "Logfile speichern", + "Logfile ansehen": "Logfile ansehen", + "Logger ansehen": "Logger ansehen", + "Datenbank-Dump": "Datenbank-Dump", + "Übersetzung neu laden": "Übersetzung neu laden", + "Auf Deutsch wechseln": "Auf Deutsch wechseln", + "Auf Englisch wechseln": "Auf Englisch wechseln", + "Auf Französisch wechseln": "Auf Französisch wechseln", + "Auf Polnisch wechseln": "Auf Polnisch wechseln", + "Nr.": "Nr.", + "Type": "Type", + "Plugin": "Plugin", + "Classname": "Classname", + "Instanz": "Instanz", + "Version": "Version", + "Mehrere Instanzen möglich": "Mehrere Instanzen möglich", + "Ja": "Ja", + "Nein": "Nein", + "Thread": "Thread", + "Thread-Id": "Thread-Id", + "Aktiv": "Aktiv", + "Visu Client": "Visu Client", + "Port": "Port", + "Client Software": "Client Software", + "Browser": "Browser", + "No active clients": "Keine aktiven Clients", + "Die eingegebenen Daten sind kein numerischer Wert": "Die eingegebenen Daten sind kein numerischer Wert", + "Filter": "Filter", + "Logfile": "Log-Datei", + "Dateien ohne zugehöriges Item im /var/cache Verzeichnis": "Dateien ohne zugehöriges Item im /var/cache Verzeichnis", + "Letzte Modifikation": "Letzte Modifikation", + "Erstellungsdatum": "Erstellungsdatum", + "no data available": "keine Daten verfügbar", + "logger name": "Logger Name", + "disabled": "disabled", + "level": "Level", + "filters": "Filter(s)", + "handlers": "Handler(s)", + "logfiles": "Logfile(s)", + "Logging": "Logging", + "Passwort anzeigen": "Passwort anzeigen", + "SmartHomeNG Version": "SmartHomeNG Version", + "Watch_Items": "Watch_Items", + "Anforderungen": "Anforderungen", + "Übersicht": "Übersicht", + "Eingabe im .CONF Format": "Eingabe im .CONF Format", + "Ergebnis im .YAML Format": "Ergebnis im .YAML Format", + + + "_items": { + "path": "Pfad", + "name": "Name", + "type": "Typ (type)", + "value": "Wert (value)", + "cache": "cache", + "enforce_updates": "enforce_updates", + "eval": "eval", + "eval_trigger": "eval_trigger", + "cycle": "cycle", + "crontab": "crontab", + "autotimer": "autotimer", + "threshold": "threshold" + }, + + "_threads": { + "True": "Ja", + "False": "Nein" + }, + + "_disclosure": { + "Lizenz": "Lizenz", + "Link": "Link", + "Name": "Name", + "disclosure_title": "Offenlegung von Open Source Software Komponenten des SmartHomeNG BackendServer Plugins", + "Verwendete Open Source Software Komponenten": "Verwendete Open Source Software Komponenten", + "Icons/Bilder": "Icons/Bilder", + "Alle Icons und Bilder kommen von": "Alle Icons und Bilder kommen von " + }, + + "_button": { + "smarthomeNG starten": "SmartHomeNG starten", + "knxd service starten": "knxd service starten", + "knxd socket starten": "knxd socket starten", + "smarthomeNG beenden": "SmartHomeNG beenden", + "knxd service beenden": "knxd service beenden", + "knxd socket beenden": "knxd socket beenden", + "Filter anwenden": "Filter anwenden", + "Cacheprüfung": "Cacheprüfung", + "Passwort-Hash erzeugen": "Passwort-Hash erzeugen", + "Englisch": "English", + "Deutsch": "Deutsch", + "Französisch": "French", + "Polnisch": "Polish", + "Auslösen": "Auslösen", + "Neu Laden": "Neu Laden", + "Deaktivieren": "Deaktivieren", + "Aktivieren": "Aktivieren", + "Hinzufügen": "Hinzufügen", + "Leeren" : "Leeren", + "Schließen": "Schließen", + "Änderungen verwerfen" : "Änderungen verwerfen", + "Blöcke speichern" : "Blöcke speichern", + "Beenden" : "Beenden", + "Speichern" : "Speichern", + "Speichern_und_Neu_Laden" : "Speichern und neu laden", + "Löschen" : "Löschen", + "Konvertieren": "Konvertieren" + }, + + "_menu": { + "Systeminfo": "Systeminfo", + "Dienste": "Dienste", + "CONF-YAML Konverter": "CONF-YAML Konverter", + "Items": "Items", + "Logiken": "Logiken", + "Blockly-Logiken-Editor": "Blockly-Logiken-Editor", + "Scheduler": "Scheduler", + "Plugins": "Plugins", + "Threads": "Threads", + "Visu": "Visu", + "Disclosure": "Disclosure" + } +} diff --git a/backend/_pv_1_3_5/locale/en.json b/backend/_pv_1_3_5/locale/en.json new file mode 100755 index 000000000..2758acf9e --- /dev/null +++ b/backend/_pv_1_3_5/locale/en.json @@ -0,0 +1,192 @@ +{ + "Scheduler": "Scheduler", + "Logik": "Logic", + "Systemlogiken": "System Logics", + "nächste Ausführung": "next execution", + "Cycle": "Cycle", + "Crontab": "Crontab", + "Dateiname": "Filename", + "Aktionen": "Actions", + "Items": "Items", + "Item": "Item", + "gesamt": "total", + "Suchen": "Search", + "Suche zurücksetzen": "Reset search", + "Alle aufklappen": "Unfold All", + "Alle zuklappen": "Fold All", + "Itempfad suchen...": "Search Itempath...", + "Item im Baum auswählen um Details einzusehen!": "Select item in tree to see details!", + "Item-Informationen": "Item Information", + "Attribut": "attribute", + "Wert": "value", + "Pfad": "path", + "Name": "name", + "Typ": "type", + + "Änderungsinformationen": "Information about changes", + "Letztes Update": "last update", + "Letzte Änderung": "last change", + "Geändert durch": "changed by", + "age": "age", + "vorheriger Wert": "previous value", + "previous change": "previous change", + "previous age": "previous age", + + "Evaluation und Trigger": "Initialization, Evaluation and Trigger Configuration", + "Plugin spezifische Attribute": "Plugin specific configurations", + "Verbundene Logiken": "Bound Logics", + "Verbundene Trigger": "Bound Triggers", + "Willkommen im Backend von": "Welcome to the backend of", + "Eigenschaft": "Property", + "IP": "IP Address", + "Betriebssystem": "Operating System", + "Architektur": "Architecture", + "Benutzer": "User", + "Freier Speicher": "Free disk space", + "Datum": "Date", + "Zeit": "Time", + "Tag": "day", + "Tage": "days", + "Stunde": "hour", + "Stunden": "hours", + "Minute": "minute", + "Minuten": "minutes", + "Sekunden": "seconds", + "Betriebszeit": "Uptime", + "Python Version": "Python Version", + "in": "in", + "installierte Version": "installed Version", + "Neuste Version": "Newest Version", + "Keine Antwort von PyPI": "No answer from PyPI", + "PyPI nicht erreichbar": "PyPI inaccessible", + "PyPI Prüfung deaktiviert": "PyPI check disabled", + "Dienst": "Service", + "Status": "Status", + "Aktion": "Action", + "Root-Passwort": "root password", + "Neu starten": "Restart system", + "Dienst für die KNX Unterstützung": "Service for KNX support", + "Nicht aktiv": "Not active", + "Sprache des Backends": "Language of Backend", + "Logfile speichern": "Save logfile", + "Logfile ansehen": "View logfile", + "Logger ansehen": "View loggers", + "Datenbank-Dump": "Dump database", + "Übersetzung neu laden": "Reload translation", + "Auf Deutsch wechseln": "Switch to German", + "Auf Englisch wechseln": "Switch to English", + "Auf Französisch wechseln": "Switch to French", + "Auf Polnisch wechseln": "Switch to Polish", + "Nr.": "No.", + "Type": "Type", + "Plugin": "Plugin", + "Classname": "Classname", + "Instanz": "Instance", + "Version": "Version", + "Mehrere Instanzen möglich": "Multiple Instances possible", + "Ja": "Yes", + "Nein": "No", + "Thread": "Thread", + "Thread-Id": "Thread-Id", + "Aktiv": "Active", + "Visu Client": "Visu Client", + "Port": "Port", + "Client Software": "Client Software", + "Browser": "Browser", + "No active clients": "No active clients", + "Die eingegebenen Daten sind kein numerischer Wert": "Die eingegebenen Daten sind kein numerischer Wert", + "Filter": "Filter", + "Logfile": "Logfile", + "Dateien ohne zugehöriges Item im /var/cache Verzeichnis": "Files without corresponding item in /var/cache folder", + "Letzte Modifikation": "Last Modification", + "Erstellungsdatum": "Created", + "no data available": "no data available", + "logger name": "Logger Name", + "disabled": "Disabled", + "level": "Level", + "filters": "Filter(s)", + "handlers": "Handler(s)", + "logfiles": "Logfile(s)", + "Logging": "Logging", + "Passwort anzeigen": "Show Password", + "SmartHomeNG Version": "SmartHomeNG Version", + "Watch_Items": "Watch_Items", + "Anforderungen": "Requirements", + "Übersicht": "Overview", + "Eingabe im .CONF Format": "Input in .CONF format", + "Ergebnis im .YAML Format": "Result in .YAML format", + + "_items": { + "path": "Pfad", + "name": "name", + "type": "type", + "value": "value", + "cache": "cache", + "enforce_updates": "enforce_updates", + "eval": "eval", + "eval_trigger": "eval_trigger", + "cycle": "cycle", + "crontab": "crontab", + "autotimer": "autotimer", + "threshold": "threshold" + }, + + "_threads": { + "True": "Yes", + "False": "No" + }, + + + "_disclosure": { + "Lizenz": "License", + "Link": "Link", + "Name": "Name", + "disclosure_title": "Disclosure of Open Source Software Components deployed in SmartHomeNG BackendServer Plugin", + "Verwendete Open Source Software Komponenten": "Open Source Software Components used for the Plugin", + "Icons/Bilder": "Icons/Images", + "Alle Icons und Bilder kommen von": "All icons and images are taken from " + }, + + "_button": { + "Auslösen": "Trigger", + "Neu Laden": "Reload", + "smarthomeNG starten": "Start SmartHomeNG", + "knxd service starten": "Start knxd service", + "knxd socket starten": "Start knxd socket", + "smarthomeNG beenden": "Stop SmartHomeNG", + "knxd service beenden": "Stop knxd service", + "knxd socket beenden": "Stop knxd socket", + "Filter anwenden": "Apply Filter", + "Cacheprüfung": "Cache Check", + "Passwort-Hash erzeugen": "Create Password Hash", + "Englisch": "English", + "Deutsch": "Deutsch", + "Französisch": "French", + "Polnisch": "Polish", + "Deaktivieren": "Disable", + "Aktivieren": "Enable", + "Leeren" : "Clear", + "Schließen": "Close", + "Änderungen verwerfen" : "Undo Changes", + "Blöcke speichern" : "Save Blocks", + "Beenden" : "Stop", + "Speichern" : "Save", + "Speichern_und_Neu_Laden" : "Save and Reload", + "Löschen" : "Delete", + "Konvertieren": "Convert" + }, + + "_menu": { + "Systeminfo": "Systeminfo", + "Dienste": "Services", + "Items": "Items", + "Logiken": "Logics", + "Blockly-Logiken-Editor": "Blockly Logics Editor", + "Scheduler": "Scheduler", + "Plugins": "Plugins", + "Threads": "Threads", + "Visu": "Visu", + "Disclosure": "Disclosure", + "CONF-YAML Konverter": "CONF-YAML Converter" + } +} diff --git a/backend/_pv_1_3_5/locale/fr.json b/backend/_pv_1_3_5/locale/fr.json new file mode 100755 index 000000000..a4a6acdff --- /dev/null +++ b/backend/_pv_1_3_5/locale/fr.json @@ -0,0 +1,221 @@ +{ + "Scheduler": "Planificateur", + "Logik": "Logique", + "Systemlogiken": "Logiques système", + "Nutzerlogiken": "Logiques utilisateur", + "Neue Logiken (nicht geladen)": "Nouvelles logiques (non encore chargées)", + "nächste Ausführung": "Prochaine exécution", + "Cycle": "Cycle", + "Crontab": "Crontab", + "Crontab(s)": "Crontab(s)", + "Dateiname": "Nom du fichier", + "Aktionen": "Actions", + "Items": "Objets", + "Item": "Objet", + "gesamt": "total", + "Suchen": "Chercher", + "Suche zurücksetzen": "Réinitialiser", + "Alle aufklappen": "Montrer tout", + "Alle zuklappen": "Cacher tout", + "Itempfad suchen...": "Chercher chemin...", + "Item im Baum auswählen um Details einzusehen!": "Choisir un objet dans l'arborescence pour afficher les détails!", + "Item-Informationen": "Informations sur l'objet", + "Attribut": "Attribut", + "Wert": "Valeur", + "Pfad": "Chemin", + "Name": "Nom", + "Typ": "Type", + + "Änderungsinformationen": "Informations sur les modifications", + "Letztes Update": "Dernière mise à jour", + "Letzte Änderung": "Dernière modification", + "Geändert durch": "Modifié par", + "age": "Âge", + "aktueller": "actuel", + "vorheriger": "précédent", + "vorheriger Wert": "Valeur précédente", + "previous change": "Modification précédente", + "previous age": "Âge précédent", + + "Evaluation und Trigger": "Configuration de l'initialisation, de l'évaluation et des déclencheurs", + "Plugin spezifische Attribute": "Attributs spécifiques à l'extension", + "Plugin Metadaten": "Métadonnées de l'extension", + "Verbundene Logiken": "Logiques connexes", + "Verbundene Trigger": "Déclencheurs connexes", + "Willkommen im Backend von": "Bienvenue au Backend de", + "Eigenschaft": "Propriété", + "IP": "Adresse IP", + "Betriebssystem": "Système d'exploitation", + "Architektur": "Architecture", + "Benutzer": "Utilisateur", + "Freier Speicher": "Mémoire libre", + "Datum": "Date", + "Zeit": "Heure", + "Tag": "jour", + "Tage": "jours", + "Stunde": "heure", + "Stunden": "heures", + "Minute": "minute", + "Minuten": "minutes", + "Sekunden": "secondes", + "Betriebszeit": "Temps en service", + "Python Version": "Version Python", + "in": "dans", + "installierte Version": "Version installée", + "Neuste Version": "Dernière version", + "Keine Antwort von PyPI": "Pas de réponse de PyPI", + "PyPI nicht erreichbar": "PyPI non accessible", + "PyPI Prüfung deaktiviert": "Vérification PyPI désactivée", + "Dienst": "Service", + "Status": "Etat", + "Aktion": "Action", + "Root-Passwort": "Mot de passe 'root'", + "Neu starten": "Redémarrer le système", + "Dienst für die KNX Unterstützung": "Service pour le support du KNX", + "Nicht aktiv": "Inactif", + "Sprache des Backends": "Langue du backend", + "Logfile speichern": "Sauvegarder fichier journal", + "Logfile ansehen": "Afficher journal", + "Logger ansehen": "Afficher journalisateurs", + "Datenbank-Dump": "Dump de la base de données", + "Übersetzung neu laden": "Recharger traduction", + "Auf Deutsch wechseln": "Basculer vers l'allemand", + "Auf Englisch wechseln": "Basculer vers l'anglais", + "Auf Polnisch wechseln": "Basculer vers le polonais", + "Nr.": "N°", + "Type": "Type", + "Plugin": "Extension", + "Classname": "Nom de la classe", + "Instanz": "Instance", + "Version": "Version", + "Mehrere Instanzen möglich": "Supporte plusieurs instances", + "Ja": "Oui", + "Nein": "Non", + "Thread": "Tâche", + "Thread-Id": "Id de tâche", + "Aktiv": "Active", + "Visu Client": "Client Visu", + "Port": "Port", + "Client Software": "Logiciel client", + "Browser": "Navigateur", + "No active clients": "Pas de clients actifs", + "Die eingegebenen Daten sind kein numerischer Wert": "Les valeurs entrées ne sont pas numériques", + "Filter": "Filtre", + "Logfile": "Fichier log", + "Dateien ohne zugehöriges Item im /var/cache Verzeichnis": "Fichiers dans le répertoire /var/cache sans objet associé", + "Letzte Modifikation": "Dernière modification", + "Erstellungsdatum": "Date de création", + "no data available": "pas de données disponibles", + "logger name": "Nom du journalisateur", + "disabled": "Désactivé", + "level": "Niveau", + "filters": "Filtres", + "handlers": "Gestionnaire", + "logfiles": "Fichier(s) journal", + "Logging": "Journalisation", + "Passwort anzeigen": "Afficher mot de passe", + "SmartHomeNG Version": "Version de SmartHomeNG", + "Watch_Items": "Objets surveillés", + "Watch_Item(s)": "Objet(s) surveillé(s)", + "Anforderungen": "Version demandée", + "Übersicht": "Aperçu", + "Eingabe im .CONF Format": "Entrée en format .CONF", + "Ergebnis im .YAML Format": "Résultat en format .YAML", + "Wartung": "Maintenance", + "Tester": "Testeur", + "Beschreibung": "Description", + "Documentation": "Documentation", + "Support": "Support", + "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.": "Appuyez F11 si le curseur est dans la fenêtre de l'éditeur pour passer en mode plein-écran. Appuyez F11 ou ESC pour sortir du mode plein-écran.", + "Zeilenumbruch" : "Coupure de ligne", + "Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.": "Appuyez ctrl-espace pour activer le complètement automatique des commandes Python. Appuyez ctrl-i pour activer le complètement automatique des chemins des objets.", + "Hilfe": "Aide", + "help_search_1": "Ctrl-F / Cmd-F: Démarrer la recherche", + "help_search_2": "Ctrl-G / Cmd-G: Prochain résultat", + "help_search_3": "Shift-Ctrl-G / Shift-Cmd-G: Résultat précédent", + "help_search_4": "Shift-Ctrl-F / Cmd-Option-F: Remplacer", + "help_search_5": "Shift-Ctrl-R / Shift-Cmd-Option-F: Remplacer tout", + "help_search_6": "Alt-F: Recherche persistente (dialogue ne se ferme pas, pour prochain résultat, Shift-Entrée pour résultat précédent)", + "help_search_7": "Alt-G: Sauter vers ligne", + "Suche": "Chercher", + "Hilfslinien": "Lignes de séparation", + "PyPI Check": "Vérification PyPI", + "Systemeigenschaften": "Propriétés du système", + "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!": "Si vous ne sauvegardez pas vous perdez toutes modifications!", + + "_items": { + "path": "Chemin", + "name": "Nom", + "type": "Type (type)", + "value": "Valeur (value)", + "cache": "cache", + "enforce_updates": "enforce_updates", + "eval": "eval", + "eval_trigger": "eval_trigger", + "cycle": "cycle", + "crontab": "crontab", + "autotimer": "autotimer", + "threshold": "threshold" + }, + + "_threads": { + "True": "Oui", + "False": "Non" + }, + + "_disclosure": { + "Lizenz": "Licence", + "Link": "Lien", + "Name": "Nom", + "disclosure_title": "Déclaration des composantes Open Source utilisées dans le serveur Backend de SmartHomeNG", + "Verwendete Open Source Software Komponenten": "Composantes Open Source utilisées", + "Icons/Bilder": "Icônes/Images", + "Alle Icons und Bilder kommen von": "Toutes les images et icônes parviennent de" + }, + + "_button": { + "Auslösen": "Déclencher", + "Neu Laden": "Recharger", + "smarthomeNG starten": "démarrer SmartHomeNG", + "knxd service starten": "démarrer service knxd", + "knxd socket starten": "démarrer socket knxd", + "smarthomeNG beenden": "arrêter SmartHomeNG", + "knxd service beenden": "arrêter service knxd", + "knxd socket beenden": "arrêter socket knxd", + "Filter anwenden": "Appliquer le filtre", + "Cacheprüfung": "Test du cache", + "Passwort-Hash erzeugen": "Mot de passe créer hachage", + "Englisch": "Anglais", + "Deutsch": "Allemand", + "Französisch": "Français", + "Polnisch": "Polonais", + "Deaktivieren": "Désactiver", + "Aktivieren": "Activer", + "Hinzufügen": "Ajouter", + "Leeren" : "Vider", + "Schließen": "Fermer", + "Änderungen verwerfen" : "Annuler modifications", + "Blöcke speichern" : "Enregistrer les blocs", + "Beenden" : "Terminer", + "Speichern" : "Sauvegarder", + "Speichern_und_Neu_Laden" : "Sauvegarder et recharger", + "Speichern_Neu_Laden_und_Triggern": "Sauvegarder, recharger et déclencher", + "Löschen" : "Supprimer", + "Konvertieren": "Convertir", + "Neue Blockly Logik": "Nouvelle logique 'Blockly'" + }, + + "_menu": { + "Systeminfo": "Info système", + "Dienste": "Services", + "Items": "Objets", + "Logiken": "Logiques", + "Blockly-Logiken-Editor": "Blockly - Editeur de Logiques", + "Scheduler": "Planificateur", + "Plugins": "Extensions", + "Threads": "Tâches", + "Visu": "Visu", + "Disclosure": "Déclaration", + "CONF-YAML Konverter": "Convertisseur .conf vers .yaml" + } +} diff --git a/backend/_pv_1_3_5/locale/pl.json b/backend/_pv_1_3_5/locale/pl.json new file mode 100755 index 000000000..0a23e96e7 --- /dev/null +++ b/backend/_pv_1_3_5/locale/pl.json @@ -0,0 +1,191 @@ +{ + "Scheduler": "Planista", + "Logik": "Logika", + "Systemlogiken": "Logika systemowa", + "nächste Ausführung": "Następne wykonanie", + "Cycle": "Cykl", + "Crontab": "Harmonogram", + "Dateiname": "Nazwa pliku", + "Aktionen": "Akcje", + "Items": "Itemy", + "Item": "Item", + "gesamt": "w sumie", + "Suchen": "Szukaj", + "Suche zurücksetzen": "Reset wyszukiwania", + "Alle aufklappen": "Rozwiń wszystko", + "Alle zuklappen": "Zwiń wszystko", + "Itempfad suchen...": "Szukaj Itemów...", + "Item im Baum auswählen um Details einzusehen!": "Wybierz Item aby zobaczyć szczegóły!", + "Item-Informationen": "Informacje o Itemie", + "Attribut": "atrybut", + "Wert": "wartość", + "Pfad": "ścieżka", + "Name": "nazwa", + "Typ": "typ", + + "Änderungsinformationen": "Inormacje o zmianach", + "Letztes Update": "ostatnia aktualizacja", + "Letzte Änderung": "ostatnia zmiana", + "Geändert durch": "zmieniono przez", + "age": "czas aktualnej wartości", + "vorheriger Wert": "poprzednia wartość", + "previous change": "poprzednia zmiana", + "previous age": "czas poprzedniej wartości", + + "Evaluation und Trigger": "Inicjalizacja, ewaluacja i wyzwalacze", + "Plugin spezifische Attribute": "Konfiguracja pluginów", + "Verbundene Logiken": "Powiązana Logika", + "Verbundene Trigger": "Powiązane wyzwalacze", + "Willkommen im Backend von": "Witaj w backendzie", + "Eigenschaft": "Atrybut", + "IP": "Adres IP", + "Betriebssystem": "System operacyjny", + "Architektur": "Architektura", + "Benutzer": "Użytkownik", + "Freier Speicher": "Wolne miejsce", + "Datum": "Data", + "Zeit": "Czas", + "Tag": "dzień", + "Tage": "dni", + "Stunde": "godzina", + "Stunden": "godzin", + "Minute": "minuta", + "Minuten": "minut", + "Sekunden": "sekund", + "Betriebszeit": "Czas pracy", + "Python Version": "Wersja Pythona", + "installierte Version": "Zainstalowana wersja", + "Neuste Version": "Najnowsza wersja", + "Keine Antwort von PyPI": "Brak odpowiedzi z PyPI", + "PyPI nicht erreichbar": "PyPI niedostępne", + "PyPI Prüfung deaktiviert": "sprawdzanie PyPI wyłączone", + "Dienst": "Usługa", + "Status": "Status", + "Aktion": "Akcja", + "Root-Passwort": "Hasło roota", + "Neu starten": "Restart systemu", + "Dienst für die KNX Unterstützung": "Usługa KNX", + "Nicht aktiv": "Nieaktywne", + "Sprache des Backends": "Język", + "Logfile speichern": "Zapisz log", + "Logfile ansehen": "Przeglądaj log", + "Logger ansehen": "Przeglądaj loggery", + "Datenbank-Dump": "Pobierz bazę danych", + "Übersetzung neu laden": "Przeładuj tłumaczenie", + "Auf Deutsch wechseln": "Przełącz na nimiecki", + "Auf Englisch wechseln": "Przełącz na angielski", + "Auf Französisch wechseln": "Przełącz na francuski", + "Auf Polnisch wechseln": "Przełącz na polski", + "Nr.": "Nr", + "Type": "Typ", + "Plugin": "Plugin", + "Classname": "Nazwa klasy", + "Instanz": "Instancja", + "Version": "Wersja", + "Mehrere Instanzen möglich": "Możliwe wiele instancji", + "Ja": "Tak", + "Nein": "Nie", + "Thread": "Wątki", + "Thread-Id": "Id Wątku", + "Aktiv": "Aktywny", + "Visu Client": "Klient Visu", + "Port": "Port", + "Client Software": "Oprogramowanie klienta", + "Browser": "Przeglądarka", + "No active clients": "Brak aktywnych klientów", + "Die eingegebenen Daten sind kein numerischer Wert": "Wprowadzona wartość nie jest liczbą", + "Filter": "Filtr", + "Logfile": "Log", + "Dateien ohne zugehöriges Item im /var/cache Verzeichnis": "Pliki w var/cache bez odpowiadającego im Itema", + "Letzte Modifikation": "Ostatnia modyfikacja", + "Erstellungsdatum": "Utworzono", + "no data available": "brak danych", + "logger lame": "Nazwa Loggera", + "disabled": "Wyłączony", + "level": "Poziom", + "filters": "Filtry", + "handlers": "Handlery", + "logfiles": "Log", + "Logging": "Logowanie", + "Passwort anzeigen": "pokaż", + "SmartHomeNG Version": "Wersja SmartHomeNG", + "Watch_Items": "Obserwowane Itemy", + "Anforderungen": "Wymagania", + "Übersicht": "Badanie", + "Eingabe im .CONF Format": "Eingabe im .CONF Format", + "Ergebnis im .YAML Format": "Ergebnis im .YAML Format" + + "_items": { + "path": "ścieżka", + "name": "nazwa", + "type": "typ", + "value": "wartość", + "cache": "pamięć podręczna", + "enforce_updates": "wymuszone aktualizacje", + "eval": "ewaluacja", + "eval_trigger": "wyzwalacze ewaluacji", + "cycle": "cykl", + "crontab": "harmonogram", + "autotimer": "autotimer", + "threshold": "próg" + }, + + "_threads": { + "True": "Tak", + "False": "Nie" + }, + + + "_disclosure": { + "Lizenz": "Licencja", + "Link": "Link", + "Name": "Nazwa", + "disclosure_title": "Deklaracja oprogramowania Open Source wykorzystanego w SmartHomeNG przez plugin 'backend'", + "Verwendete Open Source Software Komponenten": "Wykaz użytego oprogramowania Open Source", + "Icons/Bilder": "Ikony/Obrazy", + "Alle Icons und Bilder kommen von": "Wszystkie ikony i obrazy pochodzą z" + }, + + "_button": { + "Auslösen": "Uruchom", + "Neu Laden": "Przeładuj", + "smarthomeNG starten": "Start SmartHomeNG", + "knxd service starten": "Start usługi knxd", + "knxd socket starten": "Start socketa knxd", + "smarthomeNG beenden": "Stop SmartHomeNG", + "knxd service beenden": "Stop usługi knxd", + "knxd socket beenden": "Stop socketa knxd", + "Filter anwenden": "Zastosuj filtr", + "Cacheprüfung": "Sprawdź pamięć podręczną", + "Passwort-Hash erzeugen": "Utwórz zahashowane hasło", + "Englisch": "English", + "Deutsch": "Deutsch", + "Französisch": "French", + "Polnisch": "Polski", + "Deaktivieren": "Wyłącz", + "Aktivieren": "Włącz", + "Leeren" : "Wyczyść", + "Schließen": "Zamknij", + "Änderungen verwerfen" : "Cofnij Zmiany", + "Blöcke speichern" : "Zapisz Bloki", + "Beenden" : "Stop", + "Speichern" : "Zapisz", + "Speichern_und_Neu_Laden" : "Zapisz i przeładuj", + "Löschen" : "Skasuj" + "Konvertieren": "Konvertieren" + }, + + "_menu": { + "Systeminfo": "System", + "Dienste": "Usługi", + "Items": "Itemy", + "Logiken": "Logika", + "Blockly-Logiken-Editor": "Edytor logiki Blockly", + "Scheduler": "Planista", + "Plugins": "Pluginy", + "Threads": "Wątki", + "Visu": "Visu", + "Disclosure": "Deklaracja", + "CONF-YAML Konverter": "CONF-YAML Konverter" + } +} diff --git a/backend/_pv_1_3_5/plugin.yaml b/backend/_pv_1_3_5/plugin.yaml new file mode 100755 index 000000000..8164922bb --- /dev/null +++ b/backend/_pv_1_3_5/plugin.yaml @@ -0,0 +1,24 @@ +# Metadata for the Smart-Plugin +plugin: + # Global plugin attributes + type: system # plugin type (gateway, interface, protocol, system, web) + subtype: core # plugin subtype (if applicable) + description: # Alternative: description in multiple languages + de: 'Web Interface zur Anzeige von Informationen zum System und SmartHomeNG Backend-Daten' + en: 'webinterface for displaying system information and SmartHomeNG backend data' + maintainer: psilo909, msinn, bmxp + tester: Sandman60 +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md # url of documentation (wiki) page + + version: 1.3.5 # Plugin version + sh_minversion: 1.3 # minimum shNG version to use this plugin + sh_maxversion: 1.3a # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: False # plugin supports multi instance + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/backend/_pv_1_3_5/requirements.txt b/backend/_pv_1_3_5/requirements.txt new file mode 100755 index 000000000..f66c2e57b --- /dev/null +++ b/backend/_pv_1_3_5/requirements.txt @@ -0,0 +1,3 @@ +cherrypy>=8.1.2 +jinja2>=2.8 +python-dateutil>=2.5.3 \ No newline at end of file diff --git a/backend/static/blockly/CONTRIBUTING.md b/backend/_pv_1_3_5/static/blockly/CONTRIBUTING.md old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/CONTRIBUTING.md rename to backend/_pv_1_3_5/static/blockly/CONTRIBUTING.md diff --git a/backend/static/blockly/LICENSE b/backend/_pv_1_3_5/static/blockly/LICENSE old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/LICENSE rename to backend/_pv_1_3_5/static/blockly/LICENSE diff --git a/backend/static/blockly/README.md b/backend/_pv_1_3_5/static/blockly/README.md old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/README.md rename to backend/_pv_1_3_5/static/blockly/README.md diff --git a/backend/static/blockly/accessible/README b/backend/_pv_1_3_5/static/blockly/accessible/README old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/README rename to backend/_pv_1_3_5/static/blockly/accessible/README diff --git a/backend/static/blockly/accessible/app.component.js b/backend/_pv_1_3_5/static/blockly/accessible/app.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/app.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/app.component.js diff --git a/backend/static/blockly/accessible/audio.service.js b/backend/_pv_1_3_5/static/blockly/accessible/audio.service.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/audio.service.js rename to backend/_pv_1_3_5/static/blockly/accessible/audio.service.js diff --git a/backend/static/blockly/accessible/clipboard.service.js b/backend/_pv_1_3_5/static/blockly/accessible/clipboard.service.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/clipboard.service.js rename to backend/_pv_1_3_5/static/blockly/accessible/clipboard.service.js diff --git a/backend/static/blockly/accessible/field.component.js b/backend/_pv_1_3_5/static/blockly/accessible/field.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/field.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/field.component.js diff --git a/backend/static/blockly/accessible/libs/Rx.umd.min.js b/backend/_pv_1_3_5/static/blockly/accessible/libs/Rx.umd.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/libs/Rx.umd.min.js rename to backend/_pv_1_3_5/static/blockly/accessible/libs/Rx.umd.min.js diff --git a/backend/static/blockly/accessible/libs/angular2-all.umd.min.js b/backend/_pv_1_3_5/static/blockly/accessible/libs/angular2-all.umd.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/libs/angular2-all.umd.min.js rename to backend/_pv_1_3_5/static/blockly/accessible/libs/angular2-all.umd.min.js diff --git a/backend/static/blockly/accessible/libs/angular2-polyfills.min.js b/backend/_pv_1_3_5/static/blockly/accessible/libs/angular2-polyfills.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/libs/angular2-polyfills.min.js rename to backend/_pv_1_3_5/static/blockly/accessible/libs/angular2-polyfills.min.js diff --git a/backend/static/blockly/accessible/libs/es6-shim.min.js b/backend/_pv_1_3_5/static/blockly/accessible/libs/es6-shim.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/libs/es6-shim.min.js rename to backend/_pv_1_3_5/static/blockly/accessible/libs/es6-shim.min.js diff --git a/backend/static/blockly/accessible/media/accessible.css b/backend/_pv_1_3_5/static/blockly/accessible/media/accessible.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/accessible.css rename to backend/_pv_1_3_5/static/blockly/accessible/media/accessible.css diff --git a/backend/static/blockly/accessible/media/click.mp3 b/backend/_pv_1_3_5/static/blockly/accessible/media/click.mp3 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/click.mp3 rename to backend/_pv_1_3_5/static/blockly/accessible/media/click.mp3 diff --git a/backend/static/blockly/accessible/media/click.ogg b/backend/_pv_1_3_5/static/blockly/accessible/media/click.ogg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/click.ogg rename to backend/_pv_1_3_5/static/blockly/accessible/media/click.ogg diff --git a/backend/static/blockly/accessible/media/click.wav b/backend/_pv_1_3_5/static/blockly/accessible/media/click.wav old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/click.wav rename to backend/_pv_1_3_5/static/blockly/accessible/media/click.wav diff --git a/backend/static/blockly/accessible/media/delete.mp3 b/backend/_pv_1_3_5/static/blockly/accessible/media/delete.mp3 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/delete.mp3 rename to backend/_pv_1_3_5/static/blockly/accessible/media/delete.mp3 diff --git a/backend/static/blockly/accessible/media/delete.ogg b/backend/_pv_1_3_5/static/blockly/accessible/media/delete.ogg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/delete.ogg rename to backend/_pv_1_3_5/static/blockly/accessible/media/delete.ogg diff --git a/backend/static/blockly/accessible/media/delete.wav b/backend/_pv_1_3_5/static/blockly/accessible/media/delete.wav old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/media/delete.wav rename to backend/_pv_1_3_5/static/blockly/accessible/media/delete.wav diff --git a/backend/static/blockly/accessible/messages.js b/backend/_pv_1_3_5/static/blockly/accessible/messages.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/messages.js rename to backend/_pv_1_3_5/static/blockly/accessible/messages.js diff --git a/backend/static/blockly/accessible/notifications.service.js b/backend/_pv_1_3_5/static/blockly/accessible/notifications.service.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/notifications.service.js rename to backend/_pv_1_3_5/static/blockly/accessible/notifications.service.js diff --git a/backend/static/blockly/accessible/toolbox-tree.component.js b/backend/_pv_1_3_5/static/blockly/accessible/toolbox-tree.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/toolbox-tree.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/toolbox-tree.component.js diff --git a/backend/static/blockly/accessible/toolbox.component.js b/backend/_pv_1_3_5/static/blockly/accessible/toolbox.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/toolbox.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/toolbox.component.js diff --git a/backend/static/blockly/accessible/translate.pipe.js b/backend/_pv_1_3_5/static/blockly/accessible/translate.pipe.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/translate.pipe.js rename to backend/_pv_1_3_5/static/blockly/accessible/translate.pipe.js diff --git a/backend/static/blockly/accessible/tree.service.js b/backend/_pv_1_3_5/static/blockly/accessible/tree.service.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/tree.service.js rename to backend/_pv_1_3_5/static/blockly/accessible/tree.service.js diff --git a/backend/static/blockly/accessible/utils.service.js b/backend/_pv_1_3_5/static/blockly/accessible/utils.service.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/utils.service.js rename to backend/_pv_1_3_5/static/blockly/accessible/utils.service.js diff --git a/backend/static/blockly/accessible/workspace-tree.component.js b/backend/_pv_1_3_5/static/blockly/accessible/workspace-tree.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/workspace-tree.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/workspace-tree.component.js diff --git a/backend/static/blockly/accessible/workspace.component.js b/backend/_pv_1_3_5/static/blockly/accessible/workspace.component.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/accessible/workspace.component.js rename to backend/_pv_1_3_5/static/blockly/accessible/workspace.component.js diff --git a/backend/static/blockly/blockly_compressed.js b/backend/_pv_1_3_5/static/blockly/blockly_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/blockly_compressed.js rename to backend/_pv_1_3_5/static/blockly/blockly_compressed.js diff --git a/backend/static/blockly/blockly_uncompressed.js b/backend/_pv_1_3_5/static/blockly/blockly_uncompressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/blockly_uncompressed.js rename to backend/_pv_1_3_5/static/blockly/blockly_uncompressed.js diff --git a/backend/static/blockly/blocks_compressed.js b/backend/_pv_1_3_5/static/blockly/blocks_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/blocks_compressed.js rename to backend/_pv_1_3_5/static/blockly/blocks_compressed.js diff --git a/backend/static/blockly/core/block.js b/backend/_pv_1_3_5/static/blockly/core/block.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/block.js rename to backend/_pv_1_3_5/static/blockly/core/block.js diff --git a/backend/static/blockly/core/block_render_svg.js b/backend/_pv_1_3_5/static/blockly/core/block_render_svg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/block_render_svg.js rename to backend/_pv_1_3_5/static/blockly/core/block_render_svg.js diff --git a/backend/static/blockly/core/block_svg.js b/backend/_pv_1_3_5/static/blockly/core/block_svg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/block_svg.js rename to backend/_pv_1_3_5/static/blockly/core/block_svg.js diff --git a/backend/static/blockly/core/blockly.js b/backend/_pv_1_3_5/static/blockly/core/blockly.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/blockly.js rename to backend/_pv_1_3_5/static/blockly/core/blockly.js diff --git a/backend/static/blockly/core/blocks.js b/backend/_pv_1_3_5/static/blockly/core/blocks.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/blocks.js rename to backend/_pv_1_3_5/static/blockly/core/blocks.js diff --git a/backend/static/blockly/core/bubble.js b/backend/_pv_1_3_5/static/blockly/core/bubble.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/bubble.js rename to backend/_pv_1_3_5/static/blockly/core/bubble.js diff --git a/backend/static/blockly/core/comment.js b/backend/_pv_1_3_5/static/blockly/core/comment.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/comment.js rename to backend/_pv_1_3_5/static/blockly/core/comment.js diff --git a/backend/static/blockly/core/connection.js b/backend/_pv_1_3_5/static/blockly/core/connection.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/connection.js rename to backend/_pv_1_3_5/static/blockly/core/connection.js diff --git a/backend/static/blockly/core/connection_db.js b/backend/_pv_1_3_5/static/blockly/core/connection_db.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/connection_db.js rename to backend/_pv_1_3_5/static/blockly/core/connection_db.js diff --git a/backend/static/blockly/core/constants.js b/backend/_pv_1_3_5/static/blockly/core/constants.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/constants.js rename to backend/_pv_1_3_5/static/blockly/core/constants.js diff --git a/backend/static/blockly/core/contextmenu.js b/backend/_pv_1_3_5/static/blockly/core/contextmenu.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/contextmenu.js rename to backend/_pv_1_3_5/static/blockly/core/contextmenu.js diff --git a/backend/static/blockly/core/css.js b/backend/_pv_1_3_5/static/blockly/core/css.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/css.js rename to backend/_pv_1_3_5/static/blockly/core/css.js diff --git a/backend/static/blockly/core/events.js b/backend/_pv_1_3_5/static/blockly/core/events.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/events.js rename to backend/_pv_1_3_5/static/blockly/core/events.js diff --git a/backend/static/blockly/core/field.js b/backend/_pv_1_3_5/static/blockly/core/field.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field.js rename to backend/_pv_1_3_5/static/blockly/core/field.js diff --git a/backend/static/blockly/core/field_angle.js b/backend/_pv_1_3_5/static/blockly/core/field_angle.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_angle.js rename to backend/_pv_1_3_5/static/blockly/core/field_angle.js diff --git a/backend/static/blockly/core/field_checkbox.js b/backend/_pv_1_3_5/static/blockly/core/field_checkbox.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_checkbox.js rename to backend/_pv_1_3_5/static/blockly/core/field_checkbox.js diff --git a/backend/static/blockly/core/field_colour.js b/backend/_pv_1_3_5/static/blockly/core/field_colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_colour.js rename to backend/_pv_1_3_5/static/blockly/core/field_colour.js diff --git a/backend/static/blockly/core/field_date.js b/backend/_pv_1_3_5/static/blockly/core/field_date.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_date.js rename to backend/_pv_1_3_5/static/blockly/core/field_date.js diff --git a/backend/static/blockly/core/field_dropdown.js b/backend/_pv_1_3_5/static/blockly/core/field_dropdown.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_dropdown.js rename to backend/_pv_1_3_5/static/blockly/core/field_dropdown.js diff --git a/backend/static/blockly/core/field_image.js b/backend/_pv_1_3_5/static/blockly/core/field_image.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_image.js rename to backend/_pv_1_3_5/static/blockly/core/field_image.js diff --git a/backend/static/blockly/core/field_label.js b/backend/_pv_1_3_5/static/blockly/core/field_label.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_label.js rename to backend/_pv_1_3_5/static/blockly/core/field_label.js diff --git a/backend/static/blockly/core/field_number.js b/backend/_pv_1_3_5/static/blockly/core/field_number.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_number.js rename to backend/_pv_1_3_5/static/blockly/core/field_number.js diff --git a/backend/static/blockly/core/field_textinput.js b/backend/_pv_1_3_5/static/blockly/core/field_textinput.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_textinput.js rename to backend/_pv_1_3_5/static/blockly/core/field_textinput.js diff --git a/backend/static/blockly/core/field_variable.js b/backend/_pv_1_3_5/static/blockly/core/field_variable.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/field_variable.js rename to backend/_pv_1_3_5/static/blockly/core/field_variable.js diff --git a/backend/static/blockly/core/flyout.js b/backend/_pv_1_3_5/static/blockly/core/flyout.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/flyout.js rename to backend/_pv_1_3_5/static/blockly/core/flyout.js diff --git a/backend/static/blockly/core/flyout_button.js b/backend/_pv_1_3_5/static/blockly/core/flyout_button.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/flyout_button.js rename to backend/_pv_1_3_5/static/blockly/core/flyout_button.js diff --git a/backend/static/blockly/core/generator.js b/backend/_pv_1_3_5/static/blockly/core/generator.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/generator.js rename to backend/_pv_1_3_5/static/blockly/core/generator.js diff --git a/backend/static/blockly/core/icon.js b/backend/_pv_1_3_5/static/blockly/core/icon.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/icon.js rename to backend/_pv_1_3_5/static/blockly/core/icon.js diff --git a/backend/static/blockly/core/inject.js b/backend/_pv_1_3_5/static/blockly/core/inject.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/inject.js rename to backend/_pv_1_3_5/static/blockly/core/inject.js diff --git a/backend/static/blockly/core/input.js b/backend/_pv_1_3_5/static/blockly/core/input.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/input.js rename to backend/_pv_1_3_5/static/blockly/core/input.js diff --git a/backend/static/blockly/core/msg.js b/backend/_pv_1_3_5/static/blockly/core/msg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/msg.js rename to backend/_pv_1_3_5/static/blockly/core/msg.js diff --git a/backend/static/blockly/core/mutator.js b/backend/_pv_1_3_5/static/blockly/core/mutator.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/mutator.js rename to backend/_pv_1_3_5/static/blockly/core/mutator.js diff --git a/backend/static/blockly/core/names.js b/backend/_pv_1_3_5/static/blockly/core/names.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/names.js rename to backend/_pv_1_3_5/static/blockly/core/names.js diff --git a/backend/static/blockly/core/options.js b/backend/_pv_1_3_5/static/blockly/core/options.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/options.js rename to backend/_pv_1_3_5/static/blockly/core/options.js diff --git a/backend/static/blockly/core/procedures.js b/backend/_pv_1_3_5/static/blockly/core/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/procedures.js rename to backend/_pv_1_3_5/static/blockly/core/procedures.js diff --git a/backend/static/blockly/core/rendered_connection.js b/backend/_pv_1_3_5/static/blockly/core/rendered_connection.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/rendered_connection.js rename to backend/_pv_1_3_5/static/blockly/core/rendered_connection.js diff --git a/backend/static/blockly/core/scrollbar.js b/backend/_pv_1_3_5/static/blockly/core/scrollbar.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/scrollbar.js rename to backend/_pv_1_3_5/static/blockly/core/scrollbar.js diff --git a/backend/static/blockly/core/toolbox.js b/backend/_pv_1_3_5/static/blockly/core/toolbox.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/toolbox.js rename to backend/_pv_1_3_5/static/blockly/core/toolbox.js diff --git a/backend/static/blockly/core/tooltip.js b/backend/_pv_1_3_5/static/blockly/core/tooltip.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/tooltip.js rename to backend/_pv_1_3_5/static/blockly/core/tooltip.js diff --git a/backend/static/blockly/core/trashcan.js b/backend/_pv_1_3_5/static/blockly/core/trashcan.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/trashcan.js rename to backend/_pv_1_3_5/static/blockly/core/trashcan.js diff --git a/backend/static/blockly/core/utils.js b/backend/_pv_1_3_5/static/blockly/core/utils.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/utils.js rename to backend/_pv_1_3_5/static/blockly/core/utils.js diff --git a/backend/static/blockly/core/variables.js b/backend/_pv_1_3_5/static/blockly/core/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/variables.js rename to backend/_pv_1_3_5/static/blockly/core/variables.js diff --git a/backend/static/blockly/core/warning.js b/backend/_pv_1_3_5/static/blockly/core/warning.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/warning.js rename to backend/_pv_1_3_5/static/blockly/core/warning.js diff --git a/backend/static/blockly/core/widgetdiv.js b/backend/_pv_1_3_5/static/blockly/core/widgetdiv.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/widgetdiv.js rename to backend/_pv_1_3_5/static/blockly/core/widgetdiv.js diff --git a/backend/static/blockly/core/workspace.js b/backend/_pv_1_3_5/static/blockly/core/workspace.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/workspace.js rename to backend/_pv_1_3_5/static/blockly/core/workspace.js diff --git a/backend/static/blockly/core/workspace_svg.js b/backend/_pv_1_3_5/static/blockly/core/workspace_svg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/workspace_svg.js rename to backend/_pv_1_3_5/static/blockly/core/workspace_svg.js diff --git a/backend/static/blockly/core/xml.js b/backend/_pv_1_3_5/static/blockly/core/xml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/xml.js rename to backend/_pv_1_3_5/static/blockly/core/xml.js diff --git a/backend/static/blockly/core/zoom_controls.js b/backend/_pv_1_3_5/static/blockly/core/zoom_controls.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/core/zoom_controls.js rename to backend/_pv_1_3_5/static/blockly/core/zoom_controls.js diff --git a/backend/static/blockly/dart_compressed.js b/backend/_pv_1_3_5/static/blockly/dart_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/dart_compressed.js rename to backend/_pv_1_3_5/static/blockly/dart_compressed.js diff --git a/backend/static/blockly/demos/code/style.css b/backend/_pv_1_3_5/static/blockly/demos/code/style.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/demos/code/style.css rename to backend/_pv_1_3_5/static/blockly/demos/code/style.css diff --git a/backend/static/blockly/generators/dart.js b/backend/_pv_1_3_5/static/blockly/generators/dart.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart.js rename to backend/_pv_1_3_5/static/blockly/generators/dart.js diff --git a/backend/static/blockly/generators/dart/colour.js b/backend/_pv_1_3_5/static/blockly/generators/dart/colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/colour.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/colour.js diff --git a/backend/static/blockly/generators/dart/lists.js b/backend/_pv_1_3_5/static/blockly/generators/dart/lists.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/lists.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/lists.js diff --git a/backend/static/blockly/generators/dart/logic.js b/backend/_pv_1_3_5/static/blockly/generators/dart/logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/logic.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/logic.js diff --git a/backend/static/blockly/generators/dart/loops.js b/backend/_pv_1_3_5/static/blockly/generators/dart/loops.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/loops.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/loops.js diff --git a/backend/static/blockly/generators/dart/math.js b/backend/_pv_1_3_5/static/blockly/generators/dart/math.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/math.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/math.js diff --git a/backend/static/blockly/generators/dart/procedures.js b/backend/_pv_1_3_5/static/blockly/generators/dart/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/procedures.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/procedures.js diff --git a/backend/static/blockly/generators/dart/text.js b/backend/_pv_1_3_5/static/blockly/generators/dart/text.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/text.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/text.js diff --git a/backend/static/blockly/generators/dart/variables.js b/backend/_pv_1_3_5/static/blockly/generators/dart/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/dart/variables.js rename to backend/_pv_1_3_5/static/blockly/generators/dart/variables.js diff --git a/backend/static/blockly/generators/javascript.js b/backend/_pv_1_3_5/static/blockly/generators/javascript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript.js diff --git a/backend/static/blockly/generators/javascript/colour.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/colour.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/colour.js diff --git a/backend/static/blockly/generators/javascript/lists.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/lists.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/lists.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/lists.js diff --git a/backend/static/blockly/generators/javascript/logic.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/logic.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/logic.js diff --git a/backend/static/blockly/generators/javascript/loops.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/loops.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/loops.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/loops.js diff --git a/backend/static/blockly/generators/javascript/math.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/math.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/math.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/math.js diff --git a/backend/static/blockly/generators/javascript/procedures.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/procedures.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/procedures.js diff --git a/backend/static/blockly/generators/javascript/text.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/text.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/text.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/text.js diff --git a/backend/static/blockly/generators/javascript/variables.js b/backend/_pv_1_3_5/static/blockly/generators/javascript/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/javascript/variables.js rename to backend/_pv_1_3_5/static/blockly/generators/javascript/variables.js diff --git a/backend/static/blockly/generators/lua.js b/backend/_pv_1_3_5/static/blockly/generators/lua.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua.js rename to backend/_pv_1_3_5/static/blockly/generators/lua.js diff --git a/backend/static/blockly/generators/lua/colour.js b/backend/_pv_1_3_5/static/blockly/generators/lua/colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/colour.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/colour.js diff --git a/backend/static/blockly/generators/lua/lists.js b/backend/_pv_1_3_5/static/blockly/generators/lua/lists.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/lists.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/lists.js diff --git a/backend/static/blockly/generators/lua/logic.js b/backend/_pv_1_3_5/static/blockly/generators/lua/logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/logic.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/logic.js diff --git a/backend/static/blockly/generators/lua/loops.js b/backend/_pv_1_3_5/static/blockly/generators/lua/loops.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/loops.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/loops.js diff --git a/backend/static/blockly/generators/lua/math.js b/backend/_pv_1_3_5/static/blockly/generators/lua/math.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/math.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/math.js diff --git a/backend/static/blockly/generators/lua/procedures.js b/backend/_pv_1_3_5/static/blockly/generators/lua/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/procedures.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/procedures.js diff --git a/backend/static/blockly/generators/lua/text.js b/backend/_pv_1_3_5/static/blockly/generators/lua/text.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/text.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/text.js diff --git a/backend/static/blockly/generators/lua/variables.js b/backend/_pv_1_3_5/static/blockly/generators/lua/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/lua/variables.js rename to backend/_pv_1_3_5/static/blockly/generators/lua/variables.js diff --git a/backend/static/blockly/generators/php.js b/backend/_pv_1_3_5/static/blockly/generators/php.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php.js rename to backend/_pv_1_3_5/static/blockly/generators/php.js diff --git a/backend/static/blockly/generators/php/colour.js b/backend/_pv_1_3_5/static/blockly/generators/php/colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/colour.js rename to backend/_pv_1_3_5/static/blockly/generators/php/colour.js diff --git a/backend/static/blockly/generators/php/lists.js b/backend/_pv_1_3_5/static/blockly/generators/php/lists.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/lists.js rename to backend/_pv_1_3_5/static/blockly/generators/php/lists.js diff --git a/backend/static/blockly/generators/php/logic.js b/backend/_pv_1_3_5/static/blockly/generators/php/logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/logic.js rename to backend/_pv_1_3_5/static/blockly/generators/php/logic.js diff --git a/backend/static/blockly/generators/php/loops.js b/backend/_pv_1_3_5/static/blockly/generators/php/loops.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/loops.js rename to backend/_pv_1_3_5/static/blockly/generators/php/loops.js diff --git a/backend/static/blockly/generators/php/math.js b/backend/_pv_1_3_5/static/blockly/generators/php/math.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/math.js rename to backend/_pv_1_3_5/static/blockly/generators/php/math.js diff --git a/backend/static/blockly/generators/php/procedures.js b/backend/_pv_1_3_5/static/blockly/generators/php/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/procedures.js rename to backend/_pv_1_3_5/static/blockly/generators/php/procedures.js diff --git a/backend/static/blockly/generators/php/text.js b/backend/_pv_1_3_5/static/blockly/generators/php/text.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/text.js rename to backend/_pv_1_3_5/static/blockly/generators/php/text.js diff --git a/backend/static/blockly/generators/php/variables.js b/backend/_pv_1_3_5/static/blockly/generators/php/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/php/variables.js rename to backend/_pv_1_3_5/static/blockly/generators/php/variables.js diff --git a/backend/static/blockly/generators/python.js b/backend/_pv_1_3_5/static/blockly/generators/python.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python.js rename to backend/_pv_1_3_5/static/blockly/generators/python.js diff --git a/backend/static/blockly/generators/python/colour.js b/backend/_pv_1_3_5/static/blockly/generators/python/colour.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/colour.js rename to backend/_pv_1_3_5/static/blockly/generators/python/colour.js diff --git a/backend/static/blockly/generators/python/lists.js b/backend/_pv_1_3_5/static/blockly/generators/python/lists.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/lists.js rename to backend/_pv_1_3_5/static/blockly/generators/python/lists.js diff --git a/backend/static/blockly/generators/python/logic.js b/backend/_pv_1_3_5/static/blockly/generators/python/logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/logic.js rename to backend/_pv_1_3_5/static/blockly/generators/python/logic.js diff --git a/backend/static/blockly/generators/python/loops.js b/backend/_pv_1_3_5/static/blockly/generators/python/loops.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/loops.js rename to backend/_pv_1_3_5/static/blockly/generators/python/loops.js diff --git a/backend/static/blockly/generators/python/math.js b/backend/_pv_1_3_5/static/blockly/generators/python/math.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/math.js rename to backend/_pv_1_3_5/static/blockly/generators/python/math.js diff --git a/backend/static/blockly/generators/python/procedures.js b/backend/_pv_1_3_5/static/blockly/generators/python/procedures.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/procedures.js rename to backend/_pv_1_3_5/static/blockly/generators/python/procedures.js diff --git a/backend/static/blockly/generators/python/text.js b/backend/_pv_1_3_5/static/blockly/generators/python/text.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/text.js rename to backend/_pv_1_3_5/static/blockly/generators/python/text.js diff --git a/backend/static/blockly/generators/python/variables.js b/backend/_pv_1_3_5/static/blockly/generators/python/variables.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/generators/python/variables.js rename to backend/_pv_1_3_5/static/blockly/generators/python/variables.js diff --git a/backend/static/blockly/i18n/common.py b/backend/_pv_1_3_5/static/blockly/i18n/common.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/common.py rename to backend/_pv_1_3_5/static/blockly/i18n/common.py diff --git a/backend/static/blockly/i18n/create_messages.py b/backend/_pv_1_3_5/static/blockly/i18n/create_messages.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/create_messages.py rename to backend/_pv_1_3_5/static/blockly/i18n/create_messages.py diff --git a/backend/static/blockly/i18n/dedup_json.py b/backend/_pv_1_3_5/static/blockly/i18n/dedup_json.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/dedup_json.py rename to backend/_pv_1_3_5/static/blockly/i18n/dedup_json.py diff --git a/backend/static/blockly/i18n/js_to_json.py b/backend/_pv_1_3_5/static/blockly/i18n/js_to_json.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/js_to_json.py rename to backend/_pv_1_3_5/static/blockly/i18n/js_to_json.py diff --git a/backend/static/blockly/i18n/json_to_js.py b/backend/_pv_1_3_5/static/blockly/i18n/json_to_js.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/json_to_js.py rename to backend/_pv_1_3_5/static/blockly/i18n/json_to_js.py diff --git a/backend/static/blockly/i18n/tests.py b/backend/_pv_1_3_5/static/blockly/i18n/tests.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/tests.py rename to backend/_pv_1_3_5/static/blockly/i18n/tests.py diff --git a/backend/static/blockly/i18n/xliff_to_json.py b/backend/_pv_1_3_5/static/blockly/i18n/xliff_to_json.py old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/i18n/xliff_to_json.py rename to backend/_pv_1_3_5/static/blockly/i18n/xliff_to_json.py diff --git a/backend/static/blockly/javascript_compressed.js b/backend/_pv_1_3_5/static/blockly/javascript_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/javascript_compressed.js rename to backend/_pv_1_3_5/static/blockly/javascript_compressed.js diff --git a/backend/static/blockly/lua_compressed.js b/backend/_pv_1_3_5/static/blockly/lua_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/lua_compressed.js rename to backend/_pv_1_3_5/static/blockly/lua_compressed.js diff --git a/backend/static/blockly/media/1x1.gif b/backend/_pv_1_3_5/static/blockly/media/1x1.gif old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/1x1.gif rename to backend/_pv_1_3_5/static/blockly/media/1x1.gif diff --git a/backend/static/blockly/media/click.mp3 b/backend/_pv_1_3_5/static/blockly/media/click.mp3 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/click.mp3 rename to backend/_pv_1_3_5/static/blockly/media/click.mp3 diff --git a/backend/static/blockly/media/click.ogg b/backend/_pv_1_3_5/static/blockly/media/click.ogg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/click.ogg rename to backend/_pv_1_3_5/static/blockly/media/click.ogg diff --git a/backend/static/blockly/media/click.wav b/backend/_pv_1_3_5/static/blockly/media/click.wav old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/click.wav rename to backend/_pv_1_3_5/static/blockly/media/click.wav diff --git a/backend/static/blockly/media/delete.mp3 b/backend/_pv_1_3_5/static/blockly/media/delete.mp3 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/delete.mp3 rename to backend/_pv_1_3_5/static/blockly/media/delete.mp3 diff --git a/backend/static/blockly/media/delete.ogg b/backend/_pv_1_3_5/static/blockly/media/delete.ogg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/delete.ogg rename to backend/_pv_1_3_5/static/blockly/media/delete.ogg diff --git a/backend/static/blockly/media/delete.wav b/backend/_pv_1_3_5/static/blockly/media/delete.wav old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/delete.wav rename to backend/_pv_1_3_5/static/blockly/media/delete.wav diff --git a/backend/static/blockly/media/disconnect.mp3 b/backend/_pv_1_3_5/static/blockly/media/disconnect.mp3 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/disconnect.mp3 rename to backend/_pv_1_3_5/static/blockly/media/disconnect.mp3 diff --git a/backend/static/blockly/media/disconnect.ogg b/backend/_pv_1_3_5/static/blockly/media/disconnect.ogg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/disconnect.ogg rename to backend/_pv_1_3_5/static/blockly/media/disconnect.ogg diff --git a/backend/static/blockly/media/disconnect.wav b/backend/_pv_1_3_5/static/blockly/media/disconnect.wav old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/disconnect.wav rename to backend/_pv_1_3_5/static/blockly/media/disconnect.wav diff --git a/backend/static/blockly/media/handclosed.cur b/backend/_pv_1_3_5/static/blockly/media/handclosed.cur old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/handclosed.cur rename to backend/_pv_1_3_5/static/blockly/media/handclosed.cur diff --git a/backend/static/blockly/media/handdelete.cur b/backend/_pv_1_3_5/static/blockly/media/handdelete.cur old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/handdelete.cur rename to backend/_pv_1_3_5/static/blockly/media/handdelete.cur diff --git a/backend/static/blockly/media/handopen.cur b/backend/_pv_1_3_5/static/blockly/media/handopen.cur old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/handopen.cur rename to backend/_pv_1_3_5/static/blockly/media/handopen.cur diff --git a/backend/static/blockly/media/quote0.png b/backend/_pv_1_3_5/static/blockly/media/quote0.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/quote0.png rename to backend/_pv_1_3_5/static/blockly/media/quote0.png diff --git a/backend/static/blockly/media/quote1.png b/backend/_pv_1_3_5/static/blockly/media/quote1.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/quote1.png rename to backend/_pv_1_3_5/static/blockly/media/quote1.png diff --git a/backend/static/blockly/media/sprites.png b/backend/_pv_1_3_5/static/blockly/media/sprites.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/sprites.png rename to backend/_pv_1_3_5/static/blockly/media/sprites.png diff --git a/backend/static/blockly/media/sprites.svg b/backend/_pv_1_3_5/static/blockly/media/sprites.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/media/sprites.svg rename to backend/_pv_1_3_5/static/blockly/media/sprites.svg diff --git a/backend/static/blockly/msg/js/ar.js b/backend/_pv_1_3_5/static/blockly/msg/js/ar.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ar.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ar.js diff --git a/backend/static/blockly/msg/js/az.js b/backend/_pv_1_3_5/static/blockly/msg/js/az.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/az.js rename to backend/_pv_1_3_5/static/blockly/msg/js/az.js diff --git a/backend/static/blockly/msg/js/ba.js b/backend/_pv_1_3_5/static/blockly/msg/js/ba.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ba.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ba.js diff --git a/backend/static/blockly/msg/js/bcc.js b/backend/_pv_1_3_5/static/blockly/msg/js/bcc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/bcc.js rename to backend/_pv_1_3_5/static/blockly/msg/js/bcc.js diff --git a/backend/static/blockly/msg/js/be-tarask.js b/backend/_pv_1_3_5/static/blockly/msg/js/be-tarask.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/be-tarask.js rename to backend/_pv_1_3_5/static/blockly/msg/js/be-tarask.js diff --git a/backend/static/blockly/msg/js/bg.js b/backend/_pv_1_3_5/static/blockly/msg/js/bg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/bg.js rename to backend/_pv_1_3_5/static/blockly/msg/js/bg.js diff --git a/backend/static/blockly/msg/js/bn.js b/backend/_pv_1_3_5/static/blockly/msg/js/bn.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/bn.js rename to backend/_pv_1_3_5/static/blockly/msg/js/bn.js diff --git a/backend/static/blockly/msg/js/br.js b/backend/_pv_1_3_5/static/blockly/msg/js/br.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/br.js rename to backend/_pv_1_3_5/static/blockly/msg/js/br.js diff --git a/backend/static/blockly/msg/js/ca.js b/backend/_pv_1_3_5/static/blockly/msg/js/ca.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ca.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ca.js diff --git a/backend/static/blockly/msg/js/cs.js b/backend/_pv_1_3_5/static/blockly/msg/js/cs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/cs.js rename to backend/_pv_1_3_5/static/blockly/msg/js/cs.js diff --git a/backend/static/blockly/msg/js/da.js b/backend/_pv_1_3_5/static/blockly/msg/js/da.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/da.js rename to backend/_pv_1_3_5/static/blockly/msg/js/da.js diff --git a/backend/static/blockly/msg/js/de.js b/backend/_pv_1_3_5/static/blockly/msg/js/de.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/de.js rename to backend/_pv_1_3_5/static/blockly/msg/js/de.js diff --git a/backend/static/blockly/msg/js/diq.js b/backend/_pv_1_3_5/static/blockly/msg/js/diq.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/diq.js rename to backend/_pv_1_3_5/static/blockly/msg/js/diq.js diff --git a/backend/static/blockly/msg/js/el.js b/backend/_pv_1_3_5/static/blockly/msg/js/el.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/el.js rename to backend/_pv_1_3_5/static/blockly/msg/js/el.js diff --git a/backend/static/blockly/msg/js/en-gb.js b/backend/_pv_1_3_5/static/blockly/msg/js/en-gb.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/en-gb.js rename to backend/_pv_1_3_5/static/blockly/msg/js/en-gb.js diff --git a/backend/static/blockly/msg/js/en.js b/backend/_pv_1_3_5/static/blockly/msg/js/en.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/en.js rename to backend/_pv_1_3_5/static/blockly/msg/js/en.js diff --git a/backend/static/blockly/msg/js/es.js b/backend/_pv_1_3_5/static/blockly/msg/js/es.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/es.js rename to backend/_pv_1_3_5/static/blockly/msg/js/es.js diff --git a/backend/static/blockly/msg/js/et.js b/backend/_pv_1_3_5/static/blockly/msg/js/et.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/et.js rename to backend/_pv_1_3_5/static/blockly/msg/js/et.js diff --git a/backend/static/blockly/msg/js/fa.js b/backend/_pv_1_3_5/static/blockly/msg/js/fa.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/fa.js rename to backend/_pv_1_3_5/static/blockly/msg/js/fa.js diff --git a/backend/static/blockly/msg/js/fi.js b/backend/_pv_1_3_5/static/blockly/msg/js/fi.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/fi.js rename to backend/_pv_1_3_5/static/blockly/msg/js/fi.js diff --git a/backend/static/blockly/msg/js/fr.js b/backend/_pv_1_3_5/static/blockly/msg/js/fr.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/fr.js rename to backend/_pv_1_3_5/static/blockly/msg/js/fr.js diff --git a/backend/static/blockly/msg/js/he.js b/backend/_pv_1_3_5/static/blockly/msg/js/he.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/he.js rename to backend/_pv_1_3_5/static/blockly/msg/js/he.js diff --git a/backend/static/blockly/msg/js/hi.js b/backend/_pv_1_3_5/static/blockly/msg/js/hi.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/hi.js rename to backend/_pv_1_3_5/static/blockly/msg/js/hi.js diff --git a/backend/static/blockly/msg/js/hrx.js b/backend/_pv_1_3_5/static/blockly/msg/js/hrx.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/hrx.js rename to backend/_pv_1_3_5/static/blockly/msg/js/hrx.js diff --git a/backend/static/blockly/msg/js/hu.js b/backend/_pv_1_3_5/static/blockly/msg/js/hu.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/hu.js rename to backend/_pv_1_3_5/static/blockly/msg/js/hu.js diff --git a/backend/static/blockly/msg/js/ia.js b/backend/_pv_1_3_5/static/blockly/msg/js/ia.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ia.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ia.js diff --git a/backend/static/blockly/msg/js/id.js b/backend/_pv_1_3_5/static/blockly/msg/js/id.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/id.js rename to backend/_pv_1_3_5/static/blockly/msg/js/id.js diff --git a/backend/static/blockly/msg/js/is.js b/backend/_pv_1_3_5/static/blockly/msg/js/is.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/is.js rename to backend/_pv_1_3_5/static/blockly/msg/js/is.js diff --git a/backend/static/blockly/msg/js/it.js b/backend/_pv_1_3_5/static/blockly/msg/js/it.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/it.js rename to backend/_pv_1_3_5/static/blockly/msg/js/it.js diff --git a/backend/static/blockly/msg/js/ja.js b/backend/_pv_1_3_5/static/blockly/msg/js/ja.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ja.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ja.js diff --git a/backend/static/blockly/msg/js/ko.js b/backend/_pv_1_3_5/static/blockly/msg/js/ko.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ko.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ko.js diff --git a/backend/static/blockly/msg/js/lb.js b/backend/_pv_1_3_5/static/blockly/msg/js/lb.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/lb.js rename to backend/_pv_1_3_5/static/blockly/msg/js/lb.js diff --git a/backend/static/blockly/msg/js/lki.js b/backend/_pv_1_3_5/static/blockly/msg/js/lki.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/lki.js rename to backend/_pv_1_3_5/static/blockly/msg/js/lki.js diff --git a/backend/static/blockly/msg/js/lrc.js b/backend/_pv_1_3_5/static/blockly/msg/js/lrc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/lrc.js rename to backend/_pv_1_3_5/static/blockly/msg/js/lrc.js diff --git a/backend/static/blockly/msg/js/lt.js b/backend/_pv_1_3_5/static/blockly/msg/js/lt.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/lt.js rename to backend/_pv_1_3_5/static/blockly/msg/js/lt.js diff --git a/backend/static/blockly/msg/js/mk.js b/backend/_pv_1_3_5/static/blockly/msg/js/mk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/mk.js rename to backend/_pv_1_3_5/static/blockly/msg/js/mk.js diff --git a/backend/static/blockly/msg/js/ms.js b/backend/_pv_1_3_5/static/blockly/msg/js/ms.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ms.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ms.js diff --git a/backend/static/blockly/msg/js/nb.js b/backend/_pv_1_3_5/static/blockly/msg/js/nb.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/nb.js rename to backend/_pv_1_3_5/static/blockly/msg/js/nb.js diff --git a/backend/static/blockly/msg/js/nl.js b/backend/_pv_1_3_5/static/blockly/msg/js/nl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/nl.js rename to backend/_pv_1_3_5/static/blockly/msg/js/nl.js diff --git a/backend/static/blockly/msg/js/oc.js b/backend/_pv_1_3_5/static/blockly/msg/js/oc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/oc.js rename to backend/_pv_1_3_5/static/blockly/msg/js/oc.js diff --git a/backend/static/blockly/msg/js/pl.js b/backend/_pv_1_3_5/static/blockly/msg/js/pl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/pl.js rename to backend/_pv_1_3_5/static/blockly/msg/js/pl.js diff --git a/backend/static/blockly/msg/js/pms.js b/backend/_pv_1_3_5/static/blockly/msg/js/pms.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/pms.js rename to backend/_pv_1_3_5/static/blockly/msg/js/pms.js diff --git a/backend/static/blockly/msg/js/pt-br.js b/backend/_pv_1_3_5/static/blockly/msg/js/pt-br.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/pt-br.js rename to backend/_pv_1_3_5/static/blockly/msg/js/pt-br.js diff --git a/backend/static/blockly/msg/js/pt.js b/backend/_pv_1_3_5/static/blockly/msg/js/pt.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/pt.js rename to backend/_pv_1_3_5/static/blockly/msg/js/pt.js diff --git a/backend/static/blockly/msg/js/ro.js b/backend/_pv_1_3_5/static/blockly/msg/js/ro.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ro.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ro.js diff --git a/backend/static/blockly/msg/js/ru.js b/backend/_pv_1_3_5/static/blockly/msg/js/ru.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ru.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ru.js diff --git a/backend/static/blockly/msg/js/sc.js b/backend/_pv_1_3_5/static/blockly/msg/js/sc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sc.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sc.js diff --git a/backend/static/blockly/msg/js/sd.js b/backend/_pv_1_3_5/static/blockly/msg/js/sd.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sd.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sd.js diff --git a/backend/static/blockly/msg/js/shn.js b/backend/_pv_1_3_5/static/blockly/msg/js/shn.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/shn.js rename to backend/_pv_1_3_5/static/blockly/msg/js/shn.js diff --git a/backend/static/blockly/msg/js/sk.js b/backend/_pv_1_3_5/static/blockly/msg/js/sk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sk.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sk.js diff --git a/backend/static/blockly/msg/js/sl.js b/backend/_pv_1_3_5/static/blockly/msg/js/sl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sl.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sl.js diff --git a/backend/static/blockly/msg/js/sq.js b/backend/_pv_1_3_5/static/blockly/msg/js/sq.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sq.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sq.js diff --git a/backend/static/blockly/msg/js/sr.js b/backend/_pv_1_3_5/static/blockly/msg/js/sr.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sr.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sr.js diff --git a/backend/static/blockly/msg/js/sv.js b/backend/_pv_1_3_5/static/blockly/msg/js/sv.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/sv.js rename to backend/_pv_1_3_5/static/blockly/msg/js/sv.js diff --git a/backend/static/blockly/msg/js/ta.js b/backend/_pv_1_3_5/static/blockly/msg/js/ta.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/ta.js rename to backend/_pv_1_3_5/static/blockly/msg/js/ta.js diff --git a/backend/static/blockly/msg/js/tcy.js b/backend/_pv_1_3_5/static/blockly/msg/js/tcy.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/tcy.js rename to backend/_pv_1_3_5/static/blockly/msg/js/tcy.js diff --git a/backend/static/blockly/msg/js/th.js b/backend/_pv_1_3_5/static/blockly/msg/js/th.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/th.js rename to backend/_pv_1_3_5/static/blockly/msg/js/th.js diff --git a/backend/static/blockly/msg/js/tl.js b/backend/_pv_1_3_5/static/blockly/msg/js/tl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/tl.js rename to backend/_pv_1_3_5/static/blockly/msg/js/tl.js diff --git a/backend/static/blockly/msg/js/tlh.js b/backend/_pv_1_3_5/static/blockly/msg/js/tlh.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/tlh.js rename to backend/_pv_1_3_5/static/blockly/msg/js/tlh.js diff --git a/backend/static/blockly/msg/js/tr.js b/backend/_pv_1_3_5/static/blockly/msg/js/tr.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/tr.js rename to backend/_pv_1_3_5/static/blockly/msg/js/tr.js diff --git a/backend/static/blockly/msg/js/uk.js b/backend/_pv_1_3_5/static/blockly/msg/js/uk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/uk.js rename to backend/_pv_1_3_5/static/blockly/msg/js/uk.js diff --git a/backend/static/blockly/msg/js/vi.js b/backend/_pv_1_3_5/static/blockly/msg/js/vi.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/vi.js rename to backend/_pv_1_3_5/static/blockly/msg/js/vi.js diff --git a/backend/static/blockly/msg/js/zh-hans.js b/backend/_pv_1_3_5/static/blockly/msg/js/zh-hans.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/zh-hans.js rename to backend/_pv_1_3_5/static/blockly/msg/js/zh-hans.js diff --git a/backend/static/blockly/msg/js/zh-hant.js b/backend/_pv_1_3_5/static/blockly/msg/js/zh-hant.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/js/zh-hant.js rename to backend/_pv_1_3_5/static/blockly/msg/js/zh-hant.js diff --git a/backend/static/blockly/msg/json/ar.json b/backend/_pv_1_3_5/static/blockly/msg/json/ar.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ar.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ar.json diff --git a/backend/static/blockly/msg/json/az.json b/backend/_pv_1_3_5/static/blockly/msg/json/az.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/az.json rename to backend/_pv_1_3_5/static/blockly/msg/json/az.json diff --git a/backend/static/blockly/msg/json/ba.json b/backend/_pv_1_3_5/static/blockly/msg/json/ba.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ba.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ba.json diff --git a/backend/static/blockly/msg/json/bcc.json b/backend/_pv_1_3_5/static/blockly/msg/json/bcc.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/bcc.json rename to backend/_pv_1_3_5/static/blockly/msg/json/bcc.json diff --git a/backend/static/blockly/msg/json/be-tarask.json b/backend/_pv_1_3_5/static/blockly/msg/json/be-tarask.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/be-tarask.json rename to backend/_pv_1_3_5/static/blockly/msg/json/be-tarask.json diff --git a/backend/static/blockly/msg/json/bg.json b/backend/_pv_1_3_5/static/blockly/msg/json/bg.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/bg.json rename to backend/_pv_1_3_5/static/blockly/msg/json/bg.json diff --git a/backend/static/blockly/msg/json/bn.json b/backend/_pv_1_3_5/static/blockly/msg/json/bn.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/bn.json rename to backend/_pv_1_3_5/static/blockly/msg/json/bn.json diff --git a/backend/static/blockly/msg/json/br.json b/backend/_pv_1_3_5/static/blockly/msg/json/br.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/br.json rename to backend/_pv_1_3_5/static/blockly/msg/json/br.json diff --git a/backend/static/blockly/msg/json/ca.json b/backend/_pv_1_3_5/static/blockly/msg/json/ca.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ca.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ca.json diff --git a/backend/static/blockly/msg/json/cs.json b/backend/_pv_1_3_5/static/blockly/msg/json/cs.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/cs.json rename to backend/_pv_1_3_5/static/blockly/msg/json/cs.json diff --git a/backend/static/blockly/msg/json/da.json b/backend/_pv_1_3_5/static/blockly/msg/json/da.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/da.json rename to backend/_pv_1_3_5/static/blockly/msg/json/da.json diff --git a/backend/static/blockly/msg/json/de.json b/backend/_pv_1_3_5/static/blockly/msg/json/de.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/de.json rename to backend/_pv_1_3_5/static/blockly/msg/json/de.json diff --git a/backend/static/blockly/msg/json/diq.json b/backend/_pv_1_3_5/static/blockly/msg/json/diq.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/diq.json rename to backend/_pv_1_3_5/static/blockly/msg/json/diq.json diff --git a/backend/static/blockly/msg/json/el.json b/backend/_pv_1_3_5/static/blockly/msg/json/el.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/el.json rename to backend/_pv_1_3_5/static/blockly/msg/json/el.json diff --git a/backend/static/blockly/msg/json/en-gb.json b/backend/_pv_1_3_5/static/blockly/msg/json/en-gb.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/en-gb.json rename to backend/_pv_1_3_5/static/blockly/msg/json/en-gb.json diff --git a/backend/static/blockly/msg/json/en.json b/backend/_pv_1_3_5/static/blockly/msg/json/en.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/en.json rename to backend/_pv_1_3_5/static/blockly/msg/json/en.json diff --git a/backend/static/blockly/msg/json/es.json b/backend/_pv_1_3_5/static/blockly/msg/json/es.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/es.json rename to backend/_pv_1_3_5/static/blockly/msg/json/es.json diff --git a/backend/static/blockly/msg/json/et.json b/backend/_pv_1_3_5/static/blockly/msg/json/et.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/et.json rename to backend/_pv_1_3_5/static/blockly/msg/json/et.json diff --git a/backend/static/blockly/msg/json/fa.json b/backend/_pv_1_3_5/static/blockly/msg/json/fa.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/fa.json rename to backend/_pv_1_3_5/static/blockly/msg/json/fa.json diff --git a/backend/static/blockly/msg/json/fi.json b/backend/_pv_1_3_5/static/blockly/msg/json/fi.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/fi.json rename to backend/_pv_1_3_5/static/blockly/msg/json/fi.json diff --git a/backend/static/blockly/msg/json/fr.json b/backend/_pv_1_3_5/static/blockly/msg/json/fr.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/fr.json rename to backend/_pv_1_3_5/static/blockly/msg/json/fr.json diff --git a/backend/static/blockly/msg/json/he.json b/backend/_pv_1_3_5/static/blockly/msg/json/he.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/he.json rename to backend/_pv_1_3_5/static/blockly/msg/json/he.json diff --git a/backend/static/blockly/msg/json/hi.json b/backend/_pv_1_3_5/static/blockly/msg/json/hi.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/hi.json rename to backend/_pv_1_3_5/static/blockly/msg/json/hi.json diff --git a/backend/static/blockly/msg/json/hrx.json b/backend/_pv_1_3_5/static/blockly/msg/json/hrx.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/hrx.json rename to backend/_pv_1_3_5/static/blockly/msg/json/hrx.json diff --git a/backend/static/blockly/msg/json/hu.json b/backend/_pv_1_3_5/static/blockly/msg/json/hu.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/hu.json rename to backend/_pv_1_3_5/static/blockly/msg/json/hu.json diff --git a/backend/static/blockly/msg/json/ia.json b/backend/_pv_1_3_5/static/blockly/msg/json/ia.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ia.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ia.json diff --git a/backend/static/blockly/msg/json/id.json b/backend/_pv_1_3_5/static/blockly/msg/json/id.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/id.json rename to backend/_pv_1_3_5/static/blockly/msg/json/id.json diff --git a/backend/static/blockly/msg/json/is.json b/backend/_pv_1_3_5/static/blockly/msg/json/is.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/is.json rename to backend/_pv_1_3_5/static/blockly/msg/json/is.json diff --git a/backend/static/blockly/msg/json/it.json b/backend/_pv_1_3_5/static/blockly/msg/json/it.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/it.json rename to backend/_pv_1_3_5/static/blockly/msg/json/it.json diff --git a/backend/static/blockly/msg/json/ja.json b/backend/_pv_1_3_5/static/blockly/msg/json/ja.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ja.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ja.json diff --git a/backend/static/blockly/msg/json/ko.json b/backend/_pv_1_3_5/static/blockly/msg/json/ko.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ko.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ko.json diff --git a/backend/static/blockly/msg/json/lb.json b/backend/_pv_1_3_5/static/blockly/msg/json/lb.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/lb.json rename to backend/_pv_1_3_5/static/blockly/msg/json/lb.json diff --git a/backend/static/blockly/msg/json/lki.json b/backend/_pv_1_3_5/static/blockly/msg/json/lki.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/lki.json rename to backend/_pv_1_3_5/static/blockly/msg/json/lki.json diff --git a/backend/static/blockly/msg/json/lrc.json b/backend/_pv_1_3_5/static/blockly/msg/json/lrc.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/lrc.json rename to backend/_pv_1_3_5/static/blockly/msg/json/lrc.json diff --git a/backend/static/blockly/msg/json/lt.json b/backend/_pv_1_3_5/static/blockly/msg/json/lt.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/lt.json rename to backend/_pv_1_3_5/static/blockly/msg/json/lt.json diff --git a/backend/static/blockly/msg/json/mk.json b/backend/_pv_1_3_5/static/blockly/msg/json/mk.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/mk.json rename to backend/_pv_1_3_5/static/blockly/msg/json/mk.json diff --git a/backend/static/blockly/msg/json/ms.json b/backend/_pv_1_3_5/static/blockly/msg/json/ms.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ms.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ms.json diff --git a/backend/static/blockly/msg/json/nb.json b/backend/_pv_1_3_5/static/blockly/msg/json/nb.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/nb.json rename to backend/_pv_1_3_5/static/blockly/msg/json/nb.json diff --git a/backend/static/blockly/msg/json/nl.json b/backend/_pv_1_3_5/static/blockly/msg/json/nl.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/nl.json rename to backend/_pv_1_3_5/static/blockly/msg/json/nl.json diff --git a/backend/static/blockly/msg/json/oc.json b/backend/_pv_1_3_5/static/blockly/msg/json/oc.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/oc.json rename to backend/_pv_1_3_5/static/blockly/msg/json/oc.json diff --git a/backend/static/blockly/msg/json/pl.json b/backend/_pv_1_3_5/static/blockly/msg/json/pl.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/pl.json rename to backend/_pv_1_3_5/static/blockly/msg/json/pl.json diff --git a/backend/static/blockly/msg/json/pms.json b/backend/_pv_1_3_5/static/blockly/msg/json/pms.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/pms.json rename to backend/_pv_1_3_5/static/blockly/msg/json/pms.json diff --git a/backend/static/blockly/msg/json/pt-br.json b/backend/_pv_1_3_5/static/blockly/msg/json/pt-br.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/pt-br.json rename to backend/_pv_1_3_5/static/blockly/msg/json/pt-br.json diff --git a/backend/static/blockly/msg/json/pt.json b/backend/_pv_1_3_5/static/blockly/msg/json/pt.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/pt.json rename to backend/_pv_1_3_5/static/blockly/msg/json/pt.json diff --git a/backend/static/blockly/msg/json/qqq.json b/backend/_pv_1_3_5/static/blockly/msg/json/qqq.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/qqq.json rename to backend/_pv_1_3_5/static/blockly/msg/json/qqq.json diff --git a/backend/static/blockly/msg/json/ro.json b/backend/_pv_1_3_5/static/blockly/msg/json/ro.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ro.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ro.json diff --git a/backend/static/blockly/msg/json/ru.json b/backend/_pv_1_3_5/static/blockly/msg/json/ru.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ru.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ru.json diff --git a/backend/static/blockly/msg/json/sc.json b/backend/_pv_1_3_5/static/blockly/msg/json/sc.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sc.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sc.json diff --git a/backend/static/blockly/msg/json/sd.json b/backend/_pv_1_3_5/static/blockly/msg/json/sd.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sd.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sd.json diff --git a/backend/static/blockly/msg/json/shn.json b/backend/_pv_1_3_5/static/blockly/msg/json/shn.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/shn.json rename to backend/_pv_1_3_5/static/blockly/msg/json/shn.json diff --git a/backend/static/blockly/msg/json/sk.json b/backend/_pv_1_3_5/static/blockly/msg/json/sk.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sk.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sk.json diff --git a/backend/static/blockly/msg/json/sl.json b/backend/_pv_1_3_5/static/blockly/msg/json/sl.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sl.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sl.json diff --git a/backend/static/blockly/msg/json/sq.json b/backend/_pv_1_3_5/static/blockly/msg/json/sq.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sq.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sq.json diff --git a/backend/static/blockly/msg/json/sr.json b/backend/_pv_1_3_5/static/blockly/msg/json/sr.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sr.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sr.json diff --git a/backend/static/blockly/msg/json/sv.json b/backend/_pv_1_3_5/static/blockly/msg/json/sv.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/sv.json rename to backend/_pv_1_3_5/static/blockly/msg/json/sv.json diff --git a/backend/static/blockly/msg/json/synonyms.json b/backend/_pv_1_3_5/static/blockly/msg/json/synonyms.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/synonyms.json rename to backend/_pv_1_3_5/static/blockly/msg/json/synonyms.json diff --git a/backend/static/blockly/msg/json/ta.json b/backend/_pv_1_3_5/static/blockly/msg/json/ta.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/ta.json rename to backend/_pv_1_3_5/static/blockly/msg/json/ta.json diff --git a/backend/static/blockly/msg/json/tcy.json b/backend/_pv_1_3_5/static/blockly/msg/json/tcy.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/tcy.json rename to backend/_pv_1_3_5/static/blockly/msg/json/tcy.json diff --git a/backend/static/blockly/msg/json/th.json b/backend/_pv_1_3_5/static/blockly/msg/json/th.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/th.json rename to backend/_pv_1_3_5/static/blockly/msg/json/th.json diff --git a/backend/static/blockly/msg/json/tl.json b/backend/_pv_1_3_5/static/blockly/msg/json/tl.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/tl.json rename to backend/_pv_1_3_5/static/blockly/msg/json/tl.json diff --git a/backend/static/blockly/msg/json/tlh.json b/backend/_pv_1_3_5/static/blockly/msg/json/tlh.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/tlh.json rename to backend/_pv_1_3_5/static/blockly/msg/json/tlh.json diff --git a/backend/static/blockly/msg/json/tr.json b/backend/_pv_1_3_5/static/blockly/msg/json/tr.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/tr.json rename to backend/_pv_1_3_5/static/blockly/msg/json/tr.json diff --git a/backend/static/blockly/msg/json/uk.json b/backend/_pv_1_3_5/static/blockly/msg/json/uk.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/uk.json rename to backend/_pv_1_3_5/static/blockly/msg/json/uk.json diff --git a/backend/static/blockly/msg/json/vi.json b/backend/_pv_1_3_5/static/blockly/msg/json/vi.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/vi.json rename to backend/_pv_1_3_5/static/blockly/msg/json/vi.json diff --git a/backend/static/blockly/msg/json/zh-hans.json b/backend/_pv_1_3_5/static/blockly/msg/json/zh-hans.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/zh-hans.json rename to backend/_pv_1_3_5/static/blockly/msg/json/zh-hans.json diff --git a/backend/static/blockly/msg/json/zh-hant.json b/backend/_pv_1_3_5/static/blockly/msg/json/zh-hant.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/json/zh-hant.json rename to backend/_pv_1_3_5/static/blockly/msg/json/zh-hant.json diff --git a/backend/static/blockly/msg/messages.js b/backend/_pv_1_3_5/static/blockly/msg/messages.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/msg/messages.js rename to backend/_pv_1_3_5/static/blockly/msg/messages.js diff --git a/backend/static/blockly/php_compressed.js b/backend/_pv_1_3_5/static/blockly/php_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/php_compressed.js rename to backend/_pv_1_3_5/static/blockly/php_compressed.js diff --git a/backend/static/blockly/python_compressed.js b/backend/_pv_1_3_5/static/blockly/python_compressed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/blockly/python_compressed.js rename to backend/_pv_1_3_5/static/blockly/python_compressed.js diff --git a/backend/static/codemirror/AUTHORS b/backend/_pv_1_3_5/static/codemirror/AUTHORS old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/AUTHORS rename to backend/_pv_1_3_5/static/codemirror/AUTHORS diff --git a/backend/static/codemirror/CHANGELOG.md b/backend/_pv_1_3_5/static/codemirror/CHANGELOG.md old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/CHANGELOG.md rename to backend/_pv_1_3_5/static/codemirror/CHANGELOG.md diff --git a/backend/static/codemirror/CONTRIBUTING.md b/backend/_pv_1_3_5/static/codemirror/CONTRIBUTING.md old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/CONTRIBUTING.md rename to backend/_pv_1_3_5/static/codemirror/CONTRIBUTING.md diff --git a/backend/static/codemirror/LICENSE b/backend/_pv_1_3_5/static/codemirror/LICENSE old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/LICENSE rename to backend/_pv_1_3_5/static/codemirror/LICENSE diff --git a/backend/static/codemirror/README.md b/backend/_pv_1_3_5/static/codemirror/README.md old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/README.md rename to backend/_pv_1_3_5/static/codemirror/README.md diff --git a/backend/static/codemirror/addon/comment/comment.js b/backend/_pv_1_3_5/static/codemirror/addon/comment/comment.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/comment/comment.js rename to backend/_pv_1_3_5/static/codemirror/addon/comment/comment.js diff --git a/backend/static/codemirror/addon/comment/continuecomment.js b/backend/_pv_1_3_5/static/codemirror/addon/comment/continuecomment.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/comment/continuecomment.js rename to backend/_pv_1_3_5/static/codemirror/addon/comment/continuecomment.js diff --git a/backend/static/codemirror/addon/dialog/dialog.css b/backend/_pv_1_3_5/static/codemirror/addon/dialog/dialog.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/dialog/dialog.css rename to backend/_pv_1_3_5/static/codemirror/addon/dialog/dialog.css diff --git a/backend/static/codemirror/addon/dialog/dialog.js b/backend/_pv_1_3_5/static/codemirror/addon/dialog/dialog.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/dialog/dialog.js rename to backend/_pv_1_3_5/static/codemirror/addon/dialog/dialog.js diff --git a/backend/static/codemirror/addon/display/autorefresh.js b/backend/_pv_1_3_5/static/codemirror/addon/display/autorefresh.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/autorefresh.js rename to backend/_pv_1_3_5/static/codemirror/addon/display/autorefresh.js diff --git a/backend/static/codemirror/addon/display/fullscreen.css b/backend/_pv_1_3_5/static/codemirror/addon/display/fullscreen.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/fullscreen.css rename to backend/_pv_1_3_5/static/codemirror/addon/display/fullscreen.css diff --git a/backend/static/codemirror/addon/display/fullscreen.js b/backend/_pv_1_3_5/static/codemirror/addon/display/fullscreen.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/fullscreen.js rename to backend/_pv_1_3_5/static/codemirror/addon/display/fullscreen.js diff --git a/backend/static/codemirror/addon/display/panel.js b/backend/_pv_1_3_5/static/codemirror/addon/display/panel.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/panel.js rename to backend/_pv_1_3_5/static/codemirror/addon/display/panel.js diff --git a/backend/static/codemirror/addon/display/placeholder.js b/backend/_pv_1_3_5/static/codemirror/addon/display/placeholder.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/placeholder.js rename to backend/_pv_1_3_5/static/codemirror/addon/display/placeholder.js diff --git a/backend/static/codemirror/addon/display/rulers.js b/backend/_pv_1_3_5/static/codemirror/addon/display/rulers.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/display/rulers.js rename to backend/_pv_1_3_5/static/codemirror/addon/display/rulers.js diff --git a/backend/static/codemirror/addon/edit/closebrackets.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/closebrackets.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/closebrackets.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/closebrackets.js diff --git a/backend/static/codemirror/addon/edit/closetag.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/closetag.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/closetag.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/closetag.js diff --git a/backend/static/codemirror/addon/edit/continuelist.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/continuelist.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/continuelist.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/continuelist.js diff --git a/backend/static/codemirror/addon/edit/matchbrackets.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/matchbrackets.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/matchbrackets.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/matchbrackets.js diff --git a/backend/static/codemirror/addon/edit/matchtags.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/matchtags.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/matchtags.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/matchtags.js diff --git a/backend/static/codemirror/addon/edit/trailingspace.js b/backend/_pv_1_3_5/static/codemirror/addon/edit/trailingspace.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/edit/trailingspace.js rename to backend/_pv_1_3_5/static/codemirror/addon/edit/trailingspace.js diff --git a/backend/static/codemirror/addon/fold/brace-fold.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/brace-fold.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/brace-fold.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/brace-fold.js diff --git a/backend/static/codemirror/addon/fold/comment-fold.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/comment-fold.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/comment-fold.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/comment-fold.js diff --git a/backend/static/codemirror/addon/fold/foldcode.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/foldcode.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/foldcode.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/foldcode.js diff --git a/backend/static/codemirror/addon/fold/foldgutter.css b/backend/_pv_1_3_5/static/codemirror/addon/fold/foldgutter.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/foldgutter.css rename to backend/_pv_1_3_5/static/codemirror/addon/fold/foldgutter.css diff --git a/backend/static/codemirror/addon/fold/foldgutter.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/foldgutter.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/foldgutter.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/foldgutter.js diff --git a/backend/static/codemirror/addon/fold/indent-fold.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/indent-fold.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/indent-fold.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/indent-fold.js diff --git a/backend/static/codemirror/addon/fold/markdown-fold.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/markdown-fold.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/markdown-fold.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/markdown-fold.js diff --git a/backend/static/codemirror/addon/fold/xml-fold.js b/backend/_pv_1_3_5/static/codemirror/addon/fold/xml-fold.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/fold/xml-fold.js rename to backend/_pv_1_3_5/static/codemirror/addon/fold/xml-fold.js diff --git a/backend/static/codemirror/addon/hint/anyword-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/anyword-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/anyword-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/anyword-hint.js diff --git a/backend/static/codemirror/addon/hint/css-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/css-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/css-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/css-hint.js diff --git a/backend/static/codemirror/addon/hint/html-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/html-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/html-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/html-hint.js diff --git a/backend/static/codemirror/addon/hint/javascript-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/javascript-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/javascript-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/javascript-hint.js diff --git a/backend/static/codemirror/addon/hint/show-hint.css b/backend/_pv_1_3_5/static/codemirror/addon/hint/show-hint.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/show-hint.css rename to backend/_pv_1_3_5/static/codemirror/addon/hint/show-hint.css diff --git a/backend/static/codemirror/addon/hint/show-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/show-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/show-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/show-hint.js diff --git a/backend/static/codemirror/addon/hint/sql-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/sql-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/sql-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/sql-hint.js diff --git a/backend/static/codemirror/addon/hint/xml-hint.js b/backend/_pv_1_3_5/static/codemirror/addon/hint/xml-hint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/hint/xml-hint.js rename to backend/_pv_1_3_5/static/codemirror/addon/hint/xml-hint.js diff --git a/backend/static/codemirror/addon/lint/coffeescript-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/coffeescript-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/coffeescript-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/coffeescript-lint.js diff --git a/backend/static/codemirror/addon/lint/css-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/css-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/css-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/css-lint.js diff --git a/backend/static/codemirror/addon/lint/html-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/html-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/html-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/html-lint.js diff --git a/backend/static/codemirror/addon/lint/javascript-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/javascript-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/javascript-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/javascript-lint.js diff --git a/backend/static/codemirror/addon/lint/json-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/json-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/json-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/json-lint.js diff --git a/backend/static/codemirror/addon/lint/lint.css b/backend/_pv_1_3_5/static/codemirror/addon/lint/lint.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/lint.css rename to backend/_pv_1_3_5/static/codemirror/addon/lint/lint.css diff --git a/backend/static/codemirror/addon/lint/lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/lint.js diff --git a/backend/static/codemirror/addon/lint/yaml-lint.js b/backend/_pv_1_3_5/static/codemirror/addon/lint/yaml-lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/lint/yaml-lint.js rename to backend/_pv_1_3_5/static/codemirror/addon/lint/yaml-lint.js diff --git a/backend/static/codemirror/addon/merge/merge.css b/backend/_pv_1_3_5/static/codemirror/addon/merge/merge.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/merge/merge.css rename to backend/_pv_1_3_5/static/codemirror/addon/merge/merge.css diff --git a/backend/static/codemirror/addon/merge/merge.js b/backend/_pv_1_3_5/static/codemirror/addon/merge/merge.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/merge/merge.js rename to backend/_pv_1_3_5/static/codemirror/addon/merge/merge.js diff --git a/backend/static/codemirror/addon/mode/loadmode.js b/backend/_pv_1_3_5/static/codemirror/addon/mode/loadmode.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/mode/loadmode.js rename to backend/_pv_1_3_5/static/codemirror/addon/mode/loadmode.js diff --git a/backend/static/codemirror/addon/mode/multiplex.js b/backend/_pv_1_3_5/static/codemirror/addon/mode/multiplex.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/mode/multiplex.js rename to backend/_pv_1_3_5/static/codemirror/addon/mode/multiplex.js diff --git a/backend/static/codemirror/addon/mode/multiplex_test.js b/backend/_pv_1_3_5/static/codemirror/addon/mode/multiplex_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/mode/multiplex_test.js rename to backend/_pv_1_3_5/static/codemirror/addon/mode/multiplex_test.js diff --git a/backend/static/codemirror/addon/mode/overlay.js b/backend/_pv_1_3_5/static/codemirror/addon/mode/overlay.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/mode/overlay.js rename to backend/_pv_1_3_5/static/codemirror/addon/mode/overlay.js diff --git a/backend/static/codemirror/addon/mode/simple.js b/backend/_pv_1_3_5/static/codemirror/addon/mode/simple.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/mode/simple.js rename to backend/_pv_1_3_5/static/codemirror/addon/mode/simple.js diff --git a/backend/static/codemirror/addon/runmode/colorize.js b/backend/_pv_1_3_5/static/codemirror/addon/runmode/colorize.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/runmode/colorize.js rename to backend/_pv_1_3_5/static/codemirror/addon/runmode/colorize.js diff --git a/backend/static/codemirror/addon/runmode/runmode-standalone.js b/backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode-standalone.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/runmode/runmode-standalone.js rename to backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode-standalone.js diff --git a/backend/static/codemirror/addon/runmode/runmode.js b/backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/runmode/runmode.js rename to backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode.js diff --git a/backend/static/codemirror/addon/runmode/runmode.node.js b/backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode.node.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/runmode/runmode.node.js rename to backend/_pv_1_3_5/static/codemirror/addon/runmode/runmode.node.js diff --git a/backend/static/codemirror/addon/scroll/annotatescrollbar.js b/backend/_pv_1_3_5/static/codemirror/addon/scroll/annotatescrollbar.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/scroll/annotatescrollbar.js rename to backend/_pv_1_3_5/static/codemirror/addon/scroll/annotatescrollbar.js diff --git a/backend/static/codemirror/addon/scroll/scrollpastend.js b/backend/_pv_1_3_5/static/codemirror/addon/scroll/scrollpastend.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/scroll/scrollpastend.js rename to backend/_pv_1_3_5/static/codemirror/addon/scroll/scrollpastend.js diff --git a/backend/static/codemirror/addon/scroll/simplescrollbars.css b/backend/_pv_1_3_5/static/codemirror/addon/scroll/simplescrollbars.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/scroll/simplescrollbars.css rename to backend/_pv_1_3_5/static/codemirror/addon/scroll/simplescrollbars.css diff --git a/backend/static/codemirror/addon/scroll/simplescrollbars.js b/backend/_pv_1_3_5/static/codemirror/addon/scroll/simplescrollbars.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/scroll/simplescrollbars.js rename to backend/_pv_1_3_5/static/codemirror/addon/scroll/simplescrollbars.js diff --git a/backend/static/codemirror/addon/search/jump-to-line.js b/backend/_pv_1_3_5/static/codemirror/addon/search/jump-to-line.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/jump-to-line.js rename to backend/_pv_1_3_5/static/codemirror/addon/search/jump-to-line.js diff --git a/backend/static/codemirror/addon/search/match-highlighter.js b/backend/_pv_1_3_5/static/codemirror/addon/search/match-highlighter.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/match-highlighter.js rename to backend/_pv_1_3_5/static/codemirror/addon/search/match-highlighter.js diff --git a/backend/static/codemirror/addon/search/matchesonscrollbar.css b/backend/_pv_1_3_5/static/codemirror/addon/search/matchesonscrollbar.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/matchesonscrollbar.css rename to backend/_pv_1_3_5/static/codemirror/addon/search/matchesonscrollbar.css diff --git a/backend/static/codemirror/addon/search/matchesonscrollbar.js b/backend/_pv_1_3_5/static/codemirror/addon/search/matchesonscrollbar.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/matchesonscrollbar.js rename to backend/_pv_1_3_5/static/codemirror/addon/search/matchesonscrollbar.js diff --git a/backend/static/codemirror/addon/search/search.js b/backend/_pv_1_3_5/static/codemirror/addon/search/search.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/search.js rename to backend/_pv_1_3_5/static/codemirror/addon/search/search.js diff --git a/backend/static/codemirror/addon/search/searchcursor.js b/backend/_pv_1_3_5/static/codemirror/addon/search/searchcursor.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/search/searchcursor.js rename to backend/_pv_1_3_5/static/codemirror/addon/search/searchcursor.js diff --git a/backend/static/codemirror/addon/selection/active-line.js b/backend/_pv_1_3_5/static/codemirror/addon/selection/active-line.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/selection/active-line.js rename to backend/_pv_1_3_5/static/codemirror/addon/selection/active-line.js diff --git a/backend/static/codemirror/addon/selection/mark-selection.js b/backend/_pv_1_3_5/static/codemirror/addon/selection/mark-selection.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/selection/mark-selection.js rename to backend/_pv_1_3_5/static/codemirror/addon/selection/mark-selection.js diff --git a/backend/static/codemirror/addon/selection/selection-pointer.js b/backend/_pv_1_3_5/static/codemirror/addon/selection/selection-pointer.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/selection/selection-pointer.js rename to backend/_pv_1_3_5/static/codemirror/addon/selection/selection-pointer.js diff --git a/backend/static/codemirror/addon/tern/tern.css b/backend/_pv_1_3_5/static/codemirror/addon/tern/tern.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/tern/tern.css rename to backend/_pv_1_3_5/static/codemirror/addon/tern/tern.css diff --git a/backend/static/codemirror/addon/tern/tern.js b/backend/_pv_1_3_5/static/codemirror/addon/tern/tern.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/tern/tern.js rename to backend/_pv_1_3_5/static/codemirror/addon/tern/tern.js diff --git a/backend/static/codemirror/addon/tern/worker.js b/backend/_pv_1_3_5/static/codemirror/addon/tern/worker.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/tern/worker.js rename to backend/_pv_1_3_5/static/codemirror/addon/tern/worker.js diff --git a/backend/static/codemirror/addon/wrap/hardwrap.js b/backend/_pv_1_3_5/static/codemirror/addon/wrap/hardwrap.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/addon/wrap/hardwrap.js rename to backend/_pv_1_3_5/static/codemirror/addon/wrap/hardwrap.js diff --git a/backend/static/codemirror/bin/authors.sh b/backend/_pv_1_3_5/static/codemirror/bin/authors.sh old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/authors.sh rename to backend/_pv_1_3_5/static/codemirror/bin/authors.sh diff --git a/backend/static/codemirror/bin/compress b/backend/_pv_1_3_5/static/codemirror/bin/compress old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/compress rename to backend/_pv_1_3_5/static/codemirror/bin/compress diff --git a/backend/static/codemirror/bin/lint b/backend/_pv_1_3_5/static/codemirror/bin/lint old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/lint rename to backend/_pv_1_3_5/static/codemirror/bin/lint diff --git a/backend/static/codemirror/bin/release b/backend/_pv_1_3_5/static/codemirror/bin/release old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/release rename to backend/_pv_1_3_5/static/codemirror/bin/release diff --git a/backend/static/codemirror/bin/source-highlight b/backend/_pv_1_3_5/static/codemirror/bin/source-highlight old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/source-highlight rename to backend/_pv_1_3_5/static/codemirror/bin/source-highlight diff --git a/backend/static/codemirror/bin/upload-release.js b/backend/_pv_1_3_5/static/codemirror/bin/upload-release.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bin/upload-release.js rename to backend/_pv_1_3_5/static/codemirror/bin/upload-release.js diff --git a/backend/static/codemirror/bower.json b/backend/_pv_1_3_5/static/codemirror/bower.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/bower.json rename to backend/_pv_1_3_5/static/codemirror/bower.json diff --git a/backend/static/codemirror/doc/activebookmark.js b/backend/_pv_1_3_5/static/codemirror/doc/activebookmark.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/activebookmark.js rename to backend/_pv_1_3_5/static/codemirror/doc/activebookmark.js diff --git a/backend/static/codemirror/doc/docs.css b/backend/_pv_1_3_5/static/codemirror/doc/docs.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/docs.css rename to backend/_pv_1_3_5/static/codemirror/doc/docs.css diff --git a/backend/static/codemirror/doc/internals.html b/backend/_pv_1_3_5/static/codemirror/doc/internals.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/internals.html rename to backend/_pv_1_3_5/static/codemirror/doc/internals.html diff --git a/backend/static/codemirror/doc/logo.png b/backend/_pv_1_3_5/static/codemirror/doc/logo.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/logo.png rename to backend/_pv_1_3_5/static/codemirror/doc/logo.png diff --git a/backend/static/codemirror/doc/logo.svg b/backend/_pv_1_3_5/static/codemirror/doc/logo.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/logo.svg rename to backend/_pv_1_3_5/static/codemirror/doc/logo.svg diff --git a/backend/static/codemirror/doc/manual.html b/backend/_pv_1_3_5/static/codemirror/doc/manual.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/manual.html rename to backend/_pv_1_3_5/static/codemirror/doc/manual.html diff --git a/backend/static/codemirror/doc/realworld.html b/backend/_pv_1_3_5/static/codemirror/doc/realworld.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/realworld.html rename to backend/_pv_1_3_5/static/codemirror/doc/realworld.html diff --git a/backend/static/codemirror/doc/releases.html b/backend/_pv_1_3_5/static/codemirror/doc/releases.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/releases.html rename to backend/_pv_1_3_5/static/codemirror/doc/releases.html diff --git a/backend/static/codemirror/doc/reporting.html b/backend/_pv_1_3_5/static/codemirror/doc/reporting.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/reporting.html rename to backend/_pv_1_3_5/static/codemirror/doc/reporting.html diff --git a/backend/static/codemirror/doc/upgrade_v2.2.html b/backend/_pv_1_3_5/static/codemirror/doc/upgrade_v2.2.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/upgrade_v2.2.html rename to backend/_pv_1_3_5/static/codemirror/doc/upgrade_v2.2.html diff --git a/backend/static/codemirror/doc/upgrade_v3.html b/backend/_pv_1_3_5/static/codemirror/doc/upgrade_v3.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/upgrade_v3.html rename to backend/_pv_1_3_5/static/codemirror/doc/upgrade_v3.html diff --git a/backend/static/codemirror/doc/upgrade_v4.html b/backend/_pv_1_3_5/static/codemirror/doc/upgrade_v4.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/upgrade_v4.html rename to backend/_pv_1_3_5/static/codemirror/doc/upgrade_v4.html diff --git a/backend/static/codemirror/doc/yinyang.png b/backend/_pv_1_3_5/static/codemirror/doc/yinyang.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/doc/yinyang.png rename to backend/_pv_1_3_5/static/codemirror/doc/yinyang.png diff --git a/backend/static/codemirror/index.html b/backend/_pv_1_3_5/static/codemirror/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/index.html rename to backend/_pv_1_3_5/static/codemirror/index.html diff --git a/backend/static/codemirror/keymap/emacs.js b/backend/_pv_1_3_5/static/codemirror/keymap/emacs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/keymap/emacs.js rename to backend/_pv_1_3_5/static/codemirror/keymap/emacs.js diff --git a/backend/static/codemirror/keymap/sublime.js b/backend/_pv_1_3_5/static/codemirror/keymap/sublime.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/keymap/sublime.js rename to backend/_pv_1_3_5/static/codemirror/keymap/sublime.js diff --git a/backend/static/codemirror/keymap/vim.js b/backend/_pv_1_3_5/static/codemirror/keymap/vim.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/keymap/vim.js rename to backend/_pv_1_3_5/static/codemirror/keymap/vim.js diff --git a/backend/static/codemirror/lib/codemirror.css b/backend/_pv_1_3_5/static/codemirror/lib/codemirror.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/lib/codemirror.css rename to backend/_pv_1_3_5/static/codemirror/lib/codemirror.css diff --git a/backend/static/codemirror/lib/codemirror.js b/backend/_pv_1_3_5/static/codemirror/lib/codemirror.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/lib/codemirror.js rename to backend/_pv_1_3_5/static/codemirror/lib/codemirror.js diff --git a/backend/static/codemirror/mode/apl/apl.js b/backend/_pv_1_3_5/static/codemirror/mode/apl/apl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/apl/apl.js rename to backend/_pv_1_3_5/static/codemirror/mode/apl/apl.js diff --git a/backend/static/codemirror/mode/apl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/apl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/apl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/apl/index.html diff --git a/backend/static/codemirror/mode/asciiarmor/asciiarmor.js b/backend/_pv_1_3_5/static/codemirror/mode/asciiarmor/asciiarmor.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asciiarmor/asciiarmor.js rename to backend/_pv_1_3_5/static/codemirror/mode/asciiarmor/asciiarmor.js diff --git a/backend/static/codemirror/mode/asciiarmor/index.html b/backend/_pv_1_3_5/static/codemirror/mode/asciiarmor/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asciiarmor/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/asciiarmor/index.html diff --git a/backend/static/codemirror/mode/asn.1/asn.1.js b/backend/_pv_1_3_5/static/codemirror/mode/asn.1/asn.1.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asn.1/asn.1.js rename to backend/_pv_1_3_5/static/codemirror/mode/asn.1/asn.1.js diff --git a/backend/static/codemirror/mode/asn.1/index.html b/backend/_pv_1_3_5/static/codemirror/mode/asn.1/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asn.1/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/asn.1/index.html diff --git a/backend/static/codemirror/mode/asterisk/asterisk.js b/backend/_pv_1_3_5/static/codemirror/mode/asterisk/asterisk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asterisk/asterisk.js rename to backend/_pv_1_3_5/static/codemirror/mode/asterisk/asterisk.js diff --git a/backend/static/codemirror/mode/asterisk/index.html b/backend/_pv_1_3_5/static/codemirror/mode/asterisk/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/asterisk/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/asterisk/index.html diff --git a/backend/static/codemirror/mode/brainfuck/brainfuck.js b/backend/_pv_1_3_5/static/codemirror/mode/brainfuck/brainfuck.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/brainfuck/brainfuck.js rename to backend/_pv_1_3_5/static/codemirror/mode/brainfuck/brainfuck.js diff --git a/backend/static/codemirror/mode/brainfuck/index.html b/backend/_pv_1_3_5/static/codemirror/mode/brainfuck/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/brainfuck/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/brainfuck/index.html diff --git a/backend/static/codemirror/mode/clike/clike.js b/backend/_pv_1_3_5/static/codemirror/mode/clike/clike.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clike/clike.js rename to backend/_pv_1_3_5/static/codemirror/mode/clike/clike.js diff --git a/backend/static/codemirror/mode/clike/index.html b/backend/_pv_1_3_5/static/codemirror/mode/clike/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clike/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/clike/index.html diff --git a/backend/static/codemirror/mode/clike/scala.html b/backend/_pv_1_3_5/static/codemirror/mode/clike/scala.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clike/scala.html rename to backend/_pv_1_3_5/static/codemirror/mode/clike/scala.html diff --git a/backend/static/codemirror/mode/clike/test.js b/backend/_pv_1_3_5/static/codemirror/mode/clike/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clike/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/clike/test.js diff --git a/backend/static/codemirror/mode/clojure/clojure.js b/backend/_pv_1_3_5/static/codemirror/mode/clojure/clojure.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clojure/clojure.js rename to backend/_pv_1_3_5/static/codemirror/mode/clojure/clojure.js diff --git a/backend/static/codemirror/mode/clojure/index.html b/backend/_pv_1_3_5/static/codemirror/mode/clojure/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/clojure/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/clojure/index.html diff --git a/backend/static/codemirror/mode/cmake/cmake.js b/backend/_pv_1_3_5/static/codemirror/mode/cmake/cmake.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cmake/cmake.js rename to backend/_pv_1_3_5/static/codemirror/mode/cmake/cmake.js diff --git a/backend/static/codemirror/mode/cmake/index.html b/backend/_pv_1_3_5/static/codemirror/mode/cmake/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cmake/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/cmake/index.html diff --git a/backend/static/codemirror/mode/cobol/cobol.js b/backend/_pv_1_3_5/static/codemirror/mode/cobol/cobol.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cobol/cobol.js rename to backend/_pv_1_3_5/static/codemirror/mode/cobol/cobol.js diff --git a/backend/static/codemirror/mode/cobol/index.html b/backend/_pv_1_3_5/static/codemirror/mode/cobol/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cobol/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/cobol/index.html diff --git a/backend/static/codemirror/mode/coffeescript/coffeescript.js b/backend/_pv_1_3_5/static/codemirror/mode/coffeescript/coffeescript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/coffeescript/coffeescript.js rename to backend/_pv_1_3_5/static/codemirror/mode/coffeescript/coffeescript.js diff --git a/backend/static/codemirror/mode/coffeescript/index.html b/backend/_pv_1_3_5/static/codemirror/mode/coffeescript/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/coffeescript/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/coffeescript/index.html diff --git a/backend/static/codemirror/mode/commonlisp/commonlisp.js b/backend/_pv_1_3_5/static/codemirror/mode/commonlisp/commonlisp.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/commonlisp/commonlisp.js rename to backend/_pv_1_3_5/static/codemirror/mode/commonlisp/commonlisp.js diff --git a/backend/static/codemirror/mode/commonlisp/index.html b/backend/_pv_1_3_5/static/codemirror/mode/commonlisp/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/commonlisp/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/commonlisp/index.html diff --git a/backend/static/codemirror/mode/crystal/crystal.js b/backend/_pv_1_3_5/static/codemirror/mode/crystal/crystal.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/crystal/crystal.js rename to backend/_pv_1_3_5/static/codemirror/mode/crystal/crystal.js diff --git a/backend/static/codemirror/mode/crystal/index.html b/backend/_pv_1_3_5/static/codemirror/mode/crystal/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/crystal/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/crystal/index.html diff --git a/backend/static/codemirror/mode/css/css.js b/backend/_pv_1_3_5/static/codemirror/mode/css/css.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/css.js rename to backend/_pv_1_3_5/static/codemirror/mode/css/css.js diff --git a/backend/static/codemirror/mode/css/gss.html b/backend/_pv_1_3_5/static/codemirror/mode/css/gss.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/gss.html rename to backend/_pv_1_3_5/static/codemirror/mode/css/gss.html diff --git a/backend/static/codemirror/mode/css/gss_test.js b/backend/_pv_1_3_5/static/codemirror/mode/css/gss_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/gss_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/css/gss_test.js diff --git a/backend/static/codemirror/mode/css/index.html b/backend/_pv_1_3_5/static/codemirror/mode/css/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/css/index.html diff --git a/backend/static/codemirror/mode/css/less.html b/backend/_pv_1_3_5/static/codemirror/mode/css/less.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/less.html rename to backend/_pv_1_3_5/static/codemirror/mode/css/less.html diff --git a/backend/static/codemirror/mode/css/less_test.js b/backend/_pv_1_3_5/static/codemirror/mode/css/less_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/less_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/css/less_test.js diff --git a/backend/static/codemirror/mode/css/scss.html b/backend/_pv_1_3_5/static/codemirror/mode/css/scss.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/scss.html rename to backend/_pv_1_3_5/static/codemirror/mode/css/scss.html diff --git a/backend/static/codemirror/mode/css/scss_test.js b/backend/_pv_1_3_5/static/codemirror/mode/css/scss_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/scss_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/css/scss_test.js diff --git a/backend/static/codemirror/mode/css/test.js b/backend/_pv_1_3_5/static/codemirror/mode/css/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/css/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/css/test.js diff --git a/backend/static/codemirror/mode/cypher/cypher.js b/backend/_pv_1_3_5/static/codemirror/mode/cypher/cypher.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cypher/cypher.js rename to backend/_pv_1_3_5/static/codemirror/mode/cypher/cypher.js diff --git a/backend/static/codemirror/mode/cypher/index.html b/backend/_pv_1_3_5/static/codemirror/mode/cypher/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cypher/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/cypher/index.html diff --git a/backend/static/codemirror/mode/cypher/test.js b/backend/_pv_1_3_5/static/codemirror/mode/cypher/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/cypher/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/cypher/test.js diff --git a/backend/static/codemirror/mode/d/d.js b/backend/_pv_1_3_5/static/codemirror/mode/d/d.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/d/d.js rename to backend/_pv_1_3_5/static/codemirror/mode/d/d.js diff --git a/backend/static/codemirror/mode/d/index.html b/backend/_pv_1_3_5/static/codemirror/mode/d/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/d/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/d/index.html diff --git a/backend/static/codemirror/mode/dart/dart.js b/backend/_pv_1_3_5/static/codemirror/mode/dart/dart.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dart/dart.js rename to backend/_pv_1_3_5/static/codemirror/mode/dart/dart.js diff --git a/backend/static/codemirror/mode/dart/index.html b/backend/_pv_1_3_5/static/codemirror/mode/dart/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dart/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/dart/index.html diff --git a/backend/static/codemirror/mode/diff/diff.js b/backend/_pv_1_3_5/static/codemirror/mode/diff/diff.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/diff/diff.js rename to backend/_pv_1_3_5/static/codemirror/mode/diff/diff.js diff --git a/backend/static/codemirror/mode/diff/index.html b/backend/_pv_1_3_5/static/codemirror/mode/diff/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/diff/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/diff/index.html diff --git a/backend/static/codemirror/mode/django/django.js b/backend/_pv_1_3_5/static/codemirror/mode/django/django.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/django/django.js rename to backend/_pv_1_3_5/static/codemirror/mode/django/django.js diff --git a/backend/static/codemirror/mode/django/index.html b/backend/_pv_1_3_5/static/codemirror/mode/django/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/django/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/django/index.html diff --git a/backend/static/codemirror/mode/dockerfile/dockerfile.js b/backend/_pv_1_3_5/static/codemirror/mode/dockerfile/dockerfile.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dockerfile/dockerfile.js rename to backend/_pv_1_3_5/static/codemirror/mode/dockerfile/dockerfile.js diff --git a/backend/static/codemirror/mode/dockerfile/index.html b/backend/_pv_1_3_5/static/codemirror/mode/dockerfile/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dockerfile/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/dockerfile/index.html diff --git a/backend/static/codemirror/mode/dtd/dtd.js b/backend/_pv_1_3_5/static/codemirror/mode/dtd/dtd.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dtd/dtd.js rename to backend/_pv_1_3_5/static/codemirror/mode/dtd/dtd.js diff --git a/backend/static/codemirror/mode/dtd/index.html b/backend/_pv_1_3_5/static/codemirror/mode/dtd/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dtd/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/dtd/index.html diff --git a/backend/static/codemirror/mode/dylan/dylan.js b/backend/_pv_1_3_5/static/codemirror/mode/dylan/dylan.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dylan/dylan.js rename to backend/_pv_1_3_5/static/codemirror/mode/dylan/dylan.js diff --git a/backend/static/codemirror/mode/dylan/index.html b/backend/_pv_1_3_5/static/codemirror/mode/dylan/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dylan/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/dylan/index.html diff --git a/backend/static/codemirror/mode/dylan/test.js b/backend/_pv_1_3_5/static/codemirror/mode/dylan/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/dylan/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/dylan/test.js diff --git a/backend/static/codemirror/mode/ebnf/ebnf.js b/backend/_pv_1_3_5/static/codemirror/mode/ebnf/ebnf.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ebnf/ebnf.js rename to backend/_pv_1_3_5/static/codemirror/mode/ebnf/ebnf.js diff --git a/backend/static/codemirror/mode/ebnf/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ebnf/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ebnf/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ebnf/index.html diff --git a/backend/static/codemirror/mode/ecl/ecl.js b/backend/_pv_1_3_5/static/codemirror/mode/ecl/ecl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ecl/ecl.js rename to backend/_pv_1_3_5/static/codemirror/mode/ecl/ecl.js diff --git a/backend/static/codemirror/mode/ecl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ecl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ecl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ecl/index.html diff --git a/backend/static/codemirror/mode/eiffel/eiffel.js b/backend/_pv_1_3_5/static/codemirror/mode/eiffel/eiffel.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/eiffel/eiffel.js rename to backend/_pv_1_3_5/static/codemirror/mode/eiffel/eiffel.js diff --git a/backend/static/codemirror/mode/eiffel/index.html b/backend/_pv_1_3_5/static/codemirror/mode/eiffel/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/eiffel/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/eiffel/index.html diff --git a/backend/static/codemirror/mode/elm/elm.js b/backend/_pv_1_3_5/static/codemirror/mode/elm/elm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/elm/elm.js rename to backend/_pv_1_3_5/static/codemirror/mode/elm/elm.js diff --git a/backend/static/codemirror/mode/elm/index.html b/backend/_pv_1_3_5/static/codemirror/mode/elm/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/elm/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/elm/index.html diff --git a/backend/static/codemirror/mode/erlang/erlang.js b/backend/_pv_1_3_5/static/codemirror/mode/erlang/erlang.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/erlang/erlang.js rename to backend/_pv_1_3_5/static/codemirror/mode/erlang/erlang.js diff --git a/backend/static/codemirror/mode/erlang/index.html b/backend/_pv_1_3_5/static/codemirror/mode/erlang/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/erlang/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/erlang/index.html diff --git a/backend/static/codemirror/mode/factor/factor.js b/backend/_pv_1_3_5/static/codemirror/mode/factor/factor.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/factor/factor.js rename to backend/_pv_1_3_5/static/codemirror/mode/factor/factor.js diff --git a/backend/static/codemirror/mode/factor/index.html b/backend/_pv_1_3_5/static/codemirror/mode/factor/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/factor/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/factor/index.html diff --git a/backend/static/codemirror/mode/fcl/fcl.js b/backend/_pv_1_3_5/static/codemirror/mode/fcl/fcl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/fcl/fcl.js rename to backend/_pv_1_3_5/static/codemirror/mode/fcl/fcl.js diff --git a/backend/static/codemirror/mode/fcl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/fcl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/fcl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/fcl/index.html diff --git a/backend/static/codemirror/mode/forth/forth.js b/backend/_pv_1_3_5/static/codemirror/mode/forth/forth.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/forth/forth.js rename to backend/_pv_1_3_5/static/codemirror/mode/forth/forth.js diff --git a/backend/static/codemirror/mode/forth/index.html b/backend/_pv_1_3_5/static/codemirror/mode/forth/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/forth/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/forth/index.html diff --git a/backend/static/codemirror/mode/fortran/fortran.js b/backend/_pv_1_3_5/static/codemirror/mode/fortran/fortran.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/fortran/fortran.js rename to backend/_pv_1_3_5/static/codemirror/mode/fortran/fortran.js diff --git a/backend/static/codemirror/mode/fortran/index.html b/backend/_pv_1_3_5/static/codemirror/mode/fortran/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/fortran/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/fortran/index.html diff --git a/backend/static/codemirror/mode/gas/gas.js b/backend/_pv_1_3_5/static/codemirror/mode/gas/gas.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gas/gas.js rename to backend/_pv_1_3_5/static/codemirror/mode/gas/gas.js diff --git a/backend/static/codemirror/mode/gas/index.html b/backend/_pv_1_3_5/static/codemirror/mode/gas/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gas/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/gas/index.html diff --git a/backend/static/codemirror/mode/gfm/gfm.js b/backend/_pv_1_3_5/static/codemirror/mode/gfm/gfm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gfm/gfm.js rename to backend/_pv_1_3_5/static/codemirror/mode/gfm/gfm.js diff --git a/backend/static/codemirror/mode/gfm/index.html b/backend/_pv_1_3_5/static/codemirror/mode/gfm/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gfm/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/gfm/index.html diff --git a/backend/static/codemirror/mode/gfm/test.js b/backend/_pv_1_3_5/static/codemirror/mode/gfm/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gfm/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/gfm/test.js diff --git a/backend/static/codemirror/mode/gherkin/gherkin.js b/backend/_pv_1_3_5/static/codemirror/mode/gherkin/gherkin.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gherkin/gherkin.js rename to backend/_pv_1_3_5/static/codemirror/mode/gherkin/gherkin.js diff --git a/backend/static/codemirror/mode/gherkin/index.html b/backend/_pv_1_3_5/static/codemirror/mode/gherkin/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/gherkin/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/gherkin/index.html diff --git a/backend/static/codemirror/mode/go/go.js b/backend/_pv_1_3_5/static/codemirror/mode/go/go.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/go/go.js rename to backend/_pv_1_3_5/static/codemirror/mode/go/go.js diff --git a/backend/static/codemirror/mode/go/index.html b/backend/_pv_1_3_5/static/codemirror/mode/go/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/go/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/go/index.html diff --git a/backend/static/codemirror/mode/groovy/groovy.js b/backend/_pv_1_3_5/static/codemirror/mode/groovy/groovy.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/groovy/groovy.js rename to backend/_pv_1_3_5/static/codemirror/mode/groovy/groovy.js diff --git a/backend/static/codemirror/mode/groovy/index.html b/backend/_pv_1_3_5/static/codemirror/mode/groovy/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/groovy/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/groovy/index.html diff --git a/backend/static/codemirror/mode/haml/haml.js b/backend/_pv_1_3_5/static/codemirror/mode/haml/haml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haml/haml.js rename to backend/_pv_1_3_5/static/codemirror/mode/haml/haml.js diff --git a/backend/static/codemirror/mode/haml/index.html b/backend/_pv_1_3_5/static/codemirror/mode/haml/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haml/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/haml/index.html diff --git a/backend/static/codemirror/mode/haml/test.js b/backend/_pv_1_3_5/static/codemirror/mode/haml/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haml/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/haml/test.js diff --git a/backend/static/codemirror/mode/handlebars/handlebars.js b/backend/_pv_1_3_5/static/codemirror/mode/handlebars/handlebars.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/handlebars/handlebars.js rename to backend/_pv_1_3_5/static/codemirror/mode/handlebars/handlebars.js diff --git a/backend/static/codemirror/mode/handlebars/index.html b/backend/_pv_1_3_5/static/codemirror/mode/handlebars/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/handlebars/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/handlebars/index.html diff --git a/backend/static/codemirror/mode/haskell-literate/haskell-literate.js b/backend/_pv_1_3_5/static/codemirror/mode/haskell-literate/haskell-literate.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haskell-literate/haskell-literate.js rename to backend/_pv_1_3_5/static/codemirror/mode/haskell-literate/haskell-literate.js diff --git a/backend/static/codemirror/mode/haskell-literate/index.html b/backend/_pv_1_3_5/static/codemirror/mode/haskell-literate/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haskell-literate/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/haskell-literate/index.html diff --git a/backend/static/codemirror/mode/haskell/haskell.js b/backend/_pv_1_3_5/static/codemirror/mode/haskell/haskell.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haskell/haskell.js rename to backend/_pv_1_3_5/static/codemirror/mode/haskell/haskell.js diff --git a/backend/static/codemirror/mode/haskell/index.html b/backend/_pv_1_3_5/static/codemirror/mode/haskell/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haskell/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/haskell/index.html diff --git a/backend/static/codemirror/mode/haxe/haxe.js b/backend/_pv_1_3_5/static/codemirror/mode/haxe/haxe.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haxe/haxe.js rename to backend/_pv_1_3_5/static/codemirror/mode/haxe/haxe.js diff --git a/backend/static/codemirror/mode/haxe/index.html b/backend/_pv_1_3_5/static/codemirror/mode/haxe/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/haxe/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/haxe/index.html diff --git a/backend/static/codemirror/mode/htmlembedded/htmlembedded.js b/backend/_pv_1_3_5/static/codemirror/mode/htmlembedded/htmlembedded.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/htmlembedded/htmlembedded.js rename to backend/_pv_1_3_5/static/codemirror/mode/htmlembedded/htmlembedded.js diff --git a/backend/static/codemirror/mode/htmlembedded/index.html b/backend/_pv_1_3_5/static/codemirror/mode/htmlembedded/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/htmlembedded/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/htmlembedded/index.html diff --git a/backend/static/codemirror/mode/htmlmixed/htmlmixed.js b/backend/_pv_1_3_5/static/codemirror/mode/htmlmixed/htmlmixed.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/htmlmixed/htmlmixed.js rename to backend/_pv_1_3_5/static/codemirror/mode/htmlmixed/htmlmixed.js diff --git a/backend/static/codemirror/mode/htmlmixed/index.html b/backend/_pv_1_3_5/static/codemirror/mode/htmlmixed/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/htmlmixed/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/htmlmixed/index.html diff --git a/backend/static/codemirror/mode/http/http.js b/backend/_pv_1_3_5/static/codemirror/mode/http/http.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/http/http.js rename to backend/_pv_1_3_5/static/codemirror/mode/http/http.js diff --git a/backend/static/codemirror/mode/http/index.html b/backend/_pv_1_3_5/static/codemirror/mode/http/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/http/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/http/index.html diff --git a/backend/static/codemirror/mode/idl/idl.js b/backend/_pv_1_3_5/static/codemirror/mode/idl/idl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/idl/idl.js rename to backend/_pv_1_3_5/static/codemirror/mode/idl/idl.js diff --git a/backend/static/codemirror/mode/idl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/idl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/idl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/idl/index.html diff --git a/backend/static/codemirror/mode/index.html b/backend/_pv_1_3_5/static/codemirror/mode/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/index.html diff --git a/backend/static/codemirror/mode/javascript/index.html b/backend/_pv_1_3_5/static/codemirror/mode/javascript/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/javascript/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/javascript/index.html diff --git a/backend/static/codemirror/mode/javascript/javascript.js b/backend/_pv_1_3_5/static/codemirror/mode/javascript/javascript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/javascript/javascript.js rename to backend/_pv_1_3_5/static/codemirror/mode/javascript/javascript.js diff --git a/backend/static/codemirror/mode/javascript/json-ld.html b/backend/_pv_1_3_5/static/codemirror/mode/javascript/json-ld.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/javascript/json-ld.html rename to backend/_pv_1_3_5/static/codemirror/mode/javascript/json-ld.html diff --git a/backend/static/codemirror/mode/javascript/test.js b/backend/_pv_1_3_5/static/codemirror/mode/javascript/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/javascript/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/javascript/test.js diff --git a/backend/static/codemirror/mode/javascript/typescript.html b/backend/_pv_1_3_5/static/codemirror/mode/javascript/typescript.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/javascript/typescript.html rename to backend/_pv_1_3_5/static/codemirror/mode/javascript/typescript.html diff --git a/backend/static/codemirror/mode/jinja2/index.html b/backend/_pv_1_3_5/static/codemirror/mode/jinja2/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/jinja2/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/jinja2/index.html diff --git a/backend/static/codemirror/mode/jinja2/jinja2.js b/backend/_pv_1_3_5/static/codemirror/mode/jinja2/jinja2.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/jinja2/jinja2.js rename to backend/_pv_1_3_5/static/codemirror/mode/jinja2/jinja2.js diff --git a/backend/static/codemirror/mode/jsx/index.html b/backend/_pv_1_3_5/static/codemirror/mode/jsx/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/jsx/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/jsx/index.html diff --git a/backend/static/codemirror/mode/jsx/jsx.js b/backend/_pv_1_3_5/static/codemirror/mode/jsx/jsx.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/jsx/jsx.js rename to backend/_pv_1_3_5/static/codemirror/mode/jsx/jsx.js diff --git a/backend/static/codemirror/mode/jsx/test.js b/backend/_pv_1_3_5/static/codemirror/mode/jsx/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/jsx/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/jsx/test.js diff --git a/backend/static/codemirror/mode/julia/index.html b/backend/_pv_1_3_5/static/codemirror/mode/julia/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/julia/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/julia/index.html diff --git a/backend/static/codemirror/mode/julia/julia.js b/backend/_pv_1_3_5/static/codemirror/mode/julia/julia.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/julia/julia.js rename to backend/_pv_1_3_5/static/codemirror/mode/julia/julia.js diff --git a/backend/static/codemirror/mode/livescript/index.html b/backend/_pv_1_3_5/static/codemirror/mode/livescript/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/livescript/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/livescript/index.html diff --git a/backend/static/codemirror/mode/livescript/livescript.js b/backend/_pv_1_3_5/static/codemirror/mode/livescript/livescript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/livescript/livescript.js rename to backend/_pv_1_3_5/static/codemirror/mode/livescript/livescript.js diff --git a/backend/static/codemirror/mode/lua/index.html b/backend/_pv_1_3_5/static/codemirror/mode/lua/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/lua/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/lua/index.html diff --git a/backend/static/codemirror/mode/lua/lua.js b/backend/_pv_1_3_5/static/codemirror/mode/lua/lua.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/lua/lua.js rename to backend/_pv_1_3_5/static/codemirror/mode/lua/lua.js diff --git a/backend/static/codemirror/mode/markdown/index.html b/backend/_pv_1_3_5/static/codemirror/mode/markdown/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/markdown/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/markdown/index.html diff --git a/backend/static/codemirror/mode/markdown/markdown.js b/backend/_pv_1_3_5/static/codemirror/mode/markdown/markdown.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/markdown/markdown.js rename to backend/_pv_1_3_5/static/codemirror/mode/markdown/markdown.js diff --git a/backend/static/codemirror/mode/markdown/test.js b/backend/_pv_1_3_5/static/codemirror/mode/markdown/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/markdown/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/markdown/test.js diff --git a/backend/static/codemirror/mode/mathematica/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mathematica/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mathematica/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mathematica/index.html diff --git a/backend/static/codemirror/mode/mathematica/mathematica.js b/backend/_pv_1_3_5/static/codemirror/mode/mathematica/mathematica.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mathematica/mathematica.js rename to backend/_pv_1_3_5/static/codemirror/mode/mathematica/mathematica.js diff --git a/backend/static/codemirror/mode/mbox/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mbox/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mbox/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mbox/index.html diff --git a/backend/static/codemirror/mode/mbox/mbox.js b/backend/_pv_1_3_5/static/codemirror/mode/mbox/mbox.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mbox/mbox.js rename to backend/_pv_1_3_5/static/codemirror/mode/mbox/mbox.js diff --git a/backend/static/codemirror/mode/meta.js b/backend/_pv_1_3_5/static/codemirror/mode/meta.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/meta.js rename to backend/_pv_1_3_5/static/codemirror/mode/meta.js diff --git a/backend/static/codemirror/mode/mirc/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mirc/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mirc/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mirc/index.html diff --git a/backend/static/codemirror/mode/mirc/mirc.js b/backend/_pv_1_3_5/static/codemirror/mode/mirc/mirc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mirc/mirc.js rename to backend/_pv_1_3_5/static/codemirror/mode/mirc/mirc.js diff --git a/backend/static/codemirror/mode/mllike/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mllike/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mllike/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mllike/index.html diff --git a/backend/static/codemirror/mode/mllike/mllike.js b/backend/_pv_1_3_5/static/codemirror/mode/mllike/mllike.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mllike/mllike.js rename to backend/_pv_1_3_5/static/codemirror/mode/mllike/mllike.js diff --git a/backend/static/codemirror/mode/modelica/index.html b/backend/_pv_1_3_5/static/codemirror/mode/modelica/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/modelica/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/modelica/index.html diff --git a/backend/static/codemirror/mode/modelica/modelica.js b/backend/_pv_1_3_5/static/codemirror/mode/modelica/modelica.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/modelica/modelica.js rename to backend/_pv_1_3_5/static/codemirror/mode/modelica/modelica.js diff --git a/backend/static/codemirror/mode/mscgen/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mscgen/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mscgen/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mscgen/index.html diff --git a/backend/static/codemirror/mode/mscgen/mscgen.js b/backend/_pv_1_3_5/static/codemirror/mode/mscgen/mscgen.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mscgen/mscgen.js rename to backend/_pv_1_3_5/static/codemirror/mode/mscgen/mscgen.js diff --git a/backend/static/codemirror/mode/mscgen/mscgen_test.js b/backend/_pv_1_3_5/static/codemirror/mode/mscgen/mscgen_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mscgen/mscgen_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/mscgen/mscgen_test.js diff --git a/backend/static/codemirror/mode/mscgen/msgenny_test.js b/backend/_pv_1_3_5/static/codemirror/mode/mscgen/msgenny_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mscgen/msgenny_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/mscgen/msgenny_test.js diff --git a/backend/static/codemirror/mode/mscgen/xu_test.js b/backend/_pv_1_3_5/static/codemirror/mode/mscgen/xu_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mscgen/xu_test.js rename to backend/_pv_1_3_5/static/codemirror/mode/mscgen/xu_test.js diff --git a/backend/static/codemirror/mode/mumps/index.html b/backend/_pv_1_3_5/static/codemirror/mode/mumps/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mumps/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/mumps/index.html diff --git a/backend/static/codemirror/mode/mumps/mumps.js b/backend/_pv_1_3_5/static/codemirror/mode/mumps/mumps.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/mumps/mumps.js rename to backend/_pv_1_3_5/static/codemirror/mode/mumps/mumps.js diff --git a/backend/static/codemirror/mode/nginx/index.html b/backend/_pv_1_3_5/static/codemirror/mode/nginx/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/nginx/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/nginx/index.html diff --git a/backend/static/codemirror/mode/nginx/nginx.js b/backend/_pv_1_3_5/static/codemirror/mode/nginx/nginx.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/nginx/nginx.js rename to backend/_pv_1_3_5/static/codemirror/mode/nginx/nginx.js diff --git a/backend/static/codemirror/mode/nsis/index.html b/backend/_pv_1_3_5/static/codemirror/mode/nsis/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/nsis/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/nsis/index.html diff --git a/backend/static/codemirror/mode/nsis/nsis.js b/backend/_pv_1_3_5/static/codemirror/mode/nsis/nsis.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/nsis/nsis.js rename to backend/_pv_1_3_5/static/codemirror/mode/nsis/nsis.js diff --git a/backend/static/codemirror/mode/ntriples/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ntriples/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ntriples/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ntriples/index.html diff --git a/backend/static/codemirror/mode/ntriples/ntriples.js b/backend/_pv_1_3_5/static/codemirror/mode/ntriples/ntriples.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ntriples/ntriples.js rename to backend/_pv_1_3_5/static/codemirror/mode/ntriples/ntriples.js diff --git a/backend/static/codemirror/mode/octave/index.html b/backend/_pv_1_3_5/static/codemirror/mode/octave/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/octave/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/octave/index.html diff --git a/backend/static/codemirror/mode/octave/octave.js b/backend/_pv_1_3_5/static/codemirror/mode/octave/octave.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/octave/octave.js rename to backend/_pv_1_3_5/static/codemirror/mode/octave/octave.js diff --git a/backend/static/codemirror/mode/oz/index.html b/backend/_pv_1_3_5/static/codemirror/mode/oz/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/oz/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/oz/index.html diff --git a/backend/static/codemirror/mode/oz/oz.js b/backend/_pv_1_3_5/static/codemirror/mode/oz/oz.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/oz/oz.js rename to backend/_pv_1_3_5/static/codemirror/mode/oz/oz.js diff --git a/backend/static/codemirror/mode/pascal/index.html b/backend/_pv_1_3_5/static/codemirror/mode/pascal/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pascal/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/pascal/index.html diff --git a/backend/static/codemirror/mode/pascal/pascal.js b/backend/_pv_1_3_5/static/codemirror/mode/pascal/pascal.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pascal/pascal.js rename to backend/_pv_1_3_5/static/codemirror/mode/pascal/pascal.js diff --git a/backend/static/codemirror/mode/pegjs/index.html b/backend/_pv_1_3_5/static/codemirror/mode/pegjs/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pegjs/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/pegjs/index.html diff --git a/backend/static/codemirror/mode/pegjs/pegjs.js b/backend/_pv_1_3_5/static/codemirror/mode/pegjs/pegjs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pegjs/pegjs.js rename to backend/_pv_1_3_5/static/codemirror/mode/pegjs/pegjs.js diff --git a/backend/static/codemirror/mode/perl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/perl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/perl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/perl/index.html diff --git a/backend/static/codemirror/mode/perl/perl.js b/backend/_pv_1_3_5/static/codemirror/mode/perl/perl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/perl/perl.js rename to backend/_pv_1_3_5/static/codemirror/mode/perl/perl.js diff --git a/backend/static/codemirror/mode/php/index.html b/backend/_pv_1_3_5/static/codemirror/mode/php/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/php/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/php/index.html diff --git a/backend/static/codemirror/mode/php/php.js b/backend/_pv_1_3_5/static/codemirror/mode/php/php.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/php/php.js rename to backend/_pv_1_3_5/static/codemirror/mode/php/php.js diff --git a/backend/static/codemirror/mode/php/test.js b/backend/_pv_1_3_5/static/codemirror/mode/php/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/php/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/php/test.js diff --git a/backend/static/codemirror/mode/pig/index.html b/backend/_pv_1_3_5/static/codemirror/mode/pig/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pig/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/pig/index.html diff --git a/backend/static/codemirror/mode/pig/pig.js b/backend/_pv_1_3_5/static/codemirror/mode/pig/pig.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pig/pig.js rename to backend/_pv_1_3_5/static/codemirror/mode/pig/pig.js diff --git a/backend/static/codemirror/mode/powershell/index.html b/backend/_pv_1_3_5/static/codemirror/mode/powershell/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/powershell/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/powershell/index.html diff --git a/backend/static/codemirror/mode/powershell/powershell.js b/backend/_pv_1_3_5/static/codemirror/mode/powershell/powershell.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/powershell/powershell.js rename to backend/_pv_1_3_5/static/codemirror/mode/powershell/powershell.js diff --git a/backend/static/codemirror/mode/powershell/test.js b/backend/_pv_1_3_5/static/codemirror/mode/powershell/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/powershell/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/powershell/test.js diff --git a/backend/static/codemirror/mode/properties/index.html b/backend/_pv_1_3_5/static/codemirror/mode/properties/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/properties/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/properties/index.html diff --git a/backend/static/codemirror/mode/properties/properties.js b/backend/_pv_1_3_5/static/codemirror/mode/properties/properties.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/properties/properties.js rename to backend/_pv_1_3_5/static/codemirror/mode/properties/properties.js diff --git a/backend/static/codemirror/mode/protobuf/index.html b/backend/_pv_1_3_5/static/codemirror/mode/protobuf/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/protobuf/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/protobuf/index.html diff --git a/backend/static/codemirror/mode/protobuf/protobuf.js b/backend/_pv_1_3_5/static/codemirror/mode/protobuf/protobuf.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/protobuf/protobuf.js rename to backend/_pv_1_3_5/static/codemirror/mode/protobuf/protobuf.js diff --git a/backend/static/codemirror/mode/pug/index.html b/backend/_pv_1_3_5/static/codemirror/mode/pug/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pug/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/pug/index.html diff --git a/backend/static/codemirror/mode/pug/pug.js b/backend/_pv_1_3_5/static/codemirror/mode/pug/pug.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/pug/pug.js rename to backend/_pv_1_3_5/static/codemirror/mode/pug/pug.js diff --git a/backend/static/codemirror/mode/puppet/index.html b/backend/_pv_1_3_5/static/codemirror/mode/puppet/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/puppet/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/puppet/index.html diff --git a/backend/static/codemirror/mode/puppet/puppet.js b/backend/_pv_1_3_5/static/codemirror/mode/puppet/puppet.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/puppet/puppet.js rename to backend/_pv_1_3_5/static/codemirror/mode/puppet/puppet.js diff --git a/backend/static/codemirror/mode/python/index.html b/backend/_pv_1_3_5/static/codemirror/mode/python/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/python/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/python/index.html diff --git a/backend/static/codemirror/mode/python/python.js b/backend/_pv_1_3_5/static/codemirror/mode/python/python.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/python/python.js rename to backend/_pv_1_3_5/static/codemirror/mode/python/python.js diff --git a/backend/static/codemirror/mode/python/test.js b/backend/_pv_1_3_5/static/codemirror/mode/python/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/python/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/python/test.js diff --git a/backend/static/codemirror/mode/q/index.html b/backend/_pv_1_3_5/static/codemirror/mode/q/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/q/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/q/index.html diff --git a/backend/static/codemirror/mode/q/q.js b/backend/_pv_1_3_5/static/codemirror/mode/q/q.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/q/q.js rename to backend/_pv_1_3_5/static/codemirror/mode/q/q.js diff --git a/backend/static/codemirror/mode/r/index.html b/backend/_pv_1_3_5/static/codemirror/mode/r/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/r/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/r/index.html diff --git a/backend/static/codemirror/mode/r/r.js b/backend/_pv_1_3_5/static/codemirror/mode/r/r.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/r/r.js rename to backend/_pv_1_3_5/static/codemirror/mode/r/r.js diff --git a/backend/static/codemirror/mode/rpm/changes/index.html b/backend/_pv_1_3_5/static/codemirror/mode/rpm/changes/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rpm/changes/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/rpm/changes/index.html diff --git a/backend/static/codemirror/mode/rpm/index.html b/backend/_pv_1_3_5/static/codemirror/mode/rpm/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rpm/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/rpm/index.html diff --git a/backend/static/codemirror/mode/rpm/rpm.js b/backend/_pv_1_3_5/static/codemirror/mode/rpm/rpm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rpm/rpm.js rename to backend/_pv_1_3_5/static/codemirror/mode/rpm/rpm.js diff --git a/backend/static/codemirror/mode/rst/index.html b/backend/_pv_1_3_5/static/codemirror/mode/rst/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rst/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/rst/index.html diff --git a/backend/static/codemirror/mode/rst/rst.js b/backend/_pv_1_3_5/static/codemirror/mode/rst/rst.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rst/rst.js rename to backend/_pv_1_3_5/static/codemirror/mode/rst/rst.js diff --git a/backend/static/codemirror/mode/ruby/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ruby/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ruby/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ruby/index.html diff --git a/backend/static/codemirror/mode/ruby/ruby.js b/backend/_pv_1_3_5/static/codemirror/mode/ruby/ruby.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ruby/ruby.js rename to backend/_pv_1_3_5/static/codemirror/mode/ruby/ruby.js diff --git a/backend/static/codemirror/mode/ruby/test.js b/backend/_pv_1_3_5/static/codemirror/mode/ruby/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ruby/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/ruby/test.js diff --git a/backend/static/codemirror/mode/rust/index.html b/backend/_pv_1_3_5/static/codemirror/mode/rust/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rust/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/rust/index.html diff --git a/backend/static/codemirror/mode/rust/rust.js b/backend/_pv_1_3_5/static/codemirror/mode/rust/rust.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rust/rust.js rename to backend/_pv_1_3_5/static/codemirror/mode/rust/rust.js diff --git a/backend/static/codemirror/mode/rust/test.js b/backend/_pv_1_3_5/static/codemirror/mode/rust/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/rust/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/rust/test.js diff --git a/backend/static/codemirror/mode/sas/index.html b/backend/_pv_1_3_5/static/codemirror/mode/sas/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sas/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/sas/index.html diff --git a/backend/static/codemirror/mode/sas/sas.js b/backend/_pv_1_3_5/static/codemirror/mode/sas/sas.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sas/sas.js rename to backend/_pv_1_3_5/static/codemirror/mode/sas/sas.js diff --git a/backend/static/codemirror/mode/sass/index.html b/backend/_pv_1_3_5/static/codemirror/mode/sass/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sass/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/sass/index.html diff --git a/backend/static/codemirror/mode/sass/sass.js b/backend/_pv_1_3_5/static/codemirror/mode/sass/sass.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sass/sass.js rename to backend/_pv_1_3_5/static/codemirror/mode/sass/sass.js diff --git a/backend/static/codemirror/mode/scheme/index.html b/backend/_pv_1_3_5/static/codemirror/mode/scheme/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/scheme/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/scheme/index.html diff --git a/backend/static/codemirror/mode/scheme/scheme.js b/backend/_pv_1_3_5/static/codemirror/mode/scheme/scheme.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/scheme/scheme.js rename to backend/_pv_1_3_5/static/codemirror/mode/scheme/scheme.js diff --git a/backend/static/codemirror/mode/shell/index.html b/backend/_pv_1_3_5/static/codemirror/mode/shell/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/shell/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/shell/index.html diff --git a/backend/static/codemirror/mode/shell/shell.js b/backend/_pv_1_3_5/static/codemirror/mode/shell/shell.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/shell/shell.js rename to backend/_pv_1_3_5/static/codemirror/mode/shell/shell.js diff --git a/backend/static/codemirror/mode/shell/test.js b/backend/_pv_1_3_5/static/codemirror/mode/shell/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/shell/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/shell/test.js diff --git a/backend/static/codemirror/mode/sieve/index.html b/backend/_pv_1_3_5/static/codemirror/mode/sieve/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sieve/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/sieve/index.html diff --git a/backend/static/codemirror/mode/sieve/sieve.js b/backend/_pv_1_3_5/static/codemirror/mode/sieve/sieve.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sieve/sieve.js rename to backend/_pv_1_3_5/static/codemirror/mode/sieve/sieve.js diff --git a/backend/static/codemirror/mode/slim/index.html b/backend/_pv_1_3_5/static/codemirror/mode/slim/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/slim/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/slim/index.html diff --git a/backend/static/codemirror/mode/slim/slim.js b/backend/_pv_1_3_5/static/codemirror/mode/slim/slim.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/slim/slim.js rename to backend/_pv_1_3_5/static/codemirror/mode/slim/slim.js diff --git a/backend/static/codemirror/mode/slim/test.js b/backend/_pv_1_3_5/static/codemirror/mode/slim/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/slim/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/slim/test.js diff --git a/backend/static/codemirror/mode/smalltalk/index.html b/backend/_pv_1_3_5/static/codemirror/mode/smalltalk/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/smalltalk/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/smalltalk/index.html diff --git a/backend/static/codemirror/mode/smalltalk/smalltalk.js b/backend/_pv_1_3_5/static/codemirror/mode/smalltalk/smalltalk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/smalltalk/smalltalk.js rename to backend/_pv_1_3_5/static/codemirror/mode/smalltalk/smalltalk.js diff --git a/backend/static/codemirror/mode/smarty/index.html b/backend/_pv_1_3_5/static/codemirror/mode/smarty/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/smarty/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/smarty/index.html diff --git a/backend/static/codemirror/mode/smarty/smarty.js b/backend/_pv_1_3_5/static/codemirror/mode/smarty/smarty.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/smarty/smarty.js rename to backend/_pv_1_3_5/static/codemirror/mode/smarty/smarty.js diff --git a/backend/static/codemirror/mode/solr/index.html b/backend/_pv_1_3_5/static/codemirror/mode/solr/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/solr/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/solr/index.html diff --git a/backend/static/codemirror/mode/solr/solr.js b/backend/_pv_1_3_5/static/codemirror/mode/solr/solr.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/solr/solr.js rename to backend/_pv_1_3_5/static/codemirror/mode/solr/solr.js diff --git a/backend/static/codemirror/mode/soy/index.html b/backend/_pv_1_3_5/static/codemirror/mode/soy/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/soy/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/soy/index.html diff --git a/backend/static/codemirror/mode/soy/soy.js b/backend/_pv_1_3_5/static/codemirror/mode/soy/soy.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/soy/soy.js rename to backend/_pv_1_3_5/static/codemirror/mode/soy/soy.js diff --git a/backend/static/codemirror/mode/soy/test.js b/backend/_pv_1_3_5/static/codemirror/mode/soy/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/soy/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/soy/test.js diff --git a/backend/static/codemirror/mode/sparql/index.html b/backend/_pv_1_3_5/static/codemirror/mode/sparql/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sparql/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/sparql/index.html diff --git a/backend/static/codemirror/mode/sparql/sparql.js b/backend/_pv_1_3_5/static/codemirror/mode/sparql/sparql.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sparql/sparql.js rename to backend/_pv_1_3_5/static/codemirror/mode/sparql/sparql.js diff --git a/backend/static/codemirror/mode/spreadsheet/index.html b/backend/_pv_1_3_5/static/codemirror/mode/spreadsheet/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/spreadsheet/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/spreadsheet/index.html diff --git a/backend/static/codemirror/mode/spreadsheet/spreadsheet.js b/backend/_pv_1_3_5/static/codemirror/mode/spreadsheet/spreadsheet.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/spreadsheet/spreadsheet.js rename to backend/_pv_1_3_5/static/codemirror/mode/spreadsheet/spreadsheet.js diff --git a/backend/static/codemirror/mode/sql/index.html b/backend/_pv_1_3_5/static/codemirror/mode/sql/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sql/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/sql/index.html diff --git a/backend/static/codemirror/mode/sql/sql.js b/backend/_pv_1_3_5/static/codemirror/mode/sql/sql.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/sql/sql.js rename to backend/_pv_1_3_5/static/codemirror/mode/sql/sql.js diff --git a/backend/static/codemirror/mode/stex/index.html b/backend/_pv_1_3_5/static/codemirror/mode/stex/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/stex/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/stex/index.html diff --git a/backend/static/codemirror/mode/stex/stex.js b/backend/_pv_1_3_5/static/codemirror/mode/stex/stex.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/stex/stex.js rename to backend/_pv_1_3_5/static/codemirror/mode/stex/stex.js diff --git a/backend/static/codemirror/mode/stex/test.js b/backend/_pv_1_3_5/static/codemirror/mode/stex/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/stex/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/stex/test.js diff --git a/backend/static/codemirror/mode/stylus/index.html b/backend/_pv_1_3_5/static/codemirror/mode/stylus/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/stylus/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/stylus/index.html diff --git a/backend/static/codemirror/mode/stylus/stylus.js b/backend/_pv_1_3_5/static/codemirror/mode/stylus/stylus.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/stylus/stylus.js rename to backend/_pv_1_3_5/static/codemirror/mode/stylus/stylus.js diff --git a/backend/static/codemirror/mode/swift/index.html b/backend/_pv_1_3_5/static/codemirror/mode/swift/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/swift/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/swift/index.html diff --git a/backend/static/codemirror/mode/swift/swift.js b/backend/_pv_1_3_5/static/codemirror/mode/swift/swift.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/swift/swift.js rename to backend/_pv_1_3_5/static/codemirror/mode/swift/swift.js diff --git a/backend/static/codemirror/mode/swift/test.js b/backend/_pv_1_3_5/static/codemirror/mode/swift/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/swift/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/swift/test.js diff --git a/backend/static/codemirror/mode/tcl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/tcl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tcl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/tcl/index.html diff --git a/backend/static/codemirror/mode/tcl/tcl.js b/backend/_pv_1_3_5/static/codemirror/mode/tcl/tcl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tcl/tcl.js rename to backend/_pv_1_3_5/static/codemirror/mode/tcl/tcl.js diff --git a/backend/static/codemirror/mode/textile/index.html b/backend/_pv_1_3_5/static/codemirror/mode/textile/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/textile/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/textile/index.html diff --git a/backend/static/codemirror/mode/textile/test.js b/backend/_pv_1_3_5/static/codemirror/mode/textile/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/textile/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/textile/test.js diff --git a/backend/static/codemirror/mode/textile/textile.js b/backend/_pv_1_3_5/static/codemirror/mode/textile/textile.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/textile/textile.js rename to backend/_pv_1_3_5/static/codemirror/mode/textile/textile.js diff --git a/backend/static/codemirror/mode/tiddlywiki/index.html b/backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiddlywiki/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/index.html diff --git a/backend/static/codemirror/mode/tiddlywiki/tiddlywiki.css b/backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/tiddlywiki.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiddlywiki/tiddlywiki.css rename to backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/tiddlywiki.css diff --git a/backend/static/codemirror/mode/tiddlywiki/tiddlywiki.js b/backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/tiddlywiki.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiddlywiki/tiddlywiki.js rename to backend/_pv_1_3_5/static/codemirror/mode/tiddlywiki/tiddlywiki.js diff --git a/backend/static/codemirror/mode/tiki/index.html b/backend/_pv_1_3_5/static/codemirror/mode/tiki/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiki/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/tiki/index.html diff --git a/backend/static/codemirror/mode/tiki/tiki.css b/backend/_pv_1_3_5/static/codemirror/mode/tiki/tiki.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiki/tiki.css rename to backend/_pv_1_3_5/static/codemirror/mode/tiki/tiki.css diff --git a/backend/static/codemirror/mode/tiki/tiki.js b/backend/_pv_1_3_5/static/codemirror/mode/tiki/tiki.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tiki/tiki.js rename to backend/_pv_1_3_5/static/codemirror/mode/tiki/tiki.js diff --git a/backend/static/codemirror/mode/toml/index.html b/backend/_pv_1_3_5/static/codemirror/mode/toml/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/toml/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/toml/index.html diff --git a/backend/static/codemirror/mode/toml/toml.js b/backend/_pv_1_3_5/static/codemirror/mode/toml/toml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/toml/toml.js rename to backend/_pv_1_3_5/static/codemirror/mode/toml/toml.js diff --git a/backend/static/codemirror/mode/tornado/index.html b/backend/_pv_1_3_5/static/codemirror/mode/tornado/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tornado/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/tornado/index.html diff --git a/backend/static/codemirror/mode/tornado/tornado.js b/backend/_pv_1_3_5/static/codemirror/mode/tornado/tornado.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/tornado/tornado.js rename to backend/_pv_1_3_5/static/codemirror/mode/tornado/tornado.js diff --git a/backend/static/codemirror/mode/troff/index.html b/backend/_pv_1_3_5/static/codemirror/mode/troff/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/troff/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/troff/index.html diff --git a/backend/static/codemirror/mode/troff/troff.js b/backend/_pv_1_3_5/static/codemirror/mode/troff/troff.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/troff/troff.js rename to backend/_pv_1_3_5/static/codemirror/mode/troff/troff.js diff --git a/backend/static/codemirror/mode/ttcn-cfg/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ttcn-cfg/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ttcn-cfg/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ttcn-cfg/index.html diff --git a/backend/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js b/backend/_pv_1_3_5/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js rename to backend/_pv_1_3_5/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js diff --git a/backend/static/codemirror/mode/ttcn/index.html b/backend/_pv_1_3_5/static/codemirror/mode/ttcn/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ttcn/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/ttcn/index.html diff --git a/backend/static/codemirror/mode/ttcn/ttcn.js b/backend/_pv_1_3_5/static/codemirror/mode/ttcn/ttcn.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/ttcn/ttcn.js rename to backend/_pv_1_3_5/static/codemirror/mode/ttcn/ttcn.js diff --git a/backend/static/codemirror/mode/turtle/index.html b/backend/_pv_1_3_5/static/codemirror/mode/turtle/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/turtle/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/turtle/index.html diff --git a/backend/static/codemirror/mode/turtle/turtle.js b/backend/_pv_1_3_5/static/codemirror/mode/turtle/turtle.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/turtle/turtle.js rename to backend/_pv_1_3_5/static/codemirror/mode/turtle/turtle.js diff --git a/backend/static/codemirror/mode/twig/index.html b/backend/_pv_1_3_5/static/codemirror/mode/twig/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/twig/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/twig/index.html diff --git a/backend/static/codemirror/mode/twig/twig.js b/backend/_pv_1_3_5/static/codemirror/mode/twig/twig.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/twig/twig.js rename to backend/_pv_1_3_5/static/codemirror/mode/twig/twig.js diff --git a/backend/static/codemirror/mode/vb/index.html b/backend/_pv_1_3_5/static/codemirror/mode/vb/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vb/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/vb/index.html diff --git a/backend/static/codemirror/mode/vb/vb.js b/backend/_pv_1_3_5/static/codemirror/mode/vb/vb.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vb/vb.js rename to backend/_pv_1_3_5/static/codemirror/mode/vb/vb.js diff --git a/backend/static/codemirror/mode/vbscript/index.html b/backend/_pv_1_3_5/static/codemirror/mode/vbscript/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vbscript/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/vbscript/index.html diff --git a/backend/static/codemirror/mode/vbscript/vbscript.js b/backend/_pv_1_3_5/static/codemirror/mode/vbscript/vbscript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vbscript/vbscript.js rename to backend/_pv_1_3_5/static/codemirror/mode/vbscript/vbscript.js diff --git a/backend/static/codemirror/mode/velocity/index.html b/backend/_pv_1_3_5/static/codemirror/mode/velocity/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/velocity/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/velocity/index.html diff --git a/backend/static/codemirror/mode/velocity/velocity.js b/backend/_pv_1_3_5/static/codemirror/mode/velocity/velocity.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/velocity/velocity.js rename to backend/_pv_1_3_5/static/codemirror/mode/velocity/velocity.js diff --git a/backend/static/codemirror/mode/verilog/index.html b/backend/_pv_1_3_5/static/codemirror/mode/verilog/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/verilog/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/verilog/index.html diff --git a/backend/static/codemirror/mode/verilog/test.js b/backend/_pv_1_3_5/static/codemirror/mode/verilog/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/verilog/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/verilog/test.js diff --git a/backend/static/codemirror/mode/verilog/verilog.js b/backend/_pv_1_3_5/static/codemirror/mode/verilog/verilog.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/verilog/verilog.js rename to backend/_pv_1_3_5/static/codemirror/mode/verilog/verilog.js diff --git a/backend/static/codemirror/mode/vhdl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/vhdl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vhdl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/vhdl/index.html diff --git a/backend/static/codemirror/mode/vhdl/vhdl.js b/backend/_pv_1_3_5/static/codemirror/mode/vhdl/vhdl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vhdl/vhdl.js rename to backend/_pv_1_3_5/static/codemirror/mode/vhdl/vhdl.js diff --git a/backend/static/codemirror/mode/vue/index.html b/backend/_pv_1_3_5/static/codemirror/mode/vue/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vue/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/vue/index.html diff --git a/backend/static/codemirror/mode/vue/vue.js b/backend/_pv_1_3_5/static/codemirror/mode/vue/vue.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/vue/vue.js rename to backend/_pv_1_3_5/static/codemirror/mode/vue/vue.js diff --git a/backend/static/codemirror/mode/webidl/index.html b/backend/_pv_1_3_5/static/codemirror/mode/webidl/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/webidl/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/webidl/index.html diff --git a/backend/static/codemirror/mode/webidl/webidl.js b/backend/_pv_1_3_5/static/codemirror/mode/webidl/webidl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/webidl/webidl.js rename to backend/_pv_1_3_5/static/codemirror/mode/webidl/webidl.js diff --git a/backend/static/codemirror/mode/xml/index.html b/backend/_pv_1_3_5/static/codemirror/mode/xml/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xml/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/xml/index.html diff --git a/backend/static/codemirror/mode/xml/test.js b/backend/_pv_1_3_5/static/codemirror/mode/xml/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xml/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/xml/test.js diff --git a/backend/static/codemirror/mode/xml/xml.js b/backend/_pv_1_3_5/static/codemirror/mode/xml/xml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xml/xml.js rename to backend/_pv_1_3_5/static/codemirror/mode/xml/xml.js diff --git a/backend/static/codemirror/mode/xquery/index.html b/backend/_pv_1_3_5/static/codemirror/mode/xquery/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xquery/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/xquery/index.html diff --git a/backend/static/codemirror/mode/xquery/test.js b/backend/_pv_1_3_5/static/codemirror/mode/xquery/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xquery/test.js rename to backend/_pv_1_3_5/static/codemirror/mode/xquery/test.js diff --git a/backend/static/codemirror/mode/xquery/xquery.js b/backend/_pv_1_3_5/static/codemirror/mode/xquery/xquery.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/xquery/xquery.js rename to backend/_pv_1_3_5/static/codemirror/mode/xquery/xquery.js diff --git a/backend/static/codemirror/mode/yacas/index.html b/backend/_pv_1_3_5/static/codemirror/mode/yacas/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yacas/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/yacas/index.html diff --git a/backend/static/codemirror/mode/yacas/yacas.js b/backend/_pv_1_3_5/static/codemirror/mode/yacas/yacas.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yacas/yacas.js rename to backend/_pv_1_3_5/static/codemirror/mode/yacas/yacas.js diff --git a/backend/static/codemirror/mode/yaml-frontmatter/index.html b/backend/_pv_1_3_5/static/codemirror/mode/yaml-frontmatter/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yaml-frontmatter/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/yaml-frontmatter/index.html diff --git a/backend/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js b/backend/_pv_1_3_5/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js rename to backend/_pv_1_3_5/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js diff --git a/backend/static/codemirror/mode/yaml/index.html b/backend/_pv_1_3_5/static/codemirror/mode/yaml/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yaml/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/yaml/index.html diff --git a/backend/static/codemirror/mode/yaml/yaml.js b/backend/_pv_1_3_5/static/codemirror/mode/yaml/yaml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/yaml/yaml.js rename to backend/_pv_1_3_5/static/codemirror/mode/yaml/yaml.js diff --git a/backend/static/codemirror/mode/z80/index.html b/backend/_pv_1_3_5/static/codemirror/mode/z80/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/z80/index.html rename to backend/_pv_1_3_5/static/codemirror/mode/z80/index.html diff --git a/backend/static/codemirror/mode/z80/z80.js b/backend/_pv_1_3_5/static/codemirror/mode/z80/z80.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/mode/z80/z80.js rename to backend/_pv_1_3_5/static/codemirror/mode/z80/z80.js diff --git a/backend/static/codemirror/package.json b/backend/_pv_1_3_5/static/codemirror/package.json old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/package.json rename to backend/_pv_1_3_5/static/codemirror/package.json diff --git a/backend/static/codemirror/rollup.config.js b/backend/_pv_1_3_5/static/codemirror/rollup.config.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/rollup.config.js rename to backend/_pv_1_3_5/static/codemirror/rollup.config.js diff --git a/backend/static/codemirror/test/comment_test.js b/backend/_pv_1_3_5/static/codemirror/test/comment_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/comment_test.js rename to backend/_pv_1_3_5/static/codemirror/test/comment_test.js diff --git a/backend/static/codemirror/test/doc_test.js b/backend/_pv_1_3_5/static/codemirror/test/doc_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/doc_test.js rename to backend/_pv_1_3_5/static/codemirror/test/doc_test.js diff --git a/backend/static/codemirror/test/driver.js b/backend/_pv_1_3_5/static/codemirror/test/driver.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/driver.js rename to backend/_pv_1_3_5/static/codemirror/test/driver.js diff --git a/backend/static/codemirror/test/emacs_test.js b/backend/_pv_1_3_5/static/codemirror/test/emacs_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/emacs_test.js rename to backend/_pv_1_3_5/static/codemirror/test/emacs_test.js diff --git a/backend/static/codemirror/test/index.html b/backend/_pv_1_3_5/static/codemirror/test/index.html old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/index.html rename to backend/_pv_1_3_5/static/codemirror/test/index.html diff --git a/backend/static/codemirror/test/lint.js b/backend/_pv_1_3_5/static/codemirror/test/lint.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/lint.js rename to backend/_pv_1_3_5/static/codemirror/test/lint.js diff --git a/backend/static/codemirror/test/mode_test.css b/backend/_pv_1_3_5/static/codemirror/test/mode_test.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/mode_test.css rename to backend/_pv_1_3_5/static/codemirror/test/mode_test.css diff --git a/backend/static/codemirror/test/mode_test.js b/backend/_pv_1_3_5/static/codemirror/test/mode_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/mode_test.js rename to backend/_pv_1_3_5/static/codemirror/test/mode_test.js diff --git a/backend/static/codemirror/test/multi_test.js b/backend/_pv_1_3_5/static/codemirror/test/multi_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/multi_test.js rename to backend/_pv_1_3_5/static/codemirror/test/multi_test.js diff --git a/backend/static/codemirror/test/phantom_driver.js b/backend/_pv_1_3_5/static/codemirror/test/phantom_driver.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/phantom_driver.js rename to backend/_pv_1_3_5/static/codemirror/test/phantom_driver.js diff --git a/backend/static/codemirror/test/run.js b/backend/_pv_1_3_5/static/codemirror/test/run.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/run.js rename to backend/_pv_1_3_5/static/codemirror/test/run.js diff --git a/backend/static/codemirror/test/scroll_test.js b/backend/_pv_1_3_5/static/codemirror/test/scroll_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/scroll_test.js rename to backend/_pv_1_3_5/static/codemirror/test/scroll_test.js diff --git a/backend/static/codemirror/test/search_test.js b/backend/_pv_1_3_5/static/codemirror/test/search_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/search_test.js rename to backend/_pv_1_3_5/static/codemirror/test/search_test.js diff --git a/backend/static/codemirror/test/sql-hint-test.js b/backend/_pv_1_3_5/static/codemirror/test/sql-hint-test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/sql-hint-test.js rename to backend/_pv_1_3_5/static/codemirror/test/sql-hint-test.js diff --git a/backend/static/codemirror/test/sublime_test.js b/backend/_pv_1_3_5/static/codemirror/test/sublime_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/sublime_test.js rename to backend/_pv_1_3_5/static/codemirror/test/sublime_test.js diff --git a/backend/static/codemirror/test/test.js b/backend/_pv_1_3_5/static/codemirror/test/test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/test.js rename to backend/_pv_1_3_5/static/codemirror/test/test.js diff --git a/backend/static/codemirror/test/vim_test.js b/backend/_pv_1_3_5/static/codemirror/test/vim_test.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/test/vim_test.js rename to backend/_pv_1_3_5/static/codemirror/test/vim_test.js diff --git a/backend/static/codemirror/theme/3024-day.css b/backend/_pv_1_3_5/static/codemirror/theme/3024-day.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/3024-day.css rename to backend/_pv_1_3_5/static/codemirror/theme/3024-day.css diff --git a/backend/static/codemirror/theme/3024-night.css b/backend/_pv_1_3_5/static/codemirror/theme/3024-night.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/3024-night.css rename to backend/_pv_1_3_5/static/codemirror/theme/3024-night.css diff --git a/backend/static/codemirror/theme/abcdef.css b/backend/_pv_1_3_5/static/codemirror/theme/abcdef.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/abcdef.css rename to backend/_pv_1_3_5/static/codemirror/theme/abcdef.css diff --git a/backend/static/codemirror/theme/ambiance-mobile.css b/backend/_pv_1_3_5/static/codemirror/theme/ambiance-mobile.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/ambiance-mobile.css rename to backend/_pv_1_3_5/static/codemirror/theme/ambiance-mobile.css diff --git a/backend/static/codemirror/theme/ambiance.css b/backend/_pv_1_3_5/static/codemirror/theme/ambiance.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/ambiance.css rename to backend/_pv_1_3_5/static/codemirror/theme/ambiance.css diff --git a/backend/static/codemirror/theme/base16-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/base16-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/base16-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/base16-dark.css diff --git a/backend/static/codemirror/theme/base16-light.css b/backend/_pv_1_3_5/static/codemirror/theme/base16-light.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/base16-light.css rename to backend/_pv_1_3_5/static/codemirror/theme/base16-light.css diff --git a/backend/static/codemirror/theme/bespin.css b/backend/_pv_1_3_5/static/codemirror/theme/bespin.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/bespin.css rename to backend/_pv_1_3_5/static/codemirror/theme/bespin.css diff --git a/backend/static/codemirror/theme/blackboard.css b/backend/_pv_1_3_5/static/codemirror/theme/blackboard.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/blackboard.css rename to backend/_pv_1_3_5/static/codemirror/theme/blackboard.css diff --git a/backend/static/codemirror/theme/cobalt.css b/backend/_pv_1_3_5/static/codemirror/theme/cobalt.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/cobalt.css rename to backend/_pv_1_3_5/static/codemirror/theme/cobalt.css diff --git a/backend/static/codemirror/theme/colorforth.css b/backend/_pv_1_3_5/static/codemirror/theme/colorforth.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/colorforth.css rename to backend/_pv_1_3_5/static/codemirror/theme/colorforth.css diff --git a/backend/static/codemirror/theme/dracula.css b/backend/_pv_1_3_5/static/codemirror/theme/dracula.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/dracula.css rename to backend/_pv_1_3_5/static/codemirror/theme/dracula.css diff --git a/backend/static/codemirror/theme/duotone-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/duotone-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/duotone-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/duotone-dark.css diff --git a/backend/static/codemirror/theme/duotone-light.css b/backend/_pv_1_3_5/static/codemirror/theme/duotone-light.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/duotone-light.css rename to backend/_pv_1_3_5/static/codemirror/theme/duotone-light.css diff --git a/backend/static/codemirror/theme/eclipse.css b/backend/_pv_1_3_5/static/codemirror/theme/eclipse.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/eclipse.css rename to backend/_pv_1_3_5/static/codemirror/theme/eclipse.css diff --git a/backend/static/codemirror/theme/elegant.css b/backend/_pv_1_3_5/static/codemirror/theme/elegant.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/elegant.css rename to backend/_pv_1_3_5/static/codemirror/theme/elegant.css diff --git a/backend/static/codemirror/theme/erlang-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/erlang-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/erlang-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/erlang-dark.css diff --git a/backend/static/codemirror/theme/hopscotch.css b/backend/_pv_1_3_5/static/codemirror/theme/hopscotch.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/hopscotch.css rename to backend/_pv_1_3_5/static/codemirror/theme/hopscotch.css diff --git a/backend/static/codemirror/theme/icecoder.css b/backend/_pv_1_3_5/static/codemirror/theme/icecoder.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/icecoder.css rename to backend/_pv_1_3_5/static/codemirror/theme/icecoder.css diff --git a/backend/static/codemirror/theme/isotope.css b/backend/_pv_1_3_5/static/codemirror/theme/isotope.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/isotope.css rename to backend/_pv_1_3_5/static/codemirror/theme/isotope.css diff --git a/backend/static/codemirror/theme/lesser-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/lesser-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/lesser-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/lesser-dark.css diff --git a/backend/static/codemirror/theme/liquibyte.css b/backend/_pv_1_3_5/static/codemirror/theme/liquibyte.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/liquibyte.css rename to backend/_pv_1_3_5/static/codemirror/theme/liquibyte.css diff --git a/backend/static/codemirror/theme/material.css b/backend/_pv_1_3_5/static/codemirror/theme/material.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/material.css rename to backend/_pv_1_3_5/static/codemirror/theme/material.css diff --git a/backend/static/codemirror/theme/mbo.css b/backend/_pv_1_3_5/static/codemirror/theme/mbo.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/mbo.css rename to backend/_pv_1_3_5/static/codemirror/theme/mbo.css diff --git a/backend/static/codemirror/theme/mdn-like.css b/backend/_pv_1_3_5/static/codemirror/theme/mdn-like.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/mdn-like.css rename to backend/_pv_1_3_5/static/codemirror/theme/mdn-like.css diff --git a/backend/static/codemirror/theme/midnight.css b/backend/_pv_1_3_5/static/codemirror/theme/midnight.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/midnight.css rename to backend/_pv_1_3_5/static/codemirror/theme/midnight.css diff --git a/backend/static/codemirror/theme/monokai.css b/backend/_pv_1_3_5/static/codemirror/theme/monokai.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/monokai.css rename to backend/_pv_1_3_5/static/codemirror/theme/monokai.css diff --git a/backend/static/codemirror/theme/neat.css b/backend/_pv_1_3_5/static/codemirror/theme/neat.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/neat.css rename to backend/_pv_1_3_5/static/codemirror/theme/neat.css diff --git a/backend/static/codemirror/theme/neo.css b/backend/_pv_1_3_5/static/codemirror/theme/neo.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/neo.css rename to backend/_pv_1_3_5/static/codemirror/theme/neo.css diff --git a/backend/static/codemirror/theme/night.css b/backend/_pv_1_3_5/static/codemirror/theme/night.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/night.css rename to backend/_pv_1_3_5/static/codemirror/theme/night.css diff --git a/backend/static/codemirror/theme/panda-syntax.css b/backend/_pv_1_3_5/static/codemirror/theme/panda-syntax.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/panda-syntax.css rename to backend/_pv_1_3_5/static/codemirror/theme/panda-syntax.css diff --git a/backend/static/codemirror/theme/paraiso-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/paraiso-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/paraiso-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/paraiso-dark.css diff --git a/backend/static/codemirror/theme/paraiso-light.css b/backend/_pv_1_3_5/static/codemirror/theme/paraiso-light.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/paraiso-light.css rename to backend/_pv_1_3_5/static/codemirror/theme/paraiso-light.css diff --git a/backend/static/codemirror/theme/pastel-on-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/pastel-on-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/pastel-on-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/pastel-on-dark.css diff --git a/backend/static/codemirror/theme/railscasts.css b/backend/_pv_1_3_5/static/codemirror/theme/railscasts.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/railscasts.css rename to backend/_pv_1_3_5/static/codemirror/theme/railscasts.css diff --git a/backend/static/codemirror/theme/rubyblue.css b/backend/_pv_1_3_5/static/codemirror/theme/rubyblue.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/rubyblue.css rename to backend/_pv_1_3_5/static/codemirror/theme/rubyblue.css diff --git a/backend/static/codemirror/theme/seti.css b/backend/_pv_1_3_5/static/codemirror/theme/seti.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/seti.css rename to backend/_pv_1_3_5/static/codemirror/theme/seti.css diff --git a/backend/static/codemirror/theme/solarized.css b/backend/_pv_1_3_5/static/codemirror/theme/solarized.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/solarized.css rename to backend/_pv_1_3_5/static/codemirror/theme/solarized.css diff --git a/backend/static/codemirror/theme/the-matrix.css b/backend/_pv_1_3_5/static/codemirror/theme/the-matrix.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/the-matrix.css rename to backend/_pv_1_3_5/static/codemirror/theme/the-matrix.css diff --git a/backend/static/codemirror/theme/tomorrow-night-bright.css b/backend/_pv_1_3_5/static/codemirror/theme/tomorrow-night-bright.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/tomorrow-night-bright.css rename to backend/_pv_1_3_5/static/codemirror/theme/tomorrow-night-bright.css diff --git a/backend/static/codemirror/theme/tomorrow-night-eighties.css b/backend/_pv_1_3_5/static/codemirror/theme/tomorrow-night-eighties.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/tomorrow-night-eighties.css rename to backend/_pv_1_3_5/static/codemirror/theme/tomorrow-night-eighties.css diff --git a/backend/static/codemirror/theme/ttcn.css b/backend/_pv_1_3_5/static/codemirror/theme/ttcn.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/ttcn.css rename to backend/_pv_1_3_5/static/codemirror/theme/ttcn.css diff --git a/backend/static/codemirror/theme/twilight.css b/backend/_pv_1_3_5/static/codemirror/theme/twilight.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/twilight.css rename to backend/_pv_1_3_5/static/codemirror/theme/twilight.css diff --git a/backend/static/codemirror/theme/vibrant-ink.css b/backend/_pv_1_3_5/static/codemirror/theme/vibrant-ink.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/vibrant-ink.css rename to backend/_pv_1_3_5/static/codemirror/theme/vibrant-ink.css diff --git a/backend/static/codemirror/theme/xq-dark.css b/backend/_pv_1_3_5/static/codemirror/theme/xq-dark.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/xq-dark.css rename to backend/_pv_1_3_5/static/codemirror/theme/xq-dark.css diff --git a/backend/static/codemirror/theme/xq-light.css b/backend/_pv_1_3_5/static/codemirror/theme/xq-light.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/xq-light.css rename to backend/_pv_1_3_5/static/codemirror/theme/xq-light.css diff --git a/backend/static/codemirror/theme/yeti.css b/backend/_pv_1_3_5/static/codemirror/theme/yeti.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/yeti.css rename to backend/_pv_1_3_5/static/codemirror/theme/yeti.css diff --git a/backend/static/codemirror/theme/zenburn.css b/backend/_pv_1_3_5/static/codemirror/theme/zenburn.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/codemirror/theme/zenburn.css rename to backend/_pv_1_3_5/static/codemirror/theme/zenburn.css diff --git a/backend/static/css/bootstrap-reload.css b/backend/_pv_1_3_5/static/css/bootstrap-reload.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-reload.css rename to backend/_pv_1_3_5/static/css/bootstrap-reload.css diff --git a/backend/static/css/bootstrap-theme.css b/backend/_pv_1_3_5/static/css/bootstrap-theme.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-theme.css rename to backend/_pv_1_3_5/static/css/bootstrap-theme.css diff --git a/backend/static/css/bootstrap-theme.css.map b/backend/_pv_1_3_5/static/css/bootstrap-theme.css.map old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-theme.css.map rename to backend/_pv_1_3_5/static/css/bootstrap-theme.css.map diff --git a/backend/static/css/bootstrap-theme.min.css b/backend/_pv_1_3_5/static/css/bootstrap-theme.min.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-theme.min.css rename to backend/_pv_1_3_5/static/css/bootstrap-theme.min.css diff --git a/backend/static/css/bootstrap-theme.min.css.map b/backend/_pv_1_3_5/static/css/bootstrap-theme.min.css.map old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-theme.min.css.map rename to backend/_pv_1_3_5/static/css/bootstrap-theme.min.css.map diff --git a/backend/static/css/bootstrap-treeview.css b/backend/_pv_1_3_5/static/css/bootstrap-treeview.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-treeview.css rename to backend/_pv_1_3_5/static/css/bootstrap-treeview.css diff --git a/backend/static/css/bootstrap-treeview.min.css b/backend/_pv_1_3_5/static/css/bootstrap-treeview.min.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap-treeview.min.css rename to backend/_pv_1_3_5/static/css/bootstrap-treeview.min.css diff --git a/backend/static/css/bootstrap.css b/backend/_pv_1_3_5/static/css/bootstrap.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap.css rename to backend/_pv_1_3_5/static/css/bootstrap.css diff --git a/backend/static/css/bootstrap.css.map b/backend/_pv_1_3_5/static/css/bootstrap.css.map old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap.css.map rename to backend/_pv_1_3_5/static/css/bootstrap.css.map diff --git a/backend/static/css/bootstrap.min.css b/backend/_pv_1_3_5/static/css/bootstrap.min.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap.min.css rename to backend/_pv_1_3_5/static/css/bootstrap.min.css diff --git a/backend/static/css/bootstrap.min.css.map b/backend/_pv_1_3_5/static/css/bootstrap.min.css.map old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/bootstrap.min.css.map rename to backend/_pv_1_3_5/static/css/bootstrap.min.css.map diff --git a/backend/static/css/font-awesome.css b/backend/_pv_1_3_5/static/css/font-awesome.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/font-awesome.css rename to backend/_pv_1_3_5/static/css/font-awesome.css diff --git a/backend/static/css/font-awesome.min.css b/backend/_pv_1_3_5/static/css/font-awesome.min.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/css/font-awesome.min.css rename to backend/_pv_1_3_5/static/css/font-awesome.min.css diff --git a/backend/static/fonts/FontAwesome.otf b/backend/_pv_1_3_5/static/fonts/FontAwesome.otf old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/FontAwesome.otf rename to backend/_pv_1_3_5/static/fonts/FontAwesome.otf diff --git a/backend/static/fonts/fontawesome-webfont.eot b/backend/_pv_1_3_5/static/fonts/fontawesome-webfont.eot old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/fontawesome-webfont.eot rename to backend/_pv_1_3_5/static/fonts/fontawesome-webfont.eot diff --git a/backend/static/fonts/fontawesome-webfont.svg b/backend/_pv_1_3_5/static/fonts/fontawesome-webfont.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/fontawesome-webfont.svg rename to backend/_pv_1_3_5/static/fonts/fontawesome-webfont.svg diff --git a/backend/static/fonts/fontawesome-webfont.ttf b/backend/_pv_1_3_5/static/fonts/fontawesome-webfont.ttf old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/fontawesome-webfont.ttf rename to backend/_pv_1_3_5/static/fonts/fontawesome-webfont.ttf diff --git a/backend/static/fonts/fontawesome-webfont.woff b/backend/_pv_1_3_5/static/fonts/fontawesome-webfont.woff old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/fontawesome-webfont.woff rename to backend/_pv_1_3_5/static/fonts/fontawesome-webfont.woff diff --git a/backend/static/fonts/fontawesome-webfont.woff2 b/backend/_pv_1_3_5/static/fonts/fontawesome-webfont.woff2 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/fontawesome-webfont.woff2 rename to backend/_pv_1_3_5/static/fonts/fontawesome-webfont.woff2 diff --git a/backend/static/fonts/glyphicons-halflings-regular.eot b/backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.eot old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/glyphicons-halflings-regular.eot rename to backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.eot diff --git a/backend/static/fonts/glyphicons-halflings-regular.svg b/backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/glyphicons-halflings-regular.svg rename to backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.svg diff --git a/backend/static/fonts/glyphicons-halflings-regular.ttf b/backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.ttf old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/glyphicons-halflings-regular.ttf rename to backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.ttf diff --git a/backend/static/fonts/glyphicons-halflings-regular.woff b/backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.woff old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/glyphicons-halflings-regular.woff rename to backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.woff diff --git a/backend/static/fonts/glyphicons-halflings-regular.woff2 b/backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.woff2 old mode 100644 new mode 100755 similarity index 100% rename from backend/static/fonts/glyphicons-halflings-regular.woff2 rename to backend/_pv_1_3_5/static/fonts/glyphicons-halflings-regular.woff2 diff --git a/backend/static/img/NIC.svg b/backend/_pv_1_3_5/static/img/NIC.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/NIC.svg rename to backend/_pv_1_3_5/static/img/NIC.svg diff --git a/backend/static/img/cache.svg b/backend/_pv_1_3_5/static/img/cache.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/cache.svg rename to backend/_pv_1_3_5/static/img/cache.svg diff --git a/backend/static/img/clock.svg b/backend/_pv_1_3_5/static/img/clock.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/clock.svg rename to backend/_pv_1_3_5/static/img/clock.svg diff --git a/backend/static/img/cpu.svg b/backend/_pv_1_3_5/static/img/cpu.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/cpu.svg rename to backend/_pv_1_3_5/static/img/cpu.svg diff --git a/backend/static/img/db_backup.svg b/backend/_pv_1_3_5/static/img/db_backup.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/db_backup.svg rename to backend/_pv_1_3_5/static/img/db_backup.svg diff --git a/backend/static/img/favicon.ico b/backend/_pv_1_3_5/static/img/favicon.ico old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/favicon.ico rename to backend/_pv_1_3_5/static/img/favicon.ico diff --git a/backend/static/img/hd.svg b/backend/_pv_1_3_5/static/img/hd.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/hd.svg rename to backend/_pv_1_3_5/static/img/hd.svg diff --git a/backend/static/img/home.svg b/backend/_pv_1_3_5/static/img/home.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/home.svg rename to backend/_pv_1_3_5/static/img/home.svg diff --git a/backend/static/img/knxd.svg b/backend/_pv_1_3_5/static/img/knxd.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/knxd.svg rename to backend/_pv_1_3_5/static/img/knxd.svg diff --git a/backend/static/img/knxd_service.png b/backend/_pv_1_3_5/static/img/knxd_service.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/knxd_service.png rename to backend/_pv_1_3_5/static/img/knxd_service.png diff --git a/backend/static/img/knxd_socket.png b/backend/_pv_1_3_5/static/img/knxd_socket.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/knxd_socket.png rename to backend/_pv_1_3_5/static/img/knxd_socket.png diff --git a/backend/static/img/languages.svg b/backend/_pv_1_3_5/static/img/languages.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/languages.svg rename to backend/_pv_1_3_5/static/img/languages.svg diff --git a/backend/static/img/logfile.svg b/backend/_pv_1_3_5/static/img/logfile.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logfile.svg rename to backend/_pv_1_3_5/static/img/logfile.svg diff --git a/backend/static/img/logo_big.png b/backend/_pv_1_3_5/static/img/logo_big.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_big.png rename to backend/_pv_1_3_5/static/img/logo_big.png diff --git a/backend/static/img/logo_long.png b/backend/_pv_1_3_5/static/img/logo_long.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_long.png rename to backend/_pv_1_3_5/static/img/logo_long.png diff --git a/backend/static/img/logo_small_120x120.png b/backend/_pv_1_3_5/static/img/logo_small_120x120.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_small_120x120.png rename to backend/_pv_1_3_5/static/img/logo_small_120x120.png diff --git a/backend/static/img/logo_small_152x152.png b/backend/_pv_1_3_5/static/img/logo_small_152x152.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_small_152x152.png rename to backend/_pv_1_3_5/static/img/logo_small_152x152.png diff --git a/backend/static/img/logo_small_32x32.png b/backend/_pv_1_3_5/static/img/logo_small_32x32.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_small_32x32.png rename to backend/_pv_1_3_5/static/img/logo_small_32x32.png diff --git a/backend/static/img/logo_small_76x76.png b/backend/_pv_1_3_5/static/img/logo_small_76x76.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/logo_small_76x76.png rename to backend/_pv_1_3_5/static/img/logo_small_76x76.png diff --git a/backend/static/img/password.svg b/backend/_pv_1_3_5/static/img/password.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/password.svg rename to backend/_pv_1_3_5/static/img/password.svg diff --git a/backend/static/img/preferences.svg b/backend/_pv_1_3_5/static/img/preferences.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/preferences.svg rename to backend/_pv_1_3_5/static/img/preferences.svg diff --git a/backend/static/img/python.png b/backend/_pv_1_3_5/static/img/python.png old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/python.png rename to backend/_pv_1_3_5/static/img/python.png diff --git a/backend/static/img/reboot.svg b/backend/_pv_1_3_5/static/img/reboot.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/reboot.svg rename to backend/_pv_1_3_5/static/img/reboot.svg diff --git a/backend/static/img/terminal-server.svg b/backend/_pv_1_3_5/static/img/terminal-server.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/terminal-server.svg rename to backend/_pv_1_3_5/static/img/terminal-server.svg diff --git a/backend/static/img/tux_hdd.svg b/backend/_pv_1_3_5/static/img/tux_hdd.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/tux_hdd.svg rename to backend/_pv_1_3_5/static/img/tux_hdd.svg diff --git a/backend/static/img/user.svg b/backend/_pv_1_3_5/static/img/user.svg old mode 100644 new mode 100755 similarity index 100% rename from backend/static/img/user.svg rename to backend/_pv_1_3_5/static/img/user.svg diff --git a/backend/static/js/backend.js b/backend/_pv_1_3_5/static/js/backend.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/backend.js rename to backend/_pv_1_3_5/static/js/backend.js diff --git a/backend/static/js/bootstrap-reload.js b/backend/_pv_1_3_5/static/js/bootstrap-reload.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap-reload.js rename to backend/_pv_1_3_5/static/js/bootstrap-reload.js diff --git a/backend/static/js/bootstrap-reload.min.js b/backend/_pv_1_3_5/static/js/bootstrap-reload.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap-reload.min.js rename to backend/_pv_1_3_5/static/js/bootstrap-reload.min.js diff --git a/backend/static/js/bootstrap-treeview.js b/backend/_pv_1_3_5/static/js/bootstrap-treeview.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap-treeview.js rename to backend/_pv_1_3_5/static/js/bootstrap-treeview.js diff --git a/backend/static/js/bootstrap-treeview.min.js b/backend/_pv_1_3_5/static/js/bootstrap-treeview.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap-treeview.min.js rename to backend/_pv_1_3_5/static/js/bootstrap-treeview.min.js diff --git a/backend/static/js/bootstrap.js b/backend/_pv_1_3_5/static/js/bootstrap.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap.js rename to backend/_pv_1_3_5/static/js/bootstrap.js diff --git a/backend/static/js/bootstrap.min.js b/backend/_pv_1_3_5/static/js/bootstrap.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/bootstrap.min.js rename to backend/_pv_1_3_5/static/js/bootstrap.min.js diff --git a/backend/static/js/google-prettify/lang-aea.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-aea.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-aea.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-aea.js diff --git a/backend/static/js/google-prettify/lang-agc.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-agc.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-agc.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-agc.js diff --git a/backend/static/js/google-prettify/lang-apollo.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-apollo.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-apollo.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-apollo.js diff --git a/backend/static/js/google-prettify/lang-basic.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-basic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-basic.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-basic.js diff --git a/backend/static/js/google-prettify/lang-cbm.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-cbm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-cbm.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-cbm.js diff --git a/backend/static/js/google-prettify/lang-cl.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-cl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-cl.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-cl.js diff --git a/backend/static/js/google-prettify/lang-clj.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-clj.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-clj.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-clj.js diff --git a/backend/static/js/google-prettify/lang-css.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-css.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-css.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-css.js diff --git a/backend/static/js/google-prettify/lang-dart.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-dart.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-dart.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-dart.js diff --git a/backend/static/js/google-prettify/lang-el.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-el.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-el.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-el.js diff --git a/backend/static/js/google-prettify/lang-erl.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-erl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-erl.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-erl.js diff --git a/backend/static/js/google-prettify/lang-erlang.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-erlang.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-erlang.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-erlang.js diff --git a/backend/static/js/google-prettify/lang-fs.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-fs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-fs.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-fs.js diff --git a/backend/static/js/google-prettify/lang-go.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-go.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-go.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-go.js diff --git a/backend/static/js/google-prettify/lang-hs.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-hs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-hs.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-hs.js diff --git a/backend/static/js/google-prettify/lang-lasso.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lasso.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lasso.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lasso.js diff --git a/backend/static/js/google-prettify/lang-lassoscript.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lassoscript.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lassoscript.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lassoscript.js diff --git a/backend/static/js/google-prettify/lang-latex.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-latex.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-latex.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-latex.js diff --git a/backend/static/js/google-prettify/lang-lgt.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lgt.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lgt.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lgt.js diff --git a/backend/static/js/google-prettify/lang-lisp.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lisp.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lisp.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lisp.js diff --git a/backend/static/js/google-prettify/lang-ll.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-ll.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-ll.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-ll.js diff --git a/backend/static/js/google-prettify/lang-llvm.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-llvm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-llvm.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-llvm.js diff --git a/backend/static/js/google-prettify/lang-logtalk.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-logtalk.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-logtalk.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-logtalk.js diff --git a/backend/static/js/google-prettify/lang-ls.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-ls.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-ls.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-ls.js diff --git a/backend/static/js/google-prettify/lang-lsp.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lsp.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lsp.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lsp.js diff --git a/backend/static/js/google-prettify/lang-lua.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-lua.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-lua.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-lua.js diff --git a/backend/static/js/google-prettify/lang-matlab.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-matlab.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-matlab.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-matlab.js diff --git a/backend/static/js/google-prettify/lang-ml.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-ml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-ml.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-ml.js diff --git a/backend/static/js/google-prettify/lang-mumps.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-mumps.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-mumps.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-mumps.js diff --git a/backend/static/js/google-prettify/lang-n.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-n.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-n.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-n.js diff --git a/backend/static/js/google-prettify/lang-nemerle.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-nemerle.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-nemerle.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-nemerle.js diff --git a/backend/static/js/google-prettify/lang-pascal.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-pascal.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-pascal.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-pascal.js diff --git a/backend/static/js/google-prettify/lang-proto.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-proto.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-proto.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-proto.js diff --git a/backend/static/js/google-prettify/lang-r.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-r.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-r.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-r.js diff --git a/backend/static/js/google-prettify/lang-rd.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-rd.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-rd.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-rd.js diff --git a/backend/static/js/google-prettify/lang-rkt.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-rkt.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-rkt.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-rkt.js diff --git a/backend/static/js/google-prettify/lang-rust.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-rust.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-rust.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-rust.js diff --git a/backend/static/js/google-prettify/lang-s.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-s.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-s.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-s.js diff --git a/backend/static/js/google-prettify/lang-scala.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-scala.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-scala.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-scala.js diff --git a/backend/static/js/google-prettify/lang-scm.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-scm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-scm.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-scm.js diff --git a/backend/static/js/google-prettify/lang-splus.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-splus.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-splus.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-splus.js diff --git a/backend/static/js/google-prettify/lang-sql.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-sql.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-sql.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-sql.js diff --git a/backend/static/js/google-prettify/lang-ss.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-ss.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-ss.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-ss.js diff --git a/backend/static/js/google-prettify/lang-swift.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-swift.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-swift.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-swift.js diff --git a/backend/static/js/google-prettify/lang-tcl.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-tcl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-tcl.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-tcl.js diff --git a/backend/static/js/google-prettify/lang-tex.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-tex.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-tex.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-tex.js diff --git a/backend/static/js/google-prettify/lang-vb.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-vb.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-vb.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-vb.js diff --git a/backend/static/js/google-prettify/lang-vbs.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-vbs.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-vbs.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-vbs.js diff --git a/backend/static/js/google-prettify/lang-vhd.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-vhd.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-vhd.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-vhd.js diff --git a/backend/static/js/google-prettify/lang-vhdl.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-vhdl.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-vhdl.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-vhdl.js diff --git a/backend/static/js/google-prettify/lang-wiki.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-wiki.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-wiki.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-wiki.js diff --git a/backend/static/js/google-prettify/lang-xq.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-xq.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-xq.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-xq.js diff --git a/backend/static/js/google-prettify/lang-xquery.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-xquery.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-xquery.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-xquery.js diff --git a/backend/static/js/google-prettify/lang-yaml.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-yaml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-yaml.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-yaml.js diff --git a/backend/static/js/google-prettify/lang-yml.js b/backend/_pv_1_3_5/static/js/google-prettify/lang-yml.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/lang-yml.js rename to backend/_pv_1_3_5/static/js/google-prettify/lang-yml.js diff --git a/backend/static/js/google-prettify/prettify.css b/backend/_pv_1_3_5/static/js/google-prettify/prettify.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/prettify.css rename to backend/_pv_1_3_5/static/js/google-prettify/prettify.css diff --git a/backend/static/js/google-prettify/prettify.js b/backend/_pv_1_3_5/static/js/google-prettify/prettify.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/prettify.js rename to backend/_pv_1_3_5/static/js/google-prettify/prettify.js diff --git a/backend/static/js/google-prettify/run_prettify.js b/backend/_pv_1_3_5/static/js/google-prettify/run_prettify.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/run_prettify.js rename to backend/_pv_1_3_5/static/js/google-prettify/run_prettify.js diff --git a/backend/static/js/google-prettify/skins/desert.css b/backend/_pv_1_3_5/static/js/google-prettify/skins/desert.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/skins/desert.css rename to backend/_pv_1_3_5/static/js/google-prettify/skins/desert.css diff --git a/backend/static/js/google-prettify/skins/doxy.css b/backend/_pv_1_3_5/static/js/google-prettify/skins/doxy.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/skins/doxy.css rename to backend/_pv_1_3_5/static/js/google-prettify/skins/doxy.css diff --git a/backend/static/js/google-prettify/skins/sons-of-obsidian.css b/backend/_pv_1_3_5/static/js/google-prettify/skins/sons-of-obsidian.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/skins/sons-of-obsidian.css rename to backend/_pv_1_3_5/static/js/google-prettify/skins/sons-of-obsidian.css diff --git a/backend/static/js/google-prettify/skins/sunburst.css b/backend/_pv_1_3_5/static/js/google-prettify/skins/sunburst.css old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/google-prettify/skins/sunburst.css rename to backend/_pv_1_3_5/static/js/google-prettify/skins/sunburst.css diff --git a/backend/static/js/jquery-3.2.1.js b/backend/_pv_1_3_5/static/js/jquery-3.2.1.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/jquery-3.2.1.js rename to backend/_pv_1_3_5/static/js/jquery-3.2.1.js diff --git a/backend/static/js/jquery-3.2.1.min.js b/backend/_pv_1_3_5/static/js/jquery-3.2.1.min.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/jquery-3.2.1.min.js rename to backend/_pv_1_3_5/static/js/jquery-3.2.1.min.js diff --git a/backend/static/js/logics_blockly_code.js b/backend/_pv_1_3_5/static/js/logics_blockly_code.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/logics_blockly_code.js rename to backend/_pv_1_3_5/static/js/logics_blockly_code.js diff --git a/backend/static/js/npm.js b/backend/_pv_1_3_5/static/js/npm.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/js/npm.js rename to backend/_pv_1_3_5/static/js/npm.js diff --git a/backend/static/shblocks/sh_items.js b/backend/_pv_1_3_5/static/shblocks/sh_items.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_items.js rename to backend/_pv_1_3_5/static/shblocks/sh_items.js diff --git a/backend/static/shblocks/sh_logic.js b/backend/_pv_1_3_5/static/shblocks/sh_logic.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_logic.js rename to backend/_pv_1_3_5/static/shblocks/sh_logic.js diff --git a/backend/static/shblocks/sh_notify.js b/backend/_pv_1_3_5/static/shblocks/sh_notify.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_notify.js rename to backend/_pv_1_3_5/static/shblocks/sh_notify.js diff --git a/backend/static/shblocks/sh_time.js b/backend/_pv_1_3_5/static/shblocks/sh_time.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_time.js rename to backend/_pv_1_3_5/static/shblocks/sh_time.js diff --git a/backend/static/shblocks/sh_tools.js b/backend/_pv_1_3_5/static/shblocks/sh_tools.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_tools.js rename to backend/_pv_1_3_5/static/shblocks/sh_tools.js diff --git a/backend/static/shblocks/sh_trigger.js b/backend/_pv_1_3_5/static/shblocks/sh_trigger.js old mode 100644 new mode 100755 similarity index 100% rename from backend/static/shblocks/sh_trigger.js rename to backend/_pv_1_3_5/static/shblocks/sh_trigger.js diff --git a/backend/templates/base.html b/backend/_pv_1_3_5/templates/base.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/base.html rename to backend/_pv_1_3_5/templates/base.html diff --git a/backend/templates/conf_yaml_converter.html b/backend/_pv_1_3_5/templates/conf_yaml_converter.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/conf_yaml_converter.html rename to backend/_pv_1_3_5/templates/conf_yaml_converter.html diff --git a/backend/templates/disclosure.html b/backend/_pv_1_3_5/templates/disclosure.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/disclosure.html rename to backend/_pv_1_3_5/templates/disclosure.html diff --git a/backend/templates/items.html b/backend/_pv_1_3_5/templates/items.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/items.html rename to backend/_pv_1_3_5/templates/items.html diff --git a/backend/templates/log_view.html b/backend/_pv_1_3_5/templates/log_view.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/log_view.html rename to backend/_pv_1_3_5/templates/log_view.html diff --git a/backend/templates/logging.html b/backend/_pv_1_3_5/templates/logging.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/logging.html rename to backend/_pv_1_3_5/templates/logging.html diff --git a/backend/templates/logics.html b/backend/_pv_1_3_5/templates/logics.html old mode 100644 new mode 100755 similarity index 95% rename from backend/templates/logics.html rename to backend/_pv_1_3_5/templates/logics.html index f9d3a8f65..161136391 --- a/backend/templates/logics.html +++ b/backend/_pv_1_3_5/templates/logics.html @@ -62,7 +62,16 @@ - {{ logic.watch_items }} + +
+
{{ _('Watch_Items') }}
+
+ {% for value in logic.watch_items %} + {{ value }}
+ {% endfor %} +
+
+ {% endif %} {% endfor %} diff --git a/backend/templates/logics_blockly.html b/backend/_pv_1_3_5/templates/logics_blockly.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/logics_blockly.html rename to backend/_pv_1_3_5/templates/logics_blockly.html diff --git a/backend/templates/logics_blockly_toolbox.html b/backend/_pv_1_3_5/templates/logics_blockly_toolbox.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/logics_blockly_toolbox.html rename to backend/_pv_1_3_5/templates/logics_blockly_toolbox.html diff --git a/backend/_pv_1_3_5/templates/logics_view.html b/backend/_pv_1_3_5/templates/logics_view.html new file mode 100755 index 000000000..ec4927766 --- /dev/null +++ b/backend/_pv_1_3_5/templates/logics_view.html @@ -0,0 +1,79 @@ + +{% extends "base.html" %} +{% import "navbar.html" as nav with context %} +{% block navbar %} + {{ nav }} +{% endblock navbar %} + +{% block content %} + + + + +
+

SmartHomeNG {{ _('Logik') }}: {{ logicname }}

+ {{ _('Dateiname') }}: {{ file_path }} +

+
+
+
+ {% if updates %} +
+ + + + +  |  + + {% endif %} +
+ + + + + + + + + + + + + + + + + + + + + + +
{{ _('Status') }}: + {% if not thislogic.enabled %}{{ _('Nicht aktiv') }}{% else %}{{ _('Aktiv') }}{% endif %} +
{{ _('nächste Ausführung') }}{% if not thislogic.enabled %}{% endif %} + {{ thislogic.next_exec }} + {% if not thislogic.enabled %}{% endif %} +
{{ _('Cycle') }}
{{ _('Crontab') }}
{{ _('Watch_Items') }}
+ +
+ {% if logic_lines %} + + {% if updates %}{% endif %} + + {% else %}{{ _('no data available') }}{% endif %} +
+
+ +{% endblock %} + diff --git a/backend/templates/logics_view.html b/backend/_pv_1_3_5/templates/logics_view.html.off old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/logics_view.html rename to backend/_pv_1_3_5/templates/logics_view.html.off diff --git a/backend/templates/main.html b/backend/_pv_1_3_5/templates/main.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/main.html rename to backend/_pv_1_3_5/templates/main.html diff --git a/backend/templates/navbar.html b/backend/_pv_1_3_5/templates/navbar.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/navbar.html rename to backend/_pv_1_3_5/templates/navbar.html diff --git a/backend/templates/plugins.html b/backend/_pv_1_3_5/templates/plugins.html old mode 100644 new mode 100755 similarity index 51% rename from backend/templates/plugins.html rename to backend/_pv_1_3_5/templates/plugins.html index 866e1b086..183e227e9 --- a/backend/templates/plugins.html +++ b/backend/_pv_1_3_5/templates/plugins.html @@ -21,7 +21,7 @@ {% for p in plugins %} - + {{ loop.index }} {% if p.smartplugin %}SmartPlugin{%else%}Classic{%endif%} {{ p.classpath }} @@ -38,6 +38,33 @@ - {%endif%} + + +
+
{{ _('Plugin spezifische Attribute') }}:
+
+ {% if p.attributes|length > 2 %} + {% for key, value in p.attributes.items() %} + {% if key not in ['class_path', 'class_name'] %} + {{ key }}: {{ value }}
+ {%endif%} + {% endfor %} + {% else %} + - + {%endif%} +
+
+ + + {% endfor %} diff --git a/backend/templates/schedules.html b/backend/_pv_1_3_5/templates/schedules.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/schedules.html rename to backend/_pv_1_3_5/templates/schedules.html diff --git a/backend/templates/services.html b/backend/_pv_1_3_5/templates/services.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/services.html rename to backend/_pv_1_3_5/templates/services.html diff --git a/backend/templates/system.html b/backend/_pv_1_3_5/templates/system.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/system.html rename to backend/_pv_1_3_5/templates/system.html diff --git a/backend/templates/threads.html b/backend/_pv_1_3_5/templates/threads.html old mode 100644 new mode 100755 similarity index 100% rename from backend/templates/threads.html rename to backend/_pv_1_3_5/templates/threads.html diff --git a/backend/templates/visu.html b/backend/_pv_1_3_5/templates/visu.html old mode 100644 new mode 100755 similarity index 97% rename from backend/templates/visu.html rename to backend/_pv_1_3_5/templates/visu.html index 8e1ca62c3..6176e9b25 --- a/backend/templates/visu.html +++ b/backend/_pv_1_3_5/templates/visu.html @@ -17,7 +17,7 @@ {% if visu_plugin_build > '2' %} {{ _('Client Software') }} {{ _('Browser') }} - {{ _('') }} + {{ '' }} {% else %} diff --git a/backend/_pv_1_3_5/tests/cptestcase.py b/backend/_pv_1_3_5/tests/cptestcase.py new file mode 100755 index 000000000..bdeb384eb --- /dev/null +++ b/backend/_pv_1_3_5/tests/cptestcase.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +from io import BytesIO +import unittest +import urllib.request, urllib.parse, urllib.error + +import cherrypy + +# Not strictly speaking mandatory but just makes sense +cherrypy.config.update({'environment': "test_suite"}) + +# This is mandatory so that the HTTP server isn't started +# if you need to actually start (why would you?), simply +# subscribe it back. +cherrypy.server.unsubscribe() + +# simulate fake socket address... they are irrelevant in our context +local = cherrypy.lib.httputil.Host('127.0.0.1', 50000, "") +remote = cherrypy.lib.httputil.Host('127.0.0.1', 50001, "") + +class BaseCherryPyTestCase(unittest.TestCase): + def request(self, path='/', method='GET', app_path='', scheme='http', + proto='HTTP/1.1', data=None, headers=None, **kwargs): + """ + CherryPy does not have a facility for serverless unit testing. + However this recipe demonstrates a way of doing it by + calling its internal API to simulate an incoming request. + This will exercise the whole stack from there. + + Remember a couple of things: + + * CherryPy is multithreaded. The response you will get + from this method is a thread-data object attached to + the current thread. Unless you use many threads from + within a unit test, you can mostly forget + about the thread data aspect of the response. + + * Responses are dispatched to a mounted application's + page handler, if found. This is the reason why you + must indicate which app you are targetting with + this request by specifying its mount point. + + You can simulate various request settings by setting + the `headers` parameter to a dictionary of headers, + the request's `scheme` or `protocol`. + + .. seealso: http://docs.cherrypy.org/stable/refman/_cprequest.html#cherrypy._cprequest.Response + """ + # This is a required header when running HTTP/1.1 + h = {'Host': '127.0.0.1'} + + if headers is not None: + h.update(headers) + + # If we have a POST/PUT request but no data + # we urlencode the named arguments in **kwargs + # and set the content-type header + if method in ('POST', 'PUT') and not data: + data = urllib.parse.urlencode(kwargs) + kwargs = None + h['content-type'] = 'application/x-www-form-urlencoded' + + # If we did have named arguments, let's + # urlencode them and use them as a querystring + qs = None + if kwargs: + qs = urllib.parse.urlencode(kwargs) + + # if we had some data passed as the request entity + # let's make sure we have the content-length set + fd = None + if data is not None: + h['content-length'] = '%d' % len(data) + #fd = StringIO(data) + fd = BytesIO(data.encode()) + + # Get our application and run the request against it + app = cherrypy.tree.apps.get(app_path) + if not app: + # XXX: perhaps not the best exception to raise? + raise AssertionError("No application mounted at '%s'" % app_path) + + # Cleanup any previous returned response + # between calls to this method + app.release_serving() + + # Let's fake the local and remote addresses + request, response = app.get_serving(local, remote, scheme, proto) + try: + h = [(k, v) for k, v in h.items()] + response = request.run(method, path, qs, proto, h, fd) + finally: + if fd: + fd.close() + fd = None + + if response.output_status.startswith(b'500'): + print(response.body) + raise AssertionError("Unexpected error") + + # collapse the response into a bytestring + response.collapse_body() + return response diff --git a/backend/_pv_1_3_5/utils.py b/backend/_pv_1_3_5/utils.py new file mode 100755 index 000000000..c83d3e10f --- /dev/null +++ b/backend/_pv_1_3_5/utils.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# -*- coding: utf8 -*- +######################################################################### +# Copyright 2016 Bernd Meiners, +# Christian Strassburg c.strassburg@gmx.de +# René Frieß rene.friess@gmail.com +# Martin Sinn m.sinn@gmx.de +######################################################################### +# Backend plugin for SmartHomeNG +# +# This plugin is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This plugin is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this plugin. If not, see . +######################################################################### + +import logging +import json +import os +import collections +from collections import OrderedDict + + +# Funktionen für Jinja2 z.Zt außerhalb der Klasse Backend, da ich Jinja2 noch nicht mit +# Methoden einer Klasse zum laufen bekam + + +def get_basename(p): + """ + returns the filename of a full pathname + + This function extends the jinja2 template engine + """ + return os.path.basename(p) + + +def is_userlogic(sh, logic): + """ + returns True if userlogic and False if system logic + + This function extends the jinja2 template engine + """ + return os.path.basename(os.path.dirname(sh.return_logic(logic).filename)) == 'logics' + + +translation_dict = {} +translation_lang = '' + + +def get_translation_lang(): + global translation_lang + return translation_lang + + +def load_translation(language): + global translation_dict # Needed to modify global copy of translation_dict + global translation_lang # Needed to modify global copy of translation_lang + + logger = logging.getLogger(__name__) + + translation_lang = language.lower() + if translation_lang == '': + translation_dict = {} + else: + lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + translation_lang + '.json' + try: + f = open(lang_filename, 'r') + except: + translation_lang = '' + return False + try: + translation_dict = json.load(f) + except Exception as e: + logger.error("Backend: load_translation language='{0}': Error '{1}'".format(translation_lang, e)) + return False + logger.debug("Backend: translation_dict='{0}'".format(translation_dict)) + return True + + +def html_escape(str): + str = str.rstrip().replace('<', '<').replace('>', '>') + str = str.rstrip().replace('(', '(').replace(')', ')') + html = str.rstrip().replace("'", ''').replace('"', '"') + return html + + +def translate(txt, block=''): + """ + returns translated text + + This function extends the jinja2 template engine + """ + logger = logging.getLogger(__name__) + + txt = str(txt) + if translation_lang == '': + tr = txt + else: + if block != '': + blockdict = translation_dict.get('_' + block, {}) + tr = blockdict.get(txt, '') + if tr == '': + tr = translation_dict.get(txt, '') + else: + tr = translation_dict.get(txt, '') + if tr == '': + logger.warning("Backend: Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt)) + tr = txt + return html_escape(tr) + + +def create_hash(plaintext): + import hashlib + hashfunc = hashlib.sha512() + hashfunc.update(plaintext.encode()) + return hashfunc.hexdigest() + + +def parse_requirements(file_path): + fobj = open(file_path) + req_dict = {} + for line in fobj: + if len(line) > 0 and '#' not in line: + if ">" in line: + if line[0:line.find(">")].lower().strip() in req_dict: + req_dict[line[0:line.find(">")].lower().strip()] += " | " + line[line.find(">"):len( + line)].lower().strip() + else: + req_dict[line[0:line.find(">")].lower().strip()] = line[line.find(">"):len(line)].lower().strip() + elif "<" in line: + if line[0:line.find("<")].lower().strip() in req_dict: + req_dict[line[0:line.find("<")].lower().strip()] += " | " + line[line.find("<"):len( + line)].lower().strip() + else: + req_dict[line[0:line.find("<")].lower().strip()] = line[line.find("<"):len(line)].lower().strip() + elif "=" in line: + if line[0:line.find("=")].lower().strip() in req_dict: + req_dict[line[0:line.find("=")].lower().strip()] += " | " + line[line.find("="):len( + line)].lower().strip() + else: + req_dict[line[0:line.find("=")].lower().strip()] = line[line.find("="):len(line)].lower().strip() + fobj.close() + return req_dict + + +def strip_quotes(string): + string = string.strip() + if len(string) > 0: + if string[0] in ['"', "'"]: # check if string starts with ' or " + if string[0] == string[-1]: # and end with it + if string.count(string[0]) == 2: # if they are the only one + string = string[1:-1] # remove them + return string + + diff --git a/backend/assets/backend_systeminfo.jpg b/backend/assets/backend_systeminfo.jpg new file mode 100755 index 000000000..fd622a6df Binary files /dev/null and b/backend/assets/backend_systeminfo.jpg differ diff --git a/backend/locale/de.json b/backend/locale/de.json old mode 100644 new mode 100755 index 7124515ad..7858c966b --- a/backend/locale/de.json +++ b/backend/locale/de.json @@ -1,11 +1,17 @@ { + "alle": "alle", + "sonstige": "sonstige", + "Scheduler (plural)": "Scheduler", "Scheduler": "Scheduler", "Logik": "Logik", "Systemlogiken": "Systemlogiken", + "Nutzerlogiken": "Nutzerlogiken", "Neue Logiken (nicht geladen)": "Neue Logiken (nicht geladen)", + "letzte Ausführung": "letzte Ausführung", "nächste Ausführung": "nächste Ausführung", "Cycle": "Cycle", "Crontab": "Crontab", + "Crontab(s)": "Crontab(s)", "Dateiname": "Dateiname", "Aktionen": "Aktionen", "Items": "Items", @@ -28,13 +34,17 @@ "Letztes Update": "Letztes Update", "Letzte Änderung": "Letzte Änderung", "Geändert durch": "Geändert durch", - "age": "Alter", + "age": "Alter (Änderung)", + "update_age": "Alter (Update)", "vorheriger Wert": "vorheriger Wert", + "previous update": "vorheriges Update", "previous change": "vorherige Änderung", - "previous age": "vorheriges Alter", + "previous update age": "vorh. Alter (Update)", + "previous age": "vorh. Alter (Änderung)", "Evaluation und Trigger": "Initialisierungs-, Evaluations- und Trigger-Konfiguration", "Plugin spezifische Attribute": "Plugin spezifische Konfigurationen", + "Plugin Metadaten": "Plugin Metadaten", "Verbundene Logiken": "Verbundene Logiken", "Verbundene Trigger": "Verbundene Trigger", "Willkommen im Backend von": "Willkommen im Backend von", @@ -58,6 +68,7 @@ "in": "in", "installierte Version": "installierte Version", "Neuste Version": "Neuste Version", + "Neuste Version!": "Neuste Version, bitte vor der Installation prüfen ob sie zu Problemen führt!", "Keine Antwort von PyPI": "Keine Antwort von PyPI", "PyPI nicht erreichbar": "PyPI nicht erreichbar", "PyPI Prüfung deaktiviert": "PyPI Prüfung deaktiviert", @@ -78,6 +89,22 @@ "Auf Englisch wechseln": "Auf Englisch wechseln", "Auf Französisch wechseln": "Auf Französisch wechseln", "Auf Polnisch wechseln": "Auf Polnisch wechseln", + "YAML Syntax Checker": "YAML Syntax Checker", + "Eval Syntax Checker": "Eval Syntax Checker", + "Ausdruck (Eingabe im Python Eval-Format)": "Ausdruck (Eingabe im Python Eval-Format)", + "Relativ zu (Eingabe des Item-Path)": "Relativ zu (Eingabe des Item-Path)", + "Expandierter Ausdruck": "Expandierter Ausdruck", + "Ergebnis": "Ergebnis", + "Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.": "Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.", + "Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.": "Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.", + "Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.": "Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.", + "Hier wird das Ergebnis Ausdruck angezeigt.": "Hier wird das Ergebnis Ausdruck angezeigt.", + "Hier den YAML Code eingeben, der geprüft werden soll.": "Hier den YAML Code eingeben, der geprüft werden soll.", + "Eingabe im .YAML Format": "Eingabe im .YAML Format", + "Ergebnis: Aufbereitetes .YAML Format": "Ergebnis: Aufbereitetes .YAML Format", + "Ergebnis: Aufbereitet als Python Source Code": "Ergebnis: Aufbereitet als Python Source Code", + "Python Code Ausgabe": "Python Code Ausgabe", + "Nr.": "Nr.", "Type": "Type", "Plugin": "Plugin", @@ -87,6 +114,10 @@ "Mehrere Instanzen möglich": "Mehrere Instanzen möglich", "Ja": "Ja", "Nein": "Nein", + + "Szene": "Szene", + "Lernen": "Lernen", + "Thread": "Thread", "Thread-Id": "Thread-Id", "Aktiv": "Aktiv", @@ -111,12 +142,54 @@ "Logging": "Logging", "Passwort anzeigen": "Passwort anzeigen", "SmartHomeNG Version": "SmartHomeNG Version", + "SmartHomeNG Plugins Version": "SmartHomeNG Plugins Version", "Watch_Items": "Watch_Items", + "Watch_Item(s)": "Watch_Item(s)", "Anforderungen": "Anforderungen", "Übersicht": "Übersicht", "Eingabe im .CONF Format": "Eingabe im .CONF Format", "Ergebnis im .YAML Format": "Ergebnis im .YAML Format", - + "Wartung": "Wartung", + "Tester": "Tester", + "Beschreibung": "Beschreibung", + "Documentation": "Dokumentation", + "Support": "Support", + "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.": "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.", + "Zeilenumbruch" : "Zeilenumbruch", + "Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.": "Strg + Space: Autovervollständigen von Python Befehlen. Strg + I: Autovervollständigen von Item-Pfaden.", + "Hilfe": "Hilfe", + "help_search_1": "Strg + F / Cmd + F: Suche starten", + "help_search_2": "Strg + G / Cmd + G: Nächsten Treffer finden", + "help_search_3": "Shift + Strg + G / Shift + Cmd + G: Vorherigen Treffer finden", + "help_search_4": "Shift + Strg + F / Cmd + Option + F: Ersetzen", + "help_search_5": "Shift + Strg + R / Shift + Cmd + Option + F: Alle ersetzen", + "help_search_6": "Alt + F: Persistenter Such-Dialog (Enter für nächsten Treffer, Shift + Enter für vorherigen Treffer)" , + "help_search_7": "Alt + G: In Zeile springen", + "Suche": "Suche", + "Hilfslinien": "Hilfslinien", + "PyPI Check": "PyPI Check", + "Systemeigenschaften": "Systemeigenschaften", + "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!": "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!", + "Wollen Sie die Logik" : "Wollen Sie die Logik", + "wirklich löschen?" : "wirklich löschen?", + "Neue Logik erstellen": "Neue Logik erstellen", + "Angaben für die Erzeugung einer neuen Python Logik": "Angaben für die Erzeugung einer neuen Python Logik", + "Dateiname des Python Codes der Logik (ohne Extension '.py')": "Dateiname des Python Codes der Logik (ohne Extension '.py')", + "Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet": "Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet", + "Logikname": "Logikname", + "Bitte Dateinamen angeben": "Bitte Dateinamen angeben", + "Logik-Datei": "Logik-Datei", + "existiert bereits": "existiert bereits", + "Der Logikname wird bereits verwendet": "Der Logikname wird bereits verwendet", + "sowie": "sowie", + "führen nicht zum": "führen nicht zum", + "der Logik": "der Logik", + "Bitte bei Bedarf anschließend": "Bitte bei Bedarf anschließend", + "drücken": "drücken", + "CONF-YAML Konverter": "CONF-YAML Konverter", + "Pakete ohne Requirements": "Pakete ohne Requirements", + "Version unterstützt!": "Version unterstützt!", + "Version nicht zulässig!": "Version nicht zulässig!", "_items": { "path": "Pfad", @@ -127,6 +200,8 @@ "enforce_updates": "enforce_updates", "eval": "eval", "eval_trigger": "eval_trigger", + "on_update": "on_update", + "on_change": "on_change", "cycle": "cycle", "crontab": "crontab", "autotimer": "autotimer", @@ -155,6 +230,7 @@ "smarthomeNG beenden": "SmartHomeNG beenden", "knxd service beenden": "knxd service beenden", "knxd socket beenden": "knxd socket beenden", + "Datenbank-Dump": "Datenbank-Dump", "Filter anwenden": "Filter anwenden", "Cacheprüfung": "Cacheprüfung", "Passwort-Hash erzeugen": "Passwort-Hash erzeugen", @@ -164,6 +240,7 @@ "Polnisch": "Polish", "Auslösen": "Auslösen", "Neu Laden": "Neu Laden", + "Prüfen": "Prüfen", "Deaktivieren": "Deaktivieren", "Aktivieren": "Aktivieren", "Hinzufügen": "Hinzufügen", @@ -174,8 +251,14 @@ "Beenden" : "Beenden", "Speichern" : "Speichern", "Speichern_und_Neu_Laden" : "Speichern und neu laden", + "Speichern_Neu_Laden_und_Triggern": "Speichern, neu laden und Auslösen", "Löschen" : "Löschen", - "Konvertieren": "Konvertieren" + "Konvertieren": "Konvertieren", + "Neue Blockly Logik": "Neue Blockly Logik", + "Neue Python Logik": "Neue Python Logik", + "Erstellen": "Erstellen", + "Entladen": "Entladen", + "Nach unten scrollen": "Nach unten scrollen" }, "_menu": { @@ -187,8 +270,10 @@ "Blockly-Logiken-Editor": "Blockly-Logiken-Editor", "Scheduler": "Scheduler", "Plugins": "Plugins", + "Szenen": "Szenen", "Threads": "Threads", + "Logging": "Logging", "Visu": "Visu", - "Disclosure": "Disclosure" + "Disclosure": "Urheberrechtshinweise" } } diff --git a/backend/locale/en.json b/backend/locale/en.json old mode 100644 new mode 100755 index 2758acf9e..ba0fc8d34 --- a/backend/locale/en.json +++ b/backend/locale/en.json @@ -1,10 +1,16 @@ { + "alle": "all", + "sonstige": "other", "Scheduler": "Scheduler", + "Scheduler (plural)": "Schedulers", "Logik": "Logic", "Systemlogiken": "System Logics", + "Nutzerlogiken": "User Logics", + "letzte Ausführung": "last execution", "nächste Ausführung": "next execution", "Cycle": "Cycle", "Crontab": "Crontab", + "Crontab(s)": "Crontab(s)", "Dateiname": "Filename", "Aktionen": "Actions", "Items": "Items", @@ -27,13 +33,18 @@ "Letztes Update": "last update", "Letzte Änderung": "last change", "Geändert durch": "changed by", - "age": "age", + "age": "age (change)", + "update_age": "age (update)", + "vorheriger Wert": "previous value", + "previous update": "previous update", "previous change": "previous change", + "previous update age": "previous update age", "previous age": "previous age", "Evaluation und Trigger": "Initialization, Evaluation and Trigger Configuration", "Plugin spezifische Attribute": "Plugin specific configurations", + "Plugin Metadaten": "Plugin Metadata", "Verbundene Logiken": "Bound Logics", "Verbundene Trigger": "Bound Triggers", "Willkommen im Backend von": "Welcome to the backend of", @@ -56,7 +67,8 @@ "Python Version": "Python Version", "in": "in", "installierte Version": "installed Version", - "Neuste Version": "Newest Version", + "Neuste Version": "Newest version", + "Neuste Version!": "Newest version, please check for possible conflicts before upgrading!", "Keine Antwort von PyPI": "No answer from PyPI", "PyPI nicht erreichbar": "PyPI inaccessible", "PyPI Prüfung deaktiviert": "PyPI check disabled", @@ -77,6 +89,22 @@ "Auf Englisch wechseln": "Switch to English", "Auf Französisch wechseln": "Switch to French", "Auf Polnisch wechseln": "Switch to Polish", + "YAML Syntax Checker": "YAML Syntax Checker", + "Eval Syntax Checker": "Eval Syntax Checker", + "Ausdruck (Eingabe im Python Eval-Format)": "Expression (Enter in Python eval-format)", + "Relativ zu (Eingabe des Item-Path)": "Relative to (Enter Item-Path)", + "Expandierter Ausdruck": "Expanded expression", + "Ergebnis": "Result", + "Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.": "Enter the expression to be evaluated. Items can be entered with absolute or relative path.", + "Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.": "To resolve relative itempathes, enter the item here to which the items should be relative to.", + "Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.": "The expression with resolved relative pathes is displayed here.", + "Hier wird das Ergebnis Ausdruck angezeigt.": "The evaluated expression is displayed here.", + "Hier den YAML Code eingeben, der geprüft werden soll.": "Enter YAML code to be checked here.", + "Eingabe im .YAML Format": "Enter data in YAML format", + "Ergebnis: Aufbereitetes .YAML Format": "Result: Processed YAML format", + "Ergebnis: Aufbereitet als Python Source Code": "Result: Displayed as Python source code", + "Python Code Ausgabe": "Output as Python code", + "Nr.": "No.", "Type": "Type", "Plugin": "Plugin", @@ -86,6 +114,10 @@ "Mehrere Instanzen möglich": "Multiple Instances possible", "Ja": "Yes", "Nein": "No", + + "Szene": "Scene", + "Lernen": "Learn", + "Thread": "Thread", "Thread-Id": "Thread-Id", "Aktiv": "Active", @@ -110,11 +142,54 @@ "Logging": "Logging", "Passwort anzeigen": "Show Password", "SmartHomeNG Version": "SmartHomeNG Version", + "SmartHomeNG Plugins Version": "SmartHomeNG Plugins Version", "Watch_Items": "Watch_Items", + "Watch_Item(s)": "Watch_Item(s)", "Anforderungen": "Requirements", "Übersicht": "Overview", "Eingabe im .CONF Format": "Input in .CONF format", "Ergebnis im .YAML Format": "Result in .YAML format", + "Wartung": "Maintainer", + "Tester": "Tester", + "Beschreibung": "Description", + "Documentation": "Documentation", + "Support": "Support", + "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.": "Press F11 when cursor is in the editor to toggle full screen editing. Esc can also be used to exit full screen editing.", + "Zeilenumbruch" : "Line Wrapping", + "Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.": "Press Ctrl-Space to activate autocompletion of Python commands. Press Ctrl-I to activate autocompletion of item paths.", + "Hilfe": "Help", + "help_search_1": "Ctrl-F / Cmd-F: Start searching", + "help_search_2": "Ctrl-G / Cmd-G: Find next", + "help_search_3": "Shift-Ctrl-G / Shift-Cmd-G: Find previous", + "help_search_4": "Shift-Ctrl-F / Cmd-Option-F: Replace", + "help_search_5": "Shift-Ctrl-R / Shift-Cmd-Option-F: Replace all", + "help_search_6": "Alt-F: Persistent search (dialog doesn't autoclose, enter to find next, Shift-Enter to find previous)" , + "help_search_7": "Alt-G: Jump to line", + "Suche": "Search", + "Hilfslinien": "Rulers", + "PyPI Check": "PyPI Check", + "Systemeigenschaften": "System Properties", + "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!": "If you don't save, you will loose your last changes!", + "Wollen Sie die Logik" : "Do you really want to delete the logic", + "wirklich löschen?" : "?", + "Neue Logik erstellen": "Create new logic", + "Angaben für die Erzeugung einer neuen Python Logik": "Data for creation of a new Python logic", + "Dateiname des Python Codes der Logik (ohne Extension '.py')": "Filename of the Python code (without '.py' extension)", + "Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet": "Logic-/sectionname in /etc/logic.yaml - If empty, the filename is used", + "Logikname": "Logicname", + "Bitte Dateinamen angeben": "Please enter filename", + "Logik-Datei": "Logic-file", + "existiert bereits": "already exists", + "Der Logikname wird bereits verwendet": "The name of the logic is already used", + "sowie": "and", + "führen nicht zum": "do not", + "der Logik": "the logic", + "Bitte bei Bedarf anschließend": "If needed, please press", + "drücken": " ", + "CONF-YAML Konverter": "CONF-YAML Converter", + "Pakete ohne Requirements": "Packages without Requirements", + "Version unterstützt!": "Version usable!", + "Version nicht zulässig!": "Version not usable!", "_items": { "path": "Pfad", @@ -125,6 +200,8 @@ "enforce_updates": "enforce_updates", "eval": "eval", "eval_trigger": "eval_trigger", + "on_update": "on_update", + "on_change": "on_change", "cycle": "cycle", "crontab": "crontab", "autotimer": "autotimer", @@ -157,12 +234,14 @@ "knxd service beenden": "Stop knxd service", "knxd socket beenden": "Stop knxd socket", "Filter anwenden": "Apply Filter", + "Datenbank-Dump": "Dump database", "Cacheprüfung": "Cache Check", "Passwort-Hash erzeugen": "Create Password Hash", "Englisch": "English", "Deutsch": "Deutsch", "Französisch": "French", "Polnisch": "Polish", + "Prüfen": "Check", "Deaktivieren": "Disable", "Aktivieren": "Enable", "Leeren" : "Clear", @@ -172,8 +251,14 @@ "Beenden" : "Stop", "Speichern" : "Save", "Speichern_und_Neu_Laden" : "Save and Reload", + "Speichern_Neu_Laden_und_Triggern": "Save, Reload and Trigger", "Löschen" : "Delete", - "Konvertieren": "Convert" + "Konvertieren": "Convert", + "Neue Blockly Logik": "New Blockly logic", + "Neue Python Logik": "New Python logic", + "Erstellen": "Create", + "Entladen": "Unload", + "Nach unten scrollen": "Scroll down" }, "_menu": { @@ -184,7 +269,9 @@ "Blockly-Logiken-Editor": "Blockly Logics Editor", "Scheduler": "Scheduler", "Plugins": "Plugins", + "Szenen": "Scenes", "Threads": "Threads", + "Logging": "Logging", "Visu": "Visu", "Disclosure": "Disclosure", "CONF-YAML Konverter": "CONF-YAML Converter" diff --git a/backend/locale/fr.json b/backend/locale/fr.json old mode 100644 new mode 100755 index b81a3bd44..ffee4fc9d --- a/backend/locale/fr.json +++ b/backend/locale/fr.json @@ -1,11 +1,17 @@ { + "alle": "tous", + "sonstige": "autres", "Scheduler": "Planificateur", + "Scheduler (plural)": "Planificateurs", "Logik": "Logique", "Systemlogiken": "Logiques système", + "Nutzerlogiken": "Logiques utilisateur", "Neue Logiken (nicht geladen)": "Nouvelles logiques (non encore chargées)", + "letzte Ausführung": "", "nächste Ausführung": "Prochaine exécution", "Cycle": "Cycle", "Crontab": "Crontab", + "Crontab(s)": "Crontab(s)", "Dateiname": "Nom du fichier", "Aktionen": "Actions", "Items": "Objets", @@ -29,14 +35,19 @@ "Letzte Änderung": "Dernière modification", "Geändert durch": "Modifié par", "age": "Âge", + "age": "age (modification)", + "update_age": "", "aktueller": "actuel", "vorheriger": "précédent", "vorheriger Wert": "Valeur précédente", + "previous update": "", "previous change": "Modification précédente", + "previous update age": "", "previous age": "Âge précédent", "Evaluation und Trigger": "Configuration de l'initialisation, de l'évaluation et des déclencheurs", "Plugin spezifische Attribute": "Attributs spécifiques à l'extension", + "Plugin Metadaten": "Métadonnées de l'extension", "Verbundene Logiken": "Logiques connexes", "Verbundene Trigger": "Déclencheurs connexes", "Willkommen im Backend von": "Bienvenue au Backend de", @@ -60,6 +71,7 @@ "in": "dans", "installierte Version": "Version installée", "Neuste Version": "Dernière version", + "Neuste Version!": "", "Keine Antwort von PyPI": "Pas de réponse de PyPI", "PyPI nicht erreichbar": "PyPI non accessible", "PyPI Prüfung deaktiviert": "Vérification PyPI désactivée", @@ -79,6 +91,22 @@ "Auf Deutsch wechseln": "Basculer vers l'allemand", "Auf Englisch wechseln": "Basculer vers l'anglais", "Auf Polnisch wechseln": "Basculer vers le polonais", + "YAML Syntax Checker": "", + "Eval Syntax Checker": "", + "Ausdruck (Eingabe im Python Eval-Format)": "", + "Relativ zu (Eingabe des Item-Path)": "", + "Expandierter Ausdruck": "", + "Ergebnis": "", + "Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.": "", + "Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.": "", + "Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.": "", + "Hier wird das Ergebnis Ausdruck angezeigt.": "", + "Hier den YAML Code eingeben, der geprüft werden soll.": "", + "Eingabe im .YAML Format": "", + "Ergebnis: Aufbereitetes .YAML Format": "", + "Ergebnis: Aufbereitet als Python Source Code": "", + "Python Code Ausgabe": "", + "Nr.": "N°", "Type": "Type", "Plugin": "Extension", @@ -88,6 +116,10 @@ "Mehrere Instanzen möglich": "Supporte plusieurs instances", "Ja": "Oui", "Nein": "Non", + + "Szene": "", + "Lernen": "", + "Thread": "Tâche", "Thread-Id": "Id de tâche", "Aktiv": "Active", @@ -112,11 +144,54 @@ "Logging": "Journalisation", "Passwort anzeigen": "Afficher mot de passe", "SmartHomeNG Version": "Version de SmartHomeNG", + "SmartHomeNG Plugins Version": "Version de SmartHomeNG Extensions", "Watch_Items": "Objets surveillés", + "Watch_Item(s)": "Objet(s) surveillé(s)", "Anforderungen": "Version demandée", "Übersicht": "Aperçu", "Eingabe im .CONF Format": "Entrée en format .CONF", "Ergebnis im .YAML Format": "Résultat en format .YAML", + "Wartung": "Maintenance", + "Tester": "Testeur", + "Beschreibung": "Description", + "Documentation": "Documentation", + "Support": "Support", + "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.": "Appuyez F11 si le curseur est dans la fenêtre de l'éditeur pour passer en mode plein-écran. Appuyez F11 ou ESC pour sortir du mode plein-écran.", + "Zeilenumbruch" : "Coupure de ligne", + "Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.": "Appuyez ctrl-espace pour activer le complètement automatique des commandes Python. Appuyez ctrl-i pour activer le complètement automatique des chemins des objets.", + "Hilfe": "Aide", + "help_search_1": "Ctrl-F / Cmd-F: Démarrer la recherche", + "help_search_2": "Ctrl-G / Cmd-G: Prochain résultat", + "help_search_3": "Shift-Ctrl-G / Shift-Cmd-G: Résultat précédent", + "help_search_4": "Shift-Ctrl-F / Cmd-Option-F: Remplacer", + "help_search_5": "Shift-Ctrl-R / Shift-Cmd-Option-F: Remplacer tout", + "help_search_6": "Alt-F: Recherche persistente (dialogue ne se ferme pas, pour prochain résultat, Shift-Entrée pour résultat précédent)", + "help_search_7": "Alt-G: Sauter vers ligne", + "Suche": "Chercher", + "Hilfslinien": "Lignes de séparation", + "PyPI Check": "Vérification PyPI", + "Systemeigenschaften": "Propriétés du système", + "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!": "Si vous ne sauvegardez pas vous perdez toutes modifications!", + "Wollen Sie die Logik" : "Voulez-vous vraiment supprimer cette logique", + "wirklich löschen?" : "?", + "Neue Logik erstellen": "Créer nouvelle logique", + "Angaben für die Erzeugung einer neuen Python Logik": "Donées de la nouvelle logique", + "Dateiname des Python Codes der Logik (ohne Extension '.py')": "Nom du fichier Python de la logique (sans l'extension '.py')", + "Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet": "Nom de la logique dans /etc/logic.yaml - Si vide le nom du fichier sera utilisé", + "Logikname": "Nom de la logique", + "Bitte Dateinamen angeben": "Veuillez entrer le nom du fichier:", + "Logik-Datei": "Fichier logique", + "existiert bereits": "existe déjà", + "Der Logikname wird bereits verwendet": "Ce nom de la logique est déjà utilisé", + "sowie": "ainsi que", + "führen nicht zum": "n'aboutissent pas à", + "der Logik": "de la logique", + "Bitte bei Bedarf anschließend": "Connecter en cas de besoin s.v.p.", + "drücken": "pousser", + "CONF-YAML Konverter": "Convertisseur .conf vers .yaml", + "Pakete ohne Requirements": "", + "Version unterstützt!": "", + "Version nicht zulässig!": "", "_items": { "path": "Chemin", @@ -127,6 +202,8 @@ "enforce_updates": "enforce_updates", "eval": "eval", "eval_trigger": "eval_trigger", + "on_update": "on_update", + "on_change": "on_change", "cycle": "cycle", "crontab": "crontab", "autotimer": "autotimer", @@ -158,12 +235,14 @@ "knxd service beenden": "arrêter service knxd", "knxd socket beenden": "arrêter socket knxd", "Filter anwenden": "Appliquer le filtre", + "Datenbank-Dump": "Dump de la base de données", "Cacheprüfung": "Test du cache", "Passwort-Hash erzeugen": "Mot de passe créer hachage", "Englisch": "Anglais", "Deutsch": "Allemand", "Französisch": "Français", "Polnisch": "Polonais", + "Prüfen": "", "Deaktivieren": "Désactiver", "Aktivieren": "Activer", "Hinzufügen": "Ajouter", @@ -174,8 +253,14 @@ "Beenden" : "Terminer", "Speichern" : "Sauvegarder", "Speichern_und_Neu_Laden" : "Sauvegarder et recharger", + "Speichern_Neu_Laden_und_Triggern": "Sauvegarder, recharger et déclencher", "Löschen" : "Supprimer", - "Konvertieren": "Convertir" + "Konvertieren": "Convertir", + "Neue Blockly Logik": "Nouvelle logique 'Blockly'", + "Neue Python Logik": "Nouvelle logique 'Python'", + "Erstellen": "Créer", + "Entladen": "Décharger", + "Nach unten scrollen": "" }, "_menu": { @@ -186,7 +271,9 @@ "Blockly-Logiken-Editor": "Blockly - Editeur de Logiques", "Scheduler": "Planificateur", "Plugins": "Extensions", + "Szenen": "", "Threads": "Tâches", + "Logging": "Journalisation", "Visu": "Visu", "Disclosure": "Déclaration", "CONF-YAML Konverter": "Convertisseur .conf vers .yaml" diff --git a/backend/locale/pl.json b/backend/locale/pl.json old mode 100644 new mode 100755 index 0a23e96e7..84fc594bc --- a/backend/locale/pl.json +++ b/backend/locale/pl.json @@ -1,10 +1,16 @@ { + "alle": "", + "sonstige": "", "Scheduler": "Planista", + "Scheduler (plural)": "", "Logik": "Logika", "Systemlogiken": "Logika systemowa", + "Nutzerlogiken": "Logika użytkownika", + "letzte Ausführung": "", "nächste Ausführung": "Następne wykonanie", "Cycle": "Cykl", "Crontab": "Harmonogram", + "Crontab(s)": "Harmonogram", "Dateiname": "Nazwa pliku", "Aktionen": "Akcje", "Items": "Itemy", @@ -28,12 +34,16 @@ "Letzte Änderung": "ostatnia zmiana", "Geändert durch": "zmieniono przez", "age": "czas aktualnej wartości", + "update_age": "", "vorheriger Wert": "poprzednia wartość", + "previous update": "", "previous change": "poprzednia zmiana", + "previous update age": "", "previous age": "czas poprzedniej wartości", "Evaluation und Trigger": "Inicjalizacja, ewaluacja i wyzwalacze", "Plugin spezifische Attribute": "Konfiguracja pluginów", + "Plugin Metadaten": "Metadane pluginu", "Verbundene Logiken": "Powiązana Logika", "Verbundene Trigger": "Powiązane wyzwalacze", "Willkommen im Backend von": "Witaj w backendzie", @@ -56,6 +66,7 @@ "Python Version": "Wersja Pythona", "installierte Version": "Zainstalowana wersja", "Neuste Version": "Najnowsza wersja", + "Neuste Version!": "", "Keine Antwort von PyPI": "Brak odpowiedzi z PyPI", "PyPI nicht erreichbar": "PyPI niedostępne", "PyPI Prüfung deaktiviert": "sprawdzanie PyPI wyłączone", @@ -76,6 +87,22 @@ "Auf Englisch wechseln": "Przełącz na angielski", "Auf Französisch wechseln": "Przełącz na francuski", "Auf Polnisch wechseln": "Przełącz na polski", + "YAML Syntax Checker": "", + "Eval Syntax Checker": "", + "Ausdruck (Eingabe im Python Eval-Format)": "", + "Relativ zu (Eingabe des Item-Path)": "", + "Expandierter Ausdruck": "", + "Ergebnis": "", + "Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.": "", + "Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.": "", + "Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.": "", + "Hier wird das Ergebnis Ausdruck angezeigt.": "", + "Hier den YAML Code eingeben, der geprüft werden soll.": "", + "Eingabe im .YAML Format": "", + "Ergebnis: Aufbereitetes .YAML Format": "", + "Ergebnis: Aufbereitet als Python Source Code": "", + "Python Code Ausgabe": "", + "Nr.": "Nr", "Type": "Typ", "Plugin": "Plugin", @@ -85,6 +112,10 @@ "Mehrere Instanzen möglich": "Możliwe wiele instancji", "Ja": "Tak", "Nein": "Nie", + + "Szene": "", + "Lernen": "", + "Thread": "Wątki", "Thread-Id": "Id Wątku", "Aktiv": "Aktywny", @@ -109,11 +140,54 @@ "Logging": "Logowanie", "Passwort anzeigen": "pokaż", "SmartHomeNG Version": "Wersja SmartHomeNG", + "SmartHomeNG Plugins Version": "Wersja Pluginy SmartHomeNG", "Watch_Items": "Obserwowane Itemy", + "Watch_Item(s)": "Obserwowane Itemy", "Anforderungen": "Wymagania", - "Übersicht": "Badanie", - "Eingabe im .CONF Format": "Eingabe im .CONF Format", - "Ergebnis im .YAML Format": "Ergebnis im .YAML Format" + "Übersicht": "Podsumowanie", + "Eingabe im .CONF Format": "Wejście w formacie .CONF", + "Ergebnis im .YAML Format": "Wyjście w formacie .YAML", + "Wartung": "Opiekun", + "Tester": "Tester", + "Beschreibung": "Opis", + "Documentation": "Dokumentacja", + "Support": "Wsparcie", + "Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.": "Press F11 when cursor is in the editor to toggle full screen editing. Esc can also be used to exit full screen editing.", + "Zeilenumbruch" : "Line Wrapping", + "Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.": "Press ctrl-space to activate autocompletion of Python commands. Press ctrl-i to activate autocompletion of item paths.", + "Hilfe": "Help", + "help_search_1": "Ctrl-F / Cmd-F: Start searching", + "help_search_2": "Ctrl-G / Cmd-G: Find next", + "help_search_3": "Shift-Ctrl-G / Shift-Cmd-G: Find previous", + "help_search_4": "Shift-Ctrl-F / Cmd-Option-F: Replace", + "help_search_5": "Shift-Ctrl-R / Shift-Cmd-Option-F: Replace all", + "help_search_6": "Alt-F: Persistent search (dialog doesn't autoclose, enter to find next, Shift-Enter to find previous)" , + "help_search_7": "Alt-G: Jump to line", + "Suche": "Search", + "Hilfslinien": "Rulers", + "PyPI Check": "PyPI Check", + "Systemeigenschaften": "System Properties", + "Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!": "If you don't save, you will loose your last changes!", + "Wollen Sie die Logik" : "", + "wirklich löschen?" : "", + "Neue Logik erstellen": "", + "Angaben für die Erzeugung einer neuen Python Logik": "", + "Dateiname des Python Codes der Logik (ohne Extension '.py')": "", + "Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet": "", + "Logikname": "", + "Bitte Dateinamen angeben": "", + "Logik-Datei": "", + "existiert bereits": "", + "Der Logikname wird bereits verwendet": "", + "sowie": "", + "führen nicht zum": "", + "der Logik": "", + "Bitte bei Bedarf anschließend": "", + "drücken": "", + "CONF-YAML Konverter": "Konwerter CONF-YAML", + "Pakete ohne Requirements": "", + "Version unterstützt!": "", + "Version nicht zulässig!": "", "_items": { "path": "ścieżka", @@ -124,6 +198,8 @@ "enforce_updates": "wymuszone aktualizacje", "eval": "ewaluacja", "eval_trigger": "wyzwalacze ewaluacji", + "on_update": "on_update", + "on_change": "on_change", "cycle": "cykl", "crontab": "harmonogram", "autotimer": "autotimer", @@ -156,12 +232,14 @@ "knxd service beenden": "Stop usługi knxd", "knxd socket beenden": "Stop socketa knxd", "Filter anwenden": "Zastosuj filtr", + "Datenbank-Dump": "Pobierz bazę danych", "Cacheprüfung": "Sprawdź pamięć podręczną", "Passwort-Hash erzeugen": "Utwórz zahashowane hasło", "Englisch": "English", "Deutsch": "Deutsch", "Französisch": "French", "Polnisch": "Polski", + "Prüfen": "", "Deaktivieren": "Wyłącz", "Aktivieren": "Włącz", "Leeren" : "Wyczyść", @@ -171,8 +249,14 @@ "Beenden" : "Stop", "Speichern" : "Zapisz", "Speichern_und_Neu_Laden" : "Zapisz i przeładuj", + "Speichern_Neu_Laden_und_Triggern": "", "Löschen" : "Skasuj" - "Konvertieren": "Konvertieren" + "Konvertieren": "Konwertuj", + "Neue Blockly Logik": "", + "Neue Python Logik": "", + "Erstellen": "", + "Entladen": "", + "Nach unten scrollen": "" }, "_menu": { @@ -183,9 +267,11 @@ "Blockly-Logiken-Editor": "Edytor logiki Blockly", "Scheduler": "Planista", "Plugins": "Pluginy", + "Szenen": "", "Threads": "Wątki", + "Logging": "Logowanie", "Visu": "Visu", "Disclosure": "Deklaracja", - "CONF-YAML Konverter": "CONF-YAML Konverter" + "CONF-YAML Konverter": "Konwerter CONF-YAML" } } diff --git a/backend/plugin.yaml b/backend/plugin.yaml old mode 100644 new mode 100755 index 43c7ce7b3..5c9248473 --- a/backend/plugin.yaml +++ b/backend/plugin.yaml @@ -1,13 +1,46 @@ +# Metadata for the Smart-Plugin plugin: - type: system # plugin type (system, gateway, interface, protocol, cloud) - subtype: core # plugin subtype (if applicable) - version: 1.3.5 # Plugin version -# keywords: # keywords, where applicable - sh_minversion: 1.3 # minimum shNG version to use this plugin -# sh_maxversion: # maximum shNG version to use this plugin (if not latest) - multi_instance: false # plugin supports multi instance - description: 'Web Interface zur Anzeige von Informationen zum System und SmartHomeNG Backend-Daten' -# documentation: # url of wiki page - maintainer: psilo909, msinn, bmxp, cmalo # Who maintains this plugin? - tester: Sandman60 # Who tests this plugin? + # Global plugin attributes + type: system # plugin type (gateway, interface, protocol, system, web) + subtype: core # plugin subtype (if applicable) + description: # Alternative: description in multiple languages + de: 'Web Interface zur Anzeige von Informationen zum System und SmartHomeNG Backend-Daten' + en: 'webinterface for displaying system information and SmartHomeNG backend data' + maintainer: psilo909, msinn, bmxp + tester: Sandman60 +# keywords: iot xyz +# documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md # url of documentation (wiki) page + support: https://knx-user-forum.de/forum/supportforen/smarthome-py/959964-support-thread-für-das-backend-plugin + version: 1.4.8 # Plugin version + sh_minversion: 1.3d # minimum shNG version to use this plugin +# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) + multi_instance: False # plugin supports multi instance + classname: BackendServer # class containing the plugin + +parameters: + # Definition of parameters to be configured in etc/plugin.yaml + updates_allowed: + type: bool + default: True + description: + de: 'Update von Werten durch das Backend Plugin ist erlaubt' + en: 'Update of values through the backend plugin is allowed' + + developer_mode: + type: bool + default: no + description: + de: 'Entwickler Modus aktiviert' + en: 'Developer mode is activated' + + pypi_timeout: + type: int + default: 5 + description: + de: 'Timeout bei der Abfrage der pypi Website' + en: 'Timeout for getting data from the pypi website' + +item_attributes: + # Definition of item attributes defined by this plugin + diff --git a/backend/requirements.txt b/backend/requirements.txt old mode 100644 new mode 100755 diff --git a/backend/tests/cptestcase.py b/backend/tests/cptestcase.py old mode 100644 new mode 100755 diff --git a/backend/tests/test_backend_blocklylogics.py b/backend/tests/test_backend_blocklylogics.py deleted file mode 100644 index 41439d571..000000000 --- a/backend/tests/test_backend_blocklylogics.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- -from tests import common -import cherrypy -from bs4 import BeautifulSoup - -import lib.item - -from plugins.backend import Backend as Root -from plugins.backend.tests.cptestcase import BaseCherryPyTestCase -from tests.mock.core import MockSmartHome - - -def setUpModule(): - bs = MockBackendServer() - sh = bs._sh - cherrypy.tree.mount(Root(backendserver=bs,developer_mode=True), '/') - cherrypy.engine.start() -setup_module = setUpModule - - -def tearDownModule(): - cherrypy.engine.exit() -teardown_module = tearDownModule - - -class TestCherryPyApp(BaseCherryPyTestCase): - def test_backendIntegration(self): - response = self.request('/index') - self.assertEqual(response.output_status, b'200 OK') - body = BeautifulSoup(response.body[0]) - self.assertEqual( str(body.find("a", href="logics.html"))[:2], '') - # self.assertEqual(response.body, ['hello world']) - - def test_DynToolbox(self): - response = self.request('/logics_blockly_html') - #resp_body = str(response.body[0],'utf-8') - bs_body = BeautifulSoup(response.body[0]) - #items = bs_body.find("category", name="SmartHome Items") - shItemsCat = bs_body.xml.find_all(attrs={'name': 'SmartHome Items'})[0] - # print(shItemsCat) - # print("categories: {}".format(len(list(shItemsCat.find_all("category")))) ) - # print(" blocks: {}".format(len(shItemsCat.find_all("block", type="sh_item_obj") )) ) - self.assertEqual(len(list(shItemsCat.find_all("block", type="sh_item_obj") )), 9 ) - self.assertEqual(len(list(shItemsCat.find_all("category") )), 6 ) - - def test_logics_blockly_load(self): - response = self.request('/logics_blockly_load') - self.assertEqual(response.output_status, b'200 OK') - resp_xml = str(response.body[0],'utf-8') - #print(resp_xml) - self.assertRegex(resp_xml, 'Unit Test') - self.assertRegex(resp_xml, 'testen.unit.test') - self.assertRegex(resp_xml, 'bool') - - - - # def test_logics_blockly_load(self): - # with open(fn_py, 'w') as fpy: - # with open(fn_xml, 'w') as fxml: - # fpy.write(py) - # fxml.write(xml) - - # def test_echo(self): - # response = self.request('/echo', msg="hey there") - # self.assertEqual(response.output_status, '200 OK') - # self.assertEqual(response.body, ["hey there"]) - # - # response = self.request('/echo', method='POST', msg="back from the future") - # self.assertEqual(response.output_status, '200 OK') - # self.assertEqual(response.body, ["back from the future"]) - # - - -class MockBackendServer(): - _sh = MockSmartHome() - - def __init__(self): - self._sh.with_items_from(common.BASE + "/tests/resources/blockly_items.conf") - - # HACK: Make tests work! Backend accesses private field _logic_dir - # directly instead of using a method (the field was remove in the - # meantime). Setting this just to make it work again. - self._sh._logic_dir = common.BASE + "/tests/resources/" - - -if __name__ == '__main__': - import unittest - unittest.main() diff --git a/backend/user_doc.rst b/backend/user_doc.rst new file mode 100755 index 000000000..bb66585ba --- /dev/null +++ b/backend/user_doc.rst @@ -0,0 +1,9 @@ +backend +####### + +Das Backend Plugin liefert zahlreiche Infroamtionen, die zum Beispiel bei der Fehlersuche +hilfreich sind. Inzwischen kann man damit auch eine Reihe von Administrationsaufgaben erledigen. + +.. image:: assets/backend_systeminfo.jpg + +Genauer ist das unter :doc:`/backend/backend` beschrieben. diff --git a/backend/utils.py b/backend/utils.py old mode 100644 new mode 100755 index 037b67a93..a8cf14cfb --- a/backend/utils.py +++ b/backend/utils.py @@ -25,39 +25,49 @@ import logging import json import os +import html import collections from collections import OrderedDict +from lib.logic import Logics -# Funktionen für Jinja2 z.Zt außerhalb der Klasse Backend, da ich Jinja2 noch nicht mit -# Methoden einer Klasse zum laufen bekam +translation_dict = {} +translation_dict_en = {} +translation_dict_de = {} +translation_lang = '' -def get_basename(p): - """ - returns the filename of a full pathname - This function extends the jinja2 template engine - """ - return os.path.basename(p) +def get_translation_lang(): + global translation_lang + return translation_lang -def is_userlogic(sh, logic): - """ - returns True if userlogic and False if system logic - - This function extends the jinja2 template engine - """ - return os.path.basename(os.path.dirname(sh.return_logic(logic).filename)) == 'logics' +def load_translation_backuplanguages(): + global translation_dict_en # Needed to modify global copy of translation_dict + global translation_dict_de # Needed to modify global copy of translation_dict + logger = logging.getLogger(__name__) -translation_dict = {} -translation_lang = '' + lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + 'en' + '.json' + try: + f = open(lang_filename, 'r') + translation_dict_en = json.load(f) + except Exception as e: + translation_dict_en = {} + logger.error("Backend: load_translation language='{0}' failed: Error '{1}'".format('en', e)) + logger.debug("Backend: translation_dict_en='{0}'".format(translation_dict_en)) + lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + 'de' + '.json' + try: + f = open(lang_filename, 'r') + translation_dict_de = json.load(f) + except Exception as e: + translation_dict_de = {} + logger.error("Backend: load_translation language='{0}' failed: Error '{1}'".format('de', e)) + logger.debug("Backend: translation_dict_de='{0}'".format(translation_dict_de)) -def get_translation_lang(): - global translation_lang - return translation_lang + return def load_translation(language): @@ -66,6 +76,9 @@ def load_translation(language): logger = logging.getLogger(__name__) + if translation_dict_en == {}: + load_translation_backuplanguages() + translation_lang = language.lower() if translation_lang == '': translation_dict = {} @@ -73,8 +86,9 @@ def load_translation(language): lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + translation_lang + '.json' try: f = open(lang_filename, 'r') - except: + except Exception as e: translation_lang = '' + logger.error("Backend: load_translation language='{0}' failed: Error '{1}'".format(translation_lang, e)) return False try: translation_dict = json.load(f) @@ -85,12 +99,42 @@ def load_translation(language): return True -def html_escape(str): - str = str.rstrip().replace('<', '<').replace('>', '>') - str = str.rstrip().replace('(', '(').replace(')', ')') - html = str.rstrip().replace("'", ''').replace('"', '"') - return html +def _get_translation_for_block(lang, txt, block): + """ + """ + if lang == 'en': + blockdict = translation_dict_en.get('_' + block, {}) + elif lang == 'de': + blockdict = translation_dict_de.get('_' + block, {}) + else: + blockdict = translation_dict.get('_' + block, {}) + + return blockdict.get(txt, '') + + +def _get_translation(txt, block): + """ + Get translation with fallback to english and further fallback to german + """ + logger = logging.getLogger(__name__) + if block != '': + tr = _get_translation_for_block('', txt, block) + if tr == '': + logger.info("Backend: Language '{0}': Translation for '{1}' is missing!".format(translation_lang, txt)) + tr = _get_translation_for_block('en', txt, block) + if tr == '': + tr = _get_translation_for_block('de', txt, block) + else: + tr = translation_dict.get(txt, '') + if tr == '': + logger.info("Backend: Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt)) + tr = translation_dict_en.get(txt, '') + if tr == '': + logger.info("Backend: Language '{0}': Translation for '{1}' is missing".format('en', txt)) + tr = translation_dict_de.get(txt, '') + return tr + def translate(txt, block=''): """ @@ -104,17 +148,12 @@ def translate(txt, block=''): if translation_lang == '': tr = txt else: - if block != '': - blockdict = translation_dict.get('_' + block, {}) - tr = blockdict.get(txt, '') - if tr == '': - tr = translation_dict.get(txt, '') - else: - tr = translation_dict.get(txt, '') + tr = _get_translation(txt, block) + if tr == '': - logger.warning("Backend: Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt)) + logger.info("Backend: -> Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt)) tr = txt - return html_escape(tr) + return html.escape(tr) def create_hash(plaintext): @@ -125,10 +164,21 @@ def create_hash(plaintext): def parse_requirements(file_path): - fobj = open(file_path) req_dict = {} - for line in fobj: - if len(line) > 0 and '#' not in line: + try: + fobj = open(file_path) + except: + return req_dict + + for rline in fobj: + line = '' + if len(rline) > 0: + if rline.find('#') == -1: + line = rline.lower().strip() + else: + line = line[0:line.find("#")].lower().strip() + + if len(line) > 0: if ">" in line: if line[0:line.find(">")].lower().strip() in req_dict: req_dict[line[0:line.find(">")].lower().strip()] += " | " + line[line.find(">"):len( @@ -147,6 +197,9 @@ def parse_requirements(file_path): line)].lower().strip() else: req_dict[line[0:line.find("=")].lower().strip()] = line[line.find("="):len(line)].lower().strip() + else: + req_dict[line.lower().strip()] = '==*' + fobj.close() return req_dict diff --git a/backend/webif/static/codemirror/.editorconfig b/backend/webif/static/codemirror/.editorconfig new file mode 100755 index 000000000..7ed020678 --- /dev/null +++ b/backend/webif/static/codemirror/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 diff --git a/backend/webif/static/codemirror/.gitattributes b/backend/webif/static/codemirror/.gitattributes new file mode 100755 index 000000000..1c8c82d8f --- /dev/null +++ b/backend/webif/static/codemirror/.gitattributes @@ -0,0 +1,8 @@ +*.txt text eol=lf +*.js text eol=lf +*.html text eol=lf +*.md text eol=lf +*.json text eol=lf +*.yml text eol=lf +*.css text eol=lf +*.svg text eol=lf diff --git a/backend/webif/static/codemirror/.npmignore b/backend/webif/static/codemirror/.npmignore new file mode 100755 index 000000000..f23ca7195 --- /dev/null +++ b/backend/webif/static/codemirror/.npmignore @@ -0,0 +1,11 @@ +/node_modules +/demo +/doc +/test +/test*.html +/index.html +/mode/*/*test.js +/mode/*/*.html +/mode/index.html +.* +bin diff --git a/backend/webif/static/codemirror/.travis.yml b/backend/webif/static/codemirror/.travis.yml new file mode 100755 index 000000000..52b8b8159 --- /dev/null +++ b/backend/webif/static/codemirror/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - stable +sudo: false diff --git a/backend/webif/static/codemirror/AUTHORS b/backend/webif/static/codemirror/AUTHORS new file mode 100755 index 000000000..65d848089 --- /dev/null +++ b/backend/webif/static/codemirror/AUTHORS @@ -0,0 +1,700 @@ +List of CodeMirror contributors. Updated before every release. + +4r2r +Aaron Brooks +Abdelouahab +Abe Fettig +Adam Ahmed +Adam King +Adam Particka +adanlobato +Adán Lobato +Adrian Aichner +Adrian Heine +Adrien Bertrand +aeroson +Ahmad Amireh +Ahmad M. Zawawi +ahoward +Akeksandr Motsjonov +Alasdair Smith +Alberto González Palomo +Alberto Pose +Albert Xing +Alexander Pavlov +Alexander Schepanovski +Alexander Shvets +Alexander Solovyov +Alexandre Bique +alexey-k +Alex Piggott +Aliaksei Chapyzhenka +Allen Sarkisyan +Ami Fischman +Amin Shali +Amin Ullah Khan +amshali@google.com +Amsul +amuntean +Amy +Ananya Sen +anaran +AndersMad +Anders Nawroth +Anderson Mesquita +Anders Wåglund +Andrea G +Andreas Reischuck +Andres Taylor +Andre von Houck +Andrew Cheng +Andrew Dassonville +Andrey Fedorov +Andrey Klyuchnikov +Andrey Lushnikov +Andrey Shchekin +Andy Joslin +Andy Kimball +Andy Li +Angelo +angelozerr +angelo.zerr@gmail.com +Ankit +Ankit Ahuja +Ansel Santosa +Anthony Dugois +anthonygego +Anthony Gégo +Anthony Grimes +Anton Kovalyov +Apollo Zhu +AQNOUCH Mohammed +Aram Shatakhtsyan +areos +Arnab Bose +Arsène von Wyss +Arthur Müller +Arun Narasani +as3boyan +asolove +atelierbram +AtomicPages LLC +Atul Bhouraskar +Aurelian Oancea +Axel Lewenhaupt +Barret Rennie +Basarat Ali Syed +Bastian Müller +belhaj +Bem Jones-Bey +benbro +Beni Cherniavsky-Paskin +Benjamin DeCoste +Benjamin Young +Ben Keen +Ben Miller +Ben Mosher +Bernhard Sirlinger +Bert Chang +Bharad +BigBlueHat +Billy Moon +binny +B Krishna Chaitanya +Blaine G +blukat29 +boomyjee +borawjm +Brad Metcalf +Brandon Frohs +Brandon Wamboldt +Brett Zamir +Brian Grinstead +Brian Sletten +brrd +Bruce Mitchener +Bryan Massoth +Caitlin Potter +Calin Barbat +callodacity +Camilo Roca +Casey Klebba +Chad Jolly +Chandra Sekhar Pydi +Charles Skelton +Cheah Chu Yeow +Chris Coyier +Chris Ford +Chris Granger +Chris Houseknecht +Chris Lohfink +Chris Morgan +Chris Smith +Christian Gruen +Christian Oyarzun +Christian Petrov +Christopher Brown +Christopher Kramer +Christopher Mitchell +Christopher Pfohl +Chunliang Lyu +ciaranj +CodeAnimal +CodeBitt +coderaiser +Cole R Lawrence +ComFreek +Curtis Gagliardi +dagsta +daines +Dale Jung +Dan Bentley +Dan Heberden +Daniel, Dao Quang Minh +Daniele Di Sarli +Daniel Faust +Daniel Huigens +Daniel Kesler +Daniel KJ +Daniel Neel +Daniel Parnell +Daniel Thwaites +Danila Malyutin +Danny Yoo +darealshinji +Darius Roberts +Dave Brondsema +Dave Myers +David Barnett +David H. Bronke +David Mignot +David Pathakjee +David Vázquez +David Whittington +deebugger +Deep Thought +Devin Abbott +Devon Carew +Dick Choi +dignifiedquire +Dimage Sapelkin +Dmitry Kiselyov +domagoj412 +Dominator008 +Domizio Demichelis +Doug Wikle +Drew Bratcher +Drew Hintz +Drew Khoury +Drini Cami +Dror BG +duralog +dwelle +eborden +edsharp +ekhaled +Elisée +Emmanuel Schanzer +Enam Mijbah Noor +Eric Allam +Erik Welander +eustas +Fabien Dubosson +Fabien O'Carroll +Fabio Zendhi Nagao +Faiza Alsaied +Fauntleroy +fbuchinger +feizhang365 +Felipe Lalanne +Felix Raab +ficristo +Filip Noetzel +Filip Stollár +flack +Florian Felten +ForbesLindesay +Forbes Lindesay +Ford_Lawnmower +Forrest Oliphant +Franco Catena +Frank Wiegand +Fredrik Borg +Gabriel Gheorghian +Gabriel Horner +Gabriel Nahmias +galambalazs +Gary Sheng +Gautam Mehta +Gavin Douglas +gekkoe +Geordie Hall +George Stephanis +geowarin +Gerard Braad +Gergely Hegykozi +Giovanni Calò +Glebov Boris +Glenn Jorde +Glenn Ruehle +Golevka +Google Inc. +Gordon Smith +Grant Skinner +greengiant +Gregory Koberger +Grzegorz Mazur +Guan Gui +Guillaume Massé +Guillaume Massé +guraga +Gustavo Rodrigues +Hakan Tunc +Hans Engel +Hardest +Harshvardhan Gupta +Hasan Karahan +Hector Oswaldo Caballero +Hendrik Wallbaum +Henrik Haugbølle +Herculano Campos +Hiroyuki Makino +hitsthings +Hocdoc +Hugues Malphettes +Ian Beck +Ian Davies +Ian Dickinson +Ian Wehrman +Ian Wetherbee +Ice White +ICHIKAWA, Yuji +idleberg +ilvalle +Ingo Richter +Irakli Gozalishvili +Ivan Kurnosov +Ivoah +Jacob Lee +Jaimin +Jake Peyser +Jakob Miland +Jakub Vrana +Jakub Vrána +James Campos +James Howard +James Thorne +Jamie Hill +Jamie Morris +Jan Jongboom +jankeromnes +Jan Keromnes +Jan Odvarko +Jan Schär +Jan T. Sott +Jared Dean +Jared Forsyth +Jared Jacobs +Jason +Jason Barnabe +Jason Grout +Jason Johnston +Jason San Jose +Jason Siefken +Jayaprabhakar +Jaydeep Solanki +Jean Boussier +Jeff Blaisdell +Jeff Hanke +Jeff Jenkins +jeffkenton +Jeff Pickhardt +jem (graphite) +Jeremy Parmenter +Jim +Jim Avery +jkaplon +JobJob +jochenberger +Jochen Berger +Joel Einbinder +joelpinheiro +Johan Ask +John Connor +John-David Dalton +John Engler +John Lees-Miller +John Snelson +John Van Der Loo +Jon Ander Peñalba +Jonas Döbertin +Jonas Helfer +Jonathan Hart +Jonathan Malmaud +Jon Gacnik +jongalloway +Jon Malmaud +Jon Sangster +Joost-Wim Boekesteijn +Joseph Pecoraro +Josh Barnes +Josh Cohen +Josh Soref +Joshua Newman +Josh Watzman +jots +jsoojeon +ju1ius +Juan Benavides Romero +Jucovschi Constantin +Juho Vuori +Julien CROUZET +Julien Rebetez +Justin Andresen +Justin Hileman +jwallers@gmail.com +kaniga +karevn +Kayur Patel +Kazuhito Hokamura +Ken Newman +ken restivo +Ken Rockot +Kevin Earls +Kevin Kwok +Kevin Muret +Kevin Sawicki +Kevin Ushey +Klaus Silveira +Koh Zi Han, Cliff +komakino +Konstantin Lopuhin +koops +Kris Ciccarello +ks-ifware +kubelsmieci +KwanEsq +Kyle Kelley +KyleMcNutt +Lanfei +Lanny +Laszlo Vidacs +leaf corcoran +Leonid Khachaturov +Leon Sorokin +Leonya Khachaturov +Liam Newman +Libo Cannici +LloydMilligan +LM +lochel +Lorenzo Stoakes +Louis Mauchet +Luca Fabbri +Luciano Longo +Lu Fangjian +Luke Browning +Luke Granger-Brown +Luke Stagner +lynschinzer +M1cha +Madhura Jayaratne +Maksim Lin +Maksym Taran +Malay Majithia +Manideep +Manuel Rego Casasnovas +Marat Dreizin +Marcel Gerber +Marcelo Camargo +Marco Aurélio +Marco Munizaga +Marcus Bointon +Marek Rudnicki +Marijn Haverbeke +Mário Gonçalves +Mario Pietsch +Mark Anderson +Mark Lentczner +Marko Bonaci +Mark Peace +Markus Bordihn +Markus Olsson +Martin Balek +Martín Gaitán +Martin Hasoň +Martin Hunt +Martin Laine +Martin Zagora +Mason Malone +Mateusz Paprocki +Mathias Bynens +mats cronqvist +Matt Gaide +Matthew Bauer +Matthew Beale +matthewhayes +Matthew Rathbone +Matthias Bussonnier +Matthias BUSSONNIER +Matt McDonald +Matt Pass +Matt Sacks +mauricio +Maximilian Hils +Maxim Kraev +Max Kirsch +Max Schaefer +Max Xiantu +mbarkhau +McBrainy +mce2 +melpon +Metatheos +Micah Dubinko +Michael +Michael Goderbauer +Michael Grey +Michael Kaminsky +Michael Lehenbauer +Michael Walker +Michael Zhou +Michal Čihař +Michal Dorner +Mighty Guava +Miguel Castillo +mihailik +Mike +Mike Brevoort +Mike Diaz +Mike Ivanov +Mike Kadin +Mike Kobit +MinRK +Miraculix87 +misfo +mkaminsky11 +mloginov +Moritz Schwörer +Moshe Wajnberg +mps +ms +mtaran-google +Mu-An Chiou +mzabuawala +Narciso Jaramillo +Nathan Williams +ndr +nerbert +NetworkNode +nextrevision +ngn +nguillaumin +Ng Zhi An +Nicholas Bollweg +Nicholas Bollweg (Nick) +Nick Kreeger +Nick Small +Nicolas Kick +Nicolò Ribaudo +Niels van Groningen +nightwing +Nikita Beloglazov +Nikita Vasilyev +Nikolay Kostov +nilp0inter +Nisarg Jhaveri +nlwillia +noragrossman +Norman Rzepka +opl- +Oreoluwa Onatemowo +Oskar Segersvärd +pablo +pabloferz +Pablo Zubieta +Page +paladox +Panupong Pasupat +paris +Paris +Paris Kasidiaris +Patil Arpith +Patrick Stoica +Patrick Strawderman +Paul Garvin +Paul Ivanov +Paul Masson +Pavel +Pavel Feldman +Pavel Petržela +Pavel Strashkin +Paweł Bartkiewicz +peteguhl +peter +Peter Flynn +peterkroon +Peter Kroon +Philipp A +Philip Stadermann +Pi Delport +Pierre Gerold +Pieter Ouwerkerk +Pontus Melke +prasanthj +Prasanth J +Prayag Verma +Radek Piórkowski +Rahul +Rahul Anand +ramwin1 +Randall Mason +Randy Burden +Randy Edmunds +Rasmus Erik Voel Jensen +Rasmus Schultz +ray ratchup +Ray Ratchup +Remi Nyborg +Renaud Durlin +Richard Denton +Richard van der Meer +Richard Z.H. Wang +Rishi Goomar +Robert Brignull +Robert Crossfield +Roberto Abdelkader Martínez Pérez +robertop23 +Robert Plummer +Rrandom +Rrrandom +Ruslan Osmanov +Ryan Petrello +Ryan Prior +sabaca +Sam Lee +Sam Rawlins +Samuel Ainsworth +Sam Wilson +sandeepshetty +Sander AKA Redsandro +Sander Verweij +santec +Sarah McAlear and Wenlin Zhang +Sascha Peilicke +satamas +satchmorun +sathyamoorthi +Saul Costa +S. Chris Colbert +SCLINIC\jdecker +Scott Aikin +Scott Goodhew +Sebastian Wilzbach +Sebastian Zaha +Sergey Goder +Sergey Tselovalnikov +Se-Won Kim +shaund +shaun gilchrist +Shawn A +Shea Bunge +sheopory +Shil S +Shiv Deepak +Shmuel Englard +Shubham Jain +Siamak Mokhtari +silverwind +Simon Edwards +sinkuu +snasa +soliton4 +sonson +spastorelli +srajanpaliwal +Stanislav Oaserele +Stas Kobzar +Stefan Borsje +Steffen Beyer +Steffen Bruchmann +Steffen Kowalski +Stephen Lavelle +Steve Champagne +Steve Hoover +Steve O'Hara +stoskov +Stu Kennedy +Sungho Kim +sverweij +Taha Jahangir +takamori +Tako Schotanus +Takuji Shimokawa +Takuya Matsuyama +Tarmil +TDaglis +tel +Tentone +tfjgeorge +Thaddee Tyl +thanasis +TheHowl +themrmax +think +Thomas Brouard +Thomas Dvornik +Thomas Kluyver +Thomas Schmid +Tim Alby +Tim Baumann +Timothy Farrell +Timothy Gu +Timothy Hatcher +TobiasBg +Todd Berman +Todd Kennedy +Tomas-A +Tomas Varaneckas +Tom Erik Støwer +Tom Klancer +Tom MacWright +Tony Jian +Travis Heppe +Triangle717 +Tristan Tarrant +TSUYUSATO Kitsune +twifkak +Tyler Long +VapidWorx +Vestimir Markov +vf +Victor Bocharsky +Vincent Woo +Volker Mische +vtripolitakis +Weiyan Shao +wenli +Wes Cossick +Wesley Wiser +Weston Ruter +Will Binns-Smith +Will Dean +William Jamieson +William Stein +Willy +Wojtek Ptak +Wu Cheng-Han +Xavier Mendez +Yassin N. Hassan +YNH Webdev +Yunchi Luo +Yuvi Panda +Yvonnick Esnault +Zac Anger +Zachary Dremann +Zeno Rocha +Zhang Hao +Ziv +zziuni +魏鹏刚 diff --git a/backend/webif/static/codemirror/CHANGELOG.md b/backend/webif/static/codemirror/CHANGELOG.md new file mode 100755 index 000000000..f81fcdd07 --- /dev/null +++ b/backend/webif/static/codemirror/CHANGELOG.md @@ -0,0 +1,1272 @@ +## 5.32.0 (2017-11-22) + +### Bug fixes + +Increase contrast on default bracket-matching colors. + +[javascript mode](http://codemirror.net/mode/javascript/): Recognize TypeScript type parameters for calls, type guards, and type parameter defaults. Improve handling of `enum` and `module` keywords. + +[comment addon](http://codemirror.net/doc/manual.html#addon_comment): Fix bug when uncommenting a comment that spans all but the last selected line. + +[searchcursor addon](http://codemirror.net/doc/manual.html#addon_searchcursor): Fix bug in case folding. + +[emacs bindings](http://codemirror.net/demo/emacs.html): Prevent single-character deletions from resetting the kill ring. + +[closebrackets addon](http://codemirror.net/doc/manual.html#addon_closebrackets): Tweak quote matching behavior. + +### New features + +[continuelist addon](http://codemirror.net/doc/manual.html#addon_continuelist): Increment ordered list numbers when adding one. + +## 5.31.0 (2017-10-20) + +### Bug fixes + +Further improve selection drawing and cursor motion in right-to-left documents. + +[vim bindings](http://codemirror.net/demo/vim.html): Fix ctrl-w behavior, support quote-dot and backtick-dot marks, make the wide cursor visible in contentEditable [input mode](http://codemirror.net/doc/manual.html#option_contentEditable). + +[continuecomment addon](http://codemirror.net/doc/manual.html#addon_continuecomment): Fix bug when pressing enter after a single-line block comment. + +[markdown mode](http://codemirror.net/mode/markdown/): Fix issue with leaving indented fenced code blocks. + +[javascript mode](http://codemirror.net/mode/javascript/): Fix bad parsing of operators without spaces between them. Fix some corner cases around semicolon insertion and regexps. + +### New features + +Modes added with [`addOverlay`](http://codemirror.net/doc/manual.html#addOverlay) now have access to a [`baseToken`](http://codemirror.net/doc/manual.html#baseToken) method on their input stream, giving access to the tokens of the underlying mode. + +## 5.30.0 (2017-09-20) + +### Bug fixes + +Fixed a number of issues with drawing right-to-left selections and mouse selection in bidirectional text. + +[search addon](http://codemirror.net/demo/search/): Fix crash when restarting search after doing empty search. + +[mark-selection addon](http://cm/doc/manual.html#addon_mark-selection): Fix off-by-one bug. + +[tern addon](http://codemirror.net/demo/tern.html): Fix bad request made when editing at the bottom of a large document. + +[javascript mode](http://codemirror.net/mode/javascript/): Improve parsing in a number of corner cases. + +[markdown mode](http://codemirror.net/mode/markdown/): Fix crash when a sub-mode doesn't support indentation, allow uppercase X in task lists. + +[gfm mode](http://codemirror.net/mode/gfm/): Don't highlight SHA1 'hashes' without numbers to avoid false positives. + +[soy mode](http://codemirror.net/mode/soy/): Support injected data and `@param` in comments. + +### New features + +[simple mode addon](http://codemirror.net/demo/simplemode.html): Allow groups in regexps when `token` isn't an array. + +## 5.29.0 (2017-08-24) + +### Bug fixes + +Fix crash in contentEditable input style when editing near a bookmark. + +Make sure change origins are preserved when splitting changes on [read-only marks](http://codemirror.net/doc/manual.html#mark_readOnly). + +[javascript mode](http://codemirror.net/mode/javascript/): More support for TypeScript syntax. + +[d mode](http://codemirror.net/mode/d/): Support nested comments. + +[python mode](http://codemirror.net/mode/python/): Improve tokenizing of operators. + +[markdown mode](http://codemirror.net/mode/markdown/): Further improve CommonMark conformance. + +[css mode](http://codemirror.net/mode/css/): Don't run comment tokens through the mode's state machine. + +[shell mode](http://codemirror.net/mode/shell/): Allow strings to span lines. + +[search addon](http://codemirror.net/demo/search/): Fix crash in persistent search when `extraKeys` is null. + +## 5.28.0 (2017-07-21) + +### Bug fixes + +Fix copying of, or replacing editor content with, a single dash character when copying a big selection in some corner cases. + +Make [`"goLineLeft"`](http://codemirror.net/doc/manual.html#command_goLineLeft)/`"goLineRight"` behave better on wrapped lines. + +[sql mode](http://codemirror.net/mode/sql/): Fix tokenizing of multi-dot operator and allow digits in subfield names. + +[searchcursor addon](http://codemirror.net/doc/manual.html#addon_searchcursor): Fix infinite loop on some composed character inputs. + +[markdown mode](http://codemirror.net/mode/markdown/): Make list parsing more CommonMark-compliant. + +[gfm mode](http://codemirror.net/mode/gfm/): Highlight colon syntax for emoji. + +### New features + +Expose [`startOperation`](http://codemirror.net/doc/manual.html#startOperation) and `endOperation` for explicit operation management. + +[sublime bindings](http://codemirror.net/demo/sublime.html): Add extend-selection (Ctrl-Alt- or Cmd-Shift-Up/Down). + +## 5.27.4 (2017-06-29) + +### Bug fixes + +Fix crash when using mode lookahead. + +[markdown mode](http://codemirror.net/mode/markdown/): Don't block inner mode's indentation support. + +## 5.27.2 (2017-06-22) + +### Bug fixes + +Fix crash in the [simple mode](http://codemirror.net/demo/simplemode.html)< addon. + +## 5.27.0 (2017-06-22) + +### Bug fixes + +Fix infinite loop in forced display update. + +Properly disable the hidden textarea when `readOnly` is `"nocursor"`. + +Calling the `Doc` constructor without `new` works again. + +[sql mode](http://codemirror.net/mode/sql/): Handle nested comments. + +[javascript mode](http://codemirror.net/mode/javascript/): Improve support for TypeScript syntax. + +[markdown mode](http://codemirror.net/mode/markdown/): Fix bug where markup was ignored on indented paragraph lines. + +[vim bindings](http://codemirror.net/demo/vim.html): Referencing invalid registers no longer causes an uncaught exception. + +[rust mode](http://codemirror.net/mode/rust/): Add the correct MIME type. + +[matchbrackets addon](http://codemirror.net/doc/manual.html#addon_matchbrackets): Document options. + +### New features + +Mouse button clicks can now be bound in keymaps by using names like `"LeftClick"` or `"Ctrl-Alt-MiddleTripleClick"`. When bound to a function, that function will be passed the position of the click as second argument. + +The behavior of mouse selection and dragging can now be customized with the [`configureMouse`](http://codemirror.net/doc/manual.html#option_configureMouse) option. + +Modes can now look ahead across line boundaries with the [`StringStream`](http://codemirror.net/doc/manual.html#StringStream)`.lookahead` method. + +Introduces a `"type"` token type, makes modes that recognize types output it, and add styling for it to the themes. + +New [`pasteLinesPerSelection`](http://codemirror.net/doc/manual.html#option_pasteLinesPerSelection) option to control the behavior of pasting multiple lines into multiple selections. + +[searchcursor addon](http://codemirror.net/doc/manual.html#addon_searchcursor): Support multi-line regular expression matches, and normalize strings when matching. + +## 5.26.0 (2017-05-22) + +### Bug fixes + +In textarea-mode, don't reset the input field during composition. + +More careful restoration of selections in widgets, during editor redraw. + +[javascript mode](http://codemirror.net/mode/javascript/): More TypeScript parsing fixes. + +[julia mode](http://codemirror.net/mode/julia/): Fix issue where the mode gets stuck. + +[markdown mode](http://codemirror.net/mode/markdown/): Understand cross-line links, parse all bracketed things as links. + +[soy mode](http://codemirror.net/mode/soy/): Support single-quoted strings. + +[go mode](http://codemirror.net/mode/go/): Don't try to indent inside strings or comments. + +### New features + +[vim bindings](http://codemirror.net/demo/vim.html): Parse line offsets in line or range specs. + +## 5.25.2 (2017-04-20) + +### Bug fixes + +Better handling of selections that cover the whole viewport in contentEditable-mode. + +No longer accidentally scroll the editor into view when calling `setValue`. + +Work around Chrome Android bug when converting screen coordinates to editor positions. + +Make sure long-clicking a selection sets a cursor and doesn't show the editor losing focus. + +Fix issue where pointer events were incorrectly disabled on Chrome's overlay scrollbars. + +[javascript mode](http://codemirror.net/mode/javascript/): Recognize annotations and TypeScript-style type parameters. + +[shell mode](http://codemirror.net/mode/shell/): Handle nested braces. + +[markdown mode](http://codemirror.net/mode/markdown/): Make parsing of strong/em delimiters CommonMark-compliant. + +## 5.25.0 (2017-03-20) + +### Bug fixes + +In contentEditable-mode, properly locate changes that repeat a character when inserted with IME. + +Fix handling of selections bigger than the viewport in contentEditable mode. + +Improve handling of changes that insert or delete lines in contentEditable mode. + +Count Unicode control characters 0x80 to 0x9F as special (non-printing) chars. + +Fix handling of shadow DOM roots when finding the active element. + +Add `role=presentation` to more DOM elements to improve screen reader support. + +[merge addon](http://codemirror.net/doc/manual.html#addon_merge): Make aligning of unchanged chunks more robust. + +[comment addon](http://codemirror.net/doc/manual.html#addon_comment): Fix comment-toggling on a block of text that starts and ends in a (differnet) block comment. + +[javascript mode](http://codemirror.net/mode/javascript/): Improve support for TypeScript syntax. + +[r mode](http://codemirror.net/mode/r/): Fix indentation after semicolon-less statements. + +[shell mode](http://codemirror.net/mode/shell/): Properly handle escaped parentheses in parenthesized expressions. + +[markdown mode](http://codemirror.net/mode/markdown/): Fix a few bugs around leaving fenced code blocks. + +[soy mode](http://codemirror.net/mode/soy/): Improve indentation. + +### New features + +[lint addon](http://codemirror.net/doc/manual.html#addon_lint): Support asynchronous linters that return promises. + +[continuelist addon](http://codemirror.net/doc/manual.html#addon_continuelist): Support continuing task lists. + +[vim bindings](http://codemirror.net/demo/vim.html): Make Y behave like yy. + +[sql mode](http://codemirror.net/mode/sql/): Support sqlite dialect. + +## 5.24.2 (2017-02-22) + +### Bug fixes + +[javascript mode](http://codemirror.net/mode/javascript/): Support computed class method names. + +[merge addon](http://codemirror.net/doc/manual.html#addon_merge): Improve aligning of unchanged code in the presence of marks and line widgets. + +## 5.24.0 (2017-02-20) + +### Bug fixes + +A cursor directly before a line-wrapping break is now drawn before or after the line break depending on which direction you arrived from. + +Visual cursor motion in line-wrapped right-to-left text should be much more correct. + +Fix bug in handling of read-only marked text. + +[shell mode](http://codemirror.net/mode/shell/): Properly tokenize nested parentheses. + +[python mode](http://codemirror.net/mode/python/): Support underscores in number literals. + +[sass mode](http://codemirror.net/mode/sass/): Uses the full list of CSS properties and keywords from the CSS mode, rather than defining its own incomplete subset. + +[css mode](http://codemirror.net/mode/css/): Expose `lineComment` property for LESS and SCSS dialects. Recognize vendor prefixes on pseudo-elements. + +[julia mode](http://codemirror.net/mode/julia/): Properly indent `elseif` lines. + +[markdown mode](http://codemirror.net/mode/markdown/): Properly recognize the end of fenced code blocks when inside other markup. + +[scala mode](http://codemirror.net/mode/clike/): Improve handling of operators containing #, @, and : chars. + +[xml mode](http://codemirror.net/mode/xml/): Allow dashes in HTML tag names. + +[javascript mode](http://codemirror.net/mode/javascript/): Improve parsing of async methods, TypeScript-style comma-separated superclass lists. + +[indent-fold addon](http://codemirror.net/demo/folding.html): Ignore comment lines. + +### New features + +Positions now support a `sticky` property which determines whether they should be associated with the character before (value `"before"`) or after (value `"after"`) them. + +[vim bindings](http://codemirror.net/demo/vim.html): Make it possible to remove built-in bindings through the API. + +[comment addon](http://codemirror.net/doc/manual.html#addon_comment): Support a per-mode useInnerComments option to optionally suppress descending to the inner modes to get comment strings. + +### Breaking changes + +The [sass mode](http://codemirror.net/mode/sass/) now depends on the [css mode](http://codemirror.net/mode/css/). + +## 5.23.0 (2017-01-19) + +### Bug fixes + +Presentation-related elements DOM elements are now marked as such to help screen readers. + +[markdown mode](http://codemirror.net/mode/markdown/): Be more picky about what HTML tags look like to avoid false positives. + +### New features + +`findModeByMIME` now understands `+json` and `+xml` MIME suffixes. + +[closebrackets addon](http://codemirror.net/doc/manual.html#addon_closebrackets): Add support for an `override` option to ignore language-specific defaults. + +[panel addon](http://codemirror.net/doc/manual.html#addon_panel): Add a `stable` option that auto-scrolls the content to keep it in the same place when inserting/removing a panel. + +## 5.22.2 (2017-01-12) + +### Bug fixes + +Include rollup.config.js in NPM package, so that it can be used to build from source. + +## 5.22.0 (2016-12-20) + +### Bug fixes + +[sublime bindings](http://codemirror.net/demo/sublime.html): Make `selectBetweenBrackets` work with multiple cursors. + +[javascript mode](http://codemirror.net/mode/javascript/): Fix issues with parsing complex TypeScript types, imports, and exports. + +A contentEditable editor instance with autofocus enabled no longer crashes during initializing. + +### New features + +[emacs bindings](http://codemirror.net/demo/emacs.html): Export `CodeMirror.emacs` to allow other addons to hook into Emacs-style functionality. + +[active-line addon](http://codemirror.net/doc/manual.html#addon_active-line): Add `nonEmpty` option. + +New event: [`optionChange`](http://codemirror.net/doc/manual.html#event_optionChange). + +## 5.21.0 (2016-11-21) + +### Bug fixes + +Tapping/clicking the editor in [contentEditable mode](http://codemirror.net/doc/manual.html#option_inputStyle) on Chrome now puts the cursor at the tapped position. + +Fix various crashes and misbehaviors when reading composition events in [contentEditable mode](http://codemirror.net/doc/manual.html#option_inputStyle). + +Catches and ignores an IE 'Unspecified Error' when creating an editor in an iframe before there is a ``. + +[merge addon](http://codemirror.net/doc/manual.html#addon_merge): Fix several issues in the chunk-aligning feature. + +[verilog mode](http://codemirror.net/mode/verilog): Rewritten to address various issues. + +[julia mode](http://codemirror.net/mode/julia): Recognize Julia 0.5 syntax. + +[swift mode](http://codemirror.net/mode/swift): Various fixes and adjustments to current syntax. + +[markdown mode](http://codemirror.net/mode/markdown): Allow lists without a blank line above them. + +### New features + +The [`setGutterMarker`](http://codemirror.net/doc/manual.html#setGutterMarker), [`clearGutter`](http://codemirror.net/doc/manual.html#clearGutter), and [`lineInfo`](http://codemirror.net/doc/manual.html#lineInfo) methods are now available on `Doc` objects. + +The [`heightAtLine`](http://codemirror.net/doc/manual.html#heightAtLine) method now takes an extra argument to allow finding the height at the top of the line's line widgets. + +[ruby mode](http://codemirror.net/mode/ruby): `else` and `elsif` are now immediately indented. + +[vim bindings](http://codemirror.net/demo/vim.html): Bind Ctrl-T and Ctrl-D to in- and dedent in insert mode. + +## 5.20.2 (2016-10-21) + +### Bug fixes + +Fix `CodeMirror.version` returning the wrong version number. + +## 5.20.0 (2016-10-20) + +### Bug fixes + +Make `newlineAndIndent` command work with multiple cursors on the same line. + +Make sure keypress events for backspace are ignored. + +Tokens styled with overlays no longer get a nonsense `cm-cm-overlay` class. + +Line endings for pasted content are now normalized to the editor's [preferred ending](http://codemirror.net/doc/manual.html#option_lineSeparator). + +[javascript mode](http://codemirror.net/mode/javascript): Improve support for class expressions. Support TypeScript optional class properties, the `abstract` keyword, and return type declarations for arrow functions. + +[css mode](http://codemirror.net/mode/css): Fix highlighting of mixed-case keywords. + +[closebrackets addon](http://codemirror.net/doc/manual.html#addon_closebrackets): Improve behavior when typing a quote before a string. + +### New features + +The core is now maintained as a number of small files, using ES6 syntax and modules, under the `src/` directory. A git checkout no longer contains a working `codemirror.js` until you `npm build` (but when installing from NPM, it is included). + +The [`refresh`](http://codemirror.net/doc/manual.html#event_refresh) event is now documented and stable. + +## 5.19.0 (2016-09-20) + +### Bugfixes + +[erlang mode](http://codemirror.net/mode/erlang): Fix mode crash when trying to read an empty context. + +[comment addon](http://codemirror.net/doc/manual.html#addon_comment): Fix broken behavior when toggling comments inside a comment. + +xml-fold addon: Fix a null-dereference bug. + +Page up and page down now do something even in single-line documents. + +Fix an issue where the cursor position could be off in really long (~8000 character) tokens. + +### New features + +[javascript mode](http://codemirror.net/mode/javascript): Better indentation when semicolons are missing. Better support for TypeScript classes, optional parameters, and the `type` keyword. + +The [`blur`](http://codemirror.net/doc/manual.html#event_blur) and [`focus`](http://codemirror.net/doc/manual.html#event_focus) events now pass the DOM event to their handlers. + +## 5.18.2 (2016-08-23) + +### Bugfixes + +[vue mode](http://codemirror.net/mode/vue): Fix outdated references to renamed Pug mode dependency. + +## 5.18.0 (2016-08-22) + +### Bugfixes + +Make sure [gutter backgrounds](http://codemirror.net/doc/manual.html#addLineClass) stick to the rest of the gutter during horizontal scrolling. + +The contenteditable [`inputStyle`](http://codemirror.net/doc/manual.html#option_inputStyle) now properly supports pasting on pre-Edge IE versions. + +[javascript mode](http://codemirror.net/mode/javascript): Fix some small parsing bugs and improve TypeScript support. + +[matchbrackets addon](http://codemirror.net/doc/manual.html#addon_matchbrackets): Fix bug where active highlighting was left in editor when the addon was disabled. + +[match-highlighter addon](http://codemirror.net/doc/manual.html#addon_match-highlighter): Only start highlighting things when the editor gains focus. + +[javascript-hint addon](http://codemirror.net/doc/manual.html#addon_javascript-hint): Also complete non-enumerable properties. + +### New features + +The [`addOverlay`](http://codemirror.net/doc/manual.html#addOverlay) method now supports a `priority` option to control the order in which overlays are applied. + +MIME types that end in `+json` now default to the JSON mode when the MIME itself is not defined. + +### Breaking changes + +The mode formerly known as Jade was renamed to [Pug](http://codemirror.net/mode/pug). + +The [Python mode](http://codemirror.net/mode/python) now defaults to Python 3 (rather than 2) syntax. + +## 5.17.0 (2016-07-19) + +### Bugfixes + +Fix problem with wrapped trailing whitespace displaying incorrectly. + +Prevent IME dialog from overlapping typed content in Chrome. + +Improve measuring of characters near a line wrap. + +[javascript mode](http://codemirror.net/mode/javascript): Improve support for `async`, allow trailing commas in `import` lists. + +[vim bindings](http://codemirror.net/demo/vim.html): Fix backspace in replace mode. + +[sublime bindings](http://codemirror.net/demo/sublime.html): Fix some key bindings on OS X to match Sublime Text. + +### New features + +[markdown mode](http://codemirror.net/mode/markdown): Add more classes to image links in highlight-formatting mode. + +## 5.16.0 (2016-06-20) + +### Bugfixes + +Fix glitches when dragging content caused by the drop indicator receiving mouse events. + +Make Control-drag work on Firefox. + +Make clicking or selection-dragging at the end of a wrapped line select the right position. + +[show-hint addon](http://codemirror.net/doc/manual.html#addon_show-hint): Prevent widget scrollbar from hiding part of the hint text. + +[rulers addon](http://codemirror.net/doc/manual.html#addon_rulers): Prevent rulers from forcing a horizontal editor scrollbar. + +### New features + +[search addon](http://codemirror.net/doc/manual.html#addon_search): Automatically bind search-related keys in persistent dialog. + +[sublime keymap](http://codemirror.net/demo/sublime.html): Add a multi-cursor aware smart backspace binding. + +## 5.15.2 (2016-05-20) + +### Bugfixes + +Fix a critical document corruption bug that occurs when a document is gradually grown. + +## 5.15.0 (2016-05-20) + +### Bugfixes + +Fix bug that caused the selection to reset when focusing the editor in contentEditable input mode. + +Fix issue where not all ASCII control characters were being replaced by placeholders. + +Remove the assumption that all modes have a `startState` method from several wrapping modes. + +Fix issue where the editor would complain about overlapping collapsed ranges when there weren't any. + +Optimize document tree building when loading or pasting huge chunks of content. + +[markdown mode](http://codemirror.net/mode/markdown/): Fix several issues in matching link targets. + +[clike mode](http://codemirror.net/mode/clike/): Improve indentation of C++ template declarations. + +### New features + +Explicitly bind Ctrl-O on OS X to make that binding (“open line”) act as expected. + +Pasting [linewise-copied](http://codemirror.net/doc/manual.html#option_lineWiseCopyCut) content when there is no selection now inserts the lines above the current line. + +[javascript mode](http://codemirror.net/mode/javascript/): Support `async`/`await` and improve support for TypeScript type syntax. + +## 5.14.2 (2016-04-20) + +### Bugfixes + +Push a new package to NPM due to an [NPM bug](https://github.com/npm/npm/issues/5082) omitting the LICENSE file in 5.14.0. + +Set `dataTransfer.effectAllowed` in `dragstart` handler to help browsers use the right drag icon. + +Add the [mbox mode](http://codemirror.net/mode/mbox/index.html) to `mode/meta.js`. + +## 5.14.0 (2016-04-20) + +### Bugfixes + +[`posFromIndex`](http://codemirror.net/doc/manual.html#posFromIndex) and [`indexFromPos`](http://codemirror.net/doc/manual.html#indexFromPos) now take [`lineSeparator`](http://codemirror.net/doc/manual.html#option_lineSeparator) into account. + +[vim bindings](http://codemirror.net/demo/vim.html): Only call `.save()` when it is actually available. + +[comment addon](http://codemirror.net/doc/manual.html#addon_comment): Be careful not to mangle multi-line strings. + +[Python mode](http://codemirror.net/mode/python/index.html): Improve distinguishing of decorators from `@` operators. + +[`findMarks`](http://codemirror.net/doc/manual.html#findMarks): No longer return marks that touch but don't overlap given range. + +### New features + +[vim bindings](http://codemirror.net/demo/vim.html): Add yank command. + +[match-highlighter addon](http://codemirror.net/doc/manual.html#addon_match-highlighter): Add `trim` option to disable ignoring of whitespace. + +[PowerShell mode](http://codemirror.net/mode/powershell/index.html): Added. + +[Yacas mode](http://codemirror.net/mode/yacas/index.html): Added. + +[Web IDL mode](http://codemirror.net/mode/webidl/index.html): Added. + +[SAS mode](http://codemirror.net/mode/sas/index.html): Added. + +[mbox mode](http://codemirror.net/mode/mbox/index.html): Added. + +## 5.13.2 (2016-03-23) + +### Bugfixes + +Solves a problem where the gutter would sometimes not extend all the way to the end of the document. + +## 5.13.0 (2016-03-21) + +### New features + +New DOM event forwarded: [`"dragleave"`](http://codemirror.net/doc/manual.html#event_dom). + +[protobuf mode](http://codemirror.net/mode/protobuf/index.html): Newly added. + +### Bugfixes + +Fix problem where [`findMarks`](http://codemirror.net/doc/manual.html#findMarks) sometimes failed to find multi-line marks. + +Fix crash that showed up when atomic ranges and bidi text were combined. + +[show-hint addon](http://codemirror.net/demo/complete.html): Completion widgets no longer close when the line indented or dedented. + +[merge addon](http://codemirror.net/demo/merge.html): Fix bug when merging chunks at the end of the file. + +[placeholder addon](http://codemirror.net/doc/manual.html#addon_placeholder): No longer gets confused by [`swapDoc`](http://codemirror.net/doc/manual.html#swapDoc). + +[simplescrollbars addon](http://codemirror.net/doc/manual.html#addon_simplescrollbars): Fix invalid state when deleting at end of document. + +[clike mode](http://codemirror.net/mode/clike/index.html): No longer gets confused when a comment starts after an operator. + +[markdown mode](http://codemirror.net/mode/markdown/index.html): Now supports CommonMark-style flexible list indentation. + +[dylan mode](http://codemirror.net/mode/dylan/index.html): Several improvements and fixes. + +## 5.12.0 (2016-02-19) + +### New features + +[Vim bindings](http://codemirror.net/demo/vim.html): Ctrl-Q is now an alias for Ctrl-V. + +[Vim bindings](http://codemirror.net/demo/vim.html): The Vim API now exposes an `unmap` method to unmap bindings. + +[active-line addon](http://codemirror.net/demo/activeline.html): This addon can now style the active line's gutter. + +[FCL mode](http://codemirror.net/mode/fcl/): Newly added. + +[SQL mode](http://codemirror.net/mode/sql/): Now has a Postgresql dialect. + +### Bugfixes + +Fix [issue](https://github.com/codemirror/CodeMirror/issues/3781) where trying to scroll to a horizontal position outside of the document's width could cause the gutter to be positioned incorrectly. + +Use absolute, rather than fixed positioning in the context-menu intercept hack, to work around a [problem](https://github.com/codemirror/CodeMirror/issues/3238) when the editor is inside a transformed parent container. + +Solve a [problem](https://github.com/codemirror/CodeMirror/issues/3821) where the horizontal scrollbar could hide text in Firefox. + +Fix a [bug](https://github.com/codemirror/CodeMirror/issues/3834) that caused phantom scroll space under the text in some situations. + +[Sublime Text bindings](http://codemirror.net/demo/sublime.html): Bind delete-line to Shift-Ctrl-K on OS X. + +[Markdown mode](http://codemirror.net/mode/markdown/): Fix [issue](https://github.com/codemirror/CodeMirror/issues/3787) where the mode would keep state related to fenced code blocks in an unsafe way, leading to occasional corrupted parses. + +[Markdown mode](http://codemirror.net/mode/markdown/): Ignore backslashes in code fragments. + +[Markdown mode](http://codemirror.net/mode/markdown/): Use whichever mode is registered as `text/html` to parse HTML. + +[Clike mode](http://codemirror.net/mode/clike/): Improve indentation of Scala `=>` functions. + +[Python mode](http://codemirror.net/mode/python/): Improve indentation of bracketed code. + +[HTMLMixed mode](http://codemirror.net/mode/htmlmixed/): Support multi-line opening tags for sub-languages (` + + + + + +
+

Active Line Demo

+
+ + + +

Styling the current cursor line.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/anywordhint.html b/backend/webif/static/codemirror/demo/anywordhint.html new file mode 100755 index 000000000..0a7caece2 --- /dev/null +++ b/backend/webif/static/codemirror/demo/anywordhint.html @@ -0,0 +1,79 @@ + + +CodeMirror: Any Word Completion Demo + + + + + + + + + + + +
+

Any Word Completion Demo

+
+ +

Press ctrl-space to activate autocompletion. The +completion uses +the anyword-hint.js +module, which simply looks at nearby words in the buffer and completes +to those.

+ + +
diff --git a/backend/webif/static/codemirror/demo/bidi.html b/backend/webif/static/codemirror/demo/bidi.html new file mode 100755 index 000000000..645e648c8 --- /dev/null +++ b/backend/webif/static/codemirror/demo/bidi.html @@ -0,0 +1,106 @@ + + +CodeMirror: Bi-directional Text Demo + + + + + + + + + +
+

Bi-directional Text Demo

+
+
+ Editor default direction: + + +
+
+ HTML document direction: + + +
+
+ +
+
+ + + +

Demonstration of bi-directional text support. See + the related + blog post for more background.

+ +
diff --git a/backend/webif/static/codemirror/demo/btree.html b/backend/webif/static/codemirror/demo/btree.html new file mode 100755 index 000000000..ba07bc74f --- /dev/null +++ b/backend/webif/static/codemirror/demo/btree.html @@ -0,0 +1,83 @@ + + +CodeMirror: B-Tree visualization + + + + + + + + +
+

B-Tree visualization

+
+
+ + + +

+ +
diff --git a/backend/webif/static/codemirror/demo/buffers.html b/backend/webif/static/codemirror/demo/buffers.html new file mode 100755 index 000000000..16ffc7dfe --- /dev/null +++ b/backend/webif/static/codemirror/demo/buffers.html @@ -0,0 +1,109 @@ + + +CodeMirror: Multiple Buffer & Split View Demo + + + + + + + + + + +
+

Multiple Buffer & Split View Demo

+ + +
+
+ Select buffer: +     +
+
+
+ Select buffer: +     +
+ + + +

Demonstration of + using linked documents + to provide a split view on a document, and + using swapDoc + to use a single editor to display multiple documents.

+ +
diff --git a/backend/webif/static/codemirror/demo/changemode.html b/backend/webif/static/codemirror/demo/changemode.html new file mode 100755 index 000000000..9405932ab --- /dev/null +++ b/backend/webif/static/codemirror/demo/changemode.html @@ -0,0 +1,58 @@ + + +CodeMirror: Mode-Changing Demo + + + + + + + + + + +
+

Mode-Changing Demo

+
+ +

On changes to the content of the above editor, a (crude) script +tries to auto-detect the language used, and switches the editor to +either JavaScript or Scheme mode based on that.

+ + +
diff --git a/backend/webif/static/codemirror/demo/closebrackets.html b/backend/webif/static/codemirror/demo/closebrackets.html new file mode 100755 index 000000000..d702f5269 --- /dev/null +++ b/backend/webif/static/codemirror/demo/closebrackets.html @@ -0,0 +1,52 @@ + + +CodeMirror: Closebrackets Demo + + + + + + + + + + +
+

Closebrackets Demo

+
+ + +
diff --git a/backend/webif/static/codemirror/demo/closetag.html b/backend/webif/static/codemirror/demo/closetag.html new file mode 100755 index 000000000..79959d2c4 --- /dev/null +++ b/backend/webif/static/codemirror/demo/closetag.html @@ -0,0 +1,41 @@ + + +CodeMirror: Close-Tag Demo + + + + + + + + + + + + + + +
+

Close-Tag Demo

+
+ + +
diff --git a/backend/webif/static/codemirror/demo/complete.html b/backend/webif/static/codemirror/demo/complete.html new file mode 100755 index 000000000..0464389eb --- /dev/null +++ b/backend/webif/static/codemirror/demo/complete.html @@ -0,0 +1,126 @@ + + +CodeMirror: Autocomplete Demo + + + + + + + + + + + + + +
+

Autocomplete Demo

+
+ +

Press ctrl-space to activate autocompletion. Built +on top of the show-hint +and javascript-hint +addons.

+ +
+ + + +
diff --git a/backend/webif/static/codemirror/demo/emacs.html b/backend/webif/static/codemirror/demo/emacs.html new file mode 100755 index 000000000..c626b8d40 --- /dev/null +++ b/backend/webif/static/codemirror/demo/emacs.html @@ -0,0 +1,75 @@ + + +CodeMirror: Emacs bindings demo + + + + + + + + + + + + + + + + +
+

Emacs bindings demo

+
+ +

The emacs keybindings are enabled by +including keymap/emacs.js and setting +the keyMap option to "emacs". Because +CodeMirror's internal API is quite different from Emacs, they are only +a loose approximation of actual emacs bindings, though.

+ +

Also note that a lot of browsers disallow certain keys from being +captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the +result that idiomatic use of Emacs keys will constantly close your tab +or open a new window.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/folding.html b/backend/webif/static/codemirror/demo/folding.html new file mode 100755 index 000000000..1882b7c81 --- /dev/null +++ b/backend/webif/static/codemirror/demo/folding.html @@ -0,0 +1,133 @@ + + + + CodeMirror: Code Folding Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Code Folding Demo

+
+
JavaScript:
+
+
HTML:
+
+
Python:
+
+
Markdown:
+
+
+ +
+ diff --git a/backend/webif/static/codemirror/demo/fullscreen.html b/backend/webif/static/codemirror/demo/fullscreen.html new file mode 100755 index 000000000..1fbdc488e --- /dev/null +++ b/backend/webif/static/codemirror/demo/fullscreen.html @@ -0,0 +1,83 @@ + + +CodeMirror: Full Screen Editing + + + + + + + + + + + + +
+

Full Screen Editing

+
+ + +

Demonstration of + the fullscreen + addon. Press F11 when cursor is in the editor to + toggle full screen editing. Esc can also be used + to exit full screen editing.

+
diff --git a/backend/webif/static/codemirror/demo/hardwrap.html b/backend/webif/static/codemirror/demo/hardwrap.html new file mode 100755 index 000000000..84ba0cc0c --- /dev/null +++ b/backend/webif/static/codemirror/demo/hardwrap.html @@ -0,0 +1,75 @@ + + +CodeMirror: Hard-wrapping Demo + + + + + + + + + + +
+

Hard-wrapping Demo

+
+ +

Demonstration of +the hardwrap addon. +The above editor has its change event hooked up to +the wrapParagraphsInRange method, so that the paragraphs +are reflown as you are typing.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/html5complete.html b/backend/webif/static/codemirror/demo/html5complete.html new file mode 100755 index 000000000..411baae3e --- /dev/null +++ b/backend/webif/static/codemirror/demo/html5complete.html @@ -0,0 +1,56 @@ + + + + CodeMirror: HTML completion demo + + + + + + + + + + + + + + + + + + + +
+

HTML completion demo

+ +

Shows the XML completer + parameterized with information about the tags in HTML. + Press ctrl-space to activate completion.

+ +
+ + +
+ diff --git a/backend/webif/static/codemirror/demo/indentwrap.html b/backend/webif/static/codemirror/demo/indentwrap.html new file mode 100755 index 000000000..3d3d0af6a --- /dev/null +++ b/backend/webif/static/codemirror/demo/indentwrap.html @@ -0,0 +1,59 @@ + + +CodeMirror: Indented wrapped line demo + + + + + + + + + +
+

Indented wrapped line demo

+
+ +

This page uses a hack on top of the "renderLine" + event to make wrapped text line up with the base indentation of + the line.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/lint.html b/backend/webif/static/codemirror/demo/lint.html new file mode 100755 index 000000000..96009b4e1 --- /dev/null +++ b/backend/webif/static/codemirror/demo/lint.html @@ -0,0 +1,171 @@ + + +CodeMirror: Linter Demo + + + + + + + + + + + + + + + + + + +
+

Linter Demo

+ + +

+ +

+ +

+ + +
diff --git a/backend/webif/static/codemirror/demo/loadmode.html b/backend/webif/static/codemirror/demo/loadmode.html new file mode 100755 index 000000000..809cd9022 --- /dev/null +++ b/backend/webif/static/codemirror/demo/loadmode.html @@ -0,0 +1,72 @@ + + +CodeMirror: Lazy Mode Loading Demo + + + + + + + + + + +
+

Lazy Mode Loading Demo

+

Current mode: text/plain

+
+

Filename, mime, or mode name:

+ + +
diff --git a/backend/webif/static/codemirror/demo/marker.html b/backend/webif/static/codemirror/demo/marker.html new file mode 100755 index 000000000..3a8b85000 --- /dev/null +++ b/backend/webif/static/codemirror/demo/marker.html @@ -0,0 +1,52 @@ + + +CodeMirror: Breakpoint Demo + + + + + + + + + +
+

Breakpoint Demo

+
+ +

Click the line-number gutter to add or remove 'breakpoints'.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/markselection.html b/backend/webif/static/codemirror/demo/markselection.html new file mode 100755 index 000000000..d4c8a7a0d --- /dev/null +++ b/backend/webif/static/codemirror/demo/markselection.html @@ -0,0 +1,52 @@ + + +CodeMirror: Selection Marking Demo + + + + + + + + + + +
+

Selection Marking Demo

+
+ + + +

Simple addon to easily mark (and style) selected text. Docs.

+ +
diff --git a/backend/webif/static/codemirror/demo/matchhighlighter.html b/backend/webif/static/codemirror/demo/matchhighlighter.html new file mode 100755 index 000000000..893d72134 --- /dev/null +++ b/backend/webif/static/codemirror/demo/matchhighlighter.html @@ -0,0 +1,103 @@ + + +CodeMirror: Match Highlighter Demo + + + + + + + + + + + + +
+

Match Highlighter Demo

+
+ + + +

Search and highlight occurences of the selected text.

+ +
diff --git a/backend/webif/static/codemirror/demo/matchtags.html b/backend/webif/static/codemirror/demo/matchtags.html new file mode 100755 index 000000000..175639a39 --- /dev/null +++ b/backend/webif/static/codemirror/demo/matchtags.html @@ -0,0 +1,48 @@ + + +CodeMirror: Tag Matcher Demo + + + + + + + + + + + +
+

Tag Matcher Demo

+ + +
+ + + +

Put the cursor on or inside a pair of tags to highlight them. + Press Ctrl-J to jump to the tag that matches the one under the + cursor.

+
diff --git a/backend/webif/static/codemirror/demo/merge.html b/backend/webif/static/codemirror/demo/merge.html new file mode 100755 index 000000000..9e2d14ea3 --- /dev/null +++ b/backend/webif/static/codemirror/demo/merge.html @@ -0,0 +1,123 @@ + + +CodeMirror: merge view demo + + + + + + + + + + + + + + + +
+

merge view demo

+ + +
+ +

The merge +addon provides an interface for displaying and merging diffs, +either two-way +or three-way. +The left (or center) pane is editable, and the differences with the +other pane(s) are optionally shown live as you edit +it. In the two-way configuration, there are also options to pad changed +sections to align them, and to collapse unchanged +stretches of text.

+ +

This addon depends on +the google-diff-match-patch +library to compute the diffs.

+ + +
diff --git a/backend/webif/static/codemirror/demo/multiplex.html b/backend/webif/static/codemirror/demo/multiplex.html new file mode 100755 index 000000000..ca8c80aed --- /dev/null +++ b/backend/webif/static/codemirror/demo/multiplex.html @@ -0,0 +1,75 @@ + + +CodeMirror: Multiplexing Parser Demo + + + + + + + + + + +
+

Multiplexing Parser Demo

+
+ + + +

Demonstration of a multiplexing mode, which, at certain + boundary strings, switches to one or more inner modes. The out + (HTML) mode does not get fed the content of the << + >> blocks. See + the manual and + the source for more + information.

+ +

+ Parsing/Highlighting Tests: + normal, + verbose. +

+ +
diff --git a/backend/webif/static/codemirror/demo/mustache.html b/backend/webif/static/codemirror/demo/mustache.html new file mode 100755 index 000000000..ae4e6a891 --- /dev/null +++ b/backend/webif/static/codemirror/demo/mustache.html @@ -0,0 +1,69 @@ + + +CodeMirror: Overlay Parser Demo + + + + + + + + + + +
+

Overlay Parser Demo

+
+ + + +

Demonstration of a mode that parses HTML, highlighting + the Mustache templating + directives inside of it by using the code + in overlay.js. View + source to see the 15 lines of code needed to accomplish this.

+ +
diff --git a/backend/webif/static/codemirror/demo/panel.html b/backend/webif/static/codemirror/demo/panel.html new file mode 100755 index 000000000..1ce3d87c7 --- /dev/null +++ b/backend/webif/static/codemirror/demo/panel.html @@ -0,0 +1,136 @@ + + +CodeMirror: Panel Demo + + + + + + + + + + + + + +
+ +

Panel Demo

+ +
+ +
+ +

+ The panel + addon allows you to display panels above or below an editor. +
+ Click the links below to add panels at the given position: +

+ +
+

+ top + after-top + before-bottom + bottom +

+

+ You can also replace an existing panel: +

+
+ + +
+ + + +
+ +
diff --git a/backend/webif/static/codemirror/demo/placeholder.html b/backend/webif/static/codemirror/demo/placeholder.html new file mode 100755 index 000000000..432331a48 --- /dev/null +++ b/backend/webif/static/codemirror/demo/placeholder.html @@ -0,0 +1,45 @@ + + +CodeMirror: Placeholder demo + + + + + + + + + +
+

Placeholder demo

+
+ +

The placeholder + plug-in adds an option placeholder that can be set to + make text appear in the editor when it is empty and not focused. + If the source textarea has a placeholder attribute, + it will automatically be inherited.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/preview.html b/backend/webif/static/codemirror/demo/preview.html new file mode 100755 index 000000000..19e1530b8 --- /dev/null +++ b/backend/webif/static/codemirror/demo/preview.html @@ -0,0 +1,87 @@ + + +CodeMirror: HTML5 preview + + + + + + + + + + + + +
+

HTML5 preview

+ + + + +
diff --git a/backend/webif/static/codemirror/demo/requirejs.html b/backend/webif/static/codemirror/demo/requirejs.html new file mode 100755 index 000000000..438ef9fbf --- /dev/null +++ b/backend/webif/static/codemirror/demo/requirejs.html @@ -0,0 +1,70 @@ + + + + CodeMirror: HTML completion demo + + + + + + + + + + + + +
+

RequireJS module loading demo

+ +

This demo does the same thing as + the HTML5 completion demo, but + loads its dependencies + with Require.js, rather than + explicitly. Press ctrl-space to activate + completion.

+ +
+ + + + +
+ diff --git a/backend/webif/static/codemirror/demo/resize.html b/backend/webif/static/codemirror/demo/resize.html new file mode 100755 index 000000000..1c1ef390a --- /dev/null +++ b/backend/webif/static/codemirror/demo/resize.html @@ -0,0 +1,51 @@ + + +CodeMirror: Autoresize Demo + + + + + + + + + +
+

Autoresize Demo

+
+ +

By setting an editor's height style +to auto and giving +the viewportMargin +a value of Infinity, CodeMirror can be made to +automatically resize to fit its content.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/rulers.html b/backend/webif/static/codemirror/demo/rulers.html new file mode 100755 index 000000000..2ac411158 --- /dev/null +++ b/backend/webif/static/codemirror/demo/rulers.html @@ -0,0 +1,49 @@ + + +CodeMirror: Ruler Demo + + + + + + + + + +
+

Ruler Demo

+ + + +

Demonstration of +the rulers addon, which +displays vertical lines at given column offsets.

+ +
diff --git a/backend/webif/static/codemirror/demo/runmode.html b/backend/webif/static/codemirror/demo/runmode.html new file mode 100755 index 000000000..ab8938d8d --- /dev/null +++ b/backend/webif/static/codemirror/demo/runmode.html @@ -0,0 +1,62 @@ + + +CodeMirror: Mode Runner Demo + + + + + + + + + +
+

Mode Runner Demo

+ + +
+ +

+
+    
+
+    

Running a CodeMirror mode outside of the editor. + The CodeMirror.runMode function, defined + in addon/runmode/runmode.js takes the following arguments:

+ +
+
text (string)
+
The document to run through the highlighter.
+
mode (mode spec)
+
The mode to use (must be loaded as normal).
+
output (function or DOM node)
+
If this is a function, it will be called for each token with + two arguments, the token's text and the token's style class (may + be null for unstyled tokens). If it is a DOM node, + the tokens will be converted to span elements as in + an editor, and inserted into the node + (through innerHTML).
+
+ +
diff --git a/backend/webif/static/codemirror/demo/search.html b/backend/webif/static/codemirror/demo/search.html new file mode 100755 index 000000000..4ca81e20f --- /dev/null +++ b/backend/webif/static/codemirror/demo/search.html @@ -0,0 +1,99 @@ + + +CodeMirror: Search/Replace Demo + + + + + + + + + + + + + + + + + +
+

Search/Replace Demo

+
+ + + +

Demonstration of primitive search/replace functionality. The + keybindings (which can be configured with custom keymaps) are:

+
+
Ctrl-F / Cmd-F
Start searching
+
Ctrl-G / Cmd-G
Find next
+
Shift-Ctrl-G / Shift-Cmd-G
Find previous
+
Shift-Ctrl-F / Cmd-Option-F
Replace
+
Shift-Ctrl-R / Shift-Cmd-Option-F
Replace all
+
Alt-F
Persistent search (dialog doesn't autoclose, + enter to find next, Shift-Enter to find previous)
+
Alt-G
Jump to line
+
+

Searching is enabled by + including addon/search/search.js + and addon/search/searchcursor.js. + Jump to line - including addon/search/jump-to-line.js.

+

For good-looking input dialogs, you also want to include + addon/dialog/dialog.js + and addon/dialog/dialog.css.

+
diff --git a/backend/webif/static/codemirror/demo/simplemode.html b/backend/webif/static/codemirror/demo/simplemode.html new file mode 100755 index 000000000..04c194a4b --- /dev/null +++ b/backend/webif/static/codemirror/demo/simplemode.html @@ -0,0 +1,185 @@ + + +CodeMirror: Simple Mode Demo + + + + + + + + + + + +
+

Simple Mode Demo

+ +

The mode/simple +addon allows CodeMirror modes to be specified using a relatively simple +declarative format. This format is not as powerful as writing code +directly against the mode +interface, but is a lot easier to get started with, and +sufficiently expressive for many simple language modes.

+ +

This interface is still in flux. It is unlikely to be scrapped or +overhauled completely, so do start writing code against it, but +details might change as it stabilizes, and you might have to tweak +your code when upgrading.

+ +

Simple modes (loosely based on +the Common +JavaScript Syntax Highlighting Specification, which never took +off), are state machines, where each state has a number of rules that +match tokens. A rule describes a type of token that may occur in the +current state, and possibly a transition to another state caused by +that token.

+ +

The CodeMirror.defineSimpleMode(name, states) method +takes a mode name and an object that describes the mode's states. The +editor below shows an example of such a mode (and is itself +highlighted by the mode shown in it).

+ +
+ +

Each state is an array of rules. A rule may have the following properties:

+ +
+
regex: string | RegExp
+
The regular expression that matches the token. May be a string + or a regex object. When a regex, the ignoreCase flag + will be taken into account when matching the token. This regex + has to capture groups when the token property is + an array. If it captures groups, it must capture all of the string + (since JS provides no way to find out where a group matched).
+
token: string | array<string> | null
+
An optional token style. Multiple styles can be specified by + separating them with dots or spaces. When this property holds an array of token styles, + the regex for this rule must capture a group for each array item. +
+
sol: boolean
+
When true, this token will only match at the start of the line. + (The ^ regexp marker doesn't work as you'd expect in + this context because of limitations in JavaScript's RegExp + API.)
+
next: string
+
When a next property is present, the mode will + transfer to the state named by the property when the token is + encountered.
+
push: string
+
Like next, but instead replacing the current state + by the new state, the current state is kept on a stack, and can be + returned to with the pop directive.
+
pop: bool
+
When true, and there is another state on the state stack, will + cause the mode to pop that state off the stack and transition to + it.
+
mode: {spec, end, persistent}
+
Can be used to embed another mode inside a mode. When present, + must hold an object with a spec property that describes + the embedded mode, and an optional end end property + that specifies the regexp that will end the extent of the mode. When + a persistent property is set (and true), the nested + mode's state will be preserved between occurrences of the mode.
+
indent: bool
+
When true, this token changes the indentation to be one unit + more than the current line's indentation.
+
dedent: bool
+
When true, this token will pop one scope off the indentation + stack.
+
dedentIfLineStart: bool
+
If a token has its dedent property set, it will, by + default, cause lines where it appears at the start to be dedented. + Set this property to false to prevent that behavior.
+
+ +

The meta property of the states object is special, and +will not be interpreted as a state. Instead, properties set on it will +be set on the mode, which is useful for properties +like lineComment, +which sets the comment style for a mode. The simple mode addon also +recognizes a few such properties:

+ +
+
dontIndentStates: array<string>
+
An array of states in which the mode's auto-indentation should + not take effect. Usually used for multi-line comment and string + states.
+
+ + + + + +
diff --git a/backend/webif/static/codemirror/demo/simplescrollbars.html b/backend/webif/static/codemirror/demo/simplescrollbars.html new file mode 100755 index 000000000..9d4093264 --- /dev/null +++ b/backend/webif/static/codemirror/demo/simplescrollbars.html @@ -0,0 +1,82 @@ + + +CodeMirror: Simple Scrollbar Demo + + + + + + + + + + + + +
+

Simple Scrollbar Demo

+
+ +

The simplescrollbars addon defines two +styles of non-native scrollbars: "simple" and "overlay" (click to try), which can be passed to +the scrollbarStyle option. These implement +the scrollbar using DOM elements, allowing more control over +its appearance.

+ + +
diff --git a/backend/webif/static/codemirror/demo/spanaffectswrapping_shim.html b/backend/webif/static/codemirror/demo/spanaffectswrapping_shim.html new file mode 100755 index 000000000..879d99b60 --- /dev/null +++ b/backend/webif/static/codemirror/demo/spanaffectswrapping_shim.html @@ -0,0 +1,85 @@ + + +CodeMirror: Automatically derive odd wrapping behavior for your browser + + + + + +
+

Automatically derive odd wrapping behavior for your browser

+ + +

This is a hack to automatically derive + a spanAffectsWrapping regexp for a browser. See the + comments above that variable + in lib/codemirror.js + for some more details.

+ +
+

+
+    
+  
diff --git a/backend/webif/static/codemirror/demo/sublime.html b/backend/webif/static/codemirror/demo/sublime.html new file mode 100755 index 000000000..233dd83a4 --- /dev/null +++ b/backend/webif/static/codemirror/demo/sublime.html @@ -0,0 +1,77 @@ + + +CodeMirror: Sublime Text bindings demo + + + + + + + + + + + + + + + + + + + + + + +
+

Sublime Text bindings demo

+ +

The sublime keymap defines many Sublime Text-specific +bindings for CodeMirror. See the code below for an overview.

+ +

Enable the keymap by +loading keymap/sublime.js +and setting +the keyMap +option to "sublime".

+ +

(A lot of the search functionality is still missing.) + + + +

diff --git a/backend/webif/static/codemirror/demo/tern.html b/backend/webif/static/codemirror/demo/tern.html new file mode 100755 index 000000000..d0dee8a70 --- /dev/null +++ b/backend/webif/static/codemirror/demo/tern.html @@ -0,0 +1,133 @@ + + +CodeMirror: Tern Demo + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Tern Demo

+
+ +

Demonstrates integration of Tern +and CodeMirror. The following keys are bound:

+ +
+
Ctrl-Space
Autocomplete
+
Ctrl-O
Find docs for the expression at the cursor
+
Ctrl-I
Find type at cursor
+
Alt-.
Jump to definition (Alt-, to jump back)
+
Ctrl-Q
Rename variable
+
Ctrl-.
Select all occurrences of a variable
+
+ +

Documentation is sparse for now. See the top of +the script for a rough API +overview.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/theme.html b/backend/webif/static/codemirror/demo/theme.html new file mode 100755 index 000000000..9194dcea8 --- /dev/null +++ b/backend/webif/static/codemirror/demo/theme.html @@ -0,0 +1,168 @@ + + +CodeMirror: Theme Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Theme Demo

+
+ +

Select a theme: +

+ + +
diff --git a/backend/webif/static/codemirror/demo/trailingspace.html b/backend/webif/static/codemirror/demo/trailingspace.html new file mode 100755 index 000000000..1992ba3ff --- /dev/null +++ b/backend/webif/static/codemirror/demo/trailingspace.html @@ -0,0 +1,48 @@ + + +CodeMirror: Trailing Whitespace Demo + + + + + + + + + +
+

Trailing Whitespace Demo

+
+ + + +

Uses +the trailingspace +addon to highlight trailing whitespace.

+ +
diff --git a/backend/webif/static/codemirror/demo/variableheight.html b/backend/webif/static/codemirror/demo/variableheight.html new file mode 100755 index 000000000..d49942864 --- /dev/null +++ b/backend/webif/static/codemirror/demo/variableheight.html @@ -0,0 +1,67 @@ + + +CodeMirror: Variable Height Demo + + + + + + + + + + +
+

Variable Height Demo

+
+ +
diff --git a/backend/webif/static/codemirror/demo/vim.html b/backend/webif/static/codemirror/demo/vim.html new file mode 100755 index 000000000..bd704f758 --- /dev/null +++ b/backend/webif/static/codemirror/demo/vim.html @@ -0,0 +1,113 @@ + + +CodeMirror: Vim bindings demo + + + + + + + + + + + + + + + + +
+

Vim bindings demo

+ +

Note: The CodeMirror vim bindings do not have an +active maintainer. That means that if you report bugs in it, they are +likely to go unanswered. It also means that if you want to help, you +are very welcome to look +at the +open issues and see which ones you can solve.

+ +
+
Key buffer:
+ +

The vim keybindings are enabled by including keymap/vim.js and setting the +keyMap option to vim.

+ +

Features

+ +
    +
  • All common motions and operators, including text objects
  • +
  • Operator motion orthogonality
  • +
  • Visual mode - characterwise, linewise, blockwise
  • +
  • Full macro support (q, @)
  • +
  • Incremental highlighted search (/, ?, #, *, g#, g*)
  • +
  • Search/replace with confirm (:substitute, :%s)
  • +
  • Search history
  • +
  • Jump lists (Ctrl-o, Ctrl-i)
  • +
  • Key/command mapping with API (:map, :nmap, :vmap)
  • +
  • Sort (:sort)
  • +
  • Marks (`, ')
  • +
  • :global
  • +
  • Insert mode behaves identical to base CodeMirror
  • +
  • Cross-buffer yank/paste
  • +
+ +

For the full list of key mappings and Ex commands, refer to the +defaultKeymap and defaultExCommandMap at the +top of keymap/vim.js. + +

Note that while the vim mode tries to emulate the most useful +features of vim as faithfully as possible, it does not strive to +become a complete vim implementation

+ + + +
diff --git a/backend/webif/static/codemirror/demo/visibletabs.html b/backend/webif/static/codemirror/demo/visibletabs.html new file mode 100755 index 000000000..2eec337ed --- /dev/null +++ b/backend/webif/static/codemirror/demo/visibletabs.html @@ -0,0 +1,62 @@ + + +CodeMirror: Visible tabs demo + + + + + + + + + +
+

Visible tabs demo

+
+ +

Tabs inside the editor are spans with the +class cm-tab, and can be styled.

+ + + +
diff --git a/backend/webif/static/codemirror/demo/widget.html b/backend/webif/static/codemirror/demo/widget.html new file mode 100755 index 000000000..da39a9297 --- /dev/null +++ b/backend/webif/static/codemirror/demo/widget.html @@ -0,0 +1,85 @@ + + +CodeMirror: Inline Widget Demo + + + + + + + + + + +
+

Inline Widget Demo

+ + +
+ +

This demo runs JSHint over the code +in the editor (which is the script used on this page), and +inserts line widgets to +display the warnings that JSHint comes up with.

+
diff --git a/backend/webif/static/codemirror/demo/xmlcomplete.html b/backend/webif/static/codemirror/demo/xmlcomplete.html new file mode 100755 index 000000000..043f0c429 --- /dev/null +++ b/backend/webif/static/codemirror/demo/xmlcomplete.html @@ -0,0 +1,119 @@ + + +CodeMirror: XML Autocomplete Demo + + + + + + + + + + + + +
+

XML Autocomplete Demo

+
+ +

Press ctrl-space, or type a '<' character to + activate autocompletion. This demo defines a simple schema that + guides completion. The schema can be customized—see + the manual.

+ +

Development of the xml-hint addon was kindly + sponsored + by www.xperiment.mobi.

+ + +
diff --git a/backend/webif/static/codemirror/doc/activebookmark.js b/backend/webif/static/codemirror/doc/activebookmark.js new file mode 100755 index 000000000..407282d02 --- /dev/null +++ b/backend/webif/static/codemirror/doc/activebookmark.js @@ -0,0 +1,57 @@ +// Kludge in HTML5 tag recognition in IE8 +document.createElement("section"); +document.createElement("article"); + +(function() { + if (!window.addEventListener) return; + var pending = false, prevVal = null; + + function updateSoon() { + if (!pending) { + pending = true; + setTimeout(update, 250); + } + } + + function update() { + pending = false; + var marks = document.getElementById("nav").getElementsByTagName("a"), found; + for (var i = 0; i < marks.length; ++i) { + var mark = marks[i], m; + if (mark.getAttribute("data-default")) { + if (found == null) found = i; + } else if (m = mark.href.match(/#(.*)/)) { + var ref = document.getElementById(m[1]); + if (ref && ref.getBoundingClientRect().top < 50) + found = i; + } + } + if (found != null && found != prevVal) { + prevVal = found; + var lis = document.getElementById("nav").getElementsByTagName("li"); + for (var i = 0; i < lis.length; ++i) lis[i].className = ""; + for (var i = 0; i < marks.length; ++i) { + if (found == i) { + marks[i].className = "active"; + for (var n = marks[i]; n; n = n.parentNode) + if (n.nodeName == "LI") n.className = "active"; + } else { + marks[i].className = ""; + } + } + } + } + + window.addEventListener("scroll", updateSoon); + window.addEventListener("load", updateSoon); + window.addEventListener("hashchange", function() { + setTimeout(function() { + var hash = document.location.hash, found = null, m; + var marks = document.getElementById("nav").getElementsByTagName("a"); + for (var i = 0; i < marks.length; i++) + if ((m = marks[i].href.match(/(#.*)/)) && m[1] == hash) { found = i; break; } + if (found != null) for (var i = 0; i < marks.length; i++) + marks[i].className = i == found ? "active" : ""; + }, 300); + }); +})(); diff --git a/backend/webif/static/codemirror/doc/docs.css b/backend/webif/static/codemirror/doc/docs.css new file mode 100755 index 000000000..881d2aa45 --- /dev/null +++ b/backend/webif/static/codemirror/doc/docs.css @@ -0,0 +1,271 @@ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(//themes.googleusercontent.com/static/fonts/sourcesanspro/v5/ODelI1aHBYDBqgeIAH2zlBM0YzuT7MdOe03otPbuUS0.woff) format('woff'); +} + +body, html { margin: 0; padding: 0; height: 100%; } +section, article { display: block; padding: 0; } + +body { + background: #f8f8f8; + font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; + line-height: 1.5; +} + +p { margin-top: 0; } + +h2, h3, h1 { + font-weight: normal; + margin-bottom: .7em; +} +h1 { font-size: 140%; } +h2 { font-size: 120%; } +h3 { font-size: 110%; } +article > h2:first-child, section:first-child > h2 { margin-top: 0; } + +#nav h1 { + margin-right: 12px; + margin-top: 0; + margin-bottom: 2px; + color: #d30707; + letter-spacing: .5px; +} + +a, a:visited, a:link, .quasilink { + color: #A21313; + text-decoration: none; +} + +em { + padding-right: 2px; +} + +.quasilink { + cursor: pointer; +} + +article { + max-width: 700px; + margin: 0 0 0 160px; + border-left: 2px solid #E30808; + border-right: 1px solid #ddd; + padding: 30px 50px 100px 50px; + background: white; + z-index: 2; + position: relative; + min-height: 100%; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +#nav { + position: fixed; + padding-top: 30px; + max-height: 100%; + box-sizing: -moz-border-box; + box-sizing: border-box; + overflow-y: auto; + left: 0; right: none; + width: 160px; + text-align: right; + z-index: 1; +} + +@media screen and (min-width: 1000px) { + article { + margin: 0 auto; + } + #nav { + right: 50%; + width: auto; + border-right: 349px solid transparent; + } +} + +#nav ul { + display: block; + margin: 0; padding: 0; + margin-bottom: 32px; +} + +#nav li { + display: block; + margin-bottom: 4px; +} + +#nav li ul { + font-size: 80%; + margin-bottom: 0; + display: none; +} + +#nav li.active ul { + display: block; +} + +#nav li li a { + padding-right: 20px; + display: inline-block; +} + +#nav ul a { + color: black; + padding: 0 7px 1px 11px; +} + +#nav ul a.active, #nav ul a:hover { + border-bottom: 1px solid #E30808; + margin-bottom: -1px; + color: #E30808; +} + +#logo { + border: 0; + margin-right: 12px; + margin-bottom: 25px; +} + +section { + border-top: 1px solid #E30808; + margin: 1.5em 0; +} + +section.first { + border: none; + margin-top: 0; +} + +#demo { + position: relative; +} + +#demolist { + position: absolute; + right: 5px; + top: 5px; + z-index: 25; +} + +.yinyang { + position: absolute; + top: -10px; + left: 0; right: 0; + margin: auto; + display: block; + height: 120px; +} + +.actions { + margin: 1em 0 0; + min-height: 100px; + position: relative; +} + +.actionspicture { + pointer-events: none; + position: absolute; + height: 100px; + top: 0; left: 0; right: 0; +} + +.actionlink { + pointer-events: auto; + font-family: arial; + font-size: 80%; + font-weight: bold; + position: absolute; + top: 0; bottom: 0; + line-height: 1; + height: 1em; + margin: auto; +} + +.actionlink.download { + color: white; + right: 50%; + margin-right: 13px; + text-shadow: -1px 1px 3px #b00, -1px -1px 3px #b00, 1px 0px 3px #b00; +} + +.actionlink.fund { + color: #b00; + left: 50%; + margin-left: 15px; +} + +.actionlink:hover { + text-decoration: underline; +} + +.actionlink a { + color: inherit; +} + +.actionsleft { + float: left; +} + +.actionsright { + float: right; + text-align: right; +} + +@media screen and (max-width: 800px) { + .actions { + padding-top: 120px; + } + .actionsleft, .actionsright { + float: none; + text-align: left; + margin-bottom: 1em; + } +} + +th { + text-decoration: underline; + font-weight: normal; + text-align: left; +} + +#features ul { + list-style: none; + margin: 0 0 1em; + padding: 0 0 0 1.2em; +} + +#features li:before { + content: "-"; + width: 1em; + display: inline-block; + padding: 0; + margin: 0; + margin-left: -1em; +} + +.rel { + margin-bottom: 0; +} +.rel-note { + margin-top: 0; + color: #555; +} + +pre { + padding-left: 15px; + border-left: 2px solid #ddd; +} + +code { + padding: 0 2px; +} + +strong { + text-decoration: underline; + font-weight: normal; +} + +.field { + border: 1px solid #A21313; +} diff --git a/backend/webif/static/codemirror/doc/internals.html b/backend/webif/static/codemirror/doc/internals.html new file mode 100755 index 000000000..079466f63 --- /dev/null +++ b/backend/webif/static/codemirror/doc/internals.html @@ -0,0 +1,504 @@ + + +CodeMirror: Internals + + + + + + + +
+ +

(Re-) Implementing A Syntax-Highlighting Editor in JavaScript

+ +

+ Topic: JavaScript, code editor implementation
+ Author: Marijn Haverbeke
+ Date: March 2nd 2011 (updated November 13th 2011) +

+ +

Caution: this text was written briefly after +version 2 was initially written. It no longer (even including the +update at the bottom) fully represents the current implementation. I'm +leaving it here as a historic document. For more up-to-date +information, look at the entries +tagged cm-internals +on my blog.

+ +

This is a followup to +my Brutal Odyssey to the +Dark Side of the DOM Tree story. That one describes the +mind-bending process of implementing (what would become) CodeMirror 1. +This one describes the internals of CodeMirror 2, a complete rewrite +and rethink of the old code base. I wanted to give this piece another +Hunter Thompson copycat subtitle, but somehow that would be out of +place—the process this time around was one of straightforward +engineering, requiring no serious mind-bending whatsoever.

+ +

So, what is wrong with CodeMirror 1? I'd estimate, by mailing list +activity and general search-engine presence, that it has been +integrated into about a thousand systems by now. The most prominent +one, since a few weeks, +being Google +code's project hosting. It works, and it's being used widely.

+ +

Still, I did not start replacing it because I was bored. CodeMirror +1 was heavily reliant on designMode +or contentEditable (depending on the browser). Neither of +these are well specified (HTML5 tries +to specify +their basics), and, more importantly, they tend to be one of the more +obscure and buggy areas of browser functionality—CodeMirror, by using +this functionality in a non-typical way, was constantly running up +against browser bugs. WebKit wouldn't show an empty line at the end of +the document, and in some releases would suddenly get unbearably slow. +Firefox would show the cursor in the wrong place. Internet Explorer +would insist on linkifying everything that looked like a URL or email +address, a behaviour that can't be turned off. Some bugs I managed to +work around (which was often a frustrating, painful process), others, +such as the Firefox cursor placement, I gave up on, and had to tell +user after user that they were known problems, but not something I +could help.

+ +

Also, there is the fact that designMode (which seemed +to be less buggy than contentEditable in Webkit and +Firefox, and was thus used by CodeMirror 1 in those browsers) requires +a frame. Frames are another tricky area. It takes some effort to +prevent getting tripped up by domain restrictions, they don't +initialize synchronously, behave strangely in response to the back +button, and, on several browsers, can't be moved around the DOM +without having them re-initialize. They did provide a very nice way to +namespace the library, though—CodeMirror 1 could freely pollute the +namespace inside the frame.

+ +

Finally, working with an editable document means working with +selection in arbitrary DOM structures. Internet Explorer (8 and +before) has an utterly different (and awkward) selection API than all +of the other browsers, and even among the different implementations of +document.selection, details about how exactly a selection +is represented vary quite a bit. Add to that the fact that Opera's +selection support tended to be very buggy until recently, and you can +imagine why CodeMirror 1 contains 700 lines of selection-handling +code.

+ +

And that brings us to the main issue with the CodeMirror 1 +code base: The proportion of browser-bug-workarounds to real +application code was getting dangerously high. By building on top of a +few dodgy features, I put the system in a vulnerable position—any +incompatibility and bugginess in these features, I had to paper over +with my own code. Not only did I have to do some serious stunt-work to +get it to work on older browsers (as detailed in the +previous story), things +also kept breaking in newly released versions, requiring me to come up +with new scary hacks in order to keep up. This was starting +to lose its appeal.

+ +
+

General Approach

+ +

What CodeMirror 2 does is try to sidestep most of the hairy hacks +that came up in version 1. I owe a lot to the +ACE editor for inspiration on how to +approach this.

+ +

I absolutely did not want to be completely reliant on key events to +generate my input. Every JavaScript programmer knows that key event +information is horrible and incomplete. Some people (most awesomely +Mihai Bazon with Ymacs) have been able +to build more or less functioning editors by directly reading key +events, but it takes a lot of work (the kind of never-ending, fragile +work I described earlier), and will never be able to properly support +things like multi-keystoke international character +input. [see below for caveat]

+ +

So what I do is focus a hidden textarea, and let the browser +believe that the user is typing into that. What we show to the user is +a DOM structure we built to represent his document. If this is updated +quickly enough, and shows some kind of believable cursor, it feels +like a real text-input control.

+ +

Another big win is that this DOM representation does not have to +span the whole document. Some CodeMirror 1 users insisted that they +needed to put a 30 thousand line XML document into CodeMirror. Putting +all that into the DOM takes a while, especially since, for some +reason, an editable DOM tree is slower than a normal one on most +browsers. If we have full control over what we show, we must only +ensure that the visible part of the document has been added, and can +do the rest only when needed. (Fortunately, the onscroll +event works almost the same on all browsers, and lends itself well to +displaying things only as they are scrolled into view.)

+
+
+

Input

+ +

ACE uses its hidden textarea only as a text input shim, and does +all cursor movement and things like text deletion itself by directly +handling key events. CodeMirror's way is to let the browser do its +thing as much as possible, and not, for example, define its own set of +key bindings. One way to do this would have been to have the whole +document inside the hidden textarea, and after each key event update +the display DOM to reflect what's in that textarea.

+ +

That'd be simple, but it is not realistic. For even medium-sized +document the editor would be constantly munging huge strings, and get +terribly slow. What CodeMirror 2 does is put the current selection, +along with an extra line on the top and on the bottom, into the +textarea.

+ +

This means that the arrow keys (and their ctrl-variations), home, +end, etcetera, do not have to be handled specially. We just read the +cursor position in the textarea, and update our cursor to match it. +Also, copy and paste work pretty much for free, and people get their +native key bindings, without any special work on my part. For example, +I have emacs key bindings configured for Chrome and Firefox. There is +no way for a script to detect this. [no longer the case]

+ +

Of course, since only a small part of the document sits in the +textarea, keys like page up and ctrl-end won't do the right thing. +CodeMirror is catching those events and handling them itself.

+
+
+

Selection

+ +

Getting and setting the selection range of a textarea in modern +browsers is trivial—you just use the selectionStart +and selectionEnd properties. On IE you have to do some +insane stuff with temporary ranges and compensating for the fact that +moving the selection by a 'character' will treat \r\n as a single +character, but even there it is possible to build functions that +reliably set and get the selection range.

+ +

But consider this typical case: When I'm somewhere in my document, +press shift, and press the up arrow, something gets selected. Then, if +I, still holding shift, press the up arrow again, the top of my +selection is adjusted. The selection remembers where its head +and its anchor are, and moves the head when we shift-move. +This is a generally accepted property of selections, and done right by +every editing component built in the past twenty years.

+ +

But not something that the browser selection APIs expose.

+ +

Great. So when someone creates an 'upside-down' selection, the next +time CodeMirror has to update the textarea, it'll re-create the +selection as an 'upside-up' selection, with the anchor at the top, and +the next cursor motion will behave in an unexpected way—our second +up-arrow press in the example above will not do anything, since it is +interpreted in exactly the same way as the first.

+ +

No problem. We'll just, ehm, detect that the selection is +upside-down (you can tell by the way it was created), and then, when +an upside-down selection is present, and a cursor-moving key is +pressed in combination with shift, we quickly collapse the selection +in the textarea to its start, allow the key to take effect, and then +combine its new head with its old anchor to get the real +selection.

+ +

In short, scary hacks could not be avoided entirely in CodeMirror +2.

+ +

And, the observant reader might ask, how do you even know that a +key combo is a cursor-moving combo, if you claim you support any +native key bindings? Well, we don't, but we can learn. The editor +keeps a set known cursor-movement combos (initialized to the +predictable defaults), and updates this set when it observes that +pressing a certain key had (only) the effect of moving the cursor. +This, of course, doesn't work if the first time the key is used was +for extending an inverted selection, but it works most of the +time.

+
+
+

Intelligent Updating

+ +

One thing that always comes up when you have a complicated internal +state that's reflected in some user-visible external representation +(in this case, the displayed code and the textarea's content) is +keeping the two in sync. The naive way is to just update the display +every time you change your state, but this is not only error prone +(you'll forget), it also easily leads to duplicate work on big, +composite operations. Then you start passing around flags indicating +whether the display should be updated in an attempt to be efficient +again and, well, at that point you might as well give up completely.

+ +

I did go down that road, but then switched to a much simpler model: +simply keep track of all the things that have been changed during an +action, and then, only at the end, use this information to update the +user-visible display.

+ +

CodeMirror uses a concept of operations, which start by +calling a specific set-up function that clears the state and end by +calling another function that reads this state and does the required +updating. Most event handlers, and all the user-visible methods that +change state are wrapped like this. There's a method +called operation that accepts a function, and returns +another function that wraps the given function as an operation.

+ +

It's trivial to extend this (as CodeMirror does) to detect nesting, +and, when an operation is started inside an operation, simply +increment the nesting count, and only do the updating when this count +reaches zero again.

+ +

If we have a set of changed ranges and know the currently shown +range, we can (with some awkward code to deal with the fact that +changes can add and remove lines, so we're dealing with a changing +coordinate system) construct a map of the ranges that were left +intact. We can then compare this map with the part of the document +that's currently visible (based on scroll offset and editor height) to +determine whether something needs to be updated.

+ +

CodeMirror uses two update algorithms—a full refresh, where it just +discards the whole part of the DOM that contains the edited text and +rebuilds it, and a patch algorithm, where it uses the information +about changed and intact ranges to update only the out-of-date parts +of the DOM. When more than 30 percent (which is the current heuristic, +might change) of the lines need to be updated, the full refresh is +chosen (since it's faster to do than painstakingly finding and +updating all the changed lines), in the other case it does the +patching (so that, if you scroll a line or select another character, +the whole screen doesn't have to be +re-rendered). [the full-refresh +algorithm was dropped, it wasn't really faster than the patching +one]

+ +

All updating uses innerHTML rather than direct DOM +manipulation, since that still seems to be by far the fastest way to +build documents. There's a per-line function that combines the +highlighting, marking, and +selection info for that line into a snippet of HTML. The patch updater +uses this to reset individual lines, the refresh updater builds an +HTML chunk for the whole visible document at once, and then uses a +single innerHTML update to do the refresh.

+
+
+

Parsers can be Simple

+ +

When I wrote CodeMirror 1, I +thought interruptable +parsers were a hugely scary and complicated thing, and I used a +bunch of heavyweight abstractions to keep this supposed complexity +under control: parsers +were iterators +that consumed input from another iterator, and used funny +closure-resetting tricks to copy and resume themselves.

+ +

This made for a rather nice system, in that parsers formed strictly +separate modules, and could be composed in predictable ways. +Unfortunately, it was quite slow (stacking three or four iterators on +top of each other), and extremely intimidating to people not used to a +functional programming style.

+ +

With a few small changes, however, we can keep all those +advantages, but simplify the API and make the whole thing less +indirect and inefficient. CodeMirror +2's mode API uses explicit state +objects, and makes the parser/tokenizer a function that simply takes a +state and a character stream abstraction, advances the stream one +token, and returns the way the token should be styled. This state may +be copied, optionally in a mode-defined way, in order to be able to +continue a parse at a given point. Even someone who's never touched a +lambda in his life can understand this approach. Additionally, far +fewer objects are allocated in the course of parsing now.

+ +

The biggest speedup comes from the fact that the parsing no longer +has to touch the DOM though. In CodeMirror 1, on an older browser, you +could see the parser work its way through the document, +managing some twenty lines in each 50-millisecond time slice it got. It +was reading its input from the DOM, and updating the DOM as it went +along, which any experienced JavaScript programmer will immediately +spot as a recipe for slowness. In CodeMirror 2, the parser usually +finishes the whole document in a single 100-millisecond time slice—it +manages some 1500 lines during that time on Chrome. All it has to do +is munge strings, so there is no real reason for it to be slow +anymore.

+
+
+

What Gives?

+ +

Given all this, what can you expect from CodeMirror 2?

+ +
    + +
  • Small. the base library is +some 45k when minified +now, 17k when gzipped. It's smaller than +its own logo.
  • + +
  • Lightweight. CodeMirror 2 initializes very +quickly, and does almost no work when it is not focused. This means +you can treat it almost like a textarea, have multiple instances on a +page without trouble.
  • + +
  • Huge document support. Since highlighting is +really fast, and no DOM structure is being built for non-visible +content, you don't have to worry about locking up your browser when a +user enters a megabyte-sized document.
  • + +
  • Extended API. Some things kept coming up in the +mailing list, such as marking pieces of text or lines, which were +extremely hard to do with CodeMirror 1. The new version has proper +support for these built in.
  • + +
  • Tab support. Tabs inside editable documents were, +for some reason, a no-go. At least six different people announced they +were going to add tab support to CodeMirror 1, none survived (I mean, +none delivered a working version). CodeMirror 2 no longer removes tabs +from your document.
  • + +
  • Sane styling. iframe nodes aren't +really known for respecting document flow. Now that an editor instance +is a plain div element, it is much easier to size it to +fit the surrounding elements. You don't even have to make it scroll if +you do not want to.
  • + +
+ +

On the downside, a CodeMirror 2 instance is not a native +editable component. Though it does its best to emulate such a +component as much as possible, there is functionality that browsers +just do not allow us to hook into. Doing select-all from the context +menu, for example, is not currently detected by CodeMirror.

+ +

[Updates from November 13th 2011] Recently, I've made +some changes to the codebase that cause some of the text above to no +longer be current. I've left the text intact, but added markers at the +passages that are now inaccurate. The new situation is described +below.

+
+
+

Content Representation

+ +

The original implementation of CodeMirror 2 represented the +document as a flat array of line objects. This worked well—splicing +arrays will require the part of the array after the splice to be +moved, but this is basically just a simple memmove of a +bunch of pointers, so it is cheap even for huge documents.

+ +

However, I recently added line wrapping and code folding (line +collapsing, basically). Once lines start taking up a non-constant +amount of vertical space, looking up a line by vertical position +(which is needed when someone clicks the document, and to determine +the visible part of the document during scrolling) can only be done +with a linear scan through the whole array, summing up line heights as +you go. Seeing how I've been going out of my way to make big documents +fast, this is not acceptable.

+ +

The new representation is based on a B-tree. The leaves of the tree +contain arrays of line objects, with a fixed minimum and maximum size, +and the non-leaf nodes simply hold arrays of child nodes. Each node +stores both the amount of lines that live below them and the vertical +space taken up by these lines. This allows the tree to be indexed both +by line number and by vertical position, and all access has +logarithmic complexity in relation to the document size.

+ +

I gave line objects and tree nodes parent pointers, to the node +above them. When a line has to update its height, it can simply walk +these pointers to the top of the tree, adding or subtracting the +difference in height from each node it encounters. The parent pointers +also make it cheaper (in complexity terms, the difference is probably +tiny in normal-sized documents) to find the current line number when +given a line object. In the old approach, the whole document array had +to be searched. Now, we can just walk up the tree and count the sizes +of the nodes coming before us at each level.

+ +

I chose B-trees, not regular binary trees, mostly because they +allow for very fast bulk insertions and deletions. When there is a big +change to a document, it typically involves adding, deleting, or +replacing a chunk of subsequent lines. In a regular balanced tree, all +these inserts or deletes would have to be done separately, which could +be really expensive. In a B-tree, to insert a chunk, you just walk +down the tree once to find where it should go, insert them all in one +shot, and then break up the node if needed. This breaking up might +involve breaking up nodes further up, but only requires a single pass +back up the tree. For deletion, I'm somewhat lax in keeping things +balanced—I just collapse nodes into a leaf when their child count goes +below a given number. This means that there are some weird editing +patterns that may result in a seriously unbalanced tree, but even such +an unbalanced tree will perform well, unless you spend a day making +strangely repeating edits to a really big document.

+
+
+

Keymaps

+ +

Above, I claimed that directly catching key +events for things like cursor movement is impractical because it +requires some browser-specific kludges. I then proceeded to explain +some awful hacks that were needed to make it +possible for the selection changes to be detected through the +textarea. In fact, the second hack is about as bad as the first.

+ +

On top of that, in the presence of user-configurable tab sizes and +collapsed and wrapped lines, lining up cursor movement in the textarea +with what's visible on the screen becomes a nightmare. Thus, I've +decided to move to a model where the textarea's selection is no longer +depended on.

+ +

So I moved to a model where all cursor movement is handled by my +own code. This adds support for a goal column, proper interaction of +cursor movement with collapsed lines, and makes it possible for +vertical movement to move through wrapped lines properly, instead of +just treating them like non-wrapped lines.

+ +

The key event handlers now translate the key event into a string, +something like Ctrl-Home or Shift-Cmd-R, and +use that string to look up an action to perform. To make keybinding +customizable, this lookup goes through +a table, using a scheme that +allows such tables to be chained together (for example, the default +Mac bindings fall through to a table named 'emacsy', which defines +basic Emacs-style bindings like Ctrl-F, and which is also +used by the custom Emacs bindings).

+ +

A new +option extraKeys +allows ad-hoc keybindings to be defined in a much nicer way than what +was possible with the +old onKeyEvent +callback. You simply provide an object mapping key identifiers to +functions, instead of painstakingly looking at raw key events.

+ +

Built-in commands map to strings, rather than functions, for +example "goLineUp" is the default action bound to the up +arrow key. This allows new keymaps to refer to them without +duplicating any code. New commands can be defined by assigning to +the CodeMirror.commands object, which maps such commands +to functions.

+ +

The hidden textarea now only holds the current selection, with no +extra characters around it. This has a nice advantage: polling for +input becomes much, much faster. If there's a big selection, this text +does not have to be read from the textarea every time—when we poll, +just noticing that something is still selected is enough to tell us +that no new text was typed.

+ +

The reason that cheap polling is important is that many browsers do +not fire useful events on IME (input method engine) input, which is +the thing where people inputting a language like Japanese or Chinese +use multiple keystrokes to create a character or sequence of +characters. Most modern browsers fire input when the +composing is finished, but many don't fire anything when the character +is updated during composition. So we poll, whenever the +editor is focused, to provide immediate updates of the display.

+ +
+
diff --git a/backend/webif/static/codemirror/doc/logo.png b/backend/webif/static/codemirror/doc/logo.png new file mode 100755 index 000000000..9aabda1d7 Binary files /dev/null and b/backend/webif/static/codemirror/doc/logo.png differ diff --git a/backend/webif/static/codemirror/doc/logo.svg b/backend/webif/static/codemirror/doc/logo.svg new file mode 100755 index 000000000..b39b24c81 --- /dev/null +++ b/backend/webif/static/codemirror/doc/logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/codemirror/doc/manual.html b/backend/webif/static/codemirror/doc/manual.html new file mode 100755 index 000000000..f46e6bd5a --- /dev/null +++ b/backend/webif/static/codemirror/doc/manual.html @@ -0,0 +1,3527 @@ + + +CodeMirror: User Manual + + + + + + + + + + + + + + + + +
+ +
+

+ User manual and reference guide + version 5.32.0 +

+ +

CodeMirror is a code-editor component that can be embedded in + Web pages. The core library provides only the editor + component, no accompanying buttons, auto-completion, or other IDE + functionality. It does provide a rich API on top of which such + functionality can be straightforwardly implemented. See + the addons included in the distribution, + and the list + of externally hosted addons, for reusable + implementations of extra features.

+ +

CodeMirror works with language-specific modes. Modes are + JavaScript programs that help color (and optionally indent) text + written in a given language. The distribution comes with a number + of modes (see the mode/ + directory), and it isn't hard to write new + ones for other languages.

+
+ +
+

Basic Usage

+ +

The easiest way to use CodeMirror is to simply load the script + and style sheet found under lib/ in the distribution, + plus a mode script from one of the mode/ directories. + For example:

+ +
<script src="lib/codemirror.js"></script>
+<link rel="stylesheet" href="lib/codemirror.css">
+<script src="mode/javascript/javascript.js"></script>
+ +

(Alternatively, use a module loader. More + about that later.)

+ +

Having done this, an editor instance can be created like + this:

+ +
var myCodeMirror = CodeMirror(document.body);
+ +

The editor will be appended to the document body, will start + empty, and will use the mode that we loaded. To have more control + over the new editor, a configuration object can be passed + to CodeMirror as a second + argument:

+ +
var myCodeMirror = CodeMirror(document.body, {
+  value: "function myScript(){return 100;}\n",
+  mode:  "javascript"
+});
+ +

This will initialize the editor with a piece of code already in + it, and explicitly tell it to use the JavaScript mode (which is + useful when multiple modes are loaded). + See below for a full discussion of the + configuration options that CodeMirror accepts.

+ +

In cases where you don't want to append the editor to an + element, and need more control over the way it is inserted, the + first argument to the CodeMirror function can also + be a function that, when given a DOM element, inserts it into the + document somewhere. This could be used to, for example, replace a + textarea with a real editor:

+ +
var myCodeMirror = CodeMirror(function(elt) {
+  myTextArea.parentNode.replaceChild(elt, myTextArea);
+}, {value: myTextArea.value});
+ +

However, for this use case, which is a common way to use + CodeMirror, the library provides a much more powerful + shortcut:

+ +
var myCodeMirror = CodeMirror.fromTextArea(myTextArea);
+ +

This will, among other things, ensure that the textarea's value + is updated with the editor's contents when the form (if it is part + of a form) is submitted. See the API + reference for a full description of this method.

+ +

Module loaders

+ +

The files in the CodeMirror distribution contain shims for + loading them (and their dependencies) in AMD or CommonJS + environments. If the variables exports + and module exist and have type object, CommonJS-style + require will be used. If not, but there is a + function define with an amd property + present, AMD-style (RequireJS) will be used.

+ +

It is possible to + use Browserify or similar + tools to statically build modules using CodeMirror. Alternatively, + use RequireJS to dynamically + load dependencies at runtime. Both of these approaches have the + advantage that they don't use the global namespace and can, thus, + do things like load multiple versions of CodeMirror alongside each + other.

+ +

Here's a simple example of using RequireJS to load CodeMirror:

+ +
require([
+  "cm/lib/codemirror", "cm/mode/htmlmixed/htmlmixed"
+], function(CodeMirror) {
+  CodeMirror.fromTextArea(document.getElementById("code"), {
+    lineNumbers: true,
+    mode: "htmlmixed"
+  });
+});
+ +

It will automatically load the modes that the mixed HTML mode + depends on (XML, JavaScript, and CSS). Do not use + RequireJS' paths option to configure the path to + CodeMirror, since it will break loading submodules through + relative paths. Use + the packages + configuration option instead, as in:

+ +
require.config({
+  packages: [{
+    name: "codemirror",
+    location: "../path/to/codemirror",
+    main: "lib/codemirror"
+  }]
+});
+ +
+ +
+

Configuration

+ +

Both the CodeMirror + function and its fromTextArea method take as second + (optional) argument an object containing configuration options. + Any option not supplied like this will be taken + from CodeMirror.defaults, an + object containing the default options. You can update this object + to change the defaults on your page.

+ +

Options are not checked in any way, so setting bogus option + values is bound to lead to odd errors.

+ +

These are the supported options:

+ +
+
value: string|CodeMirror.Doc
+
The starting value of the editor. Can be a string, or + a document object.
+ +
mode: string|object
+
The mode to use. When not given, this will default to the + first mode that was loaded. It may be a string, which either + simply names the mode or is + a MIME type + associated with the mode. Alternatively, it may be an object + containing configuration options for the mode, with + a name property that names the mode (for + example {name: "javascript", json: true}). The demo + pages for each mode contain information about what configuration + parameters the mode supports. You can ask CodeMirror which modes + and MIME types have been defined by inspecting + the CodeMirror.modes + and CodeMirror.mimeModes objects. The first maps + mode names to their constructors, and the second maps MIME types + to mode specs.
+ +
lineSeparator: string|null
+
Explicitly set the line separator for the editor. By default + (value null), the document will be split on CRLFs + as well as lone CRs and LFs, and a single LF will be used as + line separator in all output (such + as getValue). When a + specific string is given, lines will only be split on that + string, and output will, by default, use that same + separator.
+ +
theme: string
+
The theme to style the editor with. You must make sure the + CSS file defining the corresponding .cm-s-[name] + styles is loaded (see + the theme directory in the + distribution). The default is "default", for which + colors are included in codemirror.css. It is + possible to use multiple theming classes at once—for + example "foo bar" will assign both + the cm-s-foo and the cm-s-bar classes + to the editor.
+ +
indentUnit: integer
+
How many spaces a block (whatever that means in the edited + language) should be indented. The default is 2.
+ +
smartIndent: boolean
+
Whether to use the context-sensitive indentation that the + mode provides (or just indent the same as the line before). + Defaults to true.
+ +
tabSize: integer
+
The width of a tab character. Defaults to 4.
+ +
indentWithTabs: boolean
+
Whether, when indenting, the first N*tabSize + spaces should be replaced by N tabs. Default is false.
+ +
electricChars: boolean
+
Configures whether the editor should re-indent the current + line when a character is typed that might change its proper + indentation (only works if the mode supports indentation). + Default is true.
+ +
specialChars: RegExp
+
A regular expression used to determine which characters + should be replaced by a + special placeholder. + Mostly useful for non-printing special characters. The default + is /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/.
+
specialCharPlaceholder: function(char) → Element
+
A function that, given a special character identified by + the specialChars + option, produces a DOM node that is used to represent the + character. By default, a red dot () + is shown, with a title tooltip to indicate the character code.
+ +
rtlMoveVisually: boolean
+
Determines whether horizontal cursor movement through + right-to-left (Arabic, Hebrew) text is visual (pressing the left + arrow moves the cursor left) or logical (pressing the left arrow + moves to the next lower index in the string, which is visually + right in right-to-left text). The default is false + on Windows, and true on other platforms.
+ +
keyMap: string
+
Configures the key map to use. The default + is "default", which is the only key map defined + in codemirror.js itself. Extra key maps are found in + the key map directory. See + the section on key maps for more + information.
+ +
extraKeys: object
+
Can be used to specify extra key bindings for the editor, + alongside the ones defined + by keyMap. Should be + either null, or a valid key map value.
+ +
configureMouse: fn(cm: CodeMirror, repeat: "single" | "double" | "triple", event: Event) → Object
+
Allows you to configure the behavior of mouse selection and + dragging. The function is called when the left mouse button is + pressed. The returned object may have the following properties: +
+
unit: "char" | "word" | "line" | "rectangle" | fn(CodeMirror, Pos) → {from: Pos, to: Pos}
+
The unit by which to select. May be one of the built-in + units, or a function that takes a position and returns a + range around that, for a custom unit.
+
extend: bool
+
Whether to extend the existing selection range or start a new one.
+
addNew: bool
+
When enabled, this adds a new range to the existing selection, rather than replacing it.
+
moveOnDrag: bool
+
When the mouse even drags content around inside the + editor, this controls whether it is copied (false) or moved + (true). +
+
+ +
lineWrapping: boolean
+
Whether CodeMirror should scroll or wrap for long lines. + Defaults to false (scroll).
+ +
lineNumbers: boolean
+
Whether to show line numbers to the left of the editor.
+ +
firstLineNumber: integer
+
At which number to start counting lines. Default is 1.
+ +
lineNumberFormatter: function(line: integer) → string
+
A function used to format line numbers. The function is + passed the line number, and should return a string that will be + shown in the gutter.
+ +
gutters: array<string>
+
Can be used to add extra gutters (beyond or instead of the + line number gutter). Should be an array of CSS class names, each + of which defines a width (and optionally a + background), and which will be used to draw the background of + the gutters. May include + the CodeMirror-linenumbers class, in order to + explicitly set the position of the line number gutter (it will + default to be to the right of all other gutters). These class + names are the keys passed + to setGutterMarker.
+ +
fixedGutter: boolean
+
Determines whether the gutter scrolls along with the content + horizontally (false) or whether it stays fixed during horizontal + scrolling (true, the default).
+ +
scrollbarStyle: string
+
Chooses a scrollbar implementation. The default + is "native", showing native scrollbars. The core + library also provides the "null" style, which + completely hides the + scrollbars. Addons can + implement additional scrollbar models.
+ +
coverGutterNextToScrollbar: boolean
+
When fixedGutter + is on, and there is a horizontal scrollbar, by default the + gutter will be visible to the left of this scrollbar. If this + option is set to true, it will be covered by an element with + class CodeMirror-gutter-filler.
+ +
inputStyle: string
+
Selects the way CodeMirror handles input and focus. The core + library defines the "textarea" + and "contenteditable" input models. On mobile + browsers, the default is "contenteditable". On + desktop browsers, the default is "textarea". + Support for IME and screen readers is better in + the "contenteditable" model. The intention is to + make it the default on modern desktop browsers in the + future.
+ +
readOnly: boolean|string
+
This disables editing of the editor content by the user. If + the special value "nocursor" is given (instead of + simply true), focusing of the editor is also + disallowed.
+ +
showCursorWhenSelecting: boolean
+
Whether the cursor should be drawn when a selection is + active. Defaults to false.
+ +
lineWiseCopyCut: boolean
+
When enabled, which is the default, doing copy or cut when + there is no selection will copy or cut the whole lines that have + cursors on them.
+ +
pasteLinesPerSelection: boolean
+
When pasting something from an external source (not from the + editor itself), if the number of lines matches the number of + selection, CodeMirror will by default insert one line per + selection. You can set this to false to disable + that behavior.
+ +
undoDepth: integer
+
The maximum number of undo levels that the editor stores. + Note that this includes selection change events. Defaults to + 200.
+ +
historyEventDelay: integer
+
The period of inactivity (in milliseconds) that will cause a + new history event to be started when typing or deleting. + Defaults to 1250.
+ +
tabindex: integer
+
The tab + index to assign to the editor. If not given, no tab index + will be assigned.
+ +
autofocus: boolean
+
Can be used to make CodeMirror focus itself on + initialization. Defaults to off. + When fromTextArea is + used, and no explicit value is given for this option, it will be + set to true when either the source textarea is focused, or it + has an autofocus attribute and no other element is + focused.
+
+ +

Below this a few more specialized, low-level options are + listed. These are only useful in very specific situations, you + might want to skip them the first time you read this manual.

+ +
+
dragDrop: boolean
+
Controls whether drag-and-drop is enabled. On by default.
+ +
allowDropFileTypes: array<string>
+
When set (default is null) only files whose + type is in the array can be dropped into the editor. The strings + should be MIME types, and will be checked against + the type + of the File object as reported by the browser.
+ +
cursorBlinkRate: number
+
Half-period in milliseconds used for cursor blinking. The default blink + rate is 530ms. By setting this to zero, blinking can be disabled. A + negative value hides the cursor entirely.
+ +
cursorScrollMargin: number
+
How much extra space to always keep above and below the + cursor when approaching the top or bottom of the visible view in + a scrollable document. Default is 0.
+ +
cursorHeight: number
+
Determines the height of the cursor. Default is 1, meaning + it spans the whole height of the line. For some fonts (and by + some tastes) a smaller height (for example 0.85), + which causes the cursor to not reach all the way to the bottom + of the line, looks better
+ +
resetSelectionOnContextMenu: boolean
+
Controls whether, when the context menu is opened with a + click outside of the current selection, the cursor is moved to + the point of the click. Defaults to true.
+ +
workTime, workDelay: number
+
Highlighting is done by a pseudo background-thread that will + work for workTime milliseconds, and then use + timeout to sleep for workDelay milliseconds. The + defaults are 200 and 300, you can change these options to make + the highlighting more or less aggressive.
+ +
pollInterval: number
+
Indicates how quickly CodeMirror should poll its input + textarea for changes (when focused). Most input is captured by + events, but some things, like IME input on some browsers, don't + generate events that allow CodeMirror to properly detect it. + Thus, it polls. Default is 100 milliseconds.
+ +
flattenSpans: boolean
+
By default, CodeMirror will combine adjacent tokens into a + single span if they have the same class. This will result in a + simpler DOM tree, and thus perform better. With some kinds of + styling (such as rounded corners), this will change the way the + document looks. You can set this option to false to disable this + behavior.
+ +
addModeClass: boolean
+
When enabled (off by default), an extra CSS class will be + added to each token, indicating the + (inner) mode that produced it, prefixed + with "cm-m-". For example, tokens from the XML mode + will get the cm-m-xml class.
+ +
maxHighlightLength: number
+
When highlighting long lines, in order to stay responsive, + the editor will give up and simply style the rest of the line as + plain text when it reaches a certain position. The default is + 10 000. You can set this to Infinity to turn off + this behavior.
+ +
viewportMargin: integer
+
Specifies the amount of lines that are rendered above and + below the part of the document that's currently scrolled into + view. This affects the amount of updates needed when scrolling, + and the amount of work that such an update does. You should + usually leave it at its default, 10. Can be set + to Infinity to make sure the whole document is + always rendered, and thus the browser's text search works on it. + This will have bad effects on performance of big + documents.
+
+
+ +
+

Events

+ +

Various CodeMirror-related objects emit events, which allow + client code to react to various situations. Handlers for such + events can be registered with the on + and off methods on the objects + that the event fires on. To fire your own events, + use CodeMirror.signal(target, name, args...), + where target is a non-DOM-node object.

+ +

An editor instance fires the following events. + The instance argument always refers to the editor + itself.

+ +
+
"change" (instance: CodeMirror, changeObj: object)
+
Fires every time the content of the editor is changed. + The changeObj is a {from, to, text, removed, + origin} object containing information about the changes + that occurred as second argument. from + and to are the positions (in the pre-change + coordinate system) where the change started and ended (for + example, it might be {ch:0, line:18} if the + position is at the beginning of line #19). text is + an array of strings representing the text that replaced the + changed range (split by line). removed is the text + that used to be between from and to, + which is overwritten by this change. This event is + fired before the end of + an operation, before the DOM updates + happen.
+ +
"changes" (instance: CodeMirror, changes: array<object>)
+
Like the "change" + event, but batched per operation, + passing an array containing all the changes that happened in the + operation. This event is fired after the operation finished, and + display changes it makes will trigger a new operation.
+ +
"beforeChange" (instance: CodeMirror, changeObj: object)
+
This event is fired before a change is applied, and its + handler may choose to modify or cancel the change. + The changeObj object + has from, to, and text + properties, as with + the "change" event. It + also has a cancel() method, which can be called to + cancel the change, and, if the change isn't + coming from an undo or redo event, an update(from, to, + text) method, which may be used to modify the change. + Undo or redo changes can't be modified, because they hold some + metainformation for restoring old marked ranges that is only + valid for that specific change. All three arguments + to update are optional, and can be left off to + leave the existing value for that field + intact. Note: you may not do anything from + a "beforeChange" handler that would cause changes + to the document or its visualization. Doing so will, since this + handler is called directly from the bowels of the CodeMirror + implementation, probably cause the editor to become + corrupted.
+ +
"cursorActivity" (instance: CodeMirror)
+
Will be fired when the cursor or selection moves, or any + change is made to the editor content.
+ +
"keyHandled" (instance: CodeMirror, name: string, event: Event)
+
Fired after a key is handled through a + key map. name is the name of the handled key (for + example "Ctrl-X" or "'q'"), + and event is the DOM keydown + or keypress event.
+ +
"inputRead" (instance: CodeMirror, changeObj: object)
+
Fired whenever new input is read from the hidden textarea + (typed or pasted by the user).
+ +
"electricInput" (instance: CodeMirror, line: integer)
+
Fired if text input matched the + mode's electric patterns, + and this caused the line's indentation to change.
+ +
"beforeSelectionChange" (instance: CodeMirror, obj: {ranges, origin, update})
+
This event is fired before the selection is moved. Its + handler may inspect the set of selection ranges, present as an + array of {anchor, head} objects in + the ranges property of the obj + argument, and optionally change them by calling + the update method on this object, passing an array + of ranges in the same format. The object also contains + an origin property holding the origin string passed + to the selection-changing method, if any. Handlers for this + event have the same restriction + as "beforeChange" + handlers — they should not do anything to directly update the + state of the editor.
+ +
"viewportChange" (instance: CodeMirror, from: number, to: number)
+
Fires whenever the view port of + the editor changes (due to scrolling, editing, or any other + factor). The from and to arguments + give the new start and end of the viewport.
+ +
"swapDoc" (instance: CodeMirror, oldDoc: Doc)
+
This is signalled when the editor's document is replaced + using the swapDoc + method.
+ +
"gutterClick" (instance: CodeMirror, line: integer, gutter: string, clickEvent: Event)
+
Fires when the editor gutter (the line-number area) is + clicked. Will pass the editor instance as first argument, the + (zero-based) number of the line that was clicked as second + argument, the CSS class of the gutter that was clicked as third + argument, and the raw mousedown event object as + fourth argument.
+ +
"gutterContextMenu" (instance: CodeMirror, line: integer, gutter: string, contextMenu: Event: Event)
+
Fires when the editor gutter (the line-number area) + receives a contextmenu event. Will pass the editor + instance as first argument, the (zero-based) number of the line + that was clicked as second argument, the CSS class of the + gutter that was clicked as third argument, and the raw + contextmenu mouse event object as fourth argument. + You can preventDefault the event, to signal that + CodeMirror should do no further handling.
+ +
"focus" (instance: CodeMirror, event: Event)
+
Fires whenever the editor is focused.
+ +
"blur" (instance: CodeMirror, event: Event)
+
Fires whenever the editor is unfocused.
+ +
"scroll" (instance: CodeMirror)
+
Fires when the editor is scrolled.
+ +
"refresh" (instance: CodeMirror)
+
Fires when the editor is refreshed + or resized. Mostly useful to invalidate + cached values that depend on the editor or character size.
+ +
"optionChange" (instance: CodeMirror, option: string)
+
Dispatched every time an option is changed with setOption.
+ +
"scrollCursorIntoView" (instance: CodeMirror, event: Event)
+
Fires when the editor tries to scroll its cursor into view. + Can be hooked into to take care of additional scrollable + containers around the editor. When the event object has + its preventDefault method called, CodeMirror will + not itself try to scroll the window.
+ +
"update" (instance: CodeMirror)
+
Will be fired whenever CodeMirror updates its DOM display.
+ +
"renderLine" (instance: CodeMirror, line: LineHandle, element: Element)
+
Fired whenever a line is (re-)rendered to the DOM. Fired + right after the DOM element is built, before it is + added to the document. The handler may mess with the style of + the resulting element, or add event handlers, but + should not try to change the state of the editor.
+ +
"mousedown", + "dblclick", "touchstart", "contextmenu", + "keydown", "keypress", + "keyup", "cut", "copy", "paste", + "dragstart", "dragenter", + "dragover", "dragleave", + "drop" + (instance: CodeMirror, event: Event)
+
Fired when CodeMirror is handling a DOM event of this type. + You can preventDefault the event, or give it a + truthy codemirrorIgnore property, to signal that + CodeMirror should do no further handling.
+
+ +

Document objects (instances + of CodeMirror.Doc) emit the + following events:

+ +
+
"change" (doc: CodeMirror.Doc, changeObj: object)
+
Fired whenever a change occurs to the + document. changeObj has a similar type as the + object passed to the + editor's "change" + event.
+ +
"beforeChange" (doc: CodeMirror.Doc, change: object)
+
See the description of the + same event on editor instances.
+ +
"cursorActivity" (doc: CodeMirror.Doc)
+
Fired whenever the cursor or selection in this document + changes.
+ +
"beforeSelectionChange" (doc: CodeMirror.Doc, selection: {head, anchor})
+
Equivalent to + the event by the same + name as fired on editor instances.
+
+ +

Line handles (as returned by, for + example, getLineHandle) + support these events:

+ +
+
"delete" ()
+
Will be fired when the line object is deleted. A line object + is associated with the start of the line. Mostly useful + when you need to find out when your gutter + markers on a given line are removed.
+
"change" (line: LineHandle, changeObj: object)
+
Fires when the line's text content is changed in any way + (but the line is not deleted outright). The change + object is similar to the one passed + to change event on the editor + object.
+
+ +

Marked range handles (CodeMirror.TextMarker), as returned + by markText + and setBookmark, emit the + following events:

+ +
+
"beforeCursorEnter" ()
+
Fired when the cursor enters the marked range. From this + event handler, the editor state may be inspected + but not modified, with the exception that the range on + which the event fires may be cleared.
+
"clear" (from: {line, ch}, to: {line, ch})
+
Fired when the range is cleared, either through cursor + movement in combination + with clearOnEnter + or through a call to its clear() method. Will only + be fired once per handle. Note that deleting the range through + text editing does not fire this event, because an undo action + might bring the range back into existence. from + and to give the part of the document that the range + spanned when it was cleared.
+
"hide" ()
+
Fired when the last part of the marker is removed from the + document by editing operations.
+
"unhide" ()
+
Fired when, after the marker was removed by editing, a undo + operation brought the marker back.
+
+ +

Line widgets (CodeMirror.LineWidget), returned + by addLineWidget, fire + these events:

+ +
+
"redraw" ()
+
Fired whenever the editor re-adds the widget to the DOM. + This will happen once right after the widget is added (if it is + scrolled into view), and then again whenever it is scrolled out + of view and back in again, or when changes to the editor options + or the line the widget is on require the widget to be + redrawn.
+
+
+ +
+

Key Maps

+ +

Key maps are ways to associate keys and mouse buttons with + functionality. A key map is an object mapping strings that + identify the buttons to functions that implement their + functionality.

+ +

The CodeMirror distributions comes + with Emacs, Vim, + and Sublime Text-style keymaps.

+ +

Keys are identified either by name or by character. + The CodeMirror.keyNames object defines names for + common keys and associates them with their key codes. Examples of + names defined here are Enter, F5, + and Q. These can be prefixed + with Shift-, Cmd-, Ctrl-, + and Alt- to specify a modifier. So for + example, Shift-Ctrl-Space would be a valid key + identifier.

+ +

Common example: map the Tab key to insert spaces instead of a tab + character.

+ +
+editor.setOption("extraKeys", {
+  Tab: function(cm) {
+    var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
+    cm.replaceSelection(spaces);
+  }
+});
+ +

Alternatively, a character can be specified directly by + surrounding it in single quotes, for example '$' + or 'q'. Due to limitations in the way browsers fire + key events, these may not be prefixed with modifiers.

+ +

To bind mouse buttons, use the names `LeftClick`, + `MiddleClick`, and `RightClick`. These can also be prefixed with + modifiers, and in addition, the word `Double` or `Triple` can be + put before `Click` (as in `LeftDoubleClick`) to bind a double- or + triple-click. The function for such a binding is passed the + position that was clicked as second argument.

+ +

Multi-stroke key bindings can be specified + by separating the key names by spaces in the property name, for + example Ctrl-X Ctrl-V. When a map contains + multi-stoke bindings or keys with modifiers that are not specified + in the default order (Shift-Cmd-Ctrl-Alt), you must + call CodeMirror.normalizeKeyMap on it before it can + be used. This function takes a keymap and modifies it to normalize + modifier order and properly recognize multi-stroke bindings. It + will return the keymap itself.

+ +

The CodeMirror.keyMap object associates key maps + with names. User code and key map definitions can assign extra + properties to this object. Anywhere where a key map is expected, a + string can be given, which will be looked up in this object. It + also contains the "default" key map holding the + default bindings.

+ +

The values of properties in key maps can be either functions of + a single argument (the CodeMirror instance), strings, or + false. Strings refer + to commands, which are described below. If + the property is set to false, CodeMirror leaves + handling of the key up to the browser. A key handler function may + return CodeMirror.Pass to indicate that it has + decided not to handle the key, and other handlers (or the default + behavior) should be given a turn.

+ +

Keys mapped to command names that start with the + characters "go" or to functions that have a + truthy motion property (which should be used for + cursor-movement actions) will be fired even when an + extra Shift modifier is present (i.e. "Up": + "goLineUp" matches both up and shift-up). This is used to + easily implement shift-selection.

+ +

Key maps can defer to each other by defining + a fallthrough property. This indicates that when a + key is not found in the map itself, one or more other maps should + be searched. It can hold either a single key map or an array of + key maps.

+ +

When a key map needs to set something up when it becomes + active, or tear something down when deactivated, it can + contain attach and/or detach properties, + which should hold functions that take the editor instance and the + next or previous keymap. Note that this only works for the + top-level keymap, not for fallthrough + maps or maps added + with extraKeys + or addKeyMap.

+
+ +
+

Commands

+ +

Commands are parameter-less actions that can be performed on an + editor. Their main use is for key bindings. Commands are defined by + adding properties to the CodeMirror.commands object. + A number of common commands are defined by the library itself, + most of them used by the default key bindings. The value of a + command property must be a function of one argument (an editor + instance).

+ +

Some of the commands below are referenced in the default + key map, but not defined by the core library. These are intended to + be defined by user code or addons.

+ +

Commands can also be run with + the execCommand + method.

+ +
+
selectAllCtrl-A (PC), Cmd-A (Mac)
+
Select the whole content of the editor.
+ +
singleSelectionEsc
+
When multiple selections are present, this deselects all but + the primary selection.
+ +
killLineCtrl-K (Mac)
+
Emacs-style line killing. Deletes the part of the line after + the cursor. If that consists only of whitespace, the newline at + the end of the line is also deleted.
+ +
deleteLineCtrl-D (PC), Cmd-D (Mac)
+
Deletes the whole line under the cursor, including newline at the end.
+ +
delLineLeft
+
Delete the part of the line before the cursor.
+ +
delWrappedLineLeftCmd-Backspace (Mac)
+
Delete the part of the line from the left side of the visual line the cursor is on to the cursor.
+ +
delWrappedLineRightCmd-Delete (Mac)
+
Delete the part of the line from the cursor to the right side of the visual line the cursor is on.
+ +
undoCtrl-Z (PC), Cmd-Z (Mac)
+
Undo the last change. Note that, because browsers still + don't make it possible for scripts to react to or customize the + context menu, selecting undo (or redo) from the context menu in + a CodeMirror instance does not work.
+ +
redoCtrl-Y (PC), Shift-Cmd-Z (Mac), Cmd-Y (Mac)
+
Redo the last undone change.
+ +
undoSelectionCtrl-U (PC), Cmd-U (Mac)
+
Undo the last change to the selection, or if there are no + selection-only changes at the top of the history, undo the last + change.
+ +
redoSelectionAlt-U (PC), Shift-Cmd-U (Mac)
+
Redo the last change to the selection, or the last text change if + no selection changes remain.
+ +
goDocStartCtrl-Home (PC), Cmd-Up (Mac), Cmd-Home (Mac)
+
Move the cursor to the start of the document.
+ +
goDocEndCtrl-End (PC), Cmd-End (Mac), Cmd-Down (Mac)
+
Move the cursor to the end of the document.
+ +
goLineStartAlt-Left (PC), Ctrl-A (Mac)
+
Move the cursor to the start of the line.
+ +
goLineStartSmartHome
+
Move to the start of the text on the line, or if we are + already there, to the actual start of the line (including + whitespace).
+ +
goLineEndAlt-Right (PC), Ctrl-E (Mac)
+
Move the cursor to the end of the line.
+ +
goLineRightCmd-Right (Mac)
+
Move the cursor to the right side of the visual line it is on.
+ +
goLineLeftCmd-Left (Mac)
+
Move the cursor to the left side of the visual line it is on. If + this line is wrapped, that may not be the start of the line.
+ +
goLineLeftSmart
+
Move the cursor to the left side of the visual line it is + on. If that takes it to the start of the line, behave + like goLineStartSmart.
+ +
goLineUpUp, Ctrl-P (Mac)
+
Move the cursor up one line.
+ +
goLineDownDown, Ctrl-N (Mac)
+
Move down one line.
+ +
goPageUpPageUp, Shift-Ctrl-V (Mac)
+
Move the cursor up one screen, and scroll up by the same distance.
+ +
goPageDownPageDown, Ctrl-V (Mac)
+
Move the cursor down one screen, and scroll down by the same distance.
+ +
goCharLeftLeft, Ctrl-B (Mac)
+
Move the cursor one character left, going to the previous line + when hitting the start of line.
+ +
goCharRightRight, Ctrl-F (Mac)
+
Move the cursor one character right, going to the next line + when hitting the end of line.
+ +
goColumnLeft
+
Move the cursor one character left, but don't cross line boundaries.
+ +
goColumnRight
+
Move the cursor one character right, don't cross line boundaries.
+ +
goWordLeftAlt-B (Mac)
+
Move the cursor to the start of the previous word.
+ +
goWordRightAlt-F (Mac)
+
Move the cursor to the end of the next word.
+ +
goGroupLeftCtrl-Left (PC), Alt-Left (Mac)
+
Move to the left of the group before the cursor. A group is + a stretch of word characters, a stretch of punctuation + characters, a newline, or a stretch of more than one + whitespace character.
+ +
goGroupRightCtrl-Right (PC), Alt-Right (Mac)
+
Move to the right of the group after the cursor + (see above).
+ +
delCharBeforeShift-Backspace, Ctrl-H (Mac)
+
Delete the character before the cursor.
+ +
delCharAfterDelete, Ctrl-D (Mac)
+
Delete the character after the cursor.
+ +
delWordBeforeAlt-Backspace (Mac)
+
Delete up to the start of the word before the cursor.
+ +
delWordAfterAlt-D (Mac)
+
Delete up to the end of the word after the cursor.
+ +
delGroupBeforeCtrl-Backspace (PC), Alt-Backspace (Mac)
+
Delete to the left of the group before the cursor.
+ +
delGroupAfterCtrl-Delete (PC), Ctrl-Alt-Backspace (Mac), Alt-Delete (Mac)
+
Delete to the start of the group after the cursor.
+ +
indentAutoShift-Tab
+
Auto-indent the current line or selection.
+ +
indentMoreCtrl-] (PC), Cmd-] (Mac)
+
Indent the current line or selection by one indent unit.
+ +
indentLessCtrl-[ (PC), Cmd-[ (Mac)
+
Dedent the current line or selection by one indent unit.
+ +
insertTab
+
Insert a tab character at the cursor.
+ +
insertSoftTab
+
Insert the amount of spaces that match the width a tab at + the cursor position would have.
+ +
defaultTabTab
+
If something is selected, indent it by + one indent unit. If nothing is + selected, insert a tab character.
+ +
transposeCharsCtrl-T (Mac)
+
Swap the characters before and after the cursor.
+ +
newlineAndIndentEnter
+
Insert a newline and auto-indent the new line.
+ +
toggleOverwriteInsert
+
Flip the overwrite flag.
+ +
saveCtrl-S (PC), Cmd-S (Mac)
+
Not defined by the core library, only referred to in + key maps. Intended to provide an easy way for user code to define + a save command.
+ +
findCtrl-F (PC), Cmd-F (Mac)
+
findNextCtrl-G (PC), Cmd-G (Mac)
+
findPrevShift-Ctrl-G (PC), Shift-Cmd-G (Mac)
+
replaceShift-Ctrl-F (PC), Cmd-Alt-F (Mac)
+
replaceAllShift-Ctrl-R (PC), Shift-Cmd-Alt-F (Mac)
+
Not defined by the core library, but defined in + the search addon (or custom client + addons).
+ +
+ +
+ +
+

Customized Styling

+ +

Up to a certain extent, CodeMirror's look can be changed by + modifying style sheet files. The style sheets supplied by modes + simply provide the colors for that mode, and can be adapted in a + very straightforward way. To style the editor itself, it is + possible to alter or override the styles defined + in codemirror.css.

+ +

Some care must be taken there, since a lot of the rules in this + file are necessary to have CodeMirror function properly. Adjusting + colors should be safe, of course, and with some care a lot of + other things can be changed as well. The CSS classes defined in + this file serve the following roles:

+ +
+
CodeMirror
+
The outer element of the editor. This should be used for the + editor width, height, borders and positioning. Can also be used + to set styles that should hold for everything inside the editor + (such as font and font size), or to set a background. Setting + this class' height style to auto will + make the editor resize to fit its + content (it is recommended to also set + the viewportMargin + option to Infinity when doing this.
+ +
CodeMirror-focused
+
Whenever the editor is focused, the top element gets this + class. This is used to hide the cursor and give the selection a + different color when the editor is not focused.
+ +
CodeMirror-gutters
+
This is the backdrop for all gutters. Use it to set the + default gutter background color, and optionally add a border on + the right of the gutters.
+ +
CodeMirror-linenumbers
+
Use this for giving a background or width to the line number + gutter.
+ +
CodeMirror-linenumber
+
Used to style the actual individual line numbers. These + won't be children of the CodeMirror-linenumbers + (plural) element, but rather will be absolutely positioned to + overlay it. Use this to set alignment and text properties for + the line numbers.
+ +
CodeMirror-lines
+
The visible lines. This is where you specify vertical + padding for the editor content.
+ +
CodeMirror-cursor
+
The cursor is a block element that is absolutely positioned. + You can make it look whichever way you want.
+ +
CodeMirror-selected
+
The selection is represented by span elements + with this class.
+ +
CodeMirror-matchingbracket, + CodeMirror-nonmatchingbracket
+
These are used to style matched (or unmatched) brackets.
+
+ +

If your page's style sheets do funky things to + all div or pre elements (you probably + shouldn't do that), you'll have to define rules to cancel these + effects out again for elements under the CodeMirror + class.

+ +

Themes are also simply CSS files, which define colors for + various syntactic elements. See the files in + the theme directory.

+
+ +
+

Programming API

+ +

A lot of CodeMirror features are only available through its + API. Thus, you need to write code (or + use addons) if you want to expose them to + your users.

+ +

Whenever points in the document are represented, the API uses + objects with line and ch properties. + Both are zero-based. CodeMirror makes sure to 'clip' any positions + passed by client code so that they fit inside the document, so you + shouldn't worry too much about sanitizing your coordinates. If you + give ch a value of null, or don't + specify it, it will be replaced with the length of the specified + line. Such positions may also have a sticky property + holding "before" or "after", whether the + position is associated with the character before or after it. This + influences, for example, where the cursor is drawn on a + line-break or bidi-direction boundary.

+ +

Methods prefixed with doc. can, unless otherwise + specified, be called both on CodeMirror (editor) + instances and CodeMirror.Doc instances. Methods + prefixed with cm. are only available + on CodeMirror instances.

+ +

Constructor

+ +

Constructing an editor instance is done with + the CodeMirror(place: Element|fn(Element), + ?option: object) constructor. If the place + argument is a DOM element, the editor will be appended to it. If + it is a function, it will be called, and is expected to place the + editor into the document. options may be an element + mapping option names to values. The options + that it doesn't explicitly specify (or all options, if it is not + passed) will be taken + from CodeMirror.defaults.

+ +

Note that the options object passed to the constructor will be + mutated when the instance's options + are changed, so you shouldn't share such + objects between instances.

+ +

See CodeMirror.fromTextArea + for another way to construct an editor instance.

+ +

Content manipulation methods

+ +
+
doc.getValue(?separator: string) → string
+
Get the current editor content. You can pass it an optional + argument to specify the string to be used to separate lines + (defaults to "\n").
+
doc.setValue(content: string)
+
Set the editor content.
+ +
doc.getRange(from: {line, ch}, to: {line, ch}, ?separator: string) → string
+
Get the text between the given points in the editor, which + should be {line, ch} objects. An optional third + argument can be given to indicate the line separator string to + use (defaults to "\n").
+
doc.replaceRange(replacement: string, from: {line, ch}, to: {line, ch}, ?origin: string)
+
Replace the part of the document between from + and to with the given string. from + and to must be {line, ch} + objects. to can be left off to simply insert the + string at position from. When origin + is given, it will be passed on + to "change" events, and + its first letter will be used to determine whether this change + can be merged with previous history events, in the way described + for selection origins.
+ +
doc.getLine(n: integer) → string
+
Get the content of line n.
+ +
doc.lineCount() → integer
+
Get the number of lines in the editor.
+
doc.firstLine() → integer
+
Get the first line of the editor. This will + usually be zero but for linked sub-views, + or documents instantiated with a non-zero + first line, it might return other values.
+
doc.lastLine() → integer
+
Get the last line of the editor. This will + usually be doc.lineCount() - 1, + but for linked sub-views, + it might return other values.
+ +
doc.getLineHandle(num: integer) → LineHandle
+
Fetches the line handle for the given line number.
+
doc.getLineNumber(handle: LineHandle) → integer
+
Given a line handle, returns the current position of that + line (or null when it is no longer in the + document).
+
doc.eachLine(f: (line: LineHandle))
+
doc.eachLine(start: integer, end: integer, f: (line: LineHandle))
+
Iterate over the whole document, or if start + and end line numbers are given, the range + from start up to (not including) end, + and call f for each line, passing the line handle. + This is a faster way to visit a range of line handlers than + calling getLineHandle + for each of them. Note that line handles have + a text property containing the line's content (as a + string).
+ +
doc.markClean()
+
Set the editor content as 'clean', a flag that it will + retain until it is edited, and which will be set again when such + an edit is undone again. Useful to track whether the content + needs to be saved. This function is deprecated in favor + of changeGeneration, + which allows multiple subsystems to track different notions of + cleanness without interfering.
+
doc.changeGeneration(?closeEvent: boolean) → integer
+
Returns a number that can later be passed + to isClean to test whether + any edits were made (and not undone) in the meantime. + If closeEvent is true, the current history event + will be ‘closed’, meaning it can't be combined with further + changes (rapid typing or deleting events are typically + combined).
+
doc.isClean(?generation: integer) → boolean
+
Returns whether the document is currently clean — not + modified since initialization or the last call + to markClean if no + argument is passed, or since the matching call + to changeGeneration + if a generation value is given.
+
+ +

Cursor and selection methods

+ +
+
doc.getSelection(?lineSep: string) → string
+
Get the currently selected code. Optionally pass a line + separator to put between the lines in the output. When multiple + selections are present, they are concatenated with instances + of lineSep in between.
+
doc.getSelections(?lineSep: string) → array<string>
+
Returns an array containing a string for each selection, + representing the content of the selections.
+ +
doc.replaceSelection(replacement: string, ?select: string)
+
Replace the selection(s) with the given string. By default, + the new selection ends up after the inserted text. The + optional select argument can be used to change + this—passing "around" will cause the new text to be + selected, passing "start" will collapse the + selection to the start of the inserted text.
+
doc.replaceSelections(replacements: array<string>, ?select: string)
+
The length of the given array should be the same as the + number of active selections. Replaces the content of the + selections with the strings in the array. + The select argument works the same as + in replaceSelection.
+ +
doc.getCursor(?start: string) → {line, ch}
+
Retrieve one end of the primary + selection. start is an optional string indicating + which end of the selection to return. It may + be "from", "to", "head" + (the side of the selection that moves when you press + shift+arrow), or "anchor" (the fixed side of the + selection). Omitting the argument is the same as + passing "head". A {line, ch} object + will be returned.
+
doc.listSelections() → array<{anchor, head}>
+
Retrieves a list of all current selections. These will + always be sorted, and never overlap (overlapping selections are + merged). Each object in the array contains anchor + and head properties referring to {line, + ch} objects.
+ +
doc.somethingSelected() → boolean
+
Return true if any text is selected.
+
doc.setCursor(pos: {line, ch}|number, ?ch: number, ?options: object)
+
Set the cursor position. You can either pass a + single {line, ch} object, or the line and the + character as two separate parameters. Will replace all + selections with a single, empty selection at the given position. + The supported options are the same as for setSelection.
+ +
doc.setSelection(anchor: {line, ch}, ?head: {line, ch}, ?options: object)
+
Set a single selection range. anchor + and head should be {line, ch} + objects. head defaults to anchor when + not given. These options are supported: +
+
scroll: boolean
+
Determines whether the selection head should be scrolled + into view. Defaults to true.
+
origin: string
+
Determines whether the selection history event may be + merged with the previous one. When an origin starts with the + character +, and the last recorded selection had + the same origin and was similar (close + in time, both + collapsed or both non-collapsed), the new one will replace the + old one. When it starts with *, it will always + replace the previous event (if that had the same origin). + Built-in motion uses the "+move" origin. User input uses the "+input" origin.
+
bias: number
+
Determine the direction into which the selection endpoints + should be adjusted when they fall inside + an atomic range. Can be either -1 + (backward) or 1 (forward). When not given, the bias will be + based on the relative position of the old selection—the editor + will try to move further away from that, to prevent getting + stuck.
+
+ +
doc.setSelections(ranges: array<{anchor, head}>, ?primary: integer, ?options: object)
+
Sets a new set of selections. There must be at least one + selection in the given array. When primary is a + number, it determines which selection is the primary one. When + it is not given, the primary index is taken from the previous + selection, or set to the last range if the previous selection + had less ranges than the new one. Supports the same options + as setSelection.
+
doc.addSelection(anchor: {line, ch}, ?head: {line, ch})
+
Adds a new selection to the existing set of selections, and + makes it the primary selection.
+ +
doc.extendSelection(from: {line, ch}, ?to: {line, ch}, ?options: object)
+
Similar + to setSelection, but + will, if shift is held or + the extending flag is set, move the + head of the selection while leaving the anchor at its current + place. to is optional, and can be passed to ensure + a region (for example a word or paragraph) will end up selected + (in addition to whatever lies between that region and the + current anchor). When multiple selections are present, all but + the primary selection will be dropped by this method. + Supports the same options as setSelection.
+
doc.extendSelections(heads: array<{line, ch}>, ?options: object)
+
An equivalent + of extendSelection + that acts on all selections at once.
+
doc.extendSelectionsBy(f: function(range: {anchor, head}) → {line, ch}), ?options: object)
+
Applies the given function to all existing selections, and + calls extendSelections + on the result.
+
doc.setExtending(value: boolean)
+
Sets or clears the 'extending' flag, which acts similar to + the shift key, in that it will cause cursor movement and calls + to extendSelection + to leave the selection anchor in place.
+
doc.getExtending() → boolean
+
Get the value of the 'extending' flag.
+ +
cm.hasFocus() → boolean
+
Tells you whether the editor currently has focus.
+ +
cm.findPosH(start: {line, ch}, amount: integer, unit: string, visually: boolean) → {line, ch, ?hitSide: boolean}
+
Used to find the target position for horizontal cursor + motion. start is a {line, ch} + object, amount an integer (may be negative), + and unit one of the + string "char", "column", + or "word". Will return a position that is produced + by moving amount times the distance specified + by unit. When visually is true, motion + in right-to-left text will be visual rather than logical. When + the motion was clipped by hitting the end or start of the + document, the returned value will have a hitSide + property set to true.
+
cm.findPosV(start: {line, ch}, amount: integer, unit: string) → {line, ch, ?hitSide: boolean}
+
Similar to findPosH, + but used for vertical motion. unit may + be "line" or "page". The other + arguments and the returned value have the same interpretation as + they have in findPosH.
+ +
cm.findWordAt(pos: {line, ch}) → {anchor: {line, ch}, head: {line, ch}}
+
Returns the start and end of the 'word' (the stretch of + letters, whitespace, or punctuation) at the given position.
+
+ +

Configuration methods

+ +
+
cm.setOption(option: string, value: any)
+
Change the configuration of the editor. option + should the name of an option, + and value should be a valid value for that + option.
+
cm.getOption(option: string) → any
+
Retrieves the current value of the given option for this + editor instance.
+ +
cm.addKeyMap(map: object, bottom: boolean)
+
Attach an additional key map to the + editor. This is mostly useful for addons that need to register + some key handlers without trampling on + the extraKeys + option. Maps added in this way have a higher precedence than + the extraKeys + and keyMap options, + and between them, the maps added earlier have a lower precedence + than those added later, unless the bottom argument + was passed, in which case they end up below other key maps added + with this method.
+
cm.removeKeyMap(map: object)
+
Disable a keymap added + with addKeyMap. Either + pass in the key map object itself, or a string, which will be + compared against the name property of the active + key maps.
+ +
cm.addOverlay(mode: string|object, ?options: object)
+
Enable a highlighting overlay. This is a stateless mini-mode + that can be used to add extra highlighting. For example, + the search addon uses it to + highlight the term that's currently being + searched. mode can be a mode + spec or a mode object (an object with + a token method). + The options parameter is optional. If given, it + should be an object, optionally containing the following options: +
+
opaque: bool
+
Defaults to off, but can be given to allow the overlay + styling, when not null, to override the styling of + the base mode entirely, instead of the two being applied + together.
+
priority: number
+
Determines the ordering in which the overlays are + applied. Those with high priority are applied after those + with lower priority, and able to override the opaqueness of + the ones that come before. Defaults to 0.
+
+
+ +
cm.removeOverlay(mode: string|object)
+
Pass this the exact value passed for the mode + parameter to addOverlay, + or a string that corresponds to the name property of + that value, to remove an overlay again.
+ +
cm.on(type: string, func: (...args))
+
Register an event handler for the given event type (a + string) on the editor instance. There is also + a CodeMirror.on(object, type, func) version + that allows registering of events on any object.
+
cm.off(type: string, func: (...args))
+
Remove an event handler on the editor instance. An + equivalent CodeMirror.off(object, type, + func) also exists.
+
+ +

Document management methods

+ +

Each editor is associated with an instance + of CodeMirror.Doc, its document. A document + represents the editor content, plus a selection, an undo history, + and a mode. A document can only be + associated with a single editor at a time. You can create new + documents by calling the CodeMirror.Doc(text, mode, + firstLineNumber) constructor. The last two arguments are + optional and can be used to set a mode for the document and make + it start at a line number other than 0, respectively.

+ +
+
cm.getDoc() → Doc
+
Retrieve the currently active document from an editor.
+
doc.getEditor() → CodeMirror
+
Retrieve the editor associated with a document. May + return null.
+ +
cm.swapDoc(doc: CodeMirror.Doc) → Doc
+
Attach a new document to the editor. Returns the old + document, which is now no longer associated with an editor.
+ +
doc.copy(copyHistory: boolean) → Doc
+
Create an identical copy of the given doc. + When copyHistory is true, the history will also be + copied. Can not be called directly on an editor.
+ +
doc.linkedDoc(options: object) → Doc
+
Create a new document that's linked to the target document. + Linked documents will stay in sync (changes to one are also + applied to the other) until unlinked. + These are the options that are supported: +
+
sharedHist: boolean
+
When turned on, the linked copy will share an undo + history with the original. Thus, something done in one of + the two can be undone in the other, and vice versa.
+
from: integer
+
to: integer
+
Can be given to make the new document a subview of the + original. Subviews only show a given range of lines. Note + that line coordinates inside the subview will be consistent + with those of the parent, so that for example a subview + starting at line 10 will refer to its first line as line 10, + not 0.
+
mode: string|object
+
By default, the new document inherits the mode of the + parent. This option can be set to + a mode spec to give it a + different mode.
+
+
doc.unlinkDoc(doc: CodeMirror.Doc)
+
Break the link between two documents. After calling this, + changes will no longer propagate between the documents, and, if + they had a shared history, the history will become + separate.
+
doc.iterLinkedDocs(function: (doc: CodeMirror.Doc, sharedHist: boolean))
+
Will call the given function for all documents linked to the + target document. It will be passed two arguments, the linked document + and a boolean indicating whether that document shares history + with the target.
+
+ +

History-related methods

+ +
+
doc.undo()
+
Undo one edit (if any undo events are stored).
+
doc.redo()
+
Redo one undone edit.
+ +
doc.undoSelection()
+
Undo one edit or selection change.
+
doc.redoSelection()
+
Redo one undone edit or selection change.
+ +
doc.historySize() → {undo: integer, redo: integer}
+
Returns an object with {undo, redo} properties, + both of which hold integers, indicating the amount of stored + undo and redo operations.
+
doc.clearHistory()
+
Clears the editor's undo history.
+
doc.getHistory() → object
+
Get a (JSON-serializable) representation of the undo history.
+
doc.setHistory(history: object)
+
Replace the editor's undo history with the one provided, + which must be a value as returned + by getHistory. Note that + this will have entirely undefined results if the editor content + isn't also the same as it was when getHistory was + called.
+
+ +

Text-marking methods

+ +
+
doc.markText(from: {line, ch}, to: {line, ch}, ?options: object) → TextMarker
+
Can be used to mark a range of text with a specific CSS + class name. from and to should + be {line, ch} objects. The options + parameter is optional. When given, it should be an object that + may contain the following configuration options: +
+
className: string
+
Assigns a CSS class to the marked stretch of text.
+
inclusiveLeft: boolean
+
Determines whether + text inserted on the left of the marker will end up inside + or outside of it.
+
inclusiveRight: boolean
+
Like inclusiveLeft, + but for the right side.
+
atomic: boolean
+
Atomic ranges act as a single unit when cursor movement is + concerned—i.e. it is impossible to place the cursor inside of + them. In atomic ranges, inclusiveLeft + and inclusiveRight have a different meaning—they + will prevent the cursor from being placed respectively + directly before and directly after the range.
+
collapsed: boolean
+
Collapsed ranges do not show up in the display. Setting a + range to be collapsed will automatically make it atomic.
+
clearOnEnter: boolean
+
When enabled, will cause the mark to clear itself whenever + the cursor enters its range. This is mostly useful for + text-replacement widgets that need to 'snap open' when the + user tries to edit them. The + "clear" event + fired on the range handle can be used to be notified when this + happens.
+
clearWhenEmpty: boolean
+
Determines whether the mark is automatically cleared when + it becomes empty. Default is true.
+
replacedWith: Element
+
Use a given node to display this range. Implies both + collapsed and atomic. The given DOM node must be an + inline element (as opposed to a block element).
+
handleMouseEvents: boolean
+
When replacedWith is given, this determines + whether the editor will capture mouse and drag events + occurring in this widget. Default is false—the events will be + left alone for the default browser handler, or specific + handlers on the widget, to capture.
+
readOnly: boolean
+
A read-only span can, as long as it is not cleared, not be + modified except by + calling setValue to reset + the whole document. Note: adding a read-only span + currently clears the undo history of the editor, because + existing undo events being partially nullified by read-only + spans would corrupt the history (in the current + implementation).
+
addToHistory: boolean
+
When set to true (default is false), adding this marker + will create an event in the undo history that can be + individually undone (clearing the marker).
+
startStyle: string
Can be used to specify + an extra CSS class to be applied to the leftmost span that + is part of the marker.
+
endStyle: string
Equivalent + to startStyle, but for the rightmost span.
+
css: string
+
A string of CSS to be applied to the covered text. For example "color: #fe3".
+
title: + string
When given, will give the nodes created + for this span a HTML title attribute with the + given value.
+
shared: boolean
When the + target document is linked to other + documents, you can set shared to true to make the + marker appear in all documents. By default, a marker appears + only in its target document.
+
+ The method will return an object that represents the marker + (with constructor CodeMirror.TextMarker), which + exposes three methods: + clear(), to remove the mark, + find(), which returns + a {from, to} object (both holding document + positions), indicating the current position of the marked range, + or undefined if the marker is no longer in the + document, and finally changed(), + which you can call if you've done something that might change + the size of the marker (for example changing the content of + a replacedWith + node), and want to cheaply update the display.
+ +
doc.setBookmark(pos: {line, ch}, ?options: object) → TextMarker
+
Inserts a bookmark, a handle that follows the text around it + as it is being edited, at the given position. A bookmark has two + methods find() and clear(). The first + returns the current position of the bookmark, if it is still in + the document, and the second explicitly removes the bookmark. + The options argument is optional. If given, the following + properties are recognized: +
+
widget: Element
Can be used to display a DOM + node at the current location of the bookmark (analogous to + the replacedWith + option to markText).
+
insertLeft: boolean
By default, text typed + when the cursor is on top of the bookmark will end up to the + right of the bookmark. Set this option to true to make it go + to the left instead.
+
shared: boolean
See + the corresponding option + to markText.
+
handleMouseEvents: boolean
+
As with markText, + this determines whether mouse events on the widget inserted + for this bookmark are handled by CodeMirror. The default is + false.
+
+ +
doc.findMarks(from: {line, ch}, to: {line, ch}) → array<TextMarker>
+
Returns an array of all the bookmarks and marked ranges + found between the given positions (non-inclusive).
+
doc.findMarksAt(pos: {line, ch}) → array<TextMarker>
+
Returns an array of all the bookmarks and marked ranges + present at the given position.
+
doc.getAllMarks() → array<TextMarker>
+
Returns an array containing all marked ranges in the document.
+
+ +

Widget, gutter, and decoration methods

+ +
+
doc.setGutterMarker(line: integer|LineHandle, gutterID: string, value: Element) → LineHandle
+
Sets the gutter marker for the given gutter (identified by + its CSS class, see + the gutters option) + to the given value. Value can be either null, to + clear the marker, or a DOM element, to set it. The DOM element + will be shown in the specified gutter next to the specified + line.
+ +
doc.clearGutter(gutterID: string)
+
Remove all gutter markers in + the gutter with the given ID.
+ +
doc.addLineClass(line: integer|LineHandle, where: string, class: string) → LineHandle
+
Set a CSS class name for the given line. line + can be a number or a line handle. where determines + to which element this class should be applied, can can be one + of "text" (the text element, which lies in front of + the selection), "background" (a background element + that will be behind the selection), "gutter" (the + line's gutter space), or "wrap" (the wrapper node + that wraps all of the line's elements, including gutter + elements). class should be the name of the class to + apply.
+ +
doc.removeLineClass(line: integer|LineHandle, where: string, class: string) → LineHandle
+
Remove a CSS class from a line. line can be a + line handle or number. where should be one + of "text", "background", + or "wrap" + (see addLineClass). class + can be left off to remove all classes for the specified node, or + be a string to remove only a specific class.
+ +
doc.lineInfo(line: integer|LineHandle) → object
+
Returns the line number, text content, and marker status of + the given line, which can be either a number or a line handle. + The returned object has the structure {line, handle, text, + gutterMarkers, textClass, bgClass, wrapClass, widgets}, + where gutterMarkers is an object mapping gutter IDs + to marker elements, and widgets is an array + of line widgets attached to this + line, and the various class properties refer to classes added + with addLineClass.
+ +
cm.addWidget(pos: {line, ch}, node: Element, scrollIntoView: boolean)
+
Puts node, which should be an absolutely + positioned DOM node, into the editor, positioned right below the + given {line, ch} position. + When scrollIntoView is true, the editor will ensure + that the entire node is visible (if possible). To remove the + widget again, simply use DOM methods (move it somewhere else, or + call removeChild on its parent).
+ +
doc.addLineWidget(line: integer|LineHandle, node: Element, ?options: object) → LineWidget
+
Adds a line widget, an element shown below a line, spanning + the whole of the editor's width, and moving the lines below it + downwards. line should be either an integer or a + line handle, and node should be a DOM node, which + will be displayed below the given line. options, + when given, should be an object that configures the behavior of + the widget. The following options are supported (all default to + false): +
+
coverGutter: boolean
+
Whether the widget should cover the gutter.
+
noHScroll: boolean
+
Whether the widget should stay fixed in the face of + horizontal scrolling.
+
above: boolean
+
Causes the widget to be placed above instead of below + the text of the line.
+
handleMouseEvents: boolean
+
Determines whether the editor will capture mouse and + drag events occurring in this widget. Default is false—the + events will be left alone for the default browser handler, + or specific handlers on the widget, to capture.
+
insertAt: integer
+
By default, the widget is added below other widgets for + the line. This option can be used to place it at a different + position (zero for the top, N to put it after the Nth other + widget). Note that this only has effect once, when the + widget is created. +
+ Note that the widget node will become a descendant of nodes with + CodeMirror-specific CSS classes, and those classes might in some + cases affect it. This method returns an object that represents + the widget placement. It'll have a line property + pointing at the line handle that it is associated with, and the following methods: +
+
clear()
Removes the widget.
+
changed()
Call + this if you made some change to the widget's DOM node that + might affect its height. It'll force CodeMirror to update + the height of the line that contains the widget.
+
+
+
+ +

Sizing, scrolling and positioning methods

+ +
+
cm.setSize(width: number|string, height: number|string)
+
Programmatically set the size of the editor (overriding the + applicable CSS + rules). width and height + can be either numbers (interpreted as pixels) or CSS units + ("100%", for example). You can + pass null for either of them to indicate that that + dimension should not be changed.
+ +
cm.scrollTo(x: number, y: number)
+
Scroll the editor to a given (pixel) position. Both + arguments may be left as null + or undefined to have no effect.
+
cm.getScrollInfo() → {left, top, width, height, clientWidth, clientHeight}
+
Get an {left, top, width, height, clientWidth, + clientHeight} object that represents the current scroll + position, the size of the scrollable area, and the size of the + visible area (minus scrollbars).
+
cm.scrollIntoView(what: {line, ch}|{left, top, right, bottom}|{from, to}|null, ?margin: number)
+
Scrolls the given position into view. what may + be null to scroll the cursor into view, + a {line, ch} position to scroll a character into + view, a {left, top, right, bottom} pixel range (in + editor-local coordinates), or a range {from, to} + containing either two character positions or two pixel squares. + The margin parameter is optional. When given, it + indicates the amount of vertical pixels around the given area + that should be made visible as well.
+ +
cm.cursorCoords(where: boolean|{line, ch}, mode: string) → {left, top, bottom}
+
Returns an {left, top, bottom} object + containing the coordinates of the cursor position. + If mode is "local", they will be + relative to the top-left corner of the editable document. If it + is "page" or not given, they are relative to the + top-left corner of the page. If mode + is "window", the coordinates are relative to the + top-left corner of the currently visible (scrolled) + window. where can be a boolean indicating whether + you want the start (true) or the end + (false) of the selection, or, if a {line, + ch} object is given, it specifies the precise position at + which you want to measure.
+
cm.charCoords(pos: {line, ch}, ?mode: string) → {left, right, top, bottom}
+
Returns the position and dimensions of an arbitrary + character. pos should be a {line, ch} + object. This differs from cursorCoords in that + it'll give the size of the whole character, rather than just the + position that the cursor would have when it would sit at that + position.
+
cm.coordsChar(object: {left, top}, ?mode: string) → {line, ch}
+
Given an {left, top} object (e.g. coordinates of a mouse event) returns + the {line, ch} position that corresponds to it. The + optional mode parameter determines relative to what + the coordinates are interpreted. It may + be "window", "page" (the default), + or "local".
+
cm.lineAtHeight(height: number, ?mode: string) → number
+
Computes the line at the given pixel + height. mode can be one of the same strings + that coordsChar + accepts.
+
cm.heightAtLine(line: integer|LineHandle, ?mode: string, ?includeWidgets: bool) → number
+
Computes the height of the top of a line, in the coordinate + system specified by mode + (see coordsChar), which + defaults to "page". When a line below the bottom of + the document is specified, the returned value is the bottom of + the last line in the document. By default, the position of the + actual text is returned. If `includeWidgets` is true and the + line has line widgets, the position above the first line widget + is returned.
+
cm.defaultTextHeight() → number
+
Returns the line height of the default font for the editor.
+
cm.defaultCharWidth() → number
+
Returns the pixel width of an 'x' in the default font for + the editor. (Note that for non-monospace fonts, this is mostly + useless, and even for monospace fonts, non-ascii characters + might have a different width).
+ +
cm.getViewport() → {from: number, to: number}
+
Returns a {from, to} object indicating the + start (inclusive) and end (exclusive) of the currently rendered + part of the document. In big documents, when most content is + scrolled out of view, CodeMirror will only render the visible + part, and a margin around it. See also + the viewportChange + event.
+ +
cm.refresh()
+
If your code does something to change the size of the editor + element (window resizes are already listened for), or unhides + it, you should probably follow up by calling this method to + ensure CodeMirror is still looking as intended. See also + the autorefresh addon.
+
+ +

Mode, state, and token-related methods

+ +

When writing language-aware functionality, it can often be + useful to hook into the knowledge that the CodeMirror language + mode has. See the section on modes for a + more detailed description of how these work.

+ +
+
doc.getMode() → object
+
Gets the (outer) mode object for the editor. Note that this + is distinct from getOption("mode"), which gives you + the mode specification, rather than the resolved, instantiated + mode object.
+ +
cm.getModeAt(pos: {line, ch}) → object
+
Gets the inner mode at a given position. This will return + the same as getMode for + simple modes, but will return an inner mode for nesting modes + (such as htmlmixed).
+ +
cm.getTokenAt(pos: {line, ch}, ?precise: boolean) → object
+
Retrieves information about the token the current mode found + before the given position (a {line, ch} object). The + returned object has the following properties: +
+
start
The character (on the given line) at which the token starts.
+
end
The character at which the token ends.
+
string
The token's string.
+
type
The token type the mode assigned + to the token, such as "keyword" + or "comment" (may also be null).
+
state
The mode's state at the end of this token.
+
+ If precise is true, the token will be guaranteed to be accurate based on recent edits. If false or + not specified, the token will use cached state information, which will be faster but might not be accurate if + edits were recently made and highlighting has not yet completed. +
+ +
cm.getLineTokens(line: integer, ?precise: boolean) → array<{start, end, string, type, state}>
+
This is similar + to getTokenAt, but + collects all tokens for a given line into an array. It is much + cheaper than repeatedly calling getTokenAt, which + re-parses the part of the line before the token for every call.
+ +
cm.getTokenTypeAt(pos: {line, ch}) → string
+
This is a (much) cheaper version + of getTokenAt useful for + when you just need the type of the token at a given position, + and no other information. Will return null for + unstyled tokens, and a string, potentially containing multiple + space-separated style names, otherwise.
+ +
cm.getHelpers(pos: {line, ch}, type: string) → array<helper>
+
Fetch the set of applicable helper values for the given + position. Helpers provide a way to look up functionality + appropriate for a mode. The type argument provides + the helper namespace (see + registerHelper), in + which the values will be looked up. When the mode itself has a + property that corresponds to the type, that + directly determines the keys that are used to look up the helper + values (it may be either a single string, or an array of + strings). Failing that, the mode's helperType + property and finally the mode's name are used.
+
For example, the JavaScript mode has a + property fold containing "brace". When + the brace-fold addon is loaded, that defines a + helper named brace in the fold + namespace. This is then used by + the foldcode addon to + figure out that it can use that folding function to fold + JavaScript code.
+
When any 'global' + helpers are defined for the given namespace, their predicates + are called on the current mode and editor, and all those that + declare they are applicable will also be added to the array that + is returned.
+ +
cm.getHelper(pos: {line, ch}, type: string) → helper
+
Returns the first applicable helper value. + See getHelpers.
+ +
cm.getStateAfter(?line: integer, ?precise: boolean) → object
+
Returns the mode's parser state, if any, at the end of the + given line number. If no line number is given, the state at the + end of the document is returned. This can be useful for storing + parsing errors in the state, or getting other kinds of + contextual information for a line. precise is defined + as in getTokenAt().
+
+ +

Miscellaneous methods

+ +
+
cm.operation(func: () → any) → any
+
CodeMirror internally buffers changes and only updates its + DOM structure after it has finished performing some operation. + If you need to perform a lot of operations on a CodeMirror + instance, you can call this method with a function argument. It + will call the function, buffering up all changes, and only doing + the expensive update after the function returns. This can be a + lot faster. The return value from this method will be the return + value of your function.
+ +
cm.startOperation()
+
cm.endOperation()
+
In normal circumstances, use the above operation + method. But if you want to buffer operations happening asynchronously, + or that can't all be wrapped in a callback function, you can + call startOperation to tell CodeMirror to start + buffering changes, and endOperation to actually + render all the updates. Be careful: if you use this + API and forget to call endOperation, the editor will + just never update.
+ +
cm.indentLine(line: integer, ?dir: string|integer)
+
Adjust the indentation of the given line. The second + argument (which defaults to "smart") may be one of: +
+
"prev"
+
Base indentation on the indentation of the previous line.
+
"smart"
+
Use the mode's smart indentation if available, behave + like "prev" otherwise.
+
"add"
+
Increase the indentation of the line by + one indent unit.
+
"subtract"
+
Reduce the indentation of the line.
+
<integer>
+
Add (positive number) or reduce (negative number) the + indentation by the given amount of spaces.
+
+ +
cm.toggleOverwrite(?value: boolean)
+
Switches between overwrite and normal insert mode (when not + given an argument), or sets the overwrite mode to a specific + state (when given an argument).
+ +
cm.isReadOnly() → boolean
+
Tells you whether the editor's content can be edited by the + user.
+ +
doc.lineSeparator()
+
Returns the preferred line separator string for this + document, as per the option + by the same name. When that option is null, the + string "\n" is returned.
+ +
cm.execCommand(name: string)
+
Runs the command with the given name on the editor.
+ +
doc.posFromIndex(index: integer) → {line, ch}
+
Calculates and returns a {line, ch} object for a + zero-based index who's value is relative to the start of the + editor's text. If the index is out of range of the text then + the returned object is clipped to start or end of the text + respectively.
+
doc.indexFromPos(object: {line, ch}) → integer
+
The reverse of posFromIndex.
+ +
cm.focus()
+
Give the editor focus.
+ +
cm.getInputField() → Element
+
Returns the input field for the editor. Will be a textarea + or an editable div, depending on the value of + the inputStyle + option.
+
cm.getWrapperElement() → Element
+
Returns the DOM node that represents the editor, and + controls its size. Remove this from your tree to delete an + editor instance.
+
cm.getScrollerElement() → Element
+
Returns the DOM node that is responsible for the scrolling + of the editor.
+
cm.getGutterElement() → Element
+
Fetches the DOM node that contains the editor gutters.
+
+ +

Static properties

+

The CodeMirror object itself provides + several useful properties.

+ +
+
CodeMirror.version: string
+
It contains a string that indicates the version of the + library. This is a triple of + integers "major.minor.patch", + where patch is zero for releases, and something + else (usually one) for dev snapshots.
+ +
CodeMirror.fromTextArea(textArea: TextAreaElement, ?config: object)
+
This method provides another way to initialize an editor. It + takes a textarea DOM node as first argument and an optional + configuration object as second. It will replace the textarea + with a CodeMirror instance, and wire up the form of that + textarea (if any) to make sure the editor contents are put into + the textarea when the form is submitted. The text in the + textarea will provide the content for the editor. A CodeMirror + instance created this way has three additional methods: +
+
cm.save()
+
Copy the content of the editor into the textarea.
+ +
cm.toTextArea()
+
Remove the editor, and restore the original textarea (with + the editor's current content). If you dynamically create and + destroy editors made with `fromTextArea`, without destroying + the form they are part of, you should make sure to call + `toTextArea` to remove the editor, or its `"submit"` handler + on the form will cause a memory leak.
+ +
cm.getTextArea() → TextAreaElement
+
Returns the textarea that the instance was based on.
+
+
+ +
CodeMirror.defaults: object
+
An object containing default values for + all options. You can assign to its + properties to modify defaults (though this won't affect editors + that have already been created).
+ +
CodeMirror.defineExtension(name: string, value: any)
+
If you want to define extra methods in terms of the + CodeMirror API, it is possible to + use defineExtension. This will cause the given + value (usually a method) to be added to all CodeMirror instances + created from then on.
+ +
CodeMirror.defineDocExtension(name: string, value: any)
+
Like defineExtension, + but the method will be added to the interface + for Doc objects instead.
+ +
CodeMirror.defineOption(name: string, + default: any, updateFunc: function)
+
Similarly, defineOption can be used to define new options for + CodeMirror. The updateFunc will be called with the + editor instance and the new value when an editor is initialized, + and whenever the option is modified + through setOption.
+ +
CodeMirror.defineInitHook(func: function)
+
If your extension just needs to run some + code whenever a CodeMirror instance is initialized, + use CodeMirror.defineInitHook. Give it a function as + its only argument, and from then on, that function will be called + (with the instance as argument) whenever a new CodeMirror instance + is initialized.
+ +
CodeMirror.registerHelper(type: string, name: string, value: helper)
+
Registers a helper value with the given name in + the given namespace (type). This is used to define + functionality that may be looked up by mode. Will create (if it + doesn't already exist) a property on the CodeMirror + object for the given type, pointing to an object + that maps names to values. I.e. after + doing CodeMirror.registerHelper("hint", "foo", + myFoo), the value CodeMirror.hint.foo will + point to myFoo.
+ +
CodeMirror.registerGlobalHelper(type: string, name: string, predicate: fn(mode, CodeMirror), value: helper)
+
Acts + like registerHelper, + but also registers this helper as 'global', meaning that it will + be included by getHelpers + whenever the given predicate returns true when + called with the local mode and editor.
+ +
CodeMirror.Pos(line: integer, ?ch: integer, ?sticky: string)
+
A constructor for the objects that are used to represent + positions in editor documents. sticky defaults to + null, but can be set to "before" + or "after" to make the position explicitly + associate with the character before or after it.
+ +
CodeMirror.changeEnd(change: object) → {line, ch}
+
Utility function that computes an end position from a change + (an object with from, to, + and text properties, as passed to + various event handlers). The + returned position will be the end of the changed + range, after the change is applied.
+ +
CodeMirror.countColumn(line: string, index: number, tabSize: number) → number
+
Find the column position at a given string index using a given tabsize.
+
+
+ +
+

Addons

+ +

The addon directory in the distribution contains a + number of reusable components that implement extra editor + functionality (on top of extension functions + like defineOption, defineExtension, + and registerHelper). In + brief, they are:

+ +
+
dialog/dialog.js
+
Provides a very simple way to query users for text input. + Adds the openDialog(template, callback, options) → + closeFunction method to CodeMirror instances, + which can be called with an HTML fragment or a detached DOM + node that provides the prompt (should include an input + or button tag), and a callback function that is called + when the user presses enter. It returns a function closeFunction + which, if called, will close the dialog immediately. + openDialog takes the following options: +
+
closeOnEnter: bool
+
If true, the dialog will be closed when the user presses + enter in the input. Defaults to true.
+
closeOnBlur: bool
+
Determines whether the dialog is closed when it loses focus. Defaults to true.
+
onKeyDown: fn(event: KeyboardEvent, value: string, close: fn()) → bool
+
An event handler that will be called whenever keydown fires in the + dialog's input. If your callback returns true, + the dialog will not do any further processing of the event.
+
onKeyUp: fn(event: KeyboardEvent, value: string, close: fn()) → bool
+
Same as onKeyDown but for the + keyup event.
+
onInput: fn(event: InputEvent, value: string, close: fn()) → bool
+
Same as onKeyDown but for the + input event.
+
onClose: fn(instance):
+
A callback that will be called after the dialog has been closed and + removed from the DOM. No return value.
+
+ +

Also adds an openNotification(template, options) → + closeFunction function that simply shows an HTML + fragment as a notification at the top of the editor. It takes a + single option: duration, the amount of time after + which the notification will be automatically closed. If + duration is zero, the dialog will not be closed automatically.

+ +

Depends on addon/dialog/dialog.css.

+ +
search/searchcursor.js
+
Adds the getSearchCursor(query, start, options) → + cursor method to CodeMirror instances, which can be used + to implement search/replace functionality. query + can be a regular expression or a string. start + provides the starting position of the search. It can be + a {line, ch} object, or can be left off to default + to the start of the document. options is an + optional object, which can contain the property `caseFold: + false` to disable case folding when mathing a string, or the + property `multiline: disable` to disable multi-line matching for + regular expressions (which may help performance). A search + cursor has the following methods: +
+
findNext() → boolean
+
findPrevious() → boolean
+
Search forward or backward from the current position. + The return value indicates whether a match was found. If + matching a regular expression, the return value will be the + array returned by the match method, in case you + want to extract matched groups.
+
from() → {line, ch}
+
to() → {line, ch}
+
These are only valid when the last call + to findNext or findPrevious did + not return false. They will return {line, ch} + objects pointing at the start and end of the match.
+
replace(text: string, ?origin: string)
+
Replaces the currently found match with the given text + and adjusts the cursor position to reflect the + replacement.
+
+ + +
Implements the search commands. CodeMirror has keys bound to + these by default, but will not do anything with them unless an + implementation is provided. Depends + on searchcursor.js, and will make use + of openDialog when + available to make prompting for search queries less ugly.
+ +
search/jump-to-line.js
+
Implements a jumpToLine command and binding Alt-G to it. + Accepts linenumber, +/-linenumber, line:char, + scroll% and :linenumber formats. + This will make use of openDialog + when available to make prompting for line number neater.
+ +
search/matchesonscrollbar.js
+
Adds a showMatchesOnScrollbar method to editor + instances, which should be given a query (string or regular + expression), optionally a case-fold flag (only applicable for + strings), and optionally a class name (defaults + to CodeMirror-search-match) as arguments. When + called, matches of the given query will be displayed on the + editor's vertical scrollbar. The method returns an object with + a clear method that can be called to remove the + matches. Depends on + the annotatescrollbar + addon, and + the matchesonscrollbar.css + file provides a default (transparent yellowish) definition of + the CSS class applied to the matches. Note that the matches are + only perfectly aligned if your scrollbar does not have buttons + at the top and bottom. You can use + the simplescrollbar + addon to make sure of this. If this addon is loaded, + the search addon will + automatically use it.
+ +
edit/matchbrackets.js
+
Defines an option matchBrackets which, when set + to true or an options object, causes matching brackets to be + highlighted whenever the cursor is next to them. It also adds a + method matchBrackets that forces this to happen + once, and a method findMatchingBracket that can be + used to run the bracket-finding algorithm that this uses + internally. It takes a start position and an optional config + object. By default, it will find the match to a matchable + character either before or after the cursor (preferring the one + before), but you can control its behavior with these options: +
+
afterCursor
+
Only use the character after the start position, never the one before it.
+
strict
+
Causes only matches where both brackets are at the same side of the start position to be considered.
+
maxScanLines
+
Stop after scanning this amount of lines without a successful match. Defaults to 1000.
+
maxScanLineLength
+
Ignore lines longer than this. Defaults to 10000.
+
+ +
edit/closebrackets.js
+
Defines an option autoCloseBrackets that will + auto-close brackets and quotes when typed. By default, it'll + auto-close ()[]{}''"", but you can pass it a string + similar to that (containing pairs of matching characters), or an + object with pairs and + optionally explode properties to customize + it. explode should be a similar string that gives + the pairs of characters that, when enter is pressed between + them, should have the second character also moved to its own + line. By default, if the active mode has + a closeBrackets property, that overrides the + configuration given in the option. But you can add + an override property with a truthy value to + override mode-specific + configuration. Demo + here.
+ +
edit/matchtags.js
+
Defines an option matchTags that, when enabled, + will cause the tags around the cursor to be highlighted (using + the CodeMirror-matchingtag class). Also + defines + a command toMatchingTag, + which you can bind a key to in order to jump to the tag matching + the one under the cursor. Depends on + the addon/fold/xml-fold.js + addon. Demo here.
+ +
edit/trailingspace.js
+
Adds an option showTrailingSpace which, when + enabled, adds the CSS class cm-trailingspace to + stretches of whitespace at the end of lines. + The demo has a nice + squiggly underline style for this class.
+ +
edit/closetag.js
+
Defines an autoCloseTags option that will + auto-close XML tags when '>' or '/' + is typed, and + a closeTag command that + closes the nearest open tag. Depends on + the fold/xml-fold.js addon. See + the demo.
+ +
edit/continuelist.js
+
Markdown specific. Defines + a "newlineAndIndentContinueMarkdownList" command + that can be bound to enter to automatically + insert the leading characters for continuing a list. See + the Markdown mode + demo.
+ +
comment/comment.js
+
Addon for commenting and uncommenting code. Adds four + methods to CodeMirror instances: +
+
toggleComment(from: {line, ch}, to: {line, ch}, ?options: object)
+
Tries to uncomment the current selection, and if that + fails, line-comments it.
+
lineComment(from: {line, ch}, to: {line, ch}, ?options: object)
+
Set the lines in the given range to be line comments. Will + fall back to blockComment when no line comment + style is defined for the mode.
+
blockComment(from: {line, ch}, to: {line, ch}, ?options: object)
+
Wrap the code in the given range in a block comment. Will + fall back to lineComment when no block comment + style is defined for the mode.
+
uncomment(from: {line, ch}, to: {line, ch}, ?options: object) → boolean
+
Try to uncomment the given range. + Returns true if a comment range was found and + removed, false otherwise.
+
+ The options object accepted by these methods may + have the following properties: +
+
blockCommentStart, blockCommentEnd, blockCommentLead, lineComment: string
+
Override the comment string + properties of the mode with custom comment strings.
+
padding: string
+
A string that will be inserted after opening and leading + markers, and before closing comment markers. Defaults to a + single space.
+
commentBlankLines: boolean
+
Whether, when adding line comments, to also comment lines + that contain only whitespace.
+
indent: boolean
+
When adding line comments and this is turned on, it will + align the comment block to the current indentation of the + first line of the block.
+
fullLines: boolean
+
When block commenting, this controls whether the whole + lines are indented, or only the precise range that is given. + Defaults to true.
+
+ The addon also defines + a toggleComment command, + which is a shorthand command for calling + toggleComment with no options.
+ +
fold/foldcode.js
+
Helps with code folding. Adds a foldCode method + to editor instances, which will try to do a code fold starting + at the given line, or unfold the fold that is already present. + The method takes as first argument the position that should be + folded (may be a line number or + a Pos), and as second optional + argument either a range-finder function, or an options object, + supporting the following properties: +
+
rangeFinder: fn(CodeMirror, Pos)
+
The function that is used to find + foldable ranges. If this is not directly passed, it will + default to CodeMirror.fold.auto, which + uses getHelpers with + a "fold" type to find folding functions + appropriate for the local mode. There are files in + the addon/fold/ + directory providing CodeMirror.fold.brace, which + finds blocks in brace languages (JavaScript, C, Java, + etc), CodeMirror.fold.indent, for languages where + indentation determines block structure (Python, Haskell), + and CodeMirror.fold.xml, for XML-style languages, + and CodeMirror.fold.comment, for folding comment + blocks.
+
widget: string|Element
+
The widget to show for folded ranges. Can be either a + string, in which case it'll become a span with + class CodeMirror-foldmarker, or a DOM node.
+
scanUp: boolean
+
When true (default is false), the addon will try to find + foldable ranges on the lines above the current one if there + isn't an eligible one on the given line.
+
minFoldSize: integer
+
The minimum amount of lines that a fold should span to be + accepted. Defaults to 0, which also allows single-line + folds.
+
+ See the demo for an + example.
+ +
fold/foldgutter.js
+
Provides an option foldGutter, which can be + used to create a gutter with markers indicating the blocks that + can be folded. Create a gutter using + the gutters option, + giving it the class CodeMirror-foldgutter or + something else if you configure the addon to use a different + class, and this addon will show markers next to folded and + foldable blocks, and handle clicks in this gutter. Note that + CSS styles should be applied to make the gutter, and the fold + markers within it, visible. A default set of CSS styles are + available in: + + addon/fold/foldgutter.css + . + The option + can be either set to true, or an object containing + the following optional option fields: +
+
gutter: string
+
The CSS class of the gutter. Defaults + to "CodeMirror-foldgutter". You will have to + style this yourself to give it a width (and possibly a + background). See the default gutter style rules above.
+
indicatorOpen: string | Element
+
A CSS class or DOM element to be used as the marker for + open, foldable blocks. Defaults + to "CodeMirror-foldgutter-open".
+
indicatorFolded: string | Element
+
A CSS class or DOM element to be used as the marker for + folded blocks. Defaults to "CodeMirror-foldgutter-folded".
+
rangeFinder: fn(CodeMirror, Pos)
+
The range-finder function to use when determining whether + something can be folded. When not + given, CodeMirror.fold.auto + will be used as default.
+
+ The foldOptions editor option can be set to an + object to provide an editor-wide default configuration. + Demo here.
+ +
runmode/runmode.js
+
Can be used to run a CodeMirror mode over text without + actually opening an editor instance. + See the demo for an example. + There are alternate versions of the file available for + running stand-alone + (without including all of CodeMirror) and + for running under + node.js (see bin/source-highlight for an example of using the latter).
+ +
runmode/colorize.js
+
Provides a convenient way to syntax-highlight code snippets + in a webpage. Depends on + the runmode addon (or + its standalone variant). Provides + a CodeMirror.colorize function that can be called + with an array (or other array-ish collection) of DOM nodes that + represent the code snippets. By default, it'll get + all pre tags. Will read the data-lang + attribute of these nodes to figure out their language, and + syntax-color their content using the relevant CodeMirror mode + (you'll have to load the scripts for the relevant modes + yourself). A second argument may be provided to give a default + mode, used when no language attribute is found for a node. Used + in this manual to highlight example code.
+ +
mode/overlay.js
+
Mode combinator that can be used to extend a mode with an + 'overlay' — a secondary mode is run over the stream, along with + the base mode, and can color specific pieces of text without + interfering with the base mode. + Defines CodeMirror.overlayMode, which is used to + create such a mode. See this + demo for a detailed example.
+ +
mode/multiplex.js
+
Mode combinator that can be used to easily 'multiplex' + between several modes. + Defines CodeMirror.multiplexingMode which, when + given as first argument a mode object, and as other arguments + any number of {open, close, mode [, delimStyle, innerStyle, parseDelimiters]} + objects, will return a mode object that starts parsing using the + mode passed as first argument, but will switch to another mode + as soon as it encounters a string that occurs in one of + the open fields of the passed objects. When in a + sub-mode, it will go back to the top mode again when + the close string is encountered. + Pass "\n" for open or close + if you want to switch on a blank line. +
  • When delimStyle is specified, it will be the token + style returned for the delimiter tokens (as well as + [delimStyle]-open on the opening token and + [delimStyle]-close on the closing token).
  • +
  • When innerStyle is specified, it will be the token + style added for each inner mode token.
  • +
  • When parseDelimiters is true, the content of + the delimiters will also be passed to the inner mode. + (And delimStyle is ignored.)
The outer + mode will not see the content between the delimiters. + See this demo for an + example.
+ +
hint/show-hint.js
+
Provides a framework for showing autocompletion hints. + Defines editor.showHint, which takes an optional + options object, and pops up a widget that allows the user to + select a completion. Finding hints is done with a hinting + functions (the hint option), which is a function + that take an editor instance and options object, and return + a {list, from, to} object, where list + is an array of strings or objects (the completions), + and from and to give the start and end + of the token that is being completed as {line, ch} + objects. An optional selectedHint property (an + integer) can be added to the completion object to control the + initially selected hint.
+
If no hinting function is given, the addon will + use CodeMirror.hint.auto, which + calls getHelpers with + the "hint" type to find applicable hinting + functions, and tries them one by one. If that fails, it looks + for a "hintWords" helper to fetch a list of + completable words for the mode, and + uses CodeMirror.hint.fromList to complete from + those.
+
When completions aren't simple strings, they should be + objects with the following properties: +
+
text: string
+
The completion text. This is the only required + property.
+
displayText: string
+
The text that should be displayed in the menu.
+
className: string
+
A CSS class name to apply to the completion's line in the + menu.
+
render: fn(Element, self, data)
+
A method used to create the DOM structure for showing the + completion by appending it to its first argument.
+
hint: fn(CodeMirror, self, data)
+
A method used to actually apply the completion, instead of + the default behavior.
+
from: {line, ch}
+
Optional from position that will be used by pick() instead + of the global one passed with the full list of completions.
+
to: {line, ch}
+
Optional to position that will be used by pick() instead + of the global one passed with the full list of completions.
+
+ +
The plugin understands the following options, which may be + either passed directly in the argument to showHint, + or provided by setting an hintOptions editor + option to an object (the former takes precedence). The options + object will also be passed along to the hinting function, which + may understand additional options. +
+
hint: function
+
A hinting function, as specified above. It is possible to + set the async property on a hinting function to + true, in which case it will be called with + arguments (cm, callback, ?options), and the + completion interface will only be popped up when the hinting + function calls the callback, passing it the object holding the + completions. + The hinting function can also return a promise, and the completion + interface will only be popped when the promise resolves. + By default, hinting only works when there is no + selection. You can give a hinting function + a supportsSelection property with a truthy value + to indicate that it supports selections.
+
completeSingle: boolean
+
Determines whether, when only a single completion is + available, it is completed without showing the dialog. + Defaults to true.
+
alignWithWord: boolean
+
Whether the pop-up should be horizontally aligned with the + start of the word (true, default), or with the cursor (false).
+
closeOnUnfocus: boolean
+
When enabled (which is the default), the pop-up will close + when the editor is unfocused.
+
customKeys: keymap
+
Allows you to provide a custom key map of keys to be active + when the pop-up is active. The handlers will be called with an + extra argument, a handle to the completion menu, which + has moveFocus(n), setFocus(n), pick(), + and close() methods (see the source for details), + that can be used to change the focused element, pick the + current element or close the menu. Additionally menuSize() + can give you access to the size of the current dropdown menu, + length give you the number of available completions, and + data give you full access to the completion returned by the + hinting function.
+
extraKeys: keymap
+
Like customKeys above, but the bindings will + be added to the set of default bindings, instead of replacing + them.
+
+ The following events will be fired on the completions object + during completion: +
+
"shown" ()
+
Fired when the pop-up is shown.
+
"select" (completion, Element)
+
Fired when a completion is selected. Passed the completion + value (string or object) and the DOM node that represents it + in the menu.
+
"pick" (completion)
+
Fired when a completion is picked. Passed the completion value + (string or object).
+
"close" ()
+
Fired when the completion is finished.
+
+ This addon depends on styles + from addon/hint/show-hint.css. Check + out the demo for an + example.
+ +
hint/javascript-hint.js
+
Defines a simple hinting function for JavaScript + (CodeMirror.hint.javascript) and CoffeeScript + (CodeMirror.hint.coffeescript) code. This will + simply use the JavaScript environment that the editor runs in as + a source of information about objects and their properties.
+ +
hint/xml-hint.js
+
Defines CodeMirror.hint.xml, which produces + hints for XML tagnames, attribute names, and attribute values, + guided by a schemaInfo option (a property of the + second argument passed to the hinting function, or the third + argument passed to CodeMirror.showHint).
The + schema info should be an object mapping tag names to information + about these tags, with optionally a "!top" property + containing a list of the names of valid top-level tags. The + values of the properties should be objects with optional + properties children (an array of valid child + element names, omit to simply allow all tags to appear) + and attrs (an object mapping attribute names + to null for free-form attributes, and an array of + valid values for restricted + attributes). Demo + here.
+ +
hint/html-hint.js
+
Provides schema info to + the xml-hint addon for HTML + documents. Defines a schema + object CodeMirror.htmlSchema that you can pass to + as a schemaInfo option, and + a CodeMirror.hint.html hinting function that + automatically calls CodeMirror.hint.xml with this + schema data. See + the demo.
+ +
hint/css-hint.js
+
A hinting function for CSS, SCSS, or LESS code. + Defines CodeMirror.hint.css.
+ +
hint/anyword-hint.js
+
A very simple hinting function + (CodeMirror.hint.anyword) that simply looks for + words in the nearby code and completes to those. Takes two + optional options, word, a regular expression that + matches words (sequences of one or more character), + and range, which defines how many lines the addon + should scan when completing (defaults to 500).
+ +
hint/sql-hint.js
+
A simple SQL hinter. Defines CodeMirror.hint.sql. + Takes two optional options, tables, a object with + table names as keys and array of respective column names as values, + and defaultTable, a string corresponding to a + table name in tables for autocompletion.
+ +
search/match-highlighter.js
+
Adds a highlightSelectionMatches option that + can be enabled to highlight all instances of a currently + selected word. Can be set either to true or to an object + containing the following options: minChars, for the + minimum amount of selected characters that triggers a highlight + (default 2), style, for the style to be used to + highlight the matches (default "matchhighlight", + which will correspond to CSS + class cm-matchhighlight), trim, which + controls whether whitespace is trimmed from the selection, + and showToken which can be set to true + or to a regexp matching the characters that make up a word. When + enabled, it causes the current word to be highlighted when + nothing is selected (defaults to off). + Demo here.
+ +
lint/lint.js
+
Defines an interface component for showing linting warnings, + with pluggable warning sources + (see html-lint.js, + json-lint.js, + javascript-lint.js, + coffeescript-lint.js, + and css-lint.js + in the same directory). Defines a lint option that + can be set to an annotation source (for + example CodeMirror.lint.javascript), to an options + object (in which case the getAnnotations field is + used as annotation source), or simply to true. When + no annotation source is + specified, getHelper with + type "lint" is used to find an annotation function. + An annotation source function should, when given a document + string, an options object, and an editor instance, return an + array of {message, severity, from, to} objects + representing problems. When the function has + an async property with a truthy value, it will be + called with an additional second argument, which is a callback + to pass the array to. + The linting function can also return a promise, in that case the linter + will only be executed when the promise resolves. + By default, the linter will run (debounced) whenever the document is changed. + You can pass a lintOnChange: false option to disable that. + Depends on addon/lint/lint.css. A demo can be + found here.
+ +
selection/mark-selection.js
+
Causes the selected text to be marked with the CSS class + CodeMirror-selectedtext when the styleSelectedText option + is enabled. Useful to change the colour of the selection (in addition to the background), + like in this demo.
+ +
selection/active-line.js
+
Defines a styleActiveLine option that, when + enabled, gives the wrapper of the line that contains the cursor + the class CodeMirror-activeline, adds a background + with the class CodeMirror-activeline-background, + and adds the class CodeMirror-activeline-gutter to + the line's gutter space is enabled. The option's value may be a + boolean or an object specifying the following options: +
+
nonEmpty: bool
+
Controls whether single-line selections, or just cursor + selections, are styled. Defaults to false (only cursor + selections).
+
+ See the demo.
+ +
selection/selection-pointer.js
+
Defines a selectionPointer option which you can + use to control the mouse cursor appearance when hovering over + the selection. It can be set to a string, + like "pointer", or to true, in which case + the "default" (arrow) cursor will be used. You can + see a demo here.
+ +
mode/loadmode.js
+
Defines a CodeMirror.requireMode(modename, + callback) function that will try to load a given mode and + call the callback when it succeeded. You'll have to + set CodeMirror.modeURL to a string that mode paths + can be constructed from, for + example "mode/%N/%N.js"—the %N's will + be replaced with the mode name. Also + defines CodeMirror.autoLoadMode(instance, mode), + which will ensure the given mode is loaded and cause the given + editor instance to refresh its mode when the loading + succeeded. See the demo.
+ +
mode/meta.js
+
Provides meta-information about all the modes in the + distribution in a single file. + Defines CodeMirror.modeInfo, an array of objects + with {name, mime, mode} properties, + where name is the human-readable + name, mime the MIME type, and mode the + name of the mode file that defines this MIME. There are optional + properties mimes, which holds an array of MIME + types for modes with multiple MIMEs associated, + and ext, which holds an array of file extensions + associated with this mode. Four convenience + functions, CodeMirror.findModeByMIME, + CodeMirror.findModeByExtension, + CodeMirror.findModeByFileName + and CodeMirror.findModeByName are provided, which + return such an object given a MIME, extension, file name or mode name + string. Note that, for historical reasons, this file resides in the + top-level mode directory, not + under addon. Demo.
+ +
comment/continuecomment.js
+
Adds a continueComments option, which sets whether the + editor will make the next line continue a comment when you press Enter + inside a comment block. Can be set to a boolean to enable/disable this + functionality. Set to a string, it will continue comments using a custom + shortcut. Set to an object, it will use the key property for + a custom shortcut and the boolean continueLineComment + property to determine whether single-line comments should be continued + (defaulting to true).
+ +
display/placeholder.js
+
Adds a placeholder option that can be used to + make content appear in the editor when it is empty and not + focused. It can hold either a string or a DOM node. Also gives + the editor a CodeMirror-empty CSS class whenever it + doesn't contain any text. + See the demo.
+ +
display/fullscreen.js
+
Defines an option fullScreen that, when set + to true, will make the editor full-screen (as in, + taking up the whole browser window). Depends + on fullscreen.css. Demo + here.
+ +
display/autorefresh.js
+
This addon can be useful when initializing an editor in a + hidden DOM node, in cases where it is difficult to + call refresh when the editor + becomes visible. It defines an option autoRefresh + which you can set to true to ensure that, if the editor wasn't + visible on initialization, it will be refreshed the first time + it becomes visible. This is done by polling every 250 + milliseconds (you can pass a value like {delay: + 500} as the option value to configure this). Note that + this addon will only refresh the editor once when it + first becomes visible, and won't take care of further restyling + and resizing.
+ +
scroll/simplescrollbars.js
+
Defines two additional scrollbar + models, "simple" and "overlay" + (see demo) that can + be selected with + the scrollbarStyle + option. Depends + on simplescrollbars.css, + which can be further overridden to style your own + scrollbars.
+ +
scroll/annotatescrollbar.js
+
Provides functionality for showing markers on the scrollbar + to call out certain parts of the document. Adds a + method annotateScrollbar to editor instances that + can be called, with a CSS class name as argument, to create a + set of annotations. The method returns an object + whose update method can be called with a sorted array + of {from: Pos, to: Pos} objects marking the ranges + to be highlighted. To detach the annotations, call the + object's clear method.
+ +
display/rulers.js
+
Adds a rulers option, which can be used to show + one or more vertical rulers in the editor. The option, if + defined, should be given an array of {column [, className, + color, lineStyle, width]} objects or numbers (which + indicate a column). The ruler will be displayed at the column + indicated by the number or the column property. + The className property can be used to assign a + custom style to a ruler. Demo + here.
+ +
display/panel.js
+
Defines an addPanel method for CodeMirror + instances, which places a DOM node above or below an editor, and + shrinks the editor to make room for the node. The method takes + as first argument as DOM node, and as second an optional options + object. The Panel object returned by this method + has a clear method that is used to remove the + panel, and a changed method that can be used to + notify the addon when the size of the panel's DOM node has + changed.
+ The method accepts the following options: +
+
position: string
+
Controls the position of the newly added panel. The + following values are recognized: +
+
top (default)
+
Adds the panel at the very top.
+
after-top
+
Adds the panel at the bottom of the top panels.
+
bottom
+
Adds the panel at the very bottom.
+
before-bottom
+
Adds the panel at the top of the bottom panels.
+
+
+
before: Panel
+
The new panel will be added before the given panel.
+
after: Panel
+
The new panel will be added after the given panel.
+
replace: Panel
+
The new panel will replace the given panel.
+
stable: bool
+
Whether to scroll the editor to keep the text's vertical + position stable, when adding a panel above it. Defaults to false.
+
+ When using the after, before or replace options, + if the panel doesn't exists or has been removed, + the value of the position option will be used as a fallback. +
+ A demo of the addon is available here. +
+ +
wrap/hardwrap.js
+
Addon to perform hard line wrapping/breaking for paragraphs + of text. Adds these methods to editor instances: +
+
wrapParagraph(?pos: {line, ch}, ?options: object)
+
Wraps the paragraph at the given position. + If pos is not given, it defaults to the cursor + position.
+
wrapRange(from: {line, ch}, to: {line, ch}, ?options: object)
+
Wraps the given range as one big paragraph.
+
wrapParagraphsInRange(from: {line, ch}, to: {line, ch}, ?options: object)
+
Wraps the paragraphs in (and overlapping with) the + given range individually.
+
+ The following options are recognized: +
+
paragraphStart, paragraphEnd: RegExp
+
Blank lines are always considered paragraph boundaries. + These options can be used to specify a pattern that causes + lines to be considered the start or end of a paragraph.
+
column: number
+
The column to wrap at. Defaults to 80.
+
wrapOn: RegExp
+
A regular expression that matches only those + two-character strings that allow wrapping. By default, the + addon wraps on whitespace and after dash characters.
+
killTrailingSpace: boolean
+
Whether trailing space caused by wrapping should be + preserved, or deleted. Defaults to true.
+
+ A demo of the addon is available here. +
+ +
merge/merge.js
+
Implements an interface for merging changes, using either a + 2-way or a 3-way view. The CodeMirror.MergeView + constructor takes arguments similar to + the CodeMirror + constructor, first a node to append the interface to, and then + an options object. Options are passed through to the editors + inside the view. These extra options are recognized: +
+
origLeft and origRight: string
+
If given these provide original versions of the + document, which will be shown to the left and right of the + editor in non-editable CodeMirror instances. The merge + interface will highlight changes between the editable + document and the original(s). To create a 2-way (as opposed + to 3-way) merge view, provide only one of them.
+
revertButtons: boolean
+
Determines whether buttons that allow the user to revert + changes are shown. Defaults to true.
+
revertChunk: fn(mv: MergeView, from: CodeMirror, fromStart: Pos, fromEnd: Pos, to: CodeMirror, toStart: Pos, toEnd: Pos)
+
Can be used to define custom behavior when the user + reverts a changed chunk.
+
connect: string
+
Sets the style used to connect changed chunks of code. + By default, connectors are drawn. When this is set + to "align", the smaller chunk is padded to + align with the bigger chunk instead.
+
collapseIdentical: boolean|number
+
When true (default is false), stretches of unchanged + text will be collapsed. When a number is given, this + indicates the amount of lines to leave visible around such + stretches (which defaults to 2).
+
allowEditingOriginals: boolean
+
Determines whether the original editor allows editing. + Defaults to false.
+
showDifferences: boolean
+
When true (the default), changed pieces of text are + highlighted.
+
chunkClassLocation: string|Array
+
By default the chunk highlights are added + using addLineClass + with "background". Override this to customize it to be any + valid `where` parameter or an Array of valid `where` + parameters.
+
+ The addon also defines commands "goNextDiff" + and "goPrevDiff" to quickly jump to the next + changed chunk. Demo + here.
+ +
tern/tern.js
+
Provides integration with + the Tern JavaScript analysis + engine, for completion, definition finding, and minor + refactoring help. See the demo + for a very simple integration. For more involved scenarios, see + the comments at the top of + the addon and the + implementation of the + (multi-file) demonstration + on the Tern website.
+
+
+ +
+

Writing CodeMirror Modes

+ +

Modes typically consist of a single JavaScript file. This file + defines, in the simplest case, a lexer (tokenizer) for your + language—a function that takes a character stream as input, + advances it past a token, and returns a style for that token. More + advanced modes can also handle indentation for the language.

+ +

This section describes the low-level mode interface. Many modes + are written directly against this, since it offers a lot of + control, but for a quick mode definition, you might want to use + the simple mode addon.

+ +

The mode script should + call CodeMirror.defineMode to + register itself with CodeMirror. This function takes two + arguments. The first should be the name of the mode, for which you + should use a lowercase string, preferably one that is also the + name of the files that define the mode (i.e. "xml" is + defined in xml.js). The second argument should be a + function that, given a CodeMirror configuration object (the thing + passed to the CodeMirror function) and an optional + mode configuration object (as in + the mode option), returns + a mode object.

+ +

Typically, you should use this second argument + to defineMode as your module scope function (modes + should not leak anything into the global scope!), i.e. write your + whole mode inside this function.

+ +

The main responsibility of a mode script is parsing + the content of the editor. Depending on the language and the + amount of functionality desired, this can be done in really easy + or extremely complicated ways. Some parsers can be stateless, + meaning that they look at one element (token) of the code + at a time, with no memory of what came before. Most, however, will + need to remember something. This is done by using a state + object, which is an object that is always passed when + reading a token, and which can be mutated by the tokenizer.

+ +

Modes that use a state must define + a startState method on their mode + object. This is a function of no arguments that produces a state + object to be used at the start of a document.

+ +

The most important part of a mode object is + its token(stream, state) method. All + modes must define this method. It should read one token from the + stream it is given as an argument, optionally update its state, + and return a style string, or null for tokens that do + not have to be styled. For your styles, you are encouraged to use + the 'standard' names defined in the themes (without + the cm- prefix). If that fails, it is also possible + to come up with your own and write your own CSS theme file.

+ +

A typical token string would + be "variable" or "comment". Multiple + styles can be returned (separated by spaces), for + example "string error" for a thing that looks like a + string but is invalid somehow (say, missing its closing quote). + When a style is prefixed by "line-" + or "line-background-", the style will be applied to + the whole line, analogous to what + the addLineClass method + does—styling the "text" in the simple case, and + the "background" element + when "line-background-" is prefixed.

+ +

The stream object that's passed + to token encapsulates a line of code (tokens may + never span lines) and our current position in that line. It has + the following API:

+ +
+
eol() → boolean
+
Returns true only if the stream is at the end of the + line.
+
sol() → boolean
+
Returns true only if the stream is at the start of the + line.
+ +
peek() → string
+
Returns the next character in the stream without advancing + it. Will return a null at the end of the + line.
+
next() → string
+
Returns the next character in the stream and advances it. + Also returns null when no more characters are + available.
+ +
eat(match: string|regexp|function(char: string) → boolean) → string
+
match can be a character, a regular expression, + or a function that takes a character and returns a boolean. If + the next character in the stream 'matches' the given argument, + it is consumed and returned. Otherwise, undefined + is returned.
+
eatWhile(match: string|regexp|function(char: string) → boolean) → boolean
+
Repeatedly calls eat with the given argument, + until it fails. Returns true if any characters were eaten.
+
eatSpace() → boolean
+
Shortcut for eatWhile when matching + white-space.
+
skipToEnd()
+
Moves the position to the end of the line.
+
skipTo(str: string) → boolean
+
Skips to the start of the next occurrence of the given string, if + found on the current line (doesn't advance the stream if the + string does not occur on the line). Returns true if the + string was found.
+
match(pattern: string, ?consume: boolean, ?caseFold: boolean) → boolean
+
match(pattern: regexp, ?consume: boolean) → array<string>
+
Act like a + multi-character eat—if consume is true + or not given—or a look-ahead that doesn't update the stream + position—if it is false. pattern can be either a + string or a regular expression starting with ^. + When it is a string, caseFold can be set to true to + make the match case-insensitive. When successfully matching a + regular expression, the returned value will be the array + returned by match, in case you need to extract + matched groups.
+ +
backUp(n: integer)
+
Backs up the stream n characters. Backing it up + further than the start of the current token will cause things to + break, so be careful.
+
column() → integer
+
Returns the column (taking into account tabs) at which the + current token starts.
+
indentation() → integer
+
Tells you how far the current line has been indented, in + spaces. Corrects for tab characters.
+ +
current() → string
+
Get the string between the start of the current token and + the current stream position.
+ +
lookAhead(n: number) → ?string
+
Get the line n (>0) lines after the current + one, in order to scan ahead across line boundaries. Note that + you want to do this carefully, since looking far ahead will make + mode state caching much less effective.
+ +
baseToken() → ?{type: ?string, size: number}
+
Modes added + through addOverlay + (and only such modes) can use this method to inspect + the current token produced by the underlying mode.
+
+ +

By default, blank lines are simply skipped when + tokenizing a document. For languages that have significant blank + lines, you can define + a blankLine(state) method on your + mode that will get called whenever a blank line is passed over, so + that it can update the parser state.

+ +

Because state object are mutated, and CodeMirror + needs to keep valid versions of a state around so that it can + restart a parse at any line, copies must be made of state objects. + The default algorithm used is that a new state object is created, + which gets all the properties of the old object. Any properties + which hold arrays get a copy of these arrays (since arrays tend to + be used as mutable stacks). When this is not correct, for example + because a mode mutates non-array properties of its state object, a + mode object should define + a copyState method, which is given a + state and should return a safe copy of that state.

+ +

If you want your mode to provide smart indentation + (through the indentLine + method and the indentAuto + and newlineAndIndent commands, to which keys can be + bound), you must define + an indent(state, textAfter) method + on your mode object.

+ +

The indentation method should inspect the given state object, + and optionally the textAfter string, which contains + the text on the line that is being indented, and return an + integer, the amount of spaces to indent. It should usually take + the indentUnit + option into account. An indentation method may + return CodeMirror.Pass to indicate that it + could not come up with a precise indentation.

+ +

To work well with + the commenting addon, a mode may + define lineComment (string that + starts a line + comment), blockCommentStart, blockCommentEnd + (strings that start and end block comments), + and blockCommentLead (a string to put at the start of + continued lines in a block comment). All of these are + optional.

+ +

Finally, a mode may define either + an electricChars or an electricInput + property, which are used to automatically reindent the line when + certain patterns are typed and + the electricChars + option is enabled. electricChars may be a string, and + will trigger a reindent whenever one of the characters in that + string are typed. Often, it is more appropriate to + use electricInput, which should hold a regular + expression, and will trigger indentation when the part of the + line before the cursor matches the expression. It should + usually end with a $ character, so that it only + matches when the indentation-changing pattern was just typed, not when something was + typed after the pattern.

+ +

So, to summarize, a mode must provide + a token method, and it may + provide startState, copyState, + and indent methods. For an example of a trivial mode, + see the diff mode, for a more + involved example, see the C-like + mode.

+ +

Sometimes, it is useful for modes to nest—to have one + mode delegate work to another mode. An example of this kind of + mode is the mixed-mode HTML + mode. To implement such nesting, it is usually necessary to + create mode objects and copy states yourself. To create a mode + object, there are CodeMirror.getMode(options, + parserConfig), where the first argument is a configuration + object as passed to the mode constructor function, and the second + argument is a mode specification as in + the mode option. To copy a + state object, call CodeMirror.copyState(mode, state), + where mode is the mode that created the given + state.

+ +

In a nested mode, it is recommended to add an + extra method, innerMode which, given + a state object, returns a {state, mode} object with + the inner mode and its state for the current position. These are + used by utility scripts such as the tag + closer to get context information. Use + the CodeMirror.innerMode helper function to, starting + from a mode and a state, recursively walk down to the innermost + mode and state.

+ +

To make indentation work properly in a nested parser, it is + advisable to give the startState method of modes that + are intended to be nested an optional argument that provides the + base indentation for the block of code. The JavaScript and CSS + parser do this, for example, to allow JavaScript and CSS code + inside the mixed-mode HTML mode to be properly indented.

+ +

It is possible, and encouraged, to associate + your mode, or a certain configuration of your mode, with + a MIME type. For + example, the JavaScript mode associates itself + with text/javascript, and its JSON variant + with application/json. To do this, + call CodeMirror.defineMIME(mime, + modeSpec), where modeSpec can be a string or + object specifying a mode, as in + the mode option.

+ +

If a mode specification wants to add some properties to the + resulting mode object, typically for use + with getHelpers, it may + contain a modeProps property, which holds an object. + This object's properties will be copied to the actual mode + object.

+ +

Sometimes, it is useful to add or override mode + object properties from external code. + The CodeMirror.extendMode function + can be used to add properties to mode objects produced for a + specific mode. Its first argument is the name of the mode, its + second an object that specifies the properties that should be + added. This is mostly useful to add utilities that can later be + looked up through getMode.

+
+ +
+

VIM Mode API

+ +

CodeMirror has a robust VIM mode that attempts to faithfully + emulate VIM's most useful features. It can be enabled by + including keymap/vim.js + and setting the keyMap option to + "vim".

+ +

Configuration

+ +

VIM mode accepts configuration options for customizing + behavior at run time. These methods can be called at any time + and will affect all existing CodeMirror instances unless + specified otherwise. The methods are exposed on the + CodeMirror.Vim object.

+ +
+
setOption(name: string, value: any, ?cm: CodeMirror, ?cfg: object)
+
Sets the value of a VIM option. name should + be the name of an option. If cfg.scope is not set + and cm is provided, then sets the global and + instance values of the option. Otherwise, sets either the + global or instance value of the option depending on whether + cfg.scope is global or + local.
+
getOption(name: string, ?cm: CodeMirror: ?cfg: object)
+
Gets the current value of a VIM option. If + cfg.scope is not set and cm is + provided, then gets the instance value of the option, falling + back to the global value if not set. If cfg.scope is provided, then gets the global or + local value without checking the other.
+ +
map(lhs: string, rhs: string, ?context: string)
+
Maps a key sequence to another key sequence. Implements + VIM's :map command. To map ; to : in VIM would be + :map ; :. That would translate to + CodeMirror.Vim.map(';', ':');. + The context can be normal, + visual, or insert, which correspond + to :nmap, :vmap, and + :imap + respectively.
+ +
mapCommand(keys: string, type: string, name: string, ?args: object, ?extra: object)
+
Maps a key sequence to a motion, + operator, or action type command. + The args object is passed through to the command when it is + invoked by the provided key sequence. + extras.context can be normal, + visual, or insert, to map the key + sequence only in the corresponding mode. + extras.isEdit is applicable only to actions, + determining whether it is recorded for replay for the + . single-repeat command. +
+ +

Extending VIM

+ +

CodeMirror's VIM mode implements a large subset of VIM's core + editing functionality. But since there's always more to be + desired, there is a set of APIs for extending VIM's + functionality. As with the configuration API, the methods are + exposed on CodeMirror.Vim and may + be called at any time.

+ +
+
defineOption(name: string, default: any, type: string, ?aliases: array<string>, ?callback: function (?value: any, ?cm: CodeMirror) → ?any)
+
Defines a VIM style option and makes it available to the + :set command. Type can be boolean or + string, used for validation and by + :set to determine which syntax to accept. If a + callback is passed in, VIM does not store the value of the + option itself, but instead uses the callback as a setter/getter. If the + first argument to the callback is undefined, then the + callback should return the value of the option. Otherwise, it should set + instead. Since VIM options have global and instance values, whether a + CodeMirror instance is passed in denotes whether the global + or local value should be used. Consequently, it's possible for the + callback to be called twice for a single setOption or + getOption call. Note that right now, VIM does not support + defining buffer-local options that do not have global values. If an + option should not have a global value, either always ignore the + cm parameter in the callback, or always pass in a + cfg.scope to setOption and + getOption.
+ +
defineMotion(name: string, fn: function(cm: CodeMirror, head: {line, ch}, ?motionArgs: object}) → {line, ch})
+
Defines a motion command for VIM. The motion should return + the desired result position of the cursor. head + is the current position of the cursor. It can differ from + cm.getCursor('head') if VIM is in visual mode. + motionArgs is the object passed into + mapCommand().
+ +
defineOperator(name: string, fn: function(cm: CodeMirror, ?operatorArgs: object, ranges: array<{anchor, head}>) → ?{line, ch})
+
Defines an operator command, similar to + defineMotion. ranges is the range + of text the operator should operate on. If the cursor should + be set to a certain position after the operation finishes, it + can return a cursor object.
+ +
defineAction(name: string, fn: function(cm: CodeMirror, ?actionArgs: object))
+
Defines an action command, similar to + defineMotion. Action commands + can have arbitrary behavior, making them more flexible than + motions and operators, at the loss of orthogonality.
+ +
defineEx(name: string, ?prefix: string, fn: function(cm: CodeMirror, ?params: object))
+
Defines an Ex command, and maps it to :name. + If a prefix is provided, it, and any prefixed substring of the + name beginning with the prefix can + be used to invoke the command. If the prefix is + falsy, then name is used as the prefix. + params.argString contains the part of the prompted + string after the command name. params.args is + params.argString split by whitespace. If the + command was prefixed with a + line range, + params.line and params.lineEnd will + be set. +
+ +
+ +
+ + diff --git a/backend/webif/static/codemirror/doc/realworld.html b/backend/webif/static/codemirror/doc/realworld.html new file mode 100755 index 000000000..da0f4e4e6 --- /dev/null +++ b/backend/webif/static/codemirror/doc/realworld.html @@ -0,0 +1,186 @@ + + +CodeMirror: Real-world Uses + + + + + +
+ +

CodeMirror real-world uses

+ +

Create a pull + request if you'd like your project to be added to this list.

+ + + +
+ diff --git a/backend/webif/static/codemirror/doc/releases.html b/backend/webif/static/codemirror/doc/releases.html new file mode 100755 index 000000000..7fb8eebef --- /dev/null +++ b/backend/webif/static/codemirror/doc/releases.html @@ -0,0 +1,1557 @@ + + +CodeMirror: Release History + + + + + + +
+ +

Release notes and version history

+ +
+ +

Version 5.x

+ +

22-11-2017: Version 5.32.0:

+ +
    +
  • Increase contrast on default bracket-matching colors.
  • +
  • javascript mode: Recognize TypeScript type parameters for calls, type guards, and type parameter defaults. Improve handling of enum and module keywords.
  • +
  • comment addon: Fix bug when uncommenting a comment that spans all but the last selected line.
  • +
  • searchcursor addon: Fix bug in case folding.
  • +
  • emacs bindings: Prevent single-character deletions from resetting the kill ring.
  • +
  • closebrackets addon: Tweak quote matching behavior.
  • +
  • continuelist addon: Increment ordered list numbers when adding one.
  • +
+ +

20-10-2017: Version 5.31.0:

+ +
    +
  • Modes added with addOverlay now have access to a baseToken method on their input stream, giving access to the tokens of the underlying mode.
  • +
  • Further improve selection drawing and cursor motion in right-to-left documents.
  • +
  • vim bindings: Fix ctrl-w behavior, support quote-dot and backtick-dot marks, make the wide cursor visible in contentEditable input mode.
  • +
  • continuecomment addon: Fix bug when pressing enter after a single-line block comment.
  • +
  • markdown mode: Fix issue with leaving indented fenced code blocks.
  • +
  • javascript mode: Fix bad parsing of operators without spaces between them. Fix some corner cases around semicolon insertion and regexps.
  • +
+ +

20-09-2017: Version 5.30.0:

+ +
    +
  • Fixed a number of issues with drawing right-to-left selections and mouse selection in bidirectional text.
  • +
  • search addon: Fix crash when restarting search after doing empty search.
  • +
  • mark-selection addon: Fix off-by-one bug.
  • +
  • tern addon: Fix bad request made when editing at the bottom of a large document.
  • +
  • javascript mode: Improve parsing in a number of corner cases.
  • +
  • markdown mode: Fix crash when a sub-mode doesn't support indentation, allow uppercase X in task lists.
  • +
  • gfm mode: Don't highlight SHA1 'hashes' without numbers to avoid false positives.
  • +
  • soy mode: Support injected data and @param in comments.
  • +
  • simple mode addon: Allow groups in regexps when token isn't an array.
  • +
+ +

24-08-2017: Version 5.29.0:

+ +
    +
  • Fix crash in contentEditable input style when editing near a bookmark.
  • +
  • Make sure change origins are preserved when splitting changes on read-only marks.
  • +
  • javascript mode: More support for TypeScript syntax.
  • +
  • d mode: Support nested comments.
  • +
  • python mode: Improve tokenizing of operators.
  • +
  • markdown mode: Further improve CommonMark conformance.
  • +
  • css mode: Don't run comment tokens through the mode's state machine.
  • +
  • shell mode: Allow strings to span lines.
  • +
  • search addon: Fix crash in persistent search when extraKeys is null.
  • +
+ +

21-07-2017: Version 5.28.0:

+ +
    +
  • Fix copying of, or replacing editor content with, a single dash character when copying a big selection in some corner cases.
  • +
  • Make "goLineLeft"/"goLineRight" behave better on wrapped lines.
  • +
  • sql mode: Fix tokenizing of multi-dot operator and allow digits in subfield names.
  • +
  • searchcursor addon: Fix infinite loop on some composed character inputs.
  • +
  • markdown mode: Make list parsing more CommonMark-compliant.
  • +
  • gfm mode: Highlight colon syntax for emoji.
  • +
+ +

29-06-2017: Version 5.27.4:

+ +
    +
  • Fix crash when using mode lookahead.
  • +
  • markdown mode: Don't block inner mode's indentation support.
  • +
+ +

22-06-2017: Version 5.27.2:

+ + + +

22-06-2017: Version 5.27.0:

+ +
    +
  • Fix infinite loop in forced display update.
  • +
  • Properly disable the hidden textarea when readOnly is "nocursor".
  • +
  • Calling the Doc constructor without new works again.
  • +
  • sql mode: Handle nested comments.
  • +
  • javascript mode: Improve support for TypeScript syntax.
  • +
  • markdown mode: Fix bug where markup was ignored on indented paragraph lines.
  • +
  • vim bindings: Referencing invalid registers no longer causes an uncaught exception.
  • +
  • rust mode: Add the correct MIME type.
  • +
  • matchbrackets addon: Document options.
  • +
  • Mouse button clicks can now be bound in keymaps by using names like "LeftClick" or "Ctrl-Alt-MiddleTripleClick". When bound to a function, that function will be passed the position of the click as second argument.
  • +
  • The behavior of mouse selection and dragging can now be customized with the configureMouse option.
  • +
  • Modes can now look ahead across line boundaries with the StringStream.lookahead method.
  • +
  • Introduces a "type" token type, makes modes that recognize types output it, and add styling for it to the themes.
  • +
  • New pasteLinesPerSelection option to control the behavior of pasting multiple lines into multiple selections.
  • +
  • searchcursor addon: Support multi-line regular expression matches, and normalize strings when matching.
  • +
+ +

22-05-2017: Version 5.26.0:

+ +
    +
  • In textarea-mode, don't reset the input field during composition.
  • +
  • More careful restoration of selections in widgets, during editor redraw.
  • +
  • vim bindings: Parse line offsets in line or range specs.
  • +
  • javascript mode: More TypeScript parsing fixes.
  • +
  • julia mode: Fix issue where the mode gets stuck.
  • +
  • markdown mode: Understand cross-line links, parse all bracketed things as links.
  • +
  • soy mode: Support single-quoted strings.
  • +
  • go mode: Don't try to indent inside strings or comments.
  • +
+ +

20-04-2017: Version 5.25.2:

+ +
    +
  • Better handling of selections that cover the whole viewport in contentEditable-mode.
  • +
  • No longer accidentally scroll the editor into view when calling setValue.
  • +
  • Work around Chrome Android bug when converting screen coordinates to editor positions.
  • +
  • Make sure long-clicking a selection sets a cursor and doesn't show the editor losing focus.
  • +
  • Fix issue where pointer events were incorrectly disabled on Chrome's overlay scrollbars.
  • +
  • javascript mode: Recognize annotations and TypeScript-style type parameters.
  • +
  • shell mode: Handle nested braces.
  • +
  • markdown mode: Make parsing of strong/em delimiters CommonMark-compliant.
  • +
+ +

20-03-2017: Version 5.25.0:

+ +
    +
  • In contentEditable-mode, properly locate changes that repeat a character when inserted with IME.
  • +
  • Fix handling of selections bigger than the viewport in contentEditable mode.
  • +
  • Improve handling of changes that insert or delete lines in contentEditable mode.
  • +
  • Count Unicode control characters 0x80 to 0x9F as special (non-printing) chars.
  • +
  • Fix handling of shadow DOM roots when finding the active element.
  • +
  • Add role=presentation to more DOM elements to improve screen reader support.
  • +
  • merge addon: Make aligning of unchanged chunks more robust.
  • +
  • comment addon: Fix comment-toggling on a block of text that starts and ends in a (differnet) block comment.
  • +
  • javascript mode: Improve support for TypeScript syntax.
  • +
  • r mode: Fix indentation after semicolon-less statements.
  • +
  • shell mode: Properly handle escaped parentheses in parenthesized expressions.
  • +
  • markdown mode: Fix a few bugs around leaving fenced code blocks.
  • +
  • soy mode: Improve indentation.
  • +
  • lint addon: Support asynchronous linters that return promises.
  • +
  • continuelist addon: Support continuing task lists.
  • +
  • vim bindings: Make Y behave like yy.
  • +
  • sql mode: Support sqlite dialect.
  • +
+ +

22-02-2017: Version 5.24.2:

+ +
    +
  • javascript mode: Support computed class method names.
  • +
  • merge addon: Improve aligning of unchanged code in the presence of marks and line widgets.
  • +
+ +

20-02-2017: Version 5.24.0:

+ +
    +
  • Positions now support a sticky property which determines whether they should be associated with the character before (value "before") or after (value "after") them.
  • +
  • vim bindings: Make it possible to remove built-in bindings through the API.
  • +
  • comment addon: Support a per-mode useInnerComments option to optionally suppress descending to the inner modes to get comment strings.
  • +
  • A cursor directly before a line-wrapping break is now drawn before or after the line break depending on which direction you arrived from.
  • +
  • Visual cursor motion in line-wrapped right-to-left text should be much more correct.
  • +
  • Fix bug in handling of read-only marked text.
  • +
  • shell mode: Properly tokenize nested parentheses.
  • +
  • python mode: Support underscores in number literals.
  • +
  • sass mode: Uses the full list of CSS properties and keywords from the CSS mode, rather than defining its own incomplete subset. Now depends on the css mode.
  • +
  • css mode: Expose lineComment property for LESS and SCSS dialects. Recognize vendor prefixes on pseudo-elements.
  • +
  • julia mode: Properly indent elseif lines.
  • +
  • markdown mode: Properly recognize the end of fenced code blocks when inside other markup.
  • +
  • scala mode: Improve handling of operators containing #, @, and : chars.
  • +
  • xml mode: Allow dashes in HTML tag names.
  • +
  • javascript mode: Improve parsing of async methods, TypeScript-style comma-separated superclass lists.
  • +
  • indent-fold addon: Ignore comment lines.
  • +
+ +

19-01-2017: Version 5.23.0:

+ +
    +
  • Presentation-related elements DOM elements are now marked as such to help screen readers.
  • +
  • markdown mode: Be more picky about what HTML tags look like to avoid false positives.
  • +
  • findModeByMIME now understands +json and +xml MIME suffixes.
  • +
  • closebrackets addon: Add support for an override option to ignore language-specific defaults.
  • +
  • panel addon: Add a stable option that auto-scrolls the content to keep it in the same place when inserting/removing a panel.
  • +
+ +

20-12-2016: Version 5.22.0:

+ +
    +
  • sublime bindings: Make selectBetweenBrackets work with multiple cursors.
  • +
  • javascript mode: Fix issues with parsing complex TypeScript types, imports, and exports.
  • +
  • A contentEditable editor instance with autofocus enabled no longer crashes during initializing.
  • +
  • emacs bindings: Export CodeMirror.emacs to allow other addons to hook into Emacs-style functionality.
  • +
  • active-line addon: Add nonEmpty option.
  • +
  • New event: optionChange.
  • +
+ +

21-11-2016: Version 5.21.0:

+ +
    +
  • Tapping/clicking the editor in contentEditable mode on Chrome now puts the cursor at the tapped position.
  • +
  • Fix various crashes and misbehaviors when reading composition events in contentEditable mode.
  • +
  • Catches and ignores an IE 'Unspecified Error' when creating an editor in an iframe before there is a <body>.
  • +
  • merge addon: Fix several issues in the chunk-aligning feature.
  • +
  • verilog mode: Rewritten to address various issues.
  • +
  • julia mode: Recognize Julia 0.5 syntax.
  • +
  • swift mode: Various fixes and adjustments to current syntax.
  • +
  • markdown mode: Allow lists without a blank line above them.
  • +
  • The setGutterMarker, clearGutter, and lineInfo methods are now available on Doc objects.
  • +
  • The heightAtLine method now takes an extra argument to allow finding the height at the top of the line's line widgets.
  • +
  • ruby mode: else and elsif are now immediately indented.
  • +
  • vim bindings: Bind Ctrl-T and Ctrl-D to in- and dedent in insert mode.
  • +
+ +

20-10-2016: Version 5.20.0:

+ +
    +
  • Make newlineAndIndent command work with multiple cursors on the same line.
  • +
  • Make sure keypress events for backspace are ignored.
  • +
  • Tokens styled with overlays no longer get a nonsense cm-cm-overlay class.
  • +
  • Line endings for pasted content are now normalized to the editor's preferred ending.
  • +
  • javascript mode: Improve support for class expressions. Support TypeScript optional class properties, the abstract keyword, and return type declarations for arrow functions.
  • +
  • css mode: Fix highlighting of mixed-case keywords.
  • +
  • closebrackets addon: Improve behavior when typing a quote before a string.
  • +
  • The core is now maintained as a number of small files, using ES6 syntax and modules, under the src/ directory. A git checkout no longer contains a working codemirror.js until you npm build (but when installing from NPM, it is included).
  • +
  • The refresh event is now documented and stable.
  • +
+ +

20-09-2016: Version 5.19.0:

+ +
    +
  • erlang mode: Fix mode crash when trying to read an empty context.
  • +
  • comment addon: Fix broken behavior when toggling comments inside a comment.
  • +
  • xml-fold addon: Fix a null-dereference bug.
  • +
  • Page up and page down now do something even in single-line documents.
  • +
  • Fix an issue where the cursor position could be off in really long (~8000 character) tokens.
  • +
  • javascript mode: Better indentation when semicolons are missing. Better support for TypeScript classes, optional parameters, and the type keyword.
  • +
  • The blur and focus events now pass the DOM event to their handlers.
  • +
+ +

23-08-2016: Version 5.18.2:

+ +
    +
  • vue mode: Fix outdated references to renamed Pug mode dependency.
  • +
+ +

22-08-2016: Version 5.18.0:

+ +
    +
  • Make sure gutter backgrounds stick to the rest of the gutter during horizontal scrolling.
  • +
  • The contenteditable inputStyle now properly supports pasting on pre-Edge IE versions.
  • +
  • javascript mode: Fix some small parsing bugs and improve TypeScript support.
  • +
  • matchbrackets addon: Fix bug where active highlighting was left in editor when the addon was disabled.
  • +
  • match-highlighter addon: Only start highlighting things when the editor gains focus.
  • +
  • javascript-hint addon: Also complete non-enumerable properties.
  • +
  • The addOverlay method now supports a priority option to control the order in which overlays are applied.
  • +
  • MIME types that end in +json now default to the JSON mode when the MIME itself is not defined.
  • +
  • The mode formerly known as Jade was renamed to Pug.
  • +
  • The Python mode now defaults to Python 3 (rather than 2) syntax.
  • +
+ +

19-07-2016: Version 5.17.0:

+ +
    +
  • Fix problem with wrapped trailing whitespace displaying incorrectly.
  • +
  • Prevent IME dialog from overlapping typed content in Chrome.
  • +
  • Improve measuring of characters near a line wrap.
  • +
  • javascript mode: Improve support for async, allow trailing commas in import lists.
  • +
  • vim bindings: Fix backspace in replace mode.
  • +
  • sublime bindings: Fix some key bindings on OS X to match Sublime Text.
  • +
  • markdown mode: Add more classes to image links in highlight-formatting mode.
  • +
+ +

20-06-2016: Version 5.16.0:

+ +
    +
  • Fix glitches when dragging content caused by the drop indicator receiving mouse events.
  • +
  • Make Control-drag work on Firefox.
  • +
  • Make clicking or selection-dragging at the end of a wrapped line select the right position.
  • +
  • show-hint addon: Prevent widget scrollbar from hiding part of the hint text.
  • +
  • rulers addon: Prevent rulers from forcing a horizontal editor scrollbar.
  • +
  • search addon: Automatically bind search-related keys in persistent dialog.
  • +
  • sublime keymap: Add a multi-cursor aware smart backspace binding.
  • +
+ +

20-05-2016: Version 5.15.2:

+ +
    +
  • Fix a critical document corruption bug that occurs when a document is gradually grown.
  • +
+ +

20-05-2016: Version 5.15.0:

+ +
    +
  • Fix bug that caused the selection to reset when focusing the editor in contentEditable input mode.
  • +
  • Fix issue where not all ASCII control characters were being replaced by placeholders.
  • +
  • Remove the assumption that all modes have a startState method from several wrapping modes.
  • +
  • Fix issue where the editor would complain about overlapping collapsed ranges when there weren't any.
  • +
  • Optimize document tree building when loading or pasting huge chunks of content.
  • +
  • Explicitly bind Ctrl-O on OS X to make that binding (“open line”) act as expected.
  • +
  • Pasting linewise-copied content when there is no selection now inserts the lines above the current line.
  • +
  • markdown mode: Fix several issues in matching link targets.
  • +
  • clike mode: Improve indentation of C++ template declarations.
  • +
  • javascript mode: Support async/await and improve support for TypeScript type syntax.
  • +
+ +

20-04-2016: Version 5.14.0:

+ + + +

21-03-2016: Version 5.13.2:

+ +
    +
  • Solves a problem where the gutter would sometimes not extend all the way to the end of the document.
  • +
+ +

21-03-2016: Version 5.13:

+ + + +

19-02-2016: Version 5.12:

+ +
    +
  • Vim bindings: Ctrl-Q is now an alias for Ctrl-V.
  • +
  • Vim bindings: The Vim API now exposes an unmap method to unmap bindings.
  • +
  • active-line addon: This addon can now style the active line's gutter.
  • +
  • FCL mode: Newly added.
  • +
  • SQL mode: Now has a Postgresql dialect.
  • +
  • Fix issue where trying to scroll to a horizontal position outside of the document's width could cause the gutter to be positioned incorrectly.
  • +
  • Use absolute, rather than fixed positioning in the context-menu intercept hack, to work around a problem when the editor is inside a transformed parent container.
  • +
  • Solve a problem where the horizontal scrollbar could hide text in Firefox.
  • +
  • Fix a bug that caused phantom scroll space under the text in some situations.
  • +
  • Sublime Text bindings: Bind delete-line to Shift-Ctrl-K on OS X.
  • +
  • Markdown mode: Fix issue where the mode would keep state related to fenced code blocks in an unsafe way, leading to occasional corrupted parses.
  • +
  • Markdown mode: Ignore backslashes in code fragments.
  • +
  • Markdown mode: Use whichever mode is registered as text/html to parse HTML.
  • +
  • Clike mode: Improve indentation of Scala => functions.
  • +
  • Python mode: Improve indentation of bracketed code.
  • +
  • HTMLMixed mode: Support multi-line opening tags for sub-languages (<script>, <style>, etc).
  • +
  • Spreadsheet mode: Fix bug where the mode did not advance the stream when finding a backslash.
  • +
  • XML mode: The mode now takes a matchClosing option to configure whether mismatched closing tags should be highlighted as errors.
  • +
+ +

20-01-2016: Version 5.11:

+ +
    +
  • New modes: JSX, literate Haskell
  • +
  • The editor now forwards more DOM events: cut, copy, paste, and touchstart. It will also forward mousedown for drag events
  • +
  • Fixes a bug where bookmarks next to collapsed spans were not rendered
  • +
  • The Swift mode now supports auto-indentation
  • +
  • Frontmatters in the YAML frontmatter mode are now optional as intended
  • +
  • Full list of patches
  • +
+ +

21-12-2015: Version 5.10:

+ + + +

23-11-2015: Version 5.9:

+ +
    +
  • Improve the way overlay (OS X-style) scrollbars are handled
  • +
  • Make annotatescrollbar and scrollpastend addons work properly together
  • +
  • Make show-hint addon select options on single click by default, move selection to hovered item
  • +
  • Properly fold comments that include block-comment-start markers
  • +
  • Many small language mode fixes
  • +
  • Full list of patches
  • +
+ +

20-10-2015: Version 5.8:

+ + + +

20-09-2015: Version 5.7:

+ + + +

20-08-2015: Version 5.6:

+ +
    +
  • Fix bug where you could paste into a readOnly editor
  • +
  • Show a cursor at the drop location when dragging over the editor
  • +
  • The Rust mode was rewritten to handle modern Rust
  • +
  • The editor and theme CSS was cleaned up. Some selectors are now less specific than before
  • +
  • New theme: abcdef
  • +
  • Lines longer than maxHighlightLength are now less likely to mess up indentation
  • +
  • New addons: autorefresh for refreshing an editor the first time it becomes visible, and html-lint for using HTMLHint
  • +
  • The search addon now recognizes \r and \n in pattern and replacement input
  • +
  • Full list of patches
  • +
+ +

20-07-2015: Version 5.5:

+ + + +

25-06-2015: Version 5.4:

+ + + +

20-05-2015: Version 5.3:

+ + + +

20-04-2015: Version 5.2:

+ + + +

23-03-2015: Version 5.1:

+ + + +

20-02-2015: Version 5.0:

+ +
    +
  • Experimental mobile support (tested on iOS, Android Chrome, stock Android browser)
  • +
  • New option inputStyle to switch between hidden textarea and contenteditable input.
  • +
  • The getInputField + method is no longer guaranteed to return a textarea.
  • +
  • Full list of patches.
  • +
+ +
+ +
+ +

Version 4.x

+ +

20-02-2015: Version 4.13:

+ + + +

22-01-2015: Version 4.12:

+ + + +

9-01-2015: Version 4.11:

+ +

Unfortunately, 4.10 did not take care of the + Firefox scrolling issue entirely. This release adds two more patches + to address that.

+ +

29-12-2014: Version 4.10:

+ +

Emergency single-patch update to 4.9. Fixes + Firefox-specific problem where the cursor could end up behind the + horizontal scrollbar.

+ +

23-12-2014: Version 4.9:

+ + + +

22-11-2014: Version 4.8:

+ + + +

20-10-2014: Version 4.7:

+ +
    +
  • Incompatible: + The lint addon now passes the + editor's value as first argument to asynchronous lint functions, + for consistency. The editor is still passed, as fourth + argument.
  • +
  • Improved handling of unicode identifiers in modes for + languages that support them.
  • +
  • More mode + improvements: CoffeeScript + (indentation), Verilog + (indentation), Scala + (indentation, triple-quoted strings), + and PHP (interpolated + variables in heredoc strings).
  • +
  • New modes: Textile and Tornado templates.
  • +
  • Experimental new way to define modes.
  • +
  • Improvements to the Vim + bindings: Arbitrary insert mode key mappings are now possible, + and text objects are supported in visual mode.
  • +
  • The mode meta-information file + now includes information about file extensions, + and helper + functions findModeByMIME + and findModeByExtension.
  • +
  • New logo!
  • +
  • Full list of patches.
  • +
+ +

19-09-2014: Version 4.6:

+ + + +

21-08-2014: Version 4.5:

+ +
    +
  • Fix several serious bugs with horizontal scrolling
  • +
  • New mode: Slim
  • +
  • New command: goLineLeftSmart
  • +
  • More fixes and extensions for the Vim visual block mode
  • +
  • Full list of patches.
  • +
+ +

21-07-2014: Version 4.4:

+ +
    +
  • Note: Some events might now fire in slightly + different order ("change" is still guaranteed to fire + before "cursorActivity")
  • +
  • Nested operations in multiple editors are now synced (complete + at same time, reducing DOM reflows)
  • +
  • Visual block mode for vim (<C-v>) is nearly complete
  • +
  • New mode: Kotlin
  • +
  • Better multi-selection paste for text copied from multiple CodeMirror selections
  • +
  • Full list of patches.
  • +
+ +

23-06-2014: Version 4.3:

+ +
    +
  • Several vim bindings + improvements: search and exCommand history, global flag + for :substitute, :global command. +
  • Allow hiding the cursor by + setting cursorBlinkRate + to a negative value.
  • +
  • Make gutter markers themeable, use this in foldgutter.
  • +
  • Full list of patches.
  • +
+ +

19-05-2014: Version 4.2:

+ +
    +
  • Fix problem where some modes were broken by the fact that empty tokens were forbidden.
  • +
  • Several fixes to context menu handling.
  • +
  • On undo, scroll change, not cursor, into view.
  • +
  • Rewritten Jade mode.
  • +
  • Various improvements to Shell (support for more syntax) and Python (better indentation) modes.
  • +
  • New mode: Cypher.
  • +
  • New theme: Neo.
  • +
  • Support direct styling options (color, line style, width) in the rulers addon.
  • +
  • Recognize per-editor configuration for the show-hint and foldcode addons.
  • +
  • More intelligent scanning for existing close tags in closetag addon.
  • +
  • In the Vim bindings: Fix bracket matching, support case conversion in visual mode, visual paste, append action.
  • +
  • Full list of patches.
  • +
+ +

22-04-2014: Version 4.1:

+ +
    +
  • Slightly incompatible: + The "cursorActivity" + event now fires after all other events for the operation (and only + for handlers that were actually registered at the time the + activity happened).
  • +
  • New command: insertSoftTab.
  • +
  • New mode: Django.
  • +
  • Improved modes: Verilog (rewritten), Jinja2, Haxe, PHP (string interpolation highlighted), JavaScript (indentation of trailing else, template strings), LiveScript (multi-line strings).
  • +
  • Many small issues from the 3.x→4.x transition were found and fixed.
  • +
  • Full list of patches.
  • +
+ +

20-03-2014: Version 4.0:

+ +

This is a new major version of CodeMirror. There + are a few incompatible changes in the API. Upgrade + with care, and read the upgrading + guide.

+ + + +
+ +
+ +

Version 3.x

+ +

22-04-2014: Version 3.24:

+ +

Merges the improvements from 4.1 that could + easily be applied to the 3.x code. Also improves the way the editor + size is updated when line widgets change.

+ +

20-03-2014: Version 3.23:

+ +
    +
  • In the XML mode, + add brackets style to angle brackets, fix + case-sensitivity of tags for HTML.
  • +
  • New mode: Dylan.
  • +
  • Many improvements to the Vim bindings.
  • +
+ +

21-02-2014: Version 3.22:

+ + + +

16-01-2014: Version 3.21:

+ +
    +
  • Auto-indenting a block will no longer add trailing whitespace to blank lines.
  • +
  • Marking text has a new option clearWhenEmpty to control auto-removal.
  • +
  • Several bugfixes in the handling of bidirectional text.
  • +
  • The XML and CSS modes were largely rewritten. LESS support was added to the CSS mode.
  • +
  • The OCaml mode was moved to an mllike mode, F# support added.
  • +
  • Make it possible to fetch multiple applicable helper values with getHelpers, and to register helpers matched on predicates with registerGlobalHelper.
  • +
  • New theme pastel-on-dark.
  • +
  • Better ECMAScript 6 support in JavaScript mode.
  • +
  • Full list of patches.
  • +
+ +

21-11-2013: Version 3.20:

+ + + +

21-10-2013: Version 3.19:

+ + + +

23-09-2013: Version 3.18:

+ +

Emergency release to fix a problem in 3.17 + where .setOption("lineNumbers", false) would raise an + error.

+ +

23-09-2013: Version 3.17:

+ + + +

21-08-2013: Version 3.16:

+ + + +

29-07-2013: Version 3.15:

+ + + +

20-06-2013: Version 3.14:

+ + + +

20-05-2013: Version 3.13:

+ + + +

19-04-2013: Version 3.12:

+ + + +

20-03-2013: Version 3.11:

+ + + +

21-02-2013: Version 3.1:

+ + + + +

25-01-2013: Version 3.02:

+ +

Single-bugfix release. Fixes a problem that + prevents CodeMirror instances from being garbage-collected after + they become unused.

+ +

21-01-2013: Version 3.01:

+ + + +

10-12-2012: Version 3.0:

+ +

New major version. Only + partially backwards-compatible. See + the upgrading guide for more + information. Changes since release candidate 2:

+ +
    +
  • Rewritten VIM mode.
  • +
  • Fix a few minor scrolling and sizing issues.
  • +
  • Work around Safari segfault when dragging.
  • +
  • Full list of patches.
  • +
+ +

20-11-2012: Version 3.0, release candidate 2:

+ +
    +
  • New mode: HTTP.
  • +
  • Improved handling of selection anchor position.
  • +
  • Improve IE performance on longer lines.
  • +
  • Reduce gutter glitches during horiz. scrolling.
  • +
  • Add addKeyMap and removeKeyMap methods.
  • +
  • Rewrite formatting and closetag add-ons.
  • +
  • Full list of patches.
  • +
+ +

20-11-2012: Version 3.0, release candidate 1:

+ + + +

22-10-2012: Version 3.0, beta 2:

+ +
    +
  • Fix page-based coordinate computation.
  • +
  • Fix firing of gutterClick event.
  • +
  • Add cursorHeight option.
  • +
  • Fix bi-directional text regression.
  • +
  • Add viewportMargin option.
  • +
  • Directly handle mousewheel events (again, hopefully better).
  • +
  • Make vertical cursor movement more robust (through widgets, big line gaps).
  • +
  • Add flattenSpans option.
  • +
  • Many optimizations. Poor responsiveness should be fixed.
  • +
  • Initialization in hidden state works again.
  • +
  • Full list of patches.
  • +
+ +

19-09-2012: Version 3.0, beta 1:

+ +
    +
  • Bi-directional text support.
  • +
  • More powerful gutter model.
  • +
  • Support for arbitrary text/widget height.
  • +
  • In-line widgets.
  • +
  • Generalized event handling.
  • +
+ +
+ +
+ +

Version 2.x

+ +

21-01-2013: Version 2.38:

+ +

Integrate some bugfixes, enhancements to the vim keymap, and new + modes + (D, Sass, APL) + from the v3 branch.

+ +

20-12-2012: Version 2.37:

+ +
    +
  • New mode: SQL (will replace plsql and mysql modes).
  • +
  • Further work on the new VIM mode.
  • +
  • Fix Cmd/Ctrl keys on recent Operas on OS X.
  • +
  • Full list of patches.
  • +
+ +

20-11-2012: Version 2.36:

+ + + +

22-10-2012: Version 2.35:

+ +
    +
  • New (sub) mode: TypeScript.
  • +
  • Don't overwrite (insert key) when pasting.
  • +
  • Fix several bugs in markText/undo interaction.
  • +
  • Better indentation of JavaScript code without semicolons.
  • +
  • Add defineInitHook function.
  • +
  • Full list of patches.
  • +
+ +

19-09-2012: Version 2.34:

+ +
    +
  • New mode: Common Lisp.
  • +
  • Fix right-click select-all on most browsers.
  • +
  • Change the way highlighting happens:
      Saves memory and CPU cycles.
      compareStates is no longer needed.
      onHighlightComplete no longer works.
  • +
  • Integrate mode (Markdown, XQuery, CSS, sTex) tests in central testsuite.
  • +
  • Add a CodeMirror.version property.
  • +
  • More robust handling of nested modes in formatting and closetag plug-ins.
  • +
  • Un/redo now preserves marked text and bookmarks.
  • +
  • Full list of patches.
  • +
+ +

23-08-2012: Version 2.33:

+ +
    +
  • New mode: Sieve.
  • +
  • New getViewPort and onViewportChange API.
  • +
  • Configurable cursor blink rate.
  • +
  • Make binding a key to false disabling handling (again).
  • +
  • Show non-printing characters as red dots.
  • +
  • More tweaks to the scrolling model.
  • +
  • Expanded testsuite. Basic linter added.
  • +
  • Remove most uses of innerHTML. Remove CodeMirror.htmlEscape.
  • +
  • Full list of patches.
  • +
+ +

23-07-2012: Version 2.32:

+ +

Emergency fix for a bug where an editor with + line wrapping on IE will break when there is no + scrollbar.

+ +

20-07-2012: Version 2.31:

+ + + +

22-06-2012: Version 2.3:

+ +
    +
  • New scrollbar implementation. Should flicker less. Changes DOM structure of the editor.
  • +
  • New theme: vibrant-ink.
  • +
  • Many extensions to the VIM keymap (including text objects).
  • +
  • Add mode-multiplexing utility script.
  • +
  • Fix bug where right-click paste works in read-only mode.
  • +
  • Add a getScrollInfo method.
  • +
  • Lots of other fixes.
  • +
+ +

23-05-2012: Version 2.25:

+ +
    +
  • New mode: Erlang.
  • +
  • Remove xmlpure mode (use xml.js).
  • +
  • Fix line-wrapping in Opera.
  • +
  • Fix X Windows middle-click paste in Chrome.
  • +
  • Fix bug that broke pasting of huge documents.
  • +
  • Fix backspace and tab key repeat in Opera.
  • +
+ +

23-04-2012: Version 2.24:

+ +
    +
  • Drop support for Internet Explorer 6.
  • +
  • New + modes: Shell, Tiki + wiki, Pig Latin.
  • +
  • New themes: Ambiance, Blackboard.
  • +
  • More control over drag/drop + with dragDrop + and onDragEvent + options.
  • +
  • Make HTML mode a bit less pedantic.
  • +
  • Add compoundChange API method.
  • +
  • Several fixes in undo history and line hiding.
  • +
  • Remove (broken) support for catchall in key maps, + add nofallthrough boolean field instead.
  • +
+ +

26-03-2012: Version 2.23:

+ +
    +
  • Change default binding for tab [more] + +
  • +
  • New modes: XQuery and VBScript.
  • +
  • Two new themes: lesser-dark and xq-dark.
  • +
  • Differentiate between background and text styles in setLineClass.
  • +
  • Fix drag-and-drop in IE9+.
  • +
  • Extend charCoords + and cursorCoords with a mode argument.
  • +
  • Add autofocus option.
  • +
  • Add findMarksAt method.
  • +
+ +

27-02-2012: Version 2.22:

+ + + +

27-01-2012: Version 2.21:

+ +
    +
  • Added LESS, MySQL, + Go, and Verilog modes.
  • +
  • Add smartIndent + option.
  • +
  • Support a cursor in readOnly-mode.
  • +
  • Support assigning multiple styles to a token.
  • +
  • Use a new approach to drawing the selection.
  • +
  • Add scrollTo method.
  • +
  • Allow undo/redo events to span non-adjacent lines.
  • +
  • Lots and lots of bugfixes.
  • +
+ +

20-12-2011: Version 2.2:

+ + + +

21-11-2011: Version 2.18:

+

Fixes TextMarker.clear, which is broken in 2.17.

+ +

21-11-2011: Version 2.17:

+
    +
  • Add support for line + wrapping and code + folding.
  • +
  • Add Github-style Markdown mode.
  • +
  • Add Monokai + and Rubyblue themes.
  • +
  • Add setBookmark method.
  • +
  • Move some of the demo code into reusable components + under lib/util.
  • +
  • Make screen-coord-finding code faster and more reliable.
  • +
  • Fix drag-and-drop in Firefox.
  • +
  • Improve support for IME.
  • +
  • Speed up content rendering.
  • +
  • Fix browser's built-in search in Webkit.
  • +
  • Make double- and triple-click work in IE.
  • +
  • Various fixes to modes.
  • +
+ +

27-10-2011: Version 2.16:

+
    +
  • Add Perl, Rust, TiddlyWiki, and Groovy modes.
  • +
  • Dragging text inside the editor now moves, rather than copies.
  • +
  • Add a coordsFromIndex method.
  • +
  • API change: setValue now no longer clears history. Use clearHistory for that.
  • +
  • API change: markText now + returns an object with clear and find + methods. Marked text is now more robust when edited.
  • +
  • Fix editing code with tabs in Internet Explorer.
  • +
+ +

26-09-2011: Version 2.15:

+

Fix bug that snuck into 2.14: Clicking the + character that currently has the cursor didn't re-focus the + editor.

+ +

26-09-2011: Version 2.14:

+ + + +

23-08-2011: Version 2.13:

+ + +

25-07-2011: Version 2.12:

+
    +
  • Add a SPARQL mode.
  • +
  • Fix bug with cursor jumping around in an unfocused editor in IE.
  • +
  • Allow key and mouse events to bubble out of the editor. Ignore widget clicks.
  • +
  • Solve cursor flakiness after undo/redo.
  • +
  • Fix block-reindent ignoring the last few lines.
  • +
  • Fix parsing of multi-line attrs in XML mode.
  • +
  • Use innerHTML for HTML-escaping.
  • +
  • Some fixes to indentation in C-like mode.
  • +
  • Shrink horiz scrollbars when long lines removed.
  • +
  • Fix width feedback loop bug that caused the width of an inner DIV to shrink.
  • +
+ +

04-07-2011: Version 2.11:

+
    +
  • Add a Scheme mode.
  • +
  • Add a replace method to search cursors, for cursor-preserving replacements.
  • +
  • Make the C-like mode mode more customizable.
  • +
  • Update XML mode to spot mismatched tags.
  • +
  • Add getStateAfter API and compareState mode API methods for finer-grained mode magic.
  • +
  • Add a getScrollerElement API method to manipulate the scrolling DIV.
  • +
  • Fix drag-and-drop for Firefox.
  • +
  • Add a C# configuration for the C-like mode.
  • +
  • Add full-screen editing and mode-changing demos.
  • +
+ +

07-06-2011: Version 2.1:

+

Add + a theme system + (demo). Note that this is not + backwards-compatible—you'll have to update your styles and + modes!

+ +

07-06-2011: Version 2.02:

+
    +
  • Add a Lua mode.
  • +
  • Fix reverse-searching for a regexp.
  • +
  • Empty lines can no longer break highlighting.
  • +
  • Rework scrolling model (the outer wrapper no longer does the scrolling).
  • +
  • Solve horizontal jittering on long lines.
  • +
  • Add runmode.js.
  • +
  • Immediately re-highlight text when typing.
  • +
  • Fix problem with 'sticking' horizontal scrollbar.
  • +
+ +

26-05-2011: Version 2.01:

+
    +
  • Add a Smalltalk mode.
  • +
  • Add a reStructuredText mode.
  • +
  • Add a Python mode.
  • +
  • Add a PL/SQL mode.
  • +
  • coordsChar now works
  • +
  • Fix a problem where onCursorActivity interfered with onChange.
  • +
  • Fix a number of scrolling and mouse-click-position glitches.
  • +
  • Pass information about the changed lines to onChange.
  • +
  • Support cmd-up/down on OS X.
  • +
  • Add triple-click line selection.
  • +
  • Don't handle shift when changing the selection through the API.
  • +
  • Support "nocursor" mode for readOnly option.
  • +
  • Add an onHighlightComplete option.
  • +
  • Fix the context menu for Firefox.
  • +
+ +

28-03-2011: Version 2.0:

+

CodeMirror 2 is a complete rewrite that's + faster, smaller, simpler to use, and less dependent on browser + quirks. See this + and this + for more information.

+ +

22-02-2011: Version 2.0 beta 2:

+

Somewhat more mature API, lots of bugs shaken out.

+ +

17-02-2011: Version 0.94:

+
    +
  • tabMode: "spaces" was modified slightly (now indents when something is selected).
  • +
  • Fixes a bug that would cause the selection code to break on some IE versions.
  • +
  • Disabling spell-check on WebKit browsers now works.
  • +
+ +

08-02-2011: Version 2.0 beta 1:

+

CodeMirror 2 is a complete rewrite of + CodeMirror, no longer depending on an editable frame.

+ +

19-01-2011: Version 0.93:

+
    +
  • Added a Regular Expression parser.
  • +
  • Fixes to the PHP parser.
  • +
  • Support for regular expression in search/replace.
  • +
  • Add save method to instances created with fromTextArea.
  • +
  • Add support for MS T-SQL in the SQL parser.
  • +
  • Support use of CSS classes for highlighting brackets.
  • +
  • Fix yet another hang with line-numbering in hidden editors.
  • +
+
+ +
+ +

Version 0.x

+ +

28-03-2011: Version 1.0:

+
    +
  • Fix error when debug history overflows.
  • +
  • Refine handling of C# verbatim strings.
  • +
  • Fix some issues with JavaScript indentation.
  • +
+ +

17-12-2010: Version 0.92:

+
    +
  • Make CodeMirror work in XHTML documents.
  • +
  • Fix bug in handling of backslashes in Python strings.
  • +
  • The styleNumbers option is now officially + supported and documented.
  • +
  • onLineNumberClick option added.
  • +
  • More consistent names onLoad and + onCursorActivity callbacks. Old names still work, but + are deprecated.
  • +
  • Add a Freemarker mode.
  • +
+ +

11-11-2010: Version 0.91:

+
    +
  • Adds support for Java.
  • +
  • Small additions to the PHP and SQL parsers.
  • +
  • Work around various Webkit issues.
  • +
  • Fix toTextArea to update the code in the textarea.
  • +
  • Add a noScriptCaching option (hack to ease development).
  • +
  • Make sub-modes of HTML mixed mode configurable.
  • +
+ +

02-10-2010: Version 0.9:

+
    +
  • Add support for searching backwards.
  • +
  • There are now parsers for Scheme, XQuery, and OmetaJS.
  • +
  • Makes height: "dynamic" more robust.
  • +
  • Fixes bug where paste did not work on OS X.
  • +
  • Add a enterMode and electricChars options to make indentation even more customizable.
  • +
  • Add firstLineNumber option.
  • +
  • Fix bad handling of @media rules by the CSS parser.
  • +
  • Take a new, more robust approach to working around the invisible-last-line bug in WebKit.
  • +
+ +

22-07-2010: Version 0.8:

+
    +
  • Add a cursorCoords method to find the screen + coordinates of the cursor.
  • +
  • A number of fixes and support for more syntax in the PHP parser.
  • +
  • Fix indentation problem with JSON-mode JS parser in Webkit.
  • +
  • Add a minification UI.
  • +
  • Support a height: dynamic mode, where the editor's + height will adjust to the size of its content.
  • +
  • Better support for IME input mode.
  • +
  • Fix JavaScript parser getting confused when seeing a no-argument + function call.
  • +
  • Have CSS parser see the difference between selectors and other + identifiers.
  • +
  • Fix scrolling bug when pasting in a horizontally-scrolled + editor.
  • +
  • Support toTextArea method in instances created with + fromTextArea.
  • +
  • Work around new Opera cursor bug that causes the cursor to jump + when pressing backspace at the end of a line.
  • +
+ +

27-04-2010: Version + 0.67:

+

More consistent page-up/page-down behaviour + across browsers. Fix some issues with hidden editors looping forever + when line-numbers were enabled. Make PHP parser parse + "\\" correctly. Have jumpToLine work on + line handles, and add cursorLine function to fetch the + line handle where the cursor currently is. Add new + setStylesheet function to switch style-sheets in a + running editor.

+ +

01-03-2010: Version + 0.66:

+

Adds removeLine method to API. + Introduces the PLSQL parser. + Marks XML errors by adding (rather than replacing) a CSS class, so + that they can be disabled by modifying their style. Fixes several + selection bugs, and a number of small glitches.

+ +

12-11-2009: Version + 0.65:

+

Add support for having both line-wrapping and + line-numbers turned on, make paren-highlighting style customisable + (markParen and unmarkParen config + options), work around a selection bug that Opera + reintroduced in version 10.

+ +

23-10-2009: Version + 0.64:

+

Solves some issues introduced by the + paste-handling changes from the previous release. Adds + setSpellcheck, setTextWrapping, + setIndentUnit, setUndoDepth, + setTabMode, and setLineNumbers to + customise a running editor. Introduces an SQL parser. Fixes a few small + problems in the Python + parser. And, as usual, add workarounds for various newly discovered + browser incompatibilities.

+ +

31-08-2009: Version 0.63:

+

Overhaul of paste-handling (less fragile), fixes for several + serious IE8 issues (cursor jumping, end-of-document bugs) and a number + of small problems.

+ +

30-05-2009: Version 0.62:

+

Introduces Python + and Lua parsers. Add + setParser (on-the-fly mode changing) and + clearHistory methods. Make parsing passes time-based + instead of lines-based (see the passTime option).

+ +
+
diff --git a/backend/webif/static/codemirror/doc/reporting.html b/backend/webif/static/codemirror/doc/reporting.html new file mode 100755 index 000000000..1657400ce --- /dev/null +++ b/backend/webif/static/codemirror/doc/reporting.html @@ -0,0 +1,60 @@ + + +CodeMirror: Reporting Bugs + + + + + +
+ +

Reporting bugs effectively

+ +
+ +

So you found a problem in CodeMirror. By all means, report it! Bug +reports from users are the main drive behind improvements to +CodeMirror. But first, please read over these points:

+ +
    +
  1. CodeMirror is maintained by volunteers. They don't owe you + anything, so be polite. Reports with an indignant or belligerent + tone tend to be moved to the bottom of the pile.
  2. + +
  3. Include information about the browser in which the + problem occurred. Even if you tested several browsers, and + the problem occurred in all of them, mention this fact in the bug + report. Also include browser version numbers and the operating + system that you're on.
  4. + +
  5. Mention which release of CodeMirror you're using. Preferably, + try also with the current development snapshot, to ensure the + problem has not already been fixed.
  6. + +
  7. Mention very precisely what went wrong. "X is broken" is not a + good bug report. What did you expect to happen? What happened + instead? Describe the exact steps a maintainer has to take to reproduce + the error. We can not fix something that we can not observe.
  8. + +
  9. If the problem can not be reproduced in any of the demos + included in the CodeMirror distribution, please provide an HTML + document that demonstrates the problem. The best way to do this is + to go to jsbin.com, enter + it there, press save, and include the resulting link in your bug + report.
  10. +
+ +
+ +
diff --git a/backend/webif/static/codemirror/doc/upgrade_v2.2.html b/backend/webif/static/codemirror/doc/upgrade_v2.2.html new file mode 100755 index 000000000..3948ce6e5 --- /dev/null +++ b/backend/webif/static/codemirror/doc/upgrade_v2.2.html @@ -0,0 +1,96 @@ + + +CodeMirror: Version 2.2 upgrade guide + + + + + +
+ +

Upgrading to v2.2

+ +

There are a few things in the 2.2 release that require some care +when upgrading.

+ +

No more default.css

+ +

The default theme is now included +in codemirror.css, so +you do not have to included it separately anymore. (It was tiny, so +even if you're not using it, the extra data overhead is negligible.) + +

Different key customization

+ +

CodeMirror has moved to a system +where keymaps are used to +bind behavior to keys. This means custom +bindings are now possible.

+ +

Three options that influenced key +behavior, tabMode, enterMode, +and smartHome, are no longer supported. Instead, you can +provide custom bindings to influence the way these keys act. This is +done through the +new extraKeys +option, which can hold an object mapping key names to functionality. A +simple example would be:

+ +
  extraKeys: {
+    "Ctrl-S": function(instance) { saveText(instance.getValue()); },
+    "Ctrl-/": "undo"
+  }
+ +

Keys can be mapped either to functions, which will be given the +editor instance as argument, or to strings, which are mapped through +functions through the CodeMirror.commands table, which +contains all the built-in editing commands, and can be inspected and +extended by external code.

+ +

By default, the Home key is bound to +the "goLineStartSmart" command, which moves the cursor to +the first non-whitespace character on the line. You can set do this to +make it always go to the very start instead:

+ +
  extraKeys: {"Home": "goLineStart"}
+ +

Similarly, Enter is bound +to "newlineAndIndent" by default. You can bind it to +something else to get different behavior. To disable special handling +completely and only get a newline character inserted, you can bind it +to false:

+ +
  extraKeys: {"Enter": false}
+ +

The same works for Tab. If you don't want CodeMirror +to handle it, bind it to false. The default behaviour is +to indent the current line more ("indentMore" command), +and indent it less when shift is held ("indentLess"). +There are also "indentAuto" (smart indent) +and "insertTab" commands provided for alternate +behaviors. Or you can write your own handler function to do something +different altogether.

+ +

Tabs

+ +

Handling of tabs changed completely. The display width of tabs can +now be set with the tabSize option, and tabs can +be styled by setting CSS rules +for the cm-tab class.

+ +

The default width for tabs is now 4, as opposed to the 8 that is +hard-wired into browsers. If you are relying on 8-space tabs, make +sure you explicitly set tabSize: 8 in your options.

+ +
diff --git a/backend/webif/static/codemirror/doc/upgrade_v3.html b/backend/webif/static/codemirror/doc/upgrade_v3.html new file mode 100755 index 000000000..5f94067aa --- /dev/null +++ b/backend/webif/static/codemirror/doc/upgrade_v3.html @@ -0,0 +1,230 @@ + + +CodeMirror: Version 3 upgrade guide + + + + + + + + + + + + + + +
+ +

Upgrading to version 3

+ +

Version 3 does not depart too much from 2.x API, and sites that use +CodeMirror in a very simple way might be able to upgrade without +trouble. But it does introduce a number of incompatibilities. Please +at least skim this text before upgrading.

+ +

Note that version 3 drops full support for Internet +Explorer 7. The editor will mostly work on that browser, but +it'll be significantly glitchy.

+ +
+

DOM structure

+ +

This one is the most likely to cause problems. The internal +structure of the editor has changed quite a lot, mostly to implement a +new scrolling model.

+ +

Editor height is now set on the outer wrapper element (CSS +class CodeMirror), not on the scroller element +(CodeMirror-scroll).

+ +

Other nodes were moved, dropped, and added. If you have any code +that makes assumptions about the internal DOM structure of the editor, +you'll have to re-test it and probably update it to work with v3.

+ +

See the styling section of the +manual for more information.

+
+
+

Gutter model

+ +

In CodeMirror 2.x, there was a single gutter, and line markers +created with setMarker would have to somehow coexist with +the line numbers (if present). Version 3 allows you to specify an +array of gutters, by class +name, +use setGutterMarker +to add or remove markers in individual gutters, and clear whole +gutters +with clearGutter. +Gutter markers are now specified as DOM nodes, rather than HTML +snippets.

+ +

The gutters no longer horizontally scrolls along with the content. +The fixedGutter option was removed (since it is now the +only behavior).

+ +
+<style>
+  /* Define a gutter style */
+  .note-gutter { width: 3em; background: cyan; }
+</style>
+<script>
+  // Create an instance with two gutters -- line numbers and notes
+  var cm = new CodeMirror(document.body, {
+    gutters: ["note-gutter", "CodeMirror-linenumbers"],
+    lineNumbers: true
+  });
+  // Add a note to line 0
+  cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi"));
+</script>
+
+
+
+

Event handling

+ +

Most of the onXYZ options have been removed. The same +effect is now obtained by calling +the on method with a string +identifying the event type. Multiple handlers can now be registered +(and individually unregistered) for an event, and objects such as line +handlers now also expose events. See the +full list here.

+ +

(The onKeyEvent and onDragEvent options, +which act more as hooks than as event handlers, are still there in +their old form.)

+ +
+cm.on("change", function(cm, change) {
+  console.log("something changed! (" + change.origin + ")");
+});
+
+
+
+

markText method arguments

+ +

The markText method +(which has gained some interesting new features, such as creating +atomic and read-only spans, or replacing spans with widgets) no longer +takes the CSS class name as a separate argument, but makes it an +optional field in the options object instead.

+ +
+// Style first ten lines, and forbid the cursor from entering them
+cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, {
+  className: "magic-text",
+  inclusiveLeft: true,
+  atomic: true
+});
+
+
+
+

Line folding

+ +

The interface for hiding lines has been +removed. markText can +now be used to do the same in a more flexible and powerful way.

+ +

The folding script has been +updated to use the new interface, and should now be more robust.

+ +
+// Fold a range, replacing it with the text "??"
+var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, {
+  replacedWith: document.createTextNode("??"),
+  // Auto-unfold when cursor moves into the range
+  clearOnEnter: true
+});
+// Get notified when auto-unfolding
+CodeMirror.on(range, "clear", function() {
+  console.log("boom");
+});
+
+
+
+

Line CSS classes

+ +

The setLineClass method has been replaced +by addLineClass +and removeLineClass, +which allow more modular control over the classes attached to a line.

+ +
+var marked = cm.addLineClass(10, "background", "highlighted-line");
+setTimeout(function() {
+  cm.removeLineClass(marked, "background", "highlighted-line");
+});
+
+
+
+

Position properties

+ +

All methods that take or return objects that represent screen +positions now use {left, top, bottom, right} properties +(not always all of them) instead of the {x, y, yBot} used +by some methods in v2.x.

+ +

Affected methods +are cursorCoords, charCoords, coordsChar, +and getScrollInfo.

+
+
+

Bracket matching no longer in core

+ +

The matchBrackets +option is no longer defined in the core editor. +Load addon/edit/matchbrackets.js to enable it.

+
+
+

Mode management

+ +

The CodeMirror.listModes +and CodeMirror.listMIMEs functions, used for listing +defined modes, are gone. You are now encouraged to simply +inspect CodeMirror.modes (mapping mode names to mode +constructors) and CodeMirror.mimeModes (mapping MIME +strings to mode specs).

+
+
+

New features

+ +

Some more reasons to upgrade to version 3.

+ +
    +
  • Bi-directional text support. CodeMirror will now mostly do the + right thing when editing Arabic or Hebrew text.
  • +
  • Arbitrary line heights. Using fonts with different heights + inside the editor (whether off by one pixel or fifty) is now + supported and handled gracefully.
  • +
  • In-line widgets. See the demo + and the docs.
  • +
  • Defining custom options + with CodeMirror.defineOption.
  • +
+
+
+ + diff --git a/backend/webif/static/codemirror/doc/upgrade_v4.html b/backend/webif/static/codemirror/doc/upgrade_v4.html new file mode 100755 index 000000000..09df00ca1 --- /dev/null +++ b/backend/webif/static/codemirror/doc/upgrade_v4.html @@ -0,0 +1,144 @@ + + +CodeMirror: Version 4 upgrade guide + + + + + + +
+ +

Upgrading to version 4

+ +

CodeMirror 4's interface is very close version 3, but it +does fix a few awkward details in a backwards-incompatible ways. At +least skim the text below before upgrading.

+ +

Multiple selections

+ +

The main new feature in version 4 is multiple selections. The +single-selection variants of methods are still there, but now +typically act only on the primary selection (usually the last +one added).

+ +

The exception to this +is getSelection, +which will now return the content of all selections +(separated by newlines, or whatever lineSep parameter you passed +it).

+ +
+ +

The beforeSelectionChange event

+ +

This event still exists, but the object it is passed has +a completely new +interface, because such changes now concern multiple +selections.

+ +
+ +

replaceSelection's collapsing behavior

+ +

By +default, replaceSelection +would leave the newly inserted text selected. This is only rarely what +you want, and also (slightly) more expensive in the new model, so the +default was changed to "end", meaning the old behavior +must be explicitly specified by passing a second argument +of "around".

+ +
+ +

change event data

+ +

Rather than forcing client code to follow next +pointers from one change object to the next, the library will now +simply fire +multiple "change" +events. Existing code will probably continue to work unmodified.

+ +
+ +

showIfHidden option to line widgets

+ +

This option, which conceptually caused line widgets to be visible +even if their line was hidden, was never really well-defined, and was +buggy from the start. It would be a rather expensive feature, both in +code complexity and run-time performance, to implement properly. It +has been dropped entirely in 4.0.

+ +
+ +

Module loaders

+ +

All modules in the CodeMirror distribution are now wrapped in a +shim function to make them compatible with both AMD +(requirejs) and CommonJS (as used +by node +and browserify) module loaders. +When neither of these is present, they fall back to simply using the +global CodeMirror variable.

+ +

If you have a module loader present in your environment, CodeMirror +will attempt to use it, and you might need to change the way you load +CodeMirror modules.

+ +
+ +

Mutating shared data structures

+ +

Data structures produced by the library should not be mutated +unless explicitly allowed, in general. This is slightly more strict in +4.0 than it was in earlier versions, which copied the position objects +returned by getCursor +for nebulous, historic reasons. In 4.0, mutating these +objects will corrupt your editor's selection.

+ +
+ +

Deprecated interfaces dropped

+ +

A few properties and methods that have been deprecated for a while +are now gone. Most notably, the onKeyEvent +and onDragEvent options (use the +corresponding events instead).

+ +

Two silly methods, which were mostly there to stay close to the 0.x +API, setLine and removeLine are now gone. +Use the more +flexible replaceRange +method instead.

+ +

The long names for folding and completing functions +(CodeMirror.braceRangeFinder, CodeMirror.javascriptHint, +etc) are also gone +(use CodeMirror.fold.brace, CodeMirror.hint.javascript).

+ +

The className property in the return value +of getTokenAt, which +has been superseded by the type property, is also no +longer present.

+ +
+
diff --git a/backend/webif/static/codemirror/doc/yinyang.png b/backend/webif/static/codemirror/doc/yinyang.png new file mode 100755 index 000000000..2eafd3f1c Binary files /dev/null and b/backend/webif/static/codemirror/doc/yinyang.png differ diff --git a/backend/webif/static/codemirror/index.html b/backend/webif/static/codemirror/index.html new file mode 100755 index 000000000..d62ab84a3 --- /dev/null +++ b/backend/webif/static/codemirror/index.html @@ -0,0 +1,196 @@ + + +CodeMirror + + + + + + + + + + + + + + + + + +
+ +
+

CodeMirror is a versatile text editor + implemented in JavaScript for the browser. It is specialized for + editing code, and comes with a number of language modes and addons + that implement more advanced editing functionality.

+ +

A rich programming API and a + CSS theming system are + available for customizing CodeMirror to fit your application, and + extending it with new functionality.

+
+ +
+

This is CodeMirror

+
+
+ + +
+
+ + + +
+
+ Get the current version: 5.32.0.
+ You can see the code,
+ read the release notes,
+ or study the user manual. +
+
+ Software needs maintenance,
+ maintainers need to subsist.
+ Current funding status =
+ You can help per month or + once. +
+
+ +
+ +
+

Features

+ +
+ +
+

Community

+ +

CodeMirror is an open-source project shared under + an MIT license. It is the editor used in the + dev tools for + Firefox, + Chrome, + and Safari, in Light + Table, Adobe + Brackets, Bitbucket, + and many other projects.

+ +

Development and bug tracking happens + on github + (alternate git + repository). + Please read these + pointers before submitting a bug. Use pull requests to submit + patches. All contributions must be released under the same MIT + license that CodeMirror uses.

+ +

Discussion around the project is done on + a discussion forum. + Announcements related to the project, such as new versions, are + posted in the + forum's "announce" + category. If needed, you can + contact the maintainer + directly. We aim to be an inclusive, welcoming community. To make + that explicit, we have + a code of + conduct that applies to communication around the project.

+ +

A list of CodeMirror-related software that is not part of the + main distribution is maintained + on our + wiki. Feel free to add your project.

+
+ +
+

Browser support

+

The desktop versions of the following browsers, + in standards mode (HTML5 <!doctype html> + recommended) are supported:

+ + + + + + +
Firefoxversion 4 and up
Chromeany version
Safariversion 5.2 and up
Internet Explorer/Edgeversion 8 and up
Operaversion 9 and up
+

Support for modern mobile browsers is experimental. Recent + versions of the iOS browser and Chrome on Android should work + pretty well.

+
+ +
diff --git a/backend/webif/static/codemirror/keymap/emacs.js b/backend/webif/static/codemirror/keymap/emacs.js new file mode 100755 index 000000000..316045328 --- /dev/null +++ b/backend/webif/static/codemirror/keymap/emacs.js @@ -0,0 +1,416 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } + + // Kill 'ring' + + var killRing = []; + function addToRing(str) { + killRing.push(str); + if (killRing.length > 50) killRing.shift(); + } + function growRingTop(str) { + if (!killRing.length) return addToRing(str); + killRing[killRing.length - 1] += str; + } + function getFromRing(n) { return killRing[killRing.length - (n ? Math.min(n, 1) : 1)] || ""; } + function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); } + + var lastKill = null; + + function kill(cm, from, to, ring, text) { + if (text == null) text = cm.getRange(from, to); + + if (ring == "grow" && lastKill && lastKill.cm == cm && posEq(from, lastKill.pos) && cm.isClean(lastKill.gen)) + growRingTop(text); + else if (ring !== false) + addToRing(text); + cm.replaceRange("", from, to, "+delete"); + + if (ring == "grow") lastKill = {cm: cm, pos: from, gen: cm.changeGeneration()}; + else lastKill = null; + } + + // Boundaries of various units + + function byChar(cm, pos, dir) { + return cm.findPosH(pos, dir, "char", true); + } + + function byWord(cm, pos, dir) { + return cm.findPosH(pos, dir, "word", true); + } + + function byLine(cm, pos, dir) { + return cm.findPosV(pos, dir, "line", cm.doc.sel.goalColumn); + } + + function byPage(cm, pos, dir) { + return cm.findPosV(pos, dir, "page", cm.doc.sel.goalColumn); + } + + function byParagraph(cm, pos, dir) { + var no = pos.line, line = cm.getLine(no); + var sawText = /\S/.test(dir < 0 ? line.slice(0, pos.ch) : line.slice(pos.ch)); + var fst = cm.firstLine(), lst = cm.lastLine(); + for (;;) { + no += dir; + if (no < fst || no > lst) + return cm.clipPos(Pos(no - dir, dir < 0 ? 0 : null)); + line = cm.getLine(no); + var hasText = /\S/.test(line); + if (hasText) sawText = true; + else if (sawText) return Pos(no, 0); + } + } + + function bySentence(cm, pos, dir) { + var line = pos.line, ch = pos.ch; + var text = cm.getLine(pos.line), sawWord = false; + for (;;) { + var next = text.charAt(ch + (dir < 0 ? -1 : 0)); + if (!next) { // End/beginning of line reached + if (line == (dir < 0 ? cm.firstLine() : cm.lastLine())) return Pos(line, ch); + text = cm.getLine(line + dir); + if (!/\S/.test(text)) return Pos(line, ch); + line += dir; + ch = dir < 0 ? text.length : 0; + continue; + } + if (sawWord && /[!?.]/.test(next)) return Pos(line, ch + (dir > 0 ? 1 : 0)); + if (!sawWord) sawWord = /\w/.test(next); + ch += dir; + } + } + + function byExpr(cm, pos, dir) { + var wrap; + if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, {strict: true})) + && wrap.match && (wrap.forward ? 1 : -1) == dir) + return dir > 0 ? Pos(wrap.to.line, wrap.to.ch + 1) : wrap.to; + + for (var first = true;; first = false) { + var token = cm.getTokenAt(pos); + var after = Pos(pos.line, dir < 0 ? token.start : token.end); + if (first && dir > 0 && token.end == pos.ch || !/\w/.test(token.string)) { + var newPos = cm.findPosH(after, dir, "char"); + if (posEq(after, newPos)) return pos; + else pos = newPos; + } else { + return after; + } + } + } + + // Prefixes (only crudely supported) + + function getPrefix(cm, precise) { + var digits = cm.state.emacsPrefix; + if (!digits) return precise ? null : 1; + clearPrefix(cm); + return digits == "-" ? -1 : Number(digits); + } + + function repeated(cmd) { + var f = typeof cmd == "string" ? function(cm) { cm.execCommand(cmd); } : cmd; + return function(cm) { + var prefix = getPrefix(cm); + f(cm); + for (var i = 1; i < prefix; ++i) f(cm); + }; + } + + function findEnd(cm, pos, by, dir) { + var prefix = getPrefix(cm); + if (prefix < 0) { dir = -dir; prefix = -prefix; } + for (var i = 0; i < prefix; ++i) { + var newPos = by(cm, pos, dir); + if (posEq(newPos, pos)) break; + pos = newPos; + } + return pos; + } + + function move(by, dir) { + var f = function(cm) { + cm.extendSelection(findEnd(cm, cm.getCursor(), by, dir)); + }; + f.motion = true; + return f; + } + + function killTo(cm, by, dir, ring) { + var selections = cm.listSelections(), cursor; + var i = selections.length; + while (i--) { + cursor = selections[i].head; + kill(cm, cursor, findEnd(cm, cursor, by, dir), ring); + } + } + + function killRegion(cm, ring) { + if (cm.somethingSelected()) { + var selections = cm.listSelections(), selection; + var i = selections.length; + while (i--) { + selection = selections[i]; + kill(cm, selection.anchor, selection.head, ring); + } + return true; + } + } + + function addPrefix(cm, digit) { + if (cm.state.emacsPrefix) { + if (digit != "-") cm.state.emacsPrefix += digit; + return; + } + // Not active yet + cm.state.emacsPrefix = digit; + cm.on("keyHandled", maybeClearPrefix); + cm.on("inputRead", maybeDuplicateInput); + } + + var prefixPreservingKeys = {"Alt-G": true, "Ctrl-X": true, "Ctrl-Q": true, "Ctrl-U": true}; + + function maybeClearPrefix(cm, arg) { + if (!cm.state.emacsPrefixMap && !prefixPreservingKeys.hasOwnProperty(arg)) + clearPrefix(cm); + } + + function clearPrefix(cm) { + cm.state.emacsPrefix = null; + cm.off("keyHandled", maybeClearPrefix); + cm.off("inputRead", maybeDuplicateInput); + } + + function maybeDuplicateInput(cm, event) { + var dup = getPrefix(cm); + if (dup > 1 && event.origin == "+input") { + var one = event.text.join("\n"), txt = ""; + for (var i = 1; i < dup; ++i) txt += one; + cm.replaceSelection(txt); + } + } + + function addPrefixMap(cm) { + cm.state.emacsPrefixMap = true; + cm.addKeyMap(prefixMap); + cm.on("keyHandled", maybeRemovePrefixMap); + cm.on("inputRead", maybeRemovePrefixMap); + } + + function maybeRemovePrefixMap(cm, arg) { + if (typeof arg == "string" && (/^\d$/.test(arg) || arg == "Ctrl-U")) return; + cm.removeKeyMap(prefixMap); + cm.state.emacsPrefixMap = false; + cm.off("keyHandled", maybeRemovePrefixMap); + cm.off("inputRead", maybeRemovePrefixMap); + } + + // Utilities + + function setMark(cm) { + cm.setCursor(cm.getCursor()); + cm.setExtending(!cm.getExtending()); + cm.on("change", function() { cm.setExtending(false); }); + } + + function clearMark(cm) { + cm.setExtending(false); + cm.setCursor(cm.getCursor()); + } + + function getInput(cm, msg, f) { + if (cm.openDialog) + cm.openDialog(msg + ": ", f, {bottom: true}); + else + f(prompt(msg, "")); + } + + function operateOnWord(cm, op) { + var start = cm.getCursor(), end = cm.findPosH(start, 1, "word"); + cm.replaceRange(op(cm.getRange(start, end)), start, end); + cm.setCursor(end); + } + + function toEnclosingExpr(cm) { + var pos = cm.getCursor(), line = pos.line, ch = pos.ch; + var stack = []; + while (line >= cm.firstLine()) { + var text = cm.getLine(line); + for (var i = ch == null ? text.length : ch; i > 0;) { + var ch = text.charAt(--i); + if (ch == ")") + stack.push("("); + else if (ch == "]") + stack.push("["); + else if (ch == "}") + stack.push("{"); + else if (/[\(\{\[]/.test(ch) && (!stack.length || stack.pop() != ch)) + return cm.extendSelection(Pos(line, i)); + } + --line; ch = null; + } + } + + function quit(cm) { + cm.execCommand("clearSearch"); + clearMark(cm); + } + + CodeMirror.emacs = {kill: kill, killRegion: killRegion, repeated: repeated}; + + // Actual keymap + + var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({ + "Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"), true);}, + "Ctrl-K": repeated(function(cm) { + var start = cm.getCursor(), end = cm.clipPos(Pos(start.line)); + var text = cm.getRange(start, end); + if (!/\S/.test(text)) { + text += "\n"; + end = Pos(start.line + 1, 0); + } + kill(cm, start, end, "grow", text); + }), + "Alt-W": function(cm) { + addToRing(cm.getSelection()); + clearMark(cm); + }, + "Ctrl-Y": function(cm) { + var start = cm.getCursor(); + cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste"); + cm.setSelection(start, cm.getCursor()); + }, + "Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");}, + + "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark, + + "Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1), + "Right": move(byChar, 1), "Left": move(byChar, -1), + "Ctrl-D": function(cm) { killTo(cm, byChar, 1, false); }, + "Delete": function(cm) { killRegion(cm, false) || killTo(cm, byChar, 1, false); }, + "Ctrl-H": function(cm) { killTo(cm, byChar, -1, false); }, + "Backspace": function(cm) { killRegion(cm, false) || killTo(cm, byChar, -1, false); }, + + "Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1), + "Alt-D": function(cm) { killTo(cm, byWord, 1, "grow"); }, + "Alt-Backspace": function(cm) { killTo(cm, byWord, -1, "grow"); }, + + "Ctrl-N": move(byLine, 1), "Ctrl-P": move(byLine, -1), + "Down": move(byLine, 1), "Up": move(byLine, -1), + "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "End": "goLineEnd", "Home": "goLineStart", + + "Alt-V": move(byPage, -1), "Ctrl-V": move(byPage, 1), + "PageUp": move(byPage, -1), "PageDown": move(byPage, 1), + + "Ctrl-Up": move(byParagraph, -1), "Ctrl-Down": move(byParagraph, 1), + + "Alt-A": move(bySentence, -1), "Alt-E": move(bySentence, 1), + "Alt-K": function(cm) { killTo(cm, bySentence, 1, "grow"); }, + + "Ctrl-Alt-K": function(cm) { killTo(cm, byExpr, 1, "grow"); }, + "Ctrl-Alt-Backspace": function(cm) { killTo(cm, byExpr, -1, "grow"); }, + "Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1, "grow"), + + "Shift-Ctrl-Alt-2": function(cm) { + var cursor = cm.getCursor(); + cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor); + }, + "Ctrl-Alt-T": function(cm) { + var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1); + var rightEnd = byExpr(cm, leftEnd, 1), rightStart = byExpr(cm, rightEnd, -1); + cm.replaceRange(cm.getRange(rightStart, rightEnd) + cm.getRange(leftEnd, rightStart) + + cm.getRange(leftStart, leftEnd), leftStart, rightEnd); + }, + "Ctrl-Alt-U": repeated(toEnclosingExpr), + + "Alt-Space": function(cm) { + var pos = cm.getCursor(), from = pos.ch, to = pos.ch, text = cm.getLine(pos.line); + while (from && /\s/.test(text.charAt(from - 1))) --from; + while (to < text.length && /\s/.test(text.charAt(to))) ++to; + cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to)); + }, + "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }), + "Ctrl-T": repeated(function(cm) { + cm.execCommand("transposeChars"); + }), + + "Alt-C": repeated(function(cm) { + operateOnWord(cm, function(w) { + var letter = w.search(/\w/); + if (letter == -1) return w; + return w.slice(0, letter) + w.charAt(letter).toUpperCase() + w.slice(letter + 1).toLowerCase(); + }); + }), + "Alt-U": repeated(function(cm) { + operateOnWord(cm, function(w) { return w.toUpperCase(); }); + }), + "Alt-L": repeated(function(cm) { + operateOnWord(cm, function(w) { return w.toLowerCase(); }); + }), + + "Alt-;": "toggleComment", + + "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"), + "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"), + "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd", + "Ctrl-S": "findPersistentNext", "Ctrl-R": "findPersistentPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace", + "Alt-/": "autocomplete", + "Enter": "newlineAndIndent", + "Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }), + "Tab": "indentAuto", + + "Alt-G G": function(cm) { + var prefix = getPrefix(cm, true); + if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1); + + getInput(cm, "Goto line", function(str) { + var num; + if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0) + cm.setCursor(num - 1); + }); + }, + + "Ctrl-X Tab": function(cm) { + cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit")); + }, + "Ctrl-X Ctrl-X": function(cm) { + cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor")); + }, + "Ctrl-X Ctrl-S": "save", + "Ctrl-X Ctrl-W": "save", + "Ctrl-X S": "saveAll", + "Ctrl-X F": "open", + "Ctrl-X U": repeated("undo"), + "Ctrl-X K": "close", + "Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), "grow"); }, + "Ctrl-X H": "selectAll", + + "Ctrl-Q Tab": repeated("insertTab"), + "Ctrl-U": addPrefixMap + }); + + var prefixMap = {"Ctrl-G": clearPrefix}; + function regPrefix(d) { + prefixMap[d] = function(cm) { addPrefix(cm, d); }; + keyMap["Ctrl-" + d] = function(cm) { addPrefix(cm, d); }; + prefixPreservingKeys["Ctrl-" + d] = true; + } + for (var i = 0; i < 10; ++i) regPrefix(String(i)); + regPrefix("-"); +}); diff --git a/backend/webif/static/codemirror/keymap/sublime.js b/backend/webif/static/codemirror/keymap/sublime.js new file mode 100755 index 000000000..08c9ebfb3 --- /dev/null +++ b/backend/webif/static/codemirror/keymap/sublime.js @@ -0,0 +1,704 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// A rough approximation of Sublime Text's keybindings +// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/edit/matchbrackets")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/edit/matchbrackets"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var cmds = CodeMirror.commands; + var Pos = CodeMirror.Pos; + + // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that. + function findPosSubword(doc, start, dir) { + if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1)); + var line = doc.getLine(start.line); + if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0)); + var state = "start", type; + for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) { + var next = line.charAt(dir < 0 ? pos - 1 : pos); + var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o"; + if (cat == "w" && next.toUpperCase() == next) cat = "W"; + if (state == "start") { + if (cat != "o") { state = "in"; type = cat; } + } else if (state == "in") { + if (type != cat) { + if (type == "w" && cat == "W" && dir < 0) pos--; + if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; } + break; + } + } + } + return Pos(start.line, pos); + } + + function moveSubword(cm, dir) { + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosSubword(cm.doc, range.head, dir); + else + return dir < 0 ? range.from() : range.to(); + }); + } + + cmds.goSubwordLeft = function(cm) { moveSubword(cm, -1); }; + cmds.goSubwordRight = function(cm) { moveSubword(cm, 1); }; + + cmds.scrollLineUp = function(cm) { + var info = cm.getScrollInfo(); + if (!cm.somethingSelected()) { + var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local"); + if (cm.getCursor().line >= visibleBottomLine) + cm.execCommand("goLineUp"); + } + cm.scrollTo(null, info.top - cm.defaultTextHeight()); + }; + cmds.scrollLineDown = function(cm) { + var info = cm.getScrollInfo(); + if (!cm.somethingSelected()) { + var visibleTopLine = cm.lineAtHeight(info.top, "local")+1; + if (cm.getCursor().line <= visibleTopLine) + cm.execCommand("goLineDown"); + } + cm.scrollTo(null, info.top + cm.defaultTextHeight()); + }; + + cmds.splitSelectionByLine = function(cm) { + var ranges = cm.listSelections(), lineRanges = []; + for (var i = 0; i < ranges.length; i++) { + var from = ranges[i].from(), to = ranges[i].to(); + for (var line = from.line; line <= to.line; ++line) + if (!(to.line > from.line && line == to.line && to.ch == 0)) + lineRanges.push({anchor: line == from.line ? from : Pos(line, 0), + head: line == to.line ? to : Pos(line)}); + } + cm.setSelections(lineRanges, 0); + }; + + cmds.singleSelectionTop = function(cm) { + var range = cm.listSelections()[0]; + cm.setSelection(range.anchor, range.head, {scroll: false}); + }; + + cmds.selectLine = function(cm) { + var ranges = cm.listSelections(), extended = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + extended.push({anchor: Pos(range.from().line, 0), + head: Pos(range.to().line + 1, 0)}); + } + cm.setSelections(extended); + }; + + function insertLine(cm, above) { + if (cm.isReadOnly()) return CodeMirror.Pass + cm.operation(function() { + var len = cm.listSelections().length, newSelection = [], last = -1; + for (var i = 0; i < len; i++) { + var head = cm.listSelections()[i].head; + if (head.line <= last) continue; + var at = Pos(head.line + (above ? 0 : 1), 0); + cm.replaceRange("\n", at, null, "+insertLine"); + cm.indentLine(at.line, null, true); + newSelection.push({head: at, anchor: at}); + last = head.line + 1; + } + cm.setSelections(newSelection); + }); + cm.execCommand("indentAuto"); + } + + cmds.insertLineAfter = function(cm) { return insertLine(cm, false); }; + + cmds.insertLineBefore = function(cm) { return insertLine(cm, true); }; + + function wordAt(cm, pos) { + var start = pos.ch, end = start, line = cm.getLine(pos.line); + while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start; + while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end; + return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)}; + } + + cmds.selectNextOccurrence = function(cm) { + var from = cm.getCursor("from"), to = cm.getCursor("to"); + var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel; + if (CodeMirror.cmpPos(from, to) == 0) { + var word = wordAt(cm, from); + if (!word.word) return; + cm.setSelection(word.from, word.to); + fullWord = true; + } else { + var text = cm.getRange(from, to); + var query = fullWord ? new RegExp("\\b" + text + "\\b") : text; + var cur = cm.getSearchCursor(query, to); + var found = cur.findNext(); + if (!found) { + cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0)); + found = cur.findNext(); + } + if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to())) + return CodeMirror.Pass + cm.addSelection(cur.from(), cur.to()); + } + if (fullWord) + cm.state.sublimeFindFullWord = cm.doc.sel; + }; + + function addCursorToSelection(cm, dir) { + var ranges = cm.listSelections(), newRanges = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var newAnchor = cm.findPosV(range.anchor, dir, "line"); + var newHead = cm.findPosV(range.head, dir, "line"); + var newRange = {anchor: newAnchor, head: newHead}; + newRanges.push(range); + newRanges.push(newRange); + } + cm.setSelections(newRanges); + } + cmds.addCursorToPrevLine = function(cm) { addCursorToSelection(cm, -1); }; + cmds.addCursorToNextLine = function(cm) { addCursorToSelection(cm, 1); }; + + function isSelectedRange(ranges, from, to) { + for (var i = 0; i < ranges.length; i++) + if (ranges[i].from() == from && ranges[i].to() == to) return true + return false + } + + var mirror = "(){}[]"; + function selectBetweenBrackets(cm) { + var ranges = cm.listSelections(), newRanges = [] + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], pos = range.head, opening = cm.scanForBracket(pos, -1); + if (!opening) return false; + for (;;) { + var closing = cm.scanForBracket(pos, 1); + if (!closing) return false; + if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) { + newRanges.push({anchor: Pos(opening.pos.line, opening.pos.ch + 1), + head: closing.pos}); + break; + } + pos = Pos(closing.pos.line, closing.pos.ch + 1); + } + } + cm.setSelections(newRanges); + return true; + } + + cmds.selectScope = function(cm) { + selectBetweenBrackets(cm) || cm.execCommand("selectAll"); + }; + cmds.selectBetweenBrackets = function(cm) { + if (!selectBetweenBrackets(cm)) return CodeMirror.Pass; + }; + + cmds.goToBracket = function(cm) { + cm.extendSelectionsBy(function(range) { + var next = cm.scanForBracket(range.head, 1); + if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos; + var prev = cm.scanForBracket(range.head, -1); + return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head; + }); + }; + + cmds.swapLineUp = function(cm) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], from = range.from().line - 1, to = range.to().line; + newSels.push({anchor: Pos(range.anchor.line - 1, range.anchor.ch), + head: Pos(range.head.line - 1, range.head.ch)}); + if (range.to().ch == 0 && !range.empty()) --to; + if (from > at) linesToMove.push(from, to); + else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; + at = to; + } + cm.operation(function() { + for (var i = 0; i < linesToMove.length; i += 2) { + var from = linesToMove[i], to = linesToMove[i + 1]; + var line = cm.getLine(from); + cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); + if (to > cm.lastLine()) + cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine"); + else + cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); + } + cm.setSelections(newSels); + cm.scrollIntoView(); + }); + }; + + cmds.swapLineDown = function(cm) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1; + for (var i = ranges.length - 1; i >= 0; i--) { + var range = ranges[i], from = range.to().line + 1, to = range.from().line; + if (range.to().ch == 0 && !range.empty()) from--; + if (from < at) linesToMove.push(from, to); + else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; + at = to; + } + cm.operation(function() { + for (var i = linesToMove.length - 2; i >= 0; i -= 2) { + var from = linesToMove[i], to = linesToMove[i + 1]; + var line = cm.getLine(from); + if (from == cm.lastLine()) + cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine"); + else + cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); + cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); + } + cm.scrollIntoView(); + }); + }; + + cmds.toggleCommentIndented = function(cm) { + cm.toggleComment({ indent: true }); + } + + cmds.joinLines = function(cm) { + var ranges = cm.listSelections(), joined = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], from = range.from(); + var start = from.line, end = range.to().line; + while (i < ranges.length - 1 && ranges[i + 1].from().line == end) + end = ranges[++i].to().line; + joined.push({start: start, end: end, anchor: !range.empty() && from}); + } + cm.operation(function() { + var offset = 0, ranges = []; + for (var i = 0; i < joined.length; i++) { + var obj = joined[i]; + var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head; + for (var line = obj.start; line <= obj.end; line++) { + var actual = line - offset; + if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1); + if (actual < cm.lastLine()) { + cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length)); + ++offset; + } + } + ranges.push({anchor: anchor || head, head: head}); + } + cm.setSelections(ranges, 0); + }); + }; + + cmds.duplicateLine = function(cm) { + cm.operation(function() { + var rangeCount = cm.listSelections().length; + for (var i = 0; i < rangeCount; i++) { + var range = cm.listSelections()[i]; + if (range.empty()) + cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0)); + else + cm.replaceRange(cm.getRange(range.from(), range.to()), range.from()); + } + cm.scrollIntoView(); + }); + }; + + + function sortLines(cm, caseSensitive) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), toSort = [], selected; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.empty()) continue; + var from = range.from().line, to = range.to().line; + while (i < ranges.length - 1 && ranges[i + 1].from().line == to) + to = ranges[++i].to().line; + if (!ranges[i].to().ch) to--; + toSort.push(from, to); + } + if (toSort.length) selected = true; + else toSort.push(cm.firstLine(), cm.lastLine()); + + cm.operation(function() { + var ranges = []; + for (var i = 0; i < toSort.length; i += 2) { + var from = toSort[i], to = toSort[i + 1]; + var start = Pos(from, 0), end = Pos(to); + var lines = cm.getRange(start, end, false); + if (caseSensitive) + lines.sort(); + else + lines.sort(function(a, b) { + var au = a.toUpperCase(), bu = b.toUpperCase(); + if (au != bu) { a = au; b = bu; } + return a < b ? -1 : a == b ? 0 : 1; + }); + cm.replaceRange(lines, start, end); + if (selected) ranges.push({anchor: start, head: Pos(to + 1, 0)}); + } + if (selected) cm.setSelections(ranges, 0); + }); + } + + cmds.sortLines = function(cm) { sortLines(cm, true); }; + cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); }; + + cmds.nextBookmark = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) while (marks.length) { + var current = marks.shift(); + var found = current.find(); + if (found) { + marks.push(current); + return cm.setSelection(found.from, found.to); + } + } + }; + + cmds.prevBookmark = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) while (marks.length) { + marks.unshift(marks.pop()); + var found = marks[marks.length - 1].find(); + if (!found) + marks.pop(); + else + return cm.setSelection(found.from, found.to); + } + }; + + cmds.toggleBookmark = function(cm) { + var ranges = cm.listSelections(); + var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []); + for (var i = 0; i < ranges.length; i++) { + var from = ranges[i].from(), to = ranges[i].to(); + var found = cm.findMarks(from, to); + for (var j = 0; j < found.length; j++) { + if (found[j].sublimeBookmark) { + found[j].clear(); + for (var k = 0; k < marks.length; k++) + if (marks[k] == found[j]) + marks.splice(k--, 1); + break; + } + } + if (j == found.length) + marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false})); + } + }; + + cmds.clearBookmarks = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear(); + marks.length = 0; + }; + + cmds.selectBookmarks = function(cm) { + var marks = cm.state.sublimeBookmarks, ranges = []; + if (marks) for (var i = 0; i < marks.length; i++) { + var found = marks[i].find(); + if (!found) + marks.splice(i--, 0); + else + ranges.push({anchor: found.from, head: found.to}); + } + if (ranges.length) + cm.setSelections(ranges, 0); + }; + + function modifyWordOrSelection(cm, mod) { + cm.operation(function() { + var ranges = cm.listSelections(), indices = [], replacements = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.empty()) { indices.push(i); replacements.push(""); } + else replacements.push(mod(cm.getRange(range.from(), range.to()))); + } + cm.replaceSelections(replacements, "around", "case"); + for (var i = indices.length - 1, at; i >= 0; i--) { + var range = ranges[indices[i]]; + if (at && CodeMirror.cmpPos(range.head, at) > 0) continue; + var word = wordAt(cm, range.head); + at = word.from; + cm.replaceRange(mod(word.word), word.from, word.to); + } + }); + } + + cmds.smartBackspace = function(cm) { + if (cm.somethingSelected()) return CodeMirror.Pass; + + cm.operation(function() { + var cursors = cm.listSelections(); + var indentUnit = cm.getOption("indentUnit"); + + for (var i = cursors.length - 1; i >= 0; i--) { + var cursor = cursors[i].head; + var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor); + var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize")); + + // Delete by one character by default + var deletePos = cm.findPosH(cursor, -1, "char", false); + + if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) { + var prevIndent = new Pos(cursor.line, + CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit)); + + // Smart delete only if we found a valid prevIndent location + if (prevIndent.ch != cursor.ch) deletePos = prevIndent; + } + + cm.replaceRange("", deletePos, cursor, "+delete"); + } + }); + }; + + cmds.delLineRight = function(cm) { + cm.operation(function() { + var ranges = cm.listSelections(); + for (var i = ranges.length - 1; i >= 0; i--) + cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete"); + cm.scrollIntoView(); + }); + }; + + cmds.upcaseAtCursor = function(cm) { + modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); }); + }; + cmds.downcaseAtCursor = function(cm) { + modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); }); + }; + + cmds.setSublimeMark = function(cm) { + if (cm.state.sublimeMark) cm.state.sublimeMark.clear(); + cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); + }; + cmds.selectToSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) cm.setSelection(cm.getCursor(), found); + }; + cmds.deleteToSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) { + var from = cm.getCursor(), to = found; + if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; } + cm.state.sublimeKilled = cm.getRange(from, to); + cm.replaceRange("", from, to); + } + }; + cmds.swapWithSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) { + cm.state.sublimeMark.clear(); + cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); + cm.setCursor(found); + } + }; + cmds.sublimeYank = function(cm) { + if (cm.state.sublimeKilled != null) + cm.replaceSelection(cm.state.sublimeKilled, null, "paste"); + }; + + cmds.showInCenter = function(cm) { + var pos = cm.cursorCoords(null, "local"); + cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2); + }; + + cmds.selectLinesUpward = function(cm) { + cm.operation(function() { + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.head.line > cm.firstLine()) + cm.addSelection(Pos(range.head.line - 1, range.head.ch)); + } + }); + }; + cmds.selectLinesDownward = function(cm) { + cm.operation(function() { + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.head.line < cm.lastLine()) + cm.addSelection(Pos(range.head.line + 1, range.head.ch)); + } + }); + }; + + function getTarget(cm) { + var from = cm.getCursor("from"), to = cm.getCursor("to"); + if (CodeMirror.cmpPos(from, to) == 0) { + var word = wordAt(cm, from); + if (!word.word) return; + from = word.from; + to = word.to; + } + return {from: from, to: to, query: cm.getRange(from, to), word: word}; + } + + function findAndGoTo(cm, forward) { + var target = getTarget(cm); + if (!target) return; + var query = target.query; + var cur = cm.getSearchCursor(query, forward ? target.to : target.from); + + if (forward ? cur.findNext() : cur.findPrevious()) { + cm.setSelection(cur.from(), cur.to()); + } else { + cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0) + : cm.clipPos(Pos(cm.lastLine()))); + if (forward ? cur.findNext() : cur.findPrevious()) + cm.setSelection(cur.from(), cur.to()); + else if (target.word) + cm.setSelection(target.from, target.to); + } + }; + cmds.findUnder = function(cm) { findAndGoTo(cm, true); }; + cmds.findUnderPrevious = function(cm) { findAndGoTo(cm,false); }; + cmds.findAllUnder = function(cm) { + var target = getTarget(cm); + if (!target) return; + var cur = cm.getSearchCursor(target.query); + var matches = []; + var primaryIndex = -1; + while (cur.findNext()) { + matches.push({anchor: cur.from(), head: cur.to()}); + if (cur.from().line <= target.from.line && cur.from().ch <= target.from.ch) + primaryIndex++; + } + cm.setSelections(matches, primaryIndex); + }; + + + var keyMap = CodeMirror.keyMap; + keyMap.macSublime = { + "Cmd-Left": "goLineStartSmart", + "Shift-Tab": "indentLess", + "Shift-Ctrl-K": "deleteLine", + "Alt-Q": "wrapLines", + "Ctrl-Left": "goSubwordLeft", + "Ctrl-Right": "goSubwordRight", + "Ctrl-Alt-Up": "scrollLineUp", + "Ctrl-Alt-Down": "scrollLineDown", + "Cmd-L": "selectLine", + "Shift-Cmd-L": "splitSelectionByLine", + "Esc": "singleSelectionTop", + "Cmd-Enter": "insertLineAfter", + "Shift-Cmd-Enter": "insertLineBefore", + "Cmd-D": "selectNextOccurrence", + "Shift-Cmd-Up": "addCursorToPrevLine", + "Shift-Cmd-Down": "addCursorToNextLine", + "Shift-Cmd-Space": "selectScope", + "Shift-Cmd-M": "selectBetweenBrackets", + "Cmd-M": "goToBracket", + "Cmd-Ctrl-Up": "swapLineUp", + "Cmd-Ctrl-Down": "swapLineDown", + "Cmd-/": "toggleCommentIndented", + "Cmd-J": "joinLines", + "Shift-Cmd-D": "duplicateLine", + "F9": "sortLines", + "Cmd-F9": "sortLinesInsensitive", + "F2": "nextBookmark", + "Shift-F2": "prevBookmark", + "Cmd-F2": "toggleBookmark", + "Shift-Cmd-F2": "clearBookmarks", + "Alt-F2": "selectBookmarks", + "Backspace": "smartBackspace", + "Cmd-K Cmd-K": "delLineRight", + "Cmd-K Cmd-U": "upcaseAtCursor", + "Cmd-K Cmd-L": "downcaseAtCursor", + "Cmd-K Cmd-Space": "setSublimeMark", + "Cmd-K Cmd-A": "selectToSublimeMark", + "Cmd-K Cmd-W": "deleteToSublimeMark", + "Cmd-K Cmd-X": "swapWithSublimeMark", + "Cmd-K Cmd-Y": "sublimeYank", + "Cmd-K Cmd-C": "showInCenter", + "Cmd-K Cmd-G": "clearBookmarks", + "Cmd-K Cmd-Backspace": "delLineLeft", + "Cmd-K Cmd-0": "unfoldAll", + "Cmd-K Cmd-J": "unfoldAll", + "Ctrl-Shift-Up": "selectLinesUpward", + "Ctrl-Shift-Down": "selectLinesDownward", + "Cmd-F3": "findUnder", + "Shift-Cmd-F3": "findUnderPrevious", + "Alt-F3": "findAllUnder", + "Shift-Cmd-[": "fold", + "Shift-Cmd-]": "unfold", + "Cmd-I": "findIncremental", + "Shift-Cmd-I": "findIncrementalReverse", + "Cmd-H": "replace", + "F3": "findNext", + "Shift-F3": "findPrev", + "fallthrough": "macDefault" + }; + CodeMirror.normalizeKeyMap(keyMap.macSublime); + + keyMap.pcSublime = { + "Shift-Tab": "indentLess", + "Shift-Ctrl-K": "deleteLine", + "Alt-Q": "wrapLines", + "Ctrl-T": "transposeChars", + "Alt-Left": "goSubwordLeft", + "Alt-Right": "goSubwordRight", + "Ctrl-Up": "scrollLineUp", + "Ctrl-Down": "scrollLineDown", + "Ctrl-L": "selectLine", + "Shift-Ctrl-L": "splitSelectionByLine", + "Esc": "singleSelectionTop", + "Ctrl-Enter": "insertLineAfter", + "Shift-Ctrl-Enter": "insertLineBefore", + "Ctrl-D": "selectNextOccurrence", + "Alt-CtrlUp": "addCursorToPrevLine", + "Alt-CtrlDown": "addCursorToNextLine", + "Shift-Ctrl-Space": "selectScope", + "Shift-Ctrl-M": "selectBetweenBrackets", + "Ctrl-M": "goToBracket", + "Shift-Ctrl-Up": "swapLineUp", + "Shift-Ctrl-Down": "swapLineDown", + "Ctrl-/": "toggleCommentIndented", + "Ctrl-J": "joinLines", + "Shift-Ctrl-D": "duplicateLine", + "F9": "sortLines", + "Ctrl-F9": "sortLinesInsensitive", + "F2": "nextBookmark", + "Shift-F2": "prevBookmark", + "Ctrl-F2": "toggleBookmark", + "Shift-Ctrl-F2": "clearBookmarks", + "Alt-F2": "selectBookmarks", + "Backspace": "smartBackspace", + "Ctrl-K Ctrl-K": "delLineRight", + "Ctrl-K Ctrl-U": "upcaseAtCursor", + "Ctrl-K Ctrl-L": "downcaseAtCursor", + "Ctrl-K Ctrl-Space": "setSublimeMark", + "Ctrl-K Ctrl-A": "selectToSublimeMark", + "Ctrl-K Ctrl-W": "deleteToSublimeMark", + "Ctrl-K Ctrl-X": "swapWithSublimeMark", + "Ctrl-K Ctrl-Y": "sublimeYank", + "Ctrl-K Ctrl-C": "showInCenter", + "Ctrl-K Ctrl-G": "clearBookmarks", + "Ctrl-K Ctrl-Backspace": "delLineLeft", + "Ctrl-K Ctrl-0": "unfoldAll", + "Ctrl-K Ctrl-J": "unfoldAll", + "Ctrl-Alt-Up": "selectLinesUpward", + "Ctrl-Alt-Down": "selectLinesDownward", + "Ctrl-F3": "findUnder", + "Shift-Ctrl-F3": "findUnderPrevious", + "Alt-F3": "findAllUnder", + "Shift-Ctrl-[": "fold", + "Shift-Ctrl-]": "unfold", + "Ctrl-I": "findIncremental", + "Shift-Ctrl-I": "findIncrementalReverse", + "Ctrl-H": "replace", + "F3": "findNext", + "Shift-F3": "findPrev", + "fallthrough": "pcDefault" + }; + CodeMirror.normalizeKeyMap(keyMap.pcSublime); + + var mac = keyMap.default == keyMap.macDefault; + keyMap.sublime = mac ? keyMap.macSublime : keyMap.pcSublime; +}); diff --git a/backend/webif/static/codemirror/keymap/vim.js b/backend/webif/static/codemirror/keymap/vim.js new file mode 100755 index 000000000..7cf5a956e --- /dev/null +++ b/backend/webif/static/codemirror/keymap/vim.js @@ -0,0 +1,5212 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Supported keybindings: + * Too many to list. Refer to defaultKeyMap below. + * + * Supported Ex commands: + * Refer to defaultExCommandMap below. + * + * Registers: unnamed, -, a-z, A-Z, 0-9 + * (Does not respect the special case for number registers when delete + * operator is made with these commands: %, (, ), , /, ?, n, N, {, } ) + * TODO: Implement the remaining registers. + * + * Marks: a-z, A-Z, and 0-9 + * TODO: Implement the remaining special marks. They have more complex + * behavior. + * + * Events: + * 'vim-mode-change' - raised on the editor anytime the current mode changes, + * Event object: {mode: "visual", subMode: "linewise"} + * + * Code structure: + * 1. Default keymap + * 2. Variable declarations and short basic helpers + * 3. Instance (External API) implementation + * 4. Internal state tracking objects (input state, counter) implementation + * and instantiation + * 5. Key handler (the main command dispatcher) implementation + * 6. Motion, operator, and action implementations + * 7. Helper functions for the key handler, motions, operators, and actions + * 8. Set up Vim to work as a keymap for CodeMirror. + * 9. Ex command implementations. + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/dialog/dialog"), require("../addon/edit/matchbrackets.js")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/dialog/dialog", "../addon/edit/matchbrackets"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + 'use strict'; + + var defaultKeymap = [ + // Key to key mapping. This goes first to make it possible to override + // existing mappings. + { keys: '', type: 'keyToKey', toKeys: 'h' }, + { keys: '', type: 'keyToKey', toKeys: 'l' }, + { keys: '', type: 'keyToKey', toKeys: 'k' }, + { keys: '', type: 'keyToKey', toKeys: 'j' }, + { keys: '', type: 'keyToKey', toKeys: 'l' }, + { keys: '', type: 'keyToKey', toKeys: 'h', context: 'normal'}, + { keys: '', type: 'keyToKey', toKeys: 'W' }, + { keys: '', type: 'keyToKey', toKeys: 'B', context: 'normal' }, + { keys: '', type: 'keyToKey', toKeys: 'w' }, + { keys: '', type: 'keyToKey', toKeys: 'b', context: 'normal' }, + { keys: '', type: 'keyToKey', toKeys: 'j' }, + { keys: '', type: 'keyToKey', toKeys: 'k' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, + { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, + { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' }, + { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'}, + { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' }, + { keys: 'S', type: 'keyToKey', toKeys: 'VdO', context: 'visual' }, + { keys: '', type: 'keyToKey', toKeys: '0' }, + { keys: '', type: 'keyToKey', toKeys: '$' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: 'j^', context: 'normal' }, + { keys: '', type: 'action', action: 'toggleOverwrite', context: 'insert' }, + // Motions + { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }}, + { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }}, + { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }}, + { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }}, + { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }}, + { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }}, + { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }}, + { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }}, + { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }}, + { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }}, + { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }}, + { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }}, + { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }}, + { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }}, + { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }}, + { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }}, + { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }}, + { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }}, + { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }}, + { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }}, + { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }}, + { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }}, + { keys: '0', type: 'motion', motion: 'moveToStartOfLine' }, + { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }}, + { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }}, + { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }}, + { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }}, + { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }}, + { keys: 'f', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }}, + { keys: 'F', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }}, + { keys: 't', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }}, + { keys: 'T', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }}, + { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }}, + { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }}, + { keys: '\'', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}}, + { keys: '`', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}}, + { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } }, + { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } }, + { keys: ']\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } }, + { keys: '[\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } }, + // the next two aren't motions but must come before more general motion declarations + { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}}, + { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}}, + { keys: ']', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}}, + { keys: '[', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}}, + { keys: '|', type: 'motion', motion: 'moveToColumn'}, + { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'}, + { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'}, + // Operators + { keys: 'd', type: 'operator', operator: 'delete' }, + { keys: 'y', type: 'operator', operator: 'yank' }, + { keys: 'c', type: 'operator', operator: 'change' }, + { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }}, + { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }}, + { keys: 'g~', type: 'operator', operator: 'changeCase' }, + { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true }, + { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true }, + { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }}, + { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }}, + // Operator-Motion dual commands + { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }}, + { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }}, + { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, + { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'expandToLine', motionArgs: { linewise: true }, context: 'normal'}, + { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, + { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'}, + { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'}, + { keys: '', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' }, + // Actions + { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }}, + { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }}, + { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }}, + { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }}, + { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' }, + { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' }, + { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' }, + { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' }, + { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' }, + { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' }, + { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' }, + { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' }, + { keys: 'v', type: 'action', action: 'toggleVisualMode' }, + { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }}, + { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, + { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, + { keys: 'gv', type: 'action', action: 'reselectLastSelection' }, + { keys: 'J', type: 'action', action: 'joinLines', isEdit: true }, + { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }}, + { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }}, + { keys: 'r', type: 'action', action: 'replace', isEdit: true }, + { keys: '@', type: 'action', action: 'replayMacro' }, + { keys: 'q', type: 'action', action: 'enterMacroRecordMode' }, + // Handle Replace-mode as a special case of insert mode. + { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }}, + { keys: 'u', type: 'action', action: 'undo', context: 'normal' }, + { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true }, + { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true }, + { keys: '', type: 'action', action: 'redo' }, + { keys: 'm', type: 'action', action: 'setMark' }, + { keys: '"', type: 'action', action: 'setRegister' }, + { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }}, + { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }}, + { keys: 'z', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }}, + { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: '.', type: 'action', action: 'repeatLastEdit' }, + { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}}, + { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}}, + { keys: '', type: 'action', action: 'indent', actionArgs: { indentRight: true }, context: 'insert' }, + { keys: '', type: 'action', action: 'indent', actionArgs: { indentRight: false }, context: 'insert' }, + // Text object motions + { keys: 'a', type: 'motion', motion: 'textObjectManipulation' }, + { keys: 'i', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }}, + // Search + { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }}, + { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }}, + { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, + { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, + { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }}, + { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }}, + // Ex command + { keys: ':', type: 'ex' } + ]; + + /** + * Ex commands + * Care must be taken when adding to the default Ex command map. For any + * pair of commands that have a shared prefix, at least one of their + * shortNames must not match the prefix of the other command. + */ + var defaultExCommandMap = [ + { name: 'colorscheme', shortName: 'colo' }, + { name: 'map' }, + { name: 'imap', shortName: 'im' }, + { name: 'nmap', shortName: 'nm' }, + { name: 'vmap', shortName: 'vm' }, + { name: 'unmap' }, + { name: 'write', shortName: 'w' }, + { name: 'undo', shortName: 'u' }, + { name: 'redo', shortName: 'red' }, + { name: 'set', shortName: 'se' }, + { name: 'set', shortName: 'se' }, + { name: 'setlocal', shortName: 'setl' }, + { name: 'setglobal', shortName: 'setg' }, + { name: 'sort', shortName: 'sor' }, + { name: 'substitute', shortName: 's', possiblyAsync: true }, + { name: 'nohlsearch', shortName: 'noh' }, + { name: 'yank', shortName: 'y' }, + { name: 'delmarks', shortName: 'delm' }, + { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true }, + { name: 'global', shortName: 'g' } + ]; + + var Pos = CodeMirror.Pos; + + var Vim = function() { + function enterVimMode(cm) { + cm.setOption('disableInput', true); + cm.setOption('showCursorWhenSelecting', false); + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + cm.on('cursorActivity', onCursorActivity); + maybeInitVimState(cm); + CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); + } + + function leaveVimMode(cm) { + cm.setOption('disableInput', false); + cm.off('cursorActivity', onCursorActivity); + CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); + cm.state.vim = null; + } + + function detachVimMap(cm, next) { + if (this == CodeMirror.keyMap.vim) { + CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); + if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) { + disableFatCursorMark(cm); + cm.getInputField().style.caretColor = ""; + } + } + + if (!next || next.attach != attachVimMap) + leaveVimMode(cm); + } + function attachVimMap(cm, prev) { + if (this == CodeMirror.keyMap.vim) { + CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); + if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) { + enableFatCursorMark(cm); + cm.getInputField().style.caretColor = "transparent"; + } + } + + if (!prev || prev.attach != attachVimMap) + enterVimMode(cm); + } + + function fatCursorMarks(cm) { + var ranges = cm.listSelections(), result = [] + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i] + if (range.empty()) { + if (range.anchor.ch < cm.getLine(range.anchor.line).length) { + result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1), + {className: "cm-fat-cursor-mark"})) + } else { + var widget = document.createElement("span") + widget.textContent = "\u00a0" + widget.className = "cm-fat-cursor-mark" + result.push(cm.setBookmark(range.anchor, {widget: widget})) + } + } + } + return result + } + + function updateFatCursorMark(cm) { + var marks = cm.state.fatCursorMarks + if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear() + cm.state.fatCursorMarks = fatCursorMarks(cm) + } + + function enableFatCursorMark(cm) { + cm.state.fatCursorMarks = fatCursorMarks(cm) + cm.on("cursorActivity", updateFatCursorMark) + } + + function disableFatCursorMark(cm) { + var marks = cm.state.fatCursorMarks + if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear() + cm.state.fatCursorMarks = null + cm.off("cursorActivity", updateFatCursorMark) + } + + // Deprecated, simply setting the keymap works again. + CodeMirror.defineOption('vimMode', false, function(cm, val, prev) { + if (val && cm.getOption("keyMap") != "vim") + cm.setOption("keyMap", "vim"); + else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap"))) + cm.setOption("keyMap", "default"); + }); + + function cmKey(key, cm) { + if (!cm) { return undefined; } + if (this[key]) { return this[key]; } + var vimKey = cmKeyToVimKey(key); + if (!vimKey) { + return false; + } + var cmd = CodeMirror.Vim.findKey(cm, vimKey); + if (typeof cmd == 'function') { + CodeMirror.signal(cm, 'vim-keypress', vimKey); + } + return cmd; + } + + var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'}; + var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'}; + function cmKeyToVimKey(key) { + if (key.charAt(0) == '\'') { + // Keypress character binding of format "'a'" + return key.charAt(1); + } + var pieces = key.split(/-(?!$)/); + var lastPiece = pieces[pieces.length - 1]; + if (pieces.length == 1 && pieces[0].length == 1) { + // No-modifier bindings use literal character bindings above. Skip. + return false; + } else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) { + // Ignore Shift+char bindings as they should be handled by literal character. + return false; + } + var hasCharacter = false; + for (var i = 0; i < pieces.length; i++) { + var piece = pieces[i]; + if (piece in modifiers) { pieces[i] = modifiers[piece]; } + else { hasCharacter = true; } + if (piece in specialKeys) { pieces[i] = specialKeys[piece]; } + } + if (!hasCharacter) { + // Vim does not support modifier only keys. + return false; + } + // TODO: Current bindings expect the character to be lower case, but + // it looks like vim key notation uses upper case. + if (isUpperCase(lastPiece)) { + pieces[pieces.length - 1] = lastPiece.toLowerCase(); + } + return '<' + pieces.join('-') + '>'; + } + + function getOnPasteFn(cm) { + var vim = cm.state.vim; + if (!vim.onPasteFn) { + vim.onPasteFn = function() { + if (!vim.insertMode) { + cm.setCursor(offsetCursor(cm.getCursor(), 0, 1)); + actions.enterInsertMode(cm, {}, vim); + } + }; + } + return vim.onPasteFn; + } + + var numberRegex = /[\d]/; + var wordCharTest = [CodeMirror.isWordChar, function(ch) { + return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch); + }], bigWordCharTest = [function(ch) { + return /\S/.test(ch); + }]; + function makeKeyRange(start, size) { + var keys = []; + for (var i = start; i < start + size; i++) { + keys.push(String.fromCharCode(i)); + } + return keys; + } + var upperCaseAlphabet = makeKeyRange(65, 26); + var lowerCaseAlphabet = makeKeyRange(97, 26); + var numbers = makeKeyRange(48, 10); + var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']); + var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']); + + function isLine(cm, line) { + return line >= cm.firstLine() && line <= cm.lastLine(); + } + function isLowerCase(k) { + return (/^[a-z]$/).test(k); + } + function isMatchableSymbol(k) { + return '()[]{}'.indexOf(k) != -1; + } + function isNumber(k) { + return numberRegex.test(k); + } + function isUpperCase(k) { + return (/^[A-Z]$/).test(k); + } + function isWhiteSpaceString(k) { + return (/^\s*$/).test(k); + } + function inArray(val, arr) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == val) { + return true; + } + } + return false; + } + + var options = {}; + function defineOption(name, defaultValue, type, aliases, callback) { + if (defaultValue === undefined && !callback) { + throw Error('defaultValue is required unless callback is provided'); + } + if (!type) { type = 'string'; } + options[name] = { + type: type, + defaultValue: defaultValue, + callback: callback + }; + if (aliases) { + for (var i = 0; i < aliases.length; i++) { + options[aliases[i]] = options[name]; + } + } + if (defaultValue) { + setOption(name, defaultValue); + } + } + + function setOption(name, value, cm, cfg) { + var option = options[name]; + cfg = cfg || {}; + var scope = cfg.scope; + if (!option) { + return new Error('Unknown option: ' + name); + } + if (option.type == 'boolean') { + if (value && value !== true) { + return new Error('Invalid argument: ' + name + '=' + value); + } else if (value !== false) { + // Boolean options are set to true if value is not defined. + value = true; + } + } + if (option.callback) { + if (scope !== 'local') { + option.callback(value, undefined); + } + if (scope !== 'global' && cm) { + option.callback(value, cm); + } + } else { + if (scope !== 'local') { + option.value = option.type == 'boolean' ? !!value : value; + } + if (scope !== 'global' && cm) { + cm.state.vim.options[name] = {value: value}; + } + } + } + + function getOption(name, cm, cfg) { + var option = options[name]; + cfg = cfg || {}; + var scope = cfg.scope; + if (!option) { + return new Error('Unknown option: ' + name); + } + if (option.callback) { + var local = cm && option.callback(undefined, cm); + if (scope !== 'global' && local !== undefined) { + return local; + } + if (scope !== 'local') { + return option.callback(); + } + return; + } else { + var local = (scope !== 'global') && (cm && cm.state.vim.options[name]); + return (local || (scope !== 'local') && option || {}).value; + } + } + + defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) { + // Option is local. Do nothing for global. + if (cm === undefined) { + return; + } + // The 'filetype' option proxies to the CodeMirror 'mode' option. + if (name === undefined) { + var mode = cm.getOption('mode'); + return mode == 'null' ? '' : mode; + } else { + var mode = name == '' ? 'null' : name; + cm.setOption('mode', mode); + } + }); + + var createCircularJumpList = function() { + var size = 100; + var pointer = -1; + var head = 0; + var tail = 0; + var buffer = new Array(size); + function add(cm, oldCur, newCur) { + var current = pointer % size; + var curMark = buffer[current]; + function useNextSlot(cursor) { + var next = ++pointer % size; + var trashMark = buffer[next]; + if (trashMark) { + trashMark.clear(); + } + buffer[next] = cm.setBookmark(cursor); + } + if (curMark) { + var markPos = curMark.find(); + // avoid recording redundant cursor position + if (markPos && !cursorEqual(markPos, oldCur)) { + useNextSlot(oldCur); + } + } else { + useNextSlot(oldCur); + } + useNextSlot(newCur); + head = pointer; + tail = pointer - size + 1; + if (tail < 0) { + tail = 0; + } + } + function move(cm, offset) { + pointer += offset; + if (pointer > head) { + pointer = head; + } else if (pointer < tail) { + pointer = tail; + } + var mark = buffer[(size + pointer) % size]; + // skip marks that are temporarily removed from text buffer + if (mark && !mark.find()) { + var inc = offset > 0 ? 1 : -1; + var newCur; + var oldCur = cm.getCursor(); + do { + pointer += inc; + mark = buffer[(size + pointer) % size]; + // skip marks that are the same as current position + if (mark && + (newCur = mark.find()) && + !cursorEqual(oldCur, newCur)) { + break; + } + } while (pointer < head && pointer > tail); + } + return mark; + } + return { + cachedCursor: undefined, //used for # and * jumps + add: add, + move: move + }; + }; + + // Returns an object to track the changes associated insert mode. It + // clones the object that is passed in, or creates an empty object one if + // none is provided. + var createInsertModeChanges = function(c) { + if (c) { + // Copy construction + return { + changes: c.changes, + expectCursorActivityForChange: c.expectCursorActivityForChange + }; + } + return { + // Change list + changes: [], + // Set to true on change, false on cursorActivity. + expectCursorActivityForChange: false + }; + }; + + function MacroModeState() { + this.latestRegister = undefined; + this.isPlaying = false; + this.isRecording = false; + this.replaySearchQueries = []; + this.onRecordingDone = undefined; + this.lastInsertModeChanges = createInsertModeChanges(); + } + MacroModeState.prototype = { + exitMacroRecordMode: function() { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.onRecordingDone) { + macroModeState.onRecordingDone(); // close dialog + } + macroModeState.onRecordingDone = undefined; + macroModeState.isRecording = false; + }, + enterMacroRecordMode: function(cm, registerName) { + var register = + vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.clear(); + this.latestRegister = registerName; + if (cm.openDialog) { + this.onRecordingDone = cm.openDialog( + '(recording)['+registerName+']', null, {bottom:true}); + } + this.isRecording = true; + } + } + }; + + function maybeInitVimState(cm) { + if (!cm.state.vim) { + // Store instance state in the CodeMirror object. + cm.state.vim = { + inputState: new InputState(), + // Vim's input state that triggered the last edit, used to repeat + // motions and operators with '.'. + lastEditInputState: undefined, + // Vim's action command before the last edit, used to repeat actions + // with '.' and insert mode repeat. + lastEditActionCommand: undefined, + // When using jk for navigation, if you move from a longer line to a + // shorter line, the cursor may clip to the end of the shorter line. + // If j is pressed again and cursor goes to the next line, the + // cursor should go back to its horizontal position on the longer + // line if it can. This is to keep track of the horizontal position. + lastHPos: -1, + // Doing the same with screen-position for gj/gk + lastHSPos: -1, + // The last motion command run. Cleared if a non-motion command gets + // executed in between. + lastMotion: null, + marks: {}, + // Mark for rendering fake cursor for visual mode. + fakeCursor: null, + insertMode: false, + // Repeat count for changes made in insert mode, triggered by key + // sequences like 3,i. Only exists when insertMode is true. + insertModeRepeat: undefined, + visualMode: false, + // If we are in visual line mode. No effect if visualMode is false. + visualLine: false, + visualBlock: false, + lastSelection: null, + lastPastedText: null, + sel: {}, + // Buffer-local/window-local values of vim options. + options: {} + }; + } + return cm.state.vim; + } + var vimGlobalState; + function resetVimGlobalState() { + vimGlobalState = { + // The current search query. + searchQuery: null, + // Whether we are searching backwards. + searchIsReversed: false, + // Replace part of the last substituted pattern + lastSubstituteReplacePart: undefined, + jumpList: createCircularJumpList(), + macroModeState: new MacroModeState, + // Recording latest f, t, F or T motion command. + lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''}, + registerController: new RegisterController({}), + // search history buffer + searchHistoryController: new HistoryController(), + // ex Command history buffer + exCommandHistoryController : new HistoryController() + }; + for (var optionName in options) { + var option = options[optionName]; + option.value = option.defaultValue; + } + } + + var lastInsertModeKeyTimer; + var vimApi= { + buildKeyMap: function() { + // TODO: Convert keymap into dictionary format for fast lookup. + }, + // Testing hook, though it might be useful to expose the register + // controller anyways. + getRegisterController: function() { + return vimGlobalState.registerController; + }, + // Testing hook. + resetVimGlobalState_: resetVimGlobalState, + + // Testing hook. + getVimGlobalState_: function() { + return vimGlobalState; + }, + + // Testing hook. + maybeInitVimState_: maybeInitVimState, + + suppressErrorLogging: false, + + InsertModeKey: InsertModeKey, + map: function(lhs, rhs, ctx) { + // Add user defined key bindings. + exCommandDispatcher.map(lhs, rhs, ctx); + }, + unmap: function(lhs, ctx) { + exCommandDispatcher.unmap(lhs, ctx); + }, + // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace + // them, or somehow make them work with the existing CodeMirror setOption/getOption API. + setOption: setOption, + getOption: getOption, + defineOption: defineOption, + defineEx: function(name, prefix, func){ + if (!prefix) { + prefix = name; + } else if (name.indexOf(prefix) !== 0) { + throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered'); + } + exCommands[name]=func; + exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'}; + }, + handleKey: function (cm, key, origin) { + var command = this.findKey(cm, key, origin); + if (typeof command === 'function') { + return command(); + } + }, + /** + * This is the outermost function called by CodeMirror, after keys have + * been mapped to their Vim equivalents. + * + * Finds a command based on the key (and cached keys if there is a + * multi-key sequence). Returns `undefined` if no key is matched, a noop + * function if a partial match is found (multi-key), and a function to + * execute the bound command if a a key is matched. The function always + * returns true. + */ + findKey: function(cm, key, origin) { + var vim = maybeInitVimState(cm); + function handleMacroRecording() { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isRecording) { + if (key == 'q') { + macroModeState.exitMacroRecordMode(); + clearInputState(cm); + return true; + } + if (origin != 'mapping') { + logKey(macroModeState, key); + } + } + } + function handleEsc() { + if (key == '') { + // Clear input state and get back to normal mode. + clearInputState(cm); + if (vim.visualMode) { + exitVisualMode(cm); + } else if (vim.insertMode) { + exitInsertMode(cm); + } + return true; + } + } + function doKeyToKey(keys) { + // TODO: prevent infinite recursion. + var match; + while (keys) { + // Pull off one command key, which is either a single character + // or a special sequence wrapped in '<' and '>', e.g. ''. + match = (/<\w+-.+?>|<\w+>|./).exec(keys); + key = match[0]; + keys = keys.substring(match.index + key.length); + CodeMirror.Vim.handleKey(cm, key, 'mapping'); + } + } + + function handleKeyInsertMode() { + if (handleEsc()) { return true; } + var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; + var keysAreChars = key.length == 1; + var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); + // Need to check all key substrings in insert mode. + while (keys.length > 1 && match.type != 'full') { + var keys = vim.inputState.keyBuffer = keys.slice(1); + var thisMatch = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); + if (thisMatch.type != 'none') { match = thisMatch; } + } + if (match.type == 'none') { clearInputState(cm); return false; } + else if (match.type == 'partial') { + if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } + lastInsertModeKeyTimer = window.setTimeout( + function() { if (vim.insertMode && vim.inputState.keyBuffer) { clearInputState(cm); } }, + getOption('insertModeEscKeysTimeout')); + return !keysAreChars; + } + + if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } + if (keysAreChars) { + var selections = cm.listSelections(); + for (var i = 0; i < selections.length; i++) { + var here = selections[i].head; + cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input'); + } + vimGlobalState.macroModeState.lastInsertModeChanges.changes.pop(); + } + clearInputState(cm); + return match.command; + } + + function handleKeyNonInsertMode() { + if (handleMacroRecording() || handleEsc()) { return true; }; + + var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; + if (/^[1-9]\d*$/.test(keys)) { return true; } + + var keysMatcher = /^(\d*)(.*)$/.exec(keys); + if (!keysMatcher) { clearInputState(cm); return false; } + var context = vim.visualMode ? 'visual' : + 'normal'; + var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context); + if (match.type == 'none') { clearInputState(cm); return false; } + else if (match.type == 'partial') { return true; } + + vim.inputState.keyBuffer = ''; + var keysMatcher = /^(\d*)(.*)$/.exec(keys); + if (keysMatcher[1] && keysMatcher[1] != '0') { + vim.inputState.pushRepeatDigit(keysMatcher[1]); + } + return match.command; + } + + var command; + if (vim.insertMode) { command = handleKeyInsertMode(); } + else { command = handleKeyNonInsertMode(); } + if (command === false) { + return undefined; + } else if (command === true) { + // TODO: Look into using CodeMirror's multi-key handling. + // Return no-op since we are caching the key. Counts as handled, but + // don't want act on it just yet. + return function() { return true; }; + } else { + return function() { + return cm.operation(function() { + cm.curOp.isVimOp = true; + try { + if (command.type == 'keyToKey') { + doKeyToKey(command.toKeys); + } else { + commandDispatcher.processCommand(cm, vim, command); + } + } catch (e) { + // clear VIM state in case it's in a bad state. + cm.state.vim = undefined; + maybeInitVimState(cm); + if (!CodeMirror.Vim.suppressErrorLogging) { + console['log'](e); + } + throw e; + } + return true; + }); + }; + } + }, + handleEx: function(cm, input) { + exCommandDispatcher.processCommand(cm, input); + }, + + defineMotion: defineMotion, + defineAction: defineAction, + defineOperator: defineOperator, + mapCommand: mapCommand, + _mapCommand: _mapCommand, + + defineRegister: defineRegister, + + exitVisualMode: exitVisualMode, + exitInsertMode: exitInsertMode + }; + + // Represents the current input state. + function InputState() { + this.prefixRepeat = []; + this.motionRepeat = []; + + this.operator = null; + this.operatorArgs = null; + this.motion = null; + this.motionArgs = null; + this.keyBuffer = []; // For matching multi-key commands. + this.registerName = null; // Defaults to the unnamed register. + } + InputState.prototype.pushRepeatDigit = function(n) { + if (!this.operator) { + this.prefixRepeat = this.prefixRepeat.concat(n); + } else { + this.motionRepeat = this.motionRepeat.concat(n); + } + }; + InputState.prototype.getRepeat = function() { + var repeat = 0; + if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) { + repeat = 1; + if (this.prefixRepeat.length > 0) { + repeat *= parseInt(this.prefixRepeat.join(''), 10); + } + if (this.motionRepeat.length > 0) { + repeat *= parseInt(this.motionRepeat.join(''), 10); + } + } + return repeat; + }; + + function clearInputState(cm, reason) { + cm.state.vim.inputState = new InputState(); + CodeMirror.signal(cm, 'vim-command-done', reason); + } + + /* + * Register stores information about copy and paste registers. Besides + * text, a register must store whether it is linewise (i.e., when it is + * pasted, should it insert itself into a new line, or should the text be + * inserted at the cursor position.) + */ + function Register(text, linewise, blockwise) { + this.clear(); + this.keyBuffer = [text || '']; + this.insertModeChanges = []; + this.searchQueries = []; + this.linewise = !!linewise; + this.blockwise = !!blockwise; + } + Register.prototype = { + setText: function(text, linewise, blockwise) { + this.keyBuffer = [text || '']; + this.linewise = !!linewise; + this.blockwise = !!blockwise; + }, + pushText: function(text, linewise) { + // if this register has ever been set to linewise, use linewise. + if (linewise) { + if (!this.linewise) { + this.keyBuffer.push('\n'); + } + this.linewise = true; + } + this.keyBuffer.push(text); + }, + pushInsertModeChanges: function(changes) { + this.insertModeChanges.push(createInsertModeChanges(changes)); + }, + pushSearchQuery: function(query) { + this.searchQueries.push(query); + }, + clear: function() { + this.keyBuffer = []; + this.insertModeChanges = []; + this.searchQueries = []; + this.linewise = false; + }, + toString: function() { + return this.keyBuffer.join(''); + } + }; + + /** + * Defines an external register. + * + * The name should be a single character that will be used to reference the register. + * The register should support setText, pushText, clear, and toString(). See Register + * for a reference implementation. + */ + function defineRegister(name, register) { + var registers = vimGlobalState.registerController.registers; + if (!name || name.length != 1) { + throw Error('Register name must be 1 character'); + } + if (registers[name]) { + throw Error('Register already defined ' + name); + } + registers[name] = register; + validRegisters.push(name); + } + + /* + * vim registers allow you to keep many independent copy and paste buffers. + * See http://usevim.com/2012/04/13/registers/ for an introduction. + * + * RegisterController keeps the state of all the registers. An initial + * state may be passed in. The unnamed register '"' will always be + * overridden. + */ + function RegisterController(registers) { + this.registers = registers; + this.unnamedRegister = registers['"'] = new Register(); + registers['.'] = new Register(); + registers[':'] = new Register(); + registers['/'] = new Register(); + } + RegisterController.prototype = { + pushText: function(registerName, operator, text, linewise, blockwise) { + if (linewise && text.charAt(text.length - 1) !== '\n'){ + text += '\n'; + } + // Lowercase and uppercase registers refer to the same register. + // Uppercase just means append. + var register = this.isValidRegister(registerName) ? + this.getRegister(registerName) : null; + // if no register/an invalid register was specified, things go to the + // default registers + if (!register) { + switch (operator) { + case 'yank': + // The 0 register contains the text from the most recent yank. + this.registers['0'] = new Register(text, linewise, blockwise); + break; + case 'delete': + case 'change': + if (text.indexOf('\n') == -1) { + // Delete less than 1 line. Update the small delete register. + this.registers['-'] = new Register(text, linewise); + } else { + // Shift down the contents of the numbered registers and put the + // deleted text into register 1. + this.shiftNumericRegisters_(); + this.registers['1'] = new Register(text, linewise); + } + break; + } + // Make sure the unnamed register is set to what just happened + this.unnamedRegister.setText(text, linewise, blockwise); + return; + } + + // If we've gotten to this point, we've actually specified a register + var append = isUpperCase(registerName); + if (append) { + register.pushText(text, linewise); + } else { + register.setText(text, linewise, blockwise); + } + // The unnamed register always has the same value as the last used + // register. + this.unnamedRegister.setText(register.toString(), linewise); + }, + // Gets the register named @name. If one of @name doesn't already exist, + // create it. If @name is invalid, return the unnamedRegister. + getRegister: function(name) { + if (!this.isValidRegister(name)) { + return this.unnamedRegister; + } + name = name.toLowerCase(); + if (!this.registers[name]) { + this.registers[name] = new Register(); + } + return this.registers[name]; + }, + isValidRegister: function(name) { + return name && inArray(name, validRegisters); + }, + shiftNumericRegisters_: function() { + for (var i = 9; i >= 2; i--) { + this.registers[i] = this.getRegister('' + (i - 1)); + } + } + }; + function HistoryController() { + this.historyBuffer = []; + this.iterator = 0; + this.initialPrefix = null; + } + HistoryController.prototype = { + // the input argument here acts a user entered prefix for a small time + // until we start autocompletion in which case it is the autocompleted. + nextMatch: function (input, up) { + var historyBuffer = this.historyBuffer; + var dir = up ? -1 : 1; + if (this.initialPrefix === null) this.initialPrefix = input; + for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) { + var element = historyBuffer[i]; + for (var j = 0; j <= element.length; j++) { + if (this.initialPrefix == element.substring(0, j)) { + this.iterator = i; + return element; + } + } + } + // should return the user input in case we reach the end of buffer. + if (i >= historyBuffer.length) { + this.iterator = historyBuffer.length; + return this.initialPrefix; + } + // return the last autocompleted query or exCommand as it is. + if (i < 0 ) return input; + }, + pushInput: function(input) { + var index = this.historyBuffer.indexOf(input); + if (index > -1) this.historyBuffer.splice(index, 1); + if (input.length) this.historyBuffer.push(input); + }, + reset: function() { + this.initialPrefix = null; + this.iterator = this.historyBuffer.length; + } + }; + var commandDispatcher = { + matchCommand: function(keys, keyMap, inputState, context) { + var matches = commandMatches(keys, keyMap, context, inputState); + if (!matches.full && !matches.partial) { + return {type: 'none'}; + } else if (!matches.full && matches.partial) { + return {type: 'partial'}; + } + + var bestMatch; + for (var i = 0; i < matches.full.length; i++) { + var match = matches.full[i]; + if (!bestMatch) { + bestMatch = match; + } + } + if (bestMatch.keys.slice(-11) == '') { + var character = lastChar(keys); + if (!character) return {type: 'none'}; + inputState.selectedCharacter = character; + } + return {type: 'full', command: bestMatch}; + }, + processCommand: function(cm, vim, command) { + vim.inputState.repeatOverride = command.repeatOverride; + switch (command.type) { + case 'motion': + this.processMotion(cm, vim, command); + break; + case 'operator': + this.processOperator(cm, vim, command); + break; + case 'operatorMotion': + this.processOperatorMotion(cm, vim, command); + break; + case 'action': + this.processAction(cm, vim, command); + break; + case 'search': + this.processSearch(cm, vim, command); + break; + case 'ex': + case 'keyToEx': + this.processEx(cm, vim, command); + break; + default: + break; + } + }, + processMotion: function(cm, vim, command) { + vim.inputState.motion = command.motion; + vim.inputState.motionArgs = copyArgs(command.motionArgs); + this.evalInput(cm, vim); + }, + processOperator: function(cm, vim, command) { + var inputState = vim.inputState; + if (inputState.operator) { + if (inputState.operator == command.operator) { + // Typing an operator twice like 'dd' makes the operator operate + // linewise + inputState.motion = 'expandToLine'; + inputState.motionArgs = { linewise: true }; + this.evalInput(cm, vim); + return; + } else { + // 2 different operators in a row doesn't make sense. + clearInputState(cm); + } + } + inputState.operator = command.operator; + inputState.operatorArgs = copyArgs(command.operatorArgs); + if (vim.visualMode) { + // Operating on a selection in visual mode. We don't need a motion. + this.evalInput(cm, vim); + } + }, + processOperatorMotion: function(cm, vim, command) { + var visualMode = vim.visualMode; + var operatorMotionArgs = copyArgs(command.operatorMotionArgs); + if (operatorMotionArgs) { + // Operator motions may have special behavior in visual mode. + if (visualMode && operatorMotionArgs.visualLine) { + vim.visualLine = true; + } + } + this.processOperator(cm, vim, command); + if (!visualMode) { + this.processMotion(cm, vim, command); + } + }, + processAction: function(cm, vim, command) { + var inputState = vim.inputState; + var repeat = inputState.getRepeat(); + var repeatIsExplicit = !!repeat; + var actionArgs = copyArgs(command.actionArgs) || {}; + if (inputState.selectedCharacter) { + actionArgs.selectedCharacter = inputState.selectedCharacter; + } + // Actions may or may not have motions and operators. Do these first. + if (command.operator) { + this.processOperator(cm, vim, command); + } + if (command.motion) { + this.processMotion(cm, vim, command); + } + if (command.motion || command.operator) { + this.evalInput(cm, vim); + } + actionArgs.repeat = repeat || 1; + actionArgs.repeatIsExplicit = repeatIsExplicit; + actionArgs.registerName = inputState.registerName; + clearInputState(cm); + vim.lastMotion = null; + if (command.isEdit) { + this.recordLastEdit(vim, inputState, command); + } + actions[command.action](cm, actionArgs, vim); + }, + processSearch: function(cm, vim, command) { + if (!cm.getSearchCursor) { + // Search depends on SearchCursor. + return; + } + var forward = command.searchArgs.forward; + var wholeWordOnly = command.searchArgs.wholeWordOnly; + getSearchState(cm).setReversed(!forward); + var promptPrefix = (forward) ? '/' : '?'; + var originalQuery = getSearchState(cm).getQuery(); + var originalScrollPos = cm.getScrollInfo(); + function handleQuery(query, ignoreCase, smartCase) { + vimGlobalState.searchHistoryController.pushInput(query); + vimGlobalState.searchHistoryController.reset(); + try { + updateSearchQuery(cm, query, ignoreCase, smartCase); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + query); + clearInputState(cm); + return; + } + commandDispatcher.processMotion(cm, vim, { + type: 'motion', + motion: 'findNext', + motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist } + }); + } + function onPromptClose(query) { + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + handleQuery(query, true /** ignoreCase */, true /** smartCase */); + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isRecording) { + logSearchQuery(macroModeState, query); + } + } + function onPromptKeyUp(e, query, close) { + var keyName = CodeMirror.keyName(e), up, offset; + if (keyName == 'Up' || keyName == 'Down') { + up = keyName == 'Up' ? true : false; + offset = e.target ? e.target.selectionEnd : 0; + query = vimGlobalState.searchHistoryController.nextMatch(query, up) || ''; + close(query); + if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length); + } else { + if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') + vimGlobalState.searchHistoryController.reset(); + } + var parsedQuery; + try { + parsedQuery = updateSearchQuery(cm, query, + true /** ignoreCase */, true /** smartCase */); + } catch (e) { + // Swallow bad regexes for incremental search. + } + if (parsedQuery) { + cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30); + } else { + clearSearchHighlight(cm); + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + } + } + function onPromptKeyDown(e, query, close) { + var keyName = CodeMirror.keyName(e); + if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || + (keyName == 'Backspace' && query == '')) { + vimGlobalState.searchHistoryController.pushInput(query); + vimGlobalState.searchHistoryController.reset(); + updateSearchQuery(cm, originalQuery); + clearSearchHighlight(cm); + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + CodeMirror.e_stop(e); + clearInputState(cm); + close(); + cm.focus(); + } else if (keyName == 'Up' || keyName == 'Down') { + CodeMirror.e_stop(e); + } else if (keyName == 'Ctrl-U') { + // Ctrl-U clears input. + CodeMirror.e_stop(e); + close(''); + } + } + switch (command.searchArgs.querySrc) { + case 'prompt': + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { + var query = macroModeState.replaySearchQueries.shift(); + handleQuery(query, true /** ignoreCase */, false /** smartCase */); + } else { + showPrompt(cm, { + onClose: onPromptClose, + prefix: promptPrefix, + desc: searchPromptDesc, + onKeyUp: onPromptKeyUp, + onKeyDown: onPromptKeyDown + }); + } + break; + case 'wordUnderCursor': + var word = expandWordUnderCursor(cm, false /** inclusive */, + true /** forward */, false /** bigWord */, + true /** noSymbol */); + var isKeyword = true; + if (!word) { + word = expandWordUnderCursor(cm, false /** inclusive */, + true /** forward */, false /** bigWord */, + false /** noSymbol */); + isKeyword = false; + } + if (!word) { + return; + } + var query = cm.getLine(word.start.line).substring(word.start.ch, + word.end.ch); + if (isKeyword && wholeWordOnly) { + query = '\\b' + query + '\\b'; + } else { + query = escapeRegex(query); + } + + // cachedCursor is used to save the old position of the cursor + // when * or # causes vim to seek for the nearest word and shift + // the cursor before entering the motion. + vimGlobalState.jumpList.cachedCursor = cm.getCursor(); + cm.setCursor(word.start); + + handleQuery(query, true /** ignoreCase */, false /** smartCase */); + break; + } + }, + processEx: function(cm, vim, command) { + function onPromptClose(input) { + // Give the prompt some time to close so that if processCommand shows + // an error, the elements don't overlap. + vimGlobalState.exCommandHistoryController.pushInput(input); + vimGlobalState.exCommandHistoryController.reset(); + exCommandDispatcher.processCommand(cm, input); + } + function onPromptKeyDown(e, input, close) { + var keyName = CodeMirror.keyName(e), up, offset; + if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || + (keyName == 'Backspace' && input == '')) { + vimGlobalState.exCommandHistoryController.pushInput(input); + vimGlobalState.exCommandHistoryController.reset(); + CodeMirror.e_stop(e); + clearInputState(cm); + close(); + cm.focus(); + } + if (keyName == 'Up' || keyName == 'Down') { + CodeMirror.e_stop(e); + up = keyName == 'Up' ? true : false; + offset = e.target ? e.target.selectionEnd : 0; + input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || ''; + close(input); + if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length); + } else if (keyName == 'Ctrl-U') { + // Ctrl-U clears input. + CodeMirror.e_stop(e); + close(''); + } else { + if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') + vimGlobalState.exCommandHistoryController.reset(); + } + } + if (command.type == 'keyToEx') { + // Handle user defined Ex to Ex mappings + exCommandDispatcher.processCommand(cm, command.exArgs.input); + } else { + if (vim.visualMode) { + showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\'<,\'>', + onKeyDown: onPromptKeyDown}); + } else { + showPrompt(cm, { onClose: onPromptClose, prefix: ':', + onKeyDown: onPromptKeyDown}); + } + } + }, + evalInput: function(cm, vim) { + // If the motion command is set, execute both the operator and motion. + // Otherwise return. + var inputState = vim.inputState; + var motion = inputState.motion; + var motionArgs = inputState.motionArgs || {}; + var operator = inputState.operator; + var operatorArgs = inputState.operatorArgs || {}; + var registerName = inputState.registerName; + var sel = vim.sel; + // TODO: Make sure cm and vim selections are identical outside visual mode. + var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head')); + var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor')); + var oldHead = copyCursor(origHead); + var oldAnchor = copyCursor(origAnchor); + var newHead, newAnchor; + var repeat; + if (operator) { + this.recordLastEdit(vim, inputState); + } + if (inputState.repeatOverride !== undefined) { + // If repeatOverride is specified, that takes precedence over the + // input state's repeat. Used by Ex mode and can be user defined. + repeat = inputState.repeatOverride; + } else { + repeat = inputState.getRepeat(); + } + if (repeat > 0 && motionArgs.explicitRepeat) { + motionArgs.repeatIsExplicit = true; + } else if (motionArgs.noRepeat || + (!motionArgs.explicitRepeat && repeat === 0)) { + repeat = 1; + motionArgs.repeatIsExplicit = false; + } + if (inputState.selectedCharacter) { + // If there is a character input, stick it in all of the arg arrays. + motionArgs.selectedCharacter = operatorArgs.selectedCharacter = + inputState.selectedCharacter; + } + motionArgs.repeat = repeat; + clearInputState(cm); + if (motion) { + var motionResult = motions[motion](cm, origHead, motionArgs, vim); + vim.lastMotion = motions[motion]; + if (!motionResult) { + return; + } + if (motionArgs.toJumplist) { + var jumpList = vimGlobalState.jumpList; + // if the current motion is # or *, use cachedCursor + var cachedCursor = jumpList.cachedCursor; + if (cachedCursor) { + recordJumpPosition(cm, cachedCursor, motionResult); + delete jumpList.cachedCursor; + } else { + recordJumpPosition(cm, origHead, motionResult); + } + } + if (motionResult instanceof Array) { + newAnchor = motionResult[0]; + newHead = motionResult[1]; + } else { + newHead = motionResult; + } + // TODO: Handle null returns from motion commands better. + if (!newHead) { + newHead = copyCursor(origHead); + } + if (vim.visualMode) { + if (!(vim.visualBlock && newHead.ch === Infinity)) { + newHead = clipCursorToContent(cm, newHead, vim.visualBlock); + } + if (newAnchor) { + newAnchor = clipCursorToContent(cm, newAnchor, true); + } + newAnchor = newAnchor || oldAnchor; + sel.anchor = newAnchor; + sel.head = newHead; + updateCmSelection(cm); + updateMark(cm, vim, '<', + cursorIsBefore(newAnchor, newHead) ? newAnchor + : newHead); + updateMark(cm, vim, '>', + cursorIsBefore(newAnchor, newHead) ? newHead + : newAnchor); + } else if (!operator) { + newHead = clipCursorToContent(cm, newHead); + cm.setCursor(newHead.line, newHead.ch); + } + } + if (operator) { + if (operatorArgs.lastSel) { + // Replaying a visual mode operation + newAnchor = oldAnchor; + var lastSel = operatorArgs.lastSel; + var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line); + var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch); + if (lastSel.visualLine) { + // Linewise Visual mode: The same number of lines. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + } else if (lastSel.visualBlock) { + // Blockwise Visual mode: The same number of lines and columns. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset); + } else if (lastSel.head.line == lastSel.anchor.line) { + // Normal Visual mode within one line: The same number of characters. + newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset); + } else { + // Normal Visual mode with several lines: The same number of lines, in the + // last line the same number of characters as in the last line the last time. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + } + vim.visualMode = true; + vim.visualLine = lastSel.visualLine; + vim.visualBlock = lastSel.visualBlock; + sel = vim.sel = { + anchor: newAnchor, + head: newHead + }; + updateCmSelection(cm); + } else if (vim.visualMode) { + operatorArgs.lastSel = { + anchor: copyCursor(sel.anchor), + head: copyCursor(sel.head), + visualBlock: vim.visualBlock, + visualLine: vim.visualLine + }; + } + var curStart, curEnd, linewise, mode; + var cmSel; + if (vim.visualMode) { + // Init visual op + curStart = cursorMin(sel.head, sel.anchor); + curEnd = cursorMax(sel.head, sel.anchor); + linewise = vim.visualLine || operatorArgs.linewise; + mode = vim.visualBlock ? 'block' : + linewise ? 'line' : + 'char'; + cmSel = makeCmSelection(cm, { + anchor: curStart, + head: curEnd + }, mode); + if (linewise) { + var ranges = cmSel.ranges; + if (mode == 'block') { + // Linewise operators in visual block mode extend to end of line + for (var i = 0; i < ranges.length; i++) { + ranges[i].head.ch = lineLength(cm, ranges[i].head.line); + } + } else if (mode == 'line') { + ranges[0].head = Pos(ranges[0].head.line + 1, 0); + } + } + } else { + // Init motion op + curStart = copyCursor(newAnchor || oldAnchor); + curEnd = copyCursor(newHead || oldHead); + if (cursorIsBefore(curEnd, curStart)) { + var tmp = curStart; + curStart = curEnd; + curEnd = tmp; + } + linewise = motionArgs.linewise || operatorArgs.linewise; + if (linewise) { + // Expand selection to entire line. + expandSelectionToLine(cm, curStart, curEnd); + } else if (motionArgs.forward) { + // Clip to trailing newlines only if the motion goes forward. + clipToLine(cm, curStart, curEnd); + } + mode = 'char'; + var exclusive = !motionArgs.inclusive || linewise; + cmSel = makeCmSelection(cm, { + anchor: curStart, + head: curEnd + }, mode, exclusive); + } + cm.setSelections(cmSel.ranges, cmSel.primary); + vim.lastMotion = null; + operatorArgs.repeat = repeat; // For indent in visual mode. + operatorArgs.registerName = registerName; + // Keep track of linewise as it affects how paste and change behave. + operatorArgs.linewise = linewise; + var operatorMoveTo = operators[operator]( + cm, operatorArgs, cmSel.ranges, oldAnchor, newHead); + if (vim.visualMode) { + exitVisualMode(cm, operatorMoveTo != null); + } + if (operatorMoveTo) { + cm.setCursor(operatorMoveTo); + } + } + }, + recordLastEdit: function(vim, inputState, actionCommand) { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { return; } + vim.lastEditInputState = inputState; + vim.lastEditActionCommand = actionCommand; + macroModeState.lastInsertModeChanges.changes = []; + macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false; + } + }; + + /** + * typedef {Object{line:number,ch:number}} Cursor An object containing the + * position of the cursor. + */ + // All of the functions below return Cursor objects. + var motions = { + moveToTopLine: function(cm, _head, motionArgs) { + var line = getUserVisibleLines(cm).top + motionArgs.repeat -1; + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + moveToMiddleLine: function(cm) { + var range = getUserVisibleLines(cm); + var line = Math.floor((range.top + range.bottom) * 0.5); + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + moveToBottomLine: function(cm, _head, motionArgs) { + var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1; + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + expandToLine: function(_cm, head, motionArgs) { + // Expands forward to end of line, and then to next line if repeat is + // >1. Does not handle backward motion! + var cur = head; + return Pos(cur.line + motionArgs.repeat - 1, Infinity); + }, + findNext: function(cm, _head, motionArgs) { + var state = getSearchState(cm); + var query = state.getQuery(); + if (!query) { + return; + } + var prev = !motionArgs.forward; + // If search is initiated with ? instead of /, negate direction. + prev = (state.isReversed()) ? !prev : prev; + highlightSearchMatches(cm, query); + return findNext(cm, prev/** prev */, query, motionArgs.repeat); + }, + goToMark: function(cm, _head, motionArgs, vim) { + var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter); + if (pos) { + return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos; + } + return null; + }, + moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) { + if (vim.visualBlock && motionArgs.sameLine) { + var sel = vim.sel; + return [ + clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)), + clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch)) + ]; + } else { + return ([vim.sel.head, vim.sel.anchor]); + } + }, + jumpToMark: function(cm, head, motionArgs, vim) { + var best = head; + for (var i = 0; i < motionArgs.repeat; i++) { + var cursor = best; + for (var key in vim.marks) { + if (!isLowerCase(key)) { + continue; + } + var mark = vim.marks[key].find(); + var isWrongDirection = (motionArgs.forward) ? + cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark); + + if (isWrongDirection) { + continue; + } + if (motionArgs.linewise && (mark.line == cursor.line)) { + continue; + } + + var equal = cursorEqual(cursor, best); + var between = (motionArgs.forward) ? + cursorIsBetween(cursor, mark, best) : + cursorIsBetween(best, mark, cursor); + + if (equal || between) { + best = mark; + } + } + } + + if (motionArgs.linewise) { + // Vim places the cursor on the first non-whitespace character of + // the line if there is one, else it places the cursor at the end + // of the line, regardless of whether a mark was found. + best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line))); + } + return best; + }, + moveByCharacters: function(_cm, head, motionArgs) { + var cur = head; + var repeat = motionArgs.repeat; + var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat; + return Pos(cur.line, ch); + }, + moveByLines: function(cm, head, motionArgs, vim) { + var cur = head; + var endCh = cur.ch; + // Depending what our last motion was, we may want to do different + // things. If our last motion was moving vertically, we want to + // preserve the HPos from our last horizontal move. If our last motion + // was going to the end of a line, moving vertically we should go to + // the end of the line, etc. + switch (vim.lastMotion) { + case this.moveByLines: + case this.moveByDisplayLines: + case this.moveByScroll: + case this.moveToColumn: + case this.moveToEol: + endCh = vim.lastHPos; + break; + default: + vim.lastHPos = endCh; + } + var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0); + var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat; + var first = cm.firstLine(); + var last = cm.lastLine(); + // Vim go to line begin or line end when cursor at first/last line and + // move to previous/next line is triggered. + if (line < first && cur.line == first){ + return this.moveToStartOfLine(cm, head, motionArgs, vim); + }else if (line > last && cur.line == last){ + return this.moveToEol(cm, head, motionArgs, vim); + } + if (motionArgs.toFirstChar){ + endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line)); + vim.lastHPos = endCh; + } + vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left; + return Pos(line, endCh); + }, + moveByDisplayLines: function(cm, head, motionArgs, vim) { + var cur = head; + switch (vim.lastMotion) { + case this.moveByDisplayLines: + case this.moveByScroll: + case this.moveByLines: + case this.moveToColumn: + case this.moveToEol: + break; + default: + vim.lastHSPos = cm.charCoords(cur,'div').left; + } + var repeat = motionArgs.repeat; + var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos); + if (res.hitSide) { + if (motionArgs.forward) { + var lastCharCoords = cm.charCoords(res, 'div'); + var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos }; + var res = cm.coordsChar(goalCoords, 'div'); + } else { + var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div'); + resCoords.left = vim.lastHSPos; + res = cm.coordsChar(resCoords, 'div'); + } + } + vim.lastHPos = res.ch; + return res; + }, + moveByPage: function(cm, head, motionArgs) { + // CodeMirror only exposes functions that move the cursor page down, so + // doing this bad hack to move the cursor and move it back. evalInput + // will move the cursor to where it should be in the end. + var curStart = head; + var repeat = motionArgs.repeat; + return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page'); + }, + moveByParagraph: function(cm, head, motionArgs) { + var dir = motionArgs.forward ? 1 : -1; + return findParagraph(cm, head, motionArgs.repeat, dir); + }, + moveByScroll: function(cm, head, motionArgs, vim) { + var scrollbox = cm.getScrollInfo(); + var curEnd = null; + var repeat = motionArgs.repeat; + if (!repeat) { + repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight()); + } + var orig = cm.charCoords(head, 'local'); + motionArgs.repeat = repeat; + var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim); + if (!curEnd) { + return null; + } + var dest = cm.charCoords(curEnd, 'local'); + cm.scrollTo(null, scrollbox.top + dest.top - orig.top); + return curEnd; + }, + moveByWords: function(cm, head, motionArgs) { + return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward, + !!motionArgs.wordEnd, !!motionArgs.bigWord); + }, + moveTillCharacter: function(cm, _head, motionArgs) { + var repeat = motionArgs.repeat; + var curEnd = moveToCharacter(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter); + var increment = motionArgs.forward ? -1 : 1; + recordLastCharacterSearch(increment, motionArgs); + if (!curEnd) return null; + curEnd.ch += increment; + return curEnd; + }, + moveToCharacter: function(cm, head, motionArgs) { + var repeat = motionArgs.repeat; + recordLastCharacterSearch(0, motionArgs); + return moveToCharacter(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter) || head; + }, + moveToSymbol: function(cm, head, motionArgs) { + var repeat = motionArgs.repeat; + return findSymbol(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter) || head; + }, + moveToColumn: function(cm, head, motionArgs, vim) { + var repeat = motionArgs.repeat; + // repeat is equivalent to which column we want to move to! + vim.lastHPos = repeat - 1; + vim.lastHSPos = cm.charCoords(head,'div').left; + return moveToColumn(cm, repeat); + }, + moveToEol: function(cm, head, motionArgs, vim) { + var cur = head; + vim.lastHPos = Infinity; + var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity); + var end=cm.clipPos(retval); + end.ch--; + vim.lastHSPos = cm.charCoords(end,'div').left; + return retval; + }, + moveToFirstNonWhiteSpaceCharacter: function(cm, head) { + // Go to the start of the line where the text begins, or the end for + // whitespace-only lines + var cursor = head; + return Pos(cursor.line, + findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line))); + }, + moveToMatchedSymbol: function(cm, head) { + var cursor = head; + var line = cursor.line; + var ch = cursor.ch; + var lineText = cm.getLine(line); + var symbol; + for (; ch < lineText.length; ch++) { + symbol = lineText.charAt(ch); + if (symbol && isMatchableSymbol(symbol)) { + var style = cm.getTokenTypeAt(Pos(line, ch + 1)); + if (style !== "string" && style !== "comment") { + break; + } + } + } + if (ch < lineText.length) { + var matched = cm.findMatchingBracket(Pos(line, ch)); + return matched.to; + } else { + return cursor; + } + }, + moveToStartOfLine: function(_cm, head) { + return Pos(head.line, 0); + }, + moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) { + var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine(); + if (motionArgs.repeatIsExplicit) { + lineNum = motionArgs.repeat - cm.getOption('firstLineNumber'); + } + return Pos(lineNum, + findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum))); + }, + textObjectManipulation: function(cm, head, motionArgs, vim) { + // TODO: lots of possible exceptions that can be thrown here. Try da( + // outside of a () block. + + // TODO: adding <> >< to this map doesn't work, presumably because + // they're operators + var mirroredPairs = {'(': ')', ')': '(', + '{': '}', '}': '{', + '[': ']', ']': '['}; + var selfPaired = {'\'': true, '"': true}; + + var character = motionArgs.selectedCharacter; + // 'b' refers to '()' block. + // 'B' refers to '{}' block. + if (character == 'b') { + character = '('; + } else if (character == 'B') { + character = '{'; + } + + // Inclusive is the difference between a and i + // TODO: Instead of using the additional text object map to perform text + // object operations, merge the map into the defaultKeyMap and use + // motionArgs to define behavior. Define separate entries for 'aw', + // 'iw', 'a[', 'i[', etc. + var inclusive = !motionArgs.textObjectInner; + + var tmp; + if (mirroredPairs[character]) { + tmp = selectCompanionObject(cm, head, character, inclusive); + } else if (selfPaired[character]) { + tmp = findBeginningAndEnd(cm, head, character, inclusive); + } else if (character === 'W') { + tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, + true /** bigWord */); + } else if (character === 'w') { + tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, + false /** bigWord */); + } else if (character === 'p') { + tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive); + motionArgs.linewise = true; + if (vim.visualMode) { + if (!vim.visualLine) { vim.visualLine = true; } + } else { + var operatorArgs = vim.inputState.operatorArgs; + if (operatorArgs) { operatorArgs.linewise = true; } + tmp.end.line--; + } + } else { + // No text object defined for this, don't move. + return null; + } + + if (!cm.state.vim.visualMode) { + return [tmp.start, tmp.end]; + } else { + return expandSelection(cm, tmp.start, tmp.end); + } + }, + + repeatLastCharacterSearch: function(cm, head, motionArgs) { + var lastSearch = vimGlobalState.lastCharacterSearch; + var repeat = motionArgs.repeat; + var forward = motionArgs.forward === lastSearch.forward; + var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1); + cm.moveH(-increment, 'char'); + motionArgs.inclusive = forward ? true : false; + var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter); + if (!curEnd) { + cm.moveH(increment, 'char'); + return head; + } + curEnd.ch += increment; + return curEnd; + } + }; + + function defineMotion(name, fn) { + motions[name] = fn; + } + + function fillArray(val, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(val); + } + return arr; + } + /** + * An operator acts on a text selection. It receives the list of selections + * as input. The corresponding CodeMirror selection is guaranteed to + * match the input selection. + */ + var operators = { + change: function(cm, args, ranges) { + var finalHead, text; + var vim = cm.state.vim; + vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock; + if (!vim.visualMode) { + var anchor = ranges[0].anchor, + head = ranges[0].head; + text = cm.getRange(anchor, head); + var lastState = vim.lastEditInputState || {}; + if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) { + // Exclude trailing whitespace if the range is not all whitespace. + var match = (/\s+$/).exec(text); + if (match && lastState.motionArgs && lastState.motionArgs.forward) { + head = offsetCursor(head, 0, - match[0].length); + text = text.slice(0, - match[0].length); + } + } + var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE); + var wasLastLine = cm.firstLine() == cm.lastLine(); + if (head.line > cm.lastLine() && args.linewise && !wasLastLine) { + cm.replaceRange('', prevLineEnd, head); + } else { + cm.replaceRange('', anchor, head); + } + if (args.linewise) { + // Push the next line back down, if there is a next line. + if (!wasLastLine) { + cm.setCursor(prevLineEnd); + CodeMirror.commands.newlineAndIndent(cm); + } + // make sure cursor ends up at the end of the line. + anchor.ch = Number.MAX_VALUE; + } + finalHead = anchor; + } else { + text = cm.getSelection(); + var replacement = fillArray('', ranges.length); + cm.replaceSelections(replacement); + finalHead = cursorMin(ranges[0].head, ranges[0].anchor); + } + vimGlobalState.registerController.pushText( + args.registerName, 'change', text, + args.linewise, ranges.length > 1); + actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim); + }, + // delete is a javascript keyword. + 'delete': function(cm, args, ranges) { + var finalHead, text; + var vim = cm.state.vim; + if (!vim.visualBlock) { + var anchor = ranges[0].anchor, + head = ranges[0].head; + if (args.linewise && + head.line != cm.firstLine() && + anchor.line == cm.lastLine() && + anchor.line == head.line - 1) { + // Special case for dd on last line (and first line). + if (anchor.line == cm.firstLine()) { + anchor.ch = 0; + } else { + anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1)); + } + } + text = cm.getRange(anchor, head); + cm.replaceRange('', anchor, head); + finalHead = anchor; + if (args.linewise) { + finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor); + } + } else { + text = cm.getSelection(); + var replacement = fillArray('', ranges.length); + cm.replaceSelections(replacement); + finalHead = ranges[0].anchor; + } + vimGlobalState.registerController.pushText( + args.registerName, 'delete', text, + args.linewise, vim.visualBlock); + var includeLineBreak = vim.insertMode + return clipCursorToContent(cm, finalHead, includeLineBreak); + }, + indent: function(cm, args, ranges) { + var vim = cm.state.vim; + var startLine = ranges[0].anchor.line; + var endLine = vim.visualBlock ? + ranges[ranges.length - 1].anchor.line : + ranges[0].head.line; + // In visual mode, n> shifts the selection right n times, instead of + // shifting n lines right once. + var repeat = (vim.visualMode) ? args.repeat : 1; + if (args.linewise) { + // The only way to delete a newline is to delete until the start of + // the next line, so in linewise mode evalInput will include the next + // line. We don't want this in indent, so we go back a line. + endLine--; + } + for (var i = startLine; i <= endLine; i++) { + for (var j = 0; j < repeat; j++) { + cm.indentLine(i, args.indentRight); + } + } + return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor); + }, + changeCase: function(cm, args, ranges, oldAnchor, newHead) { + var selections = cm.getSelections(); + var swapped = []; + var toLower = args.toLower; + for (var j = 0; j < selections.length; j++) { + var toSwap = selections[j]; + var text = ''; + if (toLower === true) { + text = toSwap.toLowerCase(); + } else if (toLower === false) { + text = toSwap.toUpperCase(); + } else { + for (var i = 0; i < toSwap.length; i++) { + var character = toSwap.charAt(i); + text += isUpperCase(character) ? character.toLowerCase() : + character.toUpperCase(); + } + } + swapped.push(text); + } + cm.replaceSelections(swapped); + if (args.shouldMoveCursor){ + return newHead; + } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) { + return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor); + } else if (args.linewise){ + return oldAnchor; + } else { + return cursorMin(ranges[0].anchor, ranges[0].head); + } + }, + yank: function(cm, args, ranges, oldAnchor) { + var vim = cm.state.vim; + var text = cm.getSelection(); + var endPos = vim.visualMode + ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor) + : oldAnchor; + vimGlobalState.registerController.pushText( + args.registerName, 'yank', + text, args.linewise, vim.visualBlock); + return endPos; + } + }; + + function defineOperator(name, fn) { + operators[name] = fn; + } + + var actions = { + jumpListWalk: function(cm, actionArgs, vim) { + if (vim.visualMode) { + return; + } + var repeat = actionArgs.repeat; + var forward = actionArgs.forward; + var jumpList = vimGlobalState.jumpList; + + var mark = jumpList.move(cm, forward ? repeat : -repeat); + var markPos = mark ? mark.find() : undefined; + markPos = markPos ? markPos : cm.getCursor(); + cm.setCursor(markPos); + }, + scroll: function(cm, actionArgs, vim) { + if (vim.visualMode) { + return; + } + var repeat = actionArgs.repeat || 1; + var lineHeight = cm.defaultTextHeight(); + var top = cm.getScrollInfo().top; + var delta = lineHeight * repeat; + var newPos = actionArgs.forward ? top + delta : top - delta; + var cursor = copyCursor(cm.getCursor()); + var cursorCoords = cm.charCoords(cursor, 'local'); + if (actionArgs.forward) { + if (newPos > cursorCoords.top) { + cursor.line += (newPos - cursorCoords.top) / lineHeight; + cursor.line = Math.ceil(cursor.line); + cm.setCursor(cursor); + cursorCoords = cm.charCoords(cursor, 'local'); + cm.scrollTo(null, cursorCoords.top); + } else { + // Cursor stays within bounds. Just reposition the scroll window. + cm.scrollTo(null, newPos); + } + } else { + var newBottom = newPos + cm.getScrollInfo().clientHeight; + if (newBottom < cursorCoords.bottom) { + cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight; + cursor.line = Math.floor(cursor.line); + cm.setCursor(cursor); + cursorCoords = cm.charCoords(cursor, 'local'); + cm.scrollTo( + null, cursorCoords.bottom - cm.getScrollInfo().clientHeight); + } else { + // Cursor stays within bounds. Just reposition the scroll window. + cm.scrollTo(null, newPos); + } + } + }, + scrollToCursor: function(cm, actionArgs) { + var lineNum = cm.getCursor().line; + var charCoords = cm.charCoords(Pos(lineNum, 0), 'local'); + var height = cm.getScrollInfo().clientHeight; + var y = charCoords.top; + var lineHeight = charCoords.bottom - y; + switch (actionArgs.position) { + case 'center': y = y - (height / 2) + lineHeight; + break; + case 'bottom': y = y - height + lineHeight; + break; + } + cm.scrollTo(null, y); + }, + replayMacro: function(cm, actionArgs, vim) { + var registerName = actionArgs.selectedCharacter; + var repeat = actionArgs.repeat; + var macroModeState = vimGlobalState.macroModeState; + if (registerName == '@') { + registerName = macroModeState.latestRegister; + } + while(repeat--){ + executeMacroRegister(cm, vim, macroModeState, registerName); + } + }, + enterMacroRecordMode: function(cm, actionArgs) { + var macroModeState = vimGlobalState.macroModeState; + var registerName = actionArgs.selectedCharacter; + if (vimGlobalState.registerController.isValidRegister(registerName)) { + macroModeState.enterMacroRecordMode(cm, registerName); + } + }, + toggleOverwrite: function(cm) { + if (!cm.state.overwrite) { + cm.toggleOverwrite(true); + cm.setOption('keyMap', 'vim-replace'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"}); + } else { + cm.toggleOverwrite(false); + cm.setOption('keyMap', 'vim-insert'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"}); + } + }, + enterInsertMode: function(cm, actionArgs, vim) { + if (cm.getOption('readOnly')) { return; } + vim.insertMode = true; + vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1; + var insertAt = (actionArgs) ? actionArgs.insertAt : null; + var sel = vim.sel; + var head = actionArgs.head || cm.getCursor('head'); + var height = cm.listSelections().length; + if (insertAt == 'eol') { + head = Pos(head.line, lineLength(cm, head.line)); + } else if (insertAt == 'charAfter') { + head = offsetCursor(head, 0, 1); + } else if (insertAt == 'firstNonBlank') { + head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head); + } else if (insertAt == 'startOfSelectedArea') { + if (!vim.visualBlock) { + if (sel.head.line < sel.anchor.line) { + head = sel.head; + } else { + head = Pos(sel.anchor.line, 0); + } + } else { + head = Pos( + Math.min(sel.head.line, sel.anchor.line), + Math.min(sel.head.ch, sel.anchor.ch)); + height = Math.abs(sel.head.line - sel.anchor.line) + 1; + } + } else if (insertAt == 'endOfSelectedArea') { + if (!vim.visualBlock) { + if (sel.head.line >= sel.anchor.line) { + head = offsetCursor(sel.head, 0, 1); + } else { + head = Pos(sel.anchor.line, 0); + } + } else { + head = Pos( + Math.min(sel.head.line, sel.anchor.line), + Math.max(sel.head.ch + 1, sel.anchor.ch)); + height = Math.abs(sel.head.line - sel.anchor.line) + 1; + } + } else if (insertAt == 'inplace') { + if (vim.visualMode){ + return; + } + } + cm.setOption('disableInput', false); + if (actionArgs && actionArgs.replace) { + // Handle Replace-mode as a special case of insert mode. + cm.toggleOverwrite(true); + cm.setOption('keyMap', 'vim-replace'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"}); + } else { + cm.toggleOverwrite(false); + cm.setOption('keyMap', 'vim-insert'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"}); + } + if (!vimGlobalState.macroModeState.isPlaying) { + // Only record if not replaying. + cm.on('change', onChange); + CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); + } + if (vim.visualMode) { + exitVisualMode(cm); + } + selectForInsert(cm, head, height); + }, + toggleVisualMode: function(cm, actionArgs, vim) { + var repeat = actionArgs.repeat; + var anchor = cm.getCursor(); + var head; + // TODO: The repeat should actually select number of characters/lines + // equal to the repeat times the size of the previous visual + // operation. + if (!vim.visualMode) { + // Entering visual mode + vim.visualMode = true; + vim.visualLine = !!actionArgs.linewise; + vim.visualBlock = !!actionArgs.blockwise; + head = clipCursorToContent( + cm, Pos(anchor.line, anchor.ch + repeat - 1), + true /** includeLineBreak */); + vim.sel = { + anchor: anchor, + head: head + }; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); + updateCmSelection(cm); + updateMark(cm, vim, '<', cursorMin(anchor, head)); + updateMark(cm, vim, '>', cursorMax(anchor, head)); + } else if (vim.visualLine ^ actionArgs.linewise || + vim.visualBlock ^ actionArgs.blockwise) { + // Toggling between modes + vim.visualLine = !!actionArgs.linewise; + vim.visualBlock = !!actionArgs.blockwise; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); + updateCmSelection(cm); + } else { + exitVisualMode(cm); + } + }, + reselectLastSelection: function(cm, _actionArgs, vim) { + var lastSelection = vim.lastSelection; + if (vim.visualMode) { + updateLastSelection(cm, vim); + } + if (lastSelection) { + var anchor = lastSelection.anchorMark.find(); + var head = lastSelection.headMark.find(); + if (!anchor || !head) { + // If the marks have been destroyed due to edits, do nothing. + return; + } + vim.sel = { + anchor: anchor, + head: head + }; + vim.visualMode = true; + vim.visualLine = lastSelection.visualLine; + vim.visualBlock = lastSelection.visualBlock; + updateCmSelection(cm); + updateMark(cm, vim, '<', cursorMin(anchor, head)); + updateMark(cm, vim, '>', cursorMax(anchor, head)); + CodeMirror.signal(cm, 'vim-mode-change', { + mode: 'visual', + subMode: vim.visualLine ? 'linewise' : + vim.visualBlock ? 'blockwise' : ''}); + } + }, + joinLines: function(cm, actionArgs, vim) { + var curStart, curEnd; + if (vim.visualMode) { + curStart = cm.getCursor('anchor'); + curEnd = cm.getCursor('head'); + if (cursorIsBefore(curEnd, curStart)) { + var tmp = curEnd; + curEnd = curStart; + curStart = tmp; + } + curEnd.ch = lineLength(cm, curEnd.line) - 1; + } else { + // Repeat is the number of lines to join. Minimum 2 lines. + var repeat = Math.max(actionArgs.repeat, 2); + curStart = cm.getCursor(); + curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1, + Infinity)); + } + var finalCh = 0; + for (var i = curStart.line; i < curEnd.line; i++) { + finalCh = lineLength(cm, curStart.line); + var tmp = Pos(curStart.line + 1, + lineLength(cm, curStart.line + 1)); + var text = cm.getRange(curStart, tmp); + text = text.replace(/\n\s*/g, ' '); + cm.replaceRange(text, curStart, tmp); + } + var curFinalPos = Pos(curStart.line, finalCh); + if (vim.visualMode) { + exitVisualMode(cm, false); + } + cm.setCursor(curFinalPos); + }, + newLineAndEnterInsertMode: function(cm, actionArgs, vim) { + vim.insertMode = true; + var insertAt = copyCursor(cm.getCursor()); + if (insertAt.line === cm.firstLine() && !actionArgs.after) { + // Special case for inserting newline before start of document. + cm.replaceRange('\n', Pos(cm.firstLine(), 0)); + cm.setCursor(cm.firstLine(), 0); + } else { + insertAt.line = (actionArgs.after) ? insertAt.line : + insertAt.line - 1; + insertAt.ch = lineLength(cm, insertAt.line); + cm.setCursor(insertAt); + var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment || + CodeMirror.commands.newlineAndIndent; + newlineFn(cm); + } + this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim); + }, + paste: function(cm, actionArgs, vim) { + var cur = copyCursor(cm.getCursor()); + var register = vimGlobalState.registerController.getRegister( + actionArgs.registerName); + var text = register.toString(); + if (!text) { + return; + } + if (actionArgs.matchIndent) { + var tabSize = cm.getOption("tabSize"); + // length that considers tabs and tabSize + var whitespaceLength = function(str) { + var tabs = (str.split("\t").length - 1); + var spaces = (str.split(" ").length - 1); + return tabs * tabSize + spaces * 1; + }; + var currentLine = cm.getLine(cm.getCursor().line); + var indent = whitespaceLength(currentLine.match(/^\s*/)[0]); + // chomp last newline b/c don't want it to match /^\s*/gm + var chompedText = text.replace(/\n$/, ''); + var wasChomped = text !== chompedText; + var firstIndent = whitespaceLength(text.match(/^\s*/)[0]); + var text = chompedText.replace(/^\s*/gm, function(wspace) { + var newIndent = indent + (whitespaceLength(wspace) - firstIndent); + if (newIndent < 0) { + return ""; + } + else if (cm.getOption("indentWithTabs")) { + var quotient = Math.floor(newIndent / tabSize); + return Array(quotient + 1).join('\t'); + } + else { + return Array(newIndent + 1).join(' '); + } + }); + text += wasChomped ? "\n" : ""; + } + if (actionArgs.repeat > 1) { + var text = Array(actionArgs.repeat + 1).join(text); + } + var linewise = register.linewise; + var blockwise = register.blockwise; + if (linewise) { + if(vim.visualMode) { + text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n'; + } else if (actionArgs.after) { + // Move the newline at the end to the start instead, and paste just + // before the newline character of the line we are on right now. + text = '\n' + text.slice(0, text.length - 1); + cur.ch = lineLength(cm, cur.line); + } else { + cur.ch = 0; + } + } else { + if (blockwise) { + text = text.split('\n'); + for (var i = 0; i < text.length; i++) { + text[i] = (text[i] == '') ? ' ' : text[i]; + } + } + cur.ch += actionArgs.after ? 1 : 0; + } + var curPosFinal; + var idx; + if (vim.visualMode) { + // save the pasted text for reselection if the need arises + vim.lastPastedText = text; + var lastSelectionCurEnd; + var selectedArea = getSelectedAreaRange(cm, vim); + var selectionStart = selectedArea[0]; + var selectionEnd = selectedArea[1]; + var selectedText = cm.getSelection(); + var selections = cm.listSelections(); + var emptyStrings = new Array(selections.length).join('1').split('1'); + // save the curEnd marker before it get cleared due to cm.replaceRange. + if (vim.lastSelection) { + lastSelectionCurEnd = vim.lastSelection.headMark.find(); + } + // push the previously selected text to unnamed register + vimGlobalState.registerController.unnamedRegister.setText(selectedText); + if (blockwise) { + // first delete the selected text + cm.replaceSelections(emptyStrings); + // Set new selections as per the block length of the yanked text + selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch); + cm.setCursor(selectionStart); + selectBlock(cm, selectionEnd); + cm.replaceSelections(text); + curPosFinal = selectionStart; + } else if (vim.visualBlock) { + cm.replaceSelections(emptyStrings); + cm.setCursor(selectionStart); + cm.replaceRange(text, selectionStart, selectionStart); + curPosFinal = selectionStart; + } else { + cm.replaceRange(text, selectionStart, selectionEnd); + curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1); + } + // restore the the curEnd marker + if(lastSelectionCurEnd) { + vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd); + } + if (linewise) { + curPosFinal.ch=0; + } + } else { + if (blockwise) { + cm.setCursor(cur); + for (var i = 0; i < text.length; i++) { + var line = cur.line+i; + if (line > cm.lastLine()) { + cm.replaceRange('\n', Pos(line, 0)); + } + var lastCh = lineLength(cm, line); + if (lastCh < cur.ch) { + extendLineToColumn(cm, line, cur.ch); + } + } + cm.setCursor(cur); + selectBlock(cm, Pos(cur.line + text.length-1, cur.ch)); + cm.replaceSelections(text); + curPosFinal = cur; + } else { + cm.replaceRange(text, cur); + // Now fine tune the cursor to where we want it. + if (linewise && actionArgs.after) { + curPosFinal = Pos( + cur.line + 1, + findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1))); + } else if (linewise && !actionArgs.after) { + curPosFinal = Pos( + cur.line, + findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line))); + } else if (!linewise && actionArgs.after) { + idx = cm.indexFromPos(cur); + curPosFinal = cm.posFromIndex(idx + text.length - 1); + } else { + idx = cm.indexFromPos(cur); + curPosFinal = cm.posFromIndex(idx + text.length); + } + } + } + if (vim.visualMode) { + exitVisualMode(cm, false); + } + cm.setCursor(curPosFinal); + }, + undo: function(cm, actionArgs) { + cm.operation(function() { + repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)(); + cm.setCursor(cm.getCursor('anchor')); + }); + }, + redo: function(cm, actionArgs) { + repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)(); + }, + setRegister: function(_cm, actionArgs, vim) { + vim.inputState.registerName = actionArgs.selectedCharacter; + }, + setMark: function(cm, actionArgs, vim) { + var markName = actionArgs.selectedCharacter; + updateMark(cm, vim, markName, cm.getCursor()); + }, + replace: function(cm, actionArgs, vim) { + var replaceWith = actionArgs.selectedCharacter; + var curStart = cm.getCursor(); + var replaceTo; + var curEnd; + var selections = cm.listSelections(); + if (vim.visualMode) { + curStart = cm.getCursor('start'); + curEnd = cm.getCursor('end'); + } else { + var line = cm.getLine(curStart.line); + replaceTo = curStart.ch + actionArgs.repeat; + if (replaceTo > line.length) { + replaceTo=line.length; + } + curEnd = Pos(curStart.line, replaceTo); + } + if (replaceWith=='\n') { + if (!vim.visualMode) cm.replaceRange('', curStart, curEnd); + // special case, where vim help says to replace by just one line-break + (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm); + } else { + var replaceWithStr = cm.getRange(curStart, curEnd); + //replace all characters in range by selected, but keep linebreaks + replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith); + if (vim.visualBlock) { + // Tabs are split in visua block before replacing + var spaces = new Array(cm.getOption("tabSize")+1).join(' '); + replaceWithStr = cm.getSelection(); + replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n'); + cm.replaceSelections(replaceWithStr); + } else { + cm.replaceRange(replaceWithStr, curStart, curEnd); + } + if (vim.visualMode) { + curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ? + selections[0].anchor : selections[0].head; + cm.setCursor(curStart); + exitVisualMode(cm, false); + } else { + cm.setCursor(offsetCursor(curEnd, 0, -1)); + } + } + }, + incrementNumberToken: function(cm, actionArgs) { + var cur = cm.getCursor(); + var lineStr = cm.getLine(cur.line); + var re = /-?\d+/g; + var match; + var start; + var end; + var numberStr; + var token; + while ((match = re.exec(lineStr)) !== null) { + token = match[0]; + start = match.index; + end = start + token.length; + if (cur.ch < end)break; + } + if (!actionArgs.backtrack && (end <= cur.ch))return; + if (token) { + var increment = actionArgs.increase ? 1 : -1; + var number = parseInt(token) + (increment * actionArgs.repeat); + var from = Pos(cur.line, start); + var to = Pos(cur.line, end); + numberStr = number.toString(); + cm.replaceRange(numberStr, from, to); + } else { + return; + } + cm.setCursor(Pos(cur.line, start + numberStr.length - 1)); + }, + repeatLastEdit: function(cm, actionArgs, vim) { + var lastEditInputState = vim.lastEditInputState; + if (!lastEditInputState) { return; } + var repeat = actionArgs.repeat; + if (repeat && actionArgs.repeatIsExplicit) { + vim.lastEditInputState.repeatOverride = repeat; + } else { + repeat = vim.lastEditInputState.repeatOverride || repeat; + } + repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */); + }, + indent: function(cm, actionArgs) { + cm.indentLine(cm.getCursor().line, actionArgs.indentRight); + }, + exitInsertMode: exitInsertMode + }; + + function defineAction(name, fn) { + actions[name] = fn; + } + + /* + * Below are miscellaneous utility functions used by vim.js + */ + + /** + * Clips cursor to ensure that line is within the buffer's range + * If includeLineBreak is true, then allow cur.ch == lineLength. + */ + function clipCursorToContent(cm, cur, includeLineBreak) { + var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() ); + var maxCh = lineLength(cm, line) - 1; + maxCh = (includeLineBreak) ? maxCh + 1 : maxCh; + var ch = Math.min(Math.max(0, cur.ch), maxCh); + return Pos(line, ch); + } + function copyArgs(args) { + var ret = {}; + for (var prop in args) { + if (args.hasOwnProperty(prop)) { + ret[prop] = args[prop]; + } + } + return ret; + } + function offsetCursor(cur, offsetLine, offsetCh) { + if (typeof offsetLine === 'object') { + offsetCh = offsetLine.ch; + offsetLine = offsetLine.line; + } + return Pos(cur.line + offsetLine, cur.ch + offsetCh); + } + function getOffset(anchor, head) { + return { + line: head.line - anchor.line, + ch: head.line - anchor.line + }; + } + function commandMatches(keys, keyMap, context, inputState) { + // Partial matches are not applied. They inform the key handler + // that the current key sequence is a subsequence of a valid key + // sequence, so that the key buffer is not cleared. + var match, partial = [], full = []; + for (var i = 0; i < keyMap.length; i++) { + var command = keyMap[i]; + if (context == 'insert' && command.context != 'insert' || + command.context && command.context != context || + inputState.operator && command.type == 'action' || + !(match = commandMatch(keys, command.keys))) { continue; } + if (match == 'partial') { partial.push(command); } + if (match == 'full') { full.push(command); } + } + return { + partial: partial.length && partial, + full: full.length && full + }; + } + function commandMatch(pressed, mapped) { + if (mapped.slice(-11) == '') { + // Last character matches anything. + var prefixLen = mapped.length - 11; + var pressedPrefix = pressed.slice(0, prefixLen); + var mappedPrefix = mapped.slice(0, prefixLen); + return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' : + mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false; + } else { + return pressed == mapped ? 'full' : + mapped.indexOf(pressed) == 0 ? 'partial' : false; + } + } + function lastChar(keys) { + var match = /^.*(<[^>]+>)$/.exec(keys); + var selectedCharacter = match ? match[1] : keys.slice(-1); + if (selectedCharacter.length > 1){ + switch(selectedCharacter){ + case '': + selectedCharacter='\n'; + break; + case '': + selectedCharacter=' '; + break; + default: + selectedCharacter=''; + break; + } + } + return selectedCharacter; + } + function repeatFn(cm, fn, repeat) { + return function() { + for (var i = 0; i < repeat; i++) { + fn(cm); + } + }; + } + function copyCursor(cur) { + return Pos(cur.line, cur.ch); + } + function cursorEqual(cur1, cur2) { + return cur1.ch == cur2.ch && cur1.line == cur2.line; + } + function cursorIsBefore(cur1, cur2) { + if (cur1.line < cur2.line) { + return true; + } + if (cur1.line == cur2.line && cur1.ch < cur2.ch) { + return true; + } + return false; + } + function cursorMin(cur1, cur2) { + if (arguments.length > 2) { + cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1)); + } + return cursorIsBefore(cur1, cur2) ? cur1 : cur2; + } + function cursorMax(cur1, cur2) { + if (arguments.length > 2) { + cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1)); + } + return cursorIsBefore(cur1, cur2) ? cur2 : cur1; + } + function cursorIsBetween(cur1, cur2, cur3) { + // returns true if cur2 is between cur1 and cur3. + var cur1before2 = cursorIsBefore(cur1, cur2); + var cur2before3 = cursorIsBefore(cur2, cur3); + return cur1before2 && cur2before3; + } + function lineLength(cm, lineNum) { + return cm.getLine(lineNum).length; + } + function trim(s) { + if (s.trim) { + return s.trim(); + } + return s.replace(/^\s+|\s+$/g, ''); + } + function escapeRegex(s) { + return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1'); + } + function extendLineToColumn(cm, lineNum, column) { + var endCh = lineLength(cm, lineNum); + var spaces = new Array(column-endCh+1).join(' '); + cm.setCursor(Pos(lineNum, endCh)); + cm.replaceRange(spaces, cm.getCursor()); + } + // This functions selects a rectangular block + // of text with selectionEnd as any of its corner + // Height of block: + // Difference in selectionEnd.line and first/last selection.line + // Width of the block: + // Distance between selectionEnd.ch and any(first considered here) selection.ch + function selectBlock(cm, selectionEnd) { + var selections = [], ranges = cm.listSelections(); + var head = copyCursor(cm.clipPos(selectionEnd)); + var isClipped = !cursorEqual(selectionEnd, head); + var curHead = cm.getCursor('head'); + var primIndex = getIndex(ranges, curHead); + var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor); + var max = ranges.length - 1; + var index = max - primIndex > primIndex ? max : 0; + var base = ranges[index].anchor; + + var firstLine = Math.min(base.line, head.line); + var lastLine = Math.max(base.line, head.line); + var baseCh = base.ch, headCh = head.ch; + + var dir = ranges[index].head.ch - baseCh; + var newDir = headCh - baseCh; + if (dir > 0 && newDir <= 0) { + baseCh++; + if (!isClipped) { headCh--; } + } else if (dir < 0 && newDir >= 0) { + baseCh--; + if (!wasClipped) { headCh++; } + } else if (dir < 0 && newDir == -1) { + baseCh--; + headCh++; + } + for (var line = firstLine; line <= lastLine; line++) { + var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)}; + selections.push(range); + } + cm.setSelections(selections); + selectionEnd.ch = headCh; + base.ch = baseCh; + return base; + } + function selectForInsert(cm, head, height) { + var sel = []; + for (var i = 0; i < height; i++) { + var lineHead = offsetCursor(head, i, 0); + sel.push({anchor: lineHead, head: lineHead}); + } + cm.setSelections(sel, 0); + } + // getIndex returns the index of the cursor in the selections. + function getIndex(ranges, cursor, end) { + for (var i = 0; i < ranges.length; i++) { + var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor); + var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor); + if (atAnchor || atHead) { + return i; + } + } + return -1; + } + function getSelectedAreaRange(cm, vim) { + var lastSelection = vim.lastSelection; + var getCurrentSelectedAreaRange = function() { + var selections = cm.listSelections(); + var start = selections[0]; + var end = selections[selections.length-1]; + var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head; + var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor; + return [selectionStart, selectionEnd]; + }; + var getLastSelectedAreaRange = function() { + var selectionStart = cm.getCursor(); + var selectionEnd = cm.getCursor(); + var block = lastSelection.visualBlock; + if (block) { + var width = block.width; + var height = block.height; + selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width); + var selections = []; + // selectBlock creates a 'proper' rectangular block. + // We do not want that in all cases, so we manually set selections. + for (var i = selectionStart.line; i < selectionEnd.line; i++) { + var anchor = Pos(i, selectionStart.ch); + var head = Pos(i, selectionEnd.ch); + var range = {anchor: anchor, head: head}; + selections.push(range); + } + cm.setSelections(selections); + } else { + var start = lastSelection.anchorMark.find(); + var end = lastSelection.headMark.find(); + var line = end.line - start.line; + var ch = end.ch - start.ch; + selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; + if (lastSelection.visualLine) { + selectionStart = Pos(selectionStart.line, 0); + selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); + } + cm.setSelection(selectionStart, selectionEnd); + } + return [selectionStart, selectionEnd]; + }; + if (!vim.visualMode) { + // In case of replaying the action. + return getLastSelectedAreaRange(); + } else { + return getCurrentSelectedAreaRange(); + } + } + // Updates the previous selection with the current selection's values. This + // should only be called in visual mode. + function updateLastSelection(cm, vim) { + var anchor = vim.sel.anchor; + var head = vim.sel.head; + // To accommodate the effect of lastPastedText in the last selection + if (vim.lastPastedText) { + head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length); + vim.lastPastedText = null; + } + vim.lastSelection = {'anchorMark': cm.setBookmark(anchor), + 'headMark': cm.setBookmark(head), + 'anchor': copyCursor(anchor), + 'head': copyCursor(head), + 'visualMode': vim.visualMode, + 'visualLine': vim.visualLine, + 'visualBlock': vim.visualBlock}; + } + function expandSelection(cm, start, end) { + var sel = cm.state.vim.sel; + var head = sel.head; + var anchor = sel.anchor; + var tmp; + if (cursorIsBefore(end, start)) { + tmp = end; + end = start; + start = tmp; + } + if (cursorIsBefore(head, anchor)) { + head = cursorMin(start, head); + anchor = cursorMax(anchor, end); + } else { + anchor = cursorMin(start, anchor); + head = cursorMax(head, end); + head = offsetCursor(head, 0, -1); + if (head.ch == -1 && head.line != cm.firstLine()) { + head = Pos(head.line - 1, lineLength(cm, head.line - 1)); + } + } + return [anchor, head]; + } + /** + * Updates the CodeMirror selection to match the provided vim selection. + * If no arguments are given, it uses the current vim selection state. + */ + function updateCmSelection(cm, sel, mode) { + var vim = cm.state.vim; + sel = sel || vim.sel; + var mode = mode || + vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char'; + var cmSel = makeCmSelection(cm, sel, mode); + cm.setSelections(cmSel.ranges, cmSel.primary); + updateFakeCursor(cm); + } + function makeCmSelection(cm, sel, mode, exclusive) { + var head = copyCursor(sel.head); + var anchor = copyCursor(sel.anchor); + if (mode == 'char') { + var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; + var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; + head = offsetCursor(sel.head, 0, headOffset); + anchor = offsetCursor(sel.anchor, 0, anchorOffset); + return { + ranges: [{anchor: anchor, head: head}], + primary: 0 + }; + } else if (mode == 'line') { + if (!cursorIsBefore(sel.head, sel.anchor)) { + anchor.ch = 0; + + var lastLine = cm.lastLine(); + if (head.line > lastLine) { + head.line = lastLine; + } + head.ch = lineLength(cm, head.line); + } else { + head.ch = 0; + anchor.ch = lineLength(cm, anchor.line); + } + return { + ranges: [{anchor: anchor, head: head}], + primary: 0 + }; + } else if (mode == 'block') { + var top = Math.min(anchor.line, head.line), + left = Math.min(anchor.ch, head.ch), + bottom = Math.max(anchor.line, head.line), + right = Math.max(anchor.ch, head.ch) + 1; + var height = bottom - top + 1; + var primary = head.line == top ? 0 : height - 1; + var ranges = []; + for (var i = 0; i < height; i++) { + ranges.push({ + anchor: Pos(top + i, left), + head: Pos(top + i, right) + }); + } + return { + ranges: ranges, + primary: primary + }; + } + } + function getHead(cm) { + var cur = cm.getCursor('head'); + if (cm.getSelection().length == 1) { + // Small corner case when only 1 character is selected. The "real" + // head is the left of head and anchor. + cur = cursorMin(cur, cm.getCursor('anchor')); + } + return cur; + } + + /** + * If moveHead is set to false, the CodeMirror selection will not be + * touched. The caller assumes the responsibility of putting the cursor + * in the right place. + */ + function exitVisualMode(cm, moveHead) { + var vim = cm.state.vim; + if (moveHead !== false) { + cm.setCursor(clipCursorToContent(cm, vim.sel.head)); + } + updateLastSelection(cm, vim); + vim.visualMode = false; + vim.visualLine = false; + vim.visualBlock = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + if (vim.fakeCursor) { + vim.fakeCursor.clear(); + } + } + + // Remove any trailing newlines from the selection. For + // example, with the caret at the start of the last word on the line, + // 'dw' should word, but not the newline, while 'w' should advance the + // caret to the first character of the next line. + function clipToLine(cm, curStart, curEnd) { + var selection = cm.getRange(curStart, curEnd); + // Only clip if the selection ends with trailing newline + whitespace + if (/\n\s*$/.test(selection)) { + var lines = selection.split('\n'); + // We know this is all whitespace. + lines.pop(); + + // Cases: + // 1. Last word is an empty line - do not clip the trailing '\n' + // 2. Last word is not an empty line - clip the trailing '\n' + var line; + // Find the line containing the last word, and clip all whitespace up + // to it. + for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) { + curEnd.line--; + curEnd.ch = 0; + } + // If the last word is not an empty line, clip an additional newline + if (line) { + curEnd.line--; + curEnd.ch = lineLength(cm, curEnd.line); + } else { + curEnd.ch = 0; + } + } + } + + // Expand the selection to line ends. + function expandSelectionToLine(_cm, curStart, curEnd) { + curStart.ch = 0; + curEnd.ch = 0; + curEnd.line++; + } + + function findFirstNonWhiteSpaceCharacter(text) { + if (!text) { + return 0; + } + var firstNonWS = text.search(/\S/); + return firstNonWS == -1 ? text.length : firstNonWS; + } + + function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) { + var cur = getHead(cm); + var line = cm.getLine(cur.line); + var idx = cur.ch; + + // Seek to first word or non-whitespace character, depending on if + // noSymbol is true. + var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0]; + while (!test(line.charAt(idx))) { + idx++; + if (idx >= line.length) { return null; } + } + + if (bigWord) { + test = bigWordCharTest[0]; + } else { + test = wordCharTest[0]; + if (!test(line.charAt(idx))) { + test = wordCharTest[1]; + } + } + + var end = idx, start = idx; + while (test(line.charAt(end)) && end < line.length) { end++; } + while (test(line.charAt(start)) && start >= 0) { start--; } + start++; + + if (inclusive) { + // If present, include all whitespace after word. + // Otherwise, include all whitespace before word, except indentation. + var wordEnd = end; + while (/\s/.test(line.charAt(end)) && end < line.length) { end++; } + if (wordEnd == end) { + var wordStart = start; + while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; } + if (!start) { start = wordStart; } + } + } + return { start: Pos(cur.line, start), end: Pos(cur.line, end) }; + } + + function recordJumpPosition(cm, oldCur, newCur) { + if (!cursorEqual(oldCur, newCur)) { + vimGlobalState.jumpList.add(cm, oldCur, newCur); + } + } + + function recordLastCharacterSearch(increment, args) { + vimGlobalState.lastCharacterSearch.increment = increment; + vimGlobalState.lastCharacterSearch.forward = args.forward; + vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter; + } + + var symbolToMode = { + '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket', + '[': 'section', ']': 'section', + '*': 'comment', '/': 'comment', + 'm': 'method', 'M': 'method', + '#': 'preprocess' + }; + var findSymbolModes = { + bracket: { + isComplete: function(state) { + if (state.nextCh === state.symb) { + state.depth++; + if (state.depth >= 1)return true; + } else if (state.nextCh === state.reverseSymb) { + state.depth--; + } + return false; + } + }, + section: { + init: function(state) { + state.curMoveThrough = true; + state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}'; + }, + isComplete: function(state) { + return state.index === 0 && state.nextCh === state.symb; + } + }, + comment: { + isComplete: function(state) { + var found = state.lastCh === '*' && state.nextCh === '/'; + state.lastCh = state.nextCh; + return found; + } + }, + // TODO: The original Vim implementation only operates on level 1 and 2. + // The current implementation doesn't check for code block level and + // therefore it operates on any levels. + method: { + init: function(state) { + state.symb = (state.symb === 'm' ? '{' : '}'); + state.reverseSymb = state.symb === '{' ? '}' : '{'; + }, + isComplete: function(state) { + if (state.nextCh === state.symb)return true; + return false; + } + }, + preprocess: { + init: function(state) { + state.index = 0; + }, + isComplete: function(state) { + if (state.nextCh === '#') { + var token = state.lineText.match(/#(\w+)/)[1]; + if (token === 'endif') { + if (state.forward && state.depth === 0) { + return true; + } + state.depth++; + } else if (token === 'if') { + if (!state.forward && state.depth === 0) { + return true; + } + state.depth--; + } + if (token === 'else' && state.depth === 0)return true; + } + return false; + } + } + }; + function findSymbol(cm, repeat, forward, symb) { + var cur = copyCursor(cm.getCursor()); + var increment = forward ? 1 : -1; + var endLine = forward ? cm.lineCount() : -1; + var curCh = cur.ch; + var line = cur.line; + var lineText = cm.getLine(line); + var state = { + lineText: lineText, + nextCh: lineText.charAt(curCh), + lastCh: null, + index: curCh, + symb: symb, + reverseSymb: (forward ? { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb], + forward: forward, + depth: 0, + curMoveThrough: false + }; + var mode = symbolToMode[symb]; + if (!mode)return cur; + var init = findSymbolModes[mode].init; + var isComplete = findSymbolModes[mode].isComplete; + if (init) { init(state); } + while (line !== endLine && repeat) { + state.index += increment; + state.nextCh = state.lineText.charAt(state.index); + if (!state.nextCh) { + line += increment; + state.lineText = cm.getLine(line) || ''; + if (increment > 0) { + state.index = 0; + } else { + var lineLen = state.lineText.length; + state.index = (lineLen > 0) ? (lineLen-1) : 0; + } + state.nextCh = state.lineText.charAt(state.index); + } + if (isComplete(state)) { + cur.line = line; + cur.ch = state.index; + repeat--; + } + } + if (state.nextCh || state.curMoveThrough) { + return Pos(line, state.index); + } + return cur; + } + + /* + * Returns the boundaries of the next word. If the cursor in the middle of + * the word, then returns the boundaries of the current word, starting at + * the cursor. If the cursor is at the start/end of a word, and we are going + * forward/backward, respectively, find the boundaries of the next word. + * + * @param {CodeMirror} cm CodeMirror object. + * @param {Cursor} cur The cursor position. + * @param {boolean} forward True to search forward. False to search + * backward. + * @param {boolean} bigWord True if punctuation count as part of the word. + * False if only [a-zA-Z0-9] characters count as part of the word. + * @param {boolean} emptyLineIsWord True if empty lines should be treated + * as words. + * @return {Object{from:number, to:number, line: number}} The boundaries of + * the word, or null if there are no more words. + */ + function findWord(cm, cur, forward, bigWord, emptyLineIsWord) { + var lineNum = cur.line; + var pos = cur.ch; + var line = cm.getLine(lineNum); + var dir = forward ? 1 : -1; + var charTests = bigWord ? bigWordCharTest: wordCharTest; + + if (emptyLineIsWord && line == '') { + lineNum += dir; + line = cm.getLine(lineNum); + if (!isLine(cm, lineNum)) { + return null; + } + pos = (forward) ? 0 : line.length; + } + + while (true) { + if (emptyLineIsWord && line == '') { + return { from: 0, to: 0, line: lineNum }; + } + var stop = (dir > 0) ? line.length : -1; + var wordStart = stop, wordEnd = stop; + // Find bounds of next word. + while (pos != stop) { + var foundWord = false; + for (var i = 0; i < charTests.length && !foundWord; ++i) { + if (charTests[i](line.charAt(pos))) { + wordStart = pos; + // Advance to end of word. + while (pos != stop && charTests[i](line.charAt(pos))) { + pos += dir; + } + wordEnd = pos; + foundWord = wordStart != wordEnd; + if (wordStart == cur.ch && lineNum == cur.line && + wordEnd == wordStart + dir) { + // We started at the end of a word. Find the next one. + continue; + } else { + return { + from: Math.min(wordStart, wordEnd + 1), + to: Math.max(wordStart, wordEnd), + line: lineNum }; + } + } + } + if (!foundWord) { + pos += dir; + } + } + // Advance to next/prev line. + lineNum += dir; + if (!isLine(cm, lineNum)) { + return null; + } + line = cm.getLine(lineNum); + pos = (dir > 0) ? 0 : line.length; + } + } + + /** + * @param {CodeMirror} cm CodeMirror object. + * @param {Pos} cur The position to start from. + * @param {int} repeat Number of words to move past. + * @param {boolean} forward True to search forward. False to search + * backward. + * @param {boolean} wordEnd True to move to end of word. False to move to + * beginning of word. + * @param {boolean} bigWord True if punctuation count as part of the word. + * False if only alphabet characters count as part of the word. + * @return {Cursor} The position the cursor should move to. + */ + function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) { + var curStart = copyCursor(cur); + var words = []; + if (forward && !wordEnd || !forward && wordEnd) { + repeat++; + } + // For 'e', empty lines are not considered words, go figure. + var emptyLineIsWord = !(forward && wordEnd); + for (var i = 0; i < repeat; i++) { + var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord); + if (!word) { + var eodCh = lineLength(cm, cm.lastLine()); + words.push(forward + ? {line: cm.lastLine(), from: eodCh, to: eodCh} + : {line: 0, from: 0, to: 0}); + break; + } + words.push(word); + cur = Pos(word.line, forward ? (word.to - 1) : word.from); + } + var shortCircuit = words.length != repeat; + var firstWord = words[0]; + var lastWord = words.pop(); + if (forward && !wordEnd) { + // w + if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) { + // We did not start in the middle of a word. Discard the extra word at the end. + lastWord = words.pop(); + } + return Pos(lastWord.line, lastWord.from); + } else if (forward && wordEnd) { + return Pos(lastWord.line, lastWord.to - 1); + } else if (!forward && wordEnd) { + // ge + if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) { + // We did not start in the middle of a word. Discard the extra word at the end. + lastWord = words.pop(); + } + return Pos(lastWord.line, lastWord.to); + } else { + // b + return Pos(lastWord.line, lastWord.from); + } + } + + function moveToCharacter(cm, repeat, forward, character) { + var cur = cm.getCursor(); + var start = cur.ch; + var idx; + for (var i = 0; i < repeat; i ++) { + var line = cm.getLine(cur.line); + idx = charIdxInLine(start, line, character, forward, true); + if (idx == -1) { + return null; + } + start = idx; + } + return Pos(cm.getCursor().line, idx); + } + + function moveToColumn(cm, repeat) { + // repeat is always >= 1, so repeat - 1 always corresponds + // to the column we want to go to. + var line = cm.getCursor().line; + return clipCursorToContent(cm, Pos(line, repeat - 1)); + } + + function updateMark(cm, vim, markName, pos) { + if (!inArray(markName, validMarks)) { + return; + } + if (vim.marks[markName]) { + vim.marks[markName].clear(); + } + vim.marks[markName] = cm.setBookmark(pos); + } + + function charIdxInLine(start, line, character, forward, includeChar) { + // Search for char in line. + // motion_options: {forward, includeChar} + // If includeChar = true, include it too. + // If forward = true, search forward, else search backwards. + // If char is not found on this line, do nothing + var idx; + if (forward) { + idx = line.indexOf(character, start + 1); + if (idx != -1 && !includeChar) { + idx -= 1; + } + } else { + idx = line.lastIndexOf(character, start - 1); + if (idx != -1 && !includeChar) { + idx += 1; + } + } + return idx; + } + + function findParagraph(cm, head, repeat, dir, inclusive) { + var line = head.line; + var min = cm.firstLine(); + var max = cm.lastLine(); + var start, end, i = line; + function isEmpty(i) { return !cm.getLine(i); } + function isBoundary(i, dir, any) { + if (any) { return isEmpty(i) != isEmpty(i + dir); } + return !isEmpty(i) && isEmpty(i + dir); + } + if (dir) { + while (min <= i && i <= max && repeat > 0) { + if (isBoundary(i, dir)) { repeat--; } + i += dir; + } + return new Pos(i, 0); + } + + var vim = cm.state.vim; + if (vim.visualLine && isBoundary(line, 1, true)) { + var anchor = vim.sel.anchor; + if (isBoundary(anchor.line, -1, true)) { + if (!inclusive || anchor.line != line) { + line += 1; + } + } + } + var startState = isEmpty(line); + for (i = line; i <= max && repeat; i++) { + if (isBoundary(i, 1, true)) { + if (!inclusive || isEmpty(i) != startState) { + repeat--; + } + } + } + end = new Pos(i, 0); + // select boundary before paragraph for the last one + if (i > max && !startState) { startState = true; } + else { inclusive = false; } + for (i = line; i > min; i--) { + if (!inclusive || isEmpty(i) == startState || i == line) { + if (isBoundary(i, -1, true)) { break; } + } + } + start = new Pos(i, 0); + return { start: start, end: end }; + } + + // TODO: perhaps this finagling of start and end positions belonds + // in codemirror/replaceRange? + function selectCompanionObject(cm, head, symb, inclusive) { + var cur = head, start, end; + + var bracketRegexp = ({ + '(': /[()]/, ')': /[()]/, + '[': /[[\]]/, ']': /[[\]]/, + '{': /[{}]/, '}': /[{}]/})[symb]; + var openSym = ({ + '(': '(', ')': '(', + '[': '[', ']': '[', + '{': '{', '}': '{'})[symb]; + var curChar = cm.getLine(cur.line).charAt(cur.ch); + // Due to the behavior of scanForBracket, we need to add an offset if the + // cursor is on a matching open bracket. + var offset = curChar === openSym ? 1 : 0; + + start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, null, {'bracketRegex': bracketRegexp}); + end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, null, {'bracketRegex': bracketRegexp}); + + if (!start || !end) { + return { start: cur, end: cur }; + } + + start = start.pos; + end = end.pos; + + if ((start.line == end.line && start.ch > end.ch) + || (start.line > end.line)) { + var tmp = start; + start = end; + end = tmp; + } + + if (inclusive) { + end.ch += 1; + } else { + start.ch += 1; + } + + return { start: start, end: end }; + } + + // Takes in a symbol and a cursor and tries to simulate text objects that + // have identical opening and closing symbols + // TODO support across multiple lines + function findBeginningAndEnd(cm, head, symb, inclusive) { + var cur = copyCursor(head); + var line = cm.getLine(cur.line); + var chars = line.split(''); + var start, end, i, len; + var firstIndex = chars.indexOf(symb); + + // the decision tree is to always look backwards for the beginning first, + // but if the cursor is in front of the first instance of the symb, + // then move the cursor forward + if (cur.ch < firstIndex) { + cur.ch = firstIndex; + // Why is this line even here??? + // cm.setCursor(cur.line, firstIndex+1); + } + // otherwise if the cursor is currently on the closing symbol + else if (firstIndex < cur.ch && chars[cur.ch] == symb) { + end = cur.ch; // assign end to the current cursor + --cur.ch; // make sure to look backwards + } + + // if we're currently on the symbol, we've got a start + if (chars[cur.ch] == symb && !end) { + start = cur.ch + 1; // assign start to ahead of the cursor + } else { + // go backwards to find the start + for (i = cur.ch; i > -1 && !start; i--) { + if (chars[i] == symb) { + start = i + 1; + } + } + } + + // look forwards for the end symbol + if (start && !end) { + for (i = start, len = chars.length; i < len && !end; i++) { + if (chars[i] == symb) { + end = i; + } + } + } + + // nothing found + if (!start || !end) { + return { start: cur, end: cur }; + } + + // include the symbols + if (inclusive) { + --start; ++end; + } + + return { + start: Pos(cur.line, start), + end: Pos(cur.line, end) + }; + } + + // Search functions + defineOption('pcre', true, 'boolean'); + function SearchState() {} + SearchState.prototype = { + getQuery: function() { + return vimGlobalState.query; + }, + setQuery: function(query) { + vimGlobalState.query = query; + }, + getOverlay: function() { + return this.searchOverlay; + }, + setOverlay: function(overlay) { + this.searchOverlay = overlay; + }, + isReversed: function() { + return vimGlobalState.isReversed; + }, + setReversed: function(reversed) { + vimGlobalState.isReversed = reversed; + }, + getScrollbarAnnotate: function() { + return this.annotate; + }, + setScrollbarAnnotate: function(annotate) { + this.annotate = annotate; + } + }; + function getSearchState(cm) { + var vim = cm.state.vim; + return vim.searchState_ || (vim.searchState_ = new SearchState()); + } + function dialog(cm, template, shortText, onClose, options) { + if (cm.openDialog) { + cm.openDialog(template, onClose, { bottom: true, value: options.value, + onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp, + selectValueOnOpen: false}); + } + else { + onClose(prompt(shortText, '')); + } + } + function splitBySlash(argString) { + var slashes = findUnescapedSlashes(argString) || []; + if (!slashes.length) return []; + var tokens = []; + // in case of strings like foo/bar + if (slashes[0] !== 0) return; + for (var i = 0; i < slashes.length; i++) { + if (typeof slashes[i] == 'number') + tokens.push(argString.substring(slashes[i] + 1, slashes[i+1])); + } + return tokens; + } + + function findUnescapedSlashes(str) { + var escapeNextChar = false; + var slashes = []; + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + if (!escapeNextChar && c == '/') { + slashes.push(i); + } + escapeNextChar = !escapeNextChar && (c == '\\'); + } + return slashes; + } + + // Translates a search string from ex (vim) syntax into javascript form. + function translateRegex(str) { + // When these match, add a '\' if unescaped or remove one if escaped. + var specials = '|(){'; + // Remove, but never add, a '\' for these. + var unescape = '}'; + var escapeNextChar = false; + var out = []; + for (var i = -1; i < str.length; i++) { + var c = str.charAt(i) || ''; + var n = str.charAt(i+1) || ''; + var specialComesNext = (n && specials.indexOf(n) != -1); + if (escapeNextChar) { + if (c !== '\\' || !specialComesNext) { + out.push(c); + } + escapeNextChar = false; + } else { + if (c === '\\') { + escapeNextChar = true; + // Treat the unescape list as special for removing, but not adding '\'. + if (n && unescape.indexOf(n) != -1) { + specialComesNext = true; + } + // Not passing this test means removing a '\'. + if (!specialComesNext || n === '\\') { + out.push(c); + } + } else { + out.push(c); + if (specialComesNext && n !== '\\') { + out.push('\\'); + } + } + } + } + return out.join(''); + } + + // Translates the replace part of a search and replace from ex (vim) syntax into + // javascript form. Similar to translateRegex, but additionally fixes back references + // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'. + var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'}; + function translateRegexReplace(str) { + var escapeNextChar = false; + var out = []; + for (var i = -1; i < str.length; i++) { + var c = str.charAt(i) || ''; + var n = str.charAt(i+1) || ''; + if (charUnescapes[c + n]) { + out.push(charUnescapes[c+n]); + i++; + } else if (escapeNextChar) { + // At any point in the loop, escapeNextChar is true if the previous + // character was a '\' and was not escaped. + out.push(c); + escapeNextChar = false; + } else { + if (c === '\\') { + escapeNextChar = true; + if ((isNumber(n) || n === '$')) { + out.push('$'); + } else if (n !== '/' && n !== '\\') { + out.push('\\'); + } + } else { + if (c === '$') { + out.push('$'); + } + out.push(c); + if (n === '/') { + out.push('\\'); + } + } + } + } + return out.join(''); + } + + // Unescape \ and / in the replace part, for PCRE mode. + var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'}; + function unescapeRegexReplace(str) { + var stream = new CodeMirror.StringStream(str); + var output = []; + while (!stream.eol()) { + // Search for \. + while (stream.peek() && stream.peek() != '\\') { + output.push(stream.next()); + } + var matched = false; + for (var matcher in unescapes) { + if (stream.match(matcher, true)) { + matched = true; + output.push(unescapes[matcher]); + break; + } + } + if (!matched) { + // Don't change anything + output.push(stream.next()); + } + } + return output.join(''); + } + + /** + * Extract the regular expression from the query and return a Regexp object. + * Returns null if the query is blank. + * If ignoreCase is passed in, the Regexp object will have the 'i' flag set. + * If smartCase is passed in, and the query contains upper case letters, + * then ignoreCase is overridden, and the 'i' flag will not be set. + * If the query contains the /i in the flag part of the regular expression, + * then both ignoreCase and smartCase are ignored, and 'i' will be passed + * through to the Regex object. + */ + function parseQuery(query, ignoreCase, smartCase) { + // First update the last search register + var lastSearchRegister = vimGlobalState.registerController.getRegister('/'); + lastSearchRegister.setText(query); + // Check if the query is already a regex. + if (query instanceof RegExp) { return query; } + // First try to extract regex + flags from the input. If no flags found, + // extract just the regex. IE does not accept flags directly defined in + // the regex string in the form /regex/flags + var slashes = findUnescapedSlashes(query); + var regexPart; + var forceIgnoreCase; + if (!slashes.length) { + // Query looks like 'regexp' + regexPart = query; + } else { + // Query looks like 'regexp/...' + regexPart = query.substring(0, slashes[0]); + var flagsPart = query.substring(slashes[0]); + forceIgnoreCase = (flagsPart.indexOf('i') != -1); + } + if (!regexPart) { + return null; + } + if (!getOption('pcre')) { + regexPart = translateRegex(regexPart); + } + if (smartCase) { + ignoreCase = (/^[^A-Z]*$/).test(regexPart); + } + var regexp = new RegExp(regexPart, + (ignoreCase || forceIgnoreCase) ? 'i' : undefined); + return regexp; + } + function showConfirm(cm, text) { + if (cm.openNotification) { + cm.openNotification('' + text + '', + {bottom: true, duration: 5000}); + } else { + alert(text); + } + } + function makePrompt(prefix, desc) { + var raw = '' + + (prefix || "") + ''; + if (desc) + raw += ' ' + desc + ''; + return raw; + } + var searchPromptDesc = '(Javascript regexp)'; + function showPrompt(cm, options) { + var shortText = (options.prefix || '') + ' ' + (options.desc || ''); + var prompt = makePrompt(options.prefix, options.desc); + dialog(cm, prompt, shortText, options.onClose, options); + } + function regexEqual(r1, r2) { + if (r1 instanceof RegExp && r2 instanceof RegExp) { + var props = ['global', 'multiline', 'ignoreCase', 'source']; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (r1[prop] !== r2[prop]) { + return false; + } + } + return true; + } + return false; + } + // Returns true if the query is valid. + function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) { + if (!rawQuery) { + return; + } + var state = getSearchState(cm); + var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase); + if (!query) { + return; + } + highlightSearchMatches(cm, query); + if (regexEqual(query, state.getQuery())) { + return query; + } + state.setQuery(query); + return query; + } + function searchOverlay(query) { + if (query.source.charAt(0) == '^') { + var matchSol = true; + } + return { + token: function(stream) { + if (matchSol && !stream.sol()) { + stream.skipToEnd(); + return; + } + var match = stream.match(query, false); + if (match) { + if (match[0].length == 0) { + // Matched empty string, skip to next. + stream.next(); + return 'searching'; + } + if (!stream.sol()) { + // Backtrack 1 to match \b + stream.backUp(1); + if (!query.exec(stream.next() + match[0])) { + stream.next(); + return null; + } + } + stream.match(query); + return 'searching'; + } + while (!stream.eol()) { + stream.next(); + if (stream.match(query, false)) break; + } + }, + query: query + }; + } + function highlightSearchMatches(cm, query) { + var searchState = getSearchState(cm); + var overlay = searchState.getOverlay(); + if (!overlay || query != overlay.query) { + if (overlay) { + cm.removeOverlay(overlay); + } + overlay = searchOverlay(query); + cm.addOverlay(overlay); + if (cm.showMatchesOnScrollbar) { + if (searchState.getScrollbarAnnotate()) { + searchState.getScrollbarAnnotate().clear(); + } + searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query)); + } + searchState.setOverlay(overlay); + } + } + function findNext(cm, prev, query, repeat) { + if (repeat === undefined) { repeat = 1; } + return cm.operation(function() { + var pos = cm.getCursor(); + var cursor = cm.getSearchCursor(query, pos); + for (var i = 0; i < repeat; i++) { + var found = cursor.find(prev); + if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); } + if (!found) { + // SearchCursor may have returned null because it hit EOF, wrap + // around and try again. + cursor = cm.getSearchCursor(query, + (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) ); + if (!cursor.find(prev)) { + return; + } + } + } + return cursor.from(); + }); + } + function clearSearchHighlight(cm) { + var state = getSearchState(cm); + cm.removeOverlay(getSearchState(cm).getOverlay()); + state.setOverlay(null); + if (state.getScrollbarAnnotate()) { + state.getScrollbarAnnotate().clear(); + state.setScrollbarAnnotate(null); + } + } + /** + * Check if pos is in the specified range, INCLUSIVE. + * Range can be specified with 1 or 2 arguments. + * If the first range argument is an array, treat it as an array of line + * numbers. Match pos against any of the lines. + * If the first range argument is a number, + * if there is only 1 range argument, check if pos has the same line + * number + * if there are 2 range arguments, then check if pos is in between the two + * range arguments. + */ + function isInRange(pos, start, end) { + if (typeof pos != 'number') { + // Assume it is a cursor position. Get the line number. + pos = pos.line; + } + if (start instanceof Array) { + return inArray(pos, start); + } else { + if (end) { + return (pos >= start && pos <= end); + } else { + return pos == start; + } + } + } + function getUserVisibleLines(cm) { + var scrollInfo = cm.getScrollInfo(); + var occludeToleranceTop = 6; + var occludeToleranceBottom = 10; + var from = cm.coordsChar({left:0, top: occludeToleranceTop + scrollInfo.top}, 'local'); + var bottomY = scrollInfo.clientHeight - occludeToleranceBottom + scrollInfo.top; + var to = cm.coordsChar({left:0, top: bottomY}, 'local'); + return {top: from.line, bottom: to.line}; + } + + function getMarkPos(cm, vim, markName) { + if (markName == '\'') { + var history = cm.doc.history.done; + var event = history[history.length - 2]; + return event && event.ranges && event.ranges[0].head; + } else if (markName == '.') { + if (cm.doc.history.lastModTime == 0) { + return // If no changes, bail out; don't bother to copy or reverse history array. + } else { + var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } }); + changeHistory.reverse(); + var lastEditPos = changeHistory[0].changes[0].to; + } + return lastEditPos; + } + + var mark = vim.marks[markName]; + return mark && mark.find(); + } + + var ExCommandDispatcher = function() { + this.buildCommandMap_(); + }; + ExCommandDispatcher.prototype = { + processCommand: function(cm, input, opt_params) { + var that = this; + cm.operation(function () { + cm.curOp.isVimOp = true; + that._processCommand(cm, input, opt_params); + }); + }, + _processCommand: function(cm, input, opt_params) { + var vim = cm.state.vim; + var commandHistoryRegister = vimGlobalState.registerController.getRegister(':'); + var previousCommand = commandHistoryRegister.toString(); + if (vim.visualMode) { + exitVisualMode(cm); + } + var inputStream = new CodeMirror.StringStream(input); + // update ": with the latest command whether valid or invalid + commandHistoryRegister.setText(input); + var params = opt_params || {}; + params.input = input; + try { + this.parseInput_(cm, inputStream, params); + } catch(e) { + showConfirm(cm, e); + throw e; + } + var command; + var commandName; + if (!params.commandName) { + // If only a line range is defined, move to the line. + if (params.line !== undefined) { + commandName = 'move'; + } + } else { + command = this.matchCommand_(params.commandName); + if (command) { + commandName = command.name; + if (command.excludeFromCommandHistory) { + commandHistoryRegister.setText(previousCommand); + } + this.parseCommandArgs_(inputStream, params, command); + if (command.type == 'exToKey') { + // Handle Ex to Key mapping. + for (var i = 0; i < command.toKeys.length; i++) { + CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping'); + } + return; + } else if (command.type == 'exToEx') { + // Handle Ex to Ex mapping. + this.processCommand(cm, command.toInput); + return; + } + } + } + if (!commandName) { + showConfirm(cm, 'Not an editor command ":' + input + '"'); + return; + } + try { + exCommands[commandName](cm, params); + // Possibly asynchronous commands (e.g. substitute, which might have a + // user confirmation), are responsible for calling the callback when + // done. All others have it taken care of for them here. + if ((!command || !command.possiblyAsync) && params.callback) { + params.callback(); + } + } catch(e) { + showConfirm(cm, e); + throw e; + } + }, + parseInput_: function(cm, inputStream, result) { + inputStream.eatWhile(':'); + // Parse range. + if (inputStream.eat('%')) { + result.line = cm.firstLine(); + result.lineEnd = cm.lastLine(); + } else { + result.line = this.parseLineSpec_(cm, inputStream); + if (result.line !== undefined && inputStream.eat(',')) { + result.lineEnd = this.parseLineSpec_(cm, inputStream); + } + } + + // Parse command name. + var commandMatch = inputStream.match(/^(\w+)/); + if (commandMatch) { + result.commandName = commandMatch[1]; + } else { + result.commandName = inputStream.match(/.*/)[0]; + } + + return result; + }, + parseLineSpec_: function(cm, inputStream) { + var numberMatch = inputStream.match(/^(\d+)/); + if (numberMatch) { + // Absolute line number plus offset (N+M or N-M) is probably a typo, + // not something the user actually wanted. (NB: vim does allow this.) + return parseInt(numberMatch[1], 10) - 1; + } + switch (inputStream.next()) { + case '.': + return this.parseLineSpecOffset_(inputStream, cm.getCursor().line); + case '$': + return this.parseLineSpecOffset_(inputStream, cm.lastLine()); + case '\'': + var markName = inputStream.next(); + var markPos = getMarkPos(cm, cm.state.vim, markName); + if (!markPos) throw new Error('Mark not set'); + return this.parseLineSpecOffset_(inputStream, markPos.line); + case '-': + case '+': + inputStream.backUp(1); + // Offset is relative to current line if not otherwise specified. + return this.parseLineSpecOffset_(inputStream, cm.getCursor().line); + default: + inputStream.backUp(1); + return undefined; + } + }, + parseLineSpecOffset_: function(inputStream, line) { + var offsetMatch = inputStream.match(/^([+-])?(\d+)/); + if (offsetMatch) { + var offset = parseInt(offsetMatch[2], 10); + if (offsetMatch[1] == "-") { + line -= offset; + } else { + line += offset; + } + } + return line; + }, + parseCommandArgs_: function(inputStream, params, command) { + if (inputStream.eol()) { + return; + } + params.argString = inputStream.match(/.*/)[0]; + // Parse command-line arguments + var delim = command.argDelimiter || /\s+/; + var args = trim(params.argString).split(delim); + if (args.length && args[0]) { + params.args = args; + } + }, + matchCommand_: function(commandName) { + // Return the command in the command map that matches the shortest + // prefix of the passed in command name. The match is guaranteed to be + // unambiguous if the defaultExCommandMap's shortNames are set up + // correctly. (see @code{defaultExCommandMap}). + for (var i = commandName.length; i > 0; i--) { + var prefix = commandName.substring(0, i); + if (this.commandMap_[prefix]) { + var command = this.commandMap_[prefix]; + if (command.name.indexOf(commandName) === 0) { + return command; + } + } + } + return null; + }, + buildCommandMap_: function() { + this.commandMap_ = {}; + for (var i = 0; i < defaultExCommandMap.length; i++) { + var command = defaultExCommandMap[i]; + var key = command.shortName || command.name; + this.commandMap_[key] = command; + } + }, + map: function(lhs, rhs, ctx) { + if (lhs != ':' && lhs.charAt(0) == ':') { + if (ctx) { throw Error('Mode not supported for ex mappings'); } + var commandName = lhs.substring(1); + if (rhs != ':' && rhs.charAt(0) == ':') { + // Ex to Ex mapping + this.commandMap_[commandName] = { + name: commandName, + type: 'exToEx', + toInput: rhs.substring(1), + user: true + }; + } else { + // Ex to key mapping + this.commandMap_[commandName] = { + name: commandName, + type: 'exToKey', + toKeys: rhs, + user: true + }; + } + } else { + if (rhs != ':' && rhs.charAt(0) == ':') { + // Key to Ex mapping. + var mapping = { + keys: lhs, + type: 'keyToEx', + exArgs: { input: rhs.substring(1) } + }; + if (ctx) { mapping.context = ctx; } + defaultKeymap.unshift(mapping); + } else { + // Key to key mapping + var mapping = { + keys: lhs, + type: 'keyToKey', + toKeys: rhs + }; + if (ctx) { mapping.context = ctx; } + defaultKeymap.unshift(mapping); + } + } + }, + unmap: function(lhs, ctx) { + if (lhs != ':' && lhs.charAt(0) == ':') { + // Ex to Ex or Ex to key mapping + if (ctx) { throw Error('Mode not supported for ex mappings'); } + var commandName = lhs.substring(1); + if (this.commandMap_[commandName] && this.commandMap_[commandName].user) { + delete this.commandMap_[commandName]; + return; + } + } else { + // Key to Ex or key to key mapping + var keys = lhs; + for (var i = 0; i < defaultKeymap.length; i++) { + if (keys == defaultKeymap[i].keys + && defaultKeymap[i].context === ctx) { + defaultKeymap.splice(i, 1); + return; + } + } + } + throw Error('No such mapping.'); + } + }; + + var exCommands = { + colorscheme: function(cm, params) { + if (!params.args || params.args.length < 1) { + showConfirm(cm, cm.getOption('theme')); + return; + } + cm.setOption('theme', params.args[0]); + }, + map: function(cm, params, ctx) { + var mapArgs = params.args; + if (!mapArgs || mapArgs.length < 2) { + if (cm) { + showConfirm(cm, 'Invalid mapping: ' + params.input); + } + return; + } + exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx); + }, + imap: function(cm, params) { this.map(cm, params, 'insert'); }, + nmap: function(cm, params) { this.map(cm, params, 'normal'); }, + vmap: function(cm, params) { this.map(cm, params, 'visual'); }, + unmap: function(cm, params, ctx) { + var mapArgs = params.args; + if (!mapArgs || mapArgs.length < 1) { + if (cm) { + showConfirm(cm, 'No such mapping: ' + params.input); + } + return; + } + exCommandDispatcher.unmap(mapArgs[0], ctx); + }, + move: function(cm, params) { + commandDispatcher.processCommand(cm, cm.state.vim, { + type: 'motion', + motion: 'moveToLineOrEdgeOfDocument', + motionArgs: { forward: false, explicitRepeat: true, + linewise: true }, + repeatOverride: params.line+1}); + }, + set: function(cm, params) { + var setArgs = params.args; + // Options passed through to the setOption/getOption calls. May be passed in by the + // local/global versions of the set command + var setCfg = params.setCfg || {}; + if (!setArgs || setArgs.length < 1) { + if (cm) { + showConfirm(cm, 'Invalid mapping: ' + params.input); + } + return; + } + var expr = setArgs[0].split('='); + var optionName = expr[0]; + var value = expr[1]; + var forceGet = false; + + if (optionName.charAt(optionName.length - 1) == '?') { + // If post-fixed with ?, then the set is actually a get. + if (value) { throw Error('Trailing characters: ' + params.argString); } + optionName = optionName.substring(0, optionName.length - 1); + forceGet = true; + } + if (value === undefined && optionName.substring(0, 2) == 'no') { + // To set boolean options to false, the option name is prefixed with + // 'no'. + optionName = optionName.substring(2); + value = false; + } + + var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean'; + if (optionIsBoolean && value == undefined) { + // Calling set with a boolean option sets it to true. + value = true; + } + // If no value is provided, then we assume this is a get. + if (!optionIsBoolean && value === undefined || forceGet) { + var oldValue = getOption(optionName, cm, setCfg); + if (oldValue instanceof Error) { + showConfirm(cm, oldValue.message); + } else if (oldValue === true || oldValue === false) { + showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName); + } else { + showConfirm(cm, ' ' + optionName + '=' + oldValue); + } + } else { + var setOptionReturn = setOption(optionName, value, cm, setCfg); + if (setOptionReturn instanceof Error) { + showConfirm(cm, setOptionReturn.message); + } + } + }, + setlocal: function (cm, params) { + // setCfg is passed through to setOption + params.setCfg = {scope: 'local'}; + this.set(cm, params); + }, + setglobal: function (cm, params) { + // setCfg is passed through to setOption + params.setCfg = {scope: 'global'}; + this.set(cm, params); + }, + registers: function(cm, params) { + var regArgs = params.args; + var registers = vimGlobalState.registerController.registers; + var regInfo = '----------Registers----------

'; + if (!regArgs) { + for (var registerName in registers) { + var text = registers[registerName].toString(); + if (text.length) { + regInfo += '"' + registerName + ' ' + text + '
'; + } + } + } else { + var registerName; + regArgs = regArgs.join(''); + for (var i = 0; i < regArgs.length; i++) { + registerName = regArgs.charAt(i); + if (!vimGlobalState.registerController.isValidRegister(registerName)) { + continue; + } + var register = registers[registerName] || new Register(); + regInfo += '"' + registerName + ' ' + register.toString() + '
'; + } + } + showConfirm(cm, regInfo); + }, + sort: function(cm, params) { + var reverse, ignoreCase, unique, number, pattern; + function parseArgs() { + if (params.argString) { + var args = new CodeMirror.StringStream(params.argString); + if (args.eat('!')) { reverse = true; } + if (args.eol()) { return; } + if (!args.eatSpace()) { return 'Invalid arguments'; } + var opts = args.match(/([dinuox]+)?\s*(\/.+\/)?\s*/); + if (!opts && !args.eol()) { return 'Invalid arguments'; } + if (opts[1]) { + ignoreCase = opts[1].indexOf('i') != -1; + unique = opts[1].indexOf('u') != -1; + var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1; + var hex = opts[1].indexOf('x') != -1 && 1; + var octal = opts[1].indexOf('o') != -1 && 1; + if (decimal + hex + octal > 1) { return 'Invalid arguments'; } + number = decimal && 'decimal' || hex && 'hex' || octal && 'octal'; + } + if (opts[2]) { + pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : ''); + } + } + } + var err = parseArgs(); + if (err) { + showConfirm(cm, err + ': ' + params.argString); + return; + } + var lineStart = params.line || cm.firstLine(); + var lineEnd = params.lineEnd || params.line || cm.lastLine(); + if (lineStart == lineEnd) { return; } + var curStart = Pos(lineStart, 0); + var curEnd = Pos(lineEnd, lineLength(cm, lineEnd)); + var text = cm.getRange(curStart, curEnd).split('\n'); + var numberRegex = pattern ? pattern : + (number == 'decimal') ? /(-?)([\d]+)/ : + (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i : + (number == 'octal') ? /([0-7]+)/ : null; + var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null; + var numPart = [], textPart = []; + if (number || pattern) { + for (var i = 0; i < text.length; i++) { + var matchPart = pattern ? text[i].match(pattern) : null; + if (matchPart && matchPart[0] != '') { + numPart.push(matchPart); + } else if (!pattern && numberRegex.exec(text[i])) { + numPart.push(text[i]); + } else { + textPart.push(text[i]); + } + } + } else { + textPart = text; + } + function compareFn(a, b) { + if (reverse) { var tmp; tmp = a; a = b; b = tmp; } + if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); } + var anum = number && numberRegex.exec(a); + var bnum = number && numberRegex.exec(b); + if (!anum) { return a < b ? -1 : 1; } + anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix); + bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix); + return anum - bnum; + } + function comparePatternFn(a, b) { + if (reverse) { var tmp; tmp = a; a = b; b = tmp; } + if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); } + return (a[0] < b[0]) ? -1 : 1; + } + numPart.sort(pattern ? comparePatternFn : compareFn); + if (pattern) { + for (var i = 0; i < numPart.length; i++) { + numPart[i] = numPart[i].input; + } + } else if (!number) { textPart.sort(compareFn); } + text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart); + if (unique) { // Remove duplicate lines + var textOld = text; + var lastLine; + text = []; + for (var i = 0; i < textOld.length; i++) { + if (textOld[i] != lastLine) { + text.push(textOld[i]); + } + lastLine = textOld[i]; + } + } + cm.replaceRange(text.join('\n'), curStart, curEnd); + }, + global: function(cm, params) { + // a global command is of the form + // :[range]g/pattern/[cmd] + // argString holds the string /pattern/[cmd] + var argString = params.argString; + if (!argString) { + showConfirm(cm, 'Regular Expression missing from global'); + return; + } + // range is specified here + var lineStart = (params.line !== undefined) ? params.line : cm.firstLine(); + var lineEnd = params.lineEnd || params.line || cm.lastLine(); + // get the tokens from argString + var tokens = splitBySlash(argString); + var regexPart = argString, cmd; + if (tokens.length) { + regexPart = tokens[0]; + cmd = tokens.slice(1, tokens.length).join('/'); + } + if (regexPart) { + // If regex part is empty, then use the previous query. Otherwise + // use the regex part as the new query. + try { + updateSearchQuery(cm, regexPart, true /** ignoreCase */, + true /** smartCase */); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + regexPart); + return; + } + } + // now that we have the regexPart, search for regex matches in the + // specified range of lines + var query = getSearchState(cm).getQuery(); + var matchedLines = [], content = ''; + for (var i = lineStart; i <= lineEnd; i++) { + var matched = query.test(cm.getLine(i)); + if (matched) { + matchedLines.push(i+1); + content+= cm.getLine(i) + '
'; + } + } + // if there is no [cmd], just display the list of matched lines + if (!cmd) { + showConfirm(cm, content); + return; + } + var index = 0; + var nextCommand = function() { + if (index < matchedLines.length) { + var command = matchedLines[index] + cmd; + exCommandDispatcher.processCommand(cm, command, { + callback: nextCommand + }); + } + index++; + }; + nextCommand(); + }, + substitute: function(cm, params) { + if (!cm.getSearchCursor) { + throw new Error('Search feature not available. Requires searchcursor.js or ' + + 'any other getSearchCursor implementation.'); + } + var argString = params.argString; + var tokens = argString ? splitBySlash(argString) : []; + var regexPart, replacePart = '', trailing, flagsPart, count; + var confirm = false; // Whether to confirm each replace. + var global = false; // True to replace all instances on a line, false to replace only 1. + if (tokens.length) { + regexPart = tokens[0]; + replacePart = tokens[1]; + if (regexPart && regexPart[regexPart.length - 1] === '$') { + regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n'; + replacePart = replacePart ? replacePart + '\n' : '\n'; + } + if (replacePart !== undefined) { + if (getOption('pcre')) { + replacePart = unescapeRegexReplace(replacePart); + } else { + replacePart = translateRegexReplace(replacePart); + } + vimGlobalState.lastSubstituteReplacePart = replacePart; + } + trailing = tokens[2] ? tokens[2].split(' ') : []; + } else { + // either the argString is empty or its of the form ' hello/world' + // actually splitBySlash returns a list of tokens + // only if the string starts with a '/' + if (argString && argString.length) { + showConfirm(cm, 'Substitutions should be of the form ' + + ':s/pattern/replace/'); + return; + } + } + // After the 3rd slash, we can have flags followed by a space followed + // by count. + if (trailing) { + flagsPart = trailing[0]; + count = parseInt(trailing[1]); + if (flagsPart) { + if (flagsPart.indexOf('c') != -1) { + confirm = true; + flagsPart.replace('c', ''); + } + if (flagsPart.indexOf('g') != -1) { + global = true; + flagsPart.replace('g', ''); + } + regexPart = regexPart + '/' + flagsPart; + } + } + if (regexPart) { + // If regex part is empty, then use the previous query. Otherwise use + // the regex part as the new query. + try { + updateSearchQuery(cm, regexPart, true /** ignoreCase */, + true /** smartCase */); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + regexPart); + return; + } + } + replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart; + if (replacePart === undefined) { + showConfirm(cm, 'No previous substitute regular expression'); + return; + } + var state = getSearchState(cm); + var query = state.getQuery(); + var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line; + var lineEnd = params.lineEnd || lineStart; + if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) { + lineEnd = Infinity; + } + if (count) { + lineStart = lineEnd; + lineEnd = lineStart + count - 1; + } + var startPos = clipCursorToContent(cm, Pos(lineStart, 0)); + var cursor = cm.getSearchCursor(query, startPos); + doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback); + }, + redo: CodeMirror.commands.redo, + undo: CodeMirror.commands.undo, + write: function(cm) { + if (CodeMirror.commands.save) { + // If a save command is defined, call it. + CodeMirror.commands.save(cm); + } else if (cm.save) { + // Saves to text area if no save command is defined and cm.save() is available. + cm.save(); + } + }, + nohlsearch: function(cm) { + clearSearchHighlight(cm); + }, + yank: function (cm) { + var cur = copyCursor(cm.getCursor()); + var line = cur.line; + var lineText = cm.getLine(line); + vimGlobalState.registerController.pushText( + '0', 'yank', lineText, true, true); + }, + delmarks: function(cm, params) { + if (!params.argString || !trim(params.argString)) { + showConfirm(cm, 'Argument required'); + return; + } + + var state = cm.state.vim; + var stream = new CodeMirror.StringStream(trim(params.argString)); + while (!stream.eol()) { + stream.eatSpace(); + + // Record the streams position at the beginning of the loop for use + // in error messages. + var count = stream.pos; + + if (!stream.match(/[a-zA-Z]/, false)) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + var sym = stream.next(); + // Check if this symbol is part of a range + if (stream.match('-', true)) { + // This symbol is part of a range. + + // The range must terminate at an alphabetic character. + if (!stream.match(/[a-zA-Z]/, false)) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + var startMark = sym; + var finishMark = stream.next(); + // The range must terminate at an alphabetic character which + // shares the same case as the start of the range. + if (isLowerCase(startMark) && isLowerCase(finishMark) || + isUpperCase(startMark) && isUpperCase(finishMark)) { + var start = startMark.charCodeAt(0); + var finish = finishMark.charCodeAt(0); + if (start >= finish) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + // Because marks are always ASCII values, and we have + // determined that they are the same case, we can use + // their char codes to iterate through the defined range. + for (var j = 0; j <= finish - start; j++) { + var mark = String.fromCharCode(start + j); + delete state.marks[mark]; + } + } else { + showConfirm(cm, 'Invalid argument: ' + startMark + '-'); + return; + } + } else { + // This symbol is a valid mark, and is not part of a range. + delete state.marks[sym]; + } + } + } + }; + + var exCommandDispatcher = new ExCommandDispatcher(); + + /** + * @param {CodeMirror} cm CodeMirror instance we are in. + * @param {boolean} confirm Whether to confirm each replace. + * @param {Cursor} lineStart Line to start replacing from. + * @param {Cursor} lineEnd Line to stop replacing at. + * @param {RegExp} query Query for performing matches with. + * @param {string} replaceWith Text to replace matches with. May contain $1, + * $2, etc for replacing captured groups using Javascript replace. + * @param {function()} callback A callback for when the replace is done. + */ + function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query, + replaceWith, callback) { + // Set up all the functions. + cm.state.vim.exMode = true; + var done = false; + var lastPos = searchCursor.from(); + function replaceAll() { + cm.operation(function() { + while (!done) { + replace(); + next(); + } + stop(); + }); + } + function replace() { + var text = cm.getRange(searchCursor.from(), searchCursor.to()); + var newText = text.replace(query, replaceWith); + searchCursor.replace(newText); + } + function next() { + // The below only loops to skip over multiple occurrences on the same + // line when 'global' is not true. + while(searchCursor.findNext() && + isInRange(searchCursor.from(), lineStart, lineEnd)) { + if (!global && lastPos && searchCursor.from().line == lastPos.line) { + continue; + } + cm.scrollIntoView(searchCursor.from(), 30); + cm.setSelection(searchCursor.from(), searchCursor.to()); + lastPos = searchCursor.from(); + done = false; + return; + } + done = true; + } + function stop(close) { + if (close) { close(); } + cm.focus(); + if (lastPos) { + cm.setCursor(lastPos); + var vim = cm.state.vim; + vim.exMode = false; + vim.lastHPos = vim.lastHSPos = lastPos.ch; + } + if (callback) { callback(); } + } + function onPromptKeyDown(e, _value, close) { + // Swallow all keys. + CodeMirror.e_stop(e); + var keyName = CodeMirror.keyName(e); + switch (keyName) { + case 'Y': + replace(); next(); break; + case 'N': + next(); break; + case 'A': + // replaceAll contains a call to close of its own. We don't want it + // to fire too early or multiple times. + var savedCallback = callback; + callback = undefined; + cm.operation(replaceAll); + callback = savedCallback; + break; + case 'L': + replace(); + // fall through and exit. + case 'Q': + case 'Esc': + case 'Ctrl-C': + case 'Ctrl-[': + stop(close); + break; + } + if (done) { stop(close); } + return true; + } + + // Actually do replace. + next(); + if (done) { + showConfirm(cm, 'No matches for ' + query.source); + return; + } + if (!confirm) { + replaceAll(); + if (callback) { callback(); }; + return; + } + showPrompt(cm, { + prefix: 'replace with ' + replaceWith + ' (y/n/a/q/l)', + onKeyDown: onPromptKeyDown + }); + } + + CodeMirror.keyMap.vim = { + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + function exitInsertMode(cm) { + var vim = cm.state.vim; + var macroModeState = vimGlobalState.macroModeState; + var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.'); + var isPlaying = macroModeState.isPlaying; + var lastChange = macroModeState.lastInsertModeChanges; + // In case of visual block, the insertModeChanges are not saved as a + // single word, so we convert them to a single word + // so as to update the ". register as expected in real vim. + var text = []; + if (!isPlaying) { + var selLength = lastChange.inVisualBlock && vim.lastSelection ? + vim.lastSelection.visualBlock.height : 1; + var changes = lastChange.changes; + var text = []; + var i = 0; + // In case of multiple selections in blockwise visual, + // the inserted text, for example: 'foo', is stored as + // 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines). + // We push the contents of the changes array as per the following: + // 1. In case of InsertModeKey, just increment by 1. + // 2. In case of a character, jump by selLength (2 in the example). + while (i < changes.length) { + // This loop will convert 'ffoooo' to 'foo'. + text.push(changes[i]); + if (changes[i] instanceof InsertModeKey) { + i++; + } else { + i+= selLength; + } + } + lastChange.changes = text; + cm.off('change', onChange); + CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); + } + if (!isPlaying && vim.insertModeRepeat > 1) { + // Perform insert mode repeat for commands like 3,a and 3,o. + repeatLastEdit(cm, vim, vim.insertModeRepeat - 1, + true /** repeatForInsert */); + vim.lastEditInputState.repeatOverride = vim.insertModeRepeat; + } + delete vim.insertModeRepeat; + vim.insertMode = false; + cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1); + cm.setOption('keyMap', 'vim'); + cm.setOption('disableInput', true); + cm.toggleOverwrite(false); // exit replace mode if we were in it. + // update the ". register before exiting insert mode + insertModeChangeRegister.setText(lastChange.changes.join('')); + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + if (macroModeState.isRecording) { + logInsertModeChange(macroModeState); + } + } + + function _mapCommand(command) { + defaultKeymap.unshift(command); + } + + function mapCommand(keys, type, name, args, extra) { + var command = {keys: keys, type: type}; + command[type] = name; + command[type + "Args"] = args; + for (var key in extra) + command[key] = extra[key]; + _mapCommand(command); + } + + // The timeout in milliseconds for the two-character ESC keymap should be + // adjusted according to your typing speed to prevent false positives. + defineOption('insertModeEscKeysTimeout', 200, 'number'); + + CodeMirror.keyMap['vim-insert'] = { + // TODO: override navigation keys so that Esc will cancel automatic + // indentation from o, O, i_ + fallthrough: ['default'], + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + CodeMirror.keyMap['vim-replace'] = { + 'Backspace': 'goCharLeft', + fallthrough: ['vim-insert'], + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + function executeMacroRegister(cm, vim, macroModeState, registerName) { + var register = vimGlobalState.registerController.getRegister(registerName); + if (registerName == ':') { + // Read-only register containing last Ex command. + if (register.keyBuffer[0]) { + exCommandDispatcher.processCommand(cm, register.keyBuffer[0]); + } + macroModeState.isPlaying = false; + return; + } + var keyBuffer = register.keyBuffer; + var imc = 0; + macroModeState.isPlaying = true; + macroModeState.replaySearchQueries = register.searchQueries.slice(0); + for (var i = 0; i < keyBuffer.length; i++) { + var text = keyBuffer[i]; + var match, key; + while (text) { + // Pull off one command key, which is either a single character + // or a special sequence wrapped in '<' and '>', e.g. ''. + match = (/<\w+-.+?>|<\w+>|./).exec(text); + key = match[0]; + text = text.substring(match.index + key.length); + CodeMirror.Vim.handleKey(cm, key, 'macro'); + if (vim.insertMode) { + var changes = register.insertModeChanges[imc++].changes; + vimGlobalState.macroModeState.lastInsertModeChanges.changes = + changes; + repeatInsertModeChanges(cm, changes, 1); + exitInsertMode(cm); + } + } + }; + macroModeState.isPlaying = false; + } + + function logKey(macroModeState, key) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.pushText(key); + } + } + + function logInsertModeChange(macroModeState) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register && register.pushInsertModeChanges) { + register.pushInsertModeChanges(macroModeState.lastInsertModeChanges); + } + } + + function logSearchQuery(macroModeState, query) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register && register.pushSearchQuery) { + register.pushSearchQuery(query); + } + } + + /** + * Listens for changes made in insert mode. + * Should only be active in insert mode. + */ + function onChange(cm, changeObj) { + var macroModeState = vimGlobalState.macroModeState; + var lastChange = macroModeState.lastInsertModeChanges; + if (!macroModeState.isPlaying) { + while(changeObj) { + lastChange.expectCursorActivityForChange = true; + if (changeObj.origin == '+input' || changeObj.origin == 'paste' + || changeObj.origin === undefined /* only in testing */) { + var text = changeObj.text.join('\n'); + if (lastChange.maybeReset) { + lastChange.changes = []; + lastChange.maybeReset = false; + } + if (cm.state.overwrite && !/\n/.test(text)) { + lastChange.changes.push([text]); + } else { + lastChange.changes.push(text); + } + } + // Change objects may be chained with next. + changeObj = changeObj.next; + } + } + } + + /** + * Listens for any kind of cursor activity on CodeMirror. + */ + function onCursorActivity(cm) { + var vim = cm.state.vim; + if (vim.insertMode) { + // Tracking cursor activity in insert mode (for macro support). + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { return; } + var lastChange = macroModeState.lastInsertModeChanges; + if (lastChange.expectCursorActivityForChange) { + lastChange.expectCursorActivityForChange = false; + } else { + // Cursor moved outside the context of an edit. Reset the change. + lastChange.maybeReset = true; + } + } else if (!cm.curOp.isVimOp) { + handleExternalSelection(cm, vim); + } + if (vim.visualMode) { + updateFakeCursor(cm); + } + } + function updateFakeCursor(cm) { + var vim = cm.state.vim; + var from = clipCursorToContent(cm, copyCursor(vim.sel.head)); + var to = offsetCursor(from, 0, 1); + if (vim.fakeCursor) { + vim.fakeCursor.clear(); + } + vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'}); + } + function handleExternalSelection(cm, vim) { + var anchor = cm.getCursor('anchor'); + var head = cm.getCursor('head'); + // Enter or exit visual mode to match mouse selection. + if (vim.visualMode && !cm.somethingSelected()) { + exitVisualMode(cm, false); + } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) { + vim.visualMode = true; + vim.visualLine = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"}); + } + if (vim.visualMode) { + // Bind CodeMirror selection model to vim selection model. + // Mouse selections are considered visual characterwise. + var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0; + var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0; + head = offsetCursor(head, 0, headOffset); + anchor = offsetCursor(anchor, 0, anchorOffset); + vim.sel = { + anchor: anchor, + head: head + }; + updateMark(cm, vim, '<', cursorMin(head, anchor)); + updateMark(cm, vim, '>', cursorMax(head, anchor)); + } else if (!vim.insertMode) { + // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse. + vim.lastHPos = cm.getCursor().ch; + } + } + + /** Wrapper for special keys pressed in insert mode */ + function InsertModeKey(keyName) { + this.keyName = keyName; + } + + /** + * Handles raw key down events from the text area. + * - Should only be active in insert mode. + * - For recording deletes in insert mode. + */ + function onKeyEventTargetKeyDown(e) { + var macroModeState = vimGlobalState.macroModeState; + var lastChange = macroModeState.lastInsertModeChanges; + var keyName = CodeMirror.keyName(e); + if (!keyName) { return; } + function onKeyFound() { + if (lastChange.maybeReset) { + lastChange.changes = []; + lastChange.maybeReset = false; + } + lastChange.changes.push(new InsertModeKey(keyName)); + return true; + } + if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) { + CodeMirror.lookupKey(keyName, 'vim-insert', onKeyFound); + } + } + + /** + * Repeats the last edit, which includes exactly 1 command and at most 1 + * insert. Operator and motion commands are read from lastEditInputState, + * while action commands are read from lastEditActionCommand. + * + * If repeatForInsert is true, then the function was called by + * exitInsertMode to repeat the insert mode changes the user just made. The + * corresponding enterInsertMode call was made with a count. + */ + function repeatLastEdit(cm, vim, repeat, repeatForInsert) { + var macroModeState = vimGlobalState.macroModeState; + macroModeState.isPlaying = true; + var isAction = !!vim.lastEditActionCommand; + var cachedInputState = vim.inputState; + function repeatCommand() { + if (isAction) { + commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand); + } else { + commandDispatcher.evalInput(cm, vim); + } + } + function repeatInsert(repeat) { + if (macroModeState.lastInsertModeChanges.changes.length > 0) { + // For some reason, repeat cw in desktop VIM does not repeat + // insert mode changes. Will conform to that behavior. + repeat = !vim.lastEditActionCommand ? 1 : repeat; + var changeObject = macroModeState.lastInsertModeChanges; + repeatInsertModeChanges(cm, changeObject.changes, repeat); + } + } + vim.inputState = vim.lastEditInputState; + if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) { + // o and O repeat have to be interlaced with insert repeats so that the + // insertions appear on separate lines instead of the last line. + for (var i = 0; i < repeat; i++) { + repeatCommand(); + repeatInsert(1); + } + } else { + if (!repeatForInsert) { + // Hack to get the cursor to end up at the right place. If I is + // repeated in insert mode repeat, cursor will be 1 insert + // change set left of where it should be. + repeatCommand(); + } + repeatInsert(repeat); + } + vim.inputState = cachedInputState; + if (vim.insertMode && !repeatForInsert) { + // Don't exit insert mode twice. If repeatForInsert is set, then we + // were called by an exitInsertMode call lower on the stack. + exitInsertMode(cm); + } + macroModeState.isPlaying = false; + }; + + function repeatInsertModeChanges(cm, changes, repeat) { + function keyHandler(binding) { + if (typeof binding == 'string') { + CodeMirror.commands[binding](cm); + } else { + binding(cm); + } + return true; + } + var head = cm.getCursor('head'); + var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock; + if (inVisualBlock) { + // Set up block selection again for repeating the changes. + var vim = cm.state.vim; + var lastSel = vim.lastSelection; + var offset = getOffset(lastSel.anchor, lastSel.head); + selectForInsert(cm, head, offset.line + 1); + repeat = cm.listSelections().length; + cm.setCursor(head); + } + for (var i = 0; i < repeat; i++) { + if (inVisualBlock) { + cm.setCursor(offsetCursor(head, i, 0)); + } + for (var j = 0; j < changes.length; j++) { + var change = changes[j]; + if (change instanceof InsertModeKey) { + CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler); + } else if (typeof change == "string") { + var cur = cm.getCursor(); + cm.replaceRange(change, cur, cur); + } else { + var start = cm.getCursor(); + var end = offsetCursor(start, 0, change[0].length); + cm.replaceRange(change[0], start, end); + } + } + } + if (inVisualBlock) { + cm.setCursor(offsetCursor(head, 0, 1)); + } + } + + resetVimGlobalState(); + return vimApi; + }; + // Initialize Vim and make it available as an API. + CodeMirror.Vim = Vim(); +}); diff --git a/backend/webif/static/codemirror/lib/codemirror.css b/backend/webif/static/codemirror/lib/codemirror.css new file mode 100755 index 000000000..8f4f22f5d --- /dev/null +++ b/backend/webif/static/codemirror/lib/codemirror.css @@ -0,0 +1,346 @@ +/* BASICS */ + +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; + color: black; + direction: ltr; +} + +/* PADDING */ + +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} +.CodeMirror pre { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ + +.CodeMirror-gutters { + border-right: 1px solid #ddd; + background-color: #f7f7f7; + white-space: nowrap; +} +.CodeMirror-linenumbers {} +.CodeMirror-linenumber { + padding: 0 3px 0 5px; + min-width: 20px; + text-align: right; + color: #999; + white-space: nowrap; +} + +.CodeMirror-guttermarker { color: black; } +.CodeMirror-guttermarker-subtle { color: #999; } + +/* CURSOR */ + +.CodeMirror-cursor { + border-left: 1px solid black; + border-right: none; + width: 0; +} +/* Shown when moving in bi-directional text */ +.CodeMirror div.CodeMirror-secondarycursor { + border-left: 1px solid silver; +} +.cm-fat-cursor .CodeMirror-cursor { + width: auto; + border: 0 !important; + background: #7e7; +} +.cm-fat-cursor div.CodeMirror-cursors { + z-index: 1; +} +.cm-fat-cursor-mark { + background-color: rgba(20, 255, 20, 0.5); + -webkit-animation: blink 1.06s steps(1) infinite; + -moz-animation: blink 1.06s steps(1) infinite; + animation: blink 1.06s steps(1) infinite; +} +.cm-animate-fat-cursor { + width: auto; + border: 0; + -webkit-animation: blink 1.06s steps(1) infinite; + -moz-animation: blink 1.06s steps(1) infinite; + animation: blink 1.06s steps(1) infinite; + background-color: #7e7; +} +@-moz-keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} +@-webkit-keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} +@keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} + +/* Can style cursor different in overwrite (non-insert) mode */ +.CodeMirror-overwrite .CodeMirror-cursor {} + +.cm-tab { display: inline-block; text-decoration: inherit; } + +.CodeMirror-rulers { + position: absolute; + left: 0; right: 0; top: -50px; bottom: -20px; + overflow: hidden; +} +.CodeMirror-ruler { + border-left: 1px solid #ccc; + top: 0; bottom: 0; + position: absolute; +} + +/* DEFAULT THEME */ + +.cm-s-default .cm-header {color: blue;} +.cm-s-default .cm-quote {color: #090;} +.cm-negative {color: #d44;} +.cm-positive {color: #292;} +.cm-header, .cm-strong {font-weight: bold;} +.cm-em {font-style: italic;} +.cm-link {text-decoration: underline;} +.cm-strikethrough {text-decoration: line-through;} + +.cm-s-default .cm-keyword {color: #708;} +.cm-s-default .cm-atom {color: #219;} +.cm-s-default .cm-number {color: #164;} +.cm-s-default .cm-def {color: #00f;} +.cm-s-default .cm-variable, +.cm-s-default .cm-punctuation, +.cm-s-default .cm-property, +.cm-s-default .cm-operator {} +.cm-s-default .cm-variable-2 {color: #05a;} +.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;} +.cm-s-default .cm-comment {color: #a50;} +.cm-s-default .cm-string {color: #a11;} +.cm-s-default .cm-string-2 {color: #f50;} +.cm-s-default .cm-meta {color: #555;} +.cm-s-default .cm-qualifier {color: #555;} +.cm-s-default .cm-builtin {color: #30a;} +.cm-s-default .cm-bracket {color: #997;} +.cm-s-default .cm-tag {color: #170;} +.cm-s-default .cm-attribute {color: #00c;} +.cm-s-default .cm-hr {color: #999;} +.cm-s-default .cm-link {color: #00c;} + +.cm-s-default .cm-error {color: #f00;} +.cm-invalidchar {color: #f00;} + +.CodeMirror-composing { border-bottom: 2px solid; } + +/* Default styles for common addons */ + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;} +.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } +.CodeMirror-activeline-background {background: #e8f2ff;} + +/* STOP */ + +/* The rest of this file contains styles related to the mechanics of + the editor. You probably shouldn't touch them. */ + +.CodeMirror { + position: relative; + overflow: hidden; + background: white; +} + +.CodeMirror-scroll { + overflow: scroll !important; /* Things will break if this is overridden */ + /* 30px is the magic margin used to hide the element's real scrollbars */ + /* See overflow: hidden in .CodeMirror */ + margin-bottom: -30px; margin-right: -30px; + padding-bottom: 30px; + height: 100%; + outline: none; /* Prevent dragging from highlighting the element */ + position: relative; +} +.CodeMirror-sizer { + position: relative; + border-right: 30px solid transparent; +} + +/* The fake, visible scrollbars. Used to force redraw during scrolling + before actual scrolling happens, thus preventing shaking and + flickering artifacts. */ +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + position: absolute; + z-index: 6; + display: none; +} +.CodeMirror-vscrollbar { + right: 0; top: 0; + overflow-x: hidden; + overflow-y: scroll; +} +.CodeMirror-hscrollbar { + bottom: 0; left: 0; + overflow-y: hidden; + overflow-x: scroll; +} +.CodeMirror-scrollbar-filler { + right: 0; bottom: 0; +} +.CodeMirror-gutter-filler { + left: 0; bottom: 0; +} + +.CodeMirror-gutters { + position: absolute; left: 0; top: 0; + min-height: 100%; + z-index: 3; +} +.CodeMirror-gutter { + white-space: normal; + height: 100%; + display: inline-block; + vertical-align: top; + margin-bottom: -30px; +} +.CodeMirror-gutter-wrapper { + position: absolute; + z-index: 4; + background: none !important; + border: none !important; +} +.CodeMirror-gutter-background { + position: absolute; + top: 0; bottom: 0; + z-index: 4; +} +.CodeMirror-gutter-elt { + position: absolute; + cursor: default; + z-index: 4; +} +.CodeMirror-gutter-wrapper ::selection { background-color: transparent } +.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent } + +.CodeMirror-lines { + cursor: text; + min-height: 1px; /* prevents collapsing before first draw */ +} +.CodeMirror pre { + /* Reset some styles that the rest of the page might have set */ + -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; + border-width: 0; + background: transparent; + font-family: inherit; + font-size: inherit; + margin: 0; + white-space: pre; + word-wrap: normal; + line-height: inherit; + color: inherit; + z-index: 2; + position: relative; + overflow: visible; + -webkit-tap-highlight-color: transparent; + -webkit-font-variant-ligatures: contextual; + font-variant-ligatures: contextual; +} +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: normal; +} + +.CodeMirror-linebackground { + position: absolute; + left: 0; right: 0; top: 0; bottom: 0; + z-index: 0; +} + +.CodeMirror-linewidget { + position: relative; + z-index: 2; + overflow: auto; +} + +.CodeMirror-widget {} + +.CodeMirror-rtl pre { direction: rtl; } + +.CodeMirror-code { + outline: none; +} + +/* Force content-box sizing for the elements where we expect it */ +.CodeMirror-scroll, +.CodeMirror-sizer, +.CodeMirror-gutter, +.CodeMirror-gutters, +.CodeMirror-linenumber { + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +.CodeMirror-measure { + position: absolute; + width: 100%; + height: 0; + overflow: hidden; + visibility: hidden; +} + +.CodeMirror-cursor { + position: absolute; + pointer-events: none; +} +.CodeMirror-measure pre { position: static; } + +div.CodeMirror-cursors { + visibility: hidden; + position: relative; + z-index: 3; +} +div.CodeMirror-dragcursors { + visibility: visible; +} + +.CodeMirror-focused div.CodeMirror-cursors { + visibility: visible; +} + +.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } +.CodeMirror-crosshair { cursor: crosshair; } +.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } +.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } + +.cm-searching { + background-color: #ffa; + background-color: rgba(255, 255, 0, .4); +} + +/* Used to force a border model for a node */ +.cm-force-border { padding-right: .1px; } + +@media print { + /* Hide the cursor when printing */ + .CodeMirror div.CodeMirror-cursors { + visibility: hidden; + } +} + +/* See issue #2901 */ +.cm-tab-wrap-hack:after { content: ''; } + +/* Help users use markselection to safely style text background */ +span.CodeMirror-selectedtext { background: none; } diff --git a/backend/webif/static/codemirror/lib/codemirror.js b/backend/webif/static/codemirror/lib/codemirror.js new file mode 100755 index 000000000..a9fa82fa5 --- /dev/null +++ b/backend/webif/static/codemirror/lib/codemirror.js @@ -0,0 +1,9653 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.CodeMirror = factory()); +}(this, (function () { 'use strict'; + +// Kludges for bugs and behavior differences that can't be feature +// detected are enabled based on userAgent etc sniffing. +var userAgent = navigator.userAgent +var platform = navigator.platform + +var gecko = /gecko\/\d/i.test(userAgent) +var ie_upto10 = /MSIE \d/.test(userAgent) +var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent) +var edge = /Edge\/(\d+)/.exec(userAgent) +var ie = ie_upto10 || ie_11up || edge +var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]) +var webkit = !edge && /WebKit\//.test(userAgent) +var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent) +var chrome = !edge && /Chrome\//.test(userAgent) +var presto = /Opera\//.test(userAgent) +var safari = /Apple Computer/.test(navigator.vendor) +var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent) +var phantom = /PhantomJS/.test(userAgent) + +var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent) +var android = /Android/.test(userAgent) +// This is woefully incomplete. Suggestions for alternative methods welcome. +var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent) +var mac = ios || /Mac/.test(platform) +var chromeOS = /\bCrOS\b/.test(userAgent) +var windows = /win/i.test(platform) + +var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/) +if (presto_version) { presto_version = Number(presto_version[1]) } +if (presto_version && presto_version >= 15) { presto = false; webkit = true } +// Some browsers use the wrong event properties to signal cmd/ctrl on OS X +var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)) +var captureRightClick = gecko || (ie && ie_version >= 9) + +function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } + +var rmClass = function(node, cls) { + var current = node.className + var match = classTest(cls).exec(current) + if (match) { + var after = current.slice(match.index + match[0].length) + node.className = current.slice(0, match.index) + (after ? match[1] + after : "") + } +} + +function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + { e.removeChild(e.firstChild) } + return e +} + +function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e) +} + +function elt(tag, content, className, style) { + var e = document.createElement(tag) + if (className) { e.className = className } + if (style) { e.style.cssText = style } + if (typeof content == "string") { e.appendChild(document.createTextNode(content)) } + else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } } + return e +} +// wrapper for elt, which removes the elt from the accessibility tree +function eltP(tag, content, className, style) { + var e = elt(tag, content, className, style) + e.setAttribute("role", "presentation") + return e +} + +var range +if (document.createRange) { range = function(node, start, end, endNode) { + var r = document.createRange() + r.setEnd(endNode || node, end) + r.setStart(node, start) + return r +} } +else { range = function(node, start, end) { + var r = document.body.createTextRange() + try { r.moveToElementText(node.parentNode) } + catch(e) { return r } + r.collapse(true) + r.moveEnd("character", end) + r.moveStart("character", start) + return r +} } + +function contains(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + { child = child.parentNode } + if (parent.contains) + { return parent.contains(child) } + do { + if (child.nodeType == 11) { child = child.host } + if (child == parent) { return true } + } while (child = child.parentNode) +} + +function activeElt() { + // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. + // IE < 10 will throw when accessed while the page is loading or in an iframe. + // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. + var activeElement + try { + activeElement = document.activeElement + } catch(e) { + activeElement = document.body || null + } + while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) + { activeElement = activeElement.shadowRoot.activeElement } + return activeElement +} + +function addClass(node, cls) { + var current = node.className + if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls } +} +function joinClasses(a, b) { + var as = a.split(" ") + for (var i = 0; i < as.length; i++) + { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i] } } + return b +} + +var selectInput = function(node) { node.select() } +if (ios) // Mobile Safari apparently has a bug where select() is broken. + { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } } +else if (ie) // Suppress mysterious IE10 errors + { selectInput = function(node) { try { node.select() } catch(_e) {} } } + +function bind(f) { + var args = Array.prototype.slice.call(arguments, 1) + return function(){return f.apply(null, args)} +} + +function copyObj(obj, target, overwrite) { + if (!target) { target = {} } + for (var prop in obj) + { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + { target[prop] = obj[prop] } } + return target +} + +// Counts the column offset in a string, taking tabs into account. +// Used mostly to find indentation. +function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/) + if (end == -1) { end = string.length } + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i) + if (nextTab < 0 || nextTab >= end) + { return n + (end - i) } + n += nextTab - i + n += tabSize - (n % tabSize) + i = nextTab + 1 + } +} + +var Delayed = function() {this.id = null}; +Delayed.prototype.set = function (ms, f) { + clearTimeout(this.id) + this.id = setTimeout(f, ms) +}; + +function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + { if (array[i] == elt) { return i } } + return -1 +} + +// Number of pixels added to scroller and sizer to hide scrollbar +var scrollerGap = 30 + +// Returned or thrown by various protocols to signal 'I'm not +// handling this'. +var Pass = {toString: function(){return "CodeMirror.Pass"}} + +// Reused option objects for setSelection & friends +var sel_dontScroll = {scroll: false}; +var sel_mouse = {origin: "*mouse"}; +var sel_move = {origin: "+move"}; +// The inverse of countColumn -- find the offset that corresponds to +// a particular column. +function findColumn(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos) + if (nextTab == -1) { nextTab = string.length } + var skipped = nextTab - pos + if (nextTab == string.length || col + skipped >= goal) + { return pos + Math.min(skipped, goal - col) } + col += nextTab - pos + col += tabSize - (col % tabSize) + pos = nextTab + 1 + if (col >= goal) { return pos } + } +} + +var spaceStrs = [""] +function spaceStr(n) { + while (spaceStrs.length <= n) + { spaceStrs.push(lst(spaceStrs) + " ") } + return spaceStrs[n] +} + +function lst(arr) { return arr[arr.length-1] } + +function map(array, f) { + var out = [] + for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i) } + return out +} + +function insertSorted(array, value, score) { + var pos = 0, priority = score(value) + while (pos < array.length && score(array[pos]) <= priority) { pos++ } + array.splice(pos, 0, value) +} + +function nothing() {} + +function createObj(base, props) { + var inst + if (Object.create) { + inst = Object.create(base) + } else { + nothing.prototype = base + inst = new nothing() + } + if (props) { copyObj(props, inst) } + return inst +} + +var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/ +function isWordCharBasic(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)) +} +function isWordChar(ch, helper) { + if (!helper) { return isWordCharBasic(ch) } + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true } + return helper.test(ch) +} + +function isEmpty(obj) { + for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } } + return true +} + +// Extending unicode characters. A series of a non-extending char + +// any number of extending chars is treated as a single unit as far +// as editing and measuring is concerned. This is not fully correct, +// since some scripts/fonts/browsers also treat other configurations +// of code points as a group. +var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/ +function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } + +// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. +function skipExtendingChars(str, pos, dir) { + while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir } + return pos +} + +// Returns the value from the range [`from`; `to`] that satisfies +// `pred` and is closest to `from`. Assumes that at least `to` +// satisfies `pred`. Supports `from` being greater than `to`. +function findFirst(pred, from, to) { + // At any point we are certain `to` satisfies `pred`, don't know + // whether `from` does. + var dir = from > to ? -1 : 1 + for (;;) { + if (from == to) { return from } + var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF) + if (mid == from) { return pred(mid) ? from : to } + if (pred(mid)) { to = mid } + else { from = mid + dir } + } +} + +// The display handles the DOM integration, both for input reading +// and content drawing. It holds references to DOM nodes and +// display-related state. + +function Display(place, doc, input) { + var d = this + this.input = input + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler") + d.scrollbarFiller.setAttribute("cm-not-content", "true") + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler") + d.gutterFiller.setAttribute("cm-not-content", "true") + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = eltP("div", null, "CodeMirror-code") + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1") + d.cursorDiv = elt("div", null, "CodeMirror-cursors") + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure") + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure") + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none") + var lines = eltP("div", [d.lineSpace], "CodeMirror-lines") + // Moved around its parent to cover visible view. + d.mover = elt("div", [lines], null, "position: relative") + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer") + d.sizerWidth = null + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;") + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters") + d.lineGutter = null + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll") + d.scroller.setAttribute("tabIndex", "-1") + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror") + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 } + if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true } + + if (place) { + if (place.appendChild) { place.appendChild(d.wrapper) } + else { place(d.wrapper) } + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first + d.reportedViewFrom = d.reportedViewTo = doc.first + // Information about the rendered lines. + d.view = [] + d.renderedView = null + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null + // Empty space (in pixels) above the view + d.viewOffset = 0 + d.lastWrapHeight = d.lastWrapWidth = 0 + d.updateLineNumbers = null + + d.nativeBarWidth = d.barHeight = d.barWidth = 0 + d.scrollbarsClipped = false + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null + d.maxLineLength = 0 + d.maxLineChanged = false + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null + + // True when shift is held down. + d.shift = false + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null + + d.activeTouch = null + + input.init(d) +} + +// Find the line object corresponding to the given line number. +function getLine(doc, n) { + n -= doc.first + if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") } + var chunk = doc + while (!chunk.lines) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize() + if (n < sz) { chunk = child; break } + n -= sz + } + } + return chunk.lines[n] +} + +// Get the part of a document between two positions, as an array of +// strings. +function getBetween(doc, start, end) { + var out = [], n = start.line + doc.iter(start.line, end.line + 1, function (line) { + var text = line.text + if (n == end.line) { text = text.slice(0, end.ch) } + if (n == start.line) { text = text.slice(start.ch) } + out.push(text) + ++n + }) + return out +} +// Get the lines between from and to, as array of strings. +function getLines(doc, from, to) { + var out = [] + doc.iter(from, to, function (line) { out.push(line.text) }) // iter aborts when callback returns truthy value + return out +} + +// Update the height of a line, propagating the height change +// upwards to parent nodes. +function updateLineHeight(line, height) { + var diff = height - line.height + if (diff) { for (var n = line; n; n = n.parent) { n.height += diff } } +} + +// Given a line object, find its line number by walking up through +// its parent links. +function lineNo(line) { + if (line.parent == null) { return null } + var cur = line.parent, no = indexOf(cur.lines, line) + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) { break } + no += chunk.children[i].chunkSize() + } + } + return no + cur.first +} + +// Find the line at the given vertical position, using the height +// information in the document tree. +function lineAtHeight(chunk, h) { + var n = chunk.first + outer: do { + for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) { + var child = chunk.children[i$1], ch = child.height + if (h < ch) { chunk = child; continue outer } + h -= ch + n += child.chunkSize() + } + return n + } while (!chunk.lines) + var i = 0 + for (; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height + if (h < lh) { break } + h -= lh + } + return n + i +} + +function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size} + +function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)) +} + +// A Pos instance represents a position within the text. +function Pos(line, ch, sticky) { + if ( sticky === void 0 ) sticky = null; + + if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) } + this.line = line + this.ch = ch + this.sticky = sticky +} + +// Compare two positions, return 0 if they are the same, a negative +// number when a is less, and a positive number otherwise. +function cmp(a, b) { return a.line - b.line || a.ch - b.ch } + +function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 } + +function copyPos(x) {return Pos(x.line, x.ch)} +function maxPos(a, b) { return cmp(a, b) < 0 ? b : a } +function minPos(a, b) { return cmp(a, b) < 0 ? a : b } + +// Most of the external API clips given positions to make sure they +// actually exist within the document. +function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))} +function clipPos(doc, pos) { + if (pos.line < doc.first) { return Pos(doc.first, 0) } + var last = doc.first + doc.size - 1 + if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) } + return clipToLen(pos, getLine(doc, pos.line).text.length) +} +function clipToLen(pos, linelen) { + var ch = pos.ch + if (ch == null || ch > linelen) { return Pos(pos.line, linelen) } + else if (ch < 0) { return Pos(pos.line, 0) } + else { return pos } +} +function clipPosArray(doc, array) { + var out = [] + for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]) } + return out +} + +// Optimize some code when these features are not used. +var sawReadOnlySpans = false; +var sawCollapsedSpans = false; +function seeReadOnlySpans() { + sawReadOnlySpans = true +} + +function seeCollapsedSpans() { + sawCollapsedSpans = true +} + +// TEXTMARKER SPANS + +function MarkedSpan(marker, from, to) { + this.marker = marker + this.from = from; this.to = to +} + +// Search an array of spans for a span matching the given marker. +function getMarkedSpanFor(spans, marker) { + if (spans) { for (var i = 0; i < spans.length; ++i) { + var span = spans[i] + if (span.marker == marker) { return span } + } } +} +// Remove a span from an array, returning undefined if no spans are +// left (we don't store arrays for lines without spans). +function removeMarkedSpan(spans, span) { + var r + for (var i = 0; i < spans.length; ++i) + { if (spans[i] != span) { (r || (r = [])).push(spans[i]) } } + return r +} +// Add a span to a line. +function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span] + span.marker.attachLine(line) +} + +// Used for the algorithm that adjusts markers for a change in the +// document. These functions cut an array of spans at a given +// character position, returning an array of remaining chunks (or +// undefined if nothing remains). +function markedSpansBefore(old, startCh, isInsert) { + var nw + if (old) { for (var i = 0; i < old.length; ++i) { + var span = old[i], marker = span.marker + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh) + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)) + } + } } + return nw +} +function markedSpansAfter(old, endCh, isInsert) { + var nw + if (old) { for (var i = 0; i < old.length; ++i) { + var span = old[i], marker = span.marker + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh) + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)) + } + } } + return nw +} + +// Given a change object, compute the new set of marker spans that +// cover the line in which the change took place. Removes spans +// entirely within the change, reconnects spans belonging to the +// same marker that appear on both sides of the change, and cuts off +// spans partially within the change. Returns an array of span +// arrays with one element for each line in (after) the change. +function stretchSpansOverChange(doc, change) { + if (change.full) { return null } + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans + if (!oldFirst && !oldLast) { return null } + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0 + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert) + var last = markedSpansAfter(oldLast, endCh, isInsert) + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0) + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i] + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker) + if (!found) { span.to = startCh } + else if (sameLine) { span.to = found.to == null ? null : found.to + offset } + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i$1 = 0; i$1 < last.length; ++i$1) { + var span$1 = last[i$1] + if (span$1.to != null) { span$1.to += offset } + if (span$1.from == null) { + var found$1 = getMarkedSpanFor(first, span$1.marker) + if (!found$1) { + span$1.from = offset + if (sameLine) { (first || (first = [])).push(span$1) } + } + } else { + span$1.from += offset + if (sameLine) { (first || (first = [])).push(span$1) } + } + } + } + // Make sure we didn't create any zero-length spans + if (first) { first = clearEmptySpans(first) } + if (last && last != first) { last = clearEmptySpans(last) } + + var newMarkers = [first] + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers + if (gap > 0 && first) + { for (var i$2 = 0; i$2 < first.length; ++i$2) + { if (first[i$2].to == null) + { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)) } } } + for (var i$3 = 0; i$3 < gap; ++i$3) + { newMarkers.push(gapMarkers) } + newMarkers.push(last) + } + return newMarkers +} + +// Remove spans that are empty and don't have a clearWhenEmpty +// option of false. +function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i] + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + { spans.splice(i--, 1) } + } + if (!spans.length) { return null } + return spans +} + +// Used to 'clip' out readOnly ranges when making a change. +function removeReadOnlyRanges(doc, from, to) { + var markers = null + doc.iter(from.line, to.line + 1, function (line) { + if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + { (markers || (markers = [])).push(mark) } + } } + }) + if (!markers) { return null } + var parts = [{from: from, to: to}] + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0) + for (var j = 0; j < parts.length; ++j) { + var p = parts[j] + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue } + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to) + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + { newParts.push({from: p.from, to: m.from}) } + if (dto > 0 || !mk.inclusiveRight && !dto) + { newParts.push({from: m.to, to: p.to}) } + parts.splice.apply(parts, newParts) + j += newParts.length - 3 + } + } + return parts +} + +// Connect or disconnect spans from a line. +function detachMarkedSpans(line) { + var spans = line.markedSpans + if (!spans) { return } + for (var i = 0; i < spans.length; ++i) + { spans[i].marker.detachLine(line) } + line.markedSpans = null +} +function attachMarkedSpans(line, spans) { + if (!spans) { return } + for (var i = 0; i < spans.length; ++i) + { spans[i].marker.attachLine(line) } + line.markedSpans = spans +} + +// Helpers used when computing which overlapping collapsed span +// counts as the larger one. +function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 } +function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 } + +// Returns a number indicating which of two overlapping collapsed +// spans is larger (and thus includes the other). Falls back to +// comparing ids when the spans cover exactly the same range. +function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length + if (lenDiff != 0) { return lenDiff } + var aPos = a.find(), bPos = b.find() + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b) + if (fromCmp) { return -fromCmp } + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b) + if (toCmp) { return toCmp } + return b.id - a.id +} + +// Find out whether a line ends or starts in a collapsed span. If +// so, return the marker for that span. +function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found + if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { + sp = sps[i] + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + { found = sp.marker } + } } + return found +} +function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } +function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } + +// Test whether there exists a collapsed span that partially +// overlaps (covers the start or end, but not both) of a new span. +// Such overlap is not allowed. +function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo) + var sps = sawCollapsedSpans && line.markedSpans + if (sps) { for (var i = 0; i < sps.length; ++i) { + var sp = sps[i] + if (!sp.marker.collapsed) { continue } + var found = sp.marker.find(0) + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker) + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker) + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } + if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || + fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) + { return true } + } } +} + +// A visual line is a line as drawn on the screen. Folding, for +// example, can cause multiple logical lines to appear on the same +// visual line. This finds the start of the visual line that the +// given line is part of (usually that is the line itself). +function visualLine(line) { + var merged + while (merged = collapsedSpanAtStart(line)) + { line = merged.find(-1, true).line } + return line +} + +function visualLineEnd(line) { + var merged + while (merged = collapsedSpanAtEnd(line)) + { line = merged.find(1, true).line } + return line +} + +// Returns an array of logical lines that continue the visual line +// started by the argument, or undefined if there are no such lines. +function visualLineContinued(line) { + var merged, lines + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line + ;(lines || (lines = [])).push(line) + } + return lines +} + +// Get the line number of the start of the visual line that the +// given line number is part of. +function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line) + if (line == vis) { return lineN } + return lineNo(vis) +} + +// Get the line number of the start of the next visual line after +// the given line. +function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) { return lineN } + var line = getLine(doc, lineN), merged + if (!lineIsHidden(doc, line)) { return lineN } + while (merged = collapsedSpanAtEnd(line)) + { line = merged.find(1, true).line } + return lineNo(line) + 1 +} + +// Compute whether a line is hidden. Lines count as hidden when they +// are part of a visual line that starts with another line, or when +// they are entirely covered by collapsed, non-widget span. +function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans + if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { + sp = sps[i] + if (!sp.marker.collapsed) { continue } + if (sp.from == null) { return true } + if (sp.marker.widgetNode) { continue } + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + { return true } + } } +} +function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true) + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) + } + if (span.marker.inclusiveRight && span.to == line.text.length) + { return true } + for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i] + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) { return true } + } +} + +// Find the height above the given line. +function heightAtLine(lineObj) { + lineObj = visualLine(lineObj) + + var h = 0, chunk = lineObj.parent + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i] + if (line == lineObj) { break } + else { h += line.height } + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i$1 = 0; i$1 < p.children.length; ++i$1) { + var cur = p.children[i$1] + if (cur == chunk) { break } + else { h += cur.height } + } + } + return h +} + +// Compute the character length of a line, taking into account +// collapsed ranges (see markText) that might hide parts, and join +// other lines onto it. +function lineLength(line) { + if (line.height == 0) { return 0 } + var len = line.text.length, merged, cur = line + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true) + cur = found.from.line + len += found.from.ch - found.to.ch + } + cur = line + while (merged = collapsedSpanAtEnd(cur)) { + var found$1 = merged.find(0, true) + len -= cur.text.length - found$1.from.ch + cur = found$1.to.line + len += cur.text.length - found$1.to.ch + } + return len +} + +// Find the longest line in the document. +function findMaxLine(cm) { + var d = cm.display, doc = cm.doc + d.maxLine = getLine(doc, doc.first) + d.maxLineLength = lineLength(d.maxLine) + d.maxLineChanged = true + doc.iter(function (line) { + var len = lineLength(line) + if (len > d.maxLineLength) { + d.maxLineLength = len + d.maxLine = line + } + }) +} + +// BIDI HELPERS + +function iterateBidiSections(order, from, to, f) { + if (!order) { return f(from, to, "ltr", 0) } + var found = false + for (var i = 0; i < order.length; ++i) { + var part = order[i] + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i) + found = true + } + } + if (!found) { f(from, to, "ltr") } +} + +var bidiOther = null +function getBidiPartAt(order, ch, sticky) { + var found + bidiOther = null + for (var i = 0; i < order.length; ++i) { + var cur = order[i] + if (cur.from < ch && cur.to > ch) { return i } + if (cur.to == ch) { + if (cur.from != cur.to && sticky == "before") { found = i } + else { bidiOther = i } + } + if (cur.from == ch) { + if (cur.from != cur.to && sticky != "before") { found = i } + else { bidiOther = i } + } + } + return found != null ? found : bidiOther +} + +// Bidirectional ordering algorithm +// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm +// that this (partially) implements. + +// One-char codes used for character types: +// L (L): Left-to-Right +// R (R): Right-to-Left +// r (AL): Right-to-Left Arabic +// 1 (EN): European Number +// + (ES): European Number Separator +// % (ET): European Number Terminator +// n (AN): Arabic Number +// , (CS): Common Number Separator +// m (NSM): Non-Spacing Mark +// b (BN): Boundary Neutral +// s (B): Paragraph Separator +// t (S): Segment Separator +// w (WS): Whitespace +// N (ON): Other Neutrals + +// Returns null if characters are ordered as they appear +// (left-to-right), or an array of sections ({from, to, level} +// objects) in the order in which they occur visually. +var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN" + // Character types for codepoints 0x600 to 0x6f9 + var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111" + function charType(code) { + if (code <= 0xf7) { return lowTypes.charAt(code) } + else if (0x590 <= code && code <= 0x5f4) { return "R" } + else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) } + else if (0x6ee <= code && code <= 0x8ac) { return "r" } + else if (0x2000 <= code && code <= 0x200b) { return "w" } + else if (code == 0x200c) { return "b" } + else { return "L" } + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/ + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/ + + function BidiSpan(level, from, to) { + this.level = level + this.from = from; this.to = to + } + + return function(str, direction) { + var outerType = direction == "ltr" ? "L" : "R" + + if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false } + var len = str.length, types = [] + for (var i = 0; i < len; ++i) + { types.push(charType(str.charCodeAt(i))) } + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) { + var type = types[i$1] + if (type == "m") { types[i$1] = prev } + else { prev = type } + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) { + var type$1 = types[i$2] + if (type$1 == "1" && cur == "r") { types[i$2] = "n" } + else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R" } } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) { + var type$2 = types[i$3] + if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1" } + else if (type$2 == "," && prev$1 == types[i$3+1] && + (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1 } + prev$1 = type$2 + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i$4 = 0; i$4 < len; ++i$4) { + var type$3 = types[i$4] + if (type$3 == ",") { types[i$4] = "N" } + else if (type$3 == "%") { + var end = (void 0) + for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N" + for (var j = i$4; j < end; ++j) { types[j] = replace } + i$4 = end - 1 + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) { + var type$4 = types[i$5] + if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L" } + else if (isStrong.test(type$4)) { cur$1 = type$4 } + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i$6 = 0; i$6 < len; ++i$6) { + if (isNeutral.test(types[i$6])) { + var end$1 = (void 0) + for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {} + var before = (i$6 ? types[i$6-1] : outerType) == "L" + var after = (end$1 < len ? types[end$1] : outerType) == "L" + var replace$1 = before == after ? (before ? "L" : "R") : outerType + for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1 } + i$6 = end$1 - 1 + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m + for (var i$7 = 0; i$7 < len;) { + if (countsAsLeft.test(types[i$7])) { + var start = i$7 + for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {} + order.push(new BidiSpan(0, start, i$7)) + } else { + var pos = i$7, at = order.length + for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {} + for (var j$2 = pos; j$2 < i$7;) { + if (countsAsNum.test(types[j$2])) { + if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)) } + var nstart = j$2 + for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {} + order.splice(at, 0, new BidiSpan(2, nstart, j$2)) + pos = j$2 + } else { ++j$2 } + } + if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) } + } + } + if (direction == "ltr") { + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length + order.unshift(new BidiSpan(0, 0, m[0].length)) + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length + order.push(new BidiSpan(0, len - m[0].length, len)) + } + } + + return direction == "rtl" ? order.reverse() : order + } +})() + +// Get the bidi ordering for the given line (and cache it). Returns +// false for lines that are fully left-to-right, and an array of +// BidiSpan objects otherwise. +function getOrder(line, direction) { + var order = line.order + if (order == null) { order = line.order = bidiOrdering(line.text, direction) } + return order +} + +// EVENT HANDLING + +// Lightweight event framework. on/off also work on DOM nodes, +// registering native DOM handlers. + +var noHandlers = [] + +var on = function(emitter, type, f) { + if (emitter.addEventListener) { + emitter.addEventListener(type, f, false) + } else if (emitter.attachEvent) { + emitter.attachEvent("on" + type, f) + } else { + var map = emitter._handlers || (emitter._handlers = {}) + map[type] = (map[type] || noHandlers).concat(f) + } +} + +function getHandlers(emitter, type) { + return emitter._handlers && emitter._handlers[type] || noHandlers +} + +function off(emitter, type, f) { + if (emitter.removeEventListener) { + emitter.removeEventListener(type, f, false) + } else if (emitter.detachEvent) { + emitter.detachEvent("on" + type, f) + } else { + var map = emitter._handlers, arr = map && map[type] + if (arr) { + var index = indexOf(arr, f) + if (index > -1) + { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) } + } + } +} + +function signal(emitter, type /*, values...*/) { + var handlers = getHandlers(emitter, type) + if (!handlers.length) { return } + var args = Array.prototype.slice.call(arguments, 2) + for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args) } +} + +// The DOM events that CodeMirror handles can be overridden by +// registering a (non-DOM) handler on the editor for the event name, +// and preventDefault-ing the event in that handler. +function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + { e = {type: e, preventDefault: function() { this.defaultPrevented = true }} } + signal(cm, override || e.type, cm, e) + return e_defaultPrevented(e) || e.codemirrorIgnore +} + +function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity + if (!arr) { return } + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []) + for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1) + { set.push(arr[i]) } } +} + +function hasHandler(emitter, type) { + return getHandlers(emitter, type).length > 0 +} + +// Add on and off methods to a constructor's prototype, to make +// registering events on such objects more convenient. +function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f)} + ctor.prototype.off = function(type, f) {off(this, type, f)} +} + +// Due to the fact that we still support jurassic IE versions, some +// compatibility wrappers are needed. + +function e_preventDefault(e) { + if (e.preventDefault) { e.preventDefault() } + else { e.returnValue = false } +} +function e_stopPropagation(e) { + if (e.stopPropagation) { e.stopPropagation() } + else { e.cancelBubble = true } +} +function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false +} +function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)} + +function e_target(e) {return e.target || e.srcElement} +function e_button(e) { + var b = e.which + if (b == null) { + if (e.button & 1) { b = 1 } + else if (e.button & 2) { b = 3 } + else if (e.button & 4) { b = 2 } + } + if (mac && e.ctrlKey && b == 1) { b = 3 } + return b +} + +// Detect drag-and-drop +var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) { return false } + var div = elt('div') + return "draggable" in div || "dragDrop" in div +}() + +var zwspSupported +function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b") + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])) + if (measure.firstChild.offsetHeight != 0) + { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) } + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px") + node.setAttribute("cm-text", "") + return node +} + +// Feature-detect IE's crummy client rect reporting for bidi text +var badBidiRects +function hasBadBidiRects(measure) { + if (badBidiRects != null) { return badBidiRects } + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")) + var r0 = range(txt, 0, 1).getBoundingClientRect() + var r1 = range(txt, 1, 2).getBoundingClientRect() + removeChildren(measure) + if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780) + return badBidiRects = (r1.right - r0.right < 3) +} + +// See if "".split is the broken IE version, if so, provide an +// alternative way to split lines. +var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) { + var pos = 0, result = [], l = string.length + while (pos <= l) { + var nl = string.indexOf("\n", pos) + if (nl == -1) { nl = string.length } + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl) + var rt = line.indexOf("\r") + if (rt != -1) { + result.push(line.slice(0, rt)) + pos += rt + 1 + } else { + result.push(line) + pos = nl + 1 + } + } + return result +} : function (string) { return string.split(/\r\n?|\n/); } + +var hasSelection = window.getSelection ? function (te) { + try { return te.selectionStart != te.selectionEnd } + catch(e) { return false } +} : function (te) { + var range + try {range = te.ownerDocument.selection.createRange()} + catch(e) {} + if (!range || range.parentElement() != te) { return false } + return range.compareEndPoints("StartToEnd", range) != 0 +} + +var hasCopyEvent = (function () { + var e = elt("div") + if ("oncopy" in e) { return true } + e.setAttribute("oncopy", "return;") + return typeof e.oncopy == "function" +})() + +var badZoomedRects = null +function hasBadZoomedRects(measure) { + if (badZoomedRects != null) { return badZoomedRects } + var node = removeChildrenAndAdd(measure, elt("span", "x")) + var normal = node.getBoundingClientRect() + var fromRange = range(node, 0, 1).getBoundingClientRect() + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 +} + +var modes = {}; +var mimeModes = {}; +// Extra arguments are stored as the mode's dependencies, which is +// used by (legacy) mechanisms like loadmode.js to automatically +// load a mode. (Preferred mechanism is the require/define calls.) +function defineMode(name, mode) { + if (arguments.length > 2) + { mode.dependencies = Array.prototype.slice.call(arguments, 2) } + modes[name] = mode +} + +function defineMIME(mime, spec) { + mimeModes[mime] = spec +} + +// Given a MIME type, a {name, ...options} config object, or a name +// string, return a mode config object. +function resolveMode(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec] + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name] + if (typeof found == "string") { found = {name: found} } + spec = createObj(found, spec) + spec.name = found.name + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return resolveMode("application/xml") + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { + return resolveMode("application/json") + } + if (typeof spec == "string") { return {name: spec} } + else { return spec || {name: "null"} } +} + +// Given a mode spec (anything that resolveMode accepts), find and +// initialize an actual mode object. +function getMode(options, spec) { + spec = resolveMode(spec) + var mfactory = modes[spec.name] + if (!mfactory) { return getMode(options, "text/plain") } + var modeObj = mfactory(options, spec) + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name] + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) { continue } + if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop] } + modeObj[prop] = exts[prop] + } + } + modeObj.name = spec.name + if (spec.helperType) { modeObj.helperType = spec.helperType } + if (spec.modeProps) { for (var prop$1 in spec.modeProps) + { modeObj[prop$1] = spec.modeProps[prop$1] } } + + return modeObj +} + +// This can be used to attach properties to mode objects from +// outside the actual mode definition. +var modeExtensions = {} +function extendMode(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}) + copyObj(properties, exts) +} + +function copyState(mode, state) { + if (state === true) { return state } + if (mode.copyState) { return mode.copyState(state) } + var nstate = {} + for (var n in state) { + var val = state[n] + if (val instanceof Array) { val = val.concat([]) } + nstate[n] = val + } + return nstate +} + +// Given a mode and a state (for that mode), find the inner mode and +// state at the position that the state refers to. +function innerMode(mode, state) { + var info + while (mode.innerMode) { + info = mode.innerMode(state) + if (!info || info.mode == mode) { break } + state = info.state + mode = info.mode + } + return info || {mode: mode, state: state} +} + +function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true +} + +// STRING STREAM + +// Fed to the mode parsers, provides helper functions to make +// parsers more succinct. + +var StringStream = function(string, tabSize, lineOracle) { + this.pos = this.start = 0 + this.string = string + this.tabSize = tabSize || 8 + this.lastColumnPos = this.lastColumnValue = 0 + this.lineStart = 0 + this.lineOracle = lineOracle +}; + +StringStream.prototype.eol = function () {return this.pos >= this.string.length}; +StringStream.prototype.sol = function () {return this.pos == this.lineStart}; +StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; +StringStream.prototype.next = function () { + if (this.pos < this.string.length) + { return this.string.charAt(this.pos++) } +}; +StringStream.prototype.eat = function (match) { + var ch = this.string.charAt(this.pos) + var ok + if (typeof match == "string") { ok = ch == match } + else { ok = ch && (match.test ? match.test(ch) : match(ch)) } + if (ok) {++this.pos; return ch} +}; +StringStream.prototype.eatWhile = function (match) { + var start = this.pos + while (this.eat(match)){} + return this.pos > start +}; +StringStream.prototype.eatSpace = function () { + var this$1 = this; + + var start = this.pos + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos } + return this.pos > start +}; +StringStream.prototype.skipToEnd = function () {this.pos = this.string.length}; +StringStream.prototype.skipTo = function (ch) { + var found = this.string.indexOf(ch, this.pos) + if (found > -1) {this.pos = found; return true} +}; +StringStream.prototype.backUp = function (n) {this.pos -= n}; +StringStream.prototype.column = function () { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue) + this.lastColumnPos = this.start + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) +}; +StringStream.prototype.indentation = function () { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) +}; +StringStream.prototype.match = function (pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; } + var substr = this.string.substr(this.pos, pattern.length) + if (cased(substr) == cased(pattern)) { + if (consume !== false) { this.pos += pattern.length } + return true + } + } else { + var match = this.string.slice(this.pos).match(pattern) + if (match && match.index > 0) { return null } + if (match && consume !== false) { this.pos += match[0].length } + return match + } +}; +StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; +StringStream.prototype.hideFirstChars = function (n, inner) { + this.lineStart += n + try { return inner() } + finally { this.lineStart -= n } +}; +StringStream.prototype.lookAhead = function (n) { + var oracle = this.lineOracle + return oracle && oracle.lookAhead(n) +}; +StringStream.prototype.baseToken = function () { + var oracle = this.lineOracle + return oracle && oracle.baseToken(this.pos) +}; + +var SavedContext = function(state, lookAhead) { + this.state = state + this.lookAhead = lookAhead +}; + +var Context = function(doc, state, line, lookAhead) { + this.state = state + this.doc = doc + this.line = line + this.maxLookAhead = lookAhead || 0 + this.baseTokens = null + this.baseTokenPos = 1 +}; + +Context.prototype.lookAhead = function (n) { + var line = this.doc.getLine(this.line + n) + if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n } + return line +}; + +Context.prototype.baseToken = function (n) { + var this$1 = this; + + if (!this.baseTokens) { return null } + while (this.baseTokens[this.baseTokenPos] <= n) + { this$1.baseTokenPos += 2 } + var type = this.baseTokens[this.baseTokenPos + 1] + return {type: type && type.replace(/( |^)overlay .*/, ""), + size: this.baseTokens[this.baseTokenPos] - n} +}; + +Context.prototype.nextLine = function () { + this.line++ + if (this.maxLookAhead > 0) { this.maxLookAhead-- } +}; + +Context.fromSaved = function (doc, saved, line) { + if (saved instanceof SavedContext) + { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) } + else + { return new Context(doc, copyState(doc.mode, saved), line) } +}; + +Context.prototype.save = function (copy) { + var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state + return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state +}; + + +// Compute a style array (an array starting with a mode generation +// -- for invalidation -- followed by pairs of end positions and +// style strings), which is used to highlight the tokens on the +// line. +function highlightLine(cm, line, context, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {} + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); }, + lineClasses, forceToEnd) + var state = context.state + + // Run overlays, adjust style array. + var loop = function ( o ) { + context.baseTokens = st + var overlay = cm.state.overlays[o], i = 1, at = 0 + context.state = true + runMode(cm, line.text, overlay.mode, context, function (end, style) { + var start = i + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i] + if (i_end > end) + { st.splice(i, 1, end, st[i+1], i_end) } + i += 2 + at = Math.min(end, i_end) + } + if (!style) { return } + if (overlay.opaque) { + st.splice(start, i - start, end, "overlay " + style) + i = start + 2 + } else { + for (; start < i; start += 2) { + var cur = st[start+1] + st[start+1] = (cur ? cur + " " : "") + "overlay " + style + } + } + }, lineClasses) + context.state = state + context.baseTokens = null + context.baseTokenPos = 1 + }; + + for (var o = 0; o < cm.state.overlays.length; ++o) loop( o ); + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} +} + +function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var context = getContextBefore(cm, lineNo(line)) + var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state) + var result = highlightLine(cm, line, context) + if (resetState) { context.state = resetState } + line.stateAfter = context.save(!resetState) + line.styles = result.styles + if (result.classes) { line.styleClasses = result.classes } + else if (line.styleClasses) { line.styleClasses = null } + if (updateFrontier === cm.doc.highlightFrontier) + { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) } + } + return line.styles +} + +function getContextBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display + if (!doc.mode.startState) { return new Context(doc, true, n) } + var start = findStartLine(cm, n, precise) + var saved = start > doc.first && getLine(doc, start - 1).stateAfter + var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start) + + doc.iter(start, n, function (line) { + processLine(cm, line.text, context) + var pos = context.line + line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null + context.nextLine() + }) + if (precise) { doc.modeFrontier = context.line } + return context +} + +// Lightweight form of highlight -- proceed over this line and +// update state, but don't save a style array. Used for lines that +// aren't currently visible. +function processLine(cm, text, context, startAt) { + var mode = cm.doc.mode + var stream = new StringStream(text, cm.options.tabSize, context) + stream.start = stream.pos = startAt || 0 + if (text == "") { callBlankLine(mode, context.state) } + while (!stream.eol()) { + readToken(mode, stream, context.state) + stream.start = stream.pos + } +} + +function callBlankLine(mode, state) { + if (mode.blankLine) { return mode.blankLine(state) } + if (!mode.innerMode) { return } + var inner = innerMode(mode, state) + if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) } +} + +function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) { inner[0] = innerMode(mode, state).mode } + var style = mode.token(stream, state) + if (stream.pos > stream.start) { return style } + } + throw new Error("Mode " + mode.name + " failed to advance stream.") +} + +var Token = function(stream, type, state) { + this.start = stream.start; this.end = stream.pos + this.string = stream.current() + this.type = type || null + this.state = state +}; + +// Utility for getTokenAt and getLineTokens +function takeToken(cm, pos, precise, asArray) { + var doc = cm.doc, mode = doc.mode, style + pos = clipPos(doc, pos) + var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise) + var stream = new StringStream(line.text, cm.options.tabSize, context), tokens + if (asArray) { tokens = [] } + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos + style = readToken(mode, stream, context.state) + if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) } + } + return asArray ? tokens : new Token(stream, style, context.state) +} + +function extractLineClasses(type, output) { + if (type) { for (;;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/) + if (!lineClass) { break } + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length) + var prop = lineClass[1] ? "bgClass" : "textClass" + if (output[prop] == null) + { output[prop] = lineClass[2] } + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + { output[prop] += " " + lineClass[2] } + } } + return type +} + +// Run the given mode's parser over a line, calling f for each token. +function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans + if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans } + var curStart = 0, curStyle = null + var stream = new StringStream(text, cm.options.tabSize, context), style + var inner = cm.options.addModeClass && [null] + if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses) } + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false + if (forceToEnd) { processLine(cm, text, context, stream.pos) } + stream.pos = text.length + style = null + } else { + style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses) + } + if (inner) { + var mName = inner[0].name + if (mName) { style = "m-" + (style ? mName + " " + style : mName) } + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 5000) + f(curStart, curStyle) + } + curStyle = style + } + stream.start = stream.pos + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 + // characters, and returns inaccurate measurements in nodes + // starting around 5000 chars. + var pos = Math.min(stream.pos, curStart + 5000) + f(pos, curStyle) + curStart = pos + } +} + +// Finds the line to start with when starting a parse. Tries to +// find a line with a stateAfter, so that it can start with a +// valid state. If that fails, it returns the line with the +// smallest indentation, which tends to need the least context to +// parse correctly. +function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100) + for (var search = n; search > lim; --search) { + if (search <= doc.first) { return doc.first } + var line = getLine(doc, search - 1), after = line.stateAfter + if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) + { return search } + var indented = countColumn(line.text, null, cm.options.tabSize) + if (minline == null || minindent > indented) { + minline = search - 1 + minindent = indented + } + } + return minline +} + +function retreatFrontier(doc, n) { + doc.modeFrontier = Math.min(doc.modeFrontier, n) + if (doc.highlightFrontier < n - 10) { return } + var start = doc.first + for (var line = n - 1; line > start; line--) { + var saved = getLine(doc, line).stateAfter + // change is on 3 + // state on line 1 looked ahead 2 -- so saw 3 + // test 1 + 2 < 3 should cover this + if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { + start = line + 1 + break + } + } + doc.highlightFrontier = Math.min(doc.highlightFrontier, start) +} + +// LINE DATA STRUCTURE + +// Line objects. These hold state related to a line, including +// highlighting info (the styles array). +var Line = function(text, markedSpans, estimateHeight) { + this.text = text + attachMarkedSpans(this, markedSpans) + this.height = estimateHeight ? estimateHeight(this) : 1 +}; + +Line.prototype.lineNo = function () { return lineNo(this) }; +eventMixin(Line) + +// Change the content (text, markers) of a line. Automatically +// invalidates cached information and tries to re-estimate the +// line's height. +function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text + if (line.stateAfter) { line.stateAfter = null } + if (line.styles) { line.styles = null } + if (line.order != null) { line.order = null } + detachMarkedSpans(line) + attachMarkedSpans(line, markedSpans) + var estHeight = estimateHeight ? estimateHeight(line) : 1 + if (estHeight != line.height) { updateLineHeight(line, estHeight) } +} + +// Detach a line from the document tree and its markers. +function cleanUpLine(line) { + line.parent = null + detachMarkedSpans(line) +} + +// Convert a style as returned by a mode (either null, or a string +// containing one or more styles) to a CSS style. This is cached, +// and also looks for line-wide styles. +var styleToClassCache = {}; +var styleToClassCacheWithMode = {}; +function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) { return null } + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")) +} + +// Render the DOM representation of the text of a line. Also builds +// up a 'line map', which points at the DOM nodes that represent +// specific stretches of text, and is used by the measuring code. +// The returned object contains the DOM node, this map, and +// information about line-wide styles that were set by the mode. +function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null) + var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + trailingSpace: false, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")} + lineView.measure = {} + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0) + builder.pos = 0 + builder.addToken = buildToken + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) + { builder.addToken = buildTokenBadBidi(builder.addToken, order) } + builder.map = [] + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line) + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)) + if (line.styleClasses) { + if (line.styleClasses.bgClass) + { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "") } + if (line.styleClasses.textClass) + { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "") } + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) } + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map + lineView.measure.cache = {} + } else { + ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) + ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}) + } + } + + // See issue #2901 + if (webkit) { + var last = builder.content.lastChild + if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) + { builder.content.className = "cm-tab-wrap-hack" } + } + + signal(cm, "renderLine", cm, lineView.line, builder.pre) + if (builder.pre.className) + { builder.textClass = joinClasses(builder.pre.className, builder.textClass || "") } + + return builder +} + +function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar") + token.title = "\\u" + ch.charCodeAt(0).toString(16) + token.setAttribute("aria-label", token.title) + return token +} + +// Build up the DOM representation for a single token, and add it to +// the line map. Takes care to render special characters separately. +function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) { return } + var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text + var special = builder.cm.state.specialChars, mustWrap = false + var content + if (!special.test(text)) { + builder.col += text.length + content = document.createTextNode(displayText) + builder.map.push(builder.pos, builder.pos + text.length, content) + if (ie && ie_version < 9) { mustWrap = true } + builder.pos += text.length + } else { + content = document.createDocumentFragment() + var pos = 0 + while (true) { + special.lastIndex = pos + var m = special.exec(text) + var skipped = m ? m.index - pos : text.length - pos + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)) + if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])) } + else { content.appendChild(txt) } + builder.map.push(builder.pos, builder.pos + skipped, txt) + builder.col += skipped + builder.pos += skipped + } + if (!m) { break } + pos += skipped + 1 + var txt$1 = (void 0) + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize + txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")) + txt$1.setAttribute("role", "presentation") + txt$1.setAttribute("cm-text", "\t") + builder.col += tabWidth + } else if (m[0] == "\r" || m[0] == "\n") { + txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")) + txt$1.setAttribute("cm-text", m[0]) + builder.col += 1 + } else { + txt$1 = builder.cm.options.specialCharPlaceholder(m[0]) + txt$1.setAttribute("cm-text", m[0]) + if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])) } + else { content.appendChild(txt$1) } + builder.col += 1 + } + builder.map.push(builder.pos, builder.pos + 1, txt$1) + builder.pos++ + } + } + builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 + if (style || startStyle || endStyle || mustWrap || css) { + var fullStyle = style || "" + if (startStyle) { fullStyle += startStyle } + if (endStyle) { fullStyle += endStyle } + var token = elt("span", [content], fullStyle, css) + if (title) { token.title = title } + return builder.content.appendChild(token) + } + builder.content.appendChild(content) +} + +function splitSpaces(text, trailingBefore) { + if (text.length > 1 && !/ /.test(text)) { return text } + var spaceBefore = trailingBefore, result = "" + for (var i = 0; i < text.length; i++) { + var ch = text.charAt(i) + if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) + { ch = "\u00a0" } + result += ch + spaceBefore = ch == " " + } + return result +} + +// Work around nonsense dimensions being reported for stretches of +// right-to-left text. +function buildTokenBadBidi(inner, order) { + return function (builder, text, style, startStyle, endStyle, title, css) { + style = style ? style + " cm-force-border" : "cm-force-border" + var start = builder.pos, end = start + text.length + for (;;) { + // Find the part that overlaps with the start of this text + var part = (void 0) + for (var i = 0; i < order.length; i++) { + part = order[i] + if (part.to > start && part.from <= start) { break } + } + if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) } + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css) + startStyle = null + text = text.slice(part.to - start) + start = part.to + } + } +} + +function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode + if (widget) { builder.map.push(builder.pos, builder.pos + size, widget) } + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + { widget = builder.content.appendChild(document.createElement("span")) } + widget.setAttribute("cm-marker", marker.id) + } + if (widget) { + builder.cm.display.input.setUneditable(widget) + builder.content.appendChild(widget) + } + builder.pos += size + builder.trailingSpace = false +} + +// Outputs a number of spans to make up a line, taking highlighting +// and marked text into account. +function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0 + if (!spans) { + for (var i$1 = 1; i$1 < styles.length; i$1+=2) + { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)) } + return + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = "" + collapsed = null; nextChange = Infinity + var foundBookmarks = [], endStyles = (void 0) + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m) + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to + spanEndStyle = "" + } + if (m.className) { spanStyle += " " + m.className } + if (m.css) { css = (css ? css + ";" : "") + m.css } + if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle } + if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to) } + if (m.title && !title) { title = m.title } + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + { collapsed = sp } + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from + } + } + if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2) + { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1] } } } + + if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2) + { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]) } } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null) + if (collapsed.to == null) { return } + if (collapsed.to == pos) { collapsed = false } + } + } + if (pos >= len) { break } + + var upto = Math.min(len, nextChange) + while (true) { + if (text) { + var end = pos + text.length + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css) + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break} + pos = end + spanStartStyle = "" + } + text = allText.slice(at, at = styles[i++]) + style = interpretTokenStyle(styles[i++], builder.cm.options) + } + } +} + + +// These objects are used to represent the visible (currently drawn) +// part of the document. A LineView may correspond to multiple +// logical lines, if those are connected by collapsed ranges. +function LineView(doc, line, lineN) { + // The starting line + this.line = line + // Continuing lines, if any + this.rest = visualLineContinued(line) + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1 + this.node = this.text = null + this.hidden = lineIsHidden(doc, line) +} + +// Create a range of LineView objects for the given lines. +function buildViewArray(cm, from, to) { + var array = [], nextPos + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos) + nextPos = pos + view.size + array.push(view) + } + return array +} + +var operationGroup = null + +function pushOperation(op) { + if (operationGroup) { + operationGroup.ops.push(op) + } else { + op.ownsGroup = operationGroup = { + ops: [op], + delayedCallbacks: [] + } + } +} + +function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0 + do { + for (; i < callbacks.length; i++) + { callbacks[i].call(null) } + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j] + if (op.cursorActivityHandlers) + { while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) } } + } + } while (i < callbacks.length) +} + +function finishOperation(op, endCb) { + var group = op.ownsGroup + if (!group) { return } + + try { fireCallbacksForOps(group) } + finally { + operationGroup = null + endCb(group) + } +} + +var orphanDelayedCallbacks = null + +// Often, we want to signal events at a point where we are in the +// middle of some work, but don't want the handler to start calling +// other methods on the editor, which might be in an inconsistent +// state or simply not expect any other events to happen. +// signalLater looks whether there are any handlers, and schedules +// them to be executed when the last operation ends, or, if no +// operation is active, when a timeout fires. +function signalLater(emitter, type /*, values...*/) { + var arr = getHandlers(emitter, type) + if (!arr.length) { return } + var args = Array.prototype.slice.call(arguments, 2), list + if (operationGroup) { + list = operationGroup.delayedCallbacks + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks + } else { + list = orphanDelayedCallbacks = [] + setTimeout(fireOrphanDelayed, 0) + } + var loop = function ( i ) { + list.push(function () { return arr[i].apply(null, args); }) + }; + + for (var i = 0; i < arr.length; ++i) + loop( i ); +} + +function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks + orphanDelayedCallbacks = null + for (var i = 0; i < delayed.length; ++i) { delayed[i]() } +} + +// When an aspect of a line changes, a string is added to +// lineView.changes. This updates the relevant part of the line's +// DOM structure. +function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j] + if (type == "text") { updateLineText(cm, lineView) } + else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims) } + else if (type == "class") { updateLineClasses(cm, lineView) } + else if (type == "widget") { updateLineWidgets(cm, lineView, dims) } + } + lineView.changes = null +} + +// Lines with gutter elements, widgets or a background class need to +// be wrapped, and have the extra elements added to the wrapper div +function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative") + if (lineView.text.parentNode) + { lineView.text.parentNode.replaceChild(lineView.node, lineView.text) } + lineView.node.appendChild(lineView.text) + if (ie && ie_version < 8) { lineView.node.style.zIndex = 2 } + } + return lineView.node +} + +function updateLineBackground(cm, lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass + if (cls) { cls += " CodeMirror-linebackground" } + if (lineView.background) { + if (cls) { lineView.background.className = cls } + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null } + } else if (cls) { + var wrap = ensureLineWrapped(lineView) + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild) + cm.display.input.setUneditable(lineView.background) + } +} + +// Wrapper around buildLineContent which will reuse the structure +// in display.externalMeasured when possible. +function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null + lineView.measure = ext.measure + return ext.built + } + return buildLineContent(cm, lineView) +} + +// Redraw the line's text. Interacts with the background and text +// classes because the mode may output tokens that influence these +// classes. +function updateLineText(cm, lineView) { + var cls = lineView.text.className + var built = getLineContent(cm, lineView) + if (lineView.text == lineView.node) { lineView.node = built.pre } + lineView.text.parentNode.replaceChild(built.pre, lineView.text) + lineView.text = built.pre + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass + lineView.textClass = built.textClass + updateLineClasses(cm, lineView) + } else if (cls) { + lineView.text.className = cls + } +} + +function updateLineClasses(cm, lineView) { + updateLineBackground(cm, lineView) + if (lineView.line.wrapClass) + { ensureLineWrapped(lineView).className = lineView.line.wrapClass } + else if (lineView.node != lineView.text) + { lineView.node.className = "" } + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass + lineView.text.className = textClass || "" +} + +function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter) + lineView.gutter = null + } + if (lineView.gutterBackground) { + lineView.node.removeChild(lineView.gutterBackground) + lineView.gutterBackground = null + } + if (lineView.line.gutterClass) { + var wrap = ensureLineWrapped(lineView) + lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, + ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")) + cm.display.input.setUneditable(lineView.gutterBackground) + wrap.insertBefore(lineView.gutterBackground, lineView.text) + } + var markers = lineView.line.gutterMarkers + if (cm.options.lineNumbers || markers) { + var wrap$1 = ensureLineWrapped(lineView) + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")) + cm.display.input.setUneditable(gutterWrap) + wrap$1.insertBefore(gutterWrap, lineView.text) + if (lineView.line.gutterClass) + { gutterWrap.className += " " + lineView.line.gutterClass } + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + { lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))) } + if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id] + if (found) + { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", + ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))) } + } } + } +} + +function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) { lineView.alignable = null } + for (var node = lineView.node.firstChild, next = (void 0); node; node = next) { + next = node.nextSibling + if (node.className == "CodeMirror-linewidget") + { lineView.node.removeChild(node) } + } + insertLineWidgets(cm, lineView, dims) +} + +// Build a line's DOM representation from scratch +function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView) + lineView.text = lineView.node = built.pre + if (built.bgClass) { lineView.bgClass = built.bgClass } + if (built.textClass) { lineView.textClass = built.textClass } + + updateLineClasses(cm, lineView) + updateLineGutter(cm, lineView, lineN, dims) + insertLineWidgets(cm, lineView, dims) + return lineView.node +} + +// A lineView may contain multiple logical lines (when merged by +// collapsed spans). The widgets for all of them need to be drawn. +function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true) + if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) + { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) } } +} + +function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) { return } + var wrap = ensureLineWrapped(lineView) + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget") + if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true") } + positionLineWidget(widget, node, lineView, dims) + cm.display.input.setUneditable(node) + if (allowAbove && widget.above) + { wrap.insertBefore(node, lineView.gutter || lineView.text) } + else + { wrap.appendChild(node) } + signalLater(widget, "redraw") + } +} + +function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + ;(lineView.alignable || (lineView.alignable = [])).push(node) + var width = dims.wrapperWidth + node.style.left = dims.fixedPos + "px" + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth + node.style.paddingLeft = dims.gutterTotalWidth + "px" + } + node.style.width = width + "px" + } + if (widget.coverGutter) { + node.style.zIndex = 5 + node.style.position = "relative" + if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px" } + } +} + +function widgetHeight(widget) { + if (widget.height != null) { return widget.height } + var cm = widget.doc.cm + if (!cm) { return 0 } + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;" + if (widget.coverGutter) + { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;" } + if (widget.noHScroll) + { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;" } + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)) + } + return widget.height = widget.node.parentNode.offsetHeight +} + +// Return true when the given mouse event happened in a widget +function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + { return true } + } +} + +// POSITION MEASUREMENT + +function paddingTop(display) {return display.lineSpace.offsetTop} +function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight} +function paddingH(display) { + if (display.cachedPaddingH) { return display.cachedPaddingH } + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")) + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle + var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)} + if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data } + return data +} + +function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth } +function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth +} +function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight +} + +// Ensure the lineView.wrapping.heights array is populated. This is +// an array of bottom offsets for the lines that make up a drawn +// line. When lineWrapping is on, there might be more than one +// height. +function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping + var curWidth = wrapping && displayWidth(cm) + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = [] + if (wrapping) { + lineView.measure.width = curWidth + var rects = lineView.text.firstChild.getClientRects() + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1] + if (Math.abs(cur.bottom - next.bottom) > 2) + { heights.push((cur.bottom + next.top) / 2 - rect.top) } + } + } + heights.push(rect.bottom - rect.top) + } +} + +// Find a line map (mapping character offsets to text nodes) and a +// measurement cache for the given line number. (A line view might +// contain multiple lines when collapsed ranges are present.) +function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + { return {map: lineView.measure.map, cache: lineView.measure.cache} } + for (var i = 0; i < lineView.rest.length; i++) + { if (lineView.rest[i] == line) + { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } } + for (var i$1 = 0; i$1 < lineView.rest.length; i$1++) + { if (lineNo(lineView.rest[i$1]) > lineN) + { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } } +} + +// Render a line into the hidden node display.externalMeasured. Used +// when measurement is needed for a line that's not in the viewport. +function updateExternalMeasurement(cm, line) { + line = visualLine(line) + var lineN = lineNo(line) + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN) + view.lineN = lineN + var built = view.built = buildLineContent(cm, view) + view.text = built.pre + removeChildrenAndAdd(cm.display.lineMeasure, built.pre) + return view +} + +// Get a {top, bottom, left, right} box (in line-local coordinates) +// for a given character. +function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias) +} + +// Find a line view that corresponds to the given line number. +function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + { return cm.display.view[findViewIndex(cm, lineN)] } + var ext = cm.display.externalMeasured + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + { return ext } +} + +// Measurement can be split in two steps, the set-up work that +// applies to the whole line, and the measurement of the actual +// character. Functions like coordsChar, that need to do a lot of +// measurements in a row, can thus ensure that the set-up work is +// only done once. +function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line) + var view = findViewForLine(cm, lineN) + if (view && !view.text) { + view = null + } else if (view && view.changes) { + updateLineForChanges(cm, view, lineN, getDimensions(cm)) + cm.curOp.forceUpdate = true + } + if (!view) + { view = updateExternalMeasurement(cm, line) } + + var info = mapFromLineView(view, line, lineN) + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + } +} + +// Given a prepared measurement object, measures the position of an +// actual character (or fetches it from the cache). +function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) { ch = -1 } + var key = ch + (bias || ""), found + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key] + } else { + if (!prepared.rect) + { prepared.rect = prepared.view.text.getBoundingClientRect() } + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect) + prepared.hasHeights = true + } + found = measureCharInner(cm, prepared, ch, bias) + if (!found.bogus) { prepared.cache[key] = found } + } + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom} +} + +var nullRect = {left: 0, right: 0, top: 0, bottom: 0} + +function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse, mStart, mEnd + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + mStart = map[i] + mEnd = map[i + 1] + if (ch < mStart) { + start = 0; end = 1 + collapse = "left" + } else if (ch < mEnd) { + start = ch - mStart + end = start + 1 + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart + start = end - 1 + if (ch >= mEnd) { collapse = "right" } + } + if (start != null) { + node = map[i + 2] + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + { collapse = bias } + if (bias == "left" && start == 0) + { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2] + collapse = "left" + } } + if (bias == "right" && start == mEnd - mStart) + { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2] + collapse = "right" + } } + break + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd} +} + +function getUsefulRect(rects, bias) { + var rect = nullRect + if (bias == "left") { for (var i = 0; i < rects.length; i++) { + if ((rect = rects[i]).left != rect.right) { break } + } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) { + if ((rect = rects[i$1]).left != rect.right) { break } + } } + return rect +} + +function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias) + var node = place.node, start = place.start, end = place.end, collapse = place.collapse + + var rect + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start } + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end } + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) + { rect = node.parentNode.getBoundingClientRect() } + else + { rect = getUsefulRect(range(node, start, end).getClientRects(), bias) } + if (rect.left || rect.right || start == 0) { break } + end = start + start = start - 1 + collapse = "right" + } + if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect) } + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) { collapse = bias = "right" } + var rects + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + { rect = rects[bias == "right" ? rects.length - 1 : 0] } + else + { rect = node.getBoundingClientRect() } + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0] + if (rSpan) + { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} } + else + { rect = nullRect } + } + + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top + var mid = (rtop + rbot) / 2 + var heights = prepared.view.measure.heights + var i = 0 + for (; i < heights.length - 1; i++) + { if (mid < heights[i]) { break } } + var top = i ? heights[i - 1] : 0, bot = heights[i] + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot} + if (!rect.left && !rect.right) { result.bogus = true } + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot } + + return result +} + +// Work around problem with bounding client rects on ranges being +// returned incorrectly when zoomed on IE10 and below. +function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + { return rect } + var scaleX = screen.logicalXDPI / screen.deviceXDPI + var scaleY = screen.logicalYDPI / screen.deviceYDPI + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY} +} + +function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {} + lineView.measure.heights = null + if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) + { lineView.measure.caches[i] = {} } } + } +} + +function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null + removeChildren(cm.display.lineMeasure) + for (var i = 0; i < cm.display.view.length; i++) + { clearLineMeasurementCacheFor(cm.display.view[i]) } +} + +function clearCaches(cm) { + clearLineMeasurementCache(cm) + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null + if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true } + cm.display.lineNumChars = null +} + +function pageScrollX() { + // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 + // which causes page_Offset and bounding client rects to use + // different reference viewports and invalidate our calculations. + if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } + return window.pageXOffset || (document.documentElement || document.body).scrollLeft +} +function pageScrollY() { + if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } + return window.pageYOffset || (document.documentElement || document.body).scrollTop +} + +function widgetTopHeight(lineObj) { + var height = 0 + if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) + { height += widgetHeight(lineObj.widgets[i]) } } } + return height +} + +// Converts a {top, bottom, left, right} box from line-local +// coordinates into another coordinate system. Context may be one of +// "line", "div" (display.lineDiv), "local"./null (editor), "window", +// or "page". +function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { + if (!includeWidgets) { + var height = widgetTopHeight(lineObj) + rect.top += height; rect.bottom += height + } + if (context == "line") { return rect } + if (!context) { context = "local" } + var yOff = heightAtLine(lineObj) + if (context == "local") { yOff += paddingTop(cm.display) } + else { yOff -= cm.display.viewOffset } + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect() + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()) + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()) + rect.left += xOff; rect.right += xOff + } + rect.top += yOff; rect.bottom += yOff + return rect +} + +// Coverts a box from "div" coords to another coordinate system. +// Context may be "window", "page", "div", or "local"./null. +function fromCoordSystem(cm, coords, context) { + if (context == "div") { return coords } + var left = coords.left, top = coords.top + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX() + top -= pageScrollY() + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect() + left += localBox.left + top += localBox.top + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect() + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top} +} + +function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) { lineObj = getLine(cm.doc, pos.line) } + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) +} + +// Returns a box for a given cursor position, which may have an +// 'other' property containing the position of the secondary cursor +// on a bidi boundary. +// A cursor Pos(line, char, "before") is on the same visual line as `char - 1` +// and after `char - 1` in writing order of `char - 1` +// A cursor Pos(line, char, "after") is on the same visual line as `char` +// and before `char` in writing order of `char` +// Examples (upper-case letters are RTL, lower-case are LTR): +// Pos(0, 1, ...) +// before after +// ab a|b a|b +// aB a|B aB| +// Ab |Ab A|b +// AB B|A B|A +// Every position after the last character on a line is considered to stick +// to the last character on the line. +function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line) + if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) } + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight) + if (right) { m.left = m.right; } else { m.right = m.left } + return intoCoordSystem(cm, lineObj, m, context) + } + var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky + if (ch >= lineObj.text.length) { + ch = lineObj.text.length + sticky = "before" + } else if (ch <= 0) { + ch = 0 + sticky = "after" + } + if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } + + function getBidi(ch, partPos, invert) { + var part = order[partPos], right = part.level == 1 + return get(invert ? ch - 1 : ch, right != invert) + } + var partPos = getBidiPartAt(order, ch, sticky) + var other = bidiOther + var val = getBidi(ch, partPos, sticky == "before") + if (other != null) { val.other = getBidi(ch, other, sticky != "before") } + return val +} + +// Used to cheaply estimate the coordinates for a position. Used for +// intermediate scroll updates. +function estimateCoords(cm, pos) { + var left = 0 + pos = clipPos(cm.doc, pos) + if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch } + var lineObj = getLine(cm.doc, pos.line) + var top = heightAtLine(lineObj) + paddingTop(cm.display) + return {left: left, right: left, top: top, bottom: top + lineObj.height} +} + +// Positions returned by coordsChar contain some extra information. +// xRel is the relative x position of the input coordinates compared +// to the found position (so xRel > 0 means the coordinates are to +// the right of the character position, for example). When outside +// is true, that means the coordinates lie outside the line's +// vertical range. +function PosWithInfo(line, ch, sticky, outside, xRel) { + var pos = Pos(line, ch, sticky) + pos.xRel = xRel + if (outside) { pos.outside = true } + return pos +} + +// Compute the character position closest to the given coordinates. +// Input must be lineSpace-local ("div" coordinate system). +function coordsChar(cm, x, y) { + var doc = cm.doc + y += cm.display.viewOffset + if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) } + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1 + if (lineN > last) + { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) } + if (x < 0) { x = 0 } + + var lineObj = getLine(doc, lineN) + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y) + var merged = collapsedSpanAtEnd(lineObj) + var mergedPos = merged && merged.find(0, true) + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + { lineN = lineNo(lineObj = mergedPos.to.line) } + else + { return found } + } +} + +function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { + y -= widgetTopHeight(lineObj) + var end = lineObj.text.length + var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0) + end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end) + return {begin: begin, end: end} +} + +function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { + if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) } + var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top + return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) +} + +// Returns true if the given side of a box is after the given +// coordinates, in top-to-bottom, left-to-right order. +function boxIsAfter(box, x, y, left) { + return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x +} + +function coordsCharInner(cm, lineObj, lineNo, x, y) { + // Move y into line-local coordinate space + y -= heightAtLine(lineObj) + var preparedMeasure = prepareMeasureForLine(cm, lineObj) + // When directly calling `measureCharPrepared`, we have to adjust + // for the widgets at this line. + var widgetHeight = widgetTopHeight(lineObj) + var begin = 0, end = lineObj.text.length, ltr = true + + var order = getOrder(lineObj, cm.doc.direction) + // If the line isn't plain left-to-right text, first figure out + // which bidi section the coordinates fall into. + if (order) { + var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) + (cm, lineObj, lineNo, preparedMeasure, order, x, y) + ltr = part.level != 1 + // The awkward -1 offsets are needed because findFirst (called + // on these below) will treat its first bound as inclusive, + // second as exclusive, but we want to actually address the + // characters in the part's range + begin = ltr ? part.from : part.to - 1 + end = ltr ? part.to : part.from - 1 + } + + // A binary search to find the first character whose bounding box + // starts after the coordinates. If we run across any whose box wrap + // the coordinates, store that. + var chAround = null, boxAround = null + var ch = findFirst(function (ch) { + var box = measureCharPrepared(cm, preparedMeasure, ch) + box.top += widgetHeight; box.bottom += widgetHeight + if (!boxIsAfter(box, x, y, false)) { return false } + if (box.top <= y && box.left <= x) { + chAround = ch + boxAround = box + } + return true + }, begin, end) + + var baseX, sticky, outside = false + // If a box around the coordinates was found, use that + if (boxAround) { + // Distinguish coordinates nearer to the left or right side of the box + var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr + ch = chAround + (atStart ? 0 : 1) + sticky = atStart ? "after" : "before" + baseX = atLeft ? boxAround.left : boxAround.right + } else { + // (Adjust for extended bound, if necessary.) + if (!ltr && (ch == end || ch == begin)) { ch++ } + // To determine which side to associate with, get the box to the + // left of the character and compare it's vertical position to the + // coordinates + sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : + (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ? + "after" : "before" + // Now get accurate coordinates for this place, in order to get a + // base X position + var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure) + baseX = coords.left + outside = y < coords.top || y >= coords.bottom + } + + ch = skipExtendingChars(lineObj.text, ch, 1) + return PosWithInfo(lineNo, ch, sticky, outside, x - baseX) +} + +function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) { + // Bidi parts are sorted left-to-right, and in a non-line-wrapping + // situation, we can take this ordering to correspond to the visual + // ordering. This finds the first part whose end is after the given + // coordinates. + var index = findFirst(function (i) { + var part = order[i], ltr = part.level != 1 + return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"), + "line", lineObj, preparedMeasure), x, y, true) + }, 0, order.length - 1) + var part = order[index] + // If this isn't the first part, the part's start is also after + // the coordinates, and the coordinates aren't on the same line as + // that start, move one part back. + if (index > 0) { + var ltr = part.level != 1 + var start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"), + "line", lineObj, preparedMeasure) + if (boxIsAfter(start, x, y, true) && start.top > y) + { part = order[index - 1] } + } + return part +} + +function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { + // In a wrapped line, rtl text on wrapping boundaries can do things + // that don't correspond to the ordering in our `order` array at + // all, so a binary search doesn't work, and we want to return a + // part that only spans one line so that the binary search in + // coordsCharInner is safe. As such, we first find the extent of the + // wrapped line, and then do a flat search in which we discard any + // spans that aren't on the line. + var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y); + var begin = ref.begin; + var end = ref.end; + if (/\s/.test(lineObj.text.charAt(end - 1))) { end-- } + var part = null, closestDist = null + for (var i = 0; i < order.length; i++) { + var p = order[i] + if (p.from >= end || p.to <= begin) { continue } + var ltr = p.level != 1 + var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right + // Weigh against spans ending before this, so that they are only + // picked if nothing ends after + var dist = endX < x ? x - endX + 1e9 : endX - x + if (!part || closestDist > dist) { + part = p + closestDist = dist + } + } + if (!part) { part = order[order.length - 1] } + // Clip the part to the wrapped line. + if (part.from < begin) { part = {from: begin, to: part.to, level: part.level} } + if (part.to > end) { part = {from: part.from, to: end, level: part.level} } + return part +} + +var measureText +// Compute the default text height. +function textHeight(display) { + if (display.cachedTextHeight != null) { return display.cachedTextHeight } + if (measureText == null) { + measureText = elt("pre") + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")) + measureText.appendChild(elt("br")) + } + measureText.appendChild(document.createTextNode("x")) + } + removeChildrenAndAdd(display.measure, measureText) + var height = measureText.offsetHeight / 50 + if (height > 3) { display.cachedTextHeight = height } + removeChildren(display.measure) + return height || 1 +} + +// Compute the default character width. +function charWidth(display) { + if (display.cachedCharWidth != null) { return display.cachedCharWidth } + var anchor = elt("span", "xxxxxxxxxx") + var pre = elt("pre", [anchor]) + removeChildrenAndAdd(display.measure, pre) + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10 + if (width > 2) { display.cachedCharWidth = width } + return width || 10 +} + +// Do a bulk-read of the DOM positions and sizes needed to draw the +// view, so that we don't interleave reading and writing to the DOM. +function getDimensions(cm) { + var d = cm.display, left = {}, width = {} + var gutterLeft = d.gutters.clientLeft + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft + width[cm.options.gutters[i]] = n.clientWidth + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth} +} + +// Computes display.scroller.scrollLeft + display.gutters.offsetWidth, +// but using getBoundingClientRect to get a sub-pixel-accurate +// result. +function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left +} + +// Returns a function that estimates the height of a line, to use as +// first approximation until the line becomes visible (and is thus +// properly measurable). +function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3) + return function (line) { + if (lineIsHidden(cm.doc, line)) { return 0 } + + var widgetsHeight = 0 + if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height } + } } + + if (wrapping) + { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th } + else + { return widgetsHeight + th } + } +} + +function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm) + doc.iter(function (line) { + var estHeight = est(line) + if (estHeight != line.height) { updateLineHeight(line, estHeight) } + }) +} + +// Given a mouse event, find the corresponding position. If liberal +// is false, it checks whether a gutter or scrollbar was clicked, +// and returns null if it was. forRect is used by rectangular +// selections, and tries to estimate a character position even for +// coordinates beyond the right of the text. +function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null } + + var x, y, space = display.lineSpace.getBoundingClientRect() + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top } + catch (e) { return null } + var coords = coordsChar(cm, x, y), line + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)) + } + return coords +} + +// Find the view element corresponding to a given line. Return null +// when the line isn't visible. +function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) { return null } + n -= cm.display.viewFrom + if (n < 0) { return null } + var view = cm.display.view + for (var i = 0; i < view.length; i++) { + n -= view[i].size + if (n < 0) { return i } + } +} + +function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()) +} + +function prepareSelection(cm, primary) { + if ( primary === void 0 ) primary = true; + + var doc = cm.doc, result = {} + var curFragment = result.cursors = document.createDocumentFragment() + var selFragment = result.selection = document.createDocumentFragment() + + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (!primary && i == doc.sel.primIndex) { continue } + var range = doc.sel.ranges[i] + if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue } + var collapsed = range.empty() + if (collapsed || cm.options.showCursorWhenSelecting) + { drawSelectionCursor(cm, range.head, curFragment) } + if (!collapsed) + { drawSelectionRange(cm, range, selFragment) } + } + return result +} + +// Draws a cursor for the given range +function drawSelectionCursor(cm, head, output) { + var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine) + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")) + cursor.style.left = pos.left + "px" + cursor.style.top = pos.top + "px" + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px" + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")) + otherCursor.style.display = "" + otherCursor.style.left = pos.other.left + "px" + otherCursor.style.top = pos.other.top + "px" + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px" + } +} + +function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } + +// Draws the given range as a highlighted selection +function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc + var fragment = document.createDocumentFragment() + var padding = paddingH(cm.display), leftSide = padding.left + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right + var docLTR = doc.direction == "ltr" + + function add(left, top, width, bottom) { + if (top < 0) { top = 0 } + top = Math.round(top) + bottom = Math.round(bottom) + fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px"))) + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line) + var lineLen = lineObj.text.length + var start, end + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias) + } + + function wrapX(pos, dir, side) { + var extent = wrappedLineExtentChar(cm, lineObj, null, pos) + var prop = (dir == "ltr") == (side == "after") ? "left" : "right" + var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1) + return coords(ch, prop)[prop] + } + + var order = getOrder(lineObj, doc.direction) + iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) { + var ltr = dir == "ltr" + var fromPos = coords(from, ltr ? "left" : "right") + var toPos = coords(to - 1, ltr ? "right" : "left") + + var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen + var first = i == 0, last = !order || i == order.length - 1 + if (toPos.top - fromPos.top <= 3) { // Single line + var openLeft = (docLTR ? openStart : openEnd) && first + var openRight = (docLTR ? openEnd : openStart) && last + var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left + var right = openRight ? rightSide : (ltr ? toPos : fromPos).right + add(left, fromPos.top, right - left, fromPos.bottom) + } else { // Multiple lines + var topLeft, topRight, botLeft, botRight + if (ltr) { + topLeft = docLTR && openStart && first ? leftSide : fromPos.left + topRight = docLTR ? rightSide : wrapX(from, dir, "before") + botLeft = docLTR ? leftSide : wrapX(to, dir, "after") + botRight = docLTR && openEnd && last ? rightSide : toPos.right + } else { + topLeft = !docLTR ? leftSide : wrapX(from, dir, "before") + topRight = !docLTR && openStart && first ? rightSide : fromPos.right + botLeft = !docLTR && openEnd && last ? leftSide : toPos.left + botRight = !docLTR ? rightSide : wrapX(to, dir, "after") + } + add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom) + if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) } + add(botLeft, toPos.top, botRight - botLeft, toPos.bottom) + } + + if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos } + if (cmpCoords(toPos, start) < 0) { start = toPos } + if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos } + if (cmpCoords(toPos, end) < 0) { end = toPos } + }) + return {start: start, end: end} + } + + var sFrom = range.from(), sTo = range.to() + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch) + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line) + var singleVLine = visualLine(fromLine) == visualLine(toLine) + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom) + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom) + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom) + } + } + if (leftEnd.bottom < rightStart.top) + { add(leftSide, leftEnd.bottom, null, rightStart.top) } + } + + output.appendChild(fragment) +} + +// Cursor-blinking +function restartBlink(cm) { + if (!cm.state.focused) { return } + var display = cm.display + clearInterval(display.blinker) + var on = true + display.cursorDiv.style.visibility = "" + if (cm.options.cursorBlinkRate > 0) + { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; }, + cm.options.cursorBlinkRate) } + else if (cm.options.cursorBlinkRate < 0) + { display.cursorDiv.style.visibility = "hidden" } +} + +function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) } +} + +function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true + setTimeout(function () { if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false + onBlur(cm) + } }, 100) +} + +function onFocus(cm, e) { + if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false } + + if (cm.options.readOnly == "nocursor") { return } + if (!cm.state.focused) { + signal(cm, "focus", cm, e) + cm.state.focused = true + addClass(cm.display.wrapper, "CodeMirror-focused") + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset() + if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20) } // Issue #1730 + } + cm.display.input.receivedFocus() + } + restartBlink(cm) +} +function onBlur(cm, e) { + if (cm.state.delayingBlurEvent) { return } + + if (cm.state.focused) { + signal(cm, "blur", cm, e) + cm.state.focused = false + rmClass(cm.display.wrapper, "CodeMirror-focused") + } + clearInterval(cm.display.blinker) + setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150) +} + +// Read the actual heights of the rendered lines, and update their +// stored heights to match. +function updateHeightsInViewport(cm) { + var display = cm.display + var prevBottom = display.lineDiv.offsetTop + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height = (void 0) + if (cur.hidden) { continue } + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight + height = bot - prevBottom + prevBottom = bot + } else { + var box = cur.node.getBoundingClientRect() + height = box.bottom - box.top + } + var diff = cur.line.height - height + if (height < 2) { height = textHeight(display) } + if (diff > .005 || diff < -.005) { + updateLineHeight(cur.line, height) + updateWidgetHeight(cur.line) + if (cur.rest) { for (var j = 0; j < cur.rest.length; j++) + { updateWidgetHeight(cur.rest[j]) } } + } + } +} + +// Read and store the height of line widgets associated with the +// given line. +function updateWidgetHeight(line) { + if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) { + var w = line.widgets[i], parent = w.node.parentNode + if (parent) { w.height = parent.offsetHeight } + } } +} + +// Compute the lines that are visible in a given viewport (defaults +// the the current scroll position). viewport may contain top, +// height, and ensure (see op.scrollToPos) properties. +function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop + top = Math.floor(top - paddingTop(display)) + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom) + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line + if (ensureFrom < from) { + from = ensureFrom + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight) + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight) + to = ensureTo + } + } + return {from: from, to: Math.max(to, from + 1)} +} + +// Re-align line numbers and gutter marks to compensate for +// horizontal scrolling. +function alignHorizontally(cm) { + var display = cm.display, view = display.view + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return } + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft + var gutterW = display.gutters.offsetWidth, left = comp + "px" + for (var i = 0; i < view.length; i++) { if (!view[i].hidden) { + if (cm.options.fixedGutter) { + if (view[i].gutter) + { view[i].gutter.style.left = left } + if (view[i].gutterBackground) + { view[i].gutterBackground.style.left = left } + } + var align = view[i].alignable + if (align) { for (var j = 0; j < align.length; j++) + { align[j].style.left = left } } + } } + if (cm.options.fixedGutter) + { display.gutters.style.left = (comp + gutterW) + "px" } +} + +// Used to ensure that the line number gutter is still the right +// size for the current document size. Returns true when an update +// is needed. +function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) { return false } + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")) + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW + display.lineGutter.style.width = "" + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1 + display.lineNumWidth = display.lineNumInnerWidth + padding + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1 + display.lineGutter.style.width = display.lineNumWidth + "px" + updateGutterSpace(cm) + return true + } + return false +} + +// SCROLLING THINGS INTO VIEW + +// If an editor sits on the top or bottom of the window, partially +// scrolled out of view, this ensures that the cursor is visible. +function maybeScrollWindow(cm, rect) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null + if (rect.top + box.top < 0) { doScroll = true } + else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false } + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")) + cm.display.lineSpace.appendChild(scrollNode) + scrollNode.scrollIntoView(doScroll) + cm.display.lineSpace.removeChild(scrollNode) + } +} + +// Scroll a given position into view (immediately), verifying that +// it actually became visible (as line heights are accurately +// measured, the position of something may 'drift' during drawing). +function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) { margin = 0 } + var rect + if (!cm.options.lineWrapping && pos == end) { + // Set pos and end to the cursor positions around the character pos sticks to + // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch + // If pos == Pos(_, 0, "before"), pos and end are unchanged + pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos + end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos + } + for (var limit = 0; limit < 5; limit++) { + var changed = false + var coords = cursorCoords(cm, pos) + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end) + rect = {left: Math.min(coords.left, endCoords.left), + top: Math.min(coords.top, endCoords.top) - margin, + right: Math.max(coords.left, endCoords.left), + bottom: Math.max(coords.bottom, endCoords.bottom) + margin} + var scrollPos = calculateScrollPos(cm, rect) + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft + if (scrollPos.scrollTop != null) { + updateScrollTop(cm, scrollPos.scrollTop) + if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true } + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft) + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true } + } + if (!changed) { break } + } + return rect +} + +// Scroll a given set of coordinates into view (immediately). +function scrollIntoView(cm, rect) { + var scrollPos = calculateScrollPos(cm, rect) + if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) } + if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) } +} + +// Calculate a new scroll position needed to scroll the given +// rectangle into view. Returns an object with scrollTop and +// scrollLeft properties. When these are undefined, the +// vertical/horizontal position does not need to be adjusted. +function calculateScrollPos(cm, rect) { + var display = cm.display, snapMargin = textHeight(cm.display) + if (rect.top < 0) { rect.top = 0 } + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop + var screen = displayHeight(cm), result = {} + if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen } + var docBottom = cm.doc.height + paddingVert(display) + var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin + if (rect.top < screentop) { + result.scrollTop = atTop ? 0 : rect.top + } else if (rect.bottom > screentop + screen) { + var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen) + if (newTop != screentop) { result.scrollTop = newTop } + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft + var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0) + var tooWide = rect.right - rect.left > screenw + if (tooWide) { rect.right = rect.left + screenw } + if (rect.left < 10) + { result.scrollLeft = 0 } + else if (rect.left < screenleft) + { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) } + else if (rect.right > screenw + screenleft - 3) + { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw } + return result +} + +// Store a relative adjustment to the scroll position in the current +// operation (to be applied when the operation finishes). +function addToScrollTop(cm, top) { + if (top == null) { return } + resolveScrollToPos(cm) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top +} + +// Make sure that at the end of the operation the current cursor is +// shown. +function ensureCursorVisible(cm) { + resolveScrollToPos(cm) + var cur = cm.getCursor() + cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin} +} + +function scrollToCoords(cm, x, y) { + if (x != null || y != null) { resolveScrollToPos(cm) } + if (x != null) { cm.curOp.scrollLeft = x } + if (y != null) { cm.curOp.scrollTop = y } +} + +function scrollToRange(cm, range) { + resolveScrollToPos(cm) + cm.curOp.scrollToPos = range +} + +// When an operation has its scrollToPos property set, and another +// scroll action is applied before the end of the operation, this +// 'simulates' scrolling that position into view in a cheap way, so +// that the effect of intermediate scroll commands is not ignored. +function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos + if (range) { + cm.curOp.scrollToPos = null + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to) + scrollToCoordsRange(cm, from, to, range.margin) + } +} + +function scrollToCoordsRange(cm, from, to, margin) { + var sPos = calculateScrollPos(cm, { + left: Math.min(from.left, to.left), + top: Math.min(from.top, to.top) - margin, + right: Math.max(from.right, to.right), + bottom: Math.max(from.bottom, to.bottom) + margin + }) + scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop) +} + +// Sync the scrollable area and scrollbars, ensure the viewport +// covers the visible area. +function updateScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) { return } + if (!gecko) { updateDisplaySimple(cm, {top: val}) } + setScrollTop(cm, val, true) + if (gecko) { updateDisplaySimple(cm) } + startWorker(cm, 100) +} + +function setScrollTop(cm, val, forceScroll) { + val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val) + if (cm.display.scroller.scrollTop == val && !forceScroll) { return } + cm.doc.scrollTop = val + cm.display.scrollbars.setScrollTop(val) + if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val } +} + +// Sync scroller and scrollbar, ensure the gutter elements are +// aligned. +function setScrollLeft(cm, val, isScroller, forceScroll) { + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth) + if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return } + cm.doc.scrollLeft = val + alignHorizontally(cm) + if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val } + cm.display.scrollbars.setScrollLeft(val) +} + +// SCROLLBARS + +// Prepare DOM reads needed to update the scrollbars. Done in one +// shot to minimize update/measure roundtrips. +function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth + var docH = Math.round(cm.doc.height + paddingVert(cm.display)) + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + } +} + +var NativeScrollbars = function(place, scroll, cm) { + this.cm = cm + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar") + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar") + place(vert); place(horiz) + + on(vert, "scroll", function () { + if (vert.clientHeight) { scroll(vert.scrollTop, "vertical") } + }) + on(horiz, "scroll", function () { + if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal") } + }) + + this.checkedZeroWidth = false + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px" } +}; + +NativeScrollbars.prototype.update = function (measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1 + var needsV = measure.scrollHeight > measure.clientHeight + 1 + var sWidth = measure.nativeBarWidth + + if (needsV) { + this.vert.style.display = "block" + this.vert.style.bottom = needsH ? sWidth + "px" : "0" + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0) + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px" + } else { + this.vert.style.display = "" + this.vert.firstChild.style.height = "0" + } + + if (needsH) { + this.horiz.style.display = "block" + this.horiz.style.right = needsV ? sWidth + "px" : "0" + this.horiz.style.left = measure.barLeft + "px" + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0) + this.horiz.firstChild.style.width = + Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px" + } else { + this.horiz.style.display = "" + this.horiz.firstChild.style.width = "0" + } + + if (!this.checkedZeroWidth && measure.clientHeight > 0) { + if (sWidth == 0) { this.zeroWidthHack() } + this.checkedZeroWidth = true + } + + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0} +}; + +NativeScrollbars.prototype.setScrollLeft = function (pos) { + if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos } + if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") } +}; + +NativeScrollbars.prototype.setScrollTop = function (pos) { + if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos } + if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert") } +}; + +NativeScrollbars.prototype.zeroWidthHack = function () { + var w = mac && !mac_geMountainLion ? "12px" : "18px" + this.horiz.style.height = this.vert.style.width = w + this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none" + this.disableHoriz = new Delayed + this.disableVert = new Delayed +}; + +NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { + bar.style.pointerEvents = "auto" + function maybeDisable() { + // To find out whether the scrollbar is still visible, we + // check whether the element under the pixel in the bottom + // right corner of the scrollbar box is the scrollbar box + // itself (when the bar is still visible) or its filler child + // (when the bar is hidden). If it is still visible, we keep + // it enabled, if it's hidden, we disable pointer events. + var box = bar.getBoundingClientRect() + var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) + : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1) + if (elt != bar) { bar.style.pointerEvents = "none" } + else { delay.set(1000, maybeDisable) } + } + delay.set(1000, maybeDisable) +}; + +NativeScrollbars.prototype.clear = function () { + var parent = this.horiz.parentNode + parent.removeChild(this.horiz) + parent.removeChild(this.vert) +}; + +var NullScrollbars = function () {}; + +NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} }; +NullScrollbars.prototype.setScrollLeft = function () {}; +NullScrollbars.prototype.setScrollTop = function () {}; +NullScrollbars.prototype.clear = function () {}; + +function updateScrollbars(cm, measure) { + if (!measure) { measure = measureForScrollbars(cm) } + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight + updateScrollbarsInner(cm, measure) + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + { updateHeightsInViewport(cm) } + updateScrollbarsInner(cm, measureForScrollbars(cm)) + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight + } +} + +// Re-synchronize the fake scrollbars with the actual size of the +// content. +function updateScrollbarsInner(cm, measure) { + var d = cm.display + var sizes = d.scrollbars.update(measure) + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px" + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px" + d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block" + d.scrollbarFiller.style.height = sizes.bottom + "px" + d.scrollbarFiller.style.width = sizes.right + "px" + } else { d.scrollbarFiller.style.display = "" } + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block" + d.gutterFiller.style.height = sizes.bottom + "px" + d.gutterFiller.style.width = measure.gutterWidth + "px" + } else { d.gutterFiller.style.display = "" } +} + +var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars} + +function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear() + if (cm.display.scrollbars.addClass) + { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) } + } + + cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller) + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function () { + if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0) } + }) + node.setAttribute("cm-not-content", "true") + }, function (pos, axis) { + if (axis == "horizontal") { setScrollLeft(cm, pos) } + else { updateScrollTop(cm, pos) } + }, cm) + if (cm.display.scrollbars.addClass) + { addClass(cm.display.wrapper, cm.display.scrollbars.addClass) } +} + +// Operations are used to wrap a series of changes to the editor +// state in such a way that each change won't have to update the +// cursor and display (which would be awkward, slow, and +// error-prone). Instead, display updates are batched and then all +// combined and executed at once. + +var nextOpId = 0 +// Start a new operation. +function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + } + pushOperation(cm.curOp) +} + +// Finish an operation, updating the display and signalling delayed events +function endOperation(cm) { + var op = cm.curOp + finishOperation(op, function (group) { + for (var i = 0; i < group.ops.length; i++) + { group.ops[i].cm.curOp = null } + endOperations(group) + }) +} + +// The DOM updates done when an operation finishes are batched so +// that the minimum number of relayouts are required. +function endOperations(group) { + var ops = group.ops + for (var i = 0; i < ops.length; i++) // Read DOM + { endOperation_R1(ops[i]) } + for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe) + { endOperation_W1(ops[i$1]) } + for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM + { endOperation_R2(ops[i$2]) } + for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe) + { endOperation_W2(ops[i$3]) } + for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM + { endOperation_finish(ops[i$4]) } +} + +function endOperation_R1(op) { + var cm = op.cm, display = cm.display + maybeClipScrollbars(cm) + if (op.updateMaxLine) { findMaxLine(cm) } + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate) +} + +function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update) +} + +function endOperation_R2(op) { + var cm = op.cm, display = cm.display + if (op.updatedDisplay) { updateHeightsInViewport(cm) } + + op.barMeasure = measureForScrollbars(cm) + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3 + cm.display.sizerWidth = op.adjustWidthTo + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth) + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)) + } + + if (op.updatedDisplay || op.selectionChanged) + { op.preparedSelection = display.input.prepareSelection() } +} + +function endOperation_W2(op) { + var cm = op.cm + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px" + if (op.maxScrollLeft < cm.doc.scrollLeft) + { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true) } + cm.display.maxLineChanged = false + } + + var takeFocus = op.focus && op.focus == activeElt() + if (op.preparedSelection) + { cm.display.input.showSelection(op.preparedSelection, takeFocus) } + if (op.updatedDisplay || op.startHeight != cm.doc.height) + { updateScrollbars(cm, op.barMeasure) } + if (op.updatedDisplay) + { setDocumentHeight(cm, op.barMeasure) } + + if (op.selectionChanged) { restartBlink(cm) } + + if (cm.state.focused && op.updateInput) + { cm.display.input.reset(op.typing) } + if (takeFocus) { ensureFocus(op.cm) } +} + +function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc + + if (op.updatedDisplay) { postUpdateDisplay(cm, op.update) } + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + { display.wheelStartX = display.wheelStartY = null } + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll) } + + if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true) } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin) + maybeScrollWindow(cm, rect) + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers + if (hidden) { for (var i = 0; i < hidden.length; ++i) + { if (!hidden[i].lines.length) { signal(hidden[i], "hide") } } } + if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1) + { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide") } } } + + if (display.wrapper.offsetHeight) + { doc.scrollTop = cm.display.scroller.scrollTop } + + // Fire change events, and delayed event handlers + if (op.changeObjs) + { signal(cm, "changes", cm, op.changeObjs) } + if (op.update) + { op.update.finish() } +} + +// Run the given function in an operation +function runInOp(cm, f) { + if (cm.curOp) { return f() } + startOperation(cm) + try { return f() } + finally { endOperation(cm) } +} +// Wraps a function in an operation. Returns the wrapped function. +function operation(cm, f) { + return function() { + if (cm.curOp) { return f.apply(cm, arguments) } + startOperation(cm) + try { return f.apply(cm, arguments) } + finally { endOperation(cm) } + } +} +// Used to add methods to editor and doc instances, wrapping them in +// operations. +function methodOp(f) { + return function() { + if (this.curOp) { return f.apply(this, arguments) } + startOperation(this) + try { return f.apply(this, arguments) } + finally { endOperation(this) } + } +} +function docMethodOp(f) { + return function() { + var cm = this.cm + if (!cm || cm.curOp) { return f.apply(this, arguments) } + startOperation(cm) + try { return f.apply(this, arguments) } + finally { endOperation(cm) } + } +} + +// Updates the display.view data structure for a given change to the +// document. From and to are in pre-change coordinates. Lendiff is +// the amount of lines added or subtracted by the change. This is +// used for changes that span multiple lines, or change the way +// lines are divided into visual lines. regLineChange (below) +// registers single-line changes. +function regChange(cm, from, to, lendiff) { + if (from == null) { from = cm.doc.first } + if (to == null) { to = cm.doc.first + cm.doc.size } + if (!lendiff) { lendiff = 0 } + + var display = cm.display + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + { display.updateLineNumbers = from } + + cm.curOp.viewChanged = true + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + { resetView(cm) } + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm) + } else { + display.viewFrom += lendiff + display.viewTo += lendiff + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm) + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1) + if (cut) { + display.view = display.view.slice(cut.index) + display.viewFrom = cut.lineN + display.viewTo += lendiff + } else { + resetView(cm) + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut$1 = viewCuttingPoint(cm, from, from, -1) + if (cut$1) { + display.view = display.view.slice(0, cut$1.index) + display.viewTo = cut$1.lineN + } else { + resetView(cm) + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1) + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1) + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)) + display.viewTo += lendiff + } else { + resetView(cm) + } + } + + var ext = display.externalMeasured + if (ext) { + if (to < ext.lineN) + { ext.lineN += lendiff } + else if (from < ext.lineN + ext.size) + { display.externalMeasured = null } + } +} + +// Register a change to a single line. Type must be one of "text", +// "gutter", "class", "widget" +function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true + var display = cm.display, ext = cm.display.externalMeasured + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + { display.externalMeasured = null } + + if (line < display.viewFrom || line >= display.viewTo) { return } + var lineView = display.view[findViewIndex(cm, line)] + if (lineView.node == null) { return } + var arr = lineView.changes || (lineView.changes = []) + if (indexOf(arr, type) == -1) { arr.push(type) } +} + +// Clear the view. +function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first + cm.display.view = [] + cm.display.viewOffset = 0 +} + +function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + { return {index: index, lineN: newN} } + var n = cm.display.viewFrom + for (var i = 0; i < index; i++) + { n += view[i].size } + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) { return null } + diff = (n + view[index].size) - oldN + index++ + } else { + diff = n - oldN + } + oldN += diff; newN += diff + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) { return null } + newN += dir * view[index - (dir < 0 ? 1 : 0)].size + index += dir + } + return {index: index, lineN: newN} +} + +// Force the view to cover a given range, adding empty view element +// or clipping off existing ones as needed. +function adjustView(cm, from, to) { + var display = cm.display, view = display.view + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to) + display.viewFrom = from + } else { + if (display.viewFrom > from) + { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view) } + else if (display.viewFrom < from) + { display.view = display.view.slice(findViewIndex(cm, from)) } + display.viewFrom = from + if (display.viewTo < to) + { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)) } + else if (display.viewTo > to) + { display.view = display.view.slice(0, findViewIndex(cm, to)) } + } + display.viewTo = to +} + +// Count the number of lines in the view whose DOM representation is +// out of date (or nonexistent). +function countDirtyView(cm) { + var view = cm.display.view, dirty = 0 + for (var i = 0; i < view.length; i++) { + var lineView = view[i] + if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty } + } + return dirty +} + +// HIGHLIGHT WORKER + +function startWorker(cm, time) { + if (cm.doc.highlightFrontier < cm.display.viewTo) + { cm.state.highlight.set(time, bind(highlightWorker, cm)) } +} + +function highlightWorker(cm) { + var doc = cm.doc + if (doc.highlightFrontier >= cm.display.viewTo) { return } + var end = +new Date + cm.options.workTime + var context = getContextBefore(cm, doc.highlightFrontier) + var changedLines = [] + + doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { + if (context.line >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles + var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null + var highlighted = highlightLine(cm, line, context, true) + if (resetState) { context.state = resetState } + line.styles = highlighted.styles + var oldCls = line.styleClasses, newCls = highlighted.classes + if (newCls) { line.styleClasses = newCls } + else if (oldCls) { line.styleClasses = null } + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass) + for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i] } + if (ischange) { changedLines.push(context.line) } + line.stateAfter = context.save() + context.nextLine() + } else { + if (line.text.length <= cm.options.maxHighlightLength) + { processLine(cm, line.text, context) } + line.stateAfter = context.line % 5 == 0 ? context.save() : null + context.nextLine() + } + if (+new Date > end) { + startWorker(cm, cm.options.workDelay) + return true + } + }) + doc.highlightFrontier = context.line + doc.modeFrontier = Math.max(doc.modeFrontier, context.line) + if (changedLines.length) { runInOp(cm, function () { + for (var i = 0; i < changedLines.length; i++) + { regLineChange(cm, changedLines[i], "text") } + }) } +} + +// DISPLAY DRAWING + +var DisplayUpdate = function(cm, viewport, force) { + var display = cm.display + + this.viewport = viewport + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport) + this.editorIsHidden = !display.wrapper.offsetWidth + this.wrapperHeight = display.wrapper.clientHeight + this.wrapperWidth = display.wrapper.clientWidth + this.oldDisplayWidth = displayWidth(cm) + this.force = force + this.dims = getDimensions(cm) + this.events = [] +}; + +DisplayUpdate.prototype.signal = function (emitter, type) { + if (hasHandler(emitter, type)) + { this.events.push(arguments) } +}; +DisplayUpdate.prototype.finish = function () { + var this$1 = this; + + for (var i = 0; i < this.events.length; i++) + { signal.apply(null, this$1.events[i]) } +}; + +function maybeClipScrollbars(cm) { + var display = cm.display + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth + display.heightForcer.style.height = scrollGap(cm) + "px" + display.sizer.style.marginBottom = -display.nativeBarWidth + "px" + display.sizer.style.borderRightWidth = scrollGap(cm) + "px" + display.scrollbarsClipped = true + } +} + +function selectionSnapshot(cm) { + if (cm.hasFocus()) { return null } + var active = activeElt() + if (!active || !contains(cm.display.lineDiv, active)) { return null } + var result = {activeElt: active} + if (window.getSelection) { + var sel = window.getSelection() + if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { + result.anchorNode = sel.anchorNode + result.anchorOffset = sel.anchorOffset + result.focusNode = sel.focusNode + result.focusOffset = sel.focusOffset + } + } + return result +} + +function restoreSelection(snapshot) { + if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return } + snapshot.activeElt.focus() + if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { + var sel = window.getSelection(), range = document.createRange() + range.setEnd(snapshot.anchorNode, snapshot.anchorOffset) + range.collapse(false) + sel.removeAllRanges() + sel.addRange(range) + sel.extend(snapshot.focusNode, snapshot.focusOffset) + } +} + +// Does the actual updating of the line display. Bails out +// (returning false) when there is nothing to be done and forced is +// false. +function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc + + if (update.editorIsHidden) { + resetView(cm) + return false + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + { return false } + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm) + update.dims = getDimensions(cm) + } + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first) + var to = Math.min(end, update.visible.to + cm.options.viewportMargin) + if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom) } + if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo) } + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from) + to = visualLineEndNo(cm.doc, to) + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth + adjustView(cm, from, to) + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)) + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px" + + var toUpdate = countDirtyView(cm) + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + { return false } + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var selSnapshot = selectionSnapshot(cm) + if (toUpdate > 4) { display.lineDiv.style.display = "none" } + patchDisplay(cm, display.updateLineNumbers, update.dims) + if (toUpdate > 4) { display.lineDiv.style.display = "" } + display.renderedView = display.view + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + restoreSelection(selSnapshot) + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv) + removeChildren(display.selectionDiv) + display.gutters.style.height = display.sizer.style.minHeight = 0 + + if (different) { + display.lastWrapHeight = update.wrapperHeight + display.lastWrapWidth = update.wrapperWidth + startWorker(cm, 400) + } + + display.updateLineNumbers = null + + return true +} + +function postUpdateDisplay(cm, update) { + var viewport = update.viewport + + for (var first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)} } + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport) + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + { break } + } + if (!updateDisplayIfNeeded(cm, update)) { break } + updateHeightsInViewport(cm) + var barMeasure = measureForScrollbars(cm) + updateSelection(cm) + updateScrollbars(cm, barMeasure) + setDocumentHeight(cm, barMeasure) + update.force = false + } + + update.signal(cm, "update", cm) + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo) + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo + } +} + +function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport) + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm) + postUpdateDisplay(cm, update) + var barMeasure = measureForScrollbars(cm) + updateSelection(cm) + updateScrollbars(cm, barMeasure) + setDocumentHeight(cm, barMeasure) + update.finish() + } +} + +// Sync the actual display DOM structure with display.view, removing +// nodes for lines that are no longer in view, and creating the ones +// that are not there yet, and updating the ones that are out of +// date. +function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers + var container = display.lineDiv, cur = container.firstChild + + function rm(node) { + var next = node.nextSibling + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + { node.style.display = "none" } + else + { node.parentNode.removeChild(node) } + return next + } + + var view = display.view, lineN = display.viewFrom + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i] + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims) + container.insertBefore(node, cur) + } else { // Already drawn + while (cur != lineView.node) { cur = rm(cur) } + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false } + updateLineForChanges(cm, lineView, lineN, dims) + } + if (updateNumber) { + removeChildren(lineView.lineNumber) + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))) + } + cur = lineView.node.nextSibling + } + lineN += lineView.size + } + while (cur) { cur = rm(cur) } +} + +function updateGutterSpace(cm) { + var width = cm.display.gutters.offsetWidth + cm.display.sizer.style.marginLeft = width + "px" +} + +function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px" + cm.display.heightForcer.style.top = measure.docHeight + "px" + cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px" +} + +// Rebuild the gutter elements, ensure the margin to the left of the +// code matches their width. +function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters + removeChildren(gutters) + var i = 0 + for (; i < specs.length; ++i) { + var gutterClass = specs[i] + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)) + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt + gElt.style.width = (cm.display.lineNumWidth || 1) + "px" + } + } + gutters.style.display = i ? "" : "none" + updateGutterSpace(cm) +} + +// Make sure the gutters options contains the element +// "CodeMirror-linenumbers" when the lineNumbers option is true. +function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers") + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]) + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0) + options.gutters.splice(found, 1) + } +} + +var wheelSamples = 0; +var wheelPixelsPerUnit = null; +// Fill in a browser-detected starting value on browsers where we +// know one. These don't have to be accurate -- the result of them +// being wrong would just be a slight flicker on the first wheel +// scroll (if it is large enough). +if (ie) { wheelPixelsPerUnit = -.53 } +else if (gecko) { wheelPixelsPerUnit = 15 } +else if (chrome) { wheelPixelsPerUnit = -.7 } +else if (safari) { wheelPixelsPerUnit = -1/3 } + +function wheelEventDelta(e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail } + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail } + else if (dy == null) { dy = e.wheelDelta } + return {x: dx, y: dy} +} +function wheelEventPixels(e) { + var delta = wheelEventDelta(e) + delta.x *= wheelPixelsPerUnit + delta.y *= wheelPixelsPerUnit + return delta +} + +function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y + + var display = cm.display, scroll = display.scroller + // Quit if there's nothing to scroll here + var canScrollX = scroll.scrollWidth > scroll.clientWidth + var canScrollY = scroll.scrollHeight > scroll.clientHeight + if (!(dx && canScrollX || dy && canScrollY)) { return } + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur + break outer + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy && canScrollY) + { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) } + setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit)) + // Only prevent default scrolling if vertical scrolling is + // actually possible. Otherwise, it causes vertical scroll + // jitter on OSX trackpads when deltaX is small and deltaY + // is large (issue #3579) + if (!dy || (dy && canScrollY)) + { e_preventDefault(e) } + display.wheelStartX = null // Abort measurement, if in progress + return + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight + if (pixels < 0) { top = Math.max(0, top + pixels - 50) } + else { bot = Math.min(cm.doc.height, bot + pixels + 50) } + updateDisplaySimple(cm, {top: top, bottom: bot}) + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop + display.wheelDX = dx; display.wheelDY = dy + setTimeout(function () { + if (display.wheelStartX == null) { return } + var movedX = scroll.scrollLeft - display.wheelStartX + var movedY = scroll.scrollTop - display.wheelStartY + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX) + display.wheelStartX = display.wheelStartY = null + if (!sample) { return } + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1) + ++wheelSamples + }, 200) + } else { + display.wheelDX += dx; display.wheelDY += dy + } + } +} + +// Selection objects are immutable. A new one is created every time +// the selection changes. A selection is one or more non-overlapping +// (and non-touching) ranges, sorted, and an integer that indicates +// which one is the primary selection (the one that's scrolled into +// view, that getCursor returns, etc). +var Selection = function(ranges, primIndex) { + this.ranges = ranges + this.primIndex = primIndex +}; + +Selection.prototype.primary = function () { return this.ranges[this.primIndex] }; + +Selection.prototype.equals = function (other) { + var this$1 = this; + + if (other == this) { return true } + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false } + for (var i = 0; i < this.ranges.length; i++) { + var here = this$1.ranges[i], there = other.ranges[i] + if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false } + } + return true +}; + +Selection.prototype.deepCopy = function () { + var this$1 = this; + + var out = [] + for (var i = 0; i < this.ranges.length; i++) + { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)) } + return new Selection(out, this.primIndex) +}; + +Selection.prototype.somethingSelected = function () { + var this$1 = this; + + for (var i = 0; i < this.ranges.length; i++) + { if (!this$1.ranges[i].empty()) { return true } } + return false +}; + +Selection.prototype.contains = function (pos, end) { + var this$1 = this; + + if (!end) { end = pos } + for (var i = 0; i < this.ranges.length; i++) { + var range = this$1.ranges[i] + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + { return i } + } + return -1 +}; + +var Range = function(anchor, head) { + this.anchor = anchor; this.head = head +}; + +Range.prototype.from = function () { return minPos(this.anchor, this.head) }; +Range.prototype.to = function () { return maxPos(this.anchor, this.head) }; +Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch }; + +// Take an unsorted, potentially overlapping set of ranges, and +// build a selection out of it. 'Consumes' ranges array (modifying +// it). +function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex] + ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }) + primIndex = indexOf(ranges, prim) + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1] + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()) + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head + if (i <= primIndex) { --primIndex } + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)) + } + } + return new Selection(ranges, primIndex) +} + +function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0) +} + +// Compute the position of the end of a change (its 'to' property +// refers to the pre-change end). +function changeEnd(change) { + if (!change.text) { return change.to } + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)) +} + +// Adjust a position to refer to the post-change position of the +// same text, or the end of the change if the change covers it. +function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) { return pos } + if (cmp(pos, change.to) <= 0) { return changeEnd(change) } + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch + if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch } + return Pos(line, ch) +} + +function computeSelAfterChange(doc, change) { + var out = [] + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i] + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))) + } + return normalizeSelection(out, doc.sel.primIndex) +} + +function offsetPos(pos, old, nw) { + if (pos.line == old.line) + { return Pos(nw.line, pos.ch - old.ch + nw.ch) } + else + { return Pos(nw.line + (pos.line - old.line), pos.ch) } +} + +// Used by replaceSelections to allow moving the selection to the +// start or around the replaced test. Hint may be "start" or "around". +function computeReplacedSel(doc, changes, hint) { + var out = [] + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev + for (var i = 0; i < changes.length; i++) { + var change = changes[i] + var from = offsetPos(change.from, oldPrev, newPrev) + var to = offsetPos(changeEnd(change), oldPrev, newPrev) + oldPrev = change.to + newPrev = to + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0 + out[i] = new Range(inv ? to : from, inv ? from : to) + } else { + out[i] = new Range(from, from) + } + } + return new Selection(out, doc.sel.primIndex) +} + +// Used to get the editor into a consistent state again when options change. + +function loadMode(cm) { + cm.doc.mode = getMode(cm.options, cm.doc.modeOption) + resetModeState(cm) +} + +function resetModeState(cm) { + cm.doc.iter(function (line) { + if (line.stateAfter) { line.stateAfter = null } + if (line.styles) { line.styles = null } + }) + cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first + startWorker(cm, 100) + cm.state.modeGen++ + if (cm.curOp) { regChange(cm) } +} + +// DOCUMENT DATA STRUCTURE + +// By default, updates that start and end at the beginning of a line +// are treated specially, in order to make the association of line +// widgets and marker elements with the text behave more intuitive. +function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore) +} + +// Perform a change on the document data structure. +function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight) + signalLater(line, "change", line, change) + } + function linesFor(start, end) { + var result = [] + for (var i = start; i < end; ++i) + { result.push(new Line(text[i], spansFor(i), estimateHeight)) } + return result + } + + var from = change.from, to = change.to, text = change.text + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line) + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)) + doc.remove(text.length, doc.size - text.length) + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1) + update(lastLine, lastLine.text, lastSpans) + if (nlines) { doc.remove(from.line, nlines) } + if (added.length) { doc.insert(from.line, added) } + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans) + } else { + var added$1 = linesFor(1, text.length - 1) + added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)) + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) + doc.insert(from.line + 1, added$1) + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)) + doc.remove(from.line + 1, nlines) + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans) + var added$2 = linesFor(1, text.length - 1) + if (nlines > 1) { doc.remove(from.line + 1, nlines - 1) } + doc.insert(from.line + 1, added$2) + } + + signalLater(doc, "change", doc, change) +} + +// Call f for all linked documents. +function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i] + if (rel.doc == skip) { continue } + var shared = sharedHist && rel.sharedHist + if (sharedHistOnly && !shared) { continue } + f(rel.doc, shared) + propagate(rel.doc, doc, shared) + } } + } + propagate(doc, null, true) +} + +// Attach a document to an editor. +function attachDoc(cm, doc) { + if (doc.cm) { throw new Error("This document is already in use.") } + cm.doc = doc + doc.cm = cm + estimateLineHeights(cm) + loadMode(cm) + setDirectionClass(cm) + if (!cm.options.lineWrapping) { findMaxLine(cm) } + cm.options.mode = doc.modeOption + regChange(cm) +} + +function setDirectionClass(cm) { + ;(cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl") +} + +function directionChanged(cm) { + runInOp(cm, function () { + setDirectionClass(cm) + regChange(cm) + }) +} + +function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = [] + this.undoDepth = Infinity + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0 + this.lastOp = this.lastSelOp = null + this.lastOrigin = this.lastSelOrigin = null + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1 +} + +// Create a history change event from an updateDoc-style change +// object. +function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)} + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1) + linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true) + return histChange +} + +// Pop all selection events off the end of a history array. Stop at +// a change event. +function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array) + if (last.ranges) { array.pop() } + else { break } + } +} + +// Find the top change event in the history. Pop off selection +// events that are in the way. +function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done) + return lst(hist.done) + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done) + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop() + return lst(hist.done) + } +} + +// Register a change in the history. Merges changes that are within +// a single operation, or are close together with an origin that +// allows merging (starting with "+") into a single event. +function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history + hist.undone.length = 0 + var time = +new Date, cur + var last + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + last = lst(cur.changes) + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change) + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)) + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done) + if (!before || !before.ranges) + { pushSelectionToHistory(doc.sel, hist.done) } + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation} + hist.done.push(cur) + while (hist.done.length > hist.undoDepth) { + hist.done.shift() + if (!hist.done[0].ranges) { hist.done.shift() } + } + } + hist.done.push(selAfter) + hist.generation = ++hist.maxGeneration + hist.lastModTime = hist.lastSelTime = time + hist.lastOp = hist.lastSelOp = opId + hist.lastOrigin = hist.lastSelOrigin = change.origin + + if (!last) { signal(doc, "historyAdded") } +} + +function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0) + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500) +} + +// Called whenever the selection changes, sets the new selection as +// the pending selection in the history, and pushes the old pending +// selection into the 'done' array when it was significantly +// different (in number of selected ranges, emptiness, or time). +function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + { hist.done[hist.done.length - 1] = sel } + else + { pushSelectionToHistory(sel, hist.done) } + + hist.lastSelTime = +new Date + hist.lastSelOrigin = origin + hist.lastSelOp = opId + if (options && options.clearRedo !== false) + { clearSelectionEvents(hist.undone) } +} + +function pushSelectionToHistory(sel, dest) { + var top = lst(dest) + if (!(top && top.ranges && top.equals(sel))) + { dest.push(sel) } +} + +// Used to store marked span information in the history. +function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0 + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { + if (line.markedSpans) + { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans } + ++n + }) +} + +// When un/re-doing restores text containing marked spans, those +// that have been explicitly cleared should not be restored. +function removeClearedSpans(spans) { + if (!spans) { return null } + var out + for (var i = 0; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i) } } + else if (out) { out.push(spans[i]) } + } + return !out ? spans : out.length ? out : null +} + +// Retrieve and filter the old marked spans stored in a change event. +function getOldSpans(doc, change) { + var found = change["spans_" + doc.id] + if (!found) { return null } + var nw = [] + for (var i = 0; i < change.text.length; ++i) + { nw.push(removeClearedSpans(found[i])) } + return nw +} + +// Used for un/re-doing changes from the history. Combines the +// result of computing the existing spans with the set of spans that +// existed in the history (so that deleting around a span and then +// undoing brings back the span). +function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change) + var stretched = stretchSpansOverChange(doc, change) + if (!old) { return stretched } + if (!stretched) { return old } + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i] + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j] + for (var k = 0; k < oldCur.length; ++k) + { if (oldCur[k].marker == span.marker) { continue spans } } + oldCur.push(span) + } + } else if (stretchCur) { + old[i] = stretchCur + } + } + return old +} + +// Used both to provide a JSON-safe object in .getHistory, and, when +// detaching a document, to split the history in two +function copyHistoryArray(events, newGroup, instantiateSel) { + var copy = [] + for (var i = 0; i < events.length; ++i) { + var event = events[i] + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event) + continue + } + var changes = event.changes, newChanges = [] + copy.push({changes: newChanges}) + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m = (void 0) + newChanges.push({from: change.from, to: change.to, text: change.text}) + if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop] + delete change[prop] + } + } } } + } + } + return copy +} + +// The 'scroll' parameter given to many of these indicated whether +// the new cursor position should be scrolled into view after +// modifying the selection. + +// If shift is held or the extend flag is set, extends a range to +// include a given position (and optionally a second position). +// Otherwise, simply returns the range between the given positions. +// Used for cursor motion and such. +function extendRange(range, head, other, extend) { + if (extend) { + var anchor = range.anchor + if (other) { + var posBefore = cmp(head, anchor) < 0 + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head + head = other + } else if (posBefore != (cmp(head, other) < 0)) { + head = other + } + } + return new Range(anchor, head) + } else { + return new Range(other || head, head) + } +} + +// Extend the primary selection range, discard the rest. +function extendSelection(doc, head, other, options, extend) { + if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend) } + setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options) +} + +// Extend all selections (pos is an array of selections with length +// equal the number of selections) +function extendSelections(doc, heads, options) { + var out = [] + var extend = doc.cm && (doc.cm.display.shift || doc.extend) + for (var i = 0; i < doc.sel.ranges.length; i++) + { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend) } + var newSel = normalizeSelection(out, doc.sel.primIndex) + setSelection(doc, newSel, options) +} + +// Updates a single range in the selection. +function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0) + ranges[i] = range + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options) +} + +// Reset the selection to a single range. +function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options) +} + +// Give beforeSelectionChange handlers a change to influence a +// selection update. +function filterSelectionChange(doc, sel, options) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + var this$1 = this; + + this.ranges = [] + for (var i = 0; i < ranges.length; i++) + { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)) } + }, + origin: options && options.origin + } + signal(doc, "beforeSelectionChange", doc, obj) + if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj) } + if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) } + else { return sel } +} + +function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done) + if (last && last.ranges) { + done[done.length - 1] = sel + setSelectionNoUndo(doc, sel, options) + } else { + setSelection(doc, sel, options) + } +} + +// Set a new selection. +function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options) + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options) +} + +function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + { sel = filterSelectionChange(doc, sel, options) } + + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1) + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)) + + if (!(options && options.scroll === false) && doc.cm) + { ensureCursorVisible(doc.cm) } +} + +function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) { return } + + doc.sel = sel + + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true + signalCursorActivity(doc.cm) + } + signalLater(doc, "cursorActivity", doc) +} + +// Verify that the selection does not partially select any atomic +// marked ranges. +function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false)) +} + +// Return a selection that does not partially select any atomic +// ranges. +function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i] + var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i] + var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear) + var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear) + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) { out = sel.ranges.slice(0, i) } + out[i] = new Range(newAnchor, newHead) + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel +} + +function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { + var line = getLine(doc, pos.line) + if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter") + if (m.explicitlyCleared) { + if (!line.markedSpans) { break } + else {--i; continue} + } + } + if (!m.atomic) { continue } + + if (oldPos) { + var near = m.find(dir < 0 ? 1 : -1), diff = (void 0) + if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) + { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null) } + if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) + { return skipAtomicInner(doc, near, pos, dir, mayClear) } + } + + var far = m.find(dir < 0 ? -1 : 1) + if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) + { far = movePos(doc, far, dir, far.line == pos.line ? line : null) } + return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null + } + } } + return pos +} + +// Ensure a given position is not inside an atomic range. +function skipAtomic(doc, pos, oldPos, bias, mayClear) { + var dir = bias || 1 + var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || + skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)) + if (!found) { + doc.cantEdit = true + return Pos(doc.first, 0) + } + return found +} + +function movePos(doc, pos, dir, line) { + if (dir < 0 && pos.ch == 0) { + if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) } + else { return null } + } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { + if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) } + else { return null } + } else { + return new Pos(pos.line, pos.ch + dir) + } +} + +function selectAll(cm) { + cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll) +} + +// UPDATING + +// Allow "beforeChange" event handlers to influence a change +function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function () { return obj.canceled = true; } + } + if (update) { obj.update = function (from, to, text, origin) { + if (from) { obj.from = clipPos(doc, from) } + if (to) { obj.to = clipPos(doc, to) } + if (text) { obj.text = text } + if (origin !== undefined) { obj.origin = origin } + } } + signal(doc, "beforeChange", doc, obj) + if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj) } + + if (obj.canceled) { return null } + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin} +} + +// Apply a change to a document, and add it to the document's +// history, and propagating it to all linked documents. +function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) } + if (doc.cm.state.suppressEdits) { return } + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true) + if (!change) { return } + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to) + if (split) { + for (var i = split.length - 1; i >= 0; --i) + { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}) } + } else { + makeChangeInner(doc, change) + } +} + +function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return } + var selAfter = computeSelAfterChange(doc, change) + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN) + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)) + var rebased = [] + + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change) + rebased.push(doc.history) + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)) + }) +} + +// Revert a change stored in a document's history. +function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return } + + var hist = doc.history, event, selAfter = doc.sel + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + var i = 0 + for (; i < source.length; i++) { + event = source[i] + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + { break } + } + if (i == source.length) { return } + hist.lastOrigin = hist.lastSelOrigin = null + + for (;;) { + event = source.pop() + if (event.ranges) { + pushSelectionToHistory(event, dest) + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}) + return + } + selAfter = event + } + else { break } + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = [] + pushSelectionToHistory(selAfter, dest) + dest.push({changes: antiChanges, generation: hist.generation}) + hist.generation = event.generation || ++hist.maxGeneration + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange") + + var loop = function ( i ) { + var change = event.changes[i] + change.origin = type + if (filter && !filterChange(doc, change, false)) { + source.length = 0 + return {} + } + + antiChanges.push(historyChangeFromChange(doc, change)) + + var after = i ? computeSelAfterChange(doc, change) : lst(source) + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)) + if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) } + var rebased = [] + + // Propagate to the linked documents + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change) + rebased.push(doc.history) + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)) + }) + }; + + for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) { + var returned = loop( i$1 ); + + if ( returned ) return returned.v; + } +} + +// Sub-views need their line numbers shifted when text is added +// above or below them in the parent document. +function shiftDoc(doc, distance) { + if (distance == 0) { return } + doc.first += distance + doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range( + Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch) + ); }), doc.sel.primIndex) + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance) + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + { regLineChange(doc.cm, l, "gutter") } + } +} + +// More lower-level change function, handling only a single document +// (not linked ones). +function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) } + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)) + return + } + if (change.from.line > doc.lastLine()) { return } + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line) + shiftDoc(doc, shift) + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin} + } + var last = doc.lastLine() + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin} + } + + change.removed = getBetween(doc, change.from, change.to) + + if (!selAfter) { selAfter = computeSelAfterChange(doc, change) } + if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans) } + else { updateDoc(doc, change, spans) } + setSelectionNoUndo(doc, selAfter, sel_dontScroll) +} + +// Handle the interaction of a change to a document with the editor +// that this document is part of. +function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to + + var recomputeMaxLength = false, checkWidthStart = from.line + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))) + doc.iter(checkWidthStart, to.line + 1, function (line) { + if (line == display.maxLine) { + recomputeMaxLength = true + return true + } + }) + } + + if (doc.sel.contains(change.from, change.to) > -1) + { signalCursorActivity(cm) } + + updateDoc(doc, change, spans, estimateHeight(cm)) + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function (line) { + var len = lineLength(line) + if (len > display.maxLineLength) { + display.maxLine = line + display.maxLineLength = len + display.maxLineChanged = true + recomputeMaxLength = false + } + }) + if (recomputeMaxLength) { cm.curOp.updateMaxLine = true } + } + + retreatFrontier(doc, from.line) + startWorker(cm, 400) + + var lendiff = change.text.length - (to.line - from.line) - 1 + // Remember that these lines changed, for updating the display + if (change.full) + { regChange(cm) } + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + { regLineChange(cm, from.line, "text") } + else + { regChange(cm, from.line, to.line + 1, lendiff) } + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change") + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + } + if (changeHandler) { signalLater(cm, "change", cm, obj) } + if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) } + } + cm.display.selForContextMenu = null +} + +function replaceRange(doc, code, from, to, origin) { + if (!to) { to = from } + if (cmp(to, from) < 0) { var assign; + (assign = [to, from], from = assign[0], to = assign[1], assign) } + if (typeof code == "string") { code = doc.splitLines(code) } + makeChange(doc, {from: from, to: to, text: code, origin: origin}) +} + +// Rebasing/resetting history to deal with externally-sourced changes + +function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff + } else if (from < pos.line) { + pos.line = from + pos.ch = 0 + } +} + +// Tries to rebase an array of history events given a change in the +// document. If the change touches the same lines as the event, the +// event, and everything 'behind' it, is discarded. If the change is +// before the event, the event's positions are updated. Uses a +// copy-on-write scheme for the positions, to avoid having to +// reallocate them all on every rebase, but also avoid problems with +// shared position objects being unsafely updated. +function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff) + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff) + } + continue + } + for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) { + var cur = sub.changes[j$1] + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch) + cur.to = Pos(cur.to.line + diff, cur.to.ch) + } else if (from <= cur.to.line) { + ok = false + break + } + } + if (!ok) { + array.splice(0, i + 1) + i = 0 + } + } +} + +function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1 + rebaseHistArray(hist.done, from, to, diff) + rebaseHistArray(hist.undone, from, to, diff) +} + +// Utility for applying a change to a line by handle or number, +// returning the number and optionally registering the line as +// changed. +function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle + if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)) } + else { no = lineNo(handle) } + if (no == null) { return null } + if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType) } + return line +} + +// The document is represented as a BTree consisting of leaves, with +// chunk of lines in them, and branches, with up to ten leaves or +// other branch nodes below them. The top node is always a branch +// node, and is the document object itself (meaning it has +// additional methods and properties). +// +// All nodes have parent links. The tree is used both to go from +// line numbers to line objects, and to go from objects to numbers. +// It also indexes by height, and is used to convert between height +// and line object, and to find the total height of the document. +// +// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + +function LeafChunk(lines) { + var this$1 = this; + + this.lines = lines + this.parent = null + var height = 0 + for (var i = 0; i < lines.length; ++i) { + lines[i].parent = this$1 + height += lines[i].height + } + this.height = height +} + +LeafChunk.prototype = { + chunkSize: function chunkSize() { return this.lines.length }, + + // Remove the n lines at offset 'at'. + removeInner: function removeInner(at, n) { + var this$1 = this; + + for (var i = at, e = at + n; i < e; ++i) { + var line = this$1.lines[i] + this$1.height -= line.height + cleanUpLine(line) + signalLater(line, "delete") + } + this.lines.splice(at, n) + }, + + // Helper used to collapse a small branch into a single leaf. + collapse: function collapse(lines) { + lines.push.apply(lines, this.lines) + }, + + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function insertInner(at, lines, height) { + var this$1 = this; + + this.height += height + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)) + for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 } + }, + + // Used to iterate over a part of the tree. + iterN: function iterN(at, n, op) { + var this$1 = this; + + for (var e = at + n; at < e; ++at) + { if (op(this$1.lines[at])) { return true } } + } +} + +function BranchChunk(children) { + var this$1 = this; + + this.children = children + var size = 0, height = 0 + for (var i = 0; i < children.length; ++i) { + var ch = children[i] + size += ch.chunkSize(); height += ch.height + ch.parent = this$1 + } + this.size = size + this.height = height + this.parent = null +} + +BranchChunk.prototype = { + chunkSize: function chunkSize() { return this.size }, + + removeInner: function removeInner(at, n) { + var this$1 = this; + + this.size -= n + for (var i = 0; i < this.children.length; ++i) { + var child = this$1.children[i], sz = child.chunkSize() + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height + child.removeInner(at, rm) + this$1.height -= oldHeight - child.height + if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null } + if ((n -= rm) == 0) { break } + at = 0 + } else { at -= sz } + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = [] + this.collapse(lines) + this.children = [new LeafChunk(lines)] + this.children[0].parent = this + } + }, + + collapse: function collapse(lines) { + var this$1 = this; + + for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) } + }, + + insertInner: function insertInner(at, lines, height) { + var this$1 = this; + + this.size += lines.length + this.height += height + for (var i = 0; i < this.children.length; ++i) { + var child = this$1.children[i], sz = child.chunkSize() + if (at <= sz) { + child.insertInner(at, lines, height) + if (child.lines && child.lines.length > 50) { + // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. + // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. + var remaining = child.lines.length % 25 + 25 + for (var pos = remaining; pos < child.lines.length;) { + var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)) + child.height -= leaf.height + this$1.children.splice(++i, 0, leaf) + leaf.parent = this$1 + } + child.lines = child.lines.slice(0, remaining) + this$1.maybeSpill() + } + break + } + at -= sz + } + }, + + // When a node has grown, check whether it should be split. + maybeSpill: function maybeSpill() { + if (this.children.length <= 10) { return } + var me = this + do { + var spilled = me.children.splice(me.children.length - 5, 5) + var sibling = new BranchChunk(spilled) + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children) + copy.parent = me + me.children = [copy, sibling] + me = copy + } else { + me.size -= sibling.size + me.height -= sibling.height + var myIndex = indexOf(me.parent.children, me) + me.parent.children.splice(myIndex + 1, 0, sibling) + } + sibling.parent = me.parent + } while (me.children.length > 10) + me.parent.maybeSpill() + }, + + iterN: function iterN(at, n, op) { + var this$1 = this; + + for (var i = 0; i < this.children.length; ++i) { + var child = this$1.children[i], sz = child.chunkSize() + if (at < sz) { + var used = Math.min(n, sz - at) + if (child.iterN(at, used, op)) { return true } + if ((n -= used) == 0) { break } + at = 0 + } else { at -= sz } + } + } +} + +// Line widgets are block elements displayed above or below a line. + +var LineWidget = function(doc, node, options) { + var this$1 = this; + + if (options) { for (var opt in options) { if (options.hasOwnProperty(opt)) + { this$1[opt] = options[opt] } } } + this.doc = doc + this.node = node +}; + +LineWidget.prototype.clear = function () { + var this$1 = this; + + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line) + if (no == null || !ws) { return } + for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1) } } + if (!ws.length) { line.widgets = null } + var height = widgetHeight(this) + updateLineHeight(line, Math.max(0, line.height - height)) + if (cm) { + runInOp(cm, function () { + adjustScrollWhenAboveVisible(cm, line, -height) + regLineChange(cm, no, "widget") + }) + signalLater(cm, "lineWidgetCleared", cm, this, no) + } +}; + +LineWidget.prototype.changed = function () { + var this$1 = this; + + var oldH = this.height, cm = this.doc.cm, line = this.line + this.height = null + var diff = widgetHeight(this) - oldH + if (!diff) { return } + updateLineHeight(line, line.height + diff) + if (cm) { + runInOp(cm, function () { + cm.curOp.forceUpdate = true + adjustScrollWhenAboveVisible(cm, line, diff) + signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line)) + }) + } +}; +eventMixin(LineWidget) + +function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + { addToScrollTop(cm, diff) } +} + +function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options) + var cm = doc.cm + if (cm && widget.noHScroll) { cm.display.alignWidgets = true } + changeLine(doc, handle, "widget", function (line) { + var widgets = line.widgets || (line.widgets = []) + if (widget.insertAt == null) { widgets.push(widget) } + else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget) } + widget.line = line + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop + updateLineHeight(line, line.height + widgetHeight(widget)) + if (aboveVisible) { addToScrollTop(cm, widget.height) } + cm.curOp.forceUpdate = true + } + return true + }) + signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)) + return widget +} + +// TEXTMARKERS + +// Created with markText and setBookmark methods. A TextMarker is a +// handle that can be used to clear or find a marked position in the +// document. Line objects hold arrays (markedSpans) containing +// {from, to, marker} object pointing to such marker objects, and +// indicating that such a marker is present on that line. Multiple +// lines may point to the same marker when it spans across lines. +// The spans will have null for their from/to properties when the +// marker continues beyond the start/end of the line. Markers have +// links back to the lines they currently touch. + +// Collapsed markers have unique ids, in order to be able to order +// them, which is needed for uniquely determining an outer marker +// when they overlap (they may nest, but not partially overlap). +var nextMarkerId = 0 + +var TextMarker = function(doc, type) { + this.lines = [] + this.type = type + this.doc = doc + this.id = ++nextMarkerId +}; + +// Clear the marker. +TextMarker.prototype.clear = function () { + var this$1 = this; + + if (this.explicitlyCleared) { return } + var cm = this.doc.cm, withOp = cm && !cm.curOp + if (withOp) { startOperation(cm) } + if (hasHandler(this, "clear")) { + var found = this.find() + if (found) { signalLater(this, "clear", found.from, found.to) } + } + var min = null, max = null + for (var i = 0; i < this.lines.length; ++i) { + var line = this$1.lines[i] + var span = getMarkedSpanFor(line.markedSpans, this$1) + if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text") } + else if (cm) { + if (span.to != null) { max = lineNo(line) } + if (span.from != null) { min = lineNo(line) } + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span) + if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm) + { updateLineHeight(line, textHeight(cm.display)) } + } + if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) { + var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual) + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual + cm.display.maxLineLength = len + cm.display.maxLineChanged = true + } + } } + + if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1) } + this.lines.length = 0 + this.explicitlyCleared = true + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false + if (cm) { reCheckSelection(cm.doc) } + } + if (cm) { signalLater(cm, "markerCleared", cm, this, min, max) } + if (withOp) { endOperation(cm) } + if (this.parent) { this.parent.clear() } +}; + +// Find the position of the marker in the document. Returns a {from, +// to} object by default. Side can be passed to get a specific side +// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the +// Pos objects returned contain a line object, rather than a line +// number (used to prevent looking up the same line twice). +TextMarker.prototype.find = function (side, lineObj) { + var this$1 = this; + + if (side == null && this.type == "bookmark") { side = 1 } + var from, to + for (var i = 0; i < this.lines.length; ++i) { + var line = this$1.lines[i] + var span = getMarkedSpanFor(line.markedSpans, this$1) + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from) + if (side == -1) { return from } + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to) + if (side == 1) { return to } + } + } + return from && {from: from, to: to} +}; + +// Signals that the marker's widget changed, and surrounding layout +// should be recomputed. +TextMarker.prototype.changed = function () { + var this$1 = this; + + var pos = this.find(-1, true), widget = this, cm = this.doc.cm + if (!pos || !cm) { return } + runInOp(cm, function () { + var line = pos.line, lineN = lineNo(pos.line) + var view = findViewForLine(cm, lineN) + if (view) { + clearLineMeasurementCacheFor(view) + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true + } + cm.curOp.updateMaxLine = true + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height + widget.height = null + var dHeight = widgetHeight(widget) - oldHeight + if (dHeight) + { updateLineHeight(line, line.height + dHeight) } + } + signalLater(cm, "markerChanged", cm, this$1) + }) +}; + +TextMarker.prototype.attachLine = function (line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this) } + } + this.lines.push(line) +}; + +TextMarker.prototype.detachLine = function (line) { + this.lines.splice(indexOf(this.lines, line), 1) + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp + ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this) + } +}; +eventMixin(TextMarker) + +// Create a marker, wire it up to the right lines, and +function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) { return markTextShared(doc, from, to, options, type) } + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) } + + var marker = new TextMarker(doc, type), diff = cmp(from, to) + if (options) { copyObj(options, marker, false) } + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + { return marker } + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true + marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget") + if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true") } + if (options.insertLeft) { marker.widgetNode.insertLeft = true } + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + { throw new Error("Inserting collapsed marker partially overlapping an existing one") } + seeCollapsedSpans() + } + + if (marker.addToHistory) + { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN) } + + var curLine = from.line, cm = doc.cm, updateMaxLine + doc.iter(curLine, to.line + 1, function (line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + { updateMaxLine = true } + if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0) } + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)) + ++curLine + }) + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) { + if (lineIsHidden(doc, line)) { updateLineHeight(line, 0) } + }) } + + if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }) } + + if (marker.readOnly) { + seeReadOnlySpans() + if (doc.history.done.length || doc.history.undone.length) + { doc.clearHistory() } + } + if (marker.collapsed) { + marker.id = ++nextMarkerId + marker.atomic = true + } + if (cm) { + // Sync editor state + if (updateMaxLine) { cm.curOp.updateMaxLine = true } + if (marker.collapsed) + { regChange(cm, from.line, to.line + 1) } + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text") } } + if (marker.atomic) { reCheckSelection(cm.doc) } + signalLater(cm, "markerAdded", cm, marker) + } + return marker +} + +// SHARED TEXTMARKERS + +// A shared marker spans multiple linked documents. It is +// implemented as a meta-marker-object controlling multiple normal +// markers. +var SharedTextMarker = function(markers, primary) { + var this$1 = this; + + this.markers = markers + this.primary = primary + for (var i = 0; i < markers.length; ++i) + { markers[i].parent = this$1 } +}; + +SharedTextMarker.prototype.clear = function () { + var this$1 = this; + + if (this.explicitlyCleared) { return } + this.explicitlyCleared = true + for (var i = 0; i < this.markers.length; ++i) + { this$1.markers[i].clear() } + signalLater(this, "clear") +}; + +SharedTextMarker.prototype.find = function (side, lineObj) { + return this.primary.find(side, lineObj) +}; +eventMixin(SharedTextMarker) + +function markTextShared(doc, from, to, options, type) { + options = copyObj(options) + options.shared = false + var markers = [markText(doc, from, to, options, type)], primary = markers[0] + var widget = options.widgetNode + linkedDocs(doc, function (doc) { + if (widget) { options.widgetNode = widget.cloneNode(true) } + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)) + for (var i = 0; i < doc.linked.length; ++i) + { if (doc.linked[i].isParent) { return } } + primary = lst(markers) + }) + return new SharedTextMarker(markers, primary) +} + +function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; }) +} + +function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find() + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to) + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type) + marker.markers.push(subMark) + subMark.parent = marker + } + } +} + +function detachSharedMarkers(markers) { + var loop = function ( i ) { + var marker = markers[i], linked = [marker.primary.doc] + linkedDocs(marker.primary.doc, function (d) { return linked.push(d); }) + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j] + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null + marker.markers.splice(j--, 1) + } + } + }; + + for (var i = 0; i < markers.length; i++) loop( i ); +} + +var nextDocId = 0 +var Doc = function(text, mode, firstLine, lineSep, direction) { + if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) } + if (firstLine == null) { firstLine = 0 } + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]) + this.first = firstLine + this.scrollTop = this.scrollLeft = 0 + this.cantEdit = false + this.cleanGeneration = 1 + this.modeFrontier = this.highlightFrontier = firstLine + var start = Pos(firstLine, 0) + this.sel = simpleSelection(start) + this.history = new History(null) + this.id = ++nextDocId + this.modeOption = mode + this.lineSep = lineSep + this.direction = (direction == "rtl") ? "rtl" : "ltr" + this.extend = false + + if (typeof text == "string") { text = this.splitLines(text) } + updateDoc(this, {from: start, to: start, text: text}) + setSelection(this, simpleSelection(start), sel_dontScroll) +} + +Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) { this.iterN(from - this.first, to - from, op) } + else { this.iterN(this.first, this.first + this.size, from) } + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0 + for (var i = 0; i < lines.length; ++i) { height += lines[i].height } + this.insertInner(at - this.first, lines, height) + }, + remove: function(at, n) { this.removeInner(at - this.first, n) }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep) { + var lines = getLines(this, this.first, this.first + this.size) + if (lineSep === false) { return lines } + return lines.join(lineSep || this.lineSeparator()) + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1 + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: this.splitLines(code), origin: "setValue", full: true}, true) + if (this.cm) { scrollToCoords(this.cm, 0, 0) } + setSelection(this, simpleSelection(top), sel_dontScroll) + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from) + to = to ? clipPos(this, to) : from + replaceRange(this, code, from, to, origin) + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)) + if (lineSep === false) { return lines } + return lines.join(lineSep || this.lineSeparator()) + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text}, + + getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }}, + getLineNumber: function(line) {return lineNo(line)}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") { line = getLine(this, line) } + return visualLine(line) + }, + + lineCount: function() {return this.size}, + firstLine: function() {return this.first}, + lastLine: function() {return this.first + this.size - 1}, + + clipPos: function(pos) {return clipPos(this, pos)}, + + getCursor: function(start) { + var range = this.sel.primary(), pos + if (start == null || start == "head") { pos = range.head } + else if (start == "anchor") { pos = range.anchor } + else if (start == "end" || start == "to" || start === false) { pos = range.to() } + else { pos = range.from() } + return pos + }, + listSelections: function() { return this.sel.ranges }, + somethingSelected: function() {return this.sel.somethingSelected()}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options) + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options) + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options) + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads), options) + }), + extendSelectionsBy: docMethodOp(function(f, options) { + var heads = map(this.sel.ranges, f) + extendSelections(this, clipPosArray(this, heads), options) + }), + setSelections: docMethodOp(function(ranges, primary, options) { + var this$1 = this; + + if (!ranges.length) { return } + var out = [] + for (var i = 0; i < ranges.length; i++) + { out[i] = new Range(clipPos(this$1, ranges[i].anchor), + clipPos(this$1, ranges[i].head)) } + if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex) } + setSelection(this, normalizeSelection(out, primary), options) + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0) + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))) + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options) + }), + + getSelection: function(lineSep) { + var this$1 = this; + + var ranges = this.sel.ranges, lines + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this$1, ranges[i].from(), ranges[i].to()) + lines = lines ? lines.concat(sel) : sel + } + if (lineSep === false) { return lines } + else { return lines.join(lineSep || this.lineSeparator()) } + }, + getSelections: function(lineSep) { + var this$1 = this; + + var parts = [], ranges = this.sel.ranges + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this$1, ranges[i].from(), ranges[i].to()) + if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()) } + parts[i] = sel + } + return parts + }, + replaceSelection: function(code, collapse, origin) { + var dup = [] + for (var i = 0; i < this.sel.ranges.length; i++) + { dup[i] = code } + this.replaceSelections(dup, collapse, origin || "+input") + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + var this$1 = this; + + var changes = [], sel = this.sel + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i] + changes[i] = {from: range.from(), to: range.to(), text: this$1.splitLines(code[i]), origin: origin} + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse) + for (var i$1 = changes.length - 1; i$1 >= 0; i$1--) + { makeChange(this$1, changes[i$1]) } + if (newSel) { setSelectionReplaceHistory(this, newSel) } + else if (this.cm) { ensureCursorVisible(this.cm) } + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo")}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo")}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true)}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true)}), + + setExtending: function(val) {this.extend = val}, + getExtending: function() {return this.extend}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0 + for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done } } + for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone } } + return {undo: done, redo: undone} + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration)}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true) + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null } + return this.history.generation + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration) + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)} + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration) + hist.done = copyHistoryArray(histData.done.slice(0), null, true) + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true) + }, + + setGutterMarker: docMethodOp(function(line, gutterID, value) { + return changeLine(this, line, "gutter", function (line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}) + markers[gutterID] = value + if (!value && isEmpty(markers)) { line.gutterMarkers = null } + return true + }) + }), + + clearGutter: docMethodOp(function(gutterID) { + var this$1 = this; + + this.iter(function (line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + changeLine(this$1, line, "gutter", function () { + line.gutterMarkers[gutterID] = null + if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null } + return true + }) + } + }) + }), + + lineInfo: function(line) { + var n + if (typeof line == "number") { + if (!isLine(this, line)) { return null } + n = line + line = getLine(this, line) + if (!line) { return null } + } else { + n = lineNo(line) + if (n == null) { return null } + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets} + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass" + if (!line[prop]) { line[prop] = cls } + else if (classTest(cls).test(line[prop])) { return false } + else { line[prop] += " " + cls } + return true + }) + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass" + var cur = line[prop] + if (!cur) { return false } + else if (cls == null) { line[prop] = null } + else { + var found = cur.match(classTest(cls)) + if (!found) { return false } + var end = found.index + found[0].length + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null + } + return true + }) + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options) + }), + removeLineWidget: function(widget) { widget.clear() }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range") + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents} + pos = clipPos(this, pos) + return markText(this, pos, pos, realOpts, "bookmark") + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos) + var markers = [], spans = getLine(this, pos.line).markedSpans + if (spans) { for (var i = 0; i < spans.length; ++i) { + var span = spans[i] + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + { markers.push(span.marker.parent || span.marker) } + } } + return markers + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to) + var found = [], lineNo = from.line + this.iter(from.line, to.line + 1, function (line) { + var spans = line.markedSpans + if (spans) { for (var i = 0; i < spans.length; i++) { + var span = spans[i] + if (!(span.to != null && lineNo == from.line && from.ch >= span.to || + span.from == null && lineNo != from.line || + span.from != null && lineNo == to.line && span.from >= to.ch) && + (!filter || filter(span.marker))) + { found.push(span.marker.parent || span.marker) } + } } + ++lineNo + }) + return found + }, + getAllMarks: function() { + var markers = [] + this.iter(function (line) { + var sps = line.markedSpans + if (sps) { for (var i = 0; i < sps.length; ++i) + { if (sps[i].from != null) { markers.push(sps[i].marker) } } } + }) + return markers + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first, sepSize = this.lineSeparator().length + this.iter(function (line) { + var sz = line.text.length + sepSize + if (sz > off) { ch = off; return true } + off -= sz + ++lineNo + }) + return clipPos(this, Pos(lineNo, ch)) + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords) + var index = coords.ch + if (coords.line < this.first || coords.ch < 0) { return 0 } + var sepSize = this.lineSeparator().length + this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value + index += line.text.length + sepSize + }) + return index + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), + this.modeOption, this.first, this.lineSep, this.direction) + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft + doc.sel = this.sel + doc.extend = false + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth + doc.setHistory(this.getHistory()) + } + return doc + }, + + linkedDoc: function(options) { + if (!options) { options = {} } + var from = this.first, to = this.first + this.size + if (options.from != null && options.from > from) { from = options.from } + if (options.to != null && options.to < to) { to = options.to } + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction) + if (options.sharedHist) { copy.history = this.history + ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}) + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}] + copySharedMarkers(copy, findSharedMarkers(this)) + return copy + }, + unlinkDoc: function(other) { + var this$1 = this; + + if (other instanceof CodeMirror) { other = other.doc } + if (this.linked) { for (var i = 0; i < this.linked.length; ++i) { + var link = this$1.linked[i] + if (link.doc != other) { continue } + this$1.linked.splice(i, 1) + other.unlinkDoc(this$1) + detachSharedMarkers(findSharedMarkers(this$1)) + break + } } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id] + linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true) + other.history = new History(null) + other.history.done = copyHistoryArray(this.history.done, splitIds) + other.history.undone = copyHistoryArray(this.history.undone, splitIds) + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f)}, + + getMode: function() {return this.mode}, + getEditor: function() {return this.cm}, + + splitLines: function(str) { + if (this.lineSep) { return str.split(this.lineSep) } + return splitLinesAuto(str) + }, + lineSeparator: function() { return this.lineSep || "\n" }, + + setDirection: docMethodOp(function (dir) { + if (dir != "rtl") { dir = "ltr" } + if (dir == this.direction) { return } + this.direction = dir + this.iter(function (line) { return line.order = null; }) + if (this.cm) { directionChanged(this.cm) } + }) +}) + +// Public alias. +Doc.prototype.eachLine = Doc.prototype.iter + +// Kludge to work around strange IE behavior where it'll sometimes +// re-fire a series of drag-related events right after the drop (#1551) +var lastDrop = 0 + +function onDrop(e) { + var cm = this + clearDragCursor(cm) + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + { return } + e_preventDefault(e) + if (ie) { lastDrop = +new Date } + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files + if (!pos || cm.isReadOnly()) { return } + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0 + var loadFile = function (file, i) { + if (cm.options.allowDropFileTypes && + indexOf(cm.options.allowDropFileTypes, file.type) == -1) + { return } + + var reader = new FileReader + reader.onload = operation(cm, function () { + var content = reader.result + if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = "" } + text[i] = content + if (++read == n) { + pos = clipPos(cm.doc, pos) + var change = {from: pos, to: pos, + text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), + origin: "paste"} + makeChange(cm.doc, change) + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))) + } + }) + reader.readAsText(file) + } + for (var i = 0; i < n; ++i) { loadFile(files[i], i) } + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e) + // Ensure the editor is re-focused + setTimeout(function () { return cm.display.input.focus(); }, 20) + return + } + try { + var text$1 = e.dataTransfer.getData("Text") + if (text$1) { + var selected + if (cm.state.draggingText && !cm.state.draggingText.copy) + { selected = cm.listSelections() } + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)) + if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1) + { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag") } } + cm.replaceSelection(text$1, "around", "paste") + cm.display.input.focus() + } + } + catch(e){} + } +} + +function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return } + + e.dataTransfer.setData("Text", cm.getSelection()) + e.dataTransfer.effectAllowed = "copyMove" + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;") + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" + if (presto) { + img.width = img.height = 1 + cm.display.wrapper.appendChild(img) + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop + } + e.dataTransfer.setDragImage(img, 0, 0) + if (presto) { img.parentNode.removeChild(img) } + } +} + +function onDragOver(cm, e) { + var pos = posFromMouse(cm, e) + if (!pos) { return } + var frag = document.createDocumentFragment() + drawSelectionCursor(cm, pos, frag) + if (!cm.display.dragCursor) { + cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors") + cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv) + } + removeChildrenAndAdd(cm.display.dragCursor, frag) +} + +function clearDragCursor(cm) { + if (cm.display.dragCursor) { + cm.display.lineSpace.removeChild(cm.display.dragCursor) + cm.display.dragCursor = null + } +} + +// These must be handled carefully, because naively registering a +// handler for each editor will cause the editors to never be +// garbage collected. + +function forEachCodeMirror(f) { + if (!document.getElementsByClassName) { return } + var byClass = document.getElementsByClassName("CodeMirror") + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror + if (cm) { f(cm) } + } +} + +var globalsRegistered = false +function ensureGlobalHandlers() { + if (globalsRegistered) { return } + registerGlobalHandlers() + globalsRegistered = true +} +function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer + on(window, "resize", function () { + if (resizeTimer == null) { resizeTimer = setTimeout(function () { + resizeTimer = null + forEachCodeMirror(onResize) + }, 100) } + }) + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function () { return forEachCodeMirror(onBlur); }) +} +// Called when the window resizes +function onResize(cm) { + var d = cm.display + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + { return } + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null + d.scrollbarsClipped = false + cm.setSize() +} + +var keyNames = { + 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" +} + +// Number keys +for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i) } +// Alphabetic keys +for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1) } +// Function keys +for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2 } + +var keyMap = {} + +keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" +} +// Note that the save and find-related commands aren't defined by +// default. User code or addons can define them. Unknown commands +// are simply ignored. +keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" +} +// Very basic readline/emacs-style bindings, which are standard on Mac. +keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", + "Ctrl-O": "openLine" +} +keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] +} +keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault + +// KEYMAP DISPATCH + +function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/) + name = parts[parts.length - 1] + var alt, ctrl, shift, cmd + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i] + if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true } + else if (/^a(lt)?$/i.test(mod)) { alt = true } + else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true } + else if (/^s(hift)?$/i.test(mod)) { shift = true } + else { throw new Error("Unrecognized modifier name: " + mod) } + } + if (alt) { name = "Alt-" + name } + if (ctrl) { name = "Ctrl-" + name } + if (cmd) { name = "Cmd-" + name } + if (shift) { name = "Shift-" + name } + return name +} + +// This is a kludge to keep keymaps mostly working as raw objects +// (backwards compatibility) while at the same time support features +// like normalization and multi-stroke key bindings. It compiles a +// new normalized keymap, and then updates the old object to reflect +// this. +function normalizeKeyMap(keymap) { + var copy = {} + for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname] + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue } + if (value == "...") { delete keymap[keyname]; continue } + + var keys = map(keyname.split(" "), normalizeKeyName) + for (var i = 0; i < keys.length; i++) { + var val = (void 0), name = (void 0) + if (i == keys.length - 1) { + name = keys.join(" ") + val = value + } else { + name = keys.slice(0, i + 1).join(" ") + val = "..." + } + var prev = copy[name] + if (!prev) { copy[name] = val } + else if (prev != val) { throw new Error("Inconsistent bindings for " + name) } + } + delete keymap[keyname] + } } + for (var prop in copy) { keymap[prop] = copy[prop] } + return keymap +} + +function lookupKey(key, map, handle, context) { + map = getKeyMap(map) + var found = map.call ? map.call(key, context) : map[key] + if (found === false) { return "nothing" } + if (found === "...") { return "multi" } + if (found != null && handle(found)) { return "handled" } + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + { return lookupKey(key, map.fallthrough, handle, context) } + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context) + if (result) { return result } + } + } +} + +// Modifier key presses don't count as 'real' key presses for the +// purpose of keymap fallthrough. +function isModifierKey(value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode] + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod" +} + +function addModifierNames(name, event, noShift) { + var base = name + if (event.altKey && base != "Alt") { name = "Alt-" + name } + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name } + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name } + if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name } + return name +} + +// Look up the name of a key as indicated by an event object. +function keyName(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) { return false } + var name = keyNames[event.keyCode] + if (name == null || event.altGraphKey) { return false } + return addModifierNames(name, event, noShift) +} + +function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val +} + +// Helper for deleting text near the selection(s), used to implement +// backspace, delete, and similar functionality. +function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = [] + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]) + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop() + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from + break + } + } + kill.push(toKill) + } + // Next, remove those actual ranges. + runInOp(cm, function () { + for (var i = kill.length - 1; i >= 0; i--) + { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete") } + ensureCursorVisible(cm) + }) +} + +function moveCharLogically(line, ch, dir) { + var target = skipExtendingChars(line.text, ch + dir, dir) + return target < 0 || target > line.text.length ? null : target +} + +function moveLogically(line, start, dir) { + var ch = moveCharLogically(line, start.ch, dir) + return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") +} + +function endOfLine(visually, cm, lineObj, lineNo, dir) { + if (visually) { + var order = getOrder(lineObj, cm.doc.direction) + if (order) { + var part = dir < 0 ? lst(order) : order[0] + var moveInStorageOrder = (dir < 0) == (part.level == 1) + var sticky = moveInStorageOrder ? "after" : "before" + var ch + // With a wrapped rtl chunk (possibly spanning multiple bidi parts), + // it could be that the last bidi part is not on the last visual line, + // since visual lines contain content order-consecutive chunks. + // Thus, in rtl, we are looking for the first (content-order) character + // in the rtl chunk that is on the last line (that is, the same line + // as the last (content-order) character). + if (part.level > 0 || cm.doc.direction == "rtl") { + var prep = prepareMeasureForLine(cm, lineObj) + ch = dir < 0 ? lineObj.text.length - 1 : 0 + var targetTop = measureCharPrepared(cm, prep, ch).top + ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch) + if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1) } + } else { ch = dir < 0 ? part.to : part.from } + return new Pos(lineNo, ch, sticky) + } + } + return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") +} + +function moveVisually(cm, line, start, dir) { + var bidi = getOrder(line, cm.doc.direction) + if (!bidi) { return moveLogically(line, start, dir) } + if (start.ch >= line.text.length) { + start.ch = line.text.length + start.sticky = "before" + } else if (start.ch <= 0) { + start.ch = 0 + start.sticky = "after" + } + var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos] + if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { + // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, + // nothing interesting happens. + return moveLogically(line, start, dir) + } + + var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); } + var prep + var getWrappedLineExtent = function (ch) { + if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } + prep = prep || prepareMeasureForLine(cm, line) + return wrappedLineExtentChar(cm, line, prep, ch) + } + var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch) + + if (cm.doc.direction == "rtl" || part.level == 1) { + var moveInStorageOrder = (part.level == 1) == (dir < 0) + var ch = mv(start, moveInStorageOrder ? 1 : -1) + if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { + // Case 2: We move within an rtl part or in an rtl editor on the same visual line + var sticky = moveInStorageOrder ? "before" : "after" + return new Pos(start.line, ch, sticky) + } + } + + // Case 3: Could not move within this bidi part in this visual line, so leave + // the current bidi part + + var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { + var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder + ? new Pos(start.line, mv(ch, 1), "before") + : new Pos(start.line, ch, "after"); } + + for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { + var part = bidi[partPos] + var moveInStorageOrder = (dir > 0) == (part.level != 1) + var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1) + if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } + ch = moveInStorageOrder ? part.from : mv(part.to, -1) + if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } + } + } + + // Case 3a: Look for other bidi parts on the same visual line + var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent) + if (res) { return res } + + // Case 3b: Look for other bidi parts on the next visual line + var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1) + if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { + res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)) + if (res) { return res } + } + + // Case 4: Nowhere to move + return null +} + +// Commands are parameter-less actions that can be performed on an +// editor, mostly used for keybindings. +var commands = { + selectAll: selectAll, + singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); }, + killLine: function (cm) { return deleteNearSelection(cm, function (range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length + if (range.head.ch == len && range.head.line < cm.lastLine()) + { return {from: range.head, to: Pos(range.head.line + 1, 0)} } + else + { return {from: range.head, to: Pos(range.head.line, len)} } + } else { + return {from: range.from(), to: range.to()} + } + }); }, + deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({ + from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) + }); }); }, + delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({ + from: Pos(range.from().line, 0), to: range.from() + }); }); }, + delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5 + var leftPos = cm.coordsChar({left: 0, top: top}, "div") + return {from: leftPos, to: range.from()} + }); }, + delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5 + var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") + return {from: range.from(), to: rightPos } + }); }, + undo: function (cm) { return cm.undo(); }, + redo: function (cm) { return cm.redo(); }, + undoSelection: function (cm) { return cm.undoSelection(); }, + redoSelection: function (cm) { return cm.redoSelection(); }, + goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); }, + goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); }, + goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, + {origin: "+move", bias: 1} + ); }, + goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); }, + {origin: "+move", bias: 1} + ); }, + goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, + {origin: "+move", bias: -1} + ); }, + goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5 + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") + }, sel_move); }, + goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5 + return cm.coordsChar({left: 0, top: top}, "div") + }, sel_move); }, + goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5 + var pos = cm.coordsChar({left: 0, top: top}, "div") + if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) } + return pos + }, sel_move); }, + goLineUp: function (cm) { return cm.moveV(-1, "line"); }, + goLineDown: function (cm) { return cm.moveV(1, "line"); }, + goPageUp: function (cm) { return cm.moveV(-1, "page"); }, + goPageDown: function (cm) { return cm.moveV(1, "page"); }, + goCharLeft: function (cm) { return cm.moveH(-1, "char"); }, + goCharRight: function (cm) { return cm.moveH(1, "char"); }, + goColumnLeft: function (cm) { return cm.moveH(-1, "column"); }, + goColumnRight: function (cm) { return cm.moveH(1, "column"); }, + goWordLeft: function (cm) { return cm.moveH(-1, "word"); }, + goGroupRight: function (cm) { return cm.moveH(1, "group"); }, + goGroupLeft: function (cm) { return cm.moveH(-1, "group"); }, + goWordRight: function (cm) { return cm.moveH(1, "word"); }, + delCharBefore: function (cm) { return cm.deleteH(-1, "char"); }, + delCharAfter: function (cm) { return cm.deleteH(1, "char"); }, + delWordBefore: function (cm) { return cm.deleteH(-1, "word"); }, + delWordAfter: function (cm) { return cm.deleteH(1, "word"); }, + delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); }, + delGroupAfter: function (cm) { return cm.deleteH(1, "group"); }, + indentAuto: function (cm) { return cm.indentSelection("smart"); }, + indentMore: function (cm) { return cm.indentSelection("add"); }, + indentLess: function (cm) { return cm.indentSelection("subtract"); }, + insertTab: function (cm) { return cm.replaceSelection("\t"); }, + insertSoftTab: function (cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from() + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize) + spaces.push(spaceStr(tabSize - col % tabSize)) + } + cm.replaceSelections(spaces) + }, + defaultTab: function (cm) { + if (cm.somethingSelected()) { cm.indentSelection("add") } + else { cm.execCommand("insertTab") } + }, + // Swap the two chars left and right of each selection's head. + // Move cursor behind the two swapped characters afterwards. + // + // Doesn't consider line feeds a character. + // Doesn't scan more than one line above to find a character. + // Doesn't do anything on an empty line. + // Doesn't do anything with non-empty selections. + transposeChars: function (cm) { return runInOp(cm, function () { + var ranges = cm.listSelections(), newSel = [] + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) { continue } + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text + if (line) { + if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1) } + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1) + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose") + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text + if (prev) { + cur = new Pos(cur.line, 1) + cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), cur, "+transpose") + } + } + } + newSel.push(new Range(cur, cur)) + } + cm.setSelections(newSel) + }); }, + newlineAndIndent: function (cm) { return runInOp(cm, function () { + var sels = cm.listSelections() + for (var i = sels.length - 1; i >= 0; i--) + { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input") } + sels = cm.listSelections() + for (var i$1 = 0; i$1 < sels.length; i$1++) + { cm.indentLine(sels[i$1].from().line, null, true) } + ensureCursorVisible(cm) + }); }, + openLine: function (cm) { return cm.replaceSelection("\n", "start"); }, + toggleOverwrite: function (cm) { return cm.toggleOverwrite(); } +} + + +function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN) + var visual = visualLine(line) + if (visual != line) { lineN = lineNo(visual) } + return endOfLine(true, cm, visual, lineN, 1) +} +function lineEnd(cm, lineN) { + var line = getLine(cm.doc, lineN) + var visual = visualLineEnd(line) + if (visual != line) { lineN = lineNo(visual) } + return endOfLine(true, cm, line, lineN, -1) +} +function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line) + var line = getLine(cm.doc, start.line) + var order = getOrder(line, cm.doc.direction) + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)) + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch + return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky) + } + return start +} + +// Run a handler that was bound to a key. +function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound] + if (!bound) { return false } + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled() + var prevShift = cm.display.shift, done = false + try { + if (cm.isReadOnly()) { cm.state.suppressEdits = true } + if (dropShift) { cm.display.shift = false } + done = bound(cm) != Pass + } finally { + cm.display.shift = prevShift + cm.state.suppressEdits = false + } + return done +} + +function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm) + if (result) { return result } + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm) +} + +// Note that, despite the name, this function is also used to check +// for bound mouse clicks. + +var stopSeq = new Delayed + +function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq + if (seq) { + if (isModifierKey(name)) { return "handled" } + if (/\'$/.test(name)) + { cm.state.keySeq = null } + else + { stopSeq.set(50, function () { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null + cm.display.input.reset() + } + }) } + if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true } + } + return dispatchKeyInner(cm, name, e, handle) +} + +function dispatchKeyInner(cm, name, e, handle) { + var result = lookupKeyForEditor(cm, name, handle) + + if (result == "multi") + { cm.state.keySeq = name } + if (result == "handled") + { signalLater(cm, "keyHandled", cm, name, e) } + + if (result == "handled" || result == "multi") { + e_preventDefault(e) + restartBlink(cm) + } + + return !!result +} + +// Handle a key from the keydown event. +function handleKeyBinding(cm, e) { + var name = keyName(e, true) + if (!name) { return false } + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) + || dispatchKey(cm, name, e, function (b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + { return doHandleBinding(cm, b) } + }) + } else { + return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }) + } +} + +// Handle a key from the keypress event +function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); }) +} + +var lastStoppedKey = null +function onKeyDown(e) { + var cm = this + cm.curOp.focus = activeElt() + if (signalDOMEvent(cm, e)) { return } + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false } + var code = e.keyCode + cm.display.shift = code == 16 || e.shiftKey + var handled = handleKeyBinding(cm, e) + if (presto) { + lastStoppedKey = handled ? code : null + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + { cm.replaceSelection("", null, "cut") } + } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + { showCrossHair(cm) } +} + +function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv + addClass(lineDiv, "CodeMirror-crosshair") + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair") + off(document, "keyup", up) + off(document, "mouseover", up) + } + } + on(document, "keyup", up) + on(document, "mouseover", up) +} + +function onKeyUp(e) { + if (e.keyCode == 16) { this.doc.sel.shift = false } + signalDOMEvent(this, e) +} + +function onKeyPress(e) { + var cm = this + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return } + var keyCode = e.keyCode, charCode = e.charCode + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return } + var ch = String.fromCharCode(charCode == null ? keyCode : charCode) + // Some browsers fire keypress events for backspace + if (ch == "\x08") { return } + if (handleCharBinding(cm, e, ch)) { return } + cm.display.input.onKeyPress(e) +} + +var DOUBLECLICK_DELAY = 400 + +var PastClick = function(time, pos, button) { + this.time = time + this.pos = pos + this.button = button +}; + +PastClick.prototype.compare = function (time, pos, button) { + return this.time + DOUBLECLICK_DELAY > time && + cmp(pos, this.pos) == 0 && button == this.button +}; + +var lastClick; +var lastDoubleClick; +function clickRepeat(pos, button) { + var now = +new Date + if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) { + lastClick = lastDoubleClick = null + return "triple" + } else if (lastClick && lastClick.compare(now, pos, button)) { + lastDoubleClick = new PastClick(now, pos, button) + lastClick = null + return "double" + } else { + lastClick = new PastClick(now, pos, button) + lastDoubleClick = null + return "single" + } +} + +// A mouse down can be a single click, double click, triple click, +// start of selection drag, start of text drag, new cursor +// (ctrl-click), rectangle drag (alt-drag), or xwin +// middle-click-paste. Or it might be a click on something we should +// not interfere with, such as a scrollbar or widget. +function onMouseDown(e) { + var cm = this, display = cm.display + if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return } + display.input.ensurePolled() + display.shift = e.shiftKey + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false + setTimeout(function () { return display.scroller.draggable = true; }, 100) + } + return + } + if (clickInGutter(cm, e)) { return } + var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single" + window.focus() + + // #3261: make sure, that we're not starting a second selection + if (button == 1 && cm.state.selectingText) + { cm.state.selectingText(e) } + + if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return } + + if (button == 1) { + if (pos) { leftButtonDown(cm, pos, repeat, e) } + else if (e_target(e) == display.scroller) { e_preventDefault(e) } + } else if (button == 2) { + if (pos) { extendSelection(cm.doc, pos) } + setTimeout(function () { return display.input.focus(); }, 20) + } else if (button == 3) { + if (captureRightClick) { onContextMenu(cm, e) } + else { delayBlurEvent(cm) } + } +} + +function handleMappedButton(cm, button, pos, repeat, event) { + var name = "Click" + if (repeat == "double") { name = "Double" + name } + else if (repeat == "triple") { name = "Triple" + name } + name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name + + return dispatchKey(cm, addModifierNames(name, event), event, function (bound) { + if (typeof bound == "string") { bound = commands[bound] } + if (!bound) { return false } + var done = false + try { + if (cm.isReadOnly()) { cm.state.suppressEdits = true } + done = bound(cm, pos) != Pass + } finally { + cm.state.suppressEdits = false + } + return done + }) +} + +function configureMouse(cm, repeat, event) { + var option = cm.getOption("configureMouse") + var value = option ? option(cm, repeat, event) : {} + if (value.unit == null) { + var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey + value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line" + } + if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey } + if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey } + if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey) } + return value +} + +function leftButtonDown(cm, pos, repeat, event) { + if (ie) { setTimeout(bind(ensureFocus, cm), 0) } + else { cm.curOp.focus = activeElt() } + + var behavior = configureMouse(cm, repeat, event) + + var sel = cm.doc.sel, contained + if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && + repeat == "single" && (contained = sel.contains(pos)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) && + (cmp(contained.to(), pos) > 0 || pos.xRel < 0)) + { leftButtonStartDrag(cm, event, pos, behavior) } + else + { leftButtonSelect(cm, event, pos, behavior) } +} + +// Start a text drag. When it ends, see if any dragging actually +// happen, and treat as a click if it didn't. +function leftButtonStartDrag(cm, event, pos, behavior) { + var display = cm.display, moved = false + var dragEnd = operation(cm, function (e) { + if (webkit) { display.scroller.draggable = false } + cm.state.draggingText = false + off(document, "mouseup", dragEnd) + off(document, "mousemove", mouseMove) + off(display.scroller, "dragstart", dragStart) + off(display.scroller, "drop", dragEnd) + if (!moved) { + e_preventDefault(e) + if (!behavior.addNew) + { extendSelection(cm.doc, pos, null, null, behavior.extend) } + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + { setTimeout(function () {document.body.focus(); display.input.focus()}, 20) } + else + { display.input.focus() } + } + }) + var mouseMove = function(e2) { + moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10 + } + var dragStart = function () { return moved = true; } + // Let the drag handler handle this. + if (webkit) { display.scroller.draggable = true } + cm.state.draggingText = dragEnd + dragEnd.copy = !behavior.moveOnDrag + // IE's approach to draggable + if (display.scroller.dragDrop) { display.scroller.dragDrop() } + on(document, "mouseup", dragEnd) + on(document, "mousemove", mouseMove) + on(display.scroller, "dragstart", dragStart) + on(display.scroller, "drop", dragEnd) + + delayBlurEvent(cm) + setTimeout(function () { return display.input.focus(); }, 20) +} + +function rangeForUnit(cm, pos, unit) { + if (unit == "char") { return new Range(pos, pos) } + if (unit == "word") { return cm.findWordAt(pos) } + if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } + var result = unit(cm, pos) + return new Range(result.from, result.to) +} + +// Normal selection, as opposed to text dragging. +function leftButtonSelect(cm, event, start, behavior) { + var display = cm.display, doc = cm.doc + e_preventDefault(event) + + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges + if (behavior.addNew && !behavior.extend) { + ourIndex = doc.sel.contains(start) + if (ourIndex > -1) + { ourRange = ranges[ourIndex] } + else + { ourRange = new Range(start, start) } + } else { + ourRange = doc.sel.primary() + ourIndex = doc.sel.primIndex + } + + if (behavior.unit == "rectangle") { + if (!behavior.addNew) { ourRange = new Range(start, start) } + start = posFromMouse(cm, event, true, true) + ourIndex = -1 + } else { + var range = rangeForUnit(cm, start, behavior.unit) + if (behavior.extend) + { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend) } + else + { ourRange = range } + } + + if (!behavior.addNew) { + ourIndex = 0 + setSelection(doc, new Selection([ourRange], 0), sel_mouse) + startSel = doc.sel + } else if (ourIndex == -1) { + ourIndex = ranges.length + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}) + } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), + {scroll: false, origin: "*mouse"}) + startSel = doc.sel + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse) + } + + var lastPos = start + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) { return } + lastPos = pos + + if (behavior.unit == "rectangle") { + var ranges = [], tabSize = cm.options.tabSize + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize) + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize) + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol) + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize) + if (left == right) + { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))) } + else if (text.length > leftPos) + { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))) } + } + if (!ranges.length) { ranges.push(new Range(start, start)) } + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}) + cm.scrollIntoView(pos) + } else { + var oldRange = ourRange + var range = rangeForUnit(cm, pos, behavior.unit) + var anchor = oldRange.anchor, head + if (cmp(range.anchor, anchor) > 0) { + head = range.head + anchor = minPos(oldRange.from(), range.anchor) + } else { + head = range.anchor + anchor = maxPos(oldRange.to(), range.head) + } + var ranges$1 = startSel.ranges.slice(0) + ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)) + setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse) + } + } + + var editorSize = display.wrapper.getBoundingClientRect() + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0 + + function extend(e) { + var curCount = ++counter + var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle") + if (!cur) { return } + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt() + extendTo(cur) + var visible = visibleLines(display, doc) + if (cur.line >= visible.to || cur.line < visible.from) + { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e) }}), 150) } + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0 + if (outside) { setTimeout(operation(cm, function () { + if (counter != curCount) { return } + display.scroller.scrollTop += outside + extend(e) + }), 50) } + } + } + + function done(e) { + cm.state.selectingText = false + counter = Infinity + e_preventDefault(e) + display.input.focus() + off(document, "mousemove", move) + off(document, "mouseup", up) + doc.history.lastSelOrigin = null + } + + var move = operation(cm, function (e) { + if (!e_button(e)) { done(e) } + else { extend(e) } + }) + var up = operation(cm, done) + cm.state.selectingText = up + on(document, "mousemove", move) + on(document, "mouseup", up) +} + +// Used when mouse-selecting to adjust the anchor to the proper side +// of a bidi jump depending on the visual position of the head. +function bidiSimplify(cm, range) { + var anchor = range.anchor; + var head = range.head; + var anchorLine = getLine(cm.doc, anchor.line) + if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range } + var order = getOrder(anchorLine) + if (!order) { return range } + var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index] + if (part.from != anchor.ch && part.to != anchor.ch) { return range } + var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1) + if (boundary == 0 || boundary == order.length) { return range } + + // Compute the relative visual position of the head compared to the + // anchor (<0 is to the left, >0 to the right) + var leftSide + if (head.line != anchor.line) { + leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0 + } else { + var headIndex = getBidiPartAt(order, head.ch, head.sticky) + var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1) + if (headIndex == boundary - 1 || headIndex == boundary) + { leftSide = dir < 0 } + else + { leftSide = dir > 0 } + } + + var usePart = order[boundary + (leftSide ? -1 : 0)] + var from = leftSide == (usePart.level == 1) + var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before" + return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head) +} + + +// Determines whether an event happened in the gutter, and fires the +// handlers for the corresponding event. +function gutterEvent(cm, e, type, prevent) { + var mX, mY + if (e.touches) { + mX = e.touches[0].clientX + mY = e.touches[0].clientY + } else { + try { mX = e.clientX; mY = e.clientY } + catch(e) { return false } + } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false } + if (prevent) { e_preventDefault(e) } + + var display = cm.display + var lineBox = display.lineDiv.getBoundingClientRect() + + if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) } + mY -= lineBox.top - display.viewOffset + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i] + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY) + var gutter = cm.options.gutters[i] + signal(cm, type, cm, line, gutter, e) + return e_defaultPrevented(e) + } + } +} + +function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true) +} + +// CONTEXT MENU HANDLING + +// To make the context menu work, we need to briefly unhide the +// textarea (making it as unobtrusive as possible) to let the +// right-click take effect on it. +function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return } + if (signalDOMEvent(cm, e, "contextmenu")) { return } + cm.display.input.onContextMenu(e) +} + +function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) { return false } + return gutterEvent(cm, e, "gutterContextMenu", false) +} + +function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-") + clearCaches(cm) +} + +var Init = {toString: function(){return "CodeMirror.Init"}} + +var defaults = {} +var optionHandlers = {} + +function defineOptions(CodeMirror) { + var optionHandlers = CodeMirror.optionHandlers + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt + if (handle) { optionHandlers[name] = + notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old) }} : handle } + } + + CodeMirror.defineOption = option + + // Passed to option handlers when there is no old value. + CodeMirror.Init = Init + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function (cm, val) { return cm.setValue(val); }, true) + option("mode", null, function (cm, val) { + cm.doc.modeOption = val + loadMode(cm) + }, true) + + option("indentUnit", 2, loadMode, true) + option("indentWithTabs", false) + option("smartIndent", true) + option("tabSize", 4, function (cm) { + resetModeState(cm) + clearCaches(cm) + regChange(cm) + }, true) + option("lineSeparator", null, function (cm, val) { + cm.doc.lineSep = val + if (!val) { return } + var newBreaks = [], lineNo = cm.doc.first + cm.doc.iter(function (line) { + for (var pos = 0;;) { + var found = line.text.indexOf(val, pos) + if (found == -1) { break } + pos = found + val.length + newBreaks.push(Pos(lineNo, found)) + } + lineNo++ + }) + for (var i = newBreaks.length - 1; i >= 0; i--) + { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) } + }) + option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g") + if (old != Init) { cm.refresh() } + }) + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true) + option("electricChars", true) + option("inputStyle", mobile ? "contenteditable" : "textarea", function () { + throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME + }, true) + option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true) + option("rtlMoveVisually", !windows) + option("wholeLineUpdateBefore", true) + + option("theme", "default", function (cm) { + themeChanged(cm) + guttersChanged(cm) + }, true) + option("keyMap", "default", function (cm, val, old) { + var next = getKeyMap(val) + var prev = old != Init && getKeyMap(old) + if (prev && prev.detach) { prev.detach(cm, next) } + if (next.attach) { next.attach(cm, prev || null) } + }) + option("extraKeys", null) + option("configureMouse", null) + + option("lineWrapping", false, wrappingChanged, true) + option("gutters", [], function (cm) { + setGuttersForLineNumbers(cm.options) + guttersChanged(cm) + }, true) + option("fixedGutter", true, function (cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0" + cm.refresh() + }, true) + option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true) + option("scrollbarStyle", "native", function (cm) { + initScrollbars(cm) + updateScrollbars(cm) + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop) + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft) + }, true) + option("lineNumbers", false, function (cm) { + setGuttersForLineNumbers(cm.options) + guttersChanged(cm) + }, true) + option("firstLineNumber", 1, guttersChanged, true) + option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true) + option("showCursorWhenSelecting", false, updateSelection, true) + + option("resetSelectionOnContextMenu", true) + option("lineWiseCopyCut", true) + option("pasteLinesPerSelection", true) + + option("readOnly", false, function (cm, val) { + if (val == "nocursor") { + onBlur(cm) + cm.display.input.blur() + } + cm.display.input.readOnlyChanged(val) + }) + option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset() }}, true) + option("dragDrop", true, dragDropChanged) + option("allowDropFileTypes", null) + + option("cursorBlinkRate", 530) + option("cursorScrollMargin", 0) + option("cursorHeight", 1, updateSelection, true) + option("singleCursorHeightPerLine", true, updateSelection, true) + option("workTime", 100) + option("workDelay", 100) + option("flattenSpans", true, resetModeState, true) + option("addModeClass", false, resetModeState, true) + option("pollInterval", 100) + option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; }) + option("historyEventDelay", 1250) + option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true) + option("maxHighlightLength", 10000, resetModeState, true) + option("moveInputWithCursor", true, function (cm, val) { + if (!val) { cm.display.input.resetPosition() } + }) + + option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; }) + option("autofocus", null) + option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true) +} + +function guttersChanged(cm) { + updateGutters(cm) + regChange(cm) + alignHorizontally(cm) +} + +function dragDropChanged(cm, value, old) { + var wasOn = old && old != Init + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions + var toggle = value ? on : off + toggle(cm.display.scroller, "dragstart", funcs.start) + toggle(cm.display.scroller, "dragenter", funcs.enter) + toggle(cm.display.scroller, "dragover", funcs.over) + toggle(cm.display.scroller, "dragleave", funcs.leave) + toggle(cm.display.scroller, "drop", funcs.drop) + } +} + +function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap") + cm.display.sizer.style.minWidth = "" + cm.display.sizerWidth = null + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap") + findMaxLine(cm) + } + estimateLineHeights(cm) + regChange(cm) + clearCaches(cm) + setTimeout(function () { return updateScrollbars(cm); }, 100) +} + +// A CodeMirror instance represents an editor. This is the object +// that user code is usually dealing with. + +function CodeMirror(place, options) { + var this$1 = this; + + if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) } + + this.options = options = options ? copyObj(options) : {} + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false) + setGuttersForLineNumbers(options) + + var doc = options.value + if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) } + this.doc = doc + + var input = new CodeMirror.inputStyles[options.inputStyle](this) + var display = this.display = new Display(place, doc, input) + display.wrapper.CodeMirror = this + updateGutters(this) + themeChanged(this) + if (options.lineWrapping) + { this.display.wrapper.className += " CodeMirror-wrap" } + initScrollbars(this) + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + selectingText: false, + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + } + + if (options.autofocus && !mobile) { display.input.focus() } + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20) } + + registerEventHandlers(this) + ensureGlobalHandlers() + + startOperation(this) + this.curOp.forceUpdate = true + attachDoc(this, doc) + + if ((options.autofocus && !mobile) || this.hasFocus()) + { setTimeout(bind(onFocus, this), 20) } + else + { onBlur(this) } + + for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt)) + { optionHandlers[opt](this$1, options[opt], Init) } } + maybeUpdateLineNumberWidth(this) + if (options.finishInit) { options.finishInit(this) } + for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1) } + endOperation(this) + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + { display.lineDiv.style.textRendering = "auto" } +} + +// The default configuration options. +CodeMirror.defaults = defaults +// Functions to run when options are changed. +CodeMirror.optionHandlers = optionHandlers + +// Attach the necessary event handlers when initializing the editor +function registerEventHandlers(cm) { + var d = cm.display + on(d.scroller, "mousedown", operation(cm, onMouseDown)) + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + { on(d.scroller, "dblclick", operation(cm, function (e) { + if (signalDOMEvent(cm, e)) { return } + var pos = posFromMouse(cm, e) + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return } + e_preventDefault(e) + var word = cm.findWordAt(pos) + extendSelection(cm.doc, word.anchor, word.head) + })) } + else + { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }) } + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }) } + + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = {end: 0} + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000) + prevTouch = d.activeTouch + prevTouch.end = +new Date + } + } + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) { return false } + var touch = e.touches[0] + return touch.radiusX <= 1 && touch.radiusY <= 1 + } + function farAway(touch, other) { + if (other.left == null) { return true } + var dx = other.left - touch.left, dy = other.top - touch.top + return dx * dx + dy * dy > 20 * 20 + } + on(d.scroller, "touchstart", function (e) { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) { + d.input.ensurePolled() + clearTimeout(touchFinished) + var now = +new Date + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null} + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX + d.activeTouch.top = e.touches[0].pageY + } + } + }) + on(d.scroller, "touchmove", function () { + if (d.activeTouch) { d.activeTouch.moved = true } + }) + on(d.scroller, "touchend", function (e) { + var touch = d.activeTouch + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + { range = new Range(pos, pos) } + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + { range = cm.findWordAt(pos) } + else // Triple tap + { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } + cm.setSelection(range.anchor, range.head) + cm.focus() + e_preventDefault(e) + } + finishTouch() + }) + on(d.scroller, "touchcancel", finishTouch) + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function () { + if (d.scroller.clientHeight) { + updateScrollTop(cm, d.scroller.scrollTop) + setScrollLeft(cm, d.scroller.scrollLeft, true) + signal(cm, "scroll", cm) + } + }) + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); }) + on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); }) + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }) + + d.dragFunctions = { + enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e) }}, + over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e) }}, + start: function (e) { return onDragStart(cm, e); }, + drop: operation(cm, onDrop), + leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm) }} + } + + var inp = d.input.getField() + on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); }) + on(inp, "keydown", operation(cm, onKeyDown)) + on(inp, "keypress", operation(cm, onKeyPress)) + on(inp, "focus", function (e) { return onFocus(cm, e); }) + on(inp, "blur", function (e) { return onBlur(cm, e); }) +} + +var initHooks = [] +CodeMirror.defineInitHook = function (f) { return initHooks.push(f); } + +// Indent the given line. The how parameter can be "smart", +// "add"/null, "subtract", or "prev". When aggressive is false +// (typically set to true for forced single-line indents), empty +// lines are not indented, and places where the mode returns Pass +// are left alone. +function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state + if (how == null) { how = "add" } + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) { how = "prev" } + else { state = getContextBefore(cm, n).state } + } + + var tabSize = cm.options.tabSize + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize) + if (line.stateAfter) { line.stateAfter = null } + var curSpaceString = line.text.match(/^\s*/)[0], indentation + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0 + how = "not" + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text) + if (indentation == Pass || indentation > 150) { + if (!aggressive) { return } + how = "prev" + } + } + if (how == "prev") { + if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize) } + else { indentation = 0 } + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit + } else if (typeof how == "number") { + indentation = curSpace + how + } + indentation = Math.max(0, indentation) + + var indentString = "", pos = 0 + if (cm.options.indentWithTabs) + { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t"} } + if (pos < indentation) { indentString += spaceStr(indentation - pos) } + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input") + line.stateAfter = null + return true + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) { + var range = doc.sel.ranges[i$1] + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos$1 = Pos(n, curSpaceString.length) + replaceOneSelection(doc, i$1, new Range(pos$1, pos$1)) + break + } + } + } +} + +// This will be set to a {lineWise: bool, text: [string]} object, so +// that, when pasting, we know what kind of selections the copied +// text was made out of. +var lastCopied = null + +function setLastCopied(newLastCopied) { + lastCopied = newLastCopied +} + +function applyTextInput(cm, inserted, deleted, sel, origin) { + var doc = cm.doc + cm.display.shift = false + if (!sel) { sel = doc.sel } + + var paste = cm.state.pasteIncoming || origin == "paste" + var textLines = splitLinesAuto(inserted), multiPaste = null + // When pasing N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.text.join("\n") == inserted) { + if (sel.ranges.length % lastCopied.text.length == 0) { + multiPaste = [] + for (var i = 0; i < lastCopied.text.length; i++) + { multiPaste.push(doc.splitLines(lastCopied.text[i])) } + } + } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) { + multiPaste = map(textLines, function (l) { return [l]; }) + } + } + + var updateInput + // Normal behavior is to insert the new text into every selection + for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) { + var range = sel.ranges[i$1] + var from = range.from(), to = range.to() + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + { from = Pos(from.line, from.ch - deleted) } + else if (cm.state.overwrite && !paste) // Handle overwrite + { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) } + else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted) + { from = to = Pos(from.line, 0) } + } + updateInput = cm.curOp.updateInput + var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")} + makeChange(cm.doc, changeEvent) + signalLater(cm, "inputRead", cm, changeEvent) + } + if (inserted && !paste) + { triggerElectric(cm, inserted) } + + ensureCursorVisible(cm) + cm.curOp.updateInput = updateInput + cm.curOp.typing = true + cm.state.pasteIncoming = cm.state.cutIncoming = false +} + +function handlePaste(e, cm) { + var pasted = e.clipboardData && e.clipboardData.getData("Text") + if (pasted) { + e.preventDefault() + if (!cm.isReadOnly() && !cm.options.disableInput) + { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }) } + return true + } +} + +function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) { return } + var sel = cm.doc.sel + + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i] + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue } + var mode = cm.getModeAt(range.head) + var indented = false + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart") + break + } } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + { indented = indentLine(cm, range.head.line, "smart") } + } + if (indented) { signalLater(cm, "electricInput", cm, range.head.line) } + } +} + +function copyableRanges(cm) { + var text = [], ranges = [] + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line + var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)} + ranges.push(lineRange) + text.push(cm.getRange(lineRange.anchor, lineRange.head)) + } + return {text: text, ranges: ranges} +} + +function disableBrowserMagic(field, spellcheck) { + field.setAttribute("autocorrect", "off") + field.setAttribute("autocapitalize", "off") + field.setAttribute("spellcheck", !!spellcheck) +} + +function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none") + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;") + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) { te.style.width = "1000px" } + else { te.setAttribute("wrap", "off") } + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) { te.style.border = "1px solid black" } + disableBrowserMagic(te) + return div +} + +// The publicly visible API. Note that methodOp(f) means +// 'wrap f in an operation, performed on its `this` parameter'. + +// This is not the complete set of editor methods. Most of the +// methods defined on the Doc type are also injected into +// CodeMirror.prototype, for backwards compatibility and +// convenience. + +function addEditorMethods(CodeMirror) { + var optionHandlers = CodeMirror.optionHandlers + + var helpers = CodeMirror.helpers = {} + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus()}, + + setOption: function(option, value) { + var options = this.options, old = options[option] + if (options[option] == value && option != "mode") { return } + options[option] = value + if (optionHandlers.hasOwnProperty(option)) + { operation(this, optionHandlers[option])(this, value, old) } + signal(this, "optionChange", this, option) + }, + + getOption: function(option) {return this.options[option]}, + getDoc: function() {return this.doc}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)) + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps + for (var i = 0; i < maps.length; ++i) + { if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1) + return true + } } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec) + if (mode.startState) { throw new Error("Overlays may not be stateful.") } + insertSorted(this.state.overlays, + {mode: mode, modeSpec: spec, opaque: options && options.opaque, + priority: (options && options.priority) || 0}, + function (overlay) { return overlay.priority; }) + this.state.modeGen++ + regChange(this) + }), + removeOverlay: methodOp(function(spec) { + var this$1 = this; + + var overlays = this.state.overlays + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1) + this$1.state.modeGen++ + regChange(this$1) + return + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev" } + else { dir = dir ? "add" : "subtract" } + } + if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive) } + }), + indentSelection: methodOp(function(how) { + var this$1 = this; + + var ranges = this.doc.sel.ranges, end = -1 + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i] + if (!range.empty()) { + var from = range.from(), to = range.to() + var start = Math.max(end, from.line) + end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1 + for (var j = start; j < end; ++j) + { indentLine(this$1, j, how) } + var newRanges = this$1.doc.sel.ranges + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll) } + } else if (range.head.line > end) { + indentLine(this$1, range.head.line, how, true) + end = range.head.line + if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1) } + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise) + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true) + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos) + var styles = getLineStyles(this, getLine(this.doc, pos.line)) + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch + var type + if (ch == 0) { type = styles[2] } + else { for (;;) { + var mid = (before + after) >> 1 + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid } + else if (styles[mid * 2 + 1] < ch) { before = mid + 1 } + else { type = styles[mid * 2 + 2]; break } + } } + var cut = type ? type.indexOf("overlay ") : -1 + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1) + }, + + getModeAt: function(pos) { + var mode = this.doc.mode + if (!mode.innerMode) { return mode } + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0] + }, + + getHelpers: function(pos, type) { + var this$1 = this; + + var found = [] + if (!helpers.hasOwnProperty(type)) { return found } + var help = helpers[type], mode = this.getModeAt(pos) + if (typeof mode[type] == "string") { + if (help[mode[type]]) { found.push(help[mode[type]]) } + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]] + if (val) { found.push(val) } + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]) + } else if (help[mode.name]) { + found.push(help[mode.name]) + } + for (var i$1 = 0; i$1 < help._global.length; i$1++) { + var cur = help._global[i$1] + if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1) + { found.push(cur.val) } + } + return found + }, + + getStateAfter: function(line, precise) { + var doc = this.doc + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line) + return getContextBefore(this, line + 1, precise).state + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary() + if (start == null) { pos = range.head } + else if (typeof start == "object") { pos = clipPos(this.doc, start) } + else { pos = start ? range.from() : range.to() } + return cursorCoords(this, pos, mode || "page") + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page") + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page") + return coordsChar(this, coords.left, coords.top) + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top + return lineAtHeight(this.doc, height + this.display.viewOffset) + }, + heightAtLine: function(line, mode, includeWidgets) { + var end = false, lineObj + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1 + if (line < this.doc.first) { line = this.doc.first } + else if (line > last) { line = last; end = true } + lineObj = getLine(this.doc, line) + } else { + lineObj = line + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top + + (end ? this.doc.height - heightAtLine(lineObj) : 0) + }, + + defaultTextHeight: function() { return textHeight(this.display) }, + defaultCharWidth: function() { return charWidth(this.display) }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display + pos = cursorCoords(this, clipPos(this.doc, pos)) + var top = pos.bottom, left = pos.left + node.style.position = "absolute" + node.setAttribute("cm-ignore-events", "true") + this.display.input.setUneditable(node) + display.sizer.appendChild(node) + if (vert == "over") { + top = pos.top + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth) + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + { top = pos.top - node.offsetHeight } + else if (pos.bottom + node.offsetHeight <= vspace) + { top = pos.bottom } + if (left + node.offsetWidth > hspace) + { left = hspace - node.offsetWidth } + } + node.style.top = top + "px" + node.style.left = node.style.right = "" + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth + node.style.right = "0px" + } else { + if (horiz == "left") { left = 0 } + else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2 } + node.style.left = left + "px" + } + if (scroll) + { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}) } + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + triggerOnMouseDown: methodOp(onMouseDown), + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + { return commands[cmd].call(null, this) } + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text) }), + + findPosH: function(from, amount, unit, visually) { + var this$1 = this; + + var dir = 1 + if (amount < 0) { dir = -1; amount = -amount } + var cur = clipPos(this.doc, from) + for (var i = 0; i < amount; ++i) { + cur = findPosH(this$1.doc, cur, dir, unit, visually) + if (cur.hitSide) { break } + } + return cur + }, + + moveH: methodOp(function(dir, unit) { + var this$1 = this; + + this.extendSelectionsBy(function (range) { + if (this$1.display.shift || this$1.doc.extend || range.empty()) + { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) } + else + { return dir < 0 ? range.from() : range.to() } + }, sel_move) + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc + if (sel.somethingSelected()) + { doc.replaceSelection("", null, "+delete") } + else + { deleteNearSelection(this, function (range) { + var other = findPosH(doc, range.head, dir, unit, false) + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other} + }) } + }), + + findPosV: function(from, amount, unit, goalColumn) { + var this$1 = this; + + var dir = 1, x = goalColumn + if (amount < 0) { dir = -1; amount = -amount } + var cur = clipPos(this.doc, from) + for (var i = 0; i < amount; ++i) { + var coords = cursorCoords(this$1, cur, "div") + if (x == null) { x = coords.left } + else { coords.left = x } + cur = findPosV(this$1, coords, dir, unit) + if (cur.hitSide) { break } + } + return cur + }, + + moveV: methodOp(function(dir, unit) { + var this$1 = this; + + var doc = this.doc, goals = [] + var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected() + doc.extendSelectionsBy(function (range) { + if (collapse) + { return dir < 0 ? range.from() : range.to() } + var headPos = cursorCoords(this$1, range.head, "div") + if (range.goalColumn != null) { headPos.left = range.goalColumn } + goals.push(headPos.left) + var pos = findPosV(this$1, headPos, dir, unit) + if (unit == "page" && range == doc.sel.primary()) + { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top) } + return pos + }, sel_move) + if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++) + { doc.sel.ranges[i].goalColumn = goals[i] } } + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text + var start = pos.ch, end = pos.ch + if (line) { + var helper = this.getHelper(pos, "wordChars") + if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end } + var startChar = line.charAt(start) + var check = isWordChar(startChar, helper) + ? function (ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); } + : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); } + while (start > 0 && check(line.charAt(start - 1))) { --start } + while (end < line.length && check(line.charAt(end))) { ++end } + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)) + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) { return } + if (this.state.overwrite = !this.state.overwrite) + { addClass(this.display.cursorDiv, "CodeMirror-overwrite") } + else + { rmClass(this.display.cursorDiv, "CodeMirror-overwrite") } + + signal(this, "overwriteToggle", this, this.state.overwrite) + }, + hasFocus: function() { return this.display.input.getField() == activeElt() }, + isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) }, + + scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }), + getScrollInfo: function() { + var scroller = this.display.scroller + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)} + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null} + if (margin == null) { margin = this.options.cursorScrollMargin } + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null} + } else if (range.from == null) { + range = {from: range, to: null} + } + if (!range.to) { range.to = range.from } + range.margin = margin || 0 + + if (range.from.line != null) { + scrollToRange(this, range) + } else { + scrollToCoordsRange(this, range.from, range.to, range.margin) + } + }), + + setSize: methodOp(function(width, height) { + var this$1 = this; + + var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; } + if (width != null) { this.display.wrapper.style.width = interpret(width) } + if (height != null) { this.display.wrapper.style.height = interpret(height) } + if (this.options.lineWrapping) { clearLineMeasurementCache(this) } + var lineNo = this.display.viewFrom + this.doc.iter(lineNo, this.display.viewTo, function (line) { + if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) + { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, "widget"); break } } } + ++lineNo + }) + this.curOp.forceUpdate = true + signal(this, "refresh", this) + }), + + operation: function(f){return runInOp(this, f)}, + startOperation: function(){return startOperation(this)}, + endOperation: function(){return endOperation(this)}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight + regChange(this) + this.curOp.forceUpdate = true + clearCaches(this) + scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop) + updateGutterSpace(this) + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + { estimateLineHeights(this) } + signal(this, "refresh", this) + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc + old.cm = null + attachDoc(this, doc) + clearCaches(this) + this.display.input.reset() + scrollToCoords(this, doc.scrollLeft, doc.scrollTop) + this.curOp.forceScroll = true + signalLater(this, "swapDoc", this, old) + return old + }), + + getInputField: function(){return this.display.input.getField()}, + getWrapperElement: function(){return this.display.wrapper}, + getScrollerElement: function(){return this.display.scroller}, + getGutterElement: function(){return this.display.gutters} + } + eventMixin(CodeMirror) + + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []} } + helpers[type][name] = value + } + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value) + helpers[type]._global.push({pred: predicate, val: value}) + } +} + +// Used for horizontal relative motion. Dir is -1 or 1 (left or +// right), unit can be "char", "column" (like char, but doesn't +// cross line boundaries), "word" (across next word), or "group" (to +// the start of next group of word or non-word-non-whitespace +// chars). The visually param controls whether, in right-to-left +// text, direction 1 means to move towards the next index in the +// string, or towards the character to the right of the current +// position. The resulting position will have a hitSide=true +// property if it reached the end of the document. +function findPosH(doc, pos, dir, unit, visually) { + var oldPos = pos + var origDir = dir + var lineObj = getLine(doc, pos.line) + function findNextLine() { + var l = pos.line + dir + if (l < doc.first || l >= doc.first + doc.size) { return false } + pos = new Pos(l, pos.ch, pos.sticky) + return lineObj = getLine(doc, l) + } + function moveOnce(boundToLine) { + var next + if (visually) { + next = moveVisually(doc.cm, lineObj, pos, dir) + } else { + next = moveLogically(lineObj, pos, dir) + } + if (next == null) { + if (!boundToLine && findNextLine()) + { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir) } + else + { return false } + } else { + pos = next + } + return true + } + + if (unit == "char") { + moveOnce() + } else if (unit == "column") { + moveOnce(true) + } else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group" + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars") + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) { break } + var cur = lineObj.text.charAt(pos.ch) || "\n" + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p" + if (group && !first && !type) { type = "s" } + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after"} + break + } + + if (type) { sawType = type } + if (dir > 0 && !moveOnce(!first)) { break } + } + } + var result = skipAtomic(doc, pos, oldPos, origDir, true) + if (equalCursorPos(oldPos, result)) { result.hitSide = true } + return result +} + +// For relative vertical movement. Dir may be -1 or 1. Unit can be +// "page" or "line". The resulting position will have a hitSide=true +// property if it reached the end of the document. +function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight) + var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3) + y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount + + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3 + } + var target + for (;;) { + target = coordsChar(cm, x, y) + if (!target.outside) { break } + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break } + y += dir * 5 + } + return target +} + +// CONTENTEDITABLE INPUT STYLE + +var ContentEditableInput = function(cm) { + this.cm = cm + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null + this.polling = new Delayed() + this.composing = null + this.gracePeriod = false + this.readDOMTimeout = null +}; + +ContentEditableInput.prototype.init = function (display) { + var this$1 = this; + + var input = this, cm = input.cm + var div = input.div = display.lineDiv + disableBrowserMagic(div, cm.options.spellcheck) + + on(div, "paste", function (e) { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } + // IE doesn't fire input events, so we schedule a read for the pasted content in this way + if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20) } + }) + + on(div, "compositionstart", function (e) { + this$1.composing = {data: e.data, done: false} + }) + on(div, "compositionupdate", function (e) { + if (!this$1.composing) { this$1.composing = {data: e.data, done: false} } + }) + on(div, "compositionend", function (e) { + if (this$1.composing) { + if (e.data != this$1.composing.data) { this$1.readFromDOMSoon() } + this$1.composing.done = true + } + }) + + on(div, "touchstart", function () { return input.forceCompositionEnd(); }) + + on(div, "input", function () { + if (!this$1.composing) { this$1.readFromDOMSoon() } + }) + + function onCopyCut(e) { + if (signalDOMEvent(cm, e)) { return } + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}) + if (e.type == "cut") { cm.replaceSelection("", null, "cut") } + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + var ranges = copyableRanges(cm) + setLastCopied({lineWise: true, text: ranges.text}) + if (e.type == "cut") { + cm.operation(function () { + cm.setSelections(ranges.ranges, 0, sel_dontScroll) + cm.replaceSelection("", null, "cut") + }) + } + } + if (e.clipboardData) { + e.clipboardData.clearData() + var content = lastCopied.text.join("\n") + // iOS exposes the clipboard API, but seems to discard content inserted into it + e.clipboardData.setData("Text", content) + if (e.clipboardData.getData("Text") == content) { + e.preventDefault() + return + } + } + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild) + te.value = lastCopied.text.join("\n") + var hadFocus = document.activeElement + selectInput(te) + setTimeout(function () { + cm.display.lineSpace.removeChild(kludge) + hadFocus.focus() + if (hadFocus == div) { input.showPrimarySelection() } + }, 50) + } + on(div, "copy", onCopyCut) + on(div, "cut", onCopyCut) +}; + +ContentEditableInput.prototype.prepareSelection = function () { + var result = prepareSelection(this.cm, false) + result.focus = this.cm.state.focused + return result +}; + +ContentEditableInput.prototype.showSelection = function (info, takeFocus) { + if (!info || !this.cm.display.view.length) { return } + if (info.focus || takeFocus) { this.showPrimarySelection() } + this.showMultipleSelections(info) +}; + +ContentEditableInput.prototype.showPrimarySelection = function () { + var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary() + var from = prim.from(), to = prim.to() + + if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { + sel.removeAllRanges() + return + } + + var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) + var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset) + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), from) == 0 && + cmp(maxPos(curAnchor, curFocus), to) == 0) + { return } + + var view = cm.display.view + var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) || + {node: view[0].measure.map[2], offset: 0} + var end = to.line < cm.display.viewTo && posToDOM(cm, to) + if (!end) { + var measure = view[view.length - 1].measure + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]} + } + + if (!start || !end) { + sel.removeAllRanges() + return + } + + var old = sel.rangeCount && sel.getRangeAt(0), rng + try { rng = range(start.node, start.offset, end.offset, end.node) } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + if (!gecko && cm.state.focused) { + sel.collapse(start.node, start.offset) + if (!rng.collapsed) { + sel.removeAllRanges() + sel.addRange(rng) + } + } else { + sel.removeAllRanges() + sel.addRange(rng) + } + if (old && sel.anchorNode == null) { sel.addRange(old) } + else if (gecko) { this.startGracePeriod() } + } + this.rememberSelection() +}; + +ContentEditableInput.prototype.startGracePeriod = function () { + var this$1 = this; + + clearTimeout(this.gracePeriod) + this.gracePeriod = setTimeout(function () { + this$1.gracePeriod = false + if (this$1.selectionChanged()) + { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }) } + }, 20) +}; + +ContentEditableInput.prototype.showMultipleSelections = function (info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors) + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection) +}; + +ContentEditableInput.prototype.rememberSelection = function () { + var sel = window.getSelection() + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset +}; + +ContentEditableInput.prototype.selectionInEditor = function () { + var sel = window.getSelection() + if (!sel.rangeCount) { return false } + var node = sel.getRangeAt(0).commonAncestorContainer + return contains(this.div, node) +}; + +ContentEditableInput.prototype.focus = function () { + if (this.cm.options.readOnly != "nocursor") { + if (!this.selectionInEditor()) + { this.showSelection(this.prepareSelection(), true) } + this.div.focus() + } +}; +ContentEditableInput.prototype.blur = function () { this.div.blur() }; +ContentEditableInput.prototype.getField = function () { return this.div }; + +ContentEditableInput.prototype.supportsTouch = function () { return true }; + +ContentEditableInput.prototype.receivedFocus = function () { + var input = this + if (this.selectionInEditor()) + { this.pollSelection() } + else + { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }) } + + function poll() { + if (input.cm.state.focused) { + input.pollSelection() + input.polling.set(input.cm.options.pollInterval, poll) + } + } + this.polling.set(this.cm.options.pollInterval, poll) +}; + +ContentEditableInput.prototype.selectionChanged = function () { + var sel = window.getSelection() + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset +}; + +ContentEditableInput.prototype.pollSelection = function () { + if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return } + var sel = window.getSelection(), cm = this.cm + // On Android Chrome (version 56, at least), backspacing into an + // uneditable block element will put the cursor in that element, + // and then, because it's not editable, hide the virtual keyboard. + // Because Android doesn't allow us to actually detect backspace + // presses in a sane way, this code checks for when that happens + // and simulates a backspace press in this case. + if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) { + this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs}) + this.blur() + this.focus() + return + } + if (this.composing) { return } + this.rememberSelection() + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) + var head = domToPos(cm, sel.focusNode, sel.focusOffset) + if (anchor && head) { runInOp(cm, function () { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll) + if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true } + }) } +}; + +ContentEditableInput.prototype.pollContent = function () { + if (this.readDOMTimeout != null) { + clearTimeout(this.readDOMTimeout) + this.readDOMTimeout = null + } + + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary() + var from = sel.from(), to = sel.to() + if (from.ch == 0 && from.line > cm.firstLine()) + { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length) } + if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine()) + { to = Pos(to.line + 1, 0) } + if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false } + + var fromIndex, fromLine, fromNode + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + fromLine = lineNo(display.view[0].line) + fromNode = display.view[0].node + } else { + fromLine = lineNo(display.view[fromIndex].line) + fromNode = display.view[fromIndex - 1].node.nextSibling + } + var toIndex = findViewIndex(cm, to.line) + var toLine, toNode + if (toIndex == display.view.length - 1) { + toLine = display.viewTo - 1 + toNode = display.lineDiv.lastChild + } else { + toLine = lineNo(display.view[toIndex + 1].line) - 1 + toNode = display.view[toIndex + 1].node.previousSibling + } + + if (!fromNode) { return false } + var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)) + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)) + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine-- } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++ } + else { break } + } + + var cutFront = 0, cutEnd = 0 + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length) + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + { ++cutFront } + var newBot = lst(newText), oldBot = lst(oldText) + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)) + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + { ++cutEnd } + // Try to move start of change to start of selection if ambiguous + if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) { + while (cutFront && cutFront > from.ch && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) { + cutFront-- + cutEnd++ + } + } + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "") + newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "") + + var chFrom = Pos(fromLine, cutFront) + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0) + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input") + return true + } +}; + +ContentEditableInput.prototype.ensurePolled = function () { + this.forceCompositionEnd() +}; +ContentEditableInput.prototype.reset = function () { + this.forceCompositionEnd() +}; +ContentEditableInput.prototype.forceCompositionEnd = function () { + if (!this.composing) { return } + clearTimeout(this.readDOMTimeout) + this.composing = null + this.updateFromDOM() + this.div.blur() + this.div.focus() +}; +ContentEditableInput.prototype.readFromDOMSoon = function () { + var this$1 = this; + + if (this.readDOMTimeout != null) { return } + this.readDOMTimeout = setTimeout(function () { + this$1.readDOMTimeout = null + if (this$1.composing) { + if (this$1.composing.done) { this$1.composing = null } + else { return } + } + this$1.updateFromDOM() + }, 80) +}; + +ContentEditableInput.prototype.updateFromDOM = function () { + var this$1 = this; + + if (this.cm.isReadOnly() || !this.pollContent()) + { runInOp(this.cm, function () { return regChange(this$1.cm); }) } +}; + +ContentEditableInput.prototype.setUneditable = function (node) { + node.contentEditable = "false" +}; + +ContentEditableInput.prototype.onKeyPress = function (e) { + if (e.charCode == 0) { return } + e.preventDefault() + if (!this.cm.isReadOnly()) + { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) } +}; + +ContentEditableInput.prototype.readOnlyChanged = function (val) { + this.div.contentEditable = String(val != "nocursor") +}; + +ContentEditableInput.prototype.onContextMenu = function () {}; +ContentEditableInput.prototype.resetPosition = function () {}; + +ContentEditableInput.prototype.needsContentAttribute = true + +function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line) + if (!view || view.hidden) { return null } + var line = getLine(cm.doc, pos.line) + var info = mapFromLineView(view, line, pos.line) + + var order = getOrder(line, cm.doc.direction), side = "left" + if (order) { + var partPos = getBidiPartAt(order, pos.ch) + side = partPos % 2 ? "right" : "left" + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side) + result.offset = result.collapse == "right" ? result.end : result.start + return result +} + +function isInGutter(node) { + for (var scan = node; scan; scan = scan.parentNode) + { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } } + return false +} + +function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos } + +function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false, lineSep = cm.doc.lineSeparator() + function recognizeMarker(id) { return function (marker) { return marker.id == id; } } + function close() { + if (closing) { + text += lineSep + closing = false + } + } + function addText(str) { + if (str) { + close() + text += str + } + } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text") + if (cmText != null) { + addText(cmText || node.textContent.replace(/\u200b/g, "")) + return + } + var markerID = node.getAttribute("cm-marker"), range + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)) + if (found.length && (range = found[0].find(0))) + { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) } + return + } + if (node.getAttribute("contenteditable") == "false") { return } + var isBlock = /^(pre|div|p)$/i.test(node.nodeName) + if (isBlock) { close() } + for (var i = 0; i < node.childNodes.length; i++) + { walk(node.childNodes[i]) } + if (isBlock) { closing = true } + } else if (node.nodeType == 3) { + addText(node.nodeValue) + } + } + for (;;) { + walk(from) + if (from == to) { break } + from = from.nextSibling + } + return text +} + +function domToPos(cm, node, offset) { + var lineNode + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset] + if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) } + node = null; offset = 0 + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) { return null } + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break } + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i] + if (lineView.node == lineNode) + { return locateNodeInLineView(lineView, node, offset) } + } +} + +function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false + if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) } + if (node == wrapper) { + bad = true + node = wrapper.childNodes[offset] + offset = 0 + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line + return badPos(Pos(lineNo(line), line.text.length), bad) + } + } + + var textNode = node.nodeType == 3 ? node : null, topNode = node + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild + if (offset) { offset = textNode.nodeValue.length } + } + while (topNode.parentNode != wrapper) { topNode = topNode.parentNode } + var measure = lineView.measure, maps = measure.maps + + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i] + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2] + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]) + var ch = map[j] + offset + if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)] } + return Pos(line, ch) + } + } + } + } + var found = find(textNode, topNode, offset) + if (found) { return badPos(found, bad) } + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0) + if (found) + { return badPos(Pos(found.line, found.ch - dist), bad) } + else + { dist += after.textContent.length } + } + for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1) + if (found) + { return badPos(Pos(found.line, found.ch + dist$1), bad) } + else + { dist$1 += before.textContent.length } + } +} + +// TEXTAREA INPUT STYLE + +var TextareaInput = function(cm) { + this.cm = cm + // See input.poll and input.reset + this.prevInput = "" + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false + // Self-resetting timeout for the poller + this.polling = new Delayed() + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false + this.composing = null +}; + +TextareaInput.prototype.init = function (display) { + var this$1 = this; + + var input = this, cm = this.cm + + // Wraps and hides input textarea + var div = this.wrapper = hiddenTextarea() + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var te = this.textarea = div.firstChild + display.wrapper.insertBefore(div, display.wrapper.firstChild) + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) { te.style.width = "0px" } + + on(te, "input", function () { + if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null } + input.poll() + }) + + on(te, "paste", function (e) { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } + + cm.state.pasteIncoming = true + input.fastPoll() + }) + + function prepareCopyCut(e) { + if (signalDOMEvent(cm, e)) { return } + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}) + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + var ranges = copyableRanges(cm) + setLastCopied({lineWise: true, text: ranges.text}) + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll) + } else { + input.prevInput = "" + te.value = ranges.text.join("\n") + selectInput(te) + } + } + if (e.type == "cut") { cm.state.cutIncoming = true } + } + on(te, "cut", prepareCopyCut) + on(te, "copy", prepareCopyCut) + + on(display.scroller, "paste", function (e) { + if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return } + cm.state.pasteIncoming = true + input.focus() + }) + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function (e) { + if (!eventInWidget(display, e)) { e_preventDefault(e) } + }) + + on(te, "compositionstart", function () { + var start = cm.getCursor("from") + if (input.composing) { input.composing.range.clear() } + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + } + }) + on(te, "compositionend", function () { + if (input.composing) { + input.poll() + input.composing.range.clear() + input.composing = null + } + }) +}; + +TextareaInput.prototype.prepareSelection = function () { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc + var result = prepareSelection(cm) + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div") + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect() + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)) + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)) + } + + return result +}; + +TextareaInput.prototype.showSelection = function (drawn) { + var cm = this.cm, display = cm.display + removeChildrenAndAdd(display.cursorDiv, drawn.cursors) + removeChildrenAndAdd(display.selectionDiv, drawn.selection) + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px" + this.wrapper.style.left = drawn.teLeft + "px" + } +}; + +// Reset the input to correspond to the selection (or to be empty, +// when not typing and nothing is selected) +TextareaInput.prototype.reset = function (typing) { + if (this.contextMenuPending || this.composing) { return } + var cm = this.cm + if (cm.somethingSelected()) { + this.prevInput = "" + var content = cm.getSelection() + this.textarea.value = content + if (cm.state.focused) { selectInput(this.textarea) } + if (ie && ie_version >= 9) { this.hasSelection = content } + } else if (!typing) { + this.prevInput = this.textarea.value = "" + if (ie && ie_version >= 9) { this.hasSelection = null } + } +}; + +TextareaInput.prototype.getField = function () { return this.textarea }; + +TextareaInput.prototype.supportsTouch = function () { return false }; + +TextareaInput.prototype.focus = function () { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus() } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } +}; + +TextareaInput.prototype.blur = function () { this.textarea.blur() }; + +TextareaInput.prototype.resetPosition = function () { + this.wrapper.style.top = this.wrapper.style.left = 0 +}; + +TextareaInput.prototype.receivedFocus = function () { this.slowPoll() }; + +// Poll for input changes, using the normal rate of polling. This +// runs as long as the editor is focused. +TextareaInput.prototype.slowPoll = function () { + var this$1 = this; + + if (this.pollingFast) { return } + this.polling.set(this.cm.options.pollInterval, function () { + this$1.poll() + if (this$1.cm.state.focused) { this$1.slowPoll() } + }) +}; + +// When an event has just come in that is likely to add or change +// something in the input textarea, we poll faster, to ensure that +// the change appears on the screen quickly. +TextareaInput.prototype.fastPoll = function () { + var missed = false, input = this + input.pollingFast = true + function p() { + var changed = input.poll() + if (!changed && !missed) {missed = true; input.polling.set(60, p)} + else {input.pollingFast = false; input.slowPoll()} + } + input.polling.set(20, p) +}; + +// Read input from the textarea, and update the document to match. +// When something is selected, it is present in the textarea, and +// selected (unless it is huge, in which case a placeholder is +// used). When nothing is selected, the cursor sits after previously +// seen text (can be empty), which is stored in prevInput (we must +// not reset the textarea when typing, because that breaks IME). +TextareaInput.prototype.poll = function () { + var this$1 = this; + + var cm = this.cm, input = this.textarea, prevInput = this.prevInput + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput && !this.composing) || + cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) + { return false } + + var text = input.value + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) { return false } + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset() + return false + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0) + if (first == 0x200b && !prevInput) { prevInput = "\u200b" } + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length) + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same } + + runInOp(cm, function () { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, this$1.composing ? "*compose" : null) + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = "" } + else { this$1.prevInput = text } + + if (this$1.composing) { + this$1.composing.range.clear() + this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}) + } + }) + return true +}; + +TextareaInput.prototype.ensurePolled = function () { + if (this.pollingFast && this.poll()) { this.pollingFast = false } +}; + +TextareaInput.prototype.onKeyPress = function () { + if (ie && ie_version >= 9) { this.hasSelection = null } + this.fastPoll() +}; + +TextareaInput.prototype.onContextMenu = function (e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop + if (!pos || presto) { return } // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu + if (reset && cm.doc.sel.contains(pos) == -1) + { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll) } + + var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText + input.wrapper.style.cssText = "position: absolute" + var wrapperBox = input.wrapper.getBoundingClientRect() + te.style.cssText = "position: absolute; width: 30px; height: 30px;\n top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);" + var oldScrollY + if (webkit) { oldScrollY = window.scrollY } // Work around Chrome issue (#2712) + display.input.focus() + if (webkit) { window.scrollTo(null, oldScrollY) } + display.input.reset() + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) { te.value = input.prevInput = " " } + input.contextMenuPending = true + display.selForContextMenu = cm.doc.sel + clearTimeout(display.detectingSelectAll) + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected() + var extval = "\u200b" + (selected ? te.value : "") + te.value = "\u21da" // Used to catch context-menu undo + te.value = extval + input.prevInput = selected ? "" : "\u200b" + te.selectionStart = 1; te.selectionEnd = extval.length + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel + } + } + function rehide() { + input.contextMenuPending = false + input.wrapper.style.cssText = oldWrapperCSS + te.style.cssText = oldCSS + if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos) } + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack() } + var i = 0, poll = function () { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") { + operation(cm, selectAll)(cm) + } else if (i++ < 10) { + display.detectingSelectAll = setTimeout(poll, 500) + } else { + display.selForContextMenu = null + display.input.reset() + } + } + display.detectingSelectAll = setTimeout(poll, 200) + } + } + + if (ie && ie_version >= 9) { prepareSelectAllHack() } + if (captureRightClick) { + e_stop(e) + var mouseup = function () { + off(window, "mouseup", mouseup) + setTimeout(rehide, 20) + } + on(window, "mouseup", mouseup) + } else { + setTimeout(rehide, 50) + } +}; + +TextareaInput.prototype.readOnlyChanged = function (val) { + if (!val) { this.reset() } + this.textarea.disabled = val == "nocursor" +}; + +TextareaInput.prototype.setUneditable = function () {}; + +TextareaInput.prototype.needsContentAttribute = false + +function fromTextArea(textarea, options) { + options = options ? copyObj(options) : {} + options.value = textarea.value + if (!options.tabindex && textarea.tabIndex) + { options.tabindex = textarea.tabIndex } + if (!options.placeholder && textarea.placeholder) + { options.placeholder = textarea.placeholder } + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt() + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body + } + + function save() {textarea.value = cm.getValue()} + + var realSubmit + if (textarea.form) { + on(textarea.form, "submit", save) + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form + realSubmit = form.submit + try { + var wrappedSubmit = form.submit = function () { + save() + form.submit = realSubmit + form.submit() + form.submit = wrappedSubmit + } + } catch(e) {} + } + } + + options.finishInit = function (cm) { + cm.save = save + cm.getTextArea = function () { return textarea; } + cm.toTextArea = function () { + cm.toTextArea = isNaN // Prevent this from being ran twice + save() + textarea.parentNode.removeChild(cm.getWrapperElement()) + textarea.style.display = "" + if (textarea.form) { + off(textarea.form, "submit", save) + if (typeof textarea.form.submit == "function") + { textarea.form.submit = realSubmit } + } + } + } + + textarea.style.display = "none" + var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); }, + options) + return cm +} + +function addLegacyProps(CodeMirror) { + CodeMirror.off = off + CodeMirror.on = on + CodeMirror.wheelEventPixels = wheelEventPixels + CodeMirror.Doc = Doc + CodeMirror.splitLines = splitLinesAuto + CodeMirror.countColumn = countColumn + CodeMirror.findColumn = findColumn + CodeMirror.isWordChar = isWordCharBasic + CodeMirror.Pass = Pass + CodeMirror.signal = signal + CodeMirror.Line = Line + CodeMirror.changeEnd = changeEnd + CodeMirror.scrollbarModel = scrollbarModel + CodeMirror.Pos = Pos + CodeMirror.cmpPos = cmp + CodeMirror.modes = modes + CodeMirror.mimeModes = mimeModes + CodeMirror.resolveMode = resolveMode + CodeMirror.getMode = getMode + CodeMirror.modeExtensions = modeExtensions + CodeMirror.extendMode = extendMode + CodeMirror.copyState = copyState + CodeMirror.startState = startState + CodeMirror.innerMode = innerMode + CodeMirror.commands = commands + CodeMirror.keyMap = keyMap + CodeMirror.keyName = keyName + CodeMirror.isModifierKey = isModifierKey + CodeMirror.lookupKey = lookupKey + CodeMirror.normalizeKeyMap = normalizeKeyMap + CodeMirror.StringStream = StringStream + CodeMirror.SharedTextMarker = SharedTextMarker + CodeMirror.TextMarker = TextMarker + CodeMirror.LineWidget = LineWidget + CodeMirror.e_preventDefault = e_preventDefault + CodeMirror.e_stopPropagation = e_stopPropagation + CodeMirror.e_stop = e_stop + CodeMirror.addClass = addClass + CodeMirror.contains = contains + CodeMirror.rmClass = rmClass + CodeMirror.keyNames = keyNames +} + +// EDITOR CONSTRUCTOR + +defineOptions(CodeMirror) + +addEditorMethods(CodeMirror) + +// Set up methods on CodeMirror's prototype to redirect to the editor's document. +var dontDelegate = "iter insert remove copy getEditor constructor".split(" ") +for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + { CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments)} + })(Doc.prototype[prop]) } } + +eventMixin(Doc) + +// INPUT HANDLING + +CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput} + +// MODE DEFINITION AND QUERYING + +// Extra arguments are stored as the mode's dependencies, which is +// used by (legacy) mechanisms like loadmode.js to automatically +// load a mode. (Preferred mechanism is the require/define calls.) +CodeMirror.defineMode = function(name/*, mode, …*/) { + if (!CodeMirror.defaults.mode && name != "null") { CodeMirror.defaults.mode = name } + defineMode.apply(this, arguments) +} + +CodeMirror.defineMIME = defineMIME + +// Minimal default mode. +CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }) +CodeMirror.defineMIME("text/plain", "null") + +// EXTENSIONS + +CodeMirror.defineExtension = function (name, func) { + CodeMirror.prototype[name] = func +} +CodeMirror.defineDocExtension = function (name, func) { + Doc.prototype[name] = func +} + +CodeMirror.fromTextArea = fromTextArea + +addLegacyProps(CodeMirror) + +CodeMirror.version = "5.32.0" + +return CodeMirror; + +}))); \ No newline at end of file diff --git a/backend/webif/static/codemirror/mode/apl/apl.js b/backend/webif/static/codemirror/mode/apl/apl.js new file mode 100755 index 000000000..caafe4e91 --- /dev/null +++ b/backend/webif/static/codemirror/mode/apl/apl.js @@ -0,0 +1,174 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("apl", function() { + var builtInOps = { + ".": "innerProduct", + "\\": "scan", + "/": "reduce", + "⌿": "reduce1Axis", + "⍀": "scan1Axis", + "¨": "each", + "⍣": "power" + }; + var builtInFuncs = { + "+": ["conjugate", "add"], + "−": ["negate", "subtract"], + "×": ["signOf", "multiply"], + "÷": ["reciprocal", "divide"], + "⌈": ["ceiling", "greaterOf"], + "⌊": ["floor", "lesserOf"], + "∣": ["absolute", "residue"], + "⍳": ["indexGenerate", "indexOf"], + "?": ["roll", "deal"], + "⋆": ["exponentiate", "toThePowerOf"], + "⍟": ["naturalLog", "logToTheBase"], + "○": ["piTimes", "circularFuncs"], + "!": ["factorial", "binomial"], + "⌹": ["matrixInverse", "matrixDivide"], + "<": [null, "lessThan"], + "≤": [null, "lessThanOrEqual"], + "=": [null, "equals"], + ">": [null, "greaterThan"], + "≥": [null, "greaterThanOrEqual"], + "≠": [null, "notEqual"], + "≡": ["depth", "match"], + "≢": [null, "notMatch"], + "∈": ["enlist", "membership"], + "⍷": [null, "find"], + "∪": ["unique", "union"], + "∩": [null, "intersection"], + "∼": ["not", "without"], + "∨": [null, "or"], + "∧": [null, "and"], + "⍱": [null, "nor"], + "⍲": [null, "nand"], + "⍴": ["shapeOf", "reshape"], + ",": ["ravel", "catenate"], + "⍪": [null, "firstAxisCatenate"], + "⌽": ["reverse", "rotate"], + "⊖": ["axis1Reverse", "axis1Rotate"], + "⍉": ["transpose", null], + "↑": ["first", "take"], + "↓": [null, "drop"], + "⊂": ["enclose", "partitionWithAxis"], + "⊃": ["diclose", "pick"], + "⌷": [null, "index"], + "⍋": ["gradeUp", null], + "⍒": ["gradeDown", null], + "⊤": ["encode", null], + "⊥": ["decode", null], + "⍕": ["format", "formatByExample"], + "⍎": ["execute", null], + "⊣": ["stop", "left"], + "⊢": ["pass", "right"] + }; + + var isOperator = /[\.\/⌿⍀¨⍣]/; + var isNiladic = /⍬/; + var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/; + var isArrow = /←/; + var isComment = /[⍝#].*$/; + + var stringEater = function(type) { + var prev; + prev = false; + return function(c) { + prev = c; + if (c === type) { + return prev === "\\"; + } + return true; + }; + }; + return { + startState: function() { + return { + prev: false, + func: false, + op: false, + string: false, + escape: false + }; + }, + token: function(stream, state) { + var ch, funcName; + if (stream.eatSpace()) { + return null; + } + ch = stream.next(); + if (ch === '"' || ch === "'") { + stream.eatWhile(stringEater(ch)); + stream.next(); + state.prev = true; + return "string"; + } + if (/[\[{\(]/.test(ch)) { + state.prev = false; + return null; + } + if (/[\]}\)]/.test(ch)) { + state.prev = true; + return null; + } + if (isNiladic.test(ch)) { + state.prev = false; + return "niladic"; + } + if (/[¯\d]/.test(ch)) { + if (state.func) { + state.func = false; + state.prev = false; + } else { + state.prev = true; + } + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (isOperator.test(ch)) { + return "operator apl-" + builtInOps[ch]; + } + if (isArrow.test(ch)) { + return "apl-arrow"; + } + if (isFunction.test(ch)) { + funcName = "apl-"; + if (builtInFuncs[ch] != null) { + if (state.prev) { + funcName += builtInFuncs[ch][1]; + } else { + funcName += builtInFuncs[ch][0]; + } + } + state.func = true; + state.prev = false; + return "function " + funcName; + } + if (isComment.test(ch)) { + stream.skipToEnd(); + return "comment"; + } + if (ch === "∘" && stream.peek() === ".") { + stream.next(); + return "function jot-dot"; + } + stream.eatWhile(/[\w\$_]/); + state.prev = true; + return "keyword"; + } + }; +}); + +CodeMirror.defineMIME("text/apl", "apl"); + +}); diff --git a/backend/webif/static/codemirror/mode/apl/index.html b/backend/webif/static/codemirror/mode/apl/index.html new file mode 100755 index 000000000..53dda6b58 --- /dev/null +++ b/backend/webif/static/codemirror/mode/apl/index.html @@ -0,0 +1,72 @@ + + +CodeMirror: APL mode + + + + + + + + + + +
+

APL mode

+
+ + + +

Simple mode that tries to handle APL as well as it can.

+

It attempts to label functions/operators based upon + monadic/dyadic usage (but this is far from fully fleshed out). + This means there are meaningful classnames so hover states can + have popups etc.

+ +

MIME types defined: text/apl (APL code)

+
diff --git a/backend/webif/static/codemirror/mode/asciiarmor/asciiarmor.js b/backend/webif/static/codemirror/mode/asciiarmor/asciiarmor.js new file mode 100755 index 000000000..fa1b0f8c6 --- /dev/null +++ b/backend/webif/static/codemirror/mode/asciiarmor/asciiarmor.js @@ -0,0 +1,74 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function errorIfNotEmpty(stream) { + var nonWS = stream.match(/^\s*\S/); + stream.skipToEnd(); + return nonWS ? "error" : null; + } + + CodeMirror.defineMode("asciiarmor", function() { + return { + token: function(stream, state) { + var m; + if (state.state == "top") { + if (stream.sol() && (m = stream.match(/^-----BEGIN (.*)?-----\s*$/))) { + state.state = "headers"; + state.type = m[1]; + return "tag"; + } + return errorIfNotEmpty(stream); + } else if (state.state == "headers") { + if (stream.sol() && stream.match(/^\w+:/)) { + state.state = "header"; + return "atom"; + } else { + var result = errorIfNotEmpty(stream); + if (result) state.state = "body"; + return result; + } + } else if (state.state == "header") { + stream.skipToEnd(); + state.state = "headers"; + return "string"; + } else if (state.state == "body") { + if (stream.sol() && (m = stream.match(/^-----END (.*)?-----\s*$/))) { + if (m[1] != state.type) return "error"; + state.state = "end"; + return "tag"; + } else { + if (stream.eatWhile(/[A-Za-z0-9+\/=]/)) { + return null; + } else { + stream.next(); + return "error"; + } + } + } else if (state.state == "end") { + return errorIfNotEmpty(stream); + } + }, + blankLine: function(state) { + if (state.state == "headers") state.state = "body"; + }, + startState: function() { + return {state: "top", type: null}; + } + }; + }); + + CodeMirror.defineMIME("application/pgp", "asciiarmor"); + CodeMirror.defineMIME("application/pgp-encrypted", "asciiarmor"); + CodeMirror.defineMIME("application/pgp-keys", "asciiarmor"); + CodeMirror.defineMIME("application/pgp-signature", "asciiarmor"); +}); diff --git a/backend/webif/static/codemirror/mode/asciiarmor/index.html b/backend/webif/static/codemirror/mode/asciiarmor/index.html new file mode 100755 index 000000000..4d584efbc --- /dev/null +++ b/backend/webif/static/codemirror/mode/asciiarmor/index.html @@ -0,0 +1,46 @@ + + +CodeMirror: ASCII Armor (PGP) mode + + + + + + + + + +
+

ASCII Armor (PGP) mode

+
+ + + +

MIME types +defined: application/pgp, application/pgp-encrypted, application/pgp-keys, application/pgp-signature

+ +
diff --git a/backend/webif/static/codemirror/mode/asn.1/asn.1.js b/backend/webif/static/codemirror/mode/asn.1/asn.1.js new file mode 100755 index 000000000..9600247ea --- /dev/null +++ b/backend/webif/static/codemirror/mode/asn.1/asn.1.js @@ -0,0 +1,204 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("asn.1", function(config, parserConfig) { + var indentUnit = config.indentUnit, + keywords = parserConfig.keywords || {}, + cmipVerbs = parserConfig.cmipVerbs || {}, + compareTypes = parserConfig.compareTypes || {}, + status = parserConfig.status || {}, + tags = parserConfig.tags || {}, + storage = parserConfig.storage || {}, + modifier = parserConfig.modifier || {}, + accessTypes = parserConfig.accessTypes|| {}, + multiLineStrings = parserConfig.multiLineStrings, + indentStatements = parserConfig.indentStatements !== false; + var isOperatorChar = /[\|\^]/; + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\[\]\(\){}:=,;]/.test(ch)) { + curPunc = ch; + return "punctuation"; + } + if (ch == "-"){ + if (stream.eat("-")) { + stream.skipToEnd(); + return "comment"; + } + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + + stream.eatWhile(/[\w\-]/); + var cur = stream.current(); + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + if (cmipVerbs.propertyIsEnumerable(cur)) return "variable cmipVerbs"; + if (compareTypes.propertyIsEnumerable(cur)) return "atom compareTypes"; + if (status.propertyIsEnumerable(cur)) return "comment status"; + if (tags.propertyIsEnumerable(cur)) return "variable-3 tags"; + if (storage.propertyIsEnumerable(cur)) return "builtin storage"; + if (modifier.propertyIsEnumerable(cur)) return "string-2 modifier"; + if (accessTypes.propertyIsEnumerable(cur)) return "atom accessTypes"; + + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped){ + var afterNext = stream.peek(); + //look if the character if the quote is like the B in '10100010'B + if (afterNext){ + afterNext = afterNext.toLowerCase(); + if(afterNext == "b" || afterNext == "h" || afterNext == "o") + stream.next(); + } + end = true; break; + } + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = null; + return "string"; + }; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + var indent = state.indented; + if (state.context && state.context.type == "statement") + indent = state.context.indented; + return state.context = new Context(indent, col, type, null, state.context); + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + //Interface + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":" || curPunc == ",") + && ctx.type == "statement"){ + popContext(state); + } + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (indentStatements && (((ctx.type == "}" || ctx.type == "top") + && curPunc != ';') || (ctx.type == "statement" + && curPunc == "newstatement"))) + pushContext(state, stream.column(), "statement"); + + state.startOfLine = false; + return style; + }, + + electricChars: "{}", + lineComment: "--", + fold: "brace" + }; + }); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + CodeMirror.defineMIME("text/x-ttcn-asn", { + name: "asn.1", + keywords: words("DEFINITIONS OBJECTS IF DERIVED INFORMATION ACTION" + + " REPLY ANY NAMED CHARACTERIZED BEHAVIOUR REGISTERED" + + " WITH AS IDENTIFIED CONSTRAINED BY PRESENT BEGIN" + + " IMPORTS FROM UNITS SYNTAX MIN-ACCESS MAX-ACCESS" + + " MINACCESS MAXACCESS REVISION STATUS DESCRIPTION" + + " SEQUENCE SET COMPONENTS OF CHOICE DistinguishedName" + + " ENUMERATED SIZE MODULE END INDEX AUGMENTS EXTENSIBILITY" + + " IMPLIED EXPORTS"), + cmipVerbs: words("ACTIONS ADD GET NOTIFICATIONS REPLACE REMOVE"), + compareTypes: words("OPTIONAL DEFAULT MANAGED MODULE-TYPE MODULE_IDENTITY" + + " MODULE-COMPLIANCE OBJECT-TYPE OBJECT-IDENTITY" + + " OBJECT-COMPLIANCE MODE CONFIRMED CONDITIONAL" + + " SUBORDINATE SUPERIOR CLASS TRUE FALSE NULL" + + " TEXTUAL-CONVENTION"), + status: words("current deprecated mandatory obsolete"), + tags: words("APPLICATION AUTOMATIC EXPLICIT IMPLICIT PRIVATE TAGS" + + " UNIVERSAL"), + storage: words("BOOLEAN INTEGER OBJECT IDENTIFIER BIT OCTET STRING" + + " UTCTime InterfaceIndex IANAifType CMIP-Attribute" + + " REAL PACKAGE PACKAGES IpAddress PhysAddress" + + " NetworkAddress BITS BMPString TimeStamp TimeTicks" + + " TruthValue RowStatus DisplayString GeneralString" + + " GraphicString IA5String NumericString" + + " PrintableString SnmpAdminAtring TeletexString" + + " UTF8String VideotexString VisibleString StringStore" + + " ISO646String T61String UniversalString Unsigned32" + + " Integer32 Gauge Gauge32 Counter Counter32 Counter64"), + modifier: words("ATTRIBUTE ATTRIBUTES MANDATORY-GROUP MANDATORY-GROUPS" + + " GROUP GROUPS ELEMENTS EQUALITY ORDERING SUBSTRINGS" + + " DEFINED"), + accessTypes: words("not-accessible accessible-for-notify read-only" + + " read-create read-write"), + multiLineStrings: true + }); +}); diff --git a/backend/webif/static/codemirror/mode/asn.1/index.html b/backend/webif/static/codemirror/mode/asn.1/index.html new file mode 100755 index 000000000..699fd4473 --- /dev/null +++ b/backend/webif/static/codemirror/mode/asn.1/index.html @@ -0,0 +1,77 @@ + + +CodeMirror: ASN.1 mode + + + + + + + + +
+

ASN.1 example

+
+ +
+ + +
+

Language: Abstract Syntax Notation One + (ASN.1) +

+

MIME types defined: text/x-ttcn-asn

+ +
+

The development of this mode has been sponsored by Ericsson + .

+

Coded by Asmelash Tsegay Gebretsadkan

+
+ diff --git a/backend/webif/static/codemirror/mode/asterisk/asterisk.js b/backend/webif/static/codemirror/mode/asterisk/asterisk.js new file mode 100755 index 000000000..b7ebfc5ad --- /dev/null +++ b/backend/webif/static/codemirror/mode/asterisk/asterisk.js @@ -0,0 +1,196 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* + * ===================================================================================== + * + * Filename: mode/asterisk/asterisk.js + * + * Description: CodeMirror mode for Asterisk dialplan + * + * Created: 05/17/2012 09:20:25 PM + * Revision: none + * + * Author: Stas Kobzar (stas@modulis.ca), + * Company: Modulis.ca Inc. + * + * ===================================================================================== + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("asterisk", function() { + var atoms = ["exten", "same", "include","ignorepat","switch"], + dpcmd = ["#include","#exec"], + apps = [ + "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi", + "alarmreceiver","amd","answer","authenticate","background","backgrounddetect", + "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent", + "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge", + "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge", + "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility", + "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa", + "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy", + "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif", + "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete", + "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus", + "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme", + "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete", + "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode", + "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish", + "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce", + "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones", + "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten", + "readfile","receivefax","receivefax","receivefax","record","removequeuemember", + "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun", + "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax", + "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags", + "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel", + "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground", + "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound", + "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor", + "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec", + "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate", + "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring", + "waitforsilence","waitmusiconhold","waituntil","while","zapateller" + ]; + + function basicToken(stream,state){ + var cur = ''; + var ch = stream.next(); + // comment + if(ch == ";") { + stream.skipToEnd(); + return "comment"; + } + // context + if(ch == '[') { + stream.skipTo(']'); + stream.eat(']'); + return "header"; + } + // string + if(ch == '"') { + stream.skipTo('"'); + return "string"; + } + if(ch == "'") { + stream.skipTo("'"); + return "string-2"; + } + // dialplan commands + if(ch == '#') { + stream.eatWhile(/\w/); + cur = stream.current(); + if(dpcmd.indexOf(cur) !== -1) { + stream.skipToEnd(); + return "strong"; + } + } + // application args + if(ch == '$'){ + var ch1 = stream.peek(); + if(ch1 == '{'){ + stream.skipTo('}'); + stream.eat('}'); + return "variable-3"; + } + } + // extension + stream.eatWhile(/\w/); + cur = stream.current(); + if(atoms.indexOf(cur) !== -1) { + state.extenStart = true; + switch(cur) { + case 'same': state.extenSame = true; break; + case 'include': + case 'switch': + case 'ignorepat': + state.extenInclude = true;break; + default:break; + } + return "atom"; + } + } + + return { + startState: function() { + return { + extenStart: false, + extenSame: false, + extenInclude: false, + extenExten: false, + extenPriority: false, + extenApplication: false + }; + }, + token: function(stream, state) { + + var cur = ''; + if(stream.eatSpace()) return null; + // extension started + if(state.extenStart){ + stream.eatWhile(/[^\s]/); + cur = stream.current(); + if(/^=>?$/.test(cur)){ + state.extenExten = true; + state.extenStart = false; + return "strong"; + } else { + state.extenStart = false; + stream.skipToEnd(); + return "error"; + } + } else if(state.extenExten) { + // set exten and priority + state.extenExten = false; + state.extenPriority = true; + stream.eatWhile(/[^,]/); + if(state.extenInclude) { + stream.skipToEnd(); + state.extenPriority = false; + state.extenInclude = false; + } + if(state.extenSame) { + state.extenPriority = false; + state.extenSame = false; + state.extenApplication = true; + } + return "tag"; + } else if(state.extenPriority) { + state.extenPriority = false; + state.extenApplication = true; + stream.next(); // get comma + if(state.extenSame) return null; + stream.eatWhile(/[^,]/); + return "number"; + } else if(state.extenApplication) { + stream.eatWhile(/,/); + cur = stream.current(); + if(cur === ',') return null; + stream.eatWhile(/\w/); + cur = stream.current().toLowerCase(); + state.extenApplication = false; + if(apps.indexOf(cur) !== -1){ + return "def strong"; + } + } else{ + return basicToken(stream,state); + } + + return null; + } + }; +}); + +CodeMirror.defineMIME("text/x-asterisk", "asterisk"); + +}); diff --git a/backend/webif/static/codemirror/mode/asterisk/index.html b/backend/webif/static/codemirror/mode/asterisk/index.html new file mode 100755 index 000000000..257bd3987 --- /dev/null +++ b/backend/webif/static/codemirror/mode/asterisk/index.html @@ -0,0 +1,154 @@ + + +CodeMirror: Asterisk dialplan mode + + + + + + + + + +
+

Asterisk dialplan mode

+
+ + +

MIME types defined: text/x-asterisk.

+ +
diff --git a/backend/webif/static/codemirror/mode/brainfuck/brainfuck.js b/backend/webif/static/codemirror/mode/brainfuck/brainfuck.js new file mode 100755 index 000000000..3becf2a5a --- /dev/null +++ b/backend/webif/static/codemirror/mode/brainfuck/brainfuck.js @@ -0,0 +1,85 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Brainfuck mode created by Michael Kaminsky https://github.com/mkaminsky11 + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") + mod(require("../../lib/codemirror")) + else if (typeof define == "function" && define.amd) + define(["../../lib/codemirror"], mod) + else + mod(CodeMirror) +})(function(CodeMirror) { + "use strict" + var reserve = "><+-.,[]".split(""); + /* + comments can be either: + placed behind lines + + +++ this is a comment + + where reserved characters cannot be used + or in a loop + [ + this is ok to use [ ] and stuff + ] + or preceded by # + */ + CodeMirror.defineMode("brainfuck", function() { + return { + startState: function() { + return { + commentLine: false, + left: 0, + right: 0, + commentLoop: false + } + }, + token: function(stream, state) { + if (stream.eatSpace()) return null + if(stream.sol()){ + state.commentLine = false; + } + var ch = stream.next().toString(); + if(reserve.indexOf(ch) !== -1){ + if(state.commentLine === true){ + if(stream.eol()){ + state.commentLine = false; + } + return "comment"; + } + if(ch === "]" || ch === "["){ + if(ch === "["){ + state.left++; + } + else{ + state.right++; + } + return "bracket"; + } + else if(ch === "+" || ch === "-"){ + return "keyword"; + } + else if(ch === "<" || ch === ">"){ + return "atom"; + } + else if(ch === "." || ch === ","){ + return "def"; + } + } + else{ + state.commentLine = true; + if(stream.eol()){ + state.commentLine = false; + } + return "comment"; + } + if(stream.eol()){ + state.commentLine = false; + } + } + }; + }); +CodeMirror.defineMIME("text/x-brainfuck","brainfuck") +}); diff --git a/backend/webif/static/codemirror/mode/brainfuck/index.html b/backend/webif/static/codemirror/mode/brainfuck/index.html new file mode 100755 index 000000000..6048fc241 --- /dev/null +++ b/backend/webif/static/codemirror/mode/brainfuck/index.html @@ -0,0 +1,85 @@ + + +CodeMirror: Brainfuck mode + + + + + + + + + + +
+

Brainfuck mode

+
+ + + +

A mode for Brainfuck

+ +

MIME types defined: text/x-brainfuck

+
diff --git a/backend/webif/static/codemirror/mode/clike/clike.js b/backend/webif/static/codemirror/mode/clike/clike.js new file mode 100755 index 000000000..02a85319f --- /dev/null +++ b/backend/webif/static/codemirror/mode/clike/clike.js @@ -0,0 +1,790 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +function Context(indented, column, type, info, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.info = info; + this.align = align; + this.prev = prev; +} +function pushContext(state, col, type, info) { + var indent = state.indented; + if (state.context && state.context.type == "statement" && type != "statement") + indent = state.context.indented; + return state.context = new Context(indent, col, type, info, null, state.context); +} +function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; +} + +function typeBefore(stream, state, pos) { + if (state.prevToken == "variable" || state.prevToken == "type") return true; + if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true; + if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true; +} + +function isTopScope(context) { + for (;;) { + if (!context || context.type == "top") return true; + if (context.type == "}" && context.prev.info != "namespace") return false; + context = context.prev; + } +} + +CodeMirror.defineMode("clike", function(config, parserConfig) { + var indentUnit = config.indentUnit, + statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, + dontAlignCalls = parserConfig.dontAlignCalls, + keywords = parserConfig.keywords || {}, + types = parserConfig.types || {}, + builtin = parserConfig.builtin || {}, + blockKeywords = parserConfig.blockKeywords || {}, + defKeywords = parserConfig.defKeywords || {}, + atoms = parserConfig.atoms || {}, + hooks = parserConfig.hooks || {}, + multiLineStrings = parserConfig.multiLineStrings, + indentStatements = parserConfig.indentStatements !== false, + indentSwitch = parserConfig.indentSwitch !== false, + namespaceSeparator = parserConfig.namespaceSeparator, + isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/, + numberStart = parserConfig.numberStart || /[\d\.]/, + number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i, + isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/, + isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/; + + var curPunc, isDefKeyword; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (hooks[ch]) { + var result = hooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (isPunctuationChar.test(ch)) { + curPunc = ch; + return null; + } + if (numberStart.test(ch)) { + stream.backUp(1) + if (stream.match(number)) return "number" + stream.next() + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {} + return "operator"; + } + stream.eatWhile(isIdentifierChar); + if (namespaceSeparator) while (stream.match(namespaceSeparator)) + stream.eatWhile(isIdentifierChar); + + var cur = stream.current(); + if (contains(keywords, cur)) { + if (contains(blockKeywords, cur)) curPunc = "newstatement"; + if (contains(defKeywords, cur)) isDefKeyword = true; + return "keyword"; + } + if (contains(types, cur)) return "type"; + if (contains(builtin, cur)) { + if (contains(blockKeywords, cur)) curPunc = "newstatement"; + return "builtin"; + } + if (contains(atoms, cur)) return "atom"; + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = null; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function maybeEOL(stream, state) { + if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context)) + state.typeAtEndOfLine = typeBefore(stream, state, stream.pos) + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false), + indented: 0, + startOfLine: true, + prevToken: null + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) { maybeEOL(stream, state); return null; } + curPunc = isDefKeyword = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + if (ctx.align == null) ctx.align = true; + + if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false))) + while (state.context.type == "statement") popContext(state); + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (indentStatements && + (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") || + (ctx.type == "statement" && curPunc == "newstatement"))) { + pushContext(state, stream.column(), "statement", stream.current()); + } + + if (style == "variable" && + ((state.prevToken == "def" || + (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) && + isTopScope(state.context) && stream.match(/^\s*\(/, false))))) + style = "def"; + + if (hooks.token) { + var result = hooks.token(stream, state, style); + if (result !== undefined) style = result; + } + + if (style == "def" && parserConfig.styleDefs === false) style = "variable"; + + state.startOfLine = false; + state.prevToken = isDefKeyword ? "def" : style || curPunc; + maybeEOL(stream, state); + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass; + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; + if (parserConfig.dontIndentStatements) + while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info)) + ctx = ctx.prev + if (hooks.indent) { + var hook = hooks.indent(state, ctx, textAfter); + if (typeof hook == "number") return hook + } + var closing = firstChar == ctx.type; + var switchBlock = ctx.prev && ctx.prev.info == "switch"; + if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) { + while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev + return ctx.indented + } + if (ctx.type == "statement") + return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); + if (ctx.align && (!dontAlignCalls || ctx.type != ")")) + return ctx.column + (closing ? 0 : 1); + if (ctx.type == ")" && !closing) + return ctx.indented + statementIndentUnit; + + return ctx.indented + (closing ? 0 : indentUnit) + + (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0); + }, + + electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/, + blockCommentStart: "/*", + blockCommentEnd: "*/", + blockCommentContinue: " * ", + lineComment: "//", + fold: "brace" + }; +}); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + function contains(words, word) { + if (typeof words === "function") { + return words(word); + } else { + return words.propertyIsEnumerable(word); + } + } + var cKeywords = "auto if break case register continue return default do sizeof " + + "static else struct switch extern typedef union for goto while enum const volatile"; + var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t"; + + function cppHook(stream, state) { + if (!state.startOfLine) return false + for (var ch, next = null; ch = stream.peek();) { + if (ch == "\\" && stream.match(/^.$/)) { + next = cppHook + break + } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) { + break + } + stream.next() + } + state.tokenize = next + return "meta" + } + + function pointerHook(_stream, state) { + if (state.prevToken == "type") return "type"; + return false; + } + + function cpp14Literal(stream) { + stream.eatWhile(/[\w\.']/); + return "number"; + } + + function cpp11StringHook(stream, state) { + stream.backUp(1); + // Raw strings. + if (stream.match(/(R|u8R|uR|UR|LR)/)) { + var match = stream.match(/"([^\s\\()]{0,16})\(/); + if (!match) { + return false; + } + state.cpp11RawStringDelim = match[1]; + state.tokenize = tokenRawString; + return tokenRawString(stream, state); + } + // Unicode strings/chars. + if (stream.match(/(u8|u|U|L)/)) { + if (stream.match(/["']/, /* eat */ false)) { + return "string"; + } + return false; + } + // Ignore this hook. + stream.next(); + return false; + } + + function cppLooksLikeConstructor(word) { + var lastTwo = /(\w+)::~?(\w+)$/.exec(word); + return lastTwo && lastTwo[1] == lastTwo[2]; + } + + // C#-style strings where "" escapes a quote. + function tokenAtString(stream, state) { + var next; + while ((next = stream.next()) != null) { + if (next == '"' && !stream.eat('"')) { + state.tokenize = null; + break; + } + } + return "string"; + } + + // C++11 raw string literal is "( anything )", where + // can be a string up to 16 characters long. + function tokenRawString(stream, state) { + // Escape characters that have special regex meanings. + var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&'); + var match = stream.match(new RegExp(".*?\\)" + delim + '"')); + if (match) + state.tokenize = null; + else + stream.skipToEnd(); + return "string"; + } + + function def(mimes, mode) { + if (typeof mimes == "string") mimes = [mimes]; + var words = []; + function add(obj) { + if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) + words.push(prop); + } + add(mode.keywords); + add(mode.types); + add(mode.builtin); + add(mode.atoms); + if (words.length) { + mode.helperType = mimes[0]; + CodeMirror.registerHelper("hintWords", mimes[0], words); + } + + for (var i = 0; i < mimes.length; ++i) + CodeMirror.defineMIME(mimes[i], mode); + } + + def(["text/x-csrc", "text/x-c", "text/x-chdr"], { + name: "clike", + keywords: words(cKeywords), + types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " + + "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " + + "uint32_t uint64_t"), + blockKeywords: words("case do else for if switch while struct"), + defKeywords: words("struct"), + typeFirstDefinitions: true, + atoms: words("null true false"), + hooks: {"#": cppHook, "*": pointerHook}, + modeProps: {fold: ["brace", "include"]} + }); + + def(["text/x-c++src", "text/x-c++hdr"], { + name: "clike", + keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " + + "static_cast typeid catch operator template typename class friend private " + + "this using const_cast inline public throw virtual delete mutable protected " + + "alignas alignof constexpr decltype nullptr noexcept thread_local final " + + "static_assert override"), + types: words(cTypes + " bool wchar_t"), + blockKeywords: words("catch class do else finally for if struct switch try while"), + defKeywords: words("class namespace struct enum union"), + typeFirstDefinitions: true, + atoms: words("true false null"), + dontIndentStatements: /^template$/, + isIdentifierChar: /[\w\$_~\xa1-\uffff]/, + hooks: { + "#": cppHook, + "*": pointerHook, + "u": cpp11StringHook, + "U": cpp11StringHook, + "L": cpp11StringHook, + "R": cpp11StringHook, + "0": cpp14Literal, + "1": cpp14Literal, + "2": cpp14Literal, + "3": cpp14Literal, + "4": cpp14Literal, + "5": cpp14Literal, + "6": cpp14Literal, + "7": cpp14Literal, + "8": cpp14Literal, + "9": cpp14Literal, + token: function(stream, state, style) { + if (style == "variable" && stream.peek() == "(" && + (state.prevToken == ";" || state.prevToken == null || + state.prevToken == "}") && + cppLooksLikeConstructor(stream.current())) + return "def"; + } + }, + namespaceSeparator: "::", + modeProps: {fold: ["brace", "include"]} + }); + + def("text/x-java", { + name: "clike", + keywords: words("abstract assert break case catch class const continue default " + + "do else enum extends final finally float for goto if implements import " + + "instanceof interface native new package private protected public " + + "return static strictfp super switch synchronized this throw throws transient " + + "try volatile while @interface"), + types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + + "Integer Long Number Object Short String StringBuffer StringBuilder Void"), + blockKeywords: words("catch class do else finally for if switch try while"), + defKeywords: words("class interface enum @interface"), + typeFirstDefinitions: true, + atoms: words("true false null"), + number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, + hooks: { + "@": function(stream) { + // Don't match the @interface keyword. + if (stream.match('interface', false)) return false; + + stream.eatWhile(/[\w\$_]/); + return "meta"; + } + }, + modeProps: {fold: ["brace", "import"]} + }); + + def("text/x-csharp", { + name: "clike", + keywords: words("abstract as async await base break case catch checked class const continue" + + " default delegate do else enum event explicit extern finally fixed for" + + " foreach goto if implicit in interface internal is lock namespace new" + + " operator out override params private protected public readonly ref return sealed" + + " sizeof stackalloc static struct switch this throw try typeof unchecked" + + " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + + " global group into join let orderby partial remove select set value var yield"), + types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" + + " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" + + " UInt64 bool byte char decimal double short int long object" + + " sbyte float string ushort uint ulong"), + blockKeywords: words("catch class do else finally for foreach if struct switch try while"), + defKeywords: words("class interface namespace struct var"), + typeFirstDefinitions: true, + atoms: words("true false null"), + hooks: { + "@": function(stream, state) { + if (stream.eat('"')) { + state.tokenize = tokenAtString; + return tokenAtString(stream, state); + } + stream.eatWhile(/[\w\$_]/); + return "meta"; + } + } + }); + + function tokenTripleString(stream, state) { + var escaped = false; + while (!stream.eol()) { + if (!escaped && stream.match('"""')) { + state.tokenize = null; + break; + } + escaped = stream.next() == "\\" && !escaped; + } + return "string"; + } + + def("text/x-scala", { + name: "clike", + keywords: words( + + /* scala */ + "abstract case catch class def do else extends final finally for forSome if " + + "implicit import lazy match new null object override package private protected return " + + "sealed super this throw trait try type val var while with yield _ " + + + /* package scala */ + "assert assume require print println printf readLine readBoolean readByte readShort " + + "readChar readInt readLong readFloat readDouble" + ), + types: words( + "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " + + "Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " + + "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " + + "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " + + "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " + + + /* package java.lang */ + "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + + "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + + "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + + "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" + ), + multiLineStrings: true, + blockKeywords: words("catch class enum do else finally for forSome if match switch try while"), + defKeywords: words("class enum def object package trait type val var"), + atoms: words("true false null"), + indentStatements: false, + indentSwitch: false, + isOperatorChar: /[+\-*&%=<>!?|\/#:@]/, + hooks: { + "@": function(stream) { + stream.eatWhile(/[\w\$_]/); + return "meta"; + }, + '"': function(stream, state) { + if (!stream.match('""')) return false; + state.tokenize = tokenTripleString; + return state.tokenize(stream, state); + }, + "'": function(stream) { + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + return "atom"; + }, + "=": function(stream, state) { + var cx = state.context + if (cx.type == "}" && cx.align && stream.eat(">")) { + state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev) + return "operator" + } else { + return false + } + } + }, + modeProps: {closeBrackets: {triples: '"'}} + }); + + function tokenKotlinString(tripleString){ + return function (stream, state) { + var escaped = false, next, end = false; + while (!stream.eol()) { + if (!tripleString && !escaped && stream.match('"') ) {end = true; break;} + if (tripleString && stream.match('"""')) {end = true; break;} + next = stream.next(); + if(!escaped && next == "$" && stream.match('{')) + stream.skipTo("}"); + escaped = !escaped && next == "\\" && !tripleString; + } + if (end || !tripleString) + state.tokenize = null; + return "string"; + } + } + + def("text/x-kotlin", { + name: "clike", + keywords: words( + /*keywords*/ + "package as typealias class interface this super val " + + "var fun for is in This throw return " + + "break continue object if else while do try when !in !is as? " + + + /*soft keywords*/ + "file import where by get set abstract enum open inner override private public internal " + + "protected catch finally out final vararg reified dynamic companion constructor init " + + "sealed field property receiver param sparam lateinit data inline noinline tailrec " + + "external annotation crossinline const operator infix suspend" + ), + types: words( + /* package java.lang */ + "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + + "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + + "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + + "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" + ), + intendSwitch: false, + indentStatements: false, + multiLineStrings: true, + number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, + blockKeywords: words("catch class do else finally for if where try while enum"), + defKeywords: words("class val var object interface fun"), + atoms: words("true false null this"), + hooks: { + '"': function(stream, state) { + state.tokenize = tokenKotlinString(stream.match('""')); + return state.tokenize(stream, state); + } + }, + modeProps: {closeBrackets: {triples: '"'}} + }); + + def(["x-shader/x-vertex", "x-shader/x-fragment"], { + name: "clike", + keywords: words("sampler1D sampler2D sampler3D samplerCube " + + "sampler1DShadow sampler2DShadow " + + "const attribute uniform varying " + + "break continue discard return " + + "for while do if else struct " + + "in out inout"), + types: words("float int bool void " + + "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " + + "mat2 mat3 mat4"), + blockKeywords: words("for while do if else struct"), + builtin: words("radians degrees sin cos tan asin acos atan " + + "pow exp log exp2 sqrt inversesqrt " + + "abs sign floor ceil fract mod min max clamp mix step smoothstep " + + "length distance dot cross normalize ftransform faceforward " + + "reflect refract matrixCompMult " + + "lessThan lessThanEqual greaterThan greaterThanEqual " + + "equal notEqual any all not " + + "texture1D texture1DProj texture1DLod texture1DProjLod " + + "texture2D texture2DProj texture2DLod texture2DProjLod " + + "texture3D texture3DProj texture3DLod texture3DProjLod " + + "textureCube textureCubeLod " + + "shadow1D shadow2D shadow1DProj shadow2DProj " + + "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " + + "dFdx dFdy fwidth " + + "noise1 noise2 noise3 noise4"), + atoms: words("true false " + + "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " + + "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " + + "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " + + "gl_FogCoord gl_PointCoord " + + "gl_Position gl_PointSize gl_ClipVertex " + + "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " + + "gl_TexCoord gl_FogFragCoord " + + "gl_FragCoord gl_FrontFacing " + + "gl_FragData gl_FragDepth " + + "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " + + "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " + + "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " + + "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " + + "gl_ProjectionMatrixInverseTranspose " + + "gl_ModelViewProjectionMatrixInverseTranspose " + + "gl_TextureMatrixInverseTranspose " + + "gl_NormalScale gl_DepthRange gl_ClipPlane " + + "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " + + "gl_FrontLightModelProduct gl_BackLightModelProduct " + + "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " + + "gl_FogParameters " + + "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " + + "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " + + "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " + + "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " + + "gl_MaxDrawBuffers"), + indentSwitch: false, + hooks: {"#": cppHook}, + modeProps: {fold: ["brace", "include"]} + }); + + def("text/x-nesc", { + name: "clike", + keywords: words(cKeywords + "as atomic async call command component components configuration event generic " + + "implementation includes interface module new norace nx_struct nx_union post provides " + + "signal task uses abstract extends"), + types: words(cTypes), + blockKeywords: words("case do else for if switch while struct"), + atoms: words("null true false"), + hooks: {"#": cppHook}, + modeProps: {fold: ["brace", "include"]} + }); + + def("text/x-objectivec", { + name: "clike", + keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in " + + "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"), + types: words(cTypes), + atoms: words("YES NO NULL NILL ON OFF true false"), + hooks: { + "@": function(stream) { + stream.eatWhile(/[\w\$]/); + return "keyword"; + }, + "#": cppHook, + indent: function(_state, ctx, textAfter) { + if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented + } + }, + modeProps: {fold: "brace"} + }); + + def("text/x-squirrel", { + name: "clike", + keywords: words("base break clone continue const default delete enum extends function in class" + + " foreach local resume return this throw typeof yield constructor instanceof static"), + types: words(cTypes), + blockKeywords: words("case catch class else for foreach if switch try while"), + defKeywords: words("function local class"), + typeFirstDefinitions: true, + atoms: words("true false null"), + hooks: {"#": cppHook}, + modeProps: {fold: ["brace", "include"]} + }); + + // Ceylon Strings need to deal with interpolation + var stringTokenizer = null; + function tokenCeylonString(type) { + return function(stream, state) { + var escaped = false, next, end = false; + while (!stream.eol()) { + if (!escaped && stream.match('"') && + (type == "single" || stream.match('""'))) { + end = true; + break; + } + if (!escaped && stream.match('``')) { + stringTokenizer = tokenCeylonString(type); + end = true; + break; + } + next = stream.next(); + escaped = type == "single" && !escaped && next == "\\"; + } + if (end) + state.tokenize = null; + return "string"; + } + } + + def("text/x-ceylon", { + name: "clike", + keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" + + " exists extends finally for function given if import in interface is let module new" + + " nonempty object of out outer package return satisfies super switch then this throw" + + " try value void while"), + types: function(word) { + // In Ceylon all identifiers that start with an uppercase are types + var first = word.charAt(0); + return (first === first.toUpperCase() && first !== first.toLowerCase()); + }, + blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"), + defKeywords: words("class dynamic function interface module object package value"), + builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" + + " native optional sealed see serializable shared suppressWarnings tagged throws variable"), + isPunctuationChar: /[\[\]{}\(\),;\:\.`]/, + isOperatorChar: /[+\-*&%=<>!?|^~:\/]/, + numberStart: /[\d#$]/, + number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i, + multiLineStrings: true, + typeFirstDefinitions: true, + atoms: words("true false null larger smaller equal empty finished"), + indentSwitch: false, + styleDefs: false, + hooks: { + "@": function(stream) { + stream.eatWhile(/[\w\$_]/); + return "meta"; + }, + '"': function(stream, state) { + state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single"); + return state.tokenize(stream, state); + }, + '`': function(stream, state) { + if (!stringTokenizer || !stream.match('`')) return false; + state.tokenize = stringTokenizer; + stringTokenizer = null; + return state.tokenize(stream, state); + }, + "'": function(stream) { + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + return "atom"; + }, + token: function(_stream, state, style) { + if ((style == "variable" || style == "type") && + state.prevToken == ".") { + return "variable-2"; + } + } + }, + modeProps: { + fold: ["brace", "import"], + closeBrackets: {triples: '"'} + } + }); + +}); diff --git a/backend/webif/static/codemirror/mode/clike/index.html b/backend/webif/static/codemirror/mode/clike/index.html new file mode 100755 index 000000000..45c670ae5 --- /dev/null +++ b/backend/webif/static/codemirror/mode/clike/index.html @@ -0,0 +1,360 @@ + + +CodeMirror: C-like mode + + + + + + + + + + + + +
+

C-like mode

+ +
+ +

C++ example

+ +
+ +

Objective-C example

+ +
+ +

Java example

+ +
+ +

Scala example

+ +
+ +

Kotlin mode

+ +
+ +

Ceylon mode

+ +
+ + + +

Simple mode that tries to handle C-like languages as well as it + can. Takes two configuration parameters: keywords, an + object whose property names are the keywords in the language, + and useCPP, which determines whether C preprocessor + directives are recognized.

+ +

MIME types defined: text/x-csrc + (C), text/x-c++src (C++), text/x-java + (Java), text/x-csharp (C#), + text/x-objectivec (Objective-C), + text/x-scala (Scala), text/x-vertex + x-shader/x-fragment (shader programs), + text/x-squirrel (Squirrel) and + text/x-ceylon (Ceylon)

+
diff --git a/backend/webif/static/codemirror/mode/clike/scala.html b/backend/webif/static/codemirror/mode/clike/scala.html new file mode 100755 index 000000000..aa04cf0f0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/clike/scala.html @@ -0,0 +1,767 @@ + + +CodeMirror: Scala mode + + + + + + + + + + +
+

Scala mode

+
+ +
+ + +
diff --git a/backend/webif/static/codemirror/mode/clike/test.js b/backend/webif/static/codemirror/mode/clike/test.js new file mode 100755 index 000000000..dad2e246a --- /dev/null +++ b/backend/webif/static/codemirror/mode/clike/test.js @@ -0,0 +1,59 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("indent", + "[type void] [def foo]([type void*] [variable a], [type int] [variable b]) {", + " [type int] [variable c] [operator =] [variable b] [operator +]", + " [number 1];", + " [keyword return] [operator *][variable a];", + "}"); + + MT("indent_switch", + "[keyword switch] ([variable x]) {", + " [keyword case] [number 10]:", + " [keyword return] [number 20];", + " [keyword default]:", + " [variable printf]([string \"foo %c\"], [variable x]);", + "}"); + + MT("def", + "[type void] [def foo]() {}", + "[keyword struct] [def bar]{}", + "[type int] [type *][def baz]() {}"); + + MT("def_new_line", + "::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]", + "[def SomeLongMethodNameThatDoesntFitIntoOneLine]([keyword const] [variable MyType][operator &] [variable param]) {}") + + MT("double_block", + "[keyword for] (;;)", + " [keyword for] (;;)", + " [variable x][operator ++];", + "[keyword return];"); + + MT("preprocessor", + "[meta #define FOO 3]", + "[type int] [variable foo];", + "[meta #define BAR\\]", + "[meta 4]", + "[type unsigned] [type int] [variable bar] [operator =] [number 8];", + "[meta #include ][comment // comment]") + + + var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src"); + function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); } + + MTCPP("cpp14_literal", + "[number 10'000];", + "[number 0b10'000];", + "[number 0x10'000];", + "[string '100000'];"); + + MTCPP("ctor_dtor", + "[def Foo::Foo]() {}", + "[def Foo::~Foo]() {}"); +})(); diff --git a/backend/webif/static/codemirror/mode/clojure/clojure.js b/backend/webif/static/codemirror/mode/clojure/clojure.js new file mode 100755 index 000000000..ed6af2c83 --- /dev/null +++ b/backend/webif/static/codemirror/mode/clojure/clojure.js @@ -0,0 +1,306 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Author: Hans Engel + * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun) + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("clojure", function (options) { + var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2", + ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable"; + var INDENT_WORD_SKIP = options.indentUnit || 2; + var NORMAL_INDENT_UNIT = options.indentUnit || 2; + + function makeKeywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var atoms = makeKeywords("true false nil"); + + var keywords = makeKeywords( + "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest " + + "slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn " + + "do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync " + + "doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars " + + "binding gen-class gen-and-load-class gen-and-save-class handler-case handle"); + + var builtins = makeKeywords( + "* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* " + + "*compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* " + + "*math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* " + + "*source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> " + + "->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor " + + "aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! " + + "alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double " + + "aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 " + + "bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set " + + "bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast " + + "byte byte-array bytes case cat cast char char-array char-escape-string char-name-string char? chars chunk chunk-append " + + "chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors " + + "clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement completing concat cond condp " + + "conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? " + + "declare dedupe default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol " + + "defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc " + + "dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last " + + "drop-while eduction empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info " + + "extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword " + + "find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? " + + "fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? " + + "gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash " + + "hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? " + + "int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep " + + "keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file " + + "load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array " + + "make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods " + + "min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty " + + "not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias " + + "ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all " + + "partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers " + + "primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str " + + "prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues " + + "quot rand rand-int rand-nth random-sample range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern " + + "re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history " + + "ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods " + + "remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest " + + "restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? " + + "seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts " + + "shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? " + + "special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol " + + "symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transduce " + + "transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec " + + "unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int " + + "unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int "+ + "unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote " + + "unquote-splicing update update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of " + + "vector? volatile! volatile? vreset! vswap! when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context " + + "with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap " + + "*default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! " + + "set-agent-send-off-executor! some-> some->>"); + + var indentKeys = makeKeywords( + // Built-ins + "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto " + + "locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type " + + "try catch " + + + // Binding forms + "let letfn binding loop for doseq dotimes when-let if-let " + + + // Data structures + "defstruct struct-map assoc " + + + // clojure.test + "testing deftest " + + + // contrib + "handler-case handle dotrace deftrace"); + + var tests = { + digit: /\d/, + digit_or_colon: /[\d:]/, + hex: /[0-9a-f]/i, + sign: /[+-]/, + exponent: /e/i, + keyword_char: /[^\s\(\[\;\)\]]/, + symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/, + block_indent: /^(?:def|with)[^\/]+$|\/(?:def|with)/ + }; + + function stateStack(indent, type, prev) { // represents a state stack object + this.indent = indent; + this.type = type; + this.prev = prev; + } + + function pushStack(state, indent, type) { + state.indentStack = new stateStack(indent, type, state.indentStack); + } + + function popStack(state) { + state.indentStack = state.indentStack.prev; + } + + function isNumber(ch, stream){ + // hex + if ( ch === '0' && stream.eat(/x/i) ) { + stream.eatWhile(tests.hex); + return true; + } + + // leading sign + if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) { + stream.eat(tests.sign); + ch = stream.next(); + } + + if ( tests.digit.test(ch) ) { + stream.eat(ch); + stream.eatWhile(tests.digit); + + if ( '.' == stream.peek() ) { + stream.eat('.'); + stream.eatWhile(tests.digit); + } else if ('/' == stream.peek() ) { + stream.eat('/'); + stream.eatWhile(tests.digit); + } + + if ( stream.eat(tests.exponent) ) { + stream.eat(tests.sign); + stream.eatWhile(tests.digit); + } + + return true; + } + + return false; + } + + // Eat character that starts after backslash \ + function eatCharacter(stream) { + var first = stream.next(); + // Read special literals: backspace, newline, space, return. + // Just read all lowercase letters. + if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) { + return; + } + // Read unicode character: \u1000 \uA0a1 + if (first === "u") { + stream.match(/[0-9a-z]{4}/i, true); + } + } + + return { + startState: function () { + return { + indentStack: null, + indentation: 0, + mode: false + }; + }, + + token: function (stream, state) { + if (state.indentStack == null && stream.sol()) { + // update indentation, but only if indentStack is empty + state.indentation = stream.indentation(); + } + + // skip spaces + if (state.mode != "string" && stream.eatSpace()) { + return null; + } + var returnType = null; + + switch(state.mode){ + case "string": // multi-line string parsing mode + var next, escaped = false; + while ((next = stream.next()) != null) { + if (next == "\"" && !escaped) { + + state.mode = false; + break; + } + escaped = !escaped && next == "\\"; + } + returnType = STRING; // continue on in string mode + break; + default: // default parsing mode + var ch = stream.next(); + + if (ch == "\"") { + state.mode = "string"; + returnType = STRING; + } else if (ch == "\\") { + eatCharacter(stream); + returnType = CHARACTER; + } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) { + returnType = ATOM; + } else if (ch == ";") { // comment + stream.skipToEnd(); // rest of the line is a comment + returnType = COMMENT; + } else if (isNumber(ch,stream)){ + returnType = NUMBER; + } else if (ch == "(" || ch == "[" || ch == "{" ) { + var keyWord = '', indentTemp = stream.column(), letter; + /** + Either + (indent-word .. + (non-indent-word .. + (;something else, bracket, etc. + */ + + if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) { + keyWord += letter; + } + + if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) || + tests.block_indent.test(keyWord))) { // indent-word + pushStack(state, indentTemp + INDENT_WORD_SKIP, ch); + } else { // non-indent word + // we continue eating the spaces + stream.eatSpace(); + if (stream.eol() || stream.peek() == ";") { + // nothing significant after + // we restart indentation the user defined spaces after + pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch); + } else { + pushStack(state, indentTemp + stream.current().length, ch); // else we match + } + } + stream.backUp(stream.current().length - 1); // undo all the eating + + returnType = BRACKET; + } else if (ch == ")" || ch == "]" || ch == "}") { + returnType = BRACKET; + if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) { + popStack(state); + } + } else if ( ch == ":" ) { + stream.eatWhile(tests.symbol); + return ATOM; + } else { + stream.eatWhile(tests.symbol); + + if (keywords && keywords.propertyIsEnumerable(stream.current())) { + returnType = KEYWORD; + } else if (builtins && builtins.propertyIsEnumerable(stream.current())) { + returnType = BUILTIN; + } else if (atoms && atoms.propertyIsEnumerable(stream.current())) { + returnType = ATOM; + } else { + returnType = VAR; + } + } + } + + return returnType; + }, + + indent: function (state) { + if (state.indentStack == null) return state.indentation; + return state.indentStack.indent; + }, + + closeBrackets: {pairs: "()[]{}\"\""}, + lineComment: ";;" + }; +}); + +CodeMirror.defineMIME("text/x-clojure", "clojure"); +CodeMirror.defineMIME("text/x-clojurescript", "clojure"); +CodeMirror.defineMIME("application/edn", "clojure"); + +}); diff --git a/backend/webif/static/codemirror/mode/clojure/index.html b/backend/webif/static/codemirror/mode/clojure/index.html new file mode 100755 index 000000000..81294bc14 --- /dev/null +++ b/backend/webif/static/codemirror/mode/clojure/index.html @@ -0,0 +1,91 @@ + + +CodeMirror: Clojure mode + + + + + + + + + +
+

Clojure mode

+
+ + +

MIME types defined: text/x-clojure.

+ +
diff --git a/backend/webif/static/codemirror/mode/cmake/cmake.js b/backend/webif/static/codemirror/mode/cmake/cmake.js new file mode 100755 index 000000000..9f9eda541 --- /dev/null +++ b/backend/webif/static/codemirror/mode/cmake/cmake.js @@ -0,0 +1,97 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) + define(["../../lib/codemirror"], mod); + else + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("cmake", function () { + var variable_regex = /({)?[a-zA-Z0-9_]+(})?/; + + function tokenString(stream, state) { + var current, prev, found_var = false; + while (!stream.eol() && (current = stream.next()) != state.pending) { + if (current === '$' && prev != '\\' && state.pending == '"') { + found_var = true; + break; + } + prev = current; + } + if (found_var) { + stream.backUp(1); + } + if (current == state.pending) { + state.continueString = false; + } else { + state.continueString = true; + } + return "string"; + } + + function tokenize(stream, state) { + var ch = stream.next(); + + // Have we found a variable? + if (ch === '$') { + if (stream.match(variable_regex)) { + return 'variable-2'; + } + return 'variable'; + } + // Should we still be looking for the end of a string? + if (state.continueString) { + // If so, go through the loop again + stream.backUp(1); + return tokenString(stream, state); + } + // Do we just have a function on our hands? + // In 'cmake_minimum_required (VERSION 2.8.8)', 'cmake_minimum_required' is matched + if (stream.match(/(\s+)?\w+\(/) || stream.match(/(\s+)?\w+\ \(/)) { + stream.backUp(1); + return 'def'; + } + if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + // Have we found a string? + if (ch == "'" || ch == '"') { + // Store the type (single or double) + state.pending = ch; + // Perform the looping function to find the end + return tokenString(stream, state); + } + if (ch == '(' || ch == ')') { + return 'bracket'; + } + if (ch.match(/[0-9]/)) { + return 'number'; + } + stream.eatWhile(/[\w-]/); + return null; + } + return { + startState: function () { + var state = {}; + state.inDefinition = false; + state.inInclude = false; + state.continueString = false; + state.pending = false; + return state; + }, + token: function (stream, state) { + if (stream.eatSpace()) return null; + return tokenize(stream, state); + } + }; +}); + +CodeMirror.defineMIME("text/x-cmake", "cmake"); + +}); diff --git a/backend/webif/static/codemirror/mode/cmake/index.html b/backend/webif/static/codemirror/mode/cmake/index.html new file mode 100755 index 000000000..ed114fece --- /dev/null +++ b/backend/webif/static/codemirror/mode/cmake/index.html @@ -0,0 +1,129 @@ + + +CodeMirror: CMake mode + + + + + + + + + + +
+

CMake mode

+
+ + +

MIME types defined: text/x-cmake.

+ +
diff --git a/backend/webif/static/codemirror/mode/cobol/cobol.js b/backend/webif/static/codemirror/mode/cobol/cobol.js new file mode 100755 index 000000000..897022b18 --- /dev/null +++ b/backend/webif/static/codemirror/mode/cobol/cobol.js @@ -0,0 +1,255 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Author: Gautam Mehta + * Branched from CodeMirror's Scheme mode + */ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("cobol", function () { + var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", + ATOM = "atom", NUMBER = "number", KEYWORD = "keyword", MODTAG = "header", + COBOLLINENUM = "def", PERIOD = "link"; + function makeKeywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var atoms = makeKeywords("TRUE FALSE ZEROES ZEROS ZERO SPACES SPACE LOW-VALUE LOW-VALUES "); + var keywords = makeKeywords( + "ACCEPT ACCESS ACQUIRE ADD ADDRESS " + + "ADVANCING AFTER ALIAS ALL ALPHABET " + + "ALPHABETIC ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED " + + "ALSO ALTER ALTERNATE AND ANY " + + "ARE AREA AREAS ARITHMETIC ASCENDING " + + "ASSIGN AT ATTRIBUTE AUTHOR AUTO " + + "AUTO-SKIP AUTOMATIC B-AND B-EXOR B-LESS " + + "B-NOT B-OR BACKGROUND-COLOR BACKGROUND-COLOUR BEEP " + + "BEFORE BELL BINARY BIT BITS " + + "BLANK BLINK BLOCK BOOLEAN BOTTOM " + + "BY CALL CANCEL CD CF " + + "CH CHARACTER CHARACTERS CLASS CLOCK-UNITS " + + "CLOSE COBOL CODE CODE-SET COL " + + "COLLATING COLUMN COMMA COMMIT COMMITMENT " + + "COMMON COMMUNICATION COMP COMP-0 COMP-1 " + + "COMP-2 COMP-3 COMP-4 COMP-5 COMP-6 " + + "COMP-7 COMP-8 COMP-9 COMPUTATIONAL COMPUTATIONAL-0 " + + "COMPUTATIONAL-1 COMPUTATIONAL-2 COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 " + + "COMPUTATIONAL-6 COMPUTATIONAL-7 COMPUTATIONAL-8 COMPUTATIONAL-9 COMPUTE " + + "CONFIGURATION CONNECT CONSOLE CONTAINED CONTAINS " + + "CONTENT CONTINUE CONTROL CONTROL-AREA CONTROLS " + + "CONVERTING COPY CORR CORRESPONDING COUNT " + + "CRT CRT-UNDER CURRENCY CURRENT CURSOR " + + "DATA DATE DATE-COMPILED DATE-WRITTEN DAY " + + "DAY-OF-WEEK DB DB-ACCESS-CONTROL-KEY DB-DATA-NAME DB-EXCEPTION " + + "DB-FORMAT-NAME DB-RECORD-NAME DB-SET-NAME DB-STATUS DBCS " + + "DBCS-EDITED DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE " + + "DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING " + + "DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED " + + "DELIMITER DEPENDING DESCENDING DESCRIBED DESTINATION " + + "DETAIL DISABLE DISCONNECT DISPLAY DISPLAY-1 " + + "DISPLAY-2 DISPLAY-3 DISPLAY-4 DISPLAY-5 DISPLAY-6 " + + "DISPLAY-7 DISPLAY-8 DISPLAY-9 DIVIDE DIVISION " + + "DOWN DROP DUPLICATE DUPLICATES DYNAMIC " + + "EBCDIC EGI EJECT ELSE EMI " + + "EMPTY EMPTY-CHECK ENABLE END END. END-ACCEPT END-ACCEPT. " + + "END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY " + + "END-DIVIDE END-EVALUATE END-IF END-INVOKE END-MULTIPLY " + + "END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN " + + "END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT " + + "END-UNSTRING END-WRITE END-XML ENTER ENTRY " + + "ENVIRONMENT EOP EQUAL EQUALS ERASE " + + "ERROR ESI EVALUATE EVERY EXCEEDS " + + "EXCEPTION EXCLUSIVE EXIT EXTEND EXTERNAL " + + "EXTERNALLY-DESCRIBED-KEY FD FETCH FILE FILE-CONTROL " + + "FILE-STREAM FILES FILLER FINAL FIND " + + "FINISH FIRST FOOTING FOR FOREGROUND-COLOR " + + "FOREGROUND-COLOUR FORMAT FREE FROM FULL " + + "FUNCTION GENERATE GET GIVING GLOBAL " + + "GO GOBACK GREATER GROUP HEADING " + + "HIGH-VALUE HIGH-VALUES HIGHLIGHT I-O I-O-CONTROL " + + "ID IDENTIFICATION IF IN INDEX " + + "INDEX-1 INDEX-2 INDEX-3 INDEX-4 INDEX-5 " + + "INDEX-6 INDEX-7 INDEX-8 INDEX-9 INDEXED " + + "INDIC INDICATE INDICATOR INDICATORS INITIAL " + + "INITIALIZE INITIATE INPUT INPUT-OUTPUT INSPECT " + + "INSTALLATION INTO INVALID INVOKE IS " + + "JUST JUSTIFIED KANJI KEEP KEY " + + "LABEL LAST LD LEADING LEFT " + + "LEFT-JUSTIFY LENGTH LENGTH-CHECK LESS LIBRARY " + + "LIKE LIMIT LIMITS LINAGE LINAGE-COUNTER " + + "LINE LINE-COUNTER LINES LINKAGE LOCAL-STORAGE " + + "LOCALE LOCALLY LOCK " + + "MEMBER MEMORY MERGE MESSAGE METACLASS " + + "MODE MODIFIED MODIFY MODULES MOVE " + + "MULTIPLE MULTIPLY NATIONAL NATIVE NEGATIVE " + + "NEXT NO NO-ECHO NONE NOT " + + "NULL NULL-KEY-MAP NULL-MAP NULLS NUMBER " + + "NUMERIC NUMERIC-EDITED OBJECT OBJECT-COMPUTER OCCURS " + + "OF OFF OMITTED ON ONLY " + + "OPEN OPTIONAL OR ORDER ORGANIZATION " + + "OTHER OUTPUT OVERFLOW OWNER PACKED-DECIMAL " + + "PADDING PAGE PAGE-COUNTER PARSE PERFORM " + + "PF PH PIC PICTURE PLUS " + + "POINTER POSITION POSITIVE PREFIX PRESENT " + + "PRINTING PRIOR PROCEDURE PROCEDURE-POINTER PROCEDURES " + + "PROCEED PROCESS PROCESSING PROGRAM PROGRAM-ID " + + "PROMPT PROTECTED PURGE QUEUE QUOTE " + + "QUOTES RANDOM RD READ READY " + + "REALM RECEIVE RECONNECT RECORD RECORD-NAME " + + "RECORDS RECURSIVE REDEFINES REEL REFERENCE " + + "REFERENCE-MONITOR REFERENCES RELATION RELATIVE RELEASE " + + "REMAINDER REMOVAL RENAMES REPEATED REPLACE " + + "REPLACING REPORT REPORTING REPORTS REPOSITORY " + + "REQUIRED RERUN RESERVE RESET RETAINING " + + "RETRIEVAL RETURN RETURN-CODE RETURNING REVERSE-VIDEO " + + "REVERSED REWIND REWRITE RF RH " + + "RIGHT RIGHT-JUSTIFY ROLLBACK ROLLING ROUNDED " + + "RUN SAME SCREEN SD SEARCH " + + "SECTION SECURE SECURITY SEGMENT SEGMENT-LIMIT " + + "SELECT SEND SENTENCE SEPARATE SEQUENCE " + + "SEQUENTIAL SET SHARED SIGN SIZE " + + "SKIP1 SKIP2 SKIP3 SORT SORT-MERGE " + + "SORT-RETURN SOURCE SOURCE-COMPUTER SPACE-FILL " + + "SPECIAL-NAMES STANDARD STANDARD-1 STANDARD-2 " + + "START STARTING STATUS STOP STORE " + + "STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUB-SCHEMA " + + "SUBFILE SUBSTITUTE SUBTRACT SUM SUPPRESS " + + "SYMBOLIC SYNC SYNCHRONIZED SYSIN SYSOUT " + + "TABLE TALLYING TAPE TENANT TERMINAL " + + "TERMINATE TEST TEXT THAN THEN " + + "THROUGH THRU TIME TIMES TITLE " + + "TO TOP TRAILING TRAILING-SIGN TRANSACTION " + + "TYPE TYPEDEF UNDERLINE UNEQUAL UNIT " + + "UNSTRING UNTIL UP UPDATE UPON " + + "USAGE USAGE-MODE USE USING VALID " + + "VALIDATE VALUE VALUES VARYING VLR " + + "WAIT WHEN WHEN-COMPILED WITH WITHIN " + + "WORDS WORKING-STORAGE WRITE XML XML-CODE " + + "XML-EVENT XML-NTEXT XML-TEXT ZERO ZERO-FILL " ); + + var builtins = makeKeywords("- * ** / + < <= = > >= "); + var tests = { + digit: /\d/, + digit_or_colon: /[\d:]/, + hex: /[0-9a-f]/i, + sign: /[+-]/, + exponent: /e/i, + keyword_char: /[^\s\(\[\;\)\]]/, + symbol: /[\w*+\-]/ + }; + function isNumber(ch, stream){ + // hex + if ( ch === '0' && stream.eat(/x/i) ) { + stream.eatWhile(tests.hex); + return true; + } + // leading sign + if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) { + stream.eat(tests.sign); + ch = stream.next(); + } + if ( tests.digit.test(ch) ) { + stream.eat(ch); + stream.eatWhile(tests.digit); + if ( '.' == stream.peek()) { + stream.eat('.'); + stream.eatWhile(tests.digit); + } + if ( stream.eat(tests.exponent) ) { + stream.eat(tests.sign); + stream.eatWhile(tests.digit); + } + return true; + } + return false; + } + return { + startState: function () { + return { + indentStack: null, + indentation: 0, + mode: false + }; + }, + token: function (stream, state) { + if (state.indentStack == null && stream.sol()) { + // update indentation, but only if indentStack is empty + state.indentation = 6 ; //stream.indentation(); + } + // skip spaces + if (stream.eatSpace()) { + return null; + } + var returnType = null; + switch(state.mode){ + case "string": // multi-line string parsing mode + var next = false; + while ((next = stream.next()) != null) { + if (next == "\"" || next == "\'") { + state.mode = false; + break; + } + } + returnType = STRING; // continue on in string mode + break; + default: // default parsing mode + var ch = stream.next(); + var col = stream.column(); + if (col >= 0 && col <= 5) { + returnType = COBOLLINENUM; + } else if (col >= 72 && col <= 79) { + stream.skipToEnd(); + returnType = MODTAG; + } else if (ch == "*" && col == 6) { // comment + stream.skipToEnd(); // rest of the line is a comment + returnType = COMMENT; + } else if (ch == "\"" || ch == "\'") { + state.mode = "string"; + returnType = STRING; + } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) { + returnType = ATOM; + } else if (ch == ".") { + returnType = PERIOD; + } else if (isNumber(ch,stream)){ + returnType = NUMBER; + } else { + if (stream.current().match(tests.symbol)) { + while (col < 71) { + if (stream.eat(tests.symbol) === undefined) { + break; + } else { + col++; + } + } + } + if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) { + returnType = KEYWORD; + } else if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) { + returnType = BUILTIN; + } else if (atoms && atoms.propertyIsEnumerable(stream.current().toUpperCase())) { + returnType = ATOM; + } else returnType = null; + } + } + return returnType; + }, + indent: function (state) { + if (state.indentStack == null) return state.indentation; + return state.indentStack.indent; + } + }; +}); + +CodeMirror.defineMIME("text/x-cobol", "cobol"); + +}); diff --git a/backend/webif/static/codemirror/mode/cobol/index.html b/backend/webif/static/codemirror/mode/cobol/index.html new file mode 100755 index 000000000..4352419a0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/cobol/index.html @@ -0,0 +1,210 @@ + + +CodeMirror: COBOL mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

COBOL mode

+ +

Select Theme Select Font Size + + + + +

+ + +
diff --git a/backend/webif/static/codemirror/mode/coffeescript/coffeescript.js b/backend/webif/static/codemirror/mode/coffeescript/coffeescript.js new file mode 100755 index 000000000..ae955db34 --- /dev/null +++ b/backend/webif/static/codemirror/mode/coffeescript/coffeescript.js @@ -0,0 +1,359 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Link to the project's GitHub page: + * https://github.com/pickhardt/coffeescript-codemirror-mode + */ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("coffeescript", function(conf, parserConf) { + var ERRORCLASS = "error"; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/; + var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/; + var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/; + var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/; + + var wordOperators = wordRegexp(["and", "or", "not", + "is", "isnt", "in", + "instanceof", "typeof"]); + var indentKeywords = ["for", "while", "loop", "if", "unless", "else", + "switch", "try", "catch", "finally", "class"]; + var commonKeywords = ["break", "by", "continue", "debugger", "delete", + "do", "in", "of", "new", "return", "then", + "this", "@", "throw", "when", "until", "extends"]; + + var keywords = wordRegexp(indentKeywords.concat(commonKeywords)); + + indentKeywords = wordRegexp(indentKeywords); + + + var stringPrefixes = /^('{3}|\"{3}|['\"])/; + var regexPrefixes = /^(\/{3}|\/)/; + var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"]; + var constants = wordRegexp(commonConstants); + + // Tokenizers + function tokenBase(stream, state) { + // Handle scope changes + if (stream.sol()) { + if (state.scope.align === null) state.scope.align = false; + var scopeOffset = state.scope.offset; + if (stream.eatSpace()) { + var lineOffset = stream.indentation(); + if (lineOffset > scopeOffset && state.scope.type == "coffee") { + return "indent"; + } else if (lineOffset < scopeOffset) { + return "dedent"; + } + return null; + } else { + if (scopeOffset > 0) { + dedent(stream, state); + } + } + } + if (stream.eatSpace()) { + return null; + } + + var ch = stream.peek(); + + // Handle docco title comment (single line) + if (stream.match("####")) { + stream.skipToEnd(); + return "comment"; + } + + // Handle multi line comments + if (stream.match("###")) { + state.tokenize = longComment; + return state.tokenize(stream, state); + } + + // Single line comment + if (ch === "#") { + stream.skipToEnd(); + return "comment"; + } + + // Handle number literals + if (stream.match(/^-?[0-9\.]/, false)) { + var floatLiteral = false; + // Floats + if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) { + floatLiteral = true; + } + if (stream.match(/^-?\d+\.\d*/)) { + floatLiteral = true; + } + if (stream.match(/^-?\.\d+/)) { + floatLiteral = true; + } + + if (floatLiteral) { + // prevent from getting extra . on 1.. + if (stream.peek() == "."){ + stream.backUp(1); + } + return "number"; + } + // Integers + var intLiteral = false; + // Hex + if (stream.match(/^-?0x[0-9a-f]+/i)) { + intLiteral = true; + } + // Decimal + if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) { + intLiteral = true; + } + // Zero by itself with no other piece of number. + if (stream.match(/^-?0(?![\dx])/i)) { + intLiteral = true; + } + if (intLiteral) { + return "number"; + } + } + + // Handle strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenFactory(stream.current(), false, "string"); + return state.tokenize(stream, state); + } + // Handle regex literals + if (stream.match(regexPrefixes)) { + if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division + state.tokenize = tokenFactory(stream.current(), true, "string-2"); + return state.tokenize(stream, state); + } else { + stream.backUp(1); + } + } + + + + // Handle operators and delimiters + if (stream.match(operators) || stream.match(wordOperators)) { + return "operator"; + } + if (stream.match(delimiters)) { + return "punctuation"; + } + + if (stream.match(constants)) { + return "atom"; + } + + if (stream.match(atProp) || state.prop && stream.match(identifiers)) { + return "property"; + } + + if (stream.match(keywords)) { + return "keyword"; + } + + if (stream.match(identifiers)) { + return "variable"; + } + + // Handle non-detected items + stream.next(); + return ERRORCLASS; + } + + function tokenFactory(delimiter, singleline, outclass) { + return function(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"\/\\]/); + if (stream.eat("\\")) { + stream.next(); + if (singleline && stream.eol()) { + return outclass; + } + } else if (stream.match(delimiter)) { + state.tokenize = tokenBase; + return outclass; + } else { + stream.eat(/['"\/]/); + } + } + if (singleline) { + if (parserConf.singleLineStringErrors) { + outclass = ERRORCLASS; + } else { + state.tokenize = tokenBase; + } + } + return outclass; + }; + } + + function longComment(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^#]/); + if (stream.match("###")) { + state.tokenize = tokenBase; + break; + } + stream.eatWhile("#"); + } + return "comment"; + } + + function indent(stream, state, type) { + type = type || "coffee"; + var offset = 0, align = false, alignOffset = null; + for (var scope = state.scope; scope; scope = scope.prev) { + if (scope.type === "coffee" || scope.type == "}") { + offset = scope.offset + conf.indentUnit; + break; + } + } + if (type !== "coffee") { + align = null; + alignOffset = stream.column() + stream.current().length; + } else if (state.scope.align) { + state.scope.align = false; + } + state.scope = { + offset: offset, + type: type, + prev: state.scope, + align: align, + alignOffset: alignOffset + }; + } + + function dedent(stream, state) { + if (!state.scope.prev) return; + if (state.scope.type === "coffee") { + var _indent = stream.indentation(); + var matched = false; + for (var scope = state.scope; scope; scope = scope.prev) { + if (_indent === scope.offset) { + matched = true; + break; + } + } + if (!matched) { + return true; + } + while (state.scope.prev && state.scope.offset !== _indent) { + state.scope = state.scope.prev; + } + return false; + } else { + state.scope = state.scope.prev; + return false; + } + } + + function tokenLexer(stream, state) { + var style = state.tokenize(stream, state); + var current = stream.current(); + + // Handle scope changes. + if (current === "return") { + state.dedent = true; + } + if (((current === "->" || current === "=>") && stream.eol()) + || style === "indent") { + indent(stream, state); + } + var delimiter_index = "[({".indexOf(current); + if (delimiter_index !== -1) { + indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); + } + if (indentKeywords.exec(current)){ + indent(stream, state); + } + if (current == "then"){ + dedent(stream, state); + } + + + if (style === "dedent") { + if (dedent(stream, state)) { + return ERRORCLASS; + } + } + delimiter_index = "])}".indexOf(current); + if (delimiter_index !== -1) { + while (state.scope.type == "coffee" && state.scope.prev) + state.scope = state.scope.prev; + if (state.scope.type == current) + state.scope = state.scope.prev; + } + if (state.dedent && stream.eol()) { + if (state.scope.type == "coffee" && state.scope.prev) + state.scope = state.scope.prev; + state.dedent = false; + } + + return style; + } + + var external = { + startState: function(basecolumn) { + return { + tokenize: tokenBase, + scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false}, + prop: false, + dedent: 0 + }; + }, + + token: function(stream, state) { + var fillAlign = state.scope.align === null && state.scope; + if (fillAlign && stream.sol()) fillAlign.align = false; + + var style = tokenLexer(stream, state); + if (style && style != "comment") { + if (fillAlign) fillAlign.align = true; + state.prop = style == "punctuation" && stream.current() == "." + } + + return style; + }, + + indent: function(state, text) { + if (state.tokenize != tokenBase) return 0; + var scope = state.scope; + var closer = text && "])}".indexOf(text.charAt(0)) > -1; + if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev; + var closes = closer && scope.type === text.charAt(0); + if (scope.align) + return scope.alignOffset - (closes ? 1 : 0); + else + return (closes ? scope.prev : scope).offset; + }, + + lineComment: "#", + fold: "indent" + }; + return external; +}); + +// IANA registered media type +// https://www.iana.org/assignments/media-types/ +CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript"); + +CodeMirror.defineMIME("text/x-coffeescript", "coffeescript"); +CodeMirror.defineMIME("text/coffeescript", "coffeescript"); + +}); diff --git a/backend/webif/static/codemirror/mode/coffeescript/index.html b/backend/webif/static/codemirror/mode/coffeescript/index.html new file mode 100755 index 000000000..92d161e9d --- /dev/null +++ b/backend/webif/static/codemirror/mode/coffeescript/index.html @@ -0,0 +1,740 @@ + + +CodeMirror: CoffeeScript mode + + + + + + + + + +
+

CoffeeScript mode

+
+ + +

MIME types defined: application/vnd.coffeescript, text/coffeescript, text/x-coffeescript.

+ +

The CoffeeScript mode was written by Jeff Pickhardt.

+ +
diff --git a/backend/webif/static/codemirror/mode/commonlisp/commonlisp.js b/backend/webif/static/codemirror/mode/commonlisp/commonlisp.js new file mode 100755 index 000000000..8cd212d3a --- /dev/null +++ b/backend/webif/static/codemirror/mode/commonlisp/commonlisp.js @@ -0,0 +1,124 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("commonlisp", function (config) { + var specialForm = /^(block|let*|return-from|catch|load-time-value|setq|eval-when|locally|symbol-macrolet|flet|macrolet|tagbody|function|multiple-value-call|the|go|multiple-value-prog1|throw|if|progn|unwind-protect|labels|progv|let|quote)$/; + var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/; + var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/; + var symbol = /[^\s'`,@()\[\]";]/; + var type; + + function readSym(stream) { + var ch; + while (ch = stream.next()) { + if (ch == "\\") stream.next(); + else if (!symbol.test(ch)) { stream.backUp(1); break; } + } + return stream.current(); + } + + function base(stream, state) { + if (stream.eatSpace()) {type = "ws"; return null;} + if (stream.match(numLiteral)) return "number"; + var ch = stream.next(); + if (ch == "\\") ch = stream.next(); + + if (ch == '"') return (state.tokenize = inString)(stream, state); + else if (ch == "(") { type = "open"; return "bracket"; } + else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; } + else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; } + else if (/['`,@]/.test(ch)) return null; + else if (ch == "|") { + if (stream.skipTo("|")) { stream.next(); return "symbol"; } + else { stream.skipToEnd(); return "error"; } + } else if (ch == "#") { + var ch = stream.next(); + if (ch == "(") { type = "open"; return "bracket"; } + else if (/[+\-=\.']/.test(ch)) return null; + else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null; + else if (ch == "|") return (state.tokenize = inComment)(stream, state); + else if (ch == ":") { readSym(stream); return "meta"; } + else if (ch == "\\") { stream.next(); readSym(stream); return "string-2" } + else return "error"; + } else { + var name = readSym(stream); + if (name == ".") return null; + type = "symbol"; + if (name == "nil" || name == "t" || name.charAt(0) == ":") return "atom"; + if (state.lastType == "open" && (specialForm.test(name) || assumeBody.test(name))) return "keyword"; + if (name.charAt(0) == "&") return "variable-2"; + return "variable"; + } + } + + function inString(stream, state) { + var escaped = false, next; + while (next = stream.next()) { + if (next == '"' && !escaped) { state.tokenize = base; break; } + escaped = !escaped && next == "\\"; + } + return "string"; + } + + function inComment(stream, state) { + var next, last; + while (next = stream.next()) { + if (next == "#" && last == "|") { state.tokenize = base; break; } + last = next; + } + type = "ws"; + return "comment"; + } + + return { + startState: function () { + return {ctx: {prev: null, start: 0, indentTo: 0}, lastType: null, tokenize: base}; + }, + + token: function (stream, state) { + if (stream.sol() && typeof state.ctx.indentTo != "number") + state.ctx.indentTo = state.ctx.start + 1; + + type = null; + var style = state.tokenize(stream, state); + if (type != "ws") { + if (state.ctx.indentTo == null) { + if (type == "symbol" && assumeBody.test(stream.current())) + state.ctx.indentTo = state.ctx.start + config.indentUnit; + else + state.ctx.indentTo = "next"; + } else if (state.ctx.indentTo == "next") { + state.ctx.indentTo = stream.column(); + } + state.lastType = type; + } + if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null}; + else if (type == "close") state.ctx = state.ctx.prev || state.ctx; + return style; + }, + + indent: function (state, _textAfter) { + var i = state.ctx.indentTo; + return typeof i == "number" ? i : state.ctx.start + 1; + }, + + closeBrackets: {pairs: "()[]{}\"\""}, + lineComment: ";;", + blockCommentStart: "#|", + blockCommentEnd: "|#" + }; +}); + +CodeMirror.defineMIME("text/x-common-lisp", "commonlisp"); + +}); diff --git a/backend/webif/static/codemirror/mode/commonlisp/index.html b/backend/webif/static/codemirror/mode/commonlisp/index.html new file mode 100755 index 000000000..f2bf4522d --- /dev/null +++ b/backend/webif/static/codemirror/mode/commonlisp/index.html @@ -0,0 +1,177 @@ + + +CodeMirror: Common Lisp mode + + + + + + + + + +
+

Common Lisp mode

+
+ + +

MIME types defined: text/x-common-lisp.

+ +
diff --git a/backend/webif/static/codemirror/mode/crystal/crystal.js b/backend/webif/static/codemirror/mode/crystal/crystal.js new file mode 100755 index 000000000..dada112da --- /dev/null +++ b/backend/webif/static/codemirror/mode/crystal/crystal.js @@ -0,0 +1,433 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("crystal", function(config) { + function wordRegExp(words, end) { + return new RegExp((end ? "" : "^") + "(?:" + words.join("|") + ")" + (end ? "$" : "\\b")); + } + + function chain(tokenize, stream, state) { + state.tokenize.push(tokenize); + return tokenize(stream, state); + } + + var operators = /^(?:[-+/%|&^]|\*\*?|[<>]{2})/; + var conditionalOperators = /^(?:[=!]~|===|<=>|[<>=!]=?|[|&]{2}|~)/; + var indexingOperators = /^(?:\[\][?=]?)/; + var anotherOperators = /^(?:\.(?:\.{2})?|->|[?:])/; + var idents = /^[a-z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/; + var types = /^[A-Z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/; + var keywords = wordRegExp([ + "abstract", "alias", "as", "asm", "begin", "break", "case", "class", "def", "do", + "else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if", + "include", "instance_sizeof", "lib", "macro", "module", "next", "of", "out", "pointerof", + "private", "protected", "rescue", "return", "require", "select", "sizeof", "struct", + "super", "then", "type", "typeof", "uninitialized", "union", "unless", "until", "when", "while", "with", + "yield", "__DIR__", "__END_LINE__", "__FILE__", "__LINE__" + ]); + var atomWords = wordRegExp(["true", "false", "nil", "self"]); + var indentKeywordsArray = [ + "def", "fun", "macro", + "class", "module", "struct", "lib", "enum", "union", + "do", "for" + ]; + var indentKeywords = wordRegExp(indentKeywordsArray); + var indentExpressionKeywordsArray = ["if", "unless", "case", "while", "until", "begin", "then"]; + var indentExpressionKeywords = wordRegExp(indentExpressionKeywordsArray); + var dedentKeywordsArray = ["end", "else", "elsif", "rescue", "ensure"]; + var dedentKeywords = wordRegExp(dedentKeywordsArray); + var dedentPunctualsArray = ["\\)", "\\}", "\\]"]; + var dedentPunctuals = new RegExp("^(?:" + dedentPunctualsArray.join("|") + ")$"); + var nextTokenizer = { + "def": tokenFollowIdent, "fun": tokenFollowIdent, "macro": tokenMacroDef, + "class": tokenFollowType, "module": tokenFollowType, "struct": tokenFollowType, + "lib": tokenFollowType, "enum": tokenFollowType, "union": tokenFollowType + }; + var matching = {"[": "]", "{": "}", "(": ")", "<": ">"}; + + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return null; + } + + // Macros + if (state.lastToken != "\\" && stream.match("{%", false)) { + return chain(tokenMacro("%", "%"), stream, state); + } + + if (state.lastToken != "\\" && stream.match("{{", false)) { + return chain(tokenMacro("{", "}"), stream, state); + } + + // Comments + if (stream.peek() == "#") { + stream.skipToEnd(); + return "comment"; + } + + // Variables and keywords + var matched; + if (stream.match(idents)) { + stream.eat(/[?!]/); + + matched = stream.current(); + if (stream.eat(":")) { + return "atom"; + } else if (state.lastToken == ".") { + return "property"; + } else if (keywords.test(matched)) { + if (indentKeywords.test(matched)) { + if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0) && !(matched == "def" && state.lastToken == "abstract")) { + state.blocks.push(matched); + state.currentIndent += 1; + } + } else if ((state.lastStyle == "operator" || !state.lastStyle) && indentExpressionKeywords.test(matched)) { + state.blocks.push(matched); + state.currentIndent += 1; + } else if (matched == "end") { + state.blocks.pop(); + state.currentIndent -= 1; + } + + if (nextTokenizer.hasOwnProperty(matched)) { + state.tokenize.push(nextTokenizer[matched]); + } + + return "keyword"; + } else if (atomWords.test(matched)) { + return "atom"; + } + + return "variable"; + } + + // Class variables and instance variables + // or attributes + if (stream.eat("@")) { + if (stream.peek() == "[") { + return chain(tokenNest("[", "]", "meta"), stream, state); + } + + stream.eat("@"); + stream.match(idents) || stream.match(types); + return "variable-2"; + } + + // Constants and types + if (stream.match(types)) { + return "tag"; + } + + // Symbols or ':' operator + if (stream.eat(":")) { + if (stream.eat("\"")) { + return chain(tokenQuote("\"", "atom", false), stream, state); + } else if (stream.match(idents) || stream.match(types) || + stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators)) { + return "atom"; + } + stream.eat(":"); + return "operator"; + } + + // Strings + if (stream.eat("\"")) { + return chain(tokenQuote("\"", "string", true), stream, state); + } + + // Strings or regexps or macro variables or '%' operator + if (stream.peek() == "%") { + var style = "string"; + var embed = true; + var delim; + + if (stream.match("%r")) { + // Regexps + style = "string-2"; + delim = stream.next(); + } else if (stream.match("%w")) { + embed = false; + delim = stream.next(); + } else if (stream.match("%q")) { + embed = false; + delim = stream.next(); + } else { + if(delim = stream.match(/^%([^\w\s=])/)) { + delim = delim[1]; + } else if (stream.match(/^%[a-zA-Z0-9_\u009F-\uFFFF]*/)) { + // Macro variables + return "meta"; + } else { + // '%' operator + return "operator"; + } + } + + if (matching.hasOwnProperty(delim)) { + delim = matching[delim]; + } + return chain(tokenQuote(delim, style, embed), stream, state); + } + + // Here Docs + if (matched = stream.match(/^<<-('?)([A-Z]\w*)\1/)) { + return chain(tokenHereDoc(matched[2], !matched[1]), stream, state) + } + + // Characters + if (stream.eat("'")) { + stream.match(/^(?:[^']|\\(?:[befnrtv0'"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\{[0-9a-fA-F]{1,6}\})))/); + stream.eat("'"); + return "atom"; + } + + // Numbers + if (stream.eat("0")) { + if (stream.eat("x")) { + stream.match(/^[0-9a-fA-F]+/); + } else if (stream.eat("o")) { + stream.match(/^[0-7]+/); + } else if (stream.eat("b")) { + stream.match(/^[01]+/); + } + return "number"; + } + + if (stream.eat(/^\d/)) { + stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/); + return "number"; + } + + // Operators + if (stream.match(operators)) { + stream.eat("="); // Operators can follow assign symbol. + return "operator"; + } + + if (stream.match(conditionalOperators) || stream.match(anotherOperators)) { + return "operator"; + } + + // Parens and braces + if (matched = stream.match(/[({[]/, false)) { + matched = matched[0]; + return chain(tokenNest(matched, matching[matched], null), stream, state); + } + + // Escapes + if (stream.eat("\\")) { + stream.next(); + return "meta"; + } + + stream.next(); + return null; + } + + function tokenNest(begin, end, style, started) { + return function (stream, state) { + if (!started && stream.match(begin)) { + state.tokenize[state.tokenize.length - 1] = tokenNest(begin, end, style, true); + state.currentIndent += 1; + return style; + } + + var nextStyle = tokenBase(stream, state); + if (stream.current() === end) { + state.tokenize.pop(); + state.currentIndent -= 1; + nextStyle = style; + } + + return nextStyle; + }; + } + + function tokenMacro(begin, end, started) { + return function (stream, state) { + if (!started && stream.match("{" + begin)) { + state.currentIndent += 1; + state.tokenize[state.tokenize.length - 1] = tokenMacro(begin, end, true); + return "meta"; + } + + if (stream.match(end + "}")) { + state.currentIndent -= 1; + state.tokenize.pop(); + return "meta"; + } + + return tokenBase(stream, state); + }; + } + + function tokenMacroDef(stream, state) { + if (stream.eatSpace()) { + return null; + } + + var matched; + if (matched = stream.match(idents)) { + if (matched == "def") { + return "keyword"; + } + stream.eat(/[?!]/); + } + + state.tokenize.pop(); + return "def"; + } + + function tokenFollowIdent(stream, state) { + if (stream.eatSpace()) { + return null; + } + + if (stream.match(idents)) { + stream.eat(/[!?]/); + } else { + stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators); + } + state.tokenize.pop(); + return "def"; + } + + function tokenFollowType(stream, state) { + if (stream.eatSpace()) { + return null; + } + + stream.match(types); + state.tokenize.pop(); + return "def"; + } + + function tokenQuote(end, style, embed) { + return function (stream, state) { + var escaped = false; + + while (stream.peek()) { + if (!escaped) { + if (stream.match("{%", false)) { + state.tokenize.push(tokenMacro("%", "%")); + return style; + } + + if (stream.match("{{", false)) { + state.tokenize.push(tokenMacro("{", "}")); + return style; + } + + if (embed && stream.match("#{", false)) { + state.tokenize.push(tokenNest("#{", "}", "meta")); + return style; + } + + var ch = stream.next(); + + if (ch == end) { + state.tokenize.pop(); + return style; + } + + escaped = embed && ch == "\\"; + } else { + stream.next(); + escaped = false; + } + } + + return style; + }; + } + + function tokenHereDoc(phrase, embed) { + return function (stream, state) { + if (stream.sol()) { + stream.eatSpace() + if (stream.match(phrase)) { + state.tokenize.pop(); + return "string"; + } + } + + var escaped = false; + while (stream.peek()) { + if (!escaped) { + if (stream.match("{%", false)) { + state.tokenize.push(tokenMacro("%", "%")); + return "string"; + } + + if (stream.match("{{", false)) { + state.tokenize.push(tokenMacro("{", "}")); + return "string"; + } + + if (embed && stream.match("#{", false)) { + state.tokenize.push(tokenNest("#{", "}", "meta")); + return "string"; + } + + escaped = embed && stream.next() == "\\"; + } else { + stream.next(); + escaped = false; + } + } + + return "string"; + } + } + + return { + startState: function () { + return { + tokenize: [tokenBase], + currentIndent: 0, + lastToken: null, + lastStyle: null, + blocks: [] + }; + }, + + token: function (stream, state) { + var style = state.tokenize[state.tokenize.length - 1](stream, state); + var token = stream.current(); + + if (style && style != "comment") { + state.lastToken = token; + state.lastStyle = style; + } + + return style; + }, + + indent: function (state, textAfter) { + textAfter = textAfter.replace(/^\s*(?:\{%)?\s*|\s*(?:%\})?\s*$/g, ""); + + if (dedentKeywords.test(textAfter) || dedentPunctuals.test(textAfter)) { + return config.indentUnit * (state.currentIndent - 1); + } + + return config.indentUnit * state.currentIndent; + }, + + fold: "indent", + electricInput: wordRegExp(dedentPunctualsArray.concat(dedentKeywordsArray), true), + lineComment: '#' + }; + }); + + CodeMirror.defineMIME("text/x-crystal", "crystal"); +}); diff --git a/backend/webif/static/codemirror/mode/crystal/index.html b/backend/webif/static/codemirror/mode/crystal/index.html new file mode 100755 index 000000000..95412579f --- /dev/null +++ b/backend/webif/static/codemirror/mode/crystal/index.html @@ -0,0 +1,116 @@ + + +CodeMirror: Crystal mode + + + + + + + + + + + +
+

Crystal mode

+
+ + +

MIME types defined: text/x-crystal.

+
diff --git a/backend/webif/static/codemirror/mode/css/css.js b/backend/webif/static/codemirror/mode/css/css.js new file mode 100755 index 000000000..00e9b3df1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/css.js @@ -0,0 +1,832 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("css", function(config, parserConfig) { + var inline = parserConfig.inline + if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); + + var indentUnit = config.indentUnit, + tokenHooks = parserConfig.tokenHooks, + documentTypes = parserConfig.documentTypes || {}, + mediaTypes = parserConfig.mediaTypes || {}, + mediaFeatures = parserConfig.mediaFeatures || {}, + mediaValueKeywords = parserConfig.mediaValueKeywords || {}, + propertyKeywords = parserConfig.propertyKeywords || {}, + nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {}, + fontProperties = parserConfig.fontProperties || {}, + counterDescriptors = parserConfig.counterDescriptors || {}, + colorKeywords = parserConfig.colorKeywords || {}, + valueKeywords = parserConfig.valueKeywords || {}, + allowNested = parserConfig.allowNested, + lineComment = parserConfig.lineComment, + supportsAtComponent = parserConfig.supportsAtComponent === true; + + var type, override; + function ret(style, tp) { type = tp; return style; } + + // Tokenizers + + function tokenBase(stream, state) { + var ch = stream.next(); + if (tokenHooks[ch]) { + var result = tokenHooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == "@") { + stream.eatWhile(/[\w\\\-]/); + return ret("def", stream.current()); + } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) { + return ret(null, "compare"); + } else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "#") { + stream.eatWhile(/[\w\\\-]/); + return ret("atom", "hash"); + } else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("keyword", "important"); + } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (ch === "-") { + if (/[\d.]/.test(stream.peek())) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (stream.match(/^-[\w\\\-]+/)) { + stream.eatWhile(/[\w\\\-]/); + if (stream.match(/^\s*:/, false)) + return ret("variable-2", "variable-definition"); + return ret("variable-2", "variable"); + } else if (stream.match(/^\w+-/)) { + return ret("meta", "meta"); + } + } else if (/[,+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { + return ret("qualifier", "qualifier"); + } else if (/[:;{}\[\]\(\)]/.test(ch)) { + return ret(null, ch); + } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || + (ch == "d" && stream.match("omain(")) || + (ch == "r" && stream.match("egexp("))) { + stream.backUp(1); + state.tokenize = tokenParenthesized; + return ret("property", "word"); + } else if (/[\w\\\-]/.test(ch)) { + stream.eatWhile(/[\w\\\-]/); + return ret("property", "word"); + } else { + return ret(null, null); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + if (quote == ")") stream.backUp(1); + break; + } + escaped = !escaped && ch == "\\"; + } + if (ch == quote || !escaped && quote != ")") state.tokenize = null; + return ret("string", "string"); + }; + } + + function tokenParenthesized(stream, state) { + stream.next(); // Must be '(' + if (!stream.match(/\s*[\"\')]/, false)) + state.tokenize = tokenString(")"); + else + state.tokenize = null; + return ret(null, "("); + } + + // Context management + + function Context(type, indent, prev) { + this.type = type; + this.indent = indent; + this.prev = prev; + } + + function pushContext(state, stream, type, indent) { + state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context); + return type; + } + + function popContext(state) { + if (state.context.prev) + state.context = state.context.prev; + return state.context.type; + } + + function pass(type, stream, state) { + return states[state.context.type](type, stream, state); + } + function popAndPass(type, stream, state, n) { + for (var i = n || 1; i > 0; i--) + state.context = state.context.prev; + return pass(type, stream, state); + } + + // Parser + + function wordAsValue(stream) { + var word = stream.current().toLowerCase(); + if (valueKeywords.hasOwnProperty(word)) + override = "atom"; + else if (colorKeywords.hasOwnProperty(word)) + override = "keyword"; + else + override = "variable"; + } + + var states = {}; + + states.top = function(type, stream, state) { + if (type == "{") { + return pushContext(state, stream, "block"); + } else if (type == "}" && state.context.prev) { + return popContext(state); + } else if (supportsAtComponent && /@component/.test(type)) { + return pushContext(state, stream, "atComponentBlock"); + } else if (/^@(-moz-)?document$/.test(type)) { + return pushContext(state, stream, "documentTypes"); + } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { + return pushContext(state, stream, "atBlock"); + } else if (/^@(font-face|counter-style)/.test(type)) { + state.stateArg = type; + return "restricted_atBlock_before"; + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + return "keyframes"; + } else if (type && type.charAt(0) == "@") { + return pushContext(state, stream, "at"); + } else if (type == "hash") { + override = "builtin"; + } else if (type == "word") { + override = "tag"; + } else if (type == "variable-definition") { + return "maybeprop"; + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } else if (type == ":") { + return "pseudo"; + } else if (allowNested && type == "(") { + return pushContext(state, stream, "parens"); + } + return state.context.type; + }; + + states.block = function(type, stream, state) { + if (type == "word") { + var word = stream.current().toLowerCase(); + if (propertyKeywords.hasOwnProperty(word)) { + override = "property"; + return "maybeprop"; + } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { + override = "string-2"; + return "maybeprop"; + } else if (allowNested) { + override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; + return "block"; + } else { + override += " error"; + return "maybeprop"; + } + } else if (type == "meta") { + return "block"; + } else if (!allowNested && (type == "hash" || type == "qualifier")) { + override = "error"; + return "block"; + } else { + return states.top(type, stream, state); + } + }; + + states.maybeprop = function(type, stream, state) { + if (type == ":") return pushContext(state, stream, "prop"); + return pass(type, stream, state); + }; + + states.prop = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" && allowNested) return pushContext(state, stream, "propBlock"); + if (type == "}" || type == "{") return popAndPass(type, stream, state); + if (type == "(") return pushContext(state, stream, "parens"); + + if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) { + override += " error"; + } else if (type == "word") { + wordAsValue(stream); + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } + return "prop"; + }; + + states.propBlock = function(type, _stream, state) { + if (type == "}") return popContext(state); + if (type == "word") { override = "property"; return "maybeprop"; } + return state.context.type; + }; + + states.parens = function(type, stream, state) { + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == ")") return popContext(state); + if (type == "(") return pushContext(state, stream, "parens"); + if (type == "interpolation") return pushContext(state, stream, "interpolation"); + if (type == "word") wordAsValue(stream); + return "parens"; + }; + + states.pseudo = function(type, stream, state) { + if (type == "meta") return "pseudo"; + + if (type == "word") { + override = "variable-3"; + return state.context.type; + } + return pass(type, stream, state); + }; + + states.documentTypes = function(type, stream, state) { + if (type == "word" && documentTypes.hasOwnProperty(stream.current())) { + override = "tag"; + return state.context.type; + } else { + return states.atBlock(type, stream, state); + } + }; + + states.atBlock = function(type, stream, state) { + if (type == "(") return pushContext(state, stream, "atBlock_parens"); + if (type == "}" || type == ";") return popAndPass(type, stream, state); + if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top"); + + if (type == "interpolation") return pushContext(state, stream, "interpolation"); + + if (type == "word") { + var word = stream.current().toLowerCase(); + if (word == "only" || word == "not" || word == "and" || word == "or") + override = "keyword"; + else if (mediaTypes.hasOwnProperty(word)) + override = "attribute"; + else if (mediaFeatures.hasOwnProperty(word)) + override = "property"; + else if (mediaValueKeywords.hasOwnProperty(word)) + override = "keyword"; + else if (propertyKeywords.hasOwnProperty(word)) + override = "property"; + else if (nonStandardPropertyKeywords.hasOwnProperty(word)) + override = "string-2"; + else if (valueKeywords.hasOwnProperty(word)) + override = "atom"; + else if (colorKeywords.hasOwnProperty(word)) + override = "keyword"; + else + override = "error"; + } + return state.context.type; + }; + + states.atComponentBlock = function(type, stream, state) { + if (type == "}") + return popAndPass(type, stream, state); + if (type == "{") + return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false); + if (type == "word") + override = "error"; + return state.context.type; + }; + + states.atBlock_parens = function(type, stream, state) { + if (type == ")") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state, 2); + return states.atBlock(type, stream, state); + }; + + states.restricted_atBlock_before = function(type, stream, state) { + if (type == "{") + return pushContext(state, stream, "restricted_atBlock"); + if (type == "word" && state.stateArg == "@counter-style") { + override = "variable"; + return "restricted_atBlock_before"; + } + return pass(type, stream, state); + }; + + states.restricted_atBlock = function(type, stream, state) { + if (type == "}") { + state.stateArg = null; + return popContext(state); + } + if (type == "word") { + if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) || + (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase()))) + override = "error"; + else + override = "property"; + return "maybeprop"; + } + return "restricted_atBlock"; + }; + + states.keyframes = function(type, stream, state) { + if (type == "word") { override = "variable"; return "keyframes"; } + if (type == "{") return pushContext(state, stream, "top"); + return pass(type, stream, state); + }; + + states.at = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == "word") override = "tag"; + else if (type == "hash") override = "builtin"; + return "at"; + }; + + states.interpolation = function(type, stream, state) { + if (type == "}") return popContext(state); + if (type == "{" || type == ";") return popAndPass(type, stream, state); + if (type == "word") override = "variable"; + else if (type != "variable" && type != "(" && type != ")") override = "error"; + return "interpolation"; + }; + + return { + startState: function(base) { + return {tokenize: null, + state: inline ? "block" : "top", + stateArg: null, + context: new Context(inline ? "block" : "top", base || 0, null)}; + }, + + token: function(stream, state) { + if (!state.tokenize && stream.eatSpace()) return null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style && typeof style == "object") { + type = style[1]; + style = style[0]; + } + override = style; + if (type != "comment") + state.state = states[state.state](type, stream, state); + return override; + }, + + indent: function(state, textAfter) { + var cx = state.context, ch = textAfter && textAfter.charAt(0); + var indent = cx.indent; + if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev; + if (cx.prev) { + if (ch == "}" && (cx.type == "block" || cx.type == "top" || + cx.type == "interpolation" || cx.type == "restricted_atBlock")) { + // Resume indentation from parent context. + cx = cx.prev; + indent = cx.indent; + } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") || + ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { + // Dedent relative to current context. + indent = Math.max(0, cx.indent - indentUnit); + } + } + return indent; + }, + + electricChars: "}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + blockCommentContinue: " * ", + lineComment: lineComment, + fold: "brace" + }; +}); + + function keySet(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) { + keys[array[i].toLowerCase()] = true; + } + return keys; + } + + var documentTypes_ = [ + "domain", "regexp", "url", "url-prefix" + ], documentTypes = keySet(documentTypes_); + + var mediaTypes_ = [ + "all", "aural", "braille", "handheld", "print", "projection", "screen", + "tty", "tv", "embossed" + ], mediaTypes = keySet(mediaTypes_); + + var mediaFeatures_ = [ + "width", "min-width", "max-width", "height", "min-height", "max-height", + "device-width", "min-device-width", "max-device-width", "device-height", + "min-device-height", "max-device-height", "aspect-ratio", + "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", + "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", + "max-color", "color-index", "min-color-index", "max-color-index", + "monochrome", "min-monochrome", "max-monochrome", "resolution", + "min-resolution", "max-resolution", "scan", "grid", "orientation", + "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", + "pointer", "any-pointer", "hover", "any-hover" + ], mediaFeatures = keySet(mediaFeatures_); + + var mediaValueKeywords_ = [ + "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", + "interlace", "progressive" + ], mediaValueKeywords = keySet(mediaValueKeywords_); + + var propertyKeywords_ = [ + "align-content", "align-items", "align-self", "alignment-adjust", + "alignment-baseline", "anchor-point", "animation", "animation-delay", + "animation-direction", "animation-duration", "animation-fill-mode", + "animation-iteration-count", "animation-name", "animation-play-state", + "animation-timing-function", "appearance", "azimuth", "backface-visibility", + "background", "background-attachment", "background-blend-mode", "background-clip", + "background-color", "background-image", "background-origin", "background-position", + "background-repeat", "background-size", "baseline-shift", "binding", + "bleed", "bookmark-label", "bookmark-level", "bookmark-state", + "bookmark-target", "border", "border-bottom", "border-bottom-color", + "border-bottom-left-radius", "border-bottom-right-radius", + "border-bottom-style", "border-bottom-width", "border-collapse", + "border-color", "border-image", "border-image-outset", + "border-image-repeat", "border-image-slice", "border-image-source", + "border-image-width", "border-left", "border-left-color", + "border-left-style", "border-left-width", "border-radius", "border-right", + "border-right-color", "border-right-style", "border-right-width", + "border-spacing", "border-style", "border-top", "border-top-color", + "border-top-left-radius", "border-top-right-radius", "border-top-style", + "border-top-width", "border-width", "bottom", "box-decoration-break", + "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", + "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count", + "column-fill", "column-gap", "column-rule", "column-rule-color", + "column-rule-style", "column-rule-width", "column-span", "column-width", + "columns", "content", "counter-increment", "counter-reset", "crop", "cue", + "cue-after", "cue-before", "cursor", "direction", "display", + "dominant-baseline", "drop-initial-after-adjust", + "drop-initial-after-align", "drop-initial-before-adjust", + "drop-initial-before-align", "drop-initial-size", "drop-initial-value", + "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", + "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", + "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", + "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", + "font-stretch", "font-style", "font-synthesis", "font-variant", + "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", + "font-variant-ligatures", "font-variant-numeric", "font-variant-position", + "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", + "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap", + "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap", + "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns", + "grid-template-rows", "hanging-punctuation", "height", "hyphens", + "icon", "image-orientation", "image-rendering", "image-resolution", + "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing", + "line-break", "line-height", "line-stacking", "line-stacking-ruby", + "line-stacking-shift", "line-stacking-strategy", "list-style", + "list-style-image", "list-style-position", "list-style-type", "margin", + "margin-bottom", "margin-left", "margin-right", "margin-top", + "marks", "marquee-direction", "marquee-loop", + "marquee-play-count", "marquee-speed", "marquee-style", "max-height", + "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", + "nav-left", "nav-right", "nav-up", "object-fit", "object-position", + "opacity", "order", "orphans", "outline", + "outline-color", "outline-offset", "outline-style", "outline-width", + "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", + "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", + "page", "page-break-after", "page-break-before", "page-break-inside", + "page-policy", "pause", "pause-after", "pause-before", "perspective", + "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position", + "presentation-level", "punctuation-trim", "quotes", "region-break-after", + "region-break-before", "region-break-inside", "region-fragment", + "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", + "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", + "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", + "shape-outside", "size", "speak", "speak-as", "speak-header", + "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", + "tab-size", "table-layout", "target", "target-name", "target-new", + "target-position", "text-align", "text-align-last", "text-decoration", + "text-decoration-color", "text-decoration-line", "text-decoration-skip", + "text-decoration-style", "text-emphasis", "text-emphasis-color", + "text-emphasis-position", "text-emphasis-style", "text-height", + "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", + "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", + "text-wrap", "top", "transform", "transform-origin", "transform-style", + "transition", "transition-delay", "transition-duration", + "transition-property", "transition-timing-function", "unicode-bidi", + "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration", + "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", + "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break", + "word-spacing", "word-wrap", "z-index", + // SVG-specific + "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", + "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", + "color-interpolation", "color-interpolation-filters", + "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", + "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", + "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", + "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", + "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", + "glyph-orientation-vertical", "text-anchor", "writing-mode" + ], propertyKeywords = keySet(propertyKeywords_); + + var nonStandardPropertyKeywords_ = [ + "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color", + "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", + "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", + "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", + "searchfield-results-decoration", "zoom" + ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); + + var fontProperties_ = [ + "font-family", "src", "unicode-range", "font-variant", "font-feature-settings", + "font-stretch", "font-weight", "font-style" + ], fontProperties = keySet(fontProperties_); + + var counterDescriptors_ = [ + "additive-symbols", "fallback", "negative", "pad", "prefix", "range", + "speak-as", "suffix", "symbols", "system" + ], counterDescriptors = keySet(counterDescriptors_); + + var colorKeywords_ = [ + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", + "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", + "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", + "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", + "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", + "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", + "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", + "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", + "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", + "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", + "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", + "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", + "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", + "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", + "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", + "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", + "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", + "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", + "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", + "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", + "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", + "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", + "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", + "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", + "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen" + ], colorKeywords = keySet(colorKeywords_); + + var valueKeywords_ = [ + "above", "absolute", "activeborder", "additive", "activecaption", "afar", + "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", + "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", + "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page", + "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", + "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", + "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", + "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", + "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", + "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", + "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", + "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", + "compact", "condensed", "contain", "content", "contents", + "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", + "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", + "decimal-leading-zero", "default", "default-button", "dense", "destination-atop", + "destination-in", "destination-out", "destination-over", "devanagari", "difference", + "disc", "discard", "disclosure-closed", "disclosure-open", "document", + "dot-dash", "dot-dot-dash", + "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", + "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", + "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", + "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", + "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", + "ethiopic-halehame-gez", "ethiopic-halehame-om-et", + "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", + "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", + "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", + "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", + "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove", + "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", + "help", "hidden", "hide", "higher", "highlight", "highlighttext", + "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", + "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", + "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", + "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert", + "italic", "japanese-formal", "japanese-informal", "justify", "kannada", + "katakana", "katakana-iroha", "keep-all", "khmer", + "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", + "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten", + "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem", + "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", + "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", + "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", + "media-controls-background", "media-current-time-display", + "media-fullscreen-button", "media-mute-button", "media-play-button", + "media-return-to-realtime-button", "media-rewind-button", + "media-seek-back-button", "media-seek-forward-button", "media-slider", + "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", + "media-volume-slider-container", "media-volume-sliderthumb", "medium", + "menu", "menulist", "menulist-button", "menulist-text", + "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", + "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize", + "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", + "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", + "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote", + "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", + "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", + "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter", + "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", + "progress", "push-button", "radial-gradient", "radio", "read-only", + "read-write", "read-write-plaintext-only", "rectangle", "region", + "relative", "repeat", "repeating-linear-gradient", + "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", + "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", + "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", + "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", + "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield", + "searchfield-cancel-button", "searchfield-decoration", + "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end", + "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", + "simp-chinese-formal", "simp-chinese-informal", "single", + "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", + "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", + "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", + "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square", + "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", + "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table", + "table-caption", "table-cell", "table-column", "table-column-group", + "table-footer-group", "table-header-group", "table-row", "table-row-group", + "tamil", + "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", + "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", + "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", + "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", + "trad-chinese-formal", "trad-chinese-informal", "transform", + "translate", "translate3d", "translateX", "translateY", "translateZ", + "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up", + "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", + "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", + "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", + "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", + "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", + "xx-large", "xx-small" + ], valueKeywords = keySet(valueKeywords_); + + var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_) + .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_) + .concat(valueKeywords_); + CodeMirror.registerHelper("hintWords", "css", allWords); + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return ["comment", "comment"]; + } + + CodeMirror.defineMIME("text/css", { + documentTypes: documentTypes, + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + fontProperties: fontProperties, + counterDescriptors: counterDescriptors, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + tokenHooks: { + "/": function(stream, state) { + if (!stream.eat("*")) return false; + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + }, + name: "css" + }); + + CodeMirror.defineMIME("text/x-scss", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + lineComment: "//", + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + ":": function(stream) { + if (stream.match(/\s*\{/, false)) + return [null, null] + return false; + }, + "$": function(stream) { + stream.match(/^[\w-]+/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "#": function(stream) { + if (!stream.eat("{")) return false; + return [null, "interpolation"]; + } + }, + name: "css", + helperType: "scss" + }); + + CodeMirror.defineMIME("text/x-less", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + lineComment: "//", + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + "@": function(stream) { + if (stream.eat("{")) return [null, "interpolation"]; + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; + stream.eatWhile(/[\w\\\-]/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "&": function() { + return ["atom", "atom"]; + } + }, + name: "css", + helperType: "less" + }); + + CodeMirror.defineMIME("text/x-gss", { + documentTypes: documentTypes, + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + fontProperties: fontProperties, + counterDescriptors: counterDescriptors, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + supportsAtComponent: true, + tokenHooks: { + "/": function(stream, state) { + if (!stream.eat("*")) return false; + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + }, + name: "css", + helperType: "gss" + }); + +}); diff --git a/backend/webif/static/codemirror/mode/css/gss.html b/backend/webif/static/codemirror/mode/css/gss.html new file mode 100755 index 000000000..232fe8c12 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/gss.html @@ -0,0 +1,103 @@ + + +CodeMirror: Closure Stylesheets (GSS) mode + + + + + + + + + + + + +
+

Closure Stylesheets (GSS) mode

+
+ + +

A mode for Closure Stylesheets (GSS).

+

MIME type defined: text/x-gss.

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/css/gss_test.js b/backend/webif/static/codemirror/mode/css/gss_test.js new file mode 100755 index 000000000..d56e59280 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/gss_test.js @@ -0,0 +1,17 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + "use strict"; + + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); } + + MT("atComponent", + "[def @component] {", + "[tag foo] {", + " [property color]: [keyword black];", + "}", + "}"); + +})(); diff --git a/backend/webif/static/codemirror/mode/css/index.html b/backend/webif/static/codemirror/mode/css/index.html new file mode 100755 index 000000000..0d85311f1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/index.html @@ -0,0 +1,75 @@ + + +CodeMirror: CSS mode + + + + + + + + + + + + +
+

CSS mode

+
+ + +

MIME types defined: text/css, text/x-scss (demo), text/x-less (demo).

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/css/less.html b/backend/webif/static/codemirror/mode/css/less.html new file mode 100755 index 000000000..adf7427d3 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/less.html @@ -0,0 +1,152 @@ + + +CodeMirror: LESS mode + + + + + + + + + + +
+

LESS mode

+
+ + +

The LESS mode is a sub-mode of the CSS mode (defined in css.js).

+ +

Parsing/Highlighting Tests: normal, verbose.

+
diff --git a/backend/webif/static/codemirror/mode/css/less_test.js b/backend/webif/static/codemirror/mode/css/less_test.js new file mode 100755 index 000000000..dd821558b --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/less_test.js @@ -0,0 +1,54 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + "use strict"; + + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); } + + MT("variable", + "[variable-2 @base]: [atom #f04615];", + "[qualifier .class] {", + " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]", + " [property color]: [variable saturate]([variable-2 @base], [number 5%]);", + "}"); + + MT("amp", + "[qualifier .child], [qualifier .sibling] {", + " [qualifier .parent] [atom &] {", + " [property color]: [keyword black];", + " }", + " [atom &] + [atom &] {", + " [property color]: [keyword red];", + " }", + "}"); + + MT("mixin", + "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", + " [property color]: [atom darken]([variable-2 @color], [number 10%]);", + "}", + "[qualifier .mixin] ([variable light]; [variable-2 @color]) {", + " [property color]: [atom lighten]([variable-2 @color], [number 10%]);", + "}", + "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {", + " [property display]: [atom block];", + "}", + "[variable-2 @switch]: [variable light];", + "[qualifier .class] {", + " [qualifier .mixin]([variable-2 @switch]; [atom #888]);", + "}"); + + MT("nest", + "[qualifier .one] {", + " [def @media] ([property width]: [number 400px]) {", + " [property font-size]: [number 1.2em];", + " [def @media] [attribute print] [keyword and] [property color] {", + " [property color]: [keyword blue];", + " }", + " }", + "}"); + + + MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }"); +})(); diff --git a/backend/webif/static/codemirror/mode/css/scss.html b/backend/webif/static/codemirror/mode/css/scss.html new file mode 100755 index 000000000..f8e4d3736 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/scss.html @@ -0,0 +1,157 @@ + + +CodeMirror: SCSS mode + + + + + + + + + +
+

SCSS mode

+
+ + +

The SCSS mode is a sub-mode of the CSS mode (defined in css.js).

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/css/scss_test.js b/backend/webif/static/codemirror/mode/css/scss_test.js new file mode 100755 index 000000000..785921b39 --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/scss_test.js @@ -0,0 +1,110 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } + + MT('url_with_quotation', + "[tag foo] { [property background]:[atom url]([string test.jpg]) }"); + + MT('url_with_double_quotes', + "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }"); + + MT('url_with_single_quotes', + "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }"); + + MT('string', + "[def @import] [string \"compass/css3\"]"); + + MT('important_keyword', + "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }"); + + MT('variable', + "[variable-2 $blue]:[atom #333]"); + + MT('variable_as_attribute', + "[tag foo] { [property color]:[variable-2 $blue] }"); + + MT('numbers', + "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }"); + + MT('number_percentage', + "[tag foo] { [property width]:[number 80%] }"); + + MT('selector', + "[builtin #hello][qualifier .world]{}"); + + MT('singleline_comment', + "[comment // this is a comment]"); + + MT('multiline_comment', + "[comment /*foobar*/]"); + + MT('attribute_with_hyphen', + "[tag foo] { [property font-size]:[number 10px] }"); + + MT('string_after_attribute', + "[tag foo] { [property content]:[string \"::\"] }"); + + MT('directives', + "[def @include] [qualifier .mixin]"); + + MT('basic_structure', + "[tag p] { [property background]:[keyword red]; }"); + + MT('nested_structure', + "[tag p] { [tag a] { [property color]:[keyword red]; } }"); + + MT('mixin', + "[def @mixin] [tag table-base] {}"); + + MT('number_without_semicolon', + "[tag p] {[property width]:[number 12]}", + "[tag a] {[property color]:[keyword red];}"); + + MT('atom_in_nested_block', + "[tag p] { [tag a] { [property color]:[atom #000]; } }"); + + MT('interpolation_in_property', + "[tag foo] { #{[variable-2 $hello]}:[number 2]; }"); + + MT('interpolation_in_selector', + "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }"); + + MT('interpolation_error', + "[tag foo]#{[variable foo]} { [property color]:[atom #000]; }"); + + MT("divide_operator", + "[tag foo] { [property width]:[number 4] [operator /] [number 2] }"); + + MT('nested_structure_with_id_selector', + "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }"); + + MT('indent_mixin', + "[def @mixin] [tag container] (", + " [variable-2 $a]: [number 10],", + " [variable-2 $b]: [number 10])", + "{}"); + + MT('indent_nested', + "[tag foo] {", + " [tag bar] {", + " }", + "}"); + + MT('indent_parentheses', + "[tag foo] {", + " [property color]: [atom darken]([variable-2 $blue],", + " [number 9%]);", + "}"); + + MT('indent_vardef', + "[variable-2 $name]:", + " [string 'val'];", + "[tag tag] {", + " [tag inner] {", + " [property margin]: [number 3px];", + " }", + "}"); +})(); diff --git a/backend/webif/static/codemirror/mode/css/test.js b/backend/webif/static/codemirror/mode/css/test.js new file mode 100755 index 000000000..6fc6e33ca --- /dev/null +++ b/backend/webif/static/codemirror/mode/css/test.js @@ -0,0 +1,206 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "css"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Error, because "foobarhello" is neither a known type or property, but + // property was expected (after "and"), and it should be in parentheses. + MT("atMediaUnknownType", + "[def @media] [attribute screen] [keyword and] [error foobarhello] { }"); + + // Soft error, because "foobarhello" is not a known property or type. + MT("atMediaUnknownProperty", + "[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }"); + + // Make sure nesting works with media queries + MT("atMediaMaxWidthNested", + "[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }"); + + MT("atMediaFeatureValueKeyword", + "[def @media] ([property orientation]: [keyword landscape]) { }"); + + MT("atMediaUnknownFeatureValueKeyword", + "[def @media] ([property orientation]: [error upsidedown]) { }"); + + MT("tagSelector", + "[tag foo] { }"); + + MT("classSelector", + "[qualifier .foo-bar_hello] { }"); + + MT("idSelector", + "[builtin #foo] { [error #foo] }"); + + MT("tagSelectorUnclosed", + "[tag foo] { [property margin]: [number 0] } [tag bar] { }"); + + MT("tagStringNoQuotes", + "[tag foo] { [property font-family]: [variable hello] [variable world]; }"); + + MT("tagStringDouble", + "[tag foo] { [property font-family]: [string \"hello world\"]; }"); + + MT("tagStringSingle", + "[tag foo] { [property font-family]: [string 'hello world']; }"); + + MT("tagColorKeyword", + "[tag foo] {", + " [property color]: [keyword black];", + " [property color]: [keyword navy];", + " [property color]: [keyword yellow];", + "}"); + + MT("tagColorHex3", + "[tag foo] { [property background]: [atom #fff]; }"); + + MT("tagColorHex4", + "[tag foo] { [property background]: [atom #ffff]; }"); + + MT("tagColorHex6", + "[tag foo] { [property background]: [atom #ffffff]; }"); + + MT("tagColorHex8", + "[tag foo] { [property background]: [atom #ffffffff]; }"); + + MT("tagColorHex5Invalid", + "[tag foo] { [property background]: [atom&error #fffff]; }"); + + MT("tagColorHexInvalid", + "[tag foo] { [property background]: [atom&error #ffg]; }"); + + MT("tagNegativeNumber", + "[tag foo] { [property margin]: [number -5px]; }"); + + MT("tagPositiveNumber", + "[tag foo] { [property padding]: [number 5px]; }"); + + MT("tagVendor", + "[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }"); + + MT("tagBogusProperty", + "[tag foo] { [property&error barhelloworld]: [number 0]; }"); + + MT("tagTwoProperties", + "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }"); + + MT("tagTwoPropertiesURL", + "[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }"); + + MT("indent_tagSelector", + "[tag strong], [tag em] {", + " [property background]: [atom rgba](", + " [number 255], [number 255], [number 0], [number .2]", + " );", + "}"); + + MT("indent_atMedia", + "[def @media] {", + " [tag foo] {", + " [property color]:", + " [keyword yellow];", + " }", + "}"); + + MT("indent_comma", + "[tag foo] {", + " [property font-family]: [variable verdana],", + " [atom sans-serif];", + "}"); + + MT("indent_parentheses", + "[tag foo]:[variable-3 before] {", + " [property background]: [atom url](", + "[string blahblah]", + "[string etc]", + "[string ]) [keyword !important];", + "}"); + + MT("font_face", + "[def @font-face] {", + " [property font-family]: [string 'myfont'];", + " [error nonsense]: [string 'abc'];", + " [property src]: [atom url]([string http://blah]),", + " [atom url]([string http://foo]);", + "}"); + + MT("empty_url", + "[def @import] [atom url]() [attribute screen];"); + + MT("parens", + "[qualifier .foo] {", + " [property background-image]: [variable fade]([atom #000], [number 20%]);", + " [property border-image]: [atom linear-gradient](", + " [atom to] [atom bottom],", + " [variable fade]([atom #000], [number 20%]) [number 0%],", + " [variable fade]([atom #000], [number 20%]) [number 100%]", + " );", + "}"); + + MT("css_variable", + ":[variable-3 root] {", + " [variable-2 --main-color]: [atom #06c];", + "}", + "[tag h1][builtin #foo] {", + " [property color]: [atom var]([variable-2 --main-color]);", + "}"); + + MT("supports", + "[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {", + " [property text-align-last]: [atom justify];", + "}"); + + MT("document", + "[def @document] [tag url]([string http://blah]),", + " [tag url-prefix]([string https://]),", + " [tag domain]([string blah.com]),", + " [tag regexp]([string \".*blah.+\"]) {", + " [builtin #id] {", + " [property background-color]: [keyword white];", + " }", + " [tag foo] {", + " [property font-family]: [variable Verdana], [atom sans-serif];", + " }", + "}"); + + MT("document_url", + "[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }"); + + MT("document_urlPrefix", + "[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }"); + + MT("document_domain", + "[def @document] [tag domain]([string blah.com]) { [tag foo] { } }"); + + MT("document_regexp", + "[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }"); + + MT("counter-style", + "[def @counter-style] [variable binary] {", + " [property system]: [atom numeric];", + " [property symbols]: [number 0] [number 1];", + " [property suffix]: [string \".\"];", + " [property range]: [atom infinite];", + " [property speak-as]: [atom numeric];", + "}"); + + MT("counter-style-additive-symbols", + "[def @counter-style] [variable simple-roman] {", + " [property system]: [atom additive];", + " [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];", + " [property range]: [number 1] [number 49];", + "}"); + + MT("counter-style-use", + "[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }"); + + MT("counter-style-symbols", + "[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }"); + + MT("comment-does-not-disrupt", + "[def @font-face] [comment /* foo */] {", + " [property src]: [atom url]([string x]);", + " [property font-family]: [variable One];", + "}") +})(); diff --git a/backend/webif/static/codemirror/mode/cypher/cypher.js b/backend/webif/static/codemirror/mode/cypher/cypher.js new file mode 100755 index 000000000..9b2490014 --- /dev/null +++ b/backend/webif/static/codemirror/mode/cypher/cypher.js @@ -0,0 +1,150 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// By the Neo4j Team and contributors. +// https://github.com/neo4j-contrib/CodeMirror + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var wordRegexp = function(words) { + return new RegExp("^(?:" + words.join("|") + ")$", "i"); + }; + + CodeMirror.defineMode("cypher", function(config) { + var tokenBase = function(stream/*, state*/) { + var ch = stream.next(); + if (ch ==='"') { + stream.match(/.*?"/); + return "string"; + } + if (ch === "'") { + stream.match(/.*?'/); + return "string"; + } + if (/[{}\(\),\.;\[\]]/.test(ch)) { + curPunc = ch; + return "node"; + } else if (ch === "/" && stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } else if (operatorChars.test(ch)) { + stream.eatWhile(operatorChars); + return null; + } else { + stream.eatWhile(/[_\w\d]/); + if (stream.eat(":")) { + stream.eatWhile(/[\w\d_\-]/); + return "atom"; + } + var word = stream.current(); + if (funcs.test(word)) return "builtin"; + if (preds.test(word)) return "def"; + if (keywords.test(word)) return "keyword"; + return "variable"; + } + }; + var pushContext = function(state, type, col) { + return state.context = { + prev: state.context, + indent: state.indent, + col: col, + type: type + }; + }; + var popContext = function(state) { + state.indent = state.context.indent; + return state.context = state.context.prev; + }; + var indentUnit = config.indentUnit; + var curPunc; + var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]); + var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]); + var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with", "call", "yield"]); + var operatorChars = /[*+\-<>=&|~%^]/; + + return { + startState: function(/*base*/) { + return { + tokenize: tokenBase, + context: null, + indent: 0, + col: 0 + }; + }, + token: function(stream, state) { + if (stream.sol()) { + if (state.context && (state.context.align == null)) { + state.context.align = false; + } + state.indent = stream.indentation(); + } + if (stream.eatSpace()) { + return null; + } + var style = state.tokenize(stream, state); + if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") { + state.context.align = true; + } + if (curPunc === "(") { + pushContext(state, ")", stream.column()); + } else if (curPunc === "[") { + pushContext(state, "]", stream.column()); + } else if (curPunc === "{") { + pushContext(state, "}", stream.column()); + } else if (/[\]\}\)]/.test(curPunc)) { + while (state.context && state.context.type === "pattern") { + popContext(state); + } + if (state.context && curPunc === state.context.type) { + popContext(state); + } + } else if (curPunc === "." && state.context && state.context.type === "pattern") { + popContext(state); + } else if (/atom|string|variable/.test(style) && state.context) { + if (/[\}\]]/.test(state.context.type)) { + pushContext(state, "pattern", stream.column()); + } else if (state.context.type === "pattern" && !state.context.align) { + state.context.align = true; + state.context.col = stream.column(); + } + } + return style; + }, + indent: function(state, textAfter) { + var firstChar = textAfter && textAfter.charAt(0); + var context = state.context; + if (/[\]\}]/.test(firstChar)) { + while (context && context.type === "pattern") { + context = context.prev; + } + } + var closing = context && firstChar === context.type; + if (!context) return 0; + if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent; + if (context.align) return context.col + (closing ? 0 : 1); + return context.indent + (closing ? 0 : indentUnit); + } + }; + }); + + CodeMirror.modeExtensions["cypher"] = { + autoFormatLineBreaks: function(text) { + var i, lines, reProcessedPortion; + var lines = text.split("\n"); + var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g; + for (var i = 0; i < lines.length; i++) + lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim(); + return lines.join("\n"); + } + }; + + CodeMirror.defineMIME("application/x-cypher-query", "cypher"); + +}); diff --git a/backend/webif/static/codemirror/mode/cypher/index.html b/backend/webif/static/codemirror/mode/cypher/index.html new file mode 100755 index 000000000..b8bd75c8b --- /dev/null +++ b/backend/webif/static/codemirror/mode/cypher/index.html @@ -0,0 +1,63 @@ + + +CodeMirror: Cypher Mode for CodeMirror + + + + + + + + + + +
+

Cypher Mode for CodeMirror

+
+ +
+

MIME types defined: + application/x-cypher-query +

+ + +
diff --git a/backend/webif/static/codemirror/mode/cypher/test.js b/backend/webif/static/codemirror/mode/cypher/test.js new file mode 100755 index 000000000..76d0d0829 --- /dev/null +++ b/backend/webif/static/codemirror/mode/cypher/test.js @@ -0,0 +1,37 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "cypher"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("unbalancedDoubledQuotedString", + "[string \"a'b\"][variable c]"); + + MT("unbalancedSingleQuotedString", + "[string 'a\"b'][variable c]"); + + MT("doubleQuotedString", + "[string \"a\"][variable b]"); + + MT("singleQuotedString", + "[string 'a'][variable b]"); + + MT("single attribute (with content)", + "[node {][atom a:][string 'a'][node }]"); + + MT("multiple attribute, singleQuotedString (with content)", + "[node {][atom a:][string 'a'][node ,][atom b:][string 'b'][node }]"); + + MT("multiple attribute, doubleQuotedString (with content)", + "[node {][atom a:][string \"a\"][node ,][atom b:][string \"b\"][node }]"); + + MT("single attribute (without content)", + "[node {][atom a:][string 'a'][node }]"); + + MT("multiple attribute, singleQuotedString (without content)", + "[node {][atom a:][string ''][node ,][atom b:][string ''][node }]"); + + MT("multiple attribute, doubleQuotedString (without content)", + "[node {][atom a:][string \"\"][node ,][atom b:][string \"\"][node }]"); + })(); diff --git a/backend/webif/static/codemirror/mode/d/d.js b/backend/webif/static/codemirror/mode/d/d.js new file mode 100755 index 000000000..77b09c224 --- /dev/null +++ b/backend/webif/static/codemirror/mode/d/d.js @@ -0,0 +1,218 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("d", function(config, parserConfig) { + var indentUnit = config.indentUnit, + statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, + keywords = parserConfig.keywords || {}, + builtin = parserConfig.builtin || {}, + blockKeywords = parserConfig.blockKeywords || {}, + atoms = parserConfig.atoms || {}, + hooks = parserConfig.hooks || {}, + multiLineStrings = parserConfig.multiLineStrings; + var isOperatorChar = /[+\-*&%=<>!?|\/]/; + + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (hooks[ch]) { + var result = hooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == '"' || ch == "'" || ch == "`") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + curPunc = ch; + return null; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (ch == "/") { + if (stream.eat("+")) { + state.tokenize = tokenNestedComment; + return tokenNestedComment(stream, state); + } + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + var cur = stream.current(); + if (keywords.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "keyword"; + } + if (builtin.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "builtin"; + } + if (atoms.propertyIsEnumerable(cur)) return "atom"; + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = null; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenNestedComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch == "+"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + var indent = state.indented; + if (state.context && state.context.type == "statement") + indent = state.context.indented; + return state.context = new Context(indent, col, type, null, state.context); + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state); + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement")) + pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; + var closing = firstChar == ctx.type; + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); + else if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}" + }; +}); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " + + "out scope struct switch try union unittest version while with"; + + CodeMirror.defineMIME("text/x-d", { + name: "d", + keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " + + "debug default delegate delete deprecated export extern final finally function goto immutable " + + "import inout invariant is lazy macro module new nothrow override package pragma private " + + "protected public pure ref return shared short static super synchronized template this " + + "throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " + + blockKeywords), + blockKeywords: words(blockKeywords), + builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " + + "ucent uint ulong ushort wchar wstring void size_t sizediff_t"), + atoms: words("exit failure success true false null"), + hooks: { + "@": function(stream, _state) { + stream.eatWhile(/[\w\$_]/); + return "meta"; + } + } + }); + +}); diff --git a/backend/webif/static/codemirror/mode/d/index.html b/backend/webif/static/codemirror/mode/d/index.html new file mode 100755 index 000000000..08cabd8a2 --- /dev/null +++ b/backend/webif/static/codemirror/mode/d/index.html @@ -0,0 +1,273 @@ + + +CodeMirror: D mode + + + + + + + + + + +
+

D mode

+
+ + + +

Simple mode that handle D-Syntax (DLang Homepage).

+ +

MIME types defined: text/x-d + .

+
diff --git a/backend/webif/static/codemirror/mode/d/test.js b/backend/webif/static/codemirror/mode/d/test.js new file mode 100755 index 000000000..d8de4ad35 --- /dev/null +++ b/backend/webif/static/codemirror/mode/d/test.js @@ -0,0 +1,11 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "d"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("nested_comments", + "[comment /+]","[comment comment]","[comment +/]","[variable void] [variable main](){}"); + +})(); diff --git a/backend/webif/static/codemirror/mode/dart/dart.js b/backend/webif/static/codemirror/mode/dart/dart.js new file mode 100755 index 000000000..4db0d3715 --- /dev/null +++ b/backend/webif/static/codemirror/mode/dart/dart.js @@ -0,0 +1,157 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../clike/clike")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../clike/clike"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var keywords = ("this super static final const abstract class extends external factory " + + "implements get native set typedef with enum throw rethrow " + + "assert break case continue default in return new deferred async await covariant " + + "try catch finally do else for if switch while import library export " + + "part of show hide is as").split(" "); + var blockKeywords = "try catch finally do else for if switch while".split(" "); + var atoms = "true false null".split(" "); + var builtins = "void bool num int double dynamic var String".split(" "); + + function set(words) { + var obj = {}; + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + function pushInterpolationStack(state) { + (state.interpolationStack || (state.interpolationStack = [])).push(state.tokenize); + } + + function popInterpolationStack(state) { + return (state.interpolationStack || (state.interpolationStack = [])).pop(); + } + + function sizeInterpolationStack(state) { + return state.interpolationStack ? state.interpolationStack.length : 0; + } + + CodeMirror.defineMIME("application/dart", { + name: "clike", + keywords: set(keywords), + blockKeywords: set(blockKeywords), + builtin: set(builtins), + atoms: set(atoms), + hooks: { + "@": function(stream) { + stream.eatWhile(/[\w\$_\.]/); + return "meta"; + }, + + // custom string handling to deal with triple-quoted strings and string interpolation + "'": function(stream, state) { + return tokenString("'", stream, state, false); + }, + "\"": function(stream, state) { + return tokenString("\"", stream, state, false); + }, + "r": function(stream, state) { + var peek = stream.peek(); + if (peek == "'" || peek == "\"") { + return tokenString(stream.next(), stream, state, true); + } + return false; + }, + + "}": function(_stream, state) { + // "}" is end of interpolation, if interpolation stack is non-empty + if (sizeInterpolationStack(state) > 0) { + state.tokenize = popInterpolationStack(state); + return null; + } + return false; + }, + + "/": function(stream, state) { + if (!stream.eat("*")) return false + state.tokenize = tokenNestedComment(1) + return state.tokenize(stream, state) + } + } + }); + + function tokenString(quote, stream, state, raw) { + var tripleQuoted = false; + if (stream.eat(quote)) { + if (stream.eat(quote)) tripleQuoted = true; + else return "string"; //empty string + } + function tokenStringHelper(stream, state) { + var escaped = false; + while (!stream.eol()) { + if (!raw && !escaped && stream.peek() == "$") { + pushInterpolationStack(state); + state.tokenize = tokenInterpolation; + return "string"; + } + var next = stream.next(); + if (next == quote && !escaped && (!tripleQuoted || stream.match(quote + quote))) { + state.tokenize = null; + break; + } + escaped = !raw && !escaped && next == "\\"; + } + return "string"; + } + state.tokenize = tokenStringHelper; + return tokenStringHelper(stream, state); + } + + function tokenInterpolation(stream, state) { + stream.eat("$"); + if (stream.eat("{")) { + // let clike handle the content of ${...}, + // we take over again when "}" appears (see hooks). + state.tokenize = null; + } else { + state.tokenize = tokenInterpolationIdentifier; + } + return null; + } + + function tokenInterpolationIdentifier(stream, state) { + stream.eatWhile(/[\w_]/); + state.tokenize = popInterpolationStack(state); + return "variable"; + } + + function tokenNestedComment(depth) { + return function (stream, state) { + var ch + while (ch = stream.next()) { + if (ch == "*" && stream.eat("/")) { + if (depth == 1) { + state.tokenize = null + break + } else { + state.tokenize = tokenNestedComment(depth - 1) + return state.tokenize(stream, state) + } + } else if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenNestedComment(depth + 1) + return state.tokenize(stream, state) + } + } + return "comment" + } + } + + CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins)); + + // This is needed to make loading through meta.js work. + CodeMirror.defineMode("dart", function(conf) { + return CodeMirror.getMode(conf, "application/dart"); + }, "clike"); +}); diff --git a/backend/webif/static/codemirror/mode/dart/index.html b/backend/webif/static/codemirror/mode/dart/index.html new file mode 100755 index 000000000..e79da5a8b --- /dev/null +++ b/backend/webif/static/codemirror/mode/dart/index.html @@ -0,0 +1,71 @@ + + +CodeMirror: Dart mode + + + + + + + + + +
+

Dart mode

+
+ +
+ + + +
diff --git a/backend/webif/static/codemirror/mode/diff/diff.js b/backend/webif/static/codemirror/mode/diff/diff.js new file mode 100755 index 000000000..fe0305e7b --- /dev/null +++ b/backend/webif/static/codemirror/mode/diff/diff.js @@ -0,0 +1,47 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("diff", function() { + + var TOKEN_NAMES = { + '+': 'positive', + '-': 'negative', + '@': 'meta' + }; + + return { + token: function(stream) { + var tw_pos = stream.string.search(/[\t ]+?$/); + + if (!stream.sol() || tw_pos === 0) { + stream.skipToEnd(); + return ("error " + ( + TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, ''); + } + + var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd(); + + if (tw_pos === -1) { + stream.skipToEnd(); + } else { + stream.pos = tw_pos; + } + + return token_name; + } + }; +}); + +CodeMirror.defineMIME("text/x-diff", "diff"); + +}); diff --git a/backend/webif/static/codemirror/mode/diff/index.html b/backend/webif/static/codemirror/mode/diff/index.html new file mode 100755 index 000000000..0af611fa4 --- /dev/null +++ b/backend/webif/static/codemirror/mode/diff/index.html @@ -0,0 +1,117 @@ + + +CodeMirror: Diff mode + + + + + + + + + +
+

Diff mode

+
+ + +

MIME types defined: text/x-diff.

+ +
diff --git a/backend/webif/static/codemirror/mode/django/django.js b/backend/webif/static/codemirror/mode/django/django.js new file mode 100755 index 000000000..7b4ef3b56 --- /dev/null +++ b/backend/webif/static/codemirror/mode/django/django.js @@ -0,0 +1,356 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), + require("../../addon/mode/overlay")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", + "../../addon/mode/overlay"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("django:inner", function() { + var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter", + "loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import", + "with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal", + "endifnotequal", "extends", "include", "load", "comment", "endcomment", + "empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now", + "regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", + "csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless", + "ssi", "templatetag", "verbatim", "endverbatim", "widthratio"], + filters = ["add", "addslashes", "capfirst", "center", "cut", "date", + "default", "default_if_none", "dictsort", + "dictsortreversed", "divisibleby", "escape", "escapejs", + "filesizeformat", "first", "floatformat", "force_escape", + "get_digit", "iriencode", "join", "last", "length", + "length_is", "linebreaks", "linebreaksbr", "linenumbers", + "ljust", "lower", "make_list", "phone2numeric", "pluralize", + "pprint", "random", "removetags", "rjust", "safe", + "safeseq", "slice", "slugify", "stringformat", "striptags", + "time", "timesince", "timeuntil", "title", "truncatechars", + "truncatechars_html", "truncatewords", "truncatewords_html", + "unordered_list", "upper", "urlencode", "urlize", + "urlizetrunc", "wordcount", "wordwrap", "yesno"], + operators = ["==", "!=", "<", ">", "<=", ">="], + wordOperators = ["in", "not", "or", "and"]; + + keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b"); + filters = new RegExp("^\\b(" + filters.join("|") + ")\\b"); + operators = new RegExp("^\\b(" + operators.join("|") + ")\\b"); + wordOperators = new RegExp("^\\b(" + wordOperators.join("|") + ")\\b"); + + // We have to return "null" instead of null, in order to avoid string + // styling as the default, when using Django templates inside HTML + // element attributes + function tokenBase (stream, state) { + // Attempt to identify a variable, template or comment tag respectively + if (stream.match("{{")) { + state.tokenize = inVariable; + return "tag"; + } else if (stream.match("{%")) { + state.tokenize = inTag; + return "tag"; + } else if (stream.match("{#")) { + state.tokenize = inComment; + return "comment"; + } + + // Ignore completely any stream series that do not match the + // Django template opening tags. + while (stream.next() != null && !stream.match(/\{[{%#]/, false)) {} + return null; + } + + // A string can be included in either single or double quotes (this is + // the delimiter). Mark everything as a string until the start delimiter + // occurs again. + function inString (delimiter, previousTokenizer) { + return function (stream, state) { + if (!state.escapeNext && stream.eat(delimiter)) { + state.tokenize = previousTokenizer; + } else { + if (state.escapeNext) { + state.escapeNext = false; + } + + var ch = stream.next(); + + // Take into account the backslash for escaping characters, such as + // the string delimiter. + if (ch == "\\") { + state.escapeNext = true; + } + } + + return "string"; + }; + } + + // Apply Django template variable syntax highlighting + function inVariable (stream, state) { + // Attempt to match a dot that precedes a property + if (state.waitDot) { + state.waitDot = false; + + if (stream.peek() != ".") { + return "null"; + } + + // Dot followed by a non-word character should be considered an error. + if (stream.match(/\.\W+/)) { + return "error"; + } else if (stream.eat(".")) { + state.waitProperty = true; + return "null"; + } else { + throw Error ("Unexpected error while waiting for property."); + } + } + + // Attempt to match a pipe that precedes a filter + if (state.waitPipe) { + state.waitPipe = false; + + if (stream.peek() != "|") { + return "null"; + } + + // Pipe followed by a non-word character should be considered an error. + if (stream.match(/\.\W+/)) { + return "error"; + } else if (stream.eat("|")) { + state.waitFilter = true; + return "null"; + } else { + throw Error ("Unexpected error while waiting for filter."); + } + } + + // Highlight properties + if (state.waitProperty) { + state.waitProperty = false; + if (stream.match(/\b(\w+)\b/)) { + state.waitDot = true; // A property can be followed by another property + state.waitPipe = true; // A property can be followed by a filter + return "property"; + } + } + + // Highlight filters + if (state.waitFilter) { + state.waitFilter = false; + if (stream.match(filters)) { + return "variable-2"; + } + } + + // Ignore all white spaces + if (stream.eatSpace()) { + state.waitProperty = false; + return "null"; + } + + // Identify numbers + if (stream.match(/\b\d+(\.\d+)?\b/)) { + return "number"; + } + + // Identify strings + if (stream.match("'")) { + state.tokenize = inString("'", state.tokenize); + return "string"; + } else if (stream.match('"')) { + state.tokenize = inString('"', state.tokenize); + return "string"; + } + + // Attempt to find the variable + if (stream.match(/\b(\w+)\b/) && !state.foundVariable) { + state.waitDot = true; + state.waitPipe = true; // A property can be followed by a filter + return "variable"; + } + + // If found closing tag reset + if (stream.match("}}")) { + state.waitProperty = null; + state.waitFilter = null; + state.waitDot = null; + state.waitPipe = null; + state.tokenize = tokenBase; + return "tag"; + } + + // If nothing was found, advance to the next character + stream.next(); + return "null"; + } + + function inTag (stream, state) { + // Attempt to match a dot that precedes a property + if (state.waitDot) { + state.waitDot = false; + + if (stream.peek() != ".") { + return "null"; + } + + // Dot followed by a non-word character should be considered an error. + if (stream.match(/\.\W+/)) { + return "error"; + } else if (stream.eat(".")) { + state.waitProperty = true; + return "null"; + } else { + throw Error ("Unexpected error while waiting for property."); + } + } + + // Attempt to match a pipe that precedes a filter + if (state.waitPipe) { + state.waitPipe = false; + + if (stream.peek() != "|") { + return "null"; + } + + // Pipe followed by a non-word character should be considered an error. + if (stream.match(/\.\W+/)) { + return "error"; + } else if (stream.eat("|")) { + state.waitFilter = true; + return "null"; + } else { + throw Error ("Unexpected error while waiting for filter."); + } + } + + // Highlight properties + if (state.waitProperty) { + state.waitProperty = false; + if (stream.match(/\b(\w+)\b/)) { + state.waitDot = true; // A property can be followed by another property + state.waitPipe = true; // A property can be followed by a filter + return "property"; + } + } + + // Highlight filters + if (state.waitFilter) { + state.waitFilter = false; + if (stream.match(filters)) { + return "variable-2"; + } + } + + // Ignore all white spaces + if (stream.eatSpace()) { + state.waitProperty = false; + return "null"; + } + + // Identify numbers + if (stream.match(/\b\d+(\.\d+)?\b/)) { + return "number"; + } + + // Identify strings + if (stream.match("'")) { + state.tokenize = inString("'", state.tokenize); + return "string"; + } else if (stream.match('"')) { + state.tokenize = inString('"', state.tokenize); + return "string"; + } + + // Attempt to match an operator + if (stream.match(operators)) { + return "operator"; + } + + // Attempt to match a word operator + if (stream.match(wordOperators)) { + return "keyword"; + } + + // Attempt to match a keyword + var keywordMatch = stream.match(keywords); + if (keywordMatch) { + if (keywordMatch[0] == "comment") { + state.blockCommentTag = true; + } + return "keyword"; + } + + // Attempt to match a variable + if (stream.match(/\b(\w+)\b/)) { + state.waitDot = true; + state.waitPipe = true; // A property can be followed by a filter + return "variable"; + } + + // If found closing tag reset + if (stream.match("%}")) { + state.waitProperty = null; + state.waitFilter = null; + state.waitDot = null; + state.waitPipe = null; + // If the tag that closes is a block comment tag, we want to mark the + // following code as comment, until the tag closes. + if (state.blockCommentTag) { + state.blockCommentTag = false; // Release the "lock" + state.tokenize = inBlockComment; + } else { + state.tokenize = tokenBase; + } + return "tag"; + } + + // If nothing was found, advance to the next character + stream.next(); + return "null"; + } + + // Mark everything as comment inside the tag and the tag itself. + function inComment (stream, state) { + if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase + else stream.skipToEnd() + return "comment"; + } + + // Mark everything as a comment until the `blockcomment` tag closes. + function inBlockComment (stream, state) { + if (stream.match(/\{%\s*endcomment\s*%\}/, false)) { + state.tokenize = inTag; + stream.match("{%"); + return "tag"; + } else { + stream.next(); + return "comment"; + } + } + + return { + startState: function () { + return {tokenize: tokenBase}; + }, + token: function (stream, state) { + return state.tokenize(stream, state); + }, + blockCommentStart: "{% comment %}", + blockCommentEnd: "{% endcomment %}" + }; + }); + + CodeMirror.defineMode("django", function(config) { + var htmlBase = CodeMirror.getMode(config, "text/html"); + var djangoInner = CodeMirror.getMode(config, "django:inner"); + return CodeMirror.overlayMode(htmlBase, djangoInner); + }); + + CodeMirror.defineMIME("text/x-django", "django"); +}); diff --git a/backend/webif/static/codemirror/mode/django/index.html b/backend/webif/static/codemirror/mode/django/index.html new file mode 100755 index 000000000..41ea07c91 --- /dev/null +++ b/backend/webif/static/codemirror/mode/django/index.html @@ -0,0 +1,73 @@ + + +CodeMirror: Django template mode + + + + + + + + + + + + + +
+

Django template mode

+
+ + + +

Mode for HTML with embedded Django template markup.

+ +

MIME types defined: text/x-django

+
diff --git a/backend/webif/static/codemirror/mode/dockerfile/dockerfile.js b/backend/webif/static/codemirror/mode/dockerfile/dockerfile.js new file mode 100755 index 000000000..4419009af --- /dev/null +++ b/backend/webif/static/codemirror/mode/dockerfile/dockerfile.js @@ -0,0 +1,79 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + // Collect all Dockerfile directives + var instructions = ["from", "maintainer", "run", "cmd", "expose", "env", + "add", "copy", "entrypoint", "volume", "user", + "workdir", "onbuild"], + instructionRegex = "(" + instructions.join('|') + ")", + instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"), + instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i"); + + CodeMirror.defineSimpleMode("dockerfile", { + start: [ + // Block comment: This is a line starting with a comment + { + regex: /#.*$/, + token: "comment" + }, + // Highlight an instruction without any arguments (for convenience) + { + regex: instructionOnlyLine, + token: "variable-2" + }, + // Highlight an instruction followed by arguments + { + regex: instructionWithArguments, + token: ["variable-2", null], + next: "arguments" + }, + { + regex: /./, + token: null + } + ], + arguments: [ + { + // Line comment without instruction arguments is an error + regex: /#.*$/, + token: "error", + next: "start" + }, + { + regex: /[^#]+\\$/, + token: null + }, + { + // Match everything except for the inline comment + regex: /[^#]+/, + token: null, + next: "start" + }, + { + regex: /$/, + token: null, + next: "start" + }, + // Fail safe return to start + { + token: null, + next: "start" + } + ], + meta: { + lineComment: "#" + } + }); + + CodeMirror.defineMIME("text/x-dockerfile", "dockerfile"); +}); diff --git a/backend/webif/static/codemirror/mode/dockerfile/index.html b/backend/webif/static/codemirror/mode/dockerfile/index.html new file mode 100755 index 000000000..a31759bce --- /dev/null +++ b/backend/webif/static/codemirror/mode/dockerfile/index.html @@ -0,0 +1,73 @@ + + +CodeMirror: Dockerfile mode + + + + + + + + + + +
+

Dockerfile mode

+
+ + + +

Dockerfile syntax highlighting for CodeMirror. Depends on + the simplemode addon.

+ +

MIME types defined: text/x-dockerfile

+
diff --git a/backend/webif/static/codemirror/mode/dtd/dtd.js b/backend/webif/static/codemirror/mode/dtd/dtd.js new file mode 100755 index 000000000..52d76ee11 --- /dev/null +++ b/backend/webif/static/codemirror/mode/dtd/dtd.js @@ -0,0 +1,142 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* + DTD mode + Ported to CodeMirror by Peter Kroon + Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues + GitHub: @peterkroon +*/ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("dtd", function(config) { + var indentUnit = config.indentUnit, type; + function ret(style, tp) {type = tp; return style;} + + function tokenBase(stream, state) { + var ch = stream.next(); + + if (ch == "<" && stream.eat("!") ) { + if (stream.eatWhile(/[\-]/)) { + state.tokenize = tokenSGMLComment; + return tokenSGMLComment(stream, state); + } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent"); + } else if (ch == "<" && stream.eat("?")) { //xml declaration + state.tokenize = inBlock("meta", "?>"); + return ret("meta", ch); + } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag"); + else if (ch == "|") return ret("keyword", "seperator"); + else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else + else if (ch.match(/[\[\]]/)) return ret("rule", ch); + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) { + var sc = stream.current(); + if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1); + return ret("tag", "tag"); + } else if (ch == "%" || ch == "*" ) return ret("number", "number"); + else { + stream.eatWhile(/[\w\\\-_%.{,]/); + return ret(null, null); + } + } + + function tokenSGMLComment(stream, state) { + var dashes = 0, ch; + while ((ch = stream.next()) != null) { + if (dashes >= 2 && ch == ">") { + state.tokenize = tokenBase; + break; + } + dashes = (ch == "-") ? dashes + 1 : 0; + } + return ret("comment", "comment"); + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && ch == "\\"; + } + return ret("string", "tag"); + }; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = tokenBase; + break; + } + stream.next(); + } + return style; + }; + } + + return { + startState: function(base) { + return {tokenize: tokenBase, + baseIndent: base || 0, + stack: []}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + + var context = state.stack[state.stack.length-1]; + if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule"); + else if (type === "endtag") state.stack[state.stack.length-1] = "endtag"; + else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop(); + else if (type == "[") state.stack.push("["); + return style; + }, + + indent: function(state, textAfter) { + var n = state.stack.length; + + if( textAfter.match(/\]\s+|\]/) )n=n-1; + else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){ + if(textAfter.substr(0,1) === "<") {} + else if( type == "doindent" && textAfter.length > 1 ) {} + else if( type == "doindent")n--; + else if( type == ">" && textAfter.length > 1) {} + else if( type == "tag" && textAfter !== ">") {} + else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--; + else if( type == "tag")n++; + else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--; + else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule") {} + else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1; + else if( textAfter === ">") {} + else n=n-1; + //over rule them all + if(type == null || type == "]")n--; + } + + return state.baseIndent + n * indentUnit; + }, + + electricChars: "]>" + }; +}); + +CodeMirror.defineMIME("application/xml-dtd", "dtd"); + +}); diff --git a/backend/webif/static/codemirror/mode/dtd/index.html b/backend/webif/static/codemirror/mode/dtd/index.html new file mode 100755 index 000000000..e6798a748 --- /dev/null +++ b/backend/webif/static/codemirror/mode/dtd/index.html @@ -0,0 +1,89 @@ + + +CodeMirror: DTD mode + + + + + + + + + +
+

DTD mode

+
+ + +

MIME types defined: application/xml-dtd.

+
diff --git a/backend/webif/static/codemirror/mode/dylan/dylan.js b/backend/webif/static/codemirror/mode/dylan/dylan.js new file mode 100755 index 000000000..0acc1a388 --- /dev/null +++ b/backend/webif/static/codemirror/mode/dylan/dylan.js @@ -0,0 +1,352 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +function forEach(arr, f) { + for (var i = 0; i < arr.length; i++) f(arr[i], i) +} +function some(arr, f) { + for (var i = 0; i < arr.length; i++) if (f(arr[i], i)) return true + return false +} + +CodeMirror.defineMode("dylan", function(_config) { + // Words + var words = { + // Words that introduce unnamed definitions like "define interface" + unnamedDefinition: ["interface"], + + // Words that introduce simple named definitions like "define library" + namedDefinition: ["module", "library", "macro", + "C-struct", "C-union", + "C-function", "C-callable-wrapper" + ], + + // Words that introduce type definitions like "define class". + // These are also parameterized like "define method" and are + // appended to otherParameterizedDefinitionWords + typeParameterizedDefinition: ["class", "C-subtype", "C-mapped-subtype"], + + // Words that introduce trickier definitions like "define method". + // These require special definitions to be added to startExpressions + otherParameterizedDefinition: ["method", "function", + "C-variable", "C-address" + ], + + // Words that introduce module constant definitions. + // These must also be simple definitions and are + // appended to otherSimpleDefinitionWords + constantSimpleDefinition: ["constant"], + + // Words that introduce module variable definitions. + // These must also be simple definitions and are + // appended to otherSimpleDefinitionWords + variableSimpleDefinition: ["variable"], + + // Other words that introduce simple definitions + // (without implicit bodies). + otherSimpleDefinition: ["generic", "domain", + "C-pointer-type", + "table" + ], + + // Words that begin statements with implicit bodies. + statement: ["if", "block", "begin", "method", "case", + "for", "select", "when", "unless", "until", + "while", "iterate", "profiling", "dynamic-bind" + ], + + // Patterns that act as separators in compound statements. + // This may include any general pattern that must be indented + // specially. + separator: ["finally", "exception", "cleanup", "else", + "elseif", "afterwards" + ], + + // Keywords that do not require special indentation handling, + // but which should be highlighted + other: ["above", "below", "by", "from", "handler", "in", + "instance", "let", "local", "otherwise", "slot", + "subclass", "then", "to", "keyed-by", "virtual" + ], + + // Condition signaling function calls + signalingCalls: ["signal", "error", "cerror", + "break", "check-type", "abort" + ] + }; + + words["otherDefinition"] = + words["unnamedDefinition"] + .concat(words["namedDefinition"]) + .concat(words["otherParameterizedDefinition"]); + + words["definition"] = + words["typeParameterizedDefinition"] + .concat(words["otherDefinition"]); + + words["parameterizedDefinition"] = + words["typeParameterizedDefinition"] + .concat(words["otherParameterizedDefinition"]); + + words["simpleDefinition"] = + words["constantSimpleDefinition"] + .concat(words["variableSimpleDefinition"]) + .concat(words["otherSimpleDefinition"]); + + words["keyword"] = + words["statement"] + .concat(words["separator"]) + .concat(words["other"]); + + // Patterns + var symbolPattern = "[-_a-zA-Z?!*@<>$%]+"; + var symbol = new RegExp("^" + symbolPattern); + var patterns = { + // Symbols with special syntax + symbolKeyword: symbolPattern + ":", + symbolClass: "<" + symbolPattern + ">", + symbolGlobal: "\\*" + symbolPattern + "\\*", + symbolConstant: "\\$" + symbolPattern + }; + var patternStyles = { + symbolKeyword: "atom", + symbolClass: "tag", + symbolGlobal: "variable-2", + symbolConstant: "variable-3" + }; + + // Compile all patterns to regular expressions + for (var patternName in patterns) + if (patterns.hasOwnProperty(patternName)) + patterns[patternName] = new RegExp("^" + patterns[patternName]); + + // Names beginning "with-" and "without-" are commonly + // used as statement macro + patterns["keyword"] = [/^with(?:out)?-[-_a-zA-Z?!*@<>$%]+/]; + + var styles = {}; + styles["keyword"] = "keyword"; + styles["definition"] = "def"; + styles["simpleDefinition"] = "def"; + styles["signalingCalls"] = "builtin"; + + // protected words lookup table + var wordLookup = {}; + var styleLookup = {}; + + forEach([ + "keyword", + "definition", + "simpleDefinition", + "signalingCalls" + ], function(type) { + forEach(words[type], function(word) { + wordLookup[word] = type; + styleLookup[word] = styles[type]; + }); + }); + + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function tokenBase(stream, state) { + // String + var ch = stream.peek(); + if (ch == "'" || ch == '"') { + stream.next(); + return chain(stream, state, tokenString(ch, "string")); + } + // Comment + else if (ch == "/") { + stream.next(); + if (stream.eat("*")) { + return chain(stream, state, tokenComment); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + stream.backUp(1); + } + // Decimal + else if (/[+\-\d\.]/.test(ch)) { + if (stream.match(/^[+-]?[0-9]*\.[0-9]*([esdx][+-]?[0-9]+)?/i) || + stream.match(/^[+-]?[0-9]+([esdx][+-]?[0-9]+)/i) || + stream.match(/^[+-]?\d+/)) { + return "number"; + } + } + // Hash + else if (ch == "#") { + stream.next(); + // Symbol with string syntax + ch = stream.peek(); + if (ch == '"') { + stream.next(); + return chain(stream, state, tokenString('"', "string")); + } + // Binary number + else if (ch == "b") { + stream.next(); + stream.eatWhile(/[01]/); + return "number"; + } + // Hex number + else if (ch == "x") { + stream.next(); + stream.eatWhile(/[\da-f]/i); + return "number"; + } + // Octal number + else if (ch == "o") { + stream.next(); + stream.eatWhile(/[0-7]/); + return "number"; + } + // Token concatenation in macros + else if (ch == '#') { + stream.next(); + return "punctuation"; + } + // Sequence literals + else if ((ch == '[') || (ch == '(')) { + stream.next(); + return "bracket"; + // Hash symbol + } else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) { + return "atom"; + } else { + stream.eatWhile(/[-a-zA-Z]/); + return "error"; + } + } else if (ch == "~") { + stream.next(); + ch = stream.peek(); + if (ch == "=") { + stream.next(); + ch = stream.peek(); + if (ch == "=") { + stream.next(); + return "operator"; + } + return "operator"; + } + return "operator"; + } else if (ch == ":") { + stream.next(); + ch = stream.peek(); + if (ch == "=") { + stream.next(); + return "operator"; + } else if (ch == ":") { + stream.next(); + return "punctuation"; + } + } else if ("[](){}".indexOf(ch) != -1) { + stream.next(); + return "bracket"; + } else if (".,".indexOf(ch) != -1) { + stream.next(); + return "punctuation"; + } else if (stream.match("end")) { + return "keyword"; + } + for (var name in patterns) { + if (patterns.hasOwnProperty(name)) { + var pattern = patterns[name]; + if ((pattern instanceof Array && some(pattern, function(p) { + return stream.match(p); + })) || stream.match(pattern)) + return patternStyles[name]; + } + } + if (/[+\-*\/^=<>&|]/.test(ch)) { + stream.next(); + return "operator"; + } + if (stream.match("define")) { + return "def"; + } else { + stream.eatWhile(/[\w\-]/); + // Keyword + if (wordLookup.hasOwnProperty(stream.current())) { + return styleLookup[stream.current()]; + } else if (stream.current().match(symbol)) { + return "variable"; + } else { + stream.next(); + return "variable-2"; + } + } + } + + function tokenComment(stream, state) { + var maybeEnd = false, maybeNested = false, nestedCount = 0, ch; + while ((ch = stream.next())) { + if (ch == "/" && maybeEnd) { + if (nestedCount > 0) { + nestedCount--; + } else { + state.tokenize = tokenBase; + break; + } + } else if (ch == "*" && maybeNested) { + nestedCount++; + } + maybeEnd = (ch == "*"); + maybeNested = (ch == "/"); + } + return "comment"; + } + + function tokenString(quote, style) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end || !escaped) { + state.tokenize = tokenBase; + } + return style; + }; + } + + // Interface + return { + startState: function() { + return { + tokenize: tokenBase, + currentIndent: 0 + }; + }, + token: function(stream, state) { + if (stream.eatSpace()) + return null; + var style = state.tokenize(stream, state); + return style; + }, + blockCommentStart: "/*", + blockCommentEnd: "*/" + }; +}); + +CodeMirror.defineMIME("text/x-dylan", "dylan"); + +}); diff --git a/backend/webif/static/codemirror/mode/dylan/index.html b/backend/webif/static/codemirror/mode/dylan/index.html new file mode 100755 index 000000000..ddf5ad067 --- /dev/null +++ b/backend/webif/static/codemirror/mode/dylan/index.html @@ -0,0 +1,407 @@ + + +CodeMirror: Dylan mode + + + + + + + + + + + + +
+

Dylan mode

+ + +
+ + + +

MIME types defined: text/x-dylan.

+
diff --git a/backend/webif/static/codemirror/mode/dylan/test.js b/backend/webif/static/codemirror/mode/dylan/test.js new file mode 100755 index 000000000..bf25be27e --- /dev/null +++ b/backend/webif/static/codemirror/mode/dylan/test.js @@ -0,0 +1,88 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "dylan"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT('comments', + '[comment // This is a line comment]', + '[comment /* This is a block comment */]', + '[comment /* This is a multi]', + '[comment line comment]', + '[comment */]', + '[comment /* And this is a /*]', + '[comment /* nested */ comment */]'); + + MT('unary_operators', + '[operator -][variable a]', + '[operator -] [variable a]', + '[operator ~][variable a]', + '[operator ~] [variable a]'); + + MT('binary_operators', + '[variable a] [operator +] [variable b]', + '[variable a] [operator -] [variable b]', + '[variable a] [operator *] [variable b]', + '[variable a] [operator /] [variable b]', + '[variable a] [operator ^] [variable b]', + '[variable a] [operator =] [variable b]', + '[variable a] [operator ==] [variable b]', + '[variable a] [operator ~=] [variable b]', + '[variable a] [operator ~==] [variable b]', + '[variable a] [operator <] [variable b]', + '[variable a] [operator <=] [variable b]', + '[variable a] [operator >] [variable b]', + '[variable a] [operator >=] [variable b]', + '[variable a] [operator &] [variable b]', + '[variable a] [operator |] [variable b]', + '[variable a] [operator :=] [variable b]'); + + MT('integers', + '[number 1]', + '[number 123]', + '[number -123]', + '[number +456]', + '[number #b010]', + '[number #o073]', + '[number #xabcDEF123]'); + + MT('floats', + '[number .3]', + '[number -1.]', + '[number -2.335]', + '[number +3.78d1]', + '[number 3.78s-1]', + '[number -3.32e+5]'); + + MT('characters_and_strings', + "[string 'a']", + "[string '\\\\'']", + '[string ""]', + '[string "a"]', + '[string "abc def"]', + '[string "More escaped characters: \\\\\\\\ \\\\a \\\\b \\\\e \\\\f \\\\n \\\\r \\\\t \\\\0 ..."]'); + + MT('brackets', + '[bracket #[[]]]', + '[bracket #()]', + '[bracket #(][number 1][bracket )]', + '[bracket [[][number 1][punctuation ,] [number 3][bracket ]]]', + '[bracket ()]', + '[bracket {}]', + '[keyword if] [bracket (][variable foo][bracket )]', + '[bracket (][number 1][bracket )]', + '[bracket [[][number 1][bracket ]]]'); + + MT('hash_words', + '[punctuation ##]', + '[atom #f]', '[atom #F]', + '[atom #t]', '[atom #T]', + '[atom #all-keys]', + '[atom #include]', + '[atom #key]', + '[atom #next]', + '[atom #rest]', + '[string #"foo"]', + '[error #invalid]'); +})(); diff --git a/backend/webif/static/codemirror/mode/ebnf/ebnf.js b/backend/webif/static/codemirror/mode/ebnf/ebnf.js new file mode 100755 index 000000000..9618f8e42 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ebnf/ebnf.js @@ -0,0 +1,195 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("ebnf", function (config) { + var commentType = {slash: 0, parenthesis: 1}; + var stateType = {comment: 0, _string: 1, characterClass: 2}; + var bracesMode = null; + + if (config.bracesMode) + bracesMode = CodeMirror.getMode(config, config.bracesMode); + + return { + startState: function () { + return { + stringType: null, + commentType: null, + braced: 0, + lhs: true, + localState: null, + stack: [], + inDefinition: false + }; + }, + token: function (stream, state) { + if (!stream) return; + + //check for state changes + if (state.stack.length === 0) { + //strings + if ((stream.peek() == '"') || (stream.peek() == "'")) { + state.stringType = stream.peek(); + stream.next(); // Skip quote + state.stack.unshift(stateType._string); + } else if (stream.match(/^\/\*/)) { //comments starting with /* + state.stack.unshift(stateType.comment); + state.commentType = commentType.slash; + } else if (stream.match(/^\(\*/)) { //comments starting with (* + state.stack.unshift(stateType.comment); + state.commentType = commentType.parenthesis; + } + } + + //return state + //stack has + switch (state.stack[0]) { + case stateType._string: + while (state.stack[0] === stateType._string && !stream.eol()) { + if (stream.peek() === state.stringType) { + stream.next(); // Skip quote + state.stack.shift(); // Clear flag + } else if (stream.peek() === "\\") { + stream.next(); + stream.next(); + } else { + stream.match(/^.[^\\\"\']*/); + } + } + return state.lhs ? "property string" : "string"; // Token style + + case stateType.comment: + while (state.stack[0] === stateType.comment && !stream.eol()) { + if (state.commentType === commentType.slash && stream.match(/\*\//)) { + state.stack.shift(); // Clear flag + state.commentType = null; + } else if (state.commentType === commentType.parenthesis && stream.match(/\*\)/)) { + state.stack.shift(); // Clear flag + state.commentType = null; + } else { + stream.match(/^.[^\*]*/); + } + } + return "comment"; + + case stateType.characterClass: + while (state.stack[0] === stateType.characterClass && !stream.eol()) { + if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) { + state.stack.shift(); + } + } + return "operator"; + } + + var peek = stream.peek(); + + if (bracesMode !== null && (state.braced || peek === "{")) { + if (state.localState === null) + state.localState = CodeMirror.startState(bracesMode); + + var token = bracesMode.token(stream, state.localState), + text = stream.current(); + + if (!token) { + for (var i = 0; i < text.length; i++) { + if (text[i] === "{") { + if (state.braced === 0) { + token = "matchingbracket"; + } + state.braced++; + } else if (text[i] === "}") { + state.braced--; + if (state.braced === 0) { + token = "matchingbracket"; + } + } + } + } + return token; + } + + //no stack + switch (peek) { + case "[": + stream.next(); + state.stack.unshift(stateType.characterClass); + return "bracket"; + case ":": + case "|": + case ";": + stream.next(); + return "operator"; + case "%": + if (stream.match("%%")) { + return "header"; + } else if (stream.match(/[%][A-Za-z]+/)) { + return "keyword"; + } else if (stream.match(/[%][}]/)) { + return "matchingbracket"; + } + break; + case "/": + if (stream.match(/[\/][A-Za-z]+/)) { + return "keyword"; + } + case "\\": + if (stream.match(/[\][a-z]+/)) { + return "string-2"; + } + case ".": + if (stream.match(".")) { + return "atom"; + } + case "*": + case "-": + case "+": + case "^": + if (stream.match(peek)) { + return "atom"; + } + case "$": + if (stream.match("$$")) { + return "builtin"; + } else if (stream.match(/[$][0-9]+/)) { + return "variable-3"; + } + case "<": + if (stream.match(/<<[a-zA-Z_]+>>/)) { + return "builtin"; + } + } + + if (stream.match(/^\/\//)) { + stream.skipToEnd(); + return "comment"; + } else if (stream.match(/return/)) { + return "operator"; + } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) { + if (stream.match(/(?=[\(.])/)) { + return "variable"; + } else if (stream.match(/(?=[\s\n]*[:=])/)) { + return "def"; + } + return "variable-2"; + } else if (["[", "]", "(", ")"].indexOf(stream.peek()) != -1) { + stream.next(); + return "bracket"; + } else if (!stream.eatSpace()) { + stream.next(); + } + return null; + } + }; + }); + + CodeMirror.defineMIME("text/x-ebnf", "ebnf"); +}); diff --git a/backend/webif/static/codemirror/mode/ebnf/index.html b/backend/webif/static/codemirror/mode/ebnf/index.html new file mode 100755 index 000000000..13845629b --- /dev/null +++ b/backend/webif/static/codemirror/mode/ebnf/index.html @@ -0,0 +1,102 @@ + + + + CodeMirror: EBNF Mode + + + + + + + + + + + + +
+

EBNF Mode (bracesMode setting = "javascript")

+
+ +

The EBNF Mode

+

Created by Robert Plummer

+
+ + diff --git a/backend/webif/static/codemirror/mode/ecl/ecl.js b/backend/webif/static/codemirror/mode/ecl/ecl.js new file mode 100755 index 000000000..8df7ebe4a --- /dev/null +++ b/backend/webif/static/codemirror/mode/ecl/ecl.js @@ -0,0 +1,206 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("ecl", function(config) { + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + function metaHook(stream, state) { + if (!state.startOfLine) return false; + stream.skipToEnd(); + return "meta"; + } + + var indentUnit = config.indentUnit; + var keyword = words("abs acos allnodes ascii asin asstring atan atan2 ave case choose choosen choosesets clustersize combine correlation cos cosh count covariance cron dataset dedup define denormalize distribute distributed distribution ebcdic enth error evaluate event eventextra eventname exists exp failcode failmessage fetch fromunicode getisvalid global graph group hash hash32 hash64 hashcrc hashmd5 having if index intformat isvalid iterate join keyunicode length library limit ln local log loop map matched matchlength matchposition matchtext matchunicode max merge mergejoin min nolocal nonempty normalize parse pipe power preload process project pull random range rank ranked realformat recordof regexfind regexreplace regroup rejected rollup round roundup row rowdiff sample set sin sinh sizeof soapcall sort sorted sqrt stepped stored sum table tan tanh thisnode topn tounicode transfer trim truncate typeof ungroup unicodeorder variance which workunit xmldecode xmlencode xmltext xmlunicode"); + var variable = words("apply assert build buildindex evaluate fail keydiff keypatch loadxml nothor notify output parallel sequential soapcall wait"); + var variable_2 = words("__compressed__ all and any as atmost before beginc++ best between case const counter csv descend encrypt end endc++ endmacro except exclusive expire export extend false few first flat from full function group header heading hole ifblock import in interface joined keep keyed last left limit load local locale lookup macro many maxcount maxlength min skew module named nocase noroot noscan nosort not of only opt or outer overwrite packed partition penalty physicallength pipe quote record relationship repeat return right scan self separator service shared skew skip sql store terminator thor threshold token transform trim true type unicodeorder unsorted validate virtual whole wild within xml xpath"); + var variable_3 = words("ascii big_endian boolean data decimal ebcdic integer pattern qstring real record rule set of string token udecimal unicode unsigned varstring varunicode"); + var builtin = words("checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when"); + var blockKeywords = words("catch class do else finally for if switch try while"); + var atoms = words("true false null"); + var hooks = {"#": metaHook}; + var isOperatorChar = /[+\-*&%=<>!?|\/]/; + + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (hooks[ch]) { + var result = hooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + curPunc = ch; + return null; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_]/); + var cur = stream.current().toLowerCase(); + if (keyword.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "keyword"; + } else if (variable.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "variable"; + } else if (variable_2.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "variable-2"; + } else if (variable_3.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "variable-3"; + } else if (builtin.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + return "builtin"; + } else { //Data types are of from KEYWORD## + var i = cur.length - 1; + while(i >= 0 && (!isNaN(cur[i]) || cur[i] == '_')) + --i; + + if (i > 0) { + var cur2 = cur.substr(0, i + 1); + if (variable_3.propertyIsEnumerable(cur2)) { + if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = "newstatement"; + return "variable-3"; + } + } + } + if (atoms.propertyIsEnumerable(cur)) return "atom"; + return null; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !escaped) + state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state); + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement")) + pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null) return 0; + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; + var closing = firstChar == ctx.type; + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit); + else if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}" + }; +}); + +CodeMirror.defineMIME("text/x-ecl", "ecl"); + +}); diff --git a/backend/webif/static/codemirror/mode/ecl/index.html b/backend/webif/static/codemirror/mode/ecl/index.html new file mode 100755 index 000000000..2306860dc --- /dev/null +++ b/backend/webif/static/codemirror/mode/ecl/index.html @@ -0,0 +1,52 @@ + + +CodeMirror: ECL mode + + + + + + + + + +
+

ECL mode

+
+ + +

Based on CodeMirror's clike mode. For more information see HPCC Systems web site.

+

MIME types defined: text/x-ecl.

+ +
diff --git a/backend/webif/static/codemirror/mode/eiffel/eiffel.js b/backend/webif/static/codemirror/mode/eiffel/eiffel.js new file mode 100755 index 000000000..b8b70e36e --- /dev/null +++ b/backend/webif/static/codemirror/mode/eiffel/eiffel.js @@ -0,0 +1,160 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("eiffel", function() { + function wordObj(words) { + var o = {}; + for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; + return o; + } + var keywords = wordObj([ + 'note', + 'across', + 'when', + 'variant', + 'until', + 'unique', + 'undefine', + 'then', + 'strip', + 'select', + 'retry', + 'rescue', + 'require', + 'rename', + 'reference', + 'redefine', + 'prefix', + 'once', + 'old', + 'obsolete', + 'loop', + 'local', + 'like', + 'is', + 'inspect', + 'infix', + 'include', + 'if', + 'frozen', + 'from', + 'external', + 'export', + 'ensure', + 'end', + 'elseif', + 'else', + 'do', + 'creation', + 'create', + 'check', + 'alias', + 'agent', + 'separate', + 'invariant', + 'inherit', + 'indexing', + 'feature', + 'expanded', + 'deferred', + 'class', + 'Void', + 'True', + 'Result', + 'Precursor', + 'False', + 'Current', + 'create', + 'attached', + 'detachable', + 'as', + 'and', + 'implies', + 'not', + 'or' + ]); + var operators = wordObj([":=", "and then","and", "or","<<",">>"]); + + function chain(newtok, stream, state) { + state.tokenize.push(newtok); + return newtok(stream, state); + } + + function tokenBase(stream, state) { + if (stream.eatSpace()) return null; + var ch = stream.next(); + if (ch == '"'||ch == "'") { + return chain(readQuoted(ch, "string"), stream, state); + } else if (ch == "-"&&stream.eat("-")) { + stream.skipToEnd(); + return "comment"; + } else if (ch == ":"&&stream.eat("=")) { + return "operator"; + } else if (/[0-9]/.test(ch)) { + stream.eatWhile(/[xXbBCc0-9\.]/); + stream.eat(/[\?\!]/); + return "ident"; + } else if (/[a-zA-Z_0-9]/.test(ch)) { + stream.eatWhile(/[a-zA-Z_0-9]/); + stream.eat(/[\?\!]/); + return "ident"; + } else if (/[=+\-\/*^%<>~]/.test(ch)) { + stream.eatWhile(/[=+\-\/*^%<>~]/); + return "operator"; + } else { + return null; + } + } + + function readQuoted(quote, style, unescaped) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && (unescaped || !escaped)) { + state.tokenize.pop(); + break; + } + escaped = !escaped && ch == "%"; + } + return style; + }; + } + + return { + startState: function() { + return {tokenize: [tokenBase]}; + }, + + token: function(stream, state) { + var style = state.tokenize[state.tokenize.length-1](stream, state); + if (style == "ident") { + var word = stream.current(); + style = keywords.propertyIsEnumerable(stream.current()) ? "keyword" + : operators.propertyIsEnumerable(stream.current()) ? "operator" + : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag" + : /^0[bB][0-1]+$/g.test(word) ? "number" + : /^0[cC][0-7]+$/g.test(word) ? "number" + : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number" + : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number" + : /^[0-9]+$/g.test(word) ? "number" + : "variable"; + } + return style; + }, + lineComment: "--" + }; +}); + +CodeMirror.defineMIME("text/x-eiffel", "eiffel"); + +}); diff --git a/backend/webif/static/codemirror/mode/eiffel/index.html b/backend/webif/static/codemirror/mode/eiffel/index.html new file mode 100755 index 000000000..108a71bec --- /dev/null +++ b/backend/webif/static/codemirror/mode/eiffel/index.html @@ -0,0 +1,429 @@ + + +CodeMirror: Eiffel mode + + + + + + + + + + +
+

Eiffel mode

+
+ + +

MIME types defined: text/x-eiffel.

+ +

Created by YNH.

+
diff --git a/backend/webif/static/codemirror/mode/elm/elm.js b/backend/webif/static/codemirror/mode/elm/elm.js new file mode 100755 index 000000000..9fcfc8837 --- /dev/null +++ b/backend/webif/static/codemirror/mode/elm/elm.js @@ -0,0 +1,205 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("elm", function() { + + function switchState(source, setState, f) { + setState(f); + return f(source, setState); + } + + // These should all be Unicode extended, as per the Haskell 2010 report + var smallRE = /[a-z_]/; + var largeRE = /[A-Z]/; + var digitRE = /[0-9]/; + var hexitRE = /[0-9A-Fa-f]/; + var octitRE = /[0-7]/; + var idRE = /[a-z_A-Z0-9\']/; + var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/; + var specialRE = /[(),;[\]`{}]/; + var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer + + function normal() { + return function (source, setState) { + if (source.eatWhile(whiteCharRE)) { + return null; + } + + var ch = source.next(); + if (specialRE.test(ch)) { + if (ch == '{' && source.eat('-')) { + var t = "comment"; + if (source.eat('#')) t = "meta"; + return switchState(source, setState, ncomment(t, 1)); + } + return null; + } + + if (ch == '\'') { + if (source.eat('\\')) + source.next(); // should handle other escapes here + else + source.next(); + + if (source.eat('\'')) + return "string"; + return "error"; + } + + if (ch == '"') { + return switchState(source, setState, stringLiteral); + } + + if (largeRE.test(ch)) { + source.eatWhile(idRE); + if (source.eat('.')) + return "qualifier"; + return "variable-2"; + } + + if (smallRE.test(ch)) { + var isDef = source.pos === 1; + source.eatWhile(idRE); + return isDef ? "type" : "variable"; + } + + if (digitRE.test(ch)) { + if (ch == '0') { + if (source.eat(/[xX]/)) { + source.eatWhile(hexitRE); // should require at least 1 + return "integer"; + } + if (source.eat(/[oO]/)) { + source.eatWhile(octitRE); // should require at least 1 + return "number"; + } + } + source.eatWhile(digitRE); + var t = "number"; + if (source.eat('.')) { + t = "number"; + source.eatWhile(digitRE); // should require at least 1 + } + if (source.eat(/[eE]/)) { + t = "number"; + source.eat(/[-+]/); + source.eatWhile(digitRE); // should require at least 1 + } + return t; + } + + if (symbolRE.test(ch)) { + if (ch == '-' && source.eat(/-/)) { + source.eatWhile(/-/); + if (!source.eat(symbolRE)) { + source.skipToEnd(); + return "comment"; + } + } + source.eatWhile(symbolRE); + return "builtin"; + } + + return "error"; + } + } + + function ncomment(type, nest) { + if (nest == 0) { + return normal(); + } + return function(source, setState) { + var currNest = nest; + while (!source.eol()) { + var ch = source.next(); + if (ch == '{' && source.eat('-')) { + ++currNest; + } else if (ch == '-' && source.eat('}')) { + --currNest; + if (currNest == 0) { + setState(normal()); + return type; + } + } + } + setState(ncomment(type, currNest)); + return type; + } + } + + function stringLiteral(source, setState) { + while (!source.eol()) { + var ch = source.next(); + if (ch == '"') { + setState(normal()); + return "string"; + } + if (ch == '\\') { + if (source.eol() || source.eat(whiteCharRE)) { + setState(stringGap); + return "string"; + } + if (!source.eat('&')) source.next(); // should handle other escapes here + } + } + setState(normal()); + return "error"; + } + + function stringGap(source, setState) { + if (source.eat('\\')) { + return switchState(source, setState, stringLiteral); + } + source.next(); + setState(normal()); + return "error"; + } + + + var wellKnownWords = (function() { + var wkw = {}; + + var keywords = [ + "case", "of", "as", + "if", "then", "else", + "let", "in", + "infix", "infixl", "infixr", + "type", "alias", + "input", "output", "foreign", "loopback", + "module", "where", "import", "exposing", + "_", "..", "|", ":", "=", "\\", "\"", "->", "<-" + ]; + + for (var i = keywords.length; i--;) + wkw[keywords[i]] = "keyword"; + + return wkw; + })(); + + + + return { + startState: function () { return { f: normal() }; }, + copyState: function (s) { return { f: s.f }; }, + + token: function(stream, state) { + var t = state.f(stream, function(s) { state.f = s; }); + var w = stream.current(); + return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t; + } + }; + + }); + + CodeMirror.defineMIME("text/x-elm", "elm"); +}); diff --git a/backend/webif/static/codemirror/mode/elm/index.html b/backend/webif/static/codemirror/mode/elm/index.html new file mode 100755 index 000000000..d5cb16abf --- /dev/null +++ b/backend/webif/static/codemirror/mode/elm/index.html @@ -0,0 +1,61 @@ + + +CodeMirror: Elm mode + + + + + + + + + +
+

Elm mode

+ +
+ + + +

MIME types defined: text/x-elm.

+
diff --git a/backend/webif/static/codemirror/mode/erlang/erlang.js b/backend/webif/static/codemirror/mode/erlang/erlang.js new file mode 100755 index 000000000..9528e19f9 --- /dev/null +++ b/backend/webif/static/codemirror/mode/erlang/erlang.js @@ -0,0 +1,619 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/*jshint unused:true, eqnull:true, curly:true, bitwise:true */ +/*jshint undef:true, latedef:true, trailing:true */ +/*global CodeMirror:true */ + +// erlang mode. +// tokenizer -> token types -> CodeMirror styles +// tokenizer maintains a parse stack +// indenter uses the parse stack + +// TODO indenter: +// bit syntax +// old guard/bif/conversion clashes (e.g. "float/1") +// type/spec/opaque + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMIME("text/x-erlang", "erlang"); + +CodeMirror.defineMode("erlang", function(cmCfg) { + "use strict"; + +///////////////////////////////////////////////////////////////////////////// +// constants + + var typeWords = [ + "-type", "-spec", "-export_type", "-opaque"]; + + var keywordWords = [ + "after","begin","catch","case","cond","end","fun","if", + "let","of","query","receive","try","when"]; + + var separatorRE = /[\->,;]/; + var separatorWords = [ + "->",";",","]; + + var operatorAtomWords = [ + "and","andalso","band","bnot","bor","bsl","bsr","bxor", + "div","not","or","orelse","rem","xor"]; + + var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/; + var operatorSymbolWords = [ + "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"]; + + var openParenRE = /[<\(\[\{]/; + var openParenWords = [ + "<<","(","[","{"]; + + var closeParenRE = /[>\)\]\}]/; + var closeParenWords = [ + "}","]",")",">>"]; + + var guardWords = [ + "is_atom","is_binary","is_bitstring","is_boolean","is_float", + "is_function","is_integer","is_list","is_number","is_pid", + "is_port","is_record","is_reference","is_tuple", + "atom","binary","bitstring","boolean","function","integer","list", + "number","pid","port","record","reference","tuple"]; + + var bifWords = [ + "abs","adler32","adler32_combine","alive","apply","atom_to_binary", + "atom_to_list","binary_to_atom","binary_to_existing_atom", + "binary_to_list","binary_to_term","bit_size","bitstring_to_list", + "byte_size","check_process_code","contact_binary","crc32", + "crc32_combine","date","decode_packet","delete_module", + "disconnect_node","element","erase","exit","float","float_to_list", + "garbage_collect","get","get_keys","group_leader","halt","hd", + "integer_to_list","internal_bif","iolist_size","iolist_to_binary", + "is_alive","is_atom","is_binary","is_bitstring","is_boolean", + "is_float","is_function","is_integer","is_list","is_number","is_pid", + "is_port","is_process_alive","is_record","is_reference","is_tuple", + "length","link","list_to_atom","list_to_binary","list_to_bitstring", + "list_to_existing_atom","list_to_float","list_to_integer", + "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded", + "monitor_node","node","node_link","node_unlink","nodes","notalive", + "now","open_port","pid_to_list","port_close","port_command", + "port_connect","port_control","pre_loaded","process_flag", + "process_info","processes","purge_module","put","register", + "registered","round","self","setelement","size","spawn","spawn_link", + "spawn_monitor","spawn_opt","split_binary","statistics", + "term_to_binary","time","throw","tl","trunc","tuple_size", + "tuple_to_list","unlink","unregister","whereis"]; + +// upper case: [A-Z] [Ø-Þ] [À-Ö] +// lower case: [a-z] [ß-ö] [ø-ÿ] + var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/; + var escapesRE = + /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/; + +///////////////////////////////////////////////////////////////////////////// +// tokenizer + + function tokenizer(stream,state) { + // in multi-line string + if (state.in_string) { + state.in_string = (!doubleQuote(stream)); + return rval(state,stream,"string"); + } + + // in multi-line atom + if (state.in_atom) { + state.in_atom = (!singleQuote(stream)); + return rval(state,stream,"atom"); + } + + // whitespace + if (stream.eatSpace()) { + return rval(state,stream,"whitespace"); + } + + // attributes and type specs + if (!peekToken(state) && + stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) { + if (is_member(stream.current(),typeWords)) { + return rval(state,stream,"type"); + }else{ + return rval(state,stream,"attribute"); + } + } + + var ch = stream.next(); + + // comment + if (ch == '%') { + stream.skipToEnd(); + return rval(state,stream,"comment"); + } + + // colon + if (ch == ":") { + return rval(state,stream,"colon"); + } + + // macro + if (ch == '?') { + stream.eatSpace(); + stream.eatWhile(anumRE); + return rval(state,stream,"macro"); + } + + // record + if (ch == "#") { + stream.eatSpace(); + stream.eatWhile(anumRE); + return rval(state,stream,"record"); + } + + // dollar escape + if (ch == "$") { + if (stream.next() == "\\" && !stream.match(escapesRE)) { + return rval(state,stream,"error"); + } + return rval(state,stream,"number"); + } + + // dot + if (ch == ".") { + return rval(state,stream,"dot"); + } + + // quoted atom + if (ch == '\'') { + if (!(state.in_atom = (!singleQuote(stream)))) { + if (stream.match(/\s*\/\s*[0-9]/,false)) { + stream.match(/\s*\/\s*[0-9]/,true); + return rval(state,stream,"fun"); // 'f'/0 style fun + } + if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) { + return rval(state,stream,"function"); + } + } + return rval(state,stream,"atom"); + } + + // string + if (ch == '"') { + state.in_string = (!doubleQuote(stream)); + return rval(state,stream,"string"); + } + + // variable + if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) { + stream.eatWhile(anumRE); + return rval(state,stream,"variable"); + } + + // atom/keyword/BIF/function + if (/[a-z_ß-öø-ÿ]/.test(ch)) { + stream.eatWhile(anumRE); + + if (stream.match(/\s*\/\s*[0-9]/,false)) { + stream.match(/\s*\/\s*[0-9]/,true); + return rval(state,stream,"fun"); // f/0 style fun + } + + var w = stream.current(); + + if (is_member(w,keywordWords)) { + return rval(state,stream,"keyword"); + }else if (is_member(w,operatorAtomWords)) { + return rval(state,stream,"operator"); + }else if (stream.match(/\s*\(/,false)) { + // 'put' and 'erlang:put' are bifs, 'foo:put' is not + if (is_member(w,bifWords) && + ((peekToken(state).token != ":") || + (peekToken(state,2).token == "erlang"))) { + return rval(state,stream,"builtin"); + }else if (is_member(w,guardWords)) { + return rval(state,stream,"guard"); + }else{ + return rval(state,stream,"function"); + } + }else if (lookahead(stream) == ":") { + if (w == "erlang") { + return rval(state,stream,"builtin"); + } else { + return rval(state,stream,"function"); + } + }else if (is_member(w,["true","false"])) { + return rval(state,stream,"boolean"); + }else{ + return rval(state,stream,"atom"); + } + } + + // number + var digitRE = /[0-9]/; + var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int + if (digitRE.test(ch)) { + stream.eatWhile(digitRE); + if (stream.eat('#')) { // 36#aZ style integer + if (!stream.eatWhile(radixRE)) { + stream.backUp(1); //"36#" - syntax error + } + } else if (stream.eat('.')) { // float + if (!stream.eatWhile(digitRE)) { + stream.backUp(1); // "3." - probably end of function + } else { + if (stream.eat(/[eE]/)) { // float with exponent + if (stream.eat(/[-+]/)) { + if (!stream.eatWhile(digitRE)) { + stream.backUp(2); // "2e-" - syntax error + } + } else { + if (!stream.eatWhile(digitRE)) { + stream.backUp(1); // "2e" - syntax error + } + } + } + } + } + return rval(state,stream,"number"); // normal integer + } + + // open parens + if (nongreedy(stream,openParenRE,openParenWords)) { + return rval(state,stream,"open_paren"); + } + + // close parens + if (nongreedy(stream,closeParenRE,closeParenWords)) { + return rval(state,stream,"close_paren"); + } + + // separators + if (greedy(stream,separatorRE,separatorWords)) { + return rval(state,stream,"separator"); + } + + // operators + if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) { + return rval(state,stream,"operator"); + } + + return rval(state,stream,null); + } + +///////////////////////////////////////////////////////////////////////////// +// utilities + function nongreedy(stream,re,words) { + if (stream.current().length == 1 && re.test(stream.current())) { + stream.backUp(1); + while (re.test(stream.peek())) { + stream.next(); + if (is_member(stream.current(),words)) { + return true; + } + } + stream.backUp(stream.current().length-1); + } + return false; + } + + function greedy(stream,re,words) { + if (stream.current().length == 1 && re.test(stream.current())) { + while (re.test(stream.peek())) { + stream.next(); + } + while (0 < stream.current().length) { + if (is_member(stream.current(),words)) { + return true; + }else{ + stream.backUp(1); + } + } + stream.next(); + } + return false; + } + + function doubleQuote(stream) { + return quote(stream, '"', '\\'); + } + + function singleQuote(stream) { + return quote(stream,'\'','\\'); + } + + function quote(stream,quoteChar,escapeChar) { + while (!stream.eol()) { + var ch = stream.next(); + if (ch == quoteChar) { + return true; + }else if (ch == escapeChar) { + stream.next(); + } + } + return false; + } + + function lookahead(stream) { + var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false); + return m ? m.pop() : ""; + } + + function is_member(element,list) { + return (-1 < list.indexOf(element)); + } + + function rval(state,stream,type) { + + // parse stack + pushToken(state,realToken(type,stream)); + + // map erlang token type to CodeMirror style class + // erlang -> CodeMirror tag + switch (type) { + case "atom": return "atom"; + case "attribute": return "attribute"; + case "boolean": return "atom"; + case "builtin": return "builtin"; + case "close_paren": return null; + case "colon": return null; + case "comment": return "comment"; + case "dot": return null; + case "error": return "error"; + case "fun": return "meta"; + case "function": return "tag"; + case "guard": return "property"; + case "keyword": return "keyword"; + case "macro": return "variable-2"; + case "number": return "number"; + case "open_paren": return null; + case "operator": return "operator"; + case "record": return "bracket"; + case "separator": return null; + case "string": return "string"; + case "type": return "def"; + case "variable": return "variable"; + default: return null; + } + } + + function aToken(tok,col,ind,typ) { + return {token: tok, + column: col, + indent: ind, + type: typ}; + } + + function realToken(type,stream) { + return aToken(stream.current(), + stream.column(), + stream.indentation(), + type); + } + + function fakeToken(type) { + return aToken(type,0,0,type); + } + + function peekToken(state,depth) { + var len = state.tokenStack.length; + var dep = (depth ? depth : 1); + + if (len < dep) { + return false; + }else{ + return state.tokenStack[len-dep]; + } + } + + function pushToken(state,token) { + + if (!(token.type == "comment" || token.type == "whitespace")) { + state.tokenStack = maybe_drop_pre(state.tokenStack,token); + state.tokenStack = maybe_drop_post(state.tokenStack); + } + } + + function maybe_drop_pre(s,token) { + var last = s.length-1; + + if (0 < last && s[last].type === "record" && token.type === "dot") { + s.pop(); + }else if (0 < last && s[last].type === "group") { + s.pop(); + s.push(token); + }else{ + s.push(token); + } + return s; + } + + function maybe_drop_post(s) { + if (!s.length) return s + var last = s.length-1; + + if (s[last].type === "dot") { + return []; + } + if (last > 1 && s[last].type === "fun" && s[last-1].token === "fun") { + return s.slice(0,last-1); + } + switch (s[last].token) { + case "}": return d(s,{g:["{"]}); + case "]": return d(s,{i:["["]}); + case ")": return d(s,{i:["("]}); + case ">>": return d(s,{i:["<<"]}); + case "end": return d(s,{i:["begin","case","fun","if","receive","try"]}); + case ",": return d(s,{e:["begin","try","when","->", + ",","(","[","{","<<"]}); + case "->": return d(s,{r:["when"], + m:["try","if","case","receive"]}); + case ";": return d(s,{E:["case","fun","if","receive","try","when"]}); + case "catch":return d(s,{e:["try"]}); + case "of": return d(s,{e:["case"]}); + case "after":return d(s,{e:["receive","try"]}); + default: return s; + } + } + + function d(stack,tt) { + // stack is a stack of Token objects. + // tt is an object; {type:tokens} + // type is a char, tokens is a list of token strings. + // The function returns (possibly truncated) stack. + // It will descend the stack, looking for a Token such that Token.token + // is a member of tokens. If it does not find that, it will normally (but + // see "E" below) return stack. If it does find a match, it will remove + // all the Tokens between the top and the matched Token. + // If type is "m", that is all it does. + // If type is "i", it will also remove the matched Token and the top Token. + // If type is "g", like "i", but add a fake "group" token at the top. + // If type is "r", it will remove the matched Token, but not the top Token. + // If type is "e", it will keep the matched Token but not the top Token. + // If type is "E", it behaves as for type "e", except if there is no match, + // in which case it will return an empty stack. + + for (var type in tt) { + var len = stack.length-1; + var tokens = tt[type]; + for (var i = len-1; -1 < i ; i--) { + if (is_member(stack[i].token,tokens)) { + var ss = stack.slice(0,i); + switch (type) { + case "m": return ss.concat(stack[i]).concat(stack[len]); + case "r": return ss.concat(stack[len]); + case "i": return ss; + case "g": return ss.concat(fakeToken("group")); + case "E": return ss.concat(stack[i]); + case "e": return ss.concat(stack[i]); + } + } + } + } + return (type == "E" ? [] : stack); + } + +///////////////////////////////////////////////////////////////////////////// +// indenter + + function indenter(state,textAfter) { + var t; + var unit = cmCfg.indentUnit; + var wordAfter = wordafter(textAfter); + var currT = peekToken(state,1); + var prevT = peekToken(state,2); + + if (state.in_string || state.in_atom) { + return CodeMirror.Pass; + }else if (!prevT) { + return 0; + }else if (currT.token == "when") { + return currT.column+unit; + }else if (wordAfter === "when" && prevT.type === "function") { + return prevT.indent+unit; + }else if (wordAfter === "(" && currT.token === "fun") { + return currT.column+3; + }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) { + return t.column; + }else if (is_member(wordAfter,["end","after","of"])) { + t = getToken(state,["begin","case","fun","if","receive","try"]); + return t ? t.column : CodeMirror.Pass; + }else if (is_member(wordAfter,closeParenWords)) { + t = getToken(state,openParenWords); + return t ? t.column : CodeMirror.Pass; + }else if (is_member(currT.token,[",","|","||"]) || + is_member(wordAfter,[",","|","||"])) { + t = postcommaToken(state); + return t ? t.column+t.token.length : unit; + }else if (currT.token == "->") { + if (is_member(prevT.token, ["receive","case","if","try"])) { + return prevT.column+unit+unit; + }else{ + return prevT.column+unit; + } + }else if (is_member(currT.token,openParenWords)) { + return currT.column+currT.token.length; + }else{ + t = defaultToken(state); + return truthy(t) ? t.column+unit : 0; + } + } + + function wordafter(str) { + var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/); + + return truthy(m) && (m.index === 0) ? m[0] : ""; + } + + function postcommaToken(state) { + var objs = state.tokenStack.slice(0,-1); + var i = getTokenIndex(objs,"type",["open_paren"]); + + return truthy(objs[i]) ? objs[i] : false; + } + + function defaultToken(state) { + var objs = state.tokenStack; + var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]); + var oper = getTokenIndex(objs,"type",["operator"]); + + if (truthy(stop) && truthy(oper) && stop < oper) { + return objs[stop+1]; + } else if (truthy(stop)) { + return objs[stop]; + } else { + return false; + } + } + + function getToken(state,tokens) { + var objs = state.tokenStack; + var i = getTokenIndex(objs,"token",tokens); + + return truthy(objs[i]) ? objs[i] : false; + } + + function getTokenIndex(objs,propname,propvals) { + + for (var i = objs.length-1; -1 < i ; i--) { + if (is_member(objs[i][propname],propvals)) { + return i; + } + } + return false; + } + + function truthy(x) { + return (x !== false) && (x != null); + } + +///////////////////////////////////////////////////////////////////////////// +// this object defines the mode + + return { + startState: + function() { + return {tokenStack: [], + in_string: false, + in_atom: false}; + }, + + token: + function(stream, state) { + return tokenizer(stream, state); + }, + + indent: + function(state, textAfter) { + return indenter(state,textAfter); + }, + + lineComment: "%" + }; +}); + +}); diff --git a/backend/webif/static/codemirror/mode/erlang/index.html b/backend/webif/static/codemirror/mode/erlang/index.html new file mode 100755 index 000000000..6d06a890a --- /dev/null +++ b/backend/webif/static/codemirror/mode/erlang/index.html @@ -0,0 +1,76 @@ + + +CodeMirror: Erlang mode + + + + + + + + + + + +
+

Erlang mode

+
+ + + +

MIME types defined: text/x-erlang.

+
diff --git a/backend/webif/static/codemirror/mode/factor/factor.js b/backend/webif/static/codemirror/mode/factor/factor.js new file mode 100755 index 000000000..e238c5ea6 --- /dev/null +++ b/backend/webif/static/codemirror/mode/factor/factor.js @@ -0,0 +1,85 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Factor syntax highlight - simple mode +// +// by Dimage Sapelkin (https://github.com/kerabromsmu) + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineSimpleMode("factor", { + // The start state contains the rules that are intially used + start: [ + // comments + {regex: /#?!.*/, token: "comment"}, + // strings """, multiline --> state + {regex: /"""/, token: "string", next: "string3"}, + {regex: /(STRING:)(\s)/, token: ["keyword", null], next: "string2"}, + {regex: /\S*?"/, token: "string", next: "string"}, + // numbers: dec, hex, unicode, bin, fractional, complex + {regex: /(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\-?\d+.?\d*)(?=\s)/, token: "number"}, + //{regex: /[+-]?/} //fractional + // definition: defining word, defined word, etc + {regex: /((?:GENERIC)|\:?\:)(\s+)(\S+)(\s+)(\()/, token: ["keyword", null, "def", null, "bracket"], next: "stack"}, + // method definition: defining word, type, defined word, etc + {regex: /(M\:)(\s+)(\S+)(\s+)(\S+)/, token: ["keyword", null, "def", null, "tag"]}, + // vocabulary using --> state + {regex: /USING\:/, token: "keyword", next: "vocabulary"}, + // vocabulary definition/use + {regex: /(USE\:|IN\:)(\s+)(\S+)(?=\s|$)/, token: ["keyword", null, "tag"]}, + // definition: a defining word, defined word + {regex: /(\S+\:)(\s+)(\S+)(?=\s|$)/, token: ["keyword", null, "def"]}, + // "keywords", incl. ; t f . [ ] { } defining words + {regex: /(?:;|\\|t|f|if|loop|while|until|do|PRIVATE>| and the like + {regex: /\S+[\)>\.\*\?]+(?=\s|$)/, token: "builtin"}, + {regex: /[\)><]+\S+(?=\s|$)/, token: "builtin"}, + // operators + {regex: /(?:[\+\-\=\/\*<>])(?=\s|$)/, token: "keyword"}, + // any id (?) + {regex: /\S+/, token: "variable"}, + {regex: /\s+|./, token: null} + ], + vocabulary: [ + {regex: /;/, token: "keyword", next: "start"}, + {regex: /\S+/, token: "tag"}, + {regex: /\s+|./, token: null} + ], + string: [ + {regex: /(?:[^\\]|\\.)*?"/, token: "string", next: "start"}, + {regex: /.*/, token: "string"} + ], + string2: [ + {regex: /^;/, token: "keyword", next: "start"}, + {regex: /.*/, token: "string"} + ], + string3: [ + {regex: /(?:[^\\]|\\.)*?"""/, token: "string", next: "start"}, + {regex: /.*/, token: "string"} + ], + stack: [ + {regex: /\)/, token: "bracket", next: "start"}, + {regex: /--/, token: "bracket"}, + {regex: /\S+/, token: "meta"}, + {regex: /\s+|./, token: null} + ], + // The meta property contains global information about the mode. It + // can contain properties like lineComment, which are supported by + // all modes, and also directives like dontIndentStates, which are + // specific to simple modes. + meta: { + dontIndentStates: ["start", "vocabulary", "string", "string3", "stack"], + lineComment: [ "!", "#!" ] + } + }); + + CodeMirror.defineMIME("text/x-factor", "factor"); +}); diff --git a/backend/webif/static/codemirror/mode/factor/index.html b/backend/webif/static/codemirror/mode/factor/index.html new file mode 100755 index 000000000..9f1548914 --- /dev/null +++ b/backend/webif/static/codemirror/mode/factor/index.html @@ -0,0 +1,77 @@ + + +CodeMirror: Factor mode + + + + + + + + + + + +
+ +

Factor mode

+ +
+
+ + +

+

Simple mode that handles Factor Syntax (Factor on WikiPedia).

+ +

MIME types defined: text/x-factor.

+ +
diff --git a/backend/webif/static/codemirror/mode/fcl/fcl.js b/backend/webif/static/codemirror/mode/fcl/fcl.js new file mode 100755 index 000000000..518116976 --- /dev/null +++ b/backend/webif/static/codemirror/mode/fcl/fcl.js @@ -0,0 +1,173 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("fcl", function(config) { + var indentUnit = config.indentUnit; + + var keywords = { + "term": true, + "method": true, "accu": true, + "rule": true, "then": true, "is": true, "and": true, "or": true, + "if": true, "default": true + }; + + var start_blocks = { + "var_input": true, + "var_output": true, + "fuzzify": true, + "defuzzify": true, + "function_block": true, + "ruleblock": true + }; + + var end_blocks = { + "end_ruleblock": true, + "end_defuzzify": true, + "end_function_block": true, + "end_fuzzify": true, + "end_var": true + }; + + var atoms = { + "true": true, "false": true, "nan": true, + "real": true, "min": true, "max": true, "cog": true, "cogs": true + }; + + var isOperatorChar = /[+\-*&^%:=<>!|\/]/; + + function tokenBase(stream, state) { + var ch = stream.next(); + + if (/[\d\.]/.test(ch)) { + if (ch == ".") { + stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); + } else if (ch == "0") { + stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); + } else { + stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); + } + return "number"; + } + + if (ch == "/" || ch == "(") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + + var cur = stream.current().toLowerCase(); + if (keywords.propertyIsEnumerable(cur) || + start_blocks.propertyIsEnumerable(cur) || + end_blocks.propertyIsEnumerable(cur)) { + return "keyword"; + } + if (atoms.propertyIsEnumerable(cur)) return "atom"; + return "variable"; + } + + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if ((ch == "/" || ch == ")") && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + + function popContext(state) { + if (!state.context.prev) return; + var t = state.context.type; + if (t == "end_block") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + var cur = stream.current().toLowerCase(); + + if (start_blocks.propertyIsEnumerable(cur)) pushContext(state, stream.column(), "end_block"); + else if (end_blocks.propertyIsEnumerable(cur)) popContext(state); + + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null) return 0; + var ctx = state.context; + + var closing = end_blocks.propertyIsEnumerable(textAfter); + if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "ryk", + fold: "brace", + blockCommentStart: "(*", + blockCommentEnd: "*)", + lineComment: "//" + }; +}); + +CodeMirror.defineMIME("text/x-fcl", "fcl"); +}); diff --git a/backend/webif/static/codemirror/mode/fcl/index.html b/backend/webif/static/codemirror/mode/fcl/index.html new file mode 100755 index 000000000..3c18d0b3c --- /dev/null +++ b/backend/webif/static/codemirror/mode/fcl/index.html @@ -0,0 +1,108 @@ + + +CodeMirror: FCL mode + + + + + + + + + + + +
+

FCL mode

+
+ + + +

MIME type: text/x-fcl

+
diff --git a/backend/webif/static/codemirror/mode/forth/forth.js b/backend/webif/static/codemirror/mode/forth/forth.js new file mode 100755 index 000000000..1f519d886 --- /dev/null +++ b/backend/webif/static/codemirror/mode/forth/forth.js @@ -0,0 +1,180 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Author: Aliaksei Chapyzhenka + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function toWordList(words) { + var ret = []; + words.split(' ').forEach(function(e){ + ret.push({name: e}); + }); + return ret; + } + + var coreWordList = toWordList( +'INVERT AND OR XOR\ + 2* 2/ LSHIFT RSHIFT\ + 0= = 0< < > U< MIN MAX\ + 2DROP 2DUP 2OVER 2SWAP ?DUP DEPTH DROP DUP OVER ROT SWAP\ + >R R> R@\ + + - 1+ 1- ABS NEGATE\ + S>D * M* UM*\ + FM/MOD SM/REM UM/MOD */ */MOD / /MOD MOD\ + HERE , @ ! CELL+ CELLS C, C@ C! CHARS 2@ 2!\ + ALIGN ALIGNED +! ALLOT\ + CHAR [CHAR] [ ] BL\ + FIND EXECUTE IMMEDIATE COUNT LITERAL STATE\ + ; DOES> >BODY\ + EVALUATE\ + SOURCE >IN\ + <# # #S #> HOLD SIGN BASE >NUMBER HEX DECIMAL\ + FILL MOVE\ + . CR EMIT SPACE SPACES TYPE U. .R U.R\ + ACCEPT\ + TRUE FALSE\ + <> U> 0<> 0>\ + NIP TUCK ROLL PICK\ + 2>R 2R@ 2R>\ + WITHIN UNUSED MARKER\ + I J\ + TO\ + COMPILE, [COMPILE]\ + SAVE-INPUT RESTORE-INPUT\ + PAD ERASE\ + 2LITERAL DNEGATE\ + D- D+ D0< D0= D2* D2/ D< D= DMAX DMIN D>S DABS\ + M+ M*/ D. D.R 2ROT DU<\ + CATCH THROW\ + FREE RESIZE ALLOCATE\ + CS-PICK CS-ROLL\ + GET-CURRENT SET-CURRENT FORTH-WORDLIST GET-ORDER SET-ORDER\ + PREVIOUS SEARCH-WORDLIST WORDLIST FIND ALSO ONLY FORTH DEFINITIONS ORDER\ + -TRAILING /STRING SEARCH COMPARE CMOVE CMOVE> BLANK SLITERAL'); + + var immediateWordList = toWordList('IF ELSE THEN BEGIN WHILE REPEAT UNTIL RECURSE [IF] [ELSE] [THEN] ?DO DO LOOP +LOOP UNLOOP LEAVE EXIT AGAIN CASE OF ENDOF ENDCASE'); + + CodeMirror.defineMode('forth', function() { + function searchWordList (wordList, word) { + var i; + for (i = wordList.length - 1; i >= 0; i--) { + if (wordList[i].name === word.toUpperCase()) { + return wordList[i]; + } + } + return undefined; + } + return { + startState: function() { + return { + state: '', + base: 10, + coreWordList: coreWordList, + immediateWordList: immediateWordList, + wordList: [] + }; + }, + token: function (stream, stt) { + var mat; + if (stream.eatSpace()) { + return null; + } + if (stt.state === '') { // interpretation + if (stream.match(/^(\]|:NONAME)(\s|$)/i)) { + stt.state = ' compilation'; + return 'builtin compilation'; + } + mat = stream.match(/^(\:)\s+(\S+)(\s|$)+/); + if (mat) { + stt.wordList.push({name: mat[2].toUpperCase()}); + stt.state = ' compilation'; + return 'def' + stt.state; + } + mat = stream.match(/^(VARIABLE|2VARIABLE|CONSTANT|2CONSTANT|CREATE|POSTPONE|VALUE|WORD)\s+(\S+)(\s|$)+/i); + if (mat) { + stt.wordList.push({name: mat[2].toUpperCase()}); + return 'def' + stt.state; + } + mat = stream.match(/^(\'|\[\'\])\s+(\S+)(\s|$)+/); + if (mat) { + return 'builtin' + stt.state; + } + } else { // compilation + // ; [ + if (stream.match(/^(\;|\[)(\s)/)) { + stt.state = ''; + stream.backUp(1); + return 'builtin compilation'; + } + if (stream.match(/^(\;|\[)($)/)) { + stt.state = ''; + return 'builtin compilation'; + } + if (stream.match(/^(POSTPONE)\s+\S+(\s|$)+/)) { + return 'builtin'; + } + } + + // dynamic wordlist + mat = stream.match(/^(\S+)(\s+|$)/); + if (mat) { + if (searchWordList(stt.wordList, mat[1]) !== undefined) { + return 'variable' + stt.state; + } + + // comments + if (mat[1] === '\\') { + stream.skipToEnd(); + return 'comment' + stt.state; + } + + // core words + if (searchWordList(stt.coreWordList, mat[1]) !== undefined) { + return 'builtin' + stt.state; + } + if (searchWordList(stt.immediateWordList, mat[1]) !== undefined) { + return 'keyword' + stt.state; + } + + if (mat[1] === '(') { + stream.eatWhile(function (s) { return s !== ')'; }); + stream.eat(')'); + return 'comment' + stt.state; + } + + // // strings + if (mat[1] === '.(') { + stream.eatWhile(function (s) { return s !== ')'; }); + stream.eat(')'); + return 'string' + stt.state; + } + if (mat[1] === 'S"' || mat[1] === '."' || mat[1] === 'C"') { + stream.eatWhile(function (s) { return s !== '"'; }); + stream.eat('"'); + return 'string' + stt.state; + } + + // numbers + if (mat[1] - 0xfffffffff) { + return 'number' + stt.state; + } + // if (mat[1].match(/^[-+]?[0-9]+\.[0-9]*/)) { + // return 'number' + stt.state; + // } + + return 'atom' + stt.state; + } + } + }; + }); + CodeMirror.defineMIME("text/x-forth", "forth"); +}); diff --git a/backend/webif/static/codemirror/mode/forth/index.html b/backend/webif/static/codemirror/mode/forth/index.html new file mode 100755 index 000000000..ae8cd3458 --- /dev/null +++ b/backend/webif/static/codemirror/mode/forth/index.html @@ -0,0 +1,75 @@ + + +CodeMirror: Forth mode + + + + + + + + + + + +
+ +

Forth mode

+ +
+
+ + + +

Simple mode that handle Forth-Syntax (Forth on WikiPedia).

+ +

MIME types defined: text/x-forth.

+ +
diff --git a/backend/webif/static/codemirror/mode/fortran/fortran.js b/backend/webif/static/codemirror/mode/fortran/fortran.js new file mode 100755 index 000000000..4d88f006a --- /dev/null +++ b/backend/webif/static/codemirror/mode/fortran/fortran.js @@ -0,0 +1,188 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("fortran", function() { + function words(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) { + keys[array[i]] = true; + } + return keys; + } + + var keywords = words([ + "abstract", "accept", "allocatable", "allocate", + "array", "assign", "asynchronous", "backspace", + "bind", "block", "byte", "call", "case", + "class", "close", "common", "contains", + "continue", "cycle", "data", "deallocate", + "decode", "deferred", "dimension", "do", + "elemental", "else", "encode", "end", + "endif", "entry", "enumerator", "equivalence", + "exit", "external", "extrinsic", "final", + "forall", "format", "function", "generic", + "go", "goto", "if", "implicit", "import", "include", + "inquire", "intent", "interface", "intrinsic", + "module", "namelist", "non_intrinsic", + "non_overridable", "none", "nopass", + "nullify", "open", "optional", "options", + "parameter", "pass", "pause", "pointer", + "print", "private", "program", "protected", + "public", "pure", "read", "recursive", "result", + "return", "rewind", "save", "select", "sequence", + "stop", "subroutine", "target", "then", "to", "type", + "use", "value", "volatile", "where", "while", + "write"]); + var builtins = words(["abort", "abs", "access", "achar", "acos", + "adjustl", "adjustr", "aimag", "aint", "alarm", + "all", "allocated", "alog", "amax", "amin", + "amod", "and", "anint", "any", "asin", + "associated", "atan", "besj", "besjn", "besy", + "besyn", "bit_size", "btest", "cabs", "ccos", + "ceiling", "cexp", "char", "chdir", "chmod", + "clog", "cmplx", "command_argument_count", + "complex", "conjg", "cos", "cosh", "count", + "cpu_time", "cshift", "csin", "csqrt", "ctime", + "c_funloc", "c_loc", "c_associated", "c_null_ptr", + "c_null_funptr", "c_f_pointer", "c_null_char", + "c_alert", "c_backspace", "c_form_feed", + "c_new_line", "c_carriage_return", + "c_horizontal_tab", "c_vertical_tab", "dabs", + "dacos", "dasin", "datan", "date_and_time", + "dbesj", "dbesj", "dbesjn", "dbesy", "dbesy", + "dbesyn", "dble", "dcos", "dcosh", "ddim", "derf", + "derfc", "dexp", "digits", "dim", "dint", "dlog", + "dlog", "dmax", "dmin", "dmod", "dnint", + "dot_product", "dprod", "dsign", "dsinh", + "dsin", "dsqrt", "dtanh", "dtan", "dtime", + "eoshift", "epsilon", "erf", "erfc", "etime", + "exit", "exp", "exponent", "extends_type_of", + "fdate", "fget", "fgetc", "float", "floor", + "flush", "fnum", "fputc", "fput", "fraction", + "fseek", "fstat", "ftell", "gerror", "getarg", + "get_command", "get_command_argument", + "get_environment_variable", "getcwd", + "getenv", "getgid", "getlog", "getpid", + "getuid", "gmtime", "hostnm", "huge", "iabs", + "iachar", "iand", "iargc", "ibclr", "ibits", + "ibset", "ichar", "idate", "idim", "idint", + "idnint", "ieor", "ierrno", "ifix", "imag", + "imagpart", "index", "int", "ior", "irand", + "isatty", "ishft", "ishftc", "isign", + "iso_c_binding", "is_iostat_end", "is_iostat_eor", + "itime", "kill", "kind", "lbound", "len", "len_trim", + "lge", "lgt", "link", "lle", "llt", "lnblnk", "loc", + "log", "logical", "long", "lshift", "lstat", "ltime", + "matmul", "max", "maxexponent", "maxloc", "maxval", + "mclock", "merge", "move_alloc", "min", "minexponent", + "minloc", "minval", "mod", "modulo", "mvbits", + "nearest", "new_line", "nint", "not", "or", "pack", + "perror", "precision", "present", "product", "radix", + "rand", "random_number", "random_seed", "range", + "real", "realpart", "rename", "repeat", "reshape", + "rrspacing", "rshift", "same_type_as", "scale", + "scan", "second", "selected_int_kind", + "selected_real_kind", "set_exponent", "shape", + "short", "sign", "signal", "sinh", "sin", "sleep", + "sngl", "spacing", "spread", "sqrt", "srand", "stat", + "sum", "symlnk", "system", "system_clock", "tan", + "tanh", "time", "tiny", "transfer", "transpose", + "trim", "ttynam", "ubound", "umask", "unlink", + "unpack", "verify", "xor", "zabs", "zcos", "zexp", + "zlog", "zsin", "zsqrt"]); + + var dataTypes = words(["c_bool", "c_char", "c_double", "c_double_complex", + "c_float", "c_float_complex", "c_funptr", "c_int", + "c_int16_t", "c_int32_t", "c_int64_t", "c_int8_t", + "c_int_fast16_t", "c_int_fast32_t", "c_int_fast64_t", + "c_int_fast8_t", "c_int_least16_t", "c_int_least32_t", + "c_int_least64_t", "c_int_least8_t", "c_intmax_t", + "c_intptr_t", "c_long", "c_long_double", + "c_long_double_complex", "c_long_long", "c_ptr", + "c_short", "c_signed_char", "c_size_t", "character", + "complex", "double", "integer", "logical", "real"]); + var isOperatorChar = /[+\-*&=<>\/\:]/; + var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i"); + + function tokenBase(stream, state) { + + if (stream.match(litOperator)){ + return 'operator'; + } + + var ch = stream.next(); + if (ch == "!") { + stream.skipToEnd(); + return "comment"; + } + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\[\]\(\),]/.test(ch)) { + return null; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_]/); + var word = stream.current().toLowerCase(); + + if (keywords.hasOwnProperty(word)){ + return 'keyword'; + } + if (builtins.hasOwnProperty(word) || dataTypes.hasOwnProperty(word)) { + return 'builtin'; + } + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end || !escaped) state.tokenize = null; + return "string"; + }; + } + + // Interface + + return { + startState: function() { + return {tokenize: null}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + return style; + } + }; +}); + +CodeMirror.defineMIME("text/x-fortran", "fortran"); + +}); diff --git a/backend/webif/static/codemirror/mode/fortran/index.html b/backend/webif/static/codemirror/mode/fortran/index.html new file mode 100755 index 000000000..9aed0efcc --- /dev/null +++ b/backend/webif/static/codemirror/mode/fortran/index.html @@ -0,0 +1,81 @@ + + +CodeMirror: Fortran mode + + + + + + + + + +
+

Fortran mode

+ + +
+ + + +

MIME types defined: text/x-fortran.

+
diff --git a/backend/webif/static/codemirror/mode/gas/gas.js b/backend/webif/static/codemirror/mode/gas/gas.js new file mode 100755 index 000000000..0c74bedc5 --- /dev/null +++ b/backend/webif/static/codemirror/mode/gas/gas.js @@ -0,0 +1,345 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("gas", function(_config, parserConfig) { + 'use strict'; + + // If an architecture is specified, its initialization function may + // populate this array with custom parsing functions which will be + // tried in the event that the standard functions do not find a match. + var custom = []; + + // The symbol used to start a line comment changes based on the target + // architecture. + // If no architecture is pased in "parserConfig" then only multiline + // comments will have syntax support. + var lineCommentStartSymbol = ""; + + // These directives are architecture independent. + // Machine specific directives should go in their respective + // architecture initialization function. + // Reference: + // http://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops + var directives = { + ".abort" : "builtin", + ".align" : "builtin", + ".altmacro" : "builtin", + ".ascii" : "builtin", + ".asciz" : "builtin", + ".balign" : "builtin", + ".balignw" : "builtin", + ".balignl" : "builtin", + ".bundle_align_mode" : "builtin", + ".bundle_lock" : "builtin", + ".bundle_unlock" : "builtin", + ".byte" : "builtin", + ".cfi_startproc" : "builtin", + ".comm" : "builtin", + ".data" : "builtin", + ".def" : "builtin", + ".desc" : "builtin", + ".dim" : "builtin", + ".double" : "builtin", + ".eject" : "builtin", + ".else" : "builtin", + ".elseif" : "builtin", + ".end" : "builtin", + ".endef" : "builtin", + ".endfunc" : "builtin", + ".endif" : "builtin", + ".equ" : "builtin", + ".equiv" : "builtin", + ".eqv" : "builtin", + ".err" : "builtin", + ".error" : "builtin", + ".exitm" : "builtin", + ".extern" : "builtin", + ".fail" : "builtin", + ".file" : "builtin", + ".fill" : "builtin", + ".float" : "builtin", + ".func" : "builtin", + ".global" : "builtin", + ".gnu_attribute" : "builtin", + ".hidden" : "builtin", + ".hword" : "builtin", + ".ident" : "builtin", + ".if" : "builtin", + ".incbin" : "builtin", + ".include" : "builtin", + ".int" : "builtin", + ".internal" : "builtin", + ".irp" : "builtin", + ".irpc" : "builtin", + ".lcomm" : "builtin", + ".lflags" : "builtin", + ".line" : "builtin", + ".linkonce" : "builtin", + ".list" : "builtin", + ".ln" : "builtin", + ".loc" : "builtin", + ".loc_mark_labels" : "builtin", + ".local" : "builtin", + ".long" : "builtin", + ".macro" : "builtin", + ".mri" : "builtin", + ".noaltmacro" : "builtin", + ".nolist" : "builtin", + ".octa" : "builtin", + ".offset" : "builtin", + ".org" : "builtin", + ".p2align" : "builtin", + ".popsection" : "builtin", + ".previous" : "builtin", + ".print" : "builtin", + ".protected" : "builtin", + ".psize" : "builtin", + ".purgem" : "builtin", + ".pushsection" : "builtin", + ".quad" : "builtin", + ".reloc" : "builtin", + ".rept" : "builtin", + ".sbttl" : "builtin", + ".scl" : "builtin", + ".section" : "builtin", + ".set" : "builtin", + ".short" : "builtin", + ".single" : "builtin", + ".size" : "builtin", + ".skip" : "builtin", + ".sleb128" : "builtin", + ".space" : "builtin", + ".stab" : "builtin", + ".string" : "builtin", + ".struct" : "builtin", + ".subsection" : "builtin", + ".symver" : "builtin", + ".tag" : "builtin", + ".text" : "builtin", + ".title" : "builtin", + ".type" : "builtin", + ".uleb128" : "builtin", + ".val" : "builtin", + ".version" : "builtin", + ".vtable_entry" : "builtin", + ".vtable_inherit" : "builtin", + ".warning" : "builtin", + ".weak" : "builtin", + ".weakref" : "builtin", + ".word" : "builtin" + }; + + var registers = {}; + + function x86(_parserConfig) { + lineCommentStartSymbol = "#"; + + registers.ax = "variable"; + registers.eax = "variable-2"; + registers.rax = "variable-3"; + + registers.bx = "variable"; + registers.ebx = "variable-2"; + registers.rbx = "variable-3"; + + registers.cx = "variable"; + registers.ecx = "variable-2"; + registers.rcx = "variable-3"; + + registers.dx = "variable"; + registers.edx = "variable-2"; + registers.rdx = "variable-3"; + + registers.si = "variable"; + registers.esi = "variable-2"; + registers.rsi = "variable-3"; + + registers.di = "variable"; + registers.edi = "variable-2"; + registers.rdi = "variable-3"; + + registers.sp = "variable"; + registers.esp = "variable-2"; + registers.rsp = "variable-3"; + + registers.bp = "variable"; + registers.ebp = "variable-2"; + registers.rbp = "variable-3"; + + registers.ip = "variable"; + registers.eip = "variable-2"; + registers.rip = "variable-3"; + + registers.cs = "keyword"; + registers.ds = "keyword"; + registers.ss = "keyword"; + registers.es = "keyword"; + registers.fs = "keyword"; + registers.gs = "keyword"; + } + + function armv6(_parserConfig) { + // Reference: + // http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf + // http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301h/DDI0301H_arm1176jzfs_r0p7_trm.pdf + lineCommentStartSymbol = "@"; + directives.syntax = "builtin"; + + registers.r0 = "variable"; + registers.r1 = "variable"; + registers.r2 = "variable"; + registers.r3 = "variable"; + registers.r4 = "variable"; + registers.r5 = "variable"; + registers.r6 = "variable"; + registers.r7 = "variable"; + registers.r8 = "variable"; + registers.r9 = "variable"; + registers.r10 = "variable"; + registers.r11 = "variable"; + registers.r12 = "variable"; + + registers.sp = "variable-2"; + registers.lr = "variable-2"; + registers.pc = "variable-2"; + registers.r13 = registers.sp; + registers.r14 = registers.lr; + registers.r15 = registers.pc; + + custom.push(function(ch, stream) { + if (ch === '#') { + stream.eatWhile(/\w/); + return "number"; + } + }); + } + + var arch = (parserConfig.architecture || "x86").toLowerCase(); + if (arch === "x86") { + x86(parserConfig); + } else if (arch === "arm" || arch === "armv6") { + armv6(parserConfig); + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next === end && !escaped) { + return false; + } + escaped = !escaped && next === "\\"; + } + return escaped; + } + + function clikeComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (ch === "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch === "*"); + } + return "comment"; + } + + return { + startState: function() { + return { + tokenize: null + }; + }, + + token: function(stream, state) { + if (state.tokenize) { + return state.tokenize(stream, state); + } + + if (stream.eatSpace()) { + return null; + } + + var style, cur, ch = stream.next(); + + if (ch === "/") { + if (stream.eat("*")) { + state.tokenize = clikeComment; + return clikeComment(stream, state); + } + } + + if (ch === lineCommentStartSymbol) { + stream.skipToEnd(); + return "comment"; + } + + if (ch === '"') { + nextUntilUnescaped(stream, '"'); + return "string"; + } + + if (ch === '.') { + stream.eatWhile(/\w/); + cur = stream.current().toLowerCase(); + style = directives[cur]; + return style || null; + } + + if (ch === '=') { + stream.eatWhile(/\w/); + return "tag"; + } + + if (ch === '{') { + return "braket"; + } + + if (ch === '}') { + return "braket"; + } + + if (/\d/.test(ch)) { + if (ch === "0" && stream.eat("x")) { + stream.eatWhile(/[0-9a-fA-F]/); + return "number"; + } + stream.eatWhile(/\d/); + return "number"; + } + + if (/\w/.test(ch)) { + stream.eatWhile(/\w/); + if (stream.eat(":")) { + return 'tag'; + } + cur = stream.current().toLowerCase(); + style = registers[cur]; + return style || null; + } + + for (var i = 0; i < custom.length; i++) { + style = custom[i](ch, stream, state); + if (style) { + return style; + } + } + }, + + lineComment: lineCommentStartSymbol, + blockCommentStart: "/*", + blockCommentEnd: "*/" + }; +}); + +}); diff --git a/backend/webif/static/codemirror/mode/gas/index.html b/backend/webif/static/codemirror/mode/gas/index.html new file mode 100755 index 000000000..df75ca2db --- /dev/null +++ b/backend/webif/static/codemirror/mode/gas/index.html @@ -0,0 +1,68 @@ + + +CodeMirror: Gas mode + + + + + + + + + +
+

Gas mode

+
+ +
+ + + +

Handles AT&T assembler syntax (more specifically this handles + the GNU Assembler (gas) syntax.) + It takes a single optional configuration parameter: + architecture, which can be one of "ARM", + "ARMv6" or "x86". + Including the parameter adds syntax for the registers and special + directives for the supplied architecture. + +

MIME types defined: text/x-gas

+
diff --git a/backend/webif/static/codemirror/mode/gfm/gfm.js b/backend/webif/static/codemirror/mode/gfm/gfm.js new file mode 100755 index 000000000..471ae906b --- /dev/null +++ b/backend/webif/static/codemirror/mode/gfm/gfm.js @@ -0,0 +1,129 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i + +CodeMirror.defineMode("gfm", function(config, modeConfig) { + var codeDepth = 0; + function blankLine(state) { + state.code = false; + return null; + } + var gfmOverlay = { + startState: function() { + return { + code: false, + codeBlock: false, + ateSpace: false + }; + }, + copyState: function(s) { + return { + code: s.code, + codeBlock: s.codeBlock, + ateSpace: s.ateSpace + }; + }, + token: function(stream, state) { + state.combineTokens = null; + + // Hack to prevent formatting override inside code blocks (block and inline) + if (state.codeBlock) { + if (stream.match(/^```+/)) { + state.codeBlock = false; + return null; + } + stream.skipToEnd(); + return null; + } + if (stream.sol()) { + state.code = false; + } + if (stream.sol() && stream.match(/^```+/)) { + stream.skipToEnd(); + state.codeBlock = true; + return null; + } + // If this block is changed, it may need to be updated in Markdown mode + if (stream.peek() === '`') { + stream.next(); + var before = stream.pos; + stream.eatWhile('`'); + var difference = 1 + stream.pos - before; + if (!state.code) { + codeDepth = difference; + state.code = true; + } else { + if (difference === codeDepth) { // Must be exact + state.code = false; + } + } + return null; + } else if (state.code) { + stream.next(); + return null; + } + // Check if space. If so, links can be formatted later on + if (stream.eatSpace()) { + state.ateSpace = true; + return null; + } + if (stream.sol() || state.ateSpace) { + state.ateSpace = false; + if (modeConfig.gitHubSpice !== false) { + if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?=.{0,6}\d)(?:[a-f0-9]{7,40}\b)/)) { + // User/Project@SHA + // User@SHA + // SHA + state.combineTokens = true; + return "link"; + } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { + // User/Project#Num + // User#Num + // #Num + state.combineTokens = true; + return "link"; + } + } + } + if (stream.match(urlRE) && + stream.string.slice(stream.start - 2, stream.start) != "](" && + (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { + // URLs + // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls + // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine + // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL + state.combineTokens = true; + return "link"; + } + stream.next(); + return null; + }, + blankLine: blankLine + }; + + var markdownConfig = { + taskLists: true, + strikethrough: true, + emoji: true + }; + for (var attr in modeConfig) { + markdownConfig[attr] = modeConfig[attr]; + } + markdownConfig.name = "markdown"; + return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay); + +}, "markdown"); + + CodeMirror.defineMIME("text/x-gfm", "gfm"); +}); diff --git a/backend/webif/static/codemirror/mode/gfm/index.html b/backend/webif/static/codemirror/mode/gfm/index.html new file mode 100755 index 000000000..ea4bac15f --- /dev/null +++ b/backend/webif/static/codemirror/mode/gfm/index.html @@ -0,0 +1,136 @@ + + +CodeMirror: GFM mode + + + + + + + + + + + + + + + + + +
+

GFM mode

+
+ + + +

Optionally depends on other modes for properly highlighted code blocks.

+ +

Gfm mode supports these options (apart those from base Markdown mode):

+
    +
  • + +
    gitHubSpice: boolean
    +
    Hashes, issues... (default: true).
    +
    +
  • +
  • + +
    taskLists: boolean
    +
    - [ ] syntax (default: true).
    +
    +
  • +
  • + +
    strikethrough: boolean
    +
    ~~foo~~ syntax (default: true).
    +
    +
  • +
  • + +
    emoji: boolean
    +
    :emoji: syntax (default: true).
    +
    +
  • +
+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/gfm/test.js b/backend/webif/static/codemirror/mode/gfm/test.js new file mode 100755 index 000000000..e7135264c --- /dev/null +++ b/backend/webif/static/codemirror/mode/gfm/test.js @@ -0,0 +1,198 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var config = {tabSize: 4, indentUnit: 2} + var mode = CodeMirror.getMode(config, "gfm"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + var modeHighlightFormatting = CodeMirror.getMode(config, {name: "gfm", highlightFormatting: true}); + function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); } + + FT("codeBackticks", + "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]"); + + FT("doubleBackticks", + "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]"); + + FT("taskList", + "[variable-2&formatting&formatting-list&formatting-list-ul - ][meta&formatting&formatting-task [ ]]][variable-2 foo]", + "[variable-2&formatting&formatting-list&formatting-list-ul - ][property&formatting&formatting-task [x]]][variable-2 foo]"); + + FT("formatting_strikethrough", + "[strikethrough&formatting&formatting-strikethrough ~~][strikethrough foo][strikethrough&formatting&formatting-strikethrough ~~]"); + + FT("formatting_strikethrough", + "foo [strikethrough&formatting&formatting-strikethrough ~~][strikethrough bar][strikethrough&formatting&formatting-strikethrough ~~]"); + + FT("formatting_emoji", + "foo [builtin&formatting&formatting-emoji :smile:] foo"); + + MT("emInWordAsterisk", + "foo[em *bar*]hello"); + + MT("emInWordUnderscore", + "foo_bar_hello"); + + MT("emStrongUnderscore", + "[em&strong ___foo___] bar"); + + MT("taskListAsterisk", + "[variable-2 * ][link&variable-2 [[]]][variable-2 foo]", // Invalid; must have space or x between [] + "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]", // Invalid; must have space after ] + "[variable-2 * ][link&variable-2 [[x]]][variable-2 hello]", // Invalid; must have space after ] + "[variable-2 * ][meta [ ]]][variable-2 ][link&variable-2 [[world]]]", // Valid; tests reference style links + " [variable-3 * ][property [x]]][variable-3 foo]"); // Valid; can be nested + + MT("taskListPlus", + "[variable-2 + ][link&variable-2 [[]]][variable-2 foo]", // Invalid; must have space or x between [] + "[variable-2 + ][link&variable-2 [[x]]][variable-2 hello]", // Invalid; must have space after ] + "[variable-2 + ][meta [ ]]][variable-2 ][link&variable-2 [[world]]]", // Valid; tests reference style links + " [variable-3 + ][property [x]]][variable-3 foo]"); // Valid; can be nested + + MT("taskListDash", + "[variable-2 - ][link&variable-2 [[]]][variable-2 foo]", // Invalid; must have space or x between [] + "[variable-2 - ][link&variable-2 [[x]]][variable-2 hello]", // Invalid; must have space after ] + "[variable-2 - ][meta [ ]]][variable-2 world]", // Valid; tests reference style links + " [variable-3 - ][property [x]]][variable-3 foo]"); // Valid; can be nested + + MT("taskListNumber", + "[variable-2 1. ][link&variable-2 [[]]][variable-2 foo]", // Invalid; must have space or x between [] + "[variable-2 2. ][link&variable-2 [[ ]]][variable-2 bar]", // Invalid; must have space after ] + "[variable-2 3. ][meta [ ]]][variable-2 world]", // Valid; tests reference style links + " [variable-3 1. ][property [x]]][variable-3 foo]"); // Valid; can be nested + + MT("SHA", + "foo [link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] bar"); + + MT("SHAEmphasis", + "[em *foo ][em&link be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]"); + + MT("shortSHA", + "foo [link be6a8cc] bar"); + + MT("tooShortSHA", + "foo be6a8c bar"); + + MT("longSHA", + "foo be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd22 bar"); + + MT("badSHA", + "foo be6a8cc1c1ecfe9489fb51e4869af15a13fc2cg2 bar"); + + MT("userSHA", + "foo [link bar@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] hello"); + + MT("userSHAEmphasis", + "[em *foo ][em&link bar@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]"); + + MT("userProjectSHA", + "foo [link bar/hello@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2] world"); + + MT("userProjectSHAEmphasis", + "[em *foo ][em&link bar/hello@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]"); + + MT("wordSHA", + "ask for feedbac") + + MT("num", + "foo [link #1] bar"); + + MT("numEmphasis", + "[em *foo ][em&link #1][em *]"); + + MT("badNum", + "foo #1bar hello"); + + MT("userNum", + "foo [link bar#1] hello"); + + MT("userNumEmphasis", + "[em *foo ][em&link bar#1][em *]"); + + MT("userProjectNum", + "foo [link bar/hello#1] world"); + + MT("userProjectNumEmphasis", + "[em *foo ][em&link bar/hello#1][em *]"); + + MT("vanillaLink", + "foo [link http://www.example.com/] bar"); + + MT("vanillaLinkNoScheme", + "foo [link www.example.com] bar"); + + MT("vanillaLinkHttps", + "foo [link https://www.example.com/] bar"); + + MT("vanillaLinkDataSchema", + "foo [link data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==] bar"); + + MT("vanillaLinkPunctuation", + "foo [link http://www.example.com/]. bar"); + + MT("vanillaLinkExtension", + "foo [link http://www.example.com/index.html] bar"); + + MT("vanillaLinkEmphasis", + "foo [em *][em&link http://www.example.com/index.html][em *] bar"); + + MT("notALink", + "foo asfd:asdf bar"); + + MT("notALink", + "[comment ``foo `bar` http://www.example.com/``] hello"); + + MT("notALink", + "[comment `foo]", + "[comment&link http://www.example.com/]", + "[comment `] foo", + "", + "[link http://www.example.com/]"); + + MT("strikethrough", + "[strikethrough ~~foo~~]"); + + MT("strikethroughWithStartingSpace", + "~~ foo~~"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo~~~]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~ bar]"); + + MT("strikethroughUnclosedStrayTildes", + "[strikethrough ~~foo ~~ bar~~]hello"); + + MT("strikethroughOneLetter", + "[strikethrough ~~a~~]"); + + MT("strikethroughWrapped", + "[strikethrough ~~foo]", + "[strikethrough foo~~]"); + + MT("strikethroughParagraph", + "[strikethrough ~~foo]", + "", + "foo[strikethrough ~~bar]"); + + MT("strikethroughEm", + "[strikethrough ~~foo][em&strikethrough *bar*][strikethrough ~~]"); + + MT("strikethroughEm", + "[em *][em&strikethrough ~~foo~~][em *]"); + + MT("strikethroughStrong", + "[strikethrough ~~][strong&strikethrough **foo**][strikethrough ~~]"); + + MT("strikethroughStrong", + "[strong **][strong&strikethrough ~~foo~~][strong **]"); + + MT("emoji", + "text [builtin :blush:] text [builtin :v:] text [builtin :+1:] text", + ":text text: [builtin :smiley_cat:]"); + +})(); diff --git a/backend/webif/static/codemirror/mode/gherkin/gherkin.js b/backend/webif/static/codemirror/mode/gherkin/gherkin.js new file mode 100755 index 000000000..fc2ebee16 --- /dev/null +++ b/backend/webif/static/codemirror/mode/gherkin/gherkin.js @@ -0,0 +1,178 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* +Gherkin mode - http://www.cukes.info/ +Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues +*/ + +// Following Objs from Brackets implementation: https://github.com/tregusti/brackets-gherkin/blob/master/main.js +//var Quotes = { +// SINGLE: 1, +// DOUBLE: 2 +//}; + +//var regex = { +// keywords: /(Feature| {2}(Scenario|In order to|As|I)| {4}(Given|When|Then|And))/ +//}; + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("gherkin", function () { + return { + startState: function () { + return { + lineNumber: 0, + tableHeaderLine: false, + allowFeature: true, + allowBackground: false, + allowScenario: false, + allowSteps: false, + allowPlaceholders: false, + allowMultilineArgument: false, + inMultilineString: false, + inMultilineTable: false, + inKeywordLine: false + }; + }, + token: function (stream, state) { + if (stream.sol()) { + state.lineNumber++; + state.inKeywordLine = false; + if (state.inMultilineTable) { + state.tableHeaderLine = false; + if (!stream.match(/\s*\|/, false)) { + state.allowMultilineArgument = false; + state.inMultilineTable = false; + } + } + } + + stream.eatSpace(); + + if (state.allowMultilineArgument) { + + // STRING + if (state.inMultilineString) { + if (stream.match('"""')) { + state.inMultilineString = false; + state.allowMultilineArgument = false; + } else { + stream.match(/.*/); + } + return "string"; + } + + // TABLE + if (state.inMultilineTable) { + if (stream.match(/\|\s*/)) { + return "bracket"; + } else { + stream.match(/[^\|]*/); + return state.tableHeaderLine ? "header" : "string"; + } + } + + // DETECT START + if (stream.match('"""')) { + // String + state.inMultilineString = true; + return "string"; + } else if (stream.match("|")) { + // Table + state.inMultilineTable = true; + state.tableHeaderLine = true; + return "bracket"; + } + + } + + // LINE COMMENT + if (stream.match(/#.*/)) { + return "comment"; + + // TAG + } else if (!state.inKeywordLine && stream.match(/@\S+/)) { + return "tag"; + + // FEATURE + } else if (!state.inKeywordLine && state.allowFeature && stream.match(/(機能|功能|フィーチャ|기능|โครงหลัก|ความสามารถ|ความต้องการทางธุรกิจ|ಹೆಚ್ಚಳ|గుణము|ਮੁਹਾਂਦਰਾ|ਨਕਸ਼ ਨੁਹਾਰ|ਖਾਸੀਅਤ|रूप लेख|وِیژگی|خاصية|תכונה|Функціонал|Функция|Функционалност|Функционал|Үзенчәлеклелек|Свойство|Особина|Мөмкинлек|Могућност|Λειτουργία|Δυνατότητα|Właściwość|Vlastnosť|Trajto|Tính năng|Savybė|Pretty much|Požiadavka|Požadavek|Potrzeba biznesowa|Özellik|Osobina|Ominaisuus|Omadus|OH HAI|Mogućnost|Mogucnost|Jellemző|Hwæt|Hwaet|Funzionalità|Funktionalitéit|Funktionalität|Funkcja|Funkcionalnost|Funkcionalitāte|Funkcia|Fungsi|Functionaliteit|Funcționalitate|Funcţionalitate|Functionalitate|Funcionalitat|Funcionalidade|Fonctionnalité|Fitur|Fīča|Feature|Eiginleiki|Egenskap|Egenskab|Característica|Caracteristica|Business Need|Aspekt|Arwedd|Ahoy matey!|Ability):/)) { + state.allowScenario = true; + state.allowBackground = true; + state.allowPlaceholders = false; + state.allowSteps = false; + state.allowMultilineArgument = false; + state.inKeywordLine = true; + return "keyword"; + + // BACKGROUND + } else if (!state.inKeywordLine && state.allowBackground && stream.match(/(背景|배경|แนวคิด|ಹಿನ್ನೆಲೆ|నేపథ్యం|ਪਿਛੋਕੜ|पृष्ठभूमि|زمینه|الخلفية|רקע|Тарих|Предыстория|Предистория|Позадина|Передумова|Основа|Контекст|Кереш|Υπόβαθρο|Założenia|Yo\-ho\-ho|Tausta|Taust|Situācija|Rerefons|Pozadina|Pozadie|Pozadí|Osnova|Latar Belakang|Kontext|Konteksts|Kontekstas|Kontekst|Háttér|Hannergrond|Grundlage|Geçmiş|Fundo|Fono|First off|Dis is what went down|Dasar|Contexto|Contexte|Context|Contesto|Cenário de Fundo|Cenario de Fundo|Cefndir|Bối cảnh|Bakgrunnur|Bakgrunn|Bakgrund|Baggrund|Background|B4|Antecedents|Antecedentes|Ær|Aer|Achtergrond):/)) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + state.allowMultilineArgument = false; + state.inKeywordLine = true; + return "keyword"; + + // SCENARIO OUTLINE + } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景大綱|场景大纲|劇本大綱|剧本大纲|テンプレ|シナリオテンプレート|シナリオテンプレ|シナリオアウトライン|시나리오 개요|สรุปเหตุการณ์|โครงสร้างของเหตุการณ์|ವಿವರಣೆ|కథనం|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਟਕਥਾ ਢਾਂਚਾ|परिदृश्य रूपरेखा|سيناريو مخطط|الگوی سناریو|תבנית תרחיש|Сценарийның төзелеше|Сценарий структураси|Структура сценарію|Структура сценария|Структура сценарија|Скица|Рамка на сценарий|Концепт|Περιγραφή Σεναρίου|Wharrimean is|Template Situai|Template Senario|Template Keadaan|Tapausaihio|Szenariogrundriss|Szablon scenariusza|Swa hwær swa|Swa hwaer swa|Struktura scenarija|Structură scenariu|Structura scenariu|Skica|Skenario konsep|Shiver me timbers|Senaryo taslağı|Schema dello scenario|Scenariomall|Scenariomal|Scenario Template|Scenario Outline|Scenario Amlinellol|Scenārijs pēc parauga|Scenarijaus šablonas|Reckon it's like|Raamstsenaarium|Plang vum Szenario|Plan du Scénario|Plan du scénario|Osnova scénáře|Osnova Scenára|Náčrt Scenáru|Náčrt Scénáře|Náčrt Scenára|MISHUN SRSLY|Menggariskan Senario|Lýsing Dæma|Lýsing Atburðarásar|Konturo de la scenaro|Koncept|Khung tình huống|Khung kịch bản|Forgatókönyv vázlat|Esquema do Cenário|Esquema do Cenario|Esquema del escenario|Esquema de l'escenari|Esbozo do escenario|Delineação do Cenário|Delineacao do Cenario|All y'all|Abstrakt Scenario|Abstract Scenario):/)) { + state.allowPlaceholders = true; + state.allowSteps = true; + state.allowMultilineArgument = false; + state.inKeywordLine = true; + return "keyword"; + + // EXAMPLES + } else if (state.allowScenario && stream.match(/(例子|例|サンプル|예|ชุดของเหตุการณ์|ชุดของตัวอย่าง|ಉದಾಹರಣೆಗಳು|ఉదాహరణలు|ਉਦਾਹਰਨਾਂ|उदाहरण|نمونه ها|امثلة|דוגמאות|Үрнәкләр|Сценарији|Примеры|Примери|Приклади|Мисоллар|Мисаллар|Σενάρια|Παραδείγματα|You'll wanna|Voorbeelden|Variantai|Tapaukset|Se þe|Se the|Se ðe|Scenarios|Scenariji|Scenarijai|Przykłady|Primjeri|Primeri|Příklady|Príklady|Piemēri|Példák|Pavyzdžiai|Paraugs|Örnekler|Juhtumid|Exemplos|Exemples|Exemple|Exempel|EXAMPLZ|Examples|Esempi|Enghreifftiau|Ekzemploj|Eksempler|Ejemplos|Dữ liệu|Dead men tell no tales|Dæmi|Contoh|Cenários|Cenarios|Beispiller|Beispiele|Atburðarásir):/)) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + state.allowMultilineArgument = true; + return "keyword"; + + // SCENARIO + } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景|场景|劇本|剧本|シナリオ|시나리오|เหตุการณ์|ಕಥಾಸಾರಾಂಶ|సన్నివేశం|ਪਟਕਥਾ|परिदृश्य|سيناريو|سناریو|תרחיש|Сценарій|Сценарио|Сценарий|Пример|Σενάριο|Tình huống|The thing of it is|Tapaus|Szenario|Swa|Stsenaarium|Skenario|Situai|Senaryo|Senario|Scenaro|Scenariusz|Scenariu|Scénario|Scenario|Scenarijus|Scenārijs|Scenarij|Scenarie|Scénář|Scenár|Primer|MISHUN|Kịch bản|Keadaan|Heave to|Forgatókönyv|Escenario|Escenari|Cenário|Cenario|Awww, look mate|Atburðarás):/)) { + state.allowPlaceholders = false; + state.allowSteps = true; + state.allowBackground = false; + state.allowMultilineArgument = false; + state.inKeywordLine = true; + return "keyword"; + + // STEPS + } else if (!state.inKeywordLine && state.allowSteps && stream.match(/(那麼|那么|而且|當|当|并且|同時|同时|前提|假设|假設|假定|假如|但是|但し|並且|もし|ならば|ただし|しかし|かつ|하지만|조건|먼저|만일|만약|단|그리고|그러면|และ |เมื่อ |แต่ |ดังนั้น |กำหนดให้ |ಸ್ಥಿತಿಯನ್ನು |ಮತ್ತು |ನೀಡಿದ |ನಂತರ |ಆದರೆ |మరియు |చెప్పబడినది |కాని |ఈ పరిస్థితిలో |అప్పుడు |ਪਰ |ਤਦ |ਜੇਕਰ |ਜਿਵੇਂ ਕਿ |ਜਦੋਂ |ਅਤੇ |यदि |परन्तु |पर |तब |तदा |तथा |जब |चूंकि |किन्तु |कदा |और |अगर |و |هنگامی |متى |لكن |عندما |ثم |بفرض |با فرض |اما |اذاً |آنگاه |כאשר |וגם |בהינתן |אזי |אז |אבל |Якщо |Һәм |Унда |Тоді |Тогда |То |Также |Та |Пусть |Припустимо, що |Припустимо |Онда |Но |Нехай |Нәтиҗәдә |Лекин |Ләкин |Коли |Когда |Когато |Када |Кад |К тому же |І |И |Задато |Задати |Задате |Если |Допустим |Дано |Дадено |Вә |Ва |Бирок |Әмма |Әйтик |Әгәр |Аммо |Али |Але |Агар |А також |А |Τότε |Όταν |Και |Δεδομένου |Αλλά |Þurh |Þegar |Þa þe |Þá |Þa |Zatati |Zakładając |Zadato |Zadate |Zadano |Zadani |Zadan |Za předpokladu |Za predpokladu |Youse know when youse got |Youse know like when |Yna |Yeah nah |Y'know |Y |Wun |Wtedy |When y'all |When |Wenn |WEN |wann |Ve |Và |Und |Un |ugeholl |Too right |Thurh |Thì |Then y'all |Then |Tha the |Tha |Tetapi |Tapi |Tak |Tada |Tad |Stel |Soit |Siis |Și |Şi |Si |Sed |Se |Så |Quando |Quand |Quan |Pryd |Potom |Pokud |Pokiaľ |Però |Pero |Pak |Oraz |Onda |Ond |Oletetaan |Og |Och |O zaman |Niin |Nhưng |När |Når |Mutta |Men |Mas |Maka |Majd |Mając |Mais |Maar |mä |Ma |Lorsque |Lorsqu'|Logo |Let go and haul |Kun |Kuid |Kui |Kiedy |Khi |Ketika |Kemudian |Keď |Když |Kaj |Kai |Kada |Kad |Jeżeli |Jeśli |Ja |It's just unbelievable |Ir |I CAN HAZ |I |Ha |Givun |Givet |Given y'all |Given |Gitt |Gegeven |Gegeben seien |Gegeben sei |Gdy |Gangway! |Fakat |Étant donnés |Etant donnés |Étant données |Etant données |Étant donnée |Etant donnée |Étant donné |Etant donné |Et |És |Entonces |Entón |Então |Entao |En |Eğer ki |Ef |Eeldades |E |Ðurh |Duota |Dun |Donitaĵo |Donat |Donada |Do |Diyelim ki |Diberi |Dengan |Den youse gotta |DEN |De |Dato |Dați fiind |Daţi fiind |Dati fiind |Dati |Date fiind |Date |Data |Dat fiind |Dar |Dann |dann |Dan |Dados |Dado |Dadas |Dada |Ða ðe |Ða |Cuando |Cho |Cando |Când |Cand |Cal |But y'all |But at the end of the day I reckon |BUT |But |Buh |Blimey! |Biết |Bet |Bagi |Aye |awer |Avast! |Atunci |Atesa |Atès |Apabila |Anrhegedig a |Angenommen |And y'all |And |AN |An |an |Amikor |Amennyiben |Ama |Als |Alors |Allora |Ali |Aleshores |Ale |Akkor |Ak |Adott |Ac |Aber |A zároveň |A tiež |A taktiež |A také |A |a |7 |\* )/)) { + state.inStep = true; + state.allowPlaceholders = true; + state.allowMultilineArgument = true; + state.inKeywordLine = true; + return "keyword"; + + // INLINE STRING + } else if (stream.match(/"[^"]*"?/)) { + return "string"; + + // PLACEHOLDER + } else if (state.allowPlaceholders && stream.match(/<[^>]*>?/)) { + return "variable"; + + // Fall through + } else { + stream.next(); + stream.eatWhile(/[^@"<#]/); + return null; + } + } + }; +}); + +CodeMirror.defineMIME("text/x-feature", "gherkin"); + +}); diff --git a/backend/webif/static/codemirror/mode/gherkin/index.html b/backend/webif/static/codemirror/mode/gherkin/index.html new file mode 100755 index 000000000..af8184c98 --- /dev/null +++ b/backend/webif/static/codemirror/mode/gherkin/index.html @@ -0,0 +1,48 @@ + + +CodeMirror: Gherkin mode + + + + + + + + + +
+

Gherkin mode

+
+ + +

MIME types defined: text/x-feature.

+ +
diff --git a/backend/webif/static/codemirror/mode/go/go.js b/backend/webif/static/codemirror/mode/go/go.js new file mode 100755 index 000000000..36131f10f --- /dev/null +++ b/backend/webif/static/codemirror/mode/go/go.js @@ -0,0 +1,187 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("go", function(config) { + var indentUnit = config.indentUnit; + + var keywords = { + "break":true, "case":true, "chan":true, "const":true, "continue":true, + "default":true, "defer":true, "else":true, "fallthrough":true, "for":true, + "func":true, "go":true, "goto":true, "if":true, "import":true, + "interface":true, "map":true, "package":true, "range":true, "return":true, + "select":true, "struct":true, "switch":true, "type":true, "var":true, + "bool":true, "byte":true, "complex64":true, "complex128":true, + "float32":true, "float64":true, "int8":true, "int16":true, "int32":true, + "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true, + "uint64":true, "int":true, "uint":true, "uintptr":true, "error": true, + "rune":true + }; + + var atoms = { + "true":true, "false":true, "iota":true, "nil":true, "append":true, + "cap":true, "close":true, "complex":true, "copy":true, "delete":true, "imag":true, + "len":true, "make":true, "new":true, "panic":true, "print":true, + "println":true, "real":true, "recover":true + }; + + var isOperatorChar = /[+\-*&^%:=<>!|\/]/; + + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'" || ch == "`") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\d\.]/.test(ch)) { + if (ch == ".") { + stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); + } else if (ch == "0") { + stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); + } else { + stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); + } + return "number"; + } + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + curPunc = ch; + return null; + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + var cur = stream.current(); + if (keywords.propertyIsEnumerable(cur)) { + if (cur == "case" || cur == "default") curPunc = "case"; + return "keyword"; + } + if (atoms.propertyIsEnumerable(cur)) return "atom"; + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && quote != "`" && next == "\\"; + } + if (end || !(escaped || quote == "`")) + state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + function popContext(state) { + if (!state.context.prev) return; + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + if (ctx.type == "case") ctx.type = "}"; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "case") ctx.type = "case"; + else if (curPunc == "}" && ctx.type == "}") popContext(state); + else if (curPunc == ctx.type) popContext(state); + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) { + state.context.type = "}"; + return ctx.indented; + } + var closing = firstChar == ctx.type; + if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}):", + closeBrackets: "()[]{}''\"\"``", + fold: "brace", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; +}); + +CodeMirror.defineMIME("text/x-go", "go"); + +}); diff --git a/backend/webif/static/codemirror/mode/go/index.html b/backend/webif/static/codemirror/mode/go/index.html new file mode 100755 index 000000000..72e3b364c --- /dev/null +++ b/backend/webif/static/codemirror/mode/go/index.html @@ -0,0 +1,85 @@ + + +CodeMirror: Go mode + + + + + + + + + + + +
+

Go mode

+
+ + + +

MIME type: text/x-go

+
diff --git a/backend/webif/static/codemirror/mode/groovy/groovy.js b/backend/webif/static/codemirror/mode/groovy/groovy.js new file mode 100755 index 000000000..0df97dd0b --- /dev/null +++ b/backend/webif/static/codemirror/mode/groovy/groovy.js @@ -0,0 +1,230 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("groovy", function(config) { + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var keywords = words( + "abstract as assert boolean break byte case catch char class const continue def default " + + "do double else enum extends final finally float for goto if implements import in " + + "instanceof int interface long native new package private protected public return " + + "short static strictfp super switch synchronized threadsafe throw throws trait transient " + + "try void volatile while"); + var blockKeywords = words("catch class def do else enum finally for if interface switch trait try while"); + var standaloneKeywords = words("return break continue"); + var atoms = words("null true false this"); + + var curPunc; + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + return startString(ch, stream, state); + } + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + curPunc = ch; + return null; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); } + return "number"; + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize.push(tokenComment); + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + if (expectExpression(state.lastToken, false)) { + return startString(ch, stream, state); + } + } + if (ch == "-" && stream.eat(">")) { + curPunc = "->"; + return null; + } + if (/[+\-*&%=<>!?|\/~]/.test(ch)) { + stream.eatWhile(/[+\-*&%=<>|~]/); + return "operator"; + } + stream.eatWhile(/[\w\$_]/); + if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; } + if (state.lastToken == ".") return "property"; + if (stream.eat(":")) { curPunc = "proplabel"; return "property"; } + var cur = stream.current(); + if (atoms.propertyIsEnumerable(cur)) { return "atom"; } + if (keywords.propertyIsEnumerable(cur)) { + if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; + else if (standaloneKeywords.propertyIsEnumerable(cur)) curPunc = "standalone"; + return "keyword"; + } + return "variable"; + } + tokenBase.isBase = true; + + function startString(quote, stream, state) { + var tripleQuoted = false; + if (quote != "/" && stream.eat(quote)) { + if (stream.eat(quote)) tripleQuoted = true; + else return "string"; + } + function t(stream, state) { + var escaped = false, next, end = !tripleQuoted; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + if (!tripleQuoted) { break; } + if (stream.match(quote + quote)) { end = true; break; } + } + if (quote == '"' && next == "$" && !escaped && stream.eat("{")) { + state.tokenize.push(tokenBaseUntilBrace()); + return "string"; + } + escaped = !escaped && next == "\\"; + } + if (end) state.tokenize.pop(); + return "string"; + } + state.tokenize.push(t); + return t(stream, state); + } + + function tokenBaseUntilBrace() { + var depth = 1; + function t(stream, state) { + if (stream.peek() == "}") { + depth--; + if (depth == 0) { + state.tokenize.pop(); + return state.tokenize[state.tokenize.length-1](stream, state); + } + } else if (stream.peek() == "{") { + depth++; + } + return tokenBase(stream, state); + } + t.isBase = true; + return t; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize.pop(); + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function expectExpression(last, newline) { + return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) || + last == "newstatement" || last == "keyword" || last == "proplabel" || + (last == "standalone" && !newline); + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: [tokenBase], + context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false), + indented: 0, + startOfLine: true, + lastToken: null + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + // Automatic semicolon insertion + if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) { + popContext(state); ctx = state.context; + } + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = state.tokenize[state.tokenize.length-1](stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state); + // Handle indentation for {x -> \n ... } + else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") { + popContext(state); + state.context.align = false; + } + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement")) + pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + state.lastToken = curPunc || style; + return style; + }, + + indent: function(state, textAfter) { + if (!state.tokenize[state.tokenize.length-1].isBase) return CodeMirror.Pass; + var firstChar = textAfter && textAfter.charAt(0), ctx = state.context; + if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) ctx = ctx.prev; + var closing = firstChar == ctx.type; + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit); + else if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : config.indentUnit); + }, + + electricChars: "{}", + closeBrackets: {triples: "'\""}, + fold: "brace" + }; +}); + +CodeMirror.defineMIME("text/x-groovy", "groovy"); + +}); diff --git a/backend/webif/static/codemirror/mode/groovy/index.html b/backend/webif/static/codemirror/mode/groovy/index.html new file mode 100755 index 000000000..bb0df078c --- /dev/null +++ b/backend/webif/static/codemirror/mode/groovy/index.html @@ -0,0 +1,84 @@ + + +CodeMirror: Groovy mode + + + + + + + + + + +
+

Groovy mode

+
+ + + +

MIME types defined: text/x-groovy

+
diff --git a/backend/webif/static/codemirror/mode/haml/haml.js b/backend/webif/static/codemirror/mode/haml/haml.js new file mode 100755 index 000000000..20ae1e19c --- /dev/null +++ b/backend/webif/static/codemirror/mode/haml/haml.js @@ -0,0 +1,161 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + + // full haml mode. This handled embedded ruby and html fragments too + CodeMirror.defineMode("haml", function(config) { + var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"}); + var rubyMode = CodeMirror.getMode(config, "ruby"); + + function rubyInQuote(endQuote) { + return function(stream, state) { + var ch = stream.peek(); + if (ch == endQuote && state.rubyState.tokenize.length == 1) { + // step out of ruby context as it seems to complete processing all the braces + stream.next(); + state.tokenize = html; + return "closeAttributeTag"; + } else { + return ruby(stream, state); + } + }; + } + + function ruby(stream, state) { + if (stream.match("-#")) { + stream.skipToEnd(); + return "comment"; + } + return rubyMode.token(stream, state.rubyState); + } + + function html(stream, state) { + var ch = stream.peek(); + + // handle haml declarations. All declarations that cant be handled here + // will be passed to html mode + if (state.previousToken.style == "comment" ) { + if (state.indented > state.previousToken.indented) { + stream.skipToEnd(); + return "commentLine"; + } + } + + if (state.startOfLine) { + if (ch == "!" && stream.match("!!")) { + stream.skipToEnd(); + return "tag"; + } else if (stream.match(/^%[\w:#\.]+=/)) { + state.tokenize = ruby; + return "hamlTag"; + } else if (stream.match(/^%[\w:]+/)) { + return "hamlTag"; + } else if (ch == "/" ) { + stream.skipToEnd(); + return "comment"; + } + } + + if (state.startOfLine || state.previousToken.style == "hamlTag") { + if ( ch == "#" || ch == ".") { + stream.match(/[\w-#\.]*/); + return "hamlAttribute"; + } + } + + // donot handle --> as valid ruby, make it HTML close comment instead + if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) { + state.tokenize = ruby; + return state.tokenize(stream, state); + } + + if (state.previousToken.style == "hamlTag" || + state.previousToken.style == "closeAttributeTag" || + state.previousToken.style == "hamlAttribute") { + if (ch == "(") { + state.tokenize = rubyInQuote(")"); + return state.tokenize(stream, state); + } else if (ch == "{") { + if (!stream.match(/^\{%.*/)) { + state.tokenize = rubyInQuote("}"); + return state.tokenize(stream, state); + } + } + } + + return htmlMode.token(stream, state.htmlState); + } + + return { + // default to html mode + startState: function() { + var htmlState = CodeMirror.startState(htmlMode); + var rubyState = CodeMirror.startState(rubyMode); + return { + htmlState: htmlState, + rubyState: rubyState, + indented: 0, + previousToken: { style: null, indented: 0}, + tokenize: html + }; + }, + + copyState: function(state) { + return { + htmlState : CodeMirror.copyState(htmlMode, state.htmlState), + rubyState: CodeMirror.copyState(rubyMode, state.rubyState), + indented: state.indented, + previousToken: state.previousToken, + tokenize: state.tokenize + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + state.startOfLine = false; + // dont record comment line as we only want to measure comment line with + // the opening comment block + if (style && style != "commentLine") { + state.previousToken = { style: style, indented: state.indented }; + } + // if current state is ruby and the previous token is not `,` reset the + // tokenize to html + if (stream.eol() && state.tokenize == ruby) { + stream.backUp(1); + var ch = stream.peek(); + stream.next(); + if (ch && ch != ",") { + state.tokenize = html; + } + } + // reprocess some of the specific style tag when finish setting previousToken + if (style == "hamlTag") { + style = "tag"; + } else if (style == "commentLine") { + style = "comment"; + } else if (style == "hamlAttribute") { + style = "attribute"; + } else if (style == "closeAttributeTag") { + style = null; + } + return style; + } + }; + }, "htmlmixed", "ruby"); + + CodeMirror.defineMIME("text/x-haml", "haml"); +}); diff --git a/backend/webif/static/codemirror/mode/haml/index.html b/backend/webif/static/codemirror/mode/haml/index.html new file mode 100755 index 000000000..2894a938e --- /dev/null +++ b/backend/webif/static/codemirror/mode/haml/index.html @@ -0,0 +1,79 @@ + + +CodeMirror: HAML mode + + + + + + + + + + + + + +
+

HAML mode

+
+ + +

MIME types defined: text/x-haml.

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/haml/test.js b/backend/webif/static/codemirror/mode/haml/test.js new file mode 100755 index 000000000..508458a43 --- /dev/null +++ b/backend/webif/static/codemirror/mode/haml/test.js @@ -0,0 +1,97 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "haml"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Requires at least one media query + MT("elementName", + "[tag %h1] Hey There"); + + MT("oneElementPerLine", + "[tag %h1] Hey There %h2"); + + MT("idSelector", + "[tag %h1][attribute #test] Hey There"); + + MT("classSelector", + "[tag %h1][attribute .hello] Hey There"); + + MT("docType", + "[tag !!! XML]"); + + MT("comment", + "[comment / Hello WORLD]"); + + MT("notComment", + "[tag %h1] This is not a / comment "); + + MT("attributes", + "[tag %a]([variable title][operator =][string \"test\"]){[atom :title] [operator =>] [string \"test\"]}"); + + MT("htmlCode", + "[tag&bracket <][tag h1][tag&bracket >]Title[tag&bracket ]"); + + MT("rubyBlock", + "[operator =][variable-2 @item]"); + + MT("selectorRubyBlock", + "[tag %a.selector=] [variable-2 @item]"); + + MT("nestedRubyBlock", + "[tag %a]", + " [operator =][variable puts] [string \"test\"]"); + + MT("multilinePlaintext", + "[tag %p]", + " Hello,", + " World"); + + MT("multilineRuby", + "[tag %p]", + " [comment -# this is a comment]", + " [comment and this is a comment too]", + " Date/Time", + " [operator -] [variable now] [operator =] [tag DateTime][operator .][property now]", + " [tag %strong=] [variable now]", + " [operator -] [keyword if] [variable now] [operator >] [tag DateTime][operator .][property parse]([string \"December 31, 2006\"])", + " [operator =][string \"Happy\"]", + " [operator =][string \"Belated\"]", + " [operator =][string \"Birthday\"]"); + + MT("multilineComment", + "[comment /]", + " [comment Multiline]", + " [comment Comment]"); + + MT("hamlComment", + "[comment -# this is a comment]"); + + MT("multilineHamlComment", + "[comment -# this is a comment]", + " [comment and this is a comment too]"); + + MT("multilineHTMLComment", + "[comment ]"); + + MT("hamlAfterRubyTag", + "[attribute .block]", + " [tag %strong=] [variable now]", + " [attribute .test]", + " [operator =][variable now]", + " [attribute .right]"); + + MT("stretchedRuby", + "[operator =] [variable puts] [string \"Hello\"],", + " [string \"World\"]"); + + MT("interpolationInHashAttribute", + //"[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test"); + "[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test"); + + MT("interpolationInHTMLAttribute", + "[tag %div]([variable title][operator =][string \"#{][variable test][string }_#{][variable ting]()[string }\"]) Test"); +})(); diff --git a/backend/webif/static/codemirror/mode/handlebars/handlebars.js b/backend/webif/static/codemirror/mode/handlebars/handlebars.js new file mode 100755 index 000000000..2174e5384 --- /dev/null +++ b/backend/webif/static/codemirror/mode/handlebars/handlebars.js @@ -0,0 +1,62 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple"), require("../../addon/mode/multiplex")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineSimpleMode("handlebars-tags", { + start: [ + { regex: /\{\{!--/, push: "dash_comment", token: "comment" }, + { regex: /\{\{!/, push: "comment", token: "comment" }, + { regex: /\{\{/, push: "handlebars", token: "tag" } + ], + handlebars: [ + { regex: /\}\}/, pop: true, token: "tag" }, + + // Double and single quotes + { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" }, + { regex: /'(?:[^\\']|\\.)*'?/, token: "string" }, + + // Handlebars keywords + { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" }, + { regex: /(?:else|this)\b/, token: "keyword" }, + + // Numeral + { regex: /\d+/i, token: "number" }, + + // Atoms like = and . + { regex: /=|~|@|true|false/, token: "atom" }, + + // Paths + { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" } + ], + dash_comment: [ + { regex: /--\}\}/, pop: true, token: "comment" }, + + // Commented code + { regex: /./, token: "comment"} + ], + comment: [ + { regex: /\}\}/, pop: true, token: "comment" }, + { regex: /./, token: "comment" } + ] + }); + + CodeMirror.defineMode("handlebars", function(config, parserConfig) { + var handlebars = CodeMirror.getMode(config, "handlebars-tags"); + if (!parserConfig || !parserConfig.base) return handlebars; + return CodeMirror.multiplexingMode( + CodeMirror.getMode(config, parserConfig.base), + {open: "{{", close: "}}", mode: handlebars, parseDelimiters: true} + ); + }); + + CodeMirror.defineMIME("text/x-handlebars-template", "handlebars"); +}); diff --git a/backend/webif/static/codemirror/mode/handlebars/index.html b/backend/webif/static/codemirror/mode/handlebars/index.html new file mode 100755 index 000000000..b1bfad1ca --- /dev/null +++ b/backend/webif/static/codemirror/mode/handlebars/index.html @@ -0,0 +1,79 @@ + + +CodeMirror: Handlebars mode + + + + + + + + + + + + +
+

Handlebars

+
+ + +

Handlebars syntax highlighting for CodeMirror.

+ +

MIME types defined: text/x-handlebars-template

+ +

Supported options: base to set the mode to + wrap. For example, use

+
mode: {name: "handlebars", base: "text/html"}
+

to highlight an HTML template.

+
diff --git a/backend/webif/static/codemirror/mode/haskell-literate/haskell-literate.js b/backend/webif/static/codemirror/mode/haskell-literate/haskell-literate.js new file mode 100755 index 000000000..906415b4c --- /dev/null +++ b/backend/webif/static/codemirror/mode/haskell-literate/haskell-literate.js @@ -0,0 +1,43 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function (mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../haskell/haskell")) + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../haskell/haskell"], mod) + else // Plain browser env + mod(CodeMirror) +})(function (CodeMirror) { + "use strict" + + CodeMirror.defineMode("haskell-literate", function (config, parserConfig) { + var baseMode = CodeMirror.getMode(config, (parserConfig && parserConfig.base) || "haskell") + + return { + startState: function () { + return { + inCode: false, + baseState: CodeMirror.startState(baseMode) + } + }, + token: function (stream, state) { + if (stream.sol()) { + if (state.inCode = stream.eat(">")) + return "meta" + } + if (state.inCode) { + return baseMode.token(stream, state.baseState) + } else { + stream.skipToEnd() + return "comment" + } + }, + innerMode: function (state) { + return state.inCode ? {state: state.baseState, mode: baseMode} : null + } + } + }, "haskell") + + CodeMirror.defineMIME("text/x-literate-haskell", "haskell-literate") +}); diff --git a/backend/webif/static/codemirror/mode/haskell-literate/index.html b/backend/webif/static/codemirror/mode/haskell-literate/index.html new file mode 100755 index 000000000..8c9bc60d1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/haskell-literate/index.html @@ -0,0 +1,282 @@ + + +CodeMirror: Haskell-literate mode + + + + + + + + + + +
+

Haskell literate mode

+
+ +
+ +

MIME types + defined: text/x-literate-haskell.

+ +

Parser configuration parameters recognized: base to + set the base mode (defaults to "haskell").

+ + + +
diff --git a/backend/webif/static/codemirror/mode/haskell/haskell.js b/backend/webif/static/codemirror/mode/haskell/haskell.js new file mode 100755 index 000000000..4197666a4 --- /dev/null +++ b/backend/webif/static/codemirror/mode/haskell/haskell.js @@ -0,0 +1,267 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("haskell", function(_config, modeConfig) { + + function switchState(source, setState, f) { + setState(f); + return f(source, setState); + } + + // These should all be Unicode extended, as per the Haskell 2010 report + var smallRE = /[a-z_]/; + var largeRE = /[A-Z]/; + var digitRE = /\d/; + var hexitRE = /[0-9A-Fa-f]/; + var octitRE = /[0-7]/; + var idRE = /[a-z_A-Z0-9'\xa1-\uffff]/; + var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/; + var specialRE = /[(),;[\]`{}]/; + var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer + + function normal(source, setState) { + if (source.eatWhile(whiteCharRE)) { + return null; + } + + var ch = source.next(); + if (specialRE.test(ch)) { + if (ch == '{' && source.eat('-')) { + var t = "comment"; + if (source.eat('#')) { + t = "meta"; + } + return switchState(source, setState, ncomment(t, 1)); + } + return null; + } + + if (ch == '\'') { + if (source.eat('\\')) { + source.next(); // should handle other escapes here + } + else { + source.next(); + } + if (source.eat('\'')) { + return "string"; + } + return "string error"; + } + + if (ch == '"') { + return switchState(source, setState, stringLiteral); + } + + if (largeRE.test(ch)) { + source.eatWhile(idRE); + if (source.eat('.')) { + return "qualifier"; + } + return "variable-2"; + } + + if (smallRE.test(ch)) { + source.eatWhile(idRE); + return "variable"; + } + + if (digitRE.test(ch)) { + if (ch == '0') { + if (source.eat(/[xX]/)) { + source.eatWhile(hexitRE); // should require at least 1 + return "integer"; + } + if (source.eat(/[oO]/)) { + source.eatWhile(octitRE); // should require at least 1 + return "number"; + } + } + source.eatWhile(digitRE); + var t = "number"; + if (source.match(/^\.\d+/)) { + t = "number"; + } + if (source.eat(/[eE]/)) { + t = "number"; + source.eat(/[-+]/); + source.eatWhile(digitRE); // should require at least 1 + } + return t; + } + + if (ch == "." && source.eat(".")) + return "keyword"; + + if (symbolRE.test(ch)) { + if (ch == '-' && source.eat(/-/)) { + source.eatWhile(/-/); + if (!source.eat(symbolRE)) { + source.skipToEnd(); + return "comment"; + } + } + var t = "variable"; + if (ch == ':') { + t = "variable-2"; + } + source.eatWhile(symbolRE); + return t; + } + + return "error"; + } + + function ncomment(type, nest) { + if (nest == 0) { + return normal; + } + return function(source, setState) { + var currNest = nest; + while (!source.eol()) { + var ch = source.next(); + if (ch == '{' && source.eat('-')) { + ++currNest; + } + else if (ch == '-' && source.eat('}')) { + --currNest; + if (currNest == 0) { + setState(normal); + return type; + } + } + } + setState(ncomment(type, currNest)); + return type; + }; + } + + function stringLiteral(source, setState) { + while (!source.eol()) { + var ch = source.next(); + if (ch == '"') { + setState(normal); + return "string"; + } + if (ch == '\\') { + if (source.eol() || source.eat(whiteCharRE)) { + setState(stringGap); + return "string"; + } + if (source.eat('&')) { + } + else { + source.next(); // should handle other escapes here + } + } + } + setState(normal); + return "string error"; + } + + function stringGap(source, setState) { + if (source.eat('\\')) { + return switchState(source, setState, stringLiteral); + } + source.next(); + setState(normal); + return "error"; + } + + + var wellKnownWords = (function() { + var wkw = {}; + function setType(t) { + return function () { + for (var i = 0; i < arguments.length; i++) + wkw[arguments[i]] = t; + }; + } + + setType("keyword")( + "case", "class", "data", "default", "deriving", "do", "else", "foreign", + "if", "import", "in", "infix", "infixl", "infixr", "instance", "let", + "module", "newtype", "of", "then", "type", "where", "_"); + + setType("keyword")( + "\.\.", ":", "::", "=", "\\", "<-", "->", "@", "~", "=>"); + + setType("builtin")( + "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<", + "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**"); + + setType("builtin")( + "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq", + "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT", + "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left", + "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read", + "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS", + "String", "True"); + + setType("builtin")( + "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf", + "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling", + "compare", "concat", "concatMap", "const", "cos", "cosh", "curry", + "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either", + "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo", + "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter", + "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap", + "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger", + "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents", + "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized", + "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last", + "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map", + "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound", + "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or", + "otherwise", "pi", "pred", "print", "product", "properFraction", + "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile", + "readIO", "readList", "readLn", "readParen", "reads", "readsPrec", + "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse", + "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq", + "sequence", "sequence_", "show", "showChar", "showList", "showParen", + "showString", "shows", "showsPrec", "significand", "signum", "sin", + "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum", + "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger", + "toRational", "truncate", "uncurry", "undefined", "unlines", "until", + "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip", + "zip3", "zipWith", "zipWith3"); + + var override = modeConfig.overrideKeywords; + if (override) for (var word in override) if (override.hasOwnProperty(word)) + wkw[word] = override[word]; + + return wkw; + })(); + + + + return { + startState: function () { return { f: normal }; }, + copyState: function (s) { return { f: s.f }; }, + + token: function(stream, state) { + var t = state.f(stream, function(s) { state.f = s; }); + var w = stream.current(); + return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t; + }, + + blockCommentStart: "{-", + blockCommentEnd: "-}", + lineComment: "--" + }; + +}); + +CodeMirror.defineMIME("text/x-haskell", "haskell"); + +}); diff --git a/backend/webif/static/codemirror/mode/haskell/index.html b/backend/webif/static/codemirror/mode/haskell/index.html new file mode 100755 index 000000000..42240b0f2 --- /dev/null +++ b/backend/webif/static/codemirror/mode/haskell/index.html @@ -0,0 +1,73 @@ + + +CodeMirror: Haskell mode + + + + + + + + + + + +
+

Haskell mode

+
+ + + +

MIME types defined: text/x-haskell.

+
diff --git a/backend/webif/static/codemirror/mode/haxe/haxe.js b/backend/webif/static/codemirror/mode/haxe/haxe.js new file mode 100755 index 000000000..d159d082e --- /dev/null +++ b/backend/webif/static/codemirror/mode/haxe/haxe.js @@ -0,0 +1,515 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("haxe", function(config, parserConfig) { + var indentUnit = config.indentUnit; + + // Tokenizer + + function kw(type) {return {type: type, style: "keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"}; + var type = kw("typedef"); + var keywords = { + "if": A, "while": A, "else": B, "do": B, "try": B, + "return": C, "break": C, "continue": C, "new": C, "throw": C, + "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"), + "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"), + "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "never": kw("property_access"), "trace":kw("trace"), + "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type, + "true": atom, "false": atom, "null": atom + }; + + var isOperatorChar = /[+\-*&%=<>!?|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function toUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == end && !escaped) + return true; + escaped = !escaped && next == "\\"; + } + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + + function haxeTokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + return chain(stream, state, haxeTokenString(ch)); + } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return ret(ch); + } else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) { + stream.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) { + toUnescaped(stream, "/"); + stream.eatWhile(/[gimsu]/); + return ret("regexp", "string-2"); + } else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, haxeTokenComment); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } else { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + } else if (ch == "#") { + stream.skipToEnd(); + return ret("conditional", "meta"); + } else if (ch == "@") { + stream.eat(/:/); + stream.eatWhile(/[\w_]/); + return ret ("metadata", "meta"); + } else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } else { + var word; + if(/[A-Z]/.test(ch)) { + stream.eatWhile(/[\w_<>]/); + word = stream.current(); + return ret("type", "variable-3", word); + } else { + stream.eatWhile(/[\w_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return (known && state.kwAllowed) ? ret(known.type, known.style, word) : + ret("variable", "variable", word); + } + } + } + + function haxeTokenString(quote) { + return function(stream, state) { + if (toUnescaped(stream, quote)) + state.tokenize = haxeTokenBase; + return ret("string", "string"); + }; + } + + function haxeTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = haxeTokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true}; + + function HaxeLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + } + + function parseHaxe(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + if (type == "variable" && imported(state, content)) return "variable-3"; + return style; + } + } + } + + function imported(state, typename) { + if (/[a-z]/.test(typename.charAt(0))) + return false; + var len = state.importedtypes.length; + for (var i = 0; i= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function inList(name, list) { + for (var v = list; v; v = v.next) + if (v.name == name) return true; + return false; + } + function register(varname) { + var state = cx.state; + if (state.context) { + cx.marked = "def"; + if (inList(varname, state.localVars)) return; + state.localVars = {name: varname, next: state.localVars}; + } else if (state.globalVars) { + if (inList(varname, state.globalVars)) return; + state.globalVars = {name: varname, next: state.globalVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: null}; + function pushcontext() { + if (!cx.state.context) cx.state.localVars = defaultVars; + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + popcontext.lex = true; + function pushlex(type, info) { + var result = function() { + var state = cx.state; + state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + function f(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(f); + } + return f; + } + + function statement(type) { + if (type == "@") return cont(metadef); + if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext); + if (type == ";") return cont(); + if (type == "attribute") return cont(maybeattribute); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), + poplex, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + if (type == "import") return cont(importdef, expect(";")); + if (type == "typedef") return cont(typedef); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator); + if (type == "type" ) return cont(maybeoperator); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(maybeexpression); + if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator); + if (type == "operator") return cont(expression); + if (type == "[") return cont(pushlex("]"), commasep(maybeexpression, "]"), poplex, maybeoperator); + if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + + function maybeoperator(type, value) { + if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator); + if (type == "operator" || type == ":") return cont(expression); + if (type == ";") return; + if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator); + if (type == ".") return cont(property, maybeoperator); + if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator); + } + + function maybeattribute(type) { + if (type == "attribute") return cont(maybeattribute); + if (type == "function") return cont(functiondef); + if (type == "var") return cont(vardef1); + } + + function metadef(type) { + if(type == ":") return cont(metadef); + if(type == "variable") return cont(metadef); + if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement); + } + function metaargs(type) { + if(type == "variable") return cont(); + } + + function importdef (type, value) { + if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); } + else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef); + } + + function typedef (type, value) + { + if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); } + else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); } + } + + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperator, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "property"; return cont();} + } + function objprop(type) { + if (type == "variable") cx.marked = "property"; + if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") return cont(what, proceed); + if (type == end) return cont(); + return cont(expect(end)); + } + return function(type) { + if (type == end) return cont(); + else return pass(what, proceed); + }; + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function vardef1(type, value) { + if (type == "variable"){register(value); return cont(typeuse, vardef2);} + return cont(); + } + function vardef2(type, value) { + if (value == "=") return cont(expression, vardef2); + if (type == ",") return cont(vardef1); + } + function forspec1(type, value) { + if (type == "variable") { + register(value); + return cont(forin, expression) + } else { + return pass() + } + } + function forin(_type, value) { + if (value == "in") return cont(); + } + function functiondef(type, value) { + //function names starting with upper-case letters are recognised as types, so cludging them together here. + if (type == "variable" || type == "type") {register(value); return cont(functiondef);} + if (value == "new") return cont(functiondef); + if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext); + } + function typeuse(type) { + if(type == ":") return cont(typestring); + } + function typestring(type) { + if(type == "type") return cont(); + if(type == "variable") return cont(); + if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex); + } + function typeprop(type) { + if(type == "variable") return cont(typeuse); + } + function funarg(type, value) { + if (type == "variable") {register(value); return cont(typeuse);} + } + + // Interface + return { + startState: function(basecolumn) { + var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"]; + var state = { + tokenize: haxeTokenBase, + reAllowed: true, + kwAllowed: true, + cc: [], + lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + importedtypes: defaulttypes, + context: parserConfig.localVars && {vars: parserConfig.localVars}, + indented: 0 + }; + if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") + state.globalVars = parserConfig.globalVars; + return state; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/)); + state.kwAllowed = type != '.'; + return parseHaxe(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize != haxeTokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; + if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + if (type == "vardef") return lexical.indented + 4; + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "stat" || type == "form") return lexical.indented + indentUnit; + else if (lexical.info == "switch" && !closing) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; +}); + +CodeMirror.defineMIME("text/x-haxe", "haxe"); + +CodeMirror.defineMode("hxml", function () { + + return { + startState: function () { + return { + define: false, + inString: false + }; + }, + token: function (stream, state) { + var ch = stream.peek(); + var sol = stream.sol(); + + ///* comments */ + if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + if (sol && ch == "-") { + var style = "variable-2"; + + stream.eat(/-/); + + if (stream.peek() == "-") { + stream.eat(/-/); + style = "keyword a"; + } + + if (stream.peek() == "D") { + stream.eat(/[D]/); + style = "keyword c"; + state.define = true; + } + + stream.eatWhile(/[A-Z]/i); + return style; + } + + var ch = stream.peek(); + + if (state.inString == false && ch == "'") { + state.inString = true; + stream.next(); + } + + if (state.inString == true) { + if (stream.skipTo("'")) { + + } else { + stream.skipToEnd(); + } + + if (stream.peek() == "'") { + stream.next(); + state.inString = false; + } + + return "string"; + } + + stream.next(); + return null; + }, + lineComment: "#" + }; +}); + +CodeMirror.defineMIME("text/x-hxml", "hxml"); + +}); diff --git a/backend/webif/static/codemirror/mode/haxe/index.html b/backend/webif/static/codemirror/mode/haxe/index.html new file mode 100755 index 000000000..d415b5e10 --- /dev/null +++ b/backend/webif/static/codemirror/mode/haxe/index.html @@ -0,0 +1,124 @@ + + +CodeMirror: Haxe mode + + + + + + + + + +
+

Haxe mode

+ + +

+ +

Hxml mode:

+ +

+
+ + + +

MIME types defined: text/x-haxe, text/x-hxml.

+
diff --git a/backend/webif/static/codemirror/mode/htmlembedded/htmlembedded.js b/backend/webif/static/codemirror/mode/htmlembedded/htmlembedded.js new file mode 100755 index 000000000..464dc57f8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/htmlembedded/htmlembedded.js @@ -0,0 +1,28 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), + require("../../addon/mode/multiplex")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", + "../../addon/mode/multiplex"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { + return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { + open: parserConfig.open || parserConfig.scriptStartRegex || "<%", + close: parserConfig.close || parserConfig.scriptEndRegex || "%>", + mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) + }); + }, "htmlmixed"); + + CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"}); + CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); + CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"}); + CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"}); +}); diff --git a/backend/webif/static/codemirror/mode/htmlembedded/index.html b/backend/webif/static/codemirror/mode/htmlembedded/index.html new file mode 100755 index 000000000..9ed33cffe --- /dev/null +++ b/backend/webif/static/codemirror/mode/htmlembedded/index.html @@ -0,0 +1,60 @@ + + +CodeMirror: Html Embedded Scripts mode + + + + + + + + + + + + + + +
+

Html Embedded Scripts mode

+
+ + + +

Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on + JavaScript, CSS and XML.
Other dependencies include those of the scripting language chosen.

+ +

MIME types defined: application/x-aspx (ASP.NET), + application/x-ejs (Embedded Javascript), application/x-jsp (JavaServer Pages) + and application/x-erb

+
diff --git a/backend/webif/static/codemirror/mode/htmlmixed/htmlmixed.js b/backend/webif/static/codemirror/mode/htmlmixed/htmlmixed.js new file mode 100755 index 000000000..33398ec5c --- /dev/null +++ b/backend/webif/static/codemirror/mode/htmlmixed/htmlmixed.js @@ -0,0 +1,152 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var defaultTags = { + script: [ + ["lang", /(javascript|babel)/i, "javascript"], + ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"], + ["type", /./, "text/plain"], + [null, null, "javascript"] + ], + style: [ + ["lang", /^css$/i, "css"], + ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"], + ["type", /./, "text/plain"], + [null, null, "css"] + ] + }; + + function maybeBackup(stream, pat, style) { + var cur = stream.current(), close = cur.search(pat); + if (close > -1) { + stream.backUp(cur.length - close); + } else if (cur.match(/<\/?$/)) { + stream.backUp(cur.length); + if (!stream.match(pat, false)) stream.match(cur); + } + return style; + } + + var attrRegexpCache = {}; + function getAttrRegexp(attr) { + var regexp = attrRegexpCache[attr]; + if (regexp) return regexp; + return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); + } + + function getAttrValue(text, attr) { + var match = text.match(getAttrRegexp(attr)) + return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : "" + } + + function getTagRegexp(tagName, anchored) { + return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); + } + + function addTags(from, to) { + for (var tag in from) { + var dest = to[tag] || (to[tag] = []); + var source = from[tag]; + for (var i = source.length - 1; i >= 0; i--) + dest.unshift(source[i]) + } + } + + function findMatchingMode(tagInfo, tagText) { + for (var i = 0; i < tagInfo.length; i++) { + var spec = tagInfo[i]; + if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2]; + } + } + + CodeMirror.defineMode("htmlmixed", function (config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, { + name: "xml", + htmlMode: true, + multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, + multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag + }); + + var tags = {}; + var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes; + addTags(defaultTags, tags); + if (configTags) addTags(configTags, tags); + if (configScript) for (var i = configScript.length - 1; i >= 0; i--) + tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) + + function html(stream, state) { + var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName + if (tag && !/[<>\s\/]/.test(stream.current()) && + (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) && + tags.hasOwnProperty(tagName)) { + state.inTag = tagName + " " + } else if (state.inTag && tag && />$/.test(stream.current())) { + var inTag = /^([\S]+) (.*)/.exec(state.inTag) + state.inTag = null + var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2]) + var mode = CodeMirror.getMode(config, modeSpec) + var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false); + state.token = function (stream, state) { + if (stream.match(endTagA, false)) { + state.token = html; + state.localState = state.localMode = null; + return null; + } + return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); + }; + state.localMode = mode; + state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); + } else if (state.inTag) { + state.inTag += stream.current() + if (stream.eol()) state.inTag += " " + } + return style; + }; + + return { + startState: function () { + var state = CodeMirror.startState(htmlMode); + return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; + }, + + copyState: function (state) { + var local; + if (state.localState) { + local = CodeMirror.copyState(state.localMode, state.localState); + } + return {token: state.token, inTag: state.inTag, + localMode: state.localMode, localState: local, + htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; + }, + + token: function (stream, state) { + return state.token(stream, state); + }, + + indent: function (state, textAfter, line) { + if (!state.localMode || /^\s*<\//.test(textAfter)) + return htmlMode.indent(state.htmlState, textAfter); + else if (state.localMode.indent) + return state.localMode.indent(state.localState, textAfter, line); + else + return CodeMirror.Pass; + }, + + innerMode: function (state) { + return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; + } + }; + }, "xml", "javascript", "css"); + + CodeMirror.defineMIME("text/html", "htmlmixed"); +}); diff --git a/backend/webif/static/codemirror/mode/htmlmixed/index.html b/backend/webif/static/codemirror/mode/htmlmixed/index.html new file mode 100755 index 000000000..e576c0592 --- /dev/null +++ b/backend/webif/static/codemirror/mode/htmlmixed/index.html @@ -0,0 +1,100 @@ + + +CodeMirror: HTML mixed mode + + + + + + + + + + + + + + +
+

HTML mixed mode

+
+ + +

The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

+ +

It takes an optional mode configuration + option, tags, which can be used to add custom + behavior for specific tags. When given, it should be an object + mapping tag names (for example script) to arrays or + three-element arrays. Those inner arrays indicate [attributeName, + valueRegexp, modeSpec] + specifications. For example, you could use ["type", /^foo$/, + "foo"] to map the attribute type="foo" to + the foo mode. When the first two fields are null + ([null, null, "mode"]), the given mode is used for + any such tag that doesn't match any of the previously given + attributes. For example:

+ +
var myModeSpec = {
+  name: "htmlmixed",
+  tags: {
+    style: [["type", /^text\/(x-)?scss$/, "text/x-scss"],
+            [null, null, "css"]],
+    custom: [[null, null, "customMode"]]
+  }
+}
+ +

MIME types defined: text/html + (redefined, only takes effect if you load this parser after the + XML parser).

+ +
diff --git a/backend/webif/static/codemirror/mode/http/http.js b/backend/webif/static/codemirror/mode/http/http.js new file mode 100755 index 000000000..9a3c5f9fd --- /dev/null +++ b/backend/webif/static/codemirror/mode/http/http.js @@ -0,0 +1,113 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("http", function() { + function failFirstLine(stream, state) { + stream.skipToEnd(); + state.cur = header; + return "error"; + } + + function start(stream, state) { + if (stream.match(/^HTTP\/\d\.\d/)) { + state.cur = responseStatusCode; + return "keyword"; + } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) { + state.cur = requestPath; + return "keyword"; + } else { + return failFirstLine(stream, state); + } + } + + function responseStatusCode(stream, state) { + var code = stream.match(/^\d+/); + if (!code) return failFirstLine(stream, state); + + state.cur = responseStatusText; + var status = Number(code[0]); + if (status >= 100 && status < 200) { + return "positive informational"; + } else if (status >= 200 && status < 300) { + return "positive success"; + } else if (status >= 300 && status < 400) { + return "positive redirect"; + } else if (status >= 400 && status < 500) { + return "negative client-error"; + } else if (status >= 500 && status < 600) { + return "negative server-error"; + } else { + return "error"; + } + } + + function responseStatusText(stream, state) { + stream.skipToEnd(); + state.cur = header; + return null; + } + + function requestPath(stream, state) { + stream.eatWhile(/\S/); + state.cur = requestProtocol; + return "string-2"; + } + + function requestProtocol(stream, state) { + if (stream.match(/^HTTP\/\d\.\d$/)) { + state.cur = header; + return "keyword"; + } else { + return failFirstLine(stream, state); + } + } + + function header(stream) { + if (stream.sol() && !stream.eat(/[ \t]/)) { + if (stream.match(/^.*?:/)) { + return "atom"; + } else { + stream.skipToEnd(); + return "error"; + } + } else { + stream.skipToEnd(); + return "string"; + } + } + + function body(stream) { + stream.skipToEnd(); + return null; + } + + return { + token: function(stream, state) { + var cur = state.cur; + if (cur != header && cur != body && stream.eatSpace()) return null; + return cur(stream, state); + }, + + blankLine: function(state) { + state.cur = body; + }, + + startState: function() { + return {cur: start}; + } + }; +}); + +CodeMirror.defineMIME("message/http", "http"); + +}); diff --git a/backend/webif/static/codemirror/mode/http/index.html b/backend/webif/static/codemirror/mode/http/index.html new file mode 100755 index 000000000..0b8d5315d --- /dev/null +++ b/backend/webif/static/codemirror/mode/http/index.html @@ -0,0 +1,45 @@ + + +CodeMirror: HTTP mode + + + + + + + + + +
+

HTTP mode

+ + +
+ + + +

MIME types defined: message/http.

+
diff --git a/backend/webif/static/codemirror/mode/idl/idl.js b/backend/webif/static/codemirror/mode/idl/idl.js new file mode 100755 index 000000000..07308d71d --- /dev/null +++ b/backend/webif/static/codemirror/mode/idl/idl.js @@ -0,0 +1,290 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function wordRegexp(words) { + return new RegExp('^((' + words.join(')|(') + '))\\b', 'i'); + }; + + var builtinArray = [ + 'a_correlate', 'abs', 'acos', 'adapt_hist_equal', 'alog', + 'alog2', 'alog10', 'amoeba', 'annotate', 'app_user_dir', + 'app_user_dir_query', 'arg_present', 'array_equal', 'array_indices', + 'arrow', 'ascii_template', 'asin', 'assoc', 'atan', + 'axis', 'axis', 'bandpass_filter', 'bandreject_filter', 'barplot', + 'bar_plot', 'beseli', 'beselj', 'beselk', 'besely', + 'beta', 'biginteger', 'bilinear', 'bin_date', 'binary_template', + 'bindgen', 'binomial', 'bit_ffs', 'bit_population', 'blas_axpy', + 'blk_con', 'boolarr', 'boolean', 'boxplot', 'box_cursor', + 'breakpoint', 'broyden', 'bubbleplot', 'butterworth', 'bytarr', + 'byte', 'byteorder', 'bytscl', 'c_correlate', 'calendar', + 'caldat', 'call_external', 'call_function', 'call_method', + 'call_procedure', 'canny', 'catch', 'cd', 'cdf', 'ceil', + 'chebyshev', 'check_math', 'chisqr_cvf', 'chisqr_pdf', 'choldc', + 'cholsol', 'cindgen', 'cir_3pnt', 'clipboard', 'close', + 'clust_wts', 'cluster', 'cluster_tree', 'cmyk_convert', 'code_coverage', + 'color_convert', 'color_exchange', 'color_quan', 'color_range_map', + 'colorbar', 'colorize_sample', 'colormap_applicable', + 'colormap_gradient', 'colormap_rotation', 'colortable', + 'comfit', 'command_line_args', 'common', 'compile_opt', 'complex', + 'complexarr', 'complexround', 'compute_mesh_normals', 'cond', 'congrid', + 'conj', 'constrained_min', 'contour', 'contour', 'convert_coord', + 'convol', 'convol_fft', 'coord2to3', 'copy_lun', 'correlate', + 'cos', 'cosh', 'cpu', 'cramer', 'createboxplotdata', + 'create_cursor', 'create_struct', 'create_view', 'crossp', 'crvlength', + 'ct_luminance', 'cti_test', 'cursor', 'curvefit', 'cv_coord', + 'cvttobm', 'cw_animate', 'cw_animate_getp', 'cw_animate_load', + 'cw_animate_run', 'cw_arcball', 'cw_bgroup', 'cw_clr_index', + 'cw_colorsel', 'cw_defroi', 'cw_field', 'cw_filesel', 'cw_form', + 'cw_fslider', 'cw_light_editor', 'cw_light_editor_get', + 'cw_light_editor_set', 'cw_orient', 'cw_palette_editor', + 'cw_palette_editor_get', 'cw_palette_editor_set', 'cw_pdmenu', + 'cw_rgbslider', 'cw_tmpl', 'cw_zoom', 'db_exists', + 'dblarr', 'dcindgen', 'dcomplex', 'dcomplexarr', 'define_key', + 'define_msgblk', 'define_msgblk_from_file', 'defroi', 'defsysv', + 'delvar', 'dendro_plot', 'dendrogram', 'deriv', 'derivsig', + 'determ', 'device', 'dfpmin', 'diag_matrix', 'dialog_dbconnect', + 'dialog_message', 'dialog_pickfile', 'dialog_printersetup', + 'dialog_printjob', 'dialog_read_image', + 'dialog_write_image', 'dictionary', 'digital_filter', 'dilate', 'dindgen', + 'dissolve', 'dist', 'distance_measure', 'dlm_load', 'dlm_register', + 'doc_library', 'double', 'draw_roi', 'edge_dog', 'efont', + 'eigenql', 'eigenvec', 'ellipse', 'elmhes', 'emboss', + 'empty', 'enable_sysrtn', 'eof', 'eos', 'erase', + 'erf', 'erfc', 'erfcx', 'erode', 'errorplot', + 'errplot', 'estimator_filter', 'execute', 'exit', 'exp', + 'expand', 'expand_path', 'expint', 'extrac', 'extract_slice', + 'f_cvf', 'f_pdf', 'factorial', 'fft', 'file_basename', + 'file_chmod', 'file_copy', 'file_delete', 'file_dirname', + 'file_expand_path', 'file_gunzip', 'file_gzip', 'file_info', + 'file_lines', 'file_link', 'file_mkdir', 'file_move', + 'file_poll_input', 'file_readlink', 'file_same', + 'file_search', 'file_tar', 'file_test', 'file_untar', 'file_unzip', + 'file_which', 'file_zip', 'filepath', 'findgen', 'finite', + 'fix', 'flick', 'float', 'floor', 'flow3', + 'fltarr', 'flush', 'format_axis_values', 'forward_function', 'free_lun', + 'fstat', 'fulstr', 'funct', 'function', 'fv_test', + 'fx_root', 'fz_roots', 'gamma', 'gamma_ct', 'gauss_cvf', + 'gauss_pdf', 'gauss_smooth', 'gauss2dfit', 'gaussfit', + 'gaussian_function', 'gaussint', 'get_drive_list', 'get_dxf_objects', + 'get_kbrd', 'get_login_info', + 'get_lun', 'get_screen_size', 'getenv', 'getwindows', 'greg2jul', + 'grib', 'grid_input', 'grid_tps', 'grid3', 'griddata', + 'gs_iter', 'h_eq_ct', 'h_eq_int', 'hanning', 'hash', + 'hdf', 'hdf5', 'heap_free', 'heap_gc', 'heap_nosave', + 'heap_refcount', 'heap_save', 'help', 'hilbert', 'hist_2d', + 'hist_equal', 'histogram', 'hls', 'hough', 'hqr', + 'hsv', 'i18n_multibytetoutf8', + 'i18n_multibytetowidechar', 'i18n_utf8tomultibyte', + 'i18n_widechartomultibyte', + 'ibeta', 'icontour', 'iconvertcoord', 'idelete', 'identity', + 'idl_base64', 'idl_container', 'idl_validname', + 'idlexbr_assistant', 'idlitsys_createtool', + 'idlunit', 'iellipse', 'igamma', 'igetcurrent', 'igetdata', + 'igetid', 'igetproperty', 'iimage', 'image', 'image_cont', + 'image_statistics', 'image_threshold', 'imaginary', 'imap', 'indgen', + 'int_2d', 'int_3d', 'int_tabulated', 'intarr', 'interpol', + 'interpolate', 'interval_volume', 'invert', 'ioctl', 'iopen', + 'ir_filter', 'iplot', 'ipolygon', 'ipolyline', 'iputdata', + 'iregister', 'ireset', 'iresolve', 'irotate', 'isa', + 'isave', 'iscale', 'isetcurrent', 'isetproperty', 'ishft', + 'isocontour', 'isosurface', 'isurface', 'itext', 'itranslate', + 'ivector', 'ivolume', 'izoom', 'journal', 'json_parse', + 'json_serialize', 'jul2greg', 'julday', 'keyword_set', 'krig2d', + 'kurtosis', 'kw_test', 'l64indgen', 'la_choldc', 'la_cholmprove', + 'la_cholsol', 'la_determ', 'la_eigenproblem', 'la_eigenql', 'la_eigenvec', + 'la_elmhes', 'la_gm_linear_model', 'la_hqr', 'la_invert', + 'la_least_square_equality', 'la_least_squares', 'la_linear_equation', + 'la_ludc', 'la_lumprove', 'la_lusol', + 'la_svd', 'la_tridc', 'la_trimprove', 'la_triql', 'la_trired', + 'la_trisol', 'label_date', 'label_region', 'ladfit', 'laguerre', + 'lambda', 'lambdap', 'lambertw', 'laplacian', 'least_squares_filter', + 'leefilt', 'legend', 'legendre', 'linbcg', 'lindgen', + 'linfit', 'linkimage', 'list', 'll_arc_distance', 'lmfit', + 'lmgr', 'lngamma', 'lnp_test', 'loadct', 'locale_get', + 'logical_and', 'logical_or', 'logical_true', 'lon64arr', 'lonarr', + 'long', 'long64', 'lsode', 'lu_complex', 'ludc', + 'lumprove', 'lusol', 'm_correlate', 'machar', 'make_array', + 'make_dll', 'make_rt', 'map', 'mapcontinents', 'mapgrid', + 'map_2points', 'map_continents', 'map_grid', 'map_image', 'map_patch', + 'map_proj_forward', 'map_proj_image', 'map_proj_info', + 'map_proj_init', 'map_proj_inverse', + 'map_set', 'matrix_multiply', 'matrix_power', 'max', 'md_test', + 'mean', 'meanabsdev', 'mean_filter', 'median', 'memory', + 'mesh_clip', 'mesh_decimate', 'mesh_issolid', + 'mesh_merge', 'mesh_numtriangles', + 'mesh_obj', 'mesh_smooth', 'mesh_surfacearea', + 'mesh_validate', 'mesh_volume', + 'message', 'min', 'min_curve_surf', 'mk_html_help', 'modifyct', + 'moment', 'morph_close', 'morph_distance', + 'morph_gradient', 'morph_hitormiss', + 'morph_open', 'morph_thin', 'morph_tophat', 'multi', 'n_elements', + 'n_params', 'n_tags', 'ncdf', 'newton', 'noise_hurl', + 'noise_pick', 'noise_scatter', 'noise_slur', 'norm', 'obj_class', + 'obj_destroy', 'obj_hasmethod', 'obj_isa', 'obj_new', 'obj_valid', + 'objarr', 'on_error', 'on_ioerror', 'online_help', 'openr', + 'openu', 'openw', 'oplot', 'oploterr', 'orderedhash', + 'p_correlate', 'parse_url', 'particle_trace', 'path_cache', 'path_sep', + 'pcomp', 'plot', 'plot3d', 'plot', 'plot_3dbox', + 'plot_field', 'ploterr', 'plots', 'polar_contour', 'polar_surface', + 'polyfill', 'polyshade', 'pnt_line', 'point_lun', 'polarplot', + 'poly', 'poly_2d', 'poly_area', 'poly_fit', 'polyfillv', + 'polygon', 'polyline', 'polywarp', 'popd', 'powell', + 'pref_commit', 'pref_get', 'pref_set', 'prewitt', 'primes', + 'print', 'printf', 'printd', 'pro', 'product', + 'profile', 'profiler', 'profiles', 'project_vol', 'ps_show_fonts', + 'psafm', 'pseudo', 'ptr_free', 'ptr_new', 'ptr_valid', + 'ptrarr', 'pushd', 'qgrid3', 'qhull', 'qromb', + 'qromo', 'qsimp', 'query_*', 'query_ascii', 'query_bmp', + 'query_csv', 'query_dicom', 'query_gif', 'query_image', 'query_jpeg', + 'query_jpeg2000', 'query_mrsid', 'query_pict', 'query_png', 'query_ppm', + 'query_srf', 'query_tiff', 'query_video', 'query_wav', 'r_correlate', + 'r_test', 'radon', 'randomn', 'randomu', 'ranks', + 'rdpix', 'read', 'readf', 'read_ascii', 'read_binary', + 'read_bmp', 'read_csv', 'read_dicom', 'read_gif', 'read_image', + 'read_interfile', 'read_jpeg', 'read_jpeg2000', 'read_mrsid', 'read_pict', + 'read_png', 'read_ppm', 'read_spr', 'read_srf', 'read_sylk', + 'read_tiff', 'read_video', 'read_wav', 'read_wave', 'read_x11_bitmap', + 'read_xwd', 'reads', 'readu', 'real_part', 'rebin', + 'recall_commands', 'recon3', 'reduce_colors', 'reform', 'region_grow', + 'register_cursor', 'regress', 'replicate', + 'replicate_inplace', 'resolve_all', + 'resolve_routine', 'restore', 'retall', 'return', 'reverse', + 'rk4', 'roberts', 'rot', 'rotate', 'round', + 'routine_filepath', 'routine_info', 'rs_test', 's_test', 'save', + 'savgol', 'scale3', 'scale3d', 'scatterplot', 'scatterplot3d', + 'scope_level', 'scope_traceback', 'scope_varfetch', + 'scope_varname', 'search2d', + 'search3d', 'sem_create', 'sem_delete', 'sem_lock', 'sem_release', + 'set_plot', 'set_shading', 'setenv', 'sfit', 'shade_surf', + 'shade_surf_irr', 'shade_volume', 'shift', 'shift_diff', 'shmdebug', + 'shmmap', 'shmunmap', 'shmvar', 'show3', 'showfont', + 'signum', 'simplex', 'sin', 'sindgen', 'sinh', + 'size', 'skewness', 'skip_lun', 'slicer3', 'slide_image', + 'smooth', 'sobel', 'socket', 'sort', 'spawn', + 'sph_4pnt', 'sph_scat', 'spher_harm', 'spl_init', 'spl_interp', + 'spline', 'spline_p', 'sprsab', 'sprsax', 'sprsin', + 'sprstp', 'sqrt', 'standardize', 'stddev', 'stop', + 'strarr', 'strcmp', 'strcompress', 'streamline', 'streamline', + 'stregex', 'stretch', 'string', 'strjoin', 'strlen', + 'strlowcase', 'strmatch', 'strmessage', 'strmid', 'strpos', + 'strput', 'strsplit', 'strtrim', 'struct_assign', 'struct_hide', + 'strupcase', 'surface', 'surface', 'surfr', 'svdc', + 'svdfit', 'svsol', 'swap_endian', 'swap_endian_inplace', 'symbol', + 'systime', 't_cvf', 't_pdf', 't3d', 'tag_names', + 'tan', 'tanh', 'tek_color', 'temporary', 'terminal_size', + 'tetra_clip', 'tetra_surface', 'tetra_volume', 'text', 'thin', + 'thread', 'threed', 'tic', 'time_test2', 'timegen', + 'timer', 'timestamp', 'timestamptovalues', 'tm_test', 'toc', + 'total', 'trace', 'transpose', 'tri_surf', 'triangulate', + 'trigrid', 'triql', 'trired', 'trisol', 'truncate_lun', + 'ts_coef', 'ts_diff', 'ts_fcast', 'ts_smooth', 'tv', + 'tvcrs', 'tvlct', 'tvrd', 'tvscl', 'typename', + 'uindgen', 'uint', 'uintarr', 'ul64indgen', 'ulindgen', + 'ulon64arr', 'ulonarr', 'ulong', 'ulong64', 'uniq', + 'unsharp_mask', 'usersym', 'value_locate', 'variance', 'vector', + 'vector_field', 'vel', 'velovect', 'vert_t3d', 'voigt', + 'volume', 'voronoi', 'voxel_proj', 'wait', 'warp_tri', + 'watershed', 'wdelete', 'wf_draw', 'where', 'widget_base', + 'widget_button', 'widget_combobox', 'widget_control', + 'widget_displaycontextmenu', 'widget_draw', + 'widget_droplist', 'widget_event', 'widget_info', + 'widget_label', 'widget_list', + 'widget_propertysheet', 'widget_slider', 'widget_tab', + 'widget_table', 'widget_text', + 'widget_tree', 'widget_tree_move', 'widget_window', + 'wiener_filter', 'window', + 'window', 'write_bmp', 'write_csv', 'write_gif', 'write_image', + 'write_jpeg', 'write_jpeg2000', 'write_nrif', 'write_pict', 'write_png', + 'write_ppm', 'write_spr', 'write_srf', 'write_sylk', 'write_tiff', + 'write_video', 'write_wav', 'write_wave', 'writeu', 'wset', + 'wshow', 'wtn', 'wv_applet', 'wv_cwt', 'wv_cw_wavelet', + 'wv_denoise', 'wv_dwt', 'wv_fn_coiflet', + 'wv_fn_daubechies', 'wv_fn_gaussian', + 'wv_fn_haar', 'wv_fn_morlet', 'wv_fn_paul', + 'wv_fn_symlet', 'wv_import_data', + 'wv_import_wavelet', 'wv_plot3d_wps', 'wv_plot_multires', + 'wv_pwt', 'wv_tool_denoise', + 'xbm_edit', 'xdisplayfile', 'xdxf', 'xfont', 'xinteranimate', + 'xloadct', 'xmanager', 'xmng_tmpl', 'xmtool', 'xobjview', + 'xobjview_rotate', 'xobjview_write_image', + 'xpalette', 'xpcolor', 'xplot3d', + 'xregistered', 'xroi', 'xsq_test', 'xsurface', 'xvaredit', + 'xvolume', 'xvolume_rotate', 'xvolume_write_image', + 'xyouts', 'zlib_compress', 'zlib_uncompress', 'zoom', 'zoom_24' + ]; + var builtins = wordRegexp(builtinArray); + + var keywordArray = [ + 'begin', 'end', 'endcase', 'endfor', + 'endwhile', 'endif', 'endrep', 'endforeach', + 'break', 'case', 'continue', 'for', + 'foreach', 'goto', 'if', 'then', 'else', + 'repeat', 'until', 'switch', 'while', + 'do', 'pro', 'function' + ]; + var keywords = wordRegexp(keywordArray); + + CodeMirror.registerHelper("hintWords", "idl", builtinArray.concat(keywordArray)); + + var identifiers = new RegExp('^[_a-z\xa1-\uffff][_a-z0-9\xa1-\uffff]*', 'i'); + + var singleOperators = /[+\-*&=<>\/@#~$]/; + var boolOperators = new RegExp('(and|or|eq|lt|le|gt|ge|ne|not)', 'i'); + + function tokenBase(stream) { + // whitespaces + if (stream.eatSpace()) return null; + + // Handle one line Comments + if (stream.match(';')) { + stream.skipToEnd(); + return 'comment'; + } + + // Handle Number Literals + if (stream.match(/^[0-9\.+-]/, false)) { + if (stream.match(/^[+-]?0x[0-9a-fA-F]+/)) + return 'number'; + if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?/)) + return 'number'; + if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?/)) + return 'number'; + } + + // Handle Strings + if (stream.match(/^"([^"]|(""))*"/)) { return 'string'; } + if (stream.match(/^'([^']|(''))*'/)) { return 'string'; } + + // Handle words + if (stream.match(keywords)) { return 'keyword'; } + if (stream.match(builtins)) { return 'builtin'; } + if (stream.match(identifiers)) { return 'variable'; } + + if (stream.match(singleOperators) || stream.match(boolOperators)) { + return 'operator'; } + + // Handle non-detected items + stream.next(); + return null; + }; + + CodeMirror.defineMode('idl', function() { + return { + token: function(stream) { + return tokenBase(stream); + } + }; + }); + + CodeMirror.defineMIME('text/x-idl', 'idl'); +}); diff --git a/backend/webif/static/codemirror/mode/idl/index.html b/backend/webif/static/codemirror/mode/idl/index.html new file mode 100755 index 000000000..4c169e2d6 --- /dev/null +++ b/backend/webif/static/codemirror/mode/idl/index.html @@ -0,0 +1,64 @@ + + +CodeMirror: IDL mode + + + + + + + + + +
+

IDL mode

+ +
+ + +

MIME types defined: text/x-idl.

+
diff --git a/backend/webif/static/codemirror/mode/index.html b/backend/webif/static/codemirror/mode/index.html new file mode 100755 index 000000000..eee26fad0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/index.html @@ -0,0 +1,165 @@ + + +CodeMirror: Language Modes + + + + + +
+ +

Language modes

+ +

This is a list of every mode in the distribution. Each mode lives +in a subdirectory of the mode/ directory, and typically +defines a single JavaScript file that implements the mode. Loading +such file will make the language available to CodeMirror, through +the mode +option.

+ +
+ +
+ +
diff --git a/backend/webif/static/codemirror/mode/javascript/index.html b/backend/webif/static/codemirror/mode/javascript/index.html new file mode 100755 index 000000000..592a133d8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/javascript/index.html @@ -0,0 +1,114 @@ + + +CodeMirror: JavaScript mode + + + + + + + + + + + + +
+

JavaScript mode

+ + +
+ + + +

+ JavaScript mode supports several configuration options: +

    +
  • json which will set the mode to expect JSON + data rather than a JavaScript program.
  • +
  • jsonld which will set the mode to expect + JSON-LD linked data rather + than a JavaScript program (demo).
  • +
  • typescript which will activate additional + syntax highlighting and some other things for TypeScript code + (demo).
  • +
  • statementIndent which (given a number) will + determine the amount of indentation to use for statements + continued on a new line.
  • +
  • wordCharacters, a regexp that indicates which + characters should be considered part of an identifier. + Defaults to /[\w$]/, which does not handle + non-ASCII identifiers. Can be set to something more elaborate + to improve Unicode support.
  • +
+

+ +

MIME types defined: text/javascript, application/json, application/ld+json, text/typescript, application/typescript.

+
diff --git a/backend/webif/static/codemirror/mode/javascript/javascript.js b/backend/webif/static/codemirror/mode/javascript/javascript.js new file mode 100755 index 000000000..514de1c8d --- /dev/null +++ b/backend/webif/static/codemirror/mode/javascript/javascript.js @@ -0,0 +1,875 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("javascript", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var statementIndent = parserConfig.statementIndent; + var jsonldMode = parserConfig.jsonld; + var jsonMode = parserConfig.json || jsonldMode; + var isTS = parserConfig.typescript; + var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d"); + var operator = kw("operator"), atom = {type: "atom", style: "atom"}; + + var jsKeywords = { + "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C, + "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"), + "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, + "this": kw("this"), "class": kw("class"), "super": kw("atom"), + "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, + "await": C + }; + + // Extend the 'normal' keywords with the TypeScript language extensions + if (isTS) { + var type = {type: "variable", style: "type"}; + var tsKeywords = { + // object-like things + "interface": kw("class"), + "implements": C, + "namespace": C, + + // scope modifiers + "public": kw("modifier"), + "private": kw("modifier"), + "protected": kw("modifier"), + "abstract": kw("modifier"), + "readonly": kw("modifier"), + + // types + "string": type, "number": type, "boolean": type, "any": type + }; + + for (var attr in tsKeywords) { + jsKeywords[attr] = tsKeywords[attr]; + } + } + + return jsKeywords; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|~^@]/; + var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; + + function readRegexp(stream) { + var escaped = false, next, inSet = false; + while ((next = stream.next()) != null) { + if (!escaped) { + if (next == "/" && !inSet) return; + if (next == "[") inSet = true; + else if (inSet && next == "]") inSet = false; + } + escaped = !escaped && next == "\\"; + } + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { + return ret("number", "number"); + } else if (ch == "." && stream.match("..")) { + return ret("spread", "meta"); + } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return ret(ch); + } else if (ch == "=" && stream.eat(">")) { + return ret("=>", "operator"); + } else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/o/i)) { + stream.eatWhile(/[0-7]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/b/i)) { + stream.eatWhile(/[01]/i); + return ret("number", "number"); + } else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } else if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } else if (expressionAllowed(stream, state, 1)) { + readRegexp(stream); + stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); + return ret("regexp", "string-2"); + } else { + stream.eat("="); + return ret("operator", "operator", stream.current()); + } + } else if (ch == "`") { + state.tokenize = tokenQuasi; + return tokenQuasi(stream, state); + } else if (ch == "#") { + stream.skipToEnd(); + return ret("error", "error"); + } else if (isOperatorChar.test(ch)) { + if (ch != ">" || !state.lexical || state.lexical.type != ">") { + if (stream.eat("=")) { + if (ch == "!" || ch == "=") stream.eat("=") + } else if (/[<>*+\-]/.test(ch)) { + stream.eat(ch) + if (ch == ">") stream.eat(ch) + } + } + return ret("operator", "operator", stream.current()); + } else if (wordRE.test(ch)) { + stream.eatWhile(wordRE); + var word = stream.current() + if (state.lastType != ".") { + if (keywords.propertyIsEnumerable(word)) { + var kw = keywords[word] + return ret(kw.type, kw.style, word) + } + if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false)) + return ret("async", "keyword", word) + } + return ret("variable", "variable", word) + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next; + if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ + state.tokenize = tokenBase; + return ret("jsonld-keyword", "meta"); + } + while ((next = stream.next()) != null) { + if (next == quote && !escaped) break; + escaped = !escaped && next == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("string", "string"); + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + function tokenQuasi(stream, state) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && next == "\\"; + } + return ret("quasi", "string-2", stream.current()); + } + + var brackets = "([{}])"; + // This is a crude lookahead trick to try and notice that we're + // parsing the argument patterns for a fat-arrow function before we + // actually hit the arrow token. It only works if the arrow is on + // the same line as the arguments and there's no strange noise + // (comments) in between. Fallback is to only notice when we hit the + // arrow, and not declare the arguments as locals for the arrow + // body. + function findFatArrow(stream, state) { + if (state.fatArrowAt) state.fatArrowAt = null; + var arrow = stream.string.indexOf("=>", stream.start); + if (arrow < 0) return; + + if (isTS) { // Try to skip TypeScript return type declarations after the arguments + var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow)) + if (m) arrow = m.index + } + + var depth = 0, sawSomething = false; + for (var pos = arrow - 1; pos >= 0; --pos) { + var ch = stream.string.charAt(pos); + var bracket = brackets.indexOf(ch); + if (bracket >= 0 && bracket < 3) { + if (!depth) { ++pos; break; } + if (--depth == 0) { if (ch == "(") sawSomething = true; break; } + } else if (bracket >= 3 && bracket < 6) { + ++depth; + } else if (wordRE.test(ch)) { + sawSomething = true; + } else if (/["'\/]/.test(ch)) { + return; + } else if (sawSomething && !depth) { + ++pos; + break; + } + } + if (sawSomething && !depth) state.fatArrowAt = pos; + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + for (var cx = state.context; cx; cx = cx.prev) { + for (var v = cx.vars; v; v = v.next) + if (v.name == varname) return true; + } + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + function inList(list) { + for (var v = list; v; v = v.next) + if (v.name == varname) return true; + return false; + } + var state = cx.state; + cx.marked = "def"; + if (state.context) { + if (inList(state.localVars)) return; + state.localVars = {name: varname, next: state.localVars}; + } else { + if (inList(state.globalVars)) return; + if (parserConfig.globalVars) + state.globalVars = {name: varname, next: state.globalVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + cx.state.localVars = defaultVars; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state, indent = state.indented; + if (state.lexical.type == "stat") indent = state.lexical.indented; + else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) + indent = outer.indented; + state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + function exp(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(exp); + }; + return exp; + } + + function statement(type, value) { + if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex); + if (type == "debugger") return cont(expect(";")); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "if") { + if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) + cx.state.cc.pop()(); + return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse); + } + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "variable") { + if (isTS && value == "type") { + cx.marked = "keyword" + return cont(typeexpr, expect("operator"), typeexpr, expect(";")); + } else if (isTS && value == "declare") { + cx.marked = "keyword" + return cont(statement) + } else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) { + cx.marked = "keyword" + return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) + } else { + return cont(pushlex("stat"), maybelabel); + } + } + if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + if (type == "class") return cont(pushlex("form"), className, poplex); + if (type == "export") return cont(pushlex("stat"), afterExport, poplex); + if (type == "import") return cont(pushlex("stat"), afterImport, poplex); + if (type == "async") return cont(statement) + if (value == "@") return cont(expression, statement) + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + return expressionInner(type, false); + } + function expressionNoComma(type) { + return expressionInner(type, true); + } + function parenExpr(type) { + if (type != "(") return pass() + return cont(pushlex(")"), expression, expect(")"), poplex) + } + function expressionInner(type, noComma) { + if (cx.state.fatArrowAt == cx.stream.start) { + var body = noComma ? arrowBodyNoComma : arrowBody; + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext); + else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); + } + + var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; + if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); + if (type == "function") return cont(functiondef, maybeop); + if (type == "class") return cont(pushlex("form"), classExpression, poplex); + if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression); + if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); + if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); + if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); + if (type == "{") return contCommasep(objprop, "}", null, maybeop); + if (type == "quasi") return pass(quasi, maybeop); + if (type == "new") return cont(maybeTarget(noComma)); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + + function maybeoperatorComma(type, value) { + if (type == ",") return cont(expression); + return maybeoperatorNoComma(type, value, false); + } + function maybeoperatorNoComma(type, value, noComma) { + var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; + var expr = noComma == false ? expression : expressionNoComma; + if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); + if (type == "operator") { + if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me); + if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false)) + return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me); + if (value == "?") return cont(expression, expect(":"), expr); + return cont(expr); + } + if (type == "quasi") { return pass(quasi, me); } + if (type == ";") return; + if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); + if (type == ".") return cont(property, me); + if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); + if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) } + if (type == "regexp") { + cx.state.lastType = cx.marked = "operator" + cx.stream.backUp(cx.stream.pos - cx.stream.start - 1) + return cont(expr) + } + } + function quasi(type, value) { + if (type != "quasi") return pass(); + if (value.slice(value.length - 2) != "${") return cont(quasi); + return cont(expression, continueQuasi); + } + function continueQuasi(type) { + if (type == "}") { + cx.marked = "string-2"; + cx.state.tokenize = tokenQuasi; + return cont(quasi); + } + } + function arrowBody(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expression); + } + function arrowBodyNoComma(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expressionNoComma); + } + function maybeTarget(noComma) { + return function(type) { + if (type == ".") return cont(noComma ? targetNoComma : target); + else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma) + else return pass(noComma ? expressionNoComma : expression); + }; + } + function target(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } + } + function targetNoComma(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperatorComma, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "property"; return cont();} + } + function objprop(type, value) { + if (type == "async") { + cx.marked = "property"; + return cont(objprop); + } else if (type == "variable" || cx.style == "keyword") { + cx.marked = "property"; + if (value == "get" || value == "set") return cont(getterSetter); + var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params + if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false))) + cx.state.fatArrowAt = cx.stream.pos + m[0].length + return cont(afterprop); + } else if (type == "number" || type == "string") { + cx.marked = jsonldMode ? "property" : (cx.style + " property"); + return cont(afterprop); + } else if (type == "jsonld-keyword") { + return cont(afterprop); + } else if (type == "modifier") { + return cont(objprop) + } else if (type == "[") { + return cont(expression, expect("]"), afterprop); + } else if (type == "spread") { + return cont(expressionNoComma, afterprop); + } else if (value == "*") { + cx.marked = "keyword"; + return cont(objprop); + } else if (type == ":") { + return pass(afterprop) + } + } + function getterSetter(type) { + if (type != "variable") return pass(afterprop); + cx.marked = "property"; + return cont(functiondef); + } + function afterprop(type) { + if (type == ":") return cont(expressionNoComma); + if (type == "(") return pass(functiondef); + } + function commasep(what, end, sep) { + function proceed(type, value) { + if (sep ? sep.indexOf(type) > -1 : type == ",") { + var lex = cx.state.lexical; + if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; + return cont(function(type, value) { + if (type == end || value == end) return pass() + return pass(what) + }, proceed); + } + if (type == end || value == end) return cont(); + return cont(expect(end)); + } + return function(type, value) { + if (type == end || value == end) return cont(); + return pass(what, proceed); + }; + } + function contCommasep(what, end, info) { + for (var i = 3; i < arguments.length; i++) + cx.cc.push(arguments[i]); + return cont(pushlex(end, info), commasep(what, end), poplex); + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function maybetype(type, value) { + if (isTS) { + if (type == ":") return cont(typeexpr); + if (value == "?") return cont(maybetype); + } + } + function mayberettype(type) { + if (isTS && type == ":") { + if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr) + else return cont(typeexpr) + } + } + function isKW(_, value) { + if (value == "is") { + cx.marked = "keyword" + return cont() + } + } + function typeexpr(type, value) { + if (type == "variable" || value == "void") { + if (value == "keyof") { + cx.marked = "keyword" + return cont(typeexpr) + } else { + cx.marked = "type" + return cont(afterType) + } + } + if (type == "string" || type == "number" || type == "atom") return cont(afterType); + if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType) + if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType) + if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) + } + function maybeReturnType(type) { + if (type == "=>") return cont(typeexpr) + } + function typeprop(type, value) { + if (type == "variable" || cx.style == "keyword") { + cx.marked = "property" + return cont(typeprop) + } else if (value == "?") { + return cont(typeprop) + } else if (type == ":") { + return cont(typeexpr) + } else if (type == "[") { + return cont(expression, maybetype, expect("]"), typeprop) + } + } + function typearg(type) { + if (type == "variable") return cont(typearg) + else if (type == ":") return cont(typeexpr) + } + function afterType(type, value) { + if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) + if (value == "|" || type == ".") return cont(typeexpr) + if (type == "[") return cont(expect("]"), afterType) + if (value == "extends") return cont(typeexpr) + } + function maybeTypeArgs(_, value) { + if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) + } + function typeparam() { + return pass(typeexpr, maybeTypeDefault) + } + function maybeTypeDefault(_, value) { + if (value == "=") return cont(typeexpr) + } + function vardef() { + return pass(pattern, maybetype, maybeAssign, vardefCont); + } + function pattern(type, value) { + if (type == "modifier") return cont(pattern) + if (type == "variable") { register(value); return cont(); } + if (type == "spread") return cont(pattern); + if (type == "[") return contCommasep(pattern, "]"); + if (type == "{") return contCommasep(proppattern, "}"); + } + function proppattern(type, value) { + if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { + register(value); + return cont(maybeAssign); + } + if (type == "variable") cx.marked = "property"; + if (type == "spread") return cont(pattern); + if (type == "}") return pass(); + return cont(expect(":"), pattern, maybeAssign); + } + function maybeAssign(_type, value) { + if (value == "=") return cont(expressionNoComma); + } + function vardefCont(type) { + if (type == ",") return cont(vardef); + } + function maybeelse(type, value) { + if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); + } + function forspec(type) { + if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); + } + function forspec1(type) { + if (type == "var") return cont(vardef, expect(";"), forspec2); + if (type == ";") return cont(forspec2); + if (type == "variable") return cont(formaybeinof); + return pass(expression, expect(";"), forspec2); + } + function formaybeinof(_type, value) { + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return cont(maybeoperatorComma, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return pass(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext); + if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef) + } + function funarg(type, value) { + if (value == "@") cont(expression, funarg) + if (type == "spread" || type == "modifier") return cont(funarg); + return pass(pattern, maybetype, maybeAssign); + } + function classExpression(type, value) { + // Class expressions may have an optional name. + if (type == "variable") return className(type, value); + return classNameAfter(type, value); + } + function className(type, value) { + if (type == "variable") {register(value); return cont(classNameAfter);} + } + function classNameAfter(type, value) { + if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter) + if (value == "extends" || value == "implements" || (isTS && type == ",")) + return cont(isTS ? typeexpr : expression, classNameAfter); + if (type == "{") return cont(pushlex("}"), classBody, poplex); + } + function classBody(type, value) { + if (type == "modifier" || type == "async" || + (type == "variable" && + (value == "static" || value == "get" || value == "set") && + cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) { + cx.marked = "keyword"; + return cont(classBody); + } + if (type == "variable" || cx.style == "keyword") { + cx.marked = "property"; + return cont(isTS ? classfield : functiondef, classBody); + } + if (type == "[") + return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody) + if (value == "*") { + cx.marked = "keyword"; + return cont(classBody); + } + if (type == ";") return cont(classBody); + if (type == "}") return cont(); + if (value == "@") return cont(expression, classBody) + } + function classfield(type, value) { + if (value == "?") return cont(classfield) + if (type == ":") return cont(typeexpr, maybeAssign) + if (value == "=") return cont(expressionNoComma) + return pass(functiondef) + } + function afterExport(type, value) { + if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } + if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } + if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";")); + return pass(statement); + } + function exportField(type, value) { + if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); } + if (type == "variable") return pass(expressionNoComma, exportField); + } + function afterImport(type) { + if (type == "string") return cont(); + return pass(importSpec, maybeMoreImports, maybeFrom); + } + function importSpec(type, value) { + if (type == "{") return contCommasep(importSpec, "}"); + if (type == "variable") register(value); + if (value == "*") cx.marked = "keyword"; + return cont(maybeAs); + } + function maybeMoreImports(type) { + if (type == ",") return cont(importSpec, maybeMoreImports) + } + function maybeAs(_type, value) { + if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } + } + function maybeFrom(_type, value) { + if (value == "from") { cx.marked = "keyword"; return cont(expression); } + } + function arrayLiteral(type) { + if (type == "]") return cont(); + return pass(commasep(expressionNoComma, "]")); + } + + function isContinuedStatement(state, textAfter) { + return state.lastType == "operator" || state.lastType == "," || + isOperatorChar.test(textAfter.charAt(0)) || + /[,.]/.test(textAfter.charAt(0)); + } + + function expressionAllowed(stream, state, backUp) { + return state.tokenize == tokenBase && + /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) || + (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) + } + + // Interface + + return { + startState: function(basecolumn) { + var state = { + tokenize: tokenBase, + lastType: "sof", + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + context: parserConfig.localVars && {vars: parserConfig.localVars}, + indented: basecolumn || 0 + }; + if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") + state.globalVars = parserConfig.globalVars; + return state; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + findFatArrow(stream, state); + } + if (state.tokenize != tokenComment && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize == tokenComment) return CodeMirror.Pass; + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top + // Kludge to prevent 'maybelse' from blocking lexical scope pops + if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { + var c = state.cc[i]; + if (c == poplex) lexical = lexical.prev; + else if (c != maybeelse) break; + } + while ((lexical.type == "stat" || lexical.type == "form") && + (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) && + (top == maybeoperatorComma || top == maybeoperatorNoComma) && + !/^[,\.=+\-*:?[\(]/.test(textAfter)))) + lexical = lexical.prev; + if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") + lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "form") return lexical.indented + indentUnit; + else if (type == "stat") + return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); + else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, + blockCommentStart: jsonMode ? null : "/*", + blockCommentEnd: jsonMode ? null : "*/", + blockCommentContinue: jsonMode ? null : " * ", + lineComment: jsonMode ? null : "//", + fold: "brace", + closeBrackets: "()[]{}''\"\"``", + + helperType: jsonMode ? "json" : "javascript", + jsonldMode: jsonldMode, + jsonMode: jsonMode, + + expressionAllowed: expressionAllowed, + + skipExpression: function(state) { + var top = state.cc[state.cc.length - 1] + if (top == expression || top == expressionNoComma) state.cc.pop() + } + }; +}); + +CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); + +CodeMirror.defineMIME("text/javascript", "javascript"); +CodeMirror.defineMIME("text/ecmascript", "javascript"); +CodeMirror.defineMIME("application/javascript", "javascript"); +CodeMirror.defineMIME("application/x-javascript", "javascript"); +CodeMirror.defineMIME("application/ecmascript", "javascript"); +CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); +CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); +CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); + +}); diff --git a/backend/webif/static/codemirror/mode/javascript/json-ld.html b/backend/webif/static/codemirror/mode/javascript/json-ld.html new file mode 100755 index 000000000..3a37f0bce --- /dev/null +++ b/backend/webif/static/codemirror/mode/javascript/json-ld.html @@ -0,0 +1,72 @@ + + +CodeMirror: JSON-LD mode + + + + + + + + + + + + +
+

JSON-LD mode

+ + +
+ + + +

This is a specialization of the JavaScript mode.

+
diff --git a/backend/webif/static/codemirror/mode/javascript/test.js b/backend/webif/static/codemirror/mode/javascript/test.js new file mode 100755 index 000000000..167e6d016 --- /dev/null +++ b/backend/webif/static/codemirror/mode/javascript/test.js @@ -0,0 +1,423 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("locals", + "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }"); + + MT("comma-and-binop", + "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }"); + + MT("destructuring", + "([keyword function]([def a], [[[def b], [def c] ]]) {", + " [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);", + " [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];", + "})();"); + + MT("destructure_trailing_comma", + "[keyword let] {[def a], [def b],} [operator =] [variable foo];", + "[keyword let] [def c];"); // Parser still in good state? + + MT("class_body", + "[keyword class] [def Foo] {", + " [property constructor]() {}", + " [property sayName]() {", + " [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];", + " }", + "}"); + + MT("class", + "[keyword class] [def Point] [keyword extends] [variable SuperThing] {", + " [keyword get] [property prop]() { [keyword return] [number 24]; }", + " [property constructor]([def x], [def y]) {", + " [keyword super]([string 'something']);", + " [keyword this].[property x] [operator =] [variable-2 x];", + " }", + "}"); + + MT("anonymous_class_expression", + "[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {", + " [property add]([def a], [def b]) {}", + "};"); + + MT("named_class_expression", + "[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {", + " [property sub]([def a], [def b]) {}", + "};"); + + MT("class_async_method", + "[keyword class] [def Foo] {", + " [property sayName1]() {}", + " [keyword async] [property sayName2]() {}", + "}"); + + MT("import", + "[keyword function] [def foo]() {", + " [keyword import] [def $] [keyword from] [string 'jquery'];", + " [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];", + "}"); + + MT("import_trailing_comma", + "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") + + MT("const", + "[keyword function] [def f]() {", + " [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", + "}"); + + MT("for/of", + "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); + + MT("generator", + "[keyword function*] [def repeat]([def n]) {", + " [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])", + " [keyword yield] [variable-2 i];", + "}"); + + MT("quotedStringAddition", + "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); + + MT("quotedFatArrow", + "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];"); + + MT("fatArrow", + "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);", + "[variable a];", // No longer in scope + "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];", + "[variable c];"); + + MT("spread", + "[keyword function] [def f]([def a], [meta ...][def b]) {", + " [variable something]([variable-2 a], [meta ...][variable-2 b]);", + "}"); + + MT("quasi", + "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); + + MT("quasi_no_function", + "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); + + MT("indent_statement", + "[keyword var] [def x] [operator =] [number 10]", + "[variable x] [operator +=] [variable y] [operator +]", + " [atom Infinity]", + "[keyword debugger];"); + + MT("indent_if", + "[keyword if] ([number 1])", + " [keyword break];", + "[keyword else] [keyword if] ([number 2])", + " [keyword continue];", + "[keyword else]", + " [number 10];", + "[keyword if] ([number 1]) {", + " [keyword break];", + "} [keyword else] [keyword if] ([number 2]) {", + " [keyword continue];", + "} [keyword else] {", + " [number 10];", + "}"); + + MT("indent_for", + "[keyword for] ([keyword var] [def i] [operator =] [number 0];", + " [variable i] [operator <] [number 100];", + " [variable i][operator ++])", + " [variable doSomething]([variable i]);", + "[keyword debugger];"); + + MT("indent_c_style", + "[keyword function] [def foo]()", + "{", + " [keyword debugger];", + "}"); + + MT("indent_else", + "[keyword for] (;;)", + " [keyword if] ([variable foo])", + " [keyword if] ([variable bar])", + " [number 1];", + " [keyword else]", + " [number 2];", + " [keyword else]", + " [number 3];"); + + MT("indent_funarg", + "[variable foo]([number 10000],", + " [keyword function]([def a]) {", + " [keyword debugger];", + "};"); + + MT("indent_below_if", + "[keyword for] (;;)", + " [keyword if] ([variable foo])", + " [number 1];", + "[number 2];"); + + MT("indent_semicolonless_if", + "[keyword function] [def foo]() {", + " [keyword if] ([variable x])", + " [variable foo]()", + "}") + + MT("indent_semicolonless_if_with_statement", + "[keyword function] [def foo]() {", + " [keyword if] ([variable x])", + " [variable foo]()", + " [variable bar]()", + "}") + + MT("multilinestring", + "[keyword var] [def x] [operator =] [string 'foo\\]", + "[string bar'];"); + + MT("scary_regexp", + "[string-2 /foo[[/]]bar/];"); + + MT("indent_strange_array", + "[keyword var] [def x] [operator =] [[", + " [number 1],,", + " [number 2],", + "]];", + "[number 10];"); + + MT("param_default", + "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {", + " [keyword return] [variable-2 x];", + "}"); + + MT("new_target", + "[keyword function] [def F]([def target]) {", + " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", + " [keyword return] [keyword new]", + " .[keyword target];", + " }", + "}"); + + MT("async", + "[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }"); + + MT("async_assignment", + "[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };"); + + MT("async_object", + "[keyword let] [def obj] [operator =] { [property async]: [atom false] };"); + + // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173 + MT("async_object_function", + "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };"); + + MT("async_object_properties", + "[keyword let] [def obj] [operator =] {", + " [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", + " [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", + " [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },", + "};"); + + MT("async_arrow", + "[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };"); + + MT("async_jquery", + "[variable $].[property ajax]({", + " [property url]: [variable url],", + " [property async]: [atom true],", + " [property method]: [string 'GET']", + "});"); + + MT("async_variable", + "[keyword const] [def async] [operator =] {[property a]: [number 1]};", + "[keyword const] [def foo] [operator =] [string-2 `bar ${][variable async].[property a][string-2 }`];") + + MT("async_comment", + "[keyword async] [comment /**/] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }"); + + MT("indent_switch", + "[keyword switch] ([variable x]) {", + " [keyword default]:", + " [keyword return] [number 2]", + "}") + + MT("regexp_corner_case", + "[operator +]{} [operator /] [atom undefined];", + "[[[meta ...][string-2 /\\//] ]];", + "[keyword void] [string-2 /\\//];", + "[keyword do] [string-2 /\\//]; [keyword while] ([number 0]);", + "[keyword if] ([number 0]) {} [keyword else] [string-2 /\\//];", + "[string-2 `${][variable async][operator ++][string-2 }//`];", + "[string-2 `${]{} [operator /] [string-2 /\\//}`];") + + MT("return_eol", + "[keyword return]", + "{} [string-2 /5/]") + + var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript") + function TS(name) { + test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) + } + + TS("typescript_extend_type", + "[keyword class] [def Foo] [keyword extends] [type Some][operator <][type Type][operator >] {}") + + TS("typescript_arrow_type", + "[keyword let] [def x]: ([variable arg]: [type Type]) [operator =>] [type ReturnType]") + + TS("typescript_class", + "[keyword class] [def Foo] {", + " [keyword public] [keyword static] [property main]() {}", + " [keyword private] [property _foo]: [type string];", + "}") + + TS("typescript_literal_types", + "[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];", + "[keyword interface] [def MyAttributes] {", + " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", + " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", + "}", + "[keyword interface] [def MyInstance] [keyword extends] [type Sequelize].[type Instance] [operator <] [type MyAttributes] [operator >] {", + " [property rawAttributes]: [type MyAttributes];", + " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", + " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", + "}") + + TS("typescript_extend_operators", + "[keyword export] [keyword interface] [def UserModel] [keyword extends]", + " [type Sequelize].[type Model] [operator <] [type UserInstance], [type UserAttributes] [operator >] {", + " [property findById]: (", + " [variable userId]: [type number]", + " ) [operator =>] [type Promise] [operator <] [type Array] [operator <] { [property id], [property name] } [operator >>];", + " [property updateById]: (", + " [variable userId]: [type number],", + " [variable isActive]: [type boolean]", + " ) [operator =>] [type Promise] [operator <] [type AccountHolderNotificationPreferenceInstance] [operator >];", + " }") + + TS("typescript_interface_with_const", + "[keyword const] [def hello]: {", + " [property prop1][operator ?]: [type string];", + " [property prop2][operator ?]: [type string];", + "} [operator =] {};") + + TS("typescript_double_extend", + "[keyword export] [keyword interface] [def UserAttributes] {", + " [property id][operator ?]: [type number];", + " [property createdAt][operator ?]: [type Date];", + "}", + "[keyword export] [keyword interface] [def UserInstance] [keyword extends] [type Sequelize].[type Instance][operator <][type UserAttributes][operator >], [type UserAttributes] {", + " [property id]: [type number];", + " [property createdAt]: [type Date];", + "}"); + + TS("typescript_index_signature", + "[keyword interface] [def A] {", + " [[ [variable prop]: [type string] ]]: [type any];", + " [property prop1]: [type any];", + "}"); + + TS("typescript_generic_class", + "[keyword class] [def Foo][operator <][type T][operator >] {", + " [property bar]() {}", + " [property foo](): [type Foo] {}", + "}") + + TS("typescript_type_when_keyword", + "[keyword export] [keyword type] [type AB] [operator =] [type A] [operator |] [type B];", + "[keyword type] [type Flags] [operator =] {", + " [property p1]: [type string];", + " [property p2]: [type boolean];", + "};") + + TS("typescript_type_when_not_keyword", + "[keyword class] [def HasType] {", + " [property type]: [type string];", + " [property constructor]([def type]: [type string]) {", + " [keyword this].[property type] [operator =] [variable-2 type];", + " }", + " [property setType]({ [def type] }: { [property type]: [type string]; }) {", + " [keyword this].[property type] [operator =] [variable-2 type];", + " }", + "}") + + TS("typescript_function_generics", + "[keyword function] [def a]() {}", + "[keyword function] [def b][operator <][type IA] [keyword extends] [type object], [type IB] [keyword extends] [type object][operator >]() {}", + "[keyword function] [def c]() {}") + + TS("typescript_complex_return_type", + "[keyword function] [def A]() {", + " [keyword return] [keyword this].[property property];", + "}", + "[keyword function] [def B](): [type Promise][operator <]{ [[ [variable key]: [type string] ]]: [type any] } [operator |] [atom null][operator >] {", + " [keyword return] [keyword this].[property property];", + "}") + + TS("typescript_complex_type_casting", + "[keyword const] [def giftpay] [operator =] [variable config].[property get]([string 'giftpay']) [keyword as] { [[ [variable platformUuid]: [type string] ]]: { [property version]: [type number]; [property apiCode]: [type string]; } };") + + TS("typescript_keyof", + "[keyword function] [def x][operator <][type T] [keyword extends] [keyword keyof] [type X][operator >]([def a]: [type T]) {", + " [keyword return]") + + TS("typescript_new_typeargs", + "[keyword let] [def x] [operator =] [keyword new] [variable Map][operator <][type string], [type Date][operator >]([string-2 `foo${][variable bar][string-2 }`])") + + TS("modifiers", + "[keyword class] [def Foo] {", + " [keyword public] [keyword abstract] [property bar]() {}", + " [property constructor]([keyword readonly] [keyword private] [def x]) {}", + "}") + + TS("arrow prop", + "({[property a]: [def p] [operator =>] [variable-2 p]})") + + TS("generic in function call", + "[keyword this].[property a][operator <][type Type][operator >]([variable foo]);", + "[keyword this].[property a][operator <][variable Type][operator >][variable foo];") + + TS("type guard", + "[keyword class] [def Appler] {", + " [keyword static] [property assertApple]([def fruit]: [type Fruit]): [variable-2 fruit] [keyword is] [type Apple] {", + " [keyword if] ([operator !]([variable-2 fruit] [keyword instanceof] [variable Apple]))", + " [keyword throw] [keyword new] [variable Error]();", + " }", + "}") + + var jsonld_mode = CodeMirror.getMode( + {indentUnit: 2}, + {name: "javascript", jsonld: true} + ); + function LD(name) { + test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1)); + } + + LD("json_ld_keywords", + '{', + ' [meta "@context"]: {', + ' [meta "@base"]: [string "http://example.com"],', + ' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],', + ' [property "likesFlavor"]: {', + ' [meta "@container"]: [meta "@list"]', + ' [meta "@reverse"]: [string "@beFavoriteOf"]', + ' },', + ' [property "nick"]: { [meta "@container"]: [meta "@set"] },', + ' [property "nick"]: { [meta "@container"]: [meta "@index"] }', + ' },', + ' [meta "@graph"]: [[ {', + ' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],', + ' [property "name"]: [string "John Lennon"],', + ' [property "modified"]: {', + ' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],', + ' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]', + ' }', + ' } ]]', + '}'); + + LD("json_ld_fake", + '{', + ' [property "@fake"]: [string "@fake"],', + ' [property "@contextual"]: [string "@identifier"],', + ' [property "user@domain.com"]: [string "@graphical"],', + ' [property "@ID"]: [string "@@ID"]', + '}'); +})(); diff --git a/backend/webif/static/codemirror/mode/javascript/typescript.html b/backend/webif/static/codemirror/mode/javascript/typescript.html new file mode 100755 index 000000000..1f26d7fe1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/javascript/typescript.html @@ -0,0 +1,61 @@ + + +CodeMirror: TypeScript mode + + + + + + + + + +
+

TypeScript mode

+ + +
+ + + +

This is a specialization of the JavaScript mode.

+
diff --git a/backend/webif/static/codemirror/mode/jinja2/index.html b/backend/webif/static/codemirror/mode/jinja2/index.html new file mode 100755 index 000000000..5a70e9153 --- /dev/null +++ b/backend/webif/static/codemirror/mode/jinja2/index.html @@ -0,0 +1,54 @@ + + +CodeMirror: Jinja2 mode + + + + + + + + + +
+

Jinja2 mode

+
+ +
diff --git a/backend/webif/static/codemirror/mode/jinja2/jinja2.js b/backend/webif/static/codemirror/mode/jinja2/jinja2.js new file mode 100755 index 000000000..5d57d1344 --- /dev/null +++ b/backend/webif/static/codemirror/mode/jinja2/jinja2.js @@ -0,0 +1,142 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("jinja2", function() { + var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif", + "extends", "filter", "endfilter", "firstof", "for", + "endfor", "if", "endif", "ifchanged", "endifchanged", + "ifequal", "endifequal", "ifnotequal", + "endifnotequal", "in", "include", "load", "not", "now", "or", + "parsed", "regroup", "reversed", "spaceless", + "endspaceless", "ssi", "templatetag", "openblock", + "closeblock", "openvariable", "closevariable", + "openbrace", "closebrace", "opencomment", + "closecomment", "widthratio", "url", "with", "endwith", + "get_current_language", "trans", "endtrans", "noop", "blocktrans", + "endblocktrans", "get_available_languages", + "get_current_language_bidi", "plural"], + operator = /^[+\-*&%=<>!?|~^]/, + sign = /^[:\[\(\{]/, + atom = ["true", "false"], + number = /^(\d[+\-\*\/])?\d+(\.\d+)?/; + + keywords = new RegExp("((" + keywords.join(")|(") + "))\\b"); + atom = new RegExp("((" + atom.join(")|(") + "))\\b"); + + function tokenBase (stream, state) { + var ch = stream.peek(); + + //Comment + if (state.incomment) { + if(!stream.skipTo("#}")) { + stream.skipToEnd(); + } else { + stream.eatWhile(/\#|}/); + state.incomment = false; + } + return "comment"; + //Tag + } else if (state.intag) { + //After operator + if(state.operator) { + state.operator = false; + if(stream.match(atom)) { + return "atom"; + } + if(stream.match(number)) { + return "number"; + } + } + //After sign + if(state.sign) { + state.sign = false; + if(stream.match(atom)) { + return "atom"; + } + if(stream.match(number)) { + return "number"; + } + } + + if(state.instring) { + if(ch == state.instring) { + state.instring = false; + } + stream.next(); + return "string"; + } else if(ch == "'" || ch == '"') { + state.instring = ch; + stream.next(); + return "string"; + } else if(stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) { + state.intag = false; + return "tag"; + } else if(stream.match(operator)) { + state.operator = true; + return "operator"; + } else if(stream.match(sign)) { + state.sign = true; + } else { + if(stream.eat(" ") || stream.sol()) { + if(stream.match(keywords)) { + return "keyword"; + } + if(stream.match(atom)) { + return "atom"; + } + if(stream.match(number)) { + return "number"; + } + if(stream.sol()) { + stream.next(); + } + } else { + stream.next(); + } + + } + return "variable"; + } else if (stream.eat("{")) { + if (stream.eat("#")) { + state.incomment = true; + if(!stream.skipTo("#}")) { + stream.skipToEnd(); + } else { + stream.eatWhile(/\#|}/); + state.incomment = false; + } + return "comment"; + //Open tag + } else if (ch = stream.eat(/\{|%/)) { + //Cache close tag + state.intag = ch; + if(ch == "{") { + state.intag = "}"; + } + stream.eat("-"); + return "tag"; + } + } + stream.next(); + }; + + return { + startState: function () { + return {tokenize: tokenBase}; + }, + token: function (stream, state) { + return state.tokenize(stream, state); + } + }; + }); +}); diff --git a/backend/webif/static/codemirror/mode/jsx/index.html b/backend/webif/static/codemirror/mode/jsx/index.html new file mode 100755 index 000000000..1054bbcc0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/jsx/index.html @@ -0,0 +1,89 @@ + + +CodeMirror: JSX mode + + + + + + + + + + + +
+

JSX mode

+ +
+ + + +

JSX Mode for React's +JavaScript syntax extension.

+ +

MIME types defined: text/jsx, text/typescript-jsx.

+ +
diff --git a/backend/webif/static/codemirror/mode/jsx/jsx.js b/backend/webif/static/codemirror/mode/jsx/jsx.js new file mode 100755 index 000000000..45c3024ab --- /dev/null +++ b/backend/webif/static/codemirror/mode/jsx/jsx.js @@ -0,0 +1,148 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript")) + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod) + else // Plain browser env + mod(CodeMirror) +})(function(CodeMirror) { + "use strict" + + // Depth means the amount of open braces in JS context, in XML + // context 0 means not in tag, 1 means in tag, and 2 means in tag + // and js block comment. + function Context(state, mode, depth, prev) { + this.state = state; this.mode = mode; this.depth = depth; this.prev = prev + } + + function copyContext(context) { + return new Context(CodeMirror.copyState(context.mode, context.state), + context.mode, + context.depth, + context.prev && copyContext(context.prev)) + } + + CodeMirror.defineMode("jsx", function(config, modeConfig) { + var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false}) + var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript") + + function flatXMLIndent(state) { + var tagName = state.tagName + state.tagName = null + var result = xmlMode.indent(state, "") + state.tagName = tagName + return result + } + + function token(stream, state) { + if (state.context.mode == xmlMode) + return xmlToken(stream, state, state.context) + else + return jsToken(stream, state, state.context) + } + + function xmlToken(stream, state, cx) { + if (cx.depth == 2) { // Inside a JS /* */ comment + if (stream.match(/^.*?\*\//)) cx.depth = 1 + else stream.skipToEnd() + return "comment" + } + + if (stream.peek() == "{") { + xmlMode.skipAttribute(cx.state) + + var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context + // If JS starts on same line as tag + if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) { + while (xmlContext.prev && !xmlContext.startOfLine) + xmlContext = xmlContext.prev + // If tag starts the line, use XML indentation level + if (xmlContext.startOfLine) indent -= config.indentUnit + // Else use JS indentation level + else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented + // Else if inside of tag + } else if (cx.depth == 1) { + indent += config.indentUnit + } + + state.context = new Context(CodeMirror.startState(jsMode, indent), + jsMode, 0, state.context) + return null + } + + if (cx.depth == 1) { // Inside of tag + if (stream.peek() == "<") { // Tag inside of tag + xmlMode.skipAttribute(cx.state) + state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)), + xmlMode, 0, state.context) + return null + } else if (stream.match("//")) { + stream.skipToEnd() + return "comment" + } else if (stream.match("/*")) { + cx.depth = 2 + return token(stream, state) + } + } + + var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop + if (/\btag\b/.test(style)) { + if (/>$/.test(cur)) { + if (cx.state.context) cx.depth = 0 + else state.context = state.context.prev + } else if (/^ -1) { + stream.backUp(cur.length - stop) + } + return style + } + + function jsToken(stream, state, cx) { + if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) { + jsMode.skipExpression(cx.state) + state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")), + xmlMode, 0, state.context) + return null + } + + var style = jsMode.token(stream, cx.state) + if (!style && cx.depth != null) { + var cur = stream.current() + if (cur == "{") { + cx.depth++ + } else if (cur == "}") { + if (--cx.depth == 0) state.context = state.context.prev + } + } + return style + } + + return { + startState: function() { + return {context: new Context(CodeMirror.startState(jsMode), jsMode)} + }, + + copyState: function(state) { + return {context: copyContext(state.context)} + }, + + token: token, + + indent: function(state, textAfter, fullLine) { + return state.context.mode.indent(state.context.state, textAfter, fullLine) + }, + + innerMode: function(state) { + return state.context + } + } + }, "xml", "javascript") + + CodeMirror.defineMIME("text/jsx", "jsx") + CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}}) +}); diff --git a/backend/webif/static/codemirror/mode/jsx/test.js b/backend/webif/static/codemirror/mode/jsx/test.js new file mode 100755 index 000000000..61f84ebe8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/jsx/test.js @@ -0,0 +1,88 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "jsx") + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)) } + + MT("selfclose", + "[keyword var] [def x] [operator =] [bracket&tag <] [tag foo] [bracket&tag />] [operator +] [number 1];") + + MT("openclose", + "([bracket&tag <][tag foo][bracket&tag >]hello [atom &][bracket&tag ][operator ++])") + + MT("attr", + "([bracket&tag <][tag foo] [attribute abc]=[string 'value'][bracket&tag >]hello [atom &][bracket&tag ][operator ++])") + + MT("braced_attr", + "([bracket&tag <][tag foo] [attribute abc]={[number 10]}[bracket&tag >]hello [atom &][bracket&tag ][operator ++])") + + MT("braced_text", + "([bracket&tag <][tag foo][bracket&tag >]hello {[number 10]} [atom &][bracket&tag ][operator ++])") + + MT("nested_tag", + "([bracket&tag <][tag foo][bracket&tag ><][tag bar][bracket&tag >][operator ++])") + + MT("nested_jsx", + "[keyword return] (", + " [bracket&tag <][tag foo][bracket&tag >]", + " say {[number 1] [operator +] [bracket&tag <][tag bar] [attribute attr]={[number 10]}[bracket&tag />]}!", + " [bracket&tag ][operator ++]", + ")") + + MT("preserve_js_context", + "[variable x] [operator =] [string-2 `quasi${][bracket&tag <][tag foo][bracket&tag />][string-2 }quoted`]") + + MT("string_interpolation", + "[variable x] [operator =] [string-2 `quasi${] [number 10] [string-2 }`]") + + MT("line_comment", + "([bracket&tag <][tag foo] [comment // hello]", + " [bracket&tag >][operator ++])") + + MT("line_comment_not_in_tag", + "([bracket&tag <][tag foo][bracket&tag >] // hello", + " [bracket&tag ][operator ++])") + + MT("block_comment", + "([bracket&tag <][tag foo] [comment /* hello]", + "[comment line 2]", + "[comment line 3 */] [bracket&tag >][operator ++])") + + MT("block_comment_not_in_tag", + "([bracket&tag <][tag foo][bracket&tag >]/* hello", + " line 2", + " line 3 */ [bracket&tag ][operator ++])") + + MT("missing_attr", + "([bracket&tag <][tag foo] [attribute selected][bracket&tag />][operator ++])") + + MT("indent_js", + "([bracket&tag <][tag foo][bracket&tag >]", + " [bracket&tag <][tag bar] [attribute baz]={[keyword function]() {", + " [keyword return] [number 10]", + " }}[bracket&tag />]", + " [bracket&tag ])") + + MT("spread", + "([bracket&tag <][tag foo] [attribute bar]={[meta ...][variable baz] [operator /][number 2]}[bracket&tag />])") + + MT("tag_attribute", + "([bracket&tag <][tag foo] [attribute bar]=[bracket&tag <][tag foo][bracket&tag />/>][operator ++])") + + var ts_mode = CodeMirror.getMode({indentUnit: 2}, "text/typescript-jsx") + function TS(name) { test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) } + + TS("tsx_react_integration", + "[keyword interface] [def Props] {", + " [property foo]: [type string];", + "}", + "[keyword class] [def MyComponent] [keyword extends] [type React].[type Component] [operator <] [type Props], [type any] [operator >] {", + " [property render]() {", + " [keyword return] [bracket&tag <][tag span][bracket&tag >]{[keyword this].[property props].[property foo]}[bracket&tag ]", + " }", + "}", + "[bracket&tag <][tag MyComponent] [attribute foo]=[string \"bar\"] [bracket&tag />]; [comment //ok]", + "[bracket&tag <][tag MyComponent] [attribute foo]={[number 0]} [bracket&tag />]; [comment //error]") + +})() diff --git a/backend/webif/static/codemirror/mode/julia/index.html b/backend/webif/static/codemirror/mode/julia/index.html new file mode 100755 index 000000000..e1492c210 --- /dev/null +++ b/backend/webif/static/codemirror/mode/julia/index.html @@ -0,0 +1,195 @@ + + +CodeMirror: Julia mode + + + + + + + + + +
+

Julia mode

+ +
+ + +

MIME types defined: text/x-julia.

+
diff --git a/backend/webif/static/codemirror/mode/julia/julia.js b/backend/webif/static/codemirror/mode/julia/julia.js new file mode 100755 index 000000000..9a36fd05a --- /dev/null +++ b/backend/webif/static/codemirror/mode/julia/julia.js @@ -0,0 +1,418 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("julia", function(config, parserConf) { + function wordRegexp(words, end) { + if (typeof end === "undefined") { end = "\\b"; } + return new RegExp("^((" + words.join(")|(") + "))" + end); + } + + var octChar = "\\\\[0-7]{1,3}"; + var hexChar = "\\\\x[A-Fa-f0-9]{1,2}"; + var sChar = "\\\\[abefnrtv0%?'\"\\\\]"; + var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])"; + + var operators = parserConf.operators || wordRegexp([ + "[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "->", "\\/\\/", + "[\\\\%*+\\-<>!=\\/^|&\\u00F7\\u22BB]=?", "\\?", "\\$", "~", ":", + "\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2218", + "\\u221A", "\\u221B", "\\u2229", "\\u222A", "\\u2260", "\\u2264", + "\\u2265", "\\u2286", "\\u2288", "\\u228A", "\\u22C5", + "\\b(in|isa)\\b(?!\.?\\()"], ""); + var delimiters = parserConf.delimiters || /^[;,()[\]{}]/; + var identifiers = parserConf.identifiers || + /^[_A-Za-z\u00A1-\u2217\u2219-\uFFFF][\w\u00A1-\u2217\u2219-\uFFFF]*!*/; + + var chars = wordRegexp([octChar, hexChar, sChar, uChar], "'"); + var openers = wordRegexp(["begin", "function", "type", "struct", "immutable", + "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", + "finally", "catch", "do"]); + var closers = wordRegexp(["end", "else", "elseif", "catch", "finally"]); + var keywords = wordRegexp(["if", "else", "elseif", "while", "for", "begin", + "let", "end", "do", "try", "catch", "finally", "return", "break", + "continue", "global", "local", "const", "export", "import", "importall", + "using", "function", "where", "macro", "module", "baremodule", "struct", + "type", "mutable", "immutable", "quote", "typealias", "abstract", + "primitive", "bitstype"]); + var builtins = wordRegexp(["true", "false", "nothing", "NaN", "Inf"]); + + var macro = /^@[_A-Za-z][\w]*/; + var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/; + var stringPrefixes = /^(`|([_A-Za-z\u00A1-\uFFFF]*"("")?))/; + + function inArray(state) { + return inGenerator(state, '[') + } + + function inGenerator(state, bracket) { + var curr = currentScope(state), + prev = currentScope(state, 1); + if (typeof(bracket) === "undefined") { bracket = '('; } + if (curr === bracket || (prev === bracket && curr === "for")) { + return true; + } + return false; + } + + function currentScope(state, n) { + if (typeof(n) === "undefined") { n = 0; } + if (state.scopes.length <= n) { + return null; + } + return state.scopes[state.scopes.length - (n + 1)]; + } + + // tokenizers + function tokenBase(stream, state) { + // Handle multiline comments + if (stream.match(/^#=/, false)) { + state.tokenize = tokenComment; + return state.tokenize(stream, state); + } + + // Handle scope changes + var leavingExpr = state.leavingExpr; + if (stream.sol()) { + leavingExpr = false; + } + state.leavingExpr = false; + + if (leavingExpr) { + if (stream.match(/^'+/)) { + return "operator"; + } + } + + if (stream.match(/\.{4,}/)) { + return "error"; + } else if (stream.match(/\.{1,3}/)) { + return "operator"; + } + + if (stream.eatSpace()) { + return null; + } + + var ch = stream.peek(); + + // Handle single line comments + if (ch === '#') { + stream.skipToEnd(); + return "comment"; + } + + if (ch === '[') { + state.scopes.push('['); + } + + if (ch === '(') { + state.scopes.push('('); + } + + var scope = currentScope(state); + + if (inArray(state) && ch === ']') { + if (scope === "for") { state.scopes.pop(); } + state.scopes.pop(); + state.leavingExpr = true; + } + + if (inGenerator(state) && ch === ')') { + if (scope === "for") { state.scopes.pop(); } + state.scopes.pop(); + state.leavingExpr = true; + } + + if (inArray(state)) { + if (state.lastToken == "end" && stream.match(/^:/)) { + return "operator"; + } + if (stream.match(/^end/)) { + return "number"; + } + } + + var match; + if (match = stream.match(openers, false)) { + state.scopes.push(match[0]); + } + + if (stream.match(closers, false)) { + state.scopes.pop(); + } + + // Handle type annotations + if (stream.match(/^::(?![:\$])/)) { + state.tokenize = tokenAnnotation; + return state.tokenize(stream, state); + } + + // Handle symbols + if (!leavingExpr && stream.match(symbol) || + stream.match(/:([<>]:|<<=?|>>>?=?|->|\/\/|\.{2,3}|[\.\\%*+\-<>!\/^|&]=?|[~\?\$])/)) { + return "builtin"; + } + + // Handle parametric types + //if (stream.match(/^{[^}]*}(?=\()/)) { + // return "builtin"; + //} + + // Handle operators and Delimiters + if (stream.match(operators)) { + return "operator"; + } + + // Handle Number Literals + if (stream.match(/^\.?\d/, false)) { + var imMatcher = RegExp(/^im\b/); + var numberLiteral = false; + // Floats + if (stream.match(/^\d*\.(?!\.)\d*([Eef][\+\-]?\d+)?/i)) { numberLiteral = true; } + if (stream.match(/^\d+\.(?!\.)\d*/)) { numberLiteral = true; } + if (stream.match(/^\.\d+/)) { numberLiteral = true; } + if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { numberLiteral = true; } + // Integers + if (stream.match(/^0x[0-9a-f]+/i)) { numberLiteral = true; } // Hex + if (stream.match(/^0b[01]+/i)) { numberLiteral = true; } // Binary + if (stream.match(/^0o[0-7]+/i)) { numberLiteral = true; } // Octal + if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { numberLiteral = true; } // Decimal + // Zero by itself with no other piece of number. + if (stream.match(/^0(?![\dx])/i)) { numberLiteral = true; } + if (numberLiteral) { + // Integer literals may be "long" + stream.match(imMatcher); + state.leavingExpr = true; + return "number"; + } + } + + // Handle Chars + if (stream.match(/^'/)) { + state.tokenize = tokenChar; + return state.tokenize(stream, state); + } + + // Handle Strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } + + if (stream.match(macro)) { + return "meta"; + } + + if (stream.match(delimiters)) { + return null; + } + + if (stream.match(keywords)) { + return "keyword"; + } + + if (stream.match(builtins)) { + return "builtin"; + } + + var isDefinition = state.isDefinition || state.lastToken == "function" || + state.lastToken == "macro" || state.lastToken == "type" || + state.lastToken == "struct" || state.lastToken == "immutable"; + + if (stream.match(identifiers)) { + if (isDefinition) { + if (stream.peek() === '.') { + state.isDefinition = true; + return "variable"; + } + state.isDefinition = false; + return "def"; + } + if (stream.match(/^({[^}]*})*\(/, false)) { + state.tokenize = tokenCallOrDef; + return state.tokenize(stream, state); + } + state.leavingExpr = true; + return "variable"; + } + + // Handle non-detected items + stream.next(); + return "error"; + } + + function tokenCallOrDef(stream, state) { + var match = stream.match(/^(\(\s*)/); + if (match) { + if (state.firstParenPos < 0) + state.firstParenPos = state.scopes.length; + state.scopes.push('('); + state.charsAdvanced += match[1].length; + } + if (currentScope(state) == '(' && stream.match(/^\)/)) { + state.scopes.pop(); + state.charsAdvanced += 1; + if (state.scopes.length <= state.firstParenPos) { + var isDefinition = stream.match(/^(\s*where\s+[^\s=]+)*\s*?=(?!=)/, false); + stream.backUp(state.charsAdvanced); + state.firstParenPos = -1; + state.charsAdvanced = 0; + state.tokenize = tokenBase; + if (isDefinition) + return "def"; + return "builtin"; + } + } + // Unfortunately javascript does not support multiline strings, so we have + // to undo anything done upto here if a function call or definition splits + // over two or more lines. + if (stream.match(/^$/g, false)) { + stream.backUp(state.charsAdvanced); + while (state.scopes.length > state.firstParenPos) + state.scopes.pop(); + state.firstParenPos = -1; + state.charsAdvanced = 0; + state.tokenize = tokenBase; + return "builtin"; + } + state.charsAdvanced += stream.match(/^([^()]*)/)[1].length; + return state.tokenize(stream, state); + } + + function tokenAnnotation(stream, state) { + stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/); + if (stream.match(/^{/)) { + state.nestedLevels++; + } else if (stream.match(/^}/)) { + state.nestedLevels--; + } + if (state.nestedLevels > 0) { + stream.match(/.*?(?={|})/) || stream.next(); + } else if (state.nestedLevels == 0) { + state.tokenize = tokenBase; + } + return "builtin"; + } + + function tokenComment(stream, state) { + if (stream.match(/^#=/)) { + state.nestedLevels++; + } + if (!stream.match(/.*?(?=(#=|=#))/)) { + stream.skipToEnd(); + } + if (stream.match(/^=#/)) { + state.nestedLevels--; + if (state.nestedLevels == 0) + state.tokenize = tokenBase; + } + return "comment"; + } + + function tokenChar(stream, state) { + var isChar = false, match; + if (stream.match(chars)) { + isChar = true; + } else if (match = stream.match(/\\u([a-f0-9]{1,4})(?=')/i)) { + var value = parseInt(match[1], 16); + if (value <= 55295 || value >= 57344) { // (U+0,U+D7FF), (U+E000,U+FFFF) + isChar = true; + stream.next(); + } + } else if (match = stream.match(/\\U([A-Fa-f0-9]{5,8})(?=')/)) { + var value = parseInt(match[1], 16); + if (value <= 1114111) { // U+10FFFF + isChar = true; + stream.next(); + } + } + if (isChar) { + state.leavingExpr = true; + state.tokenize = tokenBase; + return "string"; + } + if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); } + if (stream.match(/^'/)) { state.tokenize = tokenBase; } + return "error"; + } + + function tokenStringFactory(delimiter) { + if (delimiter.substr(-3) === '"""') { + delimiter = '"""'; + } else if (delimiter.substr(-1) === '"') { + delimiter = '"'; + } + function tokenString(stream, state) { + if (stream.eat('\\')) { + stream.next(); + } else if (stream.match(delimiter)) { + state.tokenize = tokenBase; + state.leavingExpr = true; + return "string"; + } else { + stream.eat(/[`"]/); + } + stream.eatWhile(/[^\\`"]/); + return "string"; + } + return tokenString; + } + + var external = { + startState: function() { + return { + tokenize: tokenBase, + scopes: [], + lastToken: null, + leavingExpr: false, + isDefinition: false, + nestedLevels: 0, + charsAdvanced: 0, + firstParenPos: -1 + }; + }, + + token: function(stream, state) { + var style = state.tokenize(stream, state); + var current = stream.current(); + + if (current && style) { + state.lastToken = current; + } + + return style; + }, + + indent: function(state, textAfter) { + var delta = 0; + if ( textAfter === ']' || textAfter === ')' || textAfter === "end" || + textAfter === "else" || textAfter === "catch" || textAfter === "elseif" || + textAfter === "finally" ) { + delta = -1; + } + return (state.scopes.length + delta) * config.indentUnit; + }, + + electricInput: /\b(end|else|catch|finally)\b/, + blockCommentStart: "#=", + blockCommentEnd: "=#", + lineComment: "#", + fold: "indent" + }; + return external; +}); + + +CodeMirror.defineMIME("text/x-julia", "julia"); + +}); diff --git a/backend/webif/static/codemirror/mode/livescript/index.html b/backend/webif/static/codemirror/mode/livescript/index.html new file mode 100755 index 000000000..f41547987 --- /dev/null +++ b/backend/webif/static/codemirror/mode/livescript/index.html @@ -0,0 +1,459 @@ + + +CodeMirror: LiveScript mode + + + + + + + + + + +
+

LiveScript mode

+
+ + +

MIME types defined: text/x-livescript.

+ +

The LiveScript mode was written by Kenneth Bentley.

+ +
diff --git a/backend/webif/static/codemirror/mode/livescript/livescript.js b/backend/webif/static/codemirror/mode/livescript/livescript.js new file mode 100755 index 000000000..1e363f876 --- /dev/null +++ b/backend/webif/static/codemirror/mode/livescript/livescript.js @@ -0,0 +1,280 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Link to the project's GitHub page: + * https://github.com/duralog/CodeMirror + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode('livescript', function(){ + var tokenBase = function(stream, state) { + var next_rule = state.next || "start"; + if (next_rule) { + state.next = state.next; + var nr = Rules[next_rule]; + if (nr.splice) { + for (var i$ = 0; i$ < nr.length; ++i$) { + var r = nr[i$]; + if (r.regex && stream.match(r.regex)) { + state.next = r.next || state.next; + return r.token; + } + } + stream.next(); + return 'error'; + } + if (stream.match(r = Rules[next_rule])) { + if (r.regex && stream.match(r.regex)) { + state.next = r.next; + return r.token; + } else { + stream.next(); + return 'error'; + } + } + } + stream.next(); + return 'error'; + }; + var external = { + startState: function(){ + return { + next: 'start', + lastToken: {style: null, indent: 0, content: ""} + }; + }, + token: function(stream, state){ + while (stream.pos == stream.start) + var style = tokenBase(stream, state); + state.lastToken = { + style: style, + indent: stream.indentation(), + content: stream.current() + }; + return style.replace(/\./g, ' '); + }, + indent: function(state){ + var indentation = state.lastToken.indent; + if (state.lastToken.content.match(indenter)) { + indentation += 2; + } + return indentation; + } + }; + return external; + }); + + var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*'; + var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$'); + var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))'; + var stringfill = { + token: 'string', + regex: '.+' + }; + var Rules = { + start: [ + { + token: 'comment.doc', + regex: '/\\*', + next: 'comment' + }, { + token: 'comment', + regex: '#.*' + }, { + token: 'keyword', + regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend + }, { + token: 'constant.language', + regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend + }, { + token: 'invalid.illegal', + regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend + }, { + token: 'language.support.class', + regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend + }, { + token: 'language.support.function', + regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend + }, { + token: 'variable.language', + regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend + }, { + token: 'identifier', + regex: identifier + '\\s*:(?![:=])' + }, { + token: 'variable', + regex: identifier + }, { + token: 'keyword.operator', + regex: '(?:\\.{3}|\\s+\\?)' + }, { + token: 'keyword.variable', + regex: '(?:@+|::|\\.\\.)', + next: 'key' + }, { + token: 'keyword.operator', + regex: '\\.\\s*', + next: 'key' + }, { + token: 'string', + regex: '\\\\\\S[^\\s,;)}\\]]*' + }, { + token: 'string.doc', + regex: '\'\'\'', + next: 'qdoc' + }, { + token: 'string.doc', + regex: '"""', + next: 'qqdoc' + }, { + token: 'string', + regex: '\'', + next: 'qstring' + }, { + token: 'string', + regex: '"', + next: 'qqstring' + }, { + token: 'string', + regex: '`', + next: 'js' + }, { + token: 'string', + regex: '<\\[', + next: 'words' + }, { + token: 'string.regex', + regex: '//', + next: 'heregex' + }, { + token: 'string.regex', + regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}', + next: 'key' + }, { + token: 'constant.numeric', + regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)' + }, { + token: 'lparen', + regex: '[({[]' + }, { + token: 'rparen', + regex: '[)}\\]]', + next: 'key' + }, { + token: 'keyword.operator', + regex: '\\S+' + }, { + token: 'text', + regex: '\\s+' + } + ], + heregex: [ + { + token: 'string.regex', + regex: '.*?//[gimy$?]{0,4}', + next: 'start' + }, { + token: 'string.regex', + regex: '\\s*#{' + }, { + token: 'comment.regex', + regex: '\\s+(?:#.*)?' + }, { + token: 'string.regex', + regex: '\\S+' + } + ], + key: [ + { + token: 'keyword.operator', + regex: '[.?@!]+' + }, { + token: 'identifier', + regex: identifier, + next: 'start' + }, { + token: 'text', + regex: '', + next: 'start' + } + ], + comment: [ + { + token: 'comment.doc', + regex: '.*?\\*/', + next: 'start' + }, { + token: 'comment.doc', + regex: '.+' + } + ], + qdoc: [ + { + token: 'string', + regex: ".*?'''", + next: 'key' + }, stringfill + ], + qqdoc: [ + { + token: 'string', + regex: '.*?"""', + next: 'key' + }, stringfill + ], + qstring: [ + { + token: 'string', + regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'', + next: 'key' + }, stringfill + ], + qqstring: [ + { + token: 'string', + regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"', + next: 'key' + }, stringfill + ], + js: [ + { + token: 'string', + regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`', + next: 'key' + }, stringfill + ], + words: [ + { + token: 'string', + regex: '.*?\\]>', + next: 'key' + }, stringfill + ] + }; + for (var idx in Rules) { + var r = Rules[idx]; + if (r.splice) { + for (var i = 0, len = r.length; i < len; ++i) { + var rr = r[i]; + if (typeof rr.regex === 'string') { + Rules[idx][i].regex = new RegExp('^' + rr.regex); + } + } + } else if (typeof rr.regex === 'string') { + Rules[idx].regex = new RegExp('^' + r.regex); + } + } + + CodeMirror.defineMIME('text/x-livescript', 'livescript'); + +}); diff --git a/backend/webif/static/codemirror/mode/lua/index.html b/backend/webif/static/codemirror/mode/lua/index.html new file mode 100755 index 000000000..fc98b9446 --- /dev/null +++ b/backend/webif/static/codemirror/mode/lua/index.html @@ -0,0 +1,85 @@ + + +CodeMirror: Lua mode + + + + + + + + + + + +
+

Lua mode

+
+ + +

Loosely based on Franciszek + Wawrzak's CodeMirror + 1 mode. One configuration parameter is + supported, specials, to which you can provide an + array of strings to have those identifiers highlighted with + the lua-special style.

+

MIME types defined: text/x-lua.

+ +
diff --git a/backend/webif/static/codemirror/mode/lua/lua.js b/backend/webif/static/codemirror/mode/lua/lua.js new file mode 100755 index 000000000..0b19abd30 --- /dev/null +++ b/backend/webif/static/codemirror/mode/lua/lua.js @@ -0,0 +1,159 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's +// CodeMirror 1 mode. +// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("lua", function(config, parserConfig) { + var indentUnit = config.indentUnit; + + function prefixRE(words) { + return new RegExp("^(?:" + words.join("|") + ")", "i"); + } + function wordRE(words) { + return new RegExp("^(?:" + words.join("|") + ")$", "i"); + } + var specials = wordRE(parserConfig.specials || []); + + // long list of standard functions from lua manual + var builtins = wordRE([ + "_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load", + "loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require", + "select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall", + + "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield", + + "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable", + "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable", + "debug.setupvalue","debug.traceback", + + "close","flush","lines","read","seek","setvbuf","write", + + "io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin", + "io.stdout","io.tmpfile","io.type","io.write", + + "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg", + "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max", + "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh", + "math.sqrt","math.tan","math.tanh", + + "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale", + "os.time","os.tmpname", + + "package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload", + "package.seeall", + + "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub", + "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper", + + "table.concat","table.insert","table.maxn","table.remove","table.sort" + ]); + var keywords = wordRE(["and","break","elseif","false","nil","not","or","return", + "true","function", "end", "if", "then", "else", "do", + "while", "repeat", "until", "for", "in", "local" ]); + + var indentTokens = wordRE(["function", "if","repeat","do", "\\(", "{"]); + var dedentTokens = wordRE(["end", "until", "\\)", "}"]); + var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]); + + function readBracket(stream) { + var level = 0; + while (stream.eat("=")) ++level; + stream.eat("["); + return level; + } + + function normal(stream, state) { + var ch = stream.next(); + if (ch == "-" && stream.eat("-")) { + if (stream.eat("[") && stream.eat("[")) + return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state); + stream.skipToEnd(); + return "comment"; + } + if (ch == "\"" || ch == "'") + return (state.cur = string(ch))(stream, state); + if (ch == "[" && /[\[=]/.test(stream.peek())) + return (state.cur = bracketed(readBracket(stream), "string"))(stream, state); + if (/\d/.test(ch)) { + stream.eatWhile(/[\w.%]/); + return "number"; + } + if (/[\w_]/.test(ch)) { + stream.eatWhile(/[\w\\\-_.]/); + return "variable"; + } + return null; + } + + function bracketed(level, style) { + return function(stream, state) { + var curlev = null, ch; + while ((ch = stream.next()) != null) { + if (curlev == null) {if (ch == "]") curlev = 0;} + else if (ch == "=") ++curlev; + else if (ch == "]" && curlev == level) { state.cur = normal; break; } + else curlev = null; + } + return style; + }; + } + + function string(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) state.cur = normal; + return "string"; + }; + } + + return { + startState: function(basecol) { + return {basecol: basecol || 0, indentDepth: 0, cur: normal}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = state.cur(stream, state); + var word = stream.current(); + if (style == "variable") { + if (keywords.test(word)) style = "keyword"; + else if (builtins.test(word)) style = "builtin"; + else if (specials.test(word)) style = "variable-2"; + } + if ((style != "comment") && (style != "string")){ + if (indentTokens.test(word)) ++state.indentDepth; + else if (dedentTokens.test(word)) --state.indentDepth; + } + return style; + }, + + indent: function(state, textAfter) { + var closing = dedentPartial.test(textAfter); + return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0)); + }, + + lineComment: "--", + blockCommentStart: "--[[", + blockCommentEnd: "]]" + }; +}); + +CodeMirror.defineMIME("text/x-lua", "lua"); + +}); diff --git a/backend/webif/static/codemirror/mode/markdown/index.html b/backend/webif/static/codemirror/mode/markdown/index.html new file mode 100755 index 000000000..f17ecdc9a --- /dev/null +++ b/backend/webif/static/codemirror/mode/markdown/index.html @@ -0,0 +1,411 @@ + + +CodeMirror: Markdown mode + + + + + + + + + + + +
+

Markdown mode

+
+ + + +

If you also want support strikethrough, emoji and few other goodies, check out Github-Flavored Markdown mode.

+ +

Optionally depends on other modes for properly highlighted code blocks, + and XML mode for properly highlighted inline XML blocks.

+ +

Markdown mode supports these options:

+
    +
  • + +
    highlightFormatting: boolean
    +
    Whether to separately highlight markdown meta characterts (*[]()etc.) (default: false).
    +
    +
  • +
  • + +
    maxBlockquoteDepth: boolean
    +
    Maximum allowed blockquote nesting (default: 0 - infinite nesting).
    +
    +
  • +
  • + +
    xml: boolean
    +
    Whether to highlight inline XML (default: true).
    +
    +
  • +
  • + +
    fencedCodeBlockHighlighting: boolean
    +
    Whether to syntax-highlight fenced code blocks, if given mode is included (default: true).
    +
    +
  • +
  • + +
    tokenTypeOverrides: Object
    +
    When you want ot override default token type names (e.g. {code: "code"}).
    +
    +
  • +
  • + +
    allowAtxHeaderWithoutSpace: boolean
    +
    Allow lazy headers without whitespace between hashtag and text (default: false).
    +
    +
  • +
+ +

MIME types defined: text/x-markdown.

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/markdown/markdown.js b/backend/webif/static/codemirror/mode/markdown/markdown.js new file mode 100755 index 000000000..b2f79fc30 --- /dev/null +++ b/backend/webif/static/codemirror/mode/markdown/markdown.js @@ -0,0 +1,861 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../meta"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { + + var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); + var htmlModeMissing = htmlMode.name == "null" + + function getMode(name) { + if (CodeMirror.findModeByName) { + var found = CodeMirror.findModeByName(name); + if (found) name = found.mime || found.mimes[0]; + } + var mode = CodeMirror.getMode(cmCfg, name); + return mode.name == "null" ? null : mode; + } + + // Should characters that affect highlighting be highlighted separate? + // Does not include characters that will be output (such as `1.` and `-` for lists) + if (modeCfg.highlightFormatting === undefined) + modeCfg.highlightFormatting = false; + + // Maximum number of nested blockquotes. Set to 0 for infinite nesting. + // Excess `>` will emit `error` token. + if (modeCfg.maxBlockquoteDepth === undefined) + modeCfg.maxBlockquoteDepth = 0; + + // Turn on task lists? ("- [ ] " and "- [x] ") + if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; + + // Turn on strikethrough syntax + if (modeCfg.strikethrough === undefined) + modeCfg.strikethrough = false; + + if (modeCfg.emoji === undefined) + modeCfg.emoji = false; + + if (modeCfg.fencedCodeBlockHighlighting === undefined) + modeCfg.fencedCodeBlockHighlighting = true; + + if (modeCfg.xml === undefined) + modeCfg.xml = true; + + // Allow token types to be overridden by user-provided token types. + if (modeCfg.tokenTypeOverrides === undefined) + modeCfg.tokenTypeOverrides = {}; + + var tokenTypes = { + header: "header", + code: "comment", + quote: "quote", + list1: "variable-2", + list2: "variable-3", + list3: "keyword", + hr: "hr", + image: "image", + imageAltText: "image-alt-text", + imageMarker: "image-marker", + formatting: "formatting", + linkInline: "link", + linkEmail: "link", + linkText: "link", + linkHref: "string", + em: "em", + strong: "strong", + strikethrough: "strikethrough", + emoji: "builtin" + }; + + for (var tokenType in tokenTypes) { + if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { + tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; + } + } + + var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ + , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/ + , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE + , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ + , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/ + , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/ + , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/ + , linkDefRE = /^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/ // naive link-definition + , punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~—]/ + , expandedTab = " " // CommonMark specifies tab as 4 spaces + + function switchInline(stream, state, f) { + state.f = state.inline = f; + return f(stream, state); + } + + function switchBlock(stream, state, f) { + state.f = state.block = f; + return f(stream, state); + } + + function lineIsEmpty(line) { + return !line || !/\S/.test(line.string) + } + + // Blocks + + function blankLine(state) { + // Reset linkTitle state + state.linkTitle = false; + // Reset EM state + state.em = false; + // Reset STRONG state + state.strong = false; + // Reset strikethrough state + state.strikethrough = false; + // Reset state.quote + state.quote = 0; + // Reset state.indentedCode + state.indentedCode = false; + if (state.f == htmlBlock) { + state.f = inlineNormal; + state.block = blockNormal; + } + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + // Mark this line as blank + state.prevLine = state.thisLine + state.thisLine = {stream: null} + return null; + } + + function blockNormal(stream, state) { + var firstTokenOnLine = stream.column() === state.indentation; + var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream); + var prevLineIsIndentedCode = state.indentedCode; + var prevLineIsHr = state.prevLine.hr; + var prevLineIsList = state.list !== false; + var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3; + + state.indentedCode = false; + + var lineIndentation = state.indentation; + // compute once per line (on first token) + if (state.indentationDiff === null) { + state.indentationDiff = state.indentation; + if (prevLineIsList) { + state.list = null; + // While this list item's marker's indentation is less than the deepest + // list item's content's indentation,pop the deepest list item + // indentation off the stack, and update block indentation state + while (lineIndentation < state.listStack[state.listStack.length - 1]) { + state.listStack.pop(); + if (state.listStack.length) { + state.indentation = state.listStack[state.listStack.length - 1]; + // less than the first list's indent -> the line is no longer a list + } else { + state.list = false; + } + } + if (state.list !== false) { + state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1] + } + } + } + + // not comprehensive (currently only for setext detection purposes) + var allowsInlineContinuation = ( + !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header && + (!prevLineIsList || !prevLineIsIndentedCode) && + !state.prevLine.fencedCodeEnd + ); + + var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) && + state.indentation <= maxNonCodeIndentation && stream.match(hrRE); + + var match = null; + if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd || + state.prevLine.header || prevLineLineIsEmpty)) { + stream.skipToEnd(); + state.indentedCode = true; + return tokenTypes.code; + } else if (stream.eatSpace()) { + return null; + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) { + state.quote = 0; + state.header = match[1].length; + state.thisLine.header = true; + if (modeCfg.highlightFormatting) state.formatting = "header"; + state.f = state.inline; + return getType(state); + } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) { + state.quote = firstTokenOnLine ? 1 : state.quote + 1; + if (modeCfg.highlightFormatting) state.formatting = "quote"; + stream.eatSpace(); + return getType(state); + } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) { + var listType = match[1] ? "ol" : "ul"; + + state.indentation = lineIndentation + stream.current().length; + state.list = true; + state.quote = 0; + + // Add this list item's content's indentation to the stack + state.listStack.push(state.indentation); + + if (modeCfg.taskLists && stream.match(taskListRE, false)) { + state.taskList = true; + } + state.f = state.inline; + if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; + return getType(state); + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) { + state.quote = 0; + state.fencedEndRE = new RegExp(match[1] + "+ *$"); + // try switching mode + state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]); + if (state.localMode) state.localState = CodeMirror.startState(state.localMode); + state.f = state.block = local; + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + state.code = -1 + return getType(state); + // SETEXT has lowest block-scope precedence after HR, so check it after + // the others (code, blockquote, list...) + } else if ( + // if setext set, indicates line after ---/=== + state.setext || ( + // line before ---/=== + (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false && + !state.code && !isHr && !linkDefRE.test(stream.string) && + (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE)) + ) + ) { + if ( !state.setext ) { + state.header = match[0].charAt(0) == '=' ? 1 : 2; + state.setext = state.header; + } else { + state.header = state.setext; + // has no effect on type so we can reset it now + state.setext = 0; + stream.skipToEnd(); + if (modeCfg.highlightFormatting) state.formatting = "header"; + } + state.thisLine.header = true; + state.f = state.inline; + return getType(state); + } else if (isHr) { + stream.skipToEnd(); + state.hr = true; + state.thisLine.hr = true; + return tokenTypes.hr; + } else if (stream.peek() === '[') { + return switchInline(stream, state, footnoteLink); + } + + return switchInline(stream, state, state.inline); + } + + function htmlBlock(stream, state) { + var style = htmlMode.token(stream, state.htmlState); + if (!htmlModeMissing) { + var inner = CodeMirror.innerMode(htmlMode, state.htmlState) + if ((inner.mode.name == "xml" && inner.state.tagStart === null && + (!inner.state.context && inner.state.tokenize.isInText)) || + (state.md_inside && stream.current().indexOf(">") > -1)) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + return style; + } + + function local(stream, state) { + var currListInd = state.listStack[state.listStack.length - 1] || 0; + var hasExitedList = state.indentation < currListInd; + var maxFencedEndInd = currListInd + 3; + if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) { + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + var returnType; + if (!hasExitedList) returnType = getType(state) + state.localMode = state.localState = null; + state.block = blockNormal; + state.f = inlineNormal; + state.fencedEndRE = null; + state.code = 0 + state.thisLine.fencedCodeEnd = true; + if (hasExitedList) return switchBlock(stream, state, state.block); + return returnType; + } else if (state.localMode) { + return state.localMode.token(stream, state.localState); + } else { + stream.skipToEnd(); + return tokenTypes.code; + } + } + + // Inline + function getType(state) { + var styles = []; + + if (state.formatting) { + styles.push(tokenTypes.formatting); + + if (typeof state.formatting === "string") state.formatting = [state.formatting]; + + for (var i = 0; i < state.formatting.length; i++) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i]); + + if (state.formatting[i] === "header") { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); + } + + // Add `formatting-quote` and `formatting-quote-#` for blockquotes + // Add `error` instead if the maximum blockquote nesting depth is passed + if (state.formatting[i] === "quote") { + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); + } else { + styles.push("error"); + } + } + } + } + + if (state.taskOpen) { + styles.push("meta"); + return styles.length ? styles.join(' ') : null; + } + if (state.taskClosed) { + styles.push("property"); + return styles.length ? styles.join(' ') : null; + } + + if (state.linkHref) { + styles.push(tokenTypes.linkHref, "url"); + } else { // Only apply inline styles to non-url text + if (state.strong) { styles.push(tokenTypes.strong); } + if (state.em) { styles.push(tokenTypes.em); } + if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } + if (state.emoji) { styles.push(tokenTypes.emoji); } + if (state.linkText) { styles.push(tokenTypes.linkText); } + if (state.code) { styles.push(tokenTypes.code); } + if (state.image) { styles.push(tokenTypes.image); } + if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); } + if (state.imageMarker) { styles.push(tokenTypes.imageMarker); } + } + + if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } + + if (state.quote) { + styles.push(tokenTypes.quote); + + // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.quote + "-" + state.quote); + } else { + styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); + } + } + + if (state.list !== false) { + var listMod = (state.listStack.length - 1) % 3; + if (!listMod) { + styles.push(tokenTypes.list1); + } else if (listMod === 1) { + styles.push(tokenTypes.list2); + } else { + styles.push(tokenTypes.list3); + } + } + + if (state.trailingSpaceNewLine) { + styles.push("trailing-space-new-line"); + } else if (state.trailingSpace) { + styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); + } + + return styles.length ? styles.join(' ') : null; + } + + function handleText(stream, state) { + if (stream.match(textRE, true)) { + return getType(state); + } + return undefined; + } + + function inlineNormal(stream, state) { + var style = state.text(stream, state); + if (typeof style !== 'undefined') + return style; + + if (state.list) { // List marker (*, +, -, 1., etc) + state.list = null; + return getType(state); + } + + if (state.taskList) { + var taskOpen = stream.match(taskListRE, true)[1] === " "; + if (taskOpen) state.taskOpen = true; + else state.taskClosed = true; + if (modeCfg.highlightFormatting) state.formatting = "task"; + state.taskList = false; + return getType(state); + } + + state.taskOpen = false; + state.taskClosed = false; + + if (state.header && stream.match(/^#+$/, true)) { + if (modeCfg.highlightFormatting) state.formatting = "header"; + return getType(state); + } + + var ch = stream.next(); + + // Matches link titles present on next line + if (state.linkTitle) { + state.linkTitle = false; + var matchCh = ch; + if (ch === '(') { + matchCh = ')'; + } + matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1"); + var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; + if (stream.match(new RegExp(regex), true)) { + return tokenTypes.linkHref; + } + } + + // If this block is changed, it may need to be updated in GFM mode + if (ch === '`') { + var previousFormatting = state.formatting; + if (modeCfg.highlightFormatting) state.formatting = "code"; + stream.eatWhile('`'); + var count = stream.current().length + if (state.code == 0 && (!state.quote || count == 1)) { + state.code = count + return getType(state) + } else if (count == state.code) { // Must be exact + var t = getType(state) + state.code = 0 + return t + } else { + state.formatting = previousFormatting + return getType(state) + } + } else if (state.code) { + return getType(state); + } + + if (ch === '\\') { + stream.next(); + if (modeCfg.highlightFormatting) { + var type = getType(state); + var formattingEscape = tokenTypes.formatting + "-escape"; + return type ? type + " " + formattingEscape : formattingEscape; + } + } + + if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { + state.imageMarker = true; + state.image = true; + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) { + state.imageMarker = false; + state.imageAltText = true + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === ']' && state.imageAltText) { + if (modeCfg.highlightFormatting) state.formatting = "image"; + var type = getType(state); + state.imageAltText = false; + state.image = false; + state.inline = state.f = linkHref; + return type; + } + + if (ch === '[' && !state.image) { + state.linkText = true; + if (modeCfg.highlightFormatting) state.formatting = "link"; + return getType(state); + } + + if (ch === ']' && state.linkText) { + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + state.linkText = false; + state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal + return type; + } + + if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkEmail; + } + + if (modeCfg.xml && ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) { + var end = stream.string.indexOf(">", stream.pos); + if (end != -1) { + var atts = stream.string.substring(stream.start, end); + if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; + } + stream.backUp(1); + state.htmlState = CodeMirror.startState(htmlMode); + return switchBlock(stream, state, htmlBlock); + } + + if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) { + state.md_inside = false; + return "tag"; + } else if (ch === "*" || ch === "_") { + var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2) + while (len < 3 && stream.eat(ch)) len++ + var after = stream.peek() || " " + // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis + var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before)) + var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after)) + var setEm = null, setStrong = null + if (len % 2) { // Em + if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) + setEm = true + else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) + setEm = false + } + if (len > 1) { // Strong + if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) + setStrong = true + else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) + setStrong = false + } + if (setStrong != null || setEm != null) { + if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em" + if (setEm === true) state.em = ch + if (setStrong === true) state.strong = ch + var t = getType(state) + if (setEm === false) state.em = false + if (setStrong === false) state.strong = false + return t + } + } else if (ch === ' ') { + if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(1); + } + } + } + + if (modeCfg.strikethrough) { + if (ch === '~' && stream.eatWhile(ch)) { + if (state.strikethrough) {// Remove strikethrough + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + var t = getType(state); + state.strikethrough = false; + return t; + } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough + state.strikethrough = true; + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.match(/^~~/, true)) { // Probably surrounded by space + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(2); + } + } + } + } + + if (modeCfg.emoji && ch === ":" && stream.match(/^[a-z_\d+-]+:/)) { + state.emoji = true; + if (modeCfg.highlightFormatting) state.formatting = "emoji"; + var retType = getType(state); + state.emoji = false; + return retType; + } + + if (ch === ' ') { + if (stream.match(/ +$/, false)) { + state.trailingSpace++; + } else if (state.trailingSpace) { + state.trailingSpaceNewLine = true; + } + } + + return getType(state); + } + + function linkInline(stream, state) { + var ch = stream.next(); + + if (ch === ">") { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + stream.match(/^[^>]+/, true); + + return tokenTypes.linkInline; + } + + function linkHref(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + var ch = stream.next(); + if (ch === '(' || ch === '[') { + state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + state.linkHref = true; + return getType(state); + } + return 'error'; + } + + var linkRE = { + ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, + "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/ + } + + function getLinkHrefInside(endChar) { + return function(stream, state) { + var ch = stream.next(); + + if (ch === endChar) { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + var returnState = getType(state); + state.linkHref = false; + return returnState; + } + + stream.match(linkRE[endChar]) + state.linkHref = true; + return getType(state); + }; + } + + function footnoteLink(stream, state) { + if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { + state.f = footnoteLinkInside; + stream.next(); // Consume [ + if (modeCfg.highlightFormatting) state.formatting = "link"; + state.linkText = true; + return getType(state); + } + return switchInline(stream, state, inlineNormal); + } + + function footnoteLinkInside(stream, state) { + if (stream.match(/^\]:/, true)) { + state.f = state.inline = footnoteUrl; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var returnType = getType(state); + state.linkText = false; + return returnType; + } + + stream.match(/^([^\]\\]|\\.)+/, true); + + return tokenTypes.linkText; + } + + function footnoteUrl(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + // Match URL + stream.match(/^[^\s]+/, true); + // Check for link title + if (stream.peek() === undefined) { // End of line, set flag to check next line + state.linkTitle = true; + } else { // More content on line, check if link title + stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); + } + state.f = state.inline = inlineNormal; + return tokenTypes.linkHref + " url"; + } + + var mode = { + startState: function() { + return { + f: blockNormal, + + prevLine: {stream: null}, + thisLine: {stream: null}, + + block: blockNormal, + htmlState: null, + indentation: 0, + + inline: inlineNormal, + text: handleText, + + formatting: false, + linkText: false, + linkHref: false, + linkTitle: false, + code: 0, + em: false, + strong: false, + header: 0, + setext: 0, + hr: false, + taskList: false, + list: false, + listStack: [], + quote: 0, + trailingSpace: 0, + trailingSpaceNewLine: false, + strikethrough: false, + emoji: false, + fencedEndRE: null + }; + }, + + copyState: function(s) { + return { + f: s.f, + + prevLine: s.prevLine, + thisLine: s.thisLine, + + block: s.block, + htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), + indentation: s.indentation, + + localMode: s.localMode, + localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, + + inline: s.inline, + text: s.text, + formatting: false, + linkText: s.linkText, + linkTitle: s.linkTitle, + code: s.code, + em: s.em, + strong: s.strong, + strikethrough: s.strikethrough, + emoji: s.emoji, + header: s.header, + setext: s.setext, + hr: s.hr, + taskList: s.taskList, + list: s.list, + listStack: s.listStack.slice(0), + quote: s.quote, + indentedCode: s.indentedCode, + trailingSpace: s.trailingSpace, + trailingSpaceNewLine: s.trailingSpaceNewLine, + md_inside: s.md_inside, + fencedEndRE: s.fencedEndRE + }; + }, + + token: function(stream, state) { + + // Reset state.formatting + state.formatting = false; + + if (stream != state.thisLine.stream) { + state.header = 0; + state.hr = false; + + if (stream.match(/^\s*$/, true)) { + blankLine(state); + return null; + } + + state.prevLine = state.thisLine + state.thisLine = {stream: stream} + + // Reset state.taskList + state.taskList = false; + + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + + if (!state.localState) { + state.f = state.block; + if (state.f != htmlBlock) { + var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length; + state.indentation = indentation; + state.indentationDiff = null; + if (indentation > 0) return null; + } + } + } + return state.f(stream, state); + }, + + innerMode: function(state) { + if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; + if (state.localState) return {state: state.localState, mode: state.localMode}; + return {state: state, mode: mode}; + }, + + indent: function(state, textAfter, line) { + if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line) + if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line) + return CodeMirror.Pass + }, + + blankLine: blankLine, + + getType: getType, + + closeBrackets: "()[]{}''\"\"``", + fold: "markdown" + }; + return mode; +}, "xml"); + +CodeMirror.defineMIME("text/x-markdown", "markdown"); + +}); diff --git a/backend/webif/static/codemirror/mode/markdown/test.js b/backend/webif/static/codemirror/mode/markdown/test.js new file mode 100755 index 000000000..a89fbca60 --- /dev/null +++ b/backend/webif/static/codemirror/mode/markdown/test.js @@ -0,0 +1,1289 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var config = {tabSize: 4, indentUnit: 2} + var mode = CodeMirror.getMode(config, "markdown"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + var modeHighlightFormatting = CodeMirror.getMode(config, {name: "markdown", highlightFormatting: true}); + function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); } + var modeMT_noXml = CodeMirror.getMode(config, {name: "markdown", xml: false}); + function MT_noXml(name) { test.mode(name, modeMT_noXml, Array.prototype.slice.call(arguments, 1)); } + var modeMT_noFencedHighlight = CodeMirror.getMode(config, {name: "markdown", fencedCodeBlockHighlighting: false}); + function MT_noFencedHighlight(name) { test.mode(name, modeMT_noFencedHighlight, Array.prototype.slice.call(arguments, 1)); } + var modeAtxNoSpace = CodeMirror.getMode(config, {name: "markdown", allowAtxHeaderWithoutSpace: true}); + function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); } + var modeOverrideClasses = CodeMirror.getMode(config, { + name: "markdown", + strikethrough: true, + emoji: true, + tokenTypeOverrides: { + "header" : "override-header", + "code" : "override-code", + "quote" : "override-quote", + "list1" : "override-list1", + "list2" : "override-list2", + "list3" : "override-list3", + "hr" : "override-hr", + "image" : "override-image", + "imageAltText": "override-image-alt-text", + "imageMarker": "override-image-marker", + "linkInline" : "override-link-inline", + "linkEmail" : "override-link-email", + "linkText" : "override-link-text", + "linkHref" : "override-link-href", + "em" : "override-em", + "strong" : "override-strong", + "strikethrough" : "override-strikethrough", + "emoji" : "override-emoji" + }}); + function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); } + var modeFormattingOverride = CodeMirror.getMode(config, { + name: "markdown", + highlightFormatting: true, + tokenTypeOverrides: { + "formatting" : "override-formatting" + }}); + function FormatTokenTypeOverrideTest(name) { test.mode(name, modeFormattingOverride, Array.prototype.slice.call(arguments, 1)); } + + + FT("formatting_emAsterisk", + "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]"); + + FT("formatting_emUnderscore", + "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]"); + + FT("formatting_strongAsterisk", + "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]"); + + FT("formatting_strongUnderscore", + "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]"); + + FT("formatting_codeBackticks", + "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]"); + + FT("formatting_doubleBackticks", + "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]"); + + FT("formatting_atxHeader", + "[header&header-1&formatting&formatting-header&formatting-header-1 # ][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]"); + + FT("formatting_setextHeader", + "[header&header-1 foo]", + "[header&header-1&formatting&formatting-header&formatting-header-1 =]"); + + FT("formatting_blockquote", + "[quote"e-1&formatting&formatting-quote&formatting-quote-1 > ][quote"e-1 foo]"); + + FT("formatting_list", + "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]"); + FT("formatting_list", + "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]"); + + FT("formatting_link", + "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url (][string&url http://example.com/][string&formatting&formatting-link-string&url )]"); + + FT("formatting_linkReference", + "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url [][string&url bar][string&formatting&formatting-link-string&url ]]]", + "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string&url http://example.com/]"); + + FT("formatting_linkWeb", + "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]"); + + FT("formatting_linkEmail", + "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]"); + + FT("formatting_escape", + "[formatting-escape \\*]"); + + FT("formatting_image", + "[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]"); + + FT("codeBlock", + "[comment&formatting&formatting-code-block ```css]", + "[tag foo]", + "[comment&formatting&formatting-code-block ```]"); + + MT("plainText", + "foo"); + + // Don't style single trailing space + MT("trailingSpace1", + "foo "); + + // Two or more trailing spaces should be styled with line break character + MT("trailingSpace2", + "foo[trailing-space-a ][trailing-space-new-line ]"); + + MT("trailingSpace3", + "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]"); + + MT("trailingSpace4", + "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]"); + + // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value) + MT("codeBlocksUsing4Spaces", + " [comment foo]"); + + // Code blocks using 4 spaces with internal indentation + MT("codeBlocksUsing4SpacesIndentation", + " [comment bar]", + " [comment hello]", + " [comment world]", + " [comment foo]", + "bar"); + + // Code blocks should end even after extra indented lines + MT("codeBlocksWithTrailingIndentedLine", + " [comment foo]", + " [comment bar]", + " [comment baz]", + " ", + "hello"); + + // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value) + MT("codeBlocksUsing1Tab", + "\t[comment foo]"); + + // No code blocks directly after paragraph + // http://spec.commonmark.org/0.19/#example-65 + MT("noCodeBlocksAfterParagraph", + "Foo", + " Bar"); + + MT("codeBlocksAfterATX", + "[header&header-1 # foo]", + " [comment code]"); + + MT("codeBlocksAfterSetext", + "[header&header-2 foo]", + "[header&header-2 ---]", + " [comment code]"); + + MT("codeBlocksAfterFencedCode", + "[comment ```]", + "[comment foo]", + "[comment ```]", + " [comment code]"); + + // Inline code using backticks + MT("inlineCodeUsingBackticks", + "foo [comment `bar`]"); + + // Block code using single backtick (shouldn't work) + MT("blockCodeSingleBacktick", + "[comment `]", + "[comment foo]", + "[comment `]"); + + // Unclosed backticks + // Instead of simply marking as CODE, it would be nice to have an + // incomplete flag for CODE, that is styled slightly different. + MT("unclosedBackticks", + "foo [comment `bar]"); + + // Per documentation: "To include a literal backtick character within a + // code span, you can use multiple backticks as the opening and closing + // delimiters" + MT("doubleBackticks", + "[comment ``foo ` bar``]"); + + // Tests based on Dingus + // http://daringfireball.net/projects/markdown/dingus + // + // Multiple backticks within an inline code block + MT("consecutiveBackticks", + "[comment `foo```bar`]"); + + // Multiple backticks within an inline code block with a second code block + MT("consecutiveBackticks", + "[comment `foo```bar`] hello [comment `world`]"); + + // Unclosed with several different groups of backticks + MT("unclosedBackticks", + "[comment ``foo ``` bar` hello]"); + + // Closed with several different groups of backticks + MT("closedBackticks", + "[comment ``foo ``` bar` hello``] world"); + + // info string cannot contain backtick, thus should result in inline code + MT("closingFencedMarksOnSameLine", + "[comment ``` code ```] foo"); + + // atx headers + // http://daringfireball.net/projects/markdown/syntax#header + + MT("atxH1", + "[header&header-1 # foo]"); + + MT("atxH2", + "[header&header-2 ## foo]"); + + MT("atxH3", + "[header&header-3 ### foo]"); + + MT("atxH4", + "[header&header-4 #### foo]"); + + MT("atxH5", + "[header&header-5 ##### foo]"); + + MT("atxH6", + "[header&header-6 ###### foo]"); + + // http://spec.commonmark.org/0.19/#example-24 + MT("noAtxH7", + "####### foo"); + + // http://spec.commonmark.org/0.19/#example-25 + MT("noAtxH1WithoutSpace", + "#5 bolt"); + + // CommonMark requires a space after # but most parsers don't + AtxNoSpaceTest("atxNoSpaceAllowed_H1NoSpace", + "[header&header-1 #foo]"); + + AtxNoSpaceTest("atxNoSpaceAllowed_H4NoSpace", + "[header&header-4 ####foo]"); + + AtxNoSpaceTest("atxNoSpaceAllowed_H1Space", + "[header&header-1 # foo]"); + + // Inline styles should be parsed inside headers + MT("atxH1inline", + "[header&header-1 # foo ][header&header-1&em *bar*]"); + + MT("atxIndentedTooMuch", + "[header&header-1 # foo]", + " [comment # bar]"); + + // disable atx inside blockquote until we implement proper blockquote inner mode + // TODO: fix to be CommonMark-compliant + MT("atxNestedInsideBlockquote", + "[quote"e-1 > # foo]"); + + MT("atxAfterBlockquote", + "[quote"e-1 > foo]", + "[header&header-1 # bar]"); + + // Setext headers - H1, H2 + // Per documentation, "Any number of underlining =’s or -’s will work." + // http://daringfireball.net/projects/markdown/syntax#header + // Ideally, the text would be marked as `header` as well, but this is + // not really feasible at the moment. So, instead, we're testing against + // what works today, to avoid any regressions. + // + // Check if single underlining = works + MT("setextH1", + "[header&header-1 foo]", + "[header&header-1 =]"); + + // Check if 3+ ='s work + MT("setextH1", + "[header&header-1 foo]", + "[header&header-1 ===]"); + + // Check if single underlining - works + MT("setextH2", + "[header&header-2 foo]", + "[header&header-2 -]"); + + // Check if 3+ -'s work + MT("setextH2", + "[header&header-2 foo]", + "[header&header-2 ---]"); + + // http://spec.commonmark.org/0.19/#example-45 + MT("setextH2AllowSpaces", + "[header&header-2 foo]", + " [header&header-2 ---- ]"); + + // http://spec.commonmark.org/0.19/#example-44 + MT("noSetextAfterIndentedCodeBlock", + " [comment foo]", + "[hr ---]"); + + MT("setextAfterFencedCode", + "[comment ```]", + "[comment foo]", + "[comment ```]", + "[header&header-2 bar]", + "[header&header-2 ---]"); + + MT("setextAferATX", + "[header&header-1 # foo]", + "[header&header-2 bar]", + "[header&header-2 ---]"); + + // http://spec.commonmark.org/0.19/#example-51 + MT("noSetextAfterQuote", + "[quote"e-1 > foo]", + "[hr ---]", + "", + "[quote"e-1 > foo]", + "[quote"e-1 bar]", + "[hr ---]"); + + MT("noSetextAfterList", + "[variable-2 - foo]", + "[hr ---]"); + + MT("noSetextAfterList_listContinuation", + "[variable-2 - foo]", + "bar", + "[hr ---]"); + + MT("setextAfterList_afterIndentedCode", + "[variable-2 - foo]", + "", + " [comment bar]", + "[header&header-2 baz]", + "[header&header-2 ---]"); + + MT("setextAfterList_afterFencedCodeBlocks", + "[variable-2 - foo]", + "", + " [comment ```]", + " [comment bar]", + " [comment ```]", + "[header&header-2 baz]", + "[header&header-2 ---]"); + + MT("setextAfterList_afterHeader", + "[variable-2 - foo]", + " [variable-2&header&header-1 # bar]", + "[header&header-2 baz]", + "[header&header-2 ---]"); + + MT("setextAfterList_afterHr", + "[variable-2 - foo]", + "", + " [hr ---]", + "[header&header-2 bar]", + "[header&header-2 ---]"); + + MT("setext_nestedInlineMarkup", + "[header&header-1 foo ][em&header&header-1 *bar*]", + "[header&header-1 =]"); + + MT("setext_linkDef", + "[link [[aaa]]:] [string&url http://google.com 'title']", + "[hr ---]"); + + // currently, looks max one line ahead, thus won't catch valid CommonMark + // markup + MT("setext_oneLineLookahead", + "foo", + "[header&header-1 bar]", + "[header&header-1 =]"); + + // ensure we don't regard space after dash as a list + MT("setext_emptyList", + "[header&header-2 foo]", + "[header&header-2 - ]", + "foo"); + + // Single-line blockquote with trailing space + MT("blockquoteSpace", + "[quote"e-1 > foo]"); + + // Single-line blockquote + MT("blockquoteNoSpace", + "[quote"e-1 >foo]"); + + // No blank line before blockquote + MT("blockquoteNoBlankLine", + "foo", + "[quote"e-1 > bar]"); + + MT("blockquoteNested", + "[quote"e-1 > foo]", + "[quote"e-1 >][quote"e-2 > foo]", + "[quote"e-1 >][quote"e-2 >][quote"e-3 > foo]"); + + // ensure quote-level is inferred correctly even if indented + MT("blockquoteNestedIndented", + " [quote"e-1 > foo]", + " [quote"e-1 >][quote"e-2 > foo]", + " [quote"e-1 >][quote"e-2 >][quote"e-3 > foo]"); + + // ensure quote-level is inferred correctly even if indented + MT("blockquoteIndentedTooMuch", + "foo", + " > bar"); + + // Single-line blockquote followed by normal paragraph + MT("blockquoteThenParagraph", + "[quote"e-1 >foo]", + "", + "bar"); + + // Multi-line blockquote (lazy mode) + MT("multiBlockquoteLazy", + "[quote"e-1 >foo]", + "[quote"e-1 bar]"); + + // Multi-line blockquote followed by normal paragraph (lazy mode) + MT("multiBlockquoteLazyThenParagraph", + "[quote"e-1 >foo]", + "[quote"e-1 bar]", + "", + "hello"); + + // Multi-line blockquote (non-lazy mode) + MT("multiBlockquote", + "[quote"e-1 >foo]", + "[quote"e-1 >bar]"); + + // Multi-line blockquote followed by normal paragraph (non-lazy mode) + MT("multiBlockquoteThenParagraph", + "[quote"e-1 >foo]", + "[quote"e-1 >bar]", + "", + "hello"); + + // disallow lists inside blockquote for now because it causes problems outside blockquote + // TODO: fix to be CommonMark-compliant + MT("listNestedInBlockquote", + "[quote"e-1 > - foo]"); + + // disallow fenced blocks inside blockquote because it causes problems outside blockquote + // TODO: fix to be CommonMark-compliant + MT("fencedBlockNestedInBlockquote", + "[quote"e-1 > ```]", + "[quote"e-1 > code]", + "[quote"e-1 > ```]", + // ensure we still allow inline code + "[quote"e-1 > ][quote"e-1&comment `code`]"); + + // Header with leading space after continued blockquote (#3287, negative indentation) + MT("headerAfterContinuedBlockquote", + "[quote"e-1 > foo]", + "[quote"e-1 bar]", + "", + " [header&header-1 # hello]"); + + // Check list types + + MT("listAsterisk", + "foo", + "bar", + "", + "[variable-2 * foo]", + "[variable-2 * bar]"); + + MT("listPlus", + "foo", + "bar", + "", + "[variable-2 + foo]", + "[variable-2 + bar]"); + + MT("listDash", + "foo", + "bar", + "", + "[variable-2 - foo]", + "[variable-2 - bar]"); + + MT("listNumber", + "foo", + "bar", + "", + "[variable-2 1. foo]", + "[variable-2 2. bar]"); + + MT("listFromParagraph", + "foo", + "[variable-2 1. bar]", + "[variable-2 2. hello]"); + + // List after hr + MT("listAfterHr", + "[hr ---]", + "[variable-2 - bar]"); + + // List after header + MT("listAfterHeader", + "[header&header-1 # foo]", + "[variable-2 - bar]"); + + // hr after list + MT("hrAfterList", + "[variable-2 - foo]", + "[hr -----]"); + + MT("hrAfterFencedCode", + "[comment ```]", + "[comment code]", + "[comment ```]", + "[hr ---]"); + + // allow hr inside lists + // (require prev line to be empty or hr, TODO: non-CommonMark-compliant) + MT("hrInsideList", + "[variable-2 - foo]", + "", + " [hr ---]", + " [hr ---]", + "", + " [comment ---]"); + + MT("consecutiveHr", + "[hr ---]", + "[hr ---]", + "[hr ---]"); + + // Formatting in lists (*) + MT("listAsteriskFormatting", + "[variable-2 * ][variable-2&em *foo*][variable-2 bar]", + "[variable-2 * ][variable-2&strong **foo**][variable-2 bar]", + "[variable-2 * ][variable-2&em&strong ***foo***][variable-2 bar]", + "[variable-2 * ][variable-2&comment `foo`][variable-2 bar]"); + + // Formatting in lists (+) + MT("listPlusFormatting", + "[variable-2 + ][variable-2&em *foo*][variable-2 bar]", + "[variable-2 + ][variable-2&strong **foo**][variable-2 bar]", + "[variable-2 + ][variable-2&em&strong ***foo***][variable-2 bar]", + "[variable-2 + ][variable-2&comment `foo`][variable-2 bar]"); + + // Formatting in lists (-) + MT("listDashFormatting", + "[variable-2 - ][variable-2&em *foo*][variable-2 bar]", + "[variable-2 - ][variable-2&strong **foo**][variable-2 bar]", + "[variable-2 - ][variable-2&em&strong ***foo***][variable-2 bar]", + "[variable-2 - ][variable-2&comment `foo`][variable-2 bar]"); + + // Formatting in lists (1.) + MT("listNumberFormatting", + "[variable-2 1. ][variable-2&em *foo*][variable-2 bar]", + "[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]", + "[variable-2 3. ][variable-2&em&strong ***foo***][variable-2 bar]", + "[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]"); + + // Paragraph lists + MT("listParagraph", + "[variable-2 * foo]", + "", + "[variable-2 * bar]"); + + // Multi-paragraph lists + // + // 4 spaces + MT("listMultiParagraph", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + " [variable-2 hello]"); + + // 4 spaces, extra blank lines (should still be list, per Dingus) + MT("listMultiParagraphExtra", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + "", + " [variable-2 hello]"); + + // 4 spaces, plus 1 space (should still be list, per Dingus) + MT("listMultiParagraphExtraSpace", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + " [variable-2 hello]", + "", + " [variable-2 world]"); + + // 1 tab + MT("listTab", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + "\t[variable-2 hello]"); + + // No indent + MT("listNoIndent", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + "hello"); + + MT("listCommonMarkIndentationCode", + "[variable-2 * Code blocks also affect]", + " [variable-3 * The next level starts where the contents start.]", + " [variable-3 * Anything less than that will keep the item on the same level.]", + " [variable-3 * Each list item can indent the first level further and further.]", + " [variable-3 * For the most part, this makes sense while writing a list.]", + " [keyword * This means two items with same indentation can be different levels.]", + " [keyword * Each level has an indent requirement that can change between items.]", + " [keyword * A list item that meets this will be part of the next level.]", + " [variable-3 * Otherwise, it will be part of the level where it does meet this.]", + " [variable-2 * World]"); + + // should handle nested and un-nested lists + MT("listCommonMark_MixedIndents", + "[variable-2 * list1]", + " [variable-2 list1]", + " [variable-2&header&header-1 # heading still part of list1]", + " [variable-2 text after heading still part of list1]", + "", + " [comment indented codeblock]", + " [variable-2 list1 after code block]", + " [variable-3 * list2]", + // amount of spaces on empty lines between lists doesn't matter + " ", + // extra empty lines irrelevant + "", + "", + " [variable-3 indented text part of list2]", + " [keyword * list3]", + "", + " [variable-3 text at level of list2]", + "", + " [variable-2 de-indented text part of list1 again]", + "", + " [variable-2&comment ```]", + " [comment code]", + " [variable-2&comment ```]", + "", + " [variable-2 text after fenced code]"); + + // should correctly parse numbered list content indentation + MT("listCommonMark_NumeberedListIndent", + "[variable-2 1000. list with base indent of 6]", + "", + " [variable-2 text must be indented 6 spaces at minimum]", + "", + " [variable-2 9-spaces indented text still part of list]", + "", + " [comment indented codeblock starts at 10 spaces]", + "", + " [comment text indented by 5 spaces no longer belong to list]"); + + // should consider tab as 4 spaces + MT("listCommonMark_TabIndented", + "[variable-2 * list]", + "\t[variable-3 * list2]", + "", + "\t\t[variable-3 part of list2]"); + + MT("listAfterBlockquote", + "[quote"e-1 > foo]", + "[variable-2 - bar]"); + + // shouldn't create sublist if it's indented more than allowed + MT("nestedListIndentedTooMuch", + "[variable-2 - foo]", + " [variable-2 - bar]"); + + MT("listIndentedTooMuchAfterParagraph", + "foo", + " - bar"); + + // Blockquote + MT("blockquote", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + " [variable-2"e"e-1 > hello]"); + + // Code block + MT("blockquoteCode", + "[variable-2 * foo]", + "", + "[variable-2 * bar]", + "", + " [comment > hello]", + "", + " [variable-2 world]"); + + // Code block followed by text + MT("blockquoteCodeText", + "[variable-2 * foo]", + "", + " [variable-2 bar]", + "", + " [comment hello]", + "", + " [variable-2 world]"); + + // Nested list + + MT("listAsteriskNested", + "[variable-2 * foo]", + "", + " [variable-3 * bar]"); + + MT("listPlusNested", + "[variable-2 + foo]", + "", + " [variable-3 + bar]"); + + MT("listDashNested", + "[variable-2 - foo]", + "", + " [variable-3 - bar]"); + + MT("listNumberNested", + "[variable-2 1. foo]", + "", + " [variable-3 2. bar]"); + + MT("listMixed", + "[variable-2 * foo]", + "", + " [variable-3 + bar]", + "", + " [keyword - hello]", + "", + " [variable-2 1. world]"); + + MT("listBlockquote", + "[variable-2 * foo]", + "", + " [variable-3 + bar]", + "", + " [quote"e-1&variable-3 > hello]"); + + MT("listCode", + "[variable-2 * foo]", + "", + " [variable-3 + bar]", + "", + " [comment hello]"); + + // Code with internal indentation + MT("listCodeIndentation", + "[variable-2 * foo]", + "", + " [comment bar]", + " [comment hello]", + " [comment world]", + " [comment foo]", + " [variable-2 bar]"); + + // List nesting edge cases + MT("listNested", + "[variable-2 * foo]", + "", + " [variable-3 * bar]", + "", + " [variable-3 hello]" + ); + MT("listNested", + "[variable-2 * foo]", + "", + " [variable-3 * bar]", + "", + " [keyword * foo]" + ); + + // Code followed by text + MT("listCodeText", + "[variable-2 * foo]", + "", + " [comment bar]", + "", + "hello"); + + // Following tests directly from official Markdown documentation + // http://daringfireball.net/projects/markdown/syntax#hr + + MT("hrSpace", + "[hr * * *]"); + + MT("hr", + "[hr ***]"); + + MT("hrLong", + "[hr *****]"); + + MT("hrSpaceDash", + "[hr - - -]"); + + MT("hrDashLong", + "[hr ---------------------------------------]"); + + //Images + MT("Images", + "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)]") + + //Images with highlight alt text + MT("imageEm", + "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&em&image&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); + + MT("imageStrong", + "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); + + MT("imageEmStrong", + "[image&image-marker !][image&image-alt-text&link [[][image&image-alt-text&em&strong&link ***alt text***][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]"); + + // Inline link with title + MT("linkTitle", + "[link [[foo]]][string&url (http://example.com/ \"bar\")] hello"); + + // Inline link without title + MT("linkNoTitle", + "[link [[foo]]][string&url (http://example.com/)] bar"); + + // Inline link with image + MT("linkImage", + "[link [[][link&image&image-marker !][link&image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)][link ]]][string&url (http://example.com/)] bar"); + + // Inline link with Em + MT("linkEm", + "[link [[][link&em *foo*][link ]]][string&url (http://example.com/)] bar"); + + // Inline link with Strong + MT("linkStrong", + "[link [[][link&strong **foo**][link ]]][string&url (http://example.com/)] bar"); + + // Inline link with EmStrong + MT("linkEmStrong", + "[link [[][link&em&strong ***foo***][link ]]][string&url (http://example.com/)] bar"); + + MT("multilineLink", + "[link [[foo]", + "[link bar]]][string&url (https://foo#_a)]", + "should not be italics") + + // Image with title + MT("imageTitle", + "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/ \"bar\")] hello"); + + // Image without title + MT("imageNoTitle", + "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/)] bar"); + + // Image with asterisks + MT("imageAsterisks", + "[image&image-marker !][image&image-alt-text&link [[ ][image&image-alt-text&em&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)] bar"); + + // Not a link. Should be normal text due to square brackets being used + // regularly in text, especially in quoted material, and no space is allowed + // between square brackets and parentheses (per Dingus). + MT("notALink", + "[link [[foo]]] (bar)"); + + // Reference-style links + MT("linkReference", + "[link [[foo]]][string&url [[bar]]] hello"); + + // Reference-style links with Em + MT("linkReferenceEm", + "[link [[][link&em *foo*][link ]]][string&url [[bar]]] hello"); + + // Reference-style links with Strong + MT("linkReferenceStrong", + "[link [[][link&strong **foo**][link ]]][string&url [[bar]]] hello"); + + // Reference-style links with EmStrong + MT("linkReferenceEmStrong", + "[link [[][link&em&strong ***foo***][link ]]][string&url [[bar]]] hello"); + + // Reference-style links with optional space separator (per documentation) + // "You can optionally use a space to separate the sets of brackets" + MT("linkReferenceSpace", + "[link [[foo]]] [string&url [[bar]]] hello"); + + // Should only allow a single space ("...use *a* space...") + MT("linkReferenceDoubleSpace", + "[link [[foo]]] [link [[bar]]] hello"); + + // Reference-style links with implicit link name + MT("linkImplicit", + "[link [[foo]]][string&url [[]]] hello"); + + // @todo It would be nice if, at some point, the document was actually + // checked to see if the referenced link exists + + // Link label, for reference-style links (taken from documentation) + + MT("labelNoTitle", + "[link [[foo]]:] [string&url http://example.com/]"); + + MT("labelIndented", + " [link [[foo]]:] [string&url http://example.com/]"); + + MT("labelSpaceTitle", + "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"]"); + + MT("labelDoubleTitle", + "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"] \"world\""); + + MT("labelTitleDoubleQuotes", + "[link [[foo]]:] [string&url http://example.com/ \"bar\"]"); + + MT("labelTitleSingleQuotes", + "[link [[foo]]:] [string&url http://example.com/ 'bar']"); + + MT("labelTitleParentheses", + "[link [[foo]]:] [string&url http://example.com/ (bar)]"); + + MT("labelTitleInvalid", + "[link [[foo]]:] [string&url http://example.com/] bar"); + + MT("labelLinkAngleBrackets", + "[link [[foo]]:] [string&url \"bar\"]"); + + MT("labelTitleNextDoubleQuotes", + "[link [[foo]]:] [string&url http://example.com/]", + "[string \"bar\"] hello"); + + MT("labelTitleNextSingleQuotes", + "[link [[foo]]:] [string&url http://example.com/]", + "[string 'bar'] hello"); + + MT("labelTitleNextParentheses", + "[link [[foo]]:] [string&url http://example.com/]", + "[string (bar)] hello"); + + MT("labelTitleNextMixed", + "[link [[foo]]:] [string&url http://example.com/]", + "(bar\" hello"); + + MT("labelEscape", + "[link [[foo \\]] ]]:] [string&url http://example.com/]"); + + MT("labelEscapeColon", + "[link [[foo \\]]: bar]]:] [string&url http://example.com/]"); + + MT("labelEscapeEnd", + "\\[[foo\\]]: http://example.com/"); + + MT("linkWeb", + "[link ] foo"); + + MT("linkWebDouble", + "[link ] foo [link ]"); + + MT("linkEmail", + "[link ] foo"); + + MT("linkEmailDouble", + "[link ] foo [link ]"); + + MT("emAsterisk", + "[em *foo*] bar"); + + MT("emUnderscore", + "[em _foo_] bar"); + + MT("emInWordAsterisk", + "foo[em *bar*]hello"); + + MT("emInWordUnderscore", + "foo_bar_hello"); + + // Per documentation: "...surround an * or _ with spaces, it’ll be + // treated as a literal asterisk or underscore." + + MT("emEscapedBySpaceIn", + "foo [em _bar _ hello_] world"); + + MT("emEscapedBySpaceOut", + "foo _ bar [em _hello_] world"); + + MT("emEscapedByNewline", + "foo", + "_ bar [em _hello_] world"); + + // Unclosed emphasis characters + // Instead of simply marking as EM / STRONG, it would be nice to have an + // incomplete flag for EM and STRONG, that is styled slightly different. + MT("emIncompleteAsterisk", + "foo [em *bar]"); + + MT("emIncompleteUnderscore", + "foo [em _bar]"); + + MT("strongAsterisk", + "[strong **foo**] bar"); + + MT("strongUnderscore", + "[strong __foo__] bar"); + + MT("emStrongAsterisk", + "[em *foo][em&strong **bar*][strong hello**] world"); + + MT("emStrongUnderscore", + "[em _foo ][em&strong __bar_][strong hello__] world"); + + // "...same character must be used to open and close an emphasis span."" + MT("emStrongMixed", + "[em _foo][em&strong **bar*hello__ world]"); + + MT("emStrongMixed", + "[em *foo ][em&strong __bar_hello** world]"); + + MT("linkWithNestedParens", + "[link [[foo]]][string&url (bar(baz))]") + + // These characters should be escaped: + // \ backslash + // ` backtick + // * asterisk + // _ underscore + // {} curly braces + // [] square brackets + // () parentheses + // # hash mark + // + plus sign + // - minus sign (hyphen) + // . dot + // ! exclamation mark + + MT("escapeBacktick", + "foo \\`bar\\`"); + + MT("doubleEscapeBacktick", + "foo \\\\[comment `bar\\\\`]"); + + MT("escapeAsterisk", + "foo \\*bar\\*"); + + MT("doubleEscapeAsterisk", + "foo \\\\[em *bar\\\\*]"); + + MT("escapeUnderscore", + "foo \\_bar\\_"); + + MT("doubleEscapeUnderscore", + "foo \\\\[em _bar\\\\_]"); + + MT("escapeHash", + "\\# foo"); + + MT("doubleEscapeHash", + "\\\\# foo"); + + MT("escapeNewline", + "\\", + "[em *foo*]"); + + // Class override tests + TokenTypeOverrideTest("overrideHeader1", + "[override-header&override-header-1 # Foo]"); + + TokenTypeOverrideTest("overrideHeader2", + "[override-header&override-header-2 ## Foo]"); + + TokenTypeOverrideTest("overrideHeader3", + "[override-header&override-header-3 ### Foo]"); + + TokenTypeOverrideTest("overrideHeader4", + "[override-header&override-header-4 #### Foo]"); + + TokenTypeOverrideTest("overrideHeader5", + "[override-header&override-header-5 ##### Foo]"); + + TokenTypeOverrideTest("overrideHeader6", + "[override-header&override-header-6 ###### Foo]"); + + TokenTypeOverrideTest("overrideCode", + "[override-code `foo`]"); + + TokenTypeOverrideTest("overrideCodeBlock", + "[override-code ```]", + "[override-code foo]", + "[override-code ```]"); + + TokenTypeOverrideTest("overrideQuote", + "[override-quote&override-quote-1 > foo]", + "[override-quote&override-quote-1 > bar]"); + + TokenTypeOverrideTest("overrideQuoteNested", + "[override-quote&override-quote-1 > foo]", + "[override-quote&override-quote-1 >][override-quote&override-quote-2 > bar]", + "[override-quote&override-quote-1 >][override-quote&override-quote-2 >][override-quote&override-quote-3 > baz]"); + + TokenTypeOverrideTest("overrideLists", + "[override-list1 - foo]", + "", + " [override-list2 + bar]", + "", + " [override-list3 * baz]", + "", + " [override-list1 1. qux]", + "", + " [override-list2 - quux]"); + + TokenTypeOverrideTest("overrideHr", + "[override-hr * * *]"); + + TokenTypeOverrideTest("overrideImage", + "[override-image&override-image-marker !][override-image&override-image-alt-text&link [[alt text]]][override-link-href&url (http://link.to/image.jpg)]"); + + TokenTypeOverrideTest("overrideLinkText", + "[override-link-text [[foo]]][override-link-href&url (http://example.com)]"); + + TokenTypeOverrideTest("overrideLinkEmailAndInline", + "[override-link-email <][override-link-inline foo@example.com>]"); + + TokenTypeOverrideTest("overrideEm", + "[override-em *foo*]"); + + TokenTypeOverrideTest("overrideStrong", + "[override-strong **foo**]"); + + TokenTypeOverrideTest("overrideStrikethrough", + "[override-strikethrough ~~foo~~]"); + + TokenTypeOverrideTest("overrideEmoji", + "[override-emoji :foo:]"); + + FormatTokenTypeOverrideTest("overrideFormatting", + "[override-formatting-escape \\*]"); + + // Tests to make sure GFM-specific things aren't getting through + + MT("taskList", + "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]"); + + MT("fencedCodeBlocks", + "[comment ```]", + "[comment foo]", + "", + "[comment bar]", + "[comment ```]", + "baz"); + + MT("fencedCodeBlocks_invalidClosingFence_trailingText", + "[comment ```]", + "[comment foo]", + "[comment ``` must not have trailing text]", + "[comment baz]"); + + MT("fencedCodeBlocks_invalidClosingFence_trailingTabs", + "[comment ```]", + "[comment foo]", + "[comment ```\t]", + "[comment baz]"); + + MT("fencedCodeBlocks_validClosingFence", + "[comment ```]", + "[comment foo]", + // may have trailing spaces + "[comment ``` ]", + "baz"); + + MT("fencedCodeBlocksInList_closingFenceIndented", + "[variable-2 - list]", + " [variable-2&comment ```]", + " [comment foo]", + " [variable-2&comment ```]", + " [variable-2 baz]"); + + MT("fencedCodeBlocksInList_closingFenceIndentedTooMuch", + "[variable-2 - list]", + " [variable-2&comment ```]", + " [comment foo]", + " [comment ```]", + " [comment baz]"); + + MT("fencedCodeBlockModeSwitching", + "[comment ```javascript]", + "[variable foo]", + "", + "[comment ```]", + "bar"); + + MT_noFencedHighlight("fencedCodeBlock_noHighlight", + "[comment ```javascript]", + "[comment foo]", + "[comment ```]"); + + MT("fencedCodeBlockModeSwitchingObjc", + "[comment ```objective-c]", + "[keyword @property] [variable NSString] [operator *] [variable foo];", + "[comment ```]", + "bar"); + + MT("fencedCodeBlocksMultipleChars", + "[comment `````]", + "[comment foo]", + "[comment ```]", + "[comment foo]", + "[comment `````]", + "bar"); + + MT("fencedCodeBlocksTildes", + "[comment ~~~]", + "[comment foo]", + "[comment ~~~]", + "bar"); + + MT("fencedCodeBlocksTildesMultipleChars", + "[comment ~~~~~]", + "[comment ~~~]", + "[comment foo]", + "[comment ~~~~~]", + "bar"); + + MT("fencedCodeBlocksMultipleChars", + "[comment `````]", + "[comment foo]", + "[comment ```]", + "[comment foo]", + "[comment `````]", + "bar"); + + MT("fencedCodeBlocksMixed", + "[comment ~~~]", + "[comment ```]", + "[comment foo]", + "[comment ~~~]", + "bar"); + + MT("fencedCodeBlocksAfterBlockquote", + "[quote"e-1 > foo]", + "[comment ```]", + "[comment bar]", + "[comment ```]"); + + // fencedCode indented too much should act as simple indentedCode + // (hence has no highlight formatting) + FT("tooMuchIndentedFencedCode", + " [comment ```]", + " [comment code]", + " [comment ```]"); + + MT("autoTerminateFencedCodeWhenLeavingList", + "[variable-2 - list1]", + " [variable-3 - list2]", + " [variable-3&comment ```]", + " [comment code]", + " [variable-3 - list2]", + " [variable-2&comment ```]", + " [comment code]", + "[quote"e-1 > foo]"); + + // Tests that require XML mode + + MT("xmlMode", + "[tag&bracket <][tag div][tag&bracket >]", + " *foo*", + " [tag&bracket <][tag http://github.com][tag&bracket />]", + "[tag&bracket ]", + "[link ]"); + + MT("xmlModeWithMarkdownInside", + "[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]", + "[em *foo*]", + "[link ]", + "[tag ]", + "[link ]", + "[tag&bracket <][tag div][tag&bracket >]", + "[tag&bracket ]"); + + MT_noXml("xmlHighlightDisabled", + "
foo
"); + +})(); diff --git a/backend/webif/static/codemirror/mode/mathematica/index.html b/backend/webif/static/codemirror/mode/mathematica/index.html new file mode 100755 index 000000000..57c429853 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mathematica/index.html @@ -0,0 +1,72 @@ + + +CodeMirror: Mathematica mode + + + + + + + + + + +
+

Mathematica mode

+ + + + + + +

MIME types defined: text/x-mathematica (Mathematica).

+
diff --git a/backend/webif/static/codemirror/mode/mathematica/mathematica.js b/backend/webif/static/codemirror/mode/mathematica/mathematica.js new file mode 100755 index 000000000..d6977088c --- /dev/null +++ b/backend/webif/static/codemirror/mode/mathematica/mathematica.js @@ -0,0 +1,176 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Mathematica mode copyright (c) 2015 by Calin Barbat +// Based on code by Patrick Scheibe (halirutan) +// See: https://github.com/halirutan/Mathematica-Source-Highlighting/tree/master/src/lang-mma.js + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('mathematica', function(_config, _parserConfig) { + + // used pattern building blocks + var Identifier = '[a-zA-Z\\$][a-zA-Z0-9\\$]*'; + var pBase = "(?:\\d+)"; + var pFloat = "(?:\\.\\d+|\\d+\\.\\d*|\\d+)"; + var pFloatBase = "(?:\\.\\w+|\\w+\\.\\w*|\\w+)"; + var pPrecision = "(?:`(?:`?"+pFloat+")?)"; + + // regular expressions + var reBaseForm = new RegExp('(?:'+pBase+'(?:\\^\\^'+pFloatBase+pPrecision+'?(?:\\*\\^[+-]?\\d+)?))'); + var reFloatForm = new RegExp('(?:' + pFloat + pPrecision + '?(?:\\*\\^[+-]?\\d+)?)'); + var reIdInContext = new RegExp('(?:`?)(?:' + Identifier + ')(?:`(?:' + Identifier + '))*(?:`?)'); + + function tokenBase(stream, state) { + var ch; + + // get next character + ch = stream.next(); + + // string + if (ch === '"') { + state.tokenize = tokenString; + return state.tokenize(stream, state); + } + + // comment + if (ch === '(') { + if (stream.eat('*')) { + state.commentLevel++; + state.tokenize = tokenComment; + return state.tokenize(stream, state); + } + } + + // go back one character + stream.backUp(1); + + // look for numbers + // Numbers in a baseform + if (stream.match(reBaseForm, true, false)) { + return 'number'; + } + + // Mathematica numbers. Floats (1.2, .2, 1.) can have optionally a precision (`float) or an accuracy definition + // (``float). Note: while 1.2` is possible 1.2`` is not. At the end an exponent (float*^+12) can follow. + if (stream.match(reFloatForm, true, false)) { + return 'number'; + } + + /* In[23] and Out[34] */ + if (stream.match(/(?:In|Out)\[[0-9]*\]/, true, false)) { + return 'atom'; + } + + // usage + if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::usage)/, true, false)) { + return 'meta'; + } + + // message + if (stream.match(/([a-zA-Z\$]+(?:`?[a-zA-Z0-9\$])*::[a-zA-Z\$][a-zA-Z0-9\$]*):?/, true, false)) { + return 'string-2'; + } + + // this makes a look-ahead match for something like variable:{_Integer} + // the match is then forwarded to the mma-patterns tokenizer. + if (stream.match(/([a-zA-Z\$][a-zA-Z0-9\$]*\s*:)(?:(?:[a-zA-Z\$][a-zA-Z0-9\$]*)|(?:[^:=>~@\^\&\*\)\[\]'\?,\|])).*/, true, false)) { + return 'variable-2'; + } + + // catch variables which are used together with Blank (_), BlankSequence (__) or BlankNullSequence (___) + // Cannot start with a number, but can have numbers at any other position. Examples + // blub__Integer, a1_, b34_Integer32 + if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) { + return 'variable-2'; + } + if (stream.match(/[a-zA-Z\$][a-zA-Z0-9\$]*_+/, true, false)) { + return 'variable-2'; + } + if (stream.match(/_+[a-zA-Z\$][a-zA-Z0-9\$]*/, true, false)) { + return 'variable-2'; + } + + // Named characters in Mathematica, like \[Gamma]. + if (stream.match(/\\\[[a-zA-Z\$][a-zA-Z0-9\$]*\]/, true, false)) { + return 'variable-3'; + } + + // Match all braces separately + if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) { + return 'bracket'; + } + + // Catch Slots (#, ##, #3, ##9 and the V10 named slots #name). I have never seen someone using more than one digit after #, so we match + // only one. + if (stream.match(/(?:#[a-zA-Z\$][a-zA-Z0-9\$]*|#+[0-9]?)/, true, false)) { + return 'variable-2'; + } + + // Literals like variables, keywords, functions + if (stream.match(reIdInContext, true, false)) { + return 'keyword'; + } + + // operators. Note that operators like @@ or /; are matched separately for each symbol. + if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) { + return 'operator'; + } + + // everything else is an error + stream.next(); // advance the stream. + return 'error'; + } + + function tokenString(stream, state) { + var next, end = false, escaped = false; + while ((next = stream.next()) != null) { + if (next === '"' && !escaped) { + end = true; + break; + } + escaped = !escaped && next === '\\'; + } + if (end && !escaped) { + state.tokenize = tokenBase; + } + return 'string'; + }; + + function tokenComment(stream, state) { + var prev, next; + while(state.commentLevel > 0 && (next = stream.next()) != null) { + if (prev === '(' && next === '*') state.commentLevel++; + if (prev === '*' && next === ')') state.commentLevel--; + prev = next; + } + if (state.commentLevel <= 0) { + state.tokenize = tokenBase; + } + return 'comment'; + } + + return { + startState: function() {return {tokenize: tokenBase, commentLevel: 0};}, + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + }, + blockCommentStart: "(*", + blockCommentEnd: "*)" + }; +}); + +CodeMirror.defineMIME('text/x-mathematica', { + name: 'mathematica' +}); + +}); diff --git a/backend/webif/static/codemirror/mode/mbox/index.html b/backend/webif/static/codemirror/mode/mbox/index.html new file mode 100755 index 000000000..248ea98e1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mbox/index.html @@ -0,0 +1,44 @@ + + +CodeMirror: mbox mode + + + + + + + + + +
+

mbox mode

+
+ + +

MIME types defined: application/mbox.

+ +
diff --git a/backend/webif/static/codemirror/mode/mbox/mbox.js b/backend/webif/static/codemirror/mode/mbox/mbox.js new file mode 100755 index 000000000..ba2416ac8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mbox/mbox.js @@ -0,0 +1,129 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +var rfc2822 = [ + "From", "Sender", "Reply-To", "To", "Cc", "Bcc", "Message-ID", + "In-Reply-To", "References", "Resent-From", "Resent-Sender", "Resent-To", + "Resent-Cc", "Resent-Bcc", "Resent-Message-ID", "Return-Path", "Received" +]; +var rfc2822NoEmail = [ + "Date", "Subject", "Comments", "Keywords", "Resent-Date" +]; + +CodeMirror.registerHelper("hintWords", "mbox", rfc2822.concat(rfc2822NoEmail)); + +var whitespace = /^[ \t]/; +var separator = /^From /; // See RFC 4155 +var rfc2822Header = new RegExp("^(" + rfc2822.join("|") + "): "); +var rfc2822HeaderNoEmail = new RegExp("^(" + rfc2822NoEmail.join("|") + "): "); +var header = /^[^:]+:/; // Optional fields defined in RFC 2822 +var email = /^[^ ]+@[^ ]+/; +var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/; +var bracketedEmail = /^<.*?>/; +var untilBracketedEmail = /^.*?(?=<.*>)/; + +function styleForHeader(header) { + if (header === "Subject") return "header"; + return "string"; +} + +function readToken(stream, state) { + if (stream.sol()) { + // From last line + state.inSeparator = false; + if (state.inHeader && stream.match(whitespace)) { + // Header folding + return null; + } else { + state.inHeader = false; + state.header = null; + } + + if (stream.match(separator)) { + state.inHeaders = true; + state.inSeparator = true; + return "atom"; + } + + var match; + var emailPermitted = false; + if ((match = stream.match(rfc2822HeaderNoEmail)) || + (emailPermitted = true) && (match = stream.match(rfc2822Header))) { + state.inHeaders = true; + state.inHeader = true; + state.emailPermitted = emailPermitted; + state.header = match[1]; + return "atom"; + } + + // Use vim's heuristics: recognize custom headers only if the line is in a + // block of legitimate headers. + if (state.inHeaders && (match = stream.match(header))) { + state.inHeader = true; + state.emailPermitted = true; + state.header = match[1]; + return "atom"; + } + + state.inHeaders = false; + stream.skipToEnd(); + return null; + } + + if (state.inSeparator) { + if (stream.match(email)) return "link"; + if (stream.match(untilEmail)) return "atom"; + stream.skipToEnd(); + return "atom"; + } + + if (state.inHeader) { + var style = styleForHeader(state.header); + + if (state.emailPermitted) { + if (stream.match(bracketedEmail)) return style + " link"; + if (stream.match(untilBracketedEmail)) return style; + } + stream.skipToEnd(); + return style; + } + + stream.skipToEnd(); + return null; +}; + +CodeMirror.defineMode("mbox", function() { + return { + startState: function() { + return { + // Is in a mbox separator + inSeparator: false, + // Is in a mail header + inHeader: false, + // If bracketed email is permitted. Only applicable when inHeader + emailPermitted: false, + // Name of current header + header: null, + // Is in a region of mail headers + inHeaders: false + }; + }, + token: readToken, + blankLine: function(state) { + state.inHeaders = state.inSeparator = state.inHeader = false; + } + }; +}); + +CodeMirror.defineMIME("application/mbox", "mbox"); +}); diff --git a/backend/webif/static/codemirror/mode/meta.js b/backend/webif/static/codemirror/mode/meta.js new file mode 100755 index 000000000..34da269f3 --- /dev/null +++ b/backend/webif/static/codemirror/mode/meta.js @@ -0,0 +1,216 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.modeInfo = [ + {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]}, + {name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]}, + {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]}, + {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i}, + {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]}, + {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]}, + {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]}, + {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]}, + {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]}, + {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]}, + {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]}, + {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]}, + {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/}, + {name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]}, + {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]}, + {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]}, + {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]}, + {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]}, + {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]}, + {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]}, + {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]}, + {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]}, + {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]}, + {name: "Django", mime: "text/x-django", mode: "django"}, + {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/}, + {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]}, + {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]}, + {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"}, + {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]}, + {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]}, + {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]}, + {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]}, + {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, + {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, + {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, + {name: "Esper", mime: "text/x-esper", mode: "sql"}, + {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]}, + {name: "FCL", mime: "text/x-fcl", mode: "fcl"}, + {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, + {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]}, + {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, + {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, + {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]}, + {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i}, + {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]}, + {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/}, + {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]}, + {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]}, + {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]}, + {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]}, + {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]}, + {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]}, + {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]}, + {name: "HTTP", mime: "message/http", mode: "http"}, + {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]}, + {name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]}, + {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]}, + {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]}, + {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"], + mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]}, + {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]}, + {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]}, + {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]}, + {name: "Jinja2", mime: "null", mode: "jinja2"}, + {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]}, + {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]}, + {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]}, + {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]}, + {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]}, + {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]}, + {name: "mIRC", mime: "text/mirc", mode: "mirc"}, + {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"}, + {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]}, + {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]}, + {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]}, + {name: "MS SQL", mime: "text/x-mssql", mode: "sql"}, + {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]}, + {name: "MySQL", mime: "text/x-mysql", mode: "sql"}, + {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i}, + {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]}, + {name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"], + mode: "ntriples", ext: ["nt", "nq"]}, + {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]}, + {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]}, + {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]}, + {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]}, + {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]}, + {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]}, + {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]}, + {name: "PHP", mime: ["application/x-httpd-php", "text/x-php"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]}, + {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]}, + {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]}, + {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]}, + {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]}, + {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]}, + {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]}, + {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/}, + {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]}, + {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]}, + {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]}, + {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]}, + {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"}, + {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]}, + {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]}, + {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]}, + {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]}, + {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]}, + {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]}, + {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]}, + {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]}, + {name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/}, + {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]}, + {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]}, + {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]}, + {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]}, + {name: "Solr", mime: "text/x-solr", mode: "solr"}, + {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]}, + {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]}, + {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]}, + {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]}, + {name: "SQLite", mime: "text/x-sqlite", mode: "sql"}, + {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]}, + {name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]}, + {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]}, + {name: "sTeX", mime: "text/x-stex", mode: "stex"}, + {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]}, + {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]}, + {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]}, + {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]}, + {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"}, + {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"}, + {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]}, + {name: "Tornado", mime: "text/x-tornado", mode: "tornado"}, + {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]}, + {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]}, + {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]}, + {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]}, + {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]}, + {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]}, + {name: "Twig", mime: "text/x-twig", mode: "twig"}, + {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]}, + {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]}, + {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]}, + {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]}, + {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]}, + {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]}, + {name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]}, + {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]}, + {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]}, + {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]}, + {name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]}, + {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}, + {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]}, + {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]}, + {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]} + ]; + // Ensure all modes have a mime property for backwards compatibility + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mimes) info.mime = info.mimes[0]; + } + + CodeMirror.findModeByMIME = function(mime) { + mime = mime.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mime == mime) return info; + if (info.mimes) for (var j = 0; j < info.mimes.length; j++) + if (info.mimes[j] == mime) return info; + } + if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml") + if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json") + }; + + CodeMirror.findModeByExtension = function(ext) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.ext) for (var j = 0; j < info.ext.length; j++) + if (info.ext[j] == ext) return info; + } + }; + + CodeMirror.findModeByFileName = function(filename) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.file && info.file.test(filename)) return info; + } + var dot = filename.lastIndexOf("."); + var ext = dot > -1 && filename.substring(dot + 1, filename.length); + if (ext) return CodeMirror.findModeByExtension(ext); + }; + + CodeMirror.findModeByName = function(name) { + name = name.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.name.toLowerCase() == name) return info; + if (info.alias) for (var j = 0; j < info.alias.length; j++) + if (info.alias[j].toLowerCase() == name) return info; + } + }; +}); diff --git a/backend/webif/static/codemirror/mode/mirc/index.html b/backend/webif/static/codemirror/mode/mirc/index.html new file mode 100755 index 000000000..fd2f34e4b --- /dev/null +++ b/backend/webif/static/codemirror/mode/mirc/index.html @@ -0,0 +1,160 @@ + + +CodeMirror: mIRC mode + + + + + + + + + + +
+

mIRC mode

+
+ + +

MIME types defined: text/mirc.

+ +
diff --git a/backend/webif/static/codemirror/mode/mirc/mirc.js b/backend/webif/static/codemirror/mode/mirc/mirc.js new file mode 100755 index 000000000..71ac4ddfd --- /dev/null +++ b/backend/webif/static/codemirror/mode/mirc/mirc.js @@ -0,0 +1,193 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +//mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMIME("text/mirc", "mirc"); +CodeMirror.defineMode("mirc", function() { + function parseWords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var specials = parseWords("$! $$ $& $? $+ $abook $abs $active $activecid " + + "$activewid $address $addtok $agent $agentname $agentstat $agentver " + + "$alias $and $anick $ansi2mirc $aop $appactive $appstate $asc $asctime " + + "$asin $atan $avoice $away $awaymsg $awaytime $banmask $base $bfind " + + "$binoff $biton $bnick $bvar $bytes $calc $cb $cd $ceil $chan $chanmodes " + + "$chantypes $chat $chr $cid $clevel $click $cmdbox $cmdline $cnick $color " + + "$com $comcall $comchan $comerr $compact $compress $comval $cos $count " + + "$cr $crc $creq $crlf $ctime $ctimer $ctrlenter $date $day $daylight " + + "$dbuh $dbuw $dccignore $dccport $dde $ddename $debug $decode $decompress " + + "$deltok $devent $dialog $did $didreg $didtok $didwm $disk $dlevel $dll " + + "$dllcall $dname $dns $duration $ebeeps $editbox $emailaddr $encode $error " + + "$eval $event $exist $feof $ferr $fgetc $file $filename $filtered $finddir " + + "$finddirn $findfile $findfilen $findtok $fline $floor $fopen $fread $fserve " + + "$fulladdress $fulldate $fullname $fullscreen $get $getdir $getdot $gettok $gmt " + + "$group $halted $hash $height $hfind $hget $highlight $hnick $hotline " + + "$hotlinepos $ial $ialchan $ibl $idle $iel $ifmatch $ignore $iif $iil " + + "$inelipse $ini $inmidi $inpaste $inpoly $input $inrect $inroundrect " + + "$insong $instok $int $inwave $ip $isalias $isbit $isdde $isdir $isfile " + + "$isid $islower $istok $isupper $keychar $keyrpt $keyval $knick $lactive " + + "$lactivecid $lactivewid $left $len $level $lf $line $lines $link $lock " + + "$lock $locked $log $logstamp $logstampfmt $longfn $longip $lower $ltimer " + + "$maddress $mask $matchkey $matchtok $md5 $me $menu $menubar $menucontext " + + "$menutype $mid $middir $mircdir $mircexe $mircini $mklogfn $mnick $mode " + + "$modefirst $modelast $modespl $mouse $msfile $network $newnick $nick $nofile " + + "$nopath $noqt $not $notags $notify $null $numeric $numok $oline $onpoly " + + "$opnick $or $ord $os $passivedcc $pic $play $pnick $port $portable $portfree " + + "$pos $prefix $prop $protect $puttok $qt $query $rand $r $rawmsg $read $readomo " + + "$readn $regex $regml $regsub $regsubex $remove $remtok $replace $replacex " + + "$reptok $result $rgb $right $round $scid $scon $script $scriptdir $scriptline " + + "$sdir $send $server $serverip $sfile $sha1 $shortfn $show $signal $sin " + + "$site $sline $snick $snicks $snotify $sock $sockbr $sockerr $sockname " + + "$sorttok $sound $sqrt $ssl $sreq $sslready $status $strip $str $stripped " + + "$syle $submenu $switchbar $tan $target $ticks $time $timer $timestamp " + + "$timestampfmt $timezone $tip $titlebar $toolbar $treebar $trust $ulevel " + + "$ulist $upper $uptime $url $usermode $v1 $v2 $var $vcmd $vcmdstat $vcmdver " + + "$version $vnick $vol $wid $width $wildsite $wildtok $window $wrap $xor"); + var keywords = parseWords("abook ajinvite alias aline ame amsg anick aop auser autojoin avoice " + + "away background ban bcopy beep bread break breplace bset btrunc bunset bwrite " + + "channel clear clearall cline clipboard close cnick color comclose comopen " + + "comreg continue copy creq ctcpreply ctcps dcc dccserver dde ddeserver " + + "debug dec describe dialog did didtok disable disconnect dlevel dline dll " + + "dns dqwindow drawcopy drawdot drawfill drawline drawpic drawrect drawreplace " + + "drawrot drawsave drawscroll drawtext ebeeps echo editbox emailaddr enable " + + "events exit fclose filter findtext finger firewall flash flist flood flush " + + "flushini font fopen fseek fsend fserve fullname fwrite ghide gload gmove " + + "gopts goto gplay gpoint gqreq groups gshow gsize gstop gtalk gunload hadd " + + "halt haltdef hdec hdel help hfree hinc hload hmake hop hsave ial ialclear " + + "ialmark identd if ignore iline inc invite iuser join kick linesep links list " + + "load loadbuf localinfo log mdi me menubar mkdir mnick mode msg nick noop notice " + + "notify omsg onotice part partall pdcc perform play playctrl pop protect pvoice " + + "qme qmsg query queryn quit raw reload remini remote remove rename renwin " + + "reseterror resetidle return rlevel rline rmdir run ruser save savebuf saveini " + + "say scid scon server set showmirc signam sline sockaccept sockclose socklist " + + "socklisten sockmark sockopen sockpause sockread sockrename sockudp sockwrite " + + "sound speak splay sreq strip switchbar timer timestamp titlebar tnick tokenize " + + "toolbar topic tray treebar ulist unload unset unsetall updatenl url uwho " + + "var vcadd vcmd vcrem vol while whois window winhelp write writeint if isalnum " + + "isalpha isaop isavoice isban ischan ishop isignore isin isincs isletter islower " + + "isnotify isnum ison isop isprotect isreg isupper isvoice iswm iswmcs " + + "elseif else goto menu nicklist status title icon size option text edit " + + "button check radio box scroll list combo link tab item"); + var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch"); + var isOperatorChar = /[+\-*&%=<>!?^\/\|]/; + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + function tokenBase(stream, state) { + var beforeParams = state.beforeParams; + state.beforeParams = false; + var ch = stream.next(); + if (/[\[\]{}\(\),\.]/.test(ch)) { + if (ch == "(" && beforeParams) state.inParams = true; + else if (ch == ")") state.inParams = false; + return null; + } + else if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + else if (ch == "\\") { + stream.eat("\\"); + stream.eat(/./); + return "number"; + } + else if (ch == "/" && stream.eat("*")) { + return chain(stream, state, tokenComment); + } + else if (ch == ";" && stream.match(/ *\( *\(/)) { + return chain(stream, state, tokenUnparsed); + } + else if (ch == ";" && !state.inParams) { + stream.skipToEnd(); + return "comment"; + } + else if (ch == '"') { + stream.eat(/"/); + return "keyword"; + } + else if (ch == "$") { + stream.eatWhile(/[$_a-z0-9A-Z\.:]/); + if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) { + return "keyword"; + } + else { + state.beforeParams = true; + return "builtin"; + } + } + else if (ch == "%") { + stream.eatWhile(/[^,\s()]/); + state.beforeParams = true; + return "string"; + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + else { + stream.eatWhile(/[\w\$_{}]/); + var word = stream.current().toLowerCase(); + if (keywords && keywords.propertyIsEnumerable(word)) + return "keyword"; + if (functions && functions.propertyIsEnumerable(word)) { + state.beforeParams = true; + return "keyword"; + } + return null; + } + } + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + function tokenUnparsed(stream, state) { + var maybeEnd = 0, ch; + while (ch = stream.next()) { + if (ch == ";" && maybeEnd == 2) { + state.tokenize = tokenBase; + break; + } + if (ch == ")") + maybeEnd++; + else if (ch != " ") + maybeEnd = 0; + } + return "meta"; + } + return { + startState: function() { + return { + tokenize: tokenBase, + beforeParams: false, + inParams: false + }; + }, + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + } + }; +}); + +}); diff --git a/backend/webif/static/codemirror/mode/mllike/index.html b/backend/webif/static/codemirror/mode/mllike/index.html new file mode 100755 index 000000000..5923af8f8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mllike/index.html @@ -0,0 +1,179 @@ + + +CodeMirror: ML-like mode + + + + + + + + + + +
+

OCaml mode

+ + + + +

F# mode

+ + + + + +

MIME types defined: text/x-ocaml (OCaml) and text/x-fsharp (F#).

+
diff --git a/backend/webif/static/codemirror/mode/mllike/mllike.js b/backend/webif/static/codemirror/mode/mllike/mllike.js new file mode 100755 index 000000000..4d0be609c --- /dev/null +++ b/backend/webif/static/codemirror/mode/mllike/mllike.js @@ -0,0 +1,208 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('mllike', function(_config, parserConfig) { + var words = { + 'let': 'keyword', + 'rec': 'keyword', + 'in': 'keyword', + 'of': 'keyword', + 'and': 'keyword', + 'if': 'keyword', + 'then': 'keyword', + 'else': 'keyword', + 'for': 'keyword', + 'to': 'keyword', + 'while': 'keyword', + 'do': 'keyword', + 'done': 'keyword', + 'fun': 'keyword', + 'function': 'keyword', + 'val': 'keyword', + 'type': 'keyword', + 'mutable': 'keyword', + 'match': 'keyword', + 'with': 'keyword', + 'try': 'keyword', + 'open': 'builtin', + 'ignore': 'builtin', + 'begin': 'keyword', + 'end': 'keyword' + }; + + var extraWords = parserConfig.extraWords || {}; + for (var prop in extraWords) { + if (extraWords.hasOwnProperty(prop)) { + words[prop] = parserConfig.extraWords[prop]; + } + } + + function tokenBase(stream, state) { + var ch = stream.next(); + + if (ch === '"') { + state.tokenize = tokenString; + return state.tokenize(stream, state); + } + if (ch === '(') { + if (stream.eat('*')) { + state.commentLevel++; + state.tokenize = tokenComment; + return state.tokenize(stream, state); + } + } + if (ch === '~') { + stream.eatWhile(/\w/); + return 'variable-2'; + } + if (ch === '`') { + stream.eatWhile(/\w/); + return 'quote'; + } + if (ch === '/' && parserConfig.slashComments && stream.eat('/')) { + stream.skipToEnd(); + return 'comment'; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\d]/); + if (stream.eat('.')) { + stream.eatWhile(/[\d]/); + } + return 'number'; + } + if ( /[+\-*&%=<>!?|]/.test(ch)) { + return 'operator'; + } + if (/[\w\xa1-\uffff]/.test(ch)) { + stream.eatWhile(/[\w\xa1-\uffff]/); + var cur = stream.current(); + return words.hasOwnProperty(cur) ? words[cur] : 'variable'; + } + return null + } + + function tokenString(stream, state) { + var next, end = false, escaped = false; + while ((next = stream.next()) != null) { + if (next === '"' && !escaped) { + end = true; + break; + } + escaped = !escaped && next === '\\'; + } + if (end && !escaped) { + state.tokenize = tokenBase; + } + return 'string'; + }; + + function tokenComment(stream, state) { + var prev, next; + while(state.commentLevel > 0 && (next = stream.next()) != null) { + if (prev === '(' && next === '*') state.commentLevel++; + if (prev === '*' && next === ')') state.commentLevel--; + prev = next; + } + if (state.commentLevel <= 0) { + state.tokenize = tokenBase; + } + return 'comment'; + } + + return { + startState: function() {return {tokenize: tokenBase, commentLevel: 0};}, + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + }, + + blockCommentStart: "(*", + blockCommentEnd: "*)", + lineComment: parserConfig.slashComments ? "//" : null + }; +}); + +CodeMirror.defineMIME('text/x-ocaml', { + name: 'mllike', + extraWords: { + 'succ': 'keyword', + 'trace': 'builtin', + 'exit': 'builtin', + 'print_string': 'builtin', + 'print_endline': 'builtin', + 'true': 'atom', + 'false': 'atom', + 'raise': 'keyword' + } +}); + +CodeMirror.defineMIME('text/x-fsharp', { + name: 'mllike', + extraWords: { + 'abstract': 'keyword', + 'as': 'keyword', + 'assert': 'keyword', + 'base': 'keyword', + 'class': 'keyword', + 'default': 'keyword', + 'delegate': 'keyword', + 'downcast': 'keyword', + 'downto': 'keyword', + 'elif': 'keyword', + 'exception': 'keyword', + 'extern': 'keyword', + 'finally': 'keyword', + 'global': 'keyword', + 'inherit': 'keyword', + 'inline': 'keyword', + 'interface': 'keyword', + 'internal': 'keyword', + 'lazy': 'keyword', + 'let!': 'keyword', + 'member' : 'keyword', + 'module': 'keyword', + 'namespace': 'keyword', + 'new': 'keyword', + 'null': 'keyword', + 'override': 'keyword', + 'private': 'keyword', + 'public': 'keyword', + 'return': 'keyword', + 'return!': 'keyword', + 'select': 'keyword', + 'static': 'keyword', + 'struct': 'keyword', + 'upcast': 'keyword', + 'use': 'keyword', + 'use!': 'keyword', + 'val': 'keyword', + 'when': 'keyword', + 'yield': 'keyword', + 'yield!': 'keyword', + + 'List': 'builtin', + 'Seq': 'builtin', + 'Map': 'builtin', + 'Set': 'builtin', + 'int': 'builtin', + 'string': 'builtin', + 'raise': 'builtin', + 'failwith': 'builtin', + 'not': 'builtin', + 'true': 'builtin', + 'false': 'builtin' + }, + slashComments: true +}); + +}); diff --git a/backend/webif/static/codemirror/mode/modelica/index.html b/backend/webif/static/codemirror/mode/modelica/index.html new file mode 100755 index 000000000..408c3b17e --- /dev/null +++ b/backend/webif/static/codemirror/mode/modelica/index.html @@ -0,0 +1,67 @@ + + +CodeMirror: Modelica mode + + + + + + + + + + + + +
+

Modelica mode

+ +
+ + + +

Simple mode that tries to handle Modelica as well as it can.

+ +

MIME types defined: text/x-modelica + (Modlica code).

+
diff --git a/backend/webif/static/codemirror/mode/modelica/modelica.js b/backend/webif/static/codemirror/mode/modelica/modelica.js new file mode 100755 index 000000000..77ec7a3c1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/modelica/modelica.js @@ -0,0 +1,245 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Modelica support for CodeMirror, copyright (c) by Lennart Ochel + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +}) + +(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("modelica", function(config, parserConfig) { + + var indentUnit = config.indentUnit; + var keywords = parserConfig.keywords || {}; + var builtin = parserConfig.builtin || {}; + var atoms = parserConfig.atoms || {}; + + var isSingleOperatorChar = /[;=\(:\),{}.*<>+\-\/^\[\]]/; + var isDoubleOperatorChar = /(:=|<=|>=|==|<>|\.\+|\.\-|\.\*|\.\/|\.\^)/; + var isDigit = /[0-9]/; + var isNonDigit = /[_a-zA-Z]/; + + function tokenLineComment(stream, state) { + stream.skipToEnd(); + state.tokenize = null; + return "comment"; + } + + function tokenBlockComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenString(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == '"' && !escaped) { + state.tokenize = null; + state.sol = false; + break; + } + escaped = !escaped && ch == "\\"; + } + + return "string"; + } + + function tokenIdent(stream, state) { + stream.eatWhile(isDigit); + while (stream.eat(isDigit) || stream.eat(isNonDigit)) { } + + + var cur = stream.current(); + + if(state.sol && (cur == "package" || cur == "model" || cur == "when" || cur == "connector")) state.level++; + else if(state.sol && cur == "end" && state.level > 0) state.level--; + + state.tokenize = null; + state.sol = false; + + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + else if (builtin.propertyIsEnumerable(cur)) return "builtin"; + else if (atoms.propertyIsEnumerable(cur)) return "atom"; + else return "variable"; + } + + function tokenQIdent(stream, state) { + while (stream.eat(/[^']/)) { } + + state.tokenize = null; + state.sol = false; + + if(stream.eat("'")) + return "variable"; + else + return "error"; + } + + function tokenUnsignedNuber(stream, state) { + stream.eatWhile(isDigit); + if (stream.eat('.')) { + stream.eatWhile(isDigit); + } + if (stream.eat('e') || stream.eat('E')) { + if (!stream.eat('-')) + stream.eat('+'); + stream.eatWhile(isDigit); + } + + state.tokenize = null; + state.sol = false; + return "number"; + } + + // Interface + return { + startState: function() { + return { + tokenize: null, + level: 0, + sol: true + }; + }, + + token: function(stream, state) { + if(state.tokenize != null) { + return state.tokenize(stream, state); + } + + if(stream.sol()) { + state.sol = true; + } + + // WHITESPACE + if(stream.eatSpace()) { + state.tokenize = null; + return null; + } + + var ch = stream.next(); + + // LINECOMMENT + if(ch == '/' && stream.eat('/')) { + state.tokenize = tokenLineComment; + } + // BLOCKCOMMENT + else if(ch == '/' && stream.eat('*')) { + state.tokenize = tokenBlockComment; + } + // TWO SYMBOL TOKENS + else if(isDoubleOperatorChar.test(ch+stream.peek())) { + stream.next(); + state.tokenize = null; + return "operator"; + } + // SINGLE SYMBOL TOKENS + else if(isSingleOperatorChar.test(ch)) { + state.tokenize = null; + return "operator"; + } + // IDENT + else if(isNonDigit.test(ch)) { + state.tokenize = tokenIdent; + } + // Q-IDENT + else if(ch == "'" && stream.peek() && stream.peek() != "'") { + state.tokenize = tokenQIdent; + } + // STRING + else if(ch == '"') { + state.tokenize = tokenString; + } + // UNSIGNED_NUBER + else if(isDigit.test(ch)) { + state.tokenize = tokenUnsignedNuber; + } + // ERROR + else { + state.tokenize = null; + return "error"; + } + + return state.tokenize(stream, state); + }, + + indent: function(state, textAfter) { + if (state.tokenize != null) return CodeMirror.Pass; + + var level = state.level; + if(/(algorithm)/.test(textAfter)) level--; + if(/(equation)/.test(textAfter)) level--; + if(/(initial algorithm)/.test(textAfter)) level--; + if(/(initial equation)/.test(textAfter)) level--; + if(/(end)/.test(textAfter)) level--; + + if(level > 0) + return indentUnit*level; + else + return 0; + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; + }); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i=0; i + +CodeMirror: MscGen mode + + + + + + + + + +
+

MscGen mode

+ +
+ +

Xù mode

+ +
+ +

MsGenny mode

+
+ +

+ Simple mode for highlighting MscGen and two derived sequence + chart languages. +

+ + + +

MIME types defined: + text/x-mscgen + text/x-xu + text/x-msgenny +

+ +
diff --git a/backend/webif/static/codemirror/mode/mscgen/mscgen.js b/backend/webif/static/codemirror/mode/mscgen/mscgen.js new file mode 100755 index 000000000..2cd6f4270 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mscgen/mscgen.js @@ -0,0 +1,175 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// mode(s) for the sequence chart dsl's mscgen, xù and msgenny +// For more information on mscgen, see the site of the original author: +// http://www.mcternan.me.uk/mscgen +// +// This mode for mscgen and the two derivative languages were +// originally made for use in the mscgen_js interpreter +// (https://sverweij.github.io/mscgen_js) + +(function(mod) { + if ( typeof exports == "object" && typeof module == "object")// CommonJS + mod(require("../../lib/codemirror")); + else if ( typeof define == "function" && define.amd)// AMD + define(["../../lib/codemirror"], mod); + else// Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var languages = { + mscgen: { + "keywords" : ["msc"], + "options" : ["hscale", "width", "arcgradient", "wordwraparcs"], + "constants" : ["true", "false", "on", "off"], + "attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip"], + "brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists + "arcsWords" : ["note", "abox", "rbox", "box"], + "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"], + "singlecomment" : ["//", "#"], + "operators" : ["="] + }, + xu: { + "keywords" : ["msc", "xu"], + "options" : ["hscale", "width", "arcgradient", "wordwraparcs", "watermark"], + "constants" : ["true", "false", "on", "off", "auto"], + "attributes" : ["label", "idurl", "id", "url", "linecolor", "linecolour", "textcolor", "textcolour", "textbgcolor", "textbgcolour", "arclinecolor", "arclinecolour", "arctextcolor", "arctextcolour", "arctextbgcolor", "arctextbgcolour", "arcskip"], + "brackets" : ["\\{", "\\}"], // [ and ] are brackets too, but these get handled in with lists + "arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"], + "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"], + "singlecomment" : ["//", "#"], + "operators" : ["="] + }, + msgenny: { + "keywords" : null, + "options" : ["hscale", "width", "arcgradient", "wordwraparcs", "watermark"], + "constants" : ["true", "false", "on", "off", "auto"], + "attributes" : null, + "brackets" : ["\\{", "\\}"], + "arcsWords" : ["note", "abox", "rbox", "box", "alt", "else", "opt", "break", "par", "seq", "strict", "neg", "critical", "ignore", "consider", "assert", "loop", "ref", "exc"], + "arcsOthers" : ["\\|\\|\\|", "\\.\\.\\.", "---", "--", "<->", "==", "<<=>>", "<=>", "\\.\\.", "<<>>", "::", "<:>", "->", "=>>", "=>", ">>", ":>", "<-", "<<=", "<=", "<<", "<:", "x-", "-x"], + "singlecomment" : ["//", "#"], + "operators" : ["="] + } + } + + CodeMirror.defineMode("mscgen", function(_, modeConfig) { + var language = languages[modeConfig && modeConfig.language || "mscgen"] + return { + startState: startStateFn, + copyState: copyStateFn, + token: produceTokenFunction(language), + lineComment : "#", + blockCommentStart : "/*", + blockCommentEnd : "*/" + }; + }); + + CodeMirror.defineMIME("text/x-mscgen", "mscgen"); + CodeMirror.defineMIME("text/x-xu", {name: "mscgen", language: "xu"}); + CodeMirror.defineMIME("text/x-msgenny", {name: "mscgen", language: "msgenny"}); + + function wordRegexpBoundary(pWords) { + return new RegExp("\\b(" + pWords.join("|") + ")\\b", "i"); + } + + function wordRegexp(pWords) { + return new RegExp("(" + pWords.join("|") + ")", "i"); + } + + function startStateFn() { + return { + inComment : false, + inString : false, + inAttributeList : false, + inScript : false + }; + } + + function copyStateFn(pState) { + return { + inComment : pState.inComment, + inString : pState.inString, + inAttributeList : pState.inAttributeList, + inScript : pState.inScript + }; + } + + function produceTokenFunction(pConfig) { + + return function(pStream, pState) { + if (pStream.match(wordRegexp(pConfig.brackets), true, true)) { + return "bracket"; + } + /* comments */ + if (!pState.inComment) { + if (pStream.match(/\/\*[^\*\/]*/, true, true)) { + pState.inComment = true; + return "comment"; + } + if (pStream.match(wordRegexp(pConfig.singlecomment), true, true)) { + pStream.skipToEnd(); + return "comment"; + } + } + if (pState.inComment) { + if (pStream.match(/[^\*\/]*\*\//, true, true)) + pState.inComment = false; + else + pStream.skipToEnd(); + return "comment"; + } + /* strings */ + if (!pState.inString && pStream.match(/\"(\\\"|[^\"])*/, true, true)) { + pState.inString = true; + return "string"; + } + if (pState.inString) { + if (pStream.match(/[^\"]*\"/, true, true)) + pState.inString = false; + else + pStream.skipToEnd(); + return "string"; + } + /* keywords & operators */ + if (!!pConfig.keywords && pStream.match(wordRegexpBoundary(pConfig.keywords), true, true)) + return "keyword"; + + if (pStream.match(wordRegexpBoundary(pConfig.options), true, true)) + return "keyword"; + + if (pStream.match(wordRegexpBoundary(pConfig.arcsWords), true, true)) + return "keyword"; + + if (pStream.match(wordRegexp(pConfig.arcsOthers), true, true)) + return "keyword"; + + if (!!pConfig.operators && pStream.match(wordRegexp(pConfig.operators), true, true)) + return "operator"; + + if (!!pConfig.constants && pStream.match(wordRegexp(pConfig.constants), true, true)) + return "variable"; + + /* attribute lists */ + if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match(/\[/, true, true)) { + pConfig.inAttributeList = true; + return "bracket"; + } + if (pConfig.inAttributeList) { + if (pConfig.attributes !== null && pStream.match(wordRegexpBoundary(pConfig.attributes), true, true)) { + return "attribute"; + } + if (pStream.match(/]/, true, true)) { + pConfig.inAttributeList = false; + return "bracket"; + } + } + + pStream.next(); + return "base"; + }; + } + +}); diff --git a/backend/webif/static/codemirror/mode/mscgen/mscgen_test.js b/backend/webif/static/codemirror/mode/mscgen/mscgen_test.js new file mode 100755 index 000000000..956c5758e --- /dev/null +++ b/backend/webif/static/codemirror/mode/mscgen/mscgen_test.js @@ -0,0 +1,83 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "mscgen"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("empty chart", + "[keyword msc][bracket {]", + "[base ]", + "[bracket }]" + ); + + MT("comments", + "[comment // a single line comment]", + "[comment # another single line comment /* and */ ignored here]", + "[comment /* A multi-line comment even though it contains]", + "[comment msc keywords and \"quoted text\"*/]"); + + MT("strings", + "[string \"// a string\"]", + "[string \"a string running over]", + "[string two lines\"]", + "[string \"with \\\"escaped quote\"]" + ); + + MT("xù/ msgenny keywords classify as 'base'", + "[base watermark]", + "[base alt loop opt ref else break par seq assert]" + ); + + MT("xù/ msgenny constants classify as 'base'", + "[base auto]" + ); + + MT("mscgen constants classify as 'variable'", + "[variable true]", "[variable false]", "[variable on]", "[variable off]" + ); + + MT("mscgen options classify as keyword", + "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" + ); + + MT("mscgen arcs classify as keyword", + "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", + "[keyword |||...---]", "[keyword ..--==::]", + "[keyword ->]", "[keyword <-]", "[keyword <->]", + "[keyword =>]", "[keyword <=]", "[keyword <=>]", + "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", + "[keyword >>]", "[keyword <<]", "[keyword <<>>]", + "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", + "[keyword :>]", "[keyword <:]", "[keyword <:>]" + ); + + MT("within an attribute list, attributes classify as attribute", + "[bracket [[][attribute label]", + "[attribute id]","[attribute url]","[attribute idurl]", + "[attribute linecolor]","[attribute linecolour]","[attribute textcolor]","[attribute textcolour]","[attribute textbgcolor]","[attribute textbgcolour]", + "[attribute arclinecolor]","[attribute arclinecolour]","[attribute arctextcolor]","[attribute arctextcolour]","[attribute arctextbgcolor]","[attribute arctextbgcolour]", + "[attribute arcskip][bracket ]]]" + ); + + MT("outside an attribute list, attributes classify as base", + "[base label]", + "[base id]","[base url]","[base idurl]", + "[base linecolor]","[base linecolour]","[base textcolor]","[base textcolour]","[base textbgcolor]","[base textbgcolour]", + "[base arclinecolor]","[base arclinecolour]","[base arctextcolor]","[base arctextcolour]","[base arctextbgcolor]","[base arctextbgcolour]", + "[base arcskip]" + ); + + MT("a typical program", + "[comment # typical mscgen program]", + "[keyword msc][base ][bracket {]", + "[keyword wordwraparcs][operator =][variable true][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]", + "[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]", + "[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]", + "[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]", + "[base a ][keyword =>>][base b][bracket [[][attribute label][operator =][string \"Hello entity B\"][bracket ]]][base ;]", + "[base a ][keyword <<][base b][bracket [[][attribute label][operator =][string \"Here's an answer dude!\"][bracket ]]][base ;]", + "[base c ][keyword :>][base *][bracket [[][attribute label][operator =][string \"What about me?\"][base , ][attribute textcolor][operator =][base red][bracket ]]][base ;]", + "[bracket }]" + ); +})(); diff --git a/backend/webif/static/codemirror/mode/mscgen/msgenny_test.js b/backend/webif/static/codemirror/mode/mscgen/msgenny_test.js new file mode 100755 index 000000000..edf9da09a --- /dev/null +++ b/backend/webif/static/codemirror/mode/mscgen/msgenny_test.js @@ -0,0 +1,76 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-msgenny"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "msgenny"); } + + MT("comments", + "[comment // a single line comment]", + "[comment # another single line comment /* and */ ignored here]", + "[comment /* A multi-line comment even though it contains]", + "[comment msc keywords and \"quoted text\"*/]"); + + MT("strings", + "[string \"// a string\"]", + "[string \"a string running over]", + "[string two lines\"]", + "[string \"with \\\"escaped quote\"]" + ); + + MT("xù/ msgenny keywords classify as 'keyword'", + "[keyword watermark]", + "[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]" + ); + + MT("xù/ msgenny constants classify as 'variable'", + "[variable auto]", + "[variable true]", "[variable false]", "[variable on]", "[variable off]" + ); + + MT("mscgen options classify as keyword", + "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" + ); + + MT("mscgen arcs classify as keyword", + "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", + "[keyword |||...---]", "[keyword ..--==::]", + "[keyword ->]", "[keyword <-]", "[keyword <->]", + "[keyword =>]", "[keyword <=]", "[keyword <=>]", + "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", + "[keyword >>]", "[keyword <<]", "[keyword <<>>]", + "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", + "[keyword :>]", "[keyword <:]", "[keyword <:>]" + ); + + MT("within an attribute list, mscgen/ xù attributes classify as base", + "[base [[label]", + "[base idurl id url]", + "[base linecolor linecolour textcolor textcolour textbgcolor textbgcolour]", + "[base arclinecolor arclinecolour arctextcolor arctextcolour arctextbgcolor arctextbgcolour]", + "[base arcskip]]]" + ); + + MT("outside an attribute list, mscgen/ xù attributes classify as base", + "[base label]", + "[base idurl id url]", + "[base linecolor linecolour textcolor textcolour textbgcolor textbgcolour]", + "[base arclinecolor arclinecolour arctextcolor arctextcolour arctextbgcolor arctextbgcolour]", + "[base arcskip]" + ); + + MT("a typical program", + "[comment # typical msgenny program]", + "[keyword wordwraparcs][operator =][variable true][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30;]", + "[base a : ][string \"Entity A\"][base ,]", + "[base b : Entity B,]", + "[base c : Entity C;]", + "[base a ][keyword =>>][base b: ][string \"Hello entity B\"][base ;]", + "[base a ][keyword alt][base c][bracket {]", + "[base a ][keyword <<][base b: ][string \"Here's an answer dude!\"][base ;]", + "[keyword ---][base : ][string \"sorry, won't march - comm glitch\"]", + "[base a ][keyword x-][base b: ][string \"Here's an answer dude! (won't arrive...)\"][base ;]", + "[bracket }]", + "[base c ][keyword :>][base *: What about me?;]" + ); +})(); diff --git a/backend/webif/static/codemirror/mode/mscgen/xu_test.js b/backend/webif/static/codemirror/mode/mscgen/xu_test.js new file mode 100755 index 000000000..950aeca1f --- /dev/null +++ b/backend/webif/static/codemirror/mode/mscgen/xu_test.js @@ -0,0 +1,86 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-xu"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "xu"); } + + MT("empty chart", + "[keyword msc][bracket {]", + "[base ]", + "[bracket }]" + ); + + MT("empty chart", + "[keyword xu][bracket {]", + "[base ]", + "[bracket }]" + ); + + MT("comments", + "[comment // a single line comment]", + "[comment # another single line comment /* and */ ignored here]", + "[comment /* A multi-line comment even though it contains]", + "[comment msc keywords and \"quoted text\"*/]"); + + MT("strings", + "[string \"// a string\"]", + "[string \"a string running over]", + "[string two lines\"]", + "[string \"with \\\"escaped quote\"]" + ); + + MT("xù/ msgenny keywords classify as 'keyword'", + "[keyword watermark]", + "[keyword alt]","[keyword loop]","[keyword opt]","[keyword ref]","[keyword else]","[keyword break]","[keyword par]","[keyword seq]","[keyword assert]" + ); + + MT("xù/ msgenny constants classify as 'variable'", + "[variable auto]", + "[variable true]", "[variable false]", "[variable on]", "[variable off]" + ); + + MT("mscgen options classify as keyword", + "[keyword hscale]", "[keyword width]", "[keyword arcgradient]", "[keyword wordwraparcs]" + ); + + MT("mscgen arcs classify as keyword", + "[keyword note]","[keyword abox]","[keyword rbox]","[keyword box]", + "[keyword |||...---]", "[keyword ..--==::]", + "[keyword ->]", "[keyword <-]", "[keyword <->]", + "[keyword =>]", "[keyword <=]", "[keyword <=>]", + "[keyword =>>]", "[keyword <<=]", "[keyword <<=>>]", + "[keyword >>]", "[keyword <<]", "[keyword <<>>]", + "[keyword -x]", "[keyword x-]", "[keyword -X]", "[keyword X-]", + "[keyword :>]", "[keyword <:]", "[keyword <:>]" + ); + + MT("within an attribute list, attributes classify as attribute", + "[bracket [[][attribute label]", + "[attribute id]","[attribute url]","[attribute idurl]", + "[attribute linecolor]","[attribute linecolour]","[attribute textcolor]","[attribute textcolour]","[attribute textbgcolor]","[attribute textbgcolour]", + "[attribute arclinecolor]","[attribute arclinecolour]","[attribute arctextcolor]","[attribute arctextcolour]","[attribute arctextbgcolor]","[attribute arctextbgcolour]", + "[attribute arcskip][bracket ]]]" + ); + + MT("outside an attribute list, attributes classify as base", + "[base label]", + "[base id]","[base url]","[base idurl]", + "[base linecolor]","[base linecolour]","[base textcolor]","[base textcolour]","[base textbgcolor]","[base textbgcolour]", + "[base arclinecolor]","[base arclinecolour]","[base arctextcolor]","[base arctextcolour]","[base arctextbgcolor]","[base arctextbgcolour]", + "[base arcskip]" + ); + + MT("a typical program", + "[comment # typical xu program]", + "[keyword xu][base ][bracket {]", + "[keyword wordwraparcs][operator =][string \"true\"][base , ][keyword hscale][operator =][string \"0.8\"][base , ][keyword arcgradient][operator =][base 30, ][keyword width][operator =][variable auto][base ;]", + "[base a][bracket [[][attribute label][operator =][string \"Entity A\"][bracket ]]][base ,]", + "[base b][bracket [[][attribute label][operator =][string \"Entity B\"][bracket ]]][base ,]", + "[base c][bracket [[][attribute label][operator =][string \"Entity C\"][bracket ]]][base ;]", + "[base a ][keyword =>>][base b][bracket [[][attribute label][operator =][string \"Hello entity B\"][bracket ]]][base ;]", + "[base a ][keyword <<][base b][bracket [[][attribute label][operator =][string \"Here's an answer dude!\"][bracket ]]][base ;]", + "[base c ][keyword :>][base *][bracket [[][attribute label][operator =][string \"What about me?\"][base , ][attribute textcolor][operator =][base red][bracket ]]][base ;]", + "[bracket }]" + ); +})(); diff --git a/backend/webif/static/codemirror/mode/mumps/index.html b/backend/webif/static/codemirror/mode/mumps/index.html new file mode 100755 index 000000000..b1f92c213 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mumps/index.html @@ -0,0 +1,85 @@ + + +CodeMirror: MUMPS mode + + + + + + + + + +
+

MUMPS mode

+ + +
+ + +
diff --git a/backend/webif/static/codemirror/mode/mumps/mumps.js b/backend/webif/static/codemirror/mode/mumps/mumps.js new file mode 100755 index 000000000..469f8c3d1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/mumps/mumps.js @@ -0,0 +1,148 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* + This MUMPS Language script was constructed using vbscript.js as a template. +*/ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("mumps", function() { + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); + } + + var singleOperators = new RegExp("^[\\+\\-\\*/&#!_?\\\\<>=\\'\\[\\]]"); + var doubleOperators = new RegExp("^(('=)|(<=)|(>=)|('>)|('<)|([[)|(]])|(^$))"); + var singleDelimiters = new RegExp("^[\\.,:]"); + var brackets = new RegExp("[()]"); + var identifiers = new RegExp("^[%A-Za-z][A-Za-z0-9]*"); + var commandKeywords = ["break","close","do","else","for","goto", "halt", "hang", "if", "job","kill","lock","merge","new","open", "quit", "read", "set", "tcommit", "trollback", "tstart", "use", "view", "write", "xecute", "b","c","d","e","f","g", "h", "i", "j","k","l","m","n","o", "q", "r", "s", "tc", "tro", "ts", "u", "v", "w", "x"]; + // The following list includes instrinsic functions _and_ special variables + var intrinsicFuncsWords = ["\\$ascii", "\\$char", "\\$data", "\\$ecode", "\\$estack", "\\$etrap", "\\$extract", "\\$find", "\\$fnumber", "\\$get", "\\$horolog", "\\$io", "\\$increment", "\\$job", "\\$justify", "\\$length", "\\$name", "\\$next", "\\$order", "\\$piece", "\\$qlength", "\\$qsubscript", "\\$query", "\\$quit", "\\$random", "\\$reverse", "\\$select", "\\$stack", "\\$test", "\\$text", "\\$translate", "\\$view", "\\$x", "\\$y", "\\$a", "\\$c", "\\$d", "\\$e", "\\$ec", "\\$es", "\\$et", "\\$f", "\\$fn", "\\$g", "\\$h", "\\$i", "\\$j", "\\$l", "\\$n", "\\$na", "\\$o", "\\$p", "\\$q", "\\$ql", "\\$qs", "\\$r", "\\$re", "\\$s", "\\$st", "\\$t", "\\$tr", "\\$v", "\\$z"]; + var intrinsicFuncs = wordRegexp(intrinsicFuncsWords); + var command = wordRegexp(commandKeywords); + + function tokenBase(stream, state) { + if (stream.sol()) { + state.label = true; + state.commandMode = 0; + } + + // The character has meaning in MUMPS. Ignoring consecutive + // spaces would interfere with interpreting whether the next non-space + // character belongs to the command or argument context. + + // Examine each character and update a mode variable whose interpretation is: + // >0 => command 0 => argument <0 => command post-conditional + var ch = stream.peek(); + + if (ch == " " || ch == "\t") { // Pre-process + state.label = false; + if (state.commandMode == 0) + state.commandMode = 1; + else if ((state.commandMode < 0) || (state.commandMode == 2)) + state.commandMode = 0; + } else if ((ch != ".") && (state.commandMode > 0)) { + if (ch == ":") + state.commandMode = -1; // SIS - Command post-conditional + else + state.commandMode = 2; + } + + // Do not color parameter list as line tag + if ((ch === "(") || (ch === "\u0009")) + state.label = false; + + // MUMPS comment starts with ";" + if (ch === ";") { + stream.skipToEnd(); + return "comment"; + } + + // Number Literals // SIS/RLM - MUMPS permits canonic number followed by concatenate operator + if (stream.match(/^[-+]?\d+(\.\d+)?([eE][-+]?\d+)?/)) + return "number"; + + // Handle Strings + if (ch == '"') { + if (stream.skipTo('"')) { + stream.next(); + return "string"; + } else { + stream.skipToEnd(); + return "error"; + } + } + + // Handle operators and Delimiters + if (stream.match(doubleOperators) || stream.match(singleOperators)) + return "operator"; + + // Prevents leading "." in DO block from falling through to error + if (stream.match(singleDelimiters)) + return null; + + if (brackets.test(ch)) { + stream.next(); + return "bracket"; + } + + if (state.commandMode > 0 && stream.match(command)) + return "variable-2"; + + if (stream.match(intrinsicFuncs)) + return "builtin"; + + if (stream.match(identifiers)) + return "variable"; + + // Detect dollar-sign when not a documented intrinsic function + // "^" may introduce a GVN or SSVN - Color same as function + if (ch === "$" || ch === "^") { + stream.next(); + return "builtin"; + } + + // MUMPS Indirection + if (ch === "@") { + stream.next(); + return "string-2"; + } + + if (/[\w%]/.test(ch)) { + stream.eatWhile(/[\w%]/); + return "variable"; + } + + // Handle non-detected items + stream.next(); + return "error"; + } + + return { + startState: function() { + return { + label: false, + commandMode: 0 + }; + }, + + token: function(stream, state) { + var style = tokenBase(stream, state); + if (state.label) return "tag"; + return style; + } + }; + }); + + CodeMirror.defineMIME("text/x-mumps", "mumps"); +}); diff --git a/backend/webif/static/codemirror/mode/nginx/index.html b/backend/webif/static/codemirror/mode/nginx/index.html new file mode 100755 index 000000000..03cf67149 --- /dev/null +++ b/backend/webif/static/codemirror/mode/nginx/index.html @@ -0,0 +1,181 @@ + + +CodeMirror: NGINX mode + + + + + + + + + + + + + +
+

NGINX mode

+
+ + +

MIME types defined: text/nginx.

+ +
diff --git a/backend/webif/static/codemirror/mode/nginx/nginx.js b/backend/webif/static/codemirror/mode/nginx/nginx.js new file mode 100755 index 000000000..00a322492 --- /dev/null +++ b/backend/webif/static/codemirror/mode/nginx/nginx.js @@ -0,0 +1,178 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("nginx", function(config) { + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var keywords = words( + /* ngxDirectiveControl */ "break return rewrite set" + + /* ngxDirective */ " accept_mutex accept_mutex_delay access_log add_after_body add_before_body add_header addition_types aio alias allow ancient_browser ancient_browser_value auth_basic auth_basic_user_file auth_http auth_http_header auth_http_timeout autoindex autoindex_exact_size autoindex_localtime charset charset_types client_body_buffer_size client_body_in_file_only client_body_in_single_buffer client_body_temp_path client_body_timeout client_header_buffer_size client_header_timeout client_max_body_size connection_pool_size create_full_put_path daemon dav_access dav_methods debug_connection debug_points default_type degradation degrade deny devpoll_changes devpoll_events directio directio_alignment empty_gif env epoll_events error_log eventport_events expires fastcgi_bind fastcgi_buffer_size fastcgi_buffers fastcgi_busy_buffers_size fastcgi_cache fastcgi_cache_key fastcgi_cache_methods fastcgi_cache_min_uses fastcgi_cache_path fastcgi_cache_use_stale fastcgi_cache_valid fastcgi_catch_stderr fastcgi_connect_timeout fastcgi_hide_header fastcgi_ignore_client_abort fastcgi_ignore_headers fastcgi_index fastcgi_intercept_errors fastcgi_max_temp_file_size fastcgi_next_upstream fastcgi_param fastcgi_pass_header fastcgi_pass_request_body fastcgi_pass_request_headers fastcgi_read_timeout fastcgi_send_lowat fastcgi_send_timeout fastcgi_split_path_info fastcgi_store fastcgi_store_access fastcgi_temp_file_write_size fastcgi_temp_path fastcgi_upstream_fail_timeout fastcgi_upstream_max_fails flv geoip_city geoip_country google_perftools_profiles gzip gzip_buffers gzip_comp_level gzip_disable gzip_hash gzip_http_version gzip_min_length gzip_no_buffer gzip_proxied gzip_static gzip_types gzip_vary gzip_window if_modified_since ignore_invalid_headers image_filter image_filter_buffer image_filter_jpeg_quality image_filter_transparency imap_auth imap_capabilities imap_client_buffer index ip_hash keepalive_requests keepalive_timeout kqueue_changes kqueue_events large_client_header_buffers limit_conn limit_conn_log_level limit_rate limit_rate_after limit_req limit_req_log_level limit_req_zone limit_zone lingering_time lingering_timeout lock_file log_format log_not_found log_subrequest map_hash_bucket_size map_hash_max_size master_process memcached_bind memcached_buffer_size memcached_connect_timeout memcached_next_upstream memcached_read_timeout memcached_send_timeout memcached_upstream_fail_timeout memcached_upstream_max_fails merge_slashes min_delete_depth modern_browser modern_browser_value msie_padding msie_refresh multi_accept open_file_cache open_file_cache_errors open_file_cache_events open_file_cache_min_uses open_file_cache_valid open_log_file_cache output_buffers override_charset perl perl_modules perl_require perl_set pid pop3_auth pop3_capabilities port_in_redirect postpone_gzipping postpone_output protocol proxy proxy_bind proxy_buffer proxy_buffer_size proxy_buffering proxy_buffers proxy_busy_buffers_size proxy_cache proxy_cache_key proxy_cache_methods proxy_cache_min_uses proxy_cache_path proxy_cache_use_stale proxy_cache_valid proxy_connect_timeout proxy_headers_hash_bucket_size proxy_headers_hash_max_size proxy_hide_header proxy_ignore_client_abort proxy_ignore_headers proxy_intercept_errors proxy_max_temp_file_size proxy_method proxy_next_upstream proxy_pass_error_message proxy_pass_header proxy_pass_request_body proxy_pass_request_headers proxy_read_timeout proxy_redirect proxy_send_lowat proxy_send_timeout proxy_set_body proxy_set_header proxy_ssl_session_reuse proxy_store proxy_store_access proxy_temp_file_write_size proxy_temp_path proxy_timeout proxy_upstream_fail_timeout proxy_upstream_max_fails random_index read_ahead real_ip_header recursive_error_pages request_pool_size reset_timedout_connection resolver resolver_timeout rewrite_log rtsig_overflow_events rtsig_overflow_test rtsig_overflow_threshold rtsig_signo satisfy secure_link_secret send_lowat send_timeout sendfile sendfile_max_chunk server_name_in_redirect server_names_hash_bucket_size server_names_hash_max_size server_tokens set_real_ip_from smtp_auth smtp_capabilities smtp_client_buffer smtp_greeting_delay so_keepalive source_charset ssi ssi_ignore_recycled_buffers ssi_min_file_chunk ssi_silent_errors ssi_types ssi_value_length ssl ssl_certificate ssl_certificate_key ssl_ciphers ssl_client_certificate ssl_crl ssl_dhparam ssl_engine ssl_prefer_server_ciphers ssl_protocols ssl_session_cache ssl_session_timeout ssl_verify_client ssl_verify_depth starttls stub_status sub_filter sub_filter_once sub_filter_types tcp_nodelay tcp_nopush thread_stack_size timeout timer_resolution types_hash_bucket_size types_hash_max_size underscores_in_headers uninitialized_variable_warn use user userid userid_domain userid_expires userid_mark userid_name userid_p3p userid_path userid_service valid_referers variables_hash_bucket_size variables_hash_max_size worker_connections worker_cpu_affinity worker_priority worker_processes worker_rlimit_core worker_rlimit_nofile worker_rlimit_sigpending worker_threads working_directory xclient xml_entities xslt_stylesheet xslt_typesdrew@li229-23" + ); + + var keywords_block = words( + /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map" + ); + + var keywords_important = words( + /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files" + ); + + var indentUnit = config.indentUnit, type; + function ret(style, tp) {type = tp; return style;} + + function tokenBase(stream, state) { + + + stream.eatWhile(/[\w\$_]/); + + var cur = stream.current(); + + + if (keywords.propertyIsEnumerable(cur)) { + return "keyword"; + } + else if (keywords_block.propertyIsEnumerable(cur)) { + return "variable-2"; + } + else if (keywords_important.propertyIsEnumerable(cur)) { + return "string-2"; + } + /**/ + + var ch = stream.next(); + if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());} + else if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + else if (ch == "<" && stream.eat("!")) { + state.tokenize = tokenSGMLComment; + return tokenSGMLComment(stream, state); + } + else if (ch == "=") ret(null, "compare"); + else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + else if (ch == "#") { + stream.skipToEnd(); + return ret("comment", "comment"); + } + else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("keyword", "important"); + } + else if (/\d/.test(ch)) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } + else if (/[,.+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } + else if (/[;{}:\[\]]/.test(ch)) { + return ret(null, ch); + } + else { + stream.eatWhile(/[\w\\\-]/); + return ret("variable", "variable"); + } + } + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + function tokenSGMLComment(stream, state) { + var dashes = 0, ch; + while ((ch = stream.next()) != null) { + if (dashes >= 2 && ch == ">") { + state.tokenize = tokenBase; + break; + } + dashes = (ch == "-") ? dashes + 1 : 0; + } + return ret("comment", "comment"); + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) + break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("string", "string"); + }; + } + + return { + startState: function(base) { + return {tokenize: tokenBase, + baseIndent: base || 0, + stack: []}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + type = null; + var style = state.tokenize(stream, state); + + var context = state.stack[state.stack.length-1]; + if (type == "hash" && context == "rule") style = "atom"; + else if (style == "variable") { + if (context == "rule") style = "number"; + else if (!context || context == "@media{") style = "tag"; + } + + if (context == "rule" && /^[\{\};]$/.test(type)) + state.stack.pop(); + if (type == "{") { + if (context == "@media") state.stack[state.stack.length-1] = "@media{"; + else state.stack.push("{"); + } + else if (type == "}") state.stack.pop(); + else if (type == "@media") state.stack.push("@media"); + else if (context == "{" && type != "comment") state.stack.push("rule"); + return style; + }, + + indent: function(state, textAfter) { + var n = state.stack.length; + if (/^\}/.test(textAfter)) + n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1; + return state.baseIndent + n * indentUnit; + }, + + electricChars: "}" + }; +}); + +CodeMirror.defineMIME("text/x-nginx-conf", "nginx"); + +}); diff --git a/backend/webif/static/codemirror/mode/nsis/index.html b/backend/webif/static/codemirror/mode/nsis/index.html new file mode 100755 index 000000000..2afae87f0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/nsis/index.html @@ -0,0 +1,80 @@ + + +CodeMirror: NSIS mode + + + + + + + + + + + +
+

NSIS mode

+ + + + + + +

MIME types defined: text/x-nsis.

+
\ No newline at end of file diff --git a/backend/webif/static/codemirror/mode/nsis/nsis.js b/backend/webif/static/codemirror/mode/nsis/nsis.js new file mode 100755 index 000000000..d6c61facf --- /dev/null +++ b/backend/webif/static/codemirror/mode/nsis/nsis.js @@ -0,0 +1,95 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Author: Jan T. Sott (http://github.com/idleberg) + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineSimpleMode("nsis",{ + start:[ + // Numbers + {regex: /(?:[+-]?)(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\d+.?\d*)/, token: "number"}, + + // Strings + { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" }, + { regex: /'(?:[^\\']|\\.)*'?/, token: "string" }, + { regex: /`(?:[^\\`]|\\.)*`?/, token: "string" }, + + // Compile Time Commands + {regex: /^\s*(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|system|tempfile|warning|verbose|define|undef|insertmacro|makensis|searchparse|searchreplace))\b/, token: "keyword"}, + + // Conditional Compilation + {regex: /^\s*(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/, token: "keyword", indent: true}, + {regex: /^\s*(?:\!(else|endif|macroend))\b/, token: "keyword", dedent: true}, + + // Runtime Commands + {regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"}, + {regex: /^\s*(?:Function|PageEx|Section(?:Group)?)\b/, token: "keyword", indent: true}, + {regex: /^\s*(?:(Function|PageEx|Section(?:Group)?)End)\b/, token: "keyword", dedent: true}, + + // Command Options + {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR(32|64)?|HKCU(32|64)?|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM(32|64)?|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"}, + {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|false|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|off|on|right|show|silent|silentlog|textonly|top|true|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"}, + + // LogicLib.nsh + {regex: /\$\{(?:And(?:If(?:Not)?|Unless)|Break|Case(?:Else)?|Continue|Default|Do(?:Until|While)?|Else(?:If(?:Not)?|Unless)?|End(?:If|Select|Switch)|Exit(?:Do|For|While)|For(?:Each)?|If(?:Cmd|Not(?:Then)?|Then)?|Loop(?:Until|While)?|Or(?:If(?:Not)?|Unless)|Select|Switch|Unless|While)\}/, token: "variable-2", indent: true}, + + // FileFunc.nsh + {regex: /\$\{(?:BannerTrimPath|DirState|DriveSpace|Get(BaseName|Drives|ExeName|ExePath|FileAttributes|FileExt|FileName|FileVersion|Options|OptionsS|Parameters|Parent|Root|Size|Time)|Locate|RefreshShellIcons)\}/, token: "variable-2", dedent: true}, + + // Memento.nsh + {regex: /\$\{(?:Memento(?:Section(?:Done|End|Restore|Save)?|UnselectedSection))\}/, token: "variable-2", dedent: true}, + + // TextFunc.nsh + {regex: /\$\{(?:Config(?:Read|ReadS|Write|WriteS)|File(?:Join|ReadFromEnd|Recode)|Line(?:Find|Read|Sum)|Text(?:Compare|CompareS)|TrimNewLines)\}/, token: "variable-2", dedent: true}, + + // WinVer.nsh + {regex: /\$\{(?:(?:At(?:Least|Most)|Is)(?:ServicePack|Win(?:7|8|10|95|98|200(?:0|3|8(?:R2)?)|ME|NT4|Vista|XP))|Is(?:NT|Server))\}/, token: "variable", dedent: true}, + + // WordFunc.nsh + {regex: /\$\{(?:StrFilterS?|Version(?:Compare|Convert)|Word(?:AddS?|Find(?:(?:2|3)X)?S?|InsertS?|ReplaceS?))\}/, token: "variable-2", dedent: true}, + + // x64.nsh + {regex: /\$\{(?:RunningX64)\}/, token: "variable", dedent: true}, + {regex: /\$\{(?:Disable|Enable)X64FSRedirection\}/, token: "variable-2", dedent: true}, + + // Line Comment + {regex: /(#|;).*/, token: "comment"}, + + // Block Comment + {regex: /\/\*/, token: "comment", next: "comment"}, + + // Operator + {regex: /[-+\/*=<>!]+/, token: "operator"}, + + // Variable + {regex: /\$\w+/, token: "variable"}, + + // Constant + {regex: /\${[\w\.:-]+}/, token: "variable-2"}, + + // Language String + {regex: /\$\([\w\.:-]+\)/, token: "variable-3"} + ], + comment: [ + {regex: /.*?\*\//, token: "comment", next: "start"}, + {regex: /.*/, token: "comment"} + ], + meta: { + electricInput: /^\s*((Function|PageEx|Section|Section(Group)?)End|(\!(endif|macroend))|\$\{(End(If|Unless|While)|Loop(Until)|Next)\})$/, + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: ["#", ";"] + } +}); + +CodeMirror.defineMIME("text/x-nsis", "nsis"); +}); diff --git a/backend/webif/static/codemirror/mode/ntriples/index.html b/backend/webif/static/codemirror/mode/ntriples/index.html new file mode 100755 index 000000000..9c9984639 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ntriples/index.html @@ -0,0 +1,70 @@ + + +CodeMirror: N-Triples mode + + + + + + + + + +
+

N-Triples mode

+

The N-Triples mode also works well with on + N-Quad documents. +

+
+ +
+ + +

MIME types defined: application/n-triples.

+ +
+

N-Quads add a fourth + element to the statement to track which graph the statement is from. + Otherwise, it's identical to N-Triples.

+
+ +
+ + +

MIME types defined: application/n-quads.

+
diff --git a/backend/webif/static/codemirror/mode/ntriples/ntriples.js b/backend/webif/static/codemirror/mode/ntriples/ntriples.js new file mode 100755 index 000000000..148272e1f --- /dev/null +++ b/backend/webif/static/codemirror/mode/ntriples/ntriples.js @@ -0,0 +1,195 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/********************************************************** +* This script provides syntax highlighting support for +* the N-Triples format. +* N-Triples format specification: +* https://www.w3.org/TR/n-triples/ +***********************************************************/ + +/* + The following expression defines the defined ASF grammar transitions. + + pre_subject -> + { + ( writing_subject_uri | writing_bnode_uri ) + -> pre_predicate + -> writing_predicate_uri + -> pre_object + -> writing_object_uri | writing_object_bnode | + ( + writing_object_literal + -> writing_literal_lang | writing_literal_type + ) + -> post_object + -> BEGIN + } otherwise { + -> ERROR + } +*/ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("ntriples", function() { + + var Location = { + PRE_SUBJECT : 0, + WRITING_SUB_URI : 1, + WRITING_BNODE_URI : 2, + PRE_PRED : 3, + WRITING_PRED_URI : 4, + PRE_OBJ : 5, + WRITING_OBJ_URI : 6, + WRITING_OBJ_BNODE : 7, + WRITING_OBJ_LITERAL : 8, + WRITING_LIT_LANG : 9, + WRITING_LIT_TYPE : 10, + POST_OBJ : 11, + ERROR : 12 + }; + function transitState(currState, c) { + var currLocation = currState.location; + var ret; + + // Opening. + if (currLocation == Location.PRE_SUBJECT && c == '<') ret = Location.WRITING_SUB_URI; + else if(currLocation == Location.PRE_SUBJECT && c == '_') ret = Location.WRITING_BNODE_URI; + else if(currLocation == Location.PRE_PRED && c == '<') ret = Location.WRITING_PRED_URI; + else if(currLocation == Location.PRE_OBJ && c == '<') ret = Location.WRITING_OBJ_URI; + else if(currLocation == Location.PRE_OBJ && c == '_') ret = Location.WRITING_OBJ_BNODE; + else if(currLocation == Location.PRE_OBJ && c == '"') ret = Location.WRITING_OBJ_LITERAL; + + // Closing. + else if(currLocation == Location.WRITING_SUB_URI && c == '>') ret = Location.PRE_PRED; + else if(currLocation == Location.WRITING_BNODE_URI && c == ' ') ret = Location.PRE_PRED; + else if(currLocation == Location.WRITING_PRED_URI && c == '>') ret = Location.PRE_OBJ; + else if(currLocation == Location.WRITING_OBJ_URI && c == '>') ret = Location.POST_OBJ; + else if(currLocation == Location.WRITING_OBJ_BNODE && c == ' ') ret = Location.POST_OBJ; + else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '"') ret = Location.POST_OBJ; + else if(currLocation == Location.WRITING_LIT_LANG && c == ' ') ret = Location.POST_OBJ; + else if(currLocation == Location.WRITING_LIT_TYPE && c == '>') ret = Location.POST_OBJ; + + // Closing typed and language literal. + else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '@') ret = Location.WRITING_LIT_LANG; + else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '^') ret = Location.WRITING_LIT_TYPE; + + // Spaces. + else if( c == ' ' && + ( + currLocation == Location.PRE_SUBJECT || + currLocation == Location.PRE_PRED || + currLocation == Location.PRE_OBJ || + currLocation == Location.POST_OBJ + ) + ) ret = currLocation; + + // Reset. + else if(currLocation == Location.POST_OBJ && c == '.') ret = Location.PRE_SUBJECT; + + // Error + else ret = Location.ERROR; + + currState.location=ret; + } + + return { + startState: function() { + return { + location : Location.PRE_SUBJECT, + uris : [], + anchors : [], + bnodes : [], + langs : [], + types : [] + }; + }, + token: function(stream, state) { + var ch = stream.next(); + if(ch == '<') { + transitState(state, ch); + var parsedURI = ''; + stream.eatWhile( function(c) { if( c != '#' && c != '>' ) { parsedURI += c; return true; } return false;} ); + state.uris.push(parsedURI); + if( stream.match('#', false) ) return 'variable'; + stream.next(); + transitState(state, '>'); + return 'variable'; + } + if(ch == '#') { + var parsedAnchor = ''; + stream.eatWhile(function(c) { if(c != '>' && c != ' ') { parsedAnchor+= c; return true; } return false;}); + state.anchors.push(parsedAnchor); + return 'variable-2'; + } + if(ch == '>') { + transitState(state, '>'); + return 'variable'; + } + if(ch == '_') { + transitState(state, ch); + var parsedBNode = ''; + stream.eatWhile(function(c) { if( c != ' ' ) { parsedBNode += c; return true; } return false;}); + state.bnodes.push(parsedBNode); + stream.next(); + transitState(state, ' '); + return 'builtin'; + } + if(ch == '"') { + transitState(state, ch); + stream.eatWhile( function(c) { return c != '"'; } ); + stream.next(); + if( stream.peek() != '@' && stream.peek() != '^' ) { + transitState(state, '"'); + } + return 'string'; + } + if( ch == '@' ) { + transitState(state, '@'); + var parsedLang = ''; + stream.eatWhile(function(c) { if( c != ' ' ) { parsedLang += c; return true; } return false;}); + state.langs.push(parsedLang); + stream.next(); + transitState(state, ' '); + return 'string-2'; + } + if( ch == '^' ) { + stream.next(); + transitState(state, '^'); + var parsedType = ''; + stream.eatWhile(function(c) { if( c != '>' ) { parsedType += c; return true; } return false;} ); + state.types.push(parsedType); + stream.next(); + transitState(state, '>'); + return 'variable'; + } + if( ch == ' ' ) { + transitState(state, ch); + } + if( ch == '.' ) { + transitState(state, ch); + } + } + }; +}); + +// define the registered Media Type for n-triples: +// https://www.w3.org/TR/n-triples/#n-triples-mediatype +CodeMirror.defineMIME("application/n-triples", "ntriples"); + +// N-Quads is based on the N-Triples format (so same highlighting works) +// https://www.w3.org/TR/n-quads/ +CodeMirror.defineMIME("application/n-quads", "ntriples"); + +// previously used, though technically incorrect media type for n-triples +CodeMirror.defineMIME("text/n-triples", "ntriples"); + +}); diff --git a/backend/webif/static/codemirror/mode/octave/index.html b/backend/webif/static/codemirror/mode/octave/index.html new file mode 100755 index 000000000..3490ee637 --- /dev/null +++ b/backend/webif/static/codemirror/mode/octave/index.html @@ -0,0 +1,83 @@ + + +CodeMirror: Octave mode + + + + + + + + + +
+

Octave mode

+ +
+ + +

MIME types defined: text/x-octave.

+
diff --git a/backend/webif/static/codemirror/mode/octave/octave.js b/backend/webif/static/codemirror/mode/octave/octave.js new file mode 100755 index 000000000..b77ad682e --- /dev/null +++ b/backend/webif/static/codemirror/mode/octave/octave.js @@ -0,0 +1,139 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("octave", function() { + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + var singleOperators = new RegExp("^[\\+\\-\\*/&|\\^~<>!@'\\\\]"); + var singleDelimiters = new RegExp('^[\\(\\[\\{\\},:=;]'); + var doubleOperators = new RegExp("^((==)|(~=)|(<=)|(>=)|(<<)|(>>)|(\\.[\\+\\-\\*/\\^\\\\]))"); + var doubleDelimiters = new RegExp("^((!=)|(\\+=)|(\\-=)|(\\*=)|(/=)|(&=)|(\\|=)|(\\^=))"); + var tripleDelimiters = new RegExp("^((>>=)|(<<=))"); + var expressionEnd = new RegExp("^[\\]\\)]"); + var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*"); + + var builtins = wordRegexp([ + 'error', 'eval', 'function', 'abs', 'acos', 'atan', 'asin', 'cos', + 'cosh', 'exp', 'log', 'prod', 'sum', 'log10', 'max', 'min', 'sign', 'sin', 'sinh', + 'sqrt', 'tan', 'reshape', 'break', 'zeros', 'default', 'margin', 'round', 'ones', + 'rand', 'syn', 'ceil', 'floor', 'size', 'clear', 'zeros', 'eye', 'mean', 'std', 'cov', + 'det', 'eig', 'inv', 'norm', 'rank', 'trace', 'expm', 'logm', 'sqrtm', 'linspace', 'plot', + 'title', 'xlabel', 'ylabel', 'legend', 'text', 'grid', 'meshgrid', 'mesh', 'num2str', + 'fft', 'ifft', 'arrayfun', 'cellfun', 'input', 'fliplr', 'flipud', 'ismember' + ]); + + var keywords = wordRegexp([ + 'return', 'case', 'switch', 'else', 'elseif', 'end', 'endif', 'endfunction', + 'if', 'otherwise', 'do', 'for', 'while', 'try', 'catch', 'classdef', 'properties', 'events', + 'methods', 'global', 'persistent', 'endfor', 'endwhile', 'printf', 'sprintf', 'disp', 'until', + 'continue', 'pkg' + ]); + + + // tokenizers + function tokenTranspose(stream, state) { + if (!stream.sol() && stream.peek() === '\'') { + stream.next(); + state.tokenize = tokenBase; + return 'operator'; + } + state.tokenize = tokenBase; + return tokenBase(stream, state); + } + + + function tokenComment(stream, state) { + if (stream.match(/^.*%}/)) { + state.tokenize = tokenBase; + return 'comment'; + }; + stream.skipToEnd(); + return 'comment'; + } + + function tokenBase(stream, state) { + // whitespaces + if (stream.eatSpace()) return null; + + // Handle one line Comments + if (stream.match('%{')){ + state.tokenize = tokenComment; + stream.skipToEnd(); + return 'comment'; + } + + if (stream.match(/^[%#]/)){ + stream.skipToEnd(); + return 'comment'; + } + + // Handle Number Literals + if (stream.match(/^[0-9\.+-]/, false)) { + if (stream.match(/^[+-]?0x[0-9a-fA-F]+[ij]?/)) { + stream.tokenize = tokenBase; + return 'number'; }; + if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; }; + if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; }; + } + if (stream.match(wordRegexp(['nan','NaN','inf','Inf']))) { return 'number'; }; + + // Handle Strings + var m = stream.match(/^"(?:[^"]|"")*("|$)/) || stream.match(/^'(?:[^']|'')*('|$)/) + if (m) { return m[1] ? 'string' : "string error"; } + + // Handle words + if (stream.match(keywords)) { return 'keyword'; } ; + if (stream.match(builtins)) { return 'builtin'; } ; + if (stream.match(identifiers)) { return 'variable'; } ; + + if (stream.match(singleOperators) || stream.match(doubleOperators)) { return 'operator'; }; + if (stream.match(singleDelimiters) || stream.match(doubleDelimiters) || stream.match(tripleDelimiters)) { return null; }; + + if (stream.match(expressionEnd)) { + state.tokenize = tokenTranspose; + return null; + }; + + + // Handle non-detected items + stream.next(); + return 'error'; + }; + + + return { + startState: function() { + return { + tokenize: tokenBase + }; + }, + + token: function(stream, state) { + var style = state.tokenize(stream, state); + if (style === 'number' || style === 'variable'){ + state.tokenize = tokenTranspose; + } + return style; + }, + + lineComment: '%', + + fold: 'indent' + }; +}); + +CodeMirror.defineMIME("text/x-octave", "octave"); + +}); diff --git a/backend/webif/static/codemirror/mode/oz/index.html b/backend/webif/static/codemirror/mode/oz/index.html new file mode 100755 index 000000000..febd82a59 --- /dev/null +++ b/backend/webif/static/codemirror/mode/oz/index.html @@ -0,0 +1,59 @@ + + +CodeMirror: Oz mode + + + + + + + + + + +
+

Oz mode

+ +

MIME type defined: text/x-oz.

+ + +
diff --git a/backend/webif/static/codemirror/mode/oz/oz.js b/backend/webif/static/codemirror/mode/oz/oz.js new file mode 100755 index 000000000..50ffda37a --- /dev/null +++ b/backend/webif/static/codemirror/mode/oz/oz.js @@ -0,0 +1,252 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("oz", function (conf) { + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + var singleOperators = /[\^@!\|<>#~\.\*\-\+\\/,=]/; + var doubleOperators = /(<-)|(:=)|(=<)|(>=)|(<=)|(<:)|(>:)|(=:)|(\\=)|(\\=:)|(!!)|(==)|(::)/; + var tripleOperators = /(:::)|(\.\.\.)|(=<:)|(>=:)/; + + var middle = ["in", "then", "else", "of", "elseof", "elsecase", "elseif", "catch", + "finally", "with", "require", "prepare", "import", "export", "define", "do"]; + var end = ["end"]; + + var atoms = wordRegexp(["true", "false", "nil", "unit"]); + var commonKeywords = wordRegexp(["andthen", "at", "attr", "declare", "feat", "from", "lex", + "mod", "div", "mode", "orelse", "parser", "prod", "prop", "scanner", "self", "syn", "token"]); + var openingKeywords = wordRegexp(["local", "proc", "fun", "case", "class", "if", "cond", "or", "dis", + "choice", "not", "thread", "try", "raise", "lock", "for", "suchthat", "meth", "functor"]); + var middleKeywords = wordRegexp(middle); + var endKeywords = wordRegexp(end); + + // Tokenizers + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return null; + } + + // Brackets + if(stream.match(/[{}]/)) { + return "bracket"; + } + + // Special [] keyword + if (stream.match(/(\[])/)) { + return "keyword" + } + + // Operators + if (stream.match(tripleOperators) || stream.match(doubleOperators)) { + return "operator"; + } + + // Atoms + if(stream.match(atoms)) { + return 'atom'; + } + + // Opening keywords + var matched = stream.match(openingKeywords); + if (matched) { + if (!state.doInCurrentLine) + state.currentIndent++; + else + state.doInCurrentLine = false; + + // Special matching for signatures + if(matched[0] == "proc" || matched[0] == "fun") + state.tokenize = tokenFunProc; + else if(matched[0] == "class") + state.tokenize = tokenClass; + else if(matched[0] == "meth") + state.tokenize = tokenMeth; + + return 'keyword'; + } + + // Middle and other keywords + if (stream.match(middleKeywords) || stream.match(commonKeywords)) { + return "keyword" + } + + // End keywords + if (stream.match(endKeywords)) { + state.currentIndent--; + return 'keyword'; + } + + // Eat the next char for next comparisons + var ch = stream.next(); + + // Strings + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + + // Numbers + if (/[~\d]/.test(ch)) { + if (ch == "~") { + if(! /^[0-9]/.test(stream.peek())) + return null; + else if (( stream.next() == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) || stream.match(/^[0-9]*(\.[0-9]+)?([eE][~+]?[0-9]+)?/)) + return "number"; + } + + if ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) || stream.match(/^[0-9]*(\.[0-9]+)?([eE][~+]?[0-9]+)?/)) + return "number"; + + return null; + } + + // Comments + if (ch == "%") { + stream.skipToEnd(); + return 'comment'; + } + else if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + } + + // Single operators + if(singleOperators.test(ch)) { + return "operator"; + } + + // If nothing match, we skip the entire alphanumerical block + stream.eatWhile(/\w/); + + return "variable"; + } + + function tokenClass(stream, state) { + if (stream.eatSpace()) { + return null; + } + stream.match(/([A-Z][A-Za-z0-9_]*)|(`.+`)/); + state.tokenize = tokenBase; + return "variable-3" + } + + function tokenMeth(stream, state) { + if (stream.eatSpace()) { + return null; + } + stream.match(/([a-zA-Z][A-Za-z0-9_]*)|(`.+`)/); + state.tokenize = tokenBase; + return "def" + } + + function tokenFunProc(stream, state) { + if (stream.eatSpace()) { + return null; + } + + if(!state.hasPassedFirstStage && stream.eat("{")) { + state.hasPassedFirstStage = true; + return "bracket"; + } + else if(state.hasPassedFirstStage) { + stream.match(/([A-Z][A-Za-z0-9_]*)|(`.+`)|\$/); + state.hasPassedFirstStage = false; + state.tokenize = tokenBase; + return "def" + } + else { + state.tokenize = tokenBase; + return null; + } + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenString(quote) { + return function (stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end || !escaped) + state.tokenize = tokenBase; + return "string"; + }; + } + + function buildElectricInputRegEx() { + // Reindentation should occur on [] or on a match of any of + // the block closing keywords, at the end of a line. + var allClosings = middle.concat(end); + return new RegExp("[\\[\\]]|(" + allClosings.join("|") + ")$"); + } + + return { + + startState: function () { + return { + tokenize: tokenBase, + currentIndent: 0, + doInCurrentLine: false, + hasPassedFirstStage: false + }; + }, + + token: function (stream, state) { + if (stream.sol()) + state.doInCurrentLine = 0; + + return state.tokenize(stream, state); + }, + + indent: function (state, textAfter) { + var trueText = textAfter.replace(/^\s+|\s+$/g, ''); + + if (trueText.match(endKeywords) || trueText.match(middleKeywords) || trueText.match(/(\[])/)) + return conf.indentUnit * (state.currentIndent - 1); + + if (state.currentIndent < 0) + return 0; + + return state.currentIndent * conf.indentUnit; + }, + fold: "indent", + electricInput: buildElectricInputRegEx(), + lineComment: "%", + blockCommentStart: "/*", + blockCommentEnd: "*/" + }; +}); + +CodeMirror.defineMIME("text/x-oz", "oz"); + +}); diff --git a/backend/webif/static/codemirror/mode/pascal/index.html b/backend/webif/static/codemirror/mode/pascal/index.html new file mode 100755 index 000000000..f8a99ad01 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pascal/index.html @@ -0,0 +1,61 @@ + + +CodeMirror: Pascal mode + + + + + + + + + +
+

Pascal mode

+ + +
+ + + +

MIME types defined: text/x-pascal.

+
diff --git a/backend/webif/static/codemirror/mode/pascal/pascal.js b/backend/webif/static/codemirror/mode/pascal/pascal.js new file mode 100755 index 000000000..2d0c3d424 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pascal/pascal.js @@ -0,0 +1,109 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("pascal", function() { + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var keywords = words("and array begin case const div do downto else end file for forward integer " + + "boolean char function goto if in label mod nil not of or packed procedure " + + "program record repeat set string then to type until var while with"); + var atoms = {"null": true}; + + var isOperatorChar = /[+\-*&%=<>!?|\/]/; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == "#" && state.startOfLine) { + stream.skipToEnd(); + return "meta"; + } + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (ch == "(" && stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return null; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (ch == "/") { + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_]/); + var cur = stream.current(); + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + if (atoms.propertyIsEnumerable(cur)) return "atom"; + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !escaped) state.tokenize = null; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == ")" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + // Interface + + return { + startState: function() { + return {tokenize: null}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + return style; + }, + + electricChars: "{}" + }; +}); + +CodeMirror.defineMIME("text/x-pascal", "pascal"); + +}); diff --git a/backend/webif/static/codemirror/mode/pegjs/index.html b/backend/webif/static/codemirror/mode/pegjs/index.html new file mode 100755 index 000000000..0c7460488 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pegjs/index.html @@ -0,0 +1,66 @@ + + + + CodeMirror: PEG.js Mode + + + + + + + + + + + + +
+

PEG.js Mode

+
+ +

The PEG.js Mode

+

Created by Forbes Lindesay.

+
+ + diff --git a/backend/webif/static/codemirror/mode/pegjs/pegjs.js b/backend/webif/static/codemirror/mode/pegjs/pegjs.js new file mode 100755 index 000000000..6c7207466 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pegjs/pegjs.js @@ -0,0 +1,114 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../javascript/javascript")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../javascript/javascript"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("pegjs", function (config) { + var jsMode = CodeMirror.getMode(config, "javascript"); + + function identifier(stream) { + return stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/); + } + + return { + startState: function () { + return { + inString: false, + stringType: null, + inComment: false, + inCharacterClass: false, + braced: 0, + lhs: true, + localState: null + }; + }, + token: function (stream, state) { + if (stream) + + //check for state changes + if (!state.inString && !state.inComment && ((stream.peek() == '"') || (stream.peek() == "'"))) { + state.stringType = stream.peek(); + stream.next(); // Skip quote + state.inString = true; // Update state + } + if (!state.inString && !state.inComment && stream.match(/^\/\*/)) { + state.inComment = true; + } + + //return state + if (state.inString) { + while (state.inString && !stream.eol()) { + if (stream.peek() === state.stringType) { + stream.next(); // Skip quote + state.inString = false; // Clear flag + } else if (stream.peek() === '\\') { + stream.next(); + stream.next(); + } else { + stream.match(/^.[^\\\"\']*/); + } + } + return state.lhs ? "property string" : "string"; // Token style + } else if (state.inComment) { + while (state.inComment && !stream.eol()) { + if (stream.match(/\*\//)) { + state.inComment = false; // Clear flag + } else { + stream.match(/^.[^\*]*/); + } + } + return "comment"; + } else if (state.inCharacterClass) { + while (state.inCharacterClass && !stream.eol()) { + if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) { + state.inCharacterClass = false; + } + } + } else if (stream.peek() === '[') { + stream.next(); + state.inCharacterClass = true; + return 'bracket'; + } else if (stream.match(/^\/\//)) { + stream.skipToEnd(); + return "comment"; + } else if (state.braced || stream.peek() === '{') { + if (state.localState === null) { + state.localState = CodeMirror.startState(jsMode); + } + var token = jsMode.token(stream, state.localState); + var text = stream.current(); + if (!token) { + for (var i = 0; i < text.length; i++) { + if (text[i] === '{') { + state.braced++; + } else if (text[i] === '}') { + state.braced--; + } + }; + } + return token; + } else if (identifier(stream)) { + if (stream.peek() === ':') { + return 'variable'; + } + return 'variable-2'; + } else if (['[', ']', '(', ')'].indexOf(stream.peek()) != -1) { + stream.next(); + return 'bracket'; + } else if (!stream.eatSpace()) { + stream.next(); + } + return null; + } + }; +}, "javascript"); + +}); diff --git a/backend/webif/static/codemirror/mode/perl/index.html b/backend/webif/static/codemirror/mode/perl/index.html new file mode 100755 index 000000000..8c1021c42 --- /dev/null +++ b/backend/webif/static/codemirror/mode/perl/index.html @@ -0,0 +1,75 @@ + + +CodeMirror: Perl mode + + + + + + + + + +
+

Perl mode

+ + +
+ + + +

MIME types defined: text/x-perl.

+
diff --git a/backend/webif/static/codemirror/mode/perl/perl.js b/backend/webif/static/codemirror/mode/perl/perl.js new file mode 100755 index 000000000..66e4ed034 --- /dev/null +++ b/backend/webif/static/codemirror/mode/perl/perl.js @@ -0,0 +1,837 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08) +// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com) + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("perl",function(){ + // http://perldoc.perl.org + var PERL={ // null - magic touch + // 1 - keyword + // 2 - def + // 3 - atom + // 4 - operator + // 5 - variable-2 (predefined) + // [x,y] - x=1,2,3; y=must be defined if x{...} + // PERL operators + '->' : 4, + '++' : 4, + '--' : 4, + '**' : 4, + // ! ~ \ and unary + and - + '=~' : 4, + '!~' : 4, + '*' : 4, + '/' : 4, + '%' : 4, + 'x' : 4, + '+' : 4, + '-' : 4, + '.' : 4, + '<<' : 4, + '>>' : 4, + // named unary operators + '<' : 4, + '>' : 4, + '<=' : 4, + '>=' : 4, + 'lt' : 4, + 'gt' : 4, + 'le' : 4, + 'ge' : 4, + '==' : 4, + '!=' : 4, + '<=>' : 4, + 'eq' : 4, + 'ne' : 4, + 'cmp' : 4, + '~~' : 4, + '&' : 4, + '|' : 4, + '^' : 4, + '&&' : 4, + '||' : 4, + '//' : 4, + '..' : 4, + '...' : 4, + '?' : 4, + ':' : 4, + '=' : 4, + '+=' : 4, + '-=' : 4, + '*=' : 4, // etc. ??? + ',' : 4, + '=>' : 4, + '::' : 4, + // list operators (rightward) + 'not' : 4, + 'and' : 4, + 'or' : 4, + 'xor' : 4, + // PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;) + 'BEGIN' : [5,1], + 'END' : [5,1], + 'PRINT' : [5,1], + 'PRINTF' : [5,1], + 'GETC' : [5,1], + 'READ' : [5,1], + 'READLINE' : [5,1], + 'DESTROY' : [5,1], + 'TIE' : [5,1], + 'TIEHANDLE' : [5,1], + 'UNTIE' : [5,1], + 'STDIN' : 5, + 'STDIN_TOP' : 5, + 'STDOUT' : 5, + 'STDOUT_TOP' : 5, + 'STDERR' : 5, + 'STDERR_TOP' : 5, + '$ARG' : 5, + '$_' : 5, + '@ARG' : 5, + '@_' : 5, + '$LIST_SEPARATOR' : 5, + '$"' : 5, + '$PROCESS_ID' : 5, + '$PID' : 5, + '$$' : 5, + '$REAL_GROUP_ID' : 5, + '$GID' : 5, + '$(' : 5, + '$EFFECTIVE_GROUP_ID' : 5, + '$EGID' : 5, + '$)' : 5, + '$PROGRAM_NAME' : 5, + '$0' : 5, + '$SUBSCRIPT_SEPARATOR' : 5, + '$SUBSEP' : 5, + '$;' : 5, + '$REAL_USER_ID' : 5, + '$UID' : 5, + '$<' : 5, + '$EFFECTIVE_USER_ID' : 5, + '$EUID' : 5, + '$>' : 5, + '$a' : 5, + '$b' : 5, + '$COMPILING' : 5, + '$^C' : 5, + '$DEBUGGING' : 5, + '$^D' : 5, + '${^ENCODING}' : 5, + '$ENV' : 5, + '%ENV' : 5, + '$SYSTEM_FD_MAX' : 5, + '$^F' : 5, + '@F' : 5, + '${^GLOBAL_PHASE}' : 5, + '$^H' : 5, + '%^H' : 5, + '@INC' : 5, + '%INC' : 5, + '$INPLACE_EDIT' : 5, + '$^I' : 5, + '$^M' : 5, + '$OSNAME' : 5, + '$^O' : 5, + '${^OPEN}' : 5, + '$PERLDB' : 5, + '$^P' : 5, + '$SIG' : 5, + '%SIG' : 5, + '$BASETIME' : 5, + '$^T' : 5, + '${^TAINT}' : 5, + '${^UNICODE}' : 5, + '${^UTF8CACHE}' : 5, + '${^UTF8LOCALE}' : 5, + '$PERL_VERSION' : 5, + '$^V' : 5, + '${^WIN32_SLOPPY_STAT}' : 5, + '$EXECUTABLE_NAME' : 5, + '$^X' : 5, + '$1' : 5, // - regexp $1, $2... + '$MATCH' : 5, + '$&' : 5, + '${^MATCH}' : 5, + '$PREMATCH' : 5, + '$`' : 5, + '${^PREMATCH}' : 5, + '$POSTMATCH' : 5, + "$'" : 5, + '${^POSTMATCH}' : 5, + '$LAST_PAREN_MATCH' : 5, + '$+' : 5, + '$LAST_SUBMATCH_RESULT' : 5, + '$^N' : 5, + '@LAST_MATCH_END' : 5, + '@+' : 5, + '%LAST_PAREN_MATCH' : 5, + '%+' : 5, + '@LAST_MATCH_START' : 5, + '@-' : 5, + '%LAST_MATCH_START' : 5, + '%-' : 5, + '$LAST_REGEXP_CODE_RESULT' : 5, + '$^R' : 5, + '${^RE_DEBUG_FLAGS}' : 5, + '${^RE_TRIE_MAXBUF}' : 5, + '$ARGV' : 5, + '@ARGV' : 5, + 'ARGV' : 5, + 'ARGVOUT' : 5, + '$OUTPUT_FIELD_SEPARATOR' : 5, + '$OFS' : 5, + '$,' : 5, + '$INPUT_LINE_NUMBER' : 5, + '$NR' : 5, + '$.' : 5, + '$INPUT_RECORD_SEPARATOR' : 5, + '$RS' : 5, + '$/' : 5, + '$OUTPUT_RECORD_SEPARATOR' : 5, + '$ORS' : 5, + '$\\' : 5, + '$OUTPUT_AUTOFLUSH' : 5, + '$|' : 5, + '$ACCUMULATOR' : 5, + '$^A' : 5, + '$FORMAT_FORMFEED' : 5, + '$^L' : 5, + '$FORMAT_PAGE_NUMBER' : 5, + '$%' : 5, + '$FORMAT_LINES_LEFT' : 5, + '$-' : 5, + '$FORMAT_LINE_BREAK_CHARACTERS' : 5, + '$:' : 5, + '$FORMAT_LINES_PER_PAGE' : 5, + '$=' : 5, + '$FORMAT_TOP_NAME' : 5, + '$^' : 5, + '$FORMAT_NAME' : 5, + '$~' : 5, + '${^CHILD_ERROR_NATIVE}' : 5, + '$EXTENDED_OS_ERROR' : 5, + '$^E' : 5, + '$EXCEPTIONS_BEING_CAUGHT' : 5, + '$^S' : 5, + '$WARNING' : 5, + '$^W' : 5, + '${^WARNING_BITS}' : 5, + '$OS_ERROR' : 5, + '$ERRNO' : 5, + '$!' : 5, + '%OS_ERROR' : 5, + '%ERRNO' : 5, + '%!' : 5, + '$CHILD_ERROR' : 5, + '$?' : 5, + '$EVAL_ERROR' : 5, + '$@' : 5, + '$OFMT' : 5, + '$#' : 5, + '$*' : 5, + '$ARRAY_BASE' : 5, + '$[' : 5, + '$OLD_PERL_VERSION' : 5, + '$]' : 5, + // PERL blocks + 'if' :[1,1], + elsif :[1,1], + 'else' :[1,1], + 'while' :[1,1], + unless :[1,1], + 'for' :[1,1], + foreach :[1,1], + // PERL functions + 'abs' :1, // - absolute value function + accept :1, // - accept an incoming socket connect + alarm :1, // - schedule a SIGALRM + 'atan2' :1, // - arctangent of Y/X in the range -PI to PI + bind :1, // - binds an address to a socket + binmode :1, // - prepare binary files for I/O + bless :1, // - create an object + bootstrap :1, // + 'break' :1, // - break out of a "given" block + caller :1, // - get context of the current subroutine call + chdir :1, // - change your current working directory + chmod :1, // - changes the permissions on a list of files + chomp :1, // - remove a trailing record separator from a string + chop :1, // - remove the last character from a string + chown :1, // - change the ownership on a list of files + chr :1, // - get character this number represents + chroot :1, // - make directory new root for path lookups + close :1, // - close file (or pipe or socket) handle + closedir :1, // - close directory handle + connect :1, // - connect to a remote socket + 'continue' :[1,1], // - optional trailing block in a while or foreach + 'cos' :1, // - cosine function + crypt :1, // - one-way passwd-style encryption + dbmclose :1, // - breaks binding on a tied dbm file + dbmopen :1, // - create binding on a tied dbm file + 'default' :1, // + defined :1, // - test whether a value, variable, or function is defined + 'delete' :1, // - deletes a value from a hash + die :1, // - raise an exception or bail out + 'do' :1, // - turn a BLOCK into a TERM + dump :1, // - create an immediate core dump + each :1, // - retrieve the next key/value pair from a hash + endgrent :1, // - be done using group file + endhostent :1, // - be done using hosts file + endnetent :1, // - be done using networks file + endprotoent :1, // - be done using protocols file + endpwent :1, // - be done using passwd file + endservent :1, // - be done using services file + eof :1, // - test a filehandle for its end + 'eval' :1, // - catch exceptions or compile and run code + 'exec' :1, // - abandon this program to run another + exists :1, // - test whether a hash key is present + exit :1, // - terminate this program + 'exp' :1, // - raise I to a power + fcntl :1, // - file control system call + fileno :1, // - return file descriptor from filehandle + flock :1, // - lock an entire file with an advisory lock + fork :1, // - create a new process just like this one + format :1, // - declare a picture format with use by the write() function + formline :1, // - internal function used for formats + getc :1, // - get the next character from the filehandle + getgrent :1, // - get next group record + getgrgid :1, // - get group record given group user ID + getgrnam :1, // - get group record given group name + gethostbyaddr :1, // - get host record given its address + gethostbyname :1, // - get host record given name + gethostent :1, // - get next hosts record + getlogin :1, // - return who logged in at this tty + getnetbyaddr :1, // - get network record given its address + getnetbyname :1, // - get networks record given name + getnetent :1, // - get next networks record + getpeername :1, // - find the other end of a socket connection + getpgrp :1, // - get process group + getppid :1, // - get parent process ID + getpriority :1, // - get current nice value + getprotobyname :1, // - get protocol record given name + getprotobynumber :1, // - get protocol record numeric protocol + getprotoent :1, // - get next protocols record + getpwent :1, // - get next passwd record + getpwnam :1, // - get passwd record given user login name + getpwuid :1, // - get passwd record given user ID + getservbyname :1, // - get services record given its name + getservbyport :1, // - get services record given numeric port + getservent :1, // - get next services record + getsockname :1, // - retrieve the sockaddr for a given socket + getsockopt :1, // - get socket options on a given socket + given :1, // + glob :1, // - expand filenames using wildcards + gmtime :1, // - convert UNIX time into record or string using Greenwich time + 'goto' :1, // - create spaghetti code + grep :1, // - locate elements in a list test true against a given criterion + hex :1, // - convert a string to a hexadecimal number + 'import' :1, // - patch a module's namespace into your own + index :1, // - find a substring within a string + 'int' :1, // - get the integer portion of a number + ioctl :1, // - system-dependent device control system call + 'join' :1, // - join a list into a string using a separator + keys :1, // - retrieve list of indices from a hash + kill :1, // - send a signal to a process or process group + last :1, // - exit a block prematurely + lc :1, // - return lower-case version of a string + lcfirst :1, // - return a string with just the next letter in lower case + length :1, // - return the number of bytes in a string + 'link' :1, // - create a hard link in the filesytem + listen :1, // - register your socket as a server + local : 2, // - create a temporary value for a global variable (dynamic scoping) + localtime :1, // - convert UNIX time into record or string using local time + lock :1, // - get a thread lock on a variable, subroutine, or method + 'log' :1, // - retrieve the natural logarithm for a number + lstat :1, // - stat a symbolic link + m :null, // - match a string with a regular expression pattern + map :1, // - apply a change to a list to get back a new list with the changes + mkdir :1, // - create a directory + msgctl :1, // - SysV IPC message control operations + msgget :1, // - get SysV IPC message queue + msgrcv :1, // - receive a SysV IPC message from a message queue + msgsnd :1, // - send a SysV IPC message to a message queue + my : 2, // - declare and assign a local variable (lexical scoping) + 'new' :1, // + next :1, // - iterate a block prematurely + no :1, // - unimport some module symbols or semantics at compile time + oct :1, // - convert a string to an octal number + open :1, // - open a file, pipe, or descriptor + opendir :1, // - open a directory + ord :1, // - find a character's numeric representation + our : 2, // - declare and assign a package variable (lexical scoping) + pack :1, // - convert a list into a binary representation + 'package' :1, // - declare a separate global namespace + pipe :1, // - open a pair of connected filehandles + pop :1, // - remove the last element from an array and return it + pos :1, // - find or set the offset for the last/next m//g search + print :1, // - output a list to a filehandle + printf :1, // - output a formatted list to a filehandle + prototype :1, // - get the prototype (if any) of a subroutine + push :1, // - append one or more elements to an array + q :null, // - singly quote a string + qq :null, // - doubly quote a string + qr :null, // - Compile pattern + quotemeta :null, // - quote regular expression magic characters + qw :null, // - quote a list of words + qx :null, // - backquote quote a string + rand :1, // - retrieve the next pseudorandom number + read :1, // - fixed-length buffered input from a filehandle + readdir :1, // - get a directory from a directory handle + readline :1, // - fetch a record from a file + readlink :1, // - determine where a symbolic link is pointing + readpipe :1, // - execute a system command and collect standard output + recv :1, // - receive a message over a Socket + redo :1, // - start this loop iteration over again + ref :1, // - find out the type of thing being referenced + rename :1, // - change a filename + require :1, // - load in external functions from a library at runtime + reset :1, // - clear all variables of a given name + 'return' :1, // - get out of a function early + reverse :1, // - flip a string or a list + rewinddir :1, // - reset directory handle + rindex :1, // - right-to-left substring search + rmdir :1, // - remove a directory + s :null, // - replace a pattern with a string + say :1, // - print with newline + scalar :1, // - force a scalar context + seek :1, // - reposition file pointer for random-access I/O + seekdir :1, // - reposition directory pointer + select :1, // - reset default output or do I/O multiplexing + semctl :1, // - SysV semaphore control operations + semget :1, // - get set of SysV semaphores + semop :1, // - SysV semaphore operations + send :1, // - send a message over a socket + setgrent :1, // - prepare group file for use + sethostent :1, // - prepare hosts file for use + setnetent :1, // - prepare networks file for use + setpgrp :1, // - set the process group of a process + setpriority :1, // - set a process's nice value + setprotoent :1, // - prepare protocols file for use + setpwent :1, // - prepare passwd file for use + setservent :1, // - prepare services file for use + setsockopt :1, // - set some socket options + shift :1, // - remove the first element of an array, and return it + shmctl :1, // - SysV shared memory operations + shmget :1, // - get SysV shared memory segment identifier + shmread :1, // - read SysV shared memory + shmwrite :1, // - write SysV shared memory + shutdown :1, // - close down just half of a socket connection + 'sin' :1, // - return the sine of a number + sleep :1, // - block for some number of seconds + socket :1, // - create a socket + socketpair :1, // - create a pair of sockets + 'sort' :1, // - sort a list of values + splice :1, // - add or remove elements anywhere in an array + 'split' :1, // - split up a string using a regexp delimiter + sprintf :1, // - formatted print into a string + 'sqrt' :1, // - square root function + srand :1, // - seed the random number generator + stat :1, // - get a file's status information + state :1, // - declare and assign a state variable (persistent lexical scoping) + study :1, // - optimize input data for repeated searches + 'sub' :1, // - declare a subroutine, possibly anonymously + 'substr' :1, // - get or alter a portion of a stirng + symlink :1, // - create a symbolic link to a file + syscall :1, // - execute an arbitrary system call + sysopen :1, // - open a file, pipe, or descriptor + sysread :1, // - fixed-length unbuffered input from a filehandle + sysseek :1, // - position I/O pointer on handle used with sysread and syswrite + system :1, // - run a separate program + syswrite :1, // - fixed-length unbuffered output to a filehandle + tell :1, // - get current seekpointer on a filehandle + telldir :1, // - get current seekpointer on a directory handle + tie :1, // - bind a variable to an object class + tied :1, // - get a reference to the object underlying a tied variable + time :1, // - return number of seconds since 1970 + times :1, // - return elapsed time for self and child processes + tr :null, // - transliterate a string + truncate :1, // - shorten a file + uc :1, // - return upper-case version of a string + ucfirst :1, // - return a string with just the next letter in upper case + umask :1, // - set file creation mode mask + undef :1, // - remove a variable or function definition + unlink :1, // - remove one link to a file + unpack :1, // - convert binary structure into normal perl variables + unshift :1, // - prepend more elements to the beginning of a list + untie :1, // - break a tie binding to a variable + use :1, // - load in a module at compile time + utime :1, // - set a file's last access and modify times + values :1, // - return a list of the values in a hash + vec :1, // - test or set particular bits in a string + wait :1, // - wait for any child process to die + waitpid :1, // - wait for a particular child process to die + wantarray :1, // - get void vs scalar vs list context of current subroutine call + warn :1, // - print debugging info + when :1, // + write :1, // - print a picture record + y :null}; // - transliterate a string + + var RXstyle="string-2"; + var RXmodifiers=/[goseximacplud]/; // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type + + function tokenChain(stream,state,chain,style,tail){ // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;) + state.chain=null; // 12 3tail + state.style=null; + state.tail=null; + state.tokenize=function(stream,state){ + var e=false,c,i=0; + while(c=stream.next()){ + if(c===chain[i]&&!e){ + if(chain[++i]!==undefined){ + state.chain=chain[i]; + state.style=style; + state.tail=tail;} + else if(tail) + stream.eatWhile(tail); + state.tokenize=tokenPerl; + return style;} + e=!e&&c=="\\";} + return style;}; + return state.tokenize(stream,state);} + + function tokenSOMETHING(stream,state,string){ + state.tokenize=function(stream,state){ + if(stream.string==string) + state.tokenize=tokenPerl; + stream.skipToEnd(); + return "string";}; + return state.tokenize(stream,state);} + + function tokenPerl(stream,state){ + if(stream.eatSpace()) + return null; + if(state.chain) + return tokenChain(stream,state,state.chain,state.style,state.tail); + if(stream.match(/^\-?[\d\.]/,false)) + if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/)) + return 'number'; + if(stream.match(/^<<(?=\w)/)){ // NOTE: <"],RXstyle,RXmodifiers);} + if(/[\^'"!~\/]/.test(c)){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}} + else if(c=="q"){ + c=look(stream, 1); + if(c=="("){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[")"],"string");} + if(c=="["){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["]"],"string");} + if(c=="{"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["}"],"string");} + if(c=="<"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[">"],"string");} + if(/[\^'"!~\/]/.test(c)){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[stream.eat(c)],"string");}} + else if(c=="w"){ + c=look(stream, 1); + if(c=="("){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[")"],"bracket");} + if(c=="["){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["]"],"bracket");} + if(c=="{"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["}"],"bracket");} + if(c=="<"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[">"],"bracket");} + if(/[\^'"!~\/]/.test(c)){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[stream.eat(c)],"bracket");}} + else if(c=="r"){ + c=look(stream, 1); + if(c=="("){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);} + if(c=="["){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);} + if(c=="{"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);} + if(c=="<"){ + eatSuffix(stream, 2); + return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);} + if(/[\^'"!~\/]/.test(c)){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}} + else if(/[\^'"!~\/(\[{<]/.test(c)){ + if(c=="("){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[")"],"string");} + if(c=="["){ + eatSuffix(stream, 1); + return tokenChain(stream,state,["]"],"string");} + if(c=="{"){ + eatSuffix(stream, 1); + return tokenChain(stream,state,["}"],"string");} + if(c=="<"){ + eatSuffix(stream, 1); + return tokenChain(stream,state,[">"],"string");} + if(/[\^'"!~\/]/.test(c)){ + return tokenChain(stream,state,[stream.eat(c)],"string");}}}} + if(ch=="m"){ + var c=look(stream, -2); + if(!(c&&/\w/.test(c))){ + c=stream.eat(/[(\[{<\^'"!~\/]/); + if(c){ + if(/[\^'"!~\/]/.test(c)){ + return tokenChain(stream,state,[c],RXstyle,RXmodifiers);} + if(c=="("){ + return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);} + if(c=="["){ + return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);} + if(c=="{"){ + return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);} + if(c=="<"){ + return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}} + if(ch=="s"){ + var c=/[\/>\]})\w]/.test(look(stream, -2)); + if(!c){ + c=stream.eat(/[(\[{<\^'"!~\/]/); + if(c){ + if(c=="[") + return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers); + if(c=="{") + return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers); + if(c=="<") + return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers); + if(c=="(") + return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers); + return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}} + if(ch=="y"){ + var c=/[\/>\]})\w]/.test(look(stream, -2)); + if(!c){ + c=stream.eat(/[(\[{<\^'"!~\/]/); + if(c){ + if(c=="[") + return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers); + if(c=="{") + return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers); + if(c=="<") + return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers); + if(c=="(") + return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers); + return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}} + if(ch=="t"){ + var c=/[\/>\]})\w]/.test(look(stream, -2)); + if(!c){ + c=stream.eat("r");if(c){ + c=stream.eat(/[(\[{<\^'"!~\/]/); + if(c){ + if(c=="[") + return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers); + if(c=="{") + return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers); + if(c=="<") + return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers); + if(c=="(") + return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers); + return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}} + if(ch=="`"){ + return tokenChain(stream,state,[ch],"variable-2");} + if(ch=="/"){ + if(!/~\s*$/.test(prefix(stream))) + return "operator"; + else + return tokenChain(stream,state,[ch],RXstyle,RXmodifiers);} + if(ch=="$"){ + var p=stream.pos; + if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}")) + return "variable-2"; + else + stream.pos=p;} + if(/[$@%]/.test(ch)){ + var p=stream.pos; + if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(look(stream, -2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){ + var c=stream.current(); + if(PERL[c]) + return "variable-2";} + stream.pos=p;} + if(/[$@%&]/.test(ch)){ + if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){ + var c=stream.current(); + if(PERL[c]) + return "variable-2"; + else + return "variable";}} + if(ch=="#"){ + if(look(stream, -2)!="$"){ + stream.skipToEnd(); + return "comment";}} + if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){ + var p=stream.pos; + stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/); + if(PERL[stream.current()]) + return "operator"; + else + stream.pos=p;} + if(ch=="_"){ + if(stream.pos==1){ + if(suffix(stream, 6)=="_END__"){ + return tokenChain(stream,state,['\0'],"comment");} + else if(suffix(stream, 7)=="_DATA__"){ + return tokenChain(stream,state,['\0'],"variable-2");} + else if(suffix(stream, 7)=="_C__"){ + return tokenChain(stream,state,['\0'],"string");}}} + if(/\w/.test(ch)){ + var p=stream.pos; + if(look(stream, -2)=="{"&&(look(stream, 0)=="}"||stream.eatWhile(/\w/)&&look(stream, 0)=="}")) + return "string"; + else + stream.pos=p;} + if(/[A-Z]/.test(ch)){ + var l=look(stream, -2); + var p=stream.pos; + stream.eatWhile(/[A-Z_]/); + if(/[\da-z]/.test(look(stream, 0))){ + stream.pos=p;} + else{ + var c=PERL[stream.current()]; + if(!c) + return "meta"; + if(c[1]) + c=c[0]; + if(l!=":"){ + if(c==1) + return "keyword"; + else if(c==2) + return "def"; + else if(c==3) + return "atom"; + else if(c==4) + return "operator"; + else if(c==5) + return "variable-2"; + else + return "meta";} + else + return "meta";}} + if(/[a-zA-Z_]/.test(ch)){ + var l=look(stream, -2); + stream.eatWhile(/\w/); + var c=PERL[stream.current()]; + if(!c) + return "meta"; + if(c[1]) + c=c[0]; + if(l!=":"){ + if(c==1) + return "keyword"; + else if(c==2) + return "def"; + else if(c==3) + return "atom"; + else if(c==4) + return "operator"; + else if(c==5) + return "variable-2"; + else + return "meta";} + else + return "meta";} + return null;} + + return { + startState: function() { + return { + tokenize: tokenPerl, + chain: null, + style: null, + tail: null + }; + }, + token: function(stream, state) { + return (state.tokenize || tokenPerl)(stream, state); + }, + lineComment: '#' + }; +}); + +CodeMirror.registerHelper("wordChars", "perl", /[\w$]/); + +CodeMirror.defineMIME("text/x-perl", "perl"); + +// it's like "peek", but need for look-ahead or look-behind if index < 0 +function look(stream, c){ + return stream.string.charAt(stream.pos+(c||0)); +} + +// return a part of prefix of current stream from current position +function prefix(stream, c){ + if(c){ + var x=stream.pos-c; + return stream.string.substr((x>=0?x:0),c);} + else{ + return stream.string.substr(0,stream.pos-1); + } +} + +// return a part of suffix of current stream from current position +function suffix(stream, c){ + var y=stream.string.length; + var x=y-stream.pos+1; + return stream.string.substr(stream.pos,(c&&c=(y=stream.string.length-1)) + stream.pos=y; + else + stream.pos=x; +} + +}); diff --git a/backend/webif/static/codemirror/mode/php/index.html b/backend/webif/static/codemirror/mode/php/index.html new file mode 100755 index 000000000..adf6b1be2 --- /dev/null +++ b/backend/webif/static/codemirror/mode/php/index.html @@ -0,0 +1,64 @@ + + +CodeMirror: PHP mode + + + + + + + + + + + + + + + +
+

PHP mode

+
+ + + +

Simple HTML/PHP mode based on + the C-like mode. Depends on XML, + JavaScript, CSS, HTMLMixed, and C-like modes.

+ +

MIME types defined: application/x-httpd-php (HTML with PHP code), text/x-php (plain, non-wrapped PHP code).

+
diff --git a/backend/webif/static/codemirror/mode/php/php.js b/backend/webif/static/codemirror/mode/php/php.js new file mode 100755 index 000000000..589c9a663 --- /dev/null +++ b/backend/webif/static/codemirror/mode/php/php.js @@ -0,0 +1,234 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function keywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + // Helper for phpString + function matchSequence(list, end, escapes) { + if (list.length == 0) return phpString(end); + return function (stream, state) { + var patterns = list[0]; + for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) { + state.tokenize = matchSequence(list.slice(1), end); + return patterns[i][1]; + } + state.tokenize = phpString(end, escapes); + return "string"; + }; + } + function phpString(closing, escapes) { + return function(stream, state) { return phpString_(stream, state, closing, escapes); }; + } + function phpString_(stream, state, closing, escapes) { + // "Complex" syntax + if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) { + state.tokenize = null; + return "string"; + } + + // Simple syntax + if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) { + // After the variable name there may appear array or object operator. + if (stream.match("[", false)) { + // Match array operator + state.tokenize = matchSequence([ + [["[", null]], + [[/\d[\w\.]*/, "number"], + [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"], + [/[\w\$]+/, "variable"]], + [["]", null]] + ], closing, escapes); + } + if (stream.match(/\-\>\w/, false)) { + // Match object operator + state.tokenize = matchSequence([ + [["->", null]], + [[/[\w]+/, "variable"]] + ], closing, escapes); + } + return "variable-2"; + } + + var escaped = false; + // Normal string + while (!stream.eol() && + (escaped || escapes === false || + (!stream.match("{$", false) && + !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) { + if (!escaped && stream.match(closing)) { + state.tokenize = null; + state.tokStack.pop(); state.tokStack.pop(); + break; + } + escaped = stream.next() == "\\" && !escaped; + } + return "string"; + } + + var phpKeywords = "abstract and array as break case catch class clone const continue declare default " + + "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " + + "for foreach function global goto if implements interface instanceof namespace " + + "new or private protected public static switch throw trait try use var while xor " + + "die echo empty exit eval include include_once isset list require require_once return " + + "print unset __halt_compiler self static parent yield insteadof finally"; + var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__"; + var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists array_intersect_key array_combine array_column pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count"; + CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" ")); + CodeMirror.registerHelper("wordChars", "php", /[\w$]/); + + var phpConfig = { + name: "clike", + helperType: "php", + keywords: keywords(phpKeywords), + blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"), + defKeywords: keywords("class function interface namespace trait"), + atoms: keywords(phpAtoms), + builtin: keywords(phpBuiltin), + multiLineStrings: true, + hooks: { + "$": function(stream) { + stream.eatWhile(/[\w\$_]/); + return "variable-2"; + }, + "<": function(stream, state) { + var before; + if (before = stream.match(/<<\s*/)) { + var quoted = stream.eat(/['"]/); + stream.eatWhile(/[\w\.]/); + var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1)); + if (quoted) stream.eat(quoted); + if (delim) { + (state.tokStack || (state.tokStack = [])).push(delim, 0); + state.tokenize = phpString(delim, quoted != "'"); + return "string"; + } + } + return false; + }, + "#": function(stream) { + while (!stream.eol() && !stream.match("?>", false)) stream.next(); + return "comment"; + }, + "/": function(stream) { + if (stream.eat("/")) { + while (!stream.eol() && !stream.match("?>", false)) stream.next(); + return "comment"; + } + return false; + }, + '"': function(_stream, state) { + (state.tokStack || (state.tokStack = [])).push('"', 0); + state.tokenize = phpString('"'); + return "string"; + }, + "{": function(_stream, state) { + if (state.tokStack && state.tokStack.length) + state.tokStack[state.tokStack.length - 1]++; + return false; + }, + "}": function(_stream, state) { + if (state.tokStack && state.tokStack.length > 0 && + !--state.tokStack[state.tokStack.length - 1]) { + state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]); + } + return false; + } + } + }; + + CodeMirror.defineMode("php", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, (parserConfig && parserConfig.htmlMode) || "text/html"); + var phpMode = CodeMirror.getMode(config, phpConfig); + + function dispatch(stream, state) { + var isPHP = state.curMode == phpMode; + if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null; + if (!isPHP) { + if (stream.match(/^<\?\w*/)) { + state.curMode = phpMode; + if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, "")) + state.curState = state.php; + return "meta"; + } + if (state.pending == '"' || state.pending == "'") { + while (!stream.eol() && stream.next() != state.pending) {} + var style = "string"; + } else if (state.pending && stream.pos < state.pending.end) { + stream.pos = state.pending.end; + var style = state.pending.style; + } else { + var style = htmlMode.token(stream, state.curState); + } + if (state.pending) state.pending = null; + var cur = stream.current(), openPHP = cur.search(/<\?/), m; + if (openPHP != -1) { + if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0]; + else state.pending = {end: stream.pos, style: style}; + stream.backUp(cur.length - openPHP); + } + return style; + } else if (isPHP && state.php.tokenize == null && stream.match("?>")) { + state.curMode = htmlMode; + state.curState = state.html; + if (!state.php.context.prev) state.php = null; + return "meta"; + } else { + return phpMode.token(stream, state.curState); + } + } + + return { + startState: function() { + var html = CodeMirror.startState(htmlMode) + var php = parserConfig.startOpen ? CodeMirror.startState(phpMode) : null + return {html: html, + php: php, + curMode: parserConfig.startOpen ? phpMode : htmlMode, + curState: parserConfig.startOpen ? php : html, + pending: null}; + }, + + copyState: function(state) { + var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html), + php = state.php, phpNew = php && CodeMirror.copyState(phpMode, php), cur; + if (state.curMode == htmlMode) cur = htmlNew; + else cur = phpNew; + return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, + pending: state.pending}; + }, + + token: dispatch, + + indent: function(state, textAfter) { + if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) || + (state.curMode == phpMode && /^\?>/.test(textAfter))) + return htmlMode.indent(state.html, textAfter); + return state.curMode.indent(state.curState, textAfter); + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//", + + innerMode: function(state) { return {state: state.curState, mode: state.curMode}; } + }; + }, "htmlmixed", "clike"); + + CodeMirror.defineMIME("application/x-httpd-php", "php"); + CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true}); + CodeMirror.defineMIME("text/x-php", phpConfig); +}); diff --git a/backend/webif/static/codemirror/mode/php/test.js b/backend/webif/static/codemirror/mode/php/test.js new file mode 100755 index 000000000..e2ecefc18 --- /dev/null +++ b/backend/webif/static/codemirror/mode/php/test.js @@ -0,0 +1,154 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "php"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT('simple_test', + '[meta ]'); + + MT('variable_interpolation_non_alphanumeric', + '[meta $/$\\$}$\\\"$:$;$?$|$[[$]]$+$=aaa"]', + '[meta ?>]'); + + MT('variable_interpolation_digits', + '[meta ]'); + + MT('variable_interpolation_simple_syntax_1', + '[meta ]'); + + MT('variable_interpolation_simple_syntax_2', + '[meta ]'); + + MT('variable_interpolation_simple_syntax_3', + '[meta [variable aaaaa][string .aaaaaa"];', + '[keyword echo] [string "aaa][variable-2 $aaaa][string ->][variable-2 $aaaaa][string .aaaaaa"];', + '[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string [[2]].aaaaaa"];', + '[keyword echo] [string "aaa][variable-2 $aaaa]->[variable aaaaa][string ->aaaa2.aaaaaa"];', + '[meta ?>]'); + + MT('variable_interpolation_escaping', + '[meta aaa.aaa"];', + '[keyword echo] [string "aaa\\$aaaa[[2]]aaa.aaa"];', + '[keyword echo] [string "aaa\\$aaaa[[asd]]aaa.aaa"];', + '[keyword echo] [string "aaa{\\$aaaa->aaa.aaa"];', + '[keyword echo] [string "aaa{\\$aaaa[[2]]aaa.aaa"];', + '[keyword echo] [string "aaa{\\aaaaa[[asd]]aaa.aaa"];', + '[keyword echo] [string "aaa\\${aaaa->aaa.aaa"];', + '[keyword echo] [string "aaa\\${aaaa[[2]]aaa.aaa"];', + '[keyword echo] [string "aaa\\${aaaa[[asd]]aaa.aaa"];', + '[meta ?>]'); + + MT('variable_interpolation_complex_syntax_1', + '[meta aaa.aaa"];', + '[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa]}[string ->aaa.aaa"];', + '[keyword echo] [string "aaa][variable-2 $]{[variable-2 $aaaa][[',' [number 42]',']]}[string ->aaa.aaa"];', + '[keyword echo] [string "aaa][variable-2 $]{[variable aaaa][meta ?>]aaaaaa'); + + MT('variable_interpolation_complex_syntax_2', + '[meta } $aaaaaa.aaa"];', + '[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*}?>*/][[',' [string "aaa][variable-2 $aaa][string {}][variable-2 $]{[variable aaa]}[string "]',']]}[string ->aaa.aaa"];', + '[keyword echo] [string "][variable-2 $]{[variable aaa][comment /*} } $aaa } */]}[string ->aaa.aaa"];'); + + + function build_recursive_monsters(nt, t, n){ + var monsters = [t]; + for (var i = 1; i <= n; ++i) + monsters[i] = nt.join(monsters[i - 1]); + return monsters; + } + + var m1 = build_recursive_monsters( + ['[string "][variable-2 $]{[variable aaa] [operator +] ', '}[string "]'], + '[comment /* }?>} */] [string "aaa][variable-2 $aaa][string .aaa"]', + 10 + ); + + MT('variable_interpolation_complex_syntax_3_1', + '[meta ]'); + + var m2 = build_recursive_monsters( + ['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', '}[string .a"]'], + '[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]', + 5 + ); + + MT('variable_interpolation_complex_syntax_3_2', + '[meta ]'); + + function build_recursive_monsters_2(mf1, mf2, nt, t, n){ + var monsters = [t]; + for (var i = 1; i <= n; ++i) + monsters[i] = nt[0] + mf1[i - 1] + nt[1] + mf2[i - 1] + nt[2] + monsters[i - 1] + nt[3]; + return monsters; + } + + var m3 = build_recursive_monsters_2( + m1, + m2, + ['[string "a][variable-2 $]{[variable aaa] [operator +] ', ' [operator +] ', ' [operator +] ', '}[string .a"]'], + '[comment /* }?>{{ */] [string "a?>}{{aa][variable-2 $aaa][string .a}a?>a"]', + 4 + ); + + MT('variable_interpolation_complex_syntax_3_3', + '[meta ]'); + + MT("variable_interpolation_heredoc", + "[meta +CodeMirror: Pig Latin mode + + + + + + + + + +
+

Pig Latin mode

+
+ + + +

+ Simple mode that handles Pig Latin language. +

+ +

MIME type defined: text/x-pig + (PIG code) +

diff --git a/backend/webif/static/codemirror/mode/pig/pig.js b/backend/webif/static/codemirror/mode/pig/pig.js new file mode 100755 index 000000000..5b567272e --- /dev/null +++ b/backend/webif/static/codemirror/mode/pig/pig.js @@ -0,0 +1,178 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* + * Pig Latin Mode for CodeMirror 2 + * @author Prasanth Jayachandran + * @link https://github.com/prasanthj/pig-codemirror-2 + * This implementation is adapted from PL/SQL mode in CodeMirror 2. + */ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("pig", function(_config, parserConfig) { + var keywords = parserConfig.keywords, + builtins = parserConfig.builtins, + types = parserConfig.types, + multiLineStrings = parserConfig.multiLineStrings; + + var isOperatorChar = /[*+\-%<>=&?:\/!|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function tokenComment(stream, state) { + var isEnd = false; + var ch; + while(ch = stream.next()) { + if(ch == "/" && isEnd) { + state.tokenize = tokenBase; + break; + } + isEnd = (ch == "*"); + } + return "comment"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; break; + } + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = tokenBase; + return "error"; + }; + } + + + function tokenBase(stream, state) { + var ch = stream.next(); + + // is a start of string? + if (ch == '"' || ch == "'") + return chain(stream, state, tokenString(ch)); + // is it one of the special chars + else if(/[\[\]{}\(\),;\.]/.test(ch)) + return null; + // is it a number? + else if(/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + // multi line comment or operator + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, tokenComment); + } + else { + stream.eatWhile(isOperatorChar); + return "operator"; + } + } + // single line comment or operator + else if (ch=="-") { + if(stream.eat("-")){ + stream.skipToEnd(); + return "comment"; + } + else { + stream.eatWhile(isOperatorChar); + return "operator"; + } + } + // is it an operator + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + else { + // get the while word + stream.eatWhile(/[\w\$_]/); + // is it one of the listed keywords? + if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) { + //keywords can be used as variables like flatten(group), group.$0 etc.. + if (!stream.eat(")") && !stream.eat(".")) + return "keyword"; + } + // is it one of the builtin functions? + if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) + return "variable-2"; + // is it one of the listed types? + if (types && types.propertyIsEnumerable(stream.current().toUpperCase())) + return "variable-3"; + // default is a 'variable' + return "variable"; + } + } + + // Interface + return { + startState: function() { + return { + tokenize: tokenBase, + startOfLine: true + }; + }, + + token: function(stream, state) { + if(stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + return style; + } + }; +}); + +(function() { + function keywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + // builtin funcs taken from trunk revision 1303237 + var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL " + + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS " + + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG " + + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN " + + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER " + + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS " + + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA " + + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE " + + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG " + + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER "; + + // taken from QueryLexer.g + var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP " + + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL " + + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE " + + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " + + "NEQ MATCHES TRUE FALSE DUMP"; + + // data types + var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP "; + + CodeMirror.defineMIME("text/x-pig", { + name: "pig", + builtins: keywords(pBuiltins), + keywords: keywords(pKeywords), + types: keywords(pTypes) + }); + + CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" ")); +}()); + +}); diff --git a/backend/webif/static/codemirror/mode/powershell/index.html b/backend/webif/static/codemirror/mode/powershell/index.html new file mode 100755 index 000000000..6b235df8f --- /dev/null +++ b/backend/webif/static/codemirror/mode/powershell/index.html @@ -0,0 +1,204 @@ + + + + + CodeMirror: Powershell mode + + + + + + + + +
+

PowerShell mode

+ +
+ + +

MIME types defined: application/x-powershell.

+
+ + diff --git a/backend/webif/static/codemirror/mode/powershell/powershell.js b/backend/webif/static/codemirror/mode/powershell/powershell.js new file mode 100755 index 000000000..2728ef9d9 --- /dev/null +++ b/backend/webif/static/codemirror/mode/powershell/powershell.js @@ -0,0 +1,398 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + 'use strict'; + if (typeof exports == 'object' && typeof module == 'object') // CommonJS + mod(require('../../lib/codemirror')); + else if (typeof define == 'function' && define.amd) // AMD + define(['../../lib/codemirror'], mod); + else // Plain browser env + mod(window.CodeMirror); +})(function(CodeMirror) { +'use strict'; + +CodeMirror.defineMode('powershell', function() { + function buildRegexp(patterns, options) { + options = options || {}; + var prefix = options.prefix !== undefined ? options.prefix : '^'; + var suffix = options.suffix !== undefined ? options.suffix : '\\b'; + + for (var i = 0; i < patterns.length; i++) { + if (patterns[i] instanceof RegExp) { + patterns[i] = patterns[i].source; + } + else { + patterns[i] = patterns[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + } + + return new RegExp(prefix + '(' + patterns.join('|') + ')' + suffix, 'i'); + } + + var notCharacterOrDash = '(?=[^A-Za-z\\d\\-_]|$)'; + var varNames = /[\w\-:]/ + var keywords = buildRegexp([ + /begin|break|catch|continue|data|default|do|dynamicparam/, + /else|elseif|end|exit|filter|finally|for|foreach|from|function|if|in/, + /param|process|return|switch|throw|trap|try|until|where|while/ + ], { suffix: notCharacterOrDash }); + + var punctuation = /[\[\]{},;`\.]|@[({]/; + var wordOperators = buildRegexp([ + 'f', + /b?not/, + /[ic]?split/, 'join', + /is(not)?/, 'as', + /[ic]?(eq|ne|[gl][te])/, + /[ic]?(not)?(like|match|contains)/, + /[ic]?replace/, + /b?(and|or|xor)/ + ], { prefix: '-' }); + var symbolOperators = /[+\-*\/%]=|\+\+|--|\.\.|[+\-*&^%:=!|\/]|<(?!#)|(?!#)>/; + var operators = buildRegexp([wordOperators, symbolOperators], { suffix: '' }); + + var numbers = /^((0x[\da-f]+)|((\d+\.\d+|\d\.|\.\d+|\d+)(e[\+\-]?\d+)?))[ld]?([kmgtp]b)?/i; + + var identifiers = /^[A-Za-z\_][A-Za-z\-\_\d]*\b/; + + var symbolBuiltins = /[A-Z]:|%|\?/i; + var namedBuiltins = buildRegexp([ + /Add-(Computer|Content|History|Member|PSSnapin|Type)/, + /Checkpoint-Computer/, + /Clear-(Content|EventLog|History|Host|Item(Property)?|Variable)/, + /Compare-Object/, + /Complete-Transaction/, + /Connect-PSSession/, + /ConvertFrom-(Csv|Json|SecureString|StringData)/, + /Convert-Path/, + /ConvertTo-(Csv|Html|Json|SecureString|Xml)/, + /Copy-Item(Property)?/, + /Debug-Process/, + /Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/, + /Disconnect-PSSession/, + /Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/, + /(Enter|Exit)-PSSession/, + /Export-(Alias|Clixml|Console|Counter|Csv|FormatData|ModuleMember|PSSession)/, + /ForEach-Object/, + /Format-(Custom|List|Table|Wide)/, + new RegExp('Get-(Acl|Alias|AuthenticodeSignature|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Counter|Credential' + + '|Culture|Date|Event|EventLog|EventSubscriber|ExecutionPolicy|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job' + + '|Location|Member|Module|PfxCertificate|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration' + + '|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|Verb|WinEvent|WmiObject)'), + /Group-Object/, + /Import-(Alias|Clixml|Counter|Csv|LocalizedData|Module|PSSession)/, + /ImportSystemModules/, + /Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)/, + /Join-Path/, + /Limit-EventLog/, + /Measure-(Command|Object)/, + /Move-Item(Property)?/, + new RegExp('New-(Alias|Event|EventLog|Item(Property)?|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile' + + '|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy|WinEvent)'), + /Out-(Default|File|GridView|Host|Null|Printer|String)/, + /Pause/, + /(Pop|Push)-Location/, + /Read-Host/, + /Receive-(Job|PSSession)/, + /Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)/, + /Remove-(Computer|Event|EventLog|Item(Property)?|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)/, + /Rename-(Computer|Item(Property)?)/, + /Reset-ComputerMachinePassword/, + /Resolve-Path/, + /Restart-(Computer|Service)/, + /Restore-Computer/, + /Resume-(Job|Service)/, + /Save-Help/, + /Select-(Object|String|Xml)/, + /Send-MailMessage/, + new RegExp('Set-(Acl|Alias|AuthenticodeSignature|Content|Date|ExecutionPolicy|Item(Property)?|Location|PSBreakpoint|PSDebug' + + '|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)'), + /Show-(Command|ControlPanelItem|EventLog)/, + /Sort-Object/, + /Split-Path/, + /Start-(Job|Process|Service|Sleep|Transaction|Transcript)/, + /Stop-(Computer|Job|Process|Service|Transcript)/, + /Suspend-(Job|Service)/, + /TabExpansion2/, + /Tee-Object/, + /Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)/, + /Trace-Command/, + /Unblock-File/, + /Undo-Transaction/, + /Unregister-(Event|PSSessionConfiguration)/, + /Update-(FormatData|Help|List|TypeData)/, + /Use-Transaction/, + /Wait-(Event|Job|Process)/, + /Where-Object/, + /Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning)/, + /cd|help|mkdir|more|oss|prompt/, + /ac|asnp|cat|cd|chdir|clc|clear|clhy|cli|clp|cls|clv|cnsn|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|dnsn|ebp/, + /echo|epal|epcsv|epsn|erase|etsn|exsn|fc|fl|foreach|ft|fw|gal|gbp|gc|gci|gcm|gcs|gdr|ghy|gi|gjb|gl|gm|gmo|gp|gps/, + /group|gsn|gsnp|gsv|gu|gv|gwmi|h|history|icm|iex|ihy|ii|ipal|ipcsv|ipmo|ipsn|irm|ise|iwmi|iwr|kill|lp|ls|man|md/, + /measure|mi|mount|move|mp|mv|nal|ndr|ni|nmo|npssc|nsn|nv|ogv|oh|popd|ps|pushd|pwd|r|rbp|rcjb|rcsn|rd|rdr|ren|ri/, + /rjb|rm|rmdir|rmo|rni|rnp|rp|rsn|rsnp|rujb|rv|rvpa|rwmi|sajb|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls/, + /sort|sp|spjb|spps|spsv|start|sujb|sv|swmi|tee|trcm|type|where|wjb|write/ + ], { prefix: '', suffix: '' }); + var variableBuiltins = buildRegexp([ + /[$?^_]|Args|ConfirmPreference|ConsoleFileName|DebugPreference|Error|ErrorActionPreference|ErrorView|ExecutionContext/, + /FormatEnumerationLimit|Home|Host|Input|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount/, + /MaximumHistoryCount|MaximumVariableCount|MyInvocation|NestedPromptLevel|OutputEncoding|Pid|Profile|ProgressPreference/, + /PSBoundParameters|PSCommandPath|PSCulture|PSDefaultParameterValues|PSEmailServer|PSHome|PSScriptRoot|PSSessionApplicationName/, + /PSSessionConfigurationName|PSSessionOption|PSUICulture|PSVersionTable|Pwd|ShellId|StackTrace|VerbosePreference/, + /WarningPreference|WhatIfPreference/, + + /Event|EventArgs|EventSubscriber|Sender/, + /Matches|Ofs|ForEach|LastExitCode|PSCmdlet|PSItem|PSSenderInfo|This/, + /true|false|null/ + ], { prefix: '\\$', suffix: '' }); + + var builtins = buildRegexp([symbolBuiltins, namedBuiltins, variableBuiltins], { suffix: notCharacterOrDash }); + + var grammar = { + keyword: keywords, + number: numbers, + operator: operators, + builtin: builtins, + punctuation: punctuation, + identifier: identifiers + }; + + // tokenizers + function tokenBase(stream, state) { + // Handle Comments + //var ch = stream.peek(); + + var parent = state.returnStack[state.returnStack.length - 1]; + if (parent && parent.shouldReturnFrom(state)) { + state.tokenize = parent.tokenize; + state.returnStack.pop(); + return state.tokenize(stream, state); + } + + if (stream.eatSpace()) { + return null; + } + + if (stream.eat('(')) { + state.bracketNesting += 1; + return 'punctuation'; + } + + if (stream.eat(')')) { + state.bracketNesting -= 1; + return 'punctuation'; + } + + for (var key in grammar) { + if (stream.match(grammar[key])) { + return key; + } + } + + var ch = stream.next(); + + // single-quote string + if (ch === "'") { + return tokenSingleQuoteString(stream, state); + } + + if (ch === '$') { + return tokenVariable(stream, state); + } + + // double-quote string + if (ch === '"') { + return tokenDoubleQuoteString(stream, state); + } + + if (ch === '<' && stream.eat('#')) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + + if (ch === '#') { + stream.skipToEnd(); + return 'comment'; + } + + if (ch === '@') { + var quoteMatch = stream.eat(/["']/); + if (quoteMatch && stream.eol()) { + state.tokenize = tokenMultiString; + state.startQuote = quoteMatch[0]; + return tokenMultiString(stream, state); + } else if (stream.eol()) { + return 'error'; + } else if (stream.peek().match(/[({]/)) { + return 'punctuation'; + } else if (stream.peek().match(varNames)) { + // splatted variable + return tokenVariable(stream, state); + } + } + return 'error'; + } + + function tokenSingleQuoteString(stream, state) { + var ch; + while ((ch = stream.peek()) != null) { + stream.next(); + + if (ch === "'" && !stream.eat("'")) { + state.tokenize = tokenBase; + return 'string'; + } + } + + return 'error'; + } + + function tokenDoubleQuoteString(stream, state) { + var ch; + while ((ch = stream.peek()) != null) { + if (ch === '$') { + state.tokenize = tokenStringInterpolation; + return 'string'; + } + + stream.next(); + if (ch === '`') { + stream.next(); + continue; + } + + if (ch === '"' && !stream.eat('"')) { + state.tokenize = tokenBase; + return 'string'; + } + } + + return 'error'; + } + + function tokenStringInterpolation(stream, state) { + return tokenInterpolation(stream, state, tokenDoubleQuoteString); + } + + function tokenMultiStringReturn(stream, state) { + state.tokenize = tokenMultiString; + state.startQuote = '"' + return tokenMultiString(stream, state); + } + + function tokenHereStringInterpolation(stream, state) { + return tokenInterpolation(stream, state, tokenMultiStringReturn); + } + + function tokenInterpolation(stream, state, parentTokenize) { + if (stream.match('$(')) { + var savedBracketNesting = state.bracketNesting; + state.returnStack.push({ + /*jshint loopfunc:true */ + shouldReturnFrom: function(state) { + return state.bracketNesting === savedBracketNesting; + }, + tokenize: parentTokenize + }); + state.tokenize = tokenBase; + state.bracketNesting += 1; + return 'punctuation'; + } else { + stream.next(); + state.returnStack.push({ + shouldReturnFrom: function() { return true; }, + tokenize: parentTokenize + }); + state.tokenize = tokenVariable; + return state.tokenize(stream, state); + } + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == '>') { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch === '#'); + } + return 'comment'; + } + + function tokenVariable(stream, state) { + var ch = stream.peek(); + if (stream.eat('{')) { + state.tokenize = tokenVariableWithBraces; + return tokenVariableWithBraces(stream, state); + } else if (ch != undefined && ch.match(varNames)) { + stream.eatWhile(varNames); + state.tokenize = tokenBase; + return 'variable-2'; + } else { + state.tokenize = tokenBase; + return 'error'; + } + } + + function tokenVariableWithBraces(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch === '}') { + state.tokenize = tokenBase; + break; + } + } + return 'variable-2'; + } + + function tokenMultiString(stream, state) { + var quote = state.startQuote; + if (stream.sol() && stream.match(new RegExp(quote + '@'))) { + state.tokenize = tokenBase; + } + else if (quote === '"') { + while (!stream.eol()) { + var ch = stream.peek(); + if (ch === '$') { + state.tokenize = tokenHereStringInterpolation; + return 'string'; + } + + stream.next(); + if (ch === '`') { + stream.next(); + } + } + } + else { + stream.skipToEnd(); + } + + return 'string'; + } + + var external = { + startState: function() { + return { + returnStack: [], + bracketNesting: 0, + tokenize: tokenBase + }; + }, + + token: function(stream, state) { + return state.tokenize(stream, state); + }, + + blockCommentStart: '<#', + blockCommentEnd: '#>', + lineComment: '#', + fold: 'brace' + }; + return external; +}); + +CodeMirror.defineMIME('application/x-powershell', 'powershell'); +}); diff --git a/backend/webif/static/codemirror/mode/powershell/test.js b/backend/webif/static/codemirror/mode/powershell/test.js new file mode 100755 index 000000000..9c9aed0d5 --- /dev/null +++ b/backend/webif/static/codemirror/mode/powershell/test.js @@ -0,0 +1,74 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "powershell"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + function forEach(arr, f) { for (var i = 0; i < arr.length; i++) f(arr[i], i) } + + MT('comment', '[number 1][comment # A]'); + MT('comment_multiline', '[number 1][comment <#]', + '[comment ABC]', + '[comment #>][number 2]'); + + forEach([ + '0', '1234', + '12kb', '12mb', '12Gb', '12Tb', '12PB', '12L', '12D', '12lkb', '12dtb', + '1.234', '1.234e56', '1.', '1.e2', '.2', '.2e34', + '1.2MB', '1.kb', '.1dTB', '1.e1gb', '.2', '.2e34', + '0x1', '0xabcdef', '0x3tb', '0xelmb' + ], function(number) { + MT("number_" + number, "[number " + number + "]"); + }); + + MT('string_literal_escaping', "[string 'a''']"); + MT('string_literal_variable', "[string 'a $x']"); + MT('string_escaping_1', '[string "a `""]'); + MT('string_escaping_2', '[string "a """]'); + MT('string_variable_escaping', '[string "a `$x"]'); + MT('string_variable', '[string "a ][variable-2 $x][string b"]'); + MT('string_variable_spaces', '[string "a ][variable-2 ${x y}][string b"]'); + MT('string_expression', '[string "a ][punctuation $(][variable-2 $x][operator +][number 3][punctuation )][string b"]'); + MT('string_expression_nested', '[string "A][punctuation $(][string "a][punctuation $(][string "w"][punctuation )][string b"][punctuation )][string B"]'); + + MT('string_heredoc', '[string @"]', + '[string abc]', + '[string "@]'); + MT('string_heredoc_quotes', '[string @"]', + '[string abc "\']', + '[string "@]'); + MT('string_heredoc_variable', '[string @"]', + '[string a ][variable-2 $x][string b]', + '[string "@]'); + MT('string_heredoc_nested_string', '[string @"]', + '[string a][punctuation $(][string "w"][punctuation )][string b]', + '[string "@]'); + MT('string_heredoc_literal_quotes', "[string @']", + '[string abc "\']', + "[string '@]"); + + MT('array', "[punctuation @(][string 'a'][punctuation ,][string 'b'][punctuation )]"); + MT('hash', "[punctuation @{][string 'key'][operator :][string 'value'][punctuation }]"); + + MT('variable', "[variable-2 $test]"); + MT('variable_global', "[variable-2 $global:test]"); + MT('variable_spaces', "[variable-2 ${test test}]"); + MT('operator_splat', "[variable-2 @x]"); + MT('variable_builtin', "[builtin $ErrorActionPreference]"); + MT('variable_builtin_symbols', "[builtin $$]"); + + MT('operator', "[operator +]"); + MT('operator_unary', "[operator +][number 3]"); + MT('operator_long', "[operator -match]"); + + forEach([ + '(', ')', '[[', ']]', '{', '}', ',', '`', ';', '.' + ], function(punctuation) { + MT("punctuation_" + punctuation.replace(/^[\[\]]/,''), "[punctuation " + punctuation + "]"); + }); + + MT('keyword', "[keyword if]"); + + MT('call_builtin', "[builtin Get-ChildItem]"); +})(); diff --git a/backend/webif/static/codemirror/mode/properties/index.html b/backend/webif/static/codemirror/mode/properties/index.html new file mode 100755 index 000000000..f885302de --- /dev/null +++ b/backend/webif/static/codemirror/mode/properties/index.html @@ -0,0 +1,53 @@ + + +CodeMirror: Properties files mode + + + + + + + + + +
+

Properties files mode

+
+ + +

MIME types defined: text/x-properties, + text/x-ini.

+ +
diff --git a/backend/webif/static/codemirror/mode/properties/properties.js b/backend/webif/static/codemirror/mode/properties/properties.js new file mode 100755 index 000000000..ef8bf37ee --- /dev/null +++ b/backend/webif/static/codemirror/mode/properties/properties.js @@ -0,0 +1,78 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("properties", function() { + return { + token: function(stream, state) { + var sol = stream.sol() || state.afterSection; + var eol = stream.eol(); + + state.afterSection = false; + + if (sol) { + if (state.nextMultiline) { + state.inMultiline = true; + state.nextMultiline = false; + } else { + state.position = "def"; + } + } + + if (eol && ! state.nextMultiline) { + state.inMultiline = false; + state.position = "def"; + } + + if (sol) { + while(stream.eatSpace()) {} + } + + var ch = stream.next(); + + if (sol && (ch === "#" || ch === "!" || ch === ";")) { + state.position = "comment"; + stream.skipToEnd(); + return "comment"; + } else if (sol && ch === "[") { + state.afterSection = true; + stream.skipTo("]"); stream.eat("]"); + return "header"; + } else if (ch === "=" || ch === ":") { + state.position = "quote"; + return null; + } else if (ch === "\\" && state.position === "quote") { + if (stream.eol()) { // end of line? + // Multiline value + state.nextMultiline = true; + } + } + + return state.position; + }, + + startState: function() { + return { + position : "def", // Current position, "def", "quote" or "comment" + nextMultiline : false, // Is the next line multiline value + inMultiline : false, // Is the current line a multiline value + afterSection : false // Did we just open a section + }; + } + + }; +}); + +CodeMirror.defineMIME("text/x-properties", "properties"); +CodeMirror.defineMIME("text/x-ini", "properties"); + +}); diff --git a/backend/webif/static/codemirror/mode/protobuf/index.html b/backend/webif/static/codemirror/mode/protobuf/index.html new file mode 100755 index 000000000..55d453566 --- /dev/null +++ b/backend/webif/static/codemirror/mode/protobuf/index.html @@ -0,0 +1,104 @@ + + +CodeMirror: ProtoBuf mode + + + + + + + + + +
+

ProtoBuf mode

+
+ +
+ + +

MIME types defined: text/x-protobuf.

+ +
diff --git a/backend/webif/static/codemirror/mode/protobuf/protobuf.js b/backend/webif/static/codemirror/mode/protobuf/protobuf.js new file mode 100755 index 000000000..93cb3b0e0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/protobuf/protobuf.js @@ -0,0 +1,69 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); + }; + + var keywordArray = [ + "package", "message", "import", "syntax", + "required", "optional", "repeated", "reserved", "default", "extensions", "packed", + "bool", "bytes", "double", "enum", "float", "string", + "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64", + "option", "service", "rpc", "returns" + ]; + var keywords = wordRegexp(keywordArray); + + CodeMirror.registerHelper("hintWords", "protobuf", keywordArray); + + var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*"); + + function tokenBase(stream) { + // whitespaces + if (stream.eatSpace()) return null; + + // Handle one line Comments + if (stream.match("//")) { + stream.skipToEnd(); + return "comment"; + } + + // Handle Number Literals + if (stream.match(/^[0-9\.+-]/, false)) { + if (stream.match(/^[+-]?0x[0-9a-fA-F]+/)) + return "number"; + if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?/)) + return "number"; + if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?/)) + return "number"; + } + + // Handle Strings + if (stream.match(/^"([^"]|(""))*"/)) { return "string"; } + if (stream.match(/^'([^']|(''))*'/)) { return "string"; } + + // Handle words + if (stream.match(keywords)) { return "keyword"; } + if (stream.match(identifiers)) { return "variable"; } ; + + // Handle non-detected items + stream.next(); + return null; + }; + + CodeMirror.defineMode("protobuf", function() { + return {token: tokenBase}; + }); + + CodeMirror.defineMIME("text/x-protobuf", "protobuf"); +}); diff --git a/backend/webif/static/codemirror/mode/pug/index.html b/backend/webif/static/codemirror/mode/pug/index.html new file mode 100755 index 000000000..1765853a1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pug/index.html @@ -0,0 +1,70 @@ + + +CodeMirror: Pug Templating Mode + + + + + + + + + + + + + +
+

Pug Templating Mode

+
+ +

The Pug Templating Mode

+

Created by Forbes Lindesay. Managed as part of a Brackets extension at https://github.com/ForbesLindesay/jade-brackets.

+

MIME type defined: text/x-pug, text/x-jade.

+
diff --git a/backend/webif/static/codemirror/mode/pug/pug.js b/backend/webif/static/codemirror/mode/pug/pug.js new file mode 100755 index 000000000..401823365 --- /dev/null +++ b/backend/webif/static/codemirror/mode/pug/pug.js @@ -0,0 +1,591 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("pug", function (config) { + // token types + var KEYWORD = 'keyword'; + var DOCTYPE = 'meta'; + var ID = 'builtin'; + var CLASS = 'qualifier'; + + var ATTRS_NEST = { + '{': '}', + '(': ')', + '[': ']' + }; + + var jsMode = CodeMirror.getMode(config, 'javascript'); + + function State() { + this.javaScriptLine = false; + this.javaScriptLineExcludesColon = false; + + this.javaScriptArguments = false; + this.javaScriptArgumentsDepth = 0; + + this.isInterpolating = false; + this.interpolationNesting = 0; + + this.jsState = CodeMirror.startState(jsMode); + + this.restOfLine = ''; + + this.isIncludeFiltered = false; + this.isEach = false; + + this.lastTag = ''; + this.scriptType = ''; + + // Attributes Mode + this.isAttrs = false; + this.attrsNest = []; + this.inAttributeName = true; + this.attributeIsType = false; + this.attrValue = ''; + + // Indented Mode + this.indentOf = Infinity; + this.indentToken = ''; + + this.innerMode = null; + this.innerState = null; + + this.innerModeForLine = false; + } + /** + * Safely copy a state + * + * @return {State} + */ + State.prototype.copy = function () { + var res = new State(); + res.javaScriptLine = this.javaScriptLine; + res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon; + res.javaScriptArguments = this.javaScriptArguments; + res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth; + res.isInterpolating = this.isInterpolating; + res.interpolationNesting = this.interpolationNesting; + + res.jsState = CodeMirror.copyState(jsMode, this.jsState); + + res.innerMode = this.innerMode; + if (this.innerMode && this.innerState) { + res.innerState = CodeMirror.copyState(this.innerMode, this.innerState); + } + + res.restOfLine = this.restOfLine; + + res.isIncludeFiltered = this.isIncludeFiltered; + res.isEach = this.isEach; + res.lastTag = this.lastTag; + res.scriptType = this.scriptType; + res.isAttrs = this.isAttrs; + res.attrsNest = this.attrsNest.slice(); + res.inAttributeName = this.inAttributeName; + res.attributeIsType = this.attributeIsType; + res.attrValue = this.attrValue; + res.indentOf = this.indentOf; + res.indentToken = this.indentToken; + + res.innerModeForLine = this.innerModeForLine; + + return res; + }; + + function javaScript(stream, state) { + if (stream.sol()) { + // if javaScriptLine was set at end of line, ignore it + state.javaScriptLine = false; + state.javaScriptLineExcludesColon = false; + } + if (state.javaScriptLine) { + if (state.javaScriptLineExcludesColon && stream.peek() === ':') { + state.javaScriptLine = false; + state.javaScriptLineExcludesColon = false; + return; + } + var tok = jsMode.token(stream, state.jsState); + if (stream.eol()) state.javaScriptLine = false; + return tok || true; + } + } + function javaScriptArguments(stream, state) { + if (state.javaScriptArguments) { + if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') { + state.javaScriptArguments = false; + return; + } + if (stream.peek() === '(') { + state.javaScriptArgumentsDepth++; + } else if (stream.peek() === ')') { + state.javaScriptArgumentsDepth--; + } + if (state.javaScriptArgumentsDepth === 0) { + state.javaScriptArguments = false; + return; + } + + var tok = jsMode.token(stream, state.jsState); + return tok || true; + } + } + + function yieldStatement(stream) { + if (stream.match(/^yield\b/)) { + return 'keyword'; + } + } + + function doctype(stream) { + if (stream.match(/^(?:doctype) *([^\n]+)?/)) { + return DOCTYPE; + } + } + + function interpolation(stream, state) { + if (stream.match('#{')) { + state.isInterpolating = true; + state.interpolationNesting = 0; + return 'punctuation'; + } + } + + function interpolationContinued(stream, state) { + if (state.isInterpolating) { + if (stream.peek() === '}') { + state.interpolationNesting--; + if (state.interpolationNesting < 0) { + stream.next(); + state.isInterpolating = false; + return 'punctuation'; + } + } else if (stream.peek() === '{') { + state.interpolationNesting++; + } + return jsMode.token(stream, state.jsState) || true; + } + } + + function caseStatement(stream, state) { + if (stream.match(/^case\b/)) { + state.javaScriptLine = true; + return KEYWORD; + } + } + + function when(stream, state) { + if (stream.match(/^when\b/)) { + state.javaScriptLine = true; + state.javaScriptLineExcludesColon = true; + return KEYWORD; + } + } + + function defaultStatement(stream) { + if (stream.match(/^default\b/)) { + return KEYWORD; + } + } + + function extendsStatement(stream, state) { + if (stream.match(/^extends?\b/)) { + state.restOfLine = 'string'; + return KEYWORD; + } + } + + function append(stream, state) { + if (stream.match(/^append\b/)) { + state.restOfLine = 'variable'; + return KEYWORD; + } + } + function prepend(stream, state) { + if (stream.match(/^prepend\b/)) { + state.restOfLine = 'variable'; + return KEYWORD; + } + } + function block(stream, state) { + if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) { + state.restOfLine = 'variable'; + return KEYWORD; + } + } + + function include(stream, state) { + if (stream.match(/^include\b/)) { + state.restOfLine = 'string'; + return KEYWORD; + } + } + + function includeFiltered(stream, state) { + if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) { + state.isIncludeFiltered = true; + return KEYWORD; + } + } + + function includeFilteredContinued(stream, state) { + if (state.isIncludeFiltered) { + var tok = filter(stream, state); + state.isIncludeFiltered = false; + state.restOfLine = 'string'; + return tok; + } + } + + function mixin(stream, state) { + if (stream.match(/^mixin\b/)) { + state.javaScriptLine = true; + return KEYWORD; + } + } + + function call(stream, state) { + if (stream.match(/^\+([-\w]+)/)) { + if (!stream.match(/^\( *[-\w]+ *=/, false)) { + state.javaScriptArguments = true; + state.javaScriptArgumentsDepth = 0; + } + return 'variable'; + } + if (stream.match(/^\+#{/, false)) { + stream.next(); + state.mixinCallAfter = true; + return interpolation(stream, state); + } + } + function callArguments(stream, state) { + if (state.mixinCallAfter) { + state.mixinCallAfter = false; + if (!stream.match(/^\( *[-\w]+ *=/, false)) { + state.javaScriptArguments = true; + state.javaScriptArgumentsDepth = 0; + } + return true; + } + } + + function conditional(stream, state) { + if (stream.match(/^(if|unless|else if|else)\b/)) { + state.javaScriptLine = true; + return KEYWORD; + } + } + + function each(stream, state) { + if (stream.match(/^(- *)?(each|for)\b/)) { + state.isEach = true; + return KEYWORD; + } + } + function eachContinued(stream, state) { + if (state.isEach) { + if (stream.match(/^ in\b/)) { + state.javaScriptLine = true; + state.isEach = false; + return KEYWORD; + } else if (stream.sol() || stream.eol()) { + state.isEach = false; + } else if (stream.next()) { + while (!stream.match(/^ in\b/, false) && stream.next()); + return 'variable'; + } + } + } + + function whileStatement(stream, state) { + if (stream.match(/^while\b/)) { + state.javaScriptLine = true; + return KEYWORD; + } + } + + function tag(stream, state) { + var captures; + if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) { + state.lastTag = captures[1].toLowerCase(); + if (state.lastTag === 'script') { + state.scriptType = 'application/javascript'; + } + return 'tag'; + } + } + + function filter(stream, state) { + if (stream.match(/^:([\w\-]+)/)) { + var innerMode; + if (config && config.innerModes) { + innerMode = config.innerModes(stream.current().substring(1)); + } + if (!innerMode) { + innerMode = stream.current().substring(1); + } + if (typeof innerMode === 'string') { + innerMode = CodeMirror.getMode(config, innerMode); + } + setInnerMode(stream, state, innerMode); + return 'atom'; + } + } + + function code(stream, state) { + if (stream.match(/^(!?=|-)/)) { + state.javaScriptLine = true; + return 'punctuation'; + } + } + + function id(stream) { + if (stream.match(/^#([\w-]+)/)) { + return ID; + } + } + + function className(stream) { + if (stream.match(/^\.([\w-]+)/)) { + return CLASS; + } + } + + function attrs(stream, state) { + if (stream.peek() == '(') { + stream.next(); + state.isAttrs = true; + state.attrsNest = []; + state.inAttributeName = true; + state.attrValue = ''; + state.attributeIsType = false; + return 'punctuation'; + } + } + + function attrsContinued(stream, state) { + if (state.isAttrs) { + if (ATTRS_NEST[stream.peek()]) { + state.attrsNest.push(ATTRS_NEST[stream.peek()]); + } + if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) { + state.attrsNest.pop(); + } else if (stream.eat(')')) { + state.isAttrs = false; + return 'punctuation'; + } + if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) { + if (stream.peek() === '=' || stream.peek() === '!') { + state.inAttributeName = false; + state.jsState = CodeMirror.startState(jsMode); + if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') { + state.attributeIsType = true; + } else { + state.attributeIsType = false; + } + } + return 'attribute'; + } + + var tok = jsMode.token(stream, state.jsState); + if (state.attributeIsType && tok === 'string') { + state.scriptType = stream.current().toString(); + } + if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) { + try { + Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, '')); + state.inAttributeName = true; + state.attrValue = ''; + stream.backUp(stream.current().length); + return attrsContinued(stream, state); + } catch (ex) { + //not the end of an attribute + } + } + state.attrValue += stream.current(); + return tok || true; + } + } + + function attributesBlock(stream, state) { + if (stream.match(/^&attributes\b/)) { + state.javaScriptArguments = true; + state.javaScriptArgumentsDepth = 0; + return 'keyword'; + } + } + + function indent(stream) { + if (stream.sol() && stream.eatSpace()) { + return 'indent'; + } + } + + function comment(stream, state) { + if (stream.match(/^ *\/\/(-)?([^\n]*)/)) { + state.indentOf = stream.indentation(); + state.indentToken = 'comment'; + return 'comment'; + } + } + + function colon(stream) { + if (stream.match(/^: */)) { + return 'colon'; + } + } + + function text(stream, state) { + if (stream.match(/^(?:\| ?| )([^\n]+)/)) { + return 'string'; + } + if (stream.match(/^(<[^\n]*)/, false)) { + // html string + setInnerMode(stream, state, 'htmlmixed'); + state.innerModeForLine = true; + return innerMode(stream, state, true); + } + } + + function dot(stream, state) { + if (stream.eat('.')) { + var innerMode = null; + if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) { + innerMode = state.scriptType.toLowerCase().replace(/"|'/g, ''); + } else if (state.lastTag === 'style') { + innerMode = 'css'; + } + setInnerMode(stream, state, innerMode); + return 'dot'; + } + } + + function fail(stream) { + stream.next(); + return null; + } + + + function setInnerMode(stream, state, mode) { + mode = CodeMirror.mimeModes[mode] || mode; + mode = config.innerModes ? config.innerModes(mode) || mode : mode; + mode = CodeMirror.mimeModes[mode] || mode; + mode = CodeMirror.getMode(config, mode); + state.indentOf = stream.indentation(); + + if (mode && mode.name !== 'null') { + state.innerMode = mode; + } else { + state.indentToken = 'string'; + } + } + function innerMode(stream, state, force) { + if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) { + if (state.innerMode) { + if (!state.innerState) { + state.innerState = state.innerMode.startState ? CodeMirror.startState(state.innerMode, stream.indentation()) : {}; + } + return stream.hideFirstChars(state.indentOf + 2, function () { + return state.innerMode.token(stream, state.innerState) || true; + }); + } else { + stream.skipToEnd(); + return state.indentToken; + } + } else if (stream.sol()) { + state.indentOf = Infinity; + state.indentToken = null; + state.innerMode = null; + state.innerState = null; + } + } + function restOfLine(stream, state) { + if (stream.sol()) { + // if restOfLine was set at end of line, ignore it + state.restOfLine = ''; + } + if (state.restOfLine) { + stream.skipToEnd(); + var tok = state.restOfLine; + state.restOfLine = ''; + return tok; + } + } + + + function startState() { + return new State(); + } + function copyState(state) { + return state.copy(); + } + /** + * Get the next token in the stream + * + * @param {Stream} stream + * @param {State} state + */ + function nextToken(stream, state) { + var tok = innerMode(stream, state) + || restOfLine(stream, state) + || interpolationContinued(stream, state) + || includeFilteredContinued(stream, state) + || eachContinued(stream, state) + || attrsContinued(stream, state) + || javaScript(stream, state) + || javaScriptArguments(stream, state) + || callArguments(stream, state) + + || yieldStatement(stream, state) + || doctype(stream, state) + || interpolation(stream, state) + || caseStatement(stream, state) + || when(stream, state) + || defaultStatement(stream, state) + || extendsStatement(stream, state) + || append(stream, state) + || prepend(stream, state) + || block(stream, state) + || include(stream, state) + || includeFiltered(stream, state) + || mixin(stream, state) + || call(stream, state) + || conditional(stream, state) + || each(stream, state) + || whileStatement(stream, state) + || tag(stream, state) + || filter(stream, state) + || code(stream, state) + || id(stream, state) + || className(stream, state) + || attrs(stream, state) + || attributesBlock(stream, state) + || indent(stream, state) + || text(stream, state) + || comment(stream, state) + || colon(stream, state) + || dot(stream, state) + || fail(stream, state); + + return tok === true ? null : tok; + } + return { + startState: startState, + copyState: copyState, + token: nextToken + }; +}, 'javascript', 'css', 'htmlmixed'); + +CodeMirror.defineMIME('text/x-pug', 'pug'); +CodeMirror.defineMIME('text/x-jade', 'pug'); + +}); diff --git a/backend/webif/static/codemirror/mode/puppet/index.html b/backend/webif/static/codemirror/mode/puppet/index.html new file mode 100755 index 000000000..5614c3695 --- /dev/null +++ b/backend/webif/static/codemirror/mode/puppet/index.html @@ -0,0 +1,121 @@ + + +CodeMirror: Puppet mode + + + + + + + + + + +
+

Puppet mode

+
+ + +

MIME types defined: text/x-puppet.

+ +
diff --git a/backend/webif/static/codemirror/mode/puppet/puppet.js b/backend/webif/static/codemirror/mode/puppet/puppet.js new file mode 100755 index 000000000..57041300a --- /dev/null +++ b/backend/webif/static/codemirror/mode/puppet/puppet.js @@ -0,0 +1,220 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("puppet", function () { + // Stores the words from the define method + var words = {}; + // Taken, mostly, from the Puppet official variable standards regex + var variable_regex = /({)?([a-z][a-z0-9_]*)?((::[a-z][a-z0-9_]*)*::)?[a-zA-Z0-9_]+(})?/; + + // Takes a string of words separated by spaces and adds them as + // keys with the value of the first argument 'style' + function define(style, string) { + var split = string.split(' '); + for (var i = 0; i < split.length; i++) { + words[split[i]] = style; + } + } + + // Takes commonly known puppet types/words and classifies them to a style + define('keyword', 'class define site node include import inherits'); + define('keyword', 'case if else in and elsif default or'); + define('atom', 'false true running present absent file directory undef'); + define('builtin', 'action augeas burst chain computer cron destination dport exec ' + + 'file filebucket group host icmp iniface interface jump k5login limit log_level ' + + 'log_prefix macauthorization mailalias maillist mcx mount nagios_command ' + + 'nagios_contact nagios_contactgroup nagios_host nagios_hostdependency ' + + 'nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service ' + + 'nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo ' + + 'nagios_servicegroup nagios_timeperiod name notify outiface package proto reject ' + + 'resources router schedule scheduled_task selboolean selmodule service source ' + + 'sport ssh_authorized_key sshkey stage state table tidy todest toports tosource ' + + 'user vlan yumrepo zfs zone zpool'); + + // After finding a start of a string ('|") this function attempts to find the end; + // If a variable is encountered along the way, we display it differently when it + // is encapsulated in a double-quoted string. + function tokenString(stream, state) { + var current, prev, found_var = false; + while (!stream.eol() && (current = stream.next()) != state.pending) { + if (current === '$' && prev != '\\' && state.pending == '"') { + found_var = true; + break; + } + prev = current; + } + if (found_var) { + stream.backUp(1); + } + if (current == state.pending) { + state.continueString = false; + } else { + state.continueString = true; + } + return "string"; + } + + // Main function + function tokenize(stream, state) { + // Matches one whole word + var word = stream.match(/[\w]+/, false); + // Matches attributes (i.e. ensure => present ; 'ensure' would be matched) + var attribute = stream.match(/(\s+)?\w+\s+=>.*/, false); + // Matches non-builtin resource declarations + // (i.e. "apache::vhost {" or "mycustomclasss {" would be matched) + var resource = stream.match(/(\s+)?[\w:_]+(\s+)?{/, false); + // Matches virtual and exported resources (i.e. @@user { ; and the like) + var special_resource = stream.match(/(\s+)?[@]{1,2}[\w:_]+(\s+)?{/, false); + + // Finally advance the stream + var ch = stream.next(); + + // Have we found a variable? + if (ch === '$') { + if (stream.match(variable_regex)) { + // If so, and its in a string, assign it a different color + return state.continueString ? 'variable-2' : 'variable'; + } + // Otherwise return an invalid variable + return "error"; + } + // Should we still be looking for the end of a string? + if (state.continueString) { + // If so, go through the loop again + stream.backUp(1); + return tokenString(stream, state); + } + // Are we in a definition (class, node, define)? + if (state.inDefinition) { + // If so, return def (i.e. for 'class myclass {' ; 'myclass' would be matched) + if (stream.match(/(\s+)?[\w:_]+(\s+)?/)) { + return 'def'; + } + // Match the rest it the next time around + stream.match(/\s+{/); + state.inDefinition = false; + } + // Are we in an 'include' statement? + if (state.inInclude) { + // Match and return the included class + stream.match(/(\s+)?\S+(\s+)?/); + state.inInclude = false; + return 'def'; + } + // Do we just have a function on our hands? + // In 'ensure_resource("myclass")', 'ensure_resource' is matched + if (stream.match(/(\s+)?\w+\(/)) { + stream.backUp(1); + return 'def'; + } + // Have we matched the prior attribute regex? + if (attribute) { + stream.match(/(\s+)?\w+/); + return 'tag'; + } + // Do we have Puppet specific words? + if (word && words.hasOwnProperty(word)) { + // Negates the initial next() + stream.backUp(1); + // rs move the stream + stream.match(/[\w]+/); + // We want to process these words differently + // do to the importance they have in Puppet + if (stream.match(/\s+\S+\s+{/, false)) { + state.inDefinition = true; + } + if (word == 'include') { + state.inInclude = true; + } + // Returns their value as state in the prior define methods + return words[word]; + } + // Is there a match on a reference? + if (/(^|\s+)[A-Z][\w:_]+/.test(word)) { + // Negate the next() + stream.backUp(1); + // Match the full reference + stream.match(/(^|\s+)[A-Z][\w:_]+/); + return 'def'; + } + // Have we matched the prior resource regex? + if (resource) { + stream.match(/(\s+)?[\w:_]+/); + return 'def'; + } + // Have we matched the prior special_resource regex? + if (special_resource) { + stream.match(/(\s+)?[@]{1,2}/); + return 'special'; + } + // Match all the comments. All of them. + if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + // Have we found a string? + if (ch == "'" || ch == '"') { + // Store the type (single or double) + state.pending = ch; + // Perform the looping function to find the end + return tokenString(stream, state); + } + // Match all the brackets + if (ch == '{' || ch == '}') { + return 'bracket'; + } + // Match characters that we are going to assume + // are trying to be regex + if (ch == '/') { + stream.match(/.*?\//); + return 'variable-3'; + } + // Match all the numbers + if (ch.match(/[0-9]/)) { + stream.eatWhile(/[0-9]+/); + return 'number'; + } + // Match the '=' and '=>' operators + if (ch == '=') { + if (stream.peek() == '>') { + stream.next(); + } + return "operator"; + } + // Keep advancing through all the rest + stream.eatWhile(/[\w-]/); + // Return a blank line for everything else + return null; + } + // Start it all + return { + startState: function () { + var state = {}; + state.inDefinition = false; + state.inInclude = false; + state.continueString = false; + state.pending = false; + return state; + }, + token: function (stream, state) { + // Strip the spaces, but regex will account for them eitherway + if (stream.eatSpace()) return null; + // Go through the main process + return tokenize(stream, state); + } + }; +}); + +CodeMirror.defineMIME("text/x-puppet", "puppet"); + +}); diff --git a/backend/webif/static/codemirror/mode/python/index.html b/backend/webif/static/codemirror/mode/python/index.html new file mode 100755 index 000000000..0ac02a333 --- /dev/null +++ b/backend/webif/static/codemirror/mode/python/index.html @@ -0,0 +1,198 @@ + + +CodeMirror: Python mode + + + + + + + + + + +
+

Python mode

+ +
+ + +

Cython mode

+ +
+ + +

Configuration Options for Python mode:

+
    +
  • version - 2/3 - The version of Python to recognize. Default is 3.
  • +
  • singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.
  • +
  • hangingIndent - int - If you want to write long arguments to a function starting on a new line, how much that line should be indented. Defaults to one normal indentation unit.
  • +
+

Advanced Configuration Options:

+

Usefull for superset of python syntax like Enthought enaml, IPython magics and questionmark help

+
    +
  • singleOperators - RegEx - Regular Expression for single operator matching, default :
    ^[\\+\\-\\*/%&|\\^~<>!]
    including
    @
    on Python 3
  • +
  • singleDelimiters - RegEx - Regular Expression for single delimiter matching, default :
    ^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]
  • +
  • doubleOperators - RegEx - Regular Expression for double operators matching, default :
    ^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))
  • +
  • doubleDelimiters - RegEx - Regular Expression for double delimiters matching, default :
    ^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))
  • +
  • tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default :
    ^((//=)|(>>=)|(<<=)|(\\*\\*=))
  • +
  • identifiers - RegEx - Regular Expression for identifier, default :
    ^[_A-Za-z][_A-Za-z0-9]*
    on Python 2 and
    ^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*
    on Python 3.
  • +
  • extra_keywords - list of string - List of extra words ton consider as keywords
  • +
  • extra_builtins - list of string - List of extra words ton consider as builtins
  • +
+ + +

MIME types defined: text/x-python and text/x-cython.

+
diff --git a/backend/webif/static/codemirror/mode/python/python.js b/backend/webif/static/codemirror/mode/python/python.js new file mode 100755 index 000000000..c31879320 --- /dev/null +++ b/backend/webif/static/codemirror/mode/python/python.js @@ -0,0 +1,334 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + var wordOperators = wordRegexp(["and", "or", "not", "is"]); + var commonKeywords = ["as", "assert", "break", "class", "continue", + "def", "del", "elif", "else", "except", "finally", + "for", "from", "global", "if", "import", + "lambda", "pass", "raise", "return", + "try", "while", "with", "yield", "in"]; + var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr", + "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod", + "enumerate", "eval", "filter", "float", "format", "frozenset", + "getattr", "globals", "hasattr", "hash", "help", "hex", "id", + "input", "int", "isinstance", "issubclass", "iter", "len", + "list", "locals", "map", "max", "memoryview", "min", "next", + "object", "oct", "open", "ord", "pow", "property", "range", + "repr", "reversed", "round", "set", "setattr", "slice", + "sorted", "staticmethod", "str", "sum", "super", "tuple", + "type", "vars", "zip", "__import__", "NotImplemented", + "Ellipsis", "__debug__"]; + CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins)); + + function top(state) { + return state.scopes[state.scopes.length - 1]; + } + + CodeMirror.defineMode("python", function(conf, parserConf) { + var ERRORCLASS = "error"; + + var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/; + // (Backwards-compatiblity with old, cumbersome config system) + var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters, + parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/] + for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1) + + var hangingIndent = parserConf.hangingIndent || conf.indentUnit; + + var myKeywords = commonKeywords, myBuiltins = commonBuiltins; + if (parserConf.extra_keywords != undefined) + myKeywords = myKeywords.concat(parserConf.extra_keywords); + + if (parserConf.extra_builtins != undefined) + myBuiltins = myBuiltins.concat(parserConf.extra_builtins); + + var py3 = !(parserConf.version && Number(parserConf.version) < 3) + if (py3) { + // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator + var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/; + myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]); + myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]); + var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i"); + } else { + var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/; + myKeywords = myKeywords.concat(["exec", "print"]); + myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile", + "file", "intern", "long", "raw_input", "reduce", "reload", + "unichr", "unicode", "xrange", "False", "True", "None"]); + var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i"); + } + var keywords = wordRegexp(myKeywords); + var builtins = wordRegexp(myBuiltins); + + // tokenizers + function tokenBase(stream, state) { + if (stream.sol()) state.indent = stream.indentation() + // Handle scope changes + if (stream.sol() && top(state).type == "py") { + var scopeOffset = top(state).offset; + if (stream.eatSpace()) { + var lineOffset = stream.indentation(); + if (lineOffset > scopeOffset) + pushPyScope(state); + else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#") + state.errorToken = true; + return null; + } else { + var style = tokenBaseInner(stream, state); + if (scopeOffset > 0 && dedent(stream, state)) + style += " " + ERRORCLASS; + return style; + } + } + return tokenBaseInner(stream, state); + } + + function tokenBaseInner(stream, state) { + if (stream.eatSpace()) return null; + + var ch = stream.peek(); + + // Handle Comments + if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + + // Handle Number Literals + if (stream.match(/^[0-9\.]/, false)) { + var floatLiteral = false; + // Floats + if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; } + if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; } + if (stream.match(/^\.\d+/)) { floatLiteral = true; } + if (floatLiteral) { + // Float literals may be "imaginary" + stream.eat(/J/i); + return "number"; + } + // Integers + var intLiteral = false; + // Hex + if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true; + // Binary + if (stream.match(/^0b[01_]+/i)) intLiteral = true; + // Octal + if (stream.match(/^0o[0-7_]+/i)) intLiteral = true; + // Decimal + if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) { + // Decimal literals may be "imaginary" + stream.eat(/J/i); + // TODO - Can you have imaginary longs? + intLiteral = true; + } + // Zero by itself with no other piece of number. + if (stream.match(/^0(?![\dx])/i)) intLiteral = true; + if (intLiteral) { + // Integer literals may be "long" + stream.eat(/L/i); + return "number"; + } + } + + // Handle Strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } + + for (var i = 0; i < operators.length; i++) + if (stream.match(operators[i])) return "operator" + + if (stream.match(delimiters)) return "punctuation"; + + if (state.lastToken == "." && stream.match(identifiers)) + return "property"; + + if (stream.match(keywords) || stream.match(wordOperators)) + return "keyword"; + + if (stream.match(builtins)) + return "builtin"; + + if (stream.match(/^(self|cls)\b/)) + return "variable-2"; + + if (stream.match(identifiers)) { + if (state.lastToken == "def" || state.lastToken == "class") + return "def"; + return "variable"; + } + + // Handle non-detected items + stream.next(); + return ERRORCLASS; + } + + function tokenStringFactory(delimiter) { + while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0) + delimiter = delimiter.substr(1); + + var singleline = delimiter.length == 1; + var OUTCLASS = "string"; + + function tokenString(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"\\]/); + if (stream.eat("\\")) { + stream.next(); + if (singleline && stream.eol()) + return OUTCLASS; + } else if (stream.match(delimiter)) { + state.tokenize = tokenBase; + return OUTCLASS; + } else { + stream.eat(/['"]/); + } + } + if (singleline) { + if (parserConf.singleLineStringErrors) + return ERRORCLASS; + else + state.tokenize = tokenBase; + } + return OUTCLASS; + } + tokenString.isString = true; + return tokenString; + } + + function pushPyScope(state) { + while (top(state).type != "py") state.scopes.pop() + state.scopes.push({offset: top(state).offset + conf.indentUnit, + type: "py", + align: null}) + } + + function pushBracketScope(stream, state, type) { + var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1 + state.scopes.push({offset: state.indent + hangingIndent, + type: type, + align: align}) + } + + function dedent(stream, state) { + var indented = stream.indentation(); + while (state.scopes.length > 1 && top(state).offset > indented) { + if (top(state).type != "py") return true; + state.scopes.pop(); + } + return top(state).offset != indented; + } + + function tokenLexer(stream, state) { + if (stream.sol()) state.beginningOfLine = true; + + var style = state.tokenize(stream, state); + var current = stream.current(); + + // Handle decorators + if (state.beginningOfLine && current == "@") + return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS; + + if (/\S/.test(current)) state.beginningOfLine = false; + + if ((style == "variable" || style == "builtin") + && state.lastToken == "meta") + style = "meta"; + + // Handle scope changes. + if (current == "pass" || current == "return") + state.dedent += 1; + + if (current == "lambda") state.lambda = true; + if (current == ":" && !state.lambda && top(state).type == "py") + pushPyScope(state); + + var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1; + if (delimiter_index != -1) + pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); + + delimiter_index = "])}".indexOf(current); + if (delimiter_index != -1) { + if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent + else return ERRORCLASS; + } + if (state.dedent > 0 && stream.eol() && top(state).type == "py") { + if (state.scopes.length > 1) state.scopes.pop(); + state.dedent -= 1; + } + + return style; + } + + var external = { + startState: function(basecolumn) { + return { + tokenize: tokenBase, + scopes: [{offset: basecolumn || 0, type: "py", align: null}], + indent: basecolumn || 0, + lastToken: null, + lambda: false, + dedent: 0 + }; + }, + + token: function(stream, state) { + var addErr = state.errorToken; + if (addErr) state.errorToken = false; + var style = tokenLexer(stream, state); + + if (style && style != "comment") + state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style; + if (style == "punctuation") style = null; + + if (stream.eol() && state.lambda) + state.lambda = false; + return addErr ? style + " " + ERRORCLASS : style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase) + return state.tokenize.isString ? CodeMirror.Pass : 0; + + var scope = top(state), closing = scope.type == textAfter.charAt(0) + if (scope.align != null) + return scope.align - (closing ? 1 : 0) + else + return scope.offset - (closing ? hangingIndent : 0) + }, + + electricInput: /^\s*[\}\]\)]$/, + closeBrackets: {triples: "'\""}, + lineComment: "#", + fold: "indent" + }; + return external; + }); + + CodeMirror.defineMIME("text/x-python", "python"); + + var words = function(str) { return str.split(" "); }; + + CodeMirror.defineMIME("text/x-cython", { + name: "python", + extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+ + "extern gil include nogil property public "+ + "readonly struct union DEF IF ELIF ELSE") + }); + +}); diff --git a/backend/webif/static/codemirror/mode/python/test.js b/backend/webif/static/codemirror/mode/python/test.js new file mode 100755 index 000000000..950eed51e --- /dev/null +++ b/backend/webif/static/codemirror/mode/python/test.js @@ -0,0 +1,35 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 4}, + {name: "python", + version: 3, + singleLineStringErrors: false}); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Error, because "foobarhello" is neither a known type or property, but + // property was expected (after "and"), and it should be in parentheses. + MT("decoratorStartOfLine", + "[meta @dec]", + "[keyword def] [def function]():", + " [keyword pass]"); + + MT("decoratorIndented", + "[keyword class] [def Foo]:", + " [meta @dec]", + " [keyword def] [def function]():", + " [keyword pass]"); + + MT("matmulWithSpace:", "[variable a] [operator @] [variable b]"); + MT("matmulWithoutSpace:", "[variable a][operator @][variable b]"); + MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]"); + var before_equal_sign = ["+", "-", "*", "/", "=", "!", ">", "<"]; + for (var i = 0; i < before_equal_sign.length; ++i) { + var c = before_equal_sign[i] + MT("before_equal_sign_" + c, "[variable a] [operator " + c + "=] [variable b]"); + } + + MT("fValidStringPrefix", "[string f'this is a {formatted} string']"); + MT("uValidStringPrefix", "[string u'this is an unicode string']"); +})(); diff --git a/backend/webif/static/codemirror/mode/q/index.html b/backend/webif/static/codemirror/mode/q/index.html new file mode 100755 index 000000000..72785ba3b --- /dev/null +++ b/backend/webif/static/codemirror/mode/q/index.html @@ -0,0 +1,144 @@ + + +CodeMirror: Q mode + + + + + + + + + + +
+

Q mode

+ + +
+ + + +

MIME type defined: text/x-q.

+
diff --git a/backend/webif/static/codemirror/mode/q/q.js b/backend/webif/static/codemirror/mode/q/q.js new file mode 100755 index 000000000..9aee18ab1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/q/q.js @@ -0,0 +1,139 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("q",function(config){ + var indentUnit=config.indentUnit, + curPunc, + keywords=buildRE(["abs","acos","aj","aj0","all","and","any","asc","asin","asof","atan","attr","avg","avgs","bin","by","ceiling","cols","cor","cos","count","cov","cross","csv","cut","delete","deltas","desc","dev","differ","distinct","div","do","each","ej","enlist","eval","except","exec","exit","exp","fby","fills","first","fkeys","flip","floor","from","get","getenv","group","gtime","hclose","hcount","hdel","hopen","hsym","iasc","idesc","if","ij","in","insert","inter","inv","key","keys","last","like","list","lj","load","log","lower","lsq","ltime","ltrim","mavg","max","maxs","mcount","md5","mdev","med","meta","min","mins","mmax","mmin","mmu","mod","msum","neg","next","not","null","or","over","parse","peach","pj","plist","prd","prds","prev","prior","rand","rank","ratios","raze","read0","read1","reciprocal","reverse","rload","rotate","rsave","rtrim","save","scan","select","set","setenv","show","signum","sin","sqrt","ss","ssr","string","sublist","sum","sums","sv","system","tables","tan","til","trim","txf","type","uj","ungroup","union","update","upper","upsert","value","var","view","views","vs","wavg","where","where","while","within","wj","wj1","wsum","xasc","xbar","xcol","xcols","xdesc","xexp","xgroup","xkey","xlog","xprev","xrank"]), + E=/[|/&^!+:\\\-*%$=~#;@><,?_\'\"\[\(\]\)\s{}]/; + function buildRE(w){return new RegExp("^("+w.join("|")+")$");} + function tokenBase(stream,state){ + var sol=stream.sol(),c=stream.next(); + curPunc=null; + if(sol) + if(c=="/") + return(state.tokenize=tokenLineComment)(stream,state); + else if(c=="\\"){ + if(stream.eol()||/\s/.test(stream.peek())) + return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream):state.tokenize=tokenBase,"comment"; + else + return state.tokenize=tokenBase,"builtin"; + } + if(/\s/.test(c)) + return stream.peek()=="/"?(stream.skipToEnd(),"comment"):"whitespace"; + if(c=='"') + return(state.tokenize=tokenString)(stream,state); + if(c=='`') + return stream.eatWhile(/[A-Za-z\d_:\/.]/),"symbol"; + if(("."==c&&/\d/.test(stream.peek()))||/\d/.test(c)){ + var t=null; + stream.backUp(1); + if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([DT](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/) + || stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/) + || stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/) + || stream.match(/^\d+[ptuv]{1}/)) + t="temporal"; + else if(stream.match(/^0[NwW]{1}/) + || stream.match(/^0x[\da-fA-F]*/) + || stream.match(/^[01]+[b]{1}/) + || stream.match(/^\d+[chijn]{1}/) + || stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/)) + t="number"; + return(t&&(!(c=stream.peek())||E.test(c)))?t:(stream.next(),"error"); + } + if(/[A-Za-z]|\./.test(c)) + return stream.eatWhile(/[A-Za-z._\d]/),keywords.test(stream.current())?"keyword":"variable"; + if(/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c)) + return null; + if(/[{}\(\[\]\)]/.test(c)) + return null; + return"error"; + } + function tokenLineComment(stream,state){ + return stream.skipToEnd(),/\/\s*$/.test(stream.current())?(state.tokenize=tokenBlockComment)(stream,state):(state.tokenize=tokenBase),"comment"; + } + function tokenBlockComment(stream,state){ + var f=stream.sol()&&stream.peek()=="\\"; + stream.skipToEnd(); + if(f&&/^\\\s*$/.test(stream.current())) + state.tokenize=tokenBase; + return"comment"; + } + function tokenCommentToEOF(stream){return stream.skipToEnd(),"comment";} + function tokenString(stream,state){ + var escaped=false,next,end=false; + while((next=stream.next())){ + if(next=="\""&&!escaped){end=true;break;} + escaped=!escaped&&next=="\\"; + } + if(end)state.tokenize=tokenBase; + return"string"; + } + function pushContext(state,type,col){state.context={prev:state.context,indent:state.indent,col:col,type:type};} + function popContext(state){state.indent=state.context.indent;state.context=state.context.prev;} + return{ + startState:function(){ + return{tokenize:tokenBase, + context:null, + indent:0, + col:0}; + }, + token:function(stream,state){ + if(stream.sol()){ + if(state.context&&state.context.align==null) + state.context.align=false; + state.indent=stream.indentation(); + } + //if (stream.eatSpace()) return null; + var style=state.tokenize(stream,state); + if(style!="comment"&&state.context&&state.context.align==null&&state.context.type!="pattern"){ + state.context.align=true; + } + if(curPunc=="(")pushContext(state,")",stream.column()); + else if(curPunc=="[")pushContext(state,"]",stream.column()); + else if(curPunc=="{")pushContext(state,"}",stream.column()); + else if(/[\]\}\)]/.test(curPunc)){ + while(state.context&&state.context.type=="pattern")popContext(state); + if(state.context&&curPunc==state.context.type)popContext(state); + } + else if(curPunc=="."&&state.context&&state.context.type=="pattern")popContext(state); + else if(/atom|string|variable/.test(style)&&state.context){ + if(/[\}\]]/.test(state.context.type)) + pushContext(state,"pattern",stream.column()); + else if(state.context.type=="pattern"&&!state.context.align){ + state.context.align=true; + state.context.col=stream.column(); + } + } + return style; + }, + indent:function(state,textAfter){ + var firstChar=textAfter&&textAfter.charAt(0); + var context=state.context; + if(/[\]\}]/.test(firstChar)) + while (context&&context.type=="pattern")context=context.prev; + var closing=context&&firstChar==context.type; + if(!context) + return 0; + else if(context.type=="pattern") + return context.col; + else if(context.align) + return context.col+(closing?0:1); + else + return context.indent+(closing?0:indentUnit); + } + }; +}); +CodeMirror.defineMIME("text/x-q","q"); + +}); diff --git a/backend/webif/static/codemirror/mode/r/index.html b/backend/webif/static/codemirror/mode/r/index.html new file mode 100755 index 000000000..01b6e664b --- /dev/null +++ b/backend/webif/static/codemirror/mode/r/index.html @@ -0,0 +1,88 @@ + + +CodeMirror: R mode + + + + + + + + + +
+

R mode

+
+ + +

MIME types defined: text/x-rsrc.

+ +

Development of the CodeMirror R mode was kindly sponsored + by Ubalo.

+ +
diff --git a/backend/webif/static/codemirror/mode/r/r.js b/backend/webif/static/codemirror/mode/r/r.js new file mode 100755 index 000000000..be7db46b8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/r/r.js @@ -0,0 +1,183 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("wordChars", "r", /[\w.]/); + +CodeMirror.defineMode("r", function(config) { + function wordObj(str) { + var words = str.split(" "), res = {}; + for (var i = 0; i < words.length; ++i) res[words[i]] = true; + return res; + } + var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_"); + var builtins = wordObj("list quote bquote eval return call parse deparse"); + var keywords = wordObj("if else repeat while function for in next break"); + var blockkeywords = wordObj("if else repeat while function for"); + var opChars = /[+\-*\/^<>=!&|~$:]/; + var curPunc; + + function tokenBase(stream, state) { + curPunc = null; + var ch = stream.next(); + if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } else if (ch == "0" && stream.eat("x")) { + stream.eatWhile(/[\da-f]/i); + return "number"; + } else if (ch == "." && stream.eat(/\d/)) { + stream.match(/\d*(?:e[+\-]?\d+)?/); + return "number"; + } else if (/\d/.test(ch)) { + stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/); + return "number"; + } else if (ch == "'" || ch == '"') { + state.tokenize = tokenString(ch); + return "string"; + } else if (ch == "`") { + stream.match(/[^`]+`/); + return "variable-3"; + } else if (ch == "." && stream.match(/.[.\d]+/)) { + return "keyword"; + } else if (/[\w\.]/.test(ch) && ch != "_") { + stream.eatWhile(/[\w\.]/); + var word = stream.current(); + if (atoms.propertyIsEnumerable(word)) return "atom"; + if (keywords.propertyIsEnumerable(word)) { + // Block keywords start new blocks, except 'else if', which only starts + // one new block for the 'if', no block for the 'else'. + if (blockkeywords.propertyIsEnumerable(word) && + !stream.match(/\s*if(\s+|$)/, false)) + curPunc = "block"; + return "keyword"; + } + if (builtins.propertyIsEnumerable(word)) return "builtin"; + return "variable"; + } else if (ch == "%") { + if (stream.skipTo("%")) stream.next(); + return "operator variable-2"; + } else if ( + (ch == "<" && stream.eat("-")) || + (ch == "<" && stream.match("<-")) || + (ch == "-" && stream.match(/>>?/)) + ) { + return "operator arrow"; + } else if (ch == "=" && state.ctx.argList) { + return "arg-is"; + } else if (opChars.test(ch)) { + if (ch == "$") return "operator dollar"; + stream.eatWhile(opChars); + return "operator"; + } else if (/[\(\){}\[\];]/.test(ch)) { + curPunc = ch; + if (ch == ";") return "semi"; + return null; + } else { + return null; + } + } + + function tokenString(quote) { + return function(stream, state) { + if (stream.eat("\\")) { + var ch = stream.next(); + if (ch == "x") stream.match(/^[a-f0-9]{2}/i); + else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next(); + else if (ch == "u") stream.match(/^[a-f0-9]{4}/i); + else if (ch == "U") stream.match(/^[a-f0-9]{8}/i); + else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/); + return "string-2"; + } else { + var next; + while ((next = stream.next()) != null) { + if (next == quote) { state.tokenize = tokenBase; break; } + if (next == "\\") { stream.backUp(1); break; } + } + return "string"; + } + }; + } + + var ALIGN_YES = 1, ALIGN_NO = 2, BRACELESS = 4 + + function push(state, type, stream) { + state.ctx = {type: type, + indent: state.indent, + flags: 0, + column: stream.column(), + prev: state.ctx}; + } + function setFlag(state, flag) { + var ctx = state.ctx + state.ctx = {type: ctx.type, + indent: ctx.indent, + flags: ctx.flags | flag, + column: ctx.column, + prev: ctx.prev} + } + function pop(state) { + state.indent = state.ctx.indent; + state.ctx = state.ctx.prev; + } + + return { + startState: function() { + return {tokenize: tokenBase, + ctx: {type: "top", + indent: -config.indentUnit, + flags: ALIGN_NO}, + indent: 0, + afterIdent: false}; + }, + + token: function(stream, state) { + if (stream.sol()) { + if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO + if (state.ctx.flags & BRACELESS) pop(state) + state.indent = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (style != "comment" && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES) + + if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && state.ctx.type == "block") pop(state); + if (curPunc == "{") push(state, "}", stream); + else if (curPunc == "(") { + push(state, ")", stream); + if (state.afterIdent) state.ctx.argList = true; + } + else if (curPunc == "[") push(state, "]", stream); + else if (curPunc == "block") push(state, "block", stream); + else if (curPunc == state.ctx.type) pop(state); + else if (state.ctx.type == "block" && style != "comment") setFlag(state, BRACELESS) + state.afterIdent = style == "variable" || style == "keyword"; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx, + closing = firstChar == ctx.type; + if (ctx.flags & BRACELESS) ctx = ctx.prev + if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit); + else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1); + else return ctx.indent + (closing ? 0 : config.indentUnit); + }, + + lineComment: "#" + }; +}); + +CodeMirror.defineMIME("text/x-rsrc", "r"); + +}); diff --git a/backend/webif/static/codemirror/mode/rpm/changes/index.html b/backend/webif/static/codemirror/mode/rpm/changes/index.html new file mode 100755 index 000000000..6e5031bd1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/rpm/changes/index.html @@ -0,0 +1,66 @@ + + +CodeMirror: RPM changes mode + + + + + + + + + + + +
+

RPM changes mode

+ +
+ + +

MIME types defined: text/x-rpm-changes.

+
diff --git a/backend/webif/static/codemirror/mode/rpm/index.html b/backend/webif/static/codemirror/mode/rpm/index.html new file mode 100755 index 000000000..9a34e6dfb --- /dev/null +++ b/backend/webif/static/codemirror/mode/rpm/index.html @@ -0,0 +1,149 @@ + + +CodeMirror: RPM changes mode + + + + + + + + + + + +
+

RPM changes mode

+ +
+ + +

RPM spec mode

+ +
+ + +

MIME types defined: text/x-rpm-spec, text/x-rpm-changes.

+
diff --git a/backend/webif/static/codemirror/mode/rpm/rpm.js b/backend/webif/static/codemirror/mode/rpm/rpm.js new file mode 100755 index 000000000..87cde591a --- /dev/null +++ b/backend/webif/static/codemirror/mode/rpm/rpm.js @@ -0,0 +1,109 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("rpm-changes", function() { + var headerSeperator = /^-+$/; + var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /; + var simpleEmail = /^[\w+.-]+@[\w.-]+/; + + return { + token: function(stream) { + if (stream.sol()) { + if (stream.match(headerSeperator)) { return 'tag'; } + if (stream.match(headerLine)) { return 'tag'; } + } + if (stream.match(simpleEmail)) { return 'string'; } + stream.next(); + return null; + } + }; +}); + +CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes"); + +// Quick and dirty spec file highlighting + +CodeMirror.defineMode("rpm-spec", function() { + var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/; + + var preamble = /^[a-zA-Z0-9()]+:/; + var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/; + var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros + var control_flow_simple = /^%(else|endif)/; // rpm control flow macros + var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros + + return { + startState: function () { + return { + controlFlow: false, + macroParameters: false, + section: false + }; + }, + token: function (stream, state) { + var ch = stream.peek(); + if (ch == "#") { stream.skipToEnd(); return "comment"; } + + if (stream.sol()) { + if (stream.match(preamble)) { return "header"; } + if (stream.match(section)) { return "atom"; } + } + + if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT' + if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}' + + if (stream.match(control_flow_simple)) { return "keyword"; } + if (stream.match(control_flow_complex)) { + state.controlFlow = true; + return "keyword"; + } + if (state.controlFlow) { + if (stream.match(operators)) { return "operator"; } + if (stream.match(/^(\d+)/)) { return "number"; } + if (stream.eol()) { state.controlFlow = false; } + } + + if (stream.match(arch)) { + if (stream.eol()) { state.controlFlow = false; } + return "number"; + } + + // Macros like '%make_install' or '%attr(0775,root,root)' + if (stream.match(/^%[\w]+/)) { + if (stream.match(/^\(/)) { state.macroParameters = true; } + return "keyword"; + } + if (state.macroParameters) { + if (stream.match(/^\d+/)) { return "number";} + if (stream.match(/^\)/)) { + state.macroParameters = false; + return "keyword"; + } + } + + // Macros like '%{defined fedora}' + if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) { + if (stream.eol()) { state.controlFlow = false; } + return "def"; + } + + //TODO: Include bash script sub-parser (CodeMirror supports that) + stream.next(); + return null; + } + }; +}); + +CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec"); + +}); diff --git a/backend/webif/static/codemirror/mode/rst/index.html b/backend/webif/static/codemirror/mode/rst/index.html new file mode 100755 index 000000000..2902dea23 --- /dev/null +++ b/backend/webif/static/codemirror/mode/rst/index.html @@ -0,0 +1,535 @@ + + +CodeMirror: reStructuredText mode + + + + + + + + + + +
+

reStructuredText mode

+
+ + +

+ The python mode will be used for highlighting blocks + containing Python/IPython terminal sessions: blocks starting with + >>> (for Python) or In [num]: (for + IPython). + + Further, the stex mode will be used for highlighting + blocks containing LaTex code. +

+ +

MIME types defined: text/x-rst.

+
diff --git a/backend/webif/static/codemirror/mode/rst/rst.js b/backend/webif/static/codemirror/mode/rst/rst.js new file mode 100755 index 000000000..bcf110c1a --- /dev/null +++ b/backend/webif/static/codemirror/mode/rst/rst.js @@ -0,0 +1,557 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('rst', function (config, options) { + + var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/; + var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/; + var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/; + + var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/; + var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/; + var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/; + + var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://"; + var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})"; + var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*"; + var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path); + + var overlay = { + token: function (stream) { + + if (stream.match(rx_strong) && stream.match (/\W+|$/, false)) + return 'strong'; + if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false)) + return 'em'; + if (stream.match(rx_literal) && stream.match (/\W+|$/, false)) + return 'string-2'; + if (stream.match(rx_number)) + return 'number'; + if (stream.match(rx_positive)) + return 'positive'; + if (stream.match(rx_negative)) + return 'negative'; + if (stream.match(rx_uri)) + return 'link'; + + while (stream.next() != null) { + if (stream.match(rx_strong, false)) break; + if (stream.match(rx_emphasis, false)) break; + if (stream.match(rx_literal, false)) break; + if (stream.match(rx_number, false)) break; + if (stream.match(rx_positive, false)) break; + if (stream.match(rx_negative, false)) break; + if (stream.match(rx_uri, false)) break; + } + + return null; + } + }; + + var mode = CodeMirror.getMode( + config, options.backdrop || 'rst-base' + ); + + return CodeMirror.overlayMode(mode, overlay, true); // combine +}, 'python', 'stex'); + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +CodeMirror.defineMode('rst-base', function (config) { + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function format(string) { + var args = Array.prototype.slice.call(arguments, 1); + return string.replace(/{(\d+)}/g, function (match, n) { + return typeof args[n] != 'undefined' ? args[n] : match; + }); + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + var mode_python = CodeMirror.getMode(config, 'python'); + var mode_stex = CodeMirror.getMode(config, 'stex'); + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + var SEPA = "\\s+"; + var TAIL = "(?:\\s*|\\W|$)", + rx_TAIL = new RegExp(format('^{0}', TAIL)); + + var NAME = + "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)", + rx_NAME = new RegExp(format('^{0}', NAME)); + var NAME_WWS = + "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)"; + var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS); + + var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)"; + var TEXT2 = "(?:[^\\`]+)", + rx_TEXT2 = new RegExp(format('^{0}', TEXT2)); + + var rx_section = new RegExp( + "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$"); + var rx_explicit = new RegExp( + format('^\\.\\.{0}', SEPA)); + var rx_link = new RegExp( + format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL)); + var rx_directive = new RegExp( + format('^{0}::{1}', REF_NAME, TAIL)); + var rx_substitution = new RegExp( + format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL)); + var rx_footnote = new RegExp( + format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL)); + var rx_citation = new RegExp( + format('^\\[{0}\\]{1}', REF_NAME, TAIL)); + + var rx_substitution_ref = new RegExp( + format('^\\|{0}\\|', TEXT1)); + var rx_footnote_ref = new RegExp( + format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME)); + var rx_citation_ref = new RegExp( + format('^\\[{0}\\]_', REF_NAME)); + var rx_link_ref1 = new RegExp( + format('^{0}__?', REF_NAME)); + var rx_link_ref2 = new RegExp( + format('^`{0}`_', TEXT2)); + + var rx_role_pre = new RegExp( + format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL)); + var rx_role_suf = new RegExp( + format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL)); + var rx_role = new RegExp( + format('^:{0}:{1}', NAME, TAIL)); + + var rx_directive_name = new RegExp(format('^{0}', REF_NAME)); + var rx_directive_tail = new RegExp(format('^::{0}', TAIL)); + var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1)); + var rx_substitution_sepa = new RegExp(format('^{0}', SEPA)); + var rx_substitution_name = new RegExp(format('^{0}', REF_NAME)); + var rx_substitution_tail = new RegExp(format('^::{0}', TAIL)); + var rx_link_head = new RegExp("^_"); + var rx_link_name = new RegExp(format('^{0}|_', REF_NAME)); + var rx_link_tail = new RegExp(format('^:{0}', TAIL)); + + var rx_verbatim = new RegExp('^::\\s*$'); + var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s'); + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_normal(stream, state) { + var token = null; + + if (stream.sol() && stream.match(rx_examples, false)) { + change(state, to_mode, { + mode: mode_python, local: CodeMirror.startState(mode_python) + }); + } else if (stream.sol() && stream.match(rx_explicit)) { + change(state, to_explicit); + token = 'meta'; + } else if (stream.sol() && stream.match(rx_section)) { + change(state, to_normal); + token = 'header'; + } else if (phase(state) == rx_role_pre || + stream.match(rx_role_pre, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role_pre, 1)); + stream.match(/^:/); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role_pre, 2)); + stream.match(rx_NAME); + token = 'keyword'; + + if (stream.current().match(/^(?:math|latex)/)) { + state.tmp_stex = true; + } + break; + case 2: + change(state, to_normal, context(rx_role_pre, 3)); + stream.match(/^:`/); + token = 'meta'; + break; + case 3: + if (state.tmp_stex) { + state.tmp_stex = undefined; state.tmp = { + mode: mode_stex, local: CodeMirror.startState(mode_stex) + }; + } + + if (state.tmp) { + if (stream.peek() == '`') { + change(state, to_normal, context(rx_role_pre, 4)); + state.tmp = undefined; + break; + } + + token = state.tmp.mode.token(stream, state.tmp.local); + break; + } + + change(state, to_normal, context(rx_role_pre, 4)); + stream.match(rx_TEXT2); + token = 'string'; + break; + case 4: + change(state, to_normal, context(rx_role_pre, 5)); + stream.match(/^`/); + token = 'meta'; + break; + case 5: + change(state, to_normal, context(rx_role_pre, 6)); + stream.match(rx_TAIL); + break; + default: + change(state, to_normal); + } + } else if (phase(state) == rx_role_suf || + stream.match(rx_role_suf, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role_suf, 1)); + stream.match(/^`/); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role_suf, 2)); + stream.match(rx_TEXT2); + token = 'string'; + break; + case 2: + change(state, to_normal, context(rx_role_suf, 3)); + stream.match(/^`:/); + token = 'meta'; + break; + case 3: + change(state, to_normal, context(rx_role_suf, 4)); + stream.match(rx_NAME); + token = 'keyword'; + break; + case 4: + change(state, to_normal, context(rx_role_suf, 5)); + stream.match(/^:/); + token = 'meta'; + break; + case 5: + change(state, to_normal, context(rx_role_suf, 6)); + stream.match(rx_TAIL); + break; + default: + change(state, to_normal); + } + } else if (phase(state) == rx_role || stream.match(rx_role, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_role, 1)); + stream.match(/^:/); + token = 'meta'; + break; + case 1: + change(state, to_normal, context(rx_role, 2)); + stream.match(rx_NAME); + token = 'keyword'; + break; + case 2: + change(state, to_normal, context(rx_role, 3)); + stream.match(/^:/); + token = 'meta'; + break; + case 3: + change(state, to_normal, context(rx_role, 4)); + stream.match(rx_TAIL); + break; + default: + change(state, to_normal); + } + } else if (phase(state) == rx_substitution_ref || + stream.match(rx_substitution_ref, false)) { + + switch (stage(state)) { + case 0: + change(state, to_normal, context(rx_substitution_ref, 1)); + stream.match(rx_substitution_text); + token = 'variable-2'; + break; + case 1: + change(state, to_normal, context(rx_substitution_ref, 2)); + if (stream.match(/^_?_?/)) token = 'link'; + break; + default: + change(state, to_normal); + } + } else if (stream.match(rx_footnote_ref)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_citation_ref)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_link_ref1)) { + change(state, to_normal); + if (!stream.peek() || stream.peek().match(/^\W$/)) { + token = 'link'; + } + } else if (phase(state) == rx_link_ref2 || + stream.match(rx_link_ref2, false)) { + + switch (stage(state)) { + case 0: + if (!stream.peek() || stream.peek().match(/^\W$/)) { + change(state, to_normal, context(rx_link_ref2, 1)); + } else { + stream.match(rx_link_ref2); + } + break; + case 1: + change(state, to_normal, context(rx_link_ref2, 2)); + stream.match(/^`/); + token = 'link'; + break; + case 2: + change(state, to_normal, context(rx_link_ref2, 3)); + stream.match(rx_TEXT2); + break; + case 3: + change(state, to_normal, context(rx_link_ref2, 4)); + stream.match(/^`_/); + token = 'link'; + break; + default: + change(state, to_normal); + } + } else if (stream.match(rx_verbatim)) { + change(state, to_verbatim); + } + + else { + if (stream.next()) change(state, to_normal); + } + + return token; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_explicit(stream, state) { + var token = null; + + if (phase(state) == rx_substitution || + stream.match(rx_substitution, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_substitution, 1)); + stream.match(rx_substitution_text); + token = 'variable-2'; + break; + case 1: + change(state, to_explicit, context(rx_substitution, 2)); + stream.match(rx_substitution_sepa); + break; + case 2: + change(state, to_explicit, context(rx_substitution, 3)); + stream.match(rx_substitution_name); + token = 'keyword'; + break; + case 3: + change(state, to_explicit, context(rx_substitution, 4)); + stream.match(rx_substitution_tail); + token = 'meta'; + break; + default: + change(state, to_normal); + } + } else if (phase(state) == rx_directive || + stream.match(rx_directive, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_directive, 1)); + stream.match(rx_directive_name); + token = 'keyword'; + + if (stream.current().match(/^(?:math|latex)/)) + state.tmp_stex = true; + else if (stream.current().match(/^python/)) + state.tmp_py = true; + break; + case 1: + change(state, to_explicit, context(rx_directive, 2)); + stream.match(rx_directive_tail); + token = 'meta'; + + if (stream.match(/^latex\s*$/) || state.tmp_stex) { + state.tmp_stex = undefined; change(state, to_mode, { + mode: mode_stex, local: CodeMirror.startState(mode_stex) + }); + } + break; + case 2: + change(state, to_explicit, context(rx_directive, 3)); + if (stream.match(/^python\s*$/) || state.tmp_py) { + state.tmp_py = undefined; change(state, to_mode, { + mode: mode_python, local: CodeMirror.startState(mode_python) + }); + } + break; + default: + change(state, to_normal); + } + } else if (phase(state) == rx_link || stream.match(rx_link, false)) { + + switch (stage(state)) { + case 0: + change(state, to_explicit, context(rx_link, 1)); + stream.match(rx_link_head); + stream.match(rx_link_name); + token = 'link'; + break; + case 1: + change(state, to_explicit, context(rx_link, 2)); + stream.match(rx_link_tail); + token = 'meta'; + break; + default: + change(state, to_normal); + } + } else if (stream.match(rx_footnote)) { + change(state, to_normal); + token = 'quote'; + } else if (stream.match(rx_citation)) { + change(state, to_normal); + token = 'quote'; + } + + else { + stream.eatSpace(); + if (stream.eol()) { + change(state, to_normal); + } else { + stream.skipToEnd(); + change(state, to_comment); + token = 'comment'; + } + } + + return token; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_comment(stream, state) { + return as_block(stream, state, 'comment'); + } + + function to_verbatim(stream, state) { + return as_block(stream, state, 'meta'); + } + + function as_block(stream, state, token) { + if (stream.eol() || stream.eatSpace()) { + stream.skipToEnd(); + return token; + } else { + change(state, to_normal); + return null; + } + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function to_mode(stream, state) { + + if (state.ctx.mode && state.ctx.local) { + + if (stream.sol()) { + if (!stream.eatSpace()) change(state, to_normal); + return null; + } + + return state.ctx.mode.token(stream, state.ctx.local); + } + + change(state, to_normal); + return null; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + function context(phase, stage, mode, local) { + return {phase: phase, stage: stage, mode: mode, local: local}; + } + + function change(state, tok, ctx) { + state.tok = tok; + state.ctx = ctx || {}; + } + + function stage(state) { + return state.ctx.stage || 0; + } + + function phase(state) { + return state.ctx.phase; + } + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + return { + startState: function () { + return {tok: to_normal, ctx: context(undefined, 0)}; + }, + + copyState: function (state) { + var ctx = state.ctx, tmp = state.tmp; + if (ctx.local) + ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)}; + if (tmp) + tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)}; + return {tok: state.tok, ctx: ctx, tmp: tmp}; + }, + + innerMode: function (state) { + return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode} + : state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode} + : null; + }, + + token: function (stream, state) { + return state.tok(stream, state); + } + }; +}, 'python', 'stex'); + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +CodeMirror.defineMIME('text/x-rst', 'rst'); + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +}); diff --git a/backend/webif/static/codemirror/mode/ruby/index.html b/backend/webif/static/codemirror/mode/ruby/index.html new file mode 100755 index 000000000..97544babc --- /dev/null +++ b/backend/webif/static/codemirror/mode/ruby/index.html @@ -0,0 +1,183 @@ + + +CodeMirror: Ruby mode + + + + + + + + + + +
+

Ruby mode

+
+ + +

MIME types defined: text/x-ruby.

+ +

Development of the CodeMirror Ruby mode was kindly sponsored + by Ubalo.

+ +
diff --git a/backend/webif/static/codemirror/mode/ruby/ruby.js b/backend/webif/static/codemirror/mode/ruby/ruby.js new file mode 100755 index 000000000..874c1830e --- /dev/null +++ b/backend/webif/static/codemirror/mode/ruby/ruby.js @@ -0,0 +1,296 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("ruby", function(config) { + function wordObj(words) { + var o = {}; + for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; + return o; + } + var keywords = wordObj([ + "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else", + "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or", + "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless", + "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc", + "caller", "lambda", "proc", "public", "protected", "private", "require", "load", + "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__" + ]); + var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then", + "catch", "loop", "proc", "begin"]); + var dedentWords = wordObj(["end", "until"]); + var matching = {"[": "]", "{": "}", "(": ")"}; + var curPunc; + + function chain(newtok, stream, state) { + state.tokenize.push(newtok); + return newtok(stream, state); + } + + function tokenBase(stream, state) { + if (stream.sol() && stream.match("=begin") && stream.eol()) { + state.tokenize.push(readBlockComment); + return "comment"; + } + if (stream.eatSpace()) return null; + var ch = stream.next(), m; + if (ch == "`" || ch == "'" || ch == '"') { + return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state); + } else if (ch == "/") { + if (regexpAhead(stream)) + return chain(readQuoted(ch, "string-2", true), stream, state); + else + return "operator"; + } else if (ch == "%") { + var style = "string", embed = true; + if (stream.eat("s")) style = "atom"; + else if (stream.eat(/[WQ]/)) style = "string"; + else if (stream.eat(/[r]/)) style = "string-2"; + else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; } + var delim = stream.eat(/[^\w\s=]/); + if (!delim) return "operator"; + if (matching.propertyIsEnumerable(delim)) delim = matching[delim]; + return chain(readQuoted(delim, style, embed, true), stream, state); + } else if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) { + return chain(readHereDoc(m[1]), stream, state); + } else if (ch == "0") { + if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/); + else if (stream.eat("b")) stream.eatWhile(/[01]/); + else stream.eatWhile(/[0-7]/); + return "number"; + } else if (/\d/.test(ch)) { + stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/); + return "number"; + } else if (ch == "?") { + while (stream.match(/^\\[CM]-/)) {} + if (stream.eat("\\")) stream.eatWhile(/\w/); + else stream.next(); + return "string"; + } else if (ch == ":") { + if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state); + if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state); + + // :> :>> :< :<< are valid symbols + if (stream.eat(/[\<\>]/)) { + stream.eat(/[\<\>]/); + return "atom"; + } + + // :+ :- :/ :* :| :& :! are valid symbols + if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) { + return "atom"; + } + + // Symbols can't start by a digit + if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) { + stream.eatWhile(/[\w$\xa1-\uffff]/); + // Only one ? ! = is allowed and only as the last character + stream.eat(/[\?\!\=]/); + return "atom"; + } + return "operator"; + } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) { + stream.eat("@"); + stream.eatWhile(/[\w\xa1-\uffff]/); + return "variable-2"; + } else if (ch == "$") { + if (stream.eat(/[a-zA-Z_]/)) { + stream.eatWhile(/[\w]/); + } else if (stream.eat(/\d/)) { + stream.eat(/\d/); + } else { + stream.next(); // Must be a special global like $: or $! + } + return "variable-3"; + } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) { + stream.eatWhile(/[\w\xa1-\uffff]/); + stream.eat(/[\?\!]/); + if (stream.eat(":")) return "atom"; + return "ident"; + } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) { + curPunc = "|"; + return null; + } else if (/[\(\)\[\]{}\\;]/.test(ch)) { + curPunc = ch; + return null; + } else if (ch == "-" && stream.eat(">")) { + return "arrow"; + } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) { + var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/); + if (ch == "." && !more) curPunc = "."; + return "operator"; + } else { + return null; + } + } + + function regexpAhead(stream) { + var start = stream.pos, depth = 0, next, found = false, escaped = false + while ((next = stream.next()) != null) { + if (!escaped) { + if ("[{(".indexOf(next) > -1) { + depth++ + } else if ("]})".indexOf(next) > -1) { + depth-- + if (depth < 0) break + } else if (next == "/" && depth == 0) { + found = true + break + } + escaped = next == "\\" + } else { + escaped = false + } + } + stream.backUp(stream.pos - start) + return found + } + + function tokenBaseUntilBrace(depth) { + if (!depth) depth = 1; + return function(stream, state) { + if (stream.peek() == "}") { + if (depth == 1) { + state.tokenize.pop(); + return state.tokenize[state.tokenize.length-1](stream, state); + } else { + state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1); + } + } else if (stream.peek() == "{") { + state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1); + } + return tokenBase(stream, state); + }; + } + function tokenBaseOnce() { + var alreadyCalled = false; + return function(stream, state) { + if (alreadyCalled) { + state.tokenize.pop(); + return state.tokenize[state.tokenize.length-1](stream, state); + } + alreadyCalled = true; + return tokenBase(stream, state); + }; + } + function readQuoted(quote, style, embed, unescaped) { + return function(stream, state) { + var escaped = false, ch; + + if (state.context.type === 'read-quoted-paused') { + state.context = state.context.prev; + stream.eat("}"); + } + + while ((ch = stream.next()) != null) { + if (ch == quote && (unescaped || !escaped)) { + state.tokenize.pop(); + break; + } + if (embed && ch == "#" && !escaped) { + if (stream.eat("{")) { + if (quote == "}") { + state.context = {prev: state.context, type: 'read-quoted-paused'}; + } + state.tokenize.push(tokenBaseUntilBrace()); + break; + } else if (/[@\$]/.test(stream.peek())) { + state.tokenize.push(tokenBaseOnce()); + break; + } + } + escaped = !escaped && ch == "\\"; + } + return style; + }; + } + function readHereDoc(phrase) { + return function(stream, state) { + if (stream.match(phrase)) state.tokenize.pop(); + else stream.skipToEnd(); + return "string"; + }; + } + function readBlockComment(stream, state) { + if (stream.sol() && stream.match("=end") && stream.eol()) + state.tokenize.pop(); + stream.skipToEnd(); + return "comment"; + } + + return { + startState: function() { + return {tokenize: [tokenBase], + indented: 0, + context: {type: "top", indented: -config.indentUnit}, + continuedLine: false, + lastTok: null, + varList: false}; + }, + + token: function(stream, state) { + curPunc = null; + if (stream.sol()) state.indented = stream.indentation(); + var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype; + var thisTok = curPunc; + if (style == "ident") { + var word = stream.current(); + style = state.lastTok == "." ? "property" + : keywords.propertyIsEnumerable(stream.current()) ? "keyword" + : /^[A-Z]/.test(word) ? "tag" + : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def" + : "variable"; + if (style == "keyword") { + thisTok = word; + if (indentWords.propertyIsEnumerable(word)) kwtype = "indent"; + else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent"; + else if ((word == "if" || word == "unless") && stream.column() == stream.indentation()) + kwtype = "indent"; + else if (word == "do" && state.context.indented < state.indented) + kwtype = "indent"; + } + } + if (curPunc || (style && style != "comment")) state.lastTok = thisTok; + if (curPunc == "|") state.varList = !state.varList; + + if (kwtype == "indent" || /[\(\[\{]/.test(curPunc)) + state.context = {prev: state.context, type: curPunc || style, indented: state.indented}; + else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev) + state.context = state.context.prev; + + if (stream.eol()) + state.continuedLine = (curPunc == "\\" || style == "operator"); + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0); + var ct = state.context; + var closing = ct.type == matching[firstChar] || + ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter); + return ct.indented + (closing ? 0 : config.indentUnit) + + (state.continuedLine ? config.indentUnit : 0); + }, + + electricInput: /^\s*(?:end|rescue|elsif|else|\})$/, + lineComment: "#", + fold: "indent" + }; +}); + +CodeMirror.defineMIME("text/x-ruby", "ruby"); + +}); diff --git a/backend/webif/static/codemirror/mode/ruby/test.js b/backend/webif/static/codemirror/mode/ruby/test.js new file mode 100755 index 000000000..3133bd63f --- /dev/null +++ b/backend/webif/static/codemirror/mode/ruby/test.js @@ -0,0 +1,16 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "ruby"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("divide_equal_operator", + "[variable bar] [operator /=] [variable foo]"); + + MT("divide_equal_operator_no_spacing", + "[variable foo][operator /=][number 42]"); + + MT("complex_regexp", + "[keyword if] [variable cr] [operator =~] [string-2 /(?: \\( #{][tag RE_NOT][string-2 }\\( | #{][tag RE_NOT_PAR_OR][string-2 }* #{][tag RE_OPA_OR][string-2 } )/][variable x]") +})(); diff --git a/backend/webif/static/codemirror/mode/rust/index.html b/backend/webif/static/codemirror/mode/rust/index.html new file mode 100755 index 000000000..1fe0ad1e6 --- /dev/null +++ b/backend/webif/static/codemirror/mode/rust/index.html @@ -0,0 +1,64 @@ + + +CodeMirror: Rust mode + + + + + + + + + + +
+

Rust mode

+ + +
+ + + +

MIME types defined: text/x-rustsrc.

+
diff --git a/backend/webif/static/codemirror/mode/rust/rust.js b/backend/webif/static/codemirror/mode/rust/rust.js new file mode 100755 index 000000000..b635563ae --- /dev/null +++ b/backend/webif/static/codemirror/mode/rust/rust.js @@ -0,0 +1,72 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/simple")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/simple"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineSimpleMode("rust",{ + start: [ + // string and byte string + {regex: /b?"/, token: "string", next: "string"}, + // raw string and raw byte string + {regex: /b?r"/, token: "string", next: "string_raw"}, + {regex: /b?r#+"/, token: "string", next: "string_raw_hash"}, + // character + {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"}, + // byte + {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"}, + + {regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/, + token: "number"}, + {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]}, + {regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"}, + {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"}, + {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"}, + {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, + token: ["keyword", null ,"def"]}, + {regex: /#!?\[.*\]/, token: "meta"}, + {regex: /\/\/.*/, token: "comment"}, + {regex: /\/\*/, token: "comment", next: "comment"}, + {regex: /[-+\/*=<>!]+/, token: "operator"}, + {regex: /[a-zA-Z_]\w*!/,token: "variable-3"}, + {regex: /[a-zA-Z_]\w*/, token: "variable"}, + {regex: /[\{\[\(]/, indent: true}, + {regex: /[\}\]\)]/, dedent: true} + ], + string: [ + {regex: /"/, token: "string", next: "start"}, + {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"} + ], + string_raw: [ + {regex: /"/, token: "string", next: "start"}, + {regex: /[^"]*/, token: "string"} + ], + string_raw_hash: [ + {regex: /"#+/, token: "string", next: "start"}, + {regex: /(?:[^"]|"(?!#))*/, token: "string"} + ], + comment: [ + {regex: /.*?\*\//, token: "comment", next: "start"}, + {regex: /.*/, token: "comment"} + ], + meta: { + dontIndentStates: ["comment"], + electricInput: /^\s*\}$/, + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//", + fold: "brace" + } +}); + + +CodeMirror.defineMIME("text/x-rustsrc", "rust"); +CodeMirror.defineMIME("text/rust", "rust"); +}); diff --git a/backend/webif/static/codemirror/mode/rust/test.js b/backend/webif/static/codemirror/mode/rust/test.js new file mode 100755 index 000000000..eb256c47e --- /dev/null +++ b/backend/webif/static/codemirror/mode/rust/test.js @@ -0,0 +1,39 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 4}, "rust"); + function MT(name) {test.mode(name, mode, Array.prototype.slice.call(arguments, 1));} + + MT('integer_test', + '[number 123i32]', + '[number 123u32]', + '[number 123_u32]', + '[number 0xff_u8]', + '[number 0o70_i16]', + '[number 0b1111_1111_1001_0000_i32]', + '[number 0usize]'); + + MT('float_test', + '[number 123.0f64]', + '[number 0.1f64]', + '[number 0.1f32]', + '[number 12E+99_f64]'); + + MT('string-literals-test', + '[string "foo"]', + '[string r"foo"]', + '[string "\\"foo\\""]', + '[string r#""foo""#]', + '[string "foo #\\"# bar"]', + + '[string b"foo"]', + '[string br"foo"]', + '[string b"\\"foo\\""]', + '[string br#""foo""#]', + '[string br##"foo #" bar"##]', + + "[string-2 'h']", + "[string-2 b'h']"); + +})(); diff --git a/backend/webif/static/codemirror/mode/sas/index.html b/backend/webif/static/codemirror/mode/sas/index.html new file mode 100755 index 000000000..636e06594 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sas/index.html @@ -0,0 +1,81 @@ + + +CodeMirror: SAS mode + + + + + + + + + + +
+

SAS mode

+
+ + + +

MIME types defined: text/x-sas.

+ +
diff --git a/backend/webif/static/codemirror/mode/sas/sas.js b/backend/webif/static/codemirror/mode/sas/sas.js new file mode 100755 index 000000000..d85b33534 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sas/sas.js @@ -0,0 +1,303 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + + +// SAS mode copyright (c) 2016 Jared Dean, SAS Institute +// Created by Jared Dean + +// TODO +// indent and de-indent +// identify macro variables + + +//Definitions +// comment -- text within * ; or /* */ +// keyword -- SAS language variable +// variable -- macro variables starts with '&' or variable formats +// variable-2 -- DATA Step, proc, or macro names +// string -- text within ' ' or " " +// operator -- numeric operator + / - * ** le eq ge ... and so on +// builtin -- proc %macro data run mend +// atom +// def + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("sas", function () { + var words = {}; + var isDoubleOperatorSym = { + eq: 'operator', + lt: 'operator', + le: 'operator', + gt: 'operator', + ge: 'operator', + "in": 'operator', + ne: 'operator', + or: 'operator' + }; + var isDoubleOperatorChar = /(<=|>=|!=|<>)/; + var isSingleOperatorChar = /[=\(:\),{}.*<>+\-\/^\[\]]/; + + // Takes a string of words separated by spaces and adds them as + // keys with the value of the first argument 'style' + function define(style, string, context) { + if (context) { + var split = string.split(' '); + for (var i = 0; i < split.length; i++) { + words[split[i]] = {style: style, state: context}; + } + } + } + //datastep + define('def', 'stack pgm view source debug nesting nolist', ['inDataStep']); + define('def', 'if while until for do do; end end; then else cancel', ['inDataStep']); + define('def', 'label format _n_ _error_', ['inDataStep']); + define('def', 'ALTER BUFNO BUFSIZE CNTLLEV COMPRESS DLDMGACTION ENCRYPT ENCRYPTKEY EXTENDOBSCOUNTER GENMAX GENNUM INDEX LABEL OBSBUF OUTREP PW PWREQ READ REPEMPTY REPLACE REUSE ROLE SORTEDBY SPILL TOBSNO TYPE WRITE FILECLOSE FIRSTOBS IN OBS POINTOBS WHERE WHEREUP IDXNAME IDXWHERE DROP KEEP RENAME', ['inDataStep']); + define('def', 'filevar finfo finv fipname fipnamel fipstate first firstobs floor', ['inDataStep']); + define('def', 'varfmt varinfmt varlabel varlen varname varnum varray varrayx vartype verify vformat vformatd vformatdx vformatn vformatnx vformatw vformatwx vformatx vinarray vinarrayx vinformat vinformatd vinformatdx vinformatn vinformatnx vinformatw vinformatwx vinformatx vlabel vlabelx vlength vlengthx vname vnamex vnferr vtype vtypex weekday', ['inDataStep']); + define('def', 'zipfips zipname zipnamel zipstate', ['inDataStep']); + define('def', 'put putc putn', ['inDataStep']); + define('builtin', 'data run', ['inDataStep']); + + + //proc + define('def', 'data', ['inProc']); + + // flow control for macros + define('def', '%if %end %end; %else %else; %do %do; %then', ['inMacro']); + + //everywhere + define('builtin', 'proc run; quit; libname filename %macro %mend option options', ['ALL']); + + define('def', 'footnote title libname ods', ['ALL']); + define('def', '%let %put %global %sysfunc %eval ', ['ALL']); + // automatic macro variables http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a003167023.htm + define('variable', '&sysbuffr &syscc &syscharwidth &syscmd &sysdate &sysdate9 &sysday &sysdevic &sysdmg &sysdsn &sysencoding &sysenv &syserr &syserrortext &sysfilrc &syshostname &sysindex &sysinfo &sysjobid &syslast &syslckrc &syslibrc &syslogapplname &sysmacroname &sysmenv &sysmsg &sysncpu &sysodspath &sysparm &syspbuff &sysprocessid &sysprocessname &sysprocname &sysrc &sysscp &sysscpl &sysscpl &syssite &sysstartid &sysstartname &systcpiphostname &systime &sysuserid &sysver &sysvlong &sysvlong4 &syswarningtext', ['ALL']); + + //footnote[1-9]? title[1-9]? + + //options statement + define('def', 'source2 nosource2 page pageno pagesize', ['ALL']); + + //proc and datastep + define('def', '_all_ _character_ _cmd_ _freq_ _i_ _infile_ _last_ _msg_ _null_ _numeric_ _temporary_ _type_ abort abs addr adjrsq airy alpha alter altlog altprint and arcos array arsin as atan attrc attrib attrn authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward band base betainv between blocksize blshift bnot bor brshift bufno bufsize bxor by byerr byline byte calculated call cards cards4 catcache cbufno cdf ceil center cexist change chisq cinv class cleanup close cnonct cntllev coalesce codegen col collate collin column comamid comaux1 comaux2 comdef compbl compound compress config continue convert cos cosh cpuid create cross crosstab css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datalines datalines4 datejul datepart datetime day dbcslang dbcstype dclose ddm delete delimiter depdb depdbsl depsl depsyd deptab dequote descending descript design= device dflang dhms dif digamma dim dinfo display distinct dkricond dkrocond dlm dnum do dopen doptname doptnum dread drop dropnote dsname dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov erf erfc error errorcheck errors exist exp fappend fclose fcol fdelete feedback fetch fetchobs fexist fget file fileclose fileexist filefmt filename fileref fmterr fmtsearch fnonct fnote font fontalias fopen foptname foptnum force formatted formchar formdelim formdlim forward fpoint fpos fput fread frewind frlen from fsep fuzz fwrite gaminv gamma getoption getvarc getvarn go goto group gwindow hbar hbound helpenv helploc hms honorappearance hosthelp hostprint hour hpct html hvar ibessel ibr id if index indexc indexw initcmd initstmt inner input inputc inputn inr insert int intck intnx into intrr invaliddata irr is jbessel join juldate keep kentb kurtosis label lag last lbound leave left length levels lgamma lib library libref line linesize link list log log10 log2 logpdf logpmf logsdf lostcard lowcase lrecl ls macro macrogen maps mautosource max maxdec maxr mdy mean measures median memtype merge merror min minute missing missover mlogic mod mode model modify month mopen mort mprint mrecall msglevel msymtabmax mvarsize myy n nest netpv new news nmiss no nobatch nobs nocaps nocardimage nocenter nocharcode nocmdmac nocol nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad nopercent noprint noprintinit normal norow norsasuser nosetinit nosplash nosymbolgen note notes notitle notitles notsorted noverbose noxsync noxwait npv null number numkeys nummousekeys nway obs on open order ordinal otherwise out outer outp= output over ovp p(1 5 10 25 50 75 90 95 99) pad pad2 paired parm parmcards path pathdll pathname pdf peek peekc pfkey pmf point poisson poke position printer probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probsig probt procleave prt ps pw pwreq qtr quote r ranbin rancau ranexp rangam range ranks rannor ranpoi rantbl rantri ranuni read recfm register regr remote remove rename repeat replace resolve retain return reuse reverse rewind right round rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sasmsg sasmstore sasscript sasuser saving scan sdf second select selection separated seq serror set setcomm setot sign simple sin sinh siteinfo skewness skip sle sls sortedby sortpgm sortseq sortsize soundex spedis splashlocation split spool sqrt start std stderr stdin stfips stimer stname stnamel stop stopover subgroup subpopn substr sum sumwgt symbol symbolgen symget symput sysget sysin sysleave sysmsg sysparm sysprint sysprintfont sysprod sysrc system t table tables tan tanh tapeclose tbufsize terminal test then timepart tinv tnonct to today tol tooldef totper transformout translate trantab tranwrd trigamma trim trimn trunc truncover type unformatted uniform union until upcase update user usericon uss validate value var weight when where while wincharset window work workinit workterm write wsum xsync xwait yearcutoff yes yyq min max', ['inDataStep', 'inProc']); + define('operator', 'and not ', ['inDataStep', 'inProc']); + + // Main function + function tokenize(stream, state) { + // Finally advance the stream + var ch = stream.next(); + + // BLOCKCOMMENT + if (ch === '/' && stream.eat('*')) { + state.continueComment = true; + return "comment"; + } else if (state.continueComment === true) { // in comment block + //comment ends at the beginning of the line + if (ch === '*' && stream.peek() === '/') { + stream.next(); + state.continueComment = false; + } else if (stream.skipTo('*')) { //comment is potentially later in line + stream.skipTo('*'); + stream.next(); + if (stream.eat('/')) + state.continueComment = false; + } else { + stream.skipToEnd(); + } + return "comment"; + } + + if (ch == "*" && stream.column() == stream.indentation()) { + stream.skipToEnd() + return "comment" + } + + // DoubleOperator match + var doubleOperator = ch + stream.peek(); + + if ((ch === '"' || ch === "'") && !state.continueString) { + state.continueString = ch + return "string" + } else if (state.continueString) { + if (state.continueString == ch) { + state.continueString = null; + } else if (stream.skipTo(state.continueString)) { + // quote found on this line + stream.next(); + state.continueString = null; + } else { + stream.skipToEnd(); + } + return "string"; + } else if (state.continueString !== null && stream.eol()) { + stream.skipTo(state.continueString) || stream.skipToEnd(); + return "string"; + } else if (/[\d\.]/.test(ch)) { //find numbers + if (ch === ".") + stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); + else if (ch === "0") + stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); + else + stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); + return "number"; + } else if (isDoubleOperatorChar.test(ch + stream.peek())) { // TWO SYMBOL TOKENS + stream.next(); + return "operator"; + } else if (isDoubleOperatorSym.hasOwnProperty(doubleOperator)) { + stream.next(); + if (stream.peek() === ' ') + return isDoubleOperatorSym[doubleOperator.toLowerCase()]; + } else if (isSingleOperatorChar.test(ch)) { // SINGLE SYMBOL TOKENS + return "operator"; + } + + // Matches one whole word -- even if the word is a character + var word; + if (stream.match(/[%&;\w]+/, false) != null) { + word = ch + stream.match(/[%&;\w]+/, true); + if (/&/.test(word)) return 'variable' + } else { + word = ch; + } + // the word after DATA PROC or MACRO + if (state.nextword) { + stream.match(/[\w]+/); + // match memname.libname + if (stream.peek() === '.') stream.skipTo(' '); + state.nextword = false; + return 'variable-2'; + } + + word = word.toLowerCase() + // Are we in a DATA Step? + if (state.inDataStep) { + if (word === 'run;' || stream.match(/run\s;/)) { + state.inDataStep = false; + return 'builtin'; + } + // variable formats + if ((word) && stream.next() === '.') { + //either a format or libname.memname + if (/\w/.test(stream.peek())) return 'variable-2'; + else return 'variable'; + } + // do we have a DATA Step keyword + if (word && words.hasOwnProperty(word) && + (words[word].state.indexOf("inDataStep") !== -1 || + words[word].state.indexOf("ALL") !== -1)) { + //backup to the start of the word + if (stream.start < stream.pos) + stream.backUp(stream.pos - stream.start); + //advance the length of the word and return + for (var i = 0; i < word.length; ++i) stream.next(); + return words[word].style; + } + } + // Are we in an Proc statement? + if (state.inProc) { + if (word === 'run;' || word === 'quit;') { + state.inProc = false; + return 'builtin'; + } + // do we have a proc keyword + if (word && words.hasOwnProperty(word) && + (words[word].state.indexOf("inProc") !== -1 || + words[word].state.indexOf("ALL") !== -1)) { + stream.match(/[\w]+/); + return words[word].style; + } + } + // Are we in a Macro statement? + if (state.inMacro) { + if (word === '%mend') { + if (stream.peek() === ';') stream.next(); + state.inMacro = false; + return 'builtin'; + } + if (word && words.hasOwnProperty(word) && + (words[word].state.indexOf("inMacro") !== -1 || + words[word].state.indexOf("ALL") !== -1)) { + stream.match(/[\w]+/); + return words[word].style; + } + + return 'atom'; + } + // Do we have Keywords specific words? + if (word && words.hasOwnProperty(word)) { + // Negates the initial next() + stream.backUp(1); + // Actually move the stream + stream.match(/[\w]+/); + if (word === 'data' && /=/.test(stream.peek()) === false) { + state.inDataStep = true; + state.nextword = true; + return 'builtin'; + } + if (word === 'proc') { + state.inProc = true; + state.nextword = true; + return 'builtin'; + } + if (word === '%macro') { + state.inMacro = true; + state.nextword = true; + return 'builtin'; + } + if (/title[1-9]/.test(word)) return 'def'; + + if (word === 'footnote') { + stream.eat(/[1-9]/); + return 'def'; + } + + // Returns their value as state in the prior define methods + if (state.inDataStep === true && words[word].state.indexOf("inDataStep") !== -1) + return words[word].style; + if (state.inProc === true && words[word].state.indexOf("inProc") !== -1) + return words[word].style; + if (state.inMacro === true && words[word].state.indexOf("inMacro") !== -1) + return words[word].style; + if (words[word].state.indexOf("ALL") !== -1) + return words[word].style; + return null; + } + // Unrecognized syntax + return null; + } + + return { + startState: function () { + return { + inDataStep: false, + inProc: false, + inMacro: false, + nextword: false, + continueString: null, + continueComment: false + }; + }, + token: function (stream, state) { + // Strip the spaces, but regex will account for them either way + if (stream.eatSpace()) return null; + // Go through the main process + return tokenize(stream, state); + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/" + }; + + }); + + CodeMirror.defineMIME("text/x-sas", "sas"); +}); diff --git a/backend/webif/static/codemirror/mode/sass/index.html b/backend/webif/static/codemirror/mode/sass/index.html new file mode 100755 index 000000000..6305649e5 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sass/index.html @@ -0,0 +1,68 @@ + + +CodeMirror: Sass mode + + + + + + + + + + + +
+

Sass mode

+
+ + +

MIME types defined: text/x-sass.

+
diff --git a/backend/webif/static/codemirror/mode/sass/sass.js b/backend/webif/static/codemirror/mode/sass/sass.js new file mode 100755 index 000000000..7d8135bfe --- /dev/null +++ b/backend/webif/static/codemirror/mode/sass/sass.js @@ -0,0 +1,454 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("sass", function(config) { + var cssMode = CodeMirror.mimeModes["text/css"]; + var propertyKeywords = cssMode.propertyKeywords || {}, + colorKeywords = cssMode.colorKeywords || {}, + valueKeywords = cssMode.valueKeywords || {}, + fontProperties = cssMode.fontProperties || {}; + + function tokenRegexp(words) { + return new RegExp("^" + words.join("|")); + } + + var keywords = ["true", "false", "null", "auto"]; + var keywordsRegexp = new RegExp("^" + keywords.join("|")); + + var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", + "\\!=", "/", "\\*", "%", "and", "or", "not", ";","\\{","\\}",":"]; + var opRegexp = tokenRegexp(operators); + + var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/; + + var word; + + function isEndLine(stream) { + return !stream.peek() || stream.match(/\s+$/, false); + } + + function urlTokens(stream, state) { + var ch = stream.peek(); + + if (ch === ")") { + stream.next(); + state.tokenizer = tokenBase; + return "operator"; + } else if (ch === "(") { + stream.next(); + stream.eatSpace(); + + return "operator"; + } else if (ch === "'" || ch === '"') { + state.tokenizer = buildStringTokenizer(stream.next()); + return "string"; + } else { + state.tokenizer = buildStringTokenizer(")", false); + return "string"; + } + } + function comment(indentation, multiLine) { + return function(stream, state) { + if (stream.sol() && stream.indentation() <= indentation) { + state.tokenizer = tokenBase; + return tokenBase(stream, state); + } + + if (multiLine && stream.skipTo("*/")) { + stream.next(); + stream.next(); + state.tokenizer = tokenBase; + } else { + stream.skipToEnd(); + } + + return "comment"; + }; + } + + function buildStringTokenizer(quote, greedy) { + if (greedy == null) { greedy = true; } + + function stringTokenizer(stream, state) { + var nextChar = stream.next(); + var peekChar = stream.peek(); + var previousChar = stream.string.charAt(stream.pos-2); + + var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\")); + + if (endingString) { + if (nextChar !== quote && greedy) { stream.next(); } + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + state.tokenizer = tokenBase; + return "string"; + } else if (nextChar === "#" && peekChar === "{") { + state.tokenizer = buildInterpolationTokenizer(stringTokenizer); + stream.next(); + return "operator"; + } else { + return "string"; + } + } + + return stringTokenizer; + } + + function buildInterpolationTokenizer(currentTokenizer) { + return function(stream, state) { + if (stream.peek() === "}") { + stream.next(); + state.tokenizer = currentTokenizer; + return "operator"; + } else { + return tokenBase(stream, state); + } + }; + } + + function indent(state) { + if (state.indentCount == 0) { + state.indentCount++; + var lastScopeOffset = state.scopes[0].offset; + var currentOffset = lastScopeOffset + config.indentUnit; + state.scopes.unshift({ offset:currentOffset }); + } + } + + function dedent(state) { + if (state.scopes.length == 1) return; + + state.scopes.shift(); + } + + function tokenBase(stream, state) { + var ch = stream.peek(); + + // Comment + if (stream.match("/*")) { + state.tokenizer = comment(stream.indentation(), true); + return state.tokenizer(stream, state); + } + if (stream.match("//")) { + state.tokenizer = comment(stream.indentation(), false); + return state.tokenizer(stream, state); + } + + // Interpolation + if (stream.match("#{")) { + state.tokenizer = buildInterpolationTokenizer(tokenBase); + return "operator"; + } + + // Strings + if (ch === '"' || ch === "'") { + stream.next(); + state.tokenizer = buildStringTokenizer(ch); + return "string"; + } + + if(!state.cursorHalf){// state.cursorHalf === 0 + // first half i.e. before : for key-value pairs + // including selectors + + if (ch === "-") { + if (stream.match(/^-\w+-/)) { + return "meta"; + } + } + + if (ch === ".") { + stream.next(); + if (stream.match(/^[\w-]+/)) { + indent(state); + return "qualifier"; + } else if (stream.peek() === "#") { + indent(state); + return "tag"; + } + } + + if (ch === "#") { + stream.next(); + // ID selectors + if (stream.match(/^[\w-]+/)) { + indent(state); + return "builtin"; + } + if (stream.peek() === "#") { + indent(state); + return "tag"; + } + } + + // Variables + if (ch === "$") { + stream.next(); + stream.eatWhile(/[\w-]/); + return "variable-2"; + } + + // Numbers + if (stream.match(/^-?[0-9\.]+/)) + return "number"; + + // Units + if (stream.match(/^(px|em|in)\b/)) + return "unit"; + + if (stream.match(keywordsRegexp)) + return "keyword"; + + if (stream.match(/^url/) && stream.peek() === "(") { + state.tokenizer = urlTokens; + return "atom"; + } + + if (ch === "=") { + // Match shortcut mixin definition + if (stream.match(/^=[\w-]+/)) { + indent(state); + return "meta"; + } + } + + if (ch === "+") { + // Match shortcut mixin definition + if (stream.match(/^\+[\w-]+/)){ + return "variable-3"; + } + } + + if(ch === "@"){ + if(stream.match(/@extend/)){ + if(!stream.match(/\s*[\w]/)) + dedent(state); + } + } + + + // Indent Directives + if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) { + indent(state); + return "def"; + } + + // Other Directives + if (ch === "@") { + stream.next(); + stream.eatWhile(/[\w-]/); + return "def"; + } + + if (stream.eatWhile(/[\w-]/)){ + if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){ + word = stream.current().toLowerCase(); + var prop = state.prevProp + "-" + word; + if (propertyKeywords.hasOwnProperty(prop)) { + return "property"; + } else if (propertyKeywords.hasOwnProperty(word)) { + state.prevProp = word; + return "property"; + } else if (fontProperties.hasOwnProperty(word)) { + return "property"; + } + return "tag"; + } + else if(stream.match(/ *:/,false)){ + indent(state); + state.cursorHalf = 1; + state.prevProp = stream.current().toLowerCase(); + return "property"; + } + else if(stream.match(/ *,/,false)){ + return "tag"; + } + else{ + indent(state); + return "tag"; + } + } + + if(ch === ":"){ + if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element + return "variable-3"; + } + stream.next(); + state.cursorHalf=1; + return "operator"; + } + + } // cursorHalf===0 ends here + else{ + + if (ch === "#") { + stream.next(); + // Hex numbers + if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){ + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "number"; + } + } + + // Numbers + if (stream.match(/^-?[0-9\.]+/)){ + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "number"; + } + + // Units + if (stream.match(/^(px|em|in)\b/)){ + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "unit"; + } + + if (stream.match(keywordsRegexp)){ + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "keyword"; + } + + if (stream.match(/^url/) && stream.peek() === "(") { + state.tokenizer = urlTokens; + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "atom"; + } + + // Variables + if (ch === "$") { + stream.next(); + stream.eatWhile(/[\w-]/); + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "variable-2"; + } + + // bang character for !important, !default, etc. + if (ch === "!") { + stream.next(); + state.cursorHalf = 0; + return stream.match(/^[\w]+/) ? "keyword": "operator"; + } + + if (stream.match(opRegexp)){ + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + return "operator"; + } + + // attributes + if (stream.eatWhile(/[\w-]/)) { + if (isEndLine(stream)) { + state.cursorHalf = 0; + } + word = stream.current().toLowerCase(); + if (valueKeywords.hasOwnProperty(word)) { + return "atom"; + } else if (colorKeywords.hasOwnProperty(word)) { + return "keyword"; + } else if (propertyKeywords.hasOwnProperty(word)) { + state.prevProp = stream.current().toLowerCase(); + return "property"; + } else { + return "tag"; + } + } + + //stream.eatSpace(); + if (isEndLine(stream)) { + state.cursorHalf = 0; + return null; + } + + } // else ends here + + if (stream.match(opRegexp)) + return "operator"; + + // If we haven't returned by now, we move 1 character + // and return an error + stream.next(); + return null; + } + + function tokenLexer(stream, state) { + if (stream.sol()) state.indentCount = 0; + var style = state.tokenizer(stream, state); + var current = stream.current(); + + if (current === "@return" || current === "}"){ + dedent(state); + } + + if (style !== null) { + var startOfToken = stream.pos - current.length; + + var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount); + + var newScopes = []; + + for (var i = 0; i < state.scopes.length; i++) { + var scope = state.scopes[i]; + + if (scope.offset <= withCurrentIndent) + newScopes.push(scope); + } + + state.scopes = newScopes; + } + + + return style; + } + + return { + startState: function() { + return { + tokenizer: tokenBase, + scopes: [{offset: 0, type: "sass"}], + indentCount: 0, + cursorHalf: 0, // cursor half tells us if cursor lies after (1) + // or before (0) colon (well... more or less) + definedVars: [], + definedMixins: [] + }; + }, + token: function(stream, state) { + var style = tokenLexer(stream, state); + + state.lastToken = { style: style, content: stream.current() }; + + return style; + }, + + indent: function(state) { + return state.scopes[0].offset; + } + }; +}, "css"); + +CodeMirror.defineMIME("text/x-sass", "sass"); + +}); diff --git a/backend/webif/static/codemirror/mode/sass/test.js b/backend/webif/static/codemirror/mode/sass/test.js new file mode 100755 index 000000000..6b2f59321 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sass/test.js @@ -0,0 +1,122 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "sass"); + // Since Sass has an indent-based syntax, is almost impossible to test correctly the indentation in all cases. + // So disable it for tests. + mode.indent = undefined; + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("comment", + "[comment // this is a comment]", + "[comment also this is a comment]") + + MT("comment_multiline", + "[comment /* this is a comment]", + "[comment also this is a comment]") + + MT("variable", + "[variable-2 $page-width][operator :] [number 800][unit px]") + + MT("global_attributes", + "[tag body]", + " [property font][operator :]", + " [property family][operator :] [atom sans-serif]", + " [property size][operator :] [number 30][unit em]", + " [property weight][operator :] [atom bold]") + + MT("scoped_styles", + "[builtin #contents]", + " [property width][operator :] [variable-2 $page-width]", + " [builtin #sidebar]", + " [property float][operator :] [atom right]", + " [property width][operator :] [variable-2 $sidebar-width]", + " [builtin #main]", + " [property width][operator :] [variable-2 $page-width] [operator -] [variable-2 $sidebar-width]", + " [property background][operator :] [variable-2 $primary-color]", + " [tag h2]", + " [property color][operator :] [keyword blue]") + + // Sass allows to write the colon as first char instead of a "separator". + // :color red + // Not supported + // MT("property_syntax", + // "[qualifier .foo]", + // " [operator :][property color] [keyword red]") + + MT("import", + "[def @import] [string \"sass/variables\"]", + // Probably it should parsed as above: as a string even without the " or ' + // "[def @import] [string sass/baz]" + "[def @import] [tag sass][operator /][tag baz]") + + MT("def", + "[def @if] [variable-2 $foo] [def @else]") + + MT("tag_on_more_lines", + "[tag td],", + "[tag th]", + " [property font-family][operator :] [string \"Arial\"], [atom serif]") + + MT("important", + "[qualifier .foo]", + " [property text-decoration][operator :] [atom none] [keyword !important]", + "[tag h1]", + " [property font-size][operator :] [number 2.5][unit em]") + + MT("selector", + // SCSS doesn't highlight the : + // "[tag h1]:[variable-3 before],", + // "[tag h2]:[variable-3 before]", + "[tag h1][variable-3 :before],", + "[tag h2][variable-3 :before]", + " [property content][operator :] [string \"::\"]") + + MT("definition_mixin_equal", + "[variable-2 $defined-bs-type][operator :] [atom border-box] [keyword !default]", + "[meta =bs][operator (][variable-2 $bs-type][operator :] [variable-2 $defined-bs-type][operator )]", + " [meta -webkit-][property box-sizing][operator :] [variable-2 $bs-type]", + " [property box-sizing][operator :] [variable-2 $bs-type]") + + MT("definition_mixin_with_space", + "[variable-2 $defined-bs-type][operator :] [atom border-box] [keyword !default]", + "[def @mixin] [tag bs][operator (][variable-2 $bs-type][operator :] [variable-2 $defined-bs-type][operator )] ", + " [meta -moz-][property box-sizing][operator :] [variable-2 $bs-type]", + " [property box-sizing][operator :] [variable-2 $bs-type]") + + MT("numbers_start_dot_include_plus", + // The % is not highlighted correctly + // "[meta =button-links][operator (][variable-2 $button-base][operator :] [atom darken][operator (][variable-2 $color11], [number 10][unit %][operator )][operator )]", + "[meta =button-links][operator (][variable-2 $button-base][operator :] [atom darken][operator (][variable-2 $color11], [number 10][operator %))]", + " [property padding][operator :] [number .3][unit em] [number .6][unit em]", + " [variable-3 +border-radius][operator (][number 8][unit px][operator )]", + " [property background-color][operator :] [variable-2 $button-base]") + + MT("include", + "[qualifier .bar]", + " [def @include] [tag border-radius][operator (][number 8][unit px][operator )]") + + MT("reference_parent", + "[qualifier .col]", + " [property clear][operator :] [atom both]", + // SCSS doesn't highlight the : + // " &:[variable-3 after]", + " &[variable-3 :after]", + " [property content][operator :] [string '']", + " [property clear][operator :] [atom both]") + + MT("reference_parent_with_spaces", + "[tag section]", + " [property border-left][operator :] [number 20][unit px] [atom transparent] [atom solid] ", + " &[qualifier .section3]", + " [qualifier .title]", + " [property color][operator :] [keyword white] ", + " [qualifier .vermas]", + " [property display][operator :] [atom none]") + + MT("font_face", + "[def @font-face]", + " [property font-family][operator :] [string 'icomoon']", + " [property src][operator :] [atom url][operator (][string fonts/icomoon.ttf][operator )]") +})(); diff --git a/backend/webif/static/codemirror/mode/scheme/index.html b/backend/webif/static/codemirror/mode/scheme/index.html new file mode 100755 index 000000000..04d5c6a2a --- /dev/null +++ b/backend/webif/static/codemirror/mode/scheme/index.html @@ -0,0 +1,77 @@ + + +CodeMirror: Scheme mode + + + + + + + + + +
+

Scheme mode

+
+ + +

MIME types defined: text/x-scheme.

+ +
diff --git a/backend/webif/static/codemirror/mode/scheme/scheme.js b/backend/webif/static/codemirror/mode/scheme/scheme.js new file mode 100755 index 000000000..1d8f7d17f --- /dev/null +++ b/backend/webif/static/codemirror/mode/scheme/scheme.js @@ -0,0 +1,249 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Author: Koh Zi Han, based on implementation by Koh Zi Chun + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("scheme", function () { + var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", + ATOM = "atom", NUMBER = "number", BRACKET = "bracket"; + var INDENT_WORD_SKIP = 2; + + function makeKeywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"); + var indentKeys = makeKeywords("define let letrec let* lambda"); + + function stateStack(indent, type, prev) { // represents a state stack object + this.indent = indent; + this.type = type; + this.prev = prev; + } + + function pushStack(state, indent, type) { + state.indentStack = new stateStack(indent, type, state.indentStack); + } + + function popStack(state) { + state.indentStack = state.indentStack.prev; + } + + var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i); + var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i); + var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i); + var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i); + + function isBinaryNumber (stream) { + return stream.match(binaryMatcher); + } + + function isOctalNumber (stream) { + return stream.match(octalMatcher); + } + + function isDecimalNumber (stream, backup) { + if (backup === true) { + stream.backUp(1); + } + return stream.match(decimalMatcher); + } + + function isHexNumber (stream) { + return stream.match(hexMatcher); + } + + return { + startState: function () { + return { + indentStack: null, + indentation: 0, + mode: false, + sExprComment: false + }; + }, + + token: function (stream, state) { + if (state.indentStack == null && stream.sol()) { + // update indentation, but only if indentStack is empty + state.indentation = stream.indentation(); + } + + // skip spaces + if (stream.eatSpace()) { + return null; + } + var returnType = null; + + switch(state.mode){ + case "string": // multi-line string parsing mode + var next, escaped = false; + while ((next = stream.next()) != null) { + if (next == "\"" && !escaped) { + + state.mode = false; + break; + } + escaped = !escaped && next == "\\"; + } + returnType = STRING; // continue on in scheme-string mode + break; + case "comment": // comment parsing mode + var next, maybeEnd = false; + while ((next = stream.next()) != null) { + if (next == "#" && maybeEnd) { + + state.mode = false; + break; + } + maybeEnd = (next == "|"); + } + returnType = COMMENT; + break; + case "s-expr-comment": // s-expr commenting mode + state.mode = false; + if(stream.peek() == "(" || stream.peek() == "["){ + // actually start scheme s-expr commenting mode + state.sExprComment = 0; + }else{ + // if not we just comment the entire of the next token + stream.eatWhile(/[^/s]/); // eat non spaces + returnType = COMMENT; + break; + } + default: // default parsing mode + var ch = stream.next(); + + if (ch == "\"") { + state.mode = "string"; + returnType = STRING; + + } else if (ch == "'") { + returnType = ATOM; + } else if (ch == '#') { + if (stream.eat("|")) { // Multi-line comment + state.mode = "comment"; // toggle to comment mode + returnType = COMMENT; + } else if (stream.eat(/[tf]/i)) { // #t/#f (atom) + returnType = ATOM; + } else if (stream.eat(';')) { // S-Expr comment + state.mode = "s-expr-comment"; + returnType = COMMENT; + } else { + var numTest = null, hasExactness = false, hasRadix = true; + if (stream.eat(/[ei]/i)) { + hasExactness = true; + } else { + stream.backUp(1); // must be radix specifier + } + if (stream.match(/^#b/i)) { + numTest = isBinaryNumber; + } else if (stream.match(/^#o/i)) { + numTest = isOctalNumber; + } else if (stream.match(/^#x/i)) { + numTest = isHexNumber; + } else if (stream.match(/^#d/i)) { + numTest = isDecimalNumber; + } else if (stream.match(/^[-+0-9.]/, false)) { + hasRadix = false; + numTest = isDecimalNumber; + // re-consume the intial # if all matches failed + } else if (!hasExactness) { + stream.eat('#'); + } + if (numTest != null) { + if (hasRadix && !hasExactness) { + // consume optional exactness after radix + stream.match(/^#[ei]/i); + } + if (numTest(stream)) + returnType = NUMBER; + } + } + } else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal + returnType = NUMBER; + } else if (ch == ";") { // comment + stream.skipToEnd(); // rest of the line is a comment + returnType = COMMENT; + } else if (ch == "(" || ch == "[") { + var keyWord = ''; var indentTemp = stream.column(), letter; + /** + Either + (indent-word .. + (non-indent-word .. + (;something else, bracket, etc. + */ + + while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) { + keyWord += letter; + } + + if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word + + pushStack(state, indentTemp + INDENT_WORD_SKIP, ch); + } else { // non-indent word + // we continue eating the spaces + stream.eatSpace(); + if (stream.eol() || stream.peek() == ";") { + // nothing significant after + // we restart indentation 1 space after + pushStack(state, indentTemp + 1, ch); + } else { + pushStack(state, indentTemp + stream.current().length, ch); // else we match + } + } + stream.backUp(stream.current().length - 1); // undo all the eating + + if(typeof state.sExprComment == "number") state.sExprComment++; + + returnType = BRACKET; + } else if (ch == ")" || ch == "]") { + returnType = BRACKET; + if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) { + popStack(state); + + if(typeof state.sExprComment == "number"){ + if(--state.sExprComment == 0){ + returnType = COMMENT; // final closing bracket + state.sExprComment = false; // turn off s-expr commenting mode + } + } + } + } else { + stream.eatWhile(/[\w_\-!$%&*+\.\/:<=>?@\^~]/); + + if (keywords && keywords.propertyIsEnumerable(stream.current())) { + returnType = BUILTIN; + } else returnType = "variable"; + } + } + return (typeof state.sExprComment == "number") ? COMMENT : returnType; + }, + + indent: function (state) { + if (state.indentStack == null) return state.indentation; + return state.indentStack.indent; + }, + + closeBrackets: {pairs: "()[]{}\"\""}, + lineComment: ";;" + }; +}); + +CodeMirror.defineMIME("text/x-scheme", "scheme"); + +}); diff --git a/backend/webif/static/codemirror/mode/shell/index.html b/backend/webif/static/codemirror/mode/shell/index.html new file mode 100755 index 000000000..e42f4b5f3 --- /dev/null +++ b/backend/webif/static/codemirror/mode/shell/index.html @@ -0,0 +1,66 @@ + + +CodeMirror: Shell mode + + + + + + + + + + +
+

Shell mode

+ + + + + + +

MIME types defined: text/x-sh, application/x-sh.

+
diff --git a/backend/webif/static/codemirror/mode/shell/shell.js b/backend/webif/static/codemirror/mode/shell/shell.js new file mode 100755 index 000000000..9b8b90b30 --- /dev/null +++ b/backend/webif/static/codemirror/mode/shell/shell.js @@ -0,0 +1,142 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('shell', function() { + + var words = {}; + function define(style, string) { + var split = string.split(' '); + for(var i = 0; i < split.length; i++) { + words[split[i]] = style; + } + }; + + // Atoms + define('atom', 'true false'); + + // Keywords + define('keyword', 'if then do else elif while until for in esac fi fin ' + + 'fil done exit set unset export function'); + + // Commands + define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' + + 'curl cut diff echo find gawk gcc get git grep hg kill killall ln ls make ' + + 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' + + 'shopt shred source sort sleep ssh start stop su sudo svn tee telnet top ' + + 'touch vi vim wall wc wget who write yes zsh'); + + function tokenBase(stream, state) { + if (stream.eatSpace()) return null; + + var sol = stream.sol(); + var ch = stream.next(); + + if (ch === '\\') { + stream.next(); + return null; + } + if (ch === '\'' || ch === '"' || ch === '`') { + state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string")); + return tokenize(stream, state); + } + if (ch === '#') { + if (sol && stream.eat('!')) { + stream.skipToEnd(); + return 'meta'; // 'comment'? + } + stream.skipToEnd(); + return 'comment'; + } + if (ch === '$') { + state.tokens.unshift(tokenDollar); + return tokenize(stream, state); + } + if (ch === '+' || ch === '=') { + return 'operator'; + } + if (ch === '-') { + stream.eat('-'); + stream.eatWhile(/\w/); + return 'attribute'; + } + if (/\d/.test(ch)) { + stream.eatWhile(/\d/); + if(stream.eol() || !/\w/.test(stream.peek())) { + return 'number'; + } + } + stream.eatWhile(/[\w-]/); + var cur = stream.current(); + if (stream.peek() === '=' && /\w+/.test(cur)) return 'def'; + return words.hasOwnProperty(cur) ? words[cur] : null; + } + + function tokenString(quote, style) { + var close = quote == "(" ? ")" : quote == "{" ? "}" : quote + return function(stream, state) { + var next, end = false, escaped = false; + while ((next = stream.next()) != null) { + if (next === close && !escaped) { + end = true; + break; + } + if (next === '$' && !escaped && quote !== "'") { + escaped = true; + stream.backUp(1); + state.tokens.unshift(tokenDollar); + break; + } + if (!escaped && next === quote && quote !== close) { + state.tokens.unshift(tokenString(quote, style)) + return tokenize(stream, state) + } + escaped = !escaped && next === '\\'; + } + if (end) state.tokens.shift(); + return style; + }; + }; + + var tokenDollar = function(stream, state) { + if (state.tokens.length > 1) stream.eat('$'); + var ch = stream.next() + if (/['"({]/.test(ch)) { + state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string"); + return tokenize(stream, state); + } + if (!/\d/.test(ch)) stream.eatWhile(/\w/); + state.tokens.shift(); + return 'def'; + }; + + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase) (stream, state); + }; + + return { + startState: function() {return {tokens:[]};}, + token: function(stream, state) { + return tokenize(stream, state); + }, + closeBrackets: "()[]{}''\"\"``", + lineComment: '#', + fold: "brace" + }; +}); + +CodeMirror.defineMIME('text/x-sh', 'shell'); +// Apache uses a slightly different Media Type for Shell scripts +// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types +CodeMirror.defineMIME('application/x-sh', 'shell'); + +}); diff --git a/backend/webif/static/codemirror/mode/shell/test.js b/backend/webif/static/codemirror/mode/shell/test.js new file mode 100755 index 000000000..86e344c57 --- /dev/null +++ b/backend/webif/static/codemirror/mode/shell/test.js @@ -0,0 +1,64 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({}, "shell"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("var", + "text [def $var] text"); + MT("varBraces", + "text[def ${var}]text"); + MT("varVar", + "text [def $a$b] text"); + MT("varBracesVarBraces", + "text[def ${a}${b}]text"); + + MT("singleQuotedVar", + "[string 'text $var text']"); + MT("singleQuotedVarBraces", + "[string 'text ${var} text']"); + + MT("doubleQuotedVar", + '[string "text ][def $var][string text"]'); + MT("doubleQuotedVarBraces", + '[string "text][def ${var}][string text"]'); + MT("doubleQuotedVarPunct", + '[string "text ][def $@][string text"]'); + MT("doubleQuotedVarVar", + '[string "][def $a$b][string "]'); + MT("doubleQuotedVarBracesVarBraces", + '[string "][def ${a}${b}][string "]'); + + MT("notAString", + "text\\'text"); + MT("escapes", + "outside\\'\\\"\\`\\\\[string \"inside\\`\\'\\\"\\\\`\\$notAVar\"]outside\\$\\(notASubShell\\)"); + + MT("subshell", + "[builtin echo] [quote $(whoami)] s log, stardate [quote `date`]."); + MT("doubleQuotedSubshell", + "[builtin echo] [string \"][quote $(whoami)][string 's log, stardate `date`.\"]"); + + MT("hashbang", + "[meta #!/bin/bash]"); + MT("comment", + "text [comment # Blurb]"); + + MT("numbers", + "[number 0] [number 1] [number 2]"); + MT("keywords", + "[keyword while] [atom true]; [keyword do]", + " [builtin sleep] [number 3]", + "[keyword done]"); + MT("options", + "[builtin ls] [attribute -l] [attribute --human-readable]"); + MT("operator", + "[def var][operator =]value"); + + MT("doubleParens", + "foo [quote $((bar))]") + + MT("nested braces", + "[builtin echo] [def ${A[${B}]]}]") +})(); diff --git a/backend/webif/static/codemirror/mode/sieve/index.html b/backend/webif/static/codemirror/mode/sieve/index.html new file mode 100755 index 000000000..6f029b623 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sieve/index.html @@ -0,0 +1,93 @@ + + +CodeMirror: Sieve (RFC5228) mode + + + + + + + + + +
+

Sieve (RFC5228) mode

+
+ + +

MIME types defined: application/sieve.

+ +
diff --git a/backend/webif/static/codemirror/mode/sieve/sieve.js b/backend/webif/static/codemirror/mode/sieve/sieve.js new file mode 100755 index 000000000..0920d0bab --- /dev/null +++ b/backend/webif/static/codemirror/mode/sieve/sieve.js @@ -0,0 +1,193 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("sieve", function(config) { + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var keywords = words("if elsif else stop require"); + var atoms = words("true false not"); + var indentUnit = config.indentUnit; + + function tokenBase(stream, state) { + + var ch = stream.next(); + if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + + if (ch === '#') { + stream.skipToEnd(); + return "comment"; + } + + if (ch == "\"") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + + if (ch == "(") { + state._indent.push("("); + // add virtual angel wings so that editor behaves... + // ...more sane incase of broken brackets + state._indent.push("{"); + return null; + } + + if (ch === "{") { + state._indent.push("{"); + return null; + } + + if (ch == ")") { + state._indent.pop(); + state._indent.pop(); + } + + if (ch === "}") { + state._indent.pop(); + return null; + } + + if (ch == ",") + return null; + + if (ch == ";") + return null; + + + if (/[{}\(\),;]/.test(ch)) + return null; + + // 1*DIGIT "K" / "M" / "G" + if (/\d/.test(ch)) { + stream.eatWhile(/[\d]/); + stream.eat(/[KkMmGg]/); + return "number"; + } + + // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_") + if (ch == ":") { + stream.eatWhile(/[a-zA-Z_]/); + stream.eatWhile(/[a-zA-Z0-9_]/); + + return "operator"; + } + + stream.eatWhile(/\w/); + var cur = stream.current(); + + // "text:" *(SP / HTAB) (hash-comment / CRLF) + // *(multiline-literal / multiline-dotstart) + // "." CRLF + if ((cur == "text") && stream.eat(":")) + { + state.tokenize = tokenMultiLineString; + return "string"; + } + + if (keywords.propertyIsEnumerable(cur)) + return "keyword"; + + if (atoms.propertyIsEnumerable(cur)) + return "atom"; + + return null; + } + + function tokenMultiLineString(stream, state) + { + state._multiLineString = true; + // the first line is special it may contain a comment + if (!stream.sol()) { + stream.eatSpace(); + + if (stream.peek() == "#") { + stream.skipToEnd(); + return "comment"; + } + + stream.skipToEnd(); + return "string"; + } + + if ((stream.next() == ".") && (stream.eol())) + { + state._multiLineString = false; + state.tokenize = tokenBase; + } + + return "string"; + } + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) + break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return "string"; + }; + } + + return { + startState: function(base) { + return {tokenize: tokenBase, + baseIndent: base || 0, + _indent: []}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) + return null; + + return (state.tokenize || tokenBase)(stream, state); + }, + + indent: function(state, _textAfter) { + var length = state._indent.length; + if (_textAfter && (_textAfter[0] == "}")) + length--; + + if (length <0) + length = 0; + + return length * indentUnit; + }, + + electricChars: "}" + }; +}); + +CodeMirror.defineMIME("application/sieve", "sieve"); + +}); diff --git a/backend/webif/static/codemirror/mode/slim/index.html b/backend/webif/static/codemirror/mode/slim/index.html new file mode 100755 index 000000000..7fa4e50df --- /dev/null +++ b/backend/webif/static/codemirror/mode/slim/index.html @@ -0,0 +1,96 @@ + + +CodeMirror: SLIM mode + + + + + + + + + + + + + + + + + + + + +
+

SLIM mode

+
+ + +

MIME types defined: application/x-slim.

+ +

+ Parsing/Highlighting Tests: + normal, + verbose. +

+
diff --git a/backend/webif/static/codemirror/mode/slim/slim.js b/backend/webif/static/codemirror/mode/slim/slim.js new file mode 100755 index 000000000..991a97efc --- /dev/null +++ b/backend/webif/static/codemirror/mode/slim/slim.js @@ -0,0 +1,575 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Slim Highlighting for CodeMirror copyright (c) HicknHack Software Gmbh + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + + CodeMirror.defineMode("slim", function(config) { + var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"}); + var rubyMode = CodeMirror.getMode(config, "ruby"); + var modes = { html: htmlMode, ruby: rubyMode }; + var embedded = { + ruby: "ruby", + javascript: "javascript", + css: "text/css", + sass: "text/x-sass", + scss: "text/x-scss", + less: "text/x-less", + styl: "text/x-styl", // no highlighting so far + coffee: "coffeescript", + asciidoc: "text/x-asciidoc", + markdown: "text/x-markdown", + textile: "text/x-textile", // no highlighting so far + creole: "text/x-creole", // no highlighting so far + wiki: "text/x-wiki", // no highlighting so far + mediawiki: "text/x-mediawiki", // no highlighting so far + rdoc: "text/x-rdoc", // no highlighting so far + builder: "text/x-builder", // no highlighting so far + nokogiri: "text/x-nokogiri", // no highlighting so far + erb: "application/x-erb" + }; + var embeddedRegexp = function(map){ + var arr = []; + for(var key in map) arr.push(key); + return new RegExp("^("+arr.join('|')+"):"); + }(embedded); + + var styleMap = { + "commentLine": "comment", + "slimSwitch": "operator special", + "slimTag": "tag", + "slimId": "attribute def", + "slimClass": "attribute qualifier", + "slimAttribute": "attribute", + "slimSubmode": "keyword special", + "closeAttributeTag": null, + "slimDoctype": null, + "lineContinuation": null + }; + var closing = { + "{": "}", + "[": "]", + "(": ")" + }; + + var nameStartChar = "_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"; + var nameChar = nameStartChar + "\\-0-9\xB7\u0300-\u036F\u203F-\u2040"; + var nameRegexp = new RegExp("^[:"+nameStartChar+"](?::["+nameChar+"]|["+nameChar+"]*)"); + var attributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*(?=\\s*=)"); + var wrappedAttributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*"); + var classNameRegexp = /^\.-?[_a-zA-Z]+[\w\-]*/; + var classIdRegexp = /^#[_a-zA-Z]+[\w\-]*/; + + function backup(pos, tokenize, style) { + var restore = function(stream, state) { + state.tokenize = tokenize; + if (stream.pos < pos) { + stream.pos = pos; + return style; + } + return state.tokenize(stream, state); + }; + return function(stream, state) { + state.tokenize = restore; + return tokenize(stream, state); + }; + } + + function maybeBackup(stream, state, pat, offset, style) { + var cur = stream.current(); + var idx = cur.search(pat); + if (idx > -1) { + state.tokenize = backup(stream.pos, state.tokenize, style); + stream.backUp(cur.length - idx - offset); + } + return style; + } + + function continueLine(state, column) { + state.stack = { + parent: state.stack, + style: "continuation", + indented: column, + tokenize: state.line + }; + state.line = state.tokenize; + } + function finishContinue(state) { + if (state.line == state.tokenize) { + state.line = state.stack.tokenize; + state.stack = state.stack.parent; + } + } + + function lineContinuable(column, tokenize) { + return function(stream, state) { + finishContinue(state); + if (stream.match(/^\\$/)) { + continueLine(state, column); + return "lineContinuation"; + } + var style = tokenize(stream, state); + if (stream.eol() && stream.current().match(/(?:^|[^\\])(?:\\\\)*\\$/)) { + stream.backUp(1); + } + return style; + }; + } + function commaContinuable(column, tokenize) { + return function(stream, state) { + finishContinue(state); + var style = tokenize(stream, state); + if (stream.eol() && stream.current().match(/,$/)) { + continueLine(state, column); + } + return style; + }; + } + + function rubyInQuote(endQuote, tokenize) { + // TODO: add multi line support + return function(stream, state) { + var ch = stream.peek(); + if (ch == endQuote && state.rubyState.tokenize.length == 1) { + // step out of ruby context as it seems to complete processing all the braces + stream.next(); + state.tokenize = tokenize; + return "closeAttributeTag"; + } else { + return ruby(stream, state); + } + }; + } + function startRubySplat(tokenize) { + var rubyState; + var runSplat = function(stream, state) { + if (state.rubyState.tokenize.length == 1 && !state.rubyState.context.prev) { + stream.backUp(1); + if (stream.eatSpace()) { + state.rubyState = rubyState; + state.tokenize = tokenize; + return tokenize(stream, state); + } + stream.next(); + } + return ruby(stream, state); + }; + return function(stream, state) { + rubyState = state.rubyState; + state.rubyState = CodeMirror.startState(rubyMode); + state.tokenize = runSplat; + return ruby(stream, state); + }; + } + + function ruby(stream, state) { + return rubyMode.token(stream, state.rubyState); + } + + function htmlLine(stream, state) { + if (stream.match(/^\\$/)) { + return "lineContinuation"; + } + return html(stream, state); + } + function html(stream, state) { + if (stream.match(/^#\{/)) { + state.tokenize = rubyInQuote("}", state.tokenize); + return null; + } + return maybeBackup(stream, state, /[^\\]#\{/, 1, htmlMode.token(stream, state.htmlState)); + } + + function startHtmlLine(lastTokenize) { + return function(stream, state) { + var style = htmlLine(stream, state); + if (stream.eol()) state.tokenize = lastTokenize; + return style; + }; + } + + function startHtmlMode(stream, state, offset) { + state.stack = { + parent: state.stack, + style: "html", + indented: stream.column() + offset, // pipe + space + tokenize: state.line + }; + state.line = state.tokenize = html; + return null; + } + + function comment(stream, state) { + stream.skipToEnd(); + return state.stack.style; + } + + function commentMode(stream, state) { + state.stack = { + parent: state.stack, + style: "comment", + indented: state.indented + 1, + tokenize: state.line + }; + state.line = comment; + return comment(stream, state); + } + + function attributeWrapper(stream, state) { + if (stream.eat(state.stack.endQuote)) { + state.line = state.stack.line; + state.tokenize = state.stack.tokenize; + state.stack = state.stack.parent; + return null; + } + if (stream.match(wrappedAttributeNameRegexp)) { + state.tokenize = attributeWrapperAssign; + return "slimAttribute"; + } + stream.next(); + return null; + } + function attributeWrapperAssign(stream, state) { + if (stream.match(/^==?/)) { + state.tokenize = attributeWrapperValue; + return null; + } + return attributeWrapper(stream, state); + } + function attributeWrapperValue(stream, state) { + var ch = stream.peek(); + if (ch == '"' || ch == "\'") { + state.tokenize = readQuoted(ch, "string", true, false, attributeWrapper); + stream.next(); + return state.tokenize(stream, state); + } + if (ch == '[') { + return startRubySplat(attributeWrapper)(stream, state); + } + if (stream.match(/^(true|false|nil)\b/)) { + state.tokenize = attributeWrapper; + return "keyword"; + } + return startRubySplat(attributeWrapper)(stream, state); + } + + function startAttributeWrapperMode(state, endQuote, tokenize) { + state.stack = { + parent: state.stack, + style: "wrapper", + indented: state.indented + 1, + tokenize: tokenize, + line: state.line, + endQuote: endQuote + }; + state.line = state.tokenize = attributeWrapper; + return null; + } + + function sub(stream, state) { + if (stream.match(/^#\{/)) { + state.tokenize = rubyInQuote("}", state.tokenize); + return null; + } + var subStream = new CodeMirror.StringStream(stream.string.slice(state.stack.indented), stream.tabSize); + subStream.pos = stream.pos - state.stack.indented; + subStream.start = stream.start - state.stack.indented; + subStream.lastColumnPos = stream.lastColumnPos - state.stack.indented; + subStream.lastColumnValue = stream.lastColumnValue - state.stack.indented; + var style = state.subMode.token(subStream, state.subState); + stream.pos = subStream.pos + state.stack.indented; + return style; + } + function firstSub(stream, state) { + state.stack.indented = stream.column(); + state.line = state.tokenize = sub; + return state.tokenize(stream, state); + } + + function createMode(mode) { + var query = embedded[mode]; + var spec = CodeMirror.mimeModes[query]; + if (spec) { + return CodeMirror.getMode(config, spec); + } + var factory = CodeMirror.modes[query]; + if (factory) { + return factory(config, {name: query}); + } + return CodeMirror.getMode(config, "null"); + } + + function getMode(mode) { + if (!modes.hasOwnProperty(mode)) { + return modes[mode] = createMode(mode); + } + return modes[mode]; + } + + function startSubMode(mode, state) { + var subMode = getMode(mode); + var subState = CodeMirror.startState(subMode); + + state.subMode = subMode; + state.subState = subState; + + state.stack = { + parent: state.stack, + style: "sub", + indented: state.indented + 1, + tokenize: state.line + }; + state.line = state.tokenize = firstSub; + return "slimSubmode"; + } + + function doctypeLine(stream, _state) { + stream.skipToEnd(); + return "slimDoctype"; + } + + function startLine(stream, state) { + var ch = stream.peek(); + if (ch == '<') { + return (state.tokenize = startHtmlLine(state.tokenize))(stream, state); + } + if (stream.match(/^[|']/)) { + return startHtmlMode(stream, state, 1); + } + if (stream.match(/^\/(!|\[\w+])?/)) { + return commentMode(stream, state); + } + if (stream.match(/^(-|==?[<>]?)/)) { + state.tokenize = lineContinuable(stream.column(), commaContinuable(stream.column(), ruby)); + return "slimSwitch"; + } + if (stream.match(/^doctype\b/)) { + state.tokenize = doctypeLine; + return "keyword"; + } + + var m = stream.match(embeddedRegexp); + if (m) { + return startSubMode(m[1], state); + } + + return slimTag(stream, state); + } + + function slim(stream, state) { + if (state.startOfLine) { + return startLine(stream, state); + } + return slimTag(stream, state); + } + + function slimTag(stream, state) { + if (stream.eat('*')) { + state.tokenize = startRubySplat(slimTagExtras); + return null; + } + if (stream.match(nameRegexp)) { + state.tokenize = slimTagExtras; + return "slimTag"; + } + return slimClass(stream, state); + } + function slimTagExtras(stream, state) { + if (stream.match(/^(<>?|> state.indented && state.last != "slimSubmode") { + state.line = state.tokenize = state.stack.tokenize; + state.stack = state.stack.parent; + state.subMode = null; + state.subState = null; + } + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + state.startOfLine = false; + if (style) state.last = style; + return styleMap.hasOwnProperty(style) ? styleMap[style] : style; + }, + + blankLine: function(state) { + if (state.subMode && state.subMode.blankLine) { + return state.subMode.blankLine(state.subState); + } + }, + + innerMode: function(state) { + if (state.subMode) return {state: state.subState, mode: state.subMode}; + return {state: state, mode: mode}; + } + + //indent: function(state) { + // return state.indented; + //} + }; + return mode; + }, "htmlmixed", "ruby"); + + CodeMirror.defineMIME("text/x-slim", "slim"); + CodeMirror.defineMIME("application/x-slim", "slim"); +}); diff --git a/backend/webif/static/codemirror/mode/slim/test.js b/backend/webif/static/codemirror/mode/slim/test.js new file mode 100755 index 000000000..be4ddacb6 --- /dev/null +++ b/backend/webif/static/codemirror/mode/slim/test.js @@ -0,0 +1,96 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Slim Highlighting for CodeMirror copyright (c) HicknHack Software Gmbh + +(function() { + var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "slim"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Requires at least one media query + MT("elementName", + "[tag h1] Hey There"); + + MT("oneElementPerLine", + "[tag h1] Hey There .h2"); + + MT("idShortcut", + "[attribute&def #test] Hey There"); + + MT("tagWithIdShortcuts", + "[tag h1][attribute&def #test] Hey There"); + + MT("classShortcut", + "[attribute&qualifier .hello] Hey There"); + + MT("tagWithIdAndClassShortcuts", + "[tag h1][attribute&def #test][attribute&qualifier .hello] Hey There"); + + MT("docType", + "[keyword doctype] xml"); + + MT("comment", + "[comment / Hello WORLD]"); + + MT("notComment", + "[tag h1] This is not a / comment "); + + MT("attributes", + "[tag a]([attribute title]=[string \"test\"]) [attribute href]=[string \"link\"]}"); + + MT("multiLineAttributes", + "[tag a]([attribute title]=[string \"test\"]", + " ) [attribute href]=[string \"link\"]}"); + + MT("htmlCode", + "[tag&bracket <][tag h1][tag&bracket >]Title[tag&bracket ]"); + + MT("rubyBlock", + "[operator&special =][variable-2 @item]"); + + MT("selectorRubyBlock", + "[tag a][attribute&qualifier .test][operator&special =] [variable-2 @item]"); + + MT("nestedRubyBlock", + "[tag a]", + " [operator&special =][variable puts] [string \"test\"]"); + + MT("multilinePlaintext", + "[tag p]", + " | Hello,", + " World"); + + MT("multilineRuby", + "[tag p]", + " [comment /# this is a comment]", + " [comment and this is a comment too]", + " | Date/Time", + " [operator&special -] [variable now] [operator =] [tag DateTime][operator .][property now]", + " [tag strong][operator&special =] [variable now]", + " [operator&special -] [keyword if] [variable now] [operator >] [tag DateTime][operator .][property parse]([string \"December 31, 2006\"])", + " [operator&special =][string \"Happy\"]", + " [operator&special =][string \"Belated\"]", + " [operator&special =][string \"Birthday\"]"); + + MT("multilineComment", + "[comment /]", + " [comment Multiline]", + " [comment Comment]"); + + MT("hamlAfterRubyTag", + "[attribute&qualifier .block]", + " [tag strong][operator&special =] [variable now]", + " [attribute&qualifier .test]", + " [operator&special =][variable now]", + " [attribute&qualifier .right]"); + + MT("stretchedRuby", + "[operator&special =] [variable puts] [string \"Hello\"],", + " [string \"World\"]"); + + MT("interpolationInHashAttribute", + "[tag div]{[attribute id] = [string \"]#{[variable test]}[string _]#{[variable ting]}[string \"]} test"); + + MT("interpolationInHTMLAttribute", + "[tag div]([attribute title]=[string \"]#{[variable test]}[string _]#{[variable ting]()}[string \"]) Test"); +})(); diff --git a/backend/webif/static/codemirror/mode/smalltalk/index.html b/backend/webif/static/codemirror/mode/smalltalk/index.html new file mode 100755 index 000000000..2155ebc2a --- /dev/null +++ b/backend/webif/static/codemirror/mode/smalltalk/index.html @@ -0,0 +1,68 @@ + + +CodeMirror: Smalltalk mode + + + + + + + + + + +
+

Smalltalk mode

+
+ + + +

Simple Smalltalk mode.

+ +

MIME types defined: text/x-stsrc.

+
diff --git a/backend/webif/static/codemirror/mode/smalltalk/smalltalk.js b/backend/webif/static/codemirror/mode/smalltalk/smalltalk.js new file mode 100755 index 000000000..bb510ba2e --- /dev/null +++ b/backend/webif/static/codemirror/mode/smalltalk/smalltalk.js @@ -0,0 +1,168 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('smalltalk', function(config) { + + var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/; + var keywords = /true|false|nil|self|super|thisContext/; + + var Context = function(tokenizer, parent) { + this.next = tokenizer; + this.parent = parent; + }; + + var Token = function(name, context, eos) { + this.name = name; + this.context = context; + this.eos = eos; + }; + + var State = function() { + this.context = new Context(next, null); + this.expectVariable = true; + this.indentation = 0; + this.userIndentationDelta = 0; + }; + + State.prototype.userIndent = function(indentation) { + this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; + }; + + var next = function(stream, context, state) { + var token = new Token(null, context, false); + var aChar = stream.next(); + + if (aChar === '"') { + token = nextComment(stream, new Context(nextComment, context)); + + } else if (aChar === '\'') { + token = nextString(stream, new Context(nextString, context)); + + } else if (aChar === '#') { + if (stream.peek() === '\'') { + stream.next(); + token = nextSymbol(stream, new Context(nextSymbol, context)); + } else { + if (stream.eatWhile(/[^\s.{}\[\]()]/)) + token.name = 'string-2'; + else + token.name = 'meta'; + } + + } else if (aChar === '$') { + if (stream.next() === '<') { + stream.eatWhile(/[^\s>]/); + stream.next(); + } + token.name = 'string-2'; + + } else if (aChar === '|' && state.expectVariable) { + token.context = new Context(nextTemporaries, context); + + } else if (/[\[\]{}()]/.test(aChar)) { + token.name = 'bracket'; + token.eos = /[\[{(]/.test(aChar); + + if (aChar === '[') { + state.indentation++; + } else if (aChar === ']') { + state.indentation = Math.max(0, state.indentation - 1); + } + + } else if (specialChars.test(aChar)) { + stream.eatWhile(specialChars); + token.name = 'operator'; + token.eos = aChar !== ';'; // ; cascaded message expression + + } else if (/\d/.test(aChar)) { + stream.eatWhile(/[\w\d]/); + token.name = 'number'; + + } else if (/[\w_]/.test(aChar)) { + stream.eatWhile(/[\w\d_]/); + token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; + + } else { + token.eos = state.expectVariable; + } + + return token; + }; + + var nextComment = function(stream, context) { + stream.eatWhile(/[^"]/); + return new Token('comment', stream.eat('"') ? context.parent : context, true); + }; + + var nextString = function(stream, context) { + stream.eatWhile(/[^']/); + return new Token('string', stream.eat('\'') ? context.parent : context, false); + }; + + var nextSymbol = function(stream, context) { + stream.eatWhile(/[^']/); + return new Token('string-2', stream.eat('\'') ? context.parent : context, false); + }; + + var nextTemporaries = function(stream, context) { + var token = new Token(null, context, false); + var aChar = stream.next(); + + if (aChar === '|') { + token.context = context.parent; + token.eos = true; + + } else { + stream.eatWhile(/[^|]/); + token.name = 'variable'; + } + + return token; + }; + + return { + startState: function() { + return new State; + }, + + token: function(stream, state) { + state.userIndent(stream.indentation()); + + if (stream.eatSpace()) { + return null; + } + + var token = state.context.next(stream, state.context, state); + state.context = token.context; + state.expectVariable = token.eos; + + return token.name; + }, + + blankLine: function(state) { + state.userIndent(0); + }, + + indent: function(state, textAfter) { + var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; + return (state.indentation + i) * config.indentUnit; + }, + + electricChars: ']' + }; + +}); + +CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); + +}); diff --git a/backend/webif/static/codemirror/mode/smarty/index.html b/backend/webif/static/codemirror/mode/smarty/index.html new file mode 100755 index 000000000..b19c8f09b --- /dev/null +++ b/backend/webif/static/codemirror/mode/smarty/index.html @@ -0,0 +1,138 @@ + + +CodeMirror: Smarty mode + + + + + + + + + + +
+

Smarty mode

+
+ +

Mode for Smarty version 2 or 3, which allows for custom delimiter tags.

+ +

Several configuration parameters are supported:

+ +
    +
  • leftDelimiter and rightDelimiter, + which should be strings that determine where the Smarty syntax + starts and ends.
  • +
  • version, which should be 2 or 3.
  • +
  • baseMode, which can be a mode spec + like "text/html" to set a different background mode.
  • +
+ +

MIME types defined: text/x-smarty

+ +

Smarty 2, custom delimiters

+ +
+ +

Smarty 3

+ + + + + +
diff --git a/backend/webif/static/codemirror/mode/smarty/smarty.js b/backend/webif/static/codemirror/mode/smarty/smarty.js new file mode 100755 index 000000000..6e0fbed42 --- /dev/null +++ b/backend/webif/static/codemirror/mode/smarty/smarty.js @@ -0,0 +1,225 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Smarty 2 and 3 mode. + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("smarty", function(config, parserConf) { + var rightDelimiter = parserConf.rightDelimiter || "}"; + var leftDelimiter = parserConf.leftDelimiter || "{"; + var version = parserConf.version || 2; + var baseMode = CodeMirror.getMode(config, parserConf.baseMode || "null"); + + var keyFunctions = ["debug", "extends", "function", "include", "literal"]; + var regs = { + operatorChars: /[+\-*&%=<>!?]/, + validIdentifier: /[a-zA-Z0-9_]/, + stringChar: /['"]/ + }; + + var last; + function cont(style, lastType) { + last = lastType; + return style; + } + + function chain(stream, state, parser) { + state.tokenize = parser; + return parser(stream, state); + } + + // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode + function doesNotCount(stream, pos) { + if (pos == null) pos = stream.pos; + return version === 3 && leftDelimiter == "{" && + (pos == stream.string.length || /\s/.test(stream.string.charAt(pos))); + } + + function tokenTop(stream, state) { + var string = stream.string; + for (var scan = stream.pos;;) { + var nextMatch = string.indexOf(leftDelimiter, scan); + scan = nextMatch + leftDelimiter.length; + if (nextMatch == -1 || !doesNotCount(stream, nextMatch + leftDelimiter.length)) break; + } + if (nextMatch == stream.pos) { + stream.match(leftDelimiter); + if (stream.eat("*")) { + return chain(stream, state, tokenBlock("comment", "*" + rightDelimiter)); + } else { + state.depth++; + state.tokenize = tokenSmarty; + last = "startTag"; + return "tag"; + } + } + + if (nextMatch > -1) stream.string = string.slice(0, nextMatch); + var token = baseMode.token(stream, state.base); + if (nextMatch > -1) stream.string = string; + return token; + } + + // parsing Smarty content + function tokenSmarty(stream, state) { + if (stream.match(rightDelimiter, true)) { + if (version === 3) { + state.depth--; + if (state.depth <= 0) { + state.tokenize = tokenTop; + } + } else { + state.tokenize = tokenTop; + } + return cont("tag", null); + } + + if (stream.match(leftDelimiter, true)) { + state.depth++; + return cont("tag", "startTag"); + } + + var ch = stream.next(); + if (ch == "$") { + stream.eatWhile(regs.validIdentifier); + return cont("variable-2", "variable"); + } else if (ch == "|") { + return cont("operator", "pipe"); + } else if (ch == ".") { + return cont("operator", "property"); + } else if (regs.stringChar.test(ch)) { + state.tokenize = tokenAttribute(ch); + return cont("string", "string"); + } else if (regs.operatorChars.test(ch)) { + stream.eatWhile(regs.operatorChars); + return cont("operator", "operator"); + } else if (ch == "[" || ch == "]") { + return cont("bracket", "bracket"); + } else if (ch == "(" || ch == ")") { + return cont("bracket", "operator"); + } else if (/\d/.test(ch)) { + stream.eatWhile(/\d/); + return cont("number", "number"); + } else { + + if (state.last == "variable") { + if (ch == "@") { + stream.eatWhile(regs.validIdentifier); + return cont("property", "property"); + } else if (ch == "|") { + stream.eatWhile(regs.validIdentifier); + return cont("qualifier", "modifier"); + } + } else if (state.last == "pipe") { + stream.eatWhile(regs.validIdentifier); + return cont("qualifier", "modifier"); + } else if (state.last == "whitespace") { + stream.eatWhile(regs.validIdentifier); + return cont("attribute", "modifier"); + } if (state.last == "property") { + stream.eatWhile(regs.validIdentifier); + return cont("property", null); + } else if (/\s/.test(ch)) { + last = "whitespace"; + return null; + } + + var str = ""; + if (ch != "/") { + str += ch; + } + var c = null; + while (c = stream.eat(regs.validIdentifier)) { + str += c; + } + for (var i=0, j=keyFunctions.length; i + +CodeMirror: Solr mode + + + + + + + + + +
+

Solr mode

+ +
+ +
+ + + +

MIME types defined: text/x-solr.

+
diff --git a/backend/webif/static/codemirror/mode/solr/solr.js b/backend/webif/static/codemirror/mode/solr/solr.js new file mode 100755 index 000000000..dc8b82501 --- /dev/null +++ b/backend/webif/static/codemirror/mode/solr/solr.js @@ -0,0 +1,104 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("solr", function() { + "use strict"; + + var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\"\\]/; + var isOperatorChar = /[\|\!\+\-\*\?\~\^\&]/; + var isOperatorString = /^(OR|AND|NOT|TO)$/i; + + function isNumber(word) { + return parseFloat(word).toString() === word; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) break; + escaped = !escaped && next == "\\"; + } + + if (!escaped) state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenOperator(operator) { + return function(stream, state) { + var style = "operator"; + if (operator == "+") + style += " positive"; + else if (operator == "-") + style += " negative"; + else if (operator == "|") + stream.eat(/\|/); + else if (operator == "&") + stream.eat(/\&/); + else if (operator == "^") + style += " boost"; + + state.tokenize = tokenBase; + return style; + }; + } + + function tokenWord(ch) { + return function(stream, state) { + var word = ch; + while ((ch = stream.peek()) && ch.match(isStringChar) != null) { + word += stream.next(); + } + + state.tokenize = tokenBase; + if (isOperatorString.test(word)) + return "operator"; + else if (isNumber(word)) + return "number"; + else if (stream.peek() == ":") + return "field"; + else + return "string"; + }; + } + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"') + state.tokenize = tokenString(ch); + else if (isOperatorChar.test(ch)) + state.tokenize = tokenOperator(ch); + else if (isStringChar.test(ch)) + state.tokenize = tokenWord(ch); + + return (state.tokenize != tokenBase) ? state.tokenize(stream, state) : null; + } + + return { + startState: function() { + return { + tokenize: tokenBase + }; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + } + }; +}); + +CodeMirror.defineMIME("text/x-solr", "solr"); + +}); diff --git a/backend/webif/static/codemirror/mode/soy/index.html b/backend/webif/static/codemirror/mode/soy/index.html new file mode 100755 index 000000000..f0216f097 --- /dev/null +++ b/backend/webif/static/codemirror/mode/soy/index.html @@ -0,0 +1,68 @@ + + +CodeMirror: Soy (Closure Template) mode + + + + + + + + + + + + + + +
+

Soy (Closure Template) mode

+
+ + + +

A mode for Closure Templates (Soy).

+

MIME type defined: text/x-soy.

+
diff --git a/backend/webif/static/codemirror/mode/soy/soy.js b/backend/webif/static/codemirror/mode/soy/soy.js new file mode 100755 index 000000000..98f308658 --- /dev/null +++ b/backend/webif/static/codemirror/mode/soy/soy.js @@ -0,0 +1,354 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var indentingTags = ["template", "literal", "msg", "fallbackmsg", "let", "if", "elseif", + "else", "switch", "case", "default", "foreach", "ifempty", "for", + "call", "param", "deltemplate", "delcall", "log"]; + + CodeMirror.defineMode("soy", function(config) { + var textMode = CodeMirror.getMode(config, "text/plain"); + var modes = { + html: CodeMirror.getMode(config, {name: "text/html", multilineTagIndentFactor: 2, multilineTagIndentPastTag: false}), + attributes: textMode, + text: textMode, + uri: textMode, + css: CodeMirror.getMode(config, "text/css"), + js: CodeMirror.getMode(config, {name: "text/javascript", statementIndent: 2 * config.indentUnit}) + }; + + function last(array) { + return array[array.length - 1]; + } + + function tokenUntil(stream, state, untilRegExp) { + if (stream.sol()) { + for (var indent = 0; indent < state.indent; indent++) { + if (!stream.eat(/\s/)) break; + } + if (indent) return null; + } + var oldString = stream.string; + var match = untilRegExp.exec(oldString.substr(stream.pos)); + if (match) { + // We don't use backUp because it backs up just the position, not the state. + // This uses an undocumented API. + stream.string = oldString.substr(0, stream.pos + match.index); + } + var result = stream.hideFirstChars(state.indent, function() { + var localState = last(state.localStates); + return localState.mode.token(stream, localState.state); + }); + stream.string = oldString; + return result; + } + + function contains(list, element) { + while (list) { + if (list.element === element) return true; + list = list.next; + } + return false; + } + + function prepend(list, element) { + return { + element: element, + next: list + }; + } + + // Reference a variable `name` in `list`. + // Let `loose` be truthy to ignore missing identifiers. + function ref(list, name, loose) { + return contains(list, name) ? "variable-2" : (loose ? "variable" : "variable-2 error"); + } + + function popscope(state) { + if (state.scopes) { + state.variables = state.scopes.element; + state.scopes = state.scopes.next; + } + } + + return { + startState: function() { + return { + kind: [], + kindTag: [], + soyState: [], + templates: null, + variables: prepend(null, 'ij'), + scopes: null, + indent: 0, + quoteKind: null, + localStates: [{ + mode: modes.html, + state: CodeMirror.startState(modes.html) + }] + }; + }, + + copyState: function(state) { + return { + tag: state.tag, // Last seen Soy tag. + kind: state.kind.concat([]), // Values of kind="" attributes. + kindTag: state.kindTag.concat([]), // Opened tags with kind="" attributes. + soyState: state.soyState.concat([]), + templates: state.templates, + variables: state.variables, + scopes: state.scopes, + indent: state.indent, // Indentation of the following line. + quoteKind: state.quoteKind, + localStates: state.localStates.map(function(localState) { + return { + mode: localState.mode, + state: CodeMirror.copyState(localState.mode, localState.state) + }; + }) + }; + }, + + token: function(stream, state) { + var match; + + switch (last(state.soyState)) { + case "comment": + if (stream.match(/^.*?\*\//)) { + state.soyState.pop(); + } else { + stream.skipToEnd(); + } + if (!state.scopes) { + var paramRe = /@param\??\s+(\S+)/g; + var current = stream.current(); + for (var match; (match = paramRe.exec(current)); ) { + state.variables = prepend(state.variables, match[1]); + } + } + return "comment"; + + case "string": + var match = stream.match(/^.*?(["']|\\[\s\S])/); + if (!match) { + stream.skipToEnd(); + } else if (match[1] == state.quoteKind) { + state.quoteKind = null; + state.soyState.pop(); + } + return "string"; + } + + if (stream.match(/^\/\*/)) { + state.soyState.push("comment"); + return "comment"; + } else if (stream.match(stream.sol() || (state.soyState.length && last(state.soyState) != "literal") ? /^\s*\/\/.*/ : /^\s+\/\/.*/)) { + return "comment"; + } + + switch (last(state.soyState)) { + case "templ-def": + if (match = stream.match(/^\.?([\w]+(?!\.[\w]+)*)/)) { + state.templates = prepend(state.templates, match[1]); + state.scopes = prepend(state.scopes, state.variables); + state.soyState.pop(); + return "def"; + } + stream.next(); + return null; + + case "templ-ref": + if (match = stream.match(/^\.?([\w]+)/)) { + state.soyState.pop(); + // If the first character is '.', try to match against a local template name. + if (match[0][0] == '.') { + return ref(state.templates, match[1], true); + } + // Otherwise + return "variable"; + } + stream.next(); + return null; + + case "param-def": + if (match = stream.match(/^\w+/)) { + state.variables = prepend(state.variables, match[0]); + state.soyState.pop(); + state.soyState.push("param-type"); + return "def"; + } + stream.next(); + return null; + + case "param-type": + if (stream.peek() == "}") { + state.soyState.pop(); + return null; + } + if (stream.eatWhile(/^[\w]+/)) { + return "variable-3"; + } + stream.next(); + return null; + + case "var-def": + if (match = stream.match(/^\$([\w]+)/)) { + state.variables = prepend(state.variables, match[1]); + state.soyState.pop(); + return "def"; + } + stream.next(); + return null; + + case "tag": + if (stream.match(/^\/?}/)) { + if (state.tag == "/template" || state.tag == "/deltemplate") { + popscope(state); + state.variables = prepend(null, 'ij'); + state.indent = 0; + } else { + if (state.tag == "/for" || state.tag == "/foreach") { + popscope(state); + } + state.indent -= config.indentUnit * + (stream.current() == "/}" || indentingTags.indexOf(state.tag) == -1 ? 2 : 1); + } + state.soyState.pop(); + return "keyword"; + } else if (stream.match(/^([\w?]+)(?==)/)) { + if (stream.current() == "kind" && (match = stream.match(/^="([^"]+)/, false))) { + var kind = match[1]; + state.kind.push(kind); + state.kindTag.push(state.tag); + var mode = modes[kind] || modes.html; + var localState = last(state.localStates); + if (localState.mode.indent) { + state.indent += localState.mode.indent(localState.state, ""); + } + state.localStates.push({ + mode: mode, + state: CodeMirror.startState(mode) + }); + } + return "attribute"; + } else if (match = stream.match(/^["']/)) { + state.soyState.push("string"); + state.quoteKind = match; + return "string"; + } + if (match = stream.match(/^\$([\w]+)/)) { + return ref(state.variables, match[1]); + } + if (match = stream.match(/^\w+/)) { + return /^(?:as|and|or|not|in)$/.test(match[0]) ? "keyword" : null; + } + stream.next(); + return null; + + case "literal": + if (stream.match(/^(?=\{\/literal})/)) { + state.indent -= config.indentUnit; + state.soyState.pop(); + return this.token(stream, state); + } + return tokenUntil(stream, state, /\{\/literal}/); + } + + if (stream.match(/^\{literal}/)) { + state.indent += config.indentUnit; + state.soyState.push("literal"); + return "keyword"; + + // A tag-keyword must be followed by whitespace, comment or a closing tag. + } else if (match = stream.match(/^\{([\/@\\]?\w+\??)(?=[\s\}]|\/[/*])/)) { + if (match[1] != "/switch") + state.indent += (/^(\/|(else|elseif|ifempty|case|fallbackmsg|default)$)/.test(match[1]) && state.tag != "switch" ? 1 : 2) * config.indentUnit; + state.tag = match[1]; + if (state.tag == "/" + last(state.kindTag)) { + // We found the tag that opened the current kind="". + state.kind.pop(); + state.kindTag.pop(); + state.localStates.pop(); + var localState = last(state.localStates); + if (localState.mode.indent) { + state.indent -= localState.mode.indent(localState.state, ""); + } + } + state.soyState.push("tag"); + if (state.tag == "template" || state.tag == "deltemplate") { + state.soyState.push("templ-def"); + } else if (state.tag == "call" || state.tag == "delcall") { + state.soyState.push("templ-ref"); + } else if (state.tag == "let") { + state.soyState.push("var-def"); + } else if (state.tag == "for" || state.tag == "foreach") { + state.scopes = prepend(state.scopes, state.variables); + state.soyState.push("var-def"); + } else if (state.tag == "namespace") { + if (!state.scopes) { + state.variables = prepend(null, 'ij'); + } + } else if (state.tag.match(/^@(?:param\??|inject)/)) { + state.soyState.push("param-def"); + } + return "keyword"; + + // Not a tag-keyword; it's an implicit print tag. + } else if (stream.eat('{')) { + state.tag = "print"; + state.indent += 2 * config.indentUnit; + state.soyState.push("tag"); + return "keyword"; + } + + return tokenUntil(stream, state, /\{|\s+\/\/|\/\*/); + }, + + indent: function(state, textAfter) { + var indent = state.indent, top = last(state.soyState); + if (top == "comment") return CodeMirror.Pass; + + if (top == "literal") { + if (/^\{\/literal}/.test(textAfter)) indent -= config.indentUnit; + } else { + if (/^\s*\{\/(template|deltemplate)\b/.test(textAfter)) return 0; + if (/^\{(\/|(fallbackmsg|elseif|else|ifempty)\b)/.test(textAfter)) indent -= config.indentUnit; + if (state.tag != "switch" && /^\{(case|default)\b/.test(textAfter)) indent -= config.indentUnit; + if (/^\{\/switch\b/.test(textAfter)) indent -= config.indentUnit; + } + var localState = last(state.localStates); + if (indent && localState.mode.indent) { + indent += localState.mode.indent(localState.state, textAfter); + } + return indent; + }, + + innerMode: function(state) { + if (state.soyState.length && last(state.soyState) != "literal") return null; + else return last(state.localStates); + }, + + electricInput: /^\s*\{(\/|\/template|\/deltemplate|\/switch|fallbackmsg|elseif|else|case|default|ifempty|\/literal\})$/, + lineComment: "//", + blockCommentStart: "/*", + blockCommentEnd: "*/", + blockCommentContinue: " * ", + useInnerComments: false, + fold: "indent" + }; + }, "htmlmixed"); + + CodeMirror.registerHelper("hintWords", "soy", indentingTags.concat( + ["delpackage", "namespace", "alias", "print", "css", "debugger"])); + + CodeMirror.defineMIME("text/x-soy", "soy"); +}); diff --git a/backend/webif/static/codemirror/mode/soy/test.js b/backend/webif/static/codemirror/mode/soy/test.js new file mode 100755 index 000000000..7cd111f2f --- /dev/null +++ b/backend/webif/static/codemirror/mode/soy/test.js @@ -0,0 +1,114 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "soy"); + function MT(name) {test.mode(name, mode, Array.prototype.slice.call(arguments, 1));} + + // Test of small keywords and words containing them. + MT('keywords-test', + '[keyword {] [keyword as] worrying [keyword and] notorious [keyword as]', + ' the Fandor-alias assassin, [keyword or]', + ' Corcand cannot fit [keyword in] [keyword }]'); + + MT('let-test', + '[keyword {template] [def .name][keyword }]', + ' [keyword {let] [def $name]: [string "world"][keyword /}]', + ' [tag&bracket <][tag h1][tag&bracket >]', + ' Hello, [keyword {][variable-2 $name][keyword }]', + ' [tag&bracket ]', + '[keyword {/template}]', + ''); + + MT('param-type-test', + '[keyword {@param] [def a]: ' + + '[variable-3 list]<[[[variable-3 a]: [variable-3 int], ' + + '[variable-3 b]: [variable-3 map]<[variable-3 string], ' + + '[variable-3 bool]>]]>][keyword }]'); + + MT('undefined-var', + '[keyword {][variable-2&error $var]'); + + MT('param-scope-test', + '[keyword {template] [def .a][keyword }]', + ' [keyword {@param] [def x]: [variable-3 string][keyword }]', + ' [keyword {][variable-2 $x][keyword }]', + '[keyword {/template}]', + '', + '[keyword {template] [def .b][keyword }]', + ' [keyword {][variable-2&error $x][keyword }]', + '[keyword {/template}]', + ''); + + MT('if-variable-test', + '[keyword {if] [variable-2&error $showThing][keyword }]', + ' Yo!', + '[keyword {/if}]', + ''); + + MT('defined-if-variable-test', + '[keyword {template] [def .foo][keyword }]', + ' [keyword {@param?] [def showThing]: [variable-3 bool][keyword }]', + ' [keyword {if] [variable-2 $showThing][keyword }]', + ' Yo!', + ' [keyword {/if}]', + '[keyword {/template}]', + ''); + + MT('template-calls-test', + '[keyword {template] [def .foo][keyword }]', + ' Yo!', + '[keyword {/template}]', + '[keyword {call] [variable-2 .foo][keyword /}]', + '[keyword {call] [variable foo][keyword /}]', + '[keyword {call] [variable .bar][keyword /}]', + '[keyword {call] [variable bar][keyword /}]', + ''); + + MT('foreach-scope-test', + '[keyword {@param] [def bar]: [variable-3 string][keyword }]', + '[keyword {foreach] [def $foo] [keyword in] [variable-2&error $foos][keyword }]', + ' [keyword {][variable-2 $foo][keyword }]', + '[keyword {/foreach}]', + '[keyword {][variable-2&error $foo][keyword }]', + '[keyword {][variable-2 $bar][keyword }]'); + + MT('foreach-ifempty-indent-test', + '[keyword {foreach] [def $foo] [keyword in] [variable-2&error $foos][keyword }]', + ' something', + '[keyword {ifempty}]', + ' nothing', + '[keyword {/foreach}]', + ''); + + MT('nested-kind-test', + '[keyword {template] [def .foo] [attribute kind]=[string "html"][keyword }]', + ' [tag&bracket <][tag div][tag&bracket >]', + ' [keyword {call] [variable .bar][keyword }]', + ' [keyword {param] [attribute kind]=[string "js"][keyword }]', + ' [keyword var] [def bar] [operator =] [number 5];', + ' [keyword {/param}]', + ' [keyword {/call}]', + ' [tag&bracket ]', + '[keyword {/template}]', + ''); + + MT('tag-starting-with-function-call-is-not-a-keyword', + '[keyword {]index([variable-2&error $foo])[keyword }]', + '[keyword {css] [string "some-class"][keyword }]', + '[keyword {]css([string "some-class"])[keyword }]', + ''); + + MT('allow-missing-colon-in-@param', + '[keyword {template] [def .foo][keyword }]', + ' [keyword {@param] [def showThing] [variable-3 bool][keyword }]', + ' [keyword {if] [variable-2 $showThing][keyword }]', + ' Yo!', + ' [keyword {/if}]', + '[keyword {/template}]', + ''); + + MT('single-quote-strings', + '[keyword {][string "foo"] [string \'bar\'][keyword }]', + ''); +})(); diff --git a/backend/webif/static/codemirror/mode/sparql/index.html b/backend/webif/static/codemirror/mode/sparql/index.html new file mode 100755 index 000000000..84ef4d363 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sparql/index.html @@ -0,0 +1,61 @@ + + +CodeMirror: SPARQL mode + + + + + + + + + + +
+

SPARQL mode

+
+ + +

MIME types defined: application/sparql-query.

+ +
diff --git a/backend/webif/static/codemirror/mode/sparql/sparql.js b/backend/webif/static/codemirror/mode/sparql/sparql.js new file mode 100755 index 000000000..095dcca65 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sparql/sparql.js @@ -0,0 +1,180 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("sparql", function(config) { + var indentUnit = config.indentUnit; + var curPunc; + + function wordRegexp(words) { + return new RegExp("^(?:" + words.join("|") + ")$", "i"); + } + var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri", + "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample", + "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen", + "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends", + "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds", + "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384", + "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists", + "isblank", "isliteral", "a", "bind"]); + var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe", + "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional", + "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group", + "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union", + "true", "false", "with", + "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]); + var operatorChars = /[*+\-<>=&|\^\/!\?]/; + + function tokenBase(stream, state) { + var ch = stream.next(); + curPunc = null; + if (ch == "$" || ch == "?") { + if(ch == "?" && stream.match(/\s/, false)){ + return "operator"; + } + stream.match(/^[\w\d]*/); + return "variable-2"; + } + else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { + stream.match(/^[^\s\u00a0>]*>?/); + return "atom"; + } + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenLiteral(ch); + return state.tokenize(stream, state); + } + else if (/[{}\(\),\.;\[\]]/.test(ch)) { + curPunc = ch; + return "bracket"; + } + else if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + else if (operatorChars.test(ch)) { + stream.eatWhile(operatorChars); + return "operator"; + } + else if (ch == ":") { + stream.eatWhile(/[\w\d\._\-]/); + return "atom"; + } + else if (ch == "@") { + stream.eatWhile(/[a-z\d\-]/i); + return "meta"; + } + else { + stream.eatWhile(/[_\w\d]/); + if (stream.eat(":")) { + stream.eatWhile(/[\w\d_\-]/); + return "atom"; + } + var word = stream.current(); + if (ops.test(word)) + return "builtin"; + else if (keywords.test(word)) + return "keyword"; + else + return "variable"; + } + } + + function tokenLiteral(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && ch == "\\"; + } + return "string"; + }; + } + + function pushContext(state, type, col) { + state.context = {prev: state.context, indent: state.indent, col: col, type: type}; + } + function popContext(state) { + state.indent = state.context.indent; + state.context = state.context.prev; + } + + return { + startState: function() { + return {tokenize: tokenBase, + context: null, + indent: 0, + col: 0}; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (state.context && state.context.align == null) state.context.align = false; + state.indent = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + + if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { + state.context.align = true; + } + + if (curPunc == "(") pushContext(state, ")", stream.column()); + else if (curPunc == "[") pushContext(state, "]", stream.column()); + else if (curPunc == "{") pushContext(state, "}", stream.column()); + else if (/[\]\}\)]/.test(curPunc)) { + while (state.context && state.context.type == "pattern") popContext(state); + if (state.context && curPunc == state.context.type) { + popContext(state); + if (curPunc == "}" && state.context && state.context.type == "pattern") + popContext(state); + } + } + else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); + else if (/atom|string|variable/.test(style) && state.context) { + if (/[\}\]]/.test(state.context.type)) + pushContext(state, "pattern", stream.column()); + else if (state.context.type == "pattern" && !state.context.align) { + state.context.align = true; + state.context.col = stream.column(); + } + } + + return style; + }, + + indent: function(state, textAfter) { + var firstChar = textAfter && textAfter.charAt(0); + var context = state.context; + if (/[\]\}]/.test(firstChar)) + while (context && context.type == "pattern") context = context.prev; + + var closing = context && firstChar == context.type; + if (!context) + return 0; + else if (context.type == "pattern") + return context.col; + else if (context.align) + return context.col + (closing ? 0 : 1); + else + return context.indent + (closing ? 0 : indentUnit); + }, + + lineComment: "#" + }; +}); + +CodeMirror.defineMIME("application/sparql-query", "sparql"); + +}); diff --git a/backend/webif/static/codemirror/mode/spreadsheet/index.html b/backend/webif/static/codemirror/mode/spreadsheet/index.html new file mode 100755 index 000000000..a52f76f05 --- /dev/null +++ b/backend/webif/static/codemirror/mode/spreadsheet/index.html @@ -0,0 +1,42 @@ + + +CodeMirror: Spreadsheet mode + + + + + + + + + + +
+

Spreadsheet mode

+
+ + + +

MIME types defined: text/x-spreadsheet.

+ +

The Spreadsheet Mode

+

Created by Robert Plummer

+
diff --git a/backend/webif/static/codemirror/mode/spreadsheet/spreadsheet.js b/backend/webif/static/codemirror/mode/spreadsheet/spreadsheet.js new file mode 100755 index 000000000..222f29766 --- /dev/null +++ b/backend/webif/static/codemirror/mode/spreadsheet/spreadsheet.js @@ -0,0 +1,112 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("spreadsheet", function () { + return { + startState: function () { + return { + stringType: null, + stack: [] + }; + }, + token: function (stream, state) { + if (!stream) return; + + //check for state changes + if (state.stack.length === 0) { + //strings + if ((stream.peek() == '"') || (stream.peek() == "'")) { + state.stringType = stream.peek(); + stream.next(); // Skip quote + state.stack.unshift("string"); + } + } + + //return state + //stack has + switch (state.stack[0]) { + case "string": + while (state.stack[0] === "string" && !stream.eol()) { + if (stream.peek() === state.stringType) { + stream.next(); // Skip quote + state.stack.shift(); // Clear flag + } else if (stream.peek() === "\\") { + stream.next(); + stream.next(); + } else { + stream.match(/^.[^\\\"\']*/); + } + } + return "string"; + + case "characterClass": + while (state.stack[0] === "characterClass" && !stream.eol()) { + if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) + state.stack.shift(); + } + return "operator"; + } + + var peek = stream.peek(); + + //no stack + switch (peek) { + case "[": + stream.next(); + state.stack.unshift("characterClass"); + return "bracket"; + case ":": + stream.next(); + return "operator"; + case "\\": + if (stream.match(/\\[a-z]+/)) return "string-2"; + else { + stream.next(); + return "atom"; + } + case ".": + case ",": + case ";": + case "*": + case "-": + case "+": + case "^": + case "<": + case "/": + case "=": + stream.next(); + return "atom"; + case "$": + stream.next(); + return "builtin"; + } + + if (stream.match(/\d+/)) { + if (stream.match(/^\w+/)) return "error"; + return "number"; + } else if (stream.match(/^[a-zA-Z_]\w*/)) { + if (stream.match(/(?=[\(.])/, false)) return "keyword"; + return "variable-2"; + } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) { + stream.next(); + return "bracket"; + } else if (!stream.eatSpace()) { + stream.next(); + } + return null; + } + }; + }); + + CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet"); +}); diff --git a/backend/webif/static/codemirror/mode/sql/index.html b/backend/webif/static/codemirror/mode/sql/index.html new file mode 100755 index 000000000..b434f0f40 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sql/index.html @@ -0,0 +1,88 @@ + + +CodeMirror: SQL Mode for CodeMirror + + + + + + + + + + + + +
+

SQL Mode for CodeMirror

+
+ +
+

MIME types defined: + text/x-sql, + text/x-mysql, + text/x-mariadb, + text/x-cassandra, + text/x-plsql, + text/x-mssql, + text/x-hive, + text/x-pgsql, + text/x-gql, + text/x-gpsql. + text/x-esper. +

+ + +
diff --git a/backend/webif/static/codemirror/mode/sql/sql.js b/backend/webif/static/codemirror/mode/sql/sql.js new file mode 100755 index 000000000..da416f204 --- /dev/null +++ b/backend/webif/static/codemirror/mode/sql/sql.js @@ -0,0 +1,488 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("sql", function(config, parserConfig) { + "use strict"; + + var client = parserConfig.client || {}, + atoms = parserConfig.atoms || {"false": true, "true": true, "null": true}, + builtin = parserConfig.builtin || {}, + keywords = parserConfig.keywords || {}, + operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/, + support = parserConfig.support || {}, + hooks = parserConfig.hooks || {}, + dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true}; + + function tokenBase(stream, state) { + var ch = stream.next(); + + // call hooks from the mime type + if (hooks[ch]) { + var result = hooks[ch](stream, state); + if (result !== false) return result; + } + + if (support.hexNumber && + ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) + || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) { + // hex + // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html + return "number"; + } else if (support.binaryNumber && + (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/)) + || (ch == "0" && stream.match(/^b[01]+/)))) { + // bitstring + // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html + return "number"; + } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) { + // numbers + // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html + stream.match(/^[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?/); + support.decimallessFloat && stream.match(/^\.(?!\.)/); + return "number"; + } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) { + // placeholders + return "variable-3"; + } else if (ch == "'" || (ch == '"' && support.doubleQuote)) { + // strings + // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html + state.tokenize = tokenLiteral(ch); + return state.tokenize(stream, state); + } else if ((((support.nCharCast && (ch == "n" || ch == "N")) + || (support.charsetCast && ch == "_" && stream.match(/[a-z][a-z0-9]*/i))) + && (stream.peek() == "'" || stream.peek() == '"'))) { + // charset casting: _utf8'str', N'str', n'str' + // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html + return "keyword"; + } else if (/^[\(\),\;\[\]]/.test(ch)) { + // no highlighting + return null; + } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) { + // 1-line comment + stream.skipToEnd(); + return "comment"; + } else if ((support.commentHash && ch == "#") + || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) { + // 1-line comments + // ref: https://kb.askmonty.org/en/comment-syntax/ + stream.skipToEnd(); + return "comment"; + } else if (ch == "/" && stream.eat("*")) { + // multi-line comments + // ref: https://kb.askmonty.org/en/comment-syntax/ + state.tokenize = tokenComment(1); + return state.tokenize(stream, state); + } else if (ch == ".") { + // .1 for 0.1 + if (support.zerolessFloat && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) + return "number"; + if (stream.match(/^\.+/)) + return null + // .table_name (ODBC) + // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html + if (support.ODBCdotTable && stream.match(/^[\w\d_]+/)) + return "variable-2"; + } else if (operatorChars.test(ch)) { + // operators + stream.eatWhile(operatorChars); + return null; + } else if (ch == '{' && + (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) { + // dates (weird ODBC syntax) + // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html + return "number"; + } else { + stream.eatWhile(/^[_\w\d]/); + var word = stream.current().toLowerCase(); + // dates (standard SQL syntax) + // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html + if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/))) + return "number"; + if (atoms.hasOwnProperty(word)) return "atom"; + if (builtin.hasOwnProperty(word)) return "builtin"; + if (keywords.hasOwnProperty(word)) return "keyword"; + if (client.hasOwnProperty(word)) return "string-2"; + return null; + } + } + + // 'string', with char specified in quote escaped by '\' + function tokenLiteral(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && ch == "\\"; + } + return "string"; + }; + } + function tokenComment(depth) { + return function(stream, state) { + var m = stream.match(/^.*?(\/\*|\*\/)/) + if (!m) stream.skipToEnd() + else if (m[1] == "/*") state.tokenize = tokenComment(depth + 1) + else if (depth > 1) state.tokenize = tokenComment(depth - 1) + else state.tokenize = tokenBase + return "comment" + } + } + + function pushContext(stream, state, type) { + state.context = { + prev: state.context, + indent: stream.indentation(), + col: stream.column(), + type: type + }; + } + + function popContext(state) { + state.indent = state.context.indent; + state.context = state.context.prev; + } + + return { + startState: function() { + return {tokenize: tokenBase, context: null}; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (state.context && state.context.align == null) + state.context.align = false; + } + if (state.tokenize == tokenBase && stream.eatSpace()) return null; + + var style = state.tokenize(stream, state); + if (style == "comment") return style; + + if (state.context && state.context.align == null) + state.context.align = true; + + var tok = stream.current(); + if (tok == "(") + pushContext(stream, state, ")"); + else if (tok == "[") + pushContext(stream, state, "]"); + else if (state.context && state.context.type == tok) + popContext(state); + return style; + }, + + indent: function(state, textAfter) { + var cx = state.context; + if (!cx) return CodeMirror.Pass; + var closing = textAfter.charAt(0) == cx.type; + if (cx.align) return cx.col + (closing ? 0 : 1); + else return cx.indent + (closing ? 0 : config.indentUnit); + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : "--" + }; +}); + +(function() { + "use strict"; + + // `identifier` + function hookIdentifier(stream) { + // MySQL/MariaDB identifiers + // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html + var ch; + while ((ch = stream.next()) != null) { + if (ch == "`" && !stream.eat("`")) return "variable-2"; + } + stream.backUp(stream.current().length - 1); + return stream.eatWhile(/\w/) ? "variable-2" : null; + } + + // "identifier" + function hookIdentifierDoublequote(stream) { + // Standard SQL /SQLite identifiers + // ref: http://web.archive.org/web/20160813185132/http://savage.net.au/SQL/sql-99.bnf.html#delimited%20identifier + // ref: http://sqlite.org/lang_keywords.html + var ch; + while ((ch = stream.next()) != null) { + if (ch == "\"" && !stream.eat("\"")) return "variable-2"; + } + stream.backUp(stream.current().length - 1); + return stream.eatWhile(/\w/) ? "variable-2" : null; + } + + // variable token + function hookVar(stream) { + // variables + // @@prefix.varName @varName + // varName can be quoted with ` or ' or " + // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html + if (stream.eat("@")) { + stream.match(/^session\./); + stream.match(/^local\./); + stream.match(/^global\./); + } + + if (stream.eat("'")) { + stream.match(/^.*'/); + return "variable-2"; + } else if (stream.eat('"')) { + stream.match(/^.*"/); + return "variable-2"; + } else if (stream.eat("`")) { + stream.match(/^.*`/); + return "variable-2"; + } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) { + return "variable-2"; + } + return null; + }; + + // short client keyword token + function hookClient(stream) { + // \N means NULL + // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html + if (stream.eat("N")) { + return "atom"; + } + // \g, etc + // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html + return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null; + } + + // these keywords are used by all SQL dialects (however, a mode can still overwrite it) + var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit "; + + // turn a space-separated list into an array + function set(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + // A generic SQL Mode. It's not a standard, it just try to support what is generally supported + CodeMirror.defineMIME("text/x-sql", { + name: "sql", + keywords: set(sqlKeywords + "begin"), + builtin: set("bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable doubleQuote binaryNumber hexNumber") + }); + + CodeMirror.defineMIME("text/x-mssql", { + name: "sql", + client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), + keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered declare exec"), + builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=]/, + dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"), + hooks: { + "@": hookVar + } + }); + + CodeMirror.defineMIME("text/x-mysql", { + name: "sql", + client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), + keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"), + builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=&|^]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"), + hooks: { + "@": hookVar, + "`": hookIdentifier, + "\\": hookClient + } + }); + + CodeMirror.defineMIME("text/x-mariadb", { + name: "sql", + client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), + keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"), + builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=&|^]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"), + hooks: { + "@": hookVar, + "`": hookIdentifier, + "\\": hookClient + } + }); + + // provided by the phpLiteAdmin project - phpliteadmin.org + CodeMirror.defineMIME("text/x-sqlite", { + name: "sql", + // commands of the official SQLite client, ref: https://www.sqlite.org/cli.html#dotcmd + client: set("auth backup bail binary changes check clone databases dbinfo dump echo eqp exit explain fullschema headers help import imposter indexes iotrace limit lint load log mode nullvalue once open output print prompt quit read restore save scanstats schema separator session shell show stats system tables testcase timeout timer trace vfsinfo vfslist vfsname width"), + // ref: http://sqlite.org/lang_keywords.html + keywords: set(sqlKeywords + "abort action add after all analyze attach autoincrement before begin cascade case cast check collate column commit conflict constraint cross current_date current_time current_timestamp database default deferrable deferred detach each else end escape except exclusive exists explain fail for foreign full glob if ignore immediate index indexed initially inner instead intersect isnull key left limit match natural no notnull null of offset outer plan pragma primary query raise recursive references regexp reindex release rename replace restrict right rollback row savepoint temp temporary then to transaction trigger unique using vacuum view virtual when with without"), + // SQLite is weakly typed, ref: http://sqlite.org/datatype3.html. This is just a list of some common types. + builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text clob bigint int int2 int8 integer float double char varchar date datetime year unsigned signed numeric real"), + // ref: http://sqlite.org/syntax/literal-value.html + atoms: set("null current_date current_time current_timestamp"), + // ref: http://sqlite.org/lang_expr.html#binaryops + operatorChars: /^[*+\-%<>!=&|/~]/, + // SQLite is weakly typed, ref: http://sqlite.org/datatype3.html. This is just a list of some common types. + dateSQL: set("date time timestamp datetime"), + support: set("decimallessFloat zerolessFloat"), + identifierQuote: "\"", //ref: http://sqlite.org/lang_keywords.html + hooks: { + // bind-parameters ref:http://sqlite.org/lang_expr.html#varparam + "@": hookVar, + ":": hookVar, + "?": hookVar, + "$": hookVar, + // The preferred way to escape Identifiers is using double quotes, ref: http://sqlite.org/lang_keywords.html + "\"": hookIdentifierDoublequote, + // there is also support for backtics, ref: http://sqlite.org/lang_keywords.html + "`": hookIdentifier + } + }); + + // the query language used by Apache Cassandra is called CQL, but this mime type + // is called Cassandra to avoid confusion with Contextual Query Language + CodeMirror.defineMIME("text/x-cassandra", { + name: "sql", + client: { }, + keywords: set("add all allow alter and any apply as asc authorize batch begin by clustering columnfamily compact consistency count create custom delete desc distinct drop each_quorum exists filtering from grant if in index insert into key keyspace keyspaces level limit local_one local_quorum modify nan norecursive nosuperuser not of on one order password permission permissions primary quorum rename revoke schema select set storage superuser table three to token truncate ttl two type unlogged update use user users using values where with writetime"), + builtin: set("ascii bigint blob boolean counter decimal double float frozen inet int list map static text timestamp timeuuid tuple uuid varchar varint"), + atoms: set("false true infinity NaN"), + operatorChars: /^[<>=]/, + dateSQL: { }, + support: set("commentSlashSlash decimallessFloat"), + hooks: { } + }); + + // this is based on Peter Raganitsch's 'plsql' mode + CodeMirror.defineMIME("text/x-plsql", { + name: "sql", + client: set("appinfo arraysize autocommit autoprint autorecovery autotrace blockterminator break btitle cmdsep colsep compatibility compute concat copycommit copytypecheck define describe echo editfile embedded escape exec execute feedback flagger flush heading headsep instance linesize lno loboffset logsource long longchunksize markup native newpage numformat numwidth pagesize pause pno recsep recsepchar release repfooter repheader serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix tab term termout time timing trimout trimspool ttitle underline verify version wrap"), + keywords: set("abort accept access add all alter and any array arraylen as asc assert assign at attributes audit authorization avg base_table begin between binary_integer body boolean by case cast char char_base check close cluster clusters colauth column comment commit compress connect connected constant constraint crash create current currval cursor data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete desc digits dispose distinct do drop else elseif elsif enable end entry escape exception exception_init exchange exclusive exists exit external fast fetch file for force form from function generic goto grant group having identified if immediate in increment index indexes indicator initial initrans insert interface intersect into is key level library like limited local lock log logging long loop master maxextents maxtrans member minextents minus mislabel mode modify multiset new next no noaudit nocompress nologging noparallel not nowait number_base object of off offline on online only open option or order out package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior private privileges procedure public raise range raw read rebuild record ref references refresh release rename replace resource restrict return returning returns reverse revoke rollback row rowid rowlabel rownum rows run savepoint schema segment select separate session set share snapshot some space split sql start statement storage subtype successful synonym tabauth table tables tablespace task terminate then to trigger truncate type union unique unlimited unrecoverable unusable update use using validate value values variable view views when whenever where while with work"), + builtin: set("abs acos add_months ascii asin atan atan2 average bfile bfilename bigserial bit blob ceil character chartorowid chr clob concat convert cos cosh count dec decode deref dual dump dup_val_on_index empty error exp false float floor found glb greatest hextoraw initcap instr instrb int integer isopen last_day least length lengthb ln lower lpad ltrim lub make_ref max min mlslabel mod months_between natural naturaln nchar nclob new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null number numeric nvarchar2 nvl others power rawtohex real reftohex round rowcount rowidtochar rowtype rpad rtrim serial sign signtype sin sinh smallint soundex sqlcode sqlerrm sqrt stddev string substr substrb sum sysdate tan tanh to_char text to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid unlogged upper user userenv varchar varchar2 variance varying vsize xml"), + operatorChars: /^[*+\-%<>!=~]/, + dateSQL: set("date time timestamp"), + support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber") + }); + + // Created to support specific hive keywords + CodeMirror.defineMIME("text/x-hive", { + name: "sql", + keywords: set("select alter $elem$ $key$ $value$ add after all analyze and archive as asc before between binary both bucket buckets by cascade case cast change cluster clustered clusterstatus collection column columns comment compute concatenate continue create cross cursor data database databases dbproperties deferred delete delimited desc describe directory disable distinct distribute drop else enable end escaped exclusive exists explain export extended external false fetch fields fileformat first format formatted from full function functions grant group having hold_ddltime idxproperties if import in index indexes inpath inputdriver inputformat insert intersect into is items join keys lateral left like limit lines load local location lock locks mapjoin materialized minus msck no_drop nocompress not of offline on option or order out outer outputdriver outputformat overwrite partition partitioned partitions percent plus preserve procedure purge range rcfile read readonly reads rebuild recordreader recordwriter recover reduce regexp rename repair replace restrict revoke right rlike row schema schemas semi sequencefile serde serdeproperties set shared show show_database sort sorted ssl statistics stored streamtable table tables tablesample tblproperties temporary terminated textfile then tmp to touch transform trigger true unarchive undo union uniquejoin unlock update use using utc utc_tmestamp view when where while with"), + builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=]/, + dateSQL: set("date timestamp"), + support: set("ODBCdotTable doubleQuote binaryNumber hexNumber") + }); + + CodeMirror.defineMIME("text/x-pgsql", { + name: "sql", + client: set("source"), + // https://www.postgresql.org/docs/10/static/sql-keywords-appendix.html + keywords: set(sqlKeywords + "a abort abs absent absolute access according action ada add admin after aggregate all allocate also always analyse analyze any are array array_agg array_max_cardinality asensitive assertion assignment asymmetric at atomic attribute attributes authorization avg backward base64 before begin begin_frame begin_partition bernoulli binary bit_length blob blocked bom both breadth c cache call called cardinality cascade cascaded case cast catalog catalog_name ceil ceiling chain characteristics characters character_length character_set_catalog character_set_name character_set_schema char_length check checkpoint class class_origin clob close cluster coalesce cobol collate collation collation_catalog collation_name collation_schema collect column columns column_name command_function command_function_code comment comments commit committed concurrently condition condition_number configuration conflict connect connection connection_name constraint constraints constraint_catalog constraint_name constraint_schema constructor contains content continue control conversion convert copy corr corresponding cost covar_pop covar_samp cross csv cube cume_dist current current_catalog current_date current_default_transform_group current_path current_role current_row current_schema current_time current_timestamp current_transform_group_for_type current_user cursor cursor_name cycle data database datalink datetime_interval_code datetime_interval_precision day db deallocate dec declare default defaults deferrable deferred defined definer degree delimiter delimiters dense_rank depth deref derived describe descriptor deterministic diagnostics dictionary disable discard disconnect dispatch dlnewcopy dlpreviouscopy dlurlcomplete dlurlcompleteonly dlurlcompletewrite dlurlpath dlurlpathonly dlurlpathwrite dlurlscheme dlurlserver dlvalue do document domain dynamic dynamic_function dynamic_function_code each element else empty enable encoding encrypted end end-exec end_frame end_partition enforced enum equals escape event every except exception exclude excluding exclusive exec execute exists exp explain expression extension external extract false family fetch file filter final first first_value flag float floor following for force foreign fortran forward found frame_row free freeze fs full function functions fusion g general generated get global go goto grant granted greatest grouping groups handler header hex hierarchy hold hour id identity if ignore ilike immediate immediately immutable implementation implicit import including increment indent index indexes indicator inherit inherits initially inline inner inout input insensitive instance instantiable instead integrity intersect intersection invoker isnull isolation k key key_member key_type label lag language large last last_value lateral lead leading leakproof least left length level library like_regex link listen ln load local localtime localtimestamp location locator lock locked logged lower m map mapping match matched materialized max maxvalue max_cardinality member merge message_length message_octet_length message_text method min minute minvalue mod mode modifies module month more move multiset mumps name names namespace national natural nchar nclob nesting new next nfc nfd nfkc nfkd nil no none normalize normalized nothing notify notnull nowait nth_value ntile null nullable nullif nulls number object occurrences_regex octets octet_length of off offset oids old only open operator option options ordering ordinality others out outer output over overlaps overlay overriding owned owner p pad parallel parameter parameter_mode parameter_name parameter_ordinal_position parameter_specific_catalog parameter_specific_name parameter_specific_schema parser partial partition pascal passing passthrough password percent percentile_cont percentile_disc percent_rank period permission placing plans pli policy portion position position_regex power precedes preceding prepare prepared preserve primary prior privileges procedural procedure program public quote range rank read reads reassign recheck recovery recursive ref references referencing refresh regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy regr_syy reindex relative release rename repeatable replace replica requiring reset respect restart restore restrict restricted result return returned_cardinality returned_length returned_octet_length returned_sqlstate returning returns revoke right role rollback rollup routine routine_catalog routine_name routine_schema row rows row_count row_number rule savepoint scale schema schema_name scope scope_catalog scope_name scope_schema scroll search second section security selective self sensitive sequence sequences serializable server server_name session session_user setof sets share show similar simple size skip snapshot some source space specific specifictype specific_name sql sqlcode sqlerror sqlexception sqlstate sqlwarning sqrt stable standalone start state statement static statistics stddev_pop stddev_samp stdin stdout storage strict strip structure style subclass_origin submultiset substring substring_regex succeeds sum symmetric sysid system system_time system_user t tables tablesample tablespace table_name temp template temporary then ties timezone_hour timezone_minute to token top_level_count trailing transaction transactions_committed transactions_rolled_back transaction_active transform transforms translate translate_regex translation treat trigger trigger_catalog trigger_name trigger_schema trim trim_array true truncate trusted type types uescape unbounded uncommitted under unencrypted unique unknown unlink unlisten unlogged unnamed unnest until untyped upper uri usage user user_defined_type_catalog user_defined_type_code user_defined_type_name user_defined_type_schema using vacuum valid validate validator value value_of varbinary variadic var_pop var_samp verbose version versioning view views volatile when whenever whitespace width_bucket window within work wrapper write xmlagg xmlattributes xmlbinary xmlcast xmlcomment xmlconcat xmldeclaration xmldocument xmlelement xmlexists xmlforest xmliterate xmlnamespaces xmlparse xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltext xmlvalidate year yes loop repeat attach path depends detach zone"), + // https://www.postgresql.org/docs/10/static/datatype.html + builtin: set("bigint int8 bigserial serial8 bit varying varbit boolean bool box bytea character char varchar cidr circle date double precision float8 inet integer int int4 interval json jsonb line lseg macaddr macaddr8 money numeric decimal path pg_lsn point polygon real float4 smallint int2 smallserial serial2 serial serial4 text time without zone with timetz timestamp timestamptz tsquery tsvector txid_snapshot uuid xml"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=&|^\/#@?~]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber nCharCast charsetCast") + }); + + // Google's SQL-like query language, GQL + CodeMirror.defineMIME("text/x-gql", { + name: "sql", + keywords: set("ancestor and asc by contains desc descendant distinct from group has in is limit offset on order select superset where"), + atoms: set("false true"), + builtin: set("blob datetime first key __key__ string integer double boolean null"), + operatorChars: /^[*+\-%<>!=]/ + }); + + // Greenplum + CodeMirror.defineMIME("text/x-gpsql", { + name: "sql", + client: set("source"), + //https://github.com/greenplum-db/gpdb/blob/master/src/include/parser/kwlist.h + keywords: set("abort absolute access action active add admin after aggregate all also alter always analyse analyze and any array as asc assertion assignment asymmetric at authorization backward before begin between bigint binary bit boolean both by cache called cascade cascaded case cast chain char character characteristics check checkpoint class close cluster coalesce codegen collate column comment commit committed concurrency concurrently configuration connection constraint constraints contains content continue conversion copy cost cpu_rate_limit create createdb createexttable createrole createuser cross csv cube current current_catalog current_date current_role current_schema current_time current_timestamp current_user cursor cycle data database day deallocate dec decimal declare decode default defaults deferrable deferred definer delete delimiter delimiters deny desc dictionary disable discard distinct distributed do document domain double drop dxl each else enable encoding encrypted end enum errors escape every except exchange exclude excluding exclusive execute exists explain extension external extract false family fetch fields filespace fill filter first float following for force foreign format forward freeze from full function global grant granted greatest group group_id grouping handler hash having header hold host hour identity if ignore ilike immediate immutable implicit in including inclusive increment index indexes inherit inherits initially inline inner inout input insensitive insert instead int integer intersect interval into invoker is isnull isolation join key language large last leading least left level like limit list listen load local localtime localtimestamp location lock log login mapping master match maxvalue median merge minute minvalue missing mode modifies modify month move name names national natural nchar new newline next no nocreatedb nocreateexttable nocreaterole nocreateuser noinherit nologin none noovercommit nosuperuser not nothing notify notnull nowait null nullif nulls numeric object of off offset oids old on only operator option options or order ordered others out outer over overcommit overlaps overlay owned owner parser partial partition partitions passing password percent percentile_cont percentile_disc placing plans position preceding precision prepare prepared preserve primary prior privileges procedural procedure protocol queue quote randomly range read readable reads real reassign recheck recursive ref references reindex reject relative release rename repeatable replace replica reset resource restart restrict returning returns revoke right role rollback rollup rootpartition row rows rule savepoint scatter schema scroll search second security segment select sequence serializable session session_user set setof sets share show similar simple smallint some split sql stable standalone start statement statistics stdin stdout storage strict strip subpartition subpartitions substring superuser symmetric sysid system table tablespace temp template temporary text then threshold ties time timestamp to trailing transaction treat trigger trim true truncate trusted type unbounded uncommitted unencrypted union unique unknown unlisten until update user using vacuum valid validation validator value values varchar variadic varying verbose version view volatile web when where whitespace window with within without work writable write xml xmlattributes xmlconcat xmlelement xmlexists xmlforest xmlparse xmlpi xmlroot xmlserialize year yes zone"), + builtin: set("bigint int8 bigserial serial8 bit varying varbit boolean bool box bytea character char varchar cidr circle date double precision float float8 inet integer int int4 interval json jsonb line lseg macaddr macaddr8 money numeric decimal path pg_lsn point polygon real float4 smallint int2 smallserial serial2 serial serial4 text time without zone with timetz timestamp timestamptz tsquery tsvector txid_snapshot uuid xml"), + atoms: set("false true null unknown"), + operatorChars: /^[*+\-%<>!=&|^\/#@?~]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber nCharCast charsetCast") + }); + + // Spark SQL + CodeMirror.defineMIME("text/x-sparksql", { + name: "sql", + keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases datata dbproperties defined delete delimited desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"), + builtin: set("tinyint smallint int bigint boolean float double string binary timestamp decimal array map struct uniontype delimited serde sequencefile textfile rcfile inputformat outputformat"), + atoms: set("false true null"), + operatorChars: /^[*+\-%<>!=~&|^]/, + dateSQL: set("date time timestamp"), + support: set("ODBCdotTable doubleQuote zerolessFloat") + }); + + // Esper + CodeMirror.defineMIME("text/x-esper", { + name: "sql", + client: set("source"), + // http://www.espertech.com/esper/release-5.5.0/esper-reference/html/appendix_keywords.html + keywords: set("alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit after all and as at asc avedev avg between by case cast coalesce count create current_timestamp day days delete define desc distinct else end escape events every exists false first from full group having hour hours in inner insert instanceof into irstream is istream join last lastweekday left limit like max match_recognize matches median measures metadatasql min minute minutes msec millisecond milliseconds not null offset on or order outer output partition pattern prev prior regexp retain-union retain-intersection right rstream sec second seconds select set some snapshot sql stddev sum then true unidirectional until update variable weekday when where window"), + builtin: {}, + atoms: set("false true null"), + operatorChars: /^[*+\-%<>!=&|^\/#@?~]/, + dateSQL: set("time"), + support: set("decimallessFloat zerolessFloat binaryNumber hexNumber") + }); +}()); + +}); + +/* + How Properties of Mime Types are used by SQL Mode + ================================================= + + keywords: + A list of keywords you want to be highlighted. + builtin: + A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword"). + operatorChars: + All characters that must be handled as operators. + client: + Commands parsed and executed by the client (not the server). + support: + A list of supported syntaxes which are not common, but are supported by more than 1 DBMS. + * ODBCdotTable: .tableName + * zerolessFloat: .1 + * doubleQuote + * nCharCast: N'string' + * charsetCast: _utf8'string' + * commentHash: use # char for comments + * commentSlashSlash: use // for comments + * commentSpaceRequired: require a space after -- for comments + atoms: + Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others: + UNKNOWN, INFINITY, UNDERFLOW, NaN... + dateSQL: + Used for date/time SQL standard syntax, because not all DBMS's support same temporal types. +*/ diff --git a/backend/webif/static/codemirror/mode/stex/index.html b/backend/webif/static/codemirror/mode/stex/index.html new file mode 100755 index 000000000..14679da4f --- /dev/null +++ b/backend/webif/static/codemirror/mode/stex/index.html @@ -0,0 +1,110 @@ + + +CodeMirror: sTeX mode + + + + + + + + + +
+

sTeX mode

+
+ + +

MIME types defined: text/x-stex.

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/stex/stex.js b/backend/webif/static/codemirror/mode/stex/stex.js new file mode 100755 index 000000000..835ed46d1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/stex/stex.js @@ -0,0 +1,251 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* + * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de) + * Licence: MIT + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("stex", function() { + "use strict"; + + function pushCommand(state, command) { + state.cmdState.push(command); + } + + function peekCommand(state) { + if (state.cmdState.length > 0) { + return state.cmdState[state.cmdState.length - 1]; + } else { + return null; + } + } + + function popCommand(state) { + var plug = state.cmdState.pop(); + if (plug) { + plug.closeBracket(); + } + } + + // returns the non-default plugin closest to the end of the list + function getMostPowerful(state) { + var context = state.cmdState; + for (var i = context.length - 1; i >= 0; i--) { + var plug = context[i]; + if (plug.name == "DEFAULT") { + continue; + } + return plug; + } + return { styleIdentifier: function() { return null; } }; + } + + function addPluginPattern(pluginName, cmdStyle, styles) { + return function () { + this.name = pluginName; + this.bracketNo = 0; + this.style = cmdStyle; + this.styles = styles; + this.argument = null; // \begin and \end have arguments that follow. These are stored in the plugin + + this.styleIdentifier = function() { + return this.styles[this.bracketNo - 1] || null; + }; + this.openBracket = function() { + this.bracketNo++; + return "bracket"; + }; + this.closeBracket = function() {}; + }; + } + + var plugins = {}; + + plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]); + plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]); + plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]); + plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]); + plugins["end"] = addPluginPattern("end", "tag", ["atom"]); + + plugins["DEFAULT"] = function () { + this.name = "DEFAULT"; + this.style = "tag"; + + this.styleIdentifier = this.openBracket = this.closeBracket = function() {}; + }; + + function setState(state, f) { + state.f = f; + } + + // called when in a normal (no environment) context + function normal(source, state) { + var plug; + // Do we look like '\command' ? If so, attempt to apply the plugin 'command' + if (source.match(/^\\[a-zA-Z@]+/)) { + var cmdName = source.current().slice(1); + plug = plugins[cmdName] || plugins["DEFAULT"]; + plug = new plug(); + pushCommand(state, plug); + setState(state, beginParams); + return plug.style; + } + + // escape characters + if (source.match(/^\\[$&%#{}_]/)) { + return "tag"; + } + + // white space control characters + if (source.match(/^\\[,;!\/\\]/)) { + return "tag"; + } + + // find if we're starting various math modes + if (source.match("\\[")) { + setState(state, function(source, state){ return inMathMode(source, state, "\\]"); }); + return "keyword"; + } + if (source.match("$$")) { + setState(state, function(source, state){ return inMathMode(source, state, "$$"); }); + return "keyword"; + } + if (source.match("$")) { + setState(state, function(source, state){ return inMathMode(source, state, "$"); }); + return "keyword"; + } + + var ch = source.next(); + if (ch == "%") { + source.skipToEnd(); + return "comment"; + } else if (ch == '}' || ch == ']') { + plug = peekCommand(state); + if (plug) { + plug.closeBracket(ch); + setState(state, beginParams); + } else { + return "error"; + } + return "bracket"; + } else if (ch == '{' || ch == '[') { + plug = plugins["DEFAULT"]; + plug = new plug(); + pushCommand(state, plug); + return "bracket"; + } else if (/\d/.test(ch)) { + source.eatWhile(/[\w.%]/); + return "atom"; + } else { + source.eatWhile(/[\w\-_]/); + plug = getMostPowerful(state); + if (plug.name == 'begin') { + plug.argument = source.current(); + } + return plug.styleIdentifier(); + } + } + + function inMathMode(source, state, endModeSeq) { + if (source.eatSpace()) { + return null; + } + if (source.match(endModeSeq)) { + setState(state, normal); + return "keyword"; + } + if (source.match(/^\\[a-zA-Z@]+/)) { + return "tag"; + } + if (source.match(/^[a-zA-Z]+/)) { + return "variable-2"; + } + // escape characters + if (source.match(/^\\[$&%#{}_]/)) { + return "tag"; + } + // white space control characters + if (source.match(/^\\[,;!\/]/)) { + return "tag"; + } + // special math-mode characters + if (source.match(/^[\^_&]/)) { + return "tag"; + } + // non-special characters + if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) { + return null; + } + if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) { + return "number"; + } + var ch = source.next(); + if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") { + return "bracket"; + } + + if (ch == "%") { + source.skipToEnd(); + return "comment"; + } + return "error"; + } + + function beginParams(source, state) { + var ch = source.peek(), lastPlug; + if (ch == '{' || ch == '[') { + lastPlug = peekCommand(state); + lastPlug.openBracket(ch); + source.eat(ch); + setState(state, normal); + return "bracket"; + } + if (/[ \t\r]/.test(ch)) { + source.eat(ch); + return null; + } + setState(state, normal); + popCommand(state); + + return normal(source, state); + } + + return { + startState: function() { + return { + cmdState: [], + f: normal + }; + }, + copyState: function(s) { + return { + cmdState: s.cmdState.slice(), + f: s.f + }; + }, + token: function(stream, state) { + return state.f(stream, state); + }, + blankLine: function(state) { + state.f = normal; + state.cmdState.length = 0; + }, + lineComment: "%" + }; + }); + + CodeMirror.defineMIME("text/x-stex", "stex"); + CodeMirror.defineMIME("text/x-latex", "stex"); + +}); diff --git a/backend/webif/static/codemirror/mode/stex/test.js b/backend/webif/static/codemirror/mode/stex/test.js new file mode 100755 index 000000000..22f027ec7 --- /dev/null +++ b/backend/webif/static/codemirror/mode/stex/test.js @@ -0,0 +1,123 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({tabSize: 4}, "stex"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("word", + "foo"); + + MT("twoWords", + "foo bar"); + + MT("beginEndDocument", + "[tag \\begin][bracket {][atom document][bracket }]", + "[tag \\end][bracket {][atom document][bracket }]"); + + MT("beginEndEquation", + "[tag \\begin][bracket {][atom equation][bracket }]", + " E=mc^2", + "[tag \\end][bracket {][atom equation][bracket }]"); + + MT("beginModule", + "[tag \\begin][bracket {][atom module][bracket }[[]]]"); + + MT("beginModuleId", + "[tag \\begin][bracket {][atom module][bracket }[[]id=bbt-size[bracket ]]]"); + + MT("importModule", + "[tag \\importmodule][bracket [[][string b-b-t][bracket ]]{][builtin b-b-t][bracket }]"); + + MT("importModulePath", + "[tag \\importmodule][bracket [[][tag \\KWARCslides][bracket {][string dmath/en/cardinality][bracket }]]{][builtin card][bracket }]"); + + MT("psForPDF", + "[tag \\PSforPDF][bracket [[][atom 1][bracket ]]{]#1[bracket }]"); + + MT("comment", + "[comment % foo]"); + + MT("tagComment", + "[tag \\item][comment % bar]"); + + MT("commentTag", + " [comment % \\item]"); + + MT("commentLineBreak", + "[comment %]", + "foo"); + + MT("tagErrorCurly", + "[tag \\begin][error }][bracket {]"); + + MT("tagErrorSquare", + "[tag \\item][error ]]][bracket {]"); + + MT("commentCurly", + "[comment % }]"); + + MT("tagHash", + "the [tag \\#] key"); + + MT("tagNumber", + "a [tag \\$][atom 5] stetson"); + + MT("tagPercent", + "[atom 100][tag \\%] beef"); + + MT("tagAmpersand", + "L [tag \\&] N"); + + MT("tagUnderscore", + "foo[tag \\_]bar"); + + MT("tagBracketOpen", + "[tag \\emph][bracket {][tag \\{][bracket }]"); + + MT("tagBracketClose", + "[tag \\emph][bracket {][tag \\}][bracket }]"); + + MT("tagLetterNumber", + "section [tag \\S][atom 1]"); + + MT("textTagNumber", + "para [tag \\P][atom 2]"); + + MT("thinspace", + "x[tag \\,]y"); + + MT("thickspace", + "x[tag \\;]y"); + + MT("negativeThinspace", + "x[tag \\!]y"); + + MT("periodNotSentence", + "J.\\ L.\\ is"); + + MT("periodSentence", + "X[tag \\@]. The"); + + MT("italicCorrection", + "[bracket {][tag \\em] If[tag \\/][bracket }] I"); + + MT("tagBracket", + "[tag \\newcommand][bracket {][tag \\pop][bracket }]"); + + MT("inlineMathTagFollowedByNumber", + "[keyword $][tag \\pi][number 2][keyword $]"); + + MT("inlineMath", + "[keyword $][number 3][variable-2 x][tag ^][number 2.45]-[tag \\sqrt][bracket {][tag \\$\\alpha][bracket }] = [number 2][keyword $] other text"); + + MT("displayMath", + "More [keyword $$]\t[variable-2 S][tag ^][variable-2 n][tag \\sum] [variable-2 i][keyword $$] other text"); + + MT("mathWithComment", + "[keyword $][variable-2 x] [comment % $]", + "[variable-2 y][keyword $] other text"); + + MT("lineBreakArgument", + "[tag \\\\][bracket [[][atom 1cm][bracket ]]]"); +})(); diff --git a/backend/webif/static/codemirror/mode/stylus/index.html b/backend/webif/static/codemirror/mode/stylus/index.html new file mode 100755 index 000000000..862c18f25 --- /dev/null +++ b/backend/webif/static/codemirror/mode/stylus/index.html @@ -0,0 +1,106 @@ + + +CodeMirror: Stylus mode + + + + + + + + + + + +
+

Stylus mode

+
+
+ + +

MIME types defined: text/x-styl.

+

Created by Dmitry Kiselyov

+
diff --git a/backend/webif/static/codemirror/mode/stylus/stylus.js b/backend/webif/static/codemirror/mode/stylus/stylus.js new file mode 100755 index 000000000..b83be16f4 --- /dev/null +++ b/backend/webif/static/codemirror/mode/stylus/stylus.js @@ -0,0 +1,771 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("stylus", function(config) { + var indentUnit = config.indentUnit, + indentUnitString = '', + tagKeywords = keySet(tagKeywords_), + tagVariablesRegexp = /^(a|b|i|s|col|em)$/i, + propertyKeywords = keySet(propertyKeywords_), + nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_), + valueKeywords = keySet(valueKeywords_), + colorKeywords = keySet(colorKeywords_), + documentTypes = keySet(documentTypes_), + documentTypesRegexp = wordRegexp(documentTypes_), + mediaFeatures = keySet(mediaFeatures_), + mediaTypes = keySet(mediaTypes_), + fontProperties = keySet(fontProperties_), + operatorsRegexp = /^\s*([.]{2,3}|&&|\|\||\*\*|[?!=:]?=|[-+*\/%<>]=?|\?:|\~)/, + wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_), + blockKeywords = keySet(blockKeywords_), + vendorPrefixesRegexp = new RegExp(/^\-(moz|ms|o|webkit)-/i), + commonAtoms = keySet(commonAtoms_), + firstWordMatch = "", + states = {}, + ch, + style, + type, + override; + + while (indentUnitString.length < indentUnit) indentUnitString += ' '; + + /** + * Tokenizers + */ + function tokenBase(stream, state) { + firstWordMatch = stream.string.match(/(^[\w-]+\s*=\s*$)|(^\s*[\w-]+\s*=\s*[\w-])|(^\s*(\.|#|@|\$|\&|\[|\d|\+|::?|\{|\>|~|\/)?\s*[\w-]*([a-z0-9-]|\*|\/\*)(\(|,)?)/); + state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(/^\s*/, "") : ""; + state.context.line.indent = stream.indentation(); + ch = stream.peek(); + + // Line comment + if (stream.match("//")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } + // Block comment + if (stream.match("/*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + // String + if (ch == "\"" || ch == "'") { + stream.next(); + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + // Def + if (ch == "@") { + stream.next(); + stream.eatWhile(/[\w\\-]/); + return ["def", stream.current()]; + } + // ID selector or Hex color + if (ch == "#") { + stream.next(); + // Hex color + if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) { + return ["atom", "atom"]; + } + // ID selector + if (stream.match(/^[a-z][\w-]*/i)) { + return ["builtin", "hash"]; + } + } + // Vendor prefixes + if (stream.match(vendorPrefixesRegexp)) { + return ["meta", "vendor-prefixes"]; + } + // Numbers + if (stream.match(/^-?[0-9]?\.?[0-9]/)) { + stream.eatWhile(/[a-z%]/i); + return ["number", "unit"]; + } + // !important|optional + if (ch == "!") { + stream.next(); + return [stream.match(/^(important|optional)/i) ? "keyword": "operator", "important"]; + } + // Class + if (ch == "." && stream.match(/^\.[a-z][\w-]*/i)) { + return ["qualifier", "qualifier"]; + } + // url url-prefix domain regexp + if (stream.match(documentTypesRegexp)) { + if (stream.peek() == "(") state.tokenize = tokenParenthesized; + return ["property", "word"]; + } + // Mixins / Functions + if (stream.match(/^[a-z][\w-]*\(/i)) { + stream.backUp(1); + return ["keyword", "mixin"]; + } + // Block mixins + if (stream.match(/^(\+|-)[a-z][\w-]*\(/i)) { + stream.backUp(1); + return ["keyword", "block-mixin"]; + } + // Parent Reference BEM naming + if (stream.string.match(/^\s*&/) && stream.match(/^[-_]+[a-z][\w-]*/)) { + return ["qualifier", "qualifier"]; + } + // / Root Reference & Parent Reference + if (stream.match(/^(\/|&)(-|_|:|\.|#|[a-z])/)) { + stream.backUp(1); + return ["variable-3", "reference"]; + } + if (stream.match(/^&{1}\s*$/)) { + return ["variable-3", "reference"]; + } + // Word operator + if (stream.match(wordOperatorKeywordsRegexp)) { + return ["operator", "operator"]; + } + // Word + if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) { + // Variable + if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) { + if (!wordIsTag(stream.current())) { + stream.match(/\./); + return ["variable-2", "variable-name"]; + } + } + return ["variable-2", "word"]; + } + // Operators + if (stream.match(operatorsRegexp)) { + return ["operator", stream.current()]; + } + // Delimiters + if (/[:;,{}\[\]\(\)]/.test(ch)) { + stream.next(); + return [null, ch]; + } + // Non-detected items + stream.next(); + return [null, null]; + } + + /** + * Token comment + */ + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return ["comment", "comment"]; + } + + /** + * Token string + */ + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + if (quote == ")") stream.backUp(1); + break; + } + escaped = !escaped && ch == "\\"; + } + if (ch == quote || !escaped && quote != ")") state.tokenize = null; + return ["string", "string"]; + }; + } + + /** + * Token parenthesized + */ + function tokenParenthesized(stream, state) { + stream.next(); // Must be "(" + if (!stream.match(/\s*[\"\')]/, false)) + state.tokenize = tokenString(")"); + else + state.tokenize = null; + return [null, "("]; + } + + /** + * Context management + */ + function Context(type, indent, prev, line) { + this.type = type; + this.indent = indent; + this.prev = prev; + this.line = line || {firstWord: "", indent: 0}; + } + + function pushContext(state, stream, type, indent) { + indent = indent >= 0 ? indent : indentUnit; + state.context = new Context(type, stream.indentation() + indent, state.context); + return type; + } + + function popContext(state, currentIndent) { + var contextIndent = state.context.indent - indentUnit; + currentIndent = currentIndent || false; + state.context = state.context.prev; + if (currentIndent) state.context.indent = contextIndent; + return state.context.type; + } + + function pass(type, stream, state) { + return states[state.context.type](type, stream, state); + } + + function popAndPass(type, stream, state, n) { + for (var i = n || 1; i > 0; i--) + state.context = state.context.prev; + return pass(type, stream, state); + } + + + /** + * Parser + */ + function wordIsTag(word) { + return word.toLowerCase() in tagKeywords; + } + + function wordIsProperty(word) { + word = word.toLowerCase(); + return word in propertyKeywords || word in fontProperties; + } + + function wordIsBlock(word) { + return word.toLowerCase() in blockKeywords; + } + + function wordIsVendorPrefix(word) { + return word.toLowerCase().match(vendorPrefixesRegexp); + } + + function wordAsValue(word) { + var wordLC = word.toLowerCase(); + var override = "variable-2"; + if (wordIsTag(word)) override = "tag"; + else if (wordIsBlock(word)) override = "block-keyword"; + else if (wordIsProperty(word)) override = "property"; + else if (wordLC in valueKeywords || wordLC in commonAtoms) override = "atom"; + else if (wordLC == "return" || wordLC in colorKeywords) override = "keyword"; + + // Font family + else if (word.match(/^[A-Z]/)) override = "string"; + return override; + } + + function typeIsBlock(type, stream) { + return ((endOfLine(stream) && (type == "{" || type == "]" || type == "hash" || type == "qualifier")) || type == "block-mixin"); + } + + function typeIsInterpolation(type, stream) { + return type == "{" && stream.match(/^\s*\$?[\w-]+/i, false); + } + + function typeIsPseudo(type, stream) { + return type == ":" && stream.match(/^[a-z-]+/, false); + } + + function startOfLine(stream) { + return stream.sol() || stream.string.match(new RegExp("^\\s*" + escapeRegExp(stream.current()))); + } + + function endOfLine(stream) { + return stream.eol() || stream.match(/^\s*$/, false); + } + + function firstWordOfLine(line) { + var re = /^\s*[-_]*[a-z0-9]+[\w-]*/i; + var result = typeof line == "string" ? line.match(re) : line.string.match(re); + return result ? result[0].replace(/^\s*/, "") : ""; + } + + + /** + * Block + */ + states.block = function(type, stream, state) { + if ((type == "comment" && startOfLine(stream)) || + (type == "," && endOfLine(stream)) || + type == "mixin") { + return pushContext(state, stream, "block", 0); + } + if (typeIsInterpolation(type, stream)) { + return pushContext(state, stream, "interpolation"); + } + if (endOfLine(stream) && type == "]") { + if (!/^\s*(\.|#|:|\[|\*|&)/.test(stream.string) && !wordIsTag(firstWordOfLine(stream))) { + return pushContext(state, stream, "block", 0); + } + } + if (typeIsBlock(type, stream)) { + return pushContext(state, stream, "block"); + } + if (type == "}" && endOfLine(stream)) { + return pushContext(state, stream, "block", 0); + } + if (type == "variable-name") { + if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstWordOfLine(stream))) { + return pushContext(state, stream, "variableName"); + } + else { + return pushContext(state, stream, "variableName", 0); + } + } + if (type == "=") { + if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) { + return pushContext(state, stream, "block", 0); + } + return pushContext(state, stream, "block"); + } + if (type == "*") { + if (endOfLine(stream) || stream.match(/\s*(,|\.|#|\[|:|{)/,false)) { + override = "tag"; + return pushContext(state, stream, "block"); + } + } + if (typeIsPseudo(type, stream)) { + return pushContext(state, stream, "pseudo"); + } + if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) { + return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock"); + } + if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + return pushContext(state, stream, "keyframes"); + } + if (/@extends?/.test(type)) { + return pushContext(state, stream, "extend", 0); + } + if (type && type.charAt(0) == "@") { + + // Property Lookup + if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1))) { + override = "variable-2"; + return "block"; + } + if (/(@import|@require|@charset)/.test(type)) { + return pushContext(state, stream, "block", 0); + } + return pushContext(state, stream, "block"); + } + if (type == "reference" && endOfLine(stream)) { + return pushContext(state, stream, "block"); + } + if (type == "(") { + return pushContext(state, stream, "parens"); + } + + if (type == "vendor-prefixes") { + return pushContext(state, stream, "vendorPrefixes"); + } + if (type == "word") { + var word = stream.current(); + override = wordAsValue(word); + + if (override == "property") { + if (startOfLine(stream)) { + return pushContext(state, stream, "block", 0); + } else { + override = "atom"; + return "block"; + } + } + + if (override == "tag") { + + // tag is a css value + if (/embed|menu|pre|progress|sub|table/.test(word)) { + if (wordIsProperty(firstWordOfLine(stream))) { + override = "atom"; + return "block"; + } + } + + // tag is an attribute + if (stream.string.match(new RegExp("\\[\\s*" + word + "|" + word +"\\s*\\]"))) { + override = "atom"; + return "block"; + } + + // tag is a variable + if (tagVariablesRegexp.test(word)) { + if ((startOfLine(stream) && stream.string.match(/=/)) || + (!startOfLine(stream) && + !stream.string.match(/^(\s*\.|#|\&|\[|\/|>|\*)/) && + !wordIsTag(firstWordOfLine(stream)))) { + override = "variable-2"; + if (wordIsBlock(firstWordOfLine(stream))) return "block"; + return pushContext(state, stream, "block", 0); + } + } + + if (endOfLine(stream)) return pushContext(state, stream, "block"); + } + if (override == "block-keyword") { + override = "keyword"; + + // Postfix conditionals + if (stream.current(/(if|unless)/) && !startOfLine(stream)) { + return "block"; + } + return pushContext(state, stream, "block"); + } + if (word == "return") return pushContext(state, stream, "block", 0); + + // Placeholder selector + if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/)) { + return pushContext(state, stream, "block"); + } + } + return state.context.type; + }; + + + /** + * Parens + */ + states.parens = function(type, stream, state) { + if (type == "(") return pushContext(state, stream, "parens"); + if (type == ")") { + if (state.context.prev.type == "parens") { + return popContext(state); + } + if ((stream.string.match(/^[a-z][\w-]*\(/i) && endOfLine(stream)) || + wordIsBlock(firstWordOfLine(stream)) || + /(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(firstWordOfLine(stream)) || + (!stream.string.match(/^-?[a-z][\w-\.\[\]\'\"]*\s*=/) && + wordIsTag(firstWordOfLine(stream)))) { + return pushContext(state, stream, "block"); + } + if (stream.string.match(/^[\$-]?[a-z][\w-\.\[\]\'\"]*\s*=/) || + stream.string.match(/^\s*(\(|\)|[0-9])/) || + stream.string.match(/^\s+[a-z][\w-]*\(/i) || + stream.string.match(/^\s+[\$-]?[a-z]/i)) { + return pushContext(state, stream, "block", 0); + } + if (endOfLine(stream)) return pushContext(state, stream, "block"); + else return pushContext(state, stream, "block", 0); + } + if (type && type.charAt(0) == "@" && wordIsProperty(stream.current().slice(1))) { + override = "variable-2"; + } + if (type == "word") { + var word = stream.current(); + override = wordAsValue(word); + if (override == "tag" && tagVariablesRegexp.test(word)) { + override = "variable-2"; + } + if (override == "property" || word == "to") override = "atom"; + } + if (type == "variable-name") { + return pushContext(state, stream, "variableName"); + } + if (typeIsPseudo(type, stream)) { + return pushContext(state, stream, "pseudo"); + } + return state.context.type; + }; + + + /** + * Vendor prefixes + */ + states.vendorPrefixes = function(type, stream, state) { + if (type == "word") { + override = "property"; + return pushContext(state, stream, "block", 0); + } + return popContext(state); + }; + + + /** + * Pseudo + */ + states.pseudo = function(type, stream, state) { + if (!wordIsProperty(firstWordOfLine(stream.string))) { + stream.match(/^[a-z-]+/); + override = "variable-3"; + if (endOfLine(stream)) return pushContext(state, stream, "block"); + return popContext(state); + } + return popAndPass(type, stream, state); + }; + + + /** + * atBlock + */ + states.atBlock = function(type, stream, state) { + if (type == "(") return pushContext(state, stream, "atBlock_parens"); + if (typeIsBlock(type, stream)) { + return pushContext(state, stream, "block"); + } + if (typeIsInterpolation(type, stream)) { + return pushContext(state, stream, "interpolation"); + } + if (type == "word") { + var word = stream.current().toLowerCase(); + if (/^(only|not|and|or)$/.test(word)) + override = "keyword"; + else if (documentTypes.hasOwnProperty(word)) + override = "tag"; + else if (mediaTypes.hasOwnProperty(word)) + override = "attribute"; + else if (mediaFeatures.hasOwnProperty(word)) + override = "property"; + else if (nonStandardPropertyKeywords.hasOwnProperty(word)) + override = "string-2"; + else override = wordAsValue(stream.current()); + if (override == "tag" && endOfLine(stream)) { + return pushContext(state, stream, "block"); + } + } + if (type == "operator" && /^(not|and|or)$/.test(stream.current())) { + override = "keyword"; + } + return state.context.type; + }; + + states.atBlock_parens = function(type, stream, state) { + if (type == "{" || type == "}") return state.context.type; + if (type == ")") { + if (endOfLine(stream)) return pushContext(state, stream, "block"); + else return pushContext(state, stream, "atBlock"); + } + if (type == "word") { + var word = stream.current().toLowerCase(); + override = wordAsValue(word); + if (/^(max|min)/.test(word)) override = "property"; + if (override == "tag") { + tagVariablesRegexp.test(word) ? override = "variable-2" : override = "atom"; + } + return state.context.type; + } + return states.atBlock(type, stream, state); + }; + + + /** + * Keyframes + */ + states.keyframes = function(type, stream, state) { + if (stream.indentation() == "0" && ((type == "}" && startOfLine(stream)) || type == "]" || type == "hash" + || type == "qualifier" || wordIsTag(stream.current()))) { + return popAndPass(type, stream, state); + } + if (type == "{") return pushContext(state, stream, "keyframes"); + if (type == "}") { + if (startOfLine(stream)) return popContext(state, true); + else return pushContext(state, stream, "keyframes"); + } + if (type == "unit" && /^[0-9]+\%$/.test(stream.current())) { + return pushContext(state, stream, "keyframes"); + } + if (type == "word") { + override = wordAsValue(stream.current()); + if (override == "block-keyword") { + override = "keyword"; + return pushContext(state, stream, "keyframes"); + } + } + if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) { + return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock"); + } + if (type == "mixin") { + return pushContext(state, stream, "block", 0); + } + return state.context.type; + }; + + + /** + * Interpolation + */ + states.interpolation = function(type, stream, state) { + if (type == "{") popContext(state) && pushContext(state, stream, "block"); + if (type == "}") { + if (stream.string.match(/^\s*(\.|#|:|\[|\*|&|>|~|\+|\/)/i) || + (stream.string.match(/^\s*[a-z]/i) && wordIsTag(firstWordOfLine(stream)))) { + return pushContext(state, stream, "block"); + } + if (!stream.string.match(/^(\{|\s*\&)/) || + stream.match(/\s*[\w-]/,false)) { + return pushContext(state, stream, "block", 0); + } + return pushContext(state, stream, "block"); + } + if (type == "variable-name") { + return pushContext(state, stream, "variableName", 0); + } + if (type == "word") { + override = wordAsValue(stream.current()); + if (override == "tag") override = "atom"; + } + return state.context.type; + }; + + + /** + * Extend/s + */ + states.extend = function(type, stream, state) { + if (type == "[" || type == "=") return "extend"; + if (type == "]") return popContext(state); + if (type == "word") { + override = wordAsValue(stream.current()); + return "extend"; + } + return popContext(state); + }; + + + /** + * Variable name + */ + states.variableName = function(type, stream, state) { + if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) { + if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2"; + return "variableName"; + } + return popAndPass(type, stream, state); + }; + + + return { + startState: function(base) { + return { + tokenize: null, + state: "block", + context: new Context("block", base || 0, null) + }; + }, + token: function(stream, state) { + if (!state.tokenize && stream.eatSpace()) return null; + style = (state.tokenize || tokenBase)(stream, state); + if (style && typeof style == "object") { + type = style[1]; + style = style[0]; + } + override = style; + state.state = states[state.state](type, stream, state); + return override; + }, + indent: function(state, textAfter, line) { + + var cx = state.context, + ch = textAfter && textAfter.charAt(0), + indent = cx.indent, + lineFirstWord = firstWordOfLine(textAfter), + lineIndent = line.match(/^\s*/)[0].replace(/\t/g, indentUnitString).length, + prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : "", + prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent; + + if (cx.prev && + (ch == "}" && (cx.type == "block" || cx.type == "atBlock" || cx.type == "keyframes") || + ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") || + ch == "{" && (cx.type == "at"))) { + indent = cx.indent - indentUnit; + } else if (!(/(\})/.test(ch))) { + if (/@|\$|\d/.test(ch) || + /^\{/.test(textAfter) || +/^\s*\/(\/|\*)/.test(textAfter) || + /^\s*\/\*/.test(prevLineFirstWord) || + /^\s*[\w-\.\[\]\'\"]+\s*(\?|:|\+)?=/i.test(textAfter) || +/^(\+|-)?[a-z][\w-]*\(/i.test(textAfter) || +/^return/.test(textAfter) || + wordIsBlock(lineFirstWord)) { + indent = lineIndent; + } else if (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(ch) || wordIsTag(lineFirstWord)) { + if (/\,\s*$/.test(prevLineFirstWord)) { + indent = prevLineIndent; + } else if (/^\s+/.test(line) && (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(prevLineFirstWord) || wordIsTag(prevLineFirstWord))) { + indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit; + } else { + indent = lineIndent; + } + } else if (!/,\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) || wordIsProperty(lineFirstWord))) { + if (wordIsBlock(prevLineFirstWord)) { + indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit; + } else if (/^\{/.test(prevLineFirstWord)) { + indent = lineIndent <= prevLineIndent ? lineIndent : prevLineIndent + indentUnit; + } else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(prevLineFirstWord)) { + indent = lineIndent >= prevLineIndent ? prevLineIndent : lineIndent; + } else if (/^(\.|#|:|\[|\*|&|@|\+|\-|>|~|\/)/.test(prevLineFirstWord) || + /=\s*$/.test(prevLineFirstWord) || + wordIsTag(prevLineFirstWord) || + /^\$[\w-\.\[\]\'\"]/.test(prevLineFirstWord)) { + indent = prevLineIndent + indentUnit; + } else { + indent = lineIndent; + } + } + } + return indent; + }, + electricChars: "}", + lineComment: "//", + fold: "indent" + }; + }); + + // developer.mozilla.org/en-US/docs/Web/HTML/Element + var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"]; + + // github.com/codemirror/CodeMirror/blob/master/mode/css/css.js + var documentTypes_ = ["domain", "regexp", "url", "url-prefix"]; + var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"]; + var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"]; + var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"]; + var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"]; + var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"]; + var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]; + var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"]; + + var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"], + blockKeywords_ = ["for","if","else","unless", "from", "to"], + commonAtoms_ = ["null","true","false","href","title","type","not-allowed","readonly","disabled"], + commonDef_ = ["@font-face", "@keyframes", "@media", "@viewport", "@page", "@host", "@supports", "@block", "@css"]; + + var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_, + propertyKeywords_,nonStandardPropertyKeywords_, + colorKeywords_,valueKeywords_,fontProperties_, + wordOperatorKeywords_,blockKeywords_, + commonAtoms_,commonDef_); + + function wordRegexp(words) { + words = words.sort(function(a,b){return b > a;}); + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + function keySet(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) keys[array[i]] = true; + return keys; + } + + function escapeRegExp(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + } + + CodeMirror.registerHelper("hintWords", "stylus", hintWords); + CodeMirror.defineMIME("text/x-styl", "stylus"); +}); diff --git a/backend/webif/static/codemirror/mode/swift/index.html b/backend/webif/static/codemirror/mode/swift/index.html new file mode 100755 index 000000000..109f3fdb0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/swift/index.html @@ -0,0 +1,88 @@ + + +CodeMirror: Swift mode + + + + + + + + + + +
+

Swift mode

+
+ + + +

A simple mode for Swift

+ +

MIME types defined: text/x-swift (Swift code)

+
diff --git a/backend/webif/static/codemirror/mode/swift/swift.js b/backend/webif/static/codemirror/mode/swift/swift.js new file mode 100755 index 000000000..43ab7c8fb --- /dev/null +++ b/backend/webif/static/codemirror/mode/swift/swift.js @@ -0,0 +1,210 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Swift mode created by Michael Kaminsky https://github.com/mkaminsky11 + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") + mod(require("../../lib/codemirror")) + else if (typeof define == "function" && define.amd) + define(["../../lib/codemirror"], mod) + else + mod(CodeMirror) +})(function(CodeMirror) { + "use strict" + + function wordSet(words) { + var set = {} + for (var i = 0; i < words.length; i++) set[words[i]] = true + return set + } + + var keywords = wordSet(["_","var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype", + "open","public","internal","fileprivate","private","deinit","init","new","override","self","subscript","super", + "convenience","dynamic","final","indirect","lazy","required","static","unowned","unowned(safe)","unowned(unsafe)","weak","as","is", + "break","case","continue","default","else","fallthrough","for","guard","if","in","repeat","switch","where","while", + "defer","return","inout","mutating","nonmutating","catch","do","rethrows","throw","throws","try","didSet","get","set","willSet", + "assignment","associativity","infix","left","none","operator","postfix","precedence","precedencegroup","prefix","right", + "Any","AnyObject","Type","dynamicType","Self","Protocol","__COLUMN__","__FILE__","__FUNCTION__","__LINE__"]) + var definingKeywords = wordSet(["var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype","for"]) + var atoms = wordSet(["true","false","nil","self","super","_"]) + var types = wordSet(["Array","Bool","Character","Dictionary","Double","Float","Int","Int8","Int16","Int32","Int64","Never","Optional","Set","String", + "UInt8","UInt16","UInt32","UInt64","Void"]) + var operators = "+-/*%=|&<>~^?!" + var punc = ":;,.(){}[]" + var binary = /^\-?0b[01][01_]*/ + var octal = /^\-?0o[0-7][0-7_]*/ + var hexadecimal = /^\-?0x[\dA-Fa-f][\dA-Fa-f_]*(?:(?:\.[\dA-Fa-f][\dA-Fa-f_]*)?[Pp]\-?\d[\d_]*)?/ + var decimal = /^\-?\d[\d_]*(?:\.\d[\d_]*)?(?:[Ee]\-?\d[\d_]*)?/ + var identifier = /^\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1/ + var property = /^\.(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/ + var instruction = /^\#[A-Za-z]+/ + var attribute = /^@(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/ + //var regexp = /^\/(?!\s)(?:\/\/)?(?:\\.|[^\/])+\// + + function tokenBase(stream, state, prev) { + if (stream.sol()) state.indented = stream.indentation() + if (stream.eatSpace()) return null + + var ch = stream.peek() + if (ch == "/") { + if (stream.match("//")) { + stream.skipToEnd() + return "comment" + } + if (stream.match("/*")) { + state.tokenize.push(tokenComment) + return tokenComment(stream, state) + } + } + if (stream.match(instruction)) return "builtin" + if (stream.match(attribute)) return "attribute" + if (stream.match(binary)) return "number" + if (stream.match(octal)) return "number" + if (stream.match(hexadecimal)) return "number" + if (stream.match(decimal)) return "number" + if (stream.match(property)) return "property" + if (operators.indexOf(ch) > -1) { + stream.next() + return "operator" + } + if (punc.indexOf(ch) > -1) { + stream.next() + stream.match("..") + return "punctuation" + } + if (ch == '"' || ch == "'") { + stream.next() + var tokenize = tokenString(ch) + state.tokenize.push(tokenize) + return tokenize(stream, state) + } + + if (stream.match(identifier)) { + var ident = stream.current() + if (types.hasOwnProperty(ident)) return "variable-2" + if (atoms.hasOwnProperty(ident)) return "atom" + if (keywords.hasOwnProperty(ident)) { + if (definingKeywords.hasOwnProperty(ident)) + state.prev = "define" + return "keyword" + } + if (prev == "define") return "def" + return "variable" + } + + stream.next() + return null + } + + function tokenUntilClosingParen() { + var depth = 0 + return function(stream, state, prev) { + var inner = tokenBase(stream, state, prev) + if (inner == "punctuation") { + if (stream.current() == "(") ++depth + else if (stream.current() == ")") { + if (depth == 0) { + stream.backUp(1) + state.tokenize.pop() + return state.tokenize[state.tokenize.length - 1](stream, state) + } + else --depth + } + } + return inner + } + } + + function tokenString(quote) { + return function(stream, state) { + var ch, escaped = false + while (ch = stream.next()) { + if (escaped) { + if (ch == "(") { + state.tokenize.push(tokenUntilClosingParen()) + return "string" + } + escaped = false + } else if (ch == quote) { + break + } else { + escaped = ch == "\\" + } + } + state.tokenize.pop() + return "string" + } + } + + function tokenComment(stream, state) { + stream.match(/^(?:[^*]|\*(?!\/))*/) + if (stream.match("*/")) state.tokenize.pop() + return "comment" + } + + function Context(prev, align, indented) { + this.prev = prev + this.align = align + this.indented = indented + } + + function pushContext(state, stream) { + var align = stream.match(/^\s*($|\/[\/\*])/, false) ? null : stream.column() + 1 + state.context = new Context(state.context, align, state.indented) + } + + function popContext(state) { + if (state.context) { + state.indented = state.context.indented + state.context = state.context.prev + } + } + + CodeMirror.defineMode("swift", function(config) { + return { + startState: function() { + return { + prev: null, + context: null, + indented: 0, + tokenize: [] + } + }, + + token: function(stream, state) { + var prev = state.prev + state.prev = null + var tokenize = state.tokenize[state.tokenize.length - 1] || tokenBase + var style = tokenize(stream, state, prev) + if (!style || style == "comment") state.prev = prev + else if (!state.prev) state.prev = style + + if (style == "punctuation") { + var bracket = /[\(\[\{]|([\]\)\}])/.exec(stream.current()) + if (bracket) (bracket[1] ? popContext : pushContext)(state, stream) + } + + return style + }, + + indent: function(state, textAfter) { + var cx = state.context + if (!cx) return 0 + var closing = /^[\]\}\)]/.test(textAfter) + if (cx.align != null) return cx.align - (closing ? 1 : 0) + return cx.indented + (closing ? 0 : config.indentUnit) + }, + + electricInput: /^\s*[\)\}\]]$/, + + lineComment: "//", + blockCommentStart: "/*", + blockCommentEnd: "*/", + fold: "brace", + closeBrackets: "()[]{}''\"\"``" + } + }) + + CodeMirror.defineMIME("text/x-swift","swift") +}); diff --git a/backend/webif/static/codemirror/mode/swift/test.js b/backend/webif/static/codemirror/mode/swift/test.js new file mode 100755 index 000000000..786b89e29 --- /dev/null +++ b/backend/webif/static/codemirror/mode/swift/test.js @@ -0,0 +1,149 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "swift"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Ensure all number types are properly represented. + MT("numbers", + "[keyword var] [def a] [operator =] [number 17]", + "[keyword var] [def b] [operator =] [number -0.5]", + "[keyword var] [def c] [operator =] [number 0.3456e-4]", + "[keyword var] [def d] [operator =] [number 345e2]", + "[keyword var] [def e] [operator =] [number 0o7324]", + "[keyword var] [def f] [operator =] [number 0b10010]", + "[keyword var] [def g] [operator =] [number -0x35ade]", + "[keyword var] [def h] [operator =] [number 0xaea.ep-13]", + "[keyword var] [def i] [operator =] [number 0x13ep6]"); + + // Variable/class/etc definition. + MT("definition", + "[keyword var] [def a] [operator =] [number 5]", + "[keyword let] [def b][punctuation :] [variable-2 Int] [operator =] [number 10]", + "[keyword class] [def C] [punctuation {] [punctuation }]", + "[keyword struct] [def D] [punctuation {] [punctuation }]", + "[keyword enum] [def E] [punctuation {] [punctuation }]", + "[keyword extension] [def F] [punctuation {] [punctuation }]", + "[keyword protocol] [def G] [punctuation {] [punctuation }]", + "[keyword func] [def h][punctuation ()] [punctuation {] [punctuation }]", + "[keyword import] [def Foundation]", + "[keyword typealias] [def NewString] [operator =] [variable-2 String]", + "[keyword associatedtype] [def I]", + "[keyword for] [def j] [keyword in] [number 0][punctuation ..][operator <][number 3] [punctuation {] [punctuation }]"); + + // Strings and string interpolation. + MT("strings", + "[keyword var] [def a][punctuation :] [variable-2 String] [operator =] [string \"test\"]", + "[keyword var] [def b][punctuation :] [variable-2 String] [operator =] [string \"\\(][variable a][string )\"]"); + + // Comments. + MT("comments", + "[comment // This is a comment]", + "[comment /* This is another comment */]", + "[keyword var] [def a] [operator =] [number 5] [comment // Third comment]"); + + // Atoms. + MT("atoms", + "[keyword class] [def FooClass] [punctuation {]", + " [keyword let] [def fooBool][punctuation :] [variable-2 Bool][operator ?]", + " [keyword let] [def fooInt][punctuation :] [variable-2 Int][operator ?]", + " [keyword func] [keyword init][punctuation (][variable fooBool][punctuation :] [variable-2 Bool][punctuation ,] [variable barBool][punctuation :] [variable-2 Bool][punctuation )] [punctuation {]", + " [atom super][property .init][punctuation ()]", + " [atom self][property .fooBool] [operator =] [variable fooBool]", + " [variable fooInt] [operator =] [atom nil]", + " [keyword if] [variable barBool] [operator ==] [atom true] [punctuation {]", + " [variable print][punctuation (][string \"True!\"][punctuation )]", + " [punctuation }] [keyword else] [keyword if] [variable barBool] [operator ==] [atom false] [punctuation {]", + " [keyword for] [atom _] [keyword in] [number 0][punctuation ...][number 5] [punctuation {]", + " [variable print][punctuation (][string \"False!\"][punctuation )]", + " [punctuation }]", + " [punctuation }]", + " [punctuation }]", + "[punctuation }]"); + + // Types. + MT("types", + "[keyword var] [def a] [operator =] [variable-2 Array][operator <][variable-2 Int][operator >]", + "[keyword var] [def b] [operator =] [variable-2 Set][operator <][variable-2 Bool][operator >]", + "[keyword var] [def c] [operator =] [variable-2 Dictionary][operator <][variable-2 String][punctuation ,][variable-2 Character][operator >]", + "[keyword var] [def d][punctuation :] [variable-2 Int64][operator ?] [operator =] [variable-2 Optional][punctuation (][number 8][punctuation )]", + "[keyword func] [def e][punctuation ()] [operator ->] [variable-2 Void] [punctuation {]", + " [keyword var] [def e1][punctuation :] [variable-2 Float] [operator =] [number 1.2]", + "[punctuation }]", + "[keyword func] [def f][punctuation ()] [operator ->] [variable-2 Never] [punctuation {]", + " [keyword var] [def f1][punctuation :] [variable-2 Double] [operator =] [number 2.4]", + "[punctuation }]"); + + // Operators. + MT("operators", + "[keyword var] [def a] [operator =] [number 1] [operator +] [number 2]", + "[keyword var] [def b] [operator =] [number 1] [operator -] [number 2]", + "[keyword var] [def c] [operator =] [number 1] [operator *] [number 2]", + "[keyword var] [def d] [operator =] [number 1] [operator /] [number 2]", + "[keyword var] [def e] [operator =] [number 1] [operator %] [number 2]", + "[keyword var] [def f] [operator =] [number 1] [operator |] [number 2]", + "[keyword var] [def g] [operator =] [number 1] [operator &] [number 2]", + "[keyword var] [def h] [operator =] [number 1] [operator <<] [number 2]", + "[keyword var] [def i] [operator =] [number 1] [operator >>] [number 2]", + "[keyword var] [def j] [operator =] [number 1] [operator ^] [number 2]", + "[keyword var] [def k] [operator =] [operator ~][number 1]", + "[keyword var] [def l] [operator =] [variable foo] [operator ?] [number 1] [punctuation :] [number 2]", + "[keyword var] [def m][punctuation :] [variable-2 Int] [operator =] [variable-2 Optional][punctuation (][number 8][punctuation )][operator !]"); + + // Punctuation. + MT("punctuation", + "[keyword let] [def a] [operator =] [number 1][punctuation ;] [keyword let] [def b] [operator =] [number 2]", + "[keyword let] [def testArr][punctuation :] [punctuation [[][variable-2 Int][punctuation ]]] [operator =] [punctuation [[][variable a][punctuation ,] [variable b][punctuation ]]]", + "[keyword for] [def i] [keyword in] [number 0][punctuation ..][operator <][variable testArr][property .count] [punctuation {]", + " [variable print][punctuation (][variable testArr][punctuation [[][variable i][punctuation ]])]", + "[punctuation }]"); + + // Identifiers. + MT("identifiers", + "[keyword let] [def abc] [operator =] [number 1]", + "[keyword let] [def ABC] [operator =] [number 2]", + "[keyword let] [def _123] [operator =] [number 3]", + "[keyword let] [def _$1$2$3] [operator =] [number 4]", + "[keyword let] [def A1$_c32_$_] [operator =] [number 5]", + "[keyword let] [def `var`] [operator =] [punctuation [[][number 1][punctuation ,] [number 2][punctuation ,] [number 3][punctuation ]]]", + "[keyword let] [def square$] [operator =] [variable `var`][property .map] [punctuation {][variable $0] [operator *] [variable $0][punctuation }]", + "$$ [number 1][variable a] $[atom _] [variable _$] [variable __] `[variable a] [variable b]`"); + + // Properties. + MT("properties", + "[variable print][punctuation (][variable foo][property .abc][punctuation )]", + "[variable print][punctuation (][variable foo][property .ABC][punctuation )]", + "[variable print][punctuation (][variable foo][property ._123][punctuation )]", + "[variable print][punctuation (][variable foo][property ._$1$2$3][punctuation )]", + "[variable print][punctuation (][variable foo][property .A1$_c32_$_][punctuation )]", + "[variable print][punctuation (][variable foo][property .`var`][punctuation )]", + "[variable print][punctuation (][variable foo][property .__][punctuation )]"); + + // Instructions or other things that start with #. + MT("instructions", + "[keyword if] [builtin #available][punctuation (][variable iOS] [number 9][punctuation ,] [operator *][punctuation )] [punctuation {}]", + "[variable print][punctuation (][builtin #file][punctuation ,] [builtin #function][punctuation )]", + "[variable print][punctuation (][builtin #line][punctuation ,] [builtin #column][punctuation )]", + "[builtin #if] [atom true]", + "[keyword import] [def A]", + "[builtin #elseif] [atom false]", + "[keyword import] [def B]", + "[builtin #endif]", + "[builtin #sourceLocation][punctuation (][variable file][punctuation :] [string \"file.swift\"][punctuation ,] [variable line][punctuation :] [number 2][punctuation )]"); + + // Attributes; things that start with @. + MT("attributes", + "[attribute @objc][punctuation (][variable objcFoo][punctuation :)]", + "[attribute @available][punctuation (][variable iOS][punctuation )]"); + + // Property/number edge case. + MT("property_number", + "[variable print][punctuation (][variable foo][property ._123][punctuation )]", + "[variable print][punctuation (]") + + // TODO: correctly identify when multiple variables are being declared + // by use of a comma-separated list. + // TODO: correctly identify when variables are being declared in a tuple. + // TODO: identify protocols as types when used before an extension? +})(); diff --git a/backend/webif/static/codemirror/mode/tcl/index.html b/backend/webif/static/codemirror/mode/tcl/index.html new file mode 100755 index 000000000..ce4ad3423 --- /dev/null +++ b/backend/webif/static/codemirror/mode/tcl/index.html @@ -0,0 +1,142 @@ + + +CodeMirror: Tcl mode + + + + + + + + + + +
+

Tcl mode

+
+ + +

MIME types defined: text/x-tcl.

+ +
diff --git a/backend/webif/static/codemirror/mode/tcl/tcl.js b/backend/webif/static/codemirror/mode/tcl/tcl.js new file mode 100755 index 000000000..8c76d52ca --- /dev/null +++ b/backend/webif/static/codemirror/mode/tcl/tcl.js @@ -0,0 +1,139 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +//tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("tcl", function() { + function parseWords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " + + "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " + + "binary break catch cd close concat continue dde eof encoding error " + + "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " + + "filename flush for foreach format gets glob global history http if " + + "incr info interp join lappend lindex linsert list llength load lrange " + + "lreplace lsearch lset lsort memory msgcat namespace open package parray " + + "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " + + "registry regsub rename resource return scan seek set socket source split " + + "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " + + "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " + + "tclvars tell time trace unknown unset update uplevel upvar variable " + + "vwait"); + var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch"); + var isOperatorChar = /[+\-*&%=<>!?^\/\|]/; + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + function tokenBase(stream, state) { + var beforeParams = state.beforeParams; + state.beforeParams = false; + var ch = stream.next(); + if ((ch == '"' || ch == "'") && state.inParams) { + return chain(stream, state, tokenString(ch)); + } else if (/[\[\]{}\(\),;\.]/.test(ch)) { + if (ch == "(" && beforeParams) state.inParams = true; + else if (ch == ")") state.inParams = false; + return null; + } else if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } else if (ch == "#") { + if (stream.eat("*")) + return chain(stream, state, tokenComment); + if (ch == "#" && stream.match(/ *\[ *\[/)) + return chain(stream, state, tokenUnparsed); + stream.skipToEnd(); + return "comment"; + } else if (ch == '"') { + stream.skipTo(/"/); + return "comment"; + } else if (ch == "$") { + stream.eatWhile(/[$_a-z0-9A-Z\.{:]/); + stream.eatWhile(/}/); + state.beforeParams = true; + return "builtin"; + } else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "comment"; + } else { + stream.eatWhile(/[\w\$_{}\xa1-\uffff]/); + var word = stream.current().toLowerCase(); + if (keywords && keywords.propertyIsEnumerable(word)) + return "keyword"; + if (functions && functions.propertyIsEnumerable(word)) { + state.beforeParams = true; + return "keyword"; + } + return null; + } + } + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end) state.tokenize = tokenBase; + return "string"; + }; + } + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "#" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + function tokenUnparsed(stream, state) { + var maybeEnd = 0, ch; + while (ch = stream.next()) { + if (ch == "#" && maybeEnd == 2) { + state.tokenize = tokenBase; + break; + } + if (ch == "]") + maybeEnd++; + else if (ch != " ") + maybeEnd = 0; + } + return "meta"; + } + return { + startState: function() { + return { + tokenize: tokenBase, + beforeParams: false, + inParams: false + }; + }, + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + } + }; +}); +CodeMirror.defineMIME("text/x-tcl", "tcl"); + +}); diff --git a/backend/webif/static/codemirror/mode/textile/index.html b/backend/webif/static/codemirror/mode/textile/index.html new file mode 100755 index 000000000..42b156b1e --- /dev/null +++ b/backend/webif/static/codemirror/mode/textile/index.html @@ -0,0 +1,191 @@ + + +CodeMirror: Textile mode + + + + + + + + + +
+

Textile mode

+
+ + +

MIME types defined: text/x-textile.

+ +

Parsing/Highlighting Tests: normal, verbose.

+ +
diff --git a/backend/webif/static/codemirror/mode/textile/test.js b/backend/webif/static/codemirror/mode/textile/test.js new file mode 100755 index 000000000..49cdaf9c9 --- /dev/null +++ b/backend/webif/static/codemirror/mode/textile/test.js @@ -0,0 +1,417 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({tabSize: 4}, 'textile'); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT('simpleParagraphs', + 'Some text.', + '', + 'Some more text.'); + + /* + * Phrase Modifiers + */ + + MT('em', + 'foo [em _bar_]'); + + MT('emBoogus', + 'code_mirror'); + + MT('strong', + 'foo [strong *bar*]'); + + MT('strongBogus', + '3 * 3 = 9'); + + MT('italic', + 'foo [em __bar__]'); + + MT('italicBogus', + 'code__mirror'); + + MT('bold', + 'foo [strong **bar**]'); + + MT('boldBogus', + '3 ** 3 = 27'); + + MT('simpleLink', + '[link "CodeMirror":http://codemirror.net]'); + + MT('referenceLink', + '[link "CodeMirror":code_mirror]', + 'Normal Text.', + '[link [[code_mirror]]http://codemirror.net]'); + + MT('footCite', + 'foo bar[qualifier [[1]]]'); + + MT('footCiteBogus', + 'foo bar[[1a2]]'); + + MT('special-characters', + 'Registered [tag (r)], ' + + 'Trademark [tag (tm)], and ' + + 'Copyright [tag (c)] 2008'); + + MT('cite', + "A book is [keyword ??The Count of Monte Cristo??] by Dumas."); + + MT('additionAndDeletion', + 'The news networks declared [negative -Al Gore-] ' + + '[positive +George W. Bush+] the winner in Florida.'); + + MT('subAndSup', + 'f(x, n) = log [builtin ~4~] x [builtin ^n^]'); + + MT('spanAndCode', + 'A [quote %span element%] and [atom @code element@]'); + + MT('spanBogus', + 'Percentage 25% is not a span.'); + + MT('citeBogus', + 'Question? is not a citation.'); + + MT('codeBogus', + 'user@example.com'); + + MT('subBogus', + '~username'); + + MT('supBogus', + 'foo ^ bar'); + + MT('deletionBogus', + '3 - 3 = 0'); + + MT('additionBogus', + '3 + 3 = 6'); + + MT('image', + 'An image: [string !http://www.example.com/image.png!]'); + + MT('imageWithAltText', + 'An image: [string !http://www.example.com/image.png (Alt Text)!]'); + + MT('imageWithUrl', + 'An image: [string !http://www.example.com/image.png!:http://www.example.com/]'); + + /* + * Headers + */ + + MT('h1', + '[header&header-1 h1. foo]'); + + MT('h2', + '[header&header-2 h2. foo]'); + + MT('h3', + '[header&header-3 h3. foo]'); + + MT('h4', + '[header&header-4 h4. foo]'); + + MT('h5', + '[header&header-5 h5. foo]'); + + MT('h6', + '[header&header-6 h6. foo]'); + + MT('h7Bogus', + 'h7. foo'); + + MT('multipleHeaders', + '[header&header-1 h1. Heading 1]', + '', + 'Some text.', + '', + '[header&header-2 h2. Heading 2]', + '', + 'More text.'); + + MT('h1inline', + '[header&header-1 h1. foo ][header&header-1&em _bar_][header&header-1 baz]'); + + /* + * Lists + */ + + MT('ul', + 'foo', + 'bar', + '', + '[variable-2 * foo]', + '[variable-2 * bar]'); + + MT('ulNoBlank', + 'foo', + 'bar', + '[variable-2 * foo]', + '[variable-2 * bar]'); + + MT('ol', + 'foo', + 'bar', + '', + '[variable-2 # foo]', + '[variable-2 # bar]'); + + MT('olNoBlank', + 'foo', + 'bar', + '[variable-2 # foo]', + '[variable-2 # bar]'); + + MT('ulFormatting', + '[variable-2 * ][variable-2&em _foo_][variable-2 bar]', + '[variable-2 * ][variable-2&strong *][variable-2&em&strong _foo_]' + + '[variable-2&strong *][variable-2 bar]', + '[variable-2 * ][variable-2&strong *foo*][variable-2 bar]'); + + MT('olFormatting', + '[variable-2 # ][variable-2&em _foo_][variable-2 bar]', + '[variable-2 # ][variable-2&strong *][variable-2&em&strong _foo_]' + + '[variable-2&strong *][variable-2 bar]', + '[variable-2 # ][variable-2&strong *foo*][variable-2 bar]'); + + MT('ulNested', + '[variable-2 * foo]', + '[variable-3 ** bar]', + '[keyword *** bar]', + '[variable-2 **** bar]', + '[variable-3 ** bar]'); + + MT('olNested', + '[variable-2 # foo]', + '[variable-3 ## bar]', + '[keyword ### bar]', + '[variable-2 #### bar]', + '[variable-3 ## bar]'); + + MT('ulNestedWithOl', + '[variable-2 * foo]', + '[variable-3 ## bar]', + '[keyword *** bar]', + '[variable-2 #### bar]', + '[variable-3 ** bar]'); + + MT('olNestedWithUl', + '[variable-2 # foo]', + '[variable-3 ** bar]', + '[keyword ### bar]', + '[variable-2 **** bar]', + '[variable-3 ## bar]'); + + MT('definitionList', + '[number - coffee := Hot ][number&em _and_][number black]', + '', + 'Normal text.'); + + MT('definitionListSpan', + '[number - coffee :=]', + '', + '[number Hot ][number&em _and_][number black =:]', + '', + 'Normal text.'); + + MT('boo', + '[number - dog := woof woof]', + '[number - cat := meow meow]', + '[number - whale :=]', + '[number Whale noises.]', + '', + '[number Also, ][number&em _splashing_][number . =:]'); + + /* + * Attributes + */ + + MT('divWithAttribute', + '[punctuation div][punctuation&attribute (#my-id)][punctuation . foo bar]'); + + MT('divWithAttributeAnd2emRightPadding', + '[punctuation div][punctuation&attribute (#my-id)((][punctuation . foo bar]'); + + MT('divWithClassAndId', + '[punctuation div][punctuation&attribute (my-class#my-id)][punctuation . foo bar]'); + + MT('paragraphWithCss', + 'p[attribute {color:red;}]. foo bar'); + + MT('paragraphNestedStyles', + 'p. [strong *foo ][strong&em _bar_][strong *]'); + + MT('paragraphWithLanguage', + 'p[attribute [[fr]]]. Parlez-vous français?'); + + MT('paragraphLeftAlign', + 'p[attribute <]. Left'); + + MT('paragraphRightAlign', + 'p[attribute >]. Right'); + + MT('paragraphRightAlign', + 'p[attribute =]. Center'); + + MT('paragraphJustified', + 'p[attribute <>]. Justified'); + + MT('paragraphWithLeftIndent1em', + 'p[attribute (]. Left'); + + MT('paragraphWithRightIndent1em', + 'p[attribute )]. Right'); + + MT('paragraphWithLeftIndent2em', + 'p[attribute ((]. Left'); + + MT('paragraphWithRightIndent2em', + 'p[attribute ))]. Right'); + + MT('paragraphWithLeftIndent3emRightIndent2em', + 'p[attribute ((())]. Right'); + + MT('divFormatting', + '[punctuation div. ][punctuation&strong *foo ]' + + '[punctuation&strong&em _bar_][punctuation&strong *]'); + + MT('phraseModifierAttributes', + 'p[attribute (my-class)]. This is a paragraph that has a class and' + + ' this [em _][em&attribute (#special-phrase)][em emphasized phrase_]' + + ' has an id.'); + + MT('linkWithClass', + '[link "(my-class). This is a link with class":http://redcloth.org]'); + + /* + * Layouts + */ + + MT('paragraphLayouts', + 'p. This is one paragraph.', + '', + 'p. This is another.'); + + MT('div', + '[punctuation div. foo bar]'); + + MT('pre', + '[operator pre. Text]'); + + MT('bq.', + '[bracket bq. foo bar]', + '', + 'Normal text.'); + + MT('footnote', + '[variable fn123. foo ][variable&strong *bar*]'); + + /* + * Spanning Layouts + */ + + MT('bq..ThenParagraph', + '[bracket bq.. foo bar]', + '', + '[bracket More quote.]', + 'p. Normal Text'); + + MT('bq..ThenH1', + '[bracket bq.. foo bar]', + '', + '[bracket More quote.]', + '[header&header-1 h1. Header Text]'); + + MT('bc..ThenParagraph', + '[atom bc.. # Some ruby code]', + '[atom obj = {foo: :bar}]', + '[atom puts obj]', + '', + '[atom obj[[:love]] = "*love*"]', + '[atom puts obj.love.upcase]', + '', + 'p. Normal text.'); + + MT('fn1..ThenParagraph', + '[variable fn1.. foo bar]', + '', + '[variable More.]', + 'p. Normal Text'); + + MT('pre..ThenParagraph', + '[operator pre.. foo bar]', + '', + '[operator More.]', + 'p. Normal Text'); + + /* + * Tables + */ + + MT('table', + '[variable-3&operator |_. name |_. age|]', + '[variable-3 |][variable-3&strong *Walter*][variable-3 | 5 |]', + '[variable-3 |Florence| 6 |]', + '', + 'p. Normal text.'); + + MT('tableWithAttributes', + '[variable-3&operator |_. name |_. age|]', + '[variable-3 |][variable-3&attribute /2.][variable-3 Jim |]', + '[variable-3 |][variable-3&attribute \\2{color: red}.][variable-3 Sam |]'); + + /* + * HTML + */ + + MT('html', + '[comment
]', + '[comment
]', + '', + '[header&header-1 h1. Welcome]', + '', + '[variable-2 * Item one]', + '[variable-2 * Item two]', + '', + '[comment Example]', + '', + '[comment
]', + '[comment
]'); + + MT('inlineHtml', + 'I can use HTML directly in my [comment Textile].'); + + /* + * No-Textile + */ + + MT('notextile', + '[string-2 notextile. *No* formatting]'); + + MT('notextileInline', + 'Use [string-2 ==*asterisks*==] for [strong *strong*] text.'); + + MT('notextileWithPre', + '[operator pre. *No* formatting]'); + + MT('notextileWithSpanningPre', + '[operator pre.. *No* formatting]', + '', + '[operator *No* formatting]'); + + /* Only toggling phrases between non-word chars. */ + + MT('phrase-in-word', + 'foo_bar_baz'); + + MT('phrase-non-word', + '[negative -x-] aaa-bbb ccc-ddd [negative -eee-] fff [negative -ggg-]'); + + MT('phrase-lone-dash', + 'foo - bar - baz'); +})(); diff --git a/backend/webif/static/codemirror/mode/textile/textile.js b/backend/webif/static/codemirror/mode/textile/textile.js new file mode 100755 index 000000000..bc5a2f369 --- /dev/null +++ b/backend/webif/static/codemirror/mode/textile/textile.js @@ -0,0 +1,469 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") { // CommonJS + mod(require("../../lib/codemirror")); + } else if (typeof define == "function" && define.amd) { // AMD + define(["../../lib/codemirror"], mod); + } else { // Plain browser env + mod(CodeMirror); + } +})(function(CodeMirror) { + "use strict"; + + var TOKEN_STYLES = { + addition: "positive", + attributes: "attribute", + bold: "strong", + cite: "keyword", + code: "atom", + definitionList: "number", + deletion: "negative", + div: "punctuation", + em: "em", + footnote: "variable", + footCite: "qualifier", + header: "header", + html: "comment", + image: "string", + italic: "em", + link: "link", + linkDefinition: "link", + list1: "variable-2", + list2: "variable-3", + list3: "keyword", + notextile: "string-2", + pre: "operator", + p: "property", + quote: "bracket", + span: "quote", + specialChar: "tag", + strong: "strong", + sub: "builtin", + sup: "builtin", + table: "variable-3", + tableHeading: "operator" + }; + + function startNewLine(stream, state) { + state.mode = Modes.newLayout; + state.tableHeading = false; + + if (state.layoutType === "definitionList" && state.spanningLayout && + stream.match(RE("definitionListEnd"), false)) + state.spanningLayout = false; + } + + function handlePhraseModifier(stream, state, ch) { + if (ch === "_") { + if (stream.eat("_")) + return togglePhraseModifier(stream, state, "italic", /__/, 2); + else + return togglePhraseModifier(stream, state, "em", /_/, 1); + } + + if (ch === "*") { + if (stream.eat("*")) { + return togglePhraseModifier(stream, state, "bold", /\*\*/, 2); + } + return togglePhraseModifier(stream, state, "strong", /\*/, 1); + } + + if (ch === "[") { + if (stream.match(/\d+\]/)) state.footCite = true; + return tokenStyles(state); + } + + if (ch === "(") { + var spec = stream.match(/^(r|tm|c)\)/); + if (spec) + return tokenStylesWith(state, TOKEN_STYLES.specialChar); + } + + if (ch === "<" && stream.match(/(\w+)[^>]+>[^<]+<\/\1>/)) + return tokenStylesWith(state, TOKEN_STYLES.html); + + if (ch === "?" && stream.eat("?")) + return togglePhraseModifier(stream, state, "cite", /\?\?/, 2); + + if (ch === "=" && stream.eat("=")) + return togglePhraseModifier(stream, state, "notextile", /==/, 2); + + if (ch === "-" && !stream.eat("-")) + return togglePhraseModifier(stream, state, "deletion", /-/, 1); + + if (ch === "+") + return togglePhraseModifier(stream, state, "addition", /\+/, 1); + + if (ch === "~") + return togglePhraseModifier(stream, state, "sub", /~/, 1); + + if (ch === "^") + return togglePhraseModifier(stream, state, "sup", /\^/, 1); + + if (ch === "%") + return togglePhraseModifier(stream, state, "span", /%/, 1); + + if (ch === "@") + return togglePhraseModifier(stream, state, "code", /@/, 1); + + if (ch === "!") { + var type = togglePhraseModifier(stream, state, "image", /(?:\([^\)]+\))?!/, 1); + stream.match(/^:\S+/); // optional Url portion + return type; + } + return tokenStyles(state); + } + + function togglePhraseModifier(stream, state, phraseModifier, closeRE, openSize) { + var charBefore = stream.pos > openSize ? stream.string.charAt(stream.pos - openSize - 1) : null; + var charAfter = stream.peek(); + if (state[phraseModifier]) { + if ((!charAfter || /\W/.test(charAfter)) && charBefore && /\S/.test(charBefore)) { + var type = tokenStyles(state); + state[phraseModifier] = false; + return type; + } + } else if ((!charBefore || /\W/.test(charBefore)) && charAfter && /\S/.test(charAfter) && + stream.match(new RegExp("^.*\\S" + closeRE.source + "(?:\\W|$)"), false)) { + state[phraseModifier] = true; + state.mode = Modes.attributes; + } + return tokenStyles(state); + }; + + function tokenStyles(state) { + var disabled = textileDisabled(state); + if (disabled) return disabled; + + var styles = []; + if (state.layoutType) styles.push(TOKEN_STYLES[state.layoutType]); + + styles = styles.concat(activeStyles( + state, "addition", "bold", "cite", "code", "deletion", "em", "footCite", + "image", "italic", "link", "span", "strong", "sub", "sup", "table", "tableHeading")); + + if (state.layoutType === "header") + styles.push(TOKEN_STYLES.header + "-" + state.header); + + return styles.length ? styles.join(" ") : null; + } + + function textileDisabled(state) { + var type = state.layoutType; + + switch(type) { + case "notextile": + case "code": + case "pre": + return TOKEN_STYLES[type]; + default: + if (state.notextile) + return TOKEN_STYLES.notextile + (type ? (" " + TOKEN_STYLES[type]) : ""); + return null; + } + } + + function tokenStylesWith(state, extraStyles) { + var disabled = textileDisabled(state); + if (disabled) return disabled; + + var type = tokenStyles(state); + if (extraStyles) + return type ? (type + " " + extraStyles) : extraStyles; + else + return type; + } + + function activeStyles(state) { + var styles = []; + for (var i = 1; i < arguments.length; ++i) { + if (state[arguments[i]]) + styles.push(TOKEN_STYLES[arguments[i]]); + } + return styles; + } + + function blankLine(state) { + var spanningLayout = state.spanningLayout, type = state.layoutType; + + for (var key in state) if (state.hasOwnProperty(key)) + delete state[key]; + + state.mode = Modes.newLayout; + if (spanningLayout) { + state.layoutType = type; + state.spanningLayout = true; + } + } + + var REs = { + cache: {}, + single: { + bc: "bc", + bq: "bq", + definitionList: /- .*?:=+/, + definitionListEnd: /.*=:\s*$/, + div: "div", + drawTable: /\|.*\|/, + foot: /fn\d+/, + header: /h[1-6]/, + html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/, + link: /[^"]+":\S/, + linkDefinition: /\[[^\s\]]+\]\S+/, + list: /(?:#+|\*+)/, + notextile: "notextile", + para: "p", + pre: "pre", + table: "table", + tableCellAttributes: /[\/\\]\d+/, + tableHeading: /\|_\./, + tableText: /[^"_\*\[\(\?\+~\^%@|-]+/, + text: /[^!"_=\*\[\(<\?\+~\^%@-]+/ + }, + attributes: { + align: /(?:<>|<|>|=)/, + selector: /\([^\(][^\)]+\)/, + lang: /\[[^\[\]]+\]/, + pad: /(?:\(+|\)+){1,2}/, + css: /\{[^\}]+\}/ + }, + createRe: function(name) { + switch (name) { + case "drawTable": + return REs.makeRe("^", REs.single.drawTable, "$"); + case "html": + return REs.makeRe("^", REs.single.html, "(?:", REs.single.html, ")*", "$"); + case "linkDefinition": + return REs.makeRe("^", REs.single.linkDefinition, "$"); + case "listLayout": + return REs.makeRe("^", REs.single.list, RE("allAttributes"), "*\\s+"); + case "tableCellAttributes": + return REs.makeRe("^", REs.choiceRe(REs.single.tableCellAttributes, + RE("allAttributes")), "+\\."); + case "type": + return REs.makeRe("^", RE("allTypes")); + case "typeLayout": + return REs.makeRe("^", RE("allTypes"), RE("allAttributes"), + "*\\.\\.?", "(\\s+|$)"); + case "attributes": + return REs.makeRe("^", RE("allAttributes"), "+"); + + case "allTypes": + return REs.choiceRe(REs.single.div, REs.single.foot, + REs.single.header, REs.single.bc, REs.single.bq, + REs.single.notextile, REs.single.pre, REs.single.table, + REs.single.para); + + case "allAttributes": + return REs.choiceRe(REs.attributes.selector, REs.attributes.css, + REs.attributes.lang, REs.attributes.align, REs.attributes.pad); + + default: + return REs.makeRe("^", REs.single[name]); + } + }, + makeRe: function() { + var pattern = ""; + for (var i = 0; i < arguments.length; ++i) { + var arg = arguments[i]; + pattern += (typeof arg === "string") ? arg : arg.source; + } + return new RegExp(pattern); + }, + choiceRe: function() { + var parts = [arguments[0]]; + for (var i = 1; i < arguments.length; ++i) { + parts[i * 2 - 1] = "|"; + parts[i * 2] = arguments[i]; + } + + parts.unshift("(?:"); + parts.push(")"); + return REs.makeRe.apply(null, parts); + } + }; + + function RE(name) { + return (REs.cache[name] || (REs.cache[name] = REs.createRe(name))); + } + + var Modes = { + newLayout: function(stream, state) { + if (stream.match(RE("typeLayout"), false)) { + state.spanningLayout = false; + return (state.mode = Modes.blockType)(stream, state); + } + var newMode; + if (!textileDisabled(state)) { + if (stream.match(RE("listLayout"), false)) + newMode = Modes.list; + else if (stream.match(RE("drawTable"), false)) + newMode = Modes.table; + else if (stream.match(RE("linkDefinition"), false)) + newMode = Modes.linkDefinition; + else if (stream.match(RE("definitionList"))) + newMode = Modes.definitionList; + else if (stream.match(RE("html"), false)) + newMode = Modes.html; + } + return (state.mode = (newMode || Modes.text))(stream, state); + }, + + blockType: function(stream, state) { + var match, type; + state.layoutType = null; + + if (match = stream.match(RE("type"))) + type = match[0]; + else + return (state.mode = Modes.text)(stream, state); + + if (match = type.match(RE("header"))) { + state.layoutType = "header"; + state.header = parseInt(match[0][1]); + } else if (type.match(RE("bq"))) { + state.layoutType = "quote"; + } else if (type.match(RE("bc"))) { + state.layoutType = "code"; + } else if (type.match(RE("foot"))) { + state.layoutType = "footnote"; + } else if (type.match(RE("notextile"))) { + state.layoutType = "notextile"; + } else if (type.match(RE("pre"))) { + state.layoutType = "pre"; + } else if (type.match(RE("div"))) { + state.layoutType = "div"; + } else if (type.match(RE("table"))) { + state.layoutType = "table"; + } + + state.mode = Modes.attributes; + return tokenStyles(state); + }, + + text: function(stream, state) { + if (stream.match(RE("text"))) return tokenStyles(state); + + var ch = stream.next(); + if (ch === '"') + return (state.mode = Modes.link)(stream, state); + return handlePhraseModifier(stream, state, ch); + }, + + attributes: function(stream, state) { + state.mode = Modes.layoutLength; + + if (stream.match(RE("attributes"))) + return tokenStylesWith(state, TOKEN_STYLES.attributes); + else + return tokenStyles(state); + }, + + layoutLength: function(stream, state) { + if (stream.eat(".") && stream.eat(".")) + state.spanningLayout = true; + + state.mode = Modes.text; + return tokenStyles(state); + }, + + list: function(stream, state) { + var match = stream.match(RE("list")); + state.listDepth = match[0].length; + var listMod = (state.listDepth - 1) % 3; + if (!listMod) + state.layoutType = "list1"; + else if (listMod === 1) + state.layoutType = "list2"; + else + state.layoutType = "list3"; + + state.mode = Modes.attributes; + return tokenStyles(state); + }, + + link: function(stream, state) { + state.mode = Modes.text; + if (stream.match(RE("link"))) { + stream.match(/\S+/); + return tokenStylesWith(state, TOKEN_STYLES.link); + } + return tokenStyles(state); + }, + + linkDefinition: function(stream, state) { + stream.skipToEnd(); + return tokenStylesWith(state, TOKEN_STYLES.linkDefinition); + }, + + definitionList: function(stream, state) { + stream.match(RE("definitionList")); + + state.layoutType = "definitionList"; + + if (stream.match(/\s*$/)) + state.spanningLayout = true; + else + state.mode = Modes.attributes; + + return tokenStyles(state); + }, + + html: function(stream, state) { + stream.skipToEnd(); + return tokenStylesWith(state, TOKEN_STYLES.html); + }, + + table: function(stream, state) { + state.layoutType = "table"; + return (state.mode = Modes.tableCell)(stream, state); + }, + + tableCell: function(stream, state) { + if (stream.match(RE("tableHeading"))) + state.tableHeading = true; + else + stream.eat("|"); + + state.mode = Modes.tableCellAttributes; + return tokenStyles(state); + }, + + tableCellAttributes: function(stream, state) { + state.mode = Modes.tableText; + + if (stream.match(RE("tableCellAttributes"))) + return tokenStylesWith(state, TOKEN_STYLES.attributes); + else + return tokenStyles(state); + }, + + tableText: function(stream, state) { + if (stream.match(RE("tableText"))) + return tokenStyles(state); + + if (stream.peek() === "|") { // end of cell + state.mode = Modes.tableCell; + return tokenStyles(state); + } + return handlePhraseModifier(stream, state, stream.next()); + } + }; + + CodeMirror.defineMode("textile", function() { + return { + startState: function() { + return { mode: Modes.newLayout }; + }, + token: function(stream, state) { + if (stream.sol()) startNewLine(stream, state); + return state.mode(stream, state); + }, + blankLine: blankLine + }; + }); + + CodeMirror.defineMIME("text/x-textile", "textile"); +}); diff --git a/backend/webif/static/codemirror/mode/tiddlywiki/index.html b/backend/webif/static/codemirror/mode/tiddlywiki/index.html new file mode 100755 index 000000000..77dd0457c --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiddlywiki/index.html @@ -0,0 +1,154 @@ + + +CodeMirror: TiddlyWiki mode + + + + + + + + + + + +
+

TiddlyWiki mode

+ + +
+ + + +

TiddlyWiki mode supports a single configuration.

+ +

MIME types defined: text/x-tiddlywiki.

+
diff --git a/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.css b/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.css new file mode 100755 index 000000000..9a69b639f --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.css @@ -0,0 +1,14 @@ +span.cm-underlined { + text-decoration: underline; +} +span.cm-strikethrough { + text-decoration: line-through; +} +span.cm-brace { + color: #170; + font-weight: bold; +} +span.cm-table { + color: blue; + font-weight: bold; +} diff --git a/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.js b/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.js new file mode 100755 index 000000000..1a3b3bc68 --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiddlywiki/tiddlywiki.js @@ -0,0 +1,308 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/*** + |''Name''|tiddlywiki.js| + |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror| + |''Author''|PMario| + |''Version''|0.1.7| + |''Status''|''stable''| + |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]| + |''Documentation''|http://codemirror.tiddlyspace.com/| + |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]| + |''CoreVersion''|2.5.0| + |''Requires''|codemirror.js| + |''Keywords''|syntax highlighting color code mirror codemirror| + ! Info + CoreVersion parameter is needed for TiddlyWiki only! +***/ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("tiddlywiki", function () { + // Tokenizer + var textwords = {}; + + var keywords = { + "allTags": true, "closeAll": true, "list": true, + "newJournal": true, "newTiddler": true, + "permaview": true, "saveChanges": true, + "search": true, "slider": true, "tabs": true, + "tag": true, "tagging": true, "tags": true, + "tiddler": true, "timeline": true, + "today": true, "version": true, "option": true, + "with": true, "filter": true + }; + + var isSpaceName = /[\w_\-]/i, + reHR = /^\-\-\-\-+$/, //
+ reWikiCommentStart = /^\/\*\*\*$/, // /*** + reWikiCommentStop = /^\*\*\*\/$/, // ***/ + reBlockQuote = /^<<<$/, + + reJsCodeStart = /^\/\/\{\{\{$/, // //{{{ js block start + reJsCodeStop = /^\/\/\}\}\}$/, // //}}} js stop + reXmlCodeStart = /^$/, // xml block start + reXmlCodeStop = /^$/, // xml stop + + reCodeBlockStart = /^\{\{\{$/, // {{{ TW text div block start + reCodeBlockStop = /^\}\}\}$/, // }}} TW text stop + + reUntilCodeStop = /.*?\}\}\}/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function tokenBase(stream, state) { + var sol = stream.sol(), ch = stream.peek(); + + state.block = false; // indicates the start of a code block. + + // check start of blocks + if (sol && /[<\/\*{}\-]/.test(ch)) { + if (stream.match(reCodeBlockStart)) { + state.block = true; + return chain(stream, state, twTokenCode); + } + if (stream.match(reBlockQuote)) + return 'quote'; + if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) + return 'comment'; + if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) + return 'comment'; + if (stream.match(reHR)) + return 'hr'; + } + + stream.next(); + if (sol && /[\/\*!#;:>|]/.test(ch)) { + if (ch == "!") { // tw header + stream.skipToEnd(); + return "header"; + } + if (ch == "*") { // tw list + stream.eatWhile('*'); + return "comment"; + } + if (ch == "#") { // tw numbered list + stream.eatWhile('#'); + return "comment"; + } + if (ch == ";") { // definition list, term + stream.eatWhile(';'); + return "comment"; + } + if (ch == ":") { // definition list, description + stream.eatWhile(':'); + return "comment"; + } + if (ch == ">") { // single line quote + stream.eatWhile(">"); + return "quote"; + } + if (ch == '|') + return 'header'; + } + + if (ch == '{' && stream.match(/\{\{/)) + return chain(stream, state, twTokenCode); + + // rudimentary html:// file:// link matching. TW knows much more ... + if (/[hf]/i.test(ch) && + /[ti]/i.test(stream.peek()) && + stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) + return "link"; + + // just a little string indicator, don't want to have the whole string covered + if (ch == '"') + return 'string'; + + if (ch == '~') // _no_ CamelCase indicator should be bold + return 'brace'; + + if (/[\[\]]/.test(ch) && stream.match(ch)) // check for [[..]] + return 'brace'; + + if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting + stream.eatWhile(isSpaceName); + return "link"; + } + + if (/\d/.test(ch)) { // numbers + stream.eatWhile(/\d/); + return "number"; + } + + if (ch == "/") { // tw invisible comment + if (stream.eat("%")) { + return chain(stream, state, twTokenComment); + } else if (stream.eat("/")) { // + return chain(stream, state, twTokenEm); + } + } + + if (ch == "_" && stream.eat("_")) // tw underline + return chain(stream, state, twTokenUnderline); + + // strikethrough and mdash handling + if (ch == "-" && stream.eat("-")) { + // if strikethrough looks ugly, change CSS. + if (stream.peek() != ' ') + return chain(stream, state, twTokenStrike); + // mdash + if (stream.peek() == ' ') + return 'brace'; + } + + if (ch == "'" && stream.eat("'")) // tw bold + return chain(stream, state, twTokenStrong); + + if (ch == "<" && stream.eat("<")) // tw macro + return chain(stream, state, twTokenMacro); + + // core macro handling + stream.eatWhile(/[\w\$_]/); + return textwords.propertyIsEnumerable(stream.current()) ? "keyword" : null + } + + // tw invisible comment + function twTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "%"); + } + return "comment"; + } + + // tw strong / bold + function twTokenStrong(stream, state) { + var maybeEnd = false, + ch; + while (ch = stream.next()) { + if (ch == "'" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "'"); + } + return "strong"; + } + + // tw code + function twTokenCode(stream, state) { + var sb = state.block; + + if (sb && stream.current()) { + return "comment"; + } + + if (!sb && stream.match(reUntilCodeStop)) { + state.tokenize = tokenBase; + return "comment"; + } + + if (sb && stream.sol() && stream.match(reCodeBlockStop)) { + state.tokenize = tokenBase; + return "comment"; + } + + stream.next(); + return "comment"; + } + + // tw em / italic + function twTokenEm(stream, state) { + var maybeEnd = false, + ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "/"); + } + return "em"; + } + + // tw underlined text + function twTokenUnderline(stream, state) { + var maybeEnd = false, + ch; + while (ch = stream.next()) { + if (ch == "_" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "_"); + } + return "underlined"; + } + + // tw strike through text looks ugly + // change CSS if needed + function twTokenStrike(stream, state) { + var maybeEnd = false, ch; + + while (ch = stream.next()) { + if (ch == "-" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "-"); + } + return "strikethrough"; + } + + // macro + function twTokenMacro(stream, state) { + if (stream.current() == '<<') { + return 'macro'; + } + + var ch = stream.next(); + if (!ch) { + state.tokenize = tokenBase; + return null; + } + if (ch == ">") { + if (stream.peek() == '>') { + stream.next(); + state.tokenize = tokenBase; + return "macro"; + } + } + + stream.eatWhile(/[\w\$_]/); + return keywords.propertyIsEnumerable(stream.current()) ? "keyword" : null + } + + // Interface + return { + startState: function () { + return {tokenize: tokenBase}; + }, + + token: function (stream, state) { + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + return style; + } + }; +}); + +CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki"); +}); diff --git a/backend/webif/static/codemirror/mode/tiki/index.html b/backend/webif/static/codemirror/mode/tiki/index.html new file mode 100755 index 000000000..091c5fb2a --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiki/index.html @@ -0,0 +1,95 @@ + + +CodeMirror: Tiki wiki mode + + + + + + + + + + +
+

Tiki wiki mode

+ + +
+ + + +
diff --git a/backend/webif/static/codemirror/mode/tiki/tiki.css b/backend/webif/static/codemirror/mode/tiki/tiki.css new file mode 100755 index 000000000..1d8704c78 --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiki/tiki.css @@ -0,0 +1,26 @@ +.cm-tw-syntaxerror { + color: #FFF; + background-color: #900; +} + +.cm-tw-deleted { + text-decoration: line-through; +} + +.cm-tw-header5 { + font-weight: bold; +} +.cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/ + padding-left: 10px; +} + +.cm-tw-box { + border-top-width: 0px !important; + border-style: solid; + border-width: 1px; + border-color: inherit; +} + +.cm-tw-underline { + text-decoration: underline; +} \ No newline at end of file diff --git a/backend/webif/static/codemirror/mode/tiki/tiki.js b/backend/webif/static/codemirror/mode/tiki/tiki.js new file mode 100755 index 000000000..b4794e433 --- /dev/null +++ b/backend/webif/static/codemirror/mode/tiki/tiki.js @@ -0,0 +1,312 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('tiki', function(config) { + function inBlock(style, terminator, returnTokenizer) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + + if (returnTokenizer) state.tokenize = returnTokenizer; + + return style; + }; + } + + function inLine(style) { + return function(stream, state) { + while(!stream.eol()) { + stream.next(); + } + state.tokenize = inText; + return style; + }; + } + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var sol = stream.sol(); + var ch = stream.next(); + + //non start of line + switch (ch) { //switch is generally much faster than if, so it is used here + case "{": //plugin + stream.eat("/"); + stream.eatSpace(); + stream.eatWhile(/[^\s\u00a0=\"\'\/?(}]/); + state.tokenize = inPlugin; + return "tag"; + case "_": //bold + if (stream.eat("_")) + return chain(inBlock("strong", "__", inText)); + break; + case "'": //italics + if (stream.eat("'")) + return chain(inBlock("em", "''", inText)); + break; + case "(":// Wiki Link + if (stream.eat("(")) + return chain(inBlock("variable-2", "))", inText)); + break; + case "[":// Weblink + return chain(inBlock("variable-3", "]", inText)); + break; + case "|": //table + if (stream.eat("|")) + return chain(inBlock("comment", "||")); + break; + case "-": + if (stream.eat("=")) {//titleBar + return chain(inBlock("header string", "=-", inText)); + } else if (stream.eat("-")) {//deleted + return chain(inBlock("error tw-deleted", "--", inText)); + } + break; + case "=": //underline + if (stream.match("==")) + return chain(inBlock("tw-underline", "===", inText)); + break; + case ":": + if (stream.eat(":")) + return chain(inBlock("comment", "::")); + break; + case "^": //box + return chain(inBlock("tw-box", "^")); + break; + case "~": //np + if (stream.match("np~")) + return chain(inBlock("meta", "~/np~")); + break; + } + + //start of line types + if (sol) { + switch (ch) { + case "!": //header at start of line + if (stream.match('!!!!!')) { + return chain(inLine("header string")); + } else if (stream.match('!!!!')) { + return chain(inLine("header string")); + } else if (stream.match('!!!')) { + return chain(inLine("header string")); + } else if (stream.match('!!')) { + return chain(inLine("header string")); + } else { + return chain(inLine("header string")); + } + break; + case "*": //unordered list line item, or
  • at start of line + case "#": //ordered list line item, or
  • at start of line + case "+": //ordered list line item, or
  • at start of line + return chain(inLine("tw-listitem bracket")); + break; + } + } + + //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki + return null; + } + + var indentUnit = config.indentUnit; + + // Return variables for tokenizers + var pluginName, type; + function inPlugin(stream, state) { + var ch = stream.next(); + var peek = stream.peek(); + + if (ch == "}") { + state.tokenize = inText; + //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin + return "tag"; + } else if (ch == "(" || ch == ")") { + return "bracket"; + } else if (ch == "=") { + type = "equals"; + + if (peek == ">") { + stream.next(); + peek = stream.peek(); + } + + //here we detect values directly after equal character with no quotes + if (!/[\'\"]/.test(peek)) { + state.tokenize = inAttributeNoQuote(); + } + //end detect values + + return "operator"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + return state.tokenize(stream, state); + } else { + stream.eatWhile(/[^\s\u00a0=\"\'\/?]/); + return "keyword"; + } + } + + function inAttribute(quote) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inPlugin; + break; + } + } + return "string"; + }; + } + + function inAttributeNoQuote() { + return function(stream, state) { + while (!stream.eol()) { + var ch = stream.next(); + var peek = stream.peek(); + if (ch == " " || ch == "," || /[ )}]/.test(peek)) { + state.tokenize = inPlugin; + break; + } + } + return "string"; +}; + } + +var curState, setStyle; +function pass() { + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); +} + +function cont() { + pass.apply(null, arguments); + return true; +} + +function pushContext(pluginName, startOfLine) { + var noIndent = curState.context && curState.context.noIndent; + curState.context = { + prev: curState.context, + pluginName: pluginName, + indent: curState.indented, + startOfLine: startOfLine, + noIndent: noIndent + }; +} + +function popContext() { + if (curState.context) curState.context = curState.context.prev; +} + +function element(type) { + if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));} + else if (type == "closePlugin") { + var err = false; + if (curState.context) { + err = curState.context.pluginName != pluginName; + popContext(); + } else { + err = true; + } + if (err) setStyle = "error"; + return cont(endcloseplugin(err)); + } + else if (type == "string") { + if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata"); + if (curState.tokenize == inText) popContext(); + return cont(); + } + else return cont(); +} + +function endplugin(startOfLine) { + return function(type) { + if ( + type == "selfclosePlugin" || + type == "endPlugin" + ) + return cont(); + if (type == "endPlugin") {pushContext(curState.pluginName, startOfLine); return cont();} + return cont(); + }; +} + +function endcloseplugin(err) { + return function(type) { + if (err) setStyle = "error"; + if (type == "endPlugin") return cont(); + return pass(); + }; +} + +function attributes(type) { + if (type == "keyword") {setStyle = "attribute"; return cont(attributes);} + if (type == "equals") return cont(attvalue, attributes); + return pass(); +} +function attvalue(type) { + if (type == "keyword") {setStyle = "string"; return cont();} + if (type == "string") return cont(attvaluemaybe); + return pass(); +} +function attvaluemaybe(type) { + if (type == "string") return cont(attvaluemaybe); + else return pass(); +} +return { + startState: function() { + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, pluginName: null, context: null}; + }, + token: function(stream, state) { + if (stream.sol()) { + state.startOfLine = true; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + + setStyle = type = pluginName = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "comment") { + curState = state; + while (true) { + var comb = state.cc.pop() || element; + if (comb(type || style)) break; + } + } + state.startOfLine = false; + return setStyle || style; + }, + indent: function(state, textAfter) { + var context = state.context; + if (context && context.noIndent) return 0; + if (context && /^{\//.test(textAfter)) + context = context.prev; + while (context && !context.startOfLine) + context = context.prev; + if (context) return context.indent + indentUnit; + else return 0; + }, + electricChars: "/" +}; +}); + +CodeMirror.defineMIME("text/tiki", "tiki"); + +}); diff --git a/backend/webif/static/codemirror/mode/toml/index.html b/backend/webif/static/codemirror/mode/toml/index.html new file mode 100755 index 000000000..90a2a0215 --- /dev/null +++ b/backend/webif/static/codemirror/mode/toml/index.html @@ -0,0 +1,73 @@ + + +CodeMirror: TOML Mode + + + + + + + + + +
    +

    TOML Mode

    +
    + +

    The TOML Mode

    +

    Created by Forbes Lindesay.

    +

    MIME type defined: text/x-toml.

    +
    diff --git a/backend/webif/static/codemirror/mode/toml/toml.js b/backend/webif/static/codemirror/mode/toml/toml.js new file mode 100755 index 000000000..baeca1556 --- /dev/null +++ b/backend/webif/static/codemirror/mode/toml/toml.js @@ -0,0 +1,88 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("toml", function () { + return { + startState: function () { + return { + inString: false, + stringType: "", + lhs: true, + inArray: 0 + }; + }, + token: function (stream, state) { + //check for state changes + if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) { + state.stringType = stream.peek(); + stream.next(); // Skip quote + state.inString = true; // Update state + } + if (stream.sol() && state.inArray === 0) { + state.lhs = true; + } + //return state + if (state.inString) { + while (state.inString && !stream.eol()) { + if (stream.peek() === state.stringType) { + stream.next(); // Skip quote + state.inString = false; // Clear flag + } else if (stream.peek() === '\\') { + stream.next(); + stream.next(); + } else { + stream.match(/^.[^\\\"\']*/); + } + } + return state.lhs ? "property string" : "string"; // Token style + } else if (state.inArray && stream.peek() === ']') { + stream.next(); + state.inArray--; + return 'bracket'; + } else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) { + stream.next();//skip closing ] + // array of objects has an extra open & close [] + if (stream.peek() === ']') stream.next(); + return "atom"; + } else if (stream.peek() === "#") { + stream.skipToEnd(); + return "comment"; + } else if (stream.eatSpace()) { + return null; + } else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) { + return "property"; + } else if (state.lhs && stream.peek() === "=") { + stream.next(); + state.lhs = false; + return null; + } else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) { + return 'atom'; //date + } else if (!state.lhs && (stream.match('true') || stream.match('false'))) { + return 'atom'; + } else if (!state.lhs && stream.peek() === '[') { + state.inArray++; + stream.next(); + return 'bracket'; + } else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) { + return 'number'; + } else if (!stream.eatSpace()) { + stream.next(); + } + return null; + } + }; +}); + +CodeMirror.defineMIME('text/x-toml', 'toml'); + +}); diff --git a/backend/webif/static/codemirror/mode/tornado/index.html b/backend/webif/static/codemirror/mode/tornado/index.html new file mode 100755 index 000000000..8ee7ef56c --- /dev/null +++ b/backend/webif/static/codemirror/mode/tornado/index.html @@ -0,0 +1,63 @@ + + +CodeMirror: Tornado template mode + + + + + + + + + + + + +
    +

    Tornado template mode

    +
    + + + +

    Mode for HTML with embedded Tornado template markup.

    + +

    MIME types defined: text/x-tornado

    +
    diff --git a/backend/webif/static/codemirror/mode/tornado/tornado.js b/backend/webif/static/codemirror/mode/tornado/tornado.js new file mode 100755 index 000000000..dbfbc3489 --- /dev/null +++ b/backend/webif/static/codemirror/mode/tornado/tornado.js @@ -0,0 +1,68 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), + require("../../addon/mode/overlay")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", + "../../addon/mode/overlay"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("tornado:inner", function() { + var keywords = ["and","as","assert","autoescape","block","break","class","comment","context", + "continue","datetime","def","del","elif","else","end","escape","except", + "exec","extends","false","finally","for","from","global","if","import","in", + "include","is","json_encode","lambda","length","linkify","load","module", + "none","not","or","pass","print","put","raise","raw","return","self","set", + "squeeze","super","true","try","url_escape","while","with","without","xhtml_escape","yield"]; + keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b"); + + function tokenBase (stream, state) { + stream.eatWhile(/[^\{]/); + var ch = stream.next(); + if (ch == "{") { + if (ch = stream.eat(/\{|%|#/)) { + state.tokenize = inTag(ch); + return "tag"; + } + } + } + function inTag (close) { + if (close == "{") { + close = "}"; + } + return function (stream, state) { + var ch = stream.next(); + if ((ch == close) && stream.eat("}")) { + state.tokenize = tokenBase; + return "tag"; + } + if (stream.match(keywords)) { + return "keyword"; + } + return close == "#" ? "comment" : "string"; + }; + } + return { + startState: function () { + return {tokenize: tokenBase}; + }, + token: function (stream, state) { + return state.tokenize(stream, state); + } + }; + }); + + CodeMirror.defineMode("tornado", function(config) { + var htmlBase = CodeMirror.getMode(config, "text/html"); + var tornadoInner = CodeMirror.getMode(config, "tornado:inner"); + return CodeMirror.overlayMode(htmlBase, tornadoInner); + }); + + CodeMirror.defineMIME("text/x-tornado", "tornado"); +}); diff --git a/backend/webif/static/codemirror/mode/troff/index.html b/backend/webif/static/codemirror/mode/troff/index.html new file mode 100755 index 000000000..7c5a54e54 --- /dev/null +++ b/backend/webif/static/codemirror/mode/troff/index.html @@ -0,0 +1,146 @@ + + +CodeMirror: troff mode + + + + + + + + + + +
    +

    troff

    + + + + + + +

    MIME types defined: troff.

    +
    diff --git a/backend/webif/static/codemirror/mode/troff/troff.js b/backend/webif/static/codemirror/mode/troff/troff.js new file mode 100755 index 000000000..86154b6e1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/troff/troff.js @@ -0,0 +1,84 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) + define(["../../lib/codemirror"], mod); + else + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('troff', function() { + + var words = {}; + + function tokenBase(stream) { + if (stream.eatSpace()) return null; + + var sol = stream.sol(); + var ch = stream.next(); + + if (ch === '\\') { + if (stream.match('fB') || stream.match('fR') || stream.match('fI') || + stream.match('u') || stream.match('d') || + stream.match('%') || stream.match('&')) { + return 'string'; + } + if (stream.match('m[')) { + stream.skipTo(']'); + stream.next(); + return 'string'; + } + if (stream.match('s+') || stream.match('s-')) { + stream.eatWhile(/[\d-]/); + return 'string'; + } + if (stream.match('\(') || stream.match('*\(')) { + stream.eatWhile(/[\w-]/); + return 'string'; + } + return 'string'; + } + if (sol && (ch === '.' || ch === '\'')) { + if (stream.eat('\\') && stream.eat('\"')) { + stream.skipToEnd(); + return 'comment'; + } + } + if (sol && ch === '.') { + if (stream.match('B ') || stream.match('I ') || stream.match('R ')) { + return 'attribute'; + } + if (stream.match('TH ') || stream.match('SH ') || stream.match('SS ') || stream.match('HP ')) { + stream.skipToEnd(); + return 'quote'; + } + if ((stream.match(/[A-Z]/) && stream.match(/[A-Z]/)) || (stream.match(/[a-z]/) && stream.match(/[a-z]/))) { + return 'attribute'; + } + } + stream.eatWhile(/[\w-]/); + var cur = stream.current(); + return words.hasOwnProperty(cur) ? words[cur] : null; + } + + function tokenize(stream, state) { + return (state.tokens[0] || tokenBase) (stream, state); + }; + + return { + startState: function() {return {tokens:[]};}, + token: function(stream, state) { + return tokenize(stream, state); + } + }; +}); + +CodeMirror.defineMIME('text/troff', 'troff'); +CodeMirror.defineMIME('text/x-troff', 'troff'); +CodeMirror.defineMIME('application/x-troff', 'troff'); + +}); diff --git a/backend/webif/static/codemirror/mode/ttcn-cfg/index.html b/backend/webif/static/codemirror/mode/ttcn-cfg/index.html new file mode 100755 index 000000000..4a4cd4571 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ttcn-cfg/index.html @@ -0,0 +1,115 @@ + + +CodeMirror: TTCN-CFG mode + + + + + + + + +
    +

    TTCN-CFG example

    +
    + +
    + + +
    +

    Language: Testing and Test Control Notation - + Configuration files + (TTCN-CFG) +

    +

    MIME types defined: text/x-ttcn-cfg.

    + +
    +

    The development of this mode has been sponsored by Ericsson + .

    +

    Coded by Asmelash Tsegay Gebretsadkan

    +
    + diff --git a/backend/webif/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js b/backend/webif/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js new file mode 100755 index 000000000..e10805119 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ttcn-cfg/ttcn-cfg.js @@ -0,0 +1,214 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("ttcn-cfg", function(config, parserConfig) { + var indentUnit = config.indentUnit, + keywords = parserConfig.keywords || {}, + fileNCtrlMaskOptions = parserConfig.fileNCtrlMaskOptions || {}, + externalCommands = parserConfig.externalCommands || {}, + multiLineStrings = parserConfig.multiLineStrings, + indentStatements = parserConfig.indentStatements !== false; + var isOperatorChar = /[\|]/; + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[:=]/.test(ch)) { + curPunc = ch; + return "punctuation"; + } + if (ch == "#"){ + stream.skipToEnd(); + return "comment"; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + if (ch == "["){ + stream.eatWhile(/[\w_\]]/); + return "number sectionTitle"; + } + + stream.eatWhile(/[\w\$_]/); + var cur = stream.current(); + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + if (fileNCtrlMaskOptions.propertyIsEnumerable(cur)) + return "negative fileNCtrlMaskOptions"; + if (externalCommands.propertyIsEnumerable(cur)) return "negative externalCommands"; + + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped){ + var afterNext = stream.peek(); + //look if the character if the quote is like the B in '10100010'B + if (afterNext){ + afterNext = afterNext.toLowerCase(); + if(afterNext == "b" || afterNext == "h" || afterNext == "o") + stream.next(); + } + end = true; break; + } + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = null; + return "string"; + }; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + var indent = state.indented; + if (state.context && state.context.type == "statement") + indent = state.context.indented; + return state.context = new Context(indent, col, type, null, state.context); + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + //Interface + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":" || curPunc == ",") + && ctx.type == "statement"){ + popContext(state); + } + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (indentStatements && (((ctx.type == "}" || ctx.type == "top") + && curPunc != ';') || (ctx.type == "statement" + && curPunc == "newstatement"))) + pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + return style; + }, + + electricChars: "{}", + lineComment: "#", + fold: "brace" + }; + }); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) + obj[words[i]] = true; + return obj; + } + + CodeMirror.defineMIME("text/x-ttcn-cfg", { + name: "ttcn-cfg", + keywords: words("Yes No LogFile FileMask ConsoleMask AppendFile" + + " TimeStampFormat LogEventTypes SourceInfoFormat" + + " LogEntityName LogSourceInfo DiskFullAction" + + " LogFileNumber LogFileSize MatchingHints Detailed" + + " Compact SubCategories Stack Single None Seconds" + + " DateTime Time Stop Error Retry Delete TCPPort KillTimer" + + " NumHCs UnixSocketsEnabled LocalAddress"), + fileNCtrlMaskOptions: words("TTCN_EXECUTOR TTCN_ERROR TTCN_WARNING" + + " TTCN_PORTEVENT TTCN_TIMEROP TTCN_VERDICTOP" + + " TTCN_DEFAULTOP TTCN_TESTCASE TTCN_ACTION" + + " TTCN_USER TTCN_FUNCTION TTCN_STATISTICS" + + " TTCN_PARALLEL TTCN_MATCHING TTCN_DEBUG" + + " EXECUTOR ERROR WARNING PORTEVENT TIMEROP" + + " VERDICTOP DEFAULTOP TESTCASE ACTION USER" + + " FUNCTION STATISTICS PARALLEL MATCHING DEBUG" + + " LOG_ALL LOG_NOTHING ACTION_UNQUALIFIED" + + " DEBUG_ENCDEC DEBUG_TESTPORT" + + " DEBUG_UNQUALIFIED DEFAULTOP_ACTIVATE" + + " DEFAULTOP_DEACTIVATE DEFAULTOP_EXIT" + + " DEFAULTOP_UNQUALIFIED ERROR_UNQUALIFIED" + + " EXECUTOR_COMPONENT EXECUTOR_CONFIGDATA" + + " EXECUTOR_EXTCOMMAND EXECUTOR_LOGOPTIONS" + + " EXECUTOR_RUNTIME EXECUTOR_UNQUALIFIED" + + " FUNCTION_RND FUNCTION_UNQUALIFIED" + + " MATCHING_DONE MATCHING_MCSUCCESS" + + " MATCHING_MCUNSUCC MATCHING_MMSUCCESS" + + " MATCHING_MMUNSUCC MATCHING_PCSUCCESS" + + " MATCHING_PCUNSUCC MATCHING_PMSUCCESS" + + " MATCHING_PMUNSUCC MATCHING_PROBLEM" + + " MATCHING_TIMEOUT MATCHING_UNQUALIFIED" + + " PARALLEL_PORTCONN PARALLEL_PORTMAP" + + " PARALLEL_PTC PARALLEL_UNQUALIFIED" + + " PORTEVENT_DUALRECV PORTEVENT_DUALSEND" + + " PORTEVENT_MCRECV PORTEVENT_MCSEND" + + " PORTEVENT_MMRECV PORTEVENT_MMSEND" + + " PORTEVENT_MQUEUE PORTEVENT_PCIN" + + " PORTEVENT_PCOUT PORTEVENT_PMIN" + + " PORTEVENT_PMOUT PORTEVENT_PQUEUE" + + " PORTEVENT_STATE PORTEVENT_UNQUALIFIED" + + " STATISTICS_UNQUALIFIED STATISTICS_VERDICT" + + " TESTCASE_FINISH TESTCASE_START" + + " TESTCASE_UNQUALIFIED TIMEROP_GUARD" + + " TIMEROP_READ TIMEROP_START TIMEROP_STOP" + + " TIMEROP_TIMEOUT TIMEROP_UNQUALIFIED" + + " USER_UNQUALIFIED VERDICTOP_FINAL" + + " VERDICTOP_GETVERDICT VERDICTOP_SETVERDICT" + + " VERDICTOP_UNQUALIFIED WARNING_UNQUALIFIED"), + externalCommands: words("BeginControlPart EndControlPart BeginTestCase" + + " EndTestCase"), + multiLineStrings: true + }); +}); \ No newline at end of file diff --git a/backend/webif/static/codemirror/mode/ttcn/index.html b/backend/webif/static/codemirror/mode/ttcn/index.html new file mode 100755 index 000000000..f1ef81131 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ttcn/index.html @@ -0,0 +1,118 @@ + + +CodeMirror: TTCN mode + + + + + + + + +
    +

    TTCN example

    +
    + +
    + + +
    +

    Language: Testing and Test Control Notation + (TTCN) +

    +

    MIME types defined: text/x-ttcn, + text/x-ttcn3, text/x-ttcnpp.

    +
    +

    The development of this mode has been sponsored by Ericsson + .

    +

    Coded by Asmelash Tsegay Gebretsadkan

    +
    + diff --git a/backend/webif/static/codemirror/mode/ttcn/ttcn.js b/backend/webif/static/codemirror/mode/ttcn/ttcn.js new file mode 100755 index 000000000..305185177 --- /dev/null +++ b/backend/webif/static/codemirror/mode/ttcn/ttcn.js @@ -0,0 +1,283 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("ttcn", function(config, parserConfig) { + var indentUnit = config.indentUnit, + keywords = parserConfig.keywords || {}, + builtin = parserConfig.builtin || {}, + timerOps = parserConfig.timerOps || {}, + portOps = parserConfig.portOps || {}, + configOps = parserConfig.configOps || {}, + verdictOps = parserConfig.verdictOps || {}, + sutOps = parserConfig.sutOps || {}, + functionOps = parserConfig.functionOps || {}, + + verdictConsts = parserConfig.verdictConsts || {}, + booleanConsts = parserConfig.booleanConsts || {}, + otherConsts = parserConfig.otherConsts || {}, + + types = parserConfig.types || {}, + visibilityModifiers = parserConfig.visibilityModifiers || {}, + templateMatch = parserConfig.templateMatch || {}, + multiLineStrings = parserConfig.multiLineStrings, + indentStatements = parserConfig.indentStatements !== false; + var isOperatorChar = /[+\-*&@=<>!\/]/; + var curPunc; + + function tokenBase(stream, state) { + var ch = stream.next(); + + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[\[\]{}\(\),;\\:\?\.]/.test(ch)) { + curPunc = ch; + return "punctuation"; + } + if (ch == "#"){ + stream.skipToEnd(); + return "atom preprocessor"; + } + if (ch == "%"){ + stream.eatWhile(/\b/); + return "atom ttcn3Macros"; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/); + return "number"; + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (isOperatorChar.test(ch)) { + if(ch == "@"){ + if(stream.match("try") || stream.match("catch") + || stream.match("lazy")){ + return "keyword"; + } + } + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w\$_\xa1-\uffff]/); + var cur = stream.current(); + + if (keywords.propertyIsEnumerable(cur)) return "keyword"; + if (builtin.propertyIsEnumerable(cur)) return "builtin"; + + if (timerOps.propertyIsEnumerable(cur)) return "def timerOps"; + if (configOps.propertyIsEnumerable(cur)) return "def configOps"; + if (verdictOps.propertyIsEnumerable(cur)) return "def verdictOps"; + if (portOps.propertyIsEnumerable(cur)) return "def portOps"; + if (sutOps.propertyIsEnumerable(cur)) return "def sutOps"; + if (functionOps.propertyIsEnumerable(cur)) return "def functionOps"; + + if (verdictConsts.propertyIsEnumerable(cur)) return "string verdictConsts"; + if (booleanConsts.propertyIsEnumerable(cur)) return "string booleanConsts"; + if (otherConsts.propertyIsEnumerable(cur)) return "string otherConsts"; + + if (types.propertyIsEnumerable(cur)) return "builtin types"; + if (visibilityModifiers.propertyIsEnumerable(cur)) + return "builtin visibilityModifiers"; + if (templateMatch.propertyIsEnumerable(cur)) return "atom templateMatch"; + + return "variable"; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped){ + var afterQuote = stream.peek(); + //look if the character after the quote is like the B in '10100010'B + if (afterQuote){ + afterQuote = afterQuote.toLowerCase(); + if(afterQuote == "b" || afterQuote == "h" || afterQuote == "o") + stream.next(); + } + end = true; break; + } + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = null; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + + function pushContext(state, col, type) { + var indent = state.indented; + if (state.context && state.context.type == "statement") + indent = state.context.indented; + return state.context = new Context(indent, col, type, null, state.context); + } + + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return state.context = state.context.prev; + } + + //Interface + return { + startState: function(basecolumn) { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":" || curPunc == ",") + && ctx.type == "statement"){ + popContext(state); + } + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } + else if (curPunc == ctx.type) popContext(state); + else if (indentStatements && + (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || + (ctx.type == "statement" && curPunc == "newstatement"))) + pushContext(state, stream.column(), "statement"); + + state.startOfLine = false; + + return style; + }, + + electricChars: "{}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//", + fold: "brace" + }; + }); + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + function def(mimes, mode) { + if (typeof mimes == "string") mimes = [mimes]; + var words = []; + function add(obj) { + if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) + words.push(prop); + } + + add(mode.keywords); + add(mode.builtin); + add(mode.timerOps); + add(mode.portOps); + + if (words.length) { + mode.helperType = mimes[0]; + CodeMirror.registerHelper("hintWords", mimes[0], words); + } + + for (var i = 0; i < mimes.length; ++i) + CodeMirror.defineMIME(mimes[i], mode); + } + + def(["text/x-ttcn", "text/x-ttcn3", "text/x-ttcnpp"], { + name: "ttcn", + keywords: words("activate address alive all alt altstep and and4b any" + + " break case component const continue control deactivate" + + " display do else encode enumerated except exception" + + " execute extends extension external for from function" + + " goto group if import in infinity inout interleave" + + " label language length log match message mixed mod" + + " modifies module modulepar mtc noblock not not4b nowait" + + " of on optional or or4b out override param pattern port" + + " procedure record recursive rem repeat return runs select" + + " self sender set signature system template testcase to" + + " type union value valueof var variant while with xor xor4b"), + builtin: words("bit2hex bit2int bit2oct bit2str char2int char2oct encvalue" + + " decomp decvalue float2int float2str hex2bit hex2int" + + " hex2oct hex2str int2bit int2char int2float int2hex" + + " int2oct int2str int2unichar isbound ischosen ispresent" + + " isvalue lengthof log2str oct2bit oct2char oct2hex oct2int" + + " oct2str regexp replace rnd sizeof str2bit str2float" + + " str2hex str2int str2oct substr unichar2int unichar2char" + + " enum2int"), + types: words("anytype bitstring boolean char charstring default float" + + " hexstring integer objid octetstring universal verdicttype timer"), + timerOps: words("read running start stop timeout"), + portOps: words("call catch check clear getcall getreply halt raise receive" + + " reply send trigger"), + configOps: words("create connect disconnect done kill killed map unmap"), + verdictOps: words("getverdict setverdict"), + sutOps: words("action"), + functionOps: words("apply derefers refers"), + + verdictConsts: words("error fail inconc none pass"), + booleanConsts: words("true false"), + otherConsts: words("null NULL omit"), + + visibilityModifiers: words("private public friend"), + templateMatch: words("complement ifpresent subset superset permutation"), + multiLineStrings: true + }); +}); diff --git a/backend/webif/static/codemirror/mode/turtle/index.html b/backend/webif/static/codemirror/mode/turtle/index.html new file mode 100755 index 000000000..a4962b617 --- /dev/null +++ b/backend/webif/static/codemirror/mode/turtle/index.html @@ -0,0 +1,50 @@ + + +CodeMirror: Turtle mode + + + + + + + + + +
    +

    Turtle mode

    +
    + + +

    MIME types defined: text/turtle.

    + +
    diff --git a/backend/webif/static/codemirror/mode/turtle/turtle.js b/backend/webif/static/codemirror/mode/turtle/turtle.js new file mode 100755 index 000000000..0988f0a44 --- /dev/null +++ b/backend/webif/static/codemirror/mode/turtle/turtle.js @@ -0,0 +1,162 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("turtle", function(config) { + var indentUnit = config.indentUnit; + var curPunc; + + function wordRegexp(words) { + return new RegExp("^(?:" + words.join("|") + ")$", "i"); + } + var ops = wordRegexp([]); + var keywords = wordRegexp(["@prefix", "@base", "a"]); + var operatorChars = /[*+\-<>=&|]/; + + function tokenBase(stream, state) { + var ch = stream.next(); + curPunc = null; + if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { + stream.match(/^[^\s\u00a0>]*>?/); + return "atom"; + } + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenLiteral(ch); + return state.tokenize(stream, state); + } + else if (/[{}\(\),\.;\[\]]/.test(ch)) { + curPunc = ch; + return null; + } + else if (ch == "#") { + stream.skipToEnd(); + return "comment"; + } + else if (operatorChars.test(ch)) { + stream.eatWhile(operatorChars); + return null; + } + else if (ch == ":") { + return "operator"; + } else { + stream.eatWhile(/[_\w\d]/); + if(stream.peek() == ":") { + return "variable-3"; + } else { + var word = stream.current(); + + if(keywords.test(word)) { + return "meta"; + } + + if(ch >= "A" && ch <= "Z") { + return "comment"; + } else { + return "keyword"; + } + } + var word = stream.current(); + if (ops.test(word)) + return null; + else if (keywords.test(word)) + return "meta"; + else + return "variable"; + } + } + + function tokenLiteral(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && ch == "\\"; + } + return "string"; + }; + } + + function pushContext(state, type, col) { + state.context = {prev: state.context, indent: state.indent, col: col, type: type}; + } + function popContext(state) { + state.indent = state.context.indent; + state.context = state.context.prev; + } + + return { + startState: function() { + return {tokenize: tokenBase, + context: null, + indent: 0, + col: 0}; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (state.context && state.context.align == null) state.context.align = false; + state.indent = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + + if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { + state.context.align = true; + } + + if (curPunc == "(") pushContext(state, ")", stream.column()); + else if (curPunc == "[") pushContext(state, "]", stream.column()); + else if (curPunc == "{") pushContext(state, "}", stream.column()); + else if (/[\]\}\)]/.test(curPunc)) { + while (state.context && state.context.type == "pattern") popContext(state); + if (state.context && curPunc == state.context.type) popContext(state); + } + else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); + else if (/atom|string|variable/.test(style) && state.context) { + if (/[\}\]]/.test(state.context.type)) + pushContext(state, "pattern", stream.column()); + else if (state.context.type == "pattern" && !state.context.align) { + state.context.align = true; + state.context.col = stream.column(); + } + } + + return style; + }, + + indent: function(state, textAfter) { + var firstChar = textAfter && textAfter.charAt(0); + var context = state.context; + if (/[\]\}]/.test(firstChar)) + while (context && context.type == "pattern") context = context.prev; + + var closing = context && firstChar == context.type; + if (!context) + return 0; + else if (context.type == "pattern") + return context.col; + else if (context.align) + return context.col + (closing ? 0 : 1); + else + return context.indent + (closing ? 0 : indentUnit); + }, + + lineComment: "#" + }; +}); + +CodeMirror.defineMIME("text/turtle", "turtle"); + +}); diff --git a/backend/webif/static/codemirror/mode/twig/index.html b/backend/webif/static/codemirror/mode/twig/index.html new file mode 100755 index 000000000..02493a5cb --- /dev/null +++ b/backend/webif/static/codemirror/mode/twig/index.html @@ -0,0 +1,45 @@ + + +CodeMirror: Twig mode + + + + + + + + + +
    +

    Twig mode

    +
    + +
    diff --git a/backend/webif/static/codemirror/mode/twig/twig.js b/backend/webif/static/codemirror/mode/twig/twig.js new file mode 100755 index 000000000..b4e98972b --- /dev/null +++ b/backend/webif/static/codemirror/mode/twig/twig.js @@ -0,0 +1,141 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../addon/mode/multiplex")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../addon/mode/multiplex"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("twig:inner", function() { + var keywords = ["and", "as", "autoescape", "endautoescape", "block", "do", "endblock", "else", "elseif", "extends", "for", "endfor", "embed", "endembed", "filter", "endfilter", "flush", "from", "if", "endif", "in", "is", "include", "import", "not", "or", "set", "spaceless", "endspaceless", "with", "endwith", "trans", "endtrans", "blocktrans", "endblocktrans", "macro", "endmacro", "use", "verbatim", "endverbatim"], + operator = /^[+\-*&%=<>!?|~^]/, + sign = /^[:\[\(\{]/, + atom = ["true", "false", "null", "empty", "defined", "divisibleby", "divisible by", "even", "odd", "iterable", "sameas", "same as"], + number = /^(\d[+\-\*\/])?\d+(\.\d+)?/; + + keywords = new RegExp("((" + keywords.join(")|(") + "))\\b"); + atom = new RegExp("((" + atom.join(")|(") + "))\\b"); + + function tokenBase (stream, state) { + var ch = stream.peek(); + + //Comment + if (state.incomment) { + if (!stream.skipTo("#}")) { + stream.skipToEnd(); + } else { + stream.eatWhile(/\#|}/); + state.incomment = false; + } + return "comment"; + //Tag + } else if (state.intag) { + //After operator + if (state.operator) { + state.operator = false; + if (stream.match(atom)) { + return "atom"; + } + if (stream.match(number)) { + return "number"; + } + } + //After sign + if (state.sign) { + state.sign = false; + if (stream.match(atom)) { + return "atom"; + } + if (stream.match(number)) { + return "number"; + } + } + + if (state.instring) { + if (ch == state.instring) { + state.instring = false; + } + stream.next(); + return "string"; + } else if (ch == "'" || ch == '"') { + state.instring = ch; + stream.next(); + return "string"; + } else if (stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) { + state.intag = false; + return "tag"; + } else if (stream.match(operator)) { + state.operator = true; + return "operator"; + } else if (stream.match(sign)) { + state.sign = true; + } else { + if (stream.eat(" ") || stream.sol()) { + if (stream.match(keywords)) { + return "keyword"; + } + if (stream.match(atom)) { + return "atom"; + } + if (stream.match(number)) { + return "number"; + } + if (stream.sol()) { + stream.next(); + } + } else { + stream.next(); + } + + } + return "variable"; + } else if (stream.eat("{")) { + if (stream.eat("#")) { + state.incomment = true; + if (!stream.skipTo("#}")) { + stream.skipToEnd(); + } else { + stream.eatWhile(/\#|}/); + state.incomment = false; + } + return "comment"; + //Open tag + } else if (ch = stream.eat(/\{|%/)) { + //Cache close tag + state.intag = ch; + if (ch == "{") { + state.intag = "}"; + } + stream.eat("-"); + return "tag"; + } + } + stream.next(); + }; + + return { + startState: function () { + return {}; + }, + token: function (stream, state) { + return tokenBase(stream, state); + } + }; + }); + + CodeMirror.defineMode("twig", function(config, parserConfig) { + var twigInner = CodeMirror.getMode(config, "twig:inner"); + if (!parserConfig || !parserConfig.base) return twigInner; + return CodeMirror.multiplexingMode( + CodeMirror.getMode(config, parserConfig.base), { + open: /\{[{#%]/, close: /[}#%]\}/, mode: twigInner, parseDelimiters: true + } + ); + }); + CodeMirror.defineMIME("text/x-twig", "twig"); +}); diff --git a/backend/webif/static/codemirror/mode/vb/index.html b/backend/webif/static/codemirror/mode/vb/index.html new file mode 100755 index 000000000..869724890 --- /dev/null +++ b/backend/webif/static/codemirror/mode/vb/index.html @@ -0,0 +1,49 @@ + + +CodeMirror: VB.NET mode + + + + + + + + + + + +
    +

    VB.NET mode

    +
    + +
    +

    MIME type defined: text/x-vb.

    + +
    diff --git a/backend/webif/static/codemirror/mode/vb/vb.js b/backend/webif/static/codemirror/mode/vb/vb.js new file mode 100755 index 000000000..735eb7f7e --- /dev/null +++ b/backend/webif/static/codemirror/mode/vb/vb.js @@ -0,0 +1,275 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("vb", function(conf, parserConf) { + var ERRORCLASS = 'error'; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); + } + + var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]"); + var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); + var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); + var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); + var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"); + var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); + + var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property', 'try']; + var middleKeywords = ['else','elseif','case', 'catch']; + var endKeywords = ['next','loop']; + + var operatorKeywords = ['and', 'or', 'not', 'xor', 'in']; + var wordOperators = wordRegexp(operatorKeywords); + var commonKeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until', + 'goto', 'byval','byref','new','handles','property', 'return', + 'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false']; + var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single']; + + var keywords = wordRegexp(commonKeywords); + var types = wordRegexp(commontypes); + var stringPrefixes = '"'; + + var opening = wordRegexp(openingKeywords); + var middle = wordRegexp(middleKeywords); + var closing = wordRegexp(endKeywords); + var doubleClosing = wordRegexp(['end']); + var doOpening = wordRegexp(['do']); + + var indentInfo = null; + + CodeMirror.registerHelper("hintWords", "vb", openingKeywords.concat(middleKeywords).concat(endKeywords) + .concat(operatorKeywords).concat(commonKeywords).concat(commontypes)); + + function indent(_stream, state) { + state.currentIndent++; + } + + function dedent(_stream, state) { + state.currentIndent--; + } + // tokenizers + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return null; + } + + var ch = stream.peek(); + + // Handle Comments + if (ch === "'") { + stream.skipToEnd(); + return 'comment'; + } + + + // Handle Number Literals + if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) { + var floatLiteral = false; + // Floats + if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; } + else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; } + else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; } + + if (floatLiteral) { + // Float literals may be "imaginary" + stream.eat(/J/i); + return 'number'; + } + // Integers + var intLiteral = false; + // Hex + if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; } + // Octal + else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; } + // Decimal + else if (stream.match(/^[1-9]\d*F?/)) { + // Decimal literals may be "imaginary" + stream.eat(/J/i); + // TODO - Can you have imaginary longs? + intLiteral = true; + } + // Zero by itself with no other piece of number. + else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } + if (intLiteral) { + // Integer literals may be "long" + stream.eat(/L/i); + return 'number'; + } + } + + // Handle Strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } + + // Handle operators and Delimiters + if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { + return null; + } + if (stream.match(doubleOperators) + || stream.match(singleOperators) + || stream.match(wordOperators)) { + return 'operator'; + } + if (stream.match(singleDelimiters)) { + return null; + } + if (stream.match(doOpening)) { + indent(stream,state); + state.doInCurrentLine = true; + return 'keyword'; + } + if (stream.match(opening)) { + if (! state.doInCurrentLine) + indent(stream,state); + else + state.doInCurrentLine = false; + return 'keyword'; + } + if (stream.match(middle)) { + return 'keyword'; + } + + if (stream.match(doubleClosing)) { + dedent(stream,state); + dedent(stream,state); + return 'keyword'; + } + if (stream.match(closing)) { + dedent(stream,state); + return 'keyword'; + } + + if (stream.match(types)) { + return 'keyword'; + } + + if (stream.match(keywords)) { + return 'keyword'; + } + + if (stream.match(identifiers)) { + return 'variable'; + } + + // Handle non-detected items + stream.next(); + return ERRORCLASS; + } + + function tokenStringFactory(delimiter) { + var singleline = delimiter.length == 1; + var OUTCLASS = 'string'; + + return function(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"]/); + if (stream.match(delimiter)) { + state.tokenize = tokenBase; + return OUTCLASS; + } else { + stream.eat(/['"]/); + } + } + if (singleline) { + if (parserConf.singleLineStringErrors) { + return ERRORCLASS; + } else { + state.tokenize = tokenBase; + } + } + return OUTCLASS; + }; + } + + + function tokenLexer(stream, state) { + var style = state.tokenize(stream, state); + var current = stream.current(); + + // Handle '.' connected identifiers + if (current === '.') { + style = state.tokenize(stream, state); + if (style === 'variable') { + return 'variable'; + } else { + return ERRORCLASS; + } + } + + + var delimiter_index = '[({'.indexOf(current); + if (delimiter_index !== -1) { + indent(stream, state ); + } + if (indentInfo === 'dedent') { + if (dedent(stream, state)) { + return ERRORCLASS; + } + } + delimiter_index = '])}'.indexOf(current); + if (delimiter_index !== -1) { + if (dedent(stream, state)) { + return ERRORCLASS; + } + } + + return style; + } + + var external = { + electricChars:"dDpPtTfFeE ", + startState: function() { + return { + tokenize: tokenBase, + lastToken: null, + currentIndent: 0, + nextLineIndent: 0, + doInCurrentLine: false + + + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + state.currentIndent += state.nextLineIndent; + state.nextLineIndent = 0; + state.doInCurrentLine = 0; + } + var style = tokenLexer(stream, state); + + state.lastToken = {style:style, content: stream.current()}; + + + + return style; + }, + + indent: function(state, textAfter) { + var trueText = textAfter.replace(/^\s+|\s+$/g, '') ; + if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1); + if(state.currentIndent < 0) return 0; + return state.currentIndent * conf.indentUnit; + }, + + lineComment: "'" + }; + return external; +}); + +CodeMirror.defineMIME("text/x-vb", "vb"); + +}); diff --git a/backend/webif/static/codemirror/mode/vbscript/index.html b/backend/webif/static/codemirror/mode/vbscript/index.html new file mode 100755 index 000000000..ad7532d7d --- /dev/null +++ b/backend/webif/static/codemirror/mode/vbscript/index.html @@ -0,0 +1,55 @@ + + +CodeMirror: VBScript mode + + + + + + + + + +
    +

    VBScript mode

    + + +
    + + + +

    MIME types defined: text/vbscript.

    +
    diff --git a/backend/webif/static/codemirror/mode/vbscript/vbscript.js b/backend/webif/static/codemirror/mode/vbscript/vbscript.js new file mode 100755 index 000000000..b66df2239 --- /dev/null +++ b/backend/webif/static/codemirror/mode/vbscript/vbscript.js @@ -0,0 +1,350 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* +For extra ASP classic objects, initialize CodeMirror instance with this option: + isASP: true + +E.G.: + var editor = CodeMirror.fromTextArea(document.getElementById("code"), { + lineNumbers: true, + isASP: true + }); +*/ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("vbscript", function(conf, parserConf) { + var ERRORCLASS = 'error'; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); + } + + var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]"); + var doubleOperators = new RegExp("^((<>)|(<=)|(>=))"); + var singleDelimiters = new RegExp('^[\\.,]'); + var brakets = new RegExp('^[\\(\\)]'); + var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*"); + + var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for']; + var middleKeywords = ['else','elseif','case']; + var endKeywords = ['next','loop','wend']; + + var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']); + var commonkeywords = ['dim', 'redim', 'then', 'until', 'randomize', + 'byval','byref','new','property', 'exit', 'in', + 'const','private', 'public', + 'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me']; + + //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx + var atomWords = ['true', 'false', 'nothing', 'empty', 'null']; + //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx + var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart', + 'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject', + 'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left', + 'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round', + 'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp', + 'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year']; + + //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx + var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare', + 'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek', + 'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError', + 'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2', + 'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo', + 'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse', + 'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray']; + //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx + var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp']; + var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count']; + var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit']; + + var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application']; + var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response + 'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request + 'contents', 'staticobjects', //application + 'codepage', 'lcid', 'sessionid', 'timeout', //session + 'scripttimeout']; //server + var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response + 'binaryread', //request + 'remove', 'removeall', 'lock', 'unlock', //application + 'abandon', //session + 'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server + + var knownWords = knownMethods.concat(knownProperties); + + builtinObjsWords = builtinObjsWords.concat(builtinConsts); + + if (conf.isASP){ + builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords); + knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties); + }; + + var keywords = wordRegexp(commonkeywords); + var atoms = wordRegexp(atomWords); + var builtinFuncs = wordRegexp(builtinFuncsWords); + var builtinObjs = wordRegexp(builtinObjsWords); + var known = wordRegexp(knownWords); + var stringPrefixes = '"'; + + var opening = wordRegexp(openingKeywords); + var middle = wordRegexp(middleKeywords); + var closing = wordRegexp(endKeywords); + var doubleClosing = wordRegexp(['end']); + var doOpening = wordRegexp(['do']); + var noIndentWords = wordRegexp(['on error resume next', 'exit']); + var comment = wordRegexp(['rem']); + + + function indent(_stream, state) { + state.currentIndent++; + } + + function dedent(_stream, state) { + state.currentIndent--; + } + // tokenizers + function tokenBase(stream, state) { + if (stream.eatSpace()) { + return 'space'; + //return null; + } + + var ch = stream.peek(); + + // Handle Comments + if (ch === "'") { + stream.skipToEnd(); + return 'comment'; + } + if (stream.match(comment)){ + stream.skipToEnd(); + return 'comment'; + } + + + // Handle Number Literals + if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) { + var floatLiteral = false; + // Floats + if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; } + else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; } + else if (stream.match(/^\.\d+/)) { floatLiteral = true; } + + if (floatLiteral) { + // Float literals may be "imaginary" + stream.eat(/J/i); + return 'number'; + } + // Integers + var intLiteral = false; + // Hex + if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; } + // Octal + else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; } + // Decimal + else if (stream.match(/^[1-9]\d*F?/)) { + // Decimal literals may be "imaginary" + stream.eat(/J/i); + // TODO - Can you have imaginary longs? + intLiteral = true; + } + // Zero by itself with no other piece of number. + else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } + if (intLiteral) { + // Integer literals may be "long" + stream.eat(/L/i); + return 'number'; + } + } + + // Handle Strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } + + // Handle operators and Delimiters + if (stream.match(doubleOperators) + || stream.match(singleOperators) + || stream.match(wordOperators)) { + return 'operator'; + } + if (stream.match(singleDelimiters)) { + return null; + } + + if (stream.match(brakets)) { + return "bracket"; + } + + if (stream.match(noIndentWords)) { + state.doInCurrentLine = true; + + return 'keyword'; + } + + if (stream.match(doOpening)) { + indent(stream,state); + state.doInCurrentLine = true; + + return 'keyword'; + } + if (stream.match(opening)) { + if (! state.doInCurrentLine) + indent(stream,state); + else + state.doInCurrentLine = false; + + return 'keyword'; + } + if (stream.match(middle)) { + return 'keyword'; + } + + + if (stream.match(doubleClosing)) { + dedent(stream,state); + dedent(stream,state); + + return 'keyword'; + } + if (stream.match(closing)) { + if (! state.doInCurrentLine) + dedent(stream,state); + else + state.doInCurrentLine = false; + + return 'keyword'; + } + + if (stream.match(keywords)) { + return 'keyword'; + } + + if (stream.match(atoms)) { + return 'atom'; + } + + if (stream.match(known)) { + return 'variable-2'; + } + + if (stream.match(builtinFuncs)) { + return 'builtin'; + } + + if (stream.match(builtinObjs)){ + return 'variable-2'; + } + + if (stream.match(identifiers)) { + return 'variable'; + } + + // Handle non-detected items + stream.next(); + return ERRORCLASS; + } + + function tokenStringFactory(delimiter) { + var singleline = delimiter.length == 1; + var OUTCLASS = 'string'; + + return function(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"]/); + if (stream.match(delimiter)) { + state.tokenize = tokenBase; + return OUTCLASS; + } else { + stream.eat(/['"]/); + } + } + if (singleline) { + if (parserConf.singleLineStringErrors) { + return ERRORCLASS; + } else { + state.tokenize = tokenBase; + } + } + return OUTCLASS; + }; + } + + + function tokenLexer(stream, state) { + var style = state.tokenize(stream, state); + var current = stream.current(); + + // Handle '.' connected identifiers + if (current === '.') { + style = state.tokenize(stream, state); + + current = stream.current(); + if (style && (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword')){//|| knownWords.indexOf(current.substring(1)) > -1) { + if (style === 'builtin' || style === 'keyword') style='variable'; + if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2'; + + return style; + } else { + return ERRORCLASS; + } + } + + return style; + } + + var external = { + electricChars:"dDpPtTfFeE ", + startState: function() { + return { + tokenize: tokenBase, + lastToken: null, + currentIndent: 0, + nextLineIndent: 0, + doInCurrentLine: false, + ignoreKeyword: false + + + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + state.currentIndent += state.nextLineIndent; + state.nextLineIndent = 0; + state.doInCurrentLine = 0; + } + var style = tokenLexer(stream, state); + + state.lastToken = {style:style, content: stream.current()}; + + if (style==='space') style=null; + + return style; + }, + + indent: function(state, textAfter) { + var trueText = textAfter.replace(/^\s+|\s+$/g, '') ; + if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1); + if(state.currentIndent < 0) return 0; + return state.currentIndent * conf.indentUnit; + } + + }; + return external; +}); + +CodeMirror.defineMIME("text/vbscript", "vbscript"); + +}); diff --git a/backend/webif/static/codemirror/mode/velocity/index.html b/backend/webif/static/codemirror/mode/velocity/index.html new file mode 100755 index 000000000..7eba8f418 --- /dev/null +++ b/backend/webif/static/codemirror/mode/velocity/index.html @@ -0,0 +1,120 @@ + + +CodeMirror: Velocity mode + + + + + + + + + + +
    +

    Velocity mode

    +
    + + +

    MIME types defined: text/velocity.

    + +
    diff --git a/backend/webif/static/codemirror/mode/velocity/velocity.js b/backend/webif/static/codemirror/mode/velocity/velocity.js new file mode 100755 index 000000000..12ee22124 --- /dev/null +++ b/backend/webif/static/codemirror/mode/velocity/velocity.js @@ -0,0 +1,201 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("velocity", function() { + function parseWords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var keywords = parseWords("#end #else #break #stop #[[ #]] " + + "#{end} #{else} #{break} #{stop}"); + var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " + + "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}"); + var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent.count $foreach.parent.hasNext $foreach.parent.first $foreach.parent.last $foreach.parent $velocityCount $!bodyContent $bodyContent"); + var isOperatorChar = /[+\-*&%=<>!?:\/|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + function tokenBase(stream, state) { + var beforeParams = state.beforeParams; + state.beforeParams = false; + var ch = stream.next(); + // start of unparsed string? + if ((ch == "'") && !state.inString && state.inParams) { + state.lastTokenWasBuiltin = false; + return chain(stream, state, tokenString(ch)); + } + // start of parsed string? + else if ((ch == '"')) { + state.lastTokenWasBuiltin = false; + if (state.inString) { + state.inString = false; + return "string"; + } + else if (state.inParams) + return chain(stream, state, tokenString(ch)); + } + // is it one of the special signs []{}().,;? Seperator? + else if (/[\[\]{}\(\),;\.]/.test(ch)) { + if (ch == "(" && beforeParams) + state.inParams = true; + else if (ch == ")") { + state.inParams = false; + state.lastTokenWasBuiltin = true; + } + return null; + } + // start of a number value? + else if (/\d/.test(ch)) { + state.lastTokenWasBuiltin = false; + stream.eatWhile(/[\w\.]/); + return "number"; + } + // multi line comment? + else if (ch == "#" && stream.eat("*")) { + state.lastTokenWasBuiltin = false; + return chain(stream, state, tokenComment); + } + // unparsed content? + else if (ch == "#" && stream.match(/ *\[ *\[/)) { + state.lastTokenWasBuiltin = false; + return chain(stream, state, tokenUnparsed); + } + // single line comment? + else if (ch == "#" && stream.eat("#")) { + state.lastTokenWasBuiltin = false; + stream.skipToEnd(); + return "comment"; + } + // variable? + else if (ch == "$") { + stream.eatWhile(/[\w\d\$_\.{}]/); + // is it one of the specials? + if (specials && specials.propertyIsEnumerable(stream.current())) { + return "keyword"; + } + else { + state.lastTokenWasBuiltin = true; + state.beforeParams = true; + return "builtin"; + } + } + // is it a operator? + else if (isOperatorChar.test(ch)) { + state.lastTokenWasBuiltin = false; + stream.eatWhile(isOperatorChar); + return "operator"; + } + else { + // get the whole word + stream.eatWhile(/[\w\$_{}@]/); + var word = stream.current(); + // is it one of the listed keywords? + if (keywords && keywords.propertyIsEnumerable(word)) + return "keyword"; + // is it one of the listed functions? + if (functions && functions.propertyIsEnumerable(word) || + (stream.current().match(/^#@?[a-z0-9_]+ *$/i) && stream.peek()=="(") && + !(functions && functions.propertyIsEnumerable(word.toLowerCase()))) { + state.beforeParams = true; + state.lastTokenWasBuiltin = false; + return "keyword"; + } + if (state.inString) { + state.lastTokenWasBuiltin = false; + return "string"; + } + if (stream.pos > word.length && stream.string.charAt(stream.pos-word.length-1)=="." && state.lastTokenWasBuiltin) + return "builtin"; + // default: just a "word" + state.lastTokenWasBuiltin = false; + return null; + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if ((next == quote) && !escaped) { + end = true; + break; + } + if (quote=='"' && stream.peek() == '$' && !escaped) { + state.inString = true; + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end) state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "#" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function tokenUnparsed(stream, state) { + var maybeEnd = 0, ch; + while (ch = stream.next()) { + if (ch == "#" && maybeEnd == 2) { + state.tokenize = tokenBase; + break; + } + if (ch == "]") + maybeEnd++; + else if (ch != " ") + maybeEnd = 0; + } + return "meta"; + } + // Interface + + return { + startState: function() { + return { + tokenize: tokenBase, + beforeParams: false, + inParams: false, + inString: false, + lastTokenWasBuiltin: false + }; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + }, + blockCommentStart: "#*", + blockCommentEnd: "*#", + lineComment: "##", + fold: "velocity" + }; +}); + +CodeMirror.defineMIME("text/velocity", "velocity"); + +}); diff --git a/backend/webif/static/codemirror/mode/verilog/index.html b/backend/webif/static/codemirror/mode/verilog/index.html new file mode 100755 index 000000000..9c52722af --- /dev/null +++ b/backend/webif/static/codemirror/mode/verilog/index.html @@ -0,0 +1,120 @@ + + +CodeMirror: Verilog/SystemVerilog mode + + + + + + + + + + +
    +

    SystemVerilog mode

    + +
    + + + +

    +Syntax highlighting and indentation for the Verilog and SystemVerilog languages (IEEE 1800). +

    Configuration options:

    +
      +
    • noIndentKeywords - List of keywords which should not cause indentation to increase. E.g. ["package", "module"]. Default: None
    • +
    +

    + +

    MIME types defined: text/x-verilog and text/x-systemverilog.

    +
    diff --git a/backend/webif/static/codemirror/mode/verilog/test.js b/backend/webif/static/codemirror/mode/verilog/test.js new file mode 100755 index 000000000..8334fab05 --- /dev/null +++ b/backend/webif/static/codemirror/mode/verilog/test.js @@ -0,0 +1,273 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 4}, "verilog"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("binary_literals", + "[number 1'b0]", + "[number 1'b1]", + "[number 1'bx]", + "[number 1'bz]", + "[number 1'bX]", + "[number 1'bZ]", + "[number 1'B0]", + "[number 1'B1]", + "[number 1'Bx]", + "[number 1'Bz]", + "[number 1'BX]", + "[number 1'BZ]", + "[number 1'b0]", + "[number 1'b1]", + "[number 2'b01]", + "[number 2'bxz]", + "[number 2'b11]", + "[number 2'b10]", + "[number 2'b1Z]", + "[number 12'b0101_0101_0101]", + "[number 1'b 0]", + "[number 'b0101]" + ); + + MT("octal_literals", + "[number 3'o7]", + "[number 3'O7]", + "[number 3'so7]", + "[number 3'SO7]" + ); + + MT("decimal_literals", + "[number 0]", + "[number 1]", + "[number 7]", + "[number 123_456]", + "[number 'd33]", + "[number 8'd255]", + "[number 8'D255]", + "[number 8'sd255]", + "[number 8'SD255]", + "[number 32'd123]", + "[number 32 'd123]", + "[number 32 'd 123]" + ); + + MT("hex_literals", + "[number 4'h0]", + "[number 4'ha]", + "[number 4'hF]", + "[number 4'hx]", + "[number 4'hz]", + "[number 4'hX]", + "[number 4'hZ]", + "[number 32'hdc78]", + "[number 32'hDC78]", + "[number 32 'hDC78]", + "[number 32'h DC78]", + "[number 32 'h DC78]", + "[number 32'h44x7]", + "[number 32'hFFF?]" + ); + + MT("real_number_literals", + "[number 1.2]", + "[number 0.1]", + "[number 2394.26331]", + "[number 1.2E12]", + "[number 1.2e12]", + "[number 1.30e-2]", + "[number 0.1e-0]", + "[number 23E10]", + "[number 29E-2]", + "[number 236.123_763_e-12]" + ); + + MT("operators", + "[meta ^]" + ); + + MT("keywords", + "[keyword logic]", + "[keyword logic] [variable foo]", + "[keyword reg] [variable abc]" + ); + + MT("variables", + "[variable _leading_underscore]", + "[variable _if]", + "[number 12] [variable foo]", + "[variable foo] [number 14]" + ); + + MT("tick_defines", + "[def `FOO]", + "[def `foo]", + "[def `FOO_bar]" + ); + + MT("system_calls", + "[meta $display]", + "[meta $vpi_printf]" + ); + + MT("line_comment", "[comment // Hello world]"); + + // Alignment tests + MT("align_port_map_style1", + /** + * mod mod(.a(a), + * .b(b) + * ); + */ + "[variable mod] [variable mod][bracket (].[variable a][bracket (][variable a][bracket )],", + " .[variable b][bracket (][variable b][bracket )]", + " [bracket )];", + "" + ); + + MT("align_port_map_style2", + /** + * mod mod( + * .a(a), + * .b(b) + * ); + */ + "[variable mod] [variable mod][bracket (]", + " .[variable a][bracket (][variable a][bracket )],", + " .[variable b][bracket (][variable b][bracket )]", + "[bracket )];", + "" + ); + + // Indentation tests + MT("indent_single_statement_if", + "[keyword if] [bracket (][variable foo][bracket )]", + " [keyword break];", + "" + ); + + MT("no_indent_after_single_line_if", + "[keyword if] [bracket (][variable foo][bracket )] [keyword break];", + "" + ); + + MT("indent_after_if_begin_same_line", + "[keyword if] [bracket (][variable foo][bracket )] [keyword begin]", + " [keyword break];", + " [keyword break];", + "[keyword end]", + "" + ); + + MT("indent_after_if_begin_next_line", + "[keyword if] [bracket (][variable foo][bracket )]", + " [keyword begin]", + " [keyword break];", + " [keyword break];", + " [keyword end]", + "" + ); + + MT("indent_single_statement_if_else", + "[keyword if] [bracket (][variable foo][bracket )]", + " [keyword break];", + "[keyword else]", + " [keyword break];", + "" + ); + + MT("indent_if_else_begin_same_line", + "[keyword if] [bracket (][variable foo][bracket )] [keyword begin]", + " [keyword break];", + " [keyword break];", + "[keyword end] [keyword else] [keyword begin]", + " [keyword break];", + " [keyword break];", + "[keyword end]", + "" + ); + + MT("indent_if_else_begin_next_line", + "[keyword if] [bracket (][variable foo][bracket )]", + " [keyword begin]", + " [keyword break];", + " [keyword break];", + " [keyword end]", + "[keyword else]", + " [keyword begin]", + " [keyword break];", + " [keyword break];", + " [keyword end]", + "" + ); + + MT("indent_if_nested_without_begin", + "[keyword if] [bracket (][variable foo][bracket )]", + " [keyword if] [bracket (][variable foo][bracket )]", + " [keyword if] [bracket (][variable foo][bracket )]", + " [keyword break];", + "" + ); + + MT("indent_case", + "[keyword case] [bracket (][variable state][bracket )]", + " [variable FOO]:", + " [keyword break];", + " [variable BAR]:", + " [keyword break];", + "[keyword endcase]", + "" + ); + + MT("unindent_after_end_with_preceding_text", + "[keyword begin]", + " [keyword break]; [keyword end]", + "" + ); + + MT("export_function_one_line_does_not_indent", + "[keyword export] [string \"DPI-C\"] [keyword function] [variable helloFromSV];", + "" + ); + + MT("export_task_one_line_does_not_indent", + "[keyword export] [string \"DPI-C\"] [keyword task] [variable helloFromSV];", + "" + ); + + MT("export_function_two_lines_indents_properly", + "[keyword export]", + " [string \"DPI-C\"] [keyword function] [variable helloFromSV];", + "" + ); + + MT("export_task_two_lines_indents_properly", + "[keyword export]", + " [string \"DPI-C\"] [keyword task] [variable helloFromSV];", + "" + ); + + MT("import_function_one_line_does_not_indent", + "[keyword import] [string \"DPI-C\"] [keyword function] [variable helloFromC];", + "" + ); + + MT("import_task_one_line_does_not_indent", + "[keyword import] [string \"DPI-C\"] [keyword task] [variable helloFromC];", + "" + ); + + MT("import_package_single_line_does_not_indent", + "[keyword import] [variable p]::[variable x];", + "[keyword import] [variable p]::[variable y];", + "" + ); + + MT("covergroup_with_function_indents_properly", + "[keyword covergroup] [variable cg] [keyword with] [keyword function] [variable sample][bracket (][keyword bit] [variable b][bracket )];", + " [variable c] : [keyword coverpoint] [variable c];", + "[keyword endgroup]: [variable cg]", + "" + ); + +})(); diff --git a/backend/webif/static/codemirror/mode/verilog/verilog.js b/backend/webif/static/codemirror/mode/verilog/verilog.js new file mode 100755 index 000000000..340468609 --- /dev/null +++ b/backend/webif/static/codemirror/mode/verilog/verilog.js @@ -0,0 +1,675 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("verilog", function(config, parserConfig) { + + var indentUnit = config.indentUnit, + statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, + dontAlignCalls = parserConfig.dontAlignCalls, + noIndentKeywords = parserConfig.noIndentKeywords || [], + multiLineStrings = parserConfig.multiLineStrings, + hooks = parserConfig.hooks || {}; + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + /** + * Keywords from IEEE 1800-2012 + */ + var keywords = words( + "accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind " + + "bins binsof bit break buf bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config " + + "const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable " + + "dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup " + + "endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask " + + "enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin " + + "function generate genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import " + + "incdir include initial inout input inside instance int integer interconnect interface intersect join join_any " + + "join_none large let liblist library local localparam logic longint macromodule matches medium modport module " + + "nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 null or output package packed " + + "parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup " + + "pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg " + + "reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime " + + "s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify " + + "specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on " + + "table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior " + + "trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void " + + "wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor"); + + /** Operators from IEEE 1800-2012 + unary_operator ::= + + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ + binary_operator ::= + + | - | * | / | % | == | != | === | !== | ==? | !=? | && | || | ** + | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<< + | -> | <-> + inc_or_dec_operator ::= ++ | -- + unary_module_path_operator ::= + ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ + binary_module_path_operator ::= + == | != | && | || | & | | | ^ | ^~ | ~^ + */ + var isOperatorChar = /[\+\-\*\/!~&|^%=?:]/; + var isBracketChar = /[\[\]{}()]/; + + var unsignedNumber = /\d[0-9_]*/; + var decimalLiteral = /\d*\s*'s?d\s*\d[0-9_]*/i; + var binaryLiteral = /\d*\s*'s?b\s*[xz01][xz01_]*/i; + var octLiteral = /\d*\s*'s?o\s*[xz0-7][xz0-7_]*/i; + var hexLiteral = /\d*\s*'s?h\s*[0-9a-fxz?][0-9a-fxz?_]*/i; + var realLiteral = /(\d[\d_]*(\.\d[\d_]*)?E-?[\d_]+)|(\d[\d_]*\.\d[\d_]*)/i; + + var closingBracketOrWord = /^((\w+)|[)}\]])/; + var closingBracket = /[)}\]]/; + + var curPunc; + var curKeyword; + + // Block openings which are closed by a matching keyword in the form of ("end" + keyword) + // E.g. "task" => "endtask" + var blockKeywords = words( + "case checker class clocking config function generate interface module package " + + "primitive program property specify sequence table task" + ); + + // Opening/closing pairs + var openClose = {}; + for (var keyword in blockKeywords) { + openClose[keyword] = "end" + keyword; + } + openClose["begin"] = "end"; + openClose["casex"] = "endcase"; + openClose["casez"] = "endcase"; + openClose["do" ] = "while"; + openClose["fork" ] = "join;join_any;join_none"; + openClose["covergroup"] = "endgroup"; + + for (var i in noIndentKeywords) { + var keyword = noIndentKeywords[i]; + if (openClose[keyword]) { + openClose[keyword] = undefined; + } + } + + // Keywords which open statements that are ended with a semi-colon + var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while"); + + function tokenBase(stream, state) { + var ch = stream.peek(), style; + if (hooks[ch] && (style = hooks[ch](stream, state)) != false) return style; + if (hooks.tokenBase && (style = hooks.tokenBase(stream, state)) != false) + return style; + + if (/[,;:\.]/.test(ch)) { + curPunc = stream.next(); + return null; + } + if (isBracketChar.test(ch)) { + curPunc = stream.next(); + return "bracket"; + } + // Macros (tick-defines) + if (ch == '`') { + stream.next(); + if (stream.eatWhile(/[\w\$_]/)) { + return "def"; + } else { + return null; + } + } + // System calls + if (ch == '$') { + stream.next(); + if (stream.eatWhile(/[\w\$_]/)) { + return "meta"; + } else { + return null; + } + } + // Time literals + if (ch == '#') { + stream.next(); + stream.eatWhile(/[\d_.]/); + return "def"; + } + // Strings + if (ch == '"') { + stream.next(); + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + // Comments + if (ch == "/") { + stream.next(); + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + stream.backUp(1); + } + + // Numeric literals + if (stream.match(realLiteral) || + stream.match(decimalLiteral) || + stream.match(binaryLiteral) || + stream.match(octLiteral) || + stream.match(hexLiteral) || + stream.match(unsignedNumber) || + stream.match(realLiteral)) { + return "number"; + } + + // Operators + if (stream.eatWhile(isOperatorChar)) { + return "meta"; + } + + // Keywords / plain variables + if (stream.eatWhile(/[\w\$_]/)) { + var cur = stream.current(); + if (keywords[cur]) { + if (openClose[cur]) { + curPunc = "newblock"; + } + if (statementKeywords[cur]) { + curPunc = "newstatement"; + } + curKeyword = cur; + return "keyword"; + } + return "variable"; + } + + stream.next(); + return null; + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return "comment"; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + function pushContext(state, col, type) { + var indent = state.indented; + var c = new Context(indent, col, type, null, state.context); + return state.context = c; + } + function popContext(state) { + var t = state.context.type; + if (t == ")" || t == "]" || t == "}") { + state.indented = state.context.indented; + } + return state.context = state.context.prev; + } + + function isClosing(text, contextClosing) { + if (text == contextClosing) { + return true; + } else { + // contextClosing may be multiple keywords separated by ; + var closingKeywords = contextClosing.split(";"); + for (var i in closingKeywords) { + if (text == closingKeywords[i]) { + return true; + } + } + return false; + } + } + + function buildElectricInputRegEx() { + // Reindentation should occur on any bracket char: {}()[] + // or on a match of any of the block closing keywords, at + // the end of a line + var allClosings = []; + for (var i in openClose) { + if (openClose[i]) { + var closings = openClose[i].split(";"); + for (var j in closings) { + allClosings.push(closings[j]); + } + } + } + var re = new RegExp("[{}()\\[\\]]|(" + allClosings.join("|") + ")$"); + return re; + } + + // Interface + return { + + // Regex to force current line to reindent + electricInput: buildElectricInputRegEx(), + + startState: function(basecolumn) { + var state = { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + if (hooks.startState) hooks.startState(state); + return state; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (hooks.token) { + // Call hook, with an optional return value of a style to override verilog styling. + var style = hooks.token(stream, state); + if (style !== undefined) { + return style; + } + } + if (stream.eatSpace()) return null; + curPunc = null; + curKeyword = null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta" || style == "variable") return style; + if (ctx.align == null) ctx.align = true; + + if (curPunc == ctx.type) { + popContext(state); + } else if ((curPunc == ";" && ctx.type == "statement") || + (ctx.type && isClosing(curKeyword, ctx.type))) { + ctx = popContext(state); + while (ctx && ctx.type == "statement") ctx = popContext(state); + } else if (curPunc == "{") { + pushContext(state, stream.column(), "}"); + } else if (curPunc == "[") { + pushContext(state, stream.column(), "]"); + } else if (curPunc == "(") { + pushContext(state, stream.column(), ")"); + } else if (ctx && ctx.type == "endcase" && curPunc == ":") { + pushContext(state, stream.column(), "statement"); + } else if (curPunc == "newstatement") { + pushContext(state, stream.column(), "statement"); + } else if (curPunc == "newblock") { + if (curKeyword == "function" && ctx && (ctx.type == "statement" || ctx.type == "endgroup")) { + // The 'function' keyword can appear in some other contexts where it actually does not + // indicate a function (import/export DPI and covergroup definitions). + // Do nothing in this case + } else if (curKeyword == "task" && ctx && ctx.type == "statement") { + // Same thing for task + } else { + var close = openClose[curKeyword]; + pushContext(state, stream.column(), close); + } + } + + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; + if (hooks.indent) { + var fromHook = hooks.indent(state); + if (fromHook >= 0) return fromHook; + } + var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); + if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; + var closing = false; + var possibleClosing = textAfter.match(closingBracketOrWord); + if (possibleClosing) + closing = isClosing(possibleClosing[0], ctx.type); + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); + else if (closingBracket.test(ctx.type) && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1); + else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit; + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; +}); + + CodeMirror.defineMIME("text/x-verilog", { + name: "verilog" + }); + + CodeMirror.defineMIME("text/x-systemverilog", { + name: "verilog" + }); + + + + // TL-Verilog mode. + // See tl-x.org for language spec. + // See the mode in action at makerchip.com. + // Contact: steve.hoover@redwoodeda.com + + // TLV Identifier prefixes. + // Note that sign is not treated separately, so "+/-" versions of numeric identifiers + // are included. + var tlvIdentifierStyle = { + "|": "link", + ">": "property", // Should condition this off for > TLV 1c. + "$": "variable", + "$$": "variable", + "?$": "qualifier", + "?*": "qualifier", + "-": "hr", + "/": "property", + "/-": "property", + "@": "variable-3", + "@-": "variable-3", + "@++": "variable-3", + "@+=": "variable-3", + "@+=-": "variable-3", + "@--": "variable-3", + "@-=": "variable-3", + "%+": "tag", + "%-": "tag", + "%": "tag", + ">>": "tag", + "<<": "tag", + "<>": "tag", + "#": "tag", // Need to choose a style for this. + "^": "attribute", + "^^": "attribute", + "^!": "attribute", + "*": "variable-2", + "**": "variable-2", + "\\": "keyword", + "\"": "comment" + }; + + // Lines starting with these characters define scope (result in indentation). + var tlvScopePrefixChars = { + "/": "beh-hier", + ">": "beh-hier", + "-": "phys-hier", + "|": "pipe", + "?": "when", + "@": "stage", + "\\": "keyword" + }; + var tlvIndentUnit = 3; + var tlvTrackStatements = false; + var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/; // Matches an identifiere. + // Note that ':' is excluded, because of it's use in [:]. + var tlvFirstLevelIndentMatch = /^[! ] /; + var tlvLineIndentationMatch = /^[! ] */; + var tlvCommentMatch = /^\/[\/\*]/; + + + // Returns a style specific to the scope at the given indentation column. + // Type is one of: "indent", "scope-ident", "before-scope-ident". + function tlvScopeStyle(state, indentation, type) { + // Begin scope. + var depth = indentation / tlvIndentUnit; // TODO: Pass this in instead. + return "tlv-" + state.tlvIndentationStyle[depth] + "-" + type; + } + + // Return true if the next thing in the stream is an identifier with a mnemonic. + function tlvIdentNext(stream) { + var match; + return (match = stream.match(tlvIdentMatch, false)) && match[2].length > 0; + } + + CodeMirror.defineMIME("text/x-tlv", { + name: "verilog", + + hooks: { + + electricInput: false, + + + // Return undefined for verilog tokenizing, or style for TLV token (null not used). + // Standard CM styles are used for most formatting, but some TL-Verilog-specific highlighting + // can be enabled with the definition of cm-tlv-* styles, including highlighting for: + // - M4 tokens + // - TLV scope indentation + // - Statement delimitation (enabled by tlvTrackStatements) + token: function(stream, state) { + var style = undefined; + var match; // Return value of pattern matches. + + // Set highlighting mode based on code region (TLV or SV). + if (stream.sol() && ! state.tlvInBlockComment) { + // Process region. + if (stream.peek() == '\\') { + style = "def"; + stream.skipToEnd(); + if (stream.string.match(/\\SV/)) { + state.tlvCodeActive = false; + } else if (stream.string.match(/\\TLV/)){ + state.tlvCodeActive = true; + } + } + // Correct indentation in the face of a line prefix char. + if (state.tlvCodeActive && stream.pos == 0 && + (state.indented == 0) && (match = stream.match(tlvLineIndentationMatch, false))) { + state.indented = match[0].length; + } + + // Compute indentation state: + // o Auto indentation on next line + // o Indentation scope styles + var indented = state.indented; + var depth = indented / tlvIndentUnit; + if (depth <= state.tlvIndentationStyle.length) { + // not deeper than current scope + + var blankline = stream.string.length == indented; + var chPos = depth * tlvIndentUnit; + if (chPos < stream.string.length) { + var bodyString = stream.string.slice(chPos); + var ch = bodyString[0]; + if (tlvScopePrefixChars[ch] && ((match = bodyString.match(tlvIdentMatch)) && + tlvIdentifierStyle[match[1]])) { + // This line begins scope. + // Next line gets indented one level. + indented += tlvIndentUnit; + // Style the next level of indentation (except non-region keyword identifiers, + // which are statements themselves) + if (!(ch == "\\" && chPos > 0)) { + state.tlvIndentationStyle[depth] = tlvScopePrefixChars[ch]; + if (tlvTrackStatements) {state.statementComment = false;} + depth++; + } + } + } + // Clear out deeper indentation levels unless line is blank. + if (!blankline) { + while (state.tlvIndentationStyle.length > depth) { + state.tlvIndentationStyle.pop(); + } + } + } + // Set next level of indentation. + state.tlvNextIndent = indented; + } + + if (state.tlvCodeActive) { + // Highlight as TLV. + + var beginStatement = false; + if (tlvTrackStatements) { + // This starts a statement if the position is at the scope level + // and we're not within a statement leading comment. + beginStatement = + (stream.peek() != " ") && // not a space + (style === undefined) && // not a region identifier + !state.tlvInBlockComment && // not in block comment + //!stream.match(tlvCommentMatch, false) && // not comment start + (stream.column() == state.tlvIndentationStyle.length * tlvIndentUnit); // at scope level + if (beginStatement) { + if (state.statementComment) { + // statement already started by comment + beginStatement = false; + } + state.statementComment = + stream.match(tlvCommentMatch, false); // comment start + } + } + + var match; + if (style !== undefined) { + // Region line. + style += " " + tlvScopeStyle(state, 0, "scope-ident") + } else if (((stream.pos / tlvIndentUnit) < state.tlvIndentationStyle.length) && + (match = stream.match(stream.sol() ? tlvFirstLevelIndentMatch : /^ /))) { + // Indentation + style = // make this style distinct from the previous one to prevent + // codemirror from combining spans + "tlv-indent-" + (((stream.pos % 2) == 0) ? "even" : "odd") + + // and style it + " " + tlvScopeStyle(state, stream.pos - tlvIndentUnit, "indent"); + // Style the line prefix character. + if (match[0].charAt(0) == "!") { + style += " tlv-alert-line-prefix"; + } + // Place a class before a scope identifier. + if (tlvIdentNext(stream)) { + style += " " + tlvScopeStyle(state, stream.pos, "before-scope-ident"); + } + } else if (state.tlvInBlockComment) { + // In a block comment. + if (stream.match(/^.*?\*\//)) { + // Exit block comment. + state.tlvInBlockComment = false; + if (tlvTrackStatements && !stream.eol()) { + // Anything after comment is assumed to be real statement content. + state.statementComment = false; + } + } else { + stream.skipToEnd(); + } + style = "comment"; + } else if ((match = stream.match(tlvCommentMatch)) && !state.tlvInBlockComment) { + // Start comment. + if (match[0] == "//") { + // Line comment. + stream.skipToEnd(); + } else { + // Block comment. + state.tlvInBlockComment = true; + } + style = "comment"; + } else if (match = stream.match(tlvIdentMatch)) { + // looks like an identifier (or identifier prefix) + var prefix = match[1]; + var mnemonic = match[2]; + if (// is identifier prefix + tlvIdentifierStyle.hasOwnProperty(prefix) && + // has mnemonic or we're at the end of the line (maybe it hasn't been typed yet) + (mnemonic.length > 0 || stream.eol())) { + style = tlvIdentifierStyle[prefix]; + if (stream.column() == state.indented) { + // Begin scope. + style += " " + tlvScopeStyle(state, stream.column(), "scope-ident") + } + } else { + // Just swallow one character and try again. + // This enables subsequent identifier match with preceding symbol character, which + // is legal within a statement. (Eg, !$reset). It also enables detection of + // comment start with preceding symbols. + stream.backUp(stream.current().length - 1); + style = "tlv-default"; + } + } else if (stream.match(/^\t+/)) { + // Highlight tabs, which are illegal. + style = "tlv-tab"; + } else if (stream.match(/^[\[\]{}\(\);\:]+/)) { + // [:], (), {}, ;. + style = "meta"; + } else if (match = stream.match(/^[mM]4([\+_])?[\w\d_]*/)) { + // m4 pre proc + style = (match[1] == "+") ? "tlv-m4-plus" : "tlv-m4"; + } else if (stream.match(/^ +/)){ + // Skip over spaces. + if (stream.eol()) { + // Trailing spaces. + style = "error"; + } else { + // Non-trailing spaces. + style = "tlv-default"; + } + } else if (stream.match(/^[\w\d_]+/)) { + // alpha-numeric token. + style = "number"; + } else { + // Eat the next char w/ no formatting. + stream.next(); + style = "tlv-default"; + } + if (beginStatement) { + style += " tlv-statement"; + } + } else { + if (stream.match(/^[mM]4([\w\d_]*)/)) { + // m4 pre proc + style = "tlv-m4"; + } + } + return style; + }, + + indent: function(state) { + return (state.tlvCodeActive == true) ? state.tlvNextIndent : -1; + }, + + startState: function(state) { + state.tlvIndentationStyle = []; // Styles to use for each level of indentation. + state.tlvCodeActive = true; // True when we're in a TLV region (and at beginning of file). + state.tlvNextIndent = -1; // The number of spaces to autoindent the next line if tlvCodeActive. + state.tlvInBlockComment = false; // True inside /**/ comment. + if (tlvTrackStatements) { + state.statementComment = false; // True inside a statement's header comment. + } + } + + } + }); +}); diff --git a/backend/webif/static/codemirror/mode/vhdl/index.html b/backend/webif/static/codemirror/mode/vhdl/index.html new file mode 100755 index 000000000..3051bc37e --- /dev/null +++ b/backend/webif/static/codemirror/mode/vhdl/index.html @@ -0,0 +1,95 @@ + + +CodeMirror: VHDL mode + + + + + + + + + + +
    +

    VHDL mode

    + +
    + + + +

    +Syntax highlighting and indentation for the VHDL language. +

    Configuration options:

    +
      +
    • atoms - List of atom words. Default: "null"
    • +
    • hooks - List of meta hooks. Default: ["`", "$"]
    • +
    • multiLineStrings - Whether multi-line strings are accepted. Default: false
    • +
    +

    + +

    MIME types defined: text/x-vhdl.

    +
    diff --git a/backend/webif/static/codemirror/mode/vhdl/vhdl.js b/backend/webif/static/codemirror/mode/vhdl/vhdl.js new file mode 100755 index 000000000..97e086e42 --- /dev/null +++ b/backend/webif/static/codemirror/mode/vhdl/vhdl.js @@ -0,0 +1,189 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Originally written by Alf Nielsen, re-written by Michael Zhou +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +function words(str) { + var obj = {}, words = str.split(","); + for (var i = 0; i < words.length; ++i) { + var allCaps = words[i].toUpperCase(); + var firstCap = words[i].charAt(0).toUpperCase() + words[i].slice(1); + obj[words[i]] = true; + obj[allCaps] = true; + obj[firstCap] = true; + } + return obj; +} + +function metaHook(stream) { + stream.eatWhile(/[\w\$_]/); + return "meta"; +} + +CodeMirror.defineMode("vhdl", function(config, parserConfig) { + var indentUnit = config.indentUnit, + atoms = parserConfig.atoms || words("null"), + hooks = parserConfig.hooks || {"`": metaHook, "$": metaHook}, + multiLineStrings = parserConfig.multiLineStrings; + + var keywords = words("abs,access,after,alias,all,and,architecture,array,assert,attribute,begin,block," + + "body,buffer,bus,case,component,configuration,constant,disconnect,downto,else,elsif,end,end block,end case," + + "end component,end for,end generate,end if,end loop,end process,end record,end units,entity,exit,file,for," + + "function,generate,generic,generic map,group,guarded,if,impure,in,inertial,inout,is,label,library,linkage," + + "literal,loop,map,mod,nand,new,next,nor,null,of,on,open,or,others,out,package,package body,port,port map," + + "postponed,procedure,process,pure,range,record,register,reject,rem,report,return,rol,ror,select,severity,signal," + + "sla,sll,sra,srl,subtype,then,to,transport,type,unaffected,units,until,use,variable,wait,when,while,with,xnor,xor"); + + var blockKeywords = words("architecture,entity,begin,case,port,else,elsif,end,for,function,if"); + + var isOperatorChar = /[&|~> + +CodeMirror: Vue.js mode + + + + + + + + + + + + + + + + + + + + + +
    +

    Vue.js mode

    +
    + + +

    MIME types defined: text/x-vue

    + +
    diff --git a/backend/webif/static/codemirror/mode/vue/vue.js b/backend/webif/static/codemirror/mode/vue/vue.js new file mode 100755 index 000000000..84cd07c9a --- /dev/null +++ b/backend/webif/static/codemirror/mode/vue/vue.js @@ -0,0 +1,77 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function (mod) { + "use strict"; + if (typeof exports === "object" && typeof module === "object") {// CommonJS + mod(require("../../lib/codemirror"), + require("../../addon/mode/overlay"), + require("../xml/xml"), + require("../javascript/javascript"), + require("../coffeescript/coffeescript"), + require("../css/css"), + require("../sass/sass"), + require("../stylus/stylus"), + require("../pug/pug"), + require("../handlebars/handlebars")); + } else if (typeof define === "function" && define.amd) { // AMD + define(["../../lib/codemirror", + "../../addon/mode/overlay", + "../xml/xml", + "../javascript/javascript", + "../coffeescript/coffeescript", + "../css/css", + "../sass/sass", + "../stylus/stylus", + "../pug/pug", + "../handlebars/handlebars"], mod); + } else { // Plain browser env + mod(CodeMirror); + } +})(function (CodeMirror) { + var tagLanguages = { + script: [ + ["lang", /coffee(script)?/, "coffeescript"], + ["type", /^(?:text|application)\/(?:x-)?coffee(?:script)?$/, "coffeescript"], + ["lang", /^babel$/, "javascript"], + ["type", /^text\/babel$/, "javascript"], + ["type", /^text\/ecmascript-\d+$/, "javascript"] + ], + style: [ + ["lang", /^stylus$/i, "stylus"], + ["lang", /^sass$/i, "sass"], + ["lang", /^less$/i, "text/x-less"], + ["lang", /^scss$/i, "text/x-scss"], + ["type", /^(text\/)?(x-)?styl(us)?$/i, "stylus"], + ["type", /^text\/sass/i, "sass"], + ["type", /^(text\/)?(x-)?scss$/i, "text/x-scss"], + ["type", /^(text\/)?(x-)?less$/i, "text/x-less"] + ], + template: [ + ["lang", /^vue-template$/i, "vue"], + ["lang", /^pug$/i, "pug"], + ["lang", /^handlebars$/i, "handlebars"], + ["type", /^(text\/)?(x-)?pug$/i, "pug"], + ["type", /^text\/x-handlebars-template$/i, "handlebars"], + [null, null, "vue-template"] + ] + }; + + CodeMirror.defineMode("vue-template", function (config, parserConfig) { + var mustacheOverlay = { + token: function (stream) { + if (stream.match(/^\{\{.*?\}\}/)) return "meta mustache"; + while (stream.next() && !stream.match("{{", false)) {} + return null; + } + }; + return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay); + }); + + CodeMirror.defineMode("vue", function (config) { + return CodeMirror.getMode(config, {name: "htmlmixed", tags: tagLanguages}); + }, "htmlmixed", "xml", "javascript", "coffeescript", "css", "sass", "stylus", "pug", "handlebars"); + + CodeMirror.defineMIME("script/x-vue", "vue"); + CodeMirror.defineMIME("text/x-vue", "vue"); +}); diff --git a/backend/webif/static/codemirror/mode/webidl/index.html b/backend/webif/static/codemirror/mode/webidl/index.html new file mode 100755 index 000000000..1d4112e1c --- /dev/null +++ b/backend/webif/static/codemirror/mode/webidl/index.html @@ -0,0 +1,71 @@ + + +CodeMirror: Web IDL mode + + + + + + + + + + +
    +

    Web IDL mode

    + +
    + +
    + + + +

    MIME type defined: text/x-webidl.

    +
    diff --git a/backend/webif/static/codemirror/mode/webidl/webidl.js b/backend/webif/static/codemirror/mode/webidl/webidl.js new file mode 100755 index 000000000..814333620 --- /dev/null +++ b/backend/webif/static/codemirror/mode/webidl/webidl.js @@ -0,0 +1,195 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); +}; + +var builtinArray = [ + "Clamp", + "Constructor", + "EnforceRange", + "Exposed", + "ImplicitThis", + "Global", "PrimaryGlobal", + "LegacyArrayClass", + "LegacyUnenumerableNamedProperties", + "LenientThis", + "NamedConstructor", + "NewObject", + "NoInterfaceObject", + "OverrideBuiltins", + "PutForwards", + "Replaceable", + "SameObject", + "TreatNonObjectAsNull", + "TreatNullAs", + "EmptyString", + "Unforgeable", + "Unscopeable" +]; +var builtins = wordRegexp(builtinArray); + +var typeArray = [ + "unsigned", "short", "long", // UnsignedIntegerType + "unrestricted", "float", "double", // UnrestrictedFloatType + "boolean", "byte", "octet", // Rest of PrimitiveType + "Promise", // PromiseType + "ArrayBuffer", "DataView", "Int8Array", "Int16Array", "Int32Array", + "Uint8Array", "Uint16Array", "Uint32Array", "Uint8ClampedArray", + "Float32Array", "Float64Array", // BufferRelatedType + "ByteString", "DOMString", "USVString", "sequence", "object", "RegExp", + "Error", "DOMException", "FrozenArray", // Rest of NonAnyType + "any", // Rest of SingleType + "void" // Rest of ReturnType +]; +var types = wordRegexp(typeArray); + +var keywordArray = [ + "attribute", "callback", "const", "deleter", "dictionary", "enum", "getter", + "implements", "inherit", "interface", "iterable", "legacycaller", "maplike", + "partial", "required", "serializer", "setlike", "setter", "static", + "stringifier", "typedef", // ArgumentNameKeyword except + // "unrestricted" + "optional", "readonly", "or" +]; +var keywords = wordRegexp(keywordArray); + +var atomArray = [ + "true", "false", // BooleanLiteral + "Infinity", "NaN", // FloatLiteral + "null" // Rest of ConstValue +]; +var atoms = wordRegexp(atomArray); + +CodeMirror.registerHelper("hintWords", "webidl", + builtinArray.concat(typeArray).concat(keywordArray).concat(atomArray)); + +var startDefArray = ["callback", "dictionary", "enum", "interface"]; +var startDefs = wordRegexp(startDefArray); + +var endDefArray = ["typedef"]; +var endDefs = wordRegexp(endDefArray); + +var singleOperators = /^[:<=>?]/; +var integers = /^-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/; +var floats = /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/; +var identifiers = /^_?[A-Za-z][0-9A-Z_a-z-]*/; +var identifiersEnd = /^_?[A-Za-z][0-9A-Z_a-z-]*(?=\s*;)/; +var strings = /^"[^"]*"/; +var multilineComments = /^\/\*.*?\*\//; +var multilineCommentsStart = /^\/\*.*/; +var multilineCommentsEnd = /^.*?\*\//; + +function readToken(stream, state) { + // whitespace + if (stream.eatSpace()) return null; + + // comment + if (state.inComment) { + if (stream.match(multilineCommentsEnd)) { + state.inComment = false; + return "comment"; + } + stream.skipToEnd(); + return "comment"; + } + if (stream.match("//")) { + stream.skipToEnd(); + return "comment"; + } + if (stream.match(multilineComments)) return "comment"; + if (stream.match(multilineCommentsStart)) { + state.inComment = true; + return "comment"; + } + + // integer and float + if (stream.match(/^-?[0-9\.]/, false)) { + if (stream.match(integers) || stream.match(floats)) return "number"; + } + + // string + if (stream.match(strings)) return "string"; + + // identifier + if (state.startDef && stream.match(identifiers)) return "def"; + + if (state.endDef && stream.match(identifiersEnd)) { + state.endDef = false; + return "def"; + } + + if (stream.match(keywords)) return "keyword"; + + if (stream.match(types)) { + var lastToken = state.lastToken; + var nextToken = (stream.match(/^\s*(.+?)\b/, false) || [])[1]; + + if (lastToken === ":" || lastToken === "implements" || + nextToken === "implements" || nextToken === "=") { + // Used as identifier + return "builtin"; + } else { + // Used as type + return "variable-3"; + } + } + + if (stream.match(builtins)) return "builtin"; + if (stream.match(atoms)) return "atom"; + if (stream.match(identifiers)) return "variable"; + + // other + if (stream.match(singleOperators)) return "operator"; + + // unrecognized + stream.next(); + return null; +}; + +CodeMirror.defineMode("webidl", function() { + return { + startState: function() { + return { + // Is in multiline comment + inComment: false, + // Last non-whitespace, matched token + lastToken: "", + // Next token is a definition + startDef: false, + // Last token of the statement is a definition + endDef: false + }; + }, + token: function(stream, state) { + var style = readToken(stream, state); + + if (style) { + var cur = stream.current(); + state.lastToken = cur; + if (style === "keyword") { + state.startDef = startDefs.test(cur); + state.endDef = state.endDef || endDefs.test(cur); + } else { + state.startDef = false; + } + } + + return style; + } + }; +}); + +CodeMirror.defineMIME("text/x-webidl", "webidl"); +}); diff --git a/backend/webif/static/codemirror/mode/xml/index.html b/backend/webif/static/codemirror/mode/xml/index.html new file mode 100755 index 000000000..c56b8b6eb --- /dev/null +++ b/backend/webif/static/codemirror/mode/xml/index.html @@ -0,0 +1,61 @@ + + +CodeMirror: XML mode + + + + + + + + + +
    +

    XML mode

    +
    + +

    The XML mode supports these configuration parameters:

    +
    +
    htmlMode (boolean)
    +
    This switches the mode to parse HTML instead of XML. This + means attributes do not have to be quoted, and some elements + (such as br) do not require a closing tag.
    +
    matchClosing (boolean)
    +
    Controls whether the mode checks that close tags match the + corresponding opening tag, and highlights mismatches as errors. + Defaults to true.
    +
    alignCDATA (boolean)
    +
    Setting this to true will force the opening tag of CDATA + blocks to not be indented.
    +
    + +

    MIME types defined: application/xml, text/html.

    +
    diff --git a/backend/webif/static/codemirror/mode/xml/test.js b/backend/webif/static/codemirror/mode/xml/test.js new file mode 100755 index 000000000..f48156b51 --- /dev/null +++ b/backend/webif/static/codemirror/mode/xml/test.js @@ -0,0 +1,51 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml"; + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); } + + MT("matching", + "[tag&bracket <][tag top][tag&bracket >]", + " text", + " [tag&bracket <][tag inner][tag&bracket />]", + "[tag&bracket ]"); + + MT("nonmatching", + "[tag&bracket <][tag top][tag&bracket >]", + " [tag&bracket <][tag inner][tag&bracket />]", + " [tag&bracket ]"); + + MT("doctype", + "[meta ]", + "[tag&bracket <][tag top][tag&bracket />]"); + + MT("cdata", + "[tag&bracket <][tag top][tag&bracket >]", + " [atom ]", + "[tag&bracket ]"); + + // HTML tests + mode = CodeMirror.getMode({indentUnit: 2}, "text/html"); + + MT("selfclose", + "[tag&bracket <][tag html][tag&bracket >]", + " [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]", + "[tag&bracket ]"); + + MT("list", + "[tag&bracket <][tag ol][tag&bracket >]", + " [tag&bracket <][tag li][tag&bracket >]one", + " [tag&bracket <][tag li][tag&bracket >]two", + "[tag&bracket ]"); + + MT("valueless", + "[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]"); + + MT("pThenArticle", + "[tag&bracket <][tag p][tag&bracket >]", + " foo", + "[tag&bracket <][tag article][tag&bracket >]bar"); + +})(); diff --git a/backend/webif/static/codemirror/mode/xml/xml.js b/backend/webif/static/codemirror/mode/xml/xml.js new file mode 100755 index 000000000..f987a3a3c --- /dev/null +++ b/backend/webif/static/codemirror/mode/xml/xml.js @@ -0,0 +1,394 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +var htmlConfig = { + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, + 'track': true, 'wbr': true, 'menuitem': true}, + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, + 'th': true, 'tr': true}, + contextGrabbers: { + 'dd': {'dd': true, 'dt': true}, + 'dt': {'dd': true, 'dt': true}, + 'li': {'li': true}, + 'option': {'option': true, 'optgroup': true}, + 'optgroup': {'optgroup': true}, + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, + 'rp': {'rp': true, 'rt': true}, + 'rt': {'rp': true, 'rt': true}, + 'tbody': {'tbody': true, 'tfoot': true}, + 'td': {'td': true, 'th': true}, + 'tfoot': {'tbody': true}, + 'th': {'td': true, 'th': true}, + 'thead': {'tbody': true, 'tfoot': true}, + 'tr': {'tr': true} + }, + doNotIndent: {"pre": true}, + allowUnquoted: true, + allowMissing: true, + caseFold: true +} + +var xmlConfig = { + autoSelfClosers: {}, + implicitlyClosed: {}, + contextGrabbers: {}, + doNotIndent: {}, + allowUnquoted: false, + allowMissing: false, + caseFold: false +} + +CodeMirror.defineMode("xml", function(editorConf, config_) { + var indentUnit = editorConf.indentUnit + var config = {} + var defaults = config_.htmlMode ? htmlConfig : xmlConfig + for (var prop in defaults) config[prop] = defaults[prop] + for (var prop in config_) config[prop] = config_[prop] + + // Return variables for tokenizers + var type, setStyle; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); + else return null; + } else if (stream.match("--")) { + return chain(inBlock("comment", "-->")); + } else if (stream.match("DOCTYPE", true, true)) { + stream.eatWhile(/[\w\._\-]/); + return chain(doctype(1)); + } else { + return null; + } + } else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("meta", "?>"); + return "meta"; + } else { + type = stream.eat("/") ? "closeTag" : "openTag"; + state.tokenize = inTag; + return "tag bracket"; + } + } else if (ch == "&") { + var ok; + if (stream.eat("#")) { + if (stream.eat("x")) { + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); + } else { + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); + } + } else { + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); + } + return ok ? "atom" : "error"; + } else { + stream.eatWhile(/[^&<]/); + return null; + } + } + inText.isInText = true; + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "tag bracket"; + } else if (ch == "=") { + type = "equals"; + return null; + } else if (ch == "<") { + state.tokenize = inText; + state.state = baseState; + state.tagName = state.tagStart = null; + var next = state.tokenize(stream, state); + return next ? next + " tag error" : "tag error"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + state.stringStartCol = stream.column(); + return state.tokenize(stream, state); + } else { + stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); + return "word"; + } + } + + function inAttribute(quote) { + var closure = function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "string"; + }; + closure.isInAttribute = true; + return closure; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + }; + } + function doctype(depth) { + return function(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch == "<") { + state.tokenize = doctype(depth + 1); + return state.tokenize(stream, state); + } else if (ch == ">") { + if (depth == 1) { + state.tokenize = inText; + break; + } else { + state.tokenize = doctype(depth - 1); + return state.tokenize(stream, state); + } + } + } + return "meta"; + }; + } + + function Context(state, tagName, startOfLine) { + this.prev = state.context; + this.tagName = tagName; + this.indent = state.indented; + this.startOfLine = startOfLine; + if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) + this.noIndent = true; + } + function popContext(state) { + if (state.context) state.context = state.context.prev; + } + function maybePopContext(state, nextTagName) { + var parentTagName; + while (true) { + if (!state.context) { + return; + } + parentTagName = state.context.tagName; + if (!config.contextGrabbers.hasOwnProperty(parentTagName) || + !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { + return; + } + popContext(state); + } + } + + function baseState(type, stream, state) { + if (type == "openTag") { + state.tagStart = stream.column(); + return tagNameState; + } else if (type == "closeTag") { + return closeTagNameState; + } else { + return baseState; + } + } + function tagNameState(type, stream, state) { + if (type == "word") { + state.tagName = stream.current(); + setStyle = "tag"; + return attrState; + } else { + setStyle = "error"; + return tagNameState; + } + } + function closeTagNameState(type, stream, state) { + if (type == "word") { + var tagName = stream.current(); + if (state.context && state.context.tagName != tagName && + config.implicitlyClosed.hasOwnProperty(state.context.tagName)) + popContext(state); + if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { + setStyle = "tag"; + return closeState; + } else { + setStyle = "tag error"; + return closeStateErr; + } + } else { + setStyle = "error"; + return closeStateErr; + } + } + + function closeState(type, _stream, state) { + if (type != "endTag") { + setStyle = "error"; + return closeState; + } + popContext(state); + return baseState; + } + function closeStateErr(type, stream, state) { + setStyle = "error"; + return closeState(type, stream, state); + } + + function attrState(type, _stream, state) { + if (type == "word") { + setStyle = "attribute"; + return attrEqState; + } else if (type == "endTag" || type == "selfcloseTag") { + var tagName = state.tagName, tagStart = state.tagStart; + state.tagName = state.tagStart = null; + if (type == "selfcloseTag" || + config.autoSelfClosers.hasOwnProperty(tagName)) { + maybePopContext(state, tagName); + } else { + maybePopContext(state, tagName); + state.context = new Context(state, tagName, tagStart == state.indented); + } + return baseState; + } + setStyle = "error"; + return attrState; + } + function attrEqState(type, stream, state) { + if (type == "equals") return attrValueState; + if (!config.allowMissing) setStyle = "error"; + return attrState(type, stream, state); + } + function attrValueState(type, stream, state) { + if (type == "string") return attrContinuedState; + if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;} + setStyle = "error"; + return attrState(type, stream, state); + } + function attrContinuedState(type, stream, state) { + if (type == "string") return attrContinuedState; + return attrState(type, stream, state); + } + + return { + startState: function(baseIndent) { + var state = {tokenize: inText, + state: baseState, + indented: baseIndent || 0, + tagName: null, tagStart: null, + context: null} + if (baseIndent != null) state.baseIndent = baseIndent + return state + }, + + token: function(stream, state) { + if (!state.tagName && stream.sol()) + state.indented = stream.indentation(); + + if (stream.eatSpace()) return null; + type = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "comment") { + setStyle = null; + state.state = state.state(type || style, stream, state); + if (setStyle) + style = setStyle == "error" ? style + " error" : setStyle; + } + return style; + }, + + indent: function(state, textAfter, fullLine) { + var context = state.context; + // Indent multi-line strings (e.g. css). + if (state.tokenize.isInAttribute) { + if (state.tagStart == state.indented) + return state.stringStartCol + 1; + else + return state.indented + indentUnit; + } + if (context && context.noIndent) return CodeMirror.Pass; + if (state.tokenize != inTag && state.tokenize != inText) + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; + // Indent the starts of attribute names. + if (state.tagName) { + if (config.multilineTagIndentPastTag !== false) + return state.tagStart + state.tagName.length + 2; + else + return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1); + } + if (config.alignCDATA && /$/, + blockCommentStart: "", + + configuration: config.htmlMode ? "html" : "xml", + helperType: config.htmlMode ? "html" : "xml", + + skipAttribute: function(state) { + if (state.state == attrValueState) + state.state = attrState + } + }; +}); + +CodeMirror.defineMIME("text/xml", "xml"); +CodeMirror.defineMIME("application/xml", "xml"); +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); + +}); diff --git a/backend/webif/static/codemirror/mode/xquery/index.html b/backend/webif/static/codemirror/mode/xquery/index.html new file mode 100755 index 000000000..7ac5aaeff --- /dev/null +++ b/backend/webif/static/codemirror/mode/xquery/index.html @@ -0,0 +1,210 @@ + + +CodeMirror: XQuery mode + + + + + + + + + + +
    +

    XQuery mode

    + + +
    + +
    + + + +

    MIME types defined: application/xquery.

    + +

    Development of the CodeMirror XQuery mode was sponsored by + MarkLogic and developed by + Mike Brevoort. +

    + +
    diff --git a/backend/webif/static/codemirror/mode/xquery/test.js b/backend/webif/static/codemirror/mode/xquery/test.js new file mode 100755 index 000000000..9697f9b0a --- /dev/null +++ b/backend/webif/static/codemirror/mode/xquery/test.js @@ -0,0 +1,67 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Don't take these too seriously -- the expected results appear to be +// based on the results of actual runs without any serious manual +// verification. If a change you made causes them to fail, the test is +// as likely to wrong as the code. + +(function() { + var mode = CodeMirror.getMode({tabSize: 4}, "xquery"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("eviltest", + "[keyword xquery] [keyword version] [variable "1][keyword .][atom 0][keyword -][variable ml"][def&variable ;] [comment (: this is : a \"comment\" :)]", + " [keyword let] [variable $let] [keyword :=] [variable <x] [variable attr][keyword =][variable "value">"test"<func>][def&variable ;function]() [variable $var] {[keyword function]()} {[variable $var]}[variable <][keyword /][variable func><][keyword /][variable x>]", + " [keyword let] [variable $joe][keyword :=][atom 1]", + " [keyword return] [keyword element] [variable element] {", + " [keyword attribute] [variable attribute] { [atom 1] },", + " [keyword element] [variable test] { [variable 'a'] }, [keyword attribute] [variable foo] { [variable "bar"] },", + " [def&variable fn:doc]()[[ [variable foo][keyword /][variable @bar] [keyword eq] [variable $let] ]],", + " [keyword //][variable x] } [comment (: a more 'evil' test :)]", + " [comment (: Modified Blakeley example (: with nested comment :) ... :)]", + " [keyword declare] [variable private] [keyword function] [def&variable local:declare]() {()}[variable ;]", + " [keyword declare] [variable private] [keyword function] [def&variable local:private]() {()}[variable ;]", + " [keyword declare] [variable private] [keyword function] [def&variable local:function]() {()}[variable ;]", + " [keyword declare] [variable private] [keyword function] [def&variable local:local]() {()}[variable ;]", + " [keyword let] [variable $let] [keyword :=] [variable <let>let] [variable $let] [keyword :=] [variable "let"<][keyword /let][variable >]", + " [keyword return] [keyword element] [variable element] {", + " [keyword attribute] [variable attribute] { [keyword try] { [def&variable xdmp:version]() } [keyword catch]([variable $e]) { [def&variable xdmp:log]([variable $e]) } },", + " [keyword attribute] [variable fn:doc] { [variable "bar"] [keyword castable] [keyword as] [atom xs:string] },", + " [keyword element] [variable text] { [keyword text] { [variable "text"] } },", + " [def&variable fn:doc]()[[ [qualifier child::][variable eq][keyword /]([variable @bar] [keyword |] [qualifier attribute::][variable attribute]) [keyword eq] [variable $let] ]],", + " [keyword //][variable fn:doc]", + " }"); + + MT("testEmptySequenceKeyword", + "[string \"foo\"] [keyword instance] [keyword of] [keyword empty-sequence]()"); + + MT("testMultiAttr", + "[tag

    ][variable hello] [variable world][tag

    ]"); + + MT("test namespaced variable", + "[keyword declare] [keyword namespace] [variable e] [keyword =] [string \"http://example.com/ANamespace\"][variable ;declare] [keyword variable] [variable $e:exampleComThisVarIsNotRecognized] [keyword as] [keyword element]([keyword *]) [variable external;]"); + + MT("test EQName variable", + "[keyword declare] [keyword variable] [variable $\"http://www.example.com/ns/my\":var] [keyword :=] [atom 12][variable ;]", + "[tag ]{[variable $\"http://www.example.com/ns/my\":var]}[tag ]"); + + MT("test EQName function", + "[keyword declare] [keyword function] [def&variable \"http://www.example.com/ns/my\":fn] ([variable $a] [keyword as] [atom xs:integer]) [keyword as] [atom xs:integer] {", + " [variable $a] [keyword +] [atom 2]", + "}[variable ;]", + "[tag ]{[def&variable \"http://www.example.com/ns/my\":fn]([atom 12])}[tag ]"); + + MT("test EQName function with single quotes", + "[keyword declare] [keyword function] [def&variable 'http://www.example.com/ns/my':fn] ([variable $a] [keyword as] [atom xs:integer]) [keyword as] [atom xs:integer] {", + " [variable $a] [keyword +] [atom 2]", + "}[variable ;]", + "[tag ]{[def&variable 'http://www.example.com/ns/my':fn]([atom 12])}[tag ]"); + + MT("testProcessingInstructions", + "[def&variable data]([comment&meta ]) [keyword instance] [keyword of] [atom xs:string]"); + + MT("testQuoteEscapeDouble", + "[keyword let] [variable $rootfolder] [keyword :=] [string \"c:\\builds\\winnt\\HEAD\\qa\\scripts\\\"]", + "[keyword let] [variable $keysfolder] [keyword :=] [def&variable concat]([variable $rootfolder], [string \"keys\\\"])"); +})(); diff --git a/backend/webif/static/codemirror/mode/xquery/xquery.js b/backend/webif/static/codemirror/mode/xquery/xquery.js new file mode 100755 index 000000000..f5db831c1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/xquery/xquery.js @@ -0,0 +1,448 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("xquery", function() { + + // The keywords object is set to the result of this self executing + // function. Each keyword is a property of the keywords object whose + // value is {type: atype, style: astyle} + var keywords = function(){ + // convenience functions used to build keywords object + function kw(type) {return {type: type, style: "keyword"};} + var operator = kw("operator") + , atom = {type: "atom", style: "atom"} + , punctuation = {type: "punctuation", style: null} + , qualifier = {type: "axis_specifier", style: "qualifier"}; + + // kwObj is what is return from this function at the end + var kwObj = { + ',': punctuation + }; + + // a list of 'basic' keywords. For each add a property to kwObj with the value of + // {type: basic[i], style: "keyword"} e.g. 'after' --> {type: "after", style: "keyword"} + var basic = ['after', 'all', 'allowing', 'ancestor', 'ancestor-or-self', 'any', 'array', 'as', + 'ascending', 'at', 'attribute', 'base-uri', 'before', 'boundary-space', 'by', 'case', 'cast', + 'castable', 'catch', 'child', 'collation', 'comment', 'construction', 'contains', 'content', + 'context', 'copy', 'copy-namespaces', 'count', 'decimal-format', 'declare', 'default', 'delete', + 'descendant', 'descendant-or-self', 'descending', 'diacritics', 'different', 'distance', + 'document', 'document-node', 'element', 'else', 'empty', 'empty-sequence', 'encoding', 'end', + 'entire', 'every', 'exactly', 'except', 'external', 'first', 'following', 'following-sibling', + 'for', 'from', 'ftand', 'ftnot', 'ft-option', 'ftor', 'function', 'fuzzy', 'greatest', 'group', + 'if', 'import', 'in', 'inherit', 'insensitive', 'insert', 'instance', 'intersect', 'into', + 'invoke', 'is', 'item', 'language', 'last', 'lax', 'least', 'let', 'levels', 'lowercase', 'map', + 'modify', 'module', 'most', 'namespace', 'next', 'no', 'node', 'nodes', 'no-inherit', + 'no-preserve', 'not', 'occurs', 'of', 'only', 'option', 'order', 'ordered', 'ordering', + 'paragraph', 'paragraphs', 'parent', 'phrase', 'preceding', 'preceding-sibling', 'preserve', + 'previous', 'processing-instruction', 'relationship', 'rename', 'replace', 'return', + 'revalidation', 'same', 'satisfies', 'schema', 'schema-attribute', 'schema-element', 'score', + 'self', 'sensitive', 'sentence', 'sentences', 'sequence', 'skip', 'sliding', 'some', 'stable', + 'start', 'stemming', 'stop', 'strict', 'strip', 'switch', 'text', 'then', 'thesaurus', 'times', + 'to', 'transform', 'treat', 'try', 'tumbling', 'type', 'typeswitch', 'union', 'unordered', + 'update', 'updating', 'uppercase', 'using', 'validate', 'value', 'variable', 'version', + 'weight', 'when', 'where', 'wildcards', 'window', 'with', 'without', 'word', 'words', 'xquery']; + for(var i=0, l=basic.length; i < l; i++) { kwObj[basic[i]] = kw(basic[i]);}; + + // a list of types. For each add a property to kwObj with the value of + // {type: "atom", style: "atom"} + var types = ['xs:anyAtomicType', 'xs:anySimpleType', 'xs:anyType', 'xs:anyURI', + 'xs:base64Binary', 'xs:boolean', 'xs:byte', 'xs:date', 'xs:dateTime', 'xs:dateTimeStamp', + 'xs:dayTimeDuration', 'xs:decimal', 'xs:double', 'xs:duration', 'xs:ENTITIES', 'xs:ENTITY', + 'xs:float', 'xs:gDay', 'xs:gMonth', 'xs:gMonthDay', 'xs:gYear', 'xs:gYearMonth', 'xs:hexBinary', + 'xs:ID', 'xs:IDREF', 'xs:IDREFS', 'xs:int', 'xs:integer', 'xs:item', 'xs:java', 'xs:language', + 'xs:long', 'xs:Name', 'xs:NCName', 'xs:negativeInteger', 'xs:NMTOKEN', 'xs:NMTOKENS', + 'xs:nonNegativeInteger', 'xs:nonPositiveInteger', 'xs:normalizedString', 'xs:NOTATION', + 'xs:numeric', 'xs:positiveInteger', 'xs:precisionDecimal', 'xs:QName', 'xs:short', 'xs:string', + 'xs:time', 'xs:token', 'xs:unsignedByte', 'xs:unsignedInt', 'xs:unsignedLong', + 'xs:unsignedShort', 'xs:untyped', 'xs:untypedAtomic', 'xs:yearMonthDuration']; + for(var i=0, l=types.length; i < l; i++) { kwObj[types[i]] = atom;}; + + // each operator will add a property to kwObj with value of {type: "operator", style: "keyword"} + var operators = ['eq', 'ne', 'lt', 'le', 'gt', 'ge', ':=', '=', '>', '>=', '<', '<=', '.', '|', '?', 'and', 'or', 'div', 'idiv', 'mod', '*', '/', '+', '-']; + for(var i=0, l=operators.length; i < l; i++) { kwObj[operators[i]] = operator;}; + + // each axis_specifiers will add a property to kwObj with value of {type: "axis_specifier", style: "qualifier"} + var axis_specifiers = ["self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "parent::", + "ancestor::", "ancestor-or-self::", "following::", "preceding::", "following-sibling::", "preceding-sibling::"]; + for(var i=0, l=axis_specifiers.length; i < l; i++) { kwObj[axis_specifiers[i]] = qualifier; }; + + return kwObj; + }(); + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + // the primary mode tokenizer + function tokenBase(stream, state) { + var ch = stream.next(), + mightBeFunction = false, + isEQName = isEQNameAhead(stream); + + // an XML tag (if not in some sub, chained tokenizer) + if (ch == "<") { + if(stream.match("!--", true)) + return chain(stream, state, tokenXMLComment); + + if(stream.match("![CDATA", false)) { + state.tokenize = tokenCDATA; + return "tag"; + } + + if(stream.match("?", false)) { + return chain(stream, state, tokenPreProcessing); + } + + var isclose = stream.eat("/"); + stream.eatSpace(); + var tagName = "", c; + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; + + return chain(stream, state, tokenTag(tagName, isclose)); + } + // start code block + else if(ch == "{") { + pushStateStack(state, { type: "codeblock"}); + return null; + } + // end code block + else if(ch == "}") { + popStateStack(state); + return null; + } + // if we're in an XML block + else if(isInXmlBlock(state)) { + if(ch == ">") + return "tag"; + else if(ch == "/" && stream.eat(">")) { + popStateStack(state); + return "tag"; + } + else + return "variable"; + } + // if a number + else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:E[+\-]?\d+)?/); + return "atom"; + } + // comment start + else if (ch === "(" && stream.eat(":")) { + pushStateStack(state, { type: "comment"}); + return chain(stream, state, tokenComment); + } + // quoted string + else if (!isEQName && (ch === '"' || ch === "'")) + return chain(stream, state, tokenString(ch)); + // variable + else if(ch === "$") { + return chain(stream, state, tokenVariable); + } + // assignment + else if(ch ===":" && stream.eat("=")) { + return "keyword"; + } + // open paren + else if(ch === "(") { + pushStateStack(state, { type: "paren"}); + return null; + } + // close paren + else if(ch === ")") { + popStateStack(state); + return null; + } + // open paren + else if(ch === "[") { + pushStateStack(state, { type: "bracket"}); + return null; + } + // close paren + else if(ch === "]") { + popStateStack(state); + return null; + } + else { + var known = keywords.propertyIsEnumerable(ch) && keywords[ch]; + + // if there's a EQName ahead, consume the rest of the string portion, it's likely a function + if(isEQName && ch === '\"') while(stream.next() !== '"'){} + if(isEQName && ch === '\'') while(stream.next() !== '\''){} + + // gobble up a word if the character is not known + if(!known) stream.eatWhile(/[\w\$_-]/); + + // gobble a colon in the case that is a lib func type call fn:doc + var foundColon = stream.eat(":"); + + // if there's not a second colon, gobble another word. Otherwise, it's probably an axis specifier + // which should get matched as a keyword + if(!stream.eat(":") && foundColon) { + stream.eatWhile(/[\w\$_-]/); + } + // if the next non whitespace character is an open paren, this is probably a function (if not a keyword of other sort) + if(stream.match(/^[ \t]*\(/, false)) { + mightBeFunction = true; + } + // is the word a keyword? + var word = stream.current(); + known = keywords.propertyIsEnumerable(word) && keywords[word]; + + // if we think it's a function call but not yet known, + // set style to variable for now for lack of something better + if(mightBeFunction && !known) known = {type: "function_call", style: "variable def"}; + + // if the previous word was element, attribute, axis specifier, this word should be the name of that + if(isInXmlConstructor(state)) { + popStateStack(state); + return "variable"; + } + // as previously checked, if the word is element,attribute, axis specifier, call it an "xmlconstructor" and + // push the stack so we know to look for it on the next word + if(word == "element" || word == "attribute" || known.type == "axis_specifier") pushStateStack(state, {type: "xmlconstructor"}); + + // if the word is known, return the details of that else just call this a generic 'word' + return known ? known.style : "variable"; + } + } + + // handle comments, including nested + function tokenComment(stream, state) { + var maybeEnd = false, maybeNested = false, nestedCount = 0, ch; + while (ch = stream.next()) { + if (ch == ")" && maybeEnd) { + if(nestedCount > 0) + nestedCount--; + else { + popStateStack(state); + break; + } + } + else if(ch == ":" && maybeNested) { + nestedCount++; + } + maybeEnd = (ch == ":"); + maybeNested = (ch == "("); + } + + return "comment"; + } + + // tokenizer for string literals + // optionally pass a tokenizer function to set state.tokenize back to when finished + function tokenString(quote, f) { + return function(stream, state) { + var ch; + + if(isInString(state) && stream.current() == quote) { + popStateStack(state); + if(f) state.tokenize = f; + return "string"; + } + + pushStateStack(state, { type: "string", name: quote, tokenize: tokenString(quote, f) }); + + // if we're in a string and in an XML block, allow an embedded code block + if(stream.match("{", false) && isInXmlAttributeBlock(state)) { + state.tokenize = tokenBase; + return "string"; + } + + + while (ch = stream.next()) { + if (ch == quote) { + popStateStack(state); + if(f) state.tokenize = f; + break; + } + else { + // if we're in a string and in an XML block, allow an embedded code block in an attribute + if(stream.match("{", false) && isInXmlAttributeBlock(state)) { + state.tokenize = tokenBase; + return "string"; + } + + } + } + + return "string"; + }; + } + + // tokenizer for variables + function tokenVariable(stream, state) { + var isVariableChar = /[\w\$_-]/; + + // a variable may start with a quoted EQName so if the next character is quote, consume to the next quote + if(stream.eat("\"")) { + while(stream.next() !== '\"'){}; + stream.eat(":"); + } else { + stream.eatWhile(isVariableChar); + if(!stream.match(":=", false)) stream.eat(":"); + } + stream.eatWhile(isVariableChar); + state.tokenize = tokenBase; + return "variable"; + } + + // tokenizer for XML tags + function tokenTag(name, isclose) { + return function(stream, state) { + stream.eatSpace(); + if(isclose && stream.eat(">")) { + popStateStack(state); + state.tokenize = tokenBase; + return "tag"; + } + // self closing tag without attributes? + if(!stream.eat("/")) + pushStateStack(state, { type: "tag", name: name, tokenize: tokenBase}); + if(!stream.eat(">")) { + state.tokenize = tokenAttribute; + return "tag"; + } + else { + state.tokenize = tokenBase; + } + return "tag"; + }; + } + + // tokenizer for XML attributes + function tokenAttribute(stream, state) { + var ch = stream.next(); + + if(ch == "/" && stream.eat(">")) { + if(isInXmlAttributeBlock(state)) popStateStack(state); + if(isInXmlBlock(state)) popStateStack(state); + return "tag"; + } + if(ch == ">") { + if(isInXmlAttributeBlock(state)) popStateStack(state); + return "tag"; + } + if(ch == "=") + return null; + // quoted string + if (ch == '"' || ch == "'") + return chain(stream, state, tokenString(ch, tokenAttribute)); + + if(!isInXmlAttributeBlock(state)) + pushStateStack(state, { type: "attribute", tokenize: tokenAttribute}); + + stream.eat(/[a-zA-Z_:]/); + stream.eatWhile(/[-a-zA-Z0-9_:.]/); + stream.eatSpace(); + + // the case where the attribute has not value and the tag was closed + if(stream.match(">", false) || stream.match("/", false)) { + popStateStack(state); + state.tokenize = tokenBase; + } + + return "attribute"; + } + + // handle comments, including nested + function tokenXMLComment(stream, state) { + var ch; + while (ch = stream.next()) { + if (ch == "-" && stream.match("->", true)) { + state.tokenize = tokenBase; + return "comment"; + } + } + } + + + // handle CDATA + function tokenCDATA(stream, state) { + var ch; + while (ch = stream.next()) { + if (ch == "]" && stream.match("]", true)) { + state.tokenize = tokenBase; + return "comment"; + } + } + } + + // handle preprocessing instructions + function tokenPreProcessing(stream, state) { + var ch; + while (ch = stream.next()) { + if (ch == "?" && stream.match(">", true)) { + state.tokenize = tokenBase; + return "comment meta"; + } + } + } + + + // functions to test the current context of the state + function isInXmlBlock(state) { return isIn(state, "tag"); } + function isInXmlAttributeBlock(state) { return isIn(state, "attribute"); } + function isInXmlConstructor(state) { return isIn(state, "xmlconstructor"); } + function isInString(state) { return isIn(state, "string"); } + + function isEQNameAhead(stream) { + // assume we've already eaten a quote (") + if(stream.current() === '"') + return stream.match(/^[^\"]+\"\:/, false); + else if(stream.current() === '\'') + return stream.match(/^[^\"]+\'\:/, false); + else + return false; + } + + function isIn(state, type) { + return (state.stack.length && state.stack[state.stack.length - 1].type == type); + } + + function pushStateStack(state, newState) { + state.stack.push(newState); + } + + function popStateStack(state) { + state.stack.pop(); + var reinstateTokenize = state.stack.length && state.stack[state.stack.length-1].tokenize; + state.tokenize = reinstateTokenize || tokenBase; + } + + // the interface for the mode API + return { + startState: function() { + return { + tokenize: tokenBase, + cc: [], + stack: [] + }; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + return style; + }, + + blockCommentStart: "(:", + blockCommentEnd: ":)" + + }; + +}); + +CodeMirror.defineMIME("application/xquery", "xquery"); + +}); diff --git a/backend/webif/static/codemirror/mode/yacas/index.html b/backend/webif/static/codemirror/mode/yacas/index.html new file mode 100755 index 000000000..8e52cafb1 --- /dev/null +++ b/backend/webif/static/codemirror/mode/yacas/index.html @@ -0,0 +1,87 @@ + + +CodeMirror: yacas mode + + + + + + + + + + +
    +

    yacas mode

    + + + + + + +

    MIME types defined: text/x-yacas (yacas).

    +
    diff --git a/backend/webif/static/codemirror/mode/yacas/yacas.js b/backend/webif/static/codemirror/mode/yacas/yacas.js new file mode 100755 index 000000000..34c84fbd0 --- /dev/null +++ b/backend/webif/static/codemirror/mode/yacas/yacas.js @@ -0,0 +1,204 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Yacas mode copyright (c) 2015 by Grzegorz Mazur +// Loosely based on mathematica mode by Calin Barbat + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('yacas', function(_config, _parserConfig) { + + function words(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + + var bodiedOps = words("Assert BackQuote D Defun Deriv For ForEach FromFile " + + "FromString Function Integrate InverseTaylor Limit " + + "LocalSymbols Macro MacroRule MacroRulePattern " + + "NIntegrate Rule RulePattern Subst TD TExplicitSum " + + "TSum Taylor Taylor1 Taylor2 Taylor3 ToFile " + + "ToStdout ToString TraceRule Until While"); + + // patterns + var pFloatForm = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)"; + var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)"; + + // regular expressions + var reFloatForm = new RegExp(pFloatForm); + var reIdentifier = new RegExp(pIdentifier); + var rePattern = new RegExp(pIdentifier + "?_" + pIdentifier); + var reFunctionLike = new RegExp(pIdentifier + "\\s*\\("); + + function tokenBase(stream, state) { + var ch; + + // get next character + ch = stream.next(); + + // string + if (ch === '"') { + state.tokenize = tokenString; + return state.tokenize(stream, state); + } + + // comment + if (ch === '/') { + if (stream.eat('*')) { + state.tokenize = tokenComment; + return state.tokenize(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + + // go back one character + stream.backUp(1); + + // update scope info + var m = stream.match(/^(\w+)\s*\(/, false); + if (m !== null && bodiedOps.hasOwnProperty(m[1])) + state.scopes.push('bodied'); + + var scope = currentScope(state); + + if (scope === 'bodied' && ch === '[') + state.scopes.pop(); + + if (ch === '[' || ch === '{' || ch === '(') + state.scopes.push(ch); + + scope = currentScope(state); + + if (scope === '[' && ch === ']' || + scope === '{' && ch === '}' || + scope === '(' && ch === ')') + state.scopes.pop(); + + if (ch === ';') { + while (scope === 'bodied') { + state.scopes.pop(); + scope = currentScope(state); + } + } + + // look for ordered rules + if (stream.match(/\d+ *#/, true, false)) { + return 'qualifier'; + } + + // look for numbers + if (stream.match(reFloatForm, true, false)) { + return 'number'; + } + + // look for placeholders + if (stream.match(rePattern, true, false)) { + return 'variable-3'; + } + + // match all braces separately + if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) { + return 'bracket'; + } + + // literals looking like function calls + if (stream.match(reFunctionLike, true, false)) { + stream.backUp(1); + return 'variable'; + } + + // all other identifiers + if (stream.match(reIdentifier, true, false)) { + return 'variable-2'; + } + + // operators; note that operators like @@ or /; are matched separately for each symbol. + if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%|#)/, true, false)) { + return 'operator'; + } + + // everything else is an error + return 'error'; + } + + function tokenString(stream, state) { + var next, end = false, escaped = false; + while ((next = stream.next()) != null) { + if (next === '"' && !escaped) { + end = true; + break; + } + escaped = !escaped && next === '\\'; + } + if (end && !escaped) { + state.tokenize = tokenBase; + } + return 'string'; + }; + + function tokenComment(stream, state) { + var prev, next; + while((next = stream.next()) != null) { + if (prev === '*' && next === '/') { + state.tokenize = tokenBase; + break; + } + prev = next; + } + return 'comment'; + } + + function currentScope(state) { + var scope = null; + if (state.scopes.length > 0) + scope = state.scopes[state.scopes.length - 1]; + return scope; + } + + return { + startState: function() { + return { + tokenize: tokenBase, + scopes: [] + }; + }, + token: function(stream, state) { + if (stream.eatSpace()) return null; + return state.tokenize(stream, state); + }, + indent: function(state, textAfter) { + if (state.tokenize !== tokenBase && state.tokenize !== null) + return CodeMirror.Pass; + + var delta = 0; + if (textAfter === ']' || textAfter === '];' || + textAfter === '}' || textAfter === '};' || + textAfter === ');') + delta = -1; + + return (state.scopes.length + delta) * _config.indentUnit; + }, + electricChars: "{}[]();", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + }; +}); + +CodeMirror.defineMIME('text/x-yacas', { + name: 'yacas' +}); + +}); diff --git a/backend/webif/static/codemirror/mode/yaml-frontmatter/index.html b/backend/webif/static/codemirror/mode/yaml-frontmatter/index.html new file mode 100755 index 000000000..30cb294e8 --- /dev/null +++ b/backend/webif/static/codemirror/mode/yaml-frontmatter/index.html @@ -0,0 +1,121 @@ + + +CodeMirror: YAML front matter mode + + + + + + + + + + + + + +
    +

    YAML front matter mode

    +
    + +

    Defines a mode that parses +a YAML frontmatter +at the start of a file, switching to a base mode at the end of that. +Takes a mode configuration option base to configure the +base mode, which defaults to "gfm".

    + + + +
    diff --git a/backend/webif/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js b/backend/webif/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js new file mode 100755 index 000000000..5f4977237 --- /dev/null +++ b/backend/webif/static/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js @@ -0,0 +1,68 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function (mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../yaml/yaml")) + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../yaml/yaml"], mod) + else // Plain browser env + mod(CodeMirror) +})(function (CodeMirror) { + + var START = 0, FRONTMATTER = 1, BODY = 2 + + // a mixed mode for Markdown text with an optional YAML front matter + CodeMirror.defineMode("yaml-frontmatter", function (config, parserConfig) { + var yamlMode = CodeMirror.getMode(config, "yaml") + var innerMode = CodeMirror.getMode(config, parserConfig && parserConfig.base || "gfm") + + function curMode(state) { + return state.state == BODY ? innerMode : yamlMode + } + + return { + startState: function () { + return { + state: START, + inner: CodeMirror.startState(yamlMode) + } + }, + copyState: function (state) { + return { + state: state.state, + inner: CodeMirror.copyState(curMode(state), state.inner) + } + }, + token: function (stream, state) { + if (state.state == START) { + if (stream.match(/---/, false)) { + state.state = FRONTMATTER + return yamlMode.token(stream, state.inner) + } else { + state.state = BODY + state.inner = CodeMirror.startState(innerMode) + return innerMode.token(stream, state.inner) + } + } else if (state.state == FRONTMATTER) { + var end = stream.sol() && stream.match(/---/, false) + var style = yamlMode.token(stream, state.inner) + if (end) { + state.state = BODY + state.inner = CodeMirror.startState(innerMode) + } + return style + } else { + return innerMode.token(stream, state.inner) + } + }, + innerMode: function (state) { + return {mode: curMode(state), state: state.inner} + }, + blankLine: function (state) { + var mode = curMode(state) + if (mode.blankLine) return mode.blankLine(state.inner) + } + } + }) +}); diff --git a/backend/webif/static/codemirror/mode/yaml/index.html b/backend/webif/static/codemirror/mode/yaml/index.html new file mode 100755 index 000000000..be9b63236 --- /dev/null +++ b/backend/webif/static/codemirror/mode/yaml/index.html @@ -0,0 +1,80 @@ + + +CodeMirror: YAML mode + + + + + + + + + +
    +

    YAML mode

    +
    + + +

    MIME types defined: text/x-yaml.

    + +
    diff --git a/backend/webif/static/codemirror/mode/yaml/yaml.js b/backend/webif/static/codemirror/mode/yaml/yaml.js new file mode 100755 index 000000000..59c0ecdbe --- /dev/null +++ b/backend/webif/static/codemirror/mode/yaml/yaml.js @@ -0,0 +1,118 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("yaml", function() { + + var cons = ['true', 'false', 'on', 'off', 'yes', 'no']; + var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i'); + + return { + token: function(stream, state) { + var ch = stream.peek(); + var esc = state.escaped; + state.escaped = false; + /* comments */ + if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) { + stream.skipToEnd(); + return "comment"; + } + + if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/)) + return "string"; + + if (state.literal && stream.indentation() > state.keyCol) { + stream.skipToEnd(); return "string"; + } else if (state.literal) { state.literal = false; } + if (stream.sol()) { + state.keyCol = 0; + state.pair = false; + state.pairStart = false; + /* document start */ + if(stream.match(/---/)) { return "def"; } + /* document end */ + if (stream.match(/\.\.\./)) { return "def"; } + /* array list item */ + if (stream.match(/\s*-\s+/)) { return 'meta'; } + } + /* inline pairs/lists */ + if (stream.match(/^(\{|\}|\[|\])/)) { + if (ch == '{') + state.inlinePairs++; + else if (ch == '}') + state.inlinePairs--; + else if (ch == '[') + state.inlineList++; + else + state.inlineList--; + return 'meta'; + } + + /* list seperator */ + if (state.inlineList > 0 && !esc && ch == ',') { + stream.next(); + return 'meta'; + } + /* pairs seperator */ + if (state.inlinePairs > 0 && !esc && ch == ',') { + state.keyCol = 0; + state.pair = false; + state.pairStart = false; + stream.next(); + return 'meta'; + } + + /* start of value of a pair */ + if (state.pairStart) { + /* block literals */ + if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; }; + /* references */ + if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; } + /* numbers */ + if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; } + if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; } + /* keywords */ + if (stream.match(keywordRegex)) { return 'keyword'; } + } + + /* pairs (associative arrays) -> key */ + if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) { + state.pair = true; + state.keyCol = stream.indentation(); + return "atom"; + } + if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; } + + /* nothing found, continue */ + state.pairStart = false; + state.escaped = (ch == '\\'); + stream.next(); + return null; + }, + startState: function() { + return { + pair: false, + pairStart: false, + keyCol: 0, + inlinePairs: 0, + inlineList: 0, + literal: false, + escaped: false + }; + } + }; +}); + +CodeMirror.defineMIME("text/x-yaml", "yaml"); +CodeMirror.defineMIME("text/yaml", "yaml"); + +}); diff --git a/backend/webif/static/codemirror/mode/z80/index.html b/backend/webif/static/codemirror/mode/z80/index.html new file mode 100755 index 000000000..a41b7473e --- /dev/null +++ b/backend/webif/static/codemirror/mode/z80/index.html @@ -0,0 +1,53 @@ + + +CodeMirror: Z80 assembly mode + + + + + + + + + +
    +

    Z80 assembly mode

    + + +
    + + + +

    MIME types defined: text/x-z80, text/x-ez80.

    +
    diff --git a/backend/webif/static/codemirror/mode/z80/z80.js b/backend/webif/static/codemirror/mode/z80/z80.js new file mode 100755 index 000000000..aae70216f --- /dev/null +++ b/backend/webif/static/codemirror/mode/z80/z80.js @@ -0,0 +1,116 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode('z80', function(_config, parserConfig) { + var ez80 = parserConfig.ez80; + var keywords1, keywords2; + if (ez80) { + keywords1 = /^(exx?|(ld|cp)([di]r?)?|[lp]ea|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|[de]i|halt|im|in([di]mr?|ir?|irx|2r?)|ot(dmr?|[id]rx|imr?)|out(0?|[di]r?|[di]2r?)|tst(io)?|slp)(\.([sl]?i)?[sl])?\b/i; + keywords2 = /^(((call|j[pr]|rst|ret[in]?)(\.([sl]?i)?[sl])?)|(rs|st)mix)\b/i; + } else { + keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i; + keywords2 = /^(call|j[pr]|ret[in]?|b_?(call|jump))\b/i; + } + + var variables1 = /^(af?|bc?|c|de?|e|hl?|l|i[xy]?|r|sp)\b/i; + var variables2 = /^(n?[zc]|p[oe]?|m)\b/i; + var errors = /^([hl][xy]|i[xy][hl]|slia|sll)\b/i; + var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+d?)\b/i; + + return { + startState: function() { + return { + context: 0 + }; + }, + token: function(stream, state) { + if (!stream.column()) + state.context = 0; + + if (stream.eatSpace()) + return null; + + var w; + + if (stream.eatWhile(/\w/)) { + if (ez80 && stream.eat('.')) { + stream.eatWhile(/\w/); + } + w = stream.current(); + + if (stream.indentation()) { + if ((state.context == 1 || state.context == 4) && variables1.test(w)) { + state.context = 4; + return 'var2'; + } + + if (state.context == 2 && variables2.test(w)) { + state.context = 4; + return 'var3'; + } + + if (keywords1.test(w)) { + state.context = 1; + return 'keyword'; + } else if (keywords2.test(w)) { + state.context = 2; + return 'keyword'; + } else if (state.context == 4 && numbers.test(w)) { + return 'number'; + } + + if (errors.test(w)) + return 'error'; + } else if (stream.match(numbers)) { + return 'number'; + } else { + return null; + } + } else if (stream.eat(';')) { + stream.skipToEnd(); + return 'comment'; + } else if (stream.eat('"')) { + while (w = stream.next()) { + if (w == '"') + break; + + if (w == '\\') + stream.next(); + } + return 'string'; + } else if (stream.eat('\'')) { + if (stream.match(/\\?.'/)) + return 'number'; + } else if (stream.eat('.') || stream.sol() && stream.eat('#')) { + state.context = 5; + + if (stream.eatWhile(/\w/)) + return 'def'; + } else if (stream.eat('$')) { + if (stream.eatWhile(/[\da-f]/i)) + return 'number'; + } else if (stream.eat('%')) { + if (stream.eatWhile(/[01]/)) + return 'number'; + } else { + stream.next(); + } + return null; + } + }; +}); + +CodeMirror.defineMIME("text/x-z80", "z80"); +CodeMirror.defineMIME("text/x-ez80", { name: "z80", ez80: true }); + +}); diff --git a/backend/webif/static/codemirror/package.json b/backend/webif/static/codemirror/package.json new file mode 100755 index 000000000..3e9f20c65 --- /dev/null +++ b/backend/webif/static/codemirror/package.json @@ -0,0 +1,49 @@ +{ + "name": "codemirror", + "version": "5.32.0", + "main": "lib/codemirror.js", + "style": "lib/codemirror.css", + "description": "Full-featured in-browser code editor", + "license": "MIT", + "directories": { + "lib": "./lib" + }, + "scripts": { + "build": "rollup -c", + "watch": "rollup -w -c", + "prepare": "npm run-script build", + "test": "node ./test/run.js", + "lint": "bin/lint" + }, + "devDependencies": { + "blint": "^1", + "node-static": "0.6.0", + "phantomjs-prebuilt": "^2.1.12", + "rollup": "^0.41.0", + "rollup-plugin-buble": "^0.15.0", + "rollup-watch": "^3.2.0" + }, + "bugs": "http://github.com/codemirror/CodeMirror/issues", + "keywords": [ + "JavaScript", + "CodeMirror", + "Editor" + ], + "homepage": "http://codemirror.net", + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/codemirror/CodeMirror.git" + }, + "jspm": { + "directories": {}, + "dependencies": {}, + "devDependencies": {} + } +} diff --git a/backend/webif/static/codemirror/rollup.config.js b/backend/webif/static/codemirror/rollup.config.js new file mode 100755 index 000000000..9a17b24ff --- /dev/null +++ b/backend/webif/static/codemirror/rollup.config.js @@ -0,0 +1,18 @@ +import buble from 'rollup-plugin-buble'; + +export default { + banner: `// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . +`, + entry: "src/codemirror.js", + format: "umd", + dest: "lib/codemirror.js", + moduleName: "CodeMirror", + plugins: [ buble({namedFunctionExpressions: false}) ] +}; diff --git a/backend/webif/static/codemirror/src/codemirror.js b/backend/webif/static/codemirror/src/codemirror.js new file mode 100755 index 000000000..2a2f54e4c --- /dev/null +++ b/backend/webif/static/codemirror/src/codemirror.js @@ -0,0 +1,3 @@ +import { CodeMirror } from "./edit/main.js" + +export default CodeMirror diff --git a/backend/webif/static/codemirror/src/display/Display.js b/backend/webif/static/codemirror/src/display/Display.js new file mode 100755 index 000000000..54b228a9b --- /dev/null +++ b/backend/webif/static/codemirror/src/display/Display.js @@ -0,0 +1,106 @@ +import { gecko, ie, ie_version, mobile, webkit } from "../util/browser.js" +import { elt, eltP } from "../util/dom.js" +import { scrollerGap } from "../util/misc.js" + +// The display handles the DOM integration, both for input reading +// and content drawing. It holds references to DOM nodes and +// display-related state. + +export function Display(place, doc, input) { + let d = this + this.input = input + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler") + d.scrollbarFiller.setAttribute("cm-not-content", "true") + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler") + d.gutterFiller.setAttribute("cm-not-content", "true") + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = eltP("div", null, "CodeMirror-code") + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1") + d.cursorDiv = elt("div", null, "CodeMirror-cursors") + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure") + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure") + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none") + let lines = eltP("div", [d.lineSpace], "CodeMirror-lines") + // Moved around its parent to cover visible view. + d.mover = elt("div", [lines], null, "position: relative") + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer") + d.sizerWidth = null + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;") + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters") + d.lineGutter = null + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll") + d.scroller.setAttribute("tabIndex", "-1") + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror") + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 } + if (!webkit && !(gecko && mobile)) d.scroller.draggable = true + + if (place) { + if (place.appendChild) place.appendChild(d.wrapper) + else place(d.wrapper) + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first + d.reportedViewFrom = d.reportedViewTo = doc.first + // Information about the rendered lines. + d.view = [] + d.renderedView = null + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null + // Empty space (in pixels) above the view + d.viewOffset = 0 + d.lastWrapHeight = d.lastWrapWidth = 0 + d.updateLineNumbers = null + + d.nativeBarWidth = d.barHeight = d.barWidth = 0 + d.scrollbarsClipped = false + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null + d.maxLineLength = 0 + d.maxLineChanged = false + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null + + // True when shift is held down. + d.shift = false + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null + + d.activeTouch = null + + input.init(d) +} diff --git a/backend/webif/static/codemirror/src/display/focus.js b/backend/webif/static/codemirror/src/display/focus.js new file mode 100755 index 000000000..aa731b435 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/focus.js @@ -0,0 +1,47 @@ +import { restartBlink } from "./selection.js" +import { webkit } from "../util/browser.js" +import { addClass, rmClass } from "../util/dom.js" +import { signal } from "../util/event.js" + +export function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) } +} + +export function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true + setTimeout(() => { if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false + onBlur(cm) + } }, 100) +} + +export function onFocus(cm, e) { + if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false + + if (cm.options.readOnly == "nocursor") return + if (!cm.state.focused) { + signal(cm, "focus", cm, e) + cm.state.focused = true + addClass(cm.display.wrapper, "CodeMirror-focused") + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset() + if (webkit) setTimeout(() => cm.display.input.reset(true), 20) // Issue #1730 + } + cm.display.input.receivedFocus() + } + restartBlink(cm) +} +export function onBlur(cm, e) { + if (cm.state.delayingBlurEvent) return + + if (cm.state.focused) { + signal(cm, "blur", cm, e) + cm.state.focused = false + rmClass(cm.display.wrapper, "CodeMirror-focused") + } + clearInterval(cm.display.blinker) + setTimeout(() => { if (!cm.state.focused) cm.display.shift = false }, 150) +} diff --git a/backend/webif/static/codemirror/src/display/gutters.js b/backend/webif/static/codemirror/src/display/gutters.js new file mode 100755 index 000000000..37405b6d8 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/gutters.js @@ -0,0 +1,34 @@ +import { elt, removeChildren } from "../util/dom.js" +import { indexOf } from "../util/misc.js" + +import { updateGutterSpace } from "./update_display.js" + +// Rebuild the gutter elements, ensure the margin to the left of the +// code matches their width. +export function updateGutters(cm) { + let gutters = cm.display.gutters, specs = cm.options.gutters + removeChildren(gutters) + let i = 0 + for (; i < specs.length; ++i) { + let gutterClass = specs[i] + let gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)) + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt + gElt.style.width = (cm.display.lineNumWidth || 1) + "px" + } + } + gutters.style.display = i ? "" : "none" + updateGutterSpace(cm) +} + +// Make sure the gutters options contains the element +// "CodeMirror-linenumbers" when the lineNumbers option is true. +export function setGuttersForLineNumbers(options) { + let found = indexOf(options.gutters, "CodeMirror-linenumbers") + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]) + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0) + options.gutters.splice(found, 1) + } +} diff --git a/backend/webif/static/codemirror/src/display/highlight_worker.js b/backend/webif/static/codemirror/src/display/highlight_worker.js new file mode 100755 index 000000000..606981571 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/highlight_worker.js @@ -0,0 +1,55 @@ +import { getContextBefore, highlightLine, processLine } from "../line/highlight.js" +import { copyState } from "../modes.js" +import { bind } from "../util/misc.js" + +import { runInOp } from "./operations.js" +import { regLineChange } from "./view_tracking.js" + +// HIGHLIGHT WORKER + +export function startWorker(cm, time) { + if (cm.doc.highlightFrontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)) +} + +function highlightWorker(cm) { + let doc = cm.doc + if (doc.highlightFrontier >= cm.display.viewTo) return + let end = +new Date + cm.options.workTime + let context = getContextBefore(cm, doc.highlightFrontier) + let changedLines = [] + + doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), line => { + if (context.line >= cm.display.viewFrom) { // Visible + let oldStyles = line.styles + let resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null + let highlighted = highlightLine(cm, line, context, true) + if (resetState) context.state = resetState + line.styles = highlighted.styles + let oldCls = line.styleClasses, newCls = highlighted.classes + if (newCls) line.styleClasses = newCls + else if (oldCls) line.styleClasses = null + let ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass) + for (let i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i] + if (ischange) changedLines.push(context.line) + line.stateAfter = context.save() + context.nextLine() + } else { + if (line.text.length <= cm.options.maxHighlightLength) + processLine(cm, line.text, context) + line.stateAfter = context.line % 5 == 0 ? context.save() : null + context.nextLine() + } + if (+new Date > end) { + startWorker(cm, cm.options.workDelay) + return true + } + }) + doc.highlightFrontier = context.line + doc.modeFrontier = Math.max(doc.modeFrontier, context.line) + if (changedLines.length) runInOp(cm, () => { + for (let i = 0; i < changedLines.length; i++) + regLineChange(cm, changedLines[i], "text") + }) +} diff --git a/backend/webif/static/codemirror/src/display/line_numbers.js b/backend/webif/static/codemirror/src/display/line_numbers.js new file mode 100755 index 000000000..3ab957509 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/line_numbers.js @@ -0,0 +1,48 @@ +import { lineNumberFor } from "../line/utils_line.js" +import { compensateForHScroll } from "../measurement/position_measurement.js" +import { elt } from "../util/dom.js" + +import { updateGutterSpace } from "./update_display.js" + +// Re-align line numbers and gutter marks to compensate for +// horizontal scrolling. +export function alignHorizontally(cm) { + let display = cm.display, view = display.view + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return + let comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft + let gutterW = display.gutters.offsetWidth, left = comp + "px" + for (let i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter) { + if (view[i].gutter) + view[i].gutter.style.left = left + if (view[i].gutterBackground) + view[i].gutterBackground.style.left = left + } + let align = view[i].alignable + if (align) for (let j = 0; j < align.length; j++) + align[j].style.left = left + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px" +} + +// Used to ensure that the line number gutter is still the right +// size for the current document size. Returns true when an update +// is needed. +export function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false + let doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display + if (last.length != display.lineNumChars) { + let test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")) + let innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW + display.lineGutter.style.width = "" + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1 + display.lineNumWidth = display.lineNumInnerWidth + padding + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1 + display.lineGutter.style.width = display.lineNumWidth + "px" + updateGutterSpace(cm) + return true + } + return false +} diff --git a/backend/webif/static/codemirror/src/display/mode_state.js b/backend/webif/static/codemirror/src/display/mode_state.js new file mode 100755 index 000000000..5d8ebf250 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/mode_state.js @@ -0,0 +1,22 @@ +import { getMode } from "../modes.js" + +import { startWorker } from "./highlight_worker.js" +import { regChange } from "./view_tracking.js" + +// Used to get the editor into a consistent state again when options change. + +export function loadMode(cm) { + cm.doc.mode = getMode(cm.options, cm.doc.modeOption) + resetModeState(cm) +} + +export function resetModeState(cm) { + cm.doc.iter(line => { + if (line.stateAfter) line.stateAfter = null + if (line.styles) line.styles = null + }) + cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first + startWorker(cm, 100) + cm.state.modeGen++ + if (cm.curOp) regChange(cm) +} diff --git a/backend/webif/static/codemirror/src/display/operations.js b/backend/webif/static/codemirror/src/display/operations.js new file mode 100755 index 000000000..5cc26d265 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/operations.js @@ -0,0 +1,205 @@ +import { clipPos } from "../line/pos.js" +import { findMaxLine } from "../line/spans.js" +import { displayWidth, measureChar, scrollGap } from "../measurement/position_measurement.js" +import { signal } from "../util/event.js" +import { activeElt } from "../util/dom.js" +import { finishOperation, pushOperation } from "../util/operation_group.js" + +import { ensureFocus } from "./focus.js" +import { measureForScrollbars, updateScrollbars } from "./scrollbars.js" +import { restartBlink } from "./selection.js" +import { maybeScrollWindow, scrollPosIntoView, setScrollLeft, setScrollTop } from "./scrolling.js" +import { DisplayUpdate, maybeClipScrollbars, postUpdateDisplay, setDocumentHeight, updateDisplayIfNeeded } from "./update_display.js" +import { updateHeightsInViewport } from "./update_lines.js" + +// Operations are used to wrap a series of changes to the editor +// state in such a way that each change won't have to update the +// cursor and display (which would be awkward, slow, and +// error-prone). Instead, display updates are batched and then all +// combined and executed at once. + +let nextOpId = 0 +// Start a new operation. +export function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + } + pushOperation(cm.curOp) +} + +// Finish an operation, updating the display and signalling delayed events +export function endOperation(cm) { + let op = cm.curOp + finishOperation(op, group => { + for (let i = 0; i < group.ops.length; i++) + group.ops[i].cm.curOp = null + endOperations(group) + }) +} + +// The DOM updates done when an operation finishes are batched so +// that the minimum number of relayouts are required. +function endOperations(group) { + let ops = group.ops + for (let i = 0; i < ops.length; i++) // Read DOM + endOperation_R1(ops[i]) + for (let i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W1(ops[i]) + for (let i = 0; i < ops.length; i++) // Read DOM + endOperation_R2(ops[i]) + for (let i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W2(ops[i]) + for (let i = 0; i < ops.length; i++) // Read DOM + endOperation_finish(ops[i]) +} + +function endOperation_R1(op) { + let cm = op.cm, display = cm.display + maybeClipScrollbars(cm) + if (op.updateMaxLine) findMaxLine(cm) + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate) +} + +function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update) +} + +function endOperation_R2(op) { + let cm = op.cm, display = cm.display + if (op.updatedDisplay) updateHeightsInViewport(cm) + + op.barMeasure = measureForScrollbars(cm) + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3 + cm.display.sizerWidth = op.adjustWidthTo + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth) + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)) + } + + if (op.updatedDisplay || op.selectionChanged) + op.preparedSelection = display.input.prepareSelection() +} + +function endOperation_W2(op) { + let cm = op.cm + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px" + if (op.maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true) + cm.display.maxLineChanged = false + } + + let takeFocus = op.focus && op.focus == activeElt() + if (op.preparedSelection) + cm.display.input.showSelection(op.preparedSelection, takeFocus) + if (op.updatedDisplay || op.startHeight != cm.doc.height) + updateScrollbars(cm, op.barMeasure) + if (op.updatedDisplay) + setDocumentHeight(cm, op.barMeasure) + + if (op.selectionChanged) restartBlink(cm) + + if (cm.state.focused && op.updateInput) + cm.display.input.reset(op.typing) + if (takeFocus) ensureFocus(op.cm) +} + +function endOperation_finish(op) { + let cm = op.cm, display = cm.display, doc = cm.doc + + if (op.updatedDisplay) postUpdateDisplay(cm, op.update) + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + display.wheelStartX = display.wheelStartY = null + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null) setScrollTop(cm, op.scrollTop, op.forceScroll) + + if (op.scrollLeft != null) setScrollLeft(cm, op.scrollLeft, true, true) + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + let rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin) + maybeScrollWindow(cm, rect) + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + let hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers + if (hidden) for (let i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide") + if (unhidden) for (let i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide") + + if (display.wrapper.offsetHeight) + doc.scrollTop = cm.display.scroller.scrollTop + + // Fire change events, and delayed event handlers + if (op.changeObjs) + signal(cm, "changes", cm, op.changeObjs) + if (op.update) + op.update.finish() +} + +// Run the given function in an operation +export function runInOp(cm, f) { + if (cm.curOp) return f() + startOperation(cm) + try { return f() } + finally { endOperation(cm) } +} +// Wraps a function in an operation. Returns the wrapped function. +export function operation(cm, f) { + return function() { + if (cm.curOp) return f.apply(cm, arguments) + startOperation(cm) + try { return f.apply(cm, arguments) } + finally { endOperation(cm) } + } +} +// Used to add methods to editor and doc instances, wrapping them in +// operations. +export function methodOp(f) { + return function() { + if (this.curOp) return f.apply(this, arguments) + startOperation(this) + try { return f.apply(this, arguments) } + finally { endOperation(this) } + } +} +export function docMethodOp(f) { + return function() { + let cm = this.cm + if (!cm || cm.curOp) return f.apply(this, arguments) + startOperation(cm) + try { return f.apply(this, arguments) } + finally { endOperation(cm) } + } +} diff --git a/backend/webif/static/codemirror/src/display/scroll_events.js b/backend/webif/static/codemirror/src/display/scroll_events.js new file mode 100755 index 000000000..fbed42663 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/scroll_events.js @@ -0,0 +1,115 @@ +import { chrome, gecko, ie, mac, presto, safari, webkit } from "../util/browser.js" +import { e_preventDefault } from "../util/event.js" + +import { updateDisplaySimple } from "./update_display.js" +import { setScrollLeft, updateScrollTop } from "./scrolling.js" + +// Since the delta values reported on mouse wheel events are +// unstandardized between browsers and even browser versions, and +// generally horribly unpredictable, this code starts by measuring +// the scroll effect that the first few mouse wheel events have, +// and, from that, detects the way it can convert deltas to pixel +// offsets afterwards. +// +// The reason we want to know the amount a wheel event will scroll +// is that it gives us a chance to update the display before the +// actual scrolling happens, reducing flickering. + +let wheelSamples = 0, wheelPixelsPerUnit = null +// Fill in a browser-detected starting value on browsers where we +// know one. These don't have to be accurate -- the result of them +// being wrong would just be a slight flicker on the first wheel +// scroll (if it is large enough). +if (ie) wheelPixelsPerUnit = -.53 +else if (gecko) wheelPixelsPerUnit = 15 +else if (chrome) wheelPixelsPerUnit = -.7 +else if (safari) wheelPixelsPerUnit = -1/3 + +function wheelEventDelta(e) { + let dx = e.wheelDeltaX, dy = e.wheelDeltaY + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail + else if (dy == null) dy = e.wheelDelta + return {x: dx, y: dy} +} +export function wheelEventPixels(e) { + let delta = wheelEventDelta(e) + delta.x *= wheelPixelsPerUnit + delta.y *= wheelPixelsPerUnit + return delta +} + +export function onScrollWheel(cm, e) { + let delta = wheelEventDelta(e), dx = delta.x, dy = delta.y + + let display = cm.display, scroll = display.scroller + // Quit if there's nothing to scroll here + let canScrollX = scroll.scrollWidth > scroll.clientWidth + let canScrollY = scroll.scrollHeight > scroll.clientHeight + if (!(dx && canScrollX || dy && canScrollY)) return + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (let cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (let i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur + break outer + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy && canScrollY) + updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) + setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit)) + // Only prevent default scrolling if vertical scrolling is + // actually possible. Otherwise, it causes vertical scroll + // jitter on OSX trackpads when deltaX is small and deltaY + // is large (issue #3579) + if (!dy || (dy && canScrollY)) + e_preventDefault(e) + display.wheelStartX = null // Abort measurement, if in progress + return + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + let pixels = dy * wheelPixelsPerUnit + let top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight + if (pixels < 0) top = Math.max(0, top + pixels - 50) + else bot = Math.min(cm.doc.height, bot + pixels + 50) + updateDisplaySimple(cm, {top: top, bottom: bot}) + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop + display.wheelDX = dx; display.wheelDY = dy + setTimeout(() => { + if (display.wheelStartX == null) return + let movedX = scroll.scrollLeft - display.wheelStartX + let movedY = scroll.scrollTop - display.wheelStartY + let sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX) + display.wheelStartX = display.wheelStartY = null + if (!sample) return + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1) + ++wheelSamples + }, 200) + } else { + display.wheelDX += dx; display.wheelDY += dy + } + } +} diff --git a/backend/webif/static/codemirror/src/display/scrollbars.js b/backend/webif/static/codemirror/src/display/scrollbars.js new file mode 100755 index 000000000..7308c5e27 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/scrollbars.js @@ -0,0 +1,192 @@ +import { addClass, elt, rmClass } from "../util/dom.js" +import { on } from "../util/event.js" +import { scrollGap, paddingVert } from "../measurement/position_measurement.js" +import { ie, ie_version, mac, mac_geMountainLion } from "../util/browser.js" +import { updateHeightsInViewport } from "./update_lines.js" +import { Delayed } from "../util/misc.js" + +import { setScrollLeft, updateScrollTop } from "./scrolling.js" + +// SCROLLBARS + +// Prepare DOM reads needed to update the scrollbars. Done in one +// shot to minimize update/measure roundtrips. +export function measureForScrollbars(cm) { + let d = cm.display, gutterW = d.gutters.offsetWidth + let docH = Math.round(cm.doc.height + paddingVert(cm.display)) + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + } +} + +class NativeScrollbars { + constructor(place, scroll, cm) { + this.cm = cm + let vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar") + let horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar") + place(vert); place(horiz) + + on(vert, "scroll", () => { + if (vert.clientHeight) scroll(vert.scrollTop, "vertical") + }) + on(horiz, "scroll", () => { + if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal") + }) + + this.checkedZeroWidth = false + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px" + } + + update(measure) { + let needsH = measure.scrollWidth > measure.clientWidth + 1 + let needsV = measure.scrollHeight > measure.clientHeight + 1 + let sWidth = measure.nativeBarWidth + + if (needsV) { + this.vert.style.display = "block" + this.vert.style.bottom = needsH ? sWidth + "px" : "0" + let totalHeight = measure.viewHeight - (needsH ? sWidth : 0) + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px" + } else { + this.vert.style.display = "" + this.vert.firstChild.style.height = "0" + } + + if (needsH) { + this.horiz.style.display = "block" + this.horiz.style.right = needsV ? sWidth + "px" : "0" + this.horiz.style.left = measure.barLeft + "px" + let totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0) + this.horiz.firstChild.style.width = + Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px" + } else { + this.horiz.style.display = "" + this.horiz.firstChild.style.width = "0" + } + + if (!this.checkedZeroWidth && measure.clientHeight > 0) { + if (sWidth == 0) this.zeroWidthHack() + this.checkedZeroWidth = true + } + + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0} + } + + setScrollLeft(pos) { + if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos + if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") + } + + setScrollTop(pos) { + if (this.vert.scrollTop != pos) this.vert.scrollTop = pos + if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert, "vert") + } + + zeroWidthHack() { + let w = mac && !mac_geMountainLion ? "12px" : "18px" + this.horiz.style.height = this.vert.style.width = w + this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none" + this.disableHoriz = new Delayed + this.disableVert = new Delayed + } + + enableZeroWidthBar(bar, delay, type) { + bar.style.pointerEvents = "auto" + function maybeDisable() { + // To find out whether the scrollbar is still visible, we + // check whether the element under the pixel in the bottom + // right corner of the scrollbar box is the scrollbar box + // itself (when the bar is still visible) or its filler child + // (when the bar is hidden). If it is still visible, we keep + // it enabled, if it's hidden, we disable pointer events. + let box = bar.getBoundingClientRect() + let elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) + : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1) + if (elt != bar) bar.style.pointerEvents = "none" + else delay.set(1000, maybeDisable) + } + delay.set(1000, maybeDisable) + } + + clear() { + let parent = this.horiz.parentNode + parent.removeChild(this.horiz) + parent.removeChild(this.vert) + } +} + +class NullScrollbars { + update() { return {bottom: 0, right: 0} } + setScrollLeft() {} + setScrollTop() {} + clear() {} +} + +export function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm) + let startWidth = cm.display.barWidth, startHeight = cm.display.barHeight + updateScrollbarsInner(cm, measure) + for (let i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + updateHeightsInViewport(cm) + updateScrollbarsInner(cm, measureForScrollbars(cm)) + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight + } +} + +// Re-synchronize the fake scrollbars with the actual size of the +// content. +function updateScrollbarsInner(cm, measure) { + let d = cm.display + let sizes = d.scrollbars.update(measure) + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px" + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px" + d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block" + d.scrollbarFiller.style.height = sizes.bottom + "px" + d.scrollbarFiller.style.width = sizes.right + "px" + } else d.scrollbarFiller.style.display = "" + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block" + d.gutterFiller.style.height = sizes.bottom + "px" + d.gutterFiller.style.width = measure.gutterWidth + "px" + } else d.gutterFiller.style.display = "" +} + +export let scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars} + +export function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear() + if (cm.display.scrollbars.addClass) + rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) + } + + cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](node => { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller) + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", () => { + if (cm.state.focused) setTimeout(() => cm.display.input.focus(), 0) + }) + node.setAttribute("cm-not-content", "true") + }, (pos, axis) => { + if (axis == "horizontal") setScrollLeft(cm, pos) + else updateScrollTop(cm, pos) + }, cm) + if (cm.display.scrollbars.addClass) + addClass(cm.display.wrapper, cm.display.scrollbars.addClass) +} diff --git a/backend/webif/static/codemirror/src/display/scrolling.js b/backend/webif/static/codemirror/src/display/scrolling.js new file mode 100755 index 000000000..26ec993b0 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/scrolling.js @@ -0,0 +1,184 @@ +import { Pos } from "../line/pos.js" +import { cursorCoords, displayHeight, displayWidth, estimateCoords, paddingTop, paddingVert, scrollGap, textHeight } from "../measurement/position_measurement.js" +import { gecko, phantom } from "../util/browser.js" +import { elt } from "../util/dom.js" +import { signalDOMEvent } from "../util/event.js" + +import { startWorker } from "./highlight_worker.js" +import { alignHorizontally } from "./line_numbers.js" +import { updateDisplaySimple } from "./update_display.js" + +// SCROLLING THINGS INTO VIEW + +// If an editor sits on the top or bottom of the window, partially +// scrolled out of view, this ensures that the cursor is visible. +export function maybeScrollWindow(cm, rect) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) return + + let display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null + if (rect.top + box.top < 0) doScroll = true + else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false + if (doScroll != null && !phantom) { + let scrollNode = elt("div", "\u200b", null, `position: absolute; + top: ${rect.top - display.viewOffset - paddingTop(cm.display)}px; + height: ${rect.bottom - rect.top + scrollGap(cm) + display.barHeight}px; + left: ${rect.left}px; width: ${Math.max(2, rect.right - rect.left)}px;`) + cm.display.lineSpace.appendChild(scrollNode) + scrollNode.scrollIntoView(doScroll) + cm.display.lineSpace.removeChild(scrollNode) + } +} + +// Scroll a given position into view (immediately), verifying that +// it actually became visible (as line heights are accurately +// measured, the position of something may 'drift' during drawing). +export function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0 + let rect + if (!cm.options.lineWrapping && pos == end) { + // Set pos and end to the cursor positions around the character pos sticks to + // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch + // If pos == Pos(_, 0, "before"), pos and end are unchanged + pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos + end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos + } + for (let limit = 0; limit < 5; limit++) { + let changed = false + let coords = cursorCoords(cm, pos) + let endCoords = !end || end == pos ? coords : cursorCoords(cm, end) + rect = {left: Math.min(coords.left, endCoords.left), + top: Math.min(coords.top, endCoords.top) - margin, + right: Math.max(coords.left, endCoords.left), + bottom: Math.max(coords.bottom, endCoords.bottom) + margin} + let scrollPos = calculateScrollPos(cm, rect) + let startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft + if (scrollPos.scrollTop != null) { + updateScrollTop(cm, scrollPos.scrollTop) + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft) + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true + } + if (!changed) break + } + return rect +} + +// Scroll a given set of coordinates into view (immediately). +export function scrollIntoView(cm, rect) { + let scrollPos = calculateScrollPos(cm, rect) + if (scrollPos.scrollTop != null) updateScrollTop(cm, scrollPos.scrollTop) + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft) +} + +// Calculate a new scroll position needed to scroll the given +// rectangle into view. Returns an object with scrollTop and +// scrollLeft properties. When these are undefined, the +// vertical/horizontal position does not need to be adjusted. +function calculateScrollPos(cm, rect) { + let display = cm.display, snapMargin = textHeight(cm.display) + if (rect.top < 0) rect.top = 0 + let screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop + let screen = displayHeight(cm), result = {} + if (rect.bottom - rect.top > screen) rect.bottom = rect.top + screen + let docBottom = cm.doc.height + paddingVert(display) + let atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin + if (rect.top < screentop) { + result.scrollTop = atTop ? 0 : rect.top + } else if (rect.bottom > screentop + screen) { + let newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen) + if (newTop != screentop) result.scrollTop = newTop + } + + let screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft + let screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0) + let tooWide = rect.right - rect.left > screenw + if (tooWide) rect.right = rect.left + screenw + if (rect.left < 10) + result.scrollLeft = 0 + else if (rect.left < screenleft) + result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) + else if (rect.right > screenw + screenleft - 3) + result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw + return result +} + +// Store a relative adjustment to the scroll position in the current +// operation (to be applied when the operation finishes). +export function addToScrollTop(cm, top) { + if (top == null) return + resolveScrollToPos(cm) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top +} + +// Make sure that at the end of the operation the current cursor is +// shown. +export function ensureCursorVisible(cm) { + resolveScrollToPos(cm) + let cur = cm.getCursor() + cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin} +} + +export function scrollToCoords(cm, x, y) { + if (x != null || y != null) resolveScrollToPos(cm) + if (x != null) cm.curOp.scrollLeft = x + if (y != null) cm.curOp.scrollTop = y +} + +export function scrollToRange(cm, range) { + resolveScrollToPos(cm) + cm.curOp.scrollToPos = range +} + +// When an operation has its scrollToPos property set, and another +// scroll action is applied before the end of the operation, this +// 'simulates' scrolling that position into view in a cheap way, so +// that the effect of intermediate scroll commands is not ignored. +function resolveScrollToPos(cm) { + let range = cm.curOp.scrollToPos + if (range) { + cm.curOp.scrollToPos = null + let from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to) + scrollToCoordsRange(cm, from, to, range.margin) + } +} + +export function scrollToCoordsRange(cm, from, to, margin) { + let sPos = calculateScrollPos(cm, { + left: Math.min(from.left, to.left), + top: Math.min(from.top, to.top) - margin, + right: Math.max(from.right, to.right), + bottom: Math.max(from.bottom, to.bottom) + margin + }) + scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop) +} + +// Sync the scrollable area and scrollbars, ensure the viewport +// covers the visible area. +export function updateScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return + if (!gecko) updateDisplaySimple(cm, {top: val}) + setScrollTop(cm, val, true) + if (gecko) updateDisplaySimple(cm) + startWorker(cm, 100) +} + +export function setScrollTop(cm, val, forceScroll) { + val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val) + if (cm.display.scroller.scrollTop == val && !forceScroll) return + cm.doc.scrollTop = val + cm.display.scrollbars.setScrollTop(val) + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val +} + +// Sync scroller and scrollbar, ensure the gutter elements are +// aligned. +export function setScrollLeft(cm, val, isScroller, forceScroll) { + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth) + if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) return + cm.doc.scrollLeft = val + alignHorizontally(cm) + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val + cm.display.scrollbars.setScrollLeft(val) +} diff --git a/backend/webif/static/codemirror/src/display/selection.js b/backend/webif/static/codemirror/src/display/selection.js new file mode 100755 index 000000000..c658c0a27 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/selection.js @@ -0,0 +1,158 @@ +import { Pos } from "../line/pos.js" +import { visualLine } from "../line/spans.js" +import { getLine } from "../line/utils_line.js" +import { charCoords, cursorCoords, displayWidth, paddingH, wrappedLineExtentChar } from "../measurement/position_measurement.js" +import { getOrder, iterateBidiSections } from "../util/bidi.js" +import { elt } from "../util/dom.js" + +export function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()) +} + +export function prepareSelection(cm, primary = true) { + let doc = cm.doc, result = {} + let curFragment = result.cursors = document.createDocumentFragment() + let selFragment = result.selection = document.createDocumentFragment() + + for (let i = 0; i < doc.sel.ranges.length; i++) { + if (!primary && i == doc.sel.primIndex) continue + let range = doc.sel.ranges[i] + if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue + let collapsed = range.empty() + if (collapsed || cm.options.showCursorWhenSelecting) + drawSelectionCursor(cm, range.head, curFragment) + if (!collapsed) + drawSelectionRange(cm, range, selFragment) + } + return result +} + +// Draws a cursor for the given range +export function drawSelectionCursor(cm, head, output) { + let pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine) + + let cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")) + cursor.style.left = pos.left + "px" + cursor.style.top = pos.top + "px" + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px" + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + let otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")) + otherCursor.style.display = "" + otherCursor.style.left = pos.other.left + "px" + otherCursor.style.top = pos.other.top + "px" + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px" + } +} + +function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } + +// Draws the given range as a highlighted selection +function drawSelectionRange(cm, range, output) { + let display = cm.display, doc = cm.doc + let fragment = document.createDocumentFragment() + let padding = paddingH(cm.display), leftSide = padding.left + let rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right + let docLTR = doc.direction == "ltr" + + function add(left, top, width, bottom) { + if (top < 0) top = 0 + top = Math.round(top) + bottom = Math.round(bottom) + fragment.appendChild(elt("div", null, "CodeMirror-selected", `position: absolute; left: ${left}px; + top: ${top}px; width: ${width == null ? rightSide - left : width}px; + height: ${bottom - top}px`)) + } + + function drawForLine(line, fromArg, toArg) { + let lineObj = getLine(doc, line) + let lineLen = lineObj.text.length + let start, end + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias) + } + + function wrapX(pos, dir, side) { + let extent = wrappedLineExtentChar(cm, lineObj, null, pos) + let prop = (dir == "ltr") == (side == "after") ? "left" : "right" + let ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1) + return coords(ch, prop)[prop] + } + + let order = getOrder(lineObj, doc.direction) + iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, (from, to, dir, i) => { + let ltr = dir == "ltr" + let fromPos = coords(from, ltr ? "left" : "right") + let toPos = coords(to - 1, ltr ? "right" : "left") + + let openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen + let first = i == 0, last = !order || i == order.length - 1 + if (toPos.top - fromPos.top <= 3) { // Single line + let openLeft = (docLTR ? openStart : openEnd) && first + let openRight = (docLTR ? openEnd : openStart) && last + let left = openLeft ? leftSide : (ltr ? fromPos : toPos).left + let right = openRight ? rightSide : (ltr ? toPos : fromPos).right + add(left, fromPos.top, right - left, fromPos.bottom) + } else { // Multiple lines + let topLeft, topRight, botLeft, botRight + if (ltr) { + topLeft = docLTR && openStart && first ? leftSide : fromPos.left + topRight = docLTR ? rightSide : wrapX(from, dir, "before") + botLeft = docLTR ? leftSide : wrapX(to, dir, "after") + botRight = docLTR && openEnd && last ? rightSide : toPos.right + } else { + topLeft = !docLTR ? leftSide : wrapX(from, dir, "before") + topRight = !docLTR && openStart && first ? rightSide : fromPos.right + botLeft = !docLTR && openEnd && last ? leftSide : toPos.left + botRight = !docLTR ? rightSide : wrapX(to, dir, "after") + } + add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom) + if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top) + add(botLeft, toPos.top, botRight - botLeft, toPos.bottom) + } + + if (!start || cmpCoords(fromPos, start) < 0) start = fromPos + if (cmpCoords(toPos, start) < 0) start = toPos + if (!end || cmpCoords(fromPos, end) < 0) end = fromPos + if (cmpCoords(toPos, end) < 0) end = toPos + }) + return {start: start, end: end} + } + + let sFrom = range.from(), sTo = range.to() + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch) + } else { + let fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line) + let singleVLine = visualLine(fromLine) == visualLine(toLine) + let leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end + let rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom) + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom) + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom) + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top) + } + + output.appendChild(fragment) +} + +// Cursor-blinking +export function restartBlink(cm) { + if (!cm.state.focused) return + let display = cm.display + clearInterval(display.blinker) + let on = true + display.cursorDiv.style.visibility = "" + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(() => display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden", + cm.options.cursorBlinkRate) + else if (cm.options.cursorBlinkRate < 0) + display.cursorDiv.style.visibility = "hidden" +} diff --git a/backend/webif/static/codemirror/src/display/update_display.js b/backend/webif/static/codemirror/src/display/update_display.js new file mode 100755 index 000000000..86c713213 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/update_display.js @@ -0,0 +1,260 @@ +import { sawCollapsedSpans } from "../line/saw_special_spans.js" +import { heightAtLine, visualLineEndNo, visualLineNo } from "../line/spans.js" +import { getLine, lineNumberFor } from "../line/utils_line.js" +import { displayHeight, displayWidth, getDimensions, paddingVert, scrollGap } from "../measurement/position_measurement.js" +import { mac, webkit } from "../util/browser.js" +import { activeElt, removeChildren, contains } from "../util/dom.js" +import { hasHandler, signal } from "../util/event.js" +import { indexOf } from "../util/misc.js" + +import { buildLineElement, updateLineForChanges } from "./update_line.js" +import { startWorker } from "./highlight_worker.js" +import { maybeUpdateLineNumberWidth } from "./line_numbers.js" +import { measureForScrollbars, updateScrollbars } from "./scrollbars.js" +import { updateSelection } from "./selection.js" +import { updateHeightsInViewport, visibleLines } from "./update_lines.js" +import { adjustView, countDirtyView, resetView } from "./view_tracking.js" + +// DISPLAY DRAWING + +export class DisplayUpdate { + constructor(cm, viewport, force) { + let display = cm.display + + this.viewport = viewport + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport) + this.editorIsHidden = !display.wrapper.offsetWidth + this.wrapperHeight = display.wrapper.clientHeight + this.wrapperWidth = display.wrapper.clientWidth + this.oldDisplayWidth = displayWidth(cm) + this.force = force + this.dims = getDimensions(cm) + this.events = [] + } + + signal(emitter, type) { + if (hasHandler(emitter, type)) + this.events.push(arguments) + } + finish() { + for (let i = 0; i < this.events.length; i++) + signal.apply(null, this.events[i]) + } +} + +export function maybeClipScrollbars(cm) { + let display = cm.display + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth + display.heightForcer.style.height = scrollGap(cm) + "px" + display.sizer.style.marginBottom = -display.nativeBarWidth + "px" + display.sizer.style.borderRightWidth = scrollGap(cm) + "px" + display.scrollbarsClipped = true + } +} + +function selectionSnapshot(cm) { + if (cm.hasFocus()) return null + let active = activeElt() + if (!active || !contains(cm.display.lineDiv, active)) return null + let result = {activeElt: active} + if (window.getSelection) { + let sel = window.getSelection() + if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { + result.anchorNode = sel.anchorNode + result.anchorOffset = sel.anchorOffset + result.focusNode = sel.focusNode + result.focusOffset = sel.focusOffset + } + } + return result +} + +function restoreSelection(snapshot) { + if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) return + snapshot.activeElt.focus() + if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { + let sel = window.getSelection(), range = document.createRange() + range.setEnd(snapshot.anchorNode, snapshot.anchorOffset) + range.collapse(false) + sel.removeAllRanges() + sel.addRange(range) + sel.extend(snapshot.focusNode, snapshot.focusOffset) + } +} + +// Does the actual updating of the line display. Bails out +// (returning false) when there is nothing to be done and forced is +// false. +export function updateDisplayIfNeeded(cm, update) { + let display = cm.display, doc = cm.doc + + if (update.editorIsHidden) { + resetView(cm) + return false + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + return false + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm) + update.dims = getDimensions(cm) + } + + // Compute a suitable new viewport (from & to) + let end = doc.first + doc.size + let from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first) + let to = Math.min(end, update.visible.to + cm.options.viewportMargin) + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom) + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo) + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from) + to = visualLineEndNo(cm.doc, to) + } + + let different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth + adjustView(cm, from, to) + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)) + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px" + + let toUpdate = countDirtyView(cm) + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + return false + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + let selSnapshot = selectionSnapshot(cm) + if (toUpdate > 4) display.lineDiv.style.display = "none" + patchDisplay(cm, display.updateLineNumbers, update.dims) + if (toUpdate > 4) display.lineDiv.style.display = "" + display.renderedView = display.view + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + restoreSelection(selSnapshot) + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv) + removeChildren(display.selectionDiv) + display.gutters.style.height = display.sizer.style.minHeight = 0 + + if (different) { + display.lastWrapHeight = update.wrapperHeight + display.lastWrapWidth = update.wrapperWidth + startWorker(cm, 400) + } + + display.updateLineNumbers = null + + return true +} + +export function postUpdateDisplay(cm, update) { + let viewport = update.viewport + + for (let first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)} + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport) + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + break + } + if (!updateDisplayIfNeeded(cm, update)) break + updateHeightsInViewport(cm) + let barMeasure = measureForScrollbars(cm) + updateSelection(cm) + updateScrollbars(cm, barMeasure) + setDocumentHeight(cm, barMeasure) + update.force = false + } + + update.signal(cm, "update", cm) + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo) + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo + } +} + +export function updateDisplaySimple(cm, viewport) { + let update = new DisplayUpdate(cm, viewport) + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm) + postUpdateDisplay(cm, update) + let barMeasure = measureForScrollbars(cm) + updateSelection(cm) + updateScrollbars(cm, barMeasure) + setDocumentHeight(cm, barMeasure) + update.finish() + } +} + +// Sync the actual display DOM structure with display.view, removing +// nodes for lines that are no longer in view, and creating the ones +// that are not there yet, and updating the ones that are out of +// date. +function patchDisplay(cm, updateNumbersFrom, dims) { + let display = cm.display, lineNumbers = cm.options.lineNumbers + let container = display.lineDiv, cur = container.firstChild + + function rm(node) { + let next = node.nextSibling + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none" + else + node.parentNode.removeChild(node) + return next + } + + let view = display.view, lineN = display.viewFrom + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (let i = 0; i < view.length; i++) { + let lineView = view[i] + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + let node = buildLineElement(cm, lineView, lineN, dims) + container.insertBefore(node, cur) + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur) + let updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false + updateLineForChanges(cm, lineView, lineN, dims) + } + if (updateNumber) { + removeChildren(lineView.lineNumber) + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))) + } + cur = lineView.node.nextSibling + } + lineN += lineView.size + } + while (cur) cur = rm(cur) +} + +export function updateGutterSpace(cm) { + let width = cm.display.gutters.offsetWidth + cm.display.sizer.style.marginLeft = width + "px" +} + +export function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px" + cm.display.heightForcer.style.top = measure.docHeight + "px" + cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px" +} diff --git a/backend/webif/static/codemirror/src/display/update_line.js b/backend/webif/static/codemirror/src/display/update_line.js new file mode 100755 index 000000000..db9df26d9 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/update_line.js @@ -0,0 +1,188 @@ +import { buildLineContent } from "../line/line_data.js" +import { lineNumberFor } from "../line/utils_line.js" +import { ie, ie_version } from "../util/browser.js" +import { elt } from "../util/dom.js" +import { signalLater } from "../util/operation_group.js" + +// When an aspect of a line changes, a string is added to +// lineView.changes. This updates the relevant part of the line's +// DOM structure. +export function updateLineForChanges(cm, lineView, lineN, dims) { + for (let j = 0; j < lineView.changes.length; j++) { + let type = lineView.changes[j] + if (type == "text") updateLineText(cm, lineView) + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims) + else if (type == "class") updateLineClasses(cm, lineView) + else if (type == "widget") updateLineWidgets(cm, lineView, dims) + } + lineView.changes = null +} + +// Lines with gutter elements, widgets or a background class need to +// be wrapped, and have the extra elements added to the wrapper div +function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative") + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text) + lineView.node.appendChild(lineView.text) + if (ie && ie_version < 8) lineView.node.style.zIndex = 2 + } + return lineView.node +} + +function updateLineBackground(cm, lineView) { + let cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass + if (cls) cls += " CodeMirror-linebackground" + if (lineView.background) { + if (cls) lineView.background.className = cls + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null } + } else if (cls) { + let wrap = ensureLineWrapped(lineView) + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild) + cm.display.input.setUneditable(lineView.background) + } +} + +// Wrapper around buildLineContent which will reuse the structure +// in display.externalMeasured when possible. +function getLineContent(cm, lineView) { + let ext = cm.display.externalMeasured + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null + lineView.measure = ext.measure + return ext.built + } + return buildLineContent(cm, lineView) +} + +// Redraw the line's text. Interacts with the background and text +// classes because the mode may output tokens that influence these +// classes. +function updateLineText(cm, lineView) { + let cls = lineView.text.className + let built = getLineContent(cm, lineView) + if (lineView.text == lineView.node) lineView.node = built.pre + lineView.text.parentNode.replaceChild(built.pre, lineView.text) + lineView.text = built.pre + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass + lineView.textClass = built.textClass + updateLineClasses(cm, lineView) + } else if (cls) { + lineView.text.className = cls + } +} + +function updateLineClasses(cm, lineView) { + updateLineBackground(cm, lineView) + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass + else if (lineView.node != lineView.text) + lineView.node.className = "" + let textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass + lineView.text.className = textClass || "" +} + +function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter) + lineView.gutter = null + } + if (lineView.gutterBackground) { + lineView.node.removeChild(lineView.gutterBackground) + lineView.gutterBackground = null + } + if (lineView.line.gutterClass) { + let wrap = ensureLineWrapped(lineView) + lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, + `left: ${cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth}px; width: ${dims.gutterTotalWidth}px`) + cm.display.input.setUneditable(lineView.gutterBackground) + wrap.insertBefore(lineView.gutterBackground, lineView.text) + } + let markers = lineView.line.gutterMarkers + if (cm.options.lineNumbers || markers) { + let wrap = ensureLineWrapped(lineView) + let gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", `left: ${cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth}px`) + cm.display.input.setUneditable(gutterWrap) + wrap.insertBefore(gutterWrap, lineView.text) + if (lineView.line.gutterClass) + gutterWrap.className += " " + lineView.line.gutterClass + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + `left: ${dims.gutterLeft["CodeMirror-linenumbers"]}px; width: ${cm.display.lineNumInnerWidth}px`)) + if (markers) for (let k = 0; k < cm.options.gutters.length; ++k) { + let id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id] + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", + `left: ${dims.gutterLeft[id]}px; width: ${dims.gutterWidth[id]}px`)) + } + } +} + +function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) lineView.alignable = null + for (let node = lineView.node.firstChild, next; node; node = next) { + next = node.nextSibling + if (node.className == "CodeMirror-linewidget") + lineView.node.removeChild(node) + } + insertLineWidgets(cm, lineView, dims) +} + +// Build a line's DOM representation from scratch +export function buildLineElement(cm, lineView, lineN, dims) { + let built = getLineContent(cm, lineView) + lineView.text = lineView.node = built.pre + if (built.bgClass) lineView.bgClass = built.bgClass + if (built.textClass) lineView.textClass = built.textClass + + updateLineClasses(cm, lineView) + updateLineGutter(cm, lineView, lineN, dims) + insertLineWidgets(cm, lineView, dims) + return lineView.node +} + +// A lineView may contain multiple logical lines (when merged by +// collapsed spans). The widgets for all of them need to be drawn. +function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true) + if (lineView.rest) for (let i = 0; i < lineView.rest.length; i++) + insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) +} + +function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) return + let wrap = ensureLineWrapped(lineView) + for (let i = 0, ws = line.widgets; i < ws.length; ++i) { + let widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget") + if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true") + positionLineWidget(widget, node, lineView, dims) + cm.display.input.setUneditable(node) + if (allowAbove && widget.above) + wrap.insertBefore(node, lineView.gutter || lineView.text) + else + wrap.appendChild(node) + signalLater(widget, "redraw") + } +} + +function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + ;(lineView.alignable || (lineView.alignable = [])).push(node) + let width = dims.wrapperWidth + node.style.left = dims.fixedPos + "px" + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth + node.style.paddingLeft = dims.gutterTotalWidth + "px" + } + node.style.width = width + "px" + } + if (widget.coverGutter) { + node.style.zIndex = 5 + node.style.position = "relative" + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px" + } +} diff --git a/backend/webif/static/codemirror/src/display/update_lines.js b/backend/webif/static/codemirror/src/display/update_lines.js new file mode 100755 index 000000000..7f06018d0 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/update_lines.js @@ -0,0 +1,64 @@ +import { heightAtLine } from "../line/spans.js" +import { getLine, lineAtHeight, updateLineHeight } from "../line/utils_line.js" +import { paddingTop, textHeight } from "../measurement/position_measurement.js" +import { ie, ie_version } from "../util/browser.js" + +// Read the actual heights of the rendered lines, and update their +// stored heights to match. +export function updateHeightsInViewport(cm) { + let display = cm.display + let prevBottom = display.lineDiv.offsetTop + for (let i = 0; i < display.view.length; i++) { + let cur = display.view[i], height + if (cur.hidden) continue + if (ie && ie_version < 8) { + let bot = cur.node.offsetTop + cur.node.offsetHeight + height = bot - prevBottom + prevBottom = bot + } else { + let box = cur.node.getBoundingClientRect() + height = box.bottom - box.top + } + let diff = cur.line.height - height + if (height < 2) height = textHeight(display) + if (diff > .005 || diff < -.005) { + updateLineHeight(cur.line, height) + updateWidgetHeight(cur.line) + if (cur.rest) for (let j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]) + } + } +} + +// Read and store the height of line widgets associated with the +// given line. +function updateWidgetHeight(line) { + if (line.widgets) for (let i = 0; i < line.widgets.length; ++i) { + let w = line.widgets[i], parent = w.node.parentNode + if (parent) w.height = parent.offsetHeight + } +} + +// Compute the lines that are visible in a given viewport (defaults +// the the current scroll position). viewport may contain top, +// height, and ensure (see op.scrollToPos) properties. +export function visibleLines(display, doc, viewport) { + let top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop + top = Math.floor(top - paddingTop(display)) + let bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight + + let from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom) + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + let ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line + if (ensureFrom < from) { + from = ensureFrom + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight) + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight) + to = ensureTo + } + } + return {from: from, to: Math.max(to, from + 1)} +} diff --git a/backend/webif/static/codemirror/src/display/view_tracking.js b/backend/webif/static/codemirror/src/display/view_tracking.js new file mode 100755 index 000000000..41464f235 --- /dev/null +++ b/backend/webif/static/codemirror/src/display/view_tracking.js @@ -0,0 +1,153 @@ +import { buildViewArray } from "../line/line_data.js" +import { sawCollapsedSpans } from "../line/saw_special_spans.js" +import { visualLineEndNo, visualLineNo } from "../line/spans.js" +import { findViewIndex } from "../measurement/position_measurement.js" +import { indexOf } from "../util/misc.js" + +// Updates the display.view data structure for a given change to the +// document. From and to are in pre-change coordinates. Lendiff is +// the amount of lines added or subtracted by the change. This is +// used for changes that span multiple lines, or change the way +// lines are divided into visual lines. regLineChange (below) +// registers single-line changes. +export function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first + if (to == null) to = cm.doc.first + cm.doc.size + if (!lendiff) lendiff = 0 + + let display = cm.display + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from + + cm.curOp.viewChanged = true + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm) + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm) + } else { + display.viewFrom += lendiff + display.viewTo += lendiff + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm) + } else if (from <= display.viewFrom) { // Top overlap + let cut = viewCuttingPoint(cm, to, to + lendiff, 1) + if (cut) { + display.view = display.view.slice(cut.index) + display.viewFrom = cut.lineN + display.viewTo += lendiff + } else { + resetView(cm) + } + } else if (to >= display.viewTo) { // Bottom overlap + let cut = viewCuttingPoint(cm, from, from, -1) + if (cut) { + display.view = display.view.slice(0, cut.index) + display.viewTo = cut.lineN + } else { + resetView(cm) + } + } else { // Gap in the middle + let cutTop = viewCuttingPoint(cm, from, from, -1) + let cutBot = viewCuttingPoint(cm, to, to + lendiff, 1) + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)) + display.viewTo += lendiff + } else { + resetView(cm) + } + } + + let ext = display.externalMeasured + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff + else if (from < ext.lineN + ext.size) + display.externalMeasured = null + } +} + +// Register a change to a single line. Type must be one of "text", +// "gutter", "class", "widget" +export function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true + let display = cm.display, ext = cm.display.externalMeasured + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null + + if (line < display.viewFrom || line >= display.viewTo) return + let lineView = display.view[findViewIndex(cm, line)] + if (lineView.node == null) return + let arr = lineView.changes || (lineView.changes = []) + if (indexOf(arr, type) == -1) arr.push(type) +} + +// Clear the view. +export function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first + cm.display.view = [] + cm.display.viewOffset = 0 +} + +function viewCuttingPoint(cm, oldN, newN, dir) { + let index = findViewIndex(cm, oldN), diff, view = cm.display.view + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + return {index: index, lineN: newN} + let n = cm.display.viewFrom + for (let i = 0; i < index; i++) + n += view[i].size + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null + diff = (n + view[index].size) - oldN + index++ + } else { + diff = n - oldN + } + oldN += diff; newN += diff + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null + newN += dir * view[index - (dir < 0 ? 1 : 0)].size + index += dir + } + return {index: index, lineN: newN} +} + +// Force the view to cover a given range, adding empty view element +// or clipping off existing ones as needed. +export function adjustView(cm, from, to) { + let display = cm.display, view = display.view + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to) + display.viewFrom = from + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view) + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)) + display.viewFrom = from + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)) + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)) + } + display.viewTo = to +} + +// Count the number of lines in the view whose DOM representation is +// out of date (or nonexistent). +export function countDirtyView(cm) { + let view = cm.display.view, dirty = 0 + for (let i = 0; i < view.length; i++) { + let lineView = view[i] + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty + } + return dirty +} diff --git a/backend/webif/static/codemirror/src/edit/CodeMirror.js b/backend/webif/static/codemirror/src/edit/CodeMirror.js new file mode 100755 index 000000000..4759209cf --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/CodeMirror.js @@ -0,0 +1,214 @@ +import { Display } from "../display/Display.js" +import { onFocus, onBlur } from "../display/focus.js" +import { setGuttersForLineNumbers, updateGutters } from "../display/gutters.js" +import { maybeUpdateLineNumberWidth } from "../display/line_numbers.js" +import { endOperation, operation, startOperation } from "../display/operations.js" +import { initScrollbars } from "../display/scrollbars.js" +import { onScrollWheel } from "../display/scroll_events.js" +import { setScrollLeft, updateScrollTop } from "../display/scrolling.js" +import { clipPos, Pos } from "../line/pos.js" +import { posFromMouse } from "../measurement/position_measurement.js" +import { eventInWidget } from "../measurement/widgets.js" +import Doc from "../model/Doc.js" +import { attachDoc } from "../model/document_data.js" +import { Range } from "../model/selection.js" +import { extendSelection } from "../model/selection_updates.js" +import { captureRightClick, ie, ie_version, mobile, webkit } from "../util/browser.js" +import { e_preventDefault, e_stop, on, signal, signalDOMEvent } from "../util/event.js" +import { bind, copyObj, Delayed } from "../util/misc.js" + +import { clearDragCursor, onDragOver, onDragStart, onDrop } from "./drop_events.js" +import { ensureGlobalHandlers } from "./global_events.js" +import { onKeyDown, onKeyPress, onKeyUp } from "./key_events.js" +import { clickInGutter, onContextMenu, onMouseDown } from "./mouse_events.js" +import { themeChanged } from "./utils.js" +import { defaults, optionHandlers, Init } from "./options.js" + +// A CodeMirror instance represents an editor. This is the object +// that user code is usually dealing with. + +export function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options) + + this.options = options = options ? copyObj(options) : {} + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false) + setGuttersForLineNumbers(options) + + let doc = options.value + if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) + this.doc = doc + + let input = new CodeMirror.inputStyles[options.inputStyle](this) + let display = this.display = new Display(place, doc, input) + display.wrapper.CodeMirror = this + updateGutters(this) + themeChanged(this) + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap" + initScrollbars(this) + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + selectingText: false, + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + } + + if (options.autofocus && !mobile) display.input.focus() + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) setTimeout(() => this.display.input.reset(true), 20) + + registerEventHandlers(this) + ensureGlobalHandlers() + + startOperation(this) + this.curOp.forceUpdate = true + attachDoc(this, doc) + + if ((options.autofocus && !mobile) || this.hasFocus()) + setTimeout(bind(onFocus, this), 20) + else + onBlur(this) + + for (let opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](this, options[opt], Init) + maybeUpdateLineNumberWidth(this) + if (options.finishInit) options.finishInit(this) + for (let i = 0; i < initHooks.length; ++i) initHooks[i](this) + endOperation(this) + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + display.lineDiv.style.textRendering = "auto" +} + +// The default configuration options. +CodeMirror.defaults = defaults +// Functions to run when options are changed. +CodeMirror.optionHandlers = optionHandlers + +export default CodeMirror + +// Attach the necessary event handlers when initializing the editor +function registerEventHandlers(cm) { + let d = cm.display + on(d.scroller, "mousedown", operation(cm, onMouseDown)) + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + on(d.scroller, "dblclick", operation(cm, e => { + if (signalDOMEvent(cm, e)) return + let pos = posFromMouse(cm, e) + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return + e_preventDefault(e) + let word = cm.findWordAt(pos) + extendSelection(cm.doc, word.anchor, word.head) + })) + else + on(d.scroller, "dblclick", e => signalDOMEvent(cm, e) || e_preventDefault(e)) + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", e => onContextMenu(cm, e)) + + // Used to suppress mouse event handling when a touch happens + let touchFinished, prevTouch = {end: 0} + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(() => d.activeTouch = null, 1000) + prevTouch = d.activeTouch + prevTouch.end = +new Date + } + } + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) return false + let touch = e.touches[0] + return touch.radiusX <= 1 && touch.radiusY <= 1 + } + function farAway(touch, other) { + if (other.left == null) return true + let dx = other.left - touch.left, dy = other.top - touch.top + return dx * dx + dy * dy > 20 * 20 + } + on(d.scroller, "touchstart", e => { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) { + d.input.ensurePolled() + clearTimeout(touchFinished) + let now = +new Date + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null} + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX + d.activeTouch.top = e.touches[0].pageY + } + } + }) + on(d.scroller, "touchmove", () => { + if (d.activeTouch) d.activeTouch.moved = true + }) + on(d.scroller, "touchend", e => { + let touch = d.activeTouch + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + let pos = cm.coordsChar(d.activeTouch, "page"), range + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + range = new Range(pos, pos) + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + range = cm.findWordAt(pos) + else // Triple tap + range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) + cm.setSelection(range.anchor, range.head) + cm.focus() + e_preventDefault(e) + } + finishTouch() + }) + on(d.scroller, "touchcancel", finishTouch) + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", () => { + if (d.scroller.clientHeight) { + updateScrollTop(cm, d.scroller.scrollTop) + setScrollLeft(cm, d.scroller.scrollLeft, true) + signal(cm, "scroll", cm) + } + }) + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", e => onScrollWheel(cm, e)) + on(d.scroller, "DOMMouseScroll", e => onScrollWheel(cm, e)) + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", () => d.wrapper.scrollTop = d.wrapper.scrollLeft = 0) + + d.dragFunctions = { + enter: e => {if (!signalDOMEvent(cm, e)) e_stop(e)}, + over: e => {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e) }}, + start: e => onDragStart(cm, e), + drop: operation(cm, onDrop), + leave: e => {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm) }} + } + + let inp = d.input.getField() + on(inp, "keyup", e => onKeyUp.call(cm, e)) + on(inp, "keydown", operation(cm, onKeyDown)) + on(inp, "keypress", operation(cm, onKeyPress)) + on(inp, "focus", e => onFocus(cm, e)) + on(inp, "blur", e => onBlur(cm, e)) +} + +let initHooks = [] +CodeMirror.defineInitHook = f => initHooks.push(f) diff --git a/backend/webif/static/codemirror/src/edit/commands.js b/backend/webif/static/codemirror/src/edit/commands.js new file mode 100755 index 000000000..3916b129f --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/commands.js @@ -0,0 +1,178 @@ +import { deleteNearSelection } from "./deleteNearSelection.js" +import { runInOp } from "../display/operations.js" +import { ensureCursorVisible } from "../display/scrolling.js" +import { endOfLine } from "../input/movement.js" +import { clipPos, Pos } from "../line/pos.js" +import { visualLine, visualLineEnd } from "../line/spans.js" +import { getLine, lineNo } from "../line/utils_line.js" +import { Range } from "../model/selection.js" +import { selectAll } from "../model/selection_updates.js" +import { countColumn, sel_dontScroll, sel_move, spaceStr } from "../util/misc.js" +import { getOrder } from "../util/bidi.js" + +// Commands are parameter-less actions that can be performed on an +// editor, mostly used for keybindings. +export let commands = { + selectAll: selectAll, + singleSelection: cm => cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll), + killLine: cm => deleteNearSelection(cm, range => { + if (range.empty()) { + let len = getLine(cm.doc, range.head.line).text.length + if (range.head.ch == len && range.head.line < cm.lastLine()) + return {from: range.head, to: Pos(range.head.line + 1, 0)} + else + return {from: range.head, to: Pos(range.head.line, len)} + } else { + return {from: range.from(), to: range.to()} + } + }), + deleteLine: cm => deleteNearSelection(cm, range => ({ + from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) + })), + delLineLeft: cm => deleteNearSelection(cm, range => ({ + from: Pos(range.from().line, 0), to: range.from() + })), + delWrappedLineLeft: cm => deleteNearSelection(cm, range => { + let top = cm.charCoords(range.head, "div").top + 5 + let leftPos = cm.coordsChar({left: 0, top: top}, "div") + return {from: leftPos, to: range.from()} + }), + delWrappedLineRight: cm => deleteNearSelection(cm, range => { + let top = cm.charCoords(range.head, "div").top + 5 + let rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") + return {from: range.from(), to: rightPos } + }), + undo: cm => cm.undo(), + redo: cm => cm.redo(), + undoSelection: cm => cm.undoSelection(), + redoSelection: cm => cm.redoSelection(), + goDocStart: cm => cm.extendSelection(Pos(cm.firstLine(), 0)), + goDocEnd: cm => cm.extendSelection(Pos(cm.lastLine())), + goLineStart: cm => cm.extendSelectionsBy(range => lineStart(cm, range.head.line), + {origin: "+move", bias: 1} + ), + goLineStartSmart: cm => cm.extendSelectionsBy(range => lineStartSmart(cm, range.head), + {origin: "+move", bias: 1} + ), + goLineEnd: cm => cm.extendSelectionsBy(range => lineEnd(cm, range.head.line), + {origin: "+move", bias: -1} + ), + goLineRight: cm => cm.extendSelectionsBy(range => { + let top = cm.cursorCoords(range.head, "div").top + 5 + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") + }, sel_move), + goLineLeft: cm => cm.extendSelectionsBy(range => { + let top = cm.cursorCoords(range.head, "div").top + 5 + return cm.coordsChar({left: 0, top: top}, "div") + }, sel_move), + goLineLeftSmart: cm => cm.extendSelectionsBy(range => { + let top = cm.cursorCoords(range.head, "div").top + 5 + let pos = cm.coordsChar({left: 0, top: top}, "div") + if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head) + return pos + }, sel_move), + goLineUp: cm => cm.moveV(-1, "line"), + goLineDown: cm => cm.moveV(1, "line"), + goPageUp: cm => cm.moveV(-1, "page"), + goPageDown: cm => cm.moveV(1, "page"), + goCharLeft: cm => cm.moveH(-1, "char"), + goCharRight: cm => cm.moveH(1, "char"), + goColumnLeft: cm => cm.moveH(-1, "column"), + goColumnRight: cm => cm.moveH(1, "column"), + goWordLeft: cm => cm.moveH(-1, "word"), + goGroupRight: cm => cm.moveH(1, "group"), + goGroupLeft: cm => cm.moveH(-1, "group"), + goWordRight: cm => cm.moveH(1, "word"), + delCharBefore: cm => cm.deleteH(-1, "char"), + delCharAfter: cm => cm.deleteH(1, "char"), + delWordBefore: cm => cm.deleteH(-1, "word"), + delWordAfter: cm => cm.deleteH(1, "word"), + delGroupBefore: cm => cm.deleteH(-1, "group"), + delGroupAfter: cm => cm.deleteH(1, "group"), + indentAuto: cm => cm.indentSelection("smart"), + indentMore: cm => cm.indentSelection("add"), + indentLess: cm => cm.indentSelection("subtract"), + insertTab: cm => cm.replaceSelection("\t"), + insertSoftTab: cm => { + let spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize + for (let i = 0; i < ranges.length; i++) { + let pos = ranges[i].from() + let col = countColumn(cm.getLine(pos.line), pos.ch, tabSize) + spaces.push(spaceStr(tabSize - col % tabSize)) + } + cm.replaceSelections(spaces) + }, + defaultTab: cm => { + if (cm.somethingSelected()) cm.indentSelection("add") + else cm.execCommand("insertTab") + }, + // Swap the two chars left and right of each selection's head. + // Move cursor behind the two swapped characters afterwards. + // + // Doesn't consider line feeds a character. + // Doesn't scan more than one line above to find a character. + // Doesn't do anything on an empty line. + // Doesn't do anything with non-empty selections. + transposeChars: cm => runInOp(cm, () => { + let ranges = cm.listSelections(), newSel = [] + for (let i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) continue + let cur = ranges[i].head, line = getLine(cm.doc, cur.line).text + if (line) { + if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1) + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1) + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose") + } else if (cur.line > cm.doc.first) { + let prev = getLine(cm.doc, cur.line - 1).text + if (prev) { + cur = new Pos(cur.line, 1) + cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), cur, "+transpose") + } + } + } + newSel.push(new Range(cur, cur)) + } + cm.setSelections(newSel) + }), + newlineAndIndent: cm => runInOp(cm, () => { + let sels = cm.listSelections() + for (let i = sels.length - 1; i >= 0; i--) + cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input") + sels = cm.listSelections() + for (let i = 0; i < sels.length; i++) + cm.indentLine(sels[i].from().line, null, true) + ensureCursorVisible(cm) + }), + openLine: cm => cm.replaceSelection("\n", "start"), + toggleOverwrite: cm => cm.toggleOverwrite() +} + + +function lineStart(cm, lineN) { + let line = getLine(cm.doc, lineN) + let visual = visualLine(line) + if (visual != line) lineN = lineNo(visual) + return endOfLine(true, cm, visual, lineN, 1) +} +function lineEnd(cm, lineN) { + let line = getLine(cm.doc, lineN) + let visual = visualLineEnd(line) + if (visual != line) lineN = lineNo(visual) + return endOfLine(true, cm, line, lineN, -1) +} +function lineStartSmart(cm, pos) { + let start = lineStart(cm, pos.line) + let line = getLine(cm.doc, start.line) + let order = getOrder(line, cm.doc.direction) + if (!order || order[0].level == 0) { + let firstNonWS = Math.max(0, line.text.search(/\S/)) + let inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch + return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky) + } + return start +} diff --git a/backend/webif/static/codemirror/src/edit/deleteNearSelection.js b/backend/webif/static/codemirror/src/edit/deleteNearSelection.js new file mode 100755 index 000000000..82e331a5f --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/deleteNearSelection.js @@ -0,0 +1,30 @@ +import { runInOp } from "../display/operations.js" +import { ensureCursorVisible } from "../display/scrolling.js" +import { cmp } from "../line/pos.js" +import { replaceRange } from "../model/changes.js" +import { lst } from "../util/misc.js" + +// Helper for deleting text near the selection(s), used to implement +// backspace, delete, and similar functionality. +export function deleteNearSelection(cm, compute) { + let ranges = cm.doc.sel.ranges, kill = [] + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (let i = 0; i < ranges.length; i++) { + let toKill = compute(ranges[i]) + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + let replaced = kill.pop() + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from + break + } + } + kill.push(toKill) + } + // Next, remove those actual ranges. + runInOp(cm, () => { + for (let i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete") + ensureCursorVisible(cm) + }) +} diff --git a/backend/webif/static/codemirror/src/edit/drop_events.js b/backend/webif/static/codemirror/src/edit/drop_events.js new file mode 100755 index 000000000..12c760f0d --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/drop_events.js @@ -0,0 +1,119 @@ +import { drawSelectionCursor } from "../display/selection.js" +import { operation } from "../display/operations.js" +import { clipPos } from "../line/pos.js" +import { posFromMouse } from "../measurement/position_measurement.js" +import { eventInWidget } from "../measurement/widgets.js" +import { makeChange, replaceRange } from "../model/changes.js" +import { changeEnd } from "../model/change_measurement.js" +import { simpleSelection } from "../model/selection.js" +import { setSelectionNoUndo, setSelectionReplaceHistory } from "../model/selection_updates.js" +import { ie, presto, safari } from "../util/browser.js" +import { elt, removeChildrenAndAdd } from "../util/dom.js" +import { e_preventDefault, e_stop, signalDOMEvent } from "../util/event.js" +import { indexOf } from "../util/misc.js" + +// Kludge to work around strange IE behavior where it'll sometimes +// re-fire a series of drag-related events right after the drop (#1551) +let lastDrop = 0 + +export function onDrop(e) { + let cm = this + clearDragCursor(cm) + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return + e_preventDefault(e) + if (ie) lastDrop = +new Date + let pos = posFromMouse(cm, e, true), files = e.dataTransfer.files + if (!pos || cm.isReadOnly()) return + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + let n = files.length, text = Array(n), read = 0 + let loadFile = (file, i) => { + if (cm.options.allowDropFileTypes && + indexOf(cm.options.allowDropFileTypes, file.type) == -1) + return + + let reader = new FileReader + reader.onload = operation(cm, () => { + let content = reader.result + if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = "" + text[i] = content + if (++read == n) { + pos = clipPos(cm.doc, pos) + let change = {from: pos, to: pos, + text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), + origin: "paste"} + makeChange(cm.doc, change) + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))) + } + }) + reader.readAsText(file) + } + for (let i = 0; i < n; ++i) loadFile(files[i], i) + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e) + // Ensure the editor is re-focused + setTimeout(() => cm.display.input.focus(), 20) + return + } + try { + let text = e.dataTransfer.getData("Text") + if (text) { + let selected + if (cm.state.draggingText && !cm.state.draggingText.copy) + selected = cm.listSelections() + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)) + if (selected) for (let i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag") + cm.replaceSelection(text, "around", "paste") + cm.display.input.focus() + } + } + catch(e){} + } +} + +export function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return + + e.dataTransfer.setData("Text", cm.getSelection()) + e.dataTransfer.effectAllowed = "copyMove" + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + let img = elt("img", null, null, "position: fixed; left: 0; top: 0;") + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" + if (presto) { + img.width = img.height = 1 + cm.display.wrapper.appendChild(img) + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop + } + e.dataTransfer.setDragImage(img, 0, 0) + if (presto) img.parentNode.removeChild(img) + } +} + +export function onDragOver(cm, e) { + let pos = posFromMouse(cm, e) + if (!pos) return + let frag = document.createDocumentFragment() + drawSelectionCursor(cm, pos, frag) + if (!cm.display.dragCursor) { + cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors") + cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv) + } + removeChildrenAndAdd(cm.display.dragCursor, frag) +} + +export function clearDragCursor(cm) { + if (cm.display.dragCursor) { + cm.display.lineSpace.removeChild(cm.display.dragCursor) + cm.display.dragCursor = null + } +} diff --git a/backend/webif/static/codemirror/src/edit/fromTextArea.js b/backend/webif/static/codemirror/src/edit/fromTextArea.js new file mode 100755 index 000000000..92498c104 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/fromTextArea.js @@ -0,0 +1,61 @@ +import { CodeMirror } from "./CodeMirror.js" +import { activeElt } from "../util/dom.js" +import { off, on } from "../util/event.js" +import { copyObj } from "../util/misc.js" + +export function fromTextArea(textarea, options) { + options = options ? copyObj(options) : {} + options.value = textarea.value + if (!options.tabindex && textarea.tabIndex) + options.tabindex = textarea.tabIndex + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + let hasFocus = activeElt() + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body + } + + function save() {textarea.value = cm.getValue()} + + let realSubmit + if (textarea.form) { + on(textarea.form, "submit", save) + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + let form = textarea.form + realSubmit = form.submit + try { + let wrappedSubmit = form.submit = () => { + save() + form.submit = realSubmit + form.submit() + form.submit = wrappedSubmit + } + } catch(e) {} + } + } + + options.finishInit = cm => { + cm.save = save + cm.getTextArea = () => textarea + cm.toTextArea = () => { + cm.toTextArea = isNaN // Prevent this from being ran twice + save() + textarea.parentNode.removeChild(cm.getWrapperElement()) + textarea.style.display = "" + if (textarea.form) { + off(textarea.form, "submit", save) + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit + } + } + } + + textarea.style.display = "none" + let cm = CodeMirror(node => textarea.parentNode.insertBefore(node, textarea.nextSibling), + options) + return cm +} diff --git a/backend/webif/static/codemirror/src/edit/global_events.js b/backend/webif/static/codemirror/src/edit/global_events.js new file mode 100755 index 000000000..269e870ef --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/global_events.js @@ -0,0 +1,44 @@ +import { onBlur } from "../display/focus.js" +import { on } from "../util/event.js" + +// These must be handled carefully, because naively registering a +// handler for each editor will cause the editors to never be +// garbage collected. + +function forEachCodeMirror(f) { + if (!document.getElementsByClassName) return + let byClass = document.getElementsByClassName("CodeMirror") + for (let i = 0; i < byClass.length; i++) { + let cm = byClass[i].CodeMirror + if (cm) f(cm) + } +} + +let globalsRegistered = false +export function ensureGlobalHandlers() { + if (globalsRegistered) return + registerGlobalHandlers() + globalsRegistered = true +} +function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + let resizeTimer + on(window, "resize", () => { + if (resizeTimer == null) resizeTimer = setTimeout(() => { + resizeTimer = null + forEachCodeMirror(onResize) + }, 100) + }) + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", () => forEachCodeMirror(onBlur)) +} +// Called when the window resizes +function onResize(cm) { + let d = cm.display + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + return + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null + d.scrollbarsClipped = false + cm.setSize() +} diff --git a/backend/webif/static/codemirror/src/edit/key_events.js b/backend/webif/static/codemirror/src/edit/key_events.js new file mode 100755 index 000000000..f0521d070 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/key_events.js @@ -0,0 +1,159 @@ +import { signalLater } from "../util/operation_group.js" +import { restartBlink } from "../display/selection.js" +import { isModifierKey, keyName, lookupKey } from "../input/keymap.js" +import { eventInWidget } from "../measurement/widgets.js" +import { ie, ie_version, mac, presto } from "../util/browser.js" +import { activeElt, addClass, rmClass } from "../util/dom.js" +import { e_preventDefault, off, on, signalDOMEvent } from "../util/event.js" +import { hasCopyEvent } from "../util/feature_detection.js" +import { Delayed, Pass } from "../util/misc.js" + +import { commands } from "./commands.js" + +// Run a handler that was bound to a key. +function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound] + if (!bound) return false + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled() + let prevShift = cm.display.shift, done = false + try { + if (cm.isReadOnly()) cm.state.suppressEdits = true + if (dropShift) cm.display.shift = false + done = bound(cm) != Pass + } finally { + cm.display.shift = prevShift + cm.state.suppressEdits = false + } + return done +} + +function lookupKeyForEditor(cm, name, handle) { + for (let i = 0; i < cm.state.keyMaps.length; i++) { + let result = lookupKey(name, cm.state.keyMaps[i], handle, cm) + if (result) return result + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm) +} + +// Note that, despite the name, this function is also used to check +// for bound mouse clicks. + +let stopSeq = new Delayed + +export function dispatchKey(cm, name, e, handle) { + let seq = cm.state.keySeq + if (seq) { + if (isModifierKey(name)) return "handled" + if (/\'$/.test(name)) + cm.state.keySeq = null + else + stopSeq.set(50, () => { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null + cm.display.input.reset() + } + }) + if (dispatchKeyInner(cm, seq + " " + name, e, handle)) return true + } + return dispatchKeyInner(cm, name, e, handle) +} + +function dispatchKeyInner(cm, name, e, handle) { + let result = lookupKeyForEditor(cm, name, handle) + + if (result == "multi") + cm.state.keySeq = name + if (result == "handled") + signalLater(cm, "keyHandled", cm, name, e) + + if (result == "handled" || result == "multi") { + e_preventDefault(e) + restartBlink(cm) + } + + return !!result +} + +// Handle a key from the keydown event. +function handleKeyBinding(cm, e) { + let name = keyName(e, true) + if (!name) return false + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, b => doHandleBinding(cm, b, true)) + || dispatchKey(cm, name, e, b => { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b) + }) + } else { + return dispatchKey(cm, name, e, b => doHandleBinding(cm, b)) + } +} + +// Handle a key from the keypress event +function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, b => doHandleBinding(cm, b, true)) +} + +let lastStoppedKey = null +export function onKeyDown(e) { + let cm = this + cm.curOp.focus = activeElt() + if (signalDOMEvent(cm, e)) return + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false + let code = e.keyCode + cm.display.shift = code == 16 || e.shiftKey + let handled = handleKeyBinding(cm, e) + if (presto) { + lastStoppedKey = handled ? code : null + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut") + } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + showCrossHair(cm) +} + +function showCrossHair(cm) { + let lineDiv = cm.display.lineDiv + addClass(lineDiv, "CodeMirror-crosshair") + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair") + off(document, "keyup", up) + off(document, "mouseover", up) + } + } + on(document, "keyup", up) + on(document, "mouseover", up) +} + +export function onKeyUp(e) { + if (e.keyCode == 16) this.doc.sel.shift = false + signalDOMEvent(this, e) +} + +export function onKeyPress(e) { + let cm = this + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return + let keyCode = e.keyCode, charCode = e.charCode + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return + let ch = String.fromCharCode(charCode == null ? keyCode : charCode) + // Some browsers fire keypress events for backspace + if (ch == "\x08") return + if (handleCharBinding(cm, e, ch)) return + cm.display.input.onKeyPress(e) +} diff --git a/backend/webif/static/codemirror/src/edit/legacy.js b/backend/webif/static/codemirror/src/edit/legacy.js new file mode 100755 index 000000000..889badbe5 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/legacy.js @@ -0,0 +1,62 @@ +import { scrollbarModel } from "../display/scrollbars.js" +import { wheelEventPixels } from "../display/scroll_events.js" +import { keyMap, keyName, isModifierKey, lookupKey, normalizeKeyMap } from "../input/keymap.js" +import { keyNames } from "../input/keynames.js" +import { Line } from "../line/line_data.js" +import { cmp, Pos } from "../line/pos.js" +import { changeEnd } from "../model/change_measurement.js" +import Doc from "../model/Doc.js" +import { LineWidget } from "../model/line_widget.js" +import { SharedTextMarker, TextMarker } from "../model/mark_text.js" +import { copyState, extendMode, getMode, innerMode, mimeModes, modeExtensions, modes, resolveMode, startState } from "../modes.js" +import { addClass, contains, rmClass } from "../util/dom.js" +import { e_preventDefault, e_stop, e_stopPropagation, off, on, signal } from "../util/event.js" +import { splitLinesAuto } from "../util/feature_detection.js" +import { countColumn, findColumn, isWordCharBasic, Pass } from "../util/misc.js" +import StringStream from "../util/StringStream.js" + +import { commands } from "./commands.js" + +export function addLegacyProps(CodeMirror) { + CodeMirror.off = off + CodeMirror.on = on + CodeMirror.wheelEventPixels = wheelEventPixels + CodeMirror.Doc = Doc + CodeMirror.splitLines = splitLinesAuto + CodeMirror.countColumn = countColumn + CodeMirror.findColumn = findColumn + CodeMirror.isWordChar = isWordCharBasic + CodeMirror.Pass = Pass + CodeMirror.signal = signal + CodeMirror.Line = Line + CodeMirror.changeEnd = changeEnd + CodeMirror.scrollbarModel = scrollbarModel + CodeMirror.Pos = Pos + CodeMirror.cmpPos = cmp + CodeMirror.modes = modes + CodeMirror.mimeModes = mimeModes + CodeMirror.resolveMode = resolveMode + CodeMirror.getMode = getMode + CodeMirror.modeExtensions = modeExtensions + CodeMirror.extendMode = extendMode + CodeMirror.copyState = copyState + CodeMirror.startState = startState + CodeMirror.innerMode = innerMode + CodeMirror.commands = commands + CodeMirror.keyMap = keyMap + CodeMirror.keyName = keyName + CodeMirror.isModifierKey = isModifierKey + CodeMirror.lookupKey = lookupKey + CodeMirror.normalizeKeyMap = normalizeKeyMap + CodeMirror.StringStream = StringStream + CodeMirror.SharedTextMarker = SharedTextMarker + CodeMirror.TextMarker = TextMarker + CodeMirror.LineWidget = LineWidget + CodeMirror.e_preventDefault = e_preventDefault + CodeMirror.e_stopPropagation = e_stopPropagation + CodeMirror.e_stop = e_stop + CodeMirror.addClass = addClass + CodeMirror.contains = contains + CodeMirror.rmClass = rmClass + CodeMirror.keyNames = keyNames +} diff --git a/backend/webif/static/codemirror/src/edit/main.js b/backend/webif/static/codemirror/src/edit/main.js new file mode 100755 index 000000000..c89e5d879 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/main.js @@ -0,0 +1,69 @@ +// EDITOR CONSTRUCTOR + +import { CodeMirror } from "./CodeMirror.js" +export { CodeMirror } from "./CodeMirror.js" + +import { eventMixin } from "../util/event.js" +import { indexOf } from "../util/misc.js" + +import { defineOptions } from "./options.js" + +defineOptions(CodeMirror) + +import addEditorMethods from "./methods.js" + +addEditorMethods(CodeMirror) + +import Doc from "../model/Doc.js" + +// Set up methods on CodeMirror's prototype to redirect to the editor's document. +let dontDelegate = "iter insert remove copy getEditor constructor".split(" ") +for (let prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments)} + })(Doc.prototype[prop]) + +eventMixin(Doc) + +// INPUT HANDLING + +import ContentEditableInput from "../input/ContentEditableInput.js" +import TextareaInput from "../input/TextareaInput.js" +CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput} + +// MODE DEFINITION AND QUERYING + +import { defineMIME, defineMode } from "../modes.js" + +// Extra arguments are stored as the mode's dependencies, which is +// used by (legacy) mechanisms like loadmode.js to automatically +// load a mode. (Preferred mechanism is the require/define calls.) +CodeMirror.defineMode = function(name/*, mode, …*/) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name + defineMode.apply(this, arguments) +} + +CodeMirror.defineMIME = defineMIME + +// Minimal default mode. +CodeMirror.defineMode("null", () => ({token: stream => stream.skipToEnd()})) +CodeMirror.defineMIME("text/plain", "null") + +// EXTENSIONS + +CodeMirror.defineExtension = (name, func) => { + CodeMirror.prototype[name] = func +} +CodeMirror.defineDocExtension = (name, func) => { + Doc.prototype[name] = func +} + +import { fromTextArea } from "./fromTextArea.js" + +CodeMirror.fromTextArea = fromTextArea + +import { addLegacyProps } from "./legacy.js" + +addLegacyProps(CodeMirror) + +CodeMirror.version = "5.32.0" diff --git a/backend/webif/static/codemirror/src/edit/methods.js b/backend/webif/static/codemirror/src/edit/methods.js new file mode 100755 index 000000000..5cefed7c1 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/methods.js @@ -0,0 +1,539 @@ +import { deleteNearSelection } from "./deleteNearSelection.js" +import { commands } from "./commands.js" +import { attachDoc } from "../model/document_data.js" +import { activeElt, addClass, rmClass } from "../util/dom.js" +import { eventMixin, signal } from "../util/event.js" +import { getLineStyles, getContextBefore, takeToken } from "../line/highlight.js" +import { indentLine } from "../input/indent.js" +import { triggerElectric } from "../input/input.js" +import { onKeyDown, onKeyPress, onKeyUp } from "./key_events.js" +import { onMouseDown } from "./mouse_events.js" +import { getKeyMap } from "../input/keymap.js" +import { endOfLine, moveLogically, moveVisually } from "../input/movement.js" +import { endOperation, methodOp, operation, runInOp, startOperation } from "../display/operations.js" +import { clipLine, clipPos, equalCursorPos, Pos } from "../line/pos.js" +import { charCoords, charWidth, clearCaches, clearLineMeasurementCache, coordsChar, cursorCoords, displayHeight, displayWidth, estimateLineHeights, fromCoordSystem, intoCoordSystem, scrollGap, textHeight } from "../measurement/position_measurement.js" +import { Range } from "../model/selection.js" +import { replaceOneSelection, skipAtomic } from "../model/selection_updates.js" +import { addToScrollTop, ensureCursorVisible, scrollIntoView, scrollToCoords, scrollToCoordsRange, scrollToRange } from "../display/scrolling.js" +import { heightAtLine } from "../line/spans.js" +import { updateGutterSpace } from "../display/update_display.js" +import { indexOf, insertSorted, isWordChar, sel_dontScroll, sel_move } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" +import { getLine, isLine, lineAtHeight } from "../line/utils_line.js" +import { regChange, regLineChange } from "../display/view_tracking.js" + +// The publicly visible API. Note that methodOp(f) means +// 'wrap f in an operation, performed on its `this` parameter'. + +// This is not the complete set of editor methods. Most of the +// methods defined on the Doc type are also injected into +// CodeMirror.prototype, for backwards compatibility and +// convenience. + +export default function(CodeMirror) { + let optionHandlers = CodeMirror.optionHandlers + + let helpers = CodeMirror.helpers = {} + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus()}, + + setOption: function(option, value) { + let options = this.options, old = options[option] + if (options[option] == value && option != "mode") return + options[option] = value + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old) + signal(this, "optionChange", this, option) + }, + + getOption: function(option) {return this.options[option]}, + getDoc: function() {return this.doc}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)) + }, + removeKeyMap: function(map) { + let maps = this.state.keyMaps + for (let i = 0; i < maps.length; ++i) + if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1) + return true + } + }, + + addOverlay: methodOp(function(spec, options) { + let mode = spec.token ? spec : CodeMirror.getMode(this.options, spec) + if (mode.startState) throw new Error("Overlays may not be stateful.") + insertSorted(this.state.overlays, + {mode: mode, modeSpec: spec, opaque: options && options.opaque, + priority: (options && options.priority) || 0}, + overlay => overlay.priority) + this.state.modeGen++ + regChange(this) + }), + removeOverlay: methodOp(function(spec) { + let overlays = this.state.overlays + for (let i = 0; i < overlays.length; ++i) { + let cur = overlays[i].modeSpec + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1) + this.state.modeGen++ + regChange(this) + return + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev" + else dir = dir ? "add" : "subtract" + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive) + }), + indentSelection: methodOp(function(how) { + let ranges = this.doc.sel.ranges, end = -1 + for (let i = 0; i < ranges.length; i++) { + let range = ranges[i] + if (!range.empty()) { + let from = range.from(), to = range.to() + let start = Math.max(end, from.line) + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1 + for (let j = start; j < end; ++j) + indentLine(this, j, how) + let newRanges = this.doc.sel.ranges + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll) + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true) + end = range.head.line + if (i == this.doc.sel.primIndex) ensureCursorVisible(this) + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise) + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true) + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos) + let styles = getLineStyles(this, getLine(this.doc, pos.line)) + let before = 0, after = (styles.length - 1) / 2, ch = pos.ch + let type + if (ch == 0) type = styles[2] + else for (;;) { + let mid = (before + after) >> 1 + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid + else if (styles[mid * 2 + 1] < ch) before = mid + 1 + else { type = styles[mid * 2 + 2]; break } + } + let cut = type ? type.indexOf("overlay ") : -1 + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1) + }, + + getModeAt: function(pos) { + let mode = this.doc.mode + if (!mode.innerMode) return mode + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0] + }, + + getHelpers: function(pos, type) { + let found = [] + if (!helpers.hasOwnProperty(type)) return found + let help = helpers[type], mode = this.getModeAt(pos) + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]) + } else if (mode[type]) { + for (let i = 0; i < mode[type].length; i++) { + let val = help[mode[type][i]] + if (val) found.push(val) + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]) + } else if (help[mode.name]) { + found.push(help[mode.name]) + } + for (let i = 0; i < help._global.length; i++) { + let cur = help._global[i] + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val) + } + return found + }, + + getStateAfter: function(line, precise) { + let doc = this.doc + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line) + return getContextBefore(this, line + 1, precise).state + }, + + cursorCoords: function(start, mode) { + let pos, range = this.doc.sel.primary() + if (start == null) pos = range.head + else if (typeof start == "object") pos = clipPos(this.doc, start) + else pos = start ? range.from() : range.to() + return cursorCoords(this, pos, mode || "page") + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page") + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page") + return coordsChar(this, coords.left, coords.top) + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top + return lineAtHeight(this.doc, height + this.display.viewOffset) + }, + heightAtLine: function(line, mode, includeWidgets) { + let end = false, lineObj + if (typeof line == "number") { + let last = this.doc.first + this.doc.size - 1 + if (line < this.doc.first) line = this.doc.first + else if (line > last) { line = last; end = true } + lineObj = getLine(this.doc, line) + } else { + lineObj = line + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top + + (end ? this.doc.height - heightAtLine(lineObj) : 0) + }, + + defaultTextHeight: function() { return textHeight(this.display) }, + defaultCharWidth: function() { return charWidth(this.display) }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}}, + + addWidget: function(pos, node, scroll, vert, horiz) { + let display = this.display + pos = cursorCoords(this, clipPos(this.doc, pos)) + let top = pos.bottom, left = pos.left + node.style.position = "absolute" + node.setAttribute("cm-ignore-events", "true") + this.display.input.setUneditable(node) + display.sizer.appendChild(node) + if (vert == "over") { + top = pos.top + } else if (vert == "above" || vert == "near") { + let vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth) + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth + } + node.style.top = top + "px" + node.style.left = node.style.right = "" + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth + node.style.right = "0px" + } else { + if (horiz == "left") left = 0 + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2 + node.style.left = left + "px" + } + if (scroll) + scrollIntoView(this, {left, top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}) + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + triggerOnMouseDown: methodOp(onMouseDown), + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd].call(null, this) + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text) }), + + findPosH: function(from, amount, unit, visually) { + let dir = 1 + if (amount < 0) { dir = -1; amount = -amount } + let cur = clipPos(this.doc, from) + for (let i = 0; i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually) + if (cur.hitSide) break + } + return cur + }, + + moveH: methodOp(function(dir, unit) { + this.extendSelectionsBy(range => { + if (this.display.shift || this.doc.extend || range.empty()) + return findPosH(this.doc, range.head, dir, unit, this.options.rtlMoveVisually) + else + return dir < 0 ? range.from() : range.to() + }, sel_move) + }), + + deleteH: methodOp(function(dir, unit) { + let sel = this.doc.sel, doc = this.doc + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete") + else + deleteNearSelection(this, range => { + let other = findPosH(doc, range.head, dir, unit, false) + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other} + }) + }), + + findPosV: function(from, amount, unit, goalColumn) { + let dir = 1, x = goalColumn + if (amount < 0) { dir = -1; amount = -amount } + let cur = clipPos(this.doc, from) + for (let i = 0; i < amount; ++i) { + let coords = cursorCoords(this, cur, "div") + if (x == null) x = coords.left + else coords.left = x + cur = findPosV(this, coords, dir, unit) + if (cur.hitSide) break + } + return cur + }, + + moveV: methodOp(function(dir, unit) { + let doc = this.doc, goals = [] + let collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected() + doc.extendSelectionsBy(range => { + if (collapse) + return dir < 0 ? range.from() : range.to() + let headPos = cursorCoords(this, range.head, "div") + if (range.goalColumn != null) headPos.left = range.goalColumn + goals.push(headPos.left) + let pos = findPosV(this, headPos, dir, unit) + if (unit == "page" && range == doc.sel.primary()) + addToScrollTop(this, charCoords(this, pos, "div").top - headPos.top) + return pos + }, sel_move) + if (goals.length) for (let i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i] + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + let doc = this.doc, line = getLine(doc, pos.line).text + let start = pos.ch, end = pos.ch + if (line) { + let helper = this.getHelper(pos, "wordChars") + if ((pos.sticky == "before" || end == line.length) && start) --start; else ++end + let startChar = line.charAt(start) + let check = isWordChar(startChar, helper) + ? ch => isWordChar(ch, helper) + : /\s/.test(startChar) ? ch => /\s/.test(ch) + : ch => (!/\s/.test(ch) && !isWordChar(ch)) + while (start > 0 && check(line.charAt(start - 1))) --start + while (end < line.length && check(line.charAt(end))) ++end + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)) + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return + if (this.state.overwrite = !this.state.overwrite) + addClass(this.display.cursorDiv, "CodeMirror-overwrite") + else + rmClass(this.display.cursorDiv, "CodeMirror-overwrite") + + signal(this, "overwriteToggle", this, this.state.overwrite) + }, + hasFocus: function() { return this.display.input.getField() == activeElt() }, + isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) }, + + scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }), + getScrollInfo: function() { + let scroller = this.display.scroller + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)} + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null} + if (margin == null) margin = this.options.cursorScrollMargin + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null} + } else if (range.from == null) { + range = {from: range, to: null} + } + if (!range.to) range.to = range.from + range.margin = margin || 0 + + if (range.from.line != null) { + scrollToRange(this, range) + } else { + scrollToCoordsRange(this, range.from, range.to, range.margin) + } + }), + + setSize: methodOp(function(width, height) { + let interpret = val => typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val + if (width != null) this.display.wrapper.style.width = interpret(width) + if (height != null) this.display.wrapper.style.height = interpret(height) + if (this.options.lineWrapping) clearLineMeasurementCache(this) + let lineNo = this.display.viewFrom + this.doc.iter(lineNo, this.display.viewTo, line => { + if (line.widgets) for (let i = 0; i < line.widgets.length; i++) + if (line.widgets[i].noHScroll) { regLineChange(this, lineNo, "widget"); break } + ++lineNo + }) + this.curOp.forceUpdate = true + signal(this, "refresh", this) + }), + + operation: function(f){return runInOp(this, f)}, + startOperation: function(){return startOperation(this)}, + endOperation: function(){return endOperation(this)}, + + refresh: methodOp(function() { + let oldHeight = this.display.cachedTextHeight + regChange(this) + this.curOp.forceUpdate = true + clearCaches(this) + scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop) + updateGutterSpace(this) + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this) + signal(this, "refresh", this) + }), + + swapDoc: methodOp(function(doc) { + let old = this.doc + old.cm = null + attachDoc(this, doc) + clearCaches(this) + this.display.input.reset() + scrollToCoords(this, doc.scrollLeft, doc.scrollTop) + this.curOp.forceScroll = true + signalLater(this, "swapDoc", this, old) + return old + }), + + getInputField: function(){return this.display.input.getField()}, + getWrapperElement: function(){return this.display.wrapper}, + getScrollerElement: function(){return this.display.scroller}, + getGutterElement: function(){return this.display.gutters} + } + eventMixin(CodeMirror) + + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []} + helpers[type][name] = value + } + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value) + helpers[type]._global.push({pred: predicate, val: value}) + } +} + +// Used for horizontal relative motion. Dir is -1 or 1 (left or +// right), unit can be "char", "column" (like char, but doesn't +// cross line boundaries), "word" (across next word), or "group" (to +// the start of next group of word or non-word-non-whitespace +// chars). The visually param controls whether, in right-to-left +// text, direction 1 means to move towards the next index in the +// string, or towards the character to the right of the current +// position. The resulting position will have a hitSide=true +// property if it reached the end of the document. +function findPosH(doc, pos, dir, unit, visually) { + let oldPos = pos + let origDir = dir + let lineObj = getLine(doc, pos.line) + function findNextLine() { + let l = pos.line + dir + if (l < doc.first || l >= doc.first + doc.size) return false + pos = new Pos(l, pos.ch, pos.sticky) + return lineObj = getLine(doc, l) + } + function moveOnce(boundToLine) { + let next + if (visually) { + next = moveVisually(doc.cm, lineObj, pos, dir) + } else { + next = moveLogically(lineObj, pos, dir) + } + if (next == null) { + if (!boundToLine && findNextLine()) + pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir) + else + return false + } else { + pos = next + } + return true + } + + if (unit == "char") { + moveOnce() + } else if (unit == "column") { + moveOnce(true) + } else if (unit == "word" || unit == "group") { + let sawType = null, group = unit == "group" + let helper = doc.cm && doc.cm.getHelper(pos, "wordChars") + for (let first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break + let cur = lineObj.text.charAt(pos.ch) || "\n" + let type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p" + if (group && !first && !type) type = "s" + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after"} + break + } + + if (type) sawType = type + if (dir > 0 && !moveOnce(!first)) break + } + } + let result = skipAtomic(doc, pos, oldPos, origDir, true) + if (equalCursorPos(oldPos, result)) result.hitSide = true + return result +} + +// For relative vertical movement. Dir may be -1 or 1. Unit can be +// "page" or "line". The resulting position will have a hitSide=true +// property if it reached the end of the document. +function findPosV(cm, pos, dir, unit) { + let doc = cm.doc, x = pos.left, y + if (unit == "page") { + let pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight) + let moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3) + y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount + + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3 + } + let target + for (;;) { + target = coordsChar(cm, x, y) + if (!target.outside) break + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break } + y += dir * 5 + } + return target +} diff --git a/backend/webif/static/codemirror/src/edit/mouse_events.js b/backend/webif/static/codemirror/src/edit/mouse_events.js new file mode 100755 index 000000000..696a4bbfa --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/mouse_events.js @@ -0,0 +1,407 @@ +import { delayBlurEvent, ensureFocus } from "../display/focus.js" +import { operation } from "../display/operations.js" +import { visibleLines } from "../display/update_lines.js" +import { clipPos, cmp, maxPos, minPos, Pos } from "../line/pos.js" +import { getLine, lineAtHeight } from "../line/utils_line.js" +import { posFromMouse } from "../measurement/position_measurement.js" +import { eventInWidget } from "../measurement/widgets.js" +import { normalizeSelection, Range, Selection } from "../model/selection.js" +import { extendRange, extendSelection, replaceOneSelection, setSelection } from "../model/selection_updates.js" +import { captureRightClick, chromeOS, ie, ie_version, mac, webkit } from "../util/browser.js" +import { getOrder, getBidiPartAt } from "../util/bidi.js" +import { activeElt } from "../util/dom.js" +import { e_button, e_defaultPrevented, e_preventDefault, e_target, hasHandler, off, on, signal, signalDOMEvent } from "../util/event.js" +import { dragAndDrop } from "../util/feature_detection.js" +import { bind, countColumn, findColumn, sel_mouse } from "../util/misc.js" +import { addModifierNames } from "../input/keymap.js" +import { Pass } from "../util/misc.js" + +import { dispatchKey } from "./key_events.js" +import { commands } from "./commands.js" + +const DOUBLECLICK_DELAY = 400 + +class PastClick { + constructor(time, pos, button) { + this.time = time + this.pos = pos + this.button = button + } + + compare(time, pos, button) { + return this.time + DOUBLECLICK_DELAY > time && + cmp(pos, this.pos) == 0 && button == this.button + } +} + +let lastClick, lastDoubleClick +function clickRepeat(pos, button) { + let now = +new Date + if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) { + lastClick = lastDoubleClick = null + return "triple" + } else if (lastClick && lastClick.compare(now, pos, button)) { + lastDoubleClick = new PastClick(now, pos, button) + lastClick = null + return "double" + } else { + lastClick = new PastClick(now, pos, button) + lastDoubleClick = null + return "single" + } +} + +// A mouse down can be a single click, double click, triple click, +// start of selection drag, start of text drag, new cursor +// (ctrl-click), rectangle drag (alt-drag), or xwin +// middle-click-paste. Or it might be a click on something we should +// not interfere with, such as a scrollbar or widget. +export function onMouseDown(e) { + let cm = this, display = cm.display + if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return + display.input.ensurePolled() + display.shift = e.shiftKey + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false + setTimeout(() => display.scroller.draggable = true, 100) + } + return + } + if (clickInGutter(cm, e)) return + let pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single" + window.focus() + + // #3261: make sure, that we're not starting a second selection + if (button == 1 && cm.state.selectingText) + cm.state.selectingText(e) + + if (pos && handleMappedButton(cm, button, pos, repeat, e)) return + + if (button == 1) { + if (pos) leftButtonDown(cm, pos, repeat, e) + else if (e_target(e) == display.scroller) e_preventDefault(e) + } else if (button == 2) { + if (pos) extendSelection(cm.doc, pos) + setTimeout(() => display.input.focus(), 20) + } else if (button == 3) { + if (captureRightClick) onContextMenu(cm, e) + else delayBlurEvent(cm) + } +} + +function handleMappedButton(cm, button, pos, repeat, event) { + let name = "Click" + if (repeat == "double") name = "Double" + name + else if (repeat == "triple") name = "Triple" + name + name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name + + return dispatchKey(cm, addModifierNames(name, event), event, bound => { + if (typeof bound == "string") bound = commands[bound] + if (!bound) return false + let done = false + try { + if (cm.isReadOnly()) cm.state.suppressEdits = true + done = bound(cm, pos) != Pass + } finally { + cm.state.suppressEdits = false + } + return done + }) +} + +function configureMouse(cm, repeat, event) { + let option = cm.getOption("configureMouse") + let value = option ? option(cm, repeat, event) : {} + if (value.unit == null) { + let rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey + value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line" + } + if (value.extend == null || cm.doc.extend) value.extend = cm.doc.extend || event.shiftKey + if (value.addNew == null) value.addNew = mac ? event.metaKey : event.ctrlKey + if (value.moveOnDrag == null) value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey) + return value +} + +function leftButtonDown(cm, pos, repeat, event) { + if (ie) setTimeout(bind(ensureFocus, cm), 0) + else cm.curOp.focus = activeElt() + + let behavior = configureMouse(cm, repeat, event) + + let sel = cm.doc.sel, contained + if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && + repeat == "single" && (contained = sel.contains(pos)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) && + (cmp(contained.to(), pos) > 0 || pos.xRel < 0)) + leftButtonStartDrag(cm, event, pos, behavior) + else + leftButtonSelect(cm, event, pos, behavior) +} + +// Start a text drag. When it ends, see if any dragging actually +// happen, and treat as a click if it didn't. +function leftButtonStartDrag(cm, event, pos, behavior) { + let display = cm.display, moved = false + let dragEnd = operation(cm, e => { + if (webkit) display.scroller.draggable = false + cm.state.draggingText = false + off(document, "mouseup", dragEnd) + off(document, "mousemove", mouseMove) + off(display.scroller, "dragstart", dragStart) + off(display.scroller, "drop", dragEnd) + if (!moved) { + e_preventDefault(e) + if (!behavior.addNew) + extendSelection(cm.doc, pos, null, null, behavior.extend) + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + setTimeout(() => {document.body.focus(); display.input.focus()}, 20) + else + display.input.focus() + } + }) + let mouseMove = function(e2) { + moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10 + } + let dragStart = () => moved = true + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true + cm.state.draggingText = dragEnd + dragEnd.copy = !behavior.moveOnDrag + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop() + on(document, "mouseup", dragEnd) + on(document, "mousemove", mouseMove) + on(display.scroller, "dragstart", dragStart) + on(display.scroller, "drop", dragEnd) + + delayBlurEvent(cm) + setTimeout(() => display.input.focus(), 20) +} + +function rangeForUnit(cm, pos, unit) { + if (unit == "char") return new Range(pos, pos) + if (unit == "word") return cm.findWordAt(pos) + if (unit == "line") return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) + let result = unit(cm, pos) + return new Range(result.from, result.to) +} + +// Normal selection, as opposed to text dragging. +function leftButtonSelect(cm, event, start, behavior) { + let display = cm.display, doc = cm.doc + e_preventDefault(event) + + let ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges + if (behavior.addNew && !behavior.extend) { + ourIndex = doc.sel.contains(start) + if (ourIndex > -1) + ourRange = ranges[ourIndex] + else + ourRange = new Range(start, start) + } else { + ourRange = doc.sel.primary() + ourIndex = doc.sel.primIndex + } + + if (behavior.unit == "rectangle") { + if (!behavior.addNew) ourRange = new Range(start, start) + start = posFromMouse(cm, event, true, true) + ourIndex = -1 + } else { + let range = rangeForUnit(cm, start, behavior.unit) + if (behavior.extend) + ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend) + else + ourRange = range + } + + if (!behavior.addNew) { + ourIndex = 0 + setSelection(doc, new Selection([ourRange], 0), sel_mouse) + startSel = doc.sel + } else if (ourIndex == -1) { + ourIndex = ranges.length + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}) + } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), + {scroll: false, origin: "*mouse"}) + startSel = doc.sel + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse) + } + + let lastPos = start + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return + lastPos = pos + + if (behavior.unit == "rectangle") { + let ranges = [], tabSize = cm.options.tabSize + let startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize) + let posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize) + let left = Math.min(startCol, posCol), right = Math.max(startCol, posCol) + for (let line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + let text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize) + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))) + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))) + } + if (!ranges.length) ranges.push(new Range(start, start)) + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}) + cm.scrollIntoView(pos) + } else { + let oldRange = ourRange + let range = rangeForUnit(cm, pos, behavior.unit) + let anchor = oldRange.anchor, head + if (cmp(range.anchor, anchor) > 0) { + head = range.head + anchor = minPos(oldRange.from(), range.anchor) + } else { + head = range.anchor + anchor = maxPos(oldRange.to(), range.head) + } + let ranges = startSel.ranges.slice(0) + ranges[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)) + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse) + } + } + + let editorSize = display.wrapper.getBoundingClientRect() + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + let counter = 0 + + function extend(e) { + let curCount = ++counter + let cur = posFromMouse(cm, e, true, behavior.unit == "rectangle") + if (!cur) return + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt() + extendTo(cur) + let visible = visibleLines(display, doc) + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, () => {if (counter == curCount) extend(e)}), 150) + } else { + let outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0 + if (outside) setTimeout(operation(cm, () => { + if (counter != curCount) return + display.scroller.scrollTop += outside + extend(e) + }), 50) + } + } + + function done(e) { + cm.state.selectingText = false + counter = Infinity + e_preventDefault(e) + display.input.focus() + off(document, "mousemove", move) + off(document, "mouseup", up) + doc.history.lastSelOrigin = null + } + + let move = operation(cm, e => { + if (!e_button(e)) done(e) + else extend(e) + }) + let up = operation(cm, done) + cm.state.selectingText = up + on(document, "mousemove", move) + on(document, "mouseup", up) +} + +// Used when mouse-selecting to adjust the anchor to the proper side +// of a bidi jump depending on the visual position of the head. +function bidiSimplify(cm, range) { + let {anchor, head} = range, anchorLine = getLine(cm.doc, anchor.line) + if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) return range + let order = getOrder(anchorLine) + if (!order) return range + let index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index] + if (part.from != anchor.ch && part.to != anchor.ch) return range + let boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1) + if (boundary == 0 || boundary == order.length) return range + + // Compute the relative visual position of the head compared to the + // anchor (<0 is to the left, >0 to the right) + let leftSide + if (head.line != anchor.line) { + leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0 + } else { + let headIndex = getBidiPartAt(order, head.ch, head.sticky) + let dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1) + if (headIndex == boundary - 1 || headIndex == boundary) + leftSide = dir < 0 + else + leftSide = dir > 0 + } + + let usePart = order[boundary + (leftSide ? -1 : 0)] + let from = leftSide == (usePart.level == 1) + let ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before" + return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head) +} + + +// Determines whether an event happened in the gutter, and fires the +// handlers for the corresponding event. +function gutterEvent(cm, e, type, prevent) { + let mX, mY + if (e.touches) { + mX = e.touches[0].clientX + mY = e.touches[0].clientY + } else { + try { mX = e.clientX; mY = e.clientY } + catch(e) { return false } + } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false + if (prevent) e_preventDefault(e) + + let display = cm.display + let lineBox = display.lineDiv.getBoundingClientRect() + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e) + mY -= lineBox.top - display.viewOffset + + for (let i = 0; i < cm.options.gutters.length; ++i) { + let g = display.gutters.childNodes[i] + if (g && g.getBoundingClientRect().right >= mX) { + let line = lineAtHeight(cm.doc, mY) + let gutter = cm.options.gutters[i] + signal(cm, type, cm, line, gutter, e) + return e_defaultPrevented(e) + } + } +} + +export function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true) +} + +// CONTEXT MENU HANDLING + +// To make the context menu work, we need to briefly unhide the +// textarea (making it as unobtrusive as possible) to let the +// right-click take effect on it. +export function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return + if (signalDOMEvent(cm, e, "contextmenu")) return + cm.display.input.onContextMenu(e) +} + +function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false + return gutterEvent(cm, e, "gutterContextMenu", false) +} diff --git a/backend/webif/static/codemirror/src/edit/options.js b/backend/webif/static/codemirror/src/edit/options.js new file mode 100755 index 000000000..28f8bb60c --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/options.js @@ -0,0 +1,190 @@ +import { onBlur } from "../display/focus.js" +import { setGuttersForLineNumbers, updateGutters } from "../display/gutters.js" +import { alignHorizontally } from "../display/line_numbers.js" +import { loadMode, resetModeState } from "../display/mode_state.js" +import { initScrollbars, updateScrollbars } from "../display/scrollbars.js" +import { updateSelection } from "../display/selection.js" +import { regChange } from "../display/view_tracking.js" +import { getKeyMap } from "../input/keymap.js" +import { defaultSpecialCharPlaceholder } from "../line/line_data.js" +import { Pos } from "../line/pos.js" +import { findMaxLine } from "../line/spans.js" +import { clearCaches, compensateForHScroll, estimateLineHeights } from "../measurement/position_measurement.js" +import { replaceRange } from "../model/changes.js" +import { mobile, windows } from "../util/browser.js" +import { addClass, rmClass } from "../util/dom.js" +import { off, on } from "../util/event.js" + +import { themeChanged } from "./utils.js" + +export let Init = {toString: function(){return "CodeMirror.Init"}} + +export let defaults = {} +export let optionHandlers = {} + +export function defineOptions(CodeMirror) { + let optionHandlers = CodeMirror.optionHandlers + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt + if (handle) optionHandlers[name] = + notOnInit ? (cm, val, old) => {if (old != Init) handle(cm, val, old)} : handle + } + + CodeMirror.defineOption = option + + // Passed to option handlers when there is no old value. + CodeMirror.Init = Init + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", (cm, val) => cm.setValue(val), true) + option("mode", null, (cm, val) => { + cm.doc.modeOption = val + loadMode(cm) + }, true) + + option("indentUnit", 2, loadMode, true) + option("indentWithTabs", false) + option("smartIndent", true) + option("tabSize", 4, cm => { + resetModeState(cm) + clearCaches(cm) + regChange(cm) + }, true) + option("lineSeparator", null, (cm, val) => { + cm.doc.lineSep = val + if (!val) return + let newBreaks = [], lineNo = cm.doc.first + cm.doc.iter(line => { + for (let pos = 0;;) { + let found = line.text.indexOf(val, pos) + if (found == -1) break + pos = found + val.length + newBreaks.push(Pos(lineNo, found)) + } + lineNo++ + }) + for (let i = newBreaks.length - 1; i >= 0; i--) + replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) + }) + option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, (cm, val, old) => { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g") + if (old != Init) cm.refresh() + }) + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, cm => cm.refresh(), true) + option("electricChars", true) + option("inputStyle", mobile ? "contenteditable" : "textarea", () => { + throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME + }, true) + option("spellcheck", false, (cm, val) => cm.getInputField().spellcheck = val, true) + option("rtlMoveVisually", !windows) + option("wholeLineUpdateBefore", true) + + option("theme", "default", cm => { + themeChanged(cm) + guttersChanged(cm) + }, true) + option("keyMap", "default", (cm, val, old) => { + let next = getKeyMap(val) + let prev = old != Init && getKeyMap(old) + if (prev && prev.detach) prev.detach(cm, next) + if (next.attach) next.attach(cm, prev || null) + }) + option("extraKeys", null) + option("configureMouse", null) + + option("lineWrapping", false, wrappingChanged, true) + option("gutters", [], cm => { + setGuttersForLineNumbers(cm.options) + guttersChanged(cm) + }, true) + option("fixedGutter", true, (cm, val) => { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0" + cm.refresh() + }, true) + option("coverGutterNextToScrollbar", false, cm => updateScrollbars(cm), true) + option("scrollbarStyle", "native", cm => { + initScrollbars(cm) + updateScrollbars(cm) + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop) + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft) + }, true) + option("lineNumbers", false, cm => { + setGuttersForLineNumbers(cm.options) + guttersChanged(cm) + }, true) + option("firstLineNumber", 1, guttersChanged, true) + option("lineNumberFormatter", integer => integer, guttersChanged, true) + option("showCursorWhenSelecting", false, updateSelection, true) + + option("resetSelectionOnContextMenu", true) + option("lineWiseCopyCut", true) + option("pasteLinesPerSelection", true) + + option("readOnly", false, (cm, val) => { + if (val == "nocursor") { + onBlur(cm) + cm.display.input.blur() + } + cm.display.input.readOnlyChanged(val) + }) + option("disableInput", false, (cm, val) => {if (!val) cm.display.input.reset()}, true) + option("dragDrop", true, dragDropChanged) + option("allowDropFileTypes", null) + + option("cursorBlinkRate", 530) + option("cursorScrollMargin", 0) + option("cursorHeight", 1, updateSelection, true) + option("singleCursorHeightPerLine", true, updateSelection, true) + option("workTime", 100) + option("workDelay", 100) + option("flattenSpans", true, resetModeState, true) + option("addModeClass", false, resetModeState, true) + option("pollInterval", 100) + option("undoDepth", 200, (cm, val) => cm.doc.history.undoDepth = val) + option("historyEventDelay", 1250) + option("viewportMargin", 10, cm => cm.refresh(), true) + option("maxHighlightLength", 10000, resetModeState, true) + option("moveInputWithCursor", true, (cm, val) => { + if (!val) cm.display.input.resetPosition() + }) + + option("tabindex", null, (cm, val) => cm.display.input.getField().tabIndex = val || "") + option("autofocus", null) + option("direction", "ltr", (cm, val) => cm.doc.setDirection(val), true) +} + +function guttersChanged(cm) { + updateGutters(cm) + regChange(cm) + alignHorizontally(cm) +} + +function dragDropChanged(cm, value, old) { + let wasOn = old && old != Init + if (!value != !wasOn) { + let funcs = cm.display.dragFunctions + let toggle = value ? on : off + toggle(cm.display.scroller, "dragstart", funcs.start) + toggle(cm.display.scroller, "dragenter", funcs.enter) + toggle(cm.display.scroller, "dragover", funcs.over) + toggle(cm.display.scroller, "dragleave", funcs.leave) + toggle(cm.display.scroller, "drop", funcs.drop) + } +} + +function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap") + cm.display.sizer.style.minWidth = "" + cm.display.sizerWidth = null + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap") + findMaxLine(cm) + } + estimateLineHeights(cm) + regChange(cm) + clearCaches(cm) + setTimeout(() => updateScrollbars(cm), 100) +} diff --git a/backend/webif/static/codemirror/src/edit/utils.js b/backend/webif/static/codemirror/src/edit/utils.js new file mode 100755 index 000000000..fda0be741 --- /dev/null +++ b/backend/webif/static/codemirror/src/edit/utils.js @@ -0,0 +1,7 @@ +import { clearCaches } from "../measurement/position_measurement.js" + +export function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-") + clearCaches(cm) +} diff --git a/backend/webif/static/codemirror/src/input/ContentEditableInput.js b/backend/webif/static/codemirror/src/input/ContentEditableInput.js new file mode 100755 index 000000000..e3af520a0 --- /dev/null +++ b/backend/webif/static/codemirror/src/input/ContentEditableInput.js @@ -0,0 +1,517 @@ +import { operation, runInOp } from "../display/operations.js" +import { prepareSelection } from "../display/selection.js" +import { regChange } from "../display/view_tracking.js" +import { applyTextInput, copyableRanges, disableBrowserMagic, handlePaste, hiddenTextarea, lastCopied, setLastCopied } from "./input.js" +import { cmp, maxPos, minPos, Pos } from "../line/pos.js" +import { getBetween, getLine, lineNo } from "../line/utils_line.js" +import { findViewForLine, findViewIndex, mapFromLineView, nodeAndOffsetInLineMap } from "../measurement/position_measurement.js" +import { replaceRange } from "../model/changes.js" +import { simpleSelection } from "../model/selection.js" +import { setSelection } from "../model/selection_updates.js" +import { getBidiPartAt, getOrder } from "../util/bidi.js" +import { android, chrome, gecko, ie_version } from "../util/browser.js" +import { contains, range, removeChildrenAndAdd, selectInput } from "../util/dom.js" +import { on, signalDOMEvent } from "../util/event.js" +import { Delayed, lst, sel_dontScroll } from "../util/misc.js" + +// CONTENTEDITABLE INPUT STYLE + +export default class ContentEditableInput { + constructor(cm) { + this.cm = cm + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null + this.polling = new Delayed() + this.composing = null + this.gracePeriod = false + this.readDOMTimeout = null + } + + init(display) { + let input = this, cm = input.cm + let div = input.div = display.lineDiv + disableBrowserMagic(div, cm.options.spellcheck) + + on(div, "paste", e => { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return + // IE doesn't fire input events, so we schedule a read for the pasted content in this way + if (ie_version <= 11) setTimeout(operation(cm, () => this.updateFromDOM()), 20) + }) + + on(div, "compositionstart", e => { + this.composing = {data: e.data, done: false} + }) + on(div, "compositionupdate", e => { + if (!this.composing) this.composing = {data: e.data, done: false} + }) + on(div, "compositionend", e => { + if (this.composing) { + if (e.data != this.composing.data) this.readFromDOMSoon() + this.composing.done = true + } + }) + + on(div, "touchstart", () => input.forceCompositionEnd()) + + on(div, "input", () => { + if (!this.composing) this.readFromDOMSoon() + }) + + function onCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}) + if (e.type == "cut") cm.replaceSelection("", null, "cut") + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + let ranges = copyableRanges(cm) + setLastCopied({lineWise: true, text: ranges.text}) + if (e.type == "cut") { + cm.operation(() => { + cm.setSelections(ranges.ranges, 0, sel_dontScroll) + cm.replaceSelection("", null, "cut") + }) + } + } + if (e.clipboardData) { + e.clipboardData.clearData() + let content = lastCopied.text.join("\n") + // iOS exposes the clipboard API, but seems to discard content inserted into it + e.clipboardData.setData("Text", content) + if (e.clipboardData.getData("Text") == content) { + e.preventDefault() + return + } + } + // Old-fashioned briefly-focus-a-textarea hack + let kludge = hiddenTextarea(), te = kludge.firstChild + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild) + te.value = lastCopied.text.join("\n") + let hadFocus = document.activeElement + selectInput(te) + setTimeout(() => { + cm.display.lineSpace.removeChild(kludge) + hadFocus.focus() + if (hadFocus == div) input.showPrimarySelection() + }, 50) + } + on(div, "copy", onCopyCut) + on(div, "cut", onCopyCut) + } + + prepareSelection() { + let result = prepareSelection(this.cm, false) + result.focus = this.cm.state.focused + return result + } + + showSelection(info, takeFocus) { + if (!info || !this.cm.display.view.length) return + if (info.focus || takeFocus) this.showPrimarySelection() + this.showMultipleSelections(info) + } + + showPrimarySelection() { + let sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary() + let from = prim.from(), to = prim.to() + + if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { + sel.removeAllRanges() + return + } + + let curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) + let curFocus = domToPos(cm, sel.focusNode, sel.focusOffset) + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), from) == 0 && + cmp(maxPos(curAnchor, curFocus), to) == 0) + return + + let view = cm.display.view + let start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) || + {node: view[0].measure.map[2], offset: 0} + let end = to.line < cm.display.viewTo && posToDOM(cm, to) + if (!end) { + let measure = view[view.length - 1].measure + let map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]} + } + + if (!start || !end) { + sel.removeAllRanges() + return + } + + let old = sel.rangeCount && sel.getRangeAt(0), rng + try { rng = range(start.node, start.offset, end.offset, end.node) } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + if (!gecko && cm.state.focused) { + sel.collapse(start.node, start.offset) + if (!rng.collapsed) { + sel.removeAllRanges() + sel.addRange(rng) + } + } else { + sel.removeAllRanges() + sel.addRange(rng) + } + if (old && sel.anchorNode == null) sel.addRange(old) + else if (gecko) this.startGracePeriod() + } + this.rememberSelection() + } + + startGracePeriod() { + clearTimeout(this.gracePeriod) + this.gracePeriod = setTimeout(() => { + this.gracePeriod = false + if (this.selectionChanged()) + this.cm.operation(() => this.cm.curOp.selectionChanged = true) + }, 20) + } + + showMultipleSelections(info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors) + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection) + } + + rememberSelection() { + let sel = window.getSelection() + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset + } + + selectionInEditor() { + let sel = window.getSelection() + if (!sel.rangeCount) return false + let node = sel.getRangeAt(0).commonAncestorContainer + return contains(this.div, node) + } + + focus() { + if (this.cm.options.readOnly != "nocursor") { + if (!this.selectionInEditor()) + this.showSelection(this.prepareSelection(), true) + this.div.focus() + } + } + blur() { this.div.blur() } + getField() { return this.div } + + supportsTouch() { return true } + + receivedFocus() { + let input = this + if (this.selectionInEditor()) + this.pollSelection() + else + runInOp(this.cm, () => input.cm.curOp.selectionChanged = true) + + function poll() { + if (input.cm.state.focused) { + input.pollSelection() + input.polling.set(input.cm.options.pollInterval, poll) + } + } + this.polling.set(this.cm.options.pollInterval, poll) + } + + selectionChanged() { + let sel = window.getSelection() + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset + } + + pollSelection() { + if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) return + let sel = window.getSelection(), cm = this.cm + // On Android Chrome (version 56, at least), backspacing into an + // uneditable block element will put the cursor in that element, + // and then, because it's not editable, hide the virtual keyboard. + // Because Android doesn't allow us to actually detect backspace + // presses in a sane way, this code checks for when that happens + // and simulates a backspace press in this case. + if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) { + this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs}) + this.blur() + this.focus() + return + } + if (this.composing) return + this.rememberSelection() + let anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) + let head = domToPos(cm, sel.focusNode, sel.focusOffset) + if (anchor && head) runInOp(cm, () => { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll) + if (anchor.bad || head.bad) cm.curOp.selectionChanged = true + }) + } + + pollContent() { + if (this.readDOMTimeout != null) { + clearTimeout(this.readDOMTimeout) + this.readDOMTimeout = null + } + + let cm = this.cm, display = cm.display, sel = cm.doc.sel.primary() + let from = sel.from(), to = sel.to() + if (from.ch == 0 && from.line > cm.firstLine()) + from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length) + if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine()) + to = Pos(to.line + 1, 0) + if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false + + let fromIndex, fromLine, fromNode + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + fromLine = lineNo(display.view[0].line) + fromNode = display.view[0].node + } else { + fromLine = lineNo(display.view[fromIndex].line) + fromNode = display.view[fromIndex - 1].node.nextSibling + } + let toIndex = findViewIndex(cm, to.line) + let toLine, toNode + if (toIndex == display.view.length - 1) { + toLine = display.viewTo - 1 + toNode = display.lineDiv.lastChild + } else { + toLine = lineNo(display.view[toIndex + 1].line) - 1 + toNode = display.view[toIndex + 1].node.previousSibling + } + + if (!fromNode) return false + let newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)) + let oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)) + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine-- } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++ } + else break + } + + let cutFront = 0, cutEnd = 0 + let newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length) + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + ++cutFront + let newBot = lst(newText), oldBot = lst(oldText) + let maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)) + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + ++cutEnd + // Try to move start of change to start of selection if ambiguous + if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) { + while (cutFront && cutFront > from.ch && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) { + cutFront-- + cutEnd++ + } + } + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "") + newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "") + + let chFrom = Pos(fromLine, cutFront) + let chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0) + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input") + return true + } + } + + ensurePolled() { + this.forceCompositionEnd() + } + reset() { + this.forceCompositionEnd() + } + forceCompositionEnd() { + if (!this.composing) return + clearTimeout(this.readDOMTimeout) + this.composing = null + this.updateFromDOM() + this.div.blur() + this.div.focus() + } + readFromDOMSoon() { + if (this.readDOMTimeout != null) return + this.readDOMTimeout = setTimeout(() => { + this.readDOMTimeout = null + if (this.composing) { + if (this.composing.done) this.composing = null + else return + } + this.updateFromDOM() + }, 80) + } + + updateFromDOM() { + if (this.cm.isReadOnly() || !this.pollContent()) + runInOp(this.cm, () => regChange(this.cm)) + } + + setUneditable(node) { + node.contentEditable = "false" + } + + onKeyPress(e) { + if (e.charCode == 0) return + e.preventDefault() + if (!this.cm.isReadOnly()) + operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) + } + + readOnlyChanged(val) { + this.div.contentEditable = String(val != "nocursor") + } + + onContextMenu() {} + resetPosition() {} +} + +ContentEditableInput.prototype.needsContentAttribute = true + +function posToDOM(cm, pos) { + let view = findViewForLine(cm, pos.line) + if (!view || view.hidden) return null + let line = getLine(cm.doc, pos.line) + let info = mapFromLineView(view, line, pos.line) + + let order = getOrder(line, cm.doc.direction), side = "left" + if (order) { + let partPos = getBidiPartAt(order, pos.ch) + side = partPos % 2 ? "right" : "left" + } + let result = nodeAndOffsetInLineMap(info.map, pos.ch, side) + result.offset = result.collapse == "right" ? result.end : result.start + return result +} + +function isInGutter(node) { + for (let scan = node; scan; scan = scan.parentNode) + if (/CodeMirror-gutter-wrapper/.test(scan.className)) return true + return false +} + +function badPos(pos, bad) { if (bad) pos.bad = true; return pos } + +function domTextBetween(cm, from, to, fromLine, toLine) { + let text = "", closing = false, lineSep = cm.doc.lineSeparator() + function recognizeMarker(id) { return marker => marker.id == id } + function close() { + if (closing) { + text += lineSep + closing = false + } + } + function addText(str) { + if (str) { + close() + text += str + } + } + function walk(node) { + if (node.nodeType == 1) { + let cmText = node.getAttribute("cm-text") + if (cmText != null) { + addText(cmText || node.textContent.replace(/\u200b/g, "")) + return + } + let markerID = node.getAttribute("cm-marker"), range + if (markerID) { + let found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)) + if (found.length && (range = found[0].find(0))) + addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) + return + } + if (node.getAttribute("contenteditable") == "false") return + let isBlock = /^(pre|div|p)$/i.test(node.nodeName) + if (isBlock) close() + for (let i = 0; i < node.childNodes.length; i++) + walk(node.childNodes[i]) + if (isBlock) closing = true + } else if (node.nodeType == 3) { + addText(node.nodeValue) + } + } + for (;;) { + walk(from) + if (from == to) break + from = from.nextSibling + } + return text +} + +function domToPos(cm, node, offset) { + let lineNode + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset] + if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) + node = null; offset = 0 + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) return null + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break + } + } + for (let i = 0; i < cm.display.view.length; i++) { + let lineView = cm.display.view[i] + if (lineView.node == lineNode) + return locateNodeInLineView(lineView, node, offset) + } +} + +function locateNodeInLineView(lineView, node, offset) { + let wrapper = lineView.text.firstChild, bad = false + if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true) + if (node == wrapper) { + bad = true + node = wrapper.childNodes[offset] + offset = 0 + if (!node) { + let line = lineView.rest ? lst(lineView.rest) : lineView.line + return badPos(Pos(lineNo(line), line.text.length), bad) + } + } + + let textNode = node.nodeType == 3 ? node : null, topNode = node + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild + if (offset) offset = textNode.nodeValue.length + } + while (topNode.parentNode != wrapper) topNode = topNode.parentNode + let measure = lineView.measure, maps = measure.maps + + function find(textNode, topNode, offset) { + for (let i = -1; i < (maps ? maps.length : 0); i++) { + let map = i < 0 ? measure.map : maps[i] + for (let j = 0; j < map.length; j += 3) { + let curNode = map[j + 2] + if (curNode == textNode || curNode == topNode) { + let line = lineNo(i < 0 ? lineView.line : lineView.rest[i]) + let ch = map[j] + offset + if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)] + return Pos(line, ch) + } + } + } + } + let found = find(textNode, topNode, offset) + if (found) return badPos(found, bad) + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (let after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0) + if (found) + return badPos(Pos(found.line, found.ch - dist), bad) + else + dist += after.textContent.length + } + for (let before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1) + if (found) + return badPos(Pos(found.line, found.ch + dist), bad) + else + dist += before.textContent.length + } +} diff --git a/backend/webif/static/codemirror/src/input/TextareaInput.js b/backend/webif/static/codemirror/src/input/TextareaInput.js new file mode 100755 index 000000000..c0f04aaaf --- /dev/null +++ b/backend/webif/static/codemirror/src/input/TextareaInput.js @@ -0,0 +1,350 @@ +import { operation, runInOp } from "../display/operations.js" +import { prepareSelection } from "../display/selection.js" +import { applyTextInput, copyableRanges, handlePaste, hiddenTextarea, setLastCopied } from "./input.js" +import { cursorCoords, posFromMouse } from "../measurement/position_measurement.js" +import { eventInWidget } from "../measurement/widgets.js" +import { simpleSelection } from "../model/selection.js" +import { selectAll, setSelection } from "../model/selection_updates.js" +import { captureRightClick, ie, ie_version, ios, mac, mobile, presto, webkit } from "../util/browser.js" +import { activeElt, removeChildrenAndAdd, selectInput } from "../util/dom.js" +import { e_preventDefault, e_stop, off, on, signalDOMEvent } from "../util/event.js" +import { hasSelection } from "../util/feature_detection.js" +import { Delayed, sel_dontScroll } from "../util/misc.js" + +// TEXTAREA INPUT STYLE + +export default class TextareaInput { + constructor(cm) { + this.cm = cm + // See input.poll and input.reset + this.prevInput = "" + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false + // Self-resetting timeout for the poller + this.polling = new Delayed() + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false + this.composing = null + } + + init(display) { + let input = this, cm = this.cm + + // Wraps and hides input textarea + let div = this.wrapper = hiddenTextarea() + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + let te = this.textarea = div.firstChild + display.wrapper.insertBefore(div, display.wrapper.firstChild) + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) te.style.width = "0px" + + on(te, "input", () => { + if (ie && ie_version >= 9 && this.hasSelection) this.hasSelection = null + input.poll() + }) + + on(te, "paste", e => { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return + + cm.state.pasteIncoming = true + input.fastPoll() + }) + + function prepareCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}) + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + let ranges = copyableRanges(cm) + setLastCopied({lineWise: true, text: ranges.text}) + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll) + } else { + input.prevInput = "" + te.value = ranges.text.join("\n") + selectInput(te) + } + } + if (e.type == "cut") cm.state.cutIncoming = true + } + on(te, "cut", prepareCopyCut) + on(te, "copy", prepareCopyCut) + + on(display.scroller, "paste", e => { + if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return + cm.state.pasteIncoming = true + input.focus() + }) + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", e => { + if (!eventInWidget(display, e)) e_preventDefault(e) + }) + + on(te, "compositionstart", () => { + let start = cm.getCursor("from") + if (input.composing) input.composing.range.clear() + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + } + }) + on(te, "compositionend", () => { + if (input.composing) { + input.poll() + input.composing.range.clear() + input.composing = null + } + }) + } + + prepareSelection() { + // Redraw the selection and/or cursor + let cm = this.cm, display = cm.display, doc = cm.doc + let result = prepareSelection(cm) + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + let headPos = cursorCoords(cm, doc.sel.primary().head, "div") + let wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect() + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)) + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)) + } + + return result + } + + showSelection(drawn) { + let cm = this.cm, display = cm.display + removeChildrenAndAdd(display.cursorDiv, drawn.cursors) + removeChildrenAndAdd(display.selectionDiv, drawn.selection) + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px" + this.wrapper.style.left = drawn.teLeft + "px" + } + } + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + reset(typing) { + if (this.contextMenuPending || this.composing) return + let cm = this.cm + if (cm.somethingSelected()) { + this.prevInput = "" + let content = cm.getSelection() + this.textarea.value = content + if (cm.state.focused) selectInput(this.textarea) + if (ie && ie_version >= 9) this.hasSelection = content + } else if (!typing) { + this.prevInput = this.textarea.value = "" + if (ie && ie_version >= 9) this.hasSelection = null + } + } + + getField() { return this.textarea } + + supportsTouch() { return false } + + focus() { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus() } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } + } + + blur() { this.textarea.blur() } + + resetPosition() { + this.wrapper.style.top = this.wrapper.style.left = 0 + } + + receivedFocus() { this.slowPoll() } + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + slowPoll() { + if (this.pollingFast) return + this.polling.set(this.cm.options.pollInterval, () => { + this.poll() + if (this.cm.state.focused) this.slowPoll() + }) + } + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + fastPoll() { + let missed = false, input = this + input.pollingFast = true + function p() { + let changed = input.poll() + if (!changed && !missed) {missed = true; input.polling.set(60, p)} + else {input.pollingFast = false; input.slowPoll()} + } + input.polling.set(20, p) + } + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + poll() { + let cm = this.cm, input = this.textarea, prevInput = this.prevInput + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput && !this.composing) || + cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) + return false + + let text = input.value + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset() + return false + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + let first = text.charCodeAt(0) + if (first == 0x200b && !prevInput) prevInput = "\u200b" + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") } + } + // Find the part of the input that is actually new + let same = 0, l = Math.min(prevInput.length, text.length) + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same + + runInOp(cm, () => { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, this.composing ? "*compose" : null) + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = this.prevInput = "" + else this.prevInput = text + + if (this.composing) { + this.composing.range.clear() + this.composing.range = cm.markText(this.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}) + } + }) + return true + } + + ensurePolled() { + if (this.pollingFast && this.poll()) this.pollingFast = false + } + + onKeyPress() { + if (ie && ie_version >= 9) this.hasSelection = null + this.fastPoll() + } + + onContextMenu(e) { + let input = this, cm = input.cm, display = cm.display, te = input.textarea + let pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop + if (!pos || presto) return // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + let reset = cm.options.resetSelectionOnContextMenu + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll) + + let oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText + input.wrapper.style.cssText = "position: absolute" + let wrapperBox = input.wrapper.getBoundingClientRect() + te.style.cssText = `position: absolute; width: 30px; height: 30px; + top: ${e.clientY - wrapperBox.top - 5}px; left: ${e.clientX - wrapperBox.left - 5}px; + z-index: 1000; background: ${ie ? "rgba(255, 255, 255, .05)" : "transparent"}; + outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);` + let oldScrollY + if (webkit) oldScrollY = window.scrollY // Work around Chrome issue (#2712) + display.input.focus() + if (webkit) window.scrollTo(null, oldScrollY) + display.input.reset() + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) te.value = input.prevInput = " " + input.contextMenuPending = true + display.selForContextMenu = cm.doc.sel + clearTimeout(display.detectingSelectAll) + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + let selected = cm.somethingSelected() + let extval = "\u200b" + (selected ? te.value : "") + te.value = "\u21da" // Used to catch context-menu undo + te.value = extval + input.prevInput = selected ? "" : "\u200b" + te.selectionStart = 1; te.selectionEnd = extval.length + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel + } + } + function rehide() { + input.contextMenuPending = false + input.wrapper.style.cssText = oldWrapperCSS + te.style.cssText = oldCSS + if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos) + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) prepareSelectAllHack() + let i = 0, poll = () => { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") { + operation(cm, selectAll)(cm) + } else if (i++ < 10) { + display.detectingSelectAll = setTimeout(poll, 500) + } else { + display.selForContextMenu = null + display.input.reset() + } + } + display.detectingSelectAll = setTimeout(poll, 200) + } + } + + if (ie && ie_version >= 9) prepareSelectAllHack() + if (captureRightClick) { + e_stop(e) + let mouseup = () => { + off(window, "mouseup", mouseup) + setTimeout(rehide, 20) + } + on(window, "mouseup", mouseup) + } else { + setTimeout(rehide, 50) + } + } + + readOnlyChanged(val) { + if (!val) this.reset() + this.textarea.disabled = val == "nocursor" + } + + setUneditable() {} +} + +TextareaInput.prototype.needsContentAttribute = false diff --git a/backend/webif/static/codemirror/src/input/indent.js b/backend/webif/static/codemirror/src/input/indent.js new file mode 100755 index 000000000..c88772cb6 --- /dev/null +++ b/backend/webif/static/codemirror/src/input/indent.js @@ -0,0 +1,71 @@ +import { getContextBefore } from "../line/highlight.js" +import { Pos } from "../line/pos.js" +import { getLine } from "../line/utils_line.js" +import { replaceRange } from "../model/changes.js" +import { Range } from "../model/selection.js" +import { replaceOneSelection } from "../model/selection_updates.js" +import { countColumn, Pass, spaceStr } from "../util/misc.js" + +// Indent the given line. The how parameter can be "smart", +// "add"/null, "subtract", or "prev". When aggressive is false +// (typically set to true for forced single-line indents), empty +// lines are not indented, and places where the mode returns Pass +// are left alone. +export function indentLine(cm, n, how, aggressive) { + let doc = cm.doc, state + if (how == null) how = "add" + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) how = "prev" + else state = getContextBefore(cm, n).state + } + + let tabSize = cm.options.tabSize + let line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize) + if (line.stateAfter) line.stateAfter = null + let curSpaceString = line.text.match(/^\s*/)[0], indentation + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0 + how = "not" + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text) + if (indentation == Pass || indentation > 150) { + if (!aggressive) return + how = "prev" + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize) + else indentation = 0 + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit + } else if (typeof how == "number") { + indentation = curSpace + how + } + indentation = Math.max(0, indentation) + + let indentString = "", pos = 0 + if (cm.options.indentWithTabs) + for (let i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t"} + if (pos < indentation) indentString += spaceStr(indentation - pos) + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input") + line.stateAfter = null + return true + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (let i = 0; i < doc.sel.ranges.length; i++) { + let range = doc.sel.ranges[i] + if (range.head.line == n && range.head.ch < curSpaceString.length) { + let pos = Pos(n, curSpaceString.length) + replaceOneSelection(doc, i, new Range(pos, pos)) + break + } + } + } +} diff --git a/backend/webif/static/codemirror/src/input/input.js b/backend/webif/static/codemirror/src/input/input.js new file mode 100755 index 000000000..ff86c39d3 --- /dev/null +++ b/backend/webif/static/codemirror/src/input/input.js @@ -0,0 +1,135 @@ +import { runInOp } from "../display/operations.js" +import { ensureCursorVisible } from "../display/scrolling.js" +import { Pos } from "../line/pos.js" +import { getLine } from "../line/utils_line.js" +import { makeChange } from "../model/changes.js" +import { ios, webkit } from "../util/browser.js" +import { elt } from "../util/dom.js" +import { lst, map } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" +import { splitLinesAuto } from "../util/feature_detection.js" + +import { indentLine } from "./indent.js" + +// This will be set to a {lineWise: bool, text: [string]} object, so +// that, when pasting, we know what kind of selections the copied +// text was made out of. +export let lastCopied = null + +export function setLastCopied(newLastCopied) { + lastCopied = newLastCopied +} + +export function applyTextInput(cm, inserted, deleted, sel, origin) { + let doc = cm.doc + cm.display.shift = false + if (!sel) sel = doc.sel + + let paste = cm.state.pasteIncoming || origin == "paste" + let textLines = splitLinesAuto(inserted), multiPaste = null + // When pasing N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.text.join("\n") == inserted) { + if (sel.ranges.length % lastCopied.text.length == 0) { + multiPaste = [] + for (let i = 0; i < lastCopied.text.length; i++) + multiPaste.push(doc.splitLines(lastCopied.text[i])) + } + } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) { + multiPaste = map(textLines, l => [l]) + } + } + + let updateInput + // Normal behavior is to insert the new text into every selection + for (let i = sel.ranges.length - 1; i >= 0; i--) { + let range = sel.ranges[i] + let from = range.from(), to = range.to() + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + from = Pos(from.line, from.ch - deleted) + else if (cm.state.overwrite && !paste) // Handle overwrite + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) + else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted) + from = to = Pos(from.line, 0) + } + updateInput = cm.curOp.updateInput + let changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")} + makeChange(cm.doc, changeEvent) + signalLater(cm, "inputRead", cm, changeEvent) + } + if (inserted && !paste) + triggerElectric(cm, inserted) + + ensureCursorVisible(cm) + cm.curOp.updateInput = updateInput + cm.curOp.typing = true + cm.state.pasteIncoming = cm.state.cutIncoming = false +} + +export function handlePaste(e, cm) { + let pasted = e.clipboardData && e.clipboardData.getData("Text") + if (pasted) { + e.preventDefault() + if (!cm.isReadOnly() && !cm.options.disableInput) + runInOp(cm, () => applyTextInput(cm, pasted, 0, null, "paste")) + return true + } +} + +export function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) return + let sel = cm.doc.sel + + for (let i = sel.ranges.length - 1; i >= 0; i--) { + let range = sel.ranges[i] + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue + let mode = cm.getModeAt(range.head) + let indented = false + if (mode.electricChars) { + for (let j = 0; j < mode.electricChars.length; j++) + if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart") + break + } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + indented = indentLine(cm, range.head.line, "smart") + } + if (indented) signalLater(cm, "electricInput", cm, range.head.line) + } +} + +export function copyableRanges(cm) { + let text = [], ranges = [] + for (let i = 0; i < cm.doc.sel.ranges.length; i++) { + let line = cm.doc.sel.ranges[i].head.line + let lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)} + ranges.push(lineRange) + text.push(cm.getRange(lineRange.anchor, lineRange.head)) + } + return {text: text, ranges: ranges} +} + +export function disableBrowserMagic(field, spellcheck) { + field.setAttribute("autocorrect", "off") + field.setAttribute("autocapitalize", "off") + field.setAttribute("spellcheck", !!spellcheck) +} + +export function hiddenTextarea() { + let te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none") + let div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;") + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) te.style.width = "1000px" + else te.setAttribute("wrap", "off") + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) te.style.border = "1px solid black" + disableBrowserMagic(te) + return div +} diff --git a/backend/webif/static/codemirror/src/input/keymap.js b/backend/webif/static/codemirror/src/input/keymap.js new file mode 100755 index 000000000..1dfcf8aff --- /dev/null +++ b/backend/webif/static/codemirror/src/input/keymap.js @@ -0,0 +1,145 @@ +import { flipCtrlCmd, mac, presto } from "../util/browser.js" +import { map } from "../util/misc.js" + +import { keyNames } from "./keynames.js" + +export let keyMap = {} + +keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" +} +// Note that the save and find-related commands aren't defined by +// default. User code or addons can define them. Unknown commands +// are simply ignored. +keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" +} +// Very basic readline/emacs-style bindings, which are standard on Mac. +keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", + "Ctrl-O": "openLine" +} +keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] +} +keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault + +// KEYMAP DISPATCH + +function normalizeKeyName(name) { + let parts = name.split(/-(?!$)/) + name = parts[parts.length - 1] + let alt, ctrl, shift, cmd + for (let i = 0; i < parts.length - 1; i++) { + let mod = parts[i] + if (/^(cmd|meta|m)$/i.test(mod)) cmd = true + else if (/^a(lt)?$/i.test(mod)) alt = true + else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true + else if (/^s(hift)?$/i.test(mod)) shift = true + else throw new Error("Unrecognized modifier name: " + mod) + } + if (alt) name = "Alt-" + name + if (ctrl) name = "Ctrl-" + name + if (cmd) name = "Cmd-" + name + if (shift) name = "Shift-" + name + return name +} + +// This is a kludge to keep keymaps mostly working as raw objects +// (backwards compatibility) while at the same time support features +// like normalization and multi-stroke key bindings. It compiles a +// new normalized keymap, and then updates the old object to reflect +// this. +export function normalizeKeyMap(keymap) { + let copy = {} + for (let keyname in keymap) if (keymap.hasOwnProperty(keyname)) { + let value = keymap[keyname] + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue + if (value == "...") { delete keymap[keyname]; continue } + + let keys = map(keyname.split(" "), normalizeKeyName) + for (let i = 0; i < keys.length; i++) { + let val, name + if (i == keys.length - 1) { + name = keys.join(" ") + val = value + } else { + name = keys.slice(0, i + 1).join(" ") + val = "..." + } + let prev = copy[name] + if (!prev) copy[name] = val + else if (prev != val) throw new Error("Inconsistent bindings for " + name) + } + delete keymap[keyname] + } + for (let prop in copy) keymap[prop] = copy[prop] + return keymap +} + +export function lookupKey(key, map, handle, context) { + map = getKeyMap(map) + let found = map.call ? map.call(key, context) : map[key] + if (found === false) return "nothing" + if (found === "...") return "multi" + if (found != null && handle(found)) return "handled" + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + return lookupKey(key, map.fallthrough, handle, context) + for (let i = 0; i < map.fallthrough.length; i++) { + let result = lookupKey(key, map.fallthrough[i], handle, context) + if (result) return result + } + } +} + +// Modifier key presses don't count as 'real' key presses for the +// purpose of keymap fallthrough. +export function isModifierKey(value) { + let name = typeof value == "string" ? value : keyNames[value.keyCode] + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod" +} + +export function addModifierNames(name, event, noShift) { + let base = name + if (event.altKey && base != "Alt") name = "Alt-" + name + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name + if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name + return name +} + +// Look up the name of a key as indicated by an event object. +export function keyName(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false + let name = keyNames[event.keyCode] + if (name == null || event.altGraphKey) return false + return addModifierNames(name, event, noShift) +} + +export function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val +} diff --git a/backend/webif/static/codemirror/src/input/keynames.js b/backend/webif/static/codemirror/src/input/keynames.js new file mode 100755 index 000000000..66bc80010 --- /dev/null +++ b/backend/webif/static/codemirror/src/input/keynames.js @@ -0,0 +1,17 @@ +export let keyNames = { + 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" +} + +// Number keys +for (let i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i) +// Alphabetic keys +for (let i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i) +// Function keys +for (let i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i diff --git a/backend/webif/static/codemirror/src/input/movement.js b/backend/webif/static/codemirror/src/input/movement.js new file mode 100755 index 000000000..8d50fd2a0 --- /dev/null +++ b/backend/webif/static/codemirror/src/input/movement.js @@ -0,0 +1,110 @@ +import { Pos } from "../line/pos.js" +import { prepareMeasureForLine, measureCharPrepared, wrappedLineExtentChar } from "../measurement/position_measurement.js" +import { getBidiPartAt, getOrder } from "../util/bidi.js" +import { findFirst, lst, skipExtendingChars } from "../util/misc.js" + +function moveCharLogically(line, ch, dir) { + let target = skipExtendingChars(line.text, ch + dir, dir) + return target < 0 || target > line.text.length ? null : target +} + +export function moveLogically(line, start, dir) { + let ch = moveCharLogically(line, start.ch, dir) + return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") +} + +export function endOfLine(visually, cm, lineObj, lineNo, dir) { + if (visually) { + let order = getOrder(lineObj, cm.doc.direction) + if (order) { + let part = dir < 0 ? lst(order) : order[0] + let moveInStorageOrder = (dir < 0) == (part.level == 1) + let sticky = moveInStorageOrder ? "after" : "before" + let ch + // With a wrapped rtl chunk (possibly spanning multiple bidi parts), + // it could be that the last bidi part is not on the last visual line, + // since visual lines contain content order-consecutive chunks. + // Thus, in rtl, we are looking for the first (content-order) character + // in the rtl chunk that is on the last line (that is, the same line + // as the last (content-order) character). + if (part.level > 0 || cm.doc.direction == "rtl") { + let prep = prepareMeasureForLine(cm, lineObj) + ch = dir < 0 ? lineObj.text.length - 1 : 0 + let targetTop = measureCharPrepared(cm, prep, ch).top + ch = findFirst(ch => measureCharPrepared(cm, prep, ch).top == targetTop, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch) + if (sticky == "before") ch = moveCharLogically(lineObj, ch, 1) + } else ch = dir < 0 ? part.to : part.from + return new Pos(lineNo, ch, sticky) + } + } + return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") +} + +export function moveVisually(cm, line, start, dir) { + let bidi = getOrder(line, cm.doc.direction) + if (!bidi) return moveLogically(line, start, dir) + if (start.ch >= line.text.length) { + start.ch = line.text.length + start.sticky = "before" + } else if (start.ch <= 0) { + start.ch = 0 + start.sticky = "after" + } + let partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos] + if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { + // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, + // nothing interesting happens. + return moveLogically(line, start, dir) + } + + let mv = (pos, dir) => moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir) + let prep + let getWrappedLineExtent = ch => { + if (!cm.options.lineWrapping) return {begin: 0, end: line.text.length} + prep = prep || prepareMeasureForLine(cm, line) + return wrappedLineExtentChar(cm, line, prep, ch) + } + let wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch) + + if (cm.doc.direction == "rtl" || part.level == 1) { + let moveInStorageOrder = (part.level == 1) == (dir < 0) + let ch = mv(start, moveInStorageOrder ? 1 : -1) + if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { + // Case 2: We move within an rtl part or in an rtl editor on the same visual line + let sticky = moveInStorageOrder ? "before" : "after" + return new Pos(start.line, ch, sticky) + } + } + + // Case 3: Could not move within this bidi part in this visual line, so leave + // the current bidi part + + let searchInVisualLine = (partPos, dir, wrappedLineExtent) => { + let getRes = (ch, moveInStorageOrder) => moveInStorageOrder + ? new Pos(start.line, mv(ch, 1), "before") + : new Pos(start.line, ch, "after") + + for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { + let part = bidi[partPos] + let moveInStorageOrder = (dir > 0) == (part.level != 1) + let ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1) + if (part.from <= ch && ch < part.to) return getRes(ch, moveInStorageOrder) + ch = moveInStorageOrder ? part.from : mv(part.to, -1) + if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) return getRes(ch, moveInStorageOrder) + } + } + + // Case 3a: Look for other bidi parts on the same visual line + let res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent) + if (res) return res + + // Case 3b: Look for other bidi parts on the next visual line + let nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1) + if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { + res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)) + if (res) return res + } + + // Case 4: Nowhere to move + return null +} diff --git a/backend/webif/static/codemirror/src/line/highlight.js b/backend/webif/static/codemirror/src/line/highlight.js new file mode 100755 index 000000000..79f088451 --- /dev/null +++ b/backend/webif/static/codemirror/src/line/highlight.js @@ -0,0 +1,284 @@ +import { countColumn } from "../util/misc.js" +import { copyState, innerMode, startState } from "../modes.js" +import StringStream from "../util/StringStream.js" + +import { getLine, lineNo } from "./utils_line.js" +import { clipPos } from "./pos.js" + +class SavedContext { + constructor(state, lookAhead) { + this.state = state + this.lookAhead = lookAhead + } +} + +class Context { + constructor(doc, state, line, lookAhead) { + this.state = state + this.doc = doc + this.line = line + this.maxLookAhead = lookAhead || 0 + this.baseTokens = null + this.baseTokenPos = 1 + } + + lookAhead(n) { + let line = this.doc.getLine(this.line + n) + if (line != null && n > this.maxLookAhead) this.maxLookAhead = n + return line + } + + baseToken(n) { + if (!this.baseTokens) return null + while (this.baseTokens[this.baseTokenPos] <= n) + this.baseTokenPos += 2 + let type = this.baseTokens[this.baseTokenPos + 1] + return {type: type && type.replace(/( |^)overlay .*/, ""), + size: this.baseTokens[this.baseTokenPos] - n} + } + + nextLine() { + this.line++ + if (this.maxLookAhead > 0) this.maxLookAhead-- + } + + static fromSaved(doc, saved, line) { + if (saved instanceof SavedContext) + return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) + else + return new Context(doc, copyState(doc.mode, saved), line) + } + + save(copy) { + let state = copy !== false ? copyState(this.doc.mode, this.state) : this.state + return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state + } +} + + +// Compute a style array (an array starting with a mode generation +// -- for invalidation -- followed by pairs of end positions and +// style strings), which is used to highlight the tokens on the +// line. +export function highlightLine(cm, line, context, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + let st = [cm.state.modeGen], lineClasses = {} + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, context, (end, style) => st.push(end, style), + lineClasses, forceToEnd) + let state = context.state + + // Run overlays, adjust style array. + for (let o = 0; o < cm.state.overlays.length; ++o) { + context.baseTokens = st + let overlay = cm.state.overlays[o], i = 1, at = 0 + context.state = true + runMode(cm, line.text, overlay.mode, context, (end, style) => { + let start = i + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + let i_end = st[i] + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end) + i += 2 + at = Math.min(end, i_end) + } + if (!style) return + if (overlay.opaque) { + st.splice(start, i - start, end, "overlay " + style) + i = start + 2 + } else { + for (; start < i; start += 2) { + let cur = st[start+1] + st[start+1] = (cur ? cur + " " : "") + "overlay " + style + } + } + }, lineClasses) + context.state = state + context.baseTokens = null + context.baseTokenPos = 1 + } + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} +} + +export function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + let context = getContextBefore(cm, lineNo(line)) + let resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state) + let result = highlightLine(cm, line, context) + if (resetState) context.state = resetState + line.stateAfter = context.save(!resetState) + line.styles = result.styles + if (result.classes) line.styleClasses = result.classes + else if (line.styleClasses) line.styleClasses = null + if (updateFrontier === cm.doc.highlightFrontier) + cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) + } + return line.styles +} + +export function getContextBefore(cm, n, precise) { + let doc = cm.doc, display = cm.display + if (!doc.mode.startState) return new Context(doc, true, n) + let start = findStartLine(cm, n, precise) + let saved = start > doc.first && getLine(doc, start - 1).stateAfter + let context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start) + + doc.iter(start, n, line => { + processLine(cm, line.text, context) + let pos = context.line + line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null + context.nextLine() + }) + if (precise) doc.modeFrontier = context.line + return context +} + +// Lightweight form of highlight -- proceed over this line and +// update state, but don't save a style array. Used for lines that +// aren't currently visible. +export function processLine(cm, text, context, startAt) { + let mode = cm.doc.mode + let stream = new StringStream(text, cm.options.tabSize, context) + stream.start = stream.pos = startAt || 0 + if (text == "") callBlankLine(mode, context.state) + while (!stream.eol()) { + readToken(mode, stream, context.state) + stream.start = stream.pos + } +} + +function callBlankLine(mode, state) { + if (mode.blankLine) return mode.blankLine(state) + if (!mode.innerMode) return + let inner = innerMode(mode, state) + if (inner.mode.blankLine) return inner.mode.blankLine(inner.state) +} + +export function readToken(mode, stream, state, inner) { + for (let i = 0; i < 10; i++) { + if (inner) inner[0] = innerMode(mode, state).mode + let style = mode.token(stream, state) + if (stream.pos > stream.start) return style + } + throw new Error("Mode " + mode.name + " failed to advance stream.") +} + +class Token { + constructor(stream, type, state) { + this.start = stream.start; this.end = stream.pos + this.string = stream.current() + this.type = type || null + this.state = state + } +} + +// Utility for getTokenAt and getLineTokens +export function takeToken(cm, pos, precise, asArray) { + let doc = cm.doc, mode = doc.mode, style + pos = clipPos(doc, pos) + let line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise) + let stream = new StringStream(line.text, cm.options.tabSize, context), tokens + if (asArray) tokens = [] + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos + style = readToken(mode, stream, context.state) + if (asArray) tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) + } + return asArray ? tokens : new Token(stream, style, context.state) +} + +function extractLineClasses(type, output) { + if (type) for (;;) { + let lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/) + if (!lineClass) break + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length) + let prop = lineClass[1] ? "bgClass" : "textClass" + if (output[prop] == null) + output[prop] = lineClass[2] + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + output[prop] += " " + lineClass[2] + } + return type +} + +// Run the given mode's parser over a line, calling f for each token. +function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { + let flattenSpans = mode.flattenSpans + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans + let curStart = 0, curStyle = null + let stream = new StringStream(text, cm.options.tabSize, context), style + let inner = cm.options.addModeClass && [null] + if (text == "") extractLineClasses(callBlankLine(mode, context.state), lineClasses) + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false + if (forceToEnd) processLine(cm, text, context, stream.pos) + stream.pos = text.length + style = null + } else { + style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses) + } + if (inner) { + let mName = inner[0].name + if (mName) style = "m-" + (style ? mName + " " + style : mName) + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 5000) + f(curStart, curStyle) + } + curStyle = style + } + stream.start = stream.pos + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 + // characters, and returns inaccurate measurements in nodes + // starting around 5000 chars. + let pos = Math.min(stream.pos, curStart + 5000) + f(pos, curStyle) + curStart = pos + } +} + +// Finds the line to start with when starting a parse. Tries to +// find a line with a stateAfter, so that it can start with a +// valid state. If that fails, it returns the line with the +// smallest indentation, which tends to need the least context to +// parse correctly. +function findStartLine(cm, n, precise) { + let minindent, minline, doc = cm.doc + let lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100) + for (let search = n; search > lim; --search) { + if (search <= doc.first) return doc.first + let line = getLine(doc, search - 1), after = line.stateAfter + if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) + return search + let indented = countColumn(line.text, null, cm.options.tabSize) + if (minline == null || minindent > indented) { + minline = search - 1 + minindent = indented + } + } + return minline +} + +export function retreatFrontier(doc, n) { + doc.modeFrontier = Math.min(doc.modeFrontier, n) + if (doc.highlightFrontier < n - 10) return + let start = doc.first + for (let line = n - 1; line > start; line--) { + let saved = getLine(doc, line).stateAfter + // change is on 3 + // state on line 1 looked ahead 2 -- so saw 3 + // test 1 + 2 < 3 should cover this + if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { + start = line + 1 + break + } + } + doc.highlightFrontier = Math.min(doc.highlightFrontier, start) +} diff --git a/backend/webif/static/codemirror/src/line/line_data.js b/backend/webif/static/codemirror/src/line/line_data.js new file mode 100755 index 000000000..74acdaffc --- /dev/null +++ b/backend/webif/static/codemirror/src/line/line_data.js @@ -0,0 +1,337 @@ +import { getOrder } from "../util/bidi.js" +import { ie, ie_version, webkit } from "../util/browser.js" +import { elt, eltP, joinClasses } from "../util/dom.js" +import { eventMixin, signal } from "../util/event.js" +import { hasBadBidiRects, zeroWidthElement } from "../util/feature_detection.js" +import { lst, spaceStr } from "../util/misc.js" + +import { getLineStyles } from "./highlight.js" +import { attachMarkedSpans, compareCollapsedMarkers, detachMarkedSpans, lineIsHidden, visualLineContinued } from "./spans.js" +import { getLine, lineNo, updateLineHeight } from "./utils_line.js" + +// LINE DATA STRUCTURE + +// Line objects. These hold state related to a line, including +// highlighting info (the styles array). +export class Line { + constructor(text, markedSpans, estimateHeight) { + this.text = text + attachMarkedSpans(this, markedSpans) + this.height = estimateHeight ? estimateHeight(this) : 1 + } + + lineNo() { return lineNo(this) } +} +eventMixin(Line) + +// Change the content (text, markers) of a line. Automatically +// invalidates cached information and tries to re-estimate the +// line's height. +export function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text + if (line.stateAfter) line.stateAfter = null + if (line.styles) line.styles = null + if (line.order != null) line.order = null + detachMarkedSpans(line) + attachMarkedSpans(line, markedSpans) + let estHeight = estimateHeight ? estimateHeight(line) : 1 + if (estHeight != line.height) updateLineHeight(line, estHeight) +} + +// Detach a line from the document tree and its markers. +export function cleanUpLine(line) { + line.parent = null + detachMarkedSpans(line) +} + +// Convert a style as returned by a mode (either null, or a string +// containing one or more styles) to a CSS style. This is cached, +// and also looks for line-wide styles. +let styleToClassCache = {}, styleToClassCacheWithMode = {} +function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) return null + let cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")) +} + +// Render the DOM representation of the text of a line. Also builds +// up a 'line map', which points at the DOM nodes that represent +// specific stretches of text, and is used by the measuring code. +// The returned object contains the DOM node, this map, and +// information about line-wide styles that were set by the mode. +export function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + let content = eltP("span", null, null, webkit ? "padding-right: .1px" : null) + let builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + trailingSpace: false, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")} + lineView.measure = {} + + // Iterate over the logical lines that make up this visual line. + for (let i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + let line = i ? lineView.rest[i - 1] : lineView.line, order + builder.pos = 0 + builder.addToken = buildToken + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) + builder.addToken = buildTokenBadBidi(builder.addToken, order) + builder.map = [] + let allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line) + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)) + if (line.styleClasses) { + if (line.styleClasses.bgClass) + builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "") + if (line.styleClasses.textClass) + builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "") + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map + lineView.measure.cache = {} + } else { + ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) + ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}) + } + } + + // See issue #2901 + if (webkit) { + let last = builder.content.lastChild + if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) + builder.content.className = "cm-tab-wrap-hack" + } + + signal(cm, "renderLine", cm, lineView.line, builder.pre) + if (builder.pre.className) + builder.textClass = joinClasses(builder.pre.className, builder.textClass || "") + + return builder +} + +export function defaultSpecialCharPlaceholder(ch) { + let token = elt("span", "\u2022", "cm-invalidchar") + token.title = "\\u" + ch.charCodeAt(0).toString(16) + token.setAttribute("aria-label", token.title) + return token +} + +// Build up the DOM representation for a single token, and add it to +// the line map. Takes care to render special characters separately. +function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) return + let displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text + let special = builder.cm.state.specialChars, mustWrap = false + let content + if (!special.test(text)) { + builder.col += text.length + content = document.createTextNode(displayText) + builder.map.push(builder.pos, builder.pos + text.length, content) + if (ie && ie_version < 9) mustWrap = true + builder.pos += text.length + } else { + content = document.createDocumentFragment() + let pos = 0 + while (true) { + special.lastIndex = pos + let m = special.exec(text) + let skipped = m ? m.index - pos : text.length - pos + if (skipped) { + let txt = document.createTextNode(displayText.slice(pos, pos + skipped)) + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])) + else content.appendChild(txt) + builder.map.push(builder.pos, builder.pos + skipped, txt) + builder.col += skipped + builder.pos += skipped + } + if (!m) break + pos += skipped + 1 + let txt + if (m[0] == "\t") { + let tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize + txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")) + txt.setAttribute("role", "presentation") + txt.setAttribute("cm-text", "\t") + builder.col += tabWidth + } else if (m[0] == "\r" || m[0] == "\n") { + txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")) + txt.setAttribute("cm-text", m[0]) + builder.col += 1 + } else { + txt = builder.cm.options.specialCharPlaceholder(m[0]) + txt.setAttribute("cm-text", m[0]) + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])) + else content.appendChild(txt) + builder.col += 1 + } + builder.map.push(builder.pos, builder.pos + 1, txt) + builder.pos++ + } + } + builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 + if (style || startStyle || endStyle || mustWrap || css) { + let fullStyle = style || "" + if (startStyle) fullStyle += startStyle + if (endStyle) fullStyle += endStyle + let token = elt("span", [content], fullStyle, css) + if (title) token.title = title + return builder.content.appendChild(token) + } + builder.content.appendChild(content) +} + +function splitSpaces(text, trailingBefore) { + if (text.length > 1 && !/ /.test(text)) return text + let spaceBefore = trailingBefore, result = "" + for (let i = 0; i < text.length; i++) { + let ch = text.charAt(i) + if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) + ch = "\u00a0" + result += ch + spaceBefore = ch == " " + } + return result +} + +// Work around nonsense dimensions being reported for stretches of +// right-to-left text. +function buildTokenBadBidi(inner, order) { + return (builder, text, style, startStyle, endStyle, title, css) => { + style = style ? style + " cm-force-border" : "cm-force-border" + let start = builder.pos, end = start + text.length + for (;;) { + // Find the part that overlaps with the start of this text + let part + for (let i = 0; i < order.length; i++) { + part = order[i] + if (part.to > start && part.from <= start) break + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css) + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css) + startStyle = null + text = text.slice(part.to - start) + start = part.to + } + } +} + +function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + let widget = !ignoreWidget && marker.widgetNode + if (widget) builder.map.push(builder.pos, builder.pos + size, widget) + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + widget = builder.content.appendChild(document.createElement("span")) + widget.setAttribute("cm-marker", marker.id) + } + if (widget) { + builder.cm.display.input.setUneditable(widget) + builder.content.appendChild(widget) + } + builder.pos += size + builder.trailingSpace = false +} + +// Outputs a number of spans to make up a line, taking highlighting +// and marked text into account. +function insertLineContent(line, builder, styles) { + let spans = line.markedSpans, allText = line.text, at = 0 + if (!spans) { + for (let i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)) + return + } + + let len = allText.length, pos = 0, i = 1, text = "", style, css + let nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = "" + collapsed = null; nextChange = Infinity + let foundBookmarks = [], endStyles + for (let j = 0; j < spans.length; ++j) { + let sp = spans[j], m = sp.marker + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m) + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to + spanEndStyle = "" + } + if (m.className) spanStyle += " " + m.className + if (m.css) css = (css ? css + ";" : "") + m.css + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle + if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to) + if (m.title && !title) title = m.title + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from + } + } + if (endStyles) for (let j = 0; j < endStyles.length; j += 2) + if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j] + + if (!collapsed || collapsed.from == pos) for (let j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]) + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null) + if (collapsed.to == null) return + if (collapsed.to == pos) collapsed = false + } + } + if (pos >= len) break + + let upto = Math.min(len, nextChange) + while (true) { + if (text) { + let end = pos + text.length + if (!collapsed) { + let tokenText = end > upto ? text.slice(0, upto - pos) : text + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css) + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break} + pos = end + spanStartStyle = "" + } + text = allText.slice(at, at = styles[i++]) + style = interpretTokenStyle(styles[i++], builder.cm.options) + } + } +} + + +// These objects are used to represent the visible (currently drawn) +// part of the document. A LineView may correspond to multiple +// logical lines, if those are connected by collapsed ranges. +export function LineView(doc, line, lineN) { + // The starting line + this.line = line + // Continuing lines, if any + this.rest = visualLineContinued(line) + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1 + this.node = this.text = null + this.hidden = lineIsHidden(doc, line) +} + +// Create a range of LineView objects for the given lines. +export function buildViewArray(cm, from, to) { + let array = [], nextPos + for (let pos = from; pos < to; pos = nextPos) { + let view = new LineView(cm.doc, getLine(cm.doc, pos), pos) + nextPos = pos + view.size + array.push(view) + } + return array +} diff --git a/backend/webif/static/codemirror/src/line/pos.js b/backend/webif/static/codemirror/src/line/pos.js new file mode 100755 index 000000000..2a498f8f3 --- /dev/null +++ b/backend/webif/static/codemirror/src/line/pos.js @@ -0,0 +1,40 @@ +import { getLine } from "./utils_line.js" + +// A Pos instance represents a position within the text. +export function Pos(line, ch, sticky = null) { + if (!(this instanceof Pos)) return new Pos(line, ch, sticky) + this.line = line + this.ch = ch + this.sticky = sticky +} + +// Compare two positions, return 0 if they are the same, a negative +// number when a is less, and a positive number otherwise. +export function cmp(a, b) { return a.line - b.line || a.ch - b.ch } + +export function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 } + +export function copyPos(x) {return Pos(x.line, x.ch)} +export function maxPos(a, b) { return cmp(a, b) < 0 ? b : a } +export function minPos(a, b) { return cmp(a, b) < 0 ? a : b } + +// Most of the external API clips given positions to make sure they +// actually exist within the document. +export function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))} +export function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0) + let last = doc.first + doc.size - 1 + if (pos.line > last) return Pos(last, getLine(doc, last).text.length) + return clipToLen(pos, getLine(doc, pos.line).text.length) +} +function clipToLen(pos, linelen) { + let ch = pos.ch + if (ch == null || ch > linelen) return Pos(pos.line, linelen) + else if (ch < 0) return Pos(pos.line, 0) + else return pos +} +export function clipPosArray(doc, array) { + let out = [] + for (let i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]) + return out +} diff --git a/backend/webif/static/codemirror/src/line/saw_special_spans.js b/backend/webif/static/codemirror/src/line/saw_special_spans.js new file mode 100755 index 000000000..d315e7ba9 --- /dev/null +++ b/backend/webif/static/codemirror/src/line/saw_special_spans.js @@ -0,0 +1,10 @@ +// Optimize some code when these features are not used. +export let sawReadOnlySpans = false, sawCollapsedSpans = false + +export function seeReadOnlySpans() { + sawReadOnlySpans = true +} + +export function seeCollapsedSpans() { + sawCollapsedSpans = true +} diff --git a/backend/webif/static/codemirror/src/line/spans.js b/backend/webif/static/codemirror/src/line/spans.js new file mode 100755 index 000000000..f7e5f4b6e --- /dev/null +++ b/backend/webif/static/codemirror/src/line/spans.js @@ -0,0 +1,372 @@ +import { indexOf, lst } from "../util/misc.js" + +import { cmp } from "./pos.js" +import { sawCollapsedSpans } from "./saw_special_spans.js" +import { getLine, isLine, lineNo } from "./utils_line.js" + +// TEXTMARKER SPANS + +export function MarkedSpan(marker, from, to) { + this.marker = marker + this.from = from; this.to = to +} + +// Search an array of spans for a span matching the given marker. +export function getMarkedSpanFor(spans, marker) { + if (spans) for (let i = 0; i < spans.length; ++i) { + let span = spans[i] + if (span.marker == marker) return span + } +} +// Remove a span from an array, returning undefined if no spans are +// left (we don't store arrays for lines without spans). +export function removeMarkedSpan(spans, span) { + let r + for (let i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]) + return r +} +// Add a span to a line. +export function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span] + span.marker.attachLine(line) +} + +// Used for the algorithm that adjusts markers for a change in the +// document. These functions cut an array of spans at a given +// character position, returning an array of remaining chunks (or +// undefined if nothing remains). +function markedSpansBefore(old, startCh, isInsert) { + let nw + if (old) for (let i = 0; i < old.length; ++i) { + let span = old[i], marker = span.marker + let startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh) + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + let endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)) + } + } + return nw +} +function markedSpansAfter(old, endCh, isInsert) { + let nw + if (old) for (let i = 0; i < old.length; ++i) { + let span = old[i], marker = span.marker + let endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh) + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + let startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)) + } + } + return nw +} + +// Given a change object, compute the new set of marker spans that +// cover the line in which the change took place. Removes spans +// entirely within the change, reconnects spans belonging to the +// same marker that appear on both sides of the change, and cuts off +// spans partially within the change. Returns an array of span +// arrays with one element for each line in (after) the change. +export function stretchSpansOverChange(doc, change) { + if (change.full) return null + let oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans + let oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans + if (!oldFirst && !oldLast) return null + + let startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0 + // Get the spans that 'stick out' on both sides + let first = markedSpansBefore(oldFirst, startCh, isInsert) + let last = markedSpansAfter(oldLast, endCh, isInsert) + + // Next, merge those two ends + let sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0) + if (first) { + // Fix up .to properties of first + for (let i = 0; i < first.length; ++i) { + let span = first[i] + if (span.to == null) { + let found = getMarkedSpanFor(last, span.marker) + if (!found) span.to = startCh + else if (sameLine) span.to = found.to == null ? null : found.to + offset + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (let i = 0; i < last.length; ++i) { + let span = last[i] + if (span.to != null) span.to += offset + if (span.from == null) { + let found = getMarkedSpanFor(first, span.marker) + if (!found) { + span.from = offset + if (sameLine) (first || (first = [])).push(span) + } + } else { + span.from += offset + if (sameLine) (first || (first = [])).push(span) + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first) + if (last && last != first) last = clearEmptySpans(last) + + let newMarkers = [first] + if (!sameLine) { + // Fill gap with whole-line-spans + let gap = change.text.length - 2, gapMarkers + if (gap > 0 && first) + for (let i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)) + for (let i = 0; i < gap; ++i) + newMarkers.push(gapMarkers) + newMarkers.push(last) + } + return newMarkers +} + +// Remove spans that are empty and don't have a clearWhenEmpty +// option of false. +function clearEmptySpans(spans) { + for (let i = 0; i < spans.length; ++i) { + let span = spans[i] + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1) + } + if (!spans.length) return null + return spans +} + +// Used to 'clip' out readOnly ranges when making a change. +export function removeReadOnlyRanges(doc, from, to) { + let markers = null + doc.iter(from.line, to.line + 1, line => { + if (line.markedSpans) for (let i = 0; i < line.markedSpans.length; ++i) { + let mark = line.markedSpans[i].marker + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark) + } + }) + if (!markers) return null + let parts = [{from: from, to: to}] + for (let i = 0; i < markers.length; ++i) { + let mk = markers[i], m = mk.find(0) + for (let j = 0; j < parts.length; ++j) { + let p = parts[j] + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue + let newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to) + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({from: p.from, to: m.from}) + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({from: m.to, to: p.to}) + parts.splice.apply(parts, newParts) + j += newParts.length - 3 + } + } + return parts +} + +// Connect or disconnect spans from a line. +export function detachMarkedSpans(line) { + let spans = line.markedSpans + if (!spans) return + for (let i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line) + line.markedSpans = null +} +export function attachMarkedSpans(line, spans) { + if (!spans) return + for (let i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line) + line.markedSpans = spans +} + +// Helpers used when computing which overlapping collapsed span +// counts as the larger one. +function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 } +function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 } + +// Returns a number indicating which of two overlapping collapsed +// spans is larger (and thus includes the other). Falls back to +// comparing ids when the spans cover exactly the same range. +export function compareCollapsedMarkers(a, b) { + let lenDiff = a.lines.length - b.lines.length + if (lenDiff != 0) return lenDiff + let aPos = a.find(), bPos = b.find() + let fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b) + if (fromCmp) return -fromCmp + let toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b) + if (toCmp) return toCmp + return b.id - a.id +} + +// Find out whether a line ends or starts in a collapsed span. If +// so, return the marker for that span. +function collapsedSpanAtSide(line, start) { + let sps = sawCollapsedSpans && line.markedSpans, found + if (sps) for (let sp, i = 0; i < sps.length; ++i) { + sp = sps[i] + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker + } + return found +} +export function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } +export function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } + +// Test whether there exists a collapsed span that partially +// overlaps (covers the start or end, but not both) of a new span. +// Such overlap is not allowed. +export function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + let line = getLine(doc, lineNo) + let sps = sawCollapsedSpans && line.markedSpans + if (sps) for (let i = 0; i < sps.length; ++i) { + let sp = sps[i] + if (!sp.marker.collapsed) continue + let found = sp.marker.find(0) + let fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker) + let toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker) + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue + if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || + fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) + return true + } +} + +// A visual line is a line as drawn on the screen. Folding, for +// example, can cause multiple logical lines to appear on the same +// visual line. This finds the start of the visual line that the +// given line is part of (usually that is the line itself). +export function visualLine(line) { + let merged + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line + return line +} + +export function visualLineEnd(line) { + let merged + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line + return line +} + +// Returns an array of logical lines that continue the visual line +// started by the argument, or undefined if there are no such lines. +export function visualLineContinued(line) { + let merged, lines + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line + ;(lines || (lines = [])).push(line) + } + return lines +} + +// Get the line number of the start of the visual line that the +// given line number is part of. +export function visualLineNo(doc, lineN) { + let line = getLine(doc, lineN), vis = visualLine(line) + if (line == vis) return lineN + return lineNo(vis) +} + +// Get the line number of the start of the next visual line after +// the given line. +export function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN + let line = getLine(doc, lineN), merged + if (!lineIsHidden(doc, line)) return lineN + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line + return lineNo(line) + 1 +} + +// Compute whether a line is hidden. Lines count as hidden when they +// are part of a visual line that starts with another line, or when +// they are entirely covered by collapsed, non-widget span. +export function lineIsHidden(doc, line) { + let sps = sawCollapsedSpans && line.markedSpans + if (sps) for (let sp, i = 0; i < sps.length; ++i) { + sp = sps[i] + if (!sp.marker.collapsed) continue + if (sp.from == null) return true + if (sp.marker.widgetNode) continue + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true + } +} +function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + let end = span.marker.find(1, true) + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true + for (let sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i] + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true + } +} + +// Find the height above the given line. +export function heightAtLine(lineObj) { + lineObj = visualLine(lineObj) + + let h = 0, chunk = lineObj.parent + for (let i = 0; i < chunk.lines.length; ++i) { + let line = chunk.lines[i] + if (line == lineObj) break + else h += line.height + } + for (let p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (let i = 0; i < p.children.length; ++i) { + let cur = p.children[i] + if (cur == chunk) break + else h += cur.height + } + } + return h +} + +// Compute the character length of a line, taking into account +// collapsed ranges (see markText) that might hide parts, and join +// other lines onto it. +export function lineLength(line) { + if (line.height == 0) return 0 + let len = line.text.length, merged, cur = line + while (merged = collapsedSpanAtStart(cur)) { + let found = merged.find(0, true) + cur = found.from.line + len += found.from.ch - found.to.ch + } + cur = line + while (merged = collapsedSpanAtEnd(cur)) { + let found = merged.find(0, true) + len -= cur.text.length - found.from.ch + cur = found.to.line + len += cur.text.length - found.to.ch + } + return len +} + +// Find the longest line in the document. +export function findMaxLine(cm) { + let d = cm.display, doc = cm.doc + d.maxLine = getLine(doc, doc.first) + d.maxLineLength = lineLength(d.maxLine) + d.maxLineChanged = true + doc.iter(line => { + let len = lineLength(line) + if (len > d.maxLineLength) { + d.maxLineLength = len + d.maxLine = line + } + }) +} diff --git a/backend/webif/static/codemirror/src/line/utils_line.js b/backend/webif/static/codemirror/src/line/utils_line.js new file mode 100755 index 000000000..c88629435 --- /dev/null +++ b/backend/webif/static/codemirror/src/line/utils_line.js @@ -0,0 +1,85 @@ +import { indexOf } from "../util/misc.js" + +// Find the line object corresponding to the given line number. +export function getLine(doc, n) { + n -= doc.first + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.") + let chunk = doc + while (!chunk.lines) { + for (let i = 0;; ++i) { + let child = chunk.children[i], sz = child.chunkSize() + if (n < sz) { chunk = child; break } + n -= sz + } + } + return chunk.lines[n] +} + +// Get the part of a document between two positions, as an array of +// strings. +export function getBetween(doc, start, end) { + let out = [], n = start.line + doc.iter(start.line, end.line + 1, line => { + let text = line.text + if (n == end.line) text = text.slice(0, end.ch) + if (n == start.line) text = text.slice(start.ch) + out.push(text) + ++n + }) + return out +} +// Get the lines between from and to, as array of strings. +export function getLines(doc, from, to) { + let out = [] + doc.iter(from, to, line => { out.push(line.text) }) // iter aborts when callback returns truthy value + return out +} + +// Update the height of a line, propagating the height change +// upwards to parent nodes. +export function updateLineHeight(line, height) { + let diff = height - line.height + if (diff) for (let n = line; n; n = n.parent) n.height += diff +} + +// Given a line object, find its line number by walking up through +// its parent links. +export function lineNo(line) { + if (line.parent == null) return null + let cur = line.parent, no = indexOf(cur.lines, line) + for (let chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (let i = 0;; ++i) { + if (chunk.children[i] == cur) break + no += chunk.children[i].chunkSize() + } + } + return no + cur.first +} + +// Find the line at the given vertical position, using the height +// information in the document tree. +export function lineAtHeight(chunk, h) { + let n = chunk.first + outer: do { + for (let i = 0; i < chunk.children.length; ++i) { + let child = chunk.children[i], ch = child.height + if (h < ch) { chunk = child; continue outer } + h -= ch + n += child.chunkSize() + } + return n + } while (!chunk.lines) + let i = 0 + for (; i < chunk.lines.length; ++i) { + let line = chunk.lines[i], lh = line.height + if (h < lh) break + h -= lh + } + return n + i +} + +export function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size} + +export function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)) +} diff --git a/backend/webif/static/codemirror/src/measurement/position_measurement.js b/backend/webif/static/codemirror/src/measurement/position_measurement.js new file mode 100755 index 000000000..aeff0e5b8 --- /dev/null +++ b/backend/webif/static/codemirror/src/measurement/position_measurement.js @@ -0,0 +1,700 @@ +import { buildLineContent, LineView } from "../line/line_data.js" +import { clipPos, Pos } from "../line/pos.js" +import { collapsedSpanAtEnd, heightAtLine, lineIsHidden, visualLine } from "../line/spans.js" +import { getLine, lineAtHeight, lineNo, updateLineHeight } from "../line/utils_line.js" +import { bidiOther, getBidiPartAt, getOrder } from "../util/bidi.js" +import { chrome, android, ie, ie_version } from "../util/browser.js" +import { elt, removeChildren, range, removeChildrenAndAdd } from "../util/dom.js" +import { e_target } from "../util/event.js" +import { hasBadZoomedRects } from "../util/feature_detection.js" +import { countColumn, findFirst, isExtendingChar, scrollerGap, skipExtendingChars } from "../util/misc.js" +import { updateLineForChanges } from "../display/update_line.js" + +import { widgetHeight } from "./widgets.js" + +// POSITION MEASUREMENT + +export function paddingTop(display) {return display.lineSpace.offsetTop} +export function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight} +export function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH + let e = removeChildrenAndAdd(display.measure, elt("pre", "x")) + let style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle + let data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)} + if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data + return data +} + +export function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth } +export function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth +} +export function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight +} + +// Ensure the lineView.wrapping.heights array is populated. This is +// an array of bottom offsets for the lines that make up a drawn +// line. When lineWrapping is on, there might be more than one +// height. +function ensureLineHeights(cm, lineView, rect) { + let wrapping = cm.options.lineWrapping + let curWidth = wrapping && displayWidth(cm) + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + let heights = lineView.measure.heights = [] + if (wrapping) { + lineView.measure.width = curWidth + let rects = lineView.text.firstChild.getClientRects() + for (let i = 0; i < rects.length - 1; i++) { + let cur = rects[i], next = rects[i + 1] + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top) + } + } + heights.push(rect.bottom - rect.top) + } +} + +// Find a line map (mapping character offsets to text nodes) and a +// measurement cache for the given line number. (A line view might +// contain multiple lines when collapsed ranges are present.) +export function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return {map: lineView.measure.map, cache: lineView.measure.cache} + for (let i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} + for (let i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true} +} + +// Render a line into the hidden node display.externalMeasured. Used +// when measurement is needed for a line that's not in the viewport. +function updateExternalMeasurement(cm, line) { + line = visualLine(line) + let lineN = lineNo(line) + let view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN) + view.lineN = lineN + let built = view.built = buildLineContent(cm, view) + view.text = built.pre + removeChildrenAndAdd(cm.display.lineMeasure, built.pre) + return view +} + +// Get a {top, bottom, left, right} box (in line-local coordinates) +// for a given character. +export function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias) +} + +// Find a line view that corresponds to the given line number. +export function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)] + let ext = cm.display.externalMeasured + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext +} + +// Measurement can be split in two steps, the set-up work that +// applies to the whole line, and the measurement of the actual +// character. Functions like coordsChar, that need to do a lot of +// measurements in a row, can thus ensure that the set-up work is +// only done once. +export function prepareMeasureForLine(cm, line) { + let lineN = lineNo(line) + let view = findViewForLine(cm, lineN) + if (view && !view.text) { + view = null + } else if (view && view.changes) { + updateLineForChanges(cm, view, lineN, getDimensions(cm)) + cm.curOp.forceUpdate = true + } + if (!view) + view = updateExternalMeasurement(cm, line) + + let info = mapFromLineView(view, line, lineN) + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + } +} + +// Given a prepared measurement object, measures the position of an +// actual character (or fetches it from the cache). +export function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) ch = -1 + let key = ch + (bias || ""), found + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key] + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect() + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect) + prepared.hasHeights = true + } + found = measureCharInner(cm, prepared, ch, bias) + if (!found.bogus) prepared.cache[key] = found + } + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom} +} + +let nullRect = {left: 0, right: 0, top: 0, bottom: 0} + +export function nodeAndOffsetInLineMap(map, ch, bias) { + let node, start, end, collapse, mStart, mEnd + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (let i = 0; i < map.length; i += 3) { + mStart = map[i] + mEnd = map[i + 1] + if (ch < mStart) { + start = 0; end = 1 + collapse = "left" + } else if (ch < mEnd) { + start = ch - mStart + end = start + 1 + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart + start = end - 1 + if (ch >= mEnd) collapse = "right" + } + if (start != null) { + node = map[i + 2] + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2] + collapse = "left" + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2] + collapse = "right" + } + break + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd} +} + +function getUsefulRect(rects, bias) { + let rect = nullRect + if (bias == "left") for (let i = 0; i < rects.length; i++) { + if ((rect = rects[i]).left != rect.right) break + } else for (let i = rects.length - 1; i >= 0; i--) { + if ((rect = rects[i]).left != rect.right) break + } + return rect +} + +function measureCharInner(cm, prepared, ch, bias) { + let place = nodeAndOffsetInLineMap(prepared.map, ch, bias) + let node = place.node, start = place.start, end = place.end, collapse = place.collapse + + let rect + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (let i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) + rect = node.parentNode.getBoundingClientRect() + else + rect = getUsefulRect(range(node, start, end).getClientRects(), bias) + if (rect.left || rect.right || start == 0) break + end = start + start = start - 1 + collapse = "right" + } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect) + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right" + let rects + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0] + else + rect = node.getBoundingClientRect() + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + let rSpan = node.parentNode.getClientRects()[0] + if (rSpan) + rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} + else + rect = nullRect + } + + let rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top + let mid = (rtop + rbot) / 2 + let heights = prepared.view.measure.heights + let i = 0 + for (; i < heights.length - 1; i++) + if (mid < heights[i]) break + let top = i ? heights[i - 1] : 0, bot = heights[i] + let result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot} + if (!rect.left && !rect.right) result.bogus = true + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot } + + return result +} + +// Work around problem with bounding client rects on ranges being +// returned incorrectly when zoomed on IE10 and below. +function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + return rect + let scaleX = screen.logicalXDPI / screen.deviceXDPI + let scaleY = screen.logicalYDPI / screen.deviceYDPI + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY} +} + +export function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {} + lineView.measure.heights = null + if (lineView.rest) for (let i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {} + } +} + +export function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null + removeChildren(cm.display.lineMeasure) + for (let i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]) +} + +export function clearCaches(cm) { + clearLineMeasurementCache(cm) + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true + cm.display.lineNumChars = null +} + +function pageScrollX() { + // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 + // which causes page_Offset and bounding client rects to use + // different reference viewports and invalidate our calculations. + if (chrome && android) return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) + return window.pageXOffset || (document.documentElement || document.body).scrollLeft +} +function pageScrollY() { + if (chrome && android) return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) + return window.pageYOffset || (document.documentElement || document.body).scrollTop +} + +function widgetTopHeight(lineObj) { + let height = 0 + if (lineObj.widgets) for (let i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) + height += widgetHeight(lineObj.widgets[i]) + return height +} + +// Converts a {top, bottom, left, right} box from line-local +// coordinates into another coordinate system. Context may be one of +// "line", "div" (display.lineDiv), "local"./null (editor), "window", +// or "page". +export function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { + if (!includeWidgets) { + let height = widgetTopHeight(lineObj) + rect.top += height; rect.bottom += height + } + if (context == "line") return rect + if (!context) context = "local" + let yOff = heightAtLine(lineObj) + if (context == "local") yOff += paddingTop(cm.display) + else yOff -= cm.display.viewOffset + if (context == "page" || context == "window") { + let lOff = cm.display.lineSpace.getBoundingClientRect() + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()) + let xOff = lOff.left + (context == "window" ? 0 : pageScrollX()) + rect.left += xOff; rect.right += xOff + } + rect.top += yOff; rect.bottom += yOff + return rect +} + +// Coverts a box from "div" coords to another coordinate system. +// Context may be "window", "page", "div", or "local"./null. +export function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords + let left = coords.left, top = coords.top + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX() + top -= pageScrollY() + } else if (context == "local" || !context) { + let localBox = cm.display.sizer.getBoundingClientRect() + left += localBox.left + top += localBox.top + } + + let lineSpaceBox = cm.display.lineSpace.getBoundingClientRect() + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top} +} + +export function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line) + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) +} + +// Returns a box for a given cursor position, which may have an +// 'other' property containing the position of the secondary cursor +// on a bidi boundary. +// A cursor Pos(line, char, "before") is on the same visual line as `char - 1` +// and after `char - 1` in writing order of `char - 1` +// A cursor Pos(line, char, "after") is on the same visual line as `char` +// and before `char` in writing order of `char` +// Examples (upper-case letters are RTL, lower-case are LTR): +// Pos(0, 1, ...) +// before after +// ab a|b a|b +// aB a|B aB| +// Ab |Ab A|b +// AB B|A B|A +// Every position after the last character on a line is considered to stick +// to the last character on the line. +export function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line) + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj) + function get(ch, right) { + let m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight) + if (right) m.left = m.right; else m.right = m.left + return intoCoordSystem(cm, lineObj, m, context) + } + let order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky + if (ch >= lineObj.text.length) { + ch = lineObj.text.length + sticky = "before" + } else if (ch <= 0) { + ch = 0 + sticky = "after" + } + if (!order) return get(sticky == "before" ? ch - 1 : ch, sticky == "before") + + function getBidi(ch, partPos, invert) { + let part = order[partPos], right = part.level == 1 + return get(invert ? ch - 1 : ch, right != invert) + } + let partPos = getBidiPartAt(order, ch, sticky) + let other = bidiOther + let val = getBidi(ch, partPos, sticky == "before") + if (other != null) val.other = getBidi(ch, other, sticky != "before") + return val +} + +// Used to cheaply estimate the coordinates for a position. Used for +// intermediate scroll updates. +export function estimateCoords(cm, pos) { + let left = 0 + pos = clipPos(cm.doc, pos) + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch + let lineObj = getLine(cm.doc, pos.line) + let top = heightAtLine(lineObj) + paddingTop(cm.display) + return {left: left, right: left, top: top, bottom: top + lineObj.height} +} + +// Positions returned by coordsChar contain some extra information. +// xRel is the relative x position of the input coordinates compared +// to the found position (so xRel > 0 means the coordinates are to +// the right of the character position, for example). When outside +// is true, that means the coordinates lie outside the line's +// vertical range. +function PosWithInfo(line, ch, sticky, outside, xRel) { + let pos = Pos(line, ch, sticky) + pos.xRel = xRel + if (outside) pos.outside = true + return pos +} + +// Compute the character position closest to the given coordinates. +// Input must be lineSpace-local ("div" coordinate system). +export function coordsChar(cm, x, y) { + let doc = cm.doc + y += cm.display.viewOffset + if (y < 0) return PosWithInfo(doc.first, 0, null, true, -1) + let lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1 + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) + if (x < 0) x = 0 + + let lineObj = getLine(doc, lineN) + for (;;) { + let found = coordsCharInner(cm, lineObj, lineN, x, y) + let merged = collapsedSpanAtEnd(lineObj) + let mergedPos = merged && merged.find(0, true) + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line) + else + return found + } +} + +function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { + y -= widgetTopHeight(lineObj) + let end = lineObj.text.length + let begin = findFirst(ch => measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y, end, 0) + end = findFirst(ch => measureCharPrepared(cm, preparedMeasure, ch).top > y, begin, end) + return {begin, end} +} + +export function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj) + let targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top + return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) +} + +// Returns true if the given side of a box is after the given +// coordinates, in top-to-bottom, left-to-right order. +function boxIsAfter(box, x, y, left) { + return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x +} + +function coordsCharInner(cm, lineObj, lineNo, x, y) { + // Move y into line-local coordinate space + y -= heightAtLine(lineObj) + let preparedMeasure = prepareMeasureForLine(cm, lineObj) + // When directly calling `measureCharPrepared`, we have to adjust + // for the widgets at this line. + let widgetHeight = widgetTopHeight(lineObj) + let begin = 0, end = lineObj.text.length, ltr = true + + let order = getOrder(lineObj, cm.doc.direction) + // If the line isn't plain left-to-right text, first figure out + // which bidi section the coordinates fall into. + if (order) { + let part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) + (cm, lineObj, lineNo, preparedMeasure, order, x, y) + ltr = part.level != 1 + // The awkward -1 offsets are needed because findFirst (called + // on these below) will treat its first bound as inclusive, + // second as exclusive, but we want to actually address the + // characters in the part's range + begin = ltr ? part.from : part.to - 1 + end = ltr ? part.to : part.from - 1 + } + + // A binary search to find the first character whose bounding box + // starts after the coordinates. If we run across any whose box wrap + // the coordinates, store that. + let chAround = null, boxAround = null + let ch = findFirst(ch => { + let box = measureCharPrepared(cm, preparedMeasure, ch) + box.top += widgetHeight; box.bottom += widgetHeight + if (!boxIsAfter(box, x, y, false)) return false + if (box.top <= y && box.left <= x) { + chAround = ch + boxAround = box + } + return true + }, begin, end) + + let baseX, sticky, outside = false + // If a box around the coordinates was found, use that + if (boxAround) { + // Distinguish coordinates nearer to the left or right side of the box + let atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr + ch = chAround + (atStart ? 0 : 1) + sticky = atStart ? "after" : "before" + baseX = atLeft ? boxAround.left : boxAround.right + } else { + // (Adjust for extended bound, if necessary.) + if (!ltr && (ch == end || ch == begin)) ch++ + // To determine which side to associate with, get the box to the + // left of the character and compare it's vertical position to the + // coordinates + sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : + (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ? + "after" : "before" + // Now get accurate coordinates for this place, in order to get a + // base X position + let coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure) + baseX = coords.left + outside = y < coords.top || y >= coords.bottom + } + + ch = skipExtendingChars(lineObj.text, ch, 1) + return PosWithInfo(lineNo, ch, sticky, outside, x - baseX) +} + +function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) { + // Bidi parts are sorted left-to-right, and in a non-line-wrapping + // situation, we can take this ordering to correspond to the visual + // ordering. This finds the first part whose end is after the given + // coordinates. + let index = findFirst(i => { + let part = order[i], ltr = part.level != 1 + return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"), + "line", lineObj, preparedMeasure), x, y, true) + }, 0, order.length - 1) + let part = order[index] + // If this isn't the first part, the part's start is also after + // the coordinates, and the coordinates aren't on the same line as + // that start, move one part back. + if (index > 0) { + let ltr = part.level != 1 + let start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"), + "line", lineObj, preparedMeasure) + if (boxIsAfter(start, x, y, true) && start.top > y) + part = order[index - 1] + } + return part +} + +function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { + // In a wrapped line, rtl text on wrapping boundaries can do things + // that don't correspond to the ordering in our `order` array at + // all, so a binary search doesn't work, and we want to return a + // part that only spans one line so that the binary search in + // coordsCharInner is safe. As such, we first find the extent of the + // wrapped line, and then do a flat search in which we discard any + // spans that aren't on the line. + let {begin, end} = wrappedLineExtent(cm, lineObj, preparedMeasure, y) + if (/\s/.test(lineObj.text.charAt(end - 1))) end-- + let part = null, closestDist = null + for (let i = 0; i < order.length; i++) { + let p = order[i] + if (p.from >= end || p.to <= begin) continue + let ltr = p.level != 1 + let endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right + // Weigh against spans ending before this, so that they are only + // picked if nothing ends after + let dist = endX < x ? x - endX + 1e9 : endX - x + if (!part || closestDist > dist) { + part = p + closestDist = dist + } + } + if (!part) part = order[order.length - 1] + // Clip the part to the wrapped line. + if (part.from < begin) part = {from: begin, to: part.to, level: part.level} + if (part.to > end) part = {from: part.from, to: end, level: part.level} + return part +} + +let measureText +// Compute the default text height. +export function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight + if (measureText == null) { + measureText = elt("pre") + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (let i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")) + measureText.appendChild(elt("br")) + } + measureText.appendChild(document.createTextNode("x")) + } + removeChildrenAndAdd(display.measure, measureText) + let height = measureText.offsetHeight / 50 + if (height > 3) display.cachedTextHeight = height + removeChildren(display.measure) + return height || 1 +} + +// Compute the default character width. +export function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth + let anchor = elt("span", "xxxxxxxxxx") + let pre = elt("pre", [anchor]) + removeChildrenAndAdd(display.measure, pre) + let rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10 + if (width > 2) display.cachedCharWidth = width + return width || 10 +} + +// Do a bulk-read of the DOM positions and sizes needed to draw the +// view, so that we don't interleave reading and writing to the DOM. +export function getDimensions(cm) { + let d = cm.display, left = {}, width = {} + let gutterLeft = d.gutters.clientLeft + for (let n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft + width[cm.options.gutters[i]] = n.clientWidth + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth} +} + +// Computes display.scroller.scrollLeft + display.gutters.offsetWidth, +// but using getBoundingClientRect to get a sub-pixel-accurate +// result. +export function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left +} + +// Returns a function that estimates the height of a line, to use as +// first approximation until the line becomes visible (and is thus +// properly measurable). +export function estimateHeight(cm) { + let th = textHeight(cm.display), wrapping = cm.options.lineWrapping + let perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3) + return line => { + if (lineIsHidden(cm.doc, line)) return 0 + + let widgetsHeight = 0 + if (line.widgets) for (let i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height + } + + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th + else + return widgetsHeight + th + } +} + +export function estimateLineHeights(cm) { + let doc = cm.doc, est = estimateHeight(cm) + doc.iter(line => { + let estHeight = est(line) + if (estHeight != line.height) updateLineHeight(line, estHeight) + }) +} + +// Given a mouse event, find the corresponding position. If liberal +// is false, it checks whether a gutter or scrollbar was clicked, +// and returns null if it was. forRect is used by rectangular +// selections, and tries to estimate a character position even for +// coordinates beyond the right of the text. +export function posFromMouse(cm, e, liberal, forRect) { + let display = cm.display + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null + + let x, y, space = display.lineSpace.getBoundingClientRect() + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top } + catch (e) { return null } + let coords = coordsChar(cm, x, y), line + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + let colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)) + } + return coords +} + +// Find the view element corresponding to a given line. Return null +// when the line isn't visible. +export function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null + n -= cm.display.viewFrom + if (n < 0) return null + let view = cm.display.view + for (let i = 0; i < view.length; i++) { + n -= view[i].size + if (n < 0) return i + } +} diff --git a/backend/webif/static/codemirror/src/measurement/widgets.js b/backend/webif/static/codemirror/src/measurement/widgets.js new file mode 100755 index 000000000..39d7553d1 --- /dev/null +++ b/backend/webif/static/codemirror/src/measurement/widgets.js @@ -0,0 +1,26 @@ +import { contains, elt, removeChildrenAndAdd } from "../util/dom.js" +import { e_target } from "../util/event.js" + +export function widgetHeight(widget) { + if (widget.height != null) return widget.height + let cm = widget.doc.cm + if (!cm) return 0 + if (!contains(document.body, widget.node)) { + let parentStyle = "position: relative;" + if (widget.coverGutter) + parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;" + if (widget.noHScroll) + parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;" + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)) + } + return widget.height = widget.node.parentNode.offsetHeight +} + +// Return true when the given mouse event happened in a widget +export function eventInWidget(display, e) { + for (let n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + return true + } +} diff --git a/backend/webif/static/codemirror/src/model/Doc.js b/backend/webif/static/codemirror/src/model/Doc.js new file mode 100755 index 000000000..b64ac8437 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/Doc.js @@ -0,0 +1,432 @@ +import CodeMirror from "../edit/CodeMirror.js" +import { docMethodOp } from "../display/operations.js" +import { Line } from "../line/line_data.js" +import { clipPos, clipPosArray, Pos } from "../line/pos.js" +import { visualLine } from "../line/spans.js" +import { getBetween, getLine, getLines, isLine, lineNo } from "../line/utils_line.js" +import { classTest } from "../util/dom.js" +import { splitLinesAuto } from "../util/feature_detection.js" +import { createObj, map, isEmpty, sel_dontScroll } from "../util/misc.js" +import { ensureCursorVisible, scrollToCoords } from "../display/scrolling.js" + +import { changeLine, makeChange, makeChangeFromHistory, replaceRange } from "./changes.js" +import { computeReplacedSel } from "./change_measurement.js" +import { BranchChunk, LeafChunk } from "./chunk.js" +import { directionChanged, linkedDocs, updateDoc } from "./document_data.js" +import { copyHistoryArray, History } from "./history.js" +import { addLineWidget } from "./line_widget.js" +import { copySharedMarkers, detachSharedMarkers, findSharedMarkers, markText } from "./mark_text.js" +import { normalizeSelection, Range, simpleSelection } from "./selection.js" +import { extendSelection, extendSelections, setSelection, setSelectionReplaceHistory, setSimpleSelection } from "./selection_updates.js" + +let nextDocId = 0 +let Doc = function(text, mode, firstLine, lineSep, direction) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep, direction) + if (firstLine == null) firstLine = 0 + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]) + this.first = firstLine + this.scrollTop = this.scrollLeft = 0 + this.cantEdit = false + this.cleanGeneration = 1 + this.modeFrontier = this.highlightFrontier = firstLine + let start = Pos(firstLine, 0) + this.sel = simpleSelection(start) + this.history = new History(null) + this.id = ++nextDocId + this.modeOption = mode + this.lineSep = lineSep + this.direction = (direction == "rtl") ? "rtl" : "ltr" + this.extend = false + + if (typeof text == "string") text = this.splitLines(text) + updateDoc(this, {from: start, to: start, text: text}) + setSelection(this, simpleSelection(start), sel_dontScroll) +} + +Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op) + else this.iterN(this.first, this.first + this.size, from) + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + let height = 0 + for (let i = 0; i < lines.length; ++i) height += lines[i].height + this.insertInner(at - this.first, lines, height) + }, + remove: function(at, n) { this.removeInner(at - this.first, n) }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep) { + let lines = getLines(this, this.first, this.first + this.size) + if (lineSep === false) return lines + return lines.join(lineSep || this.lineSeparator()) + }, + setValue: docMethodOp(function(code) { + let top = Pos(this.first, 0), last = this.first + this.size - 1 + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: this.splitLines(code), origin: "setValue", full: true}, true) + if (this.cm) scrollToCoords(this.cm, 0, 0) + setSelection(this, simpleSelection(top), sel_dontScroll) + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from) + to = to ? clipPos(this, to) : from + replaceRange(this, code, from, to, origin) + }, + getRange: function(from, to, lineSep) { + let lines = getBetween(this, clipPos(this, from), clipPos(this, to)) + if (lineSep === false) return lines + return lines.join(lineSep || this.lineSeparator()) + }, + + getLine: function(line) {let l = this.getLineHandle(line); return l && l.text}, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line)}, + getLineNumber: function(line) {return lineNo(line)}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line) + return visualLine(line) + }, + + lineCount: function() {return this.size}, + firstLine: function() {return this.first}, + lastLine: function() {return this.first + this.size - 1}, + + clipPos: function(pos) {return clipPos(this, pos)}, + + getCursor: function(start) { + let range = this.sel.primary(), pos + if (start == null || start == "head") pos = range.head + else if (start == "anchor") pos = range.anchor + else if (start == "end" || start == "to" || start === false) pos = range.to() + else pos = range.from() + return pos + }, + listSelections: function() { return this.sel.ranges }, + somethingSelected: function() {return this.sel.somethingSelected()}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options) + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options) + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options) + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads), options) + }), + extendSelectionsBy: docMethodOp(function(f, options) { + let heads = map(this.sel.ranges, f) + extendSelections(this, clipPosArray(this, heads), options) + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) return + let out = [] + for (let i = 0; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)) + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex) + setSelection(this, normalizeSelection(out, primary), options) + }), + addSelection: docMethodOp(function(anchor, head, options) { + let ranges = this.sel.ranges.slice(0) + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))) + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options) + }), + + getSelection: function(lineSep) { + let ranges = this.sel.ranges, lines + for (let i = 0; i < ranges.length; i++) { + let sel = getBetween(this, ranges[i].from(), ranges[i].to()) + lines = lines ? lines.concat(sel) : sel + } + if (lineSep === false) return lines + else return lines.join(lineSep || this.lineSeparator()) + }, + getSelections: function(lineSep) { + let parts = [], ranges = this.sel.ranges + for (let i = 0; i < ranges.length; i++) { + let sel = getBetween(this, ranges[i].from(), ranges[i].to()) + if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()) + parts[i] = sel + } + return parts + }, + replaceSelection: function(code, collapse, origin) { + let dup = [] + for (let i = 0; i < this.sel.ranges.length; i++) + dup[i] = code + this.replaceSelections(dup, collapse, origin || "+input") + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + let changes = [], sel = this.sel + for (let i = 0; i < sel.ranges.length; i++) { + let range = sel.ranges[i] + changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin} + } + let newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse) + for (let i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]) + if (newSel) setSelectionReplaceHistory(this, newSel) + else if (this.cm) ensureCursorVisible(this.cm) + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo")}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo")}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true)}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true)}), + + setExtending: function(val) {this.extend = val}, + getExtending: function() {return this.extend}, + + historySize: function() { + let hist = this.history, done = 0, undone = 0 + for (let i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done + for (let i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone + return {undo: done, redo: undone} + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration)}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true) + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null + return this.history.generation + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration) + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)} + }, + setHistory: function(histData) { + let hist = this.history = new History(this.history.maxGeneration) + hist.done = copyHistoryArray(histData.done.slice(0), null, true) + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true) + }, + + setGutterMarker: docMethodOp(function(line, gutterID, value) { + return changeLine(this, line, "gutter", line => { + let markers = line.gutterMarkers || (line.gutterMarkers = {}) + markers[gutterID] = value + if (!value && isEmpty(markers)) line.gutterMarkers = null + return true + }) + }), + + clearGutter: docMethodOp(function(gutterID) { + this.iter(line => { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + changeLine(this, line, "gutter", () => { + line.gutterMarkers[gutterID] = null + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null + return true + }) + } + }) + }), + + lineInfo: function(line) { + let n + if (typeof line == "number") { + if (!isLine(this, line)) return null + n = line + line = getLine(this, line) + if (!line) return null + } else { + n = lineNo(line) + if (n == null) return null + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets} + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", line => { + let prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass" + if (!line[prop]) line[prop] = cls + else if (classTest(cls).test(line[prop])) return false + else line[prop] += " " + cls + return true + }) + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", line => { + let prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass" + let cur = line[prop] + if (!cur) return false + else if (cls == null) line[prop] = null + else { + let found = cur.match(classTest(cls)) + if (!found) return false + let end = found.index + found[0].length + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null + } + return true + }) + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options) + }), + removeLineWidget: function(widget) { widget.clear() }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range") + }, + setBookmark: function(pos, options) { + let realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents} + pos = clipPos(this, pos) + return markText(this, pos, pos, realOpts, "bookmark") + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos) + let markers = [], spans = getLine(this, pos.line).markedSpans + if (spans) for (let i = 0; i < spans.length; ++i) { + let span = spans[i] + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker) + } + return markers + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to) + let found = [], lineNo = from.line + this.iter(from.line, to.line + 1, line => { + let spans = line.markedSpans + if (spans) for (let i = 0; i < spans.length; i++) { + let span = spans[i] + if (!(span.to != null && lineNo == from.line && from.ch >= span.to || + span.from == null && lineNo != from.line || + span.from != null && lineNo == to.line && span.from >= to.ch) && + (!filter || filter(span.marker))) + found.push(span.marker.parent || span.marker) + } + ++lineNo + }) + return found + }, + getAllMarks: function() { + let markers = [] + this.iter(line => { + let sps = line.markedSpans + if (sps) for (let i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker) + }) + return markers + }, + + posFromIndex: function(off) { + let ch, lineNo = this.first, sepSize = this.lineSeparator().length + this.iter(line => { + let sz = line.text.length + sepSize + if (sz > off) { ch = off; return true } + off -= sz + ++lineNo + }) + return clipPos(this, Pos(lineNo, ch)) + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords) + let index = coords.ch + if (coords.line < this.first || coords.ch < 0) return 0 + let sepSize = this.lineSeparator().length + this.iter(this.first, coords.line, line => { // iter aborts when callback returns a truthy value + index += line.text.length + sepSize + }) + return index + }, + + copy: function(copyHistory) { + let doc = new Doc(getLines(this, this.first, this.first + this.size), + this.modeOption, this.first, this.lineSep, this.direction) + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft + doc.sel = this.sel + doc.extend = false + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth + doc.setHistory(this.getHistory()) + } + return doc + }, + + linkedDoc: function(options) { + if (!options) options = {} + let from = this.first, to = this.first + this.size + if (options.from != null && options.from > from) from = options.from + if (options.to != null && options.to < to) to = options.to + let copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction) + if (options.sharedHist) copy.history = this.history + ;(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}) + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}] + copySharedMarkers(copy, findSharedMarkers(this)) + return copy + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc + if (this.linked) for (let i = 0; i < this.linked.length; ++i) { + let link = this.linked[i] + if (link.doc != other) continue + this.linked.splice(i, 1) + other.unlinkDoc(this) + detachSharedMarkers(findSharedMarkers(this)) + break + } + // If the histories were shared, split them again + if (other.history == this.history) { + let splitIds = [other.id] + linkedDocs(other, doc => splitIds.push(doc.id), true) + other.history = new History(null) + other.history.done = copyHistoryArray(this.history.done, splitIds) + other.history.undone = copyHistoryArray(this.history.undone, splitIds) + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f)}, + + getMode: function() {return this.mode}, + getEditor: function() {return this.cm}, + + splitLines: function(str) { + if (this.lineSep) return str.split(this.lineSep) + return splitLinesAuto(str) + }, + lineSeparator: function() { return this.lineSep || "\n" }, + + setDirection: docMethodOp(function (dir) { + if (dir != "rtl") dir = "ltr" + if (dir == this.direction) return + this.direction = dir + this.iter(line => line.order = null) + if (this.cm) directionChanged(this.cm) + }) +}) + +// Public alias. +Doc.prototype.eachLine = Doc.prototype.iter + +export default Doc diff --git a/backend/webif/static/codemirror/src/model/change_measurement.js b/backend/webif/static/codemirror/src/model/change_measurement.js new file mode 100755 index 000000000..4d45313de --- /dev/null +++ b/backend/webif/static/codemirror/src/model/change_measurement.js @@ -0,0 +1,61 @@ +import { cmp, Pos } from "../line/pos.js" +import { lst } from "../util/misc.js" + +import { normalizeSelection, Range, Selection } from "./selection.js" + +// Compute the position of the end of a change (its 'to' property +// refers to the pre-change end). +export function changeEnd(change) { + if (!change.text) return change.to + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)) +} + +// Adjust a position to refer to the post-change position of the +// same text, or the end of the change if the change covers it. +function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos + if (cmp(pos, change.to) <= 0) return changeEnd(change) + + let line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch + return Pos(line, ch) +} + +export function computeSelAfterChange(doc, change) { + let out = [] + for (let i = 0; i < doc.sel.ranges.length; i++) { + let range = doc.sel.ranges[i] + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))) + } + return normalizeSelection(out, doc.sel.primIndex) +} + +function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch) + else + return Pos(nw.line + (pos.line - old.line), pos.ch) +} + +// Used by replaceSelections to allow moving the selection to the +// start or around the replaced test. Hint may be "start" or "around". +export function computeReplacedSel(doc, changes, hint) { + let out = [] + let oldPrev = Pos(doc.first, 0), newPrev = oldPrev + for (let i = 0; i < changes.length; i++) { + let change = changes[i] + let from = offsetPos(change.from, oldPrev, newPrev) + let to = offsetPos(changeEnd(change), oldPrev, newPrev) + oldPrev = change.to + newPrev = to + if (hint == "around") { + let range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0 + out[i] = new Range(inv ? to : from, inv ? from : to) + } else { + out[i] = new Range(from, from) + } + } + return new Selection(out, doc.sel.primIndex) +} diff --git a/backend/webif/static/codemirror/src/model/changes.js b/backend/webif/static/codemirror/src/model/changes.js new file mode 100755 index 000000000..b00e29b13 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/changes.js @@ -0,0 +1,330 @@ +import { retreatFrontier } from "../line/highlight.js" +import { startWorker } from "../display/highlight_worker.js" +import { operation } from "../display/operations.js" +import { regChange, regLineChange } from "../display/view_tracking.js" +import { clipLine, clipPos, cmp, Pos } from "../line/pos.js" +import { sawReadOnlySpans } from "../line/saw_special_spans.js" +import { lineLength, removeReadOnlyRanges, stretchSpansOverChange, visualLine } from "../line/spans.js" +import { getBetween, getLine, lineNo } from "../line/utils_line.js" +import { estimateHeight } from "../measurement/position_measurement.js" +import { hasHandler, signal, signalCursorActivity } from "../util/event.js" +import { indexOf, lst, map, sel_dontScroll } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" + +import { changeEnd, computeSelAfterChange } from "./change_measurement.js" +import { isWholeLineUpdate, linkedDocs, updateDoc } from "./document_data.js" +import { addChangeToHistory, historyChangeFromChange, mergeOldSpans, pushSelectionToHistory } from "./history.js" +import { Range, Selection } from "./selection.js" +import { setSelection, setSelectionNoUndo } from "./selection_updates.js" + +// UPDATING + +// Allow "beforeChange" event handlers to influence a change +function filterChange(doc, change, update) { + let obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: () => obj.canceled = true + } + if (update) obj.update = (from, to, text, origin) => { + if (from) obj.from = clipPos(doc, from) + if (to) obj.to = clipPos(doc, to) + if (text) obj.text = text + if (origin !== undefined) obj.origin = origin + } + signal(doc, "beforeChange", doc, obj) + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj) + + if (obj.canceled) return null + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin} +} + +// Apply a change to a document, and add it to the document's +// history, and propagating it to all linked documents. +export function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) + if (doc.cm.state.suppressEdits) return + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true) + if (!change) return + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + let split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to) + if (split) { + for (let i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}) + } else { + makeChangeInner(doc, change) + } +} + +function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return + let selAfter = computeSelAfterChange(doc, change) + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN) + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)) + let rebased = [] + + linkedDocs(doc, (doc, sharedHist) => { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change) + rebased.push(doc.history) + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)) + }) +} + +// Revert a change stored in a document's history. +export function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) return + + let hist = doc.history, event, selAfter = doc.sel + let source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + let i = 0 + for (; i < source.length; i++) { + event = source[i] + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break + } + if (i == source.length) return + hist.lastOrigin = hist.lastSelOrigin = null + + for (;;) { + event = source.pop() + if (event.ranges) { + pushSelectionToHistory(event, dest) + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}) + return + } + selAfter = event + } + else break + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + let antiChanges = [] + pushSelectionToHistory(selAfter, dest) + dest.push({changes: antiChanges, generation: hist.generation}) + hist.generation = event.generation || ++hist.maxGeneration + + let filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange") + + for (let i = event.changes.length - 1; i >= 0; --i) { + let change = event.changes[i] + change.origin = type + if (filter && !filterChange(doc, change, false)) { + source.length = 0 + return + } + + antiChanges.push(historyChangeFromChange(doc, change)) + + let after = i ? computeSelAfterChange(doc, change) : lst(source) + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)) + if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) + let rebased = [] + + // Propagate to the linked documents + linkedDocs(doc, (doc, sharedHist) => { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change) + rebased.push(doc.history) + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)) + }) + } +} + +// Sub-views need their line numbers shifted when text is added +// above or below them in the parent document. +function shiftDoc(doc, distance) { + if (distance == 0) return + doc.first += distance + doc.sel = new Selection(map(doc.sel.ranges, range => new Range( + Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch) + )), doc.sel.primIndex) + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance) + for (let d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + regLineChange(doc.cm, l, "gutter") + } +} + +// More lower-level change function, handling only a single document +// (not linked ones). +function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)) + return + } + if (change.from.line > doc.lastLine()) return + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + let shift = change.text.length - 1 - (doc.first - change.from.line) + shiftDoc(doc, shift) + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin} + } + let last = doc.lastLine() + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin} + } + + change.removed = getBetween(doc, change.from, change.to) + + if (!selAfter) selAfter = computeSelAfterChange(doc, change) + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans) + else updateDoc(doc, change, spans) + setSelectionNoUndo(doc, selAfter, sel_dontScroll) +} + +// Handle the interaction of a change to a document with the editor +// that this document is part of. +function makeChangeSingleDocInEditor(cm, change, spans) { + let doc = cm.doc, display = cm.display, from = change.from, to = change.to + + let recomputeMaxLength = false, checkWidthStart = from.line + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))) + doc.iter(checkWidthStart, to.line + 1, line => { + if (line == display.maxLine) { + recomputeMaxLength = true + return true + } + }) + } + + if (doc.sel.contains(change.from, change.to) > -1) + signalCursorActivity(cm) + + updateDoc(doc, change, spans, estimateHeight(cm)) + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, line => { + let len = lineLength(line) + if (len > display.maxLineLength) { + display.maxLine = line + display.maxLineLength = len + display.maxLineChanged = true + recomputeMaxLength = false + } + }) + if (recomputeMaxLength) cm.curOp.updateMaxLine = true + } + + retreatFrontier(doc, from.line) + startWorker(cm, 400) + + let lendiff = change.text.length - (to.line - from.line) - 1 + // Remember that these lines changed, for updating the display + if (change.full) + regChange(cm) + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text") + else + regChange(cm, from.line, to.line + 1, lendiff) + + let changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change") + if (changeHandler || changesHandler) { + let obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + } + if (changeHandler) signalLater(cm, "change", cm, obj) + if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) + } + cm.display.selForContextMenu = null +} + +export function replaceRange(doc, code, from, to, origin) { + if (!to) to = from + if (cmp(to, from) < 0) [from, to] = [to, from] + if (typeof code == "string") code = doc.splitLines(code) + makeChange(doc, {from, to, text: code, origin}) +} + +// Rebasing/resetting history to deal with externally-sourced changes + +function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff + } else if (from < pos.line) { + pos.line = from + pos.ch = 0 + } +} + +// Tries to rebase an array of history events given a change in the +// document. If the change touches the same lines as the event, the +// event, and everything 'behind' it, is discarded. If the change is +// before the event, the event's positions are updated. Uses a +// copy-on-write scheme for the positions, to avoid having to +// reallocate them all on every rebase, but also avoid problems with +// shared position objects being unsafely updated. +function rebaseHistArray(array, from, to, diff) { + for (let i = 0; i < array.length; ++i) { + let sub = array[i], ok = true + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true } + for (let j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff) + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff) + } + continue + } + for (let j = 0; j < sub.changes.length; ++j) { + let cur = sub.changes[j] + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch) + cur.to = Pos(cur.to.line + diff, cur.to.ch) + } else if (from <= cur.to.line) { + ok = false + break + } + } + if (!ok) { + array.splice(0, i + 1) + i = 0 + } + } +} + +function rebaseHist(hist, change) { + let from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1 + rebaseHistArray(hist.done, from, to, diff) + rebaseHistArray(hist.undone, from, to, diff) +} + +// Utility for applying a change to a line by handle or number, +// returning the number and optionally registering the line as +// changed. +export function changeLine(doc, handle, changeType, op) { + let no = handle, line = handle + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)) + else no = lineNo(handle) + if (no == null) return null + if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType) + return line +} diff --git a/backend/webif/static/codemirror/src/model/chunk.js b/backend/webif/static/codemirror/src/model/chunk.js new file mode 100755 index 000000000..d82716ded --- /dev/null +++ b/backend/webif/static/codemirror/src/model/chunk.js @@ -0,0 +1,167 @@ +import { cleanUpLine } from "../line/line_data.js" +import { indexOf } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" + +// The document is represented as a BTree consisting of leaves, with +// chunk of lines in them, and branches, with up to ten leaves or +// other branch nodes below them. The top node is always a branch +// node, and is the document object itself (meaning it has +// additional methods and properties). +// +// All nodes have parent links. The tree is used both to go from +// line numbers to line objects, and to go from objects to numbers. +// It also indexes by height, and is used to convert between height +// and line object, and to find the total height of the document. +// +// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + +export function LeafChunk(lines) { + this.lines = lines + this.parent = null + let height = 0 + for (let i = 0; i < lines.length; ++i) { + lines[i].parent = this + height += lines[i].height + } + this.height = height +} + +LeafChunk.prototype = { + chunkSize() { return this.lines.length }, + + // Remove the n lines at offset 'at'. + removeInner(at, n) { + for (let i = at, e = at + n; i < e; ++i) { + let line = this.lines[i] + this.height -= line.height + cleanUpLine(line) + signalLater(line, "delete") + } + this.lines.splice(at, n) + }, + + // Helper used to collapse a small branch into a single leaf. + collapse(lines) { + lines.push.apply(lines, this.lines) + }, + + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner(at, lines, height) { + this.height += height + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)) + for (let i = 0; i < lines.length; ++i) lines[i].parent = this + }, + + // Used to iterate over a part of the tree. + iterN(at, n, op) { + for (let e = at + n; at < e; ++at) + if (op(this.lines[at])) return true + } +} + +export function BranchChunk(children) { + this.children = children + let size = 0, height = 0 + for (let i = 0; i < children.length; ++i) { + let ch = children[i] + size += ch.chunkSize(); height += ch.height + ch.parent = this + } + this.size = size + this.height = height + this.parent = null +} + +BranchChunk.prototype = { + chunkSize() { return this.size }, + + removeInner(at, n) { + this.size -= n + for (let i = 0; i < this.children.length; ++i) { + let child = this.children[i], sz = child.chunkSize() + if (at < sz) { + let rm = Math.min(n, sz - at), oldHeight = child.height + child.removeInner(at, rm) + this.height -= oldHeight - child.height + if (sz == rm) { this.children.splice(i--, 1); child.parent = null } + if ((n -= rm) == 0) break + at = 0 + } else at -= sz + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + let lines = [] + this.collapse(lines) + this.children = [new LeafChunk(lines)] + this.children[0].parent = this + } + }, + + collapse(lines) { + for (let i = 0; i < this.children.length; ++i) this.children[i].collapse(lines) + }, + + insertInner(at, lines, height) { + this.size += lines.length + this.height += height + for (let i = 0; i < this.children.length; ++i) { + let child = this.children[i], sz = child.chunkSize() + if (at <= sz) { + child.insertInner(at, lines, height) + if (child.lines && child.lines.length > 50) { + // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. + // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. + let remaining = child.lines.length % 25 + 25 + for (let pos = remaining; pos < child.lines.length;) { + let leaf = new LeafChunk(child.lines.slice(pos, pos += 25)) + child.height -= leaf.height + this.children.splice(++i, 0, leaf) + leaf.parent = this + } + child.lines = child.lines.slice(0, remaining) + this.maybeSpill() + } + break + } + at -= sz + } + }, + + // When a node has grown, check whether it should be split. + maybeSpill() { + if (this.children.length <= 10) return + let me = this + do { + let spilled = me.children.splice(me.children.length - 5, 5) + let sibling = new BranchChunk(spilled) + if (!me.parent) { // Become the parent node + let copy = new BranchChunk(me.children) + copy.parent = me + me.children = [copy, sibling] + me = copy + } else { + me.size -= sibling.size + me.height -= sibling.height + let myIndex = indexOf(me.parent.children, me) + me.parent.children.splice(myIndex + 1, 0, sibling) + } + sibling.parent = me.parent + } while (me.children.length > 10) + me.parent.maybeSpill() + }, + + iterN(at, n, op) { + for (let i = 0; i < this.children.length; ++i) { + let child = this.children[i], sz = child.chunkSize() + if (at < sz) { + let used = Math.min(n, sz - at) + if (child.iterN(at, used, op)) return true + if ((n -= used) == 0) break + at = 0 + } else at -= sz + } + } +} diff --git a/backend/webif/static/codemirror/src/model/document_data.js b/backend/webif/static/codemirror/src/model/document_data.js new file mode 100755 index 000000000..d946e7af1 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/document_data.js @@ -0,0 +1,111 @@ +import { loadMode } from "../display/mode_state.js" +import { runInOp } from "../display/operations.js" +import { regChange } from "../display/view_tracking.js" +import { Line, updateLine } from "../line/line_data.js" +import { findMaxLine } from "../line/spans.js" +import { getLine } from "../line/utils_line.js" +import { estimateLineHeights } from "../measurement/position_measurement.js" +import { addClass, rmClass } from "../util/dom.js" +import { lst } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" + +// DOCUMENT DATA STRUCTURE + +// By default, updates that start and end at the beginning of a line +// are treated specially, in order to make the association of line +// widgets and marker elements with the text behave more intuitive. +export function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore) +} + +// Perform a change on the document data structure. +export function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight) + signalLater(line, "change", line, change) + } + function linesFor(start, end) { + let result = [] + for (let i = start; i < end; ++i) + result.push(new Line(text[i], spansFor(i), estimateHeight)) + return result + } + + let from = change.from, to = change.to, text = change.text + let firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line) + let lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)) + doc.remove(text.length, doc.size - text.length) + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + let added = linesFor(0, text.length - 1) + update(lastLine, lastLine.text, lastSpans) + if (nlines) doc.remove(from.line, nlines) + if (added.length) doc.insert(from.line, added) + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans) + } else { + let added = linesFor(1, text.length - 1) + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)) + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) + doc.insert(from.line + 1, added) + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)) + doc.remove(from.line + 1, nlines) + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans) + let added = linesFor(1, text.length - 1) + if (nlines > 1) doc.remove(from.line + 1, nlines - 1) + doc.insert(from.line + 1, added) + } + + signalLater(doc, "change", doc, change) +} + +// Call f for all linked documents. +export function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (let i = 0; i < doc.linked.length; ++i) { + let rel = doc.linked[i] + if (rel.doc == skip) continue + let shared = sharedHist && rel.sharedHist + if (sharedHistOnly && !shared) continue + f(rel.doc, shared) + propagate(rel.doc, doc, shared) + } + } + propagate(doc, null, true) +} + +// Attach a document to an editor. +export function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use.") + cm.doc = doc + doc.cm = cm + estimateLineHeights(cm) + loadMode(cm) + setDirectionClass(cm) + if (!cm.options.lineWrapping) findMaxLine(cm) + cm.options.mode = doc.modeOption + regChange(cm) +} + +function setDirectionClass(cm) { + ;(cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl") +} + +export function directionChanged(cm) { + runInOp(cm, () => { + setDirectionClass(cm) + regChange(cm) + }) +} diff --git a/backend/webif/static/codemirror/src/model/history.js b/backend/webif/static/codemirror/src/model/history.js new file mode 100755 index 000000000..753a89da9 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/history.js @@ -0,0 +1,228 @@ +import { cmp, copyPos } from "../line/pos.js" +import { stretchSpansOverChange } from "../line/spans.js" +import { getBetween } from "../line/utils_line.js" +import { signal } from "../util/event.js" +import { indexOf, lst } from "../util/misc.js" + +import { changeEnd } from "./change_measurement.js" +import { linkedDocs } from "./document_data.js" +import { Selection } from "./selection.js" + +export function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = [] + this.undoDepth = Infinity + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0 + this.lastOp = this.lastSelOp = null + this.lastOrigin = this.lastSelOrigin = null + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1 +} + +// Create a history change event from an updateDoc-style change +// object. +export function historyChangeFromChange(doc, change) { + let histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)} + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1) + linkedDocs(doc, doc => attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1), true) + return histChange +} + +// Pop all selection events off the end of a history array. Stop at +// a change event. +function clearSelectionEvents(array) { + while (array.length) { + let last = lst(array) + if (last.ranges) array.pop() + else break + } +} + +// Find the top change event in the history. Pop off selection +// events that are in the way. +function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done) + return lst(hist.done) + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done) + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop() + return lst(hist.done) + } +} + +// Register a change in the history. Merges changes that are within +// a single operation, or are close together with an origin that +// allows merging (starting with "+") into a single event. +export function addChangeToHistory(doc, change, selAfter, opId) { + let hist = doc.history + hist.undone.length = 0 + let time = +new Date, cur + let last + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + last = lst(cur.changes) + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change) + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)) + } + } else { + // Can not be merged, start a new event. + let before = lst(hist.done) + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done) + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation} + hist.done.push(cur) + while (hist.done.length > hist.undoDepth) { + hist.done.shift() + if (!hist.done[0].ranges) hist.done.shift() + } + } + hist.done.push(selAfter) + hist.generation = ++hist.maxGeneration + hist.lastModTime = hist.lastSelTime = time + hist.lastOp = hist.lastSelOp = opId + hist.lastOrigin = hist.lastSelOrigin = change.origin + + if (!last) signal(doc, "historyAdded") +} + +function selectionEventCanBeMerged(doc, origin, prev, sel) { + let ch = origin.charAt(0) + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500) +} + +// Called whenever the selection changes, sets the new selection as +// the pending selection in the history, and pushes the old pending +// selection into the 'done' array when it was significantly +// different (in number of selected ranges, emptiness, or time). +export function addSelectionToHistory(doc, sel, opId, options) { + let hist = doc.history, origin = options && options.origin + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel + else + pushSelectionToHistory(sel, hist.done) + + hist.lastSelTime = +new Date + hist.lastSelOrigin = origin + hist.lastSelOp = opId + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone) +} + +export function pushSelectionToHistory(sel, dest) { + let top = lst(dest) + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel) +} + +// Used to store marked span information in the history. +function attachLocalSpans(doc, change, from, to) { + let existing = change["spans_" + doc.id], n = 0 + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), line => { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans + ++n + }) +} + +// When un/re-doing restores text containing marked spans, those +// that have been explicitly cleared should not be restored. +function removeClearedSpans(spans) { + if (!spans) return null + let out + for (let i = 0; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i) } + else if (out) out.push(spans[i]) + } + return !out ? spans : out.length ? out : null +} + +// Retrieve and filter the old marked spans stored in a change event. +function getOldSpans(doc, change) { + let found = change["spans_" + doc.id] + if (!found) return null + let nw = [] + for (let i = 0; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])) + return nw +} + +// Used for un/re-doing changes from the history. Combines the +// result of computing the existing spans with the set of spans that +// existed in the history (so that deleting around a span and then +// undoing brings back the span). +export function mergeOldSpans(doc, change) { + let old = getOldSpans(doc, change) + let stretched = stretchSpansOverChange(doc, change) + if (!old) return stretched + if (!stretched) return old + + for (let i = 0; i < old.length; ++i) { + let oldCur = old[i], stretchCur = stretched[i] + if (oldCur && stretchCur) { + spans: for (let j = 0; j < stretchCur.length; ++j) { + let span = stretchCur[j] + for (let k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans + oldCur.push(span) + } + } else if (stretchCur) { + old[i] = stretchCur + } + } + return old +} + +// Used both to provide a JSON-safe object in .getHistory, and, when +// detaching a document, to split the history in two +export function copyHistoryArray(events, newGroup, instantiateSel) { + let copy = [] + for (let i = 0; i < events.length; ++i) { + let event = events[i] + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event) + continue + } + let changes = event.changes, newChanges = [] + copy.push({changes: newChanges}) + for (let j = 0; j < changes.length; ++j) { + let change = changes[j], m + newChanges.push({from: change.from, to: change.to, text: change.text}) + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop] + delete change[prop] + } + } + } + } + return copy +} diff --git a/backend/webif/static/codemirror/src/model/line_widget.js b/backend/webif/static/codemirror/src/model/line_widget.js new file mode 100755 index 000000000..4a82d5389 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/line_widget.js @@ -0,0 +1,78 @@ +import { runInOp } from "../display/operations.js" +import { addToScrollTop } from "../display/scrolling.js" +import { regLineChange } from "../display/view_tracking.js" +import { heightAtLine, lineIsHidden } from "../line/spans.js" +import { lineNo, updateLineHeight } from "../line/utils_line.js" +import { widgetHeight } from "../measurement/widgets.js" +import { changeLine } from "./changes.js" +import { eventMixin } from "../util/event.js" +import { signalLater } from "../util/operation_group.js" + +// Line widgets are block elements displayed above or below a line. + +export class LineWidget { + constructor(doc, node, options) { + if (options) for (let opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt] + this.doc = doc + this.node = node + } + + clear() { + let cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line) + if (no == null || !ws) return + for (let i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1) + if (!ws.length) line.widgets = null + let height = widgetHeight(this) + updateLineHeight(line, Math.max(0, line.height - height)) + if (cm) { + runInOp(cm, () => { + adjustScrollWhenAboveVisible(cm, line, -height) + regLineChange(cm, no, "widget") + }) + signalLater(cm, "lineWidgetCleared", cm, this, no) + } + } + + changed() { + let oldH = this.height, cm = this.doc.cm, line = this.line + this.height = null + let diff = widgetHeight(this) - oldH + if (!diff) return + updateLineHeight(line, line.height + diff) + if (cm) { + runInOp(cm, () => { + cm.curOp.forceUpdate = true + adjustScrollWhenAboveVisible(cm, line, diff) + signalLater(cm, "lineWidgetChanged", cm, this, lineNo(line)) + }) + } + } +} +eventMixin(LineWidget) + +function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollTop(cm, diff) +} + +export function addLineWidget(doc, handle, node, options) { + let widget = new LineWidget(doc, node, options) + let cm = doc.cm + if (cm && widget.noHScroll) cm.display.alignWidgets = true + changeLine(doc, handle, "widget", line => { + let widgets = line.widgets || (line.widgets = []) + if (widget.insertAt == null) widgets.push(widget) + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget) + widget.line = line + if (cm && !lineIsHidden(doc, line)) { + let aboveVisible = heightAtLine(line) < doc.scrollTop + updateLineHeight(line, line.height + widgetHeight(widget)) + if (aboveVisible) addToScrollTop(cm, widget.height) + cm.curOp.forceUpdate = true + } + return true + }) + signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)) + return widget +} diff --git a/backend/webif/static/codemirror/src/model/mark_text.js b/backend/webif/static/codemirror/src/model/mark_text.js new file mode 100755 index 000000000..955c72c4a --- /dev/null +++ b/backend/webif/static/codemirror/src/model/mark_text.js @@ -0,0 +1,292 @@ +import { eltP } from "../util/dom.js" +import { eventMixin, hasHandler, on } from "../util/event.js" +import { endOperation, operation, runInOp, startOperation } from "../display/operations.js" +import { clipPos, cmp, Pos } from "../line/pos.js" +import { lineNo, updateLineHeight } from "../line/utils_line.js" +import { clearLineMeasurementCacheFor, findViewForLine, textHeight } from "../measurement/position_measurement.js" +import { seeReadOnlySpans, seeCollapsedSpans } from "../line/saw_special_spans.js" +import { addMarkedSpan, conflictingCollapsedRange, getMarkedSpanFor, lineIsHidden, lineLength, MarkedSpan, removeMarkedSpan, visualLine } from "../line/spans.js" +import { copyObj, indexOf, lst } from "../util/misc.js" +import { signalLater } from "../util/operation_group.js" +import { widgetHeight } from "../measurement/widgets.js" +import { regChange, regLineChange } from "../display/view_tracking.js" + +import { linkedDocs } from "./document_data.js" +import { addChangeToHistory } from "./history.js" +import { reCheckSelection } from "./selection_updates.js" + +// TEXTMARKERS + +// Created with markText and setBookmark methods. A TextMarker is a +// handle that can be used to clear or find a marked position in the +// document. Line objects hold arrays (markedSpans) containing +// {from, to, marker} object pointing to such marker objects, and +// indicating that such a marker is present on that line. Multiple +// lines may point to the same marker when it spans across lines. +// The spans will have null for their from/to properties when the +// marker continues beyond the start/end of the line. Markers have +// links back to the lines they currently touch. + +// Collapsed markers have unique ids, in order to be able to order +// them, which is needed for uniquely determining an outer marker +// when they overlap (they may nest, but not partially overlap). +let nextMarkerId = 0 + +export class TextMarker { + constructor(doc, type) { + this.lines = [] + this.type = type + this.doc = doc + this.id = ++nextMarkerId + } + + // Clear the marker. + clear() { + if (this.explicitlyCleared) return + let cm = this.doc.cm, withOp = cm && !cm.curOp + if (withOp) startOperation(cm) + if (hasHandler(this, "clear")) { + let found = this.find() + if (found) signalLater(this, "clear", found.from, found.to) + } + let min = null, max = null + for (let i = 0; i < this.lines.length; ++i) { + let line = this.lines[i] + let span = getMarkedSpanFor(line.markedSpans, this) + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text") + else if (cm) { + if (span.to != null) max = lineNo(line) + if (span.from != null) min = lineNo(line) + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span) + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)) + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (let i = 0; i < this.lines.length; ++i) { + let visual = visualLine(this.lines[i]), len = lineLength(visual) + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual + cm.display.maxLineLength = len + cm.display.maxLineChanged = true + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1) + this.lines.length = 0 + this.explicitlyCleared = true + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false + if (cm) reCheckSelection(cm.doc) + } + if (cm) signalLater(cm, "markerCleared", cm, this, min, max) + if (withOp) endOperation(cm) + if (this.parent) this.parent.clear() + } + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + find(side, lineObj) { + if (side == null && this.type == "bookmark") side = 1 + let from, to + for (let i = 0; i < this.lines.length; ++i) { + let line = this.lines[i] + let span = getMarkedSpanFor(line.markedSpans, this) + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from) + if (side == -1) return from + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to) + if (side == 1) return to + } + } + return from && {from: from, to: to} + } + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + changed() { + let pos = this.find(-1, true), widget = this, cm = this.doc.cm + if (!pos || !cm) return + runInOp(cm, () => { + let line = pos.line, lineN = lineNo(pos.line) + let view = findViewForLine(cm, lineN) + if (view) { + clearLineMeasurementCacheFor(view) + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true + } + cm.curOp.updateMaxLine = true + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + let oldHeight = widget.height + widget.height = null + let dHeight = widgetHeight(widget) - oldHeight + if (dHeight) + updateLineHeight(line, line.height + dHeight) + } + signalLater(cm, "markerChanged", cm, this) + }) + } + + attachLine(line) { + if (!this.lines.length && this.doc.cm) { + let op = this.doc.cm.curOp + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this) + } + this.lines.push(line) + } + + detachLine(line) { + this.lines.splice(indexOf(this.lines, line), 1) + if (!this.lines.length && this.doc.cm) { + let op = this.doc.cm.curOp + ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this) + } + } +} +eventMixin(TextMarker) + +// Create a marker, wire it up to the right lines, and +export function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type) + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type) + + let marker = new TextMarker(doc, type), diff = cmp(from, to) + if (options) copyObj(options, marker, false) + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true + marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget") + if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true") + if (options.insertLeft) marker.widgetNode.insertLeft = true + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one") + seeCollapsedSpans() + } + + if (marker.addToHistory) + addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN) + + let curLine = from.line, cm = doc.cm, updateMaxLine + doc.iter(curLine, to.line + 1, line => { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0) + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)) + ++curLine + }) + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, line => { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0) + }) + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", () => marker.clear()) + + if (marker.readOnly) { + seeReadOnlySpans() + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory() + } + if (marker.collapsed) { + marker.id = ++nextMarkerId + marker.atomic = true + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true + if (marker.collapsed) + regChange(cm, from.line, to.line + 1) + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + for (let i = from.line; i <= to.line; i++) regLineChange(cm, i, "text") + if (marker.atomic) reCheckSelection(cm.doc) + signalLater(cm, "markerAdded", cm, marker) + } + return marker +} + +// SHARED TEXTMARKERS + +// A shared marker spans multiple linked documents. It is +// implemented as a meta-marker-object controlling multiple normal +// markers. +export class SharedTextMarker { + constructor(markers, primary) { + this.markers = markers + this.primary = primary + for (let i = 0; i < markers.length; ++i) + markers[i].parent = this + } + + clear() { + if (this.explicitlyCleared) return + this.explicitlyCleared = true + for (let i = 0; i < this.markers.length; ++i) + this.markers[i].clear() + signalLater(this, "clear") + } + + find(side, lineObj) { + return this.primary.find(side, lineObj) + } +} +eventMixin(SharedTextMarker) + +function markTextShared(doc, from, to, options, type) { + options = copyObj(options) + options.shared = false + let markers = [markText(doc, from, to, options, type)], primary = markers[0] + let widget = options.widgetNode + linkedDocs(doc, doc => { + if (widget) options.widgetNode = widget.cloneNode(true) + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)) + for (let i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return + primary = lst(markers) + }) + return new SharedTextMarker(markers, primary) +} + +export function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), m => m.parent) +} + +export function copySharedMarkers(doc, markers) { + for (let i = 0; i < markers.length; i++) { + let marker = markers[i], pos = marker.find() + let mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to) + if (cmp(mFrom, mTo)) { + let subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type) + marker.markers.push(subMark) + subMark.parent = marker + } + } +} + +export function detachSharedMarkers(markers) { + for (let i = 0; i < markers.length; i++) { + let marker = markers[i], linked = [marker.primary.doc] + linkedDocs(marker.primary.doc, d => linked.push(d)) + for (let j = 0; j < marker.markers.length; j++) { + let subMarker = marker.markers[j] + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null + marker.markers.splice(j--, 1) + } + } + } +} diff --git a/backend/webif/static/codemirror/src/model/selection.js b/backend/webif/static/codemirror/src/model/selection.js new file mode 100755 index 000000000..2e374aa82 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/selection.js @@ -0,0 +1,82 @@ +import { cmp, copyPos, equalCursorPos, maxPos, minPos } from "../line/pos.js" +import { indexOf } from "../util/misc.js" + +// Selection objects are immutable. A new one is created every time +// the selection changes. A selection is one or more non-overlapping +// (and non-touching) ranges, sorted, and an integer that indicates +// which one is the primary selection (the one that's scrolled into +// view, that getCursor returns, etc). +export class Selection { + constructor(ranges, primIndex) { + this.ranges = ranges + this.primIndex = primIndex + } + + primary() { return this.ranges[this.primIndex] } + + equals(other) { + if (other == this) return true + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false + for (let i = 0; i < this.ranges.length; i++) { + let here = this.ranges[i], there = other.ranges[i] + if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) return false + } + return true + } + + deepCopy() { + let out = [] + for (let i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)) + return new Selection(out, this.primIndex) + } + + somethingSelected() { + for (let i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true + return false + } + + contains(pos, end) { + if (!end) end = pos + for (let i = 0; i < this.ranges.length; i++) { + let range = this.ranges[i] + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i + } + return -1 + } +} + +export class Range { + constructor(anchor, head) { + this.anchor = anchor; this.head = head + } + + from() { return minPos(this.anchor, this.head) } + to() { return maxPos(this.anchor, this.head) } + empty() { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch } +} + +// Take an unsorted, potentially overlapping set of ranges, and +// build a selection out of it. 'Consumes' ranges array (modifying +// it). +export function normalizeSelection(ranges, primIndex) { + let prim = ranges[primIndex] + ranges.sort((a, b) => cmp(a.from(), b.from())) + primIndex = indexOf(ranges, prim) + for (let i = 1; i < ranges.length; i++) { + let cur = ranges[i], prev = ranges[i - 1] + if (cmp(prev.to(), cur.from()) >= 0) { + let from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()) + let inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head + if (i <= primIndex) --primIndex + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)) + } + } + return new Selection(ranges, primIndex) +} + +export function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0) +} diff --git a/backend/webif/static/codemirror/src/model/selection_updates.js b/backend/webif/static/codemirror/src/model/selection_updates.js new file mode 100755 index 000000000..77986a9e9 --- /dev/null +++ b/backend/webif/static/codemirror/src/model/selection_updates.js @@ -0,0 +1,208 @@ +import { signalLater } from "../util/operation_group.js" +import { ensureCursorVisible } from "../display/scrolling.js" +import { clipPos, cmp, Pos } from "../line/pos.js" +import { getLine } from "../line/utils_line.js" +import { hasHandler, signal, signalCursorActivity } from "../util/event.js" +import { lst, sel_dontScroll } from "../util/misc.js" + +import { addSelectionToHistory } from "./history.js" +import { normalizeSelection, Range, Selection, simpleSelection } from "./selection.js" + +// The 'scroll' parameter given to many of these indicated whether +// the new cursor position should be scrolled into view after +// modifying the selection. + +// If shift is held or the extend flag is set, extends a range to +// include a given position (and optionally a second position). +// Otherwise, simply returns the range between the given positions. +// Used for cursor motion and such. +export function extendRange(range, head, other, extend) { + if (extend) { + let anchor = range.anchor + if (other) { + let posBefore = cmp(head, anchor) < 0 + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head + head = other + } else if (posBefore != (cmp(head, other) < 0)) { + head = other + } + } + return new Range(anchor, head) + } else { + return new Range(other || head, head) + } +} + +// Extend the primary selection range, discard the rest. +export function extendSelection(doc, head, other, options, extend) { + if (extend == null) extend = doc.cm && (doc.cm.display.shift || doc.extend) + setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options) +} + +// Extend all selections (pos is an array of selections with length +// equal the number of selections) +export function extendSelections(doc, heads, options) { + let out = [] + let extend = doc.cm && (doc.cm.display.shift || doc.extend) + for (let i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend) + let newSel = normalizeSelection(out, doc.sel.primIndex) + setSelection(doc, newSel, options) +} + +// Updates a single range in the selection. +export function replaceOneSelection(doc, i, range, options) { + let ranges = doc.sel.ranges.slice(0) + ranges[i] = range + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options) +} + +// Reset the selection to a single range. +export function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options) +} + +// Give beforeSelectionChange handlers a change to influence a +// selection update. +function filterSelectionChange(doc, sel, options) { + let obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = [] + for (let i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)) + }, + origin: options && options.origin + } + signal(doc, "beforeSelectionChange", doc, obj) + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj) + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1) + else return sel +} + +export function setSelectionReplaceHistory(doc, sel, options) { + let done = doc.history.done, last = lst(done) + if (last && last.ranges) { + done[done.length - 1] = sel + setSelectionNoUndo(doc, sel, options) + } else { + setSelection(doc, sel, options) + } +} + +// Set a new selection. +export function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options) + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options) +} + +export function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel, options) + + let bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1) + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)) + + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm) +} + +function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return + + doc.sel = sel + + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true + signalCursorActivity(doc.cm) + } + signalLater(doc, "cursorActivity", doc) +} + +// Verify that the selection does not partially select any atomic +// marked ranges. +export function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false)) +} + +// Return a selection that does not partially select any atomic +// ranges. +function skipAtomicInSelection(doc, sel, bias, mayClear) { + let out + for (let i = 0; i < sel.ranges.length; i++) { + let range = sel.ranges[i] + let old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i] + let newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear) + let newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear) + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i) + out[i] = new Range(newAnchor, newHead) + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel +} + +function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { + let line = getLine(doc, pos.line) + if (line.markedSpans) for (let i = 0; i < line.markedSpans.length; ++i) { + let sp = line.markedSpans[i], m = sp.marker + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter") + if (m.explicitlyCleared) { + if (!line.markedSpans) break + else {--i; continue} + } + } + if (!m.atomic) continue + + if (oldPos) { + let near = m.find(dir < 0 ? 1 : -1), diff + if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) + near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null) + if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) + return skipAtomicInner(doc, near, pos, dir, mayClear) + } + + let far = m.find(dir < 0 ? -1 : 1) + if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) + far = movePos(doc, far, dir, far.line == pos.line ? line : null) + return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null + } + } + return pos +} + +// Ensure a given position is not inside an atomic range. +export function skipAtomic(doc, pos, oldPos, bias, mayClear) { + let dir = bias || 1 + let found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || + skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)) + if (!found) { + doc.cantEdit = true + return Pos(doc.first, 0) + } + return found +} + +function movePos(doc, pos, dir, line) { + if (dir < 0 && pos.ch == 0) { + if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1)) + else return null + } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { + if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0) + else return null + } else { + return new Pos(pos.line, pos.ch + dir) + } +} + +export function selectAll(cm) { + cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll) +} diff --git a/backend/webif/static/codemirror/src/modes.js b/backend/webif/static/codemirror/src/modes.js new file mode 100755 index 000000000..838451702 --- /dev/null +++ b/backend/webif/static/codemirror/src/modes.js @@ -0,0 +1,96 @@ +import { copyObj, createObj } from "./util/misc.js" + +// Known modes, by name and by MIME +export let modes = {}, mimeModes = {} + +// Extra arguments are stored as the mode's dependencies, which is +// used by (legacy) mechanisms like loadmode.js to automatically +// load a mode. (Preferred mechanism is the require/define calls.) +export function defineMode(name, mode) { + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2) + modes[name] = mode +} + +export function defineMIME(mime, spec) { + mimeModes[mime] = spec +} + +// Given a MIME type, a {name, ...options} config object, or a name +// string, return a mode config object. +export function resolveMode(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec] + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + let found = mimeModes[spec.name] + if (typeof found == "string") found = {name: found} + spec = createObj(found, spec) + spec.name = found.name + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return resolveMode("application/xml") + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { + return resolveMode("application/json") + } + if (typeof spec == "string") return {name: spec} + else return spec || {name: "null"} +} + +// Given a mode spec (anything that resolveMode accepts), find and +// initialize an actual mode object. +export function getMode(options, spec) { + spec = resolveMode(spec) + let mfactory = modes[spec.name] + if (!mfactory) return getMode(options, "text/plain") + let modeObj = mfactory(options, spec) + if (modeExtensions.hasOwnProperty(spec.name)) { + let exts = modeExtensions[spec.name] + for (let prop in exts) { + if (!exts.hasOwnProperty(prop)) continue + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop] + modeObj[prop] = exts[prop] + } + } + modeObj.name = spec.name + if (spec.helperType) modeObj.helperType = spec.helperType + if (spec.modeProps) for (let prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop] + + return modeObj +} + +// This can be used to attach properties to mode objects from +// outside the actual mode definition. +export let modeExtensions = {} +export function extendMode(mode, properties) { + let exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}) + copyObj(properties, exts) +} + +export function copyState(mode, state) { + if (state === true) return state + if (mode.copyState) return mode.copyState(state) + let nstate = {} + for (let n in state) { + let val = state[n] + if (val instanceof Array) val = val.concat([]) + nstate[n] = val + } + return nstate +} + +// Given a mode and a state (for that mode), find the inner mode and +// state at the position that the state refers to. +export function innerMode(mode, state) { + let info + while (mode.innerMode) { + info = mode.innerMode(state) + if (!info || info.mode == mode) break + state = info.state + mode = info.mode + } + return info || {mode: mode, state: state} +} + +export function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true +} diff --git a/backend/webif/static/codemirror/src/util/StringStream.js b/backend/webif/static/codemirror/src/util/StringStream.js new file mode 100755 index 000000000..022c4bc20 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/StringStream.js @@ -0,0 +1,90 @@ +import { countColumn } from "./misc.js" + +// STRING STREAM + +// Fed to the mode parsers, provides helper functions to make +// parsers more succinct. + +class StringStream { + constructor(string, tabSize, lineOracle) { + this.pos = this.start = 0 + this.string = string + this.tabSize = tabSize || 8 + this.lastColumnPos = this.lastColumnValue = 0 + this.lineStart = 0 + this.lineOracle = lineOracle + } + + eol() {return this.pos >= this.string.length} + sol() {return this.pos == this.lineStart} + peek() {return this.string.charAt(this.pos) || undefined} + next() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++) + } + eat(match) { + let ch = this.string.charAt(this.pos) + let ok + if (typeof match == "string") ok = ch == match + else ok = ch && (match.test ? match.test(ch) : match(ch)) + if (ok) {++this.pos; return ch} + } + eatWhile(match) { + let start = this.pos + while (this.eat(match)){} + return this.pos > start + } + eatSpace() { + let start = this.pos + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos + return this.pos > start + } + skipToEnd() {this.pos = this.string.length} + skipTo(ch) { + let found = this.string.indexOf(ch, this.pos) + if (found > -1) {this.pos = found; return true} + } + backUp(n) {this.pos -= n} + column() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue) + this.lastColumnPos = this.start + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + } + indentation() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + } + match(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + let cased = str => caseInsensitive ? str.toLowerCase() : str + let substr = this.string.substr(this.pos, pattern.length) + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length + return true + } + } else { + let match = this.string.slice(this.pos).match(pattern) + if (match && match.index > 0) return null + if (match && consume !== false) this.pos += match[0].length + return match + } + } + current(){return this.string.slice(this.start, this.pos)} + hideFirstChars(n, inner) { + this.lineStart += n + try { return inner() } + finally { this.lineStart -= n } + } + lookAhead(n) { + let oracle = this.lineOracle + return oracle && oracle.lookAhead(n) + } + baseToken() { + let oracle = this.lineOracle + return oracle && oracle.baseToken(this.pos) + } +} + +export default StringStream diff --git a/backend/webif/static/codemirror/src/util/bidi.js b/backend/webif/static/codemirror/src/util/bidi.js new file mode 100755 index 000000000..33ab854d8 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/bidi.js @@ -0,0 +1,214 @@ +import { lst } from "./misc.js" + +// BIDI HELPERS + +export function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr", 0) + let found = false + for (let i = 0; i < order.length; ++i) { + let part = order[i] + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i) + found = true + } + } + if (!found) f(from, to, "ltr") +} + +export let bidiOther = null +export function getBidiPartAt(order, ch, sticky) { + let found + bidiOther = null + for (let i = 0; i < order.length; ++i) { + let cur = order[i] + if (cur.from < ch && cur.to > ch) return i + if (cur.to == ch) { + if (cur.from != cur.to && sticky == "before") found = i + else bidiOther = i + } + if (cur.from == ch) { + if (cur.from != cur.to && sticky != "before") found = i + else bidiOther = i + } + } + return found != null ? found : bidiOther +} + +// Bidirectional ordering algorithm +// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm +// that this (partially) implements. + +// One-char codes used for character types: +// L (L): Left-to-Right +// R (R): Right-to-Left +// r (AL): Right-to-Left Arabic +// 1 (EN): European Number +// + (ES): European Number Separator +// % (ET): European Number Terminator +// n (AN): Arabic Number +// , (CS): Common Number Separator +// m (NSM): Non-Spacing Mark +// b (BN): Boundary Neutral +// s (B): Paragraph Separator +// t (S): Segment Separator +// w (WS): Whitespace +// N (ON): Other Neutrals + +// Returns null if characters are ordered as they appear +// (left-to-right), or an array of sections ({from, to, level} +// objects) in the order in which they occur visually. +let bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + let lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN" + // Character types for codepoints 0x600 to 0x6f9 + let arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111" + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code) + else if (0x590 <= code && code <= 0x5f4) return "R" + else if (0x600 <= code && code <= 0x6f9) return arabicTypes.charAt(code - 0x600) + else if (0x6ee <= code && code <= 0x8ac) return "r" + else if (0x2000 <= code && code <= 0x200b) return "w" + else if (code == 0x200c) return "b" + else return "L" + } + + let bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/ + let isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/ + + function BidiSpan(level, from, to) { + this.level = level + this.from = from; this.to = to + } + + return function(str, direction) { + let outerType = direction == "ltr" ? "L" : "R" + + if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) return false + let len = str.length, types = [] + for (let i = 0; i < len; ++i) + types.push(charType(str.charCodeAt(i))) + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (let i = 0, prev = outerType; i < len; ++i) { + let type = types[i] + if (type == "m") types[i] = prev + else prev = type + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (let i = 0, cur = outerType; i < len; ++i) { + let type = types[i] + if (type == "1" && cur == "r") types[i] = "n" + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R" } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (let i = 1, prev = types[0]; i < len - 1; ++i) { + let type = types[i] + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1" + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev + prev = type + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (let i = 0; i < len; ++i) { + let type = types[i] + if (type == ",") types[i] = "N" + else if (type == "%") { + let end + for (end = i + 1; end < len && types[end] == "%"; ++end) {} + let replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N" + for (let j = i; j < end; ++j) types[j] = replace + i = end - 1 + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (let i = 0, cur = outerType; i < len; ++i) { + let type = types[i] + if (cur == "L" && type == "1") types[i] = "L" + else if (isStrong.test(type)) cur = type + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (let i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + let end + for (end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + let before = (i ? types[i-1] : outerType) == "L" + let after = (end < len ? types[end] : outerType) == "L" + let replace = before == after ? (before ? "L" : "R") : outerType + for (let j = i; j < end; ++j) types[j] = replace + i = end - 1 + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + let order = [], m + for (let i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + let start = i + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push(new BidiSpan(0, start, i)) + } else { + let pos = i, at = order.length + for (++i; i < len && types[i] != "L"; ++i) {} + for (let j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)) + let nstart = j + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, new BidiSpan(2, nstart, j)) + pos = j + } else ++j + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)) + } + } + if (direction == "ltr") { + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length + order.unshift(new BidiSpan(0, 0, m[0].length)) + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length + order.push(new BidiSpan(0, len - m[0].length, len)) + } + } + + return direction == "rtl" ? order.reverse() : order + } +})() + +// Get the bidi ordering for the given line (and cache it). Returns +// false for lines that are fully left-to-right, and an array of +// BidiSpan objects otherwise. +export function getOrder(line, direction) { + let order = line.order + if (order == null) order = line.order = bidiOrdering(line.text, direction) + return order +} diff --git a/backend/webif/static/codemirror/src/util/browser.js b/backend/webif/static/codemirror/src/util/browser.js new file mode 100755 index 000000000..9fc4602c6 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/browser.js @@ -0,0 +1,33 @@ +// Kludges for bugs and behavior differences that can't be feature +// detected are enabled based on userAgent etc sniffing. +let userAgent = navigator.userAgent +let platform = navigator.platform + +export let gecko = /gecko\/\d/i.test(userAgent) +let ie_upto10 = /MSIE \d/.test(userAgent) +let ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent) +let edge = /Edge\/(\d+)/.exec(userAgent) +export let ie = ie_upto10 || ie_11up || edge +export let ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]) +export let webkit = !edge && /WebKit\//.test(userAgent) +let qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent) +export let chrome = !edge && /Chrome\//.test(userAgent) +export let presto = /Opera\//.test(userAgent) +export let safari = /Apple Computer/.test(navigator.vendor) +export let mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent) +export let phantom = /PhantomJS/.test(userAgent) + +export let ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent) +export let android = /Android/.test(userAgent) +// This is woefully incomplete. Suggestions for alternative methods welcome. +export let mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent) +export let mac = ios || /Mac/.test(platform) +export let chromeOS = /\bCrOS\b/.test(userAgent) +export let windows = /win/i.test(platform) + +let presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/) +if (presto_version) presto_version = Number(presto_version[1]) +if (presto_version && presto_version >= 15) { presto = false; webkit = true } +// Some browsers use the wrong event properties to signal cmd/ctrl on OS X +export let flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)) +export let captureRightClick = gecko || (ie && ie_version >= 9) diff --git a/backend/webif/static/codemirror/src/util/dom.js b/backend/webif/static/codemirror/src/util/dom.js new file mode 100755 index 000000000..04d2569d2 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/dom.js @@ -0,0 +1,97 @@ +import { ie, ios } from "./browser.js" + +export function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } + +export let rmClass = function(node, cls) { + let current = node.className + let match = classTest(cls).exec(current) + if (match) { + let after = current.slice(match.index + match[0].length) + node.className = current.slice(0, match.index) + (after ? match[1] + after : "") + } +} + +export function removeChildren(e) { + for (let count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild) + return e +} + +export function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e) +} + +export function elt(tag, content, className, style) { + let e = document.createElement(tag) + if (className) e.className = className + if (style) e.style.cssText = style + if (typeof content == "string") e.appendChild(document.createTextNode(content)) + else if (content) for (let i = 0; i < content.length; ++i) e.appendChild(content[i]) + return e +} +// wrapper for elt, which removes the elt from the accessibility tree +export function eltP(tag, content, className, style) { + let e = elt(tag, content, className, style) + e.setAttribute("role", "presentation") + return e +} + +export let range +if (document.createRange) range = function(node, start, end, endNode) { + let r = document.createRange() + r.setEnd(endNode || node, end) + r.setStart(node, start) + return r +} +else range = function(node, start, end) { + let r = document.body.createTextRange() + try { r.moveToElementText(node.parentNode) } + catch(e) { return r } + r.collapse(true) + r.moveEnd("character", end) + r.moveStart("character", start) + return r +} + +export function contains(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + child = child.parentNode + if (parent.contains) + return parent.contains(child) + do { + if (child.nodeType == 11) child = child.host + if (child == parent) return true + } while (child = child.parentNode) +} + +export function activeElt() { + // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. + // IE < 10 will throw when accessed while the page is loading or in an iframe. + // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. + let activeElement + try { + activeElement = document.activeElement + } catch(e) { + activeElement = document.body || null + } + while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) + activeElement = activeElement.shadowRoot.activeElement + return activeElement +} + +export function addClass(node, cls) { + let current = node.className + if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls +} +export function joinClasses(a, b) { + let as = a.split(" ") + for (let i = 0; i < as.length; i++) + if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i] + return b +} + +export let selectInput = function(node) { node.select() } +if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } +else if (ie) // Suppress mysterious IE10 errors + selectInput = function(node) { try { node.select() } catch(_e) {} } diff --git a/backend/webif/static/codemirror/src/util/event.js b/backend/webif/static/codemirror/src/util/event.js new file mode 100755 index 000000000..4b6c77057 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/event.js @@ -0,0 +1,103 @@ +import { mac } from "./browser.js" +import { indexOf } from "./misc.js" + +// EVENT HANDLING + +// Lightweight event framework. on/off also work on DOM nodes, +// registering native DOM handlers. + +const noHandlers = [] + +export let on = function(emitter, type, f) { + if (emitter.addEventListener) { + emitter.addEventListener(type, f, false) + } else if (emitter.attachEvent) { + emitter.attachEvent("on" + type, f) + } else { + let map = emitter._handlers || (emitter._handlers = {}) + map[type] = (map[type] || noHandlers).concat(f) + } +} + +export function getHandlers(emitter, type) { + return emitter._handlers && emitter._handlers[type] || noHandlers +} + +export function off(emitter, type, f) { + if (emitter.removeEventListener) { + emitter.removeEventListener(type, f, false) + } else if (emitter.detachEvent) { + emitter.detachEvent("on" + type, f) + } else { + let map = emitter._handlers, arr = map && map[type] + if (arr) { + let index = indexOf(arr, f) + if (index > -1) + map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) + } + } +} + +export function signal(emitter, type /*, values...*/) { + let handlers = getHandlers(emitter, type) + if (!handlers.length) return + let args = Array.prototype.slice.call(arguments, 2) + for (let i = 0; i < handlers.length; ++i) handlers[i].apply(null, args) +} + +// The DOM events that CodeMirror handles can be overridden by +// registering a (non-DOM) handler on the editor for the event name, +// and preventDefault-ing the event in that handler. +export function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + e = {type: e, preventDefault: function() { this.defaultPrevented = true }} + signal(cm, override || e.type, cm, e) + return e_defaultPrevented(e) || e.codemirrorIgnore +} + +export function signalCursorActivity(cm) { + let arr = cm._handlers && cm._handlers.cursorActivity + if (!arr) return + let set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []) + for (let i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) + set.push(arr[i]) +} + +export function hasHandler(emitter, type) { + return getHandlers(emitter, type).length > 0 +} + +// Add on and off methods to a constructor's prototype, to make +// registering events on such objects more convenient. +export function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f)} + ctor.prototype.off = function(type, f) {off(this, type, f)} +} + +// Due to the fact that we still support jurassic IE versions, some +// compatibility wrappers are needed. + +export function e_preventDefault(e) { + if (e.preventDefault) e.preventDefault() + else e.returnValue = false +} +export function e_stopPropagation(e) { + if (e.stopPropagation) e.stopPropagation() + else e.cancelBubble = true +} +export function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false +} +export function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)} + +export function e_target(e) {return e.target || e.srcElement} +export function e_button(e) { + let b = e.which + if (b == null) { + if (e.button & 1) b = 1 + else if (e.button & 2) b = 3 + else if (e.button & 4) b = 2 + } + if (mac && e.ctrlKey && b == 1) b = 3 + return b +} diff --git a/backend/webif/static/codemirror/src/util/feature_detection.js b/backend/webif/static/codemirror/src/util/feature_detection.js new file mode 100755 index 000000000..c33734ebb --- /dev/null +++ b/backend/webif/static/codemirror/src/util/feature_detection.js @@ -0,0 +1,84 @@ +import { elt, range, removeChildren, removeChildrenAndAdd } from "./dom.js" +import { ie, ie_version } from "./browser.js" + +// Detect drag-and-drop +export let dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) return false + let div = elt('div') + return "draggable" in div || "dragDrop" in div +}() + +let zwspSupported +export function zeroWidthElement(measure) { + if (zwspSupported == null) { + let test = elt("span", "\u200b") + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])) + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) + } + let node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px") + node.setAttribute("cm-text", "") + return node +} + +// Feature-detect IE's crummy client rect reporting for bidi text +let badBidiRects +export function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects + let txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")) + let r0 = range(txt, 0, 1).getBoundingClientRect() + let r1 = range(txt, 1, 2).getBoundingClientRect() + removeChildren(measure) + if (!r0 || r0.left == r0.right) return false // Safari returns null in some cases (#2780) + return badBidiRects = (r1.right - r0.right < 3) +} + +// See if "".split is the broken IE version, if so, provide an +// alternative way to split lines. +export let splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? string => { + let pos = 0, result = [], l = string.length + while (pos <= l) { + let nl = string.indexOf("\n", pos) + if (nl == -1) nl = string.length + let line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl) + let rt = line.indexOf("\r") + if (rt != -1) { + result.push(line.slice(0, rt)) + pos += rt + 1 + } else { + result.push(line) + pos = nl + 1 + } + } + return result +} : string => string.split(/\r\n?|\n/) + +export let hasSelection = window.getSelection ? te => { + try { return te.selectionStart != te.selectionEnd } + catch(e) { return false } +} : te => { + let range + try {range = te.ownerDocument.selection.createRange()} + catch(e) {} + if (!range || range.parentElement() != te) return false + return range.compareEndPoints("StartToEnd", range) != 0 +} + +export let hasCopyEvent = (() => { + let e = elt("div") + if ("oncopy" in e) return true + e.setAttribute("oncopy", "return;") + return typeof e.oncopy == "function" +})() + +let badZoomedRects = null +export function hasBadZoomedRects(measure) { + if (badZoomedRects != null) return badZoomedRects + let node = removeChildrenAndAdd(measure, elt("span", "x")) + let normal = node.getBoundingClientRect() + let fromRange = range(node, 0, 1).getBoundingClientRect() + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 +} diff --git a/backend/webif/static/codemirror/src/util/misc.js b/backend/webif/static/codemirror/src/util/misc.js new file mode 100755 index 000000000..39661eb44 --- /dev/null +++ b/backend/webif/static/codemirror/src/util/misc.js @@ -0,0 +1,150 @@ +export function bind(f) { + let args = Array.prototype.slice.call(arguments, 1) + return function(){return f.apply(null, args)} +} + +export function copyObj(obj, target, overwrite) { + if (!target) target = {} + for (let prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop] + return target +} + +// Counts the column offset in a string, taking tabs into account. +// Used mostly to find indentation. +export function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/) + if (end == -1) end = string.length + } + for (let i = startIndex || 0, n = startValue || 0;;) { + let nextTab = string.indexOf("\t", i) + if (nextTab < 0 || nextTab >= end) + return n + (end - i) + n += nextTab - i + n += tabSize - (n % tabSize) + i = nextTab + 1 + } +} + +export class Delayed { + constructor() {this.id = null} + set(ms, f) { + clearTimeout(this.id) + this.id = setTimeout(f, ms) + } +} + +export function indexOf(array, elt) { + for (let i = 0; i < array.length; ++i) + if (array[i] == elt) return i + return -1 +} + +// Number of pixels added to scroller and sizer to hide scrollbar +export let scrollerGap = 30 + +// Returned or thrown by various protocols to signal 'I'm not +// handling this'. +export let Pass = {toString: function(){return "CodeMirror.Pass"}} + +// Reused option objects for setSelection & friends +export let sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"} + +// The inverse of countColumn -- find the offset that corresponds to +// a particular column. +export function findColumn(string, goal, tabSize) { + for (let pos = 0, col = 0;;) { + let nextTab = string.indexOf("\t", pos) + if (nextTab == -1) nextTab = string.length + let skipped = nextTab - pos + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col) + col += nextTab - pos + col += tabSize - (col % tabSize) + pos = nextTab + 1 + if (col >= goal) return pos + } +} + +let spaceStrs = [""] +export function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " ") + return spaceStrs[n] +} + +export function lst(arr) { return arr[arr.length-1] } + +export function map(array, f) { + let out = [] + for (let i = 0; i < array.length; i++) out[i] = f(array[i], i) + return out +} + +export function insertSorted(array, value, score) { + let pos = 0, priority = score(value) + while (pos < array.length && score(array[pos]) <= priority) pos++ + array.splice(pos, 0, value) +} + +function nothing() {} + +export function createObj(base, props) { + let inst + if (Object.create) { + inst = Object.create(base) + } else { + nothing.prototype = base + inst = new nothing() + } + if (props) copyObj(props, inst) + return inst +} + +let nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/ +export function isWordCharBasic(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)) +} +export function isWordChar(ch, helper) { + if (!helper) return isWordCharBasic(ch) + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true + return helper.test(ch) +} + +export function isEmpty(obj) { + for (let n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false + return true +} + +// Extending unicode characters. A series of a non-extending char + +// any number of extending chars is treated as a single unit as far +// as editing and measuring is concerned. This is not fully correct, +// since some scripts/fonts/browsers also treat other configurations +// of code points as a group. +let extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/ +export function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } + +// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. +export function skipExtendingChars(str, pos, dir) { + while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) pos += dir + return pos +} + +// Returns the value from the range [`from`; `to`] that satisfies +// `pred` and is closest to `from`. Assumes that at least `to` +// satisfies `pred`. Supports `from` being greater than `to`. +export function findFirst(pred, from, to) { + // At any point we are certain `to` satisfies `pred`, don't know + // whether `from` does. + let dir = from > to ? -1 : 1 + for (;;) { + if (from == to) return from + let midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF) + if (mid == from) return pred(mid) ? from : to + if (pred(mid)) to = mid + else from = mid + dir + } +} diff --git a/backend/webif/static/codemirror/src/util/operation_group.js b/backend/webif/static/codemirror/src/util/operation_group.js new file mode 100755 index 000000000..f6815949d --- /dev/null +++ b/backend/webif/static/codemirror/src/util/operation_group.js @@ -0,0 +1,72 @@ +import { getHandlers } from "./event.js" + +let operationGroup = null + +export function pushOperation(op) { + if (operationGroup) { + operationGroup.ops.push(op) + } else { + op.ownsGroup = operationGroup = { + ops: [op], + delayedCallbacks: [] + } + } +} + +function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + let callbacks = group.delayedCallbacks, i = 0 + do { + for (; i < callbacks.length; i++) + callbacks[i].call(null) + for (let j = 0; j < group.ops.length; j++) { + let op = group.ops[j] + if (op.cursorActivityHandlers) + while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) + } + } while (i < callbacks.length) +} + +export function finishOperation(op, endCb) { + let group = op.ownsGroup + if (!group) return + + try { fireCallbacksForOps(group) } + finally { + operationGroup = null + endCb(group) + } +} + +let orphanDelayedCallbacks = null + +// Often, we want to signal events at a point where we are in the +// middle of some work, but don't want the handler to start calling +// other methods on the editor, which might be in an inconsistent +// state or simply not expect any other events to happen. +// signalLater looks whether there are any handlers, and schedules +// them to be executed when the last operation ends, or, if no +// operation is active, when a timeout fires. +export function signalLater(emitter, type /*, values...*/) { + let arr = getHandlers(emitter, type) + if (!arr.length) return + let args = Array.prototype.slice.call(arguments, 2), list + if (operationGroup) { + list = operationGroup.delayedCallbacks + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks + } else { + list = orphanDelayedCallbacks = [] + setTimeout(fireOrphanDelayed, 0) + } + for (let i = 0; i < arr.length; ++i) + list.push(() => arr[i].apply(null, args)) +} + +function fireOrphanDelayed() { + let delayed = orphanDelayedCallbacks + orphanDelayedCallbacks = null + for (let i = 0; i < delayed.length; ++i) delayed[i]() +} diff --git a/backend/webif/static/codemirror/test/comment_test.js b/backend/webif/static/codemirror/test/comment_test.js new file mode 100755 index 000000000..c6b9fe810 --- /dev/null +++ b/backend/webif/static/codemirror/test/comment_test.js @@ -0,0 +1,114 @@ +namespace = "comment_"; + +(function() { + function test(name, mode, run, before, after) { + return testCM(name, function(cm) { + run(cm); + eq(cm.getValue(), after); + }, {value: before, mode: mode}); + } + + var simpleProg = "function foo() {\n return bar;\n}"; + var inlineBlock = "foo(/* bar */ true);"; + var inlineBlocks = "foo(/* bar */ true, /* baz */ false);"; + var multiLineInlineBlock = ["above();", "foo(/* bar */ true);", "below();"]; + + test("block", "javascript", function(cm) { + cm.blockComment(Pos(0, 3), Pos(3, 0), {blockCommentLead: " *"}); + }, simpleProg + "\n", "/* function foo() {\n * return bar;\n * }\n */"); + + test("blockToggle", "javascript", function(cm) { + cm.blockComment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"}); + cm.uncomment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"}); + }, simpleProg, simpleProg); + + test("blockToggle2", "javascript", function(cm) { + cm.setCursor({line: 0, ch: 7 /* inside the block comment */}); + cm.execCommand("toggleComment"); + }, inlineBlock, "foo(bar true);"); + + // This test should work but currently fails. + // test("blockToggle3", "javascript", function(cm) { + // cm.setCursor({line: 0, ch: 7 /* inside the first block comment */}); + // cm.execCommand("toggleComment"); + // }, inlineBlocks, "foo(bar true, /* baz */ false);"); + + test("line", "javascript", function(cm) { + cm.lineComment(Pos(1, 1), Pos(1, 1)); + }, simpleProg, "function foo() {\n// return bar;\n}"); + + test("lineToggle", "javascript", function(cm) { + cm.lineComment(Pos(0, 0), Pos(2, 1)); + cm.uncomment(Pos(0, 0), Pos(2, 1)); + }, simpleProg, simpleProg); + + test("fallbackToBlock", "css", function(cm) { + cm.lineComment(Pos(0, 0), Pos(2, 1)); + }, "html {\n border: none;\n}", "/* html {\n border: none;\n} */"); + + test("fallbackToLine", "ruby", function(cm) { + cm.blockComment(Pos(0, 0), Pos(1)); + }, "def blah()\n return hah\n", "# def blah()\n# return hah\n"); + + test("ignoreExternalBlockComments", "javascript", function(cm) { + cm.execCommand("toggleComment"); + }, inlineBlocks, "// " + inlineBlocks); + + test("ignoreExternalBlockComments2", "javascript", function(cm) { + cm.setCursor({line: 0, ch: null /* eol */}); + cm.execCommand("toggleComment"); + }, inlineBlocks, "// " + inlineBlocks); + + test("ignoreExternalBlockCommentsMultiLineAbove", "javascript", function(cm) { + cm.setSelection({line: 0, ch: 0}, {line: 1, ch: 1}); + cm.execCommand("toggleComment"); + }, multiLineInlineBlock.join("\n"), ["// " + multiLineInlineBlock[0], + "// " + multiLineInlineBlock[1], + multiLineInlineBlock[2]].join("\n")); + + test("ignoreExternalBlockCommentsMultiLineBelow", "javascript", function(cm) { + cm.setSelection({line: 1, ch: 13 /* after end of block comment */}, {line: 2, ch: 1}); + cm.execCommand("toggleComment"); + }, multiLineInlineBlock.join("\n"), [multiLineInlineBlock[0], + "// " + multiLineInlineBlock[1], + "// " + multiLineInlineBlock[2]].join("\n")); + + test("commentRange", "javascript", function(cm) { + cm.blockComment(Pos(1, 2), Pos(1, 13), {fullLines: false}); + }, simpleProg, "function foo() {\n /*return bar;*/\n}"); + + test("indented", "javascript", function(cm) { + cm.lineComment(Pos(1, 0), Pos(2), {indent: true}); + }, simpleProg, "function foo() {\n// return bar;\n// }"); + + test("singleEmptyLine", "javascript", function(cm) { + cm.setCursor(1); + cm.execCommand("toggleComment"); + }, "a;\n\nb;", "a;\n// \nb;"); + + test("dontMessWithStrings", "javascript", function(cm) { + cm.execCommand("toggleComment"); + }, "console.log(\"/*string*/\");", "// console.log(\"/*string*/\");"); + + test("dontMessWithStrings2", "javascript", function(cm) { + cm.execCommand("toggleComment"); + }, "console.log(\"// string\");", "// console.log(\"// string\");"); + + test("dontMessWithStrings3", "javascript", function(cm) { + cm.execCommand("toggleComment"); + }, "// console.log(\"// string\");", "console.log(\"// string\");"); + + test("includeLastLine", "javascript", function(cm) { + cm.execCommand("selectAll") + cm.execCommand("toggleComment") + }, "// foo\n// bar\nbaz", "// // foo\n// // bar\n// baz") + + test("uncommentWithTrailingBlockEnd", "xml", function(cm) { + cm.execCommand("toggleComment") + }, " -->", "foo -->") + + test("dontCommentInComment", "xml", function(cm) { + cm.setCursor(1, 0) + cm.execCommand("toggleComment") + }, "", "") +})(); diff --git a/backend/webif/static/codemirror/test/contenteditable_test.js b/backend/webif/static/codemirror/test/contenteditable_test.js new file mode 100755 index 000000000..9130fa496 --- /dev/null +++ b/backend/webif/static/codemirror/test/contenteditable_test.js @@ -0,0 +1,110 @@ +(function() { + "use strict"; + + namespace = "contenteditable_"; + var Pos = CodeMirror.Pos + + function findTextNode(dom, text) { + if (dom instanceof CodeMirror) dom = dom.getInputField() + if (dom.nodeType == 1) { + for (var ch = dom.firstChild; ch; ch = ch.nextSibling) { + var found = findTextNode(ch, text) + if (found) return found + } + } else if (dom.nodeType == 3 && dom.nodeValue == text) { + return dom + } + } + + function lineElt(node) { + for (;;) { + var parent = node.parentNode + if (/CodeMirror-code/.test(parent.className)) return node + node = parent + } + } + + testCM("insert_text", function(cm) { + findTextNode(cm, "foobar").nodeValue = "foo bar" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "foo bar") + }, {inputStyle: "contenteditable", value: "foobar"}) + + testCM("split_line", function(cm) { + cm.setSelection(Pos(2, 3)) + var node = findTextNode(cm, "foobar") + node.nodeValue = "foo" + var lineNode = lineElt(node) + lineNode.parentNode.insertBefore(document.createElement("pre"), lineNode.nextSibling).textContent = "bar" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "one\ntwo\nfoo\nbar\nthree\nfour\n") + }, {inputStyle: "contenteditable", value: "one\ntwo\nfoobar\nthree\nfour\n"}) + + testCM("join_line", function(cm) { + cm.setSelection(Pos(2, 3)) + var node = findTextNode(cm, "foo") + node.nodeValue = "foobar" + var lineNode = lineElt(node) + lineNode.parentNode.removeChild(lineNode.nextSibling) + cm.display.input.updateFromDOM() + eq(cm.getValue(), "one\ntwo\nfoobar\nthree\nfour\n") + }, {inputStyle: "contenteditable", value: "one\ntwo\nfoo\nbar\nthree\nfour\n"}) + + testCM("delete_multiple", function(cm) { + cm.setSelection(Pos(1, 3), Pos(4, 0)) + var text = findTextNode(cm, "two"), startLine = lineElt(text) + for (var i = 0; i < 3; i++) + startLine.parentNode.removeChild(startLine.nextSibling) + text.nodeValue = "twothree" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "one\ntwothree\nfour\n") + }, {inputStyle: "contenteditable", value: "one\ntwo\nfoo\nbar\nthree\nfour\n"}) + + testCM("ambiguous_diff_middle", function(cm) { + cm.setSelection(Pos(0, 2)) + findTextNode(cm, "baah").nodeValue = "baaah" + cm.display.input.updateFromDOM() + eqCharPos(cm.getCursor(), Pos(0, 3)) + }, {inputStyle: "contenteditable", value: "baah"}) + + testCM("ambiguous_diff_start", function(cm) { + cm.setSelection(Pos(0, 1)) + findTextNode(cm, "baah").nodeValue = "baaah" + cm.display.input.updateFromDOM() + eqCharPos(cm.getCursor(), Pos(0, 2)) + }, {inputStyle: "contenteditable", value: "baah"}) + + testCM("ambiguous_diff_end", function(cm) { + cm.setSelection(Pos(0, 3)) + findTextNode(cm, "baah").nodeValue = "baaah" + cm.display.input.updateFromDOM() + eqCharPos(cm.getCursor(), Pos(0, 4)) + }, {inputStyle: "contenteditable", value: "baah"}) + + testCM("force_redraw", function(cm) { + findTextNode(cm, "foo").parentNode.appendChild(document.createElement("hr")).className = "inserted" + cm.display.input.updateFromDOM() + eq(byClassName(cm.getInputField(), "inserted").length, 0) + }, {inputStyle: "contenteditable", value: "foo"}) + + testCM("type_on_empty_line", function(cm) { + cm.setSelection(Pos(1, 0)) + findTextNode(cm, "\u200b").nodeValue += "hello" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "foo\nhello\nbar") + }, {inputStyle: "contenteditable", value: "foo\n\nbar"}) + + testCM("type_after_empty_line", function(cm) { + cm.setSelection(Pos(2, 0)) + findTextNode(cm, "bar").nodeValue = "hellobar" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "foo\n\nhellobar") + }, {inputStyle: "contenteditable", value: "foo\n\nbar"}) + + testCM("type_before_empty_line", function(cm) { + cm.setSelection(Pos(0, 3)) + findTextNode(cm, "foo").nodeValue = "foohello" + cm.display.input.updateFromDOM() + eq(cm.getValue(), "foohello\n\nbar") + }, {inputStyle: "contenteditable", value: "foo\n\nbar"}) +})(); diff --git a/backend/webif/static/codemirror/test/doc_test.js b/backend/webif/static/codemirror/test/doc_test.js new file mode 100755 index 000000000..3af20ff98 --- /dev/null +++ b/backend/webif/static/codemirror/test/doc_test.js @@ -0,0 +1,371 @@ +(function() { + // A minilanguage for instantiating linked CodeMirror instances and Docs + function instantiateSpec(spec, place, opts) { + var names = {}, pos = 0, l = spec.length, editors = []; + while (spec) { + var m = spec.match(/^(\w+)(\*?)(?:='([^\']*)'|<(~?)(\w+)(?:\/(\d+)-(\d+))?)\s*/); + var name = m[1], isDoc = m[2], cur; + if (m[3]) { + cur = isDoc ? CodeMirror.Doc(m[3]) : CodeMirror(place, clone(opts, {value: m[3]})); + } else { + var other = m[5]; + if (!names.hasOwnProperty(other)) { + names[other] = editors.length; + editors.push(CodeMirror(place, opts)); + } + var doc = editors[names[other]].linkedDoc({ + sharedHist: !m[4], + from: m[6] ? Number(m[6]) : null, + to: m[7] ? Number(m[7]) : null + }); + cur = isDoc ? doc : CodeMirror(place, clone(opts, {value: doc})); + } + names[name] = editors.length; + editors.push(cur); + spec = spec.slice(m[0].length); + } + return editors; + } + + function clone(obj, props) { + if (!obj) return; + clone.prototype = obj; + var inst = new clone(); + if (props) for (var n in props) if (props.hasOwnProperty(n)) + inst[n] = props[n]; + return inst; + } + + function eqAll(val) { + var end = arguments.length, msg = null; + if (typeof arguments[end-1] == "string") + msg = arguments[--end]; + if (i == end) throw new Error("No editors provided to eqAll"); + for (var i = 1; i < end; ++i) + eq(arguments[i].getValue(), val, msg) + } + + function testDoc(name, spec, run, opts, expectFail) { + if (!opts) opts = {}; + + return test("doc_" + name, function() { + var place = document.getElementById("testground"); + var editors = instantiateSpec(spec, place, opts); + var successful = false; + + try { + run.apply(null, editors); + successful = true; + } finally { + if (!successful || verbose) { + place.style.visibility = "visible"; + } else { + for (var i = 0; i < editors.length; ++i) + if (editors[i] instanceof CodeMirror) + place.removeChild(editors[i].getWrapperElement()); + } + } + }, expectFail); + } + + var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent); + + function testBasic(a, b) { + eqAll("x", a, b); + a.setValue("hey"); + eqAll("hey", a, b); + b.setValue("wow"); + eqAll("wow", a, b); + a.replaceRange("u\nv\nw", Pos(0, 3)); + b.replaceRange("i", Pos(0, 4)); + b.replaceRange("j", Pos(2, 1)); + eqAll("wowui\nv\nwj", a, b); + } + + testDoc("basic", "A='x' B 0, "not at left"); + is(pos.top > 0, "not at top"); + }); + + testDoc("copyDoc", "A='u'", function(a) { + var copy = a.getDoc().copy(true); + a.setValue("foo"); + copy.setValue("bar"); + var old = a.swapDoc(copy); + eq(a.getValue(), "bar"); + a.undo(); + eq(a.getValue(), "u"); + a.swapDoc(old); + eq(a.getValue(), "foo"); + eq(old.historySize().undo, 1); + eq(old.copy(false).historySize().undo, 0); + }); + + testDoc("docKeepsMode", "A='1+1'", function(a) { + var other = CodeMirror.Doc("hi", "text/x-markdown"); + a.setOption("mode", "text/javascript"); + var old = a.swapDoc(other); + eq(a.getOption("mode"), "text/x-markdown"); + eq(a.getMode().name, "markdown"); + a.swapDoc(old); + eq(a.getOption("mode"), "text/javascript"); + eq(a.getMode().name, "javascript"); + }); + + testDoc("subview", "A='1\n2\n3\n4\n5' B<~A/1-3", function(a, b) { + eq(b.getValue(), "2\n3"); + eq(b.firstLine(), 1); + b.setCursor(Pos(4)); + eqCharPos(b.getCursor(), Pos(2, 1)); + a.replaceRange("-1\n0\n", Pos(0, 0)); + eq(b.firstLine(), 3); + eqCharPos(b.getCursor(), Pos(4, 1)); + a.undo(); + eqCharPos(b.getCursor(), Pos(2, 1)); + b.replaceRange("oyoy\n", Pos(2, 0)); + eq(a.getValue(), "1\n2\noyoy\n3\n4\n5"); + b.undo(); + eq(a.getValue(), "1\n2\n3\n4\n5"); + }); + + testDoc("subviewEditOnBoundary", "A='11\n22\n33\n44\n55' B<~A/1-4", function(a, b) { + a.replaceRange("x\nyy\nz", Pos(0, 1), Pos(2, 1)); + eq(b.firstLine(), 2); + eq(b.lineCount(), 2); + eq(b.getValue(), "z3\n44"); + a.replaceRange("q\nrr\ns", Pos(3, 1), Pos(4, 1)); + eq(b.firstLine(), 2); + eq(b.getValue(), "z3\n4q"); + eq(a.getValue(), "1x\nyy\nz3\n4q\nrr\ns5"); + a.execCommand("selectAll"); + a.replaceSelection("!"); + eqAll("!", a, b); + }); + + + testDoc("sharedMarker", "A='ab\ncd\nef\ngh' B 500){ + totalTime = 0; + delay = 50; + } + setTimeout(function(){step(i + 1);}, delay); + } else { // Quit tests + running = false; + return null; + } + } + step(0); +} + +function label(str, msg) { + if (msg) return str + " (" + msg + ")"; + return str; +} +function eq(a, b, msg) { + if (a != b) throw new Failure(label(a + " != " + b, msg)); +} +function near(a, b, margin, msg) { + if (Math.abs(a - b) > margin) + throw new Failure(label(a + " is not close to " + b + " (" + margin + ")", msg)); +} +function eqCharPos(a, b, msg) { + function str(p) { return "{line:" + p.line + ",ch:" + p.ch + ",sticky:" + p.sticky + "}"; } + if (a == b) return; + if (a == null) throw new Failure(label("comparing null to " + str(b), msg)); + if (b == null) throw new Failure(label("comparing " + str(a) + " to null", msg)); + if (a.line != b.line || a.ch != b.ch) throw new Failure(label(str(a) + " != " + str(b), msg)); +} +function eqCursorPos(a, b, msg) { + eqCharPos(a, b, msg); + if (a) eq(a.sticky, b.sticky, msg ? msg + ' (sticky)' : 'sticky'); +} +function is(a, msg) { + if (!a) throw new Failure(label("assertion failed", msg)); +} + +function countTests() { + if (!filters.length) return tests.length; + var sum = 0; + for (var i = 0; i < tests.length; ++i) { + var name = tests[i].name; + for (var j = 0; j < filters.length; j++) { + if (name.match(filters[j])) { + ++sum; + break; + } + } + } + return sum; +} + +function parseTestFilter(s) { + if (/_\*$/.test(s)) return new RegExp("^" + s.slice(0, s.length - 2), "i"); + else return new RegExp(s, "i"); +} diff --git a/backend/webif/static/codemirror/test/emacs_test.js b/backend/webif/static/codemirror/test/emacs_test.js new file mode 100755 index 000000000..412dba4b4 --- /dev/null +++ b/backend/webif/static/codemirror/test/emacs_test.js @@ -0,0 +1,149 @@ +(function() { + "use strict"; + + var Pos = CodeMirror.Pos; + namespace = "emacs_"; + + var eventCache = {}; + function fakeEvent(keyName) { + var event = eventCache[key]; + if (event) return event; + + var ctrl, shift, alt; + var key = keyName.replace(/\w+-/g, function(type) { + if (type == "Ctrl-") ctrl = true; + else if (type == "Alt-") alt = true; + else if (type == "Shift-") shift = true; + return ""; + }); + var code; + for (var c in CodeMirror.keyNames) + if (CodeMirror.keyNames[c] == key) { code = c; break; } + if (code == null) throw new Error("Unknown key: " + key); + + return eventCache[keyName] = { + type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt, + preventDefault: function(){}, stopPropagation: function(){} + }; + } + + function sim(name, start /*, actions... */) { + var keys = Array.prototype.slice.call(arguments, 2); + testCM(name, function(cm) { + for (var i = 0; i < keys.length; ++i) { + var cur = keys[i]; + if (cur instanceof Pos) cm.setCursor(cur); + else if (cur.call) cur(cm); + else cm.triggerOnKeyDown(fakeEvent(cur)); + } + }, {keyMap: "emacs", value: start, mode: "javascript"}); + } + + function at(line, ch, sticky) { return function(cm) { eqCursorPos(cm.getCursor(), Pos(line, ch, sticky)); }; } + function txt(str) { return function(cm) { eq(cm.getValue(), str); }; } + + sim("motionHSimple", "abc", "Ctrl-F", "Ctrl-F", "Ctrl-B", at(0, 1, "after")); + sim("motionHMulti", "abcde", + "Ctrl-4", "Ctrl-F", at(0, 4, "before"), "Ctrl--", "Ctrl-2", "Ctrl-F", at(0, 2, "after"), + "Ctrl-5", "Ctrl-B", at(0, 0, "after")); + + sim("motionHWord", "abc. def ghi", + "Alt-F", at(0, 3, "before"), "Alt-F", at(0, 8, "before"), + "Ctrl-B", "Alt-B", at(0, 5, "after"), "Alt-B", at(0, 0, "after")); + sim("motionHWordMulti", "abc. def ghi ", + "Ctrl-3", "Alt-F", at(0, 12, "before"), "Ctrl-2", "Alt-B", at(0, 5, "after"), + "Ctrl--", "Alt-B", at(0, 8, "before")); + + sim("motionVSimple", "a\nb\nc\n", "Ctrl-N", "Ctrl-N", "Ctrl-P", at(1, 0, "after")); + sim("motionVMulti", "a\nb\nc\nd\ne\n", + "Ctrl-2", "Ctrl-N", at(2, 0, "after"), "Ctrl-F", "Ctrl--", "Ctrl-N", at(1, 1, "before"), + "Ctrl--", "Ctrl-3", "Ctrl-P", at(4, 1, "before")); + + sim("killYank", "abc\ndef\nghi", + "Ctrl-F", "Ctrl-Space", "Ctrl-N", "Ctrl-N", "Ctrl-W", "Ctrl-E", "Ctrl-Y", + txt("ahibc\ndef\ng")); + sim("killRing", "abcdef", + "Ctrl-Space", "Ctrl-F", "Ctrl-W", "Ctrl-Space", "Ctrl-F", "Ctrl-W", + "Ctrl-Y", "Alt-Y", + txt("acdef")); + sim("copyYank", "abcd", + "Ctrl-Space", "Ctrl-E", "Alt-W", "Ctrl-Y", + txt("abcdabcd")); + + sim("killLineSimple", "foo\nbar", "Ctrl-F", "Ctrl-K", txt("f\nbar")); + sim("killLineEmptyLine", "foo\n \nbar", "Ctrl-N", "Ctrl-K", txt("foo\nbar")); + sim("killLineMulti", "foo\nbar\nbaz", + "Ctrl-F", "Ctrl-F", "Ctrl-K", "Ctrl-K", "Ctrl-K", "Ctrl-A", "Ctrl-Y", + txt("o\nbarfo\nbaz")); + + sim("moveByParagraph", "abc\ndef\n\n\nhij\nklm\n\n", + "Ctrl-F", "Ctrl-Down", at(2, 0), "Ctrl-Down", at(6, 0), + "Ctrl-N", "Ctrl-Up", at(3, 0), "Ctrl-Up", at(0, 0), + Pos(1, 2), "Ctrl-Down", at(2, 0), Pos(4, 2), "Ctrl-Up", at(3, 0)); + sim("moveByParagraphMulti", "abc\n\ndef\n\nhij\n\nklm", + "Ctrl-U", "2", "Ctrl-Down", at(3, 0), + "Shift-Alt-.", "Ctrl-3", "Ctrl-Up", at(1, 0)); + + sim("moveBySentence", "sentence one! sentence\ntwo\n\nparagraph two", + "Alt-E", at(0, 13), "Alt-E", at(1, 3), "Ctrl-F", "Alt-A", at(0, 13)); + + sim("moveByExpr", "function foo(a, b) {}", + "Ctrl-Alt-F", at(0, 8), "Ctrl-Alt-F", at(0, 12), "Ctrl-Alt-F", at(0, 18), + "Ctrl-Alt-B", at(0, 12), "Ctrl-Alt-B", at(0, 9)); + sim("moveByExprMulti", "foo bar baz bug", + "Ctrl-2", "Ctrl-Alt-F", at(0, 7), + "Ctrl--", "Ctrl-Alt-F", at(0, 4), + "Ctrl--", "Ctrl-2", "Ctrl-Alt-B", at(0, 11)); + sim("delExpr", "var x = [\n a,\n b\n c\n];", + Pos(0, 8), "Ctrl-Alt-K", txt("var x = ;"), "Ctrl-/", + Pos(4, 1), "Ctrl-Alt-Backspace", txt("var x = ;")); + sim("delExprMulti", "foo bar baz", + "Ctrl-2", "Ctrl-Alt-K", txt(" baz"), + "Ctrl-/", "Ctrl-E", "Ctrl-2", "Ctrl-Alt-Backspace", txt("foo ")); + + sim("justOneSpace", "hi bye ", + Pos(0, 4), "Alt-Space", txt("hi bye "), + Pos(0, 4), "Alt-Space", txt("hi b ye "), + "Ctrl-A", "Alt-Space", "Ctrl-E", "Alt-Space", txt(" hi b ye ")); + + sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar")) + + sim("transposeChar", "abcd\ne", + "Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\ne"), at(0, 3), + "Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\ne"), at(0, 4), + "Ctrl-F", "Ctrl-T", txt("bcde\na"), at(1, 1)); + + sim("manipWordCase", "foo BAR bAZ", + "Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"), + "Ctrl-A", "Alt-U", "Alt-L", "Alt-C", txt("FOO bar Baz")); + sim("manipWordCaseMulti", "foo Bar bAz", + "Ctrl-2", "Alt-U", txt("FOO BAR bAz"), + "Ctrl-A", "Ctrl-3", "Alt-C", txt("Foo Bar Baz")); + + sim("upExpr", "foo {\n bar[];\n baz(blah);\n}", + Pos(2, 7), "Ctrl-Alt-U", at(2, 5), "Ctrl-Alt-U", at(0, 4)); + sim("transposeExpr", "do foo[bar] dah", + Pos(0, 6), "Ctrl-Alt-T", txt("do [bar]foo dah")); + + sim("clearMark", "abcde", Pos(0, 2), "Ctrl-Space", "Ctrl-F", "Ctrl-F", + "Ctrl-G", "Ctrl-W", txt("abcde")); + + sim("delRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Delete", txt("cde")); + sim("backspaceRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Backspace", txt("cde")); + + sim("backspaceDoesntAddToRing", "foobar", "Ctrl-F", "Ctrl-F", "Ctrl-F", "Ctrl-K", "Backspace", "Backspace", "Ctrl-Y", txt("fbar")); + + testCM("save", function(cm) { + var saved = false; + CodeMirror.commands.save = function(cm) { saved = cm.getValue(); }; + cm.triggerOnKeyDown(fakeEvent("Ctrl-X")); + cm.triggerOnKeyDown(fakeEvent("Ctrl-S")); + is(saved, "hi"); + }, {value: "hi", keyMap: "emacs"}); + + testCM("gotoInvalidLineFloat", function(cm) { + cm.openDialog = function(_, cb) { cb("2.2"); }; + cm.triggerOnKeyDown(fakeEvent("Alt-G")); + cm.triggerOnKeyDown(fakeEvent("G")); + }, {value: "1\n2\n3\n4", keyMap: "emacs"}); +})(); diff --git a/backend/webif/static/codemirror/test/index.html b/backend/webif/static/codemirror/test/index.html new file mode 100755 index 000000000..99bee5bb9 --- /dev/null +++ b/backend/webif/static/codemirror/test/index.html @@ -0,0 +1,269 @@ + + + +CodeMirror: Test Suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Test Suite

    + +

    A limited set of programmatic sanity tests for CodeMirror.

    + +
    +
    Ran 0 of 0 tests
    +
    +

    Please enable JavaScript...

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/backend/webif/static/codemirror/test/lint.js b/backend/webif/static/codemirror/test/lint.js new file mode 100755 index 000000000..e7c114cd9 --- /dev/null +++ b/backend/webif/static/codemirror/test/lint.js @@ -0,0 +1,20 @@ +var blint = require("blint"); + +["mode", "lib", "addon", "keymap"].forEach(function(dir) { + blint.checkDir(dir, { + browser: true, + allowedGlobals: ["CodeMirror", "define", "test", "requirejs"], + ecmaVersion: 5, + tabs: dir == "lib" + }); +}); + +["src"].forEach(function(dir) { + blint.checkDir(dir, { + browser: true, + ecmaVersion: 6, + semicolons: false + }); +}); + +module.exports = {ok: blint.success()}; diff --git a/backend/webif/static/codemirror/test/mode_test.css b/backend/webif/static/codemirror/test/mode_test.css new file mode 100755 index 000000000..f83271b4e --- /dev/null +++ b/backend/webif/static/codemirror/test/mode_test.css @@ -0,0 +1,23 @@ +.mt-output .mt-token { + border: 1px solid #ddd; + white-space: pre; + font-family: "Consolas", monospace; + text-align: center; +} + +.mt-output .mt-style { + font-size: x-small; +} + +.mt-output .mt-state { + font-size: x-small; + vertical-align: top; +} + +.mt-output .mt-state-row { + display: none; +} + +.mt-state-unhide .mt-output .mt-state-row { + display: table-row; +} diff --git a/backend/webif/static/codemirror/test/mode_test.js b/backend/webif/static/codemirror/test/mode_test.js new file mode 100755 index 000000000..9773f8012 --- /dev/null +++ b/backend/webif/static/codemirror/test/mode_test.js @@ -0,0 +1,193 @@ +/** + * Helper to test CodeMirror highlighting modes. It pretty prints output of the + * highlighter and can check against expected styles. + * + * Mode tests are registered by calling test.mode(testName, mode, + * tokens), where mode is a mode object as returned by + * CodeMirror.getMode, and tokens is an array of lines that make up + * the test. + * + * These lines are strings, in which styled stretches of code are + * enclosed in brackets `[]`, and prefixed by their style. For + * example, `[keyword if]`. Brackets in the code itself must be + * duplicated to prevent them from being interpreted as token + * boundaries. For example `a[[i]]` for `a[i]`. If a token has + * multiple styles, the styles must be separated by ampersands, for + * example `[tag&error ]`. + * + * See the test.js files in the css, markdown, gfm, and stex mode + * directories for examples. + */ +(function() { + function findSingle(str, pos, ch) { + for (;;) { + var found = str.indexOf(ch, pos); + if (found == -1) return null; + if (str.charAt(found + 1) != ch) return found; + pos = found + 2; + } + } + + var styleName = /[\w&-_]+/g; + function parseTokens(strs) { + var tokens = [], plain = ""; + for (var i = 0; i < strs.length; ++i) { + if (i) plain += "\n"; + var str = strs[i], pos = 0; + while (pos < str.length) { + var style = null, text; + if (str.charAt(pos) == "[" && str.charAt(pos+1) != "[") { + styleName.lastIndex = pos + 1; + var m = styleName.exec(str); + style = m[0].replace(/&/g, " "); + var textStart = pos + style.length + 2; + var end = findSingle(str, textStart, "]"); + if (end == null) throw new Error("Unterminated token at " + pos + " in '" + str + "'" + style); + text = str.slice(textStart, end); + pos = end + 1; + } else { + var end = findSingle(str, pos, "["); + if (end == null) end = str.length; + text = str.slice(pos, end); + pos = end; + } + text = text.replace(/\[\[|\]\]/g, function(s) {return s.charAt(0);}); + tokens.push({style: style, text: text}); + plain += text; + } + } + return {tokens: tokens, plain: plain}; + } + + test.mode = function(name, mode, tokens, modeName) { + var data = parseTokens(tokens); + return test((modeName || mode.name) + "_" + name, function() { + return compare(data.plain, data.tokens, mode); + }); + }; + + function esc(str) { + return str.replace('&', '&').replace('<', '<').replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); + } + + function compare(text, expected, mode) { + + var expectedOutput = []; + for (var i = 0; i < expected.length; ++i) { + var sty = expected[i].style; + if (sty && sty.indexOf(" ")) sty = sty.split(' ').sort().join(' '); + expectedOutput.push({style: sty, text: expected[i].text}); + } + + var observedOutput = highlight(text, mode); + + var s = ""; + var diff = highlightOutputsDifferent(expectedOutput, observedOutput); + if (diff != null) { + s += '
    '; + s += '
    ' + esc(text) + '
    '; + s += '
    '; + s += 'expected:'; + s += prettyPrintOutputTable(expectedOutput, diff); + s += 'observed: [display states]'; + s += prettyPrintOutputTable(observedOutput, diff); + s += '
    '; + s += '
    '; + } + if (observedOutput.indentFailures) { + for (var i = 0; i < observedOutput.indentFailures.length; i++) + s += "
    " + esc(observedOutput.indentFailures[i]) + "
    "; + } + if (s) throw new Failure(s); + } + + function stringify(obj) { + function replacer(key, obj) { + if (typeof obj == "function") { + var m = obj.toString().match(/function\s*[^\s(]*/); + return m ? m[0] : "function"; + } + return obj; + } + if (window.JSON && JSON.stringify) + return JSON.stringify(obj, replacer, 2); + return "[unsupported]"; // Fail safely if no native JSON. + } + + function highlight(string, mode) { + var state = mode.startState(); + + var lines = string.replace(/\r\n/g,'\n').split('\n'); + var st = [], pos = 0; + for (var i = 0; i < lines.length; ++i) { + var line = lines[i], newLine = true; + if (mode.indent) { + var ws = line.match(/^\s*/)[0]; + var indent = mode.indent(state, line.slice(ws.length)); + if (indent != CodeMirror.Pass && indent != ws.length) + (st.indentFailures || (st.indentFailures = [])).push( + "Indentation of line " + (i + 1) + " is " + indent + " (expected " + ws.length + ")"); + } + var stream = new CodeMirror.StringStream(line, 4, { + lookAhead: function(n) { return lines[i + n] } + }); + if (line == "" && mode.blankLine) mode.blankLine(state); + /* Start copied code from CodeMirror.highlight */ + while (!stream.eol()) { + for (var j = 0; j < 10 && stream.start >= stream.pos; j++) + var compare = mode.token(stream, state); + if (j == 10) + throw new Failure("Failed to advance the stream." + stream.string + " " + stream.pos); + var substr = stream.current(); + if (compare && compare.indexOf(" ") > -1) compare = compare.split(' ').sort().join(' '); + stream.start = stream.pos; + if (pos && st[pos-1].style == compare && !newLine) { + st[pos-1].text += substr; + } else if (substr) { + st[pos++] = {style: compare, text: substr, state: stringify(state)}; + } + // Give up when line is ridiculously long + if (stream.pos > 5000) { + st[pos++] = {style: null, text: this.text.slice(stream.pos)}; + break; + } + newLine = false; + } + } + + return st; + } + + function highlightOutputsDifferent(o1, o2) { + var minLen = Math.min(o1.length, o2.length); + for (var i = 0; i < minLen; ++i) + if (o1[i].style != o2[i].style || o1[i].text != o2[i].text) return i; + if (o1.length > minLen || o2.length > minLen) return minLen; + } + + function prettyPrintOutputTable(output, diffAt) { + var s = ''; + s += ''; + for (var i = 0; i < output.length; ++i) { + var style = output[i].style, val = output[i].text; + s += + ''; + } + s += ''; + for (var i = 0; i < output.length; ++i) { + s += ''; + } + if(output[0].state) { + s += ''; + for (var i = 0; i < output.length; ++i) { + s += ''; + } + } + s += '
    ' + + '' + + esc(val.replace(/ /g,'\xb7')) + // · MIDDLE DOT + '' + + '
    ' + (output[i].style || null) + '
    ' + esc(output[i].state) + '
    '; + return s; + } +})(); diff --git a/backend/webif/static/codemirror/test/multi_test.js b/backend/webif/static/codemirror/test/multi_test.js new file mode 100755 index 000000000..49169b990 --- /dev/null +++ b/backend/webif/static/codemirror/test/multi_test.js @@ -0,0 +1,285 @@ +(function() { + namespace = "multi_"; + + function hasSelections(cm) { + var sels = cm.listSelections(); + var given = (arguments.length - 1) / 4; + if (sels.length != given) + throw new Failure("expected " + given + " selections, found " + sels.length); + for (var i = 0, p = 1; i < given; i++, p += 4) { + var anchor = Pos(arguments[p], arguments[p + 1]); + var head = Pos(arguments[p + 2], arguments[p + 3]); + eqCharPos(sels[i].anchor, anchor, "anchor of selection " + i); + eqCharPos(sels[i].head, head, "head of selection " + i); + } + } + function hasCursors(cm) { + var sels = cm.listSelections(); + var given = (arguments.length - 1) / 2; + if (sels.length != given) + throw new Failure("expected " + given + " selections, found " + sels.length); + for (var i = 0, p = 1; i < given; i++, p += 2) { + eqCursorPos(sels[i].anchor, sels[i].head, "something selected for " + i); + var head = Pos(arguments[p], arguments[p + 1]); + eqCharPos(sels[i].head, head, "selection " + i); + } + } + + testCM("getSelection", function(cm) { + select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)}, {anchor: Pos(2, 2), head: Pos(2, 0)}); + eq(cm.getSelection(), "1234\n56\n90"); + eq(cm.getSelection(false).join("|"), "1234|56|90"); + eq(cm.getSelections().join("|"), "1234\n56|90"); + }, {value: "1234\n5678\n90"}); + + testCM("setSelection", function(cm) { + select(cm, Pos(3, 0), Pos(0, 0), {anchor: Pos(2, 5), head: Pos(1, 0)}); + hasSelections(cm, 0, 0, 0, 0, + 2, 5, 1, 0, + 3, 0, 3, 0); + cm.setSelection(Pos(1, 2), Pos(1, 1)); + hasSelections(cm, 1, 2, 1, 1); + select(cm, {anchor: Pos(1, 1), head: Pos(2, 4)}, + {anchor: Pos(0, 0), head: Pos(1, 3)}, + Pos(3, 0), Pos(2, 2)); + hasSelections(cm, 0, 0, 2, 4, + 3, 0, 3, 0); + cm.setSelections([{anchor: Pos(0, 1), head: Pos(0, 2)}, + {anchor: Pos(1, 1), head: Pos(1, 2)}, + {anchor: Pos(2, 1), head: Pos(2, 2)}], 1); + eqCharPos(cm.getCursor("head"), Pos(1, 2)); + eqCharPos(cm.getCursor("anchor"), Pos(1, 1)); + eqCharPos(cm.getCursor("from"), Pos(1, 1)); + eqCharPos(cm.getCursor("to"), Pos(1, 2)); + cm.setCursor(Pos(1, 1)); + hasCursors(cm, 1, 1); + }, {value: "abcde\nabcde\nabcde\n"}); + + testCM("somethingSelected", function(cm) { + select(cm, Pos(0, 1), {anchor: Pos(0, 3), head: Pos(0, 5)}); + eq(cm.somethingSelected(), true); + select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5)); + eq(cm.somethingSelected(), false); + }, {value: "123456789"}); + + testCM("extendSelection", function(cm) { + select(cm, Pos(0, 1), Pos(1, 1), Pos(2, 1)); + cm.setExtending(true); + cm.extendSelections([Pos(0, 2), Pos(1, 0), Pos(2, 3)]); + hasSelections(cm, 0, 1, 0, 2, + 1, 1, 1, 0, + 2, 1, 2, 3); + cm.extendSelection(Pos(2, 4), Pos(2, 0)); + hasSelections(cm, 2, 4, 2, 0); + }, {value: "1234\n1234\n1234"}); + + testCM("addSelection", function(cm) { + select(cm, Pos(0, 1), Pos(1, 1)); + cm.addSelection(Pos(0, 0), Pos(0, 4)); + hasSelections(cm, 0, 0, 0, 4, + 1, 1, 1, 1); + cm.addSelection(Pos(2, 2)); + hasSelections(cm, 0, 0, 0, 4, + 1, 1, 1, 1, + 2, 2, 2, 2); + }, {value: "1234\n1234\n1234"}); + + testCM("replaceSelection", function(cm) { + var selections = [{anchor: Pos(0, 0), head: Pos(0, 1)}, + {anchor: Pos(0, 2), head: Pos(0, 3)}, + {anchor: Pos(0, 4), head: Pos(0, 5)}, + {anchor: Pos(2, 1), head: Pos(2, 4)}, + {anchor: Pos(2, 5), head: Pos(2, 6)}]; + var val = "123456\n123456\n123456"; + cm.setValue(val); + cm.setSelections(selections); + cm.replaceSelection("ab", "around"); + eq(cm.getValue(), "ab2ab4ab6\n123456\n1ab5ab"); + hasSelections(cm, 0, 0, 0, 2, + 0, 3, 0, 5, + 0, 6, 0, 8, + 2, 1, 2, 3, + 2, 4, 2, 6); + cm.setValue(val); + cm.setSelections(selections); + cm.replaceSelection("", "around"); + eq(cm.getValue(), "246\n123456\n15"); + hasSelections(cm, 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 2, 0, 2, + 2, 1, 2, 1, + 2, 2, 2, 2); + cm.setValue(val); + cm.setSelections(selections); + cm.replaceSelection("X\nY\nZ", "around"); + hasSelections(cm, 0, 0, 2, 1, + 2, 2, 4, 1, + 4, 2, 6, 1, + 8, 1, 10, 1, + 10, 2, 12, 1); + cm.replaceSelection("a", "around"); + hasSelections(cm, 0, 0, 0, 1, + 0, 2, 0, 3, + 0, 4, 0, 5, + 2, 1, 2, 2, + 2, 3, 2, 4); + cm.replaceSelection("xy", "start"); + hasSelections(cm, 0, 0, 0, 0, + 0, 3, 0, 3, + 0, 6, 0, 6, + 2, 1, 2, 1, + 2, 4, 2, 4); + cm.replaceSelection("z\nf"); + hasSelections(cm, 1, 1, 1, 1, + 2, 1, 2, 1, + 3, 1, 3, 1, + 6, 1, 6, 1, + 7, 1, 7, 1); + eq(cm.getValue(), "z\nfxy2z\nfxy4z\nfxy6\n123456\n1z\nfxy5z\nfxy"); + }); + + function select(cm) { + var sels = []; + for (var i = 1; i < arguments.length; i++) { + var arg = arguments[i]; + if (arg.head) sels.push(arg); + else sels.push({head: arg, anchor: arg}); + } + cm.setSelections(sels, sels.length - 1); + } + + testCM("indentSelection", function(cm) { + select(cm, Pos(0, 1), Pos(1, 1)); + cm.indentSelection(4); + eq(cm.getValue(), " foo\n bar\nbaz"); + + select(cm, Pos(0, 2), Pos(0, 3), Pos(0, 4)); + cm.indentSelection(-2); + eq(cm.getValue(), " foo\n bar\nbaz"); + + select(cm, {anchor: Pos(0, 0), head: Pos(1, 2)}, + {anchor: Pos(1, 3), head: Pos(2, 0)}); + cm.indentSelection(-2); + eq(cm.getValue(), "foo\n bar\nbaz"); + }, {value: "foo\nbar\nbaz"}); + + testCM("killLine", function(cm) { + select(cm, Pos(0, 1), Pos(0, 2), Pos(1, 1)); + cm.execCommand("killLine"); + eq(cm.getValue(), "f\nb\nbaz"); + cm.execCommand("killLine"); + eq(cm.getValue(), "fbbaz"); + cm.setValue("foo\nbar\nbaz"); + select(cm, Pos(0, 1), {anchor: Pos(0, 2), head: Pos(2, 1)}); + cm.execCommand("killLine"); + eq(cm.getValue(), "faz"); + }, {value: "foo\nbar\nbaz"}); + + testCM("deleteLine", function(cm) { + select(cm, Pos(0, 0), + {head: Pos(0, 1), anchor: Pos(2, 0)}, + Pos(4, 0)); + cm.execCommand("deleteLine"); + eq(cm.getValue(), "4\n6\n7"); + select(cm, Pos(2, 1)); + cm.execCommand("deleteLine"); + eq(cm.getValue(), "4\n6\n"); + }, {value: "1\n2\n3\n4\n5\n6\n7"}); + + testCM("deleteH", function(cm) { + select(cm, Pos(0, 4), {anchor: Pos(1, 4), head: Pos(1, 5)}); + cm.execCommand("delWordAfter"); + eq(cm.getValue(), "foo bar baz\nabc ef ghi\n"); + cm.execCommand("delWordAfter"); + eq(cm.getValue(), "foo baz\nabc ghi\n"); + cm.execCommand("delCharBefore"); + cm.execCommand("delCharBefore"); + eq(cm.getValue(), "fo baz\nab ghi\n"); + select(cm, Pos(0, 3), Pos(0, 4), Pos(0, 5)); + cm.execCommand("delWordAfter"); + eq(cm.getValue(), "fo \nab ghi\n"); + }, {value: "foo bar baz\nabc def ghi\n"}); + + testCM("goLineStart", function(cm) { + select(cm, Pos(0, 2), Pos(0, 3), Pos(1, 1)); + cm.execCommand("goLineStart"); + hasCursors(cm, 0, 0, 1, 0); + select(cm, Pos(1, 1), Pos(0, 1)); + cm.setExtending(true); + cm.execCommand("goLineStart"); + hasSelections(cm, 0, 1, 0, 0, + 1, 1, 1, 0); + }, {value: "foo\nbar\nbaz"}); + + testCM("moveV", function(cm) { + select(cm, Pos(0, 2), Pos(1, 2)); + cm.execCommand("goLineDown"); + hasCursors(cm, 1, 2, 2, 2); + cm.execCommand("goLineUp"); + hasCursors(cm, 0, 2, 1, 2); + cm.execCommand("goLineUp"); + hasCursors(cm, 0, 0, 0, 2); + cm.execCommand("goLineUp"); + hasCursors(cm, 0, 0); + select(cm, Pos(0, 2), Pos(1, 2)); + cm.setExtending(true); + cm.execCommand("goLineDown"); + hasSelections(cm, 0, 2, 2, 2); + }, {value: "12345\n12345\n12345"}); + + testCM("moveH", function(cm) { + select(cm, Pos(0, 1), Pos(0, 3), Pos(0, 5), Pos(2, 3)); + cm.execCommand("goCharRight"); + hasCursors(cm, 0, 2, 0, 4, 1, 0, 2, 4); + cm.execCommand("goCharLeft"); + hasCursors(cm, 0, 1, 0, 3, 0, 5, 2, 3); + for (var i = 0; i < 15; i++) + cm.execCommand("goCharRight"); + hasCursors(cm, 2, 4, 2, 5); + }, {value: "12345\n12345\n12345"}); + + testCM("newlineAndIndent", function(cm) { + select(cm, Pos(0, 5), Pos(1, 5)); + cm.execCommand("newlineAndIndent"); + hasCursors(cm, 1, 2, 3, 2); + eq(cm.getValue(), "x = [\n 1];\ny = [\n 2];"); + cm.undo(); + eq(cm.getValue(), "x = [1];\ny = [2];"); + hasCursors(cm, 0, 5, 1, 5); + select(cm, Pos(0, 5), Pos(0, 6)); + cm.execCommand("newlineAndIndent"); + hasCursors(cm, 1, 2, 2, 0); + eq(cm.getValue(), "x = [\n 1\n];\ny = [2];"); + }, {value: "x = [1];\ny = [2];", mode: "javascript"}); + + testCM("goDocStartEnd", function(cm) { + select(cm, Pos(0, 1), Pos(1, 1)); + cm.execCommand("goDocStart"); + hasCursors(cm, 0, 0); + select(cm, Pos(0, 1), Pos(1, 1)); + cm.execCommand("goDocEnd"); + hasCursors(cm, 1, 3); + select(cm, Pos(0, 1), Pos(1, 1)); + cm.setExtending(true); + cm.execCommand("goDocEnd"); + hasSelections(cm, 1, 1, 1, 3); + }, {value: "abc\ndef"}); + + testCM("selectionHistory", function(cm) { + for (var i = 0; i < 3; ++i) + cm.addSelection(Pos(0, i * 2), Pos(0, i * 2 + 1)); + cm.execCommand("undoSelection"); + eq(cm.getSelection(), "1\n2"); + cm.execCommand("undoSelection"); + eq(cm.getSelection(), "1"); + cm.execCommand("undoSelection"); + eq(cm.getSelection(), ""); + eqCharPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), "1"); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), "1\n2"); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), "1\n2\n3"); + }, {value: "1 2 3"}); +})(); diff --git a/backend/webif/static/codemirror/test/phantom_driver.js b/backend/webif/static/codemirror/test/phantom_driver.js new file mode 100755 index 000000000..dbad08db6 --- /dev/null +++ b/backend/webif/static/codemirror/test/phantom_driver.js @@ -0,0 +1,31 @@ +var page = require('webpage').create(); + +page.open("http://localhost:3000/test/index.html", function (status) { + if (status != "success") { + console.log("page couldn't be loaded successfully"); + phantom.exit(1); + } + waitFor(function () { + return page.evaluate(function () { + var output = document.getElementById('status'); + if (!output) { return false; } + return (/^(\d+ failures?|all passed)/i).test(output.innerText); + }); + }, function () { + var failed = page.evaluate(function () { return window.failed; }); + var output = page.evaluate(function () { + return document.getElementById('output').innerText + "\n" + + document.getElementById('status').innerText; + }); + console.log(output); + phantom.exit(failed > 0 ? 1 : 0); + }); +}); + +function waitFor (test, cb) { + if (test()) { + cb(); + } else { + setTimeout(function () { waitFor(test, cb); }, 250); + } +} diff --git a/backend/webif/static/codemirror/test/run.js b/backend/webif/static/codemirror/test/run.js new file mode 100755 index 000000000..54984e73a --- /dev/null +++ b/backend/webif/static/codemirror/test/run.js @@ -0,0 +1,31 @@ +#!/usr/bin/env node + +var ok = require("./lint").ok; + +var files = new (require('node-static').Server)(); + +var server = require('http').createServer(function (req, res) { + req.addListener('end', function () { + files.serve(req, res, function (err/*, result */) { + if (err) { + console.error(err); + process.exit(1); + } + }); + }).resume(); +}).addListener('error', function (err) { + throw err; +}).listen(3000, function () { + var childProcess = require('child_process'); + var phantomjs = require("phantomjs-prebuilt"); + var childArgs = [ + require("path").join(__dirname, 'phantom_driver.js') + ]; + childProcess.execFile(phantomjs.path, childArgs, function (err, stdout, stderr) { + server.close(); + console.log(stdout); + if (err) console.error(err); + if (stderr) console.error(stderr); + process.exit(err || stderr || !ok ? 1 : 0); + }); +}); diff --git a/backend/webif/static/codemirror/test/scroll_test.js b/backend/webif/static/codemirror/test/scroll_test.js new file mode 100755 index 000000000..d1d219005 --- /dev/null +++ b/backend/webif/static/codemirror/test/scroll_test.js @@ -0,0 +1,126 @@ +(function() { + "use strict"; + + namespace = "scroll_"; + + testCM("bars_hidden", function(cm) { + for (var i = 0;; i++) { + var wrapBox = cm.getWrapperElement().getBoundingClientRect(); + var scrollBox = cm.getScrollerElement().getBoundingClientRect(); + is(wrapBox.bottom < scrollBox.bottom - 10); + is(wrapBox.right < scrollBox.right - 10); + if (i == 1) break; + cm.getWrapperElement().style.height = "auto"; + cm.refresh(); + } + }); + + function barH(cm) { return byClassName(cm.getWrapperElement(), "CodeMirror-hscrollbar")[0]; } + function barV(cm) { return byClassName(cm.getWrapperElement(), "CodeMirror-vscrollbar")[0]; } + + function displayBottom(cm, scrollbar) { + if (scrollbar && cm.display.scroller.offsetHeight > cm.display.scroller.clientHeight) + return barH(cm).getBoundingClientRect().top; + else + return cm.getWrapperElement().getBoundingClientRect().bottom - 1; + } + + function displayRight(cm, scrollbar) { + if (scrollbar && cm.display.scroller.offsetWidth > cm.display.scroller.clientWidth) + return barV(cm).getBoundingClientRect().left; + else + return cm.getWrapperElement().getBoundingClientRect().right - 1; + } + + function testMovedownFixed(cm, hScroll) { + cm.setSize("100px", "100px"); + if (hScroll) cm.setValue(new Array(100).join("x")); + var bottom = displayBottom(cm, hScroll); + for (var i = 0; i < 30; i++) { + cm.replaceSelection("x\n"); + var cursorBottom = cm.cursorCoords(null, "window").bottom; + is(cursorBottom <= bottom); + } + is(cursorBottom >= bottom - 5); + } + + testCM("movedown_fixed", function(cm) {testMovedownFixed(cm, false);}); + testCM("movedown_hscroll_fixed", function(cm) {testMovedownFixed(cm, true);}); + + function testMovedownResize(cm, hScroll) { + cm.getWrapperElement().style.height = "auto"; + if (hScroll) cm.setValue(new Array(100).join("x")); + cm.refresh(); + for (var i = 0; i < 30; i++) { + cm.replaceSelection("x\n"); + var bottom = displayBottom(cm, hScroll); + var cursorBottom = cm.cursorCoords(null, "window").bottom; + is(cursorBottom <= bottom); + is(cursorBottom >= bottom - 5); + } + } + + testCM("movedown_resize", function(cm) {testMovedownResize(cm, false);}); + testCM("movedown_hscroll_resize", function(cm) {testMovedownResize(cm, true);}); + + function testMoveright(cm, wrap, scroll) { + cm.setSize("100px", "100px"); + if (wrap) cm.setOption("lineWrapping", true); + if (scroll) { + cm.setValue("\n" + new Array(100).join("x\n")); + cm.setCursor(Pos(0, 0)); + } + var right = displayRight(cm, scroll); + for (var i = 0; i < 10; i++) { + cm.replaceSelection("xxxxxxxxxx"); + var cursorRight = cm.cursorCoords(null, "window").right; + is(cursorRight < right); + } + if (!wrap) is(cursorRight > right - 20); + } + + testCM("moveright", function(cm) {testMoveright(cm, false, false);}); + testCM("moveright_wrap", function(cm) {testMoveright(cm, true, false);}); + testCM("moveright_scroll", function(cm) {testMoveright(cm, false, true);}); + testCM("moveright_scroll_wrap", function(cm) {testMoveright(cm, true, true);}); + + testCM("suddenly_wide", function(cm) { + addDoc(cm, 100, 100); + cm.replaceSelection(new Array(600).join("l ") + "\n"); + cm.execCommand("goLineUp"); + cm.execCommand("goLineEnd"); + is(barH(cm).scrollLeft > cm.getScrollerElement().scrollLeft - 1); + }); + + testCM("wrap_changes_height", function(cm) { + var line = new Array(20).join("a ") + "\n"; + cm.setValue(new Array(20).join(line)); + var box = cm.getWrapperElement().getBoundingClientRect(); + cm.setSize(cm.cursorCoords(Pos(0), "window").right - box.left + 2, + cm.cursorCoords(Pos(19, 0), "window").bottom - box.top + 2); + cm.setCursor(Pos(19, 0)); + cm.replaceSelection("\n"); + is(cm.cursorCoords(null, "window").bottom < displayBottom(cm, false)); + }, {lineWrapping: true}); + + testCM("height_auto_with_gutter_expect_no_scroll_after_line_delete", function(cm) { + cm.setSize(null, "auto"); + cm.setValue("x\n"); + cm.execCommand("goDocEnd"); + cm.execCommand("delCharBefore"); + eq(cm.getScrollInfo().top, 0); + cm.scrollTo(null, 10); + is(cm.getScrollInfo().top < 5); + }, {lineNumbers: true}); + + testCM("bidi_ensureCursorVisible", function(cm) { + cm.setValue("
    وضع الاستخدام. عندما لا تعطى، وهذا الافتراضي إلى الطريقة الاولى\n"); + cm.execCommand("goLineStart"); + eq(cm.getScrollInfo().left, 0); + cm.execCommand("goCharRight"); + cm.execCommand("goCharRight"); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(0, 3, "before")); + eq(cm.getScrollInfo().left, 0); + }, {lineWrapping: false}); +})(); diff --git a/backend/webif/static/codemirror/test/search_test.js b/backend/webif/static/codemirror/test/search_test.js new file mode 100755 index 000000000..e3188de52 --- /dev/null +++ b/backend/webif/static/codemirror/test/search_test.js @@ -0,0 +1,85 @@ +(function() { + "use strict"; + + function run(doc, query, options) { + var cursor = doc.getSearchCursor(query, null, options); + for (var i = 3; i < arguments.length; i += 4) { + var found = cursor.findNext(); + is(found, "not enough results (forward)"); + eqCharPos(Pos(arguments[i], arguments[i + 1]), cursor.from(), "from, forward, " + (i - 3) / 4); + eqCharPos(Pos(arguments[i + 2], arguments[i + 3]), cursor.to(), "to, forward, " + (i - 3) / 4); + } + is(!cursor.findNext(), "too many matches (forward)"); + for (var i = arguments.length - 4; i >= 3; i -= 4) { + var found = cursor.findPrevious(); + is(found, "not enough results (backwards)"); + eqCharPos(Pos(arguments[i], arguments[i + 1]), cursor.from(), "from, backwards, " + (i - 3) / 4); + eqCharPos(Pos(arguments[i + 2], arguments[i + 3]), cursor.to(), "to, backwards, " + (i - 3) / 4); + } + is(!cursor.findPrevious(), "too many matches (backwards)"); + } + + function test(name, f) { window.test("search_" + name, f) } + + test("simple", function() { + var doc = new CodeMirror.Doc("abcdefg\nabcdefg") + run(doc, "cde", false, 0, 2, 0, 5, 1, 2, 1, 5); + }); + + test("multiline", function() { + var doc = new CodeMirror.Doc("hallo\na\nb\ngoodbye") + run(doc, "llo\na\nb\ngoo", false, 0, 2, 3, 3); + run(doc, "blah\na\nb\nhall", false); + run(doc, "bye\nx\neye", false); + }); + + test("regexp", function() { + var doc = new CodeMirror.Doc("abcde\nabcde") + run(doc, /bcd/, false, 0, 1, 0, 4, 1, 1, 1, 4); + run(doc, /BCD/, false); + run(doc, /BCD/i, false, 0, 1, 0, 4, 1, 1, 1, 4); + }); + + test("regexpMultiline", function() { + var doc = new CodeMirror.Doc("foo foo\nbar\nbaz") + run(doc, /fo[^]*az/, {multiline: true}, 0, 0, 2, 3) + run(doc, /[oa][^u]/, {multiline: true}, 0, 1, 0, 3, 0, 5, 0, 7, 1, 1, 1, 3, 2, 1, 2, 3) + run(doc, /[a][^u]{2}/, {multiline: true}, 1, 1, 2, 0) + }) + + test("insensitive", function() { + var doc = new CodeMirror.Doc("hallo\nHALLO\noink\nhAllO") + run(doc, "All", false, 3, 1, 3, 4); + run(doc, "All", true, 0, 1, 0, 4, 1, 1, 1, 4, 3, 1, 3, 4); + }); + + test("multilineInsensitive", function() { + var doc = new CodeMirror.Doc("zie ginds komT\nDe Stoomboot\nuit Spanje weer aan") + run(doc, "komt\nde stoomboot\nuit", false); + run(doc, "komt\nde stoomboot\nuit", {caseFold: true}, 0, 10, 2, 3); + run(doc, "kOMt\ndE stOOmboot\nuiT", {caseFold: true}, 0, 10, 2, 3); + }); + + test("multilineInsensitiveSlow", function() { + var text = "" + for (var i = 0; i < 1000; i++) text += "foo\nbar\n" + var doc = new CodeMirror.Doc("find\nme\n" + text + "find\nme\n") + var t0 = +new Date + run(doc, /find\nme/, {multiline: true}, 0, 0, 1, 2, 2002, 0, 2003, 2) + is(+new Date - t0 < 100) + }) + + test("expandingCaseFold", function() { + var doc = new CodeMirror.Doc("İİ İİ\nuu uu") + run(doc, "", true, 0, 8, 0, 12, 1, 8, 1, 12); + run(doc, "İİ", true, 0, 3, 0, 5, 0, 6, 0, 8); + }); + + test("normalize", function() { + if (!String.prototype.normalize) return + var doc = new CodeMirror.Doc("yılbaşı\n수 있을까\nLe taux d'humidité à London") + run(doc, "s", false, 0, 5, 0, 6) + run(doc, "이", false, 1, 2, 1, 3) + run(doc, "a", false, 0, 4, 0, 5, 2, 4, 2, 5, 2, 19, 2, 20) + }) +})(); diff --git a/backend/webif/static/codemirror/test/sql-hint-test.js b/backend/webif/static/codemirror/test/sql-hint-test.js new file mode 100755 index 000000000..1094ec03d --- /dev/null +++ b/backend/webif/static/codemirror/test/sql-hint-test.js @@ -0,0 +1,238 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var Pos = CodeMirror.Pos; + + var simpleTables = { + "users": ["name", "score", "birthDate"], + "xcountries": ["name", "population", "size"] + }; + + var schemaTables = { + "schema.users": ["name", "score", "birthDate"], + "schema.countries": ["name", "population", "size"] + }; + + var displayTextTables = [{ + text: "mytable", + displayText: "mytable | The main table", + columns: [{text: "id", displayText: "id | Unique ID"}, + {text: "name", displayText: "name | The name"}] + }]; + + namespace = "sql-hint_"; + + function test(name, spec) { + testCM(name, function(cm) { + cm.setValue(spec.value); + cm.setCursor(spec.cursor); + var completion = CodeMirror.hint.sql(cm, {tables: spec.tables}); + if (!deepCompare(completion.list, spec.list)) + throw new Failure("Wrong completion results " + JSON.stringify(completion.list) + " vs " + JSON.stringify(spec.list)); + eqCharPos(completion.from, spec.from); + eqCharPos(completion.to, spec.to); + }, { + value: spec.value, + mode: spec.mode || "text/x-mysql" + }); + } + + test("keywords", { + value: "SEL", + cursor: Pos(0, 3), + list: ["SELECT"], + from: Pos(0, 0), + to: Pos(0, 3) + }); + + test("from", { + value: "SELECT * fr", + cursor: Pos(0, 11), + list: ["FROM"], + from: Pos(0, 9), + to: Pos(0, 11) + }); + + test("table", { + value: "SELECT xc", + cursor: Pos(0, 9), + tables: simpleTables, + list: ["xcountries"], + from: Pos(0, 7), + to: Pos(0, 9) + }); + + test("columns", { + value: "SELECT users.", + cursor: Pos(0, 13), + tables: simpleTables, + list: ["users.name", "users.score", "users.birthDate"], + from: Pos(0, 7), + to: Pos(0, 13) + }); + + test("singlecolumn", { + value: "SELECT users.na", + cursor: Pos(0, 15), + tables: simpleTables, + list: ["users.name"], + from: Pos(0, 7), + to: Pos(0, 15) + }); + + test("quoted", { + value: "SELECT `users`.`na", + cursor: Pos(0, 18), + tables: simpleTables, + list: ["`users`.`name`"], + from: Pos(0, 7), + to: Pos(0, 18) + }); + + test("doublequoted", { + value: "SELECT \"users\".\"na", + cursor: Pos(0, 18), + tables: simpleTables, + list: ["\"users\".\"name\""], + from: Pos(0, 7), + to: Pos(0, 18), + mode: "text/x-sqlite" + }); + + test("quotedcolumn", { + value: "SELECT users.`na", + cursor: Pos(0, 16), + tables: simpleTables, + list: ["`users`.`name`"], + from: Pos(0, 7), + to: Pos(0, 16) + }); + + test("doublequotedcolumn", { + value: "SELECT users.\"na", + cursor: Pos(0, 16), + tables: simpleTables, + list: ["\"users\".\"name\""], + from: Pos(0, 7), + to: Pos(0, 16), + mode: "text/x-sqlite" + }); + + test("schema", { + value: "SELECT schem", + cursor: Pos(0, 12), + tables: schemaTables, + list: ["schema.users", "schema.countries", + "SCHEMA", "SCHEMA_NAME", "SCHEMAS"], + from: Pos(0, 7), + to: Pos(0, 12) + }); + + test("schemaquoted", { + value: "SELECT `sch", + cursor: Pos(0, 11), + tables: schemaTables, + list: ["`schema`.`users`", "`schema`.`countries`"], + from: Pos(0, 7), + to: Pos(0, 11) + }); + + test("schemadoublequoted", { + value: "SELECT \"sch", + cursor: Pos(0, 11), + tables: schemaTables, + list: ["\"schema\".\"users\"", "\"schema\".\"countries\""], + from: Pos(0, 7), + to: Pos(0, 11), + mode: "text/x-sqlite" + }); + + test("schemacolumn", { + value: "SELECT schema.users.", + cursor: Pos(0, 20), + tables: schemaTables, + list: ["schema.users.name", + "schema.users.score", + "schema.users.birthDate"], + from: Pos(0, 7), + to: Pos(0, 20) + }); + + test("schemacolumnquoted", { + value: "SELECT `schema`.`users`.", + cursor: Pos(0, 24), + tables: schemaTables, + list: ["`schema`.`users`.`name`", + "`schema`.`users`.`score`", + "`schema`.`users`.`birthDate`"], + from: Pos(0, 7), + to: Pos(0, 24) + }); + + test("schemacolumndoublequoted", { + value: "SELECT \"schema\".\"users\".", + cursor: Pos(0, 24), + tables: schemaTables, + list: ["\"schema\".\"users\".\"name\"", + "\"schema\".\"users\".\"score\"", + "\"schema\".\"users\".\"birthDate\""], + from: Pos(0, 7), + to: Pos(0, 24), + mode: "text/x-sqlite" + }); + + test("displayText_table", { + value: "SELECT myt", + cursor: Pos(0, 10), + tables: displayTextTables, + list: [{text: "mytable", displayText: "mytable | The main table",}], + from: Pos(0, 7), + to: Pos(0, 10) + }); + + test("displayText_column", { + value: "SELECT mytable.", + cursor: Pos(0, 15), + tables: displayTextTables, + list: [{text: "mytable.id", displayText: "id | Unique ID"}, + {text: "mytable.name", displayText: "name | The name"}], + from: Pos(0, 7), + to: Pos(0, 15) + }); + + test("alias_complete", { + value: "SELECT t. FROM users t", + cursor: Pos(0, 9), + tables: simpleTables, + list: ["t.name", "t.score", "t.birthDate"], + from: Pos(0, 7), + to: Pos(0, 9) + }); + + test("alias_complete_with_displayText", { + value: "SELECT t. FROM mytable t", + cursor: Pos(0, 9), + tables: displayTextTables, + list: [{text: "t.id", displayText: "id | Unique ID"}, + {text: "t.name", displayText: "name | The name"}], + from: Pos(0, 7), + to: Pos(0, 9) + }) + + function deepCompare(a, b) { + if (a === b) return true + if (!(a && typeof a == "object") || + !(b && typeof b == "object")) return false + var array = Array.isArray(a) + if (Array.isArray(b) != array) return false + if (array) { + if (a.length != b.length) return false + for (var i = 0; i < a.length; i++) if (!deepCompare(a[i], b[i])) return false + } else { + for (var p in a) if (!(p in b) || !deepCompare(a[p], b[p])) return false + for (var p in b) if (!(p in a)) return false + } + return true + } +})(); diff --git a/backend/webif/static/codemirror/test/sublime_test.js b/backend/webif/static/codemirror/test/sublime_test.js new file mode 100755 index 000000000..e9cd342ff --- /dev/null +++ b/backend/webif/static/codemirror/test/sublime_test.js @@ -0,0 +1,307 @@ +(function() { + "use strict"; + + var Pos = CodeMirror.Pos; + namespace = "sublime_"; + + function stTest(name) { + var actions = Array.prototype.slice.call(arguments, 1); + testCM(name, function(cm) { + for (var i = 0; i < actions.length; i++) { + var action = actions[i]; + if (typeof action == "string" && i == 0) + cm.setValue(action); + else if (typeof action == "string") + cm.execCommand(action); + else if (action instanceof Pos) + cm.setCursor(action); + else + action(cm); + } + }); + } + + function at(line, ch, msg) { + return function(cm) { + eq(cm.listSelections().length, 1); + eqCursorPos(cm.getCursor("head"), Pos(line, ch), msg); + eqCursorPos(cm.getCursor("anchor"), Pos(line, ch), msg); + }; + } + + function val(content, msg) { + return function(cm) { eq(cm.getValue(), content, msg); }; + } + + function argsToRanges(args) { + if (args.length % 4) throw new Error("Wrong number of arguments for ranges."); + var ranges = []; + for (var i = 0; i < args.length; i += 4) + ranges.push({anchor: Pos(args[i], args[i + 1]), + head: Pos(args[i + 2], args[i + 3])}); + return ranges; + } + + function setSel() { + var ranges = argsToRanges(arguments); + return function(cm) { cm.setSelections(ranges, 0); }; + } + + function hasSel() { + var ranges = argsToRanges(arguments); + return function(cm) { + var sels = cm.listSelections(); + if (sels.length != ranges.length) + throw new Failure("Expected " + ranges.length + " selections, but found " + sels.length); + for (var i = 0; i < sels.length; i++) { + eqCharPos(sels[i].anchor, ranges[i].anchor, "anchor " + i); + eqCharPos(sels[i].head, ranges[i].head, "head " + i); + } + }; + } + + stTest("bySubword", "the foo_bar DooDahBah \n a", + "goSubwordLeft", at(0, 0), + "goSubwordRight", at(0, 3), + "goSubwordRight", at(0, 7), + "goSubwordRight", at(0, 11), + "goSubwordRight", at(0, 15), + "goSubwordRight", at(0, 18), + "goSubwordRight", at(0, 21), + "goSubwordRight", at(0, 22), + "goSubwordRight", at(1, 0), + "goSubwordRight", at(1, 2), + "goSubwordRight", at(1, 2), + "goSubwordLeft", at(1, 1), + "goSubwordLeft", at(1, 0), + "goSubwordLeft", at(0, 22), + "goSubwordLeft", at(0, 18), + "goSubwordLeft", at(0, 15), + "goSubwordLeft", at(0, 12), + "goSubwordLeft", at(0, 8), + "goSubwordLeft", at(0, 4), + "goSubwordLeft", at(0, 0)); + + stTest("splitSelectionByLine", "abc\ndef\nghi", + setSel(0, 1, 2, 2), + "splitSelectionByLine", + hasSel(0, 1, 0, 3, + 1, 0, 1, 3, + 2, 0, 2, 2)); + + stTest("splitSelectionByLineMulti", "abc\ndef\nghi\njkl", + setSel(0, 1, 1, 1, + 1, 2, 3, 2, + 3, 3, 3, 3), + "splitSelectionByLine", + hasSel(0, 1, 0, 3, + 1, 0, 1, 1, + 1, 2, 1, 3, + 2, 0, 2, 3, + 3, 0, 3, 2, + 3, 3, 3, 3)); + + stTest("selectLine", "abc\ndef\nghi", + setSel(0, 1, 0, 1, + 2, 0, 2, 1), + "selectLine", + hasSel(0, 0, 1, 0, + 2, 0, 2, 3), + setSel(0, 1, 1, 0), + "selectLine", + hasSel(0, 0, 2, 0)); + + stTest("insertLineAfter", "abcde\nfghijkl\nmn", + setSel(0, 1, 0, 1, + 0, 3, 0, 3, + 1, 2, 1, 2, + 1, 3, 1, 5), "insertLineAfter", + hasSel(1, 0, 1, 0, + 3, 0, 3, 0), val("abcde\n\nfghijkl\n\nmn")); + + stTest("insertLineBefore", "abcde\nfghijkl\nmn", + setSel(0, 1, 0, 1, + 0, 3, 0, 3, + 1, 2, 1, 2, + 1, 3, 1, 5), "insertLineBefore", + hasSel(0, 0, 0, 0, + 2, 0, 2, 0), val("\nabcde\n\nfghijkl\nmn")); + + stTest("selectNextOccurrence", "a foo bar\nfoobar foo", + setSel(0, 2, 0, 5), + "selectNextOccurrence", hasSel(0, 2, 0, 5, + 1, 0, 1, 3), + "selectNextOccurrence", hasSel(0, 2, 0, 5, + 1, 0, 1, 3, + 1, 7, 1, 10), + "selectNextOccurrence", hasSel(0, 2, 0, 5, + 1, 0, 1, 3, + 1, 7, 1, 10), + Pos(0, 3), "selectNextOccurrence", hasSel(0, 2, 0, 5), + "selectNextOccurrence", hasSel(0, 2, 0, 5, + 1, 7, 1, 10), + setSel(0, 6, 0, 9), + "selectNextOccurrence", hasSel(0, 6, 0, 9, + 1, 3, 1, 6)); + + stTest("selectScope", "foo(a) {\n bar[1, 2];\n}", + "selectScope", hasSel(0, 0, 2, 1), + Pos(0, 4), "selectScope", hasSel(0, 4, 0, 5), + Pos(0, 5), "selectScope", hasSel(0, 4, 0, 5), + Pos(0, 6), "selectScope", hasSel(0, 0, 2, 1), + Pos(0, 8), "selectScope", hasSel(0, 8, 2, 0), + Pos(1, 2), "selectScope", hasSel(0, 8, 2, 0), + Pos(1, 6), "selectScope", hasSel(1, 6, 1, 10), + Pos(1, 9), "selectScope", hasSel(1, 6, 1, 10)); + + stTest("goToBracket", "foo(a) {\n bar[1, 2];\n}", + Pos(0, 0), "goToBracket", at(0, 0), + Pos(0, 4), "goToBracket", at(0, 5), "goToBracket", at(0, 4), + Pos(0, 8), "goToBracket", at(2, 0), "goToBracket", at(0, 8), + Pos(1, 2), "goToBracket", at(2, 0), + Pos(1, 7), "goToBracket", at(1, 10), "goToBracket", at(1, 6)); + + stTest("swapLine", "1\n2\n3---\n4\n5", + "swapLineDown", val("2\n1\n3---\n4\n5"), + "swapLineUp", val("1\n2\n3---\n4\n5"), + "swapLineUp", val("1\n2\n3---\n4\n5"), + Pos(4, 1), "swapLineDown", val("1\n2\n3---\n4\n5"), + setSel(0, 1, 0, 1, + 1, 0, 2, 0, + 2, 2, 2, 2), + "swapLineDown", val("4\n1\n2\n3---\n5"), + hasSel(1, 1, 1, 1, + 2, 0, 3, 0, + 3, 2, 3, 2), + "swapLineUp", val("1\n2\n3---\n4\n5"), + hasSel(0, 1, 0, 1, + 1, 0, 2, 0, + 2, 2, 2, 2)); + + stTest("swapLineEmptyBottomSel", "1\n2\n3", + setSel(0, 1, 1, 0), + "swapLineDown", val("2\n1\n3"), hasSel(1, 1, 2, 0), + "swapLineUp", val("1\n2\n3"), hasSel(0, 1, 1, 0), + "swapLineUp", val("1\n2\n3"), hasSel(0, 0, 0, 0)); + + stTest("swapLineUpFromEnd", "a\nb\nc", + Pos(2, 1), "swapLineUp", + hasSel(1, 1, 1, 1), val("a\nc\nb")); + + stTest("joinLines", "abc\ndef\nghi\njkl", + "joinLines", val("abc def\nghi\njkl"), at(0, 4), + "undo", + setSel(0, 2, 1, 1), "joinLines", + val("abc def ghi\njkl"), hasSel(0, 2, 0, 8), + "undo", + setSel(0, 1, 0, 1, + 1, 1, 1, 1, + 3, 1, 3, 1), "joinLines", + val("abc def ghi\njkl"), hasSel(0, 4, 0, 4, + 0, 8, 0, 8, + 1, 3, 1, 3)); + + stTest("duplicateLine", "abc\ndef\nghi", + Pos(1, 0), "duplicateLine", val("abc\ndef\ndef\nghi"), at(2, 0), + "undo", + setSel(0, 1, 0, 1, + 1, 1, 1, 1, + 2, 1, 2, 1), "duplicateLine", + val("abc\nabc\ndef\ndef\nghi\nghi"), hasSel(1, 1, 1, 1, + 3, 1, 3, 1, + 5, 1, 5, 1)); + stTest("duplicateLineSelection", "abcdef", + setSel(0, 1, 0, 1, + 0, 2, 0, 4, + 0, 5, 0, 5), + "duplicateLine", + val("abcdef\nabcdcdef\nabcdcdef"), hasSel(2, 1, 2, 1, + 2, 4, 2, 6, + 2, 7, 2, 7)); + + stTest("selectLinesUpward", "123\n345\n789\n012", + setSel(0, 1, 0, 1, + 1, 1, 1, 3, + 2, 0, 2, 0, + 3, 0, 3, 0), + "selectLinesUpward", + hasSel(0, 1, 0, 1, + 0, 3, 0, 3, + 1, 0, 1, 0, + 1, 1, 1, 3, + 2, 0, 2, 0, + 3, 0, 3, 0)); + + stTest("selectLinesDownward", "123\n345\n789\n012", + setSel(0, 1, 0, 1, + 1, 1, 1, 3, + 2, 0, 2, 0, + 3, 0, 3, 0), + "selectLinesDownward", + hasSel(0, 1, 0, 1, + 1, 1, 1, 3, + 2, 0, 2, 0, + 2, 3, 2, 3, + 3, 0, 3, 0)); + + stTest("sortLines", "c\nb\na\nC\nB\nA", + "sortLines", val("A\nB\nC\na\nb\nc"), + "undo", + setSel(0, 0, 2, 0, + 3, 0, 5, 0), + "sortLines", val("b\nc\na\nB\nC\nA"), + hasSel(0, 0, 2, 0, + 3, 0, 5, 0), + "undo", + setSel(1, 0, 5, 0), "sortLinesInsensitive", val("c\na\nB\nb\nC\nA")); + + stTest("bookmarks", "abc\ndef\nghi\njkl", + Pos(0, 1), "toggleBookmark", + setSel(1, 1, 1, 2), "toggleBookmark", + setSel(2, 1, 2, 2), "toggleBookmark", + "nextBookmark", hasSel(0, 1, 0, 1), + "nextBookmark", hasSel(1, 1, 1, 2), + "nextBookmark", hasSel(2, 1, 2, 2), + "prevBookmark", hasSel(1, 1, 1, 2), + "prevBookmark", hasSel(0, 1, 0, 1), + "prevBookmark", hasSel(2, 1, 2, 2), + "prevBookmark", hasSel(1, 1, 1, 2), + "toggleBookmark", + "prevBookmark", hasSel(2, 1, 2, 2), + "prevBookmark", hasSel(0, 1, 0, 1), + "selectBookmarks", hasSel(0, 1, 0, 1, + 2, 1, 2, 2), + "clearBookmarks", + Pos(0, 0), "selectBookmarks", at(0, 0)); + + stTest("smartBackspace", " foo\n bar", + setSel(0, 2, 0, 2, 1, 4, 1, 4, 1, 6, 1, 6), "smartBackspace", + val("foo\n br")) + + stTest("upAndDowncaseAtCursor", "abc\ndef x\nghI", + setSel(0, 1, 0, 3, + 1, 1, 1, 1, + 1, 4, 1, 4), "upcaseAtCursor", + val("aBC\nDEF x\nghI"), hasSel(0, 1, 0, 3, + 1, 3, 1, 3, + 1, 4, 1, 4), + "downcaseAtCursor", + val("abc\ndef x\nghI"), hasSel(0, 1, 0, 3, + 1, 3, 1, 3, + 1, 4, 1, 4)); + + stTest("mark", "abc\ndef\nghi", + Pos(1, 1), "setSublimeMark", + Pos(2, 1), "selectToSublimeMark", hasSel(2, 1, 1, 1), + Pos(0, 1), "swapWithSublimeMark", at(1, 1), "swapWithSublimeMark", at(0, 1), + "deleteToSublimeMark", val("aef\nghi"), + "sublimeYank", val("abc\ndef\nghi"), at(1, 1)); + + stTest("findUnder", "foo foobar a", + "findUnder", hasSel(0, 4, 0, 7), + "findUnder", hasSel(0, 0, 0, 3), + "findUnderPrevious", hasSel(0, 4, 0, 7), + "findUnderPrevious", hasSel(0, 0, 0, 3), + Pos(0, 4), "findUnder", hasSel(0, 4, 0, 10), + Pos(0, 11), "findUnder", hasSel(0, 11, 0, 11)); +})(); diff --git a/backend/webif/static/codemirror/test/test.js b/backend/webif/static/codemirror/test/test.js new file mode 100755 index 000000000..415dd9f0b --- /dev/null +++ b/backend/webif/static/codemirror/test/test.js @@ -0,0 +1,2550 @@ +var Pos = CodeMirror.Pos; + +CodeMirror.defaults.rtlMoveVisually = true; + +function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i], i); +} + +function addDoc(cm, width, height) { + var content = [], line = ""; + for (var i = 0; i < width; ++i) line += "x"; + for (var i = 0; i < height; ++i) content.push(line); + cm.setValue(content.join("\n")); +} + +function byClassName(elt, cls) { + if (elt.getElementsByClassName) return elt.getElementsByClassName(cls); + var found = [], re = new RegExp("\\b" + cls + "\\b"); + function search(elt) { + if (elt.nodeType == 3) return; + if (re.test(elt.className)) found.push(elt); + for (var i = 0, e = elt.childNodes.length; i < e; ++i) + search(elt.childNodes[i]); + } + search(elt); + return found; +} + +var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent); +var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent); +var mac = /Mac/.test(navigator.platform); +var phantom = /PhantomJS/.test(navigator.userAgent); +var opera = /Opera\/\./.test(navigator.userAgent); +var opera_version = opera && navigator.userAgent.match(/Version\/(\d+\.\d+)/); +if (opera_version) opera_version = Number(opera_version); +var opera_lt10 = opera && (!opera_version || opera_version < 10); + +namespace = "core_"; + +test("core_fromTextArea", function() { + var te = document.getElementById("code"); + te.value = "CONTENT"; + var cm = CodeMirror.fromTextArea(te); + is(!te.offsetHeight); + eq(cm.getValue(), "CONTENT"); + cm.setValue("foo\nbar"); + eq(cm.getValue(), "foo\nbar"); + cm.save(); + is(/^foo\r?\nbar$/.test(te.value)); + cm.setValue("xxx"); + cm.toTextArea(); + is(te.offsetHeight); + eq(te.value, "xxx"); +}); + +testCM("getRange", function(cm) { + eq(cm.getLine(0), "1234"); + eq(cm.getLine(1), "5678"); + eq(cm.getLine(2), null); + eq(cm.getLine(-1), null); + eq(cm.getRange(Pos(0, 0), Pos(0, 3)), "123"); + eq(cm.getRange(Pos(0, -1), Pos(0, 200)), "1234"); + eq(cm.getRange(Pos(0, 2), Pos(1, 2)), "34\n56"); + eq(cm.getRange(Pos(1, 2), Pos(100, 0)), "78"); +}, {value: "1234\n5678"}); + +testCM("replaceRange", function(cm) { + eq(cm.getValue(), ""); + cm.replaceRange("foo\n", Pos(0, 0)); + eq(cm.getValue(), "foo\n"); + cm.replaceRange("a\nb", Pos(0, 1)); + eq(cm.getValue(), "fa\nboo\n"); + eq(cm.lineCount(), 3); + cm.replaceRange("xyzzy", Pos(0, 0), Pos(1, 1)); + eq(cm.getValue(), "xyzzyoo\n"); + cm.replaceRange("abc", Pos(0, 0), Pos(10, 0)); + eq(cm.getValue(), "abc"); + eq(cm.lineCount(), 1); +}); + +testCM("selection", function(cm) { + cm.setSelection(Pos(0, 4), Pos(2, 2)); + is(cm.somethingSelected()); + eq(cm.getSelection(), "11\n222222\n33"); + eqCursorPos(cm.getCursor(false), Pos(2, 2)); + eqCursorPos(cm.getCursor(true), Pos(0, 4)); + cm.setSelection(Pos(1, 0)); + is(!cm.somethingSelected()); + eq(cm.getSelection(), ""); + eqCursorPos(cm.getCursor(true), Pos(1, 0)); + cm.replaceSelection("abc", "around"); + eq(cm.getSelection(), "abc"); + eq(cm.getValue(), "111111\nabc222222\n333333"); + cm.replaceSelection("def", "end"); + eq(cm.getSelection(), ""); + eqCursorPos(cm.getCursor(true), Pos(1, 3)); + cm.setCursor(Pos(2, 1)); + eqCursorPos(cm.getCursor(true), Pos(2, 1)); + cm.setCursor(1, 2); + eqCursorPos(cm.getCursor(true), Pos(1, 2)); +}, {value: "111111\n222222\n333333"}); + +testCM("extendSelection", function(cm) { + cm.setExtending(true); + addDoc(cm, 10, 10); + cm.setSelection(Pos(3, 5)); + eqCursorPos(cm.getCursor("head"), Pos(3, 5)); + eqCursorPos(cm.getCursor("anchor"), Pos(3, 5)); + cm.setSelection(Pos(2, 5), Pos(5, 5)); + eqCursorPos(cm.getCursor("head"), Pos(5, 5)); + eqCursorPos(cm.getCursor("anchor"), Pos(2, 5)); + eqCursorPos(cm.getCursor("start"), Pos(2, 5)); + eqCursorPos(cm.getCursor("end"), Pos(5, 5)); + cm.setSelection(Pos(5, 5), Pos(2, 5)); + eqCursorPos(cm.getCursor("head"), Pos(2, 5)); + eqCursorPos(cm.getCursor("anchor"), Pos(5, 5)); + eqCursorPos(cm.getCursor("start"), Pos(2, 5)); + eqCursorPos(cm.getCursor("end"), Pos(5, 5)); + cm.extendSelection(Pos(3, 2)); + eqCursorPos(cm.getCursor("head"), Pos(3, 2)); + eqCursorPos(cm.getCursor("anchor"), Pos(5, 5)); + cm.extendSelection(Pos(6, 2)); + eqCursorPos(cm.getCursor("head"), Pos(6, 2)); + eqCursorPos(cm.getCursor("anchor"), Pos(5, 5)); + cm.extendSelection(Pos(6, 3), Pos(6, 4)); + eqCursorPos(cm.getCursor("head"), Pos(6, 4)); + eqCursorPos(cm.getCursor("anchor"), Pos(5, 5)); + cm.extendSelection(Pos(0, 3), Pos(0, 4)); + eqCursorPos(cm.getCursor("head"), Pos(0, 3)); + eqCursorPos(cm.getCursor("anchor"), Pos(5, 5)); + cm.extendSelection(Pos(4, 5), Pos(6, 5)); + eqCursorPos(cm.getCursor("head"), Pos(6, 5)); + eqCursorPos(cm.getCursor("anchor"), Pos(4, 5)); + cm.setExtending(false); + cm.extendSelection(Pos(0, 3), Pos(0, 4)); + eqCursorPos(cm.getCursor("head"), Pos(0, 3)); + eqCursorPos(cm.getCursor("anchor"), Pos(0, 4)); +}); + +testCM("lines", function(cm) { + eq(cm.getLine(0), "111111"); + eq(cm.getLine(1), "222222"); + eq(cm.getLine(-1), null); + cm.replaceRange("", Pos(1, 0), Pos(2, 0)) + cm.replaceRange("abc", Pos(1, 0), Pos(1)); + eq(cm.getValue(), "111111\nabc"); +}, {value: "111111\n222222\n333333"}); + +testCM("indent", function(cm) { + cm.indentLine(1); + eq(cm.getLine(1), " blah();"); + cm.setOption("indentUnit", 8); + cm.indentLine(1); + eq(cm.getLine(1), "\tblah();"); + cm.setOption("indentUnit", 10); + cm.setOption("tabSize", 4); + cm.indentLine(1); + eq(cm.getLine(1), "\t\t blah();"); +}, {value: "if (x) {\nblah();\n}", indentUnit: 3, indentWithTabs: true, tabSize: 8}); + +testCM("indentByNumber", function(cm) { + cm.indentLine(0, 2); + eq(cm.getLine(0), " foo"); + cm.indentLine(0, -200); + eq(cm.getLine(0), "foo"); + cm.setSelection(Pos(0, 0), Pos(1, 2)); + cm.indentSelection(3); + eq(cm.getValue(), " foo\n bar\nbaz"); +}, {value: "foo\nbar\nbaz"}); + +test("core_defaults", function() { + var defsCopy = {}, defs = CodeMirror.defaults; + for (var opt in defs) defsCopy[opt] = defs[opt]; + defs.indentUnit = 5; + defs.value = "uu"; + defs.indentWithTabs = true; + defs.tabindex = 55; + var place = document.getElementById("testground"), cm = CodeMirror(place); + try { + eq(cm.getOption("indentUnit"), 5); + cm.setOption("indentUnit", 10); + eq(defs.indentUnit, 5); + eq(cm.getValue(), "uu"); + eq(cm.getOption("indentWithTabs"), true); + eq(cm.getInputField().tabIndex, 55); + } + finally { + for (var opt in defsCopy) defs[opt] = defsCopy[opt]; + place.removeChild(cm.getWrapperElement()); + } +}); + +testCM("lineInfo", function(cm) { + eq(cm.lineInfo(-1), null); + var mark = document.createElement("span"); + var lh = cm.setGutterMarker(1, "FOO", mark); + var info = cm.lineInfo(1); + eq(info.text, "222222"); + eq(info.gutterMarkers.FOO, mark); + eq(info.line, 1); + eq(cm.lineInfo(2).gutterMarkers, null); + cm.setGutterMarker(lh, "FOO", null); + eq(cm.lineInfo(1).gutterMarkers, null); + cm.setGutterMarker(1, "FOO", mark); + cm.setGutterMarker(0, "FOO", mark); + cm.clearGutter("FOO"); + eq(cm.lineInfo(0).gutterMarkers, null); + eq(cm.lineInfo(1).gutterMarkers, null); +}, {value: "111111\n222222\n333333"}); + +testCM("coords", function(cm) { + cm.setSize(null, 100); + addDoc(cm, 32, 200); + var top = cm.charCoords(Pos(0, 0)); + var bot = cm.charCoords(Pos(200, 30)); + is(top.left < bot.left); + is(top.top < bot.top); + is(top.top < top.bottom); + cm.scrollTo(null, 100); + var top2 = cm.charCoords(Pos(0, 0)); + is(top.top > top2.top); + eq(top.left, top2.left); +}); + +testCM("coordsChar", function(cm) { + addDoc(cm, 35, 70); + for (var i = 0; i < 2; ++i) { + var sys = i ? "local" : "page"; + for (var ch = 0; ch <= 35; ch += 5) { + for (var line = 0; line < 70; line += 5) { + cm.setCursor(line, ch); + var coords = cm.charCoords(Pos(line, ch), sys); + var pos = cm.coordsChar({left: coords.left + 1, top: coords.top + 1}, sys); + eqCharPos(pos, Pos(line, ch)); + } + } + } +}, {lineNumbers: true}); + +testCM("coordsCharBidi", function(cm) { + addDoc(cm, 35, 70); + // Put an rtl character into each line to trigger the bidi code path in coordsChar + cm.setValue(cm.getValue().replace(/\bx/g, 'و')) + for (var i = 0; i < 2; ++i) { + var sys = i ? "local" : "page"; + for (var ch = 2; ch <= 35; ch += 5) { + for (var line = 0; line < 70; line += 5) { + cm.setCursor(line, ch); + var coords = cm.charCoords(Pos(line, ch), sys); + var pos = cm.coordsChar({left: coords.left + 1, top: coords.top + 1}, sys); + eqCharPos(pos, Pos(line, ch)); + } + } + } +}, {lineNumbers: true}); + +testCM("badBidiOptimization", function(cm) { + var coords = cm.charCoords(Pos(0, 34)) + eqCharPos(cm.coordsChar({left: coords.right, top: coords.top + 2}), Pos(0, 34)) +}, {value: "----------

    هل يمكنك اختيار مستوى قسط التأمين الذي ترغب بدفعه؟

    "}) + +testCM("posFromIndex", function(cm) { + cm.setValue( + "This function should\n" + + "convert a zero based index\n" + + "to line and ch." + ); + + var examples = [ + { index: -1, line: 0, ch: 0 }, // <- Tests clipping + { index: 0, line: 0, ch: 0 }, + { index: 10, line: 0, ch: 10 }, + { index: 39, line: 1, ch: 18 }, + { index: 55, line: 2, ch: 7 }, + { index: 63, line: 2, ch: 15 }, + { index: 64, line: 2, ch: 15 } // <- Tests clipping + ]; + + for (var i = 0; i < examples.length; i++) { + var example = examples[i]; + var pos = cm.posFromIndex(example.index); + eq(pos.line, example.line); + eq(pos.ch, example.ch); + if (example.index >= 0 && example.index < 64) + eq(cm.indexFromPos(pos), example.index); + } +}); + +testCM("undo", function(cm) { + cm.replaceRange("def", Pos(0, 0), Pos(0)); + eq(cm.historySize().undo, 1); + cm.undo(); + eq(cm.getValue(), "abc"); + eq(cm.historySize().undo, 0); + eq(cm.historySize().redo, 1); + cm.redo(); + eq(cm.getValue(), "def"); + eq(cm.historySize().undo, 1); + eq(cm.historySize().redo, 0); + cm.setValue("1\n\n\n2"); + cm.clearHistory(); + eq(cm.historySize().undo, 0); + for (var i = 0; i < 20; ++i) { + cm.replaceRange("a", Pos(0, 0)); + cm.replaceRange("b", Pos(3, 0)); + } + eq(cm.historySize().undo, 40); + for (var i = 0; i < 40; ++i) + cm.undo(); + eq(cm.historySize().redo, 40); + eq(cm.getValue(), "1\n\n\n2"); +}, {value: "abc"}); + +testCM("undoDepth", function(cm) { + cm.replaceRange("d", Pos(0)); + cm.replaceRange("e", Pos(0)); + cm.replaceRange("f", Pos(0)); + cm.undo(); cm.undo(); cm.undo(); + eq(cm.getValue(), "abcd"); +}, {value: "abc", undoDepth: 4}); + +testCM("undoDoesntClearValue", function(cm) { + cm.undo(); + eq(cm.getValue(), "x"); +}, {value: "x"}); + +testCM("undoMultiLine", function(cm) { + cm.operation(function() { + cm.replaceRange("x", Pos(0, 0)); + cm.replaceRange("y", Pos(1, 0)); + }); + cm.undo(); + eq(cm.getValue(), "abc\ndef\nghi"); + cm.operation(function() { + cm.replaceRange("y", Pos(1, 0)); + cm.replaceRange("x", Pos(0, 0)); + }); + cm.undo(); + eq(cm.getValue(), "abc\ndef\nghi"); + cm.operation(function() { + cm.replaceRange("y", Pos(2, 0)); + cm.replaceRange("x", Pos(1, 0)); + cm.replaceRange("z", Pos(2, 0)); + }); + cm.undo(); + eq(cm.getValue(), "abc\ndef\nghi", 3); +}, {value: "abc\ndef\nghi"}); + +testCM("undoComposite", function(cm) { + cm.replaceRange("y", Pos(1)); + cm.operation(function() { + cm.replaceRange("x", Pos(0)); + cm.replaceRange("z", Pos(2)); + }); + eq(cm.getValue(), "ax\nby\ncz\n"); + cm.undo(); + eq(cm.getValue(), "a\nby\nc\n"); + cm.undo(); + eq(cm.getValue(), "a\nb\nc\n"); + cm.redo(); cm.redo(); + eq(cm.getValue(), "ax\nby\ncz\n"); +}, {value: "a\nb\nc\n"}); + +testCM("undoSelection", function(cm) { + cm.setSelection(Pos(0, 2), Pos(0, 4)); + cm.replaceSelection(""); + cm.setCursor(Pos(1, 0)); + cm.undo(); + eqCursorPos(cm.getCursor(true), Pos(0, 2)); + eqCursorPos(cm.getCursor(false), Pos(0, 4)); + cm.setCursor(Pos(1, 0)); + cm.redo(); + eqCursorPos(cm.getCursor(true), Pos(0, 2)); + eqCursorPos(cm.getCursor(false), Pos(0, 2)); +}, {value: "abcdefgh\n"}); + +testCM("undoSelectionAsBefore", function(cm) { + cm.replaceSelection("abc", "around"); + cm.undo(); + cm.redo(); + eq(cm.getSelection(), "abc"); +}); + +testCM("selectionChangeConfusesHistory", function(cm) { + cm.replaceSelection("abc", null, "dontmerge"); + cm.operation(function() { + cm.setCursor(Pos(0, 0)); + cm.replaceSelection("abc", null, "dontmerge"); + }); + eq(cm.historySize().undo, 2); +}); + +testCM("markTextSingleLine", function(cm) { + forEach([{a: 0, b: 1, c: "", f: 2, t: 5}, + {a: 0, b: 4, c: "", f: 0, t: 2}, + {a: 1, b: 2, c: "x", f: 3, t: 6}, + {a: 4, b: 5, c: "", f: 3, t: 5}, + {a: 4, b: 5, c: "xx", f: 3, t: 7}, + {a: 2, b: 5, c: "", f: 2, t: 3}, + {a: 2, b: 5, c: "abcd", f: 6, t: 7}, + {a: 2, b: 6, c: "x", f: null, t: null}, + {a: 3, b: 6, c: "", f: null, t: null}, + {a: 0, b: 9, c: "hallo", f: null, t: null}, + {a: 4, b: 6, c: "x", f: 3, t: 4}, + {a: 4, b: 8, c: "", f: 3, t: 4}, + {a: 6, b: 6, c: "a", f: 3, t: 6}, + {a: 8, b: 9, c: "", f: 3, t: 6}], function(test) { + cm.setValue("1234567890"); + var r = cm.markText(Pos(0, 3), Pos(0, 6), {className: "foo"}); + cm.replaceRange(test.c, Pos(0, test.a), Pos(0, test.b)); + var f = r.find(); + eq(f && f.from.ch, test.f); eq(f && f.to.ch, test.t); + }); +}); + +testCM("markTextMultiLine", function(cm) { + function p(v) { return v && Pos(v[0], v[1]); } + forEach([{a: [0, 0], b: [0, 5], c: "", f: [0, 0], t: [2, 5]}, + {a: [0, 0], b: [0, 5], c: "foo\n", f: [1, 0], t: [3, 5]}, + {a: [0, 1], b: [0, 10], c: "", f: [0, 1], t: [2, 5]}, + {a: [0, 5], b: [0, 6], c: "x", f: [0, 6], t: [2, 5]}, + {a: [0, 0], b: [1, 0], c: "", f: [0, 0], t: [1, 5]}, + {a: [0, 6], b: [2, 4], c: "", f: [0, 5], t: [0, 7]}, + {a: [0, 6], b: [2, 4], c: "aa", f: [0, 5], t: [0, 9]}, + {a: [1, 2], b: [1, 8], c: "", f: [0, 5], t: [2, 5]}, + {a: [0, 5], b: [2, 5], c: "xx", f: null, t: null}, + {a: [0, 0], b: [2, 10], c: "x", f: null, t: null}, + {a: [1, 5], b: [2, 5], c: "", f: [0, 5], t: [1, 5]}, + {a: [2, 0], b: [2, 3], c: "", f: [0, 5], t: [2, 2]}, + {a: [2, 5], b: [3, 0], c: "a\nb", f: [0, 5], t: [2, 5]}, + {a: [2, 3], b: [3, 0], c: "x", f: [0, 5], t: [2, 3]}, + {a: [1, 1], b: [1, 9], c: "1\n2\n3", f: [0, 5], t: [4, 5]}], function(test) { + cm.setValue("aaaaaaaaaa\nbbbbbbbbbb\ncccccccccc\ndddddddd\n"); + var r = cm.markText(Pos(0, 5), Pos(2, 5), + {className: "CodeMirror-matchingbracket"}); + cm.replaceRange(test.c, p(test.a), p(test.b)); + var f = r.find(); + eqCursorPos(f && f.from, p(test.f)); eqCursorPos(f && f.to, p(test.t)); + }); +}); + +testCM("markTextUndo", function(cm) { + var marker1, marker2, bookmark; + marker1 = cm.markText(Pos(0, 1), Pos(0, 3), + {className: "CodeMirror-matchingbracket"}); + marker2 = cm.markText(Pos(0, 0), Pos(2, 1), + {className: "CodeMirror-matchingbracket"}); + bookmark = cm.setBookmark(Pos(1, 5)); + cm.operation(function(){ + cm.replaceRange("foo", Pos(0, 2)); + cm.replaceRange("bar\nbaz\nbug\n", Pos(2, 0), Pos(3, 0)); + }); + var v1 = cm.getValue(); + cm.setValue(""); + eq(marker1.find(), null); eq(marker2.find(), null); eq(bookmark.find(), null); + cm.undo(); + eqCursorPos(bookmark.find(), Pos(1, 5), "still there"); + cm.undo(); + var m1Pos = marker1.find(), m2Pos = marker2.find(); + eqCursorPos(m1Pos.from, Pos(0, 1)); eqCursorPos(m1Pos.to, Pos(0, 3)); + eqCursorPos(m2Pos.from, Pos(0, 0)); eqCursorPos(m2Pos.to, Pos(2, 1)); + eqCursorPos(bookmark.find(), Pos(1, 5)); + cm.redo(); cm.redo(); + eq(bookmark.find(), null); + cm.undo(); + eqCursorPos(bookmark.find(), Pos(1, 5)); + eq(cm.getValue(), v1); +}, {value: "1234\n56789\n00\n"}); + +testCM("markTextStayGone", function(cm) { + var m1 = cm.markText(Pos(0, 0), Pos(0, 1)); + cm.replaceRange("hi", Pos(0, 2)); + m1.clear(); + cm.undo(); + eq(m1.find(), null); +}, {value: "hello"}); + +testCM("markTextAllowEmpty", function(cm) { + var m1 = cm.markText(Pos(0, 1), Pos(0, 2), {clearWhenEmpty: false}); + is(m1.find()); + cm.replaceRange("x", Pos(0, 0)); + is(m1.find()); + cm.replaceRange("y", Pos(0, 2)); + is(m1.find()); + cm.replaceRange("z", Pos(0, 3), Pos(0, 4)); + is(!m1.find()); + var m2 = cm.markText(Pos(0, 1), Pos(0, 2), {clearWhenEmpty: false, + inclusiveLeft: true, + inclusiveRight: true}); + cm.replaceRange("q", Pos(0, 1), Pos(0, 2)); + is(m2.find()); + cm.replaceRange("", Pos(0, 0), Pos(0, 3)); + is(!m2.find()); + var m3 = cm.markText(Pos(0, 1), Pos(0, 1), {clearWhenEmpty: false}); + cm.replaceRange("a", Pos(0, 3)); + is(m3.find()); + cm.replaceRange("b", Pos(0, 1)); + is(!m3.find()); +}, {value: "abcde"}); + +testCM("markTextStacked", function(cm) { + var m1 = cm.markText(Pos(0, 0), Pos(0, 0), {clearWhenEmpty: false}); + var m2 = cm.markText(Pos(0, 0), Pos(0, 0), {clearWhenEmpty: false}); + cm.replaceRange("B", Pos(0, 1)); + is(m1.find() && m2.find()); +}, {value: "A"}); + +testCM("undoPreservesNewMarks", function(cm) { + cm.markText(Pos(0, 3), Pos(0, 4)); + cm.markText(Pos(1, 1), Pos(1, 3)); + cm.replaceRange("", Pos(0, 3), Pos(3, 1)); + var mBefore = cm.markText(Pos(0, 0), Pos(0, 1)); + var mAfter = cm.markText(Pos(0, 5), Pos(0, 6)); + var mAround = cm.markText(Pos(0, 2), Pos(0, 4)); + cm.undo(); + eqCursorPos(mBefore.find().from, Pos(0, 0)); + eqCursorPos(mBefore.find().to, Pos(0, 1)); + eqCursorPos(mAfter.find().from, Pos(3, 3)); + eqCursorPos(mAfter.find().to, Pos(3, 4)); + eqCursorPos(mAround.find().from, Pos(0, 2)); + eqCursorPos(mAround.find().to, Pos(3, 2)); + var found = cm.findMarksAt(Pos(2, 2)); + eq(found.length, 1); + eq(found[0], mAround); +}, {value: "aaaa\nbbbb\ncccc\ndddd"}); + +testCM("markClearBetween", function(cm) { + cm.setValue("aaa\nbbb\nccc\nddd\n"); + cm.markText(Pos(0, 0), Pos(2)); + cm.replaceRange("aaa\nbbb\nccc", Pos(0, 0), Pos(2)); + eq(cm.findMarksAt(Pos(1, 1)).length, 0); +}); + +testCM("findMarksMiddle", function(cm) { + var mark = cm.markText(Pos(1, 1), Pos(3, 1)); + var found = cm.findMarks(Pos(2, 1), Pos(2, 2)); + eq(found.length, 1); + eq(found[0], mark); +}, {value: "line 0\nline 1\nline 2\nline 3"}); + +testCM("deleteSpanCollapsedInclusiveLeft", function(cm) { + var from = Pos(1, 0), to = Pos(1, 1); + var m = cm.markText(from, to, {collapsed: true, inclusiveLeft: true}); + // Delete collapsed span. + cm.replaceRange("", from, to); +}, {value: "abc\nX\ndef"}); + +testCM("markTextCSS", function(cm) { + function present() { + var spans = cm.display.lineDiv.getElementsByTagName("span"); + for (var i = 0; i < spans.length; i++) + if (spans[i].style.color == "cyan" && span[i].textContent == "cdefg") return true; + } + var m = cm.markText(Pos(0, 2), Pos(0, 6), {css: "color: cyan"}); + m.clear(); + is(!present()); +}, {value: "abcdefgh"}); + +testCM("bookmark", function(cm) { + function p(v) { return v && Pos(v[0], v[1]); } + forEach([{a: [1, 0], b: [1, 1], c: "", d: [1, 4]}, + {a: [1, 1], b: [1, 1], c: "xx", d: [1, 7]}, + {a: [1, 4], b: [1, 5], c: "ab", d: [1, 6]}, + {a: [1, 4], b: [1, 6], c: "", d: null}, + {a: [1, 5], b: [1, 6], c: "abc", d: [1, 5]}, + {a: [1, 6], b: [1, 8], c: "", d: [1, 5]}, + {a: [1, 4], b: [1, 4], c: "\n\n", d: [3, 1]}, + {bm: [1, 9], a: [1, 1], b: [1, 1], c: "\n", d: [2, 8]}], function(test) { + cm.setValue("1234567890\n1234567890\n1234567890"); + var b = cm.setBookmark(p(test.bm) || Pos(1, 5)); + cm.replaceRange(test.c, p(test.a), p(test.b)); + eqCursorPos(b.find(), p(test.d)); + }); +}); + +testCM("bookmarkInsertLeft", function(cm) { + var br = cm.setBookmark(Pos(0, 2), {insertLeft: false}); + var bl = cm.setBookmark(Pos(0, 2), {insertLeft: true}); + cm.setCursor(Pos(0, 2)); + cm.replaceSelection("hi"); + eqCursorPos(br.find(), Pos(0, 2)); + eqCursorPos(bl.find(), Pos(0, 4)); + cm.replaceRange("", Pos(0, 4), Pos(0, 5)); + cm.replaceRange("", Pos(0, 2), Pos(0, 4)); + cm.replaceRange("", Pos(0, 1), Pos(0, 2)); + // Verify that deleting next to bookmarks doesn't kill them + eqCursorPos(br.find(), Pos(0, 1)); + eqCursorPos(bl.find(), Pos(0, 1)); +}, {value: "abcdef"}); + +testCM("bookmarkCursor", function(cm) { + var pos01 = cm.cursorCoords(Pos(0, 1)), pos11 = cm.cursorCoords(Pos(1, 1)), + pos20 = cm.cursorCoords(Pos(2, 0)), pos30 = cm.cursorCoords(Pos(3, 0)), + pos41 = cm.cursorCoords(Pos(4, 1)); + cm.setBookmark(Pos(0, 1), {widget: document.createTextNode("←"), insertLeft: true}); + cm.setBookmark(Pos(2, 0), {widget: document.createTextNode("←"), insertLeft: true}); + cm.setBookmark(Pos(1, 1), {widget: document.createTextNode("→")}); + cm.setBookmark(Pos(3, 0), {widget: document.createTextNode("→")}); + var new01 = cm.cursorCoords(Pos(0, 1)), new11 = cm.cursorCoords(Pos(1, 1)), + new20 = cm.cursorCoords(Pos(2, 0)), new30 = cm.cursorCoords(Pos(3, 0)); + near(new01.left, pos01.left, 1); + near(new01.top, pos01.top, 1); + is(new11.left > pos11.left, "at right, middle of line"); + near(new11.top == pos11.top, 1); + near(new20.left, pos20.left, 1); + near(new20.top, pos20.top, 1); + is(new30.left > pos30.left, "at right, empty line"); + near(new30.top, pos30, 1); + cm.setBookmark(Pos(4, 0), {widget: document.createTextNode("→")}); + is(cm.cursorCoords(Pos(4, 1)).left > pos41.left, "single-char bug"); +}, {value: "foo\nbar\n\n\nx\ny"}); + +testCM("multiBookmarkCursor", function(cm) { + if (phantom) return; + var ms = [], m; + function add(insertLeft) { + for (var i = 0; i < 3; ++i) { + var node = document.createElement("span"); + node.innerHTML = "X"; + ms.push(cm.setBookmark(Pos(0, 1), {widget: node, insertLeft: insertLeft})); + } + } + var base1 = cm.cursorCoords(Pos(0, 1)).left, base4 = cm.cursorCoords(Pos(0, 4)).left; + add(true); + near(base1, cm.cursorCoords(Pos(0, 1)).left, 1); + while (m = ms.pop()) m.clear(); + add(false); + near(base4, cm.cursorCoords(Pos(0, 1)).left, 1); +}, {value: "abcdefg"}); + +testCM("getAllMarks", function(cm) { + addDoc(cm, 10, 10); + var m1 = cm.setBookmark(Pos(0, 2)); + var m2 = cm.markText(Pos(0, 2), Pos(3, 2)); + var m3 = cm.markText(Pos(1, 2), Pos(1, 8)); + var m4 = cm.markText(Pos(8, 0), Pos(9, 0)); + eq(cm.getAllMarks().length, 4); + m1.clear(); + m3.clear(); + eq(cm.getAllMarks().length, 2); +}); + +testCM("setValueClears", function(cm) { + cm.addLineClass(0, "wrap", "foo"); + var mark = cm.markText(Pos(0, 0), Pos(1, 1), {inclusiveLeft: true, inclusiveRight: true}); + cm.setValue("foo"); + is(!cm.lineInfo(0).wrapClass); + is(!mark.find()); +}, {value: "a\nb"}); + +testCM("bug577", function(cm) { + cm.setValue("a\nb"); + cm.clearHistory(); + cm.setValue("fooooo"); + cm.undo(); +}); + +testCM("scrollSnap", function(cm) { + cm.setSize(100, 100); + addDoc(cm, 200, 200); + cm.setCursor(Pos(100, 180)); + var info = cm.getScrollInfo(); + is(info.left > 0 && info.top > 0); + cm.setCursor(Pos(0, 0)); + info = cm.getScrollInfo(); + is(info.left == 0 && info.top == 0, "scrolled clean to top"); + cm.setCursor(Pos(100, 180)); + cm.setCursor(Pos(199, 0)); + info = cm.getScrollInfo(); + is(info.left == 0 && info.top + 2 > info.height - cm.getScrollerElement().clientHeight, "scrolled clean to bottom"); +}); + +testCM("scrollIntoView", function(cm) { + if (phantom) return; + function test(line, ch, msg) { + var pos = Pos(line, ch); + cm.scrollIntoView(pos); + var outer = cm.getWrapperElement().getBoundingClientRect(); + var box = cm.charCoords(pos, "window"); + is(box.left >= outer.left, msg + " (left)"); + is(box.right <= outer.right, msg + " (right)"); + is(box.top >= outer.top, msg + " (top)"); + is(box.bottom <= outer.bottom, msg + " (bottom)"); + } + addDoc(cm, 200, 200); + test(199, 199, "bottom right"); + test(0, 0, "top left"); + test(100, 100, "center"); + test(199, 0, "bottom left"); + test(0, 199, "top right"); + test(100, 100, "center again"); +}); + +testCM("scrollBackAndForth", function(cm) { + addDoc(cm, 1, 200); + cm.operation(function() { + cm.scrollIntoView(Pos(199, 0)); + cm.scrollIntoView(Pos(4, 0)); + }); + is(cm.getScrollInfo().top > 0); +}); + +testCM("selectAllNoScroll", function(cm) { + addDoc(cm, 1, 200); + cm.execCommand("selectAll"); + eq(cm.getScrollInfo().top, 0); + cm.setCursor(199); + cm.execCommand("selectAll"); + is(cm.getScrollInfo().top > 0); +}); + +testCM("selectionPos", function(cm) { + if (phantom || cm.getOption("inputStyle") != "textarea") return; + cm.setSize(100, 100); + addDoc(cm, 200, 100); + cm.setSelection(Pos(1, 100), Pos(98, 100)); + var lineWidth = cm.charCoords(Pos(0, 200), "local").left; + var lineHeight = (cm.charCoords(Pos(99)).top - cm.charCoords(Pos(0)).top) / 100; + cm.scrollTo(0, 0); + var selElt = byClassName(cm.getWrapperElement(), "CodeMirror-selected"); + var outer = cm.getWrapperElement().getBoundingClientRect(); + var sawMiddle, sawTop, sawBottom; + for (var i = 0, e = selElt.length; i < e; ++i) { + var box = selElt[i].getBoundingClientRect(); + var atLeft = box.left - outer.left < 30; + var width = box.right - box.left; + var atRight = box.right - outer.left > .8 * lineWidth; + if (atLeft && atRight) { + sawMiddle = true; + is(box.bottom - box.top > 90 * lineHeight, "middle high"); + is(width > .9 * lineWidth, "middle wide"); + } else { + is(width > .4 * lineWidth, "top/bot wide enough"); + is(width < .6 * lineWidth, "top/bot slim enough"); + if (atLeft) { + sawBottom = true; + is(box.top - outer.top > 96 * lineHeight, "bot below"); + } else if (atRight) { + sawTop = true; + is(box.top - outer.top < 2.1 * lineHeight, "top above"); + } + } + } + is(sawTop && sawBottom && sawMiddle, "all parts"); +}, null); + +testCM("restoreHistory", function(cm) { + cm.setValue("abc\ndef"); + cm.replaceRange("hello", Pos(1, 0), Pos(1)); + cm.replaceRange("goop", Pos(0, 0), Pos(0)); + cm.undo(); + var storedVal = cm.getValue(), storedHist = cm.getHistory(); + if (window.JSON) storedHist = JSON.parse(JSON.stringify(storedHist)); + eq(storedVal, "abc\nhello"); + cm.setValue(""); + cm.clearHistory(); + eq(cm.historySize().undo, 0); + cm.setValue(storedVal); + cm.setHistory(storedHist); + cm.redo(); + eq(cm.getValue(), "goop\nhello"); + cm.undo(); cm.undo(); + eq(cm.getValue(), "abc\ndef"); +}); + +testCM("doubleScrollbar", function(cm) { + var dummy = document.body.appendChild(document.createElement("p")); + dummy.style.cssText = "height: 50px; overflow: scroll; width: 50px"; + var scrollbarWidth = dummy.offsetWidth + 1 - dummy.clientWidth; + document.body.removeChild(dummy); + if (scrollbarWidth < 2) return; + cm.setSize(null, 100); + addDoc(cm, 1, 300); + var wrap = cm.getWrapperElement(); + is(wrap.offsetWidth - byClassName(wrap, "CodeMirror-lines")[0].offsetWidth <= scrollbarWidth * 1.5); +}); + +testCM("weirdLinebreaks", function(cm) { + cm.setValue("foo\nbar\rbaz\r\nquux\n\rplop"); + is(cm.getValue(), "foo\nbar\nbaz\nquux\n\nplop"); + is(cm.lineCount(), 6); + cm.setValue("\n\n"); + is(cm.lineCount(), 3); +}); + +testCM("setSize", function(cm) { + cm.setSize(100, 100); + var wrap = cm.getWrapperElement(); + is(wrap.offsetWidth, 100); + is(wrap.offsetHeight, 100); + cm.setSize("100%", "3em"); + is(wrap.style.width, "100%"); + is(wrap.style.height, "3em"); + cm.setSize(null, 40); + is(wrap.style.width, "100%"); + is(wrap.style.height, "40px"); +}); + +function foldLines(cm, start, end, autoClear) { + return cm.markText(Pos(start, 0), Pos(end - 1), { + inclusiveLeft: true, + inclusiveRight: true, + collapsed: true, + clearOnEnter: autoClear + }); +} + +testCM("collapsedLines", function(cm) { + addDoc(cm, 4, 10); + var range = foldLines(cm, 4, 5), cleared = 0; + CodeMirror.on(range, "clear", function() {cleared++;}); + cm.setCursor(Pos(3, 0)); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(5, 0)); + cm.replaceRange("abcdefg", Pos(3, 0), Pos(3)); + cm.setCursor(Pos(3, 6)); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(5, 4)); + cm.replaceRange("ab", Pos(3, 0), Pos(3)); + cm.setCursor(Pos(3, 2)); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(5, 2)); + cm.operation(function() {range.clear(); range.clear();}); + eq(cleared, 1); +}); + +testCM("collapsedRangeCoordsChar", function(cm) { + var pos_1_3 = cm.charCoords(Pos(1, 3)); + pos_1_3.left += 2; pos_1_3.top += 2; + var opts = {collapsed: true, inclusiveLeft: true, inclusiveRight: true}; + var m1 = cm.markText(Pos(0, 0), Pos(2, 0), opts); + eqCharPos(cm.coordsChar(pos_1_3), Pos(3, 3)); + m1.clear(); + var m1 = cm.markText(Pos(0, 0), Pos(1, 1), {collapsed: true, inclusiveLeft: true}); + var m2 = cm.markText(Pos(1, 1), Pos(2, 0), {collapsed: true, inclusiveRight: true}); + eqCharPos(cm.coordsChar(pos_1_3), Pos(3, 3)); + m1.clear(); m2.clear(); + var m1 = cm.markText(Pos(0, 0), Pos(1, 6), opts); + eqCharPos(cm.coordsChar(pos_1_3), Pos(3, 3)); +}, {value: "123456\nabcdef\nghijkl\nmnopqr\n"}); + +testCM("collapsedRangeBetweenLinesSelected", function(cm) { + if (cm.getOption("inputStyle") != "textarea") return; + var widget = document.createElement("span"); + widget.textContent = "\u2194"; + cm.markText(Pos(0, 3), Pos(1, 0), {replacedWith: widget}); + cm.setSelection(Pos(0, 3), Pos(1, 0)); + var selElts = byClassName(cm.getWrapperElement(), "CodeMirror-selected"); + for (var i = 0, w = 0; i < selElts.length; i++) + w += selElts[i].offsetWidth; + is(w > 0); +}, {value: "one\ntwo"}); + +testCM("randomCollapsedRanges", function(cm) { + addDoc(cm, 20, 500); + cm.operation(function() { + for (var i = 0; i < 200; i++) { + var start = Pos(Math.floor(Math.random() * 500), Math.floor(Math.random() * 20)); + if (i % 4) + try { cm.markText(start, Pos(start.line + 2, 1), {collapsed: true}); } + catch(e) { if (!/overlapping/.test(String(e))) throw e; } + else + cm.markText(start, Pos(start.line, start.ch + 4), {"className": "foo"}); + } + }); +}); + +testCM("hiddenLinesAutoUnfold", function(cm) { + var range = foldLines(cm, 1, 3, true), cleared = 0; + CodeMirror.on(range, "clear", function() {cleared++;}); + cm.setCursor(Pos(3, 0)); + eq(cleared, 0); + cm.execCommand("goCharLeft"); + eq(cleared, 1); + range = foldLines(cm, 1, 3, true); + CodeMirror.on(range, "clear", function() {cleared++;}); + eqCursorPos(cm.getCursor(), Pos(3, 0)); + cm.setCursor(Pos(0, 3)); + cm.execCommand("goCharRight"); + eq(cleared, 2); +}, {value: "abc\ndef\nghi\njkl"}); + +testCM("hiddenLinesSelectAll", function(cm) { // Issue #484 + addDoc(cm, 4, 20); + foldLines(cm, 0, 10); + foldLines(cm, 11, 20); + CodeMirror.commands.selectAll(cm); + eqCursorPos(cm.getCursor(true), Pos(10, 0)); + eqCursorPos(cm.getCursor(false), Pos(10, 4)); +}); + + +testCM("everythingFolded", function(cm) { + addDoc(cm, 2, 2); + function enterPress() { + cm.triggerOnKeyDown({type: "keydown", keyCode: 13, preventDefault: function(){}, stopPropagation: function(){}}); + } + var fold = foldLines(cm, 0, 2); + enterPress(); + eq(cm.getValue(), "xx\nxx"); + fold.clear(); + fold = foldLines(cm, 0, 2, true); + eq(fold.find(), null); + enterPress(); + eq(cm.getValue(), "\nxx\nxx"); +}); + +testCM("structuredFold", function(cm) { + if (phantom) return; + addDoc(cm, 4, 8); + var range = cm.markText(Pos(1, 2), Pos(6, 2), { + replacedWith: document.createTextNode("Q") + }); + cm.setCursor(0, 3); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(6, 2)); + CodeMirror.commands.goCharLeft(cm); + eqCharPos(cm.getCursor(), Pos(1, 2)); + CodeMirror.commands.delCharAfter(cm); + eq(cm.getValue(), "xxxx\nxxxx\nxxxx"); + addDoc(cm, 4, 8); + range = cm.markText(Pos(1, 2), Pos(6, 2), { + replacedWith: document.createTextNode("M"), + clearOnEnter: true + }); + var cleared = 0; + CodeMirror.on(range, "clear", function(){++cleared;}); + cm.setCursor(0, 3); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(6, 2)); + CodeMirror.commands.goCharLeft(cm); + eqCharPos(cm.getCursor(), Pos(6, 1)); + eq(cleared, 1); + range.clear(); + eq(cleared, 1); + range = cm.markText(Pos(1, 2), Pos(6, 2), { + replacedWith: document.createTextNode("Q"), + clearOnEnter: true + }); + range.clear(); + cm.setCursor(1, 2); + CodeMirror.commands.goCharRight(cm); + eqCharPos(cm.getCursor(), Pos(1, 3)); + range = cm.markText(Pos(2, 0), Pos(4, 4), { + replacedWith: document.createTextNode("M") + }); + cm.setCursor(1, 0); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(2, 0)); +}, null); + +testCM("nestedFold", function(cm) { + addDoc(cm, 10, 3); + function fold(ll, cl, lr, cr) { + return cm.markText(Pos(ll, cl), Pos(lr, cr), {collapsed: true}); + } + var inner1 = fold(0, 6, 1, 3), inner2 = fold(0, 2, 1, 8), outer = fold(0, 1, 2, 3), inner0 = fold(0, 5, 0, 6); + cm.setCursor(0, 1); + CodeMirror.commands.goCharRight(cm); + eqCursorPos(cm.getCursor(), Pos(2, 3)); + inner0.clear(); + CodeMirror.commands.goCharLeft(cm); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + outer.clear(); + CodeMirror.commands.goCharRight(cm); + eqCursorPos(cm.getCursor(), Pos(0, 2, "before")); + CodeMirror.commands.goCharRight(cm); + eqCursorPos(cm.getCursor(), Pos(1, 8)); + inner2.clear(); + CodeMirror.commands.goCharLeft(cm); + eqCursorPos(cm.getCursor(), Pos(1, 7, "after")); + cm.setCursor(0, 5); + CodeMirror.commands.goCharRight(cm); + eqCursorPos(cm.getCursor(), Pos(0, 6, "before")); + CodeMirror.commands.goCharRight(cm); + eqCursorPos(cm.getCursor(), Pos(1, 3)); +}); + +testCM("badNestedFold", function(cm) { + addDoc(cm, 4, 4); + cm.markText(Pos(0, 2), Pos(3, 2), {collapsed: true}); + var caught; + try {cm.markText(Pos(0, 1), Pos(0, 3), {collapsed: true});} + catch(e) {caught = e;} + is(caught instanceof Error, "no error"); + is(/overlap/i.test(caught.message), "wrong error"); +}); + +testCM("nestedFoldOnSide", function(cm) { + var m1 = cm.markText(Pos(0, 1), Pos(2, 1), {collapsed: true, inclusiveRight: true}); + var m2 = cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true}); + cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true}).clear(); + try { cm.markText(Pos(0, 1), Pos(0, 2), {collapsed: true, inclusiveLeft: true}); } + catch(e) { var caught = e; } + is(caught && /overlap/i.test(caught.message)); + var m3 = cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true}); + var m4 = cm.markText(Pos(2, 0), Pos(2, 1), {collapse: true, inclusiveRight: true}); + m1.clear(); m4.clear(); + m1 = cm.markText(Pos(0, 1), Pos(2, 1), {collapsed: true}); + cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true}).clear(); + try { cm.markText(Pos(2, 0), Pos(2, 1), {collapsed: true, inclusiveRight: true}); } + catch(e) { var caught = e; } + is(caught && /overlap/i.test(caught.message)); +}, {value: "ab\ncd\ef"}); + +testCM("editInFold", function(cm) { + addDoc(cm, 4, 6); + var m = cm.markText(Pos(1, 2), Pos(3, 2), {collapsed: true}); + cm.replaceRange("", Pos(0, 0), Pos(1, 3)); + cm.replaceRange("", Pos(2, 1), Pos(3, 3)); + cm.replaceRange("a\nb\nc\nd", Pos(0, 1), Pos(1, 0)); + cm.cursorCoords(Pos(0, 0)); +}); + +testCM("wrappingInlineWidget", function(cm) { + cm.setSize("11em"); + var w = document.createElement("span"); + w.style.color = "red"; + w.innerHTML = "one two three four"; + cm.markText(Pos(0, 6), Pos(0, 9), {replacedWith: w}); + var cur0 = cm.cursorCoords(Pos(0, 0)), cur1 = cm.cursorCoords(Pos(0, 10)); + is(cur0.top < cur1.top); + is(cur0.bottom < cur1.bottom); + var curL = cm.cursorCoords(Pos(0, 6)), curR = cm.cursorCoords(Pos(0, 9)); + eq(curL.top, cur0.top); + eq(curL.bottom, cur0.bottom); + eq(curR.top, cur1.top); + eq(curR.bottom, cur1.bottom); + cm.replaceRange("", Pos(0, 9), Pos(0)); + curR = cm.cursorCoords(Pos(0, 9)); + if (phantom) return; + eq(curR.top, cur1.top); + eq(curR.bottom, cur1.bottom); +}, {value: "1 2 3 xxx 4", lineWrapping: true}); + +testCM("showEmptyWidgetSpan", function(cm) { + var marker = cm.markText(Pos(0, 2), Pos(0, 2), { + clearWhenEmpty: false, + replacedWith: document.createTextNode("X") + }); + var text = cm.display.view[0].text; + eq(text.textContent || text.innerText, "abXc"); +}, {value: "abc"}); + +testCM("changedInlineWidget", function(cm) { + cm.setSize("10em"); + var w = document.createElement("span"); + w.innerHTML = "x"; + var m = cm.markText(Pos(0, 4), Pos(0, 5), {replacedWith: w}); + w.innerHTML = "and now the widget is really really long all of a sudden and a scrollbar is needed"; + m.changed(); + var hScroll = byClassName(cm.getWrapperElement(), "CodeMirror-hscrollbar")[0]; + is(hScroll.scrollWidth > hScroll.clientWidth); +}, {value: "hello there"}); + +testCM("changedBookmark", function(cm) { + cm.setSize("10em"); + var w = document.createElement("span"); + w.innerHTML = "x"; + var m = cm.setBookmark(Pos(0, 4), {widget: w}); + w.innerHTML = "and now the widget is really really long all of a sudden and a scrollbar is needed"; + m.changed(); + var hScroll = byClassName(cm.getWrapperElement(), "CodeMirror-hscrollbar")[0]; + is(hScroll.scrollWidth > hScroll.clientWidth); +}, {value: "abcdefg"}); + +testCM("inlineWidget", function(cm) { + var w = cm.setBookmark(Pos(0, 2), {widget: document.createTextNode("uu")}); + cm.setCursor(0, 2); + CodeMirror.commands.goLineDown(cm); + eqCharPos(cm.getCursor(), Pos(1, 4)); + cm.setCursor(0, 2); + cm.replaceSelection("hi"); + eqCharPos(w.find(), Pos(0, 2)); + cm.setCursor(0, 1); + cm.replaceSelection("ay"); + eqCharPos(w.find(), Pos(0, 4)); + eq(cm.getLine(0), "uayuhiuu"); +}, {value: "uuuu\nuuuuuu"}); + +testCM("wrappingAndResizing", function(cm) { + cm.setSize(null, "auto"); + cm.setOption("lineWrapping", true); + var wrap = cm.getWrapperElement(), h0 = wrap.offsetHeight; + var doc = "xxx xxx xxx xxx xxx"; + cm.setValue(doc); + for (var step = 10, w = cm.charCoords(Pos(0, 18), "div").right;; w += step) { + cm.setSize(w); + if (wrap.offsetHeight <= h0 * (opera_lt10 ? 1.2 : 1.5)) { + if (step == 10) { w -= 10; step = 1; } + else break; + } + } + // Ensure that putting the cursor at the end of the maximally long + // line doesn't cause wrapping to happen. + cm.setCursor(Pos(0, doc.length)); + eq(wrap.offsetHeight, h0); + cm.replaceSelection("x"); + is(wrap.offsetHeight > h0, "wrapping happens"); + // Now add a max-height and, in a document consisting of + // almost-wrapped lines, go over it so that a scrollbar appears. + cm.setValue(doc + "\n" + doc + "\n"); + cm.getScrollerElement().style.maxHeight = "100px"; + cm.replaceRange("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n!\n", Pos(2, 0)); + forEach([Pos(0, doc.length), Pos(0, doc.length - 1), + Pos(0, 0), Pos(1, doc.length), Pos(1, doc.length - 1)], + function(pos) { + var coords = cm.charCoords(pos); + eqCharPos(pos, cm.coordsChar({left: coords.left + 2, top: coords.top + 5})); + }); +}, null, ie_lt8); + +testCM("measureEndOfLine", function(cm) { + if (phantom) return; + cm.setSize(null, "auto"); + var inner = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild; + var lh = inner.offsetHeight; + for (var step = 10, w = cm.charCoords(Pos(0, 7), "div").right;; w += step) { + cm.setSize(w); + if (inner.offsetHeight < 2.5 * lh) { + if (step == 10) { w -= 10; step = 1; } + else break; + } + } + cm.setValue(cm.getValue() + "\n\n"); + var endPos = cm.charCoords(Pos(0, 18), "local"); + is(endPos.top > lh * .8, "not at top"); + is(endPos.left > w - 20, "at right"); + endPos = cm.charCoords(Pos(0, 18)); + eqCursorPos(cm.coordsChar({left: endPos.left, top: endPos.top + 5}), Pos(0, 18, "before")); + + var wrapPos = cm.cursorCoords(Pos(0, 9, "before")); + is(wrapPos.top < endPos.top, "wrapPos is actually in first line"); + eqCursorPos(cm.coordsChar({left: wrapPos.left + 10, top: wrapPos.top}), Pos(0, 9, "before")); +}, {mode: "text/html", value: "", lineWrapping: true}, ie_lt8 || opera_lt10); + +testCM("measureWrappedEndOfLine", function(cm) { + if (phantom) return; + cm.setSize(null, "auto"); + var inner = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild; + var lh = inner.offsetHeight; + for (var step = 10, w = cm.charCoords(Pos(0, 7), "div").right;; w += step) { + cm.setSize(w); + if (inner.offsetHeight < 2.5 * lh) { + if (step == 10) { w -= 10; step = 1; } + else break; + } + } + for (var i = 0; i < 3; ++i) { + var endPos = cm.charCoords(Pos(0, 12)); // Next-to-last since last would wrap (#1862) + endPos.left += w; // Add width of editor just to be sure that we are behind last character + eqCursorPos(cm.coordsChar(endPos), Pos(0, 13, "before")); + endPos.left += w * 100; + eqCursorPos(cm.coordsChar(endPos), Pos(0, 13, "before")); + cm.setValue("0123456789abcابجابجابجابج"); + if (i == 1) { + var node = document.createElement("div"); + node.innerHTML = "hi"; node.style.height = "30px"; + cm.addLineWidget(0, node, {above: true}); + } + } +}, {mode: "text/html", value: "0123456789abcde0123456789", lineWrapping: true}, ie_lt8 || opera_lt10); + +testCM("measureEndOfLineBidi", function(cm) { + eqCursorPos(cm.coordsChar({left: 5000, top: cm.charCoords(Pos(0, 0)).top}), Pos(0, 8, "after")) +}, {value: "إإإإuuuuإإإإ"}) + +testCM("measureWrappedBidiLevel2", function(cm) { + cm.setSize(cm.charCoords(Pos(0, 6), "editor").right + 60) + var c9 = cm.charCoords(Pos(0, 9)) + eqCharPos(cm.coordsChar({left: c9.right - 1, top: c9.top + 1}), Pos(0, 9)) +}, {value: "foobar إإ إإ إإ إإ 555 بببببب", lineWrapping: true}) + +testCM("measureWrappedBeginOfLine", function(cm) { + if (phantom) return; + cm.setSize(null, "auto"); + var inner = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild; + var lh = inner.offsetHeight; + for (var step = 10, w = cm.charCoords(Pos(0, 7), "div").right;; w += step) { + cm.setSize(w); + if (inner.offsetHeight < 2.5 * lh) { + if (step == 10) { w -= 10; step = 1; } + else break; + } + } + var beginOfSecondLine = Pos(0, 13, "after"); + for (var i = 0; i < 2; ++i) { + var beginPos = cm.charCoords(Pos(0, 0)); + beginPos.left -= w; + eqCursorPos(cm.coordsChar(beginPos), Pos(0, 0, "after")); + beginPos = cm.cursorCoords(beginOfSecondLine); + beginPos.left = 0; + eqCursorPos(cm.coordsChar(beginPos), beginOfSecondLine); + cm.setValue("0123456789abcابجابجابجابج"); + beginOfSecondLine = Pos(0, 25, "before"); + } +}, {mode: "text/html", value: "0123456789abcde0123456789", lineWrapping: true}); + +testCM("scrollVerticallyAndHorizontally", function(cm) { + if (cm.getOption("inputStyle") != "textarea") return; + cm.setSize(100, 100); + addDoc(cm, 40, 40); + cm.setCursor(39); + var wrap = cm.getWrapperElement(), bar = byClassName(wrap, "CodeMirror-vscrollbar")[0]; + is(bar.offsetHeight < wrap.offsetHeight, "vertical scrollbar limited by horizontal one"); + var cursorBox = byClassName(wrap, "CodeMirror-cursor")[0].getBoundingClientRect(); + var editorBox = wrap.getBoundingClientRect(); + is(cursorBox.bottom < editorBox.top + cm.getScrollerElement().clientHeight, + "bottom line visible"); +}, {lineNumbers: true}); + +testCM("moveVstuck", function(cm) { + var lines = byClassName(cm.getWrapperElement(), "CodeMirror-lines")[0].firstChild, h0 = lines.offsetHeight; + var val = "fooooooooooooooooooooooooo baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar\n"; + cm.setValue(val); + for (var w = cm.charCoords(Pos(0, 26), "div").right * 2.8;; w += 5) { + cm.setSize(w); + if (lines.offsetHeight <= 3.5 * h0) break; + } + cm.setCursor(Pos(0, val.length - 1)); + cm.moveV(-1, "line"); + eqCursorPos(cm.getCursor(), Pos(0, 27, "before")); + is(cm.cursorCoords(null, "local").top < h0, "cursor is in first visual line"); +}, {lineWrapping: true}, ie_lt8 || opera_lt10); + +testCM("collapseOnMove", function(cm) { + cm.setSelection(Pos(0, 1), Pos(2, 4)); + cm.execCommand("goLineUp"); + is(!cm.somethingSelected()); + eqCharPos(cm.getCursor(), Pos(0, 1)); + cm.setSelection(Pos(0, 1), Pos(2, 4)); + cm.execCommand("goPageDown"); + is(!cm.somethingSelected()); + eqCharPos(cm.getCursor(), Pos(2, 4)); + cm.execCommand("goLineUp"); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(0, 4)); + cm.setSelection(Pos(0, 1), Pos(2, 4)); + cm.execCommand("goCharLeft"); + is(!cm.somethingSelected()); + eqCharPos(cm.getCursor(), Pos(0, 1)); +}, {value: "aaaaa\nb\nccccc"}); + +testCM("clickTab", function(cm) { + var p0 = cm.charCoords(Pos(0, 0)); + eqCharPos(cm.coordsChar({left: p0.left + 5, top: p0.top + 5}), Pos(0, 0)); + eqCharPos(cm.coordsChar({left: p0.right - 5, top: p0.top + 5}), Pos(0, 1)); +}, {value: "\t\n\n", lineWrapping: true, tabSize: 8}); + +testCM("verticalScroll", function(cm) { + cm.setSize(100, 200); + cm.setValue("foo\nbar\nbaz\n"); + var sc = cm.getScrollerElement(), baseWidth = sc.scrollWidth; + cm.replaceRange("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah", Pos(0, 0), Pos(0)); + is(sc.scrollWidth > baseWidth, "scrollbar present"); + cm.replaceRange("foo", Pos(0, 0), Pos(0)); + if (!phantom) eq(sc.scrollWidth, baseWidth, "scrollbar gone"); + cm.replaceRange("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah", Pos(0, 0), Pos(0)); + cm.replaceRange("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbh", Pos(1, 0), Pos(1)); + is(sc.scrollWidth > baseWidth, "present again"); + var curWidth = sc.scrollWidth; + cm.replaceRange("foo", Pos(0, 0), Pos(0)); + is(sc.scrollWidth < curWidth, "scrollbar smaller"); + is(sc.scrollWidth > baseWidth, "but still present"); +}); + +testCM("extraKeys", function(cm) { + var outcome; + function fakeKey(expected, code, props) { + if (typeof code == "string") code = code.charCodeAt(0); + var e = {type: "keydown", keyCode: code, preventDefault: function(){}, stopPropagation: function(){}}; + if (props) for (var n in props) e[n] = props[n]; + outcome = null; + cm.triggerOnKeyDown(e); + eq(outcome, expected); + } + CodeMirror.commands.testCommand = function() {outcome = "tc";}; + CodeMirror.commands.goTestCommand = function() {outcome = "gtc";}; + cm.setOption("extraKeys", {"Shift-X": function() {outcome = "sx";}, + "X": function() {outcome = "x";}, + "Ctrl-Alt-U": function() {outcome = "cau";}, + "End": "testCommand", + "Home": "goTestCommand", + "Tab": false}); + fakeKey(null, "U"); + fakeKey("cau", "U", {ctrlKey: true, altKey: true}); + fakeKey(null, "U", {shiftKey: true, ctrlKey: true, altKey: true}); + fakeKey("x", "X"); + fakeKey("sx", "X", {shiftKey: true}); + fakeKey("tc", 35); + fakeKey(null, 35, {shiftKey: true}); + fakeKey("gtc", 36); + fakeKey("gtc", 36, {shiftKey: true}); + fakeKey(null, 9); +}, null, window.opera && mac); + +testCM("wordMovementCommands", function(cm) { + cm.execCommand("goWordLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); + eqCursorPos(cm.getCursor(), Pos(0, 7, "before")); + cm.execCommand("goWordLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 5, "after")); + cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); + eqCursorPos(cm.getCursor(), Pos(0, 12, "before")); + cm.execCommand("goWordLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 9, "after")); + cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); + eqCursorPos(cm.getCursor(), Pos(0, 24, "before")); + cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); + eqCursorPos(cm.getCursor(), Pos(1, 9, "before")); + cm.execCommand("goWordRight"); + eqCursorPos(cm.getCursor(), Pos(1, 13, "before")); + cm.execCommand("goWordRight"); cm.execCommand("goWordRight"); + eqCharPos(cm.getCursor(), Pos(2, 0)); +}, {value: "this is (the) firstline.\na foo12\u00e9\u00f8\u00d7bar\n"}); + +testCM("groupMovementCommands", function(cm) { + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(0, 4, "before")); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(0, 7, "before")); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(0, 10, "before")); + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 7, "after")); + cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(0, 15, "before")); + cm.setCursor(Pos(0, 17)); + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 16, "after")); + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 14, "after")); + cm.execCommand("goGroupRight"); cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(0, 20, "before")); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(1, 0, "after")); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(1, 2, "before")); + cm.execCommand("goGroupRight"); + eqCursorPos(cm.getCursor(), Pos(1, 5, "before")); + cm.execCommand("goGroupLeft"); cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(1, 0, "after")); + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 20, "after")); + cm.execCommand("goGroupLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 16, "after")); +}, {value: "booo ba---quux. ffff\n abc d"}); + +testCM("groupsAndWhitespace", function(cm) { + var positions = [Pos(0, 0), Pos(0, 2), Pos(0, 5), Pos(0, 9), Pos(0, 11), + Pos(1, 0), Pos(1, 2), Pos(1, 5)]; + for (var i = 1; i < positions.length; i++) { + cm.execCommand("goGroupRight"); + eqCharPos(cm.getCursor(), positions[i]); + } + for (var i = positions.length - 2; i >= 0; i--) { + cm.execCommand("goGroupLeft"); + eqCharPos(cm.getCursor(), i == 2 ? Pos(0, 6, "before") : positions[i]); + } +}, {value: " foo +++ \n bar"}); + +testCM("charMovementCommands", function(cm) { + cm.execCommand("goCharLeft"); cm.execCommand("goColumnLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goCharRight"); cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(0, 2, "before")); + cm.setCursor(Pos(1, 0)); + cm.execCommand("goColumnLeft"); + eqCursorPos(cm.getCursor(), Pos(1, 0)); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 5, "before")); + cm.execCommand("goColumnRight"); + eqCursorPos(cm.getCursor(), Pos(0, 5, "before")); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(1, 0, "after")); + cm.execCommand("goLineEnd"); + eqCursorPos(cm.getCursor(), Pos(1, 5, "before")); + cm.execCommand("goLineStartSmart"); + eqCursorPos(cm.getCursor(), Pos(1, 1, "after")); + cm.execCommand("goLineStartSmart"); + eqCursorPos(cm.getCursor(), Pos(1, 0, "after")); + cm.setCursor(Pos(2, 0)); + cm.execCommand("goCharRight"); cm.execCommand("goColumnRight"); + eqCursorPos(cm.getCursor(), Pos(2, 0)); +}, {value: "line1\n ine2\n"}); + +testCM("verticalMovementCommands", function(cm) { + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goLineDown"); + if (!phantom) // This fails in PhantomJS, though not in a real Webkit + eqCharPos(cm.getCursor(), Pos(1, 0)); + cm.setCursor(Pos(1, 12)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(2, 5)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(3, 0)); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(2, 5)); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(1, 12)); + cm.execCommand("goPageDown"); + eqCharPos(cm.getCursor(), Pos(5, 0)); + cm.execCommand("goPageDown"); cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(5, 0)); + cm.execCommand("goPageUp"); + eqCharPos(cm.getCursor(), Pos(0, 0)); +}, {value: "line1\nlong long line2\nline3\n\nline5\n"}); + +testCM("verticalMovementCommandsWrapping", function(cm) { + cm.setSize(120); + cm.setCursor(Pos(0, 5)); + cm.execCommand("goLineDown"); + eq(cm.getCursor().line, 0); + is(cm.getCursor().ch > 5, "moved beyond wrap"); + for (var i = 0; ; ++i) { + is(i < 20, "no endless loop"); + cm.execCommand("goLineDown"); + var cur = cm.getCursor(); + if (cur.line == 1) eq(cur.ch, 5); + if (cur.line == 2) { eq(cur.ch, 1); break; } + } +}, {value: "a very long line that wraps around somehow so that we can test cursor movement\nshortone\nk", + lineWrapping: true}); + +testCM("verticalMovementCommandsSingleLine", function(cm) { + cm.display.wrapper.style.height = "auto"; + cm.refresh(); + cm.execCommand("goLineUp"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); + cm.setCursor(Pos(0, 5)); + cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); + cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); + cm.execCommand("goLineUp"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goLineUp"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.execCommand("goPageDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); + cm.execCommand("goPageDown"); cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); + cm.execCommand("goPageUp"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.setCursor(Pos(0, 5)); + cm.execCommand("goPageUp"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); + cm.setCursor(Pos(0, 5)); + cm.execCommand("goPageDown"); + eqCursorPos(cm.getCursor(), Pos(0, 11)); +}, {value: "single line"}); + + +testCM("rtlMovement", function(cm) { + if (cm.getOption("inputStyle") != "textarea") return; + forEach(["خحج", "خحabcخحج", "abخحخحجcd", "abخde", "abخح2342خ1حج", "خ1ح2خح3حxج", + "خحcd", "1خحcd", "abcdeح1ج", "خمرحبها مها!", "foobarر", "خ ة ق", + "", "يتم السحب في 05 فبراير 2014"], function(line) { + cm.setValue(line + "\n"); cm.execCommand("goLineStart"); + var cursors = byClassName(cm.getWrapperElement(), "CodeMirror-cursors")[0]; + var cursor = cursors.firstChild; + var prevX = cursor.offsetLeft, prevY = cursor.offsetTop; + for (var i = 0; i <= line.length; ++i) { + cm.execCommand("goCharRight"); + cursor = cursors.firstChild; + if (i == line.length) is(cursor.offsetTop > prevY, "next line"); + else is(cursor.offsetLeft > prevX, "moved right"); + prevX = cursor.offsetLeft; prevY = cursor.offsetTop; + } + cm.setCursor(0, 0); cm.execCommand("goLineEnd"); + prevX = cursors.firstChild.offsetLeft; + for (var i = 0; i < line.length; ++i) { + cm.execCommand("goCharLeft"); + cursor = cursors.firstChild; + is(cursor.offsetLeft < prevX, "moved left"); + prevX = cursor.offsetLeft; + } + }); +}, null, ie_lt9); + +// Verify that updating a line clears its bidi ordering +testCM("bidiUpdate", function(cm) { + cm.setCursor(Pos(0, 2, "before")); + cm.replaceSelection("خحج", "start"); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(0, 6, "before")); +}, {value: "abcd\n"}); + +testCM("movebyTextUnit", function(cm) { + cm.setValue("בְּרֵאשִ\nééé́\n"); + cm.execCommand("goLineStart"); + for (var i = 0; i < 4; ++i) cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(0, 0, "after")); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(1, 0, "after")); + cm.execCommand("goCharRight"); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(1, 4, "before")); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(1, 7, "before")); +}); + +testCM("lineChangeEvents", function(cm) { + addDoc(cm, 3, 5); + var log = [], want = ["ch 0", "ch 1", "del 2", "ch 0", "ch 0", "del 1", "del 3", "del 4"]; + for (var i = 0; i < 5; ++i) { + CodeMirror.on(cm.getLineHandle(i), "delete", function(i) { + return function() {log.push("del " + i);}; + }(i)); + CodeMirror.on(cm.getLineHandle(i), "change", function(i) { + return function() {log.push("ch " + i);}; + }(i)); + } + cm.replaceRange("x", Pos(0, 1)); + cm.replaceRange("xy", Pos(1, 1), Pos(2)); + cm.replaceRange("foo\nbar", Pos(0, 1)); + cm.replaceRange("", Pos(0, 0), Pos(cm.lineCount())); + eq(log.length, want.length, "same length"); + for (var i = 0; i < log.length; ++i) + eq(log[i], want[i]); +}); + +testCM("scrollEntirelyToRight", function(cm) { + if (phantom || cm.getOption("inputStyle") != "textarea") return; + addDoc(cm, 500, 2); + cm.setCursor(Pos(0, 500)); + var wrap = cm.getWrapperElement(), cur = byClassName(wrap, "CodeMirror-cursor")[0]; + is(wrap.getBoundingClientRect().right > cur.getBoundingClientRect().left); +}); + +testCM("lineWidgets", function(cm) { + addDoc(cm, 500, 3); + var last = cm.charCoords(Pos(2, 0)); + var node = document.createElement("div"); + node.innerHTML = "hi"; + var widget = cm.addLineWidget(1, node); + is(last.top < cm.charCoords(Pos(2, 0)).top, "took up space"); + cm.setCursor(Pos(1, 1)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(2, 1)); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(1, 1)); +}); + +testCM("lineWidgetFocus", function(cm) { + var place = document.getElementById("testground"); + place.className = "offscreen"; + try { + addDoc(cm, 500, 10); + var node = document.createElement("input"); + var widget = cm.addLineWidget(1, node); + node.focus(); + eq(document.activeElement, node); + cm.replaceRange("new stuff", Pos(1, 0)); + eq(document.activeElement, node); + } finally { + place.className = ""; + } +}); + +testCM("lineWidgetCautiousRedraw", function(cm) { + var node = document.createElement("div"); + node.innerHTML = "hahah"; + var w = cm.addLineWidget(0, node); + var redrawn = false; + w.on("redraw", function() { redrawn = true; }); + cm.replaceSelection("0"); + is(!redrawn); +}, {value: "123\n456"}); + + +var knownScrollbarWidth; +function scrollbarWidth(measure) { + if (knownScrollbarWidth != null) return knownScrollbarWidth; + var div = document.createElement('div'); + div.style.cssText = "width: 50px; height: 50px; overflow-x: scroll"; + document.body.appendChild(div); + knownScrollbarWidth = div.offsetHeight - div.clientHeight; + document.body.removeChild(div); + return knownScrollbarWidth || 0; +} + +testCM("lineWidgetChanged", function(cm) { + addDoc(cm, 2, 300); + var halfScrollbarWidth = scrollbarWidth(cm.display.measure)/2; + cm.setOption('lineNumbers', true); + cm.setSize(600, cm.defaultTextHeight() * 50); + cm.scrollTo(null, cm.heightAtLine(125, "local")); + + var expectedWidgetHeight = 60; + var expectedLinesInWidget = 3; + function w() { + var node = document.createElement("div"); + // we use these children with just under half width of the line to check measurements are made with correct width + // when placed in the measure div. + // If the widget is measured at a width much narrower than it is displayed at, the underHalf children will span two lines and break the test. + // If the widget is measured at a width much wider than it is displayed at, the overHalf children will combine and break the test. + // Note that this test only checks widgets where coverGutter is true, because these require extra styling to get the width right. + // It may also be worthwhile to check this for non-coverGutter widgets. + // Visually: + // Good: + // | ------------- display width ------------- | + // | ------- widget-width when measured ------ | + // | | -- under-half -- | | -- under-half -- | | + // | | --- over-half --- | | + // | | --- over-half --- | | + // Height: measured as 3 lines, same as it will be when actually displayed + + // Bad (too narrow): + // | ------------- display width ------------- | + // | ------ widget-width when measured ----- | < -- uh oh + // | | -- under-half -- | | + // | | -- under-half -- | | < -- when measured, shoved to next line + // | | --- over-half --- | | + // | | --- over-half --- | | + // Height: measured as 4 lines, more than expected . Will be displayed as 3 lines! + + // Bad (too wide): + // | ------------- display width ------------- | + // | -------- widget-width when measured ------- | < -- uh oh + // | | -- under-half -- | | -- under-half -- | | + // | | --- over-half --- | | --- over-half --- | | < -- when measured, combined on one line + // Height: measured as 2 lines, less than expected. Will be displayed as 3 lines! + + var barelyUnderHalfWidthHtml = '
    '; + var barelyOverHalfWidthHtml = '
    '; + node.innerHTML = new Array(3).join(barelyUnderHalfWidthHtml) + new Array(3).join(barelyOverHalfWidthHtml); + node.style.cssText = "background: yellow;font-size:0;line-height: " + (expectedWidgetHeight/expectedLinesInWidget) + "px;"; + return node; + } + var info0 = cm.getScrollInfo(); + var w0 = cm.addLineWidget(0, w(), { coverGutter: true }); + var w150 = cm.addLineWidget(150, w(), { coverGutter: true }); + var w300 = cm.addLineWidget(300, w(), { coverGutter: true }); + var info1 = cm.getScrollInfo(); + eq(info0.height + (3 * expectedWidgetHeight), info1.height); + eq(info0.top + expectedWidgetHeight, info1.top); + expectedWidgetHeight = 12; + w0.node.style.lineHeight = w150.node.style.lineHeight = w300.node.style.lineHeight = (expectedWidgetHeight/expectedLinesInWidget) + "px"; + w0.changed(); w150.changed(); w300.changed(); + var info2 = cm.getScrollInfo(); + eq(info0.height + (3 * expectedWidgetHeight), info2.height); + eq(info0.top + expectedWidgetHeight, info2.top); +}); + +testCM("getLineNumber", function(cm) { + addDoc(cm, 2, 20); + var h1 = cm.getLineHandle(1); + eq(cm.getLineNumber(h1), 1); + cm.replaceRange("hi\nbye\n", Pos(0, 0)); + eq(cm.getLineNumber(h1), 3); + cm.setValue(""); + eq(cm.getLineNumber(h1), null); +}); + +testCM("jumpTheGap", function(cm) { + if (phantom) return; + var longLine = "abcdef ghiklmnop qrstuvw xyz "; + longLine += longLine; longLine += longLine; longLine += longLine; + cm.replaceRange(longLine, Pos(2, 0), Pos(2)); + cm.setSize("200px", null); + cm.getWrapperElement().style.lineHeight = 2; + cm.refresh(); + cm.setCursor(Pos(0, 1)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(1, 1)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(2, 1)); + cm.execCommand("goLineDown"); + eq(cm.getCursor().line, 2); + is(cm.getCursor().ch > 1); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(2, 1)); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(1, 1)); + var node = document.createElement("div"); + node.innerHTML = "hi"; node.style.height = "30px"; + cm.addLineWidget(0, node); + cm.addLineWidget(1, node.cloneNode(true), {above: true}); + cm.setCursor(Pos(0, 2)); + cm.execCommand("goLineDown"); + eqCharPos(cm.getCursor(), Pos(1, 2)); + cm.execCommand("goLineUp"); + eqCharPos(cm.getCursor(), Pos(0, 2)); +}, {lineWrapping: true, value: "abc\ndef\nghi\njkl\n"}); + +testCM("addLineClass", function(cm) { + function cls(line, text, bg, wrap, gutter) { + var i = cm.lineInfo(line); + eq(i.textClass, text); + eq(i.bgClass, bg); + eq(i.wrapClass, wrap); + if (typeof i.handle.gutterClass !== 'undefined') { + eq(i.handle.gutterClass, gutter); + } + } + cm.addLineClass(0, "text", "foo"); + cm.addLineClass(0, "text", "bar"); + cm.addLineClass(1, "background", "baz"); + cm.addLineClass(1, "wrap", "foo"); + cm.addLineClass(1, "gutter", "gutter-class"); + cls(0, "foo bar", null, null, null); + cls(1, null, "baz", "foo", "gutter-class"); + var lines = cm.display.lineDiv; + eq(byClassName(lines, "foo").length, 2); + eq(byClassName(lines, "bar").length, 1); + eq(byClassName(lines, "baz").length, 1); + eq(byClassName(lines, "gutter-class").length, 2); // Gutter classes are reflected in 2 nodes + cm.removeLineClass(0, "text", "foo"); + cls(0, "bar", null, null, null); + cm.removeLineClass(0, "text", "foo"); + cls(0, "bar", null, null, null); + cm.removeLineClass(0, "text", "bar"); + cls(0, null, null, null); + + cm.addLineClass(1, "wrap", "quux"); + cls(1, null, "baz", "foo quux", "gutter-class"); + cm.removeLineClass(1, "wrap"); + cls(1, null, "baz", null, "gutter-class"); + cm.removeLineClass(1, "gutter", "gutter-class"); + eq(byClassName(lines, "gutter-class").length, 0); + cls(1, null, "baz", null, null); + + cm.addLineClass(1, "gutter", "gutter-class"); + cls(1, null, "baz", null, "gutter-class"); + cm.removeLineClass(1, "gutter", "gutter-class"); + cls(1, null, "baz", null, null); + +}, {value: "hohoho\n", lineNumbers: true}); + +testCM("atomicMarker", function(cm) { + addDoc(cm, 10, 10); + function atom(ll, cl, lr, cr, li, ri) { + return cm.markText(Pos(ll, cl), Pos(lr, cr), + {atomic: true, inclusiveLeft: li, inclusiveRight: ri}); + } + var m = atom(0, 1, 0, 5); + cm.setCursor(Pos(0, 1)); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(0, 5)); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + m.clear(); + m = atom(0, 0, 0, 5, true); + eqCursorPos(cm.getCursor(), Pos(0, 5), "pushed out"); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 5)); + m.clear(); + m = atom(8, 4, 9, 10, false, true); + cm.setCursor(Pos(9, 8)); + eqCursorPos(cm.getCursor(), Pos(8, 4), "set"); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(8, 4), "char right"); + cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(8, 4), "line down"); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(8, 3, "after")); + m.clear(); + m = atom(1, 1, 3, 8); + cm.setCursor(Pos(0, 0)); + cm.setCursor(Pos(2, 0)); + eqCursorPos(cm.getCursor(), Pos(3, 8)); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(1, 1)); + cm.execCommand("goCharRight"); + eqCursorPos(cm.getCursor(), Pos(3, 8)); + cm.execCommand("goLineUp"); + eqCursorPos(cm.getCursor(), Pos(1, 1)); + cm.execCommand("goLineDown"); + eqCursorPos(cm.getCursor(), Pos(3, 8)); + cm.execCommand("delCharBefore"); + eq(cm.getValue().length, 80, "del chunk"); + m = atom(3, 0, 5, 5); + cm.setCursor(Pos(3, 0)); + cm.execCommand("delWordAfter"); + eq(cm.getValue().length, 53, "del chunk"); +}); + +testCM("selectionBias", function(cm) { + cm.markText(Pos(0, 1), Pos(0, 3), {atomic: true}); + cm.setCursor(Pos(0, 2)); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + cm.setCursor(Pos(0, 2)); + eqCursorPos(cm.getCursor(), Pos(0, 3)); + cm.setCursor(Pos(0, 2)); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + cm.setCursor(Pos(0, 2), null, {bias: -1}); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + cm.setCursor(Pos(0, 4)); + cm.setCursor(Pos(0, 2), null, {bias: 1}); + eqCursorPos(cm.getCursor(), Pos(0, 3)); +}, {value: "12345"}); + +testCM("selectionHomeEnd", function(cm) { + cm.markText(Pos(1, 0), Pos(1, 1), {atomic: true, inclusiveLeft: true}); + cm.markText(Pos(1, 3), Pos(1, 4), {atomic: true, inclusiveRight: true}); + cm.setCursor(Pos(1, 2)); + cm.execCommand("goLineStart"); + eqCursorPos(cm.getCursor(), Pos(1, 1)); + cm.execCommand("goLineEnd"); + eqCursorPos(cm.getCursor(), Pos(1, 3)); +}, {value: "ab\ncdef\ngh"}); + +testCM("readOnlyMarker", function(cm) { + function mark(ll, cl, lr, cr, at) { + return cm.markText(Pos(ll, cl), Pos(lr, cr), + {readOnly: true, atomic: at}); + } + var m = mark(0, 1, 0, 4); + cm.setCursor(Pos(0, 2)); + cm.replaceSelection("hi", "end"); + eqCursorPos(cm.getCursor(), Pos(0, 2)); + eq(cm.getLine(0), "abcde"); + cm.execCommand("selectAll"); + cm.replaceSelection("oops", "around"); + eq(cm.getValue(), "oopsbcd"); + cm.undo(); + eqCursorPos(m.find().from, Pos(0, 1)); + eqCursorPos(m.find().to, Pos(0, 4)); + m.clear(); + cm.setCursor(Pos(0, 2)); + cm.replaceSelection("hi", "around"); + eq(cm.getLine(0), "abhicde"); + eqCursorPos(cm.getCursor(), Pos(0, 4)); + m = mark(0, 2, 2, 2, true); + cm.setSelection(Pos(1, 1), Pos(2, 4)); + cm.replaceSelection("t", "end"); + eqCursorPos(cm.getCursor(), Pos(2, 3)); + eq(cm.getLine(2), "klto"); + cm.execCommand("goCharLeft"); + cm.execCommand("goCharLeft"); + eqCursorPos(cm.getCursor(), Pos(0, 2)); + cm.setSelection(Pos(0, 1), Pos(0, 3)); + cm.replaceSelection("xx", "around"); + eqCursorPos(cm.getCursor(), Pos(0, 3)); + eq(cm.getLine(0), "axxhicde"); +}, {value: "abcde\nfghij\nklmno\n"}); + +testCM("dirtyBit", function(cm) { + eq(cm.isClean(), true); + cm.replaceSelection("boo", null, "test"); + eq(cm.isClean(), false); + cm.undo(); + eq(cm.isClean(), true); + cm.replaceSelection("boo", null, "test"); + cm.replaceSelection("baz", null, "test"); + cm.undo(); + eq(cm.isClean(), false); + cm.markClean(); + eq(cm.isClean(), true); + cm.undo(); + eq(cm.isClean(), false); + cm.redo(); + eq(cm.isClean(), true); +}); + +testCM("changeGeneration", function(cm) { + cm.replaceSelection("x"); + var softGen = cm.changeGeneration(); + cm.replaceSelection("x"); + cm.undo(); + eq(cm.getValue(), ""); + is(!cm.isClean(softGen)); + cm.replaceSelection("x"); + var hardGen = cm.changeGeneration(true); + cm.replaceSelection("x"); + cm.undo(); + eq(cm.getValue(), "x"); + is(cm.isClean(hardGen)); +}); + +testCM("addKeyMap", function(cm) { + function sendKey(code) { + cm.triggerOnKeyDown({type: "keydown", keyCode: code, + preventDefault: function(){}, stopPropagation: function(){}}); + } + + sendKey(39); + eqCursorPos(cm.getCursor(), Pos(0, 1, "before")); + var test = 0; + var map1 = {Right: function() { ++test; }}, map2 = {Right: function() { test += 10; }} + cm.addKeyMap(map1); + sendKey(39); + eqCursorPos(cm.getCursor(), Pos(0, 1, "before")); + eq(test, 1); + cm.addKeyMap(map2, true); + sendKey(39); + eq(test, 2); + cm.removeKeyMap(map1); + sendKey(39); + eq(test, 12); + cm.removeKeyMap(map2); + sendKey(39); + eq(test, 12); + eqCursorPos(cm.getCursor(), Pos(0, 2, "before")); + cm.addKeyMap({Right: function() { test = 55; }, name: "mymap"}); + sendKey(39); + eq(test, 55); + cm.removeKeyMap("mymap"); + sendKey(39); + eqCursorPos(cm.getCursor(), Pos(0, 3, "before")); +}, {value: "abc"}); + +function mouseDown(cm, button, pos, mods) { + var coords = cm.charCoords(pos, "window") + var event = {type: "mousedown", + preventDefault: Math.min, + which: button, + target: cm.display.lineDiv, + clientX: coords.left, clientY: coords.top} + if (mods) for (var prop in mods) event[prop] = mods[prop] + cm.triggerOnMouseDown(event) +} + +testCM("mouseBinding", function(cm) { + var fired = [] + cm.addKeyMap({ + "Shift-LeftClick": function(_cm, pos) { + eqCharPos(pos, Pos(1, 2)) + fired.push("a") + }, + "Shift-LeftDoubleClick": function() { fired.push("b") }, + "Shift-LeftTripleClick": function() { fired.push("c") } + }) + + function send(button, mods) { mouseDown(cm, button, Pos(1, 2), mods) } + send(1, {shiftKey: true}) + send(1, {shiftKey: true}) + send(1, {shiftKey: true}) + send(1, {}) + send(2, {ctrlKey: true}) + send(2, {ctrlKey: true}) + eq(fired.join(" "), "a b c") +}, {value: "foo\nbar\nbaz"}) + +testCM("configureMouse", function(cm) { + cm.setOption("configureMouse", function() { return {unit: "word"} }) + mouseDown(cm, 1, Pos(0, 5)) + eqCharPos(cm.getCursor("from"), Pos(0, 4)) + eqCharPos(cm.getCursor("to"), Pos(0, 7)) + cm.setOption("configureMouse", function() { return {extend: true} }) + mouseDown(cm, 1, Pos(0, 0)) + eqCharPos(cm.getCursor("from"), Pos(0, 0)) + eqCharPos(cm.getCursor("to"), Pos(0, 4)) +}, {value: "foo bar baz"}) + +testCM("findPosH", function(cm) { + forEach([{from: Pos(0, 0), to: Pos(0, 1, "before"), by: 1}, + {from: Pos(0, 0), to: Pos(0, 0), by: -1, hitSide: true}, + {from: Pos(0, 0), to: Pos(0, 4, "before"), by: 1, unit: "word"}, + {from: Pos(0, 0), to: Pos(0, 8, "before"), by: 2, unit: "word"}, + {from: Pos(0, 0), to: Pos(2, 0, "after"), by: 20, unit: "word", hitSide: true}, + {from: Pos(0, 7), to: Pos(0, 5, "after"), by: -1, unit: "word"}, + {from: Pos(0, 4), to: Pos(0, 8, "before"), by: 1, unit: "word"}, + {from: Pos(1, 0), to: Pos(1, 18, "before"), by: 3, unit: "word"}, + {from: Pos(1, 22), to: Pos(1, 5, "after"), by: -3, unit: "word"}, + {from: Pos(1, 15), to: Pos(1, 10, "after"), by: -5}, + {from: Pos(1, 15), to: Pos(1, 10, "after"), by: -5, unit: "column"}, + {from: Pos(1, 15), to: Pos(1, 0, "after"), by: -50, unit: "column", hitSide: true}, + {from: Pos(1, 15), to: Pos(1, 24, "before"), by: 50, unit: "column", hitSide: true}, + {from: Pos(1, 15), to: Pos(2, 0, "after"), by: 50, hitSide: true}], function(t) { + var r = cm.findPosH(t.from, t.by, t.unit || "char"); + eqCursorPos(r, t.to); + eq(!!r.hitSide, !!t.hitSide); + }); +}, {value: "line one\nline two.something.other\n"}); + +testCM("beforeChange", function(cm) { + cm.on("beforeChange", function(cm, change) { + var text = []; + for (var i = 0; i < change.text.length; ++i) + text.push(change.text[i].replace(/\s/g, "_")); + change.update(null, null, text); + }); + cm.setValue("hello, i am a\nnew document\n"); + eq(cm.getValue(), "hello,_i_am_a\nnew_document\n"); + CodeMirror.on(cm.getDoc(), "beforeChange", function(doc, change) { + if (change.from.line == 0) change.cancel(); + }); + cm.setValue("oops"); // Canceled + eq(cm.getValue(), "hello,_i_am_a\nnew_document\n"); + cm.replaceRange("hey hey hey", Pos(1, 0), Pos(2, 0)); + eq(cm.getValue(), "hello,_i_am_a\nhey_hey_hey"); +}, {value: "abcdefghijk"}); + +testCM("beforeChangeUndo", function(cm) { + cm.replaceRange("hi", Pos(0, 0), Pos(0)); + cm.replaceRange("bye", Pos(0, 0), Pos(0)); + eq(cm.historySize().undo, 2); + cm.on("beforeChange", function(cm, change) { + is(!change.update); + change.cancel(); + }); + cm.undo(); + eq(cm.historySize().undo, 0); + eq(cm.getValue(), "bye\ntwo"); +}, {value: "one\ntwo"}); + +testCM("beforeSelectionChange", function(cm) { + function notAtEnd(cm, pos) { + var len = cm.getLine(pos.line).length; + if (!len || pos.ch == len) return Pos(pos.line, pos.ch - 1); + return pos; + } + cm.on("beforeSelectionChange", function(cm, obj) { + obj.update([{anchor: notAtEnd(cm, obj.ranges[0].anchor), + head: notAtEnd(cm, obj.ranges[0].head)}]); + }); + + addDoc(cm, 10, 10); + cm.execCommand("goLineEnd"); + eqCursorPos(cm.getCursor(), Pos(0, 9)); + cm.execCommand("selectAll"); + eqCursorPos(cm.getCursor("start"), Pos(0, 0)); + eqCursorPos(cm.getCursor("end"), Pos(9, 9)); +}); + +testCM("change_removedText", function(cm) { + cm.setValue("abc\ndef"); + + var removedText = []; + cm.on("change", function(cm, change) { + removedText.push(change.removed); + }); + + cm.operation(function() { + cm.replaceRange("xyz", Pos(0, 0), Pos(1,1)); + cm.replaceRange("123", Pos(0,0)); + }); + + eq(removedText.length, 2); + eq(removedText[0].join("\n"), "abc\nd"); + eq(removedText[1].join("\n"), ""); + + var removedText = []; + cm.undo(); + eq(removedText.length, 2); + eq(removedText[0].join("\n"), "123"); + eq(removedText[1].join("\n"), "xyz"); + + var removedText = []; + cm.redo(); + eq(removedText.length, 2); + eq(removedText[0].join("\n"), "abc\nd"); + eq(removedText[1].join("\n"), ""); +}); + +testCM("lineStyleFromMode", function(cm) { + CodeMirror.defineMode("test_mode", function() { + return {token: function(stream) { + if (stream.match(/^\[[^\]]*\]/)) return " line-brackets "; + if (stream.match(/^\([^\)]*\)/)) return " line-background-parens "; + if (stream.match(/^<[^>]*>/)) return " span line-line line-background-bg "; + stream.match(/^\s+|^\S+/); + }}; + }); + cm.setOption("mode", "test_mode"); + var bracketElts = byClassName(cm.getWrapperElement(), "brackets"); + eq(bracketElts.length, 1, "brackets count"); + eq(bracketElts[0].nodeName, "PRE"); + is(!/brackets.*brackets/.test(bracketElts[0].className)); + var parenElts = byClassName(cm.getWrapperElement(), "parens"); + eq(parenElts.length, 1, "parens count"); + eq(parenElts[0].nodeName, "DIV"); + is(!/parens.*parens/.test(parenElts[0].className)); + eq(parenElts[0].parentElement.nodeName, "DIV"); + + is(byClassName(cm.getWrapperElement(), "bg").length > 0); + is(byClassName(cm.getWrapperElement(), "line").length > 0); + var spanElts = byClassName(cm.getWrapperElement(), "cm-span"); + eq(spanElts.length, 2); + is(/^\s*cm-span\s*$/.test(spanElts[0].className)); +}, {value: "line1: [br] [br]\nline2: (par) (par)\nline3: "}); + +testCM("lineStyleFromBlankLine", function(cm) { + CodeMirror.defineMode("lineStyleFromBlankLine_mode", function() { + return {token: function(stream) { stream.skipToEnd(); return "comment"; }, + blankLine: function() { return "line-blank"; }}; + }); + cm.setOption("mode", "lineStyleFromBlankLine_mode"); + var blankElts = byClassName(cm.getWrapperElement(), "blank"); + eq(blankElts.length, 1); + eq(blankElts[0].nodeName, "PRE"); + cm.replaceRange("x", Pos(1, 0)); + blankElts = byClassName(cm.getWrapperElement(), "blank"); + eq(blankElts.length, 0); +}, {value: "foo\n\nbar"}); + +CodeMirror.registerHelper("xxx", "a", "A"); +CodeMirror.registerHelper("xxx", "b", "B"); +CodeMirror.defineMode("yyy", function() { + return { + token: function(stream) { stream.skipToEnd(); }, + xxx: ["a", "b", "q"] + }; +}); +CodeMirror.registerGlobalHelper("xxx", "c", function(m) { return m.enableC; }, "C"); + +testCM("helpers", function(cm) { + cm.setOption("mode", "yyy"); + eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), "A/B"); + cm.setOption("mode", {name: "yyy", modeProps: {xxx: "b", enableC: true}}); + eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), "B/C"); + cm.setOption("mode", "javascript"); + eq(cm.getHelpers(Pos(0, 0), "xxx").join("/"), ""); +}); + +testCM("selectionHistory", function(cm) { + for (var i = 0; i < 3; i++) { + cm.setExtending(true); + cm.execCommand("goCharRight"); + cm.setExtending(false); + cm.execCommand("goCharRight"); + cm.execCommand("goCharRight"); + } + cm.execCommand("undoSelection"); + eq(cm.getSelection(), "c"); + cm.execCommand("undoSelection"); + eq(cm.getSelection(), ""); + eqCursorPos(cm.getCursor(), Pos(0, 4, "before")); + cm.execCommand("undoSelection"); + eq(cm.getSelection(), "b"); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), ""); + eqCursorPos(cm.getCursor(), Pos(0, 4, "before")); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), "c"); + cm.execCommand("redoSelection"); + eq(cm.getSelection(), ""); + eqCursorPos(cm.getCursor(), Pos(0, 6, "before")); +}, {value: "a b c d"}); + +testCM("selectionChangeReducesRedo", function(cm) { + cm.replaceSelection("X"); + cm.execCommand("goCharRight"); + cm.undoSelection(); + cm.execCommand("selectAll"); + cm.undoSelection(); + eq(cm.getValue(), "Xabc"); + eqCursorPos(cm.getCursor(), Pos(0, 1)); + cm.undoSelection(); + eq(cm.getValue(), "abc"); +}, {value: "abc"}); + +testCM("selectionHistoryNonOverlapping", function(cm) { + cm.setSelection(Pos(0, 0), Pos(0, 1)); + cm.setSelection(Pos(0, 2), Pos(0, 3)); + cm.execCommand("undoSelection"); + eqCursorPos(cm.getCursor("anchor"), Pos(0, 0)); + eqCursorPos(cm.getCursor("head"), Pos(0, 1)); +}, {value: "1234"}); + +testCM("cursorMotionSplitsHistory", function(cm) { + cm.replaceSelection("a"); + cm.execCommand("goCharRight"); + cm.replaceSelection("b"); + cm.replaceSelection("c"); + cm.undo(); + eq(cm.getValue(), "a1234"); + eqCursorPos(cm.getCursor(), Pos(0, 2, "before")); + cm.undo(); + eq(cm.getValue(), "1234"); + eqCursorPos(cm.getCursor(), Pos(0, 0)); +}, {value: "1234"}); + +testCM("selChangeInOperationDoesNotSplit", function(cm) { + for (var i = 0; i < 4; i++) { + cm.operation(function() { + cm.replaceSelection("x"); + cm.setCursor(Pos(0, cm.getCursor().ch - 1)); + }); + } + eqCursorPos(cm.getCursor(), Pos(0, 0)); + eq(cm.getValue(), "xxxxa"); + cm.undo(); + eq(cm.getValue(), "a"); +}, {value: "a"}); + +testCM("alwaysMergeSelEventWithChangeOrigin", function(cm) { + cm.replaceSelection("U", null, "foo"); + cm.setSelection(Pos(0, 0), Pos(0, 1), {origin: "foo"}); + cm.undoSelection(); + eq(cm.getValue(), "a"); + cm.replaceSelection("V", null, "foo"); + cm.setSelection(Pos(0, 0), Pos(0, 1), {origin: "bar"}); + cm.undoSelection(); + eq(cm.getValue(), "Va"); +}, {value: "a"}); + +testCM("getTokenAt", function(cm) { + var tokPlus = cm.getTokenAt(Pos(0, 2)); + eq(tokPlus.type, "operator"); + eq(tokPlus.string, "+"); + var toks = cm.getLineTokens(0); + eq(toks.length, 3); + forEach([["number", "1"], ["operator", "+"], ["number", "2"]], function(expect, i) { + eq(toks[i].type, expect[0]); + eq(toks[i].string, expect[1]); + }); +}, {value: "1+2", mode: "javascript"}); + +testCM("getTokenTypeAt", function(cm) { + eq(cm.getTokenTypeAt(Pos(0, 0)), "number"); + eq(cm.getTokenTypeAt(Pos(0, 6)), "string"); + cm.addOverlay({ + token: function(stream) { + if (stream.match("foo")) return "foo"; + else stream.next(); + } + }); + eq(byClassName(cm.getWrapperElement(), "cm-foo").length, 1); + eq(cm.getTokenTypeAt(Pos(0, 6)), "string"); +}, {value: "1 + 'foo'", mode: "javascript"}); + +testCM("addOverlay", function(cm) { + cm.addOverlay({ + token: function(stream) { + var base = stream.baseToken() + if (!/comment/.test(base.type) && stream.match(/\d+/)) return "x" + stream.next() + } + }) + var x = byClassName(cm.getWrapperElement(), "cm-x") + is(x.length, 1) + is(x[0].textContent, "233") + cm.replaceRange("", Pos(0, 4), Pos(0, 6)) + is(byClassName(cm.getWrapperElement(), "cm-x").length, 2) +}, {value: "foo /* 100 */\nbar + 233;\nbaz", mode: "javascript"}) + +testCM("resizeLineWidget", function(cm) { + addDoc(cm, 200, 3); + var widget = document.createElement("pre"); + widget.innerHTML = "imwidget"; + widget.style.background = "yellow"; + cm.addLineWidget(1, widget, {noHScroll: true}); + cm.setSize(40); + is(widget.parentNode.offsetWidth < 42); +}); + +testCM("combinedOperations", function(cm) { + var place = document.getElementById("testground"); + var other = CodeMirror(place, {value: "123"}); + try { + cm.operation(function() { + cm.addLineClass(0, "wrap", "foo"); + other.addLineClass(0, "wrap", "foo"); + }); + eq(byClassName(cm.getWrapperElement(), "foo").length, 1); + eq(byClassName(other.getWrapperElement(), "foo").length, 1); + cm.operation(function() { + cm.removeLineClass(0, "wrap", "foo"); + other.removeLineClass(0, "wrap", "foo"); + }); + eq(byClassName(cm.getWrapperElement(), "foo").length, 0); + eq(byClassName(other.getWrapperElement(), "foo").length, 0); + } finally { + place.removeChild(other.getWrapperElement()); + } +}, {value: "abc"}); + +testCM("eventOrder", function(cm) { + var seen = []; + cm.on("change", function() { + if (!seen.length) cm.replaceSelection("."); + seen.push("change"); + }); + cm.on("cursorActivity", function() { + cm.replaceSelection("!"); + seen.push("activity"); + }); + cm.replaceSelection("/"); + eq(seen.join(","), "change,change,activity,change"); +}); + +testCM("splitSpaces_nonspecial", function(cm) { + eq(byClassName(cm.getWrapperElement(), "cm-invalidchar").length, 0); +}, { + specialChars: /[\u00a0]/, + value: "spaces -> <- between" +}); + +test("core_rmClass", function() { + var node = document.createElement("div"); + node.className = "foo-bar baz-quux yadda"; + CodeMirror.rmClass(node, "quux"); + eq(node.className, "foo-bar baz-quux yadda"); + CodeMirror.rmClass(node, "baz-quux"); + eq(node.className, "foo-bar yadda"); + CodeMirror.rmClass(node, "yadda"); + eq(node.className, "foo-bar"); + CodeMirror.rmClass(node, "foo-bar"); + eq(node.className, ""); + node.className = " foo "; + CodeMirror.rmClass(node, "foo"); + eq(node.className, ""); +}); + +test("core_addClass", function() { + var node = document.createElement("div"); + CodeMirror.addClass(node, "a"); + eq(node.className, "a"); + CodeMirror.addClass(node, "a"); + eq(node.className, "a"); + CodeMirror.addClass(node, "b"); + eq(node.className, "a b"); + CodeMirror.addClass(node, "a"); + CodeMirror.addClass(node, "b"); + eq(node.className, "a b"); +}); + +testCM("lineSeparator", function(cm) { + eq(cm.lineCount(), 3); + eq(cm.getLine(1), "bar\r"); + eq(cm.getLine(2), "baz\rquux"); + cm.setOption("lineSeparator", "\r"); + eq(cm.lineCount(), 5); + eq(cm.getLine(4), "quux"); + eq(cm.getValue(), "foo\rbar\r\rbaz\rquux"); + eq(cm.getValue("\n"), "foo\nbar\n\nbaz\nquux"); + cm.setOption("lineSeparator", null); + cm.setValue("foo\nbar\r\nbaz\rquux"); + eq(cm.lineCount(), 4); +}, {value: "foo\nbar\r\nbaz\rquux", + lineSeparator: "\n"}); + +var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/ +var getChar = function (noExtending) { var res; do {res = String.fromCharCode(Math.floor(Math.random()*0x8ac)); } while ([0x90].indexOf(res.charCodeAt(0)) != -1 || (noExtending && extendingChars.test(res))); return res } +var getString = function (n) { var res = getChar(true); while (--n > 0) res += getChar(); return res } + +function makeItWrapAfter(cm, pos) { + var firstLineTop = cm.cursorCoords(Pos(0, 0)).top; + for(var w = 0, posTop; posTop != firstLineTop; ++w) { + cm.setSize(w); + posTop = cm.charCoords(pos).top; + } +} + +function countIf(arr, f) { + var result = 0 + for (var i = 0; i < arr.length; i++) if (f[arr[i]]) result++ + return result +} + +function testMoveBidi(str) { + testCM("move_bidi_" + str, function(cm) { + if (cm.getOption("inputStyle") != "textarea" || !cm.getOption("rtlMoveVisually")) return; + cm.getScrollerElement().style.fontFamily = "monospace"; + makeItWrapAfter(cm, Pos(0, 5)); + + var steps = str.length - countIf(str.split(""), function(ch) { return extendingChars.test(ch) }); + var lineBreaks = {} + lineBreaks[6 - countIf(str.substr(0, 5).split(""), function(ch) { return extendingChars.test(ch) })] = 'w'; + if (str.indexOf("\n") != -1) { + lineBreaks[steps - 2] = 'n'; + } + + // Make sure we are at the visual beginning of the first line + cm.execCommand("goLineStart"); + + var prevCoords = cm.cursorCoords(), coords; + for(var i = 0; i < steps; ++i) { + cm.execCommand("goCharRight"); + coords = cm.cursorCoords(); + if ((i >= 10 && i <= 12) && !lineBreaks[i] && coords.left < prevCoords.left && coords.top > prevCoords.top) { + // The first line wraps twice + lineBreaks[i] = 'w'; + } + if (!lineBreaks[i]) { + is(coords.left > prevCoords.left, "In step " + i + ", cursor didn't move right"); + eq(coords.top, prevCoords.top, "In step " + i + ", cursor moved out of line"); + } else { + is(coords.left < prevCoords.left, i); + is(coords.top > prevCoords.top, i); + } + prevCoords = coords; + } + + cm.execCommand("goCharRight"); + coords = cm.cursorCoords(); + eq(coords.left, prevCoords.left, "Moving " + steps + " steps right didn't reach the end"); + eq(coords.top, prevCoords.top, "Moving " + steps + " steps right didn't reach the end"); + + for(i = steps - 1; i >= 0; --i) { + cm.execCommand("goCharLeft"); + coords = cm.cursorCoords(); + if (!(lineBreaks[i] == 'n' || lineBreaks[i + 1] == 'w')) { + is(coords.left < prevCoords.left, "In step " + i + ", cursor didn't move left"); + eq(coords.top, prevCoords.top, "In step " + i + ", cursor is not at the same line anymore"); + } else { + is(coords.left > prevCoords.left, i); + is(coords.top < prevCoords.top, i); + } + prevCoords = coords; + } + + cm.execCommand("goCharLeft"); + coords = cm.cursorCoords(); + eq(coords.left, prevCoords.left, "Moving " + steps + " steps left didn't reach the beginning"); + eq(coords.top, prevCoords.top, "Moving " + steps + " steps left didn't reach the beginning"); + }, {value: str, lineWrapping: true}) +}; + +function testMoveEndBidi(str) { + testCM("move_end_bidi_" + str, function(cm) { + cm.getScrollerElement().style.fontFamily = "monospace"; + makeItWrapAfter(cm, Pos(0, 5)); + + cm.execCommand("goLineStart"); + var pos = cm.doc.getCursor(); + cm.execCommand("goCharLeft"); + eqCursorPos(pos, cm.doc.getCursor()); + + cm.execCommand("goLineEnd"); + pos = cm.doc.getCursor(); + cm.execCommand("goColumnRight"); + eqCursorPos(pos, cm.doc.getCursor()); + }, {value: str, lineWrapping: true}) +}; + +var bidiTests = []; + +// We don't correctly implement L1 UBA +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1331501 +// and https://bugs.chromium.org/p/chromium/issues/detail?id=673405 +/* +bidiTests.push("Say ا ب جabj\nS"); +bidiTests.push("Sayyy ا ا ب ج"); +*/ + +if (!phantom) { + bidiTests.push("Όȝǝڪȉۥ״ۺ׆ɀҩۏ\nҳ"); + bidiTests.push("ŌӰтقȤ؁ƥ؅٣ĎȺ١\nϚ"); + bidiTests.push("ٻоҤѕѽΩ־؉ïίքdz\nٵ"); + bidiTests.push("؅؁ĆՕƿɁǞϮؠȩóć\nď"); + bidiTests.push("RŨďңŪzϢŎƏԖڇڦ\nӈ"); + bidiTests.push("ό׊۷٢ԜһОצЉيčǟ\nѩ"); + bidiTests.push("ۑÚҳҕڬġڹհяųKV\nr"); + bidiTests.push("źڻғúہ4ם1Ƞc1a\nԁ"); + bidiTests.push("ҒȨҟփƞ٦ԓȦڰғâƥ\nڤ"); + bidiTests.push("ϖسՉȏŧΔԛdžĎӟیڡ\nέ"); + bidiTests.push("۹ؼL۵ĺȧКԙػא7״\nم"); + bidiTests.push("ن (ي)\u2009أقواس"); // thin space to throw off Firefox 51's broken white-space compressing behavior +} + +bidiTests.push("քմѧǮßپüŢҍҞўڳ\nӧ"); + +//bidiTests.push("Count ١ ٢ ٣ ٤"); +//bidiTests.push("ӣאƦϰ؊ȓېÛوը٬ز\nϪ"); +//bidiTests.push("ҾճٳџIՖӻ٥׭֐؜ڏ\nێ"); +//bidiTests.push("ҬÓФ؜ڂį٦Ͽɓڐͳٵ\nՈ"); +//bidiTests.push("aѴNijȻهˇ҃ڱӧǻֵ\na"); +//bidiTests.push(" a٧ا٢ ب جa\nS"); + +for (var i = 0; i < bidiTests.length; ++i) { + testMoveBidi(bidiTests[i]); + testMoveEndBidi(bidiTests[i]); +} + +/* +for (var i = 0; i < 5; ++i) { + testMoveBidi(getString(12) + "\n" + getString(1)); +} +*/ + +function testCoordsWrappedBidi(str) { + testCM("coords_wrapped_bidi_" + str, function(cm) { + cm.getScrollerElement().style.fontFamily = "monospace"; + makeItWrapAfter(cm, Pos(0, 5)); + + // Make sure we are at the visual beginning of the first line + var pos = Pos(0, 0), lastPos; + cm.doc.setCursor(pos); + do { + lastPos = pos; + cm.execCommand("goCharLeft"); + pos = cm.doc.getCursor(); + } while (pos != lastPos) + + var top = cm.charCoords(Pos(0, 0)).top, lastTop; + for (var i = 1; i < str.length; ++i) { + lastTop = top; + top = cm.charCoords(Pos(0, i)).top; + is(top >= lastTop); + } + }, {value: str, lineWrapping: true}) +}; + +testCoordsWrappedBidi("Count ١ ٢ ٣ ٤"); +/* +for (var i = 0; i < 5; ++i) { + testCoordsWrappedBidi(getString(50)); +} +*/ + +testCM("rtl_wrapped_selection", function(cm) { + cm.setSelection(Pos(0, 10), Pos(0, 190)) + is(byClassName(cm.getWrapperElement(), "CodeMirror-selected").length >= 3) +}, {value: new Array(10).join(" فتي تم تضمينها فتي تم"), lineWrapping: true}) + +testCM("bidi_wrapped_selection", function(cm) { + if (phantom) return + cm.setSize(cm.charCoords(Pos(0, 10), "editor").left) + cm.setSelection(Pos(0, 37), Pos(0, 80)) + var blocks = byClassName(cm.getWrapperElement(), "CodeMirror-selected") + is(blocks.length >= 2) + is(blocks.length <= 3) + var boxTop = blocks[0].getBoundingClientRect(), boxBot = blocks[blocks.length - 1].getBoundingClientRect() + is(boxTop.left > cm.charCoords(Pos(0, 1)).right) + is(boxBot.right < cm.charCoords(Pos(0, cm.getLine(0).length - 2)).left) +}, {value: "

    مفتي11 تم تضمينهفتي تم تضمينها فتي تفتي تم تضمينها فتي تفتي تم تضمينها فتي تفتي تم تضمينها فتي تا فت10ي ت

    ", lineWrapping: true}) + +testCM("delete_wrapped", function(cm) { + makeItWrapAfter(cm, Pos(0, 2)); + cm.doc.setCursor(Pos(0, 3, "after")); + cm.deleteH(-1, "char"); + eq(cm.getLine(0), "1245"); +}, {value: "12345", lineWrapping: true}) + +testCM("issue_4878", function(cm) { + if (phantom) return + cm.setCursor(Pos(1, 12, "after")); + cm.moveH(-1, "char"); + eqCursorPos(cm.getCursor(), Pos(0, 113, "before")); +}, {value: " في تطبيق السمات مرة واحدة https://github.com/codemirror/CodeMirror/issues/4878#issuecomment-330550964على سبيل المثال \"foo bar\"\n" + +" سيتم تعيين", direction: "rtl", lineWrapping: true}); + +CodeMirror.defineMode("lookahead_mode", function() { + // Colors text as atom if the line two lines down has an x in it + return { + token: function(stream) { + stream.skipToEnd() + return /x/.test(stream.lookAhead(2)) ? "atom" : null + } + } +}) + +testCM("mode_lookahead", function(cm) { + eq(cm.getTokenAt(Pos(0, 1)).type, "atom") + eq(cm.getTokenAt(Pos(1, 1)).type, "atom") + eq(cm.getTokenAt(Pos(2, 1)).type, null) + cm.replaceRange("\n", Pos(2, 0)) + eq(cm.getTokenAt(Pos(0, 1)).type, null) + eq(cm.getTokenAt(Pos(1, 1)).type, "atom") +}, {value: "foo\na\nx\nx\n", mode: "lookahead_mode"}) diff --git a/backend/webif/static/codemirror/test/vim_test.js b/backend/webif/static/codemirror/test/vim_test.js new file mode 100755 index 000000000..18268ee78 --- /dev/null +++ b/backend/webif/static/codemirror/test/vim_test.js @@ -0,0 +1,4238 @@ +var Pos = CodeMirror.Pos; +CodeMirror.Vim.suppressErrorLogging = true; + +var code = '' + +' wOrd1 (#%\n' + +' word3] \n' + +'aopop pop 0 1 2 3 4\n' + +' (a) [b] {c} \n' + +'int getchar(void) {\n' + +' static char buf[BUFSIZ];\n' + +' static char *bufp = buf;\n' + +' if (n == 0) { /* buffer is empty */\n' + +' n = read(0, buf, sizeof buf);\n' + +' bufp = buf;\n' + +' }\n' + +'\n' + +' return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' + +' \n' + +'}\n'; + +var lines = (function() { + lineText = code.split('\n'); + var ret = []; + for (var i = 0; i < lineText.length; i++) { + ret[i] = { + line: i, + length: lineText[i].length, + lineText: lineText[i], + textStart: /^\s*/.exec(lineText[i])[0].length + }; + } + return ret; +})(); +var endOfDocument = makeCursor(lines.length - 1, + lines[lines.length - 1].length); +var wordLine = lines[0]; +var bigWordLine = lines[1]; +var charLine = lines[2]; +var bracesLine = lines[3]; +var seekBraceLine = lines[4]; + +var word1 = { + start: new Pos(wordLine.line, 1), + end: new Pos(wordLine.line, 5) +}; +var word2 = { + start: new Pos(wordLine.line, word1.end.ch + 2), + end: new Pos(wordLine.line, word1.end.ch + 4) +}; +var word3 = { + start: new Pos(bigWordLine.line, 1), + end: new Pos(bigWordLine.line, 5) +}; +var bigWord1 = word1; +var bigWord2 = word2; +var bigWord3 = { + start: new Pos(bigWordLine.line, 1), + end: new Pos(bigWordLine.line, 7) +}; +var bigWord4 = { + start: new Pos(bigWordLine.line, bigWord1.end.ch + 3), + end: new Pos(bigWordLine.line, bigWord1.end.ch + 7) +}; + +var oChars = [ new Pos(charLine.line, 1), + new Pos(charLine.line, 3), + new Pos(charLine.line, 7) ]; +var pChars = [ new Pos(charLine.line, 2), + new Pos(charLine.line, 4), + new Pos(charLine.line, 6), + new Pos(charLine.line, 8) ]; +var numChars = [ new Pos(charLine.line, 10), + new Pos(charLine.line, 12), + new Pos(charLine.line, 14), + new Pos(charLine.line, 16), + new Pos(charLine.line, 18)]; +var parens1 = { + start: new Pos(bracesLine.line, 1), + end: new Pos(bracesLine.line, 3) +}; +var squares1 = { + start: new Pos(bracesLine.line, 5), + end: new Pos(bracesLine.line, 7) +}; +var curlys1 = { + start: new Pos(bracesLine.line, 9), + end: new Pos(bracesLine.line, 11) +}; +var seekOutside = { + start: new Pos(seekBraceLine.line, 1), + end: new Pos(seekBraceLine.line, 16) +}; +var seekInside = { + start: new Pos(seekBraceLine.line, 14), + end: new Pos(seekBraceLine.line, 11) +}; + +function copyCursor(cur) { + return new Pos(cur.line, cur.ch); +} + +function forEach(arr, func) { + for (var i = 0; i < arr.length; i++) { + func(arr[i], i, arr); + } +} + +function testVim(name, run, opts, expectedFail) { + var vimOpts = { + lineNumbers: true, + vimMode: true, + showCursorWhenSelecting: true, + value: code + }; + for (var prop in opts) { + if (opts.hasOwnProperty(prop)) { + vimOpts[prop] = opts[prop]; + } + } + return test('vim_' + name, function() { + var place = document.getElementById("testground"); + var cm = CodeMirror(place, vimOpts); + var vim = CodeMirror.Vim.maybeInitVimState_(cm); + + function doKeysFn(cm) { + return function(args) { + if (args instanceof Array) { + arguments = args; + } + for (var i = 0; i < arguments.length; i++) { + var result = CodeMirror.Vim.handleKey(cm, arguments[i]); + if (!result && cm.state.vim.insertMode) { + cm.replaceSelections(fillArray(arguments[i], cm.listSelections().length)); + } + } + } + } + function doInsertModeKeysFn(cm) { + return function(args) { + if (args instanceof Array) { arguments = args; } + function executeHandler(handler) { + if (typeof handler == 'string') { + CodeMirror.commands[handler](cm); + } else { + handler(cm); + } + return true; + } + for (var i = 0; i < arguments.length; i++) { + var key = arguments[i]; + // Find key in keymap and handle. + var handled = CodeMirror.lookupKey(key, cm.getOption('keyMap'), executeHandler, cm); + // Record for insert mode. + if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') { + var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges; + if (lastChange && (key.indexOf('Delete') != -1 || key.indexOf('Backspace') != -1)) { + lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key)); + } + } + } + } + } + function doExFn(cm) { + return function(command) { + cm.openDialog = helpers.fakeOpenDialog(command); + helpers.doKeys(':'); + } + } + function assertCursorAtFn(cm) { + return function(line, ch) { + var pos; + if (ch == null && typeof line.line == 'number') { + pos = line; + } else { + pos = makeCursor(line, ch); + } + eqCursorPos(cm.getCursor(), pos); + } + } + function fakeOpenDialog(result) { + return function(text, callback) { + return callback(result); + } + } + function fakeOpenNotification(matcher) { + return function(text) { + matcher(text); + } + } + var helpers = { + doKeys: doKeysFn(cm), + // Warning: Only emulates keymap events, not character insertions. Use + // replaceRange to simulate character insertions. + // Keys are in CodeMirror format, NOT vim format. + doInsertModeKeys: doInsertModeKeysFn(cm), + doEx: doExFn(cm), + assertCursorAt: assertCursorAtFn(cm), + fakeOpenDialog: fakeOpenDialog, + fakeOpenNotification: fakeOpenNotification, + getRegisterController: function() { + return CodeMirror.Vim.getRegisterController(); + } + } + CodeMirror.Vim.resetVimGlobalState_(); + var successful = false; + var savedOpenNotification = cm.openNotification; + var savedOpenDialog = cm.openDialog; + try { + run(cm, vim, helpers); + successful = true; + } finally { + cm.openNotification = savedOpenNotification; + cm.openDialog = savedOpenDialog; + if (!successful || verbose) { + place.style.visibility = "visible"; + } else { + place.removeChild(cm.getWrapperElement()); + } + } + }, expectedFail); +}; +testVim('qq@q', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'q', 'l', 'l', 'q'); + helpers.assertCursorAt(0,2); + helpers.doKeys('@', 'q'); + helpers.assertCursorAt(0,4); +}, { value: ' '}); +testVim('@@', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'q', 'l', 'l', 'q'); + helpers.assertCursorAt(0,2); + helpers.doKeys('@', 'q'); + helpers.assertCursorAt(0,4); + helpers.doKeys('@', '@'); + helpers.assertCursorAt(0,6); +}, { value: ' '}); +var jumplistScene = ''+ + 'word\n'+ + '(word)\n'+ + '{word\n'+ + 'word.\n'+ + '\n'+ + 'word search\n'+ + '}word\n'+ + 'word\n'+ + 'word\n'; +function testJumplist(name, keys, endPos, startPos, dialog) { + endPos = makeCursor(endPos[0], endPos[1]); + startPos = makeCursor(startPos[0], startPos[1]); + testVim(name, function(cm, vim, helpers) { + CodeMirror.Vim.resetVimGlobalState_(); + if(dialog)cm.openDialog = helpers.fakeOpenDialog('word'); + cm.setCursor(startPos); + helpers.doKeys.apply(null, keys); + helpers.assertCursorAt(endPos); + }, {value: jumplistScene}); +}; +testJumplist('jumplist_H', ['H', ''], [5,2], [5,2]); +testJumplist('jumplist_M', ['M', ''], [2,2], [2,2]); +testJumplist('jumplist_L', ['L', ''], [2,2], [2,2]); +testJumplist('jumplist_[[', ['[', '[', ''], [5,2], [5,2]); +testJumplist('jumplist_]]', [']', ']', ''], [2,2], [2,2]); +testJumplist('jumplist_G', ['G', ''], [5,2], [5,2]); +testJumplist('jumplist_gg', ['g', 'g', ''], [5,2], [5,2]); +testJumplist('jumplist_%', ['%', ''], [1,5], [1,5]); +testJumplist('jumplist_{', ['{', ''], [1,5], [1,5]); +testJumplist('jumplist_}', ['}', ''], [1,5], [1,5]); +testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', ''], [1,0], [1,5]); +testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', ''], [1,5], [1,5]); +testJumplist('jumplist_*_cachedCursor', ['*', ''], [1,3], [1,3]); +testJumplist('jumplist_#_cachedCursor', ['#', ''], [1,3], [1,3]); +testJumplist('jumplist_n', ['#', 'n', ''], [1,1], [2,3]); +testJumplist('jumplist_N', ['#', 'N', ''], [1,1], [2,3]); +testJumplist('jumplist_repeat_', ['*', '*', '*', '3', ''], [2,3], [2,3]); +testJumplist('jumplist_repeat_', ['*', '*', '*', '3', '', '2', ''], [5,0], [2,3]); +testJumplist('jumplist_repeated_motion', ['3', '*', ''], [2,3], [2,3]); +testJumplist('jumplist_/', ['/', ''], [2,3], [2,3], 'dialog'); +testJumplist('jumplist_?', ['?', ''], [2,3], [2,3], 'dialog'); +testJumplist('jumplist_skip_deleted_mark', + ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], + [0,2], [0,2]); +testJumplist('jumplist_skip_deleted_mark', + ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], + [1,0], [0,2]); + +/** + * @param name Name of the test + * @param keys An array of keys or a string with a single key to simulate. + * @param endPos The expected end position of the cursor. + * @param startPos The position the cursor should start at, defaults to 0, 0. + */ +function testMotion(name, keys, endPos, startPos) { + testVim(name, function(cm, vim, helpers) { + if (!startPos) { + startPos = new Pos(0, 0); + } + cm.setCursor(startPos); + helpers.doKeys(keys); + helpers.assertCursorAt(endPos); + }); +}; + +function makeCursor(line, ch) { + return new Pos(line, ch); +}; + +function offsetCursor(cur, offsetLine, offsetCh) { + return new Pos(cur.line + offsetLine, cur.ch + offsetCh); +}; + +// Motion tests +testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4)); +testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4)); +testMotion('h', 'h', makeCursor(0, 0), word1.start); +testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end); +testMotion('l', 'l', makeCursor(0, 1)); +testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2)); +testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end); +testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end); +testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument); +testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end); +testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4)); +testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4)); +testMotion('w', 'w', word1.start); +testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2)); +testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51)); +testMotion('w_repeat', ['2', 'w'], word2.start); +testMotion('w_wrap', ['w'], word3.start, word2.start); +testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument); +testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0)); +testMotion('W', 'W', bigWord1.start); +testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start); +testMotion('e', 'e', word1.end); +testMotion('e_repeat', ['2', 'e'], word2.end); +testMotion('e_wrap', 'e', word3.end, word2.end); +testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument); +testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0)); +testMotion('b', 'b', word3.start, word3.end); +testMotion('b_repeat', ['2', 'b'], word2.start, word3.end); +testMotion('b_wrap', 'b', word2.start, word3.start); +testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0)); +testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument); +testMotion('ge', ['g', 'e'], word2.end, word3.end); +testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start); +testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start); +testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0), + makeCursor(0, 0)); +testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument); +testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart), + makeCursor(3, 1)); +testMotion('gg_repeat', ['3', 'g', 'g'], + makeCursor(lines[2].line, lines[2].textStart)); +testMotion('G', 'G', + makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart), + makeCursor(3, 1)); +testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line, + lines[2].textStart)); +// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B. +testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8)); +testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8)); +testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8)); +testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4)); +testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8)); +testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1)); +testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1), + makeCursor(0, 3)); +testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0)); +testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]); +testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0)); +testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1), + makeCursor(charLine.line, 0)); +testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1), + pChars[0]); +testMotion('F', ['F', 'p'], pChars[0], pChars[1]); +testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]); +testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]); +testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]); +testMotion('%_parens', ['%'], parens1.end, parens1.start); +testMotion('%_squares', ['%'], squares1.end, squares1.start); +testMotion('%_braces', ['%'], curlys1.end, curlys1.start); +testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start); +testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start); +testVim('%_seek_skip', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,9); +}, {value:'01234"("()'}); +testVim('%_skip_string', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,4); + cm.setCursor(0,2); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,0); +}, {value:'(")")'}); +testVim('%_skip_comment', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,6); + cm.setCursor(0,3); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,0); +}, {value:'(/*)*/)'}); +// Make sure that moving down after going to the end of a line always leaves you +// at the end of a line, but preserves the offset in other cases +testVim('Changing lines after Eol operation', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['$']); + helpers.doKeys(['j']); + // After moving to Eol and then down, we should be at Eol of line 2 + helpers.assertCursorAt(new Pos(1, lines[1].length - 1)); + helpers.doKeys(['j']); + // After moving down, we should be at Eol of line 3 + helpers.assertCursorAt(new Pos(2, lines[2].length - 1)); + helpers.doKeys(['h']); + helpers.doKeys(['j']); + // After moving back one space and then down, since line 4 is shorter than line 2, we should + // be at Eol of line 2 - 1 + helpers.assertCursorAt(new Pos(3, lines[3].length - 1)); + helpers.doKeys(['j']); + helpers.doKeys(['j']); + // After moving down again, since line 3 has enough characters, we should be back to the + // same place we were at on line 1 + helpers.assertCursorAt(new Pos(5, lines[2].length - 2)); +}); +//making sure gj and gk recover from clipping +testVim('gj_gk_clipping', function(cm,vim,helpers){ + cm.setCursor(0, 1); + helpers.doKeys('g','j','g','j'); + helpers.assertCursorAt(2, 1); + helpers.doKeys('g','k','g','k'); + helpers.assertCursorAt(0, 1); +},{value: 'line 1\n\nline 2'}); +//testing a mix of j/k and gj/gk +testVim('j_k_and_gj_gk', function(cm,vim,helpers){ + cm.setSize(120); + cm.setCursor(0, 0); + //go to the last character on the first line + helpers.doKeys('$'); + //move up/down on the column within the wrapped line + //side-effect: cursor is not locked to eol anymore + helpers.doKeys('g','k'); + var cur=cm.getCursor(); + eq(cur.line,0); + is((cur.ch<176),'gk didn\'t move cursor back (1)'); + helpers.doKeys('g','j'); + helpers.assertCursorAt(0, 176); + //should move to character 177 on line 2 (j/k preserve character index within line) + helpers.doKeys('j'); + //due to different line wrapping, the cursor can be on a different screen-x now + //gj and gk preserve screen-x on movement, much like moveV + helpers.doKeys('3','g','k'); + cur=cm.getCursor(); + eq(cur.line,1); + is((cur.ch<176),'gk didn\'t move cursor back (2)'); + helpers.doKeys('g','j','2','g','j'); + //should return to the same character-index + helpers.doKeys('k'); + helpers.assertCursorAt(0, 176); +},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'}); +testVim('gj_gk', function(cm, vim, helpers) { + if (phantom) return; + cm.setSize(120); + // Test top of document edge case. + cm.setCursor(0, 4); + helpers.doKeys('g', 'j'); + helpers.doKeys('10', 'g', 'k'); + helpers.assertCursorAt(0, 4); + + // Test moving down preserves column position. + helpers.doKeys('g', 'j'); + var pos1 = cm.getCursor(); + var expectedPos2 = new Pos(0, (pos1.ch - 4) * 2 + 4); + helpers.doKeys('g', 'j'); + helpers.assertCursorAt(expectedPos2); + + // Move to the last character + cm.setCursor(0, 0); + // Move left to reset HSPos + helpers.doKeys('h'); + // Test bottom of document edge case. + helpers.doKeys('100', 'g', 'j'); + var endingPos = cm.getCursor(); + is(endingPos != 0, 'gj should not be on wrapped line 0'); + var topLeftCharCoords = cm.charCoords(makeCursor(0, 0)); + var endingCharCoords = cm.charCoords(endingPos); + is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0'); +},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' }); +testVim('}', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(1, 0); + cm.setCursor(0, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(4, 0); + cm.setCursor(0, 0); + helpers.doKeys('6', '}'); + helpers.assertCursorAt(5, 0); +}, { value: 'a\n\nb\nc\n\nd' }); +testVim('{', function(cm, vim, helpers) { + cm.setCursor(5, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(4, 0); + cm.setCursor(5, 0); + helpers.doKeys('2', '{'); + helpers.assertCursorAt(1, 0); + cm.setCursor(5, 0); + helpers.doKeys('6', '{'); + helpers.assertCursorAt(0, 0); +}, { value: 'a\n\nb\nc\n\nd' }); +testVim('paragraph_motions', function(cm, vim, helpers) { + cm.setCursor(10, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(4, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(7, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(16, 0); + + cm.setCursor(9, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(14, 0); + + cm.setCursor(6, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(7, 0); + + // ip inside empty space + cm.setCursor(10, 0); + helpers.doKeys('v', 'i', 'p'); + eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(12, 0), cm.getCursor('head')); + helpers.doKeys('i', 'p'); + eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(13, 1), cm.getCursor('head')); + helpers.doKeys('2', 'i', 'p'); + eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(16, 1), cm.getCursor('head')); + + // should switch to visualLine mode + cm.setCursor(14, 0); + helpers.doKeys('', 'v', 'i', 'p'); + helpers.assertCursorAt(14, 0); + + cm.setCursor(14, 0); + helpers.doKeys('', 'V', 'i', 'p'); + eqCursorPos(Pos(16, 1), cm.getCursor('head')); + + // ap inside empty space + cm.setCursor(10, 0); + helpers.doKeys('', 'v', 'a', 'p'); + eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(13, 1), cm.getCursor('head')); + helpers.doKeys('a', 'p'); + eqCursorPos(Pos(7, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(16, 1), cm.getCursor('head')); + + cm.setCursor(13, 0); + helpers.doKeys('v', 'a', 'p'); + eqCursorPos(Pos(13, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(14, 0), cm.getCursor('head')); + + cm.setCursor(16, 0); + helpers.doKeys('v', 'a', 'p'); + eqCursorPos(Pos(14, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(16, 1), cm.getCursor('head')); + + cm.setCursor(0, 0); + helpers.doKeys('v', 'a', 'p'); + eqCursorPos(Pos(0, 0), cm.getCursor('anchor')); + eqCursorPos(Pos(4, 0), cm.getCursor('head')); + + cm.setCursor(0, 0); + helpers.doKeys('d', 'i', 'p'); + var register = helpers.getRegisterController().getRegister(); + eq('a\na\n', register.toString()); + is(register.linewise); + helpers.doKeys('3', 'j', 'p'); + helpers.doKeys('y', 'i', 'p'); + is(register.linewise); + eq('b\na\na\nc\n', register.toString()); +}, { value: 'a\na\n\n\n\nb\nc\n\n\n\n\n\n\nd\n\ne\nf' }); + +// Operator tests +testVim('dl', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('d', 'l'); + eq('word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dl_eol', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('d', 'l'); + eq(' word1', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 5); +}, { value: ' word1 ' }); +testVim('dl_repeat', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('2', 'd', 'l'); + eq('ord1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' w', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dh', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'h'); + eq(' wrd1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('o', register.toString()); + is(!register.linewise); + eqCursorPos(offsetCursor(curStart, 0 , -1), cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dj', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'j'); + eq(' word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1\nword2\n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2\n word3' }); +testVim('dj_end_of_document', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'j'); + eq('', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1 \n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1 ' }); +testVim('dk', function(cm, vim, helpers) { + var curStart = makeCursor(1, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'k'); + eq(' word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1\nword2\n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2\n word3' }); +testVim('dk_start_of_document', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'k'); + eq('', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1 \n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1 ' }); +testVim('dw_space', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('d', 'w'); + eq('word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dw_word', function(cm, vim, helpers) { + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('d', 'w'); + eq(' word2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1 ', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1 word2' }); +testVim('dw_unicode_word', function(cm, vim, helpers) { + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 10); + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 6); + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 5); + helpers.doKeys('d', 'e'); + eq(cm.getValue().length, 2); +}, { value: ' \u0562\u0561\u0580\u0587\xbbe\xb5g ' }); +testVim('dw_only_word', function(cm, vim, helpers) { + // Test that if there is only 1 word left, dw deletes till the end of the + // line. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1 ', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1 ' }); +testVim('dw_eol', function(cm, vim, helpers) { + // Assert that dw does not delete the newline if last word to delete is at end + // of line. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' \nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\nword2' }); +testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) { + // Assert that dw does not delete the newline if last word to delete is at end + // of line and it is followed by multiple newlines. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' \n\nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\n\nword2' }); +testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq(' \nword', cm.getValue()); +}, { value: '\n \nword' }); +testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('word', cm.getValue()); +}, { value: '\nword' }); +testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n', cm.getValue()); +}, { value: '\n\n' }); +testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n \n', cm.getValue()); +}, { value: ' \n \n' }); +testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n\n', cm.getValue()); +}, { value: ' \n\n' }); +testVim('dw_word_whitespace_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n \nword2', cm.getValue()); +}, { value: 'word1\n \nword2'}) +testVim('dw_end_of_document', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('d', 'w'); + eq('\nab', cm.getValue()); +}, { value: '\nabc' }); +testVim('dw_repeat', function(cm, vim, helpers) { + // Assert that dw does delete newline if it should go to the next line, and + // that repeat works properly. + cm.setCursor(0, 1); + helpers.doKeys('d', '2', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\nword2' }); +testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'e'); + eq('\n\n', cm.getValue()); +}, { value: 'word\n\n' }); +testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('d', 'e'); + eq('wor', cm.getValue()); +}, { value: 'word\n\n\n' }); +testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'e'); + eq('', cm.getValue()); +}, { value: ' \n\n\n' }); +testVim('de_end_of_document', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('d', 'e'); + eq('\nab', cm.getValue()); +}, { value: '\nabc' }); +testVim('db_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('\n\n', cm.getValue()); +}, { value: '\n\n\n' }); +testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('\nword', cm.getValue()); +}, { value: '\n\nword' }); +testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 3); + helpers.doKeys('d', 'b'); + eq('\n\nd', cm.getValue()); +}, { value: '\n\nword' }); +testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('', cm.getValue()); +}, { value: '\n \n' }); +testVim('db_start_of_document', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'b'); + eq('abc\n', cm.getValue()); +}, { value: 'abc\n' }); +testVim('dge_empty_lines', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doKeys('d', 'g', 'e'); + // Note: In real VIM the result should be '', but it's not quite consistent, + // since 2 newlines are deleted. But in the similar case of word\n\n, only + // 1 newline is deleted. We'll diverge from VIM's behavior since it's much + // easier this way. + eq('\n', cm.getValue()); +}, { value: '\n\n' }); +testVim('dge_word_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doKeys('d', 'g', 'e'); + eq('wor\n', cm.getValue()); +}, { value: 'word\n\n'}); +testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'g', 'e'); + eq('', cm.getValue()); +}, { value: '\n \n' }); +testVim('dge_start_of_document', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'g', 'e'); + eq('bc\n', cm.getValue()); +}, { value: 'abc\n' }); +testVim('d_inclusive', function(cm, vim, helpers) { + // Assert that when inclusive is set, the character the cursor is on gets + // deleted too. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('d', 'e'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('d_reverse', function(cm, vim, helpers) { + // Test that deleting in reverse works. + cm.setCursor(1, 0); + helpers.doKeys('d', 'b'); + eq(' word2 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\n', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2 ' }); +testVim('dd', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(1, 0)); + var expectedLineCount = cm.lineCount() - 1; + helpers.doKeys('d', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[1].textStart); +}); +testVim('dd_prefix_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(2, 0)); + var expectedLineCount = cm.lineCount() - 2; + helpers.doKeys('2', 'd', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[2].textStart); +}); +testVim('dd_motion_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(2, 0)); + var expectedLineCount = cm.lineCount() - 2; + helpers.doKeys('d', '2', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[2].textStart); +}); +testVim('dd_multiply_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(6, 0)); + var expectedLineCount = cm.lineCount() - 6; + helpers.doKeys('2', 'd', '3', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[6].textStart); +}); +testVim('dd_lastline', function(cm, vim, helpers) { + cm.setCursor(cm.lineCount(), 0); + var expectedLineCount = cm.lineCount() - 1; + helpers.doKeys('d', 'd'); + eq(expectedLineCount, cm.lineCount()); + helpers.assertCursorAt(cm.lineCount() - 1, 0); +}); +testVim('dd_only_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + var expectedRegister = cm.getValue() + "\n"; + helpers.doKeys('d','d'); + eq(1, cm.lineCount()); + eq('', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedRegister, register.toString()); +}, { value: "thisistheonlyline" }); +// Yank commands should behave the exact same as d commands, expect that nothing +// gets deleted. +testVim('yw_repeat', function(cm, vim, helpers) { + // Assert that yw does yank newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('y', '2', 'w'); + eq(' word1\nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2' }); +testVim('yy_multiply_repeat', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(6, 0)); + var expectedLineCount = cm.lineCount(); + helpers.doKeys('2', 'y', '3', 'y'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}); +testVim('2dd_blank_P', function(cm, vim, helpers) { + helpers.doKeys('2', 'd', 'd', 'P'); + eq('\na\n\n', cm.getValue()); +}, { value: '\na\n\n' }); +// Change commands behave like d commands except that it also enters insert +// mode. In addition, when the change is linewise, an additional newline is +// inserted so that insert mode starts on that line. +testVim('cw', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('c', '2', 'w'); + eq(' word3', cm.getValue()); + helpers.assertCursorAt(0, 0); +}, { value: 'word1 word2 word3'}); +testVim('cw_repeat', function(cm, vim, helpers) { + // Assert that cw does delete newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('c', '2', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: ' word1\nword2' }); +testVim('cc_multiply_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange(new Pos(0, 0), + new Pos(6, 0)); + var expectedLineCount = cm.lineCount() - 5; + helpers.doKeys('2', 'c', '3', 'c'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('ct', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('c', 't', 'w'); + eq(' word1 word3', cm.getValue()); + helpers.doKeys('', 'c', '|'); + eq(' word3', cm.getValue()); + helpers.assertCursorAt(0, 0); + helpers.doKeys('', '2', 'u', 'w', 'h'); + helpers.doKeys('c', '2', 'g', 'e'); + eq(' wordword3', cm.getValue()); +}, { value: ' word1 word2 word3'}); +testVim('cc_should_not_append_to_document', function(cm, vim, helpers) { + var expectedLineCount = cm.lineCount(); + cm.setCursor(cm.lastLine(), 0); + helpers.doKeys('c', 'c'); + eq(expectedLineCount, cm.lineCount()); +}); +function fillArray(val, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(val); + } + return arr; +} +testVim('c_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'c'); + var replacement = fillArray('hello', 3); + cm.replaceSelections(replacement); + eq('1hello\n5hello\nahellofg', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(2, 3); + helpers.doKeys('', '2', 'k', 'h', 'C'); + replacement = fillArray('world', 3); + cm.replaceSelections(replacement); + eq('1hworld\n5hworld\nahworld', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('c_visual_block_replay', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'c'); + var replacement = fillArray('fo', 3); + cm.replaceSelections(replacement); + eq('1fo4\n5fo8\nafodefg', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(0, 0); + helpers.doKeys('.'); + eq('foo4\nfoo8\nfoodefg', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); + +testVim('d_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'd'); + eq('1\n5\nafg', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('D_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'D'); + eq('1\n5\na', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); + +testVim('s_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 's'); + var replacement = fillArray('hello{', 3); + cm.replaceSelections(replacement); + eq('1hello{\n5hello{\nahello{fg\n', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(2, 3); + helpers.doKeys('', '1', 'k', 'h', 'S'); + replacement = fillArray('world', 1); + cm.replaceSelections(replacement); + eq('1hello{\n world\n', cm.getValue()); +}, {value: '1234\n5678\nabcdefg\n'}); + +// Swapcase commands edit in place and do not modify registers. +testVim('g~w_repeat', function(cm, vim, helpers) { + // Assert that dw does delete newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('g', '~', '2', 'w'); + eq(' WORD1\nWORD2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2' }); +testVim('g~g~', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + var expectedLineCount = cm.lineCount(); + var expectedValue = cm.getValue().toUpperCase(); + helpers.doKeys('2', 'g', '~', '3', 'g', '~'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2\nword3\nword4\nword5\nword6' }); +testVim('gu_and_gU', function(cm, vim, helpers) { + var curStart = makeCursor(0, 7); + var value = cm.getValue(); + cm.setCursor(curStart); + helpers.doKeys('2', 'g', 'U', 'w'); + eq(cm.getValue(), 'wa wb xX WC wd'); + eqCursorPos(curStart, cm.getCursor()); + helpers.doKeys('2', 'g', 'u', 'w'); + eq(cm.getValue(), value); + + helpers.doKeys('2', 'g', 'U', 'B'); + eq(cm.getValue(), 'wa WB Xx wc wd'); + eqCursorPos(makeCursor(0, 3), cm.getCursor()); + + cm.setCursor(makeCursor(0, 4)); + helpers.doKeys('g', 'u', 'i', 'w'); + eq(cm.getValue(), 'wa wb Xx wc wd'); + eqCursorPos(makeCursor(0, 3), cm.getCursor()); + + // TODO: support gUgU guu + // eqCursorPos(makeCursor(0, 0), cm.getCursor()); + + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); +}, { value: 'wa wb xx wc wd' }); +testVim('visual_block_~', function(cm, vim, helpers) { + cm.setCursor(1, 1); + helpers.doKeys('', 'l', 'l', 'j', '~'); + helpers.assertCursorAt(1, 1); + eq('hello\nwoRLd\naBCDe', cm.getValue()); + cm.setCursor(2, 0); + helpers.doKeys('v', 'l', 'l', '~'); + helpers.assertCursorAt(2, 0); + eq('hello\nwoRLd\nAbcDe', cm.getValue()); +},{value: 'hello\nwOrld\nabcde' }); +testVim('._swapCase_visualBlock', function(cm, vim, helpers) { + helpers.doKeys('', 'j', 'j', 'l', '~'); + cm.setCursor(0, 3); + helpers.doKeys('.'); + eq('HelLO\nWorLd\nAbcdE', cm.getValue()); +},{value: 'hEllo\nwOrlD\naBcDe' }); +testVim('._delete_visualBlock', function(cm, vim, helpers) { + helpers.doKeys('', 'j', 'x'); + eq('ive\ne\nsome\nsugar', cm.getValue()); + helpers.doKeys('.'); + eq('ve\n\nsome\nsugar', cm.getValue()); + helpers.doKeys('j', 'j', '.'); + eq('ve\n\nome\nugar', cm.getValue()); + helpers.doKeys('u', '', '.'); + eq('ve\n\nme\ngar', cm.getValue()); +},{value: 'give\nme\nsome\nsugar' }); +testVim('>{motion}', function(cm, vim, helpers) { + cm.setCursor(1, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\n word2\nword3 '; + helpers.doKeys('>', 'k'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); +testVim('>>', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\n word2\nword3 '; + helpers.doKeys('2', '>', '>'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); +testVim('<{motion}', function(cm, vim, helpers) { + cm.setCursor(1, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('<', 'k'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); +testVim('<<', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('2', '<', '<'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); + +// Edit tests +function testEdit(name, before, pos, edit, after) { + return testVim(name, function(cm, vim, helpers) { + var ch = before.search(pos) + var line = before.substring(0, ch).split('\n').length - 1; + if (line) { + ch = before.substring(0, ch).split('\n').pop().length; + } + cm.setCursor(line, ch); + helpers.doKeys.apply(this, edit.split('')); + eq(after, cm.getValue()); + }, {value: before}); +} + +// These Delete tests effectively cover word-wise Change, Visual & Yank. +// Tabs are used as differentiated whitespace to catch edge cases. +// Normal word: +testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz'); +testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz'); +testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz'); +testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz'); +testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz'); +testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz'); +testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz'); +testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz'); +testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz'); +testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz'); +testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t'); +testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo'); +testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.'); +testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.'); +// Big word: +testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz'); +testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz'); +testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz'); +testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz'); +testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t'); +testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo'); +testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t'); +testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo'); +// Deleting text objects +// Open and close on same line +testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz'); +testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz'); +testEdit('dib_open_spc', 'foo (bAr) baz', /\(/, 'dib', 'foo () baz'); +testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo baz'); +testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo baz'); + +testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz'); +testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz'); +testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo baz'); +testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo baz'); + +testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz'); +testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz'); +testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo baz'); +testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo baz'); + +// delete around and inner b. +testEdit('dab_on_(_should_delete_around_()block', 'o( in(abc) )', /\(a/, 'dab', 'o( in )'); + +// delete around and inner B. +testEdit('daB_on_{_should_delete_around_{}block', 'o{ in{abc} }', /{a/, 'daB', 'o{ in }'); +testEdit('diB_on_{_should_delete_inner_{}block', 'o{ in{abc} }', /{a/, 'diB', 'o{ in{} }'); + +testEdit('da{_on_{_should_delete_inner_block', 'o{ in{abc} }', /{a/, 'da{', 'o{ in }'); +testEdit('di[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'di[', 'foo (bAr) baz'); +testEdit('di[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'di[', 'foo (bAr) baz'); +testEdit('da[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'da[', 'foo (bAr) baz'); +testEdit('da[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'da[', 'foo (bAr) baz'); +testMotion('di(_outside_should_stay', ['d', 'i', '('], new Pos(0, 0), new Pos(0, 0)); + +// Open and close on different lines, equally indented +testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b'); +testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b'); +testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab'); +testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab'); +testEdit('daB_middle_spc', 'a{\n\tbar\n}b', /r/, 'daB', 'ab'); + +// open and close on diff lines, open indented less than close +testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b'); +testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b'); +testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab'); +testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab'); + +// open and close on diff lines, open indented more than close +testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b'); +testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b'); +testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb'); +testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb'); + +function testSelection(name, before, pos, keys, sel) { + return testVim(name, function(cm, vim, helpers) { + var ch = before.search(pos) + var line = before.substring(0, ch).split('\n').length - 1; + if (line) { + ch = before.substring(0, ch).split('\n').pop().length; + } + cm.setCursor(line, ch); + helpers.doKeys.apply(this, keys.split('')); + eq(sel, cm.getSelection()); + }, {value: before}); +} +testSelection('viw_middle_spc', 'foo \tbAr\t baz', /A/, 'viw', 'bAr'); +testSelection('vaw_middle_spc', 'foo \tbAr\t baz', /A/, 'vaw', 'bAr\t '); +testSelection('viw_middle_punct', 'foo \tbAr,\t baz', /A/, 'viw', 'bAr'); +testSelection('vaW_middle_punct', 'foo \tbAr,\t baz', /A/, 'vaW', 'bAr,\t '); +testSelection('viw_start_spc', 'foo \tbAr\t baz', /b/, 'viw', 'bAr'); +testSelection('viw_end_spc', 'foo \tbAr\t baz', /r/, 'viw', 'bAr'); +testSelection('viw_eol', 'foo \tbAr', /r/, 'viw', 'bAr'); +testSelection('vi{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'vi{', '\n\tbar\n\t'); +testSelection('va{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'va{', '{\n\tbar\n\t}'); + +testVim('mouse_select', function(cm, vim, helpers) { + cm.setSelection(Pos(0, 2), Pos(0, 4), {origin: '*mouse'}); + is(cm.state.vim.visualMode); + is(!cm.state.vim.visualLine); + is(!cm.state.vim.visualBlock); + helpers.doKeys(''); + is(!cm.somethingSelected()); + helpers.doKeys('g', 'v'); + eq('cd', cm.getSelection()); +}, {value: 'abcdef'}); + +// Operator-motion tests +testVim('D', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('D'); + eq(' wo\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('rd1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 2); +}, { value: ' word1\nword2\n word3' }); +testVim('C', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('C'); + eq(' wo\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('rd1', register.toString()); + is(!register.linewise); + eqCursorPos(curStart, cm.getCursor()); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: ' word1\nword2\n word3' }); +testVim('Y', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('Y'); + eq(' word1\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1\n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\n word3' }); +testVim('~', function(cm, vim, helpers) { + helpers.doKeys('3', '~'); + eq('ABCdefg', cm.getValue()); + helpers.assertCursorAt(0, 3); +}, { value: 'abcdefg' }); + +// Action tests +testVim('ctrl-a', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(''); + eq('-9', cm.getValue()); + helpers.assertCursorAt(0, 1); + helpers.doKeys('2',''); + eq('-7', cm.getValue()); +}, {value: '-10'}); +testVim('ctrl-x', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(''); + eq('-1', cm.getValue()); + helpers.assertCursorAt(0, 1); + helpers.doKeys('2',''); + eq('-3', cm.getValue()); +}, {value: '0'}); +testVim('/ search forward', function(cm, vim, helpers) { + forEach(['', ''], function(key) { + cm.setCursor(0, 0); + helpers.doKeys(key); + helpers.assertCursorAt(0, 5); + helpers.doKeys('l'); + helpers.doKeys(key); + helpers.assertCursorAt(0, 10); + cm.setCursor(0, 11); + helpers.doKeys(key); + helpers.assertCursorAt(0, 11); + }); +}, {value: '__jmp1 jmp2 jmp'}); +testVim('insert_ctrl_w', function(cm, vim, helpers) { + var curStart = makeCursor(0, 10); + cm.setCursor(curStart); + helpers.doKeys('a'); + helpers.doKeys(''); + eq('word1/', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word2', register.toString()); + is(!register.linewise); + var curEnd = makeCursor(0, 6); + eqCursorPos(curEnd, cm.getCursor()); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'word1/word2' }); +testVim('a', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('a'); + helpers.assertCursorAt(0, 2); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('a_eol', function(cm, vim, helpers) { + cm.setCursor(0, lines[0].length - 1); + helpers.doKeys('a'); + helpers.assertCursorAt(0, lines[0].length); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('A_endOfSelectedArea', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'j', 'l'); + helpers.doKeys('A'); + helpers.assertCursorAt(1, 2); + eq('vim-insert', cm.getOption('keyMap')); +}, {value: 'foo\nbar'}); +testVim('i', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('i'); + helpers.assertCursorAt(0, 1); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('i_repeat', function(cm, vim, helpers) { + helpers.doKeys('3', 'i'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('testtesttest', cm.getValue()); + helpers.assertCursorAt(0, 11); +}, { value: '' }); +testVim('i_repeat_delete', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('2', 'i'); + cm.replaceRange('z', cm.getCursor()); + helpers.doInsertModeKeys('Backspace', 'Backspace'); + helpers.doKeys(''); + eq('abe', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'abcde' }); +testVim('insert', function(cm, vim, helpers) { + helpers.doKeys('i'); + eq('vim-insert', cm.getOption('keyMap')); + eq(false, cm.state.overwrite); + helpers.doKeys(''); + eq('vim-replace', cm.getOption('keyMap')); + eq(true, cm.state.overwrite); + helpers.doKeys(''); + eq('vim-insert', cm.getOption('keyMap')); + eq(false, cm.state.overwrite); +}); +testVim('i_backspace', function(cm, vim, helpers) { + cm.setCursor(0, 10); + helpers.doKeys('i'); + helpers.doInsertModeKeys('Backspace'); + helpers.assertCursorAt(0, 9); + eq('012345678', cm.getValue()); +}, { value: '0123456789'}); +testVim('i_overwrite_backspace', function(cm, vim, helpers) { + cm.setCursor(0, 10); + helpers.doKeys('i'); + helpers.doKeys(''); + helpers.doInsertModeKeys('Backspace'); + helpers.assertCursorAt(Pos(0, 9, "after")); + eq('0123456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('A', function(cm, vim, helpers) { + helpers.doKeys('A'); + helpers.assertCursorAt(0, lines[0].length); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('A_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'A'); + var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); + replacement.pop(); + cm.replaceSelections(replacement); + eq('testhello\nmehello\npleahellose', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(0, 0); + helpers.doKeys('.'); + // TODO this doesn't work yet + // eq('teshellothello\nme hello hello\nplehelloahellose', cm.getValue()); +}, {value: 'test\nme\nplease'}); +testVim('I', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('I'); + helpers.assertCursorAt(0, lines[0].textStart); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('I_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('3', 'I'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('testtesttestblah', cm.getValue()); + helpers.assertCursorAt(0, 11); +}, { value: 'blah' }); +testVim('I_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'l', 'l', 'I'); + var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); + replacement.pop(); + cm.replaceSelections(replacement); + eq('hellotest\nhellome\nhelloplease', cm.getValue()); +}, {value: 'test\nme\nplease'}); +testVim('o', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('o'); + eq('word1\n\nword2', cm.getValue()); + helpers.assertCursorAt(1, 0); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'word1\nword2' }); +testVim('o_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('3', 'o'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('\ntest\ntest\ntest', cm.getValue()); + helpers.assertCursorAt(3, 3); +}, { value: '' }); +testVim('O', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('O'); + eq('\nword1\nword2', cm.getValue()); + helpers.assertCursorAt(0, 0); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'word1\nword2' }); +testVim('J', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('J'); + var expectedValue = 'word1 word2\nword3\n word4'; + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1); +}, { value: 'word1 \n word2\nword3\n word4' }); +testVim('J_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('3', 'J'); + var expectedValue = 'word1 word2 word3\n word4'; + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1); +}, { value: 'word1 \n word2\nword3\n word4' }); +testVim('p', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); + helpers.doKeys('p'); + eq('__abc\ndef_', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_register', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); + helpers.doKeys('"', 'a', 'p'); + eq('__abc\ndef_', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_wrong_register', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); + helpers.doKeys('p'); + eq('___', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: '___' }); +testVim('p_line', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); + helpers.doKeys('2', 'p'); + eq('___\n a\nd\n a\nd', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_lastline', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd', true); + helpers.doKeys('2', 'p'); + eq('___\n a\nd\n a\nd', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim(']p_first_indent_is_smaller', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq(' ___\n abc\n def', cm.getValue()); +}, { value: ' ___' }); +testVim(']p_first_indent_is_larger', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq(' ___\n abc\ndef', cm.getValue()); +}, { value: ' ___' }); +testVim(']p_with_tab_indents', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', '\t\tabc\n\t\t\tdef\n', true); + helpers.doKeys(']', 'p'); + eq('\t___\n\tabc\n\t\tdef', cm.getValue()); +}, { value: '\t___', indentWithTabs: true}); +testVim(']p_with_spaces_translated_to_tabs', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq('\t___\n\tabc\n\t\tdef', cm.getValue()); +}, { value: '\t___', indentWithTabs: true, tabSize: 2 }); +testVim('[p', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys('[', 'p'); + eq(' abc\n def\n ___', cm.getValue()); +}, { value: ' ___' }); +testVim('P', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); + helpers.doKeys('P'); + eq('_abc\ndef__', cm.getValue()); + helpers.assertCursorAt(1, 3); +}, { value: '___' }); +testVim('P_line', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); + helpers.doKeys('2', 'P'); + eq(' a\nd\n a\nd\n___', cm.getValue()); + helpers.assertCursorAt(0, 2); +}, { value: '___' }); +testVim('r', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('3', 'r', 'u'); + eq('wuuuet\nanother', cm.getValue(),'3r failed'); + helpers.assertCursorAt(0, 3); + cm.setCursor(0, 4); + helpers.doKeys('v', 'j', 'h', 'r', ''); + eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed'); + cm.setValue("ox"); + helpers.doKeys('r', ''); + eq('ox', cm.getValue()); + helpers.doKeys('r', ''); + eq('ox', cm.getValue()); + helpers.doKeys('r', ''); + eq('\nx', cm.getValue()); +}, { value: 'wordet\nanother' }); +testVim('r_visual_block', function(cm, vim, helpers) { + cm.setCursor(2, 3); + helpers.doKeys('', 'k', 'k', 'h', 'h', 'r', 'l'); + eq('1lll\n5lll\nalllefg', cm.getValue()); + helpers.doKeys('', 'l', 'j', 'r', ''); + eq('1 l\n5 l\nalllefg', cm.getValue()); + cm.setCursor(2, 0); + helpers.doKeys('o'); + helpers.doKeys(''); + cm.replaceRange('\t\t', cm.getCursor()); + helpers.doKeys('', 'h', 'h', 'r', 'r'); + eq('1 l\n5 l\nalllefg\nrrrrrrrr', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('R', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('R'); + helpers.assertCursorAt(0, 1); + eq('vim-replace', cm.getOption('keyMap')); + is(cm.state.overwrite, 'Setting overwrite state failed'); +}); +testVim('mark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('`', 't'); + helpers.assertCursorAt(2, 2); + cm.setCursor(2, 0); + cm.replaceRange(' h', cm.getCursor()); + cm.setCursor(0, 0); + helpers.doKeys('\'', 't'); + helpers.assertCursorAt(2, 3); +}); +testVim('mark\'', function(cm, vim, helpers) { + cm.setCursor(2, 2); + cm.setCursor(0, 0); + helpers.doKeys('`', '\''); + helpers.assertCursorAt(2, 2); + cm.setCursor(2, 0); + cm.replaceRange(' h', cm.getCursor()); + cm.setCursor(0, 0); + helpers.doKeys('\'', '\''); + helpers.assertCursorAt(2, 3); +}); +testVim('mark.', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('O', 'testing', ''); + cm.setCursor(3, 3); + helpers.doKeys('\'', '.'); + helpers.assertCursorAt(0, 0); + cm.setCursor(4, 4); + helpers.doKeys('`', '.'); + helpers.assertCursorAt(0, 6); +}); +testVim('jumpToMark_next', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 2); + cm.setCursor(0, 0); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_next_repeat', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(0, 0); + helpers.doKeys('2', ']', '`'); + helpers.assertCursorAt(3, 2); + cm.setCursor(0, 0); + helpers.doKeys('2', ']', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_next_sameline', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 2); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 4); +}); +testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(4, 0); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(4, 0); +}); +testVim('jumpToMark_next_nomark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 2); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 1); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_next_action', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('d', ']', '`'); + helpers.assertCursorAt(0, 0); + var actual = cm.getLine(0); + var expected = 'pop pop 0 1 2 3 4'; + eq(actual, expected, "Deleting while jumping to the next mark failed."); +}); +testVim('jumpToMark_next_line_action', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('d', ']', '\''); + helpers.assertCursorAt(0, 1); + var actual = cm.getLine(0); + var expected = ' (a) [b] {c} ' + eq(actual, expected, "Deleting while jumping to the next mark line failed."); +}); +testVim('jumpToMark_prev', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(4, 0); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 2); + cm.setCursor(4, 0); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(5, 0); + helpers.doKeys('2', '[', '`'); + helpers.assertCursorAt(3, 2); + cm.setCursor(5, 0); + helpers.doKeys('2', '[', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 2); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) { + cm.setCursor(4, 4); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 0); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 2); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 6); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('delmark_single', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 't'); + helpers.doEx('delmarks t'); + cm.setCursor(0, 0); + helpers.doKeys('`', 't'); + helpers.assertCursorAt(0, 0); +}); +testVim('delmark_range', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks b-d'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_multi', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks bcd'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_multi_space', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks b c d'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_all', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks a b-de'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(0, 0); +}); +testVim('visual', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l'); + helpers.assertCursorAt(0, 4); + eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor')); + helpers.doKeys('d'); + eq('15', cm.getValue()); +}, { value: '12345' }); +testVim('visual_yank', function(cm, vim, helpers) { + helpers.doKeys('v', '3', 'l', 'y'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('p'); + eq('aa te test for yank', cm.getValue()); +}, { value: 'a test for yank' }) +testVim('visual_w', function(cm, vim, helpers) { + helpers.doKeys('v', 'w'); + eq(cm.getSelection(), 'motion t'); +}, { value: 'motion test'}); +testVim('visual_initial_selection', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v'); + cm.getSelection('n'); +}, { value: 'init'}); +testVim('visual_crossover_left', function(cm, vim, helpers) { + cm.setCursor(0, 2); + helpers.doKeys('v', 'l', 'h', 'h'); + cm.getSelection('ro'); +}, { value: 'cross'}); +testVim('visual_crossover_left', function(cm, vim, helpers) { + cm.setCursor(0, 2); + helpers.doKeys('v', 'h', 'l', 'l'); + cm.getSelection('os'); +}, { value: 'cross'}); +testVim('visual_crossover_up', function(cm, vim, helpers) { + cm.setCursor(3, 2); + helpers.doKeys('v', 'j', 'k', 'k'); + eqCursorPos(Pos(2, 2), cm.getCursor('head')); + eqCursorPos(Pos(3, 3), cm.getCursor('anchor')); + helpers.doKeys('k'); + eqCursorPos(Pos(1, 2), cm.getCursor('head')); + eqCursorPos(Pos(3, 3), cm.getCursor('anchor')); +}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); +testVim('visual_crossover_down', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('v', 'k', 'j', 'j'); + eqCursorPos(Pos(2, 3), cm.getCursor('head')); + eqCursorPos(Pos(1, 2), cm.getCursor('anchor')); + helpers.doKeys('j'); + eqCursorPos(Pos(3, 3), cm.getCursor('head')); + eqCursorPos(Pos(1, 2), cm.getCursor('anchor')); +}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); +testVim('visual_exit', function(cm, vim, helpers) { + helpers.doKeys('', 'l', 'j', 'j', ''); + eqCursorPos(cm.getCursor('anchor'), cm.getCursor('head')); + eq(vim.visualMode, false); +}, { value: 'hello\nworld\nfoo' }); +testVim('visual_line', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd'); + eq(' 4\n 5', cm.getValue()); +}, { value: ' 1\n 2\n 3\n 4\n 5' }); +testVim('visual_block_move_to_eol', function(cm, vim, helpers) { + // moveToEol should move all block cursors to end of line + cm.setCursor(0, 0); + helpers.doKeys('', 'G', '$'); + var selections = cm.getSelections().join(); + eq('123,45,6', selections); + // Checks that with cursor at Infinity, finding words backwards still works. + helpers.doKeys('2', 'k', 'b'); + selections = cm.getSelections().join(); + eq('1', selections); +}, {value: '123\n45\n6'}); +testVim('visual_block_different_line_lengths', function(cm, vim, helpers) { + // test the block selection with lines of different length + // i.e. extending the selection + // till the end of the longest line. + helpers.doKeys('', 'l', 'j', 'j', '6', 'l', 'd'); + helpers.doKeys('d', 'd', 'd', 'd'); + eq('', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('visual_block_truncate_on_short_line', function(cm, vim, helpers) { + // check for left side selection in case + // of moving up to a shorter line. + cm.replaceRange('', cm.getCursor()); + cm.setCursor(3, 4); + helpers.doKeys('', 'l', 'k', 'k', 'd'); + eq('hello world\n{\ntis\nsa!', cm.getValue()); +}, {value: 'hello world\n{\nthis is\nsparta!'}); +testVim('visual_block_corners', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('', '2', 'l', 'k'); + // circle around the anchor + // and check the selections + var selections = cm.getSelections(); + eq('345891', selections.join('')); + helpers.doKeys('4', 'h'); + selections = cm.getSelections(); + eq('123678', selections.join('')); + helpers.doKeys('j', 'j'); + selections = cm.getSelections(); + eq('678abc', selections.join('')); + helpers.doKeys('4', 'l'); + selections = cm.getSelections(); + eq('891cde', selections.join('')); +}, {value: '12345\n67891\nabcde'}); +testVim('visual_block_mode_switch', function(cm, vim, helpers) { + // switch between visual modes + cm.setCursor(1, 1); + // blockwise to characterwise visual + helpers.doKeys('', 'j', 'l', 'v'); + var selections = cm.getSelections(); + eq('7891\nabc', selections.join('')); + // characterwise to blockwise + helpers.doKeys(''); + selections = cm.getSelections(); + eq('78bc', selections.join('')); + // blockwise to linewise visual + helpers.doKeys('V'); + selections = cm.getSelections(); + eq('67891\nabcde', selections.join('')); +}, {value: '12345\n67891\nabcde'}); +testVim('visual_block_crossing_short_line', function(cm, vim, helpers) { + // visual block with long and short lines + cm.setCursor(0, 3); + helpers.doKeys('', 'j', 'j', 'j'); + var selections = cm.getSelections().join(); + eq('4,,d,b', selections); + helpers.doKeys('3', 'k'); + selections = cm.getSelections().join(); + eq('4', selections); + helpers.doKeys('5', 'j', 'k'); + selections = cm.getSelections().join(""); + eq(10, selections.length); +}, {value: '123456\n78\nabcdefg\nfoobar\n}\n'}); +testVim('visual_block_curPos_on_exit', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '3' , 'l', ''); + eqCursorPos(makeCursor(0, 3), cm.getCursor()); + helpers.doKeys('h', '', '2' , 'j' ,'3' , 'l'); + eq(cm.getSelections().join(), "3456,,cdef"); + helpers.doKeys('4' , 'h'); + eq(cm.getSelections().join(), "23,8,bc"); + helpers.doKeys('2' , 'l'); + eq(cm.getSelections().join(), "34,,cd"); +}, {value: '123456\n78\nabcdefg\nfoobar'}); + +testVim('visual_marks', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l', 'j', 'j', 'v'); + // Test visual mode marks + cm.setCursor(2, 1); + helpers.doKeys('\'', '<'); + helpers.assertCursorAt(0, 1); + helpers.doKeys('\'', '>'); + helpers.assertCursorAt(2, 0); +}); +testVim('visual_join', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J'); + eq(' 1 2 3\n 4\n 5', cm.getValue()); + is(!vim.visualMode); +}, { value: ' 1\n 2\n 3\n 4\n 5' }); +testVim('visual_join_2', function(cm, vim, helpers) { + helpers.doKeys('G', 'V', 'g', 'g', 'J'); + eq('1 2 3 4 5 6 ', cm.getValue()); + is(!vim.visualMode); +}, { value: '1\n2\n3\n4\n5\n6\n'}); +testVim('visual_blank', function(cm, vim, helpers) { + helpers.doKeys('v', 'k'); + eq(vim.visualMode, true); +}, { value: '\n' }); +testVim('reselect_visual', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l', 'l', 'y', 'g', 'v'); + helpers.assertCursorAt(0, 5); + eqCursorPos(makeCursor(0, 1), cm.getCursor('anchor')); + helpers.doKeys('v'); + cm.setCursor(1, 0); + helpers.doKeys('v', 'l', 'l', 'p'); + eq('123456\n2345\nbar', cm.getValue()); + cm.setCursor(0, 0); + helpers.doKeys('g', 'v'); + // here the fake cursor is at (1, 3) + helpers.assertCursorAt(1, 4); + eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor')); + helpers.doKeys('v'); + cm.setCursor(2, 0); + helpers.doKeys('v', 'l', 'l', 'g', 'v'); + helpers.assertCursorAt(1, 4); + eqCursorPos(makeCursor(1, 0), cm.getCursor('anchor')); + helpers.doKeys('g', 'v'); + helpers.assertCursorAt(2, 3); + eqCursorPos(makeCursor(2, 0), cm.getCursor('anchor')); + eq('123456\n2345\nbar', cm.getValue()); +}, { value: '123456\nfoo\nbar' }); +testVim('reselect_visual_line', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'j', 'j', 'V', 'g', 'v', 'd'); + eq('foo\nand\nbar', cm.getValue()); + cm.setCursor(1, 0); + helpers.doKeys('V', 'y', 'j'); + helpers.doKeys('V', 'p' , 'g', 'v', 'd'); + eq('foo\nand', cm.getValue()); +}, { value: 'hello\nthis\nis\nfoo\nand\nbar' }); +testVim('reselect_visual_block', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('', 'k', 'h', ''); + cm.setCursor(2, 1); + helpers.doKeys('v', 'l', 'g', 'v'); + eqCursorPos(Pos(1, 2), vim.sel.anchor); + eqCursorPos(Pos(0, 1), vim.sel.head); + // Ensure selection is done with visual block mode rather than one + // continuous range. + eq(cm.getSelections().join(''), '23oo') + helpers.doKeys('g', 'v'); + eqCursorPos(Pos(2, 1), vim.sel.anchor); + eqCursorPos(Pos(2, 2), vim.sel.head); + helpers.doKeys(''); + // Ensure selection of deleted range + cm.setCursor(1, 1); + helpers.doKeys('v', '', 'j', 'd', 'g', 'v'); + eq(cm.getSelections().join(''), 'or'); +}, { value: '123456\nfoo\nbar' }); +testVim('s_normal', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('s'); + helpers.doKeys(''); + eq('ac', cm.getValue()); +}, { value: 'abc'}); +testVim('s_visual', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v', 's'); + helpers.doKeys(''); + helpers.assertCursorAt(0, 0); + eq('ac', cm.getValue()); +}, { value: 'abc'}); +testVim('o_visual', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys('v','l','l','l','o'); + helpers.assertCursorAt(0,0); + helpers.doKeys('v','v','j','j','j','o'); + helpers.assertCursorAt(0,0); + helpers.doKeys('O'); + helpers.doKeys('l','l') + helpers.assertCursorAt(3, 3); + helpers.doKeys('d'); + eq('p',cm.getValue()); +}, { value: 'abcd\nefgh\nijkl\nmnop'}); +testVim('o_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('','3','j','l','l', 'o'); + eqCursorPos(Pos(3, 3), vim.sel.anchor); + eqCursorPos(Pos(0, 1), vim.sel.head); + helpers.doKeys('O'); + eqCursorPos(Pos(3, 1), vim.sel.anchor); + eqCursorPos(Pos(0, 3), vim.sel.head); + helpers.doKeys('o'); + eqCursorPos(Pos(0, 3), vim.sel.anchor); + eqCursorPos(Pos(3, 1), vim.sel.head); +}, { value: 'abcd\nefgh\nijkl\nmnop'}); +testVim('changeCase_visual', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'l', 'l'); + helpers.doKeys('U'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('v', 'l', 'l'); + helpers.doKeys('u'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('l', 'l', 'l', '.'); + helpers.assertCursorAt(0, 3); + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('j', '@', 'a'); + helpers.assertCursorAt(1, 0); + cm.setCursor(3, 0); + helpers.doKeys('V', 'U', 'j', '.'); + eq('ABCDEF\nGHIJKL\nMnopq\nSHORT LINE\nLONG LINE OF TEXT', cm.getValue()); +}, { value: 'abcdef\nghijkl\nmnopq\nshort line\nlong line of text'}); +testVim('changeCase_visual_block', function(cm, vim, helpers) { + cm.setCursor(2, 1); + helpers.doKeys('', 'k', 'k', 'h', 'U'); + eq('ABcdef\nGHijkl\nMNopq\nfoo', cm.getValue()); + cm.setCursor(0, 2); + helpers.doKeys('.'); + eq('ABCDef\nGHIJkl\nMNOPq\nfoo', cm.getValue()); + // check when last line is shorter. + cm.setCursor(2, 2); + helpers.doKeys('.'); + eq('ABCDef\nGHIJkl\nMNOPq\nfoO', cm.getValue()); +}, { value: 'abcdef\nghijkl\nmnopq\nfoo'}); +testVim('visual_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'l', 'l', 'y'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('3', 'l', 'j', 'v', 'l', 'p'); + helpers.assertCursorAt(1, 5); + eq('this is a\nunithitest for visual paste', cm.getValue()); + cm.setCursor(0, 0); + // in case of pasting whole line + helpers.doKeys('y', 'y'); + cm.setCursor(1, 6); + helpers.doKeys('v', 'l', 'l', 'l', 'p'); + helpers.assertCursorAt(2, 0); + eq('this is a\nunithi\nthis is a\n for visual paste', cm.getValue()); +}, { value: 'this is a\nunit test for visual paste'}); + +// This checks the contents of the register used to paste the text +testVim('v_paste_from_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + cm.setCursor(1, 0); + helpers.doKeys('v', 'p'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+register/.test(text)); + }); +}, { value: 'register contents\nare not erased'}); +testVim('S_normal', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('j', 'S'); + helpers.doKeys(''); + helpers.assertCursorAt(1, 1); + eq('aa{\n \ncc', cm.getValue()); + helpers.doKeys('j', 'S'); + eq('aa{\n \n ', cm.getValue()); + helpers.assertCursorAt(2, 2); + helpers.doKeys(''); + helpers.doKeys('d', 'd', 'd', 'd'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('S'); + is(vim.insertMode); + eq('', cm.getValue()); +}, { value: 'aa{\nbb\ncc'}); +testVim('blockwise_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '3', 'j', 'l', 'y'); + cm.setCursor(0, 2); + // paste one char after the current cursor position + helpers.doKeys('p'); + eq('helhelo\nworwold\nfoofo\nbarba', cm.getValue()); + cm.setCursor(0, 0); + helpers.doKeys('v', '4', 'l', 'y'); + cm.setCursor(0, 0); + helpers.doKeys('', '3', 'j', 'p'); + eq('helheelhelo\norwold\noofo\narba', cm.getValue()); +}, { value: 'hello\nworld\nfoo\nbar'}); +testVim('blockwise_paste_long/short_line', function(cm, vim, helpers) { + // extend short lines in case of different line lengths. + cm.setCursor(0, 0); + helpers.doKeys('', 'j', 'j', 'y'); + cm.setCursor(0, 3); + helpers.doKeys('p'); + eq('hellho\nfoo f\nbar b', cm.getValue()); +}, { value: 'hello\nfoo\nbar'}); +testVim('blockwise_paste_cut_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'x'); + cm.setCursor(0, 0); + helpers.doKeys('P'); + eq('cut\nand\npaste\nme', cm.getValue()); +}, { value: 'cut\nand\npaste\nme'}); +testVim('blockwise_paste_from_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', '"', 'a', 'y'); + cm.setCursor(0, 3); + helpers.doKeys('"', 'a', 'p'); + eq('foobfar\nhellho\nworlwd', cm.getValue()); +}, { value: 'foobar\nhello\nworld'}); +testVim('blockwise_paste_last_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'l', 'y'); + cm.setCursor(3, 0); + helpers.doKeys('p'); + eq('cut\nand\npaste\nmcue\n an\n pa', cm.getValue()); +}, { value: 'cut\nand\npaste\nme'}); + +testVim('S_visual', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v', 'j', 'S'); + helpers.doKeys(''); + helpers.assertCursorAt(0, 0); + eq('\ncc', cm.getValue()); +}, { value: 'aa\nbb\ncc'}); + +testVim('d_/', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('2', 'd', '/'); + helpers.assertCursorAt(0, 0); + eq('match \n next', cm.getValue()); + cm.openDialog = helpers.fakeOpenDialog('2'); + helpers.doKeys('d', ':'); + // TODO eq(' next', cm.getValue()); +}, { value: 'text match match \n next' }); +testVim('/ and n/N', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 11); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 6); + helpers.doKeys('N'); + helpers.assertCursorAt(0, 11); + + cm.setCursor(0, 0); + helpers.doKeys('2', '/'); + helpers.assertCursorAt(1, 6); +}, { value: 'match nope match \n nope Match' }); +testVim('/_case', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('Match'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 6); +}, { value: 'match nope match \n nope Match' }); +testVim('/_2_pcre', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', true); + cm.openDialog = helpers.fakeOpenDialog('(word){2}'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 9); + helpers.doKeys('n'); + helpers.assertCursorAt(2, 1); +}, { value: 'word\n another wordword\n wordwordword\n' }); +testVim('/_2_nopcre', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', false); + cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 9); + helpers.doKeys('n'); + helpers.assertCursorAt(2, 1); +}, { value: 'word\n another wordword\n wordwordword\n' }); +testVim('/_nongreedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('aa'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('?_nongreedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('aa'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('/_greedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a+'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('?_greedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a+'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('/_greedy_0_or_more', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a*'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 5); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 0); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa\n aa'}); +testVim('?_greedy_0_or_more', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a*'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 5); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa\n aa'}); +testVim('? and n/N', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 6); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 11); + helpers.doKeys('N'); + helpers.assertCursorAt(1, 6); + + cm.setCursor(0, 0); + helpers.doKeys('2', '?'); + helpers.assertCursorAt(0, 11); +}, { value: 'match nope match \n nope Match' }); +testVim('*', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 22); + + cm.setCursor(0, 9); + helpers.doKeys('2', '*'); + helpers.assertCursorAt(1, 8); +}, { value: 'nomatch match nomatch match \nnomatch Match' }); +testVim('*_no_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 0); +}, { value: ' \n match \n' }); +testVim('*_symbol', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('*'); + helpers.assertCursorAt(1, 0); +}, { value: ' /}\n/} match \n' }); +testVim('#', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('#'); + helpers.assertCursorAt(1, 8); + + cm.setCursor(0, 9); + helpers.doKeys('2', '#'); + helpers.assertCursorAt(0, 22); +}, { value: 'nomatch match nomatch match \nnomatch Match' }); +testVim('*_seek', function(cm, vim, helpers) { + // Should skip over space and symbols. + cm.setCursor(0, 3); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 22); +}, { value: ' := match nomatch match \nnomatch Match' }); +testVim('#', function(cm, vim, helpers) { + // Should skip over space and symbols. + cm.setCursor(0, 3); + helpers.doKeys('#'); + helpers.assertCursorAt(1, 8); +}, { value: ' := match nomatch match \nnomatch Match' }); +testVim('g*', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('g', '*'); + helpers.assertCursorAt(0, 18); + cm.setCursor(0, 8); + helpers.doKeys('3', 'g', '*'); + helpers.assertCursorAt(1, 8); +}, { value: 'matches match alsoMatch\nmatchme matching' }); +testVim('g#', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('g', '#'); + helpers.assertCursorAt(0, 0); + cm.setCursor(0, 8); + helpers.doKeys('3', 'g', '#'); + helpers.assertCursorAt(1, 0); +}, { value: 'matches match alsoMatch\nmatchme matching' }); +testVim('macro_insert', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '0', 'i'); + cm.replaceRange('foo', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q', '@', 'a'); + eq('foofoo', cm.getValue()); +}, { value: ''}); +testVim('macro_insert_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '$', 'a'); + cm.replaceRange('larry.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('a'); + cm.replaceRange('curly.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('a'); + cm.replaceRange('moe.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('@', 'a'); + // At this point, the most recent edit should be the 2nd insert change + // inside the macro, i.e. "curly.". + helpers.doKeys('.'); + eq('larry.curly.moe.larry.curly.curly.', cm.getValue()); +}, { value: ''}); +testVim('macro_space', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', ''); + helpers.assertCursorAt(0, 2); + helpers.doKeys('q', 'a', '', '', 'q'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0, 6); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0, 8); +}, { value: 'one line of text.'}); +testVim('macro_t_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 't', 'e', 'q'); + helpers.assertCursorAt(0, 1); + helpers.doKeys('l', '@', 'a'); + helpers.assertCursorAt(0, 6); + helpers.doKeys('l', ';'); + helpers.assertCursorAt(0, 12); +}, { value: 'one line of text.'}); +testVim('macro_f_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'b', 'f', 'e', 'q'); + helpers.assertCursorAt(0, 2); + helpers.doKeys('@', 'b'); + helpers.assertCursorAt(0, 7); + helpers.doKeys(';'); + helpers.assertCursorAt(0, 13); +}, { value: 'one line of text.'}); +testVim('macro_slash_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'c'); + cm.openDialog = helpers.fakeOpenDialog('e'); + helpers.doKeys('/', 'q'); + helpers.assertCursorAt(0, 2); + helpers.doKeys('@', 'c'); + helpers.assertCursorAt(0, 7); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 13); +}, { value: 'one line of text.'}); +testVim('macro_multislash_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'd'); + cm.openDialog = helpers.fakeOpenDialog('e'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('t'); + helpers.doKeys('/', 'q'); + helpers.assertCursorAt(0, 12); + helpers.doKeys('@', 'd'); + helpers.assertCursorAt(0, 15); +}, { value: 'one line of text to rule them all.'}); +testVim('macro_last_ex_command_register', function (cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('s/a/b'); + helpers.doKeys('2', '@', ':'); + eq('bbbaa', cm.getValue()); + helpers.assertCursorAt(0, 2); +}, { value: 'aaaaa'}); +testVim('macro_parens', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'z', 'i'); + cm.replaceRange('(', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('e', 'a'); + cm.replaceRange(')', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('w', '@', 'z'); + helpers.doKeys('w', '@', 'z'); + eq('(see) (spot) (run)', cm.getValue()); +}, { value: 'see spot run'}); +testVim('macro_overwrite', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'z', '0', 'i'); + cm.replaceRange('I ', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('e'); + // Now replace the macro with something else. + helpers.doKeys('q', 'z', 'a'); + cm.replaceRange('.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('e', '@', 'z'); + helpers.doKeys('e', '@', 'z'); + eq('I see. spot. run.', cm.getValue()); +}, { value: 'see spot run'}); +testVim('macro_search_f', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'f', ' '); + helpers.assertCursorAt(0,3); + helpers.doKeys('q', '0'); + helpers.assertCursorAt(0,0); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0,3); +}, { value: 'The quick brown fox jumped over the lazy dog.'}); +testVim('macro_search_2f', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '2', 'f', ' '); + helpers.assertCursorAt(0,9); + helpers.doKeys('q', '0'); + helpers.assertCursorAt(0,0); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0,9); +}, { value: 'The quick brown fox jumped over the lazy dog.'}); +testVim('macro_yank_tick', function(cm, vim, helpers) { + cm.setCursor(0, 0); + // Start recording a macro into the \' register. + helpers.doKeys('q', '\''); + helpers.doKeys('y', '', '', '', '', 'p'); + helpers.assertCursorAt(0,4); + eq('the tex parrot', cm.getValue()); +}, { value: 'the ex parrot'}); +testVim('yank_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'b', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo/.test(text)); + is(/b\s+bar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', 'l', 'j', '"', 'a', 'y'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+oo\nar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_line_to_line_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'A', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_word_to_word_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + helpers.doKeys('j', '"', 'A', 'y', 'w'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foobar/.test(text)); + is(/"\s+foobar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_line_to_word_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + helpers.doKeys('j', '"', 'A', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_word_to_line_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'A', 'y', 'w'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('macro_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'i'); + cm.replaceRange('gangnam', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('q', 'b', 'o'); + cm.replaceRange('style', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+i/.test(text)); + is(/b\s+o/.test(text)); + }); + helpers.doKeys(':'); +}, { value: ''}); +testVim('._register', function(cm,vim,helpers) { + cm.setCursor(0,0); + helpers.doKeys('i'); + cm.replaceRange('foo',cm.getCursor()); + helpers.doKeys(''); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/\.\s+foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim(':_register', function(cm,vim,helpers) { + helpers.doEx('bar'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/:\s+bar/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_register_escape', function(cm, vim, helpers) { + // Check that the register is restored if the user escapes rather than confirms. + cm.openDialog = helpers.fakeOpenDialog('waldo'); + helpers.doKeys('/'); + var onKeyDown; + var onKeyUp; + var KEYCODES = { + f: 70, + o: 79, + Esc: 27 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + onKeyUp = options.onKeyUp; + }; + var close = function() {}; + helpers.doKeys('/'); + // Fake some keyboard events coming in. + onKeyDown({keyCode: KEYCODES.f}, '', close); + onKeyUp({keyCode: KEYCODES.f}, '', close); + onKeyDown({keyCode: KEYCODES.o}, 'f', close); + onKeyUp({keyCode: KEYCODES.o}, 'f', close); + onKeyDown({keyCode: KEYCODES.o}, 'fo', close); + onKeyUp({keyCode: KEYCODES.o}, 'fo', close); + onKeyDown({keyCode: KEYCODES.Esc}, 'foo', close); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/waldo/.test(text)); + is(!/foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_register', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('foo'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/\/\s+foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_history', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('this'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('checks'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('search'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('history'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('checks'); + helpers.doKeys('/'); + var onKeyDown; + var onKeyUp; + var query = ''; + var keyCodes = { + Up: 38, + Down: 40 + }; + cm.openDialog = function(template, callback, options) { + onKeyUp = options.onKeyUp; + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') query = newVal; + } + helpers.doKeys('/'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'checks'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'history'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'search'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'this'); + onKeyDown({keyCode: keyCodes.Down}, query, close); + onKeyUp({keyCode: keyCodes.Down}, query, close); + eq(query, 'search'); +}, {value: ''}); +testVim('exCommand_history', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('registers'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('sort'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('map'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('invalid'); + helpers.doKeys(':'); + var onKeyDown; + var onKeyUp; + var input = ''; + var keyCodes = { + Up: 38, + Down: 40, + s: 115 + }; + cm.openDialog = function(template, callback, options) { + onKeyUp = options.onKeyUp; + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys(':'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'invalid'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'map'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'sort'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'registers'); + onKeyDown({keyCode: keyCodes.s}, '', close); + input = 's'; + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'sort'); +}, {value: ''}); +testVim('search_clear', function(cm, vim, helpers) { + var onKeyDown; + var input = ''; + var keyCodes = { + Ctrl: 17, + u: 85 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys('/'); + input = 'foo'; + onKeyDown({keyCode: keyCodes.Ctrl}, input, close); + onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); + eq(input, ''); +}); +testVim('exCommand_clear', function(cm, vim, helpers) { + var onKeyDown; + var input = ''; + var keyCodes = { + Ctrl: 17, + u: 85 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys(':'); + input = 'foo'; + onKeyDown({keyCode: keyCodes.Ctrl}, input, close); + onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); + eq(input, ''); +}); +testVim('.', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('2', 'd', 'w'); + helpers.doKeys('.'); + eq('5 6', cm.getValue()); +}, { value: '1 2 3 4 5 6'}); +testVim('._repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('2', 'd', 'w'); + helpers.doKeys('3', '.'); + eq('6', cm.getValue()); +}, { value: '1 2 3 4 5 6'}); +testVim('._insert', function(cm, vim, helpers) { + helpers.doKeys('i'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('testestt', cm.getValue()); + helpers.assertCursorAt(0, 6); + helpers.doKeys('O'); + cm.replaceRange('xyz', cm.getCursor()); + helpers.doInsertModeKeys('Backspace'); + helpers.doInsertModeKeys('Down'); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('xy\nxy\ntestestt', cm.getValue()); + helpers.assertCursorAt(1, 1); +}, { value: ''}); +testVim('._insert_repeat', function(cm, vim, helpers) { + helpers.doKeys('i'); + cm.replaceRange('test', cm.getCursor()); + cm.setCursor(0, 4); + helpers.doKeys(''); + helpers.doKeys('2', '.'); + eq('testesttestt', cm.getValue()); + helpers.assertCursorAt(0, 10); +}, { value: ''}); +testVim('._repeat_insert', function(cm, vim, helpers) { + helpers.doKeys('3', 'i'); + cm.replaceRange('te', cm.getCursor()); + cm.setCursor(0, 2); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('tetettetetee', cm.getValue()); + helpers.assertCursorAt(0, 10); +}, { value: ''}); +testVim('._insert_o', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + cm.setCursor(1, 1); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('\nz\nz', cm.getValue()); + helpers.assertCursorAt(2, 0); +}, { value: ''}); +testVim('._insert_o_repeat', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(1, 0); + helpers.doKeys('2', '.'); + eq('\nz\nz\nz', cm.getValue()); + helpers.assertCursorAt(3, 0); +}, { value: ''}); +testVim('._insert_o_indent', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(1, 2); + helpers.doKeys('.'); + eq('{\n z\n z', cm.getValue()); + helpers.assertCursorAt(2, 2); +}, { value: '{'}); +testVim('._insert_cw', function(cm, vim, helpers) { + helpers.doKeys('c', 'w'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(0, 3); + helpers.doKeys('2', 'l'); + helpers.doKeys('.'); + eq('test test word3', cm.getValue()); + helpers.assertCursorAt(0, 8); +}, { value: 'word1 word2 word3' }); +testVim('._insert_cw_repeat', function(cm, vim, helpers) { + // For some reason, repeat cw in desktop VIM will does not repeat insert mode + // changes. Will conform to that behavior. + helpers.doKeys('c', 'w'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(0, 4); + helpers.doKeys('l'); + helpers.doKeys('2', '.'); + eq('test test', cm.getValue()); + helpers.assertCursorAt(0, 8); +}, { value: 'word1 word2 word3' }); +testVim('._delete', function(cm, vim, helpers) { + cm.setCursor(0, 5); + helpers.doKeys('i'); + helpers.doInsertModeKeys('Backspace'); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('zace', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'zabcde'}); +testVim('._delete_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('i'); + helpers.doInsertModeKeys('Backspace'); + helpers.doKeys(''); + helpers.doKeys('2', '.'); + eq('zzce', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'zzabcde'}); +testVim('._visual_>', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('V', 'j', '>'); + cm.setCursor(2, 0) + helpers.doKeys('.'); + eq(' 1\n 2\n 3\n 4', cm.getValue()); + helpers.assertCursorAt(2, 2); +}, { value: '1\n2\n3\n4'}); +testVim('._replace_repeat', function(cm, vim, helpers) { + helpers.doKeys('R'); + cm.replaceRange('123', cm.getCursor(), offsetCursor(cm.getCursor(), 0, 3)); + cm.setCursor(0, 3); + helpers.doKeys(''); + helpers.doKeys('2', '.'); + eq('12123123\nabcdefg', cm.getValue()); + helpers.assertCursorAt(0, 7); + cm.setCursor(1, 0); + helpers.doKeys('.'); + eq('12123123\n123123g', cm.getValue()); + helpers.doKeys('l', '"', '.', 'p'); + eq('12123123\n123123g123', cm.getValue()); +}, { value: 'abcdef\nabcdefg'}); +testVim('f;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(9, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('F;', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('F', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(2, cm.getCursor().ch); +}, { value: '01x3xx6x8x'}); +testVim('t;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(8, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('T;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(2, cm.getCursor().ch); +}, { value: '0xx3xx678x'}); +testVim('f,', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('f', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(2, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('F,', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('F', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(9, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('t,', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('t', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(3, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('T,', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('T', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(8, cm.getCursor().ch); +}, { value: '01x3xx67xx'}); +testVim('fd,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('d', ';'); + eq('56789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('d', ','); + eq('01239', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fd,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('d', ';'); + eq('01239', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('d', ','); + eq('56789', cm.getValue()); +}, { value: '0123456789'}); +testVim('td,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('d', ';'); + eq('456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('d', ','); + eq('012349', cm.getValue()); +}, { value: '0123456789'}); +testVim('Td,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('d', ';'); + eq('012349', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('d', ','); + eq('456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('fc,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('c', ';', ''); + eq('56789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('c', ','); + eq('01239', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fc,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('c', ';', ''); + eq('01239', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('c', ','); + eq('56789', cm.getValue()); +}, { value: '0123456789'}); +testVim('tc,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('c', ';', ''); + eq('456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('c', ','); + eq('012349', cm.getValue()); +}, { value: '0123456789'}); +testVim('Tc,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('c', ';', ''); + eq('012349', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('c', ','); + eq('456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('fy,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('y', ';', 'P'); + eq('012340123456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('y', ',', 'P'); + eq('012345678456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fy,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('y', ';', 'p'); + eq('012345678945678', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('y', ',', 'P'); + eq('012340123456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('ty,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('y', ';', 'P'); + eq('01230123456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('y', ',', 'p'); + eq('01234567895678', cm.getValue()); +}, { value: '0123456789'}); +testVim('Ty,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('y', ';', 'p'); + eq('01234567895678', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('y', ',', 'P'); + eq('01230123456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('HML', function(cm, vim, helpers) { + var lines = 35; + var textHeight = cm.defaultTextHeight(); + cm.setSize(600, lines*textHeight); + cm.setCursor(120, 0); + helpers.doKeys('H'); + helpers.assertCursorAt(86, 2); + helpers.doKeys('L'); + helpers.assertCursorAt(120, 4); + helpers.doKeys('M'); + helpers.assertCursorAt(103,4); +}, { value: (function(){ + var lines = new Array(100); + var upper = ' xx\n'; + var lower = ' xx\n'; + upper = lines.join(upper); + lower = lines.join(lower); + return upper + lower; +})()}); + +var zVals = []; +forEach(['zb','zz','zt','z-','z.','z'], function(e, idx){ + var lineNum = 250; + var lines = 35; + testVim(e, function(cm, vim, helpers) { + var k1 = e[0]; + var k2 = e.substring(1); + var textHeight = cm.defaultTextHeight(); + cm.setSize(600, lines*textHeight); + cm.setCursor(lineNum, 0); + helpers.doKeys(k1, k2); + zVals[idx] = cm.getScrollInfo().top; + }, { value: (function(){ + return new Array(500).join('\n'); + })()}); +}); +testVim('zb_to_bottom', function(cm, vim, helpers){ + var lineNum = 250; + cm.setSize(600, 35*cm.defaultTextHeight()); + cm.setCursor(lineNum, 0); + helpers.doKeys('z', 'b'); + var scrollInfo = cm.getScrollInfo(); + eq(scrollInfo.top + scrollInfo.clientHeight, cm.charCoords(Pos(lineNum, 0), 'local').bottom); +}, { value: (function(){ + return new Array(500).join('\n'); +})()}); +testVim('zt_to_top', function(cm, vim, helpers){ + var lineNum = 250; + cm.setSize(600, 35*cm.defaultTextHeight()); + cm.setCursor(lineNum, 0); + helpers.doKeys('z', 't'); + eq(cm.getScrollInfo().top, cm.charCoords(Pos(lineNum, 0), 'local').top); +}, { value: (function(){ + return new Array(500).join('\n'); +})()}); +testVim('zb', function(cm, vim, helpers){ + eq(zVals[2], zVals[5]); +}); + +var moveTillCharacterSandbox = + 'The quick brown fox \n'; +testVim('moveTillCharacter', function(cm, vim, helpers){ + cm.setCursor(0, 0); + // Search for the 'q'. + cm.openDialog = helpers.fakeOpenDialog('q'); + helpers.doKeys('/'); + eq(4, cm.getCursor().ch); + // Jump to just before the first o in the list. + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick brown fox \n', cm.getValue()); + // Delete that one character. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick bown fox \n', cm.getValue()); + // Delete everything until the next 'o'. + helpers.doKeys('.'); + eq('The quick box \n', cm.getValue()); + // An unmatched character should have no effect. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('q'); + eq('The quick box \n', cm.getValue()); + // Matches should only be possible on single lines. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('z'); + eq('The quick box \n', cm.getValue()); + // After all that, the search for 'q' should still be active, so the 'N' command + // can run it again in reverse. Use that to delete everything back to the 'q'. + helpers.doKeys('d'); + helpers.doKeys('N'); + eq('The ox \n', cm.getValue()); + eq(4, cm.getCursor().ch); +}, { value: moveTillCharacterSandbox}); +testVim('searchForPipe', function(cm, vim, helpers){ + CodeMirror.Vim.setOption('pcre', false); + cm.setCursor(0, 0); + // Search for the '|'. + cm.openDialog = helpers.fakeOpenDialog('|'); + helpers.doKeys('/'); + eq(4, cm.getCursor().ch); +}, { value: 'this|that'}); + + +var scrollMotionSandbox = + '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'; +testVim('scrollMotion', function(cm, vim, helpers){ + var prevCursor, prevScrollInfo; + cm.setCursor(0, 0); + // ctrl-y at the top of the file should have no effect. + helpers.doKeys(''); + eq(0, cm.getCursor().line); + prevScrollInfo = cm.getScrollInfo(); + helpers.doKeys(''); + eq(1, cm.getCursor().line); + is(prevScrollInfo.top < cm.getScrollInfo().top); + // Jump to the end of the sandbox. + cm.setCursor(1000, 0); + prevCursor = cm.getCursor(); + // ctrl-e at the bottom of the file should have no effect. + helpers.doKeys(''); + eq(prevCursor.line, cm.getCursor().line); + prevScrollInfo = cm.getScrollInfo(); + helpers.doKeys(''); + eq(prevCursor.line - 1, cm.getCursor().line, "Y"); + is(prevScrollInfo.top > cm.getScrollInfo().top); +}, { value: scrollMotionSandbox}); + +var squareBracketMotionSandbox = ''+ + '({\n'+//0 + ' ({\n'+//11 + ' /*comment {\n'+//2 + ' */(\n'+//3 + '#else \n'+//4 + ' /* )\n'+//5 + '#if }\n'+//6 + ' )}*/\n'+//7 + ')}\n'+//8 + '{}\n'+//9 + '#else {{\n'+//10 + '{}\n'+//11 + '}\n'+//12 + '{\n'+//13 + '#endif\n'+//14 + '}\n'+//15 + '}\n'+//16 + '#else';//17 +testVim('[[, ]]', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(']', ']'); + helpers.assertCursorAt(9,0); + helpers.doKeys('2', ']', ']'); + helpers.assertCursorAt(13,0); + helpers.doKeys(']', ']'); + helpers.assertCursorAt(17,0); + helpers.doKeys('[', '['); + helpers.assertCursorAt(13,0); + helpers.doKeys('2', '[', '['); + helpers.assertCursorAt(9,0); + helpers.doKeys('[', '['); + helpers.assertCursorAt(0,0); +}, { value: squareBracketMotionSandbox}); +testVim('[], ][', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(']', '['); + helpers.assertCursorAt(12,0); + helpers.doKeys('2', ']', '['); + helpers.assertCursorAt(16,0); + helpers.doKeys(']', '['); + helpers.assertCursorAt(17,0); + helpers.doKeys('[', ']'); + helpers.assertCursorAt(16,0); + helpers.doKeys('2', '[', ']'); + helpers.assertCursorAt(12,0); + helpers.doKeys('[', ']'); + helpers.assertCursorAt(0,0); +}, { value: squareBracketMotionSandbox}); +testVim('[{, ]}', function(cm, vim, helpers) { + cm.setCursor(4, 10); + helpers.doKeys('[', '{'); + helpers.assertCursorAt(2,12); + helpers.doKeys('2', '[', '{'); + helpers.assertCursorAt(0,1); + cm.setCursor(4, 10); + helpers.doKeys(']', '}'); + helpers.assertCursorAt(6,11); + helpers.doKeys('2', ']', '}'); + helpers.assertCursorAt(8,1); + cm.setCursor(0,1); + helpers.doKeys(']', '}'); + helpers.assertCursorAt(8,1); + helpers.doKeys('[', '{'); + helpers.assertCursorAt(0,1); +}, { value: squareBracketMotionSandbox}); +testVim('[(, ])', function(cm, vim, helpers) { + cm.setCursor(4, 10); + helpers.doKeys('[', '('); + helpers.assertCursorAt(3,14); + helpers.doKeys('2', '[', '('); + helpers.assertCursorAt(0,0); + cm.setCursor(4, 10); + helpers.doKeys(']', ')'); + helpers.assertCursorAt(5,11); + helpers.doKeys('2', ']', ')'); + helpers.assertCursorAt(8,0); + helpers.doKeys('[', '('); + helpers.assertCursorAt(0,0); + helpers.doKeys(']', ')'); + helpers.assertCursorAt(8,0); +}, { value: squareBracketMotionSandbox}); +testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) { + forEach(['*', '/'], function(key){ + cm.setCursor(7, 0); + helpers.doKeys('2', '[', key); + helpers.assertCursorAt(2,2); + helpers.doKeys('2', ']', key); + helpers.assertCursorAt(7,5); + }); +}, { value: squareBracketMotionSandbox}); +testVim('[#, ]#', function(cm, vim, helpers) { + cm.setCursor(10, 3); + helpers.doKeys('2', '[', '#'); + helpers.assertCursorAt(4,0); + helpers.doKeys('5', ']', '#'); + helpers.assertCursorAt(17,0); + cm.setCursor(10, 3); + helpers.doKeys(']', '#'); + helpers.assertCursorAt(14,0); +}, { value: squareBracketMotionSandbox}); +testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) { + cm.setCursor(11, 0); + helpers.doKeys('[', 'm'); + helpers.assertCursorAt(10,7); + helpers.doKeys('4', '[', 'm'); + helpers.assertCursorAt(1,3); + helpers.doKeys('5', ']', 'm'); + helpers.assertCursorAt(11,0); + helpers.doKeys('[', 'M'); + helpers.assertCursorAt(9,1); + helpers.doKeys('3', ']', 'M'); + helpers.assertCursorAt(15,0); + helpers.doKeys('5', '[', 'M'); + helpers.assertCursorAt(7,3); +}, { value: squareBracketMotionSandbox}); + +testVim('i_indent_right', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('i', ''); + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, 5); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); +testVim('i_indent_left', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('i', ''); + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); + +// Ex mode tests +testVim('ex_go_to_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('4'); + helpers.assertCursorAt(3, 0); +}, { value: 'a\nb\nc\nd\ne\n'}); +testVim('ex_go_to_mark', function(cm, vim, helpers) { + cm.setCursor(3, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(0, 0); + helpers.doEx('\'a'); + helpers.assertCursorAt(3, 0); +}, { value: 'a\nb\nc\nd\ne\n'}); +testVim('ex_go_to_line_offset', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('+3'); + helpers.assertCursorAt(3, 0); + helpers.doEx('-1'); + helpers.assertCursorAt(2, 0); + helpers.doEx('.2'); + helpers.assertCursorAt(4, 0); + helpers.doEx('.-3'); + helpers.assertCursorAt(1, 0); +}, { value: 'a\nb\nc\nd\ne\n'}); +testVim('ex_go_to_mark_offset', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(0, 0); + helpers.doEx('\'a1'); + helpers.assertCursorAt(3, 0); + helpers.doEx('\'a-1'); + helpers.assertCursorAt(1, 0); + helpers.doEx('\'a+2'); + helpers.assertCursorAt(4, 0); +}, { value: 'a\nb\nc\nd\ne\n'}); +testVim('ex_write', function(cm, vim, helpers) { + var tmp = CodeMirror.commands.save; + var written; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + // Test that w, wr, wri ... write all trigger :write. + var command = 'write'; + for (var i = 1; i < command.length; i++) { + written = false; + actualCm = null; + helpers.doEx(command.substring(0, i)); + eq(written, true); + eq(actualCm, cm); + } + CodeMirror.commands.save = tmp; +}); +testVim('ex_sort', function(cm, vim, helpers) { + helpers.doEx('sort'); + eq('Z\na\nb\nc\nd', cm.getValue()); +}, { value: 'b\nZ\nd\nc\na'}); +testVim('ex_sort_reverse', function(cm, vim, helpers) { + helpers.doEx('sort!'); + eq('d\nc\nb\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_range', function(cm, vim, helpers) { + helpers.doEx('2,3sort'); + eq('b\nc\nd\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_oneline', function(cm, vim, helpers) { + helpers.doEx('2sort'); + // Expect no change. + eq('b\nd\nc\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_ignoreCase', function(cm, vim, helpers) { + helpers.doEx('sort i'); + eq('a\nb\nc\nd\nZ', cm.getValue()); +}, { value: 'b\nZ\nd\nc\na'}); +testVim('ex_sort_unique', function(cm, vim, helpers) { + helpers.doEx('sort u'); + eq('Z\na\nb\nc\nd', cm.getValue()); +}, { value: 'b\nZ\na\na\nd\na\nc\na'}); +testVim('ex_sort_decimal', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('d3\n s5\n6\n.9', cm.getValue()); +}, { value: '6\nd3\n s5\n.9'}); +testVim('ex_sort_decimal_negative', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('z-9\nd3\n s5\n6\n.9', cm.getValue()); +}, { value: '6\nd3\n s5\n.9\nz-9'}); +testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! d'); + eq('.9\n6\n s5\nd3', cm.getValue()); +}, { value: '6\nd3\n s5\n.9'}); +testVim('ex_sort_hex', function(cm, vim, helpers) { + helpers.doEx('sort x'); + eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue()); +}, { value: '6\nd3\n s5\n&0xB\n.9'}); +testVim('ex_sort_octal', function(cm, vim, helpers) { + helpers.doEx('sort o'); + eq('.9\n.8\nd3\n s5\n6', cm.getValue()); +}, { value: '6\nd3\n s5\n.9\n.8'}); +testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('z\ny\nc1\nb2\na3', cm.getValue()); +}, { value: 'a3\nz\nc1\ny\nb2'}); +testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! d'); + eq('a3\nb2\nc1\nz\ny', cm.getValue()); +}, { value: 'a3\nz\nc1\ny\nb2'}); +testVim('ex_sort_pattern_alpha', function(cm, vim, helpers) { + helpers.doEx('sort /[a-z]/'); + eq('a3\nb2\nc1\ny\nz', cm.getValue()); +}, { value: 'z\ny\nc1\nb2\na3'}); +testVim('ex_sort_pattern_alpha_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! /[a-z]/'); + eq('z\ny\nc1\nb2\na3', cm.getValue()); +}, { value: 'z\ny\nc1\nb2\na3'}); +testVim('ex_sort_pattern_alpha_ignoreCase', function(cm, vim, helpers) { + helpers.doEx('sort i/[a-z]/'); + eq('a3\nb2\nC1\nY\nz', cm.getValue()); +}, { value: 'z\nY\nC1\nb2\na3'}); +testVim('ex_sort_pattern_alpha_longer', function(cm, vim, helpers) { + helpers.doEx('sort /[a-z]+/'); + eq('a\naa\nab\nade\nadele\nadelle\nadriana\nalex\nalexandra\nb\nc\ny\nz', cm.getValue()); +}, { value: 'z\nab\naa\nade\nadelle\nalexandra\nalex\nadriana\nadele\ny\nc\nb\na'}); +testVim('ex_sort_pattern_alpha_only', function(cm, vim, helpers) { + helpers.doEx('sort /^[a-z]$/'); + eq('z1\ny2\na3\nb\nc', cm.getValue()); +}, { value: 'z1\ny2\na3\nc\nb'}); +testVim('ex_sort_pattern_alpha_only_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! /^[a-z]$/'); + eq('c\nb\nz1\ny2\na3', cm.getValue()); +}, { value: 'z1\ny2\na3\nc\nb'}); +testVim('ex_sort_pattern_alpha_num', function(cm, vim, helpers) { + helpers.doEx('sort /[a-z][0-9]/'); + eq('c\nb\na3\ny2\nz1', cm.getValue()); +}, { value: 'z1\ny2\na3\nc\nb'}); +// test for :global command +testVim('ex_global', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('g/one/s//two'); + eq('two two\n two two\n two two', cm.getValue()); + helpers.doEx('1,2g/two/s//one'); + eq('one one\n one one\n two two', cm.getValue()); +}, {value: 'one one\n one one\n one one'}); +testVim('ex_global_confirm', function(cm, vim, helpers) { + cm.setCursor(0, 0); + var onKeyDown; + var openDialogSave = cm.openDialog; + var KEYCODES = { + a: 65, + n: 78, + q: 81, + y: 89 + }; + // Intercept the ex command, 'global' + cm.openDialog = function(template, callback, options) { + // Intercept the prompt for the embedded ex command, 'substitute' + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + callback('g/one/s//two/gc'); + }; + helpers.doKeys(':'); + var close = function() {}; + onKeyDown({keyCode: KEYCODES.n}, '', close); + onKeyDown({keyCode: KEYCODES.y}, '', close); + onKeyDown({keyCode: KEYCODES.a}, '', close); + onKeyDown({keyCode: KEYCODES.q}, '', close); + onKeyDown({keyCode: KEYCODES.y}, '', close); + eq('one two\n two two\n one one\n two one\n one one', cm.getValue()); +}, {value: 'one one\n one one\n one one\n one one\n one one'}); +// Basic substitute tests. +testVim('ex_substitute_same_line', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('s/one/two/g'); + eq('one one\n two two', cm.getValue()); +}, { value: 'one one\n one one'}); +testVim('ex_substitute_full_file', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/one/two/g'); + eq('two two\n two two', cm.getValue()); +}, { value: 'one one\n one one'}); +testVim('ex_substitute_input_range', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('1,3s/\\d/0/g'); + eq('0\n0\n0\n4', cm.getValue()); +}, { value: '1\n2\n3\n4' }); +testVim('ex_substitute_range_current_to_input', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('.,3s/\\d/0/g'); + eq('1\n0\n0\n4', cm.getValue()); +}, { value: '1\n2\n3\n4' }); +testVim('ex_substitute_range_input_to_current', function(cm, vim, helpers) { + cm.setCursor(3, 0); + helpers.doEx('2,.s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_range_offset', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doEx('-1,+1s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_range_implicit_offset', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('.1,.3s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_to_eof', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doEx('.,$s/\\d/0/g'); + eq('1\n2\n0\n0\n0', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_to_relative_eof', function(cm, vim, helpers) { + cm.setCursor(4, 0); + helpers.doEx('2,$-2s/\\d/0/g'); + eq('1\n0\n0\n4\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_range_mark', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('ma'); + cm.setCursor(0, 0); + helpers.doEx('.,\'as/\\d/0/g'); + eq('0\n0\n0\n4\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_range_mark_offset', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('ma'); + cm.setCursor(0, 0); + helpers.doEx('\'a-1,\'a+1s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_visual_range', function(cm, vim, helpers) { + cm.setCursor(1, 0); + // Set last visual mode selection marks '< and '> at lines 2 and 4 + helpers.doKeys('V', '2', 'j', 'v'); + helpers.doEx('\'<,\'>s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_empty_query', function(cm, vim, helpers) { + // If the query is empty, use last query. + cm.setCursor(1, 0); + cm.openDialog = helpers.fakeOpenDialog('1'); + helpers.doKeys('/'); + helpers.doEx('s//b/g'); + eq('abb ab2 ab3', cm.getValue()); +}, { value: 'a11 a12 a13' }); +testVim('ex_substitute_javascript', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', false); + cm.setCursor(1, 0); + // Throw all the things that javascript likes to treat as special values + // into the replace part. All should be literal (this is VIM). + helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/g') + eq('a $$ $\' $` $& 0 b', cm.getValue()); +}, { value: 'a 0 b' }); +testVim('ex_substitute_empty_arguments', function(cm,vim,helpers) { + cm.setCursor(0, 0); + helpers.doEx('s/a/b/g'); + cm.setCursor(1, 0); + helpers.doEx('s'); + eq('b b\nb a', cm.getValue()); +}, {value: 'a a\na a'}); + +// More complex substitute tests that test both pcre and nopcre options. +function testSubstitute(name, options) { + testVim(name + '_pcre', function(cm, vim, helpers) { + cm.setCursor(1, 0); + CodeMirror.Vim.setOption('pcre', true); + helpers.doEx(options.expr); + eq(options.expectedValue, cm.getValue()); + }, options); + // If no noPcreExpr is defined, assume that it's the same as the expr. + var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr; + testVim(name + '_nopcre', function(cm, vim, helpers) { + cm.setCursor(1, 0); + CodeMirror.Vim.setOption('pcre', false); + helpers.doEx(noPcreExpr); + eq(options.expectedValue, cm.getValue()); + }, options); +} +testSubstitute('ex_substitute_capture', { + value: 'a11 a12 a13', + expectedValue: 'a1111 a1212 a1313', + // $n is a backreference + expr: 's/(\\d+)/$1$1/g', + // \n is a backreference. + noPcreExpr: 's/\\(\\d+\\)/\\1\\1/g'}); +testSubstitute('ex_substitute_capture2', { + value: 'a 0 b', + expectedValue: 'a $00 b', + expr: 's/(\\d+)/$$$1$1/g', + noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/g'}); +testSubstitute('ex_substitute_nocapture', { + value: 'a11 a12 a13', + expectedValue: 'a$1$1 a$1$1 a$1$1', + expr: 's/(\\d+)/$$1$$1/g', + noPcreExpr: 's/\\(\\d+\\)/$1$1/g'}); +testSubstitute('ex_substitute_nocapture2', { + value: 'a 0 b', + expectedValue: 'a $10 b', + expr: 's/(\\d+)/$$1$1/g', + noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/g'}); +testSubstitute('ex_substitute_nocapture', { + value: 'a b c', + expectedValue: 'a $ c', + expr: 's/b/$$/', + noPcreExpr: 's/b/$/'}); +testSubstitute('ex_substitute_slash_regex', { + value: 'one/two \n three/four', + expectedValue: 'one|two \n three|four', + expr: '%s/\\//|'}); +testSubstitute('ex_substitute_pipe_regex', { + value: 'one|two \n three|four', + expectedValue: 'one,two \n three,four', + expr: '%s/\\|/,/', + noPcreExpr: '%s/|/,/'}); +testSubstitute('ex_substitute_or_regex', { + value: 'one|two \n three|four', + expectedValue: 'ana|twa \n thraa|faar', + expr: '%s/o|e|u/a/g', + noPcreExpr: '%s/o\\|e\\|u/a/g'}); +testSubstitute('ex_substitute_or_word_regex', { + value: 'one|two \n three|four', + expectedValue: 'five|five \n three|four', + expr: '%s/(one|two)/five/g', + noPcreExpr: '%s/\\(one\\|two\\)/five/g'}); +testSubstitute('ex_substitute_backslashslash_regex', { + value: 'one\\two \n three\\four', + expectedValue: 'one,two \n three,four', + expr: '%s/\\\\/,'}); +testSubstitute('ex_substitute_slash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one/two \n three/four', + expr: '%s/,/\\/'}); +testSubstitute('ex_substitute_backslash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one\\two \n three\\four', + expr: '%s/,/\\\\/g'}); +testSubstitute('ex_substitute_multibackslash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes. + expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes. +testSubstitute('ex_substitute_dollar_match', { + value: 'one,two \n three,four', + expectedValue: 'one,two ,\n three,four', + expr: '%s/$/,/g'}); +testSubstitute('ex_substitute_newline_match', { + value: 'one,two \n three,four', + expectedValue: 'one,two , three,four', + expr: '%s/\\n/,/g'}); +testSubstitute('ex_substitute_newline_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one\ntwo \n three\nfour', + expr: '%s/,/\\n/g'}); +testSubstitute('ex_substitute_braces_word', { + value: 'ababab abb ab{2}', + expectedValue: 'ab abb ab{2}', + expr: '%s/(ab){2}//g', + noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'}); +testSubstitute('ex_substitute_braces_range', { + value: 'a aa aaa aaaa', + expectedValue: 'a a', + expr: '%s/a{2,3}//g', + noPcreExpr: '%s/a\\{2,3\\}//g'}); +testSubstitute('ex_substitute_braces_literal', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab abb ', + expr: '%s/ab\\{2\\}//g', + noPcreExpr: '%s/ab{2}//g'}); +testSubstitute('ex_substitute_braces_char', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab ab{2}', + expr: '%s/ab{2}//g', + noPcreExpr: '%s/ab\\{2\\}//g'}); +testSubstitute('ex_substitute_braces_no_escape', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab ab{2}', + expr: '%s/ab{2}//g', + noPcreExpr: '%s/ab\\{2}//g'}); +testSubstitute('ex_substitute_count', { + value: '1\n2\n3\n4', + expectedValue: '1\n0\n0\n4', + expr: 's/\\d/0/i 2'}); +testSubstitute('ex_substitute_count_with_range', { + value: '1\n2\n3\n4', + expectedValue: '1\n2\n0\n0', + expr: '1,3s/\\d/0/ 3'}); +testSubstitute('ex_substitute_not_global', { + value: 'aaa\nbaa\ncaa', + expectedValue: 'xaa\nbxa\ncxa', + expr: '%s/a/x/'}); +function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) { + testVim(name, function(cm, vim, helpers) { + var savedOpenDialog = cm.openDialog; + var savedKeyName = CodeMirror.keyName; + var onKeyDown; + var recordedCallback; + var closed = true; // Start out closed, set false on second openDialog. + function close() { + closed = true; + } + // First openDialog should save callback. + cm.openDialog = function(template, callback, options) { + recordedCallback = callback; + } + // Do first openDialog. + helpers.doKeys(':'); + // Second openDialog should save keyDown handler. + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + closed = false; + }; + // Return the command to Vim and trigger second openDialog. + recordedCallback(command); + // The event should really use keyCode, but here just mock it out and use + // key and replace keyName to just return key. + CodeMirror.keyName = function (e) { return e.key; } + keys = keys.toUpperCase(); + for (var i = 0; i < keys.length; i++) { + is(!closed); + onKeyDown({ key: keys.charAt(i) }, '', close); + } + try { + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(finalPos); + is(closed); + } catch(e) { + throw e + } finally { + // Restore overridden functions. + CodeMirror.keyName = savedKeyName; + cm.openDialog = savedOpenDialog; + } + }, { value: initialValue }); +}; +testSubstituteConfirm('ex_substitute_confirm_emptydoc', + '%s/x/b/c', '', '', '', makeCursor(0, 0)); +testSubstituteConfirm('ex_substitute_confirm_nomatch', + '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0)); +testSubstituteConfirm('ex_substitute_confirm_accept', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_random_keys', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_some', + '%s/a/b/cg', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_all', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_accept_then_all', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_quit', + '%s/a/b/cg', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_last', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_oneline', + '1s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_range_accept', + '1,2s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_some', + '1,3s/a/b/cg', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_all', + '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_last', + '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0)); +//:noh should clear highlighting of search-results but allow to resume search through n +testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('?'); + helpers.doEx('noh'); + eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared'); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting'); +}, { value: 'match nope match \n nope Match' }); +testVim('ex_yank', function (cm, vim, helpers) { + var curStart = makeCursor(3, 0); + cm.setCursor(curStart); + helpers.doEx('y'); + var register = helpers.getRegisterController().getRegister(); + var line = cm.getLine(3); + eq(line + '\n', register.toString()); +}); +testVim('set_boolean', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', true, 'boolean'); + // Test default value is set. + is(CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set to non-boolean + CodeMirror.Vim.setOption('testoption', '5'); + fail(); + } catch (expected) {} + // Test setOption + CodeMirror.Vim.setOption('testoption', false); + is(!CodeMirror.Vim.getOption('testoption')); +}); +testVim('ex_set_boolean', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', true, 'boolean'); + // Test default value is set. + is(CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set to non-boolean + helpers.doEx('set testoption=22'); + fail(); + } catch (expected) {} + // Test setOption + helpers.doEx('set notestoption'); + is(!CodeMirror.Vim.getOption('testoption')); +}); +testVim('set_string', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', 'a', 'string'); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set non-string. + CodeMirror.Vim.setOption('testoption', true); + fail(); + } catch (expected) {} + try { + // Test fail to set 'notestoption' + CodeMirror.Vim.setOption('notestoption', 'b'); + fail(); + } catch (expected) {} + // Test setOption + CodeMirror.Vim.setOption('testoption', 'c'); + eq('c', CodeMirror.Vim.getOption('testoption')); +}); +testVim('ex_set_string', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testopt', 'a', 'string'); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testopt')); + try { + // Test fail to set 'notestopt' + helpers.doEx('set notestopt=b'); + fail(); + } catch (expected) {} + // Test setOption + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt')); + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global + eq('c', CodeMirror.Vim.getOption('testopt')); // global + // Test setOption global + helpers.doEx('setg testopt=d') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); + // Test setOption local + helpers.doEx('setl testopt=e') + eq('e', CodeMirror.Vim.getOption('testopt', cm)); + eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); +}); +testVim('ex_set_callback', function(cm, vim, helpers) { + var global; + + function cb(val, cm, cfg) { + if (val === undefined) { + // Getter + if (cm) { + return cm._local; + } else { + return global; + } + } else { + // Setter + if (cm) { + cm._local = val; + } else { + global = val; + } + } + } + + CodeMirror.Vim.defineOption('testopt', 'a', 'string', cb); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testopt')); + try { + // Test fail to set 'notestopt' + helpers.doEx('set notestopt=b'); + fail(); + } catch (expected) {} + // Test setOption (Identical to the string tests, but via callback instead) + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global + eq('c', CodeMirror.Vim.getOption('testopt')); // global + // Test setOption global + helpers.doEx('setg testopt=d') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); + // Test setOption local + helpers.doEx('setl testopt=e') + eq('e', CodeMirror.Vim.getOption('testopt', cm)); + eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); +}) +testVim('ex_set_filetype', function(cm, vim, helpers) { + CodeMirror.defineMode('test_mode', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + CodeMirror.defineMode('test_mode_2', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + // Test mode is set. + helpers.doEx('set filetype=test_mode'); + eq('test_mode', cm.getMode().name); + // Test 'ft' alias also sets mode. + helpers.doEx('set ft=test_mode_2'); + eq('test_mode_2', cm.getMode().name); +}); +testVim('ex_set_filetype_null', function(cm, vim, helpers) { + CodeMirror.defineMode('test_mode', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + cm.setOption('mode', 'test_mode'); + // Test mode is set to null. + helpers.doEx('set filetype='); + eq('null', cm.getMode().name); +}); +// TODO: Reset key maps after each test. +testVim('ex_map_key2key', function(cm, vim, helpers) { + helpers.doEx('map a x'); + helpers.doKeys('a'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); +testVim('ex_unmap_key2key', function(cm, vim, helpers) { + helpers.doEx('unmap a'); + helpers.doKeys('a'); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'abc' }); +testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) { + try { + helpers.doEx('unmap a'); + fail(); + } catch (expected) {} + helpers.doKeys('a'); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'abc' }); +testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) { + helpers.doEx('map ; :'); + var dialogOpened = false; + cm.openDialog = function() { + dialogOpened = true; + } + helpers.doKeys(';'); + eq(dialogOpened, true); +}); +testVim('ex_map_ex2key:', function(cm, vim, helpers) { + helpers.doEx('map :del x'); + helpers.doEx('del'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); +testVim('ex_map_ex2ex', function(cm, vim, helpers) { + helpers.doEx('map :del :w'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + helpers.doEx('del'); + CodeMirror.commands.save = tmp; + eq(written, true); + eq(actualCm, cm); +}); +testVim('ex_map_key2ex', function(cm, vim, helpers) { + helpers.doEx('map a :w'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + helpers.doKeys('a'); + CodeMirror.commands.save = tmp; + eq(written, true); + eq(actualCm, cm); +}); +testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) { + CodeMirror.Vim.map('b', ':w', 'visual'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + // Mapping should not work in normal mode. + helpers.doKeys('b'); + eq(written, false); + // Mapping should work in visual mode. + helpers.doKeys('v', 'b'); + eq(written, true); + eq(actualCm, cm); + + CodeMirror.commands.save = tmp; +}); +testVim('ex_imap', function(cm, vim, helpers) { + CodeMirror.Vim.map('jk', '', 'insert'); + helpers.doKeys('i'); + is(vim.insertMode); + helpers.doKeys('j', 'k'); + is(!vim.insertMode); + cm.setCursor(0, 1); + CodeMirror.Vim.map('jj', '', 'insert'); + helpers.doKeys('', '2', 'j', 'l', 'c'); + var replacement = fillArray('fo', 3); + cm.replaceSelections(replacement); + eq('1fo4\n5fo8\nafodefg', cm.getValue()); + helpers.doKeys('j', 'j'); + cm.setCursor(0, 0); + helpers.doKeys('.'); + eq('foo4\nfoo8\nfoodefg', cm.getValue()); +}, { value: '1234\n5678\nabcdefg' }); +testVim('ex_unmap_api', function(cm, vim, helpers) { + CodeMirror.Vim.map('', 'gg', 'normal'); + is(CodeMirror.Vim.handleKey(cm, "", "normal"), "Alt-X key is mapped"); + CodeMirror.Vim.unmap("", "normal"); + is(!CodeMirror.Vim.handleKey(cm, "", "normal"), "Alt-X key is unmapped"); +}); + +// Testing registration of functions as ex-commands and mapping to -keys +testVim('ex_api_test', function(cm, vim, helpers) { + var res=false; + var val='from'; + CodeMirror.Vim.defineEx('extest','ext',function(cm,params){ + if(params.args)val=params.args[0]; + else res=true; + }); + helpers.doEx(':ext to'); + eq(val,'to','Defining ex-command failed'); + CodeMirror.Vim.map('',':ext'); + helpers.doKeys('',''); + is(res,'Mapping to key failed'); +}); +// For now, this test needs to be last because it messes up : for future tests. +testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) { + helpers.doEx('map : x'); + helpers.doKeys(':'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); + +// Test event handlers +testVim('beforeSelectionChange', function(cm, vim, helpers) { + cm.setCursor(0, 100); + eqCursorPos(cm.getCursor('head'), cm.getCursor('anchor')); +}, { value: 'abc' }); + + diff --git a/backend/webif/static/codemirror/theme/3024-day.css b/backend/webif/static/codemirror/theme/3024-day.css new file mode 100755 index 000000000..713265530 --- /dev/null +++ b/backend/webif/static/codemirror/theme/3024-day.css @@ -0,0 +1,41 @@ +/* + + Name: 3024 day + Author: Jan T. Sott (http://github.com/idleberg) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; } +.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; } + +.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; } +.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; } + +.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; } +.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; } +.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; } +.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; } + +.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; } + +.cm-s-3024-day span.cm-comment { color: #cdab53; } +.cm-s-3024-day span.cm-atom { color: #a16a94; } +.cm-s-3024-day span.cm-number { color: #a16a94; } + +.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; } +.cm-s-3024-day span.cm-keyword { color: #db2d20; } +.cm-s-3024-day span.cm-string { color: #fded02; } + +.cm-s-3024-day span.cm-variable { color: #01a252; } +.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; } +.cm-s-3024-day span.cm-def { color: #e8bbd0; } +.cm-s-3024-day span.cm-bracket { color: #3a3432; } +.cm-s-3024-day span.cm-tag { color: #db2d20; } +.cm-s-3024-day span.cm-link { color: #a16a94; } +.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; } + +.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; } diff --git a/backend/webif/static/codemirror/theme/3024-night.css b/backend/webif/static/codemirror/theme/3024-night.css new file mode 100755 index 000000000..adc5900ad --- /dev/null +++ b/backend/webif/static/codemirror/theme/3024-night.css @@ -0,0 +1,39 @@ +/* + + Name: 3024 night + Author: Jan T. Sott (http://github.com/idleberg) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; } +.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; } +.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); } +.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); } +.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; } +.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; } +.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; } +.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; } + +.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; } + +.cm-s-3024-night span.cm-comment { color: #cdab53; } +.cm-s-3024-night span.cm-atom { color: #a16a94; } +.cm-s-3024-night span.cm-number { color: #a16a94; } + +.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; } +.cm-s-3024-night span.cm-keyword { color: #db2d20; } +.cm-s-3024-night span.cm-string { color: #fded02; } + +.cm-s-3024-night span.cm-variable { color: #01a252; } +.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; } +.cm-s-3024-night span.cm-def { color: #e8bbd0; } +.cm-s-3024-night span.cm-bracket { color: #d6d5d4; } +.cm-s-3024-night span.cm-tag { color: #db2d20; } +.cm-s-3024-night span.cm-link { color: #a16a94; } +.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; } + +.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; } +.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/abcdef.css b/backend/webif/static/codemirror/theme/abcdef.css new file mode 100755 index 000000000..cf9353094 --- /dev/null +++ b/backend/webif/static/codemirror/theme/abcdef.css @@ -0,0 +1,32 @@ +.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; } +.cm-s-abcdef div.CodeMirror-selected { background: #515151; } +.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); } +.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); } +.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; } +.cm-s-abcdef .CodeMirror-guttermarker { color: #222; } +.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; } +.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; } +.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; } + +.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; } +.cm-s-abcdef span.cm-atom { color: #77F; } +.cm-s-abcdef span.cm-number { color: violet; } +.cm-s-abcdef span.cm-def { color: #fffabc; } +.cm-s-abcdef span.cm-variable { color: #abcdef; } +.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; } +.cm-s-abcdef span.cm-variable-3, .cm-s-abcdef span.cm-type { color: #def; } +.cm-s-abcdef span.cm-property { color: #fedcba; } +.cm-s-abcdef span.cm-operator { color: #ff0; } +.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;} +.cm-s-abcdef span.cm-string { color: #2b4; } +.cm-s-abcdef span.cm-meta { color: #C9F; } +.cm-s-abcdef span.cm-qualifier { color: #FFF700; } +.cm-s-abcdef span.cm-builtin { color: #30aabc; } +.cm-s-abcdef span.cm-bracket { color: #8a8a8a; } +.cm-s-abcdef span.cm-tag { color: #FFDD44; } +.cm-s-abcdef span.cm-attribute { color: #DDFF00; } +.cm-s-abcdef span.cm-error { color: #FF0000; } +.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; } +.cm-s-abcdef span.cm-link { color: blueviolet; } + +.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; } diff --git a/backend/webif/static/codemirror/theme/ambiance-mobile.css b/backend/webif/static/codemirror/theme/ambiance-mobile.css new file mode 100755 index 000000000..88d332e1a --- /dev/null +++ b/backend/webif/static/codemirror/theme/ambiance-mobile.css @@ -0,0 +1,5 @@ +.cm-s-ambiance.CodeMirror { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} diff --git a/backend/webif/static/codemirror/theme/ambiance.css b/backend/webif/static/codemirror/theme/ambiance.css new file mode 100755 index 000000000..782fca43f --- /dev/null +++ b/backend/webif/static/codemirror/theme/ambiance.css @@ -0,0 +1,74 @@ +/* ambiance theme for codemirror */ + +/* Color scheme */ + +.cm-s-ambiance .cm-header { color: blue; } +.cm-s-ambiance .cm-quote { color: #24C2C7; } + +.cm-s-ambiance .cm-keyword { color: #cda869; } +.cm-s-ambiance .cm-atom { color: #CF7EA9; } +.cm-s-ambiance .cm-number { color: #78CF8A; } +.cm-s-ambiance .cm-def { color: #aac6e3; } +.cm-s-ambiance .cm-variable { color: #ffb795; } +.cm-s-ambiance .cm-variable-2 { color: #eed1b3; } +.cm-s-ambiance .cm-variable-3, .cm-s-ambiance .cm-type { color: #faded3; } +.cm-s-ambiance .cm-property { color: #eed1b3; } +.cm-s-ambiance .cm-operator { color: #fa8d6a; } +.cm-s-ambiance .cm-comment { color: #555; font-style:italic; } +.cm-s-ambiance .cm-string { color: #8f9d6a; } +.cm-s-ambiance .cm-string-2 { color: #9d937c; } +.cm-s-ambiance .cm-meta { color: #D2A8A1; } +.cm-s-ambiance .cm-qualifier { color: yellow; } +.cm-s-ambiance .cm-builtin { color: #9999cc; } +.cm-s-ambiance .cm-bracket { color: #24C2C7; } +.cm-s-ambiance .cm-tag { color: #fee4ff; } +.cm-s-ambiance .cm-attribute { color: #9B859D; } +.cm-s-ambiance .cm-hr { color: pink; } +.cm-s-ambiance .cm-link { color: #F4C20B; } +.cm-s-ambiance .cm-special { color: #FF9D00; } +.cm-s-ambiance .cm-error { color: #AF2018; } + +.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; } +.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; } + +.cm-s-ambiance div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } +.cm-s-ambiance.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-ambiance .CodeMirror-line::selection, .cm-s-ambiance .CodeMirror-line > span::selection, .cm-s-ambiance .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-ambiance .CodeMirror-line::-moz-selection, .cm-s-ambiance .CodeMirror-line > span::-moz-selection, .cm-s-ambiance .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } + +/* Editor styling */ + +.cm-s-ambiance.CodeMirror { + line-height: 1.40em; + color: #E6E1DC; + background-color: #202020; + -webkit-box-shadow: inset 0 0 10px black; + -moz-box-shadow: inset 0 0 10px black; + box-shadow: inset 0 0 10px black; +} + +.cm-s-ambiance .CodeMirror-gutters { + background: #3D3D3D; + border-right: 1px solid #4D4D4D; + box-shadow: 0 10px 20px black; +} + +.cm-s-ambiance .CodeMirror-linenumber { + text-shadow: 0px 1px 1px #4d4d4d; + color: #111; + padding: 0 5px; +} + +.cm-s-ambiance .CodeMirror-guttermarker { color: #aaa; } +.cm-s-ambiance .CodeMirror-guttermarker-subtle { color: #111; } + +.cm-s-ambiance .CodeMirror-cursor { border-left: 1px solid #7991E8; } + +.cm-s-ambiance .CodeMirror-activeline-background { + background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031); +} + +.cm-s-ambiance.CodeMirror, +.cm-s-ambiance .CodeMirror-gutters { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC"); +} diff --git a/backend/webif/static/codemirror/theme/base16-dark.css b/backend/webif/static/codemirror/theme/base16-dark.css new file mode 100755 index 000000000..026a81689 --- /dev/null +++ b/backend/webif/static/codemirror/theme/base16-dark.css @@ -0,0 +1,38 @@ +/* + + Name: Base16 Default Dark + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; } +.cm-s-base16-dark div.CodeMirror-selected { background: #303030; } +.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); } +.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); } +.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; } +.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; } +.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; } +.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; } +.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; } + +.cm-s-base16-dark span.cm-comment { color: #8f5536; } +.cm-s-base16-dark span.cm-atom { color: #aa759f; } +.cm-s-base16-dark span.cm-number { color: #aa759f; } + +.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; } +.cm-s-base16-dark span.cm-keyword { color: #ac4142; } +.cm-s-base16-dark span.cm-string { color: #f4bf75; } + +.cm-s-base16-dark span.cm-variable { color: #90a959; } +.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; } +.cm-s-base16-dark span.cm-def { color: #d28445; } +.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; } +.cm-s-base16-dark span.cm-tag { color: #ac4142; } +.cm-s-base16-dark span.cm-link { color: #aa759f; } +.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; } + +.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; } +.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/base16-light.css b/backend/webif/static/codemirror/theme/base16-light.css new file mode 100755 index 000000000..474e0ca9d --- /dev/null +++ b/backend/webif/static/codemirror/theme/base16-light.css @@ -0,0 +1,38 @@ +/* + + Name: Base16 Default Light + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; } +.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; } +.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; } +.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; } +.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; } +.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; } + +.cm-s-base16-light span.cm-comment { color: #8f5536; } +.cm-s-base16-light span.cm-atom { color: #aa759f; } +.cm-s-base16-light span.cm-number { color: #aa759f; } + +.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; } +.cm-s-base16-light span.cm-keyword { color: #ac4142; } +.cm-s-base16-light span.cm-string { color: #f4bf75; } + +.cm-s-base16-light span.cm-variable { color: #90a959; } +.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; } +.cm-s-base16-light span.cm-def { color: #d28445; } +.cm-s-base16-light span.cm-bracket { color: #202020; } +.cm-s-base16-light span.cm-tag { color: #ac4142; } +.cm-s-base16-light span.cm-link { color: #aa759f; } +.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; } + +.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; } +.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/bespin.css b/backend/webif/static/codemirror/theme/bespin.css new file mode 100755 index 000000000..60913ba93 --- /dev/null +++ b/backend/webif/static/codemirror/theme/bespin.css @@ -0,0 +1,34 @@ +/* + + Name: Bespin + Author: Mozilla / Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;} +.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;} +.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;} +.cm-s-bespin .CodeMirror-linenumber {color: #666666;} +.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;} + +.cm-s-bespin span.cm-comment {color: #937121;} +.cm-s-bespin span.cm-atom {color: #9b859d;} +.cm-s-bespin span.cm-number {color: #9b859d;} + +.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;} +.cm-s-bespin span.cm-keyword {color: #cf6a4c;} +.cm-s-bespin span.cm-string {color: #f9ee98;} + +.cm-s-bespin span.cm-variable {color: #54be0d;} +.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;} +.cm-s-bespin span.cm-def {color: #cf7d34;} +.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;} +.cm-s-bespin span.cm-bracket {color: #9d9b97;} +.cm-s-bespin span.cm-tag {color: #cf6a4c;} +.cm-s-bespin span.cm-link {color: #9b859d;} + +.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-bespin .CodeMirror-activeline-background { background: #404040; } diff --git a/backend/webif/static/codemirror/theme/blackboard.css b/backend/webif/static/codemirror/theme/blackboard.css new file mode 100755 index 000000000..b6eaedb18 --- /dev/null +++ b/backend/webif/static/codemirror/theme/blackboard.css @@ -0,0 +1,32 @@ +/* Port of TextMate's Blackboard theme */ + +.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; } +.cm-s-blackboard div.CodeMirror-selected { background: #253B76; } +.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); } +.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); } +.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; } +.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; } +.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; } +.cm-s-blackboard .CodeMirror-linenumber { color: #888; } +.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } + +.cm-s-blackboard .cm-keyword { color: #FBDE2D; } +.cm-s-blackboard .cm-atom { color: #D8FA3C; } +.cm-s-blackboard .cm-number { color: #D8FA3C; } +.cm-s-blackboard .cm-def { color: #8DA6CE; } +.cm-s-blackboard .cm-variable { color: #FF6400; } +.cm-s-blackboard .cm-operator { color: #FBDE2D; } +.cm-s-blackboard .cm-comment { color: #AEAEAE; } +.cm-s-blackboard .cm-string { color: #61CE3C; } +.cm-s-blackboard .cm-string-2 { color: #61CE3C; } +.cm-s-blackboard .cm-meta { color: #D8FA3C; } +.cm-s-blackboard .cm-builtin { color: #8DA6CE; } +.cm-s-blackboard .cm-tag { color: #8DA6CE; } +.cm-s-blackboard .cm-attribute { color: #8DA6CE; } +.cm-s-blackboard .cm-header { color: #FF6400; } +.cm-s-blackboard .cm-hr { color: #AEAEAE; } +.cm-s-blackboard .cm-link { color: #8DA6CE; } +.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; } + +.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; } +.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } diff --git a/backend/webif/static/codemirror/theme/cobalt.css b/backend/webif/static/codemirror/theme/cobalt.css new file mode 100755 index 000000000..bbbda3b54 --- /dev/null +++ b/backend/webif/static/codemirror/theme/cobalt.css @@ -0,0 +1,25 @@ +.cm-s-cobalt.CodeMirror { background: #002240; color: white; } +.cm-s-cobalt div.CodeMirror-selected { background: #b36539; } +.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } +.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } +.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; } +.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-cobalt span.cm-comment { color: #08f; } +.cm-s-cobalt span.cm-atom { color: #845dc4; } +.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; } +.cm-s-cobalt span.cm-keyword { color: #ffee80; } +.cm-s-cobalt span.cm-string { color: #3ad900; } +.cm-s-cobalt span.cm-meta { color: #ff9d00; } +.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; } +.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def, .cm-s-cobalt .cm-type { color: white; } +.cm-s-cobalt span.cm-bracket { color: #d8d8d8; } +.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; } +.cm-s-cobalt span.cm-link { color: #845dc4; } +.cm-s-cobalt span.cm-error { color: #9d1e15; } + +.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; } +.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } diff --git a/backend/webif/static/codemirror/theme/colorforth.css b/backend/webif/static/codemirror/theme/colorforth.css new file mode 100755 index 000000000..19095e41d --- /dev/null +++ b/backend/webif/static/codemirror/theme/colorforth.css @@ -0,0 +1,33 @@ +.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; } +.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; } +.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; } +.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; } +.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-colorforth span.cm-comment { color: #ededed; } +.cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; } +.cm-s-colorforth span.cm-keyword { color: #ffd900; } +.cm-s-colorforth span.cm-builtin { color: #00d95a; } +.cm-s-colorforth span.cm-variable { color: #73ff00; } +.cm-s-colorforth span.cm-string { color: #007bff; } +.cm-s-colorforth span.cm-number { color: #00c4ff; } +.cm-s-colorforth span.cm-atom { color: #606060; } + +.cm-s-colorforth span.cm-variable-2 { color: #EEE; } +.cm-s-colorforth span.cm-variable-3, .cm-s-colorforth span.cm-type { color: #DDD; } +.cm-s-colorforth span.cm-property {} +.cm-s-colorforth span.cm-operator {} + +.cm-s-colorforth span.cm-meta { color: yellow; } +.cm-s-colorforth span.cm-qualifier { color: #FFF700; } +.cm-s-colorforth span.cm-bracket { color: #cc7; } +.cm-s-colorforth span.cm-tag { color: #FFBD40; } +.cm-s-colorforth span.cm-attribute { color: #FFF700; } +.cm-s-colorforth span.cm-error { color: #f00; } + +.cm-s-colorforth div.CodeMirror-selected { background: #333d53; } + +.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); } + +.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; } diff --git a/backend/webif/static/codemirror/theme/dracula.css b/backend/webif/static/codemirror/theme/dracula.css new file mode 100755 index 000000000..253133efe --- /dev/null +++ b/backend/webif/static/codemirror/theme/dracula.css @@ -0,0 +1,40 @@ +/* + + Name: dracula + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme) + +*/ + + +.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters { + background-color: #282a36 !important; + color: #f8f8f2 !important; + border: none; +} +.cm-s-dracula .CodeMirror-gutters { color: #282a36; } +.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; } +.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; } +.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula span.cm-comment { color: #6272a4; } +.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; } +.cm-s-dracula span.cm-number { color: #bd93f9; } +.cm-s-dracula span.cm-variable { color: #50fa7b; } +.cm-s-dracula span.cm-variable-2 { color: white; } +.cm-s-dracula span.cm-def { color: #50fa7b; } +.cm-s-dracula span.cm-operator { color: #ff79c6; } +.cm-s-dracula span.cm-keyword { color: #ff79c6; } +.cm-s-dracula span.cm-atom { color: #bd93f9; } +.cm-s-dracula span.cm-meta { color: #f8f8f2; } +.cm-s-dracula span.cm-tag { color: #ff79c6; } +.cm-s-dracula span.cm-attribute { color: #50fa7b; } +.cm-s-dracula span.cm-qualifier { color: #50fa7b; } +.cm-s-dracula span.cm-property { color: #66d9ef; } +.cm-s-dracula span.cm-builtin { color: #50fa7b; } +.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; } + +.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); } +.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/duotone-dark.css b/backend/webif/static/codemirror/theme/duotone-dark.css new file mode 100755 index 000000000..88fdc76c8 --- /dev/null +++ b/backend/webif/static/codemirror/theme/duotone-dark.css @@ -0,0 +1,35 @@ +/* +Name: DuoTone-Dark +Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes) + +CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/) +*/ + +.cm-s-duotone-dark.CodeMirror { background: #2a2734; color: #6c6783; } +.cm-s-duotone-dark div.CodeMirror-selected { background: #545167!important; } +.cm-s-duotone-dark .CodeMirror-gutters { background: #2a2734; border-right: 0px; } +.cm-s-duotone-dark .CodeMirror-linenumber { color: #545167; } + +/* begin cursor */ +.cm-s-duotone-dark .CodeMirror-cursor { border-left: 1px solid #ffad5c; /* border-left: 1px solid #ffad5c80; */ border-right: .5em solid #ffad5c; /* border-right: .5em solid #ffad5c80; */ opacity: .5; } +.cm-s-duotone-dark .CodeMirror-activeline-background { background: #363342; /* background: #36334280; */ opacity: .5;} +.cm-s-duotone-dark .cm-fat-cursor .CodeMirror-cursor { background: #ffad5c; /* background: #ffad5c80; */ opacity: .5;} +/* end cursor */ + +.cm-s-duotone-dark span.cm-atom, .cm-s-duotone-dark span.cm-number, .cm-s-duotone-dark span.cm-keyword, .cm-s-duotone-dark span.cm-variable, .cm-s-duotone-dark span.cm-attribute, .cm-s-duotone-dark span.cm-quote, .cm-s-duotone-dark span.cm-hr, .cm-s-duotone-dark span.cm-link { color: #ffcc99; } + +.cm-s-duotone-dark span.cm-property { color: #9a86fd; } +.cm-s-duotone-dark span.cm-punctuation, .cm-s-duotone-dark span.cm-unit, .cm-s-duotone-dark span.cm-negative { color: #e09142; } +.cm-s-duotone-dark span.cm-string { color: #ffb870; } +.cm-s-duotone-dark span.cm-operator { color: #ffad5c; } +.cm-s-duotone-dark span.cm-positive { color: #6a51e6; } + +.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-type, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; } +.cm-s-duotone-dark span.cm-def, .cm-s-duotone-dark span.cm-tag, .cm-s-duotone-dark span.cm-builtin, .cm-s-duotone-dark span.cm-qualifier, .cm-s-duotone-dark span.cm-header, .cm-s-duotone-dark span.cm-em { color: #eeebff; } +.cm-s-duotone-dark span.cm-bracket, .cm-s-duotone-dark span.cm-comment { color: #6c6783; } + +/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */ +.cm-s-duotone-dark span.cm-error, .cm-s-duotone-dark span.cm-invalidchar { color: #f00; } + +.cm-s-duotone-dark span.cm-header { font-weight: normal; } +.cm-s-duotone-dark .CodeMirror-matchingbracket { text-decoration: underline; color: #eeebff !important; } diff --git a/backend/webif/static/codemirror/theme/duotone-light.css b/backend/webif/static/codemirror/theme/duotone-light.css new file mode 100755 index 000000000..d99480f7c --- /dev/null +++ b/backend/webif/static/codemirror/theme/duotone-light.css @@ -0,0 +1,36 @@ +/* +Name: DuoTone-Light +Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes) + +CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/) +*/ + +.cm-s-duotone-light.CodeMirror { background: #faf8f5; color: #b29762; } +.cm-s-duotone-light div.CodeMirror-selected { background: #e3dcce !important; } +.cm-s-duotone-light .CodeMirror-gutters { background: #faf8f5; border-right: 0px; } +.cm-s-duotone-light .CodeMirror-linenumber { color: #cdc4b1; } + +/* begin cursor */ +.cm-s-duotone-light .CodeMirror-cursor { border-left: 1px solid #93abdc; /* border-left: 1px solid #93abdc80; */ border-right: .5em solid #93abdc; /* border-right: .5em solid #93abdc80; */ opacity: .5; } +.cm-s-duotone-light .CodeMirror-activeline-background { background: #e3dcce; /* background: #e3dcce80; */ opacity: .5; } +.cm-s-duotone-light .cm-fat-cursor .CodeMirror-cursor { background: #93abdc; /* #93abdc80; */ opacity: .5; } +/* end cursor */ + +.cm-s-duotone-light span.cm-atom, .cm-s-duotone-light span.cm-number, .cm-s-duotone-light span.cm-keyword, .cm-s-duotone-light span.cm-variable, .cm-s-duotone-light span.cm-attribute, .cm-s-duotone-light span.cm-quote, .cm-s-duotone-light-light span.cm-hr, .cm-s-duotone-light-light span.cm-link { color: #063289; } + +.cm-s-duotone-light span.cm-property { color: #b29762; } +.cm-s-duotone-light span.cm-punctuation, .cm-s-duotone-light span.cm-unit, .cm-s-duotone-light span.cm-negative { color: #063289; } +.cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; } +.cm-s-duotone-light span.cm-positive { color: #896724; } + +.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-type, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; } +.cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; } +.cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; } + +/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */ +/* .cm-s-duotone-light span.cm-error { background: #896724; color: #728fcb; } */ +.cm-s-duotone-light span.cm-error, .cm-s-duotone-light span.cm-invalidchar { color: #f00; } + +.cm-s-duotone-light span.cm-header { font-weight: normal; } +.cm-s-duotone-light .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; } + diff --git a/backend/webif/static/codemirror/theme/eclipse.css b/backend/webif/static/codemirror/theme/eclipse.css new file mode 100755 index 000000000..800d603f6 --- /dev/null +++ b/backend/webif/static/codemirror/theme/eclipse.css @@ -0,0 +1,23 @@ +.cm-s-eclipse span.cm-meta { color: #FF1717; } +.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; } +.cm-s-eclipse span.cm-atom { color: #219; } +.cm-s-eclipse span.cm-number { color: #164; } +.cm-s-eclipse span.cm-def { color: #00f; } +.cm-s-eclipse span.cm-variable { color: black; } +.cm-s-eclipse span.cm-variable-2 { color: #0000C0; } +.cm-s-eclipse span.cm-variable-3, .cm-s-eclipse span.cm-type { color: #0000C0; } +.cm-s-eclipse span.cm-property { color: black; } +.cm-s-eclipse span.cm-operator { color: black; } +.cm-s-eclipse span.cm-comment { color: #3F7F5F; } +.cm-s-eclipse span.cm-string { color: #2A00FF; } +.cm-s-eclipse span.cm-string-2 { color: #f50; } +.cm-s-eclipse span.cm-qualifier { color: #555; } +.cm-s-eclipse span.cm-builtin { color: #30a; } +.cm-s-eclipse span.cm-bracket { color: #cc7; } +.cm-s-eclipse span.cm-tag { color: #170; } +.cm-s-eclipse span.cm-attribute { color: #00c; } +.cm-s-eclipse span.cm-link { color: #219; } +.cm-s-eclipse span.cm-error { color: #f00; } + +.cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/backend/webif/static/codemirror/theme/elegant.css b/backend/webif/static/codemirror/theme/elegant.css new file mode 100755 index 000000000..45b3ea655 --- /dev/null +++ b/backend/webif/static/codemirror/theme/elegant.css @@ -0,0 +1,13 @@ +.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom { color: #762; } +.cm-s-elegant span.cm-comment { color: #262; font-style: italic; line-height: 1em; } +.cm-s-elegant span.cm-meta { color: #555; font-style: italic; line-height: 1em; } +.cm-s-elegant span.cm-variable { color: black; } +.cm-s-elegant span.cm-variable-2 { color: #b11; } +.cm-s-elegant span.cm-qualifier { color: #555; } +.cm-s-elegant span.cm-keyword { color: #730; } +.cm-s-elegant span.cm-builtin { color: #30a; } +.cm-s-elegant span.cm-link { color: #762; } +.cm-s-elegant span.cm-error { background-color: #fdd; } + +.cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/backend/webif/static/codemirror/theme/erlang-dark.css b/backend/webif/static/codemirror/theme/erlang-dark.css new file mode 100755 index 000000000..8c8a4171a --- /dev/null +++ b/backend/webif/static/codemirror/theme/erlang-dark.css @@ -0,0 +1,34 @@ +.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; } +.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539; } +.cm-s-erlang-dark .CodeMirror-line::selection, .cm-s-erlang-dark .CodeMirror-line > span::selection, .cm-s-erlang-dark .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } +.cm-s-erlang-dark .CodeMirror-line::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } +.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-erlang-dark .CodeMirror-guttermarker { color: white; } +.cm-s-erlang-dark .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-erlang-dark span.cm-quote { color: #ccc; } +.cm-s-erlang-dark span.cm-atom { color: #f133f1; } +.cm-s-erlang-dark span.cm-attribute { color: #ff80e1; } +.cm-s-erlang-dark span.cm-bracket { color: #ff9d00; } +.cm-s-erlang-dark span.cm-builtin { color: #eaa; } +.cm-s-erlang-dark span.cm-comment { color: #77f; } +.cm-s-erlang-dark span.cm-def { color: #e7a; } +.cm-s-erlang-dark span.cm-keyword { color: #ffee80; } +.cm-s-erlang-dark span.cm-meta { color: #50fefe; } +.cm-s-erlang-dark span.cm-number { color: #ffd0d0; } +.cm-s-erlang-dark span.cm-operator { color: #d55; } +.cm-s-erlang-dark span.cm-property { color: #ccc; } +.cm-s-erlang-dark span.cm-qualifier { color: #ccc; } +.cm-s-erlang-dark span.cm-special { color: #ffbbbb; } +.cm-s-erlang-dark span.cm-string { color: #3ad900; } +.cm-s-erlang-dark span.cm-string-2 { color: #ccc; } +.cm-s-erlang-dark span.cm-tag { color: #9effff; } +.cm-s-erlang-dark span.cm-variable { color: #50fe50; } +.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; } +.cm-s-erlang-dark span.cm-variable-3, .cm-s-erlang-dark span.cm-type { color: #ccc; } +.cm-s-erlang-dark span.cm-error { color: #9d1e15; } + +.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; } +.cm-s-erlang-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/hopscotch.css b/backend/webif/static/codemirror/theme/hopscotch.css new file mode 100755 index 000000000..7d05431bd --- /dev/null +++ b/backend/webif/static/codemirror/theme/hopscotch.css @@ -0,0 +1,34 @@ +/* + + Name: Hopscotch + Author: Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;} +.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;} +.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;} +.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;} +.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;} + +.cm-s-hopscotch span.cm-comment {color: #b33508;} +.cm-s-hopscotch span.cm-atom {color: #c85e7c;} +.cm-s-hopscotch span.cm-number {color: #c85e7c;} + +.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;} +.cm-s-hopscotch span.cm-keyword {color: #dd464c;} +.cm-s-hopscotch span.cm-string {color: #fdcc59;} + +.cm-s-hopscotch span.cm-variable {color: #8fc13e;} +.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;} +.cm-s-hopscotch span.cm-def {color: #fd8b19;} +.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;} +.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;} +.cm-s-hopscotch span.cm-tag {color: #dd464c;} +.cm-s-hopscotch span.cm-link {color: #c85e7c;} + +.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; } diff --git a/backend/webif/static/codemirror/theme/icecoder.css b/backend/webif/static/codemirror/theme/icecoder.css new file mode 100755 index 000000000..5440fbe27 --- /dev/null +++ b/backend/webif/static/codemirror/theme/icecoder.css @@ -0,0 +1,43 @@ +/* +ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net +*/ + +.cm-s-icecoder { color: #666; background: #1d1d1b; } + +.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; } /* off-white 1 */ +.cm-s-icecoder span.cm-atom { color: #e1c76e; } /* yellow */ +.cm-s-icecoder span.cm-number { color: #6cb5d9; } /* blue */ +.cm-s-icecoder span.cm-def { color: #b9ca4a; } /* green */ + +.cm-s-icecoder span.cm-variable { color: #6cb5d9; } /* blue */ +.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; } /* pink */ +.cm-s-icecoder span.cm-variable-3, .cm-s-icecoder span.cm-type { color: #f9602c; } /* orange */ + +.cm-s-icecoder span.cm-property { color: #eee; } /* off-white 1 */ +.cm-s-icecoder span.cm-operator { color: #9179bb; } /* purple */ +.cm-s-icecoder span.cm-comment { color: #97a3aa; } /* grey-blue */ + +.cm-s-icecoder span.cm-string { color: #b9ca4a; } /* green */ +.cm-s-icecoder span.cm-string-2 { color: #6cb5d9; } /* blue */ + +.cm-s-icecoder span.cm-meta { color: #555; } /* grey */ + +.cm-s-icecoder span.cm-qualifier { color: #555; } /* grey */ +.cm-s-icecoder span.cm-builtin { color: #214e7b; } /* bright blue */ +.cm-s-icecoder span.cm-bracket { color: #cc7; } /* grey-yellow */ + +.cm-s-icecoder span.cm-tag { color: #e8e8e8; } /* off-white 2 */ +.cm-s-icecoder span.cm-attribute { color: #099; } /* teal */ + +.cm-s-icecoder span.cm-header { color: #6a0d6a; } /* purple-pink */ +.cm-s-icecoder span.cm-quote { color: #186718; } /* dark green */ +.cm-s-icecoder span.cm-hr { color: #888; } /* mid-grey */ +.cm-s-icecoder span.cm-link { color: #e1c76e; } /* yellow */ +.cm-s-icecoder span.cm-error { color: #d00; } /* red */ + +.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; } +.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; } +.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; } +.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; } +.cm-s-icecoder .CodeMirror-activeline-background { background: #000; } diff --git a/backend/webif/static/codemirror/theme/isotope.css b/backend/webif/static/codemirror/theme/isotope.css new file mode 100755 index 000000000..d0d6263cf --- /dev/null +++ b/backend/webif/static/codemirror/theme/isotope.css @@ -0,0 +1,34 @@ +/* + + Name: Isotope + Author: David Desandro / Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;} +.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;} +.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;} +.cm-s-isotope .CodeMirror-linenumber {color: #808080;} +.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;} + +.cm-s-isotope span.cm-comment {color: #3300ff;} +.cm-s-isotope span.cm-atom {color: #cc00ff;} +.cm-s-isotope span.cm-number {color: #cc00ff;} + +.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;} +.cm-s-isotope span.cm-keyword {color: #ff0000;} +.cm-s-isotope span.cm-string {color: #ff0099;} + +.cm-s-isotope span.cm-variable {color: #33ff00;} +.cm-s-isotope span.cm-variable-2 {color: #0066ff;} +.cm-s-isotope span.cm-def {color: #ff9900;} +.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;} +.cm-s-isotope span.cm-bracket {color: #e0e0e0;} +.cm-s-isotope span.cm-tag {color: #ff0000;} +.cm-s-isotope span.cm-link {color: #cc00ff;} + +.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-isotope .CodeMirror-activeline-background { background: #202020; } diff --git a/backend/webif/static/codemirror/theme/lesser-dark.css b/backend/webif/static/codemirror/theme/lesser-dark.css new file mode 100755 index 000000000..b2ec418fd --- /dev/null +++ b/backend/webif/static/codemirror/theme/lesser-dark.css @@ -0,0 +1,47 @@ +/* +http://lesscss.org/ dark theme +Ported to CodeMirror by Peter Kroon +*/ +.cm-s-lesser-dark { + line-height: 1.3em; +} +.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; } +.cm-s-lesser-dark div.CodeMirror-selected { background: #45443B; } /* 33322B*/ +.cm-s-lesser-dark .CodeMirror-line::selection, .cm-s-lesser-dark .CodeMirror-line > span::selection, .cm-s-lesser-dark .CodeMirror-line > span > span::selection { background: rgba(69, 68, 59, .99); } +.cm-s-lesser-dark .CodeMirror-line::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(69, 68, 59, .99); } +.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/ + +.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/ + +.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; } +.cm-s-lesser-dark .CodeMirror-guttermarker { color: #599eff; } +.cm-s-lesser-dark .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; } + +.cm-s-lesser-dark span.cm-header { color: #a0a; } +.cm-s-lesser-dark span.cm-quote { color: #090; } +.cm-s-lesser-dark span.cm-keyword { color: #599eff; } +.cm-s-lesser-dark span.cm-atom { color: #C2B470; } +.cm-s-lesser-dark span.cm-number { color: #B35E4D; } +.cm-s-lesser-dark span.cm-def { color: white; } +.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; } +.cm-s-lesser-dark span.cm-variable-2 { color: #669199; } +.cm-s-lesser-dark span.cm-variable-3, .cm-s-lesser-dark span.cm-type { color: white; } +.cm-s-lesser-dark span.cm-property { color: #92A75C; } +.cm-s-lesser-dark span.cm-operator { color: #92A75C; } +.cm-s-lesser-dark span.cm-comment { color: #666; } +.cm-s-lesser-dark span.cm-string { color: #BCD279; } +.cm-s-lesser-dark span.cm-string-2 { color: #f50; } +.cm-s-lesser-dark span.cm-meta { color: #738C73; } +.cm-s-lesser-dark span.cm-qualifier { color: #555; } +.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; } +.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; } +.cm-s-lesser-dark span.cm-tag { color: #669199; } +.cm-s-lesser-dark span.cm-attribute { color: #00c; } +.cm-s-lesser-dark span.cm-hr { color: #999; } +.cm-s-lesser-dark span.cm-link { color: #00c; } +.cm-s-lesser-dark span.cm-error { color: #9d1e15; } + +.cm-s-lesser-dark .CodeMirror-activeline-background { background: #3C3A3A; } +.cm-s-lesser-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/liquibyte.css b/backend/webif/static/codemirror/theme/liquibyte.css new file mode 100755 index 000000000..393825e02 --- /dev/null +++ b/backend/webif/static/codemirror/theme/liquibyte.css @@ -0,0 +1,95 @@ +.cm-s-liquibyte.CodeMirror { + background-color: #000; + color: #fff; + line-height: 1.2em; + font-size: 1em; +} +.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight { + text-decoration: underline; + text-decoration-color: #0f0; + text-decoration-style: wavy; +} +.cm-s-liquibyte .cm-trailingspace { + text-decoration: line-through; + text-decoration-color: #f00; + text-decoration-style: dotted; +} +.cm-s-liquibyte .cm-tab { + text-decoration: line-through; + text-decoration-color: #404040; + text-decoration-style: dotted; +} +.cm-s-liquibyte .CodeMirror-gutters { background-color: #262626; border-right: 1px solid #505050; padding-right: 0.8em; } +.cm-s-liquibyte .CodeMirror-gutter-elt div { font-size: 1.2em; } +.cm-s-liquibyte .CodeMirror-guttermarker { } +.cm-s-liquibyte .CodeMirror-guttermarker-subtle { } +.cm-s-liquibyte .CodeMirror-linenumber { color: #606060; padding-left: 0; } +.cm-s-liquibyte .CodeMirror-cursor { border-left: 1px solid #eee; } + +.cm-s-liquibyte span.cm-comment { color: #008000; } +.cm-s-liquibyte span.cm-def { color: #ffaf40; font-weight: bold; } +.cm-s-liquibyte span.cm-keyword { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-builtin { color: #ffaf40; font-weight: bold; } +.cm-s-liquibyte span.cm-variable { color: #5967ff; font-weight: bold; } +.cm-s-liquibyte span.cm-string { color: #ff8000; } +.cm-s-liquibyte span.cm-number { color: #0f0; font-weight: bold; } +.cm-s-liquibyte span.cm-atom { color: #bf3030; font-weight: bold; } + +.cm-s-liquibyte span.cm-variable-2 { color: #007f7f; font-weight: bold; } +.cm-s-liquibyte span.cm-variable-3, .cm-s-liquibyte span.cm-type { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-property { color: #999; font-weight: bold; } +.cm-s-liquibyte span.cm-operator { color: #fff; } + +.cm-s-liquibyte span.cm-meta { color: #0f0; } +.cm-s-liquibyte span.cm-qualifier { color: #fff700; font-weight: bold; } +.cm-s-liquibyte span.cm-bracket { color: #cc7; } +.cm-s-liquibyte span.cm-tag { color: #ff0; font-weight: bold; } +.cm-s-liquibyte span.cm-attribute { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-error { color: #f00; } + +.cm-s-liquibyte div.CodeMirror-selected { background-color: rgba(255, 0, 0, 0.25); } + +.cm-s-liquibyte span.cm-compilation { background-color: rgba(255, 255, 255, 0.12); } + +.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); } + +/* Default styles for common addons */ +.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; } +.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; } +.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); } +/* Scrollbars */ +/* Simple */ +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div:hover { + background-color: rgba(80, 80, 80, .7); +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div { + background-color: rgba(80, 80, 80, .3); + border: 1px solid #404040; + border-radius: 5px; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div { + border-top: 1px solid #404040; + border-bottom: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div { + border-left: 1px solid #404040; + border-right: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-vertical { + background-color: #262626; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal { + background-color: #262626; + border-top: 1px solid #404040; +} +/* Overlay */ +.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div { + background-color: #404040; + border-radius: 5px; +} +.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div { + border: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div { + border: 1px solid #404040; +} diff --git a/backend/webif/static/codemirror/theme/material.css b/backend/webif/static/codemirror/theme/material.css new file mode 100755 index 000000000..84962a244 --- /dev/null +++ b/backend/webif/static/codemirror/theme/material.css @@ -0,0 +1,53 @@ +/* + + Name: material + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) + +*/ + +.cm-s-material.CodeMirror { + background-color: #263238; + color: rgba(233, 237, 237, 1); +} +.cm-s-material .CodeMirror-gutters { + background: #263238; + color: rgb(83,127,126); + border: none; +} +.cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } +.cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } +.cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } +.cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } + +.cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } +.cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } +.cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } +.cm-s-material .cm-variable-2 { color: #80CBC4; } +.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #82B1FF; } +.cm-s-material .cm-builtin { color: #DECB6B; } +.cm-s-material .cm-atom { color: #F77669; } +.cm-s-material .cm-number { color: #F77669; } +.cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } +.cm-s-material .cm-string { color: #C3E88D; } +.cm-s-material .cm-string-2 { color: #80CBC4; } +.cm-s-material .cm-comment { color: #546E7A; } +.cm-s-material .cm-variable { color: #82B1FF; } +.cm-s-material .cm-tag { color: #80CBC4; } +.cm-s-material .cm-meta { color: #80CBC4; } +.cm-s-material .cm-attribute { color: #FFCB6B; } +.cm-s-material .cm-property { color: #80CBAE; } +.cm-s-material .cm-qualifier { color: #DECB6B; } +.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #DECB6B; } +.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } +.cm-s-material .cm-error { + color: rgba(255, 255, 255, 1.0); + background-color: #EC5F67; +} +.cm-s-material .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/backend/webif/static/codemirror/theme/mbo.css b/backend/webif/static/codemirror/theme/mbo.css new file mode 100755 index 000000000..e164fcf42 --- /dev/null +++ b/backend/webif/static/codemirror/theme/mbo.css @@ -0,0 +1,37 @@ +/****************************************************************/ +/* Based on mbonaci's Brackets mbo theme */ +/* https://github.com/mbonaci/global/blob/master/Mbo.tmTheme */ +/* Create your own: http://tmtheme-editor.herokuapp.com */ +/****************************************************************/ + +.cm-s-mbo.CodeMirror { background: #2c2c2c; color: #ffffec; } +.cm-s-mbo div.CodeMirror-selected { background: #716C62; } +.cm-s-mbo .CodeMirror-line::selection, .cm-s-mbo .CodeMirror-line > span::selection, .cm-s-mbo .CodeMirror-line > span > span::selection { background: rgba(113, 108, 98, .99); } +.cm-s-mbo .CodeMirror-line::-moz-selection, .cm-s-mbo .CodeMirror-line > span::-moz-selection, .cm-s-mbo .CodeMirror-line > span > span::-moz-selection { background: rgba(113, 108, 98, .99); } +.cm-s-mbo .CodeMirror-gutters { background: #4e4e4e; border-right: 0px; } +.cm-s-mbo .CodeMirror-guttermarker { color: white; } +.cm-s-mbo .CodeMirror-guttermarker-subtle { color: grey; } +.cm-s-mbo .CodeMirror-linenumber { color: #dadada; } +.cm-s-mbo .CodeMirror-cursor { border-left: 1px solid #ffffec; } + +.cm-s-mbo span.cm-comment { color: #95958a; } +.cm-s-mbo span.cm-atom { color: #00a8c6; } +.cm-s-mbo span.cm-number { color: #00a8c6; } + +.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; } +.cm-s-mbo span.cm-keyword { color: #ffb928; } +.cm-s-mbo span.cm-string { color: #ffcf6c; } +.cm-s-mbo span.cm-string.cm-property { color: #ffffec; } + +.cm-s-mbo span.cm-variable { color: #ffffec; } +.cm-s-mbo span.cm-variable-2 { color: #00a8c6; } +.cm-s-mbo span.cm-def { color: #ffffec; } +.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; } +.cm-s-mbo span.cm-tag { color: #9ddfe9; } +.cm-s-mbo span.cm-link { color: #f54b07; } +.cm-s-mbo span.cm-error { border-bottom: #636363; color: #ffffec; } +.cm-s-mbo span.cm-qualifier { color: #ffffec; } + +.cm-s-mbo .CodeMirror-activeline-background { background: #494b41; } +.cm-s-mbo .CodeMirror-matchingbracket { color: #ffb928 !important; } +.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); } diff --git a/backend/webif/static/codemirror/theme/mdn-like.css b/backend/webif/static/codemirror/theme/mdn-like.css new file mode 100755 index 000000000..622ed3efb --- /dev/null +++ b/backend/webif/static/codemirror/theme/mdn-like.css @@ -0,0 +1,46 @@ +/* + MDN-LIKE Theme - Mozilla + Ported to CodeMirror by Peter Kroon + Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues + GitHub: @peterkroon + + The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation + +*/ +.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; } +.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; } +.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; } +.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; } + +.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } +.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; } +.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; } + +.cm-s-mdn-like .cm-keyword { color: #6262FF; } +.cm-s-mdn-like .cm-atom { color: #F90; } +.cm-s-mdn-like .cm-number { color: #ca7841; } +.cm-s-mdn-like .cm-def { color: #8DA6CE; } +.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } +.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def, .cm-s-mdn-like span.cm-type { color: #07a; } + +.cm-s-mdn-like .cm-variable { color: #07a; } +.cm-s-mdn-like .cm-property { color: #905; } +.cm-s-mdn-like .cm-qualifier { color: #690; } + +.cm-s-mdn-like .cm-operator { color: #cda869; } +.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } +.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } +.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/ +.cm-s-mdn-like .cm-meta { color: #000; } /*?*/ +.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/ +.cm-s-mdn-like .cm-tag { color: #997643; } +.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/ +.cm-s-mdn-like .cm-header { color: #FF6400; } +.cm-s-mdn-like .cm-hr { color: #AEAEAE; } +.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } +.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } + +div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; } +div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; } + +.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAyCAYAAAAp8UeFAAAHvklEQVR42s2b63bcNgyEQZCSHCdt2vd/0tWF7I+Q6XgMXiTtuvU5Pl57ZQKkKHzEAOtF5KeIJBGJ8uvL599FRFREZhFx8DeXv8trn68RuGaC8TRfo3SNp9dlDDHedyLyTUTeRWStXKPZrjtpZxaRw5hPqozRs1N8/enzIiQRWcCgy4MUA0f+XWliDhyL8Lfyvx7ei/Ae3iQFHyw7U/59pQVIMEEPEz0G7XiwdRjzSfC3UTtz9vchIntxvry5iMgfIhJoEflOz2CQr3F5h/HfeFe+GTdLaKcu9L8LTeQb/R/7GgbsfKedyNdoHsN31uRPWrfZ5wsj/NzzRQHuToIdU3ahwnsKPxXCjJITuOsi7XLc7SG/v5GdALs7wf8JjTFiB5+QvTEfRyGOfX3Lrx8wxyQi3sNq46O7QahQiCsRFgqddjBouVEHOKDgXAQHD9gJCr5sMKkEdjwsarG/ww3BMHBU7OBjXnzdyY7SfCxf5/z6ATccrwlKuwC/jhznnPF4CgVzhhVf4xp2EixcBActO75iZ8/fM9zAs2OMzKdslgXWJ9XG8PQoOAMA5fGcsvORgv0doBXyHrCwfLJAOwo71QLNkb8n2Pl6EWiR7OCibtkPaz4Kc/0NNAze2gju3zOwekALDaCFPI5vjPFmgGY5AZqyGEvH1x7QfIb8YtxMnA/b+QQ0aQDAwc6JMFg8CbQZ4qoYEEHbRwNojuK3EHwd7VALSgq+MNDKzfT58T8qdpADrgW0GmgcAS1lhzztJmkAzcPNOQbsWEALBDSlMKUG0Eq4CLAQWvEVQ9WU57gZJwZtgPO3r9oBTQ9WO8TjqXINx8R0EYpiZEUWOF3FxkbJkgU9B2f41YBrIj5ZfsQa0M5kTgiAAqM3ShXLgu8XMqcrQBvJ0CL5pnTsfMB13oB8athpAq2XOQmcGmoACCLydx7nToa23ATaSIY2ichfOdPTGxlasXMLaL0MLZAOwAKIM+y8CmicobGdCcbbK9DzN+yYGVoNNI5iUKTMyYOjPse4A8SM1MmcXgU0toOq1yO/v8FOxlASyc7TgeYaAMBJHcY1CcCwGI/TK4AmDbDyKYBBtFUkRwto8gygiQEaByFgJ00BH2M8JWwQS1nafDXQCidWyOI8AcjDCSjCLk8ngObuAm3JAHAdubAmOaK06V8MNEsKPJOhobSprwQa6gD7DclRQdqcwL4zxqgBrQcabUiBLclRDKAlWp+etPkBaNMA0AKlrHwTdEByZAA4GM+SNluSY6wAzcMNewxmgig5Ks0nkrSpBvSaQHMdKTBAnLojOdYyGpQ254602ZILPdTD1hdlggdIm74jbTp8vDwF5ZYUeLWGJpWsh6XNyXgcYwVoJQTEhhTYkxzZjiU5npU2TaB979TQehlaAVq4kaGpiPwwwLkYUuBbQwocyQTv1tA0+1UFWoJF3iv1oq+qoSk8EQdJmwHkziIF7oOZk14EGitibAdjLYYK78H5vZOhtWpoI0ATGHs0Q8OMb4Ey+2bU2UYztCtA0wFAs7TplGLRVQCcqaFdGSPCeTI1QNIC52iWNzof6Uib7xjEp07mNNoUYmVosVItHrHzRlLgBn9LFyRHaQCtVUMbtTNhoXWiTOO9k/V8BdAc1Oq0ArSQs6/5SU0hckNy9NnXqQY0PGYo5dWJ7nINaN6o958FWin27aBaWRka1r5myvLOAm0j30eBJqCxHLReVclxhxOEN2JfDWjxBtAC7MIH1fVaGdoOp4qJYDgKtKPSFNID2gSnGldrCqkFZ+5UeQXQBIRrSwocbdZYQT/2LwRahBPBXoHrB8nxaGROST62DKUbQOMMzZIC9abkuELfQzQALWTnDNAm8KHWFOJgJ5+SHIvTPcmx1xQyZRhNL5Qci689aXMEaN/uNIWkEwDAvFpOZmgsBaaGnbs1NPa1Jm32gBZAIh1pCtG7TSH4aE0y1uVY4uqoFPisGlpP2rSA5qTecWn5agK6BzSpgAyD+wFaqhnYoSZ1Vwr8CmlTQbrcO3ZaX0NAEyMbYaAlyquFoLKK3SPby9CeVUPThrSJmkCAE0CrKUQadi4DrdSlWhmah0YL9z9vClH59YGbHx1J8VZTyAjQepJjmXwAKTDQI3omc3p1U4gDUf6RfcdYfrUp5ClAi2J3Ba6UOXGo+K+bQrjjssitG2SJzshaLwMtXgRagUNpYYoVkMSBLM+9GGiJZMvduG6DRZ4qc04DMPtQQxOjEtACmhO7K1AbNbQDEggZyJwscFpAGwENhoBeUwh3bWolhe8BTYVKxQEWrSUn/uhcM5KhvUu/+eQu0Lzhi+VrK0PrZZNDQKs9cpYUuFYgMVpD4/NxenJTiMCNqdUEUf1qZWjppLT5qSkkUZbCwkbZMSuVnu80hfSkzRbQeqCZSAh6huR4VtoM2gHAlLf72smuWgE+VV7XpE25Ab2WFDgyhnSuKbs4GuGzCjR+tIoUuMFg3kgcWKLTwRqanJQ2W00hAsenfaApRC42hbCvK1SlE0HtE9BGgneJO+ELamitD1YjjOYnNYVcraGhtKkW0EqVVeDx733I2NH581k1NNxNLG0i0IJ8/NjVaOZ0tYZ2Vtr0Xv7tPV3hkWp9EFkgS/J0vosngTaSoaG06WHi+xObQkaAdlbanP8B2+2l0f90LmUAAAAASUVORK5CYII=); } diff --git a/backend/webif/static/codemirror/theme/midnight.css b/backend/webif/static/codemirror/theme/midnight.css new file mode 100755 index 000000000..17ed39c8b --- /dev/null +++ b/backend/webif/static/codemirror/theme/midnight.css @@ -0,0 +1,43 @@ +/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */ + +/**/ +.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949; } +.cm-s-midnight.CodeMirror-focused span.CodeMirror-matchhighlight { background: #314D67 !important; } + +/**/ +.cm-s-midnight .CodeMirror-activeline-background { background: #253540; } + +.cm-s-midnight.CodeMirror { + background: #0F192A; + color: #D1EDFF; +} + +.cm-s-midnight div.CodeMirror-selected { background: #314D67; } +.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); } +.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); } +.cm-s-midnight .CodeMirror-gutters { background: #0F192A; border-right: 1px solid; } +.cm-s-midnight .CodeMirror-guttermarker { color: white; } +.cm-s-midnight .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-midnight .CodeMirror-linenumber { color: #D0D0D0; } +.cm-s-midnight .CodeMirror-cursor { border-left: 1px solid #F8F8F0; } + +.cm-s-midnight span.cm-comment { color: #428BDD; } +.cm-s-midnight span.cm-atom { color: #AE81FF; } +.cm-s-midnight span.cm-number { color: #D1EDFF; } + +.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute { color: #A6E22E; } +.cm-s-midnight span.cm-keyword { color: #E83737; } +.cm-s-midnight span.cm-string { color: #1DC116; } + +.cm-s-midnight span.cm-variable { color: #FFAA3E; } +.cm-s-midnight span.cm-variable-2 { color: #FFAA3E; } +.cm-s-midnight span.cm-def { color: #4DD; } +.cm-s-midnight span.cm-bracket { color: #D1EDFF; } +.cm-s-midnight span.cm-tag { color: #449; } +.cm-s-midnight span.cm-link { color: #AE81FF; } +.cm-s-midnight span.cm-error { background: #F92672; color: #F8F8F0; } + +.cm-s-midnight .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/backend/webif/static/codemirror/theme/monokai.css b/backend/webif/static/codemirror/theme/monokai.css new file mode 100755 index 000000000..b5edd13fe --- /dev/null +++ b/backend/webif/static/codemirror/theme/monokai.css @@ -0,0 +1,36 @@ +/* Based on Sublime Text's Monokai theme */ + +.cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } +.cm-s-monokai div.CodeMirror-selected { background: #49483E; } +.cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } +.cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } +.cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } +.cm-s-monokai .CodeMirror-guttermarker { color: white; } +.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } + +.cm-s-monokai span.cm-comment { color: #75715e; } +.cm-s-monokai span.cm-atom { color: #ae81ff; } +.cm-s-monokai span.cm-number { color: #ae81ff; } + +.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; } +.cm-s-monokai span.cm-keyword { color: #f92672; } +.cm-s-monokai span.cm-builtin { color: #66d9ef; } +.cm-s-monokai span.cm-string { color: #e6db74; } + +.cm-s-monokai span.cm-variable { color: #f8f8f2; } +.cm-s-monokai span.cm-variable-2 { color: #9effff; } +.cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; } +.cm-s-monokai span.cm-def { color: #fd971f; } +.cm-s-monokai span.cm-bracket { color: #f8f8f2; } +.cm-s-monokai span.cm-tag { color: #f92672; } +.cm-s-monokai span.cm-header { color: #ae81ff; } +.cm-s-monokai span.cm-link { color: #ae81ff; } +.cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } + +.cm-s-monokai .CodeMirror-activeline-background { background: #373831; } +.cm-s-monokai .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/backend/webif/static/codemirror/theme/neat.css b/backend/webif/static/codemirror/theme/neat.css new file mode 100755 index 000000000..4267b1a37 --- /dev/null +++ b/backend/webif/static/codemirror/theme/neat.css @@ -0,0 +1,12 @@ +.cm-s-neat span.cm-comment { color: #a86; } +.cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; } +.cm-s-neat span.cm-string { color: #a22; } +.cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; } +.cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; } +.cm-s-neat span.cm-variable { color: black; } +.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; } +.cm-s-neat span.cm-meta { color: #555; } +.cm-s-neat span.cm-link { color: #3a3; } + +.cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/backend/webif/static/codemirror/theme/neo.css b/backend/webif/static/codemirror/theme/neo.css new file mode 100755 index 000000000..b28d5c65f --- /dev/null +++ b/backend/webif/static/codemirror/theme/neo.css @@ -0,0 +1,43 @@ +/* neo theme for codemirror */ + +/* Color scheme */ + +.cm-s-neo.CodeMirror { + background-color:#ffffff; + color:#2e383c; + line-height:1.4375; +} +.cm-s-neo .cm-comment { color:#75787b; } +.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; } +.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; } +.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; } +.cm-s-neo .cm-string { color:#b35e14; } +.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; } + + +/* Editor styling */ + +.cm-s-neo pre { + padding:0; +} + +.cm-s-neo .CodeMirror-gutters { + border:none; + border-right:10px solid transparent; + background-color:transparent; +} + +.cm-s-neo .CodeMirror-linenumber { + padding:0; + color:#e0e2e5; +} + +.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; } +.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; } + +.cm-s-neo .CodeMirror-cursor { + width: auto; + border: 0; + background: rgba(155,157,162,0.37); + z-index: 1; +} diff --git a/backend/webif/static/codemirror/theme/night.css b/backend/webif/static/codemirror/theme/night.css new file mode 100755 index 000000000..f631bf42c --- /dev/null +++ b/backend/webif/static/codemirror/theme/night.css @@ -0,0 +1,27 @@ +/* Loosely based on the Midnight Textmate theme */ + +.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; } +.cm-s-night div.CodeMirror-selected { background: #447; } +.cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); } +.cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); } +.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-night .CodeMirror-guttermarker { color: white; } +.cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; } +.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; } +.cm-s-night .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-night span.cm-comment { color: #8900d1; } +.cm-s-night span.cm-atom { color: #845dc4; } +.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; } +.cm-s-night span.cm-keyword { color: #599eff; } +.cm-s-night span.cm-string { color: #37f14a; } +.cm-s-night span.cm-meta { color: #7678e2; } +.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; } +.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def, .cm-s-night span.cm-type { color: white; } +.cm-s-night span.cm-bracket { color: #8da6ce; } +.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; } +.cm-s-night span.cm-link { color: #845dc4; } +.cm-s-night span.cm-error { color: #9d1e15; } + +.cm-s-night .CodeMirror-activeline-background { background: #1C005A; } +.cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/panda-syntax.css b/backend/webif/static/codemirror/theme/panda-syntax.css new file mode 100755 index 000000000..6de58b56f --- /dev/null +++ b/backend/webif/static/codemirror/theme/panda-syntax.css @@ -0,0 +1,85 @@ +/* + Name: Panda Syntax + Author: Siamak Mokhtari (http://github.com/siamak/) + CodeMirror template by Siamak Mokhtari (https://github.com/siamak/atom-panda-syntax) +*/ +.cm-s-panda-syntax { + background: #292A2B; + color: #E6E6E6; + line-height: 1.5; + font-family: 'Operator Mono', 'Source Sans Pro', Menlo, Monaco, Consolas, Courier New, monospace; +} +.cm-s-panda-syntax .CodeMirror-cursor { border-color: #ff2c6d; } +.cm-s-panda-syntax .CodeMirror-activeline-background { + background: rgba(99, 123, 156, 0.1); +} +.cm-s-panda-syntax .CodeMirror-selected { + background: #FFF; +} +.cm-s-panda-syntax .cm-comment { + font-style: italic; + color: #676B79; +} +.cm-s-panda-syntax .cm-operator { + color: #f3f3f3; +} +.cm-s-panda-syntax .cm-string { + color: #19F9D8; +} +.cm-s-panda-syntax .cm-string-2 { + color: #FFB86C; +} + +.cm-s-panda-syntax .cm-tag { + color: #ff2c6d; +} +.cm-s-panda-syntax .cm-meta { + color: #b084eb; +} + +.cm-s-panda-syntax .cm-number { + color: #FFB86C; +} +.cm-s-panda-syntax .cm-atom { + color: #ff2c6d; +} +.cm-s-panda-syntax .cm-keyword { + color: #FF75B5; +} +.cm-s-panda-syntax .cm-variable { + color: #ffb86c; +} +.cm-s-panda-syntax .cm-variable-2 { + color: #ff9ac1; +} +.cm-s-panda-syntax .cm-variable-3, .cm-s-panda-syntax .cm-type { + color: #ff9ac1; +} + +.cm-s-panda-syntax .cm-def { + color: #e6e6e6; +} +.cm-s-panda-syntax .cm-property { + color: #f3f3f3; +} +.cm-s-panda-syntax .cm-unit { + color: #ffb86c; +} + +.cm-s-panda-syntax .cm-attribute { + color: #ffb86c; +} + +.cm-s-panda-syntax .CodeMirror-matchingbracket { + border-bottom: 1px dotted #19F9D8; + padding-bottom: 2px; + color: #e6e6e6; +} +.cm-s-panda-syntax .CodeMirror-gutters { + background: #292a2b; + border-right-color: rgba(255, 255, 255, 0.1); +} +.cm-s-panda-syntax .CodeMirror-linenumber { + color: #e6e6e6; + opacity: 0.6; +} diff --git a/backend/webif/static/codemirror/theme/paraiso-dark.css b/backend/webif/static/codemirror/theme/paraiso-dark.css new file mode 100755 index 000000000..aa9d207e6 --- /dev/null +++ b/backend/webif/static/codemirror/theme/paraiso-dark.css @@ -0,0 +1,38 @@ +/* + + Name: Paraíso (Dark) + Author: Jan T. Sott + + Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) + +*/ + +.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; } +.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; } +.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); } +.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); } +.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; } +.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; } +.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; } +.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; } +.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; } + +.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; } +.cm-s-paraiso-dark span.cm-atom { color: #815ba4; } +.cm-s-paraiso-dark span.cm-number { color: #815ba4; } + +.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; } +.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; } +.cm-s-paraiso-dark span.cm-string { color: #fec418; } + +.cm-s-paraiso-dark span.cm-variable { color: #48b685; } +.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; } +.cm-s-paraiso-dark span.cm-def { color: #f99b15; } +.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; } +.cm-s-paraiso-dark span.cm-tag { color: #ef6155; } +.cm-s-paraiso-dark span.cm-link { color: #815ba4; } +.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; } + +.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; } +.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/paraiso-light.css b/backend/webif/static/codemirror/theme/paraiso-light.css new file mode 100755 index 000000000..ae0c755f8 --- /dev/null +++ b/backend/webif/static/codemirror/theme/paraiso-light.css @@ -0,0 +1,38 @@ +/* + + Name: Paraíso (Light) + Author: Jan T. Sott + + Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) + +*/ + +.cm-s-paraiso-light.CodeMirror { background: #e7e9db; color: #41323f; } +.cm-s-paraiso-light div.CodeMirror-selected { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-line::selection, .cm-s-paraiso-light .CodeMirror-line > span::selection, .cm-s-paraiso-light .CodeMirror-line > span > span::selection { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-line::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span > span::-moz-selection { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-gutters { background: #e7e9db; border-right: 0px; } +.cm-s-paraiso-light .CodeMirror-guttermarker { color: black; } +.cm-s-paraiso-light .CodeMirror-guttermarker-subtle { color: #8d8687; } +.cm-s-paraiso-light .CodeMirror-linenumber { color: #8d8687; } +.cm-s-paraiso-light .CodeMirror-cursor { border-left: 1px solid #776e71; } + +.cm-s-paraiso-light span.cm-comment { color: #e96ba8; } +.cm-s-paraiso-light span.cm-atom { color: #815ba4; } +.cm-s-paraiso-light span.cm-number { color: #815ba4; } + +.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute { color: #48b685; } +.cm-s-paraiso-light span.cm-keyword { color: #ef6155; } +.cm-s-paraiso-light span.cm-string { color: #fec418; } + +.cm-s-paraiso-light span.cm-variable { color: #48b685; } +.cm-s-paraiso-light span.cm-variable-2 { color: #06b6ef; } +.cm-s-paraiso-light span.cm-def { color: #f99b15; } +.cm-s-paraiso-light span.cm-bracket { color: #41323f; } +.cm-s-paraiso-light span.cm-tag { color: #ef6155; } +.cm-s-paraiso-light span.cm-link { color: #815ba4; } +.cm-s-paraiso-light span.cm-error { background: #ef6155; color: #776e71; } + +.cm-s-paraiso-light .CodeMirror-activeline-background { background: #CFD1C4; } +.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/pastel-on-dark.css b/backend/webif/static/codemirror/theme/pastel-on-dark.css new file mode 100755 index 000000000..60435dd15 --- /dev/null +++ b/backend/webif/static/codemirror/theme/pastel-on-dark.css @@ -0,0 +1,52 @@ +/** + * Pastel On Dark theme ported from ACE editor + * @license MIT + * @copyright AtomicPages LLC 2014 + * @author Dennis Thompson, AtomicPages LLC + * @version 1.1 + * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme + */ + +.cm-s-pastel-on-dark.CodeMirror { + background: #2c2827; + color: #8F938F; + line-height: 1.5; +} +.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); } +.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); } +.cm-s-pastel-on-dark .CodeMirror-line::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(221,240,255,0.2); } + +.cm-s-pastel-on-dark .CodeMirror-gutters { + background: #34302f; + border-right: 0px; + padding: 0 3px; +} +.cm-s-pastel-on-dark .CodeMirror-guttermarker { color: white; } +.cm-s-pastel-on-dark .CodeMirror-guttermarker-subtle { color: #8F938F; } +.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; } +.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } +.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; } +.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; } +.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; } +.cm-s-pastel-on-dark span.cm-property { color: #8F938F; } +.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; } +.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; } +.cm-s-pastel-on-dark span.cm-string { color: #66A968; } +.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; } +.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; } +.cm-s-pastel-on-dark span.cm-variable-3, .cm-s-pastel-on-dark span.cm-type { color: #DE8E30; } +.cm-s-pastel-on-dark span.cm-def { color: #757aD8; } +.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; } +.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; } +.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; } +.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; } +.cm-s-pastel-on-dark span.cm-error { + background: #757aD8; + color: #f8f8f0; +} +.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031); } +.cm-s-pastel-on-dark .CodeMirror-matchingbracket { + border: 1px solid rgba(255,255,255,0.25); + color: #8F938F !important; + margin: -1px -1px 0 -1px; +} diff --git a/backend/webif/static/codemirror/theme/railscasts.css b/backend/webif/static/codemirror/theme/railscasts.css new file mode 100755 index 000000000..aeff0449d --- /dev/null +++ b/backend/webif/static/codemirror/theme/railscasts.css @@ -0,0 +1,34 @@ +/* + + Name: Railscasts + Author: Ryan Bates (http://railscasts.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;} +.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;} +.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;} +.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;} +.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;} + +.cm-s-railscasts span.cm-comment {color: #bc9458;} +.cm-s-railscasts span.cm-atom {color: #b6b3eb;} +.cm-s-railscasts span.cm-number {color: #b6b3eb;} + +.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;} +.cm-s-railscasts span.cm-keyword {color: #da4939;} +.cm-s-railscasts span.cm-string {color: #ffc66d;} + +.cm-s-railscasts span.cm-variable {color: #a5c261;} +.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;} +.cm-s-railscasts span.cm-def {color: #cc7833;} +.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;} +.cm-s-railscasts span.cm-bracket {color: #f4f1ed;} +.cm-s-railscasts span.cm-tag {color: #da4939;} +.cm-s-railscasts span.cm-link {color: #b6b3eb;} + +.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; } diff --git a/backend/webif/static/codemirror/theme/rubyblue.css b/backend/webif/static/codemirror/theme/rubyblue.css new file mode 100755 index 000000000..1f181b06e --- /dev/null +++ b/backend/webif/static/codemirror/theme/rubyblue.css @@ -0,0 +1,25 @@ +.cm-s-rubyblue.CodeMirror { background: #112435; color: white; } +.cm-s-rubyblue div.CodeMirror-selected { background: #38566F; } +.cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); } +.cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); } +.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; } +.cm-s-rubyblue .CodeMirror-guttermarker { color: white; } +.cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; } +.cm-s-rubyblue .CodeMirror-linenumber { color: white; } +.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; } +.cm-s-rubyblue span.cm-atom { color: #F4C20B; } +.cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; } +.cm-s-rubyblue span.cm-keyword { color: #F0F; } +.cm-s-rubyblue span.cm-string { color: #F08047; } +.cm-s-rubyblue span.cm-meta { color: #F0F; } +.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; } +.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def, .cm-s-rubyblue span.cm-type { color: white; } +.cm-s-rubyblue span.cm-bracket { color: #F0F; } +.cm-s-rubyblue span.cm-link { color: #F4C20B; } +.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; } +.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; } +.cm-s-rubyblue span.cm-error { color: #AF2018; } + +.cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; } diff --git a/backend/webif/static/codemirror/theme/seti.css b/backend/webif/static/codemirror/theme/seti.css new file mode 100755 index 000000000..814f76f7d --- /dev/null +++ b/backend/webif/static/codemirror/theme/seti.css @@ -0,0 +1,44 @@ +/* + + Name: seti + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original seti color scheme by Jesse Weed (https://github.com/jesseweed/seti-syntax) + +*/ + + +.cm-s-seti.CodeMirror { + background-color: #151718 !important; + color: #CFD2D1 !important; + border: none; +} +.cm-s-seti .CodeMirror-gutters { + color: #404b53; + background-color: #0E1112; + border: none; +} +.cm-s-seti .CodeMirror-cursor { border-left: solid thin #f8f8f0; } +.cm-s-seti .CodeMirror-linenumber { color: #6D8A88; } +.cm-s-seti.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti .CodeMirror-line::selection, .cm-s-seti .CodeMirror-line > span::selection, .cm-s-seti .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti .CodeMirror-line::-moz-selection, .cm-s-seti .CodeMirror-line > span::-moz-selection, .cm-s-seti .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti span.cm-comment { color: #41535b; } +.cm-s-seti span.cm-string, .cm-s-seti span.cm-string-2 { color: #55b5db; } +.cm-s-seti span.cm-number { color: #cd3f45; } +.cm-s-seti span.cm-variable { color: #55b5db; } +.cm-s-seti span.cm-variable-2 { color: #a074c4; } +.cm-s-seti span.cm-def { color: #55b5db; } +.cm-s-seti span.cm-keyword { color: #ff79c6; } +.cm-s-seti span.cm-operator { color: #9fca56; } +.cm-s-seti span.cm-keyword { color: #e6cd69; } +.cm-s-seti span.cm-atom { color: #cd3f45; } +.cm-s-seti span.cm-meta { color: #55b5db; } +.cm-s-seti span.cm-tag { color: #55b5db; } +.cm-s-seti span.cm-attribute { color: #9fca56; } +.cm-s-seti span.cm-qualifier { color: #9fca56; } +.cm-s-seti span.cm-property { color: #a074c4; } +.cm-s-seti span.cm-variable-3, .cm-s-seti span.cm-type { color: #9fca56; } +.cm-s-seti span.cm-builtin { color: #9fca56; } +.cm-s-seti .CodeMirror-activeline-background { background: #101213; } +.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/solarized.css b/backend/webif/static/codemirror/theme/solarized.css new file mode 100755 index 000000000..fcd1d70de --- /dev/null +++ b/backend/webif/static/codemirror/theme/solarized.css @@ -0,0 +1,168 @@ +/* +Solarized theme for code-mirror +http://ethanschoonover.com/solarized +*/ + +/* +Solarized color palette +http://ethanschoonover.com/solarized/img/solarized-palette.png +*/ + +.solarized.base03 { color: #002b36; } +.solarized.base02 { color: #073642; } +.solarized.base01 { color: #586e75; } +.solarized.base00 { color: #657b83; } +.solarized.base0 { color: #839496; } +.solarized.base1 { color: #93a1a1; } +.solarized.base2 { color: #eee8d5; } +.solarized.base3 { color: #fdf6e3; } +.solarized.solar-yellow { color: #b58900; } +.solarized.solar-orange { color: #cb4b16; } +.solarized.solar-red { color: #dc322f; } +.solarized.solar-magenta { color: #d33682; } +.solarized.solar-violet { color: #6c71c4; } +.solarized.solar-blue { color: #268bd2; } +.solarized.solar-cyan { color: #2aa198; } +.solarized.solar-green { color: #859900; } + +/* Color scheme for code-mirror */ + +.cm-s-solarized { + line-height: 1.45em; + color-profile: sRGB; + rendering-intent: auto; +} +.cm-s-solarized.cm-s-dark { + color: #839496; + background-color: #002b36; + text-shadow: #002b36 0 1px; +} +.cm-s-solarized.cm-s-light { + background-color: #fdf6e3; + color: #657b83; + text-shadow: #eee8d5 0 1px; +} + +.cm-s-solarized .CodeMirror-widget { + text-shadow: none; +} + +.cm-s-solarized .cm-header { color: #586e75; } +.cm-s-solarized .cm-quote { color: #93a1a1; } + +.cm-s-solarized .cm-keyword { color: #cb4b16; } +.cm-s-solarized .cm-atom { color: #d33682; } +.cm-s-solarized .cm-number { color: #d33682; } +.cm-s-solarized .cm-def { color: #2aa198; } + +.cm-s-solarized .cm-variable { color: #839496; } +.cm-s-solarized .cm-variable-2 { color: #b58900; } +.cm-s-solarized .cm-variable-3, .cm-s-solarized .cm-type { color: #6c71c4; } + +.cm-s-solarized .cm-property { color: #2aa198; } +.cm-s-solarized .cm-operator { color: #6c71c4; } + +.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; } + +.cm-s-solarized .cm-string { color: #859900; } +.cm-s-solarized .cm-string-2 { color: #b58900; } + +.cm-s-solarized .cm-meta { color: #859900; } +.cm-s-solarized .cm-qualifier { color: #b58900; } +.cm-s-solarized .cm-builtin { color: #d33682; } +.cm-s-solarized .cm-bracket { color: #cb4b16; } +.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; } +.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; } +.cm-s-solarized .cm-tag { color: #93a1a1; } +.cm-s-solarized .cm-attribute { color: #2aa198; } +.cm-s-solarized .cm-hr { + color: transparent; + border-top: 1px solid #586e75; + display: block; +} +.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; } +.cm-s-solarized .cm-special { color: #6c71c4; } +.cm-s-solarized .cm-em { + color: #999; + text-decoration: underline; + text-decoration-style: dotted; +} +.cm-s-solarized .cm-error, +.cm-s-solarized .cm-invalidchar { + color: #586e75; + border-bottom: 1px dotted #dc322f; +} + +.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; } +.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); } +.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); } + +.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; } +.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; } +.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; } + +/* Editor styling */ + + + +/* Little shadow on the view-port of the buffer view */ +.cm-s-solarized.CodeMirror { + -moz-box-shadow: inset 7px 0 12px -6px #000; + -webkit-box-shadow: inset 7px 0 12px -6px #000; + box-shadow: inset 7px 0 12px -6px #000; +} + +/* Remove gutter border */ +.cm-s-solarized .CodeMirror-gutters { + border-right: 0; +} + +/* Gutter colors and line number styling based of color scheme (dark / light) */ + +/* Dark */ +.cm-s-solarized.cm-s-dark .CodeMirror-gutters { + background-color: #073642; +} + +.cm-s-solarized.cm-s-dark .CodeMirror-linenumber { + color: #586e75; + text-shadow: #021014 0 -1px; +} + +/* Light */ +.cm-s-solarized.cm-s-light .CodeMirror-gutters { + background-color: #eee8d5; +} + +.cm-s-solarized.cm-s-light .CodeMirror-linenumber { + color: #839496; +} + +/* Common */ +.cm-s-solarized .CodeMirror-linenumber { + padding: 0 5px; +} +.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; } +.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; } +.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; } + +.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text { + color: #586e75; +} + +/* Cursor */ +.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; } + +/* Fat cursor */ +.cm-s-solarized.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; } +.cm-s-solarized.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; } +.cm-s-solarized.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: #586e75; } +.cm-s-solarized.cm-s-dark .cm-animate-fat-cursor { background-color: #586e75; } + +/* Active line */ +.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background { + background: rgba(255, 255, 255, 0.06); +} +.cm-s-solarized.cm-s-light .CodeMirror-activeline-background { + background: rgba(0, 0, 0, 0.06); +} diff --git a/backend/webif/static/codemirror/theme/the-matrix.css b/backend/webif/static/codemirror/theme/the-matrix.css new file mode 100755 index 000000000..c4c93c11e --- /dev/null +++ b/backend/webif/static/codemirror/theme/the-matrix.css @@ -0,0 +1,30 @@ +.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; } +.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D; } +.cm-s-the-matrix .CodeMirror-line::selection, .cm-s-the-matrix .CodeMirror-line > span::selection, .cm-s-the-matrix .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-the-matrix .CodeMirror-line::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; } +.cm-s-the-matrix .CodeMirror-guttermarker { color: #0f0; } +.cm-s-the-matrix .CodeMirror-guttermarker-subtle { color: white; } +.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; } +.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00; } + +.cm-s-the-matrix span.cm-keyword { color: #008803; font-weight: bold; } +.cm-s-the-matrix span.cm-atom { color: #3FF; } +.cm-s-the-matrix span.cm-number { color: #FFB94F; } +.cm-s-the-matrix span.cm-def { color: #99C; } +.cm-s-the-matrix span.cm-variable { color: #F6C; } +.cm-s-the-matrix span.cm-variable-2 { color: #C6F; } +.cm-s-the-matrix span.cm-variable-3, .cm-s-the-matrix span.cm-type { color: #96F; } +.cm-s-the-matrix span.cm-property { color: #62FFA0; } +.cm-s-the-matrix span.cm-operator { color: #999; } +.cm-s-the-matrix span.cm-comment { color: #CCCCCC; } +.cm-s-the-matrix span.cm-string { color: #39C; } +.cm-s-the-matrix span.cm-meta { color: #C9F; } +.cm-s-the-matrix span.cm-qualifier { color: #FFF700; } +.cm-s-the-matrix span.cm-builtin { color: #30a; } +.cm-s-the-matrix span.cm-bracket { color: #cc7; } +.cm-s-the-matrix span.cm-tag { color: #FFBD40; } +.cm-s-the-matrix span.cm-attribute { color: #FFF700; } +.cm-s-the-matrix span.cm-error { color: #FF0000; } + +.cm-s-the-matrix .CodeMirror-activeline-background { background: #040; } diff --git a/backend/webif/static/codemirror/theme/tomorrow-night-bright.css b/backend/webif/static/codemirror/theme/tomorrow-night-bright.css new file mode 100755 index 000000000..b6dd4a927 --- /dev/null +++ b/backend/webif/static/codemirror/theme/tomorrow-night-bright.css @@ -0,0 +1,35 @@ +/* + + Name: Tomorrow Night - Bright + Author: Chris Kempson + + Port done by Gerard Braad + +*/ + +.cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; } +.cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; } +.cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; } +.cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; } +.cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; } +.cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } + +.cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; } +.cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; } +.cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; } + +.cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; } +.cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; } +.cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; } + +.cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; } +.cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; } +.cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; } +.cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; } +.cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; } +.cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; } +.cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; } + +.cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; } +.cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/tomorrow-night-eighties.css b/backend/webif/static/codemirror/theme/tomorrow-night-eighties.css new file mode 100755 index 000000000..2a9debc32 --- /dev/null +++ b/backend/webif/static/codemirror/theme/tomorrow-night-eighties.css @@ -0,0 +1,38 @@ +/* + + Name: Tomorrow Night - Eighties + Author: Chris Kempson + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-tomorrow-night-eighties.CodeMirror { background: #000000; color: #CCCCCC; } +.cm-s-tomorrow-night-eighties div.CodeMirror-selected { background: #2D2D2D; } +.cm-s-tomorrow-night-eighties .CodeMirror-line::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-tomorrow-night-eighties .CodeMirror-line::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-tomorrow-night-eighties .CodeMirror-gutters { background: #000000; border-right: 0px; } +.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker { color: #f2777a; } +.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-tomorrow-night-eighties .CodeMirror-linenumber { color: #515151; } +.cm-s-tomorrow-night-eighties .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } + +.cm-s-tomorrow-night-eighties span.cm-comment { color: #d27b53; } +.cm-s-tomorrow-night-eighties span.cm-atom { color: #a16a94; } +.cm-s-tomorrow-night-eighties span.cm-number { color: #a16a94; } + +.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute { color: #99cc99; } +.cm-s-tomorrow-night-eighties span.cm-keyword { color: #f2777a; } +.cm-s-tomorrow-night-eighties span.cm-string { color: #ffcc66; } + +.cm-s-tomorrow-night-eighties span.cm-variable { color: #99cc99; } +.cm-s-tomorrow-night-eighties span.cm-variable-2 { color: #6699cc; } +.cm-s-tomorrow-night-eighties span.cm-def { color: #f99157; } +.cm-s-tomorrow-night-eighties span.cm-bracket { color: #CCCCCC; } +.cm-s-tomorrow-night-eighties span.cm-tag { color: #f2777a; } +.cm-s-tomorrow-night-eighties span.cm-link { color: #a16a94; } +.cm-s-tomorrow-night-eighties span.cm-error { background: #f2777a; color: #6A6A6A; } + +.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background { background: #343600; } +.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/backend/webif/static/codemirror/theme/ttcn.css b/backend/webif/static/codemirror/theme/ttcn.css new file mode 100755 index 000000000..0b14ac35d --- /dev/null +++ b/backend/webif/static/codemirror/theme/ttcn.css @@ -0,0 +1,64 @@ +.cm-s-ttcn .cm-quote { color: #090; } +.cm-s-ttcn .cm-negative { color: #d44; } +.cm-s-ttcn .cm-positive { color: #292; } +.cm-s-ttcn .cm-header, .cm-strong { font-weight: bold; } +.cm-s-ttcn .cm-em { font-style: italic; } +.cm-s-ttcn .cm-link { text-decoration: underline; } +.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } +.cm-s-ttcn .cm-header { color: #00f; font-weight: bold; } + +.cm-s-ttcn .cm-atom { color: #219; } +.cm-s-ttcn .cm-attribute { color: #00c; } +.cm-s-ttcn .cm-bracket { color: #997; } +.cm-s-ttcn .cm-comment { color: #333333; } +.cm-s-ttcn .cm-def { color: #00f; } +.cm-s-ttcn .cm-em { font-style: italic; } +.cm-s-ttcn .cm-error { color: #f00; } +.cm-s-ttcn .cm-hr { color: #999; } +.cm-s-ttcn .cm-invalidchar { color: #f00; } +.cm-s-ttcn .cm-keyword { font-weight:bold; } +.cm-s-ttcn .cm-link { color: #00c; text-decoration: underline; } +.cm-s-ttcn .cm-meta { color: #555; } +.cm-s-ttcn .cm-negative { color: #d44; } +.cm-s-ttcn .cm-positive { color: #292; } +.cm-s-ttcn .cm-qualifier { color: #555; } +.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } +.cm-s-ttcn .cm-string { color: #006400; } +.cm-s-ttcn .cm-string-2 { color: #f50; } +.cm-s-ttcn .cm-strong { font-weight: bold; } +.cm-s-ttcn .cm-tag { color: #170; } +.cm-s-ttcn .cm-variable { color: #8B2252; } +.cm-s-ttcn .cm-variable-2 { color: #05a; } +.cm-s-ttcn .cm-variable-3, .cm-s-ttcn .cm-type { color: #085; } + +.cm-s-ttcn .cm-invalidchar { color: #f00; } + +/* ASN */ +.cm-s-ttcn .cm-accessTypes, +.cm-s-ttcn .cm-compareTypes { color: #27408B; } +.cm-s-ttcn .cm-cmipVerbs { color: #8B2252; } +.cm-s-ttcn .cm-modifier { color:#D2691E; } +.cm-s-ttcn .cm-status { color:#8B4545; } +.cm-s-ttcn .cm-storage { color:#A020F0; } +.cm-s-ttcn .cm-tags { color:#006400; } + +/* CFG */ +.cm-s-ttcn .cm-externalCommands { color: #8B4545; font-weight:bold; } +.cm-s-ttcn .cm-fileNCtrlMaskOptions, +.cm-s-ttcn .cm-sectionTitle { color: #2E8B57; font-weight:bold; } + +/* TTCN */ +.cm-s-ttcn .cm-booleanConsts, +.cm-s-ttcn .cm-otherConsts, +.cm-s-ttcn .cm-verdictConsts { color: #006400; } +.cm-s-ttcn .cm-configOps, +.cm-s-ttcn .cm-functionOps, +.cm-s-ttcn .cm-portOps, +.cm-s-ttcn .cm-sutOps, +.cm-s-ttcn .cm-timerOps, +.cm-s-ttcn .cm-verdictOps { color: #0000FF; } +.cm-s-ttcn .cm-preprocessor, +.cm-s-ttcn .cm-templateMatch, +.cm-s-ttcn .cm-ttcn3Macros { color: #27408B; } +.cm-s-ttcn .cm-types { color: #A52A2A; font-weight:bold; } +.cm-s-ttcn .cm-visibilityModifiers { font-weight:bold; } diff --git a/backend/webif/static/codemirror/theme/twilight.css b/backend/webif/static/codemirror/theme/twilight.css new file mode 100755 index 000000000..b2b1b2aa9 --- /dev/null +++ b/backend/webif/static/codemirror/theme/twilight.css @@ -0,0 +1,32 @@ +.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/ +.cm-s-twilight div.CodeMirror-selected { background: #323232; } /**/ +.cm-s-twilight .CodeMirror-line::selection, .cm-s-twilight .CodeMirror-line > span::selection, .cm-s-twilight .CodeMirror-line > span > span::selection { background: rgba(50, 50, 50, 0.99); } +.cm-s-twilight .CodeMirror-line::-moz-selection, .cm-s-twilight .CodeMirror-line > span::-moz-selection, .cm-s-twilight .CodeMirror-line > span > span::-moz-selection { background: rgba(50, 50, 50, 0.99); } + +.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; } +.cm-s-twilight .CodeMirror-guttermarker { color: white; } +.cm-s-twilight .CodeMirror-guttermarker-subtle { color: #aaa; } +.cm-s-twilight .CodeMirror-linenumber { color: #aaa; } +.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-twilight .cm-keyword { color: #f9ee98; } /**/ +.cm-s-twilight .cm-atom { color: #FC0; } +.cm-s-twilight .cm-number { color: #ca7841; } /**/ +.cm-s-twilight .cm-def { color: #8DA6CE; } +.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/ +.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def, .cm-s-twilight span.cm-type { color: #607392; } /**/ +.cm-s-twilight .cm-operator { color: #cda869; } /**/ +.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/ +.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/ +.cm-s-twilight .cm-string-2 { color:#bd6b18; } /*?*/ +.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/ +.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/ +.cm-s-twilight .cm-tag { color: #997643; } /**/ +.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/ +.cm-s-twilight .cm-header { color: #FF6400; } +.cm-s-twilight .cm-hr { color: #AEAEAE; } +.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/ +.cm-s-twilight .cm-error { border-bottom: 1px solid red; } + +.cm-s-twilight .CodeMirror-activeline-background { background: #27282E; } +.cm-s-twilight .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/vibrant-ink.css b/backend/webif/static/codemirror/theme/vibrant-ink.css new file mode 100755 index 000000000..b13ecf216 --- /dev/null +++ b/backend/webif/static/codemirror/theme/vibrant-ink.css @@ -0,0 +1,34 @@ +/* Taken from the popular Visual Studio Vibrant Ink Schema */ + +.cm-s-vibrant-ink.CodeMirror { background: black; color: white; } +.cm-s-vibrant-ink div.CodeMirror-selected { background: #35493c; } +.cm-s-vibrant-ink .CodeMirror-line::selection, .cm-s-vibrant-ink .CodeMirror-line > span::selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::selection { background: rgba(53, 73, 60, 0.99); } +.cm-s-vibrant-ink .CodeMirror-line::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::-moz-selection { background: rgba(53, 73, 60, 0.99); } + +.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-vibrant-ink .CodeMirror-guttermarker { color: white; } +.cm-s-vibrant-ink .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-vibrant-ink .cm-keyword { color: #CC7832; } +.cm-s-vibrant-ink .cm-atom { color: #FC0; } +.cm-s-vibrant-ink .cm-number { color: #FFEE98; } +.cm-s-vibrant-ink .cm-def { color: #8DA6CE; } +.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; } +.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def, .cm-s-vibrant span.cm-type { color: #FFC66D; } +.cm-s-vibrant-ink .cm-operator { color: #888; } +.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; } +.cm-s-vibrant-ink .cm-string { color: #A5C25C; } +.cm-s-vibrant-ink .cm-string-2 { color: red; } +.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; } +.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-header { color: #FF6400; } +.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; } +.cm-s-vibrant-ink .cm-link { color: blue; } +.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; } + +.cm-s-vibrant-ink .CodeMirror-activeline-background { background: #27282E; } +.cm-s-vibrant-ink .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/xq-dark.css b/backend/webif/static/codemirror/theme/xq-dark.css new file mode 100755 index 000000000..7da1a0f70 --- /dev/null +++ b/backend/webif/static/codemirror/theme/xq-dark.css @@ -0,0 +1,53 @@ +/* +Copyright (C) 2011 by MarkLogic Corporation +Author: Mike Brevoort + +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. +*/ +.cm-s-xq-dark.CodeMirror { background: #0a001f; color: #f8f8f8; } +.cm-s-xq-dark div.CodeMirror-selected { background: #27007A; } +.cm-s-xq-dark .CodeMirror-line::selection, .cm-s-xq-dark .CodeMirror-line > span::selection, .cm-s-xq-dark .CodeMirror-line > span > span::selection { background: rgba(39, 0, 122, 0.99); } +.cm-s-xq-dark .CodeMirror-line::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 0, 122, 0.99); } +.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-xq-dark .CodeMirror-guttermarker { color: #FFBD40; } +.cm-s-xq-dark .CodeMirror-guttermarker-subtle { color: #f8f8f8; } +.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; } +.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-xq-dark span.cm-keyword { color: #FFBD40; } +.cm-s-xq-dark span.cm-atom { color: #6C8CD5; } +.cm-s-xq-dark span.cm-number { color: #164; } +.cm-s-xq-dark span.cm-def { color: #FFF; text-decoration:underline; } +.cm-s-xq-dark span.cm-variable { color: #FFF; } +.cm-s-xq-dark span.cm-variable-2 { color: #EEE; } +.cm-s-xq-dark span.cm-variable-3, .cm-s-xq-dark span.cm-type { color: #DDD; } +.cm-s-xq-dark span.cm-property {} +.cm-s-xq-dark span.cm-operator {} +.cm-s-xq-dark span.cm-comment { color: gray; } +.cm-s-xq-dark span.cm-string { color: #9FEE00; } +.cm-s-xq-dark span.cm-meta { color: yellow; } +.cm-s-xq-dark span.cm-qualifier { color: #FFF700; } +.cm-s-xq-dark span.cm-builtin { color: #30a; } +.cm-s-xq-dark span.cm-bracket { color: #cc7; } +.cm-s-xq-dark span.cm-tag { color: #FFBD40; } +.cm-s-xq-dark span.cm-attribute { color: #FFF700; } +.cm-s-xq-dark span.cm-error { color: #f00; } + +.cm-s-xq-dark .CodeMirror-activeline-background { background: #27282E; } +.cm-s-xq-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/backend/webif/static/codemirror/theme/xq-light.css b/backend/webif/static/codemirror/theme/xq-light.css new file mode 100755 index 000000000..7b182ea99 --- /dev/null +++ b/backend/webif/static/codemirror/theme/xq-light.css @@ -0,0 +1,43 @@ +/* +Copyright (C) 2011 by MarkLogic Corporation +Author: Mike Brevoort + +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. +*/ +.cm-s-xq-light span.cm-keyword { line-height: 1em; font-weight: bold; color: #5A5CAD; } +.cm-s-xq-light span.cm-atom { color: #6C8CD5; } +.cm-s-xq-light span.cm-number { color: #164; } +.cm-s-xq-light span.cm-def { text-decoration:underline; } +.cm-s-xq-light span.cm-variable { color: black; } +.cm-s-xq-light span.cm-variable-2 { color:black; } +.cm-s-xq-light span.cm-variable-3, .cm-s-xq-light span.cm-type { color: black; } +.cm-s-xq-light span.cm-property {} +.cm-s-xq-light span.cm-operator {} +.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; } +.cm-s-xq-light span.cm-string { color: red; } +.cm-s-xq-light span.cm-meta { color: yellow; } +.cm-s-xq-light span.cm-qualifier { color: grey; } +.cm-s-xq-light span.cm-builtin { color: #7EA656; } +.cm-s-xq-light span.cm-bracket { color: #cc7; } +.cm-s-xq-light span.cm-tag { color: #3F7F7F; } +.cm-s-xq-light span.cm-attribute { color: #7F007F; } +.cm-s-xq-light span.cm-error { color: #f00; } + +.cm-s-xq-light .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-xq-light .CodeMirror-matchingbracket { outline:1px solid grey;color:black !important;background:yellow; } diff --git a/backend/webif/static/codemirror/theme/yeti.css b/backend/webif/static/codemirror/theme/yeti.css new file mode 100755 index 000000000..d085f7249 --- /dev/null +++ b/backend/webif/static/codemirror/theme/yeti.css @@ -0,0 +1,44 @@ +/* + + Name: yeti + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax) + +*/ + + +.cm-s-yeti.CodeMirror { + background-color: #ECEAE8 !important; + color: #d1c9c0 !important; + border: none; +} + +.cm-s-yeti .CodeMirror-gutters { + color: #adaba6; + background-color: #E5E1DB; + border: none; +} +.cm-s-yeti .CodeMirror-cursor { border-left: solid thin #d1c9c0; } +.cm-s-yeti .CodeMirror-linenumber { color: #adaba6; } +.cm-s-yeti.CodeMirror-focused div.CodeMirror-selected { background: #DCD8D2; } +.cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection { background: #DCD8D2; } +.cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection { background: #DCD8D2; } +.cm-s-yeti span.cm-comment { color: #d4c8be; } +.cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 { color: #96c0d8; } +.cm-s-yeti span.cm-number { color: #a074c4; } +.cm-s-yeti span.cm-variable { color: #55b5db; } +.cm-s-yeti span.cm-variable-2 { color: #a074c4; } +.cm-s-yeti span.cm-def { color: #55b5db; } +.cm-s-yeti span.cm-operator { color: #9fb96e; } +.cm-s-yeti span.cm-keyword { color: #9fb96e; } +.cm-s-yeti span.cm-atom { color: #a074c4; } +.cm-s-yeti span.cm-meta { color: #96c0d8; } +.cm-s-yeti span.cm-tag { color: #96c0d8; } +.cm-s-yeti span.cm-attribute { color: #9fb96e; } +.cm-s-yeti span.cm-qualifier { color: #96c0d8; } +.cm-s-yeti span.cm-property { color: #a074c4; } +.cm-s-yeti span.cm-builtin { color: #a074c4; } +.cm-s-yeti span.cm-variable-3, .cm-s-yeti span.cm-type { color: #96c0d8; } +.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; } +.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; } diff --git a/backend/webif/static/codemirror/theme/zenburn.css b/backend/webif/static/codemirror/theme/zenburn.css new file mode 100755 index 000000000..781c40aca --- /dev/null +++ b/backend/webif/static/codemirror/theme/zenburn.css @@ -0,0 +1,37 @@ +/** + * " + * Using Zenburn color palette from the Emacs Zenburn Theme + * https://github.com/bbatsov/zenburn-emacs/blob/master/zenburn-theme.el + * + * Also using parts of https://github.com/xavi/coderay-lighttable-theme + * " + * From: https://github.com/wisenomad/zenburn-lighttable-theme/blob/master/zenburn.css + */ + +.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; } +.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; } +.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; } +.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; } +.cm-s-zenburn span.cm-comment { color: #7f9f7f; } +.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; } +.cm-s-zenburn span.cm-atom { color: #bfebbf; } +.cm-s-zenburn span.cm-def { color: #dcdccc; } +.cm-s-zenburn span.cm-variable { color: #dfaf8f; } +.cm-s-zenburn span.cm-variable-2 { color: #dcdccc; } +.cm-s-zenburn span.cm-string { color: #cc9393; } +.cm-s-zenburn span.cm-string-2 { color: #cc9393; } +.cm-s-zenburn span.cm-number { color: #dcdccc; } +.cm-s-zenburn span.cm-tag { color: #93e0e3; } +.cm-s-zenburn span.cm-property { color: #dfaf8f; } +.cm-s-zenburn span.cm-attribute { color: #dfaf8f; } +.cm-s-zenburn span.cm-qualifier { color: #7cb8bb; } +.cm-s-zenburn span.cm-meta { color: #f0dfaf; } +.cm-s-zenburn span.cm-header { color: #f0efd0; } +.cm-s-zenburn span.cm-operator { color: #f0efd0; } +.cm-s-zenburn span.CodeMirror-matchingbracket { box-sizing: border-box; background: transparent; border-bottom: 1px solid; } +.cm-s-zenburn span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid; background: none; } +.cm-s-zenburn .CodeMirror-activeline { background: #000000; } +.cm-s-zenburn .CodeMirror-activeline-background { background: #000000; } +.cm-s-zenburn div.CodeMirror-selected { background: #545454; } +.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected { background: #4f4f4f; } diff --git a/backend/webif/static/css/backend.css b/backend/webif/static/css/backend.css new file mode 100755 index 000000000..d2a5d5801 --- /dev/null +++ b/backend/webif/static/css/backend.css @@ -0,0 +1,12 @@ +.table.table-striped.pluginList>tbody>tr:nth-child(even) { + background-color:#fff; +} + +.table.table-striped.logicsList>tbody>tr:nth-child(4n+3) { + background-color:#fff; +} + +.table-hover>tbody>tr:hover>td, +.table-hover>tbody>tr:hover>th { + background-color: #ecf3f8; +} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-reload.css b/backend/webif/static/css/bootstrap-reload.css new file mode 100755 index 000000000..0fd748a6d --- /dev/null +++ b/backend/webif/static/css/bootstrap-reload.css @@ -0,0 +1,20 @@ +.panel-refresh { + min-height:250px; + position:relative; +} + +.refresh-container { + position:absolute; + top:0; + right:0; + background:rgba(0, 0, 0, 0.5); + width:100%; + height:100%; + display: none; + text-align:center; + z-index:4; +} +.refresh-spinner { + padding: 30px; + opacity: 0.8; +} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-theme.css b/backend/webif/static/css/bootstrap-theme.css new file mode 100755 index 000000000..31d888266 --- /dev/null +++ b/backend/webif/static/css/bootstrap-theme.css @@ -0,0 +1,587 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default.disabled, +.btn-primary.disabled, +.btn-success.disabled, +.btn-info.disabled, +.btn-warning.disabled, +.btn-danger.disabled, +.btn-default[disabled], +.btn-primary[disabled], +.btn-success[disabled], +.btn-info[disabled], +.btn-warning[disabled], +.btn-danger[disabled], +fieldset[disabled] .btn-default, +fieldset[disabled] .btn-primary, +fieldset[disabled] .btn-success, +fieldset[disabled] .btn-info, +fieldset[disabled] .btn-warning, +fieldset[disabled] .btn-danger { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/backend/webif/static/css/bootstrap-theme.css.map b/backend/webif/static/css/bootstrap-theme.css.map new file mode 100755 index 000000000..d876f60fb --- /dev/null +++ b/backend/webif/static/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-theme.min.css b/backend/webif/static/css/bootstrap-theme.min.css new file mode 100755 index 000000000..5e3940195 --- /dev/null +++ b/backend/webif/static/css/bootstrap-theme.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} +/*# sourceMappingURL=bootstrap-theme.min.css.map */ \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-theme.min.css.map b/backend/webif/static/css/bootstrap-theme.min.css.map new file mode 100755 index 000000000..94813e900 --- /dev/null +++ b/backend/webif/static/css/bootstrap-theme.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-treeview.css b/backend/webif/static/css/bootstrap-treeview.css new file mode 100755 index 000000000..23c6cf066 --- /dev/null +++ b/backend/webif/static/css/bootstrap-treeview.css @@ -0,0 +1,37 @@ +/* ========================================================= + * bootstrap-treeview.css v1.2.0 + * ========================================================= + * Copyright 2013 Jonathan Miles + * Project URL : http://www.jondmiles.com/bootstrap-treeview + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +.treeview .list-group-item { + cursor: pointer; +} + +.treeview span.indent { + margin-left: 10px; + margin-right: 10px; +} + +.treeview span.icon { + width: 12px; + margin-right: 5px; +} + +.treeview .node-disabled { + color: silver; + cursor: not-allowed; +} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap-treeview.min.css b/backend/webif/static/css/bootstrap-treeview.min.css new file mode 100755 index 000000000..57a348a87 --- /dev/null +++ b/backend/webif/static/css/bootstrap-treeview.min.css @@ -0,0 +1 @@ +.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap.css b/backend/webif/static/css/bootstrap.css new file mode 100755 index 000000000..6167622ce --- /dev/null +++ b/backend/webif/static/css/bootstrap.css @@ -0,0 +1,6757 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + padding-right: 15px; + padding-left: 15px; + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/backend/webif/static/css/bootstrap.css.map b/backend/webif/static/css/bootstrap.css.map new file mode 100755 index 000000000..f010c82d1 --- /dev/null +++ b/backend/webif/static/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,4EAA4E;ACG5E;EACE,wBAAA;EACA,2BAAA;EACA,+BAAA;CDDD;ACQD;EACE,UAAA;CDND;ACmBD;;;;;;;;;;;;;EAaE,eAAA;CDjBD;ACyBD;;;;EAIE,sBAAA;EACA,yBAAA;CDvBD;AC+BD;EACE,cAAA;EACA,UAAA;CD7BD;ACqCD;;EAEE,cAAA;CDnCD;AC6CD;EACE,8BAAA;CD3CD;ACmDD;;EAEE,WAAA;CDjDD;AC2DD;EACE,0BAAA;CDzDD;ACgED;;EAEE,kBAAA;CD9DD;ACqED;EACE,mBAAA;CDnED;AC2ED;EACE,eAAA;EACA,iBAAA;CDzED;ACgFD;EACE,iBAAA;EACA,YAAA;CD9ED;ACqFD;EACE,eAAA;CDnFD;AC0FD;;EAEE,eAAA;EACA,eAAA;EACA,mBAAA;EACA,yBAAA;CDxFD;AC2FD;EACE,YAAA;CDzFD;AC4FD;EACE,gBAAA;CD1FD;ACoGD;EACE,UAAA;CDlGD;ACyGD;EACE,iBAAA;CDvGD;ACiHD;EACE,iBAAA;CD/GD;ACsHD;EACE,gCAAA;KAAA,6BAAA;UAAA,wBAAA;EACA,UAAA;CDpHD;AC2HD;EACE,eAAA;CDzHD;ACgID;;;;EAIE,kCAAA;EACA,eAAA;CD9HD;ACgJD;;;;;EAKE,eAAA;EACA,cAAA;EACA,UAAA;CD9ID;ACqJD;EACE,kBAAA;CDnJD;AC6JD;;EAEE,qBAAA;CD3JD;ACsKD;;;;EAIE,2BAAA;EACA,gBAAA;CDpKD;AC2KD;;EAEE,gBAAA;CDzKD;ACgLD;;EAEE,UAAA;EACA,WAAA;CD9KD;ACsLD;EACE,oBAAA;CDpLD;AC+LD;;EAEE,+BAAA;KAAA,4BAAA;UAAA,uBAAA;EACA,WAAA;CD7LD;ACsMD;;EAEE,aAAA;CDpMD;AC4MD;EACE,8BAAA;EACA,gCAAA;KAAA,6BAAA;UAAA,wBAAA;CD1MD;ACmND;;EAEE,yBAAA;CDjND;ACwND;EACE,0BAAA;EACA,cAAA;EACA,+BAAA;CDtND;AC8ND;EACE,UAAA;EACA,WAAA;CD5ND;ACmOD;EACE,eAAA;CDjOD;ACyOD;EACE,kBAAA;CDvOD;ACiPD;EACE,0BAAA;EACA,kBAAA;CD/OD;ACkPD;;EAEE,WAAA;CDhPD;AACD,qFAAqF;AElFrF;EA7FI;;;IAGI,mCAAA;IACA,uBAAA;IACA,oCAAA;YAAA,4BAAA;IACA,6BAAA;GFkLL;EE/KC;;IAEI,2BAAA;GFiLL;EE9KC;IACI,6BAAA;GFgLL;EE7KC;IACI,8BAAA;GF+KL;EE1KC;;IAEI,YAAA;GF4KL;EEzKC;;IAEI,uBAAA;IACA,yBAAA;GF2KL;EExKC;IACI,4BAAA;GF0KL;EEvKC;;IAEI,yBAAA;GFyKL;EEtKC;IACI,2BAAA;GFwKL;EErKC;;;IAGI,WAAA;IACA,UAAA;GFuKL;EEpKC;;IAEI,wBAAA;GFsKL;EEhKC;IACI,cAAA;GFkKL;EEhKC;;IAGQ,kCAAA;GFiKT;EE9JC;IACI,uBAAA;GFgKL;EE7JC;IACI,qCAAA;GF+JL;EEhKC;;IAKQ,kCAAA;GF+JT;EE5JC;;IAGQ,kCAAA;GF6JT;CACF;AGnPD;EACE,oCAAA;EACA,sDAAA;EACA,gYAAA;CHqPD;AG7OD;EACE,mBAAA;EACA,SAAA;EACA,sBAAA;EACA,oCAAA;EACA,mBAAA;EACA,oBAAA;EACA,eAAA;EACA,oCAAA;EACA,mCAAA;CH+OD;AG3OmC;EAAW,iBAAA;CH8O9C;AG7OmC;EAAW,iBAAA;CHgP9C;AG9OmC;;EAAW,iBAAA;CHkP9C;AGjPmC;EAAW,iBAAA;CHoP9C;AGnPmC;EAAW,iBAAA;CHsP9C;AGrPmC;EAAW,iBAAA;CHwP9C;AGvPmC;EAAW,iBAAA;CH0P9C;AGzPmC;EAAW,iBAAA;CH4P9C;AG3PmC;EAAW,iBAAA;CH8P9C;AG7PmC;EAAW,iBAAA;CHgQ9C;AG/PmC;EAAW,iBAAA;CHkQ9C;AGjQmC;EAAW,iBAAA;CHoQ9C;AGnQmC;EAAW,iBAAA;CHsQ9C;AGrQmC;EAAW,iBAAA;CHwQ9C;AGvQmC;EAAW,iBAAA;CH0Q9C;AGzQmC;EAAW,iBAAA;CH4Q9C;AG3QmC;EAAW,iBAAA;CH8Q9C;AG7QmC;EAAW,iBAAA;CHgR9C;AG/QmC;EAAW,iBAAA;CHkR9C;AGjRmC;EAAW,iBAAA;CHoR9C;AGnRmC;EAAW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;EAAW,iBAAA;CH4tB9C;AG3tBmC;EAAW,iBAAA;CH8tB9C;AG7tBmC;EAAW,iBAAA;CHguB9C;AG/tBmC;EAAW,iBAAA;CHkuB9C;AGjuBmC;EAAW,iBAAA;CHouB9C;AGnuBmC;EAAW,iBAAA;CHsuB9C;AGruBmC;EAAW,iBAAA;CHwuB9C;AGvuBmC;EAAW,iBAAA;CH0uB9C;AGzuBmC;EAAW,iBAAA;CH4uB9C;AG3uBmC;EAAW,iBAAA;CH8uB9C;AG7uBmC;EAAW,iBAAA;CHgvB9C;AIthCD;ECgEE,+BAAA;EACG,4BAAA;EACK,uBAAA;CLy9BT;AIxhCD;;EC6DE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL+9BT;AIthCD;EACE,gBAAA;EACA,8CAAA;CJwhCD;AIrhCD;EACE,4DAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;CJuhCD;AInhCD;;;;EAIE,qBAAA;EACA,mBAAA;EACA,qBAAA;CJqhCD;AI/gCD;EACE,eAAA;EACA,sBAAA;CJihCD;AI/gCC;;EAEE,eAAA;EACA,2BAAA;CJihCH;AI9gCC;EEnDA,2CAAA;EACA,qBAAA;CNokCD;AIvgCD;EACE,UAAA;CJygCD;AIngCD;EACE,uBAAA;CJqgCD;AIjgCD;;;;;EGvEE,eAAA;EACA,gBAAA;EACA,aAAA;CP+kCD;AIrgCD;EACE,mBAAA;CJugCD;AIjgCD;EACE,aAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EC6FA,yCAAA;EACK,oCAAA;EACG,iCAAA;EEvLR,sBAAA;EACA,gBAAA;EACA,aAAA;CP+lCD;AIjgCD;EACE,mBAAA;CJmgCD;AI7/BD;EACE,iBAAA;EACA,oBAAA;EACA,UAAA;EACA,8BAAA;CJ+/BD;AIv/BD;EACE,mBAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,WAAA;EACA,iBAAA;EACA,uBAAA;EACA,UAAA;CJy/BD;AIj/BC;;EAEE,iBAAA;EACA,YAAA;EACA,aAAA;EACA,UAAA;EACA,kBAAA;EACA,WAAA;CJm/BH;AIx+BD;EACE,gBAAA;CJ0+BD;AQjoCD;;;;;;;;;;;;EAEE,qBAAA;EACA,iBAAA;EACA,iBAAA;EACA,eAAA;CR6oCD;AQlpCD;;;;;;;;;;;;;;;;;;;;;;;;EASI,oBAAA;EACA,eAAA;EACA,eAAA;CRmqCH;AQ/pCD;;;;;;EAGE,iBAAA;EACA,oBAAA;CRoqCD;AQxqCD;;;;;;;;;;;;EAQI,eAAA;CR8qCH;AQ3qCD;;;;;;EAGE,iBAAA;EACA,oBAAA;CRgrCD;AQprCD;;;;;;;;;;;;EAQI,eAAA;CR0rCH;AQtrCD;;EAAU,gBAAA;CR0rCT;AQzrCD;;EAAU,gBAAA;CR6rCT;AQ5rCD;;EAAU,gBAAA;CRgsCT;AQ/rCD;;EAAU,gBAAA;CRmsCT;AQlsCD;;EAAU,gBAAA;CRssCT;AQrsCD;;EAAU,gBAAA;CRysCT;AQnsCD;EACE,iBAAA;CRqsCD;AQlsCD;EACE,oBAAA;EACA,gBAAA;EACA,iBAAA;EACA,iBAAA;CRosCD;AQ/rCD;EAwOA;IA1OI,gBAAA;GRqsCD;CACF;AQ7rCD;;EAEE,eAAA;CR+rCD;AQ5rCD;;EAEE,0BAAA;EACA,cAAA;CR8rCD;AQ1rCD;EAAuB,iBAAA;CR6rCtB;AQ5rCD;EAAuB,kBAAA;CR+rCtB;AQ9rCD;EAAuB,mBAAA;CRisCtB;AQhsCD;EAAuB,oBAAA;CRmsCtB;AQlsCD;EAAuB,oBAAA;CRqsCtB;AQlsCD;EAAuB,0BAAA;CRqsCtB;AQpsCD;EAAuB,0BAAA;CRusCtB;AQtsCD;EAAuB,2BAAA;CRysCtB;AQtsCD;EACE,eAAA;CRwsCD;AQtsCD;ECrGE,eAAA;CT8yCD;AS7yCC;;EAEE,eAAA;CT+yCH;AQ1sCD;ECxGE,eAAA;CTqzCD;ASpzCC;;EAEE,eAAA;CTszCH;AQ9sCD;EC3GE,eAAA;CT4zCD;AS3zCC;;EAEE,eAAA;CT6zCH;AQltCD;EC9GE,eAAA;CTm0CD;ASl0CC;;EAEE,eAAA;CTo0CH;AQttCD;ECjHE,eAAA;CT00CD;ASz0CC;;EAEE,eAAA;CT20CH;AQttCD;EAGE,YAAA;EE3HA,0BAAA;CVk1CD;AUj1CC;;EAEE,0BAAA;CVm1CH;AQxtCD;EE9HE,0BAAA;CVy1CD;AUx1CC;;EAEE,0BAAA;CV01CH;AQ5tCD;EEjIE,0BAAA;CVg2CD;AU/1CC;;EAEE,0BAAA;CVi2CH;AQhuCD;EEpIE,0BAAA;CVu2CD;AUt2CC;;EAEE,0BAAA;CVw2CH;AQpuCD;EEvIE,0BAAA;CV82CD;AU72CC;;EAEE,0BAAA;CV+2CH;AQnuCD;EACE,oBAAA;EACA,oBAAA;EACA,iCAAA;CRquCD;AQ7tCD;;EAEE,cAAA;EACA,oBAAA;CR+tCD;AQluCD;;;;EAMI,iBAAA;CRkuCH;AQ3tCD;EACE,gBAAA;EACA,iBAAA;CR6tCD;AQztCD;EALE,gBAAA;EACA,iBAAA;EAMA,kBAAA;CR4tCD;AQ9tCD;EAKI,sBAAA;EACA,kBAAA;EACA,mBAAA;CR4tCH;AQvtCD;EACE,cAAA;EACA,oBAAA;CRytCD;AQvtCD;;EAEE,wBAAA;CRytCD;AQvtCD;EACE,kBAAA;CRytCD;AQvtCD;EACE,eAAA;CRytCD;AQhsCD;EA6EA;IAvFM,YAAA;IACA,aAAA;IACA,YAAA;IACA,kBAAA;IGtNJ,iBAAA;IACA,wBAAA;IACA,oBAAA;GXq6CC;EQ7nCH;IAhFM,mBAAA;GRgtCH;CACF;AQvsCD;;EAGE,aAAA;EACA,kCAAA;CRwsCD;AQtsCD;EACE,eAAA;EA9IqB,0BAAA;CRu1CtB;AQpsCD;EACE,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,+BAAA;CRssCD;AQjsCG;;;EACE,iBAAA;CRqsCL;AQ/sCD;;;EAmBI,eAAA;EACA,eAAA;EACA,wBAAA;EACA,eAAA;CRisCH;AQ/rCG;;;EACE,uBAAA;CRmsCL;AQ3rCD;;EAEE,oBAAA;EACA,gBAAA;EACA,gCAAA;EACA,eAAA;EACA,kBAAA;CR6rCD;AQvrCG;;;;;;EAAW,YAAA;CR+rCd;AQ9rCG;;;;;;EACE,uBAAA;CRqsCL;AQ/rCD;EACE,oBAAA;EACA,mBAAA;EACA,wBAAA;CRisCD;AYv+CD;;;;EAIE,+DAAA;CZy+CD;AYr+CD;EACE,iBAAA;EACA,eAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CZu+CD;AYn+CD;EACE,iBAAA;EACA,eAAA;EACA,YAAA;EACA,uBAAA;EACA,mBAAA;EACA,uDAAA;UAAA,+CAAA;CZq+CD;AY3+CD;EASI,WAAA;EACA,gBAAA;EACA,kBAAA;EACA,yBAAA;UAAA,iBAAA;CZq+CH;AYh+CD;EACE,eAAA;EACA,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,sBAAA;EACA,sBAAA;EACA,eAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;CZk+CD;AY7+CD;EAeI,WAAA;EACA,mBAAA;EACA,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,iBAAA;CZi+CH;AY59CD;EACE,kBAAA;EACA,mBAAA;CZ89CD;AaxhDD;ECHE,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,oBAAA;Cd8hDD;AaxhDC;EAqEF;IAvEI,aAAA;Gb8hDD;CACF;Aa1hDC;EAkEF;IApEI,aAAA;GbgiDD;CACF;Aa5hDD;EA+DA;IAjEI,cAAA;GbkiDD;CACF;AazhDD;ECvBE,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,oBAAA;CdmjDD;AathDD;ECvBE,mBAAA;EACA,oBAAA;CdgjDD;AehjDG;EACE,mBAAA;EAEA,gBAAA;EAEA,mBAAA;EACA,oBAAA;CfgjDL;AehiDG;EACE,YAAA;CfkiDL;Ae3hDC;EACE,YAAA;Cf6hDH;Ae9hDC;EACE,oBAAA;CfgiDH;AejiDC;EACE,oBAAA;CfmiDH;AepiDC;EACE,WAAA;CfsiDH;AeviDC;EACE,oBAAA;CfyiDH;Ae1iDC;EACE,oBAAA;Cf4iDH;Ae7iDC;EACE,WAAA;Cf+iDH;AehjDC;EACE,oBAAA;CfkjDH;AenjDC;EACE,oBAAA;CfqjDH;AetjDC;EACE,WAAA;CfwjDH;AezjDC;EACE,oBAAA;Cf2jDH;Ae5jDC;EACE,mBAAA;Cf8jDH;AehjDC;EACE,YAAA;CfkjDH;AenjDC;EACE,oBAAA;CfqjDH;AetjDC;EACE,oBAAA;CfwjDH;AezjDC;EACE,WAAA;Cf2jDH;Ae5jDC;EACE,oBAAA;Cf8jDH;Ae/jDC;EACE,oBAAA;CfikDH;AelkDC;EACE,WAAA;CfokDH;AerkDC;EACE,oBAAA;CfukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBAAA;EACA,oBAAA;ChBqrED;AgBxrED;;;;;;EAWQ,aAAA;EACA,wBAAA;EACA,oBAAA;EACA,2BAAA;ChBqrEP;AgBnsED;EAoBI,uBAAA;EACA,8BAAA;ChBkrEH;AgBvsED;;;;;;EA8BQ,cAAA;ChBirEP;AgB/sED;EAoCI,2BAAA;ChB8qEH;AgBltED;EAyCI,uBAAA;ChB4qEH;AgBrqED;;;;;;EAOQ,aAAA;ChBsqEP;AgB3pED;EACE,uBAAA;ChB6pED;AgB9pED;;;;;;EAQQ,uBAAA;ChB8pEP;AgBtqED;;EAeM,yBAAA;ChB2pEL;AgBjpED;EAEI,0BAAA;ChBkpEH;AgBzoED;EAEI,0BAAA;ChB0oEH;AgBjoED;EACE,iBAAA;EACA,YAAA;EACA,sBAAA;ChBmoED;AgB9nEG;;EACE,iBAAA;EACA,YAAA;EACA,oBAAA;ChBioEL;AiB7wEC;;;;;;;;;;;;EAOI,0BAAA;CjBoxEL;AiB9wEC;;;;;EAMI,0BAAA;CjB+wEL;AiBlyEC;;;;;;;;;;;;EAOI,0BAAA;CjByyEL;AiBnyEC;;;;;EAMI,0BAAA;CjBoyEL;AiBvzEC;;;;;;;;;;;;EAOI,0BAAA;CjB8zEL;AiBxzEC;;;;;EAMI,0BAAA;CjByzEL;AiB50EC;;;;;;;;;;;;EAOI,0BAAA;CjBm1EL;AiB70EC;;;;;EAMI,0BAAA;CjB80EL;AiBj2EC;;;;;;;;;;;;EAOI,0BAAA;CjBw2EL;AiBl2EC;;;;;EAMI,0BAAA;CjBm2EL;AgBjtED;EACE,iBAAA;EACA,kBAAA;ChBmtED;AgBtpED;EACA;IA3DI,YAAA;IACA,oBAAA;IACA,mBAAA;IACA,6CAAA;IACA,uBAAA;GhBotED;EgB7pEH;IAnDM,iBAAA;GhBmtEH;EgBhqEH;;;;;;IA1CY,oBAAA;GhBktET;EgBxqEH;IAlCM,UAAA;GhB6sEH;EgB3qEH;;;;;;IAzBY,eAAA;GhB4sET;EgBnrEH;;;;;;IArBY,gBAAA;GhBgtET;EgB3rEH;;;;IARY,iBAAA;GhBysET;CACF;AkBn6ED;EACE,WAAA;EACA,UAAA;EACA,UAAA;EAIA,aAAA;ClBk6ED;AkB/5ED;EACE,eAAA;EACA,YAAA;EACA,WAAA;EACA,oBAAA;EACA,gBAAA;EACA,qBAAA;EACA,eAAA;EACA,UAAA;EACA,iCAAA;ClBi6ED;AkB95ED;EACE,sBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;ClBg6ED;AkBr5ED;Eb4BE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL43ET;AkBr5ED;;EAEE,gBAAA;EACA,mBAAA;EACA,oBAAA;ClBu5ED;AkBp5ED;EACE,eAAA;ClBs5ED;AkBl5ED;EACE,eAAA;EACA,YAAA;ClBo5ED;AkBh5ED;;EAEE,aAAA;ClBk5ED;AkB94ED;;;EZrEE,2CAAA;EACA,qBAAA;CNw9ED;AkB74ED;EACE,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;ClB+4ED;AkBr3ED;EACE,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EbxDA,yDAAA;EACQ,iDAAA;EAyHR,uFAAA;EACK,0EAAA;EACG,uEAAA;CLwzET;AmBh8EC;EACE,sBAAA;EACA,WAAA;EdUF,uFAAA;EACQ,+EAAA;CLy7ET;AKx5EC;EACE,YAAA;EACA,WAAA;CL05EH;AKx5EC;EAA0B,YAAA;CL25E3B;AK15EC;EAAgC,YAAA;CL65EjC;AkBj4EC;EACE,UAAA;EACA,8BAAA;ClBm4EH;AkB33EC;;;EAGE,0BAAA;EACA,WAAA;ClB63EH;AkB13EC;;EAEE,oBAAA;ClB43EH;AkBx3EC;EACE,aAAA;ClB03EH;AkB92ED;EACE,yBAAA;ClBg3ED;AkBx0ED;EAtBI;;;;IACE,kBAAA;GlBo2EH;EkBj2EC;;;;;;;;IAEE,kBAAA;GlBy2EH;EkBt2EC;;;;;;;;IAEE,kBAAA;GlB82EH;CACF;AkBp2ED;EACE,oBAAA;ClBs2ED;AkB91ED;;EAEE,mBAAA;EACA,eAAA;EACA,iBAAA;EACA,oBAAA;ClBg2ED;AkBr2ED;;EAQI,iBAAA;EACA,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,gBAAA;ClBi2EH;AkB91ED;;;;EAIE,mBAAA;EACA,mBAAA;EACA,mBAAA;ClBg2ED;AkB71ED;;EAEE,iBAAA;ClB+1ED;AkB31ED;;EAEE,mBAAA;EACA,sBAAA;EACA,mBAAA;EACA,iBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;ClB61ED;AkB31ED;;EAEE,cAAA;EACA,kBAAA;ClB61ED;AkBp1EC;;;;;;EAGE,oBAAA;ClBy1EH;AkBn1EC;;;;EAEE,oBAAA;ClBu1EH;AkBj1EC;;;;EAGI,oBAAA;ClBo1EL;AkBz0ED;EAEE,iBAAA;EACA,oBAAA;EAEA,iBAAA;EACA,iBAAA;ClBy0ED;AkBv0EC;;EAEE,gBAAA;EACA,iBAAA;ClBy0EH;AkB5zED;ECnQE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnBkkFD;AmBhkFC;EACE,aAAA;EACA,kBAAA;CnBkkFH;AmB/jFC;;EAEE,aAAA;CnBikFH;AkBx0ED;EAEI,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;ClBy0EH;AkB/0ED;EASI,aAAA;EACA,kBAAA;ClBy0EH;AkBn1ED;;EAcI,aAAA;ClBy0EH;AkBv1ED;EAiBI,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;ClBy0EH;AkBr0ED;EC/RE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBumFD;AmBrmFC;EACE,aAAA;EACA,kBAAA;CnBumFH;AmBpmFC;;EAEE,aAAA;CnBsmFH;AkBj1ED;EAEI,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ClBk1EH;AkBx1ED;EASI,aAAA;EACA,kBAAA;ClBk1EH;AkB51ED;;EAcI,aAAA;ClBk1EH;AkBh2ED;EAiBI,aAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;ClBk1EH;AkBz0ED;EAEE,mBAAA;ClB00ED;AkB50ED;EAMI,sBAAA;ClBy0EH;AkBr0ED;EACE,mBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,mBAAA;EACA,qBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBn0ED;;;;;;;;;;EC1ZI,eAAA;CnByuFH;AkB/0ED;ECtZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CL0rFT;AmBxuFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL+rFT;AkBz1ED;EC5YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBwuFH;AkB91ED;ECtYI,eAAA;CnBuuFH;AkB91ED;;;;;;;;;;EC7ZI,eAAA;CnBuwFH;AkB12ED;ECzZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLwtFT;AmBtwFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL6tFT;AkBp3ED;EC/YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBswFH;AkBz3ED;ECzYI,eAAA;CnBqwFH;AkBz3ED;;;;;;;;;;EChaI,eAAA;CnBqyFH;AkBr4ED;EC5ZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLsvFT;AmBpyFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL2vFT;AkB/4ED;EClZI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBoyFH;AkBp5ED;EC5YI,eAAA;CnBmyFH;AkBh5EC;EACE,UAAA;ClBk5EH;AkBh5EC;EACE,OAAA;ClBk5EH;AkBx4ED;EACE,eAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;ClB04ED;AkBvzED;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBy3EH;EkBrvEH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBu3EH;EkB1vEH;IAxHM,sBAAA;GlBq3EH;EkB7vEH;IApHM,sBAAA;IACA,uBAAA;GlBo3EH;EkBjwEH;;;IA9GQ,YAAA;GlBo3EL;EkBtwEH;IAxGM,YAAA;GlBi3EH;EkBzwEH;IApGM,iBAAA;IACA,uBAAA;GlBg3EH;EkB7wEH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB62EH;EkBpxEH;;IAtFQ,gBAAA;GlB82EL;EkBxxEH;;IAjFM,mBAAA;IACA,eAAA;GlB62EH;EkB7xEH;IA3EM,OAAA;GlB22EH;CACF;AkBj2ED;;;;EASI,cAAA;EACA,iBAAA;EACA,iBAAA;ClB81EH;AkBz2ED;;EAiBI,iBAAA;ClB41EH;AkB72ED;EJthBE,mBAAA;EACA,oBAAA;Cds4FD;AkB10EC;EAyBF;IAnCM,kBAAA;IACA,iBAAA;IACA,iBAAA;GlBw1EH;CACF;AkBx3ED;EAwCI,YAAA;ClBm1EH;AkBr0EC;EAUF;IAdQ,kBAAA;IACA,gBAAA;GlB60EL;CACF;AkBn0EC;EAEF;IANQ,iBAAA;IACA,gBAAA;GlB20EL;CACF;AoBp6FD;EACE,sBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,uBAAA;EACA,+BAAA;MAAA,2BAAA;EACA,gBAAA;EACA,uBAAA;EACA,8BAAA;EACA,oBAAA;EC0CA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,mBAAA;EhB+JA,0BAAA;EACG,uBAAA;EACC,sBAAA;EACI,kBAAA;CL+tFT;AoBv6FG;;;;;;EdnBF,2CAAA;EACA,qBAAA;CNk8FD;AoB16FC;;;EAGE,YAAA;EACA,sBAAA;CpB46FH;AoBz6FC;;EAEE,WAAA;EACA,uBAAA;Ef2BF,yDAAA;EACQ,iDAAA;CLi5FT;AoBz6FC;;;EAGE,oBAAA;EE7CF,cAAA;EAGA,0BAAA;EjB8DA,yBAAA;EACQ,iBAAA;CL05FT;AoBz6FG;;EAEE,qBAAA;CpB26FL;AoBl6FD;EC3DE,YAAA;EACA,uBAAA;EACA,mBAAA;CrBg+FD;AqB99FC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBs+FT;AqBn+FC;;;EAGE,uBAAA;CrBq+FH;AqBh+FG;;;;;;;;;EAGE,uBAAA;EACI,mBAAA;CrBw+FT;AoBv9FD;ECZI,YAAA;EACA,uBAAA;CrBs+FH;AoBx9FD;EC9DE,YAAA;EACA,0BAAA;EACA,sBAAA;CrByhGD;AqBvhGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB+hGT;AqB5hGC;;;EAGE,uBAAA;CrB8hGH;AqBzhGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBiiGT;AoB7gGD;ECfI,eAAA;EACA,uBAAA;CrB+hGH;AoB7gGD;EClEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBklGD;AqBhlGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBwlGT;AqBrlGC;;;EAGE,uBAAA;CrBulGH;AqBllGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB0lGT;AoBlkGD;ECnBI,eAAA;EACA,uBAAA;CrBwlGH;AoBlkGD;ECtEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB2oGD;AqBzoGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBipGT;AqB9oGC;;;EAGE,uBAAA;CrBgpGH;AqB3oGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBmpGT;AoBvnGD;ECvBI,eAAA;EACA,uBAAA;CrBipGH;AoBvnGD;EC1EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBosGD;AqBlsGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB0sGT;AqBvsGC;;;EAGE,uBAAA;CrBysGH;AqBpsGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB4sGT;AoB5qGD;EC3BI,eAAA;EACA,uBAAA;CrB0sGH;AoB5qGD;EC9EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB6vGD;AqB3vGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBmwGT;AqBhwGC;;;EAGE,uBAAA;CrBkwGH;AqB7vGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBqwGT;AoBjuGD;EC/BI,eAAA;EACA,uBAAA;CrBmwGH;AoB5tGD;EACE,eAAA;EACA,oBAAA;EACA,iBAAA;CpB8tGD;AoB5tGC;;;;;EAKE,8BAAA;EfnCF,yBAAA;EACQ,iBAAA;CLkwGT;AoB7tGC;;;;EAIE,0BAAA;CpB+tGH;AoB7tGC;;EAEE,eAAA;EACA,2BAAA;EACA,8BAAA;CpB+tGH;AoB3tGG;;;;EAEE,eAAA;EACA,sBAAA;CpB+tGL;AoBttGD;;ECxEE,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CrBkyGD;AoBztGD;;EC5EE,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrByyGD;AoB5tGD;;EChFE,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrBgzGD;AoB3tGD;EACE,eAAA;EACA,YAAA;CpB6tGD;AoBztGD;EACE,gBAAA;CpB2tGD;AoBptGC;;;EACE,YAAA;CpBwtGH;AuBl3GD;EACE,WAAA;ElBoLA,yCAAA;EACK,oCAAA;EACG,iCAAA;CLisGT;AuBr3GC;EACE,WAAA;CvBu3GH;AuBn3GD;EACE,cAAA;CvBq3GD;AuBn3GC;EAAY,eAAA;CvBs3Gb;AuBr3GC;EAAY,mBAAA;CvBw3Gb;AuBv3GC;EAAY,yBAAA;CvB03Gb;AuBv3GD;EACE,mBAAA;EACA,UAAA;EACA,iBAAA;ElBuKA,gDAAA;EACQ,2CAAA;KAAA,wCAAA;EAOR,mCAAA;EACQ,8BAAA;KAAA,2BAAA;EAGR,yCAAA;EACQ,oCAAA;KAAA,iCAAA;CL2sGT;AwBr5GD;EACE,sBAAA;EACA,SAAA;EACA,UAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,yBAAA;EACA,oCAAA;EACA,mCAAA;CxBu5GD;AwBn5GD;;EAEE,mBAAA;CxBq5GD;AwBj5GD;EACE,WAAA;CxBm5GD;AwB/4GD;EACE,mBAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,sCAAA;EACA,mBAAA;EnBsBA,oDAAA;EACQ,4CAAA;EmBrBR,qCAAA;UAAA,6BAAA;CxBk5GD;AwB74GC;EACE,SAAA;EACA,WAAA;CxB+4GH;AwBx6GD;ECzBE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBo8GD;AwB96GD;EAmCI,eAAA;EACA,kBAAA;EACA,YAAA;EACA,oBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxB84GH;AwBx4GC;;EAEE,sBAAA;EACA,eAAA;EACA,0BAAA;CxB04GH;AwBp4GC;;;EAGE,YAAA;EACA,sBAAA;EACA,WAAA;EACA,0BAAA;CxBs4GH;AwB73GC;;;EAGE,eAAA;CxB+3GH;AwB33GC;;EAEE,sBAAA;EACA,8BAAA;EACA,uBAAA;EE3GF,oEAAA;EF6GE,oBAAA;CxB63GH;AwBx3GD;EAGI,eAAA;CxBw3GH;AwB33GD;EAQI,WAAA;CxBs3GH;AwB92GD;EACE,WAAA;EACA,SAAA;CxBg3GD;AwBx2GD;EACE,QAAA;EACA,YAAA;CxB02GD;AwBt2GD;EACE,eAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxBw2GD;AwBp2GD;EACE,gBAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,aAAA;CxBs2GD;AwBl2GD;EACE,SAAA;EACA,WAAA;CxBo2GD;AwB51GD;;EAII,cAAA;EACA,0BAAA;EACA,4BAAA;EACA,YAAA;CxB41GH;AwBn2GD;;EAWI,UAAA;EACA,aAAA;EACA,mBAAA;CxB41GH;AwBv0GD;EAXE;IApEA,WAAA;IACA,SAAA;GxB05GC;EwBv1GD;IA1DA,QAAA;IACA,YAAA;GxBo5GC;CACF;A2BpiHD;;EAEE,mBAAA;EACA,sBAAA;EACA,uBAAA;C3BsiHD;A2B1iHD;;EAMI,mBAAA;EACA,YAAA;C3BwiHH;A2BtiHG;;;;;;;;EAIE,WAAA;C3B4iHL;A2BtiHD;;;;EAKI,kBAAA;C3BuiHH;A2BliHD;EACE,kBAAA;C3BoiHD;A2BriHD;;;EAOI,YAAA;C3BmiHH;A2B1iHD;;;EAYI,iBAAA;C3BmiHH;A2B/hHD;EACE,iBAAA;C3BiiHD;A2B7hHD;EACE,eAAA;C3B+hHD;A2B9hHC;EClDA,8BAAA;EACG,2BAAA;C5BmlHJ;A2B7hHD;;EC/CE,6BAAA;EACG,0BAAA;C5BglHJ;A2B5hHD;EACE,YAAA;C3B8hHD;A2B5hHD;EACE,iBAAA;C3B8hHD;A2B5hHD;;ECnEE,8BAAA;EACG,2BAAA;C5BmmHJ;A2B3hHD;ECjEE,6BAAA;EACG,0BAAA;C5B+lHJ;A2B1hHD;;EAEE,WAAA;C3B4hHD;A2B3gHD;EACE,kBAAA;EACA,mBAAA;C3B6gHD;A2B3gHD;EACE,mBAAA;EACA,oBAAA;C3B6gHD;A2BxgHD;EtB/CE,yDAAA;EACQ,iDAAA;CL0jHT;A2BxgHC;EtBnDA,yBAAA;EACQ,iBAAA;CL8jHT;A2BrgHD;EACE,eAAA;C3BugHD;A2BpgHD;EACE,wBAAA;EACA,uBAAA;C3BsgHD;A2BngHD;EACE,wBAAA;C3BqgHD;A2B9/GD;;;EAII,eAAA;EACA,YAAA;EACA,YAAA;EACA,gBAAA;C3B+/GH;A2BtgHD;EAcM,YAAA;C3B2/GL;A2BzgHD;;;;EAsBI,iBAAA;EACA,eAAA;C3By/GH;A2Bp/GC;EACE,iBAAA;C3Bs/GH;A2Bp/GC;EC3KA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5B4pHF;A2Bt/GC;EC/KA,2BAAA;EACC,0BAAA;EAOD,gCAAA;EACC,+BAAA;C5BkqHF;A2Bv/GD;EACE,iBAAA;C3By/GD;A2Bv/GD;;EC/KE,8BAAA;EACC,6BAAA;C5B0qHF;A2Bt/GD;EC7LE,2BAAA;EACC,0BAAA;C5BsrHF;A2Bl/GD;EACE,eAAA;EACA,YAAA;EACA,oBAAA;EACA,0BAAA;C3Bo/GD;A2Bx/GD;;EAOI,YAAA;EACA,oBAAA;EACA,UAAA;C3Bq/GH;A2B9/GD;EAYI,YAAA;C3Bq/GH;A2BjgHD;EAgBI,WAAA;C3Bo/GH;A2Bn+GD;;;;EAKM,mBAAA;EACA,uBAAA;EACA,qBAAA;C3Bo+GL;A6B9sHD;EACE,mBAAA;EACA,eAAA;EACA,0BAAA;C7BgtHD;A6B7sHC;EACE,YAAA;EACA,gBAAA;EACA,iBAAA;C7B+sHH;A6BxtHD;EAeI,mBAAA;EACA,WAAA;EAKA,YAAA;EAEA,YAAA;EACA,iBAAA;C7BusHH;A6BrsHG;EACE,WAAA;C7BusHL;A6B7rHD;;;EV0BE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBwqHD;AmBtqHC;;;EACE,aAAA;EACA,kBAAA;CnB0qHH;AmBvqHC;;;;;;EAEE,aAAA;CnB6qHH;A6B/sHD;;;EVqBE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnB+rHD;AmB7rHC;;;EACE,aAAA;EACA,kBAAA;CnBisHH;AmB9rHC;;;;;;EAEE,aAAA;CnBosHH;A6B7tHD;;;EAGE,oBAAA;C7B+tHD;A6B7tHC;;;EACE,iBAAA;C7BiuHH;A6B7tHD;;EAEE,UAAA;EACA,oBAAA;EACA,uBAAA;C7B+tHD;A6B1tHD;EACE,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;EACA,eAAA;EACA,mBAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;C7B4tHD;A6BztHC;EACE,kBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6BztHC;EACE,mBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6B/uHD;;EA0BI,cAAA;C7BytHH;A6BptHD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;C5Bi0HJ;A6BrtHD;EACE,gBAAA;C7ButHD;A6BrtHD;;;;;;;EDxGE,6BAAA;EACG,0BAAA;C5Bs0HJ;A6BttHD;EACE,eAAA;C7BwtHD;A6BntHD;EACE,mBAAA;EAGA,aAAA;EACA,oBAAA;C7BmtHD;A6BxtHD;EAUI,mBAAA;C7BitHH;A6B3tHD;EAYM,kBAAA;C7BktHL;A6B/sHG;;;EAGE,WAAA;C7BitHL;A6B5sHC;;EAGI,mBAAA;C7B6sHL;A6B1sHC;;EAGI,WAAA;EACA,kBAAA;C7B2sHL;A8B12HD;EACE,iBAAA;EACA,gBAAA;EACA,iBAAA;C9B42HD;A8B/2HD;EAOI,mBAAA;EACA,eAAA;C9B22HH;A8Bn3HD;EAWM,mBAAA;EACA,eAAA;EACA,mBAAA;C9B22HL;A8B12HK;;EAEE,sBAAA;EACA,0BAAA;C9B42HP;A8Bv2HG;EACE,eAAA;C9By2HL;A8Bv2HK;;EAEE,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,oBAAA;C9By2HP;A8Bl2HG;;;EAGE,0BAAA;EACA,sBAAA;C9Bo2HL;A8B74HD;ELHE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBm5HD;A8Bn5HD;EA0DI,gBAAA;C9B41HH;A8Bn1HD;EACE,8BAAA;C9Bq1HD;A8Bt1HD;EAGI,YAAA;EAEA,oBAAA;C9Bq1HH;A8B11HD;EASM,kBAAA;EACA,wBAAA;EACA,8BAAA;EACA,2BAAA;C9Bo1HL;A8Bn1HK;EACE,mCAAA;C9Bq1HP;A8B/0HK;;;EAGE,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,iCAAA;EACA,gBAAA;C9Bi1HP;A8B50HC;EAqDA,YAAA;EA8BA,iBAAA;C9B6vHD;A8Bh1HC;EAwDE,YAAA;C9B2xHH;A8Bn1HC;EA0DI,mBAAA;EACA,mBAAA;C9B4xHL;A8Bv1HC;EAgEE,UAAA;EACA,WAAA;C9B0xHH;A8B9wHD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9ByxHH;E8BztHH;IA9DQ,iBAAA;G9B0xHL;CACF;A8Bp2HC;EAuFE,gBAAA;EACA,mBAAA;C9BgxHH;A8Bx2HC;;;EA8FE,uBAAA;C9B+wHH;A8BjwHD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9B8wHH;E8B3uHH;;;IA9BM,0BAAA;G9B8wHH;CACF;A8B/2HD;EAEI,YAAA;C9Bg3HH;A8Bl3HD;EAMM,mBAAA;C9B+2HL;A8Br3HD;EASM,iBAAA;C9B+2HL;A8B12HK;;;EAGE,YAAA;EACA,0BAAA;C9B42HP;A8Bp2HD;EAEI,YAAA;C9Bq2HH;A8Bv2HD;EAIM,gBAAA;EACA,eAAA;C9Bs2HL;A8B11HD;EACE,YAAA;C9B41HD;A8B71HD;EAII,YAAA;C9B41HH;A8Bh2HD;EAMM,mBAAA;EACA,mBAAA;C9B61HL;A8Bp2HD;EAYI,UAAA;EACA,WAAA;C9B21HH;A8B/0HD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9B01HH;E8B1xHH;IA9DQ,iBAAA;G9B21HL;CACF;A8Bn1HD;EACE,iBAAA;C9Bq1HD;A8Bt1HD;EAKI,gBAAA;EACA,mBAAA;C9Bo1HH;A8B11HD;;;EAYI,uBAAA;C9Bm1HH;A8Br0HD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9Bk1HH;E8B/yHH;;;IA9BM,0BAAA;G9Bk1HH;CACF;A8Bz0HD;EAEI,cAAA;C9B00HH;A8B50HD;EAKI,eAAA;C9B00HH;A8Bj0HD;EAEE,iBAAA;EF3OA,2BAAA;EACC,0BAAA;C5B8iIF;A+BxiID;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,8BAAA;C/B0iID;A+BliID;EA8nBA;IAhoBI,mBAAA;G/BwiID;CACF;A+BzhID;EAgnBA;IAlnBI,YAAA;G/B+hID;CACF;A+BjhID;EACE,oBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,2DAAA;UAAA,mDAAA;EAEA,kCAAA;C/BkhID;A+BhhIC;EACE,iBAAA;C/BkhIH;A+Bt/HD;EA6jBA;IArlBI,YAAA;IACA,cAAA;IACA,yBAAA;YAAA,iBAAA;G/BkhID;E+BhhIC;IACE,0BAAA;IACA,wBAAA;IACA,kBAAA;IACA,6BAAA;G/BkhIH;E+B/gIC;IACE,oBAAA;G/BihIH;E+B5gIC;;;IAGE,gBAAA;IACA,iBAAA;G/B8gIH;CACF;A+B1gID;;EAGI,kBAAA;C/B2gIH;A+BtgIC;EAmjBF;;IArjBM,kBAAA;G/B6gIH;CACF;A+BpgID;;;;EAII,oBAAA;EACA,mBAAA;C/BsgIH;A+BhgIC;EAgiBF;;;;IAniBM,gBAAA;IACA,eAAA;G/B0gIH;CACF;A+B9/HD;EACE,cAAA;EACA,sBAAA;C/BggID;A+B3/HD;EA8gBA;IAhhBI,iBAAA;G/BigID;CACF;A+B7/HD;;EAEE,gBAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;C/B+/HD;A+Bz/HD;EAggBA;;IAlgBI,iBAAA;G/BggID;CACF;A+B9/HD;EACE,OAAA;EACA,sBAAA;C/BggID;A+B9/HD;EACE,UAAA;EACA,iBAAA;EACA,sBAAA;C/BggID;A+B1/HD;EACE,YAAA;EACA,mBAAA;EACA,gBAAA;EACA,kBAAA;EACA,aAAA;C/B4/HD;A+B1/HC;;EAEE,sBAAA;C/B4/HH;A+BrgID;EAaI,eAAA;C/B2/HH;A+Bl/HD;EALI;;IAEE,mBAAA;G/B0/HH;CACF;A+Bh/HD;EACE,mBAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;EC9LA,gBAAA;EACA,mBAAA;ED+LA,8BAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;C/Bm/HD;A+B/+HC;EACE,WAAA;C/Bi/HH;A+B//HD;EAmBI,eAAA;EACA,YAAA;EACA,YAAA;EACA,mBAAA;C/B++HH;A+BrgID;EAyBI,gBAAA;C/B++HH;A+Bz+HD;EAqbA;IAvbI,cAAA;G/B++HD;CACF;A+Bt+HD;EACE,oBAAA;C/Bw+HD;A+Bz+HD;EAII,kBAAA;EACA,qBAAA;EACA,kBAAA;C/Bw+HH;A+B58HC;EA2YF;IAjaM,iBAAA;IACA,YAAA;IACA,YAAA;IACA,cAAA;IACA,8BAAA;IACA,UAAA;IACA,yBAAA;YAAA,iBAAA;G/Bs+HH;E+B3kHH;;IAxZQ,2BAAA;G/Bu+HL;E+B/kHH;IArZQ,kBAAA;G/Bu+HL;E+Bt+HK;;IAEE,uBAAA;G/Bw+HP;CACF;A+Bt9HD;EA+XA;IA1YI,YAAA;IACA,UAAA;G/Bq+HD;E+B5lHH;IAtYM,YAAA;G/Bq+HH;E+B/lHH;IApYQ,kBAAA;IACA,qBAAA;G/Bs+HL;CACF;A+B39HD;EACE,mBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,qCAAA;E1B9NA,6FAAA;EACQ,qFAAA;E2B/DR,gBAAA;EACA,mBAAA;ChC4vID;AkBtuHD;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBwyHH;EkBpqHH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBsyHH;EkBzqHH;IAxHM,sBAAA;GlBoyHH;EkB5qHH;IApHM,sBAAA;IACA,uBAAA;GlBmyHH;EkBhrHH;;;IA9GQ,YAAA;GlBmyHL;EkBrrHH;IAxGM,YAAA;GlBgyHH;EkBxrHH;IApGM,iBAAA;IACA,uBAAA;GlB+xHH;EkB5rHH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB4xHH;EkBnsHH;;IAtFQ,gBAAA;GlB6xHL;EkBvsHH;;IAjFM,mBAAA;IACA,eAAA;GlB4xHH;EkB5sHH;IA3EM,OAAA;GlB0xHH;CACF;A+BpgIC;EAmWF;IAzWM,mBAAA;G/B8gIH;E+B5gIG;IACE,iBAAA;G/B8gIL;CACF;A+B7/HD;EAoVA;IA5VI,YAAA;IACA,UAAA;IACA,eAAA;IACA,gBAAA;IACA,eAAA;IACA,kBAAA;I1BzPF,yBAAA;IACQ,iBAAA;GLmwIP;CACF;A+BngID;EACE,cAAA;EHpUA,2BAAA;EACC,0BAAA;C5B00IF;A+BngID;EACE,iBAAA;EHzUA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5By0IF;A+B//HD;EChVE,gBAAA;EACA,mBAAA;ChCk1ID;A+BhgIC;ECnVA,iBAAA;EACA,oBAAA;ChCs1ID;A+BjgIC;ECtVA,iBAAA;EACA,oBAAA;ChC01ID;A+B3/HD;EChWE,iBAAA;EACA,oBAAA;ChC81ID;A+Bv/HD;EAsSA;IA1SI,YAAA;IACA,kBAAA;IACA,mBAAA;G/B+/HD;CACF;A+Bl+HD;EAhBE;IExWA,uBAAA;GjC81IC;E+Br/HD;IE5WA,wBAAA;IF8WE,oBAAA;G/Bu/HD;E+Bz/HD;IAKI,gBAAA;G/Bu/HH;CACF;A+B9+HD;EACE,0BAAA;EACA,sBAAA;C/Bg/HD;A+Bl/HD;EAKI,YAAA;C/Bg/HH;A+B/+HG;;EAEE,eAAA;EACA,8BAAA;C/Bi/HL;A+B1/HD;EAcI,YAAA;C/B++HH;A+B7/HD;EAmBM,YAAA;C/B6+HL;A+B3+HK;;EAEE,YAAA;EACA,8BAAA;C/B6+HP;A+Bz+HK;;;EAGE,YAAA;EACA,0BAAA;C/B2+HP;A+Bv+HK;;;EAGE,YAAA;EACA,8BAAA;C/By+HP;A+BjhID;EA8CI,mBAAA;C/Bs+HH;A+Br+HG;;EAEE,uBAAA;C/Bu+HL;A+BxhID;EAoDM,uBAAA;C/Bu+HL;A+B3hID;;EA0DI,sBAAA;C/Bq+HH;A+B99HK;;;EAGE,0BAAA;EACA,YAAA;C/Bg+HP;A+B/7HC;EAoKF;IA7LU,YAAA;G/B49HP;E+B39HO;;IAEE,YAAA;IACA,8BAAA;G/B69HT;E+Bz9HO;;;IAGE,YAAA;IACA,0BAAA;G/B29HT;E+Bv9HO;;;IAGE,YAAA;IACA,8BAAA;G/By9HT;CACF;A+B3jID;EA8GI,YAAA;C/Bg9HH;A+B/8HG;EACE,YAAA;C/Bi9HL;A+BjkID;EAqHI,YAAA;C/B+8HH;A+B98HG;;EAEE,YAAA;C/Bg9HL;A+B58HK;;;;EAEE,YAAA;C/Bg9HP;A+Bx8HD;EACE,uBAAA;EACA,sBAAA;C/B08HD;A+B58HD;EAKI,eAAA;C/B08HH;A+Bz8HG;;EAEE,YAAA;EACA,8BAAA;C/B28HL;A+Bp9HD;EAcI,eAAA;C/By8HH;A+Bv9HD;EAmBM,eAAA;C/Bu8HL;A+Br8HK;;EAEE,YAAA;EACA,8BAAA;C/Bu8HP;A+Bn8HK;;;EAGE,YAAA;EACA,0BAAA;C/Bq8HP;A+Bj8HK;;;EAGE,YAAA;EACA,8BAAA;C/Bm8HP;A+B3+HD;EA+CI,mBAAA;C/B+7HH;A+B97HG;;EAEE,uBAAA;C/Bg8HL;A+Bl/HD;EAqDM,uBAAA;C/Bg8HL;A+Br/HD;;EA2DI,sBAAA;C/B87HH;A+Bx7HK;;;EAGE,0BAAA;EACA,YAAA;C/B07HP;A+Bn5HC;EAwBF;IAvDU,sBAAA;G/Bs7HP;E+B/3HH;IApDU,0BAAA;G/Bs7HP;E+Bl4HH;IAjDU,eAAA;G/Bs7HP;E+Br7HO;;IAEE,YAAA;IACA,8BAAA;G/Bu7HT;E+Bn7HO;;;IAGE,YAAA;IACA,0BAAA;G/Bq7HT;E+Bj7HO;;;IAGE,YAAA;IACA,8BAAA;G/Bm7HT;CACF;A+B3hID;EA+GI,eAAA;C/B+6HH;A+B96HG;EACE,YAAA;C/Bg7HL;A+BjiID;EAsHI,eAAA;C/B86HH;A+B76HG;;EAEE,YAAA;C/B+6HL;A+B36HK;;;;EAEE,YAAA;C/B+6HP;AkCzjJD;EACE,kBAAA;EACA,oBAAA;EACA,iBAAA;EACA,0BAAA;EACA,mBAAA;ClC2jJD;AkChkJD;EAQI,sBAAA;ClC2jJH;AkCnkJD;EAWM,kBAAA;EACA,eAAA;EACA,YAAA;ClC2jJL;AkCxkJD;EAkBI,eAAA;ClCyjJH;AmC7kJD;EACE,sBAAA;EACA,gBAAA;EACA,eAAA;EACA,mBAAA;CnC+kJD;AmCnlJD;EAOI,gBAAA;CnC+kJH;AmCtlJD;;EAUM,mBAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,sBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,kBAAA;CnCglJL;AmC9kJG;;EAGI,eAAA;EPXN,+BAAA;EACG,4BAAA;C5B2lJJ;AmC7kJG;;EPvBF,gCAAA;EACG,6BAAA;C5BwmJJ;AmCxkJG;;;;EAEE,WAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CnC4kJL;AmCtkJG;;;;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;EACA,gBAAA;CnC2kJL;AmCloJD;;;;;;EAkEM,eAAA;EACA,uBAAA;EACA,mBAAA;EACA,oBAAA;CnCwkJL;AmC/jJD;;EC3EM,mBAAA;EACA,gBAAA;EACA,uBAAA;CpC8oJL;AoC5oJG;;ERKF,+BAAA;EACG,4BAAA;C5B2oJJ;AoC3oJG;;ERTF,gCAAA;EACG,6BAAA;C5BwpJJ;AmC1kJD;;EChFM,kBAAA;EACA,gBAAA;EACA,iBAAA;CpC8pJL;AoC5pJG;;ERKF,+BAAA;EACG,4BAAA;C5B2pJJ;AoC3pJG;;ERTF,gCAAA;EACG,6BAAA;C5BwqJJ;AqC3qJD;EACE,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,mBAAA;CrC6qJD;AqCjrJD;EAOI,gBAAA;CrC6qJH;AqCprJD;;EAUM,sBAAA;EACA,kBAAA;EACA,uBAAA;EACA,uBAAA;EACA,oBAAA;CrC8qJL;AqC5rJD;;EAmBM,sBAAA;EACA,0BAAA;CrC6qJL;AqCjsJD;;EA2BM,aAAA;CrC0qJL;AqCrsJD;;EAkCM,YAAA;CrCuqJL;AqCzsJD;;;;EA2CM,eAAA;EACA,uBAAA;EACA,oBAAA;CrCoqJL;AsCltJD;EACE,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,mBAAA;EACA,oBAAA;EACA,yBAAA;EACA,qBAAA;CtCotJD;AsChtJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CtCktJL;AsC7sJC;EACE,cAAA;CtC+sJH;AsC3sJC;EACE,mBAAA;EACA,UAAA;CtC6sJH;AsCtsJD;ECtCE,0BAAA;CvC+uJD;AuC5uJG;;EAEE,0BAAA;CvC8uJL;AsCzsJD;EC1CE,0BAAA;CvCsvJD;AuCnvJG;;EAEE,0BAAA;CvCqvJL;AsC5sJD;EC9CE,0BAAA;CvC6vJD;AuC1vJG;;EAEE,0BAAA;CvC4vJL;AsC/sJD;EClDE,0BAAA;CvCowJD;AuCjwJG;;EAEE,0BAAA;CvCmwJL;AsCltJD;ECtDE,0BAAA;CvC2wJD;AuCxwJG;;EAEE,0BAAA;CvC0wJL;AsCrtJD;EC1DE,0BAAA;CvCkxJD;AuC/wJG;;EAEE,0BAAA;CvCixJL;AwCnxJD;EACE,sBAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,eAAA;EACA,uBAAA;EACA,oBAAA;EACA,mBAAA;EACA,0BAAA;EACA,oBAAA;CxCqxJD;AwClxJC;EACE,cAAA;CxCoxJH;AwChxJC;EACE,mBAAA;EACA,UAAA;CxCkxJH;AwC/wJC;;EAEE,OAAA;EACA,iBAAA;CxCixJH;AwC5wJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CxC8wJL;AwCzwJC;;EAEE,eAAA;EACA,uBAAA;CxC2wJH;AwCxwJC;EACE,aAAA;CxC0wJH;AwCvwJC;EACE,kBAAA;CxCywJH;AwCtwJC;EACE,iBAAA;CxCwwJH;AyCl0JD;EACE,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,eAAA;EACA,0BAAA;CzCo0JD;AyCz0JD;;EASI,eAAA;CzCo0JH;AyC70JD;EAaI,oBAAA;EACA,gBAAA;EACA,iBAAA;CzCm0JH;AyCl1JD;EAmBI,0BAAA;CzCk0JH;AyC/zJC;;EAEE,mBAAA;EACA,mBAAA;EACA,oBAAA;CzCi0JH;AyC31JD;EA8BI,gBAAA;CzCg0JH;AyC9yJD;EACA;IAfI,kBAAA;IACA,qBAAA;GzCg0JD;EyC9zJC;;IAEE,mBAAA;IACA,oBAAA;GzCg0JH;EyCvzJH;;IAJM,gBAAA;GzC+zJH;CACF;A0C52JD;EACE,eAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;ErCiLA,4CAAA;EACK,uCAAA;EACG,oCAAA;CL8rJT;A0Cx3JD;;EAaI,kBAAA;EACA,mBAAA;C1C+2JH;A0C32JC;;;EAGE,sBAAA;C1C62JH;A0Cl4JD;EA0BI,aAAA;EACA,eAAA;C1C22JH;A2Cp4JD;EACE,cAAA;EACA,oBAAA;EACA,8BAAA;EACA,mBAAA;C3Cs4JD;A2C14JD;EAQI,cAAA;EAEA,eAAA;C3Co4JH;A2C94JD;EAeI,kBAAA;C3Ck4JH;A2Cj5JD;;EAqBI,iBAAA;C3Cg4JH;A2Cr5JD;EAyBI,gBAAA;C3C+3JH;A2Cv3JD;;EAEE,oBAAA;C3Cy3JD;A2C33JD;;EAMI,mBAAA;EACA,UAAA;EACA,aAAA;EACA,eAAA;C3Cy3JH;A2Cj3JD;ECvDE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C26JD;A2Ct3JD;EClDI,0BAAA;C5C26JH;A2Cz3JD;EC/CI,eAAA;C5C26JH;A2Cx3JD;EC3DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Cs7JD;A2C73JD;ECtDI,0BAAA;C5Cs7JH;A2Ch4JD;ECnDI,eAAA;C5Cs7JH;A2C/3JD;EC/DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Ci8JD;A2Cp4JD;EC1DI,0BAAA;C5Ci8JH;A2Cv4JD;ECvDI,eAAA;C5Ci8JH;A2Ct4JD;ECnEE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C48JD;A2C34JD;EC9DI,0BAAA;C5C48JH;A2C94JD;EC3DI,eAAA;C5C48JH;A6C98JD;EACE;IAAQ,4BAAA;G7Ci9JP;E6Ch9JD;IAAQ,yBAAA;G7Cm9JP;CACF;A6Ch9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6Cx9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6C98JD;EACE,iBAAA;EACA,aAAA;EACA,oBAAA;EACA,0BAAA;EACA,mBAAA;ExCsCA,uDAAA;EACQ,+CAAA;CL26JT;A6C78JD;EACE,YAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,mBAAA;EACA,0BAAA;ExCyBA,uDAAA;EACQ,+CAAA;EAyHR,oCAAA;EACK,+BAAA;EACG,4BAAA;CL+zJT;A6C18JD;;ECCI,8MAAA;EACA,yMAAA;EACA,sMAAA;EDAF,mCAAA;UAAA,2BAAA;C7C88JD;A6Cv8JD;;ExC5CE,2DAAA;EACK,sDAAA;EACG,mDAAA;CLu/JT;A6Cp8JD;EErEE,0BAAA;C/C4gKD;A+CzgKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C49JH;A6Cx8JD;EEzEE,0BAAA;C/CohKD;A+CjhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co+JH;A6C58JD;EE7EE,0BAAA;C/C4hKD;A+CzhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C4+JH;A6Ch9JD;EEjFE,0BAAA;C/CoiKD;A+CjiKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co/JH;AgD5iKD;EAEE,iBAAA;ChD6iKD;AgD3iKC;EACE,cAAA;ChD6iKH;AgDziKD;;EAEE,QAAA;EACA,iBAAA;ChD2iKD;AgDxiKD;EACE,eAAA;ChD0iKD;AgDviKD;EACE,eAAA;ChDyiKD;AgDtiKC;EACE,gBAAA;ChDwiKH;AgDpiKD;;EAEE,mBAAA;ChDsiKD;AgDniKD;;EAEE,oBAAA;ChDqiKD;AgDliKD;;;EAGE,oBAAA;EACA,oBAAA;ChDoiKD;AgDjiKD;EACE,uBAAA;ChDmiKD;AgDhiKD;EACE,uBAAA;ChDkiKD;AgD9hKD;EACE,cAAA;EACA,mBAAA;ChDgiKD;AgD1hKD;EACE,gBAAA;EACA,iBAAA;ChD4hKD;AiDnlKD;EAEE,oBAAA;EACA,gBAAA;CjDolKD;AiD5kKD;EACE,mBAAA;EACA,eAAA;EACA,mBAAA;EAEA,oBAAA;EACA,uBAAA;EACA,uBAAA;CjD6kKD;AiD1kKC;ErB3BA,6BAAA;EACC,4BAAA;C5BwmKF;AiD3kKC;EACE,iBAAA;ErBvBF,gCAAA;EACC,+BAAA;C5BqmKF;AiDpkKD;;EAEE,YAAA;CjDskKD;AiDxkKD;;EAKI,YAAA;CjDukKH;AiDnkKC;;;;EAEE,sBAAA;EACA,YAAA;EACA,0BAAA;CjDukKH;AiDnkKD;EACE,YAAA;EACA,iBAAA;CjDqkKD;AiDhkKC;;;EAGE,0BAAA;EACA,eAAA;EACA,oBAAA;CjDkkKH;AiDvkKC;;;EASI,eAAA;CjDmkKL;AiD5kKC;;;EAYI,eAAA;CjDqkKL;AiDhkKC;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;CjDkkKH;AiDxkKC;;;;;;;;;EAYI,eAAA;CjDukKL;AiDnlKC;;;EAeI,eAAA;CjDykKL;AkD3qKC;EACE,eAAA;EACA,0BAAA;ClD6qKH;AkD3qKG;;EAEE,eAAA;ClD6qKL;AkD/qKG;;EAKI,eAAA;ClD8qKP;AkD3qKK;;;;EAEE,eAAA;EACA,0BAAA;ClD+qKP;AkD7qKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDkrKP;AkDxsKC;EACE,eAAA;EACA,0BAAA;ClD0sKH;AkDxsKG;;EAEE,eAAA;ClD0sKL;AkD5sKG;;EAKI,eAAA;ClD2sKP;AkDxsKK;;;;EAEE,eAAA;EACA,0BAAA;ClD4sKP;AkD1sKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD+sKP;AkDruKC;EACE,eAAA;EACA,0BAAA;ClDuuKH;AkDruKG;;EAEE,eAAA;ClDuuKL;AkDzuKG;;EAKI,eAAA;ClDwuKP;AkDruKK;;;;EAEE,eAAA;EACA,0BAAA;ClDyuKP;AkDvuKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD4uKP;AkDlwKC;EACE,eAAA;EACA,0BAAA;ClDowKH;AkDlwKG;;EAEE,eAAA;ClDowKL;AkDtwKG;;EAKI,eAAA;ClDqwKP;AkDlwKK;;;;EAEE,eAAA;EACA,0BAAA;ClDswKP;AkDpwKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDywKP;AiDxqKD;EACE,cAAA;EACA,mBAAA;CjD0qKD;AiDxqKD;EACE,iBAAA;EACA,iBAAA;CjD0qKD;AmDpyKD;EACE,oBAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;E9C0DA,kDAAA;EACQ,0CAAA;CL6uKT;AmDnyKD;EACE,cAAA;CnDqyKD;AmDhyKD;EACE,mBAAA;EACA,qCAAA;EvBpBA,6BAAA;EACC,4BAAA;C5BuzKF;AmDtyKD;EAMI,eAAA;CnDmyKH;AmD9xKD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;CnDgyKD;AmDpyKD;;;;;EAWI,eAAA;CnDgyKH;AmD3xKD;EACE,mBAAA;EACA,0BAAA;EACA,2BAAA;EvBxCA,gCAAA;EACC,+BAAA;C5Bs0KF;AmDrxKD;;EAGI,iBAAA;CnDsxKH;AmDzxKD;;EAMM,oBAAA;EACA,iBAAA;CnDuxKL;AmDnxKG;;EAEI,cAAA;EvBvEN,6BAAA;EACC,4BAAA;C5B61KF;AmDjxKG;;EAEI,iBAAA;EvBvEN,gCAAA;EACC,+BAAA;C5B21KF;AmD1yKD;EvB1DE,2BAAA;EACC,0BAAA;C5Bu2KF;AmD7wKD;EAEI,oBAAA;CnD8wKH;AmD3wKD;EACE,oBAAA;CnD6wKD;AmDrwKD;;;EAII,iBAAA;CnDswKH;AmD1wKD;;;EAOM,mBAAA;EACA,oBAAA;CnDwwKL;AmDhxKD;;EvBzGE,6BAAA;EACC,4BAAA;C5B63KF;AmDrxKD;;;;EAmBQ,4BAAA;EACA,6BAAA;CnDwwKP;AmD5xKD;;;;;;;;EAwBU,4BAAA;CnD8wKT;AmDtyKD;;;;;;;;EA4BU,6BAAA;CnDoxKT;AmDhzKD;;EvBjGE,gCAAA;EACC,+BAAA;C5Bq5KF;AmDrzKD;;;;EAyCQ,+BAAA;EACA,gCAAA;CnDkxKP;AmD5zKD;;;;;;;;EA8CU,+BAAA;CnDwxKT;AmDt0KD;;;;;;;;EAkDU,gCAAA;CnD8xKT;AmDh1KD;;;;EA2DI,2BAAA;CnD2xKH;AmDt1KD;;EA+DI,cAAA;CnD2xKH;AmD11KD;;EAmEI,UAAA;CnD2xKH;AmD91KD;;;;;;;;;;;;EA0EU,eAAA;CnDkyKT;AmD52KD;;;;;;;;;;;;EA8EU,gBAAA;CnD4yKT;AmD13KD;;;;;;;;EAuFU,iBAAA;CnD6yKT;AmDp4KD;;;;;;;;EAgGU,iBAAA;CnD8yKT;AmD94KD;EAsGI,UAAA;EACA,iBAAA;CnD2yKH;AmDjyKD;EACE,oBAAA;CnDmyKD;AmDpyKD;EAKI,iBAAA;EACA,mBAAA;CnDkyKH;AmDxyKD;EASM,gBAAA;CnDkyKL;AmD3yKD;EAcI,iBAAA;CnDgyKH;AmD9yKD;;EAkBM,2BAAA;CnDgyKL;AmDlzKD;EAuBI,cAAA;CnD8xKH;AmDrzKD;EAyBM,8BAAA;CnD+xKL;AmDxxKD;EC1PE,mBAAA;CpDqhLD;AoDnhLC;EACE,eAAA;EACA,0BAAA;EACA,mBAAA;CpDqhLH;AoDxhLC;EAMI,uBAAA;CpDqhLL;AoD3hLC;EASI,eAAA;EACA,0BAAA;CpDqhLL;AoDlhLC;EAEI,0BAAA;CpDmhLL;AmDvyKD;EC7PE,sBAAA;CpDuiLD;AoDriLC;EACE,YAAA;EACA,0BAAA;EACA,sBAAA;CpDuiLH;AoD1iLC;EAMI,0BAAA;CpDuiLL;AoD7iLC;EASI,eAAA;EACA,uBAAA;CpDuiLL;AoDpiLC;EAEI,6BAAA;CpDqiLL;AmDtzKD;EChQE,sBAAA;CpDyjLD;AoDvjLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpDyjLH;AoD5jLC;EAMI,0BAAA;CpDyjLL;AoD/jLC;EASI,eAAA;EACA,0BAAA;CpDyjLL;AoDtjLC;EAEI,6BAAA;CpDujLL;AmDr0KD;ECnQE,sBAAA;CpD2kLD;AoDzkLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD2kLH;AoD9kLC;EAMI,0BAAA;CpD2kLL;AoDjlLC;EASI,eAAA;EACA,0BAAA;CpD2kLL;AoDxkLC;EAEI,6BAAA;CpDykLL;AmDp1KD;ECtQE,sBAAA;CpD6lLD;AoD3lLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD6lLH;AoDhmLC;EAMI,0BAAA;CpD6lLL;AoDnmLC;EASI,eAAA;EACA,0BAAA;CpD6lLL;AoD1lLC;EAEI,6BAAA;CpD2lLL;AmDn2KD;ECzQE,sBAAA;CpD+mLD;AoD7mLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD+mLH;AoDlnLC;EAMI,0BAAA;CpD+mLL;AoDrnLC;EASI,eAAA;EACA,0BAAA;CpD+mLL;AoD5mLC;EAEI,6BAAA;CpD6mLL;AqD7nLD;EACE,mBAAA;EACA,eAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;CrD+nLD;AqDpoLD;;;;;EAYI,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;CrD+nLH;AqD1nLD;EACE,uBAAA;CrD4nLD;AqDxnLD;EACE,oBAAA;CrD0nLD;AsDrpLD;EACE,iBAAA;EACA,cAAA;EACA,oBAAA;EACA,0BAAA;EACA,0BAAA;EACA,mBAAA;EjDwDA,wDAAA;EACQ,gDAAA;CLgmLT;AsD/pLD;EASI,mBAAA;EACA,kCAAA;CtDypLH;AsDppLD;EACE,cAAA;EACA,mBAAA;CtDspLD;AsDppLD;EACE,aAAA;EACA,mBAAA;CtDspLD;AuD5qLD;EACE,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,0BAAA;EjCRA,aAAA;EAGA,0BAAA;CtBqrLD;AuD7qLC;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;EjCfF,aAAA;EAGA,0BAAA;CtB6rLD;AuDzqLC;EACE,WAAA;EACA,gBAAA;EACA,wBAAA;EACA,UAAA;EACA,yBAAA;CvD2qLH;AwDhsLD;EACE,iBAAA;CxDksLD;AwD9rLD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,kCAAA;EAIA,WAAA;CxD6rLD;AwD1rLC;EnD+GA,sCAAA;EACI,kCAAA;EACC,iCAAA;EACG,8BAAA;EAkER,oDAAA;EAEK,0CAAA;EACG,oCAAA;CL6gLT;AwDhsLC;EnD2GA,mCAAA;EACI,+BAAA;EACC,8BAAA;EACG,2BAAA;CLwlLT;AwDpsLD;EACE,mBAAA;EACA,iBAAA;CxDssLD;AwDlsLD;EACE,mBAAA;EACA,YAAA;EACA,aAAA;CxDosLD;AwDhsLD;EACE,mBAAA;EACA,uBAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EnDaA,iDAAA;EACQ,yCAAA;EmDZR,qCAAA;UAAA,6BAAA;EAEA,WAAA;CxDksLD;AwD9rLD;EACE,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,uBAAA;CxDgsLD;AwD9rLC;ElCrEA,WAAA;EAGA,yBAAA;CtBowLD;AwDjsLC;ElCtEA,aAAA;EAGA,0BAAA;CtBwwLD;AwDhsLD;EACE,cAAA;EACA,iCAAA;CxDksLD;AwD9rLD;EACE,iBAAA;CxDgsLD;AwD5rLD;EACE,UAAA;EACA,wBAAA;CxD8rLD;AwDzrLD;EACE,mBAAA;EACA,cAAA;CxD2rLD;AwDvrLD;EACE,cAAA;EACA,kBAAA;EACA,8BAAA;CxDyrLD;AwD5rLD;EAQI,iBAAA;EACA,iBAAA;CxDurLH;AwDhsLD;EAaI,kBAAA;CxDsrLH;AwDnsLD;EAiBI,eAAA;CxDqrLH;AwDhrLD;EACE,mBAAA;EACA,aAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;CxDkrLD;AwDhqLD;EAZE;IACE,aAAA;IACA,kBAAA;GxD+qLD;EwD7qLD;InDvEA,kDAAA;IACQ,0CAAA;GLuvLP;EwD5qLD;IAAY,aAAA;GxD+qLX;CACF;AwD1qLD;EAFE;IAAY,aAAA;GxDgrLX;CACF;AyD/zLD;EACE,mBAAA;EACA,cAAA;EACA,eAAA;ECRA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;EDHA,gBAAA;EnCVA,WAAA;EAGA,yBAAA;CtBs1LD;AyD30LC;EnCdA,aAAA;EAGA,0BAAA;CtB01LD;AyD90LC;EAAW,iBAAA;EAAmB,eAAA;CzDk1L/B;AyDj1LC;EAAW,iBAAA;EAAmB,eAAA;CzDq1L/B;AyDp1LC;EAAW,gBAAA;EAAmB,eAAA;CzDw1L/B;AyDv1LC;EAAW,kBAAA;EAAmB,eAAA;CzD21L/B;AyDv1LD;EACE,iBAAA;EACA,iBAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,mBAAA;CzDy1LD;AyDr1LD;EACE,mBAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;CzDu1LD;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,QAAA;EACA,iBAAA;EACA,4BAAA;EACA,yBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,SAAA;EACA,iBAAA;EACA,4BAAA;EACA,wBAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,WAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;A2Dl7LD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EDXA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;ECAA,gBAAA;EAEA,uBAAA;EACA,qCAAA;UAAA,6BAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EtD8CA,kDAAA;EACQ,0CAAA;CLk5LT;A2D77LC;EAAY,kBAAA;C3Dg8Lb;A2D/7LC;EAAY,kBAAA;C3Dk8Lb;A2Dj8LC;EAAY,iBAAA;C3Do8Lb;A2Dn8LC;EAAY,mBAAA;C3Ds8Lb;A2Dn8LD;EACE,UAAA;EACA,kBAAA;EACA,gBAAA;EACA,0BAAA;EACA,iCAAA;EACA,2BAAA;C3Dq8LD;A2Dl8LD;EACE,kBAAA;C3Do8LD;A2D57LC;;EAEE,mBAAA;EACA,eAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;C3D87LH;A2D37LD;EACE,mBAAA;C3D67LD;A2D37LD;EACE,mBAAA;EACA,YAAA;C3D67LD;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,0BAAA;EACA,sCAAA;EACA,cAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,uBAAA;C3D47LL;A2Dz7LC;EACE,SAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,4BAAA;EACA,wCAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,UAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;C3D47LL;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,oBAAA;EACA,6BAAA;EACA,yCAAA;EACA,WAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,SAAA;EACA,mBAAA;EACA,oBAAA;EACA,0BAAA;C3D47LL;A2Dx7LC;EACE,SAAA;EACA,aAAA;EACA,kBAAA;EACA,sBAAA;EACA,2BAAA;EACA,uCAAA;C3D07LH;A2Dz7LG;EACE,aAAA;EACA,WAAA;EACA,sBAAA;EACA,wBAAA;EACA,cAAA;C3D27LL;A4DpjMD;EACE,mBAAA;C5DsjMD;A4DnjMD;EACE,mBAAA;EACA,iBAAA;EACA,YAAA;C5DqjMD;A4DxjMD;EAMI,cAAA;EACA,mBAAA;EvD6KF,0CAAA;EACK,qCAAA;EACG,kCAAA;CLy4LT;A4D/jMD;;EAcM,eAAA;C5DqjML;A4D3hMC;EA4NF;IvD3DE,uDAAA;IAEK,6CAAA;IACG,uCAAA;IA7JR,oCAAA;IAEQ,4BAAA;IA+GR,4BAAA;IAEQ,oBAAA;GL86LP;E4DzjMG;;IvDmHJ,2CAAA;IACQ,mCAAA;IuDjHF,QAAA;G5D4jML;E4D1jMG;;IvD8GJ,4CAAA;IACQ,oCAAA;IuD5GF,QAAA;G5D6jML;E4D3jMG;;;IvDyGJ,wCAAA;IACQ,gCAAA;IuDtGF,QAAA;G5D8jML;CACF;A4DpmMD;;;EA6CI,eAAA;C5D4jMH;A4DzmMD;EAiDI,QAAA;C5D2jMH;A4D5mMD;;EAsDI,mBAAA;EACA,OAAA;EACA,YAAA;C5D0jMH;A4DlnMD;EA4DI,WAAA;C5DyjMH;A4DrnMD;EA+DI,YAAA;C5DyjMH;A4DxnMD;;EAmEI,QAAA;C5DyjMH;A4D5nMD;EAuEI,YAAA;C5DwjMH;A4D/nMD;EA0EI,WAAA;C5DwjMH;A4DhjMD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EtC9FA,aAAA;EAGA,0BAAA;EsC6FA,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;EACA,mCAAA;C5DmjMD;A4D9iMC;EdnGE,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9CopMH;A4DljMC;EACE,WAAA;EACA,SAAA;EdxGA,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9C6pMH;A4DpjMC;;EAEE,WAAA;EACA,YAAA;EACA,sBAAA;EtCvHF,aAAA;EAGA,0BAAA;CtB4qMD;A4DtlMD;;;;EAuCI,mBAAA;EACA,SAAA;EACA,kBAAA;EACA,WAAA;EACA,sBAAA;C5DqjMH;A4DhmMD;;EA+CI,UAAA;EACA,mBAAA;C5DqjMH;A4DrmMD;;EAoDI,WAAA;EACA,oBAAA;C5DqjMH;A4D1mMD;;EAyDI,YAAA;EACA,aAAA;EACA,eAAA;EACA,mBAAA;C5DqjMH;A4DhjMG;EACE,iBAAA;C5DkjML;A4D9iMG;EACE,iBAAA;C5DgjML;A4DtiMD;EACE,mBAAA;EACA,aAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;C5DwiMD;A4DjjMD;EAYI,sBAAA;EACA,YAAA;EACA,aAAA;EACA,YAAA;EACA,oBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;EAWA,0BAAA;EACA,mCAAA;C5D8hMH;A4D7jMD;EAkCI,UAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;C5D8hMH;A4DvhMD;EACE,mBAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;C5DyhMD;A4DxhMC;EACE,kBAAA;C5D0hMH;A4Dj/LD;EAhCE;;;;IAKI,YAAA;IACA,aAAA;IACA,kBAAA;IACA,gBAAA;G5DmhMH;E4D3hMD;;IAYI,mBAAA;G5DmhMH;E4D/hMD;;IAgBI,oBAAA;G5DmhMH;E4D9gMD;IACE,UAAA;IACA,WAAA;IACA,qBAAA;G5DghMD;E4D5gMD;IACE,aAAA;G5D8gMD;CACF;A6D7wMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,aAAA;EACA,eAAA;C7D6yMH;A6D3yMC;;;;;;;;;;;;;;;;EACE,YAAA;C7D4zMH;AiCp0MD;E6BRE,eAAA;EACA,kBAAA;EACA,mBAAA;C9D+0MD;AiCt0MD;EACE,wBAAA;CjCw0MD;AiCt0MD;EACE,uBAAA;CjCw0MD;AiCh0MD;EACE,yBAAA;CjCk0MD;AiCh0MD;EACE,0BAAA;CjCk0MD;AiCh0MD;EACE,mBAAA;CjCk0MD;AiCh0MD;E8BzBE,YAAA;EACA,mBAAA;EACA,kBAAA;EACA,8BAAA;EACA,UAAA;C/D41MD;AiC9zMD;EACE,yBAAA;CjCg0MD;AiCzzMD;EACE,gBAAA;CjC2zMD;AgE51MD;EACE,oBAAA;ChE81MD;AgEx1MD;;;;ECdE,yBAAA;CjE42MD;AgEv1MD;;;;;;;;;;;;EAYE,yBAAA;ChEy1MD;AgEl1MD;EA6IA;IC7LE,0BAAA;GjEs4MC;EiEr4MD;IAAU,0BAAA;GjEw4MT;EiEv4MD;IAAU,8BAAA;GjE04MT;EiEz4MD;;IACU,+BAAA;GjE44MT;CACF;AgE51MD;EAwIA;IA1II,0BAAA;GhEk2MD;CACF;AgE51MD;EAmIA;IArII,2BAAA;GhEk2MD;CACF;AgE51MD;EA8HA;IAhII,iCAAA;GhEk2MD;CACF;AgE31MD;EAwHA;IC7LE,0BAAA;GjEo6MC;EiEn6MD;IAAU,0BAAA;GjEs6MT;EiEr6MD;IAAU,8BAAA;GjEw6MT;EiEv6MD;;IACU,+BAAA;GjE06MT;CACF;AgEr2MD;EAmHA;IArHI,0BAAA;GhE22MD;CACF;AgEr2MD;EA8GA;IAhHI,2BAAA;GhE22MD;CACF;AgEr2MD;EAyGA;IA3GI,iCAAA;GhE22MD;CACF;AgEp2MD;EAmGA;IC7LE,0BAAA;GjEk8MC;EiEj8MD;IAAU,0BAAA;GjEo8MT;EiEn8MD;IAAU,8BAAA;GjEs8MT;EiEr8MD;;IACU,+BAAA;GjEw8MT;CACF;AgE92MD;EA8FA;IAhGI,0BAAA;GhEo3MD;CACF;AgE92MD;EAyFA;IA3FI,2BAAA;GhEo3MD;CACF;AgE92MD;EAoFA;IAtFI,iCAAA;GhEo3MD;CACF;AgE72MD;EA8EA;IC7LE,0BAAA;GjEg+MC;EiE/9MD;IAAU,0BAAA;GjEk+MT;EiEj+MD;IAAU,8BAAA;GjEo+MT;EiEn+MD;;IACU,+BAAA;GjEs+MT;CACF;AgEv3MD;EAyEA;IA3EI,0BAAA;GhE63MD;CACF;AgEv3MD;EAoEA;IAtEI,2BAAA;GhE63MD;CACF;AgEv3MD;EA+DA;IAjEI,iCAAA;GhE63MD;CACF;AgEt3MD;EAyDA;ICrLE,yBAAA;GjEs/MC;CACF;AgEt3MD;EAoDA;ICrLE,yBAAA;GjE2/MC;CACF;AgEt3MD;EA+CA;ICrLE,yBAAA;GjEggNC;CACF;AgEt3MD;EA0CA;ICrLE,yBAAA;GjEqgNC;CACF;AgEn3MD;ECnJE,yBAAA;CjEygND;AgEh3MD;EA4BA;IC7LE,0BAAA;GjEqhNC;EiEphND;IAAU,0BAAA;GjEuhNT;EiEthND;IAAU,8BAAA;GjEyhNT;EiExhND;;IACU,+BAAA;GjE2hNT;CACF;AgE93MD;EACE,yBAAA;ChEg4MD;AgE33MD;EAqBA;IAvBI,0BAAA;GhEi4MD;CACF;AgE/3MD;EACE,yBAAA;ChEi4MD;AgE53MD;EAcA;IAhBI,2BAAA;GhEk4MD;CACF;AgEh4MD;EACE,yBAAA;ChEk4MD;AgE73MD;EAOA;IATI,iCAAA;GhEm4MD;CACF;AgE53MD;EACA;ICrLE,yBAAA;GjEojNC;CACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on
      ,
        , or
        .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: (@carousel-control-font-size * 1.5);\n height: (@carousel-control-font-size * 1.5);\n margin-top: (@carousel-control-font-size / -2);\n font-size: (@carousel-control-font-size * 1.5);\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: (@carousel-control-font-size / -2);\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: (@carousel-control-font-size / -2);\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]} \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap.min.css b/backend/webif/static/css/bootstrap.min.css new file mode 100755 index 000000000..ed3905e0e --- /dev/null +++ b/backend/webif/static/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/webif/static/css/bootstrap.min.css.map b/backend/webif/static/css/bootstrap.min.css.map new file mode 100755 index 000000000..6c7fa40b9 --- /dev/null +++ b/backend/webif/static/css/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/normalize.less","less/print.less","bootstrap.css","dist/css/bootstrap.css","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":";;;;4EAQA,KACE,YAAA,WACA,yBAAA,KACA,qBAAA,KAOF,KACE,OAAA,EAaF,QAAA,MAAA,QAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,KAAA,IAAA,QAAA,QAaE,QAAA,MAQF,MAAA,OAAA,SAAA,MAIE,QAAA,aACA,eAAA,SAQF,sBACE,QAAA,KACA,OAAA,EAQF,SAAA,SAEE,QAAA,KAUF,EACE,iBAAA,YAQF,SAAA,QAEE,QAAA,EAUF,YACE,cAAA,IAAA,OAOF,EAAA,OAEE,YAAA,IAOF,IACE,WAAA,OAQF,GACE,OAAA,MAAA,EACA,UAAA,IAOF,KACE,MAAA,KACA,WAAA,KAOF,MACE,UAAA,IAOF,IAAA,IAEE,SAAA,SACA,UAAA,IACA,YAAA,EACA,eAAA,SAGF,IACE,IAAA,MAGF,IACE,OAAA,OAUF,IACE,OAAA,EAOF,eACE,SAAA,OAUF,OACE,OAAA,IAAA,KAOF,GACE,OAAA,EAAA,mBAAA,YAAA,gBAAA,YACA,WAAA,YAOF,IACE,SAAA,KAOF,KAAA,IAAA,IAAA,KAIE,YAAA,UAAA,UACA,UAAA,IAkBF,OAAA,MAAA,SAAA,OAAA,SAKE,OAAA,EACA,KAAA,QACA,MAAA,QAOF,OACE,SAAA,QAUF,OAAA,OAEE,eAAA,KAWF,OAAA,wBAAA,kBAAA,mBAIE,mBAAA,OACA,OAAA,QAOF,iBAAA,qBAEE,OAAA,QAOF,yBAAA,wBAEE,QAAA,EACA,OAAA,EAQF,MACE,YAAA,OAWF,qBAAA,kBAEE,mBAAA,WAAA,gBAAA,WAAA,WAAA,WACA,QAAA,EASF,8CAAA,8CAEE,OAAA,KAQF,mBACE,mBAAA,YACA,gBAAA,YAAA,WAAA,YAAA,mBAAA,UASF,iDAAA,8CAEE,mBAAA,KAOF,SACE,QAAA,MAAA,OAAA,MACA,OAAA,EAAA,IACA,OAAA,IAAA,MAAA,OAQF,OACE,QAAA,EACA,OAAA,EAOF,SACE,SAAA,KAQF,SACE,YAAA,IAUF,MACE,eAAA,EACA,gBAAA,SAGF,GAAA,GAEE,QAAA,uFCjUF,aA7FI,EAAA,OAAA,QAGI,MAAA,eACA,YAAA,eACA,WAAA,cAAA,mBAAA,eACA,WAAA,eAGJ,EAAA,UAEI,gBAAA,UAGJ,cACI,QAAA,KAAA,WAAA,IAGJ,kBACI,QAAA,KAAA,YAAA,IAKJ,6BAAA,mBAEI,QAAA,GAGJ,WAAA,IAEI,OAAA,IAAA,MAAA,KC4KL,kBAAA,MDvKK,MC0KL,QAAA,mBDrKK,IE8KN,GDLC,kBAAA,MDrKK,ICwKL,UAAA,eCUD,GF5KM,GE2KN,EF1KM,QAAA,ECuKL,OAAA,ECSD,GF3KM,GCsKL,iBAAA,MD/JK,QCkKL,QAAA,KCSD,YFtKU,oBCiKT,iBAAA,eD7JK,OCgKL,OAAA,IAAA,MAAA,KD5JK,OC+JL,gBAAA,mBCSD,UFpKU,UC+JT,iBAAA,eDzJS,mBEkKV,mBDLC,OAAA,IAAA,MAAA,gBEjPD,WACA,YAAA,uBFsPD,IAAA,+CE7OC,IAAK,sDAAuD,4BAA6B,iDAAkD,gBAAiB,gDAAiD,eAAgB,+CAAgD,mBAAoB,2EAA4E,cAE7W,WACA,SAAA,SACA,IAAA,IACA,QAAA,aACA,YAAA,uBACA,WAAA,OACA,YAAA,IACA,YAAA,EAIkC,uBAAA,YAAW,wBAAA,UACX,2BAAW,QAAA,QAEX,uBDuPlC,QAAS,QCtPyB,sBFiPnC,uBEjP8C,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,qBAAW,QAAA,QACX,0BAAW,QAAA,QACX,qBAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,sBAAW,QAAA,QACX,yBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,+BAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,gCAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,gCAAW,QAAA,QACX,gCAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,0BAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,mCAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,sBAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,0BAAW,QAAA,QACX,4BAAW,QAAA,QACX,qCAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,mCAAW,QAAA,QACX,uCAAW,QAAA,QACX,gCAAW,QAAA,QACX,oCAAW,QAAA,QACX,qCAAW,QAAA,QACX,yCAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,iCAAW,QAAA,QACX,oCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,qBAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QASX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,+BAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,mCAAW,QAAA,QACX,4BAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,kCAAW,QAAA,QACX,mCAAW,QAAA,QACX,sCAAW,QAAA,QACX,0CAAW,QAAA,QACX,oCAAW,QAAA,QACX,wCAAW,QAAA,QACX,qCAAW,QAAA,QACX,iCAAW,QAAA,QACX,gCAAW,QAAA,QACX,kCAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QCtS/C,0BCgEE,QAAA,QHi+BF,EDNC,mBAAA,WGxhCI,gBAAiB,WFiiCZ,WAAY,WGl+BZ,OADL,QJg+BJ,mBAAA,WGthCI,gBAAiB,WACpB,WAAA,WHyhCD,KGrhCC,UAAW,KAEX,4BAAA,cAEA,KACA,YAAA,iBAAA,UAAA,MAAA,WHuhCD,UAAA,KGnhCC,YAAa,WF4hCb,MAAO,KACP,iBAAkB,KExhClB,OADA,MAEA,OHqhCD,SG/gCC,YAAa,QACb,UAAA,QACA,YAAA,QAEA,EFwhCA,MAAO,QEthCL,gBAAA,KAIF,QH8gCD,QKjkCC,MAAA,QACA,gBAAA,UF6DF,QACE,QAAA,IAAA,KAAA,yBHygCD,eAAA,KGlgCC,OHqgCD,OAAA,ECSD,IACE,eAAgB,ODDjB,4BM/kCC,0BLklCF,gBKnlCE,iBADA,eH4EA,QAAS,MACT,UAAA,KHugCD,OAAA,KGhgCC,aACA,cAAA,IAEA,eACA,QAAA,aC6FA,UAAA,KACK,OAAA,KACG,QAAA,IEvLR,YAAA,WACA,iBAAA,KACA,OAAA,IAAA,MAAA,KN+lCD,cAAA,IGjgCC,mBAAoB,IAAI,IAAI,YAC5B,cAAA,IAAA,IAAA,YHmgCD,WAAA,IAAA,IAAA,YG5/BC,YACA,cAAA,IAEA,GH+/BD,WAAA,KGv/BC,cAAe,KACf,OAAA,EACA,WAAA,IAAA,MAAA,KAEA,SACA,SAAA,SACA,MAAA,IACA,OAAA,IACA,QAAA,EHy/BD,OAAA,KGj/BC,SAAA,OF0/BA,KAAM,cEx/BJ,OAAA,EAEA,0BACA,yBACA,SAAA,OACA,MAAA,KHm/BH,OAAA,KGx+BC,OAAQ,EACR,SAAA,QH0+BD,KAAA,KCSD,cACE,OAAQ,QAQV,IACA,IMlpCE,IACA,IACA,IACA,INwoCF,GACA,GACA,GACA,GACA,GACA,GDAC,YAAA,QOlpCC,YAAa,IN2pCb,YAAa,IACb,MAAO,QAoBT,WAZA,UAaA,WAZA,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UDMC,WCLD,UACA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SMppCE,YAAa,INwqCb,YAAa,EACb,MAAO,KAGT,IMxqCE,IAJF,IN2qCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UM5qCA,WN8qCA,UACA,UANA,SM5qCI,UN8qCJ,SM3qCA,UN6qCA,SAQE,UAAW,IAGb,IMprCE,IAJF,INurCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UMvrCA,WNyrCA,UACA,UANA,SMxrCI,UN0rCJ,SMtrCA,UNwrCA,SMxrCU,UAAA,IACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KAOR,IADF,GPssCC,UAAA,KCSD,EMzsCE,OAAA,EAAA,EAAA,KAEA,MPosCD,cAAA,KO/rCC,UAAW,KAwOX,YAAa,IA1OX,YAAA,IPssCH,yBO7rCC,MNssCE,UAAW,MMjsCf,OAAA,MAEE,UAAA,IAKF,MP0rCC,KO1rCsB,QAAA,KP6rCtB,iBAAA,QO5rCsB,WP+rCtB,WAAA,KO9rCsB,YPisCtB,WAAA,MOhsCsB,aPmsCtB,WAAA,OOlsCsB,cPqsCtB,WAAA,QOlsCsB,aPqsCtB,YAAA,OOpsCsB,gBPusCtB,eAAA,UOtsCsB,gBPysCtB,eAAA,UOrsCC,iBPwsCD,eAAA,WQ3yCC,YR8yCD,MAAA,KCSD,cOpzCI,MAAA,QAHF,qBDwGF,qBP6sCC,MAAA,QCSD,cO3zCI,MAAA,QAHF,qBD2GF,qBPitCC,MAAA,QCSD,WOl0CI,MAAA,QAHF,kBD8GF,kBPqtCC,MAAA,QCSD,cOz0CI,MAAA,QAHF,qBDiHF,qBPytCC,MAAA,QCSD,aOh1CI,MAAA,QDwHF,oBAHF,oBExHE,MAAA,QACA,YR01CA,MAAO,KQx1CL,iBAAA,QAHF,mBF8HF,mBP2tCC,iBAAA,QCSD,YQ/1CI,iBAAA,QAHF,mBFiIF,mBP+tCC,iBAAA,QCSD,SQt2CI,iBAAA,QAHF,gBFoIF,gBPmuCC,iBAAA,QCSD,YQ72CI,iBAAA,QAHF,mBFuIF,mBPuuCC,iBAAA,QCSD,WQp3CI,iBAAA,QF6IF,kBADF,kBAEE,iBAAA,QPsuCD,aO7tCC,eAAgB,INsuChB,OAAQ,KAAK,EAAE,KMpuCf,cAAA,IAAA,MAAA,KAFF,GPkuCC,GCSC,WAAY,EACZ,cAAe,KM9tCf,MP0tCD,MO3tCD,MAPI,MASF,cAAA,EAIF,eALE,aAAA,EACA,WAAA,KPkuCD,aO9tCC,aAAc,EAKZ,YAAA,KACA,WAAA,KP6tCH,gBOvtCC,QAAS,aACT,cAAA,IACA,aAAA,IAEF,GNguCE,WAAY,EM9tCZ,cAAA,KAGA,GADF,GP0tCC,YAAA,WOttCC,GPytCD,YAAA,IOnnCD,GAvFM,YAAA,EAEA,yBACA,kBGtNJ,MAAA,KACA,MAAA,MACA,SAAA,OVq6CC,MAAA,KO7nCC,WAAY,MAhFV,cAAA,SPgtCH,YAAA,OOtsCD,kBNgtCE,YAAa,OM1sCjB,0BPssCC,YOrsCC,OAAA,KA9IqB,cAAA,IAAA,OAAA,KAmJvB,YACE,UAAA,IACA,eAAA,UAEA,WPssCD,QAAA,KAAA,KOjsCG,OAAA,EAAA,EAAA,KN0sCF,UAAW,OACX,YAAa,IAAI,MAAM,KMptCzB,yBP+sCC,wBO/sCD,yBNytCE,cAAe,EMnsCb,kBAFA,kBACA,iBPksCH,QAAA,MO/rCG,UAAA,INwsCF,YAAa,WACb,MAAO,KMhsCT,yBP2rCC,yBO3rCD,wBAEE,QAAA,cAEA,oBACA,sBACA,cAAA,KP6rCD,aAAA,EOvrCG,WAAA,MNgsCF,aAAc,IAAI,MAAM,KACxB,YAAa,EMhsCX,kCNksCJ,kCMnsCe,iCACX,oCNmsCJ,oCDLC,mCCUC,QAAS,GMjsCX,iCNmsCA,iCMzsCM,gCAOJ,mCNmsCF,mCDLC,kCO7rCC,QAAA,cPksCD,QWv+CC,cAAe,KVg/Cf,WAAY,OACZ,YAAa,WU7+Cb,KXy+CD,IWr+CD,IACE,KACA,YAAA,MAAA,OAAA,SAAA,cAAA,UAEA,KACA,QAAA,IAAA,IXu+CD,UAAA,IWn+CC,MAAO,QACP,iBAAA,QACA,cAAA,IAEA,IACA,QAAA,IAAA,IACA,UAAA,IV4+CA,MU5+CA,KXq+CD,iBAAA,KW3+CC,cAAe,IASb,mBAAA,MAAA,EAAA,KAAA,EAAA,gBACA,WAAA,MAAA,EAAA,KAAA,EAAA,gBAEA,QV6+CF,QU7+CE,EXq+CH,UAAA,KWh+CC,YAAa,IACb,mBAAA,KACA,WAAA,KAEA,IACA,QAAA,MACA,QAAA,MACA,OAAA,EAAA,EAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,WAAA,UXk+CD,UAAA,WW7+CC,iBAAkB,QAehB,OAAA,IAAA,MAAA,KACA,cAAA,IAEA,SACA,QAAA,EACA,UAAA,QXi+CH,MAAA,QW59CC,YAAa,SACb,iBAAA,YACA,cAAA,EC1DF,gBCHE,WAAA,MACA,WAAA,OAEA,Wb8hDD,cAAA,KYxhDC,aAAA,KAqEA,aAAc,KAvEZ,YAAA,KZ+hDH,yBY1hDC,WAkEE,MAAO,OZ69CV,yBY5hDC,WA+DE,MAAO,OZk+CV,0BYzhDC,WCvBA,MAAA,QAGA,iBbmjDD,cAAA,KYthDC,aAAc,KCvBd,aAAA,KACA,YAAA,KCAE,KACE,aAAA,MAEA,YAAA,MAGA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UdgjDL,SAAA,SchiDG,WAAA,IACE,cAAA,KdkiDL,aAAA,Kc1hDG,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud6hDH,MAAA,Kc7hDG,WdgiDH,MAAA,KchiDG,WdmiDH,MAAA,acniDG,WdsiDH,MAAA,actiDG,UdyiDH,MAAA,IcziDG,Ud4iDH,MAAA,ac5iDG,Ud+iDH,MAAA,ac/iDG,UdkjDH,MAAA,IcljDG,UdqjDH,MAAA,acrjDG,UdwjDH,MAAA,acxjDG,Ud2jDH,MAAA,Ic3jDG,Ud8jDH,MAAA,ac/iDG,UdkjDH,MAAA,YcljDG,gBdqjDH,MAAA,KcrjDG,gBdwjDH,MAAA,acxjDG,gBd2jDH,MAAA,ac3jDG,ed8jDH,MAAA,Ic9jDG,edikDH,MAAA,acjkDG,edokDH,MAAA,acpkDG,edukDH,MAAA,IcvkDG,ed0kDH,MAAA,ac1kDG,ed6kDH,MAAA,ac7kDG,edglDH,MAAA,IchlDG,edmlDH,MAAA,ac9kDG,edilDH,MAAA,YchmDG,edmmDH,MAAA,KcnmDG,gBdsmDH,KAAA,KctmDG,gBdymDH,KAAA,aczmDG,gBd4mDH,KAAA,ac5mDG,ed+mDH,KAAA,Ic/mDG,edknDH,KAAA,aclnDG,edqnDH,KAAA,acrnDG,edwnDH,KAAA,IcxnDG,ed2nDH,KAAA,ac3nDG,ed8nDH,KAAA,ac9nDG,edioDH,KAAA,IcjoDG,edooDH,KAAA,ac/nDG,edkoDH,KAAA,YcnnDG,edsnDH,KAAA,KctnDG,kBdynDH,YAAA,KcznDG,kBd4nDH,YAAA,ac5nDG,kBd+nDH,YAAA,ac/nDG,iBdkoDH,YAAA,IcloDG,iBdqoDH,YAAA,acroDG,iBdwoDH,YAAA,acxoDG,iBd2oDH,YAAA,Ic3oDG,iBd8oDH,YAAA,ac9oDG,iBdipDH,YAAA,acjpDG,iBdopDH,YAAA,IcppDG,iBdupDH,YAAA,acvpDG,iBd0pDH,YAAA,Yc5rDG,iBACE,YAAA,EAOJ,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud0rDD,MAAA,Kc1rDC,Wd6rDD,MAAA,Kc7rDC,WdgsDD,MAAA,achsDC,WdmsDD,MAAA,acnsDC,UdssDD,MAAA,IctsDC,UdysDD,MAAA,aczsDC,Ud4sDD,MAAA,ac5sDC,Ud+sDD,MAAA,Ic/sDC,UdktDD,MAAA,acltDC,UdqtDD,MAAA,acrtDC,UdwtDD,MAAA,IcxtDC,Ud2tDD,MAAA,ac5sDC,Ud+sDD,MAAA,Yc/sDC,gBdktDD,MAAA,KcltDC,gBdqtDD,MAAA,acrtDC,gBdwtDD,MAAA,acxtDC,ed2tDD,MAAA,Ic3tDC,ed8tDD,MAAA,ac9tDC,ediuDD,MAAA,acjuDC,edouDD,MAAA,IcpuDC,eduuDD,MAAA,acvuDC,ed0uDD,MAAA,ac1uDC,ed6uDD,MAAA,Ic7uDC,edgvDD,MAAA,ac3uDC,ed8uDD,MAAA,Yc7vDC,edgwDD,MAAA,KchwDC,gBdmwDD,KAAA,KcnwDC,gBdswDD,KAAA,actwDC,gBdywDD,KAAA,aczwDC,ed4wDD,KAAA,Ic5wDC,ed+wDD,KAAA,ac/wDC,edkxDD,KAAA,aclxDC,edqxDD,KAAA,IcrxDC,edwxDD,KAAA,acxxDC,ed2xDD,KAAA,ac3xDC,ed8xDD,KAAA,Ic9xDC,ediyDD,KAAA,ac5xDC,ed+xDD,KAAA,YchxDC,edmxDD,KAAA,KcnxDC,kBdsxDD,YAAA,KctxDC,kBdyxDD,YAAA,aczxDC,kBd4xDD,YAAA,ac5xDC,iBd+xDD,YAAA,Ic/xDC,iBdkyDD,YAAA,aclyDC,iBdqyDD,YAAA,acryDC,iBdwyDD,YAAA,IcxyDC,iBd2yDD,YAAA,ac3yDC,iBd8yDD,YAAA,ac9yDC,iBdizDD,YAAA,IcjzDC,iBdozDD,YAAA,acpzDC,iBduzDD,YAAA,YY9yDD,iBE3CE,YAAA,GAQF,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Udw1DD,MAAA,Kcx1DC,Wd21DD,MAAA,Kc31DC,Wd81DD,MAAA,ac91DC,Wdi2DD,MAAA,acj2DC,Udo2DD,MAAA,Icp2DC,Udu2DD,MAAA,acv2DC,Ud02DD,MAAA,ac12DC,Ud62DD,MAAA,Ic72DC,Udg3DD,MAAA,ach3DC,Udm3DD,MAAA,acn3DC,Uds3DD,MAAA,Ict3DC,Udy3DD,MAAA,ac12DC,Ud62DD,MAAA,Yc72DC,gBdg3DD,MAAA,Kch3DC,gBdm3DD,MAAA,acn3DC,gBds3DD,MAAA,act3DC,edy3DD,MAAA,Icz3DC,ed43DD,MAAA,ac53DC,ed+3DD,MAAA,ac/3DC,edk4DD,MAAA,Icl4DC,edq4DD,MAAA,acr4DC,edw4DD,MAAA,acx4DC,ed24DD,MAAA,Ic34DC,ed84DD,MAAA,acz4DC,ed44DD,MAAA,Yc35DC,ed85DD,MAAA,Kc95DC,gBdi6DD,KAAA,Kcj6DC,gBdo6DD,KAAA,acp6DC,gBdu6DD,KAAA,acv6DC,ed06DD,KAAA,Ic16DC,ed66DD,KAAA,ac76DC,edg7DD,KAAA,ach7DC,edm7DD,KAAA,Icn7DC,eds7DD,KAAA,act7DC,edy7DD,KAAA,acz7DC,ed47DD,KAAA,Ic57DC,ed+7DD,KAAA,ac17DC,ed67DD,KAAA,Yc96DC,edi7DD,KAAA,Kcj7DC,kBdo7DD,YAAA,Kcp7DC,kBdu7DD,YAAA,acv7DC,kBd07DD,YAAA,ac17DC,iBd67DD,YAAA,Ic77DC,iBdg8DD,YAAA,ach8DC,iBdm8DD,YAAA,acn8DC,iBds8DD,YAAA,Ict8DC,iBdy8DD,YAAA,acz8DC,iBd48DD,YAAA,ac58DC,iBd+8DD,YAAA,Ic/8DC,iBdk9DD,YAAA,acl9DC,iBdq9DD,YAAA,YYz8DD,iBE9CE,YAAA,GAQF,0BACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Uds/DD,MAAA,Kct/DC,Wdy/DD,MAAA,Kcz/DC,Wd4/DD,MAAA,ac5/DC,Wd+/DD,MAAA,ac//DC,UdkgED,MAAA,IclgEC,UdqgED,MAAA,acrgEC,UdwgED,MAAA,acxgEC,Ud2gED,MAAA,Ic3gEC,Ud8gED,MAAA,ac9gEC,UdihED,MAAA,acjhEC,UdohED,MAAA,IcphEC,UduhED,MAAA,acxgEC,Ud2gED,MAAA,Yc3gEC,gBd8gED,MAAA,Kc9gEC,gBdihED,MAAA,acjhEC,gBdohED,MAAA,acphEC,eduhED,MAAA,IcvhEC,ed0hED,MAAA,ac1hEC,ed6hED,MAAA,ac7hEC,edgiED,MAAA,IchiEC,edmiED,MAAA,acniEC,edsiED,MAAA,actiEC,edyiED,MAAA,IcziEC,ed4iED,MAAA,acviEC,ed0iED,MAAA,YczjEC,ed4jED,MAAA,Kc5jEC,gBd+jED,KAAA,Kc/jEC,gBdkkED,KAAA,aclkEC,gBdqkED,KAAA,acrkEC,edwkED,KAAA,IcxkEC,ed2kED,KAAA,ac3kEC,ed8kED,KAAA,ac9kEC,edilED,KAAA,IcjlEC,edolED,KAAA,acplEC,edulED,KAAA,acvlEC,ed0lED,KAAA,Ic1lEC,ed6lED,KAAA,acxlEC,ed2lED,KAAA,Yc5kEC,ed+kED,KAAA,Kc/kEC,kBdklED,YAAA,KcllEC,kBdqlED,YAAA,acrlEC,kBdwlED,YAAA,acxlEC,iBd2lED,YAAA,Ic3lEC,iBd8lED,YAAA,ac9lEC,iBdimED,YAAA,acjmEC,iBdomED,YAAA,IcpmEC,iBdumED,YAAA,acvmEC,iBd0mED,YAAA,ac1mEC,iBd6mED,YAAA,Ic7mEC,iBdgnED,YAAA,achnEC,iBdmnED,YAAA,YetrED,iBACA,YAAA,GAGA,MACA,iBAAA,YAEA,QfyrED,YAAA,IevrEC,eAAgB,IAChB,MAAA,KfyrED,WAAA,KelrEC,GACA,WAAA,KfsrED,OexrEC,MAAO,KdmsEP,UAAW,KACX,cAAe,KcvrET,mBd0rER,mBczrEQ,mBAHA,mBACA,mBd0rER,mBDHC,QAAA,IensEC,YAAa,WAoBX,eAAA,IACA,WAAA,IAAA,MAAA,KArBJ,mBdktEE,eAAgB,OAChB,cAAe,IAAI,MAAM,KDJ1B,uCCMD,uCcrtEA,wCdstEA,wCclrEI,2CANI,2CforEP,WAAA,EezqEG,mBf4qEH,WAAA,IAAA,MAAA,KCWD,cACE,iBAAkB,Kc/pEpB,6BdkqEA,6BcjqEE,6BAZM,6BfsqEP,6BCMD,6BDHC,QAAA,ICWD,gBACE,OAAQ,IAAI,MAAM,Kc1qEpB,4Bd6qEA,4Bc7qEA,4BAQQ,4Bf8pEP,4BCMD,4Bc7pEM,OAAA,IAAA,MAAA,KAYF,4BAFJ,4BfopEC,oBAAA,IevoEG,yCf0oEH,iBAAA,QehoEC,4BACA,iBAAA,QfooED,uBe9nEG,SAAA,OdyoEF,QAAS,acxoEL,MAAA,KAEA,sBfioEL,sBgB7wEC,SAAA,OfwxEA,QAAS,WACT,MAAO,KAST,0BerxEE,0Bf+wEF,0BAGA,0BexxEM,0BAMJ,0BfgxEF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCgBlyEC,sCAAA,oCfyyEF,sCetxEM,sCf2xEJ,iBAAkB,QASpB,2Be1yEE,2BfoyEF,2BAGA,2Be7yEM,2BAMJ,2BfqyEF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBvzEC,uCAAA,qCf8zEF,uCe3yEM,uCfgzEJ,iBAAkB,QASpB,wBe/zEE,wBfyzEF,wBAGA,wBel0EM,wBAMJ,wBf0zEF,wBAGA,wBACA,wBDNC,wBCAD,wBAGA,wBASE,iBAAkB,QDLnB,oCgB50EC,oCAAA,kCfm1EF,oCeh0EM,oCfq0EJ,iBAAkB,QASpB,2Bep1EE,2Bf80EF,2BAGA,2Bev1EM,2BAMJ,2Bf+0EF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBj2EC,uCAAA,qCfw2EF,uCer1EM,uCf01EJ,iBAAkB,QASpB,0Bez2EE,0Bfm2EF,0BAGA,0Be52EM,0BAMJ,0Bfo2EF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCehtEC,sCADF,oCdwtEA,sCe12EM,sCDoJJ,iBAAA,QA6DF,kBACE,WAAY,KA3DV,WAAA,KAEA,oCACA,kBACA,MAAA,KfotED,cAAA,Ke7pEC,WAAY,OAnDV,mBAAA,yBfmtEH,OAAA,IAAA,MAAA,KCWD,yBACE,cAAe,Ec5qEjB,qCd+qEA,qCcjtEI,qCARM,qCfktET,qCCMD,qCDHC,YAAA,OCWD,kCACE,OAAQ,EcvrEV,0Dd0rEA,0Dc1rEA,0DAzBU,0Df4sET,0DCMD,0DAME,YAAa,Ec/rEf,yDdksEA,yDclsEA,yDArBU,yDfgtET,yDCMD,yDAME,aAAc,EDLjB,yDe1sEW,yDEzNV,yDjBk6EC,yDiBj6ED,cAAA,GAMA,SjBk6ED,UAAA,EiB/5EC,QAAS,EACT,OAAA,EACA,OAAA,EAEA,OACA,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,KACA,UAAA,KjBi6ED,YAAA,QiB95EC,MAAO,KACP,OAAA,EACA,cAAA,IAAA,MAAA,QAEA,MjBg6ED,QAAA,aiBr5EC,UAAW,Kb4BX,cAAA,IACG,YAAA,IJ63EJ,mBiBr5EC,mBAAoB,WhBg6EjB,gBAAiB,WgB95EpB,WAAA,WjBy5ED,qBiBv5EC,kBAGA,OAAQ,IAAI,EAAE,EACd,WAAA,MjBs5ED,YAAA,OiBj5EC,iBACA,QAAA,MAIF,kBhB25EE,QAAS,MgBz5ET,MAAA,KAIF,iBAAA,ahB05EE,OAAQ,KI99ER,uBY2EF,2BjB64EC,wBiB54EC,QAAA,IAAA,KAAA,yBACA,eAAA,KAEA,OACA,QAAA,MjB+4ED,YAAA,IiBr3EC,UAAW,KACX,YAAA,WACA,MAAA,KAEA,cACA,QAAA,MACA,MAAA,KACA,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KbxDA,iBAAA,KACQ,iBAAA,KAyHR,OAAA,IAAA,MAAA,KACK,cAAA,IACG,mBAAA,MAAA,EAAA,IAAA,IAAA,iBJwzET,WAAA,MAAA,EAAA,IAAA,IAAA,iBkBh8EC,mBAAA,aAAA,YAAA,KAAA,mBAAA,YAAA,KACE,cAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KACA,WAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KdWM,oBJy7ET,aAAA,QIx5EC,QAAA,EACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBAEF,gCAA0B,MAAA,KJ25E3B,QAAA,EI15EiC,oCJ65EjC,MAAA,KiBh4EG,yCACA,MAAA,KAQF,0BhBs4EA,iBAAkB,YAClB,OAAQ,EgBn4EN,wBjB63EH,wBiB13EC,iChBq4EA,iBAAkB,KgBn4EhB,QAAA,EAIF,wBACE,iCjB03EH,OAAA,YiB72EC,sBjBg3ED,OAAA,KiB91EG,mBhB02EF,mBAAoB,KAEtB,qDgB32EM,8BjBo2EH,8BiBj2EC,wCAAA,+BhB62EA,YAAa,KgB32EX,iCjBy2EH,iCiBt2EC,2CAAA,kChB02EF,0BACA,0BACA,oCACA,2BAKE,YAAa,KgBh3EX,iCjB82EH,iCACF,2CiBp2EC,kChBu2EA,0BACA,0BACA,oCACA,2BgBz2EA,YAAA,MhBi3EF,YgBv2EE,cAAA,KAGA,UADA,OjBi2ED,SAAA,SiBr2EC,QAAS,MhBg3ET,WAAY,KgBx2EV,cAAA,KAGA,gBADA,aAEA,WAAA,KjBi2EH,aAAA,KiB91EC,cAAe,EhBy2Ef,YAAa,IACb,OAAQ,QgBp2ER,+BjBg2ED,sCiBl2EC,yBACA,gCAIA,SAAU,ShBw2EV,WAAY,MgBt2EZ,YAAA,MAIF,oBAAA,cAEE,WAAA,KAGA,iBADA,cAEA,SAAA,SACA,QAAA,aACA,aAAA,KjB61ED,cAAA,EiB31EC,YAAa,IhBs2Eb,eAAgB,OgBp2EhB,OAAA,QAUA,kCjBo1ED,4BCWC,WAAY,EACZ,YAAa,KgBv1Eb,wCAAA,qCjBm1ED,8BCOD,+BgBh2EI,2BhB+1EJ,4BAME,OAAQ,YDNT,0BiBv1EG,uBAMF,oCAAA,iChB61EA,OAAQ,YDNT,yBiBp1EK,sBAaJ,mCAFF,gCAGE,OAAA,YAGA,qBjBy0ED,WAAA,KiBv0EC,YAAA,IhBk1EA,eAAgB,IgBh1Ed,cAAA,EjB00EH,8BiB5zED,8BCnQE,cAAA,EACA,aAAA,EAEA,UACA,OAAA,KlBkkFD,QAAA,IAAA,KkBhkFC,UAAA,KACE,YAAA,IACA,cAAA,IAGF,gBjB0kFA,OAAQ,KiBxkFN,YAAA,KD2PA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBy0EH,QAAA,IAAA,KiB/0EC,UAAW,KAST,YAAA,IACA,cAAA,IAVJ,mChB81EE,OAAQ,KgBh1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBy0EH,WAAA,KiBr0EC,QAAS,IAAI,KC/Rb,UAAA,KACA,YAAA,IAEA,UACA,OAAA,KlBumFD,QAAA,KAAA,KkBrmFC,UAAA,KACE,YAAA,UACA,cAAA,IAGF,gBjB+mFA,OAAQ,KiB7mFN,YAAA,KDuRA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBk1EH,QAAA,KAAA,KiBx1EC,UAAW,KAST,YAAA,UACA,cAAA,IAVJ,mChBu2EE,OAAQ,KgBz1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBk1EH,WAAA,KiBz0EC,QAAS,KAAK,KAEd,UAAA,KjB00ED,YAAA,UiBt0EG,cjBy0EH,SAAA,SiBp0EC,4BACA,cAAA,OAEA,uBACA,SAAA,SACA,IAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,MACA,MAAA,KjBu0ED,OAAA,KiBr0EC,YAAa,KhBg1Eb,WAAY,OACZ,eAAgB,KDLjB,oDiBv0EC,uCADA,iCAGA,MAAO,KhBg1EP,OAAQ,KACR,YAAa,KDLd,oDiBv0EC,uCADA,iCAKA,MAAO,KhB80EP,OAAQ,KACR,YAAa,KAKf,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBruFG,mCAJA,yBD0ZJ,gCbvWE,MAAA,QJ2rFD,2BkBxuFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJgsFD,iCiBz1EC,aAAc,QC5YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlByuFH,gCiB91EC,MAAO,QCtYL,iBAAA,QlBuuFH,aAAA,QCWD,oCACE,MAAO,QAKT,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBnwFG,mCAJA,yBD6ZJ,gCb1WE,MAAA,QJytFD,2BkBtwFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ8tFD,iCiBp3EC,aAAc,QC/YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBuwFH,gCiBz3EC,MAAO,QCzYL,iBAAA,QlBqwFH,aAAA,QCWD,oCACE,MAAO,QAKT,qBAEA,4BAJA,0BADA,uBAEA,kBAEA,yBDNC,0BkBjyFG,iCAJA,uBDgaJ,8Bb7WE,MAAA,QJuvFD,yBkBpyFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ4vFD,+BiB/4EC,aAAc,QClZZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBqyFH,8BiBp5EC,MAAO,QC5YL,iBAAA,QlBmyFH,aAAA,QiB/4EG,kCjBk5EH,MAAA,QiB/4EG,2CjBk5EH,IAAA,KiBv4EC,mDACA,IAAA,EAEA,YjB04ED,QAAA,MiBvzEC,WAAY,IAwEZ,cAAe,KAtIX,MAAA,QAEA,yBjBy3EH,yBiBrvEC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBw3EH,2BiB1vEC,QAAS,aAxHP,MAAA,KjBq3EH,eAAA,OiBj3EG,kCACA,QAAA,aAmHJ,0BhB4wEE,QAAS,aACT,eAAgB,OgBr3Ed,wCjB82EH,6CiBtwED,2CjBywEC,MAAA,KiB72EG,wCACA,MAAA,KAmGJ,4BhBwxEE,cAAe,EgBp3Eb,eAAA,OAGA,uBADA,oBjB82EH,QAAA,aiBpxEC,WAAY,EhB+xEZ,cAAe,EgBr3EX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB6xEC,sCiBx2EG,SAAA,SjB22EH,YAAA,EiBh2ED,kDhB42EE,IAAK,GgBl2EL,2BjB+1EH,kCiBh2EG,wBAEA,+BAXF,YAAa,IhBo3Eb,WAAY,EgBn2EV,cAAA,EJviBF,2BIshBF,wBJrhBE,WAAA,KI4jBA,6BAyBA,aAAc,MAnCV,YAAA,MAEA,yBjBw1EH,gCACF,YAAA,IiBx3EG,cAAe,EAwCf,WAAA,OAwBJ,sDAdQ,MAAA,KjB80EL,yBACF,+CiBn0EC,YAAA,KAEE,UAAW,MjBs0EZ,yBACF,+CmBp6FG,YAAa,IACf,UAAA,MAGA,KACA,QAAA,aACA,QAAA,IAAA,KAAA,cAAA,EACA,UAAA,KACA,YAAA,IACA,YAAA,WACA,WAAA,OC0CA,YAAA,OACA,eAAA,OACA,iBAAA,aACA,aAAA,ahB+JA,OAAA,QACG,oBAAA,KACC,iBAAA,KACI,gBAAA,KJ+tFT,YAAA,KmBv6FG,iBAAA,KlBm7FF,OAAQ,IAAI,MAAM,YAClB,cAAe,IkB96Ff,kBdzBA,kBACA,WLk8FD,kBCOD,kBADA,WAME,QAAS,IAAI,KAAK,yBAClB,eAAgB,KkBh7FhB,WnBy6FD,WmB56FG,WlBw7FF,MAAO,KkBn7FL,gBAAA,Kf6BM,YADR,YJk5FD,iBAAA,KmBz6FC,QAAA,ElBq7FA,mBAAoB,MAAM,EAAE,IAAI,IAAI,iBAC5B,WAAY,MAAM,EAAE,IAAI,IAAI,iBoBh+FpC,cAGA,ejB8DA,wBACQ,OAAA,YJ05FT,OAAA,kBmBz6FG,mBAAA,KlBq7FM,WAAY,KkBn7FhB,QAAA,IASN,eC3DE,yBACA,eAAA,KpBi+FD,aoB99FC,MAAA,KnB0+FA,iBAAkB,KmBx+FhB,aAAA,KpBk+FH,mBoBh+FO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBi+FH,mBoB99FC,MAAA,KnB0+FA,iBAAkB,QAClB,aAAc,QmBt+FR,oBADJ,oBpBi+FH,mCoB99FG,MAAA,KnB0+FF,iBAAkB,QAClB,aAAc,QmBt+FN,0BnB4+FV,0BAHA,0BmB1+FM,0BnB4+FN,0BAHA,0BDFC,yCoBx+FK,yCnB4+FN,yCmBv+FE,MAAA,KnB++FA,iBAAkB,QAClB,aAAc,QmBx+FZ,oBpBg+FH,oBoBh+FG,mCnB6+FF,iBAAkB,KmBz+FV,4BnB8+FV,4BAHA,4BDHC,6BCOD,6BAHA,6BkB39FA,sCClBM,sCnB8+FN,sCmBx+FI,iBAAA,KACA,aAAA,KDcJ,oBC9DE,MAAA,KACA,iBAAA,KpB0hGD,aoBvhGC,MAAA,KnBmiGA,iBAAkB,QmBjiGhB,aAAA,QpB2hGH,mBoBzhGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB0hGH,mBoBvhGC,MAAA,KnBmiGA,iBAAkB,QAClB,aAAc,QmB/hGR,oBADJ,oBpB0hGH,mCoBvhGG,MAAA,KnBmiGF,iBAAkB,QAClB,aAAc,QmB/hGN,0BnBqiGV,0BAHA,0BmBniGM,0BnBqiGN,0BAHA,0BDFC,yCoBjiGK,yCnBqiGN,yCmBhiGE,MAAA,KnBwiGA,iBAAkB,QAClB,aAAc,QmBjiGZ,oBpByhGH,oBoBzhGG,mCnBsiGF,iBAAkB,KmBliGV,4BnBuiGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBjhGA,sCCrBM,sCnBuiGN,sCmBjiGI,iBAAA,QACA,aAAA,QDkBJ,oBClEE,MAAA,QACA,iBAAA,KpBmlGD,aoBhlGC,MAAA,KnB4lGA,iBAAkB,QmB1lGhB,aAAA,QpBolGH,mBoBllGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBmlGH,mBoBhlGC,MAAA,KnB4lGA,iBAAkB,QAClB,aAAc,QmBxlGR,oBADJ,oBpBmlGH,mCoBhlGG,MAAA,KnB4lGF,iBAAkB,QAClB,aAAc,QmBxlGN,0BnB8lGV,0BAHA,0BmB5lGM,0BnB8lGN,0BAHA,0BDFC,yCoB1lGK,yCnB8lGN,yCmBzlGE,MAAA,KnBimGA,iBAAkB,QAClB,aAAc,QmB1lGZ,oBpBklGH,oBoBllGG,mCnB+lGF,iBAAkB,KmB3lGV,4BnBgmGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBtkGA,sCCzBM,sCnBgmGN,sCmB1lGI,iBAAA,QACA,aAAA,QDsBJ,oBCtEE,MAAA,QACA,iBAAA,KpB4oGD,UoBzoGC,MAAA,KnBqpGA,iBAAkB,QmBnpGhB,aAAA,QpB6oGH,gBoB3oGO,gBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB4oGH,gBoBzoGC,MAAA,KnBqpGA,iBAAkB,QAClB,aAAc,QmBjpGR,iBADJ,iBpB4oGH,gCoBzoGG,MAAA,KnBqpGF,iBAAkB,QAClB,aAAc,QmBjpGN,uBnBupGV,uBAHA,uBmBrpGM,uBnBupGN,uBAHA,uBDFC,sCoBnpGK,sCnBupGN,sCmBlpGE,MAAA,KnB0pGA,iBAAkB,QAClB,aAAc,QmBnpGZ,iBpB2oGH,iBoB3oGG,gCnBwpGF,iBAAkB,KmBppGV,yBnBypGV,yBAHA,yBDHC,0BCOD,0BAHA,0BkB3nGA,mCC7BM,mCnBypGN,mCmBnpGI,iBAAA,QACA,aAAA,QD0BJ,iBC1EE,MAAA,QACA,iBAAA,KpBqsGD,aoBlsGC,MAAA,KnB8sGA,iBAAkB,QmB5sGhB,aAAA,QpBssGH,mBoBpsGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBqsGH,mBoBlsGC,MAAA,KnB8sGA,iBAAkB,QAClB,aAAc,QmB1sGR,oBADJ,oBpBqsGH,mCoBlsGG,MAAA,KnB8sGF,iBAAkB,QAClB,aAAc,QmB1sGN,0BnBgtGV,0BAHA,0BmB9sGM,0BnBgtGN,0BAHA,0BDFC,yCoB5sGK,yCnBgtGN,yCmB3sGE,MAAA,KnBmtGA,iBAAkB,QAClB,aAAc,QmB5sGZ,oBpBosGH,oBoBpsGG,mCnBitGF,iBAAkB,KmB7sGV,4BnBktGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBhrGA,sCCjCM,sCnBktGN,sCmB5sGI,iBAAA,QACA,aAAA,QD8BJ,oBC9EE,MAAA,QACA,iBAAA,KpB8vGD,YoB3vGC,MAAA,KnBuwGA,iBAAkB,QmBrwGhB,aAAA,QpB+vGH,kBoB7vGO,kBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB8vGH,kBoB3vGC,MAAA,KnBuwGA,iBAAkB,QAClB,aAAc,QmBnwGR,mBADJ,mBpB8vGH,kCoB3vGG,MAAA,KnBuwGF,iBAAkB,QAClB,aAAc,QmBnwGN,yBnBywGV,yBAHA,yBmBvwGM,yBnBywGN,yBAHA,yBDFC,wCoBrwGK,wCnBywGN,wCmBpwGE,MAAA,KnB4wGA,iBAAkB,QAClB,aAAc,QmBrwGZ,mBpB6vGH,mBoB7vGG,kCnB0wGF,iBAAkB,KmBtwGV,2BnB2wGV,2BAHA,2BDHC,4BCOD,4BAHA,4BkBruGA,qCCrCM,qCnB2wGN,qCmBrwGI,iBAAA,QACA,aAAA,QDuCJ,mBACE,MAAA,QACA,iBAAA,KnB+tGD,UmB5tGC,YAAA,IlBwuGA,MAAO,QACP,cAAe,EAEjB,UGzwGE,iBemCE,iBflCM,oBJkwGT,6BmB7tGC,iBAAA,YlByuGA,mBAAoB,KACZ,WAAY,KkBtuGlB,UAEF,iBAAA,gBnB6tGD,gBmB3tGG,aAAA,YnBiuGH,gBmB/tGG,gBAIA,MAAA,QlBuuGF,gBAAiB,UACjB,iBAAkB,YDNnB,0BmBhuGK,0BAUN,mCATM,mClB2uGJ,MAAO,KmB1yGP,gBAAA,KAGA,mBADA,QpBmyGD,QAAA,KAAA,KmBztGC,UAAW,KlBquGX,YAAa,UmBjzGb,cAAA,IAGA,mBADA,QpB0yGD,QAAA,IAAA,KmB5tGC,UAAW,KlBwuGX,YAAa,ImBxzGb,cAAA,IAGA,mBADA,QpBizGD,QAAA,IAAA,ImB3tGC,UAAW,KACX,YAAA,IACA,cAAA,IAIF,WACE,QAAA,MnB2tGD,MAAA,KCYD,sBACE,WAAY,IqBz3GZ,6BADF,4BtBk3GC,6BI7rGC,MAAA,KAEQ,MJisGT,QAAA,EsBr3GC,mBAAA,QAAA,KAAA,OACE,cAAA,QAAA,KAAA,OtBu3GH,WAAA,QAAA,KAAA,OsBl3GC,StBq3GD,QAAA,EsBn3Ga,UtBs3Gb,QAAA,KsBr3Ga,atBw3Gb,QAAA,MsBv3Ga,etB03Gb,QAAA,UsBt3GC,kBACA,QAAA,gBlBwKA,YACQ,SAAA,SAAA,OAAA,EAOR,SAAA,OACQ,mCAAA,KAAA,8BAAA,KAGR,2BAAA,KACQ,4BAAA,KAAA,uBAAA,KJ2sGT,oBAAA,KuBr5GC,4BAA6B,OAAQ,WACrC,uBAAA,OAAA,WACA,oBAAA,OAAA,WAEA,OACA,QAAA,aACA,MAAA,EACA,OAAA,EACA,YAAA,IACA,eAAA,OvBu5GD,WAAA,IAAA,OuBn5GC,WAAY,IAAI,QtBk6GhB,aAAc,IAAI,MAAM,YsBh6GxB,YAAA,IAAA,MAAA,YAKA,UADF,QvBo5GC,SAAA,SuB94GC,uBACA,QAAA,EAEA,eACA,SAAA,SACA,IAAA,KACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,MAAA,KACA,UAAA,MACA,QAAA,IAAA,EACA,OAAA,IAAA,EAAA,EACA,UAAA,KACA,WAAA,KACA,WAAA,KnBsBA,iBAAA,KACQ,wBAAA,YmBrBR,gBAAA,YtB+5GA,OsB/5GA,IAAA,MAAA,KvBk5GD,OAAA,IAAA,MAAA,gBuB74GC,cAAA,IACE,mBAAA,EAAA,IAAA,KAAA,iBACA,WAAA,EAAA,IAAA,KAAA,iBAzBJ,0BCzBE,MAAA,EACA,KAAA,KAEA,wBxBo8GD,OAAA,IuB96GC,OAAQ,IAAI,EAmCV,SAAA,OACA,iBAAA,QAEA,oBACA,QAAA,MACA,QAAA,IAAA,KACA,MAAA,KvB84GH,YAAA,IuBx4GC,YAAA,WtBw5GA,MAAO,KsBt5GL,YAAA,OvB44GH,0BuB14GG,0BAMF,MAAA,QtBo5GA,gBAAiB,KACjB,iBAAkB,QsBj5GhB,yBAEA,+BADA,+BvBu4GH,MAAA,KuB73GC,gBAAA,KtB64GA,iBAAkB,QAClB,QAAS,EDZV,2BuB33GC,iCAAA,iCAEE,MAAA,KEzGF,iCF2GE,iCAEA,gBAAA,KvB63GH,OAAA,YuBx3GC,iBAAkB,YAGhB,iBAAA,KvBw3GH,OAAA,0DuBn3GG,qBvBs3GH,QAAA,MuB72GC,QACA,QAAA,EAQF,qBACE,MAAA,EACA,KAAA,KAIF,oBACE,MAAA,KACA,KAAA,EAEA,iBACA,QAAA,MACA,QAAA,IAAA,KvBw2GD,UAAA,KuBp2GC,YAAa,WACb,MAAA,KACA,YAAA,OAEA,mBACA,SAAA,MACA,IAAA,EvBs2GD,MAAA,EuBl2GC,OAAQ,EACR,KAAA,EACA,QAAA,IAQF,2BtB42GE,MAAO,EsBx2GL,KAAA,KAEA,eACA,sCvB41GH,QAAA,GuBn2GC,WAAY,EtBm3GZ,cAAe,IAAI,OsBx2GjB,cAAA,IAAA,QAEA,uBvB41GH,8CuBv0GC,IAAK,KAXL,OAAA,KApEA,cAAA,IvB25GC,yBuBv1GD,6BA1DA,MAAA,EACA,KAAA,KvBq5GD,kC0BpiHG,MAAO,KzBojHP,KAAM,GyBhjHR,W1BsiHD,oB0B1iHC,SAAU,SzB0jHV,QAAS,ayBpjHP,eAAA,OAGA,yB1BsiHH,gBCgBC,SAAU,SACV,MAAO,KyB7iHT,gC1BsiHC,gCCYD,+BAFA,+ByBhjHA,uBANM,uBzBujHN,sBAFA,sBAQE,QAAS,EyBljHP,qB1BuiHH,2B0BliHD,2BACE,iC1BoiHD,YAAA,KCgBD,aACE,YAAa,KDZd,kB0B1iHD,wBAAA,0BzB2jHE,MAAO,KDZR,kB0B/hHD,wBACE,0B1BiiHD,YAAA,I0B5hHC,yE1B+hHD,cAAA,E2BhlHC,4BACG,YAAA,EDsDL,mEzB6iHE,wBAAyB,E0B5lHzB,2BAAA,E3BilHD,6C0B5hHD,8CACE,uBAAA,E1B8hHD,0BAAA,E0B3hHC,sB1B8hHD,MAAA,KCgBD,8D0B/mHE,cAAA,E3BomHD,mE0B3hHD,oECjEE,wBAAA,EACG,2BAAA,EDqEL,oEzB0iHE,uBAAwB,EyBxiHxB,0BAAA,EAiBF,mCACE,iCACA,QAAA,EAEF,iCACE,cAAA,IACA,aAAA,IAKF,oCtB/CE,cAAA,KACQ,aAAA,KsBkDR,iCtBnDA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBsByDV,0CACE,mBAAA,K1BugHD,WAAA,K0BngHC,YACA,YAAA,EAGF,eACE,aAAA,IAAA,IAAA,E1BqgHD,oBAAA,ECgBD,uBACE,aAAc,EAAE,IAAI,IyB1gHlB,yBACA,+BACA,oC1B+/GH,QAAA,M0BtgHC,MAAO,KAcH,MAAA,K1B2/GL,UAAA,KCgBD,oCACE,MAAO,KyBpgHL,8BACA,oC1By/GH,oC0Bp/GC,0CACE,WAAA,K1Bs/GH,YAAA,E2B/pHC,4DACC,cAAA,EAQA,sD3B4pHF,uBAAA,I0Bt/GC,wBAAA,IC/KA,2BAAA,EACC,0BAAA,EAQA,sD3BkqHF,uBAAA,E0Bv/GC,wBAAyB,EACzB,2BAAA,I1By/GD,0BAAA,ICgBD,uE0BtrHE,cAAA,E3B2qHD,4E0Bt/GD,6EC7LE,2BAAA,EACC,0BAAA,EDoMH,6EACE,uBAAA,EACA,wBAAA,EAEA,qB1Bo/GD,QAAA,M0Bx/GC,MAAO,KzBwgHP,aAAc,MyBjgHZ,gBAAA,SAEA,0B1Bq/GH,gC0B9/GC,QAAS,WAYP,MAAA,K1Bq/GH,MAAA,G0Bj/GG,qC1Bo/GH,MAAA,KCgBD,+CACE,KAAM,KyB7+GF,gDAFA,6C1Bs+GL,2D0Br+GK,wDEzOJ,SAAU,SACV,KAAA,cACA,eAAA,K5BitHD,a4B7sHC,SAAA,SACE,QAAA,MACA,gBAAA,S5BgtHH,0B4BxtHC,MAAO,KAeL,cAAA,EACA,aAAA,EAOA,2BACA,SAAA,S5BusHH,QAAA,E4BrsHG,MAAA,KACE,MAAA,K5BusHL,cAAA,ECgBD,iCACE,QAAS,EiBnrHT,8BACA,mCACA,sCACA,OAAA,KlBwqHD,QAAA,KAAA,KkBtqHC,UAAA,KjBsrHA,YAAa,UACb,cAAe,IiBrrHb,oClB0qHH,yCkBvqHC,4CjBurHA,OAAQ,KACR,YAAa,KDTd,8C4B/sHD,mDAAA,sD3B0tHA,sCACA,2CiBzrHI,8CjB8rHF,OAAQ,KiB1sHR,8BACA,mCACA,sCACA,OAAA,KlB+rHD,QAAA,IAAA,KkB7rHC,UAAA,KjB6sHA,YAAa,IACb,cAAe,IiB5sHb,oClBisHH,yCkB9rHC,4CjB8sHA,OAAQ,KACR,YAAa,KDTd,8C4B7tHD,mDAAA,sD3BwuHA,sCACA,2CiBhtHI,8CjBqtHF,OAAQ,K2BzuHR,2B5B6tHD,mB4B7tHC,iB3B8uHA,QAAS,W2BzuHX,8D5B6tHC,sD4B7tHD,oDAEE,cAAA,EAEA,mB5B+tHD,iB4B1tHC,MAAO,GACP,YAAA,OACA,eAAA,OAEA,mBACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,K5B4tHD,WAAA,O4BztHC,iBAAA,KACE,OAAA,IAAA,MAAA,KACA,cAAA,I5B4tHH,4B4BztHC,QAAA,IAAA,KACE,UAAA,KACA,cAAA,I5B4tHH,4B4B/uHC,QAAS,KAAK,K3B+vHd,UAAW,K2BruHT,cAAA,IAKJ,wCAAA,qC3BquHE,WAAY,EAEd,uCACA,+BACA,kC0B70HE,6CACG,8CC4GL,6D5BqtHC,wE4BptHC,wBAAA,E5ButHD,2BAAA,ECgBD,+BACE,aAAc,EAEhB,sCACA,8B2BhuHA,+D5BstHC,oDCWD,iC0Bl1HE,4CACG,6CCiHH,uBAAA,E5BwtHD,0BAAA,E4BltHC,8BAGA,YAAA,E5BotHD,iB4BxtHC,SAAU,SAUR,UAAA,E5BitHH,YAAA,O4B/sHK,sB5BktHL,SAAA,SCgBD,2BACE,YAAa,K2BxtHb,6BAAA,4B5B4sHD,4B4BzsHK,QAAA,EAGJ,kCAAA,wCAGI,aAAA,K5B4sHL,iC6B12HD,uCACE,QAAA,EACA,YAAA,K7B62HD,K6B/2HC,aAAc,EAOZ,cAAA,EACA,WAAA,KARJ,QAWM,SAAA,SACA,QAAA,M7B42HL,U6B12HK,SAAA,S5B03HJ,QAAS,M4Bx3HH,QAAA,KAAA,KAMJ,gB7Bu2HH,gB6Bt2HK,gBAAA,K7By2HL,iBAAA,KCgBD,mB4Br3HQ,MAAA,KAGA,yBADA,yB7B02HP,MAAA,K6Bl2HG,gBAAA,K5Bk3HF,OAAQ,YACR,iBAAkB,Y4B/2Hd,aAzCN,mB7B64HC,mBwBh5HC,iBAAA,KACA,aAAA,QAEA,kBxBm5HD,OAAA,I6Bn5HC,OAAQ,IAAI,EA0DV,SAAA,O7B41HH,iBAAA,Q6Bl1HC,c7Bq1HD,UAAA,K6Bn1HG,UAEA,cAAA,IAAA,MAAA,KALJ,aASM,MAAA,KACA,cAAA,KAEA,e7Bo1HL,aAAA,I6Bn1HK,YAAA,WACE,OAAA,IAAA,MAAA,Y7Bq1HP,cAAA,IAAA,IAAA,EAAA,ECgBD,qBACE,aAAc,KAAK,KAAK,K4B51HlB,sBAEA,4BADA,4BAEA,MAAA,K7Bi1HP,OAAA,Q6B50HC,iBAAA,KAqDA,OAAA,IAAA,MAAA,KA8BA,oBAAA,YAnFA,wBAwDE,MAAA,K7B2xHH,cAAA,E6BzxHK,2BACA,MAAA,KA3DJ,6BAgEE,cAAA,IACA,WAAA,OAYJ,iDA0DE,IAAK,KAjED,KAAA,K7B0xHH,yB6BztHD,2BA9DM,QAAA,W7B0xHL,MAAA,G6Bn2HD,6BAuFE,cAAA,GAvFF,6B5Bw3HA,aAAc,EACd,cAAe,IDZhB,kC6BtuHD,wCA3BA,wCATM,OAAA,IAAA,MAAA,K7B+wHH,yB6B3uHD,6B5B2vHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,kC6B92HD,wC7B+2HD,wC6B72HG,oBAAA,MAIE,c7B+2HL,MAAA,K6B52HK,gB7B+2HL,cAAA,ICgBD,iBACE,YAAa,I4Bv3HP,uBAQR,6B7Bo2HC,6B6Bl2HG,MAAA,K7Bq2HH,iBAAA,Q6Bn2HK,gBACA,MAAA,KAYN,mBACE,WAAA,I7B41HD,YAAA,E6Bz1HG,e7B41HH,MAAA,K6B11HK,kBACA,MAAA,KAPN,oBAYI,cAAA,IACA,WAAA,OAYJ,wCA0DE,IAAK,KAjED,KAAA,K7B21HH,yB6B1xHD,kBA9DM,QAAA,W7B21HL,MAAA,G6Bl1HD,oBACA,cAAA,GAIE,oBACA,cAAA,EANJ,yB5B02HE,aAAc,EACd,cAAe,IDZhB,8B6B1yHD,oCA3BA,oCATM,OAAA,IAAA,MAAA,K7Bm1HH,yB6B/yHD,yB5B+zHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,8B6Bx0HD,oC7By0HD,oC6Bv0HG,oBAAA,MAGA,uB7B00HH,QAAA,K6B/zHC,qBF3OA,QAAA,M3B+iID,yB8BxiIC,WAAY,KACZ,uBAAA,EACA,wBAAA,EAEA,Q9B0iID,SAAA,S8BliIC,WAAY,KA8nBZ,cAAe,KAhoBb,OAAA,IAAA,MAAA,Y9ByiIH,yB8BzhIC,QAgnBE,cAAe,K9B86GlB,yB8BjhIC,eACA,MAAA,MAGA,iBACA,cAAA,KAAA,aAAA,KAEA,WAAA,Q9BkhID,2BAAA,M8BhhIC,WAAA,IAAA,MAAA,YACE,mBAAA,MAAA,EAAA,IAAA,EAAA,qB9BkhIH,WAAA,MAAA,EAAA,IAAA,EAAA,qB8Bz7GD,oBArlBI,WAAA,KAEA,yBAAA,iB9BkhID,MAAA,K8BhhIC,WAAA,EACE,mBAAA,KACA,WAAA,KAEA,0B9BkhIH,QAAA,gB8B/gIC,OAAA,eACE,eAAA,E9BihIH,SAAA,kBCkBD,oBACE,WAAY,QDZf,sC8B/gIK,mC9B8gIH,oC8BzgIC,cAAe,E7B4hIf,aAAc,G6Bj+GlB,sCAnjBE,mC7ByhIA,WAAY,MDdX,4D8BngID,sC9BogID,mCCkBG,WAAY,O6B3gId,kCANE,gC9BsgIH,4B8BvgIG,0BAuiBF,aAAc,M7Bm/Gd,YAAa,MAEf,yBDZC,kC8B3gIK,gC9B0gIH,4B8B3gIG,0BAcF,aAAc,EAChB,YAAA,GAMF,mBA8gBE,QAAS,KAhhBP,aAAA,EAAA,EAAA,I9BkgIH,yB8B7/HC,mB7B+gIE,cAAe,G6B1gIjB,qBADA,kB9BggID,SAAA,M8Bz/HC,MAAO,EAggBP,KAAM,E7B4gHN,QAAS,KDdR,yB8B7/HD,qB9B8/HD,kB8B7/HC,cAAA,GAGF,kBACE,IAAA,EACA,aAAA,EAAA,EAAA,I9BigID,qB8B1/HC,OAAQ,EACR,cAAA,EACA,aAAA,IAAA,EAAA,EAEA,cACA,MAAA,K9B4/HD,OAAA,K8B1/HC,QAAA,KAAA,K7B4gIA,UAAW,K6B1gIT,YAAA,KAIA,oBAbJ,oB9BwgIC,gBAAA,K8Bv/HG,kB7B0gIF,QAAS,MDdR,yBACF,iC8Bh/HC,uCACA,YAAA,OAGA,eC9LA,SAAA,SACA,MAAA,MD+LA,QAAA,IAAA,KACA,WAAA,IACA,aAAA,KACA,cAAA,I9Bm/HD,iBAAA,Y8B/+HC,iBAAA,KACE,OAAA,IAAA,MAAA,Y9Bi/HH,cAAA,I8B5+HG,qBACA,QAAA,EAEA,yB9B++HH,QAAA,M8BrgIC,MAAO,KAyBL,OAAA,I9B++HH,cAAA,I8BpjHD,mCAvbI,WAAA,I9Bg/HH,yB8Bt+HC,eACA,QAAA,MAGE,YACA,OAAA,MAAA,M9By+HH,iB8B58HC,YAAA,KA2YA,eAAgB,KAjaZ,YAAA,KAEA,yBACA,iCACA,SAAA,OACA,MAAA,KACA,MAAA,KAAA,WAAA,E9Bs+HH,iBAAA,Y8B3kHC,OAAQ,E7B8lHR,mBAAoB,K6Bt/HhB,WAAA,KAGA,kDAqZN,sC9BklHC,QAAA,IAAA,KAAA,IAAA,KCmBD,sC6Bv/HQ,YAAA,KAmBR,4C9Bs9HD,4C8BvlHG,iBAAkB,M9B4lHnB,yB8B5lHD,YAtYI,MAAA,K9Bq+HH,OAAA,E8Bn+HK,eACA,MAAA,K9Bu+HP,iB8B39HG,YAAa,KACf,eAAA,MAGA,aACA,QAAA,KAAA,K1B9NA,WAAA,IACQ,aAAA,M2B/DR,cAAA,IACA,YAAA,M/B4vID,WAAA,IAAA,MAAA,YiBtuHC,cAAe,IAAI,MAAM,YAwEzB,mBAAoB,MAAM,EAAE,IAAI,EAAE,qBAAyB,EAAE,IAAI,EAAE,qBAtI/D,WAAA,MAAA,EAAA,IAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,qBAEA,yBjBwyHH,yBiBpqHC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBuyHH,2BiBzqHC,QAAS,aAxHP,MAAA,KjBoyHH,eAAA,OiBhyHG,kCACA,QAAA,aAmHJ,0BhBmsHE,QAAS,aACT,eAAgB,OgB5yHd,wCjB6xHH,6CiBrrHD,2CjBwrHC,MAAA,KiB5xHG,wCACA,MAAA,KAmGJ,4BhB+sHE,cAAe,EgB3yHb,eAAA,OAGA,uBADA,oBjB6xHH,QAAA,aiBnsHC,WAAY,EhBstHZ,cAAe,EgB5yHX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB4sHC,sCiBvxHG,SAAA,SjB0xHH,YAAA,E8BngID,kDAmWE,IAAK,GAvWH,yBACE,yB9B8gIL,cAAA,I8B5/HD,oCAoVE,cAAe,GA1Vf,yBACA,aACA,MAAA,KACA,YAAA,E1BzPF,eAAA,EACQ,aAAA,EJmwIP,YAAA,EACF,OAAA,E8BngIG,mBAAoB,KACtB,WAAA,M9BugID,8B8BngIC,WAAY,EACZ,uBAAA,EHzUA,wBAAA,EAQA,mDACC,cAAA,E3By0IF,uBAAA,I8B//HC,wBAAyB,IChVzB,2BAAA,EACA,0BAAA,EDkVA,YCnVA,WAAA,IACA,cAAA,IDqVA,mBCtVA,WAAA,KACA,cAAA,KD+VF,mBChWE,WAAA,KACA,cAAA,KDuWF,aAsSE,WAAY,KA1SV,cAAA,KAEA,yB9B+/HD,aACF,MAAA,K8Bl+HG,aAAc,KAhBhB,YAAA,MACA,yBE5WA,aF8WE,MAAA,eAFF,cAKI,MAAA,gB9Bu/HH,aAAA,M8B7+HD,4BACA,aAAA,GADF,gBAKI,iBAAA,Q9Bg/HH,aAAA,QCmBD,8B6BhgIM,MAAA,KARN,oC9B0/HC,oC8B5+HG,MAAA,Q9B++HH,iBAAA,Y8B1+HK,6B9B6+HL,MAAA,KCmBD,iC6B5/HQ,MAAA,KAKF,uC9By+HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bz/HZ,sCAIF,4C9Bu+HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bv/HZ,wCAxCR,8C9BihIC,8C8Bn+HG,MAAA,K9Bs+HH,iBAAA,YCmBD,+B6Bt/HM,aAAA,KAGA,qCApDN,qC9B2hIC,iBAAA,KCmBD,yC6Bp/HI,iBAAA,KAOE,iCAAA,6B7Bk/HJ,aAAc,Q6B9+HR,oCAiCN,0C9B+7HD,0C8B3xHC,MAAO,KA7LC,iBAAA,QACA,yB7B8+HR,sD6B5+HU,MAAA,KAKF,4D9By9HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bz+HV,2DAIF,iE9Bu9HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bv+HV,6D9B09HX,mEADE,mE8B1jIC,MAAO,KA8GP,iBAAA,aAEE,6B9Bi9HL,MAAA,K8B58HG,mC9B+8HH,MAAA,KCmBD,0B6B/9HM,MAAA,KAIA,gCAAA,gC7Bg+HJ,MAAO,K6Bt9HT,0CARQ,0CASN,mD9Bu8HD,mD8Bt8HC,MAAA,KAFF,gBAKI,iBAAA,K9B08HH,aAAA,QCmBD,8B6B19HM,MAAA,QARN,oC9Bo9HC,oC8Bt8HG,MAAA,K9By8HH,iBAAA,Y8Bp8HK,6B9Bu8HL,MAAA,QCmBD,iC6Bt9HQ,MAAA,QAKF,uC9Bm8HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bn9HZ,sCAIF,4C9Bi8HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bj9HZ,wCAxCR,8C9B2+HC,8C8B57HG,MAAA,K9B+7HH,iBAAA,YCmBD,+B6B/8HM,aAAA,KAGA,qCArDN,qC9Bq/HC,iBAAA,KCmBD,yC6B78HI,iBAAA,KAME,iCAAA,6B7B48HJ,aAAc,Q6Bx8HR,oCAuCN,0C9Bm5HD,0C8B33HC,MAAO,KAvDC,iBAAA,QAuDV,yBApDU,kE9Bs7HP,aAAA,Q8Bn7HO,0D9Bs7HP,iBAAA,QCmBD,sD6Bt8HU,MAAA,QAKF,4D9Bm7HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bn8HV,2DAIF,iE9Bi7HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bj8HV,6D9Bo7HX,mEADE,mE8B1hIC,MAAO,KA+GP,iBAAA,aAEE,6B9Bg7HL,MAAA,Q8B36HG,mC9B86HH,MAAA,KCmBD,0B6B97HM,MAAA,QAIA,gCAAA,gC7B+7HJ,MAAO,KgCvkJT,0CH0oBQ,0CGzoBN,mDjCwjJD,mDiCvjJC,MAAA,KAEA,YACA,QAAA,IAAA,KjC2jJD,cAAA,KiChkJC,WAAY,KAQV,iBAAA,QjC2jJH,cAAA,IiCxjJK,eACA,QAAA,ajC4jJL,yBiCxkJC,QAAS,EAAE,IAkBT,MAAA,KjCyjJH,QAAA,SkC5kJC,oBACA,MAAA,KAEA,YlC+kJD,QAAA,akCnlJC,aAAc,EAOZ,OAAA,KAAA,ElC+kJH,cAAA,ICmBD,eiC/lJM,QAAA,OAEA,iBACA,oBACA,SAAA,SACA,MAAA,KACA,QAAA,IAAA,KACA,YAAA,KACA,YAAA,WlCglJL,MAAA,QkC9kJG,gBAAA,KjCimJF,iBAAkB,KiC9lJZ,OAAA,IAAA,MAAA,KPVH,6B3B2lJJ,gCkC7kJG,YAAA,EjCgmJF,uBAAwB,I0BvnJxB,0BAAA,I3BymJD,4BkCxkJG,+BjC2lJF,wBAAyB,IACzB,2BAA4B,IiCxlJxB,uBAFA,uBAGA,0BAFA,0BlC8kJL,QAAA,EkCtkJG,MAAA,QjCylJF,iBAAkB,KAClB,aAAc,KAEhB,sBiCvlJM,4BAFA,4BjC0lJN,yBiCvlJM,+BAFA,+BAGA,QAAA,ElC2kJL,MAAA,KkCloJC,OAAQ,QjCqpJR,iBAAkB,QAClB,aAAc,QiCnlJV,wBAEA,8BADA,8BjColJN,2BiCtlJM,iCjCulJN,iCDZC,MAAA,KkC/jJC,OAAQ,YjCklJR,iBAAkB,KkC7pJd,aAAA,KAEA,oBnC8oJL,uBmC5oJG,QAAA,KAAA,KlC+pJF,UAAW,K0B1pJX,YAAA,U3B4oJD,gCmC3oJG,mClC8pJF,uBAAwB,I0BvqJxB,0BAAA,I3BypJD,+BkC1kJD,kCjC6lJE,wBAAyB,IkC7qJrB,2BAAA,IAEA,oBnC8pJL,uBmC5pJG,QAAA,IAAA,KlC+qJF,UAAW,K0B1qJX,YAAA,I3B4pJD,gCmC3pJG,mClC8qJF,uBAAwB,I0BvrJxB,0BAAA,I3ByqJD,+BoC3qJD,kCACE,wBAAA,IACA,2BAAA,IAEA,OpC6qJD,aAAA,EoCjrJC,OAAQ,KAAK,EAOX,WAAA,OpC6qJH,WAAA,KCmBD,UmC7rJM,QAAA,OAEA,YACA,eACA,QAAA,apC8qJL,QAAA,IAAA,KoC5rJC,iBAAkB,KnC+sJlB,OAAQ,IAAI,MAAM,KmC5rJd,cAAA,KAnBN,kBpCisJC,kBCmBC,gBAAiB,KmCzrJb,iBAAA,KA3BN,eAAA,kBAkCM,MAAA,MAlCN,mBAAA,sBnC6tJE,MAAO,KmClrJH,mBAEA,yBADA,yBpCqqJL,sBqCltJC,MAAO,KACP,OAAA,YACA,iBAAA,KAEA,OACA,QAAA,OACA,QAAA,KAAA,KAAA,KACA,UAAA,IACA,YAAA,IACA,YAAA,EACA,MAAA,KrCotJD,WAAA,OqChtJG,YAAA,OpCmuJF,eAAgB,SoCjuJZ,cAAA,MrCotJL,cqCltJK,cAKJ,MAAA,KACE,gBAAA,KrC+sJH,OAAA,QqC1sJG,aACA,QAAA,KAOJ,YCtCE,SAAA,StC+uJD,IAAA,KCmBD,eqC7vJM,iBAAA,KALJ,2BD0CF,2BrC4sJC,iBAAA,QCmBD,eqCpwJM,iBAAA,QALJ,2BD8CF,2BrC+sJC,iBAAA,QCmBD,eqC3wJM,iBAAA,QALJ,2BDkDF,2BrCktJC,iBAAA,QCmBD,YqClxJM,iBAAA,QALJ,wBDsDF,wBrCqtJC,iBAAA,QCmBD,eqCzxJM,iBAAA,QALJ,2BD0DF,2BrCwtJC,iBAAA,QCmBD,cqChyJM,iBAAA,QCDJ,0BADF,0BAEE,iBAAA,QAEA,OACA,QAAA,aACA,UAAA,KACA,QAAA,IAAA,IACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OvCqxJD,YAAA,OuClxJC,eAAA,OACE,iBAAA,KvCoxJH,cAAA,KuC/wJG,aACA,QAAA,KAGF,YtCkyJA,SAAU,SsChyJR,IAAA,KAMA,0BvC4wJH,eCmBC,IAAK,EsC7xJD,QAAA,IAAA,IvCgxJL,cuC9wJK,cAKJ,MAAA,KtC4xJA,gBAAiB,KsC1xJf,OAAA,QvC4wJH,+BuCxwJC,4BACE,MAAA,QvC0wJH,iBAAA,KuCtwJG,wBvCywJH,MAAA,MuCrwJG,+BvCwwJH,aAAA,IwCj0JC,uBACA,YAAA,IAEA,WACA,YAAA,KxCo0JD,eAAA,KwCz0JC,cAAe,KvC41Jf,MAAO,QuCn1JL,iBAAA,KAIA,eAbJ,cAcI,MAAA,QxCo0JH,awCl1JC,cAAe,KAmBb,UAAA,KxCk0JH,YAAA,ICmBD,cuCh1JI,iBAAA,QAEA,sBxCi0JH,4BwC31JC,cAAe,KA8Bb,aAAA,KxCg0JH,cAAA,IwC7yJD,sBAfI,UAAA,KxCi0JD,oCwC9zJC,WvCi1JA,YAAa,KuC/0JX,eAAA,KxCi0JH,sBwCvzJD,4BvC00JE,cAAe,KuC90Jb,aAAA,KC5CJ,ezC42JD,cyC32JC,UAAA,MAGA,WACA,QAAA,MACA,QAAA,IACA,cAAA,KrCiLA,YAAA,WACK,iBAAA,KACG,OAAA,IAAA,MAAA,KJ8rJT,cAAA,IyCx3JC,mBAAoB,OAAO,IAAI,YxC24J1B,cAAe,OAAO,IAAI,YwC93J7B,WAAA,OAAA,IAAA,YAKF,iBzC22JD,eCmBC,aAAc,KACd,YAAa,KwCv3JX,mBA1BJ,kBzCk4JC,kByCv2JG,aAAA,QCzBJ,oBACE,QAAA,IACA,MAAA,KAEA,O1Cs4JD,QAAA,K0C14JC,cAAe,KAQb,OAAA,IAAA,MAAA,YAEA,cAAA,IAVJ,UAeI,WAAA,E1Ck4JH,MAAA,QCmBD,mByC/4JI,YAAA,IArBJ,SAyBI,U1C+3JH,cAAA,ECmBD,WyCx4JE,WAAA,IAFF,mBAAA,mBAMI,cAAA,KAEA,0BACA,0B1Cy3JH,SAAA,S0Cj3JC,IAAK,KCvDL,MAAA,MACA,MAAA,Q3C46JD,e0Ct3JC,MAAO,QClDL,iBAAA,Q3C26JH,aAAA,Q2Cx6JG,kB3C26JH,iBAAA,Q2Cn7JC,2BACA,MAAA,Q3Cu7JD,Y0C73JC,MAAO,QCtDL,iBAAA,Q3Cs7JH,aAAA,Q2Cn7JG,e3Cs7JH,iBAAA,Q2C97JC,wBACA,MAAA,Q3Ck8JD,e0Cp4JC,MAAO,QC1DL,iBAAA,Q3Ci8JH,aAAA,Q2C97JG,kB3Ci8JH,iBAAA,Q2Cz8JC,2BACA,MAAA,Q3C68JD,c0C34JC,MAAO,QC9DL,iBAAA,Q3C48JH,aAAA,Q2Cz8JG,iB3C48JH,iBAAA,Q4C78JC,0BAAQ,MAAA,QACR,wCAAQ,K5Cm9JP,oBAAA,KAAA,E4C/8JD,GACA,oBAAA,EAAA,GACA,mCAAQ,K5Cq9JP,oBAAA,KAAA,E4Cv9JD,GACA,oBAAA,EAAA,GACA,gCAAQ,K5Cq9JP,oBAAA,KAAA,E4C78JD,GACA,oBAAA,EAAA,GAGA,UACA,OAAA,KxCsCA,cAAA,KACQ,SAAA,OJ26JT,iBAAA,Q4C78JC,cAAe,IACf,mBAAA,MAAA,EAAA,IAAA,IAAA,eACA,WAAA,MAAA,EAAA,IAAA,IAAA,eAEA,cACA,MAAA,KACA,MAAA,EACA,OAAA,KACA,UAAA,KxCyBA,YAAA,KACQ,MAAA,KAyHR,WAAA,OACK,iBAAA,QACG,mBAAA,MAAA,EAAA,KAAA,EAAA,gBJ+zJT,WAAA,MAAA,EAAA,KAAA,EAAA,gB4C18JC,mBAAoB,MAAM,IAAI,K3Cq+JzB,cAAe,MAAM,IAAI,K4Cp+J5B,WAAA,MAAA,IAAA,KDEF,sBCAE,gCDAF,iBAAA,yK5C88JD,iBAAA,oK4Cv8JC,iBAAiB,iK3Cm+JjB,wBAAyB,KAAK,KG/gK9B,gBAAA,KAAA,KJy/JD,qBIv/JS,+BwCmDR,kBAAmB,qBAAqB,GAAG,OAAO,SErElD,aAAA,qBAAA,GAAA,OAAA,S9C4gKD,UAAA,qBAAA,GAAA,OAAA,S6Cz9JG,sBACA,iBAAA,Q7C69JH,wC4Cx8JC,iBAAkB,yKEzElB,iBAAA,oK9CohKD,iBAAA,iK6Cj+JG,mBACA,iBAAA,Q7Cq+JH,qC4C58JC,iBAAkB,yKE7ElB,iBAAA,oK9C4hKD,iBAAA,iK6Cz+JG,sBACA,iBAAA,Q7C6+JH,wC4Ch9JC,iBAAkB,yKEjFlB,iBAAA,oK9CoiKD,iBAAA,iK6Cj/JG,qBACA,iBAAA,Q7Cq/JH,uC+C5iKC,iBAAkB,yKAElB,iBAAA,oK/C6iKD,iBAAA,iK+C1iKG,O/C6iKH,WAAA,KC4BD,mB8CnkKE,WAAA,E/C4iKD,O+CxiKD,YACE,SAAA,O/C0iKD,KAAA,E+CtiKC,Y/CyiKD,MAAA,Q+CriKG,c/CwiKH,QAAA,MC4BD,4B8C9jKE,UAAA,KAGF,aAAA,mBAEE,aAAA,KAGF,YAAA,kB9C+jKE,cAAe,K8CxjKjB,YAHE,Y/CoiKD,a+ChiKC,QAAA,W/CmiKD,eAAA,I+C/hKC,c/CkiKD,eAAA,O+C7hKC,cACA,eAAA,OAMF,eACE,WAAA,EACA,cAAA,ICvDF,YAEE,aAAA,EACA,WAAA,KAQF,YACE,aAAA,EACA,cAAA,KAGA,iBACA,SAAA,SACA,QAAA,MhD6kKD,QAAA,KAAA,KgD1kKC,cAAA,KrB3BA,iBAAA,KACC,OAAA,IAAA,MAAA,KqB6BD,6BACE,uBAAA,IrBvBF,wBAAA,I3BsmKD,4BgDpkKC,cAAe,E/CgmKf,2BAA4B,I+C9lK5B,0BAAA,IAFF,kBAAA,uBAKI,MAAA,KAIF,2CAAA,gD/CgmKA,MAAO,K+C5lKL,wBAFA,wBhDykKH,6BgDxkKG,6BAKF,MAAO,KACP,gBAAA,KACA,iBAAA,QAKA,uB/C4lKA,MAAO,KACP,WAAY,K+CzlKV,0BhDmkKH,gCgDlkKG,gCALF,MAAA,K/CmmKA,OAAQ,YACR,iBAAkB,KDxBnB,mDgD5kKC,yDAAA,yD/CymKA,MAAO,QDxBR,gDgDhkKC,sDAAA,sD/C6lKA,MAAO,K+CzlKL,wBAEA,8BADA,8BhDmkKH,QAAA,EgDxkKC,MAAA,K/ComKA,iBAAkB,QAClB,aAAc,QAEhB,iDDpBC,wDCuBD,uDADA,uD+CzmKE,8DAYI,6D/C4lKN,uD+CxmKE,8D/C2mKF,6DAKE,MAAO,QDxBR,8CiD1qKG,oDADF,oDAEE,MAAA,QAEA,yBhDusKF,MAAO,QgDrsKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDwsKJ,MAAO,QDtBR,gCiDhrKO,gCAGF,qCAFE,qChD2sKN,MAAO,QACP,iBAAkB,QAEpB,iCgDvsKQ,uCAFA,uChD0sKR,sCDtBC,4CiDnrKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,sBhDouKF,MAAO,QgDluKH,iBAAA,QAFF,uBAAA,4BAKI,MAAA,QAGF,gDAAA,qDhDquKJ,MAAO,QDtBR,6BiD7sKO,6BAGF,kCAFE,kChDwuKN,MAAO,QACP,iBAAkB,QAEpB,8BgDpuKQ,oCAFA,oChDuuKR,mCDtBC,yCiDhtKO,yCArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,yBhDiwKF,MAAO,QgD/vKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDkwKJ,MAAO,QDtBR,gCiD1uKO,gCAGF,qCAFE,qChDqwKN,MAAO,QACP,iBAAkB,QAEpB,iCgDjwKQ,uCAFA,uChDowKR,sCDtBC,4CiD7uKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,wBhD8xKF,MAAO,QgD5xKH,iBAAA,QAFF,yBAAA,8BAKI,MAAA,QAGF,kDAAA,uDhD+xKJ,MAAO,QDtBR,+BiDvwKO,+BAGF,oCAFE,oChDkyKN,MAAO,QACP,iBAAkB,QAEpB,gCgD9xKQ,sCAFA,sChDiyKR,qCDtBC,2CiD1wKO,2CDkGN,MAAO,KACP,iBAAA,QACA,aAAA,QAEF,yBACE,WAAA,EACA,cAAA,IE1HF,sBACE,cAAA,EACA,YAAA,IAEA,O9C0DA,cAAA,KACQ,iBAAA,KJ6uKT,OAAA,IAAA,MAAA,YkDnyKC,cAAe,IACf,mBAAA,EAAA,IAAA,IAAA,gBlDqyKD,WAAA,EAAA,IAAA,IAAA,gBkD/xKC,YACA,QAAA,KvBnBC,e3BuzKF,QAAA,KAAA,KkDtyKC,cAAe,IAAI,MAAM,YAMvB,uBAAA,IlDmyKH,wBAAA,IkD7xKC,0CACA,MAAA,QAEA,alDgyKD,WAAA,EkDpyKC,cAAe,EjDg0Kf,UAAW,KACX,MAAO,QDtBR,oBkD1xKC,sBjDkzKF,eiDxzKI,mBAKJ,qBAEE,MAAA,QvBvCA,cACC,QAAA,KAAA,K3Bs0KF,iBAAA,QkDrxKC,WAAY,IAAI,MAAM,KjDizKtB,2BAA4B,IiD9yK1B,0BAAA,IAHJ,mBAAA,mCAMM,cAAA,ElDwxKL,oCkDnxKG,oDjD+yKF,aAAc,IAAI,EiD7yKZ,cAAA,EvBtEL,4D3B61KF,4EkDjxKG,WAAA,EjD6yKF,uBAAwB,IiD3yKlB,wBAAA,IvBtEL,0D3B21KF,0EkD1yKC,cAAe,EvB1Df,2BAAA,IACC,0BAAA,IuB0FH,+EAEI,uBAAA,ElD8wKH,wBAAA,EkD1wKC,wDlD6wKD,iBAAA,EC4BD,0BACE,iBAAkB,EiDlyKpB,8BlD0wKC,ckD1wKD,gCjDuyKE,cAAe,EiDvyKjB,sCAQM,sBlDwwKL,wCC4BC,cAAe,K0Br5Kf,aAAA,KuByGF,wDlDqxKC,0BC4BC,uBAAwB,IACxB,wBAAyB,IiDlzK3B,yFAoBQ,yFlDwwKP,2DkDzwKO,2DjDqyKN,uBAAwB,IACxB,wBAAyB,IAK3B,wGiD9zKA,wGjD4zKA,wGDtBC,wGCuBD,0EiD7zKA,0EjD2zKA,0EiDnyKU,0EjD2yKR,uBAAwB,IAK1B,uGiDx0KA,uGjDs0KA,uGDtBC,uGCuBD,yEiDv0KA,yEjDq0KA,yEiDzyKU,yEvB7HR,wBAAA,IuBiGF,sDlDqzKC,yBC4BC,2BAA4B,IAC5B,0BAA2B,IiDxyKrB,qFA1CR,qFAyCQ,wDlDmxKP,wDC4BC,2BAA4B,IAC5B,0BAA2B,IAG7B,oGDtBC,oGCwBD,oGiD91KA,oGjD21KA,uEiD7yKU,uEjD+yKV,uEiD71KA,uEjDm2KE,0BAA2B,IAG7B,mGDtBC,mGCwBD,mGiDx2KA,mGjDq2KA,sEiDnzKU,sEjDqzKV,sEiDv2KA,sEjD62KE,2BAA4B,IiDlzK1B,0BlD2xKH,qCkDt1KD,0BAAA,qCA+DI,WAAA,IAAA,MAAA,KA/DJ,kDAAA,kDAmEI,WAAA,EAnEJ,uBAAA,yCjD23KE,OAAQ,EiDjzKA,+CjDqzKV,+CiD/3KA,+CjDi4KA,+CAEA,+CANA,+CDjBC,iECoBD,iEiDh4KA,iEjDk4KA,iEAEA,iEANA,iEAWE,YAAa,EiD3zKL,8CjD+zKV,8CiD74KA,8CjD+4KA,8CAEA,8CANA,8CDjBC,gECoBD,gEiD94KA,gEjDg5KA,gEAEA,gEANA,gEAWE,aAAc,EAIhB,+CiD35KA,+CjDy5KA,+CiDl0KU,+CjDq0KV,iEiD55KA,iEjD05KA,iEDtBC,iEC6BC,cAAe,EAEjB,8CiDn0KU,8CjDq0KV,8CiDr6KA,8CjDo6KA,gEDtBC,gECwBD,gEiDh0KI,gEACA,cAAA,EAUJ,yBACE,cAAA,ElDmyKD,OAAA,EkD/xKG,aACA,cAAA,KANJ,oBASM,cAAA,ElDkyKL,cAAA,IkD7xKG,2BlDgyKH,WAAA,IC4BD,4BiDxzKM,cAAA,EAKF,wDAvBJ,wDlDqzKC,WAAA,IAAA,MAAA,KkD5xKK,2BlD+xKL,WAAA,EmDlhLC,uDnDqhLD,cAAA,IAAA,MAAA,KmDlhLG,eACA,aAAA,KnDshLH,8BmDxhLC,MAAA,KAMI,iBAAA,QnDqhLL,aAAA,KmDlhLK,0DACA,iBAAA,KAGJ,qCAEI,MAAA,QnDmhLL,iBAAA,KmDpiLC,yDnDuiLD,oBAAA,KmDpiLG,eACA,aAAA,QnDwiLH,8BmD1iLC,MAAA,KAMI,iBAAA,QnDuiLL,aAAA,QmDpiLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDqiLL,iBAAA,KmDtjLC,yDnDyjLD,oBAAA,QmDtjLG,eACA,aAAA,QnD0jLH,8BmD5jLC,MAAA,QAMI,iBAAA,QnDyjLL,aAAA,QmDtjLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDujLL,iBAAA,QmDxkLC,yDnD2kLD,oBAAA,QmDxkLG,YACA,aAAA,QnD4kLH,2BmD9kLC,MAAA,QAMI,iBAAA,QnD2kLL,aAAA,QmDxkLK,uDACA,iBAAA,QAGJ,kCAEI,MAAA,QnDykLL,iBAAA,QmD1lLC,sDnD6lLD,oBAAA,QmD1lLG,eACA,aAAA,QnD8lLH,8BmDhmLC,MAAA,QAMI,iBAAA,QnD6lLL,aAAA,QmD1lLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnD2lLL,iBAAA,QmD5mLC,yDnD+mLD,oBAAA,QmD5mLG,cACA,aAAA,QnDgnLH,6BmDlnLC,MAAA,QAMI,iBAAA,QnD+mLL,aAAA,QmD5mLK,yDACA,iBAAA,QAGJ,oCAEI,MAAA,QnD6mLL,iBAAA,QoD5nLC,wDACA,oBAAA,QAEA,kBACA,SAAA,SpD+nLD,QAAA,MoDpoLC,OAAQ,EnDgqLR,QAAS,EACT,SAAU,OAEZ,yCmDtpLI,wBADA,yBAEA,yBACA,wBACA,SAAA,SACA,IAAA,EACA,OAAA,EpD+nLH,KAAA,EoD1nLC,MAAO,KACP,OAAA,KpD4nLD,OAAA,EoDvnLC,wBpD0nLD,eAAA,OqDppLC,uBACA,eAAA,IAEA,MACA,WAAA,KACA,QAAA,KjDwDA,cAAA,KACQ,iBAAA,QJgmLT,OAAA,IAAA,MAAA,QqD/pLC,cAAe,IASb,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACA,WAAA,MAAA,EAAA,IAAA,IAAA,gBAKJ,iBACE,aAAA,KACA,aAAA,gBAEF,SACE,QAAA,KACA,cAAA,ICtBF,SACE,QAAA,IACA,cAAA,IAEA,OACA,MAAA,MACA,UAAA,KjCRA,YAAA,IAGA,YAAA,ErBqrLD,MAAA,KsD7qLC,YAAA,EAAA,IAAA,EAAA,KrDysLA,OAAQ,kBqDvsLN,QAAA,GjCbF,aiCeE,ajCZF,MAAA,KrB6rLD,gBAAA,KsDzqLC,OAAA,QACE,OAAA,kBACA,QAAA,GAEA,aACA,mBAAA,KtD2qLH,QAAA,EuDhsLC,OAAQ,QACR,WAAA,IvDksLD,OAAA,EuD7rLC,YACA,SAAA,OAEA,OACA,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EAIA,QAAA,KvD6rLD,QAAA,KuD1rLC,SAAA,OnD+GA,2BAAA,MACI,QAAA,EAEI,0BAkER,mBAAA,kBAAA,IAAA,SAEK,cAAA,aAAA,IAAA,SACG,WAAA,UAAA,IAAA,SJ6gLT,kBAAA,kBuDhsLC,cAAA,kBnD2GA,aAAA,kBACI,UAAA,kBAEI,wBJwlLT,kBAAA,euDpsLK,cAAe,eACnB,aAAA,eACA,UAAA,eAIF,mBACE,WAAA,OACA,WAAA,KvDqsLD,cuDhsLC,SAAU,SACV,MAAA,KACA,OAAA,KAEA,eACA,SAAA,SnDaA,iBAAA,KACQ,wBAAA,YmDZR,gBAAA,YtD4tLA,OsD5tLA,IAAA,MAAA,KAEA,OAAA,IAAA,MAAA,evDksLD,cAAA,IuD9rLC,QAAS,EACT,mBAAA,EAAA,IAAA,IAAA,eACA,WAAA,EAAA,IAAA,IAAA,eAEA,gBACA,SAAA,MACA,IAAA,EACA,MAAA,EvDgsLD,OAAA,EuD9rLC,KAAA,ElCrEA,QAAA,KAGA,iBAAA,KkCmEA,qBlCtEA,OAAA,iBAGA,QAAA,EkCwEF,mBACE,OAAA,kBACA,QAAA,GAIF,cACE,QAAA,KvDgsLD,cAAA,IAAA,MAAA,QuD3rLC,qBACA,WAAA,KAKF,aACE,OAAA,EACA,YAAA,WAIF,YACE,SAAA,SACA,QAAA,KvD0rLD,cuD5rLC,QAAS,KAQP,WAAA,MACA,WAAA,IAAA,MAAA,QATJ,wBAaI,cAAA,EvDsrLH,YAAA,IuDlrLG,mCvDqrLH,YAAA,KuD/qLC,oCACA,YAAA,EAEA,yBACA,SAAA,SvDkrLD,IAAA,QuDhqLC,MAAO,KAZP,OAAA,KACE,SAAA,OvDgrLD,yBuD7qLD,cnDvEA,MAAA,MACQ,OAAA,KAAA,KmD2ER,eAAY,mBAAA,EAAA,IAAA,KAAA,evD+qLX,WAAA,EAAA,IAAA,KAAA,euDzqLD,UAFA,MAAA,OvDirLD,yBwD/zLC,UACA,MAAA,OCNA,SAEA,SAAA,SACA,QAAA,KACA,QAAA,MACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KACA,eAAA,ODHA,WAAA,OnCVA,aAAA,OAGA,UAAA,OrBs1LD,YAAA,OwD30LC,OAAA,iBnCdA,QAAA,ErB61LD,WAAA,KwD90LY,YAAmB,OAAA,kBxDk1L/B,QAAA,GwDj1LY,aAAmB,QAAA,IAAA,ExDq1L/B,WAAA,KwDp1LY,eAAmB,QAAA,EAAA,IxDw1L/B,YAAA,IwDv1LY,gBAAmB,QAAA,IAAA,ExD21L/B,WAAA,IwDt1LC,cACA,QAAA,EAAA,IACA,YAAA,KAEA,eACA,UAAA,MxDy1LD,QAAA,IAAA,IwDr1LC,MAAO,KACP,WAAA,OACA,iBAAA,KACA,cAAA,IAEA,exDu1LD,SAAA,SwDn1LC,MAAA,EACE,OAAA,EACA,aAAA,YACA,aAAA,MAEA,4BxDq1LH,OAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,iCxDq1LH,MAAA,IwDn1LC,OAAA,EACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,kCxDq1LH,OAAA,EwDn1LC,KAAA,IACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,8BxDq1LH,IAAA,IwDn1LC,KAAA,EACE,WAAA,KACA,aAAA,IAAA,IAAA,IAAA,EACA,mBAAA,KAEA,6BxDq1LH,IAAA,IwDn1LC,MAAA,EACE,WAAA,KACA,aAAA,IAAA,EAAA,IAAA,IACA,kBAAA,KAEA,+BxDq1LH,IAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,oCxDq1LH,IAAA,EwDn1LC,MAAA,IACE,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,qCxDq1LH,IAAA,E0Dl7LC,KAAM,IACN,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,SACA,SAAA,SACA,IAAA,EDXA,KAAA,EAEA,QAAA,KACA,QAAA,KACA,UAAA,MACA,QAAA,IACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KCAA,eAAA,OAEA,WAAA,OACA,aAAA,OAAA,UAAA,OACA,YAAA,OACA,iBAAA,KACA,wBAAA,YtD8CA,gBAAA,YACQ,OAAA,IAAA,MAAA,KJk5LT,OAAA,IAAA,MAAA,e0D77LC,cAAA,IAAY,mBAAA,EAAA,IAAA,KAAA,e1Dg8Lb,WAAA,EAAA,IAAA,KAAA,e0D/7La,WAAA,KACZ,aAAY,WAAA,MACZ,eAAY,YAAA,KAGd,gBACE,WAAA,KAEA,cACA,YAAA,MAEA,e1Dq8LD,QAAA,IAAA,K0Dl8LC,OAAQ,EACR,UAAA,K1Do8LD,iBAAA,Q0D57LC,cAAA,IAAA,MAAA,QzDy9LA,cAAe,IAAI,IAAI,EAAE,EyDt9LvB,iBACA,QAAA,IAAA,KAEA,gBACA,sB1D87LH,SAAA,S0D37LC,QAAS,MACT,MAAA,E1D67LD,OAAA,E0D37LC,aAAc,YACd,aAAA,M1D87LD,gB0Dz7LC,aAAA,KAEE,sBACA,QAAA,GACA,aAAA,KAEA,oB1D27LH,OAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,KACA,iBAAA,gBACA,oBAAA,E1D67LL,0B0Dz7LC,OAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,KACA,oBAAA,EAEA,sB1D27LH,IAAA,I0D17LG,KAAA,MACE,WAAA,MACA,mBAAA,KACA,mBAAA,gBACA,kBAAA,E1D67LL,4B0Dz7LC,OAAA,MACE,KAAA,IACA,QAAA,IACA,mBAAA,KACA,kBAAA,EAEA,uB1D27LH,IAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,EACA,oBAAA,KACA,oBAAA,gB1D67LL,6B0Dx7LC,IAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,EACA,oBAAA,KAEA,qB1D07LH,IAAA,I0Dz7LG,MAAA,MACE,WAAA,MACA,mBAAA,EACA,kBAAA,KACA,kBAAA,gB1D47LL,2B2DpjMC,MAAO,IACP,OAAA,M3DsjMD,QAAA,I2DnjMC,mBAAoB,EACpB,kBAAA,KAEA,U3DqjMD,SAAA,S2DljMG,gBACA,SAAA,SvD6KF,MAAA,KACK,SAAA,OJ04LN,sB2D/jMC,SAAU,S1D4lMV,QAAS,K0D9kML,mBAAA,IAAA,YAAA,K3DqjML,cAAA,IAAA,YAAA,K2D3hMC,WAAA,IAAA,YAAA,KvDmKK,4BAFL,0BAGQ,YAAA,EA3JA,qDA+GR,sBAEQ,mBAAA,kBAAA,IAAA,YJ86LP,cAAA,aAAA,IAAA,Y2DzjMG,WAAA,UAAA,IAAA,YvDmHJ,4BAAA,OACQ,oBAAA,OuDjHF,oBAAA,O3D4jML,YAAA,OI58LD,mCHs+LA,2BGr+LQ,KAAA,EuD5GF,kBAAA,sB3D6jML,UAAA,sBC2BD,kCADA,2BG5+LA,KAAA,EACQ,kBAAA,uBuDtGF,UAAA,uBArCN,6B3DomMD,gC2DpmMC,iC1D+nME,KAAM,E0DllMN,kBAAA,mB3D4jMH,UAAA,oBAGA,wB2D5mMD,sBAAA,sBAsDI,QAAA,MAEA,wB3D0jMH,KAAA,E2DtjMG,sB3DyjMH,sB2DrnMC,SAAU,SA+DR,IAAA,E3DyjMH,MAAA,KC0BD,sB0D/kMI,KAAA,KAnEJ,sBAuEI,KAAA,MAvEJ,2BA0EI,4B3DwjMH,KAAA,E2D/iMC,6BACA,KAAA,MAEA,8BACA,KAAA,KtC3FA,kBsC6FA,SAAA,SACA,IAAA,EACA,OAAA,EACA,KAAA,EACA,MAAA,I3DmjMD,UAAA,K2D9iMC,MAAA,KdnGE,WAAA,OACA,YAAA,EAAA,IAAA,IAAA,eACA,iBAAA,cAAA,OAAA,kBACA,QAAA,G7CqpMH,uB2DljMC,iBAAA,sEACE,iBAAA,iEACA,iBAAA,uFdxGA,iBAAA,kEACA,OAAA,+GACA,kBAAA,SACA,wBACA,MAAA,E7C6pMH,KAAA,K2DpjMC,iBAAA,sE1DglMA,iBAAiB,iE0D9kMf,iBAAA,uFACA,iBAAA,kEACA,OAAA,+GtCvHF,kBAAA,SsCyFF,wB3DslMC,wBC4BC,MAAO,KACP,gBAAiB,KACjB,OAAQ,kB0D7kMN,QAAA,EACA,QAAA,G3DwjMH,0C2DhmMD,2CA2CI,6BADA,6B1DklMF,SAAU,S0D7kMR,IAAA,IACA,QAAA,E3DqjMH,QAAA,a2DrmMC,WAAY,MAqDV,0CADA,6B3DsjMH,KAAA,I2D1mMC,YAAa,MA0DX,2CADA,6BAEA,MAAA,IACA,aAAA,MAME,6BADF,6B3DmjMH,MAAA,K2D9iMG,OAAA,KACE,YAAA,M3DgjML,YAAA,E2DriMC,oCACA,QAAA,QAEA,oCACA,QAAA,QAEA,qBACA,SAAA,SACA,OAAA,K3DwiMD,KAAA,I2DjjMC,QAAS,GAYP,MAAA,IACA,aAAA,EACA,YAAA,KACA,WAAA,OACA,WAAA,KAEA,wBACA,QAAA,aAWA,MAAA,KACA,OAAA,K3D8hMH,OAAA,I2D7jMC,YAAa,OAkCX,OAAA,QACA,iBAAA,OACA,iBAAA,cACA,OAAA,IAAA,MAAA,K3D8hMH,cAAA,K2DthMC,6BACA,MAAA,KACA,OAAA,KACA,OAAA,EACA,iBAAA,KAEA,kBACA,SAAA,SACA,MAAA,IACA,OAAA,K3DyhMD,KAAA,I2DxhMC,QAAA,GACE,YAAA,K3D0hMH,eAAA,K2Dj/LC,MAAO,KAhCP,WAAA,O1D8iMA,YAAa,EAAE,IAAI,IAAI,eAEzB,uB0D3iMM,YAAA,KAEA,oCACA,0C3DmhMH,2C2D3hMD,6BAAA,6BAYI,MAAA,K3DmhMH,OAAA,K2D/hMD,WAAA,M1D2jME,UAAW,KDxBZ,0C2D9gMD,6BACE,YAAA,MAEA,2C3DghMD,6B2D5gMD,aAAA,M3D+gMC,kBACF,MAAA,I4D7wMC,KAAA,I3DyyME,eAAgB,KAElB,qBACE,OAAQ,MAkBZ,qCADA,sCADA,mBADA,oBAXA,gBADA,iBAOA,uBADA,wBADA,iBADA,kBADA,wBADA,yBASA,mCADA,oC2DpzME,oBAAA,qBAAA,oBAAA,qB3D2zMF,WADA,YAOA,uBADA,wBADA,qBADA,sBADA,cADA,e2D/zMI,a3Dq0MJ,cDvBC,kB4D7yMG,mB3DqzMJ,WADA,YAwBE,QAAS,MACT,QAAS,IASX,qCADA,mBANA,gBAGA,uBADA,iBADA,wBAIA,mCDhBC,oB6D/0MC,oB5Dk2MF,W+B51MA,uBhCo0MC,qB4D5zMG,cChBF,aACA,kB5D+1MF,W+Br1ME,MAAO,KhCy0MR,cgCt0MC,QAAS,MACT,aAAA,KhCw0MD,YAAA,KgC/zMC,YhCk0MD,MAAA,gBgC/zMC,WhCk0MD,MAAA,egC/zMC,MhCk0MD,QAAA,e8Dz1MC,MACA,QAAA,gBAEA,WACA,WAAA,O9B8BF,WACE,KAAA,EAAA,EAAA,EhCg0MD,MAAA,YgCzzMC,YAAa,KACb,iBAAA,YhC2zMD,OAAA,E+D31MC,Q/D81MD,QAAA,eC4BD,OACE,SAAU,M+Dn4MV,chE42MD,MAAA,aC+BD,YADA,YADA,YADA,YAIE,QAAS,e+Dp5MT,kBhEs4MC,mBgEr4MD,yBhEi4MD,kB+Dl1MD,mBA6IA,yB9D4tMA,kBACA,mB8Dj3ME,yB9D62MF,kBACA,mBACA,yB+Dv5MY,QAAA,eACV,yBAAU,YhE04MT,QAAA,gBC4BD,iB+Dp6MU,QAAA,gBhE64MX,c+D51MG,QAAS,oB/Dg2MV,c+Dl2MC,c/Dm2MH,QAAA,sB+D91MG,yB/Dk2MD,kBACF,QAAA,iB+D91MG,yB/Dk2MD,mBACF,QAAA,kBgEh6MC,yBhEo6MC,yBgEn6MD,QAAA,wBACA,+CAAU,YhEw6MT,QAAA,gBC4BD,iB+Dl8MU,QAAA,gBhE26MX,c+Dr2MG,QAAS,oB/Dy2MV,c+D32MC,c/D42MH,QAAA,sB+Dv2MG,+C/D22MD,kBACF,QAAA,iB+Dv2MG,+C/D22MD,mBACF,QAAA,kBgE97MC,+ChEk8MC,yBgEj8MD,QAAA,wBACA,gDAAU,YhEs8MT,QAAA,gBC4BD,iB+Dh+MU,QAAA,gBhEy8MX,c+D92MG,QAAS,oB/Dk3MV,c+Dp3MC,c/Dq3MH,QAAA,sB+Dh3MG,gD/Do3MD,kBACF,QAAA,iB+Dh3MG,gD/Do3MD,mBACF,QAAA,kBgE59MC,gDhEg+MC,yBgE/9MD,QAAA,wBACA,0BAAU,YhEo+MT,QAAA,gBC4BD,iB+D9/MU,QAAA,gBhEu+MX,c+Dv3MG,QAAS,oB/D23MV,c+D73MC,c/D83MH,QAAA,sB+Dz3MG,0B/D63MD,kBACF,QAAA,iB+Dz3MG,0B/D63MD,mBACF,QAAA,kBgEl/MC,0BhEs/MC,yBACF,QAAA,wBgEv/MC,yBhE2/MC,WACF,QAAA,gBgE5/MC,+ChEggNC,WACF,QAAA,gBgEjgNC,gDhEqgNC,WACF,QAAA,gBAGA,0B+Dh3MC,WA4BE,QAAS,gBC5LX,eAAU,QAAA,eACV,aAAU,ehEyhNT,QAAA,gBC4BD,oB+DnjNU,QAAA,gBhE4hNX,iB+D93MG,QAAS,oBAMX,iB/D23MD,iB+Dt2MG,QAAS,sB/D22MZ,qB+D/3MC,QAAS,e/Dk4MV,a+D53MC,qBAcE,QAAS,iB/Dm3MZ,sB+Dh4MC,QAAS,e/Dm4MV,a+D73MC,sBAOE,QAAS,kB/D23MZ,4B+D53MC,QAAS,eCpLT,ahEojNC,4BACF,QAAA,wBC6BD,aACE,cACE,QAAS","sourcesContent":["/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n margin: .67em 0;\n font-size: 2em;\n}\nmark {\n color: #000;\n background: #ff0;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\nsup {\n top: -.5em;\n}\nsub {\n bottom: -.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n height: 0;\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n margin: 0;\n font: inherit;\n color: inherit;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n padding: 0;\n border: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n padding: .35em .625em .75em;\n margin: 0 2px;\n border: 1px solid #c0c0c0;\n}\nlegend {\n padding: 0;\n border: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-spacing: 0;\n border-collapse: collapse;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n -webkit-box-shadow: none !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n display: inline-block;\n max-width: 100%;\n height: auto;\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all .2s ease-in-out;\n -o-transition: all .2s ease-in-out;\n transition: all .2s ease-in-out;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: .2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n margin-left: -5px;\n list-style: none;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n overflow: hidden;\n clear: left;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: .01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n padding: 6px 12px;\n margin-bottom: 0;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: normal;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity .15s linear;\n -o-transition: opacity .15s linear;\n transition: opacity .15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-timing-function: ease;\n -o-transition-timing-function: ease;\n transition-timing-function: ease;\n -webkit-transition-duration: .35s;\n -o-transition-duration: .35s;\n transition-duration: .35s;\n -webkit-transition-property: height, visibility;\n -o-transition-property: height, visibility;\n transition-property: height, visibility;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555;\n text-align: center;\n background-color: #eee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.nav > li.disabled > a {\n color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n -webkit-overflow-scrolling: touch;\n border-top: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-top: 8px;\n margin-right: 15px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-top: 8px;\n margin-right: -15px;\n margin-bottom: 8px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border .2s ease-in-out;\n -o-transition: border .2s ease-in-out;\n transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@-o-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n float: left;\n width: 0;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n -webkit-transition: width .6s ease;\n -o-transition: width .6s ease;\n transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n -webkit-background-size: 40px 40px;\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: .2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: .5;\n}\nbutton.close {\n -webkit-appearance: none;\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transition: -webkit-transform .3s ease-out;\n -o-transition: -o-transform .3s ease-out;\n transition: transform .3s ease-out;\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n outline: 0;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-style: normal;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n filter: alpha(opacity=0);\n opacity: 0;\n\n line-break: auto;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: .9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-style: normal;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n line-break: auto;\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999;\n border-top-color: rgba(0, 0, 0, .25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999;\n border-right-color: rgba(0, 0, 0, .25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999;\n border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999;\n border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: .6s ease-in-out left;\n -o-transition: .6s ease-in-out left;\n transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform .6s ease-in-out;\n -o-transition: -o-transform .6s ease-in-out;\n transition: transform .6s ease-in-out;\n\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n left: 0;\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n left: 0;\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n left: 0;\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n filter: alpha(opacity=90);\n outline: 0;\n opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on
          ,
            , or
            .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: (@carousel-control-font-size * 1.5);\n height: (@carousel-control-font-size * 1.5);\n margin-top: (@carousel-control-font-size / -2);\n font-size: (@carousel-control-font-size * 1.5);\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: (@carousel-control-font-size / -2);\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: (@carousel-control-font-size / -2);\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]} \ No newline at end of file diff --git a/backend/webif/static/css/codemirror_custom.css b/backend/webif/static/css/codemirror_custom.css new file mode 100755 index 000000000..020fb509d --- /dev/null +++ b/backend/webif/static/css/codemirror_custom.css @@ -0,0 +1,14 @@ +.CodeMirror { + border: 1px solid #eee; + height: auto; +} +.CodeMirror-scroll { + overflow-x: auto; + overflow-y: auto; +} + +.python-tabs .cm-tab { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=); + background-position: right; + background-repeat: no-repeat; +} \ No newline at end of file diff --git a/backend/webif/static/fonts/FontAwesome.otf b/backend/webif/static/fonts/FontAwesome.otf new file mode 100755 index 000000000..401ec0f36 Binary files /dev/null and b/backend/webif/static/fonts/FontAwesome.otf differ diff --git a/backend/webif/static/fonts/fontawesome-webfont.eot b/backend/webif/static/fonts/fontawesome-webfont.eot new file mode 100755 index 000000000..e9f60ca95 Binary files /dev/null and b/backend/webif/static/fonts/fontawesome-webfont.eot differ diff --git a/backend/webif/static/fonts/fontawesome-webfont.svg b/backend/webif/static/fonts/fontawesome-webfont.svg new file mode 100755 index 000000000..855c845e5 --- /dev/null +++ b/backend/webif/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/fonts/fontawesome-webfont.ttf b/backend/webif/static/fonts/fontawesome-webfont.ttf new file mode 100755 index 000000000..35acda2fa Binary files /dev/null and b/backend/webif/static/fonts/fontawesome-webfont.ttf differ diff --git a/backend/webif/static/fonts/fontawesome-webfont.woff b/backend/webif/static/fonts/fontawesome-webfont.woff new file mode 100755 index 000000000..400014a4b Binary files /dev/null and b/backend/webif/static/fonts/fontawesome-webfont.woff differ diff --git a/backend/webif/static/fonts/fontawesome-webfont.woff2 b/backend/webif/static/fonts/fontawesome-webfont.woff2 new file mode 100755 index 000000000..4d13fc604 Binary files /dev/null and b/backend/webif/static/fonts/fontawesome-webfont.woff2 differ diff --git a/backend/webif/static/fonts/glyphicons-halflings-regular.eot b/backend/webif/static/fonts/glyphicons-halflings-regular.eot new file mode 100755 index 000000000..b93a4953f Binary files /dev/null and b/backend/webif/static/fonts/glyphicons-halflings-regular.eot differ diff --git a/backend/webif/static/fonts/glyphicons-halflings-regular.svg b/backend/webif/static/fonts/glyphicons-halflings-regular.svg new file mode 100755 index 000000000..94fb5490a --- /dev/null +++ b/backend/webif/static/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/fonts/glyphicons-halflings-regular.ttf b/backend/webif/static/fonts/glyphicons-halflings-regular.ttf new file mode 100755 index 000000000..1413fc609 Binary files /dev/null and b/backend/webif/static/fonts/glyphicons-halflings-regular.ttf differ diff --git a/backend/webif/static/fonts/glyphicons-halflings-regular.woff b/backend/webif/static/fonts/glyphicons-halflings-regular.woff new file mode 100755 index 000000000..9e612858f Binary files /dev/null and b/backend/webif/static/fonts/glyphicons-halflings-regular.woff differ diff --git a/backend/webif/static/fonts/glyphicons-halflings-regular.woff2 b/backend/webif/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100755 index 000000000..64539b54c Binary files /dev/null and b/backend/webif/static/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/backend/webif/static/img/NIC.svg b/backend/webif/static/img/NIC.svg new file mode 100755 index 000000000..d3ef089ee --- /dev/null +++ b/backend/webif/static/img/NIC.svg @@ -0,0 +1,1877 @@ + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvWmPJMmRJfi9gPoPvh8aIBtTQTM9TNW4gwXC4+BwhuwmSPaxaAwKyawgmdN5FLKyyOX++pX3 +RFRUzdw9KvIoNne6QqsywsXN1EwvUTmeiP7d//Gr33xx/dWb3z18Ea+mw+ef/d3f3bx9ePbuzduf +Hkg+/Pzly2+/efcWpB/9+seHebmacNX1z+uXduU/P7z95sWb1z/ld/rtPe7/0S+fvXv3x4c///jw +ox+D+NsX714+CPkffn7z5S+e/e7h5cuHr66++dMffuxPlVpun72Ta+afhPyTMM3xsPw0z4df/ZKX +PHv9p2fffPPi/8UFS6wRxOObb19/9eL1H45v/p+fHsrhi7oe1nj4Yg748r+9+PXDN9srrrJcU6/C +utbDGq7SNCVcfVVD5i23b55/++rh9btfvX3z/OGbb27evHzz9pufHm7+8uz14ZfP/iDfPDv83/Lq +b/58OL589vzf5Z7rn+cv71+8fJBGv3r27iCVTaTO4cvjty9efvUP37763YP0x1ID6fFL1vpP30h1 +UjP+Jr18+fNXQvrNw7t38rryUHblr392HN9FqCw/+rdfP/zhBQdGeu1//rjV/PbN16+evf133C3t +mqYD/p/s298+vPr6pXQwuyJP6Av+2/9sF0pzeNEXIa5XYZrC4Yu0BLkqts8RH+3y3mkPf3rx8Oef +Hv7hzesH65nrt+9+o0OWEl4H/9pXv/725cPbf3r94p287ULaql3zyzdfPbyUO3oV9y+fsUdY5v6v +XfHbZ2//8PBOBvvNy2/fcS5Wf4p0/y+e/eUBozjbQ/7x64fXv33zz3zVL1I5xEO9mtNhznU+1BQO +c+UTsjxkXvyhc//XqkY9qKXVXzBgv5Ix/Me3L/7w4vVPv4hSBf6x8f3Z2xdf9eEt4VD1Hzblqg7/ +r+1/e2Np/7t3D69bE2Rq3fxymCjT1S9/g2ffvf7q5s0rDMU3XBwyRV7L7Hn55g/2bf/A76SKb7+2 +xpDwpYzcr96+eI2KP//sH/S7+uWvXn4rX/7s7Ztvv/7569+/+fyzHylz+OeH58IAZHi/Ovzj7/6X +fJC1zkl8+O3bZ8+lDvns11w9e/H1j7+jQmnn24eDfiv38qP8/j1+P+X+24ffyyrsFSj17vWfHl6+ ++Xqo2CnPXn91+Jdnb79+SuW/evns9bO3B37hdf/ixZ/km2fSZb32TntStTJ3vpZO4k28ZveIRy4Y +vnrSo569+6PwrYfXX33jtevH3csr8SlV/uYvr3735uWLb155hSPF/37i2717ePv6H1/ra7799ps/ +Hn775s3L3hF6gX3VB/ntO73nb+YhfvG5B8iXf7uV3zx7+fLFH94++/qPL56fq//M9/6gC/c+aRY9 +Z6+fe+L2K3/Y6R1/S89pk+juqxfC/C4s60ev+c2fn717/kdhL797++zti4fvWIsY3t+/eP2VvOhv +vn3x7qGP15tXX0MAOvzmj8++BhlX3g9X9nrzl7JBjBvAF188vjXI3nh8PV7ys7fPvnohm48IeT97 +8/Krh9eHX2MPkPcbP8p2Vw7Hrz7/7N8+/2wa/pvbf+nwd18eRSb6r0Le/8y7EoYSrSQrmf+3suB/ +qXHZlOKlTuumXA/lKOXGyu1Q7qZ7qfG+lc2rjT9hKHEoaVOyFukD/C7zIqXwdx3KuinX89HLjZfj +fCulfbqVGm/nO9Ju5/uxjN3H12s/cShpKDksKJ9/pr9DGUoNqxT993ooRy2ff/Z/nR/TS6MaN+Oa +htHtYyxFamzjnIbR1tEdR7lKwW+Mbt2M8zqMtPwrNeqYt1E/+njrb4z23Tjq8q/+TGfHXAT/zYhH +GV/8xghjrBeWytEuu5G+trIdY4wpft+x3O5Gsz02ciz72KHoWLWRW23MZJxkTHWsMGY3Vm5Z7qzc +o7RlhubsxnTmaCXr/8p+PXLN3LOHAntgYRtXtueWbz3bWy6cPdeYK3w2nhVijCkusYjGt8ajlNt4 +L8M+p5hSyqmkmtZ0nY7pNt2le+nOkGNOecklr/k6H/NNvsuyTuWVZpmyacnLstRlXa6X43Kz3C73 +Milm6YxUcllKLWs5lptyW+5lwsw11FRzXWqpa72ux3pb7+q9TBwZ0zWuaZWK1rqu63G9We/We5k+ +83W8Ttf5ermu1+v19fVRys317fUdp1SQJqRjPpZjPa7y1fF4c7w73ss0k95kp8ebdJNv5BVu1pvr +m+PNzc3tzb1Mu5mDkW7z7XIrr3dbb9fb4+3N7d3t/d0kwxPv0t1yV+7q3XonD7u7uZNZcnd3d4+p +cS+ddp/vpbH38vr311Lkofdy6/3uh2M6cViddjeU26HcDOW4KddDWVuRGld5fC9lKMum5KGkocSh +yGyUGoOXkbN1rjyNL383/txuyo0W6TL8Pg7leijrptShlKEsQxGGfpe9pE2JQwlDmYcyjUW7/fPP +bADGBow/N0M5amlLdTOe21Hcjl0bte1IbUdHRkRqTOOIDCOx7f9tr1tv73qYvSr9te761Hpy04fb +ftv11rZ/pL+2/aJ9cm1lZalWipWFJVtJLNGKzDsuRttTdVfwpdAapw9rP0eWaysrS7Uii10Wf7lZ +rGQriSVaUZ7c9gDhq8OY3nEcjxy3ynHKHBeMxcTev2VvX7NvC3szsfdm9tYde+fI3qjSusK2o8Vo +5cRW3bIV13zvwrdMfCt5F5k2d9KlN8LOroWtVWFvizC5JMwuCJ+XN5UpdSedfSPM8FrYYr0uwiCz +MMoo+80se/C9DP2tdMpxvRZ2WtcijDULg42yQ82yY9/LhLiVzjoKG16rvKOw5EVYc6pRmPQse/u9 +TJVb6cpjuRYmXksRdp6FrUdh7rPIAvcyiW6le4/C+lfZAopsBFk2hCjbwrzIO8qUvpPBvpFN41o2 +jypbyJKzbCZRNpVZ5It7mXi3MiRH2XBW2XhKWmQLSrIVBdmQJlkCdzI9bmSTupbNSt5Rtq0lZtnA +omxks0g09zJZb2UYsc1i48VWnGXrw1Y9h2lW9juIwHYlrm1X8lpZYLr1Q9yDgLBSgFCBQkSMNjcu +PJU1sY5WQ78fAkrY8Iv7YSdQTrHKHMsyv2aZW+dmVhi2Ee5S+NGdauaCxW6VuazbjmV7FnYs2ZRE +YGivgL3R98VFpl49szNG3xmxL17jme1+lzGiSbClyRmUMu4oZ8wmaWSXNa73Q4FugYw33XvN8pmy +4G2jYEHpchr3Ud+A22XsEHaGj9M1RZu7eDIDKGLOLj6pwKgilAqGNxTv7+Qhs4nu2swminfRmyoL +a2t19ZpYDztK7z/bSf7+42DqQG4EDwodUWZIkZly5JzZCRpj92TbQhqzGtlVn1adZY1Mi2zLe/8M +M9uysu9iZD4cu6X8SRby0eXrVrrGVDe6VDH9Skve6GCml0mN0ZiB/qjMv1GJt9pe261cF3RtgkV6 +caNF3lBCb5oHfq+7Unela6z612K67FjSSYknJZwp9iM1jj8nqiNW5yj7+e/bs0VYi8zCGy9HL9cX +ynqx1KZhSo1lV5Ynlq695rFIjZvPbuHof5+WeKFwakiN4YnlXCefKVLj06588s9ZW8FH/Xy6Goft +dfaOVem3SfG3VlRua7aQZhuppns324mte1nVqqe31d7sMX0p7Nd2k33bWh5X79FWdbMinK7d4laH +xUp2m0S3S8Vxtbo145F1Kn+5LaTbxnZrs63OW25NzcYy2tiOZ9fmcWOZO12dzYazX611Y+XrVqFm +GTq3Xv3zxnaYT0raWBsvr8qt5Wpvszy3bh9bzbu1ylV94bv3X9GPruq/gTX46Wu8IPSO6tWpgqVS +y6mC1WSViQr7HSWS1RTMxWSS4OrV/SCVlI1UEgYV60aULKpYn38mShbULFWyoGZNVLFUybqh1UkV +reqKVjRFC6rWjahZRypalTYsmY1UtmYulHvq37d4hFRQRdVSZQvqVlB1iwrXrSlcRypclQoXVC6w +Mpk7pnbdU5eG4qWqF5SvSuUL6lei+jVzWd1TBbuhCgYlDGpYkcfiUtG0REWLVMZEHaM96I4K2a0o +ZFDJoJRBLYNiVlKmagblLJJ1TVTQ7k2HP2oRDr5SvoOEVyjlLbgh4memgNU5O8RgHZAux6nsVqme +oSRy8JF3D1x7kMKaPVd/jzx5lKEoLwm/TSeykXPWDS/dSDYbrrnhkbJiRpkFZcftzvK5R+SLM/LE +07jGRW7yiVe1q6JaRgvZ+LM1Cg6mzq0dru25VDlmU2l7iZuytfnlXVk2RQSAjSWxbGyMlTrWtlzv +ynFfzKI5ltuTcvpzf1rabBMGOe7k85kSzpZ4tjQr4mnJF8pysbg9WWosu1IfLet3FBEpNlbt8+X4 +xEKOLzXePLHcPq1IjafUc0P55CI1XvruA3/ObK8fXJMbiCbXWoM5UbQkK2pPbfbVYqXZX1crZp2V +GtVa234aq+hLqA1L47dNt25Sf7MUq91Y5jfNU1oWL83WXL2sVq69HM/wrFuYl0441jle1f0I57nT +wJc2fooNT7rAjS5xoZHzHGkPusx7HuE5Gx5jfIa2tMs85gxn+S6OIjU+ykeewEF2nIJeLucaH8wp +htV/kU88kSuc8oFHVvXj5a+4qt/LbLsx3Ipgd6O2VDqKIYvFJGtQBMJlcBgfhTGo03gytzEcx5mu +4yqCZ3Mf38KBLJuOOpAjRVY4kWWPoSDbXMlwJt/RnawO5QgplE5l/MCxfE1RGc5lLCZ1MMPFDPmT +bubPP6OruUIqp7v5KOzp1p3Ok0iJkDjheE7ygpClC0X4VcT5azqhb4R93JkrerqWFSNCf6DwD6c0 +3NLLdaFasA7uaTqopWBiQl6caauMdFbDXQ3ZvdBpXUX1WOm6Vuf1DZkTFvo93diTc+HGfxvnbRy3 +c1rjscJvG3ftXLVx085HO/fsXLNzy5FH3pqF2rnihht2HriVyUZut+Vw0jHCyzpn2/KyHfc6Ixmd +8qdR5jkv11ziOjupZCxS4yNc5Du5xlN3/w9f1c0cDujXAKyeD0H+Wg51ukqydg4lXslqCbgYuOYv +n3Lt8ZszdV5luTJPhzpfif64XK5wfyFru5qXsqZZvp2hGIcG1M61hiR/lBzs6zDnZT3gAq0lXMUp +p/64j65J32cSpTYvctkky37BjaKZi+rOytaUp5UAcuGUKcsfAb/nobJ4NQmnGV7rE1Vob7dMwmdR +WZ6nXHhjFf6slYluWfUBQfgsKpPhy+umsjxN6/h2n6bCjxjLUK5qjCuqqrmsHzug++rOzVl7+XW9 +Ej5/ccJur0I9x9uO4mxAzAvgzH98+/yPL74CLtP+korDCMm8Wpa5wH0tXR9DKUsDaMqaY2/zGsyF +/ZK2Ow/tRg3UsLsOdpOt4KzRKUMTP+Bu68Kn3ol+S8tVjJj1H/LobQXv2fG/+fe/oNfxS25Orcv/ +q+9W97ZHBdudsnlWi+1F17b73I5ucttZkgG8Fui+KkHJ1jEbhC1RrgCI7Uh54p4WJw== + lSMWShDXlB3uuKkAwgZZQeWEa5oTb88AOBWs2ZxRak5Xszw28MngruplbnBV+qod9JcfgYWe+7kM +AB6N5Xkw+dAeqSAQwkAcCLK3SBYDhCgkxEAhtEneGSzkJrun+XG4ywB2eRLUZe8rdmFqNuTDiH3o +6IcbFZgGBERyAWltKIhbHziIxIachCBcG2qS4q9iJitFXoi6EHSz9AiE2xuZgxMF2mz4yNviDnzt +ZQOSdCjJBoxi9srJPbE3tEiqBbKYpTGZz2Ludvgnw4GeBAVy8EK3vysqICiEy6Bbtw7XujaQVrPH +ZwNjKQhrooR1d+LnH7CyjpZV46067KMrLJlKy0LFpVB5qbRGX1OFOdKCIaNHWfWeykxXZxT9inFU +lUaVmq7WULExPKwiYqHaQLkRbk4Fp1LBaSrO7UbN2Sk6puZgLjTULFWdpuzIKtuqO5glqyFpbyit +3zmeNlDZaajaUdm5obJzBylXxl6VnTgoO8UUnSMVnVsqOoq47SpOGlQcqDeu4IgidEslp6k4p0pO +NiWHao6rOEeqOVRynFkZytDQ4AM+kx7M07/v/O8t1Wz39H+aJd+8pHfdX9r+Gn875nyMNVC/QEOc +z+4piB550H/Hze9kjLqh07PHI6gXQhgnAj6GiIQWl1DsX/Vf6L/qae7/Xm+8HbeGXG9xCYQuwY89 +YNc7cj2aN2Ux7PpivnL1uvRYgxuNMRjw6n399XUXieHZrzlOHWJ9buO5be50Czr393Z7OrmHntTR +3zG7j2T0lpx6a089vsl9Lns/8emn8ff+75GWPZaiR8+ki0iTyziUuPk7ErnSPqWdD2n0LJ33qvfv +3cdu77jvk3nwefee7b3cR2LrEdqgc49n0LnFcLkdkduwuIbC1W2AAoGIBLJ5HykWXNNKUslOFhMP +mqt2NiFh67C9dodtIQszp60wrsBV1Fy3t3w93Rh1a2ybo2+PvkG2LZKYWW6TslF+/pltleNmOW6X +I3Z2i57d4mcdQfv5ZyoumQN3j6G9hKJ9BEdLcaXB7z4IgDc7uz5F0A/luzH03QJvNnkRIa7dUr/H +jRe37m+x4wN63MqAHZca9/jx2w1+/PL8rObLWLazVGZ2x46PyPHJ5+y9mbO0cfqAo89enb8rt0LO +YpnZOpMXbpV9PkdDNiqXV29zm9t31mU3AyhB57kUmdk624vN+IVaB+UY5cnk7bqHqO9aV8AdVwHX +gUM2zvkP9xEj+3LeSxlOPA0nMSVnY0u2cQ4ncSYyD0+iTXZxEOdjTk7jTiw+Qmo8F31Sdj7lZedx +vhyDEglgPh+HMj+yii6toVuAsM+upOPg4epraVxPw6o6sR1erSKUxky9HHI/DC3CPSpU9mkWFpZp +jhElvS7Q3vMa5lw2dhO5ejAwfqoK1dZUl2WdaT5YRXSuZruRj24eUtNaN1UtVyJp1eF9PrgKfYOS +orBEGMVikV3Bbp7nIsoCGom/0NqahJcO7ciL3DoPhtKPrsmsb3WKkZ2Z41ppcZStuMae+aKgAtj1 +tIutnvUq52ljqvn4qt7XaPPtq1cPb2m30b9ogOvWslFUbALcKISN4ajFIYgNvHj0oOK7JvIbyBly +cBPLs4vexQXsHhDaAntHAboH8VJfNFhpA5s28GkPz1WgqsJWL6utmYorxWfGtjQBWtXWdRCkj7bZ +3TXlVdRXQrAM18qKqMBi36emKUucGiRBXKrMNoX22LZQY1rNcaLSYTBsuWnU2arNIudQ5SUmjcaN +amqvFtvGWrBV9g3bneANB+XYWMo5WqKX7KX/FC/Vy7WXYy9S481QOjhg6wwa0anzpsShsPtEGU9e +8qac/tRdWc8UkXfK9Um5uVBuHynu0oJt8oKLfXrvwgktMm34FOVsSHMPai4e1nzsa3beRtRUrtBj +D9DGupQVqCrtJjKHa+5+UFG7F3u1iKDbwfCT2lqBuUfWi66PG7owJw9+zhb+XGnOu7aZfUfTDuZy +pIEz2yyFYefIOXnLudg82IEzqnuvr+m9tnEkAHSmDhFpeGumnEoLM0w5EEvUjDOZGSfTiKPe6tV9 +1bdmcwZLDJT4uhEHsuHqZhx6qWnGecxT3X3V62DCuWGYNcyqd4aMdC+1SMpbP/VCabrjg5q/WkXk +jgPq+J+O/OGAEe2TNmifEeeznqB8Nr7rAdXjeB7TYbYInibB7XE6p/icU2zgzYAKPIfG2eBwLmJy +NvLxJhb7MuLvkpy+xeWkC6jAS4jAR0tT9+dtBHSLfW4xzy3auUc6tzfpuoLpAYOkr3L9Npa5x4Y3 +abxL3j1q2WXqQYa+NWzXNkq5S8ansclds9xplaM2aQiLrTZ53tZxoknutEjTIw11t9Ukt7rkVpvc +6pPVDK3FN0IZJdcqu2bZdMvgeU6mQcO8H/TMO1cnPMhaeEV7eP9ZvVQvfVvrm3T2knqRGuNQeiTf +vCkj2noL2BiVOA6qcMjOEG425XhSrnfl3I9oheSx23J2Y6fd6HJxQUlqzBdKeu/CrY3JMz5B+aAI ++Mdj4Bk4KitwGzp6Gge/DSDdxsKP0fDmIJTZvWychN1NeLux/m1sf+owdJdhcxpe+zgXGyft17AL +37hxB9m6C+KI3f5nFsC7InORDODIpbCa46xQjG1OVLUGdjfq1pHagzsKpWCZORbioQ7VsAnzuCMD +2wZ7rJRailsNs8nyHvYhMv1MW3AL/9AAkBuzJ27DQDQQRCWmFg6iASGqhdDfIXJUCw25N31FGaqy +vSNtkNdmh2zBImO4yGKKhyk1UWYltaUWqTufCRK8FCbYgku2gcIi65nGtg6i6qVg4V7SucBhDx8+ +/TmN57sUQXYG8g/E5q7cfUj5LqQYkTR1C984f0EDh+SpilZI0JBIv6thOzJMGHM3ZrjpYo9K+YDb +39PG8E+vXz979fDV4Q9GOsywN5yhjkidc3mXsqsoQ+6l+XLAv6YOuG9h/zQTAGi7B9luMyNs4bXq +iVYv9PUGVBuAFHJI7XriWevGknSiYLW3bykLehv2rTgyF9atmz+emufhEcCwzD9v1Xu99dHeuqdZ +GPt90/Pm/bw3c81J0oZHclOcBzlLX/eR2GZx+n6yw3yi3DDXwjl6bpjvPafND2+9feuNXT2mkidk +Hg5FDd3Q7wutvldq1zrzx3nG+QnqAhfVtMsk9co3xI/mtdN0ntsKHWmg9/w2GNgN6/2GKIxIhMTK +dQ0uFIlXWGlWvZP1q2adyhWrCCzNXCcD4AisQD5ZaJa8HXLVNQRWCy3omeqKBRQwnKBhaz7/zNE1 +W2SN4Wo2IQTZTDLbEILRMHO3woTTzDOKswmm/CQz1LSggsVUqKZUdT2l/ZgyRrWsKWlNadv6u3qU +zCbsvye73BaZAOGkxLMlXSh5W0wZ7WV5UimXC92n50v9sGIx4E8rZ7TJ02KhHZ+w/FDjpSsGqaLJ +b4tzFZXaAiWHssmVGYiIKpQR1HjcpbOKnFWaRsolM0gDY3bMSAPxYug/C29yzF/H+3lQk6hwDevX +gpq2IU3Og4DxOwlqUpzf4sZh4UfCo45DaJNxJgtwmghMDpswp+yhTq00s4b+SI3Galr3diNKM610 +s0uPnelmmnlfCLrpJZ4p6ULJJ4XcUWpcLpYz/pULpRutqsEn3qecWJC2RWr8jivetzy5xif/SI2f ++Od/jxof4SjQSe4Mjp+phVyrc8rTvS2mc7Scu+AnpusJR7mhlqEOKM24Cy3v3nHjeZNtV11NDUE8 +upnOc5TGUxpy+Eyg5Fmu0vhKYTJI5S7XG86iNvg9b+n8JZhFp3OZbKZP2a0HTtN++nTd8pkNfmWP +1GkcR+WoDde5xH3ChbLjQDtj9GWO9F38yYvU+Mi3H1Ae53ofVH6o8a9V43uG5jz559EatzjoeGJn +KRvrkFmGmIkzmrQ0pLMcA41oDVK7SpObmsN9MasW4SoqOTFYvEXJXNOmde/yU6JxenSu31N+ihYz +U8hEoBAQyKEwjc8/oztdQRhgLTC1q78WIIZIR3o2HAbYjvrk4MdV3hXdiZ6VNwlH0Z8bC92Cp3cy +R7qWtubbmDYG1txiHYNHbYtpeu8HzWrUnEZtaKu/7KXb4cfg0LdnymmmGvVMT4+WYFnSn1bSU4pB +Zb+7LE8tUuOTr/3PVONgJrs9SSJ8lOlb7rIsQWTQvbVsaQuzpE3Mj3akyWuhuWu2fGhHmW/qXIOR +CyYumLfgToMrTd1oCp2/Zc4zBcznluuMrjJPKl1LiyITiaJB45+SUHqfUtqTSndA/OefmZurubia +eysaMH52p9btAI+/HjKadTcWXVjCo8Ims9nWddUcV91p1V1Wo8MqdmeV5bOcz+Sz3Lup9k6qC+6p +zz/bOaguuac2zqnHHFNS4wXH1Dmn1BPcUBqH9NRy85Rip3N8d7lk0DopzOL5Scv/HjX+wFF+4Cg/ +cJQfOMqnq/EHjvIDR/mBo/zAUT5djRs3+6NHHn74l/Tel5DqvNKZntbCtDVZZiEopWR1xs8TIsjO +/ME/l3OO/E9abfPpI4fPHA95vpqE2208+7uv/A55rHyzzFfIdXCI6WqZhyRbj1yyq6FIxTkshzBd +xbCWczXsL+k1lHIOjDDSPx6PEC7gEQLwCHHAI3iet7sdAPt2B8S+WNpud317Um7er3hNe8A1fh7z +/Jx4qTxsu0NjJgPI3zow/vTgrnoabzRYMMezCcuAkRtP9xxP9tyVv9maxqxBN56OsdvXbIb46GxH +bTPifs057MZ1w254Dh0/Z8mOMvIznYYsKT3TTx1y/AwZfj7JNVsmGJeqTKrEjKPchW1NiVnuapoj +M9pNOa1TOPPHBSjTp6vTwnPzFGZWJwKZ1gvPPiCm07wkw7MakjUKA64VFQwv9GEV2NM/SWs+ff98 +POs8zzjDB8Fm7wzAeeaULIfMGmyTx+ESbPoEsGg5AYueg7nuwLomZPDg10efcL415yG0m3bZ4U+3 +hr/+AOjod4IZwY9bQMX3ELjBp8gTLGzjO57wHqDM7TN6aMgp76kDMHHLQfbf/HWgjfHseoj79WDA +urDL9jsmwdKN5c4z/Pb8vnk4lE8T0x2ZVcfy+Q7xkT2L7+LZe68t7tHnNZ1sGtMdqHhmKqHFIEsr +XW5Hi9e+M6hBhy/FIRIbbjgRJhaNt4b/AVHVdxZBHQ1ImemOG+Nbx9R2ug485c4+6c6YdicQWTAR +b9BS74zJd4YAHEvAcyYEx89TaQE4tQXgfEKI8YU1+XSI8ZmZ/775KnbL40Nu191MbpwmZKCI8xyZ +uFNvFf621GXMljo+8H3u+uhVWM8vw7rPAuoJ7FoKuzFPd4PPmtjWpsNJXvAG6e3QFYf1+j13Dgae +BkBMv7vdLz/tnk2KyBtzeUeusaM5uaOtJX/OhZNTL+R7+iveMwrN6JoxInWf4ehcjqP5TI4jy29E +BairPC26FOPZYkl989tc9R55kCyO9HbDlq4xVnagU4vtbJGBoUcG+rP7c/LZp4VHsg== + LvkTOyuUZ28jEYPNrMlZoo8XzaNBWMkdj7NaeYxVPM7Sn7dMmbrImwR5Lo6pWmkKjVILjKAwfkZh +lzB5rjLbssw6ZOXAEVNHmYtFeH+URXzPyMJrHh2F2eEnl56X4J50KOx3Bt3YuQL7UwXSf+pnD2tt +SN7ppxR4aEEDuF3igFseyJABxrJsE3rOJsn0AIAR3j+C9B0W71wxbsDKZ05geITX7rktM5P1IIoh +gOJ8CMXi7S0bqK7DOoe0qXmTbaO/4yWuvufrHTKtYzHCFjtAsQMRT8M9BlCzpRbOI4hql2SY4KkL ++0c+2UEAjJKRJSQqEwp1QwhUJOwJYKc7ApwS4UyAMAGwFAlKWgk1AoQI0B9/u/GU748741uPBSYk +9oMPBm5nbv/wdh/5dhsBdJH1EGh5mKeVlodlmhJEyStZMzEzEE1zlJ3+0fO4VREIx4MiPnG9JrKm +KTCrfF7mmTnmpBelhymOFrXsRBwgEM784XUu4WoVdX58109arxmLPs743+qcr7Bdfzqnwq5e69cJ +6WfRbGE2bFuep7hyiKalavt5cMSZP86rCZ+oxo9VIdJZDSLt/QFMhoVkTNUS/d8zyX9jnUjxf29p +lsDANUO2bqd3tn1GMwBgg0Qc03XPfr3JSJ8sI/2Yk94P9BmP8xmOR5O1Ldrm5mC03ZFo2+PQRlj9 +9ii04VC0TYLJx49zfFrBaa3vebLWd5W/hRrdcKgZmreRZjAKwhRIIdHEwyYaHj1FWWTyv8KM2Te2 +0WusvG71EAQtHZlnnk+Wgq+Zbm64hdwbYjrQaJM8ZR5x07LpNION5rWaLCFZoMkGAIGWXa9aGrse +GtZhyYMjaJ9ubn9wPVOZnS/5bEm04Jwry4cWHv31Scv71+hzpGfXa1kH2zkNej5sS2VZ7P91oLdM +3jBFR88CHuixGXN2j//i95gHfRoyoo+xAU+LIfignx9qfOod/WiVSZbnjagBOMwZxzhPPLz5yEOb +IRcGyoSQCCEPQhpMPIx54jHMkANHKVChPZekwEEOdEnw1uAp13bwQDs4uR07EhkY0g6lbwcq9IMY +xiOSxwPk15Pp76lAmdD+/JHI33k8+/mjkS8esf7BR63/zUwTza+vR5pn2nxGSFy13BSamcKzUjx+ +YI7ZuLrx3a1bG8P7cch71QzvLffVaHqf60SxaeLGcOdG+FvLZno0Y/y158RqZvlqxvn2M6R85aFD +Y0knJV4o4XzhASvnyvyhhYezf9Ly/jU60KO7K0aHRXNZzCfwjwb+qJ4NccyECCEzbLIg9oz6T8l/ +uM2AyNxuHiIUvYxhRlvE3C5k6ezxrnc85OlSOSvpfke5cQDIJyt/CzXubYj/8YL091LjoyqJ1Hj+ +m/PnVZzm2h9z7lOdohP79PSK5SSz6Da76HyyqtqaOvLM7GtzGVY/MyW547BnJzqfn2je7QJ6OgT2 +gUhfwL1Bo9UbEGW7v5cXP5LDL8LTQ/U95z9ekP6oGs8rFumCKmKKCu3X23Ki5OxybY9Iua42uSol +/LzlCG87m+YY151HxSJNPXxjAPMjFbhi2R8TZcJAgQyIC1HDKB/eWKbHYuBy5nW0bI6wHSqYHJZD +2A0nAsZvROVUSVGthSolHpkXUSVEyoYmEUIShPwHeQ9S3jUVFMhr7nv7j5eQ/tPXuFXtLOzbgJH9 +WKzo+Kbx365ENuxT9GOitmrqSnW2Kap1p6iWjYprZVBxPrJ/Tn7+SjU+rlBcOkLTCrX105PH9ieH +jWqQq0cnnUl1SmpcTcE67rCtfg7ecJJdGCBw/eiL6keIHi17YnNnjg7Nx1yapzksewZLPX5idXfV +NiPbDXMkBVqqcJADT8T0Y1b/wwXpj6rxgspxoZiiwmwG23Kq5GyVoEFBOncAhdToB05YOVoWmH6s +xN2QD2bynDCPZYW55MYdnbjL5mzJm+FcyUDHZ77W8ySvLXNds5YHs5VXOh5vaCGf6XrM8sqwiDsU +5j9ekP5eanxUJYHL430yP4x49c0Z9q5KtaTzO4VrVMW6gtayNnQ1bjF/RemHO0iNqx/w0I54uNn4 +MLZejHbIQ4cyLuazMC+FiNYGaTw50jkpPn5znPPN3e0ZNF0RRgXYm3AznDvtcLjmX4SlIGfzMJV6 +hWOqDyVdzbmMDsGPq0edankKKyHm0xwWHvUkzHTOmsczxTXMhHkDej46Eud4SOVKGPbwOh9dlR2v +9V6tquUQ0lXZvskHV/Gxjrx81pGX94jcsxid/Zb25MTAKZ2gdfZ4nXk4JBjJvLZpj9vBpe2Eq/Zv +P2xze1xpl8ni/vNwxOj+oNG9OAEJTaSz7UHTDbb6/qBV0zt3WXFlOLcHdvcs/BctkAbEHc8CuR9O ++js9C2QdzujbngaS/DQQeZOLJ4J0jf56sH2pnLoPAhSdiefXTaGW0s5rWyZZXYHhGKIHrSO+dZ+0 +9/3vtiPeZL3QHy6zJIVit9YW7LEqgPcCHPcDbv7olXgeHJ9/QMdDKPwBHf8DOv6vg45f1rPrUMjn +orbmJ0RtXT7uwBTGT28D2u5RT5yET8gBP0zrfmbVrR0U3M6t6idXVT+5ahnO0epn3fKUrjN7xnuz +3+38/KDb7XCOk5M7tlPx0gUfO+vKeUGsnEhiblAJm/M8T+LrHjlmY4O8vhi/1+Wh5dy8Hp7QzCN5 +GyH4SFxgr7PuYgL3R1ScvPPlaMDLE/syf91M70d59lO59uOL5ml7wZOOYjh3DPEsuxoVGpnQ0A5A +mZZ1tflv3NkXwv6M3P0q+ujKvpeown/544t3D//lcHz57Pm/Y9FsPv+1DqQ5Ned94JE0n392krK4 +JUBvCYvHZMW3fh7mNvl5S1J8Q3DZnSUoDgNKfxtFcPkAhvH4heMQOfAx0RE3w5EKjI6gFPuB8RFW +PGeoJ/bcG4F2Jpzv+7ifE9PvBx/4wyRFl+dMS/qa7VRVnTU91XWTr3u6a8jVKwMkmmR9Z6f4PiGF +/i7VtRk0HzVmPi0m5czBHh8albJNCjEc7LFPC3J7PsXEk+bEhxymNH2q45TGI6B8Rmyim+i9HGfE +eM5umw9DAvRH58R3JUHfpkA3Uze9yB8TCbSfHbdDzNJ7xwINc2WYMXZIwflE/5uUIp9OGm8y+V+x +xnMOtXOnwJctx5MaTzneGa3lbBrrbRJri776/LOPjL8qGoHV469kln1wBJa5QY5q8aCtI97Kri4L +ZZtA5u58Cpnv7TytD7Ecnj1Riymzn2w7dOxiQy629H63PcGf9LcaQpjkz1P83T4pyd82xZ/FbYnM +81GRWxo5bYhdRm7JLPvg2C2idYHQWAylC3wu1tb9LtFPOZ8O6Ic58cOc+GFO/DAnHp0T25Rg75Et +6zT31/vf/L2atoTy5T+8ef2rty9ev3vx+g9ffDGq7eM3n3/2D1/zu6jf/erZu3cPb1+LRn/98i/f +fPMMurz9dVjXq3UJK1zAaVniIaR0NcnoHMK8XMnkWvSNr/XXv/4Zv7/VD815+q9/0c//Xf7+X0L9 +s3TF4ZeHf/uf0+Grz3nXr3FBe1Kr+PAK1JPnHX6xIbf3+sVYxVnitoLX+Ocn12/f3b54/u7Fm9fP +3v7l8FM1iPzk+ObNS+mLn1u/fHn31Yt3b95+eXz2/N+l97787YuXD1/++uH5ux8f/gvu+D/xj7f7 +77/VWm610f+ocyXgyEs1hM4hc9YkmS3VMkTagcG1nXmZ1jrF9fCvz7SubU/Geb6a4jIfcr2KoiRY +R0k7g1R0yOvVIjLZQVjDFWrLBccTp0Oocrkwg0POV7OswMNz3lbzlSzyeMjhakFwrWgRVyks9ZDW +K9EfcGDycjVHuT7FK1mRod23Xk0lhkOUbwurL3xcqFc5wOVQp6u84v5yFWEE1ttKuhJ95hAWhD3L +0xZ5igilhxj0pUCIwrkOUZohErLdJtRZNJyDDHudZRYu5UpE1hnu/xXht6JTyeDmAEKItTVumaTW +kA5pucLxVIcgnTOvMjPSfCVNwnvYFTFfJb9rvhJpd/Y3D0u+Ej6ZNWEeEtMty1Wa63qYs4zssrT7 +lqtVuNEBz8C3eKlU1nyQ+mrCSdA5ylgwElgYkt8njULPfTFfCT9Dj8V6NYm+d0jSlcIshSBvsizC +Csh1st0nXb9gYOZijUnCela8uIx8yvycCt4bI7+2kYtYEGjwLMz3gFpEF60HeSh6NMSk45bylbC1 +Nm5xvpIPMucW6d9Z2ib3i7qyHJYkA5jlpVOQkV3XwyIPwxDrfTL75rAcyoKg+MquFG694jbZw4Qg +azWKBnSQzivC0/vsClgTUhniqg9xkiatMgFqkgFfD1gDnMwyOWV/sJGTF7taJukJmYvwiMmswuPk +MVVuz9JVUSYeZ3cJOgH1Phlp0fgLI9zLgtko19clY/FMGbN8v+Z43+91jd/q6NermqaKW7huXm2o +Ms+QoZJTZ62yXmSSoSGBHTH5Z5tJ8narDJxfJGspDXXwY3uQT3XQZBqvCy6xGmTGiQYY+nMaoU9Z +vE2/rLXCK9o1qzc8zvVKuI70ZRQWINPr1ZaadIJFmZ6yjScQZFMuQpDVuMi0bgQbO5lvopwOlyV9 +cq+oEex5dl+jhivRg2XsvKL5KsksGJ5nBLuvvZZf1l7cK9q1rzf97/8J//7Te+whP//my18+k234 +5s3Xf/nyze+5p/zs7Ztvv7ZN5Pwtv374+uHZu4evvpSH7Heb9fCjHx/+9V8ubDwyU/IyEVIl0slK +l+0kTC1yxxE2VUIed5yiZ9XbjpPqlfAt6Ruso2RzuVORGgLeXpk1scZ4ED63VOHCs3BfXoE8yyI3 +ao/NwnDCqhNW75NlqhVlrd4Jq12h9zXqPK12Y8DGHoUyL0YRziib+0DRWxN43OZCmdB64VT13Zyy +VpUL9M5GFQ7EBeCtruCH6+Gkb044gcw96ZYivCpI/wrTebWliuQCljYLw0wiRjeWNmNPkvGxj9YO +5Mhe+jXoyijsyytxgj2r9zipswxsxbNaPZOuYn/YNKzq/kZ+VXtnr2fXtP2S2E3CGIUbA7o3yVZC +z5Xsa/Ni6bQnpn+tCh2QP9Yke7xNwSB7rXSvMNwE53E2doq1HZgBXDZXYVdTQrJYYdyYYtjgJ9mW +ZCvCG09zY6eTcHFsiNxVwNRm4fOi/BzWJBtxlQ1SlvoqasRhlf1CxA+7D5tFlP5YhYHIHnHgLjjL +y6wiLInuIgThFTI9seGsa2i7l1BFu9Jdp0obAoQi2d3QsSIIgiDXV+lQYS1TTO0+oaYgT5dNEgZY +Pk+0i4Jdt6YV9+165XQbwqKZ5BHy7DzJE15tqWg4tm9pcE6cbJhGQZghjitvn597Z4um2C8SyUDY +xFBJI9iz7LZGldGWbjh4PQWdnJb+tEaw+/SV+lXtnb2eXdP2k28+XH/9CZjfDAlUhPVCwch6sFOz +jJiMtEzVq7lyc6iY0uA0ohNHJxgPyyqf9MukMxdIRF5PI9jj7L5GLVfQ9w+9IpG7sw== + TIX+PCPYffZWflV7ba9n17qhE01v0078BGt4lomTSyC3gjysHQmFA2O/yCiJqDYLz5dtmG84l4Al +LFyoyCqVNb1isdjskEm3QgDLMvgy80WAvgpYZLIklkkWy1zh+hYhuRG0Q6A5TEu/SpYS+XuMbWMw +gihA4zZgVBF/FozDDPmUbD/ZfSJQ1YLtQ1iz7wMz9JASReQnI2L9lIuTjiAE404JMqGT3+pkEa1h +fuEOtWKMwHbhqzmg+lWE007RW2VHFpG9DhfKa5acEjdIKkQDRbSPdc7t1kYma4kyIaGBsQlYyFmG +SlYHMAhowoyxai8s6zByTsuWukBAkkG+ignbkkzOSbYTGV0wbGybcxm6KUwyVoEXmponbFjuKAsv +LFjsMvMKbpzWYZ/lNJgnaEIAnQF/PUHDKBiGkqBryXZeZKmBR9dpbutJPqVFXlGU4iiahbyq9KTw +1MM66QvsJ+vptg5dhDN2xqNKk4o6GWKmNGkBdyvKIcjcZ+HnSJPTKT5XUsXQ9AuDdMIyD3U5wZ5p +dzpZuiOKkjbUJeLsIstoeKhR7FZ/O7/QG+CV7VvaO2Ne2U2RE3zKwaR+jHPNmNyNLGq2yPHo2Enm +wpo3FBHzavChcTLWWs2HoTJZIDO+6k81it0ar4Kw+vFC2ZCBNBsqc8r2qU721/PKvAn7tg79IOuG +fSRqcqzy5FdbKsISMlZd1O5OeB0RJWZRNyKmZSM4l0KGoH7ZUnWEvSIn2POet8mn1CjzBQBsryhY +q/x5RrBV317LL2sv3irat+87JL2PMnBBC51gqhoNWuB+olC4PQvKRQbmtBm05iTSm6hwW4MWJFsR +wFY3aKn6IbOpGbQg5sp8S1uDFmpbE0wEZtACL+XzmkVrpqVEeMjGokV2Cp7YTFrS/CuY1t2kBUKQ +F9pYtOaQIAHWZtEC+41B+qBZtMgZMfIbixYZK+xXZtDCpjIty+oGrXbBYM8CR00JO6W9twi6MPHM +bs+agyyGui5bexaopcqO0OxZLjs0exaWHUAHW3sWWDM7zg1asrJg0Hd7FlYa1JONOUsWZMaoNGuW +sIW6cCegMUs+xoR3Hm1ZYBRx6sYsqSMifMdsWcLbOWAbU5aI6kV2GrdkwUxapROaIUv2j4CX2tix +ZhU/uiELfThVESObIUuefwU/xdaQNcujudCaIWuW2ZsB1W4anfBjTuKNIWuGZlxWt2Nhq52qNKzZ +sWaRwTmpN3YsbGqUjJsdS54sW7isqGbHOllqp9scA5rmtLVjObXZoDA5KiaTmajmwOSSGzMW9rWw +1H7NDLMpbH2tkkbYGJc61WxQXk+zUrWHbWxZ/kb9qtaSVs++aVt2LlJU2tqyOtVMUOCbcc1uoxKB +FeFp69aUBZ6LaKrhskkf3OtphNG01KlmgeoVmY2qP280Zflb+VXttb2eXev+f2XJ+ggjgjCAUCGG +TonnzTRXiZFlqS/YYtzFIRs+oLVCmNUgDE6VczNmQ0VJ8mSwmXWCg0A6fl5pR8jRrKXY4OQCYWXu +vDDfBExKeZLHNQeDaCxcprJhyovPixPMLwBhX402ehkM/kXYeq3m9WiEdcUT3PxgVCyTacF7ytYn +LEk1DgoysA8HRmw0irWwivoCDu8XehdiVYYyUlqnnhohyqQWV+wYIkWZCayThXmKPpHUukzHRgB/ +LWofF2lh6RTrQ/hIIJv2CwPcGENV+rk90Q3pq+oUk4i2h14NlDEOoT+vUezG9mJ+YW9Tq+ykld+j +jOQOCIjLsuGnndcPag85fHP74boYgANvfj8IuDkv7sAzx5/s7SJD4s7m+Zvljll9gbYusP+IrtAc +T833RyEx8hnq/MP2Ipvz3L1/UENEmvIVpO4/KM+yt4fu/wPv48u5AxB712BTax5A7HGyPQ4+QJEw +ZAqIwuoLDTYGmfc+lubjg4onkmTpbkBhhvJ4Lsl2DQw1qWkJvlK9Ge4LpA4GAWBwBsLGUN2HY95A +yq05hcEdCA9cko52f+BMgaV1kvkDqbpDqXF/ICRX2bfC4BBM6JYmNnSPoGx52q7mEpyx58qgdacg +LRp5dmcivYJovvp9mlsQyv8aMN2bYxDdOCVnis0zSG1pRTuba1AUfOE/Isa4b1B4q0hLbd9qzsFA +F06du3eQd2ZQmnsQht0+jZp7EPXVIlW4fxAWUuo77iGUHVAEvGZHchdhCFAy5Z3cRxjALmd6/8xJ +CCMEp+nWSwjTE0VUdxNCY03S6YfTZXrZUYhLuMxe7chVtnEAFppzDtYStsmdeE7ZuguHC+kNHKqy +z/bE0WUItiAS7dp9htCNaV325zll6zUcLvSX98r2rTzjOJSxljeY885zCCMPJ6H76MIs+3CZuyuv +Ebauw36Z+QSHmpxij9w6DzHSGQJ2rwu6zRyGRxph6z3sl/nLe037Vv4nkbqE6ZnfLsIa2SY49k0q +i/hetE5suZP55KDOQkWm2ZsU4YykuAarNS6Ic1qgbgjPTzDvCA9R84A8TCtrFFPAojof+4XwDVId +ALfJ2L+zMbQ5gzH7rbm2W2XX4lPl1inCRAQTLYSGk6ae6lMRGhosc3kaNu6BPOumhLpgGIcdeJ2x +DCMcH1hCjWJ6TlWlt18ojKlCd+x1dco0sKFOloZQmOuVJWEVYU7DUxvleRtUvl2/rjXA6zpp6XfI +Q5/ERQ3vEqfE1kcNe7IOd3NSw68wJdi1m5d6FuEJBomdm5o2a97aHNDgKzrtnBLzOMmcnNoka57q +kFObn+apdsrWU90vbB7owFURR0oswyzrZAxrHn3T2POmbMO17abL7uoAURqHQrzakbF5h6U7rH2P +bV5kJ2yd1v265o/udXWKPXTruOZeTBOBVwYhm/a89tBG2Pquh+u8AV7XvqXfm/saHE3YRt1pnk5u +mqfbIpvmiWlCE85G8wR7EZ0huOYJ/UxkztU1T9g2aHTbqJ5uRGyqp9sCm04Jq3iBEXSjekKfnAYF +FbY5MMimeLbPG72zEV3thNkcpi5XJumdjHAUbbROmM5Kwtv5hd59Tes87dAzlqtFjSNbrbOTm6pI +OxDtj02ZxB906G+1TtqZoN/0C+fGL70yp2y0wIFs6mKvrKmU/akb3bO/Xr/QW+aV7dt62Rn+Uab5 +lA1xAys4/NWvdmRwJHoeU3NqLqqRYLVNEHuc4vZ52lmHCyEGwI/YK3OKPdUZi5FXmCkUxqKVya4l +bG4Zntoobt0356pf6E3wyvZt/R594wELeAmqHk5YwaoFiDKylkkZA2WOEGlcD3Q/ROTEArsvBXIL +4Siro1VkttBrBjt/mJW3irgS2NV1gmoGL2yAf1geT9OgQzYCfKbYwtXsQxDHXCjpVOJ6RdCV952p +qw7GLSBw1lnHTFqs9gRRkwJvLStsE8J9aHRGD0uPtXkOM0LEM0RemOHLpVOukgI3espEB8wL/fZw +szs+VPRD2UsKvfcRF0ITzGFWp7kCkkX2F/kClIrjgTrKZJmxgkS1ZzOwS9UJdS1YXFUhsAuOHoJR +Iri3McCWP0GAgBkVGmWQFy/Lqu462uVhyQsreJ6oTjG6dg3fPo6EwttVHVaYZGdtGN2SpzPiVHUM +sCnAWiI3pZIa9LuTm5UC02iCtUT6pyAogVrwsnSCzZmoiKPhugBrxlhVI9gj7cZGjYYH7jUF3Vv7 +E8Ow2Q5v5tf523td+2Z+j4JkyAA3EGhQBkHSycAHEE6fZkUy1LYwMV4k5KspNBcM5lddYOyF8Yaq +K6xT8AtO7UYopQvly3kQ5yCx0moLYRJOd0xyxU5AtaFoiPXR1I1BhoR3CBO3X1jWBpRc9RGcoYrh +WDcyZNmRwSlVBZMZqkKvU2QhdRmyk0tscqr5+aSiK/owZREoDLNuJO1i4BoYGvV9l/a+8oc+tE7W +1EZxnlE2ZDVWYhuBsVLaw4dpZeuolIEv8X2hCGhTVxsaYEh0aCb4lic1VEV/Kmf7RKMA3HkwbRFE +k3RIdEGDx0a1T9Kc6ncqcynzFc2bU9BwFGifOrGkTq1KVkTXeWkqS9yWkln7aVDAhWC1mHGwvSkl +bl43GQiS6inNgD7Jg03W02l/ym0wPYHbQ5NotXu1I8v2U2l2ETkmQbMHvlHehdtHYisbxRaHdHgB +Y+0Xyl6Wx6rscxzthI2YcdrafBiqgSEKprv+PKPYjf5ifqG/vFe2b+XgFZT5S/8bZj63slc78qom +VMBv6LmDgSIHTMslKDzPKQbYmBWVNFwoizfkTWVOsaf6rUYuKgH3yuDehaG1P7VR7Nb2ev1Cb4JX +tm/r0A8yPGvGvizqJLGYr7ZkbOCwk3LVqlkGAwrLYalEcTjBOcBE/EK/LiHFYBzqckp7qN3qZIhK +dB20ygAIgRTTnmmfjXO0V2tX9Ua1ik6a2bsANl8R8SqHeonNQzyQEyRnxSWK8KbmJUrmsMoGsoZG +MX4EuwmM9Y1M6FpYll7ZQLGn2q1ODhAF62GoDG6JmMenGuV5e2F7Pb/Qm2CVnbZ16IcIl3RQtJbo +P82152TY9CDDg0NOS8iElVG6AwpapL+lU5436SXnZRkvJJyjDpU5pT3VhQkjm2GkVyZclTFc/lAj +mNOivVy7rDer1XTS0O/NWOCobmwmUbb8Ldgd+9nCnLMN7Y5taslwZDW4O6wesbpDoAHeoSrQJeWI +d2DTc6HF2yDvQYQGooF8NIh5h4AKWcox7+gz9bw20DuujdkdSAZ6p7klLamj3ikTMeqvwd7BdOO6 +h72jfQRkOe4dprgAxnXaRWe2K4OH4w8qdFvoO7ShqEqQAs25qwNe63h0pzz3/sfOMFxo0PahrkZp +D3WFysj1CqCyXpc8KxRKge2hjeLyY05xvM6b1arat/Oy6v9JcPB0zwXHu3ayok4a5BxTTObS2pHp +TjGLiCHYhwsN5N6rcoI90u50smz8yxQPQ13FzNH9oWU0W/vL+XX++l7Xvp0Dt4PxOEE4kLksam4D +kDhZ5C65FaGWgCihCbAxzubznHDYq1NsmQjDScs8XBhhLa9DXY3Qnuksi1SY9ABm6zVhbqV1fGSj +mDjY3s0v9Pf3yk4a+j3aPhxqjYVFhPkmMoDCHI2VLTQAqydHMj6LDYCyNESZtuAAuh/BHTw6ADLS +WkLo4QFOMdFI4wP6dQ35D4ndDPKNss4b1cnI5LaQqT1GgHKn6jUWJAAm2wV0jxKAq19VkQb+x0BQ +Cu2UBeYLv9XJIgdNodYeJQDQEoEGHiXgFJOcLEqgX9jA/6EYYKJTmkXDhS4jz1fESLcggUAnVFx6 +kADARkt/3xYkANeIGuZakAA8HrGY95yKLpSSQY1pQQLACRAJ4kEC1F4ijCYtTADVdzXGwwQAnaBJ +x6IEMA7zPNceJoC9BvmOmmRlcQLQ7pc6xAlgN+NLnM7eU0t0A9BjNGeEnbzakUWlw4HcjsZny9ch +VKARfL4Q3d8vswCAoSan2CPtTifPTZ9udQEUFsbwBKfYre3d+oX+/l7ZvqGD0tDQ8w== + wLGl2aNIG7jfyR4AgNVAH85AyWOETCfDQkZwgVcGiR1WgP5Uo9itBu4fLrQAgKEyp2yf6mR/Pa/M +m7Bv69APDUmPqVSSm9A7WZgbsC4OyhcZ+Goi4ryB953iPIsg/35hiwPolXWKPfV5m4JGns1W0yub +rHn9qUYxHuCv5xd6E1plJ239DqH5k4QNbCFxLW7AEXEeOOCQOI8c2ELiPHTAIXEeO+CQOHfYbSFx +Hj3gkDgPH3BMnMcPbDFxHkDgoDiPIHBQXAsh2GLiPIbAMXEeReCYOPcAbjFxLUzAIXEeSOCQOL9k +g4hzB6I3wqMJHBE3hBOMiDiPJ3BEXA8oaIg4jyjYIOI8osAhcS2iwBFxHlKwAcR5TEHDw7WgAofD +tbCCLRquxRU4HK4FFjgaroUWbMFwLbbAsXAtuMChcC26YIuE8/ACh8J5fIFD4TzAYAOF8wADh8J5 +hEF3v7cYgy0UrgUZOBLOowwcCedhBlsknMcZOBLOAw0cCXe6Os84bA2Pv0XCDWSDrzm03wFuLQJg +C4TzQIF+XYsl6HV1yghMG8iGYPPKHOXWHrpFw/nLDdd5A1pdJy3d7g8E52/RcAPZMGwN5t9Qbh4M +sAHDecxAv8yiCoaKnDIi0wayQdh6XYZy648cwXD+Yn6Vv7pXtG/jJZ21uzth5xPm0exLToa1oqiA +lqu+0tosPXXmw4xi1gVsA6GMFwoLi3EZ63KKPbQbJpQsiyzQnuKVmYgwPHUUGvrbtet6A1pdJy0d +FshHae771FvUFGPSGVDACF7tyLMGJ8HmI7JR1oGbouotIh3ETnFjj2lmfiH2ziWOlTnFnvq8WQqN +HDUieKgsQw7I41ONYrf66/mF3gSvbN/WsVc/QmeFu3Iqqr7ksjZptpNhTmNaEeDvsZ0Dd08VIk8G +OGwU0+RaGhW/kBGKeRkq6xR7qjH9Rl4pQi2HXplQykqvd3tqo9hT2+v1C1sTemX7tg7cKlWTTbBB +YfG82pHRy4ayW3O25C4zhC09q2vtFGsMID41jBcSQD6PlTnFnuqbn5PrQtBiqww2uzo8Uz/bbe3V +2kVDm6yafSs/1drcJ3OjQpoMnEbU1KsdGYgvmmkDmFUh5kWTgURI3etA6QtsmTcXTojzLGNlTrGn +uo3JyVRxe10wza7jM5Xg7MDerV02tEor2jdz7NCP0QL2zE5VQoKELCj01Y4MYF3UmPJIL6mMcQm2 +rycK8Y1iCqBt+35dbTBgr6tT7KHurTZygeFiPvS6YOYNeXymUZ435dlezi/0Bnhd+5Z+b5MUlhhR +h0SFQF7O5voyYtL9DC4o0XOWA5SRqvoXObF9tnaJnFhEXveLELFSy1BLI9izXPNXqizvRNd9q6do +eHp/Whnj4/2djOovbfXsWzb6foPq1itCgNzl6VTpsmlRZy01rhWzN6oHmNpxIxjbXVUx9suApaiq +SGhFTrDn2X2NimkCXuUVYUFBaPfnGcGdxfpafll78VbRvn3f14LkjjyZ3rLgGMlXOzJkw8UCjAJ8 +VFB5pqDSx1Rhmm8U53BLpJXXL0QnrGNdjWDPdP6m1KIY96GmalH8/ZF1yHUyvJtf6O/vle0b+olE +j32HhqxGcArssMq+2pJh0YEbG+pemlcF/1BADzThBCeYrAoPX8rDZZO68oaaGqU90u50cmBzDr0u +WotiHZ7ZKHZre7d+oTfLK9s39PuSkMFTF0vqMzvSpVODITPgXQYMe9a4QGW9NJI0gqmEESeilfE6 +LLt5Hetyij3TtUkjw1kDqEavDAls5zo81Ah2p7+cX9fe36vaNfP7maA09EzUm0R8KNWB2E6GWSur +kKYmReR6QhJl7LFxZQ4ao1jbmF05jRdOZmzqlTnFnuq3Gjkos+iVCUW08zQ8tVF8LPT1+oXeBK9s +39ZPtgkDsxTV4Rfx/asttbbUEIsZLRkkldSgjGMfOsWEkdSyLfqFIpwhE9RQmVPsoW7vUbJ0HfPj +9crCpCFT/amN8ry9r75ev9Ba0OvaNbT34KeMkPuOwLdP6N+sLbXbBtoNiBuBVg3ZLc2eylw7sBsA +NO7VG1x3RaxK7ahuWCAnZiAxUHfB4NDsOmK6ZVkI0ygd0o2sncAZO6J7QVoMQrxHQHdmuuzU8dww +1tKp3ODc8I4QfbdBc8MAPjX8FkS7RFxm7FjuDGQ+Fc4Ryi3P04iGhuReTEdxIPcC3APsJCOOuwCt +FtcO4y6rLOoYO4qbkjaY3gbEDVOyocYMxD0r0HLuIG5igGCx3IK4AQQKk+Vlo68Rwhxl84bhPhn5 +E5tnhQ2ceLgRwd2pZlRHws1SB1w24unjCX67wD0B41OjFnnFaulOWVEnjFDqTjXIda/IUNn9eSN6 +u79Wu8xf3Co6ad93OIA+DqEiyugKYMMGuu3kBt1ekUVHPjfkNnwe/DwCt+HhBjdquG1h8LJv5g7b +Zj4gssYRBQCfDRWZhtrOqz7MsdhYB+jIDWRblvzK0KhGjUgOOMCwEc61x2rHkTR1gPa0Q2ZPHZIN +tDQAVw2RHaDu7PHY0N47FjvYmzSANfJhmVTZH5GyYvsbEen4Q0wdhJ2slg0E2xAcJGTrX8deAxOB +/t1CrzFTS1o78hoP4Lg04DVmHKOJN8DrUo0dGO4aHURLUoNdM0VxzjvUtTCfPDOTsYGuYbjmZQ1z +XYsRNpDrmfkHoFY1yHWfnA1yfTpdT7gDeFfCcG0Q151qKGkmkxrA1aWZyTZoa8xgSn1+GeIJpqXX +0wkj9LlTDSLdKzIUdX/eiLb2tzJif22r56R1vf0w9OWcd0DrTm3QaLOqO3gaQQ1lj7EWIZeRNR1i +LfvzMlbjhC3AulEbJLpV5Khpe9wWXG3v1Ij9pa2ak7b1ZkfGYw8Q51cbaoNCYwni4E9HS8dkyTI3 +qGrY5uY6XIWND6KX19MIG3xzpxoOutVjQGl/2Ain9ldqF3lLWiX7pvVWI/0WkzVuoNSdauBndOg8 +wqYB+skjYFoFiGyBmH5ZUq9Or8gJI5y5Uw323CsyZHR/3oig7q/VLvMXbxXt29ebDjsU/PQb8HQj +NrSzrBfNw9kA0TCOMb/qBjgtjE9DY/0yEYWmPGCwnbCBMHeqQZ29IgND++NGyLS/VLuotaRVsmvZ +JQcfPPyBucQ3kMpObjBIBPrOlMsaUlL28Vpq2iEq4WKfl9KpFdm6mRveanLCBtvo1IaB9IoaTNKf +t4FT9vdq5P7urarTRn4/Os1HZf24+CJ5Ovzk1w/Pzp2Bc/vi1Ze/enj7/OH1uy//x8NfrPZ0+MnP +X787czl+PfvdywdtwC/ePB9usvix5eKzeM7Ov7z46t0f7Y586TG/evvwpxcPf5anvPzmcs8MTZDX +efHwzfgyFy//xcPv330pQ3D/9s3rd9959W/ffH1ycYR7TzSqR9v53x5e/OGP757a0F+/+fM3F0f2 +7nM92+nu9Vd2++dnD3v67y/+9ICjnvibah6jZRHnG1dVIeoKQKfM6lDnaFqy/tqc9GRw8/c98ak9 +sj2g47c2z9UDm5zsL/iLsY7z1G0Vf9Uzn2ggl/1kYnbUhIPUoOXUOUx6cHdoB3enbfKcrDHbyB2Z +PPs8qAhrQdZ4BHaAIPJNAAGnr5HAlpLgaC0oH7VkUDXAG7gnVl+baXgFNohcEyrWjUpCs4ZXy1Yh +HasJeiJ074LkGjA9yvYuqhmdPSLT+bkTBaZKenem1Y7nYDiOEAJTw4BQ6ROK0QU23jaRmjJUctQ+ +YwMjhk4JNZZVCTH01ulJA1EBBBC5aGsGb9f9lzIIfB6yL2vbZFdfc2ROi5U9ADArUnIwz27Uzwvz +QAdEmrW2jeS0zHpjTKtSMkclI6c2YWw0GA63ZtQsVHYPCPQU8Lps4XFFlc2UljZ6SElf5pmHsGUN +dkc7kDyEyhfFcHwrXexCLCJPmNca2b0WzTCLy+YpyiOywtQ1S5xoWiV6qMSyWPw5A5HhpKSZuKhk +onFWC/Bss6ZuYmpf9zZpM+bJBmyZrZMgizAEkxQL6oILqd+aqAnPODcvmSl9YW5jCCqrPXWlhIQQ +SLfHQN5aoqpaxA0QVm8aeihqQ5/YGTOPA3GgEw6QCPpyiUarguwBsH9Mi8XRwczGBky027XZA9Rn +iTrCsVYNJK0JozPBrKCg3MjoOaQgmj3lNl2QFsJWAizGQsn6kUuz2uIhZfGXBaYwTnZh5mV1rirU +iSKq4GAc80hKjn4URIW5igau2J6wIPYrcm6IkhqI78M5kZj8C6ydN35nQrYZnk+gqf0iopjhTk3M +7AcjH+YeMqIuHls46SpfYYIjJnHSQF0At2tQ92vAHFQcZhjui4Epn0sOWju8ckQOagClyHGLfk7u +lofXeyGmMxX0JzyZq7zdmizFANpRM1GYeW1DyEwR6CU8DSyMwVxIelqZbsXCjMAKlrE/SZ0izyTj +FAGBqS9gGUo4t2225B0gLPMQRsZOA7UopqlItayHOM05azcTTO/pPBiNtJBTxyla8EOidM7wL7jA +ZQehugB2YI2LGusDFXuieaXqVTCIVAPpJWYLRic35xGpiA8sk645ECJGCBaetWqiO7BJfF68TybL +gQBqtNtEuViH2yqwNrNX/LyNAfcRBI1gRDHEC9RoGCJLVnRGQWh7WZWHW/NmfV4pOkNpFlpnnuIV +gFyh9Qj5FxDmMHkeT1Cx+BZgIpnMzzY0IXAf5RuhIhDG26aSWBlzRsrTuCnjolgt/hJcAPV6VCoS +jcEYVqaWGVMWIOY3A5U1RUBKgTZGnFDauFLQ7KUL0EmzOmmxCSLNF1kOAjLwVBiXOzMDVY84ZIfT +/o2nJ7oHigFxJxJwcGzn9qVUZpIvdVUANBYbbsOeo7uETFshrGsPl7JdU35rhCas6xAVcGxPmtWp +xIy04IuyUytHwThXGZ6KHXlV916FAFBWO2JhQUK/FV3C7KS2VxebPDP99jQ7p8yVoqwyySxF4mT0 +f3RvIahRxzZaxj8GrGIYEZDKPH7YUZeobMzFibXanABTIwFbEmqnmztVTUwiBEYd+eOm1RwqNLYi +YAYWHya31dfW056Qyl7EKW2cdKxOk1mxLTAxMuIY3sakjpq5arbxZennDWRtBAzWk7pluMcV4xcn +EuSJlZEyArZRYXw4p3fIahB4UCogutz9A1Nt4vgDTRAgC4KnS6bkoegLE5eRSn5BwoSAr9nkKRC4 +xGbl13afML2Kvajabglfy0TsHUI7VQ4w4VMJz5saoPtuuwznPHAtZktEhNSRIjDCboWpcdNuWwr2 +klVfhih5iEfwoi2WkIF/BDTI4ySWSWcgEuqZcDKBRw+fZcYvvGv2rRfycylaFwWohfHCiCECTFPl +I81gK53uMdT0gWEHQkg2Njy2FnsHnXFh+Fx1BF2kFb0i4zSPzKj2DNBY4pETsljV8kUkRUwKw7PX +jHo9LHxENS80zAYS4qrHytRJOhX3TX4YAuILJ1k2zGFU9D5qOkIgV+V9GKWYdK+05g== + yWvJzgyWMmGEQFiF19E6r0wnKBfBAq9lEPR0YUJUymp6W3naQDWT7QJJuXJPpV/F7+PbL2trTtBN +EIRs+RMyfM8gTF1eLzrHkNk5W4qmKHMcR0QwpQIWOGTCXDUn1k0T89nbeW7JqZhKU12oZHKJoRA8 +rYMR73af7H3oXOoT0dCnSL6FwDyekhSrcYZZTbHP3bBQyFWmsmpirhD1REsREDSr9MxNdVKVx28j +wgnbU4YVnwTwYuL/V70PO06ZtHnG5mZdCtwo1BxMQQQeY4C16dhGN2FFrtHZHGIg1qR7aKDXqthb +ViZmgKsr4wBPI+jTZH1zF/TLRJBI2MbIlmpLBYHTHEZZksdFySTBaS9cMeAT2PkBFeb+2BKAISPc +Mp6bVoKwwmRDzfx9XGkIUp2VwHzeiAKEkOf3rVhYqR0VBAIy0bB3Zs15WJH7GoTqURqzyWl50teF +ERfvS86xaiJCZrQBrwaf0s4UkXNBCjJ6GSetXRgNDxyixgyDI/V/7OOdawYLAQeVCxRpMbBgQKgt +YalMue1uDyKGHChqZj7jVYGEwAQkqEd2HBKq9yYSQ4DdYSJDNcUYL1AgZYpT4ukEBGz7DuzUamok +4y0WnhiCqY5YORXb9LNNaBOv/CJTc5o1oBN4Io/H3RkVtg2q8UxxK5UnqIfYktrMTAZzs6FDDr1E +qvo8RbksgIGkoBk1MDMrtjJ0CgbF4QPUtoUamwJHfQUEOogwxWshv2D3+X1IyIHKoDbwMyJOMCia +wQn6hx4dNDAxpNiAIAzP8rQYSjgxV7pqVzQZYSUy5WhsUywYT0OKFJthgUEXJtFjhdHCQFOOPw7r +DpkFYctZmlG8qmfINGZ6rvVxq4cyTMR/VFIBsCRhkRmFFPdrUssehxGxf8MCmgE0QOJt5fx4T2px +AA1q+gSYqBC3uwyaAEZdNYDSZLpZjUc4MWlWwH2A9YNHY8XGo5Pl8cLOrKwc3BPxeWbhwixMK1Mn +aqYVn5uibFHUqpybUUcFWPKE7sVtM4O4cDrU2m+jZEbhK2rCN3ZaaOYSTPqZOerJN4xFq5iAZClL +8+gx6wuiFosmNiowYmGD71ylUZFHmCYK7FNBj17i0LGP8LaIpM1DuKymEiqWzw4E5lYsxkRBwFAU +Vc78Nt0eLQEKE/pi/iK5KbsS2+OCqV5U2LL7IM/B4KI6GTA2ZBZwwDapfqHkGVSH9N1VVyXyfFmq +Q2h4iFRuaY8wndtnV494nLxfBJVCdiPZO9S3rJ8RUpc9oLIRs5odoIpVbuhrS0axE7wHBzhSdEEg +xM7AeWenAiCCLjNqkbnkM0+sVcQeI6TITej0K9xfVU9GNgSehAGxHOo/kklrzn5Ee1I0zXbyRqiD +/RDkJc+aBHVBf4GS46S+rAJQByiJR1uAMvkRnQkO1Lxub+XRCvqMmoyyap6R5MuEz1hTS0hiB1fk +ld64oFsesNqlmKmfu4M2NVaV7LHTU19J9H5qMDQtZ0ibnaZVgylYlz4UHIZHFLAZDIsBw47agpJm +PWhjnoLufLRB2q0YjtlqzDyjA0vMNmCaqElJNdimuQwPDbNm8CXXx3U0M+v7Iv4Skb4xKy6V8qrd +Ckz/arJJ0exOscL0CB7NmDowv2BH/4TcU8NGW1CMzM6aDjTwGBMk0kd/I/duJGh4HWysCG/Uc1Gw +HSRGFZvKDQqlYaDqc2Vm2Fk1RHtdjEPSNLXkqAwvIoACLcmr4vZ11iPbVikDTp8zDWTOAlYWi94q +/E/DJ2mBJmX1E+2pvhFEGdSxwXxJySScZBmCpikqspoJRtzgFizr+zzTDLla+OeM+W5R3BTO5kW9 +Ls+bzU3Z5KxQKRDUKUULIY4uBmW2FDy0hPqdqU5KplWNF4asPueiFq6WBRTu5tq4aKChGkuLkY8M +hV6JD8N5B4uG/3I/wrpgBWZBK5bblkdmMscWTH903UMWZMQ2Tpmz0zbT5A4CmFGTUSMDBmczlsNY +yL0ax6tSm56YOGFIvWky+2oxr6vJWtzuSzYKnw65fvUtDW6Zlj7VsoThjkWdJ5q+E7HbqyUzXyAq +aFPRA2BHU1TLAgeU22AzMMNUR5uu9AFNa92AVwE4WLlTwOoI5rsyX7F9roknx6++sCcmECogFrJq +1EI7c22HtgBHVXnb0mcPfBCwx67ZUojMmgd2NYaDNZ3XoO4appbV1iF5+ASY1jSp2QnzmkrzyiM7 +Vwbn0iREqJyzPfhfYA0DdZ412HfBPr6a3kYCrLJIn1Ba+iBSYeqANw3aJCuyk3bjkjRGmIZ3EuZh +XTFMjcmdJ20gZ8tqTkGGiBRZqiswJs1kg3WLxP+MSg2axj/FwEPSyOfRLwp/5uqz5Y/jWwKhbZnH +ASEcuOhn+M6Y7ABnVzL2249MQ1ZiSE6oDF2B1HZqVYPTLGmShHWNvGKwfwee3pmJtIEuATYaVh71 +RlMAA4ywfyDRCFR6Gzum42fYGXXD0PgcrKgx25aFc/7i6CeBjIyjaECdeEgThO26KgScH/my+D7E +4a6a7AhypNQAgeabEvvDIFkxo5RvybAdQRCgsRrzEOIVDjtaGXQloki9aqd7UjTW22ASSVGpMxNE +2VaKlB2wnSqBJxdM0dMOgigSAs9BgK2T9XAZJBXm+DhYNZovyu7D14FzPhQmYoN/YuKBChTzcW4A +Tnxbo15g8lHVHkIGYObSg2rIcaomLxFAXbjos5tcQAXkC8QMnwxyb02FnjJ6qghSQOtXtar3uzDM +8ONyH8nN+DlNuhWBsuRVz7XmxLM7IWIT9DBpPCjaU6IevSCrvzLpm3AHc4M1Fx4EwKCsTzcgpGam +CMQUWvADLcQ1qz5H65o+cTEDPHyjwjQrL8x5VZ8vbZxKieruDckn2sIDINStSlswK1MrzKRKGZ/K +rBSg9KfCDMLXo1qH1Z6aUEEwftCs7MICyT5ptTTxL+ucR1Op9OgBZ3MxRblauigaxKADVOfYcK/z +vKs5ajpVzLF1YpbApB5kPbMtanLSZW1bIciZNjeQyWhoOoXUyQuNIkJwJaX4XCAmYdbr6JgjhYcz +QvKH7+xUFxj0BPD01PTlliyE6SWxpQBsiWANEJj2NJt4h9O+sWcvi8bNGmtG3JOwO5j0lPPPukp4 +KqLdxz0LhLjEft8EKQXU2XaaFZsYqlc1dTJP2TJoOswNAVUDVp8c1TvJKYVTkJnqDX5A+F4ij+9u +MouZeWkXpQ+TtmAVYEVuYArURlCxAYlrzIWrlyHJBjpkmajYwdtG8x9S+E9uGwUVu0OePLlIkllD +Mx1PxQ5qpcDnNo9A5KaBHAw0FZagRjm7ip49ZP9HrR2+gJx7sn8Sd6qZwyf1bmW16wJZgI3OPpo4 +FFWEadcwUxFNxytDAu0ztELvi0abFQuEWABu06J4UJ4BgIAGHftsPRhV9+hXQSqSVsSq3i0n4IzB +vPaOV2KyM9wRZVE5M+GigE+eyzSt3c8KIrobtGyO+wVeGjjuNNF31S7GWVPTeBsS5MLUG+wq8mrs +VAQnI7PGqrcNhuyK0y5g4Vl1rjE1JHRoGFEJ8SlVFZVkjhG1JAAzBREgNWsKCXhNKMZVj5NM2FmB +5il+eA+oETjkWYPRQaBNOgdDVhdrJwil52tc1f8bzI1ZVnXsca+a9TWZrR63TT4C8CdOid4gPemC +GWcyDyinqbfaYoWAhbV906ZjwqxAuKk+blLbUwyKLAOBEid6xVEYJM4k0pPP2+C7YiqIotGeNIGB +sA63cVuHeV3T50yKCGBqNv0I4xCqHZyGC0SPFVY4NVTBRV55NpX6m9i1HHHoue79A7wHexm9UrQ0 +mZoFCYiKC94Hb5tEiK95yJhJYzpcrHFRbzdFJJxroKimVR1OmO39DPrFNnpkzaTaBwJUycSJmcaK +MlVLe555EWeuocTm0NE0OTeYGkZnUvk1X+lKVFjeYjisujbUlRKMESRLk9ouQ2QUFDgkJctVk19R +pYpkYKkzHdqxo+oX/CybA3LnYanzM7wL3IHdLb5GhgCpwTPyKtrKkKKO9j/IxNgNIrUF53CwZrNh +E9ukuvPMY+hppnYCXDtlOBFGiasBG6k/UQQHXl03Ct2sjIXa3jKpeztkHSEoiQUpT0JDhiCXMx3L +RQ2IrtXQC6ZWN3wkuII2TDh65xYPWQbPqSYuWrUuCjVzA3QW3QRI4Jk9MH/XIcGtpkiqzTaBNCo8 +gtQyrxDjJN2GdKYA/njraqEbVn3bTC+nV3HoeEQQhHj00uqHmDDrDVMa6ObIA9MgDQdTtoiZwj6K +K4KLq7Brxqlon0OeAKGid2XlEVpF+3VW//kU/XmI/5Neg5WHEmbzc4l0xylyIvbcuER0Phm7jDCW +DRJYCM9VXDIwIxauK8w9IbBw1VwWLSuA7Ne73BWwXGeKUfRCvnIqOCAyAGuOdAzyxMvUAg3bH476 +bQTXFnluMnCcgEJyWCF4Zl0qms9ipbOSm+iNS1tRRZUlMQuZaasIXaN0H3kK3MyNqNtjcYxRyhSb +FuYUh+sV753cRJnUdpo2FsqkFmCkjYbRhrWnyEhGsoEQDSlCQh2MjAXKAGonhGxmnsJ8oM0Xkjn8 +W9h4kFUz9+aZqAq5IgabkoGTlhsJZgdRAtCanVeOVGwr/AxRjSfjFctisYJf2LlKfhulrmAWHxCo +3oAAwxgJ88Qr6Dh73qwRETkteeInjU5Z0adMGAJVYbbUSLIkZ8cuwN5WcC6w6ZkAieIiZMKnkchT +H49WV+DOKEZHE+ehtTGh/9wWCARUhd0EZ9S0yFBqRwyrnkVLR2QwpsALaB2c1G3dbyMoztCdjB/K +JBTP8sZlOKlF3d5yJRwZPcomQN+qPCoM5xUwspO/rvpWAoZUMieHaJ+QYdasigXCTomMgfWK77yq +30a3O0Rzs5dX9Z8By4opGxYFUzKRKfyPIQ6WPFDB/9CPxDABPIlBw3l+dBLWpDIgCHVMlZBp6VNT +B7MdJGa5U2ArCdwtova030YHFgaXUGdAM7Hdx9kANjiaCLgh+N8WF71wH8QEhOrr7lAoUSMQjyij +YpZDLM0pD4BBq2vh5l/MLIllzh2vmFwI9l9diCpBOwM4sUl1HPqRozEdEGivJ8E9YqVQioTTmDbw +OikqTVid4p+RKZvIi0nXm7aN56VjNWcVeOCP41YAt/tigf/0owNlN/uRv6BCJAHUjr5EuO3gWCaw +M+l9WPi4ABKf30aAAqjVkrczfcESzSkHAoRuIj9djM1FcVg5KriNaDcIOUxbzo09OWKC692aVxUv +AfWGukSDBiLbAbFYACEBiAEQ+4ArC5onZ5kNYg3CqgRF5SxRQVLLrLKu3RfVco109TwijdjEvG7u +I9tizR23uSgHEGWT60i1BCBJggFQSlETTTY2dtOUCT4vt/MAl6KWzmXSPQQDTOUc8ObsOjGohUho +qv/4TDgPMM4UpiDKs546+r3xmuCdi6r/+Ez1wAGfIBRFZk/9PLHJlP3JTjcsVYU6Gg== + 8SY9JIz2hbyqocNETXNkLGbB1MMMI3NsEGNJeDHyOiRFmBgPy8piwFzowcMJXng+eBAmDwg0gIPg +NuYJ8FDkdkiKEAKBOgPqqZMnq+LTln7UIdLlG4iN/oHmV4D5qqnUBGDB24/mG8dcKJki1yHR6s1/ +Au0RNjBuMphgeR3c5ZAQdfo0KztTAS8d8ox0t8BZMNw7u2gT1P25GHoE0sCE3WGpTWLEetORdQQi +iPQJgMoNKkS1SmLi4LwXEgAOWGq3aHhdi4bk6PlssDbx8Fv1+dEsLK0gcMnM7sD1F84TlaLpUq6c +FnqiTcTsngkd6qyP4h20TFBZPQRA+Z3NEHAiJnZ73blwsx99AYDxLGP/48NPfvPu7YvXfzj86Hi8 +fv7821e/fvPuGS7ex5m1Q24gTiSzqNJk8KqRFacwT03WKpZhYjaANmUIPWdpGuBFNMElO42dVglS +FnsGkbSkTBb2Qwdb90HqoU/Mej/38/OYJpxyDgyIVP8axUSORfEw/TqYaIKlY1G9y/xgi4Z+3bT7 +VOdE5BQYCTWvuR0MvPKUmFmRgnQHxuAa22xAKPThpAKbgjmm0syYswHEd3dOurGCTLAPKYz5KS0W +ZNYQFVDIsVzf0wiuqhwC70+pBh5RwoDsM1Dz4DAuEnMXqqsiwOHKJNoHHrlsg0k7BQJ3XHfWQ89X +Ui0TndnKQZhtbInVwX0p5X4f/fHMqpj0PqKrYSAAxpKEws/cja11URMk1Kz2L6achhWlNNs2mBf4 +LjazjjGZLCoTMF5GwEwmamMT5HEOIKAChHi5OYYCJ14eVJ3kFj0AXC9l90n9MLjA9z4qvVj12fDs +Rb2Mi+VgsbNM6TbjXnfjOvCC6PHJZMEQFL+m4fHFHLMTc0FGuFn9vkV2xgOzbmAeUy9aaQlXkTEq +01mm0aROkxZ2zMn4JUREhKThMo4l/R/K0yjUu7bGyArsfTwbg6DsRAkBuh7rAbp3sZ3cbgMPyIQY +q/ZCHJsQCsCMPOIKJiupGFZHCGLWuqqIAG7Qq7JCRs4BBaxuQkw1/2ieFgAa16VfhB0XXjqRJtSX +DKllhmszDdJO4PAj+1GgJoGMGgj3zLbv4niBJJsCQ+u8acD/QxmubW1CpoNmqElA2/FHlVlBQz80 +DSmMgCiENZwbJAjAMOCUDcBAeV8VnoMMJ8viz6uKBUKiLho9mGakEj6tID6ka0ZFyMM/NcMTPX7C +SiFtUyXBa2KeQhuABYiHA8F0XpNOWH1civa4pPBnECrfKimvIQFODMgRHQMEKkYcGg8RS7wMvdBS +W6JmAJag3Cw+BpAqgLVnxlb0OnB36oZXn5F9FvmRcr3dZUSzHKItNJngbBE9r2c2j/s8hNIAzJWD +RsroZTEreKIYMrgTVsXY2H1GrVn9A4E+Came6AEsA52WcH2sfogxcf3I4zUbUAy5VGHhh7jIcDYo +G9pDDnuk7w94ONcB4fpbZkbm0WRH/11RSa9HynDOVx2AzGtW0Sk5HEFXBDLsYcw658JSh+kcvt22 +uOYZHpKpGQIgsWD9rbSb37Sh1hD+iVHFaOcUg96lK4cMclVvu3cHuG+s6plnM5AwPzKeUqVhxk/J +esFtHmMeqEgVvgCdqPgMBygc9WTmjKfSelJfNuhrOJoRU4rZB58gcWUiAChGDZj6WDXlSFctMNaK +ZJySwn4gxlFGxWEe8LPxeEecwgMzOGQJ411AXRBYo+sbmDP1iSNMB90bqyK5eQxJF5FgmVqIOFoV +bEwKBoZe8pnWYsQLTCpv9fgh1lgX9XcHBSNWnS2ksJ2xqn2NlAHsp95jZJ1b9ZhsIu0p52C70TMR +86y7vUNLjAh/OKEjhMQw3BvvynFEf4VJz9vrAHWehMXJNaunhoRU9DplpbiTWKQ5DYH4JHOkYBWH +dM/DIme9U01JgPSBB5IymOOKOlxnyhKrJq1dgjrcZ1UcQoNGWGiH77Nk4jyVQ4+ZXFRFAfJbodEt +bN0I3bim8H67DEcyM6c5sINkMk6BHrHWIbDTyIuF7mIKzuri16l4Ip9/elWAcQMMnzIvqWe9I+gW +8jDD/Od2VoUJZTwuiEC/pGKb6oktAo2gDebSNwsPQls1QMfOVNUNwI89gWl7hfcGk0oBreSikcYs +JVScKagpImK/j8axfp9pVa16JdBP1GVGPo5RDKoFE/VJf+OqpjFGT66Ut9Qkp60Dbp7n06j/Hn4P +2FErrK1M12bgtGjOJX0YQwdXvNLkuS9pBYpc7RpkSVd1pE7lISW5OcJm1QYsrR+BbkXTdkRa0XB6 +YR0fB7t45v6hyTyg2/S3rIq3mO3YWr0Ne1xk/nfaWgCQ14dY8CBieyJngiJB7a6qJuDVwiQAGcFK +zgwZDAwaoD0w0Obht5nFEpkrMsM0gwLhJkjReGyyQ1uZd6IH7yXDfCA0QVU3wPuZPjWuHoLBCU2f +cE9gADIEE3qGgz0hMFnkoojVZDYu5GZNPe4PxjjYlL6YrizBH1h0m08IouRzVQ/wDO1tuSCedClm +uGOspoXltYB9gG0cRa5H4IGxNcsaohSJcc0KDSIh8WhJtcv6fTr/c/dlUx+YG3+iaQzMdtE53y1r +HNXS0nkENRfNFqzFPHM871MttmaoTDrzQ9DhJigFrQeEUS3qky7oEEZDXgValFqSOeoBlojUGFRn +JJyAmscmFgJUWrmCxlCRQFE/6Em4rIh+GjXJmykvqWgNO792fhM7V4vFzBarYrz6pg2eWvDQB7NG +iALzEs3oSn87tJgYBn2Z/n3sMaASY00YQKQPp2iMirHxGLTV3eAIeF8M2iaPgo/N6lssQQbOvRjm +yqy2YGTPY/S8xypHfT2NEKV7lBZ7bV0yMSa2FDSwxkJPj2oNZRIV8HCcdjlNQ2oVdn1sofmLCY3R +VDpeAX8GsJ6lnzY564YaV4vIXixcBQSiLBDODGMzCC7z04YOjTdinw7aOoog0fyNjJTHGkEKYpgF +bPDMjUk2MGsyHK68bGH/wDxiDmaLXLVVvijGAWmBacZJiwJWclVQNw+DkYmcLQzWbyPyHFQNP1qY +uyGrR44fsV1mS69hdxUNV8kGgmY0EoEfLYNPsgwW0ZKn2NAFDbhMGnXDq7Bt0XjLc+7M2JvLaOaH +TweOI7wUOV00EAIIDO0CAb4dENysBmrSqzQuOpoMnkt/HJkZchSGxSOJo4bap3ZYejDkN8RX8IY5 +KguLlptCb4PMZpF5CiiaLcwhujnSUBnR7E9+HzfbFkFIAqFlpUXDRpro8Hl4nJ0eHpvZkWZfRBQu +ZnUEapvzuSq41CScqGZ+gAkQwgKJUTfv2GJ7F0Y2AOnkFhkKeTCYw5/LIHpsBJz1BnEjgfN7VpHG +76OZAZGJycJC+DYQ6ZN+JiggWgygCTizzkdoJSqNZsMoBUvHFDS8rHngXHxjzhkGIlWN1yT7ZjRR +MnzvRHj+uP0A5qKAE3NAgUA7kx2JoYSiAYZjmKcaEj1aY7Xj4WfLMDYZ1CmYOcRbp2fVrPq6czvi +PTR0DYPVk3JMTH2T3xad5ghgZpoSdFqlcmJiK8RVOk/UFGhjsJpzsZrXESeMK6KKvumedWkdJSrY +T6u+5aT23WqZvVaF9ZBAj7AuQ7+NuAbEZVGEBiExHbIN3V5k/x60AjBphcfTkGy59GSqYVLxONZF +vajcsUpu2cEmg89mzeVgW8CkLYF5kJFMMC9Cul6S+juZ+AIbHFNslSERGFcQqJYeg3Zk1J4bgQ69 +PKhHqJ1aIvzek+WApVOCRwPMeroCHYAIPnBkDH2di+abY6N50iW46dLCqGCFNRcfCeb4m9zlrJet +xbpFo2n7uUGzmv7cX0ixvPkNcBUmNSx/cIkD9R81e3vswsJqaNRqoZh0O4KPtctIAKdBPQ6vgAMP +qksxXZPHS6Kni3mYmWgZ35RNNppSKfn4VbgfTipCCTGnG6GmzW1GZdp8zPhqezwAGjwTrGaVuBrB +5Lyq684vWyeFySG8iPHiTpgGiJlTa8u6DLMrJmBt8W7IFQTxo4bRQ1zNTlAtcwcJkLCqHQ1PAmS+ +upVjo50gZZArPaE48TINh8fzytwJdl9RpAyowPEx6A2SAA8GXxTXSBM0uafOSyR8YhaulpNnNRAi +c5Tz4L6gWTHKOgBxSMVixFiRW62q2hWbWPhMDZGnHfhqXS1MAFRDWrKN+MzkkKtFwKGenqbKBBY4 +mXg0G5K5UfOBvY374mrLl8YYRxViZirWAH5BC5CjAwgTmXsGzJMw8lTzrNkTZ+V+1fZ93pfMVI9m +gUCJsVpIud/HrgYVi5mRdHgdVMS4zKDxmC2Fnht6GAOLRGkaXJlUfsQOzKwT7F81ehj6wRpoKdpA +VuVobcoZKABuaFAg46eXAeytr8ajYhZziiHGkIMXLNUWKasZSNbuhLP5ynPq8YH6D+NyW6iiVlPU +WW1j39y3wE4uOrMUAEsLYuhsohGsibPZUzTQnetxyhqKquJObdkqG8UYRTElxC+EzybaSUWJ8KVq +6CoAoWpPcLaqoYdZPaiJl7atMswYG2YxPA0zlnS0eDXEPdKNKM67aggco3opLhWLl+Q1HRCEILd5 +seGgdq1pFIOFlbfP8xgx0WhBDzEolicJzl22h+hrGgvoKE2ho2WIE8EKooLDBEOW6YO5qVp2DNhP +Sx3QR9SA1Di6asp5y5aZ1KXLpETkCbSx+sHjuej4OUoZWU80aaclquElZHnAduSujE4WfTAZawRK +naOAuFfu1tXm1DRtIgVmBQqADUD7U8VPL+NREcyoSn9D6fgXpkfSzCBVQ8lBoZQwmV7HXA3RMqEQ +o2Z3wuQwzUP/I2qHEDcAHxRFZrsLnfkui/OUCXWEKJPPZpRZDWi0F5tuPrlg9vcX82x/SG1/M9nD +TxMff2DG45PzAhcNpNskQMbqBf685T8Oi0bRtfTHMCozo+KY/Tiu6uBsyY9x9C1rttzHkGmBWhlT +H0Mvr7F65mOotggmbImPoYNB79nkPQYEmSkPLe0xPuNtW9ZjfEZg1ybrMW9SkYBmM9RcWorjomjn +dZfxGNBKgJdbwmPYcgEl0HzHGQAzLN8h3TGw33OKnu0Y0aKTIkQISEmG29omOx6pTOOLU1uBifZU +xylait1NpuPUEjG3TMfIyU+RpCU6TuaL32Y6pqdPE87SEARVEC+piY6z7bSbRMeAg2paIctzTDd8 +mnueY5iBlCOMaY5hCUHkr2c55mFONfUkx0QHhLrLcQwwAFOZtBTHWROFeoJjfl526Y1JXNee3RjV +hJp7cuNsgLdtbmOcnsQ8HpbaGLDNSDeipTaGYqc5J8bMxg3T6omNF8v/7XmNFw2Z22Y1hq4Qc89p +XCBWLdVTGmObnuZdQmPu5nnt+YwZrjbPXbcutiy2CY1Lyx+i+YwRHFfW3NMZg4CQkW02Y0jE6oK1 +ZMY4GCj+f+y9zc4lSXKeuSfQ95BLzaJa4R4e7hFLKYeDkZTiEISkESEIDU51SWyBVQ== + LTRbaszdz3l/zNz9fFkUKWUDs+CCzfosI+LEr7u52WuPlTZZxqMp9rShjOFeH2Jky9m/Xp7J+STI +GJl/ZOo3jjEqSof6PzCa9Pr7Qf1eUIzxdxk7wxj7sPBbCGMcF7UHJhjD2UKdxQYwvrsyosEvxkeN +mtvAF+Pc8YVs9GIIyXC1AS9miTA+nYAXc0YEJ3+DF2ueVOsgIzuQPqhPwosleTPNOOENVLwVI42H +2n20ciW7mH9TeXlvMLAuKUuwi3H7AdgJdjHaTyHjvaKLcdmnELGUgurDfm0U5GJO4qiy2cjFst4t +AcMwHNCQ9ASWHRrzNnQx35sJLqaLA5npslMvve7cYqwkUKod2GKALqhasoQWRQnQymzQ4gfl30ks +5trp5UsGsPi5LfNaecUw4tsKXPHjWShoxTgPHGSFFUMFADCAWcX4DA4dl0lxSPuox11Ixc+pTyVA +xXyH8CWLU4zJFC7yhikGJRZrsaAUX4+IvkEpvow/2SDFl9WKASkG3AE/HIxisB2gtdsQxZejakEo +RskzfikIxfj7EE10IguRGQE2IPjEVM+fd+KJ4VXAz1/pxMR0lTvhxF35yUATI8KOtMaGJmaJca9B +JoZ0CvXXoVNvLvjYuMTI10IkEFxiIOSGahWoyyBmsN87lRgJgybCMUcocBG6HjOTmPh7iHc9ozkB +LAwiMTMr0FcKSNyaOMQbj/j0uBk4YoS9odoxjRge14WPb5NvYGaVao8dkD0pBYr43ZWbUU/LmTGJ +37XvIGJUfkB+JAwxCBsXa5BS0i9Zy0ohJk+D9Y0KyDNJKIAdbz92qvr3WU18WdsaBGL8Eon/Jgtf +1byxlT/McpBnUopZ1Ewwm+jDSJ5j+bHCh1GMf44n2cOoatfdYlGmGtBdO3gYDFW8X+YMX+wavPxF +gd8GHQZkGrNUMIfxtystGUnA3yxVXYnDSP6DjBHAYX61qHoRSDD/XHHDKBbEfBW04dfKi9SvgA2j +b+epotPJGkbOHU5CoIYBMu7uZHZq+CAWYAMNw+uBsxmcYYwxTJwYM4x/x8PYKMOXAA/BGEbCDo57 +IIavJiDPRhiGkR+Zxyn8jcRW8IUxqrQdLgwPjXxWs4WhJcT3EWhhgGnAJdnIwsh/chAWWBjSSkg5 +gyvc3JdiwwpTZ3G0pApD82CMKIenk30py84UBsQSQrZACnPhgLM1URgMUH7cK1AYqrmz1QQKk/h5 +XckTxt+c7VaccH2E9wmacFWIMVjC2Oe8dpIwel7i3TZIGElsuHbBET4tcN0wwsjdVbHZ+RJ3MQWS +Dtxf3jn6mK4M4W4UlG0H9dxwik0QPvgmnM8bQfj19hI2IoBw10yc+GDoAVp7owcf4vAlPNgVpMkO +PpRN3dHBJtolORi3qE1u8MHhb6MG00PqPaHBUG+e6mWpmrzGxcKGDAb4F/NGEoOREGl9AoMfcZp2 +XrC134ELRhFQS1ZwtY5wm3iRU8VDDVQwNzrrJAUj0K3fXUDBQ2NUcoK7CJKJCY6/N0pwGAMS/Cg2 +YPwv+Kv0lRZEcLVjE5t47RCA4Px75QOHMfDAqHDCcZMO7FdugwM/zGO3ZAMDNQCHJtDAB5fT+nqn +8jKVUIEGPrgSaDXRwAdFbue9o4HxvYplbTbwd/hZ0WsNBz5YQFzOHQ6McljKXIINDD/sHIkGZmD6 +unYyMJCSEOMbDPx6bzg2JheY6/HzDQuMFolHSSrwQYV5q0kFxqjBwMpGBcYtpeMSVOCDdG4pAgjs +OBj4eIMCi1RWJhP4MLAvkMAI3pz3TgRGjBoxqwACQ9ODFY15wBiNQPjacMCYcLCMDBowKAwslIr6 +IIShznNnAVf38DIKmBXfRBtIBYC/4bluIGAc6LxGcoCR7BaXyQLUS0GjlQIMxw3Es6AA41ZLz60g +OoSSCO5sDOAwBgL4ZIfokghg3hWCSxYpPERReG0CAAylAgbH4P/i3wksXfm/pyNsgf89XeMe9F/k +/6mgWirwiOpGNsTsXwAESJo1+hdIYfp7K/kX/glGoAD/YsRDfUcwfS9EErDzCv6ls39OI/PeC/g3 +/t7Av2k0+PfC1NGe5P6+u7nTD0Y82uCzFfurRiejJPe3UD9kLj3XX9BLPMOZiwT/FmivKDQK8C+2 +I5AvwL/opcb5dgf/0lzMeJeQGGWPZL8G+LewPPKqb+BfiDQeU369J5Zo45ncX1rucr9xf3HAehHe +a+6vsK2mpilBQ6VH7W/cX6Lgz/tJ7i/2PBnIC+4vUbajnG/cX5rZ/iu4v/iPe/SJ/eV/9NbfsL+i +/Z7nxP7yAu/7mdhf/lPxP01GWEWN7tkm9pdJML4kgf3lAyKPbsP+IlMl1rCxv7hXB/sxB/ZXrwDU +HBv2lxm62if1l5hZQCyC+sv2AQ8TnSv1F79wX2wzaOovTukg8i+ovzwocB879bfUwAoG9ZcqrerW +2MpgUbf11DfqL3dlUUXQMPkbfP2D+gtLuUM/lNRf0nJ5QEN/ERZVnDmov4wv9usN+stEnb4rU38Z +PhKK2tTf5/X/2RBno/4CU3FeyfwFf7KWMZG/6E7GE92Iv7AyVRbAX27Wr8n7xYHeYb+PG3Qk65dB +LxWRGPeLC+GUs+N+n8ffRNB+nyKIYsJ+kZNQWcnK+kUs8rAqjCn3m7qbSfrF37Veb6DfG2vOSfm9 +7TIl5JdZk/G8MX5Rv371MhG/jM0p3Fgjho+UwKhviF9edT3KZPzy8fGDzCZypyKfG+L3UU2mAb+I +gzHfYMAv/gY4Z+X7woYqmsD74gh0g0z3JQUVEeUV7luoBjh6wn0VmHdqQy0Nh9aJO92Xg1p3G0c1 +lSIH4O5J9+XdwoC+0X0Zw0dQKei+NDAG6+UUDVghb3Rf5X/aSLqvEjQB821O4YA+u9F9cdrsBhF0 +X1YZoZA06L64lFs6ogn3ZXeKqoI8pYpR2IHPznRf3hcWDK54X1rhYRjvy6w9gt2B94WBqYsN7wtr +UIG7at2H6LKB96WB2YcV70vl5rh64n3Z3QVjQfB9MZpgfbXzfaXlBMnB4FduxpJQ831LdbJkA/zC +yjVHAH4l+dRmQ6M0mrRsfF8Y6W0E35cGhAiD70sDFvQb4BcjudjFBvyqD4OAvgTDoG08xqAN8Asr +K4cD8FvIbj3PBPzSgLF3I/zKej9J+OWBWH1pwi8MpO9vhF/2sMCCNQi/KgtBTbsIv+wNWyUNnIRf +NVO7WhJ+0YeIU3oQfgsZmaLyTsIvhd7PKIn4Lc3QZSN++Tff7xXxS2urSfiVXrwqjyDYfAvw/0b4 +lUC8KN1BJQnbOj0qjCThV9rv494Jv/T/rqqhT2JVNFGguxOMX9QJkO62M35hLqeJvmT8wuLpy4xf +WiLfORm/JftPGPHLY0UeVIssoIaZwNsQv7hQOWOB+OVkTQ8iEL/wgFh/uSF+qc3iLBJtTbDCUQNb +E35xMwYbN2yEX4j0jS424Rfv2NXPaxJ+y+Ul1k74ZZEQXcEg/LL3mhLFJvzSeVfLgIXwWyINn4Rf +Wob18QQyfXT7lyUBxll8zxvhV1yJciXhFwPva+IfQfjVa3D3nfBLK17jIPzi6M8p5C8JvzBw4toI +v0zg30KsiKBzGDcfhF8ZetsJv/g98naD8Muv5DgT8IvJ4xh94/sy03eNnnxfpklLSXgvRqhbAdiJ ++MVw5zwnjSAM4X4Y8Nsx+BznzveF8TCI99Y2zPCI7gvRMZzMFe7LroQKIzOUh/QXRiNvgz8xWmxk +3z4yoUCm4zCc18xedBZmZmPh+hKSez9hg9CRffG8Z/y9Yn3TZqzv7ek5eL1g2GJ5u1F9x6UodW5k +0nQwfePvFembNhN9X+c/oGYx0fc+1H904fneHjKC53sfGvoC54u/cVM3mi924vLcNN/bWpeA+d6H +3uSN5Tvc4ChQvsMi4CD5AsGAzMAG8iXVtZ3J8eXfAh4ygoV4N9IOG8UXRrz3AfHF33hpguGLoDgh +vyvCdxxOjhrhO9yaJgi+DIvXsgN8kdnDuQe/F58gSsiD3zui8cOK7wWWqwu0qZAw1kmtJ7y3Vwnj +V3YvbaIcM5uNfUiDNLkXNKVLve1Signu2Nmv5PYiv4qMuLC9YI4Bu7RRe6l5RD2vob3IGKvNoZi9 +w0vLDdnL3reswBWxt3udFMBenAeo9xuvlycDpplxvd2rxqD1EsEGEdQK62W1G15Os3pZEwelklG9 +8yALqTe7lxrUGx3Fj/y6zekF3QMBDmB6R4Dejd+Fwh4j7wbphRiNC53Y6OHCKwi9JIoh2bYCekU5 +fILPiz87a5PF572trNjwvDA+ovESzwt1P+L3QecFbhjD6gbnRd3EwasRmxerVzbucPV0/L2SedNm +MC9oOZ2gmpTEc8GyYXkfs3aCyotlnZrTWgFBSgRX+iuVF1a1F1BMjEKU604qL1crnP5XKi+RU2zU +G37IEeoaU3m5Ben+K5UXkx1DxUHlhUdaxXFkWSVW0Xj4G5MXyy54xcHk5Tkd2kr10fAvblN0Z8EE +fIxLd4ATGt0LNQ8JKRiKA8a5M3nlYdQ7mbwwcLgLJi8NbHawMnnppvHkzeQliAIOdDB5Pzgqn9OH ++WMyeRmsQ1HExuSllVlEM3kVwqsjEbwMzLEcdGXyMu4C2UwwecnN4OHF5H2a3o0NyYtL5+o/kLy5 +woxaVkTYSEHZkLxqjClPh0heGnDaLcOHXWHNtkUPzf4IJK/idwL+VrX97BwmNiIvI1h4P4PIyxgD +1m5B5GWQBHPJRuRN19JEXr6QFjWILECfGImzlci7Wqt7YzAAH0ReUjIweG1EXqrsm4CvwneQilxG +EnmFAqnPTuSl8pHahTKV3ww0BpEXj5ILp43IixoVrE4DyYsyK7KuVf/LflM7jhfKqq7vka43fFqM +DgHjZZSqqXRywngZUel3TRpvimmDxksDO1qtNUA0kqUniSKPcxm+G+JaDs0bjZchwYvwSddPYZ2J +YJtxvAxmlbLzeBHtYfWkcbxAZD1EBkk0wtoRpfEnjBclVG2ieAeSMqMkihew/fvcQbywnUTPSNfP +arN2J4d3+LvYMLxQ2SH/YAov/kRfg4DwQqWGiXpj8A637QkE70ACtV5J4EUkB7GRDcA7HGwN/m6H +i3mU5O92x/Y2/C4gT8SUGL/bHTQM+i6pUGNn77JJDFQvQu92RnWCu9udadywu938oCj6RYMShH6C +uotTP9UgfEJ32b8aSTszd1mjXu5E7jZLvTbiLgUBz0jgLlpIIvQUvF2ARK/6xtvFahSfeOB2sSZA +Q6qg7eJvOPEbbBcqGIT3g7ULdRZyQ4HaBRq27ZxdFIgiuh2Y3Qv1pcnYhRYHK+4NsQsjYndB2IWG +B3GbAOVC42NO3iy8v5ryIYHXvdRzdNnndeL3ztZFKT1l6gaAdIcEg6yLqhpKtlewLqAd+KHg6l5u +DhxYXVQEYUm8UXVhxFcUVN3Lk05AdXEmp+F8mUKG4B1RPSN1keAcJuzCZwFT4VT7nA== + CcDB9XJtbaAuVkh4b4Oni6paILg2nO5THIBwuPBxZ6aA6UKyTL7eCtOFEcNusHRZU/S0ROlCg41g +30rSpVj7uhKk+ziEHhxd/B0/lBxdJgYOC7aGgv6awo3RRa0TYFcbRRf1i+2cFN3HMMWA6D6OI28M +XWQl9JpELLuIOR9aXNGzat0ZurTeamIvaAnRpuVJhi5D6XBvN4guW6Uj1hgQXcz7DPsFRJcGxPlW +iO48WI+CPoyJL6c4KLosWkCwY6PowtWJl0MZM3juUFAERTfzxRtFlx4aeyuNWQbIGSkwuh88uxkU ++8YY3ce5rp2ii5DvYTAbhkVEfKN4g2uix0qjnaCLWoLD3dBUF/dEiy/zc7EfkzkbPpeVm6f8b9Jz +n0DgBhSXsTnG2Dd4riojWl02RN8uvPJJz52JphWfSx+euoLA53LFxCJA03MZMewurZsMXMYN+3Dh +gAOC96mKgIwQUgz8cUfOiwnPVXHQXT8lPZcW9vDd6Lncg2VBpufywjHdmJ6bf2/0XIaTkYEPeq7q +mceT9Fwm1VhasdJzGYFn68ARErxDotWg59JdxhPa6Ll0tKBNDHoukgCswwqB8WFh5UbP5VmdZ8Jz +WWyDkEbAc1m3gFF2g+fSyq/d8FwaONoYnsuRDoUTGzyX/iHOPeC5MFR8pQHPhYEC+42ey+XpKUAE +BzOoMLCeDHwuh41bOaqJz+VyFfcu8Ll4y1mzEPhcZT7rs+NzCepAL67A5yoNX0ryc5Ek4HCz8XNJ +S2kS7GisBPYQcZvg5yq5oNFs8nMpukC1V/BzaTjFy1V77Ev43hWfiwSf7rnxuQQFskDR+Fxswdu0 +4XOhz2Bz+8DnMg/ImPMToJ9H4ZANoAuiGTPpuRmcDcyLAdBFHoYvywbQhbWRMkqALvhLdCCCoIuU +EUNQG0GXBDisXYOgCwPdvCDo0gCF60bQJROpKVzN2VGQpOTnci+W/az83HLZtwt+LsqCuSgJfq76 +wW/0XGbTivxhKhl5zk2Og/onoTEk5PsbPRdW/ZjpuYVQoPNJei4NCMds9FxYGx540HO5Ge+A6bk8 +chEeetJzkZzkWBf0XDxfCusCn5uGjZ87rQbo4vCMbwQZt1BFXc8doIukLj213Kx6ARQA3WlYAbpp +DYBuISgNbpIBuvlibghdZmefSdBlwTXy6EHQZXqtqvRrCgdpxdIuGLpMrmFdEwxdZsgQaN4Yunzt +saYlQ5fF3EhBmaHLf8VKdIPoEi8GVzogukwWqvtqLOARGsJXuEB0iWo8ihQlQ5+K2pkHRJcfl/Pc +ayeRRi/CEF382ZFeDIguDMOBpVmqDCszBUHRpcF9bEnwouHQgdry8VSlck3RZQ6Yaeug6EJ5x4rB +naKLBy5ZYFB0SUQYaiRLii5laJiVN4outQ1YHAdGF+6fEruB0cVLyDZgO0YXZsKdE6NLCx5NYnRp +oTZvw+jyiO02VpUvGuR/rOMNjC4sjImtGF36pkzRGqNLiNi47PCQzQKVHMJWK0Y3jYnR5XT1uLut +niRuGJsPbhhdmPV6GaMLA8MHidHlJpKdrBhdmvmoAqMrDtswWFd0CwSRPu0UXSoCKRUIii6UKxw/ +EqNL+EN1a/aJ0WV4mJXdgdGlQ/csfFx+ALzyFaPLlc8xjY9FCgnRTcPG0J1WY43QpiQ66fI9/OCb +/xFWAazRIsdjIeiqOL8kQBfOPldrwc/tGm12fG5XLCPpuV1q8oTn3vILdnbuyzhEyhUC9FZJdJJz +72hXuYJzb3KRl30Gq66Cmmst607NvZ0OMTUXzVREe3E/qepUwMrMhcYc+V0zcxFeQ7QzYLTVgq+N +mAsjfMAA5iIWeNyJy0U9AWbrjZYLPbrSUoLl4m9lpATLxd+oM9tYuaQOo9OeUblQ3OP1ybNzk/KN +lMt8DDxq0ZSgJmcxvYveQAt8+JEtnFzohwCt0mB7Phr8A5J7djZcXwm58DeQ/AlALnvyHWfycQEb +RJh7x+Oe1kskHRfyd4RxsyYEBoQYdjgurJixgo17unlBsnHPU6qsHY17PtTJEoyLJC2i6vHGIB3O +NhgrFrc9FtaYistQ23MmFBdBAK6RVyYu4h5tEnFRdaP5WUqabsHYxsOFkYIp43CxE8XQpuEqlvLs +MNzLYq1g4V5uTBgo3CsmooWEC70Mo/cG4ULCgYBYcHDhUeLj3DC4CLsy12YKLnQGz2TgokYWa+YN +gYs8fW0JwMWfIHEE/xb74C3c+LeQ6VS3uWPRJvp19hH0W6jKqvCwE36Li0QxSrBvcRP4HTkaimBl +UV/CudhFhE8oSyYLmE5vd3Jvu5EHG/a2u2VDUG+jtjqgt90whY15y64WZ0vkbRbImnh7uqp7I95C +iVjFwpQUAo2brha8W8R9MehuuFsCOsqTtNvLraUCdntZgrmxbmFEzCJQt+B1wFsL0i1+qZh8m855 +c1lBcG7hc8GvCcwtKsLaG+SW+ghoK8y4BQcF35ERt7gLeL82wi2M7JpiwC0ImQjbB9/2dOJl49sG +sCbwtvgbcSDjbfEnggwb3Ra3BM5qwG3Pbp2EoS2nMQcb2hY1UKyHU1nJaVVxgG1RY4VPcePasvgB +AfsRfWAUAgiqLZKmfexM22oHIZi2+BvBzUDa4m9koTeibW1a/CXQtvkFEs/24gD0hrNFhsUlZaax +F4pwA2ZLHcN97SzbC43IjpZVb5g74UUGyRaRJ0QfNpLtw7L7MkG2TSG35NgO9X7YMbaXwutJsS2e +Uw2xvaWX3hi2qhsoibC9+TZPgu1NUsYbwBbsCcLvza+9VbJgeu0tzdAbu1ayn0TXDot1TK6tro/a +ybVdvJEE11oWm9xaipjfsbUMZ7RJrdXMksxaZFxLf2PWIub9LMhavLdsD2FiLfU+5xuw9pSXE7za +6tk7cLWshb7aTquFDqSPZNVi7UE8YaBqu2pN3lC1r2fQWpJqL8YSS4Bqte5pdQfVSkyB9Z5BtQhU +uoO3lC4HS4PlgE5SLbP9l6yG95dD1H/TkD64xt/e+8aYOrzUTVIthAt4hQJUG9yq4NQimUYJ6Iqp +xcoeLlZQalExDnc2ILWX6xE3Ri0GqEd6UbMUGKwNQi3+Hvrnufq4nIIPPi0ylgj5B56WnJbedjrt +5QLPCE4DUIURMaCzwKo4XzbRtHfJ1CyNWHvzPqjAEywgLO83Li2MQ4BZzhP4uyjXjYgtIJ4oq9qo +tIigY3YMKC3qghg+80ZI5iHRtSFp71srg0DSksV6j2TNgtSDeWMD0iKKB3ckjP2W1DV4tPH3hqMN +Y9Boh+fhoMxCg4ol6caihYKUkRUb76JIbpBo8+8VRBvG4NASn3s/iaEdl0QbG4UWMtomNC2FhCDM +IbQcDFoS59S3bPEhLxWzBYF2WJ0TvFm86qd2mpFmIFwhpQv8LOKI7Alm+ixke129zSZ/FkG8U7FJ +hjj4d+1Jn2XM8rh2+CwCbfjCgj17u/tSsGdvdxPf0LMMkrYnyLPMwIpXy1mRGdrybNzZYCYFdva+ +3RgoqLO3v8gdOgvOMN6AYM4CaYssZCBn8XdViHoSZ2ksZwJnHyyKjJfF6hFVO/DcNtzsM7vKsfSN +MN/eAzbLupdy7axZAJqqUs9R1qdC0iDN3l4N7qDZWzStxMw+segJyiwr09xLZ2qRSRNmgasZszgn +Vk4GYha1OJfhtBMxixgkJ7XK+6UqjQDMzmOsfNk7kpvGy95O9gRMNj75DS4LSafCDoLL3kV3MJGx +o5kMt6FlwVchdTCsSPk8kytLtfR43rCyII0w7BdUWaJHXI5MnMM4ZtVuCpnHMQt3Bb07FOFPouzL +oErWDSjbHWNOoGw/otLUBctpWJGy0yimbDcPJ5GmWHZyob0RZSm24WZeTKDcJiB7dESaK8R2oiyU +9qqrNlCW8nzHDXFrsYaJFmAzlYk0Uzl9MB79Djii0SXNKfqdJXtZ4JAoWeTYUEAcJFnKlph3Xkmy +SGxi9RMgWS6svBWKagmrdI451R8omDp9B1ib3KqEWImRxbJFMbmVItuwZC913nEYVFduhmyzPHFD +yKJLos7cCcDIPAVB9t2d+fzNHaZ/JMj+wwiy7NbFHCBGXXgxP6aZAgRiCLtyfVKTw/IoaVgVXbUQ +zFmuwGjeztETnqyfuC2X6I8F6cifHJnx7cY2AbA9LjWlIbyq5MSHBWU1FJ7ywCV1yGBtdU+5MxQU +j5lQtNzmwmO5uexp7rui02fSfk4J8lg1qeYDji/mlbIYkj8BplEJSE7hC4+EDwRe1Z3ImXzy+tSt +JerhaJg40Dc7jasM9nI8B+2Sp85zMVdFjgq5VY8sSuogUMLOSLCcZdmVYtPiOgsY3MYEa15I9i81 +wUQM/M6mDFgFsFkq5QxYEUEA/qhDMqWoeMTQZ7BbccoFwFbiKhX5KRIJWO2l3scOWHZViqMfYRZ4 +sbM9EjZoa31yBO0GtaH1NYmx7M/E5StgSrn4Uh8nCF2rS6IIraYsF7yHx39TTssi27mfIDFYcBLV +iiNB4QULV0r8SfZnhKVHnZx6ip36SRZS8aGzW9fh5mJcVNXhPTNTF5UwbBzPrpbQ/gp006W9hUWq +YkTc70B8oeOEWh/jUdFZgk6hEX/T3NH0dm0dbiMfuPMcw73LcXfVzWygyyoCwfxew1ujpeTZwltk +V85IwcCisBJ+gGQFWOqtJ1eSyYDPlwt1PHj/Biovj5Pvxsm2kHfV9Im2kIvG5XYcTW2u8ZFFyTNb +XD/s3O0GYvh4WMenuBYkSURKH0Yv0jKGNmS8GQYEwysLS2bzykPzE8z0KWoQEmhBoLGyNBkfIi1Z +Po8SHgT/YZbkj0xa7tFceI9rYjfTkBUpIkL1EHseuFcS+3aSuPFcItfivZC8a6w3mGYWukBgjveG +LxBFa1iHs9cj4Bpk3GObI8IcbLtO7fxQxIsbqqMDfgNjIy0MIQVJ2LtGWviOGCX9jKJnhFg8+mRI +oAUUA4YKX+qp5o9svwGRHfbUhrcZfXy87BSEFVEGm2hGCKpw4VTcAJ1pZ8g09DcZKviz5C06HlG+ +CqHJ3k8VxrEfqsQZTvKRv4/HwgIufmF40NkNBOcKyXNheT2yOPej/IKvsvgnsWAmTAsMjqe4MyCj +cXzWeE2wbG+ZI4SZnQ5H1WqJFs6F0LxBbMET48FGlVord2VVJc3M3kBjSzXHcLodllu9IaooN961 +CsXGVkBsS4flE7s0AD/MZm5EINBSlEX1WFZFFsD7pgQiyxJvDn5UqWH0V5L46usoCDOTWQSz40+d +AyYZ0mignqPcDJYzZ27UegLoLjNe7C6CNI/EtRunl0cTFueZHLEJeC90teHCRE9CtujBMW9HqfDe +kuCp0Qh1FSTVYHXMj4lQ5K5Hr0UJNMJ8F6rwAJ7xh1+u22Rmcasuf1Scj1vgvofL1exnPMLnDIeO +YZB4GBakq9gskKVUw2qJ9FDUA4IPHoIFWNhHAj+BmAAtRFHgBawTQeDCgwKyMVet7Q== + sZYHVPLLV8Amc4XRs7hSFCPoJXLcTHwJvjKutKUzSbnp7Zrx79PrFLusyaehhY+SUrFoL7s5rDPq +asUyHQ9UJBV2ae7R9bdHxhNmilF64LAQDcQNhUHeLgT6qycjdA7MhEDAwko5kEHor8FC//gUby92 +jepXLsSL+nUJv/NaqhOwzv5g6oNji/2uyw1cckMEbSWzsDAqm2IK3zDSv7wsEkZZ2uFWJ2pixi5x +1d3MWFR5npJc+4QPv6inidc4PUrTN0vhYMBdc5onW3PoiAwMsoUZRE2wsEyO21BVjaqiMVIJ1o1k +R7MEiolw9XwFLvNXF8stal/60ixK4AfF2Qe0S6rmWzQaR2EOG16BbHKn3K1Hsxp0gadgjVVH7Ox7 +GrLGEg3cwSYOUu6p5TbWvOXRnlyNwSLYCJvY33o2nJR9qbdlPeyvQoHqLTUH++Nq4KqWXA6nfOfA +pe/5VnKbFq7Dx+0G8JA2q5mZ4Wq5qy6DiPhDv6HqT3YDutUIVn3CYLnmumFEI6EeQ1fAW0f0XsDg +QDeuO+n1OZYcYv/wZWvqPSM8EDrtcLxkG1eveFhT4V2BnGUFOKTdl0Yq9TwdDpUWJv2q5itSqTyM +GMCPfrzkfSAZyzzZVJI6D8zuRM+U3UV3nduReFk4vh8K4nBXqsQQQ5/fTSvhPbg+rzQT/Atr5LB+ +bNX3rVcO6R4wT3cwG9aB6/NuGkKZFoNSzK2BbXFCrCkpOzdEO0VOliPexyNb2q4+bkrbyvVEbUWz +z0HlKAFOFEEIjZNfOdJfFaMA4DVEliFDpg8zgqYlgmOBvMldGUQXMecUlk89WvFKqZPIHQvgprWC +dw2PkSqawyWzuGLQJChbpNyPZe6Gk+j2Uot2KurAXgi8AqmnR2AQbwlM6UvMERhBUP4ozJfph9IK +w8cg1I3owvHuYtRsMG0CiLarshA5wGOJCmV1l3ftHjOpXZBKUHJkyvN5Fmk5VVbuPdPsUkLGeRkF +QWsGpgSgBZUbaYtf/PDz5oZeodHPImVyWiSI8Z5hvUzoJruQP4GvnyvnfHuBhoHX4Wc6pKRR02Y1 +eiHTSDrkU2FJFiDwrl2TJuASQN667givHb2HKid8B1T5wtImq0dVXTzc4+5Z6tWNB8VEASxcu+CJ +zlEQFDY66lTu3yqScDu5xyxXhMT43TaX3X2Ol0FFapDG6VO73drm5NKDhSL8cEAnnhEbfKO1GIgl +8tXjRDwt3pUqdu7asgEwFjccy9tQmSkt5DmgdpSaPuzKcBXpLvNTKyo+FD2Mge/b61D4bZRq1+Gm +36Dj5LKFAmqBxnq4l8WaeBQ0UL8M3npzmIo4AY+CVaWQGA49MRyqghFcFXccQj12vCP/YQr5zwWG +qZfXzU75LpKlil2j1R+z57mr6ibgArIL9Ok3ib4j44an44Gw4Ol5vBf2X/2gm0Tv1Ebwi+hEjN8O +CNGZyAEpzYRBUCVLKZu/nCvuGsf9Ic5MzjF642A+qgBvDH0UKkAxDsFiygFXmLmnFjisPCd2pPg1 +Z+eJu7p0hPrFtQkU3/cy9MiZK0JJtMojsA7x8kPciFPtfnIGZyE85NKCuQDuW632ZhQXGJ06piFX +dtGnz5upm7PKoOh+2wBh4tPT/wxrc3KM3UpO5an0On5YGszVQ+2GN1XIDPFiup0asl+I5nkxWc11 +q5g0xALxt4hNOIFr+d8M26undSsV3xlDD6yIQazl9dIwIVPPe0ZOYVVoA54M7hwszInSQgUmSr1O +7cjnmHtSeb/tSTgdf6H4bzSTPq0byB3pB1XKKRGZwAuOe1urF6q4Dg6RiMJyftF1gk+Gd7RinXLy +qsxuqmcCa4ZKLHkWLWSfMEsqxKtAhOS0W0jLXWXhu07LbAkHARijfzgij9z11CsdNAQ4YcFIzUu9 +QtTCH2WHk/PSZIEN6XzofPEv1sDhkhmN8p6u+sOjZ5OYilogRCXxH+QKVZTcCdfwCAOuXUkY53UV +n2ZtRlNA/Iiq88r0ctEVzAAz3zOxHR7lPPiMECioRJHzUg+JymG5W0gOYOa6hmZE0mFRuxe03YHA +Cga+9RxKnjL35AoTZkYceSzIK2ChF8sfhbxQltCQVTZngeK3FSXUGbVvj185ItiH8Dm44YzOZ0CR +sS4URSMiohgg4q8EwjPodZJkCcMIhx9GRcNRkEg2BnAmncrkS3hcWsCsgqXXNvekhAtWBgu5XeXH +fJmAf1jeQkv2faiHe95XcsSGAtIXPxc1lymerfikR2gTEd/ukcsgHJY9rRk+BciKVT9ognZVbYNw +jWPLRe2FYGQdCPorV2YBHk/pEDB1du+5pczMPVlXUumqMx5rJw0Wp7us+YOlz55hhLzg4SHTwIQI +CcXot1MMOMN5sx6lxgCtK8UNuLQny3D5OKvvFD0mduo9TsV/GSeZgUi+KIfh4mohrJRTJ9/mcFoM +lmt+3DAPZgduVRTzWAqr35wemIprt/as+Q6x2Qfej+PyCESdn7NcGHf4jhAPVYyh0mVWQ+aY5+KL +D0EiM0DHJSQD/kltnoCseXL8QwPEwuiuUcKVLRLBvz+0RKShN3dCLkHvovk+tZ3QLjjWPbQh49qV +jRTvaktdvjLC43ivanmc0WlqFs1kKd5pYYSOS2XjfqJ21FFCx28DSTQKA+7HYz+LiysjqJwUPSZc +KpFkYLX6ixa3+rYslB8voAfcZvYjAdeMntbtuo1KWXPVhuw/w23YVQAtQGfMH0J5rrCeaLEDwc6j +HtW3Jp6iHkf4ygkF9zN9vJ4GjRoOQ03QOru4D89p8CjxmzN3dJqBq0A5Zx9A/dylvUECCYtq2mBJ +MTHM+jhviXgqBemnjpW/SWcMkruekzdE6VxoUVSJV7W5tqcSKYD7jbATB2sMeS3GFJj170f0Vr0M +9udICAqMLI8GwiwHoFWD9CndE4+lL+bkWfI3Y9R+lt9scsGREWOYAKer9+4wMxSukjpzAKZQIthX +EdGr/IgvV3uQD8mD3fayruAaYX2TUSGYbzbbeVR6CQMhQkwgMaeHTZTue5RSmHuyogUDPK/nuiKR +8kjpVxnMe3QwarG9q7WiMLvFWJdzyZGMwxA7yN6RMozMJ9zHqsFTExjCLXShMLogfVJ70K6KaRj6 +ze7mezSr428V25cTMfFc3QtsWNaag6rsNzPSeKd5MAqzkVBXaxTrk2iZv3oZooGkpSalFj5JtMyp +7FjWPfLC7bUDafoNJgxhq+DXYDVT2fWIHramfywlEuddQ5+M4Ur8MIRSj6IBjLn3ytAvB5xK8cH3 +4etTB1yjbUJl5Bc+K7ezhYEPWDjI5a5qkIdqJb5w3bBKzgRt6Ef3pcSyzMBU0HJl/nqztcxgxdeh +oBQ7DcIiWXoPBxEaAIYvRleppAf0ItEdQ4+cM4r538Pde2DhnMdNxnjmnke1zIDVJpwzlHXtAWo7 +InvYlyUTdnUfqlMzGh5q8rAluaCCDfNFc3mOPSC3ilMgn7nei4lD6kHhiEjGHxY5ItACK/UdG44W +N+jRd8uEnkpLDyH6MznJv2CWlBBFadQYdlP9YBGcAHKl9CdgFga/u+ZCabizzQ2ZS2MVeD/0RL3r +ZaUfNPaMcxH260C/omy3SSFhsM9lvufc7sHgJQ0Ki/rTAEJQSSBeWg3TxcRHF4Al+USLAjhRxzT4 +5p5OBsztXPeCZ6fCwbQwNJ/4hWlung8vl/Mb9oUZU4HZ614S1cq1Vlkf6yIE5MFXXDhj3r7717OG +mW53Zkbouns7SbHAVSKq+7YQVZaM0t8g5zL4ZGgEM/GMuaBA8qCMwDRMBLi5elI4AzkXdS6K+A4t +Pl+WpFFbwAkbeqLEacF6Uv9UDCNCCpWhdmiKMG2UYd5zYQliQlrZKFrbKfcLRgrTn+SqnTpdVULh +WC2RVehNyrgU0mJ0NpjJvRSyY+j6jm+dFMq4TEjtHWyr+slDDbWY4mACdfgF4B26a34rh8NAIJof +TEcfpmDG5AWLYnWwnOuubmxwqj8SQdOUpEFrXRTCZpUeLGuCtbtDUTsdTWMjb0bJQkjOPtpV+Cgu +vn2pTojA7A29+KOF2m2cGCva2SsmgUQ8PYeylMRD4JzjByysfe/PpP5cuWePtgdIt3DQguV0AkYv +73qsstxf9zBl3/Q69DYo7UY/pCwDShh0pcxyXeqwo6Y6SMXz/hK+SnmLGdlp8ZDS3EcnN3wCdUO6 +2bCKh/oX4rmuOYqJxwK5n0aj062UTnM2nsjqxMyfe57G74rV8Ng5JbeXMUqUI3D64TY5jqFjRbuG +n8uwF1tK9G9aDdUdHzISYPNjlSr7zjwOOzObBXQLhRcs443qPExzl3QElxoMc33bi1p0SawTKnHG +ZctYJFQcIiNyCAPbOpdoCAzLQ8wMtmmLbEstvGs4V7Cg/oehYAaFSkglKjBysWMNSM2Y/jv5nozM +k0pGyRrbZDg4lNdJNSa0BtQtYiXJu83wMh2x4i4auGdndImnmTlvVvYzzFjkwdCi4GkxcIHB+/Sg +4U5S3XPq3aKB1RgI1VMUxw5/lwUK7cofPdydqh3RCTBSgQiCYvX3wRf7nH7aH5PLzCinIttd7vWP +aaaCoXeL4Bj8PLpVRafDnGyQEZZc6hI7RfEsfezi2ilqBMalJZ7eGXB1arTnphN42mni5DiX3MDe +R0BUHIhrCzefLnRirlJx5+YKgyujsM1alGuPwjbLaq9oKonfoAoW5cqUgp6h2IGlH0ssVVMfq7mL +XOVCtjQgAFfTalDqQawYn3mt4VNHZ2a9sVVvNZUnlSW4l9J1XHXk6/SEJIAzFy10IqGyUVz4cI84 +6m7OMXeVJxg4JcqM2W3ldA0dLcViBUatv4+Iy8k2dMjOKNh2SW+Mz5UUDcbhWEuMgGuqRRBoJIzp +8EqZ0LxHenZlMo7L/GM8jBlwhoJQObDqpQjW1hxbSBk4FG26qJSgACoeKiamQxVQt1amBsiVDDNj +Ew5whKXfS/hNicPDol4EuIKQpBA7fpJDPiwjF56UAesXBKNAvI7Fy7BgdMWdqOYgzUDhIWYZrIod +oRCNLQLRkJxiJYpWefbucKTZFJWWJNmdwRK6OwnkcK3k3bD4oaj/zoxrFnUf0I2l4Izc1dMWes2s +HWQmshJikzsKDXg6nkNBXKOUJViSCQjDpHNNrk2zBoDNTbu1nBSONqcHqFulLBAipxBWYUe2RmrF +nyq0xJdyhxLJD4dS8fFQ1pWLJh2tqeEdnFEGa2HRVDocpORkUtObg5lTaWu+TvwE39HWwumJBDIs +M085BC5hvpJ6EIh92KKgdWsBUAlKzUtzqZ4uFBq96iFAkTqsnyhHu0xM4H/QCcZi70pPBWYWiY/o +34ccJ+VMwxVbsKiz6ym0Ze4pPciI9oBYV6i7a3X+kkLWWGFOjTlWKiqSPz2tQrdIz4pIf1zhaCFU +MWvHl3qr3JuLM65/umuNWcegyaeqZgVPbVk6wYw6S5ilxIflsUVqKZwQ5Ygobaj5Cg== + duMuab4uqeoovN92VX9lHn5qdbsB8KwCfPRj1vNUK4GG60RL9Cf5HCsg/SqkmSxqhLaYWpWh2n2F +VhiKoEw+6WIwj2EFPBTu6JhEoRUV8KfUVD7WvQoKukvdqNxTx5JuhUnqfLuKXXj0dFe40lB8I/pu +QdOn6MCl6AxWtSxtVKo73eUnwkIO7WKol/oDxFRme9n98ZQyP71PGKknfdybickPnkTAx2Bxlqqp ++id3ZVkwzFxnMlPA38SGTHpwetGeXBXneK2Kj+FGZJmhKd08fwrr2bkXUrSeSjkA0G69vOzaV7ML +JiRJigt3v4H9nlIEOKpu3p1pikNxk6mJB3qOIpfh/pnfR3ZHH+O4o3EyPuxHFruup8Qj2CTVpbBK +/zxMEmaY8vKroF7VZGV0F2VkHGceMELUbAN76ZtUYB+oOC7P+yOFmRMXXR4bzXTvmbW/FWOinqay +NXGxtGuWc8DXlCy6+zfgjzZJ2i91THr3W2dc8xtjp+m9sNc3sCIIBv0Y5ltFTU94ekPLbFp6cxWK +uoc/i/aL8clmv03txGHpEdy+XMBCXTerxa5ZEGT6DJ89cyL81UMZJd5MhliZsw2LHZuuFuZzOwfr +WfOmtWEkGrt6332OHUk5UxUfQS5NNB0uJjGTMCB8sELHzT5nQPjgDRiS6vPkRnlsqXIaqbV/3/Vw +WrVYdEXLpVC8S4uKK5+KelnngtRVgsPZEvwzZjiuG5lWCQsrJkPpiz3FVUFSjqueYskVU7WPH+lQ +yZQB9vlIuURn0RgVHIfbIdJy+SETWMBd717mruSR0UyBDKvJWZMDFrt+9HS1GOd2X+gppiG9Q11o +UA/vyAhgjOM4jdElZT0U7xVZKc1W5smjUHOGSR03Yah92bN1V3yceusfd8mFhQuIw003Ycj5k0t0 +zjXNA18Rs47hfJ0ExhZFW82A+ZxrdsVBDueCqztNIfjiFMhlLTs43ijPyF1FEUATLOVtJJ4vbHBA +TZSDeAwIzoTE6Y5CNHNsRZ0Aw3rjCJFOs/htmIOXC0rV5mD+xMcBAyd5xCXZU/50SwJYxnznT7dp +xU3Siqq6cSl11cpqPdLoshT5CMIrlCoicHIuKBozHYZ8VJ9S2S1k/u3U1Qj3IDZDFomFyi9XRBl9 +uETFnv30pipZ5VWVhQyN4mDsyY5iJU7jl7kchT0h8kJRLSKZSHzLQM5xCRvNI2BhZ1tMtoz25q6i +5gNAwJkWFjr3aEFJfRJ2pdgSluPOX70tDEYyArfoeqwoRt9CuFfI/6q+e3SlunR3mVQdkrerexgR +eYQ5nRadYdnOhRPcjpHxEFRh6Eebqp6hstfJRVkyLMwK0T/JabBF8BqUAjx6bsc70pRu4MEpAX6c +0PSel4sxMLwxRQqpJGZUwEqQmIu/b9P6vV9YowQW6ya64mAXITlWWwkRRFmqtCCokmAoNwRam9/o +bW7IYkFxdi6b0/yYNF7ZyJJR2Uf17H5zmcY7r8yGN8thwMCnuA/ADq2gb5dWIifoG5bqVeZcGWUn +3xmDAPv+FNWLHtpNQmr8neVX/DKi9JfR69qtJ+Azoj4IFg5WbR39UHaC9TjdwvgYS7k1dSqSAW9I +3oAzDZ/jNVCQhNnVIt2ni3CLPzPS/x8rIPIGYVmkEfl0ASYjcBZZyB3vBkFbz/bMKyUVjSTlW3dI +szAUFI9GiSK9ht/7vFDl/Kkkxw2JvAnrfqu/FDWWQkQ51zpUQfKhIdlAHRv0qlQ3onCURz2jKuB5 +5LN49HvclGt4TDhjuEQHA74kiHj1W75Ym77Y6RZ0MF96cW8/KqoWTkldpdEpz1KgxiMySgl/T+LS +24II+HshAWUokdtkX3q6wszocxKkK+hucbh41hdSqKl09tBA+Dk8cpmL1T6UNJ0W3+mhnvERol1g +FitUSo3xDKtTXrRQJ1BdGcZdKS2rbUFM0MxHBgkhxnw8CY6hNb5CBNYeCk/XUkoKUxVoN9cJ/96r +Ap63Vi3VkhXIebGQzsmb140jSyn8ctu4TETsmXRuKt1OS2xpmYHD41nMVO9U3ptT4IZpQUubljHd +ae4uOocUqEh9odfyw4rg2y8+WEjC5SOKc/Ciq3SUXYku1eKIXAEGIfujYH3IzCZU59RJYJuSa9ba +HKzhipP0cKMdkYxzDVE3rKR44tC6ngDnR3Qv1flSmc+KjOqRE+mfRsjQBkRBDogtGueu0UoofkMW +59Qy4MwfZUaqmGYMhVxvqmAaKstQ1hvQS3jYuk5kY1wZoowFBHM9+j0iuIy4KoWH6gGe1XrN1di8 +gqoyGjY3U5fEU4k1letFP3HvekX6sDojgE4E0U+8u/fEybAgrnKkIBY/yvRAYXc0bMbs3DzX28oY +fN3H7OFw2HuG+IeJLrR6JoYsCldbtxoE9P9ZEYaqD8a9iwmysBwqa3DDXjbmYKwT5KuxFGAoP1ei +ZAO1Mt2JYNFrEKIVzN6sFe8aIh2Y6RAijYDYRXGfHW7CNx4KtbJUM0oNc4Rnhl+oNrBEurmxG1PN +M18M/s95qN5IqWYUcykD6xeNDeOvods9fTYliPxNVYUsqngi+GZUBIo+XUyqB3r9+4hrKiRfI0yI +boDRy4YKL1p4wtW1E7mrKPFYzISAQImAegX65TY0FarVkjqUfsWjHgG0qU78ovKOclFqXh7z5vBl +ORDb/HXg8xomPdyMEyIPpqzC4e8fNQMzOImy1nKrIIlaCUhYyCdiU0ZpWkRMOLf6GJipwyHj1nWz +5BCVwBbzWEPZBwacHJts6kLD5JTquJcmLS4KvqKsyUP953ioquvCFyUwRJVIqTm8TLkDg+itLot7 +BWmZnDVmXGIMp76YIpZuhM08qmInM5Z6sz9BVVnLJDwkAm2YGkPL8iYVR78Ba67Wm7jGPnpONIMm +TucudKXNvT84SFBJhP4mRHGAiVBcOa/ZAMXMbaMWseuP8RM9uq00rza5ycPk+63TmnuOADsQy4Ff +UCegx2QgFOGzcpmW2etluGsUeHelWWpDkEpz7pZ78LNqRnv6mUbnXlZ4ngJH6UPtgbeAzpVvaUep +4BxYulUmqM2iNrt1y4tYrcV8vbNp3d01ck+VlcKsErYu0Et3PpMGtZ8YCsR4z2FkDFSBNWo4OYpc +Qb5qwXRB1RYWEH6m+ChZy+qKLW7YnSZprtXmF9/HmvJARpU5NpgZczhDAYLTpTKLHzp1g0N5i9y1 +eTuV9J/R1wYdrPSTLJYiT6vP2fA0RoKskaO6JUrTA5XWCJE1joHNmBbtipiWKkGHdU/F5TK8eeRW +lBDINEfWclf2tsjSVWmnLllcqn2qDx5kvMuPDuNDoPXGq8sg9+F6yMOO0RFvPbXG9qlOJzzYfYud +yA47CO2MEvTOYhnmxDO+xFYqTBjA3NxcxV9HcX6xGL/EKe+YF9qjoVcR/ZUHI44B9U9M0pdooN1c +d2qfqli6hqKrkXPNJc2NEGfVxYuRvkzvUdAmVrk9Kl4nJ5cyGXYjfIx0weJrTmuYp9mR+ox0HWdu +F2gz4iuL6k7LtVYdq4Uf1zPRhKi4k5CYfkdo1rweyeuUg4fWIkw3neGXsKIuyQtNw+4d9RaiklwC +/CnOhrUah3BorUQRvVgdxrT+nINZRXUKsKLkLeRm5Cmg2IO+LKPHwy7sdOYQPb7d7ly1KIweN1X1 +q4k9LIeK9fsUqKW6hIWAhwrVlY6vwaz7sJT4IyxXKDN1CcZwwSpzwHzbIKPjqQRuEOlAk/iO0Fg3 +8Us8nRxTWi3UAOgb9PbZFO1Uqk3zJiwTugGwC50mmIMScyqP3NwUCRalQtuygsNvSOqBsBhOCglb +yn7RcJyqJqS9yKRD58yULjFp3M19vD1CVo7GQ5EUgjwiN1rSE0JcWtl8bwYose6Qi7wZBHscu+Oy +JHOtHMSfI0qLHr/zjzvAwiJ6ByzTJ0HL0mJ9uzD2yNtyAIwNaeHwhMOnxIW3gdoQr41xuaS0Q9Eg +Nu0dLSbvDeNERHdbtmM3cbwTkHwoMxAWBN2WPXvU6kWvsNt+hFLCLOa6HAYIi/3MW7mJuSFTCJcS +Oldb/z4WmWCaecGc+qBWHzy50z7gfVpR9NQ1735HNy+YUXFBC3UCT1X8hRZyGJ7dnzaIl/H07g3F +u3vcpoW/Ospi8a7DQBOYsbhGRWaL+HQ1M1RxeCYv9No+Lk5h5JlUK2Kqi05WIW+80RzFiLXPSZ6h +ZdbXuQPvo0ZN+Ps0jFRSGxjml028KRUBjyKmvKPUB8LySIwrtdNtzZkjM+EZPXfkHYYZhyXoXI8/ +9cpmE6kgQq6Abwy6dEQZJyncrMIqfEeKVTqPM5P+1WJn+rFbwV2bkxel6lhyVx9XiOee0g4gpcEa +n8NwdG7YXDRZWGzDfth9SfNWtr9AN11VAzcBgRCWImlFPNknpJmBZ6Z47GJF8/Dq7fEqknWCF1t7 +FLWDRHgsqwN0dkhEsmPPIz0EMSLc7uRpVKq6a7Tjyj3pCsBMsTct5G+i6VYW2Max7ry95YlceDtM +K3qqABks5qavGENKWnylhQEilq1zO3y1uL0st6RPhQYAHK3D4iFlmF2bG2L2wcoV4UHicVXN0FX7 +OGvaWPbQmm7v4J5u3sGiSYtlqGxiieRSWHCrYTZrz0+rMdirhhY6YwRgXae3yVUZCEq+u8xQMi6A +SHWdVTxDycKlBCeMxb0ThxljLNtjy2qI8a8axW3XPeVKRPAwH068FarxBFc9XepDUBaDweVZ1GBc +jDEATEgMVnZC3DbhFQQ6wjtW25IDJ4PLjyl/Qpzdam4TN6kkHZySv+aUzQmIue/biiQS5Jmq52x/ +C4OPYPGsLimGzxJ2aiGaXt1HpfsiIVfVOU7BEZeaPYqr6fNf7N2swaVSeocZ+PKtHkdy9BAeOcry +BK5Doy1/QvI+97mgPiLHPi4PfQmaBy73ZWP9KVV9by7Y52/u5P0j0vwfhjSPwomdaI7oG+sNAmiO +wHlNfDn7LiqAsuHMz8e536CZA9+voxtmDgeZ/MyNZY7K1PuUIweUebQaS5I5lnsUKW8gcxRiCTtq +jnl1r+zEmMPAwWfDmHO/okocBvxw+JHI8ltd8Z74O4H9AckOgjnCTQy8BsAcrYXvU/PI5JdHx6HE +lzcnQRJf3qya2+nl02p4eXNH1WSXA/9Ips6GLgcSCv5YosvbGc2sHL9p1jHs6HJmPA2P5lCCMIKq +tE0uv2JKXsnlkPAKru1gOhUMTck/xnlZ7tCkcUpSwRVZ0MCWo26c+fygllNbUe83aDm78V33ZJaj +s149g1jOv/rOK6fteSauHMeo9zVp5Zelhjus/GoBpzGrHGEtdVY0qxyLx2Gyw4T0Mi/dyiSVd1P+ +E1TeVZK5Y8rRx+g0Tx5z77BvlIxyzOKHcOHTDeNcfxlLwTaTj8uEA1E+/JnshPIRVJwAlKPucjye +QpF7Ifr5ER1l0rNRRKdctOnkQblOOPloZsdsbHK0BDpMvWeE5bUcYnFaksljsbCDyQ== + scyQn2cu+eMOkoElf0TR2qHkFPuc5o3jP3Dw5zQZGsnWxz2odyL53T3gBJAcGI1u35Y88mGV5I4j +f27V6CWNnJV2nLKDRs5uIMRqbTRyNQlpcqxEsT8iZBs0clgImdlp5CUc76SRw8K+PwEjp0FS2Htj +5aXI3zByLMMZwggYOVZMrC/aWOSobzyNdBaZFuV83C5Q5OxnoiLxFUUuM4vqDQyHRRGzYa7fEWWv +K4sc5rGQyNnphSLg3KtTdb6ByIFSJ0UtOORP5mwkdUYRCuVHG4UcM8mCIH+8DEgC+XOHvm4FkMMa +FR7RrUkTWODHcTo80EYfR2Nwrr4DPv5E0UnorJ9hCv6GHn8CLRzk8fuKVYjB46he5nJ+446D6czF +XmDHryf8MmPHs7p8o45f1pOaOg5yCX8+oOMgl6gvx8ocvyLsF8jxy3jeRI7DELzKiQNFHkjVxAaO +RzvY4I1TnUm93oobZ0KkuPwVgdru5G2wxhHoZwpnY40jD8XXJ1DjkKsd/ZwVCAhDX2YZTNA40las +9A3QeHMQKjnjKAe9rDGdmHFkRFoJKf1rlAP4o/sl4PgAwwjIfYaYeDTWuxgxzlR012dG2TKLgBgD +WQDjWBjqVTFfHNlMlUQZLw7XjoDyjS5e+6yTUsMUT3XJFv/gOc6IrVXp8Awokd/I4igCupWm5b8C +LMMyhuCKwxHgELphxQmRKQqSE7bCDGp1+Rxb3EYKcmOKY8VEoG8gxfF7XDAGKJzNHI/rDSiO7Atf +n7CyPOtRHpOwt2g4vNPEke9Retkw8SZfKVHiSAdSx7KRxAEr52sY2HCc1QoWh4/cDAefFPHL+LSE +iMMQ1b3MPcMgQsGKEIea4jKnm0IMXC6nkgCIT8PKD49C0MSHXxHvDHr4dUmAtMPDr+hKFuxw4Mm7 +AeAkbMN37iYTZOE2C1qICzU4HCtKpYzMDSd9+dFDmNhwnNVVJzQcDA7W7wcz/GrOmW3IcFj1bZoY +DkMx5YIhVoxNmsEnLZwAl2qGOC+lGfkfrHAgnASVWFHhSBdrbDcpvAUTOEDhrQR9fuWEt1DrBCYc +ubjTxcEc6c6YijdIOIQB5AUHI7xZqp6I8DPg8Rsh/AzxSxDC0aJWdZsGhLNnrfUQkw9eH7cqDDx4 +VbPGhINjt1OHmZVzeN81nZsMjoBSZ1WZweBniJVXLjhgAjWaN5ANkMWlAfvuauO9Q8F7kNZsPLhO +raJbeHWNN8W9KhYkOFd41ySC9yhgFA/8cNZwx4G7OnfSwKOOOWHgh5PQOwvcNMmJAj/o+04QOLyw +8oYBp6/W9cCZWm7s3StFv6o+m3LJGwP8ZshbtVJCgB/CjE0C+ON0zg4AD9F/8L+5/Jnwb/xJ9cU2 +21er2pP9zc1MjlGCAc1E7W4s5G+HAxP83VVTP7nfadiw32kN6vfjUEewvBmLLGMadJrhYeVm9qeT ++D0NC/A7jcH7rln5GrjveC032vdDUUD7FLBvrLWohwvW98Gop6HeUz6LY0gsJta3WA6tTtb3wRrk +835jfR9EYlKcYtj3d8j6mT1t2jdIDpqEN9o33JTuthqSrPXo7RnkygCIb6hvrNiZIgnS90MfVzIp +fEMMLJyf3jjfKDc6AupdCJBwJ+tAC6OeXryWDfMND0opxMB8H4Tzh9jiZJvqISHARvk+iRyVjE/D +DO5XsdZSBRVS0u+I72paQxK+z6rSjAR8YzCT+mnle0PUQnBL4L3P6vR40L2BU5fYc4V712hEGGzv +6lbRifaGIdqszoQgjoaahQB7QzzQQ+tAffHlCNmG9YYvKf2ngTQsmr91vayBJHK33592qHdao/wH +eg3WVwfTm/fJXtssiiAf5hyT6H26BiuB3tiCS4wN6H1GfDF43lBJsHg8cN64AEtoZo0nYf13mTDv +8/HgESzvFOWtKG+o6DiABckbhSGsBgpEN5hMvNyN5M31yblYe7AWAhSbho3kPa0meV+P4/QB8v7g +iE9XHQOTa7ZWjrf6LY0yQd5U+LHJfJC8KW9kwcNG8sbHy9hCkryxobCZQfLGg+ekvpG8aWV9QfC4 +9brXliTvwmrcq76RvPG+PcZ2e8duwrRA3vz7Ni36WGD4zmgmyBtSzhocQ8WOqZ+qKsqYIG/yMcQi +McibslCRWAzyJh2JhSsbyJtmIoEC5M0nNfrkeFNkwxzwxvGmsCbKPZiGhqQGl5Mcb27CT3bjeMPM +5tfJ8abo9mhPcrwhGRIgcuN4U7Ovqcsc70LO8ngmxxtvqCqGNo43tdou4cgGzAxjJMZboCkjzJc+ +kVmwHBhvyKUOQjgD403hMyk/G8YbZgVzA+NNqRwDucZ4SzvHarUV4809WVUTGO+SwMvAeMPC4N2O +8caFDR9QlAeEdhljD4w3BVSsE18p3uy/HJ+VwgUIiwkub4w3whxXKzvGG2G585oQ7wcrrDImKhi9 +FXmiK8L7MdEsCd6P1fQJ8MZx3undzx1P1/BuBvMYZA5+N66DE9LO70YFVAT1CUZ4SgCXTO8m+fhU +JVPCuxF1Jeg/4N1Q5NzeCNP0fQYqeiV3o8G7ItokA9/2tZLajb343m7QbgQEqTgIZjcjjqxlDmY3 +e8MTd7Qxu3nR9dCuyofh4d0uMObUhOrfnkXZwbZ5TtfC+TNnO3anWkiUfAzn2oHdsLKKKnjdOI7i +zsJ149dUSrTQugtFE4dK1NxJKPizgevWHOMkzcR1i7IXbWnZ2Y5EilsHE4oFXAkO+BuuG2ZVPAau +mxbS14zrpqFaqDZx3TSzHCtw3fyJlnBuTMFMpj3npx3XjcC26lUD183aDUEIYt2MKm8rsyatm/Ui +rPQJXDcqMPTrgevmTVKp6crrLgEFSF43O7Qz1h+8bhZvqE5h5XWzhCZR33IShkscgtdNC6mJG6+b +glqKJoLXzf5QXAYGsBtzlyo+N2C3JLaUmhnYzQ1VZXxHG3rnkXZiN10frmiC2C0trjdspwWtzdzt +CeyGVW6Jgd00dIvP8jcJGt6J3YzwST5oYrf6sdzS8Ih8hLjV7ZYEk9jNVZXakAYUkejl0z0OWLYO +C4fqDdkt8x0Fq6c2dDGvkN0wiH6/IbvZ3Ib4gEB2a91giLfW0mf0O9mQ3er+SFiLkd2Mh+kRGtnN +ZU4Qtieym9pzYWnM7KY+Xd+Imd206GNYmd00N2d+FRYcggUksps/ysrIDdktyX9RKa0Dj7eyvons +lpb/cA/WRHbTfWSYIKDduG+XqB+Gdiss4oLYReCE4MhpRLc50M3TX0C7FSq5TDpJaHfJfjRmdmeg +JZndDM4w8bkxu3GpcuaC2U1fkQ5ILngx+bKAd2N2YwHReHLR/ggrJ5XDEtlN1B1fpA3Zrcjy0yey +G28cET+J7C7XFXScBdnNojECqcODYUNITsWB7Kbrrw4iK7K7pIohkN20MDUcyO6Pq4ZlRYGRmd/5 +huxGJjIFV8pTgBSi8qhwBsFcZM/0DdlNMxucGdmNn6BqLZHdsHDi25HdMBPOk8huWpSdNLJbFibd +VmQ3fpSUzkR2I0VK8VYQu5FSVO/CFdjNjChJ1wHsfpxLSxY3BkDWRGzM7nFGfthWYLR0f0zs7i2K +lFZgN6yHI1+cfWAg7SRw3b1NIftcEnTnexLW3WNsis26QVc7qru7U3qSusGrOxxdZ2wMbdg5D22g +bpKu72da7xE0M3O607BxuqfVnO67Rssw47fBxlLD3hXTPS6H4XMzc+YT0p2GjdE9rUJ0j2hKGIhu +gDgYfF0B3aSVnwugG1FuVcSZzw2DppEVz439OO8HnvsOmVHQue/Db/8G5x7RQC3Y3GDgqF2k0dwA +vnCY2sjcZDE3hfB4F2kouhxOK6MYX7liuWEk5TKo3DA0lynQdUVMObjdk8k9jqn8Y5p0uNtVIrlh +oM5wI3IDecf6yAByI8xKFnkAuUd8yAuPG8i6btoto1s9eigHjRuMVpY8bDBuWg0xp1oA+wnDahT3 +y6DI2kbi7rE+MIgboV/1bjNPIknkG4ab2lS2+TOFG3l4xQEM4R5e7O4MbjYJf56J4O5RCx0EbpwQ +S442ADdPC+Nm8LdxqzkgBH4bBnr3K307AIEJ32ZZZRuTvb0eZ6K3s4tzkLdH5LGCs50DxAbeHtar +JXd7uFVE0rRRVMFRfqNu391VALnZw9ViIrchR6TWYyVuiy76TOA2DJxjA7h9h9hl423DyuEoeNuo +62AGI3DboIqrNm6lbaOKhguAgG1j6c30m1nb+feG2p5Wk7ZBx+lutcgKtjuiTRtn+wn8VGC2sTR1 +R+/obkwFf33eMNswayUUcT3Kha4Il7LQq5u6uGK2YRWoNTDbsFDYkphtbsNDLJhtzLUKiwdm+zFb +KinbWB6p7fsK2X5dpCpfArLNE+NdDsg2IQh3ILFn9QycTl57QLZJQWBfgoBs84HebtE9Idt8rKzN +NmSb7weH0IBs06IY6QrZZrPQuAoF2I/bBSaGbH/0nj6nZ/XHhGwzAslg2QbZplnZV0O2FZmsYyK1 +GXFUCfIK2WZIjOqmgGzjMfs3DNkGDpMvzMbYxj1wHbcZ23OZHIxtfetuiLEEgmv0kw7GNi28gisj +pF2R252xXYJuk4xtWCRuCMY2S2xvbTIR27hSiewCsY3XUFisQGzDK3Sp94rYnj5wKivwvoasRIyM +ElVOG2J7MRuxzSbPzDwEYhsWqdw2xDaJGYwPBGK7kH9eVDqrbvQQC3Pg2RDbeIWtHDFimxJDNSY2 +YhvPWaC7DbGNcj3S04Kxjbo1ce5dks7ueZ92vjY0ckpFGa8NN5xDStC18brIk1/p2gwicTgPvDaD +SOqE7jGEFq5ZV7q2rFQkGa/NY10B01Z5cPXwsuG1GRdlh5Lga+O5M+aYfO3nDg76AthGPVGU6zKZ +cwcjI/DarC8qwmhPujba/LSFrQ0hKCMpwdZG145baY0ZfRxRMBhkbZYvNq1omcDLtuwrVxvrIyFn +HHShcMXLWarFACykg7BBtYdbjCVTe7h4LZHaALIxErQQtdEQiON2ALWp/zgcTIHr2R3s3HnawKIx +Rhc87X5GCMM4bYLUlK6eMG12tKIgySxtHGcBafdI1G4c7W68VhaiU7Po/DGDorgM5c9WijaUFIwx +BkQbSUN+VsHQbiHc2xDaZMw90iIytg0AA4flAGi3oajKDtCG3kulwQ6cQ9vP+u/AZ7fQQ2z0bGiU +CGYJeDZEdrfPk64fyM7tDZyNEmWBLszNvsQNCmg2FlYstN2Y2bCqCMw1+BBbMUAX2GvIsUR/WYHZ +l0tQkpd9uQfzshtxmzssOxsuBSu7O1aaqGzoXziJb6RsXAR/LkDZV7RXD042aszU6mrFZF8BqAhM +9hVzWlCycUan8ZgzN4+phsGRYGRjehqGZtMnulyItyOy4fQrnOCQEU6Pb3gAsqHLoqJ65WOj3loh +GMdRnyvaL5qO/XSns1c6NowMMwUc+4me5sHGDmbmjsZ+LAhJMvbjPESCsWGIn5tgbA== + JloOq+4YOotUSHKxoU6LYNXEYt8j2mEYi/0E5jSo2E8E4FcoNlI9eol6JgOK+1SEWJuLJ7p/GxSb +ZgY+AopdyCYuz6eEYjMnQZ97o2LDrLxSULGJ4Cp+HaTZYHOb28UBs7RyHtFYbFiU3wosdilRhb9h +sbVuetrEYjMHTpcosNiiQBjtvvQVgL+o5nHGYjPxrOZx0Qnsg6s5g4ffmIsNl4MNDjcs9qNi8IRi +gzWgTrRmYj/WhO1I7McDeBKxYRAs0EDsx+jFnYfN6uGzTxz2E0zroFwzeskk6EbDJhSD5OrcEBxO +dnUNHPaSyVt52FxXqIOIedhc1Y0+cdiMqnbXdU6mNWOr1HcHDptnd56Thk3//HzOr+ypnGXQsGkR +P3REbUt12c2Kw2Yhi0rPjMPmpQ8i6o3DTsuGw8aehjwYh40PlQHgxGHDBWsq2Vlx2DCfaqM6QkTp +AGrisOm181FtOGw6dWRXBg4boAtV/omGzS346DYcNk/uPCcNuxyulEwaNqtgOCqvNGxaNRCYhk1L +dwMMFiseRWHFnYZNl7S6LuHUUsSVS0nDhkWVGRsOm4vp09wTjRMsDazSLOs0MKhQULbxsLm8rlHv +rijH6ZEjeNhKOeOfNh424zHF3AstNbC+4hASQGxC6TgebUBsgoIkqTYQm1A6tfgwEFspmiYl5wRi +U/zCfzcQm4bT+OuuDnmXsdwrDxu5VD+HiFmUKEMNHja20W3beNiEXEbvCuVGkHRVpP4JENbj6M5G +xCbBjDrS3PAKPmYQsbH21Ju0EbEZ1hYO2ERsuKZyTQKJjWiEAm0bElsEqbtOJDZ1jPoqY3qHhZLm +DYktbWg/JxJbWLEJxOaOqjhbgdiMzQcendDiq3itFEBsLkWV0Zk4bIlBn3PisHn2TDwFDhuxMZV+ +bDhsmP2TzaunK4rhjMOmReCKFYcNsxElwmFzO90N47B5cI1YKw6bayNyVwKHjScvUaR52NOwAbEX +s4nY+AkFbQJ0zTBU6NwXbM0ZLmFuWGOMDyL2YlmJ2NMcRGyuCiUqMBE7392dic30+LMgsQkOoMAh +kNhMalaXI079J818VwKKzawm3yZBsZmYZFRig2JLlD+eCcVmaQiDUgHF5jZcO29UbCmuR59U7NmX +LKjYjIDd9/VGxSZOVT0rTMVmKootGoKKza8xxAdr1yLF4ZOKDQNvYVKxGTNjp4uNis2IE9urBRab +Fk10wmLTIFHEisXmY1CnsyfwfVc0vjYWG3EFFbpuWGzixJo7Mqr8B6liltIHFhuDoL66DYtNLQo1 +VMHFhrPp5h/mYjMQQ7TLxsWGmQv45GLTwocVXGxa1H5x5WLziBQUBReb4RgVpD9xra5t2rnY9IWZ +Ng8uNtl87BkYXGxmMNRQc+ViT3NwsTkHshVgcLF549h/YeNiw+zOO05AwSKtV3CxuQ01XBsXm2Y+ +s+BiC3U4ygRjUxHZ37DY1HmyAj2w2NAccaxJLjZzQ9WdWiYXmzFysgqCi82q5mfFXcPrGGqDuHKx +H+NI0prNlQKVmoYNij2t5n6h/1F0Lec7+WE18EdYd/C+H9enHYl98i6XT0nExsMmRSuB2N3D0c7D +7g6/JA67OzSdNOzbvsYOw74dfUygtYv8Jwr7jhdwI2Hf6q2w7CZ8cWKwbxfX7BjsOxJGxmDzfblq +ULChdlF+ZIVgB5M4IdjQoHGsC650tZhvQ2DDKOimCdhIQR335F8zmfWcb/jr2iOZZ/o1DI+75Gp4 +7Oo7sMOviRXHKkjsa/Q6oUItz/GJtfSKvka9Bh2+IF8HiyrJ12c0Ct/A15B/ISAd2Guqn9s5qddA +VT078vq8wu808fqMTs4BvGaK67jfeNdnCFwCd40iCAavA3d9Gn+y0a5hpIsasOszlIsBu0ZajH29 +N9Y1aoGeOknXSG9oYeBXCRU37Kyzca7bY7J6YK4ZPHzOSbnuoUzdINdIHbVnIq4hmSFdLwjX3TrA +HXDdvShIvjX2YyA+8NY4MON/G936GvE4Hbi/ohtrsK0vz2E72hrtDiObwagTNDdjBO8WIf3gOW9c +ayzUlKwU1joWgYZaD6NmdqY11o6O39ON4lqyKTtAXxm78S3dgNYI5WTBB2uKm7WJgbOGXFBT5kqz +xhV393dlwpSCmksRfAbCKBVh9mtlWbuALknWFDU4wcQ0bDcCZOdY9+j6Ehjr5AYExboHoHCDWLNL +zqkFCBems7DbE+cZ4IINYQ0NKifFIFgDqMyEZwCsL/OFNn41ATaI/RlffQUTLOjVV0hxN3g1rCzI +D3Y1qDaM/wW6Gr9WkmVd5/ej0FGAq+HTkboR3Gpm1J9PO7UayRNG/gJaDWYQP7tgVp+WC+3I6jMb +OZpYjboUAU4NrD4jRbUBqxP5FLxqGDQxOjkIAyMlG676jP4AQasG3Y+jQcCqE9a+sapRYac6TJck +nZaim1Rduz/fDVRdQ0UYnOoaCorAVMP56OMNUl3tiSSkGgYGccWortE3dUNUvzwBLU6TUN3i/TKg ++uII9s6nvjhOLnhqFoJ0qX+5vKKk5LaoN9N0F0r/jjbLLTGckngcaGoErchE3tDUD/Oy5VOSqZtb +oSWYeriD1c6lvpxoSCx18bwdVGpLaHcotUpRbMWkJjHh9SmR1DepMu9EaiBa2DgjgNS3F4KBo47Y +/BuM2vqtZFGP6D5hFHWN6rsdRd0N7EkStTWWCaJm8uEDh5qRmSjXxMftSSsh1Hg/iiv5JoQatXFE +UwRRBy+3lzD6aDgiajk0CdSn3asAUNfwE4I/zcJ+g7cTP436v65SVHpUWA/x9Uz2dHdv0Df2tOXr +gZ6+GHIokzytJVmrb+RpaVzGOcnTCNNe7IEQ5GnqU4+wpFaLmovYkHEYWNQ/MdDTH132b78swNA8 +Yk0e6OnmLF+SpwMUl+Dpq4ZOeOVOIyAhNqex02CHqOO0qdNXlMVu0GkQROjJBHMaaBClYY2chmF4 +i7lAukL8YOA0UsAUdwVvGonT6FY0VTxXlB47Xg8ZLEdUU6TRvDoSjcmavktkvWUkzredkzT9FEUk +dtA0rBxgAzQNg1i7znCBucsK9A0z/RiKk5RplKcpROjN8A8M+myM6dvlnMmYJlD5HhMdDdIHp6GN +MD1MwkhrdzVqAqbTsPGlw5p46eG5PqHREClzLb3BpSEuVojI1ru405jQ0vPPlSwd1gRLj9AEBVd6 +BHR1w0pDcN0CNo2JalxBTzZUGoZoxrj4stFzJpDSI/RUgYQblxOrG1AawC/GmsyTRq2VavGNk8Z3 +1N2vcQKl78uOePCkaah94qQZLz+uN5o0wEf8Gg2TvltgtwWTZi/663pjSQOQqfS5UdKQmQaDGiHi +2/CVHSSduLLgSCcKMzDSt7/enSKN8q3izqVRWchKtGRIw1AdsZ8I6SciPEGQBkXrCF505XHkNm78 +6GdtnYkvkLDu3ic9GtkepjY2eDQAadVtZqMOdahexejo24vYnRx9i2+X3OjHq7PERrOQ8jp3ajR5 +4WybZ2g0ToqFvsGMfk4Jkndm9GMoSyKjn6gMCmL0eqAJjL4jUxy86NtJsoRDx/Cw06Kh5GUnzKBF +g95GKnAwoEf0qdxY0RAqkBQaViTWnwUUTY39eN440chjMb5pTDT+ZsWUKdHjiGLzFRKN/FhUnItT +eRgIFohopNpYgL0RorvD60mI7lF2F4joNGyM6Gk1JLqbJZWEYqyQGXXaENHodqA+yh6sUOgVYEyO +is2FizsiGryuyzeTSTksnGqffGisqNS4cMVDY1kGPy7x0Fi9qd7KBWbNsocdDn1ZRZJsaFCd1LTY +aGhKypjKn2jobrVXkqG5zHPxH+vBCZl11n7KbejHlTK50LE0Ti40F899vGGhsdAmAyDueasBRTAU +ullpujOhwe2Kc+cHE1m5REK/u0afv7nz9f9fJPTXSM8/e/zr+PRP/+KHv9p+AAf87e9+9b//5sdf +/fkPv/v+h59+/6t/9cP/66O3T//0X/z0+69sjv/3V//P3/yg8/ry2++XnQoLwl+v7c/91r/5zWvH +//s3v/79X3uP6+d+5s9/98N//80Pf3j9yt/87c8zsJdLeJ3Ob3742/VkfnbzLz/8p9//6nVn/4/f +/fan3/8Pt/43v/2vHzaOypO/8zr/zx9+85//+vd/3wv9i9/+4W9/9sn+6euvf/Yvzl/96U+/9u40 +XDD86s9++9Ofv96+379ewO++s/2f//CfX+e8/Msv/uTP/iv/7da//fPf/be//es81j/5sx/+8Ml/ +fSr/2y+OT//sF39yfPr3f/jFn/w3/MeK/T4+/cvXf/2Xl+0Pn9qnf/3pP/zH49OvX3v8+7/4xZ98 +d4PPzf/5cf5FMPXLK/hCE/6iJvln7a+dvmzHev31E374/3r9z2vkYSbuQJvQqv/AahdlCgNeOsBM +r+Xla42H/3gN4J0WRghRwPA67msSKQ3VcqieYactnS2aXCK6Nu0wNgHJ7sJQRH2zIV9wcaDb7SBz +vH5iPyqKfV6j234KNvoIkADRuV43dvRrP+w07ucw7fN851GXC/twF14H+E+4xQPd04Cze6364dex +hQ8mZ6LhX87QjZqR13L7vE5isB54X7i55fj0r38RDxPeMVIWJxxe3eFChNVqh/FURdvNhMdr4nkz +usW9Lm+xHwJzbIdFdg4vw3YOYfx+vmjbuf0Nrzv+iaViCEdUAY3i+Odq95lgfXyzlLv38makLKov +p207MWv903ZYBFGg7drOIYzf/8y55Wn/4/v8d7/P7W7VOLubYZzXxs8BXtvRGl7li212Ucc77oZX ++tQA4vEC8VyENt7vLxVj5dpPA5FXrrmW811s27Ut9nkjlqPOW7acwnZ/CQe43je+RdXfDzuN+zlM ++zzfedTlwj7chf/18eI7ng279b7fXJx6P+79HHCRyB+sJ7vYtgtb7PMuLEed92s5he3m4jfgje8b +I/da317exbifw7TP851HXS7sw134Vi8vqXjH9WFMYwVRW+3facgprKlZxrTFuI1pi32OafOwy5g2 +z2Ef006D4vaNWRr7fthp3M5hsc8TnoddLu3jffg+xk/MMO0oH24RZpjjfDsOZd38XtZhfxr3YX/a +57XMwy5XPc9hv0VU2yCYuW3Mbg/P22GncX9M07480zzs+vQ/3Ie8RcsT3Cb05XHPCX2+GMuEvhi3 +CX2xzwl9HnaZ0Oc57BP6fNzrxvlirIedxu0cFvs84eXlnJf28T585S3ab9HyuBefJ1+M1eeZxt3n +mfZ5LfOwy1XPc9hv0Xzc68b5YqyHncb9MU378kzny7k8/Q/34fuPjkplV5MPforNm+uByQh9xXYj +glQaJXc7RIet7n4Kpln0kNnPwMZ3P2XdOF2P9bDTuJ/DtC8nPA87r+z9JnyTaXTOztutnc7EPIHp +dSxnuhi3y1rs8x4sR513azmD7dZOZ2LdOL2O9bDTuJ/DtC8nPA87r+z9JnyrSXROzw== + 292d3sQ8h+l2LCe7GLcrW+zzNixHnTdsOYPt7k5vYt043Y71sNO4n8O0Lyc8Dzuv7P0mfJMXd34O ++ILGeX0YFMK+feiI7Bc7DNPYU/C926FGOMY+KuCfEX7Yz8HG91Fh3Tg/9PWw07ifw7QvJzwPu1za +h/vw7Zcv+x2eX/FyGvN7X054MW5Xt9jnrVgOO2/acg7bHZ5f8bpxfu/rYadxP4dpX054Hna5tA/3 +4RsvYPbbOz/j5RzmB7+c7WLcLm2xz/uwHHbeseUctts7P+N14/zg18NO434O076c8Dzscmkf7kPO +++x383z0Hps6Jry5WFb4787YNO6e27RPH2YedvF25jnsrtHHc8u4Svu4JGiuutqXFjgJrTeWRcg0 +7iuWaZ+++zzs4uW3j6uB7Yx0nv/WYd0//enXe1D37xXsPb9BsJc38EPAdwnr4r37Oav3/vLheFvQ +9389Iom3uisaQDXPuUwzVWdtu2cOsEe9bC9vNizx2zLJ2IxwwGif9oNeEi/sZ2DjnGSeMd42HhK7 +74edxu0Upnme7Tzoclkf7sG3nGKwwfvdra4B2k6Djgpf9nm+i229tMU8b8Ny0HnDljPY7q58mvq2 +8S0h3n7YadxOYZrn2c6DLpf14R58q+mFlSzvt5ZnXt9eXF7jub+4i229rsU878Fy0Hm3ljPYbi1+ +ovX+tvFtCcZ22GncTmGa59nOgy6X9eEefMvoGAQtHlXPZ4lrsNFk2r/TWFxHi3H+HG9GQqDX6Jjt +h+pntsNyXC/3p+0cwjjjGlBm7hufUv/uh53G7RwW+zzhedjl0j7ehy2ucclj3m5RteJjOw7n1l72 +X1yM2+kt9nkt87DLVc9z2G8RPIT7ft42PlU2tx92GvfHNO3LM83Drk//w334Ngv3fE8ya7qY6Bfs +b044EPtTs/H9zVk3zpdhOeq0lQ/vbVszY/mo8iwXUx5veSfmDy83bjvL5S4vG+fzWI46beXDq5Nn ++S0Hg/jF98Eg7Nt94nU87c3oi36/qXGHtsO+BTl1Dh+DnHqkb0FOPb71sNO4ncNinye8jDHz0j7e +h68MBvstWr7aeZz5kJZfXIzb6S32eS3zsG9BTp3DxyCn3qe3IGd7v0WLcX9M07480znGLE//w334 +NpM9/OLz4+0t7g273153P9xv7zTut3fa532Yh33Lm+scPubN93Pb8uaj59okpwgcv9TV7jPp9/U2 +RUzjPkVM+xzL52GXUX+ewz5FfDy3bzZcpDstH/HDisLmbZVQXe22G+06vi8p5OlmNNtHtU+8n4GN +70uKdeNcJqyHncb9HKZ9OeF52Hll7zfhm0Wz5Utvt3Z6/vME5hJhOdPFuF3WYp/3YDnqvFvLGWy3 +drr+68a5RlgPO437OUz7csLzsPPK3m/CN4xm253e7u50/uc5zFXCcrKLcbuyxT5vw3LUecOWM9ju +7vT+141zmbAedhr3c5j25YTnYeeVvd+EbxbN7hHfu0f5OCiEffvQGVurb6MCA3HX/WFUwLHQYGo/ +LOJ7+wcp0/uIMDfMT3w94DTuvz7ty6nOgy4X9eEOfPsgw35v5/e7nMb80pcTXozb1S32eSuWw8Yt +W85gubfz250b5je+HnAa91+f9uVU50GXi/pwB75xiGG/sfPTXc5hfuTL2S7G7dIW+7wPy2Hjfi1n +sNzY+dnODfPzXg84jfuvT/tyqvOgy0V9uAPf/08GV//tTz/91Y8//PrTeA+s/sNiqxi5fslKAP7H +UcnU/q6xFwmKVqb9y7v9eq2bumS162F+xjyP8pNP8tvIbLdTGuoDPy8B7iPtcgBlHLYd/W62Xcdr +cUJjOSTwl51lmrQ3FPN/uAf+wS/yUBu4Zq9XnhcM5GS/41xQ+vP6EmhnhaOMdCD1uwBPyMiaIv0o +iqc+xxHO+E20P7UJbdx1gSi8krGMw2fAAsnc/3h9qT6D11voK3/yqEozyOg7RORG3gzWjvjO1cub +shBeZ4DyFN82DLzasohOKjuLRnRv8Gh9Wuj9K2O7elzYEcbX0mC5BejJ7Ut4Dd2x7TV8gHkT3h7D +53hCBJX50BWdwn8MM7uZ03w5gSDzKP5JjQMyPk9s/PqfT1877vzF+5etHP6n47W4iJ+88/3s6tRr +Y9VxQCC706ZXAoBXsR1sHyM2Paq3ZUMVHZRxza+dwTw5NAzS40YHmnbGyYGqqmu8VO5qI2ombXyu +MB6x4aNbHds+Punec3/UuMmGGtavnsHf41kRlEZ7QQluPiwydL19i+fS/Iqz88b9dz+sAZh09ef3 +etlyPEQ/nO43Hctd23LcYNNmGAE9vPydEN/1OQ9QarUdiJM4anzBbeiMhzqDfBgAHlX56gyQw7Tt +zrPquf9+CXl1N0oCix8AEdw/pv24+mL/EnaCg2RHDMzG7gd+93uEDeXdMpYcQj/+YA6VqDdEaar+ +CcyrH8NegIfRofBm2FiLvxWObzaimFWP8YnPAuYSI+BrKBjelg2DZER1mI3l8NjBFHgeIR5s12OP +jUfcIzyXr17E+iaN4/KAe85Z6VGZo8zXaDGpoNYn7aBH2HjHZZ8xaL8feD7eW7XtunVPid+8Sf9+ +bG++pTeqWUc8sjNslwefoWHizXrXXnPvGsbreT599ffj1GDA60lH4DgcubG5+Wth2CeMnj+eUWra +ur8KlsF+zgOAROcD8LOSMZyX41gOsJzAPLX0UcCLLXecGqgYsrLYMB2ael9+IlfDytHGw+8LaxA/ +GM/nijN+/7n4IthxtJy+fefr1faZsCXp3cM+eI00jvIVYx1hjE+CrUvP7sG4ov+EjSN8Nnw+Xz2F +vE1AUN0x+LMh549hr/X0iRBEImN4C5faRsl4+QvCNxgnJ+3YiCnrrN62XHfd5p+vnML6tbETjUbN +555fG1GQMWhe/oDYn8XGM76q16vb5vCaoy5Xvh5hNZ/ixzD7edv7/vS1M1jv3H7dP37N3L5yi16D +21/mzR897Jh/vqT95cHZ3o64TcRJynjWn735fu1uscl4Vznh/Jj2Ev7FddbxSUaCe2UcxxnGEQ4K +cTaf4whs8ueNkXmR8b78c9QMfu0U5tmdkvt4OqjxebIdUzvjDbviAyVRtIR9FP2mS3xt5Gj1lSPn +jxbowu9n2f7HsIczcaly2sYrx1F9Ry/bdeYPXjEf0l6feXY9Nma/C51IucNY4lOOsdS/hnHSR45f +a+2Ko2pM+ngJ8+qAQDnG8ns/pj08ORaMyfaai57wAO4njCM9TyyMPscBCAyyvfbYOK7jqXcN2xHD +DIkrn3/mzHJwZB+kWBfR7fgx7OUongCG3AUaz9OeGfkzNnpIAce42zOjXeXi5IFxXQJj6z1+7h71 +01fPYfcb4xfhlef4wwXl9AZtrGNx8H5m9LD57OE1oiDfRjs4Q8Czv9trHHe6oyXdzjHCeExvdruC +9Wugb6q584mLg52IPdmv/ARRR2/f4CZpXrbuG+FjfPXA+Zug712+7tenaU9GDe3DYb5Bi/mS9qON +5cn4GKO1MNJp/HjgeZlm8324zCrSg1yM5/YLPJ1x0k5lLD0mG35A+VaXcfm1ISXQxqfmEc44Qj3i +LSBI4vPPnNr6XRCI6bf6PJfvYnnbuVj+yifwl/+Djbcj/zv+KJq7wY/BE338ROnp/Bh2RmdspyNb +iaw8/ShiGCHuMn51HCO+R5ShNL+IhLNp2zJK3K4R+5Mkxl8qsfLE/qOf8Vp6iroewSb1Wye/AxjJ +apSx5e2GvUUMhFg6G0scgW+OjYhX+5G35RzmF/by8uKGXjX8jvs5YqiqR/GbGz6N777H2GFtvYzh +BF/39fWnlPtTgK5v3OMujY8PWtuRxsMbljl5b4Md+6rCOLQMpBcBFpRsEdcZwjf6AO7y1DKsZmOE +5I4Wd4C9gWUEXiT3J9FJ+4MC+SXsfXpftcZtYNhRB2F9wpuRravyyLH0GXLNZXy5yL7eoiU+jAJS +8rDX3J8RMD8HDQk4rSdmDL5WcdDY30DVOIFYtgPlk1fG/u9+c2scgqtNTwFxWq910bNsmMclektf +xDjyGlq8NeyZAyNoQccyqPkAfX1FDz/0LvyLPpPyVBuvHk+dEUsf4cpJAR1W/KGJps/TOm/fGri0 +JUbLMx0c0PLPODCjEjLWu8RzGJ6jm5om6BSO9CJAdTvPmAwwd/v2tl9e7W0YBqD+Ov0oTrlOaL/e +ctHwnHlzmlg8Hi5a8ca9XnG6cF78S1ec7lieOyA+9+3n1uUr4rAl3v+r3XFeRz/KYswjEHfua7tj +ziUgNl4pu4AXud3j7TWty0XwWfvAdXn9e9UIDbgfQlUeNa8WR6gxtvEL9REAcIwRi/REGMHUibM9 +whRfJdyDcMOaUc3hyMVH0WbQcfxSQXLYIi6CR6mXDBu2nCHSKX2Z28iPynfh5w5qp3SoC8A8QItv +ol/99MYzB8Dlh7d8ekzf59nnEWbsLxazbS6vjGOGETNe3oRS4t42TZA+3TuGQpKKjoiKaOEAMur1 +xDj2aIxuyDrEU+dn5+O6Y6PfhjPyNq1nEA7XbNcJvUni5E6vU9Cw8DnSoWoxi7/sZw9Hyz5mbado +eHoWXuqjwXR4AYxd+wDs5hffEJVENJL85l/TvNrcYddHHXnba+YLQFbVnNDcRltXphg0jHPEuF6r +pXmE8DAwdPbpbbL3ljYf9Z7264rn/LTSFu/0Z7xWAnz9EilKgoOUJweUs4fxiMmln+lnvOwc5j05 +aLBEx8qcIB3uk/GIW3+MOML5iPjlQW3EZ/eyz8E11tHQSp6xmnjKGUcmRc9TidpX6AgjnY3XBFLj +CPnxR9gKBHlPMADjZtgKRzjz9dagj22vWPzEh3calOSx46zzAFx06QD9iY15/R4oFK07b3W08JOu +8Q6hj0qL0QOf2pcwlyuWPvS/YEzMmMKOOt+uyjwbc1RhcV64k89xxxGOnH412mL/88xYUwv37HQO +zaPwkc8NVN94I2IcP9XIrIWj7f3T72z9eOZxwwfRQlQ2ein+Lb0L+KF0UJ9zzP1JzovxoM7zYiez +bcgOtKEfRY0zez20uGMIvc4j1ysmk6dxwDwRaCheGXH0kDEm9c09gv3snn7Z6ehL2MNbv7XMgBFo +6+HVxcs/7TaGa4Ah5YxJBvaaH22v1Rsf+SVzaIQRHVOe8Em95pWdIHrPEbEtk7L7O1LVP8xzarrb +UDmWWDaFdwJGfvrgvfXLRhazeTJ4lgOMWNPGZI9uGLntKJrBAezPieDOyDYw0SMWyvclJ4Qkgzu/ +Vz+g43Xp8SjZMshHOJQBtFOp4R2dkPuMl/i8XIbn2fNu8wjXHZ/FqfEQfXTKnZ+Qx5EZyvN3kgcg +dN0z3xVjNdSePWbQqlAmOc6H35uY46rzEx7s07+BfU6UeH2/hP2sRyx3sSZP+5Fhot61Vqu+AB3k +0CIUbOoRo8bTc4gBpvSKKVi3Deh3x5M80n6n0HBb3dqMyxMIym0V1Xd/YZ2SfXt0RA== + cUbEJbLe3bRWTwtXTJ5oLpI3MqbwekZIbEaH0GLpCGe5nPNGzq/ijn3vGTS541SPnLjvXPmBQ1vn +TdXvHBkmMm/9ZSy3oDstlSua1NBGBsk52T23QgB0xycZjhFAny0jiEeuAQrCjXHk18PIqBlX2fkY +9LzRXKeGgKbYDyNdN4bo20ka20fGthxfKNcSiXhuh6evNSJ13xmpAue3Rkyn6laie5I9hDv/bnlh +OfID/V/TJVaekBu3nCVuvTLYcnrkpcwDHBbn4Nc1GxS0EsthDc9Jxu6gr/1IP510JW+1ZfS2PbdF +9yUf9QhvqCCM9TkPkGEi0p9lPK6IZ5bzCeNrTImr7XUJ9t1H3u9Hw3BxV3cPrU+E1r8eLgSBLbxC +Lj9lvEp9vzSw+NPDmpGXMgdiR0C+U1T2zsWJImhIMqSqYVmnluOXOeJmJuBQI85tMmJCpL5FcGWP +a5s3HR16vB61K2RjzATRm1Pm5kHp1vL4O6aJ5ifFk5GxO3IOlG+NU0Crtpz6IjGAVqyZLZCIqbLp +bGx45ZIL5icmrmfoe8T+GQq5dGMP66R8Arn8OFZP6r40rqBB33Wl26UgBMnnERYjrt5HQNeJeG3o +9cvY5lqwP7ZN0dhrfZkHaEsILeYQNNR7IqAUqY3j9eJnnoC+tI+ALyoXgrc8/uOUL6FTqIqfIZ12 +5KuUowIPkCvaFpk3ik6n72pjm47rtex/PXkCx5Lnm9Kz81aS82B3h5D3XU8cOG55h0bjmUeuPT3g +OxPgc8Vw2P9Fz4CxRgsyq96fGEVfw2mk4F+uTcyRjhawx3AEV5ZXrCqnI3OcLly2dEw82hxshhcL +HIQ38whz7ZWPp0oN6HdMK+ejZL4UTt+RF1HWIJpDUjBmNIkBCR12eqMD8qo8Akf7zWl7GXssp87T +6oSirlQ6hVraPECIDtz8xRvPfHzcm8KWYrbNL+3APBRnUBXyQLuAI96no0kd95jwTCcuAobs7Xvt +XwlscyY4tf6lMeMB01WCnaFOP7Oa8sHn5QNl+m7qqp5Hgj/bQ+UX4jj3b5HxytwTRSD+QSh6YiRk +iO5L2KcvxDqmtM/IVL2WrZ9wHI9r9PhJX2PXCshbnpeN05+CPRYd0Ida0YePOuRT9y3BEFom3jFm +zDSD7GO1fzS+Hvm/i42vyD48Ftw9vNBISfQzjGzcpi1R75e/xna8umKSEmmMqCx7G404QoYYFx3f +M9JJGWpuBWNfgmBnt5QT7c9jSJ1RDdp7jGjOi9CYkxA1PDbmFBbNIWSfUTCGNL+EPcQZI8L/NFph +i+sM0xMx+rP3vDZIbcKnaaV2bxxuXVdkRFuGunMsa3TacylSyqix8YxIXtdp45LdeTJhja7jU7Ud +CtiGX45befruNCW0fdiRV9FSLoXx6KxxhBhiarNyFT1m4mO5+nwl2xINbD6DU8hxX5jfabSg9DGP +lt9mTbHJUFL/S9hHCxVulywHxjPDAU1JCRiPWJAx8ZUHLiVenNdn17ztnAGaQlw0pqSB0l8foaSa +I8OFMNYWUUvm36ylzehrybQiW9rkNM8bmdrbVsb7cHkoDCajpDFoITIyVHLOoeSeAkgcWeeGljNP +JIle/xfG6460HrMoPsK9pPUcGkRDoNDjdhF9ZGRHw/mS+QhDLdn9FdLLhpE5Qt/M+7Fx5q7xysQR ++nJ1nO1SScvWuD5nnUVXIyC/wC2Mj7MN6PWZbxU27j0qCDSjrvrcHlltGJcB/CzLqd2+uCmf58Zx +xUXJdhjZhFYXsR3h9aLExp4ob/cr8WCUtieyi1Sh5wGOK6azVvN8I+EHSaWKEO4r19/oxV7zCJYm +6fa0SFjA/vKbY/vbTw6qs7hnr9G12nh6LHEINY8803BcdMcRQikeVRMw3jk5TdXwteTFjvvypkee +wes71xmgA0qNyRRBUR+gZcIcdRkS+6A/kGUWMPY4bC2R9F/vL9bvsVg+a/7c62A59rWQPr/erbK8 +p3kEtuTxYDBSCY4WyqkjQk+gtM+P40R4L+0x0Xa134Hx5bPPLG6RFh8NZZwwRtNRQVe8cY8jsxWo +jBnnj+oG2FqsyeBVfY79Z9LF+TUYGff1AOg34tTJaB4YOZmhAVaJwcfzCPrXjzMDvY9tVziFrdSU +TVcJJHVYq0TvNc2aXwA6meY6vvd5gNLCiXb+ltuOjIY+kvzDeKX/MdX3dUnXHH7wRS62LmDIh7oP +5ZL93sx7eCzBfCtJYWTvQr2+h+uqHoUj/bzzo6Cs/Y5KnKeH/uz1xoV3hmnoL3Pj9LkcaIGRXcc8 +E9UQ2/JN1pVtat30Su4rhb05vVHl9P+x9/bvbdxG4vj9nOfJ/8D7tm6dJqQX2AV2N056seTYdU+O +fZbz0ktTHUWuLNYUqSMpJ+4//vnxvjMDDIAll+QuLZuizL5Y5BA7ixkAg3nDoG3T7bJgW7HPZyYK +YZeK5Las8aGOaxSgNAvludIBBgp6WBGpbFsSHXYemQ1k6TkRH3BCB7Y9oZa55F3UCDSfNJGppzZL +PAYpONojlTuW4kONcWL0F0TrkgkSf84qM9e42h064iNVfrNiBTVNgwAdXaNkMaCHiCVcHpycQ4ch +p3rbFAwC+jwhnfHrcsnZiKCdx75v5qpXJ4dshxWbq0Iy06X22ncaIKAr/UwXNGcVGW5KuwvF+bJR +tnNHOiEk4yScPLnFQMmO7mQH1eUzb/RGIE5sa5FrjowQUDl1RQg3263rTpvgj5vuypqR2ghfC3TZ +39rE/+nMiIgtMPFHyBBuI2LaePIsUHKyOZsBVadO7FJOmAglPWlZzjZDgDbPuA98bA5bxpqBmTPU +UMho7gPo1omVPJw9rc2FUQaore2tjWByGCh8Y+AqdTuTYOezdfCZtpxPhWlNsRWU7MLUJmB5yM9T +uJTgKEQcWg7bY/3PWAfwjM1TPveFd6ZFvNPbBDQE6jS3iyMOzlChhyZLmcWaMXD+ljay36JN3dkS +f3YT9wHNfOOzRbRrsZXOdn4mjc/KMC0PtjIOwWmTJmK3MlZUkzTi7ZFTD+ztsh5Byj2gq/Ls/uoO +fjj1DMNGDKSdym3G0ir30DMR8c6bZ6zSxirhPV7ayLgOTRfSHTI3yDkrD1RaNgkOn6w8Fyb5NChF +aw2QUzPoomXW8DIesjgN1DOwW5gGp9/piHtF4TOr5Wp2q0ROrCLY+j+Uv9PIqNWSx92U7Snp4Nps +FAaoVcodU26C2OliOmEczWQa2IAUdiJjYOK7oJxlueIEIeuTmjPeyBJJWIkXsTOzIsdHH0c0BhEf +U6L0xSO21TjqGZxNpBAqc9iEkNAu5LOb/virhafCTfaEDTsv56yDKMtKosD5DRGesvRMs4Tfxu51 +bc6p8qv4RDPpnT2HQTAnnI6YmbsC7UZiF3xGN3FarDrsgjvsSAe2jhgeRyw/KRGYETsx59/GwQdt +NC2HOXYGp8zcocHEL7jEnQVMtDtv5PIBCC4dnA9tZs4lqm0cnfrlhH3gC0IECbOSVTcAasVDzEpt +1cFDC7dJ0Nqc+is31sZvZICZTeTWxoXqvBLC7S42mw4b5zZ1FaZeotivYT219sSbQ0DXO/g1a4C8 +h1g3GAPdAoiT2GNQ/ugqK+F5xx2Py+25EPSgSD45mwvln3eiN7LmNbprZMancpRkd410RxOlt0MA +LpxQD2xChOepWz/ubDxLTkmFdQzMpsvp0NtCcBXCKxtXtgwwlBq7nqWZcma3Eap0vbKe4yNe8st7 +hVSZQyw4YUqbpe9ceL6uAB2eNMA0Yu1M2ikNQA5Vhqc/0Y9Il2KWdv4cY8mOaypjj6OIeQ8RLiJH +nsjcnXoWihv7Y/+wvlILpFCRpcJHK+LgcFpujWC8JTZjRY7MXm4ZMdCFNqmxdge9ePrEzqrD08Nm +seUJcIydUVHoYiUzxiwA6y1MXGKTcqUg8sSfScu8YYq+39RtK3588C5xyftmnDNeb5pG9pB8jp4S +t3vgAnKIyXuUmLIFPmKj3CJURptsk2vcS+9YCXaua3v2DOsZxIHTnnI1zButCxCd6+50HHv1MJrg +BtMnJyA8jQNemrmD7kR3JjYzHgkMXmjepSkfygUvlDu9yQe/EKhZpttTBxjYAVbxHMGZ7DDk1vlV +6kPuLBmb/0KhoYQndZI7vRzjS4rXJl1zb4D+kCD7pbNQRkXOTYZlL1TshH3EjWPBhzntMcNVhTM4 +4KOcGZpnfIBO0SWv3C6Yj/5pxVUsaBn4GFvEczpNYu4ChzmUK3pC0TuefEFwyrsEbCWMFQg456FU +bgHjija7VpmLvg3QHzm11vHyoh06kXYTs2mMFPTMXA2HSHDVDtYYw8Ghy9+Vct2NuXHOajMdajYN +2aFoqzQ4BErzYdjc+LcIa5KEQ2GA2p58UsbcdBj82XPOGIq8hac6RpMgBIKPJ5Na4xHYaJ7C5COO +R1MEg4D2oAjAqL5GwifofTw7Zh7QDnnEcLbtUYY4vLAaUgaapGGMnivumVRBrF65ahOUseAQs6mr ++JQpAlOVJAxMYwe0HSZDwYfw3Xw0ahIh1Y4LZjpTwzxPWPDz1KXcAOVqRFjuSA7Wa+sOp9wGyWoL +Rbt9EoI/V23S/7BtJrn/KuHkiEinDPQ5U5QHwQgSex4zsnd2G6A95oW90szaOJg10oUxlGlhge5s +dxxzKsZiiQSbJJJx5Z6Ij8vL4Ly3Tm2/4kC20jp2GLx5x4muUezSBZXRnG3qCi9fOl/mMlr4nIky +4SmLQPBe7XKAYqfIKOOWdRjI4DCNlcPgdzQ+QFZ5et42tgYJbhwZp7MiPHWbGgsBPJfPtoeNPmF+ +kjfXSOu3mBO306G9y88nubMuYwvLbXKRUQ3c0+z5t4aSAbIzHYcn5/woOvlmKcu1x0A3t1vhmHNb +6cohKHMagRrymfkk9YkyymXQKbzR3EgxAKastEt7MDXCF7CGFmbKKKffBGOpTDTZACPBaKl2rV2Q +AQLpyzppzslFFCnrmuQFcXAOFjjViXBonug24YJS1WwtHorQZQHNiSvuYVx2BJRsDVs1jdCyLeFc +JtQDXpXmFkzLHS56kRjzixLrUlYrZOSymBHu9CNKwjpiuLJBfuUSeSPt/JbIP04Z5FMdNCpuNNEN +7qZJ6g5gRGE+Cp4YMTA69sXciS3Qq5r+CCaCbYQI8EY2dRKTZ51uITnxcWnVDc0zKlWusRIsC2HX +zBjoMOSZZzroHAn3LJXuTFCUc9kshZamYU/uYsXOTYDAzBmG0qdk5iYebZdm6hJAffEKFlpoyjpb +QoRpoWnGCyO1RVMQg1MUdWrFQO4OhpjyRgaBiJyrzJUwo9RWG8zHWWTm44oCHCrNWTO26eZU3oCd +bSJTjIGTYbQRPg4Di05thDs3dk4qdEv9zTUuI2lTgm+keAXIKOHX8d5s4/T2dcLlayt3mh0rDSi2 +DROtuSZBdV2POPB7RpHLwU5i5SwBm1AcmzNkdtOXHoF3udjYumnrTAxb+4nqh6fhqw== + LIYkKEaTSZfF7QPmKjWZh8KnBekguQnhnPviinoRWldgizxPBsiRYzKIMo8hiZyaJSVj4MmnzcGG +NuXXSxsSVsa/bDEolz6sTP7gEcP5HJRi/zoC09xZqO48gIyUM8ucXBc46xK3Z2nf2O0BqMf8wI0T +F4ghB2bbHD8QzmGIgRgDTKwqjX5sd8pGpGap2xmc2LbSZWDYNAMEcg6cMq56h8D7ESN7hh8xOMd9 +EkWMVjsHJ23WDkMquRBXbBVyYc8YJIHXEw9cRE70UQaFw8AnIpUJ8LiDGByPtEa/QcKmvjJHew1Q +Zn4LEMERD6m9lFJ8PlRkLgqiTLq9BbrgHh8lFChpnYiI3ek8kZsMLctkPsAm8iDIpOOMcajYhTZi +UwdDYLxNshbkTBYswS+lM59drQUZBXX37BEktJpYWMZWnAAwd/4YChkf8vOpi6pGmRESAOSiGVbM +GCDHZZUJGTgMMvfbr+AjO14/MvW7CZhpHo3gUAs2ZsqUpyFnJZVPqsnQHKSAgns+U3NlJfEgER+8 +pQOPFubrT5JSZxEIV6QLN2rzMtlxbhRboxBhngDl+x87tMrkgCEwMTlyRhZpVz2MtwW049wZX6w7 +rVOnkvChLz93lUwYgXQpisKfy8MyY5LHnDISDZAJ0Fz0TTkRQiq+fVq7YjnKZPgcMVxK3mGtrYGF +4yJX982aCQiUrHknwchqJ6gVFzeit7mJZIU0NkyFnS+Ry/QkuGDlUGZK2sZKsCyNbbEwqbm4AFr6 +IYJEsNeIDlA40ujsDyt8mcWRC82dsAfyMInHlfHLnBtEpoGVKXJ/DNGWkzHt+QBgZvKObGPLhwxt +DLYyM3eiGeGK63faDAMEcg4/ctJU6MDjjbnb77yPR6LKl7KZaZzNeG6SJZMt6WWAGQtNUhgNAjy8 +6eQgVSM4Yrg3WmgM2nSAlIOxygbkEMaBN2vyWMSC03pUx51f9S4e46gmmNssE7+JxsLpRIqLbSFQ +xVz2k8uRxMKlUygjDR0Gv1QpKm8Jk8ZnbKaP9fzE0pw7tULIzLM4NsFtw0btlDiC82I122UcuxPg +ytR6a5szx5Jdm6BSOM74s8jKSI4jhmcym5s6sTIZMJa8iM9qi4Snb3jGXgcuAyrF3KaD7KngFWtS +kPDMPIcJlVl2FoGvg4zvVdw2E3N+CDyj7zwZlD/hEKRuLIxthWf8fezaWhoITIUzmNz7c3fOVLmK +nAYubIqF4kALAhXbVrE9vIplCjLndhHOq4WlFWTubPDMlYOIglgCF6jCmhJKO/+IMa4SGVTBpDwa +gxkrWzgPI6soWAZDsbOKy5TIoPIrLWaHIHWil2SH7VpsEssNKXHORTecODTpfljdg6qn27nnFiA0 +5XQgFZ6wh/bS2W18jhVLhDhrw7q7EtTSY2ciujoliSkJY+Wsr8RBQlPyPDPHBBNljm7agTO7VQJS +nTtMqUMWMRoOCSOIjdqLQMWx3MSkFiDQccG7DRMdVNGNreKdpEEkS9jqX0nqysgok7FkMaRBRgXJ +/DYVh4ncFNEmNRyBfBDX2kAWQxZsg8pVXEiywBOXmUwnA3TWKxcMYVsnT4JqPFx9RfPRIAI609fV +BMk4gooWiRNY0NZ7mmziJwJ9bgRVqjJApVx8zp/qwmo6kh3AVMEyKAjkqhnbIpwIdLq8dRYn6IVw +dcK1O2eMBYhS52syUVwEJj7lxp5YVegDcPUog1JHkSv0okzJEwNMJWcoidxWXIuC0FigEyHcmY2s +nKvInCQ2aG1lEgQ6KRIwWAmXN+3dPFSDiXkprYWhRJg2lDsTCuHOT5lbe0v5o3/K1HVrU8mnyKlE +pCg4DL6OZ2ZErxIukRKtzoy7EEfeZ5gFXfBwVkYQa8x6h7LHl7GlU+Gkr4xEjXlRkHlu+5s7j7V1 +mmMxK16ptJFbBNIdYVbGILTAxKmhVphSNSzuqitLglDplA40cY4Y7nYKZY8aI8yJTRZXAOSKLagl +ubPoCmV34hprbpzmvKzY4QxAH5UJ69zJIKzC0lzFgaJGJTAM0FeQpbO5FgM6edymHzECTum24Yt5 +BL4kCIJTV2Tcv0vwdMy0rY0YuysfbIlyh0A6VZGckhboJp2tKxi73JWSbCS4q1bPVRtjF5ouY3DR +osxlQyOcS2YEjWWg33NFHBwG57iV4QTJdexUOlOECLE6hyFXJaOhYSYE9cOQOZq1GcHlOWNXm80l +yiCQ3bza7IwOg9+mbL4Q1pILvFGZCW9hiTp3bwNIDTeSictLx+3LFgEM/VY23ozAlAVpUA8ECwO6 +czcyEYyAykgloR8IgT43w1dORwzekWn3WnxbxoYwVwWiLrgBFs5vpbSr5+W3CaxkmLPU5V0Nax5q +4XrrFBGVBqmWURpzLUQXJXRyFHO9ndfJ11dS2tXbwmmWugJ+6PZnTcZm7VMVYpdemHPF0SBbw5c7 +ULk7gup92AhUsTP8I8YQ3IihnRqt6RIeN3/NUtHCuFIS434z+oL2xohPDUGo15oyK20QmLv4jzXf +AJj55ETlnLwI9xERl0QqdeLC/+hyijIPTxWnf7EwRJXLRSuVrdtEE9xFnJyWQ0KNmRZYRbz8rJ5i +8FK+Fnt8tKVEu0PmNpPVItbmMGcSeu2Jg8x4Os5rgLAlcAqbD3yRR1uH42m7htUm2MvPlw8ZuGe0 +tNWb6GCICwXZiio6dUcUlXGJHzKGPI3mFAosbOT847YoKlbkkFxQgexai8DWjLHKh50rmas/o7kg +Exe/NFQK5+tbeuVCHHMJCnvzkClJZKi28UOd+hpnmY+J09EpV+8yDfmV+EJKrnY1HYriiihUzT1g +r6t1HZsCX4gj4/OQXNuKju24+qXClerjE3mmsb04InXXCwVlkfG4G5/tp53DzYjM1T/zVwCQbOD6 +UWkkeF6CiOaX2cKb2DLhMgm5S603U5DP+3DCDGLwxUNTN1m1P1fsanxQGNaVP0gyRpDkrg6WNZUp +tuAqYbpjYmYi8fEkchFaoKtjQadEDDDOuCBZEJ0nndthsClCtE/wVThOpCmXHGrnhhMGyp2KpwOa +Vpq4U8nKVqzUKy4jcdXeWfXVSceV7+VSGgDzxcToFMYhC7Q85VIy9vg8AoPqodYzgEBbN8de6+dF +qHaVZ20EBOV1wkcpcxbiqK34eersCoQrJsJobFq6Q7e+shMC49ytIBfj0j4dNnUam0Ydlw8Ygn2R +WGCScf1uSo93GBJeyeS4NDBf2oDj11oYu9YuOj+SwnnyU46WI4LUTQWzydPmxuWuROplBsBzV+HW +lvnRIqywq1IGutql1CuHwJ/yzKyHFIE5n9RPrfELQL4lJjM1QRwGf2rRKioAC0p52TQvjVFfPt3r +z/wg3Bf0ocMotrHgiqi22AbVZtfMb3fbGtVxt5ZG5sp3LxZ9/xvVhBeth6zrelmd4BZ6UQXXbA2F +wKwK6JU/GZxJ56SPUn1iumCvHRpetpx2zyFwZAZtE1/kwyGdo+HQFdsXpgxT4k4fXjA8deexE2fF +cmpQ2rFV5dC4jllwJN5OE0ZDTNzxW27rTmJL21/hEq9Tc4bOY4h4dkur/AmXLoxHPlNGMEeBJy42 +U4LkGHlf3djlOcfpOcqCQOVc5dbPIAPnH5WsP1xEwKV8VOxKAShjFLfZ1nIRIVeakuAuWJU7K47r +mnsvNQHZFKa9KsQgF1/n4k/CYy1zwTDoT9/jnZUPnT1WNlYvHNzlG2eK8cXeCWzTWxCYlHKHvKHn +76nJ2VzmCw5dTtIKQ1G6C/Y47ETWsjOB1xq7UjtHD88ZX+HRmiyVPDgMru2bO0ey9o7F2B2gS91R +FMnxZNIY1p0jqT4F4ivX2JSGOSCXN6o6+XLGnnJfkpeKa154eEVpaBncyJe7yP8ilqPgTr65Yhvu +Tr445/1Z2sTvUrENybe20eEDVyRKuvoF2iXKY+MkdRgcVn+ob6Heh7ulb65OhLulTzmlJM79ubMk +qHQWc5mSJCjnFJucuOoKFPalsTlBO7eLENyVRou5gknsbFwn5lbUhPAFE2ObC08IXPGEEOhqPwgR +ICj37Ci8qKpU/87dU8WHqRGuuICe18Q5lRTDea62WAoiqMcIfMUJdjVF/miPv6ehqgKfXZEL9bQu +GO5qEPD5ujx151TSjkm0Iljmq/5EQTEsPnCcmmJ69mV55IB2QS/04DC8Xsga25lJAg4u25IOHvFd +Wb4x30qyogolh1wyl3yKwLBpe8k9RJU9c6sWC6L5csBobrtLXTkFgzdiOh7jSjvzSdwVLM01FyOz +2z5hdcor10JZ7IIb75QUOTaQNV/zmZKkYrCrW2/grrm5a8YAeapbI5uArlCICqoqzL8wvBF57gnf +F1f2mAxF3xdXDSIx9VMJmPqyLVov7Yt7qa9NTmep1r40dXa4u2YrddW93CWBC3gPgwvA+OgMSgYR +XBzL5WdtNTJ/36dimauE4CoqOnE3Tqd5qxKxl5ORKRtlfkIN8oLhUezums3cBYeZq8Rry/ETckeQ +ryC7qte+xBZfC5yFtwLYG58q+ua7LTuSvdkyctf6ZsJFv+ye7yoo5N5fySfksbQNZ81FMuWSDVnC +V25GkQjqH8T+UB/fCCucG0z7skjzXQv3JO0z4dw9yViuIOewlI0EmrYci8iUg7lMFCoR43aU1KWK +2rwZAuYuZGCvjVvogRfvsVn/CXs3LxxYcHyPcgyPGB77tEUZ81FP6VJauNMLiP0rlcmMNfuj9vdG +Y6U+VlD8hSIEF+xVkO52lwo8XsTqIPlBeaq0K0uuTDF0V/zQxQHJRDiqxnIUXIPoNVg6QeHue/Pn ++4ITLFivOfbxdMF51KDPcAJYnDJwDrPf7HJXbNxGIC4YHitONuFwOWZwJu40Tq44g1NrFz9w/i9s +60PVfLNk7nyRyhejXuiCV3ajICJEx6guGO6vOcZcW5fI4q+bpYTooyVoDNPBhMpbdz9r/fTjwuc7 +D55kJ9+O+geTq+n58+5sVkxGBFUIPfluPHo+GYxmg9GrdtvCD4pXg1H4y6effHdJv4nI/Hj8w+NH +gyGg+vSTe+5z60v49tPTo+/G/YI+Pxz0ZoPxqDt5u+an+627v10MR/BjGzo4GZxezYrpZ60voOGD +yaQ736Z3Phj2J8WIWsjWvSejmf8R/5m9vSzox7ug3dz5rHXv+9GgB/BjwD16VW77pju8so1/HfRn +56tbj7oXpjF0xzb/YhdIOy8Gr85n9Wnj9tsi7sGTkwfDy/PuiahN4qAPTdfRhY22RdP49J9Fb3Yw +vhr1oY8H499qk3ZG6wvazqb1h7D00LZobjBF17AjJO23nSDobX2C3jrK1vX6pgnY2dXk9GpYjHpF +bb6Yh+uyxr1qa+TVJmxSTK+GDYQst98WcaPx8Www663Z8gICp9T85WBYNJBDpYe2tmw7kapN5ml3 +WjyaFP97BdO6wSKee2xbpMradI6uLp71Zt03TUYzfKamyFpGhlhFRvVWHu6Jxcuaog== + J+j+6jHZynAdj68mveLxpHt5PujVV3ZG9YdsMNoR+TkYrZm7Zark9shax/6AqPFlMenOxpP6lPkn +trzADscXl+PpYNZofb2nzpAyW7sf9x4WZ637e+N0b5y+D+KccZrsjdO9cTpP2t44vTEC9mzSBV11 ++N14MN2bp3vztJLKG2Ke1vdz7rZ1Wn/L3FunN0CC7q3TvXW6t04/Tus0ub3WaRPSdtA6PSjeFMPj +825//OttCqC25a2z2BqR9FHYbEbjIP/KrdM36iu/01n/YfFm0MVuNbFlwqe2ReXp8GrNXng9Ruk2 +lY/H3avpdNAdHayl9Wbr9/VnZL+B9OnvhIHZb7BF9Le4RzRaT7siCsdnZ9Nitn757L6oeEaU7rKQ +qJ85Mb2anHV7xXGvO2zgQy0/ta0ZOUS1HdNge+PhePLlr+drTcvSfv22EcWm+V6iXCNR08ui9+xq +zULbYXe4iOrPRmDF1bA7+fa3y/GoGDUgcvHJrZHbmNrD8Wg6625CrX9yR40mMCPhP7U59q/6LPrX +Fm1j1YSmHbH3RaOBei8W//tSdJ6PB6PZUSNn2RfvrzfHdm0f2W19lxWwplvbrmzZm/l69mGY+TDM +TkzKHTXfNgoz3TQBUl+Zet1gdb3e4uKqv4e+XkN8iSKxCwrv67gBRfFOjNEar12JomTbG9ZtTYdo +rmbsylbcnQxm5xfFrMGg7eKWPBzMnncH6yzg/Z68yYjctC19Awf6BnJom6P8tJi8KpCvu6x5NV6S +H8MgvdfO3ICO3Mp0MLFPB/tiN9PBDsfj4cGkKP5VP55143PBPsbzSm1Vf5ruiDu8ycr7KNLfRKf+ ++f1Jtz+4ajCJuf12refbmdrXHwy7DfIFdtG6rD9ouxZabzAd+w2mY3/72vl4cnk+Ho5f1ZedN9CG +us0ycS8Jd1AS3t4ztw2Ow+0l4Tb05VuXr93kAOZuCMDT+pG8nRMPDU+T7Y582P0s7Vtf7KLJ5NsV +UdFAsd0xUfFRVe+oP4y7Xb2j/kmQa6jecdNX5I7tcLejIMma1KdQnjQ8hLTd00cf9+a2O5lEp/Un +4K7t2A1I20D0bYWkF/XjZYfn3dGoGB4Xw6LXyB21+OS2qH1QP5S2MbWLT255W3s4mF4Ou73iohjN +nnYvd3lvu+gCuvqB7F2y3aIW/7e18FGUPtYmnz420C65/S6I113Z4eu7I3duM2xY23d37IBDPN7+ +tIaoudnCsskA7chyanDkeZfLA9V3Iuyc0KhP2nsSGjdtlZ41Szs8GwyHjZLyhruwWs8m44sGVFHr +bVFVfwbPxg2Uz/EWVc81OmLonMW7DRs4ZU3zbRHWHf7afVufOBCOs+6kmTQ1D2xtLtYnrt+gDJtp +vC2i6m/dAXmuD98RGXUJnXtsWyQPB6OiW/+YUq877D0dNzhREjyxLRInBTkh6g9ovz+YDd40GUv3 +xLZoHI1HDQjs9a4urtZngpVIDJ7ZqpHUHQ0umvT8i/fVkdtTaLKd7TOXbrwB2ru9mUsNSNsxf84+ +c6nGOG3X+91k8u2KqNhnLt2KzKWP5lrcBuUzdzV3qcGa3LE97nbkLtVXgXcrd+nj3t52J3epd3tz +lxqQts9d2ucu7XOX9rlLm+cuiY8ud6mJeN2VHf725i41IG3H7IBbkrvUZIB2ZDl9HLlLvdubu9SA +tB0TGu8hhLaLqVhNBri50NnmAN+KQqFNcgf3w/PBh+e91unZudF5r525AR25jQVcHzw5eUilmU4a ++spucXpyA4fojtUVu903FXzYGmNbFc8b1a3ai8UNxKLei0VLX31O7MXiXizuxeLtFIvfTgCyVxb3 +yuKOS8UC5/FeKO6F4vUJxb2quFcV90JxLxT3QpGEYhhhO2mYfHCLZWN9TlxTTHwXo6z7lbbxSkv3 +K83SV58T+5W2X2nr55OKWqp+NqdhwYsmCZ3BI9vSAEGaPB/8VgyfD7tvTxqejr3JefNbvhlwF8Xn +pLgYr6tFsaNVmgajfnE2GK29K7qUuXdZdGcPm1SUCR7ZFqH7Mkc8ertW5kg0GLrdqXNUc1O8NUWO +ppdY5qg2sfsiR5Vj+dEVOdqOxGmJ+zJqCQX/Ri34/334DH/vww+tD3GIaXvm0walnW6atnabr9H9 +4Ib8dnK911ruO3yQpBFx+6MkOzBGOyI7Ng3Y7Ur5hnXjcH3xuu2cTxpfXI6nYKg/u1oj7a5HOG5T +jhwyrbssROr7DF83WGKvt7jC6rt8X68hvkSR2KKmX5+iNeltJYrinRijNfHXEkXJjgm+3dqUmxor +u7IldyeD2flFMWugb+z61vxBSsTepr15FwNCmw34/uTrO3bmBnRkH82/BdH8hnVA99H8uZHcR/NX +MWgfzd9H8/fR/KUW9z6abwZ6p6P5+yuL9tH8XYnmk3qL8XwZ3W+m6u4j+LvkFNsNh98+gr+P4K8x +JPcR/Hcfo7fFcDj+tfYoDQevzmfQoN3DCrr1R2z+ua1p1fV16sHZ2dW0OByPwBAYNVh1Cw/efFqN +oDhudllI6aGt6Sz1d4mryRmoqQ2JLD+1G4J0RzZ4u05u7e7XlL6P5Cb3vVdx71XcexW3phPcyrvQ +m2ile9fi3rW4dy1uxcq8/2pSFKP7oM0W92GvHLwa338zGA+L2f1J0b8/nnRH61IX9j7HretvIqvv +F+7+a3BxNVtzAW5prvID25qouj5xxRC+NfM5Bo9s2X31cEDOiSPcOG9AthD0h4ylI7uR7/ICAVn2 +8bjT9v6XnfW/TC+LHqgFkw90TObGz0/Ljm9/uwSNrInDd/HJrZFbf/fiTjf3by8+ufdE7T1Re0/U +3hO190TtPVF7T9TeE3WTPVHW72Q8UdYtRQ6pvSdq1wztvSfqujxR29sqtx0d/1j8a8fWaLsNDrZN +HBe74pS53cfcb3nlmQ/sUdumfLsVhWcalADZkcIzDcq07EjhmQZjtC88s9VN67becNQ4j3NntuOP +pOrMcDB73h2sC3Hs9+QbsSfvi8Hd/D15Xwzu5u/JjYXermzHm1n/+y35Rm7J+yJwDffkXcyzaD7Y ++wJw79iZG9CR21gA7sGTk+Pzbn/86/6eMz/G3398ldFuc92N+jX/9nU3brbucVtKVNS//rhf/25u +arut2deAojXSuETRbzuynnZFFI7PzqbFDJfPpOg3k/Y7KjKeEcUfsa3yDkP+MRgtN224PljkaedG +am9e7p55KZLoTu1J/Oug3ySf0Tbf1lYq4gaknReN0uZc+20R590C+4Lp1+UW2ArNbaHqz9IGmvkW +FfNGJDUwn97unTc30GLRe+fNLbHEbovzJrt1zpsGFO2dN3vnzd55swtD/jG4BG7acO2dN3vnze1x +3qATYNZtkri1dwHcvsyAs0m3N+sOvxsPGpwYMI/XZZN72VYI7L3XLK7tkFTfa7dr9a9G4+PZYNZb +4ycuuQWw+cvBsElBg9JD2yI16tSv9XXanRaPJsX/XhWjXgOrc+6xbVHaoMrX6OriGcijN01GM3xm +B5bkvmz+kg14X6zsxhUrayCizibjiwYDSK23R1f9y7pm4waaznh7NN36+mu3svxag419X32tLp37 +6mu3sfra9pxiG5Qee18OsZdXk9OrIQiLnXakNtGWd8Qm39dBYh/cu53u3Kbre6Ozj3uPcwM/wO1N +F2xC2g6mC/p952RNhYR9vGCV12L7KYMN5uluJAw2IOijSBec1VQRdzSeg+Ttwx+3IfwRfSzxj/oJ +eNcQ/timAn07rNNGEmZvn+7t0719urdP9/bpTbFP62sVe/t0b5/eKII+Cvv01mcc7i3U22Kh1i97 +s9sGan069wbqDZCgewN1b6DuDdSP0UBVt9dAbULaDhqoP47H/VeTbgM5sLdOb6B12ha3zj5tRNJH +YaHe7uuB6iv7+5IrN9QIb1b/YrcuIr0tdWT2RYBrUrSvI3Njiorsmhwc1yggs7uS8FrL42zH1T8E +q6fdGw/Hky9Ph93e6/stAxpfdnuD2dsvm7hYp7O3wwYxANt8W1OTiL61C68ZdTu27h7hFN3lZddw +dG7/vrb3Ey/6iXdtDHdNRE6pwPLhbRaUt+L+1l/Pm9RxGKIjGRq0a8jYcLTmn9vWrKxfDMneIn04 +Hk1n3XXXcpYMuvkHbz6tRlYc97pNFMzSQ9uisX6y2/RqctbtFQ2JLD+1t9Ovkaim17Tv2gbY+Br6 +j6Mukojrr9nuvwYXV02CuO6BbQ26rl/qqxjCt2ahheCRbRFIG/nWi329L43u4YD27KNG4fUv3md/ +SIYcWe1pr2fuip6510t2Vi/Z5L76XdNNGlSkZHZ8+9vleFQ0MYQWn7z5lhD3ubnZt/jkXkHbK2hb +UtD2+tmH0c+O7aK/DQraJvveruzp++T6HQ6afGCFbB9ReNdzY7VH6XWDFfZ6iwusvv74ek3TEkVi +exQ1GKM19c5KFMU7QdGanJsSRcm2N63bmobd2D2+M9txdzKYnV8UTW4W2sVteTiYPe8O1pnI+z35 +RuzJDXawHdmTG8j7HdmTG4zRfk/eFaG3K9vxZtb/fkveb8m3YEveRTf9/u7cnVLAPsTGsXOD9F47 +s8uz5dbXCNvMIb8bqlTdIks7nD/wEVVB+3jKdH/Ya0q3uVndjjJoF11AV7/ozC5tD6IV2f9WfXKQ +2rTTxwZzldvv0BayK7vjY3h6uj7Z8TYYqcPx5GmNNXqzpcxt1tQ+jlJAH/q46TYX3W2pntOur3Tu +Svmc9u2rn/OhvG9bIe7ZVs6qb1N47H7BmebK1UcwG3cnTHXLEzkxbIMj+PIDXRBwm0JUuzNguyJR +RKfBIb0dVv/DQax/cHdHl91t0f9v70aO0/Gns2LyaDC5MS6gmzb6s+5pg5HfJceubNUPMhAXfmjo +uS09tGVh9Ohq1Huxy1Lo9s7DTtqKWh/XTHy8n4k3ciaKj00kHtyEFCGyz7AqwctJdzQ9a3BVzg1c +HRvpVLuiMG56DGrv9LkxTh8zhDdJ49+7fVYMGaVPPhgOb8pg3TT+bDil9xm979iZG9CRzW7Vu/Pg +iYhOvh313e16BFMIOvluPHoOWKhqWdvCD4pXg1H4y6effHdp8CTmx+O3F6fjIXTpQb/fetR9M56g +0Pk0aj349JOo9dOvn35yRf+LWs/gn47OUzC9OyLJktRkT3WEjtIsgQ86jVSWwYcs0zJVrZ+6+Bin +W/30Fr/9FT79E2C/tkTUetr6+Zeo1YeX/fTi00/aUSdJtMzylhSdTCWqdQFAoTsijxJo3hFKJK22 +TDoqj7MWNpcig/e0pcIn41Y772iRCd06hAcdUMiOzqK0dYTApJOqHB6WUSeKkpw+SKXwQ9yJMg0v +EGkn1jImSKxz0eqZbqjUAi1a1cmklgYC3SWISBLlIfRg1MkzmQTN8o5MdIRvlB0pWm3AE2XYA5F1 +hEhi6r3jRVuIDrxYY/eTTi608g0BlHVixGlQwbuiPIr9u0QCxIUvhx4BLI/xva6Rgg== + kcukJw1oTXQuSwwQOXxErjOb4G+m09RzEsdFxdLzG8hwMB6YIwNLchospYWS9GCsNAGiBCYQAiQO +Ug79Qd4ZTHmU4es6caS0wZR38jzRJViMsy8G7DjQWZq3YtGJ0xxYkAJvtM4QwH2KpZTUTweDvudZ +nFhMMKEN7wiG7JEEyM2IwEQRCgcSmsYxjCDyCaaryDXBkhgGCyeF0qkBlMaEAfAU9C3SsfKwGFgi +UnxXigOsWsGEgLHWIjbTJIEuJRk3QyLzKIpzj8hPyuB1OJuJ00Ez6IIQqe83TrII5lhIHC6fWEjl +WdBGzmmpPJfasfTrjiDYTwdkpuNihGc1MEJ0ZKQjg0LDoCGHRI4ccjRzN3EiQGul0pbM4GHdSjo6 +yWA2SQ2rCPiuYYkkSrVg9UdxIvEJBwJCopheDZ2GdRKHIFimIs+lRFgmACPKBYmYYQLFYWdYOgHq +s08/+R6lGgiwPryodfez1k8/gng9qZRlAN5UmsGjVfIMwRtKNNOZjWQaPrqRVAv5Esq1OycVku3O +SXPZdudkM+kGz20k3+6cVEk4A20u4+i5BSkH0Ao5d+dkM0kHz1XIOsK2gbQDvm0k7+6cbCrxYApt +JvPMfN9E6plFtpHcg0erJB+CN5F9MBUaS787JxXyD8ZtUQLeOdlIBt45GaE2fPfBaDxq5VIbEeg0 +RsCR53EObBcu9x4VQ0IJDIT5o7Oc5CODYITzJDaiAaQErDVRCeNHj4xiCvMnroShCMiNUOFHK0DE +w9QoFrYjFaDgQRpZHLJFUNCLeTqPVuwaFTzxwJADMH4VfPHQ4GU4qou8CaBB9z2CSmDADt+tSmDp +8Qo+eWCpTxW8CmeXYdP3CASrdVa20uFpa5GBbRM/Byu3mIywYuxk9pLNMqC6de9gPB6WG43Qr/34 +atC3JvGdE7WI6gUYS9PZhHIwAoQgU2BV560EFqQGyZ0oEBBEq0yksZDuvSi6Q5O/j0+UsObHw4Gp +vgy22ePJoP+fxVuLGc29k08/yd30cLaftdiqjLiDq9lsPDoZvwHjcs6G+9MVMvKhW5fL7LJkziyL +WmA0gryJIoGbNi3UjD6RQeU/gqCSpknbbDoyynCHwy+p1QJbVvOTLfoZUZrHUKHIUdQD7wTpefTh +yL3afMHGsAfBF0ahWoQVlXh6z5H5gL/lYKLaB7BXAQ1GdYuQG7GApy/oLwyhAk0BZLxWqChE/Ah8 +sj2KmGj+hG1T7Ar0PpK4LxAajTsZoSa6he0ZfcLflUxb7mHQplqGkfyetkHvehxZc4f6hV8ZD77H +YD+0pEDDg1NaMt+P0IPQb72adPuDAqZz/BkNeDvHwRfBWSjROnhFNmeE/0HlCTql0ZInALwyE6Dw +ZKjJ/HRRbqmqW4LmdNCri/OgHs44Ipw0cgcHMKO/x+UBW5UKpnLAs4syL/lTe8nHcDRK4+QY3GYO +l4Z5YQ6Y6XEYTpSqDzy1hn5ozcjaecjTx82ecNDDyRCQ3Fs++rL+6EMr0DJL/M9wpMTC6MfVLaGD +86O/HOf86C/BCdSXRn/pPhDKePV88FsxfF5MzorezEhJI+5fOzlbZ9sQ171tJC0NjAcV/YPvEIeT +oj+YtQ67k/6aHeJ9+vqkJoGAI28/2iUoc7Jlpdk2BAPoi+ZNBG3H2Fgu5it8AxWTvxsrjD45hPYD +IoYXSlKNzQcjWfnX4CGDyW4swSvKHbA940+MKaDEEhjsOaAvwCMX5kMKCxm0Imn/ihwfgH8PDW/g +E7HG/9wOnmobVNQ2L/Vy8avp5Rk3NRRc8FdtR4CMIoubP9BLNf01bGubXoUNwictwkPbCz9Y5a9n +RoTfNIUOdLkWWEZCfPC1+bA7Kx4NimG/UoGzq1IJndC6TGKRgJIcfIhSlYCeDm0isMmrPphlCqu2 +7kJNjXbU1nbjg7GnmZK6v6kdSkCaqlijcFBSJ8odswZFH+wMkCCdNE6lqpIVYLnSW9KWmYap3fG0 ++8tzF7TTT1E9sJ0yncAPZC0o/1ev0oTU6r0QfsHtVLX8rgT7TwKbEAhC3AIjtLtUdRMFpjXtVCux +HKzBkujybkeUXQSk4ofE0pqEtG+o/a3orV5Pc7SeZr2eZlWm+cpQSSZHG701RDcq1swA90Gsolzn +nvSkmvQMJwz+Recj/JMwyagMhr+ohOlcfOSg+pF4bijhR2lJkpaiyNLBf+U6cto4yTagKNCzRDxH +WbqashWPVlCoLIXKUsgjxX9XTlWiMH5X+nS5hY7q06fX0BfzrBQ8KwVPxjj4cI2zMirNyrT8gxIV +pEWlSTn3RAVF0hIkLT2RpYL/Xu+cjJausmjZKouWrrIlFNkAsp2DosXjwn+vcw5Ga9dYtGyNRWvX +WBV9kZ2C0k4zaedd5P9e3/SL09JwJXM/ZItU8RMHlU8sEiMNLUYdN3Mu4j/XOvPmSEnLP1StpDlS +0nWkGF+2mV2yZQfD/rnGKTdHSLAeDCUVS2iOkvlH5kkhUXZBf4XVMPiv8Xbbv9czxZJl45IsG5dk +2bgklcTQFFNmNikzt2L+c71TLFm2WpJlqyVZtlqqSVGGFKvr2sGwf65zir3nMfk+MJAC50PUyaUU +wkWMMCKGotMEjoRJFkq8YlheYl5NFGyZIFra2S78TuZ2NuH+ysAoFa0Hl6YvScvbKWgecbZS6myW +sq3CRsyyIUjXGB9ze4BIy4pybKbQgrJDSnVFW51Y1bwe3gVNaBneWNV0x23Fio+h2yLif+KO8RB/ +UFt+Mr7sj3+tjsVYZ1tEk6xZUEb4oAw5nBVG+xRlKFwsgo48qK07CX0IYRkF6xNyOauU8hMSi8C2 +YAC6mDBoTykmuUflPNIOiMkh0E557B6iA2wMDPq6Euaw8Rtz28j1iwEm6YdelHtETCODmAmMd553 +xmFXPanv4n6QRmmuP/O5ngcHD3q9q4sX45k/qe1mjxFC3NPMDxlyKVK5djBgpGmUdjT94ABBzxws +HFYPxEeJUwY1fLBj44Yw8yOh/WxwqPBJacYwsVzKGQOizuZn1SE+szD5GMSkMFqmVbsx8JTN86iu +TwP/T9Jc6DgTHR1rFFtxHmmWrIKG2Msy90FSmCEWFEfJhDRT2QhZTBPCxKNlT0VAm4lQ8GMkbZu+ +66DOu5SYe40Tv9c1Tf+0VI43wFVKoG/d+248e1H0xpM+DJ0V90tHakFEHz548tgO98uz8eSCC+GZ +ToMI749Pi5MHT/IT6PPx7O2wOPFvn1+CgjIucDbJTTxkyGiXrrEQeZyf/hceFC7ShYU0t9AWVmNJ +8gZLtBq4uOTnhcKC5FgrTkJpvArmBNaCSJtf00vW+bw4CAQRgxYlyoLUrhUBrSEt0mUr2GhB0q5g +TNDy0kIsXcH0FGxmVlrwY0ZaNHzXQZ13qWjuNdcnLXZ0ha+Jgc+t8NA8wWhokmHYRccC454aTBJy +Yqss1gJ/8P+vCoYao4VXmbCrDK1rXu/Cr7wIVVZqOax66milZmJnQVRX5O92IL2TpSlmTdo/Eboy +7J8PrfI/GgwvKjT9UN9fqeQvBN9IyxcxZv0CcagbmLAxGHAdmWHunoUdBTD8QHnAR/7ZKljw7Jk1 +QjB1Ncoz0jillibyxzAUtIkwKEQnw3zyChA/uUJpS+wiTKoXocw6mGKAObfCpEnpThpnlE8F78Ak +arBUoVMmKUjj5iNzkr4IzTFnO1adWCay+tkUd5lYwrM5Zphr4yjDrPAMQ/iqk8hULXlvDBMtVwrf +G3eiWJpAXtpJtchp81QgcLPqZ4EwwCzJDYybFz1ar8sS5I1WJrgY5cBm7PGjMA8qlFVLF/S9p93p +67m1/WQE9ums6M9b4ofDweXlAG+iLsMfDqa4XLn9T1/jv1f4Dx04gzVQfOm+0fp40Z2ag2on0D+Q +z4/NBlK8GdBp7Letn75DyM9uFrTJUU7//IJZGDE6hH86X9EIQaah+V8WzKukRR4c6tMd6tDD7qz7 +Jaw2mX36yU9PPvm3d/7P//u/pf/5f/j78p//7/8+zO9LOr7/ff/7v92E+bn693Xr693+g3IBdnaU +CiTR/uLEF0C98PpumVQNdJq89ejqX/9620I5W9Yk7pyQVPYKxclPn1uFZDKbV46OBqPXTsLeJ8Qn +iyiNeJMoUtcrEnNnDb5f1EMWTiOQUP/TlekZOipxF3hm/rwi6KJmgqdsFnWTABpqIh5DNbSE4cyg +WVRQAmigj5hTC3NKigcGasqdE1RUkMbGqgrovJsrK6C7voO6gsd6NldY8PzVxipL3Y5XKi13Th6Z +GWTMUONuWq6wuOIEoDw8eNJ6cDUbt8ySHPyr8AbOoqn47HRaTN4U/RPQ6U9Mq2l5+fgjS7k7slTy +y0dBKmwUp2iBwQepokwHHzBalWDa9/zfpqff0TMQ49k/+CBlbpMXAmCEaZjwN4vMAsiSjBLAhfmF +AYdWZ4/ixAOPDFBibC54VHZg0LIAewCgPlhkFig7Akf0aA4Yp+TjZ/TwQSWpwWZ6wRDCJtyrCGY9 +/IYo/6ij26EPINSLwyqesTHj4irtFNMjdeKfu5gDGvQ4vYUKu5B2MjryF3YeVnuus6zce1zTOgsJ +zzsiTdM4QB9CXO890Pe+BLTjatG7YXO9CIecuxuOuCPKPeoJt9hDgBvxBZ4ZtrYTaJJoUeZlCDTE +JiC2ExUHDElQeCRpmZmqo7I85NsRAbMoSgMOAyRPo3AmBADHSgcLOBnAiFSH2nHD9SBkpOtryElH +knvWk23RhwDHyQWOWU7iIsDjniVOhkA76Tsi41VmFwZ0JEvm1hSuRdhdy5yUeLA8DSYwQFJyxHn8 +IcTx0gMDZoZAItehdxxxvShJIu5vSRIxWV4SOdJZEgUAL4nmuWa4KQMuMTNDGNGKe3CmAnYId0Dd +cxLkEGxnc+IJPbZxib2Y0izjLFjgJQhzMgB6TpaASKpHz9zwvQg46bobMNLRxDBPtcEdfmcuLnDL +MBF28lzPMTGEEZkKsKiQZwpek+iylExgt4xkWuJhDCRFccDCuKMTUMs86hDADPQwz78QhiQ6zMwD +9/qAea6bAfMcLQzz1BrM4Xdm3gKXDPMykBlSlTeZEEYUZoFUJR5kgFborMS8tCPjNC7xLgVdIw23 +Ud3JQA1UHnMIYN55mOddCEMKHWZmAb89YJ3rZMA6RwnDPK0GcfidWbfAI7tXC3N0PWRdCCMChfCb +v1m8AhTTrLyhCFxaSZl3+P44FJfYQao74FAHAOadh3nehTAk0WFmHrjXh4uWuxkwz9HiHnTUWszB +d2beApd4H7EKENUTydKSzpiDIppZTYLUq7wDmkXmVUb+HmqMDAsVRv+cVfo8Zgvg14fqIhllOi1p +i0KyvWdRw98ktZsUvZ8BgarIoFBT9M8xAxxmD6DXH1ZwyTKP1ZyQeQxzJLIO5ZhgFa2QeayQhcxj +tc09x4qdw8yAkHkOFjAvgBkSGbVjAr8/ZJ7tZsg8JsU95xjAmAOAY948l+Z0wZB5DA== + cySy2uSYwMpVyD3WwkLusa7mHrTKnMNsv4e8Y1DAOg8y9DFaxwF+d8g57mPIOibEPejIZ9QBwLFu +nkdzyl9p0VqYX1p2m/aLz2pSIetY5QpZx4qZe5BVN4eaASHzHCzgXgAzNDJqxwV+f2nV2n6Wlq0l +xi9bZoFbth7gl+0cn8raXsA96XhlKGS9iFnAulPAOqdjBaxzmhjDnK7GiB0gYJ2HedaFMKLPoWYO +uPcHrONuBpxjShgkPSMJb/Cd2TbPn7J6F3CNQUwcK0RMPStNAddYtwqYxvoXg1g/Y6z8PeCYA3mG +BSCii7Ey3fzigFvcvYBbTAGDHNEWa/CduTXPl7I+F3CLQUxX5jYKQzfrSQG3rDYVMIsVLgaxQsZI ++XvALAfyzApARBZjZbLtewNececCXmVe1BPIkWyRBt+ZV/NcKStwAa8YxGSxyuPWo1WLAl6x9hQw +izUs95TVwBxW+z1glgN5ZgUg41S2WJlufnG4Dm33Am4xBe4pJpqx+u/MrXm+HK0/8Px+47ORdeJf +a5xWt+ifX/DMdxwtidO6RggyDc2/deK0WZq8c5jWhpL4f//nv7/rj/9W/h9/2v9n/x/3n4o59G/X +M/uW/7jpf/bB0OpgqImDVgZp5sD1wzQ2cjkfqDHgTUI15smFYM0cuEm4Bh9dDNgYijcK2VTxkDCO +zBbFMbmMGc+hZ4rmwNNV8Zw5cIOIDjxZFdMB8KZRHXp0Ma4zB24Q2SHiFmI7BN0oulPFw5UjUBn2 +mQM3CfzAo1WhHwJvEvyhBxfCP2VogwAQUbYYAiLwRkGgKg6uZnhVdGgO3CQ+hAVMKyJEBN4sRkSP +LkaJ5sAN4kRE3WKkiMAbxYqquLiS6VVBpDK0fhgJq2tWBJKo6OZmoSR8tCKYNAduEE7CCrCLASUk +eIOQUgX3VvK6KtZUhtaPNmEK+GK8CU+AbhJxwucWY05laO2oE5K0GHdC6AaRpwqureRxVUiqDK0f +lMJ0oYWwFNVw3iAwhZlLi6GpMrRucAoJWgxPIXSDAFUFz1ZrJhWRqzK0fuwKnquIXhF0g/gVPbcQ +wSpDa8ewiKSFKBZBm8exKri2ZitcDHAF0CYhrkDbDpxMgbLdKMwV6NSBs6kMrR/q8mp24HMKtGzR +JNxVwbXVPK6IgwXQJpGwQJ0u83ijaFigM5d5vFFEzOvRZR5vFBWr4Fo9HbrM440CZoH+XGbyBkEz +ryWXObxJ4CxQnMsc3ih4VsGzekrznKTYJK4WKMxlDm8UWwu04jKTN4qvBZrynKzYJMZWwbdaWnKJ +yRuE3wINucThzUJwgRpc4vBmYTivGpcYvEEobpFftdTiEnM3iNJ5lbjE2w0idV7xLfF1g2id14VL +TN0gYrfIp1p6cImpGwTznA5c4ukGAT2v6ZZ42jyo55XfEks3COwtcqmW4lti6QYxP6/0lni6QdzP +q7Ylnm4Q+/PabompG8T/Fvm0kqnLC298mEMQ2ZqzoxudiP7L+GLhLsHqAxbvsdZ4nHTSmG6kikVu +Sl5LkMsx3p1E10Upk2rBMLxYKYmparaIV8DwDpxIm2JidObeHIkBaBybtBfzZvJaxlJIm5eddyQQ +1KJ2tmi5BHVKGmUkQp2nBCSMdH6JIHlWAaEHI1MagF4Qop9ngM2jicyjeIGL4QqX8bCQIw9Jg75m +9pqDKph/sk3os7gKhIpdlJhCB45vAszINDdlxW3PgnZzna0RS99O8XC8aA3EqCIxIFpJ2kkVVhRR +eL9Z/sErEjzvjorhyeFwPC3MzTDPqouRbXQ9TFCJTLvCYDiPMCRBA+4+pHRDBlp59D/8Spdn4fkz +k/doC39TDRnzGz9DbUxNr5YtEmOrfZmMGtMcv/rPhDS3RcCDFwYvDrp86KsEZqaoXwYtBVky+DfB +sjPwQ0Zdxb+GJv6l7Zu3M/NuUxLxyHzAH6W5qcw8Yn5tZ4aodmYIcb8Fj2SWQdnqmoL1b3YR5k6C +Ujk/qkwbLdztIapbpmKhnOBynPN3eyzBGcvqm13SYBISo2wF9PIItGkIPJuZaW3LteCvG6dg9OYG +tvzHt/MP2zG2WHmkgx4EHeNhfvdbWbAotYzKvMOSQEm+UAwyr26ps4WRW45zvhDkEpxxvLykp62h +eR2Vc2Qno+PDsCOgdsvZxolE1y//SHsMfM7pWjRj1x1h0qL5CD/FMIAmrbKM7mhNQZ00U7DV1S2o +02a0/JoL/8aqjlUREDRbQLe6txIPCYs8eefyP9e4g4oG9XwUnvu2/yTXW7jzZikL75XUeurB+PL7 +yzVXxm1SozSoXhRTXTb0RpliV6aerNHp4uCz9J/bYaN2nHVSe6tcgrVc2+7iOPPVZtrjZ5O1Th/9 +5XP0ON1Jh1jN3W/88cj3z36D1nilHHwrobHoMQPavvSIP3ITfhR7GhIdKBfEkHacE64L/sg3w9Fn +f+cYViV1t5EZhpjb4aT9zFyz15cZmiLmGT1MzyLejPUe+3LTKd8T1wivHaN6qOYuMmZO5LkWuaEL +Ptr+uH4ehQMfWc4Kd3mdIxX7xEw4dB26FkUHb3rK3CUjqBVEedZRSy+xq25bfY3dUrwVF9lVt112 +lV2o8IQcvCgzN2R6MBbBCAVDF3Cfmc9D7WZDMBPnRicct6BD16LS4KVwZaUiynPDy/JVc3i5AV0b +U906U4s1rlfiPqiPe/7aOb8YL4KV1nZLLVjCfmK3/cyeX5DhUrXDd1ha2eGCb4eTYBn/xbtc9EcF +v6uu+sMLj5e1zmQ1/5fiPqiPe57/76hOyoyGmhaUGXWa88LMbEmXMWYO7mpJRBaFoP/yLVoyRJz4 +abFkeVKT4KNtcRaM8QVdGOwfFuVpsDgjzna8fmPcydNEt7TE2xCTD68BgYI8q6X2vFcPJcqgTqTw +bvcL81V1tEDjSuadOBJkW6YRXteMt+/x50OaSFqnHnTkQeibxlhXCEJTAtYI1pnGW7/xpvQMHVR2 +0mkTZDh0sxCUmlSTvy3rRLky/s1cp9ZtSY0WIYyHIPOvas93pj3fYTqPuEhXOyTdelLLvGmHnGuH +XEXZhN/BhFJk/+PljqoTp0nrb+YnIJUuYHdYsbou5T9q/njIBNrvjuCAA5XffXuPzDhqwzcFnfC9 +OzTTgfsd0vTGa5bA8FRR0haoo7GOzYG1KKHkOQs68iCZmsDEUcWTR/a4oGtJlFx4EA2uPcqeutEO +AeEYLYMw4qPFd1m5i82C17dLAIdIYMli4V8+/72MFO/T1MRXFrT2K49Uik+zo74S4B9oe2zmW0cl +cc6gNvrg0e2b5fzZzSH0ziuZJIK2m4VvynXJo5jD7l99eFNd4XSPZgLsV8KQkcUf3gH+4vh4Xrrz +hv6+hTrecwjLlLyBeZxxsSQDg3We4L4H0iqNFQU3M4oQoQ8xFxSVN4AehVd0IrRvk9t4u8PCAH5V +j8oGGBi8IUnM4QLCgl3IhPBvYkCPDsyb7rhG3GGHZZ6q3gpn1L2fnh59/+Rh68vW3d5g0hsWJ/HJ +Zy06wwNDBw/Aj/PHeHBwQMLRBVY5jEESm2t7ok4MimasHfCIgIkkgZmCFa4iioMlEWrfWPZOojiP +YXAxWSCmQU6ISvwxQnMIGkexZXoco/6ZiDwxSada4U8RLjIlpK3OYIAoglOtbZgO+iMyckPmmEzS +wr9piv5GTRvePDWHiwQa6QQjJgBFSDascRhiFTYEaavzCCdopmn82ngPgcmxh99SHVNCnE4wrtlG +ISFUxt03QJwa0lQ/FCB8dUxzKuW8ErMrwy9xjJ0pd+pwsZ9r1NDtiB8sqx63EtiJU3SnChwUcrXl +uco+uBw6LrqT3vnS4uAfQBrBbojyADkAUsAWHMtg584p/yFXsSZ9jyKumLNKufOwcSfCpDcIoaww +EkkSYfp8lMs0pQr1KUx1zDnBtYCXO8O0y3WUI8A4xXD3wnKTsAphdzZSDT4LWL544QXmEhIiQAA9 +QUGWSLuo0jjCmIt9Kz6VY3oGGGkwb41mB91Nc3R2pFhk1HQJC44qc1N2GglTYjRPgUi8pFrTIQLM +S5QEAMZYTHNcGvLUrjo0mJcOEFbXT7Unr5/Z5LaGA4zpeYvjhtANRo6ScxfGzmTANh49eKxi/Cip +cYMRNHnT82Noy8Y2HsUKrhE22qe+NwNiRuvOSTBe7zRKQAxIRMzSTxOfQY2Wj2ihWZMrf+YqViZI +aFJqj5hQHUc5WgCgDScMLaNdDjwzxrmj5fswtSd19U3/9EFkjeoISuXAUYA5EJuNTKlIBjBQDGO6 +jkZgfVu6qUvmtBOh4wfUYaqhgDZjYkxFhelpYDHFEZmBUY4JFoANU3BgC1SJTDL7jNSwDSd4F705 +MYGzLKUMDDxbA7My+H5oSpjgbs4g2QFNO8cR0jRRYSdMcfyg51IKLjaEeWAJvAXXH93WkytjxsA8 +lIJWjdn/MRldASJbEgh4Sg5DmMgKJzAdlojo5IdlzQL/DqnYPzkj/G+xSWbHchuwYvDuNgZBFwBj +LukUBCxotNE7idZkKetEc20iGGY6FRlTHg9AhMg0PW5P2oGYSPAXmBFJhovskKry5BmuZzBaQLPX ++Cs9J0E8kAiSVjPEa0vi3ARcYG4phfHWOAGtAv4KkjSgTAohYzco/J2UjCiDGeJAON21xsHBKsYC +V3aWUAqXvQ0Ohz5BDQcdimj0mQtBkhwVZN1JVGyKUoPIMsow5SLhUxQxNWdIlMkrNA/hKyM6PASD +IOjeRJPtd0jXEoEybutZ2ywwHC2RGJg2khFFkvAjszB6hxUjerTeosOYNIyawNLF9aK8CV1cubiH +3SSVDWwMVCvBZoxzmGAJHkJQxhMilfjwOtv5mCqstA67kyU+wg/jHRQdk6uKvnL2hETC3FcYSecL +iUTorZCpyT0U6BePTHQT+5cjyBg5mEYo0FUR4T6PpzkQkpGXj6IStDwcDLcmW/MJQCmljsD7YIRk +br/jlgQGAbw7pkcQwAUGTQ8ZdBSCtLngkWGCCqnnaJkY/1WupIkS2APEcceFDfA5CrAQkxyIYiWw +CjP0GTIQy5VLTMsB3HlMKBlA128Z/dbBoFcocDwedNobPOZl/N36Kw0tie+AhaFLir+bg3IJH7YG +YUZblEbrJCZakTLaEnPL/FTxd+S87YuF2L7CCgE7TLuvMb0XiGEA9ACPR7mnzVwqTaxDLq6Wy5hE +fmTUE8q4AjsZ06Q7MI+VTe0zIBqvzNzazY9WgBw2I9u0Nbe56QWJ7jTLRfi0B4Eqm0W2gql9kq5R +A0WqBPTPkq+vY44kg4BOUFfAt2QWJWzSaWoSSR0s6Dc/WgFibEeuACftaAEpDoZLD1CHc11SBmxp +zQYvWcDmt4J2ZtcxKb7uZibzntT6zxXeD9aCVZlq2r/s94RWHJk3FpLxaywGWiGkxJiX2O/GV5Li +RQncQqDajZm+DgUDgrcwiDticXA/50gxHiR4PlUhefB0HkfuKdToYcAYJ391b2WA7Q== + Fz9t+22xe7owyId+YguJBb2En+avDjsD7Nv5adu3ct97N9EdAl2ToAgq0O1S9O+BrqIi8sumKpIf +fG992T096E7as+5pZeJRw0wjSrTAcPGF/UxJC6QJx5RFjO4tZXI38IOJb5HEp+8mpkp7kPuOD6rM +fIfxNY0ZrwNoi81+h/XL0l+qpSB6Kvyemf0X0UqTQ4SpRa5L9C3sMwFoR5HhF3ha2O8UK2O09MX2 +tG3Ev9+j1PxX7t2y9ALVIAdHWAqUpdSnXGRCxPZaZ7wfRC2k5NClh9m6R1NFy3c+96DBe+dTduq9 +t/JWzfkEntIsuQi+u2lUmmThDKyYoW722qhqOK9LU14Fg12efxWzNClPyevIKWHexxUMTBzvo4ox +J/am6x5N48oxb/De+TGv997KMeccZ5SignT9XNOxVVD6JaW65xH61uyssIkjUV4xTXhYLiqXZXCR +OT9QAQoeOrOviitexU9eLODGr9ki3gpQ8NDuJ6GA+UKbIv1FpxLeHyq3c43oy+K32YNJ0T05G/eu +potbowlfviCrM9NakKmZ4akxY3dSbhToWwkdb85krOLWTw+W7acwQXMRgxBa3FZTDKAnyu6r/tsR +f2vz14pv/GVqpqEOXo3SOYM18eunKaZaJbxz+29H/K3NXyu+8Zfpjs8+gRF+0MQo0t/K0dyOqK5U +Fr33gDmVdTz5bjyiRChA0W5bOM3J8JdPP/nukn7LzG/Ph1fw77PTfwI3YdbSqdPWweRqet562h11 +XxWT1rNJH3W7NT+2zK+H3eFwABvO5fmgZ5u+BD7fa8Wty1mn9WJ8NerfW2z7WQt6fLf8hIhWPlJu +rFqXBgc88WjYnfEDMJuejYDL56XWh+fdSW/cHbbarefFqDcYcnODo2/alp7ozv44hc+jV1cFN7aD +N4/f4MBnKFo+vfdZq2NZDsNUZvh7GLyFzuPohN3H71ioF/dQ8/8Ytzp0ImDWU+vBk5ODCUzxYUE4 +jgansBBPDo+hpT5B3p4YCp+PMevug9K2ZPiRonC20HecP/Q/83+v7ESr+7zh++P514P9WXp59B5f +rujlODbm3WAi0tty+l+tN1/3UFUtPJqJ80sPgSCxW6ytpvda/F8csXstm67rNz7hPkWo0n5IqpYs +eUOZWe5Mz3fFr9y8Jcpf44Wv+F9ciUkMuopZXrgmFXyTmNAisijOpWFGtJQZ72GIc/MbjObx7C1Q +9+kn9/5zNP51RN9wd777YPh2Ou2ePD7+rHXvOxhB3LbuPYAN/E3hGt07HF9c4tJ4NBgCyfQcTITB +qGWaGLCxTu7ZNl+gWn7vh8F0AJsyIa1Acjzr9l43QnLQnQ56JQyT8euiCQpJPw2fTeyjiDXUWIAN +49mLojeGrbFPv5qGlhutBkEDjvXce1icte63Pv2kdTfARRrC/Ra9vAV6Quve8+5kVknl4XjUvxrM +6hG4GhXS3ojjq3mD6DxnnrkJ9dni7G79LNBxZ36gTzrSoG9RrV2lYt0RUZr80rpsFJjBpnM8dn0i +Djvt8/tp8e2bYvSs32/A+ffNLty9oyyhUxdgs+ZoSEQqFeZSU62inGJWQmm68DTLEwH6acPg1fXy +aDXDDobFqH+NHCN8G6y9gFaPYiVR8My3vxW9K+yM+ZFQVIjMEQZ2d0FaXktP5kfYbKVWej47O5sW +s89oXJaiuPtkOLwio2s86RS/Ybkcs7vhBRjMxrsljK0jYGnr2zM0E6H5y8FsQ+l999nVbAomYRCj +fziYXg67b83Xz967iHeLy/xg6HsyMp2qLYh2d129n33tvUzt9y7tydMT51kWKIFbFea3cp7dVgob +7VBouYa71PHg4nLodymrfTRxmTefos9hQc7q9FSs76nKU0mZPEpIzDlAJ3uK8d+oIyMsKIn2l/v/ +e+5xLvVeA9hrAHsNYK8BNLX33mOS4l412KsGtVQDOo7wnrev6k2DPOytw/FkVEym17JpzGH0G8Xq +sREdgVoEhfVadzHF4mq6Yi3snZe33nn5LpzZu9PeWSJlu6FQ79fwTV7DpGFFcYo5UfBBqojc5vwB +zdoEj2vM/73BDnWzb4a3eK7eNKmlMZs63cFl9ab5qOjOzpH1dbdLTLtTGW+XL9Ztlx+vGMv3Ymwv +xm6lKnJTBFGGZ0f3gmipIDoYXhWt74pdiVHeBElEebyxjMxtRCKVaW4ztn0Sb6okXrfjY/AL2bwC +BlxQNq9WFZm84rqk2NY4pCKdYi52R6Yy06aEvIhySpDF49rC1IKkLChkVJxLoVcwStxWRmmt8aIS +mFNKpSKzUykGBqWojir296U5flrBISwyeRsZlGaa5k0nkXQPi/WDUqI8RXZURuVFU42O0BUMwtIk +t5JDWRrHmaBwV5SnfFQFGGZTgmAhSqVWcCa5Tra8F4/g9pZnrFVMidMqpruZ8eSRkfid2Mw4PFSv +k5TkPeZuyhWcfq8T8D0rLEDw+1NZbu0EUjrOcpwkcRRjYW67NM1+h6fiBR5hQlU1xsJJy6eO3ump +I9V+7jSeO0mSZbjzScwINxNHsWKgscwhzhtlvFJL50262/Pmg0ybvfG/j0M0sZsPzydjsJb/Mnh1 +PoT/z3bTfL5pCRWrDz+tcSEteWy5O2nxgXdKHYqcnwn5MiqmxtWkGPxwAC8mppjG5rDp6NWweFhc +wuycPht9VsJDv/3QnQx8dbDSYy+KYRdn2suxyUp6/Oz0ny9gun7ZCg+JtdZx9V54eAhr/VpWAMq8 +3BeClXDf+3406I37RYNcqRcNMglXnIGOZCJyWvXNdzbmIo/IEv67caweA/fzkscZe/npG7Kr2oq6 +H3pb3aISrmREPoQ0z+le8QTmICWEigTdKqhrWVfU/IdV0xDrRW02CT+g7WwEgM2UxNOM15JLU8JX +1yPP5/X/OZpdEhsSXi4Xw8EFQbBSIhYEt/Dx2XTWYOXcxi1E7reQhRVtV6O93mfFCo21zPR+o9hk +o5Dkqd9ds/29Wl4r650tTQLBck2yqlwTnr9ATMsKNpniRbuYrCvnimztJ9H7m0T2Jr9bOYfUdg4d +7ND4x9kHG/6P3gH0cDK+bB2fd/vjX3fT97NP4lrj4dr7cY3WX5rpq+2noOlym6m8cuqewGCqrqbF +8+Ojg+GVMYL4nvLT4ahfAvSmk17Z/3bKz1D9K7YuL7ummbM3z8eTf5kHnYLe705ef7ZEer/nQ7F+ +lKe94aTc0zfFZPZZiTmX3YFli2Yrj4bQJNa1vv3tsgty+aA4G0+K1g/FZHqDjI2bIdb/CtJ7X99o +L9KvR7ej6VRZ3QirGuGtpvRv1IqVjDt0o6TIMy07UkT5R1fcCMRlTolwUS5Nzk2ea7xIgpjQybTG +Yu1broHx0UvIZ1dIyOPh+FcsxLmjgc+9pLxJkvIGK79+tl+L7huie1fVV86rvjU13RuhxO4V1A3F +788A714NZ7+sLYLTKkVIaOiuJfZeSbFoLa2JQ5VFvx31g7qi6wuUPu8Oi9msMGQ8P63f77s/h0W7 +f/mMOPDTv5Bz5R8+/eR5r4pLd388H8wK/rnByoChhm3J460u3nX3xeOD1oui714Qabqalx7QSiSZ +UxZd878VQ5QY/ISWqaawjHfxuaaPJ0Uxci2VSHNTD78jpIrN4QtPKT5w+Lbr22dZrCkXNdW50EHl +Xd8eDwy59lLn5mAs3kZq7y0Q5fZPu6+K0azrHgEdDwhGYtMsT0nJk6mkQzORThN7ekZnlGot+BiN +MPnVBuvXIo9bj7+O89bB14nyjIzgaW3K4ycyoVfEku6IjqIop7KZOeKjiioR3olI0X9Kp7SYJXDr +8dcyA8yxDoYyhdYxDbrOUnNcOIqEmQacZB+7zpZRAuzx13lUQomPA6vp9EKEl3MDnkxpZY8dL6SV +C2KAR4m9FPAv4IxCnFIkdHYEr4PEYUlFbA5MAPokph81zNtcU06piGEAGKfCbmK/D75WuceZKBHb +XsUiyxKLzJ69yGP8D00vYqxDJpGNMfEx9mOPV0ZmhnkxpUTDzI9NKn3G1UtT7OgiRkEDA8Nawqjw +SJEwZ4tiM5vyKM7MlFf21HbKXAS+RSp3syiJkOIcO6k9yjTRwoQaAFdKcwSvFsH82440Kdp4+56d +PtJw06JUNC6ZAIxp4leVjvESNpzFCo/yUH9joNychVKpVDSlpCnoY3FR5xIcDu2HAwiixRPHSUpl +zfKMquTCSoy0MiON6SwJVTozhWBDfBHyT/k1k8JaVKYbMK3TzIyF4FF1ZJo5bjHFiaNSiABXliR0 +zCuPMupbolJFqTY4MVPTOXdCTi92TuOCFir1gq5h9SNAlJhZjH2T0i+3LFUx8UlJnbhAUpDqwydk +gu6IGLuTZZ75OawmIwRUQp2I4iRPzJkQusTFFe+O8B49oVI/vNw/DagTIjTh7pG0hxGEJUjrMlGS +kAo+2BTxmogNUl4TtCRQsGD02M9fJakrIFCEXW25mcVSUjJ54gUqJkaZQ1N2TUS4cGGAsH9+aJNc +KeoJsCCnpClcbpGh3BzqC2QVy0F7cs0tt5SFtkj8cgNZhRiJulRGNDdEhDWMaZLkOqJMtQ4MXxq5 ++SJUBsiQ9DwQLyIjDwplLUhzKVCWUq2/LLbiwbPS9NKJF8m8zKNwC0/pwiGsGpjwQvF7iBHKmEqG +c6q0hcQ0LFL4rVJmuD5hkSeSBD9eWGy2/ZTnjMZdBnnp6QTW4nzOaGUEXANxntDCBLSxmdhAEE0W +nZk6FtpASbQkOJP8UCjcP0Wc0ApOA2kam6EEbpEaAMw3SxDkXk4C3212vAPEpc0OLy6HzQ4HOQvw +popUHMCXCMILg5EROtjKE8LnZKAdH6lcrQ3Am2GHaVVrFbBUp0YaZnT9LJ3VMkpaJASdh3Oi352y +SWQ4WCj9gRNK0yLycjYWKicPVJKLzEj8GPY/mlN5llMmIdfbTowAQhoAkd9eNC51QTtWJj1mLWOz +OtIkIsxZEsFn2l20oOHnjSvmPdvuO6WNi/atQFjG5ipsPFIrIuIGsBYvlKeDpcQNOwtw17ITTcyN +Hk5dUgECVQWGzBwuBPSGzbAqjMYG3MFLvnHp8hZrVywstIDNObLCMNnzOElTIzxT2My0WaWpoHWr +Yf0TSyX3WPCii2xOpkFMPI5JUPNSs8Fx0uK/aBmdPFDyq4Pi5eYlRMev39Z4HluVHns26Z0P+jWe +tA39w6x0H5yb919dXLAdu7oLpuFSRI/Hw34xar2gtLq12MLWBuVyZ3aAhJzWpqV9alWJ//nnbFve +Fu8+nnTfUuG3568a2mJmD0chHOyMUhkZgJedEh4FuxmJCbBfTC4wanOi4gMLd5xvEidyoFzoPDHS +LTZH2kEMkKRQYE3RnPX/Zz0RtRSF4kz5HUKrOKU9SoG1QRs17M2UmQxSzXQv5l7Nf7B4U1q/aBak +gfRtXAvXKQL4LwpGL75ApUhoR0DJlKvwQ5Qqq1Jw5+Y/MG5JQpesLPjXCwQJ8pvoTQ== + 0sxIVNiJlNnI84y0Ke3+X97LVDy/Q4I1SeJZgi2ojV4Fo2/sl5Q7Nv+BkaZm2yVlJfUiC3YrTT0U +qO6l9EHF1sLO3P95skQJKRW4A8C/3qbKEpWbSxxETPMPdPdUWyuLezT/wakXEZlWOLVlaPxtVseK +rEnSfRIcavjXr74fi9PW4Xg4nrQeT8ZXl34d2okOsj7hU51sWwUafl5S/3TsVHwZaJawfUQpOz9o +2ZA+ZZWAlLUMaZC6CWS0NdIH0kBdA4Jj2o+AYTq2LpKlVrRSFVa06YkZ3BwHWVosAu/nIe20ZAwZ +LBLpisOuwIpNTTArlime1zR6qbncjw9vlnsiaQ6nfrFJkAiKpptMkXXYCZ1qqzXyOdBAv2X+ZLmf +eILxPT/wjjfnXmt2JdDRYDor+SDn0jkqwkOfhjVmPq04OBcE3T8NbxhadByat294uZGIwksbEdW/ +YdeuZrPxyN5oXHHJ8eLdjngX2uX3l3MPIhOAAR7wvDsqhieHw/G0ME2fccvurHg0KIZ91/TRYHiB +f18cEweOiy5oBMSqSdEfzFqH3QldM3Z8Pr68xBR5ABDb/gKMNHf19VuPum/GE+O3vEu0f7ZwfaCl +eQX/7Gg/BEovitEMutqlaxoZgL5l/Dp3ZeO9n54efTfuF0t+vt+6+9vFcAQN2t3ZbDI4hRnCdy7e +ezCBLf5DormmtwTtQH0b9ifFyLbisAz/jP/M/N2Rd/8wmp686U6m94MS42HbN130sNrG+MN0SUNM +/rTtbG+m5a87z6rTwagPZIs6nAKWHhez74gnNdgVNv/iRhA7Go+Wdb1E6HDce130axHJTa9zUrw7 +I8RqRtQb6wFe31prZdQZ3a0PfnOh8OWb+mIB296MSY50wjY6G1/cAPH3Xqfol9MuxmRxDwVBU3+m +foh1c4xXcNys/tyupTw9+/UGzO8dkORTvAv71ox9G0w9MONtws1Son8d9OnI9PpRty1vhOyuSdx5 +YcuhrKeOm94I8jKVy7XE/VZvrd4QkiTGOtbS9LYWTW9vCE0uGW4pPadjMLcvjoqz2bPJAKzZWuQt +PnRjNAkSkcfjq0mvOMA82JuhSsAOdyP6cVHMun3Qsa6hM/k7d+Z3fesoqTXngtYEcseNDoZF0ce5 ++EOAnIsJHE7Gl+iPMrnWVbv+/JrMRCJa9A/hfz4ejGZE0N0XV8NiUprwvuABFWF4ygefgLgHk9np +uDvp4zXs8zUbAjtaMBXPH7xgUBS12viPf/+LYvhy/MK82vTl+Xg6wG7Tz9J1p8FDYl5EPJlyn62/ +8ruq2cBtiIVM7M9Pi/7g6qL1opiOh1c2k9CN6YMnQrScUwy016tLKmYxK0bFpPV8UmBdlJAn/ijZ +gyd562kxPW+96E5nxWTwL8pGDN5jH4mj0iPPrmaXV7N1D4mEk2orOnjUHb266r4qWs/Hl1eXPHHm +J0vsdvjLbr/vZ4Xh6AVVci/Dppfj2TysOxywmExZoPcvBx0L4272xjYb2AzEk9aDq9nYEVnMYyWq +eNG0Xo/GvddjYMorE5xY1XYAjOrOitYpJuNyWZFS67x12b2EwZsOLq6G3YCn0rE0b80m3dH0sgsi +o/cWXjvoQ3PXTQXbbRY07vJ66VEIRcLLr4JFsqRdXWSvKM+zZuOJcwJppWK1vKkIO7m2bdiHtY19 +H4SOs9g15Vl62B296U6PPT9FaShpUU3eFC30x7e+7Q9m3dPBcDB764cyEJ4vx5dzsjP48QVqneHP +LkX+8XB82h2+KC6vhlM/AzKdovzMF+Xn82IyvSxIED+G2XBiMY8G03OYZNRwTq4uPOEl8JNRv/jt +0WAy5WfolZTRVOu9z4fdEWgIqMeEb05zBVhioddiwR2HkBwWw+G3v838zlS/Jw7HYkfqsuC46I1H +/fDNad6IBzD4JQakoubwmS23YvTq98LRP9eJcDJHrTO3V1zytMZg0CVGY1huUgS01rh5yhcGLvVL +svTaCYnY9hvAAosT5nx31Ktad+EzveHgElYzOrV+g9X8ChbIdM3QOm7QiQtarsczkMNrHns0HI8n +K59rq5I2sYQvtrYVoWu2Kh1Hqzuw6Hgo2wLHxfAv3RlINsBeTJ48nIa6xbK2R+Ned4hKQ6l12OIl ++srw1Qu7iJAnx7ANU7D+6bjvDMAl9L0M7an1k/oYOlYtSs0qr1JT53GAwjgLtooVE+aF2yhUlmdi +RcsD/1r0TaSrppPHKr0yNt/yL2NQO8ajv4R+CaGWtcbVdggWGbdcjpd68Oyy2/P7VRLslVZ1RNXy +v666ONlaR8WbYrhmQYLuMxyMitaUzgbyWrwrkk7UiQJt9fWDJ4+uhkPeaO2pKvi1QmfSAf7uaDZo +QXe6jDpeSiCy4rhaY6vq8Qz28LVMI2O8zLOlQ0EL9lG3V/gac6vnBD3wONShlvaDmpY7sna2BTNT +ZSspLInrlfLooFozq2wbrqHVhJXenyxv/MOg+BVmE9iFs2CvqK8YoPhkQ40XopbOYKliTTg8y4ce +W86PfKKydBlmGp8Q9ZpVay8st8L4Xng8cG4jWDg+6CX0Eey3bGc+eVhlFQrZAvvnMVdywlOQxkxc +aRiap45wTQF6eor040XLsPQu0fr2+XHzl5nH6rytsR263uAmSlcZ2WUxhsYkyq8HKL+8xRfKUsJ4 +iFrNodVqXpS0moW2z6z4Oi4J3GhZs5deyoV6GLUxNu69H4wCdjCvgJXaPptXDet4J3Ck6nMLW69j +l8FZk1+m8XqGldst4ZhpVJNlFuM8z0Ro6o/GXt9uDUak1aInqVK/W7Gs73mn8L1/jk87hLA7HLLx +yy/3Y7PwBCyECSyIeUKWYV7TbPp6cHkKjAmcNJXtJqBeTKYFkjRZ0xTs96HXfO8u+v7mH2DiQ7Lu +OyseOf7X8emT0dm4Faiy6zi+rHeng9lFF42osgByUitsf/nq4nXnFNXW8dlZx3j8eUNd2v6iO3k9 +XWhfxf8y+qtpAXKPlGS/bK0bsvVjcXrvh0G/GN97OgbrovhlNVdxCApiT9nPutCF6WzY6Zt30IRx +g7tm2PA5+0Dgoq7z0GX/An4ejur367JfH73JFPGPVM2Cy8uJbbdqbKCR7QDrRbnqyMpRh6Zh2DVL +RCdb1rAUwcw6ybJ2gwtY550hqCp1287GvDWqTC/vgGk8CXsRx+twl6byXZiUIHv7rdO3rYeTwRu6 +XnPFuCCaUWkfWXxVb56Jy1uVOLgC2TjUw1agm2+3MBWoGTly1wi+fjEdvBpVuYIrhfOpjc2txEkt +x2eD4by5XC3vp0a81Ze95YFZpH046Vx498CyJr3xCEvLoWN/FUHY1G2jp+acldm7ZWXzSb8D9jUW +AyhL6sqWZ6BnuEp85KKtbHZpA0ArJwa9+FVn9WS0jThTTkRLm03RHeKwrW34Zg2l097lsPd2hfAy +jXqj6cppDY1mg2EptrGEShiyYfeyBjtsw1UE0KZXjNAxtVJIY7OpK4Kydi5TeyPVg8VS5yFYBTMs +q8OdwWvHlu3tsCOg2jknqFZs7Osa9Sbjy3VtUOMbgPazrt0kKFay9r3o9zvtTqarhrSsnwR7UY3W +s5CudY3D3aiGYhX0pEZr35MajcOeVK2ss9Gs0x+ukYim0eXkbDxaKQ6x3fTq1K3SuGq0pkBuybNX +1eR0gHrwqkGfdkbFq26QALCkFRo2oBxP18whbAj70mgNtqFAfF1HYLXkg4bT8y4YFsUqbmGrYoau +QXfLRZA7MNdyrllatRv8dtkpxzGoe1XNJgvmAnlHqpq+qrIsqhraLTNwbFaNrW9ofLZrmg4Hq6QJ +tEAPbbdssS9pOb7srZI41GK6avipRf9qtQdihXCG59coJ2AxTmtsJdTs7GrUWzVnTCPr/nDzZs3+ +QQ91RyOXzlBttlOztRZH7yLUtO5+3znutMx5SjCm+62/3z3+8dnzv3/WeiPX2H4XoAuGGmOVEgqN +0HgrhRurGnG0sXfxdpWHIGg5np0XpRQNZ8Q/4PatckTKuXaUd/w9H/xWDJ8XE6zxNu8EOv7h8cvi +4jLwMXDn4ZdvL06LvnH8LP74CGQWBs3ChRxgxVyS/wSDtvKFv82ejczFRSUuWKxBfCz2vzyfFL1B +IEoT/xMdT3xZkaWIj706q+jCT06tlwG5I5gGi2sZfnn48mEFEqqdRyHDy+6CL8zScgxbUjGblXx6 +LvI055q9xEOL8+9Z8OSfj3/9y6Bf11d29+fgMqlWULzuOhweOB+fP3x0wtkhwaswRQQQH3YvTaLI +oFi5fTQIkFdvLNyVp+PRuEdnXB+Ofx2ZQyCLDvJqBBIRmFQvjByPZs/N0kcuPB8PByvNBHg+wefZ +7bRigfOrXk66l5frWhJVFFk+8BrmqsFwvtcabU2q42Clw5LbPoIxARGKkSgWqy/PYdxb3UnRAjnV +sh6elp3v09av58WoNe2+wQnWHbXCiYhsbXWnCDYVKOENLl+s0/p+Sijh3zKyt+OrFsiqUWs8ahVm +htGrDbpXWNt2UHrRFy14mXt0BNS2ZmNE0StaA3I+d1vD7lvMY4OxgCE2qX3Tq945du/J6CG5ITwa +87YR7HhX0LvxmX/9YNq6Gr3GapGd1cuLhx9Q9yaDy3X2c2msXqxRqf2EMZrng8kqq5VbvyheYarp +Svul1I2D0IW1vvnLlXaZkyJgmj1ZbZpx05eTwUXY41UL+njWHfXxDHfd3h55i0gqvW5VvoSxL8fe +1wm3ijB8lbESDiXMylK63aqhx6ItXvb958Alc4mVgtNsVLhlvcA1UIsB+Kp69NNIwKom5eXlnKNk +ucgxPHsZ5H3WYQByGfSZl+dXF6ej7mDIs2QdKYfeXAvYtqSDK1M1Vk5z4+nH6RuoLGuUY2ahraH6 +9rvacYJA2oC47Nbb1eefKO1+NV9oNlKsgV1yES7xCM2v7B+L2pIOFmH1fF9Bm93Zn4x6sFXME7jk +wfXJP5U+Ebcvk2v8EagmIJR/HU9eH6wLaS2ZmzZJabUboEHWeqX1vYS9dVWppbpYzfGh1x6Ssb4w +PM24HEjzZCWl2FvfzycYqnlwOnYuniCFY57PdQ4UNDfZ54Qg5k5SGkGwetduTtUSbfWIl/ePugNe +M1V1M9nxpA9a4eBs4MzQZlOgvtJUZll5oUm5xHCp4NrC7ElqLZMlw1XD8nrQm4xPu7Oj7ttispk0 +8jraakLnBMICpY1GeMHM8r4OaGTm+6GzRtnkPRiwufvg+PDJk0w9LPB19GvyH8/+8PPnX/349R/v +d3/64q/xH561D76ZPL44//LV6N//+ujfv7j7x8NBtzP9vf7+L9/q3335zfeP//w0+Y8vj/7+x6ff +TK566aNv5dPsjkiS30XR9OE/H776Ivr9N/f/0fnTN199cTn9Zvqf8h685pv7R/8+4VZ/nR28+st/ +HX3zVVIcHw6+/nPvYafzx1cL7zrq/w1emD58dOfL9L8fzx7+85eD5L/bXzy4GB9NHw== + PDmenX/+Z/27q0cPk9//ePDP4R9/hNc8PIv+elqJ7fdpfpb+8F8///3By8POD8vfGrb78pdvvnr9 +6Jdvvpx2Lj5/+MWdq0d3H/fP4DXEr0f/A4Py8OyXH9OD4TfDn748OzifHZ6n/y1KHPmfPzzsiaP/ +/ear//jjjwYRdHp6+I9X/xjDpz/878Mn/Sf/ftDO/vn7B8ft341MJ37q9q/gNfk/737e+7an/uvu +4Xlycv+rB3fiP3x+8N0X//P5N4d//P7RYXH1pz//8Nffnd/v9bqv8dPg82/Pjs7Nq0V0r5tOBr// +ny8H//hr/2B45z/+2J58/verB0fHf/hfJOCzb+7/9TyG1+j7P/zyzYNR748Xn3/99P699OLvXw/S +9N70LH4w6T0Rn7/+UjiUvYd/nf4AnEv/WKQ/xlH/y8HhvS4Msnj69d32F8XBMH1+YWj429Gdbw6f +fPW7H7/9IldYQ//hk5/17/6cHo7/8flXP/R//lKe/u4Xwvvn0R0g6c/6T7/DYflZ/6j/a4Ss+vPB +6890207QH/pHkfjld08f3ut+9YdH//75f0/wNRp/+AdhoSbwmuj0/3uS0JfP//zoK/vpqx////a+ +azmZZknw/o/gHYRAeNOOxgjhnQRyGAmQBEgCIQkJz5ydm7nY2DfaN9hn2QfZqmrfXe0ATcRsTJz4 +vyPaZFZlZWWl7SzXueeLofKIg0b1qEvAwV0imMmUQ1QpO73gAT1epM/H3zcDtJriiAG820JMQAOe +KlyJQ3iRhkD6LprwqQmDrsWchdIQkRuoh1mG7bPf7/l26TtY+ojWV+XXV6+7wL517pN3Z91O/rZY +uCt9tL5WudVLagrQFJhee8gRtM+O++UhGXwoMN38baX0/Tgsfn2z0fOP37NppfgRIAENM6N4vDle +SAgTrdVvPX/bCNQrJf+4zlFHoDW3BSALbJeR+2D24XXFTSnDJl5z5+3tab59td1pJ6cirowSwmJ0 +104BVAvsoNsiTLQt98dnU2qUzpaIynOORnyQHqUrJcAjgVCwsEgO1OulJK58cYXF4Ngn+7nZITrB +2chJddWo5odXJOKbdHB5Pqr4PuqRPJFu9ym/e5DmRqKkCLtrJicVn2fpL36yzVk52IhUJH4F+6C3 +QMKmVR5DRs2B3fXrAZNz+YvTz/Imfv7eaebjfepRvQ53tZ8HBfDTajkcekviliU5m9SLAE2+fT0O +AmGTSZYKjd4MN170qOy5ai/+ATZPmSKoKnOtZZ/tXcV/93NeKcX6VDBTHcHPqUlTA/N6/6iUS7F4 +gQ3fPiDZEyFrDyGEtRQdLQOF7+34t/Azf1jk259dN4BRD4oAluXQ4oaqeMLxp3zz49MLXnvxFNhg +45MXnf7Sh7fGgvEuPjmRWH7o1gSJDjDUX9p0JTe96EJ5Pyq9MZ+P+c7Z+0b5nCffbD/9JL5/wmkk +3aRzAaKRHlhcEenCzLf8qqSrpE8m6vvNwKucLOBskYluknjblX0Xq0fp5FHdhQzt28anYICTluaB +xCh4frn5APL73RUrkLufp3xrdFXk7ybzo1y6VoyAR0YPQB40PAWyvxvmW7s2I91FD0OZBq785tbv +KQ+3ZPKNGu2ls7fFebz5MfWRb4NOnvY43WXI2kWyWmzk4F8Z4qpKXhCTt1SWDPmKWfFaRnoDoJEe +RZfhzwKUi0X0JvrJthrUPbx7wb0uYCjCawUOWj4drsRj4VKTGvaXZfhIGj0Mf5YAGnGABfjUjQSI +QwMRKmHkxOFnxDfO0SNwOHdoTOKE82gkAA2aKTdnOKz4Xe26Da+dI2gSGgRDTSVh0Gqs6KcIryWg +EV9HL53DB9BEshI10fNogBwh59Pze5EILURSEU1atXyQBZSrhVnfPRZDtRICGu4lSC8JOJoIIpWS +IhdoXtJPBE1EXcUMIoefTcZ8WbhBo79EkBxW5U+ON+BBoMceurwBH26I85L4BUsvdAMytJZeF9x0 +0Q4SKHIhzRo+fIujq2rLijS84ImmmikiS0oJI6scTlFEzbG2Cit6WNp9kKGlJVMsbUZiXvQ8JEYe +s2XOxSHeiWKEY1V0Q5ACCK59chszDaI6IiSCLHAaThqiyYl71B4zcssi7iVedKJRNtkE6b9Ff3FL +ACeChg//6St1wkC+/VCfV3LeSRvYAR+U/PxI5ufg9Jw2KqPrXqriDETgsQanlhA0gLAb6DOlWe7R +1ZkWvwbDXPl9tvJwZ5tMx4ht7/TNHbkuEnxE5g601pQWDxpqaRr2Zzmd8O7S/ywdegp7jHDlHry+ +ZPFz1+yX6vVVQT6lwnCSb85Lt7nWYP0Glduf3C+pRBNEpkXqhvgZpsOjykJ9N3rqfwKG6sOy/B5q +RwtsiArLTEuy8DYtTQLlmqRyIQXqapeUaMNrZ8+JW5l1J9csgP0KDeDkT2XxwaltGgBdBrwWXkSv +m895ODCoQAFdPtY/xHixYLkgBepA48WC5SKogyKjhuHkOMNaYSEPZpIFk/iJrGv8OnTOZrza1L0q +IA1XIpUE6v87wwPZ24LFVXsu1QusF2DwvxXuc0+Bwv3ZyxapylBqxDGkkpsqiPszbD1SuvyOv0qU +g4YHJB6/BPl5Lf7w02jnbzt1wPZgm3I8Ko1Ez+bgSJph2YC4D6qFH3b6hGwDgEYyD7RDndyWqrOz +Cdhn92no/ngHf4W21eXpWzIZPGdulHAbOjZM2ssLm2q+9ZMLgtenK/K9mb2lch1nkjdn24EJoNeM +MXEOUP2Zq/j57EyBEQ+HAgu8RMCEI1AKFGbXQWCo3H0w4kZJQbthUJhRF07phsjzRGr8+0PApbpS +WNJsoZIuP0dEKPHK4CXgqpTnO7g9qbPkb4Ljr5A7+pSIvzeuCvd3OXB69H5v+KHuemf5+5vWAzTJ +hRuP3zRP5oWHiM92b3dEYxn5qW5uJ2sVamF7qrAfGzVAI3JmJbdef3aY1PVjFmE4J7LnI2gAFomP +ZPFSBvx2WagVmF2BIEOdjVOxDk+DfPK8HhZvtJlV5CvPWWvlUG59elWrBPwhBoiuR2AAhcZzcFw1 +K5Wh3/kJ50rn0m+Dee7xPuhJfQZbX+A0TH4jdpfJao2roxYuXa0DI57TtHzjLGe4R8WdrIBmbRtT +bN6DjkTkszHbybTkpzTexrKRwG0MrMXFR/Fr88Ui90P4qUlclVdFFUgL3gAZ3HsnOMyFbUwDpab+ +gx5JkQkntAgq/t7dNl/vkWNuLS/qN+PS+DcZEljQdwrM+SxRKtZc3OEUXjgzEc5hwHnbHi9iqcnI +M+FJVbuLFn4iTRIAbc2RLgLQcDhvOomX8nBw9gSGP3XmVoWBTzzCPkXuAzKYdZ8BYiQv4Rk0Lb9F ++19KzQbJ7ydk4vNHeGMKFaj44/WypTzPuUfjabo8KQ9u34ZAYzmHsufDX34PEs95xpe8B6LwMcHp +Bzx+2pVLZzue0uXv11Mh9tCN5O8Dd9N8sx2Ehkf1rPoSL8zI8VquwHAHzEW0dPnUCEANpIkeAbI6 +3cINP9H2uFuVocvTK30AkhV+Eu5Q6crn9yGVR5ICSL2Yns0AZyRPzz/crU8MVgYcq81NORhgP+Tn +HVyv5bAwyD24t1sRdQMs89TJbhuVJmToWDsSVtzzOonLp2qahyEeucive/398ZH68t5fA10vlK+U +erUAbnKK52JBgOb8ZfH0bPTUQyB+835+q3rkfDLwz5DfLXUzPf8qhxZ9EojJGJlvxSov1d9twAuf ++xaFjYaXXBtwtlx/cupNlu1WizfFh6yKQfjYx9r5BFTqVROsdG4lUxt5UEQEUPgRtnBA8RPMOkTA +Rq2z7EVlVUuXfhoxSUHmF3LgcpY+WqNF8evUHQP8zdzm55nLBY6R0NpA3rtdvC+T1x9RMn+bKtdz +54WlXC3nx5b25dbh5A5K6Fw+/jK+KX0kR9Fyf7L1qEia/F5720AXGPTyi8/bACSakmVELQr9fJaG +D4aVvZSxSuaCpXFckpzly+18PNlE+uSw9HG/gYc0JzX48dZclWL+ZVop5qbNmvuCvMwno7M8/pF8 +4Dv30L58raRLW9lwgFx2neZSj5NpLrFcD5ErE4MG2HwBtF6Al+4+rc6V0/+UUNLVn+vfYCZercHz +ZtU/74mrRQOpWd5AF/894JFvT+7ho72TAc+wV7tSpDkO51I33zOZ5g7+abOnlXmRD92I+3aVRyZu +4Rech4ol8P5EPyeDkUDuCSOnSO12V6oNNptS6K1STvvdZx3Akb1V4fc2E9Myzf0pOM5mfaRAnZM+ +IPSYM6DDtaOlj/Ya2IPEx69sK15uXkbVs4qznlu7BtvSx2IdwfBtEpyjUz8MDnUrxY8sLW0jwb6B +GkMcum851avi7n5/EVRs9lmqZs4mQO9Ispzn9v2hvxHhnld8l+NHaIA+Q2nRLU3SA2hI7IKSjSiG +ieiAz5+Irc8fgbJU/c7fkgUaWOPZWS6dWbrkm1LQjsBf46iMkMQm1GczHaacj4Xr91BkkBg06Ck0 +1EGFamMPqdNKY15+j80B6nDEj6GXNx9vXVfAOvTu8ov8h08HDaB+PaEHwweUKmKaug7S4Gxte5yW +tqyC+/m10dsAot+e2ILt3J7nCSpbuQesNSLK7711rJSrLVfCw6EFVPRYjpuqvdwPCj8KKkfw4qp/ +JSMQOIZeCj/xnBtZGnxAlIWRiXhgB0VHMxX+SK/Fucp9Fdc1P1H4+VmOVHa+jNNkR/lb+Y1Ie+X6 +PQ+S5W7kf14nMKbhgsEeIt9cNLal0O1qLChQs504bMV5g9B4yu+n7AuwdJzrSjnRrKk1kFWt2UDm +9PnHr8cDrPtvVlKRMFrBNZDf5QhacIjGQNE4fywHb71BQMNB2Oi5zDXYj3U3QF2J4FADNCL2x1z6 +p+KXK+hqaC39DQj38qp4U06O0AETzGz6SUlQQtEJZ3Xhu/f3oAVzE/1ypdK8ris8VRn+RFkgMNmf +XLw7LecT1c0WBtLDFd9V+KFIdn4355OU5xfMuumXo86sfpF6iSR09n2iFJ27fOJtOZWdEEj89u9f +a0AJXBDnH7vJWi2IF4FSVPaGGGNGnAO9HCsy2QLKeKtSyU0Bs7d27bE5G7PIMkaUgFbCNeChRwoo +KenrfCuUA2szDcwVaBCPlt93p8N8Ihw5haoiq2IycD7NJwVmNh6zD52Xh0Q8W6wVP5/Gp9AEO82l +7+lBqV5Pn4pxZ/VrUE+rvHrKufOXDtBI4/dBggqt3oHQ78/AMfyxzDd/Yo8KkfzazW383dNS/YoG +3O8qLHHSVUgCuOvH28Md/F4ueLR4UZrG2NN0aPf8xWZWgTIwkwKrSrryzjOlKKtEMSWIJ16mbXib +484TvMjFT0soGQGM5KUYb40XaaiqL92DsOQRTY3H7+0U9Rq4K/yEyXa12+/OwdpsC5L/j3vkZvC2 +q4xedp8wg8OLjKfwPNRm0GLIF5xAXam4FfmIhh/B6nd8+fnbdCPKOQXIAfWLTkVZ3g== + hgLuA9BrBztAw94ZEHH3O+kuz2mP+XYn3pbIl5zlvhtg8r+PCjcnpPToEZxZS2KTJ9I3S5kjFdGr +4E23S4Gv6Hs61KsX8onQJYTn+YKzQbtW1JP0qC8sEK/6lYGOVXjP39ZrMO467UFKUIox3Z+Cs2Ly +dP76uPiGJm60/H1WKScXX+VB97MDZE+4h3l+xHZun755YdOoPOsCr/i354vyO+uPFa79/q/4/PI+ +iAx2tRv7HugC1xUv4Gp3vxzuJaYF5pEOy1jgaxCa5tulTYBd1V+zF8CC9gHrK00qEYpQAjB+c/6W +ml2UXr56Lhm7iYCQ+Q/OoF89GPR98TM3Dpcuf4qPKjWAoO6fXRVfvZCAa3PXDy1kJFB40FlRRnxB +GzVWfmuXY5KYVKDuQ2WiNkaebsGZ0k8i9wuypGlirPTPpMqvo+9Qfp513lVGvhcKborn0pXzg5AG +KAAfDs4vb2tNNtXtvIHZTCq87ggYjpcbVwR0EEP9zw8wPMv9/GzK9WIpaymWHAbL18Ek2H3BENhL +7U35PVMDoDqepTvZKT+5k9NHaEmDsdWgTz8yyLc/37dwlP+RcYhVhBT8CNDJLao92ZyU0AfclZVz +mrKzuVgxF48rv6clByWrBPBJhT1cIh/8OMCCe079bTE5CHlTMLPitv/7v//n//lfxgmHX/PZz2Yb +2byvP9Yrg/R8/rl32RclhYrLy/nsBHbvk5dayr6i1Xr9t8n17mf7tfyZ5FWfnjrHjBpabHxrRVWr +P4iN6wEISySFm45/UPKl/BI+9zGYiY3iwezDW5SIBq/DweznloZ/UUz6PkWLN+7Fv9CNczrb3haA +7lWd1VzNi1doPWXEu1Twosl+Ov107cIZjnqh+8QZzMzSTv9NP+kMfX6Be6OPiDO4S7WcoetuyRkm +rikietHzIfwxZ9F/z2yoDTjuY6UZk70dZehCgk6AHf3bR75EtPOku0RtOIF5Qut15uItH1reXOXq +yU0mUUs/RiqLPvNQXj/3iVK/0mtXLvIX7yTQzeY8Gtp9HyyGA02AsMHqTZibUoRuJN2QaJqnGpv1 ++nzTBlhCl0SUaXETkca2SVS2D9RgMfMQYw+JUN9KcNcvxCYNgCd2wUzV6UFT59amNItEN4kqk1id +f4Of1R/weq+kxPq8frl+vsdjrcYHsdTlIILFOnDfQItGhVjCyn7Vq2d4rGmnb70hz9Z4rHfkM3NK +pQISVphlKyLeeEPXYR2ssU/fq7dXxmNl/M/BNDXFz/W0MoBBO1dn+dPATZeoFOo5Haysyz1f+y90 +sPYGROXjpiVh5XKGRcRVZ9pDXg3bWKzVGtXWpTDVz7RHCCvgyLeycl1hMu/6eZdpQMR+7dL6evTT +D+kHWJmFhqEaRIHHeuf1qrDGYr/DpYRVxtAc4uH65XPe1sGae2XjFTeJxTrIjpp6WKEzyE37zp/x +0007Xzauz0kTj/W+6M+s3L8NHNbg+U8qI2GFa6NkqEC2n7vFY2V6PaKSJG6wWE8r07i7+Uvd4rBC +h0Pl5aWiM13WdTabXxf1sL4S1dDoAY+1SuS9E1+8h7ACNGoib12hLI+1F/apiJy9YS54CpefZxUF +1n6aaMTDJMQaUGEFaDantcmCbb6GKYA4vlSzceOp/6qDlXXFZ+PKQA9ribgOvCQRVsRpqulerlK5 +7/VNE4u1de6ldbHWJy2awGFFBwHzFCZaQ/8pbrqb03ptcvPU9/uwWB+886ku1tbn/egNYYV5Qprp +PlWJh/oyjcfaoM86lVz6Ao91eXWKwwolNET8MKyebnWI/HRLPGbrJTzW60x5OLh/ecFifbmdXSKs +6LzRTve7FxtXdLA+J4iXzU8Yj/Xme/l7m0zQKqzItQURDy/Dc10ir89aQacO1l6HKH/9XmGxJm7C +p87cSxjKNIA4tVJvnt0wPuSxvtF+1ebx9xuvAYSV8mZ8NeVcG8QokMpDrCEJK0QDEQO43yvhDLhY +q7FuFp4LHus2G1TN1fn8+uTnsBZ65KVSKIbWm04Gemkg4ohWQl2G0XQB1uJWIxdrpyyHNUvWwyqh +GFoyN9zJQ7tTxTrCitDwiN3r9evbHGIlVFjX6/xkIbDxlVOFdRP7TvEnTzZ1H1FR+HQxGbU5zQYc +tJPXIascVq3jGSxSund79+Tvg97dT6I2OttJd7UHARDEJY/O62AdPMGiMLDvSVx1l02QwzZ/dzNL +aLcnO/887eIe4CTk3WXqWfduggo0R/p3P18HXolo2gfylKf/rnu3EZxnKf27b7cf59JdNdFY1+3p ++1tN5/VEzVNLdzbc3Q/vKql6txP8EtTWD/I0pSVa5+2qNcc9wEm8UnC21r37ePYWderffS6lLkSi +YR4YnQ3ibt2739u7ZU337uyBKtxLd7VE+51VMgO918GY7s9junevKCbTNSDa2fv8rdXQe93j9Fw+ +B3TvlvPXbxPdu1dU9pQ0IFreSbn9KZ27sRpRvggIs075zlV3g+37TZa/W4ykNduz1h5VA3npAWbD +hJpKG61IjL1PRV4Ujc5+4N0lb7JWhjFOChUWmxvuL6VMo7ZuaIUWneGrZA9Yod9t+E8EXqs4Q6Vm +Ef7ziEw80b7jpAWP8LVZEKTg+pTyXtyFeekO7CClnpZx0V7w5tUv2iPQFJLtjOh1Yu4Fxm53B+Ts +qQcg/EiLCF3Rr4s3PxBUp+X1bhQJK2Tv+hQmV4mIkSmkg5V1QTvoCY+V6fV1sYIz5ZtU62ny6SJT +SBcrPAPf9bCO5ViZFrSkZYgTN4WWDOvY43FJWJFtIGKlVRSGtoE41+qPAqu/x5m4csQKIl9QuliR +baCDFZiMwDYYSFjhbBTTfdHFCoi8YfSxQttAFytAA82DT/x0086IEdaGVxcrUjQkrEgKKBBDRaOt +WNpJUsCP/uIXw1/sj3+tPDfY/c4VUkDnUda1GpS7t6bPxT557uPlRgHM+jkviE7NJh75fiGBmjJn +TqayW/NyxtPKqfY+jL+FpH8yS9+4zdv0UDzxfoHM0p9eiiB9CEYmWXN/o3FkktWnEhBir2WImpbE +FI8/Uz7j/wldL3gMSDsWMEhaJxgRmN/FkntK5awCMrAQ/ZyUzsR/mnJtmvex3YoPlyCaqnzCo6us +4IECg+7cgSseqOvuAgKBOK2eF86yOdx5lDQUXXRgxMRV7OwM/QPZ8lFlRuGGNUteqoYlH9Nw5wUc +fB2ivFlC5ndTORAR1aHofNkV6maEh//ww+eMfswMvU7dGcK1ESeJ/tFdRmENW6fma+gSZxgQOA03 +SajXdgzoZX0NF4hLecPDIr0MoJGBwndFFxTiNFO2F+h1HrbFXxJzKQ9pjr+qzyv71MeSHqg8fYGh +D6Y+Vegnr4xJj4imQy+lFPJrpdCgrJRCtK4UQjLNcEXKz5drOQ3FQSto6OGkEJ58A1R6KRBZZ0Sh +coj7hycfOceTrxd26gpx3e2JHHjYyfVO7U9Ocayh+dHZh/a1GbmrdQ8fisCOpBRUzUtxrMnmNbmL +eHgW0MjUMkDzsLA1JaywARwELL6ujL7ifpSz+8jvAaPrlnSWKrQkX93eGhoEHyPYkzaE/sH9uQhe +COwjZ2jkAcJDI61Cw4FCpJeHiQLaDfhasboBjXcfPD1fT7s7wwV1kaEOGYL/PAVlIQ4NbwAx6SvX +cUsKiSZfVfgPWFXJg61lEDBDUSRqGeT2XhyTbGDcbLZV7Ngy1beN3jRzxGTbiWq0M+2yyIzC66B2 +WcZVM+3MqhSaJaAfWveksqBNSg8DHedpq3tMQcPDxiJXIVlq9pUqrBQYV5VSG0Ov64V0FhuMaZu9 +0j89b5v8iKzoemBM+oqesHzc6WlhGZNuY23D1CJQLOP8zFDbsLGG1btfCRTP0AdAa80tDAxuT0vQ +lAeM3YGJwWIeWs/YyLEzTbm2dzjRhutjEk0p3WwObKny2Yzia411u81s9tSclfEbMKIazmDU03Wx +ZzZV6H46zWSaTPvGb89t9vR427PQXbntmdNcZFezmjUYcWlI1EEGu30C9U49Vm0TSetUEyizEU9q +U38DXmOsqcQDft+YL1VmY2wFqkYiMLR2MCbywNJI1FrnfmQxEQCykfCWdFDnzJrWoM/7yYbpzsU2 +lflLUtYQ9bJ5i8hc4eCvS8j7ZRsYdNwfQEV0Gmk2WEmis1EujXURbt9YHpZrT1GgEp1w771sz4xP +aqui4FISBZb9Avoz9FqgOu9VNyW8QoEw93yo1XyZd/D7EoYGH4/BWqUtWX7ZVCUZocy2w1pGOqY7 +2AKftFUuFYJeRvSyvtl1zSLOjAL0srnZFfQSNzt6g3YnZ1HlTr9Cs1Fudqxxbu6LAsx7atGZYuR0 +uFI7ctXDMXLkqp0pv1dK/V7HdDZ35ILJyTaUwAK2PSpXMNPh2qojRDKj1IO52ilP6j0cIYAZVhSa +EpcAo1ky6+ulOmV1nES8nqbn1/u9gnHi3kFOIkgYC95BlVDQ8e1AArHWGFomRBUuiaVCzc7t1Go2 +YAZ9/6MgoS1o2pDSdbWabYd8vJ6GRnRmPCKrjgg624l7VWwht9ZsHY11lZa8575J3fuNJ2fO7nXp +NJTOmz3c2Mu6+iDUmxIXwtPjeMBBymNwH1GQ7ZzF1HranrQZmvj3BQ+UuEf11FxAINXJZ3YuydVc +fjayww/Gu7zypBA4L3DNCkfo7j45QxfBiCL2vOXaWXdbuONPFV61HMoE0PS8tDgXLW946HlpITQb +uxBvUIHNA9AcHOJAK2d8BkqRQlNASmPT3nCECDsH6NCtyEERLU4Jiiih7QCyfxBKfgEMNEWg0d6x +qowyejmVI+RTKqNFlBF7lPBEEaW5ivEbo/1o4fiB0KiI/UihjmYBk0YDlqgpU0xTK+WxppZum5lf +I902M3UY0IJ0wztTioA2udWh0q0jSTfRxLWj36uhmUs3yS9gEoOC0PaXbtL2rD4sjiDdwMrhpJt9 +KQAA2ZduWi8HB+hw6QahHCGKiwAZhJNCBZ8YBYrKNBuFJ0x+Kj0sjOxseQQSr7gwoaYqrxMYRRqv +Orx2aChXPG8+vCt9kWRRYyuCHX+7xe1q3nlvT+gCaA9OWxIXRjz0hO6eCRXKXf2ALG6lwb6P2gJW +TpUwpStszAFZU/x1oXA+GwDo8KwKBEXH7FYH8s0BKWP4Ft3SuFAEgnYMJzd3OIIZBpHKoTwfweXw +Idq/jFVfT5ubw43C7qNV55fcy6F7Pj7a0v5NPLcQ2uHa//MKdzjaPtbgytn3gGGONQjoEO1fBkU8 +HA841hAgjPaPgyKZuDqArJ6PxocjJ2yeVwefj4rDcagOOXNowOWjpDpBUYTN8hJOT0VqlpTaoasf +DNcGyyKnZshKCK/bPcTJrY4RAGiH7nPZwDCb3CS724BoljRhYTURGj2TCSxoxNKONwjDFgFJH+Tq +4D4Ze6ox6bIFlzVkus/UJ1UxEtYcU8VI1JrtaeGkogrdsW4GoH5qnJ5fAIyNskZNCw== + m+xtc8TUXgBNN/YjuYas5vEDaLT7vN44ijMFEC1uT+/QSXSEqzmMWPPcctB0tn3PMNOXYwsULEac +YWlYFtlCs8mEQ5rbxNIBl4ldz7GGB78OqG5vM3WG5/dDZ+hhUHaG8/QAVvCVcbV8Du5DM4eX88mP +NW0tn0NVtLR3OZ9xLR8noY9QzqeLFdXyOXRLF22W8xnX8jnkpYuHlPMZ1/Ip1cEDyvmMa/kcitLF +A8r5jGv5HAali7bK+Yxr+RyodPEI5XzGzzn4qu+Dy/k0O1hRyycZHgeW8xnX8nF6mnk5nyIB2qDS +7c5bwWniBpn3+sVIqiQaC2PCO4hL5rniAWtFWxW1Jb134m1JrRhjnAiWHcRPJaUGYG/55JHCkjoL +ZG9SnQcUTKuqXhXPfZ+VorTJ9+TBzN+iihQaQTPO8rI2Q847aFbEZ3mGKkcXZt9YJ3zU/piwVRFw +WMaOLqMx4Yr30Gxs1e9ZEjtlVX6JLGvIXhnX1lZ+CZ+fhk0xse9u1vM1cx82O9i91Qu7jCcnWmtm +ZXfKhEu7rkSOocHCH+pp5sru9MI+KjPKrOxO34g1jlbIRWfZMMVEYb+aWSllVR2FQ1HAbA2aMsGL +1EZ83qiVaSGmNfn1WrFlGXPbU884fqP1UzVtFb06UBXetcUaSHMfAKAXLjAu6WlaX5uZr3GWWKo8 +KuDdDjZBd5+gV1VXHdMtRpMrUOp6NFN1zHJN4c40895GTeGbaf2NS+Hj0q+R0y/CMVazMZn33otP +l96wcriaUf01NM+8t5yWMK4qvZ7YNXRYrSlMrM1qcow4QpUSD6EdrWZ1LcVNdAtj7EAzZ3wbRFO6 +ZQ8lmmnhqvVpStJtP6Ip/cVUodsLK5Ooaqp0fgemoMyamqtxFWvtMHHPN3V8ncaleyoYOgBmp6pD +GgNjRA1I+M/IcJ/XLNiDklFoYg9Oa5btQT0AmkzIPWCYfccFrLVD/PyHtaq9vVZpSFg4bwRFB789 +YLGduTfC8Y+hLxuWx+nYeRruN6rWU+UOGlDESJ8BUzL+PouwNtY0zNRGU0LgK20tUF0eWNFj6O9L +e74gjC3FK1AmtXoaAaRflrXFHvD76GmXVve+tPH19bTvS3u+IP2KP01y0t6k+jRxSfD7xmeBD2x6 +bxRjUtg3cFiUHU+JwZiUu9rCsWZAKsbqmExS4s3L84zGpPnKSETlN+bKoo7hvblC3ptD0+CAluy2 +4L0RIoUmBULuVMRziPdG7he4Otx7AwD4jFJGbNTD7eO9cWhKFw/33sB6OJX3RqXcWq8VZGx5b/Ax +gisLBULWqoNgtSDYeBYY2lqKIGxSQigV6bqkSBvkqltRpOlsJ+iywBEO4wrJZf04uRFobVL33uN4 +gMDkUj6zDGIr9XB7Zs0rzhtYyabvi7JRxqZJhnBgSxfNSvxsJ+hikmFRiZ/FnEDDEj9ZMatK5bCZ +dlI3/L6WbBvLtU7DdMA77fdV4TWLJ58wG92kp+NU5iE0x0jbM67MM4jiHrMyD5t2ffd77Mq8Q2o8 +bFTmGSbDHq8yD7m7D9yKFirzpMCKeRLiAZV5ylQr4SXvsSvzHOpvqXLFeceuzJMFJM0Ps/0r85RB +LwspnftV5mmsNb24EKypO0LhPzzyjpZ6CUApUy91tU4rqZcPC0upl6ZSYDOjD1UNiijnwlrCpTmg +kCkLWARkpYpFFwqvpyFARygo0+RGGGXem0s3WOen70DT5lc7ZN18dFKsvauAJsXauzJZDNVm1HcN +dR8O2Y9S/ZPc/XDofgTQDD+Dg5Vpuvuxt7S6H41UdUhzezYllt2O9KljBMjeNsKbuAjQUeoyS1GL +x5opIP3vHet9CkwvsVv7vWPTz7kpvdmqKO7IH9K6vGAVnPEXqUzNbtFn80Ge7pt2Ipu13leT9/FD +Q2hDC2WtVotkX0/frPgWTMoOj1Mk+7w6UpEsBHSUIllYt3Z4kSyEcpQiWQjI2oeuVXYzNncQbRT9 +T8Hazl/yhwUWUO7H7sH7UVWUpyPTjl2Ux9URGOYKHaMoD782Ry/KO8DXqSSasYlvx/Y8oChP7k/j +6vL+pCgP5374g6I8HX+aRQuuZ6QxyoWCQ/59aKPqq0/dtFgrX79X6WnFiIndZDWPDIKKWXNCWnA8 +Q2j63+ezq9loPqFsNzLhkJXK9yzGgIy+PAwEO+4MlKExr7pWl/g9637AR31WiC5VzHEh7WTYSi+E +Q8ivA2oBmrn9rP48vA5LrvGuXEm6c4NKO3NXzkW3XngQVNrZeA+1Wy/1y+tcvsa2r4qFyHuxWIjW +YduF1lI4n85+lIPm/VPKijBc9Rsyo/hCqSf9ArjEfepOzmTKsrvz99trudNahjX2GThLOxcOvWI/ +ptc1KrsbR3WxEpV2wbDY7+z26/pVD+vIAGs1nJRhVVeEpYIbudtOXXbHdD8bYtNGVSnaqc+o7I6M +qLA6lH0Kz3/1iv1Yl2vF7p71yu6ejKrffk2K/Rbtti5WT2PyOdbDOjHpU3jf1cdavnmq6lLYPafP +h3pYoXKrWVqwdfmJo794dk9ZfO4c9xzvflA8yjw3LIFk/Hfcc/xh2mAxKuqNaEZlKrsf9Rlr5HO2 +kN+rVG6Dc342iijTnWdxnOIiC8mwageLfk+vlYUxyWNrBsMyy4M1Sx7hTdxjttfDtVxxYL4AY8EX +ZdRez57b7qlkORPTpDiT+8KljdxBs856xrmD1rnKpLOe7gw18ZuShUYrVmdoobuCZcKb9VhRfw3u +gKZ6NvZNdaLfj0k3tdZqVz4TB/E+hX17+mzsFvbhrATBbXfEwj6r37M5sLAP50XU7JvDC/twVX2O +fQsx9Qv7cG58nQT/Qwr7FIThN68UKTxaYR8OlMPkYyZ7FPbte0jbLOzDxXmk0/NohX24qj6FX+A4 +hX24qj6rWUM2CvtwXnrBxD1iYR9uhTkH8VEL+3AqjyJL9TiFfbiqPofOp/UPKOzTjunTZaBA7VvY +h1NbEdGOW9iHW0NcqtWBhX1qUOYdmPcq7NPVOo9b2GeDaIcU9qlAaSLsRyrs249otgv7jCu9jlbY +p1P1fezCPhwAiObIhX24YIs68/4IhX04QaEycY9R2GcWWDlSYZ+F8+YYhX04cshU9WMV9pkWlB2n +sA9X1YdPGakdxUYMSzaijGjfl/a+OaXf00zbw1NlRlmuvlqZbHsF/ZmFnspxQBc/zZi2KEx07C5+ +BiqHNVJtg15bpJLopEy4hEWiptqGRT5QlEY4dMqx9YalGpNVoSBGowyGpYxt7TUmRDQwLFt9qo3G +hM/N0Bc2BqQy6FOtIz/RsaY0mbLk1UZlMtHu5NKkI7yxK0881gz7/x3c/M8h+0aXRX19n+Z/usJG +0f9v38mJn31z6BWUWavps5RzYZIPLfX/O2y9qr2lw0qbHUOnlqXmf+ZOSEibg5v/CZqNcf+/g5v/ +ObgqPJP+f9bCT8v6Mb7RRWc7pPFC2qjxqB8t/WlZl9RxXDqP5cld+K1yqX6YCLbtM81wNONSWNAH +TWxj572lmj4rGdQQjVm9o35miOViR4jGILnRRpIaJJCus1DF0Nb6jQHULq+6pAl+ClZ31g7cV630 +AkbVu98968uUqVaAtUxy0C2nWgFQ5vlpllOtADSLSeTGmdRIEB6nEPPwSArstWjw1XOBBSwCstQD +FwdFnjjWOsZWRFA0ZfYObAGzeaU9gmap2le384W62rc111b7tuZH/LwhhHaUvs8cp4HxWhFs8sNM +l5ptHDXxayM3No2ytgPa6DAsCtSmbBsb7HpZ25PN7DiFMeKXne2rF1pQjZ0lrdNKCSm4cacfbbYu +BTq2mnvrhvBgL7qDdQwOimH6qA1Ax/iMAQfo0A7fHBRhM0qnp61mRKrqWdMSCnvBYn8Qsx8fLJRQ +WHPeH9z3zyHUe+q1/ttjP2LyNcxl2lH6/umr6nzrvwPZje/7Z6H44hh9/yzk2Ryj759DbCB4+H40 +6PvnUNZGWalO2afvn8OoLy5s/We/75/lz7fDEqzDq32fV5Lyo2viWq72BdDMlR/RjDKr9n1e7Vnt +qynEjB3qbYLFjtfYOm1FNMoioD2EqMbLgQAdpcD0mrBorZkC0q/PVRVSiQqUfi0V7CJop/oeV0il +CK9CWRHS7MeUz2QxLLjBHEIvPIu1VFYKqbwXA7W1Kj/WrNRSKadp4nCVQElro1tLlfJZKp83tO6l +7ZnyWdmeVgqpvBdztWK+t+3ZtVVIpZucBPtKGhy+9jTGroOvLD6gC4FKY8R897Hb49Acpe62GNH/ +KBqyb+z26bPVDBNR00BP6x3vq1o9LoR3pLrbnu5XtfbQbN42tpphmjUQjO5ZdyvbqGJqh8NCObZ5 +3S0Yk/VybKO6W95dBBejEccjFHRCWHtXu2iXZmSxEL16LLkmV9A7WMoGW+2LxSjIgr+qd6jUsNJ9 +rowpb+a0xB1EyCMs8znzfynqAW+yTTlWRWUeQLNxPfTu5J4tZWu6VPGpp1OZ59evB1zvRilSJaFV +JYFEQK8QkXW5403/i1494LMuVjib08qS1p0uUXX1O7pYvZdvkaleazq/hNUhFpRJRL6LUTKsyhq5 +jTfukTos0qqiS78v+/SDwwrQQCKrO/EpSgJf1YWIcgrX03c6WFnXGXNTGsk8t+rivKEB1qqb1cda +vXf1cVgdqBdeoqYo9VRjbRp1WKw/6GMtlzsVZeIYQOyGD4TEv/iq0F3gIqpkAZ3n6CKh+5xDXu9J +jAKpvAWQwdRiW5YOTjDrHqNWR8Vgj+AaUp6nRQP/snjyWczOBHSN+VE4Sa7ZlCwkaFo4rgHwC3Vx +lbkzRb8sSpu4pTsmxND6wypaqa8yL67aOI7VmAb5gc0a01j1O5WME7d0l0/QbBTDatnJcTMqAFR/ +SPOA8jiTTFCOTo5/rHGVKnBmd4aSuxvWANpuQakzJk0OmGbfWCa8rRwwgMZoWPr+ZXtjgqJTPw2M +H5EmD1clusrPmYAyEl7GdIzZz9IAwC8tfN7bzHM7KB/rS5S9sFMtbPaviDJ0S1sOEw3Kh3xi1yFV +SGq+e7dX2R0+/i1PUbRUkrifR1qZpYpKEg/9ui7ue3cO3bo1M6tG+707AwNJx5+mTEXBBGtfK7Za +PBgIm8rRLOnXikbY7BtD52r/9DY0F/Qyb+qnGJs6RmDu43OgPoW6HhhmpclImCXW9pUUHYMdzKur +H2O0V9Cm7eNxQKc642oqh61Kr6StTzHIxqSuvxlXjXzOpqq6YkyyCgEh9C3bvzbrEmduC7WlDvk3 +ugzqEs06QJusoSyQP66alwpZ5ghVG2gHts2ODWhmjYS8mpJfA2iqU+ZAoplWE1mfpjICeijRTFsK +2SNag3nWgaapYsapjQLR9ixJtFqPaFZ/Y16oZqke0Sgl3kJJotV6RIwf2k5JotV6RCkZdq+SRKv1 +iJy7e++SRAW/GFihmpxbeyWJVusREdH2L0mUSGosQRzKSi+7JYlW6xElS3qvkkSdMQ== + aeoRFXFPbkTaeR3erNBhvUndIc0K5bP5w2aFWvfDnzQrdJg1qTtOs0K+YsVYbTm8WaHjnzOMvnj0 +ZoVat92fNCvEpigev1mhw1J/z0OaFSrcD3BYrO6weCqZVSzrdzs0Loyx0fDQ2CVhnm1nseGhta9a +HdzwUDa5Y3zVSq/hoc0cqH0bHhp3O8Q5IfdqeGjsQtIx2O03PMSzoPFXrfZoeGiBoY/R8NA43URy +dB3Y8NC0oOxIfmDDbofCeXNww0Pjyam9HHs3PFSMRNPtUOHrPKThofGUsMmw+zQ8xBZHGn6+3Tpt +LFfvCv60gxseGn+3TIqwH9jw0PDkK3LH2hEaHhp7kx22Pp5l0PDQ2B7Gp13v0fAQV7UpbcH9OU3V +8NAYipH7wVbDQ2MoKEZwjIaHxvEYyf1wYMND42Jeh7pIdt+GhxglVNbtUG6tQamxd8ND1X4klN0O +5crtHtUxhNjw0LwW9ygND427HUoMfWDDQ+MUb5lye1jDQ6mMDMeRkjPFXsmFpuGhMQ055fYIDQ8N +9txmRlsMfZs3PDSGIipQhzY8tN6n8KCGhyIU7DayXUqiaXhoUHJhnto7sdvw0FjNh7M5SsNDvWP9 +AROQ3K+MzIKuLwYkzfajWcND49i1Ki1h/4aHSoKrDcp9VHVsw0NjKPI8m4MaHupBsdp+12LDwwM/ +MaFNALHXolBTJHtYw0OFR1zT7ZALrByh4aFYr2XYe/XghofGyo8ep9lueGjc7dBx8Oem+IaHh3oH +LTY8tFKLe4SGh8bdDh22+xTuVRqsFp3ahof7l+rLuh3K0RzU8FDrgpZ3OxQl9L77UWh4aJw9pj7W +9m54aJxEpfZA7d3wELM2sm6HukSz2/DwAF+nkmj2C6/0bM8DGh5KQgzX7XD/FEVVw0NDtpA3Pzms +4aGxxsibuIc3PDQu0hUO6YMbHiqnqe52qNXTLH+FS9nwUF814jUbk69wWWx4aE2zObjhoXw1tQEg +fMXKHg0Pjc8K/SRymw0Pjc8KXheIYo6LvpHudtvBp5Gov4j1yX0dUn16gsv6HmHjfH9VEaWCpURO +k8I/mYulvEqfc2XxuHyKMzOykGhDRG8nrEjSG4W12oBlPus1tfl0gmPmyhl8unET0e4szj0Fq7qc +7uvMZYTwzZ3R96clQ68/ryqZn5fkfSfgC//6vYVVgahNb/Ku1a7AOp9fxzT4a5Q7iyXOa57r21Uz +tpr1YB+PeCzCvCeuK91IPbJ2xhpVZlRozjrZceuaffxsT25iqwff5MP9mPczpe/TdrM+S/2ku4tJ +1jdfDeOrs3Vuzt44H2+yXjftq7JnH0+Xl/7dp+uJWTxPUoIUQNWmmU679eCMBAc5JzVdPQTTtDdH +VAr1AlH5eL8iqqynuV6Pkr71JvF4uXEN2LdN7O3pTqz8bAcvouHHCN1IngoFeN/R9eZ5ATvwJV2c +OogRJ4qS1/N+Y5jMv98vodktNsiE7TZ3I/IskM81rnD0QuQAE9560NrQbqfudFGBpe/VO7lzPfTb +Gfd8Ha14KGa6c/2MnWNY23ollKs6d6ElcwMT4q7nqELSma+022eEezLm/AJ3C6VCv1RtIzC5u6Ks +fk/y0somB0QcjhIZ9qwIcwdL/cqki1qMFl+qzS57Uxyf5qLb9FUuuhmfV5Ku2V35MUcPAOXmmerP +Q/c5X2OdbwDQw0qAy/UX9ZHBWRwWVvYGufOGc43mlf9dIIbO1x8fh8HyQ7cG/wJzvvuJwFLiEGf+ +Z2K9NTKtiOjWB/MbhltOLkdjEa/wF+lDPmdAk/gc/IwHUC0ykD2XS/DzIsQJG5cXHGtPa3ClGBHe +rEQrZeo6AeDWiGApdLar+GqXl2TI+/lbfp+tkkQ0E/ejocLRvZCBInle/HqNkuDGRVB249VdvABo +hHvFsHSPKvQ7WeHGpYiwLkcYdl9+CrS58QPhsZiR1cbpq3gtKD0MQxHVQeRdvBeWAaouUwS8FuXV +ptgNASudfska26ABRaphOttxAuF4lwuIQxwidw24VglBOgWAjT4pCA5iKBITUOglwOu3gHx3t1FY +rhkC1FwBAXTXIdFLtDv5uwU/n+jodWtGg3fbwWDGlXbBu0GAIfJLRHsNiTAjGZoRoAjbD5eir2lP +ajr3dirpMvOtqkCFh8O9XOsVVF9RLifBEOdFHDyAZk+QQoU7Aum/StwnE9VKzjtply7HF05eave6 +JFpXbjZtSloRyv8zdPG81HtlxNm/AjTbJM8Wb7dhxPM8B791ojzPv3UJ8q1x6Qd/PZE8074NKGR7 +XlJgyd5eaeGvMYNg8Os7ayKQYaSYgp/dKP/67IkQ/hqQ4nDewKHXyPDDmY1p+fZ8owZOelgZ+p/q +1Oh6dcbPZvbLon1OFxJ04nwy8H8UP9nKbeEn4UrIzEixDyk3JekfLpYi86eBLd6NiCN651lmOyDI +Kpnzgb9eSeGvMSU9B/TwJpjh9pvRDCe2fagE/Jnz+EP4FEY8KqPrsyRc2gLtGW7ixFU1GAPr9cLy +AqhLuExkKq/XN1LyCLvCboazQWdx4KWyc4Y+v7vO0MOg7AxdP3ad/pu+zxmOesHpvUvdwXO85gz5 +s22n/+sn4wzP75+dwfdIEh5cbhGuh3MIcYt20fNBvc+NApLPeR/ae8Jmby35p15XYUF0Mj5JdIrC +zguTW1cwVgW/rVfzIxkBXR3oJ/int0BS2ItSRnLOF7T6UF8OoWpy6mWXvox+dbcRzjX0FQKHHNSA +aPd5+QqX/QFMxpu6igXgjQ5AE18j+0YlatFWUElZJNGBdIVj81Evm7dZ4ed0XiFDg/hEkIdAsGbi +D7XiaJYfA6zLAs/V1ZSfNzyukQ4H+CtBIlqS1Y4vARcvxqUpccxYLSJp6OexVi8RRfwwa/+bw1oL +V0goYkmZAK5lmzQnBe4DKi0RryLyeiVMZruQVOWCxjsqHNKY8Cqn+pUHMXDaNrdQRbxXfJeisYHX +wuBaYsc97HlP1GX6Mrrm3Po2IoA71ScmEAwmUI0wtfwvMT6bl9bri0VArk+h3uTp8LWo7dQoX7JH +S0owp8qcFdwlAcC7R2URIBiFqAwGWelWSYlKvFAAuwBpEdGvTKeMFCLIghm0BYRrDyvhWm8d/bqd +B2l3Oj2CUgDyMuJHhZ4CJ8744Rc9kk6pdzbsyO4UPjCSdPGdy386N3JzA4k4OKXd6AL8FD8xEfsM +5B4Dr2CjBitcq244VO2nNoQPIKB1oOO3M165pXakpNeifunQQDiFw+mhBZLbN36JaF3nIlrmtMl1 +ofckKJJA/3xzN58BQzNVdedwvicjR4SBnAjU9B6xAE+HvpwOqg7uqIEgR4ccHVT0ch8JRGCiEhHg +cGaK2BpXE2NMh2xqNhfoEFC17Q5LujaHlVep0bLwRABojOhwsRV2wc4p0cHJbJ48Vpghm7rbIiIg +i6Dgr4t0qL1ETr87Ah0iYV1m4AP+HCFTpIyQcm7iAQicpobBBSkVTGmLI/kPPQqD4GSawTjwMNDH +6axNRFgbDQzkOztkIp1UlJc4wnIItqfVFSFDyW3APmsrHMRkqHgWxMKwSE3oqQmrJoJmAdDIJ/Ka +vpFg0E8/ZEIOY1kkTAeBp6ZgEUBrhUQwNqfVWiEofsgn8LSmVzJc1cLKzz9X+SaDmA/+8Oz+OvQe +ymlAlfEdzGkNJmILhgbAIEcczGneT9/BnEbM/YcIYjLUCIZwAAAaBTHkMDQTGcT3pabIaaHpRfSQ +FYFGtP6+5XRocxgdX/CQQfAGO5agllekOmWwe1/iK3jemExkmTqIv8maO4fUwUMmApRm9R7BbRDB +0YUfB9sgDxtEtkmZH9LrTJQUYdSYbaSTlsF4G5xZPhKEQ1o9jrdpMGhCDJNBLEkZXylFp1VivLvj +4QNFJ/kevoiYrarhufTOFtU7HatDG7Hne/YyK/9Zu83Jf9538siQQB5DpGgi344gbNB4E2HnO1PK +Bofd0u612ii+XCVdvD0Yywm+K+gmgAO06uZEPjaI5m/dnKLB/rduTnSDM9j/0s2JfJwAzR+7OQUJ +/cduziB0ICJO+1M3J4InNwr/xs0JZ40cXX/r5kSeTcRpf+rmRDfgvvlbN6cQKfxjNyfycfI1HgZu +TiiclPLLy/nCAvkE6u7lF7bW3YInZHcWRI+AHTHYAMKcRtC+Ob3zcJuC8EU2PNGA1EIClt9xMcaP +HBxgK+Tgz1QQqBLf0DVTC4lC8Rm88QB3dS2C4snQFxdBKVG8AgWTnmpRnRy3Gqq9K4qZah7hRt2H +fJ1QJx6JLsIAJ3uARfYmXuOyhtDlDjKA6lHJkaiQbg2CiL3VoTuuLnf9AXMHxm6nt1AeBUQfKpz6 +cz6I/IQwgC6sDZxSmBNsnCBcpqK8TOOxTqiXzRhQutqUOHggCTYhBrj5j4zjnwTJkCfon2hz9zNZ +366/pl/zEzCpc8c/0fwlSXbm40VlPZm0J/9jW1q8734n8+1J6iSabxUvLxOx0uR9MZ6chPiATFzm +UuE2P8/qtJ7n+xxWQBZKH8nqrOZqXryWPoheRrZDkBfFu2yvoFMc2qzQ1X3mDA3HT84QVWk5fbVN +CP7scV4Xzj2KDdoiIRVwlSbrwq4cvG48luqXzpYqkJkctaswJld+LEyauehmmo7W8v16qV95aOWi +W2KBznA+VKrIUJBF1TFR+PWa2nqc/vQNAz35D9CJD3UIp7uUiDpD/lyOd/Dfn97AGd7AG1lnOE+P +naHrbs0ZWLnW0EOfkAsODxXkt5909FaGQ4E57xay8FIL6HzTKdw9DytegIK9iF4XN2IU/YSWtY// +63sCv5RW405duasf/Uz5ICvWOFZEOe4Nhofx0UlthW19SUgHvlyy21UfkO4Aw0t66oN0g3afT/PC +jVvZRuAFV/VCOuEHctTVYkgexRrIsUNnPtClAkDkPAc5t/7L5nuHthr6aUt9QLoDZ4H/pfqAznoY +mf9b9UFet/OH6gMSnNAb/7fqA9IdZPHSP1IfkO4gxBb+Tn1AuoN83/yN+oDOJ4Dm76KkUogUis4/ +i5JKIVKHWFn5B1FSKUSKROdfRUklOcvLtL+JkkohUq4ERRUl5fSbEK+0TBlItJsI9xM6iEpX6QUB +AN0SnCSVye9qh0KLAf4JyiqNpCRaKUMWyHbpQDaJiKp60eqFQ2V20WERUeNwqJTdemBE1DgcKqiR +B0dEjcOh0AlzlIiocZQB41LaLyJqHA7l3H1HiIgah0PFyPyhEVHjcKiQanJwRNQ4HMolnx8hIrq/ +x9dWRNQ4HMq5yY8QETUehG5Y1m5E1Dgcqh8ssxkRNQ5SYbbnfhFR43CobY+vXkTU2O2sCpbtHxEN +GoZDYbDsKBHR/TjNdkTUOBy6ZwKANiJqn9P2iogah0NFTjs0ImocDlVx2v4R0aBhOFQdlt07Imox +LHtoRNQ4HCoLyx4WEbUQlj1GRNSYmtx5c4SIqMEg2AZ5cFhWiIgaRyLlh/RBEVHjcA== + 6CFhWUVE1HgQemFZ2xFR43CoXHQeFBG1H5bdKyIq2Cb4cKiUrq0fEfX9WoiIGodDHfx3CQ6OiBqH +QxVRLHjUiD7Xul9+I7kVo5R1eZQSnAtiJUZdHqJUGNtRFZplcSreU4UQoJf2JiC/1vGJQQpgdstu +TJmxeCOCbC4o04BIIjiDHQgWuAFg3AEZ59km/HkvBw52HCTuPW/OA8ZP8ZZL6HrBhSkAL0Puu49y +EVbAUrwf+p6HC9gIwaVljszacH3GBYv8YQbyaDssDxZmc+diyKBZ+IlMA/m794+Gyo3PuR+4bOei +MuRzpvwaQYHy1yppCyBx8Bz/6IC8b1xIgY3Y9s49qb70E9N8a+f+KvfHdzBY1SYlNqZedoMc7+ro +DWjR18kofZ2lbFxkmUfO406V7otQJD1GhQ3wCIC/vUAj9pEUHFePKB4B4xaPtPgXwwEon/+y4Gc/ +LESxqOE7Wv2+GCPvE+JfMp6D317/EobTp+U3SjO34MX8jgmz6bOig5jwuxME9dM6K4eSfrDFiQd3 +UO6f8fHf5OOmJP3DfyWG/65LJvYSkbDSHv8tpOsL+Kf36OM47YVEP+BflPzR6ykDrzGcsasYzn1l +9NArloIJf6VSvn5ICO7T3xgxeUuxkEsjovujzzvv41a9iXu6EpFMs+FN3NOV6PjHnjdxT1eiLDnD +kjdxT1cicj9Y9CYuYCj0HHpHL0lyWJ6P5cFOcPkMXGpNtrsleiQ2LEymX/PG679PwHFDnnD/I8D/ +4L/x5AlJJU6oWAz8iMGrjTfHPz709AnpP2nMAZBhNL/elr7et1+L+ev6309S6Fr3utG5LJ2kTrin +h+Dp8xMfGBMxBI+DW34UZx3CkQ4d/xAnefhP91+Of4CUCOzgWErwyi34J5KIJwgyeUJEaDqeSLJw +bBEqQcaoJBxqhAH/dl/h03DQFPz17/DXFfjrG1z71wlJnFyfPL0QJ2MHedJtOv6JJyMUxbAnYYqO +0Mlk8uQXXSPjACS8RsSJxEk8EYnTRAxcoCIJOs6cxOORJEEw6EKcIKiTIngrHiEJhnsolqBjJ3E2 +QrIUiS6wRAK8FQPgYhT3VpxJorfoSDJJcdeSMQApTgsP0RGKZAFyKkJT/IUYvAPfIgHEOIOuJVki +eQIuUHEGXmAiNJmk4QX+LSbCMskk/xYkG7qWjLMkfChBMHFwIRYhk2DGAFcsmWTRBSqZTPAjZGiS +u8bQCTAvgCLBP8RQYDlghXSc4d+KoXfYSIxFBANTThAsJBgDxwlRJwgwLkBSMs4k0AWGYjhMiUiS +isfRNYIF2OHixOM0mmac4n4rFgu89AHeIyBahB2uBVhBluWWBV5jCYI8aYBr8Qh4iCa5hxqQHOAn +wT2Iu48DokLVQPgJyKEsHeFuoFXUG4PiIe5txN/Sqie5PyAbgoWPoUVOcsQDFwiK4S4k0CJT/Ftg +GqSwyFQEbNUkusagRQZrGoOLDC6waJEB8Ri4fnDywiIzETJBcteSaJEBR9D8Q0m0yCxPe/hWjGd4 +moSLDK7E0CInAMcSHGqaX+QkhRY5yf1RRJuLjaNFTgIeAdgTBJgVWmS4umiRkxw3JSIJfpHhNQrt +yATYAwR6iEkgBktAWcBAVGwM7cgEtzTcABMxhnuI4HdkkkQ7EnAfvyMT3C5JwP2T5EkRZyjuGsPv +SPGhONqR6sUqSmwQA0NgCJERgcAMM6y43PK73OoruQ6yTQJxGB2X+BQuMMuNpYF7QMO5AlexYB+h +7QwfjiHogBkoOArAgzRYRvAwuIeEEZwekhTwWhKwHmBZONgYxaBrKmAcGigLOF5iOYEB+TYm8BLL +CwxW4CWWFxhxgZdYQWAkBF5ieYGRFHgpxgsMnoXgBUFgANbheAlcQwIjQfK8RDNIYIAHOF4CvwWB +Aa8hXgLXkHQHFzheomleuid5XgIXROme4HkJXOOke5znJXCBk+4szybwLYGXYjwvgWucdGeEhxhe +ujPCFmYk6U7zGx9c46Q7zW98ME9OugscCC6I0p0WNn6Ml+60sPFZXrqrF4sXn0nEUAwYCcOvIH8F +QEzQJNrGNA3eYyiwoNwF9H6YISUJEo+wLIsuITaEew0dkYCF0DaOs9Lf74g0HDuJ98HoaEYGgCe+ +AgmYN8syspFQUBhJI+V/8lN5R+KQv5Ik2diJBIAnnIRFZEVhHGA9EzR9Ig00LsxM+vsdnXX8RIX7 +AiUEACK1ZNzOE1QYhbgE3CiVK/KOlimWgLucScoPOfRUQi4I4JVYTBQWCfiTFh9I0Bw5BcnC4yFF +AaV6QPW6Fr52DMphNoShcySMseLpFotzkwPv8hInhn7GCE5xAdcAZ6CDMwze54WVBpLsBIZ7HAkt +IKkSkM8BFnimcMINCCX+EAaCEhFdVI3gNV6hQAqVSDvwLpSVZJzbtOBakowwaLFZkhs+fBfMlwUn +AZSrwk9+mMLPOPdWAzNIbgIMvxIER1lIHwJxlLASqgf4t6hITNow4CUG6RdgNcTXFE9wbwU6nGIN +1QEmAbTkCEuTCfh/FBkjgYYPBRxLwhvSf1Ct1tGVlSqaRofDKXoabVCjL2pVSo3WqdFLccqrRsPF +6MA4RVmjTav0bZxSrtHcNbo9zgDQWAkaOwJnbGgsEo3NoqMr4xRNjYKjUYFwepJGmdKoWzidTKO4 +YVQ7jf6H0RGVSiRW09SooxqFVavTatRejWKM0541KjZGCcdp6hp1XqXw4xVNrVqH09dweh1G/bOu +1mnUCYzCgdNKNKqLSrnBaUAaNUmjSOG0LY1KplHaMJqdRv3DKYhaLVKraSpVUZy+qlVqNWqvVjPW +KM8a9dquWidoGRotRKuoqFUZja6j0oU0upJamdKqWxqNTKWx6ap0gs6n0QlxiqNaudRonyrtVKO9 +qtVbnAqs0ZNVerSOWqfRjTCKD04/UqlQOroRkB3cUcXBBj856sQYjkHBU4KEgJqd8KYg6cFrYJuj +Mcgh8bAZ4UqCO3shAppTEglRQaLiwoIAuRaPkTx4RDb4pqA5aaCp9RUgP1gWaipkjCBicfRHDJwi +yPmXEP+DugrFcqjCJH90/SKcHL3ANZafEkfgMJngxHID86bOY/zRCK9xS0SynOwNUwRHOuxT8AoH +XrzC68pIQ+KVO6zeilEdad63EBaUVfhuDIpc8G6C5WjMjw1NnZLYh4SSC44EXIvxSwWucZxHJjmp +pTMvLDzcczh4wjIDvZrnbjKOfhH80YVbAsGnQdGIHeFxBV/+RU9zY6ElR4vgYgvTFLdP4TVKeI7i +Jt7QQDPgahy/4vhay/14rlZvS8x2w+1K3O7VbEu4Y5BJBHX6OADCu/G5f9H20FIRRx0cFXHUxlER +bdmTJvwH8ANFMDS0JBhwdoHjEo0EbVf2pJuHS3sFrnyfUCf/OqFPrh3/bWr8Fzc1Nv9tavyXNzU2 +/20I/Jc3BDaS/kTqnwhIAv/LcZxAWstORKxlFjJpCbEM24GS1n+Sz1SYr6kPr2XFY9eSK7wMxdJI +4aWZeCIOXXN0jCZhFD5CEMkEUoFZ8T+4jOAAdfyxf2Dz37blfwXbcvPXtuVGzqlxwPJQpWPjSRbs +GPgHQVFQ40sSJMsgUcMJGo2r/XdvV7sgG+Qu919LLvcWfhw4U0y+IREysMNwoYaDTDGLphO3yNBS +4tdAoIDcgAJjIWOC2SkZUAC6gJp7EWsixwTbjJEGl+Dww+cEoagy2FoYi1WHnBj715IlLUhZtSn+ +izcXW9bjQS35Efkvx1+bRps/dMls/jNcMvy+70CW8vlPuo+OfxoFPomsPB+jNK8wzL08u3udTtrr +168fmFM23bz+2+TkdT5fbF+3kyW4dTJdTzbbxXpysvlc/AtegS+JL5ydlW8rjn/+H5GbhSg= + +image/svg+xmlOpenclipartNetwork Interface Card2013-01-25T07:49:01Network Interface Card (NIC)https://openclipart.org/detail/174480/network-interface-card-by-witcombem-174480witcombemCardCircuitElectronicsInterfaceNICNetworkNetwork Interface CardPCI \ No newline at end of file diff --git a/backend/webif/static/img/cache.svg b/backend/webif/static/img/cache.svg new file mode 100755 index 000000000..6c82d0dca --- /dev/null +++ b/backend/webif/static/img/cache.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/clock.svg b/backend/webif/static/img/clock.svg new file mode 100755 index 000000000..b9a1cc8b3 --- /dev/null +++ b/backend/webif/static/img/clock.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + 2009-07-05T21:07:07 + + https://openclipart.org/detail/27002/analog-clock-by-sivvus-27002 + + + sivvus + + + + + analog + clock + photorealistic + time + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/cpu.svg b/backend/webif/static/img/cpu.svg new file mode 100755 index 000000000..6c4b7620c --- /dev/null +++ b/backend/webif/static/img/cpu.svg @@ -0,0 +1,1543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/db_backup.svg b/backend/webif/static/img/db_backup.svg new file mode 100755 index 000000000..94353b1fc --- /dev/null +++ b/backend/webif/static/img/db_backup.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/eval.svg b/backend/webif/static/img/eval.svg new file mode 100755 index 000000000..440fe5b98 --- /dev/null +++ b/backend/webif/static/img/eval.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + diff --git a/backend/webif/static/img/favicon.ico b/backend/webif/static/img/favicon.ico new file mode 100755 index 000000000..8a22cecf1 Binary files /dev/null and b/backend/webif/static/img/favicon.ico differ diff --git a/backend/webif/static/img/gateway.svg b/backend/webif/static/img/gateway.svg new file mode 100755 index 000000000..117ed8d8f --- /dev/null +++ b/backend/webif/static/img/gateway.svg @@ -0,0 +1,3793 @@ + + + + Building automation controller + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Building automation controller + + + Florian "adlerweb" Knodt + + + + + Adlerweb // BitBastelei · www.adlerweb.info + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + Drawing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/hd.svg b/backend/webif/static/img/hd.svg new file mode 100755 index 000000000..13568a687 --- /dev/null +++ b/backend/webif/static/img/hd.svg @@ -0,0 +1,8781 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/home.svg b/backend/webif/static/img/home.svg new file mode 100755 index 000000000..17ae45420 --- /dev/null +++ b/backend/webif/static/img/home.svg @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Home + 2011-05-23T14:32:40 + Black and white Home + https://openclipart.org/detail/140131/home-by-gsagri04 + + + gsagri04 + + + + + Home + black + house + icon + white + + + + + + + + + + + diff --git a/backend/webif/static/img/html.svg b/backend/webif/static/img/html.svg new file mode 100755 index 000000000..bd7a5c665 --- /dev/null +++ b/backend/webif/static/img/html.svg @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + + diff --git a/backend/webif/static/img/interface.svg b/backend/webif/static/img/interface.svg new file mode 100755 index 000000000..d3ef089ee --- /dev/null +++ b/backend/webif/static/img/interface.svg @@ -0,0 +1,1877 @@ + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvWmPJMmRJfi9gPoPvh8aIBtTQTM9TNW4gwXC4+BwhuwmSPaxaAwKyawgmdN5FLKyyOX++pX3 +RFRUzdw9KvIoNne6QqsywsXN1EwvUTmeiP7d//Gr33xx/dWb3z18Ea+mw+ef/d3f3bx9ePbuzduf +Hkg+/Pzly2+/efcWpB/9+seHebmacNX1z+uXduU/P7z95sWb1z/ld/rtPe7/0S+fvXv3x4c///jw +ox+D+NsX714+CPkffn7z5S+e/e7h5cuHr66++dMffuxPlVpun72Ta+afhPyTMM3xsPw0z4df/ZKX +PHv9p2fffPPi/8UFS6wRxOObb19/9eL1H45v/p+fHsrhi7oe1nj4Yg748r+9+PXDN9srrrJcU6/C +utbDGq7SNCVcfVVD5i23b55/++rh9btfvX3z/OGbb27evHzz9pufHm7+8uz14ZfP/iDfPDv83/Lq +b/58OL589vzf5Z7rn+cv71+8fJBGv3r27iCVTaTO4cvjty9efvUP37763YP0x1ID6fFL1vpP30h1 +UjP+Jr18+fNXQvrNw7t38rryUHblr392HN9FqCw/+rdfP/zhBQdGeu1//rjV/PbN16+evf133C3t +mqYD/p/s298+vPr6pXQwuyJP6Av+2/9sF0pzeNEXIa5XYZrC4Yu0BLkqts8RH+3y3mkPf3rx8Oef +Hv7hzesH65nrt+9+o0OWEl4H/9pXv/725cPbf3r94p287ULaql3zyzdfPbyUO3oV9y+fsUdY5v6v +XfHbZ2//8PBOBvvNy2/fcS5Wf4p0/y+e/eUBozjbQ/7x64fXv33zz3zVL1I5xEO9mtNhznU+1BQO +c+UTsjxkXvyhc//XqkY9qKXVXzBgv5Ix/Me3L/7w4vVPv4hSBf6x8f3Z2xdf9eEt4VD1Hzblqg7/ +r+1/e2Np/7t3D69bE2Rq3fxymCjT1S9/g2ffvf7q5s0rDMU3XBwyRV7L7Hn55g/2bf/A76SKb7+2 +xpDwpYzcr96+eI2KP//sH/S7+uWvXn4rX/7s7Ztvv/7569+/+fyzHylz+OeH58IAZHi/Ovzj7/6X +fJC1zkl8+O3bZ8+lDvns11w9e/H1j7+jQmnn24eDfiv38qP8/j1+P+X+24ffyyrsFSj17vWfHl6+ ++Xqo2CnPXn91+Jdnb79+SuW/evns9bO3B37hdf/ixZ/km2fSZb32TntStTJ3vpZO4k28ZveIRy4Y +vnrSo569+6PwrYfXX33jtevH3csr8SlV/uYvr3735uWLb155hSPF/37i2717ePv6H1/ra7799ps/ +Hn775s3L3hF6gX3VB/ntO73nb+YhfvG5B8iXf7uV3zx7+fLFH94++/qPL56fq//M9/6gC/c+aRY9 +Z6+fe+L2K3/Y6R1/S89pk+juqxfC/C4s60ev+c2fn717/kdhL797++zti4fvWIsY3t+/eP2VvOhv +vn3x7qGP15tXX0MAOvzmj8++BhlX3g9X9nrzl7JBjBvAF188vjXI3nh8PV7ys7fPvnohm48IeT97 +8/Krh9eHX2MPkPcbP8p2Vw7Hrz7/7N8+/2wa/pvbf+nwd18eRSb6r0Le/8y7EoYSrSQrmf+3suB/ +qXHZlOKlTuumXA/lKOXGyu1Q7qZ7qfG+lc2rjT9hKHEoaVOyFukD/C7zIqXwdx3KuinX89HLjZfj +fCulfbqVGm/nO9Ju5/uxjN3H12s/cShpKDksKJ9/pr9DGUoNqxT993ooRy2ff/Z/nR/TS6MaN+Oa +htHtYyxFamzjnIbR1tEdR7lKwW+Mbt2M8zqMtPwrNeqYt1E/+njrb4z23Tjq8q/+TGfHXAT/zYhH +GV/8xghjrBeWytEuu5G+trIdY4wpft+x3O5Gsz02ciz72KHoWLWRW23MZJxkTHWsMGY3Vm5Z7qzc +o7RlhubsxnTmaCXr/8p+PXLN3LOHAntgYRtXtueWbz3bWy6cPdeYK3w2nhVijCkusYjGt8ajlNt4 +L8M+p5hSyqmkmtZ0nY7pNt2le+nOkGNOecklr/k6H/NNvsuyTuWVZpmyacnLstRlXa6X43Kz3C73 +Milm6YxUcllKLWs5lptyW+5lwsw11FRzXWqpa72ux3pb7+q9TBwZ0zWuaZWK1rqu63G9We/We5k+ +83W8Ttf5ermu1+v19fVRys317fUdp1SQJqRjPpZjPa7y1fF4c7w73ss0k95kp8ebdJNv5BVu1pvr +m+PNzc3tzb1Mu5mDkW7z7XIrr3dbb9fb4+3N7d3t/d0kwxPv0t1yV+7q3XonD7u7uZNZcnd3d4+p +cS+ddp/vpbH38vr311Lkofdy6/3uh2M6cViddjeU26HcDOW4KddDWVuRGld5fC9lKMum5KGkocSh +yGyUGoOXkbN1rjyNL383/txuyo0W6TL8Pg7leijrptShlKEsQxGGfpe9pE2JQwlDmYcyjUW7/fPP +bADGBow/N0M5amlLdTOe21Hcjl0bte1IbUdHRkRqTOOIDCOx7f9tr1tv73qYvSr9te761Hpy04fb +ftv11rZ/pL+2/aJ9cm1lZalWipWFJVtJLNGKzDsuRttTdVfwpdAapw9rP0eWaysrS7Uii10Wf7lZ +rGQriSVaUZ7c9gDhq8OY3nEcjxy3ynHKHBeMxcTev2VvX7NvC3szsfdm9tYde+fI3qjSusK2o8Vo +5cRW3bIV13zvwrdMfCt5F5k2d9KlN8LOroWtVWFvizC5JMwuCJ+XN5UpdSedfSPM8FrYYr0uwiCz +MMoo+80se/C9DP2tdMpxvRZ2WtcijDULg42yQ82yY9/LhLiVzjoKG16rvKOw5EVYc6pRmPQse/u9 +TJVb6cpjuRYmXksRdp6FrUdh7rPIAvcyiW6le4/C+lfZAopsBFk2hCjbwrzIO8qUvpPBvpFN41o2 +jypbyJKzbCZRNpVZ5It7mXi3MiRH2XBW2XhKWmQLSrIVBdmQJlkCdzI9bmSTupbNSt5Rtq0lZtnA +omxks0g09zJZb2UYsc1i48VWnGXrw1Y9h2lW9juIwHYlrm1X8lpZYLr1Q9yDgLBSgFCBQkSMNjcu +PJU1sY5WQ78fAkrY8Iv7YSdQTrHKHMsyv2aZW+dmVhi2Ee5S+NGdauaCxW6VuazbjmV7FnYs2ZRE +YGivgL3R98VFpl49szNG3xmxL17jme1+lzGiSbClyRmUMu4oZ8wmaWSXNa73Q4FugYw33XvN8pmy +4G2jYEHpchr3Ud+A22XsEHaGj9M1RZu7eDIDKGLOLj6pwKgilAqGNxTv7+Qhs4nu2swminfRmyoL +a2t19ZpYDztK7z/bSf7+42DqQG4EDwodUWZIkZly5JzZCRpj92TbQhqzGtlVn1adZY1Mi2zLe/8M +M9uysu9iZD4cu6X8SRby0eXrVrrGVDe6VDH9Skve6GCml0mN0ZiB/qjMv1GJt9pe261cF3RtgkV6 +caNF3lBCb5oHfq+7Unela6z612K67FjSSYknJZwp9iM1jj8nqiNW5yj7+e/bs0VYi8zCGy9HL9cX +ynqx1KZhSo1lV5Ynlq695rFIjZvPbuHof5+WeKFwakiN4YnlXCefKVLj06588s9ZW8FH/Xy6Goft +dfaOVem3SfG3VlRua7aQZhuppns324mte1nVqqe31d7sMX0p7Nd2k33bWh5X79FWdbMinK7d4laH +xUp2m0S3S8Vxtbo145F1Kn+5LaTbxnZrs63OW25NzcYy2tiOZ9fmcWOZO12dzYazX611Y+XrVqFm +GTq3Xv3zxnaYT0raWBsvr8qt5Wpvszy3bh9bzbu1ylV94bv3X9GPruq/gTX46Wu8IPSO6tWpgqVS +y6mC1WSViQr7HSWS1RTMxWSS4OrV/SCVlI1UEgYV60aULKpYn38mShbULFWyoGZNVLFUybqh1UkV +reqKVjRFC6rWjahZRypalTYsmY1UtmYulHvq37d4hFRQRdVSZQvqVlB1iwrXrSlcRypclQoXVC6w +Mpk7pnbdU5eG4qWqF5SvSuUL6lei+jVzWd1TBbuhCgYlDGpYkcfiUtG0REWLVMZEHaM96I4K2a0o +ZFDJoJRBLYNiVlKmagblLJJ1TVTQ7k2HP2oRDr5SvoOEVyjlLbgh4memgNU5O8RgHZAux6nsVqme +oSRy8JF3D1x7kMKaPVd/jzx5lKEoLwm/TSeykXPWDS/dSDYbrrnhkbJiRpkFZcftzvK5R+SLM/LE +07jGRW7yiVe1q6JaRgvZ+LM1Cg6mzq0dru25VDlmU2l7iZuytfnlXVk2RQSAjSWxbGyMlTrWtlzv +ynFfzKI5ltuTcvpzf1rabBMGOe7k85kSzpZ4tjQr4mnJF8pysbg9WWosu1IfLet3FBEpNlbt8+X4 +xEKOLzXePLHcPq1IjafUc0P55CI1XvruA3/ObK8fXJMbiCbXWoM5UbQkK2pPbfbVYqXZX1crZp2V +GtVa234aq+hLqA1L47dNt25Sf7MUq91Y5jfNU1oWL83WXL2sVq69HM/wrFuYl0441jle1f0I57nT +wJc2fooNT7rAjS5xoZHzHGkPusx7HuE5Gx5jfIa2tMs85gxn+S6OIjU+ykeewEF2nIJeLucaH8wp +htV/kU88kSuc8oFHVvXj5a+4qt/LbLsx3Ipgd6O2VDqKIYvFJGtQBMJlcBgfhTGo03gytzEcx5mu +4yqCZ3Mf38KBLJuOOpAjRVY4kWWPoSDbXMlwJt/RnawO5QgplE5l/MCxfE1RGc5lLCZ1MMPFDPmT +bubPP6OruUIqp7v5KOzp1p3Ok0iJkDjheE7ygpClC0X4VcT5azqhb4R93JkrerqWFSNCf6DwD6c0 +3NLLdaFasA7uaTqopWBiQl6caauMdFbDXQ3ZvdBpXUX1WOm6Vuf1DZkTFvo93diTc+HGfxvnbRy3 +c1rjscJvG3ftXLVx085HO/fsXLNzy5FH3pqF2rnihht2HriVyUZut+Vw0jHCyzpn2/KyHfc6Ixmd +8qdR5jkv11ziOjupZCxS4yNc5Du5xlN3/w9f1c0cDujXAKyeD0H+Wg51ukqydg4lXslqCbgYuOYv +n3Lt8ZszdV5luTJPhzpfif64XK5wfyFru5qXsqZZvp2hGIcG1M61hiR/lBzs6zDnZT3gAq0lXMUp +p/64j65J32cSpTYvctkky37BjaKZi+rOytaUp5UAcuGUKcsfAb/nobJ4NQmnGV7rE1Vob7dMwmdR +WZ6nXHhjFf6slYluWfUBQfgsKpPhy+umsjxN6/h2n6bCjxjLUK5qjCuqqrmsHzug++rOzVl7+XW9 +Ej5/ccJur0I9x9uO4mxAzAvgzH98+/yPL74CLtP+korDCMm8Wpa5wH0tXR9DKUsDaMqaY2/zGsyF +/ZK2Ow/tRg3UsLsOdpOt4KzRKUMTP+Bu68Kn3ol+S8tVjJj1H/LobQXv2fG/+fe/oNfxS25Orcv/ +q+9W97ZHBdudsnlWi+1F17b73I5ucttZkgG8Fui+KkHJ1jEbhC1RrgCI7Uh54p4WJw== + lSMWShDXlB3uuKkAwgZZQeWEa5oTb88AOBWs2ZxRak5Xszw28MngruplbnBV+qod9JcfgYWe+7kM +AB6N5Xkw+dAeqSAQwkAcCLK3SBYDhCgkxEAhtEneGSzkJrun+XG4ywB2eRLUZe8rdmFqNuTDiH3o +6IcbFZgGBERyAWltKIhbHziIxIachCBcG2qS4q9iJitFXoi6EHSz9AiE2xuZgxMF2mz4yNviDnzt +ZQOSdCjJBoxi9srJPbE3tEiqBbKYpTGZz2Ludvgnw4GeBAVy8EK3vysqICiEy6Bbtw7XujaQVrPH +ZwNjKQhrooR1d+LnH7CyjpZV46067KMrLJlKy0LFpVB5qbRGX1OFOdKCIaNHWfWeykxXZxT9inFU +lUaVmq7WULExPKwiYqHaQLkRbk4Fp1LBaSrO7UbN2Sk6puZgLjTULFWdpuzIKtuqO5glqyFpbyit +3zmeNlDZaajaUdm5obJzBylXxl6VnTgoO8UUnSMVnVsqOoq47SpOGlQcqDeu4IgidEslp6k4p0pO +NiWHao6rOEeqOVRynFkZytDQ4AM+kx7M07/v/O8t1Wz39H+aJd+8pHfdX9r+Gn875nyMNVC/QEOc +z+4piB550H/Hze9kjLqh07PHI6gXQhgnAj6GiIQWl1DsX/Vf6L/qae7/Xm+8HbeGXG9xCYQuwY89 +YNc7cj2aN2Ux7PpivnL1uvRYgxuNMRjw6n399XUXieHZrzlOHWJ9buO5be50Czr393Z7OrmHntTR +3zG7j2T0lpx6a089vsl9Lns/8emn8ff+75GWPZaiR8+ki0iTyziUuPk7ErnSPqWdD2n0LJ33qvfv +3cdu77jvk3nwefee7b3cR2LrEdqgc49n0LnFcLkdkduwuIbC1W2AAoGIBLJ5HykWXNNKUslOFhMP +mqt2NiFh67C9dodtIQszp60wrsBV1Fy3t3w93Rh1a2ybo2+PvkG2LZKYWW6TslF+/pltleNmOW6X +I3Z2i57d4mcdQfv5ZyoumQN3j6G9hKJ9BEdLcaXB7z4IgDc7uz5F0A/luzH03QJvNnkRIa7dUr/H +jRe37m+x4wN63MqAHZca9/jx2w1+/PL8rObLWLazVGZ2x46PyPHJ5+y9mbO0cfqAo89enb8rt0LO +YpnZOpMXbpV9PkdDNiqXV29zm9t31mU3AyhB57kUmdk624vN+IVaB+UY5cnk7bqHqO9aV8AdVwHX +gUM2zvkP9xEj+3LeSxlOPA0nMSVnY0u2cQ4ncSYyD0+iTXZxEOdjTk7jTiw+Qmo8F31Sdj7lZedx +vhyDEglgPh+HMj+yii6toVuAsM+upOPg4epraVxPw6o6sR1erSKUxky9HHI/DC3CPSpU9mkWFpZp +jhElvS7Q3vMa5lw2dhO5ejAwfqoK1dZUl2WdaT5YRXSuZruRj24eUtNaN1UtVyJp1eF9PrgKfYOS +orBEGMVikV3Bbp7nIsoCGom/0NqahJcO7ciL3DoPhtKPrsmsb3WKkZ2Z41ppcZStuMae+aKgAtj1 +tIutnvUq52ljqvn4qt7XaPPtq1cPb2m30b9ogOvWslFUbALcKISN4ajFIYgNvHj0oOK7JvIbyBly +cBPLs4vexQXsHhDaAntHAboH8VJfNFhpA5s28GkPz1WgqsJWL6utmYorxWfGtjQBWtXWdRCkj7bZ +3TXlVdRXQrAM18qKqMBi36emKUucGiRBXKrMNoX22LZQY1rNcaLSYTBsuWnU2arNIudQ5SUmjcaN +amqvFtvGWrBV9g3bneANB+XYWMo5WqKX7KX/FC/Vy7WXYy9S481QOjhg6wwa0anzpsShsPtEGU9e +8qac/tRdWc8UkXfK9Um5uVBuHynu0oJt8oKLfXrvwgktMm34FOVsSHMPai4e1nzsa3beRtRUrtBj +D9DGupQVqCrtJjKHa+5+UFG7F3u1iKDbwfCT2lqBuUfWi66PG7owJw9+zhb+XGnOu7aZfUfTDuZy +pIEz2yyFYefIOXnLudg82IEzqnuvr+m9tnEkAHSmDhFpeGumnEoLM0w5EEvUjDOZGSfTiKPe6tV9 +1bdmcwZLDJT4uhEHsuHqZhx6qWnGecxT3X3V62DCuWGYNcyqd4aMdC+1SMpbP/VCabrjg5q/WkXk +jgPq+J+O/OGAEe2TNmifEeeznqB8Nr7rAdXjeB7TYbYInibB7XE6p/icU2zgzYAKPIfG2eBwLmJy +NvLxJhb7MuLvkpy+xeWkC6jAS4jAR0tT9+dtBHSLfW4xzy3auUc6tzfpuoLpAYOkr3L9Npa5x4Y3 +abxL3j1q2WXqQYa+NWzXNkq5S8ansclds9xplaM2aQiLrTZ53tZxoknutEjTIw11t9Ukt7rkVpvc +6pPVDK3FN0IZJdcqu2bZdMvgeU6mQcO8H/TMO1cnPMhaeEV7eP9ZvVQvfVvrm3T2knqRGuNQeiTf +vCkj2noL2BiVOA6qcMjOEG425XhSrnfl3I9oheSx23J2Y6fd6HJxQUlqzBdKeu/CrY3JMz5B+aAI ++Mdj4Bk4KitwGzp6Gge/DSDdxsKP0fDmIJTZvWychN1NeLux/m1sf+owdJdhcxpe+zgXGyft17AL +37hxB9m6C+KI3f5nFsC7InORDODIpbCa46xQjG1OVLUGdjfq1pHagzsKpWCZORbioQ7VsAnzuCMD +2wZ7rJRailsNs8nyHvYhMv1MW3AL/9AAkBuzJ27DQDQQRCWmFg6iASGqhdDfIXJUCw25N31FGaqy +vSNtkNdmh2zBImO4yGKKhyk1UWYltaUWqTufCRK8FCbYgku2gcIi65nGtg6i6qVg4V7SucBhDx8+ +/TmN57sUQXYG8g/E5q7cfUj5LqQYkTR1C984f0EDh+SpilZI0JBIv6thOzJMGHM3ZrjpYo9K+YDb +39PG8E+vXz979fDV4Q9GOsywN5yhjkidc3mXsqsoQ+6l+XLAv6YOuG9h/zQTAGi7B9luMyNs4bXq +iVYv9PUGVBuAFHJI7XriWevGknSiYLW3bykLehv2rTgyF9atmz+emufhEcCwzD9v1Xu99dHeuqdZ +GPt90/Pm/bw3c81J0oZHclOcBzlLX/eR2GZx+n6yw3yi3DDXwjl6bpjvPafND2+9feuNXT2mkidk +Hg5FDd3Q7wutvldq1zrzx3nG+QnqAhfVtMsk9co3xI/mtdN0ntsKHWmg9/w2GNgN6/2GKIxIhMTK +dQ0uFIlXWGlWvZP1q2adyhWrCCzNXCcD4AisQD5ZaJa8HXLVNQRWCy3omeqKBRQwnKBhaz7/zNE1 +W2SN4Wo2IQTZTDLbEILRMHO3woTTzDOKswmm/CQz1LSggsVUqKZUdT2l/ZgyRrWsKWlNadv6u3qU +zCbsvye73BaZAOGkxLMlXSh5W0wZ7WV5UimXC92n50v9sGIx4E8rZ7TJ02KhHZ+w/FDjpSsGqaLJ +b4tzFZXaAiWHssmVGYiIKpQR1HjcpbOKnFWaRsolM0gDY3bMSAPxYug/C29yzF/H+3lQk6hwDevX +gpq2IU3Og4DxOwlqUpzf4sZh4UfCo45DaJNxJgtwmghMDpswp+yhTq00s4b+SI3Galr3diNKM610 +s0uPnelmmnlfCLrpJZ4p6ULJJ4XcUWpcLpYz/pULpRutqsEn3qecWJC2RWr8jivetzy5xif/SI2f ++Od/jxof4SjQSe4Mjp+phVyrc8rTvS2mc7Scu+AnpusJR7mhlqEOKM24Cy3v3nHjeZNtV11NDUE8 +upnOc5TGUxpy+Eyg5Fmu0vhKYTJI5S7XG86iNvg9b+n8JZhFp3OZbKZP2a0HTtN++nTd8pkNfmWP +1GkcR+WoDde5xH3ChbLjQDtj9GWO9F38yYvU+Mi3H1Ae53ofVH6o8a9V43uG5jz559EatzjoeGJn +KRvrkFmGmIkzmrQ0pLMcA41oDVK7SpObmsN9MasW4SoqOTFYvEXJXNOmde/yU6JxenSu31N+ihYz +U8hEoBAQyKEwjc8/oztdQRhgLTC1q78WIIZIR3o2HAbYjvrk4MdV3hXdiZ6VNwlH0Z8bC92Cp3cy +R7qWtubbmDYG1txiHYNHbYtpeu8HzWrUnEZtaKu/7KXb4cfg0LdnymmmGvVMT4+WYFnSn1bSU4pB +Zb+7LE8tUuOTr/3PVONgJrs9SSJ8lOlb7rIsQWTQvbVsaQuzpE3Mj3akyWuhuWu2fGhHmW/qXIOR +CyYumLfgToMrTd1oCp2/Zc4zBcznluuMrjJPKl1LiyITiaJB45+SUHqfUtqTSndA/OefmZurubia +eysaMH52p9btAI+/HjKadTcWXVjCo8Ims9nWddUcV91p1V1Wo8MqdmeV5bOcz+Sz3Lup9k6qC+6p +zz/bOaguuac2zqnHHFNS4wXH1Dmn1BPcUBqH9NRy85Rip3N8d7lk0DopzOL5Scv/HjX+wFF+4Cg/ +cJQfOMqnq/EHjvIDR/mBo/zAUT5djRs3+6NHHn74l/Tel5DqvNKZntbCtDVZZiEopWR1xs8TIsjO +/ME/l3OO/E9abfPpI4fPHA95vpqE2208+7uv/A55rHyzzFfIdXCI6WqZhyRbj1yyq6FIxTkshzBd +xbCWczXsL+k1lHIOjDDSPx6PEC7gEQLwCHHAI3iet7sdAPt2B8S+WNpud317Um7er3hNe8A1fh7z +/Jx4qTxsu0NjJgPI3zow/vTgrnoabzRYMMezCcuAkRtP9xxP9tyVv9maxqxBN56OsdvXbIb46GxH +bTPifs057MZ1w254Dh0/Z8mOMvIznYYsKT3TTx1y/AwZfj7JNVsmGJeqTKrEjKPchW1NiVnuapoj +M9pNOa1TOPPHBSjTp6vTwnPzFGZWJwKZ1gvPPiCm07wkw7MakjUKA64VFQwv9GEV2NM/SWs+ff98 +POs8zzjDB8Fm7wzAeeaULIfMGmyTx+ESbPoEsGg5AYueg7nuwLomZPDg10efcL415yG0m3bZ4U+3 +hr/+AOjod4IZwY9bQMX3ELjBp8gTLGzjO57wHqDM7TN6aMgp76kDMHHLQfbf/HWgjfHseoj79WDA +urDL9jsmwdKN5c4z/Pb8vnk4lE8T0x2ZVcfy+Q7xkT2L7+LZe68t7tHnNZ1sGtMdqHhmKqHFIEsr +XW5Hi9e+M6hBhy/FIRIbbjgRJhaNt4b/AVHVdxZBHQ1ImemOG+Nbx9R2ug485c4+6c6YdicQWTAR +b9BS74zJd4YAHEvAcyYEx89TaQE4tQXgfEKI8YU1+XSI8ZmZ/775KnbL40Nu191MbpwmZKCI8xyZ +uFNvFf621GXMljo+8H3u+uhVWM8vw7rPAuoJ7FoKuzFPd4PPmtjWpsNJXvAG6e3QFYf1+j13Dgae +BkBMv7vdLz/tnk2KyBtzeUeusaM5uaOtJX/OhZNTL+R7+iveMwrN6JoxInWf4ehcjqP5TI4jy29E +BairPC26FOPZYkl989tc9R55kCyO9HbDlq4xVnagU4vtbJGBoUcG+rP7c/LZp4VHsg== + LvkTOyuUZ28jEYPNrMlZoo8XzaNBWMkdj7NaeYxVPM7Sn7dMmbrImwR5Lo6pWmkKjVILjKAwfkZh +lzB5rjLbssw6ZOXAEVNHmYtFeH+URXzPyMJrHh2F2eEnl56X4J50KOx3Bt3YuQL7UwXSf+pnD2tt +SN7ppxR4aEEDuF3igFseyJABxrJsE3rOJsn0AIAR3j+C9B0W71wxbsDKZ05geITX7rktM5P1IIoh +gOJ8CMXi7S0bqK7DOoe0qXmTbaO/4yWuvufrHTKtYzHCFjtAsQMRT8M9BlCzpRbOI4hql2SY4KkL ++0c+2UEAjJKRJSQqEwp1QwhUJOwJYKc7ApwS4UyAMAGwFAlKWgk1AoQI0B9/u/GU748741uPBSYk +9oMPBm5nbv/wdh/5dhsBdJH1EGh5mKeVlodlmhJEyStZMzEzEE1zlJ3+0fO4VREIx4MiPnG9JrKm +KTCrfF7mmTnmpBelhymOFrXsRBwgEM784XUu4WoVdX58109arxmLPs743+qcr7Bdfzqnwq5e69cJ +6WfRbGE2bFuep7hyiKalavt5cMSZP86rCZ+oxo9VIdJZDSLt/QFMhoVkTNUS/d8zyX9jnUjxf29p +lsDANUO2bqd3tn1GMwBgg0Qc03XPfr3JSJ8sI/2Yk94P9BmP8xmOR5O1Ldrm5mC03ZFo2+PQRlj9 +9ii04VC0TYLJx49zfFrBaa3vebLWd5W/hRrdcKgZmreRZjAKwhRIIdHEwyYaHj1FWWTyv8KM2Te2 +0WusvG71EAQtHZlnnk+Wgq+Zbm64hdwbYjrQaJM8ZR5x07LpNION5rWaLCFZoMkGAIGWXa9aGrse +GtZhyYMjaJ9ubn9wPVOZnS/5bEm04Jwry4cWHv31Scv71+hzpGfXa1kH2zkNej5sS2VZ7P91oLdM +3jBFR88CHuixGXN2j//i95gHfRoyoo+xAU+LIfignx9qfOod/WiVSZbnjagBOMwZxzhPPLz5yEOb +IRcGyoSQCCEPQhpMPIx54jHMkANHKVChPZekwEEOdEnw1uAp13bwQDs4uR07EhkY0g6lbwcq9IMY +xiOSxwPk15Pp76lAmdD+/JHI33k8+/mjkS8esf7BR63/zUwTza+vR5pn2nxGSFy13BSamcKzUjx+ +YI7ZuLrx3a1bG8P7cch71QzvLffVaHqf60SxaeLGcOdG+FvLZno0Y/y158RqZvlqxvn2M6R85aFD +Y0knJV4o4XzhASvnyvyhhYezf9Ly/jU60KO7K0aHRXNZzCfwjwb+qJ4NccyECCEzbLIg9oz6T8l/ +uM2AyNxuHiIUvYxhRlvE3C5k6ezxrnc85OlSOSvpfke5cQDIJyt/CzXubYj/8YL091LjoyqJ1Hj+ +m/PnVZzm2h9z7lOdohP79PSK5SSz6Da76HyyqtqaOvLM7GtzGVY/MyW547BnJzqfn2je7QJ6OgT2 +gUhfwL1Bo9UbEGW7v5cXP5LDL8LTQ/U95z9ekP6oGs8rFumCKmKKCu3X23Ki5OxybY9Iua42uSol +/LzlCG87m+YY151HxSJNPXxjAPMjFbhi2R8TZcJAgQyIC1HDKB/eWKbHYuBy5nW0bI6wHSqYHJZD +2A0nAsZvROVUSVGthSolHpkXUSVEyoYmEUIShPwHeQ9S3jUVFMhr7nv7j5eQ/tPXuFXtLOzbgJH9 +WKzo+Kbx365ENuxT9GOitmrqSnW2Kap1p6iWjYprZVBxPrJ/Tn7+SjU+rlBcOkLTCrX105PH9ieH +jWqQq0cnnUl1SmpcTcE67rCtfg7ecJJdGCBw/eiL6keIHi17YnNnjg7Nx1yapzksewZLPX5idXfV +NiPbDXMkBVqqcJADT8T0Y1b/wwXpj6rxgspxoZiiwmwG23Kq5GyVoEFBOncAhdToB05YOVoWmH6s +xN2QD2bynDCPZYW55MYdnbjL5mzJm+FcyUDHZ77W8ySvLXNds5YHs5VXOh5vaCGf6XrM8sqwiDsU +5j9ekP5eanxUJYHL430yP4x49c0Z9q5KtaTzO4VrVMW6gtayNnQ1bjF/RemHO0iNqx/w0I54uNn4 +MLZejHbIQ4cyLuazMC+FiNYGaTw50jkpPn5znPPN3e0ZNF0RRgXYm3AznDvtcLjmX4SlIGfzMJV6 +hWOqDyVdzbmMDsGPq0edankKKyHm0xwWHvUkzHTOmsczxTXMhHkDej46Eud4SOVKGPbwOh9dlR2v +9V6tquUQ0lXZvskHV/Gxjrx81pGX94jcsxid/Zb25MTAKZ2gdfZ4nXk4JBjJvLZpj9vBpe2Eq/Zv +P2xze1xpl8ni/vNwxOj+oNG9OAEJTaSz7UHTDbb6/qBV0zt3WXFlOLcHdvcs/BctkAbEHc8CuR9O ++js9C2QdzujbngaS/DQQeZOLJ4J0jf56sH2pnLoPAhSdiefXTaGW0s5rWyZZXYHhGKIHrSO+dZ+0 +9/3vtiPeZL3QHy6zJIVit9YW7LEqgPcCHPcDbv7olXgeHJ9/QMdDKPwBHf8DOv6vg45f1rPrUMjn +orbmJ0RtXT7uwBTGT28D2u5RT5yET8gBP0zrfmbVrR0U3M6t6idXVT+5ahnO0epn3fKUrjN7xnuz +3+38/KDb7XCOk5M7tlPx0gUfO+vKeUGsnEhiblAJm/M8T+LrHjlmY4O8vhi/1+Wh5dy8Hp7QzCN5 +GyH4SFxgr7PuYgL3R1ScvPPlaMDLE/syf91M70d59lO59uOL5ml7wZOOYjh3DPEsuxoVGpnQ0A5A +mZZ1tflv3NkXwv6M3P0q+ujKvpeown/544t3D//lcHz57Pm/Y9FsPv+1DqQ5Ned94JE0n392krK4 +JUBvCYvHZMW3fh7mNvl5S1J8Q3DZnSUoDgNKfxtFcPkAhvH4heMQOfAx0RE3w5EKjI6gFPuB8RFW +PGeoJ/bcG4F2Jpzv+7ifE9PvBx/4wyRFl+dMS/qa7VRVnTU91XWTr3u6a8jVKwMkmmR9Z6f4PiGF +/i7VtRk0HzVmPi0m5czBHh8albJNCjEc7LFPC3J7PsXEk+bEhxymNH2q45TGI6B8Rmyim+i9HGfE +eM5umw9DAvRH58R3JUHfpkA3Uze9yB8TCbSfHbdDzNJ7xwINc2WYMXZIwflE/5uUIp9OGm8y+V+x +xnMOtXOnwJctx5MaTzneGa3lbBrrbRJri776/LOPjL8qGoHV469kln1wBJa5QY5q8aCtI97Kri4L +ZZtA5u58Cpnv7TytD7Ecnj1Riymzn2w7dOxiQy629H63PcGf9LcaQpjkz1P83T4pyd82xZ/FbYnM +81GRWxo5bYhdRm7JLPvg2C2idYHQWAylC3wu1tb9LtFPOZ8O6Ic58cOc+GFO/DAnHp0T25Rg75Et +6zT31/vf/L2atoTy5T+8ef2rty9ev3vx+g9ffDGq7eM3n3/2D1/zu6jf/erZu3cPb1+LRn/98i/f +fPMMurz9dVjXq3UJK1zAaVniIaR0NcnoHMK8XMnkWvSNr/XXv/4Zv7/VD815+q9/0c//Xf7+X0L9 +s3TF4ZeHf/uf0+Grz3nXr3FBe1Kr+PAK1JPnHX6xIbf3+sVYxVnitoLX+Ocn12/f3b54/u7Fm9fP +3v7l8FM1iPzk+ObNS+mLn1u/fHn31Yt3b95+eXz2/N+l97787YuXD1/++uH5ux8f/gvu+D/xj7f7 +77/VWm610f+ocyXgyEs1hM4hc9YkmS3VMkTagcG1nXmZ1jrF9fCvz7SubU/Geb6a4jIfcr2KoiRY +R0k7g1R0yOvVIjLZQVjDFWrLBccTp0Oocrkwg0POV7OswMNz3lbzlSzyeMjhakFwrWgRVyks9ZDW +K9EfcGDycjVHuT7FK1mRod23Xk0lhkOUbwurL3xcqFc5wOVQp6u84v5yFWEE1ttKuhJ95hAWhD3L +0xZ5igilhxj0pUCIwrkOUZohErLdJtRZNJyDDHudZRYu5UpE1hnu/xXht6JTyeDmAEKItTVumaTW +kA5pucLxVIcgnTOvMjPSfCVNwnvYFTFfJb9rvhJpd/Y3D0u+Ej6ZNWEeEtMty1Wa63qYs4zssrT7 +lqtVuNEBz8C3eKlU1nyQ+mrCSdA5ylgwElgYkt8njULPfTFfCT9Dj8V6NYm+d0jSlcIshSBvsizC +Csh1st0nXb9gYOZijUnCela8uIx8yvycCt4bI7+2kYtYEGjwLMz3gFpEF60HeSh6NMSk45bylbC1 +Nm5xvpIPMucW6d9Z2ib3i7qyHJYkA5jlpVOQkV3XwyIPwxDrfTL75rAcyoKg+MquFG694jbZw4Qg +azWKBnSQzivC0/vsClgTUhniqg9xkiatMgFqkgFfD1gDnMwyOWV/sJGTF7taJukJmYvwiMmswuPk +MVVuz9JVUSYeZ3cJOgH1Phlp0fgLI9zLgtko19clY/FMGbN8v+Z43+91jd/q6NermqaKW7huXm2o +Ms+QoZJTZ62yXmSSoSGBHTH5Z5tJ8narDJxfJGspDXXwY3uQT3XQZBqvCy6xGmTGiQYY+nMaoU9Z +vE2/rLXCK9o1qzc8zvVKuI70ZRQWINPr1ZaadIJFmZ6yjScQZFMuQpDVuMi0bgQbO5lvopwOlyV9 +cq+oEex5dl+jhivRg2XsvKL5KsksGJ5nBLuvvZZf1l7cK9q1rzf97/8J//7Te+whP//my18+k234 +5s3Xf/nyze+5p/zs7Ztvv7ZN5Pwtv374+uHZu4evvpSH7Heb9fCjHx/+9V8ubDwyU/IyEVIl0slK +l+0kTC1yxxE2VUIed5yiZ9XbjpPqlfAt6Ruso2RzuVORGgLeXpk1scZ4ED63VOHCs3BfXoE8yyI3 +ao/NwnDCqhNW75NlqhVlrd4Jq12h9zXqPK12Y8DGHoUyL0YRziib+0DRWxN43OZCmdB64VT13Zyy +VpUL9M5GFQ7EBeCtruCH6+Gkb044gcw96ZYivCpI/wrTebWliuQCljYLw0wiRjeWNmNPkvGxj9YO +5Mhe+jXoyijsyytxgj2r9zipswxsxbNaPZOuYn/YNKzq/kZ+VXtnr2fXtP2S2E3CGIUbA7o3yVZC +z5Xsa/Ni6bQnpn+tCh2QP9Yke7xNwSB7rXSvMNwE53E2doq1HZgBXDZXYVdTQrJYYdyYYtjgJ9mW +ZCvCG09zY6eTcHFsiNxVwNRm4fOi/BzWJBtxlQ1SlvoqasRhlf1CxA+7D5tFlP5YhYHIHnHgLjjL +y6wiLInuIgThFTI9seGsa2i7l1BFu9Jdp0obAoQi2d3QsSIIgiDXV+lQYS1TTO0+oaYgT5dNEgZY +Pk+0i4Jdt6YV9+165XQbwqKZ5BHy7DzJE15tqWg4tm9pcE6cbJhGQZghjitvn597Z4um2C8SyUDY +xFBJI9iz7LZGldGWbjh4PQWdnJb+tEaw+/SV+lXtnb2eXdP2k28+XH/9CZjfDAlUhPVCwch6sFOz +jJiMtEzVq7lyc6iY0uA0ohNHJxgPyyqf9MukMxdIRF5PI9jj7L5GLVfQ9w+9IpG7sw== + TIX+PCPYffZWflV7ba9n17qhE01v0078BGt4lomTSyC3gjysHQmFA2O/yCiJqDYLz5dtmG84l4Al +LFyoyCqVNb1isdjskEm3QgDLMvgy80WAvgpYZLIklkkWy1zh+hYhuRG0Q6A5TEu/SpYS+XuMbWMw +gihA4zZgVBF/FozDDPmUbD/ZfSJQ1YLtQ1iz7wMz9JASReQnI2L9lIuTjiAE404JMqGT3+pkEa1h +fuEOtWKMwHbhqzmg+lWE007RW2VHFpG9DhfKa5acEjdIKkQDRbSPdc7t1kYma4kyIaGBsQlYyFmG +SlYHMAhowoyxai8s6zByTsuWukBAkkG+ignbkkzOSbYTGV0wbGybcxm6KUwyVoEXmponbFjuKAsv +LFjsMvMKbpzWYZ/lNJgnaEIAnQF/PUHDKBiGkqBryXZeZKmBR9dpbutJPqVFXlGU4iiahbyq9KTw +1MM66QvsJ+vptg5dhDN2xqNKk4o6GWKmNGkBdyvKIcjcZ+HnSJPTKT5XUsXQ9AuDdMIyD3U5wZ5p +dzpZuiOKkjbUJeLsIstoeKhR7FZ/O7/QG+CV7VvaO2Ne2U2RE3zKwaR+jHPNmNyNLGq2yPHo2Enm +wpo3FBHzavChcTLWWs2HoTJZIDO+6k81it0ar4Kw+vFC2ZCBNBsqc8r2qU721/PKvAn7tg79IOuG +fSRqcqzy5FdbKsISMlZd1O5OeB0RJWZRNyKmZSM4l0KGoH7ZUnWEvSIn2POet8mn1CjzBQBsryhY +q/x5RrBV317LL2sv3irat+87JL2PMnBBC51gqhoNWuB+olC4PQvKRQbmtBm05iTSm6hwW4MWJFsR +wFY3aKn6IbOpGbQg5sp8S1uDFmpbE0wEZtACL+XzmkVrpqVEeMjGokV2Cp7YTFrS/CuY1t2kBUKQ +F9pYtOaQIAHWZtEC+41B+qBZtMgZMfIbixYZK+xXZtDCpjIty+oGrXbBYM8CR00JO6W9twi6MPHM +bs+agyyGui5bexaopcqO0OxZLjs0exaWHUAHW3sWWDM7zg1asrJg0Hd7FlYa1JONOUsWZMaoNGuW +sIW6cCegMUs+xoR3Hm1ZYBRx6sYsqSMifMdsWcLbOWAbU5aI6kV2GrdkwUxapROaIUv2j4CX2tix +ZhU/uiELfThVESObIUuefwU/xdaQNcujudCaIWuW2ZsB1W4anfBjTuKNIWuGZlxWt2Nhq52qNKzZ +sWaRwTmpN3YsbGqUjJsdS54sW7isqGbHOllqp9scA5rmtLVjObXZoDA5KiaTmajmwOSSGzMW9rWw +1H7NDLMpbH2tkkbYGJc61WxQXk+zUrWHbWxZ/kb9qtaSVs++aVt2LlJU2tqyOtVMUOCbcc1uoxKB +FeFp69aUBZ6LaKrhskkf3OtphNG01KlmgeoVmY2qP280Zflb+VXttb2eXev+f2XJ+ggjgjCAUCGG +TonnzTRXiZFlqS/YYtzFIRs+oLVCmNUgDE6VczNmQ0VJ8mSwmXWCg0A6fl5pR8jRrKXY4OQCYWXu +vDDfBExKeZLHNQeDaCxcprJhyovPixPMLwBhX402ehkM/kXYeq3m9WiEdcUT3PxgVCyTacF7ytYn +LEk1DgoysA8HRmw0irWwivoCDu8XehdiVYYyUlqnnhohyqQWV+wYIkWZCayThXmKPpHUukzHRgB/ +LWofF2lh6RTrQ/hIIJv2CwPcGENV+rk90Q3pq+oUk4i2h14NlDEOoT+vUezG9mJ+YW9Tq+ykld+j +jOQOCIjLsuGnndcPag85fHP74boYgANvfj8IuDkv7sAzx5/s7SJD4s7m+Zvljll9gbYusP+IrtAc +T833RyEx8hnq/MP2Ipvz3L1/UENEmvIVpO4/KM+yt4fu/wPv48u5AxB712BTax5A7HGyPQ4+QJEw +ZAqIwuoLDTYGmfc+lubjg4onkmTpbkBhhvJ4Lsl2DQw1qWkJvlK9Ge4LpA4GAWBwBsLGUN2HY95A +yq05hcEdCA9cko52f+BMgaV1kvkDqbpDqXF/ICRX2bfC4BBM6JYmNnSPoGx52q7mEpyx58qgdacg +LRp5dmcivYJovvp9mlsQyv8aMN2bYxDdOCVnis0zSG1pRTuba1AUfOE/Isa4b1B4q0hLbd9qzsFA +F06du3eQd2ZQmnsQht0+jZp7EPXVIlW4fxAWUuo77iGUHVAEvGZHchdhCFAy5Z3cRxjALmd6/8xJ +CCMEp+nWSwjTE0VUdxNCY03S6YfTZXrZUYhLuMxe7chVtnEAFppzDtYStsmdeE7ZuguHC+kNHKqy +z/bE0WUItiAS7dp9htCNaV325zll6zUcLvSX98r2rTzjOJSxljeY885zCCMPJ6H76MIs+3CZuyuv +Ebauw36Z+QSHmpxij9w6DzHSGQJ2rwu6zRyGRxph6z3sl/nLe037Vv4nkbqE6ZnfLsIa2SY49k0q +i/hetE5suZP55KDOQkWm2ZsU4YykuAarNS6Ic1qgbgjPTzDvCA9R84A8TCtrFFPAojof+4XwDVId +ALfJ2L+zMbQ5gzH7rbm2W2XX4lPl1inCRAQTLYSGk6ae6lMRGhosc3kaNu6BPOumhLpgGIcdeJ2x +DCMcH1hCjWJ6TlWlt18ojKlCd+x1dco0sKFOloZQmOuVJWEVYU7DUxvleRtUvl2/rjXA6zpp6XfI +Q5/ERQ3vEqfE1kcNe7IOd3NSw68wJdi1m5d6FuEJBomdm5o2a97aHNDgKzrtnBLzOMmcnNoka57q +kFObn+apdsrWU90vbB7owFURR0oswyzrZAxrHn3T2POmbMO17abL7uoAURqHQrzakbF5h6U7rH2P +bV5kJ2yd1v265o/udXWKPXTruOZeTBOBVwYhm/a89tBG2Pquh+u8AV7XvqXfm/saHE3YRt1pnk5u +mqfbIpvmiWlCE85G8wR7EZ0huOYJ/UxkztU1T9g2aHTbqJ5uRGyqp9sCm04Jq3iBEXSjekKfnAYF +FbY5MMimeLbPG72zEV3thNkcpi5XJumdjHAUbbROmM5Kwtv5hd59Tes87dAzlqtFjSNbrbOTm6pI +OxDtj02ZxB906G+1TtqZoN/0C+fGL70yp2y0wIFs6mKvrKmU/akb3bO/Xr/QW+aV7dt62Rn+Uab5 +lA1xAys4/NWvdmRwJHoeU3NqLqqRYLVNEHuc4vZ52lmHCyEGwI/YK3OKPdUZi5FXmCkUxqKVya4l +bG4Zntoobt0356pf6E3wyvZt/R594wELeAmqHk5YwaoFiDKylkkZA2WOEGlcD3Q/ROTEArsvBXIL +4Siro1VkttBrBjt/mJW3irgS2NV1gmoGL2yAf1geT9OgQzYCfKbYwtXsQxDHXCjpVOJ6RdCV952p +qw7GLSBw1lnHTFqs9gRRkwJvLStsE8J9aHRGD0uPtXkOM0LEM0RemOHLpVOukgI3espEB8wL/fZw +szs+VPRD2UsKvfcRF0ITzGFWp7kCkkX2F/kClIrjgTrKZJmxgkS1ZzOwS9UJdS1YXFUhsAuOHoJR +Iri3McCWP0GAgBkVGmWQFy/Lqu462uVhyQsreJ6oTjG6dg3fPo6EwttVHVaYZGdtGN2SpzPiVHUM +sCnAWiI3pZIa9LuTm5UC02iCtUT6pyAogVrwsnSCzZmoiKPhugBrxlhVI9gj7cZGjYYH7jUF3Vv7 +E8Ow2Q5v5tf523td+2Z+j4JkyAA3EGhQBkHSycAHEE6fZkUy1LYwMV4k5KspNBcM5lddYOyF8Yaq +K6xT8AtO7UYopQvly3kQ5yCx0moLYRJOd0xyxU5AtaFoiPXR1I1BhoR3CBO3X1jWBpRc9RGcoYrh +WDcyZNmRwSlVBZMZqkKvU2QhdRmyk0tscqr5+aSiK/owZREoDLNuJO1i4BoYGvV9l/a+8oc+tE7W +1EZxnlE2ZDVWYhuBsVLaw4dpZeuolIEv8X2hCGhTVxsaYEh0aCb4lic1VEV/Kmf7RKMA3HkwbRFE +k3RIdEGDx0a1T9Kc6ncqcynzFc2bU9BwFGifOrGkTq1KVkTXeWkqS9yWkln7aVDAhWC1mHGwvSkl +bl43GQiS6inNgD7Jg03W02l/ym0wPYHbQ5NotXu1I8v2U2l2ETkmQbMHvlHehdtHYisbxRaHdHgB +Y+0Xyl6Wx6rscxzthI2YcdrafBiqgSEKprv+PKPYjf5ifqG/vFe2b+XgFZT5S/8bZj63slc78qom +VMBv6LmDgSIHTMslKDzPKQbYmBWVNFwoizfkTWVOsaf6rUYuKgH3yuDehaG1P7VR7Nb2ev1Cb4JX +tm/r0A8yPGvGvizqJLGYr7ZkbOCwk3LVqlkGAwrLYalEcTjBOcBE/EK/LiHFYBzqckp7qN3qZIhK +dB20ygAIgRTTnmmfjXO0V2tX9Ua1ik6a2bsANl8R8SqHeonNQzyQEyRnxSWK8KbmJUrmsMoGsoZG +MX4EuwmM9Y1M6FpYll7ZQLGn2q1ODhAF62GoDG6JmMenGuV5e2F7Pb/Qm2CVnbZ16IcIl3RQtJbo +P82152TY9CDDg0NOS8iElVG6AwpapL+lU5436SXnZRkvJJyjDpU5pT3VhQkjm2GkVyZclTFc/lAj +mNOivVy7rDer1XTS0O/NWOCobmwmUbb8Ldgd+9nCnLMN7Y5taslwZDW4O6wesbpDoAHeoSrQJeWI +d2DTc6HF2yDvQYQGooF8NIh5h4AKWcox7+gz9bw20DuujdkdSAZ6p7klLamj3ikTMeqvwd7BdOO6 +h72jfQRkOe4dprgAxnXaRWe2K4OH4w8qdFvoO7ShqEqQAs25qwNe63h0pzz3/sfOMFxo0PahrkZp +D3WFysj1CqCyXpc8KxRKge2hjeLyY05xvM6b1arat/Oy6v9JcPB0zwXHu3ayok4a5BxTTObS2pHp +TjGLiCHYhwsN5N6rcoI90u50smz8yxQPQ13FzNH9oWU0W/vL+XX++l7Xvp0Dt4PxOEE4kLksam4D +kDhZ5C65FaGWgCihCbAxzubznHDYq1NsmQjDScs8XBhhLa9DXY3Qnuksi1SY9ABm6zVhbqV1fGSj +mDjY3s0v9Pf3yk4a+j3aPhxqjYVFhPkmMoDCHI2VLTQAqydHMj6LDYCyNESZtuAAuh/BHTw6ADLS +WkLo4QFOMdFI4wP6dQ35D4ndDPKNss4b1cnI5LaQqT1GgHKn6jUWJAAm2wV0jxKAq19VkQb+x0BQ +Cu2UBeYLv9XJIgdNodYeJQDQEoEGHiXgFJOcLEqgX9jA/6EYYKJTmkXDhS4jz1fESLcggUAnVFx6 +kADARkt/3xYkANeIGuZakAA8HrGY95yKLpSSQY1pQQLACRAJ4kEC1F4ijCYtTADVdzXGwwQAnaBJ +x6IEMA7zPNceJoC9BvmOmmRlcQLQ7pc6xAlgN+NLnM7eU0t0A9BjNGeEnbzakUWlw4HcjsZny9ch +VKARfL4Q3d8vswCAoSan2CPtTifPTZ9udQEUFsbwBKfYre3d+oX+/l7ZvqGD0tDQ8w== + wLGl2aNIG7jfyR4AgNVAH85AyWOETCfDQkZwgVcGiR1WgP5Uo9itBu4fLrQAgKEyp2yf6mR/Pa/M +m7Bv69APDUmPqVSSm9A7WZgbsC4OyhcZ+Goi4ryB953iPIsg/35hiwPolXWKPfV5m4JGns1W0yub +rHn9qUYxHuCv5xd6E1plJ239DqH5k4QNbCFxLW7AEXEeOOCQOI8c2ELiPHTAIXEeO+CQOHfYbSFx +Hj3gkDgPH3BMnMcPbDFxHkDgoDiPIHBQXAsh2GLiPIbAMXEeReCYOPcAbjFxLUzAIXEeSOCQOL9k +g4hzB6I3wqMJHBE3hBOMiDiPJ3BEXA8oaIg4jyjYIOI8osAhcS2iwBFxHlKwAcR5TEHDw7WgAofD +tbCCLRquxRU4HK4FFjgaroUWbMFwLbbAsXAtuMChcC26YIuE8/ACh8J5fIFD4TzAYAOF8wADh8J5 +hEF3v7cYgy0UrgUZOBLOowwcCedhBlsknMcZOBLOAw0cCXe6Os84bA2Pv0XCDWSDrzm03wFuLQJg +C4TzQIF+XYsl6HV1yghMG8iGYPPKHOXWHrpFw/nLDdd5A1pdJy3d7g8E52/RcAPZMGwN5t9Qbh4M +sAHDecxAv8yiCoaKnDIi0wayQdh6XYZy648cwXD+Yn6Vv7pXtG/jJZ21uzth5xPm0exLToa1oqiA +lqu+0tosPXXmw4xi1gVsA6GMFwoLi3EZ63KKPbQbJpQsiyzQnuKVmYgwPHUUGvrbtet6A1pdJy0d +FshHae771FvUFGPSGVDACF7tyLMGJ8HmI7JR1oGbouotIh3ETnFjj2lmfiH2ziWOlTnFnvq8WQqN +HDUieKgsQw7I41ONYrf66/mF3gSvbN/WsVc/QmeFu3Iqqr7ksjZptpNhTmNaEeDvsZ0Dd08VIk8G +OGwU0+RaGhW/kBGKeRkq6xR7qjH9Rl4pQi2HXplQykqvd3tqo9hT2+v1C1sTemX7tg7cKlWTTbBB +YfG82pHRy4ayW3O25C4zhC09q2vtFGsMID41jBcSQD6PlTnFnuqbn5PrQtBiqww2uzo8Uz/bbe3V +2kVDm6yafSs/1drcJ3OjQpoMnEbU1KsdGYgvmmkDmFUh5kWTgURI3etA6QtsmTcXTojzLGNlTrGn +uo3JyVRxe10wza7jM5Xg7MDerV02tEor2jdz7NCP0QL2zE5VQoKELCj01Y4MYF3UmPJIL6mMcQm2 +rycK8Y1iCqBt+35dbTBgr6tT7KHurTZygeFiPvS6YOYNeXymUZ435dlezi/0Bnhd+5Z+b5MUlhhR +h0SFQF7O5voyYtL9DC4o0XOWA5SRqvoXObF9tnaJnFhEXveLELFSy1BLI9izXPNXqizvRNd9q6do +eHp/Whnj4/2djOovbfXsWzb6foPq1itCgNzl6VTpsmlRZy01rhWzN6oHmNpxIxjbXVUx9suApaiq +SGhFTrDn2X2NimkCXuUVYUFBaPfnGcGdxfpafll78VbRvn3f14LkjjyZ3rLgGMlXOzJkw8UCjAJ8 +VFB5pqDSx1Rhmm8U53BLpJXXL0QnrGNdjWDPdP6m1KIY96GmalH8/ZF1yHUyvJtf6O/vle0b+olE +j32HhqxGcArssMq+2pJh0YEbG+pemlcF/1BADzThBCeYrAoPX8rDZZO68oaaGqU90u50cmBzDr0u +WotiHZ7ZKHZre7d+oTfLK9s39PuSkMFTF0vqMzvSpVODITPgXQYMe9a4QGW9NJI0gqmEESeilfE6 +LLt5Hetyij3TtUkjw1kDqEavDAls5zo81Ah2p7+cX9fe36vaNfP7maA09EzUm0R8KNWB2E6GWSur +kKYmReR6QhJl7LFxZQ4ao1jbmF05jRdOZmzqlTnFnuq3Gjkos+iVCUW08zQ8tVF8LPT1+oXeBK9s +39ZPtgkDsxTV4Rfx/asttbbUEIsZLRkkldSgjGMfOsWEkdSyLfqFIpwhE9RQmVPsoW7vUbJ0HfPj +9crCpCFT/amN8ry9r75ev9Ba0OvaNbT34KeMkPuOwLdP6N+sLbXbBtoNiBuBVg3ZLc2eylw7sBsA +NO7VG1x3RaxK7ahuWCAnZiAxUHfB4NDsOmK6ZVkI0ygd0o2sncAZO6J7QVoMQrxHQHdmuuzU8dww +1tKp3ODc8I4QfbdBc8MAPjX8FkS7RFxm7FjuDGQ+Fc4Ryi3P04iGhuReTEdxIPcC3APsJCOOuwCt +FtcO4y6rLOoYO4qbkjaY3gbEDVOyocYMxD0r0HLuIG5igGCx3IK4AQQKk+Vlo68Rwhxl84bhPhn5 +E5tnhQ2ceLgRwd2pZlRHws1SB1w24unjCX67wD0B41OjFnnFaulOWVEnjFDqTjXIda/IUNn9eSN6 +u79Wu8xf3Co6ad93OIA+DqEiyugKYMMGuu3kBt1ekUVHPjfkNnwe/DwCt+HhBjdquG1h8LJv5g7b +Zj4gssYRBQCfDRWZhtrOqz7MsdhYB+jIDWRblvzK0KhGjUgOOMCwEc61x2rHkTR1gPa0Q2ZPHZIN +tDQAVw2RHaDu7PHY0N47FjvYmzSANfJhmVTZH5GyYvsbEen4Q0wdhJ2slg0E2xAcJGTrX8deAxOB +/t1CrzFTS1o78hoP4Lg04DVmHKOJN8DrUo0dGO4aHURLUoNdM0VxzjvUtTCfPDOTsYGuYbjmZQ1z +XYsRNpDrmfkHoFY1yHWfnA1yfTpdT7gDeFfCcG0Q151qKGkmkxrA1aWZyTZoa8xgSn1+GeIJpqXX +0wkj9LlTDSLdKzIUdX/eiLb2tzJif22r56R1vf0w9OWcd0DrTm3QaLOqO3gaQQ1lj7EWIZeRNR1i +LfvzMlbjhC3AulEbJLpV5Khpe9wWXG3v1Ij9pa2ak7b1ZkfGYw8Q51cbaoNCYwni4E9HS8dkyTI3 +qGrY5uY6XIWND6KX19MIG3xzpxoOutVjQGl/2Ain9ldqF3lLWiX7pvVWI/0WkzVuoNSdauBndOg8 +wqYB+skjYFoFiGyBmH5ZUq9Or8gJI5y5Uw323CsyZHR/3oig7q/VLvMXbxXt29ebDjsU/PQb8HQj +NrSzrBfNw9kA0TCOMb/qBjgtjE9DY/0yEYWmPGCwnbCBMHeqQZ29IgND++NGyLS/VLuotaRVsmvZ +JQcfPPyBucQ3kMpObjBIBPrOlMsaUlL28Vpq2iEq4WKfl9KpFdm6mRveanLCBtvo1IaB9IoaTNKf +t4FT9vdq5P7urarTRn4/Os1HZf24+CJ5Ovzk1w/Pzp2Bc/vi1Ze/enj7/OH1uy//x8NfrPZ0+MnP +X787czl+PfvdywdtwC/ePB9usvix5eKzeM7Ov7z46t0f7Y586TG/evvwpxcPf5anvPzmcs8MTZDX +efHwzfgyFy//xcPv330pQ3D/9s3rd9959W/ffH1ycYR7TzSqR9v53x5e/OGP757a0F+/+fM3F0f2 +7nM92+nu9Vd2++dnD3v67y/+9ICjnvibah6jZRHnG1dVIeoKQKfM6lDnaFqy/tqc9GRw8/c98ak9 +sj2g47c2z9UDm5zsL/iLsY7z1G0Vf9Uzn2ggl/1kYnbUhIPUoOXUOUx6cHdoB3enbfKcrDHbyB2Z +PPs8qAhrQdZ4BHaAIPJNAAGnr5HAlpLgaC0oH7VkUDXAG7gnVl+baXgFNohcEyrWjUpCs4ZXy1Yh +HasJeiJ074LkGjA9yvYuqhmdPSLT+bkTBaZKenem1Y7nYDiOEAJTw4BQ6ROK0QU23jaRmjJUctQ+ +YwMjhk4JNZZVCTH01ulJA1EBBBC5aGsGb9f9lzIIfB6yL2vbZFdfc2ROi5U9ADArUnIwz27Uzwvz +QAdEmrW2jeS0zHpjTKtSMkclI6c2YWw0GA63ZtQsVHYPCPQU8Lps4XFFlc2UljZ6SElf5pmHsGUN +dkc7kDyEyhfFcHwrXexCLCJPmNca2b0WzTCLy+YpyiOywtQ1S5xoWiV6qMSyWPw5A5HhpKSZuKhk +onFWC/Bss6ZuYmpf9zZpM+bJBmyZrZMgizAEkxQL6oILqd+aqAnPODcvmSl9YW5jCCqrPXWlhIQQ +SLfHQN5aoqpaxA0QVm8aeihqQ5/YGTOPA3GgEw6QCPpyiUarguwBsH9Mi8XRwczGBky027XZA9Rn +iTrCsVYNJK0JozPBrKCg3MjoOaQgmj3lNl2QFsJWAizGQsn6kUuz2uIhZfGXBaYwTnZh5mV1rirU +iSKq4GAc80hKjn4URIW5igau2J6wIPYrcm6IkhqI78M5kZj8C6ydN35nQrYZnk+gqf0iopjhTk3M +7AcjH+YeMqIuHls46SpfYYIjJnHSQF0At2tQ92vAHFQcZhjui4Epn0sOWju8ckQOagClyHGLfk7u +lofXeyGmMxX0JzyZq7zdmizFANpRM1GYeW1DyEwR6CU8DSyMwVxIelqZbsXCjMAKlrE/SZ0izyTj +FAGBqS9gGUo4t2225B0gLPMQRsZOA7UopqlItayHOM05azcTTO/pPBiNtJBTxyla8EOidM7wL7jA +ZQehugB2YI2LGusDFXuieaXqVTCIVAPpJWYLRic35xGpiA8sk645ECJGCBaetWqiO7BJfF68TybL +gQBqtNtEuViH2yqwNrNX/LyNAfcRBI1gRDHEC9RoGCJLVnRGQWh7WZWHW/NmfV4pOkNpFlpnnuIV +gFyh9Qj5FxDmMHkeT1Cx+BZgIpnMzzY0IXAf5RuhIhDG26aSWBlzRsrTuCnjolgt/hJcAPV6VCoS +jcEYVqaWGVMWIOY3A5U1RUBKgTZGnFDauFLQ7KUL0EmzOmmxCSLNF1kOAjLwVBiXOzMDVY84ZIfT +/o2nJ7oHigFxJxJwcGzn9qVUZpIvdVUANBYbbsOeo7uETFshrGsPl7JdU35rhCas6xAVcGxPmtWp +xIy04IuyUytHwThXGZ6KHXlV916FAFBWO2JhQUK/FV3C7KS2VxebPDP99jQ7p8yVoqwyySxF4mT0 +f3RvIahRxzZaxj8GrGIYEZDKPH7YUZeobMzFibXanABTIwFbEmqnmztVTUwiBEYd+eOm1RwqNLYi +YAYWHya31dfW056Qyl7EKW2cdKxOk1mxLTAxMuIY3sakjpq5arbxZennDWRtBAzWk7pluMcV4xcn +EuSJlZEyArZRYXw4p3fIahB4UCogutz9A1Nt4vgDTRAgC4KnS6bkoegLE5eRSn5BwoSAr9nkKRC4 +xGbl13afML2Kvajabglfy0TsHUI7VQ4w4VMJz5saoPtuuwznPHAtZktEhNSRIjDCboWpcdNuWwr2 +klVfhih5iEfwoi2WkIF/BDTI4ySWSWcgEuqZcDKBRw+fZcYvvGv2rRfycylaFwWohfHCiCECTFPl +I81gK53uMdT0gWEHQkg2Njy2FnsHnXFh+Fx1BF2kFb0i4zSPzKj2DNBY4pETsljV8kUkRUwKw7PX +jHo9LHxENS80zAYS4qrHytRJOhX3TX4YAuILJ1k2zGFU9D5qOkIgV+V9GKWYdK+05g== + yWvJzgyWMmGEQFiF19E6r0wnKBfBAq9lEPR0YUJUymp6W3naQDWT7QJJuXJPpV/F7+PbL2trTtBN +EIRs+RMyfM8gTF1eLzrHkNk5W4qmKHMcR0QwpQIWOGTCXDUn1k0T89nbeW7JqZhKU12oZHKJoRA8 +rYMR73af7H3oXOoT0dCnSL6FwDyekhSrcYZZTbHP3bBQyFWmsmpirhD1REsREDSr9MxNdVKVx28j +wgnbU4YVnwTwYuL/V70PO06ZtHnG5mZdCtwo1BxMQQQeY4C16dhGN2FFrtHZHGIg1qR7aKDXqthb +ViZmgKsr4wBPI+jTZH1zF/TLRJBI2MbIlmpLBYHTHEZZksdFySTBaS9cMeAT2PkBFeb+2BKAISPc +Mp6bVoKwwmRDzfx9XGkIUp2VwHzeiAKEkOf3rVhYqR0VBAIy0bB3Zs15WJH7GoTqURqzyWl50teF +ERfvS86xaiJCZrQBrwaf0s4UkXNBCjJ6GSetXRgNDxyixgyDI/V/7OOdawYLAQeVCxRpMbBgQKgt +YalMue1uDyKGHChqZj7jVYGEwAQkqEd2HBKq9yYSQ4DdYSJDNcUYL1AgZYpT4ukEBGz7DuzUamok +4y0WnhiCqY5YORXb9LNNaBOv/CJTc5o1oBN4Io/H3RkVtg2q8UxxK5UnqIfYktrMTAZzs6FDDr1E +qvo8RbksgIGkoBk1MDMrtjJ0CgbF4QPUtoUamwJHfQUEOogwxWshv2D3+X1IyIHKoDbwMyJOMCia +wQn6hx4dNDAxpNiAIAzP8rQYSjgxV7pqVzQZYSUy5WhsUywYT0OKFJthgUEXJtFjhdHCQFOOPw7r +DpkFYctZmlG8qmfINGZ6rvVxq4cyTMR/VFIBsCRhkRmFFPdrUssehxGxf8MCmgE0QOJt5fx4T2px +AA1q+gSYqBC3uwyaAEZdNYDSZLpZjUc4MWlWwH2A9YNHY8XGo5Pl8cLOrKwc3BPxeWbhwixMK1Mn +aqYVn5uibFHUqpybUUcFWPKE7sVtM4O4cDrU2m+jZEbhK2rCN3ZaaOYSTPqZOerJN4xFq5iAZClL +8+gx6wuiFosmNiowYmGD71ylUZFHmCYK7FNBj17i0LGP8LaIpM1DuKymEiqWzw4E5lYsxkRBwFAU +Vc78Nt0eLQEKE/pi/iK5KbsS2+OCqV5U2LL7IM/B4KI6GTA2ZBZwwDapfqHkGVSH9N1VVyXyfFmq +Q2h4iFRuaY8wndtnV494nLxfBJVCdiPZO9S3rJ8RUpc9oLIRs5odoIpVbuhrS0axE7wHBzhSdEEg +xM7AeWenAiCCLjNqkbnkM0+sVcQeI6TITej0K9xfVU9GNgSehAGxHOo/kklrzn5Ee1I0zXbyRqiD +/RDkJc+aBHVBf4GS46S+rAJQByiJR1uAMvkRnQkO1Lxub+XRCvqMmoyyap6R5MuEz1hTS0hiB1fk +ld64oFsesNqlmKmfu4M2NVaV7LHTU19J9H5qMDQtZ0ibnaZVgylYlz4UHIZHFLAZDIsBw47agpJm +PWhjnoLufLRB2q0YjtlqzDyjA0vMNmCaqElJNdimuQwPDbNm8CXXx3U0M+v7Iv4Skb4xKy6V8qrd +Ckz/arJJ0exOscL0CB7NmDowv2BH/4TcU8NGW1CMzM6aDjTwGBMk0kd/I/duJGh4HWysCG/Uc1Gw +HSRGFZvKDQqlYaDqc2Vm2Fk1RHtdjEPSNLXkqAwvIoACLcmr4vZ11iPbVikDTp8zDWTOAlYWi94q +/E/DJ2mBJmX1E+2pvhFEGdSxwXxJySScZBmCpikqspoJRtzgFizr+zzTDLla+OeM+W5R3BTO5kW9 +Ls+bzU3Z5KxQKRDUKUULIY4uBmW2FDy0hPqdqU5KplWNF4asPueiFq6WBRTu5tq4aKChGkuLkY8M +hV6JD8N5B4uG/3I/wrpgBWZBK5bblkdmMscWTH903UMWZMQ2Tpmz0zbT5A4CmFGTUSMDBmczlsNY +yL0ax6tSm56YOGFIvWky+2oxr6vJWtzuSzYKnw65fvUtDW6Zlj7VsoThjkWdJ5q+E7HbqyUzXyAq +aFPRA2BHU1TLAgeU22AzMMNUR5uu9AFNa92AVwE4WLlTwOoI5rsyX7F9roknx6++sCcmECogFrJq +1EI7c22HtgBHVXnb0mcPfBCwx67ZUojMmgd2NYaDNZ3XoO4appbV1iF5+ASY1jSp2QnzmkrzyiM7 +Vwbn0iREqJyzPfhfYA0DdZ412HfBPr6a3kYCrLJIn1Ba+iBSYeqANw3aJCuyk3bjkjRGmIZ3EuZh +XTFMjcmdJ20gZ8tqTkGGiBRZqiswJs1kg3WLxP+MSg2axj/FwEPSyOfRLwp/5uqz5Y/jWwKhbZnH +ASEcuOhn+M6Y7ABnVzL2249MQ1ZiSE6oDF2B1HZqVYPTLGmShHWNvGKwfwee3pmJtIEuATYaVh71 +RlMAA4ywfyDRCFR6Gzum42fYGXXD0PgcrKgx25aFc/7i6CeBjIyjaECdeEgThO26KgScH/my+D7E +4a6a7AhypNQAgeabEvvDIFkxo5RvybAdQRCgsRrzEOIVDjtaGXQloki9aqd7UjTW22ASSVGpMxNE +2VaKlB2wnSqBJxdM0dMOgigSAs9BgK2T9XAZJBXm+DhYNZovyu7D14FzPhQmYoN/YuKBChTzcW4A +Tnxbo15g8lHVHkIGYObSg2rIcaomLxFAXbjos5tcQAXkC8QMnwxyb02FnjJ6qghSQOtXtar3uzDM +8ONyH8nN+DlNuhWBsuRVz7XmxLM7IWIT9DBpPCjaU6IevSCrvzLpm3AHc4M1Fx4EwKCsTzcgpGam +CMQUWvADLcQ1qz5H65o+cTEDPHyjwjQrL8x5VZ8vbZxKieruDckn2sIDINStSlswK1MrzKRKGZ/K +rBSg9KfCDMLXo1qH1Z6aUEEwftCs7MICyT5ptTTxL+ucR1Op9OgBZ3MxRblauigaxKADVOfYcK/z +vKs5ajpVzLF1YpbApB5kPbMtanLSZW1bIciZNjeQyWhoOoXUyQuNIkJwJaX4XCAmYdbr6JgjhYcz +QvKH7+xUFxj0BPD01PTlliyE6SWxpQBsiWANEJj2NJt4h9O+sWcvi8bNGmtG3JOwO5j0lPPPukp4 +KqLdxz0LhLjEft8EKQXU2XaaFZsYqlc1dTJP2TJoOswNAVUDVp8c1TvJKYVTkJnqDX5A+F4ij+9u +MouZeWkXpQ+TtmAVYEVuYArURlCxAYlrzIWrlyHJBjpkmajYwdtG8x9S+E9uGwUVu0OePLlIkllD +Mx1PxQ5qpcDnNo9A5KaBHAw0FZagRjm7ip49ZP9HrR2+gJx7sn8Sd6qZwyf1bmW16wJZgI3OPpo4 +FFWEadcwUxFNxytDAu0ztELvi0abFQuEWABu06J4UJ4BgIAGHftsPRhV9+hXQSqSVsSq3i0n4IzB +vPaOV2KyM9wRZVE5M+GigE+eyzSt3c8KIrobtGyO+wVeGjjuNNF31S7GWVPTeBsS5MLUG+wq8mrs +VAQnI7PGqrcNhuyK0y5g4Vl1rjE1JHRoGFEJ8SlVFZVkjhG1JAAzBREgNWsKCXhNKMZVj5NM2FmB +5il+eA+oETjkWYPRQaBNOgdDVhdrJwil52tc1f8bzI1ZVnXsca+a9TWZrR63TT4C8CdOid4gPemC +GWcyDyinqbfaYoWAhbV906ZjwqxAuKk+blLbUwyKLAOBEid6xVEYJM4k0pPP2+C7YiqIotGeNIGB +sA63cVuHeV3T50yKCGBqNv0I4xCqHZyGC0SPFVY4NVTBRV55NpX6m9i1HHHoue79A7wHexm9UrQ0 +mZoFCYiKC94Hb5tEiK95yJhJYzpcrHFRbzdFJJxroKimVR1OmO39DPrFNnpkzaTaBwJUycSJmcaK +MlVLe555EWeuocTm0NE0OTeYGkZnUvk1X+lKVFjeYjisujbUlRKMESRLk9ouQ2QUFDgkJctVk19R +pYpkYKkzHdqxo+oX/CybA3LnYanzM7wL3IHdLb5GhgCpwTPyKtrKkKKO9j/IxNgNIrUF53CwZrNh +E9ukuvPMY+hppnYCXDtlOBFGiasBG6k/UQQHXl03Ct2sjIXa3jKpeztkHSEoiQUpT0JDhiCXMx3L +RQ2IrtXQC6ZWN3wkuII2TDh65xYPWQbPqSYuWrUuCjVzA3QW3QRI4Jk9MH/XIcGtpkiqzTaBNCo8 +gtQyrxDjJN2GdKYA/njraqEbVn3bTC+nV3HoeEQQhHj00uqHmDDrDVMa6ObIA9MgDQdTtoiZwj6K +K4KLq7Brxqlon0OeAKGid2XlEVpF+3VW//kU/XmI/5Neg5WHEmbzc4l0xylyIvbcuER0Phm7jDCW +DRJYCM9VXDIwIxauK8w9IbBw1VwWLSuA7Ne73BWwXGeKUfRCvnIqOCAyAGuOdAzyxMvUAg3bH476 +bQTXFnluMnCcgEJyWCF4Zl0qms9ipbOSm+iNS1tRRZUlMQuZaasIXaN0H3kK3MyNqNtjcYxRyhSb +FuYUh+sV753cRJnUdpo2FsqkFmCkjYbRhrWnyEhGsoEQDSlCQh2MjAXKAGonhGxmnsJ8oM0Xkjn8 +W9h4kFUz9+aZqAq5IgabkoGTlhsJZgdRAtCanVeOVGwr/AxRjSfjFctisYJf2LlKfhulrmAWHxCo +3oAAwxgJ88Qr6Dh73qwRETkteeInjU5Z0adMGAJVYbbUSLIkZ8cuwN5WcC6w6ZkAieIiZMKnkchT +H49WV+DOKEZHE+ehtTGh/9wWCARUhd0EZ9S0yFBqRwyrnkVLR2QwpsALaB2c1G3dbyMoztCdjB/K +JBTP8sZlOKlF3d5yJRwZPcomQN+qPCoM5xUwspO/rvpWAoZUMieHaJ+QYdasigXCTomMgfWK77yq +30a3O0Rzs5dX9Z8By4opGxYFUzKRKfyPIQ6WPFDB/9CPxDABPIlBw3l+dBLWpDIgCHVMlZBp6VNT +B7MdJGa5U2ArCdwtova030YHFgaXUGdAM7Hdx9kANjiaCLgh+N8WF71wH8QEhOrr7lAoUSMQjyij +YpZDLM0pD4BBq2vh5l/MLIllzh2vmFwI9l9diCpBOwM4sUl1HPqRozEdEGivJ8E9YqVQioTTmDbw +OikqTVid4p+RKZvIi0nXm7aN56VjNWcVeOCP41YAt/tigf/0owNlN/uRv6BCJAHUjr5EuO3gWCaw +M+l9WPi4ABKf30aAAqjVkrczfcESzSkHAoRuIj9djM1FcVg5KriNaDcIOUxbzo09OWKC692aVxUv +AfWGukSDBiLbAbFYACEBiAEQ+4ArC5onZ5kNYg3CqgRF5SxRQVLLrLKu3RfVco109TwijdjEvG7u +I9tizR23uSgHEGWT60i1BCBJggFQSlETTTY2dtOUCT4vt/MAl6KWzmXSPQQDTOUc8ObsOjGohUho +qv/4TDgPMM4UpiDKs546+r3xmuCdi6r/+Ez1wAGfIBRFZk/9PLHJlP3JTjcsVYU6Gg== + 8SY9JIz2hbyqocNETXNkLGbB1MMMI3NsEGNJeDHyOiRFmBgPy8piwFzowcMJXng+eBAmDwg0gIPg +NuYJ8FDkdkiKEAKBOgPqqZMnq+LTln7UIdLlG4iN/oHmV4D5qqnUBGDB24/mG8dcKJki1yHR6s1/ +Au0RNjBuMphgeR3c5ZAQdfo0KztTAS8d8ox0t8BZMNw7u2gT1P25GHoE0sCE3WGpTWLEetORdQQi +iPQJgMoNKkS1SmLi4LwXEgAOWGq3aHhdi4bk6PlssDbx8Fv1+dEsLK0gcMnM7sD1F84TlaLpUq6c +FnqiTcTsngkd6qyP4h20TFBZPQRA+Z3NEHAiJnZ73blwsx99AYDxLGP/48NPfvPu7YvXfzj86Hi8 +fv7821e/fvPuGS7ex5m1Q24gTiSzqNJk8KqRFacwT03WKpZhYjaANmUIPWdpGuBFNMElO42dVglS +FnsGkbSkTBb2Qwdb90HqoU/Mej/38/OYJpxyDgyIVP8axUSORfEw/TqYaIKlY1G9y/xgi4Z+3bT7 +VOdE5BQYCTWvuR0MvPKUmFmRgnQHxuAa22xAKPThpAKbgjmm0syYswHEd3dOurGCTLAPKYz5KS0W +ZNYQFVDIsVzf0wiuqhwC70+pBh5RwoDsM1Dz4DAuEnMXqqsiwOHKJNoHHrlsg0k7BQJ3XHfWQ89X +Ui0TndnKQZhtbInVwX0p5X4f/fHMqpj0PqKrYSAAxpKEws/cja11URMk1Kz2L6achhWlNNs2mBf4 +LjazjjGZLCoTMF5GwEwmamMT5HEOIKAChHi5OYYCJ14eVJ3kFj0AXC9l90n9MLjA9z4qvVj12fDs +Rb2Mi+VgsbNM6TbjXnfjOvCC6PHJZMEQFL+m4fHFHLMTc0FGuFn9vkV2xgOzbmAeUy9aaQlXkTEq +01mm0aROkxZ2zMn4JUREhKThMo4l/R/K0yjUu7bGyArsfTwbg6DsRAkBuh7rAbp3sZ3cbgMPyIQY +q/ZCHJsQCsCMPOIKJiupGFZHCGLWuqqIAG7Qq7JCRs4BBaxuQkw1/2ieFgAa16VfhB0XXjqRJtSX +DKllhmszDdJO4PAj+1GgJoGMGgj3zLbv4niBJJsCQ+u8acD/QxmubW1CpoNmqElA2/FHlVlBQz80 +DSmMgCiENZwbJAjAMOCUDcBAeV8VnoMMJ8viz6uKBUKiLho9mGakEj6tID6ka0ZFyMM/NcMTPX7C +SiFtUyXBa2KeQhuABYiHA8F0XpNOWH1civa4pPBnECrfKimvIQFODMgRHQMEKkYcGg8RS7wMvdBS +W6JmAJag3Cw+BpAqgLVnxlb0OnB36oZXn5F9FvmRcr3dZUSzHKItNJngbBE9r2c2j/s8hNIAzJWD +RsroZTEreKIYMrgTVsXY2H1GrVn9A4E+Came6AEsA52WcH2sfogxcf3I4zUbUAy5VGHhh7jIcDYo +G9pDDnuk7w94ONcB4fpbZkbm0WRH/11RSa9HynDOVx2AzGtW0Sk5HEFXBDLsYcw658JSh+kcvt22 +uOYZHpKpGQIgsWD9rbSb37Sh1hD+iVHFaOcUg96lK4cMclVvu3cHuG+s6plnM5AwPzKeUqVhxk/J +esFtHmMeqEgVvgCdqPgMBygc9WTmjKfSelJfNuhrOJoRU4rZB58gcWUiAChGDZj6WDXlSFctMNaK +ZJySwn4gxlFGxWEe8LPxeEecwgMzOGQJ411AXRBYo+sbmDP1iSNMB90bqyK5eQxJF5FgmVqIOFoV +bEwKBoZe8pnWYsQLTCpv9fgh1lgX9XcHBSNWnS2ksJ2xqn2NlAHsp95jZJ1b9ZhsIu0p52C70TMR +86y7vUNLjAh/OKEjhMQw3BvvynFEf4VJz9vrAHWehMXJNaunhoRU9DplpbiTWKQ5DYH4JHOkYBWH +dM/DIme9U01JgPSBB5IymOOKOlxnyhKrJq1dgjrcZ1UcQoNGWGiH77Nk4jyVQ4+ZXFRFAfJbodEt +bN0I3bim8H67DEcyM6c5sINkMk6BHrHWIbDTyIuF7mIKzuri16l4Ip9/elWAcQMMnzIvqWe9I+gW +8jDD/Od2VoUJZTwuiEC/pGKb6oktAo2gDebSNwsPQls1QMfOVNUNwI89gWl7hfcGk0oBreSikcYs +JVScKagpImK/j8axfp9pVa16JdBP1GVGPo5RDKoFE/VJf+OqpjFGT66Ut9Qkp60Dbp7n06j/Hn4P +2FErrK1M12bgtGjOJX0YQwdXvNLkuS9pBYpc7RpkSVd1pE7lISW5OcJm1QYsrR+BbkXTdkRa0XB6 +YR0fB7t45v6hyTyg2/S3rIq3mO3YWr0Ne1xk/nfaWgCQ14dY8CBieyJngiJB7a6qJuDVwiQAGcFK +zgwZDAwaoD0w0Obht5nFEpkrMsM0gwLhJkjReGyyQ1uZd6IH7yXDfCA0QVU3wPuZPjWuHoLBCU2f +cE9gADIEE3qGgz0hMFnkoojVZDYu5GZNPe4PxjjYlL6YrizBH1h0m08IouRzVQ/wDO1tuSCedClm +uGOspoXltYB9gG0cRa5H4IGxNcsaohSJcc0KDSIh8WhJtcv6fTr/c/dlUx+YG3+iaQzMdtE53y1r +HNXS0nkENRfNFqzFPHM871MttmaoTDrzQ9DhJigFrQeEUS3qky7oEEZDXgValFqSOeoBlojUGFRn +JJyAmscmFgJUWrmCxlCRQFE/6Em4rIh+GjXJmykvqWgNO792fhM7V4vFzBarYrz6pg2eWvDQB7NG +iALzEs3oSn87tJgYBn2Z/n3sMaASY00YQKQPp2iMirHxGLTV3eAIeF8M2iaPgo/N6lssQQbOvRjm +yqy2YGTPY/S8xypHfT2NEKV7lBZ7bV0yMSa2FDSwxkJPj2oNZRIV8HCcdjlNQ2oVdn1sofmLCY3R +VDpeAX8GsJ6lnzY564YaV4vIXixcBQSiLBDODGMzCC7z04YOjTdinw7aOoog0fyNjJTHGkEKYpgF +bPDMjUk2MGsyHK68bGH/wDxiDmaLXLVVvijGAWmBacZJiwJWclVQNw+DkYmcLQzWbyPyHFQNP1qY +uyGrR44fsV1mS69hdxUNV8kGgmY0EoEfLYNPsgwW0ZKn2NAFDbhMGnXDq7Bt0XjLc+7M2JvLaOaH +TweOI7wUOV00EAIIDO0CAb4dENysBmrSqzQuOpoMnkt/HJkZchSGxSOJo4bap3ZYejDkN8RX8IY5 +KguLlptCb4PMZpF5CiiaLcwhujnSUBnR7E9+HzfbFkFIAqFlpUXDRpro8Hl4nJ0eHpvZkWZfRBQu +ZnUEapvzuSq41CScqGZ+gAkQwgKJUTfv2GJ7F0Y2AOnkFhkKeTCYw5/LIHpsBJz1BnEjgfN7VpHG +76OZAZGJycJC+DYQ6ZN+JiggWgygCTizzkdoJSqNZsMoBUvHFDS8rHngXHxjzhkGIlWN1yT7ZjRR +MnzvRHj+uP0A5qKAE3NAgUA7kx2JoYSiAYZjmKcaEj1aY7Xj4WfLMDYZ1CmYOcRbp2fVrPq6czvi +PTR0DYPVk3JMTH2T3xad5ghgZpoSdFqlcmJiK8RVOk/UFGhjsJpzsZrXESeMK6KKvumedWkdJSrY +T6u+5aT23WqZvVaF9ZBAj7AuQ7+NuAbEZVGEBiExHbIN3V5k/x60AjBphcfTkGy59GSqYVLxONZF +vajcsUpu2cEmg89mzeVgW8CkLYF5kJFMMC9Cul6S+juZ+AIbHFNslSERGFcQqJYeg3Zk1J4bgQ69 +PKhHqJ1aIvzek+WApVOCRwPMeroCHYAIPnBkDH2di+abY6N50iW46dLCqGCFNRcfCeb4m9zlrJet +xbpFo2n7uUGzmv7cX0ixvPkNcBUmNSx/cIkD9R81e3vswsJqaNRqoZh0O4KPtctIAKdBPQ6vgAMP +qksxXZPHS6Kni3mYmWgZ35RNNppSKfn4VbgfTipCCTGnG6GmzW1GZdp8zPhqezwAGjwTrGaVuBrB +5Lyq684vWyeFySG8iPHiTpgGiJlTa8u6DLMrJmBt8W7IFQTxo4bRQ1zNTlAtcwcJkLCqHQ1PAmS+ +upVjo50gZZArPaE48TINh8fzytwJdl9RpAyowPEx6A2SAA8GXxTXSBM0uafOSyR8YhaulpNnNRAi +c5Tz4L6gWTHKOgBxSMVixFiRW62q2hWbWPhMDZGnHfhqXS1MAFRDWrKN+MzkkKtFwKGenqbKBBY4 +mXg0G5K5UfOBvY374mrLl8YYRxViZirWAH5BC5CjAwgTmXsGzJMw8lTzrNkTZ+V+1fZ93pfMVI9m +gUCJsVpIud/HrgYVi5mRdHgdVMS4zKDxmC2Fnht6GAOLRGkaXJlUfsQOzKwT7F81ehj6wRpoKdpA +VuVobcoZKABuaFAg46eXAeytr8ajYhZziiHGkIMXLNUWKasZSNbuhLP5ynPq8YH6D+NyW6iiVlPU +WW1j39y3wE4uOrMUAEsLYuhsohGsibPZUzTQnetxyhqKquJObdkqG8UYRTElxC+EzybaSUWJ8KVq +6CoAoWpPcLaqoYdZPaiJl7atMswYG2YxPA0zlnS0eDXEPdKNKM67aggco3opLhWLl+Q1HRCEILd5 +seGgdq1pFIOFlbfP8xgx0WhBDzEolicJzl22h+hrGgvoKE2ho2WIE8EKooLDBEOW6YO5qVp2DNhP +Sx3QR9SA1Di6asp5y5aZ1KXLpETkCbSx+sHjuej4OUoZWU80aaclquElZHnAduSujE4WfTAZawRK +naOAuFfu1tXm1DRtIgVmBQqADUD7U8VPL+NREcyoSn9D6fgXpkfSzCBVQ8lBoZQwmV7HXA3RMqEQ +o2Z3wuQwzUP/I2qHEDcAHxRFZrsLnfkui/OUCXWEKJPPZpRZDWi0F5tuPrlg9vcX82x/SG1/M9nD +TxMff2DG45PzAhcNpNskQMbqBf685T8Oi0bRtfTHMCozo+KY/Tiu6uBsyY9x9C1rttzHkGmBWhlT +H0Mvr7F65mOotggmbImPoYNB79nkPQYEmSkPLe0xPuNtW9ZjfEZg1ybrMW9SkYBmM9RcWorjomjn +dZfxGNBKgJdbwmPYcgEl0HzHGQAzLN8h3TGw33OKnu0Y0aKTIkQISEmG29omOx6pTOOLU1uBifZU +xylait1NpuPUEjG3TMfIyU+RpCU6TuaL32Y6pqdPE87SEARVEC+piY6z7bSbRMeAg2paIctzTDd8 +mnueY5iBlCOMaY5hCUHkr2c55mFONfUkx0QHhLrLcQwwAFOZtBTHWROFeoJjfl526Y1JXNee3RjV +hJp7cuNsgLdtbmOcnsQ8HpbaGLDNSDeipTaGYqc5J8bMxg3T6omNF8v/7XmNFw2Z22Y1hq4Qc89p +XCBWLdVTGmObnuZdQmPu5nnt+YwZrjbPXbcutiy2CY1Lyx+i+YwRHFfW3NMZg4CQkW02Y0jE6oK1 +ZMY4GCj+f+y9zc4lSXKeuSfQ95BLzaJa4R4e7hFLKYeDkZTiEISkESEIDU51SWyBVQ== + LTRbaszdz3l/zNz9fFkUKWUDs+CCzfosI+LEr7u52WuPlTZZxqMp9rShjOFeH2Jky9m/Xp7J+STI +GJl/ZOo3jjEqSof6PzCa9Pr7Qf1eUIzxdxk7wxj7sPBbCGMcF7UHJhjD2UKdxQYwvrsyosEvxkeN +mtvAF+Pc8YVs9GIIyXC1AS9miTA+nYAXc0YEJ3+DF2ueVOsgIzuQPqhPwosleTPNOOENVLwVI42H +2n20ciW7mH9TeXlvMLAuKUuwi3H7AdgJdjHaTyHjvaKLcdmnELGUgurDfm0U5GJO4qiy2cjFst4t +AcMwHNCQ9ASWHRrzNnQx35sJLqaLA5npslMvve7cYqwkUKod2GKALqhasoQWRQnQymzQ4gfl30ks +5trp5UsGsPi5LfNaecUw4tsKXPHjWShoxTgPHGSFFUMFADCAWcX4DA4dl0lxSPuox11Ixc+pTyVA +xXyH8CWLU4zJFC7yhikGJRZrsaAUX4+IvkEpvow/2SDFl9WKASkG3AE/HIxisB2gtdsQxZejakEo +RskzfikIxfj7EE10IguRGQE2IPjEVM+fd+KJ4VXAz1/pxMR0lTvhxF35yUATI8KOtMaGJmaJca9B +JoZ0CvXXoVNvLvjYuMTI10IkEFxiIOSGahWoyyBmsN87lRgJgybCMUcocBG6HjOTmPh7iHc9ozkB +LAwiMTMr0FcKSNyaOMQbj/j0uBk4YoS9odoxjRge14WPb5NvYGaVao8dkD0pBYr43ZWbUU/LmTGJ +37XvIGJUfkB+JAwxCBsXa5BS0i9Zy0ohJk+D9Y0KyDNJKIAdbz92qvr3WU18WdsaBGL8Eon/Jgtf +1byxlT/McpBnUopZ1Ewwm+jDSJ5j+bHCh1GMf44n2cOoatfdYlGmGtBdO3gYDFW8X+YMX+wavPxF +gd8GHQZkGrNUMIfxtystGUnA3yxVXYnDSP6DjBHAYX61qHoRSDD/XHHDKBbEfBW04dfKi9SvgA2j +b+epotPJGkbOHU5CoIYBMu7uZHZq+CAWYAMNw+uBsxmcYYwxTJwYM4x/x8PYKMOXAA/BGEbCDo57 +IIavJiDPRhiGkR+Zxyn8jcRW8IUxqrQdLgwPjXxWs4WhJcT3EWhhgGnAJdnIwsh/chAWWBjSSkg5 +gyvc3JdiwwpTZ3G0pApD82CMKIenk30py84UBsQSQrZACnPhgLM1URgMUH7cK1AYqrmz1QQKk/h5 +XckTxt+c7VaccH2E9wmacFWIMVjC2Oe8dpIwel7i3TZIGElsuHbBET4tcN0wwsjdVbHZ+RJ3MQWS +Dtxf3jn6mK4M4W4UlG0H9dxwik0QPvgmnM8bQfj19hI2IoBw10yc+GDoAVp7owcf4vAlPNgVpMkO +PpRN3dHBJtolORi3qE1u8MHhb6MG00PqPaHBUG+e6mWpmrzGxcKGDAb4F/NGEoOREGl9AoMfcZp2 +XrC134ELRhFQS1ZwtY5wm3iRU8VDDVQwNzrrJAUj0K3fXUDBQ2NUcoK7CJKJCY6/N0pwGAMS/Cg2 +YPwv+Kv0lRZEcLVjE5t47RCA4Px75QOHMfDAqHDCcZMO7FdugwM/zGO3ZAMDNQCHJtDAB5fT+nqn +8jKVUIEGPrgSaDXRwAdFbue9o4HxvYplbTbwd/hZ0WsNBz5YQFzOHQ6McljKXIINDD/sHIkGZmD6 +unYyMJCSEOMbDPx6bzg2JheY6/HzDQuMFolHSSrwQYV5q0kFxqjBwMpGBcYtpeMSVOCDdG4pAgjs +OBj4eIMCi1RWJhP4MLAvkMAI3pz3TgRGjBoxqwACQ9ODFY15wBiNQPjacMCYcLCMDBowKAwslIr6 +IIShznNnAVf38DIKmBXfRBtIBYC/4bluIGAc6LxGcoCR7BaXyQLUS0GjlQIMxw3Es6AA41ZLz60g +OoSSCO5sDOAwBgL4ZIfokghg3hWCSxYpPERReG0CAAylAgbH4P/i3wksXfm/pyNsgf89XeMe9F/k +/6mgWirwiOpGNsTsXwAESJo1+hdIYfp7K/kX/glGoAD/YsRDfUcwfS9EErDzCv6ls39OI/PeC/g3 +/t7Av2k0+PfC1NGe5P6+u7nTD0Y82uCzFfurRiejJPe3UD9kLj3XX9BLPMOZiwT/FmivKDQK8C+2 +I5AvwL/opcb5dgf/0lzMeJeQGGWPZL8G+LewPPKqb+BfiDQeU369J5Zo45ncX1rucr9xf3HAehHe +a+6vsK2mpilBQ6VH7W/cX6Lgz/tJ7i/2PBnIC+4vUbajnG/cX5rZ/iu4v/iPe/SJ/eV/9NbfsL+i +/Z7nxP7yAu/7mdhf/lPxP01GWEWN7tkm9pdJML4kgf3lAyKPbsP+IlMl1rCxv7hXB/sxB/ZXrwDU +HBv2lxm62if1l5hZQCyC+sv2AQ8TnSv1F79wX2wzaOovTukg8i+ovzwocB879bfUwAoG9ZcqrerW +2MpgUbf11DfqL3dlUUXQMPkbfP2D+gtLuUM/lNRf0nJ5QEN/ERZVnDmov4wv9usN+stEnb4rU38Z +PhKK2tTf5/X/2RBno/4CU3FeyfwFf7KWMZG/6E7GE92Iv7AyVRbAX27Wr8n7xYHeYb+PG3Qk65dB +LxWRGPeLC+GUs+N+n8ffRNB+nyKIYsJ+kZNQWcnK+kUs8rAqjCn3m7qbSfrF37Veb6DfG2vOSfm9 +7TIl5JdZk/G8MX5Rv371MhG/jM0p3Fgjho+UwKhviF9edT3KZPzy8fGDzCZypyKfG+L3UU2mAb+I +gzHfYMAv/gY4Z+X7woYqmsD74gh0g0z3JQUVEeUV7luoBjh6wn0VmHdqQy0Nh9aJO92Xg1p3G0c1 +lSIH4O5J9+XdwoC+0X0Zw0dQKei+NDAG6+UUDVghb3Rf5X/aSLqvEjQB821O4YA+u9F9cdrsBhF0 +X1YZoZA06L64lFs6ogn3ZXeKqoI8pYpR2IHPznRf3hcWDK54X1rhYRjvy6w9gt2B94WBqYsN7wtr +UIG7at2H6LKB96WB2YcV70vl5rh64n3Z3QVjQfB9MZpgfbXzfaXlBMnB4FduxpJQ831LdbJkA/zC +yjVHAH4l+dRmQ6M0mrRsfF8Y6W0E35cGhAiD70sDFvQb4BcjudjFBvyqD4OAvgTDoG08xqAN8Asr +K4cD8FvIbj3PBPzSgLF3I/zKej9J+OWBWH1pwi8MpO9vhF/2sMCCNQi/KgtBTbsIv+wNWyUNnIRf +NVO7WhJ+0YeIU3oQfgsZmaLyTsIvhd7PKIn4Lc3QZSN++Tff7xXxS2urSfiVXrwqjyDYfAvw/0b4 +lUC8KN1BJQnbOj0qjCThV9rv494Jv/T/rqqhT2JVNFGguxOMX9QJkO62M35hLqeJvmT8wuLpy4xf +WiLfORm/JftPGPHLY0UeVIssoIaZwNsQv7hQOWOB+OVkTQ8iEL/wgFh/uSF+qc3iLBJtTbDCUQNb +E35xMwYbN2yEX4j0jS424Rfv2NXPaxJ+y+Ul1k74ZZEQXcEg/LL3mhLFJvzSeVfLgIXwWyINn4Rf +Wob18QQyfXT7lyUBxll8zxvhV1yJciXhFwPva+IfQfjVa3D3nfBLK17jIPzi6M8p5C8JvzBw4toI +v0zg30KsiKBzGDcfhF8ZetsJv/g98naD8Muv5DgT8IvJ4xh94/sy03eNnnxfpklLSXgvRqhbAdiJ ++MVw5zwnjSAM4X4Y8Nsx+BznzveF8TCI99Y2zPCI7gvRMZzMFe7LroQKIzOUh/QXRiNvgz8xWmxk +3z4yoUCm4zCc18xedBZmZmPh+hKSez9hg9CRffG8Z/y9Yn3TZqzv7ek5eL1g2GJ5u1F9x6UodW5k +0nQwfePvFembNhN9X+c/oGYx0fc+1H904fneHjKC53sfGvoC54u/cVM3mi924vLcNN/bWpeA+d6H +3uSN5Tvc4ChQvsMi4CD5AsGAzMAG8iXVtZ3J8eXfAh4ygoV4N9IOG8UXRrz3AfHF33hpguGLoDgh +vyvCdxxOjhrhO9yaJgi+DIvXsgN8kdnDuQe/F58gSsiD3zui8cOK7wWWqwu0qZAw1kmtJ7y3Vwnj +V3YvbaIcM5uNfUiDNLkXNKVLve1Signu2Nmv5PYiv4qMuLC9YI4Bu7RRe6l5RD2vob3IGKvNoZi9 +w0vLDdnL3reswBWxt3udFMBenAeo9xuvlycDpplxvd2rxqD1EsEGEdQK62W1G15Os3pZEwelklG9 +8yALqTe7lxrUGx3Fj/y6zekF3QMBDmB6R4Dejd+Fwh4j7wbphRiNC53Y6OHCKwi9JIoh2bYCekU5 +fILPiz87a5PF572trNjwvDA+ovESzwt1P+L3QecFbhjD6gbnRd3EwasRmxerVzbucPV0/L2SedNm +MC9oOZ2gmpTEc8GyYXkfs3aCyotlnZrTWgFBSgRX+iuVF1a1F1BMjEKU604qL1crnP5XKi+RU2zU +G37IEeoaU3m5Ben+K5UXkx1DxUHlhUdaxXFkWSVW0Xj4G5MXyy54xcHk5Tkd2kr10fAvblN0Z8EE +fIxLd4ATGt0LNQ8JKRiKA8a5M3nlYdQ7mbwwcLgLJi8NbHawMnnppvHkzeQliAIOdDB5Pzgqn9OH ++WMyeRmsQ1HExuSllVlEM3kVwqsjEbwMzLEcdGXyMu4C2UwwecnN4OHF5H2a3o0NyYtL5+o/kLy5 +woxaVkTYSEHZkLxqjClPh0heGnDaLcOHXWHNtkUPzf4IJK/idwL+VrX97BwmNiIvI1h4P4PIyxgD +1m5B5GWQBHPJRuRN19JEXr6QFjWILECfGImzlci7Wqt7YzAAH0ReUjIweG1EXqrsm4CvwneQilxG +EnmFAqnPTuSl8pHahTKV3ww0BpEXj5ILp43IixoVrE4DyYsyK7KuVf/LflM7jhfKqq7vka43fFqM +DgHjZZSqqXRywngZUel3TRpvimmDxksDO1qtNUA0kqUniSKPcxm+G+JaDs0bjZchwYvwSddPYZ2J +YJtxvAxmlbLzeBHtYfWkcbxAZD1EBkk0wtoRpfEnjBclVG2ieAeSMqMkihew/fvcQbywnUTPSNfP +arN2J4d3+LvYMLxQ2SH/YAov/kRfg4DwQqWGiXpj8A637QkE70ACtV5J4EUkB7GRDcA7HGwN/m6H +i3mU5O92x/Y2/C4gT8SUGL/bHTQM+i6pUGNn77JJDFQvQu92RnWCu9udadywu938oCj6RYMShH6C +uotTP9UgfEJ32b8aSTszd1mjXu5E7jZLvTbiLgUBz0jgLlpIIvQUvF2ARK/6xtvFahSfeOB2sSZA +Q6qg7eJvOPEbbBcqGIT3g7ULdRZyQ4HaBRq27ZxdFIgiuh2Y3Qv1pcnYhRYHK+4NsQsjYndB2IWG +B3GbAOVC42NO3iy8v5ryIYHXvdRzdNnndeL3ztZFKT1l6gaAdIcEg6yLqhpKtlewLqAd+KHg6l5u +DhxYXVQEYUm8UXVhxFcUVN3Lk05AdXEmp+F8mUKG4B1RPSN1keAcJuzCZwFT4VT7nA== + CcDB9XJtbaAuVkh4b4Oni6paILg2nO5THIBwuPBxZ6aA6UKyTL7eCtOFEcNusHRZU/S0ROlCg41g +30rSpVj7uhKk+ziEHhxd/B0/lBxdJgYOC7aGgv6awo3RRa0TYFcbRRf1i+2cFN3HMMWA6D6OI28M +XWQl9JpELLuIOR9aXNGzat0ZurTeamIvaAnRpuVJhi5D6XBvN4guW6Uj1hgQXcz7DPsFRJcGxPlW +iO48WI+CPoyJL6c4KLosWkCwY6PowtWJl0MZM3juUFAERTfzxRtFlx4aeyuNWQbIGSkwuh88uxkU ++8YY3ce5rp2ii5DvYTAbhkVEfKN4g2uix0qjnaCLWoLD3dBUF/dEiy/zc7EfkzkbPpeVm6f8b9Jz +n0DgBhSXsTnG2Dd4riojWl02RN8uvPJJz52JphWfSx+euoLA53LFxCJA03MZMewurZsMXMYN+3Dh +gAOC96mKgIwQUgz8cUfOiwnPVXHQXT8lPZcW9vDd6Lncg2VBpufywjHdmJ6bf2/0XIaTkYEPeq7q +mceT9Fwm1VhasdJzGYFn68ARErxDotWg59JdxhPa6Ll0tKBNDHoukgCswwqB8WFh5UbP5VmdZ8Jz +WWyDkEbAc1m3gFF2g+fSyq/d8FwaONoYnsuRDoUTGzyX/iHOPeC5MFR8pQHPhYEC+42ey+XpKUAE +BzOoMLCeDHwuh41bOaqJz+VyFfcu8Ll4y1mzEPhcZT7rs+NzCepAL67A5yoNX0ryc5Ek4HCz8XNJ +S2kS7GisBPYQcZvg5yq5oNFs8nMpukC1V/BzaTjFy1V77Ev43hWfiwSf7rnxuQQFskDR+Fxswdu0 +4XOhz2Bz+8DnMg/ImPMToJ9H4ZANoAuiGTPpuRmcDcyLAdBFHoYvywbQhbWRMkqALvhLdCCCoIuU +EUNQG0GXBDisXYOgCwPdvCDo0gCF60bQJROpKVzN2VGQpOTnci+W/az83HLZtwt+LsqCuSgJfq76 +wW/0XGbTivxhKhl5zk2Og/onoTEk5PsbPRdW/ZjpuYVQoPNJei4NCMds9FxYGx540HO5Ge+A6bk8 +chEeetJzkZzkWBf0XDxfCusCn5uGjZ87rQbo4vCMbwQZt1BFXc8doIukLj213Kx6ARQA3WlYAbpp +DYBuISgNbpIBuvlibghdZmefSdBlwTXy6EHQZXqtqvRrCgdpxdIuGLpMrmFdEwxdZsgQaN4Yunzt +saYlQ5fF3EhBmaHLf8VKdIPoEi8GVzogukwWqvtqLOARGsJXuEB0iWo8ihQlQ5+K2pkHRJcfl/Pc +ayeRRi/CEF382ZFeDIguDMOBpVmqDCszBUHRpcF9bEnwouHQgdry8VSlck3RZQ6Yaeug6EJ5x4rB +naKLBy5ZYFB0SUQYaiRLii5laJiVN4outQ1YHAdGF+6fEruB0cVLyDZgO0YXZsKdE6NLCx5NYnRp +oTZvw+jyiO02VpUvGuR/rOMNjC4sjImtGF36pkzRGqNLiNi47PCQzQKVHMJWK0Y3jYnR5XT1uLut +niRuGJsPbhhdmPV6GaMLA8MHidHlJpKdrBhdmvmoAqMrDtswWFd0CwSRPu0UXSoCKRUIii6UKxw/ +EqNL+EN1a/aJ0WV4mJXdgdGlQ/csfFx+ALzyFaPLlc8xjY9FCgnRTcPG0J1WY43QpiQ66fI9/OCb +/xFWAazRIsdjIeiqOL8kQBfOPldrwc/tGm12fG5XLCPpuV1q8oTn3vILdnbuyzhEyhUC9FZJdJJz +72hXuYJzb3KRl30Gq66Cmmst607NvZ0OMTUXzVREe3E/qepUwMrMhcYc+V0zcxFeQ7QzYLTVgq+N +mAsjfMAA5iIWeNyJy0U9AWbrjZYLPbrSUoLl4m9lpATLxd+oM9tYuaQOo9OeUblQ3OP1ybNzk/KN +lMt8DDxq0ZSgJmcxvYveQAt8+JEtnFzohwCt0mB7Phr8A5J7djZcXwm58DeQ/AlALnvyHWfycQEb +RJh7x+Oe1kskHRfyd4RxsyYEBoQYdjgurJixgo17unlBsnHPU6qsHY17PtTJEoyLJC2i6vHGIB3O +NhgrFrc9FtaYistQ23MmFBdBAK6RVyYu4h5tEnFRdaP5WUqabsHYxsOFkYIp43CxE8XQpuEqlvLs +MNzLYq1g4V5uTBgo3CsmooWEC70Mo/cG4ULCgYBYcHDhUeLj3DC4CLsy12YKLnQGz2TgokYWa+YN +gYs8fW0JwMWfIHEE/xb74C3c+LeQ6VS3uWPRJvp19hH0W6jKqvCwE36Li0QxSrBvcRP4HTkaimBl +UV/CudhFhE8oSyYLmE5vd3Jvu5EHG/a2u2VDUG+jtjqgt90whY15y64WZ0vkbRbImnh7uqp7I95C +iVjFwpQUAo2brha8W8R9MehuuFsCOsqTtNvLraUCdntZgrmxbmFEzCJQt+B1wFsL0i1+qZh8m855 +c1lBcG7hc8GvCcwtKsLaG+SW+ghoK8y4BQcF35ERt7gLeL82wi2M7JpiwC0ImQjbB9/2dOJl49sG +sCbwtvgbcSDjbfEnggwb3Ra3BM5qwG3Pbp2EoS2nMQcb2hY1UKyHU1nJaVVxgG1RY4VPcePasvgB +AfsRfWAUAgiqLZKmfexM22oHIZi2+BvBzUDa4m9koTeibW1a/CXQtvkFEs/24gD0hrNFhsUlZaax +F4pwA2ZLHcN97SzbC43IjpZVb5g74UUGyRaRJ0QfNpLtw7L7MkG2TSG35NgO9X7YMbaXwutJsS2e +Uw2xvaWX3hi2qhsoibC9+TZPgu1NUsYbwBbsCcLvza+9VbJgeu0tzdAbu1ayn0TXDot1TK6tro/a +ybVdvJEE11oWm9xaipjfsbUMZ7RJrdXMksxaZFxLf2PWIub9LMhavLdsD2FiLfU+5xuw9pSXE7za +6tk7cLWshb7aTquFDqSPZNVi7UE8YaBqu2pN3lC1r2fQWpJqL8YSS4Bqte5pdQfVSkyB9Z5BtQhU +uoO3lC4HS4PlgE5SLbP9l6yG95dD1H/TkD64xt/e+8aYOrzUTVIthAt4hQJUG9yq4NQimUYJ6Iqp +xcoeLlZQalExDnc2ILWX6xE3Ri0GqEd6UbMUGKwNQi3+Hvrnufq4nIIPPi0ylgj5B56WnJbedjrt +5QLPCE4DUIURMaCzwKo4XzbRtHfJ1CyNWHvzPqjAEywgLO83Li2MQ4BZzhP4uyjXjYgtIJ4oq9qo +tIigY3YMKC3qghg+80ZI5iHRtSFp71srg0DSksV6j2TNgtSDeWMD0iKKB3ckjP2W1DV4tPH3hqMN +Y9Boh+fhoMxCg4ol6caihYKUkRUb76JIbpBo8+8VRBvG4NASn3s/iaEdl0QbG4UWMtomNC2FhCDM +IbQcDFoS59S3bPEhLxWzBYF2WJ0TvFm86qd2mpFmIFwhpQv8LOKI7Alm+ixke129zSZ/FkG8U7FJ +hjj4d+1Jn2XM8rh2+CwCbfjCgj17u/tSsGdvdxPf0LMMkrYnyLPMwIpXy1mRGdrybNzZYCYFdva+ +3RgoqLO3v8gdOgvOMN6AYM4CaYssZCBn8XdViHoSZ2ksZwJnHyyKjJfF6hFVO/DcNtzsM7vKsfSN +MN/eAzbLupdy7axZAJqqUs9R1qdC0iDN3l4N7qDZWzStxMw+segJyiwr09xLZ2qRSRNmgasZszgn +Vk4GYha1OJfhtBMxixgkJ7XK+6UqjQDMzmOsfNk7kpvGy95O9gRMNj75DS4LSafCDoLL3kV3MJGx +o5kMt6FlwVchdTCsSPk8kytLtfR43rCyII0w7BdUWaJHXI5MnMM4ZtVuCpnHMQt3Bb07FOFPouzL +oErWDSjbHWNOoGw/otLUBctpWJGy0yimbDcPJ5GmWHZyob0RZSm24WZeTKDcJiB7dESaK8R2oiyU +9qqrNlCW8nzHDXFrsYaJFmAzlYk0Uzl9MB79Djii0SXNKfqdJXtZ4JAoWeTYUEAcJFnKlph3Xkmy +SGxi9RMgWS6svBWKagmrdI451R8omDp9B1ib3KqEWImRxbJFMbmVItuwZC913nEYVFduhmyzPHFD +yKJLos7cCcDIPAVB9t2d+fzNHaZ/JMj+wwiy7NbFHCBGXXgxP6aZAgRiCLtyfVKTw/IoaVgVXbUQ +zFmuwGjeztETnqyfuC2X6I8F6cifHJnx7cY2AbA9LjWlIbyq5MSHBWU1FJ7ywCV1yGBtdU+5MxQU +j5lQtNzmwmO5uexp7rui02fSfk4J8lg1qeYDji/mlbIYkj8BplEJSE7hC4+EDwRe1Z3ImXzy+tSt +JerhaJg40Dc7jasM9nI8B+2Sp85zMVdFjgq5VY8sSuogUMLOSLCcZdmVYtPiOgsY3MYEa15I9i81 +wUQM/M6mDFgFsFkq5QxYEUEA/qhDMqWoeMTQZ7BbccoFwFbiKhX5KRIJWO2l3scOWHZViqMfYRZ4 +sbM9EjZoa31yBO0GtaH1NYmx7M/E5StgSrn4Uh8nCF2rS6IIraYsF7yHx39TTssi27mfIDFYcBLV +iiNB4QULV0r8SfZnhKVHnZx6ip36SRZS8aGzW9fh5mJcVNXhPTNTF5UwbBzPrpbQ/gp006W9hUWq +YkTc70B8oeOEWh/jUdFZgk6hEX/T3NH0dm0dbiMfuPMcw73LcXfVzWygyyoCwfxew1ujpeTZwltk +V85IwcCisBJ+gGQFWOqtJ1eSyYDPlwt1PHj/Biovj5Pvxsm2kHfV9Im2kIvG5XYcTW2u8ZFFyTNb +XD/s3O0GYvh4WMenuBYkSURKH0Yv0jKGNmS8GQYEwysLS2bzykPzE8z0KWoQEmhBoLGyNBkfIi1Z +Po8SHgT/YZbkj0xa7tFceI9rYjfTkBUpIkL1EHseuFcS+3aSuPFcItfivZC8a6w3mGYWukBgjveG +LxBFa1iHs9cj4Bpk3GObI8IcbLtO7fxQxIsbqqMDfgNjIy0MIQVJ2LtGWviOGCX9jKJnhFg8+mRI +oAUUA4YKX+qp5o9svwGRHfbUhrcZfXy87BSEFVEGm2hGCKpw4VTcAJ1pZ8g09DcZKviz5C06HlG+ +CqHJ3k8VxrEfqsQZTvKRv4/HwgIufmF40NkNBOcKyXNheT2yOPej/IKvsvgnsWAmTAsMjqe4MyCj +cXzWeE2wbG+ZI4SZnQ5H1WqJFs6F0LxBbMET48FGlVord2VVJc3M3kBjSzXHcLodllu9IaooN961 +CsXGVkBsS4flE7s0AD/MZm5EINBSlEX1WFZFFsD7pgQiyxJvDn5UqWH0V5L46usoCDOTWQSz40+d +AyYZ0mignqPcDJYzZ27UegLoLjNe7C6CNI/EtRunl0cTFueZHLEJeC90teHCRE9CtujBMW9HqfDe +kuCp0Qh1FSTVYHXMj4lQ5K5Hr0UJNMJ8F6rwAJ7xh1+u22Rmcasuf1Scj1vgvofL1exnPMLnDIeO +YZB4GBakq9gskKVUw2qJ9FDUA4IPHoIFWNhHAj+BmAAtRFHgBawTQeDCgwKyMVet7Q== + sZYHVPLLV8Amc4XRs7hSFCPoJXLcTHwJvjKutKUzSbnp7Zrx79PrFLusyaehhY+SUrFoL7s5rDPq +asUyHQ9UJBV2ae7R9bdHxhNmilF64LAQDcQNhUHeLgT6qycjdA7MhEDAwko5kEHor8FC//gUby92 +jepXLsSL+nUJv/NaqhOwzv5g6oNji/2uyw1cckMEbSWzsDAqm2IK3zDSv7wsEkZZ2uFWJ2pixi5x +1d3MWFR5npJc+4QPv6inidc4PUrTN0vhYMBdc5onW3PoiAwMsoUZRE2wsEyO21BVjaqiMVIJ1o1k +R7MEiolw9XwFLvNXF8stal/60ixK4AfF2Qe0S6rmWzQaR2EOG16BbHKn3K1Hsxp0gadgjVVH7Ox7 +GrLGEg3cwSYOUu6p5TbWvOXRnlyNwSLYCJvY33o2nJR9qbdlPeyvQoHqLTUH++Nq4KqWXA6nfOfA +pe/5VnKbFq7Dx+0G8JA2q5mZ4Wq5qy6DiPhDv6HqT3YDutUIVn3CYLnmumFEI6EeQ1fAW0f0XsDg +QDeuO+n1OZYcYv/wZWvqPSM8EDrtcLxkG1eveFhT4V2BnGUFOKTdl0Yq9TwdDpUWJv2q5itSqTyM +GMCPfrzkfSAZyzzZVJI6D8zuRM+U3UV3nduReFk4vh8K4nBXqsQQQ5/fTSvhPbg+rzQT/Atr5LB+ +bNX3rVcO6R4wT3cwG9aB6/NuGkKZFoNSzK2BbXFCrCkpOzdEO0VOliPexyNb2q4+bkrbyvVEbUWz +z0HlKAFOFEEIjZNfOdJfFaMA4DVEliFDpg8zgqYlgmOBvMldGUQXMecUlk89WvFKqZPIHQvgprWC +dw2PkSqawyWzuGLQJChbpNyPZe6Gk+j2Uot2KurAXgi8AqmnR2AQbwlM6UvMERhBUP4ozJfph9IK +w8cg1I3owvHuYtRsMG0CiLarshA5wGOJCmV1l3ftHjOpXZBKUHJkyvN5Fmk5VVbuPdPsUkLGeRkF +QWsGpgSgBZUbaYtf/PDz5oZeodHPImVyWiSI8Z5hvUzoJruQP4GvnyvnfHuBhoHX4Wc6pKRR02Y1 +eiHTSDrkU2FJFiDwrl2TJuASQN667givHb2HKid8B1T5wtImq0dVXTzc4+5Z6tWNB8VEASxcu+CJ +zlEQFDY66lTu3yqScDu5xyxXhMT43TaX3X2Ol0FFapDG6VO73drm5NKDhSL8cEAnnhEbfKO1GIgl +8tXjRDwt3pUqdu7asgEwFjccy9tQmSkt5DmgdpSaPuzKcBXpLvNTKyo+FD2Mge/b61D4bZRq1+Gm +36Dj5LKFAmqBxnq4l8WaeBQ0UL8M3npzmIo4AY+CVaWQGA49MRyqghFcFXccQj12vCP/YQr5zwWG +qZfXzU75LpKlil2j1R+z57mr6ibgArIL9Ok3ib4j44an44Gw4Ol5vBf2X/2gm0Tv1Ebwi+hEjN8O +CNGZyAEpzYRBUCVLKZu/nCvuGsf9Ic5MzjF642A+qgBvDH0UKkAxDsFiygFXmLmnFjisPCd2pPg1 +Z+eJu7p0hPrFtQkU3/cy9MiZK0JJtMojsA7x8kPciFPtfnIGZyE85NKCuQDuW632ZhQXGJ06piFX +dtGnz5upm7PKoOh+2wBh4tPT/wxrc3KM3UpO5an0On5YGszVQ+2GN1XIDPFiup0asl+I5nkxWc11 +q5g0xALxt4hNOIFr+d8M26undSsV3xlDD6yIQazl9dIwIVPPe0ZOYVVoA54M7hwszInSQgUmSr1O +7cjnmHtSeb/tSTgdf6H4bzSTPq0byB3pB1XKKRGZwAuOe1urF6q4Dg6RiMJyftF1gk+Gd7RinXLy +qsxuqmcCa4ZKLHkWLWSfMEsqxKtAhOS0W0jLXWXhu07LbAkHARijfzgij9z11CsdNAQ4YcFIzUu9 +QtTCH2WHk/PSZIEN6XzofPEv1sDhkhmN8p6u+sOjZ5OYilogRCXxH+QKVZTcCdfwCAOuXUkY53UV +n2ZtRlNA/Iiq88r0ctEVzAAz3zOxHR7lPPiMECioRJHzUg+JymG5W0gOYOa6hmZE0mFRuxe03YHA +Cga+9RxKnjL35AoTZkYceSzIK2ChF8sfhbxQltCQVTZngeK3FSXUGbVvj185ItiH8Dm44YzOZ0CR +sS4URSMiohgg4q8EwjPodZJkCcMIhx9GRcNRkEg2BnAmncrkS3hcWsCsgqXXNvekhAtWBgu5XeXH +fJmAf1jeQkv2faiHe95XcsSGAtIXPxc1lymerfikR2gTEd/ukcsgHJY9rRk+BciKVT9ognZVbYNw +jWPLRe2FYGQdCPorV2YBHk/pEDB1du+5pczMPVlXUumqMx5rJw0Wp7us+YOlz55hhLzg4SHTwIQI +CcXot1MMOMN5sx6lxgCtK8UNuLQny3D5OKvvFD0mduo9TsV/GSeZgUi+KIfh4mohrJRTJ9/mcFoM +lmt+3DAPZgduVRTzWAqr35wemIprt/as+Q6x2Qfej+PyCESdn7NcGHf4jhAPVYyh0mVWQ+aY5+KL +D0EiM0DHJSQD/kltnoCseXL8QwPEwuiuUcKVLRLBvz+0RKShN3dCLkHvovk+tZ3QLjjWPbQh49qV +jRTvaktdvjLC43ivanmc0WlqFs1kKd5pYYSOS2XjfqJ21FFCx28DSTQKA+7HYz+LiysjqJwUPSZc +KpFkYLX6ixa3+rYslB8voAfcZvYjAdeMntbtuo1KWXPVhuw/w23YVQAtQGfMH0J5rrCeaLEDwc6j +HtW3Jp6iHkf4ygkF9zN9vJ4GjRoOQ03QOru4D89p8CjxmzN3dJqBq0A5Zx9A/dylvUECCYtq2mBJ +MTHM+jhviXgqBemnjpW/SWcMkruekzdE6VxoUVSJV7W5tqcSKYD7jbATB2sMeS3GFJj170f0Vr0M +9udICAqMLI8GwiwHoFWD9CndE4+lL+bkWfI3Y9R+lt9scsGREWOYAKer9+4wMxSukjpzAKZQIthX +EdGr/IgvV3uQD8mD3fayruAaYX2TUSGYbzbbeVR6CQMhQkwgMaeHTZTue5RSmHuyogUDPK/nuiKR +8kjpVxnMe3QwarG9q7WiMLvFWJdzyZGMwxA7yN6RMozMJ9zHqsFTExjCLXShMLogfVJ70K6KaRj6 +ze7mezSr428V25cTMfFc3QtsWNaag6rsNzPSeKd5MAqzkVBXaxTrk2iZv3oZooGkpSalFj5JtMyp +7FjWPfLC7bUDafoNJgxhq+DXYDVT2fWIHramfywlEuddQ5+M4Ur8MIRSj6IBjLn3ytAvB5xK8cH3 +4etTB1yjbUJl5Bc+K7ezhYEPWDjI5a5qkIdqJb5w3bBKzgRt6Ef3pcSyzMBU0HJl/nqztcxgxdeh +oBQ7DcIiWXoPBxEaAIYvRleppAf0ItEdQ4+cM4r538Pde2DhnMdNxnjmnke1zIDVJpwzlHXtAWo7 +InvYlyUTdnUfqlMzGh5q8rAluaCCDfNFc3mOPSC3ilMgn7nei4lD6kHhiEjGHxY5ItACK/UdG44W +N+jRd8uEnkpLDyH6MznJv2CWlBBFadQYdlP9YBGcAHKl9CdgFga/u+ZCabizzQ2ZS2MVeD/0RL3r +ZaUfNPaMcxH260C/omy3SSFhsM9lvufc7sHgJQ0Ki/rTAEJQSSBeWg3TxcRHF4Al+USLAjhRxzT4 +5p5OBsztXPeCZ6fCwbQwNJ/4hWlung8vl/Mb9oUZU4HZ614S1cq1Vlkf6yIE5MFXXDhj3r7717OG +mW53Zkbouns7SbHAVSKq+7YQVZaM0t8g5zL4ZGgEM/GMuaBA8qCMwDRMBLi5elI4AzkXdS6K+A4t +Pl+WpFFbwAkbeqLEacF6Uv9UDCNCCpWhdmiKMG2UYd5zYQliQlrZKFrbKfcLRgrTn+SqnTpdVULh +WC2RVehNyrgU0mJ0NpjJvRSyY+j6jm+dFMq4TEjtHWyr+slDDbWY4mACdfgF4B26a34rh8NAIJof +TEcfpmDG5AWLYnWwnOuubmxwqj8SQdOUpEFrXRTCZpUeLGuCtbtDUTsdTWMjb0bJQkjOPtpV+Cgu +vn2pTojA7A29+KOF2m2cGCva2SsmgUQ8PYeylMRD4JzjByysfe/PpP5cuWePtgdIt3DQguV0AkYv +73qsstxf9zBl3/Q69DYo7UY/pCwDShh0pcxyXeqwo6Y6SMXz/hK+SnmLGdlp8ZDS3EcnN3wCdUO6 +2bCKh/oX4rmuOYqJxwK5n0aj062UTnM2nsjqxMyfe57G74rV8Ng5JbeXMUqUI3D64TY5jqFjRbuG +n8uwF1tK9G9aDdUdHzISYPNjlSr7zjwOOzObBXQLhRcs443qPExzl3QElxoMc33bi1p0SawTKnHG +ZctYJFQcIiNyCAPbOpdoCAzLQ8wMtmmLbEstvGs4V7Cg/oehYAaFSkglKjBysWMNSM2Y/jv5nozM +k0pGyRrbZDg4lNdJNSa0BtQtYiXJu83wMh2x4i4auGdndImnmTlvVvYzzFjkwdCi4GkxcIHB+/Sg +4U5S3XPq3aKB1RgI1VMUxw5/lwUK7cofPdydqh3RCTBSgQiCYvX3wRf7nH7aH5PLzCinIttd7vWP +aaaCoXeL4Bj8PLpVRafDnGyQEZZc6hI7RfEsfezi2ilqBMalJZ7eGXB1arTnphN42mni5DiX3MDe +R0BUHIhrCzefLnRirlJx5+YKgyujsM1alGuPwjbLaq9oKonfoAoW5cqUgp6h2IGlH0ssVVMfq7mL +XOVCtjQgAFfTalDqQawYn3mt4VNHZ2a9sVVvNZUnlSW4l9J1XHXk6/SEJIAzFy10IqGyUVz4cI84 +6m7OMXeVJxg4JcqM2W3ldA0dLcViBUatv4+Iy8k2dMjOKNh2SW+Mz5UUDcbhWEuMgGuqRRBoJIzp +8EqZ0LxHenZlMo7L/GM8jBlwhoJQObDqpQjW1hxbSBk4FG26qJSgACoeKiamQxVQt1amBsiVDDNj +Ew5whKXfS/hNicPDol4EuIKQpBA7fpJDPiwjF56UAesXBKNAvI7Fy7BgdMWdqOYgzUDhIWYZrIod +oRCNLQLRkJxiJYpWefbucKTZFJWWJNmdwRK6OwnkcK3k3bD4oaj/zoxrFnUf0I2l4Izc1dMWes2s +HWQmshJikzsKDXg6nkNBXKOUJViSCQjDpHNNrk2zBoDNTbu1nBSONqcHqFulLBAipxBWYUe2RmrF +nyq0xJdyhxLJD4dS8fFQ1pWLJh2tqeEdnFEGa2HRVDocpORkUtObg5lTaWu+TvwE39HWwumJBDIs +M085BC5hvpJ6EIh92KKgdWsBUAlKzUtzqZ4uFBq96iFAkTqsnyhHu0xM4H/QCcZi70pPBWYWiY/o +34ccJ+VMwxVbsKiz6ym0Ze4pPciI9oBYV6i7a3X+kkLWWGFOjTlWKiqSPz2tQrdIz4pIf1zhaCFU +MWvHl3qr3JuLM65/umuNWcegyaeqZgVPbVk6wYw6S5ilxIflsUVqKZwQ5Ygobaj5Cg== + duMuab4uqeoovN92VX9lHn5qdbsB8KwCfPRj1vNUK4GG60RL9Cf5HCsg/SqkmSxqhLaYWpWh2n2F +VhiKoEw+6WIwj2EFPBTu6JhEoRUV8KfUVD7WvQoKukvdqNxTx5JuhUnqfLuKXXj0dFe40lB8I/pu +QdOn6MCl6AxWtSxtVKo73eUnwkIO7WKol/oDxFRme9n98ZQyP71PGKknfdybickPnkTAx2Bxlqqp ++id3ZVkwzFxnMlPA38SGTHpwetGeXBXneK2Kj+FGZJmhKd08fwrr2bkXUrSeSjkA0G69vOzaV7ML +JiRJigt3v4H9nlIEOKpu3p1pikNxk6mJB3qOIpfh/pnfR3ZHH+O4o3EyPuxHFruup8Qj2CTVpbBK +/zxMEmaY8vKroF7VZGV0F2VkHGceMELUbAN76ZtUYB+oOC7P+yOFmRMXXR4bzXTvmbW/FWOinqay +NXGxtGuWc8DXlCy6+zfgjzZJ2i91THr3W2dc8xtjp+m9sNc3sCIIBv0Y5ltFTU94ekPLbFp6cxWK +uoc/i/aL8clmv03txGHpEdy+XMBCXTerxa5ZEGT6DJ89cyL81UMZJd5MhliZsw2LHZuuFuZzOwfr +WfOmtWEkGrt6332OHUk5UxUfQS5NNB0uJjGTMCB8sELHzT5nQPjgDRiS6vPkRnlsqXIaqbV/3/Vw +WrVYdEXLpVC8S4uKK5+KelnngtRVgsPZEvwzZjiuG5lWCQsrJkPpiz3FVUFSjqueYskVU7WPH+lQ +yZQB9vlIuURn0RgVHIfbIdJy+SETWMBd717mruSR0UyBDKvJWZMDFrt+9HS1GOd2X+gppiG9Q11o +UA/vyAhgjOM4jdElZT0U7xVZKc1W5smjUHOGSR03Yah92bN1V3yceusfd8mFhQuIw003Ycj5k0t0 +zjXNA18Rs47hfJ0ExhZFW82A+ZxrdsVBDueCqztNIfjiFMhlLTs43ijPyF1FEUATLOVtJJ4vbHBA +TZSDeAwIzoTE6Y5CNHNsRZ0Aw3rjCJFOs/htmIOXC0rV5mD+xMcBAyd5xCXZU/50SwJYxnznT7dp +xU3Siqq6cSl11cpqPdLoshT5CMIrlCoicHIuKBozHYZ8VJ9S2S1k/u3U1Qj3IDZDFomFyi9XRBl9 +uETFnv30pipZ5VWVhQyN4mDsyY5iJU7jl7kchT0h8kJRLSKZSHzLQM5xCRvNI2BhZ1tMtoz25q6i +5gNAwJkWFjr3aEFJfRJ2pdgSluPOX70tDEYyArfoeqwoRt9CuFfI/6q+e3SlunR3mVQdkrerexgR +eYQ5nRadYdnOhRPcjpHxEFRh6Eebqp6hstfJRVkyLMwK0T/JabBF8BqUAjx6bsc70pRu4MEpAX6c +0PSel4sxMLwxRQqpJGZUwEqQmIu/b9P6vV9YowQW6ya64mAXITlWWwkRRFmqtCCokmAoNwRam9/o +bW7IYkFxdi6b0/yYNF7ZyJJR2Uf17H5zmcY7r8yGN8thwMCnuA/ADq2gb5dWIifoG5bqVeZcGWUn +3xmDAPv+FNWLHtpNQmr8neVX/DKi9JfR69qtJ+Azoj4IFg5WbR39UHaC9TjdwvgYS7k1dSqSAW9I +3oAzDZ/jNVCQhNnVIt2ni3CLPzPS/x8rIPIGYVmkEfl0ASYjcBZZyB3vBkFbz/bMKyUVjSTlW3dI +szAUFI9GiSK9ht/7vFDl/Kkkxw2JvAnrfqu/FDWWQkQ51zpUQfKhIdlAHRv0qlQ3onCURz2jKuB5 +5LN49HvclGt4TDhjuEQHA74kiHj1W75Ym77Y6RZ0MF96cW8/KqoWTkldpdEpz1KgxiMySgl/T+LS +24II+HshAWUokdtkX3q6wszocxKkK+hucbh41hdSqKl09tBA+Dk8cpmL1T6UNJ0W3+mhnvERol1g +FitUSo3xDKtTXrRQJ1BdGcZdKS2rbUFM0MxHBgkhxnw8CY6hNb5CBNYeCk/XUkoKUxVoN9cJ/96r +Ap63Vi3VkhXIebGQzsmb140jSyn8ctu4TETsmXRuKt1OS2xpmYHD41nMVO9U3ptT4IZpQUubljHd +ae4uOocUqEh9odfyw4rg2y8+WEjC5SOKc/Ciq3SUXYku1eKIXAEGIfujYH3IzCZU59RJYJuSa9ba +HKzhipP0cKMdkYxzDVE3rKR44tC6ngDnR3Qv1flSmc+KjOqRE+mfRsjQBkRBDogtGueu0UoofkMW +59Qy4MwfZUaqmGYMhVxvqmAaKstQ1hvQS3jYuk5kY1wZoowFBHM9+j0iuIy4KoWH6gGe1XrN1di8 +gqoyGjY3U5fEU4k1letFP3HvekX6sDojgE4E0U+8u/fEybAgrnKkIBY/yvRAYXc0bMbs3DzX28oY +fN3H7OFw2HuG+IeJLrR6JoYsCldbtxoE9P9ZEYaqD8a9iwmysBwqa3DDXjbmYKwT5KuxFGAoP1ei +ZAO1Mt2JYNFrEKIVzN6sFe8aIh2Y6RAijYDYRXGfHW7CNx4KtbJUM0oNc4Rnhl+oNrBEurmxG1PN +M18M/s95qN5IqWYUcykD6xeNDeOvods9fTYliPxNVYUsqngi+GZUBIo+XUyqB3r9+4hrKiRfI0yI +boDRy4YKL1p4wtW1E7mrKPFYzISAQImAegX65TY0FarVkjqUfsWjHgG0qU78ovKOclFqXh7z5vBl +ORDb/HXg8xomPdyMEyIPpqzC4e8fNQMzOImy1nKrIIlaCUhYyCdiU0ZpWkRMOLf6GJipwyHj1nWz +5BCVwBbzWEPZBwacHJts6kLD5JTquJcmLS4KvqKsyUP953ioquvCFyUwRJVIqTm8TLkDg+itLot7 +BWmZnDVmXGIMp76YIpZuhM08qmInM5Z6sz9BVVnLJDwkAm2YGkPL8iYVR78Ba67Wm7jGPnpONIMm +TucudKXNvT84SFBJhP4mRHGAiVBcOa/ZAMXMbaMWseuP8RM9uq00rza5ycPk+63TmnuOADsQy4Ff +UCegx2QgFOGzcpmW2etluGsUeHelWWpDkEpz7pZ78LNqRnv6mUbnXlZ4ngJH6UPtgbeAzpVvaUep +4BxYulUmqM2iNrt1y4tYrcV8vbNp3d01ck+VlcKsErYu0Et3PpMGtZ8YCsR4z2FkDFSBNWo4OYpc +Qb5qwXRB1RYWEH6m+ChZy+qKLW7YnSZprtXmF9/HmvJARpU5NpgZczhDAYLTpTKLHzp1g0N5i9y1 +eTuV9J/R1wYdrPSTLJYiT6vP2fA0RoKskaO6JUrTA5XWCJE1joHNmBbtipiWKkGHdU/F5TK8eeRW +lBDINEfWclf2tsjSVWmnLllcqn2qDx5kvMuPDuNDoPXGq8sg9+F6yMOO0RFvPbXG9qlOJzzYfYud +yA47CO2MEvTOYhnmxDO+xFYqTBjA3NxcxV9HcX6xGL/EKe+YF9qjoVcR/ZUHI44B9U9M0pdooN1c +d2qfqli6hqKrkXPNJc2NEGfVxYuRvkzvUdAmVrk9Kl4nJ5cyGXYjfIx0weJrTmuYp9mR+ox0HWdu +F2gz4iuL6k7LtVYdq4Uf1zPRhKi4k5CYfkdo1rweyeuUg4fWIkw3neGXsKIuyQtNw+4d9RaiklwC +/CnOhrUah3BorUQRvVgdxrT+nINZRXUKsKLkLeRm5Cmg2IO+LKPHwy7sdOYQPb7d7ly1KIweN1X1 +q4k9LIeK9fsUqKW6hIWAhwrVlY6vwaz7sJT4IyxXKDN1CcZwwSpzwHzbIKPjqQRuEOlAk/iO0Fg3 +8Us8nRxTWi3UAOgb9PbZFO1Uqk3zJiwTugGwC50mmIMScyqP3NwUCRalQtuygsNvSOqBsBhOCglb +yn7RcJyqJqS9yKRD58yULjFp3M19vD1CVo7GQ5EUgjwiN1rSE0JcWtl8bwYose6Qi7wZBHscu+Oy +JHOtHMSfI0qLHr/zjzvAwiJ6ByzTJ0HL0mJ9uzD2yNtyAIwNaeHwhMOnxIW3gdoQr41xuaS0Q9Eg +Nu0dLSbvDeNERHdbtmM3cbwTkHwoMxAWBN2WPXvU6kWvsNt+hFLCLOa6HAYIi/3MW7mJuSFTCJcS +Oldb/z4WmWCaecGc+qBWHzy50z7gfVpR9NQ1735HNy+YUXFBC3UCT1X8hRZyGJ7dnzaIl/H07g3F +u3vcpoW/Ospi8a7DQBOYsbhGRWaL+HQ1M1RxeCYv9No+Lk5h5JlUK2Kqi05WIW+80RzFiLXPSZ6h +ZdbXuQPvo0ZN+Ps0jFRSGxjml028KRUBjyKmvKPUB8LySIwrtdNtzZkjM+EZPXfkHYYZhyXoXI8/ +9cpmE6kgQq6Abwy6dEQZJyncrMIqfEeKVTqPM5P+1WJn+rFbwV2bkxel6lhyVx9XiOee0g4gpcEa +n8NwdG7YXDRZWGzDfth9SfNWtr9AN11VAzcBgRCWImlFPNknpJmBZ6Z47GJF8/Dq7fEqknWCF1t7 +FLWDRHgsqwN0dkhEsmPPIz0EMSLc7uRpVKq6a7Tjyj3pCsBMsTct5G+i6VYW2Max7ry95YlceDtM +K3qqABks5qavGENKWnylhQEilq1zO3y1uL0st6RPhQYAHK3D4iFlmF2bG2L2wcoV4UHicVXN0FX7 +OGvaWPbQmm7v4J5u3sGiSYtlqGxiieRSWHCrYTZrz0+rMdirhhY6YwRgXae3yVUZCEq+u8xQMi6A +SHWdVTxDycKlBCeMxb0ThxljLNtjy2qI8a8axW3XPeVKRPAwH068FarxBFc9XepDUBaDweVZ1GBc +jDEATEgMVnZC3DbhFQQ6wjtW25IDJ4PLjyl/Qpzdam4TN6kkHZySv+aUzQmIue/biiQS5Jmq52x/ +C4OPYPGsLimGzxJ2aiGaXt1HpfsiIVfVOU7BEZeaPYqr6fNf7N2swaVSeocZ+PKtHkdy9BAeOcry +BK5Doy1/QvI+97mgPiLHPi4PfQmaBy73ZWP9KVV9by7Y52/u5P0j0vwfhjSPwomdaI7oG+sNAmiO +wHlNfDn7LiqAsuHMz8e536CZA9+voxtmDgeZ/MyNZY7K1PuUIweUebQaS5I5lnsUKW8gcxRiCTtq +jnl1r+zEmMPAwWfDmHO/okocBvxw+JHI8ltd8Z74O4H9AckOgjnCTQy8BsAcrYXvU/PI5JdHx6HE +lzcnQRJf3qya2+nl02p4eXNH1WSXA/9Ips6GLgcSCv5YosvbGc2sHL9p1jHs6HJmPA2P5lCCMIKq +tE0uv2JKXsnlkPAKru1gOhUMTck/xnlZ7tCkcUpSwRVZ0MCWo26c+fygllNbUe83aDm78V33ZJaj +s149g1jOv/rOK6fteSauHMeo9zVp5Zelhjus/GoBpzGrHGEtdVY0qxyLx2Gyw4T0Mi/dyiSVd1P+ +E1TeVZK5Y8rRx+g0Tx5z77BvlIxyzOKHcOHTDeNcfxlLwTaTj8uEA1E+/JnshPIRVJwAlKPucjye +QpF7Ifr5ER1l0rNRRKdctOnkQblOOPloZsdsbHK0BDpMvWeE5bUcYnFaksljsbCDyQ== + scyQn2cu+eMOkoElf0TR2qHkFPuc5o3jP3Dw5zQZGsnWxz2odyL53T3gBJAcGI1u35Y88mGV5I4j +f27V6CWNnJV2nLKDRs5uIMRqbTRyNQlpcqxEsT8iZBs0clgImdlp5CUc76SRw8K+PwEjp0FS2Htj +5aXI3zByLMMZwggYOVZMrC/aWOSobzyNdBaZFuV83C5Q5OxnoiLxFUUuM4vqDQyHRRGzYa7fEWWv +K4sc5rGQyNnphSLg3KtTdb6ByIFSJ0UtOORP5mwkdUYRCuVHG4UcM8mCIH+8DEgC+XOHvm4FkMMa +FR7RrUkTWODHcTo80EYfR2Nwrr4DPv5E0UnorJ9hCv6GHn8CLRzk8fuKVYjB46he5nJ+446D6czF +XmDHryf8MmPHs7p8o45f1pOaOg5yCX8+oOMgl6gvx8ocvyLsF8jxy3jeRI7DELzKiQNFHkjVxAaO +RzvY4I1TnUm93oobZ0KkuPwVgdru5G2wxhHoZwpnY40jD8XXJ1DjkKsd/ZwVCAhDX2YZTNA40las +9A3QeHMQKjnjKAe9rDGdmHFkRFoJKf1rlAP4o/sl4PgAwwjIfYaYeDTWuxgxzlR012dG2TKLgBgD +WQDjWBjqVTFfHNlMlUQZLw7XjoDyjS5e+6yTUsMUT3XJFv/gOc6IrVXp8Awokd/I4igCupWm5b8C +LMMyhuCKwxHgELphxQmRKQqSE7bCDGp1+Rxb3EYKcmOKY8VEoG8gxfF7XDAGKJzNHI/rDSiO7Atf +n7CyPOtRHpOwt2g4vNPEke9Retkw8SZfKVHiSAdSx7KRxAEr52sY2HCc1QoWh4/cDAefFPHL+LSE +iMMQ1b3MPcMgQsGKEIea4jKnm0IMXC6nkgCIT8PKD49C0MSHXxHvDHr4dUmAtMPDr+hKFuxw4Mm7 +AeAkbMN37iYTZOE2C1qICzU4HCtKpYzMDSd9+dFDmNhwnNVVJzQcDA7W7wcz/GrOmW3IcFj1bZoY +DkMx5YIhVoxNmsEnLZwAl2qGOC+lGfkfrHAgnASVWFHhSBdrbDcpvAUTOEDhrQR9fuWEt1DrBCYc +ubjTxcEc6c6YijdIOIQB5AUHI7xZqp6I8DPg8Rsh/AzxSxDC0aJWdZsGhLNnrfUQkw9eH7cqDDx4 +VbPGhINjt1OHmZVzeN81nZsMjoBSZ1WZweBniJVXLjhgAjWaN5ANkMWlAfvuauO9Q8F7kNZsPLhO +raJbeHWNN8W9KhYkOFd41ySC9yhgFA/8cNZwx4G7OnfSwKOOOWHgh5PQOwvcNMmJAj/o+04QOLyw +8oYBp6/W9cCZWm7s3StFv6o+m3LJGwP8ZshbtVJCgB/CjE0C+ON0zg4AD9F/8L+5/Jnwb/xJ9cU2 +21er2pP9zc1MjlGCAc1E7W4s5G+HAxP83VVTP7nfadiw32kN6vfjUEewvBmLLGMadJrhYeVm9qeT ++D0NC/A7jcH7rln5GrjveC032vdDUUD7FLBvrLWohwvW98Gop6HeUz6LY0gsJta3WA6tTtb3wRrk +835jfR9EYlKcYtj3d8j6mT1t2jdIDpqEN9o33JTuthqSrPXo7RnkygCIb6hvrNiZIgnS90MfVzIp +fEMMLJyf3jjfKDc6AupdCJBwJ+tAC6OeXryWDfMND0opxMB8H4Tzh9jiZJvqISHARvk+iRyVjE/D +DO5XsdZSBRVS0u+I72paQxK+z6rSjAR8YzCT+mnle0PUQnBL4L3P6vR40L2BU5fYc4V712hEGGzv +6lbRifaGIdqszoQgjoaahQB7QzzQQ+tAffHlCNmG9YYvKf2ngTQsmr91vayBJHK33592qHdao/wH +eg3WVwfTm/fJXtssiiAf5hyT6H26BiuB3tiCS4wN6H1GfDF43lBJsHg8cN64AEtoZo0nYf13mTDv +8/HgESzvFOWtKG+o6DiABckbhSGsBgpEN5hMvNyN5M31yblYe7AWAhSbho3kPa0meV+P4/QB8v7g +iE9XHQOTa7ZWjrf6LY0yQd5U+LHJfJC8KW9kwcNG8sbHy9hCkryxobCZQfLGg+ekvpG8aWV9QfC4 +9brXliTvwmrcq76RvPG+PcZ2e8duwrRA3vz7Ni36WGD4zmgmyBtSzhocQ8WOqZ+qKsqYIG/yMcQi +McibslCRWAzyJh2JhSsbyJtmIoEC5M0nNfrkeFNkwxzwxvGmsCbKPZiGhqQGl5Mcb27CT3bjeMPM +5tfJ8abo9mhPcrwhGRIgcuN4U7Ovqcsc70LO8ngmxxtvqCqGNo43tdou4cgGzAxjJMZboCkjzJc+ +kVmwHBhvyKUOQjgD403hMyk/G8YbZgVzA+NNqRwDucZ4SzvHarUV4809WVUTGO+SwMvAeMPC4N2O +8caFDR9QlAeEdhljD4w3BVSsE18p3uy/HJ+VwgUIiwkub4w3whxXKzvGG2G585oQ7wcrrDImKhi9 +FXmiK8L7MdEsCd6P1fQJ8MZx3undzx1P1/BuBvMYZA5+N66DE9LO70YFVAT1CUZ4SgCXTO8m+fhU +JVPCuxF1Jeg/4N1Q5NzeCNP0fQYqeiV3o8G7ItokA9/2tZLajb343m7QbgQEqTgIZjcjjqxlDmY3 +e8MTd7Qxu3nR9dCuyofh4d0uMObUhOrfnkXZwbZ5TtfC+TNnO3anWkiUfAzn2oHdsLKKKnjdOI7i +zsJ149dUSrTQugtFE4dK1NxJKPizgevWHOMkzcR1i7IXbWnZ2Y5EilsHE4oFXAkO+BuuG2ZVPAau +mxbS14zrpqFaqDZx3TSzHCtw3fyJlnBuTMFMpj3npx3XjcC26lUD183aDUEIYt2MKm8rsyatm/Ui +rPQJXDcqMPTrgevmTVKp6crrLgEFSF43O7Qz1h+8bhZvqE5h5XWzhCZR33IShkscgtdNC6mJG6+b +glqKJoLXzf5QXAYGsBtzlyo+N2C3JLaUmhnYzQ1VZXxHG3rnkXZiN10frmiC2C0trjdspwWtzdzt +CeyGVW6Jgd00dIvP8jcJGt6J3YzwST5oYrf6sdzS8Ih8hLjV7ZYEk9jNVZXakAYUkejl0z0OWLYO +C4fqDdkt8x0Fq6c2dDGvkN0wiH6/IbvZ3Ib4gEB2a91giLfW0mf0O9mQ3er+SFiLkd2Mh+kRGtnN +ZU4Qtieym9pzYWnM7KY+Xd+Imd206GNYmd00N2d+FRYcggUksps/ysrIDdktyX9RKa0Dj7eyvons +lpb/cA/WRHbTfWSYIKDduG+XqB+Gdiss4oLYReCE4MhpRLc50M3TX0C7FSq5TDpJaHfJfjRmdmeg +JZndDM4w8bkxu3GpcuaC2U1fkQ5ILngx+bKAd2N2YwHReHLR/ggrJ5XDEtlN1B1fpA3Zrcjy0yey +G28cET+J7C7XFXScBdnNojECqcODYUNITsWB7Kbrrw4iK7K7pIohkN20MDUcyO6Pq4ZlRYGRmd/5 +huxGJjIFV8pTgBSi8qhwBsFcZM/0DdlNMxucGdmNn6BqLZHdsHDi25HdMBPOk8huWpSdNLJbFibd +VmQ3fpSUzkR2I0VK8VYQu5FSVO/CFdjNjChJ1wHsfpxLSxY3BkDWRGzM7nFGfthWYLR0f0zs7i2K +lFZgN6yHI1+cfWAg7SRw3b1NIftcEnTnexLW3WNsis26QVc7qru7U3qSusGrOxxdZ2wMbdg5D22g +bpKu72da7xE0M3O607BxuqfVnO67Rssw47fBxlLD3hXTPS6H4XMzc+YT0p2GjdE9rUJ0j2hKGIhu +gDgYfF0B3aSVnwugG1FuVcSZzw2DppEVz439OO8HnvsOmVHQue/Db/8G5x7RQC3Y3GDgqF2k0dwA +vnCY2sjcZDE3hfB4F2kouhxOK6MYX7liuWEk5TKo3DA0lynQdUVMObjdk8k9jqn8Y5p0uNtVIrlh +oM5wI3IDecf6yAByI8xKFnkAuUd8yAuPG8i6btoto1s9eigHjRuMVpY8bDBuWg0xp1oA+wnDahT3 +y6DI2kbi7rE+MIgboV/1bjNPIknkG4ab2lS2+TOFG3l4xQEM4R5e7O4MbjYJf56J4O5RCx0EbpwQ +S442ADdPC+Nm8LdxqzkgBH4bBnr3K307AIEJ32ZZZRuTvb0eZ6K3s4tzkLdH5LGCs50DxAbeHtar +JXd7uFVE0rRRVMFRfqNu391VALnZw9ViIrchR6TWYyVuiy76TOA2DJxjA7h9h9hl423DyuEoeNuo +62AGI3DboIqrNm6lbaOKhguAgG1j6c30m1nb+feG2p5Wk7ZBx+lutcgKtjuiTRtn+wn8VGC2sTR1 +R+/obkwFf33eMNswayUUcT3Kha4Il7LQq5u6uGK2YRWoNTDbsFDYkphtbsNDLJhtzLUKiwdm+zFb +KinbWB6p7fsK2X5dpCpfArLNE+NdDsg2IQh3ILFn9QycTl57QLZJQWBfgoBs84HebtE9Idt8rKzN +NmSb7weH0IBs06IY6QrZZrPQuAoF2I/bBSaGbH/0nj6nZ/XHhGwzAslg2QbZplnZV0O2FZmsYyK1 +GXFUCfIK2WZIjOqmgGzjMfs3DNkGDpMvzMbYxj1wHbcZ23OZHIxtfetuiLEEgmv0kw7GNi28gisj +pF2R252xXYJuk4xtWCRuCMY2S2xvbTIR27hSiewCsY3XUFisQGzDK3Sp94rYnj5wKivwvoasRIyM +ElVOG2J7MRuxzSbPzDwEYhsWqdw2xDaJGYwPBGK7kH9eVDqrbvQQC3Pg2RDbeIWtHDFimxJDNSY2 +YhvPWaC7DbGNcj3S04Kxjbo1ce5dks7ueZ92vjY0ckpFGa8NN5xDStC18brIk1/p2gwicTgPvDaD +SOqE7jGEFq5ZV7q2rFQkGa/NY10B01Z5cPXwsuG1GRdlh5Lga+O5M+aYfO3nDg76AthGPVGU6zKZ +cwcjI/DarC8qwmhPujba/LSFrQ0hKCMpwdZG145baY0ZfRxRMBhkbZYvNq1omcDLtuwrVxvrIyFn +HHShcMXLWarFACykg7BBtYdbjCVTe7h4LZHaALIxErQQtdEQiON2ALWp/zgcTIHr2R3s3HnawKIx +Rhc87X5GCMM4bYLUlK6eMG12tKIgySxtHGcBafdI1G4c7W68VhaiU7Po/DGDorgM5c9WijaUFIwx +BkQbSUN+VsHQbiHc2xDaZMw90iIytg0AA4flAGi3oajKDtCG3kulwQ6cQ9vP+u/AZ7fQQ2z0bGiU +CGYJeDZEdrfPk64fyM7tDZyNEmWBLszNvsQNCmg2FlYstN2Y2bCqCMw1+BBbMUAX2GvIsUR/WYHZ +l0tQkpd9uQfzshtxmzssOxsuBSu7O1aaqGzoXziJb6RsXAR/LkDZV7RXD042aszU6mrFZF8BqAhM +9hVzWlCycUan8ZgzN4+phsGRYGRjehqGZtMnulyItyOy4fQrnOCQEU6Pb3gAsqHLoqJ65WOj3loh +GMdRnyvaL5qO/XSns1c6NowMMwUc+4me5sHGDmbmjsZ+LAhJMvbjPESCsWGIn5tgbA== + JloOq+4YOotUSHKxoU6LYNXEYt8j2mEYi/0E5jSo2E8E4FcoNlI9eol6JgOK+1SEWJuLJ7p/GxSb +ZgY+AopdyCYuz6eEYjMnQZ97o2LDrLxSULGJ4Cp+HaTZYHOb28UBs7RyHtFYbFiU3wosdilRhb9h +sbVuetrEYjMHTpcosNiiQBjtvvQVgL+o5nHGYjPxrOZx0Qnsg6s5g4ffmIsNl4MNDjcs9qNi8IRi +gzWgTrRmYj/WhO1I7McDeBKxYRAs0EDsx+jFnYfN6uGzTxz2E0zroFwzeskk6EbDJhSD5OrcEBxO +dnUNHPaSyVt52FxXqIOIedhc1Y0+cdiMqnbXdU6mNWOr1HcHDptnd56Thk3//HzOr+ypnGXQsGkR +P3REbUt12c2Kw2Yhi0rPjMPmpQ8i6o3DTsuGw8aehjwYh40PlQHgxGHDBWsq2Vlx2DCfaqM6QkTp +AGrisOm181FtOGw6dWRXBg4boAtV/omGzS346DYcNk/uPCcNuxyulEwaNqtgOCqvNGxaNRCYhk1L +dwMMFiseRWHFnYZNl7S6LuHUUsSVS0nDhkWVGRsOm4vp09wTjRMsDazSLOs0MKhQULbxsLm8rlHv +rijH6ZEjeNhKOeOfNh424zHF3AstNbC+4hASQGxC6TgebUBsgoIkqTYQm1A6tfgwEFspmiYl5wRi +U/zCfzcQm4bT+OuuDnmXsdwrDxu5VD+HiFmUKEMNHja20W3beNiEXEbvCuVGkHRVpP4JENbj6M5G +xCbBjDrS3PAKPmYQsbH21Ju0EbEZ1hYO2ERsuKZyTQKJjWiEAm0bElsEqbtOJDZ1jPoqY3qHhZLm +DYktbWg/JxJbWLEJxOaOqjhbgdiMzQcendDiq3itFEBsLkWV0Zk4bIlBn3PisHn2TDwFDhuxMZV+ +bDhsmP2TzaunK4rhjMOmReCKFYcNsxElwmFzO90N47B5cI1YKw6bayNyVwKHjScvUaR52NOwAbEX +s4nY+AkFbQJ0zTBU6NwXbM0ZLmFuWGOMDyL2YlmJ2NMcRGyuCiUqMBE7392dic30+LMgsQkOoMAh +kNhMalaXI079J818VwKKzawm3yZBsZmYZFRig2JLlD+eCcVmaQiDUgHF5jZcO29UbCmuR59U7NmX +LKjYjIDd9/VGxSZOVT0rTMVmKootGoKKza8xxAdr1yLF4ZOKDQNvYVKxGTNjp4uNis2IE9urBRab +Fk10wmLTIFHEisXmY1CnsyfwfVc0vjYWG3EFFbpuWGzixJo7Mqr8B6liltIHFhuDoL66DYtNLQo1 +VMHFhrPp5h/mYjMQQ7TLxsWGmQv45GLTwocVXGxa1H5x5WLziBQUBReb4RgVpD9xra5t2rnY9IWZ +Ng8uNtl87BkYXGxmMNRQc+ViT3NwsTkHshVgcLF549h/YeNiw+zOO05AwSKtV3CxuQ01XBsXm2Y+ +s+BiC3U4ygRjUxHZ37DY1HmyAj2w2NAccaxJLjZzQ9WdWiYXmzFysgqCi82q5mfFXcPrGGqDuHKx +H+NI0prNlQKVmoYNij2t5n6h/1F0Lec7+WE18EdYd/C+H9enHYl98i6XT0nExsMmRSuB2N3D0c7D +7g6/JA67OzSdNOzbvsYOw74dfUygtYv8Jwr7jhdwI2Hf6q2w7CZ8cWKwbxfX7BjsOxJGxmDzfblq +ULChdlF+ZIVgB5M4IdjQoHGsC650tZhvQ2DDKOimCdhIQR335F8zmfWcb/jr2iOZZ/o1DI+75Gp4 +7Oo7sMOviRXHKkjsa/Q6oUItz/GJtfSKvka9Bh2+IF8HiyrJ12c0Ct/A15B/ISAd2Guqn9s5qddA +VT078vq8wu808fqMTs4BvGaK67jfeNdnCFwCd40iCAavA3d9Gn+y0a5hpIsasOszlIsBu0ZajH29 +N9Y1aoGeOknXSG9oYeBXCRU37Kyzca7bY7J6YK4ZPHzOSbnuoUzdINdIHbVnIq4hmSFdLwjX3TrA +HXDdvShIvjX2YyA+8NY4MON/G936GvE4Hbi/ohtrsK0vz2E72hrtDiObwagTNDdjBO8WIf3gOW9c +ayzUlKwU1joWgYZaD6NmdqY11o6O39ON4lqyKTtAXxm78S3dgNYI5WTBB2uKm7WJgbOGXFBT5kqz +xhV393dlwpSCmksRfAbCKBVh9mtlWbuALknWFDU4wcQ0bDcCZOdY9+j6Ehjr5AYExboHoHCDWLNL +zqkFCBems7DbE+cZ4IINYQ0NKifFIFgDqMyEZwCsL/OFNn41ATaI/RlffQUTLOjVV0hxN3g1rCzI +D3Y1qDaM/wW6Gr9WkmVd5/ej0FGAq+HTkboR3Gpm1J9PO7UayRNG/gJaDWYQP7tgVp+WC+3I6jMb +OZpYjboUAU4NrD4jRbUBqxP5FLxqGDQxOjkIAyMlG676jP4AQasG3Y+jQcCqE9a+sapRYac6TJck +nZaim1Rduz/fDVRdQ0UYnOoaCorAVMP56OMNUl3tiSSkGgYGccWortE3dUNUvzwBLU6TUN3i/TKg ++uII9s6nvjhOLnhqFoJ0qX+5vKKk5LaoN9N0F0r/jjbLLTGckngcaGoErchE3tDUD/Oy5VOSqZtb +oSWYeriD1c6lvpxoSCx18bwdVGpLaHcotUpRbMWkJjHh9SmR1DepMu9EaiBa2DgjgNS3F4KBo47Y +/BuM2vqtZFGP6D5hFHWN6rsdRd0N7EkStTWWCaJm8uEDh5qRmSjXxMftSSsh1Hg/iiv5JoQatXFE +UwRRBy+3lzD6aDgiajk0CdSn3asAUNfwE4I/zcJ+g7cTP436v65SVHpUWA/x9Uz2dHdv0Df2tOXr +gZ6+GHIokzytJVmrb+RpaVzGOcnTCNNe7IEQ5GnqU4+wpFaLmovYkHEYWNQ/MdDTH132b78swNA8 +Yk0e6OnmLF+SpwMUl+Dpq4ZOeOVOIyAhNqex02CHqOO0qdNXlMVu0GkQROjJBHMaaBClYY2chmF4 +i7lAukL8YOA0UsAUdwVvGonT6FY0VTxXlB47Xg8ZLEdUU6TRvDoSjcmavktkvWUkzredkzT9FEUk +dtA0rBxgAzQNg1i7znCBucsK9A0z/RiKk5RplKcpROjN8A8M+myM6dvlnMmYJlD5HhMdDdIHp6GN +MD1MwkhrdzVqAqbTsPGlw5p46eG5PqHREClzLb3BpSEuVojI1ru405jQ0vPPlSwd1gRLj9AEBVd6 +BHR1w0pDcN0CNo2JalxBTzZUGoZoxrj4stFzJpDSI/RUgYQblxOrG1AawC/GmsyTRq2VavGNk8Z3 +1N2vcQKl78uOePCkaah94qQZLz+uN5o0wEf8Gg2TvltgtwWTZi/663pjSQOQqfS5UdKQmQaDGiHi +2/CVHSSduLLgSCcKMzDSt7/enSKN8q3izqVRWchKtGRIw1AdsZ8I6SciPEGQBkXrCF505XHkNm78 +6GdtnYkvkLDu3ic9GtkepjY2eDQAadVtZqMOdahexejo24vYnRx9i2+X3OjHq7PERrOQ8jp3ajR5 +4WybZ2g0ToqFvsGMfk4Jkndm9GMoSyKjn6gMCmL0eqAJjL4jUxy86NtJsoRDx/Cw06Kh5GUnzKBF +g95GKnAwoEf0qdxY0RAqkBQaViTWnwUUTY39eN440chjMb5pTDT+ZsWUKdHjiGLzFRKN/FhUnItT +eRgIFohopNpYgL0RorvD60mI7lF2F4joNGyM6Gk1JLqbJZWEYqyQGXXaENHodqA+yh6sUOgVYEyO +is2FizsiGryuyzeTSTksnGqffGisqNS4cMVDY1kGPy7x0Fi9qd7KBWbNsocdDn1ZRZJsaFCd1LTY +aGhKypjKn2jobrVXkqG5zHPxH+vBCZl11n7KbejHlTK50LE0Ti40F899vGGhsdAmAyDueasBRTAU +ullpujOhwe2Kc+cHE1m5REK/u0afv7nz9f9fJPTXSM8/e/zr+PRP/+KHv9p+AAf87e9+9b//5sdf +/fkPv/v+h59+/6t/9cP/66O3T//0X/z0+69sjv/3V//P3/yg8/ry2++XnQoLwl+v7c/91r/5zWvH +//s3v/79X3uP6+d+5s9/98N//80Pf3j9yt/87c8zsJdLeJ3Ob3742/VkfnbzLz/8p9//6nVn/4/f +/fan3/8Pt/43v/2vHzaOypO/8zr/zx9+85//+vd/3wv9i9/+4W9/9sn+6euvf/Yvzl/96U+/9u40 +XDD86s9++9Ofv96+379ewO++s/2f//CfX+e8/Msv/uTP/iv/7da//fPf/be//es81j/5sx/+8Ml/ +fSr/2y+OT//sF39yfPr3f/jFn/w3/MeK/T4+/cvXf/2Xl+0Pn9qnf/3pP/zH49OvX3v8+7/4xZ98 +d4PPzf/5cf5FMPXLK/hCE/6iJvln7a+dvmzHev31E374/3r9z2vkYSbuQJvQqv/AahdlCgNeOsBM +r+Xla42H/3gN4J0WRghRwPA67msSKQ3VcqieYactnS2aXCK6Nu0wNgHJ7sJQRH2zIV9wcaDb7SBz +vH5iPyqKfV6j234KNvoIkADRuV43dvRrP+w07ucw7fN851GXC/twF14H+E+4xQPd04Cze6364dex +hQ8mZ6LhX87QjZqR13L7vE5isB54X7i55fj0r38RDxPeMVIWJxxe3eFChNVqh/FURdvNhMdr4nkz +usW9Lm+xHwJzbIdFdg4vw3YOYfx+vmjbuf0Nrzv+iaViCEdUAY3i+Odq95lgfXyzlLv38makLKov +p207MWv903ZYBFGg7drOIYzf/8y55Wn/4/v8d7/P7W7VOLubYZzXxs8BXtvRGl7li212Ucc77oZX ++tQA4vEC8VyENt7vLxVj5dpPA5FXrrmW811s27Ut9nkjlqPOW7acwnZ/CQe43je+RdXfDzuN+zlM ++zzfedTlwj7chf/18eI7ng279b7fXJx6P+79HHCRyB+sJ7vYtgtb7PMuLEed92s5he3m4jfgje8b +I/da317exbifw7TP851HXS7sw134Vi8vqXjH9WFMYwVRW+3facgprKlZxrTFuI1pi32OafOwy5g2 +z2Ef006D4vaNWRr7fthp3M5hsc8TnoddLu3jffg+xk/MMO0oH24RZpjjfDsOZd38XtZhfxr3YX/a +57XMwy5XPc9hv0VU2yCYuW3Mbg/P22GncX9M07480zzs+vQ/3Ie8RcsT3Cb05XHPCX2+GMuEvhi3 +CX2xzwl9HnaZ0Oc57BP6fNzrxvlirIedxu0cFvs84eXlnJf28T585S3ab9HyuBefJ1+M1eeZxt3n +mfZ5LfOwy1XPc9hv0Xzc68b5YqyHncb9MU378kzny7k8/Q/34fuPjkplV5MPforNm+uByQh9xXYj +glQaJXc7RIet7n4Kpln0kNnPwMZ3P2XdOF2P9bDTuJ/DtC8nPA87r+z9JnyTaXTOztutnc7EPIHp +dSxnuhi3y1rs8x4sR513azmD7dZOZ2LdOL2O9bDTuJ/DtC8nPA87r+z9JnyrSXROzw== + 292d3sQ8h+l2LCe7GLcrW+zzNixHnTdsOYPt7k5vYt043Y71sNO4n8O0Lyc8Dzuv7P0mfJMXd34O ++ILGeX0YFMK+feiI7Bc7DNPYU/C926FGOMY+KuCfEX7Yz8HG91Fh3Tg/9PWw07ifw7QvJzwPu1za +h/vw7Zcv+x2eX/FyGvN7X054MW5Xt9jnrVgOO2/acg7bHZ5f8bpxfu/rYadxP4dpX054Hna5tA/3 +4RsvYPbbOz/j5RzmB7+c7WLcLm2xz/uwHHbeseUctts7P+N14/zg18NO434O076c8Dzscmkf7kPO +++x383z0Hps6Jry5WFb4787YNO6e27RPH2YedvF25jnsrtHHc8u4Svu4JGiuutqXFjgJrTeWRcg0 +7iuWaZ+++zzs4uW3j6uB7Yx0nv/WYd0//enXe1D37xXsPb9BsJc38EPAdwnr4r37Oav3/vLheFvQ +9389Iom3uisaQDXPuUwzVWdtu2cOsEe9bC9vNizx2zLJ2IxwwGif9oNeEi/sZ2DjnGSeMd42HhK7 +74edxu0Upnme7Tzoclkf7sG3nGKwwfvdra4B2k6Djgpf9nm+i229tMU8b8Ny0HnDljPY7q58mvq2 +8S0h3n7YadxOYZrn2c6DLpf14R58q+mFlSzvt5ZnXt9eXF7jub+4i229rsU878Fy0Hm3ljPYbi1+ +ovX+tvFtCcZ22GncTmGa59nOgy6X9eEefMvoGAQtHlXPZ4lrsNFk2r/TWFxHi3H+HG9GQqDX6Jjt +h+pntsNyXC/3p+0cwjjjGlBm7hufUv/uh53G7RwW+zzhedjl0j7ehy2ucclj3m5RteJjOw7n1l72 +X1yM2+kt9nkt87DLVc9z2G8RPIT7ft42PlU2tx92GvfHNO3LM83Drk//w334Ngv3fE8ya7qY6Bfs +b044EPtTs/H9zVk3zpdhOeq0lQ/vbVszY/mo8iwXUx5veSfmDy83bjvL5S4vG+fzWI46beXDq5Nn ++S0Hg/jF98Eg7Nt94nU87c3oi36/qXGHtsO+BTl1Dh+DnHqkb0FOPb71sNO4ncNinye8jDHz0j7e +h68MBvstWr7aeZz5kJZfXIzb6S32eS3zsG9BTp3DxyCn3qe3IGd7v0WLcX9M07480znGLE//w334 +NpM9/OLz4+0t7g273153P9xv7zTut3fa532Yh33Lm+scPubN93Pb8uaj59okpwgcv9TV7jPp9/U2 +RUzjPkVM+xzL52GXUX+ewz5FfDy3bzZcpDstH/HDisLmbZVQXe22G+06vi8p5OlmNNtHtU+8n4GN +70uKdeNcJqyHncb9HKZ9OeF52Hll7zfhm0Wz5Utvt3Z6/vME5hJhOdPFuF3WYp/3YDnqvFvLGWy3 +drr+68a5RlgPO437OUz7csLzsPPK3m/CN4xm253e7u50/uc5zFXCcrKLcbuyxT5vw3LUecOWM9ju +7vT+141zmbAedhr3c5j25YTnYeeVvd+EbxbN7hHfu0f5OCiEffvQGVurb6MCA3HX/WFUwLHQYGo/ +LOJ7+wcp0/uIMDfMT3w94DTuvz7ty6nOgy4X9eEOfPsgw35v5/e7nMb80pcTXozb1S32eSuWw8Yt +W85gubfz250b5je+HnAa91+f9uVU50GXi/pwB75xiGG/sfPTXc5hfuTL2S7G7dIW+7wPy2Hjfi1n +sNzY+dnODfPzXg84jfuvT/tyqvOgy0V9uAPf/08GV//tTz/91Y8//PrTeA+s/sNiqxi5fslKAP7H +UcnU/q6xFwmKVqb9y7v9eq2bumS162F+xjyP8pNP8tvIbLdTGuoDPy8B7iPtcgBlHLYd/W62Xcdr +cUJjOSTwl51lmrQ3FPN/uAf+wS/yUBu4Zq9XnhcM5GS/41xQ+vP6EmhnhaOMdCD1uwBPyMiaIv0o +iqc+xxHO+E20P7UJbdx1gSi8krGMw2fAAsnc/3h9qT6D11voK3/yqEozyOg7RORG3gzWjvjO1cub +shBeZ4DyFN82DLzasohOKjuLRnRv8Gh9Wuj9K2O7elzYEcbX0mC5BejJ7Ut4Dd2x7TV8gHkT3h7D +53hCBJX50BWdwn8MM7uZ03w5gSDzKP5JjQMyPk9s/PqfT1877vzF+5etHP6n47W4iJ+88/3s6tRr +Y9VxQCC706ZXAoBXsR1sHyM2Paq3ZUMVHZRxza+dwTw5NAzS40YHmnbGyYGqqmu8VO5qI2ombXyu +MB6x4aNbHds+Punec3/UuMmGGtavnsHf41kRlEZ7QQluPiwydL19i+fS/Iqz88b9dz+sAZh09ef3 +etlyPEQ/nO43Hctd23LcYNNmGAE9vPydEN/1OQ9QarUdiJM4anzBbeiMhzqDfBgAHlX56gyQw7Tt +zrPquf9+CXl1N0oCix8AEdw/pv24+mL/EnaCg2RHDMzG7gd+93uEDeXdMpYcQj/+YA6VqDdEaar+ +CcyrH8NegIfRofBm2FiLvxWObzaimFWP8YnPAuYSI+BrKBjelg2DZER1mI3l8NjBFHgeIR5s12OP +jUfcIzyXr17E+iaN4/KAe85Z6VGZo8zXaDGpoNYn7aBH2HjHZZ8xaL8feD7eW7XtunVPid+8Sf9+ +bG++pTeqWUc8sjNslwefoWHizXrXXnPvGsbreT599ffj1GDA60lH4DgcubG5+Wth2CeMnj+eUWra +ur8KlsF+zgOAROcD8LOSMZyX41gOsJzAPLX0UcCLLXecGqgYsrLYMB2ael9+IlfDytHGw+8LaxA/ +GM/nijN+/7n4IthxtJy+fefr1faZsCXp3cM+eI00jvIVYx1hjE+CrUvP7sG4ov+EjSN8Nnw+Xz2F +vE1AUN0x+LMh549hr/X0iRBEImN4C5faRsl4+QvCNxgnJ+3YiCnrrN62XHfd5p+vnML6tbETjUbN +555fG1GQMWhe/oDYn8XGM76q16vb5vCaoy5Xvh5hNZ/ixzD7edv7/vS1M1jv3H7dP37N3L5yi16D +21/mzR897Jh/vqT95cHZ3o64TcRJynjWn735fu1uscl4Vznh/Jj2Ev7FddbxSUaCe2UcxxnGEQ4K +cTaf4whs8ueNkXmR8b78c9QMfu0U5tmdkvt4OqjxebIdUzvjDbviAyVRtIR9FP2mS3xt5Gj1lSPn +jxbowu9n2f7HsIczcaly2sYrx1F9Ry/bdeYPXjEf0l6feXY9Nma/C51IucNY4lOOsdS/hnHSR45f +a+2Ko2pM+ngJ8+qAQDnG8ns/pj08ORaMyfaai57wAO4njCM9TyyMPscBCAyyvfbYOK7jqXcN2xHD +DIkrn3/mzHJwZB+kWBfR7fgx7OUongCG3AUaz9OeGfkzNnpIAce42zOjXeXi5IFxXQJj6z1+7h71 +01fPYfcb4xfhlef4wwXl9AZtrGNx8H5m9LD57OE1oiDfRjs4Q8Czv9trHHe6oyXdzjHCeExvdruC +9Wugb6q584mLg52IPdmv/ARRR2/f4CZpXrbuG+FjfPXA+Zug712+7tenaU9GDe3DYb5Bi/mS9qON +5cn4GKO1MNJp/HjgeZlm8324zCrSg1yM5/YLPJ1x0k5lLD0mG35A+VaXcfm1ISXQxqfmEc44Qj3i +LSBI4vPPnNr6XRCI6bf6PJfvYnnbuVj+yifwl/+Djbcj/zv+KJq7wY/BE338ROnp/Bh2RmdspyNb +iaw8/ShiGCHuMn51HCO+R5ShNL+IhLNp2zJK3K4R+5Mkxl8qsfLE/qOf8Vp6iroewSb1Wye/AxjJ +apSx5e2GvUUMhFg6G0scgW+OjYhX+5G35RzmF/by8uKGXjX8jvs5YqiqR/GbGz6N777H2GFtvYzh +BF/39fWnlPtTgK5v3OMujY8PWtuRxsMbljl5b4Md+6rCOLQMpBcBFpRsEdcZwjf6AO7y1DKsZmOE +5I4Wd4C9gWUEXiT3J9FJ+4MC+SXsfXpftcZtYNhRB2F9wpuRravyyLH0GXLNZXy5yL7eoiU+jAJS +8rDX3J8RMD8HDQk4rSdmDL5WcdDY30DVOIFYtgPlk1fG/u9+c2scgqtNTwFxWq910bNsmMclektf +xDjyGlq8NeyZAyNoQccyqPkAfX1FDz/0LvyLPpPyVBuvHk+dEUsf4cpJAR1W/KGJps/TOm/fGri0 +JUbLMx0c0PLPODCjEjLWu8RzGJ6jm5om6BSO9CJAdTvPmAwwd/v2tl9e7W0YBqD+Ov0oTrlOaL/e +ctHwnHlzmlg8Hi5a8ca9XnG6cF78S1ec7lieOyA+9+3n1uUr4rAl3v+r3XFeRz/KYswjEHfua7tj +ziUgNl4pu4AXud3j7TWty0XwWfvAdXn9e9UIDbgfQlUeNa8WR6gxtvEL9REAcIwRi/REGMHUibM9 +whRfJdyDcMOaUc3hyMVH0WbQcfxSQXLYIi6CR6mXDBu2nCHSKX2Z28iPynfh5w5qp3SoC8A8QItv +ol/99MYzB8Dlh7d8ekzf59nnEWbsLxazbS6vjGOGETNe3oRS4t42TZA+3TuGQpKKjoiKaOEAMur1 +xDj2aIxuyDrEU+dn5+O6Y6PfhjPyNq1nEA7XbNcJvUni5E6vU9Cw8DnSoWoxi7/sZw9Hyz5mbado +eHoWXuqjwXR4AYxd+wDs5hffEJVENJL85l/TvNrcYddHHXnba+YLQFbVnNDcRltXphg0jHPEuF6r +pXmE8DAwdPbpbbL3ljYf9Z7264rn/LTSFu/0Z7xWAnz9EilKgoOUJweUs4fxiMmln+lnvOwc5j05 +aLBEx8qcIB3uk/GIW3+MOML5iPjlQW3EZ/eyz8E11tHQSp6xmnjKGUcmRc9TidpX6AgjnY3XBFLj +CPnxR9gKBHlPMADjZtgKRzjz9dagj22vWPzEh3calOSx46zzAFx06QD9iY15/R4oFK07b3W08JOu +8Q6hj0qL0QOf2pcwlyuWPvS/YEzMmMKOOt+uyjwbc1RhcV64k89xxxGOnH412mL/88xYUwv37HQO +zaPwkc8NVN94I2IcP9XIrIWj7f3T72z9eOZxwwfRQlQ2ein+Lb0L+KF0UJ9zzP1JzovxoM7zYiez +bcgOtKEfRY0zez20uGMIvc4j1ysmk6dxwDwRaCheGXH0kDEm9c09gv3snn7Z6ehL2MNbv7XMgBFo +6+HVxcs/7TaGa4Ah5YxJBvaaH22v1Rsf+SVzaIQRHVOe8Em95pWdIHrPEbEtk7L7O1LVP8xzarrb +UDmWWDaFdwJGfvrgvfXLRhazeTJ4lgOMWNPGZI9uGLntKJrBAezPieDOyDYw0SMWyvclJ4Qkgzu/ +Vz+g43Xp8SjZMshHOJQBtFOp4R2dkPuMl/i8XIbn2fNu8wjXHZ/FqfEQfXTKnZ+Qx5EZyvN3kgcg +dN0z3xVjNdSePWbQqlAmOc6H35uY46rzEx7s07+BfU6UeH2/hP2sRyx3sSZP+5Fhot61Vqu+AB3k +0CIUbOoRo8bTc4gBpvSKKVi3Deh3x5M80n6n0HBb3dqMyxMIym0V1Xd/YZ2SfXt0RA== + cUbEJbLe3bRWTwtXTJ5oLpI3MqbwekZIbEaH0GLpCGe5nPNGzq/ijn3vGTS541SPnLjvXPmBQ1vn +TdXvHBkmMm/9ZSy3oDstlSua1NBGBsk52T23QgB0xycZjhFAny0jiEeuAQrCjXHk18PIqBlX2fkY +9LzRXKeGgKbYDyNdN4bo20ka20fGthxfKNcSiXhuh6evNSJ13xmpAue3Rkyn6laie5I9hDv/bnlh +OfID/V/TJVaekBu3nCVuvTLYcnrkpcwDHBbn4Nc1GxS0EsthDc9Jxu6gr/1IP510JW+1ZfS2PbdF +9yUf9QhvqCCM9TkPkGEi0p9lPK6IZ5bzCeNrTImr7XUJ9t1H3u9Hw3BxV3cPrU+E1r8eLgSBLbxC +Lj9lvEp9vzSw+NPDmpGXMgdiR0C+U1T2zsWJImhIMqSqYVmnluOXOeJmJuBQI85tMmJCpL5FcGWP +a5s3HR16vB61K2RjzATRm1Pm5kHp1vL4O6aJ5ifFk5GxO3IOlG+NU0Crtpz6IjGAVqyZLZCIqbLp +bGx45ZIL5icmrmfoe8T+GQq5dGMP66R8Arn8OFZP6r40rqBB33Wl26UgBMnnERYjrt5HQNeJeG3o +9cvY5lqwP7ZN0dhrfZkHaEsILeYQNNR7IqAUqY3j9eJnnoC+tI+ALyoXgrc8/uOUL6FTqIqfIZ12 +5KuUowIPkCvaFpk3ik6n72pjm47rtex/PXkCx5Lnm9Kz81aS82B3h5D3XU8cOG55h0bjmUeuPT3g +OxPgc8Vw2P9Fz4CxRgsyq96fGEVfw2mk4F+uTcyRjhawx3AEV5ZXrCqnI3OcLly2dEw82hxshhcL +HIQ38whz7ZWPp0oN6HdMK+ejZL4UTt+RF1HWIJpDUjBmNIkBCR12eqMD8qo8Akf7zWl7GXssp87T +6oSirlQ6hVraPECIDtz8xRvPfHzcm8KWYrbNL+3APBRnUBXyQLuAI96no0kd95jwTCcuAobs7Xvt +XwlscyY4tf6lMeMB01WCnaFOP7Oa8sHn5QNl+m7qqp5Hgj/bQ+UX4jj3b5HxytwTRSD+QSh6YiRk +iO5L2KcvxDqmtM/IVL2WrZ9wHI9r9PhJX2PXCshbnpeN05+CPRYd0Ida0YePOuRT9y3BEFom3jFm +zDSD7GO1fzS+Hvm/i42vyD48Ftw9vNBISfQzjGzcpi1R75e/xna8umKSEmmMqCx7G404QoYYFx3f +M9JJGWpuBWNfgmBnt5QT7c9jSJ1RDdp7jGjOi9CYkxA1PDbmFBbNIWSfUTCGNL+EPcQZI8L/NFph +i+sM0xMx+rP3vDZIbcKnaaV2bxxuXVdkRFuGunMsa3TacylSyqix8YxIXtdp45LdeTJhja7jU7Ud +CtiGX45befruNCW0fdiRV9FSLoXx6KxxhBhiarNyFT1m4mO5+nwl2xINbD6DU8hxX5jfabSg9DGP +lt9mTbHJUFL/S9hHCxVulywHxjPDAU1JCRiPWJAx8ZUHLiVenNdn17ztnAGaQlw0pqSB0l8foaSa +I8OFMNYWUUvm36ylzehrybQiW9rkNM8bmdrbVsb7cHkoDCajpDFoITIyVHLOoeSeAkgcWeeGljNP +JIle/xfG6460HrMoPsK9pPUcGkRDoNDjdhF9ZGRHw/mS+QhDLdn9FdLLhpE5Qt/M+7Fx5q7xysQR ++nJ1nO1SScvWuD5nnUVXIyC/wC2Mj7MN6PWZbxU27j0qCDSjrvrcHlltGJcB/CzLqd2+uCmf58Zx +xUXJdhjZhFYXsR3h9aLExp4ob/cr8WCUtieyi1Sh5wGOK6azVvN8I+EHSaWKEO4r19/oxV7zCJYm +6fa0SFjA/vKbY/vbTw6qs7hnr9G12nh6LHEINY8803BcdMcRQikeVRMw3jk5TdXwteTFjvvypkee +wes71xmgA0qNyRRBUR+gZcIcdRkS+6A/kGUWMPY4bC2R9F/vL9bvsVg+a/7c62A59rWQPr/erbK8 +p3kEtuTxYDBSCY4WyqkjQk+gtM+P40R4L+0x0Xa134Hx5bPPLG6RFh8NZZwwRtNRQVe8cY8jsxWo +jBnnj+oG2FqsyeBVfY79Z9LF+TUYGff1AOg34tTJaB4YOZmhAVaJwcfzCPrXjzMDvY9tVziFrdSU +TVcJJHVYq0TvNc2aXwA6meY6vvd5gNLCiXb+ltuOjIY+kvzDeKX/MdX3dUnXHH7wRS62LmDIh7oP +5ZL93sx7eCzBfCtJYWTvQr2+h+uqHoUj/bzzo6Cs/Y5KnKeH/uz1xoV3hmnoL3Pj9LkcaIGRXcc8 +E9UQ2/JN1pVtat30Su4rhb05vVHl9P+x9/bvbdxG4vj9nOfJ/8D7tm6dJqQX2AV2N056seTYdU+O +fZbz0ktTHUWuLNYUqSMpJ+4//vnxvjMDDIAll+QuLZuizL5Y5BA7ixkAg3nDoG3T7bJgW7HPZyYK +YZeK5Las8aGOaxSgNAvludIBBgp6WBGpbFsSHXYemQ1k6TkRH3BCB7Y9oZa55F3UCDSfNJGppzZL +PAYpONojlTuW4kONcWL0F0TrkgkSf84qM9e42h064iNVfrNiBTVNgwAdXaNkMaCHiCVcHpycQ4ch +p3rbFAwC+jwhnfHrcsnZiKCdx75v5qpXJ4dshxWbq0Iy06X22ncaIKAr/UwXNGcVGW5KuwvF+bJR +tnNHOiEk4yScPLnFQMmO7mQH1eUzb/RGIE5sa5FrjowQUDl1RQg3263rTpvgj5vuypqR2ghfC3TZ +39rE/+nMiIgtMPFHyBBuI2LaePIsUHKyOZsBVadO7FJOmAglPWlZzjZDgDbPuA98bA5bxpqBmTPU +UMho7gPo1omVPJw9rc2FUQaore2tjWByGCh8Y+AqdTuTYOezdfCZtpxPhWlNsRWU7MLUJmB5yM9T +uJTgKEQcWg7bY/3PWAfwjM1TPveFd6ZFvNPbBDQE6jS3iyMOzlChhyZLmcWaMXD+ljay36JN3dkS +f3YT9wHNfOOzRbRrsZXOdn4mjc/KMC0PtjIOwWmTJmK3MlZUkzTi7ZFTD+ztsh5Byj2gq/Ls/uoO +fjj1DMNGDKSdym3G0ir30DMR8c6bZ6zSxirhPV7ayLgOTRfSHTI3yDkrD1RaNgkOn6w8Fyb5NChF +aw2QUzPoomXW8DIesjgN1DOwW5gGp9/piHtF4TOr5Wp2q0ROrCLY+j+Uv9PIqNWSx92U7Snp4Nps +FAaoVcodU26C2OliOmEczWQa2IAUdiJjYOK7oJxlueIEIeuTmjPeyBJJWIkXsTOzIsdHH0c0BhEf +U6L0xSO21TjqGZxNpBAqc9iEkNAu5LOb/virhafCTfaEDTsv56yDKMtKosD5DRGesvRMs4Tfxu51 +bc6p8qv4RDPpnT2HQTAnnI6YmbsC7UZiF3xGN3FarDrsgjvsSAe2jhgeRyw/KRGYETsx59/GwQdt +NC2HOXYGp8zcocHEL7jEnQVMtDtv5PIBCC4dnA9tZs4lqm0cnfrlhH3gC0IECbOSVTcAasVDzEpt +1cFDC7dJ0Nqc+is31sZvZICZTeTWxoXqvBLC7S42mw4b5zZ1FaZeotivYT219sSbQ0DXO/g1a4C8 +h1g3GAPdAoiT2GNQ/ugqK+F5xx2Py+25EPSgSD45mwvln3eiN7LmNbprZMancpRkd410RxOlt0MA +LpxQD2xChOepWz/ubDxLTkmFdQzMpsvp0NtCcBXCKxtXtgwwlBq7nqWZcma3Eap0vbKe4yNe8st7 +hVSZQyw4YUqbpe9ceL6uAB2eNMA0Yu1M2ikNQA5Vhqc/0Y9Il2KWdv4cY8mOaypjj6OIeQ8RLiJH +nsjcnXoWihv7Y/+wvlILpFCRpcJHK+LgcFpujWC8JTZjRY7MXm4ZMdCFNqmxdge9ePrEzqrD08Nm +seUJcIydUVHoYiUzxiwA6y1MXGKTcqUg8sSfScu8YYq+39RtK3588C5xyftmnDNeb5pG9pB8jp4S +t3vgAnKIyXuUmLIFPmKj3CJURptsk2vcS+9YCXaua3v2DOsZxIHTnnI1zButCxCd6+50HHv1MJrg +BtMnJyA8jQNemrmD7kR3JjYzHgkMXmjepSkfygUvlDu9yQe/EKhZpttTBxjYAVbxHMGZ7DDk1vlV +6kPuLBmb/0KhoYQndZI7vRzjS4rXJl1zb4D+kCD7pbNQRkXOTYZlL1TshH3EjWPBhzntMcNVhTM4 +4KOcGZpnfIBO0SWv3C6Yj/5pxVUsaBn4GFvEczpNYu4ChzmUK3pC0TuefEFwyrsEbCWMFQg456FU +bgHjija7VpmLvg3QHzm11vHyoh06kXYTs2mMFPTMXA2HSHDVDtYYw8Ghy9+Vct2NuXHOajMdajYN +2aFoqzQ4BErzYdjc+LcIa5KEQ2GA2p58UsbcdBj82XPOGIq8hac6RpMgBIKPJ5Na4xHYaJ7C5COO +R1MEg4D2oAjAqL5GwifofTw7Zh7QDnnEcLbtUYY4vLAaUgaapGGMnivumVRBrF65ahOUseAQs6mr ++JQpAlOVJAxMYwe0HSZDwYfw3Xw0ahIh1Y4LZjpTwzxPWPDz1KXcAOVqRFjuSA7Wa+sOp9wGyWoL +Rbt9EoI/V23S/7BtJrn/KuHkiEinDPQ5U5QHwQgSex4zsnd2G6A95oW90szaOJg10oUxlGlhge5s +dxxzKsZiiQSbJJJx5Z6Ij8vL4Ly3Tm2/4kC20jp2GLx5x4muUezSBZXRnG3qCi9fOl/mMlr4nIky +4SmLQPBe7XKAYqfIKOOWdRjI4DCNlcPgdzQ+QFZ5et42tgYJbhwZp7MiPHWbGgsBPJfPtoeNPmF+ +kjfXSOu3mBO306G9y88nubMuYwvLbXKRUQ3c0+z5t4aSAbIzHYcn5/woOvlmKcu1x0A3t1vhmHNb +6cohKHMagRrymfkk9YkyymXQKbzR3EgxAKastEt7MDXCF7CGFmbKKKffBGOpTDTZACPBaKl2rV2Q +AQLpyzppzslFFCnrmuQFcXAOFjjViXBonug24YJS1WwtHorQZQHNiSvuYVx2BJRsDVs1jdCyLeFc +JtQDXpXmFkzLHS56kRjzixLrUlYrZOSymBHu9CNKwjpiuLJBfuUSeSPt/JbIP04Z5FMdNCpuNNEN +7qZJ6g5gRGE+Cp4YMTA69sXciS3Qq5r+CCaCbYQI8EY2dRKTZ51uITnxcWnVDc0zKlWusRIsC2HX +zBjoMOSZZzroHAn3LJXuTFCUc9kshZamYU/uYsXOTYDAzBmG0qdk5iYebZdm6hJAffEKFlpoyjpb +QoRpoWnGCyO1RVMQg1MUdWrFQO4OhpjyRgaBiJyrzJUwo9RWG8zHWWTm44oCHCrNWTO26eZU3oCd +bSJTjIGTYbQRPg4Di05thDs3dk4qdEv9zTUuI2lTgm+keAXIKOHX8d5s4/T2dcLlayt3mh0rDSi2 +DROtuSZBdV2POPB7RpHLwU5i5SwBm1AcmzNkdtOXHoF3udjYumnrTAxb+4nqh6fhqw== + LIYkKEaTSZfF7QPmKjWZh8KnBekguQnhnPviinoRWldgizxPBsiRYzKIMo8hiZyaJSVj4MmnzcGG +NuXXSxsSVsa/bDEolz6sTP7gEcP5HJRi/zoC09xZqO48gIyUM8ucXBc46xK3Z2nf2O0BqMf8wI0T +F4ghB2bbHD8QzmGIgRgDTKwqjX5sd8pGpGap2xmc2LbSZWDYNAMEcg6cMq56h8D7ESN7hh8xOMd9 +EkWMVjsHJ23WDkMquRBXbBVyYc8YJIHXEw9cRE70UQaFw8AnIpUJ8LiDGByPtEa/QcKmvjJHew1Q +Zn4LEMERD6m9lFJ8PlRkLgqiTLq9BbrgHh8lFChpnYiI3ek8kZsMLctkPsAm8iDIpOOMcajYhTZi +UwdDYLxNshbkTBYswS+lM59drQUZBXX37BEktJpYWMZWnAAwd/4YChkf8vOpi6pGmRESAOSiGVbM +GCDHZZUJGTgMMvfbr+AjO14/MvW7CZhpHo3gUAs2ZsqUpyFnJZVPqsnQHKSAgns+U3NlJfEgER+8 +pQOPFubrT5JSZxEIV6QLN2rzMtlxbhRboxBhngDl+x87tMrkgCEwMTlyRhZpVz2MtwW049wZX6w7 +rVOnkvChLz93lUwYgXQpisKfy8MyY5LHnDISDZAJ0Fz0TTkRQiq+fVq7YjnKZPgcMVxK3mGtrYGF +4yJX982aCQiUrHknwchqJ6gVFzeit7mJZIU0NkyFnS+Ry/QkuGDlUGZK2sZKsCyNbbEwqbm4AFr6 +IYJEsNeIDlA40ujsDyt8mcWRC82dsAfyMInHlfHLnBtEpoGVKXJ/DNGWkzHt+QBgZvKObGPLhwxt +DLYyM3eiGeGK63faDAMEcg4/ctJU6MDjjbnb77yPR6LKl7KZaZzNeG6SJZMt6WWAGQtNUhgNAjy8 +6eQgVSM4Yrg3WmgM2nSAlIOxygbkEMaBN2vyWMSC03pUx51f9S4e46gmmNssE7+JxsLpRIqLbSFQ +xVz2k8uRxMKlUygjDR0Gv1QpKm8Jk8ZnbKaP9fzE0pw7tULIzLM4NsFtw0btlDiC82I122UcuxPg +ytR6a5szx5Jdm6BSOM74s8jKSI4jhmcym5s6sTIZMJa8iM9qi4Snb3jGXgcuAyrF3KaD7KngFWtS +kPDMPIcJlVl2FoGvg4zvVdw2E3N+CDyj7zwZlD/hEKRuLIxthWf8fezaWhoITIUzmNz7c3fOVLmK +nAYubIqF4kALAhXbVrE9vIplCjLndhHOq4WlFWTubPDMlYOIglgCF6jCmhJKO/+IMa4SGVTBpDwa +gxkrWzgPI6soWAZDsbOKy5TIoPIrLWaHIHWil2SH7VpsEssNKXHORTecODTpfljdg6qn27nnFiA0 +5XQgFZ6wh/bS2W18jhVLhDhrw7q7EtTSY2ciujoliSkJY+Wsr8RBQlPyPDPHBBNljm7agTO7VQJS +nTtMqUMWMRoOCSOIjdqLQMWx3MSkFiDQccG7DRMdVNGNreKdpEEkS9jqX0nqysgok7FkMaRBRgXJ +/DYVh4ncFNEmNRyBfBDX2kAWQxZsg8pVXEiywBOXmUwnA3TWKxcMYVsnT4JqPFx9RfPRIAI609fV +BMk4gooWiRNY0NZ7mmziJwJ9bgRVqjJApVx8zp/qwmo6kh3AVMEyKAjkqhnbIpwIdLq8dRYn6IVw +dcK1O2eMBYhS52syUVwEJj7lxp5YVegDcPUog1JHkSv0okzJEwNMJWcoidxWXIuC0FigEyHcmY2s +nKvInCQ2aG1lEgQ6KRIwWAmXN+3dPFSDiXkprYWhRJg2lDsTCuHOT5lbe0v5o3/K1HVrU8mnyKlE +pCg4DL6OZ2ZErxIukRKtzoy7EEfeZ5gFXfBwVkYQa8x6h7LHl7GlU+Gkr4xEjXlRkHlu+5s7j7V1 +mmMxK16ptJFbBNIdYVbGILTAxKmhVphSNSzuqitLglDplA40cY4Y7nYKZY8aI8yJTRZXAOSKLagl +ubPoCmV34hprbpzmvKzY4QxAH5UJ69zJIKzC0lzFgaJGJTAM0FeQpbO5FgM6edymHzECTum24Yt5 +BL4kCIJTV2Tcv0vwdMy0rY0YuysfbIlyh0A6VZGckhboJp2tKxi73JWSbCS4q1bPVRtjF5ouY3DR +osxlQyOcS2YEjWWg33NFHBwG57iV4QTJdexUOlOECLE6hyFXJaOhYSYE9cOQOZq1GcHlOWNXm80l +yiCQ3bza7IwOg9+mbL4Q1pILvFGZCW9hiTp3bwNIDTeSictLx+3LFgEM/VY23ozAlAVpUA8ECwO6 +czcyEYyAykgloR8IgT43w1dORwzekWn3WnxbxoYwVwWiLrgBFs5vpbSr5+W3CaxkmLPU5V0Nax5q +4XrrFBGVBqmWURpzLUQXJXRyFHO9ndfJ11dS2tXbwmmWugJ+6PZnTcZm7VMVYpdemHPF0SBbw5c7 +ULk7gup92AhUsTP8I8YQ3IihnRqt6RIeN3/NUtHCuFIS434z+oL2xohPDUGo15oyK20QmLv4jzXf +AJj55ETlnLwI9xERl0QqdeLC/+hyijIPTxWnf7EwRJXLRSuVrdtEE9xFnJyWQ0KNmRZYRbz8rJ5i +8FK+Fnt8tKVEu0PmNpPVItbmMGcSeu2Jg8x4Os5rgLAlcAqbD3yRR1uH42m7htUm2MvPlw8ZuGe0 +tNWb6GCICwXZiio6dUcUlXGJHzKGPI3mFAosbOT847YoKlbkkFxQgexai8DWjLHKh50rmas/o7kg +Exe/NFQK5+tbeuVCHHMJCnvzkClJZKi28UOd+hpnmY+J09EpV+8yDfmV+EJKrnY1HYriiihUzT1g +r6t1HZsCX4gj4/OQXNuKju24+qXClerjE3mmsb04InXXCwVlkfG4G5/tp53DzYjM1T/zVwCQbOD6 +UWkkeF6CiOaX2cKb2DLhMgm5S603U5DP+3DCDGLwxUNTN1m1P1fsanxQGNaVP0gyRpDkrg6WNZUp +tuAqYbpjYmYi8fEkchFaoKtjQadEDDDOuCBZEJ0nndthsClCtE/wVThOpCmXHGrnhhMGyp2KpwOa +Vpq4U8nKVqzUKy4jcdXeWfXVSceV7+VSGgDzxcToFMYhC7Q85VIy9vg8AoPqodYzgEBbN8de6+dF +qHaVZ20EBOV1wkcpcxbiqK34eersCoQrJsJobFq6Q7e+shMC49ytIBfj0j4dNnUam0Ydlw8Ygn2R +WGCScf1uSo93GBJeyeS4NDBf2oDj11oYu9YuOj+SwnnyU46WI4LUTQWzydPmxuWuROplBsBzV+HW +lvnRIqywq1IGutql1CuHwJ/yzKyHFIE5n9RPrfELQL4lJjM1QRwGf2rRKioAC0p52TQvjVFfPt3r +z/wg3Bf0ocMotrHgiqi22AbVZtfMb3fbGtVxt5ZG5sp3LxZ9/xvVhBeth6zrelmd4BZ6UQXXbA2F +wKwK6JU/GZxJ56SPUn1iumCvHRpetpx2zyFwZAZtE1/kwyGdo+HQFdsXpgxT4k4fXjA8deexE2fF +cmpQ2rFV5dC4jllwJN5OE0ZDTNzxW27rTmJL21/hEq9Tc4bOY4h4dkur/AmXLoxHPlNGMEeBJy42 +U4LkGHlf3djlOcfpOcqCQOVc5dbPIAPnH5WsP1xEwKV8VOxKAShjFLfZ1nIRIVeakuAuWJU7K47r +mnsvNQHZFKa9KsQgF1/n4k/CYy1zwTDoT9/jnZUPnT1WNlYvHNzlG2eK8cXeCWzTWxCYlHKHvKHn +76nJ2VzmCw5dTtIKQ1G6C/Y47ETWsjOB1xq7UjtHD88ZX+HRmiyVPDgMru2bO0ey9o7F2B2gS91R +FMnxZNIY1p0jqT4F4ivX2JSGOSCXN6o6+XLGnnJfkpeKa154eEVpaBncyJe7yP8ilqPgTr65Yhvu +Tr445/1Z2sTvUrENybe20eEDVyRKuvoF2iXKY+MkdRgcVn+ob6Heh7ulb65OhLulTzmlJM79ubMk +qHQWc5mSJCjnFJucuOoKFPalsTlBO7eLENyVRou5gknsbFwn5lbUhPAFE2ObC08IXPGEEOhqPwgR +ICj37Ci8qKpU/87dU8WHqRGuuICe18Q5lRTDea62WAoiqMcIfMUJdjVF/miPv6ehqgKfXZEL9bQu +GO5qEPD5ujx151TSjkm0Iljmq/5EQTEsPnCcmmJ69mV55IB2QS/04DC8Xsga25lJAg4u25IOHvFd +Wb4x30qyogolh1wyl3yKwLBpe8k9RJU9c6sWC6L5csBobrtLXTkFgzdiOh7jSjvzSdwVLM01FyOz +2z5hdcor10JZ7IIb75QUOTaQNV/zmZKkYrCrW2/grrm5a8YAeapbI5uArlCICqoqzL8wvBF57gnf +F1f2mAxF3xdXDSIx9VMJmPqyLVov7Yt7qa9NTmep1r40dXa4u2YrddW93CWBC3gPgwvA+OgMSgYR +XBzL5WdtNTJ/36dimauE4CoqOnE3Tqd5qxKxl5ORKRtlfkIN8oLhUezums3cBYeZq8Rry/ETckeQ +ryC7qte+xBZfC5yFtwLYG58q+ua7LTuSvdkyctf6ZsJFv+ye7yoo5N5fySfksbQNZ81FMuWSDVnC +V25GkQjqH8T+UB/fCCucG0z7skjzXQv3JO0z4dw9yViuIOewlI0EmrYci8iUg7lMFCoR43aU1KWK +2rwZAuYuZGCvjVvogRfvsVn/CXs3LxxYcHyPcgyPGB77tEUZ81FP6VJauNMLiP0rlcmMNfuj9vdG +Y6U+VlD8hSIEF+xVkO52lwo8XsTqIPlBeaq0K0uuTDF0V/zQxQHJRDiqxnIUXIPoNVg6QeHue/Pn ++4ITLFivOfbxdMF51KDPcAJYnDJwDrPf7HJXbNxGIC4YHitONuFwOWZwJu40Tq44g1NrFz9w/i9s +60PVfLNk7nyRyhejXuiCV3ajICJEx6guGO6vOcZcW5fI4q+bpYTooyVoDNPBhMpbdz9r/fTjwuc7 +D55kJ9+O+geTq+n58+5sVkxGBFUIPfluPHo+GYxmg9GrdtvCD4pXg1H4y6effHdJv4nI/Hj8w+NH +gyGg+vSTe+5z60v49tPTo+/G/YI+Pxz0ZoPxqDt5u+an+627v10MR/BjGzo4GZxezYrpZ60voOGD +yaQ736Z3Phj2J8WIWsjWvSejmf8R/5m9vSzox7ug3dz5rHXv+9GgB/BjwD16VW77pju8so1/HfRn +56tbj7oXpjF0xzb/YhdIOy8Gr85n9Wnj9tsi7sGTkwfDy/PuiahN4qAPTdfRhY22RdP49J9Fb3Yw +vhr1oY8H499qk3ZG6wvazqb1h7D00LZobjBF17AjJO23nSDobX2C3jrK1vX6pgnY2dXk9GpYjHpF +bb6Yh+uyxr1qa+TVJmxSTK+GDYQst98WcaPx8Www663Z8gICp9T85WBYNJBDpYe2tmw7kapN5ml3 +WjyaFP97BdO6wSKee2xbpMradI6uLp71Zt03TUYzfKamyFpGhlhFRvVWHu6Jxcuaog== + J+j+6jHZynAdj68mveLxpHt5PujVV3ZG9YdsMNoR+TkYrZm7Zark9shax/6AqPFlMenOxpP6lPkn +trzADscXl+PpYNZofb2nzpAyW7sf9x4WZ637e+N0b5y+D+KccZrsjdO9cTpP2t44vTEC9mzSBV11 ++N14MN2bp3vztJLKG2Ke1vdz7rZ1Wn/L3FunN0CC7q3TvXW6t04/Tus0ub3WaRPSdtA6PSjeFMPj +825//OttCqC25a2z2BqR9FHYbEbjIP/KrdM36iu/01n/YfFm0MVuNbFlwqe2ReXp8GrNXng9Ruk2 +lY/H3avpdNAdHayl9Wbr9/VnZL+B9OnvhIHZb7BF9Le4RzRaT7siCsdnZ9Nitn757L6oeEaU7rKQ +qJ85Mb2anHV7xXGvO2zgQy0/ta0ZOUS1HdNge+PhePLlr+drTcvSfv22EcWm+V6iXCNR08ui9+xq +zULbYXe4iOrPRmDF1bA7+fa3y/GoGDUgcvHJrZHbmNrD8Wg6625CrX9yR40mMCPhP7U59q/6LPrX +Fm1j1YSmHbH3RaOBei8W//tSdJ6PB6PZUSNn2RfvrzfHdm0f2W19lxWwplvbrmzZm/l69mGY+TDM +TkzKHTXfNgoz3TQBUl+Zet1gdb3e4uKqv4e+XkN8iSKxCwrv67gBRfFOjNEar12JomTbG9ZtTYdo +rmbsylbcnQxm5xfFrMGg7eKWPBzMnncH6yzg/Z68yYjctC19Awf6BnJom6P8tJi8KpCvu6x5NV6S +H8MgvdfO3ICO3Mp0MLFPB/tiN9PBDsfj4cGkKP5VP55143PBPsbzSm1Vf5ruiDu8ycr7KNLfRKf+ ++f1Jtz+4ajCJuf12refbmdrXHwy7DfIFdtG6rD9ouxZabzAd+w2mY3/72vl4cnk+Ho5f1ZedN9CG +us0ycS8Jd1AS3t4ztw2Ow+0l4Tb05VuXr93kAOZuCMDT+pG8nRMPDU+T7Y582P0s7Vtf7KLJ5NsV +UdFAsd0xUfFRVe+oP4y7Xb2j/kmQa6jecdNX5I7tcLejIMma1KdQnjQ8hLTd00cf9+a2O5lEp/Un +4K7t2A1I20D0bYWkF/XjZYfn3dGoGB4Xw6LXyB21+OS2qH1QP5S2MbWLT255W3s4mF4Ou73iohjN +nnYvd3lvu+gCuvqB7F2y3aIW/7e18FGUPtYmnz420C65/S6I113Z4eu7I3duM2xY23d37IBDPN7+ +tIaoudnCsskA7chyanDkeZfLA9V3Iuyc0KhP2nsSGjdtlZ41Szs8GwyHjZLyhruwWs8m44sGVFHr +bVFVfwbPxg2Uz/EWVc81OmLonMW7DRs4ZU3zbRHWHf7afVufOBCOs+6kmTQ1D2xtLtYnrt+gDJtp +vC2i6m/dAXmuD98RGXUJnXtsWyQPB6OiW/+YUq877D0dNzhREjyxLRInBTkh6g9ovz+YDd40GUv3 +xLZoHI1HDQjs9a4urtZngpVIDJ7ZqpHUHQ0umvT8i/fVkdtTaLKd7TOXbrwB2ru9mUsNSNsxf84+ +c6nGOG3X+91k8u2KqNhnLt2KzKWP5lrcBuUzdzV3qcGa3LE97nbkLtVXgXcrd+nj3t52J3epd3tz +lxqQts9d2ucu7XOX9rlLm+cuiY8ud6mJeN2VHf725i41IG3H7IBbkrvUZIB2ZDl9HLlLvdubu9SA +tB0TGu8hhLaLqVhNBri50NnmAN+KQqFNcgf3w/PBh+e91unZudF5r525AR25jQVcHzw5eUilmU4a ++spucXpyA4fojtUVu903FXzYGmNbFc8b1a3ai8UNxKLei0VLX31O7MXiXizuxeLtFIvfTgCyVxb3 +yuKOS8UC5/FeKO6F4vUJxb2quFcV90JxLxT3QpGEYhhhO2mYfHCLZWN9TlxTTHwXo6z7lbbxSkv3 +K83SV58T+5W2X2nr55OKWqp+NqdhwYsmCZ3BI9vSAEGaPB/8VgyfD7tvTxqejr3JefNbvhlwF8Xn +pLgYr6tFsaNVmgajfnE2GK29K7qUuXdZdGcPm1SUCR7ZFqH7Mkc8ertW5kg0GLrdqXNUc1O8NUWO +ppdY5qg2sfsiR5Vj+dEVOdqOxGmJ+zJqCQX/Ri34/334DH/vww+tD3GIaXvm0walnW6atnabr9H9 +4Ib8dnK911ruO3yQpBFx+6MkOzBGOyI7Ng3Y7Ur5hnXjcH3xuu2cTxpfXI6nYKg/u1oj7a5HOG5T +jhwyrbssROr7DF83WGKvt7jC6rt8X68hvkSR2KKmX5+iNeltJYrinRijNfHXEkXJjgm+3dqUmxor +u7IldyeD2flFMWugb+z61vxBSsTepr15FwNCmw34/uTrO3bmBnRkH82/BdH8hnVA99H8uZHcR/NX +MWgfzd9H8/fR/KUW9z6abwZ6p6P5+yuL9tH8XYnmk3qL8XwZ3W+m6u4j+LvkFNsNh98+gr+P4K8x +JPcR/Hcfo7fFcDj+tfYoDQevzmfQoN3DCrr1R2z+ua1p1fV16sHZ2dW0OByPwBAYNVh1Cw/efFqN +oDhudllI6aGt6Sz1d4mryRmoqQ2JLD+1G4J0RzZ4u05u7e7XlL6P5Cb3vVdx71XcexW3phPcyrvQ +m2ile9fi3rW4dy1uxcq8/2pSFKP7oM0W92GvHLwa338zGA+L2f1J0b8/nnRH61IX9j7HretvIqvv +F+7+a3BxNVtzAW5prvID25qouj5xxRC+NfM5Bo9s2X31cEDOiSPcOG9AthD0h4ylI7uR7/ICAVn2 +8bjT9v6XnfW/TC+LHqgFkw90TObGz0/Ljm9/uwSNrInDd/HJrZFbf/fiTjf3by8+ufdE7T1Re0/U +3hO190TtPVF7T9TeE3WTPVHW72Q8UdYtRQ6pvSdq1wztvSfqujxR29sqtx0d/1j8a8fWaLsNDrZN +HBe74pS53cfcb3nlmQ/sUdumfLsVhWcalADZkcIzDcq07EjhmQZjtC88s9VN67becNQ4j3NntuOP +pOrMcDB73h2sC3Hs9+QbsSfvi8Hd/D15Xwzu5u/JjYXermzHm1n/+y35Rm7J+yJwDffkXcyzaD7Y ++wJw79iZG9CR21gA7sGTk+Pzbn/86/6eMz/G3398ldFuc92N+jX/9nU3brbucVtKVNS//rhf/25u +arut2deAojXSuETRbzuynnZFFI7PzqbFDJfPpOg3k/Y7KjKeEcUfsa3yDkP+MRgtN224PljkaedG +am9e7p55KZLoTu1J/Oug3ySf0Tbf1lYq4gaknReN0uZc+20R590C+4Lp1+UW2ArNbaHqz9IGmvkW +FfNGJDUwn97unTc30GLRe+fNLbHEbovzJrt1zpsGFO2dN3vnzd55swtD/jG4BG7acO2dN3vnze1x +3qATYNZtkri1dwHcvsyAs0m3N+sOvxsPGpwYMI/XZZN72VYI7L3XLK7tkFTfa7dr9a9G4+PZYNZb +4ycuuQWw+cvBsElBg9JD2yI16tSv9XXanRaPJsX/XhWjXgOrc+6xbVHaoMrX6OriGcijN01GM3xm +B5bkvmz+kg14X6zsxhUrayCizibjiwYDSK23R1f9y7pm4waaznh7NN36+mu3svxag419X32tLp37 +6mu3sfra9pxiG5Qee18OsZdXk9OrIQiLnXakNtGWd8Qm39dBYh/cu53u3Kbre6Ozj3uPcwM/wO1N +F2xC2g6mC/p952RNhYR9vGCV12L7KYMN5uluJAw2IOijSBec1VQRdzSeg+Ttwx+3IfwRfSzxj/oJ +eNcQ/timAn07rNNGEmZvn+7t0719urdP9/bpTbFP62sVe/t0b5/eKII+Cvv01mcc7i3U22Kh1i97 +s9sGan069wbqDZCgewN1b6DuDdSP0UBVt9dAbULaDhqoP47H/VeTbgM5sLdOb6B12ha3zj5tRNJH +YaHe7uuB6iv7+5IrN9QIb1b/YrcuIr0tdWT2RYBrUrSvI3Njiorsmhwc1yggs7uS8FrL42zH1T8E +q6fdGw/Hky9Ph93e6/stAxpfdnuD2dsvm7hYp7O3wwYxANt8W1OTiL61C68ZdTu27h7hFN3lZddw +dG7/vrb3Ey/6iXdtDHdNRE6pwPLhbRaUt+L+1l/Pm9RxGKIjGRq0a8jYcLTmn9vWrKxfDMneIn04 +Hk1n3XXXcpYMuvkHbz6tRlYc97pNFMzSQ9uisX6y2/RqctbtFQ2JLD+1t9Ovkaim17Tv2gbY+Br6 +j6Mukojrr9nuvwYXV02CuO6BbQ26rl/qqxjCt2ahheCRbRFIG/nWi329L43u4YD27KNG4fUv3md/ +SIYcWe1pr2fuip6510t2Vi/Z5L76XdNNGlSkZHZ8+9vleFQ0MYQWn7z5lhD3ubnZt/jkXkHbK2hb +UtD2+tmH0c+O7aK/DQraJvveruzp++T6HQ6afGCFbB9ReNdzY7VH6XWDFfZ6iwusvv74ek3TEkVi +exQ1GKM19c5KFMU7QdGanJsSRcm2N63bmobd2D2+M9txdzKYnV8UTW4W2sVteTiYPe8O1pnI+z35 +RuzJDXawHdmTG8j7HdmTG4zRfk/eFaG3K9vxZtb/fkveb8m3YEveRTf9/u7cnVLAPsTGsXOD9F47 +s8uz5dbXCNvMIb8bqlTdIks7nD/wEVVB+3jKdH/Ya0q3uVndjjJoF11AV7/ozC5tD6IV2f9WfXKQ +2rTTxwZzldvv0BayK7vjY3h6uj7Z8TYYqcPx5GmNNXqzpcxt1tQ+jlJAH/q46TYX3W2pntOur3Tu +Svmc9u2rn/OhvG9bIe7ZVs6qb1N47H7BmebK1UcwG3cnTHXLEzkxbIMj+PIDXRBwm0JUuzNguyJR +RKfBIb0dVv/DQax/cHdHl91t0f9v70aO0/Gns2LyaDC5MS6gmzb6s+5pg5HfJceubNUPMhAXfmjo +uS09tGVh9Ohq1Huxy1Lo9s7DTtqKWh/XTHy8n4k3ciaKj00kHtyEFCGyz7AqwctJdzQ9a3BVzg1c +HRvpVLuiMG56DGrv9LkxTh8zhDdJ49+7fVYMGaVPPhgOb8pg3TT+bDil9xm979iZG9CRzW7Vu/Pg +iYhOvh313e16BFMIOvluPHoOWKhqWdvCD4pXg1H4y6effHdp8CTmx+O3F6fjIXTpQb/fetR9M56g +0Pk0aj349JOo9dOvn35yRf+LWs/gn47OUzC9OyLJktRkT3WEjtIsgQ86jVSWwYcs0zJVrZ+6+Bin +W/30Fr/9FT79E2C/tkTUetr6+Zeo1YeX/fTi00/aUSdJtMzylhSdTCWqdQFAoTsijxJo3hFKJK22 +TDoqj7MWNpcig/e0pcIn41Y772iRCd06hAcdUMiOzqK0dYTApJOqHB6WUSeKkpw+SKXwQ9yJMg0v +EGkn1jImSKxz0eqZbqjUAi1a1cmklgYC3SWISBLlIfRg1MkzmQTN8o5MdIRvlB0pWm3AE2XYA5F1 +hEhi6r3jRVuIDrxYY/eTTi608g0BlHVixGlQwbuiPIr9u0QCxIUvhx4BLI/xva6Rgg== + kcukJw1oTXQuSwwQOXxErjOb4G+m09RzEsdFxdLzG8hwMB6YIwNLchospYWS9GCsNAGiBCYQAiQO +Ug79Qd4ZTHmU4es6caS0wZR38jzRJViMsy8G7DjQWZq3YtGJ0xxYkAJvtM4QwH2KpZTUTweDvudZ +nFhMMKEN7wiG7JEEyM2IwEQRCgcSmsYxjCDyCaaryDXBkhgGCyeF0qkBlMaEAfAU9C3SsfKwGFgi +UnxXigOsWsGEgLHWIjbTJIEuJRk3QyLzKIpzj8hPyuB1OJuJ00Ez6IIQqe83TrII5lhIHC6fWEjl +WdBGzmmpPJfasfTrjiDYTwdkpuNihGc1MEJ0ZKQjg0LDoCGHRI4ccjRzN3EiQGul0pbM4GHdSjo6 +yWA2SQ2rCPiuYYkkSrVg9UdxIvEJBwJCopheDZ2GdRKHIFimIs+lRFgmACPKBYmYYQLFYWdYOgHq +s08/+R6lGgiwPryodfez1k8/gng9qZRlAN5UmsGjVfIMwRtKNNOZjWQaPrqRVAv5Esq1OycVku3O +SXPZdudkM+kGz20k3+6cVEk4A20u4+i5BSkH0Ao5d+dkM0kHz1XIOsK2gbQDvm0k7+6cbCrxYApt +JvPMfN9E6plFtpHcg0erJB+CN5F9MBUaS787JxXyD8ZtUQLeOdlIBt45GaE2fPfBaDxq5VIbEeg0 +RsCR53EObBcu9x4VQ0IJDIT5o7Oc5CODYITzJDaiAaQErDVRCeNHj4xiCvMnroShCMiNUOFHK0DE +w9QoFrYjFaDgQRpZHLJFUNCLeTqPVuwaFTzxwJADMH4VfPHQ4GU4qou8CaBB9z2CSmDADt+tSmDp +8Qo+eWCpTxW8CmeXYdP3CASrdVa20uFpa5GBbRM/Byu3mIywYuxk9pLNMqC6de9gPB6WG43Qr/34 +atC3JvGdE7WI6gUYS9PZhHIwAoQgU2BV560EFqQGyZ0oEBBEq0yksZDuvSi6Q5O/j0+UsObHw4Gp +vgy22ePJoP+fxVuLGc29k08/yd30cLaftdiqjLiDq9lsPDoZvwHjcs6G+9MVMvKhW5fL7LJkziyL +WmA0gryJIoGbNi3UjD6RQeU/gqCSpknbbDoyynCHwy+p1QJbVvOTLfoZUZrHUKHIUdQD7wTpefTh +yL3afMHGsAfBF0ahWoQVlXh6z5H5gL/lYKLaB7BXAQ1GdYuQG7GApy/oLwyhAk0BZLxWqChE/Ah8 +sj2KmGj+hG1T7Ar0PpK4LxAajTsZoSa6he0ZfcLflUxb7mHQplqGkfyetkHvehxZc4f6hV8ZD77H +YD+0pEDDg1NaMt+P0IPQb72adPuDAqZz/BkNeDvHwRfBWSjROnhFNmeE/0HlCTql0ZInALwyE6Dw +ZKjJ/HRRbqmqW4LmdNCri/OgHs44Ipw0cgcHMKO/x+UBW5UKpnLAs4syL/lTe8nHcDRK4+QY3GYO +l4Z5YQ6Y6XEYTpSqDzy1hn5ozcjaecjTx82ecNDDyRCQ3Fs++rL+6EMr0DJL/M9wpMTC6MfVLaGD +86O/HOf86C/BCdSXRn/pPhDKePV88FsxfF5MzorezEhJI+5fOzlbZ9sQ171tJC0NjAcV/YPvEIeT +oj+YtQ67k/6aHeJ9+vqkJoGAI28/2iUoc7Jlpdk2BAPoi+ZNBG3H2Fgu5it8AxWTvxsrjD45hPYD +IoYXSlKNzQcjWfnX4CGDyW4swSvKHbA940+MKaDEEhjsOaAvwCMX5kMKCxm0Imn/ihwfgH8PDW/g +E7HG/9wOnmobVNQ2L/Vy8avp5Rk3NRRc8FdtR4CMIoubP9BLNf01bGubXoUNwictwkPbCz9Y5a9n +RoTfNIUOdLkWWEZCfPC1+bA7Kx4NimG/UoGzq1IJndC6TGKRgJIcfIhSlYCeDm0isMmrPphlCqu2 +7kJNjXbU1nbjg7GnmZK6v6kdSkCaqlijcFBSJ8odswZFH+wMkCCdNE6lqpIVYLnSW9KWmYap3fG0 ++8tzF7TTT1E9sJ0yncAPZC0o/1ev0oTU6r0QfsHtVLX8rgT7TwKbEAhC3AIjtLtUdRMFpjXtVCux +HKzBkujybkeUXQSk4ofE0pqEtG+o/a3orV5Pc7SeZr2eZlWm+cpQSSZHG701RDcq1swA90Gsolzn +nvSkmvQMJwz+Recj/JMwyagMhr+ohOlcfOSg+pF4bijhR2lJkpaiyNLBf+U6cto4yTagKNCzRDxH +WbqashWPVlCoLIXKUsgjxX9XTlWiMH5X+nS5hY7q06fX0BfzrBQ8KwVPxjj4cI2zMirNyrT8gxIV +pEWlSTn3RAVF0hIkLT2RpYL/Xu+cjJausmjZKouWrrIlFNkAsp2DosXjwn+vcw5Ga9dYtGyNRWvX +WBV9kZ2C0k4zaedd5P9e3/SL09JwJXM/ZItU8RMHlU8sEiMNLUYdN3Mu4j/XOvPmSEnLP1StpDlS +0nWkGF+2mV2yZQfD/rnGKTdHSLAeDCUVS2iOkvlH5kkhUXZBf4XVMPiv8Xbbv9czxZJl45IsG5dk +2bgklcTQFFNmNikzt2L+c71TLFm2WpJlqyVZtlqqSVGGFKvr2sGwf65zir3nMfk+MJAC50PUyaUU +wkWMMCKGotMEjoRJFkq8YlheYl5NFGyZIFra2S78TuZ2NuH+ysAoFa0Hl6YvScvbKWgecbZS6myW +sq3CRsyyIUjXGB9ze4BIy4pybKbQgrJDSnVFW51Y1bwe3gVNaBneWNV0x23Fio+h2yLif+KO8RB/ +UFt+Mr7sj3+tjsVYZ1tEk6xZUEb4oAw5nBVG+xRlKFwsgo48qK07CX0IYRkF6xNyOauU8hMSi8C2 +YAC6mDBoTykmuUflPNIOiMkh0E557B6iA2wMDPq6Euaw8Rtz28j1iwEm6YdelHtETCODmAmMd553 +xmFXPanv4n6QRmmuP/O5ngcHD3q9q4sX45k/qe1mjxFC3NPMDxlyKVK5djBgpGmUdjT94ABBzxws +HFYPxEeJUwY1fLBj44Yw8yOh/WxwqPBJacYwsVzKGQOizuZn1SE+szD5GMSkMFqmVbsx8JTN86iu +TwP/T9Jc6DgTHR1rFFtxHmmWrIKG2Msy90FSmCEWFEfJhDRT2QhZTBPCxKNlT0VAm4lQ8GMkbZu+ +66DOu5SYe40Tv9c1Tf+0VI43wFVKoG/d+248e1H0xpM+DJ0V90tHakFEHz548tgO98uz8eSCC+GZ +ToMI749Pi5MHT/IT6PPx7O2wOPFvn1+CgjIucDbJTTxkyGiXrrEQeZyf/hceFC7ShYU0t9AWVmNJ +8gZLtBq4uOTnhcKC5FgrTkJpvArmBNaCSJtf00vW+bw4CAQRgxYlyoLUrhUBrSEt0mUr2GhB0q5g +TNDy0kIsXcH0FGxmVlrwY0ZaNHzXQZ13qWjuNdcnLXZ0ha+Jgc+t8NA8wWhokmHYRccC454aTBJy +Yqss1gJ/8P+vCoYao4VXmbCrDK1rXu/Cr7wIVVZqOax66milZmJnQVRX5O92IL2TpSlmTdo/Eboy +7J8PrfI/GgwvKjT9UN9fqeQvBN9IyxcxZv0CcagbmLAxGHAdmWHunoUdBTD8QHnAR/7ZKljw7Jk1 +QjB1Ncoz0jillibyxzAUtIkwKEQnw3zyChA/uUJpS+wiTKoXocw6mGKAObfCpEnpThpnlE8F78Ak +arBUoVMmKUjj5iNzkr4IzTFnO1adWCay+tkUd5lYwrM5Zphr4yjDrPAMQ/iqk8hULXlvDBMtVwrf +G3eiWJpAXtpJtchp81QgcLPqZ4EwwCzJDYybFz1ar8sS5I1WJrgY5cBm7PGjMA8qlFVLF/S9p93p +67m1/WQE9ums6M9b4ofDweXlAG+iLsMfDqa4XLn9T1/jv1f4Dx04gzVQfOm+0fp40Z2ag2on0D+Q +z4/NBlK8GdBp7Letn75DyM9uFrTJUU7//IJZGDE6hH86X9EIQaah+V8WzKukRR4c6tMd6tDD7qz7 +Jaw2mX36yU9PPvm3d/7P//u/pf/5f/j78p//7/8+zO9LOr7/ff/7v92E+bn693Xr693+g3IBdnaU +CiTR/uLEF0C98PpumVQNdJq89ejqX/9620I5W9Yk7pyQVPYKxclPn1uFZDKbV46OBqPXTsLeJ8Qn +iyiNeJMoUtcrEnNnDb5f1EMWTiOQUP/TlekZOipxF3hm/rwi6KJmgqdsFnWTABpqIh5DNbSE4cyg +WVRQAmigj5hTC3NKigcGasqdE1RUkMbGqgrovJsrK6C7voO6gsd6NldY8PzVxipL3Y5XKi13Th6Z +GWTMUONuWq6wuOIEoDw8eNJ6cDUbt8ySHPyr8AbOoqn47HRaTN4U/RPQ6U9Mq2l5+fgjS7k7slTy +y0dBKmwUp2iBwQepokwHHzBalWDa9/zfpqff0TMQ49k/+CBlbpMXAmCEaZjwN4vMAsiSjBLAhfmF +AYdWZ4/ixAOPDFBibC54VHZg0LIAewCgPlhkFig7Akf0aA4Yp+TjZ/TwQSWpwWZ6wRDCJtyrCGY9 +/IYo/6ij26EPINSLwyqesTHj4irtFNMjdeKfu5gDGvQ4vYUKu5B2MjryF3YeVnuus6zce1zTOgsJ +zzsiTdM4QB9CXO890Pe+BLTjatG7YXO9CIecuxuOuCPKPeoJt9hDgBvxBZ4ZtrYTaJJoUeZlCDTE +JiC2ExUHDElQeCRpmZmqo7I85NsRAbMoSgMOAyRPo3AmBADHSgcLOBnAiFSH2nHD9SBkpOtryElH +knvWk23RhwDHyQWOWU7iIsDjniVOhkA76Tsi41VmFwZ0JEvm1hSuRdhdy5yUeLA8DSYwQFJyxHn8 +IcTx0gMDZoZAItehdxxxvShJIu5vSRIxWV4SOdJZEgUAL4nmuWa4KQMuMTNDGNGKe3CmAnYId0Dd +cxLkEGxnc+IJPbZxib2Y0izjLFjgJQhzMgB6TpaASKpHz9zwvQg46bobMNLRxDBPtcEdfmcuLnDL +MBF28lzPMTGEEZkKsKiQZwpek+iylExgt4xkWuJhDCRFccDCuKMTUMs86hDADPQwz78QhiQ6zMwD +9/qAea6bAfMcLQzz1BrM4Xdm3gKXDPMykBlSlTeZEEYUZoFUJR5kgFborMS8tCPjNC7xLgVdIw23 +Ud3JQA1UHnMIYN55mOddCEMKHWZmAb89YJ3rZMA6RwnDPK0GcfidWbfAI7tXC3N0PWRdCCMChfCb +v1m8AhTTrLyhCFxaSZl3+P44FJfYQao74FAHAOadh3nehTAk0WFmHrjXh4uWuxkwz9HiHnTUWszB +d2beApd4H7EKENUTydKSzpiDIppZTYLUq7wDmkXmVUb+HmqMDAsVRv+cVfo8Zgvg14fqIhllOi1p +i0KyvWdRw98ktZsUvZ8BgarIoFBT9M8xAxxmD6DXH1ZwyTKP1ZyQeQxzJLIO5ZhgFa2QeayQhcxj +tc09x4qdw8yAkHkOFjAvgBkSGbVjAr8/ZJ7tZsg8JsU95xjAmAOAY948l+Z0wZB5DA== + cySy2uSYwMpVyD3WwkLusa7mHrTKnMNsv4e8Y1DAOg8y9DFaxwF+d8g57mPIOibEPejIZ9QBwLFu +nkdzyl9p0VqYX1p2m/aLz2pSIetY5QpZx4qZe5BVN4eaASHzHCzgXgAzNDJqxwV+f2nV2n6Wlq0l +xi9bZoFbth7gl+0cn8raXsA96XhlKGS9iFnAulPAOqdjBaxzmhjDnK7GiB0gYJ2HedaFMKLPoWYO +uPcHrONuBpxjShgkPSMJb/Cd2TbPn7J6F3CNQUwcK0RMPStNAddYtwqYxvoXg1g/Y6z8PeCYA3mG +BSCii7Ey3fzigFvcvYBbTAGDHNEWa/CduTXPl7I+F3CLQUxX5jYKQzfrSQG3rDYVMIsVLgaxQsZI ++XvALAfyzApARBZjZbLtewNececCXmVe1BPIkWyRBt+ZV/NcKStwAa8YxGSxyuPWo1WLAl6x9hQw +izUs95TVwBxW+z1glgN5ZgUg41S2WJlufnG4Dm33Am4xBe4pJpqx+u/MrXm+HK0/8Px+47ORdeJf +a5xWt+ifX/DMdxwtidO6RggyDc2/deK0WZq8c5jWhpL4f//nv7/rj/9W/h9/2v9n/x/3n4o59G/X +M/uW/7jpf/bB0OpgqImDVgZp5sD1wzQ2cjkfqDHgTUI15smFYM0cuEm4Bh9dDNgYijcK2VTxkDCO +zBbFMbmMGc+hZ4rmwNNV8Zw5cIOIDjxZFdMB8KZRHXp0Ma4zB24Q2SHiFmI7BN0oulPFw5UjUBn2 +mQM3CfzAo1WhHwJvEvyhBxfCP2VogwAQUbYYAiLwRkGgKg6uZnhVdGgO3CQ+hAVMKyJEBN4sRkSP +LkaJ5sAN4kRE3WKkiMAbxYqquLiS6VVBpDK0fhgJq2tWBJKo6OZmoSR8tCKYNAduEE7CCrCLASUk +eIOQUgX3VvK6KtZUhtaPNmEK+GK8CU+AbhJxwucWY05laO2oE5K0GHdC6AaRpwqureRxVUiqDK0f +lMJ0oYWwFNVw3iAwhZlLi6GpMrRucAoJWgxPIXSDAFUFz1ZrJhWRqzK0fuwKnquIXhF0g/gVPbcQ +wSpDa8ewiKSFKBZBm8exKri2ZitcDHAF0CYhrkDbDpxMgbLdKMwV6NSBs6kMrR/q8mp24HMKtGzR +JNxVwbXVPK6IgwXQJpGwQJ0u83ijaFigM5d5vFFEzOvRZR5vFBWr4Fo9HbrM440CZoH+XGbyBkEz +ryWXObxJ4CxQnMsc3ih4VsGzekrznKTYJK4WKMxlDm8UWwu04jKTN4qvBZrynKzYJMZWwbdaWnKJ +yRuE3wINucThzUJwgRpc4vBmYTivGpcYvEEobpFftdTiEnM3iNJ5lbjE2w0idV7xLfF1g2id14VL +TN0gYrfIp1p6cImpGwTznA5c4ukGAT2v6ZZ42jyo55XfEks3COwtcqmW4lti6QYxP6/0lni6QdzP +q7Ylnm4Q+/PabompG8T/Fvm0kqnLC298mEMQ2ZqzoxudiP7L+GLhLsHqAxbvsdZ4nHTSmG6kikVu +Sl5LkMsx3p1E10Upk2rBMLxYKYmparaIV8DwDpxIm2JidObeHIkBaBybtBfzZvJaxlJIm5eddyQQ +1KJ2tmi5BHVKGmUkQp2nBCSMdH6JIHlWAaEHI1MagF4Qop9ngM2jicyjeIGL4QqX8bCQIw9Jg75m +9pqDKph/sk3os7gKhIpdlJhCB45vAszINDdlxW3PgnZzna0RS99O8XC8aA3EqCIxIFpJ2kkVVhRR +eL9Z/sErEjzvjorhyeFwPC3MzTDPqouRbXQ9TFCJTLvCYDiPMCRBA+4+pHRDBlp59D/8Spdn4fkz +k/doC39TDRnzGz9DbUxNr5YtEmOrfZmMGtMcv/rPhDS3RcCDFwYvDrp86KsEZqaoXwYtBVky+DfB +sjPwQ0Zdxb+GJv6l7Zu3M/NuUxLxyHzAH6W5qcw8Yn5tZ4aodmYIcb8Fj2SWQdnqmoL1b3YR5k6C +Ujk/qkwbLdztIapbpmKhnOBynPN3eyzBGcvqm13SYBISo2wF9PIItGkIPJuZaW3LteCvG6dg9OYG +tvzHt/MP2zG2WHmkgx4EHeNhfvdbWbAotYzKvMOSQEm+UAwyr26ps4WRW45zvhDkEpxxvLykp62h +eR2Vc2Qno+PDsCOgdsvZxolE1y//SHsMfM7pWjRj1x1h0qL5CD/FMIAmrbKM7mhNQZ00U7DV1S2o +02a0/JoL/8aqjlUREDRbQLe6txIPCYs8eefyP9e4g4oG9XwUnvu2/yTXW7jzZikL75XUeurB+PL7 +yzVXxm1SozSoXhRTXTb0RpliV6aerNHp4uCz9J/bYaN2nHVSe6tcgrVc2+7iOPPVZtrjZ5O1Th/9 +5XP0ON1Jh1jN3W/88cj3z36D1nilHHwrobHoMQPavvSIP3ITfhR7GhIdKBfEkHacE64L/sg3w9Fn +f+cYViV1t5EZhpjb4aT9zFyz15cZmiLmGT1MzyLejPUe+3LTKd8T1wivHaN6qOYuMmZO5LkWuaEL +Ptr+uH4ehQMfWc4Kd3mdIxX7xEw4dB26FkUHb3rK3CUjqBVEedZRSy+xq25bfY3dUrwVF9lVt112 +lV2o8IQcvCgzN2R6MBbBCAVDF3Cfmc9D7WZDMBPnRicct6BD16LS4KVwZaUiynPDy/JVc3i5AV0b +U906U4s1rlfiPqiPe/7aOb8YL4KV1nZLLVjCfmK3/cyeX5DhUrXDd1ha2eGCb4eTYBn/xbtc9EcF +v6uu+sMLj5e1zmQ1/5fiPqiPe57/76hOyoyGmhaUGXWa88LMbEmXMWYO7mpJRBaFoP/yLVoyRJz4 +abFkeVKT4KNtcRaM8QVdGOwfFuVpsDgjzna8fmPcydNEt7TE2xCTD68BgYI8q6X2vFcPJcqgTqTw +bvcL81V1tEDjSuadOBJkW6YRXteMt+/x50OaSFqnHnTkQeibxlhXCEJTAtYI1pnGW7/xpvQMHVR2 +0mkTZDh0sxCUmlSTvy3rRLky/s1cp9ZtSY0WIYyHIPOvas93pj3fYTqPuEhXOyTdelLLvGmHnGuH +XEXZhN/BhFJk/+PljqoTp0nrb+YnIJUuYHdYsbou5T9q/njIBNrvjuCAA5XffXuPzDhqwzcFnfC9 +OzTTgfsd0vTGa5bA8FRR0haoo7GOzYG1KKHkOQs68iCZmsDEUcWTR/a4oGtJlFx4EA2uPcqeutEO +AeEYLYMw4qPFd1m5i82C17dLAIdIYMli4V8+/72MFO/T1MRXFrT2K49Uik+zo74S4B9oe2zmW0cl +cc6gNvrg0e2b5fzZzSH0ziuZJIK2m4VvynXJo5jD7l99eFNd4XSPZgLsV8KQkcUf3gH+4vh4Xrrz +hv6+hTrecwjLlLyBeZxxsSQDg3We4L4H0iqNFQU3M4oQoQ8xFxSVN4AehVd0IrRvk9t4u8PCAH5V +j8oGGBi8IUnM4QLCgl3IhPBvYkCPDsyb7rhG3GGHZZ6q3gpn1L2fnh59/+Rh68vW3d5g0hsWJ/HJ +Zy06wwNDBw/Aj/PHeHBwQMLRBVY5jEESm2t7ok4MimasHfCIgIkkgZmCFa4iioMlEWrfWPZOojiP +YXAxWSCmQU6ISvwxQnMIGkexZXoco/6ZiDwxSada4U8RLjIlpK3OYIAoglOtbZgO+iMyckPmmEzS +wr9piv5GTRvePDWHiwQa6QQjJgBFSDascRhiFTYEaavzCCdopmn82ngPgcmxh99SHVNCnE4wrtlG +ISFUxt03QJwa0lQ/FCB8dUxzKuW8ErMrwy9xjJ0pd+pwsZ9r1NDtiB8sqx63EtiJU3SnChwUcrXl +uco+uBw6LrqT3vnS4uAfQBrBbojyADkAUsAWHMtg584p/yFXsSZ9jyKumLNKufOwcSfCpDcIoaww +EkkSYfp8lMs0pQr1KUx1zDnBtYCXO8O0y3WUI8A4xXD3wnKTsAphdzZSDT4LWL544QXmEhIiQAA9 +QUGWSLuo0jjCmIt9Kz6VY3oGGGkwb41mB91Nc3R2pFhk1HQJC44qc1N2GglTYjRPgUi8pFrTIQLM +S5QEAMZYTHNcGvLUrjo0mJcOEFbXT7Unr5/Z5LaGA4zpeYvjhtANRo6ScxfGzmTANh49eKxi/Cip +cYMRNHnT82Noy8Y2HsUKrhE22qe+NwNiRuvOSTBe7zRKQAxIRMzSTxOfQY2Wj2ihWZMrf+YqViZI +aFJqj5hQHUc5WgCgDScMLaNdDjwzxrmj5fswtSd19U3/9EFkjeoISuXAUYA5EJuNTKlIBjBQDGO6 +jkZgfVu6qUvmtBOh4wfUYaqhgDZjYkxFhelpYDHFEZmBUY4JFoANU3BgC1SJTDL7jNSwDSd4F705 +MYGzLKUMDDxbA7My+H5oSpjgbs4g2QFNO8cR0jRRYSdMcfyg51IKLjaEeWAJvAXXH93WkytjxsA8 +lIJWjdn/MRldASJbEgh4Sg5DmMgKJzAdlojo5IdlzQL/DqnYPzkj/G+xSWbHchuwYvDuNgZBFwBj +LukUBCxotNE7idZkKetEc20iGGY6FRlTHg9AhMg0PW5P2oGYSPAXmBFJhovskKry5BmuZzBaQLPX ++Cs9J0E8kAiSVjPEa0vi3ARcYG4phfHWOAGtAv4KkjSgTAohYzco/J2UjCiDGeJAON21xsHBKsYC +V3aWUAqXvQ0Ohz5BDQcdimj0mQtBkhwVZN1JVGyKUoPIMsow5SLhUxQxNWdIlMkrNA/hKyM6PASD +IOjeRJPtd0jXEoEybutZ2ywwHC2RGJg2khFFkvAjszB6hxUjerTeosOYNIyawNLF9aK8CV1cubiH +3SSVDWwMVCvBZoxzmGAJHkJQxhMilfjwOtv5mCqstA67kyU+wg/jHRQdk6uKvnL2hETC3FcYSecL +iUTorZCpyT0U6BePTHQT+5cjyBg5mEYo0FUR4T6PpzkQkpGXj6IStDwcDLcmW/MJQCmljsD7YIRk +br/jlgQGAbw7pkcQwAUGTQ8ZdBSCtLngkWGCCqnnaJkY/1WupIkS2APEcceFDfA5CrAQkxyIYiWw +CjP0GTIQy5VLTMsB3HlMKBlA128Z/dbBoFcocDwedNobPOZl/N36Kw0tie+AhaFLir+bg3IJH7YG +YUZblEbrJCZakTLaEnPL/FTxd+S87YuF2L7CCgE7TLuvMb0XiGEA9ACPR7mnzVwqTaxDLq6Wy5hE +fmTUE8q4AjsZ06Q7MI+VTe0zIBqvzNzazY9WgBw2I9u0Nbe56QWJ7jTLRfi0B4Eqm0W2gql9kq5R +A0WqBPTPkq+vY44kg4BOUFfAt2QWJWzSaWoSSR0s6Dc/WgFibEeuACftaAEpDoZLD1CHc11SBmxp +zQYvWcDmt4J2ZtcxKb7uZibzntT6zxXeD9aCVZlq2r/s94RWHJk3FpLxaywGWiGkxJiX2O/GV5Li +RQncQqDajZm+DgUDgrcwiDticXA/50gxHiR4PlUhefB0HkfuKdToYcAYJ391b2WA7Q== + Fz9t+22xe7owyId+YguJBb2En+avDjsD7Nv5adu3ct97N9EdAl2ToAgq0O1S9O+BrqIi8sumKpIf +fG992T096E7as+5pZeJRw0wjSrTAcPGF/UxJC6QJx5RFjO4tZXI38IOJb5HEp+8mpkp7kPuOD6rM +fIfxNY0ZrwNoi81+h/XL0l+qpSB6Kvyemf0X0UqTQ4SpRa5L9C3sMwFoR5HhF3ha2O8UK2O09MX2 +tG3Ev9+j1PxX7t2y9ALVIAdHWAqUpdSnXGRCxPZaZ7wfRC2k5NClh9m6R1NFy3c+96DBe+dTduq9 +t/JWzfkEntIsuQi+u2lUmmThDKyYoW722qhqOK9LU14Fg12efxWzNClPyevIKWHexxUMTBzvo4ox +J/am6x5N48oxb/De+TGv997KMeccZ5SignT9XNOxVVD6JaW65xH61uyssIkjUV4xTXhYLiqXZXCR +OT9QAQoeOrOviitexU9eLODGr9ki3gpQ8NDuJ6GA+UKbIv1FpxLeHyq3c43oy+K32YNJ0T05G/eu +potbowlfviCrM9NakKmZ4akxY3dSbhToWwkdb85krOLWTw+W7acwQXMRgxBa3FZTDKAnyu6r/tsR +f2vz14pv/GVqpqEOXo3SOYM18eunKaZaJbxz+29H/K3NXyu+8Zfpjs8+gRF+0MQo0t/K0dyOqK5U +Fr33gDmVdTz5bjyiRChA0W5bOM3J8JdPP/nukn7LzG/Ph1fw77PTfwI3YdbSqdPWweRqet562h11 +XxWT1rNJH3W7NT+2zK+H3eFwABvO5fmgZ5u+BD7fa8Wty1mn9WJ8NerfW2z7WQt6fLf8hIhWPlJu +rFqXBgc88WjYnfEDMJuejYDL56XWh+fdSW/cHbbarefFqDcYcnODo2/alp7ozv44hc+jV1cFN7aD +N4/f4MBnKFo+vfdZq2NZDsNUZvh7GLyFzuPohN3H71ioF/dQ8/8Ytzp0ImDWU+vBk5ODCUzxYUE4 +jgansBBPDo+hpT5B3p4YCp+PMevug9K2ZPiRonC20HecP/Q/83+v7ESr+7zh++P514P9WXp59B5f +rujlODbm3WAi0tty+l+tN1/3UFUtPJqJ80sPgSCxW6ytpvda/F8csXstm67rNz7hPkWo0n5IqpYs +eUOZWe5Mz3fFr9y8Jcpf44Wv+F9ciUkMuopZXrgmFXyTmNAisijOpWFGtJQZ72GIc/MbjObx7C1Q +9+kn9/5zNP51RN9wd777YPh2Ou2ePD7+rHXvOxhB3LbuPYAN/E3hGt07HF9c4tJ4NBgCyfQcTITB +qGWaGLCxTu7ZNl+gWn7vh8F0AJsyIa1Acjzr9l43QnLQnQ56JQyT8euiCQpJPw2fTeyjiDXUWIAN +49mLojeGrbFPv5qGlhutBkEDjvXce1icte63Pv2kdTfARRrC/Ra9vAV6Quve8+5kVknl4XjUvxrM +6hG4GhXS3ojjq3mD6DxnnrkJ9dni7G79LNBxZ36gTzrSoG9RrV2lYt0RUZr80rpsFJjBpnM8dn0i +Djvt8/tp8e2bYvSs32/A+ffNLty9oyyhUxdgs+ZoSEQqFeZSU62inGJWQmm68DTLEwH6acPg1fXy +aDXDDobFqH+NHCN8G6y9gFaPYiVR8My3vxW9K+yM+ZFQVIjMEQZ2d0FaXktP5kfYbKVWej47O5sW +s89oXJaiuPtkOLwio2s86RS/Ybkcs7vhBRjMxrsljK0jYGnr2zM0E6H5y8FsQ+l999nVbAomYRCj +fziYXg67b83Xz967iHeLy/xg6HsyMp2qLYh2d129n33tvUzt9y7tydMT51kWKIFbFea3cp7dVgob +7VBouYa71PHg4nLodymrfTRxmTefos9hQc7q9FSs76nKU0mZPEpIzDlAJ3uK8d+oIyMsKIn2l/v/ +e+5xLvVeA9hrAHsNYK8BNLX33mOS4l412KsGtVQDOo7wnrev6k2DPOytw/FkVEym17JpzGH0G8Xq +sREdgVoEhfVadzHF4mq6Yi3snZe33nn5LpzZu9PeWSJlu6FQ79fwTV7DpGFFcYo5UfBBqojc5vwB +zdoEj2vM/73BDnWzb4a3eK7eNKmlMZs63cFl9ab5qOjOzpH1dbdLTLtTGW+XL9Ztlx+vGMv3Ymwv +xm6lKnJTBFGGZ0f3gmipIDoYXhWt74pdiVHeBElEebyxjMxtRCKVaW4ztn0Sb6okXrfjY/AL2bwC +BlxQNq9WFZm84rqk2NY4pCKdYi52R6Yy06aEvIhySpDF49rC1IKkLChkVJxLoVcwStxWRmmt8aIS +mFNKpSKzUykGBqWojir296U5flrBISwyeRsZlGaa5k0nkXQPi/WDUqI8RXZURuVFU42O0BUMwtIk +t5JDWRrHmaBwV5SnfFQFGGZTgmAhSqVWcCa5Tra8F4/g9pZnrFVMidMqpruZ8eSRkfid2Mw4PFSv +k5TkPeZuyhWcfq8T8D0rLEDw+1NZbu0EUjrOcpwkcRRjYW67NM1+h6fiBR5hQlU1xsJJy6eO3ump +I9V+7jSeO0mSZbjzScwINxNHsWKgscwhzhtlvFJL50262/Pmg0ybvfG/j0M0sZsPzydjsJb/Mnh1 +PoT/z3bTfL5pCRWrDz+tcSEteWy5O2nxgXdKHYqcnwn5MiqmxtWkGPxwAC8mppjG5rDp6NWweFhc +wuycPht9VsJDv/3QnQx8dbDSYy+KYRdn2suxyUp6/Oz0ny9gun7ZCg+JtdZx9V54eAhr/VpWAMq8 +3BeClXDf+3406I37RYNcqRcNMglXnIGOZCJyWvXNdzbmIo/IEv67caweA/fzkscZe/npG7Kr2oq6 +H3pb3aISrmREPoQ0z+le8QTmICWEigTdKqhrWVfU/IdV0xDrRW02CT+g7WwEgM2UxNOM15JLU8JX +1yPP5/X/OZpdEhsSXi4Xw8EFQbBSIhYEt/Dx2XTWYOXcxi1E7reQhRVtV6O93mfFCo21zPR+o9hk +o5Dkqd9ds/29Wl4r650tTQLBck2yqlwTnr9ATMsKNpniRbuYrCvnimztJ9H7m0T2Jr9bOYfUdg4d +7ND4x9kHG/6P3gH0cDK+bB2fd/vjX3fT97NP4lrj4dr7cY3WX5rpq+2noOlym6m8cuqewGCqrqbF +8+Ojg+GVMYL4nvLT4ahfAvSmk17Z/3bKz1D9K7YuL7ummbM3z8eTf5kHnYLe705ef7ZEer/nQ7F+ +lKe94aTc0zfFZPZZiTmX3YFli2Yrj4bQJNa1vv3tsgty+aA4G0+K1g/FZHqDjI2bIdb/CtJ7X99o +L9KvR7ej6VRZ3QirGuGtpvRv1IqVjDt0o6TIMy07UkT5R1fcCMRlTolwUS5Nzk2ea7xIgpjQybTG +Yu1broHx0UvIZ1dIyOPh+FcsxLmjgc+9pLxJkvIGK79+tl+L7huie1fVV86rvjU13RuhxO4V1A3F +788A714NZ7+sLYLTKkVIaOiuJfZeSbFoLa2JQ5VFvx31g7qi6wuUPu8Oi9msMGQ8P63f77s/h0W7 +f/mMOPDTv5Bz5R8+/eR5r4pLd388H8wK/rnByoChhm3J460u3nX3xeOD1oui714Qabqalx7QSiSZ +UxZd878VQ5QY/ISWqaawjHfxuaaPJ0Uxci2VSHNTD78jpIrN4QtPKT5w+Lbr22dZrCkXNdW50EHl +Xd8eDwy59lLn5mAs3kZq7y0Q5fZPu6+K0azrHgEdDwhGYtMsT0nJk6mkQzORThN7ekZnlGot+BiN +MPnVBuvXIo9bj7+O89bB14nyjIzgaW3K4ycyoVfEku6IjqIop7KZOeKjiioR3olI0X9Kp7SYJXDr +8dcyA8yxDoYyhdYxDbrOUnNcOIqEmQacZB+7zpZRAuzx13lUQomPA6vp9EKEl3MDnkxpZY8dL6SV +C2KAR4m9FPAv4IxCnFIkdHYEr4PEYUlFbA5MAPokph81zNtcU06piGEAGKfCbmK/D75WuceZKBHb +XsUiyxKLzJ69yGP8D00vYqxDJpGNMfEx9mOPV0ZmhnkxpUTDzI9NKn3G1UtT7OgiRkEDA8Nawqjw +SJEwZ4tiM5vyKM7MlFf21HbKXAS+RSp3syiJkOIcO6k9yjTRwoQaAFdKcwSvFsH82440Kdp4+56d +PtJw06JUNC6ZAIxp4leVjvESNpzFCo/yUH9joNychVKpVDSlpCnoY3FR5xIcDu2HAwiixRPHSUpl +zfKMquTCSoy0MiON6SwJVTozhWBDfBHyT/k1k8JaVKYbMK3TzIyF4FF1ZJo5bjHFiaNSiABXliR0 +zCuPMupbolJFqTY4MVPTOXdCTi92TuOCFir1gq5h9SNAlJhZjH2T0i+3LFUx8UlJnbhAUpDqwydk +gu6IGLuTZZ75OawmIwRUQp2I4iRPzJkQusTFFe+O8B49oVI/vNw/DagTIjTh7pG0hxGEJUjrMlGS +kAo+2BTxmogNUl4TtCRQsGD02M9fJakrIFCEXW25mcVSUjJ54gUqJkaZQ1N2TUS4cGGAsH9+aJNc +KeoJsCCnpClcbpGh3BzqC2QVy0F7cs0tt5SFtkj8cgNZhRiJulRGNDdEhDWMaZLkOqJMtQ4MXxq5 ++SJUBsiQ9DwQLyIjDwplLUhzKVCWUq2/LLbiwbPS9NKJF8m8zKNwC0/pwiGsGpjwQvF7iBHKmEqG +c6q0hcQ0LFL4rVJmuD5hkSeSBD9eWGy2/ZTnjMZdBnnp6QTW4nzOaGUEXANxntDCBLSxmdhAEE0W +nZk6FtpASbQkOJP8UCjcP0Wc0ApOA2kam6EEbpEaAMw3SxDkXk4C3212vAPEpc0OLy6HzQ4HOQvw +popUHMCXCMILg5EROtjKE8LnZKAdH6lcrQ3Am2GHaVVrFbBUp0YaZnT9LJ3VMkpaJASdh3Oi352y +SWQ4WCj9gRNK0yLycjYWKicPVJKLzEj8GPY/mlN5llMmIdfbTowAQhoAkd9eNC51QTtWJj1mLWOz +OtIkIsxZEsFn2l20oOHnjSvmPdvuO6WNi/atQFjG5ipsPFIrIuIGsBYvlKeDpcQNOwtw17ITTcyN +Hk5dUgECVQWGzBwuBPSGzbAqjMYG3MFLvnHp8hZrVywstIDNObLCMNnzOElTIzxT2My0WaWpoHWr +Yf0TSyX3WPCii2xOpkFMPI5JUPNSs8Fx0uK/aBmdPFDyq4Pi5eYlRMev39Z4HluVHns26Z0P+jWe +tA39w6x0H5yb919dXLAdu7oLpuFSRI/Hw34xar2gtLq12MLWBuVyZ3aAhJzWpqV9alWJ//nnbFve +Fu8+nnTfUuG3568a2mJmD0chHOyMUhkZgJedEh4FuxmJCbBfTC4wanOi4gMLd5xvEidyoFzoPDHS +LTZH2kEMkKRQYE3RnPX/Zz0RtRSF4kz5HUKrOKU9SoG1QRs17M2UmQxSzXQv5l7Nf7B4U1q/aBak +gfRtXAvXKQL4LwpGL75ApUhoR0DJlKvwQ5Qqq1Jw5+Y/MG5JQpesLPjXCwQJ8pvoTQ== + 0sxIVNiJlNnI84y0Ke3+X97LVDy/Q4I1SeJZgi2ojV4Fo2/sl5Q7Nv+BkaZm2yVlJfUiC3YrTT0U +qO6l9EHF1sLO3P95skQJKRW4A8C/3qbKEpWbSxxETPMPdPdUWyuLezT/wakXEZlWOLVlaPxtVseK +rEnSfRIcavjXr74fi9PW4Xg4nrQeT8ZXl34d2okOsj7hU51sWwUafl5S/3TsVHwZaJawfUQpOz9o +2ZA+ZZWAlLUMaZC6CWS0NdIH0kBdA4Jj2o+AYTq2LpKlVrRSFVa06YkZ3BwHWVosAu/nIe20ZAwZ +LBLpisOuwIpNTTArlime1zR6qbncjw9vlnsiaQ6nfrFJkAiKpptMkXXYCZ1qqzXyOdBAv2X+ZLmf +eILxPT/wjjfnXmt2JdDRYDor+SDn0jkqwkOfhjVmPq04OBcE3T8NbxhadByat294uZGIwksbEdW/ +YdeuZrPxyN5oXHHJ8eLdjngX2uX3l3MPIhOAAR7wvDsqhieHw/G0ME2fccvurHg0KIZ91/TRYHiB +f18cEweOiy5oBMSqSdEfzFqH3QldM3Z8Pr68xBR5ABDb/gKMNHf19VuPum/GE+O3vEu0f7ZwfaCl +eQX/7Gg/BEovitEMutqlaxoZgL5l/Dp3ZeO9n54efTfuF0t+vt+6+9vFcAQN2t3ZbDI4hRnCdy7e +ezCBLf5DormmtwTtQH0b9ifFyLbisAz/jP/M/N2Rd/8wmp686U6m94MS42HbN130sNrG+MN0SUNM +/rTtbG+m5a87z6rTwagPZIs6nAKWHhez74gnNdgVNv/iRhA7Go+Wdb1E6HDce130axHJTa9zUrw7 +I8RqRtQb6wFe31prZdQZ3a0PfnOh8OWb+mIB296MSY50wjY6G1/cAPH3Xqfol9MuxmRxDwVBU3+m +foh1c4xXcNys/tyupTw9+/UGzO8dkORTvAv71ox9G0w9MONtws1Son8d9OnI9PpRty1vhOyuSdx5 +YcuhrKeOm94I8jKVy7XE/VZvrd4QkiTGOtbS9LYWTW9vCE0uGW4pPadjMLcvjoqz2bPJAKzZWuQt +PnRjNAkSkcfjq0mvOMA82JuhSsAOdyP6cVHMun3Qsa6hM/k7d+Z3fesoqTXngtYEcseNDoZF0ce5 ++EOAnIsJHE7Gl+iPMrnWVbv+/JrMRCJa9A/hfz4ejGZE0N0XV8NiUprwvuABFWF4ygefgLgHk9np +uDvp4zXs8zUbAjtaMBXPH7xgUBS12viPf/+LYvhy/MK82vTl+Xg6wG7Tz9J1p8FDYl5EPJlyn62/ +8ruq2cBtiIVM7M9Pi/7g6qL1opiOh1c2k9CN6YMnQrScUwy016tLKmYxK0bFpPV8UmBdlJAn/ijZ +gyd562kxPW+96E5nxWTwL8pGDN5jH4mj0iPPrmaXV7N1D4mEk2orOnjUHb266r4qWs/Hl1eXPHHm +J0vsdvjLbr/vZ4Xh6AVVci/Dppfj2TysOxywmExZoPcvBx0L4272xjYb2AzEk9aDq9nYEVnMYyWq +eNG0Xo/GvddjYMorE5xY1XYAjOrOitYpJuNyWZFS67x12b2EwZsOLq6G3YCn0rE0b80m3dH0sgsi +o/cWXjvoQ3PXTQXbbRY07vJ66VEIRcLLr4JFsqRdXWSvKM+zZuOJcwJppWK1vKkIO7m2bdiHtY19 +H4SOs9g15Vl62B296U6PPT9FaShpUU3eFC30x7e+7Q9m3dPBcDB764cyEJ4vx5dzsjP48QVqneHP +LkX+8XB82h2+KC6vhlM/AzKdovzMF+Xn82IyvSxIED+G2XBiMY8G03OYZNRwTq4uPOEl8JNRv/jt +0WAy5WfolZTRVOu9z4fdEWgIqMeEb05zBVhioddiwR2HkBwWw+G3v838zlS/Jw7HYkfqsuC46I1H +/fDNad6IBzD4JQakoubwmS23YvTq98LRP9eJcDJHrTO3V1zytMZg0CVGY1huUgS01rh5yhcGLvVL +svTaCYnY9hvAAosT5nx31Ktad+EzveHgElYzOrV+g9X8ChbIdM3QOm7QiQtarsczkMNrHns0HI8n +K59rq5I2sYQvtrYVoWu2Kh1Hqzuw6Hgo2wLHxfAv3RlINsBeTJ48nIa6xbK2R+Ned4hKQ6l12OIl ++srw1Qu7iJAnx7ANU7D+6bjvDMAl9L0M7an1k/oYOlYtSs0qr1JT53GAwjgLtooVE+aF2yhUlmdi +RcsD/1r0TaSrppPHKr0yNt/yL2NQO8ajv4R+CaGWtcbVdggWGbdcjpd68Oyy2/P7VRLslVZ1RNXy +v666ONlaR8WbYrhmQYLuMxyMitaUzgbyWrwrkk7UiQJt9fWDJ4+uhkPeaO2pKvi1QmfSAf7uaDZo +QXe6jDpeSiCy4rhaY6vq8Qz28LVMI2O8zLOlQ0EL9lG3V/gac6vnBD3wONShlvaDmpY7sna2BTNT +ZSspLInrlfLooFozq2wbrqHVhJXenyxv/MOg+BVmE9iFs2CvqK8YoPhkQ40XopbOYKliTTg8y4ce +W86PfKKydBlmGp8Q9ZpVay8st8L4Xng8cG4jWDg+6CX0Eey3bGc+eVhlFQrZAvvnMVdywlOQxkxc +aRiap45wTQF6eor040XLsPQu0fr2+XHzl5nH6rytsR263uAmSlcZ2WUxhsYkyq8HKL+8xRfKUsJ4 +iFrNodVqXpS0moW2z6z4Oi4J3GhZs5deyoV6GLUxNu69H4wCdjCvgJXaPptXDet4J3Ck6nMLW69j +l8FZk1+m8XqGldst4ZhpVJNlFuM8z0Ro6o/GXt9uDUak1aInqVK/W7Gs73mn8L1/jk87hLA7HLLx +yy/3Y7PwBCyECSyIeUKWYV7TbPp6cHkKjAmcNJXtJqBeTKYFkjRZ0xTs96HXfO8u+v7mH2DiQ7Lu +OyseOf7X8emT0dm4Faiy6zi+rHeng9lFF42osgByUitsf/nq4nXnFNXW8dlZx3j8eUNd2v6iO3k9 +XWhfxf8y+qtpAXKPlGS/bK0bsvVjcXrvh0G/GN97OgbrovhlNVdxCApiT9nPutCF6WzY6Zt30IRx +g7tm2PA5+0Dgoq7z0GX/An4ejur367JfH73JFPGPVM2Cy8uJbbdqbKCR7QDrRbnqyMpRh6Zh2DVL +RCdb1rAUwcw6ybJ2gwtY550hqCp1287GvDWqTC/vgGk8CXsRx+twl6byXZiUIHv7rdO3rYeTwRu6 +XnPFuCCaUWkfWXxVb56Jy1uVOLgC2TjUw1agm2+3MBWoGTly1wi+fjEdvBpVuYIrhfOpjc2txEkt +x2eD4by5XC3vp0a81Ze95YFZpH046Vx498CyJr3xCEvLoWN/FUHY1G2jp+acldm7ZWXzSb8D9jUW +AyhL6sqWZ6BnuEp85KKtbHZpA0ArJwa9+FVn9WS0jThTTkRLm03RHeKwrW34Zg2l097lsPd2hfAy +jXqj6cppDY1mg2EptrGEShiyYfeyBjtsw1UE0KZXjNAxtVJIY7OpK4Kydi5TeyPVg8VS5yFYBTMs +q8OdwWvHlu3tsCOg2jknqFZs7Osa9Sbjy3VtUOMbgPazrt0kKFay9r3o9zvtTqarhrSsnwR7UY3W +s5CudY3D3aiGYhX0pEZr35MajcOeVK2ss9Gs0x+ukYim0eXkbDxaKQ6x3fTq1K3SuGq0pkBuybNX +1eR0gHrwqkGfdkbFq26QALCkFRo2oBxP18whbAj70mgNtqFAfF1HYLXkg4bT8y4YFsUqbmGrYoau +QXfLRZA7MNdyrllatRv8dtkpxzGoe1XNJgvmAnlHqpq+qrIsqhraLTNwbFaNrW9ofLZrmg4Hq6QJ +tEAPbbdssS9pOb7srZI41GK6avipRf9qtQdihXCG59coJ2AxTmtsJdTs7GrUWzVnTCPr/nDzZs3+ +QQ91RyOXzlBttlOztRZH7yLUtO5+3znutMx5SjCm+62/3z3+8dnzv3/WeiPX2H4XoAuGGmOVEgqN +0HgrhRurGnG0sXfxdpWHIGg5np0XpRQNZ8Q/4PatckTKuXaUd/w9H/xWDJ8XE6zxNu8EOv7h8cvi +4jLwMXDn4ZdvL06LvnH8LP74CGQWBs3ChRxgxVyS/wSDtvKFv82ejczFRSUuWKxBfCz2vzyfFL1B +IEoT/xMdT3xZkaWIj706q+jCT06tlwG5I5gGi2sZfnn48mEFEqqdRyHDy+6CL8zScgxbUjGblXx6 +LvI055q9xEOL8+9Z8OSfj3/9y6Bf11d29+fgMqlWULzuOhweOB+fP3x0wtkhwaswRQQQH3YvTaLI +oFi5fTQIkFdvLNyVp+PRuEdnXB+Ofx2ZQyCLDvJqBBIRmFQvjByPZs/N0kcuPB8PByvNBHg+wefZ +7bRigfOrXk66l5frWhJVFFk+8BrmqsFwvtcabU2q42Clw5LbPoIxARGKkSgWqy/PYdxb3UnRAjnV +sh6elp3v09av58WoNe2+wQnWHbXCiYhsbXWnCDYVKOENLl+s0/p+Sijh3zKyt+OrFsiqUWs8ahVm +htGrDbpXWNt2UHrRFy14mXt0BNS2ZmNE0StaA3I+d1vD7lvMY4OxgCE2qX3Tq945du/J6CG5ITwa +87YR7HhX0LvxmX/9YNq6Gr3GapGd1cuLhx9Q9yaDy3X2c2msXqxRqf2EMZrng8kqq5VbvyheYarp +Svul1I2D0IW1vvnLlXaZkyJgmj1ZbZpx05eTwUXY41UL+njWHfXxDHfd3h55i0gqvW5VvoSxL8fe +1wm3ijB8lbESDiXMylK63aqhx6ItXvb958Alc4mVgtNsVLhlvcA1UIsB+Kp69NNIwKom5eXlnKNk +ucgxPHsZ5H3WYQByGfSZl+dXF6ej7mDIs2QdKYfeXAvYtqSDK1M1Vk5z4+nH6RuoLGuUY2ahraH6 +9rvacYJA2oC47Nbb1eefKO1+NV9oNlKsgV1yES7xCM2v7B+L2pIOFmH1fF9Bm93Zn4x6sFXME7jk +wfXJP5U+Ebcvk2v8EagmIJR/HU9eH6wLaS2ZmzZJabUboEHWeqX1vYS9dVWppbpYzfGh1x6Ssb4w +PM24HEjzZCWl2FvfzycYqnlwOnYuniCFY57PdQ4UNDfZ54Qg5k5SGkGwetduTtUSbfWIl/ePugNe +M1V1M9nxpA9a4eBs4MzQZlOgvtJUZll5oUm5xHCp4NrC7ElqLZMlw1XD8nrQm4xPu7Oj7ttispk0 +8jraakLnBMICpY1GeMHM8r4OaGTm+6GzRtnkPRiwufvg+PDJk0w9LPB19GvyH8/+8PPnX/349R/v +d3/64q/xH561D76ZPL44//LV6N//+ujfv7j7x8NBtzP9vf7+L9/q3335zfeP//w0+Y8vj/7+x6ff +TK566aNv5dPsjkiS30XR9OE/H776Ivr9N/f/0fnTN199cTn9Zvqf8h685pv7R/8+4VZ/nR28+st/ +HX3zVVIcHw6+/nPvYafzx1cL7zrq/w1emD58dOfL9L8fzx7+85eD5L/bXzy4GB9NHw== + PDmenX/+Z/27q0cPk9//ePDP4R9/hNc8PIv+elqJ7fdpfpb+8F8///3By8POD8vfGrb78pdvvnr9 +6Jdvvpx2Lj5/+MWdq0d3H/fP4DXEr0f/A4Py8OyXH9OD4TfDn748OzifHZ6n/y1KHPmfPzzsiaP/ +/ear//jjjwYRdHp6+I9X/xjDpz/878Mn/Sf/ftDO/vn7B8ft341MJ37q9q/gNfk/737e+7an/uvu +4Xlycv+rB3fiP3x+8N0X//P5N4d//P7RYXH1pz//8Nffnd/v9bqv8dPg82/Pjs7Nq0V0r5tOBr// +ny8H//hr/2B45z/+2J58/verB0fHf/hfJOCzb+7/9TyG1+j7P/zyzYNR748Xn3/99P699OLvXw/S +9N70LH4w6T0Rn7/+UjiUvYd/nf4AnEv/WKQ/xlH/y8HhvS4Msnj69d32F8XBMH1+YWj429Gdbw6f +fPW7H7/9IldYQ//hk5/17/6cHo7/8flXP/R//lKe/u4Xwvvn0R0g6c/6T7/DYflZ/6j/a4Ss+vPB +6890207QH/pHkfjld08f3ut+9YdH//75f0/wNRp/+AdhoSbwmuj0/3uS0JfP//zoK/vpqx////a+ +azmZZknw/o/gHYRAeNOOxgjhnQRyGAmQBEgCIQkJz5ydm7nY2DfaN9hn2QfZqmrfXe0ATcRsTJz4 +vyPaZFZlZWWl7SzXueeLofKIg0b1qEvAwV0imMmUQ1QpO73gAT1epM/H3zcDtJriiAG820JMQAOe +KlyJQ3iRhkD6LprwqQmDrsWchdIQkRuoh1mG7bPf7/l26TtY+ojWV+XXV6+7wL517pN3Z91O/rZY +uCt9tL5WudVLagrQFJhee8gRtM+O++UhGXwoMN38baX0/Tgsfn2z0fOP37NppfgRIAENM6N4vDle +SAgTrdVvPX/bCNQrJf+4zlFHoDW3BSALbJeR+2D24XXFTSnDJl5z5+3tab59td1pJ6cirowSwmJ0 +104BVAvsoNsiTLQt98dnU2qUzpaIynOORnyQHqUrJcAjgVCwsEgO1OulJK58cYXF4Ngn+7nZITrB +2chJddWo5odXJOKbdHB5Pqr4PuqRPJFu9ym/e5DmRqKkCLtrJicVn2fpL36yzVk52IhUJH4F+6C3 +QMKmVR5DRs2B3fXrAZNz+YvTz/Imfv7eaebjfepRvQ53tZ8HBfDTajkcekviliU5m9SLAE2+fT0O +AmGTSZYKjd4MN170qOy5ai/+ATZPmSKoKnOtZZ/tXcV/93NeKcX6VDBTHcHPqUlTA/N6/6iUS7F4 +gQ3fPiDZEyFrDyGEtRQdLQOF7+34t/Azf1jk259dN4BRD4oAluXQ4oaqeMLxp3zz49MLXnvxFNhg +45MXnf7Sh7fGgvEuPjmRWH7o1gSJDjDUX9p0JTe96EJ5Pyq9MZ+P+c7Z+0b5nCffbD/9JL5/wmkk +3aRzAaKRHlhcEenCzLf8qqSrpE8m6vvNwKucLOBskYluknjblX0Xq0fp5FHdhQzt28anYICTluaB +xCh4frn5APL73RUrkLufp3xrdFXk7ybzo1y6VoyAR0YPQB40PAWyvxvmW7s2I91FD0OZBq785tbv +KQ+3ZPKNGu2ls7fFebz5MfWRb4NOnvY43WXI2kWyWmzk4F8Z4qpKXhCTt1SWDPmKWfFaRnoDoJEe +RZfhzwKUi0X0JvrJthrUPbx7wb0uYCjCawUOWj4drsRj4VKTGvaXZfhIGj0Mf5YAGnGABfjUjQSI +QwMRKmHkxOFnxDfO0SNwOHdoTOKE82gkAA2aKTdnOKz4Xe26Da+dI2gSGgRDTSVh0Gqs6KcIryWg +EV9HL53DB9BEshI10fNogBwh59Pze5EILURSEU1atXyQBZSrhVnfPRZDtRICGu4lSC8JOJoIIpWS +IhdoXtJPBE1EXcUMIoefTcZ8WbhBo79EkBxW5U+ON+BBoMceurwBH26I85L4BUsvdAMytJZeF9x0 +0Q4SKHIhzRo+fIujq2rLijS84ImmmikiS0oJI6scTlFEzbG2Cit6WNp9kKGlJVMsbUZiXvQ8JEYe +s2XOxSHeiWKEY1V0Q5ACCK59chszDaI6IiSCLHAaThqiyYl71B4zcssi7iVedKJRNtkE6b9Ff3FL +ACeChg//6St1wkC+/VCfV3LeSRvYAR+U/PxI5ufg9Jw2KqPrXqriDETgsQanlhA0gLAb6DOlWe7R +1ZkWvwbDXPl9tvJwZ5tMx4ht7/TNHbkuEnxE5g601pQWDxpqaRr2Zzmd8O7S/ywdegp7jHDlHry+ +ZPFz1+yX6vVVQT6lwnCSb85Lt7nWYP0Glduf3C+pRBNEpkXqhvgZpsOjykJ9N3rqfwKG6sOy/B5q +RwtsiArLTEuy8DYtTQLlmqRyIQXqapeUaMNrZ8+JW5l1J9csgP0KDeDkT2XxwaltGgBdBrwWXkSv +m895ODCoQAFdPtY/xHixYLkgBepA48WC5SKogyKjhuHkOMNaYSEPZpIFk/iJrGv8OnTOZrza1L0q +IA1XIpUE6v87wwPZ24LFVXsu1QusF2DwvxXuc0+Bwv3ZyxapylBqxDGkkpsqiPszbD1SuvyOv0qU +g4YHJB6/BPl5Lf7w02jnbzt1wPZgm3I8Ko1Ez+bgSJph2YC4D6qFH3b6hGwDgEYyD7RDndyWqrOz +Cdhn92no/ngHf4W21eXpWzIZPGdulHAbOjZM2ssLm2q+9ZMLgtenK/K9mb2lch1nkjdn24EJoNeM +MXEOUP2Zq/j57EyBEQ+HAgu8RMCEI1AKFGbXQWCo3H0w4kZJQbthUJhRF07phsjzRGr8+0PApbpS +WNJsoZIuP0dEKPHK4CXgqpTnO7g9qbPkb4Ljr5A7+pSIvzeuCvd3OXB69H5v+KHuemf5+5vWAzTJ +hRuP3zRP5oWHiM92b3dEYxn5qW5uJ2sVamF7qrAfGzVAI3JmJbdef3aY1PVjFmE4J7LnI2gAFomP +ZPFSBvx2WagVmF2BIEOdjVOxDk+DfPK8HhZvtJlV5CvPWWvlUG59elWrBPwhBoiuR2AAhcZzcFw1 +K5Wh3/kJ50rn0m+Dee7xPuhJfQZbX+A0TH4jdpfJao2roxYuXa0DI57TtHzjLGe4R8WdrIBmbRtT +bN6DjkTkszHbybTkpzTexrKRwG0MrMXFR/Fr88Ui90P4qUlclVdFFUgL3gAZ3HsnOMyFbUwDpab+ +gx5JkQkntAgq/t7dNl/vkWNuLS/qN+PS+DcZEljQdwrM+SxRKtZc3OEUXjgzEc5hwHnbHi9iqcnI +M+FJVbuLFn4iTRIAbc2RLgLQcDhvOomX8nBw9gSGP3XmVoWBTzzCPkXuAzKYdZ8BYiQv4Rk0Lb9F ++19KzQbJ7ydk4vNHeGMKFaj44/WypTzPuUfjabo8KQ9u34ZAYzmHsufDX34PEs95xpe8B6LwMcHp +Bzx+2pVLZzue0uXv11Mh9tCN5O8Dd9N8sx2Ehkf1rPoSL8zI8VquwHAHzEW0dPnUCEANpIkeAbI6 +3cINP9H2uFuVocvTK30AkhV+Eu5Q6crn9yGVR5ICSL2Yns0AZyRPzz/crU8MVgYcq81NORhgP+Tn +HVyv5bAwyD24t1sRdQMs89TJbhuVJmToWDsSVtzzOonLp2qahyEeucive/398ZH68t5fA10vlK+U +erUAbnKK52JBgOb8ZfH0bPTUQyB+835+q3rkfDLwz5DfLXUzPf8qhxZ9EojJGJlvxSov1d9twAuf ++xaFjYaXXBtwtlx/cupNlu1WizfFh6yKQfjYx9r5BFTqVROsdG4lUxt5UEQEUPgRtnBA8RPMOkTA +Rq2z7EVlVUuXfhoxSUHmF3LgcpY+WqNF8evUHQP8zdzm55nLBY6R0NpA3rtdvC+T1x9RMn+bKtdz +54WlXC3nx5b25dbh5A5K6Fw+/jK+KX0kR9Fyf7L1qEia/F5720AXGPTyi8/bACSakmVELQr9fJaG +D4aVvZSxSuaCpXFckpzly+18PNlE+uSw9HG/gYc0JzX48dZclWL+ZVop5qbNmvuCvMwno7M8/pF8 +4Dv30L58raRLW9lwgFx2neZSj5NpLrFcD5ErE4MG2HwBtF6Al+4+rc6V0/+UUNLVn+vfYCZercHz +ZtU/74mrRQOpWd5AF/894JFvT+7ho72TAc+wV7tSpDkO51I33zOZ5g7+abOnlXmRD92I+3aVRyZu +4Rech4ol8P5EPyeDkUDuCSOnSO12V6oNNptS6K1STvvdZx3Akb1V4fc2E9Myzf0pOM5mfaRAnZM+ +IPSYM6DDtaOlj/Ya2IPEx69sK15uXkbVs4qznlu7BtvSx2IdwfBtEpyjUz8MDnUrxY8sLW0jwb6B +GkMcum851avi7n5/EVRs9lmqZs4mQO9Ispzn9v2hvxHhnld8l+NHaIA+Q2nRLU3SA2hI7IKSjSiG +ieiAz5+Irc8fgbJU/c7fkgUaWOPZWS6dWbrkm1LQjsBf46iMkMQm1GczHaacj4Xr91BkkBg06Ck0 +1EGFamMPqdNKY15+j80B6nDEj6GXNx9vXVfAOvTu8ov8h08HDaB+PaEHwweUKmKaug7S4Gxte5yW +tqyC+/m10dsAot+e2ILt3J7nCSpbuQesNSLK7711rJSrLVfCw6EFVPRYjpuqvdwPCj8KKkfw4qp/ +JSMQOIZeCj/xnBtZGnxAlIWRiXhgB0VHMxX+SK/Fucp9Fdc1P1H4+VmOVHa+jNNkR/lb+Y1Ie+X6 +PQ+S5W7kf14nMKbhgsEeIt9cNLal0O1qLChQs504bMV5g9B4yu+n7AuwdJzrSjnRrKk1kFWt2UDm +9PnHr8cDrPtvVlKRMFrBNZDf5QhacIjGQNE4fywHb71BQMNB2Oi5zDXYj3U3QF2J4FADNCL2x1z6 +p+KXK+hqaC39DQj38qp4U06O0AETzGz6SUlQQtEJZ3Xhu/f3oAVzE/1ypdK8ris8VRn+RFkgMNmf +XLw7LecT1c0WBtLDFd9V+KFIdn4355OU5xfMuumXo86sfpF6iSR09n2iFJ27fOJtOZWdEEj89u9f +a0AJXBDnH7vJWi2IF4FSVPaGGGNGnAO9HCsy2QLKeKtSyU0Bs7d27bE5G7PIMkaUgFbCNeChRwoo +KenrfCuUA2szDcwVaBCPlt93p8N8Ihw5haoiq2IycD7NJwVmNh6zD52Xh0Q8W6wVP5/Gp9AEO82l +7+lBqV5Pn4pxZ/VrUE+rvHrKufOXDtBI4/dBggqt3oHQ78/AMfyxzDd/Yo8KkfzazW383dNS/YoG +3O8qLHHSVUgCuOvH28Md/F4ueLR4UZrG2NN0aPf8xWZWgTIwkwKrSrryzjOlKKtEMSWIJ16mbXib +484TvMjFT0soGQGM5KUYb40XaaiqL92DsOQRTY3H7+0U9Rq4K/yEyXa12+/OwdpsC5L/j3vkZvC2 +q4xedp8wg8OLjKfwPNRm0GLIF5xAXam4FfmIhh/B6nd8+fnbdCPKOQXIAfWLTkVZ3g== + hgLuA9BrBztAw94ZEHH3O+kuz2mP+XYn3pbIl5zlvhtg8r+PCjcnpPToEZxZS2KTJ9I3S5kjFdGr +4E23S4Gv6Hs61KsX8onQJYTn+YKzQbtW1JP0qC8sEK/6lYGOVXjP39ZrMO467UFKUIox3Z+Cs2Ly +dP76uPiGJm60/H1WKScXX+VB97MDZE+4h3l+xHZun755YdOoPOsCr/i354vyO+uPFa79/q/4/PI+ +iAx2tRv7HugC1xUv4Gp3vxzuJaYF5pEOy1jgaxCa5tulTYBd1V+zF8CC9gHrK00qEYpQAjB+c/6W +ml2UXr56Lhm7iYCQ+Q/OoF89GPR98TM3Dpcuf4qPKjWAoO6fXRVfvZCAa3PXDy1kJFB40FlRRnxB +GzVWfmuXY5KYVKDuQ2WiNkaebsGZ0k8i9wuypGlirPTPpMqvo+9Qfp513lVGvhcKborn0pXzg5AG +KAAfDs4vb2tNNtXtvIHZTCq87ggYjpcbVwR0EEP9zw8wPMv9/GzK9WIpaymWHAbL18Ek2H3BENhL +7U35PVMDoDqepTvZKT+5k9NHaEmDsdWgTz8yyLc/37dwlP+RcYhVhBT8CNDJLao92ZyU0AfclZVz +mrKzuVgxF48rv6clByWrBPBJhT1cIh/8OMCCe079bTE5CHlTMLPitv/7v//n//lfxgmHX/PZz2Yb +2byvP9Yrg/R8/rl32RclhYrLy/nsBHbvk5dayr6i1Xr9t8n17mf7tfyZ5FWfnjrHjBpabHxrRVWr +P4iN6wEISySFm45/UPKl/BI+9zGYiY3iwezDW5SIBq/DweznloZ/UUz6PkWLN+7Fv9CNczrb3haA +7lWd1VzNi1doPWXEu1Twosl+Ov107cIZjnqh+8QZzMzSTv9NP+kMfX6Be6OPiDO4S7WcoetuyRkm +rikietHzIfwxZ9F/z2yoDTjuY6UZk70dZehCgk6AHf3bR75EtPOku0RtOIF5Qut15uItH1reXOXq +yU0mUUs/RiqLPvNQXj/3iVK/0mtXLvIX7yTQzeY8Gtp9HyyGA02AsMHqTZibUoRuJN2QaJqnGpv1 ++nzTBlhCl0SUaXETkca2SVS2D9RgMfMQYw+JUN9KcNcvxCYNgCd2wUzV6UFT59amNItEN4kqk1id +f4Of1R/weq+kxPq8frl+vsdjrcYHsdTlIILFOnDfQItGhVjCyn7Vq2d4rGmnb70hz9Z4rHfkM3NK +pQISVphlKyLeeEPXYR2ssU/fq7dXxmNl/M/BNDXFz/W0MoBBO1dn+dPATZeoFOo5Haysyz1f+y90 +sPYGROXjpiVh5XKGRcRVZ9pDXg3bWKzVGtXWpTDVz7RHCCvgyLeycl1hMu/6eZdpQMR+7dL6evTT +D+kHWJmFhqEaRIHHeuf1qrDGYr/DpYRVxtAc4uH65XPe1sGae2XjFTeJxTrIjpp6WKEzyE37zp/x +0007Xzauz0kTj/W+6M+s3L8NHNbg+U8qI2GFa6NkqEC2n7vFY2V6PaKSJG6wWE8r07i7+Uvd4rBC +h0Pl5aWiM13WdTabXxf1sL4S1dDoAY+1SuS9E1+8h7ACNGoib12hLI+1F/apiJy9YS54CpefZxUF +1n6aaMTDJMQaUGEFaDantcmCbb6GKYA4vlSzceOp/6qDlXXFZ+PKQA9ribgOvCQRVsRpqulerlK5 +7/VNE4u1de6ldbHWJy2awGFFBwHzFCZaQ/8pbrqb03ptcvPU9/uwWB+886ku1tbn/egNYYV5Qprp +PlWJh/oyjcfaoM86lVz6Ao91eXWKwwolNET8MKyebnWI/HRLPGbrJTzW60x5OLh/ecFifbmdXSKs +6LzRTve7FxtXdLA+J4iXzU8Yj/Xme/l7m0zQKqzItQURDy/Dc10ir89aQacO1l6HKH/9XmGxJm7C +p87cSxjKNIA4tVJvnt0wPuSxvtF+1ebx9xuvAYSV8mZ8NeVcG8QokMpDrCEJK0QDEQO43yvhDLhY +q7FuFp4LHus2G1TN1fn8+uTnsBZ65KVSKIbWm04Gemkg4ohWQl2G0XQB1uJWIxdrpyyHNUvWwyqh +GFoyN9zJQ7tTxTrCitDwiN3r9evbHGIlVFjX6/xkIbDxlVOFdRP7TvEnTzZ1H1FR+HQxGbU5zQYc +tJPXIascVq3jGSxSund79+Tvg97dT6I2OttJd7UHARDEJY/O62AdPMGiMLDvSVx1l02QwzZ/dzNL +aLcnO/887eIe4CTk3WXqWfduggo0R/p3P18HXolo2gfylKf/rnu3EZxnKf27b7cf59JdNdFY1+3p ++1tN5/VEzVNLdzbc3Q/vKql6txP8EtTWD/I0pSVa5+2qNcc9wEm8UnC21r37ePYWderffS6lLkSi +YR4YnQ3ibt2739u7ZU337uyBKtxLd7VE+51VMgO918GY7s9junevKCbTNSDa2fv8rdXQe93j9Fw+ +B3TvlvPXbxPdu1dU9pQ0IFreSbn9KZ27sRpRvggIs075zlV3g+37TZa/W4ykNduz1h5VA3npAWbD +hJpKG61IjL1PRV4Ujc5+4N0lb7JWhjFOChUWmxvuL6VMo7ZuaIUWneGrZA9Yod9t+E8EXqs4Q6Vm +Ef7ziEw80b7jpAWP8LVZEKTg+pTyXtyFeekO7CClnpZx0V7w5tUv2iPQFJLtjOh1Yu4Fxm53B+Ts +qQcg/EiLCF3Rr4s3PxBUp+X1bhQJK2Tv+hQmV4mIkSmkg5V1QTvoCY+V6fV1sYIz5ZtU62ny6SJT +SBcrPAPf9bCO5ViZFrSkZYgTN4WWDOvY43FJWJFtIGKlVRSGtoE41+qPAqu/x5m4csQKIl9QuliR +baCDFZiMwDYYSFjhbBTTfdHFCoi8YfSxQttAFytAA82DT/x0086IEdaGVxcrUjQkrEgKKBBDRaOt +WNpJUsCP/uIXw1/sj3+tPDfY/c4VUkDnUda1GpS7t6bPxT557uPlRgHM+jkviE7NJh75fiGBmjJn +TqayW/NyxtPKqfY+jL+FpH8yS9+4zdv0UDzxfoHM0p9eiiB9CEYmWXN/o3FkktWnEhBir2WImpbE +FI8/Uz7j/wldL3gMSDsWMEhaJxgRmN/FkntK5awCMrAQ/ZyUzsR/mnJtmvex3YoPlyCaqnzCo6us +4IECg+7cgSseqOvuAgKBOK2eF86yOdx5lDQUXXRgxMRV7OwM/QPZ8lFlRuGGNUteqoYlH9Nw5wUc +fB2ivFlC5ndTORAR1aHofNkV6maEh//ww+eMfswMvU7dGcK1ESeJ/tFdRmENW6fma+gSZxgQOA03 +SajXdgzoZX0NF4hLecPDIr0MoJGBwndFFxTiNFO2F+h1HrbFXxJzKQ9pjr+qzyv71MeSHqg8fYGh +D6Y+Vegnr4xJj4imQy+lFPJrpdCgrJRCtK4UQjLNcEXKz5drOQ3FQSto6OGkEJ58A1R6KRBZZ0Sh +coj7hycfOceTrxd26gpx3e2JHHjYyfVO7U9Ocayh+dHZh/a1GbmrdQ8fisCOpBRUzUtxrMnmNbmL +eHgW0MjUMkDzsLA1JaywARwELL6ujL7ifpSz+8jvAaPrlnSWKrQkX93eGhoEHyPYkzaE/sH9uQhe +COwjZ2jkAcJDI61Cw4FCpJeHiQLaDfhasboBjXcfPD1fT7s7wwV1kaEOGYL/PAVlIQ4NbwAx6SvX +cUsKiSZfVfgPWFXJg61lEDBDUSRqGeT2XhyTbGDcbLZV7Ngy1beN3jRzxGTbiWq0M+2yyIzC66B2 +WcZVM+3MqhSaJaAfWveksqBNSg8DHedpq3tMQcPDxiJXIVlq9pUqrBQYV5VSG0Ov64V0FhuMaZu9 +0j89b5v8iKzoemBM+oqesHzc6WlhGZNuY23D1CJQLOP8zFDbsLGG1btfCRTP0AdAa80tDAxuT0vQ +lAeM3YGJwWIeWs/YyLEzTbm2dzjRhutjEk0p3WwObKny2Yzia411u81s9tSclfEbMKIazmDU03Wx +ZzZV6H46zWSaTPvGb89t9vR427PQXbntmdNcZFezmjUYcWlI1EEGu30C9U49Vm0TSetUEyizEU9q +U38DXmOsqcQDft+YL1VmY2wFqkYiMLR2MCbywNJI1FrnfmQxEQCykfCWdFDnzJrWoM/7yYbpzsU2 +lflLUtYQ9bJ5i8hc4eCvS8j7ZRsYdNwfQEV0Gmk2WEmis1EujXURbt9YHpZrT1GgEp1w771sz4xP +aqui4FISBZb9Avoz9FqgOu9VNyW8QoEw93yo1XyZd/D7EoYGH4/BWqUtWX7ZVCUZocy2w1pGOqY7 +2AKftFUuFYJeRvSyvtl1zSLOjAL0srnZFfQSNzt6g3YnZ1HlTr9Cs1Fudqxxbu6LAsx7atGZYuR0 +uFI7ctXDMXLkqp0pv1dK/V7HdDZ35ILJyTaUwAK2PSpXMNPh2qojRDKj1IO52ilP6j0cIYAZVhSa +EpcAo1ky6+ulOmV1nES8nqbn1/u9gnHi3kFOIkgYC95BlVDQ8e1AArHWGFomRBUuiaVCzc7t1Go2 +YAZ9/6MgoS1o2pDSdbWabYd8vJ6GRnRmPCKrjgg624l7VWwht9ZsHY11lZa8575J3fuNJ2fO7nXp +NJTOmz3c2Mu6+iDUmxIXwtPjeMBBymNwH1GQ7ZzF1HranrQZmvj3BQ+UuEf11FxAINXJZ3YuydVc +fjayww/Gu7zypBA4L3DNCkfo7j45QxfBiCL2vOXaWXdbuONPFV61HMoE0PS8tDgXLW946HlpITQb +uxBvUIHNA9AcHOJAK2d8BkqRQlNASmPT3nCECDsH6NCtyEERLU4Jiiih7QCyfxBKfgEMNEWg0d6x +qowyejmVI+RTKqNFlBF7lPBEEaW5ivEbo/1o4fiB0KiI/UihjmYBk0YDlqgpU0xTK+WxppZum5lf +I902M3UY0IJ0wztTioA2udWh0q0jSTfRxLWj36uhmUs3yS9gEoOC0PaXbtL2rD4sjiDdwMrhpJt9 +KQAA2ZduWi8HB+hw6QahHCGKiwAZhJNCBZ8YBYrKNBuFJ0x+Kj0sjOxseQQSr7gwoaYqrxMYRRqv +Orx2aChXPG8+vCt9kWRRYyuCHX+7xe1q3nlvT+gCaA9OWxIXRjz0hO6eCRXKXf2ALG6lwb6P2gJW +TpUwpStszAFZU/x1oXA+GwDo8KwKBEXH7FYH8s0BKWP4Ft3SuFAEgnYMJzd3OIIZBpHKoTwfweXw +Idq/jFVfT5ubw43C7qNV55fcy6F7Pj7a0v5NPLcQ2uHa//MKdzjaPtbgytn3gGGONQjoEO1fBkU8 +HA841hAgjPaPgyKZuDqArJ6PxocjJ2yeVwefj4rDcagOOXNowOWjpDpBUYTN8hJOT0VqlpTaoasf +DNcGyyKnZshKCK/bPcTJrY4RAGiH7nPZwDCb3CS724BoljRhYTURGj2TCSxoxNKONwjDFgFJH+Tq +4D4Ze6ox6bIFlzVkus/UJ1UxEtYcU8VI1JrtaeGkogrdsW4GoH5qnJ5fAIyNskZNCw== + m+xtc8TUXgBNN/YjuYas5vEDaLT7vN44ijMFEC1uT+/QSXSEqzmMWPPcctB0tn3PMNOXYwsULEac +YWlYFtlCs8mEQ5rbxNIBl4ldz7GGB78OqG5vM3WG5/dDZ+hhUHaG8/QAVvCVcbV8Du5DM4eX88mP +NW0tn0NVtLR3OZ9xLR8noY9QzqeLFdXyOXRLF22W8xnX8jnkpYuHlPMZ1/Ip1cEDyvmMa/kcitLF +A8r5jGv5HAali7bK+Yxr+RyodPEI5XzGzzn4qu+Dy/k0O1hRyycZHgeW8xnX8nF6mnk5nyIB2qDS +7c5bwWniBpn3+sVIqiQaC2PCO4hL5rniAWtFWxW1Jb134m1JrRhjnAiWHcRPJaUGYG/55JHCkjoL +ZG9SnQcUTKuqXhXPfZ+VorTJ9+TBzN+iihQaQTPO8rI2Q847aFbEZ3mGKkcXZt9YJ3zU/piwVRFw +WMaOLqMx4Yr30Gxs1e9ZEjtlVX6JLGvIXhnX1lZ+CZ+fhk0xse9u1vM1cx82O9i91Qu7jCcnWmtm +ZXfKhEu7rkSOocHCH+pp5sru9MI+KjPKrOxO34g1jlbIRWfZMMVEYb+aWSllVR2FQ1HAbA2aMsGL +1EZ83qiVaSGmNfn1WrFlGXPbU884fqP1UzVtFb06UBXetcUaSHMfAKAXLjAu6WlaX5uZr3GWWKo8 +KuDdDjZBd5+gV1VXHdMtRpMrUOp6NFN1zHJN4c40895GTeGbaf2NS+Hj0q+R0y/CMVazMZn33otP +l96wcriaUf01NM+8t5yWMK4qvZ7YNXRYrSlMrM1qcow4QpUSD6EdrWZ1LcVNdAtj7EAzZ3wbRFO6 +ZQ8lmmnhqvVpStJtP6Ip/cVUodsLK5Ooaqp0fgemoMyamqtxFWvtMHHPN3V8ncaleyoYOgBmp6pD +GgNjRA1I+M/IcJ/XLNiDklFoYg9Oa5btQT0AmkzIPWCYfccFrLVD/PyHtaq9vVZpSFg4bwRFB789 +YLGduTfC8Y+hLxuWx+nYeRruN6rWU+UOGlDESJ8BUzL+PouwNtY0zNRGU0LgK20tUF0eWNFj6O9L +e74gjC3FK1AmtXoaAaRflrXFHvD76GmXVve+tPH19bTvS3u+IP2KP01y0t6k+jRxSfD7xmeBD2x6 +bxRjUtg3cFiUHU+JwZiUu9rCsWZAKsbqmExS4s3L84zGpPnKSETlN+bKoo7hvblC3ptD0+CAluy2 +4L0RIoUmBULuVMRziPdG7he4Otx7AwD4jFJGbNTD7eO9cWhKFw/33sB6OJX3RqXcWq8VZGx5b/Ax +gisLBULWqoNgtSDYeBYY2lqKIGxSQigV6bqkSBvkqltRpOlsJ+iywBEO4wrJZf04uRFobVL33uN4 +gMDkUj6zDGIr9XB7Zs0rzhtYyabvi7JRxqZJhnBgSxfNSvxsJ+hikmFRiZ/FnEDDEj9ZMatK5bCZ +dlI3/L6WbBvLtU7DdMA77fdV4TWLJ58wG92kp+NU5iE0x0jbM67MM4jiHrMyD5t2ffd77Mq8Q2o8 +bFTmGSbDHq8yD7m7D9yKFirzpMCKeRLiAZV5ylQr4SXvsSvzHOpvqXLFeceuzJMFJM0Ps/0r85RB +LwspnftV5mmsNb24EKypO0LhPzzyjpZ6CUApUy91tU4rqZcPC0upl6ZSYDOjD1UNiijnwlrCpTmg +kCkLWARkpYpFFwqvpyFARygo0+RGGGXem0s3WOen70DT5lc7ZN18dFKsvauAJsXauzJZDNVm1HcN +dR8O2Y9S/ZPc/XDofgTQDD+Dg5Vpuvuxt7S6H41UdUhzezYllt2O9KljBMjeNsKbuAjQUeoyS1GL +x5opIP3vHet9CkwvsVv7vWPTz7kpvdmqKO7IH9K6vGAVnPEXqUzNbtFn80Ge7pt2Ipu13leT9/FD +Q2hDC2WtVotkX0/frPgWTMoOj1Mk+7w6UpEsBHSUIllYt3Z4kSyEcpQiWQjI2oeuVXYzNncQbRT9 +T8Hazl/yhwUWUO7H7sH7UVWUpyPTjl2Ux9URGOYKHaMoD782Ry/KO8DXqSSasYlvx/Y8oChP7k/j +6vL+pCgP5374g6I8HX+aRQuuZ6QxyoWCQ/59aKPqq0/dtFgrX79X6WnFiIndZDWPDIKKWXNCWnA8 +Q2j63+ezq9loPqFsNzLhkJXK9yzGgIy+PAwEO+4MlKExr7pWl/g9637AR31WiC5VzHEh7WTYSi+E +Q8ivA2oBmrn9rP48vA5LrvGuXEm6c4NKO3NXzkW3XngQVNrZeA+1Wy/1y+tcvsa2r4qFyHuxWIjW +YduF1lI4n85+lIPm/VPKijBc9Rsyo/hCqSf9ArjEfepOzmTKsrvz99trudNahjX2GThLOxcOvWI/ +ptc1KrsbR3WxEpV2wbDY7+z26/pVD+vIAGs1nJRhVVeEpYIbudtOXXbHdD8bYtNGVSnaqc+o7I6M +qLA6lH0Kz3/1iv1Yl2vF7p71yu6ejKrffk2K/Rbtti5WT2PyOdbDOjHpU3jf1cdavnmq6lLYPafP +h3pYoXKrWVqwdfmJo794dk9ZfO4c9xzvflA8yjw3LIFk/Hfcc/xh2mAxKuqNaEZlKrsf9Rlr5HO2 +kN+rVG6Dc342iijTnWdxnOIiC8mwageLfk+vlYUxyWNrBsMyy4M1Sx7hTdxjttfDtVxxYL4AY8EX +ZdRez57b7qlkORPTpDiT+8KljdxBs856xrmD1rnKpLOe7gw18ZuShUYrVmdoobuCZcKb9VhRfw3u +gKZ6NvZNdaLfj0k3tdZqVz4TB/E+hX17+mzsFvbhrATBbXfEwj6r37M5sLAP50XU7JvDC/twVX2O +fQsx9Qv7cG58nQT/Qwr7FIThN68UKTxaYR8OlMPkYyZ7FPbte0jbLOzDxXmk0/NohX24qj6FX+A4 +hX24qj6rWUM2CvtwXnrBxD1iYR9uhTkH8VEL+3AqjyJL9TiFfbiqPofOp/UPKOzTjunTZaBA7VvY +h1NbEdGOW9iHW0NcqtWBhX1qUOYdmPcq7NPVOo9b2GeDaIcU9qlAaSLsRyrs249otgv7jCu9jlbY +p1P1fezCPhwAiObIhX24YIs68/4IhX04QaEycY9R2GcWWDlSYZ+F8+YYhX04cshU9WMV9pkWlB2n +sA9X1YdPGakdxUYMSzaijGjfl/a+OaXf00zbw1NlRlmuvlqZbHsF/ZmFnspxQBc/zZi2KEx07C5+ +BiqHNVJtg15bpJLopEy4hEWiptqGRT5QlEY4dMqx9YalGpNVoSBGowyGpYxt7TUmRDQwLFt9qo3G +hM/N0Bc2BqQy6FOtIz/RsaY0mbLk1UZlMtHu5NKkI7yxK0881gz7/x3c/M8h+0aXRX19n+Z/usJG +0f9v38mJn31z6BWUWavps5RzYZIPLfX/O2y9qr2lw0qbHUOnlqXmf+ZOSEibg5v/CZqNcf+/g5v/ +ObgqPJP+f9bCT8v6Mb7RRWc7pPFC2qjxqB8t/WlZl9RxXDqP5cld+K1yqX6YCLbtM81wNONSWNAH +TWxj572lmj4rGdQQjVm9o35miOViR4jGILnRRpIaJJCus1DF0Nb6jQHULq+6pAl+ClZ31g7cV630 +AkbVu98968uUqVaAtUxy0C2nWgFQ5vlpllOtADSLSeTGmdRIEB6nEPPwSArstWjw1XOBBSwCstQD +FwdFnjjWOsZWRFA0ZfYObAGzeaU9gmap2le384W62rc111b7tuZH/LwhhHaUvs8cp4HxWhFs8sNM +l5ptHDXxayM3No2ytgPa6DAsCtSmbBsb7HpZ25PN7DiFMeKXne2rF1pQjZ0lrdNKCSm4cacfbbYu +BTq2mnvrhvBgL7qDdQwOimH6qA1Ax/iMAQfo0A7fHBRhM0qnp61mRKrqWdMSCnvBYn8Qsx8fLJRQ +WHPeH9z3zyHUe+q1/ttjP2LyNcxl2lH6/umr6nzrvwPZje/7Z6H44hh9/yzk2Ryj759DbCB4+H40 +6PvnUNZGWalO2afvn8OoLy5s/We/75/lz7fDEqzDq32fV5Lyo2viWq72BdDMlR/RjDKr9n1e7Vnt +qynEjB3qbYLFjtfYOm1FNMoioD2EqMbLgQAdpcD0mrBorZkC0q/PVRVSiQqUfi0V7CJop/oeV0il +CK9CWRHS7MeUz2QxLLjBHEIvPIu1VFYKqbwXA7W1Kj/WrNRSKadp4nCVQElro1tLlfJZKp83tO6l +7ZnyWdmeVgqpvBdztWK+t+3ZtVVIpZucBPtKGhy+9jTGroOvLD6gC4FKY8R897Hb49Acpe62GNH/ +KBqyb+z26bPVDBNR00BP6x3vq1o9LoR3pLrbnu5XtfbQbN42tpphmjUQjO5ZdyvbqGJqh8NCObZ5 +3S0Yk/VybKO6W95dBBejEccjFHRCWHtXu2iXZmSxEL16LLkmV9A7WMoGW+2LxSjIgr+qd6jUsNJ9 +rowpb+a0xB1EyCMs8znzfynqAW+yTTlWRWUeQLNxPfTu5J4tZWu6VPGpp1OZ59evB1zvRilSJaFV +JYFEQK8QkXW5403/i1494LMuVjib08qS1p0uUXX1O7pYvZdvkaleazq/hNUhFpRJRL6LUTKsyhq5 +jTfukTos0qqiS78v+/SDwwrQQCKrO/EpSgJf1YWIcgrX03c6WFnXGXNTGsk8t+rivKEB1qqb1cda +vXf1cVgdqBdeoqYo9VRjbRp1WKw/6GMtlzsVZeIYQOyGD4TEv/iq0F3gIqpkAZ3n6CKh+5xDXu9J +jAKpvAWQwdRiW5YOTjDrHqNWR8Vgj+AaUp6nRQP/snjyWczOBHSN+VE4Sa7ZlCwkaFo4rgHwC3Vx +lbkzRb8sSpu4pTsmxND6wypaqa8yL67aOI7VmAb5gc0a01j1O5WME7d0l0/QbBTDatnJcTMqAFR/ +SPOA8jiTTFCOTo5/rHGVKnBmd4aSuxvWANpuQakzJk0OmGbfWCa8rRwwgMZoWPr+ZXtjgqJTPw2M +H5EmD1clusrPmYAyEl7GdIzZz9IAwC8tfN7bzHM7KB/rS5S9sFMtbPaviDJ0S1sOEw3Kh3xi1yFV +SGq+e7dX2R0+/i1PUbRUkrifR1qZpYpKEg/9ui7ue3cO3bo1M6tG+707AwNJx5+mTEXBBGtfK7Za +PBgIm8rRLOnXikbY7BtD52r/9DY0F/Qyb+qnGJs6RmDu43OgPoW6HhhmpclImCXW9pUUHYMdzKur +H2O0V9Cm7eNxQKc642oqh61Kr6StTzHIxqSuvxlXjXzOpqq6YkyyCgEh9C3bvzbrEmduC7WlDvk3 +ugzqEs06QJusoSyQP66alwpZ5ghVG2gHts2ODWhmjYS8mpJfA2iqU+ZAoplWE1mfpjICeijRTFsK +2SNag3nWgaapYsapjQLR9ixJtFqPaFZ/Y16oZqke0Sgl3kJJotV6RIwf2k5JotV6RCkZdq+SRKv1 +iJy7e++SRAW/GFihmpxbeyWJVusREdH2L0mUSGosQRzKSi+7JYlW6xElS3qvkkSdMQ== + aeoRFXFPbkTaeR3erNBhvUndIc0K5bP5w2aFWvfDnzQrdJg1qTtOs0K+YsVYbTm8WaHjnzOMvnj0 +ZoVat92fNCvEpigev1mhw1J/z0OaFSrcD3BYrO6weCqZVSzrdzs0Loyx0fDQ2CVhnm1nseGhta9a +HdzwUDa5Y3zVSq/hoc0cqH0bHhp3O8Q5IfdqeGjsQtIx2O03PMSzoPFXrfZoeGiBoY/R8NA43URy +dB3Y8NC0oOxIfmDDbofCeXNww0Pjyam9HHs3PFSMRNPtUOHrPKThofGUsMmw+zQ8xBZHGn6+3Tpt +LFfvCv60gxseGn+3TIqwH9jw0PDkK3LH2hEaHhp7kx22Pp5l0PDQ2B7Gp13v0fAQV7UpbcH9OU3V +8NAYipH7wVbDQ2MoKEZwjIaHxvEYyf1wYMND42Jeh7pIdt+GhxglVNbtUG6tQamxd8ND1X4klN0O +5crtHtUxhNjw0LwW9ygND427HUoMfWDDQ+MUb5lye1jDQ6mMDMeRkjPFXsmFpuGhMQ055fYIDQ8N +9txmRlsMfZs3PDSGIipQhzY8tN6n8KCGhyIU7DayXUqiaXhoUHJhnto7sdvw0FjNh7M5SsNDvWP9 +AROQ3K+MzIKuLwYkzfajWcND49i1Ki1h/4aHSoKrDcp9VHVsw0NjKPI8m4MaHupBsdp+12LDwwM/ +MaFNALHXolBTJHtYw0OFR1zT7ZALrByh4aFYr2XYe/XghofGyo8ep9lueGjc7dBx8Oem+IaHh3oH +LTY8tFKLe4SGh8bdDh22+xTuVRqsFp3ahof7l+rLuh3K0RzU8FDrgpZ3OxQl9L77UWh4aJw9pj7W +9m54aJxEpfZA7d3wELM2sm6HukSz2/DwAF+nkmj2C6/0bM8DGh5KQgzX7XD/FEVVw0NDtpA3Pzms +4aGxxsibuIc3PDQu0hUO6YMbHiqnqe52qNXTLH+FS9nwUF814jUbk69wWWx4aE2zObjhoXw1tQEg +fMXKHg0Pjc8K/SRymw0Pjc8KXheIYo6LvpHudtvBp5Gov4j1yX0dUn16gsv6HmHjfH9VEaWCpURO +k8I/mYulvEqfc2XxuHyKMzOykGhDRG8nrEjSG4W12oBlPus1tfl0gmPmyhl8unET0e4szj0Fq7qc +7uvMZYTwzZ3R96clQ68/ryqZn5fkfSfgC//6vYVVgahNb/Ku1a7AOp9fxzT4a5Q7iyXOa57r21Uz +tpr1YB+PeCzCvCeuK91IPbJ2xhpVZlRozjrZceuaffxsT25iqwff5MP9mPczpe/TdrM+S/2ku4tJ +1jdfDeOrs3Vuzt44H2+yXjftq7JnH0+Xl/7dp+uJWTxPUoIUQNWmmU679eCMBAc5JzVdPQTTtDdH +VAr1AlH5eL8iqqynuV6Pkr71JvF4uXEN2LdN7O3pTqz8bAcvouHHCN1IngoFeN/R9eZ5ATvwJV2c +OogRJ4qS1/N+Y5jMv98vodktNsiE7TZ3I/IskM81rnD0QuQAE9560NrQbqfudFGBpe/VO7lzPfTb +Gfd8Ha14KGa6c/2MnWNY23ollKs6d6ElcwMT4q7nqELSma+022eEezLm/AJ3C6VCv1RtIzC5u6Ks +fk/y0somB0QcjhIZ9qwIcwdL/cqki1qMFl+qzS57Uxyf5qLb9FUuuhmfV5Ku2V35MUcPAOXmmerP +Q/c5X2OdbwDQw0qAy/UX9ZHBWRwWVvYGufOGc43mlf9dIIbO1x8fh8HyQ7cG/wJzvvuJwFLiEGf+ +Z2K9NTKtiOjWB/MbhltOLkdjEa/wF+lDPmdAk/gc/IwHUC0ykD2XS/DzIsQJG5cXHGtPa3ClGBHe +rEQrZeo6AeDWiGApdLar+GqXl2TI+/lbfp+tkkQ0E/ejocLRvZCBInle/HqNkuDGRVB249VdvABo +hHvFsHSPKvQ7WeHGpYiwLkcYdl9+CrS58QPhsZiR1cbpq3gtKD0MQxHVQeRdvBeWAaouUwS8FuXV +ptgNASudfska26ABRaphOttxAuF4lwuIQxwidw24VglBOgWAjT4pCA5iKBITUOglwOu3gHx3t1FY +rhkC1FwBAXTXIdFLtDv5uwU/n+jodWtGg3fbwWDGlXbBu0GAIfJLRHsNiTAjGZoRoAjbD5eir2lP +ajr3dirpMvOtqkCFh8O9XOsVVF9RLifBEOdFHDyAZk+QQoU7Aum/StwnE9VKzjtply7HF05eave6 +JFpXbjZtSloRyv8zdPG81HtlxNm/AjTbJM8Wb7dhxPM8B791ojzPv3UJ8q1x6Qd/PZE8074NKGR7 +XlJgyd5eaeGvMYNg8Os7ayKQYaSYgp/dKP/67IkQ/hqQ4nDewKHXyPDDmY1p+fZ8owZOelgZ+p/q +1Oh6dcbPZvbLon1OFxJ04nwy8H8UP9nKbeEn4UrIzEixDyk3JekfLpYi86eBLd6NiCN651lmOyDI +Kpnzgb9eSeGvMSU9B/TwJpjh9pvRDCe2fagE/Jnz+EP4FEY8KqPrsyRc2gLtGW7ixFU1GAPr9cLy +AqhLuExkKq/XN1LyCLvCboazQWdx4KWyc4Y+v7vO0MOg7AxdP3ad/pu+zxmOesHpvUvdwXO85gz5 +s22n/+sn4wzP75+dwfdIEh5cbhGuh3MIcYt20fNBvc+NApLPeR/ae8Jmby35p15XYUF0Mj5JdIrC +zguTW1cwVgW/rVfzIxkBXR3oJ/int0BS2ItSRnLOF7T6UF8OoWpy6mWXvox+dbcRzjX0FQKHHNSA +aPd5+QqX/QFMxpu6igXgjQ5AE18j+0YlatFWUElZJNGBdIVj81Evm7dZ4ed0XiFDg/hEkIdAsGbi +D7XiaJYfA6zLAs/V1ZSfNzyukQ4H+CtBIlqS1Y4vARcvxqUpccxYLSJp6OexVi8RRfwwa/+bw1oL +V0goYkmZAK5lmzQnBe4DKi0RryLyeiVMZruQVOWCxjsqHNKY8Cqn+pUHMXDaNrdQRbxXfJeisYHX +wuBaYsc97HlP1GX6Mrrm3Po2IoA71ScmEAwmUI0wtfwvMT6bl9bri0VArk+h3uTp8LWo7dQoX7JH +S0owp8qcFdwlAcC7R2URIBiFqAwGWelWSYlKvFAAuwBpEdGvTKeMFCLIghm0BYRrDyvhWm8d/bqd +B2l3Oj2CUgDyMuJHhZ4CJ8744Rc9kk6pdzbsyO4UPjCSdPGdy386N3JzA4k4OKXd6AL8FD8xEfsM +5B4Dr2CjBitcq244VO2nNoQPIKB1oOO3M165pXakpNeifunQQDiFw+mhBZLbN36JaF3nIlrmtMl1 +ofckKJJA/3xzN58BQzNVdedwvicjR4SBnAjU9B6xAE+HvpwOqg7uqIEgR4ccHVT0ch8JRGCiEhHg +cGaK2BpXE2NMh2xqNhfoEFC17Q5LujaHlVep0bLwRABojOhwsRV2wc4p0cHJbJ48Vpghm7rbIiIg +i6Dgr4t0qL1ETr87Ah0iYV1m4AP+HCFTpIyQcm7iAQicpobBBSkVTGmLI/kPPQqD4GSawTjwMNDH +6axNRFgbDQzkOztkIp1UlJc4wnIItqfVFSFDyW3APmsrHMRkqHgWxMKwSE3oqQmrJoJmAdDIJ/Ka +vpFg0E8/ZEIOY1kkTAeBp6ZgEUBrhUQwNqfVWiEofsgn8LSmVzJc1cLKzz9X+SaDmA/+8Oz+OvQe +ymlAlfEdzGkNJmILhgbAIEcczGneT9/BnEbM/YcIYjLUCIZwAAAaBTHkMDQTGcT3pabIaaHpRfSQ +FYFGtP6+5XRocxgdX/CQQfAGO5agllekOmWwe1/iK3jemExkmTqIv8maO4fUwUMmApRm9R7BbRDB +0YUfB9sgDxtEtkmZH9LrTJQUYdSYbaSTlsF4G5xZPhKEQ1o9jrdpMGhCDJNBLEkZXylFp1VivLvj +4QNFJ/kevoiYrarhufTOFtU7HatDG7Hne/YyK/9Zu83Jf9538siQQB5DpGgi344gbNB4E2HnO1PK +Bofd0u612ii+XCVdvD0Yywm+K+gmgAO06uZEPjaI5m/dnKLB/rduTnSDM9j/0s2JfJwAzR+7OQUJ +/cduziB0ICJO+1M3J4InNwr/xs0JZ40cXX/r5kSeTcRpf+rmRDfgvvlbN6cQKfxjNyfycfI1HgZu +TiiclPLLy/nCAvkE6u7lF7bW3YInZHcWRI+AHTHYAMKcRtC+Ob3zcJuC8EU2PNGA1EIClt9xMcaP +HBxgK+Tgz1QQqBLf0DVTC4lC8Rm88QB3dS2C4snQFxdBKVG8AgWTnmpRnRy3Gqq9K4qZah7hRt2H +fJ1QJx6JLsIAJ3uARfYmXuOyhtDlDjKA6lHJkaiQbg2CiL3VoTuuLnf9AXMHxm6nt1AeBUQfKpz6 +cz6I/IQwgC6sDZxSmBNsnCBcpqK8TOOxTqiXzRhQutqUOHggCTYhBrj5j4zjnwTJkCfon2hz9zNZ +366/pl/zEzCpc8c/0fwlSXbm40VlPZm0J/9jW1q8734n8+1J6iSabxUvLxOx0uR9MZ6chPiATFzm +UuE2P8/qtJ7n+xxWQBZKH8nqrOZqXryWPoheRrZDkBfFu2yvoFMc2qzQ1X3mDA3HT84QVWk5fbVN +CP7scV4Xzj2KDdoiIRVwlSbrwq4cvG48luqXzpYqkJkctaswJld+LEyauehmmo7W8v16qV95aOWi +W2KBznA+VKrIUJBF1TFR+PWa2nqc/vQNAz35D9CJD3UIp7uUiDpD/lyOd/Dfn97AGd7AG1lnOE+P +naHrbs0ZWLnW0EOfkAsODxXkt5909FaGQ4E57xay8FIL6HzTKdw9DytegIK9iF4XN2IU/YSWtY// +63sCv5RW405duasf/Uz5ICvWOFZEOe4Nhofx0UlthW19SUgHvlyy21UfkO4Aw0t66oN0g3afT/PC +jVvZRuAFV/VCOuEHctTVYkgexRrIsUNnPtClAkDkPAc5t/7L5nuHthr6aUt9QLoDZ4H/pfqAznoY +mf9b9UFet/OH6gMSnNAb/7fqA9IdZPHSP1IfkO4gxBb+Tn1AuoN83/yN+oDOJ4Dm76KkUogUis4/ +i5JKIVKHWFn5B1FSKUSKROdfRUklOcvLtL+JkkohUq4ERRUl5fSbEK+0TBlItJsI9xM6iEpX6QUB +AN0SnCSVye9qh0KLAf4JyiqNpCRaKUMWyHbpQDaJiKp60eqFQ2V20WERUeNwqJTdemBE1DgcKqiR +B0dEjcOh0AlzlIiocZQB41LaLyJqHA7l3H1HiIgah0PFyPyhEVHjcKiQanJwRNQ4HMolnx8hIrq/ +x9dWRNQ4HMq5yY8QETUehG5Y1m5E1Dgcqh8ssxkRNQ5SYbbnfhFR43CobY+vXkTU2O2sCpbtHxEN +GoZDYbDsKBHR/TjNdkTUOBy6ZwKANiJqn9P2iogah0NFTjs0ImocDlVx2v4R0aBhOFQdlt07Imox +LHtoRNQ4HCoLyx4WEbUQlj1GRNSYmtx5c4SIqMEg2AZ5cFhWiIgaRyLlh/RBEVHjcA== + 6CFhWUVE1HgQemFZ2xFR43CoXHQeFBG1H5bdKyIq2Cb4cKiUrq0fEfX9WoiIGodDHfx3CQ6OiBqH +QxVRLHjUiD7Xul9+I7kVo5R1eZQSnAtiJUZdHqJUGNtRFZplcSreU4UQoJf2JiC/1vGJQQpgdstu +TJmxeCOCbC4o04BIIjiDHQgWuAFg3AEZ59km/HkvBw52HCTuPW/OA8ZP8ZZL6HrBhSkAL0Puu49y +EVbAUrwf+p6HC9gIwaVljszacH3GBYv8YQbyaDssDxZmc+diyKBZ+IlMA/m794+Gyo3PuR+4bOei +MuRzpvwaQYHy1yppCyBx8Bz/6IC8b1xIgY3Y9s49qb70E9N8a+f+KvfHdzBY1SYlNqZedoMc7+ro +DWjR18kofZ2lbFxkmUfO406V7otQJD1GhQ3wCIC/vUAj9pEUHFePKB4B4xaPtPgXwwEon/+y4Gc/ +LESxqOE7Wv2+GCPvE+JfMp6D317/EobTp+U3SjO34MX8jgmz6bOig5jwuxME9dM6K4eSfrDFiQd3 +UO6f8fHf5OOmJP3DfyWG/65LJvYSkbDSHv8tpOsL+Kf36OM47YVEP+BflPzR6ykDrzGcsasYzn1l +9NArloIJf6VSvn5ICO7T3xgxeUuxkEsjovujzzvv41a9iXu6EpFMs+FN3NOV6PjHnjdxT1eiLDnD +kjdxT1cicj9Y9CYuYCj0HHpHL0lyWJ6P5cFOcPkMXGpNtrsleiQ2LEymX/PG679PwHFDnnD/I8D/ +4L/x5AlJJU6oWAz8iMGrjTfHPz709AnpP2nMAZBhNL/elr7et1+L+ev6309S6Fr3utG5LJ2kTrin +h+Dp8xMfGBMxBI+DW34UZx3CkQ4d/xAnefhP91+Of4CUCOzgWErwyi34J5KIJwgyeUJEaDqeSLJw +bBEqQcaoJBxqhAH/dl/h03DQFPz17/DXFfjrG1z71wlJnFyfPL0QJ2MHedJtOv6JJyMUxbAnYYqO +0Mlk8uQXXSPjACS8RsSJxEk8EYnTRAxcoCIJOs6cxOORJEEw6EKcIKiTIngrHiEJhnsolqBjJ3E2 +QrIUiS6wRAK8FQPgYhT3VpxJorfoSDJJcdeSMQApTgsP0RGKZAFyKkJT/IUYvAPfIgHEOIOuJVki +eQIuUHEGXmAiNJmk4QX+LSbCMskk/xYkG7qWjLMkfChBMHFwIRYhk2DGAFcsmWTRBSqZTPAjZGiS +u8bQCTAvgCLBP8RQYDlghXSc4d+KoXfYSIxFBANTThAsJBgDxwlRJwgwLkBSMs4k0AWGYjhMiUiS +isfRNYIF2OHixOM0mmac4n4rFgu89AHeIyBahB2uBVhBluWWBV5jCYI8aYBr8Qh4iCa5hxqQHOAn +wT2Iu48DokLVQPgJyKEsHeFuoFXUG4PiIe5txN/Sqie5PyAbgoWPoUVOcsQDFwiK4S4k0CJT/Ftg +GqSwyFQEbNUkusagRQZrGoOLDC6waJEB8Ri4fnDywiIzETJBcteSaJEBR9D8Q0m0yCxPe/hWjGd4 +moSLDK7E0CInAMcSHGqaX+QkhRY5yf1RRJuLjaNFTgIeAdgTBJgVWmS4umiRkxw3JSIJfpHhNQrt +yATYAwR6iEkgBktAWcBAVGwM7cgEtzTcABMxhnuI4HdkkkQ7EnAfvyMT3C5JwP2T5EkRZyjuGsPv +SPGhONqR6sUqSmwQA0NgCJERgcAMM6y43PK73OoruQ6yTQJxGB2X+BQuMMuNpYF7QMO5AlexYB+h +7QwfjiHogBkoOArAgzRYRvAwuIeEEZwekhTwWhKwHmBZONgYxaBrKmAcGigLOF5iOYEB+TYm8BLL +CwxW4CWWFxhxgZdYQWAkBF5ieYGRFHgpxgsMnoXgBUFgANbheAlcQwIjQfK8RDNIYIAHOF4CvwWB +Aa8hXgLXkHQHFzheomleuid5XgIXROme4HkJXOOke5znJXCBk+4szybwLYGXYjwvgWucdGeEhxhe +ujPCFmYk6U7zGx9c46Q7zW98ME9OugscCC6I0p0WNn6Ml+60sPFZXrqrF4sXn0nEUAwYCcOvIH8F +QEzQJNrGNA3eYyiwoNwF9H6YISUJEo+wLIsuITaEew0dkYCF0DaOs9Lf74g0HDuJ98HoaEYGgCe+ +AgmYN8syspFQUBhJI+V/8lN5R+KQv5Ik2diJBIAnnIRFZEVhHGA9EzR9Ig00LsxM+vsdnXX8RIX7 +AiUEACK1ZNzOE1QYhbgE3CiVK/KOlimWgLucScoPOfRUQi4I4JVYTBQWCfiTFh9I0Bw5BcnC4yFF +AaV6QPW6Fr52DMphNoShcySMseLpFotzkwPv8hInhn7GCE5xAdcAZ6CDMwze54WVBpLsBIZ7HAkt +IKkSkM8BFnimcMINCCX+EAaCEhFdVI3gNV6hQAqVSDvwLpSVZJzbtOBakowwaLFZkhs+fBfMlwUn +AZSrwk9+mMLPOPdWAzNIbgIMvxIER1lIHwJxlLASqgf4t6hITNow4CUG6RdgNcTXFE9wbwU6nGIN +1QEmAbTkCEuTCfh/FBkjgYYPBRxLwhvSf1Ct1tGVlSqaRofDKXoabVCjL2pVSo3WqdFLccqrRsPF +6MA4RVmjTav0bZxSrtHcNbo9zgDQWAkaOwJnbGgsEo3NoqMr4xRNjYKjUYFwepJGmdKoWzidTKO4 +YVQ7jf6H0RGVSiRW09SooxqFVavTatRejWKM0541KjZGCcdp6hp1XqXw4xVNrVqH09dweh1G/bOu +1mnUCYzCgdNKNKqLSrnBaUAaNUmjSOG0LY1KplHaMJqdRv3DKYhaLVKraSpVUZy+qlVqNWqvVjPW +KM8a9dquWidoGRotRKuoqFUZja6j0oU0upJamdKqWxqNTKWx6ap0gs6n0QlxiqNaudRonyrtVKO9 +qtVbnAqs0ZNVerSOWqfRjTCKD04/UqlQOroRkB3cUcXBBj856sQYjkHBU4KEgJqd8KYg6cFrYJuj +Mcgh8bAZ4UqCO3shAppTEglRQaLiwoIAuRaPkTx4RDb4pqA5aaCp9RUgP1gWaipkjCBicfRHDJwi +yPmXEP+DugrFcqjCJH90/SKcHL3ANZafEkfgMJngxHID86bOY/zRCK9xS0SynOwNUwRHOuxT8AoH +XrzC68pIQ+KVO6zeilEdad63EBaUVfhuDIpc8G6C5WjMjw1NnZLYh4SSC44EXIvxSwWucZxHJjmp +pTMvLDzcczh4wjIDvZrnbjKOfhH80YVbAsGnQdGIHeFxBV/+RU9zY6ElR4vgYgvTFLdP4TVKeI7i +Jt7QQDPgahy/4vhay/14rlZvS8x2w+1K3O7VbEu4Y5BJBHX6OADCu/G5f9H20FIRRx0cFXHUxlER +bdmTJvwH8ANFMDS0JBhwdoHjEo0EbVf2pJuHS3sFrnyfUCf/OqFPrh3/bWr8Fzc1Nv9tavyXNzU2 +/20I/Jc3BDaS/kTqnwhIAv/LcZxAWstORKxlFjJpCbEM24GS1n+Sz1SYr6kPr2XFY9eSK7wMxdJI +4aWZeCIOXXN0jCZhFD5CEMkEUoFZ8T+4jOAAdfyxf2Dz37blfwXbcvPXtuVGzqlxwPJQpWPjSRbs +GPgHQVFQ40sSJMsgUcMJGo2r/XdvV7sgG+Qu919LLvcWfhw4U0y+IREysMNwoYaDTDGLphO3yNBS +4tdAoIDcgAJjIWOC2SkZUAC6gJp7EWsixwTbjJEGl+Dww+cEoagy2FoYi1WHnBj715IlLUhZtSn+ +izcXW9bjQS35Efkvx1+bRps/dMls/jNcMvy+70CW8vlPuo+OfxoFPomsPB+jNK8wzL08u3udTtrr +168fmFM23bz+2+TkdT5fbF+3kyW4dTJdTzbbxXpysvlc/AtegS+JL5ydlW8rjn/+H5GbhSg= + +image/svg+xmlOpenclipartNetwork Interface Card2013-01-25T07:49:01Network Interface Card (NIC)https://openclipart.org/detail/174480/network-interface-card-by-witcombem-174480witcombemCardCircuitElectronicsInterfaceNICNetworkNetwork Interface CardPCI \ No newline at end of file diff --git a/backend/webif/static/img/knxd.svg b/backend/webif/static/img/knxd.svg new file mode 100755 index 000000000..21c93193c --- /dev/null +++ b/backend/webif/static/img/knxd.svg @@ -0,0 +1,1246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + KNXD + + diff --git a/backend/webif/static/img/knxd_service.png b/backend/webif/static/img/knxd_service.png new file mode 100755 index 000000000..3a4d78dd3 Binary files /dev/null and b/backend/webif/static/img/knxd_service.png differ diff --git a/backend/webif/static/img/knxd_socket.png b/backend/webif/static/img/knxd_socket.png new file mode 100755 index 000000000..4668bd17c Binary files /dev/null and b/backend/webif/static/img/knxd_socket.png differ diff --git a/backend/webif/static/img/languages.svg b/backend/webif/static/img/languages.svg new file mode 100755 index 000000000..8bd14a1ce --- /dev/null +++ b/backend/webif/static/img/languages.svg @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + Ciao Modo + + + + مرحبا العالم! + + + Hallo Welt! + + + Hej Värld! + + + Hello World! + + + 世界您好! + + + Salut le Monde! + + + ハローワールド! + + + ¡HOlá mundo! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Hello, World In Several Languages + 2012-08-21T16:08:02 + "Hello, World!" in several languages. The text is converted to paths in the main portion, but is available in text format off-screen. + https://openclipart.org/detail/171842/hello-world-in-several-languages-by-jobrad-171842 + + + JoBrad + + + + + Hello + global + greeting + international + language + welcome + world + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/logfile.svg b/backend/webif/static/img/logfile.svg new file mode 100755 index 000000000..6466aa2f1 --- /dev/null +++ b/backend/webif/static/img/logfile.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/logo_big.png b/backend/webif/static/img/logo_big.png new file mode 100755 index 000000000..93865a18e Binary files /dev/null and b/backend/webif/static/img/logo_big.png differ diff --git a/backend/webif/static/img/logo_long.png b/backend/webif/static/img/logo_long.png new file mode 100755 index 000000000..07c44b49a Binary files /dev/null and b/backend/webif/static/img/logo_long.png differ diff --git a/backend/webif/static/img/logo_small_120x120.png b/backend/webif/static/img/logo_small_120x120.png new file mode 100755 index 000000000..e9e28e3d6 Binary files /dev/null and b/backend/webif/static/img/logo_small_120x120.png differ diff --git a/backend/webif/static/img/logo_small_152x152.png b/backend/webif/static/img/logo_small_152x152.png new file mode 100755 index 000000000..30111c6fc Binary files /dev/null and b/backend/webif/static/img/logo_small_152x152.png differ diff --git a/backend/webif/static/img/logo_small_32x32.png b/backend/webif/static/img/logo_small_32x32.png new file mode 100755 index 000000000..7c1fde81d Binary files /dev/null and b/backend/webif/static/img/logo_small_32x32.png differ diff --git a/backend/webif/static/img/logo_small_76x76.png b/backend/webif/static/img/logo_small_76x76.png new file mode 100755 index 000000000..c3034528b Binary files /dev/null and b/backend/webif/static/img/logo_small_76x76.png differ diff --git a/backend/webif/static/img/password.svg b/backend/webif/static/img/password.svg new file mode 100755 index 000000000..1bbe62e84 --- /dev/null +++ b/backend/webif/static/img/password.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/preferences.svg b/backend/webif/static/img/preferences.svg new file mode 100755 index 000000000..abaa35ae2 --- /dev/null +++ b/backend/webif/static/img/preferences.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/protocol.svg b/backend/webif/static/img/protocol.svg new file mode 100755 index 000000000..ce072f8b5 --- /dev/null +++ b/backend/webif/static/img/protocol.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/python.png b/backend/webif/static/img/python.png new file mode 100755 index 000000000..461284bc0 Binary files /dev/null and b/backend/webif/static/img/python.png differ diff --git a/backend/webif/static/img/reboot.svg b/backend/webif/static/img/reboot.svg new file mode 100755 index 000000000..89510c7ea --- /dev/null +++ b/backend/webif/static/img/reboot.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/webif/static/img/system.svg b/backend/webif/static/img/system.svg new file mode 100755 index 000000000..6c4b7620c --- /dev/null +++ b/backend/webif/static/img/system.svg @@ -0,0 +1,1543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/terminal-server.svg b/backend/webif/static/img/terminal-server.svg new file mode 100755 index 000000000..852bc9e7a --- /dev/null +++ b/backend/webif/static/img/terminal-server.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +image/svg+xmlOpenclipartTerminal Server2013-08-30T09:28:44This clipart ist based on lyte's server clipart representing a terminal server.https://openclipart.org/detail/182737/terminal-server-by-ujmoser-182737ujmoserltsprdpserverterminalservervnc \ No newline at end of file diff --git a/backend/webif/static/img/tree.png b/backend/webif/static/img/tree.png new file mode 100755 index 000000000..c35729217 Binary files /dev/null and b/backend/webif/static/img/tree.png differ diff --git a/backend/webif/static/img/tux_hdd.svg b/backend/webif/static/img/tux_hdd.svg new file mode 100755 index 000000000..7803418e2 --- /dev/null +++ b/backend/webif/static/img/tux_hdd.svg @@ -0,0 +1,7661 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/img/user.svg b/backend/webif/static/img/user.svg new file mode 100755 index 000000000..cdae10f80 --- /dev/null +++ b/backend/webif/static/img/user.svg @@ -0,0 +1,1300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Hombre + + + + diff --git a/backend/webif/static/img/web.svg b/backend/webif/static/img/web.svg new file mode 100755 index 000000000..a59ad70f2 --- /dev/null +++ b/backend/webif/static/img/web.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Cloud + 2008-01-07T05:02:53 + Cloud usually used to represent the internet + https://openclipart.org/detail/10771/cloud-by-cfry + + + cfry + + + + + cloud + internet + internet cloud + network + network cloud + + + + + + + + + + + \ No newline at end of file diff --git a/backend/tests/__init__.py b/backend/webif/static/js/backend.js similarity index 100% rename from backend/tests/__init__.py rename to backend/webif/static/js/backend.js diff --git a/backend/webif/static/js/bootstrap-reload.js b/backend/webif/static/js/bootstrap-reload.js new file mode 100755 index 000000000..41496a165 --- /dev/null +++ b/backend/webif/static/js/bootstrap-reload.js @@ -0,0 +1,68 @@ +(function( $, window, document, undefined ) { + var Reload = function(elem, options) { + this.$elem = $(elem); + this.options = options; + }; + + Reload.prototype.defaults = { + time: 3000, + autoReload: false, + //beforeReload: function(){}, + //afterReload: function(){}, + parameterString: '', + parseData: function(){} + }; + + Reload.prototype.init = function() { + var self = this; + + // Set the configuration parameters + self.config = $.extend({},self.defaults,self.options); + + // Set the container for refresh animation + self.config.refreshContainer = $(self.config.refreshContainer) || self.$elem.find('.refresh-container'); + + // Set the container to update the data with + self.config.dataContainer = $(self.config.dataContainer) || self.$elem.find('.data-container'); + + self.$elem.find('.panel-heading').click(self.reload()); + self.$elem.find('.panel-heading').off('click'); + self.$elem.find('.panel-heading').on('click', function() { + self.reload() + }); + + if(self.config.autoReload) { + setInterval(self.reload,self.config.time); + _self.$elem.find('.fa-sync').addClass('fa-spin'); + } + + return self; + }; + + Reload.prototype.reload = function(){ + var _self = this; + _self.$elem.find('.fa-sync').addClass('fa-spin'); + _self.config.refreshContainer.fadeIn('fast'); + // Send the AJAX request to fetch the data + $.getJSON(_self.$elem.data('url')+_self.config.parameterString, function(result) { + _self.config.parseData(result); + if(_self.config.autoReload) { + _self.config.refreshContainer.fadeOut("done", function() {}); + } else { + _self.config.refreshContainer.fadeOut("done", function() {_self.$elem.find('.fa-sync').removeClass('fa-spin');}); + } + }); + }; + + // Register the plugin to JQuery + $.fn.reload = function(options) { + this.each(function() { + var $this, reload; + $this = $(this); + reload = new Reload(this, options); + return reload.init(); + + }); + }; + +})( window.jQuery, window, document ); \ No newline at end of file diff --git a/backend/webif/static/js/bootstrap-reload.min.js b/backend/webif/static/js/bootstrap-reload.min.js new file mode 100755 index 000000000..56445b75a --- /dev/null +++ b/backend/webif/static/js/bootstrap-reload.min.js @@ -0,0 +1 @@ +!function(n,e,i,a){var t=function(e,i){this.$elem=n(e),this.options=i};t.prototype.defaults={time:3e3,autoReload:!1,parameterString:"",parseData:function(){}},t.prototype.init=function(){var e=this;return e.config=n.extend({},e.defaults,e.options),e.config.refreshContainer=n(e.config.refreshContainer)||e.$elem.find(".refresh-container"),e.config.dataContainer=n(e.config.dataContainer)||e.$elem.find(".data-container"),e.$elem.find(".panel-heading").click(e.reload()),e.$elem.find(".panel-heading").off("click"),e.$elem.find(".panel-heading").on("click",function(){e.reload()}),e.config.autoReload&&(setInterval(e.reload,e.config.time),_self.$elem.find(".fa-sync").addClass("fa-spin")),e},t.prototype.reload=function(){var e=this;e.$elem.find(".fa-sync").addClass("fa-spin"),e.config.refreshContainer.fadeIn("fast"),n.getJSON(e.$elem.data("url")+e.config.parameterString,function(n){e.config.parseData(n),e.config.autoReload?e.config.refreshContainer.fadeOut("done",function(){}):e.config.refreshContainer.fadeOut("done",function(){e.$elem.find(".fa-sync").removeClass("fa-spin")})})},n.fn.reload=function(e){this.each(function(){var i,a;return i=n(this),a=new t(this,e),a.init()})}}(window.jQuery,window,document); \ No newline at end of file diff --git a/backend/webif/static/js/bootstrap-treeview.js b/backend/webif/static/js/bootstrap-treeview.js new file mode 100755 index 000000000..7a82a2eeb --- /dev/null +++ b/backend/webif/static/js/bootstrap-treeview.js @@ -0,0 +1,1249 @@ +/* ========================================================= + * bootstrap-treeview.js v1.2.0 + * ========================================================= + * Copyright 2013 Jonathan Miles + * Project URL : http://www.jondmiles.com/bootstrap-treeview + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +;(function ($, window, document, undefined) { + + /*global jQuery, console*/ + + 'use strict'; + + var pluginName = 'treeview'; + + var _default = {}; + + _default.settings = { + + injectStyle: true, + + levels: 2, + + expandIcon: 'glyphicon glyphicon-plus', + collapseIcon: 'glyphicon glyphicon-minus', + emptyIcon: 'glyphicon', + nodeIcon: '', + selectedIcon: '', + checkedIcon: 'glyphicon glyphicon-check', + uncheckedIcon: 'glyphicon glyphicon-unchecked', + + color: undefined, // '#000000', + backColor: undefined, // '#FFFFFF', + borderColor: undefined, // '#dddddd', + onhoverColor: '#F5F5F5', + selectedColor: '#FFFFFF', + selectedBackColor: '#428bca', + searchResultColor: '#D9534F', + searchResultBackColor: undefined, //'#FFFFFF', + + enableLinks: false, + highlightSelected: true, + highlightSearchResults: true, + showBorder: true, + showIcon: true, + showCheckbox: false, + showTags: false, + multiSelect: false, + + // Event handlers + onNodeChecked: undefined, + onNodeCollapsed: undefined, + onNodeDisabled: undefined, + onNodeEnabled: undefined, + onNodeExpanded: undefined, + onNodeSelected: undefined, + onNodeUnchecked: undefined, + onNodeUnselected: undefined, + onSearchComplete: undefined, + onSearchCleared: undefined + }; + + _default.options = { + silent: false, + ignoreChildren: false + }; + + _default.searchOptions = { + ignoreCase: true, + exactMatch: false, + revealResults: true + }; + + var Tree = function (element, options) { + + this.$element = $(element); + this.elementId = element.id; + this.styleId = this.elementId + '-style'; + + this.init(options); + + return { + + // Options (public access) + options: this.options, + + // Initialize / destroy methods + init: $.proxy(this.init, this), + remove: $.proxy(this.remove, this), + + // Get methods + getNode: $.proxy(this.getNode, this), + getParent: $.proxy(this.getParent, this), + getSiblings: $.proxy(this.getSiblings, this), + getSelected: $.proxy(this.getSelected, this), + getUnselected: $.proxy(this.getUnselected, this), + getExpanded: $.proxy(this.getExpanded, this), + getCollapsed: $.proxy(this.getCollapsed, this), + getChecked: $.proxy(this.getChecked, this), + getUnchecked: $.proxy(this.getUnchecked, this), + getDisabled: $.proxy(this.getDisabled, this), + getEnabled: $.proxy(this.getEnabled, this), + + // Select methods + selectNode: $.proxy(this.selectNode, this), + unselectNode: $.proxy(this.unselectNode, this), + toggleNodeSelected: $.proxy(this.toggleNodeSelected, this), + + // Expand / collapse methods + collapseAll: $.proxy(this.collapseAll, this), + collapseNode: $.proxy(this.collapseNode, this), + expandAll: $.proxy(this.expandAll, this), + expandNode: $.proxy(this.expandNode, this), + toggleNodeExpanded: $.proxy(this.toggleNodeExpanded, this), + revealNode: $.proxy(this.revealNode, this), + + // Expand / collapse methods + checkAll: $.proxy(this.checkAll, this), + checkNode: $.proxy(this.checkNode, this), + uncheckAll: $.proxy(this.uncheckAll, this), + uncheckNode: $.proxy(this.uncheckNode, this), + toggleNodeChecked: $.proxy(this.toggleNodeChecked, this), + + // Disable / enable methods + disableAll: $.proxy(this.disableAll, this), + disableNode: $.proxy(this.disableNode, this), + enableAll: $.proxy(this.enableAll, this), + enableNode: $.proxy(this.enableNode, this), + toggleNodeDisabled: $.proxy(this.toggleNodeDisabled, this), + + // Search methods + search: $.proxy(this.search, this), + clearSearch: $.proxy(this.clearSearch, this) + }; + }; + + Tree.prototype.init = function (options) { + + this.tree = []; + this.nodes = []; + + if (options.data) { + if (typeof options.data === 'string') { + options.data = $.parseJSON(options.data); + } + this.tree = $.extend(true, [], options.data); + delete options.data; + } + this.options = $.extend({}, _default.settings, options); + + this.destroy(); + this.subscribeEvents(); + this.setInitialStates({ nodes: this.tree }, 0); + this.render(); + }; + + Tree.prototype.remove = function () { + this.destroy(); + $.removeData(this, pluginName); + $('#' + this.styleId).remove(); + }; + + Tree.prototype.destroy = function () { + + if (!this.initialized) return; + + this.$wrapper.remove(); + this.$wrapper = null; + + // Switch off events + this.unsubscribeEvents(); + + // Reset this.initialized flag + this.initialized = false; + }; + + Tree.prototype.unsubscribeEvents = function () { + + this.$element.off('click'); + this.$element.off('nodeChecked'); + this.$element.off('nodeCollapsed'); + this.$element.off('nodeDisabled'); + this.$element.off('nodeEnabled'); + this.$element.off('nodeExpanded'); + this.$element.off('nodeSelected'); + this.$element.off('nodeUnchecked'); + this.$element.off('nodeUnselected'); + this.$element.off('searchComplete'); + this.$element.off('searchCleared'); + }; + + Tree.prototype.subscribeEvents = function () { + + this.unsubscribeEvents(); + + this.$element.on('click', $.proxy(this.clickHandler, this)); + + if (typeof (this.options.onNodeChecked) === 'function') { + this.$element.on('nodeChecked', this.options.onNodeChecked); + } + + if (typeof (this.options.onNodeCollapsed) === 'function') { + this.$element.on('nodeCollapsed', this.options.onNodeCollapsed); + } + + if (typeof (this.options.onNodeDisabled) === 'function') { + this.$element.on('nodeDisabled', this.options.onNodeDisabled); + } + + if (typeof (this.options.onNodeEnabled) === 'function') { + this.$element.on('nodeEnabled', this.options.onNodeEnabled); + } + + if (typeof (this.options.onNodeExpanded) === 'function') { + this.$element.on('nodeExpanded', this.options.onNodeExpanded); + } + + if (typeof (this.options.onNodeSelected) === 'function') { + this.$element.on('nodeSelected', this.options.onNodeSelected); + } + + if (typeof (this.options.onNodeUnchecked) === 'function') { + this.$element.on('nodeUnchecked', this.options.onNodeUnchecked); + } + + if (typeof (this.options.onNodeUnselected) === 'function') { + this.$element.on('nodeUnselected', this.options.onNodeUnselected); + } + + if (typeof (this.options.onSearchComplete) === 'function') { + this.$element.on('searchComplete', this.options.onSearchComplete); + } + + if (typeof (this.options.onSearchCleared) === 'function') { + this.$element.on('searchCleared', this.options.onSearchCleared); + } + }; + + /* + Recurse the tree structure and ensure all nodes have + valid initial states. User defined states will be preserved. + For performance we also take this opportunity to + index nodes in a flattened structure + */ + Tree.prototype.setInitialStates = function (node, level) { + + if (!node.nodes) return; + level += 1; + + var parent = node; + var _this = this; + $.each(node.nodes, function checkStates(index, node) { + + // nodeId : unique, incremental identifier + node.nodeId = _this.nodes.length; + + // parentId : transversing up the tree + node.parentId = parent.nodeId; + + // if not provided set selectable default value + if (!node.hasOwnProperty('selectable')) { + node.selectable = true; + } + + // where provided we should preserve states + node.state = node.state || {}; + + // set checked state; unless set always false + if (!node.state.hasOwnProperty('checked')) { + node.state.checked = false; + } + + // set enabled state; unless set always false + if (!node.state.hasOwnProperty('disabled')) { + node.state.disabled = false; + } + + // set expanded state; if not provided based on levels + if (!node.state.hasOwnProperty('expanded')) { + if (!node.state.disabled && + (level < _this.options.levels) && + (node.nodes && node.nodes.length > 0)) { + node.state.expanded = true; + } + else { + node.state.expanded = false; + } + } + + // set selected state; unless set always false + if (!node.state.hasOwnProperty('selected')) { + node.state.selected = false; + } + + // index nodes in a flattened structure for use later + _this.nodes.push(node); + + // recurse child nodes and transverse the tree + if (node.nodes) { + _this.setInitialStates(node, level); + } + }); + }; + + Tree.prototype.clickHandler = function (event) { + + if (!this.options.enableLinks) event.preventDefault(); + + var target = $(event.target); + var node = this.findNode(target); + if (!node || node.state.disabled) return; + + var classList = target.attr('class') ? target.attr('class').split(' ') : []; + if ((classList.indexOf('expand-icon') !== -1)) { + + this.toggleExpandedState(node, _default.options); + this.render(); + } + else if ((classList.indexOf('check-icon') !== -1)) { + + this.toggleCheckedState(node, _default.options); + this.render(); + } + else { + + if (node.selectable) { + this.toggleSelectedState(node, _default.options); + } else { + this.toggleExpandedState(node, _default.options); + } + + this.render(); + } + }; + + // Looks up the DOM for the closest parent list item to retrieve the + // data attribute nodeid, which is used to lookup the node in the flattened structure. + Tree.prototype.findNode = function (target) { + + var nodeId = target.closest('li.list-group-item').attr('data-nodeid'); + var node = this.nodes[nodeId]; + + if (!node) { + console.log('Error: node does not exist'); + } + return node; + }; + + Tree.prototype.toggleExpandedState = function (node, options) { + if (!node) return; + this.setExpandedState(node, !node.state.expanded, options); + }; + + Tree.prototype.setExpandedState = function (node, state, options) { + + if (state === node.state.expanded) return; + + if (state && node.nodes) { + + // Expand a node + node.state.expanded = true; + if (!options.silent) { + this.$element.trigger('nodeExpanded', $.extend(true, {}, node)); + } + } + else if (!state) { + + // Collapse a node + node.state.expanded = false; + if (!options.silent) { + this.$element.trigger('nodeCollapsed', $.extend(true, {}, node)); + } + + // Collapse child nodes + if (node.nodes && !options.ignoreChildren) { + $.each(node.nodes, $.proxy(function (index, node) { + this.setExpandedState(node, false, options); + }, this)); + } + } + }; + + Tree.prototype.toggleSelectedState = function (node, options) { + if (!node) return; + this.setSelectedState(node, !node.state.selected, options); + }; + + Tree.prototype.setSelectedState = function (node, state, options) { + + if (state === node.state.selected) return; + + if (state) { + + // If multiSelect false, unselect previously selected + if (!this.options.multiSelect) { + $.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) { + this.setSelectedState(node, false, options); + }, this)); + } + + // Continue selecting node + node.state.selected = true; + if (!options.silent) { + this.$element.trigger('nodeSelected', $.extend(true, {}, node)); + } + } + else { + + // Unselect node + node.state.selected = false; + if (!options.silent) { + this.$element.trigger('nodeUnselected', $.extend(true, {}, node)); + } + } + }; + + Tree.prototype.toggleCheckedState = function (node, options) { + if (!node) return; + this.setCheckedState(node, !node.state.checked, options); + }; + + Tree.prototype.setCheckedState = function (node, state, options) { + + if (state === node.state.checked) return; + + if (state) { + + // Check node + node.state.checked = true; + + if (!options.silent) { + this.$element.trigger('nodeChecked', $.extend(true, {}, node)); + } + } + else { + + // Uncheck node + node.state.checked = false; + if (!options.silent) { + this.$element.trigger('nodeUnchecked', $.extend(true, {}, node)); + } + } + }; + + Tree.prototype.setDisabledState = function (node, state, options) { + + if (state === node.state.disabled) return; + + if (state) { + + // Disable node + node.state.disabled = true; + + // Disable all other states + this.setExpandedState(node, false, options); + this.setSelectedState(node, false, options); + this.setCheckedState(node, false, options); + + if (!options.silent) { + this.$element.trigger('nodeDisabled', $.extend(true, {}, node)); + } + } + else { + + // Enabled node + node.state.disabled = false; + if (!options.silent) { + this.$element.trigger('nodeEnabled', $.extend(true, {}, node)); + } + } + }; + + Tree.prototype.render = function () { + + if (!this.initialized) { + + // Setup first time only components + this.$element.addClass(pluginName); + this.$wrapper = $(this.template.list); + + this.injectStyle(); + + this.initialized = true; + } + + this.$element.empty().append(this.$wrapper.empty()); + + // Build tree + this.buildTree(this.tree, 0); + }; + + // Starting from the root node, and recursing down the + // structure we build the tree one node at a time + Tree.prototype.buildTree = function (nodes, level) { + + if (!nodes) return; + level += 1; + + var _this = this; + $.each(nodes, function addNodes(id, node) { + + var treeItem = $(_this.template.item) + .addClass('node-' + _this.elementId) + .addClass(node.state.checked ? 'node-checked' : '') + .addClass(node.state.disabled ? 'node-disabled': '') + .addClass(node.state.selected ? 'node-selected' : '') + .addClass(node.searchResult ? 'search-result' : '') + .attr('data-nodeid', node.nodeId) + .attr('style', _this.buildStyleOverride(node)); + + // Add indent/spacer to mimic tree structure + for (var i = 0; i < (level - 1); i++) { + treeItem.append(_this.template.indent); + } + + // Add expand, collapse or empty spacer icons + var classList = []; + if (node.nodes) { + classList.push('expand-icon'); + if (node.state.expanded) { + classList.push(_this.options.collapseIcon); + } + else { + classList.push(_this.options.expandIcon); + } + } + else { + classList.push(_this.options.emptyIcon); + } + + treeItem + .append($(_this.template.icon) + .addClass(classList.join(' ')) + ); + + + // Add node icon + if (_this.options.showIcon) { + + var classList = ['node-icon']; + + classList.push(node.icon || _this.options.nodeIcon); + if (node.state.selected) { + classList.pop(); + classList.push(node.selectedIcon || _this.options.selectedIcon || + node.icon || _this.options.nodeIcon); + } + + treeItem + .append($(_this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add check / unchecked icon + if (_this.options.showCheckbox) { + + var classList = ['check-icon']; + if (node.state.checked) { + classList.push(_this.options.checkedIcon); + } + else { + classList.push(_this.options.uncheckedIcon); + } + + treeItem + .append($(_this.template.icon) + .addClass(classList.join(' ')) + ); + } + + // Add text + if (_this.options.enableLinks) { + // Add hyperlink + treeItem + .append($(_this.template.link) + .attr('href', node.href) + .append(node.text) + ); + } + else { + // otherwise just text + treeItem + .append(node.text); + } + + // Add tags as badges + if (_this.options.showTags && node.tags) { + $.each(node.tags, function addTag(id, tag) { + treeItem + .append($(_this.template.badge) + .append(tag) + ); + }); + } + + // Add item to the tree + _this.$wrapper.append(treeItem); + + // Recursively add child ndoes + if (node.nodes && node.state.expanded && !node.state.disabled) { + return _this.buildTree(node.nodes, level); + } + }); + }; + + // Define any node level style override for + // 1. selectedNode + // 2. node|data assigned color overrides + Tree.prototype.buildStyleOverride = function (node) { + + if (node.state.disabled) return ''; + + var color = node.color; + var backColor = node.backColor; + + if (this.options.highlightSelected && node.state.selected) { + if (this.options.selectedColor) { + color = this.options.selectedColor; + } + if (this.options.selectedBackColor) { + backColor = this.options.selectedBackColor; + } + } + + if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) { + if (this.options.searchResultColor) { + color = this.options.searchResultColor; + } + if (this.options.searchResultBackColor) { + backColor = this.options.searchResultBackColor; + } + } + + return 'color:' + color + + ';background-color:' + backColor + ';'; + }; + + // Add inline style into head + Tree.prototype.injectStyle = function () { + + if (this.options.injectStyle && !document.getElementById(this.styleId)) { + $('').appendTo('head'); + } + }; + + // Construct trees style based on user options + Tree.prototype.buildStyle = function () { + + var style = '.node-' + this.elementId + '{'; + + if (this.options.color) { + style += 'color:' + this.options.color + ';'; + } + + if (this.options.backColor) { + style += 'background-color:' + this.options.backColor + ';'; + } + + if (!this.options.showBorder) { + style += 'border:none;'; + } + else if (this.options.borderColor) { + style += 'border:1px solid ' + this.options.borderColor + ';'; + } + style += '}'; + + if (this.options.onhoverColor) { + style += '.node-' + this.elementId + ':not(.node-disabled):hover{' + + 'background-color:' + this.options.onhoverColor + ';' + + '}'; + } + + return this.css + style; + }; + + Tree.prototype.template = { + list: '
              ', + item: '
            • ', + indent: '', + icon: '', + link: '
              ', + badge: '' + }; + + Tree.prototype.css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}' + + + /** + Returns a single node object that matches the given node id. + @param {Number} nodeId - A node's unique identifier + @return {Object} node - Matching node + */ + Tree.prototype.getNode = function (nodeId) { + return this.nodes[nodeId]; + }; + + /** + Returns the parent node of a given node, if valid otherwise returns undefined. + @param {Object|Number} identifier - A valid node or node id + @returns {Object} node - The parent node + */ + Tree.prototype.getParent = function (identifier) { + var node = this.identifyNode(identifier); + return this.nodes[node.parentId]; + }; + + /** + Returns an array of sibling nodes for a given node, if valid otherwise returns undefined. + @param {Object|Number} identifier - A valid node or node id + @returns {Array} nodes - Sibling nodes + */ + Tree.prototype.getSiblings = function (identifier) { + var node = this.identifyNode(identifier); + var parent = this.getParent(node); + var nodes = parent ? parent.nodes : this.tree; + return nodes.filter(function (obj) { + return obj.nodeId !== node.nodeId; + }); + }; + + /** + Returns an array of selected nodes. + @returns {Array} nodes - Selected nodes + */ + Tree.prototype.getSelected = function () { + return this.findNodes('true', 'g', 'state.selected'); + }; + + /** + Returns an array of unselected nodes. + @returns {Array} nodes - Unselected nodes + */ + Tree.prototype.getUnselected = function () { + return this.findNodes('false', 'g', 'state.selected'); + }; + + /** + Returns an array of expanded nodes. + @returns {Array} nodes - Expanded nodes + */ + Tree.prototype.getExpanded = function () { + return this.findNodes('true', 'g', 'state.expanded'); + }; + + /** + Returns an array of collapsed nodes. + @returns {Array} nodes - Collapsed nodes + */ + Tree.prototype.getCollapsed = function () { + return this.findNodes('false', 'g', 'state.expanded'); + }; + + /** + Returns an array of checked nodes. + @returns {Array} nodes - Checked nodes + */ + Tree.prototype.getChecked = function () { + return this.findNodes('true', 'g', 'state.checked'); + }; + + /** + Returns an array of unchecked nodes. + @returns {Array} nodes - Unchecked nodes + */ + Tree.prototype.getUnchecked = function () { + return this.findNodes('false', 'g', 'state.checked'); + }; + + /** + Returns an array of disabled nodes. + @returns {Array} nodes - Disabled nodes + */ + Tree.prototype.getDisabled = function () { + return this.findNodes('true', 'g', 'state.disabled'); + }; + + /** + Returns an array of enabled nodes. + @returns {Array} nodes - Enabled nodes + */ + Tree.prototype.getEnabled = function () { + return this.findNodes('false', 'g', 'state.disabled'); + }; + + + /** + Set a node state to selected + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.selectNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setSelectedState(node, true, options); + }, this)); + + this.render(); + }; + + /** + Set a node state to unselected + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.unselectNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setSelectedState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Toggles a node selected state; selecting if unselected, unselecting if selected. + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.toggleNodeSelected = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.toggleSelectedState(node, options); + }, this)); + + this.render(); + }; + + + /** + Collapse all tree nodes + @param {optional Object} options + */ + Tree.prototype.collapseAll = function (options) { + var identifiers = this.findNodes('true', 'g', 'state.expanded'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setExpandedState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Collapse a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.collapseNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setExpandedState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Expand all tree nodes + @param {optional Object} options + */ + Tree.prototype.expandAll = function (options) { + options = $.extend({}, _default.options, options); + + if (options && options.levels) { + this.expandLevels(this.tree, options.levels, options); + } + else { + var identifiers = this.findNodes('false', 'g', 'state.expanded'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setExpandedState(node, true, options); + }, this)); + } + + this.render(); + }; + + /** + Expand a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.expandNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setExpandedState(node, true, options); + if (node.nodes && (options && options.levels)) { + this.expandLevels(node.nodes, options.levels-1, options); + } + }, this)); + + this.render(); + }; + + Tree.prototype.expandLevels = function (nodes, level, options) { + options = $.extend({}, _default.options, options); + + $.each(nodes, $.proxy(function (index, node) { + this.setExpandedState(node, (level > 0) ? true : false, options); + if (node.nodes) { + this.expandLevels(node.nodes, level-1, options); + } + }, this)); + }; + + /** + Reveals a given tree node, expanding the tree from node to root. + @param {Object|Number|Array} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.revealNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + var parentNode = this.getParent(node); + while (parentNode) { + this.setExpandedState(parentNode, true, options); + parentNode = this.getParent(parentNode); + }; + }, this)); + + this.render(); + }; + + /** + Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed. + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.toggleNodeExpanded = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.toggleExpandedState(node, options); + }, this)); + + this.render(); + }; + + + /** + Check all tree nodes + @param {optional Object} options + */ + Tree.prototype.checkAll = function (options) { + var identifiers = this.findNodes('false', 'g', 'state.checked'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setCheckedState(node, true, options); + }, this)); + + this.render(); + }; + + /** + Check a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.checkNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setCheckedState(node, true, options); + }, this)); + + this.render(); + }; + + /** + Uncheck all tree nodes + @param {optional Object} options + */ + Tree.prototype.uncheckAll = function (options) { + var identifiers = this.findNodes('true', 'g', 'state.checked'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setCheckedState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Uncheck a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.uncheckNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setCheckedState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Toggles a nodes checked state; checking if unchecked, unchecking if checked. + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.toggleNodeChecked = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.toggleCheckedState(node, options); + }, this)); + + this.render(); + }; + + + /** + Disable all tree nodes + @param {optional Object} options + */ + Tree.prototype.disableAll = function (options) { + var identifiers = this.findNodes('false', 'g', 'state.disabled'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setDisabledState(node, true, options); + }, this)); + + this.render(); + }; + + /** + Disable a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.disableNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setDisabledState(node, true, options); + }, this)); + + this.render(); + }; + + /** + Enable all tree nodes + @param {optional Object} options + */ + Tree.prototype.enableAll = function (options) { + var identifiers = this.findNodes('true', 'g', 'state.disabled'); + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setDisabledState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Enable a given tree node + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.enableNode = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setDisabledState(node, false, options); + }, this)); + + this.render(); + }; + + /** + Toggles a nodes disabled state; disabling is enabled, enabling if disabled. + @param {Object|Number} identifiers - A valid node, node id or array of node identifiers + @param {optional Object} options + */ + Tree.prototype.toggleNodeDisabled = function (identifiers, options) { + this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) { + this.setDisabledState(node, !node.state.disabled, options); + }, this)); + + this.render(); + }; + + + /** + Common code for processing multiple identifiers + */ + Tree.prototype.forEachIdentifier = function (identifiers, options, callback) { + + options = $.extend({}, _default.options, options); + + if (!(identifiers instanceof Array)) { + identifiers = [identifiers]; + } + + $.each(identifiers, $.proxy(function (index, identifier) { + callback(this.identifyNode(identifier), options); + }, this)); + }; + + /* + Identifies a node from either a node id or object + */ + Tree.prototype.identifyNode = function (identifier) { + return ((typeof identifier) === 'number') ? + this.nodes[identifier] : + identifier; + }; + + /** + Searches the tree for nodes (text) that match given criteria + @param {String} pattern - A given string to match against + @param {optional Object} options - Search criteria options + @return {Array} nodes - Matching nodes + */ + Tree.prototype.search = function (pattern, options) { + options = $.extend({}, _default.searchOptions, options); + + this.clearSearch({ render: false }); + + var results = []; + if (pattern && pattern.length > 0) { + + if (options.exactMatch) { + pattern = '^' + pattern + '$'; + } + + var modifier = 'g'; + if (options.ignoreCase) { + modifier += 'i'; + } + + results = this.findNodes(pattern, modifier); + + // Add searchResult property to all matching nodes + // This will be used to apply custom styles + // and when identifying result to be cleared + $.each(results, function (index, node) { + node.searchResult = true; + }) + } + + // If revealResults, then render is triggered from revealNode + // otherwise we just call render. + if (options.revealResults) { + this.revealNode(results); + } + else { + this.render(); + } + + this.$element.trigger('searchComplete', $.extend(true, {}, results)); + + return results; + }; + + /** + Clears previous search results + */ + Tree.prototype.clearSearch = function (options) { + + options = $.extend({}, { render: true }, options); + + var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) { + node.searchResult = false; + }); + + if (options.render) { + this.render(); + } + + this.$element.trigger('searchCleared', $.extend(true, {}, results)); + }; + + /** + Find nodes that match a given criteria + @param {String} pattern - A given string to match against + @param {optional String} modifier - Valid RegEx modifiers + @param {optional String} attribute - Attribute to compare pattern against + @return {Array} nodes - Nodes that match your criteria + */ + Tree.prototype.findNodes = function (pattern, modifier, attribute) { + + modifier = modifier || 'g'; + attribute = attribute || 'text'; + + var _this = this; + return $.grep(this.nodes, function (node) { + var val = _this.getNodeValue(node, attribute); + if (typeof val === 'string') { + return val.match(new RegExp(pattern, modifier)); + } + }); + }; + + /** + Recursive find for retrieving nested attributes values + All values are return as strings, unless invalid + @param {Object} obj - Typically a node, could be any object + @param {String} attr - Identifies an object property using dot notation + @return {String} value - Matching attributes string representation + */ + Tree.prototype.getNodeValue = function (obj, attr) { + var index = attr.indexOf('.'); + if (index > 0) { + var _obj = obj[attr.substring(0, index)]; + var _attr = attr.substring(index + 1, attr.length); + return this.getNodeValue(_obj, _attr); + } + else { + if (obj.hasOwnProperty(attr)) { + return obj[attr].toString(); + } + else { + return undefined; + } + } + }; + + var logError = function (message) { + if (window.console) { + window.console.error(message); + } + }; + + // Prevent against multiple instantiations, + // handle updates and method calls + $.fn[pluginName] = function (options, args) { + + var result; + + this.each(function () { + var _this = $.data(this, pluginName); + if (typeof options === 'string') { + if (!_this) { + logError('Not initialized, can not call method : ' + options); + } + else if (!$.isFunction(_this[options]) || options.charAt(0) === '_') { + logError('No such method : ' + options); + } + else { + if (!(args instanceof Array)) { + args = [ args ]; + } + result = _this[options].apply(_this, args); + } + } + else if (typeof options === 'boolean') { + result = _this; + } + else { + $.data(this, pluginName, new Tree(this, $.extend(true, {}, options))); + } + }); + + return result || this; + }; + +})(jQuery, window, document); diff --git a/backend/webif/static/js/bootstrap-treeview.min.js b/backend/webif/static/js/bootstrap-treeview.min.js new file mode 100755 index 000000000..9e2803815 --- /dev/null +++ b/backend/webif/static/js/bootstrap-treeview.min.js @@ -0,0 +1 @@ +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c0?b.state.expanded=!0:b.state.expanded=!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this.render()):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):(d.selectable?this.toggleSelectedState(d,f.options):this.toggleExpandedState(d,f.options),this.render())}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){this.initialized||(this.$element.addClass(e),this.$wrapper=a(this.template.list),this.injectStyle(),this.initialized=!0),this.$element.empty().append(this.$wrapper.empty()),this.buildTree(this.tree,0)},g.prototype.buildTree=function(b,c){if(b){c+=1;var d=this;a.each(b,function(b,e){for(var f=a(d.template.item).addClass("node-"+d.elementId).addClass(e.state.checked?"node-checked":"").addClass(e.state.disabled?"node-disabled":"").addClass(e.state.selected?"node-selected":"").addClass(e.searchResult?"search-result":"").attr("data-nodeid",e.nodeId).attr("style",d.buildStyleOverride(e)),g=0;c-1>g;g++)f.append(d.template.indent);var h=[];if(e.nodes?(h.push("expand-icon"),h.push(e.state.expanded?d.options.collapseIcon:d.options.expandIcon)):h.push(d.options.emptyIcon),f.append(a(d.template.icon).addClass(h.join(" "))),d.options.showIcon){var h=["node-icon"];h.push(e.icon||d.options.nodeIcon),e.state.selected&&(h.pop(),h.push(e.selectedIcon||d.options.selectedIcon||e.icon||d.options.nodeIcon)),f.append(a(d.template.icon).addClass(h.join(" ")))}if(d.options.showCheckbox){var h=["check-icon"];h.push(e.state.checked?d.options.checkedIcon:d.options.uncheckedIcon),f.append(a(d.template.icon).addClass(h.join(" ")))}return f.append(d.options.enableLinks?a(d.template.link).attr("href",e.href).append(e.text):e.text),d.options.showTags&&e.tags&&a.each(e.tags,function(b,c){f.append(a(d.template.badge).append(c))}),d.$wrapper.append(f),e.nodes&&e.state.expanded&&!e.state.disabled?d.buildTree(e.nodes,c):void 0})}},g.prototype.buildStyleOverride=function(a){if(a.state.disabled)return"";var b=a.color,c=a.backColor;return this.options.highlightSelected&&a.state.selected&&(this.options.selectedColor&&(b=this.options.selectedColor),this.options.selectedBackColor&&(c=this.options.selectedBackColor)),this.options.highlightSearchResults&&a.searchResult&&!a.state.disabled&&(this.options.searchResultColor&&(b=this.options.searchResultColor),this.options.searchResultBackColor&&(c=this.options.searchResultBackColor)),"color:"+b+";background-color:"+c+";"},g.prototype.injectStyle=function(){this.options.injectStyle&&!c.getElementById(this.styleId)&&a('").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={list:'
                ',item:'
              • ',indent:'',icon:'',link:'',badge:''},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){var c=this.findNodes("true","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.expandAll=function(b){if(b=a.extend({},f.options,b),b&&b.levels)this.expandLevels(this.tree,b.levels,b);else{var c=this.findNodes("false","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!0,b)},this))}this.render()},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&b&&b.levels&&this.expandLevels(a.nodes,b.levels-1,b)},this)),this.render()},g.prototype.expandLevels=function(b,c,d){d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this.expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c=this.getParent(a);c;)this.setExpandedState(c,!0,b),c=this.getParent(c)},this)),this.render()},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b)},this)),this.render()},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document); \ No newline at end of file diff --git a/backend/webif/static/js/bootstrap.js b/backend/webif/static/js/bootstrap.js new file mode 100755 index 000000000..8a2e99a53 --- /dev/null +++ b/backend/webif/static/js/bootstrap.js @@ -0,0 +1,2377 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.7 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.7' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.7 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.7' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.7 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.7' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.7 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.7' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/backend/webif/static/js/bootstrap.min.js b/backend/webif/static/js/bootstrap.min.js new file mode 100755 index 000000000..9bcd2fcca --- /dev/null +++ b/backend/webif/static/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
                ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/LICENSE.txt b/backend/webif/static/js/fontawesome/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/README.md b/backend/webif/static/js/fontawesome/README.md new file mode 100644 index 000000000..f3c04252e --- /dev/null +++ b/backend/webif/static/js/fontawesome/README.md @@ -0,0 +1,7 @@ +# Font Awesome 5.0.1 + +Thanks for downloading Font Awesome! We're so excited you're here. + +Our documentation is available online. Just head here: + +https://fontawesome.com diff --git a/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.json b/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.json new file mode 100644 index 000000000..6efb4ff63 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.json @@ -0,0 +1,26643 @@ +{ + "500px": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f26e", + "label": "500px", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z" + } + } + }, + "accessible-icon": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "accessibility", + "wheelchair", + "handicap", + "person", + "wheelchair-alt" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f368", + "label": "Accessible Icon", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z" + } + } + }, + "accusoft": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f369", + "label": "Accusoft", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8" + } + } + }, + "address-book": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2b9", + "label": "Address Book", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H80C53.49 0 32 21.49 32 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zM224 96c53.019 0 96 42.981 96 96s-42.981 96-96 96-96-42.981-96-96 42.981-96 96-96zm128 304c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48v-48.711c0-20.994 13.644-39.553 33.683-45.815l22.954-7.173C173.563 312.413 198.198 320 224 320s50.437-7.587 71.363-21.699l22.954 7.173C338.356 311.736 352 330.295 352 351.289V400z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M320 320v72c0 13.255-10.745 24-24 24H152c-13.255 0-24-10.745-24-24v-72c0-21.431 14.207-40.266 34.813-46.153l18.064-5.161C193.629 275.884 208.342 280 224 280s30.371-4.116 43.122-11.314l18.064 5.161C305.793 279.734 320 298.569 320 320zm-96-64c35.346 0 64-28.654 64-64s-28.654-64-64-64-64 28.654-64 64 28.654 64 64 64zm192-96v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v48c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V48C32 21.49 53.49 0 80 0h288c26.51 0 48 21.49 48 48v48h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20zm-48 298V54a6 6 0 0 0-6-6H86a6 6 0 0 0-6 6v404a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6z" + } + } + }, + "address-card": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2bb", + "label": "Address Card", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-288 64c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm112 232c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-29.897a24 24 0 0 1 17.407-23.077l28.938-8.268C129.323 312.549 152.087 320 176 320s46.677-7.451 65.656-21.241l28.938 8.268A23.999 23.999 0 0 1 288 330.103V360zm160-52c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zm-54-176H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm0 80H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm-284-96c0-30.928 25.072-56 56-56s56 25.072 56 56-25.072 56-56 56-56-25.072-56-56zm136 89.857V340c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12v-42.143a24 24 0 0 1 17.104-22.988l13.464-4.039C140.186 281.568 157.351 288 176 288s35.814-6.432 49.433-17.17l13.464 4.039A24 24 0 0 1 256 297.857z" + } + } + }, + "adjust": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "contrast" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f042", + "label": "adjust", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z" + } + } + }, + "adn": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f170", + "label": "App.net", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z" + } + } + }, + "adversal": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36a", + "label": "Adversal", + "sponsored": { + "label": "Adversal", + "url": "https://www.adversal.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z" + } + } + }, + "affiliatetheme": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36b", + "label": "affiliatetheme", + "sponsored": { + "label": "affiliatetheme", + "url": "https://affiliatetheme.io/en" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z" + } + } + }, + "algolia": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36c", + "label": "Algolia", + "sponsored": { + "label": "Algolia", + "url": "http://www.algolia.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z" + } + } + }, + "align-center": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "middle", + "text" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f037", + "label": "align-center", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M352 44v40c0 8.837-7.163 16-16 16H112c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h224c8.837 0 16 7.163 16 16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm320-200H112c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z" + } + } + }, + "align-justify": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "text" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f039", + "label": "align-justify", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm16 144h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0-128h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" + } + } + }, + "align-left": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "text" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f036", + "label": "align-left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M288 44v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16zM0 172v40c0 8.837 7.163 16 16 16h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16zm16 312h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm256-200H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z" + } + } + }, + "align-right": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "text" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f038", + "label": "align-right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M160 84V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H176c-8.837 0-16-7.163-16-16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" + } + } + }, + "amazon": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f270", + "label": "Amazon", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z" + } + } + }, + "ambulance": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle", + "support", + "help" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0f9", + "label": "ambulance", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm32-288v32c0 6.627-5.373 12-12 12h-56v56c0 6.627-5.373 12-12 12h-32c-6.627 0-12-5.373-12-12v-56h-56c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h56v-56c0-6.627 5.373-12 12-12h32c6.627 0 12 5.373 12 12v56h56c6.627 0 12 5.373 12 12z" + } + } + }, + "american-sign-language-interpreting": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a3", + "label": "American Sign Language Interpreting", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z" + } + } + }, + "amilia": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36d", + "label": "Amilia", + "sponsored": { + "label": "Amilia", + "url": "http://www.amilia.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7" + } + } + }, + "anchor": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "link" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f13d", + "label": "Anchor", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z" + } + } + }, + "android": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "robot" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f17b", + "label": "Android", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z" + } + } + }, + "angellist": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f209", + "label": "AngelList", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z" + } + } + }, + "angle-double-down": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrows" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f103", + "label": "Angle Double Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z" + } + } + }, + "angle-double-left": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "laquo", + "quote", + "previous", + "back", + "arrows" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f100", + "label": "Angle Double Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z" + } + } + }, + "angle-double-right": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "raquo", + "quote", + "next", + "forward", + "arrows" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f101", + "label": "Angle Double Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z" + } + } + }, + "angle-double-up": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrows" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f102", + "label": "Angle Double Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z" + } + } + }, + "angle-down": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f107", + "label": "angle-down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z" + } + } + }, + "angle-left": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f104", + "label": "angle-left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z" + } + } + }, + "angle-right": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f105", + "label": "angle-right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z" + } + } + }, + "angle-up": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f106", + "label": "angle-up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z" + } + } + }, + "angrycreative": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36e", + "label": "Angry Creative", + "sponsored": { + "label": "Angry Creative", + "url": "https://angrycreative.se" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z" + } + } + }, + "angular": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f420", + "label": "Angular", + "svg": { + "brands": { + "last_modified": 1511207633238, + "raw": "", + "viewBox": [ + "0", + "0", + "415.6", + "512" + ], + "width": 415, + "height": 512, + "path": "M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z" + } + } + }, + "app-store": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f36f", + "label": "App Store", + "svg": { + "brands": { + "last_modified": 1508771132269, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z" + } + } + }, + "app-store-ios": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f370", + "label": "iOS App Store", + "svg": { + "brands": { + "last_modified": 1508771132269, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z" + } + } + }, + "apper": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f371", + "label": "Apper Systems AB", + "sponsored": { + "label": "Apper Systems AB", + "url": "http://www.apper.com/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z" + } + } + }, + "apple": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "osx", + "food" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f179", + "label": "Apple", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z" + } + } + }, + "apple-pay": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f415", + "label": "Apple Pay", + "svg": { + "brands": { + "last_modified": 1508771132269, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z" + } + } + }, + "archive": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "box", + "storage" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f187", + "label": "Archive", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488 128H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h464c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24zm-8 328V184c0-13.255-10.745-24-24-24H56c-13.255 0-24 10.745-24 24v272c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24zM308 256H204c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12z" + } + } + }, + "arrow-alt-circle-down": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "download", + "arrow-circle-o-down" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f358", + "label": "Alternate Arrow Circle Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z" + } + } + }, + "arrow-alt-circle-left": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "arrow-circle-o-left" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f359", + "label": "Alternate Arrow Circle Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z" + } + } + }, + "arrow-alt-circle-right": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward", + "arrow-circle-o-right" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f35a", + "label": "Alternate Arrow Circle Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z" + } + } + }, + "arrow-alt-circle-up": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow-circle-o-up" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f35b", + "label": "Alternate Arrow Circle Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z" + } + } + }, + "arrow-circle-down": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "download" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ab", + "label": "Arrow Circle Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z" + } + } + }, + "arrow-circle-left": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0a8", + "label": "Arrow Circle Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z" + } + } + }, + "arrow-circle-right": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0a9", + "label": "Arrow Circle Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z" + } + } + }, + "arrow-circle-up": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f0aa", + "label": "Arrow Circle Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z" + } + } + }, + "arrow-down": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "download" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f063", + "label": "arrow-down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z" + } + } + }, + "arrow-left": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f060", + "label": "arrow-left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z" + } + } + }, + "arrow-right": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f061", + "label": "arrow-right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z" + } + } + }, + "arrow-up": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f062", + "label": "arrow-up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z" + } + } + }, + "arrows-alt": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "expand", + "enlarge", + "fullscreen", + "bigger", + "move", + "reorder", + "resize", + "arrow", + "arrows" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0b2", + "label": "Alternate Arrows", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z" + } + } + }, + "arrows-alt-h": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "resize", + "arrows-h" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f337", + "label": "Alternate Arrows Horizontal", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z" + } + } + }, + "arrows-alt-v": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "resize", + "arrows-v" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f338", + "label": "Alternate Arrows Vertical", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z" + } + } + }, + "assistive-listening-systems": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a2", + "label": "Assistive Listening Systems", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z" + } + } + }, + "asterisk": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "details" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f069", + "label": "asterisk", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z" + } + } + }, + "asymmetrik": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f372", + "label": "Asymmetrik, Ltd.", + "sponsored": { + "label": "Asymmetrik, Ltd.", + "url": "http://asymmetrik.com/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z" + } + } + }, + "at": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "email", + "e-mail" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1fa", + "label": "At", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z" + } + } + }, + "audible": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f373", + "label": "Audible", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z" + } + } + }, + "audio-description": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f29e", + "label": "Audio Description", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z" + } + } + }, + "autoprefixer": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41c", + "label": "Autoprefixer", + "svg": { + "brands": { + "last_modified": 1508771132269, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z" + } + } + }, + "avianex": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f374", + "label": "avianex", + "sponsored": { + "label": "avianex", + "url": "https://www.avianex.de" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z" + } + } + }, + "aviato": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f421", + "label": "Aviato", + "svg": { + "brands": { + "last_modified": 1510848563149, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z" + } + } + }, + "aws": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f375", + "label": "Amazon Web Services (AWS)", + "svg": { + "brands": { + "last_modified": 1508771132270, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z" + } + } + }, + "backward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "rewind", + "previous" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f04a", + "label": "backward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z" + } + } + }, + "balance-scale": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f24e", + "label": "Balance Scale", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M352 448h168c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H120c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h168V153.324C264.469 143.04 246.836 121.778 241.603 96H120c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h135.999C270.594 12.57 293.828 0 320 0s49.406 12.57 64.001 32H520c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H398.397c-5.233 25.778-22.866 47.04-46.397 57.324V448zm287.981-112c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C381.94 328.75 384.019 320.331 384.019 336H384c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM512 176l72 144H440l72-144zM255.981 336c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C-2.06 328.75.019 320.331.019 336H0c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM128 176l72 144H56l72-144z" + } + } + }, + "ban": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "delete", + "remove", + "trash", + "hide", + "block", + "stop", + "abort", + "cancel" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f05e", + "label": "ban", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z" + } + } + }, + "bandcamp": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2d5", + "label": "Bandcamp", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z" + } + } + }, + "barcode": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "scan" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f02a", + "label": "barcode", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z" + } + } + }, + "bars": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "menu", + "drag", + "reorder", + "settings", + "list", + "ul", + "ol", + "checklist", + "todo", + "list", + "hamburger" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c9", + "label": "Bars", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" + } + } + }, + "bath": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2cd", + "label": "Bath", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z" + } + } + }, + "battery-empty": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f244", + "label": "Battery Empty", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z" + } + } + }, + "battery-full": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f240", + "label": "Battery Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z" + } + } + }, + "battery-half": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f242", + "label": "Battery 1/2 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z" + } + } + }, + "battery-quarter": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f243", + "label": "Battery 1/4 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z" + } + } + }, + "battery-three-quarters": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f241", + "label": "Battery 3/4 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z" + } + } + }, + "bed": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "travel" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f236", + "label": "Bed", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M552 288c13.255 0 24 10.745 24 24v136h-96v-64H96v64H0V88c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v200h456zM192 96c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80zm384 128c0-53.019-42.981-96-96-96H312c-13.255 0-24 10.745-24 24v104h288v-32z" + } + } + }, + "beer": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "alcohol", + "stein", + "drink", + "mug", + "bar", + "liquor" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0fc", + "label": "beer", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z" + } + } + }, + "behance": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1b4", + "label": "Behance", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z" + } + } + }, + "behance-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1b5", + "label": "Behance Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z" + } + } + }, + "bell": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "alert", + "reminder", + "notification" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0f3", + "label": "bell", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M433.884 366.059C411.634 343.809 384 316.118 384 208c0-79.394-57.831-145.269-133.663-157.83A31.845 31.845 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 6.75 2.095 13.008 5.663 18.17C121.831 62.731 64 128.606 64 208c0 108.118-27.643 135.809-49.893 158.059C-16.042 396.208 5.325 448 48.048 448H160c0 35.346 28.654 64 64 64s64-28.654 64-64h111.943c42.638 0 64.151-51.731 33.941-81.941zM224 472a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16c0 13.234 10.766 24 24 24z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M425.403 330.939c-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.843 31.843 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095C118.101 62.783 57.143 131.831 57.143 214.857c0 81.933-17.551 99.292-34.543 116.078C-25.496 378.441 9.726 448 66.919 448H160c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h93.08c57.19 0 92.415-69.583 44.323-117.061zM224 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm157.092-72H66.9c-16.762 0-25.135-20.39-13.334-32.191 28.585-28.585 51.577-55.724 51.577-152.952C105.143 149.319 158.462 96 224 96s118.857 53.319 118.857 118.857c0 97.65 23.221 124.574 51.568 152.952C406.278 379.661 397.783 400 381.092 400z" + } + } + }, + "bell-slash": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1f6", + "label": "Bell Slash", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M78.107 366.059C47.958 396.208 69.325 448 112.048 448H224c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h32.685L127.848 221.379c-2.198 97.078-28.439 123.378-49.741 144.68zM264 448c0 13.234 10.766 24 24 24a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16zm305.896 43.733l-10.762 12.086c-8.915 10.012-24.333 10.967-34.437 2.133L8.256 54.393C-1.848 45.558-2.811 30.28 6.104 20.267L16.865 8.181C25.781-1.831 41.199-2.786 51.303 6.049l113.81 99.512c24.017-28.778 57.946-48.996 96.55-55.39A31.85 31.85 0 0 1 256 32c0-17.673 14.327-32 32-32s32 14.327 32 32c0 6.75-2.095 13.008-5.663 18.17C390.169 62.731 448 128.606 448 208c0 108.118 27.634 135.809 49.884 158.059 12.149 12.149 15.923 27.776 13.33 42.121l56.53 49.427c10.104 8.835 11.067 24.113 2.152 34.126z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M130.9 400c-16.762 0-25.135-20.39-13.334-32.191 25.226-25.226 46.094-49.338 50.649-121.48l-46.777-41.274a168.48 168.48 0 0 0-.296 9.802c0 81.933-17.551 99.292-34.543 116.078C38.504 378.441 73.726 448 130.919 448H224c0 35.346 28.654 64 64 64s64-28.654 64-64h44.777l-54.4-48H130.9zM288 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm283.867.553l-67.931-59.571c13.104-24.118 11.524-56.318-14.532-82.042-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.848 31.848 0 0 0 320 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095c-41.471 6.618-77.891 28.571-103.249 59.841L36.459 3.037c-5.058-4.436-12.777-3.956-17.24 1.071L3.056 22.313C-1.407 27.34-.925 35.012 4.134 39.447l535.408 469.516c5.058 4.436 12.777 3.956 17.24-1.071l16.163-18.205c4.462-5.027 3.98-12.699-1.078-17.134zM288 96c65.538 0 118.857 53.319 118.857 118.857 0 97.65 23.221 124.574 51.568 152.952 2.908 2.908 4.573 6.328 5.209 9.832L194.482 141.612C216.258 113.867 250.075 96 288 96z" + } + } + }, + "bicycle": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle", + "bike" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f206", + "label": "Bicycle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z" + } + } + }, + "bimobject": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f378", + "label": "BIMobject", + "sponsored": { + "label": "BIMobject", + "url": "http://bimobject.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z" + } + } + }, + "binoculars": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1e5", + "label": "Binoculars", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M192 104H96V56c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v48zm224-48c0-13.255-10.745-24-24-24h-48c-13.255 0-24 10.745-24 24v48h96V56zM0 456c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H0v16zm88-328c-13.255 0-24 10.745-24 24C64 256 0 272 0 416h168V312c0-13.255 10.745-24 24-24V128H88zm256 328c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H344v16zM216 128v160h80V128h-80zm128 288h168c0-144-64-160-64-264 0-13.255-10.745-24-24-24H320v160c13.255 0 24 10.745 24 24v104z" + } + } + }, + "birthday-cake": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1fd", + "label": "Birthday Cake", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z" + } + } + }, + "bitbucket": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "git", + "bitbucket-square" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f171", + "label": "Bitbucket", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z" + } + } + }, + "bitcoin": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f379", + "label": "Bitcoin", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z" + } + } + }, + "bity": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f37a", + "label": "Bity", + "sponsored": { + "label": "Bity", + "url": "http://bity.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z" + } + } + }, + "black-tie": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f27e", + "label": "Font Awesome Black Tie", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z" + } + } + }, + "blackberry": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f37b", + "label": "BlackBerry", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z" + } + } + }, + "blind": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f29d", + "label": "Blind", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z" + } + } + }, + "blogger": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f37c", + "label": "Blogger", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z" + } + } + }, + "blogger-b": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f37d", + "label": "Blogger B", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z" + } + } + }, + "bluetooth": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f293", + "label": "Bluetooth", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z" + } + } + }, + "bluetooth-b": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f294", + "label": "Bluetooth", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z" + } + } + }, + "bold": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f032", + "label": "bold", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z" + } + } + }, + "bolt": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "lightning", + "weather" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0e7", + "label": "Lightning Bolt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M295.973 160H180.572L215.19 30.184C219.25 14.956 207.756 0 192 0H56C43.971 0 33.8 8.905 32.211 20.828l-31.996 240C-1.704 275.217 9.504 288 24.004 288h118.701L96.646 482.466C93.05 497.649 104.659 512 119.992 512c8.35 0 16.376-4.374 20.778-11.978l175.973-303.997c9.244-15.967-2.288-36.025-20.77-36.025z" + } + } + }, + "bomb": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1e2", + "label": "Bomb", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z" + } + } + }, + "book": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "read", + "documentation" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f02d", + "label": "book", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z" + } + } + }, + "bookmark": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "save" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f02e", + "label": "bookmark", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z" + } + } + }, + "braille": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a1", + "label": "Braille", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z" + } + } + }, + "briefcase": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "work", + "business", + "office", + "luggage", + "bag" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0b1", + "label": "Briefcase", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M320 288h192v144c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V288h192v20c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12v-20zm192-112v80H0v-80c0-26.51 21.49-48 48-48h80V80c0-26.51 21.49-48 48-48h160c26.51 0 48 21.49 48 48v48h80c26.51 0 48 21.49 48 48zM320 96H192v32h128V96z" + } + } + }, + "btc": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f15a", + "label": "BTC", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z" + } + } + }, + "bug": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "report", + "insect" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f188", + "label": "Bug", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z" + } + } + }, + "building": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "work", + "business", + "apartment", + "office", + "company" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1ad", + "label": "Building", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z" + } + } + }, + "bullhorn": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "announcement", + "share", + "broadcast", + "louder", + "megaphone" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0a1", + "label": "bullhorn", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 224c0-20.896-13.36-38.666-32-45.258V64c0-35.346-28.654-64-64-64-64.985 56-142.031 128-272 128H48c-26.51 0-48 21.49-48 48v96c0 26.51 21.49 48 48 48h43.263c-18.742 64.65 2.479 116.379 18.814 167.44 1.702 5.32 5.203 9.893 9.922 12.88 20.78 13.155 68.355 15.657 93.773 5.151 16.046-6.633 19.96-27.423 7.522-39.537-18.508-18.026-30.136-36.91-19.795-60.858a12.278 12.278 0 0 0-1.045-11.673c-16.309-24.679-3.581-62.107 28.517-72.752C346.403 327.887 418.591 395.081 480 448c35.346 0 64-28.654 64-64V269.258c18.64-6.592 32-24.362 32-45.258zm-96 139.855c-54.609-44.979-125.033-92.94-224-104.982v-69.747c98.967-12.042 169.391-60.002 224-104.982v279.711z" + } + } + }, + "bullseye": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "target" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f140", + "label": "Bullseye", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 72c101.689 0 184 82.295 184 184 0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-101.689 82.295-184 184-184m0-64C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 184c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64m0-64c-70.692 0-128 57.308-128 128s57.308 128 128 128 128-57.308 128-128-57.308-128-128-128z" + } + } + }, + "buromobelexperte": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f37f", + "label": "Büromöbel-Experte GmbH & Co. KG.", + "sponsored": { + "label": "Büromöbel-Experte GmbH & Co. KG.", + "url": "https://www.bueromoebel-experte.de" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z" + } + } + }, + "bus": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f207", + "label": "Bus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 152v80c0 13.255-10.745 24-24 24h-8v168c0 13.255-10.745 24-24 24h-8v40c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24v-40H160v40c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-40h-8c-13.255 0-24-10.745-24-24V256h-8c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h8V80C32 35.817 132.288 0 256 0s224 35.817 224 80v48h8c13.255 0 24 10.745 24 24zM112 320c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm32-56V120c0-13.255-10.745-24-24-24H104c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z" + } + } + }, + "buysellads": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f20d", + "label": "BuySellAds", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z" + } + } + }, + "calculator": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1ec", + "label": "Calculator", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 464V48C0 21.49 21.49 0 48 0h352c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm384-284V76c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v104c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12zM128 308v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm256 128V268c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-256 0v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm128-128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm0 128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" + } + } + }, + "calendar": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "date", + "time", + "when", + "event", + "calendar-o" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f133", + "label": "Calendar", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z" + } + } + }, + "calendar-alt": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "date", + "time", + "when", + "event", + "calendar" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f073", + "label": "Alternate Calendar", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm116 204c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "calendar-check": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ok" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f274", + "label": "Calendar Check", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z" + } + } + }, + "calendar-minus": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f272", + "label": "Calendar Minus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "calendar-plus": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f271", + "label": "Calendar Plus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "calendar-times": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f273", + "label": "Calendar Times", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "camera": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "photo", + "picture", + "record" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f030", + "label": "camera", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z" + } + } + }, + "camera-retro": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "photo", + "picture", + "record" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f083", + "label": "Retro Camera", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z" + } + } + }, + "car": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1b9", + "label": "Car", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M499.991 168h-54.815l-7.854-20.944c-9.192-24.513-25.425-45.351-46.942-60.263S343.651 64 317.472 64H194.528c-26.18 0-51.391 7.882-72.908 22.793-21.518 14.912-37.75 35.75-46.942 60.263L66.824 168H12.009c-8.191 0-13.974 8.024-11.384 15.795l8 24A12 12 0 0 0 20.009 216h28.815l-.052.14C29.222 227.093 16 247.997 16 272v48c0 16.225 6.049 31.029 16 42.309V424c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-61.691c9.951-11.281 16-26.085 16-42.309v-48c0-24.003-13.222-44.907-32.772-55.86l-.052-.14h28.815a12 12 0 0 0 11.384-8.205l8-24c2.59-7.771-3.193-15.795-11.384-15.795zm-365.388 1.528C143.918 144.689 168 128 194.528 128h122.944c26.528 0 50.61 16.689 59.925 41.528L391.824 208H120.176l14.427-38.472zM88 328c-17.673 0-32-14.327-32-32 0-17.673 14.327-32 32-32s48 30.327 48 48-30.327 16-48 16zm336 0c-17.673 0-48 1.673-48-16 0-17.673 30.327-48 48-48s32 14.327 32 32c0 17.673-14.327 32-32 32z" + } + } + }, + "caret-down": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "more", + "dropdown", + "menu", + "triangle down", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0d7", + "label": "Caret Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z" + } + } + }, + "caret-left": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "triangle left", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0d9", + "label": "Caret Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z" + } + } + }, + "caret-right": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward", + "triangle right", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0da", + "label": "Caret Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z" + } + } + }, + "caret-square-down": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "more", + "dropdown", + "menu", + "caret-square-o-down" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f150", + "label": "Caret Square Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "caret-square-left": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "caret-square-o-left" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f191", + "label": "Caret Square Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "caret-square-right": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward", + "caret-square-o-right" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f152", + "label": "Caret Square Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "caret-square-up": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "caret-square-o-up" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f151", + "label": "Caret Square Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "caret-up": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "triangle up", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0d8", + "label": "Caret Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z" + } + } + }, + "cart-arrow-down": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "shopping" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f218", + "label": "Shopping Cart Arrow Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z" + } + } + }, + "cart-plus": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "add", + "shopping" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f217", + "label": "Add to Shopping Cart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z" + } + } + }, + "cc-amex": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "amex" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f1f3", + "label": "American Express Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z" + } + } + }, + "cc-apple-pay": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f416", + "label": "Apple Pay Credit Card", + "svg": { + "brands": { + "last_modified": 1508771132270, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z" + } + } + }, + "cc-diners-club": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f24c", + "label": "Diner's Club Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z" + } + } + }, + "cc-discover": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1f2", + "label": "Discover Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z" + } + } + }, + "cc-jcb": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f24b", + "label": "JCB Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z" + } + } + }, + "cc-mastercard": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1f1", + "label": "MasterCard Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z" + } + } + }, + "cc-paypal": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1f4", + "label": "Paypal Credit Card", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z" + } + } + }, + "cc-stripe": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1f5", + "label": "Stripe Credit Card", + "svg": { + "brands": { + "last_modified": 1510848563150, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z" + } + } + }, + "cc-visa": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1f0", + "label": "Visa Credit Card", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z" + } + } + }, + "centercode": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f380", + "label": "Centercode", + "sponsored": { + "label": "Centercode", + "url": "https://www.centercode.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z" + } + } + }, + "certificate": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "badge", + "star" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0a3", + "label": "certificate", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z" + } + } + }, + "chart-area": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "graph", + "analytics", + "area-chart" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1fe", + "label": "Area Chart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z" + } + } + }, + "chart-bar": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "graph", + "analytics", + "bar-chart" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f080", + "label": "Bar Chart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zm-308-44v-72c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V204c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V108c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 400c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v324h452zm-356-60v-72c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V140c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V204c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V108c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12z" + } + } + }, + "chart-line": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "graph", + "analytics", + "line-chart" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f201", + "label": "Line Chart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z" + } + } + }, + "chart-pie": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "graph", + "analytics", + "pie-chart" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f200", + "label": "Pie Chart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 12.3V240h227.7c6.9 0 12.3-5.8 12-12.7-6.4-122.4-104.5-220.6-227-227-6.9-.3-12.7 5.1-12.7 12zM552.7 288c6.9 0 12.3 5.8 12 12.7-2.8 53.2-23.2 105.6-61.2 147.8-4.6 5.1-12.6 5.4-17.5.5L325 288h227.7zM401 433c4.8 4.8 4.7 12.8-.4 17.3-42.6 38.4-99 61.7-160.8 61.7C107.6 511.9-.2 403.8 0 271.5.2 143.4 100.8 38.9 227.3 32.3c6.9-.4 12.7 5.1 12.7 12V272l161 161z" + } + } + }, + "check": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "checkmark", + "done", + "todo", + "agree", + "accept", + "confirm", + "tick", + "ok" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f00c", + "label": "Check", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" + } + } + }, + "check-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "todo", + "done", + "agree", + "accept", + "confirm", + "ok" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f058", + "label": "Check Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z" + } + } + }, + "check-square": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "checkmark", + "done", + "todo", + "agree", + "accept", + "confirm", + "ok" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f14a", + "label": "Check Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z" + } + } + }, + "chevron-circle-down": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "more", + "dropdown", + "menu", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f13a", + "label": "Chevron Circle Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z" + } + } + }, + "chevron-circle-left": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f137", + "label": "Chevron Circle Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z" + } + } + }, + "chevron-circle-right": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "forward", + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f138", + "label": "Chevron Circle Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z" + } + } + }, + "chevron-circle-up": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f139", + "label": "Chevron Circle Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z" + } + } + }, + "chevron-down": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f078", + "label": "chevron-down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z" + } + } + }, + "chevron-left": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "bracket", + "previous", + "back" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f053", + "label": "chevron-left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z" + } + } + }, + "chevron-right": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "bracket", + "next", + "forward" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f054", + "label": "chevron-right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" + } + } + }, + "chevron-up": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f077", + "label": "chevron-up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z" + } + } + }, + "child": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1ae", + "label": "Child", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z" + } + } + }, + "chrome": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "browser" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f268", + "label": "Chrome", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z" + } + } + }, + "circle": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "dot", + "notification", + "circle-thin" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f111", + "label": "Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z" + } + } + }, + "circle-notch": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "circle-o-notch" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1ce", + "label": "Circle Notched", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z" + } + } + }, + "clipboard": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "paste" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f328", + "label": "Clipboard", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M336 64h-80c0-35.29-28.71-64-64-64s-64 28.71-64 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h42v36c0 6.627 5.373 12 12 12h168c6.627 0 12-5.373 12-12v-36h42a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zM192 40c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24" + } + } + }, + "clock": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "watch", + "timer", + "late", + "timestamp", + "date" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f017", + "label": "Clock", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z" + } + } + }, + "clone": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "copy" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f24d", + "label": "Clone", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z" + } + } + }, + "closed-captioning": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "cc" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f20a", + "label": "Closed Captioning", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z" + } + } + }, + "cloud": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "save" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c2", + "label": "Cloud", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M537.585 226.56C541.725 215.836 544 204.184 544 192c0-53.019-42.981-96-96-96-19.729 0-38.065 5.954-53.316 16.159C367.042 64.248 315.288 32 256 32c-88.366 0-160 71.634-160 160 0 2.728.07 5.439.204 8.133C40.171 219.845 0 273.227 0 336c0 79.529 64.471 144 144 144h368c70.692 0 128-57.308 128-128 0-61.93-43.983-113.586-102.415-125.44z" + } + } + }, + "cloud-download-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "cloud-download" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f381", + "label": "Cloud Download-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-246.627-64H328V176c0-8.837-7.164-16-16-16h-48c-8.836 0-16 7.163-16 16v112h-65.373c-14.254 0-21.393 17.234-11.314 27.314l105.373 105.373c6.248 6.248 16.379 6.248 22.627 0l105.373-105.373c10.08-10.08 2.941-27.314-11.313-27.314z" + } + } + }, + "cloud-upload-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "cloud-upload" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f382", + "label": "Cloud Upload-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-235.314-91.314L299.314 155.314c-6.248-6.248-16.379-6.248-22.627 0L171.314 260.686c-10.08 10.08-2.941 27.314 11.313 27.314H248v112c0 8.837 7.164 16 16 16h48c8.836 0 16-7.163 16-16V288h65.373c14.254 0 21.393-17.234 11.313-27.314z" + } + } + }, + "cloudscale": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f383", + "label": "cloudscale.ch", + "sponsored": { + "label": "cloudscale.ch", + "url": "https://www.cloudscale.ch" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z" + } + } + }, + "cloudsmith": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f384", + "label": "Cloudsmith", + "sponsored": { + "label": "Cloudsmith", + "url": "https://cloudsmith.io" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "332", + "512" + ], + "width": 332, + "height": 512, + "path": "M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z" + } + } + }, + "cloudversify": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f385", + "label": "cloudversify", + "sponsored": { + "label": "cloudversify", + "url": "https://www.cloudversify.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "616", + "512" + ], + "width": 616, + "height": 512, + "path": "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z" + } + } + }, + "code": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "html", + "brackets" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f121", + "label": "Code", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z" + } + } + }, + "code-branch": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "git", + "fork", + "vcs", + "svn", + "github", + "rebase", + "version", + "branch", + "code-fork" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f126", + "label": "Code Branch", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z" + } + } + }, + "codepen": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1cb", + "label": "Codepen", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z" + } + } + }, + "codiepie": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f284", + "label": "Codie Pie", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "472", + "512" + ], + "width": 472, + "height": 512, + "path": "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z" + } + } + }, + "coffee": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "morning", + "mug", + "breakfast", + "tea", + "drink", + "cafe" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0f4", + "label": "Coffee", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z" + } + } + }, + "cog": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "settings" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f013", + "label": "cog", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z" + } + } + }, + "cogs": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "settings" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f085", + "label": "cogs", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z" + } + } + }, + "columns": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "split", + "panes" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0db", + "label": "Columns", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z" + } + } + }, + "comment": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "speech", + "notification", + "note", + "chat", + "bubble", + "feedback", + "message", + "texting", + "sms", + "conversation" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f075", + "label": "comment", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160z" + } + } + }, + "comment-alt": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "speech", + "notification", + "note", + "chat", + "bubble", + "feedback", + "message", + "texting", + "sms", + "conversation", + "commenting", + "commenting" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f27a", + "label": "Alternate Comment", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208zm-416-48c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160zm-64-160c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48z" + } + } + }, + "comments": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "speech", + "notification", + "note", + "chat", + "bubble", + "feedback", + "message", + "texting", + "sms", + "conversation" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f086", + "label": "comments", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M224 358.857c-37.599 0-73.027-6.763-104.143-18.7-31.375 24.549-69.869 39.508-110.764 43.796a8.632 8.632 0 0 1-.89.047c-3.736 0-7.111-2.498-8.017-6.061-.98-3.961 2.088-6.399 5.126-9.305 15.017-14.439 33.222-25.79 40.342-74.297C17.015 266.886 0 232.622 0 195.429 0 105.16 100.297 32 224 32s224 73.159 224 163.429c-.001 90.332-100.297 163.428-224 163.428zm347.067 107.174c-13.944-13.127-30.849-23.446-37.46-67.543 68.808-64.568 52.171-156.935-37.674-207.065.031 1.334.066 2.667.066 4.006 0 122.493-129.583 216.394-284.252 211.222 38.121 30.961 93.989 50.492 156.252 50.492 34.914 0 67.811-6.148 96.704-17 29.134 22.317 64.878 35.916 102.853 39.814 3.786.395 7.363-1.973 8.27-5.467.911-3.601-1.938-5.817-4.759-8.459z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M574.507 443.86c-5.421 21.261-24.57 36.14-46.511 36.14-32.246 0-66.511-9.99-102.1-29.734-50.64 11.626-109.151 7.877-157.96-13.437 41.144-2.919 80.361-12.339 116.331-28.705 16.322-1.22 32.674-4.32 48.631-9.593C454.404 412.365 490.663 432 527.996 432c-32-17.455-43.219-38.958-46.159-58.502 25.443-18.848 46.159-47.183 46.159-81.135 0-10.495-2.383-21.536-7.041-32.467 7.405-25.93 8.656-50.194 5.185-73.938 32.164 30.461 49.856 69.128 49.856 106.405 0 33.893-12.913 65.047-34.976 91.119 2.653 2.038 5.924 4.176 9.962 6.378 19.261 10.508 28.947 32.739 23.525 54zM240.002 80C117.068 80 48.004 152.877 48.004 210.909c0 38.196 24.859 70.072 55.391 91.276-3.527 21.988-16.991 46.179-55.391 65.815 44.8 0 88.31-22.089 114.119-37.653 25.52 7.906 51.883 11.471 77.879 11.471C362.998 341.818 432 268.976 432 210.909 432 152.882 362.943 80 240.002 80m0-48C390.193 32 480 126.026 480 210.909c0 22.745-6.506 46.394-18.816 68.391-11.878 21.226-28.539 40.294-49.523 56.674-21.593 16.857-46.798 30.045-74.913 39.197-29.855 9.719-62.405 14.646-96.746 14.646-24.449 0-48.34-2.687-71.292-8.004C126.311 404.512 85.785 416 48.004 416c-22.18 0-41.472-15.197-46.665-36.761-5.194-21.563 5.064-43.878 24.811-53.976 7.663-3.918 13.324-7.737 17.519-11.294-7.393-7.829-13.952-16.124-19.634-24.844C8.09 264.655.005 238.339.005 210.909.005 126.259 89.508 32 240.002 32z" + } + } + }, + "compass": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "safari", + "directory", + "menu", + "location" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f14e", + "label": "Compass", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM307.446 120.844l-102.642 97.779a23.997 23.997 0 0 0-6.772 11.729l-33.359 137.779c-5.68 23.459 22.777 39.318 39.88 23.024l102.64-97.779a23.99 23.99 0 0 0 6.772-11.729l33.359-137.779c5.618-23.198-22.591-39.493-39.878-23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm91.326-312.131l-33.359 137.779a24.005 24.005 0 0 1-6.772 11.729l-102.64 97.779c-17.104 16.293-45.56.434-39.88-23.024l33.359-137.779a23.997 23.997 0 0 1 6.772-11.729l102.642-97.779c17.285-16.47 45.494-.175 39.878 23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z" + } + } + }, + "compress": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "collapse", + "combine", + "contract", + "merge", + "smaller" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f066", + "label": "Compress", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z" + } + } + }, + "connectdevelop": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f20e", + "label": "Connect Develop", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z" + } + } + }, + "contao": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f26d", + "label": "Contao", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z" + } + } + }, + "copy": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "duplicate", + "clone", + "file", + "files-o" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0c5", + "label": "Copy", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z" + } + } + }, + "copyright": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1f9", + "label": "Copyright", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z" + } + } + }, + "cpanel": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f388", + "label": "cPanel", + "sponsored": { + "label": "cPanel", + "url": "http://cpanel.com/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5" + } + } + }, + "creative-commons": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f25e", + "label": "Creative Commons", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z" + } + } + }, + "credit-card": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "money", + "buy", + "debit", + "checkout", + "purchase", + "payment", + "credit-card-alt" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f09d", + "label": "Credit Card", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z" + } + } + }, + "crop": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f125", + "label": "crop", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488 352h-40V109.3l57-57c9.4-9.4 9.4-24.6 0-33.9L493.7 7c-9.4-9.4-24.6-9.4-33.9 0l-57 57H160V24c0-13.3-10.7-24-24-24H88C74.7 0 64 10.7 64 24v40H24C10.7 64 0 74.7 0 88v48c0 13.3 10.7 24 24 24h40v264c0 13.3 10.7 24 24 24h264v40c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24v-40h40c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zM306.7 160L160 306.7V160h146.7zM205.3 352L352 205.3V352H205.3z" + } + } + }, + "crosshairs": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "picker" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f05b", + "label": "Crosshairs", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z" + } + } + }, + "css3": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "code" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f13c", + "label": "CSS 3 Logo", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z" + } + } + }, + "css3-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f38b", + "label": "Alternate CSS3 Logo", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z" + } + } + }, + "cube": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1b2", + "label": "Cube", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z" + } + } + }, + "cubes": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1b3", + "label": "Cubes", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z" + } + } + }, + "cut": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "scissors", + "scissors" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c4", + "label": "Cut", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M444.485 422.426c4.689 4.689 4.684 12.287 0 16.971-32.804 32.804-85.991 32.804-118.795 0L210.176 323.883l-24.859 24.859C189.63 359.657 192 371.552 192 384c0 53.019-42.981 96-96 96S0 437.019 0 384s42.981-96 96-96c4.536 0 8.995.322 13.363.93l32.93-32.93-32.93-32.93c-4.368.608-8.827.93-13.363.93-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96c0 12.448-2.37 24.343-6.682 35.258l24.859 24.859L325.69 72.603c32.804-32.804 85.991-32.804 118.795 0 4.684 4.684 4.689 12.282 0 16.971L278.059 256l166.426 166.426zM96 96c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m0 256c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m112-108c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12z" + } + } + }, + "cuttlefish": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f38c", + "label": "Cuttlefish", + "sponsored": { + "label": "Cuttlefish", + "url": "http://wearecuttlefish.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "440", + "512" + ], + "width": 440, + "height": 512, + "path": "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z" + } + } + }, + "d-and-d": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f38d", + "label": "Dungeons & Dragons", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z" + } + } + }, + "dashcube": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f210", + "label": "DashCube", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z" + } + } + }, + "database": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1c0", + "label": "Database", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z" + } + } + }, + "deaf": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a4", + "label": "Deaf", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z" + } + } + }, + "delicious": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a5", + "label": "Delicious Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z" + } + } + }, + "deploydog": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f38e", + "label": "deploy.dog", + "sponsored": { + "label": "deploy.dog", + "url": "http://deploy.dog" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z" + } + } + }, + "deskpro": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f38f", + "label": "Deskpro", + "sponsored": { + "label": "Deskpro", + "url": "http://www.deskpro.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z" + } + } + }, + "desktop": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "monitor", + "screen", + "desktop", + "computer", + "demo", + "device" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f108", + "label": "Desktop", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z" + } + } + }, + "deviantart": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1bd", + "label": "deviantART", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z" + } + } + }, + "digg": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a6", + "label": "Digg Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z" + } + } + }, + "digital-ocean": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f391", + "label": "Digital Ocean", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z" + } + } + }, + "discord": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f392", + "label": "Discord", + "svg": { + "brands": { + "last_modified": 1511276382120, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z" + } + } + }, + "discourse": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f393", + "label": "Discourse", + "sponsored": { + "label": "Discourse", + "url": "https://discourse.org" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z" + } + } + }, + "dochub": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f394", + "label": "DocHub", + "sponsored": { + "label": "DocHub", + "url": "https://dochub.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "416", + "512" + ], + "width": 416, + "height": 512, + "path": "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z" + } + } + }, + "docker": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f395", + "label": "Docker", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z" + } + } + }, + "dollar-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "usd", + "usd" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f155", + "label": "Dollar Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M113.411 169.375c0-23.337 21.536-38.417 54.865-38.417 26.726 0 54.116 12.263 76.461 28.333 5.88 4.229 14.13 2.354 17.575-4.017l23.552-43.549c2.649-4.898 1.596-10.991-2.575-14.68-24.281-21.477-59.135-34.09-91.289-37.806V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v49.832c-58.627 13.29-97.299 55.917-97.299 108.639 0 123.533 184.765 110.81 184.765 169.414 0 19.823-16.311 41.158-52.124 41.158-30.751 0-62.932-15.88-87.848-35.887-5.31-4.264-13.082-3.315-17.159 2.14l-30.389 40.667c-3.627 4.854-3.075 11.657 1.302 15.847 24.049 23.02 59.249 41.255 98.751 47.973V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-47.438c65.72-10.215 106.176-59.186 106.176-116.516.001-119.688-184.764-103.707-184.764-166.671z" + } + } + }, + "dot-circle": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "target", + "bullseye", + "notification" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f192", + "label": "Dot Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z" + } + } + }, + "download": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "import" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f019", + "label": "Download", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z" + } + } + }, + "draft2digital": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f396", + "label": "Draft2digital", + "sponsored": { + "label": "Draft2Digital", + "url": "http://draft2digital.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z" + } + } + }, + "dribbble": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f17d", + "label": "Dribbble", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z" + } + } + }, + "dribbble-square": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f397", + "label": "Dribbble Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z" + } + } + }, + "dropbox": { + "changes": [ + "3.2", + "5.0.0", + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f16b", + "label": "Dropbox", + "svg": { + "brands": { + "last_modified": 1512507825891, + "raw": "", + "viewBox": [ + "0", + "0", + "528", + "512" + ], + "width": 528, + "height": 512, + "path": "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z" + } + } + }, + "drupal": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a9", + "label": "Drupal Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z" + } + } + }, + "dyalog": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f399", + "label": "Dyalog", + "sponsored": { + "label": "Dyalog APL", + "url": "http://www.dyalog.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "416", + "512" + ], + "width": 416, + "height": 512, + "path": "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z" + } + } + }, + "earlybirds": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f39a", + "label": "Earlybirds", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z" + } + } + }, + "edge": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "browser", + "ie" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f282", + "label": "Edge Browser", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z" + } + } + }, + "edit": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "write", + "edit", + "update", + "pencil", + "pen" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f044", + "label": "Edit", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z" + } + } + }, + "eject": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f052", + "label": "eject", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z" + } + } + }, + "ellipsis-h": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "dots" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f141", + "label": "Horizontal Ellipsis", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z" + } + } + }, + "ellipsis-v": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "dots" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f142", + "label": "Vertical Ellipsis", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z" + } + } + }, + "ember": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f423", + "label": "Ember", + "svg": { + "brands": { + "last_modified": 1511207633238, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z" + } + } + }, + "empire": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d1", + "label": "Galactic Empire", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z" + } + } + }, + "envelope": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "email", + "e-mail", + "letter", + "support", + "mail", + "message", + "notification" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0e0", + "label": "Envelope", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z" + } + } + }, + "envelope-open": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "email", + "e-mail", + "letter", + "support", + "mail", + "message", + "notification" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2b6", + "label": "Envelope Open", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z" + } + } + }, + "envelope-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "email", + "e-mail", + "letter", + "support", + "mail", + "message", + "notification" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f199", + "label": "Envelope Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z" + } + } + }, + "envira": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "leaf" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f299", + "label": "Envira Gallery", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z" + } + } + }, + "eraser": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "remove", + "delete" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f12d", + "label": "eraser", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z" + } + } + }, + "erlang": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f39d", + "label": "Erlang", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z" + } + } + }, + "etsy": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2d7", + "label": "Etsy", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z" + } + } + }, + "euro-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "eur", + "eur" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f153", + "label": "Euro Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z" + } + } + }, + "exchange-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "transfer", + "arrows", + "arrow", + "exchange" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f362", + "label": "Alternate Exchange", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z" + } + } + }, + "exclamation": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "warning", + "error", + "problem", + "notification", + "notify", + "alert" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f12a", + "label": "exclamation", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z" + } + } + }, + "exclamation-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "warning", + "error", + "problem", + "notification", + "notify", + "alert" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f06a", + "label": "Exclamation Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z" + } + } + }, + "exclamation-triangle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "warning", + "error", + "problem", + "notification", + "notify", + "alert" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f071", + "label": "Exclamation Triangle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z" + } + } + }, + "expand": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "enlarge", + "bigger", + "resize" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f065", + "label": "Expand", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z" + } + } + }, + "expand-arrows-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "enlarge", + "bigger", + "resize", + "move", + "arrows-alt" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f31e", + "label": "Alternate Expand Arrows", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448.1", + "512" + ], + "width": 448, + "height": 512, + "path": "M448.1 344v112c0 13.3-10.7 24-24 24h-112c-21.4 0-32.1-25.9-17-41l36.2-36.2L224 295.6 116.8 402.9 153 439c15.1 15.1 4.4 41-17 41H24c-13.3 0-24-10.7-24-24V344c0-21.4 25.9-32.1 41-17l36.2 36.2L184.5 256 77.2 148.7 41 185c-15.1 15.1-41 4.4-41-17V56c0-13.3 10.7-24 24-24h112c21.4 0 32.1 25.9 17 41l-36.2 36.2L224 216.4l107.3-107.3L295.1 73c-15.1-15.1-4.4-41 17-41h112c13.3 0 24 10.7 24 24v112c0 21.4-25.9 32.1-41 17l-36.2-36.2L263.6 256l107.3 107.3 36.2-36.2c15.1-15.2 41-4.5 41 16.9z" + } + } + }, + "expeditedssl": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f23e", + "label": "ExpeditedSSL", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z" + } + } + }, + "external-link-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "open", + "new", + "external-link" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f35d", + "label": "Alternate External Link", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z" + } + } + }, + "external-link-square-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "open", + "new", + "external-link-square" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f360", + "label": "Alternate External Link Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z" + } + } + }, + "eye": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "show", + "visible", + "views" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f06e", + "label": "Eye", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M569.354 231.631C512.969 135.949 407.81 72 288 72 168.14 72 63.004 135.994 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.031 376.051 168.19 440 288 440c119.86 0 224.996-63.994 281.354-159.631a47.997 47.997 0 0 0 0-48.738zM288 392c-75.162 0-136-60.827-136-136 0-75.162 60.826-136 136-136 75.162 0 136 60.826 136 136 0 75.162-60.826 136-136 136zm104-136c0 57.438-46.562 104-104 104s-104-46.562-104-104c0-17.708 4.431-34.379 12.236-48.973l-.001.032c0 23.651 19.173 42.823 42.824 42.823s42.824-19.173 42.824-42.823c0-23.651-19.173-42.824-42.824-42.824l-.032.001C253.621 156.431 270.292 152 288 152c57.438 0 104 46.562 104 104z" + } + } + }, + "eye-dropper": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "eyedropper" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1fb", + "label": "Eye Dropper", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M177.38 206.64L39.03 344.97A24.01 24.01 0 0 0 32 361.94V424L0 480l32 32 56-32h62.06c6.36 0 12.47-2.53 16.97-7.03l138.35-138.33-128-128zm225.552 30.47l16.952 16.95c9.37 9.37 9.37 24.57 0 33.94l-40.973 40.97c-9.292 9.312-24.506 9.434-33.94 0L183.028 167.03c-9.37-9.37-9.37-24.57 0-33.94L224 92.12c9.289-9.309 24.502-9.438 33.94 0l16.992 16.99 82.606-82.601c35.19-35.19 92.5-35.5 128 0 40.49 48.08 29.66 98.34 0 128l-82.606 82.601z" + } + } + }, + "eye-slash": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "toggle", + "show", + "hide", + "visible", + "visiblity", + "views" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f070", + "label": "Eye Slash", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M286.693 391.984l32.579 46.542A333.958 333.958 0 0 1 288 440C168.19 440 63.031 376.051 6.646 280.369a47.999 47.999 0 0 1 0-48.739c24.023-40.766 56.913-75.775 96.024-102.537l57.077 81.539C154.736 224.82 152 240.087 152 256c0 74.736 60.135 135.282 134.693 135.984zm282.661-111.615c-31.667 53.737-78.747 97.46-135.175 125.475l.011.015 41.47 59.2c7.6 10.86 4.96 25.82-5.9 33.42l-13.11 9.18c-10.86 7.6-25.82 4.96-33.42-5.9L100.34 46.94c-7.6-10.86-4.96-25.82 5.9-33.42l13.11-9.18c10.86-7.6 25.82-4.96 33.42 5.9l51.038 72.617C230.68 75.776 258.905 72 288 72c119.81 0 224.969 63.949 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM424 256c0-75.174-60.838-136-136-136-17.939 0-35.056 3.473-50.729 9.772l19.299 27.058c25.869-8.171 55.044-6.163 80.4 7.41h-.03c-23.65 0-42.82 19.17-42.82 42.82 0 23.626 19.147 42.82 42.82 42.82 23.65 0 42.82-19.17 42.82-42.82v-.03c18.462 34.49 16.312 77.914-8.25 110.95v.01l19.314 27.061C411.496 321.2 424 290.074 424 256zM262.014 356.727l-77.53-110.757c-5.014 52.387 29.314 98.354 77.53 110.757z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z" + } + } + }, + "facebook": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "social network", + "facebook-official" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f09a", + "label": "Facebook", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z" + } + } + }, + "facebook-f": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "facebook" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f39e", + "label": "Facebook F", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "264", + "512" + ], + "width": 264, + "height": 512, + "path": "M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229" + } + } + }, + "facebook-messenger": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f39f", + "label": "Facebook Messenger", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z" + } + } + }, + "facebook-square": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "social network" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f082", + "label": "Facebook Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z" + } + } + }, + "fast-backward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "rewind", + "previous", + "beginning", + "start", + "first" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f049", + "label": "fast-backward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z" + } + } + }, + "fast-forward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "end", + "last" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f050", + "label": "fast-forward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z" + } + } + }, + "fax": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1ac", + "label": "Fax", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M128 144v320c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V144c0-26.51 21.49-48 48-48h32c26.51 0 48 21.49 48 48zm384 64v256c0 26.51-21.49 48-48 48H192c-26.51 0-48-21.49-48-48V40c0-22.091 17.909-40 40-40h207.432a39.996 39.996 0 0 1 28.284 11.716l48.569 48.569A39.999 39.999 0 0 1 480 88.568v74.174c18.641 6.591 32 24.36 32 45.258zm-320-16h240V96h-24c-13.203 0-24-10.797-24-24V48H192v144zm96 204c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm128 128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40z" + } + } + }, + "female": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "woman", + "user", + "person", + "profile" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f182", + "label": "Female", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z" + } + } + }, + "fighter-jet": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "fly", + "plane", + "airplane", + "quick", + "fast", + "travel" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0fb", + "label": "fighter-jet", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z" + } + } + }, + "file": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "new", + "page", + "pdf", + "document" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f15b", + "label": "File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z" + } + } + }, + "file-alt": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "new", + "page", + "pdf", + "document", + "file-text" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f15c", + "label": "Alternate File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z" + } + } + }, + "file-archive": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c6", + "label": "Archive File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32V32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6zm32.7-53c0 14.9-14.5 27-32.4 27S96 378 96 363c0-14.9 14.5-27 32.4-27s32.5 12.1 32.5 27zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM256 51.882L332.118 128H256V51.882zM336 464H48V48h79.714v16h32V48H208v104c0 13.255 10.745 24 24 24h104v288zM192.27 96h-32V64h32v32zm-32 0v32h-32V96h32zm0 64v32h-32v-32h32zm32 0h-32v-32h32v32zm1.909 105.678A12 12 0 0 0 182.406 256H160.27v-32h-32v32l-19.69 97.106C101.989 385.611 126.834 416 160 416c33.052 0 57.871-30.192 51.476-62.62l-17.297-87.702zM160.27 390.073c-17.918 0-32.444-12.105-32.444-27.036 0-14.932 14.525-27.036 32.444-27.036s32.444 12.105 32.444 27.036c0 14.931-14.526 27.036-32.444 27.036zm32-166.073h-32v-32h32v32z" + } + } + }, + "file-audio": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c7", + "label": "Audio File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z" + } + } + }, + "file-code": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c9", + "label": "Code File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm101.677-115.115L116.854 320l32.822-28.885a8.793 8.793 0 0 0 .605-12.624l-17.403-18.564c-3.384-3.613-8.964-3.662-12.438-.401L62.78 313.58c-3.703 3.474-3.704 9.367.001 12.84l57.659 54.055a8.738 8.738 0 0 0 6.012 2.381 8.746 8.746 0 0 0 6.427-2.782l17.403-18.563a8.795 8.795 0 0 0-.605-12.626zm84.284-127.85l-24.401-7.084a8.796 8.796 0 0 0-10.905 5.998L144.04 408.061c-1.353 4.66 1.338 9.552 5.998 10.905l24.403 7.084c4.68 1.355 9.557-1.354 10.905-5.998l54.612-188.112c1.354-4.66-1.337-9.552-5.997-10.905zm87.258 92.545l-57.658-54.055c-3.526-3.307-9.099-3.165-12.439.401l-17.403 18.563a8.795 8.795 0 0 0 .605 12.625L267.146 320l-32.822 28.885a8.793 8.793 0 0 0-.605 12.624l17.403 18.564a8.797 8.797 0 0 0 12.439.401h-.001l57.66-54.055c3.703-3.473 3.703-9.366-.001-12.839z" + } + } + }, + "file-excel": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c3", + "label": "Excel File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z" + } + } + }, + "file-image": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c5", + "label": "Image File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z" + } + } + }, + "file-pdf": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c1", + "label": "PDF File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z" + } + } + }, + "file-powerpoint": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c4", + "label": "Powerpoint File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z" + } + } + }, + "file-video": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c8", + "label": "Video File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z" + } + } + }, + "file-word": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1c2", + "label": "Word File", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z" + } + } + }, + "film": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "movie" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f008", + "label": "Film", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z" + } + } + }, + "filter": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "funnel", + "options" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0b0", + "label": "Filter", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z" + } + } + }, + "fire": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "flame", + "hot", + "popular" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f06d", + "label": "fire", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M216 23.858c0-23.802-30.653-32.765-44.149-13.038C48 191.851 224 200 224 288c0 35.629-29.114 64.458-64.85 63.994C123.98 351.538 96 322.22 96 287.046v-85.51c0-21.703-26.471-32.225-41.432-16.504C27.801 213.158 0 261.332 0 320c0 105.869 86.131 192 192 192s192-86.131 192-192c0-170.29-168-193.003-168-296.142z" + } + } + }, + "fire-extinguisher": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f134", + "label": "fire-extinguisher", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z" + } + } + }, + "firefox": { + "changes": [ + "4.4", + "5.0.0", + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [ + "browser" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f269", + "label": "Firefox", + "svg": { + "brands": { + "last_modified": 1512768505415, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z" + } + } + }, + "first-order": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2b0", + "label": "First Order", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z" + } + } + }, + "firstdraft": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a1", + "label": "firstdraft", + "sponsored": { + "label": "firstdraft", + "url": "http://www.firstdraft.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z" + } + } + }, + "flag": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "report", + "notification", + "notify" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f024", + "label": "flag", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z" + } + } + }, + "flag-checkered": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "report", + "notification", + "notify" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f11e", + "label": "flag-checkered", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M466.515 66.928C487.731 57.074 512 72.551 512 95.944v243.1c0 10.526-5.161 20.407-13.843 26.358-35.837 24.564-74.335 40.858-122.505 40.858-67.373 0-111.63-34.783-165.217-34.783-50.853 0-86.124 10.058-114.435 22.122V488c0 13.255-10.745 24-24 24H56c-13.255 0-24-10.745-24-24V101.945C17.497 91.825 8 75.026 8 56 8 24.296 34.345-1.254 66.338.048c28.468 1.158 51.779 23.968 53.551 52.404.52 8.342-.81 16.31-3.586 23.562C137.039 68.384 159.393 64 184.348 64c67.373 0 111.63 34.783 165.217 34.783 40.496 0 82.612-15.906 116.95-31.855zM96 134.63v70.49c29-10.67 51.18-17.83 73.6-20.91v-71.57c-23.5 2.17-40.44 9.79-73.6 21.99zm220.8 9.19c-26.417-4.672-49.886-13.979-73.6-21.34v67.42c24.175 6.706 47.566 16.444 73.6 22.31v-68.39zm-147.2 40.39v70.04c32.796-2.978 53.91-.635 73.6 3.8V189.9c-25.247-7.035-46.581-9.423-73.6-5.69zm73.6 142.23c26.338 4.652 49.732 13.927 73.6 21.34v-67.41c-24.277-6.746-47.54-16.45-73.6-22.32v68.39zM96 342.1c23.62-8.39 47.79-13.84 73.6-16.56v-71.29c-26.11 2.35-47.36 8.04-73.6 17.36v70.49zm368-221.6c-21.3 8.85-46.59 17.64-73.6 22.47v71.91c27.31-4.36 50.03-14.1 73.6-23.89V120.5zm0 209.96v-70.49c-22.19 14.2-48.78 22.61-73.6 26.02v71.58c25.07-2.38 48.49-11.04 73.6-27.11zM316.8 212.21v68.16c25.664 7.134 46.616 9.342 73.6 5.62v-71.11c-25.999 4.187-49.943 2.676-73.6-2.67z" + } + } + }, + "flask": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "science", + "beaker", + "experimental", + "labs" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c3", + "label": "Flask", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z" + } + } + }, + "flickr": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f16e", + "label": "Flickr", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z" + } + } + }, + "fly": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f417", + "label": "Fly", + "svg": { + "brands": { + "last_modified": 1508771132271, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z" + } + } + }, + "folder": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f07b", + "label": "Folder", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-6 272H54c-3.314 0-6-2.678-6-5.992V117.992A5.993 5.993 0 0 1 54 112h134.118l64 64H458a6 6 0 0 1 6 6v212a6 6 0 0 1-6 6z" + } + } + }, + "folder-open": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f07c", + "label": "Folder Open", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M527.943 224H480v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h400a48.001 48.001 0 0 0 40.704-22.56l79.942-128c19.948-31.917-3.038-73.44-40.703-73.44zM54 112h134.118l64 64H426a6 6 0 0 1 6 6v42H152a48 48 0 0 0-41.098 23.202L48 351.449V117.993A5.993 5.993 0 0 1 54 112zm394 288H72l77.234-128H528l-80 128z" + } + } + }, + "font": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "text" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f031", + "label": "font", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M152 416h-24.013l26.586-80.782H292.8L319.386 416H296c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-26.739L275.495 42.746A16 16 0 0 0 260.382 32h-72.766a16 16 0 0 0-15.113 10.746L42.739 416H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm64.353-271.778c4.348-15.216 6.61-28.156 7.586-34.644.839 6.521 2.939 19.476 7.727 34.706l41.335 124.006h-98.619l41.971-124.068z" + } + } + }, + "font-awesome": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "meanpath" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f2b4", + "label": "Font Awesome", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z" + } + } + }, + "font-awesome-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f35c", + "label": "Alternate Font Awesome", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z" + } + } + }, + "font-awesome-flag": { + "changes": [ + "5.0.0", + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f425", + "label": "Font Awesome Flag", + "svg": { + "brands": { + "last_modified": 1511276382121, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z" + } + } + }, + "fonticons": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f280", + "label": "Fonticons", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z" + } + } + }, + "fonticons-fi": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a2", + "label": "Fonticons Fi", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z" + } + } + }, + "fort-awesome": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f286", + "label": "Fort Awesome", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z" + } + } + }, + "fort-awesome-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a3", + "label": "Alternate Fort Awesome", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48" + } + } + }, + "forumbee": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f211", + "label": "Forumbee", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z" + } + } + }, + "forward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "forward", + "next" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f04e", + "label": "forward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z" + } + } + }, + "foursquare": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f180", + "label": "Foursquare", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "368", + "512" + ], + "width": 368, + "height": 512, + "path": "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z" + } + } + }, + "free-code-camp": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2c5", + "label": "Free Code Camp", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z" + } + } + }, + "freebsd": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a4", + "label": "FreeBSD", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z" + } + } + }, + "frown": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "face", + "emoticon", + "sad", + "disapprove", + "rating" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f119", + "label": "Frown", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm192.551 212.66c-59.128-91.455-165.846-91.594-225.064 0-11.502 17.79 15.383 35.148 26.873 17.374 46.626-72.118 124.862-71.855 171.318 0 11.328 17.524 38.548.684 26.873-17.374z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm171.547 201.782c-56.595-76.964-158.383-77.065-215.057-.001-18.82 25.593 19.858 54.018 38.67 28.438 37.511-51.01 100.365-50.796 137.717-.001 18.509 25.172 57.821-2.395 38.67-28.436z" + } + } + }, + "futbol": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1e3", + "label": "Futbol", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M207.898 325.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-455.998-.19L48 256c0 44.7 14.015 87.242 39.95 122.626l7.982-35.118 88.595 10.871 37.775 80.985-30.978 18.427c41.832 13.631 87.598 13.606 129.354 0L289.7 435.364l37.775-80.985 88.594-10.871 7.982 35.118C449.985 343.242 464 300.7 464 256l-.002-.19-27.003 23.561-65.223-60.875 17.122-87.779 35.538 3.183c-25.216-34.63-61.309-62.053-104.577-75.951l14.143 33.091L256 134.25l-77.996-43.21 14.144-33.091C148.868 71.851 112.782 99.277 87.57 133.9l35.81-3.183 16.849 87.779-65.223 60.875-27.004-23.561z" + } + } + }, + "gamepad": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "controller" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f11b", + "label": "Gamepad", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z" + } + } + }, + "gavel": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "judge", + "lawyer", + "opinion" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0e3", + "label": "Gavel", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z" + } + } + }, + "gem": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "diamond" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f3a5", + "label": "Gem", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z" + } + } + }, + "genderless": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f22d", + "label": "Genderless", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "288", + "512" + ], + "width": 288, + "height": 512, + "path": "M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z" + } + } + }, + "get-pocket": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f265", + "label": "Get Pocket", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z" + } + } + }, + "gg": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f260", + "label": "GG Currency", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z" + } + } + }, + "gg-circle": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f261", + "label": "GG Currency Circle", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z" + } + } + }, + "gift": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "present" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f06b", + "label": "gift", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M488 192h-64.512C438.72 175.003 448 152.566 448 128c0-52.935-43.065-96-96-96-41.997 0-68.742 20.693-95.992 54.15C226.671 50.192 199.613 32 160 32c-52.935 0-96 43.065-96 96 0 24.566 9.28 47.003 24.512 64H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h8v112c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V320h8c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zm-208-32c24-56 55.324-64 72-64 17.645 0 32 14.355 32 32s-14.355 32-32 32h-72zM160 96c16.676 0 48 8 72 64h-72c-17.645 0-32-14.355-32-32s14.355-32 32-32zm48 128h96v184c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V224z" + } + } + }, + "git": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d3", + "label": "Git", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z" + } + } + }, + "git-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d2", + "label": "Git Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z" + } + } + }, + "github": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "octocat" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f09b", + "label": "GitHub", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z" + } + } + }, + "github-alt": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "octocat" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f113", + "label": "Alternate GitHub", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z" + } + } + }, + "github-square": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "octocat" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f092", + "label": "GitHub Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z" + } + } + }, + "gitkraken": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a6", + "label": "GitKraken", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "592", + "512" + ], + "width": 592, + "height": 512, + "path": "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z" + } + } + }, + "gitlab": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "Axosoft" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f296", + "label": "GitLab", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z" + } + } + }, + "gitter": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f426", + "label": "Gitter", + "svg": { + "brands": { + "last_modified": 1510848563150, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z" + } + } + }, + "glass-martini": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "martini", + "drink", + "bar", + "alcohol", + "liquor", + "glass" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f000", + "label": "Martini Glass", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M507.3 27.3c10-10 2.9-27.3-11.3-27.3H16C1.8 0-5.4 17.2 4.7 27.3L216 238.6V472h-92c-15.5 0-28 12.5-28 28 0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12 0-15.5-12.5-28-28-28h-92V238.6L507.3 27.3z" + } + } + }, + "glide": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2a5", + "label": "Glide", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z" + } + } + }, + "glide-g": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2a6", + "label": "Glide G", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z" + } + } + }, + "globe": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "world", + "planet", + "map", + "place", + "travel", + "earth", + "global", + "translate", + "all", + "language", + "localize", + "location", + "coordinates", + "country" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ac", + "label": "Globe", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M364.215 192h131.43c5.439 20.419 8.354 41.868 8.354 64s-2.915 43.581-8.354 64h-131.43c5.154-43.049 4.939-86.746 0-128zM185.214 352c10.678 53.68 33.173 112.514 70.125 151.992.221.001.44.008.661.008s.44-.008.661-.008c37.012-39.543 59.467-98.414 70.125-151.992H185.214zm174.13-192h125.385C452.802 84.024 384.128 27.305 300.95 12.075c30.238 43.12 48.821 96.332 58.394 147.925zm-27.35 32H180.006c-5.339 41.914-5.345 86.037 0 128h151.989c5.339-41.915 5.345-86.037-.001-128zM152.656 352H27.271c31.926 75.976 100.6 132.695 183.778 147.925-30.246-43.136-48.823-96.35-58.393-147.925zm206.688 0c-9.575 51.605-28.163 104.814-58.394 147.925 83.178-15.23 151.852-71.949 183.778-147.925H359.344zm-32.558-192c-10.678-53.68-33.174-112.514-70.125-151.992-.221 0-.44-.008-.661-.008s-.44.008-.661.008C218.327 47.551 195.872 106.422 185.214 160h141.572zM16.355 192C10.915 212.419 8 233.868 8 256s2.915 43.581 8.355 64h131.43c-4.939-41.254-5.154-84.951 0-128H16.355zm136.301-32c9.575-51.602 28.161-104.81 58.394-147.925C127.872 27.305 59.198 84.024 27.271 160h125.385z" + } + } + }, + "gofore": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a7", + "label": "Gofore", + "sponsored": { + "label": "Gofore", + "url": "http://gofore.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "400", + "512" + ], + "width": 400, + "height": 512, + "path": "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z" + } + } + }, + "goodreads": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a8", + "label": "Goodreads", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z" + } + } + }, + "goodreads-g": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3a9", + "label": "Goodreads G", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z" + } + } + }, + "google": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a0", + "label": "Google Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "488", + "512" + ], + "width": 488, + "height": 512, + "path": "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z" + } + } + }, + "google-drive": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3aa", + "label": "Google Drive", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z" + } + } + }, + "google-play": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ab", + "label": "Google Play", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z" + } + } + }, + "google-plus": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "google-plus-circle", + "google-plus-official" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f2b3", + "label": "Google Plus", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z" + } + } + }, + "google-plus-g": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "social network", + "google-plus" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f0d5", + "label": "Google Plus G", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z" + } + } + }, + "google-plus-square": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "social network" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f0d4", + "label": "Google Plus Square", + "svg": { + "brands": { + "last_modified": 1508771132271, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z" + } + } + }, + "google-wallet": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1ee", + "label": "Google Wallet", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z" + } + } + }, + "graduation-cap": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "learning", + "school", + "student" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f19d", + "label": "Graduation Cap", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M622.884 199.005l-275.817 85.1a96 96 0 0 1-54.134 0L92.398 222.232c-8.564 11.438-11.018 23.05-11.918 38.335C89.778 266.165 96 276.355 96 288c0 11.952-6.557 22.366-16.265 27.861l16.197 123.096c.63 4.786-3.1 9.043-7.932 9.043H40c-4.828 0-8.562-4.253-7.932-9.044L48.265 315.86C38.557 310.366 32 299.952 32 288c0-12.034 6.646-22.511 16.465-27.976.947-17.951 3.974-33.231 12.152-47.597l-43.502-13.422c-22.876-6.801-22.766-39.241 0-46.01l275.817-85.1a96 96 0 0 1 54.134 0l275.817 85.1c22.877 6.801 22.767 39.241.001 46.01zM356.503 314.682l-.207.064-.207.061a127.998 127.998 0 0 1-72.177 0l-.207-.061-.207-.064-150.914-46.57L120 352c0 35.346 89.543 64 200 64s200-28.654 200-64l-12.583-83.888-150.914 46.57z" + } + } + }, + "gratipay": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "heart", + "like", + "favorite", + "love" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f184", + "label": "Gratipay (Gittip)", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z" + } + } + }, + "grav": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2d6", + "label": "Grav", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z" + } + } + }, + "gripfire": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ac", + "label": "Gripfire, Inc.", + "sponsored": { + "label": "Gripfire, Inc.", + "url": "http://gripfire.io" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9" + } + } + }, + "grunt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ad", + "label": "Grunt", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z" + } + } + }, + "gulp": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ae", + "label": "Gulp", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z" + } + } + }, + "h-square": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "hospital", + "hotel" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0fd", + "label": "H Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z" + } + } + }, + "hacker-news": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d4", + "label": "Hacker News", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z" + } + } + }, + "hacker-news-square": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3af", + "label": "Hacker News Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z" + } + } + }, + "hand-lizard": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f258", + "label": "Lizard (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z" + } + } + }, + "hand-paper": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "stop" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f256", + "label": "Paper (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z" + } + } + }, + "hand-peace": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f25b", + "label": "Peace (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z" + } + } + }, + "hand-point-down": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "point", + "finger", + "hand-o-down" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0a7", + "label": "Hand Pointing Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z" + } + } + }, + "hand-point-left": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "point", + "left", + "previous", + "back", + "finger", + "hand-o-left" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0a5", + "label": "Hand Pointing Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z" + } + } + }, + "hand-point-right": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "point", + "right", + "next", + "forward", + "finger", + "hand-o-right" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0a4", + "label": "Hand Pointing Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z" + } + } + }, + "hand-point-up": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "point", + "finger", + "hand-o-up" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0a6", + "label": "Hand Pointing Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z" + } + } + }, + "hand-pointer": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f25a", + "label": "Pointer (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z" + } + } + }, + "hand-rock": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f255", + "label": "Rock (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 128.79c0-26.322-20.861-48.344-47.18-48.783C437.935 79.558 416 101.217 416 128h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C333.935 47.558 312 69.217 312 96v32h-8V80.79c0-26.322-20.861-48.344-47.18-48.783C229.935 31.558 208 53.217 208 80v48h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C125.935 47.558 104 69.217 104 96v136l-8-7.111V176.79c0-26.322-20.861-48.344-47.18-48.783C21.935 127.558 0 149.217 0 176v66.445a95.998 95.998 0 0 0 32.221 71.751l111.668 99.261A47.999 47.999 0 0 1 160 449.333V456c0 13.255 10.745 24 24 24h240c13.255 0 24-10.745 24-24v-2.921a96.01 96.01 0 0 1 7.523-37.254l48.954-116.265A96.002 96.002 0 0 0 512 262.306V128.79z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z" + } + } + }, + "hand-scissors": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f257", + "label": "Scissors (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z" + } + } + }, + "hand-spock": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f259", + "label": "Spock (Hand)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M10.872 316.585c15.139-16.086 40.454-16.854 56.543-1.713L128 371.893v-79.405L88.995 120.865c-4.896-21.542 8.598-42.974 30.14-47.87 21.549-4.894 42.975 8.599 47.87 30.141L201.747 256h9.833L164.016 48.966c-4.946-21.531 8.498-42.994 30.028-47.94 21.532-4.95 42.994 8.498 47.94 30.028L293.664 256h15.105l48.425-193.702c5.357-21.432 27.075-34.462 48.507-29.104 21.432 5.358 34.463 27.075 29.104 48.507L391.231 256h11.08l30.768-129.265c5.117-21.491 26.685-34.768 48.177-29.647 21.491 5.117 34.765 26.686 29.647 48.177l-36.292 152.467A96.024 96.024 0 0 0 472 319.967v42.102a96.002 96.002 0 0 1-3.96 27.287l-26.174 88.287C435.825 498.022 417.101 512 395.846 512H179.172a48.002 48.002 0 0 1-32.898-13.046L12.585 373.128c-16.087-15.141-16.853-40.456-1.713-56.543z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z" + } + } + }, + "handshake": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2b5", + "label": "Handshake", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M72 112H24c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zM48 340c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zm568-228h-48c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zm-24 228c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zM485.94 92.67L528 140.74V320h-19.17c.56-14.96-4.38-28.98-14-39.71l-80.92-98.91c2.93-3.2 2.76-8.16-.38-11.16-2.82-2.7-7.08-2.92-10.14-.76-.42.3-60.35 62.93-60.35 62.93l-.2.21c-23.904 26.905-66.127 26.204-89.15-1.42-15.48-18.58-15.29-45.39.45-63.76l66.57-77.67C334.304 73.88 354.534 64 376.7 64h46.05a83.98 83.98 0 0 1 63.19 28.67zm-3.37 197.92c15.46 16.78 12.59 43.83-2.37 57.75-17.711 16.462-42.433 13.004-45.93 9.2 1.653 15.658-21.389 47.249-56.42 44.68-6.325 21.185-32.298 38.909-59.18 29.61-10.22 10.21-25.82 14.97-39.81 14.97-28.69 0-54.92-11.99-72.58-30.8L112 320V135.52l61.36-50.57A71.52 71.52 0 0 1 223.93 64h37.42c16.73 0 32.68 6.84 44.21 18.85l-63.57 74.16c-20.84 24.31-21.09 59.81-.59 84.42 29.375 35.247 83.007 35.853 113.31 1.92L402.82 193l79.75 97.59z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M616 96h-48c-7.107 0-13.49 3.091-17.884 8H526.59l-31.13-36.3-.16-.18A103.974 103.974 0 0 0 417.03 32h-46.55c-17.75 0-34.9 4.94-49.69 14.01C304.33 36.93 285.67 32 266.62 32h-32.11c-28.903 0-57.599 11.219-79.2 32.8L116.12 104H89.884C85.49 99.091 79.107 96 72 96H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h48c10.449 0 19.334-6.68 22.629-16h18.801l75.35 67.57c25.542 26.45 59.925 44.43 96.58 44.43 16.39 0 32.28-3.85 46.1-10.93 24.936.496 51.101-10.368 69.07-31.41 19.684-5.579 37.503-17.426 50.72-34.6 20.989-4.401 40.728-16.492 53.42-35.06h40.701c3.295 9.32 12.18 16 22.629 16h48c13.255 0 24-10.745 24-24V120c0-13.255-10.745-24-24-24zM48 352c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16zm412.52-5.76c-15.35 14.295-36.884 11.328-39.95 8 1.414 13.382-18.257 41.043-49.08 38.88-5.541 18.523-28.218 33.826-51.49 25.75-8.89 8.89-22.46 13.13-34.64 13.13-24.95 0-47.77-14.54-63.14-30.91l-81.3-72.91a31.976 31.976 0 0 0-21.36-8.18H96V152h26.75c8.48 0 16.62-3.37 22.62-9.37l43.88-43.88A64.004 64.004 0 0 1 234.51 80h32.11c5.8 0 11.51.79 17 2.3l-43.27 50.49c-23.56 27.48-23.84 67.62-.66 95.44 32.388 38.866 91.378 39.228 124.48 1.98l25.98-30.08L462.59 296c13.44 14.6 10.95 38.13-2.07 50.24zM544 320h-24.458c.104-20.261-6.799-39.33-19.762-54.4L421.7 162.28c4.51-9.51 2.34-21.23-6.01-28.45-10.075-8.691-25.23-7.499-33.86 2.48l-53.63 62.12c-13.828 15.41-38.223 15.145-51.64-.93a25.857 25.857 0 0 1 .23-33.47l57.92-67.58A47.09 47.09 0 0 1 370.48 80h46.55c16.11 0 31.44 6.94 42.07 19.04L504.52 152H544v168zm48 32c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16z" + } + } + }, + "hashtag": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f292", + "label": "Hashtag", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z" + } + } + }, + "hdd": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "harddrive", + "hard drive", + "storage", + "save" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0a0", + "label": "HDD", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z" + } + } + }, + "heading": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "header", + "header" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1dc", + "label": "heading", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z" + } + } + }, + "headphones": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sound", + "listen", + "music", + "audio" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f025", + "label": "headphones", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z" + } + } + }, + "heart": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "love", + "like", + "favorite" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f004", + "label": "Heart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M414.9 24C361.8 24 312 65.7 288 89.3 264 65.7 214.2 24 161.1 24 70.3 24 16 76.9 16 165.5c0 72.6 66.8 133.3 69.2 135.4l187 180.8c8.8 8.5 22.8 8.5 31.6 0l186.7-180.2c2.7-2.7 69.5-63.5 69.5-136C560 76.9 505.7 24 414.9 24z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M257.3 475.4L92.5 313.6C85.4 307 24 248.1 24 174.8 24 84.1 80.8 24 176 24c41.4 0 80.6 22.8 112 49.8 31.3-27 70.6-49.8 112-49.8 91.7 0 152 56.5 152 150.8 0 52-31.8 103.5-68.1 138.7l-.4.4-164.8 161.5a43.7 43.7 0 0 1-61.4 0zM125.9 279.1L288 438.3l161.8-158.7c27.3-27 54.2-66.3 54.2-104.8C504 107.9 465.8 72 400 72c-47.2 0-92.8 49.3-112 68.4-17-17-64-68.4-112-68.4-65.9 0-104 35.9-104 102.8 0 37.3 26.7 78.9 53.9 104.3z" + } + } + }, + "heartbeat": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ekg" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f21e", + "label": "Heartbeat", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M47.9 257C31.6 232.7 16 200.5 16 165.5 16 76.9 70.3 24 161.1 24 214.2 24 264 65.7 288 89.3 312 65.7 361.8 24 414.9 24 505.7 24 560 76.9 560 165.5c0 35-15.5 67.2-31.9 91.5H408l-26.4-58.6c-4.7-8.9-17.6-8.5-21.6.7l-53.3 134.6L235.4 120c-3.7-10.6-18.7-10.7-22.6-.2l-48 137.2H47.9zm348 32c-4.5 0-8.6-2.5-10.6-6.4l-12.8-32.5-56.9 142.8c-4.4 9.9-18.7 9.4-22.3-.9l-69.7-209.2-33.6 98.4c-1.7 4.7-6.2 7.8-11.2 7.8H73.4c5.3 5.7-12.8-12 198.9 192.6 8.8 8.5 22.8 8.5 31.6 0 204.3-197.2 191-184 199-192.6h-107z" + } + } + }, + "hire-a-helper": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b0", + "label": "HireAHelper", + "sponsored": { + "label": "HireAHelper", + "url": "https://www.hireahelper.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z" + } + } + }, + "history": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1da", + "label": "History", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z" + } + } + }, + "home": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "main", + "house" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f015", + "label": "home", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z" + } + } + }, + "hooli": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f427", + "label": "Hooli", + "svg": { + "brands": { + "last_modified": 1510848563150, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z" + } + } + }, + "hospital": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "building" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0f8", + "label": "hospital", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z" + } + } + }, + "hotjar": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b1", + "label": "Hotjar", + "sponsored": { + "label": "Hotjar", + "url": "https://www.hotjar.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z" + } + } + }, + "hourglass": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f254", + "label": "Hourglass", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z" + } + } + }, + "hourglass-end": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f253", + "label": "Hourglass End", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z" + } + } + }, + "hourglass-half": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f252", + "label": "Hourglass Half", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z" + } + } + }, + "hourglass-start": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f251", + "label": "Hourglass Start", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z" + } + } + }, + "houzz": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f27c", + "label": "Houzz", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z" + } + } + }, + "html5": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f13b", + "label": "HTML 5 Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z" + } + } + }, + "hubspot": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b2", + "label": "HubSpot", + "sponsored": { + "label": "HubSpot", + "url": "http://www.HubSpot.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z" + } + } + }, + "i-cursor": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f246", + "label": "I Beam Cursor", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z" + } + } + }, + "id-badge": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2c1", + "label": "Identification Badge", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M0 464V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm192-144c53.019 0 96-42.981 96-96s-42.981-96-96-96-96 42.981-96 96 42.981 96 96 96zm94.317 17.474l-22.954-7.173C242.437 344.413 217.802 352 192 352s-50.437-7.587-71.363-21.699l-22.954 7.173C77.644 343.736 64 362.295 64 383.289V424c0 13.255 10.745 24 24 24h208c13.255 0 24-10.745 24-24v-40.711c0-20.994-13.644-39.553-33.683-45.815zM352 52v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M192 128c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64 28.654-64 64-64m61.187 145.847l-18.064-5.161C222.371 275.884 207.658 280 192 280s-30.371-4.116-43.122-11.314l-18.064 5.161C110.207 279.734 96 298.569 96 320v72c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-72c0-21.431-14.207-40.266-34.813-46.153zM0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48zm336 32v378a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V80h288z" + } + } + }, + "id-card": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2c2", + "label": "Identification Card", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM160 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64m79.589 154.53l-28.281-9.427C196.458 314.532 178.856 320 160 320s-36.458-5.468-51.309-14.897L80.41 314.53A24 24 0 0 0 64 337.298V360c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-22.702a24 24 0 0 0-16.411-22.768zM448 340v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm32-96v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h424c6.627 0 12-5.373 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M404 256H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm12 68v-24c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12zm96-212v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zm-48 282V144H48v250a6 6 0 0 0 6 6h404a6 6 0 0 0 6-6zm-288-98c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56 25.072 56 56 56zm62.896 10.869l-13.464-4.039C211.814 313.568 194.649 320 176 320s-35.814-6.432-49.433-17.17l-13.464 4.039A24 24 0 0 0 96 329.857V372c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12v-42.143a24 24 0 0 0-17.104-22.988z" + } + } + }, + "image": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "photo", + "album", + "picture", + "picture" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f03e", + "label": "Image", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z" + } + } + }, + "images": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "photo", + "album", + "picture" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f302", + "label": "Images", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z" + } + } + }, + "imdb": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2d8", + "label": "IMDB", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z" + } + } + }, + "inbox": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f01c", + "label": "inbox", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z" + } + } + }, + "indent": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f03c", + "label": "Indent", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm176 144h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm-52.687-111.313l-96-95.984C17.266 138.652 0 145.776 0 160.016v191.975c0 14.329 17.325 21.304 27.313 11.313l96-95.992c6.249-6.247 6.249-16.377 0-22.625z" + } + } + }, + "industry": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "factory" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f275", + "label": "Industry", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z" + } + } + }, + "info": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "help", + "information", + "more", + "details" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f129", + "label": "Info", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z" + } + } + }, + "info-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "help", + "information", + "more", + "details" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f05a", + "label": "Info Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z" + } + } + }, + "instagram": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f16d", + "label": "Instagram", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" + } + } + }, + "internet-explorer": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "browser", + "ie" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f26b", + "label": "Internet-explorer", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z" + } + } + }, + "ioxhost": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f208", + "label": "ioxhost", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z" + } + } + }, + "italic": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "italics" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f033", + "label": "italic", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M204.758 416h-33.849l62.092-320h40.725a16 16 0 0 0 15.704-12.937l6.242-32C297.599 41.184 290.034 32 279.968 32H120.235a16 16 0 0 0-15.704 12.937l-6.242 32C96.362 86.816 103.927 96 113.993 96h33.846l-62.09 320H46.278a16 16 0 0 0-15.704 12.935l-6.245 32C22.402 470.815 29.967 480 40.034 480h158.479a16 16 0 0 0 15.704-12.935l6.245-32c1.927-9.88-5.638-19.065-15.704-19.065z" + } + } + }, + "itunes": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b4", + "label": "iTunes", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z" + } + } + }, + "itunes-note": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b5", + "label": "Itunes Note", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z" + } + } + }, + "jenkins": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b6", + "label": "Jenkis", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z" + } + } + }, + "joget": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b7", + "label": "Joget", + "sponsored": { + "label": "Joget", + "url": "http://www.joget.org" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6" + } + } + }, + "joomla": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1aa", + "label": "Joomla Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z" + } + } + }, + "js": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b8", + "label": "JavaScript (JS)", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z" + } + } + }, + "js-square": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3b9", + "label": "JavaScript (JS) Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z" + } + } + }, + "jsfiddle": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1cc", + "label": "jsFiddle", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z" + } + } + }, + "key": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "unlock", + "password" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f084", + "label": "key", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z" + } + } + }, + "keyboard": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "type", + "input" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f11c", + "label": "Keyboard", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z" + } + } + }, + "keycdn": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ba", + "label": "KeyCDN", + "sponsored": { + "label": "KeyCDN", + "url": "https://www.keycdn.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160" + } + } + }, + "kickstarter": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3bb", + "label": "Kickstarter", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z" + } + } + }, + "kickstarter-k": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3bc", + "label": "Kickstarter K", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z" + } + } + }, + "language": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1ab", + "label": "Language", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M304 416H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h280v320zm-120.676-72.622A12 12 0 0 0 194.839 352h22.863c8.22 0 14.007-8.078 11.362-15.861L171.61 167.085a12 12 0 0 0-11.362-8.139h-32.489a12.001 12.001 0 0 0-11.362 8.139L58.942 336.139C56.297 343.922 62.084 352 70.304 352h22.805a12 12 0 0 0 11.535-8.693l9.118-31.807h60.211l9.351 31.878zm-39.051-140.42s4.32 21.061 7.83 33.21l10.8 37.531h-38.07l11.07-37.531c3.51-12.15 7.83-33.21 7.83-33.21h.54zM616 416H336V96h280c13.255 0 24 10.745 24 24v272c0 13.255-10.745 24-24 24zm-36-228h-64v-16c0-6.627-5.373-12-12-12h-16c-6.627 0-12 5.373-12 12v16h-64c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h114.106c-6.263 14.299-16.518 28.972-30.023 43.206-6.56-6.898-12.397-13.91-17.365-20.933-3.639-5.144-10.585-6.675-15.995-3.446l-7.28 4.346-6.498 3.879c-5.956 3.556-7.693 11.421-3.735 17.117 6.065 8.729 13.098 17.336 20.984 25.726-8.122 6.226-16.841 12.244-26.103 17.964-5.521 3.41-7.381 10.556-4.162 16.19l7.941 13.896c3.362 5.883 10.935 7.826 16.706 4.276 12.732-7.831 24.571-16.175 35.443-24.891 10.917 8.761 22.766 17.102 35.396 24.881 5.774 3.556 13.353 1.618 16.717-4.27l7.944-13.903c3.213-5.623 1.37-12.76-4.135-16.171a312.737 312.737 0 0 1-26.06-18.019c21.024-22.425 35.768-46.289 42.713-69.85H580c6.627 0 12-5.373 12-12v-16c0-6.625-5.373-11.998-12-11.998z" + } + } + }, + "laptop": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "demo", + "computer", + "device" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f109", + "label": "Laptop", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M512 64v256H128V64h384m16-64H112C85.5 0 64 21.5 64 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm100 416H389.5c-3 0-5.5 2.1-5.9 5.1C381.2 436.3 368 448 352 448h-64c-16 0-29.2-11.7-31.6-26.9-.5-2.9-3-5.1-5.9-5.1H12c-6.6 0-12 5.4-12 12v36c0 26.5 21.5 48 48 48h544c26.5 0 48-21.5 48-48v-36c0-6.6-5.4-12-12-12z" + } + } + }, + "laravel": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3bd", + "label": "Laravel", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z" + } + } + }, + "lastfm": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f202", + "label": "last.fm", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z" + } + } + }, + "lastfm-square": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f203", + "label": "last.fm Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": ">", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z" + } + } + }, + "leaf": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "eco", + "nature", + "plant" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f06c", + "label": "leaf", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M395.4 420.8c-43.4 21.6-91.9 34.4-140.8 34.4-82.2 0-151.1-40.1-151.1-40.1-16.1 0-35.4 64.9-63.3 64.9-27 0-40.2-24-40.2-38.5 0-33.1 63.6-58.9 63.6-77.3 0 0-12.5-21.2-12.5-59.2 0-101.2 81.3-173.4 172.6-203.3 65.9-21.6 206 3.5 250.7-38.5C492.1 47 500.8 32 527.8 32c36.3 0 48.2 93.2 48.2 120.3 0 110.9-54.5 206.5-180.6 268.5zm-254.3-75.6c63.5-89.9 144.5-128.8 257.7-120 8.8.7 16.5-5.9 17.2-14.7.7-8.8-5.9-16.5-14.7-17.2-124-9.6-215.9 33.9-286.3 133.5-5.1 7.2-3.4 17.2 3.8 22.3 7.2 5.1 17.2 3.4 22.3-3.9z" + } + } + }, + "leanpub": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f212", + "label": "Leanpub", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z" + } + } + }, + "lemon": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "food" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f094", + "label": "Lemon", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z" + } + } + }, + "less": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41d", + "label": "Less", + "svg": { + "brands": { + "last_modified": 1508771132271, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z" + } + } + }, + "level-down-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "level-down" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3be", + "label": "Level Down-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z" + } + } + }, + "level-up-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "level-up" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3bf", + "label": "Level Up-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z" + } + } + }, + "life-ring": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "support" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1cd", + "label": "Life Ring", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z" + } + } + }, + "lightbulb": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "idea", + "inspiration" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0eb", + "label": "Lightbulb", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zm-143.107-44c-9.907 0-18.826-6.078-22.376-15.327C67.697 267.541 16 277.731 16 176 16 78.803 94.805 0 192 0s176 78.803 176 176c0 101.731-51.697 91.541-90.516 192.673-3.55 9.249-12.47 15.327-22.376 15.327H128.893zM112 176c0-44.112 35.888-80 80-80 8.837 0 16-7.164 16-16s-7.163-16-16-16c-61.757 0-112 50.243-112 112 0 8.836 7.164 16 16 16s16-7.164 16-16z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zM128 176c0-35.29 28.71-64 64-64 8.837 0 16-7.164 16-16s-7.163-16-16-16c-52.935 0-96 43.065-96 96 0 8.836 7.164 16 16 16s16-7.164 16-16zm64-128c70.734 0 128 57.254 128 128 0 77.602-37.383 60.477-80.98 160h-94.04C101.318 236.33 64 253.869 64 176c0-70.735 57.254-128 128-128m0-48C94.805 0 16 78.803 16 176c0 101.731 51.697 91.541 90.516 192.674 3.55 9.249 12.47 15.326 22.376 15.326h126.215c9.906 0 18.826-6.078 22.376-15.326C316.303 267.541 368 277.731 368 176 368 78.803 289.195 0 192 0z" + } + } + }, + "line": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c0", + "label": "Line", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z" + } + } + }, + "link": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "chain" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c1", + "label": "Link", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z" + } + } + }, + "linkedin": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "linkedin-square" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f08c", + "label": "LinkedIn", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z" + } + } + }, + "linkedin-in": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "linkedin" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f0e1", + "label": "LinkedIn In", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z" + } + } + }, + "linode": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2b8", + "label": "Linode", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z" + } + } + }, + "linux": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "tux" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f17c", + "label": "Linux", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z" + } + } + }, + "lira-sign": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "try", + "turkish", + "try" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f195", + "label": "Turkish Lira Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z" + } + } + }, + "list": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ul", + "ol", + "checklist", + "finished", + "completed", + "done", + "todo" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f03a", + "label": "list", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z" + } + } + }, + "list-alt": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ul", + "ol", + "checklist", + "finished", + "completed", + "done", + "todo" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f022", + "label": "list-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z" + } + } + }, + "list-ol": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ul", + "ol", + "checklist", + "list", + "todo", + "list", + "numbers" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0cb", + "label": "list-ol", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" + } + } + }, + "list-ul": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ul", + "ol", + "checklist", + "todo", + "list" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ca", + "label": "list-ul", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" + } + } + }, + "location-arrow": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "map", + "coordinates", + "location", + "address", + "place", + "where" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f124", + "label": "location-arrow", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M443.683 4.529L27.818 196.418C-18.702 217.889-3.39 288 47.933 288H224v175.993c0 51.727 70.161 66.526 91.582 20.115L507.38 68.225c18.905-40.961-23.752-82.133-63.697-63.696z" + } + } + }, + "lock": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "protect", + "admin", + "security" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f023", + "label": "lock", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z" + } + } + }, + "lock-open": { + "changes": [ + "3.1", + "5.0.0", + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [ + "protect", + "admin", + "password", + "lock", + "open" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3c1", + "label": "Lock Open", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z" + } + } + }, + "long-arrow-alt-down": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "long-arrow-down" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f309", + "label": "Alternate Long Arrow Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z" + } + } + }, + "long-arrow-alt-left": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "previous", + "back", + "long-arrow-left" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f30a", + "label": "Alternate Long Arrow Left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z" + } + } + }, + "long-arrow-alt-right": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "long-arrow-right" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f30b", + "label": "Alternate Long Arrow Right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z" + } + } + }, + "long-arrow-alt-up": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "long-arrow-up" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f30c", + "label": "Alternate Long Arrow Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z" + } + } + }, + "low-vision": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a8", + "label": "Low Vision", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z" + } + } + }, + "lyft": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c3", + "label": "lyft", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z" + } + } + }, + "magento": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c4", + "label": "Magento", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z" + } + } + }, + "magic": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "wizard", + "automatic", + "autocomplete" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0d0", + "label": "magic", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M101.1 505L7 410.9c-9.4-9.4-9.4-24.6 0-33.9L377 7c9.4-9.4 24.6-9.4 33.9 0l94.1 94.1c9.4 9.4 9.4 24.6 0 33.9L135 505c-9.3 9.3-24.5 9.3-33.9 0zM304 159.2l48.8 48.8 89.9-89.9-48.8-48.8-89.9 89.9zM138.9 39.3l-11.7 23.8-26.2 3.8c-4.7.7-6.6 6.5-3.2 9.8l19 18.5-4.5 26.1c-.8 4.7 4.1 8.3 8.3 6.1L144 115l23.4 12.3c4.2 2.2 9.1-1.4 8.3-6.1l-4.5-26.1 19-18.5c3.4-3.3 1.5-9.1-3.2-9.8L160.8 63l-11.7-23.8c-2-4.1-8.1-4.1-10.2.1zm97.7-20.7l-7.8 15.8-17.5 2.6c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L240 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm-192 0l-7.8 15.8L19.3 37c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L48 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm416 223.5l-7.8 15.8-17.5 2.5c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4l15.6-8.2 15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-2.8-5.4-2.8-6.8 0z" + } + } + }, + "magnet": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f076", + "label": "magnet", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512.1", + "512" + ], + "width": 512, + "height": 512, + "path": "M164.1 160H12c-6.6 0-12-5.4-12-12V68c0-19.9 16.1-36 36-36h104c19.9 0 36 16.1 36 36v80c.1 6.6-5.3 12-11.9 12zm348-12V67.9c0-19.9-16.1-36-36-36h-104c-19.9 0-36 16.1-36 36v80c0 6.6 5.4 12 12 12h152c6.6.1 12-5.3 12-11.9zm-164 44c-6.6 0-12 5.4-12 12v52c0 128.1-160 127.9-160 0v-52c0-6.6-5.4-12-12-12h-152c-6.7 0-12 5.4-12 12.1.1 21.4.6 40.3 0 53.3C.1 408 136.3 504 256.9 504 377.5 504 512 408 512 257.3c-.6-12.8-.2-33 0-53.2 0-6.7-5.3-12.1-12-12.1H348.1z" + } + } + }, + "male": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "man", + "user", + "person", + "profile" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f183", + "label": "Male", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "192", + "512" + ], + "width": 192, + "height": 512, + "path": "M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z" + } + } + }, + "map": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f279", + "label": "Map", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 56.015v335.97a23.998 23.998 0 0 1-13.267 21.466l-128 64C418.948 485.344 400 473.992 400 455.985v-335.97a23.998 23.998 0 0 1 13.267-21.466l128-64C557.052 26.656 576 38.008 576 56.015zm-206.253 42.07l-144-64c-15.751-7-33.747 4.461-33.747 21.932v335.967a24 24 0 0 0 14.253 21.931l144 64c15.751 7 33.747-4.461 33.747-21.931V120.017a24 24 0 0 0-14.253-21.932zm-228.48-63.536l-128 63.985A23.998 23.998 0 0 0 0 120v335.985c0 18.007 18.948 29.359 34.733 21.466l128-63.985A23.998 23.998 0 0 0 176 392V56.015c0-18.007-18.948-29.359-34.733-21.466z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M508.505 36.17L381.517 92.576 207.179 34.463a47.992 47.992 0 0 0-34.674 1.674l-144 64A48 48 0 0 0 0 144v287.967c0 34.938 35.991 57.864 67.495 43.863l126.988-56.406 174.339 58.113a47.992 47.992 0 0 0 34.674-1.674l144-64A48 48 0 0 0 576 368V80.033c0-34.938-35.991-57.864-67.495-43.863zM360 424l-144-48V88l144 48v288zm-312 8V144l120-53.333v288L48 432zm480-64l-120 53.333v-288L528 80v288z" + } + } + }, + "map-marker": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "map", + "pin", + "location", + "coordinates", + "localize", + "address", + "travel", + "where", + "place" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f041", + "label": "map-marker", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z" + } + } + }, + "map-marker-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "map-marker" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3c5", + "label": "Map Marker-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" + } + } + }, + "map-pin": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f276", + "label": "Map Pin", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M192 300.813v172.82l-22.015 33.023c-4.75 7.125-15.219 7.125-19.969 0L128 473.633v-172.82a162.221 162.221 0 0 0 64 0zM160 0c79.529 0 144 64.471 144 144s-64.471 144-144 144S16 223.529 16 144 80.471 0 160 0M80 136c0-39.701 32.299-72 72-72a8 8 0 0 0 0-16c-48.523 0-88 39.477-88 88a8 8 0 0 0 16 0z" + } + } + }, + "map-signs": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f277", + "label": "Map Signs", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M487.515 104.485L439.03 152.97a23.998 23.998 0 0 1-16.97 7.029H56c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h160v-8c0-13.255 10.745-24 24-24h32c13.255 0 24 10.745 24 24v8h126.059a24 24 0 0 1 16.97 7.029l48.485 48.485c4.687 4.687 4.687 12.285.001 16.971zM216 368v120c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V368h-80zm240-144H296v-48h-80v48H89.941a24 24 0 0 0-16.97 7.029l-48.485 48.485c-4.686 4.686-4.686 12.284 0 16.971l48.485 48.485a23.998 23.998 0 0 0 16.97 7.029H456c13.255 0 24-10.745 24-24v-80C480 234.745 469.255 224 456 224z" + } + } + }, + "mars": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "male" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f222", + "label": "Mars", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "mars-double": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f227", + "label": "Mars Double", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z" + } + } + }, + "mars-stroke": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f229", + "label": "Mars Stroke", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "mars-stroke-h": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f22b", + "label": "Mars Stroke Horizontal", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z" + } + } + }, + "mars-stroke-v": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f22a", + "label": "Mars Stroke Vertical", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "288", + "512" + ], + "width": 288, + "height": 512, + "path": "M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z" + } + } + }, + "maxcdn": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f136", + "label": "MaxCDN", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z" + } + } + }, + "medapps": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c6", + "label": "MedApps", + "sponsored": { + "label": "MedApps", + "url": "http://medapps.com.au" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z" + } + } + }, + "medium": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f23a", + "label": "Medium", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z" + } + } + }, + "medium-m": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c7", + "label": "Medium M", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z" + } + } + }, + "medkit": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "first aid", + "firstaid", + "help", + "support", + "health" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0fa", + "label": "medkit", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z" + } + } + }, + "medrt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3c8", + "label": "MRT", + "sponsored": { + "label": "MRT", + "url": "https://medrt.co.jp/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "544", + "512" + ], + "width": 544, + "height": 512, + "path": "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z" + } + } + }, + "meetup": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2e0", + "label": "Meetup", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z" + } + } + }, + "meh": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "face", + "emoticon", + "rating", + "neutral" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f11a", + "label": "Meh", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm160 208H176c-21.178 0-21.169 32 0 32h160c21.178 0 21.169-32 0-32z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm136 184H184c-31.776 0-31.749 48 0 48h144c31.776 0 31.749-48 0-48z" + } + } + }, + "mercury": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "transgender" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f223", + "label": "Mercury", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "288", + "512" + ], + "width": 288, + "height": 512, + "path": "M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z" + } + } + }, + "microchip": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2db", + "label": "Microchip", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z" + } + } + }, + "microphone": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "record", + "voice", + "sound" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f130", + "label": "microphone", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M96 256V96c0-53.019 42.981-96 96-96s96 42.981 96 96v160c0 53.019-42.981 96-96 96s-96-42.981-96-96zm252-56h-24c-6.627 0-12 5.373-12 12v42.68c0 66.217-53.082 120.938-119.298 121.318C126.213 376.38 72 322.402 72 256v-44c0-6.627-5.373-12-12-12H36c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c81.307-11.681 144-81.79 144-166.278v-44c0-6.627-5.373-12-12-12z" + } + } + }, + "microphone-slash": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "record", + "voice", + "sound", + "mute" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f131", + "label": "Microphone Slash", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M421.45 285.195L376 239.746V212c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12v44c0 9.957-.881 19.71-2.55 29.195zM352 96c0-53.019-42.981-96-96-96-32.574 0-61.354 16.227-78.71 41.035L352 215.746V96zm152.971 363.716L52.284 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 18.343c-9.372 9.373-9.372 24.568 0 33.941L160 205.254v49.577c0 53.089 43.436 97.452 96.524 97.167 14.626-.078 28.471-3.44 40.854-9.366l17.746 17.746c-17.529 9.971-37.794 15.666-59.372 15.622C189.355 375.864 136 321.053 136 254.656V212c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c25.625-3.682 49.396-13.172 69.942-27.083L459.717 504.97c9.373 9.373 24.569 9.373 33.941 0l11.313-11.313c9.372-9.373 9.372-24.568 0-33.941z" + } + } + }, + "microsoft": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ca", + "label": "Microsoft", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z" + } + } + }, + "minus": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "hide", + "minify", + "delete", + "remove", + "trash", + "hide", + "collapse" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f068", + "label": "minus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z" + } + } + }, + "minus-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "delete", + "remove", + "trash", + "hide" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f056", + "label": "Minus Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z" + } + } + }, + "minus-square": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "hide", + "minify", + "delete", + "remove", + "trash", + "hide", + "collapse" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f146", + "label": "Minus Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "mix": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3cb", + "label": "Mix", + "sponsored": { + "label": "Mix", + "url": "http://mix.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "416", + "512" + ], + "width": 416, + "height": 512, + "path": "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z" + } + } + }, + "mixcloud": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f289", + "label": "Mixcloud", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z" + } + } + }, + "mizuni": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3cc", + "label": "Mizuni", + "sponsored": { + "label": "Mizuni", + "url": "http://www.mizuni.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z" + } + } + }, + "mobile": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "cell phone", + "cellphone", + "text", + "call", + "iphone", + "number", + "telephone" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f10b", + "label": "Mobile Phone", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z" + } + } + }, + "mobile-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "mobile" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3cd", + "label": "Alternate Mobile", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z" + } + } + }, + "modx": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f285", + "label": "MODX", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z" + } + } + }, + "monero": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d0", + "label": "Monero", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z" + } + } + }, + "money-bill-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "money" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f3d1", + "label": "Money Bill-alt", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 120v272c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h592c13.255 0 24 10.745 24 24zM96 384c0-35.346-28.654-64-64-64v64h64zm0-256H32v64c35.346 0 64-28.654 64-64zm304 128c0-53.021-35.816-96-80-96s-80 42.979-80 96c0 53.012 35.814 96 80 96 44.167 0 80-42.969 80-96zm208 64c-35.346 0-64 28.654-64 64h64v-64zm0-192h-64c0 35.346 28.654 64 64 64v-64zM277.563 299.527c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M320 144c-53.021 0-96 50.143-96 112 0 61.847 42.977 112 96 112 53 0 96-50.13 96-112 0-61.857-42.979-112-96-112zm48 164.428c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.901c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.75 3.916 11.75 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.902zM616 64H24C10.745 64 0 74.745 0 88v335c0 13.255 10.745 24 24 24h592c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM512 400H128c0-44.183-35.817-80-80-80V192c44.183 0 80-35.817 80-80h384c0 44.183 35.817 80 80 80v128c-44.183 0-80 35.817-80 80z" + } + } + }, + "moon": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "night", + "darker", + "contrast" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f186", + "label": "Moon", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z" + } + } + }, + "motorcycle": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle", + "bike" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f21c", + "label": "Motorcycle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M512.949 192.003c-14.862-.108-29.14 2.322-42.434 6.874L437.589 144H520c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24h-45.311a24 24 0 0 0-17.839 7.945l-37.496 41.663-22.774-37.956A24 24 0 0 0 376 64h-80c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h66.411l19.2 32H227.904c-17.727-23.073-44.924-40-99.904-40H72.54c-13.455 0-24.791 11.011-24.536 24.464C48.252 141.505 58.9 152 72 152h56c24.504 0 38.686 10.919 47.787 24.769l-11.291 20.529c-13.006-3.865-26.871-5.736-41.251-5.21C55.857 194.549 1.565 249.605.034 317.021-1.603 389.076 56.317 448 128 448c59.642 0 109.744-40.794 123.953-96h84.236c13.673 0 24.589-11.421 23.976-25.077-2.118-47.12 17.522-93.665 56.185-125.026l12.485 20.808c-27.646 23.654-45.097 58.88-44.831 98.179.47 69.556 57.203 126.452 126.758 127.11 71.629.678 129.839-57.487 129.234-129.099-.588-69.591-57.455-126.386-127.047-126.892zM128 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c4.242 0 8.405.341 12.469.982L98.97 316.434C90.187 332.407 101.762 352 120 352h81.297c-12.37 28.225-40.56 48-73.297 48zm388.351-.116C470.272 402.337 432 365.554 432 320c0-21.363 8.434-40.781 22.125-55.144l49.412 82.352c4.546 7.577 14.375 10.034 21.952 5.488l13.72-8.232c7.577-4.546 10.034-14.375 5.488-21.952l-48.556-80.927A80.005 80.005 0 0 1 512 240c45.554 0 82.338 38.273 79.884 84.352-2.16 40.558-34.974 73.372-75.533 75.532z" + } + } + }, + "mouse-pointer": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f245", + "label": "Mouse Pointer", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z" + } + } + }, + "music": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "note", + "sound" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f001", + "label": "Music", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M470.4 1.5l-304 96C153.1 101.7 144 114 144 128v264.6c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V220.5l272-85.9v194c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V32c0-21.7-21.1-37-41.6-30.5z" + } + } + }, + "napster": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d2", + "label": "Napster", + "sponsored": { + "label": "Napster", + "url": "http://www.napster.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z" + } + } + }, + "neuter": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f22c", + "label": "Neuter", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "288", + "512" + ], + "width": 288, + "height": 512, + "path": "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "newspaper": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "press" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1ea", + "label": "Newspaper", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z" + } + } + }, + "nintendo-switch": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f418", + "label": "Nintendo Switch", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z" + } + } + }, + "node": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f419", + "label": "Node.js", + "svg": { + "brands": { + "last_modified": 1508771132272, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z" + } + } + }, + "node-js": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d3", + "label": "Node.js JS", + "svg": { + "brands": { + "last_modified": 1508771132271, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z" + } + } + }, + "npm": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d4", + "label": "npm", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z" + } + } + }, + "ns8": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d5", + "label": "NS8", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z" + } + } + }, + "nutritionix": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d6", + "label": "Nutritionix", + "sponsored": { + "label": "Nutritionix", + "url": "http://www.nutritionix.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "400", + "512" + ], + "width": 400, + "height": 512, + "path": "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z" + } + } + }, + "object-group": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f247", + "label": "Object Group", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z" + } + } + }, + "object-ungroup": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f248", + "label": "Object Ungroup", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z" + } + } + }, + "odnoklassniki": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f263", + "label": "Odnoklassniki", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z" + } + } + }, + "odnoklassniki-square": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f264", + "label": "Odnoklassniki Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z" + } + } + }, + "opencart": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f23d", + "label": "OpenCart", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z" + } + } + }, + "openid": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f19b", + "label": "OpenID", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z" + } + } + }, + "opera": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f26a", + "label": "Opera", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z" + } + } + }, + "optin-monster": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f23c", + "label": "Optin Monster", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z" + } + } + }, + "osi": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41a", + "label": "Open Source Initiative", + "svg": { + "brands": { + "last_modified": 1508771132272, + "raw": "", + "viewBox": [ + "0", + "0", + "495.8", + "512" + ], + "width": 495, + "height": 512, + "path": "M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z" + } + } + }, + "outdent": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f03b", + "label": "Outdent", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm208 144h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm192-128h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM4.687 267.313l96 95.984C110.734 373.348 128 366.224 128 351.984V160.008c0-14.329-17.325-21.304-27.313-11.313l-96 95.992c-6.249 6.248-6.249 16.378 0 22.626z" + } + } + }, + "page4": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d7", + "label": "page4 Corporation", + "sponsored": { + "label": "page4 Corporation", + "url": "https://en.page4.com/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z" + } + } + }, + "pagelines": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "leaf", + "leaves", + "tree", + "plant", + "eco", + "nature" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f18c", + "label": "Pagelines", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z" + } + } + }, + "paint-brush": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1fc", + "label": "Paint Brush", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M269.9 364.6c1.4 6.4 2.1 13 2.1 19.7 0 81.2-54.2 127.7-134.8 127.7C41.5 512 0 435.1 0 347.6c10.4 7.1 46.9 36.5 58.7 36.5 7 0 13-4 15.5-10.6 23.6-62.2 66.5-76.5 112.9-77.4 15.6 33.8 46.1 59.6 82.8 68.5zM460.6 0c-14.4 0-27.9 6.4-38.2 15.7C228.2 190 208 194.1 208 245.4c0 48.8 40.5 90.6 90.2 90.6 59 0 93.2-43.4 200.6-244.8 7-13.7 13.2-28.5 13.2-43.9C512 19.7 487.3 0 460.6 0z" + } + } + }, + "palfed": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d8", + "label": "Palfed", + "sponsored": { + "label": "PalFed", + "url": "https://www.palfed.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "560", + "512" + ], + "width": 560, + "height": 512, + "path": "M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z" + } + } + }, + "paper-plane": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f1d8", + "label": "Paper Plane", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z" + } + } + }, + "paperclip": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "attachment" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c6", + "label": "Paperclip", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z" + } + } + }, + "paragraph": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1dd", + "label": "paragraph", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M408 32H177.531C88.948 32 16.045 103.335 16 191.918 15.956 280.321 87.607 352 176 352v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h32v344c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h40c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24z" + } + } + }, + "paste": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "copy", + "clipboard" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ea", + "label": "Paste", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z" + } + } + }, + "patreon": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3d9", + "label": "Patreon", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z" + } + } + }, + "pause": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "wait" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f04c", + "label": "pause", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z" + } + } + }, + "pause-circle": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f28b", + "label": "Pause Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z" + } + } + }, + "paw": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "pet" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1b0", + "label": "Paw", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M85.231 330.958C36 330.958 0 273.792 0 231.5c0-28.292 16-58.042 49.538-58.042 49.231 0 85.231 57.458 85.231 99.75 0 28.292-15.692 57.75-49.538 57.75zm348 106.167c0 37.042-32 42.875-63.385 42.875-41.231 0-74.462-26.25-113.846-26.25-41.231 0-76.308 25.958-120.923 25.958-29.847 0-56.308-9.625-56.308-42.583C78.769 368 180.616 265.333 256 265.333s177.231 102.959 177.231 171.792zM182.462 203.792c-49.847 0-80-59.5-80-100.333C102.462 70.792 120.308 32 160 32c50.154 0 80 59.5 80 100.333 0 32.667-17.846 71.459-57.538 71.459zM272 132.333C272 91.5 301.846 32 352 32c39.692 0 57.539 38.792 57.539 71.458 0 40.833-30.154 100.333-80.001 100.333C289.846 203.792 272 165 272 132.333zM512 231.5c0 42.292-36 99.458-85.231 99.458-33.847 0-49.538-29.458-49.538-57.75 0-42.291 35.999-99.75 85.231-99.75C496 173.458 512 203.208 512 231.5z" + } + } + }, + "paypal": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1ed", + "label": "Paypal", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z" + } + } + }, + "pen-square": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "write", + "edit", + "update", + "pencil-square" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f14b", + "label": "Pen Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z" + } + } + }, + "pencil-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "write", + "edit", + "update", + "pencil" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f303", + "label": "Alternate Pencil", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z" + } + } + }, + "percent": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f295", + "label": "Percent", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z" + } + } + }, + "periscope": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3da", + "label": "Periscope", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z" + } + } + }, + "phabricator": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3db", + "label": "Phabricator", + "sponsored": { + "label": "Phabricator", + "url": "http://phacility.com/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z" + } + } + }, + "phoenix-framework": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3dc", + "label": "Phoenix Framework", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z" + } + } + }, + "phone": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "call", + "voice", + "number", + "support", + "earphone", + "telephone" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f095", + "label": "Phone", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M493.397 24.615l-104-23.997c-11.314-2.611-22.879 3.252-27.456 13.931l-48 111.997a24 24 0 0 0 6.862 28.029l60.617 49.596c-35.973 76.675-98.938 140.508-177.249 177.248l-49.596-60.616a24 24 0 0 0-28.029-6.862l-111.997 48C3.873 366.516-1.994 378.08.618 389.397l23.997 104C27.109 504.204 36.748 512 48 512c256.087 0 464-207.532 464-464 0-11.176-7.714-20.873-18.603-23.385z" + } + } + }, + "phone-square": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "call", + "voice", + "number", + "support", + "telephone" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f098", + "label": "Phone Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z" + } + } + }, + "phone-volume": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "telephone", + "volume-control-phone" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2a0", + "label": "Phone Volume", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z" + } + } + }, + "pied-piper": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2ae", + "label": "Pied Piper Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z" + } + } + }, + "pied-piper-alt": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a8", + "label": "Alternate Pied Piper Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z" + } + } + }, + "pied-piper-pp": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a7", + "label": "Pied Piper PP Logo (Old)", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z" + } + } + }, + "pinterest": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f0d2", + "label": "Pinterest", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z" + } + } + }, + "pinterest-p": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f231", + "label": "Pinterest P", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z" + } + } + }, + "pinterest-square": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f0d3", + "label": "Pinterest Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z" + } + } + }, + "plane": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "travel", + "trip", + "location", + "destination", + "airplane", + "fly", + "mode" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f072", + "label": "plane", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M472 200H360.211L256.013 5.711A12 12 0 0 0 245.793 0h-57.787c-7.85 0-13.586 7.413-11.616 15.011L209.624 200H99.766l-34.904-58.174A12 12 0 0 0 54.572 136H12.004c-7.572 0-13.252 6.928-11.767 14.353l21.129 105.648L.237 361.646c-1.485 7.426 4.195 14.354 11.768 14.353l42.568-.002c4.215 0 8.121-2.212 10.289-5.826L99.766 312h109.858L176.39 496.989c-1.97 7.599 3.766 15.011 11.616 15.011h57.787a12 12 0 0 0 10.22-5.711L360.212 312H472c57.438 0 104-25.072 104-56s-46.562-56-104-56z" + } + } + }, + "play": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "start", + "playing", + "music", + "sound" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f04b", + "label": "play", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" + } + } + }, + "play-circle": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "start", + "playing" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f144", + "label": "Play Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z" + } + } + }, + "playstation": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3df", + "label": "PlayStation", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z" + } + } + }, + "plug": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "power", + "connect" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1e6", + "label": "Plug", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z" + } + } + }, + "plus": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "add", + "new", + "create", + "expand" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f067", + "label": "plus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z" + } + } + }, + "plus-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "add", + "new", + "create", + "expand" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f055", + "label": "Plus Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" + } + } + }, + "plus-square": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "add", + "new", + "create", + "expand" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0fe", + "label": "Plus Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" + } + } + }, + "podcast": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2ce", + "label": "Podcast", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z" + } + } + }, + "pound-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "gbp", + "gbp" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f154", + "label": "Pound Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z" + } + } + }, + "power-off": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "on" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f011", + "label": "Power Off", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z" + } + } + }, + "print": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f02f", + "label": "print", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 192h-16V81.941a24 24 0 0 0-7.029-16.97L383.029 7.029A24 24 0 0 0 366.059 0H88C74.745 0 64 10.745 64 24v168H48c-26.51 0-48 21.49-48 48v132c0 6.627 5.373 12 12 12h52v104c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V384h52c6.627 0 12-5.373 12-12V240c0-26.51-21.49-48-48-48zm-80 256H128v-96h256v96zM128 224V64h192v40c0 13.2 10.8 24 24 24h40v96H128zm304 72c-13.254 0-24-10.746-24-24s10.746-24 24-24 24 10.746 24 24-10.746 24-24 24z" + } + } + }, + "product-hunt": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f288", + "label": "Product Hunt", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z" + } + } + }, + "pushed": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e1", + "label": "Pushed", + "sponsored": { + "label": "Pushed", + "url": "https://pushed.co" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "432", + "512" + ], + "width": 432, + "height": 512, + "path": "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z" + } + } + }, + "puzzle-piece": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "addon", + "add-on", + "section" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f12e", + "label": "Puzzle Piece", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z" + } + } + }, + "python": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e2", + "label": "Python", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z" + } + } + }, + "qq": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d6", + "label": "QQ", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z" + } + } + }, + "qrcode": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "scan" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f029", + "label": "qrcode", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z" + } + } + }, + "question": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "help", + "information", + "unknown", + "support" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f128", + "label": "Question", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z" + } + } + }, + "question-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "help", + "information", + "unknown", + "support" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f059", + "label": "Question Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z" + } + } + }, + "quora": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2c4", + "label": "Quora", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z" + } + } + }, + "quote-left": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f10d", + "label": "quote-left", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 432V304C0 166.982 63.772 67.676 193.827 32.828 209.052 28.748 224 40.265 224 56.027v33.895c0 10.057-6.228 19.133-15.687 22.55C142.316 136.312 104 181.946 104 256h72c26.51 0 48 21.49 48 48v128c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm336 48h128c26.51 0 48-21.49 48-48V304c0-26.51-21.49-48-48-48h-72c0-74.054 38.316-119.688 104.313-143.528C505.772 109.055 512 99.979 512 89.922V56.027c0-15.762-14.948-27.279-30.173-23.199C351.772 67.676 288 166.982 288 304v128c0 26.51 21.49 48 48 48z" + } + } + }, + "quote-right": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f10e", + "label": "quote-right", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 80v128c0 137.018-63.772 236.324-193.827 271.172-15.225 4.08-30.173-7.437-30.173-23.199v-33.895c0-10.057 6.228-19.133 15.687-22.55C369.684 375.688 408 330.054 408 256h-72c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h128c26.51 0 48 21.49 48 48zM176 32H48C21.49 32 0 53.49 0 80v128c0 26.51 21.49 48 48 48h72c0 74.054-38.316 119.688-104.313 143.528C6.228 402.945 0 412.021 0 422.078v33.895c0 15.762 14.948 27.279 30.173 23.199C160.228 444.324 224 345.018 224 208V80c0-26.51-21.49-48-48-48z" + } + } + }, + "random": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sort", + "shuffle" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f074", + "label": "random", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z" + } + } + }, + "ravelry": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2d9", + "label": "Ravelry", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z" + } + } + }, + "react": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41b", + "label": "React", + "svg": { + "brands": { + "last_modified": 1508771132272, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8" + } + } + }, + "rebel": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d0", + "label": "Rebel Alliance", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z" + } + } + }, + "recycle": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1b8", + "label": "Recycle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z" + } + } + }, + "red-river": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e3", + "label": "red river", + "sponsored": { + "label": "red river", + "url": "https://river.red" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z" + } + } + }, + "reddit": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a1", + "label": "reddit Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z" + } + } + }, + "reddit-alien": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f281", + "label": "reddit Alien", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z" + } + } + }, + "reddit-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a2", + "label": "reddit Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z" + } + } + }, + "redo": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "forward", + "repeat", + "repeat" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f01e", + "label": "Redo", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512.333", + "512" + ], + "width": 512, + "height": 512, + "path": "M500.333 0h-47.411c-6.853 0-12.314 5.729-11.986 12.574l3.966 82.759C399.416 41.899 331.672 8 256.001 8 119.34 8 7.899 119.526 8 256.187 8.101 393.068 119.096 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-33.971-33.971c-4.466-4.466-11.64-4.717-16.38-.543C341.308 415.448 300.606 432 256 432c-97.267 0-176-78.716-176-176 0-97.267 78.716-176 176-176 60.892 0 114.506 30.858 146.099 77.8l-101.525-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12z" + } + } + }, + "redo-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "forward", + "repeat" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2f9", + "label": "Alternate Redo", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z" + } + } + }, + "registered": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f25d", + "label": "Registered Trademark", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z" + } + } + }, + "rendact": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e4", + "label": "Rendact", + "sponsored": { + "label": "Rendact", + "url": "https://rendact.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z" + } + } + }, + "renren": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f18b", + "label": "Renren", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z" + } + } + }, + "reply": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f3e5", + "label": "Reply", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z" + } + } + }, + "reply-all": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f122", + "label": "reply-all", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z" + } + } + }, + "replyd": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e6", + "label": "replyd", + "sponsored": { + "label": "replyd" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z" + } + } + }, + "resolving": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e7", + "label": "Resolving", + "sponsored": { + "label": "Resolving", + "url": "https://resolving.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z" + } + } + }, + "retweet": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "refresh", + "reload", + "share" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f079", + "label": "Retweet", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z" + } + } + }, + "road": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "street" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f018", + "label": "road", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M567.3 383.6L429.9 78.2C426 69.5 417.4 64 408 64h-96.1l1.9 18.8c.7 7.1-4.8 13.2-11.9 13.2H274c-7.1 0-12.7-6.2-11.9-13.2L264 64h-96c-9.4 0-18 5.5-21.9 14.2L8.7 383.6C3.2 395.8 0 409.6 0 424c0 13.3 10.7 24 24 24h213.6c-7.1 0-12.7-6.2-11.9-13.2l10.8-104c.6-6.1 5.8-10.8 11.9-10.8h79.2c6.1 0 11.3 4.6 11.9 10.8l10.8 104c.7 7.1-4.8 13.2-11.9 13.2H552c13.2 0 24-10.7 24-24 0-13.9-3-27.7-8.7-40.4zM254.7 154.8l3.3-32c.6-6.1 5.8-10.8 11.9-10.8h36.2c6.1 0 11.3 4.6 11.9 10.8l3.3 32c.7 7.1-4.8 13.2-11.9 13.2h-42.8c-7.1 0-12.7-6.2-11.9-13.2zM321.8 288h-67.6c-7.1 0-12.7-6.2-11.9-13.2l7.4-72c.6-6.1 5.8-10.8 11.9-10.8h52.7c6.1 0 11.3 4.6 11.9 10.8l7.4 72c.9 7-4.7 13.2-11.8 13.2z" + } + } + }, + "rocket": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "app" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f135", + "label": "rocket", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M505.1 19.1C503.8 13 499 8.2 492.9 6.9 460.7 0 435.5 0 410.4 0 307.2 0 245.3 55.2 199.1 128H94.9c-18.2 0-34.8 10.3-42.9 26.5L2.6 253.3c-8 16 3.6 34.7 21.5 34.7h95.1c-5.9 12.8-11.9 25.5-18 37.7-3.1 6.2-1.9 13.6 3 18.5l63.6 63.6c4.9 4.9 12.3 6.1 18.5 3 12.2-6.1 24.9-12 37.7-17.9V488c0 17.8 18.8 29.4 34.7 21.5l98.7-49.4c16.3-8.1 26.5-24.8 26.5-42.9V312.8c72.6-46.3 128-108.4 128-211.1.1-25.2.1-50.4-6.8-82.6zM400 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z" + } + } + }, + "rocketchat": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e8", + "label": "Rocket.Chat", + "sponsored": { + "label": "Rocket.Chat", + "url": "https://rocket.chat" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z" + } + } + }, + "rockrms": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3e9", + "label": "Rockrms", + "sponsored": { + "label": "Rock RMS", + "url": "http://rockrms.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z" + } + } + }, + "rss": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "blog" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f09e", + "label": "rss", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z" + } + } + }, + "rss-square": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "feed", + "blog" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f143", + "label": "RSS Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z" + } + } + }, + "ruble-sign": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "rub", + "rub" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f158", + "label": "Ruble Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z" + } + } + }, + "rupee-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "indian", + "inr" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f156", + "label": "Indian Rupee Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z" + } + } + }, + "safari": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "browser" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f267", + "label": "Safari", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z" + } + } + }, + "sass": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41e", + "label": "Sass", + "svg": { + "brands": { + "last_modified": 1508771132272, + "raw": "", + "viewBox": [ + "0", + "0", + "640.4", + "512" + ], + "width": 640, + "height": 512, + "path": "M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z" + } + } + }, + "save": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "floppy", + "floppy-o" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0c7", + "label": "Save", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z" + } + } + }, + "schlix": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ea", + "label": "SCHLIX", + "sponsored": { + "label": "SCHLIX", + "url": "http://schlix.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z" + } + } + }, + "scribd": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f28a", + "label": "Scribd", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z" + } + } + }, + "search": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "magnify", + "zoom", + "enlarge", + "bigger" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f002", + "label": "Search", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z" + } + } + }, + "search-minus": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "magnify", + "minify", + "zoom", + "smaller" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f010", + "label": "Search Minus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z" + } + } + }, + "search-plus": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "magnify", + "zoom", + "enlarge", + "bigger" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f00e", + "label": "Search Plus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z" + } + } + }, + "searchengin": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3eb", + "label": "Searchengin", + "sponsored": { + "label": "SearchEng.in", + "url": "http://searcheng.in" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "460", + "512" + ], + "width": 460, + "height": 512, + "path": "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z" + } + } + }, + "sellcast": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "eercast" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f2da", + "label": "Sellcast", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z" + } + } + }, + "sellsy": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f213", + "label": "Sellsy", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z" + } + } + }, + "server": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f233", + "label": "Server", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z" + } + } + }, + "servicestack": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ec", + "label": "Servicestack", + "sponsored": { + "label": "ServiceStack", + "url": "https://servicestack.net" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z" + } + } + }, + "share": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f064", + "label": "Share", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z" + } + } + }, + "share-alt": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1e0", + "label": "Alternate Share", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z" + } + } + }, + "share-alt-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1e1", + "label": "Alternate Share Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z" + } + } + }, + "share-square": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "social", + "send" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f14d", + "label": "Share Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z" + } + } + }, + "shekel-sign": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ils", + "ils" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f20b", + "label": "Shekel Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M170.12 96H80v372c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V44c0-6.627 5.373-12 12-12h168.36C265.48 32 325 89.6 325 175.071V359c0 6.627-5.373 12-12 12h-44c-13.255 0-24-10.745-24-24V170.323C245 125.11 216.839 96 170.12 96zM436 32h-56c-6.627 0-12 5.373-12 12v372h-90.12c-46.72 0-74.88-29.11-74.88-74.323V165c0-13.255-10.745-24-24-24h-44c-6.627 0-12 5.373-12 12v183.929C123 422.4 182.52 480 267.64 480H436c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12z" + } + } + }, + "shield-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "shield" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3ed", + "label": "Alternate Shield", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M496 128c0 221.282-135.934 344.645-221.539 380.308a48 48 0 0 1-36.923 0C130.495 463.713 16 326.487 16 128a48 48 0 0 1 29.539-44.308l192-80a48 48 0 0 1 36.923 0l192 80A48 48 0 0 1 496 128zM256 446.313l.066.034c93.735-46.689 172.497-156.308 175.817-307.729L256 65.333v380.98z" + } + } + }, + "ship": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "boat", + "sea" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f21a", + "label": "Ship", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z" + } + } + }, + "shirtsinbulk": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f214", + "label": "Shirts in Bulk", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z" + } + } + }, + "shopping-bag": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f290", + "label": "Shopping Bag", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z" + } + } + }, + "shopping-basket": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f291", + "label": "Shopping Basket", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z" + } + } + }, + "shopping-cart": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "checkout", + "buy", + "purchase", + "payment" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f07a", + "label": "shopping-cart", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z" + } + } + }, + "shower": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2cc", + "label": "Shower", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z" + } + } + }, + "sign-in-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "enter", + "join", + "log in", + "login", + "sign up", + "sign in", + "signin", + "signup", + "arrow", + "sign-in" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2f6", + "label": "Alernate Sign In", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z" + } + } + }, + "sign-language": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2a7", + "label": "Sign Language", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z" + } + } + }, + "sign-out-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "log out", + "logout", + "leave", + "exit", + "arrow", + "sign-out" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2f5", + "label": "Alernate Sign Out", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z" + } + } + }, + "signal": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "graph", + "bars" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f012", + "label": "signal", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M36 384h56c6.6 0 12 5.4 12 12v104c0 6.6-5.4 12-12 12H36c-6.6 0-12-5.4-12-12V396c0-6.6 5.4-12 12-12zm116-36v152c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V348c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-80v232c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V268c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-112v344c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V156c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zM536 12v488c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12z" + } + } + }, + "simplybuilt": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f215", + "label": "SimplyBuilt", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z" + } + } + }, + "sistrix": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3ee", + "label": "SISTRIX", + "sponsored": { + "label": "SISTRIX", + "url": "https://www.sistrix.de/" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z" + } + } + }, + "sitemap": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "directory", + "hierarchy", + "organization" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0e8", + "label": "Sitemap", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M616 320h-48v-48c0-22.056-17.944-40-40-40H344v-40h48c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h48v40H112c-22.056 0-40 17.944-40 40v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24z" + } + } + }, + "skyatlas": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f216", + "label": "skyatlas", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z" + } + } + }, + "skype": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f17e", + "label": "Skype", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z" + } + } + }, + "slack": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "hashtag", + "anchor", + "hash" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f198", + "label": "Slack Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z" + } + } + }, + "slack-hash": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "hashtag", + "anchor", + "hash" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f3ef", + "label": "Slack Hashtag", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z" + } + } + }, + "sliders-h": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "settings", + "sliders" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1de", + "label": "Horizontal Sliders", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 80v40c0 6.6-5.4 12-12 12H160v8c0 13.3-10.7 24-24 24h-16c-13.3 0-24-10.7-24-24v-8H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h84v-8c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v8h404c6.6 0 12 5.4 12 12zm-12 148h-84v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h404v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12zm0 160H288v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h212v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h276c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12z" + } + } + }, + "slideshare": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1e7", + "label": "Slideshare", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z" + } + } + }, + "smile": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "face", + "emoticon", + "happy", + "approve", + "satisfied", + "rating" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f118", + "label": "Smile", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-122.526 75.34c11.479-17.755-15.349-35.194-26.873-17.374-53.418 82.627-143.71 82.681-197.164 0-11.502-17.79-38.364-.401-26.873 17.374 66.014 102.107 184.795 102.265 250.91 0zM108 192c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm195.372 182.219c18.819-25.592-19.856-54.017-38.67-28.438-50.135 68.177-135.229 68.18-185.367 0-18.828-25.601-57.478 2.861-38.67 28.438 69.298 94.231 193.323 94.351 262.707 0z" + } + } + }, + "snapchat": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2ab", + "label": "Snapchat", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z" + } + } + }, + "snapchat-ghost": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2ac", + "label": "Snapchat Ghost", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z" + } + } + }, + "snapchat-square": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2ad", + "label": "Snapchat Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z" + } + } + }, + "snowflake": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2dc", + "label": "Snowflake", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M444.816 301.639a24.12 24.12 0 0 0 2.661-16.978c-2.725-12.966-15.339-21.245-28.174-18.492l-87.407 25.046L264 256l67.896-35.215 87.407 25.046c12.835 2.753 25.449-5.526 28.174-18.492 2.725-12.966-5.471-25.708-18.305-28.461l-47.477-7.137 53.077-30.956c11.363-6.627 15.257-21.306 8.696-32.785-6.561-11.479-21.091-15.412-32.454-8.785l-53.077 30.956 17.621-45.104c4.057-12.606-2.768-26.146-15.247-30.245-12.478-4.099-25.883 2.797-29.94 15.402l-22.232 88.99-60.38 35.215V144l65.175-63.945c8.778-9.852 7.987-25.027-1.766-33.894-9.753-8.867-24.775-8.068-33.552 1.784l-29.857 37.967V24c0-13.255-10.637-24-23.758-24s-23.758 10.745-23.758 24v61.912l-29.857-37.967c-8.779-9.852-23.799-10.652-33.552-1.784-9.753 8.867-10.543 24.042-1.766 33.894L200.242 144v70.431l-60.38-35.215-22.232-88.99c-4.057-12.605-17.462-19.501-29.94-15.402-12.478 4.099-19.304 17.64-15.247 30.245l17.62 45.104-53.077-30.956c-11.363-6.627-25.893-2.694-32.454 8.785s-2.667 26.157 8.696 32.785l53.077 30.956-47.477 7.137C5.993 201.634-2.203 214.375.523 227.341c2.725 12.965 15.339 21.245 28.174 18.492l87.407-25.046L184 256l-67.896 35.215-87.406-25.045c-12.835-2.753-25.449 5.526-28.174 18.492-2.725 12.967 5.47 25.708 18.305 28.461l47.477 7.137-53.077 30.956C1.866 357.843-2.027 372.521 4.533 384s21.091 15.412 32.454 8.785l53.077-30.956-17.62 45.104a24.157 24.157 0 0 0 2.022 19.428c2.831 4.953 7.416 8.909 13.224 10.816 12.478 4.099 25.883-2.797 29.94-15.402l22.232-88.99 60.38-35.215V368l-65.175 63.945c-8.778 9.852-7.987 25.027 1.766 33.894 9.754 8.868 24.774 8.068 33.552-1.784l29.857-37.967V488c0 13.255 10.637 24 23.758 24s23.758-10.745 23.758-24v-61.912l29.857 37.967A23.59 23.59 0 0 0 295.282 472a23.534 23.534 0 0 0 15.885-6.161c9.753-8.867 10.544-24.042 1.766-33.894L247.758 368v-70.431l60.38 35.215 22.232 88.99c4.057 12.605 17.462 19.501 29.94 15.402 12.479-4.099 19.304-17.64 15.247-30.245l-17.621-45.104 53.077 30.956c11.363 6.627 25.893 2.694 32.454-8.785s2.667-26.157-8.696-32.785l-53.077-30.956 47.477-7.137c6.86-1.469 12.394-5.793 15.645-11.481z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M438.237 355.927l-66.574-38.54 59.448-10.327c5.846-1.375 10.609-5.183 13.458-10.13 2.48-4.307 3.506-9.478 2.524-14.651-2.11-11.115-12.686-18.039-23.621-15.467l-85.423 31.115L255.914 256l82.136-41.926 85.423 31.115c10.936 2.572 21.512-4.352 23.621-15.467 2.111-11.115-5.046-22.209-15.981-24.781l-59.448-10.327 66.573-38.54c9.54-5.523 12.615-18.092 6.867-28.074-5.748-9.982-18.14-13.596-27.68-8.074l-66.574 38.54 20.805-56.787c3.246-10.782-2.758-22.542-13.413-26.268-10.654-3.725-21.922 1.997-25.168 12.779l-15.838 89.735-72.423 41.926V136l69.585-58.621c7.689-8.21 6.997-20.856-1.548-28.245-8.545-7.391-21.705-6.723-29.394 1.486l-38.644 46.46V20c0-11.046-9.318-20-20.813-20s-20.813 8.954-20.813 20v77.08l-38.644-46.46c-7.689-8.21-20.849-8.876-29.394-1.486-8.544 7.389-9.236 20.035-1.547 28.245L203.187 136v83.853l-72.423-41.926-15.838-89.736c-3.247-10.782-14.515-16.504-25.169-12.779-10.656 3.725-16.659 15.486-13.413 26.268l20.805 56.787-66.573-38.54c-9.54-5.523-21.933-1.908-27.68 8.074s-2.673 22.551 6.867 28.074l66.574 38.54-59.449 10.328C5.953 207.515-1.202 218.609.907 229.724c2.11 11.114 12.686 18.038 23.622 15.466l85.422-31.115L192.086 256l-82.136 41.926-85.423-31.115c-10.936-2.572-21.511 4.352-23.622 15.466-2.109 11.113 5.046 22.209 15.981 24.781l59.449 10.328-66.574 38.54C.223 361.449-2.852 374.018 2.896 384s18.14 13.597 27.68 8.074l66.574-38.54-20.805 56.786c-1.735 5.764-.828 11.805 2.02 16.751 2.48 4.307 6.433 7.784 11.392 9.517 10.655 3.725 21.923-1.997 25.169-12.779l15.838-89.736 72.423-41.926V376l-69.585 58.621c-7.69 8.21-6.997 20.855 1.547 28.245 8.544 7.388 21.705 6.723 29.394-1.487l38.644-46.46V492c0 11.046 9.318 20 20.813 20s20.813-8.954 20.813-20v-77.081l38.644 46.46c4.111 4.389 9.782 6.621 15.478 6.621 4.96 0 9.939-1.694 13.916-5.134 8.545-7.39 9.237-20.035 1.548-28.245L244.813 376v-83.853l72.423 41.926 15.838 89.736c3.246 10.782 14.514 16.504 25.168 12.779 10.653-3.726 16.659-15.487 13.412-26.268l-20.805-56.787 66.574 38.54c9.54 5.523 21.933 1.908 27.68-8.074 5.749-9.981 2.675-22.55-6.866-28.072z" + } + } + }, + "sort": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "order" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0dc", + "label": "Sort", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z" + } + } + }, + "sort-alpha-down": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sort-alpha-asc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f15d", + "label": "Sort Alpha Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zm119.075-180.007A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z" + } + } + }, + "sort-alpha-up": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sort-alpha-desc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f15e", + "label": "Sort Alpha Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zm301.671 98.621A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z" + } + } + }, + "sort-amount-down": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sort-amount-asc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f160", + "label": "Sort Amount Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z" + } + } + }, + "sort-amount-up": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sort-amount-desc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f161", + "label": "Sort Amount Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z" + } + } + }, + "sort-down": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow", + "descending", + "sort-desc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0dd", + "label": "Sort Down (Descending)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z" + } + } + }, + "sort-numeric-down": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "numbers", + "sort-numeric-asc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f162", + "label": "Sort Numeric Down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM175.984 368H128V48c0-8.837-7.163-16-16-16H80c-8.837 0-16 7.163-16 16v320H16.019c-14.212 0-21.384 17.244-11.314 27.314l79.981 80.002c6.245 6.245 16.38 6.247 22.627 0l79.984-80.002c10.05-10.05 2.928-27.314-11.313-27.314z" + } + } + }, + "sort-numeric-up": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "numbers", + "sort-numeric-desc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f163", + "label": "Sort Numeric Up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM16.016 144H64v320c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144h47.981c14.212 0 21.384-17.244 11.314-27.314l-79.981-80.002c-6.245-6.245-16.38-6.247-22.627 0L4.702 116.686C-5.347 126.736 1.775 144 16.016 144z" + } + } + }, + "sort-up": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "arrow", + "ascending", + "sort-asc" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0de", + "label": "Sort Up (Ascending)", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z" + } + } + }, + "soundcloud": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1be", + "label": "SoundCloud", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z" + } + } + }, + "space-shuttle": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f197", + "label": "Space Shuttle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z" + } + } + }, + "speakap": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f3", + "label": "Speakap", + "sponsored": { + "label": "Speakap", + "url": "https://speakap.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z" + } + } + }, + "spinner": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "loading", + "progress" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f110", + "label": "Spinner", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z" + } + } + }, + "spotify": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1bc", + "label": "Spotify", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z" + } + } + }, + "square": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "block", + "box" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f0c8", + "label": "Square", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z" + } + } + }, + "stack-exchange": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f18d", + "label": "Stack Exchange", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z" + } + } + }, + "stack-overflow": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f16c", + "label": "Stack Overflow", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z" + } + } + }, + "star": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "award", + "achievement", + "night", + "rating", + "score", + "favorite" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f005", + "label": "Star", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z" + } + } + }, + "star-half": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "award", + "achievement", + "rating", + "score", + "star-half-empty", + "star-half-full" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f089", + "label": "star-half", + "svg": { + "solid": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z" + }, + "regular": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z" + } + } + }, + "staylinked": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f5", + "label": "StayLinked", + "sponsored": { + "label": "StayLinked", + "url": "http://www.staylinked.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "440", + "512" + ], + "width": 440, + "height": 512, + "path": "M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7" + } + } + }, + "steam": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1b6", + "label": "Steam", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z" + } + } + }, + "steam-square": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1b7", + "label": "Steam Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z" + } + } + }, + "steam-symbol": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f6", + "label": "Steam Symbol", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z" + } + } + }, + "step-backward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "rewind", + "previous", + "beginning", + "start", + "first" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f048", + "label": "step-backward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z" + } + } + }, + "step-forward": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "next", + "end", + "last" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f051", + "label": "step-forward", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z" + } + } + }, + "stethoscope": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f0f1", + "label": "Stethoscope", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 176c0-35.659-29.164-64.507-64.941-63.993-34.21.492-62.296 28.357-63.043 62.562-.531 24.282 12.476 45.558 31.984 56.848V344c0 57.346-50.243 104-112 104-60.039 0-109.189-44.096-111.878-99.24C265.005 333.847 320 269.225 320 192V36.584c0-11.44-8.075-21.29-19.293-23.534L237.81.471c-12.997-2.599-25.641 5.83-28.241 18.827l-3.138 15.689c-2.6 12.997 5.83 25.641 18.827 28.241L256 69.376v121.4c0 52.852-42.203 96.707-95.053 97.22C107.58 288.513 64 245.25 64 192V69.376l30.742-6.149c12.997-2.6 21.427-15.243 18.827-28.241l-3.138-15.689C107.831 6.3 95.188-2.129 82.19.471L19.293 13.05C8.075 15.294 0 25.144 0 36.584V192c0 77.295 55.096 141.961 128.076 156.798C130.747 439.223 208.634 512 304 512c97.047 0 176-75.364 176-168V231.417c19.124-11.068 32-31.732 32-55.417zm-64-16c8.822 0 16 7.178 16 16s-7.178 16-16 16-16-7.178-16-16 7.178-16 16-16z" + } + } + }, + "sticker-mule": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f7", + "label": "Sticker Mule", + "sponsored": { + "label": "Sticker Mule", + "url": "https://stickermule.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4" + } + } + }, + "sticky-note": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f249", + "label": "Sticky Note", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z" + } + } + }, + "stop": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "block", + "box", + "square" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f04d", + "label": "stop", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z" + } + } + }, + "stop-circle": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f28d", + "label": "Stop Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z" + } + } + }, + "strava": { + "changes": [ + "5.0.0", + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f428", + "label": "Strava", + "svg": { + "brands": { + "last_modified": 1512768505417, + "raw": "", + "viewBox": [ + "0", + "0", + "369.2", + "512" + ], + "width": 369, + "height": 512, + "path": "M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z" + } + } + }, + "street-view": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "map" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f21d", + "label": "Street View", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M192 64c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zm112 80h-11.36c-22.711 10.443-49.59 10.894-73.28 0H208c-26.51 0-48 21.49-48 48v104c0 13.255 10.745 24 24 24h16v104c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V320h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48zm85.642 189.152a72.503 72.503 0 0 1-29.01 27.009C391.133 365.251 480 385.854 480 416c0 46.304-167.656 64-224 64-70.303 0-224-20.859-224-64 0-30.123 88.361-50.665 119.367-55.839a72.516 72.516 0 0 1-29.01-27.009C74.959 343.395 0 367.599 0 416c0 77.111 178.658 96 256 96 77.249 0 256-18.865 256-96 0-48.403-74.967-72.606-122.358-82.848z" + } + } + }, + "strikethrough": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f0cc", + "label": "Strikethrough", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M496 288H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h480c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16zm-214.666 16c27.258 12.937 46.524 28.683 46.524 56.243 0 33.108-28.977 53.676-75.621 53.676-32.325 0-76.874-12.08-76.874-44.271V368c0-8.837-7.164-16-16-16H113.75c-8.836 0-16 7.163-16 16v19.204c0 66.845 77.717 101.82 154.487 101.82 88.578 0 162.013-45.438 162.013-134.424 0-19.815-3.618-36.417-10.143-50.6H281.334zm-30.952-96c-32.422-13.505-56.836-28.946-56.836-59.683 0-33.92 30.901-47.406 64.962-47.406 42.647 0 64.962 16.593 64.962 32.985V136c0 8.837 7.164 16 16 16h45.613c8.836 0 16-7.163 16-16v-30.318c0-52.438-71.725-79.875-142.575-79.875-85.203 0-150.726 40.972-150.726 125.646 0 22.71 4.665 41.176 12.777 56.547h129.823z" + } + } + }, + "stripe": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f429", + "label": "Stripe", + "svg": { + "brands": { + "last_modified": 1510848563151, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7" + } + } + }, + "stripe-s": { + "changes": [ + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f42a", + "label": "Stripe S", + "svg": { + "brands": { + "last_modified": 1512768505417, + "raw": "", + "viewBox": [ + "0", + "0", + "362.3", + "512" + ], + "width": 362, + "height": 512, + "path": "M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9" + } + } + }, + "studiovinari": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f8", + "label": "Studio Vinari", + "sponsored": { + "label": "Studio Vinari", + "url": "https://studiovinari.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z" + } + } + }, + "stumbleupon": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a4", + "label": "StumbleUpon Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z" + } + } + }, + "stumbleupon-circle": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1a3", + "label": "StumbleUpon Circle", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z" + } + } + }, + "subscript": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f12c", + "label": "subscript", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M395.198 416c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 256c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 96H16C7.163 96 0 88.837 0 80V48c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035A15.999 15.999 0 0 1 204.226 32H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 256H272z" + } + } + }, + "subway": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f239", + "label": "Subway", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z" + } + } + }, + "suitcase": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "trip", + "luggage", + "travel", + "move", + "baggage" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0f2", + "label": "Suitcase", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352z" + } + } + }, + "sun": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "weather", + "contrast", + "lighter", + "brighten", + "day" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f185", + "label": "Sun", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M274.835 12.646l25.516 62.393c4.213 10.301 16.671 14.349 26.134 8.492l57.316-35.479c15.49-9.588 34.808 4.447 30.475 22.142l-16.03 65.475c-2.647 10.81 5.053 21.408 16.152 22.231l67.224 4.987c18.167 1.348 25.546 24.057 11.641 35.826L441.81 242.26c-8.495 7.19-8.495 20.289 0 27.479l51.454 43.548c13.906 11.769 6.527 34.478-11.641 35.826l-67.224 4.987c-11.099.823-18.799 11.421-16.152 22.231l16.03 65.475c4.332 17.695-14.986 31.73-30.475 22.142l-57.316-35.479c-9.463-5.858-21.922-1.81-26.134 8.492l-25.516 62.393c-6.896 16.862-30.774 16.862-37.67 0l-25.516-62.393c-4.213-10.301-16.671-14.349-26.134-8.492l-57.317 35.479c-15.49 9.588-34.808-4.447-30.475-22.142l16.03-65.475c2.647-10.81-5.053-21.408-16.152-22.231l-67.224-4.987c-18.167-1.348-25.546-24.057-11.641-35.826L70.19 269.74c8.495-7.19 8.495-20.289 0-27.479l-51.454-43.548c-13.906-11.769-6.527-34.478 11.641-35.826l67.224-4.987c11.099-.823 18.799-11.421 16.152-22.231l-16.03-65.475c-4.332-17.695 14.986-31.73 30.475-22.142l57.317 35.479c9.463 5.858 21.921 1.81 26.134-8.492l25.516-62.393c6.896-16.861 30.774-16.861 37.67 0zM392 256c0-74.991-61.01-136-136-136-74.991 0-136 61.009-136 136s61.009 136 136 136c74.99 0 136-61.009 136-136zm-32 0c0 57.346-46.654 104-104 104s-104-46.654-104-104 46.654-104 104-104 104 46.654 104 104z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M220.116 487.936l-20.213-49.425a3.992 3.992 0 0 0-5.808-1.886l-45.404 28.104c-29.466 18.24-66.295-8.519-58.054-42.179l12.699-51.865a3.993 3.993 0 0 0-3.59-4.941l-53.251-3.951c-34.554-2.562-48.632-45.855-22.174-68.247L65.08 259.05a3.992 3.992 0 0 0 0-6.106l-40.76-34.497c-26.45-22.384-12.39-65.682 22.174-68.246l53.251-3.951a3.993 3.993 0 0 0 3.59-4.941L90.637 89.443c-8.239-33.656 28.581-60.42 58.054-42.179l45.403 28.104a3.993 3.993 0 0 0 5.808-1.887l20.213-49.425c13.116-32.071 58.638-32.081 71.758 0l20.212 49.424a3.994 3.994 0 0 0 5.809 1.887l45.403-28.104c29.464-18.236 66.297 8.513 58.054 42.179l-12.699 51.865a3.995 3.995 0 0 0 3.59 4.941l53.251 3.951c34.553 2.563 48.633 45.854 22.175 68.246l-40.76 34.497a3.993 3.993 0 0 0 0 6.107l40.76 34.496c26.511 22.441 12.322 65.689-22.175 68.247l-53.251 3.951a3.993 3.993 0 0 0-3.589 4.942l12.698 51.864c8.241 33.658-28.583 60.421-58.054 42.18l-45.403-28.104a3.994 3.994 0 0 0-5.809 1.887l-20.212 49.424c-13.159 32.178-58.675 31.993-71.757 0zm16.814-64.568l19.064 46.616 19.064-46.615c10.308-25.2 40.778-35.066 63.892-20.759l42.822 26.507-11.976-48.919c-6.475-26.444 12.38-52.339 39.487-54.349l50.226-3.726-38.444-32.536c-20.782-17.591-20.747-49.621.001-67.18l38.442-32.536-50.225-3.727c-27.151-2.015-45.95-27.948-39.488-54.349l11.978-48.919-42.823 26.507c-23.151 14.327-53.603 4.4-63.892-20.76l-19.064-46.615-19.064 46.617c-10.305 25.198-40.778 35.066-63.891 20.76l-42.823-26.508 11.977 48.918c6.474 26.446-12.381 52.338-39.488 54.35l-50.224 3.726 38.443 32.537c20.782 17.588 20.747 49.619 0 67.178L52.48 322.123l50.226 3.726c27.151 2.014 45.95 27.947 39.487 54.349l-11.977 48.919 42.823-26.507c23.188-14.355 53.622-4.352 63.891 20.758zM256 384c-70.58 0-128-57.421-128-128 0-70.58 57.42-128 128-128 70.579 0 128 57.42 128 128 0 70.579-57.421 128-128 128zm0-208c-44.112 0-80 35.888-80 80s35.888 80 80 80 80-35.888 80-80-35.888-80-80-80z" + } + } + }, + "superpowers": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2dd", + "label": "Superpowers", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z" + } + } + }, + "superscript": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "exponential" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f12b", + "label": "superscript", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M395.198 256c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 256H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035a16 16 0 0 1 13.598-7.567H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 416H272z" + } + } + }, + "supple": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3f9", + "label": "Supple", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z" + } + } + }, + "sync": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "reload", + "refresh", + "refresh" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f021", + "label": "Sync", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512.333", + "512" + ], + "width": 512, + "height": 512, + "path": "M440.935 12.574l3.966 82.766C399.416 41.904 331.674 8 256 8 134.813 8 33.933 94.924 12.296 209.824 10.908 217.193 16.604 224 24.103 224h49.084c5.57 0 10.377-3.842 11.676-9.259C103.407 137.408 172.931 80 256 80c60.893 0 114.512 30.856 146.104 77.801l-101.53-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12h-47.411c-6.853 0-12.315 5.729-11.987 12.574zM256 432c-60.895 0-114.517-30.858-146.109-77.805l101.868 4.871c6.845.327 12.573-5.134 12.573-11.986v-47.412c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12V500c0 6.627 5.373 12 12 12h47.385c6.863 0 12.328-5.745 11.985-12.599l-4.129-82.575C112.725 470.166 180.405 504 256 504c121.187 0 222.067-86.924 243.704-201.824 1.388-7.369-4.308-14.176-11.807-14.176h-49.084c-5.57 0-10.377 3.842-11.676 9.259C408.593 374.592 339.069 432 256 432z" + } + } + }, + "sync-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "reload", + "refresh" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2f1", + "label": "Alternate Sync", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z" + } + } + }, + "table": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "data", + "excel", + "spreadsheet" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ce", + "label": "table", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z" + } + } + }, + "tablet": { + "changes": [ + "3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ipad", + "device" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f10a", + "label": "tablet", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z" + } + } + }, + "tablet-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "tablet" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3fa", + "label": "Alternate Tablet", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z" + } + } + }, + "tachometer-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "tachometer" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3fd", + "label": "Alternate Tachometer", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M75.694 480a48.02 48.02 0 0 1-42.448-25.571C12.023 414.3 0 368.556 0 320 0 160.942 128.942 32 288 32s288 128.942 288 288c0 48.556-12.023 94.3-33.246 134.429A48.018 48.018 0 0 1 500.306 480H75.694zM512 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zM288 128c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32zM64 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm65.608-158.392c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm316.784 0c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm-87.078 31.534c-12.627-4.04-26.133 2.92-30.173 15.544l-45.923 143.511C250.108 322.645 224 350.264 224 384c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-19.773-8.971-37.447-23.061-49.187l45.919-143.498c4.039-12.625-2.92-26.133-15.544-30.173z" + } + } + }, + "tag": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "label" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f02b", + "label": "tag", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z" + } + } + }, + "tags": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "labels" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f02c", + "label": "tags", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z" + } + } + }, + "tasks": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "progress", + "loading", + "downloading", + "downloads", + "settings" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ae", + "label": "Tasks", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z" + } + } + }, + "taxi": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vehicle" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1ba", + "label": "Taxi", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M461.951 243.865l-21.816-87.268A79.885 79.885 0 0 0 362.522 96H352V56c0-13.255-10.745-24-24-24H184c-13.255 0-24 10.745-24 24v40h-10.522a79.885 79.885 0 0 0-77.612 60.597L50.05 243.865C25.515 252.823 8 276.366 8 304v48c0 20.207 9.374 38.214 24 49.943V456c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-54.057c14.626-11.729 24-29.737 24-49.943v-48c0-27.634-17.515-51.177-42.049-60.135zM149.478 160h213.045a15.975 15.975 0 0 1 15.522 12.12l16.97 67.88h-278.03l16.97-67.881A15.976 15.976 0 0 1 149.478 160zM132 336c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm320 0c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z" + } + } + }, + "telegram": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2c6", + "label": "Telegram", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "496", + "512" + ], + "width": 496, + "height": 512, + "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z" + } + } + }, + "telegram-plane": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f3fe", + "label": "Telegram Plane", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z" + } + } + }, + "tencent-weibo": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d5", + "label": "Tencent Weibo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z" + } + } + }, + "terminal": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "command", + "prompt", + "code" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f120", + "label": "Terminal", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z" + } + } + }, + "text-height": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f034", + "label": "text-height", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M16 32h288c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96h-54.761v320H232c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H88c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm475.308 4.685l79.995 80.001C581.309 126.693 574.297 144 559.99 144H512v224h48c15.639 0 20.635 17.991 11.313 27.314l-79.995 80.001c-6.247 6.247-16.381 6.245-22.626 0l-79.995-80.001C378.691 385.307 385.703 368 400.01 368H448V144h-48c-15.639 0-20.635-17.991-11.313-27.314l79.995-80.001c6.247-6.248 16.381-6.245 22.626 0z" + } + } + }, + "text-width": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f035", + "label": "text-width", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M16 32h416c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96H261.743v128H296c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H152c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm427.315 340.682l-80.001-79.995C353.991 283.365 336 288.362 336 304v48H112v-47.99c0-14.307-17.307-21.319-27.314-11.313L4.685 372.692c-6.245 6.245-6.247 16.379 0 22.626l80.001 79.995C94.009 484.635 112 479.638 112 464v-48h224v47.99c0 14.307 17.307 21.319 27.314 11.313l80.001-79.995c6.245-6.245 6.248-16.379 0-22.626z" + } + } + }, + "th": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "blocks", + "squares", + "boxes", + "grid" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f00a", + "label": "th", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z" + } + } + }, + "th-large": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "blocks", + "squares", + "boxes", + "grid" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f009", + "label": "th-large", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z" + } + } + }, + "th-list": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ul", + "ol", + "checklist", + "finished", + "completed", + "done", + "todo" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f00b", + "label": "th-list", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z" + } + } + }, + "themeisle": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2b2", + "label": "ThemeIsle", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z" + } + } + }, + "thermometer-empty": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2cb", + "label": "Thermometer Empty", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z" + } + } + }, + "thermometer-full": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2c7", + "label": "Thermometer Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z" + } + } + }, + "thermometer-half": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2c9", + "label": "Thermometer 1/2 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z" + } + } + }, + "thermometer-quarter": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2ca", + "label": "Thermometer 1/4 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z" + } + } + }, + "thermometer-three-quarters": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2c8", + "label": "Thermometer 3/4 Full", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z" + } + } + }, + "thumbs-down": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "dislike", + "disapprove", + "disagree", + "hand", + "thumbs-o-down" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f165", + "label": "thumbs-down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z" + } + } + }, + "thumbs-up": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "like", + "favorite", + "approve", + "agree", + "hand", + "thumbs-o-up" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f164", + "label": "thumbs-up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z" + } + } + }, + "thumbtack": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "marker", + "pin", + "location", + "coordinates", + "thumb-tack" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f08d", + "label": "Thumbtack", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z" + } + } + }, + "ticket-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "ticket" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f3ff", + "label": "Alernate Ticket", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z" + } + } + }, + "times": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "close", + "exit", + "x", + "cross" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f00d", + "label": "Times", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z" + } + } + }, + "times-circle": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "close", + "exit", + "x" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f057", + "label": "Times Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z" + } + } + }, + "tint": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "raindrop", + "waterdrop", + "drop", + "droplet" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f043", + "label": "tint", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M192 512c-98.435 0-178.087-79.652-178.087-178.087 0-111.196 101.194-154.065 148.522-311.825 9.104-30.116 51.099-28.778 59.13 0 47.546 158.486 148.522 200.069 148.522 311.825C370.087 432.348 290.435 512 192 512zm-42.522-171.826c-1.509-5.533-9.447-5.532-10.956 0-9.223 29.425-27.913 37.645-27.913 58.435C110.609 417.13 125.478 432 144 432s33.391-14.87 33.391-33.391c0-20.839-18.673-28.956-27.913-58.435z" + } + } + }, + "toggle-off": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f204", + "label": "Toggle Off", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z" + } + } + }, + "toggle-on": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f205", + "label": "Toggle On", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M576 256c0 106.039-85.961 192-192 192H192C85.961 448 0 362.039 0 256S85.961 64 192 64h192c106.039 0 192 85.961 192 192zM384 128c-70.741 0-128 57.249-128 128 0 70.741 57.249 128 128 128 70.741 0 128-57.249 128-128 0-70.741-57.249-128-128-128" + } + } + }, + "trademark": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f25c", + "label": "Trademark", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M97.119 163.133H12c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h248.559c6.627 0 12 5.373 12 12v43.133c0 6.627-5.373 12-12 12H175.44V404c0 6.627-5.373 12-12 12h-54.322c-6.627 0-12-5.373-12-12V163.133zM329.825 96h65.425a12 12 0 0 1 11.346 8.093l43.759 127.068c7.161 20.588 16.111 52.812 16.111 52.812h.896s8.95-32.224 16.111-52.812l43.758-127.068A12 12 0 0 1 538.577 96h65.41a12 12 0 0 1 11.961 11.03l24.012 296c.567 6.987-4.951 12.97-11.961 12.97h-54.101a12 12 0 0 1-11.972-11.182l-9.082-132.93c-1.79-24.168 0-53.706 0-53.706h-.896s-10.741 33.566-17.902 53.706l-30.7 84.731a12 12 0 0 1-11.282 7.912h-50.302a12 12 0 0 1-11.282-7.912l-30.7-84.731c-7.161-20.14-17.903-53.706-17.903-53.706h-.895s1.79 29.538 0 53.706l-9.082 132.93c-.428 6.295-5.66 11.182-11.97 11.182H305.4c-7.017 0-12.536-5.994-11.959-12.987l24.425-296A11.999 11.999 0 0 1 329.825 96z" + } + } + }, + "train": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f238", + "label": "Train", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z" + } + } + }, + "transgender": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "intersex" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f224", + "label": "Transgender", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "transgender-alt": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f225", + "label": "Alternate Transgender", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "480", + "512" + ], + "width": 480, + "height": 512, + "path": "M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "trash": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "garbage", + "delete", + "remove", + "hide" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f1f8", + "label": "Trash", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm415.2 56.7L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32.8 140.7c-.4-6.9 5.1-12.7 12-12.7h358.5c6.8 0 12.3 5.8 11.9 12.7z" + } + } + }, + "trash-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "garbage", + "delete", + "remove", + "hide", + "trash", + "trash-o" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2ed", + "label": "Alternate Trash", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M192 188v216c0 6.627-5.373 12-12 12h-24c-6.627 0-12-5.373-12-12V188c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12zm100-12h-24c-6.627 0-12 5.373-12 12v216c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12V188c0-6.627-5.373-12-12-12zm132-96c13.255 0 24 10.745 24 24v12c0 6.627-5.373 12-12 12h-20v336c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V128H12c-6.627 0-12-5.373-12-12v-12c0-13.255 10.745-24 24-24h74.411l34.018-56.696A48 48 0 0 1 173.589 0h100.823a48 48 0 0 1 41.16 23.304L349.589 80H424zm-269.611 0h139.223L276.16 50.913A6 6 0 0 0 271.015 48h-94.028a6 6 0 0 0-5.145 2.913L154.389 80zM368 128H80v330a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6V128z" + } + } + }, + "tree": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1bb", + "label": "Tree", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M377.33 375.429L293.906 288H328c21.017 0 31.872-25.207 17.448-40.479L262.79 160H296c20.878 0 31.851-24.969 17.587-40.331l-104-112.003c-9.485-10.214-25.676-10.229-35.174 0l-104 112.003C56.206 134.969 67.037 160 88 160h33.21l-82.659 87.521C24.121 262.801 34.993 288 56 288h34.094L6.665 375.429C-7.869 390.655 2.925 416 24.025 416H144c0 32.781-11.188 49.26-33.995 67.506C98.225 492.93 104.914 512 120 512h144c15.086 0 21.776-19.069 9.995-28.494-19.768-15.814-33.992-31.665-33.995-67.496V416h119.97c21.05 0 31.929-25.309 17.36-40.571z" + } + } + }, + "trello": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f181", + "label": "Trello", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z" + } + } + }, + "tripadvisor": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f262", + "label": "TripAdvisor", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z" + } + } + }, + "trophy": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "award", + "achievement", + "cup", + "winner", + "game" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f091", + "label": "trophy", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z" + } + } + }, + "truck": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "shipping" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0d1", + "label": "truck", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48z" + } + } + }, + "tty": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1e4", + "label": "TTY", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" + } + } + }, + "tumblr": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f173", + "label": "Tumblr", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z" + } + } + }, + "tumblr-square": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f174", + "label": "Tumblr Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z" + } + } + }, + "tv": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "display", + "computer", + "monitor", + "television" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f26c", + "label": "Television", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z" + } + } + }, + "twitch": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1e8", + "label": "Twitch", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z" + } + } + }, + "twitter": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "tweet", + "social network" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f099", + "label": "Twitter", + "svg": { + "brands": { + "last_modified": 1511276382121, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" + } + } + }, + "twitter-square": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "tweet", + "social network" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f081", + "label": "Twitter Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z" + } + } + }, + "typo3": { + "changes": [ + "5.0.1" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f42b", + "label": "Typo3", + "svg": { + "brands": { + "last_modified": 1512768505418, + "raw": "", + "viewBox": [ + "0", + "0", + "433.3", + "512" + ], + "width": 433, + "height": 512, + "path": "M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3" + } + } + }, + "uber": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f402", + "label": "Uber", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z" + } + } + }, + "uikit": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f403", + "label": "UIkit", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z" + } + } + }, + "umbrella": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f0e9", + "label": "Umbrella", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M557.011 267.631c-51.432-45.217-107.572-43.698-158.567 30.731-5.298 7.861-14.906 7.165-19.736 0-2.483-3.624-32.218-60.808-90.708-60.808-45.766 0-70.542 31.378-90.709 60.808-4.829 7.165-14.436 7.861-19.734 0-50.904-74.285-106.613-76.406-158.567-30.731-10.21 8.264-20.912-1.109-18.696-9.481C32.146 134.573 158.516 64.612 288.001 64.612c128.793 0 256.546 69.961 287.706 193.538 2.206 8.322-8.426 17.793-18.696 9.481zM256 261.001V416c0 17.645-14.355 32-32 32s-32-14.355-32-32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 52.935 43.065 96 96 96s96-43.065 96-96V261.288c-21.836-10.806-45.425-9.737-64-.287zm64-211.007V32c0-17.673-14.327-32-32-32s-32 14.327-32 32v17.987a372.105 372.105 0 0 1 64 .007z" + } + } + }, + "underline": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f0cd", + "label": "Underline", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224.264 388.24c-91.669 0-156.603-51.165-156.603-151.392V64H39.37c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h137.39c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.813v172.848c0 53.699 28.314 79.444 76.317 79.444 46.966 0 75.796-25.434 75.796-79.965V64h-28.291c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h136.868c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.291v172.848c0 99.405-64.881 151.392-156.082 151.392zM16 448h416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16z" + } + } + }, + "undo": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "back" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0e2", + "label": "Undo", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z" + } + } + }, + "undo-alt": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "back" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2ea", + "label": "Alternate Undo", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z" + } + } + }, + "uniregistry": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f404", + "label": "Uniregistry", + "svg": { + "brands": { + "last_modified": 1506345643000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3" + } + } + }, + "universal-access": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f29a", + "label": "Universal Access", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z" + } + } + }, + "university": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f19c", + "label": "University", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-12H8a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 480 128zm-24 304H24c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM64 192v192H44c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-20V192h-64v192h-32V192h-64v192h-32V192h-64v192h-32V192H64z" + } + } + }, + "unlink": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "remove", + "chain", + "chain-broken" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f127", + "label": "unlink", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z" + } + } + }, + "unlock": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "protect", + "admin", + "password", + "lock" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f09c", + "label": "unlock", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z" + } + } + }, + "unlock-alt": { + "changes": [ + "3.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "protect", + "admin", + "password", + "lock" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f13e", + "label": "Alternate Unlock", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z" + } + } + }, + "untappd": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f405", + "label": "Untappd", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z" + } + } + }, + "upload": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "import" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f093", + "label": "Upload", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z" + } + } + }, + "usb": { + "changes": [ + "4.5", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f287", + "label": "USB", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z" + } + } + }, + "user": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "person", + "man", + "head", + "profile" + ] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f007", + "label": "User", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M96 160C96 71.634 167.635 0 256 0s160 71.634 160 160-71.635 160-160 160S96 248.366 96 160zm304 192h-28.556c-71.006 42.713-159.912 42.695-230.888 0H112C50.144 352 0 402.144 0 464v24c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24v-24c0-61.856-50.144-112-112-112z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M399.326 288.908C422.188 258.886 436 221.085 436 180 436 80.591 355.414 0 256 0 156.591 0 76 80.586 76 180c0 41.073 13.806 78.878 36.674 108.908C50.028 296.336 0 349.651 0 416v28.5C0 481.72 30.28 512 67.5 512h377c37.22 0 67.5-30.28 67.5-67.5V416c0-66.374-50.052-119.667-112.674-127.092zM256 48c72.902 0 132 59.098 132 132s-59.098 132-132 132-132-59.098-132-132S183.098 48 256 48zm208 396.5c0 10.77-8.73 19.5-19.5 19.5h-377c-10.77 0-19.5-8.73-19.5-19.5V416c0-44.183 35.817-80 80-80h38.14c55.486 31.968 124.026 32.087 179.72 0H384c44.183 0 80 35.817 80 80v28.5z" + } + } + }, + "user-circle": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2bd", + "label": "User Circle", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zM144 208c0-61.856 50.144-112 112-112s112 50.144 112 112-50.144 112-112 112-112-50.144-112-112zm268.408 172.663c-80.346 100.411-232.375 100.53-312.817 0C117.003 362.973 141.218 352 168 352h18.204c44.03 21.336 95.495 21.368 139.592 0H344c26.782 0 50.997 10.973 68.408 28.663z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 34.48-8.706 66.909-24.04 95.213-13.403-26.393-37.525-47.542-67.384-56.572C378.19 273.809 385.5 249.468 385.5 224c0-71.569-57.919-129.5-129.5-129.5-71.569 0-129.5 57.919-129.5 129.5 0 25.468 7.31 49.809 20.924 70.641-29.821 9.018-53.962 30.142-67.385 56.572C64.706 322.911 56 290.482 56 256c0-110.531 89.451-200 200-200zm-80 168c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-59.927 174.943c1.519-33.998 29.554-61.097 63.927-61.097h14.171c38.337 20.889 85.337 20.881 123.659 0H332c34.373 0 62.408 27.099 63.927 61.097-77.746 76.114-202.156 76.065-279.854 0z" + } + } + }, + "user-md": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "doctor", + "profile", + "medical", + "nurse" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0f0", + "label": "user-md", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M96 128C96 57.308 153.308 0 224 0s128 57.308 128 128-57.308 128-128 128S96 198.692 96 128zm256 160v33.61c36.471 7.433 64 39.756 64 78.39v49.441c0 11.44-8.075 21.29-19.293 23.534l-21.802 4.361c-6.499 1.3-12.821-2.915-14.12-9.414l-1.569-7.845c-1.3-6.499 2.915-12.821 9.414-14.12l15.37-3.074v-42.078c0-26.283-20.793-48.297-47.071-48.797C310.039 351.498 288 373.224 288 400v42.883l15.371 3.074c6.499 1.3 10.713 7.622 9.414 14.12l-1.569 7.845c-1.3 6.499-7.622 10.714-14.12 9.414l-21.802-4.361C264.075 470.732 256 460.882 256 449.441V400c0-38.634 27.529-70.957 64-78.39V288h-22.624c-45.669 20.945-99.331 21.749-146.752 0H128v66.025c28.495 7.361 49.359 33.906 47.931 64.977-1.506 32.778-28.097 59.392-60.874 60.926C78.383 481.644 48 452.303 48 416c0-29.767 20.427-54.852 48-61.975V288c-53.019 0-96 42.981-96 96v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-53.019-42.981-96-96-96zM80 416c0 17.645 14.355 32 32 32s32-14.355 32-32-14.355-32-32-32-32 14.355-32 32z" + } + } + }, + "user-plus": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "sign up", + "signup" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f234", + "label": "Add User", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M616 332c0-6.627-5.373-12-12-12h-60v-60c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v60h-60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h60v60c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-60h60c6.627 0 12-5.373 12-12v-40zM448 444v15c0 11.598-9.402 21-21 21H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350a98.09 98.09 0 0 1 26 3.493V372c0 24.262 19.738 44 44 44h25.519c2.768 12.064 2.481 20.659 2.481 28zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172z" + } + } + }, + "user-secret": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "whisper", + "spy", + "incognito", + "privacy" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f21b", + "label": "User Secret", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M388.829 295.324l20.972-55.052c2.992-7.854-2.809-16.272-11.214-16.272H340.39c7.45-16.236 11.61-34.297 11.61-53.333 0-3.631-.16-7.224-.456-10.778C391.083 152.074 416 140.684 416 128c0-13.263-27.231-25.112-69.947-32.937-9.185-32.805-27.178-65.797-40.714-82.85-9.452-11.908-25.873-15.634-39.471-8.834l-27.557 13.779a31.997 31.997 0 0 1-28.622 0l-27.557-13.78c-13.599-6.799-30.02-3.074-39.471 8.834-13.536 17.053-31.529 50.045-40.714 82.85C59.231 102.888 32 114.737 32 128c0 12.684 24.917 24.074 64.456 31.889A129.362 129.362 0 0 0 96 170.667c0 19.037 4.159 37.098 11.608 53.333h-57.41c-8.615 0-14.423 8.809-11.029 16.727l22.906 53.447C25.799 307.882 0 342.925 0 384v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-39.97-24.43-74.231-59.171-88.676zM184 488l-48-192 48 24 24 40-24 128zm80 0l-24-128 24-40 48-24-48 192zm54.778-303.746c-.008.043-4.299 3.231-5.125 5.771-3.861 11.864-7.026 24.572-16.514 33.359-10.071 9.327-47.957 22.405-63.996-25.029-2.837-8.395-15.447-8.398-18.285 0-16.963 50.168-56.019 32.417-63.996 25.029-9.488-8.786-12.653-21.495-16.514-33.359-.826-2.54-5.118-5.728-5.125-5.771-.554-2.925-.981-5.884-1.22-8.85-.309-3.848 10.078-3.658 11.078-3.747 26.303-2.326 52.303-.579 78.023 5.497 2.563.606 11.553.529 13.793 0 25.72-6.076 51.72-7.824 78.023-5.497 1.002.089 11.387-.102 11.078 3.747-.239 2.966-.666 5.925-1.22 8.85z" + } + } + }, + "user-times": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f235", + "label": "Remove User", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M599.681 411.397c4.686-4.686 4.686-12.284 0-16.971L557.255 352l42.426-42.426c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.971 0L512 306.745l-42.426-42.426c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971L466.745 352l-42.426 42.426c-4.686 4.686-4.686 12.284 0 16.971l28.284 28.284c4.686 4.686 12.284 4.686 16.971 0L512 397.255l42.426 42.426c4.686 4.686 12.284 4.686 16.971 0l28.284-28.284zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172zm359.737 299.645C439.904 476.712 433.843 480 427 480H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350c23.366 0 44.818 8.183 61.658 21.832l-9.967 9.967c-17.156 17.156-17.156 45.07 0 62.225l28.284 28.284a43.946 43.946 0 0 0 13.762 9.337z" + } + } + }, + "users": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "people", + "profiles", + "persons" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0c0", + "label": "Users", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M220 164c0-55.229 44.772-100 100-100s100 44.771 100 100-44.772 100-100 100-100-44.771-100-100zM48 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm384 0c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-22 76c38.66 0 70 31.34 70 70v70c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24v-70c0-38.66 31.34-70 70-70h17.848c44.364 26.687 99.93 26.693 144.305 0H410m-282 70c0-11.975 2.081-23.472 5.889-34.156-21.93 1.152-44.122-4.121-63.611-15.844H56c-30.928 0-56 25.072-56 56v32c0 13.255 10.745 24 24 24h104v-62zm456-50h-14.278c-19.495 11.727-41.686 16.996-63.611 15.844A101.542 101.542 0 0 1 512 354v62h104c13.255 0 24-10.745 24-24v-32c0-30.928-25.072-56-56-56z" + } + } + }, + "ussunnah": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f407", + "label": "us-Sunnah Foundation", + "sponsored": { + "label": "us-Sunnah Foundation", + "url": "https://www.ussunnah.org" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z" + } + } + }, + "utensil-spoon": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "spoon" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2e5", + "label": "Utensil Spoon", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z" + } + } + }, + "utensils": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "food", + "restaurant", + "spoon", + "knife", + "dinner", + "eat", + "cutlery" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f2e7", + "label": "Utensils", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "416", + "512" + ], + "width": 416, + "height": 512, + "path": "M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z" + } + } + }, + "vaadin": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f408", + "label": "Vaadin", + "sponsored": { + "label": "Vaadin", + "url": "http://vaadin.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z" + } + } + }, + "venus": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "female" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f221", + "label": "Venus", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "288", + "512" + ], + "width": 288, + "height": 512, + "path": "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z" + } + } + }, + "venus-double": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f226", + "label": "Venus Double", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z" + } + } + }, + "venus-mars": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f228", + "label": "Venus Mars", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z" + } + } + }, + "viacoin": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f237", + "label": "Viacoin", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z" + } + } + }, + "viadeo": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2a9", + "label": "Viadeo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z" + } + } + }, + "viadeo-square": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2aa", + "label": "Viadeo Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z" + } + } + }, + "viber": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f409", + "label": "Viber", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z" + } + } + }, + "video": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "film", + "movie", + "record", + "camera", + "video-camera" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f03d", + "label": "Video", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M528 64h-12.118a48 48 0 0 0-33.941 14.059L384 176v-64c0-26.51-21.49-48-48-48H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-64l97.941 97.941A48 48 0 0 0 515.882 448H528c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48z" + } + } + }, + "vimeo": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f40a", + "label": "Vimeo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z" + } + } + }, + "vimeo-square": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f194", + "label": "Vimeo Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z" + } + } + }, + "vimeo-v": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "vimeo" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f27d", + "label": "Vimeo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z" + } + } + }, + "vine": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1ca", + "label": "Vine", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z" + } + } + }, + "vk": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f189", + "label": "VK", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z" + } + } + }, + "vnv": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f40b", + "label": "VNV", + "sponsored": { + "label": "VNV", + "url": "https://www.vnv.ch" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z" + } + } + }, + "volume-down": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "audio", + "lower", + "quieter", + "sound", + "music" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f027", + "label": "volume-down", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zM384 256c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z" + } + } + }, + "volume-off": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "audio", + "mute", + "sound", + "music" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f026", + "label": "volume-off", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971z" + } + } + }, + "volume-up": { + "changes": [ + "1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "audio", + "higher", + "louder", + "sound", + "music" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f028", + "label": "volume-up", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zm182.056-77.876C422.982.92 403.283 5.668 394.061 20.745c-9.221 15.077-4.473 34.774 10.604 43.995C468.967 104.063 512 174.983 512 256c0 73.431-36.077 142.292-96.507 184.206-14.522 10.072-18.129 30.01-8.057 44.532 10.076 14.528 30.016 18.126 44.531 8.057C529.633 438.927 576 350.406 576 256c0-103.244-54.579-194.877-137.944-245.859zM480 256c0-68.547-36.15-129.777-91.957-163.901-15.076-9.22-34.774-4.471-43.994 10.607-9.22 15.078-4.471 34.774 10.607 43.994C393.067 170.188 416 211.048 416 256c0 41.964-20.62 81.319-55.158 105.276-14.521 10.073-18.128 30.01-8.056 44.532 6.216 8.96 16.185 13.765 26.322 13.765a31.862 31.862 0 0 0 18.21-5.709C449.091 377.953 480 318.938 480 256zm-96 0c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z" + } + } + }, + "vuejs": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f41f", + "label": "Vue.js", + "svg": { + "brands": { + "last_modified": 1508771132272, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z" + } + } + }, + "weibo": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f18a", + "label": "Weibo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z" + } + } + }, + "weixin": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1d7", + "label": "Weixin (WeChat)", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z" + } + } + }, + "whatsapp": { + "changes": [ + "4.3", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f232", + "label": "What's App", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z" + } + } + }, + "whatsapp-square": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f40c", + "label": "What's App Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z" + } + } + }, + "wheelchair": { + "changes": [ + "4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "handicap", + "person" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f193", + "label": "Wheelchair", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z" + } + } + }, + "whmcs": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f40d", + "label": "WHMCS", + "sponsored": { + "label": "WHMCS", + "url": "https://www.whmcs.com" + }, + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z" + } + } + }, + "wifi": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f1eb", + "label": "WiFi", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M384 416c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm136.659-124.443c6.465-6.465 6.245-17.065-.564-23.167-113.793-101.985-286.526-101.869-400.19 0-6.809 6.102-7.029 16.702-.564 23.167l34.006 34.006c5.927 5.927 15.464 6.32 21.769.796 82.88-72.609 207.074-72.447 289.768 0 6.305 5.524 15.842 5.132 21.769-.796l34.006-34.006zm112.11-113.718c6.385-6.385 6.254-16.816-.35-22.973-175.768-163.86-449.134-163.8-624.837 0-6.604 6.157-6.735 16.589-.35 22.973l33.966 33.966c6.095 6.095 15.891 6.231 22.224.383 144.763-133.668 368.356-133.702 513.156 0 6.333 5.848 16.129 5.712 22.224-.383l33.967-33.966z" + } + } + }, + "wikipedia-w": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f266", + "label": "Wikipedia W", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "640", + "512" + ], + "width": 640, + "height": 512, + "path": "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z" + } + } + }, + "window-close": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f410", + "label": "Window Close", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z" + } + } + }, + "window-maximize": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2d0", + "label": "Window Maximize", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z" + } + } + }, + "window-minimize": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid" + ], + "unicode": "f2d1", + "label": "Window Minimize", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z" + } + } + }, + "window-restore": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "solid", + "regular" + ], + "unicode": "f2d2", + "label": "Window Restore", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z" + }, + "regular": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z" + } + } + }, + "windows": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "microsoft" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f17a", + "label": "Windows", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z" + } + } + }, + "won-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "krw", + "krw" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f159", + "label": "Won Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M564 192c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-48.028l18.572-80.61c1.732-7.518-3.978-14.694-11.693-14.694h-46.107a11.998 11.998 0 0 0-11.736 9.5L450.73 128H340.839l-19.725-85.987a12 12 0 0 0-11.696-9.317H265.43a12 12 0 0 0-11.687 9.277L233.696 128H124.975L107.5 42.299a12 12 0 0 0-11.758-9.602H53.628c-7.686 0-13.39 7.124-11.709 14.624L60 128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h62.342l7.171 32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h83.856l40.927 182.624A12 12 0 0 0 148.492 480h56.767c5.583 0 10.428-3.85 11.689-9.288L259.335 288h55.086l42.386 182.712A12 12 0 0 0 368.496 480h56.826a12 12 0 0 0 11.694-9.306L479.108 288H564c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-70.146l7.373-32H564zm-425.976 0h80.757l-7.457 32h-66.776l-6.524-32zm45.796 150.029c-6.194 25.831-6.758 47.25-7.321 47.25h-1.126s-1.689-22.05-6.758-47.25L157.599 288h38.812l-12.591 54.029zM274.182 224l1.996-8.602c1.856-7.962 3.457-15.968 4.803-23.398h11.794c1.347 7.43 2.947 15.436 4.803 23.398l1.996 8.602h-25.392zm130.959 118.029c-5.068 25.2-6.758 47.25-6.758 47.25h-1.126c-.563 0-1.126-21.42-7.321-47.25L377.542 288h39.107l-11.508 54.029zM430.281 224h-67.42l-7.34-32h81.577l-6.817 32z" + } + } + }, + "wordpress": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f19a", + "label": "WordPress Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z" + } + } + }, + "wordpress-simple": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f411", + "label": "Wordpress Simple", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z" + } + } + }, + "wpbeginner": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f297", + "label": "WPBeginner", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z" + } + } + }, + "wpexplorer": { + "changes": [ + "4.7", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2de", + "label": "WPExplorer", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z" + } + } + }, + "wpforms": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f298", + "label": "WPForms", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z" + } + } + }, + "wrench": { + "changes": [ + "2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "settings", + "fix", + "update", + "spanner" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f0ad", + "label": "Wrench", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z" + } + } + }, + "xbox": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f412", + "label": "Xbox", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "512", + "512" + ], + "width": 512, + "height": 512, + "path": "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z" + } + } + }, + "xing": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f168", + "label": "Xing", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z" + } + } + }, + "xing-square": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f169", + "label": "Xing Square", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z" + } + } + }, + "y-combinator": { + "changes": [ + "4.4", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f23b", + "label": "Y Combinator", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z" + } + } + }, + "yahoo": { + "changes": [ + "4.1", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f19e", + "label": "Yahoo Logo", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "360", + "512" + ], + "width": 360, + "height": 512, + "path": "M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z" + } + } + }, + "yandex": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f413", + "label": "Yandex", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "256", + "512" + ], + "width": 256, + "height": 512, + "path": "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z" + } + } + }, + "yandex-international": { + "changes": [ + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f414", + "label": "Yandex International", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "320", + "512" + ], + "width": 320, + "height": 512, + "path": "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z" + } + } + }, + "yelp": { + "changes": [ + "4.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f1e9", + "label": "Yelp", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z" + } + } + }, + "yen-sign": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "jpy", + "jpy" + ] + }, + "styles": [ + "solid" + ], + "unicode": "f157", + "label": "Yen Sign", + "svg": { + "solid": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "384", + "512" + ], + "width": 384, + "height": 512, + "path": "M351.208 32h-65.277a12 12 0 0 0-10.778 6.724l-55.39 113.163c-14.513 34.704-27.133 71.932-27.133 71.932h-1.262s-12.62-37.228-27.133-71.932l-55.39-113.163A11.997 11.997 0 0 0 98.068 32H32.792c-9.057 0-14.85 9.65-10.59 17.643L102.322 200H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h88.162L152 293.228V320H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h108v92c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-92h108c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12H232v-26.772L251.838 256H340c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12h-58.322l80.12-150.357C366.058 41.65 360.266 32 351.208 32z" + } + } + }, + "yoast": { + "changes": [ + "4.6", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [] + }, + "styles": [ + "brands" + ], + "unicode": "f2b1", + "label": "Yoast", + "svg": { + "brands": { + "last_modified": 1505155759000, + "raw": "", + "viewBox": [ + "0", + "0", + "448", + "512" + ], + "width": 448, + "height": 512, + "path": "M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z" + } + } + }, + "youtube": { + "changes": [ + "3.2", + "5.0.0" + ], + "ligatures": [], + "search": { + "terms": [ + "video", + "film", + "youtube-play", + "youtube-square" + ] + }, + "styles": [ + "brands" + ], + "unicode": "f167", + "label": "YouTube", + "svg": { + "brands": { + "last_modified": 1511276382122, + "raw": "", + "viewBox": [ + "0", + "0", + "576", + "512" + ], + "width": 576, + "height": 512, + "path": "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" + } + } + } +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.yml b/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.yml new file mode 100644 index 000000000..0adae33cc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/metadata/icons.yml @@ -0,0 +1,9042 @@ +500px: + changes: + - '4.4' + - 5.0.0 + label: 500px + search: + terms: [] + styles: + - brands + unicode: f26e +accessible-icon: + changes: + - 5.0.0 + label: Accessible Icon + search: + terms: + - accessibility + - wheelchair + - handicap + - person + - wheelchair-alt + styles: + - brands + unicode: f368 +accusoft: + changes: + - 5.0.0 + label: Accusoft + search: + terms: [] + styles: + - brands + unicode: f369 +address-book: + changes: + - '4.7' + - 5.0.0 + label: Address Book + search: + terms: [] + styles: + - solid + - regular + unicode: f2b9 +address-card: + changes: + - '4.7' + - 5.0.0 + label: Address Card + search: + terms: [] + styles: + - solid + - regular + unicode: f2bb +adjust: + changes: + - '1' + - 5.0.0 + label: adjust + search: + terms: + - contrast + styles: + - solid + unicode: f042 +adn: + changes: + - '3.2' + - 5.0.0 + label: App.net + search: + terms: [] + styles: + - brands + unicode: f170 +adversal: + changes: + - 5.0.0 + label: Adversal + search: + terms: [] + sponsored: + label: Adversal + url: 'https://www.adversal.com' + styles: + - brands + unicode: f36a +affiliatetheme: + changes: + - 5.0.0 + label: affiliatetheme + search: + terms: [] + sponsored: + label: affiliatetheme + url: 'https://affiliatetheme.io/en' + styles: + - brands + unicode: f36b +algolia: + changes: + - 5.0.0 + label: Algolia + search: + terms: [] + sponsored: + label: Algolia + url: 'http://www.algolia.com' + styles: + - brands + unicode: f36c +align-center: + changes: + - '1' + - 5.0.0 + label: align-center + search: + terms: + - middle + - text + styles: + - solid + unicode: f037 +align-justify: + changes: + - '1' + - 5.0.0 + label: align-justify + search: + terms: + - text + styles: + - solid + unicode: f039 +align-left: + changes: + - '1' + - 5.0.0 + label: align-left + search: + terms: + - text + styles: + - solid + unicode: f036 +align-right: + changes: + - '1' + - 5.0.0 + label: align-right + search: + terms: + - text + styles: + - solid + unicode: f038 +amazon: + changes: + - '4.4' + - 5.0.0 + label: Amazon + search: + terms: [] + styles: + - brands + unicode: f270 +ambulance: + changes: + - '3' + - 5.0.0 + label: ambulance + search: + terms: + - vehicle + - support + - help + styles: + - solid + unicode: f0f9 +american-sign-language-interpreting: + changes: + - '4.6' + - 5.0.0 + label: American Sign Language Interpreting + search: + terms: [] + styles: + - solid + unicode: f2a3 +amilia: + changes: + - 5.0.0 + label: Amilia + search: + terms: [] + sponsored: + label: Amilia + url: 'http://www.amilia.com' + styles: + - brands + unicode: f36d +anchor: + changes: + - '3.1' + - 5.0.0 + label: Anchor + search: + terms: + - link + styles: + - solid + unicode: f13d +android: + changes: + - '3.2' + - 5.0.0 + label: Android + search: + terms: + - robot + styles: + - brands + unicode: f17b +angellist: + changes: + - '4.2' + - 5.0.0 + label: AngelList + search: + terms: [] + styles: + - brands + unicode: f209 +angle-double-down: + changes: + - '3' + - 5.0.0 + label: Angle Double Down + search: + terms: + - arrows + styles: + - solid + unicode: f103 +angle-double-left: + changes: + - '3' + - 5.0.0 + label: Angle Double Left + search: + terms: + - laquo + - quote + - previous + - back + - arrows + styles: + - solid + unicode: f100 +angle-double-right: + changes: + - '3' + - 5.0.0 + label: Angle Double Right + search: + terms: + - raquo + - quote + - next + - forward + - arrows + styles: + - solid + unicode: f101 +angle-double-up: + changes: + - '3' + - 5.0.0 + label: Angle Double Up + search: + terms: + - arrows + styles: + - solid + unicode: f102 +angle-down: + changes: + - '3' + - 5.0.0 + label: angle-down + search: + terms: + - arrow + styles: + - solid + unicode: f107 +angle-left: + changes: + - '3' + - 5.0.0 + label: angle-left + search: + terms: + - previous + - back + - arrow + styles: + - solid + unicode: f104 +angle-right: + changes: + - '3' + - 5.0.0 + label: angle-right + search: + terms: + - next + - forward + - arrow + styles: + - solid + unicode: f105 +angle-up: + changes: + - '3' + - 5.0.0 + label: angle-up + search: + terms: + - arrow + styles: + - solid + unicode: f106 +angrycreative: + changes: + - 5.0.0 + label: Angry Creative + search: + terms: [] + sponsored: + label: Angry Creative + url: 'https://angrycreative.se' + styles: + - brands + unicode: f36e +angular: + changes: + - 5.0.0 + label: Angular + search: + terms: [] + styles: + - brands + unicode: f420 +app-store: + changes: + - 5.0.0 + label: App Store + search: + terms: [] + styles: + - brands + unicode: f36f +app-store-ios: + changes: + - 5.0.0 + label: iOS App Store + search: + terms: [] + styles: + - brands + unicode: f370 +apper: + changes: + - 5.0.0 + label: Apper Systems AB + search: + terms: [] + sponsored: + label: Apper Systems AB + url: 'http://www.apper.com/' + styles: + - brands + unicode: f371 +apple: + changes: + - '3.2' + - 5.0.0 + label: Apple + search: + terms: + - osx + - food + styles: + - brands + unicode: f179 +apple-pay: + changes: + - 5.0.0 + label: Apple Pay + search: + terms: [] + styles: + - brands + unicode: f415 +archive: + changes: + - '3.2' + - 5.0.0 + label: Archive + search: + terms: + - box + - storage + styles: + - solid + unicode: f187 +arrow-alt-circle-down: + changes: + - 5.0.0 + label: Alternate Arrow Circle Down + search: + terms: + - download + - arrow-circle-o-down + styles: + - solid + - regular + unicode: f358 +arrow-alt-circle-left: + changes: + - 5.0.0 + label: Alternate Arrow Circle Left + search: + terms: + - previous + - back + - arrow-circle-o-left + styles: + - solid + - regular + unicode: f359 +arrow-alt-circle-right: + changes: + - 5.0.0 + label: Alternate Arrow Circle Right + search: + terms: + - next + - forward + - arrow-circle-o-right + styles: + - solid + - regular + unicode: f35a +arrow-alt-circle-up: + changes: + - 5.0.0 + label: Alternate Arrow Circle Up + search: + terms: + - arrow-circle-o-up + styles: + - solid + - regular + unicode: f35b +arrow-circle-down: + changes: + - '2' + - 5.0.0 + label: Arrow Circle Down + search: + terms: + - download + styles: + - solid + unicode: f0ab +arrow-circle-left: + changes: + - '2' + - 5.0.0 + label: Arrow Circle Left + search: + terms: + - previous + - back + styles: + - solid + unicode: f0a8 +arrow-circle-right: + changes: + - '2' + - 5.0.0 + label: Arrow Circle Right + search: + terms: + - next + - forward + styles: + - solid + unicode: f0a9 +arrow-circle-up: + changes: + - '2' + - 5.0.0 + label: Arrow Circle Up + search: + terms: [] + styles: + - solid + unicode: f0aa +arrow-down: + changes: + - '1' + - 5.0.0 + label: arrow-down + search: + terms: + - download + styles: + - solid + unicode: f063 +arrow-left: + changes: + - '1' + - 5.0.0 + label: arrow-left + search: + terms: + - previous + - back + styles: + - solid + unicode: f060 +arrow-right: + changes: + - '1' + - 5.0.0 + label: arrow-right + search: + terms: + - next + - forward + styles: + - solid + unicode: f061 +arrow-up: + changes: + - '1' + - 5.0.0 + label: arrow-up + search: + terms: [] + styles: + - solid + unicode: f062 +arrows-alt: + changes: + - '2' + - 5.0.0 + label: Alternate Arrows + search: + terms: + - expand + - enlarge + - fullscreen + - bigger + - move + - reorder + - resize + - arrow + - arrows + styles: + - solid + unicode: f0b2 +arrows-alt-h: + changes: + - 5.0.0 + label: Alternate Arrows Horizontal + search: + terms: + - resize + - arrows-h + styles: + - solid + unicode: f337 +arrows-alt-v: + changes: + - 5.0.0 + label: Alternate Arrows Vertical + search: + terms: + - resize + - arrows-v + styles: + - solid + unicode: f338 +assistive-listening-systems: + changes: + - '4.6' + - 5.0.0 + label: Assistive Listening Systems + search: + terms: [] + styles: + - solid + unicode: f2a2 +asterisk: + changes: + - '1' + - 5.0.0 + label: asterisk + search: + terms: + - details + styles: + - solid + unicode: f069 +asymmetrik: + changes: + - 5.0.0 + label: 'Asymmetrik, Ltd.' + search: + terms: [] + sponsored: + label: 'Asymmetrik, Ltd.' + url: 'http://asymmetrik.com/' + styles: + - brands + unicode: f372 +at: + changes: + - '4.2' + - 5.0.0 + label: At + search: + terms: + - email + - e-mail + styles: + - solid + unicode: f1fa +audible: + changes: + - 5.0.0 + label: Audible + search: + terms: [] + styles: + - brands + unicode: f373 +audio-description: + changes: + - '4.6' + - 5.0.0 + label: Audio Description + search: + terms: [] + styles: + - solid + unicode: f29e +autoprefixer: + changes: + - 5.0.0 + label: Autoprefixer + search: + terms: [] + styles: + - brands + unicode: f41c +avianex: + changes: + - 5.0.0 + label: avianex + search: + terms: [] + sponsored: + label: avianex + url: 'https://www.avianex.de' + styles: + - brands + unicode: f374 +aviato: + changes: + - 5.0.0 + label: Aviato + search: + terms: [] + styles: + - brands + unicode: f421 +aws: + changes: + - 5.0.0 + label: Amazon Web Services (AWS) + search: + terms: [] + styles: + - brands + unicode: f375 +backward: + changes: + - '1' + - 5.0.0 + label: backward + search: + terms: + - rewind + - previous + styles: + - solid + unicode: f04a +balance-scale: + changes: + - '4.4' + - 5.0.0 + label: Balance Scale + search: + terms: [] + styles: + - solid + unicode: f24e +ban: + changes: + - '1' + - 5.0.0 + label: ban + search: + terms: + - delete + - remove + - trash + - hide + - block + - stop + - abort + - cancel + styles: + - solid + unicode: f05e +bandcamp: + changes: + - '4.7' + - 5.0.0 + label: Bandcamp + search: + terms: [] + styles: + - brands + unicode: f2d5 +barcode: + changes: + - '1' + - 5.0.0 + label: barcode + search: + terms: + - scan + styles: + - solid + unicode: f02a +bars: + changes: + - '2' + - 5.0.0 + label: Bars + search: + terms: + - menu + - drag + - reorder + - settings + - list + - ul + - ol + - checklist + - todo + - list + - hamburger + styles: + - solid + unicode: f0c9 +bath: + changes: + - '4.7' + - 5.0.0 + label: Bath + search: + terms: [] + styles: + - solid + unicode: f2cd +battery-empty: + changes: + - '4.4' + - 5.0.0 + label: Battery Empty + search: + terms: + - power + styles: + - solid + unicode: f244 +battery-full: + changes: + - '4.4' + - 5.0.0 + label: Battery Full + search: + terms: + - power + styles: + - solid + unicode: f240 +battery-half: + changes: + - '4.4' + - 5.0.0 + label: Battery 1/2 Full + search: + terms: + - power + styles: + - solid + unicode: f242 +battery-quarter: + changes: + - '4.4' + - 5.0.0 + label: Battery 1/4 Full + search: + terms: + - power + styles: + - solid + unicode: f243 +battery-three-quarters: + changes: + - '4.4' + - 5.0.0 + label: Battery 3/4 Full + search: + terms: + - power + styles: + - solid + unicode: f241 +bed: + changes: + - '4.3' + - 5.0.0 + label: Bed + search: + terms: + - travel + styles: + - solid + unicode: f236 +beer: + changes: + - '3' + - 5.0.0 + label: beer + search: + terms: + - alcohol + - stein + - drink + - mug + - bar + - liquor + styles: + - solid + unicode: f0fc +behance: + changes: + - '4.1' + - 5.0.0 + label: Behance + search: + terms: [] + styles: + - brands + unicode: f1b4 +behance-square: + changes: + - '4.1' + - 5.0.0 + label: Behance Square + search: + terms: [] + styles: + - brands + unicode: f1b5 +bell: + changes: + - '2' + - 5.0.0 + label: bell + search: + terms: + - alert + - reminder + - notification + styles: + - solid + - regular + unicode: f0f3 +bell-slash: + changes: + - '4.2' + - 5.0.0 + label: Bell Slash + search: + terms: [] + styles: + - solid + - regular + unicode: f1f6 +bicycle: + changes: + - '4.2' + - 5.0.0 + label: Bicycle + search: + terms: + - vehicle + - bike + styles: + - solid + unicode: f206 +bimobject: + changes: + - 5.0.0 + label: BIMobject + search: + terms: [] + sponsored: + label: BIMobject + url: 'http://bimobject.com' + styles: + - brands + unicode: f378 +binoculars: + changes: + - '4.2' + - 5.0.0 + label: Binoculars + search: + terms: [] + styles: + - solid + unicode: f1e5 +birthday-cake: + changes: + - '4.2' + - 5.0.0 + label: Birthday Cake + search: + terms: [] + styles: + - solid + unicode: f1fd +bitbucket: + changes: + - '3.2' + - 5.0.0 + label: Bitbucket + search: + terms: + - git + - bitbucket-square + styles: + - brands + unicode: f171 +bitcoin: + changes: + - 5.0.0 + label: Bitcoin + search: + terms: [] + styles: + - brands + unicode: f379 +bity: + changes: + - 5.0.0 + label: Bity + search: + terms: [] + sponsored: + label: Bity + url: 'http://bity.com' + styles: + - brands + unicode: f37a +black-tie: + changes: + - '4.4' + - 5.0.0 + label: Font Awesome Black Tie + search: + terms: [] + styles: + - brands + unicode: f27e +blackberry: + changes: + - 5.0.0 + label: BlackBerry + search: + terms: [] + styles: + - brands + unicode: f37b +blind: + changes: + - '4.6' + - 5.0.0 + label: Blind + search: + terms: [] + styles: + - solid + unicode: f29d +blogger: + changes: + - 5.0.0 + label: Blogger + search: + terms: [] + styles: + - brands + unicode: f37c +blogger-b: + changes: + - 5.0.0 + label: Blogger B + search: + terms: [] + styles: + - brands + unicode: f37d +bluetooth: + changes: + - '4.5' + - 5.0.0 + label: Bluetooth + search: + terms: [] + styles: + - brands + unicode: f293 +bluetooth-b: + changes: + - '4.5' + - 5.0.0 + label: Bluetooth + search: + terms: [] + styles: + - brands + unicode: f294 +bold: + changes: + - '1' + - 5.0.0 + label: bold + search: + terms: [] + styles: + - solid + unicode: f032 +bolt: + changes: + - '2' + - 5.0.0 + label: Lightning Bolt + search: + terms: + - lightning + - weather + styles: + - solid + unicode: f0e7 +bomb: + changes: + - '4.1' + - 5.0.0 + label: Bomb + search: + terms: [] + styles: + - solid + unicode: f1e2 +book: + changes: + - '1' + - 5.0.0 + label: book + search: + terms: + - read + - documentation + styles: + - solid + unicode: f02d +bookmark: + changes: + - '1' + - 5.0.0 + label: bookmark + search: + terms: + - save + styles: + - solid + - regular + unicode: f02e +braille: + changes: + - '4.6' + - 5.0.0 + label: Braille + search: + terms: [] + styles: + - solid + unicode: f2a1 +briefcase: + changes: + - '2' + - 5.0.0 + label: Briefcase + search: + terms: + - work + - business + - office + - luggage + - bag + styles: + - solid + unicode: f0b1 +btc: + changes: + - '3.2' + - 5.0.0 + label: BTC + search: + terms: [] + styles: + - brands + unicode: f15a +bug: + changes: + - '3.2' + - 5.0.0 + label: Bug + search: + terms: + - report + - insect + styles: + - solid + unicode: f188 +building: + changes: + - '4.1' + - 5.0.0 + label: Building + search: + terms: + - work + - business + - apartment + - office + - company + styles: + - solid + - regular + unicode: f1ad +bullhorn: + changes: + - '2' + - 5.0.0 + label: bullhorn + search: + terms: + - announcement + - share + - broadcast + - louder + - megaphone + styles: + - solid + unicode: f0a1 +bullseye: + changes: + - '3.1' + - 5.0.0 + label: Bullseye + search: + terms: + - target + styles: + - solid + unicode: f140 +buromobelexperte: + changes: + - 5.0.0 + label: Büromöbel-Experte GmbH & Co. KG. + search: + terms: [] + sponsored: + label: Büromöbel-Experte GmbH & Co. KG. + url: 'https://www.bueromoebel-experte.de' + styles: + - brands + unicode: f37f +bus: + changes: + - '4.2' + - 5.0.0 + label: Bus + search: + terms: + - vehicle + styles: + - solid + unicode: f207 +buysellads: + changes: + - '4.3' + - 5.0.0 + label: BuySellAds + search: + terms: [] + styles: + - brands + unicode: f20d +calculator: + changes: + - '4.2' + - 5.0.0 + label: Calculator + search: + terms: [] + styles: + - solid + unicode: f1ec +calendar: + changes: + - '3.1' + - 5.0.0 + label: Calendar + search: + terms: + - date + - time + - when + - event + - calendar-o + styles: + - solid + - regular + unicode: f133 +calendar-alt: + changes: + - '1' + - 5.0.0 + label: Alternate Calendar + search: + terms: + - date + - time + - when + - event + - calendar + styles: + - solid + - regular + unicode: f073 +calendar-check: + changes: + - '4.4' + - 5.0.0 + label: Calendar Check + search: + terms: + - ok + styles: + - solid + - regular + unicode: f274 +calendar-minus: + changes: + - '4.4' + - 5.0.0 + label: Calendar Minus + search: + terms: [] + styles: + - solid + - regular + unicode: f272 +calendar-plus: + changes: + - '4.4' + - 5.0.0 + label: Calendar Plus + search: + terms: [] + styles: + - solid + - regular + unicode: f271 +calendar-times: + changes: + - '4.4' + - 5.0.0 + label: Calendar Times + search: + terms: [] + styles: + - solid + - regular + unicode: f273 +camera: + changes: + - '1' + - 5.0.0 + label: camera + search: + terms: + - photo + - picture + - record + styles: + - solid + unicode: f030 +camera-retro: + changes: + - '1' + - 5.0.0 + label: Retro Camera + search: + terms: + - photo + - picture + - record + styles: + - solid + unicode: f083 +car: + changes: + - '4.1' + - 5.0.0 + label: Car + search: + terms: + - vehicle + styles: + - solid + unicode: f1b9 +caret-down: + changes: + - '2' + - 5.0.0 + label: Caret Down + search: + terms: + - more + - dropdown + - menu + - triangle down + - arrow + styles: + - solid + unicode: f0d7 +caret-left: + changes: + - '2' + - 5.0.0 + label: Caret Left + search: + terms: + - previous + - back + - triangle left + - arrow + styles: + - solid + unicode: f0d9 +caret-right: + changes: + - '2' + - 5.0.0 + label: Caret Right + search: + terms: + - next + - forward + - triangle right + - arrow + styles: + - solid + unicode: f0da +caret-square-down: + changes: + - '3.2' + - 5.0.0 + label: Caret Square Down + search: + terms: + - more + - dropdown + - menu + - caret-square-o-down + styles: + - solid + - regular + unicode: f150 +caret-square-left: + changes: + - '4' + - 5.0.0 + label: Caret Square Left + search: + terms: + - previous + - back + - caret-square-o-left + styles: + - solid + - regular + unicode: f191 +caret-square-right: + changes: + - '3.2' + - 5.0.0 + label: Caret Square Right + search: + terms: + - next + - forward + - caret-square-o-right + styles: + - solid + - regular + unicode: f152 +caret-square-up: + changes: + - '3.2' + - 5.0.0 + label: Caret Square Up + search: + terms: + - caret-square-o-up + styles: + - solid + - regular + unicode: f151 +caret-up: + changes: + - '2' + - 5.0.0 + label: Caret Up + search: + terms: + - triangle up + - arrow + styles: + - solid + unicode: f0d8 +cart-arrow-down: + changes: + - '4.3' + - 5.0.0 + label: Shopping Cart Arrow Down + search: + terms: + - shopping + styles: + - solid + unicode: f218 +cart-plus: + changes: + - '4.3' + - 5.0.0 + label: Add to Shopping Cart + search: + terms: + - add + - shopping + styles: + - solid + unicode: f217 +cc-amex: + changes: + - '4.2' + - 5.0.0 + label: American Express Credit Card + search: + terms: + - amex + styles: + - brands + unicode: f1f3 +cc-apple-pay: + changes: + - 5.0.0 + label: Apple Pay Credit Card + search: + terms: [] + styles: + - brands + unicode: f416 +cc-diners-club: + changes: + - '4.4' + - 5.0.0 + label: Diner's Club Credit Card + search: + terms: [] + styles: + - brands + unicode: f24c +cc-discover: + changes: + - '4.2' + - 5.0.0 + label: Discover Credit Card + search: + terms: [] + styles: + - brands + unicode: f1f2 +cc-jcb: + changes: + - '4.4' + - 5.0.0 + label: JCB Credit Card + search: + terms: [] + styles: + - brands + unicode: f24b +cc-mastercard: + changes: + - '4.2' + - 5.0.0 + label: MasterCard Credit Card + search: + terms: [] + styles: + - brands + unicode: f1f1 +cc-paypal: + changes: + - '4.2' + - 5.0.0 + label: Paypal Credit Card + search: + terms: [] + styles: + - brands + unicode: f1f4 +cc-stripe: + changes: + - '4.2' + - 5.0.0 + label: Stripe Credit Card + search: + terms: [] + styles: + - brands + unicode: f1f5 +cc-visa: + changes: + - '4.2' + - 5.0.0 + label: Visa Credit Card + search: + terms: [] + styles: + - brands + unicode: f1f0 +centercode: + changes: + - 5.0.0 + label: Centercode + search: + terms: [] + sponsored: + label: Centercode + url: 'https://www.centercode.com' + styles: + - brands + unicode: f380 +certificate: + changes: + - '2' + - 5.0.0 + label: certificate + search: + terms: + - badge + - star + styles: + - solid + unicode: f0a3 +chart-area: + changes: + - '4.2' + - 5.0.0 + label: Area Chart + search: + terms: + - graph + - analytics + - area-chart + styles: + - solid + unicode: f1fe +chart-bar: + changes: + - '1' + - 5.0.0 + label: Bar Chart + search: + terms: + - graph + - analytics + - bar-chart + styles: + - solid + - regular + unicode: f080 +chart-line: + changes: + - '4.2' + - 5.0.0 + label: Line Chart + search: + terms: + - graph + - analytics + - line-chart + styles: + - solid + unicode: f201 +chart-pie: + changes: + - '4.2' + - 5.0.0 + label: Pie Chart + search: + terms: + - graph + - analytics + - pie-chart + styles: + - solid + unicode: f200 +check: + changes: + - '1' + - 5.0.0 + label: Check + search: + terms: + - checkmark + - done + - todo + - agree + - accept + - confirm + - tick + - ok + styles: + - solid + unicode: f00c +check-circle: + changes: + - '1' + - 5.0.0 + label: Check Circle + search: + terms: + - todo + - done + - agree + - accept + - confirm + - ok + styles: + - solid + - regular + unicode: f058 +check-square: + changes: + - '3.1' + - 5.0.0 + label: Check Square + search: + terms: + - checkmark + - done + - todo + - agree + - accept + - confirm + - ok + styles: + - solid + - regular + unicode: f14a +chevron-circle-down: + changes: + - '3.1' + - 5.0.0 + label: Chevron Circle Down + search: + terms: + - more + - dropdown + - menu + - arrow + styles: + - solid + unicode: f13a +chevron-circle-left: + changes: + - '3.1' + - 5.0.0 + label: Chevron Circle Left + search: + terms: + - previous + - back + - arrow + styles: + - solid + unicode: f137 +chevron-circle-right: + changes: + - '3.1' + - 5.0.0 + label: Chevron Circle Right + search: + terms: + - next + - forward + - arrow + styles: + - solid + unicode: f138 +chevron-circle-up: + changes: + - '3.1' + - 5.0.0 + label: Chevron Circle Up + search: + terms: + - arrow + styles: + - solid + unicode: f139 +chevron-down: + changes: + - '1' + - 5.0.0 + label: chevron-down + search: + terms: [] + styles: + - solid + unicode: f078 +chevron-left: + changes: + - '1' + - 5.0.0 + label: chevron-left + search: + terms: + - bracket + - previous + - back + styles: + - solid + unicode: f053 +chevron-right: + changes: + - '1' + - 5.0.0 + label: chevron-right + search: + terms: + - bracket + - next + - forward + styles: + - solid + unicode: f054 +chevron-up: + changes: + - '1' + - 5.0.0 + label: chevron-up + search: + terms: [] + styles: + - solid + unicode: f077 +child: + changes: + - '4.1' + - 5.0.0 + label: Child + search: + terms: [] + styles: + - solid + unicode: f1ae +chrome: + changes: + - '4.4' + - 5.0.0 + label: Chrome + search: + terms: + - browser + styles: + - brands + unicode: f268 +circle: + changes: + - '3' + - 5.0.0 + label: Circle + search: + terms: + - dot + - notification + - circle-thin + styles: + - solid + - regular + unicode: f111 +circle-notch: + changes: + - '4.1' + - 5.0.0 + label: Circle Notched + search: + terms: + - circle-o-notch + styles: + - solid + unicode: f1ce +clipboard: + changes: + - 5.0.0 + label: Clipboard + search: + terms: + - paste + styles: + - solid + - regular + unicode: f328 +clock: + changes: + - '1' + - 5.0.0 + label: Clock + search: + terms: + - watch + - timer + - late + - timestamp + - date + styles: + - solid + - regular + unicode: f017 +clone: + changes: + - '4.4' + - 5.0.0 + label: Clone + search: + terms: + - copy + styles: + - solid + - regular + unicode: f24d +closed-captioning: + changes: + - '4.2' + - 5.0.0 + label: Closed Captioning + search: + terms: + - cc + styles: + - solid + - regular + unicode: f20a +cloud: + changes: + - '2' + - 5.0.0 + label: Cloud + search: + terms: + - save + styles: + - solid + unicode: f0c2 +cloud-download-alt: + changes: + - 5.0.0 + label: Cloud Download-alt + search: + terms: + - cloud-download + styles: + - solid + unicode: f381 +cloud-upload-alt: + changes: + - 5.0.0 + label: Cloud Upload-alt + search: + terms: + - cloud-upload + styles: + - solid + unicode: f382 +cloudscale: + changes: + - 5.0.0 + label: cloudscale.ch + search: + terms: [] + sponsored: + label: cloudscale.ch + url: 'https://www.cloudscale.ch' + styles: + - brands + unicode: f383 +cloudsmith: + changes: + - 5.0.0 + label: Cloudsmith + search: + terms: [] + sponsored: + label: Cloudsmith + url: 'https://cloudsmith.io' + styles: + - brands + unicode: f384 +cloudversify: + changes: + - 5.0.0 + label: cloudversify + search: + terms: [] + sponsored: + label: cloudversify + url: 'https://www.cloudversify.com' + styles: + - brands + unicode: f385 +code: + changes: + - '3.1' + - 5.0.0 + label: Code + search: + terms: + - html + - brackets + styles: + - solid + unicode: f121 +code-branch: + changes: + - 5.0.0 + label: Code Branch + search: + terms: + - git + - fork + - vcs + - svn + - github + - rebase + - version + - branch + - code-fork + styles: + - solid + unicode: f126 +codepen: + changes: + - '4.1' + - 5.0.0 + label: Codepen + search: + terms: [] + styles: + - brands + unicode: f1cb +codiepie: + changes: + - '4.5' + - 5.0.0 + label: Codie Pie + search: + terms: [] + styles: + - brands + unicode: f284 +coffee: + changes: + - '3' + - 5.0.0 + label: Coffee + search: + terms: + - morning + - mug + - breakfast + - tea + - drink + - cafe + styles: + - solid + unicode: f0f4 +cog: + changes: + - '1' + - 5.0.0 + label: cog + search: + terms: + - settings + styles: + - solid + unicode: f013 +cogs: + changes: + - '1' + - 5.0.0 + label: cogs + search: + terms: + - settings + styles: + - solid + unicode: f085 +columns: + changes: + - '2' + - 5.0.0 + label: Columns + search: + terms: + - split + - panes + styles: + - solid + unicode: f0db +comment: + changes: + - '1' + - 5.0.0 + label: comment + search: + terms: + - speech + - notification + - note + - chat + - bubble + - feedback + - message + - texting + - sms + - conversation + styles: + - solid + - regular + unicode: f075 +comment-alt: + changes: + - '4.4' + - 5.0.0 + label: Alternate Comment + search: + terms: + - speech + - notification + - note + - chat + - bubble + - feedback + - message + - texting + - sms + - conversation + - commenting + - commenting + styles: + - solid + - regular + unicode: f27a +comments: + changes: + - '1' + - 5.0.0 + label: comments + search: + terms: + - speech + - notification + - note + - chat + - bubble + - feedback + - message + - texting + - sms + - conversation + styles: + - solid + - regular + unicode: f086 +compass: + changes: + - '3.2' + - 5.0.0 + label: Compass + search: + terms: + - safari + - directory + - menu + - location + styles: + - solid + - regular + unicode: f14e +compress: + changes: + - 5.0.0 + label: Compress + search: + terms: + - collapse + - combine + - contract + - merge + - smaller + styles: + - solid + unicode: f066 +connectdevelop: + changes: + - '4.3' + - 5.0.0 + label: Connect Develop + search: + terms: [] + styles: + - brands + unicode: f20e +contao: + changes: + - '4.4' + - 5.0.0 + label: Contao + search: + terms: [] + styles: + - brands + unicode: f26d +copy: + changes: + - '2' + - 5.0.0 + label: Copy + search: + terms: + - duplicate + - clone + - file + - files-o + styles: + - solid + - regular + unicode: f0c5 +copyright: + changes: + - '4.2' + - 5.0.0 + label: Copyright + search: + terms: [] + styles: + - solid + - regular + unicode: f1f9 +cpanel: + changes: + - 5.0.0 + label: cPanel + search: + terms: [] + sponsored: + label: cPanel + url: 'http://cpanel.com/' + styles: + - brands + unicode: f388 +creative-commons: + changes: + - '4.4' + - 5.0.0 + label: Creative Commons + search: + terms: [] + styles: + - brands + unicode: f25e +credit-card: + changes: + - '2' + - 5.0.0 + label: Credit Card + search: + terms: + - money + - buy + - debit + - checkout + - purchase + - payment + - credit-card-alt + styles: + - solid + - regular + unicode: f09d +crop: + changes: + - '3.1' + - 5.0.0 + label: crop + search: + terms: [] + styles: + - solid + unicode: f125 +crosshairs: + changes: + - '1' + - 5.0.0 + label: Crosshairs + search: + terms: + - picker + styles: + - solid + unicode: f05b +css3: + changes: + - '3.1' + - 5.0.0 + label: CSS 3 Logo + search: + terms: + - code + styles: + - brands + unicode: f13c +css3-alt: + changes: + - 5.0.0 + label: Alternate CSS3 Logo + search: + terms: [] + styles: + - brands + unicode: f38b +cube: + changes: + - '4.1' + - 5.0.0 + label: Cube + search: + terms: [] + styles: + - solid + unicode: f1b2 +cubes: + changes: + - '4.1' + - 5.0.0 + label: Cubes + search: + terms: [] + styles: + - solid + unicode: f1b3 +cut: + changes: + - '2' + - 5.0.0 + label: Cut + search: + terms: + - scissors + - scissors + styles: + - solid + unicode: f0c4 +cuttlefish: + changes: + - 5.0.0 + label: Cuttlefish + search: + terms: [] + sponsored: + label: Cuttlefish + url: 'http://wearecuttlefish.com' + styles: + - brands + unicode: f38c +d-and-d: + changes: + - 5.0.0 + label: Dungeons & Dragons + search: + terms: [] + styles: + - brands + unicode: f38d +dashcube: + changes: + - '4.3' + - 5.0.0 + label: DashCube + search: + terms: [] + styles: + - brands + unicode: f210 +database: + changes: + - '4.1' + - 5.0.0 + label: Database + search: + terms: [] + styles: + - solid + unicode: f1c0 +deaf: + changes: + - '4.6' + - 5.0.0 + label: Deaf + search: + terms: [] + styles: + - solid + unicode: f2a4 +delicious: + changes: + - '4.1' + - 5.0.0 + label: Delicious Logo + search: + terms: [] + styles: + - brands + unicode: f1a5 +deploydog: + changes: + - 5.0.0 + label: deploy.dog + search: + terms: [] + sponsored: + label: deploy.dog + url: 'http://deploy.dog' + styles: + - brands + unicode: f38e +deskpro: + changes: + - 5.0.0 + label: Deskpro + search: + terms: [] + sponsored: + label: Deskpro + url: 'http://www.deskpro.com' + styles: + - brands + unicode: f38f +desktop: + changes: + - '3' + - 5.0.0 + label: Desktop + search: + terms: + - monitor + - screen + - desktop + - computer + - demo + - device + styles: + - solid + unicode: f108 +deviantart: + changes: + - '4.1' + - 5.0.0 + label: deviantART + search: + terms: [] + styles: + - brands + unicode: f1bd +digg: + changes: + - '4.1' + - 5.0.0 + label: Digg Logo + search: + terms: [] + styles: + - brands + unicode: f1a6 +digital-ocean: + changes: + - 5.0.0 + label: Digital Ocean + search: + terms: [] + styles: + - brands + unicode: f391 +discord: + changes: + - 5.0.0 + label: Discord + search: + terms: [] + styles: + - brands + unicode: f392 +discourse: + changes: + - 5.0.0 + label: Discourse + search: + terms: [] + sponsored: + label: Discourse + url: 'https://discourse.org' + styles: + - brands + unicode: f393 +dochub: + changes: + - 5.0.0 + label: DocHub + search: + terms: [] + sponsored: + label: DocHub + url: 'https://dochub.com' + styles: + - brands + unicode: f394 +docker: + changes: + - 5.0.0 + label: Docker + search: + terms: [] + styles: + - brands + unicode: f395 +dollar-sign: + changes: + - '3.2' + - 5.0.0 + label: Dollar Sign + search: + terms: + - usd + - usd + styles: + - solid + unicode: f155 +dot-circle: + changes: + - '4' + - 5.0.0 + label: Dot Circle + search: + terms: + - target + - bullseye + - notification + styles: + - solid + - regular + unicode: f192 +download: + changes: + - '1' + - 5.0.0 + label: Download + search: + terms: + - import + styles: + - solid + unicode: f019 +draft2digital: + changes: + - 5.0.0 + label: Draft2digital + search: + terms: [] + sponsored: + label: Draft2Digital + url: 'http://draft2digital.com' + styles: + - brands + unicode: f396 +dribbble: + changes: + - 5.0.0 + label: Dribbble + search: + terms: [] + styles: + - brands + unicode: f17d +dribbble-square: + changes: + - 5.0.0 + label: Dribbble Square + search: + terms: [] + styles: + - brands + unicode: f397 +dropbox: + changes: + - '3.2' + - 5.0.0 + - 5.0.1 + label: Dropbox + search: + terms: [] + styles: + - brands + unicode: f16b +drupal: + changes: + - '4.1' + - 5.0.0 + label: Drupal Logo + search: + terms: [] + styles: + - brands + unicode: f1a9 +dyalog: + changes: + - 5.0.0 + label: Dyalog + search: + terms: [] + sponsored: + label: Dyalog APL + url: 'http://www.dyalog.com' + styles: + - brands + unicode: f399 +earlybirds: + changes: + - 5.0.0 + label: Earlybirds + search: + terms: [] + styles: + - brands + unicode: f39a +edge: + changes: + - '4.5' + - 5.0.0 + label: Edge Browser + search: + terms: + - browser + - ie + styles: + - brands + unicode: f282 +edit: + changes: + - '1' + - 5.0.0 + label: Edit + search: + terms: + - write + - edit + - update + - pencil + - pen + styles: + - solid + - regular + unicode: f044 +eject: + changes: + - '1' + - 5.0.0 + label: eject + search: + terms: [] + styles: + - solid + unicode: f052 +ellipsis-h: + changes: + - '3.1' + - 5.0.0 + label: Horizontal Ellipsis + search: + terms: + - dots + styles: + - solid + unicode: f141 +ellipsis-v: + changes: + - '3.1' + - 5.0.0 + label: Vertical Ellipsis + search: + terms: + - dots + styles: + - solid + unicode: f142 +ember: + changes: + - 5.0.0 + label: Ember + search: + terms: [] + styles: + - brands + unicode: f423 +empire: + changes: + - '4.1' + - 5.0.0 + label: Galactic Empire + search: + terms: [] + styles: + - brands + unicode: f1d1 +envelope: + changes: + - '2' + - 5.0.0 + label: Envelope + search: + terms: + - email + - e-mail + - letter + - support + - mail + - message + - notification + styles: + - solid + - regular + unicode: f0e0 +envelope-open: + changes: + - '4.7' + - 5.0.0 + label: Envelope Open + search: + terms: + - email + - e-mail + - letter + - support + - mail + - message + - notification + styles: + - solid + - regular + unicode: f2b6 +envelope-square: + changes: + - '4.1' + - 5.0.0 + label: Envelope Square + search: + terms: + - email + - e-mail + - letter + - support + - mail + - message + - notification + styles: + - solid + unicode: f199 +envira: + changes: + - '4.6' + - 5.0.0 + label: Envira Gallery + search: + terms: + - leaf + styles: + - brands + unicode: f299 +eraser: + changes: + - '3.1' + - 5.0.0 + label: eraser + search: + terms: + - remove + - delete + styles: + - solid + unicode: f12d +erlang: + changes: + - 5.0.0 + label: Erlang + search: + terms: [] + styles: + - brands + unicode: f39d +etsy: + changes: + - '4.7' + - 5.0.0 + label: Etsy + search: + terms: [] + styles: + - brands + unicode: f2d7 +euro-sign: + changes: + - '3.2' + - 5.0.0 + label: Euro Sign + search: + terms: + - eur + - eur + styles: + - solid + unicode: f153 +exchange-alt: + changes: + - 5.0.0 + label: Alternate Exchange + search: + terms: + - transfer + - arrows + - arrow + - exchange + styles: + - solid + unicode: f362 +exclamation: + changes: + - '3.1' + - 5.0.0 + label: exclamation + search: + terms: + - warning + - error + - problem + - notification + - notify + - alert + styles: + - solid + unicode: f12a +exclamation-circle: + changes: + - '1' + - 5.0.0 + label: Exclamation Circle + search: + terms: + - warning + - error + - problem + - notification + - notify + - alert + styles: + - solid + unicode: f06a +exclamation-triangle: + changes: + - '1' + - 5.0.0 + label: Exclamation Triangle + search: + terms: + - warning + - error + - problem + - notification + - notify + - alert + styles: + - solid + unicode: f071 +expand: + changes: + - 5.0.0 + label: Expand + search: + terms: + - enlarge + - bigger + - resize + styles: + - solid + unicode: f065 +expand-arrows-alt: + changes: + - 5.0.0 + label: Alternate Expand Arrows + search: + terms: + - enlarge + - bigger + - resize + - move + - arrows-alt + styles: + - solid + unicode: f31e +expeditedssl: + changes: + - '4.4' + - 5.0.0 + label: ExpeditedSSL + search: + terms: [] + styles: + - brands + unicode: f23e +external-link-alt: + changes: + - 5.0.0 + label: Alternate External Link + search: + terms: + - open + - new + - external-link + styles: + - solid + unicode: f35d +external-link-square-alt: + changes: + - 5.0.0 + label: Alternate External Link Square + search: + terms: + - open + - new + - external-link-square + styles: + - solid + unicode: f360 +eye: + changes: + - '1' + - 5.0.0 + label: Eye + search: + terms: + - show + - visible + - views + styles: + - solid + unicode: f06e +eye-dropper: + changes: + - '4.2' + - 5.0.0 + label: Eye Dropper + search: + terms: + - eyedropper + styles: + - solid + unicode: f1fb +eye-slash: + changes: + - '1' + - 5.0.0 + label: Eye Slash + search: + terms: + - toggle + - show + - hide + - visible + - visiblity + - views + styles: + - solid + - regular + unicode: f070 +facebook: + changes: + - '2' + - 5.0.0 + label: Facebook + search: + terms: + - social network + - facebook-official + styles: + - brands + unicode: f09a +facebook-f: + changes: + - 5.0.0 + label: Facebook F + search: + terms: + - facebook + styles: + - brands + unicode: f39e +facebook-messenger: + changes: + - 5.0.0 + label: Facebook Messenger + search: + terms: [] + styles: + - brands + unicode: f39f +facebook-square: + changes: + - '1' + - 5.0.0 + label: Facebook Square + search: + terms: + - social network + styles: + - brands + unicode: f082 +fast-backward: + changes: + - '1' + - 5.0.0 + label: fast-backward + search: + terms: + - rewind + - previous + - beginning + - start + - first + styles: + - solid + unicode: f049 +fast-forward: + changes: + - '1' + - 5.0.0 + label: fast-forward + search: + terms: + - next + - end + - last + styles: + - solid + unicode: f050 +fax: + changes: + - '4.1' + - 5.0.0 + label: Fax + search: + terms: [] + styles: + - solid + unicode: f1ac +female: + changes: + - '3.2' + - 5.0.0 + label: Female + search: + terms: + - woman + - user + - person + - profile + styles: + - solid + unicode: f182 +fighter-jet: + changes: + - '3' + - 5.0.0 + label: fighter-jet + search: + terms: + - fly + - plane + - airplane + - quick + - fast + - travel + styles: + - solid + unicode: f0fb +file: + changes: + - '3.2' + - 5.0.0 + label: File + search: + terms: + - new + - page + - pdf + - document + styles: + - solid + - regular + unicode: f15b +file-alt: + changes: + - '3.2' + - 5.0.0 + label: Alternate File + search: + terms: + - new + - page + - pdf + - document + - file-text + styles: + - solid + - regular + unicode: f15c +file-archive: + changes: + - '4.1' + - 5.0.0 + label: Archive File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c6 +file-audio: + changes: + - '4.1' + - 5.0.0 + label: Audio File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c7 +file-code: + changes: + - '4.1' + - 5.0.0 + label: Code File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c9 +file-excel: + changes: + - '4.1' + - 5.0.0 + label: Excel File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c3 +file-image: + changes: + - '4.1' + - 5.0.0 + label: Image File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c5 +file-pdf: + changes: + - '4.1' + - 5.0.0 + label: PDF File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c1 +file-powerpoint: + changes: + - '4.1' + - 5.0.0 + label: Powerpoint File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c4 +file-video: + changes: + - '4.1' + - 5.0.0 + label: Video File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c8 +file-word: + changes: + - '4.1' + - 5.0.0 + label: Word File + search: + terms: [] + styles: + - solid + - regular + unicode: f1c2 +film: + changes: + - '1' + - 5.0.0 + label: Film + search: + terms: + - movie + styles: + - solid + unicode: f008 +filter: + changes: + - '2' + - 5.0.0 + label: Filter + search: + terms: + - funnel + - options + styles: + - solid + unicode: f0b0 +fire: + changes: + - '1' + - 5.0.0 + label: fire + search: + terms: + - flame + - hot + - popular + styles: + - solid + unicode: f06d +fire-extinguisher: + changes: + - '3.1' + - 5.0.0 + label: fire-extinguisher + search: + terms: [] + styles: + - solid + unicode: f134 +firefox: + changes: + - '4.4' + - 5.0.0 + - 5.0.1 + label: Firefox + search: + terms: + - browser + styles: + - brands + unicode: f269 +first-order: + changes: + - '4.6' + - 5.0.0 + label: First Order + search: + terms: [] + styles: + - brands + unicode: f2b0 +firstdraft: + changes: + - 5.0.0 + label: firstdraft + search: + terms: [] + sponsored: + label: firstdraft + url: 'http://www.firstdraft.com' + styles: + - brands + unicode: f3a1 +flag: + changes: + - '1' + - 5.0.0 + label: flag + search: + terms: + - report + - notification + - notify + styles: + - solid + - regular + unicode: f024 +flag-checkered: + changes: + - '3.1' + - 5.0.0 + label: flag-checkered + search: + terms: + - report + - notification + - notify + styles: + - solid + unicode: f11e +flask: + changes: + - '2' + - 5.0.0 + label: Flask + search: + terms: + - science + - beaker + - experimental + - labs + styles: + - solid + unicode: f0c3 +flickr: + changes: + - '3.2' + - 5.0.0 + label: Flickr + search: + terms: [] + styles: + - brands + unicode: f16e +fly: + changes: + - 5.0.0 + label: Fly + search: + terms: [] + styles: + - brands + unicode: f417 +folder: + changes: + - '1' + - 5.0.0 + label: Folder + search: + terms: [] + styles: + - solid + - regular + unicode: f07b +folder-open: + changes: + - '1' + - 5.0.0 + label: Folder Open + search: + terms: [] + styles: + - solid + - regular + unicode: f07c +font: + changes: + - '1' + - 5.0.0 + label: font + search: + terms: + - text + styles: + - solid + unicode: f031 +font-awesome: + changes: + - '4.6' + - 5.0.0 + label: Font Awesome + search: + terms: + - meanpath + styles: + - brands + unicode: f2b4 +font-awesome-alt: + changes: + - 5.0.0 + label: Alternate Font Awesome + search: + terms: [] + styles: + - brands + unicode: f35c +font-awesome-flag: + changes: + - 5.0.0 + - 5.0.1 + label: Font Awesome Flag + search: + terms: [] + styles: + - brands + unicode: f425 +fonticons: + changes: + - '4.4' + - 5.0.0 + label: Fonticons + search: + terms: [] + styles: + - brands + unicode: f280 +fonticons-fi: + changes: + - 5.0.0 + label: Fonticons Fi + search: + terms: [] + styles: + - brands + unicode: f3a2 +fort-awesome: + changes: + - '4.5' + - 5.0.0 + label: Fort Awesome + search: + terms: [] + styles: + - brands + unicode: f286 +fort-awesome-alt: + changes: + - 5.0.0 + label: Alternate Fort Awesome + search: + terms: [] + styles: + - brands + unicode: f3a3 +forumbee: + changes: + - '4.3' + - 5.0.0 + label: Forumbee + search: + terms: [] + styles: + - brands + unicode: f211 +forward: + changes: + - '1' + - 5.0.0 + label: forward + search: + terms: + - forward + - next + styles: + - solid + unicode: f04e +foursquare: + changes: + - '3.2' + - 5.0.0 + label: Foursquare + search: + terms: [] + styles: + - brands + unicode: f180 +free-code-camp: + changes: + - '4.7' + - 5.0.0 + label: Free Code Camp + search: + terms: [] + styles: + - brands + unicode: f2c5 +freebsd: + changes: + - 5.0.0 + label: FreeBSD + search: + terms: [] + styles: + - brands + unicode: f3a4 +frown: + changes: + - '3.1' + - 5.0.0 + label: Frown + search: + terms: + - face + - emoticon + - sad + - disapprove + - rating + styles: + - solid + - regular + unicode: f119 +futbol: + changes: + - '4.2' + - 5.0.0 + label: Futbol + search: + terms: [] + styles: + - solid + - regular + unicode: f1e3 +gamepad: + changes: + - '3.1' + - 5.0.0 + label: Gamepad + search: + terms: + - controller + styles: + - solid + unicode: f11b +gavel: + changes: + - '2' + - 5.0.0 + label: Gavel + search: + terms: + - judge + - lawyer + - opinion + styles: + - solid + unicode: f0e3 +gem: + changes: + - 5.0.0 + label: Gem + search: + terms: + - diamond + styles: + - solid + - regular + unicode: f3a5 +genderless: + changes: + - '4.4' + - 5.0.0 + label: Genderless + search: + terms: [] + styles: + - solid + unicode: f22d +get-pocket: + changes: + - '4.4' + - 5.0.0 + label: Get Pocket + search: + terms: [] + styles: + - brands + unicode: f265 +gg: + changes: + - '4.4' + - 5.0.0 + label: GG Currency + search: + terms: [] + styles: + - brands + unicode: f260 +gg-circle: + changes: + - '4.4' + - 5.0.0 + label: GG Currency Circle + search: + terms: [] + styles: + - brands + unicode: f261 +gift: + changes: + - '1' + - 5.0.0 + label: gift + search: + terms: + - present + styles: + - solid + unicode: f06b +git: + changes: + - '4.1' + - 5.0.0 + label: Git + search: + terms: [] + styles: + - brands + unicode: f1d3 +git-square: + changes: + - '4.1' + - 5.0.0 + label: Git Square + search: + terms: [] + styles: + - brands + unicode: f1d2 +github: + changes: + - '2' + - 5.0.0 + label: GitHub + search: + terms: + - octocat + styles: + - brands + unicode: f09b +github-alt: + changes: + - '3' + - 5.0.0 + label: Alternate GitHub + search: + terms: + - octocat + styles: + - brands + unicode: f113 +github-square: + changes: + - '1' + - 5.0.0 + label: GitHub Square + search: + terms: + - octocat + styles: + - brands + unicode: f092 +gitkraken: + changes: + - 5.0.0 + label: GitKraken + search: + terms: [] + styles: + - brands + unicode: f3a6 +gitlab: + changes: + - '4.6' + - 5.0.0 + label: GitLab + search: + terms: + - Axosoft + styles: + - brands + unicode: f296 +gitter: + changes: + - 5.0.0 + label: Gitter + search: + terms: [] + styles: + - brands + unicode: f426 +glass-martini: + changes: + - '1' + - 5.0.0 + label: Martini Glass + search: + terms: + - martini + - drink + - bar + - alcohol + - liquor + - glass + styles: + - solid + unicode: f000 +glide: + changes: + - '4.6' + - 5.0.0 + label: Glide + search: + terms: [] + styles: + - brands + unicode: f2a5 +glide-g: + changes: + - '4.6' + - 5.0.0 + label: Glide G + search: + terms: [] + styles: + - brands + unicode: f2a6 +globe: + changes: + - '2' + - 5.0.0 + label: Globe + search: + terms: + - world + - planet + - map + - place + - travel + - earth + - global + - translate + - all + - language + - localize + - location + - coordinates + - country + styles: + - solid + unicode: f0ac +gofore: + changes: + - 5.0.0 + label: Gofore + search: + terms: [] + sponsored: + label: Gofore + url: 'http://gofore.com' + styles: + - brands + unicode: f3a7 +goodreads: + changes: + - 5.0.0 + label: Goodreads + search: + terms: [] + styles: + - brands + unicode: f3a8 +goodreads-g: + changes: + - 5.0.0 + label: Goodreads G + search: + terms: [] + styles: + - brands + unicode: f3a9 +google: + changes: + - '4.1' + - 5.0.0 + label: Google Logo + search: + terms: [] + styles: + - brands + unicode: f1a0 +google-drive: + changes: + - 5.0.0 + label: Google Drive + search: + terms: [] + styles: + - brands + unicode: f3aa +google-play: + changes: + - 5.0.0 + label: Google Play + search: + terms: [] + styles: + - brands + unicode: f3ab +google-plus: + changes: + - '4.6' + - 5.0.0 + label: Google Plus + search: + terms: + - google-plus-circle + - google-plus-official + styles: + - brands + unicode: f2b3 +google-plus-g: + changes: + - '2' + - 5.0.0 + label: Google Plus G + search: + terms: + - social network + - google-plus + styles: + - brands + unicode: f0d5 +google-plus-square: + changes: + - '2' + - 5.0.0 + label: Google Plus Square + search: + terms: + - social network + styles: + - brands + unicode: f0d4 +google-wallet: + changes: + - '4.2' + - 5.0.0 + label: Google Wallet + search: + terms: [] + styles: + - brands + unicode: f1ee +graduation-cap: + changes: + - '4.1' + - 5.0.0 + label: Graduation Cap + search: + terms: + - learning + - school + - student + styles: + - solid + unicode: f19d +gratipay: + changes: + - '3.2' + - 5.0.0 + label: Gratipay (Gittip) + search: + terms: + - heart + - like + - favorite + - love + styles: + - brands + unicode: f184 +grav: + changes: + - '4.7' + - 5.0.0 + label: Grav + search: + terms: [] + styles: + - brands + unicode: f2d6 +gripfire: + changes: + - 5.0.0 + label: 'Gripfire, Inc.' + search: + terms: [] + sponsored: + label: 'Gripfire, Inc.' + url: 'http://gripfire.io' + styles: + - brands + unicode: f3ac +grunt: + changes: + - 5.0.0 + label: Grunt + search: + terms: [] + styles: + - brands + unicode: f3ad +gulp: + changes: + - 5.0.0 + label: Gulp + search: + terms: [] + styles: + - brands + unicode: f3ae +h-square: + changes: + - '3' + - 5.0.0 + label: H Square + search: + terms: + - hospital + - hotel + styles: + - solid + unicode: f0fd +hacker-news: + changes: + - '4.1' + - 5.0.0 + label: Hacker News + search: + terms: [] + styles: + - brands + unicode: f1d4 +hacker-news-square: + changes: + - 5.0.0 + label: Hacker News Square + search: + terms: [] + styles: + - brands + unicode: f3af +hand-lizard: + changes: + - '4.4' + - 5.0.0 + label: Lizard (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f258 +hand-paper: + changes: + - '4.4' + - 5.0.0 + label: Paper (Hand) + search: + terms: + - stop + styles: + - solid + - regular + unicode: f256 +hand-peace: + changes: + - '4.4' + - 5.0.0 + label: Peace (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f25b +hand-point-down: + changes: + - '2' + - 5.0.0 + label: Hand Pointing Down + search: + terms: + - point + - finger + - hand-o-down + styles: + - solid + - regular + unicode: f0a7 +hand-point-left: + changes: + - '2' + - 5.0.0 + label: Hand Pointing Left + search: + terms: + - point + - left + - previous + - back + - finger + - hand-o-left + styles: + - solid + - regular + unicode: f0a5 +hand-point-right: + changes: + - '2' + - 5.0.0 + label: Hand Pointing Right + search: + terms: + - point + - right + - next + - forward + - finger + - hand-o-right + styles: + - solid + - regular + unicode: f0a4 +hand-point-up: + changes: + - '2' + - 5.0.0 + label: Hand Pointing Up + search: + terms: + - point + - finger + - hand-o-up + styles: + - solid + - regular + unicode: f0a6 +hand-pointer: + changes: + - '4.4' + - 5.0.0 + label: Pointer (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f25a +hand-rock: + changes: + - '4.4' + - 5.0.0 + label: Rock (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f255 +hand-scissors: + changes: + - '4.4' + - 5.0.0 + label: Scissors (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f257 +hand-spock: + changes: + - '4.4' + - 5.0.0 + label: Spock (Hand) + search: + terms: [] + styles: + - solid + - regular + unicode: f259 +handshake: + changes: + - '4.7' + - 5.0.0 + label: Handshake + search: + terms: [] + styles: + - solid + - regular + unicode: f2b5 +hashtag: + changes: + - '4.5' + - 5.0.0 + label: Hashtag + search: + terms: [] + styles: + - solid + unicode: f292 +hdd: + changes: + - '2' + - 5.0.0 + label: HDD + search: + terms: + - harddrive + - hard drive + - storage + - save + styles: + - solid + - regular + unicode: f0a0 +heading: + changes: + - '4.1' + - 5.0.0 + label: heading + search: + terms: + - header + - header + styles: + - solid + unicode: f1dc +headphones: + changes: + - '1' + - 5.0.0 + label: headphones + search: + terms: + - sound + - listen + - music + - audio + styles: + - solid + unicode: f025 +heart: + changes: + - '1' + - 5.0.0 + label: Heart + search: + terms: + - love + - like + - favorite + styles: + - solid + - regular + unicode: f004 +heartbeat: + changes: + - '4.3' + - 5.0.0 + label: Heartbeat + search: + terms: + - ekg + styles: + - solid + unicode: f21e +hire-a-helper: + changes: + - 5.0.0 + label: HireAHelper + search: + terms: [] + sponsored: + label: HireAHelper + url: 'https://www.hireahelper.com' + styles: + - brands + unicode: f3b0 +history: + changes: + - '4.1' + - 5.0.0 + label: History + search: + terms: [] + styles: + - solid + unicode: f1da +home: + changes: + - '1' + - 5.0.0 + label: home + search: + terms: + - main + - house + styles: + - solid + unicode: f015 +hooli: + changes: + - 5.0.0 + label: Hooli + search: + terms: [] + styles: + - brands + unicode: f427 +hospital: + changes: + - '3' + - 5.0.0 + label: hospital + search: + terms: + - building + styles: + - solid + - regular + unicode: f0f8 +hotjar: + changes: + - 5.0.0 + label: Hotjar + search: + terms: [] + sponsored: + label: Hotjar + url: 'https://www.hotjar.com' + styles: + - brands + unicode: f3b1 +hourglass: + changes: + - '4.4' + - 5.0.0 + label: Hourglass + search: + terms: [] + styles: + - solid + - regular + unicode: f254 +hourglass-end: + changes: + - '4.4' + - 5.0.0 + label: Hourglass End + search: + terms: [] + styles: + - solid + unicode: f253 +hourglass-half: + changes: + - '4.4' + - 5.0.0 + label: Hourglass Half + search: + terms: [] + styles: + - solid + unicode: f252 +hourglass-start: + changes: + - '4.4' + - 5.0.0 + label: Hourglass Start + search: + terms: [] + styles: + - solid + unicode: f251 +houzz: + changes: + - '4.4' + - 5.0.0 + label: Houzz + search: + terms: [] + styles: + - brands + unicode: f27c +html5: + changes: + - '3.1' + - 5.0.0 + label: HTML 5 Logo + search: + terms: [] + styles: + - brands + unicode: f13b +hubspot: + changes: + - 5.0.0 + label: HubSpot + search: + terms: [] + sponsored: + label: HubSpot + url: 'http://www.HubSpot.com' + styles: + - brands + unicode: f3b2 +i-cursor: + changes: + - '4.4' + - 5.0.0 + label: I Beam Cursor + search: + terms: [] + styles: + - solid + unicode: f246 +id-badge: + changes: + - '4.7' + - 5.0.0 + label: Identification Badge + search: + terms: [] + styles: + - solid + - regular + unicode: f2c1 +id-card: + changes: + - '4.7' + - 5.0.0 + label: Identification Card + search: + terms: [] + styles: + - solid + - regular + unicode: f2c2 +image: + changes: + - '1' + - 5.0.0 + label: Image + search: + terms: + - photo + - album + - picture + - picture + styles: + - solid + - regular + unicode: f03e +images: + changes: + - '1' + - 5.0.0 + label: Images + search: + terms: + - photo + - album + - picture + styles: + - solid + - regular + unicode: f302 +imdb: + changes: + - '4.7' + - 5.0.0 + label: IMDB + search: + terms: [] + styles: + - brands + unicode: f2d8 +inbox: + changes: + - '1' + - 5.0.0 + label: inbox + search: + terms: [] + styles: + - solid + unicode: f01c +indent: + changes: + - '1' + - 5.0.0 + label: Indent + search: + terms: [] + styles: + - solid + unicode: f03c +industry: + changes: + - '4.4' + - 5.0.0 + label: Industry + search: + terms: + - factory + styles: + - solid + unicode: f275 +info: + changes: + - '3.1' + - 5.0.0 + label: Info + search: + terms: + - help + - information + - more + - details + styles: + - solid + unicode: f129 +info-circle: + changes: + - '1' + - 5.0.0 + label: Info Circle + search: + terms: + - help + - information + - more + - details + styles: + - solid + unicode: f05a +instagram: + changes: + - '4.6' + - 5.0.0 + label: Instagram + search: + terms: [] + styles: + - brands + unicode: f16d +internet-explorer: + changes: + - '4.4' + - 5.0.0 + label: Internet-explorer + search: + terms: + - browser + - ie + styles: + - brands + unicode: f26b +ioxhost: + changes: + - '4.2' + - 5.0.0 + label: ioxhost + search: + terms: [] + styles: + - brands + unicode: f208 +italic: + changes: + - '1' + - 5.0.0 + label: italic + search: + terms: + - italics + styles: + - solid + unicode: f033 +itunes: + changes: + - 5.0.0 + label: iTunes + search: + terms: [] + styles: + - brands + unicode: f3b4 +itunes-note: + changes: + - 5.0.0 + label: Itunes Note + search: + terms: [] + styles: + - brands + unicode: f3b5 +jenkins: + changes: + - 5.0.0 + label: Jenkis + search: + terms: [] + styles: + - brands + unicode: f3b6 +joget: + changes: + - 5.0.0 + label: Joget + search: + terms: [] + sponsored: + label: Joget + url: 'http://www.joget.org' + styles: + - brands + unicode: f3b7 +joomla: + changes: + - '4.1' + - 5.0.0 + label: Joomla Logo + search: + terms: [] + styles: + - brands + unicode: f1aa +js: + changes: + - 5.0.0 + label: JavaScript (JS) + search: + terms: [] + styles: + - brands + unicode: f3b8 +js-square: + changes: + - 5.0.0 + label: JavaScript (JS) Square + search: + terms: [] + styles: + - brands + unicode: f3b9 +jsfiddle: + changes: + - '4.1' + - 5.0.0 + label: jsFiddle + search: + terms: [] + styles: + - brands + unicode: f1cc +key: + changes: + - '1' + - 5.0.0 + label: key + search: + terms: + - unlock + - password + styles: + - solid + unicode: f084 +keyboard: + changes: + - '3.1' + - 5.0.0 + label: Keyboard + search: + terms: + - type + - input + styles: + - solid + - regular + unicode: f11c +keycdn: + changes: + - 5.0.0 + label: KeyCDN + search: + terms: [] + sponsored: + label: KeyCDN + url: 'https://www.keycdn.com' + styles: + - brands + unicode: f3ba +kickstarter: + changes: + - 5.0.0 + label: Kickstarter + search: + terms: [] + styles: + - brands + unicode: f3bb +kickstarter-k: + changes: + - 5.0.0 + label: Kickstarter K + search: + terms: [] + styles: + - brands + unicode: f3bc +language: + changes: + - '4.1' + - 5.0.0 + label: Language + search: + terms: [] + styles: + - solid + unicode: f1ab +laptop: + changes: + - '3' + - 5.0.0 + label: Laptop + search: + terms: + - demo + - computer + - device + styles: + - solid + unicode: f109 +laravel: + changes: + - 5.0.0 + label: Laravel + search: + terms: [] + styles: + - brands + unicode: f3bd +lastfm: + changes: + - '4.2' + - 5.0.0 + label: last.fm + search: + terms: [] + styles: + - brands + unicode: f202 +lastfm-square: + changes: + - '4.2' + - 5.0.0 + label: last.fm Square + search: + terms: [] + styles: + - brands + unicode: f203 +leaf: + changes: + - '1' + - 5.0.0 + label: leaf + search: + terms: + - eco + - nature + - plant + styles: + - solid + unicode: f06c +leanpub: + changes: + - '4.3' + - 5.0.0 + label: Leanpub + search: + terms: [] + styles: + - brands + unicode: f212 +lemon: + changes: + - '1' + - 5.0.0 + label: Lemon + search: + terms: + - food + styles: + - solid + - regular + unicode: f094 +less: + changes: + - 5.0.0 + label: Less + search: + terms: [] + styles: + - brands + unicode: f41d +level-down-alt: + changes: + - 5.0.0 + label: Level Down-alt + search: + terms: + - level-down + styles: + - solid + unicode: f3be +level-up-alt: + changes: + - 5.0.0 + label: Level Up-alt + search: + terms: + - level-up + styles: + - solid + unicode: f3bf +life-ring: + changes: + - '4.1' + - 5.0.0 + label: Life Ring + search: + terms: + - support + styles: + - solid + - regular + unicode: f1cd +lightbulb: + changes: + - '3' + - 5.0.0 + label: Lightbulb + search: + terms: + - idea + - inspiration + styles: + - solid + - regular + unicode: f0eb +line: + changes: + - 5.0.0 + label: Line + search: + terms: [] + styles: + - brands + unicode: f3c0 +link: + changes: + - '2' + - 5.0.0 + label: Link + search: + terms: + - chain + styles: + - solid + unicode: f0c1 +linkedin: + changes: + - '1' + - 5.0.0 + label: LinkedIn + search: + terms: + - linkedin-square + styles: + - brands + unicode: f08c +linkedin-in: + changes: + - '2' + - 5.0.0 + label: LinkedIn In + search: + terms: + - linkedin + styles: + - brands + unicode: f0e1 +linode: + changes: + - '4.7' + - 5.0.0 + label: Linode + search: + terms: [] + styles: + - brands + unicode: f2b8 +linux: + changes: + - '3.2' + - 5.0.0 + label: Linux + search: + terms: + - tux + styles: + - brands + unicode: f17c +lira-sign: + changes: + - '4' + - 5.0.0 + label: Turkish Lira Sign + search: + terms: + - try + - turkish + - try + styles: + - solid + unicode: f195 +list: + changes: + - '1' + - 5.0.0 + label: list + search: + terms: + - ul + - ol + - checklist + - finished + - completed + - done + - todo + styles: + - solid + unicode: f03a +list-alt: + changes: + - '1' + - 5.0.0 + label: list-alt + search: + terms: + - ul + - ol + - checklist + - finished + - completed + - done + - todo + styles: + - solid + - regular + unicode: f022 +list-ol: + changes: + - '2' + - 5.0.0 + label: list-ol + search: + terms: + - ul + - ol + - checklist + - list + - todo + - list + - numbers + styles: + - solid + unicode: f0cb +list-ul: + changes: + - '2' + - 5.0.0 + label: list-ul + search: + terms: + - ul + - ol + - checklist + - todo + - list + styles: + - solid + unicode: f0ca +location-arrow: + changes: + - '3.1' + - 5.0.0 + label: location-arrow + search: + terms: + - map + - coordinates + - location + - address + - place + - where + styles: + - solid + unicode: f124 +lock: + changes: + - '1' + - 5.0.0 + label: lock + search: + terms: + - protect + - admin + - security + styles: + - solid + unicode: f023 +lock-open: + changes: + - '3.1' + - 5.0.0 + - 5.0.1 + label: Lock Open + search: + terms: + - protect + - admin + - password + - lock + - open + styles: + - solid + unicode: f3c1 +long-arrow-alt-down: + changes: + - 5.0.0 + label: Alternate Long Arrow Down + search: + terms: + - long-arrow-down + styles: + - solid + unicode: f309 +long-arrow-alt-left: + changes: + - 5.0.0 + label: Alternate Long Arrow Left + search: + terms: + - previous + - back + - long-arrow-left + styles: + - solid + unicode: f30a +long-arrow-alt-right: + changes: + - 5.0.0 + label: Alternate Long Arrow Right + search: + terms: + - long-arrow-right + styles: + - solid + unicode: f30b +long-arrow-alt-up: + changes: + - 5.0.0 + label: Alternate Long Arrow Up + search: + terms: + - long-arrow-up + styles: + - solid + unicode: f30c +low-vision: + changes: + - '4.6' + - 5.0.0 + label: Low Vision + search: + terms: [] + styles: + - solid + unicode: f2a8 +lyft: + changes: + - 5.0.0 + label: lyft + search: + terms: [] + styles: + - brands + unicode: f3c3 +magento: + changes: + - 5.0.0 + label: Magento + search: + terms: [] + styles: + - brands + unicode: f3c4 +magic: + changes: + - '2' + - 5.0.0 + label: magic + search: + terms: + - wizard + - automatic + - autocomplete + styles: + - solid + unicode: f0d0 +magnet: + changes: + - '1' + - 5.0.0 + label: magnet + search: + terms: [] + styles: + - solid + unicode: f076 +male: + changes: + - '3.2' + - 5.0.0 + label: Male + search: + terms: + - man + - user + - person + - profile + styles: + - solid + unicode: f183 +map: + changes: + - '4.4' + - 5.0.0 + label: Map + search: + terms: [] + styles: + - solid + - regular + unicode: f279 +map-marker: + changes: + - '1' + - 5.0.0 + label: map-marker + search: + terms: + - map + - pin + - location + - coordinates + - localize + - address + - travel + - where + - place + styles: + - solid + unicode: f041 +map-marker-alt: + changes: + - 5.0.0 + label: Map Marker-alt + search: + terms: + - map-marker + styles: + - solid + unicode: f3c5 +map-pin: + changes: + - '4.4' + - 5.0.0 + label: Map Pin + search: + terms: [] + styles: + - solid + unicode: f276 +map-signs: + changes: + - '4.4' + - 5.0.0 + label: Map Signs + search: + terms: [] + styles: + - solid + unicode: f277 +mars: + changes: + - '4.3' + - 5.0.0 + label: Mars + search: + terms: + - male + styles: + - solid + unicode: f222 +mars-double: + changes: + - '4.3' + - 5.0.0 + label: Mars Double + search: + terms: [] + styles: + - solid + unicode: f227 +mars-stroke: + changes: + - '4.3' + - 5.0.0 + label: Mars Stroke + search: + terms: [] + styles: + - solid + unicode: f229 +mars-stroke-h: + changes: + - '4.3' + - 5.0.0 + label: Mars Stroke Horizontal + search: + terms: [] + styles: + - solid + unicode: f22b +mars-stroke-v: + changes: + - '4.3' + - 5.0.0 + label: Mars Stroke Vertical + search: + terms: [] + styles: + - solid + unicode: f22a +maxcdn: + changes: + - '3.1' + - 5.0.0 + label: MaxCDN + search: + terms: [] + styles: + - brands + unicode: f136 +medapps: + changes: + - 5.0.0 + label: MedApps + search: + terms: [] + sponsored: + label: MedApps + url: 'http://medapps.com.au' + styles: + - brands + unicode: f3c6 +medium: + changes: + - '4.3' + - 5.0.0 + label: Medium + search: + terms: [] + styles: + - brands + unicode: f23a +medium-m: + changes: + - 5.0.0 + label: Medium M + search: + terms: [] + styles: + - brands + unicode: f3c7 +medkit: + changes: + - '3' + - 5.0.0 + label: medkit + search: + terms: + - first aid + - firstaid + - help + - support + - health + styles: + - solid + unicode: f0fa +medrt: + changes: + - 5.0.0 + label: MRT + search: + terms: [] + sponsored: + label: MRT + url: 'https://medrt.co.jp/' + styles: + - brands + unicode: f3c8 +meetup: + changes: + - '4.7' + - 5.0.0 + label: Meetup + search: + terms: [] + styles: + - brands + unicode: f2e0 +meh: + changes: + - '3.1' + - 5.0.0 + label: Meh + search: + terms: + - face + - emoticon + - rating + - neutral + styles: + - solid + - regular + unicode: f11a +mercury: + changes: + - '4.3' + - 5.0.0 + label: Mercury + search: + terms: + - transgender + styles: + - solid + unicode: f223 +microchip: + changes: + - '4.7' + - 5.0.0 + label: Microchip + search: + terms: [] + styles: + - solid + unicode: f2db +microphone: + changes: + - '3.1' + - 5.0.0 + label: microphone + search: + terms: + - record + - voice + - sound + styles: + - solid + unicode: f130 +microphone-slash: + changes: + - '3.1' + - 5.0.0 + label: Microphone Slash + search: + terms: + - record + - voice + - sound + - mute + styles: + - solid + unicode: f131 +microsoft: + changes: + - 5.0.0 + label: Microsoft + search: + terms: [] + styles: + - brands + unicode: f3ca +minus: + changes: + - '1' + - 5.0.0 + label: minus + search: + terms: + - hide + - minify + - delete + - remove + - trash + - hide + - collapse + styles: + - solid + unicode: f068 +minus-circle: + changes: + - '1' + - 5.0.0 + label: Minus Circle + search: + terms: + - delete + - remove + - trash + - hide + styles: + - solid + unicode: f056 +minus-square: + changes: + - '3.1' + - 5.0.0 + label: Minus Square + search: + terms: + - hide + - minify + - delete + - remove + - trash + - hide + - collapse + styles: + - solid + - regular + unicode: f146 +mix: + changes: + - 5.0.0 + label: Mix + search: + terms: [] + sponsored: + label: Mix + url: 'http://mix.com' + styles: + - brands + unicode: f3cb +mixcloud: + changes: + - '4.5' + - 5.0.0 + label: Mixcloud + search: + terms: [] + styles: + - brands + unicode: f289 +mizuni: + changes: + - 5.0.0 + label: Mizuni + search: + terms: [] + sponsored: + label: Mizuni + url: 'http://www.mizuni.com' + styles: + - brands + unicode: f3cc +mobile: + changes: + - '3' + - 5.0.0 + label: Mobile Phone + search: + terms: + - cell phone + - cellphone + - text + - call + - iphone + - number + - telephone + styles: + - solid + unicode: f10b +mobile-alt: + changes: + - 5.0.0 + label: Alternate Mobile + search: + terms: + - mobile + styles: + - solid + unicode: f3cd +modx: + changes: + - '4.5' + - 5.0.0 + label: MODX + search: + terms: [] + styles: + - brands + unicode: f285 +monero: + changes: + - 5.0.0 + label: Monero + search: + terms: [] + styles: + - brands + unicode: f3d0 +money-bill-alt: + changes: + - 5.0.0 + label: Money Bill-alt + search: + terms: + - money + styles: + - solid + - regular + unicode: f3d1 +moon: + changes: + - '3.2' + - 5.0.0 + label: Moon + search: + terms: + - night + - darker + - contrast + styles: + - solid + - regular + unicode: f186 +motorcycle: + changes: + - '4.3' + - 5.0.0 + label: Motorcycle + search: + terms: + - vehicle + - bike + styles: + - solid + unicode: f21c +mouse-pointer: + changes: + - '4.4' + - 5.0.0 + label: Mouse Pointer + search: + terms: [] + styles: + - solid + unicode: f245 +music: + changes: + - '1' + - 5.0.0 + label: Music + search: + terms: + - note + - sound + styles: + - solid + unicode: f001 +napster: + changes: + - 5.0.0 + label: Napster + search: + terms: [] + sponsored: + label: Napster + url: 'http://www.napster.com' + styles: + - brands + unicode: f3d2 +neuter: + changes: + - '4.3' + - 5.0.0 + label: Neuter + search: + terms: [] + styles: + - solid + unicode: f22c +newspaper: + changes: + - '4.2' + - 5.0.0 + label: Newspaper + search: + terms: + - press + styles: + - solid + - regular + unicode: f1ea +nintendo-switch: + changes: + - 5.0.0 + label: Nintendo Switch + search: + terms: [] + styles: + - brands + unicode: f418 +node: + changes: + - 5.0.0 + label: Node.js + search: + terms: [] + styles: + - brands + unicode: f419 +node-js: + changes: + - 5.0.0 + label: Node.js JS + search: + terms: [] + styles: + - brands + unicode: f3d3 +npm: + changes: + - 5.0.0 + label: npm + search: + terms: [] + styles: + - brands + unicode: f3d4 +ns8: + changes: + - 5.0.0 + label: NS8 + search: + terms: [] + styles: + - brands + unicode: f3d5 +nutritionix: + changes: + - 5.0.0 + label: Nutritionix + search: + terms: [] + sponsored: + label: Nutritionix + url: 'http://www.nutritionix.com' + styles: + - brands + unicode: f3d6 +object-group: + changes: + - '4.4' + - 5.0.0 + label: Object Group + search: + terms: [] + styles: + - solid + - regular + unicode: f247 +object-ungroup: + changes: + - '4.4' + - 5.0.0 + label: Object Ungroup + search: + terms: [] + styles: + - solid + - regular + unicode: f248 +odnoklassniki: + changes: + - '4.4' + - 5.0.0 + label: Odnoklassniki + search: + terms: [] + styles: + - brands + unicode: f263 +odnoklassniki-square: + changes: + - '4.4' + - 5.0.0 + label: Odnoklassniki Square + search: + terms: [] + styles: + - brands + unicode: f264 +opencart: + changes: + - '4.4' + - 5.0.0 + label: OpenCart + search: + terms: [] + styles: + - brands + unicode: f23d +openid: + changes: + - '4.1' + - 5.0.0 + label: OpenID + search: + terms: [] + styles: + - brands + unicode: f19b +opera: + changes: + - '4.4' + - 5.0.0 + label: Opera + search: + terms: [] + styles: + - brands + unicode: f26a +optin-monster: + changes: + - '4.4' + - 5.0.0 + label: Optin Monster + search: + terms: [] + styles: + - brands + unicode: f23c +osi: + changes: + - 5.0.0 + label: Open Source Initiative + search: + terms: [] + styles: + - brands + unicode: f41a +outdent: + changes: + - '1' + - 5.0.0 + label: Outdent + search: + terms: [] + styles: + - solid + unicode: f03b +page4: + changes: + - 5.0.0 + label: page4 Corporation + search: + terms: [] + sponsored: + label: page4 Corporation + url: 'https://en.page4.com/' + styles: + - brands + unicode: f3d7 +pagelines: + changes: + - '4' + - 5.0.0 + label: Pagelines + search: + terms: + - leaf + - leaves + - tree + - plant + - eco + - nature + styles: + - brands + unicode: f18c +paint-brush: + changes: + - '4.2' + - 5.0.0 + label: Paint Brush + search: + terms: [] + styles: + - solid + unicode: f1fc +palfed: + changes: + - 5.0.0 + label: Palfed + search: + terms: [] + sponsored: + label: PalFed + url: 'https://www.palfed.com' + styles: + - brands + unicode: f3d8 +paper-plane: + changes: + - '4.1' + - 5.0.0 + label: Paper Plane + search: + terms: [] + styles: + - solid + - regular + unicode: f1d8 +paperclip: + changes: + - '2' + - 5.0.0 + label: Paperclip + search: + terms: + - attachment + styles: + - solid + unicode: f0c6 +paragraph: + changes: + - '4.1' + - 5.0.0 + label: paragraph + search: + terms: [] + styles: + - solid + unicode: f1dd +paste: + changes: + - '2' + - 5.0.0 + label: Paste + search: + terms: + - copy + - clipboard + styles: + - solid + unicode: f0ea +patreon: + changes: + - 5.0.0 + label: Patreon + search: + terms: [] + styles: + - brands + unicode: f3d9 +pause: + changes: + - '1' + - 5.0.0 + label: pause + search: + terms: + - wait + styles: + - solid + unicode: f04c +pause-circle: + changes: + - '4.5' + - 5.0.0 + label: Pause Circle + search: + terms: [] + styles: + - solid + - regular + unicode: f28b +paw: + changes: + - '4.1' + - 5.0.0 + label: Paw + search: + terms: + - pet + styles: + - solid + unicode: f1b0 +paypal: + changes: + - '4.2' + - 5.0.0 + label: Paypal + search: + terms: [] + styles: + - brands + unicode: f1ed +pen-square: + changes: + - '3.1' + - 5.0.0 + label: Pen Square + search: + terms: + - write + - edit + - update + - pencil-square + styles: + - solid + unicode: f14b +pencil-alt: + changes: + - 5.0.0 + label: Alternate Pencil + search: + terms: + - write + - edit + - update + - pencil + styles: + - solid + unicode: f303 +percent: + changes: + - '4.5' + - 5.0.0 + label: Percent + search: + terms: [] + styles: + - solid + unicode: f295 +periscope: + changes: + - 5.0.0 + label: Periscope + search: + terms: [] + styles: + - brands + unicode: f3da +phabricator: + changes: + - 5.0.0 + label: Phabricator + search: + terms: [] + sponsored: + label: Phabricator + url: 'http://phacility.com/' + styles: + - brands + unicode: f3db +phoenix-framework: + changes: + - 5.0.0 + label: Phoenix Framework + search: + terms: [] + styles: + - brands + unicode: f3dc +phone: + changes: + - '2' + - 5.0.0 + label: Phone + search: + terms: + - call + - voice + - number + - support + - earphone + - telephone + styles: + - solid + unicode: f095 +phone-square: + changes: + - '2' + - 5.0.0 + label: Phone Square + search: + terms: + - call + - voice + - number + - support + - telephone + styles: + - solid + unicode: f098 +phone-volume: + changes: + - '4.6' + - 5.0.0 + label: Phone Volume + search: + terms: + - telephone + - volume-control-phone + styles: + - solid + unicode: f2a0 +pied-piper: + changes: + - '4.6' + - 5.0.0 + label: Pied Piper Logo + search: + terms: [] + styles: + - brands + unicode: f2ae +pied-piper-alt: + changes: + - '4.1' + - 5.0.0 + label: Alternate Pied Piper Logo + search: + terms: [] + styles: + - brands + unicode: f1a8 +pied-piper-pp: + changes: + - '4.1' + - 5.0.0 + label: Pied Piper PP Logo (Old) + search: + terms: [] + styles: + - brands + unicode: f1a7 +pinterest: + changes: + - '2' + - 5.0.0 + label: Pinterest + search: + terms: [] + styles: + - brands + unicode: f0d2 +pinterest-p: + changes: + - '4.3' + - 5.0.0 + label: Pinterest P + search: + terms: [] + styles: + - brands + unicode: f231 +pinterest-square: + changes: + - '2' + - 5.0.0 + label: Pinterest Square + search: + terms: [] + styles: + - brands + unicode: f0d3 +plane: + changes: + - '1' + - 5.0.0 + label: plane + search: + terms: + - travel + - trip + - location + - destination + - airplane + - fly + - mode + styles: + - solid + unicode: f072 +play: + changes: + - '1' + - 5.0.0 + label: play + search: + terms: + - start + - playing + - music + - sound + styles: + - solid + unicode: f04b +play-circle: + changes: + - '3.1' + - 5.0.0 + label: Play Circle + search: + terms: + - start + - playing + styles: + - solid + - regular + unicode: f144 +playstation: + changes: + - 5.0.0 + label: PlayStation + search: + terms: [] + styles: + - brands + unicode: f3df +plug: + changes: + - '4.2' + - 5.0.0 + label: Plug + search: + terms: + - power + - connect + styles: + - solid + unicode: f1e6 +plus: + changes: + - '1' + - 5.0.0 + label: plus + search: + terms: + - add + - new + - create + - expand + styles: + - solid + unicode: f067 +plus-circle: + changes: + - '1' + - 5.0.0 + label: Plus Circle + search: + terms: + - add + - new + - create + - expand + styles: + - solid + unicode: f055 +plus-square: + changes: + - '3' + - 5.0.0 + label: Plus Square + search: + terms: + - add + - new + - create + - expand + styles: + - solid + - regular + unicode: f0fe +podcast: + changes: + - '4.7' + - 5.0.0 + label: Podcast + search: + terms: [] + styles: + - solid + unicode: f2ce +pound-sign: + changes: + - '3.2' + - 5.0.0 + label: Pound Sign + search: + terms: + - gbp + - gbp + styles: + - solid + unicode: f154 +power-off: + changes: + - '1' + - 5.0.0 + label: Power Off + search: + terms: + - 'on' + styles: + - solid + unicode: f011 +print: + changes: + - '1' + - 5.0.0 + label: print + search: + terms: [] + styles: + - solid + unicode: f02f +product-hunt: + changes: + - '4.5' + - 5.0.0 + label: Product Hunt + search: + terms: [] + styles: + - brands + unicode: f288 +pushed: + changes: + - 5.0.0 + label: Pushed + search: + terms: [] + sponsored: + label: Pushed + url: 'https://pushed.co' + styles: + - brands + unicode: f3e1 +puzzle-piece: + changes: + - '3.1' + - 5.0.0 + label: Puzzle Piece + search: + terms: + - addon + - add-on + - section + styles: + - solid + unicode: f12e +python: + changes: + - 5.0.0 + label: Python + search: + terms: [] + styles: + - brands + unicode: f3e2 +qq: + changes: + - '4.1' + - 5.0.0 + label: QQ + search: + terms: [] + styles: + - brands + unicode: f1d6 +qrcode: + changes: + - '1' + - 5.0.0 + label: qrcode + search: + terms: + - scan + styles: + - solid + unicode: f029 +question: + changes: + - '3.1' + - 5.0.0 + label: Question + search: + terms: + - help + - information + - unknown + - support + styles: + - solid + unicode: f128 +question-circle: + changes: + - '1' + - 5.0.0 + label: Question Circle + search: + terms: + - help + - information + - unknown + - support + styles: + - solid + - regular + unicode: f059 +quora: + changes: + - '4.7' + - 5.0.0 + label: Quora + search: + terms: [] + styles: + - brands + unicode: f2c4 +quote-left: + changes: + - '3' + - 5.0.0 + label: quote-left + search: + terms: [] + styles: + - solid + unicode: f10d +quote-right: + changes: + - '3' + - 5.0.0 + label: quote-right + search: + terms: [] + styles: + - solid + unicode: f10e +random: + changes: + - '1' + - 5.0.0 + label: random + search: + terms: + - sort + - shuffle + styles: + - solid + unicode: f074 +ravelry: + changes: + - '4.7' + - 5.0.0 + label: Ravelry + search: + terms: [] + styles: + - brands + unicode: f2d9 +react: + changes: + - 5.0.0 + label: React + search: + terms: [] + styles: + - brands + unicode: f41b +rebel: + changes: + - '4.1' + - 5.0.0 + label: Rebel Alliance + search: + terms: [] + styles: + - brands + unicode: f1d0 +recycle: + changes: + - '4.1' + - 5.0.0 + label: Recycle + search: + terms: [] + styles: + - solid + unicode: f1b8 +red-river: + changes: + - 5.0.0 + label: red river + search: + terms: [] + sponsored: + label: red river + url: 'https://river.red' + styles: + - brands + unicode: f3e3 +reddit: + changes: + - '4.1' + - 5.0.0 + label: reddit Logo + search: + terms: [] + styles: + - brands + unicode: f1a1 +reddit-alien: + changes: + - '4.5' + - 5.0.0 + label: reddit Alien + search: + terms: [] + styles: + - brands + unicode: f281 +reddit-square: + changes: + - '4.1' + - 5.0.0 + label: reddit Square + search: + terms: [] + styles: + - brands + unicode: f1a2 +redo: + changes: + - '1' + - 5.0.0 + label: Redo + search: + terms: + - forward + - repeat + - repeat + styles: + - solid + unicode: f01e +redo-alt: + changes: + - 5.0.0 + label: Alternate Redo + search: + terms: + - forward + - repeat + styles: + - solid + unicode: f2f9 +registered: + changes: + - '4.4' + - 5.0.0 + label: Registered Trademark + search: + terms: [] + styles: + - solid + - regular + unicode: f25d +rendact: + changes: + - 5.0.0 + label: Rendact + search: + terms: [] + sponsored: + label: Rendact + url: 'https://rendact.com' + styles: + - brands + unicode: f3e4 +renren: + changes: + - '3.2' + - 5.0.0 + label: Renren + search: + terms: [] + styles: + - brands + unicode: f18b +reply: + changes: + - '3' + - 5.0.0 + label: Reply + search: + terms: [] + styles: + - solid + unicode: f3e5 +reply-all: + changes: + - '3.1' + - 5.0.0 + label: reply-all + search: + terms: [] + styles: + - solid + unicode: f122 +replyd: + changes: + - 5.0.0 + label: replyd + search: + terms: [] + sponsored: + label: replyd + styles: + - brands + unicode: f3e6 +resolving: + changes: + - 5.0.0 + label: Resolving + search: + terms: [] + sponsored: + label: Resolving + url: 'https://resolving.com' + styles: + - brands + unicode: f3e7 +retweet: + changes: + - '1' + - 5.0.0 + label: Retweet + search: + terms: + - refresh + - reload + - share + styles: + - solid + unicode: f079 +road: + changes: + - '1' + - 5.0.0 + label: road + search: + terms: + - street + styles: + - solid + unicode: f018 +rocket: + changes: + - '3.1' + - 5.0.0 + label: rocket + search: + terms: + - app + styles: + - solid + unicode: f135 +rocketchat: + changes: + - 5.0.0 + label: Rocket.Chat + search: + terms: [] + sponsored: + label: Rocket.Chat + url: 'https://rocket.chat' + styles: + - brands + unicode: f3e8 +rockrms: + changes: + - 5.0.0 + label: Rockrms + search: + terms: [] + sponsored: + label: Rock RMS + url: 'http://rockrms.com' + styles: + - brands + unicode: f3e9 +rss: + changes: + - '2' + - 5.0.0 + label: rss + search: + terms: + - blog + styles: + - solid + unicode: f09e +rss-square: + changes: + - '3.1' + - 5.0.0 + label: RSS Square + search: + terms: + - feed + - blog + styles: + - solid + unicode: f143 +ruble-sign: + changes: + - '4' + - 5.0.0 + label: Ruble Sign + search: + terms: + - rub + - rub + styles: + - solid + unicode: f158 +rupee-sign: + changes: + - '3.2' + - 5.0.0 + label: Indian Rupee Sign + search: + terms: + - indian + - inr + styles: + - solid + unicode: f156 +safari: + changes: + - '4.4' + - 5.0.0 + label: Safari + search: + terms: + - browser + styles: + - brands + unicode: f267 +sass: + changes: + - 5.0.0 + label: Sass + search: + terms: [] + styles: + - brands + unicode: f41e +save: + changes: + - '2' + - 5.0.0 + label: Save + search: + terms: + - floppy + - floppy-o + styles: + - solid + - regular + unicode: f0c7 +schlix: + changes: + - 5.0.0 + label: SCHLIX + search: + terms: [] + sponsored: + label: SCHLIX + url: 'http://schlix.com' + styles: + - brands + unicode: f3ea +scribd: + changes: + - '4.5' + - 5.0.0 + label: Scribd + search: + terms: [] + styles: + - brands + unicode: f28a +search: + changes: + - '1' + - 5.0.0 + label: Search + search: + terms: + - magnify + - zoom + - enlarge + - bigger + styles: + - solid + unicode: f002 +search-minus: + changes: + - '1' + - 5.0.0 + label: Search Minus + search: + terms: + - magnify + - minify + - zoom + - smaller + styles: + - solid + unicode: f010 +search-plus: + changes: + - '1' + - 5.0.0 + label: Search Plus + search: + terms: + - magnify + - zoom + - enlarge + - bigger + styles: + - solid + unicode: f00e +searchengin: + changes: + - 5.0.0 + label: Searchengin + search: + terms: [] + sponsored: + label: SearchEng.in + url: 'http://searcheng.in' + styles: + - brands + unicode: f3eb +sellcast: + changes: + - 5.0.0 + label: Sellcast + search: + terms: + - eercast + styles: + - brands + unicode: f2da +sellsy: + changes: + - '4.3' + - 5.0.0 + label: Sellsy + search: + terms: [] + styles: + - brands + unicode: f213 +server: + changes: + - '4.3' + - 5.0.0 + label: Server + search: + terms: [] + styles: + - solid + unicode: f233 +servicestack: + changes: + - 5.0.0 + label: Servicestack + search: + terms: [] + sponsored: + label: ServiceStack + url: 'https://servicestack.net' + styles: + - brands + unicode: f3ec +share: + changes: + - '1' + - 5.0.0 + label: Share + search: + terms: [] + styles: + - solid + unicode: f064 +share-alt: + changes: + - '4.1' + - 5.0.0 + label: Alternate Share + search: + terms: [] + styles: + - solid + unicode: f1e0 +share-alt-square: + changes: + - '4.1' + - 5.0.0 + label: Alternate Share Square + search: + terms: [] + styles: + - solid + unicode: f1e1 +share-square: + changes: + - '3.1' + - 5.0.0 + label: Share Square + search: + terms: + - social + - send + styles: + - solid + - regular + unicode: f14d +shekel-sign: + changes: + - '4.2' + - 5.0.0 + label: Shekel Sign + search: + terms: + - ils + - ils + styles: + - solid + unicode: f20b +shield-alt: + changes: + - 5.0.0 + label: Alternate Shield + search: + terms: + - shield + styles: + - solid + unicode: f3ed +ship: + changes: + - '4.3' + - 5.0.0 + label: Ship + search: + terms: + - boat + - sea + styles: + - solid + unicode: f21a +shirtsinbulk: + changes: + - '4.3' + - 5.0.0 + label: Shirts in Bulk + search: + terms: [] + styles: + - brands + unicode: f214 +shopping-bag: + changes: + - '4.5' + - 5.0.0 + label: Shopping Bag + search: + terms: [] + styles: + - solid + unicode: f290 +shopping-basket: + changes: + - '4.5' + - 5.0.0 + label: Shopping Basket + search: + terms: [] + styles: + - solid + unicode: f291 +shopping-cart: + changes: + - '1' + - 5.0.0 + label: shopping-cart + search: + terms: + - checkout + - buy + - purchase + - payment + styles: + - solid + unicode: f07a +shower: + changes: + - '4.7' + - 5.0.0 + label: Shower + search: + terms: [] + styles: + - solid + unicode: f2cc +sign-in-alt: + changes: + - 5.0.0 + label: Alernate Sign In + search: + terms: + - enter + - join + - log in + - login + - sign up + - sign in + - signin + - signup + - arrow + - sign-in + styles: + - solid + unicode: f2f6 +sign-language: + changes: + - '4.6' + - 5.0.0 + label: Sign Language + search: + terms: [] + styles: + - solid + unicode: f2a7 +sign-out-alt: + changes: + - 5.0.0 + label: Alernate Sign Out + search: + terms: + - log out + - logout + - leave + - exit + - arrow + - sign-out + styles: + - solid + unicode: f2f5 +signal: + changes: + - '1' + - 5.0.0 + label: signal + search: + terms: + - graph + - bars + styles: + - solid + unicode: f012 +simplybuilt: + changes: + - '4.3' + - 5.0.0 + label: SimplyBuilt + search: + terms: [] + styles: + - brands + unicode: f215 +sistrix: + changes: + - 5.0.0 + label: SISTRIX + search: + terms: [] + sponsored: + label: SISTRIX + url: 'https://www.sistrix.de/' + styles: + - brands + unicode: f3ee +sitemap: + changes: + - '2' + - 5.0.0 + label: Sitemap + search: + terms: + - directory + - hierarchy + - organization + styles: + - solid + unicode: f0e8 +skyatlas: + changes: + - '4.3' + - 5.0.0 + label: skyatlas + search: + terms: [] + styles: + - brands + unicode: f216 +skype: + changes: + - '3.2' + - 5.0.0 + label: Skype + search: + terms: [] + styles: + - brands + unicode: f17e +slack: + changes: + - '4.1' + - 5.0.0 + label: Slack Logo + search: + terms: + - hashtag + - anchor + - hash + styles: + - brands + unicode: f198 +slack-hash: + changes: + - 5.0.0 + label: Slack Hashtag + search: + terms: + - hashtag + - anchor + - hash + styles: + - brands + unicode: f3ef +sliders-h: + changes: + - '4.1' + - 5.0.0 + label: Horizontal Sliders + search: + terms: + - settings + - sliders + styles: + - solid + unicode: f1de +slideshare: + changes: + - '4.2' + - 5.0.0 + label: Slideshare + search: + terms: [] + styles: + - brands + unicode: f1e7 +smile: + changes: + - '3.1' + - 5.0.0 + label: Smile + search: + terms: + - face + - emoticon + - happy + - approve + - satisfied + - rating + styles: + - solid + - regular + unicode: f118 +snapchat: + changes: + - '4.6' + - 5.0.0 + label: Snapchat + search: + terms: [] + styles: + - brands + unicode: f2ab +snapchat-ghost: + changes: + - '4.6' + - 5.0.0 + label: Snapchat Ghost + search: + terms: [] + styles: + - brands + unicode: f2ac +snapchat-square: + changes: + - '4.6' + - 5.0.0 + label: Snapchat Square + search: + terms: [] + styles: + - brands + unicode: f2ad +snowflake: + changes: + - '4.7' + - 5.0.0 + label: Snowflake + search: + terms: [] + styles: + - solid + - regular + unicode: f2dc +sort: + changes: + - '2' + - 5.0.0 + label: Sort + search: + terms: + - order + styles: + - solid + unicode: f0dc +sort-alpha-down: + changes: + - '3.2' + - 5.0.0 + label: Sort Alpha Down + search: + terms: + - sort-alpha-asc + styles: + - solid + unicode: f15d +sort-alpha-up: + changes: + - '3.2' + - 5.0.0 + label: Sort Alpha Up + search: + terms: + - sort-alpha-desc + styles: + - solid + unicode: f15e +sort-amount-down: + changes: + - '3.2' + - 5.0.0 + label: Sort Amount Down + search: + terms: + - sort-amount-asc + styles: + - solid + unicode: f160 +sort-amount-up: + changes: + - '3.2' + - 5.0.0 + label: Sort Amount Up + search: + terms: + - sort-amount-desc + styles: + - solid + unicode: f161 +sort-down: + changes: + - '2' + - 5.0.0 + label: Sort Down (Descending) + search: + terms: + - arrow + - descending + - sort-desc + styles: + - solid + unicode: f0dd +sort-numeric-down: + changes: + - '3.2' + - 5.0.0 + label: Sort Numeric Down + search: + terms: + - numbers + - sort-numeric-asc + styles: + - solid + unicode: f162 +sort-numeric-up: + changes: + - '3.2' + - 5.0.0 + label: Sort Numeric Up + search: + terms: + - numbers + - sort-numeric-desc + styles: + - solid + unicode: f163 +sort-up: + changes: + - '2' + - 5.0.0 + label: Sort Up (Ascending) + search: + terms: + - arrow + - ascending + - sort-asc + styles: + - solid + unicode: f0de +soundcloud: + changes: + - '4.1' + - 5.0.0 + label: SoundCloud + search: + terms: [] + styles: + - brands + unicode: f1be +space-shuttle: + changes: + - '4.1' + - 5.0.0 + label: Space Shuttle + search: + terms: [] + styles: + - solid + unicode: f197 +speakap: + changes: + - 5.0.0 + label: Speakap + search: + terms: [] + sponsored: + label: Speakap + url: 'https://speakap.com' + styles: + - brands + unicode: f3f3 +spinner: + changes: + - '3' + - 5.0.0 + label: Spinner + search: + terms: + - loading + - progress + styles: + - solid + unicode: f110 +spotify: + changes: + - '4.1' + - 5.0.0 + label: Spotify + search: + terms: [] + styles: + - brands + unicode: f1bc +square: + changes: + - '2' + - 5.0.0 + label: Square + search: + terms: + - block + - box + styles: + - solid + - regular + unicode: f0c8 +stack-exchange: + changes: + - '4' + - 5.0.0 + label: Stack Exchange + search: + terms: [] + styles: + - brands + unicode: f18d +stack-overflow: + changes: + - '3.2' + - 5.0.0 + label: Stack Overflow + search: + terms: [] + styles: + - brands + unicode: f16c +star: + changes: + - '1' + - 5.0.0 + label: Star + search: + terms: + - award + - achievement + - night + - rating + - score + - favorite + styles: + - solid + - regular + unicode: f005 +star-half: + changes: + - '1' + - 5.0.0 + label: star-half + search: + terms: + - award + - achievement + - rating + - score + - star-half-empty + - star-half-full + styles: + - solid + - regular + unicode: f089 +staylinked: + changes: + - 5.0.0 + label: StayLinked + search: + terms: [] + sponsored: + label: StayLinked + url: 'http://www.staylinked.com' + styles: + - brands + unicode: f3f5 +steam: + changes: + - '4.1' + - 5.0.0 + label: Steam + search: + terms: [] + styles: + - brands + unicode: f1b6 +steam-square: + changes: + - '4.1' + - 5.0.0 + label: Steam Square + search: + terms: [] + styles: + - brands + unicode: f1b7 +steam-symbol: + changes: + - 5.0.0 + label: Steam Symbol + search: + terms: [] + styles: + - brands + unicode: f3f6 +step-backward: + changes: + - '1' + - 5.0.0 + label: step-backward + search: + terms: + - rewind + - previous + - beginning + - start + - first + styles: + - solid + unicode: f048 +step-forward: + changes: + - '1' + - 5.0.0 + label: step-forward + search: + terms: + - next + - end + - last + styles: + - solid + unicode: f051 +stethoscope: + changes: + - '3' + - 5.0.0 + label: Stethoscope + search: + terms: [] + styles: + - solid + unicode: f0f1 +sticker-mule: + changes: + - 5.0.0 + label: Sticker Mule + search: + terms: [] + sponsored: + label: Sticker Mule + url: 'https://stickermule.com' + styles: + - brands + unicode: f3f7 +sticky-note: + changes: + - '4.4' + - 5.0.0 + label: Sticky Note + search: + terms: [] + styles: + - solid + - regular + unicode: f249 +stop: + changes: + - '1' + - 5.0.0 + label: stop + search: + terms: + - block + - box + - square + styles: + - solid + unicode: f04d +stop-circle: + changes: + - '4.5' + - 5.0.0 + label: Stop Circle + search: + terms: [] + styles: + - solid + - regular + unicode: f28d +strava: + changes: + - 5.0.0 + - 5.0.1 + label: Strava + search: + terms: [] + styles: + - brands + unicode: f428 +street-view: + changes: + - '4.3' + - 5.0.0 + label: Street View + search: + terms: + - map + styles: + - solid + unicode: f21d +strikethrough: + changes: + - '2' + - 5.0.0 + label: Strikethrough + search: + terms: [] + styles: + - solid + unicode: f0cc +stripe: + changes: + - 5.0.0 + label: Stripe + search: + terms: [] + styles: + - brands + unicode: f429 +stripe-s: + changes: + - 5.0.1 + label: Stripe S + search: + terms: [] + styles: + - brands + unicode: f42a +studiovinari: + changes: + - 5.0.0 + label: Studio Vinari + search: + terms: [] + sponsored: + label: Studio Vinari + url: 'https://studiovinari.com' + styles: + - brands + unicode: f3f8 +stumbleupon: + changes: + - '4.1' + - 5.0.0 + label: StumbleUpon Logo + search: + terms: [] + styles: + - brands + unicode: f1a4 +stumbleupon-circle: + changes: + - '4.1' + - 5.0.0 + label: StumbleUpon Circle + search: + terms: [] + styles: + - brands + unicode: f1a3 +subscript: + changes: + - '3.1' + - 5.0.0 + label: subscript + search: + terms: [] + styles: + - solid + unicode: f12c +subway: + changes: + - '4.3' + - 5.0.0 + label: Subway + search: + terms: [] + styles: + - solid + unicode: f239 +suitcase: + changes: + - '3' + - 5.0.0 + label: Suitcase + search: + terms: + - trip + - luggage + - travel + - move + - baggage + styles: + - solid + unicode: f0f2 +sun: + changes: + - '3.2' + - 5.0.0 + label: Sun + search: + terms: + - weather + - contrast + - lighter + - brighten + - day + styles: + - solid + - regular + unicode: f185 +superpowers: + changes: + - '4.7' + - 5.0.0 + label: Superpowers + search: + terms: [] + styles: + - brands + unicode: f2dd +superscript: + changes: + - '3.1' + - 5.0.0 + label: superscript + search: + terms: + - exponential + styles: + - solid + unicode: f12b +supple: + changes: + - 5.0.0 + label: Supple + search: + terms: [] + styles: + - brands + unicode: f3f9 +sync: + changes: + - '1' + - 5.0.0 + label: Sync + search: + terms: + - reload + - refresh + - refresh + styles: + - solid + unicode: f021 +sync-alt: + changes: + - 5.0.0 + label: Alternate Sync + search: + terms: + - reload + - refresh + styles: + - solid + unicode: f2f1 +table: + changes: + - '2' + - 5.0.0 + label: table + search: + terms: + - data + - excel + - spreadsheet + styles: + - solid + unicode: f0ce +tablet: + changes: + - '3' + - 5.0.0 + label: tablet + search: + terms: + - ipad + - device + styles: + - solid + unicode: f10a +tablet-alt: + changes: + - 5.0.0 + label: Alternate Tablet + search: + terms: + - tablet + styles: + - solid + unicode: f3fa +tachometer-alt: + changes: + - 5.0.0 + label: Alternate Tachometer + search: + terms: + - tachometer + styles: + - solid + unicode: f3fd +tag: + changes: + - '1' + - 5.0.0 + label: tag + search: + terms: + - label + styles: + - solid + unicode: f02b +tags: + changes: + - '1' + - 5.0.0 + label: tags + search: + terms: + - labels + styles: + - solid + unicode: f02c +tasks: + changes: + - '2' + - 5.0.0 + label: Tasks + search: + terms: + - progress + - loading + - downloading + - downloads + - settings + styles: + - solid + unicode: f0ae +taxi: + changes: + - '4.1' + - 5.0.0 + label: Taxi + search: + terms: + - vehicle + styles: + - solid + unicode: f1ba +telegram: + changes: + - '4.7' + - 5.0.0 + label: Telegram + search: + terms: [] + styles: + - brands + unicode: f2c6 +telegram-plane: + changes: + - 5.0.0 + label: Telegram Plane + search: + terms: [] + styles: + - brands + unicode: f3fe +tencent-weibo: + changes: + - '4.1' + - 5.0.0 + label: Tencent Weibo + search: + terms: [] + styles: + - brands + unicode: f1d5 +terminal: + changes: + - '3.1' + - 5.0.0 + label: Terminal + search: + terms: + - command + - prompt + - code + styles: + - solid + unicode: f120 +text-height: + changes: + - '1' + - 5.0.0 + label: text-height + search: + terms: [] + styles: + - solid + unicode: f034 +text-width: + changes: + - '1' + - 5.0.0 + label: text-width + search: + terms: [] + styles: + - solid + unicode: f035 +th: + changes: + - '1' + - 5.0.0 + label: th + search: + terms: + - blocks + - squares + - boxes + - grid + styles: + - solid + unicode: f00a +th-large: + changes: + - '1' + - 5.0.0 + label: th-large + search: + terms: + - blocks + - squares + - boxes + - grid + styles: + - solid + unicode: f009 +th-list: + changes: + - '1' + - 5.0.0 + label: th-list + search: + terms: + - ul + - ol + - checklist + - finished + - completed + - done + - todo + styles: + - solid + unicode: f00b +themeisle: + changes: + - '4.6' + - 5.0.0 + label: ThemeIsle + search: + terms: [] + styles: + - brands + unicode: f2b2 +thermometer-empty: + changes: + - '4.7' + - 5.0.0 + label: Thermometer Empty + search: + terms: [] + styles: + - solid + unicode: f2cb +thermometer-full: + changes: + - '4.7' + - 5.0.0 + label: Thermometer Full + search: + terms: [] + styles: + - solid + unicode: f2c7 +thermometer-half: + changes: + - '4.7' + - 5.0.0 + label: Thermometer 1/2 Full + search: + terms: [] + styles: + - solid + unicode: f2c9 +thermometer-quarter: + changes: + - '4.7' + - 5.0.0 + label: Thermometer 1/4 Full + search: + terms: [] + styles: + - solid + unicode: f2ca +thermometer-three-quarters: + changes: + - '4.7' + - 5.0.0 + label: Thermometer 3/4 Full + search: + terms: [] + styles: + - solid + unicode: f2c8 +thumbs-down: + changes: + - '3.2' + - 5.0.0 + label: thumbs-down + search: + terms: + - dislike + - disapprove + - disagree + - hand + - thumbs-o-down + styles: + - solid + - regular + unicode: f165 +thumbs-up: + changes: + - '3.2' + - 5.0.0 + label: thumbs-up + search: + terms: + - like + - favorite + - approve + - agree + - hand + - thumbs-o-up + styles: + - solid + - regular + unicode: f164 +thumbtack: + changes: + - '1' + - 5.0.0 + label: Thumbtack + search: + terms: + - marker + - pin + - location + - coordinates + - thumb-tack + styles: + - solid + unicode: f08d +ticket-alt: + changes: + - 5.0.0 + label: Alernate Ticket + search: + terms: + - ticket + styles: + - solid + unicode: f3ff +times: + changes: + - '1' + - 5.0.0 + label: Times + search: + terms: + - close + - exit + - x + - cross + styles: + - solid + unicode: f00d +times-circle: + changes: + - '1' + - 5.0.0 + label: Times Circle + search: + terms: + - close + - exit + - x + styles: + - solid + - regular + unicode: f057 +tint: + changes: + - '1' + - 5.0.0 + label: tint + search: + terms: + - raindrop + - waterdrop + - drop + - droplet + styles: + - solid + unicode: f043 +toggle-off: + changes: + - '4.2' + - 5.0.0 + label: Toggle Off + search: + terms: [] + styles: + - solid + unicode: f204 +toggle-on: + changes: + - '4.2' + - 5.0.0 + label: Toggle On + search: + terms: [] + styles: + - solid + unicode: f205 +trademark: + changes: + - '4.4' + - 5.0.0 + label: Trademark + search: + terms: [] + styles: + - solid + unicode: f25c +train: + changes: + - '4.3' + - 5.0.0 + label: Train + search: + terms: [] + styles: + - solid + unicode: f238 +transgender: + changes: + - '4.3' + - 5.0.0 + label: Transgender + search: + terms: + - intersex + styles: + - solid + unicode: f224 +transgender-alt: + changes: + - '4.3' + - 5.0.0 + label: Alternate Transgender + search: + terms: [] + styles: + - solid + unicode: f225 +trash: + changes: + - '4.2' + - 5.0.0 + label: Trash + search: + terms: + - garbage + - delete + - remove + - hide + styles: + - solid + unicode: f1f8 +trash-alt: + changes: + - 5.0.0 + label: Alternate Trash + search: + terms: + - garbage + - delete + - remove + - hide + - trash + - trash-o + styles: + - solid + - regular + unicode: f2ed +tree: + changes: + - '4.1' + - 5.0.0 + label: Tree + search: + terms: [] + styles: + - solid + unicode: f1bb +trello: + changes: + - '3.2' + - 5.0.0 + label: Trello + search: + terms: [] + styles: + - brands + unicode: f181 +tripadvisor: + changes: + - '4.4' + - 5.0.0 + label: TripAdvisor + search: + terms: [] + styles: + - brands + unicode: f262 +trophy: + changes: + - '1' + - 5.0.0 + label: trophy + search: + terms: + - award + - achievement + - cup + - winner + - game + styles: + - solid + unicode: f091 +truck: + changes: + - '2' + - 5.0.0 + label: truck + search: + terms: + - shipping + styles: + - solid + unicode: f0d1 +tty: + changes: + - '4.2' + - 5.0.0 + label: TTY + search: + terms: [] + styles: + - solid + unicode: f1e4 +tumblr: + changes: + - '3.2' + - 5.0.0 + label: Tumblr + search: + terms: [] + styles: + - brands + unicode: f173 +tumblr-square: + changes: + - '3.2' + - 5.0.0 + label: Tumblr Square + search: + terms: [] + styles: + - brands + unicode: f174 +tv: + changes: + - '4.4' + - 5.0.0 + label: Television + search: + terms: + - display + - computer + - monitor + - television + styles: + - solid + unicode: f26c +twitch: + changes: + - '4.2' + - 5.0.0 + label: Twitch + search: + terms: [] + styles: + - brands + unicode: f1e8 +twitter: + changes: + - '2' + - 5.0.0 + label: Twitter + search: + terms: + - tweet + - social network + styles: + - brands + unicode: f099 +twitter-square: + changes: + - '1' + - 5.0.0 + label: Twitter Square + search: + terms: + - tweet + - social network + styles: + - brands + unicode: f081 +typo3: + changes: + - 5.0.1 + label: Typo3 + search: + terms: [] + styles: + - brands + unicode: f42b +uber: + changes: + - 5.0.0 + label: Uber + search: + terms: [] + styles: + - brands + unicode: f402 +uikit: + changes: + - 5.0.0 + label: UIkit + search: + terms: [] + styles: + - brands + unicode: f403 +umbrella: + changes: + - '2' + - 5.0.0 + label: Umbrella + search: + terms: [] + styles: + - solid + unicode: f0e9 +underline: + changes: + - '2' + - 5.0.0 + label: Underline + search: + terms: [] + styles: + - solid + unicode: f0cd +undo: + changes: + - '2' + - 5.0.0 + label: Undo + search: + terms: + - back + styles: + - solid + unicode: f0e2 +undo-alt: + changes: + - 5.0.0 + label: Alternate Undo + search: + terms: + - back + styles: + - solid + unicode: f2ea +uniregistry: + changes: + - 5.0.0 + label: Uniregistry + search: + terms: [] + styles: + - brands + unicode: f404 +universal-access: + changes: + - '4.6' + - 5.0.0 + label: Universal Access + search: + terms: [] + styles: + - solid + unicode: f29a +university: + changes: + - '4.1' + - 5.0.0 + label: University + search: + terms: [] + styles: + - solid + unicode: f19c +unlink: + changes: + - '3.1' + - 5.0.0 + label: unlink + search: + terms: + - remove + - chain + - chain-broken + styles: + - solid + unicode: f127 +unlock: + changes: + - '2' + - 5.0.0 + label: unlock + search: + terms: + - protect + - admin + - password + - lock + styles: + - solid + unicode: f09c +unlock-alt: + changes: + - '3.1' + - 5.0.0 + label: Alternate Unlock + search: + terms: + - protect + - admin + - password + - lock + styles: + - solid + unicode: f13e +untappd: + changes: + - 5.0.0 + label: Untappd + search: + terms: [] + styles: + - brands + unicode: f405 +upload: + changes: + - '1' + - 5.0.0 + label: Upload + search: + terms: + - import + styles: + - solid + unicode: f093 +usb: + changes: + - '4.5' + - 5.0.0 + label: USB + search: + terms: [] + styles: + - brands + unicode: f287 +user: + changes: + - '1' + - 5.0.0 + label: User + search: + terms: + - person + - man + - head + - profile + styles: + - solid + - regular + unicode: f007 +user-circle: + changes: + - '4.7' + - 5.0.0 + label: User Circle + search: + terms: [] + styles: + - solid + - regular + unicode: f2bd +user-md: + changes: + - '2' + - 5.0.0 + label: user-md + search: + terms: + - doctor + - profile + - medical + - nurse + styles: + - solid + unicode: f0f0 +user-plus: + changes: + - '4.3' + - 5.0.0 + label: Add User + search: + terms: + - sign up + - signup + styles: + - solid + unicode: f234 +user-secret: + changes: + - '4.3' + - 5.0.0 + label: User Secret + search: + terms: + - whisper + - spy + - incognito + - privacy + styles: + - solid + unicode: f21b +user-times: + changes: + - '4.3' + - 5.0.0 + label: Remove User + search: + terms: [] + styles: + - solid + unicode: f235 +users: + changes: + - '2' + - 5.0.0 + label: Users + search: + terms: + - people + - profiles + - persons + styles: + - solid + unicode: f0c0 +ussunnah: + changes: + - 5.0.0 + label: us-Sunnah Foundation + search: + terms: [] + sponsored: + label: us-Sunnah Foundation + url: 'https://www.ussunnah.org' + styles: + - brands + unicode: f407 +utensil-spoon: + changes: + - 5.0.0 + label: Utensil Spoon + search: + terms: + - spoon + styles: + - solid + unicode: f2e5 +utensils: + changes: + - 5.0.0 + label: Utensils + search: + terms: + - food + - restaurant + - spoon + - knife + - dinner + - eat + - cutlery + styles: + - solid + unicode: f2e7 +vaadin: + changes: + - 5.0.0 + label: Vaadin + search: + terms: [] + sponsored: + label: Vaadin + url: 'http://vaadin.com' + styles: + - brands + unicode: f408 +venus: + changes: + - '4.3' + - 5.0.0 + label: Venus + search: + terms: + - female + styles: + - solid + unicode: f221 +venus-double: + changes: + - '4.3' + - 5.0.0 + label: Venus Double + search: + terms: [] + styles: + - solid + unicode: f226 +venus-mars: + changes: + - '4.3' + - 5.0.0 + label: Venus Mars + search: + terms: [] + styles: + - solid + unicode: f228 +viacoin: + changes: + - '4.3' + - 5.0.0 + label: Viacoin + search: + terms: [] + styles: + - brands + unicode: f237 +viadeo: + changes: + - '4.6' + - 5.0.0 + label: Viadeo + search: + terms: [] + styles: + - brands + unicode: f2a9 +viadeo-square: + changes: + - '4.6' + - 5.0.0 + label: Viadeo Square + search: + terms: [] + styles: + - brands + unicode: f2aa +viber: + changes: + - 5.0.0 + label: Viber + search: + terms: [] + styles: + - brands + unicode: f409 +video: + changes: + - '1' + - 5.0.0 + label: Video + search: + terms: + - film + - movie + - record + - camera + - video-camera + styles: + - solid + unicode: f03d +vimeo: + changes: + - 5.0.0 + label: Vimeo + search: + terms: [] + styles: + - brands + unicode: f40a +vimeo-square: + changes: + - '4' + - 5.0.0 + label: Vimeo Square + search: + terms: [] + styles: + - brands + unicode: f194 +vimeo-v: + changes: + - '4.4' + - 5.0.0 + label: Vimeo + search: + terms: + - vimeo + styles: + - brands + unicode: f27d +vine: + changes: + - '4.1' + - 5.0.0 + label: Vine + search: + terms: [] + styles: + - brands + unicode: f1ca +vk: + changes: + - '3.2' + - 5.0.0 + label: VK + search: + terms: [] + styles: + - brands + unicode: f189 +vnv: + changes: + - 5.0.0 + label: VNV + search: + terms: [] + sponsored: + label: VNV + url: 'https://www.vnv.ch' + styles: + - brands + unicode: f40b +volume-down: + changes: + - '1' + - 5.0.0 + label: volume-down + search: + terms: + - audio + - lower + - quieter + - sound + - music + styles: + - solid + unicode: f027 +volume-off: + changes: + - '1' + - 5.0.0 + label: volume-off + search: + terms: + - audio + - mute + - sound + - music + styles: + - solid + unicode: f026 +volume-up: + changes: + - '1' + - 5.0.0 + label: volume-up + search: + terms: + - audio + - higher + - louder + - sound + - music + styles: + - solid + unicode: f028 +vuejs: + changes: + - 5.0.0 + label: Vue.js + search: + terms: [] + styles: + - brands + unicode: f41f +weibo: + changes: + - '3.2' + - 5.0.0 + label: Weibo + search: + terms: [] + styles: + - brands + unicode: f18a +weixin: + changes: + - '4.1' + - 5.0.0 + label: Weixin (WeChat) + search: + terms: [] + styles: + - brands + unicode: f1d7 +whatsapp: + changes: + - '4.3' + - 5.0.0 + label: What's App + search: + terms: [] + styles: + - brands + unicode: f232 +whatsapp-square: + changes: + - 5.0.0 + label: What's App Square + search: + terms: [] + styles: + - brands + unicode: f40c +wheelchair: + changes: + - '4' + - 5.0.0 + label: Wheelchair + search: + terms: + - handicap + - person + styles: + - solid + unicode: f193 +whmcs: + changes: + - 5.0.0 + label: WHMCS + search: + terms: [] + sponsored: + label: WHMCS + url: 'https://www.whmcs.com' + styles: + - brands + unicode: f40d +wifi: + changes: + - '4.2' + - 5.0.0 + label: WiFi + search: + terms: [] + styles: + - solid + unicode: f1eb +wikipedia-w: + changes: + - '4.4' + - 5.0.0 + label: Wikipedia W + search: + terms: [] + styles: + - brands + unicode: f266 +window-close: + changes: + - '4.7' + - 5.0.0 + label: Window Close + search: + terms: [] + styles: + - solid + - regular + unicode: f410 +window-maximize: + changes: + - '4.7' + - 5.0.0 + label: Window Maximize + search: + terms: [] + styles: + - solid + - regular + unicode: f2d0 +window-minimize: + changes: + - '4.7' + - 5.0.0 + label: Window Minimize + search: + terms: [] + styles: + - solid + unicode: f2d1 +window-restore: + changes: + - '4.7' + - 5.0.0 + label: Window Restore + search: + terms: [] + styles: + - solid + - regular + unicode: f2d2 +windows: + changes: + - '3.2' + - 5.0.0 + label: Windows + search: + terms: + - microsoft + styles: + - brands + unicode: f17a +won-sign: + changes: + - '3.2' + - 5.0.0 + label: Won Sign + search: + terms: + - krw + - krw + styles: + - solid + unicode: f159 +wordpress: + changes: + - '4.1' + - 5.0.0 + label: WordPress Logo + search: + terms: [] + styles: + - brands + unicode: f19a +wordpress-simple: + changes: + - 5.0.0 + label: Wordpress Simple + search: + terms: [] + styles: + - brands + unicode: f411 +wpbeginner: + changes: + - '4.6' + - 5.0.0 + label: WPBeginner + search: + terms: [] + styles: + - brands + unicode: f297 +wpexplorer: + changes: + - '4.7' + - 5.0.0 + label: WPExplorer + search: + terms: [] + styles: + - brands + unicode: f2de +wpforms: + changes: + - '4.6' + - 5.0.0 + label: WPForms + search: + terms: [] + styles: + - brands + unicode: f298 +wrench: + changes: + - '2' + - 5.0.0 + label: Wrench + search: + terms: + - settings + - fix + - update + - spanner + styles: + - solid + unicode: f0ad +xbox: + changes: + - 5.0.0 + label: Xbox + search: + terms: [] + styles: + - brands + unicode: f412 +xing: + changes: + - '3.2' + - 5.0.0 + label: Xing + search: + terms: [] + styles: + - brands + unicode: f168 +xing-square: + changes: + - '3.2' + - 5.0.0 + label: Xing Square + search: + terms: [] + styles: + - brands + unicode: f169 +y-combinator: + changes: + - '4.4' + - 5.0.0 + label: Y Combinator + search: + terms: [] + styles: + - brands + unicode: f23b +yahoo: + changes: + - '4.1' + - 5.0.0 + label: Yahoo Logo + search: + terms: [] + styles: + - brands + unicode: f19e +yandex: + changes: + - 5.0.0 + label: Yandex + search: + terms: [] + styles: + - brands + unicode: f413 +yandex-international: + changes: + - 5.0.0 + label: Yandex International + search: + terms: [] + styles: + - brands + unicode: f414 +yelp: + changes: + - '4.2' + - 5.0.0 + label: Yelp + search: + terms: [] + styles: + - brands + unicode: f1e9 +yen-sign: + changes: + - '3.2' + - 5.0.0 + label: Yen Sign + search: + terms: + - jpy + - jpy + styles: + - solid + unicode: f157 +yoast: + changes: + - '4.6' + - 5.0.0 + label: Yoast + search: + terms: [] + styles: + - brands + unicode: f2b1 +youtube: + changes: + - '3.2' + - 5.0.0 + label: YouTube + search: + terms: + - video + - film + - youtube-play + - youtube-square + styles: + - brands + unicode: f167 diff --git a/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.json b/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.json new file mode 100644 index 000000000..61c5d5bc0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.json @@ -0,0 +1,2302 @@ +[ + [ + "glass", + null, + "glass-martini" + ], + [ + "meetup", + "fab", + null + ], + [ + "star-o", + "far", + "star" + ], + [ + "remove", + null, + "times" + ], + [ + "close", + null, + "times" + ], + [ + "gear", + null, + "cog" + ], + [ + "trash-o", + "far", + "trash-alt" + ], + [ + "file-o", + "far", + "file" + ], + [ + "clock-o", + "far", + "clock" + ], + [ + "arrow-circle-o-down", + "far", + "arrow-alt-circle-down" + ], + [ + "arrow-circle-o-up", + "far", + "arrow-alt-circle-up" + ], + [ + "play-circle-o", + "far", + "play-circle" + ], + [ + "repeat", + null, + "redo" + ], + [ + "rotate-right", + null, + "redo" + ], + [ + "refresh", + null, + "sync" + ], + [ + "list-alt", + "far", + null + ], + [ + "dedent", + null, + "outdent" + ], + [ + "video-camera", + null, + "video" + ], + [ + "picture-o", + "far", + "image" + ], + [ + "photo", + "far", + "image" + ], + [ + "image", + "far", + "image" + ], + [ + "pencil", + null, + "pencil-alt" + ], + [ + "map-marker", + null, + "map-marker-alt" + ], + [ + "pencil-square-o", + "far", + "edit" + ], + [ + "share-square-o", + "far", + "share-square" + ], + [ + "check-square-o", + "far", + "check-square" + ], + [ + "arrows", + null, + "arrows-alt" + ], + [ + "times-circle-o", + "far", + "times-circle" + ], + [ + "check-circle-o", + "far", + "check-circle" + ], + [ + "mail-forward", + null, + "share" + ], + [ + "eye-slash", + "far", + null + ], + [ + "warning", + null, + "exclamation-triangle" + ], + [ + "calendar", + null, + "calendar-alt" + ], + [ + "arrows-v", + null, + "arrows-alt-v" + ], + [ + "arrows-h", + null, + "arrows-alt-h" + ], + [ + "bar-chart", + "far", + "chart-bar" + ], + [ + "bar-chart-o", + "far", + "chart-bar" + ], + [ + "twitter-square", + "fab", + null + ], + [ + "facebook-square", + "fab", + null + ], + [ + "gears", + null, + "cogs" + ], + [ + "thumbs-o-up", + "far", + "thumbs-up" + ], + [ + "thumbs-o-down", + "far", + "thumbs-down" + ], + [ + "heart-o", + "far", + "heart" + ], + [ + "sign-out", + null, + "sign-out-alt" + ], + [ + "linkedin-square", + "fab", + "linkedin" + ], + [ + "thumb-tack", + null, + "thumbtack" + ], + [ + "external-link", + null, + "external-link-alt" + ], + [ + "sign-in", + null, + "sign-in-alt" + ], + [ + "github-square", + "fab", + null + ], + [ + "lemon-o", + "far", + "lemon" + ], + [ + "square-o", + "far", + "square" + ], + [ + "bookmark-o", + "far", + "bookmark" + ], + [ + "twitter", + "fab", + null + ], + [ + "facebook", + "fab", + "facebook-f" + ], + [ + "facebook-f", + "fab", + "facebook-f" + ], + [ + "github", + "fab", + null + ], + [ + "credit-card", + "far", + null + ], + [ + "feed", + null, + "rss" + ], + [ + "hdd-o", + "far", + "hdd" + ], + [ + "hand-o-right", + "far", + "hand-point-right" + ], + [ + "hand-o-left", + "far", + "hand-point-left" + ], + [ + "hand-o-up", + "far", + "hand-point-up" + ], + [ + "hand-o-down", + "far", + "hand-point-down" + ], + [ + "arrows-alt", + null, + "expand-arrows-alt" + ], + [ + "group", + null, + "users" + ], + [ + "chain", + null, + "link" + ], + [ + "scissors", + null, + "cut" + ], + [ + "files-o", + "far", + "copy" + ], + [ + "floppy-o", + "far", + "save" + ], + [ + "navicon", + null, + "bars" + ], + [ + "reorder", + null, + "bars" + ], + [ + "pinterest", + "fab", + null + ], + [ + "pinterest-square", + "fab", + null + ], + [ + "google-plus-square", + "fab", + null + ], + [ + "google-plus", + "fab", + "google-plus-g" + ], + [ + "money", + "far", + "money-bill-alt" + ], + [ + "unsorted", + null, + "sort" + ], + [ + "sort-desc", + null, + "sort-down" + ], + [ + "sort-asc", + null, + "sort-up" + ], + [ + "linkedin", + "fab", + "linkedin-in" + ], + [ + "rotate-left", + null, + "undo" + ], + [ + "legal", + null, + "gavel" + ], + [ + "tachometer", + null, + "tachometer-alt" + ], + [ + "dashboard", + null, + "tachometer-alt" + ], + [ + "comment-o", + "far", + "comment" + ], + [ + "comments-o", + "far", + "comments" + ], + [ + "flash", + null, + "bolt" + ], + [ + "clipboard", + "far", + null + ], + [ + "paste", + "far", + "clipboard" + ], + [ + "lightbulb-o", + "far", + "lightbulb" + ], + [ + "exchange", + null, + "exchange-alt" + ], + [ + "cloud-download", + null, + "cloud-download-alt" + ], + [ + "cloud-upload", + null, + "cloud-upload-alt" + ], + [ + "bell-o", + "far", + "bell" + ], + [ + "cutlery", + null, + "utensils" + ], + [ + "file-text-o", + "far", + "file-alt" + ], + [ + "building-o", + "far", + "building" + ], + [ + "hospital-o", + "far", + "hospital" + ], + [ + "tablet", + null, + "tablet-alt" + ], + [ + "mobile", + null, + "mobile-alt" + ], + [ + "mobile-phone", + null, + "mobile-alt" + ], + [ + "circle-o", + "far", + "circle" + ], + [ + "mail-reply", + null, + "reply" + ], + [ + "github-alt", + "fab", + null + ], + [ + "folder-o", + "far", + "folder" + ], + [ + "folder-open-o", + "far", + "folder-open" + ], + [ + "smile-o", + "far", + "smile" + ], + [ + "frown-o", + "far", + "frown" + ], + [ + "meh-o", + "far", + "meh" + ], + [ + "keyboard-o", + "far", + "keyboard" + ], + [ + "flag-o", + "far", + "flag" + ], + [ + "mail-reply-all", + null, + "reply-all" + ], + [ + "star-half-o", + "far", + "star-half" + ], + [ + "star-half-empty", + "far", + "star-half" + ], + [ + "star-half-full", + "far", + "star-half" + ], + [ + "code-fork", + null, + "code-branch" + ], + [ + "chain-broken", + null, + "unlink" + ], + [ + "shield", + null, + "shield-alt" + ], + [ + "calendar-o", + "far", + "calendar" + ], + [ + "maxcdn", + "fab", + null + ], + [ + "html5", + "fab", + null + ], + [ + "css3", + "fab", + null + ], + [ + "ticket", + null, + "ticket-alt" + ], + [ + "minus-square-o", + "far", + "minus-square" + ], + [ + "level-up", + null, + "level-up-alt" + ], + [ + "level-down", + null, + "level-down-alt" + ], + [ + "pencil-square", + null, + "pen-square" + ], + [ + "external-link-square", + null, + "external-link-square-alt" + ], + [ + "compass", + "far", + null + ], + [ + "caret-square-o-down", + "far", + "caret-square-down" + ], + [ + "toggle-down", + "far", + "caret-square-down" + ], + [ + "caret-square-o-up", + "far", + "caret-square-up" + ], + [ + "toggle-up", + "far", + "caret-square-up" + ], + [ + "caret-square-o-right", + "far", + "caret-square-right" + ], + [ + "toggle-right", + "far", + "caret-square-right" + ], + [ + "eur", + null, + "euro-sign" + ], + [ + "euro", + null, + "euro-sign" + ], + [ + "gbp", + null, + "pound-sign" + ], + [ + "usd", + null, + "dollar-sign" + ], + [ + "dollar", + null, + "dollar-sign" + ], + [ + "inr", + null, + "rupee-sign" + ], + [ + "rupee", + null, + "rupee-sign" + ], + [ + "jpy", + null, + "yen-sign" + ], + [ + "cny", + null, + "yen-sign" + ], + [ + "rmb", + null, + "yen-sign" + ], + [ + "yen", + null, + "yen-sign" + ], + [ + "rub", + null, + "ruble-sign" + ], + [ + "ruble", + null, + "ruble-sign" + ], + [ + "rouble", + null, + "ruble-sign" + ], + [ + "krw", + null, + "won-sign" + ], + [ + "won", + null, + "won-sign" + ], + [ + "btc", + "fab", + null + ], + [ + "bitcoin", + "fab", + "btc" + ], + [ + "file-text", + null, + "file-alt" + ], + [ + "sort-alpha-asc", + null, + "sort-alpha-down" + ], + [ + "sort-alpha-desc", + null, + "sort-alpha-up" + ], + [ + "sort-amount-asc", + null, + "sort-amount-down" + ], + [ + "sort-amount-desc", + null, + "sort-amount-up" + ], + [ + "sort-numeric-asc", + null, + "sort-numeric-down" + ], + [ + "sort-numeric-desc", + null, + "sort-numeric-up" + ], + [ + "youtube-square", + "fab", + "youtube" + ], + [ + "youtube", + "fab", + null + ], + [ + "xing", + "fab", + null + ], + [ + "xing-square", + "fab", + null + ], + [ + "youtube-play", + "fab", + "youtube" + ], + [ + "dropbox", + "fab", + null + ], + [ + "stack-overflow", + "fab", + null + ], + [ + "instagram", + "fab", + null + ], + [ + "flickr", + "fab", + null + ], + [ + "adn", + "fab", + null + ], + [ + "bitbucket", + "fab", + null + ], + [ + "bitbucket-square", + "fab", + "bitbucket" + ], + [ + "tumblr", + "fab", + null + ], + [ + "tumblr-square", + "fab", + null + ], + [ + "long-arrow-down", + null, + "long-arrow-alt-down" + ], + [ + "long-arrow-up", + null, + "long-arrow-alt-up" + ], + [ + "long-arrow-left", + null, + "long-arrow-alt-left" + ], + [ + "long-arrow-right", + null, + "long-arrow-alt-right" + ], + [ + "apple", + "fab", + null + ], + [ + "windows", + "fab", + null + ], + [ + "android", + "fab", + null + ], + [ + "linux", + "fab", + null + ], + [ + "dribbble", + "fab", + null + ], + [ + "skype", + "fab", + null + ], + [ + "foursquare", + "fab", + null + ], + [ + "trello", + "fab", + null + ], + [ + "gratipay", + "fab", + null + ], + [ + "gittip", + "fab", + "gratipay" + ], + [ + "sun-o", + "far", + "sun" + ], + [ + "moon-o", + "far", + "moon" + ], + [ + "vk", + "fab", + null + ], + [ + "weibo", + "fab", + null + ], + [ + "renren", + "fab", + null + ], + [ + "pagelines", + "fab", + null + ], + [ + "stack-exchange", + "fab", + null + ], + [ + "arrow-circle-o-right", + "far", + "arrow-alt-circle-right" + ], + [ + "arrow-circle-o-left", + "far", + "arrow-alt-circle-left" + ], + [ + "caret-square-o-left", + "far", + "caret-square-left" + ], + [ + "toggle-left", + "far", + "caret-square-left" + ], + [ + "dot-circle-o", + "far", + "dot-circle" + ], + [ + "vimeo-square", + "fab", + null + ], + [ + "try", + null, + "lira-sign" + ], + [ + "turkish-lira", + null, + "lira-sign" + ], + [ + "plus-square-o", + "far", + "plus-square" + ], + [ + "slack", + "fab", + null + ], + [ + "wordpress", + "fab", + null + ], + [ + "openid", + "fab", + null + ], + [ + "institution", + null, + "university" + ], + [ + "bank", + null, + "university" + ], + [ + "mortar-board", + null, + "graduation-cap" + ], + [ + "yahoo", + "fab", + null + ], + [ + "google", + "fab", + null + ], + [ + "reddit", + "fab", + null + ], + [ + "reddit-square", + "fab", + null + ], + [ + "stumbleupon-circle", + "fab", + null + ], + [ + "stumbleupon", + "fab", + null + ], + [ + "delicious", + "fab", + null + ], + [ + "digg", + "fab", + null + ], + [ + "pied-piper-pp", + "fab", + null + ], + [ + "pied-piper-alt", + "fab", + null + ], + [ + "drupal", + "fab", + null + ], + [ + "joomla", + "fab", + null + ], + [ + "spoon", + null, + "utensil-spoon" + ], + [ + "behance", + "fab", + null + ], + [ + "behance-square", + "fab", + null + ], + [ + "steam", + "fab", + null + ], + [ + "steam-square", + "fab", + null + ], + [ + "automobile", + null, + "car" + ], + [ + "cab", + null, + "taxi" + ], + [ + "spotify", + "fab", + null + ], + [ + "envelope-o", + "far", + "envelope" + ], + [ + "soundcloud", + "fab", + null + ], + [ + "file-pdf-o", + "far", + "file-pdf" + ], + [ + "file-word-o", + "far", + "file-word" + ], + [ + "file-excel-o", + "far", + "file-excel" + ], + [ + "file-powerpoint-o", + "far", + "file-powerpoint" + ], + [ + "file-image-o", + "far", + "file-image" + ], + [ + "file-photo-o", + "far", + "file-image" + ], + [ + "file-picture-o", + "far", + "file-image" + ], + [ + "file-archive-o", + "far", + "file-archive" + ], + [ + "file-zip-o", + "far", + "file-archive" + ], + [ + "file-audio-o", + "far", + "file-audio" + ], + [ + "file-sound-o", + "far", + "file-audio" + ], + [ + "file-video-o", + "far", + "file-video" + ], + [ + "file-movie-o", + "far", + "file-video" + ], + [ + "file-code-o", + "far", + "file-code" + ], + [ + "vine", + "fab", + null + ], + [ + "codepen", + "fab", + null + ], + [ + "jsfiddle", + "fab", + null + ], + [ + "life-ring", + "far", + null + ], + [ + "life-bouy", + "far", + "life-ring" + ], + [ + "life-buoy", + "far", + "life-ring" + ], + [ + "life-saver", + "far", + "life-ring" + ], + [ + "support", + "far", + "life-ring" + ], + [ + "circle-o-notch", + null, + "circle-notch" + ], + [ + "rebel", + "fab", + null + ], + [ + "ra", + "fab", + "rebel" + ], + [ + "resistance", + "fab", + "rebel" + ], + [ + "empire", + "fab", + null + ], + [ + "ge", + "fab", + "empire" + ], + [ + "git-square", + "fab", + null + ], + [ + "git", + "fab", + null + ], + [ + "hacker-news", + "fab", + null + ], + [ + "y-combinator-square", + "fab", + "hacker-news" + ], + [ + "yc-square", + "fab", + "hacker-news" + ], + [ + "tencent-weibo", + "fab", + null + ], + [ + "qq", + "fab", + null + ], + [ + "weixin", + "fab", + null + ], + [ + "wechat", + "fab", + "weixin" + ], + [ + "send", + null, + "paper-plane" + ], + [ + "paper-plane-o", + "far", + "paper-plane" + ], + [ + "send-o", + "far", + "paper-plane" + ], + [ + "circle-thin", + "far", + "circle" + ], + [ + "header", + null, + "heading" + ], + [ + "sliders", + null, + "sliders-h" + ], + [ + "futbol-o", + "far", + "futbol" + ], + [ + "soccer-ball-o", + "far", + "futbol" + ], + [ + "slideshare", + "fab", + null + ], + [ + "twitch", + "fab", + null + ], + [ + "yelp", + "fab", + null + ], + [ + "newspaper-o", + "far", + "newspaper" + ], + [ + "paypal", + "fab", + null + ], + [ + "google-wallet", + "fab", + null + ], + [ + "cc-visa", + "fab", + null + ], + [ + "cc-mastercard", + "fab", + null + ], + [ + "cc-discover", + "fab", + null + ], + [ + "cc-amex", + "fab", + null + ], + [ + "cc-paypal", + "fab", + null + ], + [ + "cc-stripe", + "fab", + null + ], + [ + "bell-slash-o", + "far", + "bell-slash" + ], + [ + "trash", + null, + "trash-alt" + ], + [ + "copyright", + "far", + null + ], + [ + "eyedropper", + null, + "eye-dropper" + ], + [ + "area-chart", + null, + "chart-area" + ], + [ + "pie-chart", + null, + "chart-pie" + ], + [ + "line-chart", + null, + "chart-line" + ], + [ + "lastfm", + "fab", + null + ], + [ + "lastfm-square", + "fab", + null + ], + [ + "ioxhost", + "fab", + null + ], + [ + "angellist", + "fab", + null + ], + [ + "cc", + "far", + "closed-captioning" + ], + [ + "ils", + null, + "shekel-sign" + ], + [ + "shekel", + null, + "shekel-sign" + ], + [ + "sheqel", + null, + "shekel-sign" + ], + [ + "meanpath", + "fab", + "font-awesome" + ], + [ + "buysellads", + "fab", + null + ], + [ + "connectdevelop", + "fab", + null + ], + [ + "dashcube", + "fab", + null + ], + [ + "forumbee", + "fab", + null + ], + [ + "leanpub", + "fab", + null + ], + [ + "sellsy", + "fab", + null + ], + [ + "shirtsinbulk", + "fab", + null + ], + [ + "simplybuilt", + "fab", + null + ], + [ + "skyatlas", + "fab", + null + ], + [ + "diamond", + "far", + "gem" + ], + [ + "intersex", + null, + "transgender" + ], + [ + "facebook-official", + "fab", + "facebook" + ], + [ + "pinterest-p", + "fab", + null + ], + [ + "whatsapp", + "fab", + null + ], + [ + "hotel", + null, + "bed" + ], + [ + "viacoin", + "fab", + null + ], + [ + "medium", + "fab", + null + ], + [ + "y-combinator", + "fab", + null + ], + [ + "yc", + "fab", + "y-combinator" + ], + [ + "optin-monster", + "fab", + null + ], + [ + "opencart", + "fab", + null + ], + [ + "expeditedssl", + "fab", + null + ], + [ + "battery-4", + null, + "battery-full" + ], + [ + "battery", + null, + "battery-full" + ], + [ + "battery-3", + null, + "battery-three-quarters" + ], + [ + "battery-2", + null, + "battery-half" + ], + [ + "battery-1", + null, + "battery-quarter" + ], + [ + "battery-0", + null, + "battery-empty" + ], + [ + "object-group", + "far", + null + ], + [ + "object-ungroup", + "far", + null + ], + [ + "sticky-note-o", + "far", + "sticky-note" + ], + [ + "cc-jcb", + "fab", + null + ], + [ + "cc-diners-club", + "fab", + null + ], + [ + "clone", + "far", + null + ], + [ + "hourglass-o", + "far", + "hourglass" + ], + [ + "hourglass-1", + null, + "hourglass-start" + ], + [ + "hourglass-2", + null, + "hourglass-half" + ], + [ + "hourglass-3", + null, + "hourglass-end" + ], + [ + "hand-rock-o", + "far", + "hand-rock" + ], + [ + "hand-grab-o", + "far", + "hand-rock" + ], + [ + "hand-paper-o", + "far", + "hand-paper" + ], + [ + "hand-stop-o", + "far", + "hand-paper" + ], + [ + "hand-scissors-o", + "far", + "hand-scissors" + ], + [ + "hand-lizard-o", + "far", + "hand-lizard" + ], + [ + "hand-spock-o", + "far", + "hand-spock" + ], + [ + "hand-pointer-o", + "far", + "hand-pointer" + ], + [ + "hand-peace-o", + "far", + "hand-peace" + ], + [ + "registered", + "far", + null + ], + [ + "creative-commons", + "fab", + null + ], + [ + "gg", + "fab", + null + ], + [ + "gg-circle", + "fab", + null + ], + [ + "tripadvisor", + "fab", + null + ], + [ + "odnoklassniki", + "fab", + null + ], + [ + "odnoklassniki-square", + "fab", + null + ], + [ + "get-pocket", + "fab", + null + ], + [ + "wikipedia-w", + "fab", + null + ], + [ + "safari", + "fab", + null + ], + [ + "chrome", + "fab", + null + ], + [ + "firefox", + "fab", + null + ], + [ + "opera", + "fab", + null + ], + [ + "internet-explorer", + "fab", + null + ], + [ + "television", + null, + "tv" + ], + [ + "contao", + "fab", + null + ], + [ + "500px", + "fab", + null + ], + [ + "amazon", + "fab", + null + ], + [ + "calendar-plus-o", + "far", + "calendar-plus" + ], + [ + "calendar-minus-o", + "far", + "calendar-minus" + ], + [ + "calendar-times-o", + "far", + "calendar-times" + ], + [ + "calendar-check-o", + "far", + "calendar-check" + ], + [ + "map-o", + "far", + "map" + ], + [ + "commenting", + null, + "comment-alt" + ], + [ + "commenting-o", + "far", + "comment-alt" + ], + [ + "houzz", + "fab", + null + ], + [ + "vimeo", + "fab", + "vimeo-v" + ], + [ + "black-tie", + "fab", + null + ], + [ + "fonticons", + "fab", + null + ], + [ + "reddit-alien", + "fab", + null + ], + [ + "edge", + "fab", + null + ], + [ + "credit-card-alt", + null, + "credit-card" + ], + [ + "codiepie", + "fab", + null + ], + [ + "modx", + "fab", + null + ], + [ + "fort-awesome", + "fab", + null + ], + [ + "usb", + "fab", + null + ], + [ + "product-hunt", + "fab", + null + ], + [ + "mixcloud", + "fab", + null + ], + [ + "scribd", + "fab", + null + ], + [ + "pause-circle-o", + "far", + "pause-circle" + ], + [ + "stop-circle-o", + "far", + "stop-circle" + ], + [ + "bluetooth", + "fab", + null + ], + [ + "bluetooth-b", + "fab", + null + ], + [ + "gitlab", + "fab", + null + ], + [ + "wpbeginner", + "fab", + null + ], + [ + "wpforms", + "fab", + null + ], + [ + "envira", + "fab", + null + ], + [ + "wheelchair-alt", + "fab", + "accessible-icon" + ], + [ + "question-circle-o", + "far", + "question-circle" + ], + [ + "volume-control-phone", + null, + "phone-volume" + ], + [ + "asl-interpreting", + null, + "american-sign-language-interpreting" + ], + [ + "deafness", + null, + "deaf" + ], + [ + "hard-of-hearing", + null, + "deaf" + ], + [ + "glide", + "fab", + null + ], + [ + "glide-g", + "fab", + null + ], + [ + "signing", + null, + "sign-language" + ], + [ + "viadeo", + "fab", + null + ], + [ + "viadeo-square", + "fab", + null + ], + [ + "snapchat", + "fab", + null + ], + [ + "snapchat-ghost", + "fab", + null + ], + [ + "snapchat-square", + "fab", + null + ], + [ + "pied-piper", + "fab", + null + ], + [ + "first-order", + "fab", + null + ], + [ + "yoast", + "fab", + null + ], + [ + "themeisle", + "fab", + null + ], + [ + "google-plus-official", + "fab", + "google-plus" + ], + [ + "google-plus-circle", + "fab", + "google-plus" + ], + [ + "font-awesome", + "fab", + null + ], + [ + "fa", + "fab", + "font-awesome" + ], + [ + "handshake-o", + "far", + "handshake" + ], + [ + "envelope-open-o", + "far", + "envelope-open" + ], + [ + "linode", + "fab", + null + ], + [ + "address-book-o", + "far", + "address-book" + ], + [ + "vcard", + null, + "address-card" + ], + [ + "address-card-o", + "far", + "address-card" + ], + [ + "vcard-o", + "far", + "address-card" + ], + [ + "user-circle-o", + "far", + "user-circle" + ], + [ + "user-o", + "far", + "user" + ], + [ + "id-badge", + "far", + null + ], + [ + "drivers-license", + null, + "id-card" + ], + [ + "id-card-o", + "far", + "id-card" + ], + [ + "drivers-license-o", + "far", + "id-card" + ], + [ + "quora", + "fab", + null + ], + [ + "free-code-camp", + "fab", + null + ], + [ + "telegram", + "fab", + null + ], + [ + "thermometer-4", + null, + "thermometer-full" + ], + [ + "thermometer", + null, + "thermometer-full" + ], + [ + "thermometer-3", + null, + "thermometer-three-quarters" + ], + [ + "thermometer-2", + null, + "thermometer-half" + ], + [ + "thermometer-1", + null, + "thermometer-quarter" + ], + [ + "thermometer-0", + null, + "thermometer-empty" + ], + [ + "bathtub", + null, + "bath" + ], + [ + "s15", + null, + "bath" + ], + [ + "window-maximize", + "far", + null + ], + [ + "window-restore", + "far", + null + ], + [ + "times-rectangle", + null, + "window-close" + ], + [ + "window-close-o", + "far", + "window-close" + ], + [ + "times-rectangle-o", + "far", + "window-close" + ], + [ + "bandcamp", + "fab", + null + ], + [ + "grav", + "fab", + null + ], + [ + "etsy", + "fab", + null + ], + [ + "imdb", + "fab", + null + ], + [ + "ravelry", + "fab", + null + ], + [ + "eercast", + "fab", + "sellcast" + ], + [ + "snowflake-o", + "far", + "snowflake" + ], + [ + "superpowers", + "fab", + null + ], + [ + "wpexplorer", + "fab", + null + ], + [ + "deviantart", + "fab", + null + ] +] \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.yml b/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.yml new file mode 100644 index 000000000..8495b1411 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/metadata/shims.yml @@ -0,0 +1,292 @@ +area-chart: + name: chart-area +arrow-circle-o-down: + name: arrow-alt-circle-down + prefix: far +arrow-circle-o-left: + name: arrow-alt-circle-left + prefix: far +arrow-circle-o-right: + name: arrow-alt-circle-right + prefix: far +arrow-circle-o-up: + name: arrow-alt-circle-up + prefix: far +arrows: + name: arrows-alt +arrows-alt: + name: expand-arrows-alt +arrows-h: + name: arrows-alt-h +arrows-v: + name: arrows-alt-v +bar-chart: + name: chart-bar + prefix: far +bitbucket-square: + name: bitbucket + prefix: fab +calendar: + name: calendar-alt +calendar-o: + name: calendar + prefix: far +caret-square-o-down: + name: caret-square-down + prefix: far +caret-square-o-left: + name: caret-square-left + prefix: far +caret-square-o-right: + name: caret-square-right + prefix: far +caret-square-o-up: + name: caret-square-up + prefix: far +cc: + name: closed-captioning + prefix: far +chain-broken: + name: unlink +circle-o-notch: + name: circle-notch +circle-thin: + name: circle + prefix: far +clipboard: + prefix: far +clone: + prefix: far +cloud-download: + name: cloud-download-alt +cloud-upload: + name: cloud-upload-alt +code-fork: + name: code-branch +commenting: + name: comment-alt +compass: + prefix: far +copyright: + prefix: far +creative-commons: + prefix: fab +credit-card: + prefix: far +credit-card-alt: + name: credit-card +cutlery: + name: utensils +diamond: + name: gem + prefix: far +eercast: + name: sellcast + prefix: fab +eur: + name: euro-sign +exchange: + name: exchange-alt +external-link: + name: external-link-alt +external-link-square: + name: external-link-square-alt +eye-dropper: + name: eye-dropper + prefix: far +eye-slash: + prefix: far +eyedropper: + name: eye-dropper +facebook: + name: facebook-f + prefix: fab +facebook-official: + name: facebook + prefix: fab +file-text: + name: file-alt +files-o: + name: copy + prefix: far +floppy-o: + name: save + prefix: far +gbp: + name: pound-sign +glass: + name: glass-martini +google-plus: + name: google-plus-g + prefix: fab +google-plus-circle: + name: google-plus + prefix: fab +google-plus-official: + name: google-plus + prefix: fab +hand-o-down: + name: hand-point-down + prefix: far +hand-o-left: + name: hand-point-left + prefix: far +hand-o-right: + name: hand-point-right + prefix: far +hand-o-up: + name: hand-point-up + prefix: far +header: + name: heading +id-badge: + prefix: far +ils: + name: shekel-sign +inr: + name: rupee-sign +intersex: + name: transgender +jpy: + name: yen-sign +krw: + name: won-sign +level-down: + name: level-down-alt +level-up: + name: level-up-alt +life-ring: + prefix: far +line-chart: + name: chart-line +linkedin: + name: linkedin-in + prefix: fab +linkedin-square: + name: linkedin + prefix: fab +list-alt: + prefix: far +long-arrow-down: + name: long-arrow-alt-down +long-arrow-left: + name: long-arrow-alt-left +long-arrow-right: + name: long-arrow-alt-right +long-arrow-up: + name: long-arrow-alt-up +map-marker: + name: map-marker-alt +meanpath: + name: font-awesome + prefix: fab +mobile: + name: mobile-alt +money: + name: money-bill-alt + prefix: far +object-group: + prefix: far +object-ungroup: + prefix: far +paste: + prefix: far +pencil: + name: pencil-alt +pencil-square: + name: pen-square +pencil-square-o: + name: edit + prefix: far +picture: + name: image +pie-chart: + name: chart-pie +refresh: + name: sync +registered: + prefix: far +repeat: + name: redo +rub: + name: ruble-sign +scissors: + name: cut +shield: + name: shield-alt +sign-in: + name: sign-in-alt +sign-out: + name: sign-out-alt +sliders: + name: sliders-h +sort-alpha-asc: + name: sort-alpha-down +sort-alpha-desc: + name: sort-alpha-up +sort-amount-asc: + name: sort-amount-down +sort-amount-desc: + name: sort-amount-up +sort-asc: + name: sort-up +sort-desc: + name: sort-down +sort-numeric-asc: + name: sort-numeric-down +sort-numeric-desc: + name: sort-numeric-up +spoon: + name: utensil-spoon +star-half-empty: + name: star-half +star-half-full: + name: star-half +support: + name: life-ring + prefix: far +tablet: + name: tablet-alt +tachometer: + name: tachometer-alt +television: + name: tv +thumb-tack: + name: thumbtack +thumbs-o-down: + name: thumbs-down + prefix: far +thumbs-o-up: + name: thumbs-up + prefix: far +ticket: + name: ticket-alt +trash: + name: trash-alt +trash-o: + name: trash-alt + prefix: far +try: + name: lira-sign +usd: + name: dollar-sign +video-camera: + name: video +vimeo: + name: vimeo-v + prefix: fab +volume-control-phone: + name: phone-volume +wheelchair-alt: + name: accessible-icon + prefix: fab +window-maximize: + prefix: far +window-restore: + prefix: far +youtube-play: + name: youtube + prefix: fab +youtube-square: + name: youtube + prefix: fab diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/500px.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/500px.svg new file mode 100644 index 000000000..d872f24a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/500px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accessible-icon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accessible-icon.svg new file mode 100644 index 000000000..725b9028c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accessible-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accusoft.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accusoft.svg new file mode 100644 index 000000000..8c6f59a27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/accusoft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adn.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adn.svg new file mode 100644 index 000000000..ee285395f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adversal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adversal.svg new file mode 100644 index 000000000..125dd5019 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/adversal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/affiliatetheme.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/affiliatetheme.svg new file mode 100644 index 000000000..d5dd4e8e8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/affiliatetheme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/algolia.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/algolia.svg new file mode 100644 index 000000000..979d7cd71 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/algolia.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amazon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amazon.svg new file mode 100644 index 000000000..642fdb2d9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amazon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amilia.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amilia.svg new file mode 100644 index 000000000..56cb7b4ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/amilia.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/android.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/android.svg new file mode 100644 index 000000000..62de4106b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angellist.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angellist.svg new file mode 100644 index 000000000..422885c2f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angellist.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angrycreative.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angrycreative.svg new file mode 100644 index 000000000..b2624691c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angrycreative.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angular.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angular.svg new file mode 100644 index 000000000..83dcd9d78 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/angular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store-ios.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store-ios.svg new file mode 100644 index 000000000..12fc84843 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store-ios.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store.svg new file mode 100644 index 000000000..964ccb926 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/app-store.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apper.svg new file mode 100644 index 000000000..f986f504a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple-pay.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple-pay.svg new file mode 100644 index 000000000..5d3145ada --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple-pay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple.svg new file mode 100644 index 000000000..0181ed8a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/apple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/asymmetrik.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/asymmetrik.svg new file mode 100644 index 000000000..ef4729624 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/asymmetrik.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/audible.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/audible.svg new file mode 100644 index 000000000..7ee5aef8a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/audible.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/autoprefixer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/autoprefixer.svg new file mode 100644 index 000000000..912dee1b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/autoprefixer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/avianex.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/avianex.svg new file mode 100644 index 000000000..409530967 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/avianex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aviato.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aviato.svg new file mode 100644 index 000000000..94c4adb52 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aviato.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aws.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aws.svg new file mode 100644 index 000000000..6adb45483 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/aws.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bandcamp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bandcamp.svg new file mode 100644 index 000000000..f1e1c204f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bandcamp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance-square.svg new file mode 100644 index 000000000..6a23a2aef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance.svg new file mode 100644 index 000000000..73e946774 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/behance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bimobject.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bimobject.svg new file mode 100644 index 000000000..b708fdea9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bimobject.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitbucket.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitbucket.svg new file mode 100644 index 000000000..f78877e36 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitbucket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitcoin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitcoin.svg new file mode 100644 index 000000000..9ee5f2ef9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bitcoin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bity.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bity.svg new file mode 100644 index 000000000..11122ffbc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bity.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/black-tie.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/black-tie.svg new file mode 100644 index 000000000..36f3eb79e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/black-tie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blackberry.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blackberry.svg new file mode 100644 index 000000000..d83088658 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blackberry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger-b.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger-b.svg new file mode 100644 index 000000000..c313b5212 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger-b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger.svg new file mode 100644 index 000000000..7707557e4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/blogger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth-b.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth-b.svg new file mode 100644 index 000000000..d6e3a5e12 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth-b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth.svg new file mode 100644 index 000000000..aad75a381 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/bluetooth.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/btc.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/btc.svg new file mode 100644 index 000000000..45e65158d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/btc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buromobelexperte.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buromobelexperte.svg new file mode 100644 index 000000000..f419c9091 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buromobelexperte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buysellads.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buysellads.svg new file mode 100644 index 000000000..5bb292db5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/buysellads.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-amex.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-amex.svg new file mode 100644 index 000000000..9ad630d15 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-amex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-apple-pay.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-apple-pay.svg new file mode 100644 index 000000000..a8a56ed58 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-apple-pay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-diners-club.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-diners-club.svg new file mode 100644 index 000000000..7ade2bb53 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-diners-club.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-discover.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-discover.svg new file mode 100644 index 000000000..f45384a0f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-discover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-jcb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-jcb.svg new file mode 100644 index 000000000..8671a8844 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-jcb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-mastercard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-mastercard.svg new file mode 100644 index 000000000..af0753ea1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-mastercard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-paypal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-paypal.svg new file mode 100644 index 000000000..6ca920055 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-paypal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-stripe.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-stripe.svg new file mode 100644 index 000000000..3af1d8f07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-stripe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-visa.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-visa.svg new file mode 100644 index 000000000..b5cb29a20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cc-visa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/centercode.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/centercode.svg new file mode 100644 index 000000000..440b9c83a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/centercode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/chrome.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/chrome.svg new file mode 100644 index 000000000..5ea90d91b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/chrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudscale.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudscale.svg new file mode 100644 index 000000000..9ad2a4055 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudscale.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudsmith.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudsmith.svg new file mode 100644 index 000000000..bd2d47041 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudsmith.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudversify.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudversify.svg new file mode 100644 index 000000000..4ed2518d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cloudversify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codepen.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codepen.svg new file mode 100644 index 000000000..325853708 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codepen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codiepie.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codiepie.svg new file mode 100644 index 000000000..dc7579c07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/codiepie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/connectdevelop.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/connectdevelop.svg new file mode 100644 index 000000000..8588469ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/connectdevelop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/contao.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/contao.svg new file mode 100644 index 000000000..a08f60aff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/contao.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cpanel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cpanel.svg new file mode 100644 index 000000000..7063f1188 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cpanel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/creative-commons.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/creative-commons.svg new file mode 100644 index 000000000..2d572c5b8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/creative-commons.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3-alt.svg new file mode 100644 index 000000000..544362a13 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3.svg new file mode 100644 index 000000000..5ea43eda3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/css3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cuttlefish.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cuttlefish.svg new file mode 100644 index 000000000..92f20d8ea --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/cuttlefish.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/d-and-d.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/d-and-d.svg new file mode 100644 index 000000000..9411ae036 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/d-and-d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dashcube.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dashcube.svg new file mode 100644 index 000000000..ef3bebca1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dashcube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/delicious.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/delicious.svg new file mode 100644 index 000000000..bbd3acc8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/delicious.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deploydog.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deploydog.svg new file mode 100644 index 000000000..c9764e801 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deploydog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deskpro.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deskpro.svg new file mode 100644 index 000000000..69d6e8cf6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deskpro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deviantart.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deviantart.svg new file mode 100644 index 000000000..017804bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/deviantart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digg.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digg.svg new file mode 100644 index 000000000..9c580fb0e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digital-ocean.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digital-ocean.svg new file mode 100644 index 000000000..84867cff9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/digital-ocean.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discord.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discord.svg new file mode 100644 index 000000000..650fe8f01 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discord.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discourse.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discourse.svg new file mode 100644 index 000000000..874039759 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/discourse.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dochub.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dochub.svg new file mode 100644 index 000000000..c336088d4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dochub.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/docker.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/docker.svg new file mode 100644 index 000000000..c4b131982 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/docker.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/draft2digital.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/draft2digital.svg new file mode 100644 index 000000000..e30e3c8da --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/draft2digital.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble-square.svg new file mode 100644 index 000000000..147f5aee6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble.svg new file mode 100644 index 000000000..94f80c604 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dribbble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dropbox.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dropbox.svg new file mode 100644 index 000000000..cbc4787b7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dropbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/drupal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/drupal.svg new file mode 100644 index 000000000..09a90aeeb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/drupal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dyalog.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dyalog.svg new file mode 100644 index 000000000..40a59c736 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/dyalog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/earlybirds.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/earlybirds.svg new file mode 100644 index 000000000..42c9f51f1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/earlybirds.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/edge.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/edge.svg new file mode 100644 index 000000000..70548ac78 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/edge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ember.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ember.svg new file mode 100644 index 000000000..070995d8e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ember.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/empire.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/empire.svg new file mode 100644 index 000000000..b000c8e07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/empire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/envira.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/envira.svg new file mode 100644 index 000000000..92aee1438 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/envira.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/erlang.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/erlang.svg new file mode 100644 index 000000000..c0a09aaae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/erlang.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/etsy.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/etsy.svg new file mode 100644 index 000000000..1dc363414 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/etsy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/expeditedssl.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/expeditedssl.svg new file mode 100644 index 000000000..a5c29368c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/expeditedssl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-f.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-f.svg new file mode 100644 index 000000000..56bfbc436 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-f.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-messenger.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-messenger.svg new file mode 100644 index 000000000..1ab970792 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-messenger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-square.svg new file mode 100644 index 000000000..c78d21d87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook.svg new file mode 100644 index 000000000..f6931b6b5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/facebook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firefox.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firefox.svg new file mode 100644 index 000000000..ba83d29cb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firefox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/first-order.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/first-order.svg new file mode 100644 index 000000000..527e4a5a9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/first-order.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firstdraft.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firstdraft.svg new file mode 100644 index 000000000..c2bcd3124 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/firstdraft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/flickr.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/flickr.svg new file mode 100644 index 000000000..15dcfc6c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/flickr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fly.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fly.svg new file mode 100644 index 000000000..69ee5c7b7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-alt.svg new file mode 100644 index 000000000..90132af99 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-flag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-flag.svg new file mode 100644 index 000000000..9f0b7a480 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome-flag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome.svg new file mode 100644 index 000000000..8c1d44528 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/font-awesome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons-fi.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons-fi.svg new file mode 100644 index 000000000..e654422ce --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons-fi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons.svg new file mode 100644 index 000000000..6772eb9f5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fonticons.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome-alt.svg new file mode 100644 index 000000000..5a8e0e0c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome.svg new file mode 100644 index 000000000..28e38d982 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/fort-awesome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/forumbee.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/forumbee.svg new file mode 100644 index 000000000..d31d64118 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/forumbee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/foursquare.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/foursquare.svg new file mode 100644 index 000000000..130fa9b39 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/foursquare.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/free-code-camp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/free-code-camp.svg new file mode 100644 index 000000000..be4d13b7e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/free-code-camp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/freebsd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/freebsd.svg new file mode 100644 index 000000000..98c790fa0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/freebsd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/get-pocket.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/get-pocket.svg new file mode 100644 index 000000000..f6046088f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/get-pocket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg-circle.svg new file mode 100644 index 000000000..7ff26dd65 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg.svg new file mode 100644 index 000000000..cace4961a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git-square.svg new file mode 100644 index 000000000..a6f9a2d13 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git.svg new file mode 100644 index 000000000..468515bdb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/git.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-alt.svg new file mode 100644 index 000000000..43d2da5d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-square.svg new file mode 100644 index 000000000..a235d2f4e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github.svg new file mode 100644 index 000000000..53bd7b2d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitkraken.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitkraken.svg new file mode 100644 index 000000000..a3bc20fc3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitkraken.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitlab.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitlab.svg new file mode 100644 index 000000000..5f18f6f37 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitlab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitter.svg new file mode 100644 index 000000000..6aaafd9a4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide-g.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide-g.svg new file mode 100644 index 000000000..7517405f6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide-g.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide.svg new file mode 100644 index 000000000..0fbdca4b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/glide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gofore.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gofore.svg new file mode 100644 index 000000000..792de75e7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gofore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads-g.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads-g.svg new file mode 100644 index 000000000..b35546631 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads-g.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads.svg new file mode 100644 index 000000000..040163af9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/goodreads.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-drive.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-drive.svg new file mode 100644 index 000000000..cd8dd52a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-drive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-play.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-play.svg new file mode 100644 index 000000000..82cffd530 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-g.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-g.svg new file mode 100644 index 000000000..c4587db39 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-g.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-square.svg new file mode 100644 index 000000000..f18979c9f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus.svg new file mode 100644 index 000000000..46e143e6b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-wallet.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-wallet.svg new file mode 100644 index 000000000..009afb61c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google-wallet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google.svg new file mode 100644 index 000000000..014b5ceb9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gratipay.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gratipay.svg new file mode 100644 index 000000000..a35d8b197 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gratipay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grav.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grav.svg new file mode 100644 index 000000000..e12bbf51e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grav.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gripfire.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gripfire.svg new file mode 100644 index 000000000..36556490d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gripfire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grunt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grunt.svg new file mode 100644 index 000000000..89a1f5523 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/grunt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gulp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gulp.svg new file mode 100644 index 000000000..0bb37a270 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/gulp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news-square.svg new file mode 100644 index 000000000..1bb8cab45 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news.svg new file mode 100644 index 000000000..0de37e65c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hacker-news.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hire-a-helper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hire-a-helper.svg new file mode 100644 index 000000000..5fdb39dc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hire-a-helper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hooli.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hooli.svg new file mode 100644 index 000000000..3c0e6b2c7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hooli.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hotjar.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hotjar.svg new file mode 100644 index 000000000..c514d2a41 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hotjar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/houzz.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/houzz.svg new file mode 100644 index 000000000..6392132c8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/houzz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/html5.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/html5.svg new file mode 100644 index 000000000..a06827da3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/html5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hubspot.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hubspot.svg new file mode 100644 index 000000000..03f8f4e0c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/hubspot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/imdb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/imdb.svg new file mode 100644 index 000000000..95fd166c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/imdb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/instagram.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/instagram.svg new file mode 100644 index 000000000..89c89b76f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/instagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/internet-explorer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/internet-explorer.svg new file mode 100644 index 000000000..36173c0ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/internet-explorer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ioxhost.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ioxhost.svg new file mode 100644 index 000000000..64f31af27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ioxhost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes-note.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes-note.svg new file mode 100644 index 000000000..bb46e7024 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes-note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes.svg new file mode 100644 index 000000000..32736ae83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/itunes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jenkins.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jenkins.svg new file mode 100644 index 000000000..4c2251f1b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jenkins.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joget.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joget.svg new file mode 100644 index 000000000..01e76d091 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joget.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joomla.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joomla.svg new file mode 100644 index 000000000..a5654303b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/joomla.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js-square.svg new file mode 100644 index 000000000..5f2b199b8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js.svg new file mode 100644 index 000000000..1bf21b891 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/js.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jsfiddle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jsfiddle.svg new file mode 100644 index 000000000..2fb27ee36 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/jsfiddle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/keycdn.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/keycdn.svg new file mode 100644 index 000000000..da19aee02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/keycdn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter-k.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter-k.svg new file mode 100644 index 000000000..4ad8ad2cb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter-k.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter.svg new file mode 100644 index 000000000..c765b1b40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/kickstarter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/laravel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/laravel.svg new file mode 100644 index 000000000..a308b7ee6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/laravel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm-square.svg new file mode 100644 index 000000000..fd4b7a8f3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm-square.svg @@ -0,0 +1 @@ +> \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm.svg new file mode 100644 index 000000000..7508067ab --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lastfm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/leanpub.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/leanpub.svg new file mode 100644 index 000000000..994eca34d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/leanpub.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/less.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/less.svg new file mode 100644 index 000000000..12a0ae2a9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/less.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/line.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/line.svg new file mode 100644 index 000000000..866abd878 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin-in.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin-in.svg new file mode 100644 index 000000000..5af65df8c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin-in.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin.svg new file mode 100644 index 000000000..69d8e9731 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linkedin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linode.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linode.svg new file mode 100644 index 000000000..502bdf796 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linux.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linux.svg new file mode 100644 index 000000000..3258ef705 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/linux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lyft.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lyft.svg new file mode 100644 index 000000000..4283ec51a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/lyft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/magento.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/magento.svg new file mode 100644 index 000000000..bdf6488e5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/magento.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/maxcdn.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/maxcdn.svg new file mode 100644 index 000000000..4f4b85da4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/maxcdn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medapps.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medapps.svg new file mode 100644 index 000000000..41f3273bd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medapps.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium-m.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium-m.svg new file mode 100644 index 000000000..5f0aff837 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium.svg new file mode 100644 index 000000000..1c9f86fc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medrt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medrt.svg new file mode 100644 index 000000000..377594460 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/medrt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/meetup.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/meetup.svg new file mode 100644 index 000000000..d387c4bdb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/meetup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/microsoft.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/microsoft.svg new file mode 100644 index 000000000..ed8989554 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/microsoft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mix.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mix.svg new file mode 100644 index 000000000..d1d2c5ab2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mixcloud.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mixcloud.svg new file mode 100644 index 000000000..094239bbf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mixcloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mizuni.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mizuni.svg new file mode 100644 index 000000000..8cb8d9185 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/mizuni.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/modx.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/modx.svg new file mode 100644 index 000000000..9cbc71fde --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/modx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/monero.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/monero.svg new file mode 100644 index 000000000..c4892b6c5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/monero.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/napster.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/napster.svg new file mode 100644 index 000000000..866e31da6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/napster.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nintendo-switch.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nintendo-switch.svg new file mode 100644 index 000000000..56dfeafc8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nintendo-switch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node-js.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node-js.svg new file mode 100644 index 000000000..19c8064e5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node-js.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node.svg new file mode 100644 index 000000000..3bdb5eacd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/node.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/npm.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/npm.svg new file mode 100644 index 000000000..ad643c367 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/npm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ns8.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ns8.svg new file mode 100644 index 000000000..1f5e2fc94 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ns8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nutritionix.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nutritionix.svg new file mode 100644 index 000000000..19eb0e078 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/nutritionix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki-square.svg new file mode 100644 index 000000000..e2793a94e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki.svg new file mode 100644 index 000000000..f426fd364 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/odnoklassniki.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opencart.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opencart.svg new file mode 100644 index 000000000..2f1498a1a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opencart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/openid.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/openid.svg new file mode 100644 index 000000000..d36573e03 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/openid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opera.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opera.svg new file mode 100644 index 000000000..4fd8cb920 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/opera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/optin-monster.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/optin-monster.svg new file mode 100644 index 000000000..deea2e3d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/optin-monster.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/osi.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/osi.svg new file mode 100644 index 000000000..375a5aa95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/osi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/page4.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/page4.svg new file mode 100644 index 000000000..e0eda5d37 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/page4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pagelines.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pagelines.svg new file mode 100644 index 000000000..6722988a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pagelines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/palfed.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/palfed.svg new file mode 100644 index 000000000..a23e076d0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/palfed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/patreon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/patreon.svg new file mode 100644 index 000000000..27b7c9b4d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/patreon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/paypal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/paypal.svg new file mode 100644 index 000000000..ecf00b6d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/paypal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/periscope.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/periscope.svg new file mode 100644 index 000000000..9f46704c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/periscope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phabricator.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phabricator.svg new file mode 100644 index 000000000..c51884753 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phabricator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phoenix-framework.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phoenix-framework.svg new file mode 100644 index 000000000..57d9e259a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/phoenix-framework.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-alt.svg new file mode 100644 index 000000000..0c57b063d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-pp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-pp.svg new file mode 100644 index 000000000..092ca730a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper-pp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper.svg new file mode 100644 index 000000000..2f93465dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pied-piper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-p.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-p.svg new file mode 100644 index 000000000..311932af8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-p.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-square.svg new file mode 100644 index 000000000..7a502a796 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest.svg new file mode 100644 index 000000000..42c1f6455 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pinterest.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/playstation.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/playstation.svg new file mode 100644 index 000000000..333612415 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/playstation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/product-hunt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/product-hunt.svg new file mode 100644 index 000000000..847ac2c21 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/product-hunt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pushed.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pushed.svg new file mode 100644 index 000000000..f7e24f0ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/pushed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/python.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/python.svg new file mode 100644 index 000000000..915edb6d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/python.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/qq.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/qq.svg new file mode 100644 index 000000000..541bdd570 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/quora.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/quora.svg new file mode 100644 index 000000000..601d815c7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/quora.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ravelry.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ravelry.svg new file mode 100644 index 000000000..49d511c03 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ravelry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/react.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/react.svg new file mode 100644 index 000000000..993b43e8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rebel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rebel.svg new file mode 100644 index 000000000..555b05339 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rebel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/red-river.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/red-river.svg new file mode 100644 index 000000000..6dba236e1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/red-river.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-alien.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-alien.svg new file mode 100644 index 000000000..85b98591e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-alien.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-square.svg new file mode 100644 index 000000000..e940a8517 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit.svg new file mode 100644 index 000000000..262d0a7f8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/reddit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rendact.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rendact.svg new file mode 100644 index 000000000..b3c45ecca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rendact.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/renren.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/renren.svg new file mode 100644 index 000000000..9706a7029 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/renren.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/replyd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/replyd.svg new file mode 100644 index 000000000..fe526f2b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/replyd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/resolving.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/resolving.svg new file mode 100644 index 000000000..339cbca04 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/resolving.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rocketchat.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rocketchat.svg new file mode 100644 index 000000000..fc05337be --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rocketchat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rockrms.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rockrms.svg new file mode 100644 index 000000000..6c41d7905 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/rockrms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/safari.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/safari.svg new file mode 100644 index 000000000..70dc86b8d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/safari.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sass.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sass.svg new file mode 100644 index 000000000..4f5531958 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/schlix.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/schlix.svg new file mode 100644 index 000000000..413e4ff70 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/schlix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/scribd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/scribd.svg new file mode 100644 index 000000000..f1ecad19d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/scribd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/searchengin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/searchengin.svg new file mode 100644 index 000000000..2ed72b1ac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/searchengin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellcast.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellcast.svg new file mode 100644 index 000000000..75b47f18f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellcast.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellsy.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellsy.svg new file mode 100644 index 000000000..6119fe585 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sellsy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/servicestack.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/servicestack.svg new file mode 100644 index 000000000..9f937eb4d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/servicestack.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/shirtsinbulk.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/shirtsinbulk.svg new file mode 100644 index 000000000..c3033b015 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/shirtsinbulk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/simplybuilt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/simplybuilt.svg new file mode 100644 index 000000000..fbecfe964 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/simplybuilt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sistrix.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sistrix.svg new file mode 100644 index 000000000..e62cef615 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sistrix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skyatlas.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skyatlas.svg new file mode 100644 index 000000000..45d4bc1dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skyatlas.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skype.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skype.svg new file mode 100644 index 000000000..538843cd6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/skype.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack-hash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack-hash.svg new file mode 100644 index 000000000..a465405ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack-hash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack.svg new file mode 100644 index 000000000..35db81159 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slack.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slideshare.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slideshare.svg new file mode 100644 index 000000000..faaee9454 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/slideshare.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-ghost.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-ghost.svg new file mode 100644 index 000000000..2d96a66ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-ghost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-square.svg new file mode 100644 index 000000000..c91e05ecb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat.svg new file mode 100644 index 000000000..88cfa1670 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/snapchat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/soundcloud.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/soundcloud.svg new file mode 100644 index 000000000..0d9b06160 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/soundcloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/speakap.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/speakap.svg new file mode 100644 index 000000000..b97a60729 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/speakap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/spotify.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/spotify.svg new file mode 100644 index 000000000..dcd028a9a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/spotify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-exchange.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-exchange.svg new file mode 100644 index 000000000..5b15cc0ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-exchange.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-overflow.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-overflow.svg new file mode 100644 index 000000000..aca5bde52 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stack-overflow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/staylinked.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/staylinked.svg new file mode 100644 index 000000000..696255a14 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/staylinked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-square.svg new file mode 100644 index 000000000..59a6a8f61 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-symbol.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-symbol.svg new file mode 100644 index 000000000..f0ab74db5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam-symbol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam.svg new file mode 100644 index 000000000..04b9396bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/steam.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sticker-mule.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sticker-mule.svg new file mode 100644 index 000000000..78c3d5883 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/sticker-mule.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/strava.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/strava.svg new file mode 100644 index 000000000..f69462e9b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/strava.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe-s.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe-s.svg new file mode 100644 index 000000000..5271a4b83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe-s.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe.svg new file mode 100644 index 000000000..4e79f8f25 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stripe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/studiovinari.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/studiovinari.svg new file mode 100644 index 000000000..e6e7fa897 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/studiovinari.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon-circle.svg new file mode 100644 index 000000000..a4b42346c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon.svg new file mode 100644 index 000000000..999d38627 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/stumbleupon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/superpowers.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/superpowers.svg new file mode 100644 index 000000000..a6f13f6d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/superpowers.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/supple.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/supple.svg new file mode 100644 index 000000000..5afe87926 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/supple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram-plane.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram-plane.svg new file mode 100644 index 000000000..a4e067b5d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram-plane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram.svg new file mode 100644 index 000000000..fc5492cc9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/telegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tencent-weibo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tencent-weibo.svg new file mode 100644 index 000000000..30b49fc82 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tencent-weibo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/themeisle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/themeisle.svg new file mode 100644 index 000000000..b93377556 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/themeisle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/trello.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/trello.svg new file mode 100644 index 000000000..fba695d41 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/trello.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tripadvisor.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tripadvisor.svg new file mode 100644 index 000000000..4f3e2b6dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tripadvisor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr-square.svg new file mode 100644 index 000000000..96b8cf5c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr.svg new file mode 100644 index 000000000..da593777a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/tumblr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitch.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitch.svg new file mode 100644 index 000000000..89a02fb6f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter-square.svg new file mode 100644 index 000000000..0ca7e0b97 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter.svg new file mode 100644 index 000000000..f0ed9c5fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/typo3.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/typo3.svg new file mode 100644 index 000000000..ef5341db4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/typo3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uber.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uber.svg new file mode 100644 index 000000000..569a1cd9c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uber.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uikit.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uikit.svg new file mode 100644 index 000000000..26ab61104 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uikit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uniregistry.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uniregistry.svg new file mode 100644 index 000000000..a58a5093f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/uniregistry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/untappd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/untappd.svg new file mode 100644 index 000000000..5e0629387 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/untappd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/usb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/usb.svg new file mode 100644 index 000000000..a9d265eee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/usb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ussunnah.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ussunnah.svg new file mode 100644 index 000000000..1dd9ed125 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/ussunnah.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vaadin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vaadin.svg new file mode 100644 index 000000000..fadce5ada --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vaadin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viacoin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viacoin.svg new file mode 100644 index 000000000..c4777d6fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viacoin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo-square.svg new file mode 100644 index 000000000..9212671d0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo.svg new file mode 100644 index 000000000..f4c1f8a1b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viadeo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viber.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viber.svg new file mode 100644 index 000000000..ec16581dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/viber.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-square.svg new file mode 100644 index 000000000..eed266e79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-v.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-v.svg new file mode 100644 index 000000000..c87152815 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo-v.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo.svg new file mode 100644 index 000000000..3a0c52739 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vimeo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vine.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vine.svg new file mode 100644 index 000000000..53cb27f89 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vk.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vk.svg new file mode 100644 index 000000000..022717d16 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vnv.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vnv.svg new file mode 100644 index 000000000..56cd37b49 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vnv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vuejs.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vuejs.svg new file mode 100644 index 000000000..932887c13 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/vuejs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weibo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weibo.svg new file mode 100644 index 000000000..84f18c49f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weibo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weixin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weixin.svg new file mode 100644 index 000000000..ec39377a7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/weixin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp-square.svg new file mode 100644 index 000000000..7db67533d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp.svg new file mode 100644 index 000000000..cc6f4bada --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whatsapp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whmcs.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whmcs.svg new file mode 100644 index 000000000..2bbd6959f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/whmcs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wikipedia-w.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wikipedia-w.svg new file mode 100644 index 000000000..075425306 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wikipedia-w.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/windows.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/windows.svg new file mode 100644 index 000000000..586ba25dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/windows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress-simple.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress-simple.svg new file mode 100644 index 000000000..de9795ad2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress-simple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress.svg new file mode 100644 index 000000000..3cc2bd44d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wordpress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpbeginner.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpbeginner.svg new file mode 100644 index 000000000..1f81e8445 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpbeginner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpexplorer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpexplorer.svg new file mode 100644 index 000000000..706e12a94 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpexplorer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpforms.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpforms.svg new file mode 100644 index 000000000..03a3662b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/wpforms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xbox.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xbox.svg new file mode 100644 index 000000000..5420576e3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing-square.svg new file mode 100644 index 000000000..8c9fb8292 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing.svg new file mode 100644 index 000000000..c40077111 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/xing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/y-combinator.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/y-combinator.svg new file mode 100644 index 000000000..d4a0f7e2c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/y-combinator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yahoo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yahoo.svg new file mode 100644 index 000000000..64b70d921 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yahoo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex-international.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex-international.svg new file mode 100644 index 000000000..2b1c10c79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex-international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex.svg new file mode 100644 index 000000000..d054fe043 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yandex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yelp.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yelp.svg new file mode 100644 index 000000000..e339dd5c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yelp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yoast.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yoast.svg new file mode 100644 index 000000000..1ea820e02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/yoast.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/youtube.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/youtube.svg new file mode 100644 index 000000000..e831b886f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/brands/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-book.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-book.svg new file mode 100644 index 000000000..0beb26ad9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-card.svg new file mode 100644 index 000000000..7a218d00c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/address-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-down.svg new file mode 100644 index 000000000..5f7584886 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-left.svg new file mode 100644 index 000000000..eb3fbdb9f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-right.svg new file mode 100644 index 000000000..061d97266 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-up.svg new file mode 100644 index 000000000..519288e7a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/arrow-alt-circle-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell-slash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell-slash.svg new file mode 100644 index 000000000..de485f872 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell.svg new file mode 100644 index 000000000..0a22fd3bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bell.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bookmark.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bookmark.svg new file mode 100644 index 000000000..bd315e488 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/building.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/building.svg new file mode 100644 index 000000000..4178db461 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/building.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-alt.svg new file mode 100644 index 000000000..130e2ab70 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-check.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-check.svg new file mode 100644 index 000000000..3d98c5637 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-minus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-minus.svg new file mode 100644 index 000000000..0b83b3487 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-minus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-plus.svg new file mode 100644 index 000000000..7715ffc40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-times.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-times.svg new file mode 100644 index 000000000..8a9a10c77 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar-times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar.svg new file mode 100644 index 000000000..725e88798 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/calendar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-down.svg new file mode 100644 index 000000000..29a40ab91 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-left.svg new file mode 100644 index 000000000..5fa7f8b01 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-right.svg new file mode 100644 index 000000000..03b438973 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-up.svg new file mode 100644 index 000000000..b59f23b38 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/caret-square-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/chart-bar.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/chart-bar.svg new file mode 100644 index 000000000..a2bb019cf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/chart-bar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-circle.svg new file mode 100644 index 000000000..000b850f9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-square.svg new file mode 100644 index 000000000..602b375b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/check-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/circle.svg new file mode 100644 index 000000000..835815e17 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clipboard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clipboard.svg new file mode 100644 index 000000000..f339c1f55 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clock.svg new file mode 100644 index 000000000..136a550aa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clone.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clone.svg new file mode 100644 index 000000000..c9804bf33 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/clone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/closed-captioning.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/closed-captioning.svg new file mode 100644 index 000000000..277952b0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/closed-captioning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment-alt.svg new file mode 100644 index 000000000..b31f27b57 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment.svg new file mode 100644 index 000000000..8a1e836b2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comment.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comments.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comments.svg new file mode 100644 index 000000000..fc8d9cf93 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/comments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/compass.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/compass.svg new file mode 100644 index 000000000..6a5cf4475 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/compass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copy.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copy.svg new file mode 100644 index 000000000..a488ff2c8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copyright.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copyright.svg new file mode 100644 index 000000000..2a81ca28a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/copyright.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/credit-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/credit-card.svg new file mode 100644 index 000000000..f5a047fb0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/credit-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/dot-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/dot-circle.svg new file mode 100644 index 000000000..eacf9b700 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/dot-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/edit.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/edit.svg new file mode 100644 index 000000000..d7b191461 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope-open.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope-open.svg new file mode 100644 index 000000000..0b71db8f8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope.svg new file mode 100644 index 000000000..a2557ef20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/eye-slash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/eye-slash.svg new file mode 100644 index 000000000..3548435f9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/eye-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-alt.svg new file mode 100644 index 000000000..e32217d20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-archive.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-archive.svg new file mode 100644 index 000000000..f9af993a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-audio.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-audio.svg new file mode 100644 index 000000000..87c16005c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-audio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-code.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-code.svg new file mode 100644 index 000000000..86c276872 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-excel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-excel.svg new file mode 100644 index 000000000..481230270 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-image.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-image.svg new file mode 100644 index 000000000..2ca87e5c8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-pdf.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-pdf.svg new file mode 100644 index 000000000..3f2fa4532 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-powerpoint.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-powerpoint.svg new file mode 100644 index 000000000..41e3505b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-powerpoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-video.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-video.svg new file mode 100644 index 000000000..ed02cdc11 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-word.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-word.svg new file mode 100644 index 000000000..2ba499007 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file-word.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file.svg new file mode 100644 index 000000000..9bc15133e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/flag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/flag.svg new file mode 100644 index 000000000..4df2e03fd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/flag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder-open.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder-open.svg new file mode 100644 index 000000000..5a32ec781 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder.svg new file mode 100644 index 000000000..5cfb40903 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/frown.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/frown.svg new file mode 100644 index 000000000..d2240d27c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/frown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/futbol.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/futbol.svg new file mode 100644 index 000000000..3fa2aec2b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/futbol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/gem.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/gem.svg new file mode 100644 index 000000000..9640cbf9f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/gem.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-lizard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-lizard.svg new file mode 100644 index 000000000..6dba7ecf1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-lizard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-paper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-paper.svg new file mode 100644 index 000000000..afe7adb0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-paper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-peace.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-peace.svg new file mode 100644 index 000000000..506209b2a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-peace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-down.svg new file mode 100644 index 000000000..08bc8d848 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-left.svg new file mode 100644 index 000000000..82d664039 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-right.svg new file mode 100644 index 000000000..312c20933 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-up.svg new file mode 100644 index 000000000..6f823c30e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-point-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-pointer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-pointer.svg new file mode 100644 index 000000000..1ff0b8eb0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-pointer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-rock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-rock.svg new file mode 100644 index 000000000..a13011abf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-rock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-scissors.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-scissors.svg new file mode 100644 index 000000000..3e0b478f2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-scissors.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-spock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-spock.svg new file mode 100644 index 000000000..100466704 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hand-spock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/handshake.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/handshake.svg new file mode 100644 index 000000000..aaa0b7529 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/handshake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hdd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hdd.svg new file mode 100644 index 000000000..dbf616fee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hdd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/heart.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/heart.svg new file mode 100644 index 000000000..23d9ea0a1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/heart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hospital.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hospital.svg new file mode 100644 index 000000000..987728637 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hospital.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hourglass.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hourglass.svg new file mode 100644 index 000000000..c89faa1df --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/hourglass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-badge.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-badge.svg new file mode 100644 index 000000000..9babca9d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-badge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-card.svg new file mode 100644 index 000000000..b356b822e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/id-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/image.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/image.svg new file mode 100644 index 000000000..4f7dd8dd4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/images.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/images.svg new file mode 100644 index 000000000..2371a0859 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/images.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/keyboard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/keyboard.svg new file mode 100644 index 000000000..3b3705dcb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lemon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lemon.svg new file mode 100644 index 000000000..ab9ed90b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lemon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/life-ring.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/life-ring.svg new file mode 100644 index 000000000..2cf332681 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/life-ring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lightbulb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lightbulb.svg new file mode 100644 index 000000000..0cd414e1d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/lightbulb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/list-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/list-alt.svg new file mode 100644 index 000000000..1113bbcca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/list-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/map.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/map.svg new file mode 100644 index 000000000..04bd06c74 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/meh.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/meh.svg new file mode 100644 index 000000000..896ab9e8a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/meh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/minus-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/minus-square.svg new file mode 100644 index 000000000..6b72714ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/minus-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/money-bill-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/money-bill-alt.svg new file mode 100644 index 000000000..82b1b43ee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/money-bill-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/moon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/moon.svg new file mode 100644 index 000000000..30fb1151e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/newspaper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/newspaper.svg new file mode 100644 index 000000000..a54e3ca58 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/newspaper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-group.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-group.svg new file mode 100644 index 000000000..e483f376e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-ungroup.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-ungroup.svg new file mode 100644 index 000000000..625536303 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/object-ungroup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/paper-plane.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/paper-plane.svg new file mode 100644 index 000000000..215e29334 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/paper-plane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/pause-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/pause-circle.svg new file mode 100644 index 000000000..caebd9e96 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/pause-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/play-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/play-circle.svg new file mode 100644 index 000000000..9de60df95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/play-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/plus-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/plus-square.svg new file mode 100644 index 000000000..dfc22ac64 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/plus-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/question-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/question-circle.svg new file mode 100644 index 000000000..9a30b85d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/question-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/registered.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/registered.svg new file mode 100644 index 000000000..e5dc8a20b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/registered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/save.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/save.svg new file mode 100644 index 000000000..16f6b8295 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/share-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/share-square.svg new file mode 100644 index 000000000..aa9874881 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/share-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/smile.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/smile.svg new file mode 100644 index 000000000..2a02d8723 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/smile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/snowflake.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/snowflake.svg new file mode 100644 index 000000000..ba12375bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/snowflake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/square.svg new file mode 100644 index 000000000..b9a4b9620 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star-half.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star-half.svg new file mode 100644 index 000000000..12b063fd1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star-half.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star.svg new file mode 100644 index 000000000..a1370d23f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sticky-note.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sticky-note.svg new file mode 100644 index 000000000..0882390c7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sticky-note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/stop-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/stop-circle.svg new file mode 100644 index 000000000..37bf314d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/stop-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sun.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sun.svg new file mode 100644 index 000000000..72988fdf1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/sun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-down.svg new file mode 100644 index 000000000..d7b49d534 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-up.svg new file mode 100644 index 000000000..f60e4d116 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/times-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/times-circle.svg new file mode 100644 index 000000000..15181d341 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/times-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/trash-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/trash-alt.svg new file mode 100644 index 000000000..8885ef0c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/trash-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user-circle.svg new file mode 100644 index 000000000..ced04d06d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user.svg new file mode 100644 index 000000000..65f4eaf06 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-close.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-close.svg new file mode 100644 index 000000000..137598556 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-maximize.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-maximize.svg new file mode 100644 index 000000000..39c0ac06a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-maximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-restore.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-restore.svg new file mode 100644 index 000000000..9d1bfa7b5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/regular/window-restore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-book.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-book.svg new file mode 100644 index 000000000..abc9edf9a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-card.svg new file mode 100644 index 000000000..af593022b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/address-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/adjust.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/adjust.svg new file mode 100644 index 000000000..2616d99a9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/adjust.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-center.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-center.svg new file mode 100644 index 000000000..f6efd66a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-center.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-justify.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-justify.svg new file mode 100644 index 000000000..ff8ecf90a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-justify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-left.svg new file mode 100644 index 000000000..708e49d6c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-right.svg new file mode 100644 index 000000000..1a1c204fb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/align-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ambulance.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ambulance.svg new file mode 100644 index 000000000..7091ec3f1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ambulance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/american-sign-language-interpreting.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/american-sign-language-interpreting.svg new file mode 100644 index 000000000..8bca61450 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/american-sign-language-interpreting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/anchor.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/anchor.svg new file mode 100644 index 000000000..792266ba8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/anchor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-down.svg new file mode 100644 index 000000000..3228f4abc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-left.svg new file mode 100644 index 000000000..4474d83e2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-right.svg new file mode 100644 index 000000000..cdf933666 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-up.svg new file mode 100644 index 000000000..74b542f65 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-double-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-down.svg new file mode 100644 index 000000000..146234252 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-left.svg new file mode 100644 index 000000000..1e28c704d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-right.svg new file mode 100644 index 000000000..ec7fbe9f0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-up.svg new file mode 100644 index 000000000..1d0bbead7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/angle-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/archive.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/archive.svg new file mode 100644 index 000000000..d5506e531 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-down.svg new file mode 100644 index 000000000..a2f644f8f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-left.svg new file mode 100644 index 000000000..8a53b2265 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-right.svg new file mode 100644 index 000000000..9da44be87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-up.svg new file mode 100644 index 000000000..c650c8267 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-alt-circle-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-down.svg new file mode 100644 index 000000000..08b9f13ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-left.svg new file mode 100644 index 000000000..59be8d9e3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-right.svg new file mode 100644 index 000000000..f059bab95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-up.svg new file mode 100644 index 000000000..d9d8081c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-circle-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-down.svg new file mode 100644 index 000000000..61b4db70f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-left.svg new file mode 100644 index 000000000..b229b8d13 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-right.svg new file mode 100644 index 000000000..1b9b05b47 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-up.svg new file mode 100644 index 000000000..bc571b5d9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrow-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-h.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-h.svg new file mode 100644 index 000000000..0caa926d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-h.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-v.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-v.svg new file mode 100644 index 000000000..ebb23acbd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt-v.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt.svg new file mode 100644 index 000000000..d885a5a68 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/arrows-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/assistive-listening-systems.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/assistive-listening-systems.svg new file mode 100644 index 000000000..5071f5967 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/assistive-listening-systems.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/asterisk.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/asterisk.svg new file mode 100644 index 000000000..d77cbb6b6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/asterisk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/at.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/at.svg new file mode 100644 index 000000000..6f35c426b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/at.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/audio-description.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/audio-description.svg new file mode 100644 index 000000000..0e338ff6d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/audio-description.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/backward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/backward.svg new file mode 100644 index 000000000..b37fcc22f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/backward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/balance-scale.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/balance-scale.svg new file mode 100644 index 000000000..f73485de6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/balance-scale.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ban.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ban.svg new file mode 100644 index 000000000..85f7f06f1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ban.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/barcode.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/barcode.svg new file mode 100644 index 000000000..58cbee7de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/barcode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bars.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bars.svg new file mode 100644 index 000000000..87d79f9ee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bath.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bath.svg new file mode 100644 index 000000000..fef517b2e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bath.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-empty.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-empty.svg new file mode 100644 index 000000000..b4a57fac9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-full.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-full.svg new file mode 100644 index 000000000..056b8189a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-half.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-half.svg new file mode 100644 index 000000000..16a8fc339 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-half.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-quarter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-quarter.svg new file mode 100644 index 000000000..d48ca28ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-quarter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-three-quarters.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-three-quarters.svg new file mode 100644 index 000000000..43fc35adf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/battery-three-quarters.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bed.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bed.svg new file mode 100644 index 000000000..9af828caa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/beer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/beer.svg new file mode 100644 index 000000000..692431b18 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/beer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell-slash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell-slash.svg new file mode 100644 index 000000000..c69f3105f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell.svg new file mode 100644 index 000000000..40552fba3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bell.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bicycle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bicycle.svg new file mode 100644 index 000000000..4ef7ded2d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bicycle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/binoculars.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/binoculars.svg new file mode 100644 index 000000000..0aa5fb1c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/binoculars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/birthday-cake.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/birthday-cake.svg new file mode 100644 index 000000000..50e92ae4f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/birthday-cake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/blind.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/blind.svg new file mode 100644 index 000000000..b1eddadfd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/blind.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bold.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bold.svg new file mode 100644 index 000000000..045e7fb0f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bold.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bolt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bolt.svg new file mode 100644 index 000000000..4d079451d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bolt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bomb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bomb.svg new file mode 100644 index 000000000..d7a56f2b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bomb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/book.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/book.svg new file mode 100644 index 000000000..d27fdae79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bookmark.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bookmark.svg new file mode 100644 index 000000000..d1c8e4a20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/braille.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/braille.svg new file mode 100644 index 000000000..08f034ffa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/braille.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/briefcase.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/briefcase.svg new file mode 100644 index 000000000..5bb9051a6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/briefcase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bug.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bug.svg new file mode 100644 index 000000000..b9185530a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/building.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/building.svg new file mode 100644 index 000000000..a109377bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/building.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullhorn.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullhorn.svg new file mode 100644 index 000000000..5f7316044 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullhorn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullseye.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullseye.svg new file mode 100644 index 000000000..774ec2d11 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bullseye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bus.svg new file mode 100644 index 000000000..8c2fa16a1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/bus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calculator.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calculator.svg new file mode 100644 index 000000000..cb402c8d7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calculator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-alt.svg new file mode 100644 index 000000000..35d6c7166 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-check.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-check.svg new file mode 100644 index 000000000..35b590d02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-minus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-minus.svg new file mode 100644 index 000000000..78b8a3c07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-minus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-plus.svg new file mode 100644 index 000000000..5e1b33825 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-times.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-times.svg new file mode 100644 index 000000000..4db39b2d8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar-times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar.svg new file mode 100644 index 000000000..2d3eefe8d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/calendar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera-retro.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera-retro.svg new file mode 100644 index 000000000..67b7cfd54 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera-retro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera.svg new file mode 100644 index 000000000..dc9f60813 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/camera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/car.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/car.svg new file mode 100644 index 000000000..bcf0e443c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/car.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-down.svg new file mode 100644 index 000000000..b3ee2ea95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-left.svg new file mode 100644 index 000000000..36d7191ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-right.svg new file mode 100644 index 000000000..bcd4cd106 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-down.svg new file mode 100644 index 000000000..87a4f7a05 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-left.svg new file mode 100644 index 000000000..856dcac95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-right.svg new file mode 100644 index 000000000..d69ec9fd4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-up.svg new file mode 100644 index 000000000..005ea2c06 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-square-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-up.svg new file mode 100644 index 000000000..b4c7e5485 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/caret-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-arrow-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-arrow-down.svg new file mode 100644 index 000000000..69e39712a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-arrow-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-plus.svg new file mode 100644 index 000000000..7f5ab7f52 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cart-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/certificate.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/certificate.svg new file mode 100644 index 000000000..c57ab137a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/certificate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-area.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-area.svg new file mode 100644 index 000000000..47c886290 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-area.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-bar.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-bar.svg new file mode 100644 index 000000000..13ee32a01 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-bar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-line.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-line.svg new file mode 100644 index 000000000..e27e5e091 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-pie.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-pie.svg new file mode 100644 index 000000000..c2daf275e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chart-pie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-circle.svg new file mode 100644 index 000000000..a1dfc7757 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-square.svg new file mode 100644 index 000000000..4ea6964af --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check.svg new file mode 100644 index 000000000..2ec27cf84 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-down.svg new file mode 100644 index 000000000..4be7cea6f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-left.svg new file mode 100644 index 000000000..60b5ac6ec --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-right.svg new file mode 100644 index 000000000..93350ee73 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-up.svg new file mode 100644 index 000000000..d973a5dfa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-circle-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-down.svg new file mode 100644 index 000000000..5962e8933 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-left.svg new file mode 100644 index 000000000..c2dcbcca9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-right.svg new file mode 100644 index 000000000..6d3e119b8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-up.svg new file mode 100644 index 000000000..a38c372ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/chevron-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/child.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/child.svg new file mode 100644 index 000000000..8bbc718b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/child.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle-notch.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle-notch.svg new file mode 100644 index 000000000..3cc8c0b5d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle-notch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle.svg new file mode 100644 index 000000000..c2db0b25c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clipboard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clipboard.svg new file mode 100644 index 000000000..1980a2bf1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clock.svg new file mode 100644 index 000000000..6444d5b9b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clone.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clone.svg new file mode 100644 index 000000000..0f40db074 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/clone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/closed-captioning.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/closed-captioning.svg new file mode 100644 index 000000000..f0c68d043 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/closed-captioning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-download-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-download-alt.svg new file mode 100644 index 000000000..7cc2657ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-download-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-upload-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-upload-alt.svg new file mode 100644 index 000000000..1b11389d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud-upload-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud.svg new file mode 100644 index 000000000..566d5a60d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code-branch.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code-branch.svg new file mode 100644 index 000000000..0f33c5c50 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code-branch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code.svg new file mode 100644 index 000000000..ea8da707c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/coffee.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/coffee.svg new file mode 100644 index 000000000..af4c02477 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/coffee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cog.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cog.svg new file mode 100644 index 000000000..cc178ceb5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cogs.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cogs.svg new file mode 100644 index 000000000..c016886e0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cogs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/columns.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/columns.svg new file mode 100644 index 000000000..84ec2a09e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/columns.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment-alt.svg new file mode 100644 index 000000000..6f9f80b60 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment.svg new file mode 100644 index 000000000..0a1c498a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comment.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comments.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comments.svg new file mode 100644 index 000000000..f6087bcde --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/comments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compass.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compass.svg new file mode 100644 index 000000000..dd9dc5b19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compress.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compress.svg new file mode 100644 index 000000000..f2faafbfd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/compress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copy.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copy.svg new file mode 100644 index 000000000..02534e7ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copyright.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copyright.svg new file mode 100644 index 000000000..eb5d4c61b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/copyright.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/credit-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/credit-card.svg new file mode 100644 index 000000000..676d35868 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/credit-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crop.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crop.svg new file mode 100644 index 000000000..18d6d6b83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crosshairs.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crosshairs.svg new file mode 100644 index 000000000..60acd3e28 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/crosshairs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cube.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cube.svg new file mode 100644 index 000000000..a627fd549 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cubes.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cubes.svg new file mode 100644 index 000000000..208f688a3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cubes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cut.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cut.svg new file mode 100644 index 000000000..841d17ca3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/cut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/database.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/database.svg new file mode 100644 index 000000000..a6e4982bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/database.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/deaf.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/deaf.svg new file mode 100644 index 000000000..25a7a86ec --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/deaf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/desktop.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/desktop.svg new file mode 100644 index 000000000..bba157e80 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/desktop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dollar-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dollar-sign.svg new file mode 100644 index 000000000..1d0685ad8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dollar-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dot-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dot-circle.svg new file mode 100644 index 000000000..5cb222ddd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/dot-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/download.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/download.svg new file mode 100644 index 000000000..da5eec408 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/edit.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/edit.svg new file mode 100644 index 000000000..2313feb19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eject.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eject.svg new file mode 100644 index 000000000..d240b0d1b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eject.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-h.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-h.svg new file mode 100644 index 000000000..70748ad95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-h.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-v.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-v.svg new file mode 100644 index 000000000..e8e713ad4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ellipsis-v.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-open.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-open.svg new file mode 100644 index 000000000..947ae25a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-square.svg new file mode 100644 index 000000000..c35055f9c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope.svg new file mode 100644 index 000000000..edbcad3de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eraser.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eraser.svg new file mode 100644 index 000000000..1ba581e7c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eraser.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/euro-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/euro-sign.svg new file mode 100644 index 000000000..fd18c90de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/euro-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exchange-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exchange-alt.svg new file mode 100644 index 000000000..b22538a9e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exchange-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-circle.svg new file mode 100644 index 000000000..165930398 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-triangle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-triangle.svg new file mode 100644 index 000000000..2ab53271b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation-triangle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation.svg new file mode 100644 index 000000000..89ef11a7a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/exclamation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand-arrows-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand-arrows-alt.svg new file mode 100644 index 000000000..365df17cb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand-arrows-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand.svg new file mode 100644 index 000000000..e8f812d47 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/expand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-alt.svg new file mode 100644 index 000000000..cf8f0b6ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-square-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-square-alt.svg new file mode 100644 index 000000000..099977be4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/external-link-square-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-dropper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-dropper.svg new file mode 100644 index 000000000..130172765 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-dropper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-slash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-slash.svg new file mode 100644 index 000000000..d6de57e23 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye.svg new file mode 100644 index 000000000..6a0a503af --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-backward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-backward.svg new file mode 100644 index 000000000..dfe10e5c5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-backward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-forward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-forward.svg new file mode 100644 index 000000000..57c072ae1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fast-forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fax.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fax.svg new file mode 100644 index 000000000..cbc63f3d9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fax.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/female.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/female.svg new file mode 100644 index 000000000..9bfc7ad6c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/female.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fighter-jet.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fighter-jet.svg new file mode 100644 index 000000000..3fdfe2d8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fighter-jet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-alt.svg new file mode 100644 index 000000000..e1f980c87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-archive.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-archive.svg new file mode 100644 index 000000000..ad41f1354 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-audio.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-audio.svg new file mode 100644 index 000000000..c491a45a4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-audio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-code.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-code.svg new file mode 100644 index 000000000..4036f537f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-excel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-excel.svg new file mode 100644 index 000000000..62cec9dd2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-image.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-image.svg new file mode 100644 index 000000000..6c87c8cf1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-pdf.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-pdf.svg new file mode 100644 index 000000000..9782667d5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-powerpoint.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-powerpoint.svg new file mode 100644 index 000000000..bd26fb923 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-powerpoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-video.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-video.svg new file mode 100644 index 000000000..8de9f6cf6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-word.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-word.svg new file mode 100644 index 000000000..f484a94cc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file-word.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file.svg new file mode 100644 index 000000000..7f495dcef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/film.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/film.svg new file mode 100644 index 000000000..f120aee23 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/film.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/filter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/filter.svg new file mode 100644 index 000000000..95861a392 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire-extinguisher.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire-extinguisher.svg new file mode 100644 index 000000000..2bd873807 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire-extinguisher.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire.svg new file mode 100644 index 000000000..27eb73adb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/fire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag-checkered.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag-checkered.svg new file mode 100644 index 000000000..2074db3fe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag-checkered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag.svg new file mode 100644 index 000000000..eb95c9ca8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flask.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flask.svg new file mode 100644 index 000000000..c30929ace --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/flask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder-open.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder-open.svg new file mode 100644 index 000000000..57dcfa604 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder.svg new file mode 100644 index 000000000..c9607689a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/font.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/font.svg new file mode 100644 index 000000000..adcc3d329 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/font.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/forward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/forward.svg new file mode 100644 index 000000000..5349d49fb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/frown.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/frown.svg new file mode 100644 index 000000000..1ac8aafd4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/frown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/futbol.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/futbol.svg new file mode 100644 index 000000000..936fcad2e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/futbol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gamepad.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gamepad.svg new file mode 100644 index 000000000..047a5a373 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gamepad.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gavel.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gavel.svg new file mode 100644 index 000000000..c68ac7c38 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gavel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gem.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gem.svg new file mode 100644 index 000000000..6172b8711 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gem.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/genderless.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/genderless.svg new file mode 100644 index 000000000..9c9286734 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/genderless.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gift.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gift.svg new file mode 100644 index 000000000..f372f9543 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/gift.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/glass-martini.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/glass-martini.svg new file mode 100644 index 000000000..f846c40ec --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/glass-martini.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/globe.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/globe.svg new file mode 100644 index 000000000..cab36f576 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/graduation-cap.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/graduation-cap.svg new file mode 100644 index 000000000..090ad8fb7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/graduation-cap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/h-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/h-square.svg new file mode 100644 index 000000000..0b85e2856 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/h-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-lizard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-lizard.svg new file mode 100644 index 000000000..6d27f0adf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-lizard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-paper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-paper.svg new file mode 100644 index 000000000..f4aadf12d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-paper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-peace.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-peace.svg new file mode 100644 index 000000000..8ed4eede1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-peace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-down.svg new file mode 100644 index 000000000..3facac8c5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-left.svg new file mode 100644 index 000000000..4a5ee96dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-right.svg new file mode 100644 index 000000000..a20ce998d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-up.svg new file mode 100644 index 000000000..c9668f228 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-point-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-pointer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-pointer.svg new file mode 100644 index 000000000..e1367b6c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-pointer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-rock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-rock.svg new file mode 100644 index 000000000..abd9939a3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-rock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-scissors.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-scissors.svg new file mode 100644 index 000000000..a5996614a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-scissors.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-spock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-spock.svg new file mode 100644 index 000000000..fbd12105c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hand-spock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/handshake.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/handshake.svg new file mode 100644 index 000000000..da6e2cf24 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/handshake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hashtag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hashtag.svg new file mode 100644 index 000000000..2a6094fe1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hashtag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hdd.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hdd.svg new file mode 100644 index 000000000..cead9cff5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hdd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heading.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heading.svg new file mode 100644 index 000000000..a482da135 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heading.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/headphones.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/headphones.svg new file mode 100644 index 000000000..c97cde6a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/headphones.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heart.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heart.svg new file mode 100644 index 000000000..d85320270 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heartbeat.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heartbeat.svg new file mode 100644 index 000000000..6a07ded63 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/heartbeat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/history.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/history.svg new file mode 100644 index 000000000..8157c3131 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/home.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/home.svg new file mode 100644 index 000000000..55e9e1cc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hospital.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hospital.svg new file mode 100644 index 000000000..5b6c7b456 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hospital.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-end.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-end.svg new file mode 100644 index 000000000..4773ce654 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-end.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-half.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-half.svg new file mode 100644 index 000000000..adf6f26de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-half.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-start.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-start.svg new file mode 100644 index 000000000..214b6c71c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass-start.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass.svg new file mode 100644 index 000000000..cd6052ce9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/hourglass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/i-cursor.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/i-cursor.svg new file mode 100644 index 000000000..2367160dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/i-cursor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-badge.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-badge.svg new file mode 100644 index 000000000..58a617a87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-badge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-card.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-card.svg new file mode 100644 index 000000000..a563d4db8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/id-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/image.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/image.svg new file mode 100644 index 000000000..dbf552dab --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/images.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/images.svg new file mode 100644 index 000000000..efd28e2ac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/images.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/inbox.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/inbox.svg new file mode 100644 index 000000000..761d6c7b5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/inbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/indent.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/indent.svg new file mode 100644 index 000000000..b960bc831 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/indent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/industry.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/industry.svg new file mode 100644 index 000000000..c04e11ac1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/industry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info-circle.svg new file mode 100644 index 000000000..a25c1632d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info.svg new file mode 100644 index 000000000..e6b9c3f6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/italic.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/italic.svg new file mode 100644 index 000000000..d63a32b8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/italic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/key.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/key.svg new file mode 100644 index 000000000..e0bd4948a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/keyboard.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/keyboard.svg new file mode 100644 index 000000000..12686637f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/language.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/language.svg new file mode 100644 index 000000000..eb6ac62a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/laptop.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/laptop.svg new file mode 100644 index 000000000..484e1de27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/laptop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/leaf.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/leaf.svg new file mode 100644 index 000000000..3996d626d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/leaf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lemon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lemon.svg new file mode 100644 index 000000000..e8f98bd68 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lemon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-down-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-down-alt.svg new file mode 100644 index 000000000..523508722 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-down-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-up-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-up-alt.svg new file mode 100644 index 000000000..a9672eb40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/level-up-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/life-ring.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/life-ring.svg new file mode 100644 index 000000000..da06ef464 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/life-ring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lightbulb.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lightbulb.svg new file mode 100644 index 000000000..b3a769375 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lightbulb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/link.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/link.svg new file mode 100644 index 000000000..57caa9ffd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lira-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lira-sign.svg new file mode 100644 index 000000000..802a0f519 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lira-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-alt.svg new file mode 100644 index 000000000..5e32557c2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ol.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ol.svg new file mode 100644 index 000000000..693439bd7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ul.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ul.svg new file mode 100644 index 000000000..a5851661c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list-ul.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list.svg new file mode 100644 index 000000000..3a7da9259 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/location-arrow.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/location-arrow.svg new file mode 100644 index 000000000..1d4d95f6b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/location-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock-open.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock-open.svg new file mode 100644 index 000000000..7f949963a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock.svg new file mode 100644 index 000000000..7d0e70bdc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-down.svg new file mode 100644 index 000000000..75e69e79b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-left.svg new file mode 100644 index 000000000..b9e103b3d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-right.svg new file mode 100644 index 000000000..2f388d537 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-up.svg new file mode 100644 index 000000000..cdd5dcf7b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/long-arrow-alt-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/low-vision.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/low-vision.svg new file mode 100644 index 000000000..5b82a1bdb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/low-vision.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magic.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magic.svg new file mode 100644 index 000000000..8470cb119 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magnet.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magnet.svg new file mode 100644 index 000000000..d83f6b33d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/magnet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/male.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/male.svg new file mode 100644 index 000000000..b41d026f3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/male.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker-alt.svg new file mode 100644 index 000000000..d3d94f03a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker.svg new file mode 100644 index 000000000..c2047c7ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-marker.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-pin.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-pin.svg new file mode 100644 index 000000000..7d3bef3e0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-pin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-signs.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-signs.svg new file mode 100644 index 000000000..c9274f4fa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map-signs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map.svg new file mode 100644 index 000000000..2d8316193 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-double.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-double.svg new file mode 100644 index 000000000..49a76e073 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-double.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-h.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-h.svg new file mode 100644 index 000000000..32ea3f52e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-h.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-v.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-v.svg new file mode 100644 index 000000000..e3c03aace --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke-v.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke.svg new file mode 100644 index 000000000..076d1e6d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars-stroke.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars.svg new file mode 100644 index 000000000..022f88d00 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/medkit.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/medkit.svg new file mode 100644 index 000000000..637d38e9f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/medkit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/meh.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/meh.svg new file mode 100644 index 000000000..665080df0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/meh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mercury.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mercury.svg new file mode 100644 index 000000000..a93041587 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mercury.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microchip.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microchip.svg new file mode 100644 index 000000000..4eb7e2d51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microchip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone-slash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone-slash.svg new file mode 100644 index 000000000..947557a5d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone.svg new file mode 100644 index 000000000..4868fe7ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/microphone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-circle.svg new file mode 100644 index 000000000..efe6e46a3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-square.svg new file mode 100644 index 000000000..27ebb01cc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus.svg new file mode 100644 index 000000000..b82cfd8e9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/minus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile-alt.svg new file mode 100644 index 000000000..e8084596d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile.svg new file mode 100644 index 000000000..2783241d7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mobile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/money-bill-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/money-bill-alt.svg new file mode 100644 index 000000000..960e62225 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/money-bill-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/moon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/moon.svg new file mode 100644 index 000000000..b153f3445 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/motorcycle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/motorcycle.svg new file mode 100644 index 000000000..2dd789715 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/motorcycle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mouse-pointer.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mouse-pointer.svg new file mode 100644 index 000000000..c5f252d0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/mouse-pointer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/music.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/music.svg new file mode 100644 index 000000000..9fcc6eec2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/music.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/neuter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/neuter.svg new file mode 100644 index 000000000..cb7635d0f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/neuter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/newspaper.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/newspaper.svg new file mode 100644 index 000000000..477294260 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/newspaper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-group.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-group.svg new file mode 100644 index 000000000..b07fcecf7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-ungroup.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-ungroup.svg new file mode 100644 index 000000000..4c29c1e2a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/object-ungroup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/outdent.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/outdent.svg new file mode 100644 index 000000000..f5267d1d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/outdent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paint-brush.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paint-brush.svg new file mode 100644 index 000000000..d2b43c009 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paint-brush.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paper-plane.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paper-plane.svg new file mode 100644 index 000000000..cecb40f27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paper-plane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paperclip.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paperclip.svg new file mode 100644 index 000000000..e2db0bf91 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paperclip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paragraph.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paragraph.svg new file mode 100644 index 000000000..a7462bf20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paragraph.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paste.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paste.svg new file mode 100644 index 000000000..1d49e2503 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause-circle.svg new file mode 100644 index 000000000..72a8e48c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause.svg new file mode 100644 index 000000000..63a15b6ee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paw.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paw.svg new file mode 100644 index 000000000..3fa9e2f2e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/paw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pen-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pen-square.svg new file mode 100644 index 000000000..0f30e05fd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pen-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pencil-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pencil-alt.svg new file mode 100644 index 000000000..26d7daeac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pencil-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/percent.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/percent.svg new file mode 100644 index 000000000..4b1a8ff63 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/percent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-square.svg new file mode 100644 index 000000000..39ed96930 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-volume.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-volume.svg new file mode 100644 index 000000000..872d95d1e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone-volume.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone.svg new file mode 100644 index 000000000..d7d673f1f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plane.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plane.svg new file mode 100644 index 000000000..36a360c8a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plane.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play-circle.svg new file mode 100644 index 000000000..ea1039704 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play.svg new file mode 100644 index 000000000..d7fa87f32 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plug.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plug.svg new file mode 100644 index 000000000..0082e8ada --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-circle.svg new file mode 100644 index 000000000..f7a138c6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-square.svg new file mode 100644 index 000000000..ff058b572 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus.svg new file mode 100644 index 000000000..0023570fd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/podcast.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/podcast.svg new file mode 100644 index 000000000..9ee3b6fad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/podcast.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pound-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pound-sign.svg new file mode 100644 index 000000000..8705075f9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/pound-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/power-off.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/power-off.svg new file mode 100644 index 000000000..371131806 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/power-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/print.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/print.svg new file mode 100644 index 000000000..2ac7d73a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/print.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/puzzle-piece.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/puzzle-piece.svg new file mode 100644 index 000000000..a632d8a92 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/puzzle-piece.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/qrcode.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/qrcode.svg new file mode 100644 index 000000000..c92fa7caa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/qrcode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question-circle.svg new file mode 100644 index 000000000..a8f424362 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question.svg new file mode 100644 index 000000000..065e9fe73 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-left.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-left.svg new file mode 100644 index 000000000..074b1a60f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-right.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-right.svg new file mode 100644 index 000000000..820d14653 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/quote-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/random.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/random.svg new file mode 100644 index 000000000..3c23b13ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/random.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/recycle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/recycle.svg new file mode 100644 index 000000000..1c7fa7166 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/recycle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo-alt.svg new file mode 100644 index 000000000..f014834d5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo.svg new file mode 100644 index 000000000..c536b3704 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/redo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/registered.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/registered.svg new file mode 100644 index 000000000..115cc7043 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/registered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply-all.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply-all.svg new file mode 100644 index 000000000..32886acb2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply-all.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply.svg new file mode 100644 index 000000000..50f99ff05 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/reply.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/retweet.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/retweet.svg new file mode 100644 index 000000000..6c8111bc6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/retweet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/road.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/road.svg new file mode 100644 index 000000000..5779c9a6d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/road.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rocket.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rocket.svg new file mode 100644 index 000000000..e835870c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rocket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss-square.svg new file mode 100644 index 000000000..ff9a15a63 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss.svg new file mode 100644 index 000000000..e6fa54c38 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ruble-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ruble-sign.svg new file mode 100644 index 000000000..50ec2f50b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ruble-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rupee-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rupee-sign.svg new file mode 100644 index 000000000..52e319ca1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/rupee-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/save.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/save.svg new file mode 100644 index 000000000..44298e3ec --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-minus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-minus.svg new file mode 100644 index 000000000..7befe08ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-minus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-plus.svg new file mode 100644 index 000000000..e4f5984b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search.svg new file mode 100644 index 000000000..865b962e2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/server.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/server.svg new file mode 100644 index 000000000..4e6c50fd4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt-square.svg new file mode 100644 index 000000000..7d48e4565 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt.svg new file mode 100644 index 000000000..2f3151dfa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-square.svg new file mode 100644 index 000000000..f66404d6f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share.svg new file mode 100644 index 000000000..e7e262b44 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shekel-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shekel-sign.svg new file mode 100644 index 000000000..916cc09b2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shekel-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shield-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shield-alt.svg new file mode 100644 index 000000000..f77d7ce3c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shield-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ship.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ship.svg new file mode 100644 index 000000000..61e031519 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ship.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-bag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-bag.svg new file mode 100644 index 000000000..78f8a425c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-bag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-basket.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-basket.svg new file mode 100644 index 000000000..6eef20e6a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-basket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-cart.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-cart.svg new file mode 100644 index 000000000..d409917d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shopping-cart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shower.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shower.svg new file mode 100644 index 000000000..66ccb5769 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/shower.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-in-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-in-alt.svg new file mode 100644 index 000000000..5b235c0cf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-in-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-language.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-language.svg new file mode 100644 index 000000000..552cb4a60 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-out-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-out-alt.svg new file mode 100644 index 000000000..ca9853369 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sign-out-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/signal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/signal.svg new file mode 100644 index 000000000..3a74673d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/signal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sitemap.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sitemap.svg new file mode 100644 index 000000000..9ec921d07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sitemap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sliders-h.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sliders-h.svg new file mode 100644 index 000000000..1475f4658 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sliders-h.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/smile.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/smile.svg new file mode 100644 index 000000000..74993b7a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/smile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/snowflake.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/snowflake.svg new file mode 100644 index 000000000..7f5c4804e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/snowflake.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-down.svg new file mode 100644 index 000000000..a17a517bb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-up.svg new file mode 100644 index 000000000..caa561f8e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-alpha-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-down.svg new file mode 100644 index 000000000..0b7125430 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-up.svg new file mode 100644 index 000000000..21f42185f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-amount-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-down.svg new file mode 100644 index 000000000..2644ba2b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-down.svg new file mode 100644 index 000000000..ab9464c07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-up.svg new file mode 100644 index 000000000..1c783ae16 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-numeric-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-up.svg new file mode 100644 index 000000000..c6e1001d7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort.svg new file mode 100644 index 000000000..89c08354d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sort.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/space-shuttle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/space-shuttle.svg new file mode 100644 index 000000000..1cf024de7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/space-shuttle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/spinner.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/spinner.svg new file mode 100644 index 000000000..4397764e0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/spinner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/square.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/square.svg new file mode 100644 index 000000000..40338d449 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star-half.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star-half.svg new file mode 100644 index 000000000..6599dcbfa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star-half.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star.svg new file mode 100644 index 000000000..7cfd13b8a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-backward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-backward.svg new file mode 100644 index 000000000..e6f0d100e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-backward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-forward.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-forward.svg new file mode 100644 index 000000000..33eb8fb61 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/step-forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stethoscope.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stethoscope.svg new file mode 100644 index 000000000..8c3b1b388 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stethoscope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sticky-note.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sticky-note.svg new file mode 100644 index 000000000..4b577b881 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sticky-note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop-circle.svg new file mode 100644 index 000000000..15f56cdb8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop.svg new file mode 100644 index 000000000..40338d449 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/street-view.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/street-view.svg new file mode 100644 index 000000000..5aae1c779 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/street-view.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/strikethrough.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/strikethrough.svg new file mode 100644 index 000000000..07f78c108 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/strikethrough.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subscript.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subscript.svg new file mode 100644 index 000000000..dec0b74d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subscript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subway.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subway.svg new file mode 100644 index 000000000..19e5a3799 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/subway.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/suitcase.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/suitcase.svg new file mode 100644 index 000000000..d29bd8ed2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/suitcase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sun.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sun.svg new file mode 100644 index 000000000..cdb0728b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/superscript.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/superscript.svg new file mode 100644 index 000000000..0ff2b2356 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/superscript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync-alt.svg new file mode 100644 index 000000000..3c3106d84 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync.svg new file mode 100644 index 000000000..008de5983 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/sync.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/table.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/table.svg new file mode 100644 index 000000000..5690c5cc5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet-alt.svg new file mode 100644 index 000000000..9e962f783 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet.svg new file mode 100644 index 000000000..da45e7d21 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tablet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tachometer-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tachometer-alt.svg new file mode 100644 index 000000000..f2dadf106 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tachometer-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tag.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tag.svg new file mode 100644 index 000000000..6793a2e0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tags.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tags.svg new file mode 100644 index 000000000..192075b92 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tags.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tasks.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tasks.svg new file mode 100644 index 000000000..64e6c6d32 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tasks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/taxi.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/taxi.svg new file mode 100644 index 000000000..32e55259a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/taxi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/terminal.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/terminal.svg new file mode 100644 index 000000000..85b2b5e85 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/terminal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-height.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-height.svg new file mode 100644 index 000000000..c76e184d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-height.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-width.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-width.svg new file mode 100644 index 000000000..d555b9437 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/text-width.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-large.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-large.svg new file mode 100644 index 000000000..7894f58b4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-large.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-list.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-list.svg new file mode 100644 index 000000000..361af5425 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th-list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th.svg new file mode 100644 index 000000000..73b6c92c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/th.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-empty.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-empty.svg new file mode 100644 index 000000000..5a6a6b8e9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-full.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-full.svg new file mode 100644 index 000000000..caeb8b664 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-half.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-half.svg new file mode 100644 index 000000000..8c3551274 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-half.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-quarter.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-quarter.svg new file mode 100644 index 000000000..0478872ed --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-quarter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-three-quarters.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-three-quarters.svg new file mode 100644 index 000000000..b5188d58f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thermometer-three-quarters.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-down.svg new file mode 100644 index 000000000..4ceae379c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-up.svg new file mode 100644 index 000000000..6bbb650de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbtack.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbtack.svg new file mode 100644 index 000000000..7b98d281f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/thumbtack.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ticket-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ticket-alt.svg new file mode 100644 index 000000000..70158467d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/ticket-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times-circle.svg new file mode 100644 index 000000000..cdee94147 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times.svg new file mode 100644 index 000000000..02eef1b8f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tint.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tint.svg new file mode 100644 index 000000000..0ccf37b27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-off.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-off.svg new file mode 100644 index 000000000..dce9c007b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-on.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-on.svg new file mode 100644 index 000000000..d93153403 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/toggle-on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trademark.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trademark.svg new file mode 100644 index 000000000..0d5ba89a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trademark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/train.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/train.svg new file mode 100644 index 000000000..79c0266f2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/train.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender-alt.svg new file mode 100644 index 000000000..6c1d1679e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender.svg new file mode 100644 index 000000000..10d73936f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/transgender.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash-alt.svg new file mode 100644 index 000000000..a921fe8d7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash.svg new file mode 100644 index 000000000..a264b3deb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tree.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tree.svg new file mode 100644 index 000000000..f934701d2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trophy.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trophy.svg new file mode 100644 index 000000000..6157afa00 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/trophy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/truck.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/truck.svg new file mode 100644 index 000000000..ab9fa5992 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/truck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tty.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tty.svg new file mode 100644 index 000000000..acc1e3d35 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tv.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tv.svg new file mode 100644 index 000000000..95151f5a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/tv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/umbrella.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/umbrella.svg new file mode 100644 index 000000000..a096a1051 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/umbrella.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/underline.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/underline.svg new file mode 100644 index 000000000..751232d56 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/underline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo-alt.svg new file mode 100644 index 000000000..bdc97cae1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo.svg new file mode 100644 index 000000000..44b390412 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/undo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/universal-access.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/universal-access.svg new file mode 100644 index 000000000..1079d879b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/universal-access.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/university.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/university.svg new file mode 100644 index 000000000..21cc8f958 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/university.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlink.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlink.svg new file mode 100644 index 000000000..8cba9f8fe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlink.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock-alt.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock-alt.svg new file mode 100644 index 000000000..b38ffb6ac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock.svg new file mode 100644 index 000000000..0b2258a81 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/unlock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/upload.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/upload.svg new file mode 100644 index 000000000..1c880b516 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-circle.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-circle.svg new file mode 100644 index 000000000..4e6ee383f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-md.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-md.svg new file mode 100644 index 000000000..94312df02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-md.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-plus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-plus.svg new file mode 100644 index 000000000..c0d7e8e94 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-secret.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-secret.svg new file mode 100644 index 000000000..680450eb2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-secret.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-times.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-times.svg new file mode 100644 index 000000000..037112baa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user-times.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user.svg new file mode 100644 index 000000000..ff118622e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/users.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/users.svg new file mode 100644 index 000000000..44165efd9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/users.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensil-spoon.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensil-spoon.svg new file mode 100644 index 000000000..ec19dac55 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensil-spoon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensils.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensils.svg new file mode 100644 index 000000000..29fa05ab1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/utensils.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-double.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-double.svg new file mode 100644 index 000000000..8fa1ba94f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-double.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-mars.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-mars.svg new file mode 100644 index 000000000..78089d807 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus-mars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus.svg new file mode 100644 index 000000000..637ef0cc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/venus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/video.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/video.svg new file mode 100644 index 000000000..b4aa0684f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-down.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-down.svg new file mode 100644 index 000000000..130ece787 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-off.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-off.svg new file mode 100644 index 000000000..8369dfea4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-up.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-up.svg new file mode 100644 index 000000000..6c788ea68 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/volume-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wheelchair.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wheelchair.svg new file mode 100644 index 000000000..e474ae3fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wheelchair.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wifi.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wifi.svg new file mode 100644 index 000000000..efa235ad9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wifi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-close.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-close.svg new file mode 100644 index 000000000..da63df918 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-maximize.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-maximize.svg new file mode 100644 index 000000000..d305d0ad4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-maximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-minimize.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-minimize.svg new file mode 100644 index 000000000..c0e48b3f2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-minimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-restore.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-restore.svg new file mode 100644 index 000000000..355ce8f00 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/window-restore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/won-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/won-sign.svg new file mode 100644 index 000000000..376e8c7d4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/won-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wrench.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wrench.svg new file mode 100644 index 000000000..0d805b22e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/wrench.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/yen-sign.svg b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/yen-sign.svg new file mode 100644 index 000000000..7425a5086 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/raw-svg/solid/yen-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-brands.svg b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-brands.svg new file mode 100644 index 000000000..5bc1ba3bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-brands.svg @@ -0,0 +1,1286 @@ + + + + 500px + + + + Accessible Icon + + + + Accusoft + + + + App.net + + + + Adversal + + + + affiliatetheme + + + + Algolia + + + + Amazon + + + + Amilia + + + + Android + + + + AngelList + + + + Angry Creative + + + + Angular + + + + App Store + + + + iOS App Store + + + + Apper Systems AB + + + + Apple + + + + Apple Pay + + + + Asymmetrik, Ltd. + + + + Audible + + + + Autoprefixer + + + + avianex + + + + Aviato + + + + Amazon Web Services (AWS) + + + + Bandcamp + + + + Behance + + + + Behance Square + + + + BIMobject + + + + Bitbucket + + + + Bitcoin + + + + Bity + + + + Font Awesome Black Tie + + + + BlackBerry + + + + Blogger + + + + Blogger B + + + + Bluetooth + + + + Bluetooth + + + + BTC + + + + Büromöbel-Experte GmbH & Co. KG. + + + + BuySellAds + + + + American Express Credit Card + + + + Apple Pay Credit Card + + + + Diner's Club Credit Card + + + + Discover Credit Card + + + + JCB Credit Card + + + + MasterCard Credit Card + + + + Paypal Credit Card + + + + Stripe Credit Card + + + + Visa Credit Card + + + + Centercode + + + + Chrome + + + + cloudscale.ch + + + + Cloudsmith + + + + cloudversify + + + + Codepen + + + + Codie Pie + + + + Connect Develop + + + + Contao + + + + cPanel + + + + Creative Commons + + + + CSS 3 Logo + + + + Alternate CSS3 Logo + + + + Cuttlefish + + + + Dungeons & Dragons + + + + DashCube + + + + Delicious Logo + + + + deploy.dog + + + + Deskpro + + + + deviantART + + + + Digg Logo + + + + Digital Ocean + + + + Discord + + + + Discourse + + + + DocHub + + + + Docker + + + + Draft2digital + + + + Dribbble + + + + Dribbble Square + + + + Dropbox + + + + Drupal Logo + + + + Dyalog + + + + Earlybirds + + + + Edge Browser + + + + Ember + + + + Galactic Empire + + + + Envira Gallery + + + + Erlang + + + + Etsy + + + + ExpeditedSSL + + + + Facebook + + + + Facebook F + + + + Facebook Messenger + + + + Facebook Square + + + + Firefox + + + + First Order + + + + firstdraft + + + + Flickr + + + + Fly + + + + Font Awesome + + + + Alternate Font Awesome + + + + Font Awesome Flag + + + + Fonticons + + + + Fonticons Fi + + + + Fort Awesome + + + + Alternate Fort Awesome + + + + Forumbee + + + + Foursquare + + + + Free Code Camp + + + + FreeBSD + + + + Get Pocket + + + + GG Currency + + + + GG Currency Circle + + + + Git + + + + Git Square + + + + GitHub + + + + Alternate GitHub + + + + GitHub Square + + + + GitKraken + + + + GitLab + + + + Gitter + + + + Glide + + + + Glide G + + + + Gofore + + + + Goodreads + + + + Goodreads G + + + + Google Logo + + + + Google Drive + + + + Google Play + + + + Google Plus + + + + Google Plus G + + + + Google Plus Square + + + + Google Wallet + + + + Gratipay (Gittip) + + + + Grav + + + + Gripfire, Inc. + + + + Grunt + + + + Gulp + + + + Hacker News + + + + Hacker News Square + + + + HireAHelper + + + + Hooli + + + + Hotjar + + + + Houzz + + + + HTML 5 Logo + + + + HubSpot + + + + IMDB + + + + Instagram + + + + Internet-explorer + + + + ioxhost + + + + iTunes + + + + Itunes Note + + + + Jenkis + + + + Joget + + + + Joomla Logo + + + + JavaScript (JS) + + + + JavaScript (JS) Square + + + + jsFiddle + + + + KeyCDN + + + + Kickstarter + + + + Kickstarter K + + + + Laravel + + + + last.fm + + + + last.fm Square + + + + Leanpub + + + + Less + + + + Line + + + + LinkedIn + + + + LinkedIn In + + + + Linode + + + + Linux + + + + lyft + + + + Magento + + + + MaxCDN + + + + MedApps + + + + Medium + + + + Medium M + + + + MRT + + + + Meetup + + + + Microsoft + + + + Mix + + + + Mixcloud + + + + Mizuni + + + + MODX + + + + Monero + + + + Napster + + + + Nintendo Switch + + + + Node.js + + + + Node.js JS + + + + npm + + + + NS8 + + + + Nutritionix + + + + Odnoklassniki + + + + Odnoklassniki Square + + + + OpenCart + + + + OpenID + + + + Opera + + + + Optin Monster + + + + Open Source Initiative + + + + page4 Corporation + + + + Pagelines + + + + Palfed + + + + Patreon + + + + Paypal + + + + Periscope + + + + Phabricator + + + + Phoenix Framework + + + + Pied Piper Logo + + + + Alternate Pied Piper Logo + + + + Pied Piper PP Logo (Old) + + + + Pinterest + + + + Pinterest P + + + + Pinterest Square + + + + PlayStation + + + + Product Hunt + + + + Pushed + + + + Python + + + + QQ + + + + Quora + + + + Ravelry + + + + React + + + + Rebel Alliance + + + + red river + + + + reddit Logo + + + + reddit Alien + + + + reddit Square + + + + Rendact + + + + Renren + + + + replyd + + + + Resolving + + + + Rocket.Chat + + + + Rockrms + + + + Safari + + + + Sass + + + + SCHLIX + + + + Scribd + + + + Searchengin + + + + Sellcast + + + + Sellsy + + + + Servicestack + + + + Shirts in Bulk + + + + SimplyBuilt + + + + SISTRIX + + + + skyatlas + + + + Skype + + + + Slack Logo + + + + Slack Hashtag + + + + Slideshare + + + + Snapchat + + + + Snapchat Ghost + + + + Snapchat Square + + + + SoundCloud + + + + Speakap + + + + Spotify + + + + Stack Exchange + + + + Stack Overflow + + + + StayLinked + + + + Steam + + + + Steam Square + + + + Steam Symbol + + + + Sticker Mule + + + + Strava + + + + Stripe + + + + Stripe S + + + + Studio Vinari + + + + StumbleUpon Logo + + + + StumbleUpon Circle + + + + Superpowers + + + + Supple + + + + Telegram + + + + Telegram Plane + + + + Tencent Weibo + + + + ThemeIsle + + + + Trello + + + + TripAdvisor + + + + Tumblr + + + + Tumblr Square + + + + Twitch + + + + Twitter + + + + Twitter Square + + + + Typo3 + + + + Uber + + + + UIkit + + + + Uniregistry + + + + Untappd + + + + USB + + + + us-Sunnah Foundation + + + + Vaadin + + + + Viacoin + + + + Viadeo + + + + Viadeo Square + + + + Viber + + + + Vimeo + + + + Vimeo Square + + + + Vimeo + + + + Vine + + + + VK + + + + VNV + + + + Vue.js + + + + Weibo + + + + Weixin (WeChat) + + + + What's App + + + + What's App Square + + + + WHMCS + + + + Wikipedia W + + + + Windows + + + + WordPress Logo + + + + Wordpress Simple + + + + WPBeginner + + + + WPExplorer + + + + WPForms + + + + Xbox + + + + Xing + + + + Xing Square + + + + Y Combinator + + + + Yahoo Logo + + + + Yandex + + + + Yandex International + + + + Yelp + + + + Yoast + + + + YouTube + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-regular.svg b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-regular.svg new file mode 100644 index 000000000..1a3a44e4a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-regular.svg @@ -0,0 +1,466 @@ + + + + Address Book + + + + Address Card + + + + Alternate Arrow Circle Down + + + + Alternate Arrow Circle Left + + + + Alternate Arrow Circle Right + + + + Alternate Arrow Circle Up + + + + bell + + + + Bell Slash + + + + bookmark + + + + Building + + + + Calendar + + + + Alternate Calendar + + + + Calendar Check + + + + Calendar Minus + + + + Calendar Plus + + + + Calendar Times + + + + Caret Square Down + + + + Caret Square Left + + + + Caret Square Right + + + + Caret Square Up + + + + Bar Chart + + + + Check Circle + + + + Check Square + + + + Circle + + + + Clipboard + + + + Clock + + + + Clone + + + + Closed Captioning + + + + comment + + + + Alternate Comment + + + + comments + + + + Compass + + + + Copy + + + + Copyright + + + + Credit Card + + + + Dot Circle + + + + Edit + + + + Envelope + + + + Envelope Open + + + + Eye Slash + + + + File + + + + Alternate File + + + + Archive File + + + + Audio File + + + + Code File + + + + Excel File + + + + Image File + + + + PDF File + + + + Powerpoint File + + + + Video File + + + + Word File + + + + flag + + + + Folder + + + + Folder Open + + + + Frown + + + + Futbol + + + + Gem + + + + Lizard (Hand) + + + + Paper (Hand) + + + + Peace (Hand) + + + + Hand Pointing Down + + + + Hand Pointing Left + + + + Hand Pointing Right + + + + Hand Pointing Up + + + + Pointer (Hand) + + + + Rock (Hand) + + + + Scissors (Hand) + + + + Spock (Hand) + + + + Handshake + + + + HDD + + + + Heart + + + + hospital + + + + Hourglass + + + + Identification Badge + + + + Identification Card + + + + Image + + + + Images + + + + Keyboard + + + + Lemon + + + + Life Ring + + + + Lightbulb + + + + list-alt + + + + Map + + + + Meh + + + + Minus Square + + + + Money Bill-alt + + + + Moon + + + + Newspaper + + + + Object Group + + + + Object Ungroup + + + + Paper Plane + + + + Pause Circle + + + + Play Circle + + + + Plus Square + + + + Question Circle + + + + Registered Trademark + + + + Save + + + + Share Square + + + + Smile + + + + Snowflake + + + + Square + + + + Star + + + + star-half + + + + Sticky Note + + + + Stop Circle + + + + Sun + + + + thumbs-down + + + + thumbs-up + + + + Times Circle + + + + Alternate Trash + + + + User + + + + User Circle + + + + Window Close + + + + Window Maximize + + + + Window Restore + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-solid.svg b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-solid.svg new file mode 100644 index 000000000..8bc057f7c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/svg-sprites/fa-solid.svg @@ -0,0 +1,1862 @@ + + + + Address Book + + + + Address Card + + + + adjust + + + + align-center + + + + align-justify + + + + align-left + + + + align-right + + + + ambulance + + + + American Sign Language Interpreting + + + + Anchor + + + + Angle Double Down + + + + Angle Double Left + + + + Angle Double Right + + + + Angle Double Up + + + + angle-down + + + + angle-left + + + + angle-right + + + + angle-up + + + + Archive + + + + Alternate Arrow Circle Down + + + + Alternate Arrow Circle Left + + + + Alternate Arrow Circle Right + + + + Alternate Arrow Circle Up + + + + Arrow Circle Down + + + + Arrow Circle Left + + + + Arrow Circle Right + + + + Arrow Circle Up + + + + arrow-down + + + + arrow-left + + + + arrow-right + + + + arrow-up + + + + Alternate Arrows + + + + Alternate Arrows Horizontal + + + + Alternate Arrows Vertical + + + + Assistive Listening Systems + + + + asterisk + + + + At + + + + Audio Description + + + + backward + + + + Balance Scale + + + + ban + + + + barcode + + + + Bars + + + + Bath + + + + Battery Empty + + + + Battery Full + + + + Battery 1/2 Full + + + + Battery 1/4 Full + + + + Battery 3/4 Full + + + + Bed + + + + beer + + + + bell + + + + Bell Slash + + + + Bicycle + + + + Binoculars + + + + Birthday Cake + + + + Blind + + + + bold + + + + Lightning Bolt + + + + Bomb + + + + book + + + + bookmark + + + + Braille + + + + Briefcase + + + + Bug + + + + Building + + + + bullhorn + + + + Bullseye + + + + Bus + + + + Calculator + + + + Calendar + + + + Alternate Calendar + + + + Calendar Check + + + + Calendar Minus + + + + Calendar Plus + + + + Calendar Times + + + + camera + + + + Retro Camera + + + + Car + + + + Caret Down + + + + Caret Left + + + + Caret Right + + + + Caret Square Down + + + + Caret Square Left + + + + Caret Square Right + + + + Caret Square Up + + + + Caret Up + + + + Shopping Cart Arrow Down + + + + Add to Shopping Cart + + + + certificate + + + + Area Chart + + + + Bar Chart + + + + Line Chart + + + + Pie Chart + + + + Check + + + + Check Circle + + + + Check Square + + + + Chevron Circle Down + + + + Chevron Circle Left + + + + Chevron Circle Right + + + + Chevron Circle Up + + + + chevron-down + + + + chevron-left + + + + chevron-right + + + + chevron-up + + + + Child + + + + Circle + + + + Circle Notched + + + + Clipboard + + + + Clock + + + + Clone + + + + Closed Captioning + + + + Cloud + + + + Cloud Download-alt + + + + Cloud Upload-alt + + + + Code + + + + Code Branch + + + + Coffee + + + + cog + + + + cogs + + + + Columns + + + + comment + + + + Alternate Comment + + + + comments + + + + Compass + + + + Compress + + + + Copy + + + + Copyright + + + + Credit Card + + + + crop + + + + Crosshairs + + + + Cube + + + + Cubes + + + + Cut + + + + Database + + + + Deaf + + + + Desktop + + + + Dollar Sign + + + + Dot Circle + + + + Download + + + + Edit + + + + eject + + + + Horizontal Ellipsis + + + + Vertical Ellipsis + + + + Envelope + + + + Envelope Open + + + + Envelope Square + + + + eraser + + + + Euro Sign + + + + Alternate Exchange + + + + exclamation + + + + Exclamation Circle + + + + Exclamation Triangle + + + + Expand + + + + Alternate Expand Arrows + + + + Alternate External Link + + + + Alternate External Link Square + + + + Eye + + + + Eye Dropper + + + + Eye Slash + + + + fast-backward + + + + fast-forward + + + + Fax + + + + Female + + + + fighter-jet + + + + File + + + + Alternate File + + + + Archive File + + + + Audio File + + + + Code File + + + + Excel File + + + + Image File + + + + PDF File + + + + Powerpoint File + + + + Video File + + + + Word File + + + + Film + + + + Filter + + + + fire + + + + fire-extinguisher + + + + flag + + + + flag-checkered + + + + Flask + + + + Folder + + + + Folder Open + + + + font + + + + forward + + + + Frown + + + + Futbol + + + + Gamepad + + + + Gavel + + + + Gem + + + + Genderless + + + + gift + + + + Martini Glass + + + + Globe + + + + Graduation Cap + + + + H Square + + + + Lizard (Hand) + + + + Paper (Hand) + + + + Peace (Hand) + + + + Hand Pointing Down + + + + Hand Pointing Left + + + + Hand Pointing Right + + + + Hand Pointing Up + + + + Pointer (Hand) + + + + Rock (Hand) + + + + Scissors (Hand) + + + + Spock (Hand) + + + + Handshake + + + + Hashtag + + + + HDD + + + + heading + + + + headphones + + + + Heart + + + + Heartbeat + + + + History + + + + home + + + + hospital + + + + Hourglass + + + + Hourglass End + + + + Hourglass Half + + + + Hourglass Start + + + + I Beam Cursor + + + + Identification Badge + + + + Identification Card + + + + Image + + + + Images + + + + inbox + + + + Indent + + + + Industry + + + + Info + + + + Info Circle + + + + italic + + + + key + + + + Keyboard + + + + Language + + + + Laptop + + + + leaf + + + + Lemon + + + + Level Down-alt + + + + Level Up-alt + + + + Life Ring + + + + Lightbulb + + + + Link + + + + Turkish Lira Sign + + + + list + + + + list-alt + + + + list-ol + + + + list-ul + + + + location-arrow + + + + lock + + + + Lock Open + + + + Alternate Long Arrow Down + + + + Alternate Long Arrow Left + + + + Alternate Long Arrow Right + + + + Alternate Long Arrow Up + + + + Low Vision + + + + magic + + + + magnet + + + + Male + + + + Map + + + + map-marker + + + + Map Marker-alt + + + + Map Pin + + + + Map Signs + + + + Mars + + + + Mars Double + + + + Mars Stroke + + + + Mars Stroke Horizontal + + + + Mars Stroke Vertical + + + + medkit + + + + Meh + + + + Mercury + + + + Microchip + + + + microphone + + + + Microphone Slash + + + + minus + + + + Minus Circle + + + + Minus Square + + + + Mobile Phone + + + + Alternate Mobile + + + + Money Bill-alt + + + + Moon + + + + Motorcycle + + + + Mouse Pointer + + + + Music + + + + Neuter + + + + Newspaper + + + + Object Group + + + + Object Ungroup + + + + Outdent + + + + Paint Brush + + + + Paper Plane + + + + Paperclip + + + + paragraph + + + + Paste + + + + pause + + + + Pause Circle + + + + Paw + + + + Pen Square + + + + Alternate Pencil + + + + Percent + + + + Phone + + + + Phone Square + + + + Phone Volume + + + + plane + + + + play + + + + Play Circle + + + + Plug + + + + plus + + + + Plus Circle + + + + Plus Square + + + + Podcast + + + + Pound Sign + + + + Power Off + + + + print + + + + Puzzle Piece + + + + qrcode + + + + Question + + + + Question Circle + + + + quote-left + + + + quote-right + + + + random + + + + Recycle + + + + Redo + + + + Alternate Redo + + + + Registered Trademark + + + + Reply + + + + reply-all + + + + Retweet + + + + road + + + + rocket + + + + rss + + + + RSS Square + + + + Ruble Sign + + + + Indian Rupee Sign + + + + Save + + + + Search + + + + Search Minus + + + + Search Plus + + + + Server + + + + Share + + + + Alternate Share + + + + Alternate Share Square + + + + Share Square + + + + Shekel Sign + + + + Alternate Shield + + + + Ship + + + + Shopping Bag + + + + Shopping Basket + + + + shopping-cart + + + + Shower + + + + Alernate Sign In + + + + Sign Language + + + + Alernate Sign Out + + + + signal + + + + Sitemap + + + + Horizontal Sliders + + + + Smile + + + + Snowflake + + + + Sort + + + + Sort Alpha Down + + + + Sort Alpha Up + + + + Sort Amount Down + + + + Sort Amount Up + + + + Sort Down (Descending) + + + + Sort Numeric Down + + + + Sort Numeric Up + + + + Sort Up (Ascending) + + + + Space Shuttle + + + + Spinner + + + + Square + + + + Star + + + + star-half + + + + step-backward + + + + step-forward + + + + Stethoscope + + + + Sticky Note + + + + stop + + + + Stop Circle + + + + Street View + + + + Strikethrough + + + + subscript + + + + Subway + + + + Suitcase + + + + Sun + + + + superscript + + + + Sync + + + + Alternate Sync + + + + table + + + + tablet + + + + Alternate Tablet + + + + Alternate Tachometer + + + + tag + + + + tags + + + + Tasks + + + + Taxi + + + + Terminal + + + + text-height + + + + text-width + + + + th + + + + th-large + + + + th-list + + + + Thermometer Empty + + + + Thermometer Full + + + + Thermometer 1/2 Full + + + + Thermometer 1/4 Full + + + + Thermometer 3/4 Full + + + + thumbs-down + + + + thumbs-up + + + + Thumbtack + + + + Alernate Ticket + + + + Times + + + + Times Circle + + + + tint + + + + Toggle Off + + + + Toggle On + + + + Trademark + + + + Train + + + + Transgender + + + + Alternate Transgender + + + + Trash + + + + Alternate Trash + + + + Tree + + + + trophy + + + + truck + + + + TTY + + + + Television + + + + Umbrella + + + + Underline + + + + Undo + + + + Alternate Undo + + + + Universal Access + + + + University + + + + unlink + + + + unlock + + + + Alternate Unlock + + + + Upload + + + + User + + + + User Circle + + + + user-md + + + + Add User + + + + User Secret + + + + Remove User + + + + Users + + + + Utensil Spoon + + + + Utensils + + + + Venus + + + + Venus Double + + + + Venus Mars + + + + Video + + + + volume-down + + + + volume-off + + + + volume-up + + + + Wheelchair + + + + WiFi + + + + Window Close + + + + Window Maximize + + + + Window Minimize + + + + Window Restore + + + + Won Sign + + + + Wrench + + + + Yen Sign + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/LICENSE.txt b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/fa500px.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/fa500px.js new file mode 100644 index 000000000..a43508327 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/fa500px.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: '500px', icon: [448, 512, [], "f26e", "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccessibleIcon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccessibleIcon.js new file mode 100644 index 000000000..96cf686c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccessibleIcon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'accessible-icon', icon: [448, 512, [], "f368", "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccusoft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccusoft.js new file mode 100644 index 000000000..93bbb67dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAccusoft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'accusoft', icon: [640, 512, [], "f369", "M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdn.js new file mode 100644 index 000000000..634f259e8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'adn', icon: [496, 512, [], "f170", "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdversal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdversal.js new file mode 100644 index 000000000..ca40066be --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAdversal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'adversal', icon: [512, 512, [], "f36a", "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAffiliatetheme.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAffiliatetheme.js new file mode 100644 index 000000000..7caaa5676 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAffiliatetheme.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'affiliatetheme', icon: [512, 512, [], "f36b", "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAlgolia.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAlgolia.js new file mode 100644 index 000000000..b1822e7a7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAlgolia.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'algolia', icon: [448, 512, [], "f36c", "M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmazon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmazon.js new file mode 100644 index 000000000..991914ad1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmazon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'amazon', icon: [448, 512, [], "f270", "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmilia.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmilia.js new file mode 100644 index 000000000..6cbe01e8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAmilia.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'amilia', icon: [448, 512, [], "f36d", "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAndroid.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAndroid.js new file mode 100644 index 000000000..3a7a4bb70 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAndroid.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'android', icon: [448, 512, [], "f17b", "M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngellist.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngellist.js new file mode 100644 index 000000000..6e62b563d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngellist.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'angellist', icon: [448, 512, [], "f209", "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngrycreative.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngrycreative.js new file mode 100644 index 000000000..717ad60dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngrycreative.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'angrycreative', icon: [640, 512, [], "f36e", "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngular.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngular.js new file mode 100644 index 000000000..557718dcb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAngular.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'angular', icon: [415, 512, [], "f420", "M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStore.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStore.js new file mode 100644 index 000000000..ef65070a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStore.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'app-store', icon: [512, 512, [], "f36f", "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStoreIos.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStoreIos.js new file mode 100644 index 000000000..b64efae12 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAppStoreIos.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'app-store-ios', icon: [448, 512, [], "f370", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApper.js new file mode 100644 index 000000000..85608a3bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'apper', icon: [640, 512, [], "f371", "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApple.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApple.js new file mode 100644 index 000000000..1b1c03e34 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApple.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'apple', icon: [448, 512, [], "f179", "M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApplePay.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApplePay.js new file mode 100644 index 000000000..b7ba55b55 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faApplePay.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'apple-pay', icon: [640, 512, [], "f415", "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAsymmetrik.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAsymmetrik.js new file mode 100644 index 000000000..d1d337778 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAsymmetrik.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'asymmetrik', icon: [576, 512, [], "f372", "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAudible.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAudible.js new file mode 100644 index 000000000..13a6746ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAudible.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'audible', icon: [640, 512, [], "f373", "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAutoprefixer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAutoprefixer.js new file mode 100644 index 000000000..595e3f9fa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAutoprefixer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'autoprefixer', icon: [640, 512, [], "f41c", "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAvianex.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAvianex.js new file mode 100644 index 000000000..bb7c8aaad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAvianex.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'avianex', icon: [512, 512, [], "f374", "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAviato.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAviato.js new file mode 100644 index 000000000..733271d8e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAviato.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'aviato', icon: [640, 512, [], "f421", "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAws.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAws.js new file mode 100644 index 000000000..f74f284e3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faAws.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'aws', icon: [512, 512, [], "f375", "M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBandcamp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBandcamp.js new file mode 100644 index 000000000..addf31ecc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBandcamp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bandcamp', icon: [496, 512, [], "f2d5", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehance.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehance.js new file mode 100644 index 000000000..dc2bf505b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehance.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'behance', icon: [576, 512, [], "f1b4", "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehanceSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehanceSquare.js new file mode 100644 index 000000000..dff40a213 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBehanceSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'behance-square', icon: [512, 512, [], "f1b5", "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBimobject.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBimobject.js new file mode 100644 index 000000000..75ac64eef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBimobject.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bimobject', icon: [448, 512, [], "f378", "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitbucket.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitbucket.js new file mode 100644 index 000000000..f54bb7b9c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitbucket.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bitbucket', icon: [512, 512, [], "f171", "M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitcoin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitcoin.js new file mode 100644 index 000000000..3eefeab43 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBitcoin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bitcoin', icon: [512, 512, [], "f379", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBity.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBity.js new file mode 100644 index 000000000..8d3723b47 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBity.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bity', icon: [496, 512, [], "f37a", "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackTie.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackTie.js new file mode 100644 index 000000000..92d12b899 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackTie.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'black-tie', icon: [448, 512, [], "f27e", "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackberry.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackberry.js new file mode 100644 index 000000000..ebe40f15d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlackberry.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'blackberry', icon: [512, 512, [], "f37b", "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlogger.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlogger.js new file mode 100644 index 000000000..6c4bc3e8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBlogger.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'blogger', icon: [448, 512, [], "f37c", "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBloggerB.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBloggerB.js new file mode 100644 index 000000000..0bca32363 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBloggerB.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'blogger-b', icon: [448, 512, [], "f37d", "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetooth.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetooth.js new file mode 100644 index 000000000..9c5418232 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetooth.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bluetooth', icon: [448, 512, [], "f293", "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetoothB.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetoothB.js new file mode 100644 index 000000000..edb3ffb2d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBluetoothB.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'bluetooth-b', icon: [320, 512, [], "f294", "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBtc.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBtc.js new file mode 100644 index 000000000..ed6789267 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBtc.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'btc', icon: [384, 512, [], "f15a", "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuromobelexperte.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuromobelexperte.js new file mode 100644 index 000000000..1d30b0318 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuromobelexperte.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'buromobelexperte', icon: [448, 512, [], "f37f", "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuysellads.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuysellads.js new file mode 100644 index 000000000..446a13367 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faBuysellads.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'buysellads', icon: [448, 512, [], "f20d", "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcAmex.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcAmex.js new file mode 100644 index 000000000..0a1253164 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcAmex.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-amex', icon: [576, 512, [], "f1f3", "M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcApplePay.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcApplePay.js new file mode 100644 index 000000000..9a5b5656b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcApplePay.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-apple-pay', icon: [576, 512, [], "f416", "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDinersClub.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDinersClub.js new file mode 100644 index 000000000..a2534ac73 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDinersClub.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-diners-club', icon: [576, 512, [], "f24c", "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDiscover.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDiscover.js new file mode 100644 index 000000000..322dae740 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcDiscover.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-discover', icon: [576, 512, [], "f1f2", "M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcJcb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcJcb.js new file mode 100644 index 000000000..d8d7a5f42 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcJcb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-jcb', icon: [576, 512, [], "f24b", "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcMastercard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcMastercard.js new file mode 100644 index 000000000..7f7f0533f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcMastercard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-mastercard', icon: [576, 512, [], "f1f1", "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcPaypal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcPaypal.js new file mode 100644 index 000000000..b08fb1390 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcPaypal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-paypal', icon: [576, 512, [], "f1f4", "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcStripe.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcStripe.js new file mode 100644 index 000000000..dec163e82 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcStripe.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-stripe', icon: [576, 512, [], "f1f5", "M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcVisa.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcVisa.js new file mode 100644 index 000000000..aa352cb0b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCcVisa.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cc-visa', icon: [576, 512, [], "f1f0", "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCentercode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCentercode.js new file mode 100644 index 000000000..5670fc806 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCentercode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'centercode', icon: [512, 512, [], "f380", "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faChrome.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faChrome.js new file mode 100644 index 000000000..e2a701d26 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faChrome.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'chrome', icon: [496, 512, [], "f268", "M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudscale.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudscale.js new file mode 100644 index 000000000..ad212cd26 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudscale.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cloudscale', icon: [448, 512, [], "f383", "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudsmith.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudsmith.js new file mode 100644 index 000000000..c7a913cd2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudsmith.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cloudsmith', icon: [332, 512, [], "f384", "M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudversify.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudversify.js new file mode 100644 index 000000000..c74d8fd94 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCloudversify.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cloudversify', icon: [616, 512, [], "f385", "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodepen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodepen.js new file mode 100644 index 000000000..d60059273 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodepen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'codepen', icon: [512, 512, [], "f1cb", "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodiepie.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodiepie.js new file mode 100644 index 000000000..3eda32471 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCodiepie.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'codiepie', icon: [472, 512, [], "f284", "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faConnectdevelop.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faConnectdevelop.js new file mode 100644 index 000000000..5d0a6303e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faConnectdevelop.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'connectdevelop', icon: [576, 512, [], "f20e", "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faContao.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faContao.js new file mode 100644 index 000000000..818aac416 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faContao.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'contao', icon: [512, 512, [], "f26d", "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCpanel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCpanel.js new file mode 100644 index 000000000..8e95b712e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCpanel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cpanel', icon: [640, 512, [], "f388", "M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCreativeCommons.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCreativeCommons.js new file mode 100644 index 000000000..29bbdf292 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCreativeCommons.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'creative-commons', icon: [512, 512, [], "f25e", "M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3.js new file mode 100644 index 000000000..6cf1cd071 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'css3', icon: [512, 512, [], "f13c", "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3Alt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3Alt.js new file mode 100644 index 000000000..65149a22f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCss3Alt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'css3-alt', icon: [384, 512, [], "f38b", "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCuttlefish.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCuttlefish.js new file mode 100644 index 000000000..0931e003e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faCuttlefish.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'cuttlefish', icon: [440, 512, [], "f38c", "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDAndD.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDAndD.js new file mode 100644 index 000000000..a6b9105c1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDAndD.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'd-and-d', icon: [576, 512, [], "f38d", "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDashcube.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDashcube.js new file mode 100644 index 000000000..f4f9c14ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDashcube.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dashcube', icon: [384, 512, [], "f210", "M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDelicious.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDelicious.js new file mode 100644 index 000000000..9738e7a91 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDelicious.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'delicious', icon: [448, 512, [], "f1a5", "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeploydog.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeploydog.js new file mode 100644 index 000000000..ae339c78f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeploydog.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'deploydog', icon: [512, 512, [], "f38e", "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeskpro.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeskpro.js new file mode 100644 index 000000000..8c76fce98 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeskpro.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'deskpro', icon: [480, 512, [], "f38f", "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeviantart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeviantart.js new file mode 100644 index 000000000..80d741206 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDeviantart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'deviantart', icon: [320, 512, [], "f1bd", "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigg.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigg.js new file mode 100644 index 000000000..17855a0d0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigg.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'digg', icon: [512, 512, [], "f1a6", "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigitalOcean.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigitalOcean.js new file mode 100644 index 000000000..300d08400 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDigitalOcean.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'digital-ocean', icon: [512, 512, [], "f391", "M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscord.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscord.js new file mode 100644 index 000000000..582a19a11 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscord.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'discord', icon: [448, 512, [], "f392", "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscourse.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscourse.js new file mode 100644 index 000000000..737ce307f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDiscourse.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'discourse', icon: [448, 512, [], "f393", "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDochub.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDochub.js new file mode 100644 index 000000000..8f95a3bde --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDochub.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dochub', icon: [416, 512, [], "f394", "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDocker.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDocker.js new file mode 100644 index 000000000..005cfdd8f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDocker.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'docker', icon: [640, 512, [], "f395", "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDraft2digital.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDraft2digital.js new file mode 100644 index 000000000..c4a697a43 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDraft2digital.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'draft2digital', icon: [480, 512, [], "f396", "M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbble.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbble.js new file mode 100644 index 000000000..902132267 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbble.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dribbble', icon: [512, 512, [], "f17d", "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbbleSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbbleSquare.js new file mode 100644 index 000000000..9c8de9ef2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDribbbleSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dribbble-square', icon: [448, 512, [], "f397", "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDropbox.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDropbox.js new file mode 100644 index 000000000..fbf27b2a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDropbox.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dropbox', icon: [528, 512, [], "f16b", "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDrupal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDrupal.js new file mode 100644 index 000000000..a17845712 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDrupal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'drupal', icon: [448, 512, [], "f1a9", "M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDyalog.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDyalog.js new file mode 100644 index 000000000..9e4f67ab2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faDyalog.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'dyalog', icon: [416, 512, [], "f399", "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEarlybirds.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEarlybirds.js new file mode 100644 index 000000000..3b5319d3c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEarlybirds.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'earlybirds', icon: [480, 512, [], "f39a", "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEdge.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEdge.js new file mode 100644 index 000000000..a24eb3fbe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEdge.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'edge', icon: [512, 512, [], "f282", "M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmber.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmber.js new file mode 100644 index 000000000..c0be82c9d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmber.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'ember', icon: [640, 512, [], "f423", "M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmpire.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmpire.js new file mode 100644 index 000000000..54593cbdd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEmpire.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'empire', icon: [496, 512, [], "f1d1", "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEnvira.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEnvira.js new file mode 100644 index 000000000..30891753b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEnvira.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'envira', icon: [448, 512, [], "f299", "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faErlang.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faErlang.js new file mode 100644 index 000000000..d4fc3301a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faErlang.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'erlang', icon: [640, 512, [], "f39d", "M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEtsy.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEtsy.js new file mode 100644 index 000000000..9b857fa30 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faEtsy.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'etsy', icon: [384, 512, [], "f2d7", "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faExpeditedssl.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faExpeditedssl.js new file mode 100644 index 000000000..6bf9a9576 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faExpeditedssl.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'expeditedssl', icon: [496, 512, [], "f23e", "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebook.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebook.js new file mode 100644 index 000000000..42ae63d9d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebook.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'facebook', icon: [448, 512, [], "f09a", "M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookF.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookF.js new file mode 100644 index 000000000..9e3c07533 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookF.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'facebook-f', icon: [264, 512, [], "f39e", "M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookMessenger.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookMessenger.js new file mode 100644 index 000000000..54681c0bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookMessenger.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'facebook-messenger', icon: [448, 512, [], "f39f", "M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookSquare.js new file mode 100644 index 000000000..7e9ef957f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFacebookSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'facebook-square', icon: [448, 512, [], "f082", "M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirefox.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirefox.js new file mode 100644 index 000000000..cbc3eab09 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirefox.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'firefox', icon: [480, 512, [], "f269", "M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstOrder.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstOrder.js new file mode 100644 index 000000000..9f1056275 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstOrder.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'first-order', icon: [448, 512, [], "f2b0", "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstdraft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstdraft.js new file mode 100644 index 000000000..1ce27d10d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFirstdraft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'firstdraft', icon: [384, 512, [], "f3a1", "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFlickr.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFlickr.js new file mode 100644 index 000000000..e936a7b48 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFlickr.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'flickr', icon: [448, 512, [], "f16e", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFly.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFly.js new file mode 100644 index 000000000..d76d1966b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFly.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'fly', icon: [384, 512, [], "f417", "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesome.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesome.js new file mode 100644 index 000000000..60ab07b4e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesome.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'font-awesome', icon: [448, 512, [], "f2b4", "M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeAlt.js new file mode 100644 index 000000000..6e82564c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'font-awesome-alt', icon: [448, 512, [], "f35c", "M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeFlag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeFlag.js new file mode 100644 index 000000000..d33904a7c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFontAwesomeFlag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'font-awesome-flag', icon: [448, 512, [], "f425", "M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticons.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticons.js new file mode 100644 index 000000000..a52fcfdae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticons.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'fonticons', icon: [448, 512, [], "f280", "M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticonsFi.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticonsFi.js new file mode 100644 index 000000000..e52456022 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFonticonsFi.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'fonticons-fi', icon: [384, 512, [], "f3a2", "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesome.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesome.js new file mode 100644 index 000000000..4e7870868 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesome.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'fort-awesome', icon: [448, 512, [], "f286", "M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesomeAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesomeAlt.js new file mode 100644 index 000000000..2c92c1ffd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFortAwesomeAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'fort-awesome-alt', icon: [512, 512, [], "f3a3", "M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faForumbee.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faForumbee.js new file mode 100644 index 000000000..bb1a21321 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faForumbee.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'forumbee', icon: [448, 512, [], "f211", "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFoursquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFoursquare.js new file mode 100644 index 000000000..c53699023 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFoursquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'foursquare', icon: [368, 512, [], "f180", "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreeCodeCamp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreeCodeCamp.js new file mode 100644 index 000000000..88f545074 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreeCodeCamp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'free-code-camp', icon: [576, 512, [], "f2c5", "M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreebsd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreebsd.js new file mode 100644 index 000000000..d26c3e19d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faFreebsd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'freebsd', icon: [448, 512, [], "f3a4", "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGetPocket.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGetPocket.js new file mode 100644 index 000000000..3048df172 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGetPocket.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'get-pocket', icon: [448, 512, [], "f265", "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGg.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGg.js new file mode 100644 index 000000000..dd6902eb3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGg.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gg', icon: [512, 512, [], "f260", "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGgCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGgCircle.js new file mode 100644 index 000000000..363f16406 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGgCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gg-circle', icon: [512, 512, [], "f261", "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGit.js new file mode 100644 index 000000000..28eeef37e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'git', icon: [448, 512, [], "f1d3", "M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitSquare.js new file mode 100644 index 000000000..770d474f0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'git-square', icon: [448, 512, [], "f1d2", "M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithub.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithub.js new file mode 100644 index 000000000..3004567c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithub.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'github', icon: [496, 512, [], "f09b", "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubAlt.js new file mode 100644 index 000000000..53790ef34 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'github-alt', icon: [480, 512, [], "f113", "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubSquare.js new file mode 100644 index 000000000..e9d44af37 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGithubSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'github-square', icon: [448, 512, [], "f092", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitkraken.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitkraken.js new file mode 100644 index 000000000..d99c62f02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitkraken.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gitkraken', icon: [592, 512, [], "f3a6", "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitlab.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitlab.js new file mode 100644 index 000000000..27c82c5ee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitlab.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gitlab', icon: [512, 512, [], "f296", "M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitter.js new file mode 100644 index 000000000..22fbdbffe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGitter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gitter', icon: [384, 512, [], "f426", "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlide.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlide.js new file mode 100644 index 000000000..d5d9a51f0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlide.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'glide', icon: [448, 512, [], "f2a5", "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlideG.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlideG.js new file mode 100644 index 000000000..b91e9896c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGlideG.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'glide-g', icon: [448, 512, [], "f2a6", "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGofore.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGofore.js new file mode 100644 index 000000000..d5f90075e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGofore.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gofore', icon: [400, 512, [], "f3a7", "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreads.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreads.js new file mode 100644 index 000000000..0db892404 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreads.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'goodreads', icon: [448, 512, [], "f3a8", "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreadsG.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreadsG.js new file mode 100644 index 000000000..53528bf7b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoodreadsG.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'goodreads-g', icon: [384, 512, [], "f3a9", "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogle.js new file mode 100644 index 000000000..d89f4e0b4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google', icon: [488, 512, [], "f1a0", "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleDrive.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleDrive.js new file mode 100644 index 000000000..d370cbdf8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleDrive.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-drive', icon: [512, 512, [], "f3aa", "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlay.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlay.js new file mode 100644 index 000000000..b6e705c1d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlay.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-play', icon: [512, 512, [], "f3ab", "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlus.js new file mode 100644 index 000000000..59f91566e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-plus', icon: [496, 512, [], "f2b3", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusG.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusG.js new file mode 100644 index 000000000..a2f143429 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusG.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-plus-g', icon: [640, 512, [], "f0d5", "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusSquare.js new file mode 100644 index 000000000..4ce5e90eb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGooglePlusSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-plus-square', icon: [448, 512, [], "f0d4", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleWallet.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleWallet.js new file mode 100644 index 000000000..ec26c6c27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGoogleWallet.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'google-wallet', icon: [448, 512, [], "f1ee", "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGratipay.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGratipay.js new file mode 100644 index 000000000..05011784f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGratipay.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gratipay', icon: [496, 512, [], "f184", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrav.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrav.js new file mode 100644 index 000000000..d9d767cff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrav.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'grav', icon: [512, 512, [], "f2d6", "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGripfire.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGripfire.js new file mode 100644 index 000000000..ece0924c7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGripfire.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gripfire', icon: [384, 512, [], "f3ac", "M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrunt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrunt.js new file mode 100644 index 000000000..f1a38594f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGrunt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'grunt', icon: [384, 512, [], "f3ad", "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGulp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGulp.js new file mode 100644 index 000000000..a9b76b6a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faGulp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'gulp', icon: [256, 512, [], "f3ae", "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNews.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNews.js new file mode 100644 index 000000000..11ccaba07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNews.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hacker-news', icon: [448, 512, [], "f1d4", "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNewsSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNewsSquare.js new file mode 100644 index 000000000..9740be802 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHackerNewsSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hacker-news-square', icon: [448, 512, [], "f3af", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHireAHelper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHireAHelper.js new file mode 100644 index 000000000..2df8a9bff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHireAHelper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hire-a-helper', icon: [512, 512, [], "f3b0", "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHooli.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHooli.js new file mode 100644 index 000000000..a585cc81e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHooli.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hooli', icon: [640, 512, [], "f427", "M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHotjar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHotjar.js new file mode 100644 index 000000000..b0531c7de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHotjar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hotjar', icon: [448, 512, [], "f3b1", "M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHouzz.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHouzz.js new file mode 100644 index 000000000..cfd203b83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHouzz.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'houzz', icon: [320, 512, [], "f27c", "M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHtml5.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHtml5.js new file mode 100644 index 000000000..7c99e8a2d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHtml5.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'html5', icon: [384, 512, [], "f13b", "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHubspot.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHubspot.js new file mode 100644 index 000000000..bbcb70064 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faHubspot.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'hubspot', icon: [512, 512, [], "f3b2", "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faImdb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faImdb.js new file mode 100644 index 000000000..31828a6b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faImdb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'imdb', icon: [448, 512, [], "f2d8", "M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInstagram.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInstagram.js new file mode 100644 index 000000000..9d9b1955b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInstagram.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'instagram', icon: [448, 512, [], "f16d", "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInternetExplorer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInternetExplorer.js new file mode 100644 index 000000000..d54105ad1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faInternetExplorer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'internet-explorer', icon: [512, 512, [], "f26b", "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faIoxhost.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faIoxhost.js new file mode 100644 index 000000000..bdd4d5ceb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faIoxhost.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'ioxhost', icon: [640, 512, [], "f208", "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunes.js new file mode 100644 index 000000000..1ec133578 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'itunes', icon: [448, 512, [], "f3b4", "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunesNote.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunesNote.js new file mode 100644 index 000000000..c81e77eb9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faItunesNote.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'itunes-note', icon: [384, 512, [], "f3b5", "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJenkins.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJenkins.js new file mode 100644 index 000000000..4fe5b2e2e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJenkins.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'jenkins', icon: [512, 512, [], "f3b6", "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoget.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoget.js new file mode 100644 index 000000000..ff8aee048 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoget.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'joget', icon: [496, 512, [], "f3b7", "M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoomla.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoomla.js new file mode 100644 index 000000000..4e52edf4a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJoomla.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'joomla', icon: [448, 512, [], "f1aa", "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJs.js new file mode 100644 index 000000000..e4b641958 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'js', icon: [448, 512, [], "f3b8", "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsSquare.js new file mode 100644 index 000000000..2fd882f87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'js-square', icon: [512, 512, [], "f3b9", "M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsfiddle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsfiddle.js new file mode 100644 index 000000000..3bf90bf15 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faJsfiddle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'jsfiddle', icon: [576, 512, [], "f1cc", "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKeycdn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKeycdn.js new file mode 100644 index 000000000..cc6fa9340 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKeycdn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'keycdn', icon: [512, 512, [], "f3ba", "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarter.js new file mode 100644 index 000000000..6782ddb2f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'kickstarter', icon: [448, 512, [], "f3bb", "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarterK.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarterK.js new file mode 100644 index 000000000..8edeb7730 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faKickstarterK.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'kickstarter-k', icon: [384, 512, [], "f3bc", "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLaravel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLaravel.js new file mode 100644 index 000000000..4b2dc8561 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLaravel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'laravel', icon: [640, 512, [], "f3bd", "M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfm.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfm.js new file mode 100644 index 000000000..469e58e8c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfm.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'lastfm', icon: [512, 512, [], "f202", "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfmSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfmSquare.js new file mode 100644 index 000000000..794227da9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLastfmSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'lastfm-square', icon: [448, 512, [], "f203", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLeanpub.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLeanpub.js new file mode 100644 index 000000000..b7befa447 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLeanpub.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'leanpub', icon: [576, 512, [], "f212", "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLess.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLess.js new file mode 100644 index 000000000..ec0d9bac4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLess.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'less', icon: [640, 512, [], "f41d", "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLine.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLine.js new file mode 100644 index 000000000..f8716b6cb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLine.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'line', icon: [448, 512, [], "f3c0", "M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedin.js new file mode 100644 index 000000000..d11407030 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'linkedin', icon: [448, 512, [], "f08c", "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedinIn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedinIn.js new file mode 100644 index 000000000..af3af1cf5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinkedinIn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'linkedin-in', icon: [448, 512, [], "f0e1", "M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinode.js new file mode 100644 index 000000000..1e3338b45 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'linode', icon: [448, 512, [], "f2b8", "M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinux.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinux.js new file mode 100644 index 000000000..779c483c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLinux.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'linux', icon: [448, 512, [], "f17c", "M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLyft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLyft.js new file mode 100644 index 000000000..ce11a2f7d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faLyft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'lyft', icon: [512, 512, [], "f3c3", "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMagento.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMagento.js new file mode 100644 index 000000000..a8047a2b0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMagento.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'magento', icon: [448, 512, [], "f3c4", "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMaxcdn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMaxcdn.js new file mode 100644 index 000000000..aa70893bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMaxcdn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'maxcdn', icon: [512, 512, [], "f136", "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedapps.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedapps.js new file mode 100644 index 000000000..4de8209d6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedapps.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'medapps', icon: [320, 512, [], "f3c6", "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedium.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedium.js new file mode 100644 index 000000000..82bbe162a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedium.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'medium', icon: [448, 512, [], "f23a", "M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMediumM.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMediumM.js new file mode 100644 index 000000000..8823e82d5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMediumM.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'medium-m', icon: [512, 512, [], "f3c7", "M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedrt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedrt.js new file mode 100644 index 000000000..47c7b801a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMedrt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'medrt', icon: [544, 512, [], "f3c8", "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMeetup.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMeetup.js new file mode 100644 index 000000000..dc9fceac2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMeetup.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'meetup', icon: [512, 512, [], "f2e0", "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMicrosoft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMicrosoft.js new file mode 100644 index 000000000..ded31e7a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMicrosoft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'microsoft', icon: [448, 512, [], "f3ca", "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMix.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMix.js new file mode 100644 index 000000000..2b11af729 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMix.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'mix', icon: [416, 512, [], "f3cb", "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMixcloud.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMixcloud.js new file mode 100644 index 000000000..f23cbab79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMixcloud.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'mixcloud', icon: [640, 512, [], "f289", "M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMizuni.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMizuni.js new file mode 100644 index 000000000..f73abf031 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMizuni.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'mizuni', icon: [496, 512, [], "f3cc", "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faModx.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faModx.js new file mode 100644 index 000000000..59f10e64d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faModx.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'modx', icon: [448, 512, [], "f285", "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMonero.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMonero.js new file mode 100644 index 000000000..8f86fbced --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faMonero.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'monero', icon: [496, 512, [], "f3d0", "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNapster.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNapster.js new file mode 100644 index 000000000..a6b1b7387 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNapster.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'napster', icon: [496, 512, [], "f3d2", "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNintendoSwitch.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNintendoSwitch.js new file mode 100644 index 000000000..66224d8bb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNintendoSwitch.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'nintendo-switch', icon: [448, 512, [], "f418", "M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNode.js new file mode 100644 index 000000000..553c5af03 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'node', icon: [640, 512, [], "f419", "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNodeJs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNodeJs.js new file mode 100644 index 000000000..d445a427e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNodeJs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'node-js', icon: [448, 512, [], "f3d3", "M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNpm.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNpm.js new file mode 100644 index 000000000..9a8b131a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNpm.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'npm', icon: [576, 512, [], "f3d4", "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNs8.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNs8.js new file mode 100644 index 000000000..90b33e979 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNs8.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'ns8', icon: [640, 512, [], "f3d5", "M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNutritionix.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNutritionix.js new file mode 100644 index 000000000..ff7e1b1a3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faNutritionix.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'nutritionix', icon: [400, 512, [], "f3d6", "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassniki.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassniki.js new file mode 100644 index 000000000..e8b3c77fe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassniki.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'odnoklassniki', icon: [320, 512, [], "f263", "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassnikiSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassnikiSquare.js new file mode 100644 index 000000000..64bc58b30 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOdnoklassnikiSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'odnoklassniki-square', icon: [448, 512, [], "f264", "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpencart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpencart.js new file mode 100644 index 000000000..f2153fb9d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpencart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'opencart', icon: [640, 512, [], "f23d", "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpenid.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpenid.js new file mode 100644 index 000000000..1e3a5f251 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpenid.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'openid', icon: [448, 512, [], "f19b", "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpera.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpera.js new file mode 100644 index 000000000..1baf5a574 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOpera.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'opera', icon: [496, 512, [], "f26a", "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOptinMonster.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOptinMonster.js new file mode 100644 index 000000000..2f257802c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOptinMonster.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'optin-monster', icon: [576, 512, [], "f23c", "M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOsi.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOsi.js new file mode 100644 index 000000000..59060edb5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faOsi.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'osi', icon: [495, 512, [], "f41a", "M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPage4.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPage4.js new file mode 100644 index 000000000..951c87c56 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPage4.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'page4', icon: [496, 512, [], "f3d7", "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPagelines.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPagelines.js new file mode 100644 index 000000000..7a94e6b3c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPagelines.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pagelines', icon: [384, 512, [], "f18c", "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPalfed.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPalfed.js new file mode 100644 index 000000000..b4e9c63af --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPalfed.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'palfed', icon: [560, 512, [], "f3d8", "M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPatreon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPatreon.js new file mode 100644 index 000000000..80fffcd9d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPatreon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'patreon', icon: [512, 512, [], "f3d9", "M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPaypal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPaypal.js new file mode 100644 index 000000000..a586b36a1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPaypal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'paypal', icon: [384, 512, [], "f1ed", "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPeriscope.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPeriscope.js new file mode 100644 index 000000000..104ec0832 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPeriscope.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'periscope', icon: [448, 512, [], "f3da", "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhabricator.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhabricator.js new file mode 100644 index 000000000..e6035b9be --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhabricator.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'phabricator', icon: [496, 512, [], "f3db", "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhoenixFramework.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhoenixFramework.js new file mode 100644 index 000000000..0adb556c2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPhoenixFramework.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'phoenix-framework', icon: [640, 512, [], "f3dc", "M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiper.js new file mode 100644 index 000000000..1bf2bedf1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pied-piper', icon: [640, 512, [], "f2ae", "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperAlt.js new file mode 100644 index 000000000..e7719490c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pied-piper-alt', icon: [576, 512, [], "f1a8", "M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperPp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperPp.js new file mode 100644 index 000000000..5b58a44ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPiedPiperPp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pied-piper-pp', icon: [448, 512, [], "f1a7", "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterest.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterest.js new file mode 100644 index 000000000..b31b2ecd7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterest.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pinterest', icon: [496, 512, [], "f0d2", "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestP.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestP.js new file mode 100644 index 000000000..e439d0bac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestP.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pinterest-p', icon: [384, 512, [], "f231", "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestSquare.js new file mode 100644 index 000000000..84bee1207 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPinterestSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pinterest-square', icon: [448, 512, [], "f0d3", "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPlaystation.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPlaystation.js new file mode 100644 index 000000000..0baa6f925 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPlaystation.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'playstation', icon: [576, 512, [], "f3df", "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faProductHunt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faProductHunt.js new file mode 100644 index 000000000..da318fa40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faProductHunt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'product-hunt', icon: [512, 512, [], "f288", "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPushed.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPushed.js new file mode 100644 index 000000000..08579f6ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPushed.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'pushed', icon: [432, 512, [], "f3e1", "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPython.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPython.js new file mode 100644 index 000000000..72f5f57ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faPython.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'python', icon: [448, 512, [], "f3e2", "M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQq.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQq.js new file mode 100644 index 000000000..f9d862780 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQq.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'qq', icon: [448, 512, [], "f1d6", "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQuora.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQuora.js new file mode 100644 index 000000000..3aca0f349 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faQuora.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'quora', icon: [448, 512, [], "f2c4", "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRavelry.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRavelry.js new file mode 100644 index 000000000..c9bae4696 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRavelry.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'ravelry', icon: [512, 512, [], "f2d9", "M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReact.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReact.js new file mode 100644 index 000000000..e84eb475e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReact.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'react', icon: [512, 512, [], "f41b", "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRebel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRebel.js new file mode 100644 index 000000000..4e63442ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRebel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'rebel', icon: [512, 512, [], "f1d0", "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedRiver.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedRiver.js new file mode 100644 index 000000000..500031169 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedRiver.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'red-river', icon: [448, 512, [], "f3e3", "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReddit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReddit.js new file mode 100644 index 000000000..51fe16ce2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReddit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'reddit', icon: [512, 512, [], "f1a1", "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditAlien.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditAlien.js new file mode 100644 index 000000000..01c0c36ac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditAlien.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'reddit-alien', icon: [512, 512, [], "f281", "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditSquare.js new file mode 100644 index 000000000..44d5090c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRedditSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'reddit-square', icon: [448, 512, [], "f1a2", "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRendact.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRendact.js new file mode 100644 index 000000000..e2c2d44c1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRendact.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'rendact', icon: [496, 512, [], "f3e4", "M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRenren.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRenren.js new file mode 100644 index 000000000..e87108703 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRenren.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'renren', icon: [512, 512, [], "f18b", "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReplyd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReplyd.js new file mode 100644 index 000000000..34f2c1e1d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faReplyd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'replyd', icon: [448, 512, [], "f3e6", "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faResolving.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faResolving.js new file mode 100644 index 000000000..d81f1b101 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faResolving.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'resolving', icon: [496, 512, [], "f3e7", "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRocketchat.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRocketchat.js new file mode 100644 index 000000000..f9e3423cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRocketchat.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'rocketchat', icon: [448, 512, [], "f3e8", "M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRockrms.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRockrms.js new file mode 100644 index 000000000..fc3a07c40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faRockrms.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'rockrms', icon: [496, 512, [], "f3e9", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSafari.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSafari.js new file mode 100644 index 000000000..b4e94ffb9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSafari.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'safari', icon: [512, 512, [], "f267", "M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSass.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSass.js new file mode 100644 index 000000000..6b7f09b35 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSass.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'sass', icon: [640, 512, [], "f41e", "M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSchlix.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSchlix.js new file mode 100644 index 000000000..790553199 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSchlix.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'schlix', icon: [448, 512, [], "f3ea", "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faScribd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faScribd.js new file mode 100644 index 000000000..03f0c21bb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faScribd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'scribd', icon: [384, 512, [], "f28a", "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSearchengin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSearchengin.js new file mode 100644 index 000000000..d859d034d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSearchengin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'searchengin', icon: [460, 512, [], "f3eb", "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellcast.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellcast.js new file mode 100644 index 000000000..444ba7491 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellcast.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'sellcast', icon: [448, 512, [], "f2da", "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellsy.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellsy.js new file mode 100644 index 000000000..4cda9dbf7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSellsy.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'sellsy', icon: [640, 512, [], "f213", "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faServicestack.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faServicestack.js new file mode 100644 index 000000000..b7766da31 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faServicestack.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'servicestack', icon: [496, 512, [], "f3ec", "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faShirtsinbulk.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faShirtsinbulk.js new file mode 100644 index 000000000..d0d4550eb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faShirtsinbulk.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'shirtsinbulk', icon: [448, 512, [], "f214", "M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSimplybuilt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSimplybuilt.js new file mode 100644 index 000000000..a13cc5af3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSimplybuilt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'simplybuilt', icon: [512, 512, [], "f215", "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSistrix.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSistrix.js new file mode 100644 index 000000000..b637773aa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSistrix.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'sistrix', icon: [448, 512, [], "f3ee", "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkyatlas.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkyatlas.js new file mode 100644 index 000000000..b1511ac49 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkyatlas.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'skyatlas', icon: [576, 512, [], "f216", "M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkype.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkype.js new file mode 100644 index 000000000..dda0f26ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSkype.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'skype', icon: [448, 512, [], "f17e", "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlack.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlack.js new file mode 100644 index 000000000..727e3861f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlack.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'slack', icon: [448, 512, [], "f198", "M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlackHash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlackHash.js new file mode 100644 index 000000000..e27d05236 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlackHash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'slack-hash', icon: [448, 512, [], "f3ef", "M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlideshare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlideshare.js new file mode 100644 index 000000000..6bddf2fd4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSlideshare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'slideshare', icon: [512, 512, [], "f1e7", "M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchat.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchat.js new file mode 100644 index 000000000..3c63db715 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchat.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'snapchat', icon: [496, 512, [], "f2ab", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatGhost.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatGhost.js new file mode 100644 index 000000000..e3d3305c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatGhost.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'snapchat-ghost', icon: [512, 512, [], "f2ac", "M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatSquare.js new file mode 100644 index 000000000..6c784b57d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSnapchatSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'snapchat-square', icon: [448, 512, [], "f2ad", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSoundcloud.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSoundcloud.js new file mode 100644 index 000000000..f64b52399 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSoundcloud.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'soundcloud', icon: [640, 512, [], "f1be", "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpeakap.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpeakap.js new file mode 100644 index 000000000..f261f1cd1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpeakap.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'speakap', icon: [448, 512, [], "f3f3", "M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpotify.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpotify.js new file mode 100644 index 000000000..e758bec89 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSpotify.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'spotify', icon: [496, 512, [], "f1bc", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackExchange.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackExchange.js new file mode 100644 index 000000000..0405c6ec6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackExchange.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stack-exchange', icon: [448, 512, [], "f18d", "M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackOverflow.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackOverflow.js new file mode 100644 index 000000000..608c4d6bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStackOverflow.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stack-overflow', icon: [384, 512, [], "f16c", "M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStaylinked.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStaylinked.js new file mode 100644 index 000000000..aa3d258d0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStaylinked.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'staylinked', icon: [440, 512, [], "f3f5", "M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteam.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteam.js new file mode 100644 index 000000000..a49204cf9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteam.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'steam', icon: [496, 512, [], "f1b6", "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSquare.js new file mode 100644 index 000000000..a143d6143 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'steam-square', icon: [448, 512, [], "f1b7", "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSymbol.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSymbol.js new file mode 100644 index 000000000..362f0af3e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSteamSymbol.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'steam-symbol', icon: [448, 512, [], "f3f6", "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStickerMule.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStickerMule.js new file mode 100644 index 000000000..ab2814498 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStickerMule.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'sticker-mule', icon: [576, 512, [], "f3f7", "M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStrava.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStrava.js new file mode 100644 index 000000000..e764188a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStrava.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'strava', icon: [369, 512, [], "f428", "M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripe.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripe.js new file mode 100644 index 000000000..ff89cc3dc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripe.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stripe', icon: [640, 512, [], "f429", "M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripeS.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripeS.js new file mode 100644 index 000000000..116f946e6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStripeS.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stripe-s', icon: [362, 512, [], "f42a", "M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStudiovinari.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStudiovinari.js new file mode 100644 index 000000000..d453ed235 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStudiovinari.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'studiovinari', icon: [512, 512, [], "f3f8", "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleupon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleupon.js new file mode 100644 index 000000000..51d87295c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleupon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stumbleupon', icon: [512, 512, [], "f1a4", "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleuponCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleuponCircle.js new file mode 100644 index 000000000..15df8f03c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faStumbleuponCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'stumbleupon-circle', icon: [496, 512, [], "f1a3", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSuperpowers.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSuperpowers.js new file mode 100644 index 000000000..5ac9ab289 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSuperpowers.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'superpowers', icon: [448, 512, [], "f2dd", "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSupple.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSupple.js new file mode 100644 index 000000000..6a905deca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faSupple.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'supple', icon: [640, 512, [], "f3f9", "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegram.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegram.js new file mode 100644 index 000000000..3ddcf39de --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegram.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'telegram', icon: [496, 512, [], "f2c6", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegramPlane.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegramPlane.js new file mode 100644 index 000000000..85fb650a9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTelegramPlane.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'telegram-plane', icon: [448, 512, [], "f3fe", "M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTencentWeibo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTencentWeibo.js new file mode 100644 index 000000000..6ab33a60a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTencentWeibo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'tencent-weibo', icon: [384, 512, [], "f1d5", "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faThemeisle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faThemeisle.js new file mode 100644 index 000000000..e397a113d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faThemeisle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'themeisle', icon: [512, 512, [], "f2b2", "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTrello.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTrello.js new file mode 100644 index 000000000..b11b48552 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTrello.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'trello', icon: [448, 512, [], "f181", "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTripadvisor.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTripadvisor.js new file mode 100644 index 000000000..4e336e7a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTripadvisor.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'tripadvisor', icon: [576, 512, [], "f262", "M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblr.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblr.js new file mode 100644 index 000000000..4d68094b2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblr.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'tumblr', icon: [320, 512, [], "f173", "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblrSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblrSquare.js new file mode 100644 index 000000000..79078f0cf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTumblrSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'tumblr-square', icon: [448, 512, [], "f174", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitch.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitch.js new file mode 100644 index 000000000..1f9f2464e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitch.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'twitch', icon: [448, 512, [], "f1e8", "M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitter.js new file mode 100644 index 000000000..3439c4e23 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'twitter', icon: [512, 512, [], "f099", "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitterSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitterSquare.js new file mode 100644 index 000000000..50e211b41 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTwitterSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'twitter-square', icon: [448, 512, [], "f081", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTypo3.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTypo3.js new file mode 100644 index 000000000..27471adfa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faTypo3.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'typo3', icon: [433, 512, [], "f42b", "M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUber.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUber.js new file mode 100644 index 000000000..be198af83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUber.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'uber', icon: [448, 512, [], "f402", "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUikit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUikit.js new file mode 100644 index 000000000..9c2a9a0af --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUikit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'uikit', icon: [448, 512, [], "f403", "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUniregistry.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUniregistry.js new file mode 100644 index 000000000..b56ee9733 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUniregistry.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'uniregistry', icon: [384, 512, [], "f404", "M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUntappd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUntappd.js new file mode 100644 index 000000000..4dd6056a1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUntappd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'untappd', icon: [640, 512, [], "f405", "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUsb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUsb.js new file mode 100644 index 000000000..92d91e16c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUsb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'usb', icon: [640, 512, [], "f287", "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUssunnah.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUssunnah.js new file mode 100644 index 000000000..f26270820 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faUssunnah.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'ussunnah', icon: [512, 512, [], "f407", "M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVaadin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVaadin.js new file mode 100644 index 000000000..4e2c10ddd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVaadin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vaadin', icon: [448, 512, [], "f408", "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViacoin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViacoin.js new file mode 100644 index 000000000..e8bcdcb7e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViacoin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'viacoin', icon: [384, 512, [], "f237", "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeo.js new file mode 100644 index 000000000..b12e141d0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'viadeo', icon: [448, 512, [], "f2a9", "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeoSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeoSquare.js new file mode 100644 index 000000000..52523efda --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViadeoSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'viadeo-square', icon: [448, 512, [], "f2aa", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViber.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViber.js new file mode 100644 index 000000000..37669aa7a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faViber.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'viber', icon: [512, 512, [], "f409", "M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeo.js new file mode 100644 index 000000000..080a6322a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vimeo', icon: [448, 512, [], "f40a", "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoSquare.js new file mode 100644 index 000000000..64ed6938b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vimeo-square', icon: [448, 512, [], "f194", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoV.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoV.js new file mode 100644 index 000000000..59e7891f3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVimeoV.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vimeo-v', icon: [448, 512, [], "f27d", "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVine.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVine.js new file mode 100644 index 000000000..6e3687e50 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVine.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vine', icon: [384, 512, [], "f1ca", "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVk.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVk.js new file mode 100644 index 000000000..6a02741ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVk.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vk', icon: [576, 512, [], "f189", "M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVnv.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVnv.js new file mode 100644 index 000000000..d3c0cc77b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVnv.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vnv', icon: [640, 512, [], "f40b", "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVuejs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVuejs.js new file mode 100644 index 000000000..814d7fb42 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faVuejs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'vuejs', icon: [448, 512, [], "f41f", "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeibo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeibo.js new file mode 100644 index 000000000..92b008a73 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeibo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'weibo', icon: [512, 512, [], "f18a", "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeixin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeixin.js new file mode 100644 index 000000000..f37563c36 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWeixin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'weixin', icon: [576, 512, [], "f1d7", "M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsapp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsapp.js new file mode 100644 index 000000000..2a95d5b0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsapp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'whatsapp', icon: [448, 512, [], "f232", "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsappSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsappSquare.js new file mode 100644 index 000000000..ebab48a2b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhatsappSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'whatsapp-square', icon: [448, 512, [], "f40c", "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhmcs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhmcs.js new file mode 100644 index 000000000..c8389e690 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWhmcs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'whmcs', icon: [448, 512, [], "f40d", "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWikipediaW.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWikipediaW.js new file mode 100644 index 000000000..866ea9cc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWikipediaW.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wikipedia-w', icon: [640, 512, [], "f266", "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWindows.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWindows.js new file mode 100644 index 000000000..1748104bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWindows.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'windows', icon: [448, 512, [], "f17a", "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpress.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpress.js new file mode 100644 index 000000000..810100b66 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpress.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wordpress', icon: [512, 512, [], "f19a", "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpressSimple.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpressSimple.js new file mode 100644 index 000000000..866284cb2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWordpressSimple.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wordpress-simple', icon: [512, 512, [], "f411", "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpbeginner.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpbeginner.js new file mode 100644 index 000000000..b076958ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpbeginner.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wpbeginner', icon: [512, 512, [], "f297", "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpexplorer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpexplorer.js new file mode 100644 index 000000000..db1f9cc51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpexplorer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wpexplorer', icon: [512, 512, [], "f2de", "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpforms.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpforms.js new file mode 100644 index 000000000..abc5b325e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faWpforms.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'wpforms', icon: [448, 512, [], "f298", "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXbox.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXbox.js new file mode 100644 index 000000000..b5afdb366 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXbox.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'xbox', icon: [512, 512, [], "f412", "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXing.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXing.js new file mode 100644 index 000000000..fcd0b7655 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXing.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'xing', icon: [384, 512, [], "f168", "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXingSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXingSquare.js new file mode 100644 index 000000000..06344903d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faXingSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'xing-square', icon: [448, 512, [], "f169", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYCombinator.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYCombinator.js new file mode 100644 index 000000000..701c08c87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYCombinator.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'y-combinator', icon: [448, 512, [], "f23b", "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYahoo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYahoo.js new file mode 100644 index 000000000..293cc9ab0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYahoo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'yahoo', icon: [360, 512, [], "f19e", "M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandex.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandex.js new file mode 100644 index 000000000..e9230e774 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandex.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'yandex', icon: [256, 512, [], "f413", "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandexInternational.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandexInternational.js new file mode 100644 index 000000000..432c918aa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYandexInternational.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'yandex-international', icon: [320, 512, [], "f414", "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYelp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYelp.js new file mode 100644 index 000000000..1b6e3216d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYelp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'yelp', icon: [384, 512, [], "f1e9", "M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoast.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoast.js new file mode 100644 index 000000000..31847811c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoast.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'yoast', icon: [448, 512, [], "f2b1", "M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoutube.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoutube.js new file mode 100644 index 000000000..0492d3369 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/faYoutube.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fab', iconName: 'youtube', icon: [576, 512, [], "f167", "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.es.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.es.js new file mode 100644 index 000000000..0251e6a9d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.es.js @@ -0,0 +1,650 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +var prefix = "fab"; +var fa500px = { prefix: 'fab', iconName: '500px', icon: [448, 512, [], "f26e", "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"] }; +var faAccessibleIcon = { prefix: 'fab', iconName: 'accessible-icon', icon: [448, 512, [], "f368", "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"] }; +var faAccusoft = { prefix: 'fab', iconName: 'accusoft', icon: [640, 512, [], "f369", "M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"] }; +var faAdn = { prefix: 'fab', iconName: 'adn', icon: [496, 512, [], "f170", "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"] }; +var faAdversal = { prefix: 'fab', iconName: 'adversal', icon: [512, 512, [], "f36a", "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"] }; +var faAffiliatetheme = { prefix: 'fab', iconName: 'affiliatetheme', icon: [512, 512, [], "f36b", "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"] }; +var faAlgolia = { prefix: 'fab', iconName: 'algolia', icon: [448, 512, [], "f36c", "M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"] }; +var faAmazon = { prefix: 'fab', iconName: 'amazon', icon: [448, 512, [], "f270", "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"] }; +var faAmilia = { prefix: 'fab', iconName: 'amilia', icon: [448, 512, [], "f36d", "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"] }; +var faAndroid = { prefix: 'fab', iconName: 'android', icon: [448, 512, [], "f17b", "M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"] }; +var faAngellist = { prefix: 'fab', iconName: 'angellist', icon: [448, 512, [], "f209", "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"] }; +var faAngrycreative = { prefix: 'fab', iconName: 'angrycreative', icon: [640, 512, [], "f36e", "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"] }; +var faAngular = { prefix: 'fab', iconName: 'angular', icon: [415, 512, [], "f420", "M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"] }; +var faAppStore = { prefix: 'fab', iconName: 'app-store', icon: [512, 512, [], "f36f", "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"] }; +var faAppStoreIos = { prefix: 'fab', iconName: 'app-store-ios', icon: [448, 512, [], "f370", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"] }; +var faApper = { prefix: 'fab', iconName: 'apper', icon: [640, 512, [], "f371", "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"] }; +var faApple = { prefix: 'fab', iconName: 'apple', icon: [448, 512, [], "f179", "M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"] }; +var faApplePay = { prefix: 'fab', iconName: 'apple-pay', icon: [640, 512, [], "f415", "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"] }; +var faAsymmetrik = { prefix: 'fab', iconName: 'asymmetrik', icon: [576, 512, [], "f372", "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"] }; +var faAudible = { prefix: 'fab', iconName: 'audible', icon: [640, 512, [], "f373", "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"] }; +var faAutoprefixer = { prefix: 'fab', iconName: 'autoprefixer', icon: [640, 512, [], "f41c", "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"] }; +var faAvianex = { prefix: 'fab', iconName: 'avianex', icon: [512, 512, [], "f374", "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"] }; +var faAviato = { prefix: 'fab', iconName: 'aviato', icon: [640, 512, [], "f421", "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"] }; +var faAws = { prefix: 'fab', iconName: 'aws', icon: [512, 512, [], "f375", "M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"] }; +var faBandcamp = { prefix: 'fab', iconName: 'bandcamp', icon: [496, 512, [], "f2d5", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"] }; +var faBehance = { prefix: 'fab', iconName: 'behance', icon: [576, 512, [], "f1b4", "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"] }; +var faBehanceSquare = { prefix: 'fab', iconName: 'behance-square', icon: [512, 512, [], "f1b5", "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"] }; +var faBimobject = { prefix: 'fab', iconName: 'bimobject', icon: [448, 512, [], "f378", "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"] }; +var faBitbucket = { prefix: 'fab', iconName: 'bitbucket', icon: [512, 512, [], "f171", "M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"] }; +var faBitcoin = { prefix: 'fab', iconName: 'bitcoin', icon: [512, 512, [], "f379", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"] }; +var faBity = { prefix: 'fab', iconName: 'bity', icon: [496, 512, [], "f37a", "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"] }; +var faBlackTie = { prefix: 'fab', iconName: 'black-tie', icon: [448, 512, [], "f27e", "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"] }; +var faBlackberry = { prefix: 'fab', iconName: 'blackberry', icon: [512, 512, [], "f37b", "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"] }; +var faBlogger = { prefix: 'fab', iconName: 'blogger', icon: [448, 512, [], "f37c", "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"] }; +var faBloggerB = { prefix: 'fab', iconName: 'blogger-b', icon: [448, 512, [], "f37d", "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"] }; +var faBluetooth = { prefix: 'fab', iconName: 'bluetooth', icon: [448, 512, [], "f293", "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"] }; +var faBluetoothB = { prefix: 'fab', iconName: 'bluetooth-b', icon: [320, 512, [], "f294", "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"] }; +var faBtc = { prefix: 'fab', iconName: 'btc', icon: [384, 512, [], "f15a", "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"] }; +var faBuromobelexperte = { prefix: 'fab', iconName: 'buromobelexperte', icon: [448, 512, [], "f37f", "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"] }; +var faBuysellads = { prefix: 'fab', iconName: 'buysellads', icon: [448, 512, [], "f20d", "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"] }; +var faCcAmex = { prefix: 'fab', iconName: 'cc-amex', icon: [576, 512, [], "f1f3", "M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"] }; +var faCcApplePay = { prefix: 'fab', iconName: 'cc-apple-pay', icon: [576, 512, [], "f416", "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"] }; +var faCcDinersClub = { prefix: 'fab', iconName: 'cc-diners-club', icon: [576, 512, [], "f24c", "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"] }; +var faCcDiscover = { prefix: 'fab', iconName: 'cc-discover', icon: [576, 512, [], "f1f2", "M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"] }; +var faCcJcb = { prefix: 'fab', iconName: 'cc-jcb', icon: [576, 512, [], "f24b", "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"] }; +var faCcMastercard = { prefix: 'fab', iconName: 'cc-mastercard', icon: [576, 512, [], "f1f1", "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"] }; +var faCcPaypal = { prefix: 'fab', iconName: 'cc-paypal', icon: [576, 512, [], "f1f4", "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"] }; +var faCcStripe = { prefix: 'fab', iconName: 'cc-stripe', icon: [576, 512, [], "f1f5", "M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"] }; +var faCcVisa = { prefix: 'fab', iconName: 'cc-visa', icon: [576, 512, [], "f1f0", "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"] }; +var faCentercode = { prefix: 'fab', iconName: 'centercode', icon: [512, 512, [], "f380", "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"] }; +var faChrome = { prefix: 'fab', iconName: 'chrome', icon: [496, 512, [], "f268", "M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"] }; +var faCloudscale = { prefix: 'fab', iconName: 'cloudscale', icon: [448, 512, [], "f383", "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"] }; +var faCloudsmith = { prefix: 'fab', iconName: 'cloudsmith', icon: [332, 512, [], "f384", "M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"] }; +var faCloudversify = { prefix: 'fab', iconName: 'cloudversify', icon: [616, 512, [], "f385", "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"] }; +var faCodepen = { prefix: 'fab', iconName: 'codepen', icon: [512, 512, [], "f1cb", "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"] }; +var faCodiepie = { prefix: 'fab', iconName: 'codiepie', icon: [472, 512, [], "f284", "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"] }; +var faConnectdevelop = { prefix: 'fab', iconName: 'connectdevelop', icon: [576, 512, [], "f20e", "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"] }; +var faContao = { prefix: 'fab', iconName: 'contao', icon: [512, 512, [], "f26d", "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"] }; +var faCpanel = { prefix: 'fab', iconName: 'cpanel', icon: [640, 512, [], "f388", "M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"] }; +var faCreativeCommons = { prefix: 'fab', iconName: 'creative-commons', icon: [512, 512, [], "f25e", "M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"] }; +var faCss3 = { prefix: 'fab', iconName: 'css3', icon: [512, 512, [], "f13c", "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"] }; +var faCss3Alt = { prefix: 'fab', iconName: 'css3-alt', icon: [384, 512, [], "f38b", "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"] }; +var faCuttlefish = { prefix: 'fab', iconName: 'cuttlefish', icon: [440, 512, [], "f38c", "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"] }; +var faDAndD = { prefix: 'fab', iconName: 'd-and-d', icon: [576, 512, [], "f38d", "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"] }; +var faDashcube = { prefix: 'fab', iconName: 'dashcube', icon: [384, 512, [], "f210", "M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"] }; +var faDelicious = { prefix: 'fab', iconName: 'delicious', icon: [448, 512, [], "f1a5", "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"] }; +var faDeploydog = { prefix: 'fab', iconName: 'deploydog', icon: [512, 512, [], "f38e", "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"] }; +var faDeskpro = { prefix: 'fab', iconName: 'deskpro', icon: [480, 512, [], "f38f", "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"] }; +var faDeviantart = { prefix: 'fab', iconName: 'deviantart', icon: [320, 512, [], "f1bd", "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"] }; +var faDigg = { prefix: 'fab', iconName: 'digg', icon: [512, 512, [], "f1a6", "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"] }; +var faDigitalOcean = { prefix: 'fab', iconName: 'digital-ocean', icon: [512, 512, [], "f391", "M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"] }; +var faDiscord = { prefix: 'fab', iconName: 'discord', icon: [448, 512, [], "f392", "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"] }; +var faDiscourse = { prefix: 'fab', iconName: 'discourse', icon: [448, 512, [], "f393", "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"] }; +var faDochub = { prefix: 'fab', iconName: 'dochub', icon: [416, 512, [], "f394", "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"] }; +var faDocker = { prefix: 'fab', iconName: 'docker', icon: [640, 512, [], "f395", "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"] }; +var faDraft2digital = { prefix: 'fab', iconName: 'draft2digital', icon: [480, 512, [], "f396", "M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"] }; +var faDribbble = { prefix: 'fab', iconName: 'dribbble', icon: [512, 512, [], "f17d", "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"] }; +var faDribbbleSquare = { prefix: 'fab', iconName: 'dribbble-square', icon: [448, 512, [], "f397", "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"] }; +var faDropbox = { prefix: 'fab', iconName: 'dropbox', icon: [528, 512, [], "f16b", "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"] }; +var faDrupal = { prefix: 'fab', iconName: 'drupal', icon: [448, 512, [], "f1a9", "M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"] }; +var faDyalog = { prefix: 'fab', iconName: 'dyalog', icon: [416, 512, [], "f399", "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"] }; +var faEarlybirds = { prefix: 'fab', iconName: 'earlybirds', icon: [480, 512, [], "f39a", "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"] }; +var faEdge = { prefix: 'fab', iconName: 'edge', icon: [512, 512, [], "f282", "M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"] }; +var faEmber = { prefix: 'fab', iconName: 'ember', icon: [640, 512, [], "f423", "M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"] }; +var faEmpire = { prefix: 'fab', iconName: 'empire', icon: [496, 512, [], "f1d1", "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"] }; +var faEnvira = { prefix: 'fab', iconName: 'envira', icon: [448, 512, [], "f299", "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"] }; +var faErlang = { prefix: 'fab', iconName: 'erlang', icon: [640, 512, [], "f39d", "M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"] }; +var faEtsy = { prefix: 'fab', iconName: 'etsy', icon: [384, 512, [], "f2d7", "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"] }; +var faExpeditedssl = { prefix: 'fab', iconName: 'expeditedssl', icon: [496, 512, [], "f23e", "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"] }; +var faFacebook = { prefix: 'fab', iconName: 'facebook', icon: [448, 512, [], "f09a", "M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"] }; +var faFacebookF = { prefix: 'fab', iconName: 'facebook-f', icon: [264, 512, [], "f39e", "M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"] }; +var faFacebookMessenger = { prefix: 'fab', iconName: 'facebook-messenger', icon: [448, 512, [], "f39f", "M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"] }; +var faFacebookSquare = { prefix: 'fab', iconName: 'facebook-square', icon: [448, 512, [], "f082", "M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; +var faFirefox = { prefix: 'fab', iconName: 'firefox', icon: [480, 512, [], "f269", "M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"] }; +var faFirstOrder = { prefix: 'fab', iconName: 'first-order', icon: [448, 512, [], "f2b0", "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"] }; +var faFirstdraft = { prefix: 'fab', iconName: 'firstdraft', icon: [384, 512, [], "f3a1", "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"] }; +var faFlickr = { prefix: 'fab', iconName: 'flickr', icon: [448, 512, [], "f16e", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"] }; +var faFly = { prefix: 'fab', iconName: 'fly', icon: [384, 512, [], "f417", "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"] }; +var faFontAwesome = { prefix: 'fab', iconName: 'font-awesome', icon: [448, 512, [], "f2b4", "M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"] }; +var faFontAwesomeAlt = { prefix: 'fab', iconName: 'font-awesome-alt', icon: [448, 512, [], "f35c", "M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"] }; +var faFontAwesomeFlag = { prefix: 'fab', iconName: 'font-awesome-flag', icon: [448, 512, [], "f425", "M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"] }; +var faFonticons = { prefix: 'fab', iconName: 'fonticons', icon: [448, 512, [], "f280", "M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"] }; +var faFonticonsFi = { prefix: 'fab', iconName: 'fonticons-fi', icon: [384, 512, [], "f3a2", "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"] }; +var faFortAwesome = { prefix: 'fab', iconName: 'fort-awesome', icon: [448, 512, [], "f286", "M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"] }; +var faFortAwesomeAlt = { prefix: 'fab', iconName: 'fort-awesome-alt', icon: [512, 512, [], "f3a3", "M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"] }; +var faForumbee = { prefix: 'fab', iconName: 'forumbee', icon: [448, 512, [], "f211", "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"] }; +var faFoursquare = { prefix: 'fab', iconName: 'foursquare', icon: [368, 512, [], "f180", "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"] }; +var faFreeCodeCamp = { prefix: 'fab', iconName: 'free-code-camp', icon: [576, 512, [], "f2c5", "M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"] }; +var faFreebsd = { prefix: 'fab', iconName: 'freebsd', icon: [448, 512, [], "f3a4", "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"] }; +var faGetPocket = { prefix: 'fab', iconName: 'get-pocket', icon: [448, 512, [], "f265", "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"] }; +var faGg = { prefix: 'fab', iconName: 'gg', icon: [512, 512, [], "f260", "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"] }; +var faGgCircle = { prefix: 'fab', iconName: 'gg-circle', icon: [512, 512, [], "f261", "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"] }; +var faGit = { prefix: 'fab', iconName: 'git', icon: [448, 512, [], "f1d3", "M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"] }; +var faGitSquare = { prefix: 'fab', iconName: 'git-square', icon: [448, 512, [], "f1d2", "M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"] }; +var faGithub = { prefix: 'fab', iconName: 'github', icon: [496, 512, [], "f09b", "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"] }; +var faGithubAlt = { prefix: 'fab', iconName: 'github-alt', icon: [480, 512, [], "f113", "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"] }; +var faGithubSquare = { prefix: 'fab', iconName: 'github-square', icon: [448, 512, [], "f092", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"] }; +var faGitkraken = { prefix: 'fab', iconName: 'gitkraken', icon: [592, 512, [], "f3a6", "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"] }; +var faGitlab = { prefix: 'fab', iconName: 'gitlab', icon: [512, 512, [], "f296", "M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"] }; +var faGitter = { prefix: 'fab', iconName: 'gitter', icon: [384, 512, [], "f426", "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"] }; +var faGlide = { prefix: 'fab', iconName: 'glide', icon: [448, 512, [], "f2a5", "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"] }; +var faGlideG = { prefix: 'fab', iconName: 'glide-g', icon: [448, 512, [], "f2a6", "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"] }; +var faGofore = { prefix: 'fab', iconName: 'gofore', icon: [400, 512, [], "f3a7", "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"] }; +var faGoodreads = { prefix: 'fab', iconName: 'goodreads', icon: [448, 512, [], "f3a8", "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"] }; +var faGoodreadsG = { prefix: 'fab', iconName: 'goodreads-g', icon: [384, 512, [], "f3a9", "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"] }; +var faGoogle = { prefix: 'fab', iconName: 'google', icon: [488, 512, [], "f1a0", "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"] }; +var faGoogleDrive = { prefix: 'fab', iconName: 'google-drive', icon: [512, 512, [], "f3aa", "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"] }; +var faGooglePlay = { prefix: 'fab', iconName: 'google-play', icon: [512, 512, [], "f3ab", "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"] }; +var faGooglePlus = { prefix: 'fab', iconName: 'google-plus', icon: [496, 512, [], "f2b3", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"] }; +var faGooglePlusG = { prefix: 'fab', iconName: 'google-plus-g', icon: [640, 512, [], "f0d5", "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"] }; +var faGooglePlusSquare = { prefix: 'fab', iconName: 'google-plus-square', icon: [448, 512, [], "f0d4", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"] }; +var faGoogleWallet = { prefix: 'fab', iconName: 'google-wallet', icon: [448, 512, [], "f1ee", "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"] }; +var faGratipay = { prefix: 'fab', iconName: 'gratipay', icon: [496, 512, [], "f184", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"] }; +var faGrav = { prefix: 'fab', iconName: 'grav', icon: [512, 512, [], "f2d6", "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"] }; +var faGripfire = { prefix: 'fab', iconName: 'gripfire', icon: [384, 512, [], "f3ac", "M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"] }; +var faGrunt = { prefix: 'fab', iconName: 'grunt', icon: [384, 512, [], "f3ad", "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"] }; +var faGulp = { prefix: 'fab', iconName: 'gulp', icon: [256, 512, [], "f3ae", "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"] }; +var faHackerNews = { prefix: 'fab', iconName: 'hacker-news', icon: [448, 512, [], "f1d4", "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; +var faHackerNewsSquare = { prefix: 'fab', iconName: 'hacker-news-square', icon: [448, 512, [], "f3af", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; +var faHireAHelper = { prefix: 'fab', iconName: 'hire-a-helper', icon: [512, 512, [], "f3b0", "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"] }; +var faHooli = { prefix: 'fab', iconName: 'hooli', icon: [640, 512, [], "f427", "M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"] }; +var faHotjar = { prefix: 'fab', iconName: 'hotjar', icon: [448, 512, [], "f3b1", "M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"] }; +var faHouzz = { prefix: 'fab', iconName: 'houzz', icon: [320, 512, [], "f27c", "M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"] }; +var faHtml5 = { prefix: 'fab', iconName: 'html5', icon: [384, 512, [], "f13b", "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"] }; +var faHubspot = { prefix: 'fab', iconName: 'hubspot', icon: [512, 512, [], "f3b2", "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"] }; +var faImdb = { prefix: 'fab', iconName: 'imdb', icon: [448, 512, [], "f2d8", "M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"] }; +var faInstagram = { prefix: 'fab', iconName: 'instagram', icon: [448, 512, [], "f16d", "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"] }; +var faInternetExplorer = { prefix: 'fab', iconName: 'internet-explorer', icon: [512, 512, [], "f26b", "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"] }; +var faIoxhost = { prefix: 'fab', iconName: 'ioxhost', icon: [640, 512, [], "f208", "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"] }; +var faItunes = { prefix: 'fab', iconName: 'itunes', icon: [448, 512, [], "f3b4", "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"] }; +var faItunesNote = { prefix: 'fab', iconName: 'itunes-note', icon: [384, 512, [], "f3b5", "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"] }; +var faJenkins = { prefix: 'fab', iconName: 'jenkins', icon: [512, 512, [], "f3b6", "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"] }; +var faJoget = { prefix: 'fab', iconName: 'joget', icon: [496, 512, [], "f3b7", "M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"] }; +var faJoomla = { prefix: 'fab', iconName: 'joomla', icon: [448, 512, [], "f1aa", "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"] }; +var faJs = { prefix: 'fab', iconName: 'js', icon: [448, 512, [], "f3b8", "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; +var faJsSquare = { prefix: 'fab', iconName: 'js-square', icon: [512, 512, [], "f3b9", "M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; +var faJsfiddle = { prefix: 'fab', iconName: 'jsfiddle', icon: [576, 512, [], "f1cc", "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"] }; +var faKeycdn = { prefix: 'fab', iconName: 'keycdn', icon: [512, 512, [], "f3ba", "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"] }; +var faKickstarter = { prefix: 'fab', iconName: 'kickstarter', icon: [448, 512, [], "f3bb", "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"] }; +var faKickstarterK = { prefix: 'fab', iconName: 'kickstarter-k', icon: [384, 512, [], "f3bc", "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"] }; +var faLaravel = { prefix: 'fab', iconName: 'laravel', icon: [640, 512, [], "f3bd", "M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"] }; +var faLastfm = { prefix: 'fab', iconName: 'lastfm', icon: [512, 512, [], "f202", "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"] }; +var faLastfmSquare = { prefix: 'fab', iconName: 'lastfm-square', icon: [448, 512, [], "f203", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"] }; +var faLeanpub = { prefix: 'fab', iconName: 'leanpub', icon: [576, 512, [], "f212", "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"] }; +var faLess = { prefix: 'fab', iconName: 'less', icon: [640, 512, [], "f41d", "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"] }; +var faLine = { prefix: 'fab', iconName: 'line', icon: [448, 512, [], "f3c0", "M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"] }; +var faLinkedin = { prefix: 'fab', iconName: 'linkedin', icon: [448, 512, [], "f08c", "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"] }; +var faLinkedinIn = { prefix: 'fab', iconName: 'linkedin-in', icon: [448, 512, [], "f0e1", "M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"] }; +var faLinode = { prefix: 'fab', iconName: 'linode', icon: [448, 512, [], "f2b8", "M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"] }; +var faLinux = { prefix: 'fab', iconName: 'linux', icon: [448, 512, [], "f17c", "M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"] }; +var faLyft = { prefix: 'fab', iconName: 'lyft', icon: [512, 512, [], "f3c3", "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"] }; +var faMagento = { prefix: 'fab', iconName: 'magento', icon: [448, 512, [], "f3c4", "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"] }; +var faMaxcdn = { prefix: 'fab', iconName: 'maxcdn', icon: [512, 512, [], "f136", "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"] }; +var faMedapps = { prefix: 'fab', iconName: 'medapps', icon: [320, 512, [], "f3c6", "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"] }; +var faMedium = { prefix: 'fab', iconName: 'medium', icon: [448, 512, [], "f23a", "M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"] }; +var faMediumM = { prefix: 'fab', iconName: 'medium-m', icon: [512, 512, [], "f3c7", "M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"] }; +var faMedrt = { prefix: 'fab', iconName: 'medrt', icon: [544, 512, [], "f3c8", "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"] }; +var faMeetup = { prefix: 'fab', iconName: 'meetup', icon: [512, 512, [], "f2e0", "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"] }; +var faMicrosoft = { prefix: 'fab', iconName: 'microsoft', icon: [448, 512, [], "f3ca", "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"] }; +var faMix = { prefix: 'fab', iconName: 'mix', icon: [416, 512, [], "f3cb", "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"] }; +var faMixcloud = { prefix: 'fab', iconName: 'mixcloud', icon: [640, 512, [], "f289", "M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"] }; +var faMizuni = { prefix: 'fab', iconName: 'mizuni', icon: [496, 512, [], "f3cc", "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"] }; +var faModx = { prefix: 'fab', iconName: 'modx', icon: [448, 512, [], "f285", "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"] }; +var faMonero = { prefix: 'fab', iconName: 'monero', icon: [496, 512, [], "f3d0", "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"] }; +var faNapster = { prefix: 'fab', iconName: 'napster', icon: [496, 512, [], "f3d2", "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"] }; +var faNintendoSwitch = { prefix: 'fab', iconName: 'nintendo-switch', icon: [448, 512, [], "f418", "M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"] }; +var faNode = { prefix: 'fab', iconName: 'node', icon: [640, 512, [], "f419", "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"] }; +var faNodeJs = { prefix: 'fab', iconName: 'node-js', icon: [448, 512, [], "f3d3", "M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"] }; +var faNpm = { prefix: 'fab', iconName: 'npm', icon: [576, 512, [], "f3d4", "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"] }; +var faNs8 = { prefix: 'fab', iconName: 'ns8', icon: [640, 512, [], "f3d5", "M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"] }; +var faNutritionix = { prefix: 'fab', iconName: 'nutritionix', icon: [400, 512, [], "f3d6", "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"] }; +var faOdnoklassniki = { prefix: 'fab', iconName: 'odnoklassniki', icon: [320, 512, [], "f263", "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"] }; +var faOdnoklassnikiSquare = { prefix: 'fab', iconName: 'odnoklassniki-square', icon: [448, 512, [], "f264", "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"] }; +var faOpencart = { prefix: 'fab', iconName: 'opencart', icon: [640, 512, [], "f23d", "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"] }; +var faOpenid = { prefix: 'fab', iconName: 'openid', icon: [448, 512, [], "f19b", "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"] }; +var faOpera = { prefix: 'fab', iconName: 'opera', icon: [496, 512, [], "f26a", "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"] }; +var faOptinMonster = { prefix: 'fab', iconName: 'optin-monster', icon: [576, 512, [], "f23c", "M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"] }; +var faOsi = { prefix: 'fab', iconName: 'osi', icon: [495, 512, [], "f41a", "M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"] }; +var faPage4 = { prefix: 'fab', iconName: 'page4', icon: [496, 512, [], "f3d7", "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"] }; +var faPagelines = { prefix: 'fab', iconName: 'pagelines', icon: [384, 512, [], "f18c", "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"] }; +var faPalfed = { prefix: 'fab', iconName: 'palfed', icon: [560, 512, [], "f3d8", "M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"] }; +var faPatreon = { prefix: 'fab', iconName: 'patreon', icon: [512, 512, [], "f3d9", "M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"] }; +var faPaypal = { prefix: 'fab', iconName: 'paypal', icon: [384, 512, [], "f1ed", "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"] }; +var faPeriscope = { prefix: 'fab', iconName: 'periscope', icon: [448, 512, [], "f3da", "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"] }; +var faPhabricator = { prefix: 'fab', iconName: 'phabricator', icon: [496, 512, [], "f3db", "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"] }; +var faPhoenixFramework = { prefix: 'fab', iconName: 'phoenix-framework', icon: [640, 512, [], "f3dc", "M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"] }; +var faPiedPiper = { prefix: 'fab', iconName: 'pied-piper', icon: [640, 512, [], "f2ae", "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"] }; +var faPiedPiperAlt = { prefix: 'fab', iconName: 'pied-piper-alt', icon: [576, 512, [], "f1a8", "M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"] }; +var faPiedPiperPp = { prefix: 'fab', iconName: 'pied-piper-pp', icon: [448, 512, [], "f1a7", "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"] }; +var faPinterest = { prefix: 'fab', iconName: 'pinterest', icon: [496, 512, [], "f0d2", "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"] }; +var faPinterestP = { prefix: 'fab', iconName: 'pinterest-p', icon: [384, 512, [], "f231", "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"] }; +var faPinterestSquare = { prefix: 'fab', iconName: 'pinterest-square', icon: [448, 512, [], "f0d3", "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; +var faPlaystation = { prefix: 'fab', iconName: 'playstation', icon: [576, 512, [], "f3df", "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"] }; +var faProductHunt = { prefix: 'fab', iconName: 'product-hunt', icon: [512, 512, [], "f288", "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"] }; +var faPushed = { prefix: 'fab', iconName: 'pushed', icon: [432, 512, [], "f3e1", "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"] }; +var faPython = { prefix: 'fab', iconName: 'python', icon: [448, 512, [], "f3e2", "M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"] }; +var faQq = { prefix: 'fab', iconName: 'qq', icon: [448, 512, [], "f1d6", "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"] }; +var faQuora = { prefix: 'fab', iconName: 'quora', icon: [448, 512, [], "f2c4", "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"] }; +var faRavelry = { prefix: 'fab', iconName: 'ravelry', icon: [512, 512, [], "f2d9", "M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"] }; +var faReact = { prefix: 'fab', iconName: 'react', icon: [512, 512, [], "f41b", "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"] }; +var faRebel = { prefix: 'fab', iconName: 'rebel', icon: [512, 512, [], "f1d0", "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"] }; +var faRedRiver = { prefix: 'fab', iconName: 'red-river', icon: [448, 512, [], "f3e3", "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"] }; +var faReddit = { prefix: 'fab', iconName: 'reddit', icon: [512, 512, [], "f1a1", "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"] }; +var faRedditAlien = { prefix: 'fab', iconName: 'reddit-alien', icon: [512, 512, [], "f281", "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"] }; +var faRedditSquare = { prefix: 'fab', iconName: 'reddit-square', icon: [448, 512, [], "f1a2", "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"] }; +var faRendact = { prefix: 'fab', iconName: 'rendact', icon: [496, 512, [], "f3e4", "M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"] }; +var faRenren = { prefix: 'fab', iconName: 'renren', icon: [512, 512, [], "f18b", "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"] }; +var faReplyd = { prefix: 'fab', iconName: 'replyd', icon: [448, 512, [], "f3e6", "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"] }; +var faResolving = { prefix: 'fab', iconName: 'resolving', icon: [496, 512, [], "f3e7", "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"] }; +var faRocketchat = { prefix: 'fab', iconName: 'rocketchat', icon: [448, 512, [], "f3e8", "M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"] }; +var faRockrms = { prefix: 'fab', iconName: 'rockrms', icon: [496, 512, [], "f3e9", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"] }; +var faSafari = { prefix: 'fab', iconName: 'safari', icon: [512, 512, [], "f267", "M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"] }; +var faSass = { prefix: 'fab', iconName: 'sass', icon: [640, 512, [], "f41e", "M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"] }; +var faSchlix = { prefix: 'fab', iconName: 'schlix', icon: [448, 512, [], "f3ea", "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"] }; +var faScribd = { prefix: 'fab', iconName: 'scribd', icon: [384, 512, [], "f28a", "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"] }; +var faSearchengin = { prefix: 'fab', iconName: 'searchengin', icon: [460, 512, [], "f3eb", "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"] }; +var faSellcast = { prefix: 'fab', iconName: 'sellcast', icon: [448, 512, [], "f2da", "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"] }; +var faSellsy = { prefix: 'fab', iconName: 'sellsy', icon: [640, 512, [], "f213", "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"] }; +var faServicestack = { prefix: 'fab', iconName: 'servicestack', icon: [496, 512, [], "f3ec", "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"] }; +var faShirtsinbulk = { prefix: 'fab', iconName: 'shirtsinbulk', icon: [448, 512, [], "f214", "M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"] }; +var faSimplybuilt = { prefix: 'fab', iconName: 'simplybuilt', icon: [512, 512, [], "f215", "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"] }; +var faSistrix = { prefix: 'fab', iconName: 'sistrix', icon: [448, 512, [], "f3ee", "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"] }; +var faSkyatlas = { prefix: 'fab', iconName: 'skyatlas', icon: [576, 512, [], "f216", "M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"] }; +var faSkype = { prefix: 'fab', iconName: 'skype', icon: [448, 512, [], "f17e", "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"] }; +var faSlack = { prefix: 'fab', iconName: 'slack', icon: [448, 512, [], "f198", "M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"] }; +var faSlackHash = { prefix: 'fab', iconName: 'slack-hash', icon: [448, 512, [], "f3ef", "M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"] }; +var faSlideshare = { prefix: 'fab', iconName: 'slideshare', icon: [512, 512, [], "f1e7", "M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"] }; +var faSnapchat = { prefix: 'fab', iconName: 'snapchat', icon: [496, 512, [], "f2ab", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; +var faSnapchatGhost = { prefix: 'fab', iconName: 'snapchat-ghost', icon: [512, 512, [], "f2ac", "M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"] }; +var faSnapchatSquare = { prefix: 'fab', iconName: 'snapchat-square', icon: [448, 512, [], "f2ad", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; +var faSoundcloud = { prefix: 'fab', iconName: 'soundcloud', icon: [640, 512, [], "f1be", "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"] }; +var faSpeakap = { prefix: 'fab', iconName: 'speakap', icon: [448, 512, [], "f3f3", "M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"] }; +var faSpotify = { prefix: 'fab', iconName: 'spotify', icon: [496, 512, [], "f1bc", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"] }; +var faStackExchange = { prefix: 'fab', iconName: 'stack-exchange', icon: [448, 512, [], "f18d", "M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"] }; +var faStackOverflow = { prefix: 'fab', iconName: 'stack-overflow', icon: [384, 512, [], "f16c", "M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"] }; +var faStaylinked = { prefix: 'fab', iconName: 'staylinked', icon: [440, 512, [], "f3f5", "M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"] }; +var faSteam = { prefix: 'fab', iconName: 'steam', icon: [496, 512, [], "f1b6", "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"] }; +var faSteamSquare = { prefix: 'fab', iconName: 'steam-square', icon: [448, 512, [], "f1b7", "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"] }; +var faSteamSymbol = { prefix: 'fab', iconName: 'steam-symbol', icon: [448, 512, [], "f3f6", "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"] }; +var faStickerMule = { prefix: 'fab', iconName: 'sticker-mule', icon: [576, 512, [], "f3f7", "M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"] }; +var faStrava = { prefix: 'fab', iconName: 'strava', icon: [369, 512, [], "f428", "M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"] }; +var faStripe = { prefix: 'fab', iconName: 'stripe', icon: [640, 512, [], "f429", "M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"] }; +var faStripeS = { prefix: 'fab', iconName: 'stripe-s', icon: [362, 512, [], "f42a", "M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"] }; +var faStudiovinari = { prefix: 'fab', iconName: 'studiovinari', icon: [512, 512, [], "f3f8", "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"] }; +var faStumbleupon = { prefix: 'fab', iconName: 'stumbleupon', icon: [512, 512, [], "f1a4", "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"] }; +var faStumbleuponCircle = { prefix: 'fab', iconName: 'stumbleupon-circle', icon: [496, 512, [], "f1a3", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"] }; +var faSuperpowers = { prefix: 'fab', iconName: 'superpowers', icon: [448, 512, [], "f2dd", "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"] }; +var faSupple = { prefix: 'fab', iconName: 'supple', icon: [640, 512, [], "f3f9", "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"] }; +var faTelegram = { prefix: 'fab', iconName: 'telegram', icon: [496, 512, [], "f2c6", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"] }; +var faTelegramPlane = { prefix: 'fab', iconName: 'telegram-plane', icon: [448, 512, [], "f3fe", "M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"] }; +var faTencentWeibo = { prefix: 'fab', iconName: 'tencent-weibo', icon: [384, 512, [], "f1d5", "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"] }; +var faThemeisle = { prefix: 'fab', iconName: 'themeisle', icon: [512, 512, [], "f2b2", "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"] }; +var faTrello = { prefix: 'fab', iconName: 'trello', icon: [448, 512, [], "f181", "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"] }; +var faTripadvisor = { prefix: 'fab', iconName: 'tripadvisor', icon: [576, 512, [], "f262", "M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"] }; +var faTumblr = { prefix: 'fab', iconName: 'tumblr', icon: [320, 512, [], "f173", "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"] }; +var faTumblrSquare = { prefix: 'fab', iconName: 'tumblr-square', icon: [448, 512, [], "f174", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"] }; +var faTwitch = { prefix: 'fab', iconName: 'twitch', icon: [448, 512, [], "f1e8", "M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"] }; +var faTwitter = { prefix: 'fab', iconName: 'twitter', icon: [512, 512, [], "f099", "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"] }; +var faTwitterSquare = { prefix: 'fab', iconName: 'twitter-square', icon: [448, 512, [], "f081", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"] }; +var faTypo3 = { prefix: 'fab', iconName: 'typo3', icon: [433, 512, [], "f42b", "M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"] }; +var faUber = { prefix: 'fab', iconName: 'uber', icon: [448, 512, [], "f402", "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"] }; +var faUikit = { prefix: 'fab', iconName: 'uikit', icon: [448, 512, [], "f403", "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"] }; +var faUniregistry = { prefix: 'fab', iconName: 'uniregistry', icon: [384, 512, [], "f404", "M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"] }; +var faUntappd = { prefix: 'fab', iconName: 'untappd', icon: [640, 512, [], "f405", "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"] }; +var faUsb = { prefix: 'fab', iconName: 'usb', icon: [640, 512, [], "f287", "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"] }; +var faUssunnah = { prefix: 'fab', iconName: 'ussunnah', icon: [512, 512, [], "f407", "M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"] }; +var faVaadin = { prefix: 'fab', iconName: 'vaadin', icon: [448, 512, [], "f408", "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"] }; +var faViacoin = { prefix: 'fab', iconName: 'viacoin', icon: [384, 512, [], "f237", "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"] }; +var faViadeo = { prefix: 'fab', iconName: 'viadeo', icon: [448, 512, [], "f2a9", "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"] }; +var faViadeoSquare = { prefix: 'fab', iconName: 'viadeo-square', icon: [448, 512, [], "f2aa", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"] }; +var faViber = { prefix: 'fab', iconName: 'viber', icon: [512, 512, [], "f409", "M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"] }; +var faVimeo = { prefix: 'fab', iconName: 'vimeo', icon: [448, 512, [], "f40a", "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"] }; +var faVimeoSquare = { prefix: 'fab', iconName: 'vimeo-square', icon: [448, 512, [], "f194", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"] }; +var faVimeoV = { prefix: 'fab', iconName: 'vimeo-v', icon: [448, 512, [], "f27d", "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"] }; +var faVine = { prefix: 'fab', iconName: 'vine', icon: [384, 512, [], "f1ca", "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"] }; +var faVk = { prefix: 'fab', iconName: 'vk', icon: [576, 512, [], "f189", "M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"] }; +var faVnv = { prefix: 'fab', iconName: 'vnv', icon: [640, 512, [], "f40b", "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"] }; +var faVuejs = { prefix: 'fab', iconName: 'vuejs', icon: [448, 512, [], "f41f", "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"] }; +var faWeibo = { prefix: 'fab', iconName: 'weibo', icon: [512, 512, [], "f18a", "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"] }; +var faWeixin = { prefix: 'fab', iconName: 'weixin', icon: [576, 512, [], "f1d7", "M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"] }; +var faWhatsapp = { prefix: 'fab', iconName: 'whatsapp', icon: [448, 512, [], "f232", "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"] }; +var faWhatsappSquare = { prefix: 'fab', iconName: 'whatsapp-square', icon: [448, 512, [], "f40c", "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"] }; +var faWhmcs = { prefix: 'fab', iconName: 'whmcs', icon: [448, 512, [], "f40d", "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"] }; +var faWikipediaW = { prefix: 'fab', iconName: 'wikipedia-w', icon: [640, 512, [], "f266", "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"] }; +var faWindows = { prefix: 'fab', iconName: 'windows', icon: [448, 512, [], "f17a", "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"] }; +var faWordpress = { prefix: 'fab', iconName: 'wordpress', icon: [512, 512, [], "f19a", "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"] }; +var faWordpressSimple = { prefix: 'fab', iconName: 'wordpress-simple', icon: [512, 512, [], "f411", "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"] }; +var faWpbeginner = { prefix: 'fab', iconName: 'wpbeginner', icon: [512, 512, [], "f297", "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"] }; +var faWpexplorer = { prefix: 'fab', iconName: 'wpexplorer', icon: [512, 512, [], "f2de", "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"] }; +var faWpforms = { prefix: 'fab', iconName: 'wpforms', icon: [448, 512, [], "f298", "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"] }; +var faXbox = { prefix: 'fab', iconName: 'xbox', icon: [512, 512, [], "f412", "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"] }; +var faXing = { prefix: 'fab', iconName: 'xing', icon: [384, 512, [], "f168", "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"] }; +var faXingSquare = { prefix: 'fab', iconName: 'xing-square', icon: [448, 512, [], "f169", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"] }; +var faYCombinator = { prefix: 'fab', iconName: 'y-combinator', icon: [448, 512, [], "f23b", "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"] }; +var faYahoo = { prefix: 'fab', iconName: 'yahoo', icon: [360, 512, [], "f19e", "M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"] }; +var faYandex = { prefix: 'fab', iconName: 'yandex', icon: [256, 512, [], "f413", "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"] }; +var faYandexInternational = { prefix: 'fab', iconName: 'yandex-international', icon: [320, 512, [], "f414", "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"] }; +var faYelp = { prefix: 'fab', iconName: 'yelp', icon: [384, 512, [], "f1e9", "M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"] }; +var faYoast = { prefix: 'fab', iconName: 'yoast', icon: [448, 512, [], "f2b1", "M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"] }; +var faYoutube = { prefix: 'fab', iconName: 'youtube', icon: [576, 512, [], "f167", "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"] }; +var icons$1 = { + fa500px: fa500px, + faAccessibleIcon: faAccessibleIcon, + faAccusoft: faAccusoft, + faAdn: faAdn, + faAdversal: faAdversal, + faAffiliatetheme: faAffiliatetheme, + faAlgolia: faAlgolia, + faAmazon: faAmazon, + faAmilia: faAmilia, + faAndroid: faAndroid, + faAngellist: faAngellist, + faAngrycreative: faAngrycreative, + faAngular: faAngular, + faAppStore: faAppStore, + faAppStoreIos: faAppStoreIos, + faApper: faApper, + faApple: faApple, + faApplePay: faApplePay, + faAsymmetrik: faAsymmetrik, + faAudible: faAudible, + faAutoprefixer: faAutoprefixer, + faAvianex: faAvianex, + faAviato: faAviato, + faAws: faAws, + faBandcamp: faBandcamp, + faBehance: faBehance, + faBehanceSquare: faBehanceSquare, + faBimobject: faBimobject, + faBitbucket: faBitbucket, + faBitcoin: faBitcoin, + faBity: faBity, + faBlackTie: faBlackTie, + faBlackberry: faBlackberry, + faBlogger: faBlogger, + faBloggerB: faBloggerB, + faBluetooth: faBluetooth, + faBluetoothB: faBluetoothB, + faBtc: faBtc, + faBuromobelexperte: faBuromobelexperte, + faBuysellads: faBuysellads, + faCcAmex: faCcAmex, + faCcApplePay: faCcApplePay, + faCcDinersClub: faCcDinersClub, + faCcDiscover: faCcDiscover, + faCcJcb: faCcJcb, + faCcMastercard: faCcMastercard, + faCcPaypal: faCcPaypal, + faCcStripe: faCcStripe, + faCcVisa: faCcVisa, + faCentercode: faCentercode, + faChrome: faChrome, + faCloudscale: faCloudscale, + faCloudsmith: faCloudsmith, + faCloudversify: faCloudversify, + faCodepen: faCodepen, + faCodiepie: faCodiepie, + faConnectdevelop: faConnectdevelop, + faContao: faContao, + faCpanel: faCpanel, + faCreativeCommons: faCreativeCommons, + faCss3: faCss3, + faCss3Alt: faCss3Alt, + faCuttlefish: faCuttlefish, + faDAndD: faDAndD, + faDashcube: faDashcube, + faDelicious: faDelicious, + faDeploydog: faDeploydog, + faDeskpro: faDeskpro, + faDeviantart: faDeviantart, + faDigg: faDigg, + faDigitalOcean: faDigitalOcean, + faDiscord: faDiscord, + faDiscourse: faDiscourse, + faDochub: faDochub, + faDocker: faDocker, + faDraft2digital: faDraft2digital, + faDribbble: faDribbble, + faDribbbleSquare: faDribbbleSquare, + faDropbox: faDropbox, + faDrupal: faDrupal, + faDyalog: faDyalog, + faEarlybirds: faEarlybirds, + faEdge: faEdge, + faEmber: faEmber, + faEmpire: faEmpire, + faEnvira: faEnvira, + faErlang: faErlang, + faEtsy: faEtsy, + faExpeditedssl: faExpeditedssl, + faFacebook: faFacebook, + faFacebookF: faFacebookF, + faFacebookMessenger: faFacebookMessenger, + faFacebookSquare: faFacebookSquare, + faFirefox: faFirefox, + faFirstOrder: faFirstOrder, + faFirstdraft: faFirstdraft, + faFlickr: faFlickr, + faFly: faFly, + faFontAwesome: faFontAwesome, + faFontAwesomeAlt: faFontAwesomeAlt, + faFontAwesomeFlag: faFontAwesomeFlag, + faFonticons: faFonticons, + faFonticonsFi: faFonticonsFi, + faFortAwesome: faFortAwesome, + faFortAwesomeAlt: faFortAwesomeAlt, + faForumbee: faForumbee, + faFoursquare: faFoursquare, + faFreeCodeCamp: faFreeCodeCamp, + faFreebsd: faFreebsd, + faGetPocket: faGetPocket, + faGg: faGg, + faGgCircle: faGgCircle, + faGit: faGit, + faGitSquare: faGitSquare, + faGithub: faGithub, + faGithubAlt: faGithubAlt, + faGithubSquare: faGithubSquare, + faGitkraken: faGitkraken, + faGitlab: faGitlab, + faGitter: faGitter, + faGlide: faGlide, + faGlideG: faGlideG, + faGofore: faGofore, + faGoodreads: faGoodreads, + faGoodreadsG: faGoodreadsG, + faGoogle: faGoogle, + faGoogleDrive: faGoogleDrive, + faGooglePlay: faGooglePlay, + faGooglePlus: faGooglePlus, + faGooglePlusG: faGooglePlusG, + faGooglePlusSquare: faGooglePlusSquare, + faGoogleWallet: faGoogleWallet, + faGratipay: faGratipay, + faGrav: faGrav, + faGripfire: faGripfire, + faGrunt: faGrunt, + faGulp: faGulp, + faHackerNews: faHackerNews, + faHackerNewsSquare: faHackerNewsSquare, + faHireAHelper: faHireAHelper, + faHooli: faHooli, + faHotjar: faHotjar, + faHouzz: faHouzz, + faHtml5: faHtml5, + faHubspot: faHubspot, + faImdb: faImdb, + faInstagram: faInstagram, + faInternetExplorer: faInternetExplorer, + faIoxhost: faIoxhost, + faItunes: faItunes, + faItunesNote: faItunesNote, + faJenkins: faJenkins, + faJoget: faJoget, + faJoomla: faJoomla, + faJs: faJs, + faJsSquare: faJsSquare, + faJsfiddle: faJsfiddle, + faKeycdn: faKeycdn, + faKickstarter: faKickstarter, + faKickstarterK: faKickstarterK, + faLaravel: faLaravel, + faLastfm: faLastfm, + faLastfmSquare: faLastfmSquare, + faLeanpub: faLeanpub, + faLess: faLess, + faLine: faLine, + faLinkedin: faLinkedin, + faLinkedinIn: faLinkedinIn, + faLinode: faLinode, + faLinux: faLinux, + faLyft: faLyft, + faMagento: faMagento, + faMaxcdn: faMaxcdn, + faMedapps: faMedapps, + faMedium: faMedium, + faMediumM: faMediumM, + faMedrt: faMedrt, + faMeetup: faMeetup, + faMicrosoft: faMicrosoft, + faMix: faMix, + faMixcloud: faMixcloud, + faMizuni: faMizuni, + faModx: faModx, + faMonero: faMonero, + faNapster: faNapster, + faNintendoSwitch: faNintendoSwitch, + faNode: faNode, + faNodeJs: faNodeJs, + faNpm: faNpm, + faNs8: faNs8, + faNutritionix: faNutritionix, + faOdnoklassniki: faOdnoklassniki, + faOdnoklassnikiSquare: faOdnoklassnikiSquare, + faOpencart: faOpencart, + faOpenid: faOpenid, + faOpera: faOpera, + faOptinMonster: faOptinMonster, + faOsi: faOsi, + faPage4: faPage4, + faPagelines: faPagelines, + faPalfed: faPalfed, + faPatreon: faPatreon, + faPaypal: faPaypal, + faPeriscope: faPeriscope, + faPhabricator: faPhabricator, + faPhoenixFramework: faPhoenixFramework, + faPiedPiper: faPiedPiper, + faPiedPiperAlt: faPiedPiperAlt, + faPiedPiperPp: faPiedPiperPp, + faPinterest: faPinterest, + faPinterestP: faPinterestP, + faPinterestSquare: faPinterestSquare, + faPlaystation: faPlaystation, + faProductHunt: faProductHunt, + faPushed: faPushed, + faPython: faPython, + faQq: faQq, + faQuora: faQuora, + faRavelry: faRavelry, + faReact: faReact, + faRebel: faRebel, + faRedRiver: faRedRiver, + faReddit: faReddit, + faRedditAlien: faRedditAlien, + faRedditSquare: faRedditSquare, + faRendact: faRendact, + faRenren: faRenren, + faReplyd: faReplyd, + faResolving: faResolving, + faRocketchat: faRocketchat, + faRockrms: faRockrms, + faSafari: faSafari, + faSass: faSass, + faSchlix: faSchlix, + faScribd: faScribd, + faSearchengin: faSearchengin, + faSellcast: faSellcast, + faSellsy: faSellsy, + faServicestack: faServicestack, + faShirtsinbulk: faShirtsinbulk, + faSimplybuilt: faSimplybuilt, + faSistrix: faSistrix, + faSkyatlas: faSkyatlas, + faSkype: faSkype, + faSlack: faSlack, + faSlackHash: faSlackHash, + faSlideshare: faSlideshare, + faSnapchat: faSnapchat, + faSnapchatGhost: faSnapchatGhost, + faSnapchatSquare: faSnapchatSquare, + faSoundcloud: faSoundcloud, + faSpeakap: faSpeakap, + faSpotify: faSpotify, + faStackExchange: faStackExchange, + faStackOverflow: faStackOverflow, + faStaylinked: faStaylinked, + faSteam: faSteam, + faSteamSquare: faSteamSquare, + faSteamSymbol: faSteamSymbol, + faStickerMule: faStickerMule, + faStrava: faStrava, + faStripe: faStripe, + faStripeS: faStripeS, + faStudiovinari: faStudiovinari, + faStumbleupon: faStumbleupon, + faStumbleuponCircle: faStumbleuponCircle, + faSuperpowers: faSuperpowers, + faSupple: faSupple, + faTelegram: faTelegram, + faTelegramPlane: faTelegramPlane, + faTencentWeibo: faTencentWeibo, + faThemeisle: faThemeisle, + faTrello: faTrello, + faTripadvisor: faTripadvisor, + faTumblr: faTumblr, + faTumblrSquare: faTumblrSquare, + faTwitch: faTwitch, + faTwitter: faTwitter, + faTwitterSquare: faTwitterSquare, + faTypo3: faTypo3, + faUber: faUber, + faUikit: faUikit, + faUniregistry: faUniregistry, + faUntappd: faUntappd, + faUsb: faUsb, + faUssunnah: faUssunnah, + faVaadin: faVaadin, + faViacoin: faViacoin, + faViadeo: faViadeo, + faViadeoSquare: faViadeoSquare, + faViber: faViber, + faVimeo: faVimeo, + faVimeoSquare: faVimeoSquare, + faVimeoV: faVimeoV, + faVine: faVine, + faVk: faVk, + faVnv: faVnv, + faVuejs: faVuejs, + faWeibo: faWeibo, + faWeixin: faWeixin, + faWhatsapp: faWhatsapp, + faWhatsappSquare: faWhatsappSquare, + faWhmcs: faWhmcs, + faWikipediaW: faWikipediaW, + faWindows: faWindows, + faWordpress: faWordpress, + faWordpressSimple: faWordpressSimple, + faWpbeginner: faWpbeginner, + faWpexplorer: faWpexplorer, + faWpforms: faWpforms, + faXbox: faXbox, + faXing: faXing, + faXingSquare: faXingSquare, + faYCombinator: faYCombinator, + faYahoo: faYahoo, + faYandex: faYandex, + faYandexInternational: faYandexInternational, + faYelp: faYelp, + faYoast: faYoast, + faYoutube: faYoutube +}; + +export { prefix, fa500px, faAccessibleIcon, faAccusoft, faAdn, faAdversal, faAffiliatetheme, faAlgolia, faAmazon, faAmilia, faAndroid, faAngellist, faAngrycreative, faAngular, faAppStore, faAppStoreIos, faApper, faApple, faApplePay, faAsymmetrik, faAudible, faAutoprefixer, faAvianex, faAviato, faAws, faBandcamp, faBehance, faBehanceSquare, faBimobject, faBitbucket, faBitcoin, faBity, faBlackTie, faBlackberry, faBlogger, faBloggerB, faBluetooth, faBluetoothB, faBtc, faBuromobelexperte, faBuysellads, faCcAmex, faCcApplePay, faCcDinersClub, faCcDiscover, faCcJcb, faCcMastercard, faCcPaypal, faCcStripe, faCcVisa, faCentercode, faChrome, faCloudscale, faCloudsmith, faCloudversify, faCodepen, faCodiepie, faConnectdevelop, faContao, faCpanel, faCreativeCommons, faCss3, faCss3Alt, faCuttlefish, faDAndD, faDashcube, faDelicious, faDeploydog, faDeskpro, faDeviantart, faDigg, faDigitalOcean, faDiscord, faDiscourse, faDochub, faDocker, faDraft2digital, faDribbble, faDribbbleSquare, faDropbox, faDrupal, faDyalog, faEarlybirds, faEdge, faEmber, faEmpire, faEnvira, faErlang, faEtsy, faExpeditedssl, faFacebook, faFacebookF, faFacebookMessenger, faFacebookSquare, faFirefox, faFirstOrder, faFirstdraft, faFlickr, faFly, faFontAwesome, faFontAwesomeAlt, faFontAwesomeFlag, faFonticons, faFonticonsFi, faFortAwesome, faFortAwesomeAlt, faForumbee, faFoursquare, faFreeCodeCamp, faFreebsd, faGetPocket, faGg, faGgCircle, faGit, faGitSquare, faGithub, faGithubAlt, faGithubSquare, faGitkraken, faGitlab, faGitter, faGlide, faGlideG, faGofore, faGoodreads, faGoodreadsG, faGoogle, faGoogleDrive, faGooglePlay, faGooglePlus, faGooglePlusG, faGooglePlusSquare, faGoogleWallet, faGratipay, faGrav, faGripfire, faGrunt, faGulp, faHackerNews, faHackerNewsSquare, faHireAHelper, faHooli, faHotjar, faHouzz, faHtml5, faHubspot, faImdb, faInstagram, faInternetExplorer, faIoxhost, faItunes, faItunesNote, faJenkins, faJoget, faJoomla, faJs, faJsSquare, faJsfiddle, faKeycdn, faKickstarter, faKickstarterK, faLaravel, faLastfm, faLastfmSquare, faLeanpub, faLess, faLine, faLinkedin, faLinkedinIn, faLinode, faLinux, faLyft, faMagento, faMaxcdn, faMedapps, faMedium, faMediumM, faMedrt, faMeetup, faMicrosoft, faMix, faMixcloud, faMizuni, faModx, faMonero, faNapster, faNintendoSwitch, faNode, faNodeJs, faNpm, faNs8, faNutritionix, faOdnoklassniki, faOdnoklassnikiSquare, faOpencart, faOpenid, faOpera, faOptinMonster, faOsi, faPage4, faPagelines, faPalfed, faPatreon, faPaypal, faPeriscope, faPhabricator, faPhoenixFramework, faPiedPiper, faPiedPiperAlt, faPiedPiperPp, faPinterest, faPinterestP, faPinterestSquare, faPlaystation, faProductHunt, faPushed, faPython, faQq, faQuora, faRavelry, faReact, faRebel, faRedRiver, faReddit, faRedditAlien, faRedditSquare, faRendact, faRenren, faReplyd, faResolving, faRocketchat, faRockrms, faSafari, faSass, faSchlix, faScribd, faSearchengin, faSellcast, faSellsy, faServicestack, faShirtsinbulk, faSimplybuilt, faSistrix, faSkyatlas, faSkype, faSlack, faSlackHash, faSlideshare, faSnapchat, faSnapchatGhost, faSnapchatSquare, faSoundcloud, faSpeakap, faSpotify, faStackExchange, faStackOverflow, faStaylinked, faSteam, faSteamSquare, faSteamSymbol, faStickerMule, faStrava, faStripe, faStripeS, faStudiovinari, faStumbleupon, faStumbleuponCircle, faSuperpowers, faSupple, faTelegram, faTelegramPlane, faTencentWeibo, faThemeisle, faTrello, faTripadvisor, faTumblr, faTumblrSquare, faTwitch, faTwitter, faTwitterSquare, faTypo3, faUber, faUikit, faUniregistry, faUntappd, faUsb, faUssunnah, faVaadin, faViacoin, faViadeo, faViadeoSquare, faViber, faVimeo, faVimeoSquare, faVimeoV, faVine, faVk, faVnv, faVuejs, faWeibo, faWeixin, faWhatsapp, faWhatsappSquare, faWhmcs, faWikipediaW, faWindows, faWordpress, faWordpressSimple, faWpbeginner, faWpexplorer, faWpforms, faXbox, faXing, faXingSquare, faYCombinator, faYahoo, faYandex, faYandexInternational, faYelp, faYoast, faYoutube }; +export default icons$1; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.js new file mode 100644 index 000000000..dd61e72ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/index.js @@ -0,0 +1,980 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global['fontawesome-free-brands'] = {}))); +}(this, (function (exports) { 'use strict'; + +var prefix = "fab"; +var fa500px = { prefix: 'fab', iconName: '500px', icon: [448, 512, [], "f26e", "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"] }; +var faAccessibleIcon = { prefix: 'fab', iconName: 'accessible-icon', icon: [448, 512, [], "f368", "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"] }; +var faAccusoft = { prefix: 'fab', iconName: 'accusoft', icon: [640, 512, [], "f369", "M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"] }; +var faAdn = { prefix: 'fab', iconName: 'adn', icon: [496, 512, [], "f170", "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"] }; +var faAdversal = { prefix: 'fab', iconName: 'adversal', icon: [512, 512, [], "f36a", "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"] }; +var faAffiliatetheme = { prefix: 'fab', iconName: 'affiliatetheme', icon: [512, 512, [], "f36b", "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"] }; +var faAlgolia = { prefix: 'fab', iconName: 'algolia', icon: [448, 512, [], "f36c", "M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"] }; +var faAmazon = { prefix: 'fab', iconName: 'amazon', icon: [448, 512, [], "f270", "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"] }; +var faAmilia = { prefix: 'fab', iconName: 'amilia', icon: [448, 512, [], "f36d", "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"] }; +var faAndroid = { prefix: 'fab', iconName: 'android', icon: [448, 512, [], "f17b", "M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"] }; +var faAngellist = { prefix: 'fab', iconName: 'angellist', icon: [448, 512, [], "f209", "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"] }; +var faAngrycreative = { prefix: 'fab', iconName: 'angrycreative', icon: [640, 512, [], "f36e", "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"] }; +var faAngular = { prefix: 'fab', iconName: 'angular', icon: [415, 512, [], "f420", "M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"] }; +var faAppStore = { prefix: 'fab', iconName: 'app-store', icon: [512, 512, [], "f36f", "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"] }; +var faAppStoreIos = { prefix: 'fab', iconName: 'app-store-ios', icon: [448, 512, [], "f370", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"] }; +var faApper = { prefix: 'fab', iconName: 'apper', icon: [640, 512, [], "f371", "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"] }; +var faApple = { prefix: 'fab', iconName: 'apple', icon: [448, 512, [], "f179", "M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"] }; +var faApplePay = { prefix: 'fab', iconName: 'apple-pay', icon: [640, 512, [], "f415", "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"] }; +var faAsymmetrik = { prefix: 'fab', iconName: 'asymmetrik', icon: [576, 512, [], "f372", "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"] }; +var faAudible = { prefix: 'fab', iconName: 'audible', icon: [640, 512, [], "f373", "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"] }; +var faAutoprefixer = { prefix: 'fab', iconName: 'autoprefixer', icon: [640, 512, [], "f41c", "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"] }; +var faAvianex = { prefix: 'fab', iconName: 'avianex', icon: [512, 512, [], "f374", "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"] }; +var faAviato = { prefix: 'fab', iconName: 'aviato', icon: [640, 512, [], "f421", "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"] }; +var faAws = { prefix: 'fab', iconName: 'aws', icon: [512, 512, [], "f375", "M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"] }; +var faBandcamp = { prefix: 'fab', iconName: 'bandcamp', icon: [496, 512, [], "f2d5", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"] }; +var faBehance = { prefix: 'fab', iconName: 'behance', icon: [576, 512, [], "f1b4", "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"] }; +var faBehanceSquare = { prefix: 'fab', iconName: 'behance-square', icon: [512, 512, [], "f1b5", "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"] }; +var faBimobject = { prefix: 'fab', iconName: 'bimobject', icon: [448, 512, [], "f378", "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"] }; +var faBitbucket = { prefix: 'fab', iconName: 'bitbucket', icon: [512, 512, [], "f171", "M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"] }; +var faBitcoin = { prefix: 'fab', iconName: 'bitcoin', icon: [512, 512, [], "f379", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"] }; +var faBity = { prefix: 'fab', iconName: 'bity', icon: [496, 512, [], "f37a", "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"] }; +var faBlackTie = { prefix: 'fab', iconName: 'black-tie', icon: [448, 512, [], "f27e", "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"] }; +var faBlackberry = { prefix: 'fab', iconName: 'blackberry', icon: [512, 512, [], "f37b", "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"] }; +var faBlogger = { prefix: 'fab', iconName: 'blogger', icon: [448, 512, [], "f37c", "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"] }; +var faBloggerB = { prefix: 'fab', iconName: 'blogger-b', icon: [448, 512, [], "f37d", "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"] }; +var faBluetooth = { prefix: 'fab', iconName: 'bluetooth', icon: [448, 512, [], "f293", "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"] }; +var faBluetoothB = { prefix: 'fab', iconName: 'bluetooth-b', icon: [320, 512, [], "f294", "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"] }; +var faBtc = { prefix: 'fab', iconName: 'btc', icon: [384, 512, [], "f15a", "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"] }; +var faBuromobelexperte = { prefix: 'fab', iconName: 'buromobelexperte', icon: [448, 512, [], "f37f", "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"] }; +var faBuysellads = { prefix: 'fab', iconName: 'buysellads', icon: [448, 512, [], "f20d", "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"] }; +var faCcAmex = { prefix: 'fab', iconName: 'cc-amex', icon: [576, 512, [], "f1f3", "M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"] }; +var faCcApplePay = { prefix: 'fab', iconName: 'cc-apple-pay', icon: [576, 512, [], "f416", "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"] }; +var faCcDinersClub = { prefix: 'fab', iconName: 'cc-diners-club', icon: [576, 512, [], "f24c", "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"] }; +var faCcDiscover = { prefix: 'fab', iconName: 'cc-discover', icon: [576, 512, [], "f1f2", "M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"] }; +var faCcJcb = { prefix: 'fab', iconName: 'cc-jcb', icon: [576, 512, [], "f24b", "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"] }; +var faCcMastercard = { prefix: 'fab', iconName: 'cc-mastercard', icon: [576, 512, [], "f1f1", "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"] }; +var faCcPaypal = { prefix: 'fab', iconName: 'cc-paypal', icon: [576, 512, [], "f1f4", "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"] }; +var faCcStripe = { prefix: 'fab', iconName: 'cc-stripe', icon: [576, 512, [], "f1f5", "M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"] }; +var faCcVisa = { prefix: 'fab', iconName: 'cc-visa', icon: [576, 512, [], "f1f0", "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"] }; +var faCentercode = { prefix: 'fab', iconName: 'centercode', icon: [512, 512, [], "f380", "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"] }; +var faChrome = { prefix: 'fab', iconName: 'chrome', icon: [496, 512, [], "f268", "M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"] }; +var faCloudscale = { prefix: 'fab', iconName: 'cloudscale', icon: [448, 512, [], "f383", "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"] }; +var faCloudsmith = { prefix: 'fab', iconName: 'cloudsmith', icon: [332, 512, [], "f384", "M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"] }; +var faCloudversify = { prefix: 'fab', iconName: 'cloudversify', icon: [616, 512, [], "f385", "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"] }; +var faCodepen = { prefix: 'fab', iconName: 'codepen', icon: [512, 512, [], "f1cb", "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"] }; +var faCodiepie = { prefix: 'fab', iconName: 'codiepie', icon: [472, 512, [], "f284", "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"] }; +var faConnectdevelop = { prefix: 'fab', iconName: 'connectdevelop', icon: [576, 512, [], "f20e", "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"] }; +var faContao = { prefix: 'fab', iconName: 'contao', icon: [512, 512, [], "f26d", "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"] }; +var faCpanel = { prefix: 'fab', iconName: 'cpanel', icon: [640, 512, [], "f388", "M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"] }; +var faCreativeCommons = { prefix: 'fab', iconName: 'creative-commons', icon: [512, 512, [], "f25e", "M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"] }; +var faCss3 = { prefix: 'fab', iconName: 'css3', icon: [512, 512, [], "f13c", "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"] }; +var faCss3Alt = { prefix: 'fab', iconName: 'css3-alt', icon: [384, 512, [], "f38b", "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"] }; +var faCuttlefish = { prefix: 'fab', iconName: 'cuttlefish', icon: [440, 512, [], "f38c", "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"] }; +var faDAndD = { prefix: 'fab', iconName: 'd-and-d', icon: [576, 512, [], "f38d", "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"] }; +var faDashcube = { prefix: 'fab', iconName: 'dashcube', icon: [384, 512, [], "f210", "M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"] }; +var faDelicious = { prefix: 'fab', iconName: 'delicious', icon: [448, 512, [], "f1a5", "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"] }; +var faDeploydog = { prefix: 'fab', iconName: 'deploydog', icon: [512, 512, [], "f38e", "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"] }; +var faDeskpro = { prefix: 'fab', iconName: 'deskpro', icon: [480, 512, [], "f38f", "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"] }; +var faDeviantart = { prefix: 'fab', iconName: 'deviantart', icon: [320, 512, [], "f1bd", "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"] }; +var faDigg = { prefix: 'fab', iconName: 'digg', icon: [512, 512, [], "f1a6", "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"] }; +var faDigitalOcean = { prefix: 'fab', iconName: 'digital-ocean', icon: [512, 512, [], "f391", "M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"] }; +var faDiscord = { prefix: 'fab', iconName: 'discord', icon: [448, 512, [], "f392", "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"] }; +var faDiscourse = { prefix: 'fab', iconName: 'discourse', icon: [448, 512, [], "f393", "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"] }; +var faDochub = { prefix: 'fab', iconName: 'dochub', icon: [416, 512, [], "f394", "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"] }; +var faDocker = { prefix: 'fab', iconName: 'docker', icon: [640, 512, [], "f395", "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"] }; +var faDraft2digital = { prefix: 'fab', iconName: 'draft2digital', icon: [480, 512, [], "f396", "M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"] }; +var faDribbble = { prefix: 'fab', iconName: 'dribbble', icon: [512, 512, [], "f17d", "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"] }; +var faDribbbleSquare = { prefix: 'fab', iconName: 'dribbble-square', icon: [448, 512, [], "f397", "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"] }; +var faDropbox = { prefix: 'fab', iconName: 'dropbox', icon: [528, 512, [], "f16b", "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"] }; +var faDrupal = { prefix: 'fab', iconName: 'drupal', icon: [448, 512, [], "f1a9", "M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"] }; +var faDyalog = { prefix: 'fab', iconName: 'dyalog', icon: [416, 512, [], "f399", "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"] }; +var faEarlybirds = { prefix: 'fab', iconName: 'earlybirds', icon: [480, 512, [], "f39a", "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"] }; +var faEdge = { prefix: 'fab', iconName: 'edge', icon: [512, 512, [], "f282", "M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"] }; +var faEmber = { prefix: 'fab', iconName: 'ember', icon: [640, 512, [], "f423", "M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"] }; +var faEmpire = { prefix: 'fab', iconName: 'empire', icon: [496, 512, [], "f1d1", "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"] }; +var faEnvira = { prefix: 'fab', iconName: 'envira', icon: [448, 512, [], "f299", "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"] }; +var faErlang = { prefix: 'fab', iconName: 'erlang', icon: [640, 512, [], "f39d", "M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"] }; +var faEtsy = { prefix: 'fab', iconName: 'etsy', icon: [384, 512, [], "f2d7", "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"] }; +var faExpeditedssl = { prefix: 'fab', iconName: 'expeditedssl', icon: [496, 512, [], "f23e", "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"] }; +var faFacebook = { prefix: 'fab', iconName: 'facebook', icon: [448, 512, [], "f09a", "M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"] }; +var faFacebookF = { prefix: 'fab', iconName: 'facebook-f', icon: [264, 512, [], "f39e", "M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"] }; +var faFacebookMessenger = { prefix: 'fab', iconName: 'facebook-messenger', icon: [448, 512, [], "f39f", "M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"] }; +var faFacebookSquare = { prefix: 'fab', iconName: 'facebook-square', icon: [448, 512, [], "f082", "M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; +var faFirefox = { prefix: 'fab', iconName: 'firefox', icon: [480, 512, [], "f269", "M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"] }; +var faFirstOrder = { prefix: 'fab', iconName: 'first-order', icon: [448, 512, [], "f2b0", "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"] }; +var faFirstdraft = { prefix: 'fab', iconName: 'firstdraft', icon: [384, 512, [], "f3a1", "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"] }; +var faFlickr = { prefix: 'fab', iconName: 'flickr', icon: [448, 512, [], "f16e", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"] }; +var faFly = { prefix: 'fab', iconName: 'fly', icon: [384, 512, [], "f417", "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"] }; +var faFontAwesome = { prefix: 'fab', iconName: 'font-awesome', icon: [448, 512, [], "f2b4", "M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"] }; +var faFontAwesomeAlt = { prefix: 'fab', iconName: 'font-awesome-alt', icon: [448, 512, [], "f35c", "M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"] }; +var faFontAwesomeFlag = { prefix: 'fab', iconName: 'font-awesome-flag', icon: [448, 512, [], "f425", "M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"] }; +var faFonticons = { prefix: 'fab', iconName: 'fonticons', icon: [448, 512, [], "f280", "M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"] }; +var faFonticonsFi = { prefix: 'fab', iconName: 'fonticons-fi', icon: [384, 512, [], "f3a2", "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"] }; +var faFortAwesome = { prefix: 'fab', iconName: 'fort-awesome', icon: [448, 512, [], "f286", "M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"] }; +var faFortAwesomeAlt = { prefix: 'fab', iconName: 'fort-awesome-alt', icon: [512, 512, [], "f3a3", "M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"] }; +var faForumbee = { prefix: 'fab', iconName: 'forumbee', icon: [448, 512, [], "f211", "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"] }; +var faFoursquare = { prefix: 'fab', iconName: 'foursquare', icon: [368, 512, [], "f180", "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"] }; +var faFreeCodeCamp = { prefix: 'fab', iconName: 'free-code-camp', icon: [576, 512, [], "f2c5", "M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"] }; +var faFreebsd = { prefix: 'fab', iconName: 'freebsd', icon: [448, 512, [], "f3a4", "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"] }; +var faGetPocket = { prefix: 'fab', iconName: 'get-pocket', icon: [448, 512, [], "f265", "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"] }; +var faGg = { prefix: 'fab', iconName: 'gg', icon: [512, 512, [], "f260", "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"] }; +var faGgCircle = { prefix: 'fab', iconName: 'gg-circle', icon: [512, 512, [], "f261", "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"] }; +var faGit = { prefix: 'fab', iconName: 'git', icon: [448, 512, [], "f1d3", "M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"] }; +var faGitSquare = { prefix: 'fab', iconName: 'git-square', icon: [448, 512, [], "f1d2", "M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"] }; +var faGithub = { prefix: 'fab', iconName: 'github', icon: [496, 512, [], "f09b", "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"] }; +var faGithubAlt = { prefix: 'fab', iconName: 'github-alt', icon: [480, 512, [], "f113", "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"] }; +var faGithubSquare = { prefix: 'fab', iconName: 'github-square', icon: [448, 512, [], "f092", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"] }; +var faGitkraken = { prefix: 'fab', iconName: 'gitkraken', icon: [592, 512, [], "f3a6", "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"] }; +var faGitlab = { prefix: 'fab', iconName: 'gitlab', icon: [512, 512, [], "f296", "M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"] }; +var faGitter = { prefix: 'fab', iconName: 'gitter', icon: [384, 512, [], "f426", "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"] }; +var faGlide = { prefix: 'fab', iconName: 'glide', icon: [448, 512, [], "f2a5", "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"] }; +var faGlideG = { prefix: 'fab', iconName: 'glide-g', icon: [448, 512, [], "f2a6", "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"] }; +var faGofore = { prefix: 'fab', iconName: 'gofore', icon: [400, 512, [], "f3a7", "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"] }; +var faGoodreads = { prefix: 'fab', iconName: 'goodreads', icon: [448, 512, [], "f3a8", "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"] }; +var faGoodreadsG = { prefix: 'fab', iconName: 'goodreads-g', icon: [384, 512, [], "f3a9", "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"] }; +var faGoogle = { prefix: 'fab', iconName: 'google', icon: [488, 512, [], "f1a0", "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"] }; +var faGoogleDrive = { prefix: 'fab', iconName: 'google-drive', icon: [512, 512, [], "f3aa", "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"] }; +var faGooglePlay = { prefix: 'fab', iconName: 'google-play', icon: [512, 512, [], "f3ab", "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"] }; +var faGooglePlus = { prefix: 'fab', iconName: 'google-plus', icon: [496, 512, [], "f2b3", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"] }; +var faGooglePlusG = { prefix: 'fab', iconName: 'google-plus-g', icon: [640, 512, [], "f0d5", "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"] }; +var faGooglePlusSquare = { prefix: 'fab', iconName: 'google-plus-square', icon: [448, 512, [], "f0d4", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"] }; +var faGoogleWallet = { prefix: 'fab', iconName: 'google-wallet', icon: [448, 512, [], "f1ee", "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"] }; +var faGratipay = { prefix: 'fab', iconName: 'gratipay', icon: [496, 512, [], "f184", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"] }; +var faGrav = { prefix: 'fab', iconName: 'grav', icon: [512, 512, [], "f2d6", "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"] }; +var faGripfire = { prefix: 'fab', iconName: 'gripfire', icon: [384, 512, [], "f3ac", "M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"] }; +var faGrunt = { prefix: 'fab', iconName: 'grunt', icon: [384, 512, [], "f3ad", "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"] }; +var faGulp = { prefix: 'fab', iconName: 'gulp', icon: [256, 512, [], "f3ae", "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"] }; +var faHackerNews = { prefix: 'fab', iconName: 'hacker-news', icon: [448, 512, [], "f1d4", "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; +var faHackerNewsSquare = { prefix: 'fab', iconName: 'hacker-news-square', icon: [448, 512, [], "f3af", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"] }; +var faHireAHelper = { prefix: 'fab', iconName: 'hire-a-helper', icon: [512, 512, [], "f3b0", "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"] }; +var faHooli = { prefix: 'fab', iconName: 'hooli', icon: [640, 512, [], "f427", "M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"] }; +var faHotjar = { prefix: 'fab', iconName: 'hotjar', icon: [448, 512, [], "f3b1", "M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"] }; +var faHouzz = { prefix: 'fab', iconName: 'houzz', icon: [320, 512, [], "f27c", "M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"] }; +var faHtml5 = { prefix: 'fab', iconName: 'html5', icon: [384, 512, [], "f13b", "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"] }; +var faHubspot = { prefix: 'fab', iconName: 'hubspot', icon: [512, 512, [], "f3b2", "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"] }; +var faImdb = { prefix: 'fab', iconName: 'imdb', icon: [448, 512, [], "f2d8", "M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"] }; +var faInstagram = { prefix: 'fab', iconName: 'instagram', icon: [448, 512, [], "f16d", "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"] }; +var faInternetExplorer = { prefix: 'fab', iconName: 'internet-explorer', icon: [512, 512, [], "f26b", "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"] }; +var faIoxhost = { prefix: 'fab', iconName: 'ioxhost', icon: [640, 512, [], "f208", "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"] }; +var faItunes = { prefix: 'fab', iconName: 'itunes', icon: [448, 512, [], "f3b4", "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"] }; +var faItunesNote = { prefix: 'fab', iconName: 'itunes-note', icon: [384, 512, [], "f3b5", "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"] }; +var faJenkins = { prefix: 'fab', iconName: 'jenkins', icon: [512, 512, [], "f3b6", "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"] }; +var faJoget = { prefix: 'fab', iconName: 'joget', icon: [496, 512, [], "f3b7", "M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"] }; +var faJoomla = { prefix: 'fab', iconName: 'joomla', icon: [448, 512, [], "f1aa", "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"] }; +var faJs = { prefix: 'fab', iconName: 'js', icon: [448, 512, [], "f3b8", "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; +var faJsSquare = { prefix: 'fab', iconName: 'js-square', icon: [512, 512, [], "f3b9", "M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"] }; +var faJsfiddle = { prefix: 'fab', iconName: 'jsfiddle', icon: [576, 512, [], "f1cc", "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"] }; +var faKeycdn = { prefix: 'fab', iconName: 'keycdn', icon: [512, 512, [], "f3ba", "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"] }; +var faKickstarter = { prefix: 'fab', iconName: 'kickstarter', icon: [448, 512, [], "f3bb", "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"] }; +var faKickstarterK = { prefix: 'fab', iconName: 'kickstarter-k', icon: [384, 512, [], "f3bc", "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"] }; +var faLaravel = { prefix: 'fab', iconName: 'laravel', icon: [640, 512, [], "f3bd", "M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"] }; +var faLastfm = { prefix: 'fab', iconName: 'lastfm', icon: [512, 512, [], "f202", "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"] }; +var faLastfmSquare = { prefix: 'fab', iconName: 'lastfm-square', icon: [448, 512, [], "f203", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"] }; +var faLeanpub = { prefix: 'fab', iconName: 'leanpub', icon: [576, 512, [], "f212", "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"] }; +var faLess = { prefix: 'fab', iconName: 'less', icon: [640, 512, [], "f41d", "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"] }; +var faLine = { prefix: 'fab', iconName: 'line', icon: [448, 512, [], "f3c0", "M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"] }; +var faLinkedin = { prefix: 'fab', iconName: 'linkedin', icon: [448, 512, [], "f08c", "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"] }; +var faLinkedinIn = { prefix: 'fab', iconName: 'linkedin-in', icon: [448, 512, [], "f0e1", "M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"] }; +var faLinode = { prefix: 'fab', iconName: 'linode', icon: [448, 512, [], "f2b8", "M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"] }; +var faLinux = { prefix: 'fab', iconName: 'linux', icon: [448, 512, [], "f17c", "M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"] }; +var faLyft = { prefix: 'fab', iconName: 'lyft', icon: [512, 512, [], "f3c3", "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"] }; +var faMagento = { prefix: 'fab', iconName: 'magento', icon: [448, 512, [], "f3c4", "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"] }; +var faMaxcdn = { prefix: 'fab', iconName: 'maxcdn', icon: [512, 512, [], "f136", "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"] }; +var faMedapps = { prefix: 'fab', iconName: 'medapps', icon: [320, 512, [], "f3c6", "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"] }; +var faMedium = { prefix: 'fab', iconName: 'medium', icon: [448, 512, [], "f23a", "M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"] }; +var faMediumM = { prefix: 'fab', iconName: 'medium-m', icon: [512, 512, [], "f3c7", "M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"] }; +var faMedrt = { prefix: 'fab', iconName: 'medrt', icon: [544, 512, [], "f3c8", "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"] }; +var faMeetup = { prefix: 'fab', iconName: 'meetup', icon: [512, 512, [], "f2e0", "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"] }; +var faMicrosoft = { prefix: 'fab', iconName: 'microsoft', icon: [448, 512, [], "f3ca", "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"] }; +var faMix = { prefix: 'fab', iconName: 'mix', icon: [416, 512, [], "f3cb", "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"] }; +var faMixcloud = { prefix: 'fab', iconName: 'mixcloud', icon: [640, 512, [], "f289", "M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"] }; +var faMizuni = { prefix: 'fab', iconName: 'mizuni', icon: [496, 512, [], "f3cc", "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"] }; +var faModx = { prefix: 'fab', iconName: 'modx', icon: [448, 512, [], "f285", "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"] }; +var faMonero = { prefix: 'fab', iconName: 'monero', icon: [496, 512, [], "f3d0", "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"] }; +var faNapster = { prefix: 'fab', iconName: 'napster', icon: [496, 512, [], "f3d2", "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"] }; +var faNintendoSwitch = { prefix: 'fab', iconName: 'nintendo-switch', icon: [448, 512, [], "f418", "M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"] }; +var faNode = { prefix: 'fab', iconName: 'node', icon: [640, 512, [], "f419", "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"] }; +var faNodeJs = { prefix: 'fab', iconName: 'node-js', icon: [448, 512, [], "f3d3", "M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"] }; +var faNpm = { prefix: 'fab', iconName: 'npm', icon: [576, 512, [], "f3d4", "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"] }; +var faNs8 = { prefix: 'fab', iconName: 'ns8', icon: [640, 512, [], "f3d5", "M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"] }; +var faNutritionix = { prefix: 'fab', iconName: 'nutritionix', icon: [400, 512, [], "f3d6", "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"] }; +var faOdnoklassniki = { prefix: 'fab', iconName: 'odnoklassniki', icon: [320, 512, [], "f263", "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"] }; +var faOdnoklassnikiSquare = { prefix: 'fab', iconName: 'odnoklassniki-square', icon: [448, 512, [], "f264", "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"] }; +var faOpencart = { prefix: 'fab', iconName: 'opencart', icon: [640, 512, [], "f23d", "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"] }; +var faOpenid = { prefix: 'fab', iconName: 'openid', icon: [448, 512, [], "f19b", "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"] }; +var faOpera = { prefix: 'fab', iconName: 'opera', icon: [496, 512, [], "f26a", "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"] }; +var faOptinMonster = { prefix: 'fab', iconName: 'optin-monster', icon: [576, 512, [], "f23c", "M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"] }; +var faOsi = { prefix: 'fab', iconName: 'osi', icon: [495, 512, [], "f41a", "M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"] }; +var faPage4 = { prefix: 'fab', iconName: 'page4', icon: [496, 512, [], "f3d7", "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"] }; +var faPagelines = { prefix: 'fab', iconName: 'pagelines', icon: [384, 512, [], "f18c", "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"] }; +var faPalfed = { prefix: 'fab', iconName: 'palfed', icon: [560, 512, [], "f3d8", "M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"] }; +var faPatreon = { prefix: 'fab', iconName: 'patreon', icon: [512, 512, [], "f3d9", "M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"] }; +var faPaypal = { prefix: 'fab', iconName: 'paypal', icon: [384, 512, [], "f1ed", "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"] }; +var faPeriscope = { prefix: 'fab', iconName: 'periscope', icon: [448, 512, [], "f3da", "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"] }; +var faPhabricator = { prefix: 'fab', iconName: 'phabricator', icon: [496, 512, [], "f3db", "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"] }; +var faPhoenixFramework = { prefix: 'fab', iconName: 'phoenix-framework', icon: [640, 512, [], "f3dc", "M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"] }; +var faPiedPiper = { prefix: 'fab', iconName: 'pied-piper', icon: [640, 512, [], "f2ae", "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"] }; +var faPiedPiperAlt = { prefix: 'fab', iconName: 'pied-piper-alt', icon: [576, 512, [], "f1a8", "M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"] }; +var faPiedPiperPp = { prefix: 'fab', iconName: 'pied-piper-pp', icon: [448, 512, [], "f1a7", "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"] }; +var faPinterest = { prefix: 'fab', iconName: 'pinterest', icon: [496, 512, [], "f0d2", "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"] }; +var faPinterestP = { prefix: 'fab', iconName: 'pinterest-p', icon: [384, 512, [], "f231", "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"] }; +var faPinterestSquare = { prefix: 'fab', iconName: 'pinterest-square', icon: [448, 512, [], "f0d3", "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"] }; +var faPlaystation = { prefix: 'fab', iconName: 'playstation', icon: [576, 512, [], "f3df", "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"] }; +var faProductHunt = { prefix: 'fab', iconName: 'product-hunt', icon: [512, 512, [], "f288", "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"] }; +var faPushed = { prefix: 'fab', iconName: 'pushed', icon: [432, 512, [], "f3e1", "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"] }; +var faPython = { prefix: 'fab', iconName: 'python', icon: [448, 512, [], "f3e2", "M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"] }; +var faQq = { prefix: 'fab', iconName: 'qq', icon: [448, 512, [], "f1d6", "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"] }; +var faQuora = { prefix: 'fab', iconName: 'quora', icon: [448, 512, [], "f2c4", "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"] }; +var faRavelry = { prefix: 'fab', iconName: 'ravelry', icon: [512, 512, [], "f2d9", "M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"] }; +var faReact = { prefix: 'fab', iconName: 'react', icon: [512, 512, [], "f41b", "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"] }; +var faRebel = { prefix: 'fab', iconName: 'rebel', icon: [512, 512, [], "f1d0", "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"] }; +var faRedRiver = { prefix: 'fab', iconName: 'red-river', icon: [448, 512, [], "f3e3", "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"] }; +var faReddit = { prefix: 'fab', iconName: 'reddit', icon: [512, 512, [], "f1a1", "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"] }; +var faRedditAlien = { prefix: 'fab', iconName: 'reddit-alien', icon: [512, 512, [], "f281", "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"] }; +var faRedditSquare = { prefix: 'fab', iconName: 'reddit-square', icon: [448, 512, [], "f1a2", "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"] }; +var faRendact = { prefix: 'fab', iconName: 'rendact', icon: [496, 512, [], "f3e4", "M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"] }; +var faRenren = { prefix: 'fab', iconName: 'renren', icon: [512, 512, [], "f18b", "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"] }; +var faReplyd = { prefix: 'fab', iconName: 'replyd', icon: [448, 512, [], "f3e6", "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"] }; +var faResolving = { prefix: 'fab', iconName: 'resolving', icon: [496, 512, [], "f3e7", "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"] }; +var faRocketchat = { prefix: 'fab', iconName: 'rocketchat', icon: [448, 512, [], "f3e8", "M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"] }; +var faRockrms = { prefix: 'fab', iconName: 'rockrms', icon: [496, 512, [], "f3e9", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"] }; +var faSafari = { prefix: 'fab', iconName: 'safari', icon: [512, 512, [], "f267", "M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"] }; +var faSass = { prefix: 'fab', iconName: 'sass', icon: [640, 512, [], "f41e", "M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"] }; +var faSchlix = { prefix: 'fab', iconName: 'schlix', icon: [448, 512, [], "f3ea", "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"] }; +var faScribd = { prefix: 'fab', iconName: 'scribd', icon: [384, 512, [], "f28a", "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"] }; +var faSearchengin = { prefix: 'fab', iconName: 'searchengin', icon: [460, 512, [], "f3eb", "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"] }; +var faSellcast = { prefix: 'fab', iconName: 'sellcast', icon: [448, 512, [], "f2da", "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"] }; +var faSellsy = { prefix: 'fab', iconName: 'sellsy', icon: [640, 512, [], "f213", "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"] }; +var faServicestack = { prefix: 'fab', iconName: 'servicestack', icon: [496, 512, [], "f3ec", "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"] }; +var faShirtsinbulk = { prefix: 'fab', iconName: 'shirtsinbulk', icon: [448, 512, [], "f214", "M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"] }; +var faSimplybuilt = { prefix: 'fab', iconName: 'simplybuilt', icon: [512, 512, [], "f215", "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"] }; +var faSistrix = { prefix: 'fab', iconName: 'sistrix', icon: [448, 512, [], "f3ee", "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"] }; +var faSkyatlas = { prefix: 'fab', iconName: 'skyatlas', icon: [576, 512, [], "f216", "M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"] }; +var faSkype = { prefix: 'fab', iconName: 'skype', icon: [448, 512, [], "f17e", "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"] }; +var faSlack = { prefix: 'fab', iconName: 'slack', icon: [448, 512, [], "f198", "M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"] }; +var faSlackHash = { prefix: 'fab', iconName: 'slack-hash', icon: [448, 512, [], "f3ef", "M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"] }; +var faSlideshare = { prefix: 'fab', iconName: 'slideshare', icon: [512, 512, [], "f1e7", "M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"] }; +var faSnapchat = { prefix: 'fab', iconName: 'snapchat', icon: [496, 512, [], "f2ab", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; +var faSnapchatGhost = { prefix: 'fab', iconName: 'snapchat-ghost', icon: [512, 512, [], "f2ac", "M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"] }; +var faSnapchatSquare = { prefix: 'fab', iconName: 'snapchat-square', icon: [448, 512, [], "f2ad", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"] }; +var faSoundcloud = { prefix: 'fab', iconName: 'soundcloud', icon: [640, 512, [], "f1be", "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"] }; +var faSpeakap = { prefix: 'fab', iconName: 'speakap', icon: [448, 512, [], "f3f3", "M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"] }; +var faSpotify = { prefix: 'fab', iconName: 'spotify', icon: [496, 512, [], "f1bc", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"] }; +var faStackExchange = { prefix: 'fab', iconName: 'stack-exchange', icon: [448, 512, [], "f18d", "M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"] }; +var faStackOverflow = { prefix: 'fab', iconName: 'stack-overflow', icon: [384, 512, [], "f16c", "M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"] }; +var faStaylinked = { prefix: 'fab', iconName: 'staylinked', icon: [440, 512, [], "f3f5", "M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"] }; +var faSteam = { prefix: 'fab', iconName: 'steam', icon: [496, 512, [], "f1b6", "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"] }; +var faSteamSquare = { prefix: 'fab', iconName: 'steam-square', icon: [448, 512, [], "f1b7", "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"] }; +var faSteamSymbol = { prefix: 'fab', iconName: 'steam-symbol', icon: [448, 512, [], "f3f6", "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"] }; +var faStickerMule = { prefix: 'fab', iconName: 'sticker-mule', icon: [576, 512, [], "f3f7", "M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"] }; +var faStrava = { prefix: 'fab', iconName: 'strava', icon: [369, 512, [], "f428", "M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"] }; +var faStripe = { prefix: 'fab', iconName: 'stripe', icon: [640, 512, [], "f429", "M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"] }; +var faStripeS = { prefix: 'fab', iconName: 'stripe-s', icon: [362, 512, [], "f42a", "M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"] }; +var faStudiovinari = { prefix: 'fab', iconName: 'studiovinari', icon: [512, 512, [], "f3f8", "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"] }; +var faStumbleupon = { prefix: 'fab', iconName: 'stumbleupon', icon: [512, 512, [], "f1a4", "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"] }; +var faStumbleuponCircle = { prefix: 'fab', iconName: 'stumbleupon-circle', icon: [496, 512, [], "f1a3", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"] }; +var faSuperpowers = { prefix: 'fab', iconName: 'superpowers', icon: [448, 512, [], "f2dd", "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"] }; +var faSupple = { prefix: 'fab', iconName: 'supple', icon: [640, 512, [], "f3f9", "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"] }; +var faTelegram = { prefix: 'fab', iconName: 'telegram', icon: [496, 512, [], "f2c6", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"] }; +var faTelegramPlane = { prefix: 'fab', iconName: 'telegram-plane', icon: [448, 512, [], "f3fe", "M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"] }; +var faTencentWeibo = { prefix: 'fab', iconName: 'tencent-weibo', icon: [384, 512, [], "f1d5", "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"] }; +var faThemeisle = { prefix: 'fab', iconName: 'themeisle', icon: [512, 512, [], "f2b2", "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"] }; +var faTrello = { prefix: 'fab', iconName: 'trello', icon: [448, 512, [], "f181", "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"] }; +var faTripadvisor = { prefix: 'fab', iconName: 'tripadvisor', icon: [576, 512, [], "f262", "M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"] }; +var faTumblr = { prefix: 'fab', iconName: 'tumblr', icon: [320, 512, [], "f173", "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"] }; +var faTumblrSquare = { prefix: 'fab', iconName: 'tumblr-square', icon: [448, 512, [], "f174", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"] }; +var faTwitch = { prefix: 'fab', iconName: 'twitch', icon: [448, 512, [], "f1e8", "M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"] }; +var faTwitter = { prefix: 'fab', iconName: 'twitter', icon: [512, 512, [], "f099", "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"] }; +var faTwitterSquare = { prefix: 'fab', iconName: 'twitter-square', icon: [448, 512, [], "f081", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"] }; +var faTypo3 = { prefix: 'fab', iconName: 'typo3', icon: [433, 512, [], "f42b", "M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"] }; +var faUber = { prefix: 'fab', iconName: 'uber', icon: [448, 512, [], "f402", "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"] }; +var faUikit = { prefix: 'fab', iconName: 'uikit', icon: [448, 512, [], "f403", "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"] }; +var faUniregistry = { prefix: 'fab', iconName: 'uniregistry', icon: [384, 512, [], "f404", "M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"] }; +var faUntappd = { prefix: 'fab', iconName: 'untappd', icon: [640, 512, [], "f405", "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"] }; +var faUsb = { prefix: 'fab', iconName: 'usb', icon: [640, 512, [], "f287", "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"] }; +var faUssunnah = { prefix: 'fab', iconName: 'ussunnah', icon: [512, 512, [], "f407", "M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"] }; +var faVaadin = { prefix: 'fab', iconName: 'vaadin', icon: [448, 512, [], "f408", "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"] }; +var faViacoin = { prefix: 'fab', iconName: 'viacoin', icon: [384, 512, [], "f237", "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"] }; +var faViadeo = { prefix: 'fab', iconName: 'viadeo', icon: [448, 512, [], "f2a9", "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"] }; +var faViadeoSquare = { prefix: 'fab', iconName: 'viadeo-square', icon: [448, 512, [], "f2aa", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"] }; +var faViber = { prefix: 'fab', iconName: 'viber', icon: [512, 512, [], "f409", "M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"] }; +var faVimeo = { prefix: 'fab', iconName: 'vimeo', icon: [448, 512, [], "f40a", "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"] }; +var faVimeoSquare = { prefix: 'fab', iconName: 'vimeo-square', icon: [448, 512, [], "f194", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"] }; +var faVimeoV = { prefix: 'fab', iconName: 'vimeo-v', icon: [448, 512, [], "f27d", "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"] }; +var faVine = { prefix: 'fab', iconName: 'vine', icon: [384, 512, [], "f1ca", "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"] }; +var faVk = { prefix: 'fab', iconName: 'vk', icon: [576, 512, [], "f189", "M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"] }; +var faVnv = { prefix: 'fab', iconName: 'vnv', icon: [640, 512, [], "f40b", "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"] }; +var faVuejs = { prefix: 'fab', iconName: 'vuejs', icon: [448, 512, [], "f41f", "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"] }; +var faWeibo = { prefix: 'fab', iconName: 'weibo', icon: [512, 512, [], "f18a", "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"] }; +var faWeixin = { prefix: 'fab', iconName: 'weixin', icon: [576, 512, [], "f1d7", "M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"] }; +var faWhatsapp = { prefix: 'fab', iconName: 'whatsapp', icon: [448, 512, [], "f232", "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"] }; +var faWhatsappSquare = { prefix: 'fab', iconName: 'whatsapp-square', icon: [448, 512, [], "f40c", "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"] }; +var faWhmcs = { prefix: 'fab', iconName: 'whmcs', icon: [448, 512, [], "f40d", "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"] }; +var faWikipediaW = { prefix: 'fab', iconName: 'wikipedia-w', icon: [640, 512, [], "f266", "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"] }; +var faWindows = { prefix: 'fab', iconName: 'windows', icon: [448, 512, [], "f17a", "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"] }; +var faWordpress = { prefix: 'fab', iconName: 'wordpress', icon: [512, 512, [], "f19a", "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"] }; +var faWordpressSimple = { prefix: 'fab', iconName: 'wordpress-simple', icon: [512, 512, [], "f411", "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"] }; +var faWpbeginner = { prefix: 'fab', iconName: 'wpbeginner', icon: [512, 512, [], "f297", "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"] }; +var faWpexplorer = { prefix: 'fab', iconName: 'wpexplorer', icon: [512, 512, [], "f2de", "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"] }; +var faWpforms = { prefix: 'fab', iconName: 'wpforms', icon: [448, 512, [], "f298", "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"] }; +var faXbox = { prefix: 'fab', iconName: 'xbox', icon: [512, 512, [], "f412", "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"] }; +var faXing = { prefix: 'fab', iconName: 'xing', icon: [384, 512, [], "f168", "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"] }; +var faXingSquare = { prefix: 'fab', iconName: 'xing-square', icon: [448, 512, [], "f169", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"] }; +var faYCombinator = { prefix: 'fab', iconName: 'y-combinator', icon: [448, 512, [], "f23b", "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"] }; +var faYahoo = { prefix: 'fab', iconName: 'yahoo', icon: [360, 512, [], "f19e", "M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"] }; +var faYandex = { prefix: 'fab', iconName: 'yandex', icon: [256, 512, [], "f413", "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"] }; +var faYandexInternational = { prefix: 'fab', iconName: 'yandex-international', icon: [320, 512, [], "f414", "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"] }; +var faYelp = { prefix: 'fab', iconName: 'yelp', icon: [384, 512, [], "f1e9", "M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"] }; +var faYoast = { prefix: 'fab', iconName: 'yoast', icon: [448, 512, [], "f2b1", "M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"] }; +var faYoutube = { prefix: 'fab', iconName: 'youtube', icon: [576, 512, [], "f167", "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"] }; +var icons$1 = { + fa500px: fa500px, + faAccessibleIcon: faAccessibleIcon, + faAccusoft: faAccusoft, + faAdn: faAdn, + faAdversal: faAdversal, + faAffiliatetheme: faAffiliatetheme, + faAlgolia: faAlgolia, + faAmazon: faAmazon, + faAmilia: faAmilia, + faAndroid: faAndroid, + faAngellist: faAngellist, + faAngrycreative: faAngrycreative, + faAngular: faAngular, + faAppStore: faAppStore, + faAppStoreIos: faAppStoreIos, + faApper: faApper, + faApple: faApple, + faApplePay: faApplePay, + faAsymmetrik: faAsymmetrik, + faAudible: faAudible, + faAutoprefixer: faAutoprefixer, + faAvianex: faAvianex, + faAviato: faAviato, + faAws: faAws, + faBandcamp: faBandcamp, + faBehance: faBehance, + faBehanceSquare: faBehanceSquare, + faBimobject: faBimobject, + faBitbucket: faBitbucket, + faBitcoin: faBitcoin, + faBity: faBity, + faBlackTie: faBlackTie, + faBlackberry: faBlackberry, + faBlogger: faBlogger, + faBloggerB: faBloggerB, + faBluetooth: faBluetooth, + faBluetoothB: faBluetoothB, + faBtc: faBtc, + faBuromobelexperte: faBuromobelexperte, + faBuysellads: faBuysellads, + faCcAmex: faCcAmex, + faCcApplePay: faCcApplePay, + faCcDinersClub: faCcDinersClub, + faCcDiscover: faCcDiscover, + faCcJcb: faCcJcb, + faCcMastercard: faCcMastercard, + faCcPaypal: faCcPaypal, + faCcStripe: faCcStripe, + faCcVisa: faCcVisa, + faCentercode: faCentercode, + faChrome: faChrome, + faCloudscale: faCloudscale, + faCloudsmith: faCloudsmith, + faCloudversify: faCloudversify, + faCodepen: faCodepen, + faCodiepie: faCodiepie, + faConnectdevelop: faConnectdevelop, + faContao: faContao, + faCpanel: faCpanel, + faCreativeCommons: faCreativeCommons, + faCss3: faCss3, + faCss3Alt: faCss3Alt, + faCuttlefish: faCuttlefish, + faDAndD: faDAndD, + faDashcube: faDashcube, + faDelicious: faDelicious, + faDeploydog: faDeploydog, + faDeskpro: faDeskpro, + faDeviantart: faDeviantart, + faDigg: faDigg, + faDigitalOcean: faDigitalOcean, + faDiscord: faDiscord, + faDiscourse: faDiscourse, + faDochub: faDochub, + faDocker: faDocker, + faDraft2digital: faDraft2digital, + faDribbble: faDribbble, + faDribbbleSquare: faDribbbleSquare, + faDropbox: faDropbox, + faDrupal: faDrupal, + faDyalog: faDyalog, + faEarlybirds: faEarlybirds, + faEdge: faEdge, + faEmber: faEmber, + faEmpire: faEmpire, + faEnvira: faEnvira, + faErlang: faErlang, + faEtsy: faEtsy, + faExpeditedssl: faExpeditedssl, + faFacebook: faFacebook, + faFacebookF: faFacebookF, + faFacebookMessenger: faFacebookMessenger, + faFacebookSquare: faFacebookSquare, + faFirefox: faFirefox, + faFirstOrder: faFirstOrder, + faFirstdraft: faFirstdraft, + faFlickr: faFlickr, + faFly: faFly, + faFontAwesome: faFontAwesome, + faFontAwesomeAlt: faFontAwesomeAlt, + faFontAwesomeFlag: faFontAwesomeFlag, + faFonticons: faFonticons, + faFonticonsFi: faFonticonsFi, + faFortAwesome: faFortAwesome, + faFortAwesomeAlt: faFortAwesomeAlt, + faForumbee: faForumbee, + faFoursquare: faFoursquare, + faFreeCodeCamp: faFreeCodeCamp, + faFreebsd: faFreebsd, + faGetPocket: faGetPocket, + faGg: faGg, + faGgCircle: faGgCircle, + faGit: faGit, + faGitSquare: faGitSquare, + faGithub: faGithub, + faGithubAlt: faGithubAlt, + faGithubSquare: faGithubSquare, + faGitkraken: faGitkraken, + faGitlab: faGitlab, + faGitter: faGitter, + faGlide: faGlide, + faGlideG: faGlideG, + faGofore: faGofore, + faGoodreads: faGoodreads, + faGoodreadsG: faGoodreadsG, + faGoogle: faGoogle, + faGoogleDrive: faGoogleDrive, + faGooglePlay: faGooglePlay, + faGooglePlus: faGooglePlus, + faGooglePlusG: faGooglePlusG, + faGooglePlusSquare: faGooglePlusSquare, + faGoogleWallet: faGoogleWallet, + faGratipay: faGratipay, + faGrav: faGrav, + faGripfire: faGripfire, + faGrunt: faGrunt, + faGulp: faGulp, + faHackerNews: faHackerNews, + faHackerNewsSquare: faHackerNewsSquare, + faHireAHelper: faHireAHelper, + faHooli: faHooli, + faHotjar: faHotjar, + faHouzz: faHouzz, + faHtml5: faHtml5, + faHubspot: faHubspot, + faImdb: faImdb, + faInstagram: faInstagram, + faInternetExplorer: faInternetExplorer, + faIoxhost: faIoxhost, + faItunes: faItunes, + faItunesNote: faItunesNote, + faJenkins: faJenkins, + faJoget: faJoget, + faJoomla: faJoomla, + faJs: faJs, + faJsSquare: faJsSquare, + faJsfiddle: faJsfiddle, + faKeycdn: faKeycdn, + faKickstarter: faKickstarter, + faKickstarterK: faKickstarterK, + faLaravel: faLaravel, + faLastfm: faLastfm, + faLastfmSquare: faLastfmSquare, + faLeanpub: faLeanpub, + faLess: faLess, + faLine: faLine, + faLinkedin: faLinkedin, + faLinkedinIn: faLinkedinIn, + faLinode: faLinode, + faLinux: faLinux, + faLyft: faLyft, + faMagento: faMagento, + faMaxcdn: faMaxcdn, + faMedapps: faMedapps, + faMedium: faMedium, + faMediumM: faMediumM, + faMedrt: faMedrt, + faMeetup: faMeetup, + faMicrosoft: faMicrosoft, + faMix: faMix, + faMixcloud: faMixcloud, + faMizuni: faMizuni, + faModx: faModx, + faMonero: faMonero, + faNapster: faNapster, + faNintendoSwitch: faNintendoSwitch, + faNode: faNode, + faNodeJs: faNodeJs, + faNpm: faNpm, + faNs8: faNs8, + faNutritionix: faNutritionix, + faOdnoklassniki: faOdnoklassniki, + faOdnoklassnikiSquare: faOdnoklassnikiSquare, + faOpencart: faOpencart, + faOpenid: faOpenid, + faOpera: faOpera, + faOptinMonster: faOptinMonster, + faOsi: faOsi, + faPage4: faPage4, + faPagelines: faPagelines, + faPalfed: faPalfed, + faPatreon: faPatreon, + faPaypal: faPaypal, + faPeriscope: faPeriscope, + faPhabricator: faPhabricator, + faPhoenixFramework: faPhoenixFramework, + faPiedPiper: faPiedPiper, + faPiedPiperAlt: faPiedPiperAlt, + faPiedPiperPp: faPiedPiperPp, + faPinterest: faPinterest, + faPinterestP: faPinterestP, + faPinterestSquare: faPinterestSquare, + faPlaystation: faPlaystation, + faProductHunt: faProductHunt, + faPushed: faPushed, + faPython: faPython, + faQq: faQq, + faQuora: faQuora, + faRavelry: faRavelry, + faReact: faReact, + faRebel: faRebel, + faRedRiver: faRedRiver, + faReddit: faReddit, + faRedditAlien: faRedditAlien, + faRedditSquare: faRedditSquare, + faRendact: faRendact, + faRenren: faRenren, + faReplyd: faReplyd, + faResolving: faResolving, + faRocketchat: faRocketchat, + faRockrms: faRockrms, + faSafari: faSafari, + faSass: faSass, + faSchlix: faSchlix, + faScribd: faScribd, + faSearchengin: faSearchengin, + faSellcast: faSellcast, + faSellsy: faSellsy, + faServicestack: faServicestack, + faShirtsinbulk: faShirtsinbulk, + faSimplybuilt: faSimplybuilt, + faSistrix: faSistrix, + faSkyatlas: faSkyatlas, + faSkype: faSkype, + faSlack: faSlack, + faSlackHash: faSlackHash, + faSlideshare: faSlideshare, + faSnapchat: faSnapchat, + faSnapchatGhost: faSnapchatGhost, + faSnapchatSquare: faSnapchatSquare, + faSoundcloud: faSoundcloud, + faSpeakap: faSpeakap, + faSpotify: faSpotify, + faStackExchange: faStackExchange, + faStackOverflow: faStackOverflow, + faStaylinked: faStaylinked, + faSteam: faSteam, + faSteamSquare: faSteamSquare, + faSteamSymbol: faSteamSymbol, + faStickerMule: faStickerMule, + faStrava: faStrava, + faStripe: faStripe, + faStripeS: faStripeS, + faStudiovinari: faStudiovinari, + faStumbleupon: faStumbleupon, + faStumbleuponCircle: faStumbleuponCircle, + faSuperpowers: faSuperpowers, + faSupple: faSupple, + faTelegram: faTelegram, + faTelegramPlane: faTelegramPlane, + faTencentWeibo: faTencentWeibo, + faThemeisle: faThemeisle, + faTrello: faTrello, + faTripadvisor: faTripadvisor, + faTumblr: faTumblr, + faTumblrSquare: faTumblrSquare, + faTwitch: faTwitch, + faTwitter: faTwitter, + faTwitterSquare: faTwitterSquare, + faTypo3: faTypo3, + faUber: faUber, + faUikit: faUikit, + faUniregistry: faUniregistry, + faUntappd: faUntappd, + faUsb: faUsb, + faUssunnah: faUssunnah, + faVaadin: faVaadin, + faViacoin: faViacoin, + faViadeo: faViadeo, + faViadeoSquare: faViadeoSquare, + faViber: faViber, + faVimeo: faVimeo, + faVimeoSquare: faVimeoSquare, + faVimeoV: faVimeoV, + faVine: faVine, + faVk: faVk, + faVnv: faVnv, + faVuejs: faVuejs, + faWeibo: faWeibo, + faWeixin: faWeixin, + faWhatsapp: faWhatsapp, + faWhatsappSquare: faWhatsappSquare, + faWhmcs: faWhmcs, + faWikipediaW: faWikipediaW, + faWindows: faWindows, + faWordpress: faWordpress, + faWordpressSimple: faWordpressSimple, + faWpbeginner: faWpbeginner, + faWpexplorer: faWpexplorer, + faWpforms: faWpforms, + faXbox: faXbox, + faXing: faXing, + faXingSquare: faXingSquare, + faYCombinator: faYCombinator, + faYahoo: faYahoo, + faYandex: faYandex, + faYandexInternational: faYandexInternational, + faYelp: faYelp, + faYoast: faYoast, + faYoutube: faYoutube +}; + +exports['default'] = icons$1; +exports.prefix = prefix; +exports.fa500px = fa500px; +exports.faAccessibleIcon = faAccessibleIcon; +exports.faAccusoft = faAccusoft; +exports.faAdn = faAdn; +exports.faAdversal = faAdversal; +exports.faAffiliatetheme = faAffiliatetheme; +exports.faAlgolia = faAlgolia; +exports.faAmazon = faAmazon; +exports.faAmilia = faAmilia; +exports.faAndroid = faAndroid; +exports.faAngellist = faAngellist; +exports.faAngrycreative = faAngrycreative; +exports.faAngular = faAngular; +exports.faAppStore = faAppStore; +exports.faAppStoreIos = faAppStoreIos; +exports.faApper = faApper; +exports.faApple = faApple; +exports.faApplePay = faApplePay; +exports.faAsymmetrik = faAsymmetrik; +exports.faAudible = faAudible; +exports.faAutoprefixer = faAutoprefixer; +exports.faAvianex = faAvianex; +exports.faAviato = faAviato; +exports.faAws = faAws; +exports.faBandcamp = faBandcamp; +exports.faBehance = faBehance; +exports.faBehanceSquare = faBehanceSquare; +exports.faBimobject = faBimobject; +exports.faBitbucket = faBitbucket; +exports.faBitcoin = faBitcoin; +exports.faBity = faBity; +exports.faBlackTie = faBlackTie; +exports.faBlackberry = faBlackberry; +exports.faBlogger = faBlogger; +exports.faBloggerB = faBloggerB; +exports.faBluetooth = faBluetooth; +exports.faBluetoothB = faBluetoothB; +exports.faBtc = faBtc; +exports.faBuromobelexperte = faBuromobelexperte; +exports.faBuysellads = faBuysellads; +exports.faCcAmex = faCcAmex; +exports.faCcApplePay = faCcApplePay; +exports.faCcDinersClub = faCcDinersClub; +exports.faCcDiscover = faCcDiscover; +exports.faCcJcb = faCcJcb; +exports.faCcMastercard = faCcMastercard; +exports.faCcPaypal = faCcPaypal; +exports.faCcStripe = faCcStripe; +exports.faCcVisa = faCcVisa; +exports.faCentercode = faCentercode; +exports.faChrome = faChrome; +exports.faCloudscale = faCloudscale; +exports.faCloudsmith = faCloudsmith; +exports.faCloudversify = faCloudversify; +exports.faCodepen = faCodepen; +exports.faCodiepie = faCodiepie; +exports.faConnectdevelop = faConnectdevelop; +exports.faContao = faContao; +exports.faCpanel = faCpanel; +exports.faCreativeCommons = faCreativeCommons; +exports.faCss3 = faCss3; +exports.faCss3Alt = faCss3Alt; +exports.faCuttlefish = faCuttlefish; +exports.faDAndD = faDAndD; +exports.faDashcube = faDashcube; +exports.faDelicious = faDelicious; +exports.faDeploydog = faDeploydog; +exports.faDeskpro = faDeskpro; +exports.faDeviantart = faDeviantart; +exports.faDigg = faDigg; +exports.faDigitalOcean = faDigitalOcean; +exports.faDiscord = faDiscord; +exports.faDiscourse = faDiscourse; +exports.faDochub = faDochub; +exports.faDocker = faDocker; +exports.faDraft2digital = faDraft2digital; +exports.faDribbble = faDribbble; +exports.faDribbbleSquare = faDribbbleSquare; +exports.faDropbox = faDropbox; +exports.faDrupal = faDrupal; +exports.faDyalog = faDyalog; +exports.faEarlybirds = faEarlybirds; +exports.faEdge = faEdge; +exports.faEmber = faEmber; +exports.faEmpire = faEmpire; +exports.faEnvira = faEnvira; +exports.faErlang = faErlang; +exports.faEtsy = faEtsy; +exports.faExpeditedssl = faExpeditedssl; +exports.faFacebook = faFacebook; +exports.faFacebookF = faFacebookF; +exports.faFacebookMessenger = faFacebookMessenger; +exports.faFacebookSquare = faFacebookSquare; +exports.faFirefox = faFirefox; +exports.faFirstOrder = faFirstOrder; +exports.faFirstdraft = faFirstdraft; +exports.faFlickr = faFlickr; +exports.faFly = faFly; +exports.faFontAwesome = faFontAwesome; +exports.faFontAwesomeAlt = faFontAwesomeAlt; +exports.faFontAwesomeFlag = faFontAwesomeFlag; +exports.faFonticons = faFonticons; +exports.faFonticonsFi = faFonticonsFi; +exports.faFortAwesome = faFortAwesome; +exports.faFortAwesomeAlt = faFortAwesomeAlt; +exports.faForumbee = faForumbee; +exports.faFoursquare = faFoursquare; +exports.faFreeCodeCamp = faFreeCodeCamp; +exports.faFreebsd = faFreebsd; +exports.faGetPocket = faGetPocket; +exports.faGg = faGg; +exports.faGgCircle = faGgCircle; +exports.faGit = faGit; +exports.faGitSquare = faGitSquare; +exports.faGithub = faGithub; +exports.faGithubAlt = faGithubAlt; +exports.faGithubSquare = faGithubSquare; +exports.faGitkraken = faGitkraken; +exports.faGitlab = faGitlab; +exports.faGitter = faGitter; +exports.faGlide = faGlide; +exports.faGlideG = faGlideG; +exports.faGofore = faGofore; +exports.faGoodreads = faGoodreads; +exports.faGoodreadsG = faGoodreadsG; +exports.faGoogle = faGoogle; +exports.faGoogleDrive = faGoogleDrive; +exports.faGooglePlay = faGooglePlay; +exports.faGooglePlus = faGooglePlus; +exports.faGooglePlusG = faGooglePlusG; +exports.faGooglePlusSquare = faGooglePlusSquare; +exports.faGoogleWallet = faGoogleWallet; +exports.faGratipay = faGratipay; +exports.faGrav = faGrav; +exports.faGripfire = faGripfire; +exports.faGrunt = faGrunt; +exports.faGulp = faGulp; +exports.faHackerNews = faHackerNews; +exports.faHackerNewsSquare = faHackerNewsSquare; +exports.faHireAHelper = faHireAHelper; +exports.faHooli = faHooli; +exports.faHotjar = faHotjar; +exports.faHouzz = faHouzz; +exports.faHtml5 = faHtml5; +exports.faHubspot = faHubspot; +exports.faImdb = faImdb; +exports.faInstagram = faInstagram; +exports.faInternetExplorer = faInternetExplorer; +exports.faIoxhost = faIoxhost; +exports.faItunes = faItunes; +exports.faItunesNote = faItunesNote; +exports.faJenkins = faJenkins; +exports.faJoget = faJoget; +exports.faJoomla = faJoomla; +exports.faJs = faJs; +exports.faJsSquare = faJsSquare; +exports.faJsfiddle = faJsfiddle; +exports.faKeycdn = faKeycdn; +exports.faKickstarter = faKickstarter; +exports.faKickstarterK = faKickstarterK; +exports.faLaravel = faLaravel; +exports.faLastfm = faLastfm; +exports.faLastfmSquare = faLastfmSquare; +exports.faLeanpub = faLeanpub; +exports.faLess = faLess; +exports.faLine = faLine; +exports.faLinkedin = faLinkedin; +exports.faLinkedinIn = faLinkedinIn; +exports.faLinode = faLinode; +exports.faLinux = faLinux; +exports.faLyft = faLyft; +exports.faMagento = faMagento; +exports.faMaxcdn = faMaxcdn; +exports.faMedapps = faMedapps; +exports.faMedium = faMedium; +exports.faMediumM = faMediumM; +exports.faMedrt = faMedrt; +exports.faMeetup = faMeetup; +exports.faMicrosoft = faMicrosoft; +exports.faMix = faMix; +exports.faMixcloud = faMixcloud; +exports.faMizuni = faMizuni; +exports.faModx = faModx; +exports.faMonero = faMonero; +exports.faNapster = faNapster; +exports.faNintendoSwitch = faNintendoSwitch; +exports.faNode = faNode; +exports.faNodeJs = faNodeJs; +exports.faNpm = faNpm; +exports.faNs8 = faNs8; +exports.faNutritionix = faNutritionix; +exports.faOdnoklassniki = faOdnoklassniki; +exports.faOdnoklassnikiSquare = faOdnoklassnikiSquare; +exports.faOpencart = faOpencart; +exports.faOpenid = faOpenid; +exports.faOpera = faOpera; +exports.faOptinMonster = faOptinMonster; +exports.faOsi = faOsi; +exports.faPage4 = faPage4; +exports.faPagelines = faPagelines; +exports.faPalfed = faPalfed; +exports.faPatreon = faPatreon; +exports.faPaypal = faPaypal; +exports.faPeriscope = faPeriscope; +exports.faPhabricator = faPhabricator; +exports.faPhoenixFramework = faPhoenixFramework; +exports.faPiedPiper = faPiedPiper; +exports.faPiedPiperAlt = faPiedPiperAlt; +exports.faPiedPiperPp = faPiedPiperPp; +exports.faPinterest = faPinterest; +exports.faPinterestP = faPinterestP; +exports.faPinterestSquare = faPinterestSquare; +exports.faPlaystation = faPlaystation; +exports.faProductHunt = faProductHunt; +exports.faPushed = faPushed; +exports.faPython = faPython; +exports.faQq = faQq; +exports.faQuora = faQuora; +exports.faRavelry = faRavelry; +exports.faReact = faReact; +exports.faRebel = faRebel; +exports.faRedRiver = faRedRiver; +exports.faReddit = faReddit; +exports.faRedditAlien = faRedditAlien; +exports.faRedditSquare = faRedditSquare; +exports.faRendact = faRendact; +exports.faRenren = faRenren; +exports.faReplyd = faReplyd; +exports.faResolving = faResolving; +exports.faRocketchat = faRocketchat; +exports.faRockrms = faRockrms; +exports.faSafari = faSafari; +exports.faSass = faSass; +exports.faSchlix = faSchlix; +exports.faScribd = faScribd; +exports.faSearchengin = faSearchengin; +exports.faSellcast = faSellcast; +exports.faSellsy = faSellsy; +exports.faServicestack = faServicestack; +exports.faShirtsinbulk = faShirtsinbulk; +exports.faSimplybuilt = faSimplybuilt; +exports.faSistrix = faSistrix; +exports.faSkyatlas = faSkyatlas; +exports.faSkype = faSkype; +exports.faSlack = faSlack; +exports.faSlackHash = faSlackHash; +exports.faSlideshare = faSlideshare; +exports.faSnapchat = faSnapchat; +exports.faSnapchatGhost = faSnapchatGhost; +exports.faSnapchatSquare = faSnapchatSquare; +exports.faSoundcloud = faSoundcloud; +exports.faSpeakap = faSpeakap; +exports.faSpotify = faSpotify; +exports.faStackExchange = faStackExchange; +exports.faStackOverflow = faStackOverflow; +exports.faStaylinked = faStaylinked; +exports.faSteam = faSteam; +exports.faSteamSquare = faSteamSquare; +exports.faSteamSymbol = faSteamSymbol; +exports.faStickerMule = faStickerMule; +exports.faStrava = faStrava; +exports.faStripe = faStripe; +exports.faStripeS = faStripeS; +exports.faStudiovinari = faStudiovinari; +exports.faStumbleupon = faStumbleupon; +exports.faStumbleuponCircle = faStumbleuponCircle; +exports.faSuperpowers = faSuperpowers; +exports.faSupple = faSupple; +exports.faTelegram = faTelegram; +exports.faTelegramPlane = faTelegramPlane; +exports.faTencentWeibo = faTencentWeibo; +exports.faThemeisle = faThemeisle; +exports.faTrello = faTrello; +exports.faTripadvisor = faTripadvisor; +exports.faTumblr = faTumblr; +exports.faTumblrSquare = faTumblrSquare; +exports.faTwitch = faTwitch; +exports.faTwitter = faTwitter; +exports.faTwitterSquare = faTwitterSquare; +exports.faTypo3 = faTypo3; +exports.faUber = faUber; +exports.faUikit = faUikit; +exports.faUniregistry = faUniregistry; +exports.faUntappd = faUntappd; +exports.faUsb = faUsb; +exports.faUssunnah = faUssunnah; +exports.faVaadin = faVaadin; +exports.faViacoin = faViacoin; +exports.faViadeo = faViadeo; +exports.faViadeoSquare = faViadeoSquare; +exports.faViber = faViber; +exports.faVimeo = faVimeo; +exports.faVimeoSquare = faVimeoSquare; +exports.faVimeoV = faVimeoV; +exports.faVine = faVine; +exports.faVk = faVk; +exports.faVnv = faVnv; +exports.faVuejs = faVuejs; +exports.faWeibo = faWeibo; +exports.faWeixin = faWeixin; +exports.faWhatsapp = faWhatsapp; +exports.faWhatsappSquare = faWhatsappSquare; +exports.faWhmcs = faWhmcs; +exports.faWikipediaW = faWikipediaW; +exports.faWindows = faWindows; +exports.faWordpress = faWordpress; +exports.faWordpressSimple = faWordpressSimple; +exports.faWpbeginner = faWpbeginner; +exports.faWpexplorer = faWpexplorer; +exports.faWpforms = faWpforms; +exports.faXbox = faXbox; +exports.faXing = faXing; +exports.faXingSquare = faXingSquare; +exports.faYCombinator = faYCombinator; +exports.faYahoo = faYahoo; +exports.faYandex = faYandex; +exports.faYandexInternational = faYandexInternational; +exports.faYelp = faYelp; +exports.faYoast = faYoast; +exports.faYoutube = faYoutube; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/package.json b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/package.json new file mode 100644 index 000000000..f942386c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-brands/package.json @@ -0,0 +1,48 @@ +{ + "description": "The iconic font, CSS, and SVG framework", + "keywords": [ + "font", + "awesome", + "fontawesome", + "icon", + "svg", + "bootstrap" + ], + "homepage": "https://fontawesome.com", + "bugs": { + "url": "http://github.com/FortAwesome/Font-Awesome/issues" + }, + "author": { + "name": "Dave Gandy", + "email": "dave@fontawesome.com", + "web": "http://twitter.com/davegandy" + }, + "contributors": [ + { + "name": "Brian Talbot", + "web": "http://twitter.com/talbs" + }, + { + "name": "Travis Chase", + "web": "http://twitter.com/supercodepoet" + }, + { + "name": "Rob Madole", + "web": "http://twitter.com/robmadole" + }, + { + "name": "Geremia Taglialatela", + "web": "http://twitter.com/gtagliala" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome" + }, + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "version": "5.0.1", + "name": "@fortawesome/fontawesome-free-brands" +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/LICENSE.txt b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressBook.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressBook.js new file mode 100644 index 000000000..582be9883 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressBook.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M320 320v72c0 13.255-10.745 24-24 24H152c-13.255 0-24-10.745-24-24v-72c0-21.431 14.207-40.266 34.813-46.153l18.064-5.161C193.629 275.884 208.342 280 224 280s30.371-4.116 43.122-11.314l18.064 5.161C305.793 279.734 320 298.569 320 320zm-96-64c35.346 0 64-28.654 64-64s-28.654-64-64-64-64 28.654-64 64 28.654 64 64 64zm192-96v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v48c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V48C32 21.49 53.49 0 80 0h288c26.51 0 48 21.49 48 48v48h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20zm-48 298V54a6 6 0 0 0-6-6H86a6 6 0 0 0-6 6v404a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressCard.js new file mode 100644 index 000000000..eaa42de40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faAddressCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zm-54-176H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm0 80H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm-284-96c0-30.928 25.072-56 56-56s56 25.072 56 56-25.072 56-56 56-56-25.072-56-56zm136 89.857V340c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12v-42.143a24 24 0 0 1 17.104-22.988l13.464-4.039C140.186 281.568 157.351 288 176 288s35.814-6.432 49.433-17.17l13.464 4.039A24 24 0 0 1 256 297.857z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleDown.js new file mode 100644 index 000000000..49577c18d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleLeft.js new file mode 100644 index 000000000..e07a26d5f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleRight.js new file mode 100644 index 000000000..79a6039b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleUp.js new file mode 100644 index 000000000..e65437f66 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faArrowAltCircleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBell.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBell.js new file mode 100644 index 000000000..48e5fc6f5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBell.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'bell', icon: [448, 512, [], "f0f3", "M425.403 330.939c-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.843 31.843 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095C118.101 62.783 57.143 131.831 57.143 214.857c0 81.933-17.551 99.292-34.543 116.078C-25.496 378.441 9.726 448 66.919 448H160c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h93.08c57.19 0 92.415-69.583 44.323-117.061zM224 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm157.092-72H66.9c-16.762 0-25.135-20.39-13.334-32.191 28.585-28.585 51.577-55.724 51.577-152.952C105.143 149.319 158.462 96 224 96s118.857 53.319 118.857 118.857c0 97.65 23.221 124.574 51.568 152.952C406.278 379.661 397.783 400 381.092 400z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBellSlash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBellSlash.js new file mode 100644 index 000000000..993f8e04f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBellSlash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M130.9 400c-16.762 0-25.135-20.39-13.334-32.191 25.226-25.226 46.094-49.338 50.649-121.48l-46.777-41.274a168.48 168.48 0 0 0-.296 9.802c0 81.933-17.551 99.292-34.543 116.078C38.504 378.441 73.726 448 130.919 448H224c0 35.346 28.654 64 64 64s64-28.654 64-64h44.777l-54.4-48H130.9zM288 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm283.867.553l-67.931-59.571c13.104-24.118 11.524-56.318-14.532-82.042-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.848 31.848 0 0 0 320 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095c-41.471 6.618-77.891 28.571-103.249 59.841L36.459 3.037c-5.058-4.436-12.777-3.956-17.24 1.071L3.056 22.313C-1.407 27.34-.925 35.012 4.134 39.447l535.408 469.516c5.058 4.436 12.777 3.956 17.24-1.071l16.163-18.205c4.462-5.027 3.98-12.699-1.078-17.134zM288 96c65.538 0 118.857 53.319 118.857 118.857 0 97.65 23.221 124.574 51.568 152.952 2.908 2.908 4.573 6.328 5.209 9.832L194.482 141.612C216.258 113.867 250.075 96 288 96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBookmark.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBookmark.js new file mode 100644 index 000000000..5403c328f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBookmark.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBuilding.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBuilding.js new file mode 100644 index 000000000..aa4bc0608 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faBuilding.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'building', icon: [448, 512, [], "f1ad", "M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendar.js new file mode 100644 index 000000000..8b435098a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar', icon: [448, 512, [], "f133", "M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarAlt.js new file mode 100644 index 000000000..12c046cfb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarCheck.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarCheck.js new file mode 100644 index 000000000..aae60697c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarCheck.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarMinus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarMinus.js new file mode 100644 index 000000000..47cd6fc02 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarMinus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarPlus.js new file mode 100644 index 000000000..3ef2023cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarTimes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarTimes.js new file mode 100644 index 000000000..13fab8ac4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCalendarTimes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareDown.js new file mode 100644 index 000000000..1dbd60785 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareLeft.js new file mode 100644 index 000000000..012a76c79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareRight.js new file mode 100644 index 000000000..1761e834b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareUp.js new file mode 100644 index 000000000..3efea45b6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCaretSquareUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faChartBar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faChartBar.js new file mode 100644 index 000000000..bc492f580 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faChartBar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 400c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v324h452zm-356-60v-72c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V140c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V204c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V108c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckCircle.js new file mode 100644 index 000000000..994fcb763 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'check-circle', icon: [512, 512, [], "f058", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckSquare.js new file mode 100644 index 000000000..006368c86 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCheckSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCircle.js new file mode 100644 index 000000000..834d97939 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClipboard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClipboard.js new file mode 100644 index 000000000..eb0898752 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClipboard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'clipboard', icon: [384, 512, [], "f328", "M336 64h-80c0-35.29-28.71-64-64-64s-64 28.71-64 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h42v36c0 6.627 5.373 12 12 12h168c6.627 0 12-5.373 12-12v-36h42a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zM192 40c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClock.js new file mode 100644 index 000000000..068cb9c8e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClone.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClone.js new file mode 100644 index 000000000..9380a51df --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClone.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClosedCaptioning.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClosedCaptioning.js new file mode 100644 index 000000000..3f1df904b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faClosedCaptioning.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComment.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComment.js new file mode 100644 index 000000000..c23d9e7e9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComment.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'comment', icon: [576, 512, [], "f075", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCommentAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCommentAlt.js new file mode 100644 index 000000000..03876c29e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCommentAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160zm-64-160c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComments.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComments.js new file mode 100644 index 000000000..76fa8d0f3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faComments.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'comments', icon: [576, 512, [], "f086", "M574.507 443.86c-5.421 21.261-24.57 36.14-46.511 36.14-32.246 0-66.511-9.99-102.1-29.734-50.64 11.626-109.151 7.877-157.96-13.437 41.144-2.919 80.361-12.339 116.331-28.705 16.322-1.22 32.674-4.32 48.631-9.593C454.404 412.365 490.663 432 527.996 432c-32-17.455-43.219-38.958-46.159-58.502 25.443-18.848 46.159-47.183 46.159-81.135 0-10.495-2.383-21.536-7.041-32.467 7.405-25.93 8.656-50.194 5.185-73.938 32.164 30.461 49.856 69.128 49.856 106.405 0 33.893-12.913 65.047-34.976 91.119 2.653 2.038 5.924 4.176 9.962 6.378 19.261 10.508 28.947 32.739 23.525 54zM240.002 80C117.068 80 48.004 152.877 48.004 210.909c0 38.196 24.859 70.072 55.391 91.276-3.527 21.988-16.991 46.179-55.391 65.815 44.8 0 88.31-22.089 114.119-37.653 25.52 7.906 51.883 11.471 77.879 11.471C362.998 341.818 432 268.976 432 210.909 432 152.882 362.943 80 240.002 80m0-48C390.193 32 480 126.026 480 210.909c0 22.745-6.506 46.394-18.816 68.391-11.878 21.226-28.539 40.294-49.523 56.674-21.593 16.857-46.798 30.045-74.913 39.197-29.855 9.719-62.405 14.646-96.746 14.646-24.449 0-48.34-2.687-71.292-8.004C126.311 404.512 85.785 416 48.004 416c-22.18 0-41.472-15.197-46.665-36.761-5.194-21.563 5.064-43.878 24.811-53.976 7.663-3.918 13.324-7.737 17.519-11.294-7.393-7.829-13.952-16.124-19.634-24.844C8.09 264.655.005 238.339.005 210.909.005 126.259 89.508 32 240.002 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCompass.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCompass.js new file mode 100644 index 000000000..963d57489 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCompass.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'compass', icon: [512, 512, [], "f14e", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm91.326-312.131l-33.359 137.779a24.005 24.005 0 0 1-6.772 11.729l-102.64 97.779c-17.104 16.293-45.56.434-39.88-23.024l33.359-137.779a23.997 23.997 0 0 1 6.772-11.729l102.642-97.779c17.285-16.47 45.494-.175 39.878 23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopy.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopy.js new file mode 100644 index 000000000..cbc6a33a0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopy.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'copy', icon: [448, 512, [], "f0c5", "M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopyright.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopyright.js new file mode 100644 index 000000000..c3e19b87e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCopyright.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCreditCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCreditCard.js new file mode 100644 index 000000000..cc3b81296 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faCreditCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faDotCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faDotCircle.js new file mode 100644 index 000000000..889072023 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faDotCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEdit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEdit.js new file mode 100644 index 000000000..ee0647c8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEdit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'edit', icon: [576, 512, [], "f044", "M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelope.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelope.js new file mode 100644 index 000000000..a4fe288ce --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelope.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelopeOpen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelopeOpen.js new file mode 100644 index 000000000..5769983df --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEnvelopeOpen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEyeSlash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEyeSlash.js new file mode 100644 index 000000000..5e0f23f19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faEyeSlash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFile.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFile.js new file mode 100644 index 000000000..1eb80b033 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFile.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file', icon: [384, 512, [], "f15b", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAlt.js new file mode 100644 index 000000000..41b9c19e3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileArchive.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileArchive.js new file mode 100644 index 000000000..a9aaabfbb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileArchive.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM256 51.882L332.118 128H256V51.882zM336 464H48V48h79.714v16h32V48H208v104c0 13.255 10.745 24 24 24h104v288zM192.27 96h-32V64h32v32zm-32 0v32h-32V96h32zm0 64v32h-32v-32h32zm32 0h-32v-32h32v32zm1.909 105.678A12 12 0 0 0 182.406 256H160.27v-32h-32v32l-19.69 97.106C101.989 385.611 126.834 416 160 416c33.052 0 57.871-30.192 51.476-62.62l-17.297-87.702zM160.27 390.073c-17.918 0-32.444-12.105-32.444-27.036 0-14.932 14.525-27.036 32.444-27.036s32.444 12.105 32.444 27.036c0 14.931-14.526 27.036-32.444 27.036zm32-166.073h-32v-32h32v32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAudio.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAudio.js new file mode 100644 index 000000000..7cb3ac63d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileAudio.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileCode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileCode.js new file mode 100644 index 000000000..0896c13b4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileCode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm101.677-115.115L116.854 320l32.822-28.885a8.793 8.793 0 0 0 .605-12.624l-17.403-18.564c-3.384-3.613-8.964-3.662-12.438-.401L62.78 313.58c-3.703 3.474-3.704 9.367.001 12.84l57.659 54.055a8.738 8.738 0 0 0 6.012 2.381 8.746 8.746 0 0 0 6.427-2.782l17.403-18.563a8.795 8.795 0 0 0-.605-12.626zm84.284-127.85l-24.401-7.084a8.796 8.796 0 0 0-10.905 5.998L144.04 408.061c-1.353 4.66 1.338 9.552 5.998 10.905l24.403 7.084c4.68 1.355 9.557-1.354 10.905-5.998l54.612-188.112c1.354-4.66-1.337-9.552-5.997-10.905zm87.258 92.545l-57.658-54.055c-3.526-3.307-9.099-3.165-12.439.401l-17.403 18.563a8.795 8.795 0 0 0 .605 12.625L267.146 320l-32.822 28.885a8.793 8.793 0 0 0-.605 12.624l17.403 18.564a8.797 8.797 0 0 0 12.439.401h-.001l57.66-54.055c3.703-3.473 3.703-9.366-.001-12.839z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileExcel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileExcel.js new file mode 100644 index 000000000..83d35a060 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileExcel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileImage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileImage.js new file mode 100644 index 000000000..5ebc10952 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileImage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePdf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePdf.js new file mode 100644 index 000000000..00c1439c1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePdf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePowerpoint.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePowerpoint.js new file mode 100644 index 000000000..f187960c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFilePowerpoint.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileVideo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileVideo.js new file mode 100644 index 000000000..b0089eaef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileVideo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileWord.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileWord.js new file mode 100644 index 000000000..24b7c488c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFileWord.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFlag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFlag.js new file mode 100644 index 000000000..9964f36f8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFlag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'flag', icon: [512, 512, [], "f024", "M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolder.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolder.js new file mode 100644 index 000000000..fd4219ca5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolder.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-6 272H54c-3.314 0-6-2.678-6-5.992V117.992A5.993 5.993 0 0 1 54 112h134.118l64 64H458a6 6 0 0 1 6 6v212a6 6 0 0 1-6 6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolderOpen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolderOpen.js new file mode 100644 index 000000000..a40e91479 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFolderOpen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M527.943 224H480v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h400a48.001 48.001 0 0 0 40.704-22.56l79.942-128c19.948-31.917-3.038-73.44-40.703-73.44zM54 112h134.118l64 64H426a6 6 0 0 1 6 6v42H152a48 48 0 0 0-41.098 23.202L48 351.449V117.993A5.993 5.993 0 0 1 54 112zm394 288H72l77.234-128H528l-80 128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFrown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFrown.js new file mode 100644 index 000000000..4ef8af9f1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFrown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'frown', icon: [512, 512, [], "f119", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm171.547 201.782c-56.595-76.964-158.383-77.065-215.057-.001-18.82 25.593 19.858 54.018 38.67 28.438 37.511-51.01 100.365-50.796 137.717-.001 18.509 25.172 57.821-2.395 38.67-28.436z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFutbol.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFutbol.js new file mode 100644 index 000000000..1fd195931 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faFutbol.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M207.898 325.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-455.998-.19L48 256c0 44.7 14.015 87.242 39.95 122.626l7.982-35.118 88.595 10.871 37.775 80.985-30.978 18.427c41.832 13.631 87.598 13.606 129.354 0L289.7 435.364l37.775-80.985 88.594-10.871 7.982 35.118C449.985 343.242 464 300.7 464 256l-.002-.19-27.003 23.561-65.223-60.875 17.122-87.779 35.538 3.183c-25.216-34.63-61.309-62.053-104.577-75.951l14.143 33.091L256 134.25l-77.996-43.21 14.144-33.091C148.868 71.851 112.782 99.277 87.57 133.9l35.81-3.183 16.849 87.779-65.223 60.875-27.004-23.561z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faGem.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faGem.js new file mode 100644 index 000000000..f72f33ee6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faGem.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'gem', icon: [576, 512, [], "f3a5", "M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandLizard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandLizard.js new file mode 100644 index 000000000..ea3e186a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandLizard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPaper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPaper.js new file mode 100644 index 000000000..f9680ac48 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPaper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPeace.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPeace.js new file mode 100644 index 000000000..ef510f3af --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPeace.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointDown.js new file mode 100644 index 000000000..5f490b365 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-point-down', icon: [448, 512, [], "f0a7", "M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointLeft.js new file mode 100644 index 000000000..fd599a392 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointRight.js new file mode 100644 index 000000000..9ec2b20c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointUp.js new file mode 100644 index 000000000..efa3cc822 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-point-up', icon: [448, 512, [], "f0a6", "M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointer.js new file mode 100644 index 000000000..6d0f74680 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandPointer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandRock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandRock.js new file mode 100644 index 000000000..878bdbef0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandRock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandScissors.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandScissors.js new file mode 100644 index 000000000..8093a77b5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandScissors.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandSpock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandSpock.js new file mode 100644 index 000000000..011f7a3e7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandSpock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandshake.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandshake.js new file mode 100644 index 000000000..0400d2cbf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHandshake.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M616 96h-48c-7.107 0-13.49 3.091-17.884 8H526.59l-31.13-36.3-.16-.18A103.974 103.974 0 0 0 417.03 32h-46.55c-17.75 0-34.9 4.94-49.69 14.01C304.33 36.93 285.67 32 266.62 32h-32.11c-28.903 0-57.599 11.219-79.2 32.8L116.12 104H89.884C85.49 99.091 79.107 96 72 96H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h48c10.449 0 19.334-6.68 22.629-16h18.801l75.35 67.57c25.542 26.45 59.925 44.43 96.58 44.43 16.39 0 32.28-3.85 46.1-10.93 24.936.496 51.101-10.368 69.07-31.41 19.684-5.579 37.503-17.426 50.72-34.6 20.989-4.401 40.728-16.492 53.42-35.06h40.701c3.295 9.32 12.18 16 22.629 16h48c13.255 0 24-10.745 24-24V120c0-13.255-10.745-24-24-24zM48 352c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16zm412.52-5.76c-15.35 14.295-36.884 11.328-39.95 8 1.414 13.382-18.257 41.043-49.08 38.88-5.541 18.523-28.218 33.826-51.49 25.75-8.89 8.89-22.46 13.13-34.64 13.13-24.95 0-47.77-14.54-63.14-30.91l-81.3-72.91a31.976 31.976 0 0 0-21.36-8.18H96V152h26.75c8.48 0 16.62-3.37 22.62-9.37l43.88-43.88A64.004 64.004 0 0 1 234.51 80h32.11c5.8 0 11.51.79 17 2.3l-43.27 50.49c-23.56 27.48-23.84 67.62-.66 95.44 32.388 38.866 91.378 39.228 124.48 1.98l25.98-30.08L462.59 296c13.44 14.6 10.95 38.13-2.07 50.24zM544 320h-24.458c.104-20.261-6.799-39.33-19.762-54.4L421.7 162.28c4.51-9.51 2.34-21.23-6.01-28.45-10.075-8.691-25.23-7.499-33.86 2.48l-53.63 62.12c-13.828 15.41-38.223 15.145-51.64-.93a25.857 25.857 0 0 1 .23-33.47l57.92-67.58A47.09 47.09 0 0 1 370.48 80h46.55c16.11 0 31.44 6.94 42.07 19.04L504.52 152H544v168zm48 32c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHdd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHdd.js new file mode 100644 index 000000000..812d5976d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHdd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHeart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHeart.js new file mode 100644 index 000000000..a6338638e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHeart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'heart', icon: [576, 512, [], "f004", "M257.3 475.4L92.5 313.6C85.4 307 24 248.1 24 174.8 24 84.1 80.8 24 176 24c41.4 0 80.6 22.8 112 49.8 31.3-27 70.6-49.8 112-49.8 91.7 0 152 56.5 152 150.8 0 52-31.8 103.5-68.1 138.7l-.4.4-164.8 161.5a43.7 43.7 0 0 1-61.4 0zM125.9 279.1L288 438.3l161.8-158.7c27.3-27 54.2-66.3 54.2-104.8C504 107.9 465.8 72 400 72c-47.2 0-92.8 49.3-112 68.4-17-17-64-68.4-112-68.4-65.9 0-104 35.9-104 102.8 0 37.3 26.7 78.9 53.9 104.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHospital.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHospital.js new file mode 100644 index 000000000..4198573f7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHospital.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHourglass.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHourglass.js new file mode 100644 index 000000000..ed0524982 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faHourglass.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'hourglass', icon: [384, 512, [], "f254", "M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdBadge.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdBadge.js new file mode 100644 index 000000000..d08a0d961 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdBadge.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M192 128c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64 28.654-64 64-64m61.187 145.847l-18.064-5.161C222.371 275.884 207.658 280 192 280s-30.371-4.116-43.122-11.314l-18.064 5.161C110.207 279.734 96 298.569 96 320v72c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-72c0-21.431-14.207-40.266-34.813-46.153zM0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48zm336 32v378a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V80h288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdCard.js new file mode 100644 index 000000000..c0b335dfd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faIdCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M404 256H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm12 68v-24c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12zm96-212v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zm-48 282V144H48v250a6 6 0 0 0 6 6h404a6 6 0 0 0 6-6zm-288-98c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56 25.072 56 56 56zm62.896 10.869l-13.464-4.039C211.814 313.568 194.649 320 176 320s-35.814-6.432-49.433-17.17l-13.464 4.039A24 24 0 0 0 96 329.857V372c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12v-42.143a24 24 0 0 0-17.104-22.988z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImage.js new file mode 100644 index 000000000..4d38ac666 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'image', icon: [512, 512, [], "f03e", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImages.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImages.js new file mode 100644 index 000000000..73efd8cf9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faImages.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faKeyboard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faKeyboard.js new file mode 100644 index 000000000..d58e18096 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faKeyboard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLemon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLemon.js new file mode 100644 index 000000000..91cd2c728 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLemon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'lemon', icon: [512, 512, [], "f094", "M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLifeRing.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLifeRing.js new file mode 100644 index 000000000..da769a3f6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLifeRing.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLightbulb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLightbulb.js new file mode 100644 index 000000000..35908035b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faLightbulb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zM128 176c0-35.29 28.71-64 64-64 8.837 0 16-7.164 16-16s-7.163-16-16-16c-52.935 0-96 43.065-96 96 0 8.836 7.164 16 16 16s16-7.164 16-16zm64-128c70.734 0 128 57.254 128 128 0 77.602-37.383 60.477-80.98 160h-94.04C101.318 236.33 64 253.869 64 176c0-70.735 57.254-128 128-128m0-48C94.805 0 16 78.803 16 176c0 101.731 51.697 91.541 90.516 192.674 3.55 9.249 12.47 15.326 22.376 15.326h126.215c9.906 0 18.826-6.078 22.376-15.326C316.303 267.541 368 277.731 368 176 368 78.803 289.195 0 192 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faListAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faListAlt.js new file mode 100644 index 000000000..0f37c274e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faListAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMap.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMap.js new file mode 100644 index 000000000..34da38e07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMap.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'map', icon: [576, 512, [], "f279", "M508.505 36.17L381.517 92.576 207.179 34.463a47.992 47.992 0 0 0-34.674 1.674l-144 64A48 48 0 0 0 0 144v287.967c0 34.938 35.991 57.864 67.495 43.863l126.988-56.406 174.339 58.113a47.992 47.992 0 0 0 34.674-1.674l144-64A48 48 0 0 0 576 368V80.033c0-34.938-35.991-57.864-67.495-43.863zM360 424l-144-48V88l144 48v288zm-312 8V144l120-53.333v288L48 432zm480-64l-120 53.333v-288L528 80v288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMeh.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMeh.js new file mode 100644 index 000000000..2b8d25911 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMeh.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'meh', icon: [512, 512, [], "f11a", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm136 184H184c-31.776 0-31.749 48 0 48h144c31.776 0 31.749-48 0-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMinusSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMinusSquare.js new file mode 100644 index 000000000..55839d7aa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMinusSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'minus-square', icon: [448, 512, [], "f146", "M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoneyBillAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoneyBillAlt.js new file mode 100644 index 000000000..11a363739 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoneyBillAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M320 144c-53.021 0-96 50.143-96 112 0 61.847 42.977 112 96 112 53 0 96-50.13 96-112 0-61.857-42.979-112-96-112zm48 164.428c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.901c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.75 3.916 11.75 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.902zM616 64H24C10.745 64 0 74.745 0 88v335c0 13.255 10.745 24 24 24h592c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM512 400H128c0-44.183-35.817-80-80-80V192c44.183 0 80-35.817 80-80h384c0 44.183 35.817 80 80 80v128c-44.183 0-80 35.817-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoon.js new file mode 100644 index 000000000..945783bd7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faMoon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'moon', icon: [512, 512, [], "f186", "M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faNewspaper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faNewspaper.js new file mode 100644 index 000000000..e41248ca7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faNewspaper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectGroup.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectGroup.js new file mode 100644 index 000000000..a44a947dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectGroup.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'object-group', icon: [512, 512, [], "f247", "M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectUngroup.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectUngroup.js new file mode 100644 index 000000000..1dd5a2da3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faObjectUngroup.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPaperPlane.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPaperPlane.js new file mode 100644 index 000000000..fd68da50b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPaperPlane.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPauseCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPauseCircle.js new file mode 100644 index 000000000..7c1bc49dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPauseCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlayCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlayCircle.js new file mode 100644 index 000000000..7bb3904e5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlayCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'play-circle', icon: [512, 512, [], "f144", "M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlusSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlusSquare.js new file mode 100644 index 000000000..3a014091b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faPlusSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faQuestionCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faQuestionCircle.js new file mode 100644 index 000000000..cec086827 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faQuestionCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'question-circle', icon: [512, 512, [], "f059", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faRegistered.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faRegistered.js new file mode 100644 index 000000000..0c584e630 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faRegistered.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'registered', icon: [512, 512, [], "f25d", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSave.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSave.js new file mode 100644 index 000000000..383e4ac19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSave.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faShareSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faShareSquare.js new file mode 100644 index 000000000..a390f4d31 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faShareSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'share-square', icon: [576, 512, [], "f14d", "M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSmile.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSmile.js new file mode 100644 index 000000000..cc971f7f6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSmile.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'smile', icon: [512, 512, [], "f118", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm195.372 182.219c18.819-25.592-19.856-54.017-38.67-28.438-50.135 68.177-135.229 68.18-185.367 0-18.828-25.601-57.478 2.861-38.67 28.438 69.298 94.231 193.323 94.351 262.707 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSnowflake.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSnowflake.js new file mode 100644 index 000000000..915eea229 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSnowflake.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M438.237 355.927l-66.574-38.54 59.448-10.327c5.846-1.375 10.609-5.183 13.458-10.13 2.48-4.307 3.506-9.478 2.524-14.651-2.11-11.115-12.686-18.039-23.621-15.467l-85.423 31.115L255.914 256l82.136-41.926 85.423 31.115c10.936 2.572 21.512-4.352 23.621-15.467 2.111-11.115-5.046-22.209-15.981-24.781l-59.448-10.327 66.573-38.54c9.54-5.523 12.615-18.092 6.867-28.074-5.748-9.982-18.14-13.596-27.68-8.074l-66.574 38.54 20.805-56.787c3.246-10.782-2.758-22.542-13.413-26.268-10.654-3.725-21.922 1.997-25.168 12.779l-15.838 89.735-72.423 41.926V136l69.585-58.621c7.689-8.21 6.997-20.856-1.548-28.245-8.545-7.391-21.705-6.723-29.394 1.486l-38.644 46.46V20c0-11.046-9.318-20-20.813-20s-20.813 8.954-20.813 20v77.08l-38.644-46.46c-7.689-8.21-20.849-8.876-29.394-1.486-8.544 7.389-9.236 20.035-1.547 28.245L203.187 136v83.853l-72.423-41.926-15.838-89.736c-3.247-10.782-14.515-16.504-25.169-12.779-10.656 3.725-16.659 15.486-13.413 26.268l20.805 56.787-66.573-38.54c-9.54-5.523-21.933-1.908-27.68 8.074s-2.673 22.551 6.867 28.074l66.574 38.54-59.449 10.328C5.953 207.515-1.202 218.609.907 229.724c2.11 11.114 12.686 18.038 23.622 15.466l85.422-31.115L192.086 256l-82.136 41.926-85.423-31.115c-10.936-2.572-21.511 4.352-23.622 15.466-2.109 11.113 5.046 22.209 15.981 24.781l59.449 10.328-66.574 38.54C.223 361.449-2.852 374.018 2.896 384s18.14 13.597 27.68 8.074l66.574-38.54-20.805 56.786c-1.735 5.764-.828 11.805 2.02 16.751 2.48 4.307 6.433 7.784 11.392 9.517 10.655 3.725 21.923-1.997 25.169-12.779l15.838-89.736 72.423-41.926V376l-69.585 58.621c-7.69 8.21-6.997 20.855 1.547 28.245 8.544 7.388 21.705 6.723 29.394-1.487l38.644-46.46V492c0 11.046 9.318 20 20.813 20s20.813-8.954 20.813-20v-77.081l38.644 46.46c4.111 4.389 9.782 6.621 15.478 6.621 4.96 0 9.939-1.694 13.916-5.134 8.545-7.39 9.237-20.035 1.548-28.245L244.813 376v-83.853l72.423 41.926 15.838 89.736c3.246 10.782 14.514 16.504 25.168 12.779 10.653-3.726 16.659-15.487 13.412-26.268l-20.805-56.787 66.574 38.54c9.54 5.523 21.933 1.908 27.68-8.074 5.749-9.981 2.675-22.55-6.866-28.072z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSquare.js new file mode 100644 index 000000000..bd7c8d027 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStar.js new file mode 100644 index 000000000..e61f6c0a1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'star', icon: [576, 512, [], "f005", "M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStarHalf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStarHalf.js new file mode 100644 index 000000000..14c3d4f15 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStarHalf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStickyNote.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStickyNote.js new file mode 100644 index 000000000..93b99d1f8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStickyNote.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStopCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStopCircle.js new file mode 100644 index 000000000..9d31d3688 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faStopCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSun.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSun.js new file mode 100644 index 000000000..dd298ebcb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faSun.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'sun', icon: [512, 512, [], "f185", "M220.116 487.936l-20.213-49.425a3.992 3.992 0 0 0-5.808-1.886l-45.404 28.104c-29.466 18.24-66.295-8.519-58.054-42.179l12.699-51.865a3.993 3.993 0 0 0-3.59-4.941l-53.251-3.951c-34.554-2.562-48.632-45.855-22.174-68.247L65.08 259.05a3.992 3.992 0 0 0 0-6.106l-40.76-34.497c-26.45-22.384-12.39-65.682 22.174-68.246l53.251-3.951a3.993 3.993 0 0 0 3.59-4.941L90.637 89.443c-8.239-33.656 28.581-60.42 58.054-42.179l45.403 28.104a3.993 3.993 0 0 0 5.808-1.887l20.213-49.425c13.116-32.071 58.638-32.081 71.758 0l20.212 49.424a3.994 3.994 0 0 0 5.809 1.887l45.403-28.104c29.464-18.236 66.297 8.513 58.054 42.179l-12.699 51.865a3.995 3.995 0 0 0 3.59 4.941l53.251 3.951c34.553 2.563 48.633 45.854 22.175 68.246l-40.76 34.497a3.993 3.993 0 0 0 0 6.107l40.76 34.496c26.511 22.441 12.322 65.689-22.175 68.247l-53.251 3.951a3.993 3.993 0 0 0-3.589 4.942l12.698 51.864c8.241 33.658-28.583 60.421-58.054 42.18l-45.403-28.104a3.994 3.994 0 0 0-5.809 1.887l-20.212 49.424c-13.159 32.178-58.675 31.993-71.757 0zm16.814-64.568l19.064 46.616 19.064-46.615c10.308-25.2 40.778-35.066 63.892-20.759l42.822 26.507-11.976-48.919c-6.475-26.444 12.38-52.339 39.487-54.349l50.226-3.726-38.444-32.536c-20.782-17.591-20.747-49.621.001-67.18l38.442-32.536-50.225-3.727c-27.151-2.015-45.95-27.948-39.488-54.349l11.978-48.919-42.823 26.507c-23.151 14.327-53.603 4.4-63.892-20.76l-19.064-46.615-19.064 46.617c-10.305 25.198-40.778 35.066-63.891 20.76l-42.823-26.508 11.977 48.918c6.474 26.446-12.381 52.338-39.488 54.35l-50.224 3.726 38.443 32.537c20.782 17.588 20.747 49.619 0 67.178L52.48 322.123l50.226 3.726c27.151 2.014 45.95 27.947 39.487 54.349l-11.977 48.919 42.823-26.507c23.188-14.355 53.622-4.352 63.891 20.758zM256 384c-70.58 0-128-57.421-128-128 0-70.58 57.42-128 128-128 70.579 0 128 57.42 128 128 0 70.579-57.421 128-128 128zm0-208c-44.112 0-80 35.888-80 80s35.888 80 80 80 80-35.888 80-80-35.888-80-80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsDown.js new file mode 100644 index 000000000..51cab3d3e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsUp.js new file mode 100644 index 000000000..f06cdb52c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faThumbsUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTimesCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTimesCircle.js new file mode 100644 index 000000000..a1b53a588 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTimesCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTrashAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTrashAlt.js new file mode 100644 index 000000000..cf2528492 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faTrashAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M192 188v216c0 6.627-5.373 12-12 12h-24c-6.627 0-12-5.373-12-12V188c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12zm100-12h-24c-6.627 0-12 5.373-12 12v216c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12V188c0-6.627-5.373-12-12-12zm132-96c13.255 0 24 10.745 24 24v12c0 6.627-5.373 12-12 12h-20v336c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V128H12c-6.627 0-12-5.373-12-12v-12c0-13.255 10.745-24 24-24h74.411l34.018-56.696A48 48 0 0 1 173.589 0h100.823a48 48 0 0 1 41.16 23.304L349.589 80H424zm-269.611 0h139.223L276.16 50.913A6 6 0 0 0 271.015 48h-94.028a6 6 0 0 0-5.145 2.913L154.389 80zM368 128H80v330a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6V128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUser.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUser.js new file mode 100644 index 000000000..d5f73ff16 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUser.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'user', icon: [512, 512, [], "f007", "M399.326 288.908C422.188 258.886 436 221.085 436 180 436 80.591 355.414 0 256 0 156.591 0 76 80.586 76 180c0 41.073 13.806 78.878 36.674 108.908C50.028 296.336 0 349.651 0 416v28.5C0 481.72 30.28 512 67.5 512h377c37.22 0 67.5-30.28 67.5-67.5V416c0-66.374-50.052-119.667-112.674-127.092zM256 48c72.902 0 132 59.098 132 132s-59.098 132-132 132-132-59.098-132-132S183.098 48 256 48zm208 396.5c0 10.77-8.73 19.5-19.5 19.5h-377c-10.77 0-19.5-8.73-19.5-19.5V416c0-44.183 35.817-80 80-80h38.14c55.486 31.968 124.026 32.087 179.72 0H384c44.183 0 80 35.817 80 80v28.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUserCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUserCircle.js new file mode 100644 index 000000000..979990413 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faUserCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 34.48-8.706 66.909-24.04 95.213-13.403-26.393-37.525-47.542-67.384-56.572C378.19 273.809 385.5 249.468 385.5 224c0-71.569-57.919-129.5-129.5-129.5-71.569 0-129.5 57.919-129.5 129.5 0 25.468 7.31 49.809 20.924 70.641-29.821 9.018-53.962 30.142-67.385 56.572C64.706 322.911 56 290.482 56 256c0-110.531 89.451-200 200-200zm-80 168c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-59.927 174.943c1.519-33.998 29.554-61.097 63.927-61.097h14.171c38.337 20.889 85.337 20.881 123.659 0H332c34.373 0 62.408 27.099 63.927 61.097-77.746 76.114-202.156 76.065-279.854 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowClose.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowClose.js new file mode 100644 index 000000000..9c3817737 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowClose.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowMaximize.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowMaximize.js new file mode 100644 index 000000000..795fa9190 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowMaximize.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowRestore.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowRestore.js new file mode 100644 index 000000000..eb3d054c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/faWindowRestore.js @@ -0,0 +1 @@ +module.exports = { prefix: 'far', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.es.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.es.js new file mode 100644 index 000000000..f523efb34 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.es.js @@ -0,0 +1,240 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +var prefix = "far"; +var faAddressBook = { prefix: 'far', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M320 320v72c0 13.255-10.745 24-24 24H152c-13.255 0-24-10.745-24-24v-72c0-21.431 14.207-40.266 34.813-46.153l18.064-5.161C193.629 275.884 208.342 280 224 280s30.371-4.116 43.122-11.314l18.064 5.161C305.793 279.734 320 298.569 320 320zm-96-64c35.346 0 64-28.654 64-64s-28.654-64-64-64-64 28.654-64 64 28.654 64 64 64zm192-96v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v48c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V48C32 21.49 53.49 0 80 0h288c26.51 0 48 21.49 48 48v48h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20zm-48 298V54a6 6 0 0 0-6-6H86a6 6 0 0 0-6 6v404a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6z"] }; +var faAddressCard = { prefix: 'far', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zm-54-176H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm0 80H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm-284-96c0-30.928 25.072-56 56-56s56 25.072 56 56-25.072 56-56 56-56-25.072-56-56zm136 89.857V340c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12v-42.143a24 24 0 0 1 17.104-22.988l13.464-4.039C140.186 281.568 157.351 288 176 288s35.814-6.432 49.433-17.17l13.464 4.039A24 24 0 0 1 256 297.857z"] }; +var faArrowAltCircleDown = { prefix: 'far', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z"] }; +var faArrowAltCircleLeft = { prefix: 'far', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z"] }; +var faArrowAltCircleRight = { prefix: 'far', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z"] }; +var faArrowAltCircleUp = { prefix: 'far', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z"] }; +var faBell = { prefix: 'far', iconName: 'bell', icon: [448, 512, [], "f0f3", "M425.403 330.939c-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.843 31.843 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095C118.101 62.783 57.143 131.831 57.143 214.857c0 81.933-17.551 99.292-34.543 116.078C-25.496 378.441 9.726 448 66.919 448H160c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h93.08c57.19 0 92.415-69.583 44.323-117.061zM224 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm157.092-72H66.9c-16.762 0-25.135-20.39-13.334-32.191 28.585-28.585 51.577-55.724 51.577-152.952C105.143 149.319 158.462 96 224 96s118.857 53.319 118.857 118.857c0 97.65 23.221 124.574 51.568 152.952C406.278 379.661 397.783 400 381.092 400z"] }; +var faBellSlash = { prefix: 'far', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M130.9 400c-16.762 0-25.135-20.39-13.334-32.191 25.226-25.226 46.094-49.338 50.649-121.48l-46.777-41.274a168.48 168.48 0 0 0-.296 9.802c0 81.933-17.551 99.292-34.543 116.078C38.504 378.441 73.726 448 130.919 448H224c0 35.346 28.654 64 64 64s64-28.654 64-64h44.777l-54.4-48H130.9zM288 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm283.867.553l-67.931-59.571c13.104-24.118 11.524-56.318-14.532-82.042-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.848 31.848 0 0 0 320 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095c-41.471 6.618-77.891 28.571-103.249 59.841L36.459 3.037c-5.058-4.436-12.777-3.956-17.24 1.071L3.056 22.313C-1.407 27.34-.925 35.012 4.134 39.447l535.408 469.516c5.058 4.436 12.777 3.956 17.24-1.071l16.163-18.205c4.462-5.027 3.98-12.699-1.078-17.134zM288 96c65.538 0 118.857 53.319 118.857 118.857 0 97.65 23.221 124.574 51.568 152.952 2.908 2.908 4.573 6.328 5.209 9.832L194.482 141.612C216.258 113.867 250.075 96 288 96z"] }; +var faBookmark = { prefix: 'far', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z"] }; +var faBuilding = { prefix: 'far', iconName: 'building', icon: [448, 512, [], "f1ad", "M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z"] }; +var faCalendar = { prefix: 'far', iconName: 'calendar', icon: [448, 512, [], "f133", "M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z"] }; +var faCalendarAlt = { prefix: 'far', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarCheck = { prefix: 'far', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z"] }; +var faCalendarMinus = { prefix: 'far', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarPlus = { prefix: 'far', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarTimes = { prefix: 'far', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareDown = { prefix: 'far', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareLeft = { prefix: 'far', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareRight = { prefix: 'far', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareUp = { prefix: 'far', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faChartBar = { prefix: 'far', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 400c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v324h452zm-356-60v-72c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V140c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V204c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V108c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12z"] }; +var faCheckCircle = { prefix: 'far', iconName: 'check-circle', icon: [512, 512, [], "f058", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"] }; +var faCheckSquare = { prefix: 'far', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z"] }; +var faCircle = { prefix: 'far', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"] }; +var faClipboard = { prefix: 'far', iconName: 'clipboard', icon: [384, 512, [], "f328", "M336 64h-80c0-35.29-28.71-64-64-64s-64 28.71-64 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h42v36c0 6.627 5.373 12 12 12h168c6.627 0 12-5.373 12-12v-36h42a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zM192 40c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24"] }; +var faClock = { prefix: 'far', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; +var faClone = { prefix: 'far', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z"] }; +var faClosedCaptioning = { prefix: 'far', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z"] }; +var faComment = { prefix: 'far', iconName: 'comment', icon: [576, 512, [], "f075", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160z"] }; +var faCommentAlt = { prefix: 'far', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160zm-64-160c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48z"] }; +var faComments = { prefix: 'far', iconName: 'comments', icon: [576, 512, [], "f086", "M574.507 443.86c-5.421 21.261-24.57 36.14-46.511 36.14-32.246 0-66.511-9.99-102.1-29.734-50.64 11.626-109.151 7.877-157.96-13.437 41.144-2.919 80.361-12.339 116.331-28.705 16.322-1.22 32.674-4.32 48.631-9.593C454.404 412.365 490.663 432 527.996 432c-32-17.455-43.219-38.958-46.159-58.502 25.443-18.848 46.159-47.183 46.159-81.135 0-10.495-2.383-21.536-7.041-32.467 7.405-25.93 8.656-50.194 5.185-73.938 32.164 30.461 49.856 69.128 49.856 106.405 0 33.893-12.913 65.047-34.976 91.119 2.653 2.038 5.924 4.176 9.962 6.378 19.261 10.508 28.947 32.739 23.525 54zM240.002 80C117.068 80 48.004 152.877 48.004 210.909c0 38.196 24.859 70.072 55.391 91.276-3.527 21.988-16.991 46.179-55.391 65.815 44.8 0 88.31-22.089 114.119-37.653 25.52 7.906 51.883 11.471 77.879 11.471C362.998 341.818 432 268.976 432 210.909 432 152.882 362.943 80 240.002 80m0-48C390.193 32 480 126.026 480 210.909c0 22.745-6.506 46.394-18.816 68.391-11.878 21.226-28.539 40.294-49.523 56.674-21.593 16.857-46.798 30.045-74.913 39.197-29.855 9.719-62.405 14.646-96.746 14.646-24.449 0-48.34-2.687-71.292-8.004C126.311 404.512 85.785 416 48.004 416c-22.18 0-41.472-15.197-46.665-36.761-5.194-21.563 5.064-43.878 24.811-53.976 7.663-3.918 13.324-7.737 17.519-11.294-7.393-7.829-13.952-16.124-19.634-24.844C8.09 264.655.005 238.339.005 210.909.005 126.259 89.508 32 240.002 32z"] }; +var faCompass = { prefix: 'far', iconName: 'compass', icon: [512, 512, [], "f14e", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm91.326-312.131l-33.359 137.779a24.005 24.005 0 0 1-6.772 11.729l-102.64 97.779c-17.104 16.293-45.56.434-39.88-23.024l33.359-137.779a23.997 23.997 0 0 1 6.772-11.729l102.642-97.779c17.285-16.47 45.494-.175 39.878 23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faCopy = { prefix: 'far', iconName: 'copy', icon: [448, 512, [], "f0c5", "M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"] }; +var faCopyright = { prefix: 'far', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z"] }; +var faCreditCard = { prefix: 'far', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z"] }; +var faDotCircle = { prefix: 'far', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z"] }; +var faEdit = { prefix: 'far', iconName: 'edit', icon: [576, 512, [], "f044", "M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z"] }; +var faEnvelope = { prefix: 'far', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z"] }; +var faEnvelopeOpen = { prefix: 'far', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z"] }; +var faEyeSlash = { prefix: 'far', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z"] }; +var faFile = { prefix: 'far', iconName: 'file', icon: [384, 512, [], "f15b", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z"] }; +var faFileAlt = { prefix: 'far', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z"] }; +var faFileArchive = { prefix: 'far', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM256 51.882L332.118 128H256V51.882zM336 464H48V48h79.714v16h32V48H208v104c0 13.255 10.745 24 24 24h104v288zM192.27 96h-32V64h32v32zm-32 0v32h-32V96h32zm0 64v32h-32v-32h32zm32 0h-32v-32h32v32zm1.909 105.678A12 12 0 0 0 182.406 256H160.27v-32h-32v32l-19.69 97.106C101.989 385.611 126.834 416 160 416c33.052 0 57.871-30.192 51.476-62.62l-17.297-87.702zM160.27 390.073c-17.918 0-32.444-12.105-32.444-27.036 0-14.932 14.525-27.036 32.444-27.036s32.444 12.105 32.444 27.036c0 14.931-14.526 27.036-32.444 27.036zm32-166.073h-32v-32h32v32z"] }; +var faFileAudio = { prefix: 'far', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z"] }; +var faFileCode = { prefix: 'far', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm101.677-115.115L116.854 320l32.822-28.885a8.793 8.793 0 0 0 .605-12.624l-17.403-18.564c-3.384-3.613-8.964-3.662-12.438-.401L62.78 313.58c-3.703 3.474-3.704 9.367.001 12.84l57.659 54.055a8.738 8.738 0 0 0 6.012 2.381 8.746 8.746 0 0 0 6.427-2.782l17.403-18.563a8.795 8.795 0 0 0-.605-12.626zm84.284-127.85l-24.401-7.084a8.796 8.796 0 0 0-10.905 5.998L144.04 408.061c-1.353 4.66 1.338 9.552 5.998 10.905l24.403 7.084c4.68 1.355 9.557-1.354 10.905-5.998l54.612-188.112c1.354-4.66-1.337-9.552-5.997-10.905zm87.258 92.545l-57.658-54.055c-3.526-3.307-9.099-3.165-12.439.401l-17.403 18.563a8.795 8.795 0 0 0 .605 12.625L267.146 320l-32.822 28.885a8.793 8.793 0 0 0-.605 12.624l17.403 18.564a8.797 8.797 0 0 0 12.439.401h-.001l57.66-54.055c3.703-3.473 3.703-9.366-.001-12.839z"] }; +var faFileExcel = { prefix: 'far', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z"] }; +var faFileImage = { prefix: 'far', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; +var faFilePdf = { prefix: 'far', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"] }; +var faFilePowerpoint = { prefix: 'far', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z"] }; +var faFileVideo = { prefix: 'far', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z"] }; +var faFileWord = { prefix: 'far', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z"] }; +var faFlag = { prefix: 'far', iconName: 'flag', icon: [512, 512, [], "f024", "M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z"] }; +var faFolder = { prefix: 'far', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-6 272H54c-3.314 0-6-2.678-6-5.992V117.992A5.993 5.993 0 0 1 54 112h134.118l64 64H458a6 6 0 0 1 6 6v212a6 6 0 0 1-6 6z"] }; +var faFolderOpen = { prefix: 'far', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M527.943 224H480v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h400a48.001 48.001 0 0 0 40.704-22.56l79.942-128c19.948-31.917-3.038-73.44-40.703-73.44zM54 112h134.118l64 64H426a6 6 0 0 1 6 6v42H152a48 48 0 0 0-41.098 23.202L48 351.449V117.993A5.993 5.993 0 0 1 54 112zm394 288H72l77.234-128H528l-80 128z"] }; +var faFrown = { prefix: 'far', iconName: 'frown', icon: [512, 512, [], "f119", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm171.547 201.782c-56.595-76.964-158.383-77.065-215.057-.001-18.82 25.593 19.858 54.018 38.67 28.438 37.511-51.01 100.365-50.796 137.717-.001 18.509 25.172 57.821-2.395 38.67-28.436z"] }; +var faFutbol = { prefix: 'far', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M207.898 325.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-455.998-.19L48 256c0 44.7 14.015 87.242 39.95 122.626l7.982-35.118 88.595 10.871 37.775 80.985-30.978 18.427c41.832 13.631 87.598 13.606 129.354 0L289.7 435.364l37.775-80.985 88.594-10.871 7.982 35.118C449.985 343.242 464 300.7 464 256l-.002-.19-27.003 23.561-65.223-60.875 17.122-87.779 35.538 3.183c-25.216-34.63-61.309-62.053-104.577-75.951l14.143 33.091L256 134.25l-77.996-43.21 14.144-33.091C148.868 71.851 112.782 99.277 87.57 133.9l35.81-3.183 16.849 87.779-65.223 60.875-27.004-23.561z"] }; +var faGem = { prefix: 'far', iconName: 'gem', icon: [576, 512, [], "f3a5", "M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z"] }; +var faHandLizard = { prefix: 'far', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z"] }; +var faHandPaper = { prefix: 'far', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z"] }; +var faHandPeace = { prefix: 'far', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z"] }; +var faHandPointDown = { prefix: 'far', iconName: 'hand-point-down', icon: [448, 512, [], "f0a7", "M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z"] }; +var faHandPointLeft = { prefix: 'far', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; +var faHandPointRight = { prefix: 'far', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; +var faHandPointUp = { prefix: 'far', iconName: 'hand-point-up', icon: [448, 512, [], "f0a6", "M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; +var faHandPointer = { prefix: 'far', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"] }; +var faHandRock = { prefix: 'far', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z"] }; +var faHandScissors = { prefix: 'far', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z"] }; +var faHandSpock = { prefix: 'far', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z"] }; +var faHandshake = { prefix: 'far', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M616 96h-48c-7.107 0-13.49 3.091-17.884 8H526.59l-31.13-36.3-.16-.18A103.974 103.974 0 0 0 417.03 32h-46.55c-17.75 0-34.9 4.94-49.69 14.01C304.33 36.93 285.67 32 266.62 32h-32.11c-28.903 0-57.599 11.219-79.2 32.8L116.12 104H89.884C85.49 99.091 79.107 96 72 96H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h48c10.449 0 19.334-6.68 22.629-16h18.801l75.35 67.57c25.542 26.45 59.925 44.43 96.58 44.43 16.39 0 32.28-3.85 46.1-10.93 24.936.496 51.101-10.368 69.07-31.41 19.684-5.579 37.503-17.426 50.72-34.6 20.989-4.401 40.728-16.492 53.42-35.06h40.701c3.295 9.32 12.18 16 22.629 16h48c13.255 0 24-10.745 24-24V120c0-13.255-10.745-24-24-24zM48 352c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16zm412.52-5.76c-15.35 14.295-36.884 11.328-39.95 8 1.414 13.382-18.257 41.043-49.08 38.88-5.541 18.523-28.218 33.826-51.49 25.75-8.89 8.89-22.46 13.13-34.64 13.13-24.95 0-47.77-14.54-63.14-30.91l-81.3-72.91a31.976 31.976 0 0 0-21.36-8.18H96V152h26.75c8.48 0 16.62-3.37 22.62-9.37l43.88-43.88A64.004 64.004 0 0 1 234.51 80h32.11c5.8 0 11.51.79 17 2.3l-43.27 50.49c-23.56 27.48-23.84 67.62-.66 95.44 32.388 38.866 91.378 39.228 124.48 1.98l25.98-30.08L462.59 296c13.44 14.6 10.95 38.13-2.07 50.24zM544 320h-24.458c.104-20.261-6.799-39.33-19.762-54.4L421.7 162.28c4.51-9.51 2.34-21.23-6.01-28.45-10.075-8.691-25.23-7.499-33.86 2.48l-53.63 62.12c-13.828 15.41-38.223 15.145-51.64-.93a25.857 25.857 0 0 1 .23-33.47l57.92-67.58A47.09 47.09 0 0 1 370.48 80h46.55c16.11 0 31.44 6.94 42.07 19.04L504.52 152H544v168zm48 32c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16z"] }; +var faHdd = { prefix: 'far', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z"] }; +var faHeart = { prefix: 'far', iconName: 'heart', icon: [576, 512, [], "f004", "M257.3 475.4L92.5 313.6C85.4 307 24 248.1 24 174.8 24 84.1 80.8 24 176 24c41.4 0 80.6 22.8 112 49.8 31.3-27 70.6-49.8 112-49.8 91.7 0 152 56.5 152 150.8 0 52-31.8 103.5-68.1 138.7l-.4.4-164.8 161.5a43.7 43.7 0 0 1-61.4 0zM125.9 279.1L288 438.3l161.8-158.7c27.3-27 54.2-66.3 54.2-104.8C504 107.9 465.8 72 400 72c-47.2 0-92.8 49.3-112 68.4-17-17-64-68.4-112-68.4-65.9 0-104 35.9-104 102.8 0 37.3 26.7 78.9 53.9 104.3z"] }; +var faHospital = { prefix: 'far', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z"] }; +var faHourglass = { prefix: 'far', iconName: 'hourglass', icon: [384, 512, [], "f254", "M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z"] }; +var faIdBadge = { prefix: 'far', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M192 128c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64 28.654-64 64-64m61.187 145.847l-18.064-5.161C222.371 275.884 207.658 280 192 280s-30.371-4.116-43.122-11.314l-18.064 5.161C110.207 279.734 96 298.569 96 320v72c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-72c0-21.431-14.207-40.266-34.813-46.153zM0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48zm336 32v378a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V80h288z"] }; +var faIdCard = { prefix: 'far', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M404 256H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm12 68v-24c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12zm96-212v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zm-48 282V144H48v250a6 6 0 0 0 6 6h404a6 6 0 0 0 6-6zm-288-98c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56 25.072 56 56 56zm62.896 10.869l-13.464-4.039C211.814 313.568 194.649 320 176 320s-35.814-6.432-49.433-17.17l-13.464 4.039A24 24 0 0 0 96 329.857V372c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12v-42.143a24 24 0 0 0-17.104-22.988z"] }; +var faImage = { prefix: 'far', iconName: 'image', icon: [512, 512, [], "f03e", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z"] }; +var faImages = { prefix: 'far', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z"] }; +var faKeyboard = { prefix: 'far', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z"] }; +var faLemon = { prefix: 'far', iconName: 'lemon', icon: [512, 512, [], "f094", "M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z"] }; +var faLifeRing = { prefix: 'far', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z"] }; +var faLightbulb = { prefix: 'far', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zM128 176c0-35.29 28.71-64 64-64 8.837 0 16-7.164 16-16s-7.163-16-16-16c-52.935 0-96 43.065-96 96 0 8.836 7.164 16 16 16s16-7.164 16-16zm64-128c70.734 0 128 57.254 128 128 0 77.602-37.383 60.477-80.98 160h-94.04C101.318 236.33 64 253.869 64 176c0-70.735 57.254-128 128-128m0-48C94.805 0 16 78.803 16 176c0 101.731 51.697 91.541 90.516 192.674 3.55 9.249 12.47 15.326 22.376 15.326h126.215c9.906 0 18.826-6.078 22.376-15.326C316.303 267.541 368 277.731 368 176 368 78.803 289.195 0 192 0z"] }; +var faListAlt = { prefix: 'far', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; +var faMap = { prefix: 'far', iconName: 'map', icon: [576, 512, [], "f279", "M508.505 36.17L381.517 92.576 207.179 34.463a47.992 47.992 0 0 0-34.674 1.674l-144 64A48 48 0 0 0 0 144v287.967c0 34.938 35.991 57.864 67.495 43.863l126.988-56.406 174.339 58.113a47.992 47.992 0 0 0 34.674-1.674l144-64A48 48 0 0 0 576 368V80.033c0-34.938-35.991-57.864-67.495-43.863zM360 424l-144-48V88l144 48v288zm-312 8V144l120-53.333v288L48 432zm480-64l-120 53.333v-288L528 80v288z"] }; +var faMeh = { prefix: 'far', iconName: 'meh', icon: [512, 512, [], "f11a", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm136 184H184c-31.776 0-31.749 48 0 48h144c31.776 0 31.749-48 0-48z"] }; +var faMinusSquare = { prefix: 'far', iconName: 'minus-square', icon: [448, 512, [], "f146", "M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faMoneyBillAlt = { prefix: 'far', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M320 144c-53.021 0-96 50.143-96 112 0 61.847 42.977 112 96 112 53 0 96-50.13 96-112 0-61.857-42.979-112-96-112zm48 164.428c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.901c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.75 3.916 11.75 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.902zM616 64H24C10.745 64 0 74.745 0 88v335c0 13.255 10.745 24 24 24h592c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM512 400H128c0-44.183-35.817-80-80-80V192c44.183 0 80-35.817 80-80h384c0 44.183 35.817 80 80 80v128c-44.183 0-80 35.817-80 80z"] }; +var faMoon = { prefix: 'far', iconName: 'moon', icon: [512, 512, [], "f186", "M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z"] }; +var faNewspaper = { prefix: 'far', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z"] }; +var faObjectGroup = { prefix: 'far', iconName: 'object-group', icon: [512, 512, [], "f247", "M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z"] }; +var faObjectUngroup = { prefix: 'far', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z"] }; +var faPaperPlane = { prefix: 'far', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z"] }; +var faPauseCircle = { prefix: 'far', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z"] }; +var faPlayCircle = { prefix: 'far', iconName: 'play-circle', icon: [512, 512, [], "f144", "M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z"] }; +var faPlusSquare = { prefix: 'far', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faQuestionCircle = { prefix: 'far', iconName: 'question-circle', icon: [512, 512, [], "f059", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"] }; +var faRegistered = { prefix: 'far', iconName: 'registered', icon: [512, 512, [], "f25d", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z"] }; +var faSave = { prefix: 'far', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z"] }; +var faShareSquare = { prefix: 'far', iconName: 'share-square', icon: [576, 512, [], "f14d", "M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z"] }; +var faSmile = { prefix: 'far', iconName: 'smile', icon: [512, 512, [], "f118", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm195.372 182.219c18.819-25.592-19.856-54.017-38.67-28.438-50.135 68.177-135.229 68.18-185.367 0-18.828-25.601-57.478 2.861-38.67 28.438 69.298 94.231 193.323 94.351 262.707 0z"] }; +var faSnowflake = { prefix: 'far', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M438.237 355.927l-66.574-38.54 59.448-10.327c5.846-1.375 10.609-5.183 13.458-10.13 2.48-4.307 3.506-9.478 2.524-14.651-2.11-11.115-12.686-18.039-23.621-15.467l-85.423 31.115L255.914 256l82.136-41.926 85.423 31.115c10.936 2.572 21.512-4.352 23.621-15.467 2.111-11.115-5.046-22.209-15.981-24.781l-59.448-10.327 66.573-38.54c9.54-5.523 12.615-18.092 6.867-28.074-5.748-9.982-18.14-13.596-27.68-8.074l-66.574 38.54 20.805-56.787c3.246-10.782-2.758-22.542-13.413-26.268-10.654-3.725-21.922 1.997-25.168 12.779l-15.838 89.735-72.423 41.926V136l69.585-58.621c7.689-8.21 6.997-20.856-1.548-28.245-8.545-7.391-21.705-6.723-29.394 1.486l-38.644 46.46V20c0-11.046-9.318-20-20.813-20s-20.813 8.954-20.813 20v77.08l-38.644-46.46c-7.689-8.21-20.849-8.876-29.394-1.486-8.544 7.389-9.236 20.035-1.547 28.245L203.187 136v83.853l-72.423-41.926-15.838-89.736c-3.247-10.782-14.515-16.504-25.169-12.779-10.656 3.725-16.659 15.486-13.413 26.268l20.805 56.787-66.573-38.54c-9.54-5.523-21.933-1.908-27.68 8.074s-2.673 22.551 6.867 28.074l66.574 38.54-59.449 10.328C5.953 207.515-1.202 218.609.907 229.724c2.11 11.114 12.686 18.038 23.622 15.466l85.422-31.115L192.086 256l-82.136 41.926-85.423-31.115c-10.936-2.572-21.511 4.352-23.622 15.466-2.109 11.113 5.046 22.209 15.981 24.781l59.449 10.328-66.574 38.54C.223 361.449-2.852 374.018 2.896 384s18.14 13.597 27.68 8.074l66.574-38.54-20.805 56.786c-1.735 5.764-.828 11.805 2.02 16.751 2.48 4.307 6.433 7.784 11.392 9.517 10.655 3.725 21.923-1.997 25.169-12.779l15.838-89.736 72.423-41.926V376l-69.585 58.621c-7.69 8.21-6.997 20.855 1.547 28.245 8.544 7.388 21.705 6.723 29.394-1.487l38.644-46.46V492c0 11.046 9.318 20 20.813 20s20.813-8.954 20.813-20v-77.081l38.644 46.46c4.111 4.389 9.782 6.621 15.478 6.621 4.96 0 9.939-1.694 13.916-5.134 8.545-7.39 9.237-20.035 1.548-28.245L244.813 376v-83.853l72.423 41.926 15.838 89.736c3.246 10.782 14.514 16.504 25.168 12.779 10.653-3.726 16.659-15.487 13.412-26.268l-20.805-56.787 66.574 38.54c9.54 5.523 21.933 1.908 27.68-8.074 5.749-9.981 2.675-22.55-6.866-28.072z"] }; +var faSquare = { prefix: 'far', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z"] }; +var faStar = { prefix: 'far', iconName: 'star', icon: [576, 512, [], "f005", "M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z"] }; +var faStarHalf = { prefix: 'far', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z"] }; +var faStickyNote = { prefix: 'far', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z"] }; +var faStopCircle = { prefix: 'far', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z"] }; +var faSun = { prefix: 'far', iconName: 'sun', icon: [512, 512, [], "f185", "M220.116 487.936l-20.213-49.425a3.992 3.992 0 0 0-5.808-1.886l-45.404 28.104c-29.466 18.24-66.295-8.519-58.054-42.179l12.699-51.865a3.993 3.993 0 0 0-3.59-4.941l-53.251-3.951c-34.554-2.562-48.632-45.855-22.174-68.247L65.08 259.05a3.992 3.992 0 0 0 0-6.106l-40.76-34.497c-26.45-22.384-12.39-65.682 22.174-68.246l53.251-3.951a3.993 3.993 0 0 0 3.59-4.941L90.637 89.443c-8.239-33.656 28.581-60.42 58.054-42.179l45.403 28.104a3.993 3.993 0 0 0 5.808-1.887l20.213-49.425c13.116-32.071 58.638-32.081 71.758 0l20.212 49.424a3.994 3.994 0 0 0 5.809 1.887l45.403-28.104c29.464-18.236 66.297 8.513 58.054 42.179l-12.699 51.865a3.995 3.995 0 0 0 3.59 4.941l53.251 3.951c34.553 2.563 48.633 45.854 22.175 68.246l-40.76 34.497a3.993 3.993 0 0 0 0 6.107l40.76 34.496c26.511 22.441 12.322 65.689-22.175 68.247l-53.251 3.951a3.993 3.993 0 0 0-3.589 4.942l12.698 51.864c8.241 33.658-28.583 60.421-58.054 42.18l-45.403-28.104a3.994 3.994 0 0 0-5.809 1.887l-20.212 49.424c-13.159 32.178-58.675 31.993-71.757 0zm16.814-64.568l19.064 46.616 19.064-46.615c10.308-25.2 40.778-35.066 63.892-20.759l42.822 26.507-11.976-48.919c-6.475-26.444 12.38-52.339 39.487-54.349l50.226-3.726-38.444-32.536c-20.782-17.591-20.747-49.621.001-67.18l38.442-32.536-50.225-3.727c-27.151-2.015-45.95-27.948-39.488-54.349l11.978-48.919-42.823 26.507c-23.151 14.327-53.603 4.4-63.892-20.76l-19.064-46.615-19.064 46.617c-10.305 25.198-40.778 35.066-63.891 20.76l-42.823-26.508 11.977 48.918c6.474 26.446-12.381 52.338-39.488 54.35l-50.224 3.726 38.443 32.537c20.782 17.588 20.747 49.619 0 67.178L52.48 322.123l50.226 3.726c27.151 2.014 45.95 27.947 39.487 54.349l-11.977 48.919 42.823-26.507c23.188-14.355 53.622-4.352 63.891 20.758zM256 384c-70.58 0-128-57.421-128-128 0-70.58 57.42-128 128-128 70.579 0 128 57.42 128 128 0 70.579-57.421 128-128 128zm0-208c-44.112 0-80 35.888-80 80s35.888 80 80 80 80-35.888 80-80-35.888-80-80-80z"] }; +var faThumbsDown = { prefix: 'far', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z"] }; +var faThumbsUp = { prefix: 'far', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; +var faTimesCircle = { prefix: 'far', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z"] }; +var faTrashAlt = { prefix: 'far', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M192 188v216c0 6.627-5.373 12-12 12h-24c-6.627 0-12-5.373-12-12V188c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12zm100-12h-24c-6.627 0-12 5.373-12 12v216c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12V188c0-6.627-5.373-12-12-12zm132-96c13.255 0 24 10.745 24 24v12c0 6.627-5.373 12-12 12h-20v336c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V128H12c-6.627 0-12-5.373-12-12v-12c0-13.255 10.745-24 24-24h74.411l34.018-56.696A48 48 0 0 1 173.589 0h100.823a48 48 0 0 1 41.16 23.304L349.589 80H424zm-269.611 0h139.223L276.16 50.913A6 6 0 0 0 271.015 48h-94.028a6 6 0 0 0-5.145 2.913L154.389 80zM368 128H80v330a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6V128z"] }; +var faUser = { prefix: 'far', iconName: 'user', icon: [512, 512, [], "f007", "M399.326 288.908C422.188 258.886 436 221.085 436 180 436 80.591 355.414 0 256 0 156.591 0 76 80.586 76 180c0 41.073 13.806 78.878 36.674 108.908C50.028 296.336 0 349.651 0 416v28.5C0 481.72 30.28 512 67.5 512h377c37.22 0 67.5-30.28 67.5-67.5V416c0-66.374-50.052-119.667-112.674-127.092zM256 48c72.902 0 132 59.098 132 132s-59.098 132-132 132-132-59.098-132-132S183.098 48 256 48zm208 396.5c0 10.77-8.73 19.5-19.5 19.5h-377c-10.77 0-19.5-8.73-19.5-19.5V416c0-44.183 35.817-80 80-80h38.14c55.486 31.968 124.026 32.087 179.72 0H384c44.183 0 80 35.817 80 80v28.5z"] }; +var faUserCircle = { prefix: 'far', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 34.48-8.706 66.909-24.04 95.213-13.403-26.393-37.525-47.542-67.384-56.572C378.19 273.809 385.5 249.468 385.5 224c0-71.569-57.919-129.5-129.5-129.5-71.569 0-129.5 57.919-129.5 129.5 0 25.468 7.31 49.809 20.924 70.641-29.821 9.018-53.962 30.142-67.385 56.572C64.706 322.911 56 290.482 56 256c0-110.531 89.451-200 200-200zm-80 168c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-59.927 174.943c1.519-33.998 29.554-61.097 63.927-61.097h14.171c38.337 20.889 85.337 20.881 123.659 0H332c34.373 0 62.408 27.099 63.927 61.097-77.746 76.114-202.156 76.065-279.854 0z"] }; +var faWindowClose = { prefix: 'far', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z"] }; +var faWindowMaximize = { prefix: 'far', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"] }; +var faWindowRestore = { prefix: 'far', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z"] }; +var icons$1 = { + faAddressBook: faAddressBook, + faAddressCard: faAddressCard, + faArrowAltCircleDown: faArrowAltCircleDown, + faArrowAltCircleLeft: faArrowAltCircleLeft, + faArrowAltCircleRight: faArrowAltCircleRight, + faArrowAltCircleUp: faArrowAltCircleUp, + faBell: faBell, + faBellSlash: faBellSlash, + faBookmark: faBookmark, + faBuilding: faBuilding, + faCalendar: faCalendar, + faCalendarAlt: faCalendarAlt, + faCalendarCheck: faCalendarCheck, + faCalendarMinus: faCalendarMinus, + faCalendarPlus: faCalendarPlus, + faCalendarTimes: faCalendarTimes, + faCaretSquareDown: faCaretSquareDown, + faCaretSquareLeft: faCaretSquareLeft, + faCaretSquareRight: faCaretSquareRight, + faCaretSquareUp: faCaretSquareUp, + faChartBar: faChartBar, + faCheckCircle: faCheckCircle, + faCheckSquare: faCheckSquare, + faCircle: faCircle, + faClipboard: faClipboard, + faClock: faClock, + faClone: faClone, + faClosedCaptioning: faClosedCaptioning, + faComment: faComment, + faCommentAlt: faCommentAlt, + faComments: faComments, + faCompass: faCompass, + faCopy: faCopy, + faCopyright: faCopyright, + faCreditCard: faCreditCard, + faDotCircle: faDotCircle, + faEdit: faEdit, + faEnvelope: faEnvelope, + faEnvelopeOpen: faEnvelopeOpen, + faEyeSlash: faEyeSlash, + faFile: faFile, + faFileAlt: faFileAlt, + faFileArchive: faFileArchive, + faFileAudio: faFileAudio, + faFileCode: faFileCode, + faFileExcel: faFileExcel, + faFileImage: faFileImage, + faFilePdf: faFilePdf, + faFilePowerpoint: faFilePowerpoint, + faFileVideo: faFileVideo, + faFileWord: faFileWord, + faFlag: faFlag, + faFolder: faFolder, + faFolderOpen: faFolderOpen, + faFrown: faFrown, + faFutbol: faFutbol, + faGem: faGem, + faHandLizard: faHandLizard, + faHandPaper: faHandPaper, + faHandPeace: faHandPeace, + faHandPointDown: faHandPointDown, + faHandPointLeft: faHandPointLeft, + faHandPointRight: faHandPointRight, + faHandPointUp: faHandPointUp, + faHandPointer: faHandPointer, + faHandRock: faHandRock, + faHandScissors: faHandScissors, + faHandSpock: faHandSpock, + faHandshake: faHandshake, + faHdd: faHdd, + faHeart: faHeart, + faHospital: faHospital, + faHourglass: faHourglass, + faIdBadge: faIdBadge, + faIdCard: faIdCard, + faImage: faImage, + faImages: faImages, + faKeyboard: faKeyboard, + faLemon: faLemon, + faLifeRing: faLifeRing, + faLightbulb: faLightbulb, + faListAlt: faListAlt, + faMap: faMap, + faMeh: faMeh, + faMinusSquare: faMinusSquare, + faMoneyBillAlt: faMoneyBillAlt, + faMoon: faMoon, + faNewspaper: faNewspaper, + faObjectGroup: faObjectGroup, + faObjectUngroup: faObjectUngroup, + faPaperPlane: faPaperPlane, + faPauseCircle: faPauseCircle, + faPlayCircle: faPlayCircle, + faPlusSquare: faPlusSquare, + faQuestionCircle: faQuestionCircle, + faRegistered: faRegistered, + faSave: faSave, + faShareSquare: faShareSquare, + faSmile: faSmile, + faSnowflake: faSnowflake, + faSquare: faSquare, + faStar: faStar, + faStarHalf: faStarHalf, + faStickyNote: faStickyNote, + faStopCircle: faStopCircle, + faSun: faSun, + faThumbsDown: faThumbsDown, + faThumbsUp: faThumbsUp, + faTimesCircle: faTimesCircle, + faTrashAlt: faTrashAlt, + faUser: faUser, + faUserCircle: faUserCircle, + faWindowClose: faWindowClose, + faWindowMaximize: faWindowMaximize, + faWindowRestore: faWindowRestore +}; + +export { prefix, faAddressBook, faAddressCard, faArrowAltCircleDown, faArrowAltCircleLeft, faArrowAltCircleRight, faArrowAltCircleUp, faBell, faBellSlash, faBookmark, faBuilding, faCalendar, faCalendarAlt, faCalendarCheck, faCalendarMinus, faCalendarPlus, faCalendarTimes, faCaretSquareDown, faCaretSquareLeft, faCaretSquareRight, faCaretSquareUp, faChartBar, faCheckCircle, faCheckSquare, faCircle, faClipboard, faClock, faClone, faClosedCaptioning, faComment, faCommentAlt, faComments, faCompass, faCopy, faCopyright, faCreditCard, faDotCircle, faEdit, faEnvelope, faEnvelopeOpen, faEyeSlash, faFile, faFileAlt, faFileArchive, faFileAudio, faFileCode, faFileExcel, faFileImage, faFilePdf, faFilePowerpoint, faFileVideo, faFileWord, faFlag, faFolder, faFolderOpen, faFrown, faFutbol, faGem, faHandLizard, faHandPaper, faHandPeace, faHandPointDown, faHandPointLeft, faHandPointRight, faHandPointUp, faHandPointer, faHandRock, faHandScissors, faHandSpock, faHandshake, faHdd, faHeart, faHospital, faHourglass, faIdBadge, faIdCard, faImage, faImages, faKeyboard, faLemon, faLifeRing, faLightbulb, faListAlt, faMap, faMeh, faMinusSquare, faMoneyBillAlt, faMoon, faNewspaper, faObjectGroup, faObjectUngroup, faPaperPlane, faPauseCircle, faPlayCircle, faPlusSquare, faQuestionCircle, faRegistered, faSave, faShareSquare, faSmile, faSnowflake, faSquare, faStar, faStarHalf, faStickyNote, faStopCircle, faSun, faThumbsDown, faThumbsUp, faTimesCircle, faTrashAlt, faUser, faUserCircle, faWindowClose, faWindowMaximize, faWindowRestore }; +export default icons$1; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.js new file mode 100644 index 000000000..824da437e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/index.js @@ -0,0 +1,365 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global['fontawesome-free-regular'] = {}))); +}(this, (function (exports) { 'use strict'; + +var prefix = "far"; +var faAddressBook = { prefix: 'far', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M320 320v72c0 13.255-10.745 24-24 24H152c-13.255 0-24-10.745-24-24v-72c0-21.431 14.207-40.266 34.813-46.153l18.064-5.161C193.629 275.884 208.342 280 224 280s30.371-4.116 43.122-11.314l18.064 5.161C305.793 279.734 320 298.569 320 320zm-96-64c35.346 0 64-28.654 64-64s-28.654-64-64-64-64 28.654-64 64 28.654 64 64 64zm192-96v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v64h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20v48c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V48C32 21.49 53.49 0 80 0h288c26.51 0 48 21.49 48 48v48h20c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-20zm-48 298V54a6 6 0 0 0-6-6H86a6 6 0 0 0-6 6v404a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6z"] }; +var faAddressCard = { prefix: 'far', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zm-54-176H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm0 80H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm-284-96c0-30.928 25.072-56 56-56s56 25.072 56 56-25.072 56-56 56-56-25.072-56-56zm136 89.857V340c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12v-42.143a24 24 0 0 1 17.104-22.988l13.464-4.039C140.186 281.568 157.351 288 176 288s35.814-6.432 49.433-17.17l13.464 4.039A24 24 0 0 1 256 297.857z"] }; +var faArrowAltCircleDown = { prefix: 'far', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm-32-316v116h-67c-10.7 0-16 12.9-8.5 20.5l99 99c4.7 4.7 12.3 4.7 17 0l99-99c7.6-7.6 2.2-20.5-8.5-20.5h-67V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12z"] }; +var faArrowAltCircleLeft = { prefix: 'far', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M8 256c0 137 111 248 248 248s248-111 248-248S393 8 256 8 8 119 8 256zm448 0c0 110.5-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56s200 89.5 200 200zm-72-20v40c0 6.6-5.4 12-12 12H256v67c0 10.7-12.9 16-20.5 8.5l-99-99c-4.7-4.7-4.7-12.3 0-17l99-99c7.6-7.6 20.5-2.2 20.5 8.5v67h116c6.6 0 12 5.4 12 12z"] }; +var faArrowAltCircleRight = { prefix: 'far', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm72 20v-40c0-6.6 5.4-12 12-12h116v-67c0-10.7 12.9-16 20.5-8.5l99 99c4.7 4.7 4.7 12.3 0 17l-99 99c-7.6 7.6-20.5 2.2-20.5-8.5v-67H140c-6.6 0-12-5.4-12-12z"] }; +var faArrowAltCircleUp = { prefix: 'far', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M256 504c137 0 248-111 248-248S393 8 256 8 8 119 8 256s111 248 248 248zm0-448c110.5 0 200 89.5 200 200s-89.5 200-200 200S56 366.5 56 256 145.5 56 256 56zm20 328h-40c-6.6 0-12-5.4-12-12V256h-67c-10.7 0-16-12.9-8.5-20.5l99-99c4.7-4.7 12.3-4.7 17 0l99 99c7.6 7.6 2.2 20.5-8.5 20.5h-67v116c0 6.6-5.4 12-12 12z"] }; +var faBell = { prefix: 'far', iconName: 'bell', icon: [448, 512, [], "f0f3", "M425.403 330.939c-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.843 31.843 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095C118.101 62.783 57.143 131.831 57.143 214.857c0 81.933-17.551 99.292-34.543 116.078C-25.496 378.441 9.726 448 66.919 448H160c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h93.08c57.19 0 92.415-69.583 44.323-117.061zM224 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm157.092-72H66.9c-16.762 0-25.135-20.39-13.334-32.191 28.585-28.585 51.577-55.724 51.577-152.952C105.143 149.319 158.462 96 224 96s118.857 53.319 118.857 118.857c0 97.65 23.221 124.574 51.568 152.952C406.278 379.661 397.783 400 381.092 400z"] }; +var faBellSlash = { prefix: 'far', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M130.9 400c-16.762 0-25.135-20.39-13.334-32.191 25.226-25.226 46.094-49.338 50.649-121.48l-46.777-41.274a168.48 168.48 0 0 0-.296 9.802c0 81.933-17.551 99.292-34.543 116.078C38.504 378.441 73.726 448 130.919 448H224c0 35.346 28.654 64 64 64s64-28.654 64-64h44.777l-54.4-48H130.9zM288 472c-13.234 0-24-10.766-24-24h48c0 13.234-10.766 24-24 24zm283.867.553l-67.931-59.571c13.104-24.118 11.524-56.318-14.532-82.042-16.989-16.785-34.546-34.143-34.546-116.083 0-83.026-60.958-152.074-140.467-164.762A31.848 31.848 0 0 0 320 32c0-17.673-14.327-32-32-32s-32 14.327-32 32a31.848 31.848 0 0 0 5.609 18.095c-41.471 6.618-77.891 28.571-103.249 59.841L36.459 3.037c-5.058-4.436-12.777-3.956-17.24 1.071L3.056 22.313C-1.407 27.34-.925 35.012 4.134 39.447l535.408 469.516c5.058 4.436 12.777 3.956 17.24-1.071l16.163-18.205c4.462-5.027 3.98-12.699-1.078-17.134zM288 96c65.538 0 118.857 53.319 118.857 118.857 0 97.65 23.221 124.574 51.568 152.952 2.908 2.908 4.573 6.328 5.209 9.832L194.482 141.612C216.258 113.867 250.075 96 288 96z"] }; +var faBookmark = { prefix: 'far', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M336 0H48C21.49 0 0 21.49 0 48v464l192-112 192 112V48c0-26.51-21.49-48-48-48zm0 428.43l-144-84-144 84V54a6 6 0 0 1 6-6h276c3.314 0 6 2.683 6 5.996V428.43z"] }; +var faBuilding = { prefix: 'far', iconName: 'building', icon: [448, 512, [], "f1ad", "M128 148v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12zm140 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-128 96h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm128 0h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm-76 84v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm76 12h40c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12zm180 124v36H0v-36c0-6.6 5.4-12 12-12h19.5V24c0-13.3 10.7-24 24-24h337c13.3 0 24 10.7 24 24v440H436c6.6 0 12 5.4 12 12zM79.5 463H192v-67c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v67h112.5V49L80 48l-.5 415z"] }; +var faCalendar = { prefix: 'far', iconName: 'calendar', icon: [448, 512, [], "f133", "M400 64h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V160h352v298c0 3.3-2.7 6-6 6z"] }; +var faCalendarAlt = { prefix: 'far', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarCheck = { prefix: 'far', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M400 64h-48V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H160V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v52H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V160h352v298a6 6 0 0 1-6 6zm-52.849-200.65L198.842 404.519c-4.705 4.667-12.303 4.637-16.971-.068l-75.091-75.699c-4.667-4.705-4.637-12.303.068-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l44.104 44.461 111.072-110.181c4.705-4.667 12.303-4.637 16.971.068l22.536 22.718c4.667 4.705 4.636 12.303-.069 16.97z"] }; +var faCalendarMinus = { prefix: 'far', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M124 328c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H124zm324-216v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarPlus = { prefix: 'far', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M336 292v24c0 6.6-5.4 12-12 12h-76v76c0 6.6-5.4 12-12 12h-24c-6.6 0-12-5.4-12-12v-76h-76c-6.6 0-12-5.4-12-12v-24c0-6.6 5.4-12 12-12h76v-76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v76h76c6.6 0 12 5.4 12 12zm112-180v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCalendarTimes = { prefix: 'far', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M311.7 374.7l-17 17c-4.7 4.7-12.3 4.7-17 0L224 337.9l-53.7 53.7c-4.7 4.7-12.3 4.7-17 0l-17-17c-4.7-4.7-4.7-12.3 0-17l53.7-53.7-53.7-53.7c-4.7-4.7-4.7-12.3 0-17l17-17c4.7-4.7 12.3-4.7 17 0l53.7 53.7 53.7-53.7c4.7-4.7 12.3-4.7 17 0l17 17c4.7 4.7 4.7 12.3 0 17L257.9 304l53.7 53.7c4.8 4.7 4.8 12.3.1 17zM448 112v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareDown = { prefix: 'far', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M125.1 208h197.8c10.7 0 16.1 13 8.5 20.5l-98.9 98.3c-4.7 4.7-12.2 4.7-16.9 0l-98.9-98.3c-7.7-7.5-2.3-20.5 8.4-20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareLeft = { prefix: 'far', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M272 157.1v197.8c0 10.7-13 16.1-20.5 8.5l-98.3-98.9c-4.7-4.7-4.7-12.2 0-16.9l98.3-98.9c7.5-7.7 20.5-2.3 20.5 8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareRight = { prefix: 'far', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M176 354.9V157.1c0-10.7 13-16.1 20.5-8.5l98.3 98.9c4.7 4.7 4.7 12.2 0 16.9l-98.3 98.9c-7.5 7.7-20.5 2.3-20.5-8.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faCaretSquareUp = { prefix: 'far', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M322.9 304H125.1c-10.7 0-16.1-13-8.5-20.5l98.9-98.3c4.7-4.7 12.2-4.7 16.9 0l98.9 98.3c7.7 7.5 2.3 20.5-8.4 20.5zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faChartBar = { prefix: 'far', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 400c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v324h452zm-356-60v-72c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V140c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V204c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12zm96 0V108c0-6.6-5.4-12-12-12h-24c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h24c6.6 0 12-5.4 12-12z"] }; +var faCheckCircle = { prefix: 'far', iconName: 'check-circle', icon: [512, 512, [], "f058", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z"] }; +var faCheckSquare = { prefix: 'far', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm0 400H48V80h352v352zm-35.864-241.724L191.547 361.48c-4.705 4.667-12.303 4.637-16.97-.068l-90.781-91.516c-4.667-4.705-4.637-12.303.069-16.971l22.719-22.536c4.705-4.667 12.303-4.637 16.97.069l59.792 60.277 141.352-140.216c4.705-4.667 12.303-4.637 16.97.068l22.536 22.718c4.667 4.706 4.637 12.304-.068 16.971z"] }; +var faCircle = { prefix: 'far', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"] }; +var faClipboard = { prefix: 'far', iconName: 'clipboard', icon: [384, 512, [], "f328", "M336 64h-80c0-35.29-28.71-64-64-64s-64 28.71-64 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h42v36c0 6.627 5.373 12 12 12h168c6.627 0 12-5.373 12-12v-36h42a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zM192 40c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24"] }; +var faClock = { prefix: 'far', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; +var faClone = { prefix: 'far', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0H144c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h320c26.51 0 48-21.49 48-48v-48h48c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48zM362 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h42v224c0 26.51 21.49 48 48 48h224v42a6 6 0 0 1-6 6zm96-96H150a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h308a6 6 0 0 1 6 6v308a6 6 0 0 1-6 6z"] }; +var faClosedCaptioning = { prefix: 'far', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-211.1-85.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7zm190.4 0c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.9-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 220.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6 2.8-2.5 7.1-2.1 9.2.9l19.6 27.7z"] }; +var faComment = { prefix: 'far', iconName: 'comment', icon: [576, 512, [], "f075", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160z"] }; +var faCommentAlt = { prefix: 'far', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M288 32C129 32 0 125.1 0 240c0 49.3 23.7 94.5 63.3 130.2-8.7 23.3-22.1 32.7-37.1 43.1C15.1 421-6 433 1.6 456.5c5.1 15.4 20.9 24.7 38.1 23.3 57.7-4.6 111.2-19.2 157-42.5 28.7 6.9 59.4 10.7 91.2 10.7 159.1 0 288-93 288-208C576 125.1 447.1 32 288 32zm0 368c-32.5 0-65.4-4.4-97.3-14-32.3 19-78.7 46-134.7 54 32-24 56.8-61.6 61.2-88.4C79.1 325.6 48 286.7 48 240c0-70.9 86.3-160 240-160s240 89.1 240 160c0 71-86.3 160-240 160zm-64-160c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48zm112 0c0 26.5-21.5 48-48 48s-48-21.5-48-48 21.5-48 48-48 48 21.5 48 48z"] }; +var faComments = { prefix: 'far', iconName: 'comments', icon: [576, 512, [], "f086", "M574.507 443.86c-5.421 21.261-24.57 36.14-46.511 36.14-32.246 0-66.511-9.99-102.1-29.734-50.64 11.626-109.151 7.877-157.96-13.437 41.144-2.919 80.361-12.339 116.331-28.705 16.322-1.22 32.674-4.32 48.631-9.593C454.404 412.365 490.663 432 527.996 432c-32-17.455-43.219-38.958-46.159-58.502 25.443-18.848 46.159-47.183 46.159-81.135 0-10.495-2.383-21.536-7.041-32.467 7.405-25.93 8.656-50.194 5.185-73.938 32.164 30.461 49.856 69.128 49.856 106.405 0 33.893-12.913 65.047-34.976 91.119 2.653 2.038 5.924 4.176 9.962 6.378 19.261 10.508 28.947 32.739 23.525 54zM240.002 80C117.068 80 48.004 152.877 48.004 210.909c0 38.196 24.859 70.072 55.391 91.276-3.527 21.988-16.991 46.179-55.391 65.815 44.8 0 88.31-22.089 114.119-37.653 25.52 7.906 51.883 11.471 77.879 11.471C362.998 341.818 432 268.976 432 210.909 432 152.882 362.943 80 240.002 80m0-48C390.193 32 480 126.026 480 210.909c0 22.745-6.506 46.394-18.816 68.391-11.878 21.226-28.539 40.294-49.523 56.674-21.593 16.857-46.798 30.045-74.913 39.197-29.855 9.719-62.405 14.646-96.746 14.646-24.449 0-48.34-2.687-71.292-8.004C126.311 404.512 85.785 416 48.004 416c-22.18 0-41.472-15.197-46.665-36.761-5.194-21.563 5.064-43.878 24.811-53.976 7.663-3.918 13.324-7.737 17.519-11.294-7.393-7.829-13.952-16.124-19.634-24.844C8.09 264.655.005 238.339.005 210.909.005 126.259 89.508 32 240.002 32z"] }; +var faCompass = { prefix: 'far', iconName: 'compass', icon: [512, 512, [], "f14e", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm91.326-312.131l-33.359 137.779a24.005 24.005 0 0 1-6.772 11.729l-102.64 97.779c-17.104 16.293-45.56.434-39.88-23.024l33.359-137.779a23.997 23.997 0 0 1 6.772-11.729l102.642-97.779c17.285-16.47 45.494-.175 39.878 23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faCopy = { prefix: 'far', iconName: 'copy', icon: [448, 512, [], "f0c5", "M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"] }; +var faCopyright = { prefix: 'far', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm107.351-101.064c-9.614 9.712-45.53 41.396-104.065 41.396-82.43 0-140.484-61.425-140.484-141.567 0-79.152 60.275-139.401 139.762-139.401 55.531 0 88.738 26.62 97.593 34.779a11.965 11.965 0 0 1 1.936 15.322l-18.155 28.113c-3.841 5.95-11.966 7.282-17.499 2.921-8.595-6.776-31.814-22.538-61.708-22.538-48.303 0-77.916 35.33-77.916 80.082 0 41.589 26.888 83.692 78.277 83.692 32.657 0 56.843-19.039 65.726-27.225 5.27-4.857 13.596-4.039 17.82 1.738l19.865 27.17a11.947 11.947 0 0 1-1.152 15.518z"] }; +var faCreditCard = { prefix: 'far', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M527.9 32H48.1C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48.1 48h479.8c26.6 0 48.1-21.5 48.1-48V80c0-26.5-21.5-48-48.1-48zM54.1 80h467.8c3.3 0 6 2.7 6 6v42H48.1V86c0-3.3 2.7-6 6-6zm467.8 352H54.1c-3.3 0-6-2.7-6-6V256h479.8v170c0 3.3-2.7 6-6 6zM192 332v40c0 6.6-5.4 12-12 12h-72c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12zm192 0v40c0 6.6-5.4 12-12 12H236c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12z"] }; +var faDotCircle = { prefix: 'far', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 168c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80z"] }; +var faEdit = { prefix: 'far', iconName: 'edit', icon: [576, 512, [], "f044", "M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z"] }; +var faEnvelope = { prefix: 'far', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z"] }; +var faEnvelopeOpen = { prefix: 'far', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M494.586 164.516c-4.697-3.883-111.723-89.95-135.251-108.657C337.231 38.191 299.437 0 256 0c-43.205 0-80.636 37.717-103.335 55.859-24.463 19.45-131.07 105.195-135.15 108.549A48.004 48.004 0 0 0 0 201.485V464c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V201.509a48 48 0 0 0-17.414-36.993zM464 458a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V204.347c0-1.813.816-3.526 2.226-4.665 15.87-12.814 108.793-87.554 132.364-106.293C200.755 78.88 232.398 48 256 48c23.693 0 55.857 31.369 73.41 45.389 23.573 18.741 116.503 93.493 132.366 106.316a5.99 5.99 0 0 1 2.224 4.663V458zm-31.991-187.704c4.249 5.159 3.465 12.795-1.745 16.981-28.975 23.283-59.274 47.597-70.929 56.863C336.636 362.283 299.205 400 256 400c-43.452 0-81.287-38.237-103.335-55.86-11.279-8.967-41.744-33.413-70.927-56.865-5.21-4.187-5.993-11.822-1.745-16.981l15.258-18.528c4.178-5.073 11.657-5.843 16.779-1.726 28.618 23.001 58.566 47.035 70.56 56.571C200.143 320.631 232.307 352 256 352c23.602 0 55.246-30.88 73.41-45.389 11.994-9.535 41.944-33.57 70.563-56.568 5.122-4.116 12.601-3.346 16.778 1.727l15.258 18.526z"] }; +var faEyeSlash = { prefix: 'far', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z"] }; +var faFile = { prefix: 'far', iconName: 'file', icon: [384, 512, [], "f15b", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48z"] }; +var faFileAlt = { prefix: 'far', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M288 248v28c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-28c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm-12 72H108c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-28c0-6.6-5.4-12-12-12zm108-188.1V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h204.1C264.8 0 277 5.1 286 14.1L369.9 98c9 8.9 14.1 21.2 14.1 33.9zm-128-80V128h76.1L256 51.9zM336 464V176H232c-13.3 0-24-10.7-24-24V48H48v416h288z"] }; +var faFileArchive = { prefix: 'far', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM256 51.882L332.118 128H256V51.882zM336 464H48V48h79.714v16h32V48H208v104c0 13.255 10.745 24 24 24h104v288zM192.27 96h-32V64h32v32zm-32 0v32h-32V96h32zm0 64v32h-32v-32h32zm32 0h-32v-32h32v32zm1.909 105.678A12 12 0 0 0 182.406 256H160.27v-32h-32v32l-19.69 97.106C101.989 385.611 126.834 416 160 416c33.052 0 57.871-30.192 51.476-62.62l-17.297-87.702zM160.27 390.073c-17.918 0-32.444-12.105-32.444-27.036 0-14.932 14.525-27.036 32.444-27.036s32.444 12.105 32.444 27.036c0 14.931-14.526 27.036-32.444 27.036zm32-166.073h-32v-32h32v32z"] }; +var faFileAudio = { prefix: 'far', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm144-76.024c0 10.691-12.926 16.045-20.485 8.485L136 360.486h-28c-6.627 0-12-5.373-12-12v-56c0-6.627 5.373-12 12-12h28l35.515-36.947c7.56-7.56 20.485-2.206 20.485 8.485v135.952zm41.201-47.13c9.051-9.297 9.06-24.133.001-33.439-22.149-22.752 12.235-56.246 34.395-33.481 27.198 27.94 27.212 72.444.001 100.401-21.793 22.386-56.947-10.315-34.397-33.481z"] }; +var faFileCode = { prefix: 'far', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm101.677-115.115L116.854 320l32.822-28.885a8.793 8.793 0 0 0 .605-12.624l-17.403-18.564c-3.384-3.613-8.964-3.662-12.438-.401L62.78 313.58c-3.703 3.474-3.704 9.367.001 12.84l57.659 54.055a8.738 8.738 0 0 0 6.012 2.381 8.746 8.746 0 0 0 6.427-2.782l17.403-18.563a8.795 8.795 0 0 0-.605-12.626zm84.284-127.85l-24.401-7.084a8.796 8.796 0 0 0-10.905 5.998L144.04 408.061c-1.353 4.66 1.338 9.552 5.998 10.905l24.403 7.084c4.68 1.355 9.557-1.354 10.905-5.998l54.612-188.112c1.354-4.66-1.337-9.552-5.997-10.905zm87.258 92.545l-57.658-54.055c-3.526-3.307-9.099-3.165-12.439.401l-17.403 18.563a8.795 8.795 0 0 0 .605 12.625L267.146 320l-32.822 28.885a8.793 8.793 0 0 0-.605 12.624l17.403 18.564a8.797 8.797 0 0 0 12.439.401h-.001l57.66-54.055c3.703-3.473 3.703-9.366-.001-12.839z"] }; +var faFileExcel = { prefix: 'far', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm212-240h-28.8c-4.4 0-8.4 2.4-10.5 6.3-18 33.1-22.2 42.4-28.6 57.7-13.9-29.1-6.9-17.3-28.6-57.7-2.1-3.9-6.2-6.3-10.6-6.3H124c-9.3 0-15 10-10.4 18l46.3 78-46.3 78c-4.7 8 1.1 18 10.4 18h28.9c4.4 0 8.4-2.4 10.5-6.3 21.7-40 23-45 28.6-57.7 14.9 30.2 5.9 15.9 28.6 57.7 2.1 3.9 6.2 6.3 10.6 6.3H260c9.3 0 15-10 10.4-18L224 320c.7-1.1 30.3-50.5 46.3-78 4.7-8-1.1-18-10.3-18z"] }; +var faFileImage = { prefix: 'far', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; +var faFilePdf = { prefix: 'far', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm250.2-143.7c-12.2-12-47-8.7-64.4-6.5-17.2-10.5-28.7-25-36.8-46.3 3.9-16.1 10.1-40.6 5.4-56-4.2-26.2-37.8-23.6-42.6-5.9-4.4 16.1-.4 38.5 7 67.1-10 23.9-24.9 56-35.4 74.4-20 10.3-47 26.2-51 46.2-3.3 15.8 26 55.2 76.1-31.2 22.4-7.4 46.8-16.5 68.4-20.1 18.9 10.2 41 17 55.8 17 25.5 0 28-28.2 17.5-38.7zm-198.1 77.8c5.1-13.7 24.5-29.5 30.4-35-19 30.3-30.4 35.7-30.4 35zm81.6-190.6c7.4 0 6.7 32.1 1.8 40.8-4.4-13.9-4.3-40.8-1.8-40.8zm-24.4 136.6c9.7-16.9 18-37 24.7-54.7 8.3 15.1 18.9 27.2 30.1 35.5-20.8 4.3-38.9 13.1-54.8 19.2zm131.6-5s-5 6-37.3-7.8c35.1-2.6 40.9 5.4 37.3 7.8z"] }; +var faFilePowerpoint = { prefix: 'far', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm72-60V236c0-6.6 5.4-12 12-12h69.2c36.7 0 62.8 27 62.8 66.3 0 74.3-68.7 66.5-95.5 66.5V404c0 6.6-5.4 12-12 12H132c-6.6 0-12-5.4-12-12zm48.5-87.4h23c7.9 0 13.9-2.4 18.1-7.2 8.5-9.8 8.4-28.5.1-37.8-4.1-4.6-9.9-7-17.4-7h-23.9v52z"] }; +var faFileVideo = { prefix: 'far', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M369.941 97.941l-83.882-83.882A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V131.882a48 48 0 0 0-14.059-33.941zM332.118 128H256V51.882L332.118 128zM48 464V48h160v104c0 13.255 10.745 24 24 24h104v288H48zm228.687-211.303L224 305.374V268c0-11.046-8.954-20-20-20H100c-11.046 0-20 8.954-20 20v104c0 11.046 8.954 20 20 20h104c11.046 0 20-8.954 20-20v-37.374l52.687 52.674C286.704 397.318 304 390.28 304 375.986V264.011c0-14.311-17.309-21.319-27.313-11.314z"] }; +var faFileWord = { prefix: 'far', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm220.1-208c-5.7 0-10.6 4-11.7 9.5-20.6 97.7-20.4 95.4-21 103.5-.2-1.2-.4-2.6-.7-4.3-.8-5.1.3.2-23.6-99.5-1.3-5.4-6.1-9.2-11.7-9.2h-13.3c-5.5 0-10.3 3.8-11.7 9.1-24.4 99-24 96.2-24.8 103.7-.1-1.1-.2-2.5-.5-4.2-.7-5.2-14.1-73.3-19.1-99-1.1-5.6-6-9.7-11.8-9.7h-16.8c-7.8 0-13.5 7.3-11.7 14.8 8 32.6 26.7 109.5 33.2 136 1.3 5.4 6.1 9.1 11.7 9.1h25.2c5.5 0 10.3-3.7 11.6-9.1l17.9-71.4c1.5-6.2 2.5-12 3-17.3l2.9 17.3c.1.4 12.6 50.5 17.9 71.4 1.3 5.3 6.1 9.1 11.6 9.1h24.7c5.5 0 10.3-3.7 11.6-9.1 20.8-81.9 30.2-119 34.5-136 1.9-7.6-3.8-14.9-11.6-14.9h-15.8z"] }; +var faFlag = { prefix: 'far', iconName: 'flag', icon: [512, 512, [], "f024", "M336.174 80c-49.132 0-93.305-32-161.913-32-31.301 0-58.303 6.482-80.721 15.168a48.04 48.04 0 0 0 2.142-20.727C93.067 19.575 74.167 1.594 51.201.104 23.242-1.71 0 20.431 0 48c0 17.764 9.657 33.262 24 41.562V496c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-83.443C109.869 395.28 143.259 384 199.826 384c49.132 0 93.305 32 161.913 32 58.479 0 101.972-22.617 128.548-39.981C503.846 367.161 512 352.051 512 335.855V95.937c0-34.459-35.264-57.768-66.904-44.117C409.193 67.309 371.641 80 336.174 80zM464 336c-21.783 15.412-60.824 32-102.261 32-59.945 0-102.002-32-161.913-32-43.361 0-96.379 9.403-127.826 24V128c21.784-15.412 60.824-32 102.261-32 59.945 0 102.002 32 161.913 32 43.271 0 96.32-17.366 127.826-32v240z"] }; +var faFolder = { prefix: 'far', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48zm-6 272H54c-3.314 0-6-2.678-6-5.992V117.992A5.993 5.993 0 0 1 54 112h134.118l64 64H458a6 6 0 0 1 6 6v212a6 6 0 0 1-6 6z"] }; +var faFolderOpen = { prefix: 'far', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M527.943 224H480v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h400a48.001 48.001 0 0 0 40.704-22.56l79.942-128c19.948-31.917-3.038-73.44-40.703-73.44zM54 112h134.118l64 64H426a6 6 0 0 1 6 6v42H152a48 48 0 0 0-41.098 23.202L48 351.449V117.993A5.993 5.993 0 0 1 54 112zm394 288H72l77.234-128H528l-80 128z"] }; +var faFrown = { prefix: 'far', iconName: 'frown', icon: [512, 512, [], "f119", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm171.547 201.782c-56.595-76.964-158.383-77.065-215.057-.001-18.82 25.593 19.858 54.018 38.67 28.438 37.511-51.01 100.365-50.796 137.717-.001 18.509 25.172 57.821-2.395 38.67-28.436z"] }; +var faFutbol = { prefix: 'far', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M207.898 325.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-455.998-.19L48 256c0 44.7 14.015 87.242 39.95 122.626l7.982-35.118 88.595 10.871 37.775 80.985-30.978 18.427c41.832 13.631 87.598 13.606 129.354 0L289.7 435.364l37.775-80.985 88.594-10.871 7.982 35.118C449.985 343.242 464 300.7 464 256l-.002-.19-27.003 23.561-65.223-60.875 17.122-87.779 35.538 3.183c-25.216-34.63-61.309-62.053-104.577-75.951l14.143 33.091L256 134.25l-77.996-43.21 14.144-33.091C148.868 71.851 112.782 99.277 87.57 133.9l35.81-3.183 16.849 87.779-65.223 60.875-27.004-23.561z"] }; +var faGem = { prefix: 'far', iconName: 'gem', icon: [576, 512, [], "f3a5", "M464 0H112c-4 0-7.8 2-10 5.4L2 152.6c-2.9 4.4-2.6 10.2.7 14.2l276 340.8c4.8 5.9 13.8 5.9 18.6 0l276-340.8c3.3-4.1 3.6-9.8.7-14.2L474.1 5.4C471.8 2 468.1 0 464 0zm-19.3 48l63.3 96h-68.4l-51.7-96h56.8zm-202.1 0h90.7l51.7 96H191l51.6-96zm-111.3 0h56.8l-51.7 96H68l63.3-96zm-43 144h51.4L208 352 88.3 192zm102.9 0h193.6L288 435.3 191.2 192zM368 352l68.2-160h51.4L368 352z"] }; +var faHandLizard = { prefix: 'far', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M556.686 290.542L410.328 64.829C397.001 44.272 374.417 32 349.917 32H56C25.121 32 0 57.122 0 88v8c0 44.112 35.888 80 80 80h196.042l-18.333 48H144c-48.523 0-88 39.477-88 88 0 30.879 25.121 56 56 56h131.552c2.987 0 5.914.549 8.697 1.631L352 408.418V480h224V355.829c0-23.225-6.679-45.801-19.314-65.287zM528 432H400v-23.582c0-19.948-12.014-37.508-30.604-44.736l-99.751-38.788A71.733 71.733 0 0 0 243.552 320H112c-4.411 0-8-3.589-8-8 0-22.056 17.944-40 40-40h113.709c19.767 0 37.786-12.407 44.84-30.873l24.552-64.281c8.996-23.553-8.428-48.846-33.63-48.846H80c-17.645 0-32-14.355-32-32v-8c0-4.411 3.589-8 8-8h293.917c8.166 0 15.693 4.09 20.137 10.942l146.358 225.715A71.84 71.84 0 0 1 528 355.829V432z"] }; +var faHandPaper = { prefix: 'far', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M372.57 112.641v-10.825c0-43.612-40.52-76.691-83.039-65.546-25.629-49.5-94.09-47.45-117.982.747C130.269 26.456 89.144 57.945 89.144 102v126.13c-19.953-7.427-43.308-5.068-62.083 8.871-29.355 21.796-35.794 63.333-14.55 93.153L132.48 498.569a32 32 0 0 0 26.062 13.432h222.897c14.904 0 27.835-10.289 31.182-24.813l30.184-130.958A203.637 203.637 0 0 0 448 310.564V179c0-40.62-35.523-71.992-75.43-66.359zm27.427 197.922c0 11.731-1.334 23.469-3.965 34.886L368.707 464h-201.92L51.591 302.303c-14.439-20.27 15.023-42.776 29.394-22.605l27.128 38.079c8.995 12.626 29.031 6.287 29.031-9.283V102c0-25.645 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V67c0-25.663 36.571-24.81 36.571.691V256c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16V101.125c0-25.672 36.57-24.81 36.57.691V256c0 8.837 7.163 16 16 16h6.857c8.837 0 16-7.163 16-16v-76.309c0-26.242 36.57-25.64 36.57-.691v131.563z"] }; +var faHandPeace = { prefix: 'far', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M362.146 191.976c-13.71-21.649-38.761-34.016-65.006-30.341V74c0-40.804-32.811-74-73.141-74-40.33 0-73.14 33.196-73.14 74L160 168l-18.679-78.85C126.578 50.843 83.85 32.11 46.209 47.208 8.735 62.238-9.571 104.963 5.008 142.85l55.757 144.927c-30.557 24.956-43.994 57.809-24.733 92.218l54.853 97.999C102.625 498.97 124.73 512 148.575 512h205.702c30.744 0 57.558-21.44 64.555-51.797l27.427-118.999a67.801 67.801 0 0 0 1.729-15.203L448 256c0-44.956-43.263-77.343-85.854-64.024zM399.987 326c0 1.488-.169 2.977-.502 4.423l-27.427 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H148.575c-6.486 0-12.542-3.621-15.805-9.449l-54.854-98c-4.557-8.141-2.619-18.668 4.508-24.488l26.647-21.764a16 16 0 0 0 4.812-18.139l-64.09-166.549C37.226 92.956 84.37 74.837 96.51 106.389l59.784 155.357A16 16 0 0 0 171.227 272h11.632c8.837 0 16-7.163 16-16V74c0-34.375 50.281-34.43 50.281 0v182c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16v-28c0-25.122 36.567-25.159 36.567 0v28c0 8.837 7.163 16 16 16h6.856c8.837 0 16-7.163 16-16 0-25.12 36.567-25.16 36.567 0v70z"] }; +var faHandPointDown = { prefix: 'far', iconName: 'hand-point-down', icon: [448, 512, [], "f0a7", "M188.8 512c45.616 0 83.2-37.765 83.2-83.2v-35.647a93.148 93.148 0 0 0 22.064-7.929c22.006 2.507 44.978-3.503 62.791-15.985C409.342 368.1 448 331.841 448 269.299V248c0-60.063-40-98.512-40-127.2v-2.679c4.952-5.747 8-13.536 8-22.12V32c0-17.673-12.894-32-28.8-32H156.8C140.894 0 128 14.327 128 32v64c0 8.584 3.048 16.373 8 22.12v2.679c0 6.964-6.193 14.862-23.668 30.183l-.148.129-.146.131c-9.937 8.856-20.841 18.116-33.253 25.851C48.537 195.798 0 207.486 0 252.8c0 56.928 35.286 92 83.2 92 8.026 0 15.489-.814 22.4-2.176V428.8c0 45.099 38.101 83.2 83.2 83.2zm0-48c-18.7 0-35.2-16.775-35.2-35.2V270.4c-17.325 0-35.2 26.4-70.4 26.4-26.4 0-35.2-20.625-35.2-44 0-8.794 32.712-20.445 56.1-34.926 14.575-9.074 27.225-19.524 39.875-30.799 18.374-16.109 36.633-33.836 39.596-59.075h176.752C364.087 170.79 400 202.509 400 248v21.299c0 40.524-22.197 57.124-61.325 50.601-8.001 14.612-33.979 24.151-53.625 12.925-18.225 19.365-46.381 17.787-61.05 4.95V428.8c0 18.975-16.225 35.2-35.2 35.2zM328 64c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24z"] }; +var faHandPointLeft = { prefix: 'far', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M0 220.8C0 266.416 37.765 304 83.2 304h35.647a93.148 93.148 0 0 0 7.929 22.064c-2.507 22.006 3.503 44.978 15.985 62.791C143.9 441.342 180.159 480 242.701 480H264c60.063 0 98.512-40 127.2-40h2.679c5.747 4.952 13.536 8 22.12 8h64c17.673 0 32-12.894 32-28.8V188.8c0-15.906-14.327-28.8-32-28.8h-64c-8.584 0-16.373 3.048-22.12 8H391.2c-6.964 0-14.862-6.193-30.183-23.668l-.129-.148-.131-.146c-8.856-9.937-18.116-20.841-25.851-33.253C316.202 80.537 304.514 32 259.2 32c-56.928 0-92 35.286-92 83.2 0 8.026.814 15.489 2.176 22.4H83.2C38.101 137.6 0 175.701 0 220.8zm48 0c0-18.7 16.775-35.2 35.2-35.2h158.4c0-17.325-26.4-35.2-26.4-70.4 0-26.4 20.625-35.2 44-35.2 8.794 0 20.445 32.712 34.926 56.1 9.074 14.575 19.524 27.225 30.799 39.875 16.109 18.374 33.836 36.633 59.075 39.596v176.752C341.21 396.087 309.491 432 264 432h-21.299c-40.524 0-57.124-22.197-50.601-61.325-14.612-8.001-24.151-33.979-12.925-53.625-19.365-18.225-17.787-46.381-4.95-61.05H83.2C64.225 256 48 239.775 48 220.8zM448 360c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; +var faHandPointRight = { prefix: 'far', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M428.8 137.6h-86.177a115.52 115.52 0 0 0 2.176-22.4c0-47.914-35.072-83.2-92-83.2-45.314 0-57.002 48.537-75.707 78.784-7.735 12.413-16.994 23.317-25.851 33.253l-.131.146-.129.148C135.662 161.807 127.764 168 120.8 168h-2.679c-5.747-4.952-13.536-8-22.12-8H32c-17.673 0-32 12.894-32 28.8v230.4C0 435.106 14.327 448 32 448h64c8.584 0 16.373-3.048 22.12-8h2.679c28.688 0 67.137 40 127.2 40h21.299c62.542 0 98.8-38.658 99.94-91.145 12.482-17.813 18.491-40.785 15.985-62.791A93.148 93.148 0 0 0 393.152 304H428.8c45.435 0 83.2-37.584 83.2-83.2 0-45.099-38.101-83.2-83.2-83.2zm0 118.4h-91.026c12.837 14.669 14.415 42.825-4.95 61.05 11.227 19.646 1.687 45.624-12.925 53.625 6.524 39.128-10.076 61.325-50.6 61.325H248c-45.491 0-77.21-35.913-120-39.676V215.571c25.239-2.964 42.966-21.222 59.075-39.596 11.275-12.65 21.725-25.3 30.799-39.875C232.355 112.712 244.006 80 252.8 80c23.375 0 44 8.8 44 35.2 0 35.2-26.4 53.075-26.4 70.4h158.4c18.425 0 35.2 16.5 35.2 35.2 0 18.975-16.225 35.2-35.2 35.2zM88 384c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; +var faHandPointUp = { prefix: 'far', iconName: 'hand-point-up', icon: [448, 512, [], "f0a6", "M105.6 83.2v86.177a115.52 115.52 0 0 0-22.4-2.176c-47.914 0-83.2 35.072-83.2 92 0 45.314 48.537 57.002 78.784 75.707 12.413 7.735 23.317 16.994 33.253 25.851l.146.131.148.129C129.807 376.338 136 384.236 136 391.2v2.679c-4.952 5.747-8 13.536-8 22.12v64c0 17.673 12.894 32 28.8 32h230.4c15.906 0 28.8-14.327 28.8-32v-64c0-8.584-3.048-16.373-8-22.12V391.2c0-28.688 40-67.137 40-127.2v-21.299c0-62.542-38.658-98.8-91.145-99.94-17.813-12.482-40.785-18.491-62.791-15.985A93.148 93.148 0 0 0 272 118.847V83.2C272 37.765 234.416 0 188.8 0c-45.099 0-83.2 38.101-83.2 83.2zm118.4 0v91.026c14.669-12.837 42.825-14.415 61.05 4.95 19.646-11.227 45.624-1.687 53.625 12.925 39.128-6.524 61.325 10.076 61.325 50.6V264c0 45.491-35.913 77.21-39.676 120H183.571c-2.964-25.239-21.222-42.966-39.596-59.075-12.65-11.275-25.3-21.725-39.875-30.799C80.712 279.645 48 267.994 48 259.2c0-23.375 8.8-44 35.2-44 35.2 0 53.075 26.4 70.4 26.4V83.2c0-18.425 16.5-35.2 35.2-35.2 18.975 0 35.2 16.225 35.2 35.2zM352 424c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24z"] }; +var faHandPointer = { prefix: 'far', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M358.182 179.361c-19.493-24.768-52.679-31.945-79.872-19.098-15.127-15.687-36.182-22.487-56.595-19.629V67c0-36.944-29.736-67-66.286-67S89.143 30.056 89.143 67v161.129c-19.909-7.41-43.272-5.094-62.083 8.872-29.355 21.795-35.793 63.333-14.55 93.152l109.699 154.001C134.632 501.59 154.741 512 176 512h178.286c30.802 0 57.574-21.5 64.557-51.797l27.429-118.999A67.873 67.873 0 0 0 448 326v-84c0-46.844-46.625-79.273-89.818-62.639zM80.985 279.697l27.126 38.079c8.995 12.626 29.031 6.287 29.031-9.283V67c0-25.12 36.571-25.16 36.571 0v175c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16v-35c0-25.12 36.571-25.16 36.571 0v35c0 8.836 7.163 16 16 16H272c8.837 0 16-7.164 16-16v-21c0-25.12 36.571-25.16 36.571 0v21c0 8.836 7.163 16 16 16h6.857c8.837 0 16-7.164 16-16 0-25.121 36.571-25.16 36.571 0v84c0 1.488-.169 2.977-.502 4.423l-27.43 119.001c-1.978 8.582-9.29 14.576-17.782 14.576H176c-5.769 0-11.263-2.878-14.697-7.697l-109.712-154c-14.406-20.223 14.994-42.818 29.394-22.606zM176.143 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.733 0-14-7.163-14-16zm75.428 0v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16zM327 400v-96c0-8.837 6.268-16 14-16h6c7.732 0 14 7.163 14 16v96c0 8.837-6.268 16-14 16h-6c-7.732 0-14-7.163-14-16z"] }; +var faHandRock = { prefix: 'far', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M408.864 79.052c-22.401-33.898-66.108-42.273-98.813-23.588-29.474-31.469-79.145-31.093-108.334-.022-47.16-27.02-108.71 5.055-110.671 60.806C44.846 105.407 0 140.001 0 187.429v56.953c0 32.741 14.28 63.954 39.18 85.634l97.71 85.081c4.252 3.702 3.11 5.573 3.11 32.903 0 17.673 14.327 32 32 32h252c17.673 0 32-14.327 32-32 0-23.513-1.015-30.745 3.982-42.37l42.835-99.656c6.094-14.177 9.183-29.172 9.183-44.568V146.963c0-52.839-54.314-88.662-103.136-67.911zM464 261.406a64.505 64.505 0 0 1-5.282 25.613l-42.835 99.655c-5.23 12.171-7.883 25.04-7.883 38.25V432H188v-10.286c0-16.37-7.14-31.977-19.59-42.817l-97.71-85.08C56.274 281.255 48 263.236 48 244.381v-56.953c0-33.208 52-33.537 52 .677v41.228a16 16 0 0 0 5.493 12.067l7 6.095A16 16 0 0 0 139 235.429V118.857c0-33.097 52-33.725 52 .677v26.751c0 8.836 7.164 16 16 16h7c8.836 0 16-7.164 16-16v-41.143c0-33.134 52-33.675 52 .677v40.466c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16v-27.429c0-33.03 52-33.78 52 .677v26.751c0 8.836 7.163 16 16 16h7c8.837 0 16-7.164 16-16 0-33.146 52-33.613 52 .677v114.445z"] }; +var faHandScissors = { prefix: 'far', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M256 480l70-.013c5.114 0 10.231-.583 15.203-1.729l118.999-27.427C490.56 443.835 512 417.02 512 386.277V180.575c0-23.845-13.03-45.951-34.005-57.69l-97.999-54.853c-34.409-19.261-67.263-5.824-92.218 24.733L142.85 37.008c-37.887-14.579-80.612 3.727-95.642 41.201-15.098 37.642 3.635 80.37 41.942 95.112L168 192l-94-9.141c-40.804 0-74 32.811-74 73.14 0 40.33 33.196 73.141 74 73.141h87.635c-3.675 26.245 8.692 51.297 30.341 65.006C178.657 436.737 211.044 480 256 480zm0-48.013c-25.16 0-25.12-36.567 0-36.567 8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16h-28c-25.159 0-25.122-36.567 0-36.567h28c8.837 0 16-7.163 16-16v-6.856c0-8.837-7.163-16-16-16H74c-34.43 0-34.375-50.281 0-50.281h182c8.837 0 16-7.163 16-16v-11.632a16 16 0 0 0-10.254-14.933L106.389 128.51c-31.552-12.14-13.432-59.283 19.222-46.717l166.549 64.091a16.001 16.001 0 0 0 18.139-4.812l21.764-26.647c5.82-7.127 16.348-9.064 24.488-4.508l98 54.854c5.828 3.263 9.449 9.318 9.449 15.805v205.701c0 8.491-5.994 15.804-14.576 17.782l-119.001 27.427a19.743 19.743 0 0 1-4.423.502h-70z"] }; +var faHandSpock = { prefix: 'far', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M21.096 381.79l129.092 121.513a32 32 0 0 0 21.932 8.698h237.6c14.17 0 26.653-9.319 30.68-22.904l31.815-107.313A115.955 115.955 0 0 0 477 348.811v-36.839c0-4.051.476-8.104 1.414-12.045l31.73-133.41c10.099-42.412-22.316-82.738-65.544-82.525-4.144-24.856-22.543-47.165-49.85-53.992-35.803-8.952-72.227 12.655-81.25 48.75L296.599 184 274.924 52.01c-8.286-36.07-44.303-58.572-80.304-50.296-29.616 6.804-50.138 32.389-51.882 61.295-42.637.831-73.455 40.563-64.071 81.844l31.04 136.508c-27.194-22.515-67.284-19.992-91.482 5.722-25.376 26.961-24.098 69.325 2.871 94.707zm32.068-61.811l.002-.001c7.219-7.672 19.241-7.98 26.856-.813l53.012 49.894C143.225 378.649 160 371.4 160 357.406v-69.479c0-1.193-.134-2.383-.397-3.546l-34.13-150.172c-5.596-24.617 31.502-32.86 37.054-8.421l30.399 133.757a16 16 0 0 0 15.603 12.454h8.604c10.276 0 17.894-9.567 15.594-19.583l-41.62-181.153c-5.623-24.469 31.39-33.076 37.035-8.508l45.22 196.828A16 16 0 0 0 288.956 272h13.217a16 16 0 0 0 15.522-12.119l42.372-169.49c6.104-24.422 42.962-15.159 36.865 9.217L358.805 252.12c-2.521 10.088 5.115 19.88 15.522 19.88h9.694a16 16 0 0 0 15.565-12.295L426.509 146.6c5.821-24.448 42.797-15.687 36.966 8.802L431.72 288.81a100.094 100.094 0 0 0-2.72 23.162v36.839c0 6.548-.943 13.051-2.805 19.328L397.775 464h-219.31L53.978 346.836c-7.629-7.18-7.994-19.229-.814-26.857z"] }; +var faHandshake = { prefix: 'far', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M616 96h-48c-7.107 0-13.49 3.091-17.884 8H526.59l-31.13-36.3-.16-.18A103.974 103.974 0 0 0 417.03 32h-46.55c-17.75 0-34.9 4.94-49.69 14.01C304.33 36.93 285.67 32 266.62 32h-32.11c-28.903 0-57.599 11.219-79.2 32.8L116.12 104H89.884C85.49 99.091 79.107 96 72 96H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h48c10.449 0 19.334-6.68 22.629-16h18.801l75.35 67.57c25.542 26.45 59.925 44.43 96.58 44.43 16.39 0 32.28-3.85 46.1-10.93 24.936.496 51.101-10.368 69.07-31.41 19.684-5.579 37.503-17.426 50.72-34.6 20.989-4.401 40.728-16.492 53.42-35.06h40.701c3.295 9.32 12.18 16 22.629 16h48c13.255 0 24-10.745 24-24V120c0-13.255-10.745-24-24-24zM48 352c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16zm412.52-5.76c-15.35 14.295-36.884 11.328-39.95 8 1.414 13.382-18.257 41.043-49.08 38.88-5.541 18.523-28.218 33.826-51.49 25.75-8.89 8.89-22.46 13.13-34.64 13.13-24.95 0-47.77-14.54-63.14-30.91l-81.3-72.91a31.976 31.976 0 0 0-21.36-8.18H96V152h26.75c8.48 0 16.62-3.37 22.62-9.37l43.88-43.88A64.004 64.004 0 0 1 234.51 80h32.11c5.8 0 11.51.79 17 2.3l-43.27 50.49c-23.56 27.48-23.84 67.62-.66 95.44 32.388 38.866 91.378 39.228 124.48 1.98l25.98-30.08L462.59 296c13.44 14.6 10.95 38.13-2.07 50.24zM544 320h-24.458c.104-20.261-6.799-39.33-19.762-54.4L421.7 162.28c4.51-9.51 2.34-21.23-6.01-28.45-10.075-8.691-25.23-7.499-33.86 2.48l-53.63 62.12c-13.828 15.41-38.223 15.145-51.64-.93a25.857 25.857 0 0 1 .23-33.47l57.92-67.58A47.09 47.09 0 0 1 370.48 80h46.55c16.11 0 31.44 6.94 42.07 19.04L504.52 152H544v168zm48 32c-8.837 0-16-7.163-16-16s7.163-16 16-16 16 7.163 16 16-7.163 16-16 16z"] }; +var faHdd = { prefix: 'far', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z"] }; +var faHeart = { prefix: 'far', iconName: 'heart', icon: [576, 512, [], "f004", "M257.3 475.4L92.5 313.6C85.4 307 24 248.1 24 174.8 24 84.1 80.8 24 176 24c41.4 0 80.6 22.8 112 49.8 31.3-27 70.6-49.8 112-49.8 91.7 0 152 56.5 152 150.8 0 52-31.8 103.5-68.1 138.7l-.4.4-164.8 161.5a43.7 43.7 0 0 1-61.4 0zM125.9 279.1L288 438.3l161.8-158.7c27.3-27 54.2-66.3 54.2-104.8C504 107.9 465.8 72 400 72c-47.2 0-92.8 49.3-112 68.4-17-17-64-68.4-112-68.4-65.9 0-104 35.9-104 102.8 0 37.3 26.7 78.9 53.9 104.3z"] }; +var faHospital = { prefix: 'far', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M128 244v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12zm140 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm-76 84v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm76 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm180 124v36H0v-36c0-6.627 5.373-12 12-12h19.5V85.035C31.5 73.418 42.245 64 55.5 64H144V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v40h88.5c13.255 0 24 9.418 24 21.035V464H436c6.627 0 12 5.373 12 12zM79.5 463H192v-67c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v67h112.5V112H304v24c0 13.255-10.745 24-24 24H168c-13.255 0-24-10.745-24-24v-24H79.5v351zM266 64h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6z"] }; +var faHourglass = { prefix: 'far', iconName: 'hourglass', icon: [384, 512, [], "f254", "M368 48h4c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12H12C5.373 0 0 5.373 0 12v24c0 6.627 5.373 12 12 12h4c0 80.564 32.188 165.807 97.18 208C47.899 298.381 16 383.9 16 464h-4c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h360c6.627 0 12-5.373 12-12v-24c0-6.627-5.373-12-12-12h-4c0-80.564-32.188-165.807-97.18-208C336.102 213.619 368 128.1 368 48zM64 48h256c0 101.62-57.307 184-128 184S64 149.621 64 48zm256 416H64c0-101.62 57.308-184 128-184s128 82.38 128 184z"] }; +var faIdBadge = { prefix: 'far', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M192 128c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64 28.654-64 64-64m61.187 145.847l-18.064-5.161C222.371 275.884 207.658 280 192 280s-30.371-4.116-43.122-11.314l-18.064 5.161C110.207 279.734 96 298.569 96 320v72c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-72c0-21.431-14.207-40.266-34.813-46.153zM0 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48V48c0-26.51-21.49-48-48-48H48C21.49 0 0 21.49 0 48zm336 32v378a6 6 0 0 1-6 6H54a6 6 0 0 1-6-6V80h288z"] }; +var faIdCard = { prefix: 'far', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M404 256H300c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12zm12 68v-24c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12zm96-212v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zm-48 282V144H48v250a6 6 0 0 0 6 6h404a6 6 0 0 0 6-6zm-288-98c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56 25.072 56 56 56zm62.896 10.869l-13.464-4.039C211.814 313.568 194.649 320 176 320s-35.814-6.432-49.433-17.17l-13.464 4.039A24 24 0 0 0 96 329.857V372c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12v-42.143a24 24 0 0 0-17.104-22.988z"] }; +var faImage = { prefix: 'far', iconName: 'image', icon: [512, 512, [], "f03e", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-6 336H54a6 6 0 0 1-6-6V118a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v276a6 6 0 0 1-6 6zM128 152c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zM96 352h320v-80l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L192 304l-39.515-39.515c-4.686-4.686-12.284-4.686-16.971 0L96 304v48z"] }; +var faImages = { prefix: 'far', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v48H54a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6v-10h48zm42-336H150a6 6 0 0 0-6 6v244a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6V86a6 6 0 0 0-6-6zm6-48c26.51 0 48 21.49 48 48v256c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h384zM264 144c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-72 96l39.515-39.515c4.686-4.686 12.284-4.686 16.971 0L288 240l103.515-103.515c4.686-4.686 12.284-4.686 16.971 0L480 208v80H192v-48z"] }; +var faKeyboard = { prefix: 'far', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm8 336c0 4.411-3.589 8-8 8H48c-4.411 0-8-3.589-8-8V112c0-4.411 3.589-8 8-8h480c4.411 0 8 3.589 8 8v288zM170 270v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-336 82v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm384 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zM122 188v-28c0-6.627-5.373-12-12-12H82c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm96 0v-28c0-6.627-5.373-12-12-12h-28c-6.627 0-12 5.373-12 12v28c0 6.627 5.373 12 12 12h28c6.627 0 12-5.373 12-12zm-98 158v-16c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z"] }; +var faLemon = { prefix: 'far', iconName: 'lemon', icon: [512, 512, [], "f094", "M484.112 27.889C455.989-.233 416.108-8.057 387.059 8.865 347.604 31.848 223.504-41.111 91.196 91.197-41.277 223.672 31.923 347.472 8.866 387.058c-16.922 29.051-9.1 68.932 19.022 97.054 28.135 28.135 68.011 35.938 97.057 19.021 39.423-22.97 163.557 49.969 295.858-82.329 132.474-132.477 59.273-256.277 82.331-295.861 16.922-29.05 9.1-68.931-19.022-97.054zm-22.405 72.894c-38.8 66.609 45.6 165.635-74.845 286.08-120.44 120.443-219.475 36.048-286.076 74.843-22.679 13.207-64.035-27.241-50.493-50.488 38.8-66.609-45.6-165.635 74.845-286.08C245.573 4.702 344.616 89.086 411.219 50.292c22.73-13.24 64.005 27.288 50.488 50.491zm-169.861 8.736c1.37 10.96-6.404 20.957-17.365 22.327-54.846 6.855-135.779 87.787-142.635 142.635-1.373 10.989-11.399 18.734-22.326 17.365-10.961-1.37-18.735-11.366-17.365-22.326 9.162-73.286 104.167-168.215 177.365-177.365 10.953-1.368 20.956 6.403 22.326 17.364z"] }; +var faLifeRing = { prefix: 'far', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 504c136.967 0 248-111.033 248-248S392.967 8 256 8 8 119.033 8 256s111.033 248 248 248zm-103.398-76.72l53.411-53.411c31.806 13.506 68.128 13.522 99.974 0l53.411 53.411c-63.217 38.319-143.579 38.319-206.796 0zM336 256c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zm91.28 103.398l-53.411-53.411c13.505-31.806 13.522-68.128 0-99.974l53.411-53.411c38.319 63.217 38.319 143.579 0 206.796zM359.397 84.72l-53.411 53.411c-31.806-13.505-68.128-13.522-99.973 0L152.602 84.72c63.217-38.319 143.579-38.319 206.795 0zM84.72 152.602l53.411 53.411c-13.506 31.806-13.522 68.128 0 99.974L84.72 359.398c-38.319-63.217-38.319-143.579 0-206.796z"] }; +var faLightbulb = { prefix: 'far', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zM128 176c0-35.29 28.71-64 64-64 8.837 0 16-7.164 16-16s-7.163-16-16-16c-52.935 0-96 43.065-96 96 0 8.836 7.164 16 16 16s16-7.164 16-16zm64-128c70.734 0 128 57.254 128 128 0 77.602-37.383 60.477-80.98 160h-94.04C101.318 236.33 64 253.869 64 176c0-70.735 57.254-128 128-128m0-48C94.805 0 16 78.803 16 176c0 101.731 51.697 91.541 90.516 192.674 3.55 9.249 12.47 15.326 22.376 15.326h126.215c9.906 0 18.826-6.078 22.376-15.326C316.303 267.541 368 277.731 368 176 368 78.803 289.195 0 192 0z"] }; +var faListAlt = { prefix: 'far', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zm-6 400H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h404a6 6 0 0 1 6 6v340a6 6 0 0 1-6 6zm-42-92v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm0-96v24c0 6.627-5.373 12-12 12H204c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h200c6.627 0 12 5.373 12 12zm-252 12c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm0 96c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; +var faMap = { prefix: 'far', iconName: 'map', icon: [576, 512, [], "f279", "M508.505 36.17L381.517 92.576 207.179 34.463a47.992 47.992 0 0 0-34.674 1.674l-144 64A48 48 0 0 0 0 144v287.967c0 34.938 35.991 57.864 67.495 43.863l126.988-56.406 174.339 58.113a47.992 47.992 0 0 0 34.674-1.674l144-64A48 48 0 0 0 576 368V80.033c0-34.938-35.991-57.864-67.495-43.863zM360 424l-144-48V88l144 48v288zm-312 8V144l120-53.333v288L48 432zm480-64l-120 53.333v-288L528 80v288z"] }; +var faMeh = { prefix: 'far', iconName: 'meh', icon: [512, 512, [], "f11a", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm136 184H184c-31.776 0-31.749 48 0 48h144c31.776 0 31.749-48 0-48z"] }; +var faMinusSquare = { prefix: 'far', iconName: 'minus-square', icon: [448, 512, [], "f146", "M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faMoneyBillAlt = { prefix: 'far', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M320 144c-53.021 0-96 50.143-96 112 0 61.847 42.977 112 96 112 53 0 96-50.13 96-112 0-61.857-42.979-112-96-112zm48 164.428c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.901c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.75 3.916 11.75 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.902zM616 64H24C10.745 64 0 74.745 0 88v335c0 13.255 10.745 24 24 24h592c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM512 400H128c0-44.183-35.817-80-80-80V192c44.183 0 80-35.817 80-80h384c0 44.183 35.817 80 80 80v128c-44.183 0-80 35.817-80 80z"] }; +var faMoon = { prefix: 'far', iconName: 'moon', icon: [512, 512, [], "f186", "M279.135 512c78.756 0 150.982-35.804 198.844-94.775 28.27-34.831-2.558-85.722-46.249-77.401-82.348 15.683-158.272-47.268-158.272-130.792 0-48.424 26.06-92.292 67.434-115.836 38.745-22.05 28.999-80.788-15.022-88.919A257.936 257.936 0 0 0 279.135 0c-141.36 0-256 114.575-256 256 0 141.36 114.576 256 256 256zm0-464c12.985 0 25.689 1.201 38.016 3.478-54.76 31.163-91.693 90.042-91.693 157.554 0 113.848 103.641 199.2 215.252 177.944C402.574 433.964 344.366 464 279.135 464c-114.875 0-208-93.125-208-208s93.125-208 208-208z"] }; +var faNewspaper = { prefix: 'far', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H112c-20.858 0-38.643 13.377-45.248 32H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h496c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24zM48 392V144h16v248c0 4.411-3.589 8-8 8s-8-3.589-8-8zm480 8H111.422c.374-2.614.578-5.283.578-8V112h416v288zM172 280h136c6.627 0 12-5.373 12-12v-96c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v96c0 6.627 5.373 12 12 12zm28-80h80v40h-80v-40zm-40 140v-24c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H172c-6.627 0-12-5.373-12-12zm192 0v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0-144v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12zm0 72v-24c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12H364c-6.627 0-12-5.373-12-12z"] }; +var faObjectGroup = { prefix: 'far', iconName: 'object-group', icon: [512, 512, [], "f247", "M500 128c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v256H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V128h12zm-52-64h32v32h-32V64zM32 64h32v32H32V64zm32 384H32v-32h32v32zm416 0h-32v-32h32v32zm-40-64h-12c-6.627 0-12 5.373-12 12v12H96v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h320v12c0 6.627 5.373 12 12 12h12v256zm-36-192h-84v-52c0-6.628-5.373-12-12-12H108c-6.627 0-12 5.372-12 12v168c0 6.628 5.373 12 12 12h84v52c0 6.628 5.373 12 12 12h200c6.627 0 12-5.372 12-12V204c0-6.628-5.373-12-12-12zm-268-24h144v112H136V168zm240 176H232v-24h76c6.627 0 12-5.372 12-12v-76h56v112z"] }; +var faObjectUngroup = { prefix: 'far', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M564 224c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12h-88v-24h12c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-72c-6.627 0-12 5.373-12 12v12H96V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v72c0 6.627 5.373 12 12 12h12v160H12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h88v24h-12c-6.627 0-12 5.373-12 12v72c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12V224h12zM352 64h32v32h-32V64zm0 256h32v32h-32v-32zM64 352H32v-32h32v32zm0-256H32V64h32v32zm32 216v-12c0-6.627-5.373-12-12-12H72V128h12c6.627 0 12-5.373 12-12v-12h224v12c0 6.627 5.373 12 12 12h12v160h-12c-6.627 0-12 5.373-12 12v12H96zm128 136h-32v-32h32v32zm280-64h-12c-6.627 0-12 5.373-12 12v12H256v-12c0-6.627-5.373-12-12-12h-12v-24h88v12c0 6.627 5.373 12 12 12h72c6.627 0 12-5.373 12-12v-72c0-6.627-5.373-12-12-12h-12v-88h88v12c0 6.627 5.373 12 12 12h12v160zm40 64h-32v-32h32v32zm0-256h-32v-32h32v32z"] }; +var faPaperPlane = { prefix: 'far', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M440 6.5L24 246.4c-34.4 19.9-31.1 70.8 5.7 85.9L144 379.6V464c0 46.4 59.2 65.5 86.6 28.6l43.8-59.1 111.9 46.2c5.9 2.4 12.1 3.6 18.3 3.6 8.2 0 16.3-2.1 23.6-6.2 12.8-7.2 21.6-20 23.9-34.5l59.4-387.2c6.1-40.1-36.9-68.8-71.5-48.9zM192 464v-64.6l36.6 15.1L192 464zm212.6-28.7l-153.8-63.5L391 169.5c10.7-15.5-9.5-33.5-23.7-21.2L155.8 332.6 48 288 464 48l-59.4 387.3z"] }; +var faPauseCircle = { prefix: 'far', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm96-280v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16zm-112 0v160c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16z"] }; +var faPlayCircle = { prefix: 'far', iconName: 'play-circle', icon: [512, 512, [], "f144", "M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z"] }; +var faPlusSquare = { prefix: 'far', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z"] }; +var faQuestionCircle = { prefix: 'far', iconName: 'question-circle', icon: [512, 512, [], "f059", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z"] }; +var faRegistered = { prefix: 'far', iconName: 'registered', icon: [512, 512, [], "f25d", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 448c-110.532 0-200-89.451-200-200 0-110.531 89.451-200 200-200 110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200zm110.442-81.791c-53.046-96.284-50.25-91.468-53.271-96.085 24.267-13.879 39.482-41.563 39.482-73.176 0-52.503-30.247-85.252-101.498-85.252h-78.667c-6.617 0-12 5.383-12 12V380c0 6.617 5.383 12 12 12h38.568c6.617 0 12-5.383 12-12v-83.663h31.958l47.515 89.303a11.98 11.98 0 0 0 10.593 6.36h42.81c9.14 0 14.914-9.799 10.51-17.791zM256.933 239.906h-33.875v-64.14h27.377c32.417 0 38.929 12.133 38.929 31.709-.001 20.913-11.518 32.431-32.431 32.431z"] }; +var faSave = { prefix: 'far', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z"] }; +var faShareSquare = { prefix: 'far', iconName: 'share-square', icon: [576, 512, [], "f14d", "M561.938 158.06L417.94 14.092C387.926-15.922 336 5.097 336 48.032v57.198c-42.45 1.88-84.03 6.55-120.76 17.99-35.17 10.95-63.07 27.58-82.91 49.42C108.22 199.2 96 232.6 96 271.94c0 61.697 33.178 112.455 84.87 144.76 37.546 23.508 85.248-12.651 71.02-55.74-15.515-47.119-17.156-70.923 84.11-78.76V336c0 42.993 51.968 63.913 81.94 33.94l143.998-144c18.75-18.74 18.75-49.14 0-67.88zM384 336V232.16C255.309 234.082 166.492 255.35 206.31 376 176.79 357.55 144 324.08 144 271.94c0-109.334 129.14-118.947 240-119.85V48l144 144-144 144zm24.74 84.493a82.658 82.658 0 0 0 20.974-9.303c7.976-4.952 18.286.826 18.286 10.214V464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h132c6.627 0 12 5.373 12 12v4.486c0 4.917-2.987 9.369-7.569 11.152-13.702 5.331-26.396 11.537-38.05 18.585a12.138 12.138 0 0 1-6.28 1.777H54a6 6 0 0 0-6 6v340a6 6 0 0 0 6 6h340a6 6 0 0 0 6-6v-25.966c0-5.37 3.579-10.059 8.74-11.541z"] }; +var faSmile = { prefix: 'far', iconName: 'smile', icon: [512, 512, [], "f118", "M256 56c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m0-48C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm64 136c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059s-23.059-10.324-23.059-23.059v-.017C266.386 181.488 264 190.465 264 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm-128 0c-9.535 0-18.512 2.386-26.37 6.589h.017c12.735 0 23.059 10.324 23.059 23.059 0 12.735-10.324 23.059-23.059 23.059-12.735 0-23.059-10.324-23.059-23.059v-.017C138.386 181.488 136 190.465 136 200c0 30.928 25.072 56 56 56s56-25.072 56-56-25.072-56-56-56zm195.372 182.219c18.819-25.592-19.856-54.017-38.67-28.438-50.135 68.177-135.229 68.18-185.367 0-18.828-25.601-57.478 2.861-38.67 28.438 69.298 94.231 193.323 94.351 262.707 0z"] }; +var faSnowflake = { prefix: 'far', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M438.237 355.927l-66.574-38.54 59.448-10.327c5.846-1.375 10.609-5.183 13.458-10.13 2.48-4.307 3.506-9.478 2.524-14.651-2.11-11.115-12.686-18.039-23.621-15.467l-85.423 31.115L255.914 256l82.136-41.926 85.423 31.115c10.936 2.572 21.512-4.352 23.621-15.467 2.111-11.115-5.046-22.209-15.981-24.781l-59.448-10.327 66.573-38.54c9.54-5.523 12.615-18.092 6.867-28.074-5.748-9.982-18.14-13.596-27.68-8.074l-66.574 38.54 20.805-56.787c3.246-10.782-2.758-22.542-13.413-26.268-10.654-3.725-21.922 1.997-25.168 12.779l-15.838 89.735-72.423 41.926V136l69.585-58.621c7.689-8.21 6.997-20.856-1.548-28.245-8.545-7.391-21.705-6.723-29.394 1.486l-38.644 46.46V20c0-11.046-9.318-20-20.813-20s-20.813 8.954-20.813 20v77.08l-38.644-46.46c-7.689-8.21-20.849-8.876-29.394-1.486-8.544 7.389-9.236 20.035-1.547 28.245L203.187 136v83.853l-72.423-41.926-15.838-89.736c-3.247-10.782-14.515-16.504-25.169-12.779-10.656 3.725-16.659 15.486-13.413 26.268l20.805 56.787-66.573-38.54c-9.54-5.523-21.933-1.908-27.68 8.074s-2.673 22.551 6.867 28.074l66.574 38.54-59.449 10.328C5.953 207.515-1.202 218.609.907 229.724c2.11 11.114 12.686 18.038 23.622 15.466l85.422-31.115L192.086 256l-82.136 41.926-85.423-31.115c-10.936-2.572-21.511 4.352-23.622 15.466-2.109 11.113 5.046 22.209 15.981 24.781l59.449 10.328-66.574 38.54C.223 361.449-2.852 374.018 2.896 384s18.14 13.597 27.68 8.074l66.574-38.54-20.805 56.786c-1.735 5.764-.828 11.805 2.02 16.751 2.48 4.307 6.433 7.784 11.392 9.517 10.655 3.725 21.923-1.997 25.169-12.779l15.838-89.736 72.423-41.926V376l-69.585 58.621c-7.69 8.21-6.997 20.855 1.547 28.245 8.544 7.388 21.705 6.723 29.394-1.487l38.644-46.46V492c0 11.046 9.318 20 20.813 20s20.813-8.954 20.813-20v-77.081l38.644 46.46c4.111 4.389 9.782 6.621 15.478 6.621 4.96 0 9.939-1.694 13.916-5.134 8.545-7.39 9.237-20.035 1.548-28.245L244.813 376v-83.853l72.423 41.926 15.838 89.736c3.246 10.782 14.514 16.504 25.168 12.779 10.653-3.726 16.659-15.487 13.412-26.268l-20.805-56.787 66.574 38.54c9.54 5.523 21.933 1.908 27.68-8.074 5.749-9.981 2.675-22.55-6.866-28.072z"] }; +var faSquare = { prefix: 'far', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6 400H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h340c3.3 0 6 2.7 6 6v340c0 3.3-2.7 6-6 6z"] }; +var faStar = { prefix: 'far', iconName: 'star', icon: [576, 512, [], "f005", "M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z"] }; +var faStarHalf = { prefix: 'far', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 385.3l-124.3 65.4 23.7-138.4-100.6-98 139-20.2 62.2-126V0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6v-54.3z"] }; +var faStickyNote = { prefix: 'far', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M448 348.106V80c0-26.51-21.49-48-48-48H48C21.49 32 0 53.49 0 80v351.988c0 26.51 21.49 48 48 48h268.118a48 48 0 0 0 33.941-14.059l83.882-83.882A48 48 0 0 0 448 348.106zm-128 80v-76.118h76.118L320 428.106zM400 80v223.988H296c-13.255 0-24 10.745-24 24v104H48V80h352z"] }; +var faStopCircle = { prefix: 'far', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256zm296-80v160c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16z"] }; +var faSun = { prefix: 'far', iconName: 'sun', icon: [512, 512, [], "f185", "M220.116 487.936l-20.213-49.425a3.992 3.992 0 0 0-5.808-1.886l-45.404 28.104c-29.466 18.24-66.295-8.519-58.054-42.179l12.699-51.865a3.993 3.993 0 0 0-3.59-4.941l-53.251-3.951c-34.554-2.562-48.632-45.855-22.174-68.247L65.08 259.05a3.992 3.992 0 0 0 0-6.106l-40.76-34.497c-26.45-22.384-12.39-65.682 22.174-68.246l53.251-3.951a3.993 3.993 0 0 0 3.59-4.941L90.637 89.443c-8.239-33.656 28.581-60.42 58.054-42.179l45.403 28.104a3.993 3.993 0 0 0 5.808-1.887l20.213-49.425c13.116-32.071 58.638-32.081 71.758 0l20.212 49.424a3.994 3.994 0 0 0 5.809 1.887l45.403-28.104c29.464-18.236 66.297 8.513 58.054 42.179l-12.699 51.865a3.995 3.995 0 0 0 3.59 4.941l53.251 3.951c34.553 2.563 48.633 45.854 22.175 68.246l-40.76 34.497a3.993 3.993 0 0 0 0 6.107l40.76 34.496c26.511 22.441 12.322 65.689-22.175 68.247l-53.251 3.951a3.993 3.993 0 0 0-3.589 4.942l12.698 51.864c8.241 33.658-28.583 60.421-58.054 42.18l-45.403-28.104a3.994 3.994 0 0 0-5.809 1.887l-20.212 49.424c-13.159 32.178-58.675 31.993-71.757 0zm16.814-64.568l19.064 46.616 19.064-46.615c10.308-25.2 40.778-35.066 63.892-20.759l42.822 26.507-11.976-48.919c-6.475-26.444 12.38-52.339 39.487-54.349l50.226-3.726-38.444-32.536c-20.782-17.591-20.747-49.621.001-67.18l38.442-32.536-50.225-3.727c-27.151-2.015-45.95-27.948-39.488-54.349l11.978-48.919-42.823 26.507c-23.151 14.327-53.603 4.4-63.892-20.76l-19.064-46.615-19.064 46.617c-10.305 25.198-40.778 35.066-63.891 20.76l-42.823-26.508 11.977 48.918c6.474 26.446-12.381 52.338-39.488 54.35l-50.224 3.726 38.443 32.537c20.782 17.588 20.747 49.619 0 67.178L52.48 322.123l50.226 3.726c27.151 2.014 45.95 27.947 39.487 54.349l-11.977 48.919 42.823-26.507c23.188-14.355 53.622-4.352 63.891 20.758zM256 384c-70.58 0-128-57.421-128-128 0-70.58 57.42-128 128-128 70.579 0 128 57.42 128 128 0 70.579-57.421 128-128 128zm0-208c-44.112 0-80 35.888-80 80s35.888 80 80 80 80-35.888 80-80-35.888-80-80-80z"] }; +var faThumbsDown = { prefix: 'far', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M466.27 225.31c4.674-22.647.864-44.538-8.99-62.99 2.958-23.868-4.021-48.565-17.34-66.99C438.986 39.423 404.117 0 327 0c-7 0-15 .01-22.22.01C201.195.01 168.997 40 128 40h-10.845c-5.64-4.975-13.042-8-21.155-8H32C14.327 32 0 46.327 0 64v240c0 17.673 14.327 32 32 32h64c11.842 0 22.175-6.438 27.708-16h7.052c19.146 16.953 46.013 60.653 68.76 83.4 13.667 13.667 10.153 108.6 71.76 108.6 57.58 0 95.27-31.936 95.27-104.73 0-18.41-3.93-33.73-8.85-46.54h36.48c48.602 0 85.82-41.565 85.82-85.58 0-19.15-4.96-34.99-13.73-49.84zM64 296c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm330.18 16.73H290.19c0 37.82 28.36 55.37 28.36 94.54 0 23.75 0 56.73-47.27 56.73-18.91-18.91-9.46-66.18-37.82-94.54C206.9 342.89 167.28 272 138.92 272H128V85.83c53.611 0 100.001-37.82 171.64-37.82h37.82c35.512 0 60.82 17.12 53.12 65.9 15.2 8.16 26.5 36.44 13.94 57.57 21.581 20.384 18.699 51.065 5.21 65.62 9.45 0 22.36 18.91 22.27 37.81-.09 18.91-16.71 37.82-37.82 37.82z"] }; +var faThumbsUp = { prefix: 'far', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z"] }; +var faTimesCircle = { prefix: 'far', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm101.8-262.2L295.6 256l62.2 62.2c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L256 295.6l-62.2 62.2c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l62.2-62.2-62.2-62.2c-4.7-4.7-4.7-12.3 0-17l22.6-22.6c4.7-4.7 12.3-4.7 17 0l62.2 62.2 62.2-62.2c4.7-4.7 12.3-4.7 17 0l22.6 22.6c4.7 4.7 4.7 12.3 0 17z"] }; +var faTrashAlt = { prefix: 'far', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M192 188v216c0 6.627-5.373 12-12 12h-24c-6.627 0-12-5.373-12-12V188c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12zm100-12h-24c-6.627 0-12 5.373-12 12v216c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12V188c0-6.627-5.373-12-12-12zm132-96c13.255 0 24 10.745 24 24v12c0 6.627-5.373 12-12 12h-20v336c0 26.51-21.49 48-48 48H80c-26.51 0-48-21.49-48-48V128H12c-6.627 0-12-5.373-12-12v-12c0-13.255 10.745-24 24-24h74.411l34.018-56.696A48 48 0 0 1 173.589 0h100.823a48 48 0 0 1 41.16 23.304L349.589 80H424zm-269.611 0h139.223L276.16 50.913A6 6 0 0 0 271.015 48h-94.028a6 6 0 0 0-5.145 2.913L154.389 80zM368 128H80v330a6 6 0 0 0 6 6h276a6 6 0 0 0 6-6V128z"] }; +var faUser = { prefix: 'far', iconName: 'user', icon: [512, 512, [], "f007", "M399.326 288.908C422.188 258.886 436 221.085 436 180 436 80.591 355.414 0 256 0 156.591 0 76 80.586 76 180c0 41.073 13.806 78.878 36.674 108.908C50.028 296.336 0 349.651 0 416v28.5C0 481.72 30.28 512 67.5 512h377c37.22 0 67.5-30.28 67.5-67.5V416c0-66.374-50.052-119.667-112.674-127.092zM256 48c72.902 0 132 59.098 132 132s-59.098 132-132 132-132-59.098-132-132S183.098 48 256 48zm208 396.5c0 10.77-8.73 19.5-19.5 19.5h-377c-10.77 0-19.5-8.73-19.5-19.5V416c0-44.183 35.817-80 80-80h38.14c55.486 31.968 124.026 32.087 179.72 0H384c44.183 0 80 35.817 80 80v28.5z"] }; +var faUserCircle = { prefix: 'far', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 34.48-8.706 66.909-24.04 95.213-13.403-26.393-37.525-47.542-67.384-56.572C378.19 273.809 385.5 249.468 385.5 224c0-71.569-57.919-129.5-129.5-129.5-71.569 0-129.5 57.919-129.5 129.5 0 25.468 7.31 49.809 20.924 70.641-29.821 9.018-53.962 30.142-67.385 56.572C64.706 322.911 56 290.482 56 256c0-110.531 89.451-200 200-200zm-80 168c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-59.927 174.943c1.519-33.998 29.554-61.097 63.927-61.097h14.171c38.337 20.889 85.337 20.881 123.659 0H332c34.373 0 62.408 27.099 63.927 61.097-77.746 76.114-202.156 76.065-279.854 0z"] }; +var faWindowClose = { prefix: 'far', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V86c0-3.3 2.7-6 6-6h404c3.3 0 6 2.7 6 6v340zM356.5 194.6L295.1 256l61.4 61.4c4.6 4.6 4.6 12.1 0 16.8l-22.3 22.3c-4.6 4.6-12.1 4.6-16.8 0L256 295.1l-61.4 61.4c-4.6 4.6-12.1 4.6-16.8 0l-22.3-22.3c-4.6-4.6-4.6-12.1 0-16.8l61.4-61.4-61.4-61.4c-4.6-4.6-4.6-12.1 0-16.8l22.3-22.3c4.6-4.6 12.1-4.6 16.8 0l61.4 61.4 61.4-61.4c4.6-4.6 12.1-4.6 16.8 0l22.3 22.3c4.7 4.6 4.7 12.1 0 16.8z"] }; +var faWindowMaximize = { prefix: 'far', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm0 394c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V192h416v234z"] }; +var faWindowRestore = { prefix: 'far', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M464 0H144c-26.5 0-48 21.5-48 48v48H48c-26.5 0-48 21.5-48 48v320c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-96 464H48V256h320v208zm96-96h-48V144c0-26.5-21.5-48-48-48H144V48h320v320z"] }; +var icons$1 = { + faAddressBook: faAddressBook, + faAddressCard: faAddressCard, + faArrowAltCircleDown: faArrowAltCircleDown, + faArrowAltCircleLeft: faArrowAltCircleLeft, + faArrowAltCircleRight: faArrowAltCircleRight, + faArrowAltCircleUp: faArrowAltCircleUp, + faBell: faBell, + faBellSlash: faBellSlash, + faBookmark: faBookmark, + faBuilding: faBuilding, + faCalendar: faCalendar, + faCalendarAlt: faCalendarAlt, + faCalendarCheck: faCalendarCheck, + faCalendarMinus: faCalendarMinus, + faCalendarPlus: faCalendarPlus, + faCalendarTimes: faCalendarTimes, + faCaretSquareDown: faCaretSquareDown, + faCaretSquareLeft: faCaretSquareLeft, + faCaretSquareRight: faCaretSquareRight, + faCaretSquareUp: faCaretSquareUp, + faChartBar: faChartBar, + faCheckCircle: faCheckCircle, + faCheckSquare: faCheckSquare, + faCircle: faCircle, + faClipboard: faClipboard, + faClock: faClock, + faClone: faClone, + faClosedCaptioning: faClosedCaptioning, + faComment: faComment, + faCommentAlt: faCommentAlt, + faComments: faComments, + faCompass: faCompass, + faCopy: faCopy, + faCopyright: faCopyright, + faCreditCard: faCreditCard, + faDotCircle: faDotCircle, + faEdit: faEdit, + faEnvelope: faEnvelope, + faEnvelopeOpen: faEnvelopeOpen, + faEyeSlash: faEyeSlash, + faFile: faFile, + faFileAlt: faFileAlt, + faFileArchive: faFileArchive, + faFileAudio: faFileAudio, + faFileCode: faFileCode, + faFileExcel: faFileExcel, + faFileImage: faFileImage, + faFilePdf: faFilePdf, + faFilePowerpoint: faFilePowerpoint, + faFileVideo: faFileVideo, + faFileWord: faFileWord, + faFlag: faFlag, + faFolder: faFolder, + faFolderOpen: faFolderOpen, + faFrown: faFrown, + faFutbol: faFutbol, + faGem: faGem, + faHandLizard: faHandLizard, + faHandPaper: faHandPaper, + faHandPeace: faHandPeace, + faHandPointDown: faHandPointDown, + faHandPointLeft: faHandPointLeft, + faHandPointRight: faHandPointRight, + faHandPointUp: faHandPointUp, + faHandPointer: faHandPointer, + faHandRock: faHandRock, + faHandScissors: faHandScissors, + faHandSpock: faHandSpock, + faHandshake: faHandshake, + faHdd: faHdd, + faHeart: faHeart, + faHospital: faHospital, + faHourglass: faHourglass, + faIdBadge: faIdBadge, + faIdCard: faIdCard, + faImage: faImage, + faImages: faImages, + faKeyboard: faKeyboard, + faLemon: faLemon, + faLifeRing: faLifeRing, + faLightbulb: faLightbulb, + faListAlt: faListAlt, + faMap: faMap, + faMeh: faMeh, + faMinusSquare: faMinusSquare, + faMoneyBillAlt: faMoneyBillAlt, + faMoon: faMoon, + faNewspaper: faNewspaper, + faObjectGroup: faObjectGroup, + faObjectUngroup: faObjectUngroup, + faPaperPlane: faPaperPlane, + faPauseCircle: faPauseCircle, + faPlayCircle: faPlayCircle, + faPlusSquare: faPlusSquare, + faQuestionCircle: faQuestionCircle, + faRegistered: faRegistered, + faSave: faSave, + faShareSquare: faShareSquare, + faSmile: faSmile, + faSnowflake: faSnowflake, + faSquare: faSquare, + faStar: faStar, + faStarHalf: faStarHalf, + faStickyNote: faStickyNote, + faStopCircle: faStopCircle, + faSun: faSun, + faThumbsDown: faThumbsDown, + faThumbsUp: faThumbsUp, + faTimesCircle: faTimesCircle, + faTrashAlt: faTrashAlt, + faUser: faUser, + faUserCircle: faUserCircle, + faWindowClose: faWindowClose, + faWindowMaximize: faWindowMaximize, + faWindowRestore: faWindowRestore +}; + +exports['default'] = icons$1; +exports.prefix = prefix; +exports.faAddressBook = faAddressBook; +exports.faAddressCard = faAddressCard; +exports.faArrowAltCircleDown = faArrowAltCircleDown; +exports.faArrowAltCircleLeft = faArrowAltCircleLeft; +exports.faArrowAltCircleRight = faArrowAltCircleRight; +exports.faArrowAltCircleUp = faArrowAltCircleUp; +exports.faBell = faBell; +exports.faBellSlash = faBellSlash; +exports.faBookmark = faBookmark; +exports.faBuilding = faBuilding; +exports.faCalendar = faCalendar; +exports.faCalendarAlt = faCalendarAlt; +exports.faCalendarCheck = faCalendarCheck; +exports.faCalendarMinus = faCalendarMinus; +exports.faCalendarPlus = faCalendarPlus; +exports.faCalendarTimes = faCalendarTimes; +exports.faCaretSquareDown = faCaretSquareDown; +exports.faCaretSquareLeft = faCaretSquareLeft; +exports.faCaretSquareRight = faCaretSquareRight; +exports.faCaretSquareUp = faCaretSquareUp; +exports.faChartBar = faChartBar; +exports.faCheckCircle = faCheckCircle; +exports.faCheckSquare = faCheckSquare; +exports.faCircle = faCircle; +exports.faClipboard = faClipboard; +exports.faClock = faClock; +exports.faClone = faClone; +exports.faClosedCaptioning = faClosedCaptioning; +exports.faComment = faComment; +exports.faCommentAlt = faCommentAlt; +exports.faComments = faComments; +exports.faCompass = faCompass; +exports.faCopy = faCopy; +exports.faCopyright = faCopyright; +exports.faCreditCard = faCreditCard; +exports.faDotCircle = faDotCircle; +exports.faEdit = faEdit; +exports.faEnvelope = faEnvelope; +exports.faEnvelopeOpen = faEnvelopeOpen; +exports.faEyeSlash = faEyeSlash; +exports.faFile = faFile; +exports.faFileAlt = faFileAlt; +exports.faFileArchive = faFileArchive; +exports.faFileAudio = faFileAudio; +exports.faFileCode = faFileCode; +exports.faFileExcel = faFileExcel; +exports.faFileImage = faFileImage; +exports.faFilePdf = faFilePdf; +exports.faFilePowerpoint = faFilePowerpoint; +exports.faFileVideo = faFileVideo; +exports.faFileWord = faFileWord; +exports.faFlag = faFlag; +exports.faFolder = faFolder; +exports.faFolderOpen = faFolderOpen; +exports.faFrown = faFrown; +exports.faFutbol = faFutbol; +exports.faGem = faGem; +exports.faHandLizard = faHandLizard; +exports.faHandPaper = faHandPaper; +exports.faHandPeace = faHandPeace; +exports.faHandPointDown = faHandPointDown; +exports.faHandPointLeft = faHandPointLeft; +exports.faHandPointRight = faHandPointRight; +exports.faHandPointUp = faHandPointUp; +exports.faHandPointer = faHandPointer; +exports.faHandRock = faHandRock; +exports.faHandScissors = faHandScissors; +exports.faHandSpock = faHandSpock; +exports.faHandshake = faHandshake; +exports.faHdd = faHdd; +exports.faHeart = faHeart; +exports.faHospital = faHospital; +exports.faHourglass = faHourglass; +exports.faIdBadge = faIdBadge; +exports.faIdCard = faIdCard; +exports.faImage = faImage; +exports.faImages = faImages; +exports.faKeyboard = faKeyboard; +exports.faLemon = faLemon; +exports.faLifeRing = faLifeRing; +exports.faLightbulb = faLightbulb; +exports.faListAlt = faListAlt; +exports.faMap = faMap; +exports.faMeh = faMeh; +exports.faMinusSquare = faMinusSquare; +exports.faMoneyBillAlt = faMoneyBillAlt; +exports.faMoon = faMoon; +exports.faNewspaper = faNewspaper; +exports.faObjectGroup = faObjectGroup; +exports.faObjectUngroup = faObjectUngroup; +exports.faPaperPlane = faPaperPlane; +exports.faPauseCircle = faPauseCircle; +exports.faPlayCircle = faPlayCircle; +exports.faPlusSquare = faPlusSquare; +exports.faQuestionCircle = faQuestionCircle; +exports.faRegistered = faRegistered; +exports.faSave = faSave; +exports.faShareSquare = faShareSquare; +exports.faSmile = faSmile; +exports.faSnowflake = faSnowflake; +exports.faSquare = faSquare; +exports.faStar = faStar; +exports.faStarHalf = faStarHalf; +exports.faStickyNote = faStickyNote; +exports.faStopCircle = faStopCircle; +exports.faSun = faSun; +exports.faThumbsDown = faThumbsDown; +exports.faThumbsUp = faThumbsUp; +exports.faTimesCircle = faTimesCircle; +exports.faTrashAlt = faTrashAlt; +exports.faUser = faUser; +exports.faUserCircle = faUserCircle; +exports.faWindowClose = faWindowClose; +exports.faWindowMaximize = faWindowMaximize; +exports.faWindowRestore = faWindowRestore; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/package.json b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/package.json new file mode 100644 index 000000000..cf6366fd8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-regular/package.json @@ -0,0 +1,52 @@ +{ + "description": "The iconic font, CSS, and SVG framework", + "keywords": [ + "font", + "awesome", + "fontawesome", + "icon", + "svg", + "bootstrap" + ], + "homepage": "https://fontawesome.com", + "bugs": { + "url": "http://github.com/FortAwesome/Font-Awesome/issues" + }, + "author": { + "name": "Dave Gandy", + "email": "dave@fontawesome.com", + "web": "http://twitter.com/davegandy" + }, + "contributors": [ + { + "name": "Brian Talbot", + "web": "http://twitter.com/talbs" + }, + { + "name": "Travis Chase", + "web": "http://twitter.com/supercodepoet" + }, + { + "name": "Rob Madole", + "web": "http://twitter.com/robmadole" + }, + { + "name": "Geremia Taglialatela", + "web": "http://twitter.com/gtagliala" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome" + }, + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "version": "5.0.1", + "name": "@fortawesome/fontawesome-free-regular", + "main": "index.js", + "module": "index.es.js", + "jsnext:main": "index.es.js", + "license": "(CC-BY-4.0 AND MIT)" +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/LICENSE.txt b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressBook.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressBook.js new file mode 100644 index 000000000..42d358458 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressBook.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H80C53.49 0 32 21.49 32 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zM224 96c53.019 0 96 42.981 96 96s-42.981 96-96 96-96-42.981-96-96 42.981-96 96-96zm128 304c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48v-48.711c0-20.994 13.644-39.553 33.683-45.815l22.954-7.173C173.563 312.413 198.198 320 224 320s50.437-7.587 71.363-21.699l22.954 7.173C338.356 311.736 352 330.295 352 351.289V400z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressCard.js new file mode 100644 index 000000000..fadc26589 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAddressCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-288 64c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm112 232c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-29.897a24 24 0 0 1 17.407-23.077l28.938-8.268C129.323 312.549 152.087 320 176 320s46.677-7.451 65.656-21.241l28.938 8.268A23.999 23.999 0 0 1 288 330.103V360zm160-52c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAdjust.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAdjust.js new file mode 100644 index 000000000..f109731a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAdjust.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'adjust', icon: [512, 512, [], "f042", "M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignCenter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignCenter.js new file mode 100644 index 000000000..990df243a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignCenter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'align-center', icon: [448, 512, [], "f037", "M352 44v40c0 8.837-7.163 16-16 16H112c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h224c8.837 0 16 7.163 16 16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm320-200H112c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignJustify.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignJustify.js new file mode 100644 index 000000000..eaf69c156 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignJustify.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'align-justify', icon: [448, 512, [], "f039", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm16 144h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0-128h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignLeft.js new file mode 100644 index 000000000..1568d5884 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'align-left', icon: [448, 512, [], "f036", "M288 44v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16zM0 172v40c0 8.837 7.163 16 16 16h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16zm16 312h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm256-200H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignRight.js new file mode 100644 index 000000000..af841b93b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAlignRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'align-right', icon: [448, 512, [], "f038", "M160 84V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H176c-8.837 0-16-7.163-16-16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmbulance.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmbulance.js new file mode 100644 index 000000000..993438cbf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmbulance.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ambulance', icon: [640, 512, [], "f0f9", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm32-288v32c0 6.627-5.373 12-12 12h-56v56c0 6.627-5.373 12-12 12h-32c-6.627 0-12-5.373-12-12v-56h-56c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h56v-56c0-6.627 5.373-12 12-12h32c6.627 0 12 5.373 12 12v56h56c6.627 0 12 5.373 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmericanSignLanguageInterpreting.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmericanSignLanguageInterpreting.js new file mode 100644 index 000000000..8d183e502 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAmericanSignLanguageInterpreting.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'american-sign-language-interpreting', icon: [640, 512, [], "f2a3", "M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAnchor.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAnchor.js new file mode 100644 index 000000000..edb80bbd3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAnchor.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'anchor', icon: [576, 512, [], "f13d", "M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleDown.js new file mode 100644 index 000000000..c5bee5f45 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-double-down', icon: [320, 512, [], "f103", "M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleLeft.js new file mode 100644 index 000000000..9eac50068 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-double-left', icon: [448, 512, [], "f100", "M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleRight.js new file mode 100644 index 000000000..fb783ec00 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-double-right', icon: [448, 512, [], "f101", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleUp.js new file mode 100644 index 000000000..75820623f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDoubleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-double-up', icon: [320, 512, [], "f102", "M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDown.js new file mode 100644 index 000000000..8c6ef2c43 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-down', icon: [320, 512, [], "f107", "M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleLeft.js new file mode 100644 index 000000000..4f8a8da44 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-left', icon: [256, 512, [], "f104", "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleRight.js new file mode 100644 index 000000000..4c4468e03 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-right', icon: [256, 512, [], "f105", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleUp.js new file mode 100644 index 000000000..6f15c0019 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAngleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'angle-up', icon: [320, 512, [], "f106", "M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArchive.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArchive.js new file mode 100644 index 000000000..ad3cce09f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArchive.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'archive', icon: [512, 512, [], "f187", "M488 128H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h464c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24zm-8 328V184c0-13.255-10.745-24-24-24H56c-13.255 0-24 10.745-24 24v272c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24zM308 256H204c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleDown.js new file mode 100644 index 000000000..0b19066da --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleLeft.js new file mode 100644 index 000000000..1b848c355 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleRight.js new file mode 100644 index 000000000..302b5db27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleUp.js new file mode 100644 index 000000000..c74c14f38 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowAltCircleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleDown.js new file mode 100644 index 000000000..f80dcd40e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-circle-down', icon: [512, 512, [], "f0ab", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleLeft.js new file mode 100644 index 000000000..f4e242291 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-circle-left', icon: [512, 512, [], "f0a8", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleRight.js new file mode 100644 index 000000000..97dc2aec9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-circle-right', icon: [512, 512, [], "f0a9", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleUp.js new file mode 100644 index 000000000..c64eb12da --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowCircleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-circle-up', icon: [512, 512, [], "f0aa", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowDown.js new file mode 100644 index 000000000..872402f1d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-down', icon: [448, 512, [], "f063", "M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowLeft.js new file mode 100644 index 000000000..5ea0bdf62 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-left', icon: [448, 512, [], "f060", "M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowRight.js new file mode 100644 index 000000000..f1d8cfa4a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-right', icon: [448, 512, [], "f061", "M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowUp.js new file mode 100644 index 000000000..c0077ea35 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrow-up', icon: [448, 512, [], "f062", "M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAlt.js new file mode 100644 index 000000000..79ba5ec11 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrows-alt', icon: [512, 512, [], "f0b2", "M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltH.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltH.js new file mode 100644 index 000000000..f976c8b95 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltH.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrows-alt-h', icon: [512, 512, [], "f337", "M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltV.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltV.js new file mode 100644 index 000000000..7d73f73c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faArrowsAltV.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'arrows-alt-v', icon: [256, 512, [], "f338", "M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAssistiveListeningSystems.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAssistiveListeningSystems.js new file mode 100644 index 000000000..83188e2ab --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAssistiveListeningSystems.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'assistive-listening-systems', icon: [512, 512, [], "f2a2", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAsterisk.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAsterisk.js new file mode 100644 index 000000000..5482b2f8d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAsterisk.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'asterisk', icon: [512, 512, [], "f069", "M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAt.js new file mode 100644 index 000000000..276bfa79d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'at', icon: [512, 512, [], "f1fa", "M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAudioDescription.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAudioDescription.js new file mode 100644 index 000000000..21b5f8943 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faAudioDescription.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'audio-description', icon: [512, 512, [], "f29e", "M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBackward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBackward.js new file mode 100644 index 000000000..e1370d0cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBackward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'backward', icon: [512, 512, [], "f04a", "M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBalanceScale.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBalanceScale.js new file mode 100644 index 000000000..5c54375ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBalanceScale.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'balance-scale', icon: [640, 512, [], "f24e", "M352 448h168c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H120c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h168V153.324C264.469 143.04 246.836 121.778 241.603 96H120c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h135.999C270.594 12.57 293.828 0 320 0s49.406 12.57 64.001 32H520c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H398.397c-5.233 25.778-22.866 47.04-46.397 57.324V448zm287.981-112c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C381.94 328.75 384.019 320.331 384.019 336H384c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM512 176l72 144H440l72-144zM255.981 336c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C-2.06 328.75.019 320.331.019 336H0c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM128 176l72 144H56l72-144z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBan.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBan.js new file mode 100644 index 000000000..a137b0c29 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBan.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ban', icon: [512, 512, [], "f05e", "M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBarcode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBarcode.js new file mode 100644 index 000000000..c18758b54 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBarcode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'barcode', icon: [512, 512, [], "f02a", "M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBars.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBars.js new file mode 100644 index 000000000..273cba2ee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBars.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bars', icon: [448, 512, [], "f0c9", "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBath.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBath.js new file mode 100644 index 000000000..7fa610c83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBath.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bath', icon: [512, 512, [], "f2cd", "M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryEmpty.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryEmpty.js new file mode 100644 index 000000000..190e04bfe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryEmpty.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'battery-empty', icon: [640, 512, [], "f244", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryFull.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryFull.js new file mode 100644 index 000000000..762f5a6a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryFull.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'battery-full', icon: [640, 512, [], "f240", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryHalf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryHalf.js new file mode 100644 index 000000000..95d96cd8b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryHalf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'battery-half', icon: [640, 512, [], "f242", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryQuarter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryQuarter.js new file mode 100644 index 000000000..62e462bab --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryQuarter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'battery-quarter', icon: [640, 512, [], "f243", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryThreeQuarters.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryThreeQuarters.js new file mode 100644 index 000000000..18a9af5bc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBatteryThreeQuarters.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'battery-three-quarters', icon: [640, 512, [], "f241", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBed.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBed.js new file mode 100644 index 000000000..529db20bd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBed.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bed', icon: [576, 512, [], "f236", "M552 288c13.255 0 24 10.745 24 24v136h-96v-64H96v64H0V88c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v200h456zM192 96c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80zm384 128c0-53.019-42.981-96-96-96H312c-13.255 0-24 10.745-24 24v104h288v-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBeer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBeer.js new file mode 100644 index 000000000..015ad396f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBeer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'beer', icon: [448, 512, [], "f0fc", "M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBell.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBell.js new file mode 100644 index 000000000..693c938c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBell.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bell', icon: [448, 512, [], "f0f3", "M433.884 366.059C411.634 343.809 384 316.118 384 208c0-79.394-57.831-145.269-133.663-157.83A31.845 31.845 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 6.75 2.095 13.008 5.663 18.17C121.831 62.731 64 128.606 64 208c0 108.118-27.643 135.809-49.893 158.059C-16.042 396.208 5.325 448 48.048 448H160c0 35.346 28.654 64 64 64s64-28.654 64-64h111.943c42.638 0 64.151-51.731 33.941-81.941zM224 472a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16c0 13.234 10.766 24 24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBellSlash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBellSlash.js new file mode 100644 index 000000000..c2da40b51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBellSlash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M78.107 366.059C47.958 396.208 69.325 448 112.048 448H224c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h32.685L127.848 221.379c-2.198 97.078-28.439 123.378-49.741 144.68zM264 448c0 13.234 10.766 24 24 24a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16zm305.896 43.733l-10.762 12.086c-8.915 10.012-24.333 10.967-34.437 2.133L8.256 54.393C-1.848 45.558-2.811 30.28 6.104 20.267L16.865 8.181C25.781-1.831 41.199-2.786 51.303 6.049l113.81 99.512c24.017-28.778 57.946-48.996 96.55-55.39A31.85 31.85 0 0 1 256 32c0-17.673 14.327-32 32-32s32 14.327 32 32c0 6.75-2.095 13.008-5.663 18.17C390.169 62.731 448 128.606 448 208c0 108.118 27.634 135.809 49.884 158.059 12.149 12.149 15.923 27.776 13.33 42.121l56.53 49.427c10.104 8.835 11.067 24.113 2.152 34.126z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBicycle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBicycle.js new file mode 100644 index 000000000..74b880820 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBicycle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bicycle', icon: [640, 512, [], "f206", "M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBinoculars.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBinoculars.js new file mode 100644 index 000000000..f52976240 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBinoculars.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'binoculars', icon: [512, 512, [], "f1e5", "M192 104H96V56c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v48zm224-48c0-13.255-10.745-24-24-24h-48c-13.255 0-24 10.745-24 24v48h96V56zM0 456c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H0v16zm88-328c-13.255 0-24 10.745-24 24C64 256 0 272 0 416h168V312c0-13.255 10.745-24 24-24V128H88zm256 328c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H344v16zM216 128v160h80V128h-80zm128 288h168c0-144-64-160-64-264 0-13.255-10.745-24-24-24H320v160c13.255 0 24 10.745 24 24v104z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBirthdayCake.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBirthdayCake.js new file mode 100644 index 000000000..fd36b8917 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBirthdayCake.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'birthday-cake', icon: [448, 512, [], "f1fd", "M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBlind.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBlind.js new file mode 100644 index 000000000..d68f3e2fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBlind.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'blind', icon: [384, 512, [], "f29d", "M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBold.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBold.js new file mode 100644 index 000000000..a9cd4f648 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBold.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bold', icon: [384, 512, [], "f032", "M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBolt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBolt.js new file mode 100644 index 000000000..ca654afc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBolt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bolt', icon: [320, 512, [], "f0e7", "M295.973 160H180.572L215.19 30.184C219.25 14.956 207.756 0 192 0H56C43.971 0 33.8 8.905 32.211 20.828l-31.996 240C-1.704 275.217 9.504 288 24.004 288h118.701L96.646 482.466C93.05 497.649 104.659 512 119.992 512c8.35 0 16.376-4.374 20.778-11.978l175.973-303.997c9.244-15.967-2.288-36.025-20.77-36.025z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBomb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBomb.js new file mode 100644 index 000000000..6386c1586 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBomb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bomb', icon: [512, 512, [], "f1e2", "M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBook.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBook.js new file mode 100644 index 000000000..80df6a825 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBook.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'book', icon: [448, 512, [], "f02d", "M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBookmark.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBookmark.js new file mode 100644 index 000000000..b37ecca71 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBookmark.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBraille.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBraille.js new file mode 100644 index 000000000..f456a311a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBraille.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'braille', icon: [640, 512, [], "f2a1", "M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBriefcase.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBriefcase.js new file mode 100644 index 000000000..eed465b0c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBriefcase.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'briefcase', icon: [512, 512, [], "f0b1", "M320 288h192v144c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V288h192v20c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12v-20zm192-112v80H0v-80c0-26.51 21.49-48 48-48h80V80c0-26.51 21.49-48 48-48h160c26.51 0 48 21.49 48 48v48h80c26.51 0 48 21.49 48 48zM320 96H192v32h128V96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBug.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBug.js new file mode 100644 index 000000000..cca5b4370 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBug.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bug', icon: [512, 512, [], "f188", "M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBuilding.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBuilding.js new file mode 100644 index 000000000..3dca2e056 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBuilding.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'building', icon: [448, 512, [], "f1ad", "M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullhorn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullhorn.js new file mode 100644 index 000000000..8836f2afd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullhorn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bullhorn', icon: [576, 512, [], "f0a1", "M576 224c0-20.896-13.36-38.666-32-45.258V64c0-35.346-28.654-64-64-64-64.985 56-142.031 128-272 128H48c-26.51 0-48 21.49-48 48v96c0 26.51 21.49 48 48 48h43.263c-18.742 64.65 2.479 116.379 18.814 167.44 1.702 5.32 5.203 9.893 9.922 12.88 20.78 13.155 68.355 15.657 93.773 5.151 16.046-6.633 19.96-27.423 7.522-39.537-18.508-18.026-30.136-36.91-19.795-60.858a12.278 12.278 0 0 0-1.045-11.673c-16.309-24.679-3.581-62.107 28.517-72.752C346.403 327.887 418.591 395.081 480 448c35.346 0 64-28.654 64-64V269.258c18.64-6.592 32-24.362 32-45.258zm-96 139.855c-54.609-44.979-125.033-92.94-224-104.982v-69.747c98.967-12.042 169.391-60.002 224-104.982v279.711z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullseye.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullseye.js new file mode 100644 index 000000000..d904ed57b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBullseye.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bullseye', icon: [512, 512, [], "f140", "M256 72c101.689 0 184 82.295 184 184 0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-101.689 82.295-184 184-184m0-64C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 184c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64m0-64c-70.692 0-128 57.308-128 128s57.308 128 128 128 128-57.308 128-128-57.308-128-128-128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBus.js new file mode 100644 index 000000000..f9f586dc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faBus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'bus', icon: [512, 512, [], "f207", "M512 152v80c0 13.255-10.745 24-24 24h-8v168c0 13.255-10.745 24-24 24h-8v40c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24v-40H160v40c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-40h-8c-13.255 0-24-10.745-24-24V256h-8c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h8V80C32 35.817 132.288 0 256 0s224 35.817 224 80v48h8c13.255 0 24 10.745 24 24zM112 320c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm32-56V120c0-13.255-10.745-24-24-24H104c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalculator.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalculator.js new file mode 100644 index 000000000..25db31e73 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalculator.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calculator', icon: [448, 512, [], "f1ec", "M0 464V48C0 21.49 21.49 0 48 0h352c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm384-284V76c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v104c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12zM128 308v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm256 128V268c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-256 0v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm128-128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm0 128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendar.js new file mode 100644 index 000000000..a325d9437 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar', icon: [448, 512, [], "f133", "M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarAlt.js new file mode 100644 index 000000000..739d24613 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm116 204c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarCheck.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarCheck.js new file mode 100644 index 000000000..0e0b5c7fe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarCheck.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarMinus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarMinus.js new file mode 100644 index 000000000..3474901ab --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarMinus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarPlus.js new file mode 100644 index 000000000..b9a3f36c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarTimes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarTimes.js new file mode 100644 index 000000000..6afb4320f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCalendarTimes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCamera.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCamera.js new file mode 100644 index 000000000..04c01b168 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCamera.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'camera', icon: [512, 512, [], "f030", "M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCameraRetro.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCameraRetro.js new file mode 100644 index 000000000..867c2c0a7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCameraRetro.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'camera-retro', icon: [512, 512, [], "f083", "M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCar.js new file mode 100644 index 000000000..ffb2cb020 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'car', icon: [512, 512, [], "f1b9", "M499.991 168h-54.815l-7.854-20.944c-9.192-24.513-25.425-45.351-46.942-60.263S343.651 64 317.472 64H194.528c-26.18 0-51.391 7.882-72.908 22.793-21.518 14.912-37.75 35.75-46.942 60.263L66.824 168H12.009c-8.191 0-13.974 8.024-11.384 15.795l8 24A12 12 0 0 0 20.009 216h28.815l-.052.14C29.222 227.093 16 247.997 16 272v48c0 16.225 6.049 31.029 16 42.309V424c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-61.691c9.951-11.281 16-26.085 16-42.309v-48c0-24.003-13.222-44.907-32.772-55.86l-.052-.14h28.815a12 12 0 0 0 11.384-8.205l8-24c2.59-7.771-3.193-15.795-11.384-15.795zm-365.388 1.528C143.918 144.689 168 128 194.528 128h122.944c26.528 0 50.61 16.689 59.925 41.528L391.824 208H120.176l14.427-38.472zM88 328c-17.673 0-32-14.327-32-32 0-17.673 14.327-32 32-32s48 30.327 48 48-30.327 16-48 16zm336 0c-17.673 0-48 1.673-48-16 0-17.673 30.327-48 48-48s32 14.327 32 32c0 17.673-14.327 32-32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretDown.js new file mode 100644 index 000000000..b40c1ced8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-down', icon: [320, 512, [], "f0d7", "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretLeft.js new file mode 100644 index 000000000..6132a312e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-left', icon: [192, 512, [], "f0d9", "M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretRight.js new file mode 100644 index 000000000..1ffe0149b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-right', icon: [192, 512, [], "f0da", "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareDown.js new file mode 100644 index 000000000..6b93f0401 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareLeft.js new file mode 100644 index 000000000..c4392b1bd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareRight.js new file mode 100644 index 000000000..42a1cb556 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareUp.js new file mode 100644 index 000000000..687d2214f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretSquareUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretUp.js new file mode 100644 index 000000000..bfda4b46e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCaretUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'caret-up', icon: [320, 512, [], "f0d8", "M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartArrowDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartArrowDown.js new file mode 100644 index 000000000..a36ad3093 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartArrowDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cart-arrow-down', icon: [576, 512, [], "f218", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartPlus.js new file mode 100644 index 000000000..e6346ceee --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCartPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cart-plus', icon: [576, 512, [], "f217", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCertificate.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCertificate.js new file mode 100644 index 000000000..a7b398c87 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCertificate.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'certificate', icon: [512, 512, [], "f0a3", "M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartArea.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartArea.js new file mode 100644 index 000000000..cc85c00cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartArea.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chart-area', icon: [512, 512, [], "f1fe", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartBar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartBar.js new file mode 100644 index 000000000..e20b84c88 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartBar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zm-308-44v-72c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V204c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V108c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartLine.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartLine.js new file mode 100644 index 000000000..104ff54b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartLine.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chart-line', icon: [512, 512, [], "f201", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartPie.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartPie.js new file mode 100644 index 000000000..73e2a0ddd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChartPie.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chart-pie', icon: [576, 512, [], "f200", "M288 12.3V240h227.7c6.9 0 12.3-5.8 12-12.7-6.4-122.4-104.5-220.6-227-227-6.9-.3-12.7 5.1-12.7 12zM552.7 288c6.9 0 12.3 5.8 12 12.7-2.8 53.2-23.2 105.6-61.2 147.8-4.6 5.1-12.6 5.4-17.5.5L325 288h227.7zM401 433c4.8 4.8 4.7 12.8-.4 17.3-42.6 38.4-99 61.7-160.8 61.7C107.6 511.9-.2 403.8 0 271.5.2 143.4 100.8 38.9 227.3 32.3c6.9-.4 12.7 5.1 12.7 12V272l161 161z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheck.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheck.js new file mode 100644 index 000000000..3aa3e7abe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheck.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'check', icon: [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckCircle.js new file mode 100644 index 000000000..56c49fb26 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'check-circle', icon: [512, 512, [], "f058", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckSquare.js new file mode 100644 index 000000000..71be8a698 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCheckSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleDown.js new file mode 100644 index 000000000..d050959a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-circle-down', icon: [512, 512, [], "f13a", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleLeft.js new file mode 100644 index 000000000..a9bd1bbc5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-circle-left', icon: [512, 512, [], "f137", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleRight.js new file mode 100644 index 000000000..227ac1c1c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-circle-right', icon: [512, 512, [], "f138", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleUp.js new file mode 100644 index 000000000..b78c00a31 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronCircleUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-circle-up', icon: [512, 512, [], "f139", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronDown.js new file mode 100644 index 000000000..4a528bd6d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-down', icon: [448, 512, [], "f078", "M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronLeft.js new file mode 100644 index 000000000..45e5ee10d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-left', icon: [320, 512, [], "f053", "M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronRight.js new file mode 100644 index 000000000..9f4367642 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-right', icon: [320, 512, [], "f054", "M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronUp.js new file mode 100644 index 000000000..5796d6665 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChevronUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'chevron-up', icon: [448, 512, [], "f077", "M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChild.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChild.js new file mode 100644 index 000000000..bfb176acf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faChild.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'child', icon: [384, 512, [], "f1ae", "M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircle.js new file mode 100644 index 000000000..a683d0aac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircleNotch.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircleNotch.js new file mode 100644 index 000000000..dabfd2cbf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCircleNotch.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'circle-notch', icon: [512, 512, [], "f1ce", "M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClipboard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClipboard.js new file mode 100644 index 000000000..e3149cd80 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClipboard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'clipboard', icon: [384, 512, [], "f328", "M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClock.js new file mode 100644 index 000000000..70b5a561f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClone.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClone.js new file mode 100644 index 000000000..8aa8d724e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClone.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClosedCaptioning.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClosedCaptioning.js new file mode 100644 index 000000000..a1d106add --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faClosedCaptioning.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloud.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloud.js new file mode 100644 index 000000000..181a42e6f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloud.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cloud', icon: [640, 512, [], "f0c2", "M537.585 226.56C541.725 215.836 544 204.184 544 192c0-53.019-42.981-96-96-96-19.729 0-38.065 5.954-53.316 16.159C367.042 64.248 315.288 32 256 32c-88.366 0-160 71.634-160 160 0 2.728.07 5.439.204 8.133C40.171 219.845 0 273.227 0 336c0 79.529 64.471 144 144 144h368c70.692 0 128-57.308 128-128 0-61.93-43.983-113.586-102.415-125.44z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudDownloadAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudDownloadAlt.js new file mode 100644 index 000000000..588094dc8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudDownloadAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cloud-download-alt', icon: [640, 512, [], "f381", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-246.627-64H328V176c0-8.837-7.164-16-16-16h-48c-8.836 0-16 7.163-16 16v112h-65.373c-14.254 0-21.393 17.234-11.314 27.314l105.373 105.373c6.248 6.248 16.379 6.248 22.627 0l105.373-105.373c10.08-10.08 2.941-27.314-11.313-27.314z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudUploadAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudUploadAlt.js new file mode 100644 index 000000000..b9b2aa5ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCloudUploadAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cloud-upload-alt', icon: [640, 512, [], "f382", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-235.314-91.314L299.314 155.314c-6.248-6.248-16.379-6.248-22.627 0L171.314 260.686c-10.08 10.08-2.941 27.314 11.313 27.314H248v112c0 8.837 7.164 16 16 16h48c8.836 0 16-7.163 16-16V288h65.373c14.254 0 21.393-17.234 11.313-27.314z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCode.js new file mode 100644 index 000000000..d3ffc1f6d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'code', icon: [640, 512, [], "f121", "M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCodeBranch.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCodeBranch.js new file mode 100644 index 000000000..74e9ef473 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCodeBranch.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'code-branch', icon: [384, 512, [], "f126", "M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCoffee.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCoffee.js new file mode 100644 index 000000000..15a56e16c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCoffee.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'coffee', icon: [640, 512, [], "f0f4", "M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCog.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCog.js new file mode 100644 index 000000000..5c10a48d7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCog.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cog', icon: [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCogs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCogs.js new file mode 100644 index 000000000..6f906983e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCogs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cogs', icon: [640, 512, [], "f085", "M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faColumns.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faColumns.js new file mode 100644 index 000000000..b487618f3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faColumns.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'columns', icon: [512, 512, [], "f0db", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComment.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComment.js new file mode 100644 index 000000000..9325e34f4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComment.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'comment', icon: [576, 512, [], "f075", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCommentAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCommentAlt.js new file mode 100644 index 000000000..f7d78d2a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCommentAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208zm-416-48c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComments.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComments.js new file mode 100644 index 000000000..8cec2cad3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faComments.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'comments', icon: [576, 512, [], "f086", "M224 358.857c-37.599 0-73.027-6.763-104.143-18.7-31.375 24.549-69.869 39.508-110.764 43.796a8.632 8.632 0 0 1-.89.047c-3.736 0-7.111-2.498-8.017-6.061-.98-3.961 2.088-6.399 5.126-9.305 15.017-14.439 33.222-25.79 40.342-74.297C17.015 266.886 0 232.622 0 195.429 0 105.16 100.297 32 224 32s224 73.159 224 163.429c-.001 90.332-100.297 163.428-224 163.428zm347.067 107.174c-13.944-13.127-30.849-23.446-37.46-67.543 68.808-64.568 52.171-156.935-37.674-207.065.031 1.334.066 2.667.066 4.006 0 122.493-129.583 216.394-284.252 211.222 38.121 30.961 93.989 50.492 156.252 50.492 34.914 0 67.811-6.148 96.704-17 29.134 22.317 64.878 35.916 102.853 39.814 3.786.395 7.363-1.973 8.27-5.467.911-3.601-1.938-5.817-4.759-8.459z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompass.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompass.js new file mode 100644 index 000000000..43c428b8a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompass.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'compass', icon: [512, 512, [], "f14e", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM307.446 120.844l-102.642 97.779a23.997 23.997 0 0 0-6.772 11.729l-33.359 137.779c-5.68 23.459 22.777 39.318 39.88 23.024l102.64-97.779a23.99 23.99 0 0 0 6.772-11.729l33.359-137.779c5.618-23.198-22.591-39.493-39.878-23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompress.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompress.js new file mode 100644 index 000000000..1c86959dd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCompress.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'compress', icon: [448, 512, [], "f066", "M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopy.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopy.js new file mode 100644 index 000000000..f634d4fff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopy.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'copy', icon: [448, 512, [], "f0c5", "M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopyright.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopyright.js new file mode 100644 index 000000000..628c39f72 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCopyright.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCreditCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCreditCard.js new file mode 100644 index 000000000..3e999b8f7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCreditCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrop.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrop.js new file mode 100644 index 000000000..3214b281d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrop.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'crop', icon: [512, 512, [], "f125", "M488 352h-40V109.3l57-57c9.4-9.4 9.4-24.6 0-33.9L493.7 7c-9.4-9.4-24.6-9.4-33.9 0l-57 57H160V24c0-13.3-10.7-24-24-24H88C74.7 0 64 10.7 64 24v40H24C10.7 64 0 74.7 0 88v48c0 13.3 10.7 24 24 24h40v264c0 13.3 10.7 24 24 24h264v40c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24v-40h40c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zM306.7 160L160 306.7V160h146.7zM205.3 352L352 205.3V352H205.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrosshairs.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrosshairs.js new file mode 100644 index 000000000..3ceb6ae83 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCrosshairs.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'crosshairs', icon: [512, 512, [], "f05b", "M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCube.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCube.js new file mode 100644 index 000000000..c1567162d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCube.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cube', icon: [512, 512, [], "f1b2", "M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCubes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCubes.js new file mode 100644 index 000000000..9d4281fd0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCubes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cubes', icon: [512, 512, [], "f1b3", "M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCut.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCut.js new file mode 100644 index 000000000..b8775a405 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faCut.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'cut', icon: [448, 512, [], "f0c4", "M444.485 422.426c4.689 4.689 4.684 12.287 0 16.971-32.804 32.804-85.991 32.804-118.795 0L210.176 323.883l-24.859 24.859C189.63 359.657 192 371.552 192 384c0 53.019-42.981 96-96 96S0 437.019 0 384s42.981-96 96-96c4.536 0 8.995.322 13.363.93l32.93-32.93-32.93-32.93c-4.368.608-8.827.93-13.363.93-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96c0 12.448-2.37 24.343-6.682 35.258l24.859 24.859L325.69 72.603c32.804-32.804 85.991-32.804 118.795 0 4.684 4.684 4.689 12.282 0 16.971L278.059 256l166.426 166.426zM96 96c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m0 256c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m112-108c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDatabase.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDatabase.js new file mode 100644 index 000000000..0368ac4bb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDatabase.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'database', icon: [448, 512, [], "f1c0", "M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDeaf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDeaf.js new file mode 100644 index 000000000..31bf0acdf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDeaf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'deaf', icon: [512, 512, [], "f2a4", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDesktop.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDesktop.js new file mode 100644 index 000000000..893e8fb26 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDesktop.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'desktop', icon: [576, 512, [], "f108", "M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDollarSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDollarSign.js new file mode 100644 index 000000000..b697bb521 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDollarSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'dollar-sign', icon: [320, 512, [], "f155", "M113.411 169.375c0-23.337 21.536-38.417 54.865-38.417 26.726 0 54.116 12.263 76.461 28.333 5.88 4.229 14.13 2.354 17.575-4.017l23.552-43.549c2.649-4.898 1.596-10.991-2.575-14.68-24.281-21.477-59.135-34.09-91.289-37.806V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v49.832c-58.627 13.29-97.299 55.917-97.299 108.639 0 123.533 184.765 110.81 184.765 169.414 0 19.823-16.311 41.158-52.124 41.158-30.751 0-62.932-15.88-87.848-35.887-5.31-4.264-13.082-3.315-17.159 2.14l-30.389 40.667c-3.627 4.854-3.075 11.657 1.302 15.847 24.049 23.02 59.249 41.255 98.751 47.973V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-47.438c65.72-10.215 106.176-59.186 106.176-116.516.001-119.688-184.764-103.707-184.764-166.671z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDotCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDotCircle.js new file mode 100644 index 000000000..5789fcdf5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDotCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDownload.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDownload.js new file mode 100644 index 000000000..ae67480a6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faDownload.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'download', icon: [512, 512, [], "f019", "M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEdit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEdit.js new file mode 100644 index 000000000..690747e6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEdit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'edit', icon: [576, 512, [], "f044", "M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEject.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEject.js new file mode 100644 index 000000000..dd90048df --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEject.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'eject', icon: [448, 512, [], "f052", "M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisH.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisH.js new file mode 100644 index 000000000..ef1eed4b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisH.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ellipsis-h', icon: [512, 512, [], "f141", "M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisV.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisV.js new file mode 100644 index 000000000..19ad81bce --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEllipsisV.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ellipsis-v', icon: [192, 512, [], "f142", "M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelope.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelope.js new file mode 100644 index 000000000..a79c79caf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelope.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeOpen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeOpen.js new file mode 100644 index 000000000..5c11bf152 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeOpen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeSquare.js new file mode 100644 index 000000000..b4478fa30 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEnvelopeSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'envelope-square', icon: [448, 512, [], "f199", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEraser.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEraser.js new file mode 100644 index 000000000..c6e2573a5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEraser.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'eraser', icon: [512, 512, [], "f12d", "M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEuroSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEuroSign.js new file mode 100644 index 000000000..e2b867f0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEuroSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'euro-sign', icon: [320, 512, [], "f153", "M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExchangeAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExchangeAlt.js new file mode 100644 index 000000000..1b568b6fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExchangeAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'exchange-alt', icon: [512, 512, [], "f362", "M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamation.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamation.js new file mode 100644 index 000000000..7a01d27ec --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamation.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'exclamation', icon: [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationCircle.js new file mode 100644 index 000000000..b827d5e68 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'exclamation-circle', icon: [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationTriangle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationTriangle.js new file mode 100644 index 000000000..1bff4445c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExclamationTriangle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'exclamation-triangle', icon: [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpand.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpand.js new file mode 100644 index 000000000..d06f3e4ac --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpand.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'expand', icon: [448, 512, [], "f065", "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpandArrowsAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpandArrowsAlt.js new file mode 100644 index 000000000..da8fea767 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExpandArrowsAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'expand-arrows-alt', icon: [448, 512, [], "f31e", "M448.1 344v112c0 13.3-10.7 24-24 24h-112c-21.4 0-32.1-25.9-17-41l36.2-36.2L224 295.6 116.8 402.9 153 439c15.1 15.1 4.4 41-17 41H24c-13.3 0-24-10.7-24-24V344c0-21.4 25.9-32.1 41-17l36.2 36.2L184.5 256 77.2 148.7 41 185c-15.1 15.1-41 4.4-41-17V56c0-13.3 10.7-24 24-24h112c21.4 0 32.1 25.9 17 41l-36.2 36.2L224 216.4l107.3-107.3L295.1 73c-15.1-15.1-4.4-41 17-41h112c13.3 0 24 10.7 24 24v112c0 21.4-25.9 32.1-41 17l-36.2-36.2L263.6 256l107.3 107.3 36.2-36.2c15.1-15.2 41-4.5 41 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkAlt.js new file mode 100644 index 000000000..025943005 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'external-link-alt', icon: [576, 512, [], "f35d", "M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkSquareAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkSquareAlt.js new file mode 100644 index 000000000..039fc2d79 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faExternalLinkSquareAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'external-link-square-alt', icon: [448, 512, [], "f360", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEye.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEye.js new file mode 100644 index 000000000..4705e438b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEye.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'eye', icon: [576, 512, [], "f06e", "M569.354 231.631C512.969 135.949 407.81 72 288 72 168.14 72 63.004 135.994 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.031 376.051 168.19 440 288 440c119.86 0 224.996-63.994 281.354-159.631a47.997 47.997 0 0 0 0-48.738zM288 392c-75.162 0-136-60.827-136-136 0-75.162 60.826-136 136-136 75.162 0 136 60.826 136 136 0 75.162-60.826 136-136 136zm104-136c0 57.438-46.562 104-104 104s-104-46.562-104-104c0-17.708 4.431-34.379 12.236-48.973l-.001.032c0 23.651 19.173 42.823 42.824 42.823s42.824-19.173 42.824-42.823c0-23.651-19.173-42.824-42.824-42.824l-.032.001C253.621 156.431 270.292 152 288 152c57.438 0 104 46.562 104 104z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeDropper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeDropper.js new file mode 100644 index 000000000..c1b2ce56b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeDropper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'eye-dropper', icon: [512, 512, [], "f1fb", "M177.38 206.64L39.03 344.97A24.01 24.01 0 0 0 32 361.94V424L0 480l32 32 56-32h62.06c6.36 0 12.47-2.53 16.97-7.03l138.35-138.33-128-128zm225.552 30.47l16.952 16.95c9.37 9.37 9.37 24.57 0 33.94l-40.973 40.97c-9.292 9.312-24.506 9.434-33.94 0L183.028 167.03c-9.37-9.37-9.37-24.57 0-33.94L224 92.12c9.289-9.309 24.502-9.438 33.94 0l16.992 16.99 82.606-82.601c35.19-35.19 92.5-35.5 128 0 40.49 48.08 29.66 98.34 0 128l-82.606 82.601z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeSlash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeSlash.js new file mode 100644 index 000000000..1db5dcf44 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faEyeSlash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M286.693 391.984l32.579 46.542A333.958 333.958 0 0 1 288 440C168.19 440 63.031 376.051 6.646 280.369a47.999 47.999 0 0 1 0-48.739c24.023-40.766 56.913-75.775 96.024-102.537l57.077 81.539C154.736 224.82 152 240.087 152 256c0 74.736 60.135 135.282 134.693 135.984zm282.661-111.615c-31.667 53.737-78.747 97.46-135.175 125.475l.011.015 41.47 59.2c7.6 10.86 4.96 25.82-5.9 33.42l-13.11 9.18c-10.86 7.6-25.82 4.96-33.42-5.9L100.34 46.94c-7.6-10.86-4.96-25.82 5.9-33.42l13.11-9.18c10.86-7.6 25.82-4.96 33.42 5.9l51.038 72.617C230.68 75.776 258.905 72 288 72c119.81 0 224.969 63.949 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM424 256c0-75.174-60.838-136-136-136-17.939 0-35.056 3.473-50.729 9.772l19.299 27.058c25.869-8.171 55.044-6.163 80.4 7.41h-.03c-23.65 0-42.82 19.17-42.82 42.82 0 23.626 19.147 42.82 42.82 42.82 23.65 0 42.82-19.17 42.82-42.82v-.03c18.462 34.49 16.312 77.914-8.25 110.95v.01l19.314 27.061C411.496 321.2 424 290.074 424 256zM262.014 356.727l-77.53-110.757c-5.014 52.387 29.314 98.354 77.53 110.757z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastBackward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastBackward.js new file mode 100644 index 000000000..3cfc443da --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastBackward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fast-backward', icon: [512, 512, [], "f049", "M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastForward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastForward.js new file mode 100644 index 000000000..0c1028835 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFastForward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fast-forward', icon: [512, 512, [], "f050", "M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFax.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFax.js new file mode 100644 index 000000000..9097d79c9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFax.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fax', icon: [512, 512, [], "f1ac", "M128 144v320c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V144c0-26.51 21.49-48 48-48h32c26.51 0 48 21.49 48 48zm384 64v256c0 26.51-21.49 48-48 48H192c-26.51 0-48-21.49-48-48V40c0-22.091 17.909-40 40-40h207.432a39.996 39.996 0 0 1 28.284 11.716l48.569 48.569A39.999 39.999 0 0 1 480 88.568v74.174c18.641 6.591 32 24.36 32 45.258zm-320-16h240V96h-24c-13.203 0-24-10.797-24-24V48H192v144zm96 204c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm128 128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFemale.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFemale.js new file mode 100644 index 000000000..66ed9df90 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFemale.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'female', icon: [256, 512, [], "f182", "M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFighterJet.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFighterJet.js new file mode 100644 index 000000000..055e77072 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFighterJet.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fighter-jet', icon: [640, 512, [], "f0fb", "M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFile.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFile.js new file mode 100644 index 000000000..63953cbbe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFile.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file', icon: [384, 512, [], "f15b", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAlt.js new file mode 100644 index 000000000..5c22497f0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileArchive.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileArchive.js new file mode 100644 index 000000000..ab5fd489b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileArchive.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32V32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6zm32.7-53c0 14.9-14.5 27-32.4 27S96 378 96 363c0-14.9 14.5-27 32.4-27s32.5 12.1 32.5 27zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAudio.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAudio.js new file mode 100644 index 000000000..d33439b30 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileAudio.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileCode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileCode.js new file mode 100644 index 000000000..5be166663 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileCode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileExcel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileExcel.js new file mode 100644 index 000000000..cf75800a4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileExcel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileImage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileImage.js new file mode 100644 index 000000000..77d8fbb0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileImage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePdf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePdf.js new file mode 100644 index 000000000..b5d9cd4db --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePdf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePowerpoint.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePowerpoint.js new file mode 100644 index 000000000..6311de6f6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilePowerpoint.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileVideo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileVideo.js new file mode 100644 index 000000000..6695e2bf4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileVideo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileWord.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileWord.js new file mode 100644 index 000000000..190b55667 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFileWord.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilm.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilm.js new file mode 100644 index 000000000..4f5dfd8cf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilm.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'film', icon: [512, 512, [], "f008", "M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilter.js new file mode 100644 index 000000000..7f92fe446 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFilter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'filter', icon: [512, 512, [], "f0b0", "M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFire.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFire.js new file mode 100644 index 000000000..0517cbdfb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFire.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fire', icon: [384, 512, [], "f06d", "M216 23.858c0-23.802-30.653-32.765-44.149-13.038C48 191.851 224 200 224 288c0 35.629-29.114 64.458-64.85 63.994C123.98 351.538 96 322.22 96 287.046v-85.51c0-21.703-26.471-32.225-41.432-16.504C27.801 213.158 0 261.332 0 320c0 105.869 86.131 192 192 192s192-86.131 192-192c0-170.29-168-193.003-168-296.142z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFireExtinguisher.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFireExtinguisher.js new file mode 100644 index 000000000..dbc985c33 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFireExtinguisher.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'fire-extinguisher', icon: [448, 512, [], "f134", "M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlag.js new file mode 100644 index 000000000..87fa2a398 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'flag', icon: [512, 512, [], "f024", "M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlagCheckered.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlagCheckered.js new file mode 100644 index 000000000..c48cead07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlagCheckered.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'flag-checkered', icon: [512, 512, [], "f11e", "M466.515 66.928C487.731 57.074 512 72.551 512 95.944v243.1c0 10.526-5.161 20.407-13.843 26.358-35.837 24.564-74.335 40.858-122.505 40.858-67.373 0-111.63-34.783-165.217-34.783-50.853 0-86.124 10.058-114.435 22.122V488c0 13.255-10.745 24-24 24H56c-13.255 0-24-10.745-24-24V101.945C17.497 91.825 8 75.026 8 56 8 24.296 34.345-1.254 66.338.048c28.468 1.158 51.779 23.968 53.551 52.404.52 8.342-.81 16.31-3.586 23.562C137.039 68.384 159.393 64 184.348 64c67.373 0 111.63 34.783 165.217 34.783 40.496 0 82.612-15.906 116.95-31.855zM96 134.63v70.49c29-10.67 51.18-17.83 73.6-20.91v-71.57c-23.5 2.17-40.44 9.79-73.6 21.99zm220.8 9.19c-26.417-4.672-49.886-13.979-73.6-21.34v67.42c24.175 6.706 47.566 16.444 73.6 22.31v-68.39zm-147.2 40.39v70.04c32.796-2.978 53.91-.635 73.6 3.8V189.9c-25.247-7.035-46.581-9.423-73.6-5.69zm73.6 142.23c26.338 4.652 49.732 13.927 73.6 21.34v-67.41c-24.277-6.746-47.54-16.45-73.6-22.32v68.39zM96 342.1c23.62-8.39 47.79-13.84 73.6-16.56v-71.29c-26.11 2.35-47.36 8.04-73.6 17.36v70.49zm368-221.6c-21.3 8.85-46.59 17.64-73.6 22.47v71.91c27.31-4.36 50.03-14.1 73.6-23.89V120.5zm0 209.96v-70.49c-22.19 14.2-48.78 22.61-73.6 26.02v71.58c25.07-2.38 48.49-11.04 73.6-27.11zM316.8 212.21v68.16c25.664 7.134 46.616 9.342 73.6 5.62v-71.11c-25.999 4.187-49.943 2.676-73.6-2.67z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlask.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlask.js new file mode 100644 index 000000000..5154991e7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFlask.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'flask', icon: [448, 512, [], "f0c3", "M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolder.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolder.js new file mode 100644 index 000000000..35090695f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolder.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolderOpen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolderOpen.js new file mode 100644 index 000000000..41510432f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFolderOpen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFont.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFont.js new file mode 100644 index 000000000..f81caa8bf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFont.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'font', icon: [448, 512, [], "f031", "M152 416h-24.013l26.586-80.782H292.8L319.386 416H296c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-26.739L275.495 42.746A16 16 0 0 0 260.382 32h-72.766a16 16 0 0 0-15.113 10.746L42.739 416H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm64.353-271.778c4.348-15.216 6.61-28.156 7.586-34.644.839 6.521 2.939 19.476 7.727 34.706l41.335 124.006h-98.619l41.971-124.068z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faForward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faForward.js new file mode 100644 index 000000000..df9185243 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faForward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'forward', icon: [512, 512, [], "f04e", "M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFrown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFrown.js new file mode 100644 index 000000000..eeef85df2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFrown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'frown', icon: [512, 512, [], "f119", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm192.551 212.66c-59.128-91.455-165.846-91.594-225.064 0-11.502 17.79 15.383 35.148 26.873 17.374 46.626-72.118 124.862-71.855 171.318 0 11.328 17.524 38.548.684 26.873-17.374z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFutbol.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFutbol.js new file mode 100644 index 000000000..9327516be --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faFutbol.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGamepad.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGamepad.js new file mode 100644 index 000000000..3bba5cf92 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGamepad.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'gamepad', icon: [640, 512, [], "f11b", "M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGavel.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGavel.js new file mode 100644 index 000000000..a071fd2e1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGavel.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'gavel', icon: [512, 512, [], "f0e3", "M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGem.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGem.js new file mode 100644 index 000000000..634c09d99 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGem.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'gem', icon: [576, 512, [], "f3a5", "M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGenderless.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGenderless.js new file mode 100644 index 000000000..dfce16b91 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGenderless.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'genderless', icon: [288, 512, [], "f22d", "M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGift.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGift.js new file mode 100644 index 000000000..ec52660c0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGift.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'gift', icon: [512, 512, [], "f06b", "M488 192h-64.512C438.72 175.003 448 152.566 448 128c0-52.935-43.065-96-96-96-41.997 0-68.742 20.693-95.992 54.15C226.671 50.192 199.613 32 160 32c-52.935 0-96 43.065-96 96 0 24.566 9.28 47.003 24.512 64H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h8v112c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V320h8c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zm-208-32c24-56 55.324-64 72-64 17.645 0 32 14.355 32 32s-14.355 32-32 32h-72zM160 96c16.676 0 48 8 72 64h-72c-17.645 0-32-14.355-32-32s14.355-32 32-32zm48 128h96v184c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V224z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlassMartini.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlassMartini.js new file mode 100644 index 000000000..e5b5c9793 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlassMartini.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'glass-martini', icon: [512, 512, [], "f000", "M507.3 27.3c10-10 2.9-27.3-11.3-27.3H16C1.8 0-5.4 17.2 4.7 27.3L216 238.6V472h-92c-15.5 0-28 12.5-28 28 0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12 0-15.5-12.5-28-28-28h-92V238.6L507.3 27.3z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlobe.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlobe.js new file mode 100644 index 000000000..acac4aa6b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGlobe.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'globe', icon: [512, 512, [], "f0ac", "M364.215 192h131.43c5.439 20.419 8.354 41.868 8.354 64s-2.915 43.581-8.354 64h-131.43c5.154-43.049 4.939-86.746 0-128zM185.214 352c10.678 53.68 33.173 112.514 70.125 151.992.221.001.44.008.661.008s.44-.008.661-.008c37.012-39.543 59.467-98.414 70.125-151.992H185.214zm174.13-192h125.385C452.802 84.024 384.128 27.305 300.95 12.075c30.238 43.12 48.821 96.332 58.394 147.925zm-27.35 32H180.006c-5.339 41.914-5.345 86.037 0 128h151.989c5.339-41.915 5.345-86.037-.001-128zM152.656 352H27.271c31.926 75.976 100.6 132.695 183.778 147.925-30.246-43.136-48.823-96.35-58.393-147.925zm206.688 0c-9.575 51.605-28.163 104.814-58.394 147.925 83.178-15.23 151.852-71.949 183.778-147.925H359.344zm-32.558-192c-10.678-53.68-33.174-112.514-70.125-151.992-.221 0-.44-.008-.661-.008s-.44.008-.661.008C218.327 47.551 195.872 106.422 185.214 160h141.572zM16.355 192C10.915 212.419 8 233.868 8 256s2.915 43.581 8.355 64h131.43c-4.939-41.254-5.154-84.951 0-128H16.355zm136.301-32c9.575-51.602 28.161-104.81 58.394-147.925C127.872 27.305 59.198 84.024 27.271 160h125.385z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGraduationCap.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGraduationCap.js new file mode 100644 index 000000000..ce1dc63b2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faGraduationCap.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'graduation-cap', icon: [640, 512, [], "f19d", "M622.884 199.005l-275.817 85.1a96 96 0 0 1-54.134 0L92.398 222.232c-8.564 11.438-11.018 23.05-11.918 38.335C89.778 266.165 96 276.355 96 288c0 11.952-6.557 22.366-16.265 27.861l16.197 123.096c.63 4.786-3.1 9.043-7.932 9.043H40c-4.828 0-8.562-4.253-7.932-9.044L48.265 315.86C38.557 310.366 32 299.952 32 288c0-12.034 6.646-22.511 16.465-27.976.947-17.951 3.974-33.231 12.152-47.597l-43.502-13.422c-22.876-6.801-22.766-39.241 0-46.01l275.817-85.1a96 96 0 0 1 54.134 0l275.817 85.1c22.877 6.801 22.767 39.241.001 46.01zM356.503 314.682l-.207.064-.207.061a127.998 127.998 0 0 1-72.177 0l-.207-.061-.207-.064-150.914-46.57L120 352c0 35.346 89.543 64 200 64s200-28.654 200-64l-12.583-83.888-150.914 46.57z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHSquare.js new file mode 100644 index 000000000..cb9c9fd55 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'h-square', icon: [448, 512, [], "f0fd", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandLizard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandLizard.js new file mode 100644 index 000000000..75629d5c3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandLizard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPaper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPaper.js new file mode 100644 index 000000000..cf9052532 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPaper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPeace.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPeace.js new file mode 100644 index 000000000..2a9c32ed1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPeace.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointDown.js new file mode 100644 index 000000000..dcc7a83fd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-point-down', icon: [384, 512, [], "f0a7", "M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointLeft.js new file mode 100644 index 000000000..359a6ce44 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointRight.js new file mode 100644 index 000000000..80097060d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointUp.js new file mode 100644 index 000000000..69f6beca8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-point-up', icon: [384, 512, [], "f0a6", "M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointer.js new file mode 100644 index 000000000..f4aea6e9b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandPointer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandRock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandRock.js new file mode 100644 index 000000000..05533f44e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandRock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M512 128.79c0-26.322-20.861-48.344-47.18-48.783C437.935 79.558 416 101.217 416 128h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C333.935 47.558 312 69.217 312 96v32h-8V80.79c0-26.322-20.861-48.344-47.18-48.783C229.935 31.558 208 53.217 208 80v48h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C125.935 47.558 104 69.217 104 96v136l-8-7.111V176.79c0-26.322-20.861-48.344-47.18-48.783C21.935 127.558 0 149.217 0 176v66.445a95.998 95.998 0 0 0 32.221 71.751l111.668 99.261A47.999 47.999 0 0 1 160 449.333V456c0 13.255 10.745 24 24 24h240c13.255 0 24-10.745 24-24v-2.921a96.01 96.01 0 0 1 7.523-37.254l48.954-116.265A96.002 96.002 0 0 0 512 262.306V128.79z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandScissors.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandScissors.js new file mode 100644 index 000000000..5186ac6e4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandScissors.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandSpock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandSpock.js new file mode 100644 index 000000000..614c4d1d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandSpock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M10.872 316.585c15.139-16.086 40.454-16.854 56.543-1.713L128 371.893v-79.405L88.995 120.865c-4.896-21.542 8.598-42.974 30.14-47.87 21.549-4.894 42.975 8.599 47.87 30.141L201.747 256h9.833L164.016 48.966c-4.946-21.531 8.498-42.994 30.028-47.94 21.532-4.95 42.994 8.498 47.94 30.028L293.664 256h15.105l48.425-193.702c5.357-21.432 27.075-34.462 48.507-29.104 21.432 5.358 34.463 27.075 29.104 48.507L391.231 256h11.08l30.768-129.265c5.117-21.491 26.685-34.768 48.177-29.647 21.491 5.117 34.765 26.686 29.647 48.177l-36.292 152.467A96.024 96.024 0 0 0 472 319.967v42.102a96.002 96.002 0 0 1-3.96 27.287l-26.174 88.287C435.825 498.022 417.101 512 395.846 512H179.172a48.002 48.002 0 0 1-32.898-13.046L12.585 373.128c-16.087-15.141-16.853-40.456-1.713-56.543z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandshake.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandshake.js new file mode 100644 index 000000000..ef5a7ccdb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHandshake.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M72 112H24c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zM48 340c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zm568-228h-48c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zm-24 228c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zM485.94 92.67L528 140.74V320h-19.17c.56-14.96-4.38-28.98-14-39.71l-80.92-98.91c2.93-3.2 2.76-8.16-.38-11.16-2.82-2.7-7.08-2.92-10.14-.76-.42.3-60.35 62.93-60.35 62.93l-.2.21c-23.904 26.905-66.127 26.204-89.15-1.42-15.48-18.58-15.29-45.39.45-63.76l66.57-77.67C334.304 73.88 354.534 64 376.7 64h46.05a83.98 83.98 0 0 1 63.19 28.67zm-3.37 197.92c15.46 16.78 12.59 43.83-2.37 57.75-17.711 16.462-42.433 13.004-45.93 9.2 1.653 15.658-21.389 47.249-56.42 44.68-6.325 21.185-32.298 38.909-59.18 29.61-10.22 10.21-25.82 14.97-39.81 14.97-28.69 0-54.92-11.99-72.58-30.8L112 320V135.52l61.36-50.57A71.52 71.52 0 0 1 223.93 64h37.42c16.73 0 32.68 6.84 44.21 18.85l-63.57 74.16c-20.84 24.31-21.09 59.81-.59 84.42 29.375 35.247 83.007 35.853 113.31 1.92L402.82 193l79.75 97.59z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHashtag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHashtag.js new file mode 100644 index 000000000..fddaaeb51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHashtag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hashtag', icon: [448, 512, [], "f292", "M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHdd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHdd.js new file mode 100644 index 000000000..c797ac378 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHdd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeading.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeading.js new file mode 100644 index 000000000..98963eec1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeading.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'heading', icon: [512, 512, [], "f1dc", "M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeadphones.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeadphones.js new file mode 100644 index 000000000..ffc268b85 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeadphones.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'headphones', icon: [512, 512, [], "f025", "M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeart.js new file mode 100644 index 000000000..e1940fe13 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'heart', icon: [576, 512, [], "f004", "M414.9 24C361.8 24 312 65.7 288 89.3 264 65.7 214.2 24 161.1 24 70.3 24 16 76.9 16 165.5c0 72.6 66.8 133.3 69.2 135.4l187 180.8c8.8 8.5 22.8 8.5 31.6 0l186.7-180.2c2.7-2.7 69.5-63.5 69.5-136C560 76.9 505.7 24 414.9 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeartbeat.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeartbeat.js new file mode 100644 index 000000000..730edfce9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHeartbeat.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'heartbeat', icon: [576, 512, [], "f21e", "M47.9 257C31.6 232.7 16 200.5 16 165.5 16 76.9 70.3 24 161.1 24 214.2 24 264 65.7 288 89.3 312 65.7 361.8 24 414.9 24 505.7 24 560 76.9 560 165.5c0 35-15.5 67.2-31.9 91.5H408l-26.4-58.6c-4.7-8.9-17.6-8.5-21.6.7l-53.3 134.6L235.4 120c-3.7-10.6-18.7-10.7-22.6-.2l-48 137.2H47.9zm348 32c-4.5 0-8.6-2.5-10.6-6.4l-12.8-32.5-56.9 142.8c-4.4 9.9-18.7 9.4-22.3-.9l-69.7-209.2-33.6 98.4c-1.7 4.7-6.2 7.8-11.2 7.8H73.4c5.3 5.7-12.8-12 198.9 192.6 8.8 8.5 22.8 8.5 31.6 0 204.3-197.2 191-184 199-192.6h-107z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHistory.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHistory.js new file mode 100644 index 000000000..2d7acea41 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHistory.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'history', icon: [512, 512, [], "f1da", "M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHome.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHome.js new file mode 100644 index 000000000..afbd4d6b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHome.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'home', icon: [576, 512, [], "f015", "M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHospital.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHospital.js new file mode 100644 index 000000000..a500e6da1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHospital.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglass.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglass.js new file mode 100644 index 000000000..f56b3930b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglass.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hourglass', icon: [384, 512, [], "f254", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassEnd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassEnd.js new file mode 100644 index 000000000..1b03d3935 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassEnd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hourglass-end', icon: [384, 512, [], "f253", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassHalf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassHalf.js new file mode 100644 index 000000000..e74a86350 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassHalf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hourglass-half', icon: [384, 512, [], "f252", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassStart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassStart.js new file mode 100644 index 000000000..832fcc090 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faHourglassStart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'hourglass-start', icon: [384, 512, [], "f251", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faICursor.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faICursor.js new file mode 100644 index 000000000..18766ab6f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faICursor.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'i-cursor', icon: [256, 512, [], "f246", "M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdBadge.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdBadge.js new file mode 100644 index 000000000..a41caae03 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdBadge.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M0 464V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm192-144c53.019 0 96-42.981 96-96s-42.981-96-96-96-96 42.981-96 96 42.981 96 96 96zm94.317 17.474l-22.954-7.173C242.437 344.413 217.802 352 192 352s-50.437-7.587-71.363-21.699l-22.954 7.173C77.644 343.736 64 362.295 64 383.289V424c0 13.255 10.745 24 24 24h208c13.255 0 24-10.745 24-24v-40.711c0-20.994-13.644-39.553-33.683-45.815zM352 52v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdCard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdCard.js new file mode 100644 index 000000000..dfaa1c5ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIdCard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM160 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64m79.589 154.53l-28.281-9.427C196.458 314.532 178.856 320 160 320s-36.458-5.468-51.309-14.897L80.41 314.53A24 24 0 0 0 64 337.298V360c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-22.702a24 24 0 0 0-16.411-22.768zM448 340v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm32-96v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h424c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImage.js new file mode 100644 index 000000000..4ac0b781e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'image', icon: [512, 512, [], "f03e", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImages.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImages.js new file mode 100644 index 000000000..96d60ad81 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faImages.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInbox.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInbox.js new file mode 100644 index 000000000..bf9ee7d52 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInbox.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'inbox', icon: [576, 512, [], "f01c", "M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndent.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndent.js new file mode 100644 index 000000000..3a290526f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndent.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'indent', icon: [448, 512, [], "f03c", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm176 144h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm-52.687-111.313l-96-95.984C17.266 138.652 0 145.776 0 160.016v191.975c0 14.329 17.325 21.304 27.313 11.313l96-95.992c6.249-6.247 6.249-16.377 0-22.625z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndustry.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndustry.js new file mode 100644 index 000000000..0a0384fc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faIndustry.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'industry', icon: [512, 512, [], "f275", "M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfo.js new file mode 100644 index 000000000..b200b1da8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'info', icon: [192, 512, [], "f129", "M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfoCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfoCircle.js new file mode 100644 index 000000000..1f1963883 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faInfoCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'info-circle', icon: [512, 512, [], "f05a", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faItalic.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faItalic.js new file mode 100644 index 000000000..6882ad511 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faItalic.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'italic', icon: [320, 512, [], "f033", "M204.758 416h-33.849l62.092-320h40.725a16 16 0 0 0 15.704-12.937l6.242-32C297.599 41.184 290.034 32 279.968 32H120.235a16 16 0 0 0-15.704 12.937l-6.242 32C96.362 86.816 103.927 96 113.993 96h33.846l-62.09 320H46.278a16 16 0 0 0-15.704 12.935l-6.245 32C22.402 470.815 29.967 480 40.034 480h158.479a16 16 0 0 0 15.704-12.935l6.245-32c1.927-9.88-5.638-19.065-15.704-19.065z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKey.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKey.js new file mode 100644 index 000000000..40a8ffccb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKey.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'key', icon: [512, 512, [], "f084", "M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKeyboard.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKeyboard.js new file mode 100644 index 000000000..eb9c1ce9e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faKeyboard.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLanguage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLanguage.js new file mode 100644 index 000000000..169cf5ece --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLanguage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'language', icon: [640, 512, [], "f1ab", "M304 416H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h280v320zm-120.676-72.622A12 12 0 0 0 194.839 352h22.863c8.22 0 14.007-8.078 11.362-15.861L171.61 167.085a12 12 0 0 0-11.362-8.139h-32.489a12.001 12.001 0 0 0-11.362 8.139L58.942 336.139C56.297 343.922 62.084 352 70.304 352h22.805a12 12 0 0 0 11.535-8.693l9.118-31.807h60.211l9.351 31.878zm-39.051-140.42s4.32 21.061 7.83 33.21l10.8 37.531h-38.07l11.07-37.531c3.51-12.15 7.83-33.21 7.83-33.21h.54zM616 416H336V96h280c13.255 0 24 10.745 24 24v272c0 13.255-10.745 24-24 24zm-36-228h-64v-16c0-6.627-5.373-12-12-12h-16c-6.627 0-12 5.373-12 12v16h-64c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h114.106c-6.263 14.299-16.518 28.972-30.023 43.206-6.56-6.898-12.397-13.91-17.365-20.933-3.639-5.144-10.585-6.675-15.995-3.446l-7.28 4.346-6.498 3.879c-5.956 3.556-7.693 11.421-3.735 17.117 6.065 8.729 13.098 17.336 20.984 25.726-8.122 6.226-16.841 12.244-26.103 17.964-5.521 3.41-7.381 10.556-4.162 16.19l7.941 13.896c3.362 5.883 10.935 7.826 16.706 4.276 12.732-7.831 24.571-16.175 35.443-24.891 10.917 8.761 22.766 17.102 35.396 24.881 5.774 3.556 13.353 1.618 16.717-4.27l7.944-13.903c3.213-5.623 1.37-12.76-4.135-16.171a312.737 312.737 0 0 1-26.06-18.019c21.024-22.425 35.768-46.289 42.713-69.85H580c6.627 0 12-5.373 12-12v-16c0-6.625-5.373-11.998-12-11.998z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLaptop.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLaptop.js new file mode 100644 index 000000000..5dac5f411 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLaptop.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'laptop', icon: [640, 512, [], "f109", "M512 64v256H128V64h384m16-64H112C85.5 0 64 21.5 64 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm100 416H389.5c-3 0-5.5 2.1-5.9 5.1C381.2 436.3 368 448 352 448h-64c-16 0-29.2-11.7-31.6-26.9-.5-2.9-3-5.1-5.9-5.1H12c-6.6 0-12 5.4-12 12v36c0 26.5 21.5 48 48 48h544c26.5 0 48-21.5 48-48v-36c0-6.6-5.4-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLeaf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLeaf.js new file mode 100644 index 000000000..355cfa3ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLeaf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'leaf', icon: [576, 512, [], "f06c", "M395.4 420.8c-43.4 21.6-91.9 34.4-140.8 34.4-82.2 0-151.1-40.1-151.1-40.1-16.1 0-35.4 64.9-63.3 64.9-27 0-40.2-24-40.2-38.5 0-33.1 63.6-58.9 63.6-77.3 0 0-12.5-21.2-12.5-59.2 0-101.2 81.3-173.4 172.6-203.3 65.9-21.6 206 3.5 250.7-38.5C492.1 47 500.8 32 527.8 32c36.3 0 48.2 93.2 48.2 120.3 0 110.9-54.5 206.5-180.6 268.5zm-254.3-75.6c63.5-89.9 144.5-128.8 257.7-120 8.8.7 16.5-5.9 17.2-14.7.7-8.8-5.9-16.5-14.7-17.2-124-9.6-215.9 33.9-286.3 133.5-5.1 7.2-3.4 17.2 3.8 22.3 7.2 5.1 17.2 3.4 22.3-3.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLemon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLemon.js new file mode 100644 index 000000000..48c772b66 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLemon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'lemon', icon: [512, 512, [], "f094", "M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelDownAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelDownAlt.js new file mode 100644 index 000000000..c3906686b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelDownAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'level-down-alt', icon: [320, 512, [], "f3be", "M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelUpAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelUpAlt.js new file mode 100644 index 000000000..63955ec6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLevelUpAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'level-up-alt', icon: [320, 512, [], "f3bf", "M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLifeRing.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLifeRing.js new file mode 100644 index 000000000..b315ba552 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLifeRing.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLightbulb.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLightbulb.js new file mode 100644 index 000000000..a3708ed41 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLightbulb.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zm-143.107-44c-9.907 0-18.826-6.078-22.376-15.327C67.697 267.541 16 277.731 16 176 16 78.803 94.805 0 192 0s176 78.803 176 176c0 101.731-51.697 91.541-90.516 192.673-3.55 9.249-12.47 15.327-22.376 15.327H128.893zM112 176c0-44.112 35.888-80 80-80 8.837 0 16-7.164 16-16s-7.163-16-16-16c-61.757 0-112 50.243-112 112 0 8.836 7.164 16 16 16s16-7.164 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLink.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLink.js new file mode 100644 index 000000000..3305e6a07 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLink.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'link', icon: [512, 512, [], "f0c1", "M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLiraSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLiraSign.js new file mode 100644 index 000000000..61b584774 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLiraSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'lira-sign', icon: [384, 512, [], "f195", "M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faList.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faList.js new file mode 100644 index 000000000..e3eea3762 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faList.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'list', icon: [512, 512, [], "f03a", "M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListAlt.js new file mode 100644 index 000000000..96f92f38e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListOl.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListOl.js new file mode 100644 index 000000000..4b0332d17 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListOl.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'list-ol', icon: [512, 512, [], "f0cb", "M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListUl.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListUl.js new file mode 100644 index 000000000..a6c38a0d4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faListUl.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'list-ul', icon: [512, 512, [], "f0ca", "M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLocationArrow.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLocationArrow.js new file mode 100644 index 000000000..8d707afa8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLocationArrow.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'location-arrow', icon: [512, 512, [], "f124", "M443.683 4.529L27.818 196.418C-18.702 217.889-3.39 288 47.933 288H224v175.993c0 51.727 70.161 66.526 91.582 20.115L507.38 68.225c18.905-40.961-23.752-82.133-63.697-63.696z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLock.js new file mode 100644 index 000000000..5d9191103 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'lock', icon: [448, 512, [], "f023", "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLockOpen.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLockOpen.js new file mode 100644 index 000000000..beb323cfa --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLockOpen.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'lock-open', icon: [576, 512, [], "f3c1", "M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltDown.js new file mode 100644 index 000000000..53cc6220d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'long-arrow-alt-down', icon: [256, 512, [], "f309", "M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltLeft.js new file mode 100644 index 000000000..94f0405ad --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'long-arrow-alt-left', icon: [448, 512, [], "f30a", "M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltRight.js new file mode 100644 index 000000000..ce3781150 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'long-arrow-alt-right', icon: [448, 512, [], "f30b", "M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltUp.js new file mode 100644 index 000000000..88804729b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLongArrowAltUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'long-arrow-alt-up', icon: [256, 512, [], "f30c", "M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLowVision.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLowVision.js new file mode 100644 index 000000000..4e0fc45d4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faLowVision.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'low-vision', icon: [576, 512, [], "f2a8", "M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagic.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagic.js new file mode 100644 index 000000000..830ce1115 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagic.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'magic', icon: [512, 512, [], "f0d0", "M101.1 505L7 410.9c-9.4-9.4-9.4-24.6 0-33.9L377 7c9.4-9.4 24.6-9.4 33.9 0l94.1 94.1c9.4 9.4 9.4 24.6 0 33.9L135 505c-9.3 9.3-24.5 9.3-33.9 0zM304 159.2l48.8 48.8 89.9-89.9-48.8-48.8-89.9 89.9zM138.9 39.3l-11.7 23.8-26.2 3.8c-4.7.7-6.6 6.5-3.2 9.8l19 18.5-4.5 26.1c-.8 4.7 4.1 8.3 8.3 6.1L144 115l23.4 12.3c4.2 2.2 9.1-1.4 8.3-6.1l-4.5-26.1 19-18.5c3.4-3.3 1.5-9.1-3.2-9.8L160.8 63l-11.7-23.8c-2-4.1-8.1-4.1-10.2.1zm97.7-20.7l-7.8 15.8-17.5 2.6c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L240 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm-192 0l-7.8 15.8L19.3 37c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L48 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm416 223.5l-7.8 15.8-17.5 2.5c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4l15.6-8.2 15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-2.8-5.4-2.8-6.8 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagnet.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagnet.js new file mode 100644 index 000000000..d39559469 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMagnet.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'magnet', icon: [512, 512, [], "f076", "M164.1 160H12c-6.6 0-12-5.4-12-12V68c0-19.9 16.1-36 36-36h104c19.9 0 36 16.1 36 36v80c.1 6.6-5.3 12-11.9 12zm348-12V67.9c0-19.9-16.1-36-36-36h-104c-19.9 0-36 16.1-36 36v80c0 6.6 5.4 12 12 12h152c6.6.1 12-5.3 12-11.9zm-164 44c-6.6 0-12 5.4-12 12v52c0 128.1-160 127.9-160 0v-52c0-6.6-5.4-12-12-12h-152c-6.7 0-12 5.4-12 12.1.1 21.4.6 40.3 0 53.3C.1 408 136.3 504 256.9 504 377.5 504 512 408 512 257.3c-.6-12.8-.2-33 0-53.2 0-6.7-5.3-12.1-12-12.1H348.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMale.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMale.js new file mode 100644 index 000000000..0341da577 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMale.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'male', icon: [192, 512, [], "f183", "M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMap.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMap.js new file mode 100644 index 000000000..5174f4db6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMap.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'map', icon: [576, 512, [], "f279", "M576 56.015v335.97a23.998 23.998 0 0 1-13.267 21.466l-128 64C418.948 485.344 400 473.992 400 455.985v-335.97a23.998 23.998 0 0 1 13.267-21.466l128-64C557.052 26.656 576 38.008 576 56.015zm-206.253 42.07l-144-64c-15.751-7-33.747 4.461-33.747 21.932v335.967a24 24 0 0 0 14.253 21.931l144 64c15.751 7 33.747-4.461 33.747-21.931V120.017a24 24 0 0 0-14.253-21.932zm-228.48-63.536l-128 63.985A23.998 23.998 0 0 0 0 120v335.985c0 18.007 18.948 29.359 34.733 21.466l128-63.985A23.998 23.998 0 0 0 176 392V56.015c0-18.007-18.948-29.359-34.733-21.466z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarker.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarker.js new file mode 100644 index 000000000..e4b0342f6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarker.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'map-marker', icon: [384, 512, [], "f041", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarkerAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarkerAlt.js new file mode 100644 index 000000000..909338155 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapMarkerAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'map-marker-alt', icon: [384, 512, [], "f3c5", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapPin.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapPin.js new file mode 100644 index 000000000..2083664f9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapPin.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'map-pin', icon: [320, 512, [], "f276", "M192 300.813v172.82l-22.015 33.023c-4.75 7.125-15.219 7.125-19.969 0L128 473.633v-172.82a162.221 162.221 0 0 0 64 0zM160 0c79.529 0 144 64.471 144 144s-64.471 144-144 144S16 223.529 16 144 80.471 0 160 0M80 136c0-39.701 32.299-72 72-72a8 8 0 0 0 0-16c-48.523 0-88 39.477-88 88a8 8 0 0 0 16 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapSigns.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapSigns.js new file mode 100644 index 000000000..825c22b0c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMapSigns.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'map-signs', icon: [512, 512, [], "f277", "M487.515 104.485L439.03 152.97a23.998 23.998 0 0 1-16.97 7.029H56c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h160v-8c0-13.255 10.745-24 24-24h32c13.255 0 24 10.745 24 24v8h126.059a24 24 0 0 1 16.97 7.029l48.485 48.485c4.687 4.687 4.687 12.285.001 16.971zM216 368v120c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V368h-80zm240-144H296v-48h-80v48H89.941a24 24 0 0 0-16.97 7.029l-48.485 48.485c-4.686 4.686-4.686 12.284 0 16.971l48.485 48.485a23.998 23.998 0 0 0 16.97 7.029H456c13.255 0 24-10.745 24-24v-80C480 234.745 469.255 224 456 224z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMars.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMars.js new file mode 100644 index 000000000..8d20217d3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMars.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mars', icon: [384, 512, [], "f222", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsDouble.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsDouble.js new file mode 100644 index 000000000..86793214f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsDouble.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mars-double', icon: [512, 512, [], "f227", "M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStroke.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStroke.js new file mode 100644 index 000000000..584fe3cb2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStroke.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mars-stroke', icon: [384, 512, [], "f229", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeH.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeH.js new file mode 100644 index 000000000..1403a884c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeH.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mars-stroke-h', icon: [480, 512, [], "f22b", "M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeV.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeV.js new file mode 100644 index 000000000..631e5961a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMarsStrokeV.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mars-stroke-v', icon: [288, 512, [], "f22a", "M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMedkit.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMedkit.js new file mode 100644 index 000000000..982e31ba8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMedkit.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'medkit', icon: [512, 512, [], "f0fa", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMeh.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMeh.js new file mode 100644 index 000000000..d90a8bd98 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMeh.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'meh', icon: [512, 512, [], "f11a", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm160 208H176c-21.178 0-21.169 32 0 32h160c21.178 0 21.169-32 0-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMercury.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMercury.js new file mode 100644 index 000000000..5ffb9f31d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMercury.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mercury', icon: [288, 512, [], "f223", "M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrochip.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrochip.js new file mode 100644 index 000000000..df1407be9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrochip.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'microchip', icon: [512, 512, [], "f2db", "M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophone.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophone.js new file mode 100644 index 000000000..f88166260 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophone.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'microphone', icon: [384, 512, [], "f130", "M96 256V96c0-53.019 42.981-96 96-96s96 42.981 96 96v160c0 53.019-42.981 96-96 96s-96-42.981-96-96zm252-56h-24c-6.627 0-12 5.373-12 12v42.68c0 66.217-53.082 120.938-119.298 121.318C126.213 376.38 72 322.402 72 256v-44c0-6.627-5.373-12-12-12H36c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c81.307-11.681 144-81.79 144-166.278v-44c0-6.627-5.373-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophoneSlash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophoneSlash.js new file mode 100644 index 000000000..1066bb997 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMicrophoneSlash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'microphone-slash', icon: [512, 512, [], "f131", "M421.45 285.195L376 239.746V212c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12v44c0 9.957-.881 19.71-2.55 29.195zM352 96c0-53.019-42.981-96-96-96-32.574 0-61.354 16.227-78.71 41.035L352 215.746V96zm152.971 363.716L52.284 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 18.343c-9.372 9.373-9.372 24.568 0 33.941L160 205.254v49.577c0 53.089 43.436 97.452 96.524 97.167 14.626-.078 28.471-3.44 40.854-9.366l17.746 17.746c-17.529 9.971-37.794 15.666-59.372 15.622C189.355 375.864 136 321.053 136 254.656V212c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c25.625-3.682 49.396-13.172 69.942-27.083L459.717 504.97c9.373 9.373 24.569 9.373 33.941 0l11.313-11.313c9.372-9.373 9.372-24.568 0-33.941z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinus.js new file mode 100644 index 000000000..004bb3eb1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'minus', icon: [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusCircle.js new file mode 100644 index 000000000..1c7a34505 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'minus-circle', icon: [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusSquare.js new file mode 100644 index 000000000..3b33bd6b6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMinusSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'minus-square', icon: [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobile.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobile.js new file mode 100644 index 000000000..3faea9fe7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobile.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mobile', icon: [320, 512, [], "f10b", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobileAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobileAlt.js new file mode 100644 index 000000000..507167db1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMobileAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mobile-alt', icon: [320, 512, [], "f3cd", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoneyBillAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoneyBillAlt.js new file mode 100644 index 000000000..6ebdc5fb8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoneyBillAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M640 120v272c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h592c13.255 0 24 10.745 24 24zM96 384c0-35.346-28.654-64-64-64v64h64zm0-256H32v64c35.346 0 64-28.654 64-64zm304 128c0-53.021-35.816-96-80-96s-80 42.979-80 96c0 53.012 35.814 96 80 96 44.167 0 80-42.969 80-96zm208 64c-35.346 0-64 28.654-64 64h64v-64zm0-192h-64c0 35.346 28.654 64 64 64v-64zM277.563 299.527c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoon.js new file mode 100644 index 000000000..e0195691a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMoon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'moon', icon: [512, 512, [], "f186", "M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMotorcycle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMotorcycle.js new file mode 100644 index 000000000..dfa0fb3e5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMotorcycle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'motorcycle', icon: [640, 512, [], "f21c", "M512.949 192.003c-14.862-.108-29.14 2.322-42.434 6.874L437.589 144H520c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24h-45.311a24 24 0 0 0-17.839 7.945l-37.496 41.663-22.774-37.956A24 24 0 0 0 376 64h-80c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h66.411l19.2 32H227.904c-17.727-23.073-44.924-40-99.904-40H72.54c-13.455 0-24.791 11.011-24.536 24.464C48.252 141.505 58.9 152 72 152h56c24.504 0 38.686 10.919 47.787 24.769l-11.291 20.529c-13.006-3.865-26.871-5.736-41.251-5.21C55.857 194.549 1.565 249.605.034 317.021-1.603 389.076 56.317 448 128 448c59.642 0 109.744-40.794 123.953-96h84.236c13.673 0 24.589-11.421 23.976-25.077-2.118-47.12 17.522-93.665 56.185-125.026l12.485 20.808c-27.646 23.654-45.097 58.88-44.831 98.179.47 69.556 57.203 126.452 126.758 127.11 71.629.678 129.839-57.487 129.234-129.099-.588-69.591-57.455-126.386-127.047-126.892zM128 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c4.242 0 8.405.341 12.469.982L98.97 316.434C90.187 332.407 101.762 352 120 352h81.297c-12.37 28.225-40.56 48-73.297 48zm388.351-.116C470.272 402.337 432 365.554 432 320c0-21.363 8.434-40.781 22.125-55.144l49.412 82.352c4.546 7.577 14.375 10.034 21.952 5.488l13.72-8.232c7.577-4.546 10.034-14.375 5.488-21.952l-48.556-80.927A80.005 80.005 0 0 1 512 240c45.554 0 82.338 38.273 79.884 84.352-2.16 40.558-34.974 73.372-75.533 75.532z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMousePointer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMousePointer.js new file mode 100644 index 000000000..7ff24df20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMousePointer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'mouse-pointer', icon: [320, 512, [], "f245", "M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMusic.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMusic.js new file mode 100644 index 000000000..60dc7f823 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faMusic.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'music', icon: [512, 512, [], "f001", "M470.4 1.5l-304 96C153.1 101.7 144 114 144 128v264.6c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V220.5l272-85.9v194c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V32c0-21.7-21.1-37-41.6-30.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNeuter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNeuter.js new file mode 100644 index 000000000..5c2d544d9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNeuter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'neuter', icon: [288, 512, [], "f22c", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNewspaper.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNewspaper.js new file mode 100644 index 000000000..89cd1a0da --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faNewspaper.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectGroup.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectGroup.js new file mode 100644 index 000000000..c71ddecbc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectGroup.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'object-group', icon: [512, 512, [], "f247", "M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectUngroup.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectUngroup.js new file mode 100644 index 000000000..9d2a2b585 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faObjectUngroup.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faOutdent.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faOutdent.js new file mode 100644 index 000000000..44fb87f46 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faOutdent.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'outdent', icon: [448, 512, [], "f03b", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm208 144h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm192-128h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM4.687 267.313l96 95.984C110.734 373.348 128 366.224 128 351.984V160.008c0-14.329-17.325-21.304-27.313-11.313l-96 95.992c-6.249 6.248-6.249 16.378 0 22.626z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaintBrush.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaintBrush.js new file mode 100644 index 000000000..18cbbf4db --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaintBrush.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paint-brush', icon: [512, 512, [], "f1fc", "M269.9 364.6c1.4 6.4 2.1 13 2.1 19.7 0 81.2-54.2 127.7-134.8 127.7C41.5 512 0 435.1 0 347.6c10.4 7.1 46.9 36.5 58.7 36.5 7 0 13-4 15.5-10.6 23.6-62.2 66.5-76.5 112.9-77.4 15.6 33.8 46.1 59.6 82.8 68.5zM460.6 0c-14.4 0-27.9 6.4-38.2 15.7C228.2 190 208 194.1 208 245.4c0 48.8 40.5 90.6 90.2 90.6 59 0 93.2-43.4 200.6-244.8 7-13.7 13.2-28.5 13.2-43.9C512 19.7 487.3 0 460.6 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperPlane.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperPlane.js new file mode 100644 index 000000000..587a9bfed --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperPlane.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperclip.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperclip.js new file mode 100644 index 000000000..50a1fad40 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaperclip.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paperclip', icon: [448, 512, [], "f0c6", "M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faParagraph.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faParagraph.js new file mode 100644 index 000000000..e95e3bf72 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faParagraph.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paragraph', icon: [448, 512, [], "f1dd", "M408 32H177.531C88.948 32 16.045 103.335 16 191.918 15.956 280.321 87.607 352 176 352v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h32v344c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h40c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaste.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaste.js new file mode 100644 index 000000000..b729aea51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaste.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paste', icon: [448, 512, [], "f0ea", "M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPause.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPause.js new file mode 100644 index 000000000..9fc334855 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPause.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'pause', icon: [448, 512, [], "f04c", "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPauseCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPauseCircle.js new file mode 100644 index 000000000..36726732a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPauseCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaw.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaw.js new file mode 100644 index 000000000..2b841f049 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPaw.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'paw', icon: [512, 512, [], "f1b0", "M85.231 330.958C36 330.958 0 273.792 0 231.5c0-28.292 16-58.042 49.538-58.042 49.231 0 85.231 57.458 85.231 99.75 0 28.292-15.692 57.75-49.538 57.75zm348 106.167c0 37.042-32 42.875-63.385 42.875-41.231 0-74.462-26.25-113.846-26.25-41.231 0-76.308 25.958-120.923 25.958-29.847 0-56.308-9.625-56.308-42.583C78.769 368 180.616 265.333 256 265.333s177.231 102.959 177.231 171.792zM182.462 203.792c-49.847 0-80-59.5-80-100.333C102.462 70.792 120.308 32 160 32c50.154 0 80 59.5 80 100.333 0 32.667-17.846 71.459-57.538 71.459zM272 132.333C272 91.5 301.846 32 352 32c39.692 0 57.539 38.792 57.539 71.458 0 40.833-30.154 100.333-80.001 100.333C289.846 203.792 272 165 272 132.333zM512 231.5c0 42.292-36 99.458-85.231 99.458-33.847 0-49.538-29.458-49.538-57.75 0-42.291 35.999-99.75 85.231-99.75C496 173.458 512 203.208 512 231.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPenSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPenSquare.js new file mode 100644 index 000000000..aac206fb8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPenSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'pen-square', icon: [448, 512, [], "f14b", "M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPencilAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPencilAlt.js new file mode 100644 index 000000000..2ad74e740 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPencilAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'pencil-alt', icon: [512, 512, [], "f303", "M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPercent.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPercent.js new file mode 100644 index 000000000..69f862c56 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPercent.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'percent', icon: [448, 512, [], "f295", "M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhone.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhone.js new file mode 100644 index 000000000..6f7e6ecc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhone.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'phone', icon: [512, 512, [], "f095", "M493.397 24.615l-104-23.997c-11.314-2.611-22.879 3.252-27.456 13.931l-48 111.997a24 24 0 0 0 6.862 28.029l60.617 49.596c-35.973 76.675-98.938 140.508-177.249 177.248l-49.596-60.616a24 24 0 0 0-28.029-6.862l-111.997 48C3.873 366.516-1.994 378.08.618 389.397l23.997 104C27.109 504.204 36.748 512 48 512c256.087 0 464-207.532 464-464 0-11.176-7.714-20.873-18.603-23.385z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneSquare.js new file mode 100644 index 000000000..bc22735b1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'phone-square', icon: [448, 512, [], "f098", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneVolume.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneVolume.js new file mode 100644 index 000000000..5430e1591 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPhoneVolume.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'phone-volume', icon: [384, 512, [], "f2a0", "M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlane.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlane.js new file mode 100644 index 000000000..3c6cbb438 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlane.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'plane', icon: [576, 512, [], "f072", "M472 200H360.211L256.013 5.711A12 12 0 0 0 245.793 0h-57.787c-7.85 0-13.586 7.413-11.616 15.011L209.624 200H99.766l-34.904-58.174A12 12 0 0 0 54.572 136H12.004c-7.572 0-13.252 6.928-11.767 14.353l21.129 105.648L.237 361.646c-1.485 7.426 4.195 14.354 11.768 14.353l42.568-.002c4.215 0 8.121-2.212 10.289-5.826L99.766 312h109.858L176.39 496.989c-1.97 7.599 3.766 15.011 11.616 15.011h57.787a12 12 0 0 0 10.22-5.711L360.212 312H472c57.438 0 104-25.072 104-56s-46.562-56-104-56z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlay.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlay.js new file mode 100644 index 000000000..5f3f2f172 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlay.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'play', icon: [448, 512, [], "f04b", "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlayCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlayCircle.js new file mode 100644 index 000000000..d535aeb61 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlayCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'play-circle', icon: [512, 512, [], "f144", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlug.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlug.js new file mode 100644 index 000000000..a8f9b45f0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlug.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'plug', icon: [384, 512, [], "f1e6", "M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlus.js new file mode 100644 index 000000000..b7b5ec2a8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'plus', icon: [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusCircle.js new file mode 100644 index 000000000..c0eb8bafb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'plus-circle', icon: [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusSquare.js new file mode 100644 index 000000000..77358c27a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPlusSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPodcast.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPodcast.js new file mode 100644 index 000000000..6b5c583db --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPodcast.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'podcast', icon: [448, 512, [], "f2ce", "M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPoundSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPoundSign.js new file mode 100644 index 000000000..32f3d3f00 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPoundSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'pound-sign', icon: [320, 512, [], "f154", "M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPowerOff.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPowerOff.js new file mode 100644 index 000000000..ec3e3429a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPowerOff.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'power-off', icon: [512, 512, [], "f011", "M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPrint.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPrint.js new file mode 100644 index 000000000..f1fa28ef4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPrint.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'print', icon: [512, 512, [], "f02f", "M464 192h-16V81.941a24 24 0 0 0-7.029-16.97L383.029 7.029A24 24 0 0 0 366.059 0H88C74.745 0 64 10.745 64 24v168H48c-26.51 0-48 21.49-48 48v132c0 6.627 5.373 12 12 12h52v104c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V384h52c6.627 0 12-5.373 12-12V240c0-26.51-21.49-48-48-48zm-80 256H128v-96h256v96zM128 224V64h192v40c0 13.2 10.8 24 24 24h40v96H128zm304 72c-13.254 0-24-10.746-24-24s10.746-24 24-24 24 10.746 24 24-10.746 24-24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPuzzlePiece.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPuzzlePiece.js new file mode 100644 index 000000000..d194e100a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faPuzzlePiece.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'puzzle-piece', icon: [576, 512, [], "f12e", "M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQrcode.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQrcode.js new file mode 100644 index 000000000..a5360eb1d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQrcode.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'qrcode', icon: [448, 512, [], "f029", "M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestion.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestion.js new file mode 100644 index 000000000..4dc9deff6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestion.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'question', icon: [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestionCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestionCircle.js new file mode 100644 index 000000000..c046f87c2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuestionCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'question-circle', icon: [512, 512, [], "f059", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteLeft.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteLeft.js new file mode 100644 index 000000000..99e523962 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteLeft.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'quote-left', icon: [512, 512, [], "f10d", "M0 432V304C0 166.982 63.772 67.676 193.827 32.828 209.052 28.748 224 40.265 224 56.027v33.895c0 10.057-6.228 19.133-15.687 22.55C142.316 136.312 104 181.946 104 256h72c26.51 0 48 21.49 48 48v128c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm336 48h128c26.51 0 48-21.49 48-48V304c0-26.51-21.49-48-48-48h-72c0-74.054 38.316-119.688 104.313-143.528C505.772 109.055 512 99.979 512 89.922V56.027c0-15.762-14.948-27.279-30.173-23.199C351.772 67.676 288 166.982 288 304v128c0 26.51 21.49 48 48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteRight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteRight.js new file mode 100644 index 000000000..4478345bd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faQuoteRight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'quote-right', icon: [512, 512, [], "f10e", "M512 80v128c0 137.018-63.772 236.324-193.827 271.172-15.225 4.08-30.173-7.437-30.173-23.199v-33.895c0-10.057 6.228-19.133 15.687-22.55C369.684 375.688 408 330.054 408 256h-72c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h128c26.51 0 48 21.49 48 48zM176 32H48C21.49 32 0 53.49 0 80v128c0 26.51 21.49 48 48 48h72c0 74.054-38.316 119.688-104.313 143.528C6.228 402.945 0 412.021 0 422.078v33.895c0 15.762 14.948 27.279 30.173 23.199C160.228 444.324 224 345.018 224 208V80c0-26.51-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRandom.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRandom.js new file mode 100644 index 000000000..4b39f2d92 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRandom.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'random', icon: [512, 512, [], "f074", "M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRecycle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRecycle.js new file mode 100644 index 000000000..7a70bf8ca --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRecycle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'recycle', icon: [512, 512, [], "f1b8", "M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedo.js new file mode 100644 index 000000000..de99c6bbb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'redo', icon: [512, 512, [], "f01e", "M500.333 0h-47.411c-6.853 0-12.314 5.729-11.986 12.574l3.966 82.759C399.416 41.899 331.672 8 256.001 8 119.34 8 7.899 119.526 8 256.187 8.101 393.068 119.096 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-33.971-33.971c-4.466-4.466-11.64-4.717-16.38-.543C341.308 415.448 300.606 432 256 432c-97.267 0-176-78.716-176-176 0-97.267 78.716-176 176-176 60.892 0 114.506 30.858 146.099 77.8l-101.525-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedoAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedoAlt.js new file mode 100644 index 000000000..f32608a93 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRedoAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'redo-alt', icon: [512, 512, [], "f2f9", "M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRegistered.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRegistered.js new file mode 100644 index 000000000..488258bbe --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRegistered.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'registered', icon: [512, 512, [], "f25d", "M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReply.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReply.js new file mode 100644 index 000000000..38b82800b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReply.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'reply', icon: [512, 512, [], "f3e5", "M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReplyAll.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReplyAll.js new file mode 100644 index 000000000..576fdf786 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faReplyAll.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'reply-all', icon: [576, 512, [], "f122", "M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRetweet.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRetweet.js new file mode 100644 index 000000000..a33a65968 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRetweet.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'retweet', icon: [640, 512, [], "f079", "M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRoad.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRoad.js new file mode 100644 index 000000000..052bb1c1c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRoad.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'road', icon: [576, 512, [], "f018", "M567.3 383.6L429.9 78.2C426 69.5 417.4 64 408 64h-96.1l1.9 18.8c.7 7.1-4.8 13.2-11.9 13.2H274c-7.1 0-12.7-6.2-11.9-13.2L264 64h-96c-9.4 0-18 5.5-21.9 14.2L8.7 383.6C3.2 395.8 0 409.6 0 424c0 13.3 10.7 24 24 24h213.6c-7.1 0-12.7-6.2-11.9-13.2l10.8-104c.6-6.1 5.8-10.8 11.9-10.8h79.2c6.1 0 11.3 4.6 11.9 10.8l10.8 104c.7 7.1-4.8 13.2-11.9 13.2H552c13.2 0 24-10.7 24-24 0-13.9-3-27.7-8.7-40.4zM254.7 154.8l3.3-32c.6-6.1 5.8-10.8 11.9-10.8h36.2c6.1 0 11.3 4.6 11.9 10.8l3.3 32c.7 7.1-4.8 13.2-11.9 13.2h-42.8c-7.1 0-12.7-6.2-11.9-13.2zM321.8 288h-67.6c-7.1 0-12.7-6.2-11.9-13.2l7.4-72c.6-6.1 5.8-10.8 11.9-10.8h52.7c6.1 0 11.3 4.6 11.9 10.8l7.4 72c.9 7-4.7 13.2-11.8 13.2z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRocket.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRocket.js new file mode 100644 index 000000000..f937c0bc8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRocket.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'rocket', icon: [512, 512, [], "f135", "M505.1 19.1C503.8 13 499 8.2 492.9 6.9 460.7 0 435.5 0 410.4 0 307.2 0 245.3 55.2 199.1 128H94.9c-18.2 0-34.8 10.3-42.9 26.5L2.6 253.3c-8 16 3.6 34.7 21.5 34.7h95.1c-5.9 12.8-11.9 25.5-18 37.7-3.1 6.2-1.9 13.6 3 18.5l63.6 63.6c4.9 4.9 12.3 6.1 18.5 3 12.2-6.1 24.9-12 37.7-17.9V488c0 17.8 18.8 29.4 34.7 21.5l98.7-49.4c16.3-8.1 26.5-24.8 26.5-42.9V312.8c72.6-46.3 128-108.4 128-211.1.1-25.2.1-50.4-6.8-82.6zM400 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRss.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRss.js new file mode 100644 index 000000000..d83a063b8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRss.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'rss', icon: [448, 512, [], "f09e", "M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRssSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRssSquare.js new file mode 100644 index 000000000..f9edf0582 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRssSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'rss-square', icon: [448, 512, [], "f143", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRubleSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRubleSign.js new file mode 100644 index 000000000..867333795 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRubleSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ruble-sign', icon: [384, 512, [], "f158", "M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRupeeSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRupeeSign.js new file mode 100644 index 000000000..bd8b0b03f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faRupeeSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'rupee-sign', icon: [320, 512, [], "f156", "M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSave.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSave.js new file mode 100644 index 000000000..102d27a5a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSave.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearch.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearch.js new file mode 100644 index 000000000..1b8a7440b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearch.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'search', icon: [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchMinus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchMinus.js new file mode 100644 index 000000000..cb032eec3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchMinus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'search-minus', icon: [512, 512, [], "f010", "M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchPlus.js new file mode 100644 index 000000000..a87a12d99 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSearchPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'search-plus', icon: [512, 512, [], "f00e", "M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faServer.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faServer.js new file mode 100644 index 000000000..7e75af6b3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faServer.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'server', icon: [512, 512, [], "f233", "M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShare.js new file mode 100644 index 000000000..518ad4e51 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'share', icon: [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAlt.js new file mode 100644 index 000000000..731e32370 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'share-alt', icon: [448, 512, [], "f1e0", "M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAltSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAltSquare.js new file mode 100644 index 000000000..0b0ca9352 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareAltSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'share-alt-square', icon: [448, 512, [], "f1e1", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareSquare.js new file mode 100644 index 000000000..ee2ac020a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShareSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'share-square', icon: [576, 512, [], "f14d", "M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShekelSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShekelSign.js new file mode 100644 index 000000000..cfae5b8b4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShekelSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shekel-sign', icon: [448, 512, [], "f20b", "M170.12 96H80v372c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V44c0-6.627 5.373-12 12-12h168.36C265.48 32 325 89.6 325 175.071V359c0 6.627-5.373 12-12 12h-44c-13.255 0-24-10.745-24-24V170.323C245 125.11 216.839 96 170.12 96zM436 32h-56c-6.627 0-12 5.373-12 12v372h-90.12c-46.72 0-74.88-29.11-74.88-74.323V165c0-13.255-10.745-24-24-24h-44c-6.627 0-12 5.373-12 12v183.929C123 422.4 182.52 480 267.64 480H436c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShieldAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShieldAlt.js new file mode 100644 index 000000000..b94dd7449 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShieldAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shield-alt', icon: [512, 512, [], "f3ed", "M496 128c0 221.282-135.934 344.645-221.539 380.308a48 48 0 0 1-36.923 0C130.495 463.713 16 326.487 16 128a48 48 0 0 1 29.539-44.308l192-80a48 48 0 0 1 36.923 0l192 80A48 48 0 0 1 496 128zM256 446.313l.066.034c93.735-46.689 172.497-156.308 175.817-307.729L256 65.333v380.98z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShip.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShip.js new file mode 100644 index 000000000..f21afa7ae --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShip.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ship', icon: [640, 512, [], "f21a", "M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBag.js new file mode 100644 index 000000000..fd7cd3155 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shopping-bag', icon: [448, 512, [], "f290", "M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBasket.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBasket.js new file mode 100644 index 000000000..8f18a62b0 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingBasket.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shopping-basket', icon: [576, 512, [], "f291", "M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingCart.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingCart.js new file mode 100644 index 000000000..4e72f600b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShoppingCart.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shopping-cart', icon: [576, 512, [], "f07a", "M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShower.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShower.js new file mode 100644 index 000000000..9deb7c87a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faShower.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'shower', icon: [512, 512, [], "f2cc", "M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignInAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignInAlt.js new file mode 100644 index 000000000..9e15222ed --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignInAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sign-in-alt', icon: [512, 512, [], "f2f6", "M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignLanguage.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignLanguage.js new file mode 100644 index 000000000..cf26b3598 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignLanguage.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sign-language', icon: [448, 512, [], "f2a7", "M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignOutAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignOutAlt.js new file mode 100644 index 000000000..453fdf346 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignOutAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sign-out-alt', icon: [512, 512, [], "f2f5", "M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignal.js new file mode 100644 index 000000000..a9fcefc29 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSignal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'signal', icon: [640, 512, [], "f012", "M36 384h56c6.6 0 12 5.4 12 12v104c0 6.6-5.4 12-12 12H36c-6.6 0-12-5.4-12-12V396c0-6.6 5.4-12 12-12zm116-36v152c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V348c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-80v232c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V268c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-112v344c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V156c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zM536 12v488c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSitemap.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSitemap.js new file mode 100644 index 000000000..4009f6eff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSitemap.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sitemap', icon: [640, 512, [], "f0e8", "M616 320h-48v-48c0-22.056-17.944-40-40-40H344v-40h48c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h48v40H112c-22.056 0-40 17.944-40 40v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSlidersH.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSlidersH.js new file mode 100644 index 000000000..afe1f771d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSlidersH.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sliders-h', icon: [576, 512, [], "f1de", "M576 80v40c0 6.6-5.4 12-12 12H160v8c0 13.3-10.7 24-24 24h-16c-13.3 0-24-10.7-24-24v-8H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h84v-8c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v8h404c6.6 0 12 5.4 12 12zm-12 148h-84v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h404v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12zm0 160H288v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h212v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h276c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSmile.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSmile.js new file mode 100644 index 000000000..f9854b236 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSmile.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'smile', icon: [512, 512, [], "f118", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-122.526 75.34c11.479-17.755-15.349-35.194-26.873-17.374-53.418 82.627-143.71 82.681-197.164 0-11.502-17.79-38.364-.401-26.873 17.374 66.014 102.107 184.795 102.265 250.91 0zM108 192c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSnowflake.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSnowflake.js new file mode 100644 index 000000000..9107462ff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSnowflake.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M444.816 301.639a24.12 24.12 0 0 0 2.661-16.978c-2.725-12.966-15.339-21.245-28.174-18.492l-87.407 25.046L264 256l67.896-35.215 87.407 25.046c12.835 2.753 25.449-5.526 28.174-18.492 2.725-12.966-5.471-25.708-18.305-28.461l-47.477-7.137 53.077-30.956c11.363-6.627 15.257-21.306 8.696-32.785-6.561-11.479-21.091-15.412-32.454-8.785l-53.077 30.956 17.621-45.104c4.057-12.606-2.768-26.146-15.247-30.245-12.478-4.099-25.883 2.797-29.94 15.402l-22.232 88.99-60.38 35.215V144l65.175-63.945c8.778-9.852 7.987-25.027-1.766-33.894-9.753-8.867-24.775-8.068-33.552 1.784l-29.857 37.967V24c0-13.255-10.637-24-23.758-24s-23.758 10.745-23.758 24v61.912l-29.857-37.967c-8.779-9.852-23.799-10.652-33.552-1.784-9.753 8.867-10.543 24.042-1.766 33.894L200.242 144v70.431l-60.38-35.215-22.232-88.99c-4.057-12.605-17.462-19.501-29.94-15.402-12.478 4.099-19.304 17.64-15.247 30.245l17.62 45.104-53.077-30.956c-11.363-6.627-25.893-2.694-32.454 8.785s-2.667 26.157 8.696 32.785l53.077 30.956-47.477 7.137C5.993 201.634-2.203 214.375.523 227.341c2.725 12.965 15.339 21.245 28.174 18.492l87.407-25.046L184 256l-67.896 35.215-87.406-25.045c-12.835-2.753-25.449 5.526-28.174 18.492-2.725 12.967 5.47 25.708 18.305 28.461l47.477 7.137-53.077 30.956C1.866 357.843-2.027 372.521 4.533 384s21.091 15.412 32.454 8.785l53.077-30.956-17.62 45.104a24.157 24.157 0 0 0 2.022 19.428c2.831 4.953 7.416 8.909 13.224 10.816 12.478 4.099 25.883-2.797 29.94-15.402l22.232-88.99 60.38-35.215V368l-65.175 63.945c-8.778 9.852-7.987 25.027 1.766 33.894 9.754 8.868 24.774 8.068 33.552-1.784l29.857-37.967V488c0 13.255 10.637 24 23.758 24s23.758-10.745 23.758-24v-61.912l29.857 37.967A23.59 23.59 0 0 0 295.282 472a23.534 23.534 0 0 0 15.885-6.161c9.753-8.867 10.544-24.042 1.766-33.894L247.758 368v-70.431l60.38 35.215 22.232 88.99c4.057 12.605 17.462 19.501 29.94 15.402 12.479-4.099 19.304-17.64 15.247-30.245l-17.621-45.104 53.077 30.956c11.363 6.627 25.893 2.694 32.454-8.785s2.667-26.157-8.696-32.785l-53.077-30.956 47.477-7.137c6.86-1.469 12.394-5.793 15.645-11.481z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSort.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSort.js new file mode 100644 index 000000000..65c0a2497 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSort.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort', icon: [320, 512, [], "f0dc", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaDown.js new file mode 100644 index 000000000..aff97d39d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-alpha-down', icon: [448, 512, [], "f15d", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zm119.075-180.007A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaUp.js new file mode 100644 index 000000000..8467aee7b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAlphaUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-alpha-up', icon: [448, 512, [], "f15e", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zm301.671 98.621A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountDown.js new file mode 100644 index 000000000..50cd8223b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-amount-down', icon: [512, 512, [], "f160", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountUp.js new file mode 100644 index 000000000..97952c11d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortAmountUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-amount-up', icon: [512, 512, [], "f161", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortDown.js new file mode 100644 index 000000000..475882be9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-down', icon: [320, 512, [], "f0dd", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericDown.js new file mode 100644 index 000000000..bfa65e626 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-numeric-down', icon: [448, 512, [], "f162", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM175.984 368H128V48c0-8.837-7.163-16-16-16H80c-8.837 0-16 7.163-16 16v320H16.019c-14.212 0-21.384 17.244-11.314 27.314l79.981 80.002c6.245 6.245 16.38 6.247 22.627 0l79.984-80.002c10.05-10.05 2.928-27.314-11.313-27.314z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericUp.js new file mode 100644 index 000000000..b495ae83b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortNumericUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-numeric-up', icon: [448, 512, [], "f163", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM16.016 144H64v320c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144h47.981c14.212 0 21.384-17.244 11.314-27.314l-79.981-80.002c-6.245-6.245-16.38-6.247-22.627 0L4.702 116.686C-5.347 126.736 1.775 144 16.016 144z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortUp.js new file mode 100644 index 000000000..05794401f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSortUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sort-up', icon: [320, 512, [], "f0de", "M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpaceShuttle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpaceShuttle.js new file mode 100644 index 000000000..437ced9fd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpaceShuttle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'space-shuttle', icon: [640, 512, [], "f197", "M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpinner.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpinner.js new file mode 100644 index 000000000..5ebc0bf7d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSpinner.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'spinner', icon: [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSquare.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSquare.js new file mode 100644 index 000000000..e0b35b356 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSquare.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStar.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStar.js new file mode 100644 index 000000000..19f397f14 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStar.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'star', icon: [576, 512, [], "f005", "M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStarHalf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStarHalf.js new file mode 100644 index 000000000..ed49c6163 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStarHalf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepBackward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepBackward.js new file mode 100644 index 000000000..2ca043da2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepBackward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'step-backward', icon: [448, 512, [], "f048", "M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepForward.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepForward.js new file mode 100644 index 000000000..08c47407e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStepForward.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'step-forward', icon: [448, 512, [], "f051", "M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStethoscope.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStethoscope.js new file mode 100644 index 000000000..b271a1a6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStethoscope.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'stethoscope', icon: [512, 512, [], "f0f1", "M512 176c0-35.659-29.164-64.507-64.941-63.993-34.21.492-62.296 28.357-63.043 62.562-.531 24.282 12.476 45.558 31.984 56.848V344c0 57.346-50.243 104-112 104-60.039 0-109.189-44.096-111.878-99.24C265.005 333.847 320 269.225 320 192V36.584c0-11.44-8.075-21.29-19.293-23.534L237.81.471c-12.997-2.599-25.641 5.83-28.241 18.827l-3.138 15.689c-2.6 12.997 5.83 25.641 18.827 28.241L256 69.376v121.4c0 52.852-42.203 96.707-95.053 97.22C107.58 288.513 64 245.25 64 192V69.376l30.742-6.149c12.997-2.6 21.427-15.243 18.827-28.241l-3.138-15.689C107.831 6.3 95.188-2.129 82.19.471L19.293 13.05C8.075 15.294 0 25.144 0 36.584V192c0 77.295 55.096 141.961 128.076 156.798C130.747 439.223 208.634 512 304 512c97.047 0 176-75.364 176-168V231.417c19.124-11.068 32-31.732 32-55.417zm-64-16c8.822 0 16 7.178 16 16s-7.178 16-16 16-16-7.178-16-16 7.178-16 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStickyNote.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStickyNote.js new file mode 100644 index 000000000..c747a4b52 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStickyNote.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStop.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStop.js new file mode 100644 index 000000000..f28d39934 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStop.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'stop', icon: [448, 512, [], "f04d", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStopCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStopCircle.js new file mode 100644 index 000000000..fe286dd7e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStopCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStreetView.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStreetView.js new file mode 100644 index 000000000..7228fc625 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStreetView.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'street-view', icon: [512, 512, [], "f21d", "M192 64c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zm112 80h-11.36c-22.711 10.443-49.59 10.894-73.28 0H208c-26.51 0-48 21.49-48 48v104c0 13.255 10.745 24 24 24h16v104c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V320h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48zm85.642 189.152a72.503 72.503 0 0 1-29.01 27.009C391.133 365.251 480 385.854 480 416c0 46.304-167.656 64-224 64-70.303 0-224-20.859-224-64 0-30.123 88.361-50.665 119.367-55.839a72.516 72.516 0 0 1-29.01-27.009C74.959 343.395 0 367.599 0 416c0 77.111 178.658 96 256 96 77.249 0 256-18.865 256-96 0-48.403-74.967-72.606-122.358-82.848z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStrikethrough.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStrikethrough.js new file mode 100644 index 000000000..e6ccc74c8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faStrikethrough.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'strikethrough', icon: [512, 512, [], "f0cc", "M496 288H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h480c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16zm-214.666 16c27.258 12.937 46.524 28.683 46.524 56.243 0 33.108-28.977 53.676-75.621 53.676-32.325 0-76.874-12.08-76.874-44.271V368c0-8.837-7.164-16-16-16H113.75c-8.836 0-16 7.163-16 16v19.204c0 66.845 77.717 101.82 154.487 101.82 88.578 0 162.013-45.438 162.013-134.424 0-19.815-3.618-36.417-10.143-50.6H281.334zm-30.952-96c-32.422-13.505-56.836-28.946-56.836-59.683 0-33.92 30.901-47.406 64.962-47.406 42.647 0 64.962 16.593 64.962 32.985V136c0 8.837 7.164 16 16 16h45.613c8.836 0 16-7.163 16-16v-30.318c0-52.438-71.725-79.875-142.575-79.875-85.203 0-150.726 40.972-150.726 125.646 0 22.71 4.665 41.176 12.777 56.547h129.823z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubscript.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubscript.js new file mode 100644 index 000000000..b98b97f2c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubscript.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'subscript', icon: [512, 512, [], "f12c", "M395.198 416c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 256c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 96H16C7.163 96 0 88.837 0 80V48c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035A15.999 15.999 0 0 1 204.226 32H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 256H272z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubway.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubway.js new file mode 100644 index 000000000..4a3466376 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSubway.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'subway', icon: [448, 512, [], "f239", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuitcase.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuitcase.js new file mode 100644 index 000000000..50f2dacc3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuitcase.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'suitcase', icon: [512, 512, [], "f0f2", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSun.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSun.js new file mode 100644 index 000000000..2c1cc260a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSun.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sun', icon: [512, 512, [], "f185", "M274.835 12.646l25.516 62.393c4.213 10.301 16.671 14.349 26.134 8.492l57.316-35.479c15.49-9.588 34.808 4.447 30.475 22.142l-16.03 65.475c-2.647 10.81 5.053 21.408 16.152 22.231l67.224 4.987c18.167 1.348 25.546 24.057 11.641 35.826L441.81 242.26c-8.495 7.19-8.495 20.289 0 27.479l51.454 43.548c13.906 11.769 6.527 34.478-11.641 35.826l-67.224 4.987c-11.099.823-18.799 11.421-16.152 22.231l16.03 65.475c4.332 17.695-14.986 31.73-30.475 22.142l-57.316-35.479c-9.463-5.858-21.922-1.81-26.134 8.492l-25.516 62.393c-6.896 16.862-30.774 16.862-37.67 0l-25.516-62.393c-4.213-10.301-16.671-14.349-26.134-8.492l-57.317 35.479c-15.49 9.588-34.808-4.447-30.475-22.142l16.03-65.475c2.647-10.81-5.053-21.408-16.152-22.231l-67.224-4.987c-18.167-1.348-25.546-24.057-11.641-35.826L70.19 269.74c8.495-7.19 8.495-20.289 0-27.479l-51.454-43.548c-13.906-11.769-6.527-34.478 11.641-35.826l67.224-4.987c11.099-.823 18.799-11.421 16.152-22.231l-16.03-65.475c-4.332-17.695 14.986-31.73 30.475-22.142l57.317 35.479c9.463 5.858 21.921 1.81 26.134-8.492l25.516-62.393c6.896-16.861 30.774-16.861 37.67 0zM392 256c0-74.991-61.01-136-136-136-74.991 0-136 61.009-136 136s61.009 136 136 136c74.99 0 136-61.009 136-136zm-32 0c0 57.346-46.654 104-104 104s-104-46.654-104-104 46.654-104 104-104 104 46.654 104 104z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuperscript.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuperscript.js new file mode 100644 index 000000000..ee2bb2287 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSuperscript.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'superscript', icon: [512, 512, [], "f12b", "M395.198 256c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 256H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035a16 16 0 0 1 13.598-7.567H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 416H272z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSync.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSync.js new file mode 100644 index 000000000..e987d880d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSync.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sync', icon: [512, 512, [], "f021", "M440.935 12.574l3.966 82.766C399.416 41.904 331.674 8 256 8 134.813 8 33.933 94.924 12.296 209.824 10.908 217.193 16.604 224 24.103 224h49.084c5.57 0 10.377-3.842 11.676-9.259C103.407 137.408 172.931 80 256 80c60.893 0 114.512 30.856 146.104 77.801l-101.53-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12h-47.411c-6.853 0-12.315 5.729-11.987 12.574zM256 432c-60.895 0-114.517-30.858-146.109-77.805l101.868 4.871c6.845.327 12.573-5.134 12.573-11.986v-47.412c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12V500c0 6.627 5.373 12 12 12h47.385c6.863 0 12.328-5.745 11.985-12.599l-4.129-82.575C112.725 470.166 180.405 504 256 504c121.187 0 222.067-86.924 243.704-201.824 1.388-7.369-4.308-14.176-11.807-14.176h-49.084c-5.57 0-10.377 3.842-11.676 9.259C408.593 374.592 339.069 432 256 432z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSyncAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSyncAlt.js new file mode 100644 index 000000000..b715612c1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faSyncAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'sync-alt', icon: [512, 512, [], "f2f1", "M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTable.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTable.js new file mode 100644 index 000000000..e70683cc9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTable.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'table', icon: [512, 512, [], "f0ce", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTablet.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTablet.js new file mode 100644 index 000000000..5485e2b49 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTablet.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tablet', icon: [448, 512, [], "f10a", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTabletAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTabletAlt.js new file mode 100644 index 000000000..9f619c203 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTabletAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tablet-alt', icon: [448, 512, [], "f3fa", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTachometerAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTachometerAlt.js new file mode 100644 index 000000000..19c532946 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTachometerAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tachometer-alt', icon: [576, 512, [], "f3fd", "M75.694 480a48.02 48.02 0 0 1-42.448-25.571C12.023 414.3 0 368.556 0 320 0 160.942 128.942 32 288 32s288 128.942 288 288c0 48.556-12.023 94.3-33.246 134.429A48.018 48.018 0 0 1 500.306 480H75.694zM512 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zM288 128c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32zM64 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm65.608-158.392c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm316.784 0c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm-87.078 31.534c-12.627-4.04-26.133 2.92-30.173 15.544l-45.923 143.511C250.108 322.645 224 350.264 224 384c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-19.773-8.971-37.447-23.061-49.187l45.919-143.498c4.039-12.625-2.92-26.133-15.544-30.173z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTag.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTag.js new file mode 100644 index 000000000..367fa2749 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTag.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tag', icon: [512, 512, [], "f02b", "M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTags.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTags.js new file mode 100644 index 000000000..535afd8db --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTags.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tags', icon: [640, 512, [], "f02c", "M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTasks.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTasks.js new file mode 100644 index 000000000..63e309a0a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTasks.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tasks', icon: [512, 512, [], "f0ae", "M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTaxi.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTaxi.js new file mode 100644 index 000000000..de168bae5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTaxi.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'taxi', icon: [512, 512, [], "f1ba", "M461.951 243.865l-21.816-87.268A79.885 79.885 0 0 0 362.522 96H352V56c0-13.255-10.745-24-24-24H184c-13.255 0-24 10.745-24 24v40h-10.522a79.885 79.885 0 0 0-77.612 60.597L50.05 243.865C25.515 252.823 8 276.366 8 304v48c0 20.207 9.374 38.214 24 49.943V456c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-54.057c14.626-11.729 24-29.737 24-49.943v-48c0-27.634-17.515-51.177-42.049-60.135zM149.478 160h213.045a15.975 15.975 0 0 1 15.522 12.12l16.97 67.88h-278.03l16.97-67.881A15.976 15.976 0 0 1 149.478 160zM132 336c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm320 0c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTerminal.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTerminal.js new file mode 100644 index 000000000..12f15dd86 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTerminal.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'terminal', icon: [640, 512, [], "f120", "M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextHeight.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextHeight.js new file mode 100644 index 000000000..6e8691098 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextHeight.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'text-height', icon: [576, 512, [], "f034", "M16 32h288c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96h-54.761v320H232c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H88c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm475.308 4.685l79.995 80.001C581.309 126.693 574.297 144 559.99 144H512v224h48c15.639 0 20.635 17.991 11.313 27.314l-79.995 80.001c-6.247 6.247-16.381 6.245-22.626 0l-79.995-80.001C378.691 385.307 385.703 368 400.01 368H448V144h-48c-15.639 0-20.635-17.991-11.313-27.314l79.995-80.001c6.247-6.248 16.381-6.245 22.626 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextWidth.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextWidth.js new file mode 100644 index 000000000..b556f3f67 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTextWidth.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'text-width', icon: [448, 512, [], "f035", "M16 32h416c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96H261.743v128H296c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H152c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm427.315 340.682l-80.001-79.995C353.991 283.365 336 288.362 336 304v48H112v-47.99c0-14.307-17.307-21.319-27.314-11.313L4.685 372.692c-6.245 6.245-6.247 16.379 0 22.626l80.001 79.995C94.009 484.635 112 479.638 112 464v-48h224v47.99c0 14.307 17.307 21.319 27.314 11.313l80.001-79.995c6.245-6.245 6.248-16.379 0-22.626z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTh.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTh.js new file mode 100644 index 000000000..73caa9edd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTh.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'th', icon: [512, 512, [], "f00a", "M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThLarge.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThLarge.js new file mode 100644 index 000000000..0adebe060 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThLarge.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'th-large', icon: [512, 512, [], "f009", "M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThList.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThList.js new file mode 100644 index 000000000..1c2829d78 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThList.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'th-list', icon: [512, 512, [], "f00b", "M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerEmpty.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerEmpty.js new file mode 100644 index 000000000..116b18e1c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerEmpty.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thermometer-empty', icon: [256, 512, [], "f2cb", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerFull.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerFull.js new file mode 100644 index 000000000..d9c943e69 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerFull.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thermometer-full', icon: [256, 512, [], "f2c7", "M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerHalf.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerHalf.js new file mode 100644 index 000000000..75eed3327 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerHalf.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thermometer-half', icon: [256, 512, [], "f2c9", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerQuarter.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerQuarter.js new file mode 100644 index 000000000..a0597dc33 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerQuarter.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thermometer-quarter', icon: [256, 512, [], "f2ca", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerThreeQuarters.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerThreeQuarters.js new file mode 100644 index 000000000..241be575b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThermometerThreeQuarters.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thermometer-three-quarters', icon: [256, 512, [], "f2c8", "M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsDown.js new file mode 100644 index 000000000..1724ffbc6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsUp.js new file mode 100644 index 000000000..ceeb3e4d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbsUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbtack.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbtack.js new file mode 100644 index 000000000..14dbee1cf --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faThumbtack.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'thumbtack', icon: [384, 512, [], "f08d", "M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTicketAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTicketAlt.js new file mode 100644 index 000000000..f093b9774 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTicketAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'ticket-alt', icon: [576, 512, [], "f3ff", "M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimes.js new file mode 100644 index 000000000..5808ff62c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'times', icon: [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimesCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimesCircle.js new file mode 100644 index 000000000..c984ba1c8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTimesCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTint.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTint.js new file mode 100644 index 000000000..1b7cf6565 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTint.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tint', icon: [384, 512, [], "f043", "M192 512c-98.435 0-178.087-79.652-178.087-178.087 0-111.196 101.194-154.065 148.522-311.825 9.104-30.116 51.099-28.778 59.13 0 47.546 158.486 148.522 200.069 148.522 311.825C370.087 432.348 290.435 512 192 512zm-42.522-171.826c-1.509-5.533-9.447-5.532-10.956 0-9.223 29.425-27.913 37.645-27.913 58.435C110.609 417.13 125.478 432 144 432s33.391-14.87 33.391-33.391c0-20.839-18.673-28.956-27.913-58.435z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOff.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOff.js new file mode 100644 index 000000000..2bac1db3f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOff.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'toggle-off', icon: [576, 512, [], "f204", "M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOn.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOn.js new file mode 100644 index 000000000..6563dc59c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faToggleOn.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'toggle-on', icon: [576, 512, [], "f205", "M576 256c0 106.039-85.961 192-192 192H192C85.961 448 0 362.039 0 256S85.961 64 192 64h192c106.039 0 192 85.961 192 192zM384 128c-70.741 0-128 57.249-128 128 0 70.741 57.249 128 128 128 70.741 0 128-57.249 128-128 0-70.741-57.249-128-128-128"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrademark.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrademark.js new file mode 100644 index 000000000..cd81ecb85 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrademark.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'trademark', icon: [640, 512, [], "f25c", "M97.119 163.133H12c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h248.559c6.627 0 12 5.373 12 12v43.133c0 6.627-5.373 12-12 12H175.44V404c0 6.627-5.373 12-12 12h-54.322c-6.627 0-12-5.373-12-12V163.133zM329.825 96h65.425a12 12 0 0 1 11.346 8.093l43.759 127.068c7.161 20.588 16.111 52.812 16.111 52.812h.896s8.95-32.224 16.111-52.812l43.758-127.068A12 12 0 0 1 538.577 96h65.41a12 12 0 0 1 11.961 11.03l24.012 296c.567 6.987-4.951 12.97-11.961 12.97h-54.101a12 12 0 0 1-11.972-11.182l-9.082-132.93c-1.79-24.168 0-53.706 0-53.706h-.896s-10.741 33.566-17.902 53.706l-30.7 84.731a12 12 0 0 1-11.282 7.912h-50.302a12 12 0 0 1-11.282-7.912l-30.7-84.731c-7.161-20.14-17.903-53.706-17.903-53.706h-.895s1.79 29.538 0 53.706l-9.082 132.93c-.428 6.295-5.66 11.182-11.97 11.182H305.4c-7.017 0-12.536-5.994-11.959-12.987l24.425-296A11.999 11.999 0 0 1 329.825 96z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrain.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrain.js new file mode 100644 index 000000000..55435d466 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrain.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'train', icon: [448, 512, [], "f238", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgender.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgender.js new file mode 100644 index 000000000..59f44391d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgender.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'transgender', icon: [384, 512, [], "f224", "M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgenderAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgenderAlt.js new file mode 100644 index 000000000..a89dfe91f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTransgenderAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'transgender-alt', icon: [480, 512, [], "f225", "M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrash.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrash.js new file mode 100644 index 000000000..cf914dde3 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrash.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'trash', icon: [448, 512, [], "f1f8", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm415.2 56.7L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32.8 140.7c-.4-6.9 5.1-12.7 12-12.7h358.5c6.8 0 12.3 5.8 11.9 12.7z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrashAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrashAlt.js new file mode 100644 index 000000000..d1003ed32 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrashAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTree.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTree.js new file mode 100644 index 000000000..746d2229a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTree.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tree', icon: [384, 512, [], "f1bb", "M377.33 375.429L293.906 288H328c21.017 0 31.872-25.207 17.448-40.479L262.79 160H296c20.878 0 31.851-24.969 17.587-40.331l-104-112.003c-9.485-10.214-25.676-10.229-35.174 0l-104 112.003C56.206 134.969 67.037 160 88 160h33.21l-82.659 87.521C24.121 262.801 34.993 288 56 288h34.094L6.665 375.429C-7.869 390.655 2.925 416 24.025 416H144c0 32.781-11.188 49.26-33.995 67.506C98.225 492.93 104.914 512 120 512h144c15.086 0 21.776-19.069 9.995-28.494-19.768-15.814-33.992-31.665-33.995-67.496V416h119.97c21.05 0 31.929-25.309 17.36-40.571z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrophy.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrophy.js new file mode 100644 index 000000000..821da60b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTrophy.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'trophy', icon: [576, 512, [], "f091", "M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTruck.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTruck.js new file mode 100644 index 000000000..a4f88800d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTruck.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'truck', icon: [640, 512, [], "f0d1", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTty.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTty.js new file mode 100644 index 000000000..95fe2fbe2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTty.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tty', icon: [512, 512, [], "f1e4", "M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTv.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTv.js new file mode 100644 index 000000000..e95c6c011 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faTv.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'tv', icon: [640, 512, [], "f26c", "M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUmbrella.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUmbrella.js new file mode 100644 index 000000000..bf8e6855d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUmbrella.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'umbrella', icon: [576, 512, [], "f0e9", "M557.011 267.631c-51.432-45.217-107.572-43.698-158.567 30.731-5.298 7.861-14.906 7.165-19.736 0-2.483-3.624-32.218-60.808-90.708-60.808-45.766 0-70.542 31.378-90.709 60.808-4.829 7.165-14.436 7.861-19.734 0-50.904-74.285-106.613-76.406-158.567-30.731-10.21 8.264-20.912-1.109-18.696-9.481C32.146 134.573 158.516 64.612 288.001 64.612c128.793 0 256.546 69.961 287.706 193.538 2.206 8.322-8.426 17.793-18.696 9.481zM256 261.001V416c0 17.645-14.355 32-32 32s-32-14.355-32-32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 52.935 43.065 96 96 96s96-43.065 96-96V261.288c-21.836-10.806-45.425-9.737-64-.287zm64-211.007V32c0-17.673-14.327-32-32-32s-32 14.327-32 32v17.987a372.105 372.105 0 0 1 64 .007z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnderline.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnderline.js new file mode 100644 index 000000000..f9c12f91a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnderline.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'underline', icon: [448, 512, [], "f0cd", "M224.264 388.24c-91.669 0-156.603-51.165-156.603-151.392V64H39.37c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h137.39c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.813v172.848c0 53.699 28.314 79.444 76.317 79.444 46.966 0 75.796-25.434 75.796-79.965V64h-28.291c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h136.868c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.291v172.848c0 99.405-64.881 151.392-156.082 151.392zM16 448h416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndo.js new file mode 100644 index 000000000..79a279ed6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'undo', icon: [512, 512, [], "f0e2", "M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndoAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndoAlt.js new file mode 100644 index 000000000..f3c0ae313 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUndoAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'undo-alt', icon: [512, 512, [], "f2ea", "M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversalAccess.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversalAccess.js new file mode 100644 index 000000000..7b4051e20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversalAccess.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'universal-access', icon: [512, 512, [], "f29a", "M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversity.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversity.js new file mode 100644 index 000000000..c570d98e8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUniversity.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'university', icon: [512, 512, [], "f19c", "M480 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-12H8a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 480 128zm-24 304H24c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM64 192v192H44c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-20V192h-64v192h-32V192h-64v192h-32V192h-64v192h-32V192H64z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlink.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlink.js new file mode 100644 index 000000000..80eee5d3c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlink.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'unlink', icon: [512, 512, [], "f127", "M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlock.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlock.js new file mode 100644 index 000000000..6ba6793ba --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlock.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'unlock', icon: [448, 512, [], "f09c", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlockAlt.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlockAlt.js new file mode 100644 index 000000000..06f4a2d81 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUnlockAlt.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'unlock-alt', icon: [448, 512, [], "f13e", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUpload.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUpload.js new file mode 100644 index 000000000..64d76eafb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUpload.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'upload', icon: [512, 512, [], "f093", "M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUser.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUser.js new file mode 100644 index 000000000..a9ac92155 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUser.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user', icon: [512, 512, [], "f007", "M96 160C96 71.634 167.635 0 256 0s160 71.634 160 160-71.635 160-160 160S96 248.366 96 160zm304 192h-28.556c-71.006 42.713-159.912 42.695-230.888 0H112C50.144 352 0 402.144 0 464v24c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24v-24c0-61.856-50.144-112-112-112z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserCircle.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserCircle.js new file mode 100644 index 000000000..611b10e72 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserCircle.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zM144 208c0-61.856 50.144-112 112-112s112 50.144 112 112-50.144 112-112 112-112-50.144-112-112zm268.408 172.663c-80.346 100.411-232.375 100.53-312.817 0C117.003 362.973 141.218 352 168 352h18.204c44.03 21.336 95.495 21.368 139.592 0H344c26.782 0 50.997 10.973 68.408 28.663z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserMd.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserMd.js new file mode 100644 index 000000000..dba6cd13b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserMd.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user-md', icon: [448, 512, [], "f0f0", "M96 128C96 57.308 153.308 0 224 0s128 57.308 128 128-57.308 128-128 128S96 198.692 96 128zm256 160v33.61c36.471 7.433 64 39.756 64 78.39v49.441c0 11.44-8.075 21.29-19.293 23.534l-21.802 4.361c-6.499 1.3-12.821-2.915-14.12-9.414l-1.569-7.845c-1.3-6.499 2.915-12.821 9.414-14.12l15.37-3.074v-42.078c0-26.283-20.793-48.297-47.071-48.797C310.039 351.498 288 373.224 288 400v42.883l15.371 3.074c6.499 1.3 10.713 7.622 9.414 14.12l-1.569 7.845c-1.3 6.499-7.622 10.714-14.12 9.414l-21.802-4.361C264.075 470.732 256 460.882 256 449.441V400c0-38.634 27.529-70.957 64-78.39V288h-22.624c-45.669 20.945-99.331 21.749-146.752 0H128v66.025c28.495 7.361 49.359 33.906 47.931 64.977-1.506 32.778-28.097 59.392-60.874 60.926C78.383 481.644 48 452.303 48 416c0-29.767 20.427-54.852 48-61.975V288c-53.019 0-96 42.981-96 96v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-53.019-42.981-96-96-96zM80 416c0 17.645 14.355 32 32 32s32-14.355 32-32-14.355-32-32-32-32 14.355-32 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserPlus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserPlus.js new file mode 100644 index 000000000..b9fe30902 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserPlus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user-plus', icon: [640, 512, [], "f234", "M616 332c0-6.627-5.373-12-12-12h-60v-60c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v60h-60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h60v60c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-60h60c6.627 0 12-5.373 12-12v-40zM448 444v15c0 11.598-9.402 21-21 21H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350a98.09 98.09 0 0 1 26 3.493V372c0 24.262 19.738 44 44 44h25.519c2.768 12.064 2.481 20.659 2.481 28zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserSecret.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserSecret.js new file mode 100644 index 000000000..0438e82c7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserSecret.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user-secret', icon: [448, 512, [], "f21b", "M388.829 295.324l20.972-55.052c2.992-7.854-2.809-16.272-11.214-16.272H340.39c7.45-16.236 11.61-34.297 11.61-53.333 0-3.631-.16-7.224-.456-10.778C391.083 152.074 416 140.684 416 128c0-13.263-27.231-25.112-69.947-32.937-9.185-32.805-27.178-65.797-40.714-82.85-9.452-11.908-25.873-15.634-39.471-8.834l-27.557 13.779a31.997 31.997 0 0 1-28.622 0l-27.557-13.78c-13.599-6.799-30.02-3.074-39.471 8.834-13.536 17.053-31.529 50.045-40.714 82.85C59.231 102.888 32 114.737 32 128c0 12.684 24.917 24.074 64.456 31.889A129.362 129.362 0 0 0 96 170.667c0 19.037 4.159 37.098 11.608 53.333h-57.41c-8.615 0-14.423 8.809-11.029 16.727l22.906 53.447C25.799 307.882 0 342.925 0 384v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-39.97-24.43-74.231-59.171-88.676zM184 488l-48-192 48 24 24 40-24 128zm80 0l-24-128 24-40 48-24-48 192zm54.778-303.746c-.008.043-4.299 3.231-5.125 5.771-3.861 11.864-7.026 24.572-16.514 33.359-10.071 9.327-47.957 22.405-63.996-25.029-2.837-8.395-15.447-8.398-18.285 0-16.963 50.168-56.019 32.417-63.996 25.029-9.488-8.786-12.653-21.495-16.514-33.359-.826-2.54-5.118-5.728-5.125-5.771-.554-2.925-.981-5.884-1.22-8.85-.309-3.848 10.078-3.658 11.078-3.747 26.303-2.326 52.303-.579 78.023 5.497 2.563.606 11.553.529 13.793 0 25.72-6.076 51.72-7.824 78.023-5.497 1.002.089 11.387-.102 11.078 3.747-.239 2.966-.666 5.925-1.22 8.85z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserTimes.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserTimes.js new file mode 100644 index 000000000..34c5451a2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUserTimes.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'user-times', icon: [640, 512, [], "f235", "M599.681 411.397c4.686-4.686 4.686-12.284 0-16.971L557.255 352l42.426-42.426c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.971 0L512 306.745l-42.426-42.426c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971L466.745 352l-42.426 42.426c-4.686 4.686-4.686 12.284 0 16.971l28.284 28.284c4.686 4.686 12.284 4.686 16.971 0L512 397.255l42.426 42.426c4.686 4.686 12.284 4.686 16.971 0l28.284-28.284zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172zm359.737 299.645C439.904 476.712 433.843 480 427 480H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350c23.366 0 44.818 8.183 61.658 21.832l-9.967 9.967c-17.156 17.156-17.156 45.07 0 62.225l28.284 28.284a43.946 43.946 0 0 0 13.762 9.337z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUsers.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUsers.js new file mode 100644 index 000000000..20a8bd6d6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUsers.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'users', icon: [640, 512, [], "f0c0", "M220 164c0-55.229 44.772-100 100-100s100 44.771 100 100-44.772 100-100 100-100-44.771-100-100zM48 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm384 0c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-22 76c38.66 0 70 31.34 70 70v70c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24v-70c0-38.66 31.34-70 70-70h17.848c44.364 26.687 99.93 26.693 144.305 0H410m-282 70c0-11.975 2.081-23.472 5.889-34.156-21.93 1.152-44.122-4.121-63.611-15.844H56c-30.928 0-56 25.072-56 56v32c0 13.255 10.745 24 24 24h104v-62zm456-50h-14.278c-19.495 11.727-41.686 16.996-63.611 15.844A101.542 101.542 0 0 1 512 354v62h104c13.255 0 24-10.745 24-24v-32c0-30.928-25.072-56-56-56z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensilSpoon.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensilSpoon.js new file mode 100644 index 000000000..dc8a5962d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensilSpoon.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'utensil-spoon', icon: [512, 512, [], "f2e5", "M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensils.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensils.js new file mode 100644 index 000000000..26b4e147f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faUtensils.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'utensils', icon: [416, 512, [], "f2e7", "M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenus.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenus.js new file mode 100644 index 000000000..ffd98352f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenus.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'venus', icon: [288, 512, [], "f221", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusDouble.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusDouble.js new file mode 100644 index 000000000..dad880363 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusDouble.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'venus-double', icon: [512, 512, [], "f226", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusMars.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusMars.js new file mode 100644 index 000000000..835994040 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVenusMars.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'venus-mars', icon: [576, 512, [], "f228", "M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVideo.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVideo.js new file mode 100644 index 000000000..4bb56b927 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVideo.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'video', icon: [576, 512, [], "f03d", "M528 64h-12.118a48 48 0 0 0-33.941 14.059L384 176v-64c0-26.51-21.49-48-48-48H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-64l97.941 97.941A48 48 0 0 0 515.882 448H528c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeDown.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeDown.js new file mode 100644 index 000000000..0d6814192 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeDown.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'volume-down', icon: [384, 512, [], "f027", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zM384 256c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeOff.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeOff.js new file mode 100644 index 000000000..15829556b --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeOff.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'volume-off', icon: [256, 512, [], "f026", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeUp.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeUp.js new file mode 100644 index 000000000..8ba17bac9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faVolumeUp.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'volume-up', icon: [576, 512, [], "f028", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zm182.056-77.876C422.982.92 403.283 5.668 394.061 20.745c-9.221 15.077-4.473 34.774 10.604 43.995C468.967 104.063 512 174.983 512 256c0 73.431-36.077 142.292-96.507 184.206-14.522 10.072-18.129 30.01-8.057 44.532 10.076 14.528 30.016 18.126 44.531 8.057C529.633 438.927 576 350.406 576 256c0-103.244-54.579-194.877-137.944-245.859zM480 256c0-68.547-36.15-129.777-91.957-163.901-15.076-9.22-34.774-4.471-43.994 10.607-9.22 15.078-4.471 34.774 10.607 43.994C393.067 170.188 416 211.048 416 256c0 41.964-20.62 81.319-55.158 105.276-14.521 10.073-18.128 30.01-8.056 44.532 6.216 8.96 16.185 13.765 26.322 13.765a31.862 31.862 0 0 0 18.21-5.709C449.091 377.953 480 318.938 480 256zm-96 0c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWheelchair.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWheelchair.js new file mode 100644 index 000000000..f17a5e591 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWheelchair.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'wheelchair', icon: [512, 512, [], "f193", "M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWifi.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWifi.js new file mode 100644 index 000000000..942e68b86 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWifi.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'wifi', icon: [640, 512, [], "f1eb", "M384 416c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm136.659-124.443c6.465-6.465 6.245-17.065-.564-23.167-113.793-101.985-286.526-101.869-400.19 0-6.809 6.102-7.029 16.702-.564 23.167l34.006 34.006c5.927 5.927 15.464 6.32 21.769.796 82.88-72.609 207.074-72.447 289.768 0 6.305 5.524 15.842 5.132 21.769-.796l34.006-34.006zm112.11-113.718c6.385-6.385 6.254-16.816-.35-22.973-175.768-163.86-449.134-163.8-624.837 0-6.604 6.157-6.735 16.589-.35 22.973l33.966 33.966c6.095 6.095 15.891 6.231 22.224.383 144.763-133.668 368.356-133.702 513.156 0 6.333 5.848 16.129 5.712 22.224-.383l33.967-33.966z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowClose.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowClose.js new file mode 100644 index 000000000..34b86462f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowClose.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMaximize.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMaximize.js new file mode 100644 index 000000000..b1730ef27 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMaximize.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMinimize.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMinimize.js new file mode 100644 index 000000000..0ef1be784 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowMinimize.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'window-minimize', icon: [512, 512, [], "f2d1", "M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowRestore.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowRestore.js new file mode 100644 index 000000000..5ca187a91 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWindowRestore.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWonSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWonSign.js new file mode 100644 index 000000000..dd1e558b9 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWonSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'won-sign', icon: [576, 512, [], "f159", "M564 192c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-48.028l18.572-80.61c1.732-7.518-3.978-14.694-11.693-14.694h-46.107a11.998 11.998 0 0 0-11.736 9.5L450.73 128H340.839l-19.725-85.987a12 12 0 0 0-11.696-9.317H265.43a12 12 0 0 0-11.687 9.277L233.696 128H124.975L107.5 42.299a12 12 0 0 0-11.758-9.602H53.628c-7.686 0-13.39 7.124-11.709 14.624L60 128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h62.342l7.171 32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h83.856l40.927 182.624A12 12 0 0 0 148.492 480h56.767c5.583 0 10.428-3.85 11.689-9.288L259.335 288h55.086l42.386 182.712A12 12 0 0 0 368.496 480h56.826a12 12 0 0 0 11.694-9.306L479.108 288H564c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-70.146l7.373-32H564zm-425.976 0h80.757l-7.457 32h-66.776l-6.524-32zm45.796 150.029c-6.194 25.831-6.758 47.25-7.321 47.25h-1.126s-1.689-22.05-6.758-47.25L157.599 288h38.812l-12.591 54.029zM274.182 224l1.996-8.602c1.856-7.962 3.457-15.968 4.803-23.398h11.794c1.347 7.43 2.947 15.436 4.803 23.398l1.996 8.602h-25.392zm130.959 118.029c-5.068 25.2-6.758 47.25-6.758 47.25h-1.126c-.563 0-1.126-21.42-7.321-47.25L377.542 288h39.107l-11.508 54.029zM430.281 224h-67.42l-7.34-32h81.577l-6.817 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWrench.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWrench.js new file mode 100644 index 000000000..9fc9ad6cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faWrench.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'wrench', icon: [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faYenSign.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faYenSign.js new file mode 100644 index 000000000..55f559739 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/faYenSign.js @@ -0,0 +1 @@ +module.exports = { prefix: 'fas', iconName: 'yen-sign', icon: [384, 512, [], "f157", "M351.208 32h-65.277a12 12 0 0 0-10.778 6.724l-55.39 113.163c-14.513 34.704-27.133 71.932-27.133 71.932h-1.262s-12.62-37.228-27.133-71.932l-55.39-113.163A11.997 11.997 0 0 0 98.068 32H32.792c-9.057 0-14.85 9.65-10.59 17.643L102.322 200H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h88.162L152 293.228V320H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h108v92c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-92h108c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12H232v-26.772L251.838 256H340c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12h-58.322l80.12-150.357C366.058 41.65 360.266 32 351.208 32z"] }; \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.es.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.es.js new file mode 100644 index 000000000..9f7ff9539 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.es.js @@ -0,0 +1,938 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +var prefix = "fas"; +var faAddressBook = { prefix: 'fas', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H80C53.49 0 32 21.49 32 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zM224 96c53.019 0 96 42.981 96 96s-42.981 96-96 96-96-42.981-96-96 42.981-96 96-96zm128 304c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48v-48.711c0-20.994 13.644-39.553 33.683-45.815l22.954-7.173C173.563 312.413 198.198 320 224 320s50.437-7.587 71.363-21.699l22.954 7.173C338.356 311.736 352 330.295 352 351.289V400z"] }; +var faAddressCard = { prefix: 'fas', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-288 64c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm112 232c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-29.897a24 24 0 0 1 17.407-23.077l28.938-8.268C129.323 312.549 152.087 320 176 320s46.677-7.451 65.656-21.241l28.938 8.268A23.999 23.999 0 0 1 288 330.103V360zm160-52c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8z"] }; +var faAdjust = { prefix: 'fas', iconName: 'adjust', icon: [512, 512, [], "f042", "M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z"] }; +var faAlignCenter = { prefix: 'fas', iconName: 'align-center', icon: [448, 512, [], "f037", "M352 44v40c0 8.837-7.163 16-16 16H112c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h224c8.837 0 16 7.163 16 16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm320-200H112c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; +var faAlignJustify = { prefix: 'fas', iconName: 'align-justify', icon: [448, 512, [], "f039", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm16 144h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0-128h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faAlignLeft = { prefix: 'fas', iconName: 'align-left', icon: [448, 512, [], "f036", "M288 44v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16zM0 172v40c0 8.837 7.163 16 16 16h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16zm16 312h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm256-200H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; +var faAlignRight = { prefix: 'fas', iconName: 'align-right', icon: [448, 512, [], "f038", "M160 84V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H176c-8.837 0-16-7.163-16-16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faAmbulance = { prefix: 'fas', iconName: 'ambulance', icon: [640, 512, [], "f0f9", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm32-288v32c0 6.627-5.373 12-12 12h-56v56c0 6.627-5.373 12-12 12h-32c-6.627 0-12-5.373-12-12v-56h-56c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h56v-56c0-6.627 5.373-12 12-12h32c6.627 0 12 5.373 12 12v56h56c6.627 0 12 5.373 12 12z"] }; +var faAmericanSignLanguageInterpreting = { prefix: 'fas', iconName: 'american-sign-language-interpreting', icon: [640, 512, [], "f2a3", "M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z"] }; +var faAnchor = { prefix: 'fas', iconName: 'anchor', icon: [576, 512, [], "f13d", "M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z"] }; +var faAngleDoubleDown = { prefix: 'fas', iconName: 'angle-double-down', icon: [320, 512, [], "f103", "M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"] }; +var faAngleDoubleLeft = { prefix: 'fas', iconName: 'angle-double-left', icon: [448, 512, [], "f100", "M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z"] }; +var faAngleDoubleRight = { prefix: 'fas', iconName: 'angle-double-right', icon: [448, 512, [], "f101", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z"] }; +var faAngleDoubleUp = { prefix: 'fas', iconName: 'angle-double-up', icon: [320, 512, [], "f102", "M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"] }; +var faAngleDown = { prefix: 'fas', iconName: 'angle-down', icon: [320, 512, [], "f107", "M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"] }; +var faAngleLeft = { prefix: 'fas', iconName: 'angle-left', icon: [256, 512, [], "f104", "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"] }; +var faAngleRight = { prefix: 'fas', iconName: 'angle-right', icon: [256, 512, [], "f105", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"] }; +var faAngleUp = { prefix: 'fas', iconName: 'angle-up', icon: [320, 512, [], "f106", "M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"] }; +var faArchive = { prefix: 'fas', iconName: 'archive', icon: [512, 512, [], "f187", "M488 128H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h464c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24zm-8 328V184c0-13.255-10.745-24-24-24H56c-13.255 0-24 10.745-24 24v272c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24zM308 256H204c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12z"] }; +var faArrowAltCircleDown = { prefix: 'fas', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z"] }; +var faArrowAltCircleLeft = { prefix: 'fas', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z"] }; +var faArrowAltCircleRight = { prefix: 'fas', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z"] }; +var faArrowAltCircleUp = { prefix: 'fas', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z"] }; +var faArrowCircleDown = { prefix: 'fas', iconName: 'arrow-circle-down', icon: [512, 512, [], "f0ab", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z"] }; +var faArrowCircleLeft = { prefix: 'fas', iconName: 'arrow-circle-left', icon: [512, 512, [], "f0a8", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z"] }; +var faArrowCircleRight = { prefix: 'fas', iconName: 'arrow-circle-right', icon: [512, 512, [], "f0a9", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"] }; +var faArrowCircleUp = { prefix: 'fas', iconName: 'arrow-circle-up', icon: [512, 512, [], "f0aa", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z"] }; +var faArrowDown = { prefix: 'fas', iconName: 'arrow-down', icon: [448, 512, [], "f063", "M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"] }; +var faArrowLeft = { prefix: 'fas', iconName: 'arrow-left', icon: [448, 512, [], "f060", "M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"] }; +var faArrowRight = { prefix: 'fas', iconName: 'arrow-right', icon: [448, 512, [], "f061", "M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"] }; +var faArrowUp = { prefix: 'fas', iconName: 'arrow-up', icon: [448, 512, [], "f062", "M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"] }; +var faArrowsAlt = { prefix: 'fas', iconName: 'arrows-alt', icon: [512, 512, [], "f0b2", "M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z"] }; +var faArrowsAltH = { prefix: 'fas', iconName: 'arrows-alt-h', icon: [512, 512, [], "f337", "M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z"] }; +var faArrowsAltV = { prefix: 'fas', iconName: 'arrows-alt-v', icon: [256, 512, [], "f338", "M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"] }; +var faAssistiveListeningSystems = { prefix: 'fas', iconName: 'assistive-listening-systems', icon: [512, 512, [], "f2a2", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z"] }; +var faAsterisk = { prefix: 'fas', iconName: 'asterisk', icon: [512, 512, [], "f069", "M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z"] }; +var faAt = { prefix: 'fas', iconName: 'at', icon: [512, 512, [], "f1fa", "M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"] }; +var faAudioDescription = { prefix: 'fas', iconName: 'audio-description', icon: [512, 512, [], "f29e", "M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z"] }; +var faBackward = { prefix: 'fas', iconName: 'backward', icon: [512, 512, [], "f04a", "M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z"] }; +var faBalanceScale = { prefix: 'fas', iconName: 'balance-scale', icon: [640, 512, [], "f24e", "M352 448h168c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H120c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h168V153.324C264.469 143.04 246.836 121.778 241.603 96H120c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h135.999C270.594 12.57 293.828 0 320 0s49.406 12.57 64.001 32H520c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H398.397c-5.233 25.778-22.866 47.04-46.397 57.324V448zm287.981-112c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C381.94 328.75 384.019 320.331 384.019 336H384c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM512 176l72 144H440l72-144zM255.981 336c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C-2.06 328.75.019 320.331.019 336H0c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM128 176l72 144H56l72-144z"] }; +var faBan = { prefix: 'fas', iconName: 'ban', icon: [512, 512, [], "f05e", "M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"] }; +var faBarcode = { prefix: 'fas', iconName: 'barcode', icon: [512, 512, [], "f02a", "M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z"] }; +var faBars = { prefix: 'fas', iconName: 'bars', icon: [448, 512, [], "f0c9", "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faBath = { prefix: 'fas', iconName: 'bath', icon: [512, 512, [], "f2cd", "M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; +var faBatteryEmpty = { prefix: 'fas', iconName: 'battery-empty', icon: [640, 512, [], "f244", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z"] }; +var faBatteryFull = { prefix: 'fas', iconName: 'battery-full', icon: [640, 512, [], "f240", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"] }; +var faBatteryHalf = { prefix: 'fas', iconName: 'battery-half', icon: [640, 512, [], "f242", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z"] }; +var faBatteryQuarter = { prefix: 'fas', iconName: 'battery-quarter', icon: [640, 512, [], "f243", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z"] }; +var faBatteryThreeQuarters = { prefix: 'fas', iconName: 'battery-three-quarters', icon: [640, 512, [], "f241", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z"] }; +var faBed = { prefix: 'fas', iconName: 'bed', icon: [576, 512, [], "f236", "M552 288c13.255 0 24 10.745 24 24v136h-96v-64H96v64H0V88c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v200h456zM192 96c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80zm384 128c0-53.019-42.981-96-96-96H312c-13.255 0-24 10.745-24 24v104h288v-32z"] }; +var faBeer = { prefix: 'fas', iconName: 'beer', icon: [448, 512, [], "f0fc", "M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z"] }; +var faBell = { prefix: 'fas', iconName: 'bell', icon: [448, 512, [], "f0f3", "M433.884 366.059C411.634 343.809 384 316.118 384 208c0-79.394-57.831-145.269-133.663-157.83A31.845 31.845 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 6.75 2.095 13.008 5.663 18.17C121.831 62.731 64 128.606 64 208c0 108.118-27.643 135.809-49.893 158.059C-16.042 396.208 5.325 448 48.048 448H160c0 35.346 28.654 64 64 64s64-28.654 64-64h111.943c42.638 0 64.151-51.731 33.941-81.941zM224 472a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16c0 13.234 10.766 24 24 24z"] }; +var faBellSlash = { prefix: 'fas', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M78.107 366.059C47.958 396.208 69.325 448 112.048 448H224c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h32.685L127.848 221.379c-2.198 97.078-28.439 123.378-49.741 144.68zM264 448c0 13.234 10.766 24 24 24a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16zm305.896 43.733l-10.762 12.086c-8.915 10.012-24.333 10.967-34.437 2.133L8.256 54.393C-1.848 45.558-2.811 30.28 6.104 20.267L16.865 8.181C25.781-1.831 41.199-2.786 51.303 6.049l113.81 99.512c24.017-28.778 57.946-48.996 96.55-55.39A31.85 31.85 0 0 1 256 32c0-17.673 14.327-32 32-32s32 14.327 32 32c0 6.75-2.095 13.008-5.663 18.17C390.169 62.731 448 128.606 448 208c0 108.118 27.634 135.809 49.884 158.059 12.149 12.149 15.923 27.776 13.33 42.121l56.53 49.427c10.104 8.835 11.067 24.113 2.152 34.126z"] }; +var faBicycle = { prefix: 'fas', iconName: 'bicycle', icon: [640, 512, [], "f206", "M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z"] }; +var faBinoculars = { prefix: 'fas', iconName: 'binoculars', icon: [512, 512, [], "f1e5", "M192 104H96V56c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v48zm224-48c0-13.255-10.745-24-24-24h-48c-13.255 0-24 10.745-24 24v48h96V56zM0 456c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H0v16zm88-328c-13.255 0-24 10.745-24 24C64 256 0 272 0 416h168V312c0-13.255 10.745-24 24-24V128H88zm256 328c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H344v16zM216 128v160h80V128h-80zm128 288h168c0-144-64-160-64-264 0-13.255-10.745-24-24-24H320v160c13.255 0 24 10.745 24 24v104z"] }; +var faBirthdayCake = { prefix: 'fas', iconName: 'birthday-cake', icon: [448, 512, [], "f1fd", "M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z"] }; +var faBlind = { prefix: 'fas', iconName: 'blind', icon: [384, 512, [], "f29d", "M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z"] }; +var faBold = { prefix: 'fas', iconName: 'bold', icon: [384, 512, [], "f032", "M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z"] }; +var faBolt = { prefix: 'fas', iconName: 'bolt', icon: [320, 512, [], "f0e7", "M295.973 160H180.572L215.19 30.184C219.25 14.956 207.756 0 192 0H56C43.971 0 33.8 8.905 32.211 20.828l-31.996 240C-1.704 275.217 9.504 288 24.004 288h118.701L96.646 482.466C93.05 497.649 104.659 512 119.992 512c8.35 0 16.376-4.374 20.778-11.978l175.973-303.997c9.244-15.967-2.288-36.025-20.77-36.025z"] }; +var faBomb = { prefix: 'fas', iconName: 'bomb', icon: [512, 512, [], "f1e2", "M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z"] }; +var faBook = { prefix: 'fas', iconName: 'book', icon: [448, 512, [], "f02d", "M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"] }; +var faBookmark = { prefix: 'fas', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"] }; +var faBraille = { prefix: 'fas', iconName: 'braille', icon: [640, 512, [], "f2a1", "M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faBriefcase = { prefix: 'fas', iconName: 'briefcase', icon: [512, 512, [], "f0b1", "M320 288h192v144c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V288h192v20c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12v-20zm192-112v80H0v-80c0-26.51 21.49-48 48-48h80V80c0-26.51 21.49-48 48-48h160c26.51 0 48 21.49 48 48v48h80c26.51 0 48 21.49 48 48zM320 96H192v32h128V96z"] }; +var faBug = { prefix: 'fas', iconName: 'bug', icon: [512, 512, [], "f188", "M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z"] }; +var faBuilding = { prefix: 'fas', iconName: 'building', icon: [448, 512, [], "f1ad", "M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z"] }; +var faBullhorn = { prefix: 'fas', iconName: 'bullhorn', icon: [576, 512, [], "f0a1", "M576 224c0-20.896-13.36-38.666-32-45.258V64c0-35.346-28.654-64-64-64-64.985 56-142.031 128-272 128H48c-26.51 0-48 21.49-48 48v96c0 26.51 21.49 48 48 48h43.263c-18.742 64.65 2.479 116.379 18.814 167.44 1.702 5.32 5.203 9.893 9.922 12.88 20.78 13.155 68.355 15.657 93.773 5.151 16.046-6.633 19.96-27.423 7.522-39.537-18.508-18.026-30.136-36.91-19.795-60.858a12.278 12.278 0 0 0-1.045-11.673c-16.309-24.679-3.581-62.107 28.517-72.752C346.403 327.887 418.591 395.081 480 448c35.346 0 64-28.654 64-64V269.258c18.64-6.592 32-24.362 32-45.258zm-96 139.855c-54.609-44.979-125.033-92.94-224-104.982v-69.747c98.967-12.042 169.391-60.002 224-104.982v279.711z"] }; +var faBullseye = { prefix: 'fas', iconName: 'bullseye', icon: [512, 512, [], "f140", "M256 72c101.689 0 184 82.295 184 184 0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-101.689 82.295-184 184-184m0-64C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 184c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64m0-64c-70.692 0-128 57.308-128 128s57.308 128 128 128 128-57.308 128-128-57.308-128-128-128z"] }; +var faBus = { prefix: 'fas', iconName: 'bus', icon: [512, 512, [], "f207", "M512 152v80c0 13.255-10.745 24-24 24h-8v168c0 13.255-10.745 24-24 24h-8v40c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24v-40H160v40c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-40h-8c-13.255 0-24-10.745-24-24V256h-8c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h8V80C32 35.817 132.288 0 256 0s224 35.817 224 80v48h8c13.255 0 24 10.745 24 24zM112 320c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm32-56V120c0-13.255-10.745-24-24-24H104c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; +var faCalculator = { prefix: 'fas', iconName: 'calculator', icon: [448, 512, [], "f1ec", "M0 464V48C0 21.49 21.49 0 48 0h352c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm384-284V76c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v104c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12zM128 308v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm256 128V268c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-256 0v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm128-128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm0 128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faCalendar = { prefix: 'fas', iconName: 'calendar', icon: [448, 512, [], "f133", "M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z"] }; +var faCalendarAlt = { prefix: 'fas', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm116 204c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40z"] }; +var faCalendarCheck = { prefix: 'fas', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z"] }; +var faCalendarMinus = { prefix: 'fas', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z"] }; +var faCalendarPlus = { prefix: 'fas', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z"] }; +var faCalendarTimes = { prefix: 'fas', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z"] }; +var faCamera = { prefix: 'fas', iconName: 'camera', icon: [512, 512, [], "f030", "M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z"] }; +var faCameraRetro = { prefix: 'fas', iconName: 'camera-retro', icon: [512, 512, [], "f083", "M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z"] }; +var faCar = { prefix: 'fas', iconName: 'car', icon: [512, 512, [], "f1b9", "M499.991 168h-54.815l-7.854-20.944c-9.192-24.513-25.425-45.351-46.942-60.263S343.651 64 317.472 64H194.528c-26.18 0-51.391 7.882-72.908 22.793-21.518 14.912-37.75 35.75-46.942 60.263L66.824 168H12.009c-8.191 0-13.974 8.024-11.384 15.795l8 24A12 12 0 0 0 20.009 216h28.815l-.052.14C29.222 227.093 16 247.997 16 272v48c0 16.225 6.049 31.029 16 42.309V424c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-61.691c9.951-11.281 16-26.085 16-42.309v-48c0-24.003-13.222-44.907-32.772-55.86l-.052-.14h28.815a12 12 0 0 0 11.384-8.205l8-24c2.59-7.771-3.193-15.795-11.384-15.795zm-365.388 1.528C143.918 144.689 168 128 194.528 128h122.944c26.528 0 50.61 16.689 59.925 41.528L391.824 208H120.176l14.427-38.472zM88 328c-17.673 0-32-14.327-32-32 0-17.673 14.327-32 32-32s48 30.327 48 48-30.327 16-48 16zm336 0c-17.673 0-48 1.673-48-16 0-17.673 30.327-48 48-48s32 14.327 32 32c0 17.673-14.327 32-32 32z"] }; +var faCaretDown = { prefix: 'fas', iconName: 'caret-down', icon: [320, 512, [], "f0d7", "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"] }; +var faCaretLeft = { prefix: 'fas', iconName: 'caret-left', icon: [192, 512, [], "f0d9", "M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"] }; +var faCaretRight = { prefix: 'fas', iconName: 'caret-right', icon: [192, 512, [], "f0da", "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"] }; +var faCaretSquareDown = { prefix: 'fas', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z"] }; +var faCaretSquareLeft = { prefix: 'fas', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z"] }; +var faCaretSquareRight = { prefix: 'fas', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z"] }; +var faCaretSquareUp = { prefix: 'fas', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z"] }; +var faCaretUp = { prefix: 'fas', iconName: 'caret-up', icon: [320, 512, [], "f0d8", "M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"] }; +var faCartArrowDown = { prefix: 'fas', iconName: 'cart-arrow-down', icon: [576, 512, [], "f218", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z"] }; +var faCartPlus = { prefix: 'fas', iconName: 'cart-plus', icon: [576, 512, [], "f217", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z"] }; +var faCertificate = { prefix: 'fas', iconName: 'certificate', icon: [512, 512, [], "f0a3", "M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z"] }; +var faChartArea = { prefix: 'fas', iconName: 'chart-area', icon: [512, 512, [], "f1fe", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z"] }; +var faChartBar = { prefix: 'fas', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zm-308-44v-72c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V204c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V108c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; +var faChartLine = { prefix: 'fas', iconName: 'chart-line', icon: [512, 512, [], "f201", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z"] }; +var faChartPie = { prefix: 'fas', iconName: 'chart-pie', icon: [576, 512, [], "f200", "M288 12.3V240h227.7c6.9 0 12.3-5.8 12-12.7-6.4-122.4-104.5-220.6-227-227-6.9-.3-12.7 5.1-12.7 12zM552.7 288c6.9 0 12.3 5.8 12 12.7-2.8 53.2-23.2 105.6-61.2 147.8-4.6 5.1-12.6 5.4-17.5.5L325 288h227.7zM401 433c4.8 4.8 4.7 12.8-.4 17.3-42.6 38.4-99 61.7-160.8 61.7C107.6 511.9-.2 403.8 0 271.5.2 143.4 100.8 38.9 227.3 32.3c6.9-.4 12.7 5.1 12.7 12V272l161 161z"] }; +var faCheck = { prefix: 'fas', iconName: 'check', icon: [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"] }; +var faCheckCircle = { prefix: 'fas', iconName: 'check-circle', icon: [512, 512, [], "f058", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"] }; +var faCheckSquare = { prefix: 'fas', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z"] }; +var faChevronCircleDown = { prefix: 'fas', iconName: 'chevron-circle-down', icon: [512, 512, [], "f13a", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z"] }; +var faChevronCircleLeft = { prefix: 'fas', iconName: 'chevron-circle-left', icon: [512, 512, [], "f137", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z"] }; +var faChevronCircleRight = { prefix: 'fas', iconName: 'chevron-circle-right', icon: [512, 512, [], "f138", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z"] }; +var faChevronCircleUp = { prefix: 'fas', iconName: 'chevron-circle-up', icon: [512, 512, [], "f139", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"] }; +var faChevronDown = { prefix: 'fas', iconName: 'chevron-down', icon: [448, 512, [], "f078", "M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"] }; +var faChevronLeft = { prefix: 'fas', iconName: 'chevron-left', icon: [320, 512, [], "f053", "M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"] }; +var faChevronRight = { prefix: 'fas', iconName: 'chevron-right', icon: [320, 512, [], "f054", "M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"] }; +var faChevronUp = { prefix: 'fas', iconName: 'chevron-up', icon: [448, 512, [], "f077", "M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"] }; +var faChild = { prefix: 'fas', iconName: 'child', icon: [384, 512, [], "f1ae", "M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z"] }; +var faCircle = { prefix: 'fas', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"] }; +var faCircleNotch = { prefix: 'fas', iconName: 'circle-notch', icon: [512, 512, [], "f1ce", "M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"] }; +var faClipboard = { prefix: 'fas', iconName: 'clipboard', icon: [384, 512, [], "f328", "M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z"] }; +var faClock = { prefix: 'fas', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; +var faClone = { prefix: 'fas', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"] }; +var faClosedCaptioning = { prefix: 'fas', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z"] }; +var faCloud = { prefix: 'fas', iconName: 'cloud', icon: [640, 512, [], "f0c2", "M537.585 226.56C541.725 215.836 544 204.184 544 192c0-53.019-42.981-96-96-96-19.729 0-38.065 5.954-53.316 16.159C367.042 64.248 315.288 32 256 32c-88.366 0-160 71.634-160 160 0 2.728.07 5.439.204 8.133C40.171 219.845 0 273.227 0 336c0 79.529 64.471 144 144 144h368c70.692 0 128-57.308 128-128 0-61.93-43.983-113.586-102.415-125.44z"] }; +var faCloudDownloadAlt = { prefix: 'fas', iconName: 'cloud-download-alt', icon: [640, 512, [], "f381", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-246.627-64H328V176c0-8.837-7.164-16-16-16h-48c-8.836 0-16 7.163-16 16v112h-65.373c-14.254 0-21.393 17.234-11.314 27.314l105.373 105.373c6.248 6.248 16.379 6.248 22.627 0l105.373-105.373c10.08-10.08 2.941-27.314-11.313-27.314z"] }; +var faCloudUploadAlt = { prefix: 'fas', iconName: 'cloud-upload-alt', icon: [640, 512, [], "f382", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-235.314-91.314L299.314 155.314c-6.248-6.248-16.379-6.248-22.627 0L171.314 260.686c-10.08 10.08-2.941 27.314 11.313 27.314H248v112c0 8.837 7.164 16 16 16h48c8.836 0 16-7.163 16-16V288h65.373c14.254 0 21.393-17.234 11.313-27.314z"] }; +var faCode = { prefix: 'fas', iconName: 'code', icon: [640, 512, [], "f121", "M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z"] }; +var faCodeBranch = { prefix: 'fas', iconName: 'code-branch', icon: [384, 512, [], "f126", "M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z"] }; +var faCoffee = { prefix: 'fas', iconName: 'coffee', icon: [640, 512, [], "f0f4", "M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z"] }; +var faCog = { prefix: 'fas', iconName: 'cog', icon: [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"] }; +var faCogs = { prefix: 'fas', iconName: 'cogs', icon: [640, 512, [], "f085", "M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"] }; +var faColumns = { prefix: 'fas', iconName: 'columns', icon: [512, 512, [], "f0db", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z"] }; +var faComment = { prefix: 'fas', iconName: 'comment', icon: [576, 512, [], "f075", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208z"] }; +var faCommentAlt = { prefix: 'fas', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208zm-416-48c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; +var faComments = { prefix: 'fas', iconName: 'comments', icon: [576, 512, [], "f086", "M224 358.857c-37.599 0-73.027-6.763-104.143-18.7-31.375 24.549-69.869 39.508-110.764 43.796a8.632 8.632 0 0 1-.89.047c-3.736 0-7.111-2.498-8.017-6.061-.98-3.961 2.088-6.399 5.126-9.305 15.017-14.439 33.222-25.79 40.342-74.297C17.015 266.886 0 232.622 0 195.429 0 105.16 100.297 32 224 32s224 73.159 224 163.429c-.001 90.332-100.297 163.428-224 163.428zm347.067 107.174c-13.944-13.127-30.849-23.446-37.46-67.543 68.808-64.568 52.171-156.935-37.674-207.065.031 1.334.066 2.667.066 4.006 0 122.493-129.583 216.394-284.252 211.222 38.121 30.961 93.989 50.492 156.252 50.492 34.914 0 67.811-6.148 96.704-17 29.134 22.317 64.878 35.916 102.853 39.814 3.786.395 7.363-1.973 8.27-5.467.911-3.601-1.938-5.817-4.759-8.459z"] }; +var faCompass = { prefix: 'fas', iconName: 'compass', icon: [512, 512, [], "f14e", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM307.446 120.844l-102.642 97.779a23.997 23.997 0 0 0-6.772 11.729l-33.359 137.779c-5.68 23.459 22.777 39.318 39.88 23.024l102.64-97.779a23.99 23.99 0 0 0 6.772-11.729l33.359-137.779c5.618-23.198-22.591-39.493-39.878-23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faCompress = { prefix: 'fas', iconName: 'compress', icon: [448, 512, [], "f066", "M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; +var faCopy = { prefix: 'fas', iconName: 'copy', icon: [448, 512, [], "f0c5", "M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"] }; +var faCopyright = { prefix: 'fas', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z"] }; +var faCreditCard = { prefix: 'fas', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z"] }; +var faCrop = { prefix: 'fas', iconName: 'crop', icon: [512, 512, [], "f125", "M488 352h-40V109.3l57-57c9.4-9.4 9.4-24.6 0-33.9L493.7 7c-9.4-9.4-24.6-9.4-33.9 0l-57 57H160V24c0-13.3-10.7-24-24-24H88C74.7 0 64 10.7 64 24v40H24C10.7 64 0 74.7 0 88v48c0 13.3 10.7 24 24 24h40v264c0 13.3 10.7 24 24 24h264v40c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24v-40h40c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zM306.7 160L160 306.7V160h146.7zM205.3 352L352 205.3V352H205.3z"] }; +var faCrosshairs = { prefix: 'fas', iconName: 'crosshairs', icon: [512, 512, [], "f05b", "M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z"] }; +var faCube = { prefix: 'fas', iconName: 'cube', icon: [512, 512, [], "f1b2", "M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z"] }; +var faCubes = { prefix: 'fas', iconName: 'cubes', icon: [512, 512, [], "f1b3", "M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z"] }; +var faCut = { prefix: 'fas', iconName: 'cut', icon: [448, 512, [], "f0c4", "M444.485 422.426c4.689 4.689 4.684 12.287 0 16.971-32.804 32.804-85.991 32.804-118.795 0L210.176 323.883l-24.859 24.859C189.63 359.657 192 371.552 192 384c0 53.019-42.981 96-96 96S0 437.019 0 384s42.981-96 96-96c4.536 0 8.995.322 13.363.93l32.93-32.93-32.93-32.93c-4.368.608-8.827.93-13.363.93-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96c0 12.448-2.37 24.343-6.682 35.258l24.859 24.859L325.69 72.603c32.804-32.804 85.991-32.804 118.795 0 4.684 4.684 4.689 12.282 0 16.971L278.059 256l166.426 166.426zM96 96c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m0 256c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m112-108c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12z"] }; +var faDatabase = { prefix: 'fas', iconName: 'database', icon: [448, 512, [], "f1c0", "M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z"] }; +var faDeaf = { prefix: 'fas', iconName: 'deaf', icon: [512, 512, [], "f2a4", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z"] }; +var faDesktop = { prefix: 'fas', iconName: 'desktop', icon: [576, 512, [], "f108", "M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z"] }; +var faDollarSign = { prefix: 'fas', iconName: 'dollar-sign', icon: [320, 512, [], "f155", "M113.411 169.375c0-23.337 21.536-38.417 54.865-38.417 26.726 0 54.116 12.263 76.461 28.333 5.88 4.229 14.13 2.354 17.575-4.017l23.552-43.549c2.649-4.898 1.596-10.991-2.575-14.68-24.281-21.477-59.135-34.09-91.289-37.806V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v49.832c-58.627 13.29-97.299 55.917-97.299 108.639 0 123.533 184.765 110.81 184.765 169.414 0 19.823-16.311 41.158-52.124 41.158-30.751 0-62.932-15.88-87.848-35.887-5.31-4.264-13.082-3.315-17.159 2.14l-30.389 40.667c-3.627 4.854-3.075 11.657 1.302 15.847 24.049 23.02 59.249 41.255 98.751 47.973V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-47.438c65.72-10.215 106.176-59.186 106.176-116.516.001-119.688-184.764-103.707-184.764-166.671z"] }; +var faDotCircle = { prefix: 'fas', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z"] }; +var faDownload = { prefix: 'fas', iconName: 'download', icon: [512, 512, [], "f019", "M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; +var faEdit = { prefix: 'fas', iconName: 'edit', icon: [576, 512, [], "f044", "M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"] }; +var faEject = { prefix: 'fas', iconName: 'eject', icon: [448, 512, [], "f052", "M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z"] }; +var faEllipsisH = { prefix: 'fas', iconName: 'ellipsis-h', icon: [512, 512, [], "f141", "M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"] }; +var faEllipsisV = { prefix: 'fas', iconName: 'ellipsis-v', icon: [192, 512, [], "f142", "M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"] }; +var faEnvelope = { prefix: 'fas', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"] }; +var faEnvelopeOpen = { prefix: 'fas', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z"] }; +var faEnvelopeSquare = { prefix: 'fas', iconName: 'envelope-square', icon: [448, 512, [], "f199", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z"] }; +var faEraser = { prefix: 'fas', iconName: 'eraser', icon: [512, 512, [], "f12d", "M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z"] }; +var faEuroSign = { prefix: 'fas', iconName: 'euro-sign', icon: [320, 512, [], "f153", "M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z"] }; +var faExchangeAlt = { prefix: 'fas', iconName: 'exchange-alt', icon: [512, 512, [], "f362", "M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; +var faExclamation = { prefix: 'fas', iconName: 'exclamation', icon: [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"] }; +var faExclamationCircle = { prefix: 'fas', iconName: 'exclamation-circle', icon: [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; +var faExclamationTriangle = { prefix: 'fas', iconName: 'exclamation-triangle', icon: [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; +var faExpand = { prefix: 'fas', iconName: 'expand', icon: [448, 512, [], "f065", "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"] }; +var faExpandArrowsAlt = { prefix: 'fas', iconName: 'expand-arrows-alt', icon: [448, 512, [], "f31e", "M448.1 344v112c0 13.3-10.7 24-24 24h-112c-21.4 0-32.1-25.9-17-41l36.2-36.2L224 295.6 116.8 402.9 153 439c15.1 15.1 4.4 41-17 41H24c-13.3 0-24-10.7-24-24V344c0-21.4 25.9-32.1 41-17l36.2 36.2L184.5 256 77.2 148.7 41 185c-15.1 15.1-41 4.4-41-17V56c0-13.3 10.7-24 24-24h112c21.4 0 32.1 25.9 17 41l-36.2 36.2L224 216.4l107.3-107.3L295.1 73c-15.1-15.1-4.4-41 17-41h112c13.3 0 24 10.7 24 24v112c0 21.4-25.9 32.1-41 17l-36.2-36.2L263.6 256l107.3 107.3 36.2-36.2c15.1-15.2 41-4.5 41 16.9z"] }; +var faExternalLinkAlt = { prefix: 'fas', iconName: 'external-link-alt', icon: [576, 512, [], "f35d", "M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z"] }; +var faExternalLinkSquareAlt = { prefix: 'fas', iconName: 'external-link-square-alt', icon: [448, 512, [], "f360", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z"] }; +var faEye = { prefix: 'fas', iconName: 'eye', icon: [576, 512, [], "f06e", "M569.354 231.631C512.969 135.949 407.81 72 288 72 168.14 72 63.004 135.994 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.031 376.051 168.19 440 288 440c119.86 0 224.996-63.994 281.354-159.631a47.997 47.997 0 0 0 0-48.738zM288 392c-75.162 0-136-60.827-136-136 0-75.162 60.826-136 136-136 75.162 0 136 60.826 136 136 0 75.162-60.826 136-136 136zm104-136c0 57.438-46.562 104-104 104s-104-46.562-104-104c0-17.708 4.431-34.379 12.236-48.973l-.001.032c0 23.651 19.173 42.823 42.824 42.823s42.824-19.173 42.824-42.823c0-23.651-19.173-42.824-42.824-42.824l-.032.001C253.621 156.431 270.292 152 288 152c57.438 0 104 46.562 104 104z"] }; +var faEyeDropper = { prefix: 'fas', iconName: 'eye-dropper', icon: [512, 512, [], "f1fb", "M177.38 206.64L39.03 344.97A24.01 24.01 0 0 0 32 361.94V424L0 480l32 32 56-32h62.06c6.36 0 12.47-2.53 16.97-7.03l138.35-138.33-128-128zm225.552 30.47l16.952 16.95c9.37 9.37 9.37 24.57 0 33.94l-40.973 40.97c-9.292 9.312-24.506 9.434-33.94 0L183.028 167.03c-9.37-9.37-9.37-24.57 0-33.94L224 92.12c9.289-9.309 24.502-9.438 33.94 0l16.992 16.99 82.606-82.601c35.19-35.19 92.5-35.5 128 0 40.49 48.08 29.66 98.34 0 128l-82.606 82.601z"] }; +var faEyeSlash = { prefix: 'fas', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M286.693 391.984l32.579 46.542A333.958 333.958 0 0 1 288 440C168.19 440 63.031 376.051 6.646 280.369a47.999 47.999 0 0 1 0-48.739c24.023-40.766 56.913-75.775 96.024-102.537l57.077 81.539C154.736 224.82 152 240.087 152 256c0 74.736 60.135 135.282 134.693 135.984zm282.661-111.615c-31.667 53.737-78.747 97.46-135.175 125.475l.011.015 41.47 59.2c7.6 10.86 4.96 25.82-5.9 33.42l-13.11 9.18c-10.86 7.6-25.82 4.96-33.42-5.9L100.34 46.94c-7.6-10.86-4.96-25.82 5.9-33.42l13.11-9.18c10.86-7.6 25.82-4.96 33.42 5.9l51.038 72.617C230.68 75.776 258.905 72 288 72c119.81 0 224.969 63.949 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM424 256c0-75.174-60.838-136-136-136-17.939 0-35.056 3.473-50.729 9.772l19.299 27.058c25.869-8.171 55.044-6.163 80.4 7.41h-.03c-23.65 0-42.82 19.17-42.82 42.82 0 23.626 19.147 42.82 42.82 42.82 23.65 0 42.82-19.17 42.82-42.82v-.03c18.462 34.49 16.312 77.914-8.25 110.95v.01l19.314 27.061C411.496 321.2 424 290.074 424 256zM262.014 356.727l-77.53-110.757c-5.014 52.387 29.314 98.354 77.53 110.757z"] }; +var faFastBackward = { prefix: 'fas', iconName: 'fast-backward', icon: [512, 512, [], "f049", "M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z"] }; +var faFastForward = { prefix: 'fas', iconName: 'fast-forward', icon: [512, 512, [], "f050", "M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z"] }; +var faFax = { prefix: 'fas', iconName: 'fax', icon: [512, 512, [], "f1ac", "M128 144v320c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V144c0-26.51 21.49-48 48-48h32c26.51 0 48 21.49 48 48zm384 64v256c0 26.51-21.49 48-48 48H192c-26.51 0-48-21.49-48-48V40c0-22.091 17.909-40 40-40h207.432a39.996 39.996 0 0 1 28.284 11.716l48.569 48.569A39.999 39.999 0 0 1 480 88.568v74.174c18.641 6.591 32 24.36 32 45.258zm-320-16h240V96h-24c-13.203 0-24-10.797-24-24V48H192v144zm96 204c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm128 128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40z"] }; +var faFemale = { prefix: 'fas', iconName: 'female', icon: [256, 512, [], "f182", "M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z"] }; +var faFighterJet = { prefix: 'fas', iconName: 'fighter-jet', icon: [640, 512, [], "f0fb", "M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z"] }; +var faFile = { prefix: 'fas', iconName: 'file', icon: [384, 512, [], "f15b", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileAlt = { prefix: 'fas', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileArchive = { prefix: 'fas', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32V32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6zm32.7-53c0 14.9-14.5 27-32.4 27S96 378 96 363c0-14.9 14.5-27 32.4-27s32.5 12.1 32.5 27zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileAudio = { prefix: 'fas', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileCode = { prefix: 'fas', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z"] }; +var faFileExcel = { prefix: 'fas', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileImage = { prefix: 'fas', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"] }; +var faFilePdf = { prefix: 'fas', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z"] }; +var faFilePowerpoint = { prefix: 'fas', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z"] }; +var faFileVideo = { prefix: 'fas', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z"] }; +var faFileWord = { prefix: 'fas', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFilm = { prefix: 'fas', iconName: 'film', icon: [512, 512, [], "f008", "M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z"] }; +var faFilter = { prefix: 'fas', iconName: 'filter', icon: [512, 512, [], "f0b0", "M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"] }; +var faFire = { prefix: 'fas', iconName: 'fire', icon: [384, 512, [], "f06d", "M216 23.858c0-23.802-30.653-32.765-44.149-13.038C48 191.851 224 200 224 288c0 35.629-29.114 64.458-64.85 63.994C123.98 351.538 96 322.22 96 287.046v-85.51c0-21.703-26.471-32.225-41.432-16.504C27.801 213.158 0 261.332 0 320c0 105.869 86.131 192 192 192s192-86.131 192-192c0-170.29-168-193.003-168-296.142z"] }; +var faFireExtinguisher = { prefix: 'fas', iconName: 'fire-extinguisher', icon: [448, 512, [], "f134", "M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z"] }; +var faFlag = { prefix: 'fas', iconName: 'flag', icon: [512, 512, [], "f024", "M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z"] }; +var faFlagCheckered = { prefix: 'fas', iconName: 'flag-checkered', icon: [512, 512, [], "f11e", "M466.515 66.928C487.731 57.074 512 72.551 512 95.944v243.1c0 10.526-5.161 20.407-13.843 26.358-35.837 24.564-74.335 40.858-122.505 40.858-67.373 0-111.63-34.783-165.217-34.783-50.853 0-86.124 10.058-114.435 22.122V488c0 13.255-10.745 24-24 24H56c-13.255 0-24-10.745-24-24V101.945C17.497 91.825 8 75.026 8 56 8 24.296 34.345-1.254 66.338.048c28.468 1.158 51.779 23.968 53.551 52.404.52 8.342-.81 16.31-3.586 23.562C137.039 68.384 159.393 64 184.348 64c67.373 0 111.63 34.783 165.217 34.783 40.496 0 82.612-15.906 116.95-31.855zM96 134.63v70.49c29-10.67 51.18-17.83 73.6-20.91v-71.57c-23.5 2.17-40.44 9.79-73.6 21.99zm220.8 9.19c-26.417-4.672-49.886-13.979-73.6-21.34v67.42c24.175 6.706 47.566 16.444 73.6 22.31v-68.39zm-147.2 40.39v70.04c32.796-2.978 53.91-.635 73.6 3.8V189.9c-25.247-7.035-46.581-9.423-73.6-5.69zm73.6 142.23c26.338 4.652 49.732 13.927 73.6 21.34v-67.41c-24.277-6.746-47.54-16.45-73.6-22.32v68.39zM96 342.1c23.62-8.39 47.79-13.84 73.6-16.56v-71.29c-26.11 2.35-47.36 8.04-73.6 17.36v70.49zm368-221.6c-21.3 8.85-46.59 17.64-73.6 22.47v71.91c27.31-4.36 50.03-14.1 73.6-23.89V120.5zm0 209.96v-70.49c-22.19 14.2-48.78 22.61-73.6 26.02v71.58c25.07-2.38 48.49-11.04 73.6-27.11zM316.8 212.21v68.16c25.664 7.134 46.616 9.342 73.6 5.62v-71.11c-25.999 4.187-49.943 2.676-73.6-2.67z"] }; +var faFlask = { prefix: 'fas', iconName: 'flask', icon: [448, 512, [], "f0c3", "M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z"] }; +var faFolder = { prefix: 'fas', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"] }; +var faFolderOpen = { prefix: 'fas', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z"] }; +var faFont = { prefix: 'fas', iconName: 'font', icon: [448, 512, [], "f031", "M152 416h-24.013l26.586-80.782H292.8L319.386 416H296c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-26.739L275.495 42.746A16 16 0 0 0 260.382 32h-72.766a16 16 0 0 0-15.113 10.746L42.739 416H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm64.353-271.778c4.348-15.216 6.61-28.156 7.586-34.644.839 6.521 2.939 19.476 7.727 34.706l41.335 124.006h-98.619l41.971-124.068z"] }; +var faForward = { prefix: 'fas', iconName: 'forward', icon: [512, 512, [], "f04e", "M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z"] }; +var faFrown = { prefix: 'fas', iconName: 'frown', icon: [512, 512, [], "f119", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm192.551 212.66c-59.128-91.455-165.846-91.594-225.064 0-11.502 17.79 15.383 35.148 26.873 17.374 46.626-72.118 124.862-71.855 171.318 0 11.328 17.524 38.548.684 26.873-17.374z"] }; +var faFutbol = { prefix: 'fas', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z"] }; +var faGamepad = { prefix: 'fas', iconName: 'gamepad', icon: [640, 512, [], "f11b", "M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; +var faGavel = { prefix: 'fas', iconName: 'gavel', icon: [512, 512, [], "f0e3", "M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z"] }; +var faGem = { prefix: 'fas', iconName: 'gem', icon: [576, 512, [], "f3a5", "M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z"] }; +var faGenderless = { prefix: 'fas', iconName: 'genderless', icon: [288, 512, [], "f22d", "M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z"] }; +var faGift = { prefix: 'fas', iconName: 'gift', icon: [512, 512, [], "f06b", "M488 192h-64.512C438.72 175.003 448 152.566 448 128c0-52.935-43.065-96-96-96-41.997 0-68.742 20.693-95.992 54.15C226.671 50.192 199.613 32 160 32c-52.935 0-96 43.065-96 96 0 24.566 9.28 47.003 24.512 64H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h8v112c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V320h8c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zm-208-32c24-56 55.324-64 72-64 17.645 0 32 14.355 32 32s-14.355 32-32 32h-72zM160 96c16.676 0 48 8 72 64h-72c-17.645 0-32-14.355-32-32s14.355-32 32-32zm48 128h96v184c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V224z"] }; +var faGlassMartini = { prefix: 'fas', iconName: 'glass-martini', icon: [512, 512, [], "f000", "M507.3 27.3c10-10 2.9-27.3-11.3-27.3H16C1.8 0-5.4 17.2 4.7 27.3L216 238.6V472h-92c-15.5 0-28 12.5-28 28 0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12 0-15.5-12.5-28-28-28h-92V238.6L507.3 27.3z"] }; +var faGlobe = { prefix: 'fas', iconName: 'globe', icon: [512, 512, [], "f0ac", "M364.215 192h131.43c5.439 20.419 8.354 41.868 8.354 64s-2.915 43.581-8.354 64h-131.43c5.154-43.049 4.939-86.746 0-128zM185.214 352c10.678 53.68 33.173 112.514 70.125 151.992.221.001.44.008.661.008s.44-.008.661-.008c37.012-39.543 59.467-98.414 70.125-151.992H185.214zm174.13-192h125.385C452.802 84.024 384.128 27.305 300.95 12.075c30.238 43.12 48.821 96.332 58.394 147.925zm-27.35 32H180.006c-5.339 41.914-5.345 86.037 0 128h151.989c5.339-41.915 5.345-86.037-.001-128zM152.656 352H27.271c31.926 75.976 100.6 132.695 183.778 147.925-30.246-43.136-48.823-96.35-58.393-147.925zm206.688 0c-9.575 51.605-28.163 104.814-58.394 147.925 83.178-15.23 151.852-71.949 183.778-147.925H359.344zm-32.558-192c-10.678-53.68-33.174-112.514-70.125-151.992-.221 0-.44-.008-.661-.008s-.44.008-.661.008C218.327 47.551 195.872 106.422 185.214 160h141.572zM16.355 192C10.915 212.419 8 233.868 8 256s2.915 43.581 8.355 64h131.43c-4.939-41.254-5.154-84.951 0-128H16.355zm136.301-32c9.575-51.602 28.161-104.81 58.394-147.925C127.872 27.305 59.198 84.024 27.271 160h125.385z"] }; +var faGraduationCap = { prefix: 'fas', iconName: 'graduation-cap', icon: [640, 512, [], "f19d", "M622.884 199.005l-275.817 85.1a96 96 0 0 1-54.134 0L92.398 222.232c-8.564 11.438-11.018 23.05-11.918 38.335C89.778 266.165 96 276.355 96 288c0 11.952-6.557 22.366-16.265 27.861l16.197 123.096c.63 4.786-3.1 9.043-7.932 9.043H40c-4.828 0-8.562-4.253-7.932-9.044L48.265 315.86C38.557 310.366 32 299.952 32 288c0-12.034 6.646-22.511 16.465-27.976.947-17.951 3.974-33.231 12.152-47.597l-43.502-13.422c-22.876-6.801-22.766-39.241 0-46.01l275.817-85.1a96 96 0 0 1 54.134 0l275.817 85.1c22.877 6.801 22.767 39.241.001 46.01zM356.503 314.682l-.207.064-.207.061a127.998 127.998 0 0 1-72.177 0l-.207-.061-.207-.064-150.914-46.57L120 352c0 35.346 89.543 64 200 64s200-28.654 200-64l-12.583-83.888-150.914 46.57z"] }; +var faHSquare = { prefix: 'fas', iconName: 'h-square', icon: [448, 512, [], "f0fd", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z"] }; +var faHandLizard = { prefix: 'fas', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z"] }; +var faHandPaper = { prefix: 'fas', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z"] }; +var faHandPeace = { prefix: 'fas', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z"] }; +var faHandPointDown = { prefix: 'fas', iconName: 'hand-point-down', icon: [384, 512, [], "f0a7", "M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; +var faHandPointLeft = { prefix: 'fas', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z"] }; +var faHandPointRight = { prefix: 'fas', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; +var faHandPointUp = { prefix: 'fas', iconName: 'hand-point-up', icon: [384, 512, [], "f0a6", "M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z"] }; +var faHandPointer = { prefix: 'fas', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z"] }; +var faHandRock = { prefix: 'fas', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M512 128.79c0-26.322-20.861-48.344-47.18-48.783C437.935 79.558 416 101.217 416 128h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C333.935 47.558 312 69.217 312 96v32h-8V80.79c0-26.322-20.861-48.344-47.18-48.783C229.935 31.558 208 53.217 208 80v48h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C125.935 47.558 104 69.217 104 96v136l-8-7.111V176.79c0-26.322-20.861-48.344-47.18-48.783C21.935 127.558 0 149.217 0 176v66.445a95.998 95.998 0 0 0 32.221 71.751l111.668 99.261A47.999 47.999 0 0 1 160 449.333V456c0 13.255 10.745 24 24 24h240c13.255 0 24-10.745 24-24v-2.921a96.01 96.01 0 0 1 7.523-37.254l48.954-116.265A96.002 96.002 0 0 0 512 262.306V128.79z"] }; +var faHandScissors = { prefix: 'fas', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z"] }; +var faHandSpock = { prefix: 'fas', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M10.872 316.585c15.139-16.086 40.454-16.854 56.543-1.713L128 371.893v-79.405L88.995 120.865c-4.896-21.542 8.598-42.974 30.14-47.87 21.549-4.894 42.975 8.599 47.87 30.141L201.747 256h9.833L164.016 48.966c-4.946-21.531 8.498-42.994 30.028-47.94 21.532-4.95 42.994 8.498 47.94 30.028L293.664 256h15.105l48.425-193.702c5.357-21.432 27.075-34.462 48.507-29.104 21.432 5.358 34.463 27.075 29.104 48.507L391.231 256h11.08l30.768-129.265c5.117-21.491 26.685-34.768 48.177-29.647 21.491 5.117 34.765 26.686 29.647 48.177l-36.292 152.467A96.024 96.024 0 0 0 472 319.967v42.102a96.002 96.002 0 0 1-3.96 27.287l-26.174 88.287C435.825 498.022 417.101 512 395.846 512H179.172a48.002 48.002 0 0 1-32.898-13.046L12.585 373.128c-16.087-15.141-16.853-40.456-1.713-56.543z"] }; +var faHandshake = { prefix: 'fas', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M72 112H24c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zM48 340c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zm568-228h-48c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zm-24 228c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zM485.94 92.67L528 140.74V320h-19.17c.56-14.96-4.38-28.98-14-39.71l-80.92-98.91c2.93-3.2 2.76-8.16-.38-11.16-2.82-2.7-7.08-2.92-10.14-.76-.42.3-60.35 62.93-60.35 62.93l-.2.21c-23.904 26.905-66.127 26.204-89.15-1.42-15.48-18.58-15.29-45.39.45-63.76l66.57-77.67C334.304 73.88 354.534 64 376.7 64h46.05a83.98 83.98 0 0 1 63.19 28.67zm-3.37 197.92c15.46 16.78 12.59 43.83-2.37 57.75-17.711 16.462-42.433 13.004-45.93 9.2 1.653 15.658-21.389 47.249-56.42 44.68-6.325 21.185-32.298 38.909-59.18 29.61-10.22 10.21-25.82 14.97-39.81 14.97-28.69 0-54.92-11.99-72.58-30.8L112 320V135.52l61.36-50.57A71.52 71.52 0 0 1 223.93 64h37.42c16.73 0 32.68 6.84 44.21 18.85l-63.57 74.16c-20.84 24.31-21.09 59.81-.59 84.42 29.375 35.247 83.007 35.853 113.31 1.92L402.82 193l79.75 97.59z"] }; +var faHashtag = { prefix: 'fas', iconName: 'hashtag', icon: [448, 512, [], "f292", "M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z"] }; +var faHdd = { prefix: 'fas', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faHeading = { prefix: 'fas', iconName: 'heading', icon: [512, 512, [], "f1dc", "M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z"] }; +var faHeadphones = { prefix: 'fas', iconName: 'headphones', icon: [512, 512, [], "f025", "M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z"] }; +var faHeart = { prefix: 'fas', iconName: 'heart', icon: [576, 512, [], "f004", "M414.9 24C361.8 24 312 65.7 288 89.3 264 65.7 214.2 24 161.1 24 70.3 24 16 76.9 16 165.5c0 72.6 66.8 133.3 69.2 135.4l187 180.8c8.8 8.5 22.8 8.5 31.6 0l186.7-180.2c2.7-2.7 69.5-63.5 69.5-136C560 76.9 505.7 24 414.9 24z"] }; +var faHeartbeat = { prefix: 'fas', iconName: 'heartbeat', icon: [576, 512, [], "f21e", "M47.9 257C31.6 232.7 16 200.5 16 165.5 16 76.9 70.3 24 161.1 24 214.2 24 264 65.7 288 89.3 312 65.7 361.8 24 414.9 24 505.7 24 560 76.9 560 165.5c0 35-15.5 67.2-31.9 91.5H408l-26.4-58.6c-4.7-8.9-17.6-8.5-21.6.7l-53.3 134.6L235.4 120c-3.7-10.6-18.7-10.7-22.6-.2l-48 137.2H47.9zm348 32c-4.5 0-8.6-2.5-10.6-6.4l-12.8-32.5-56.9 142.8c-4.4 9.9-18.7 9.4-22.3-.9l-69.7-209.2-33.6 98.4c-1.7 4.7-6.2 7.8-11.2 7.8H73.4c5.3 5.7-12.8-12 198.9 192.6 8.8 8.5 22.8 8.5 31.6 0 204.3-197.2 191-184 199-192.6h-107z"] }; +var faHistory = { prefix: 'fas', iconName: 'history', icon: [512, 512, [], "f1da", "M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"] }; +var faHome = { prefix: 'fas', iconName: 'home', icon: [576, 512, [], "f015", "M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z"] }; +var faHospital = { prefix: 'fas', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z"] }; +var faHourglass = { prefix: 'fas', iconName: 'hourglass', icon: [384, 512, [], "f254", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z"] }; +var faHourglassEnd = { prefix: 'fas', iconName: 'hourglass-end', icon: [384, 512, [], "f253", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z"] }; +var faHourglassHalf = { prefix: 'fas', iconName: 'hourglass-half', icon: [384, 512, [], "f252", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z"] }; +var faHourglassStart = { prefix: 'fas', iconName: 'hourglass-start', icon: [384, 512, [], "f251", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z"] }; +var faICursor = { prefix: 'fas', iconName: 'i-cursor', icon: [256, 512, [], "f246", "M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z"] }; +var faIdBadge = { prefix: 'fas', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M0 464V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm192-144c53.019 0 96-42.981 96-96s-42.981-96-96-96-96 42.981-96 96 42.981 96 96 96zm94.317 17.474l-22.954-7.173C242.437 344.413 217.802 352 192 352s-50.437-7.587-71.363-21.699l-22.954 7.173C77.644 343.736 64 362.295 64 383.289V424c0 13.255 10.745 24 24 24h208c13.255 0 24-10.745 24-24v-40.711c0-20.994-13.644-39.553-33.683-45.815zM352 52v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12z"] }; +var faIdCard = { prefix: 'fas', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM160 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64m79.589 154.53l-28.281-9.427C196.458 314.532 178.856 320 160 320s-36.458-5.468-51.309-14.897L80.41 314.53A24 24 0 0 0 64 337.298V360c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-22.702a24 24 0 0 0-16.411-22.768zM448 340v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm32-96v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h424c6.627 0 12-5.373 12-12z"] }; +var faImage = { prefix: 'fas', iconName: 'image', icon: [512, 512, [], "f03e", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"] }; +var faImages = { prefix: 'fas', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z"] }; +var faInbox = { prefix: 'fas', iconName: 'inbox', icon: [576, 512, [], "f01c", "M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z"] }; +var faIndent = { prefix: 'fas', iconName: 'indent', icon: [448, 512, [], "f03c", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm176 144h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm-52.687-111.313l-96-95.984C17.266 138.652 0 145.776 0 160.016v191.975c0 14.329 17.325 21.304 27.313 11.313l96-95.992c6.249-6.247 6.249-16.377 0-22.625z"] }; +var faIndustry = { prefix: 'fas', iconName: 'industry', icon: [512, 512, [], "f275", "M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z"] }; +var faInfo = { prefix: 'fas', iconName: 'info', icon: [192, 512, [], "f129", "M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"] }; +var faInfoCircle = { prefix: 'fas', iconName: 'info-circle', icon: [512, 512, [], "f05a", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"] }; +var faItalic = { prefix: 'fas', iconName: 'italic', icon: [320, 512, [], "f033", "M204.758 416h-33.849l62.092-320h40.725a16 16 0 0 0 15.704-12.937l6.242-32C297.599 41.184 290.034 32 279.968 32H120.235a16 16 0 0 0-15.704 12.937l-6.242 32C96.362 86.816 103.927 96 113.993 96h33.846l-62.09 320H46.278a16 16 0 0 0-15.704 12.935l-6.245 32C22.402 470.815 29.967 480 40.034 480h158.479a16 16 0 0 0 15.704-12.935l6.245-32c1.927-9.88-5.638-19.065-15.704-19.065z"] }; +var faKey = { prefix: 'fas', iconName: 'key', icon: [512, 512, [], "f084", "M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"] }; +var faKeyboard = { prefix: 'fas', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faLanguage = { prefix: 'fas', iconName: 'language', icon: [640, 512, [], "f1ab", "M304 416H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h280v320zm-120.676-72.622A12 12 0 0 0 194.839 352h22.863c8.22 0 14.007-8.078 11.362-15.861L171.61 167.085a12 12 0 0 0-11.362-8.139h-32.489a12.001 12.001 0 0 0-11.362 8.139L58.942 336.139C56.297 343.922 62.084 352 70.304 352h22.805a12 12 0 0 0 11.535-8.693l9.118-31.807h60.211l9.351 31.878zm-39.051-140.42s4.32 21.061 7.83 33.21l10.8 37.531h-38.07l11.07-37.531c3.51-12.15 7.83-33.21 7.83-33.21h.54zM616 416H336V96h280c13.255 0 24 10.745 24 24v272c0 13.255-10.745 24-24 24zm-36-228h-64v-16c0-6.627-5.373-12-12-12h-16c-6.627 0-12 5.373-12 12v16h-64c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h114.106c-6.263 14.299-16.518 28.972-30.023 43.206-6.56-6.898-12.397-13.91-17.365-20.933-3.639-5.144-10.585-6.675-15.995-3.446l-7.28 4.346-6.498 3.879c-5.956 3.556-7.693 11.421-3.735 17.117 6.065 8.729 13.098 17.336 20.984 25.726-8.122 6.226-16.841 12.244-26.103 17.964-5.521 3.41-7.381 10.556-4.162 16.19l7.941 13.896c3.362 5.883 10.935 7.826 16.706 4.276 12.732-7.831 24.571-16.175 35.443-24.891 10.917 8.761 22.766 17.102 35.396 24.881 5.774 3.556 13.353 1.618 16.717-4.27l7.944-13.903c3.213-5.623 1.37-12.76-4.135-16.171a312.737 312.737 0 0 1-26.06-18.019c21.024-22.425 35.768-46.289 42.713-69.85H580c6.627 0 12-5.373 12-12v-16c0-6.625-5.373-11.998-12-11.998z"] }; +var faLaptop = { prefix: 'fas', iconName: 'laptop', icon: [640, 512, [], "f109", "M512 64v256H128V64h384m16-64H112C85.5 0 64 21.5 64 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm100 416H389.5c-3 0-5.5 2.1-5.9 5.1C381.2 436.3 368 448 352 448h-64c-16 0-29.2-11.7-31.6-26.9-.5-2.9-3-5.1-5.9-5.1H12c-6.6 0-12 5.4-12 12v36c0 26.5 21.5 48 48 48h544c26.5 0 48-21.5 48-48v-36c0-6.6-5.4-12-12-12z"] }; +var faLeaf = { prefix: 'fas', iconName: 'leaf', icon: [576, 512, [], "f06c", "M395.4 420.8c-43.4 21.6-91.9 34.4-140.8 34.4-82.2 0-151.1-40.1-151.1-40.1-16.1 0-35.4 64.9-63.3 64.9-27 0-40.2-24-40.2-38.5 0-33.1 63.6-58.9 63.6-77.3 0 0-12.5-21.2-12.5-59.2 0-101.2 81.3-173.4 172.6-203.3 65.9-21.6 206 3.5 250.7-38.5C492.1 47 500.8 32 527.8 32c36.3 0 48.2 93.2 48.2 120.3 0 110.9-54.5 206.5-180.6 268.5zm-254.3-75.6c63.5-89.9 144.5-128.8 257.7-120 8.8.7 16.5-5.9 17.2-14.7.7-8.8-5.9-16.5-14.7-17.2-124-9.6-215.9 33.9-286.3 133.5-5.1 7.2-3.4 17.2 3.8 22.3 7.2 5.1 17.2 3.4 22.3-3.9z"] }; +var faLemon = { prefix: 'fas', iconName: 'lemon', icon: [512, 512, [], "f094", "M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z"] }; +var faLevelDownAlt = { prefix: 'fas', iconName: 'level-down-alt', icon: [320, 512, [], "f3be", "M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z"] }; +var faLevelUpAlt = { prefix: 'fas', iconName: 'level-up-alt', icon: [320, 512, [], "f3bf", "M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z"] }; +var faLifeRing = { prefix: 'fas', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z"] }; +var faLightbulb = { prefix: 'fas', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zm-143.107-44c-9.907 0-18.826-6.078-22.376-15.327C67.697 267.541 16 277.731 16 176 16 78.803 94.805 0 192 0s176 78.803 176 176c0 101.731-51.697 91.541-90.516 192.673-3.55 9.249-12.47 15.327-22.376 15.327H128.893zM112 176c0-44.112 35.888-80 80-80 8.837 0 16-7.164 16-16s-7.163-16-16-16c-61.757 0-112 50.243-112 112 0 8.836 7.164 16 16 16s16-7.164 16-16z"] }; +var faLink = { prefix: 'fas', iconName: 'link', icon: [512, 512, [], "f0c1", "M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"] }; +var faLiraSign = { prefix: 'fas', iconName: 'lira-sign', icon: [384, 512, [], "f195", "M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z"] }; +var faList = { prefix: 'fas', iconName: 'list', icon: [512, 512, [], "f03a", "M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z"] }; +var faListAlt = { prefix: 'fas', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z"] }; +var faListOl = { prefix: 'fas', iconName: 'list-ol', icon: [512, 512, [], "f0cb", "M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faListUl = { prefix: 'fas', iconName: 'list-ul', icon: [512, 512, [], "f0ca", "M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faLocationArrow = { prefix: 'fas', iconName: 'location-arrow', icon: [512, 512, [], "f124", "M443.683 4.529L27.818 196.418C-18.702 217.889-3.39 288 47.933 288H224v175.993c0 51.727 70.161 66.526 91.582 20.115L507.38 68.225c18.905-40.961-23.752-82.133-63.697-63.696z"] }; +var faLock = { prefix: 'fas', iconName: 'lock', icon: [448, 512, [], "f023", "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"] }; +var faLockOpen = { prefix: 'fas', iconName: 'lock-open', icon: [576, 512, [], "f3c1", "M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z"] }; +var faLongArrowAltDown = { prefix: 'fas', iconName: 'long-arrow-alt-down', icon: [256, 512, [], "f309", "M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z"] }; +var faLongArrowAltLeft = { prefix: 'fas', iconName: 'long-arrow-alt-left', icon: [448, 512, [], "f30a", "M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z"] }; +var faLongArrowAltRight = { prefix: 'fas', iconName: 'long-arrow-alt-right', icon: [448, 512, [], "f30b", "M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z"] }; +var faLongArrowAltUp = { prefix: 'fas', iconName: 'long-arrow-alt-up', icon: [256, 512, [], "f30c", "M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z"] }; +var faLowVision = { prefix: 'fas', iconName: 'low-vision', icon: [576, 512, [], "f2a8", "M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z"] }; +var faMagic = { prefix: 'fas', iconName: 'magic', icon: [512, 512, [], "f0d0", "M101.1 505L7 410.9c-9.4-9.4-9.4-24.6 0-33.9L377 7c9.4-9.4 24.6-9.4 33.9 0l94.1 94.1c9.4 9.4 9.4 24.6 0 33.9L135 505c-9.3 9.3-24.5 9.3-33.9 0zM304 159.2l48.8 48.8 89.9-89.9-48.8-48.8-89.9 89.9zM138.9 39.3l-11.7 23.8-26.2 3.8c-4.7.7-6.6 6.5-3.2 9.8l19 18.5-4.5 26.1c-.8 4.7 4.1 8.3 8.3 6.1L144 115l23.4 12.3c4.2 2.2 9.1-1.4 8.3-6.1l-4.5-26.1 19-18.5c3.4-3.3 1.5-9.1-3.2-9.8L160.8 63l-11.7-23.8c-2-4.1-8.1-4.1-10.2.1zm97.7-20.7l-7.8 15.8-17.5 2.6c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L240 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm-192 0l-7.8 15.8L19.3 37c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L48 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm416 223.5l-7.8 15.8-17.5 2.5c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4l15.6-8.2 15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-2.8-5.4-2.8-6.8 0z"] }; +var faMagnet = { prefix: 'fas', iconName: 'magnet', icon: [512, 512, [], "f076", "M164.1 160H12c-6.6 0-12-5.4-12-12V68c0-19.9 16.1-36 36-36h104c19.9 0 36 16.1 36 36v80c.1 6.6-5.3 12-11.9 12zm348-12V67.9c0-19.9-16.1-36-36-36h-104c-19.9 0-36 16.1-36 36v80c0 6.6 5.4 12 12 12h152c6.6.1 12-5.3 12-11.9zm-164 44c-6.6 0-12 5.4-12 12v52c0 128.1-160 127.9-160 0v-52c0-6.6-5.4-12-12-12h-152c-6.7 0-12 5.4-12 12.1.1 21.4.6 40.3 0 53.3C.1 408 136.3 504 256.9 504 377.5 504 512 408 512 257.3c-.6-12.8-.2-33 0-53.2 0-6.7-5.3-12.1-12-12.1H348.1z"] }; +var faMale = { prefix: 'fas', iconName: 'male', icon: [192, 512, [], "f183", "M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z"] }; +var faMap = { prefix: 'fas', iconName: 'map', icon: [576, 512, [], "f279", "M576 56.015v335.97a23.998 23.998 0 0 1-13.267 21.466l-128 64C418.948 485.344 400 473.992 400 455.985v-335.97a23.998 23.998 0 0 1 13.267-21.466l128-64C557.052 26.656 576 38.008 576 56.015zm-206.253 42.07l-144-64c-15.751-7-33.747 4.461-33.747 21.932v335.967a24 24 0 0 0 14.253 21.931l144 64c15.751 7 33.747-4.461 33.747-21.931V120.017a24 24 0 0 0-14.253-21.932zm-228.48-63.536l-128 63.985A23.998 23.998 0 0 0 0 120v335.985c0 18.007 18.948 29.359 34.733 21.466l128-63.985A23.998 23.998 0 0 0 176 392V56.015c0-18.007-18.948-29.359-34.733-21.466z"] }; +var faMapMarker = { prefix: 'fas', iconName: 'map-marker', icon: [384, 512, [], "f041", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z"] }; +var faMapMarkerAlt = { prefix: 'fas', iconName: 'map-marker-alt', icon: [384, 512, [], "f3c5", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"] }; +var faMapPin = { prefix: 'fas', iconName: 'map-pin', icon: [320, 512, [], "f276", "M192 300.813v172.82l-22.015 33.023c-4.75 7.125-15.219 7.125-19.969 0L128 473.633v-172.82a162.221 162.221 0 0 0 64 0zM160 0c79.529 0 144 64.471 144 144s-64.471 144-144 144S16 223.529 16 144 80.471 0 160 0M80 136c0-39.701 32.299-72 72-72a8 8 0 0 0 0-16c-48.523 0-88 39.477-88 88a8 8 0 0 0 16 0z"] }; +var faMapSigns = { prefix: 'fas', iconName: 'map-signs', icon: [512, 512, [], "f277", "M487.515 104.485L439.03 152.97a23.998 23.998 0 0 1-16.97 7.029H56c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h160v-8c0-13.255 10.745-24 24-24h32c13.255 0 24 10.745 24 24v8h126.059a24 24 0 0 1 16.97 7.029l48.485 48.485c4.687 4.687 4.687 12.285.001 16.971zM216 368v120c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V368h-80zm240-144H296v-48h-80v48H89.941a24 24 0 0 0-16.97 7.029l-48.485 48.485c-4.686 4.686-4.686 12.284 0 16.971l48.485 48.485a23.998 23.998 0 0 0 16.97 7.029H456c13.255 0 24-10.745 24-24v-80C480 234.745 469.255 224 456 224z"] }; +var faMars = { prefix: 'fas', iconName: 'mars', icon: [384, 512, [], "f222", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faMarsDouble = { prefix: 'fas', iconName: 'mars-double', icon: [512, 512, [], "f227", "M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z"] }; +var faMarsStroke = { prefix: 'fas', iconName: 'mars-stroke', icon: [384, 512, [], "f229", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faMarsStrokeH = { prefix: 'fas', iconName: 'mars-stroke-h', icon: [480, 512, [], "f22b", "M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; +var faMarsStrokeV = { prefix: 'fas', iconName: 'mars-stroke-v', icon: [288, 512, [], "f22a", "M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; +var faMedkit = { prefix: 'fas', iconName: 'medkit', icon: [512, 512, [], "f0fa", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z"] }; +var faMeh = { prefix: 'fas', iconName: 'meh', icon: [512, 512, [], "f11a", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm160 208H176c-21.178 0-21.169 32 0 32h160c21.178 0 21.169-32 0-32z"] }; +var faMercury = { prefix: 'fas', iconName: 'mercury', icon: [288, 512, [], "f223", "M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; +var faMicrochip = { prefix: 'fas', iconName: 'microchip', icon: [512, 512, [], "f2db", "M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z"] }; +var faMicrophone = { prefix: 'fas', iconName: 'microphone', icon: [384, 512, [], "f130", "M96 256V96c0-53.019 42.981-96 96-96s96 42.981 96 96v160c0 53.019-42.981 96-96 96s-96-42.981-96-96zm252-56h-24c-6.627 0-12 5.373-12 12v42.68c0 66.217-53.082 120.938-119.298 121.318C126.213 376.38 72 322.402 72 256v-44c0-6.627-5.373-12-12-12H36c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c81.307-11.681 144-81.79 144-166.278v-44c0-6.627-5.373-12-12-12z"] }; +var faMicrophoneSlash = { prefix: 'fas', iconName: 'microphone-slash', icon: [512, 512, [], "f131", "M421.45 285.195L376 239.746V212c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12v44c0 9.957-.881 19.71-2.55 29.195zM352 96c0-53.019-42.981-96-96-96-32.574 0-61.354 16.227-78.71 41.035L352 215.746V96zm152.971 363.716L52.284 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 18.343c-9.372 9.373-9.372 24.568 0 33.941L160 205.254v49.577c0 53.089 43.436 97.452 96.524 97.167 14.626-.078 28.471-3.44 40.854-9.366l17.746 17.746c-17.529 9.971-37.794 15.666-59.372 15.622C189.355 375.864 136 321.053 136 254.656V212c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c25.625-3.682 49.396-13.172 69.942-27.083L459.717 504.97c9.373 9.373 24.569 9.373 33.941 0l11.313-11.313c9.372-9.373 9.372-24.568 0-33.941z"] }; +var faMinus = { prefix: 'fas', iconName: 'minus', icon: [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"] }; +var faMinusCircle = { prefix: 'fas', iconName: 'minus-circle', icon: [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"] }; +var faMinusSquare = { prefix: 'fas', iconName: 'minus-square', icon: [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"] }; +var faMobile = { prefix: 'fas', iconName: 'mobile', icon: [320, 512, [], "f10b", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; +var faMobileAlt = { prefix: 'fas', iconName: 'mobile-alt', icon: [320, 512, [], "f3cd", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z"] }; +var faMoneyBillAlt = { prefix: 'fas', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M640 120v272c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h592c13.255 0 24 10.745 24 24zM96 384c0-35.346-28.654-64-64-64v64h64zm0-256H32v64c35.346 0 64-28.654 64-64zm304 128c0-53.021-35.816-96-80-96s-80 42.979-80 96c0 53.012 35.814 96 80 96 44.167 0 80-42.969 80-96zm208 64c-35.346 0-64 28.654-64 64h64v-64zm0-192h-64c0 35.346 28.654 64 64 64v-64zM277.563 299.527c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z"] }; +var faMoon = { prefix: 'fas', iconName: 'moon', icon: [512, 512, [], "f186", "M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"] }; +var faMotorcycle = { prefix: 'fas', iconName: 'motorcycle', icon: [640, 512, [], "f21c", "M512.949 192.003c-14.862-.108-29.14 2.322-42.434 6.874L437.589 144H520c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24h-45.311a24 24 0 0 0-17.839 7.945l-37.496 41.663-22.774-37.956A24 24 0 0 0 376 64h-80c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h66.411l19.2 32H227.904c-17.727-23.073-44.924-40-99.904-40H72.54c-13.455 0-24.791 11.011-24.536 24.464C48.252 141.505 58.9 152 72 152h56c24.504 0 38.686 10.919 47.787 24.769l-11.291 20.529c-13.006-3.865-26.871-5.736-41.251-5.21C55.857 194.549 1.565 249.605.034 317.021-1.603 389.076 56.317 448 128 448c59.642 0 109.744-40.794 123.953-96h84.236c13.673 0 24.589-11.421 23.976-25.077-2.118-47.12 17.522-93.665 56.185-125.026l12.485 20.808c-27.646 23.654-45.097 58.88-44.831 98.179.47 69.556 57.203 126.452 126.758 127.11 71.629.678 129.839-57.487 129.234-129.099-.588-69.591-57.455-126.386-127.047-126.892zM128 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c4.242 0 8.405.341 12.469.982L98.97 316.434C90.187 332.407 101.762 352 120 352h81.297c-12.37 28.225-40.56 48-73.297 48zm388.351-.116C470.272 402.337 432 365.554 432 320c0-21.363 8.434-40.781 22.125-55.144l49.412 82.352c4.546 7.577 14.375 10.034 21.952 5.488l13.72-8.232c7.577-4.546 10.034-14.375 5.488-21.952l-48.556-80.927A80.005 80.005 0 0 1 512 240c45.554 0 82.338 38.273 79.884 84.352-2.16 40.558-34.974 73.372-75.533 75.532z"] }; +var faMousePointer = { prefix: 'fas', iconName: 'mouse-pointer', icon: [320, 512, [], "f245", "M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z"] }; +var faMusic = { prefix: 'fas', iconName: 'music', icon: [512, 512, [], "f001", "M470.4 1.5l-304 96C153.1 101.7 144 114 144 128v264.6c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V220.5l272-85.9v194c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V32c0-21.7-21.1-37-41.6-30.5z"] }; +var faNeuter = { prefix: 'fas', iconName: 'neuter', icon: [288, 512, [], "f22c", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faNewspaper = { prefix: 'fas', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z"] }; +var faObjectGroup = { prefix: 'fas', iconName: 'object-group', icon: [512, 512, [], "f247", "M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z"] }; +var faObjectUngroup = { prefix: 'fas', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z"] }; +var faOutdent = { prefix: 'fas', iconName: 'outdent', icon: [448, 512, [], "f03b", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm208 144h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm192-128h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM4.687 267.313l96 95.984C110.734 373.348 128 366.224 128 351.984V160.008c0-14.329-17.325-21.304-27.313-11.313l-96 95.992c-6.249 6.248-6.249 16.378 0 22.626z"] }; +var faPaintBrush = { prefix: 'fas', iconName: 'paint-brush', icon: [512, 512, [], "f1fc", "M269.9 364.6c1.4 6.4 2.1 13 2.1 19.7 0 81.2-54.2 127.7-134.8 127.7C41.5 512 0 435.1 0 347.6c10.4 7.1 46.9 36.5 58.7 36.5 7 0 13-4 15.5-10.6 23.6-62.2 66.5-76.5 112.9-77.4 15.6 33.8 46.1 59.6 82.8 68.5zM460.6 0c-14.4 0-27.9 6.4-38.2 15.7C228.2 190 208 194.1 208 245.4c0 48.8 40.5 90.6 90.2 90.6 59 0 93.2-43.4 200.6-244.8 7-13.7 13.2-28.5 13.2-43.9C512 19.7 487.3 0 460.6 0z"] }; +var faPaperPlane = { prefix: 'fas', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"] }; +var faPaperclip = { prefix: 'fas', iconName: 'paperclip', icon: [448, 512, [], "f0c6", "M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"] }; +var faParagraph = { prefix: 'fas', iconName: 'paragraph', icon: [448, 512, [], "f1dd", "M408 32H177.531C88.948 32 16.045 103.335 16 191.918 15.956 280.321 87.607 352 176 352v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h32v344c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h40c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24z"] }; +var faPaste = { prefix: 'fas', iconName: 'paste', icon: [448, 512, [], "f0ea", "M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z"] }; +var faPause = { prefix: 'fas', iconName: 'pause', icon: [448, 512, [], "f04c", "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"] }; +var faPauseCircle = { prefix: 'fas', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"] }; +var faPaw = { prefix: 'fas', iconName: 'paw', icon: [512, 512, [], "f1b0", "M85.231 330.958C36 330.958 0 273.792 0 231.5c0-28.292 16-58.042 49.538-58.042 49.231 0 85.231 57.458 85.231 99.75 0 28.292-15.692 57.75-49.538 57.75zm348 106.167c0 37.042-32 42.875-63.385 42.875-41.231 0-74.462-26.25-113.846-26.25-41.231 0-76.308 25.958-120.923 25.958-29.847 0-56.308-9.625-56.308-42.583C78.769 368 180.616 265.333 256 265.333s177.231 102.959 177.231 171.792zM182.462 203.792c-49.847 0-80-59.5-80-100.333C102.462 70.792 120.308 32 160 32c50.154 0 80 59.5 80 100.333 0 32.667-17.846 71.459-57.538 71.459zM272 132.333C272 91.5 301.846 32 352 32c39.692 0 57.539 38.792 57.539 71.458 0 40.833-30.154 100.333-80.001 100.333C289.846 203.792 272 165 272 132.333zM512 231.5c0 42.292-36 99.458-85.231 99.458-33.847 0-49.538-29.458-49.538-57.75 0-42.291 35.999-99.75 85.231-99.75C496 173.458 512 203.208 512 231.5z"] }; +var faPenSquare = { prefix: 'fas', iconName: 'pen-square', icon: [448, 512, [], "f14b", "M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z"] }; +var faPencilAlt = { prefix: 'fas', iconName: 'pencil-alt', icon: [512, 512, [], "f303", "M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"] }; +var faPercent = { prefix: 'fas', iconName: 'percent', icon: [448, 512, [], "f295", "M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z"] }; +var faPhone = { prefix: 'fas', iconName: 'phone', icon: [512, 512, [], "f095", "M493.397 24.615l-104-23.997c-11.314-2.611-22.879 3.252-27.456 13.931l-48 111.997a24 24 0 0 0 6.862 28.029l60.617 49.596c-35.973 76.675-98.938 140.508-177.249 177.248l-49.596-60.616a24 24 0 0 0-28.029-6.862l-111.997 48C3.873 366.516-1.994 378.08.618 389.397l23.997 104C27.109 504.204 36.748 512 48 512c256.087 0 464-207.532 464-464 0-11.176-7.714-20.873-18.603-23.385z"] }; +var faPhoneSquare = { prefix: 'fas', iconName: 'phone-square', icon: [448, 512, [], "f098", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z"] }; +var faPhoneVolume = { prefix: 'fas', iconName: 'phone-volume', icon: [384, 512, [], "f2a0", "M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z"] }; +var faPlane = { prefix: 'fas', iconName: 'plane', icon: [576, 512, [], "f072", "M472 200H360.211L256.013 5.711A12 12 0 0 0 245.793 0h-57.787c-7.85 0-13.586 7.413-11.616 15.011L209.624 200H99.766l-34.904-58.174A12 12 0 0 0 54.572 136H12.004c-7.572 0-13.252 6.928-11.767 14.353l21.129 105.648L.237 361.646c-1.485 7.426 4.195 14.354 11.768 14.353l42.568-.002c4.215 0 8.121-2.212 10.289-5.826L99.766 312h109.858L176.39 496.989c-1.97 7.599 3.766 15.011 11.616 15.011h57.787a12 12 0 0 0 10.22-5.711L360.212 312H472c57.438 0 104-25.072 104-56s-46.562-56-104-56z"] }; +var faPlay = { prefix: 'fas', iconName: 'play', icon: [448, 512, [], "f04b", "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"] }; +var faPlayCircle = { prefix: 'fas', iconName: 'play-circle', icon: [512, 512, [], "f144", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z"] }; +var faPlug = { prefix: 'fas', iconName: 'plug', icon: [384, 512, [], "f1e6", "M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z"] }; +var faPlus = { prefix: 'fas', iconName: 'plus', icon: [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"] }; +var faPlusCircle = { prefix: 'fas', iconName: 'plus-circle', icon: [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; +var faPlusSquare = { prefix: 'fas', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; +var faPodcast = { prefix: 'fas', iconName: 'podcast', icon: [448, 512, [], "f2ce", "M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z"] }; +var faPoundSign = { prefix: 'fas', iconName: 'pound-sign', icon: [320, 512, [], "f154", "M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z"] }; +var faPowerOff = { prefix: 'fas', iconName: 'power-off', icon: [512, 512, [], "f011", "M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z"] }; +var faPrint = { prefix: 'fas', iconName: 'print', icon: [512, 512, [], "f02f", "M464 192h-16V81.941a24 24 0 0 0-7.029-16.97L383.029 7.029A24 24 0 0 0 366.059 0H88C74.745 0 64 10.745 64 24v168H48c-26.51 0-48 21.49-48 48v132c0 6.627 5.373 12 12 12h52v104c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V384h52c6.627 0 12-5.373 12-12V240c0-26.51-21.49-48-48-48zm-80 256H128v-96h256v96zM128 224V64h192v40c0 13.2 10.8 24 24 24h40v96H128zm304 72c-13.254 0-24-10.746-24-24s10.746-24 24-24 24 10.746 24 24-10.746 24-24 24z"] }; +var faPuzzlePiece = { prefix: 'fas', iconName: 'puzzle-piece', icon: [576, 512, [], "f12e", "M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z"] }; +var faQrcode = { prefix: 'fas', iconName: 'qrcode', icon: [448, 512, [], "f029", "M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z"] }; +var faQuestion = { prefix: 'fas', iconName: 'question', icon: [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"] }; +var faQuestionCircle = { prefix: 'fas', iconName: 'question-circle', icon: [512, 512, [], "f059", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"] }; +var faQuoteLeft = { prefix: 'fas', iconName: 'quote-left', icon: [512, 512, [], "f10d", "M0 432V304C0 166.982 63.772 67.676 193.827 32.828 209.052 28.748 224 40.265 224 56.027v33.895c0 10.057-6.228 19.133-15.687 22.55C142.316 136.312 104 181.946 104 256h72c26.51 0 48 21.49 48 48v128c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm336 48h128c26.51 0 48-21.49 48-48V304c0-26.51-21.49-48-48-48h-72c0-74.054 38.316-119.688 104.313-143.528C505.772 109.055 512 99.979 512 89.922V56.027c0-15.762-14.948-27.279-30.173-23.199C351.772 67.676 288 166.982 288 304v128c0 26.51 21.49 48 48 48z"] }; +var faQuoteRight = { prefix: 'fas', iconName: 'quote-right', icon: [512, 512, [], "f10e", "M512 80v128c0 137.018-63.772 236.324-193.827 271.172-15.225 4.08-30.173-7.437-30.173-23.199v-33.895c0-10.057 6.228-19.133 15.687-22.55C369.684 375.688 408 330.054 408 256h-72c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h128c26.51 0 48 21.49 48 48zM176 32H48C21.49 32 0 53.49 0 80v128c0 26.51 21.49 48 48 48h72c0 74.054-38.316 119.688-104.313 143.528C6.228 402.945 0 412.021 0 422.078v33.895c0 15.762 14.948 27.279 30.173 23.199C160.228 444.324 224 345.018 224 208V80c0-26.51-21.49-48-48-48z"] }; +var faRandom = { prefix: 'fas', iconName: 'random', icon: [512, 512, [], "f074", "M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z"] }; +var faRecycle = { prefix: 'fas', iconName: 'recycle', icon: [512, 512, [], "f1b8", "M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z"] }; +var faRedo = { prefix: 'fas', iconName: 'redo', icon: [512, 512, [], "f01e", "M500.333 0h-47.411c-6.853 0-12.314 5.729-11.986 12.574l3.966 82.759C399.416 41.899 331.672 8 256.001 8 119.34 8 7.899 119.526 8 256.187 8.101 393.068 119.096 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-33.971-33.971c-4.466-4.466-11.64-4.717-16.38-.543C341.308 415.448 300.606 432 256 432c-97.267 0-176-78.716-176-176 0-97.267 78.716-176 176-176 60.892 0 114.506 30.858 146.099 77.8l-101.525-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12z"] }; +var faRedoAlt = { prefix: 'fas', iconName: 'redo-alt', icon: [512, 512, [], "f2f9", "M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"] }; +var faRegistered = { prefix: 'fas', iconName: 'registered', icon: [512, 512, [], "f25d", "M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z"] }; +var faReply = { prefix: 'fas', iconName: 'reply', icon: [512, 512, [], "f3e5", "M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z"] }; +var faReplyAll = { prefix: 'fas', iconName: 'reply-all', icon: [576, 512, [], "f122", "M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z"] }; +var faRetweet = { prefix: 'fas', iconName: 'retweet', icon: [640, 512, [], "f079", "M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z"] }; +var faRoad = { prefix: 'fas', iconName: 'road', icon: [576, 512, [], "f018", "M567.3 383.6L429.9 78.2C426 69.5 417.4 64 408 64h-96.1l1.9 18.8c.7 7.1-4.8 13.2-11.9 13.2H274c-7.1 0-12.7-6.2-11.9-13.2L264 64h-96c-9.4 0-18 5.5-21.9 14.2L8.7 383.6C3.2 395.8 0 409.6 0 424c0 13.3 10.7 24 24 24h213.6c-7.1 0-12.7-6.2-11.9-13.2l10.8-104c.6-6.1 5.8-10.8 11.9-10.8h79.2c6.1 0 11.3 4.6 11.9 10.8l10.8 104c.7 7.1-4.8 13.2-11.9 13.2H552c13.2 0 24-10.7 24-24 0-13.9-3-27.7-8.7-40.4zM254.7 154.8l3.3-32c.6-6.1 5.8-10.8 11.9-10.8h36.2c6.1 0 11.3 4.6 11.9 10.8l3.3 32c.7 7.1-4.8 13.2-11.9 13.2h-42.8c-7.1 0-12.7-6.2-11.9-13.2zM321.8 288h-67.6c-7.1 0-12.7-6.2-11.9-13.2l7.4-72c.6-6.1 5.8-10.8 11.9-10.8h52.7c6.1 0 11.3 4.6 11.9 10.8l7.4 72c.9 7-4.7 13.2-11.8 13.2z"] }; +var faRocket = { prefix: 'fas', iconName: 'rocket', icon: [512, 512, [], "f135", "M505.1 19.1C503.8 13 499 8.2 492.9 6.9 460.7 0 435.5 0 410.4 0 307.2 0 245.3 55.2 199.1 128H94.9c-18.2 0-34.8 10.3-42.9 26.5L2.6 253.3c-8 16 3.6 34.7 21.5 34.7h95.1c-5.9 12.8-11.9 25.5-18 37.7-3.1 6.2-1.9 13.6 3 18.5l63.6 63.6c4.9 4.9 12.3 6.1 18.5 3 12.2-6.1 24.9-12 37.7-17.9V488c0 17.8 18.8 29.4 34.7 21.5l98.7-49.4c16.3-8.1 26.5-24.8 26.5-42.9V312.8c72.6-46.3 128-108.4 128-211.1.1-25.2.1-50.4-6.8-82.6zM400 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; +var faRss = { prefix: 'fas', iconName: 'rss', icon: [448, 512, [], "f09e", "M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"] }; +var faRssSquare = { prefix: 'fas', iconName: 'rss-square', icon: [448, 512, [], "f143", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z"] }; +var faRubleSign = { prefix: 'fas', iconName: 'ruble-sign', icon: [384, 512, [], "f158", "M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z"] }; +var faRupeeSign = { prefix: 'fas', iconName: 'rupee-sign', icon: [320, 512, [], "f156", "M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z"] }; +var faSave = { prefix: 'fas', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"] }; +var faSearch = { prefix: 'fas', iconName: 'search', icon: [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"] }; +var faSearchMinus = { prefix: 'fas', iconName: 'search-minus', icon: [512, 512, [], "f010", "M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; +var faSearchPlus = { prefix: 'fas', iconName: 'search-plus', icon: [512, 512, [], "f00e", "M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; +var faServer = { prefix: 'fas', iconName: 'server', icon: [512, 512, [], "f233", "M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"] }; +var faShare = { prefix: 'fas', iconName: 'share', icon: [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"] }; +var faShareAlt = { prefix: 'fas', iconName: 'share-alt', icon: [448, 512, [], "f1e0", "M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z"] }; +var faShareAltSquare = { prefix: 'fas', iconName: 'share-alt-square', icon: [448, 512, [], "f1e1", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z"] }; +var faShareSquare = { prefix: 'fas', iconName: 'share-square', icon: [576, 512, [], "f14d", "M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z"] }; +var faShekelSign = { prefix: 'fas', iconName: 'shekel-sign', icon: [448, 512, [], "f20b", "M170.12 96H80v372c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V44c0-6.627 5.373-12 12-12h168.36C265.48 32 325 89.6 325 175.071V359c0 6.627-5.373 12-12 12h-44c-13.255 0-24-10.745-24-24V170.323C245 125.11 216.839 96 170.12 96zM436 32h-56c-6.627 0-12 5.373-12 12v372h-90.12c-46.72 0-74.88-29.11-74.88-74.323V165c0-13.255-10.745-24-24-24h-44c-6.627 0-12 5.373-12 12v183.929C123 422.4 182.52 480 267.64 480H436c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12z"] }; +var faShieldAlt = { prefix: 'fas', iconName: 'shield-alt', icon: [512, 512, [], "f3ed", "M496 128c0 221.282-135.934 344.645-221.539 380.308a48 48 0 0 1-36.923 0C130.495 463.713 16 326.487 16 128a48 48 0 0 1 29.539-44.308l192-80a48 48 0 0 1 36.923 0l192 80A48 48 0 0 1 496 128zM256 446.313l.066.034c93.735-46.689 172.497-156.308 175.817-307.729L256 65.333v380.98z"] }; +var faShip = { prefix: 'fas', iconName: 'ship', icon: [640, 512, [], "f21a", "M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z"] }; +var faShoppingBag = { prefix: 'fas', iconName: 'shopping-bag', icon: [448, 512, [], "f290", "M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z"] }; +var faShoppingBasket = { prefix: 'fas', iconName: 'shopping-basket', icon: [576, 512, [], "f291", "M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z"] }; +var faShoppingCart = { prefix: 'fas', iconName: 'shopping-cart', icon: [576, 512, [], "f07a", "M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"] }; +var faShower = { prefix: 'fas', iconName: 'shower', icon: [512, 512, [], "f2cc", "M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z"] }; +var faSignInAlt = { prefix: 'fas', iconName: 'sign-in-alt', icon: [512, 512, [], "f2f6", "M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"] }; +var faSignLanguage = { prefix: 'fas', iconName: 'sign-language', icon: [448, 512, [], "f2a7", "M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z"] }; +var faSignOutAlt = { prefix: 'fas', iconName: 'sign-out-alt', icon: [512, 512, [], "f2f5", "M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"] }; +var faSignal = { prefix: 'fas', iconName: 'signal', icon: [640, 512, [], "f012", "M36 384h56c6.6 0 12 5.4 12 12v104c0 6.6-5.4 12-12 12H36c-6.6 0-12-5.4-12-12V396c0-6.6 5.4-12 12-12zm116-36v152c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V348c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-80v232c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V268c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-112v344c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V156c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zM536 12v488c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12z"] }; +var faSitemap = { prefix: 'fas', iconName: 'sitemap', icon: [640, 512, [], "f0e8", "M616 320h-48v-48c0-22.056-17.944-40-40-40H344v-40h48c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h48v40H112c-22.056 0-40 17.944-40 40v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24z"] }; +var faSlidersH = { prefix: 'fas', iconName: 'sliders-h', icon: [576, 512, [], "f1de", "M576 80v40c0 6.6-5.4 12-12 12H160v8c0 13.3-10.7 24-24 24h-16c-13.3 0-24-10.7-24-24v-8H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h84v-8c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v8h404c6.6 0 12 5.4 12 12zm-12 148h-84v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h404v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12zm0 160H288v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h212v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h276c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12z"] }; +var faSmile = { prefix: 'fas', iconName: 'smile', icon: [512, 512, [], "f118", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-122.526 75.34c11.479-17.755-15.349-35.194-26.873-17.374-53.418 82.627-143.71 82.681-197.164 0-11.502-17.79-38.364-.401-26.873 17.374 66.014 102.107 184.795 102.265 250.91 0zM108 192c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48z"] }; +var faSnowflake = { prefix: 'fas', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M444.816 301.639a24.12 24.12 0 0 0 2.661-16.978c-2.725-12.966-15.339-21.245-28.174-18.492l-87.407 25.046L264 256l67.896-35.215 87.407 25.046c12.835 2.753 25.449-5.526 28.174-18.492 2.725-12.966-5.471-25.708-18.305-28.461l-47.477-7.137 53.077-30.956c11.363-6.627 15.257-21.306 8.696-32.785-6.561-11.479-21.091-15.412-32.454-8.785l-53.077 30.956 17.621-45.104c4.057-12.606-2.768-26.146-15.247-30.245-12.478-4.099-25.883 2.797-29.94 15.402l-22.232 88.99-60.38 35.215V144l65.175-63.945c8.778-9.852 7.987-25.027-1.766-33.894-9.753-8.867-24.775-8.068-33.552 1.784l-29.857 37.967V24c0-13.255-10.637-24-23.758-24s-23.758 10.745-23.758 24v61.912l-29.857-37.967c-8.779-9.852-23.799-10.652-33.552-1.784-9.753 8.867-10.543 24.042-1.766 33.894L200.242 144v70.431l-60.38-35.215-22.232-88.99c-4.057-12.605-17.462-19.501-29.94-15.402-12.478 4.099-19.304 17.64-15.247 30.245l17.62 45.104-53.077-30.956c-11.363-6.627-25.893-2.694-32.454 8.785s-2.667 26.157 8.696 32.785l53.077 30.956-47.477 7.137C5.993 201.634-2.203 214.375.523 227.341c2.725 12.965 15.339 21.245 28.174 18.492l87.407-25.046L184 256l-67.896 35.215-87.406-25.045c-12.835-2.753-25.449 5.526-28.174 18.492-2.725 12.967 5.47 25.708 18.305 28.461l47.477 7.137-53.077 30.956C1.866 357.843-2.027 372.521 4.533 384s21.091 15.412 32.454 8.785l53.077-30.956-17.62 45.104a24.157 24.157 0 0 0 2.022 19.428c2.831 4.953 7.416 8.909 13.224 10.816 12.478 4.099 25.883-2.797 29.94-15.402l22.232-88.99 60.38-35.215V368l-65.175 63.945c-8.778 9.852-7.987 25.027 1.766 33.894 9.754 8.868 24.774 8.068 33.552-1.784l29.857-37.967V488c0 13.255 10.637 24 23.758 24s23.758-10.745 23.758-24v-61.912l29.857 37.967A23.59 23.59 0 0 0 295.282 472a23.534 23.534 0 0 0 15.885-6.161c9.753-8.867 10.544-24.042 1.766-33.894L247.758 368v-70.431l60.38 35.215 22.232 88.99c4.057 12.605 17.462 19.501 29.94 15.402 12.479-4.099 19.304-17.64 15.247-30.245l-17.621-45.104 53.077 30.956c11.363 6.627 25.893 2.694 32.454-8.785s2.667-26.157-8.696-32.785l-53.077-30.956 47.477-7.137c6.86-1.469 12.394-5.793 15.645-11.481z"] }; +var faSort = { prefix: 'fas', iconName: 'sort', icon: [320, 512, [], "f0dc", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z"] }; +var faSortAlphaDown = { prefix: 'fas', iconName: 'sort-alpha-down', icon: [448, 512, [], "f15d", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zm119.075-180.007A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; +var faSortAlphaUp = { prefix: 'fas', iconName: 'sort-alpha-up', icon: [448, 512, [], "f15e", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zm301.671 98.621A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; +var faSortAmountDown = { prefix: 'fas', iconName: 'sort-amount-down', icon: [512, 512, [], "f160", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; +var faSortAmountUp = { prefix: 'fas', iconName: 'sort-amount-up', icon: [512, 512, [], "f161", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; +var faSortDown = { prefix: 'fas', iconName: 'sort-down', icon: [320, 512, [], "f0dd", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z"] }; +var faSortNumericDown = { prefix: 'fas', iconName: 'sort-numeric-down', icon: [448, 512, [], "f162", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM175.984 368H128V48c0-8.837-7.163-16-16-16H80c-8.837 0-16 7.163-16 16v320H16.019c-14.212 0-21.384 17.244-11.314 27.314l79.981 80.002c6.245 6.245 16.38 6.247 22.627 0l79.984-80.002c10.05-10.05 2.928-27.314-11.313-27.314z"] }; +var faSortNumericUp = { prefix: 'fas', iconName: 'sort-numeric-up', icon: [448, 512, [], "f163", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM16.016 144H64v320c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144h47.981c14.212 0 21.384-17.244 11.314-27.314l-79.981-80.002c-6.245-6.245-16.38-6.247-22.627 0L4.702 116.686C-5.347 126.736 1.775 144 16.016 144z"] }; +var faSortUp = { prefix: 'fas', iconName: 'sort-up', icon: [320, 512, [], "f0de", "M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z"] }; +var faSpaceShuttle = { prefix: 'fas', iconName: 'space-shuttle', icon: [640, 512, [], "f197", "M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z"] }; +var faSpinner = { prefix: 'fas', iconName: 'spinner', icon: [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"] }; +var faSquare = { prefix: 'fas', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; +var faStar = { prefix: 'fas', iconName: 'star', icon: [576, 512, [], "f005", "M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"] }; +var faStarHalf = { prefix: 'fas', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z"] }; +var faStepBackward = { prefix: 'fas', iconName: 'step-backward', icon: [448, 512, [], "f048", "M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"] }; +var faStepForward = { prefix: 'fas', iconName: 'step-forward', icon: [448, 512, [], "f051", "M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"] }; +var faStethoscope = { prefix: 'fas', iconName: 'stethoscope', icon: [512, 512, [], "f0f1", "M512 176c0-35.659-29.164-64.507-64.941-63.993-34.21.492-62.296 28.357-63.043 62.562-.531 24.282 12.476 45.558 31.984 56.848V344c0 57.346-50.243 104-112 104-60.039 0-109.189-44.096-111.878-99.24C265.005 333.847 320 269.225 320 192V36.584c0-11.44-8.075-21.29-19.293-23.534L237.81.471c-12.997-2.599-25.641 5.83-28.241 18.827l-3.138 15.689c-2.6 12.997 5.83 25.641 18.827 28.241L256 69.376v121.4c0 52.852-42.203 96.707-95.053 97.22C107.58 288.513 64 245.25 64 192V69.376l30.742-6.149c12.997-2.6 21.427-15.243 18.827-28.241l-3.138-15.689C107.831 6.3 95.188-2.129 82.19.471L19.293 13.05C8.075 15.294 0 25.144 0 36.584V192c0 77.295 55.096 141.961 128.076 156.798C130.747 439.223 208.634 512 304 512c97.047 0 176-75.364 176-168V231.417c19.124-11.068 32-31.732 32-55.417zm-64-16c8.822 0 16 7.178 16 16s-7.178 16-16 16-16-7.178-16-16 7.178-16 16-16z"] }; +var faStickyNote = { prefix: 'fas', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z"] }; +var faStop = { prefix: 'fas', iconName: 'stop', icon: [448, 512, [], "f04d", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; +var faStopCircle = { prefix: 'fas', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z"] }; +var faStreetView = { prefix: 'fas', iconName: 'street-view', icon: [512, 512, [], "f21d", "M192 64c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zm112 80h-11.36c-22.711 10.443-49.59 10.894-73.28 0H208c-26.51 0-48 21.49-48 48v104c0 13.255 10.745 24 24 24h16v104c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V320h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48zm85.642 189.152a72.503 72.503 0 0 1-29.01 27.009C391.133 365.251 480 385.854 480 416c0 46.304-167.656 64-224 64-70.303 0-224-20.859-224-64 0-30.123 88.361-50.665 119.367-55.839a72.516 72.516 0 0 1-29.01-27.009C74.959 343.395 0 367.599 0 416c0 77.111 178.658 96 256 96 77.249 0 256-18.865 256-96 0-48.403-74.967-72.606-122.358-82.848z"] }; +var faStrikethrough = { prefix: 'fas', iconName: 'strikethrough', icon: [512, 512, [], "f0cc", "M496 288H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h480c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16zm-214.666 16c27.258 12.937 46.524 28.683 46.524 56.243 0 33.108-28.977 53.676-75.621 53.676-32.325 0-76.874-12.08-76.874-44.271V368c0-8.837-7.164-16-16-16H113.75c-8.836 0-16 7.163-16 16v19.204c0 66.845 77.717 101.82 154.487 101.82 88.578 0 162.013-45.438 162.013-134.424 0-19.815-3.618-36.417-10.143-50.6H281.334zm-30.952-96c-32.422-13.505-56.836-28.946-56.836-59.683 0-33.92 30.901-47.406 64.962-47.406 42.647 0 64.962 16.593 64.962 32.985V136c0 8.837 7.164 16 16 16h45.613c8.836 0 16-7.163 16-16v-30.318c0-52.438-71.725-79.875-142.575-79.875-85.203 0-150.726 40.972-150.726 125.646 0 22.71 4.665 41.176 12.777 56.547h129.823z"] }; +var faSubscript = { prefix: 'fas', iconName: 'subscript', icon: [512, 512, [], "f12c", "M395.198 416c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 256c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 96H16C7.163 96 0 88.837 0 80V48c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035A15.999 15.999 0 0 1 204.226 32H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 256H272z"] }; +var faSubway = { prefix: 'fas', iconName: 'subway', icon: [448, 512, [], "f239", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; +var faSuitcase = { prefix: 'fas', iconName: 'suitcase', icon: [512, 512, [], "f0f2", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352z"] }; +var faSun = { prefix: 'fas', iconName: 'sun', icon: [512, 512, [], "f185", "M274.835 12.646l25.516 62.393c4.213 10.301 16.671 14.349 26.134 8.492l57.316-35.479c15.49-9.588 34.808 4.447 30.475 22.142l-16.03 65.475c-2.647 10.81 5.053 21.408 16.152 22.231l67.224 4.987c18.167 1.348 25.546 24.057 11.641 35.826L441.81 242.26c-8.495 7.19-8.495 20.289 0 27.479l51.454 43.548c13.906 11.769 6.527 34.478-11.641 35.826l-67.224 4.987c-11.099.823-18.799 11.421-16.152 22.231l16.03 65.475c4.332 17.695-14.986 31.73-30.475 22.142l-57.316-35.479c-9.463-5.858-21.922-1.81-26.134 8.492l-25.516 62.393c-6.896 16.862-30.774 16.862-37.67 0l-25.516-62.393c-4.213-10.301-16.671-14.349-26.134-8.492l-57.317 35.479c-15.49 9.588-34.808-4.447-30.475-22.142l16.03-65.475c2.647-10.81-5.053-21.408-16.152-22.231l-67.224-4.987c-18.167-1.348-25.546-24.057-11.641-35.826L70.19 269.74c8.495-7.19 8.495-20.289 0-27.479l-51.454-43.548c-13.906-11.769-6.527-34.478 11.641-35.826l67.224-4.987c11.099-.823 18.799-11.421 16.152-22.231l-16.03-65.475c-4.332-17.695 14.986-31.73 30.475-22.142l57.317 35.479c9.463 5.858 21.921 1.81 26.134-8.492l25.516-62.393c6.896-16.861 30.774-16.861 37.67 0zM392 256c0-74.991-61.01-136-136-136-74.991 0-136 61.009-136 136s61.009 136 136 136c74.99 0 136-61.009 136-136zm-32 0c0 57.346-46.654 104-104 104s-104-46.654-104-104 46.654-104 104-104 104 46.654 104 104z"] }; +var faSuperscript = { prefix: 'fas', iconName: 'superscript', icon: [512, 512, [], "f12b", "M395.198 256c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 256H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035a16 16 0 0 1 13.598-7.567H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 416H272z"] }; +var faSync = { prefix: 'fas', iconName: 'sync', icon: [512, 512, [], "f021", "M440.935 12.574l3.966 82.766C399.416 41.904 331.674 8 256 8 134.813 8 33.933 94.924 12.296 209.824 10.908 217.193 16.604 224 24.103 224h49.084c5.57 0 10.377-3.842 11.676-9.259C103.407 137.408 172.931 80 256 80c60.893 0 114.512 30.856 146.104 77.801l-101.53-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12h-47.411c-6.853 0-12.315 5.729-11.987 12.574zM256 432c-60.895 0-114.517-30.858-146.109-77.805l101.868 4.871c6.845.327 12.573-5.134 12.573-11.986v-47.412c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12V500c0 6.627 5.373 12 12 12h47.385c6.863 0 12.328-5.745 11.985-12.599l-4.129-82.575C112.725 470.166 180.405 504 256 504c121.187 0 222.067-86.924 243.704-201.824 1.388-7.369-4.308-14.176-11.807-14.176h-49.084c-5.57 0-10.377 3.842-11.676 9.259C408.593 374.592 339.069 432 256 432z"] }; +var faSyncAlt = { prefix: 'fas', iconName: 'sync-alt', icon: [512, 512, [], "f2f1", "M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z"] }; +var faTable = { prefix: 'fas', iconName: 'table', icon: [512, 512, [], "f0ce", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z"] }; +var faTablet = { prefix: 'fas', iconName: 'tablet', icon: [448, 512, [], "f10a", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; +var faTabletAlt = { prefix: 'fas', iconName: 'tablet-alt', icon: [448, 512, [], "f3fa", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z"] }; +var faTachometerAlt = { prefix: 'fas', iconName: 'tachometer-alt', icon: [576, 512, [], "f3fd", "M75.694 480a48.02 48.02 0 0 1-42.448-25.571C12.023 414.3 0 368.556 0 320 0 160.942 128.942 32 288 32s288 128.942 288 288c0 48.556-12.023 94.3-33.246 134.429A48.018 48.018 0 0 1 500.306 480H75.694zM512 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zM288 128c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32zM64 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm65.608-158.392c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm316.784 0c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm-87.078 31.534c-12.627-4.04-26.133 2.92-30.173 15.544l-45.923 143.511C250.108 322.645 224 350.264 224 384c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-19.773-8.971-37.447-23.061-49.187l45.919-143.498c4.039-12.625-2.92-26.133-15.544-30.173z"] }; +var faTag = { prefix: 'fas', iconName: 'tag', icon: [512, 512, [], "f02b", "M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; +var faTags = { prefix: 'fas', iconName: 'tags', icon: [640, 512, [], "f02c", "M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"] }; +var faTasks = { prefix: 'fas', iconName: 'tasks', icon: [512, 512, [], "f0ae", "M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z"] }; +var faTaxi = { prefix: 'fas', iconName: 'taxi', icon: [512, 512, [], "f1ba", "M461.951 243.865l-21.816-87.268A79.885 79.885 0 0 0 362.522 96H352V56c0-13.255-10.745-24-24-24H184c-13.255 0-24 10.745-24 24v40h-10.522a79.885 79.885 0 0 0-77.612 60.597L50.05 243.865C25.515 252.823 8 276.366 8 304v48c0 20.207 9.374 38.214 24 49.943V456c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-54.057c14.626-11.729 24-29.737 24-49.943v-48c0-27.634-17.515-51.177-42.049-60.135zM149.478 160h213.045a15.975 15.975 0 0 1 15.522 12.12l16.97 67.88h-278.03l16.97-67.881A15.976 15.976 0 0 1 149.478 160zM132 336c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm320 0c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; +var faTerminal = { prefix: 'fas', iconName: 'terminal', icon: [640, 512, [], "f120", "M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; +var faTextHeight = { prefix: 'fas', iconName: 'text-height', icon: [576, 512, [], "f034", "M16 32h288c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96h-54.761v320H232c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H88c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm475.308 4.685l79.995 80.001C581.309 126.693 574.297 144 559.99 144H512v224h48c15.639 0 20.635 17.991 11.313 27.314l-79.995 80.001c-6.247 6.247-16.381 6.245-22.626 0l-79.995-80.001C378.691 385.307 385.703 368 400.01 368H448V144h-48c-15.639 0-20.635-17.991-11.313-27.314l79.995-80.001c6.247-6.248 16.381-6.245 22.626 0z"] }; +var faTextWidth = { prefix: 'fas', iconName: 'text-width', icon: [448, 512, [], "f035", "M16 32h416c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96H261.743v128H296c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H152c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm427.315 340.682l-80.001-79.995C353.991 283.365 336 288.362 336 304v48H112v-47.99c0-14.307-17.307-21.319-27.314-11.313L4.685 372.692c-6.245 6.245-6.247 16.379 0 22.626l80.001 79.995C94.009 484.635 112 479.638 112 464v-48h224v47.99c0 14.307 17.307 21.319 27.314 11.313l80.001-79.995c6.245-6.245 6.248-16.379 0-22.626z"] }; +var faTh = { prefix: 'fas', iconName: 'th', icon: [512, 512, [], "f00a", "M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z"] }; +var faThLarge = { prefix: 'fas', iconName: 'th-large', icon: [512, 512, [], "f009", "M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z"] }; +var faThList = { prefix: 'fas', iconName: 'th-list', icon: [512, 512, [], "f00b", "M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z"] }; +var faThermometerEmpty = { prefix: 'fas', iconName: 'thermometer-empty', icon: [256, 512, [], "f2cb", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerFull = { prefix: 'fas', iconName: 'thermometer-full', icon: [256, 512, [], "f2c7", "M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z"] }; +var faThermometerHalf = { prefix: 'fas', iconName: 'thermometer-half', icon: [256, 512, [], "f2c9", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerQuarter = { prefix: 'fas', iconName: 'thermometer-quarter', icon: [256, 512, [], "f2ca", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerThreeQuarters = { prefix: 'fas', iconName: 'thermometer-three-quarters', icon: [256, 512, [], "f2c8", "M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThumbsDown = { prefix: 'fas', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z"] }; +var faThumbsUp = { prefix: 'fas', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z"] }; +var faThumbtack = { prefix: 'fas', iconName: 'thumbtack', icon: [384, 512, [], "f08d", "M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z"] }; +var faTicketAlt = { prefix: 'fas', iconName: 'ticket-alt', icon: [576, 512, [], "f3ff", "M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z"] }; +var faTimes = { prefix: 'fas', iconName: 'times', icon: [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"] }; +var faTimesCircle = { prefix: 'fas', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"] }; +var faTint = { prefix: 'fas', iconName: 'tint', icon: [384, 512, [], "f043", "M192 512c-98.435 0-178.087-79.652-178.087-178.087 0-111.196 101.194-154.065 148.522-311.825 9.104-30.116 51.099-28.778 59.13 0 47.546 158.486 148.522 200.069 148.522 311.825C370.087 432.348 290.435 512 192 512zm-42.522-171.826c-1.509-5.533-9.447-5.532-10.956 0-9.223 29.425-27.913 37.645-27.913 58.435C110.609 417.13 125.478 432 144 432s33.391-14.87 33.391-33.391c0-20.839-18.673-28.956-27.913-58.435z"] }; +var faToggleOff = { prefix: 'fas', iconName: 'toggle-off', icon: [576, 512, [], "f204", "M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z"] }; +var faToggleOn = { prefix: 'fas', iconName: 'toggle-on', icon: [576, 512, [], "f205", "M576 256c0 106.039-85.961 192-192 192H192C85.961 448 0 362.039 0 256S85.961 64 192 64h192c106.039 0 192 85.961 192 192zM384 128c-70.741 0-128 57.249-128 128 0 70.741 57.249 128 128 128 70.741 0 128-57.249 128-128 0-70.741-57.249-128-128-128"] }; +var faTrademark = { prefix: 'fas', iconName: 'trademark', icon: [640, 512, [], "f25c", "M97.119 163.133H12c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h248.559c6.627 0 12 5.373 12 12v43.133c0 6.627-5.373 12-12 12H175.44V404c0 6.627-5.373 12-12 12h-54.322c-6.627 0-12-5.373-12-12V163.133zM329.825 96h65.425a12 12 0 0 1 11.346 8.093l43.759 127.068c7.161 20.588 16.111 52.812 16.111 52.812h.896s8.95-32.224 16.111-52.812l43.758-127.068A12 12 0 0 1 538.577 96h65.41a12 12 0 0 1 11.961 11.03l24.012 296c.567 6.987-4.951 12.97-11.961 12.97h-54.101a12 12 0 0 1-11.972-11.182l-9.082-132.93c-1.79-24.168 0-53.706 0-53.706h-.896s-10.741 33.566-17.902 53.706l-30.7 84.731a12 12 0 0 1-11.282 7.912h-50.302a12 12 0 0 1-11.282-7.912l-30.7-84.731c-7.161-20.14-17.903-53.706-17.903-53.706h-.895s1.79 29.538 0 53.706l-9.082 132.93c-.428 6.295-5.66 11.182-11.97 11.182H305.4c-7.017 0-12.536-5.994-11.959-12.987l24.425-296A11.999 11.999 0 0 1 329.825 96z"] }; +var faTrain = { prefix: 'fas', iconName: 'train', icon: [448, 512, [], "f238", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z"] }; +var faTransgender = { prefix: 'fas', iconName: 'transgender', icon: [384, 512, [], "f224", "M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faTransgenderAlt = { prefix: 'fas', iconName: 'transgender-alt', icon: [480, 512, [], "f225", "M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faTrash = { prefix: 'fas', iconName: 'trash', icon: [448, 512, [], "f1f8", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm415.2 56.7L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32.8 140.7c-.4-6.9 5.1-12.7 12-12.7h358.5c6.8 0 12.3 5.8 11.9 12.7z"] }; +var faTrashAlt = { prefix: 'fas', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z"] }; +var faTree = { prefix: 'fas', iconName: 'tree', icon: [384, 512, [], "f1bb", "M377.33 375.429L293.906 288H328c21.017 0 31.872-25.207 17.448-40.479L262.79 160H296c20.878 0 31.851-24.969 17.587-40.331l-104-112.003c-9.485-10.214-25.676-10.229-35.174 0l-104 112.003C56.206 134.969 67.037 160 88 160h33.21l-82.659 87.521C24.121 262.801 34.993 288 56 288h34.094L6.665 375.429C-7.869 390.655 2.925 416 24.025 416H144c0 32.781-11.188 49.26-33.995 67.506C98.225 492.93 104.914 512 120 512h144c15.086 0 21.776-19.069 9.995-28.494-19.768-15.814-33.992-31.665-33.995-67.496V416h119.97c21.05 0 31.929-25.309 17.36-40.571z"] }; +var faTrophy = { prefix: 'fas', iconName: 'trophy', icon: [576, 512, [], "f091", "M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"] }; +var faTruck = { prefix: 'fas', iconName: 'truck', icon: [640, 512, [], "f0d1", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48z"] }; +var faTty = { prefix: 'fas', iconName: 'tty', icon: [512, 512, [], "f1e4", "M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faTv = { prefix: 'fas', iconName: 'tv', icon: [640, 512, [], "f26c", "M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z"] }; +var faUmbrella = { prefix: 'fas', iconName: 'umbrella', icon: [576, 512, [], "f0e9", "M557.011 267.631c-51.432-45.217-107.572-43.698-158.567 30.731-5.298 7.861-14.906 7.165-19.736 0-2.483-3.624-32.218-60.808-90.708-60.808-45.766 0-70.542 31.378-90.709 60.808-4.829 7.165-14.436 7.861-19.734 0-50.904-74.285-106.613-76.406-158.567-30.731-10.21 8.264-20.912-1.109-18.696-9.481C32.146 134.573 158.516 64.612 288.001 64.612c128.793 0 256.546 69.961 287.706 193.538 2.206 8.322-8.426 17.793-18.696 9.481zM256 261.001V416c0 17.645-14.355 32-32 32s-32-14.355-32-32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 52.935 43.065 96 96 96s96-43.065 96-96V261.288c-21.836-10.806-45.425-9.737-64-.287zm64-211.007V32c0-17.673-14.327-32-32-32s-32 14.327-32 32v17.987a372.105 372.105 0 0 1 64 .007z"] }; +var faUnderline = { prefix: 'fas', iconName: 'underline', icon: [448, 512, [], "f0cd", "M224.264 388.24c-91.669 0-156.603-51.165-156.603-151.392V64H39.37c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h137.39c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.813v172.848c0 53.699 28.314 79.444 76.317 79.444 46.966 0 75.796-25.434 75.796-79.965V64h-28.291c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h136.868c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.291v172.848c0 99.405-64.881 151.392-156.082 151.392zM16 448h416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16z"] }; +var faUndo = { prefix: 'fas', iconName: 'undo', icon: [512, 512, [], "f0e2", "M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z"] }; +var faUndoAlt = { prefix: 'fas', iconName: 'undo-alt', icon: [512, 512, [], "f2ea", "M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"] }; +var faUniversalAccess = { prefix: 'fas', iconName: 'universal-access', icon: [512, 512, [], "f29a", "M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z"] }; +var faUniversity = { prefix: 'fas', iconName: 'university', icon: [512, 512, [], "f19c", "M480 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-12H8a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 480 128zm-24 304H24c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM64 192v192H44c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-20V192h-64v192h-32V192h-64v192h-32V192h-64v192h-32V192H64z"] }; +var faUnlink = { prefix: 'fas', iconName: 'unlink', icon: [512, 512, [], "f127", "M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"] }; +var faUnlock = { prefix: 'fas', iconName: 'unlock', icon: [448, 512, [], "f09c", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"] }; +var faUnlockAlt = { prefix: 'fas', iconName: 'unlock-alt', icon: [448, 512, [], "f13e", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z"] }; +var faUpload = { prefix: 'fas', iconName: 'upload', icon: [512, 512, [], "f093", "M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; +var faUser = { prefix: 'fas', iconName: 'user', icon: [512, 512, [], "f007", "M96 160C96 71.634 167.635 0 256 0s160 71.634 160 160-71.635 160-160 160S96 248.366 96 160zm304 192h-28.556c-71.006 42.713-159.912 42.695-230.888 0H112C50.144 352 0 402.144 0 464v24c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24v-24c0-61.856-50.144-112-112-112z"] }; +var faUserCircle = { prefix: 'fas', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zM144 208c0-61.856 50.144-112 112-112s112 50.144 112 112-50.144 112-112 112-112-50.144-112-112zm268.408 172.663c-80.346 100.411-232.375 100.53-312.817 0C117.003 362.973 141.218 352 168 352h18.204c44.03 21.336 95.495 21.368 139.592 0H344c26.782 0 50.997 10.973 68.408 28.663z"] }; +var faUserMd = { prefix: 'fas', iconName: 'user-md', icon: [448, 512, [], "f0f0", "M96 128C96 57.308 153.308 0 224 0s128 57.308 128 128-57.308 128-128 128S96 198.692 96 128zm256 160v33.61c36.471 7.433 64 39.756 64 78.39v49.441c0 11.44-8.075 21.29-19.293 23.534l-21.802 4.361c-6.499 1.3-12.821-2.915-14.12-9.414l-1.569-7.845c-1.3-6.499 2.915-12.821 9.414-14.12l15.37-3.074v-42.078c0-26.283-20.793-48.297-47.071-48.797C310.039 351.498 288 373.224 288 400v42.883l15.371 3.074c6.499 1.3 10.713 7.622 9.414 14.12l-1.569 7.845c-1.3 6.499-7.622 10.714-14.12 9.414l-21.802-4.361C264.075 470.732 256 460.882 256 449.441V400c0-38.634 27.529-70.957 64-78.39V288h-22.624c-45.669 20.945-99.331 21.749-146.752 0H128v66.025c28.495 7.361 49.359 33.906 47.931 64.977-1.506 32.778-28.097 59.392-60.874 60.926C78.383 481.644 48 452.303 48 416c0-29.767 20.427-54.852 48-61.975V288c-53.019 0-96 42.981-96 96v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-53.019-42.981-96-96-96zM80 416c0 17.645 14.355 32 32 32s32-14.355 32-32-14.355-32-32-32-32 14.355-32 32z"] }; +var faUserPlus = { prefix: 'fas', iconName: 'user-plus', icon: [640, 512, [], "f234", "M616 332c0-6.627-5.373-12-12-12h-60v-60c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v60h-60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h60v60c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-60h60c6.627 0 12-5.373 12-12v-40zM448 444v15c0 11.598-9.402 21-21 21H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350a98.09 98.09 0 0 1 26 3.493V372c0 24.262 19.738 44 44 44h25.519c2.768 12.064 2.481 20.659 2.481 28zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172z"] }; +var faUserSecret = { prefix: 'fas', iconName: 'user-secret', icon: [448, 512, [], "f21b", "M388.829 295.324l20.972-55.052c2.992-7.854-2.809-16.272-11.214-16.272H340.39c7.45-16.236 11.61-34.297 11.61-53.333 0-3.631-.16-7.224-.456-10.778C391.083 152.074 416 140.684 416 128c0-13.263-27.231-25.112-69.947-32.937-9.185-32.805-27.178-65.797-40.714-82.85-9.452-11.908-25.873-15.634-39.471-8.834l-27.557 13.779a31.997 31.997 0 0 1-28.622 0l-27.557-13.78c-13.599-6.799-30.02-3.074-39.471 8.834-13.536 17.053-31.529 50.045-40.714 82.85C59.231 102.888 32 114.737 32 128c0 12.684 24.917 24.074 64.456 31.889A129.362 129.362 0 0 0 96 170.667c0 19.037 4.159 37.098 11.608 53.333h-57.41c-8.615 0-14.423 8.809-11.029 16.727l22.906 53.447C25.799 307.882 0 342.925 0 384v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-39.97-24.43-74.231-59.171-88.676zM184 488l-48-192 48 24 24 40-24 128zm80 0l-24-128 24-40 48-24-48 192zm54.778-303.746c-.008.043-4.299 3.231-5.125 5.771-3.861 11.864-7.026 24.572-16.514 33.359-10.071 9.327-47.957 22.405-63.996-25.029-2.837-8.395-15.447-8.398-18.285 0-16.963 50.168-56.019 32.417-63.996 25.029-9.488-8.786-12.653-21.495-16.514-33.359-.826-2.54-5.118-5.728-5.125-5.771-.554-2.925-.981-5.884-1.22-8.85-.309-3.848 10.078-3.658 11.078-3.747 26.303-2.326 52.303-.579 78.023 5.497 2.563.606 11.553.529 13.793 0 25.72-6.076 51.72-7.824 78.023-5.497 1.002.089 11.387-.102 11.078 3.747-.239 2.966-.666 5.925-1.22 8.85z"] }; +var faUserTimes = { prefix: 'fas', iconName: 'user-times', icon: [640, 512, [], "f235", "M599.681 411.397c4.686-4.686 4.686-12.284 0-16.971L557.255 352l42.426-42.426c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.971 0L512 306.745l-42.426-42.426c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971L466.745 352l-42.426 42.426c-4.686 4.686-4.686 12.284 0 16.971l28.284 28.284c4.686 4.686 12.284 4.686 16.971 0L512 397.255l42.426 42.426c4.686 4.686 12.284 4.686 16.971 0l28.284-28.284zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172zm359.737 299.645C439.904 476.712 433.843 480 427 480H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350c23.366 0 44.818 8.183 61.658 21.832l-9.967 9.967c-17.156 17.156-17.156 45.07 0 62.225l28.284 28.284a43.946 43.946 0 0 0 13.762 9.337z"] }; +var faUsers = { prefix: 'fas', iconName: 'users', icon: [640, 512, [], "f0c0", "M220 164c0-55.229 44.772-100 100-100s100 44.771 100 100-44.772 100-100 100-100-44.771-100-100zM48 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm384 0c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-22 76c38.66 0 70 31.34 70 70v70c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24v-70c0-38.66 31.34-70 70-70h17.848c44.364 26.687 99.93 26.693 144.305 0H410m-282 70c0-11.975 2.081-23.472 5.889-34.156-21.93 1.152-44.122-4.121-63.611-15.844H56c-30.928 0-56 25.072-56 56v32c0 13.255 10.745 24 24 24h104v-62zm456-50h-14.278c-19.495 11.727-41.686 16.996-63.611 15.844A101.542 101.542 0 0 1 512 354v62h104c13.255 0 24-10.745 24-24v-32c0-30.928-25.072-56-56-56z"] }; +var faUtensilSpoon = { prefix: 'fas', iconName: 'utensil-spoon', icon: [512, 512, [], "f2e5", "M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z"] }; +var faUtensils = { prefix: 'fas', iconName: 'utensils', icon: [416, 512, [], "f2e7", "M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z"] }; +var faVenus = { prefix: 'fas', iconName: 'venus', icon: [288, 512, [], "f221", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; +var faVenusDouble = { prefix: 'fas', iconName: 'venus-double', icon: [512, 512, [], "f226", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z"] }; +var faVenusMars = { prefix: 'fas', iconName: 'venus-mars', icon: [576, 512, [], "f228", "M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faVideo = { prefix: 'fas', iconName: 'video', icon: [576, 512, [], "f03d", "M528 64h-12.118a48 48 0 0 0-33.941 14.059L384 176v-64c0-26.51-21.49-48-48-48H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-64l97.941 97.941A48 48 0 0 0 515.882 448H528c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48z"] }; +var faVolumeDown = { prefix: 'fas', iconName: 'volume-down', icon: [384, 512, [], "f027", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zM384 256c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; +var faVolumeOff = { prefix: 'fas', iconName: 'volume-off', icon: [256, 512, [], "f026", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971z"] }; +var faVolumeUp = { prefix: 'fas', iconName: 'volume-up', icon: [576, 512, [], "f028", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zm182.056-77.876C422.982.92 403.283 5.668 394.061 20.745c-9.221 15.077-4.473 34.774 10.604 43.995C468.967 104.063 512 174.983 512 256c0 73.431-36.077 142.292-96.507 184.206-14.522 10.072-18.129 30.01-8.057 44.532 10.076 14.528 30.016 18.126 44.531 8.057C529.633 438.927 576 350.406 576 256c0-103.244-54.579-194.877-137.944-245.859zM480 256c0-68.547-36.15-129.777-91.957-163.901-15.076-9.22-34.774-4.471-43.994 10.607-9.22 15.078-4.471 34.774 10.607 43.994C393.067 170.188 416 211.048 416 256c0 41.964-20.62 81.319-55.158 105.276-14.521 10.073-18.128 30.01-8.056 44.532 6.216 8.96 16.185 13.765 26.322 13.765a31.862 31.862 0 0 0 18.21-5.709C449.091 377.953 480 318.938 480 256zm-96 0c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; +var faWheelchair = { prefix: 'fas', iconName: 'wheelchair', icon: [512, 512, [], "f193", "M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z"] }; +var faWifi = { prefix: 'fas', iconName: 'wifi', icon: [640, 512, [], "f1eb", "M384 416c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm136.659-124.443c6.465-6.465 6.245-17.065-.564-23.167-113.793-101.985-286.526-101.869-400.19 0-6.809 6.102-7.029 16.702-.564 23.167l34.006 34.006c5.927 5.927 15.464 6.32 21.769.796 82.88-72.609 207.074-72.447 289.768 0 6.305 5.524 15.842 5.132 21.769-.796l34.006-34.006zm112.11-113.718c6.385-6.385 6.254-16.816-.35-22.973-175.768-163.86-449.134-163.8-624.837 0-6.604 6.157-6.735 16.589-.35 22.973l33.966 33.966c6.095 6.095 15.891 6.231 22.224.383 144.763-133.668 368.356-133.702 513.156 0 6.333 5.848 16.129 5.712 22.224-.383l33.967-33.966z"] }; +var faWindowClose = { prefix: 'fas', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z"] }; +var faWindowMaximize = { prefix: 'fas', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z"] }; +var faWindowMinimize = { prefix: 'fas', iconName: 'window-minimize', icon: [512, 512, [], "f2d1", "M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z"] }; +var faWindowRestore = { prefix: 'fas', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z"] }; +var faWonSign = { prefix: 'fas', iconName: 'won-sign', icon: [576, 512, [], "f159", "M564 192c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-48.028l18.572-80.61c1.732-7.518-3.978-14.694-11.693-14.694h-46.107a11.998 11.998 0 0 0-11.736 9.5L450.73 128H340.839l-19.725-85.987a12 12 0 0 0-11.696-9.317H265.43a12 12 0 0 0-11.687 9.277L233.696 128H124.975L107.5 42.299a12 12 0 0 0-11.758-9.602H53.628c-7.686 0-13.39 7.124-11.709 14.624L60 128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h62.342l7.171 32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h83.856l40.927 182.624A12 12 0 0 0 148.492 480h56.767c5.583 0 10.428-3.85 11.689-9.288L259.335 288h55.086l42.386 182.712A12 12 0 0 0 368.496 480h56.826a12 12 0 0 0 11.694-9.306L479.108 288H564c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-70.146l7.373-32H564zm-425.976 0h80.757l-7.457 32h-66.776l-6.524-32zm45.796 150.029c-6.194 25.831-6.758 47.25-7.321 47.25h-1.126s-1.689-22.05-6.758-47.25L157.599 288h38.812l-12.591 54.029zM274.182 224l1.996-8.602c1.856-7.962 3.457-15.968 4.803-23.398h11.794c1.347 7.43 2.947 15.436 4.803 23.398l1.996 8.602h-25.392zm130.959 118.029c-5.068 25.2-6.758 47.25-6.758 47.25h-1.126c-.563 0-1.126-21.42-7.321-47.25L377.542 288h39.107l-11.508 54.029zM430.281 224h-67.42l-7.34-32h81.577l-6.817 32z"] }; +var faWrench = { prefix: 'fas', iconName: 'wrench', icon: [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"] }; +var faYenSign = { prefix: 'fas', iconName: 'yen-sign', icon: [384, 512, [], "f157", "M351.208 32h-65.277a12 12 0 0 0-10.778 6.724l-55.39 113.163c-14.513 34.704-27.133 71.932-27.133 71.932h-1.262s-12.62-37.228-27.133-71.932l-55.39-113.163A11.997 11.997 0 0 0 98.068 32H32.792c-9.057 0-14.85 9.65-10.59 17.643L102.322 200H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h88.162L152 293.228V320H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h108v92c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-92h108c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12H232v-26.772L251.838 256H340c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12h-58.322l80.12-150.357C366.058 41.65 360.266 32 351.208 32z"] }; +var icons$1 = { + faAddressBook: faAddressBook, + faAddressCard: faAddressCard, + faAdjust: faAdjust, + faAlignCenter: faAlignCenter, + faAlignJustify: faAlignJustify, + faAlignLeft: faAlignLeft, + faAlignRight: faAlignRight, + faAmbulance: faAmbulance, + faAmericanSignLanguageInterpreting: faAmericanSignLanguageInterpreting, + faAnchor: faAnchor, + faAngleDoubleDown: faAngleDoubleDown, + faAngleDoubleLeft: faAngleDoubleLeft, + faAngleDoubleRight: faAngleDoubleRight, + faAngleDoubleUp: faAngleDoubleUp, + faAngleDown: faAngleDown, + faAngleLeft: faAngleLeft, + faAngleRight: faAngleRight, + faAngleUp: faAngleUp, + faArchive: faArchive, + faArrowAltCircleDown: faArrowAltCircleDown, + faArrowAltCircleLeft: faArrowAltCircleLeft, + faArrowAltCircleRight: faArrowAltCircleRight, + faArrowAltCircleUp: faArrowAltCircleUp, + faArrowCircleDown: faArrowCircleDown, + faArrowCircleLeft: faArrowCircleLeft, + faArrowCircleRight: faArrowCircleRight, + faArrowCircleUp: faArrowCircleUp, + faArrowDown: faArrowDown, + faArrowLeft: faArrowLeft, + faArrowRight: faArrowRight, + faArrowUp: faArrowUp, + faArrowsAlt: faArrowsAlt, + faArrowsAltH: faArrowsAltH, + faArrowsAltV: faArrowsAltV, + faAssistiveListeningSystems: faAssistiveListeningSystems, + faAsterisk: faAsterisk, + faAt: faAt, + faAudioDescription: faAudioDescription, + faBackward: faBackward, + faBalanceScale: faBalanceScale, + faBan: faBan, + faBarcode: faBarcode, + faBars: faBars, + faBath: faBath, + faBatteryEmpty: faBatteryEmpty, + faBatteryFull: faBatteryFull, + faBatteryHalf: faBatteryHalf, + faBatteryQuarter: faBatteryQuarter, + faBatteryThreeQuarters: faBatteryThreeQuarters, + faBed: faBed, + faBeer: faBeer, + faBell: faBell, + faBellSlash: faBellSlash, + faBicycle: faBicycle, + faBinoculars: faBinoculars, + faBirthdayCake: faBirthdayCake, + faBlind: faBlind, + faBold: faBold, + faBolt: faBolt, + faBomb: faBomb, + faBook: faBook, + faBookmark: faBookmark, + faBraille: faBraille, + faBriefcase: faBriefcase, + faBug: faBug, + faBuilding: faBuilding, + faBullhorn: faBullhorn, + faBullseye: faBullseye, + faBus: faBus, + faCalculator: faCalculator, + faCalendar: faCalendar, + faCalendarAlt: faCalendarAlt, + faCalendarCheck: faCalendarCheck, + faCalendarMinus: faCalendarMinus, + faCalendarPlus: faCalendarPlus, + faCalendarTimes: faCalendarTimes, + faCamera: faCamera, + faCameraRetro: faCameraRetro, + faCar: faCar, + faCaretDown: faCaretDown, + faCaretLeft: faCaretLeft, + faCaretRight: faCaretRight, + faCaretSquareDown: faCaretSquareDown, + faCaretSquareLeft: faCaretSquareLeft, + faCaretSquareRight: faCaretSquareRight, + faCaretSquareUp: faCaretSquareUp, + faCaretUp: faCaretUp, + faCartArrowDown: faCartArrowDown, + faCartPlus: faCartPlus, + faCertificate: faCertificate, + faChartArea: faChartArea, + faChartBar: faChartBar, + faChartLine: faChartLine, + faChartPie: faChartPie, + faCheck: faCheck, + faCheckCircle: faCheckCircle, + faCheckSquare: faCheckSquare, + faChevronCircleDown: faChevronCircleDown, + faChevronCircleLeft: faChevronCircleLeft, + faChevronCircleRight: faChevronCircleRight, + faChevronCircleUp: faChevronCircleUp, + faChevronDown: faChevronDown, + faChevronLeft: faChevronLeft, + faChevronRight: faChevronRight, + faChevronUp: faChevronUp, + faChild: faChild, + faCircle: faCircle, + faCircleNotch: faCircleNotch, + faClipboard: faClipboard, + faClock: faClock, + faClone: faClone, + faClosedCaptioning: faClosedCaptioning, + faCloud: faCloud, + faCloudDownloadAlt: faCloudDownloadAlt, + faCloudUploadAlt: faCloudUploadAlt, + faCode: faCode, + faCodeBranch: faCodeBranch, + faCoffee: faCoffee, + faCog: faCog, + faCogs: faCogs, + faColumns: faColumns, + faComment: faComment, + faCommentAlt: faCommentAlt, + faComments: faComments, + faCompass: faCompass, + faCompress: faCompress, + faCopy: faCopy, + faCopyright: faCopyright, + faCreditCard: faCreditCard, + faCrop: faCrop, + faCrosshairs: faCrosshairs, + faCube: faCube, + faCubes: faCubes, + faCut: faCut, + faDatabase: faDatabase, + faDeaf: faDeaf, + faDesktop: faDesktop, + faDollarSign: faDollarSign, + faDotCircle: faDotCircle, + faDownload: faDownload, + faEdit: faEdit, + faEject: faEject, + faEllipsisH: faEllipsisH, + faEllipsisV: faEllipsisV, + faEnvelope: faEnvelope, + faEnvelopeOpen: faEnvelopeOpen, + faEnvelopeSquare: faEnvelopeSquare, + faEraser: faEraser, + faEuroSign: faEuroSign, + faExchangeAlt: faExchangeAlt, + faExclamation: faExclamation, + faExclamationCircle: faExclamationCircle, + faExclamationTriangle: faExclamationTriangle, + faExpand: faExpand, + faExpandArrowsAlt: faExpandArrowsAlt, + faExternalLinkAlt: faExternalLinkAlt, + faExternalLinkSquareAlt: faExternalLinkSquareAlt, + faEye: faEye, + faEyeDropper: faEyeDropper, + faEyeSlash: faEyeSlash, + faFastBackward: faFastBackward, + faFastForward: faFastForward, + faFax: faFax, + faFemale: faFemale, + faFighterJet: faFighterJet, + faFile: faFile, + faFileAlt: faFileAlt, + faFileArchive: faFileArchive, + faFileAudio: faFileAudio, + faFileCode: faFileCode, + faFileExcel: faFileExcel, + faFileImage: faFileImage, + faFilePdf: faFilePdf, + faFilePowerpoint: faFilePowerpoint, + faFileVideo: faFileVideo, + faFileWord: faFileWord, + faFilm: faFilm, + faFilter: faFilter, + faFire: faFire, + faFireExtinguisher: faFireExtinguisher, + faFlag: faFlag, + faFlagCheckered: faFlagCheckered, + faFlask: faFlask, + faFolder: faFolder, + faFolderOpen: faFolderOpen, + faFont: faFont, + faForward: faForward, + faFrown: faFrown, + faFutbol: faFutbol, + faGamepad: faGamepad, + faGavel: faGavel, + faGem: faGem, + faGenderless: faGenderless, + faGift: faGift, + faGlassMartini: faGlassMartini, + faGlobe: faGlobe, + faGraduationCap: faGraduationCap, + faHSquare: faHSquare, + faHandLizard: faHandLizard, + faHandPaper: faHandPaper, + faHandPeace: faHandPeace, + faHandPointDown: faHandPointDown, + faHandPointLeft: faHandPointLeft, + faHandPointRight: faHandPointRight, + faHandPointUp: faHandPointUp, + faHandPointer: faHandPointer, + faHandRock: faHandRock, + faHandScissors: faHandScissors, + faHandSpock: faHandSpock, + faHandshake: faHandshake, + faHashtag: faHashtag, + faHdd: faHdd, + faHeading: faHeading, + faHeadphones: faHeadphones, + faHeart: faHeart, + faHeartbeat: faHeartbeat, + faHistory: faHistory, + faHome: faHome, + faHospital: faHospital, + faHourglass: faHourglass, + faHourglassEnd: faHourglassEnd, + faHourglassHalf: faHourglassHalf, + faHourglassStart: faHourglassStart, + faICursor: faICursor, + faIdBadge: faIdBadge, + faIdCard: faIdCard, + faImage: faImage, + faImages: faImages, + faInbox: faInbox, + faIndent: faIndent, + faIndustry: faIndustry, + faInfo: faInfo, + faInfoCircle: faInfoCircle, + faItalic: faItalic, + faKey: faKey, + faKeyboard: faKeyboard, + faLanguage: faLanguage, + faLaptop: faLaptop, + faLeaf: faLeaf, + faLemon: faLemon, + faLevelDownAlt: faLevelDownAlt, + faLevelUpAlt: faLevelUpAlt, + faLifeRing: faLifeRing, + faLightbulb: faLightbulb, + faLink: faLink, + faLiraSign: faLiraSign, + faList: faList, + faListAlt: faListAlt, + faListOl: faListOl, + faListUl: faListUl, + faLocationArrow: faLocationArrow, + faLock: faLock, + faLockOpen: faLockOpen, + faLongArrowAltDown: faLongArrowAltDown, + faLongArrowAltLeft: faLongArrowAltLeft, + faLongArrowAltRight: faLongArrowAltRight, + faLongArrowAltUp: faLongArrowAltUp, + faLowVision: faLowVision, + faMagic: faMagic, + faMagnet: faMagnet, + faMale: faMale, + faMap: faMap, + faMapMarker: faMapMarker, + faMapMarkerAlt: faMapMarkerAlt, + faMapPin: faMapPin, + faMapSigns: faMapSigns, + faMars: faMars, + faMarsDouble: faMarsDouble, + faMarsStroke: faMarsStroke, + faMarsStrokeH: faMarsStrokeH, + faMarsStrokeV: faMarsStrokeV, + faMedkit: faMedkit, + faMeh: faMeh, + faMercury: faMercury, + faMicrochip: faMicrochip, + faMicrophone: faMicrophone, + faMicrophoneSlash: faMicrophoneSlash, + faMinus: faMinus, + faMinusCircle: faMinusCircle, + faMinusSquare: faMinusSquare, + faMobile: faMobile, + faMobileAlt: faMobileAlt, + faMoneyBillAlt: faMoneyBillAlt, + faMoon: faMoon, + faMotorcycle: faMotorcycle, + faMousePointer: faMousePointer, + faMusic: faMusic, + faNeuter: faNeuter, + faNewspaper: faNewspaper, + faObjectGroup: faObjectGroup, + faObjectUngroup: faObjectUngroup, + faOutdent: faOutdent, + faPaintBrush: faPaintBrush, + faPaperPlane: faPaperPlane, + faPaperclip: faPaperclip, + faParagraph: faParagraph, + faPaste: faPaste, + faPause: faPause, + faPauseCircle: faPauseCircle, + faPaw: faPaw, + faPenSquare: faPenSquare, + faPencilAlt: faPencilAlt, + faPercent: faPercent, + faPhone: faPhone, + faPhoneSquare: faPhoneSquare, + faPhoneVolume: faPhoneVolume, + faPlane: faPlane, + faPlay: faPlay, + faPlayCircle: faPlayCircle, + faPlug: faPlug, + faPlus: faPlus, + faPlusCircle: faPlusCircle, + faPlusSquare: faPlusSquare, + faPodcast: faPodcast, + faPoundSign: faPoundSign, + faPowerOff: faPowerOff, + faPrint: faPrint, + faPuzzlePiece: faPuzzlePiece, + faQrcode: faQrcode, + faQuestion: faQuestion, + faQuestionCircle: faQuestionCircle, + faQuoteLeft: faQuoteLeft, + faQuoteRight: faQuoteRight, + faRandom: faRandom, + faRecycle: faRecycle, + faRedo: faRedo, + faRedoAlt: faRedoAlt, + faRegistered: faRegistered, + faReply: faReply, + faReplyAll: faReplyAll, + faRetweet: faRetweet, + faRoad: faRoad, + faRocket: faRocket, + faRss: faRss, + faRssSquare: faRssSquare, + faRubleSign: faRubleSign, + faRupeeSign: faRupeeSign, + faSave: faSave, + faSearch: faSearch, + faSearchMinus: faSearchMinus, + faSearchPlus: faSearchPlus, + faServer: faServer, + faShare: faShare, + faShareAlt: faShareAlt, + faShareAltSquare: faShareAltSquare, + faShareSquare: faShareSquare, + faShekelSign: faShekelSign, + faShieldAlt: faShieldAlt, + faShip: faShip, + faShoppingBag: faShoppingBag, + faShoppingBasket: faShoppingBasket, + faShoppingCart: faShoppingCart, + faShower: faShower, + faSignInAlt: faSignInAlt, + faSignLanguage: faSignLanguage, + faSignOutAlt: faSignOutAlt, + faSignal: faSignal, + faSitemap: faSitemap, + faSlidersH: faSlidersH, + faSmile: faSmile, + faSnowflake: faSnowflake, + faSort: faSort, + faSortAlphaDown: faSortAlphaDown, + faSortAlphaUp: faSortAlphaUp, + faSortAmountDown: faSortAmountDown, + faSortAmountUp: faSortAmountUp, + faSortDown: faSortDown, + faSortNumericDown: faSortNumericDown, + faSortNumericUp: faSortNumericUp, + faSortUp: faSortUp, + faSpaceShuttle: faSpaceShuttle, + faSpinner: faSpinner, + faSquare: faSquare, + faStar: faStar, + faStarHalf: faStarHalf, + faStepBackward: faStepBackward, + faStepForward: faStepForward, + faStethoscope: faStethoscope, + faStickyNote: faStickyNote, + faStop: faStop, + faStopCircle: faStopCircle, + faStreetView: faStreetView, + faStrikethrough: faStrikethrough, + faSubscript: faSubscript, + faSubway: faSubway, + faSuitcase: faSuitcase, + faSun: faSun, + faSuperscript: faSuperscript, + faSync: faSync, + faSyncAlt: faSyncAlt, + faTable: faTable, + faTablet: faTablet, + faTabletAlt: faTabletAlt, + faTachometerAlt: faTachometerAlt, + faTag: faTag, + faTags: faTags, + faTasks: faTasks, + faTaxi: faTaxi, + faTerminal: faTerminal, + faTextHeight: faTextHeight, + faTextWidth: faTextWidth, + faTh: faTh, + faThLarge: faThLarge, + faThList: faThList, + faThermometerEmpty: faThermometerEmpty, + faThermometerFull: faThermometerFull, + faThermometerHalf: faThermometerHalf, + faThermometerQuarter: faThermometerQuarter, + faThermometerThreeQuarters: faThermometerThreeQuarters, + faThumbsDown: faThumbsDown, + faThumbsUp: faThumbsUp, + faThumbtack: faThumbtack, + faTicketAlt: faTicketAlt, + faTimes: faTimes, + faTimesCircle: faTimesCircle, + faTint: faTint, + faToggleOff: faToggleOff, + faToggleOn: faToggleOn, + faTrademark: faTrademark, + faTrain: faTrain, + faTransgender: faTransgender, + faTransgenderAlt: faTransgenderAlt, + faTrash: faTrash, + faTrashAlt: faTrashAlt, + faTree: faTree, + faTrophy: faTrophy, + faTruck: faTruck, + faTty: faTty, + faTv: faTv, + faUmbrella: faUmbrella, + faUnderline: faUnderline, + faUndo: faUndo, + faUndoAlt: faUndoAlt, + faUniversalAccess: faUniversalAccess, + faUniversity: faUniversity, + faUnlink: faUnlink, + faUnlock: faUnlock, + faUnlockAlt: faUnlockAlt, + faUpload: faUpload, + faUser: faUser, + faUserCircle: faUserCircle, + faUserMd: faUserMd, + faUserPlus: faUserPlus, + faUserSecret: faUserSecret, + faUserTimes: faUserTimes, + faUsers: faUsers, + faUtensilSpoon: faUtensilSpoon, + faUtensils: faUtensils, + faVenus: faVenus, + faVenusDouble: faVenusDouble, + faVenusMars: faVenusMars, + faVideo: faVideo, + faVolumeDown: faVolumeDown, + faVolumeOff: faVolumeOff, + faVolumeUp: faVolumeUp, + faWheelchair: faWheelchair, + faWifi: faWifi, + faWindowClose: faWindowClose, + faWindowMaximize: faWindowMaximize, + faWindowMinimize: faWindowMinimize, + faWindowRestore: faWindowRestore, + faWonSign: faWonSign, + faWrench: faWrench, + faYenSign: faYenSign +}; + +export { prefix, faAddressBook, faAddressCard, faAdjust, faAlignCenter, faAlignJustify, faAlignLeft, faAlignRight, faAmbulance, faAmericanSignLanguageInterpreting, faAnchor, faAngleDoubleDown, faAngleDoubleLeft, faAngleDoubleRight, faAngleDoubleUp, faAngleDown, faAngleLeft, faAngleRight, faAngleUp, faArchive, faArrowAltCircleDown, faArrowAltCircleLeft, faArrowAltCircleRight, faArrowAltCircleUp, faArrowCircleDown, faArrowCircleLeft, faArrowCircleRight, faArrowCircleUp, faArrowDown, faArrowLeft, faArrowRight, faArrowUp, faArrowsAlt, faArrowsAltH, faArrowsAltV, faAssistiveListeningSystems, faAsterisk, faAt, faAudioDescription, faBackward, faBalanceScale, faBan, faBarcode, faBars, faBath, faBatteryEmpty, faBatteryFull, faBatteryHalf, faBatteryQuarter, faBatteryThreeQuarters, faBed, faBeer, faBell, faBellSlash, faBicycle, faBinoculars, faBirthdayCake, faBlind, faBold, faBolt, faBomb, faBook, faBookmark, faBraille, faBriefcase, faBug, faBuilding, faBullhorn, faBullseye, faBus, faCalculator, faCalendar, faCalendarAlt, faCalendarCheck, faCalendarMinus, faCalendarPlus, faCalendarTimes, faCamera, faCameraRetro, faCar, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareLeft, faCaretSquareRight, faCaretSquareUp, faCaretUp, faCartArrowDown, faCartPlus, faCertificate, faChartArea, faChartBar, faChartLine, faChartPie, faCheck, faCheckCircle, faCheckSquare, faChevronCircleDown, faChevronCircleLeft, faChevronCircleRight, faChevronCircleUp, faChevronDown, faChevronLeft, faChevronRight, faChevronUp, faChild, faCircle, faCircleNotch, faClipboard, faClock, faClone, faClosedCaptioning, faCloud, faCloudDownloadAlt, faCloudUploadAlt, faCode, faCodeBranch, faCoffee, faCog, faCogs, faColumns, faComment, faCommentAlt, faComments, faCompass, faCompress, faCopy, faCopyright, faCreditCard, faCrop, faCrosshairs, faCube, faCubes, faCut, faDatabase, faDeaf, faDesktop, faDollarSign, faDotCircle, faDownload, faEdit, faEject, faEllipsisH, faEllipsisV, faEnvelope, faEnvelopeOpen, faEnvelopeSquare, faEraser, faEuroSign, faExchangeAlt, faExclamation, faExclamationCircle, faExclamationTriangle, faExpand, faExpandArrowsAlt, faExternalLinkAlt, faExternalLinkSquareAlt, faEye, faEyeDropper, faEyeSlash, faFastBackward, faFastForward, faFax, faFemale, faFighterJet, faFile, faFileAlt, faFileArchive, faFileAudio, faFileCode, faFileExcel, faFileImage, faFilePdf, faFilePowerpoint, faFileVideo, faFileWord, faFilm, faFilter, faFire, faFireExtinguisher, faFlag, faFlagCheckered, faFlask, faFolder, faFolderOpen, faFont, faForward, faFrown, faFutbol, faGamepad, faGavel, faGem, faGenderless, faGift, faGlassMartini, faGlobe, faGraduationCap, faHSquare, faHandLizard, faHandPaper, faHandPeace, faHandPointDown, faHandPointLeft, faHandPointRight, faHandPointUp, faHandPointer, faHandRock, faHandScissors, faHandSpock, faHandshake, faHashtag, faHdd, faHeading, faHeadphones, faHeart, faHeartbeat, faHistory, faHome, faHospital, faHourglass, faHourglassEnd, faHourglassHalf, faHourglassStart, faICursor, faIdBadge, faIdCard, faImage, faImages, faInbox, faIndent, faIndustry, faInfo, faInfoCircle, faItalic, faKey, faKeyboard, faLanguage, faLaptop, faLeaf, faLemon, faLevelDownAlt, faLevelUpAlt, faLifeRing, faLightbulb, faLink, faLiraSign, faList, faListAlt, faListOl, faListUl, faLocationArrow, faLock, faLockOpen, faLongArrowAltDown, faLongArrowAltLeft, faLongArrowAltRight, faLongArrowAltUp, faLowVision, faMagic, faMagnet, faMale, faMap, faMapMarker, faMapMarkerAlt, faMapPin, faMapSigns, faMars, faMarsDouble, faMarsStroke, faMarsStrokeH, faMarsStrokeV, faMedkit, faMeh, faMercury, faMicrochip, faMicrophone, faMicrophoneSlash, faMinus, faMinusCircle, faMinusSquare, faMobile, faMobileAlt, faMoneyBillAlt, faMoon, faMotorcycle, faMousePointer, faMusic, faNeuter, faNewspaper, faObjectGroup, faObjectUngroup, faOutdent, faPaintBrush, faPaperPlane, faPaperclip, faParagraph, faPaste, faPause, faPauseCircle, faPaw, faPenSquare, faPencilAlt, faPercent, faPhone, faPhoneSquare, faPhoneVolume, faPlane, faPlay, faPlayCircle, faPlug, faPlus, faPlusCircle, faPlusSquare, faPodcast, faPoundSign, faPowerOff, faPrint, faPuzzlePiece, faQrcode, faQuestion, faQuestionCircle, faQuoteLeft, faQuoteRight, faRandom, faRecycle, faRedo, faRedoAlt, faRegistered, faReply, faReplyAll, faRetweet, faRoad, faRocket, faRss, faRssSquare, faRubleSign, faRupeeSign, faSave, faSearch, faSearchMinus, faSearchPlus, faServer, faShare, faShareAlt, faShareAltSquare, faShareSquare, faShekelSign, faShieldAlt, faShip, faShoppingBag, faShoppingBasket, faShoppingCart, faShower, faSignInAlt, faSignLanguage, faSignOutAlt, faSignal, faSitemap, faSlidersH, faSmile, faSnowflake, faSort, faSortAlphaDown, faSortAlphaUp, faSortAmountDown, faSortAmountUp, faSortDown, faSortNumericDown, faSortNumericUp, faSortUp, faSpaceShuttle, faSpinner, faSquare, faStar, faStarHalf, faStepBackward, faStepForward, faStethoscope, faStickyNote, faStop, faStopCircle, faStreetView, faStrikethrough, faSubscript, faSubway, faSuitcase, faSun, faSuperscript, faSync, faSyncAlt, faTable, faTablet, faTabletAlt, faTachometerAlt, faTag, faTags, faTasks, faTaxi, faTerminal, faTextHeight, faTextWidth, faTh, faThLarge, faThList, faThermometerEmpty, faThermometerFull, faThermometerHalf, faThermometerQuarter, faThermometerThreeQuarters, faThumbsDown, faThumbsUp, faThumbtack, faTicketAlt, faTimes, faTimesCircle, faTint, faToggleOff, faToggleOn, faTrademark, faTrain, faTransgender, faTransgenderAlt, faTrash, faTrashAlt, faTree, faTrophy, faTruck, faTty, faTv, faUmbrella, faUnderline, faUndo, faUndoAlt, faUniversalAccess, faUniversity, faUnlink, faUnlock, faUnlockAlt, faUpload, faUser, faUserCircle, faUserMd, faUserPlus, faUserSecret, faUserTimes, faUsers, faUtensilSpoon, faUtensils, faVenus, faVenusDouble, faVenusMars, faVideo, faVolumeDown, faVolumeOff, faVolumeUp, faWheelchair, faWifi, faWindowClose, faWindowMaximize, faWindowMinimize, faWindowRestore, faWonSign, faWrench, faYenSign }; +export default icons$1; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.js new file mode 100644 index 000000000..9697fe3ef --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/index.js @@ -0,0 +1,1412 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global['fontawesome-free-solid'] = {}))); +}(this, (function (exports) { 'use strict'; + +var prefix = "fas"; +var faAddressBook = { prefix: 'fas', iconName: 'address-book', icon: [448, 512, [], "f2b9", "M436 160c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V48c0-26.51-21.49-48-48-48H80C53.49 0 32 21.49 32 48v416c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20v-64h20zM224 96c53.019 0 96 42.981 96 96s-42.981 96-96 96-96-42.981-96-96 42.981-96 96-96zm128 304c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48v-48.711c0-20.994 13.644-39.553 33.683-45.815l22.954-7.173C173.563 312.413 198.198 320 224 320s50.437-7.587 71.363-21.699l22.954 7.173C338.356 311.736 352 330.295 352 351.289V400z"] }; +var faAddressCard = { prefix: 'fas', iconName: 'address-card', icon: [512, 512, [], "f2bb", "M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm-288 64c44.183 0 80 35.817 80 80s-35.817 80-80 80-80-35.817-80-80 35.817-80 80-80zm112 232c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-29.897a24 24 0 0 1 17.407-23.077l28.938-8.268C129.323 312.549 152.087 320 176 320s46.677-7.451 65.656-21.241l28.938 8.268A23.999 23.999 0 0 1 288 330.103V360zm160-52c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8zm0-64c0 6.627-5.373 12-12 12H332c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8z"] }; +var faAdjust = { prefix: 'fas', iconName: 'adjust', icon: [512, 512, [], "f042", "M8 256c0 136.966 111.033 248 248 248s248-111.034 248-248S392.966 8 256 8 8 119.033 8 256zm248 184V72c101.705 0 184 82.311 184 184 0 101.705-82.311 184-184 184z"] }; +var faAlignCenter = { prefix: 'fas', iconName: 'align-center', icon: [448, 512, [], "f037", "M352 44v40c0 8.837-7.163 16-16 16H112c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h224c8.837 0 16 7.163 16 16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm320-200H112c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; +var faAlignJustify = { prefix: 'fas', iconName: 'align-justify', icon: [448, 512, [], "f039", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm16 144h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0-128h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faAlignLeft = { prefix: 'fas', iconName: 'align-left', icon: [448, 512, [], "f036", "M288 44v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16zM0 172v40c0 8.837 7.163 16 16 16h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16zm16 312h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm256-200H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16z"] }; +var faAlignRight = { prefix: 'fas', iconName: 'align-right', icon: [448, 512, [], "f038", "M160 84V44c0-8.837 7.163-16 16-16h256c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H176c-8.837 0-16-7.163-16-16zM16 228h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 256h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faAmbulance = { prefix: 'fas', iconName: 'ambulance', icon: [640, 512, [], "f0f9", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm32-288v32c0 6.627-5.373 12-12 12h-56v56c0 6.627-5.373 12-12 12h-32c-6.627 0-12-5.373-12-12v-56h-56c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h56v-56c0-6.627 5.373-12 12-12h32c6.627 0 12 5.373 12 12v56h56c6.627 0 12 5.373 12 12z"] }; +var faAmericanSignLanguageInterpreting = { prefix: 'fas', iconName: 'american-sign-language-interpreting', icon: [640, 512, [], "f2a3", "M290.547 189.039c-20.295-10.149-44.147-11.199-64.739-3.89 42.606 0 71.208 20.475 85.578 50.576 8.576 17.899-5.148 38.071-23.617 38.071 18.429 0 32.211 20.136 23.617 38.071-14.725 30.846-46.123 50.854-80.298 50.854-.557 0-94.471-8.615-94.471-8.615l-66.406 33.347c-9.384 4.693-19.815.379-23.895-7.781L1.86 290.747c-4.167-8.615-1.111-18.897 6.946-23.621l58.072-33.069L108 159.861c6.39-57.245 34.731-109.767 79.743-146.726 11.391-9.448 28.341-7.781 37.51 3.613 9.446 11.394 7.78 28.067-3.612 37.516-12.503 10.559-23.618 22.509-32.509 35.57 21.672-14.729 46.679-24.732 74.186-28.067 14.725-1.945 28.063 8.336 29.73 23.065 1.945 14.728-8.336 28.067-23.062 29.734-16.116 1.945-31.12 7.503-44.178 15.284 26.114-5.713 58.712-3.138 88.079 11.115 13.336 6.669 18.893 22.509 12.224 35.848-6.389 13.06-22.504 18.617-35.564 12.226zm-27.229 69.472c-6.112-12.505-18.338-20.286-32.231-20.286a35.46 35.46 0 0 0-35.565 35.57c0 21.428 17.808 35.57 35.565 35.57 13.893 0 26.119-7.781 32.231-20.286 4.446-9.449 13.614-15.006 23.339-15.284-9.725-.277-18.893-5.835-23.339-15.284zm374.821-37.237c4.168 8.615 1.111 18.897-6.946 23.621l-58.071 33.069L532 352.16c-6.39 57.245-34.731 109.767-79.743 146.726-10.932 9.112-27.799 8.144-37.51-3.613-9.446-11.394-7.78-28.067 3.613-37.516 12.503-10.559 23.617-22.509 32.508-35.57-21.672 14.729-46.679 24.732-74.186 28.067-10.021 2.506-27.552-5.643-29.73-23.065-1.945-14.728 8.336-28.067 23.062-29.734 16.116-1.946 31.12-7.503 44.178-15.284-26.114 5.713-58.712 3.138-88.079-11.115-13.336-6.669-18.893-22.509-12.224-35.848 6.389-13.061 22.505-18.619 35.565-12.227 20.295 10.149 44.147 11.199 64.739 3.89-42.606 0-71.208-20.475-85.578-50.576-8.576-17.899 5.148-38.071 23.617-38.071-18.429 0-32.211-20.136-23.617-38.071 14.033-29.396 44.039-50.887 81.966-50.854l92.803 8.615 66.406-33.347c9.408-4.704 19.828-.354 23.894 7.781l44.455 88.926zm-229.227-18.618c-13.893 0-26.119 7.781-32.231 20.286-4.446 9.449-13.614 15.006-23.339 15.284 9.725.278 18.893 5.836 23.339 15.284 6.112 12.505 18.338 20.286 32.231 20.286a35.46 35.46 0 0 0 35.565-35.57c0-21.429-17.808-35.57-35.565-35.57z"] }; +var faAnchor = { prefix: 'fas', iconName: 'anchor', icon: [576, 512, [], "f13d", "M12.971 352h32.394C67.172 454.735 181.944 512 288 512c106.229 0 220.853-57.38 242.635-160h32.394c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0l-67.029 67.029c-7.56 7.56-2.206 20.485 8.485 20.485h35.146c-20.29 54.317-84.963 86.588-144.117 94.015V256h52c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-52v-5.47c37.281-13.178 63.995-48.725 64-90.518C384.005 43.772 341.605.738 289.37.01 235.723-.739 192 42.525 192 96c0 41.798 26.716 77.35 64 90.53V192h-52c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v190.015c-58.936-7.399-123.82-39.679-144.117-94.015h35.146c10.691 0 16.045-12.926 8.485-20.485l-67.029-67.029c-4.686-4.686-12.284-4.686-16.971 0L4.485 331.515C-3.074 339.074 2.28 352 12.971 352zM288 64c17.645 0 32 14.355 32 32s-14.355 32-32 32-32-14.355-32-32 14.355-32 32-32z"] }; +var faAngleDoubleDown = { prefix: 'fas', iconName: 'angle-double-down', icon: [320, 512, [], "f103", "M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"] }; +var faAngleDoubleLeft = { prefix: 'fas', iconName: 'angle-double-left', icon: [448, 512, [], "f100", "M223.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L319.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L393.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34zm-192 34l136 136c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9L127.9 256l96.4-96.4c9.4-9.4 9.4-24.6 0-33.9L201.7 103c-9.4-9.4-24.6-9.4-33.9 0l-136 136c-9.5 9.4-9.5 24.6-.1 34z"] }; +var faAngleDoubleRight = { prefix: 'fas', iconName: 'angle-double-right', icon: [448, 512, [], "f101", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34zm192-34l-136-136c-9.4-9.4-24.6-9.4-33.9 0l-22.6 22.6c-9.4 9.4-9.4 24.6 0 33.9l96.4 96.4-96.4 96.4c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l136-136c9.4-9.2 9.4-24.4 0-33.8z"] }; +var faAngleDoubleUp = { prefix: 'fas', iconName: 'angle-double-up', icon: [320, 512, [], "f102", "M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"] }; +var faAngleDown = { prefix: 'fas', iconName: 'angle-down', icon: [320, 512, [], "f107", "M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"] }; +var faAngleLeft = { prefix: 'fas', iconName: 'angle-left', icon: [256, 512, [], "f104", "M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"] }; +var faAngleRight = { prefix: 'fas', iconName: 'angle-right', icon: [256, 512, [], "f105", "M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"] }; +var faAngleUp = { prefix: 'fas', iconName: 'angle-up', icon: [320, 512, [], "f106", "M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"] }; +var faArchive = { prefix: 'fas', iconName: 'archive', icon: [512, 512, [], "f187", "M488 128H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h464c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24zm-8 328V184c0-13.255-10.745-24-24-24H56c-13.255 0-24 10.745-24 24v272c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24zM308 256H204c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h104c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12z"] }; +var faArrowAltCircleDown = { prefix: 'fas', iconName: 'arrow-alt-circle-down', icon: [512, 512, [], "f358", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM212 140v116h-70.9c-10.7 0-16.1 13-8.5 20.5l114.9 114.3c4.7 4.7 12.2 4.7 16.9 0l114.9-114.3c7.6-7.6 2.2-20.5-8.5-20.5H300V140c0-6.6-5.4-12-12-12h-64c-6.6 0-12 5.4-12 12z"] }; +var faArrowAltCircleLeft = { prefix: 'fas', iconName: 'arrow-alt-circle-left', icon: [512, 512, [], "f359", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm116-292H256v-70.9c0-10.7-13-16.1-20.5-8.5L121.2 247.5c-4.7 4.7-4.7 12.2 0 16.9l114.3 114.9c7.6 7.6 20.5 2.2 20.5-8.5V300h116c6.6 0 12-5.4 12-12v-64c0-6.6-5.4-12-12-12z"] }; +var faArrowAltCircleRight = { prefix: 'fas', iconName: 'arrow-alt-circle-right', icon: [512, 512, [], "f35a", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zM140 300h116v70.9c0 10.7 13 16.1 20.5 8.5l114.3-114.9c4.7-4.7 4.7-12.2 0-16.9l-114.3-115c-7.6-7.6-20.5-2.2-20.5 8.5V212H140c-6.6 0-12 5.4-12 12v64c0 6.6 5.4 12 12 12z"] }; +var faArrowAltCircleUp = { prefix: 'fas', iconName: 'arrow-alt-circle-up', icon: [512, 512, [], "f35b", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm292 116V256h70.9c10.7 0 16.1-13 8.5-20.5L264.5 121.2c-4.7-4.7-12.2-4.7-16.9 0l-115 114.3c-7.6 7.6-2.2 20.5 8.5 20.5H212v116c0 6.6 5.4 12 12 12h64c6.6 0 12-5.4 12-12z"] }; +var faArrowCircleDown = { prefix: 'fas', iconName: 'arrow-circle-down', icon: [512, 512, [], "f0ab", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-143.6-28.9L288 302.6V120c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v182.6l-72.4-75.5c-9.3-9.7-24.8-9.9-34.3-.4l-10.9 11c-9.4 9.4-9.4 24.6 0 33.9L239 404.3c9.4 9.4 24.6 9.4 33.9 0l132.7-132.7c9.4-9.4 9.4-24.6 0-33.9l-10.9-11c-9.5-9.5-25-9.3-34.3.4z"] }; +var faArrowCircleLeft = { prefix: 'fas', iconName: 'arrow-circle-left', icon: [512, 512, [], "f0a8", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zm28.9-143.6L209.4 288H392c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H209.4l75.5-72.4c9.7-9.3 9.9-24.8.4-34.3l-11-10.9c-9.4-9.4-24.6-9.4-33.9 0L107.7 239c-9.4 9.4-9.4 24.6 0 33.9l132.7 132.7c9.4 9.4 24.6 9.4 33.9 0l11-10.9c9.5-9.5 9.3-25-.4-34.3z"] }; +var faArrowCircleRight = { prefix: 'fas', iconName: 'arrow-circle-right', icon: [512, 512, [], "f0a9", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"] }; +var faArrowCircleUp = { prefix: 'fas', iconName: 'arrow-circle-up', icon: [512, 512, [], "f0aa", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z"] }; +var faArrowDown = { prefix: 'fas', iconName: 'arrow-down', icon: [448, 512, [], "f063", "M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"] }; +var faArrowLeft = { prefix: 'fas', iconName: 'arrow-left', icon: [448, 512, [], "f060", "M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"] }; +var faArrowRight = { prefix: 'fas', iconName: 'arrow-right', icon: [448, 512, [], "f061", "M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"] }; +var faArrowUp = { prefix: 'fas', iconName: 'arrow-up', icon: [448, 512, [], "f062", "M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"] }; +var faArrowsAlt = { prefix: 'fas', iconName: 'arrows-alt', icon: [512, 512, [], "f0b2", "M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z"] }; +var faArrowsAltH = { prefix: 'fas', iconName: 'arrows-alt-h', icon: [512, 512, [], "f337", "M377.941 169.941V216H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.568 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296h243.882v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.568 0-33.941l-86.059-86.059c-15.119-15.12-40.971-4.412-40.971 16.97z"] }; +var faArrowsAltV = { prefix: 'fas', iconName: 'arrows-alt-v', icon: [256, 512, [], "f338", "M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"] }; +var faAssistiveListeningSystems = { prefix: 'fas', iconName: 'assistive-listening-systems', icon: [512, 512, [], "f2a2", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm-80 236c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zM32 448c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm480-187.993c0-1.518-.012-3.025-.045-4.531C510.076 140.525 436.157 38.47 327.994 1.511c-14.633-4.998-30.549 2.809-35.55 17.442-5 14.633 2.81 30.549 17.442 35.55 85.906 29.354 144.61 110.513 146.077 201.953l.003.188c.026 1.118.033 2.236.033 3.363 0 15.464 12.536 28 28 28s28.001-12.536 28.001-28zM152.971 439.029l-80-80L39.03 392.97l80 80 33.941-33.941z"] }; +var faAsterisk = { prefix: 'fas', iconName: 'asterisk', icon: [512, 512, [], "f069", "M478.21 334.093L336 256l142.21-78.093c11.795-6.477 15.961-21.384 9.232-33.037l-19.48-33.741c-6.728-11.653-21.72-15.499-33.227-8.523L296 186.718l3.475-162.204C299.763 11.061 288.937 0 275.48 0h-38.96c-13.456 0-24.283 11.061-23.994 24.514L216 186.718 77.265 102.607c-11.506-6.976-26.499-3.13-33.227 8.523l-19.48 33.741c-6.728 11.653-2.562 26.56 9.233 33.037L176 256 33.79 334.093c-11.795 6.477-15.961 21.384-9.232 33.037l19.48 33.741c6.728 11.653 21.721 15.499 33.227 8.523L216 325.282l-3.475 162.204C212.237 500.939 223.064 512 236.52 512h38.961c13.456 0 24.283-11.061 23.995-24.514L296 325.282l138.735 84.111c11.506 6.976 26.499 3.13 33.227-8.523l19.48-33.741c6.728-11.653 2.563-26.559-9.232-33.036z"] }; +var faAt = { prefix: 'fas', iconName: 'at', icon: [512, 512, [], "f1fa", "M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"] }; +var faAudioDescription = { prefix: 'fas', iconName: 'audio-description', icon: [512, 512, [], "f29e", "M162.925 238.709l8.822 30.655h-25.606l9.041-30.652c1.277-4.421 2.651-9.994 3.872-15.245 1.22 5.251 2.594 10.823 3.871 15.242zm166.474-32.099h-14.523v98.781h14.523c29.776 0 46.175-17.678 46.175-49.776 0-32.239-17.49-49.005-46.175-49.005zM512 112v288c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48zM245.459 336.139l-57.097-168A12.001 12.001 0 0 0 177 160h-35.894a12.001 12.001 0 0 0-11.362 8.139l-57.097 168C70.003 343.922 75.789 352 84.009 352h29.133a12 12 0 0 0 11.535-8.693l8.574-29.906h51.367l8.793 29.977A12 12 0 0 0 204.926 352h29.172c8.22 0 14.006-8.078 11.361-15.861zm184.701-80.525c0-58.977-37.919-95.614-98.96-95.614h-57.366c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12H331.2c61.041 0 98.96-36.933 98.96-96.386z"] }; +var faBackward = { prefix: 'fas', iconName: 'backward', icon: [512, 512, [], "f04a", "M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z"] }; +var faBalanceScale = { prefix: 'fas', iconName: 'balance-scale', icon: [640, 512, [], "f24e", "M352 448h168c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H120c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h168V153.324C264.469 143.04 246.836 121.778 241.603 96H120c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h135.999C270.594 12.57 293.828 0 320 0s49.406 12.57 64.001 32H520c13.255 0 24 10.745 24 24v16c0 13.255-10.745 24-24 24H398.397c-5.233 25.778-22.866 47.04-46.397 57.324V448zm287.981-112c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C381.94 328.75 384.019 320.331 384.019 336H384c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM512 176l72 144H440l72-144zM255.981 336c.001-16.182 1.342-8.726-85.048-181.506-17.647-35.294-68.186-35.358-85.865 0C-2.06 328.75.019 320.331.019 336H0c0 44.183 57.308 80 128 80s128-35.817 128-80h-.019zM128 176l72 144H56l72-144z"] }; +var faBan = { prefix: 'fas', iconName: 'ban', icon: [512, 512, [], "f05e", "M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"] }; +var faBarcode = { prefix: 'fas', iconName: 'barcode', icon: [512, 512, [], "f02a", "M0 448V64h18v384H0zm26.857-.273V64H36v383.727h-9.143zm27.143 0V64h8.857v383.727H54zm44.857 0V64h8.857v383.727h-8.857zm36 0V64h17.714v383.727h-17.714zm44.857 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm18 0V64h8.857v383.727h-8.857zm35.715 0V64h18v383.727h-18zm44.857 0V64h18v383.727h-18zm35.999 0V64h18.001v383.727h-18.001zm36.001 0V64h18.001v383.727h-18.001zm26.857 0V64h18v383.727h-18zm45.143 0V64h26.857v383.727h-26.857zm35.714 0V64h9.143v383.727H476zm18 .273V64h18v384h-18z"] }; +var faBars = { prefix: 'fas', iconName: 'bars', icon: [448, 512, [], "f0c9", "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faBath = { prefix: 'fas', iconName: 'bath', icon: [512, 512, [], "f2cd", "M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; +var faBatteryEmpty = { prefix: 'fas', iconName: 'battery-empty', icon: [640, 512, [], "f244", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48z"] }; +var faBatteryFull = { prefix: 'fas', iconName: 'battery-full', icon: [640, 512, [], "f240", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-48 96H96v128h416V192z"] }; +var faBatteryHalf = { prefix: 'fas', iconName: 'battery-half', icon: [640, 512, [], "f242", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-240 96H96v128h224V192z"] }; +var faBatteryQuarter = { prefix: 'fas', iconName: 'battery-quarter', icon: [640, 512, [], "f243", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-336 96H96v128h128V192z"] }; +var faBatteryThreeQuarters = { prefix: 'fas', iconName: 'battery-three-quarters', icon: [640, 512, [], "f241", "M544 160v64h32v64h-32v64H64V160h480m16-64H48c-26.51 0-48 21.49-48 48v224c0 26.51 21.49 48 48 48h512c26.51 0 48-21.49 48-48v-16h8c13.255 0 24-10.745 24-24V184c0-13.255-10.745-24-24-24h-8v-16c0-26.51-21.49-48-48-48zm-144 96H96v128h320V192z"] }; +var faBed = { prefix: 'fas', iconName: 'bed', icon: [576, 512, [], "f236", "M552 288c13.255 0 24 10.745 24 24v136h-96v-64H96v64H0V88c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v200h456zM192 96c-44.183 0-80 35.817-80 80s35.817 80 80 80 80-35.817 80-80-35.817-80-80-80zm384 128c0-53.019-42.981-96-96-96H312c-13.255 0-24 10.745-24 24v104h288v-32z"] }; +var faBeer = { prefix: 'fas', iconName: 'beer', icon: [448, 512, [], "f0fc", "M368 96h-48V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24v-42.11l80.606-35.977C429.396 365.063 448 336.388 448 304.86V176c0-44.112-35.888-80-80-80zm16 208.86a16.018 16.018 0 0 1-9.479 14.611L320 343.805V160h48c8.822 0 16 7.178 16 16v128.86zM208 384c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16zm-96 0c-8.836 0-16-7.164-16-16V144c0-8.836 7.164-16 16-16s16 7.164 16 16v224c0 8.836-7.164 16-16 16z"] }; +var faBell = { prefix: 'fas', iconName: 'bell', icon: [448, 512, [], "f0f3", "M433.884 366.059C411.634 343.809 384 316.118 384 208c0-79.394-57.831-145.269-133.663-157.83A31.845 31.845 0 0 0 256 32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 6.75 2.095 13.008 5.663 18.17C121.831 62.731 64 128.606 64 208c0 108.118-27.643 135.809-49.893 158.059C-16.042 396.208 5.325 448 48.048 448H160c0 35.346 28.654 64 64 64s64-28.654 64-64h111.943c42.638 0 64.151-51.731 33.941-81.941zM224 472a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16c0 13.234 10.766 24 24 24z"] }; +var faBellSlash = { prefix: 'fas', iconName: 'bell-slash', icon: [576, 512, [], "f1f6", "M78.107 366.059C47.958 396.208 69.325 448 112.048 448H224c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64h32.685L127.848 221.379c-2.198 97.078-28.439 123.378-49.741 144.68zM264 448c0 13.234 10.766 24 24 24a8 8 0 0 1 0 16c-22.056 0-40-17.944-40-40h16zm305.896 43.733l-10.762 12.086c-8.915 10.012-24.333 10.967-34.437 2.133L8.256 54.393C-1.848 45.558-2.811 30.28 6.104 20.267L16.865 8.181C25.781-1.831 41.199-2.786 51.303 6.049l113.81 99.512c24.017-28.778 57.946-48.996 96.55-55.39A31.85 31.85 0 0 1 256 32c0-17.673 14.327-32 32-32s32 14.327 32 32c0 6.75-2.095 13.008-5.663 18.17C390.169 62.731 448 128.606 448 208c0 108.118 27.634 135.809 49.884 158.059 12.149 12.149 15.923 27.776 13.33 42.121l56.53 49.427c10.104 8.835 11.067 24.113 2.152 34.126z"] }; +var faBicycle = { prefix: 'fas', iconName: 'bicycle', icon: [640, 512, [], "f206", "M512.509 192.001c-16.373-.064-32.03 2.955-46.436 8.495l-77.68-125.153A24 24 0 0 0 368.001 64h-64c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h50.649l14.896 24H256.002v-16c0-8.837-7.163-16-16-16h-87.459c-13.441 0-24.777 10.999-24.536 24.437.232 13.044 10.876 23.563 23.995 23.563h48.726l-29.417 47.52c-13.433-4.83-27.904-7.483-42.992-7.52C58.094 191.83.412 249.012.002 319.236-.413 390.279 57.055 448 128.002 448c59.642 0 109.758-40.793 123.967-96h52.033a24 24 0 0 0 20.406-11.367L410.37 201.77l14.938 24.067c-25.455 23.448-41.385 57.081-41.307 94.437.145 68.833 57.899 127.051 126.729 127.719 70.606.685 128.181-55.803 129.255-125.996 1.086-70.941-56.526-129.72-127.476-129.996zM186.75 265.772c9.727 10.529 16.673 23.661 19.642 38.228h-43.306l23.664-38.228zM128.002 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c5.869 0 11.586.653 17.099 1.859l-45.505 73.509C89.715 331.327 101.213 352 120.002 352h81.3c-12.37 28.225-40.562 48-73.3 48zm162.63-96h-35.624c-3.96-31.756-19.556-59.894-42.383-80.026L237.371 184h127.547l-74.286 120zm217.057 95.886c-41.036-2.165-74.049-35.692-75.627-76.755-.812-21.121 6.633-40.518 19.335-55.263l44.433 71.586c4.66 7.508 14.524 9.816 22.032 5.156l13.594-8.437c7.508-4.66 9.817-14.524 5.156-22.032l-44.468-71.643a79.901 79.901 0 0 1 19.858-2.497c44.112 0 80 35.888 80 80-.001 45.54-38.252 82.316-84.313 79.885z"] }; +var faBinoculars = { prefix: 'fas', iconName: 'binoculars', icon: [512, 512, [], "f1e5", "M192 104H96V56c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24v48zm224-48c0-13.255-10.745-24-24-24h-48c-13.255 0-24 10.745-24 24v48h96V56zM0 456c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H0v16zm88-328c-13.255 0-24 10.745-24 24C64 256 0 272 0 416h168V312c0-13.255 10.745-24 24-24V128H88zm256 328c0 13.255 10.745 24 24 24h120c13.255 0 24-10.745 24-24v-16H344v16zM216 128v160h80V128h-80zm128 288h168c0-144-64-160-64-264 0-13.255-10.745-24-24-24H320v160c13.255 0 24 10.745 24 24v104z"] }; +var faBirthdayCake = { prefix: 'fas', iconName: 'birthday-cake', icon: [448, 512, [], "f1fd", "M448 384c-28.02 0-31.26-32-74.5-32-43.43 0-46.825 32-74.75 32-27.695 0-31.454-32-74.75-32-42.842 0-47.218 32-74.5 32-28.148 0-31.202-32-74.75-32-43.547 0-46.653 32-74.75 32v-80c0-26.5 21.5-48 48-48h16V112h64v144h64V112h64v144h64V112h64v144h16c26.5 0 48 21.5 48 48v80zm0 128H0v-96c43.356 0 46.767-32 74.75-32 27.951 0 31.253 32 74.75 32 42.843 0 47.217-32 74.5-32 28.148 0 31.201 32 74.75 32 43.357 0 46.767-32 74.75-32 27.488 0 31.252 32 74.5 32v96zM96 96c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40zm128 0c-17.75 0-32-14.25-32-32 0-31 32-23 32-64 12 0 32 29.5 32 56s-14.25 40-32 40z"] }; +var faBlind = { prefix: 'fas', iconName: 'blind', icon: [384, 512, [], "f29d", "M380.15 510.837a8 8 0 0 1-10.989-2.687l-125.33-206.427a31.923 31.923 0 0 0 12.958-9.485l126.048 207.608a8 8 0 0 1-2.687 10.991zM142.803 314.338l-32.54 89.485 36.12 88.285c6.693 16.36 25.377 24.192 41.733 17.501 16.357-6.692 24.193-25.376 17.501-41.734l-62.814-153.537zM96 88c24.301 0 44-19.699 44-44S120.301 0 96 0 52 19.699 52 44s19.699 44 44 44zm154.837 169.128l-120-152c-4.733-5.995-11.75-9.108-18.837-9.112V96H80v.026c-7.146.003-14.217 3.161-18.944 9.24L0 183.766v95.694c0 13.455 11.011 24.791 24.464 24.536C37.505 303.748 48 293.1 48 280v-79.766l16-20.571v140.698L9.927 469.055c-6.04 16.609 2.528 34.969 19.138 41.009 16.602 6.039 34.968-2.524 41.009-19.138L136 309.638V202.441l-31.406-39.816a4 4 0 1 1 6.269-4.971l102.3 129.217c9.145 11.584 24.368 11.339 33.708 3.965 10.41-8.216 12.159-23.334 3.966-33.708z"] }; +var faBold = { prefix: 'fas', iconName: 'bold', icon: [384, 512, [], "f032", "M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z"] }; +var faBolt = { prefix: 'fas', iconName: 'bolt', icon: [320, 512, [], "f0e7", "M295.973 160H180.572L215.19 30.184C219.25 14.956 207.756 0 192 0H56C43.971 0 33.8 8.905 32.211 20.828l-31.996 240C-1.704 275.217 9.504 288 24.004 288h118.701L96.646 482.466C93.05 497.649 104.659 512 119.992 512c8.35 0 16.376-4.374 20.778-11.978l175.973-303.997c9.244-15.967-2.288-36.025-20.77-36.025z"] }; +var faBomb = { prefix: 'fas', iconName: 'bomb', icon: [512, 512, [], "f1e2", "M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z"] }; +var faBook = { prefix: 'fas', iconName: 'book', icon: [448, 512, [], "f02d", "M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"] }; +var faBookmark = { prefix: 'fas', iconName: 'bookmark', icon: [384, 512, [], "f02e", "M0 512V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v464L192 400 0 512z"] }; +var faBraille = { prefix: 'fas', iconName: 'braille', icon: [640, 512, [], "f2a1", "M128 256c0 35.346-28.654 64-64 64S0 291.346 0 256s28.654-64 64-64 64 28.654 64 64zM64 384c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352C28.654 32 0 60.654 0 96s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm224 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zm160 192c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 160c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0-320c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faBriefcase = { prefix: 'fas', iconName: 'briefcase', icon: [512, 512, [], "f0b1", "M320 288h192v144c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V288h192v20c0 6.627 5.373 12 12 12h104c6.627 0 12-5.373 12-12v-20zm192-112v80H0v-80c0-26.51 21.49-48 48-48h80V80c0-26.51 21.49-48 48-48h160c26.51 0 48 21.49 48 48v48h80c26.51 0 48 21.49 48 48zM320 96H192v32h128V96z"] }; +var faBug = { prefix: 'fas', iconName: 'bug', icon: [512, 512, [], "f188", "M511.988 288.9c-.478 17.43-15.217 31.1-32.653 31.1H424v16c0 21.864-4.882 42.584-13.6 61.145l60.228 60.228c12.496 12.497 12.496 32.758 0 45.255-12.498 12.497-32.759 12.496-45.256 0l-54.736-54.736C345.886 467.965 314.351 480 280 480V236c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v244c-34.351 0-65.886-12.035-90.636-32.108l-54.736 54.736c-12.498 12.497-32.759 12.496-45.256 0-12.496-12.497-12.496-32.758 0-45.255l60.228-60.228C92.882 378.584 88 357.864 88 336v-16H32.666C15.23 320 .491 306.33.013 288.9-.484 270.816 14.028 256 32 256h56v-58.745l-46.628-46.628c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0L141.255 160h229.489l54.627-54.627c12.498-12.497 32.758-12.497 45.256 0 12.496 12.497 12.496 32.758 0 45.255L424 197.255V256h56c17.972 0 32.484 14.816 31.988 32.9zM257 0c-61.856 0-112 50.144-112 112h224C369 50.144 318.856 0 257 0z"] }; +var faBuilding = { prefix: 'fas', iconName: 'building', icon: [448, 512, [], "f1ad", "M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z"] }; +var faBullhorn = { prefix: 'fas', iconName: 'bullhorn', icon: [576, 512, [], "f0a1", "M576 224c0-20.896-13.36-38.666-32-45.258V64c0-35.346-28.654-64-64-64-64.985 56-142.031 128-272 128H48c-26.51 0-48 21.49-48 48v96c0 26.51 21.49 48 48 48h43.263c-18.742 64.65 2.479 116.379 18.814 167.44 1.702 5.32 5.203 9.893 9.922 12.88 20.78 13.155 68.355 15.657 93.773 5.151 16.046-6.633 19.96-27.423 7.522-39.537-18.508-18.026-30.136-36.91-19.795-60.858a12.278 12.278 0 0 0-1.045-11.673c-16.309-24.679-3.581-62.107 28.517-72.752C346.403 327.887 418.591 395.081 480 448c35.346 0 64-28.654 64-64V269.258c18.64-6.592 32-24.362 32-45.258zm-96 139.855c-54.609-44.979-125.033-92.94-224-104.982v-69.747c98.967-12.042 169.391-60.002 224-104.982v279.711z"] }; +var faBullseye = { prefix: 'fas', iconName: 'bullseye', icon: [512, 512, [], "f140", "M256 72c101.689 0 184 82.295 184 184 0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-101.689 82.295-184 184-184m0-64C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 184c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64m0-64c-70.692 0-128 57.308-128 128s57.308 128 128 128 128-57.308 128-128-57.308-128-128-128z"] }; +var faBus = { prefix: 'fas', iconName: 'bus', icon: [512, 512, [], "f207", "M512 152v80c0 13.255-10.745 24-24 24h-8v168c0 13.255-10.745 24-24 24h-8v40c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24v-40H160v40c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24v-40h-8c-13.255 0-24-10.745-24-24V256h-8c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h8V80C32 35.817 132.288 0 256 0s224 35.817 224 80v48h8c13.255 0 24 10.745 24 24zM112 320c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm32-56V120c0-13.255-10.745-24-24-24H104c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; +var faCalculator = { prefix: 'fas', iconName: 'calculator', icon: [448, 512, [], "f1ec", "M0 464V48C0 21.49 21.49 0 48 0h352c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm384-284V76c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v104c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12zM128 308v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm256 128V268c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v168c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-256 0v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm128-128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm0 128v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faCalendar = { prefix: 'fas', iconName: 'calendar', icon: [448, 512, [], "f133", "M12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm436-44v-36c0-26.5-21.5-48-48-48h-48V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H160V12c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v52H48C21.5 64 0 85.5 0 112v36c0 6.6 5.4 12 12 12h424c6.6 0 12-5.4 12-12z"] }; +var faCalendarAlt = { prefix: 'fas', iconName: 'calendar-alt', icon: [448, 512, [], "f073", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm116 204c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm128 128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40zm0-128c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-40z"] }; +var faCalendarCheck = { prefix: 'fas', iconName: 'calendar-check', icon: [448, 512, [], "f274", "M436 160H12c-6.627 0-12-5.373-12-12v-36c0-26.51 21.49-48 48-48h48V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h128V12c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v52h48c26.51 0 48 21.49 48 48v36c0 6.627-5.373 12-12 12zM12 192h424c6.627 0 12 5.373 12 12v260c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V204c0-6.627 5.373-12 12-12zm333.296 95.947l-28.169-28.398c-4.667-4.705-12.265-4.736-16.97-.068L194.12 364.665l-45.98-46.352c-4.667-4.705-12.266-4.736-16.971-.068l-28.397 28.17c-4.705 4.667-4.736 12.265-.068 16.97l82.601 83.269c4.667 4.705 12.265 4.736 16.97.068l142.953-141.805c4.705-4.667 4.736-12.265.068-16.97z"] }; +var faCalendarMinus = { prefix: 'fas', iconName: 'calendar-minus', icon: [448, 512, [], "f272", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm304 192c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H132c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h184z"] }; +var faCalendarPlus = { prefix: 'fas', iconName: 'calendar-plus', icon: [448, 512, [], "f271", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm316 140c0-6.6-5.4-12-12-12h-60v-60c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v60h-60c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h60v60c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-60h60c6.6 0 12-5.4 12-12v-40z"] }; +var faCalendarTimes = { prefix: 'fas', iconName: 'calendar-times', icon: [448, 512, [], "f273", "M436 160H12c-6.6 0-12-5.4-12-12v-36c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48v36c0 6.6-5.4 12-12 12zM12 192h424c6.6 0 12 5.4 12 12v260c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V204c0-6.6 5.4-12 12-12zm257.3 160l48.1-48.1c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0L224 306.7l-48.1-48.1c-4.7-4.7-12.3-4.7-17 0l-28.3 28.3c-4.7 4.7-4.7 12.3 0 17l48.1 48.1-48.1 48.1c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l48.1-48.1 48.1 48.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L269.3 352z"] }; +var faCamera = { prefix: 'fas', iconName: 'camera', icon: [512, 512, [], "f030", "M512 144v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48h88l12.3-32.9c7-18.7 24.9-31.1 44.9-31.1h125.5c20 0 37.9 12.4 44.9 31.1L376 96h88c26.5 0 48 21.5 48 48zM376 288c0-66.2-53.8-120-120-120s-120 53.8-120 120 53.8 120 120 120 120-53.8 120-120zm-32 0c0 48.5-39.5 88-88 88s-88-39.5-88-88 39.5-88 88-88 88 39.5 88 88z"] }; +var faCameraRetro = { prefix: 'fas', iconName: 'camera-retro', icon: [512, 512, [], "f083", "M48 32C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H48zm0 32h106c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H38c-3.3 0-6-2.7-6-6V80c0-8.8 7.2-16 16-16zm426 96H38c-3.3 0-6-2.7-6-6v-36c0-3.3 2.7-6 6-6h138l30.2-45.3c1.1-1.7 3-2.7 5-2.7H464c8.8 0 16 7.2 16 16v74c0 3.3-2.7 6-6 6zM256 424c-66.2 0-120-53.8-120-120s53.8-120 120-120 120 53.8 120 120-53.8 120-120 120zm0-208c-48.5 0-88 39.5-88 88s39.5 88 88 88 88-39.5 88-88-39.5-88-88-88zm-48 104c-8.8 0-16-7.2-16-16 0-35.3 28.7-64 64-64 8.8 0 16 7.2 16 16s-7.2 16-16 16c-17.6 0-32 14.4-32 32 0 8.8-7.2 16-16 16z"] }; +var faCar = { prefix: 'fas', iconName: 'car', icon: [512, 512, [], "f1b9", "M499.991 168h-54.815l-7.854-20.944c-9.192-24.513-25.425-45.351-46.942-60.263S343.651 64 317.472 64H194.528c-26.18 0-51.391 7.882-72.908 22.793-21.518 14.912-37.75 35.75-46.942 60.263L66.824 168H12.009c-8.191 0-13.974 8.024-11.384 15.795l8 24A12 12 0 0 0 20.009 216h28.815l-.052.14C29.222 227.093 16 247.997 16 272v48c0 16.225 6.049 31.029 16 42.309V424c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-61.691c9.951-11.281 16-26.085 16-42.309v-48c0-24.003-13.222-44.907-32.772-55.86l-.052-.14h28.815a12 12 0 0 0 11.384-8.205l8-24c2.59-7.771-3.193-15.795-11.384-15.795zm-365.388 1.528C143.918 144.689 168 128 194.528 128h122.944c26.528 0 50.61 16.689 59.925 41.528L391.824 208H120.176l14.427-38.472zM88 328c-17.673 0-32-14.327-32-32 0-17.673 14.327-32 32-32s48 30.327 48 48-30.327 16-48 16zm336 0c-17.673 0-48 1.673-48-16 0-17.673 30.327-48 48-48s32 14.327 32 32c0 17.673-14.327 32-32 32z"] }; +var faCaretDown = { prefix: 'fas', iconName: 'caret-down', icon: [320, 512, [], "f0d7", "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"] }; +var faCaretLeft = { prefix: 'fas', iconName: 'caret-left', icon: [192, 512, [], "f0d9", "M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"] }; +var faCaretRight = { prefix: 'fas', iconName: 'caret-right', icon: [192, 512, [], "f0da", "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"] }; +var faCaretSquareDown = { prefix: 'fas', iconName: 'caret-square-down', icon: [448, 512, [], "f150", "M448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM92.5 220.5l123 123c4.7 4.7 12.3 4.7 17 0l123-123c7.6-7.6 2.2-20.5-8.5-20.5H101c-10.7 0-16.1 12.9-8.5 20.5z"] }; +var faCaretSquareLeft = { prefix: 'fas', iconName: 'caret-square-left', icon: [448, 512, [], "f191", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM259.515 124.485l-123.03 123.03c-4.686 4.686-4.686 12.284 0 16.971l123.029 123.029c7.56 7.56 20.485 2.206 20.485-8.485V132.971c.001-10.691-12.925-16.045-20.484-8.486z"] }; +var faCaretSquareRight = { prefix: 'fas', iconName: 'caret-square-right', icon: [448, 512, [], "f152", "M48 32h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48zm140.485 355.515l123.029-123.029c4.686-4.686 4.686-12.284 0-16.971l-123.029-123.03c-7.56-7.56-20.485-2.206-20.485 8.485v246.059c0 10.691 12.926 16.045 20.485 8.486z"] }; +var faCaretSquareUp = { prefix: 'fas', iconName: 'caret-square-up', icon: [448, 512, [], "f151", "M0 432V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm355.515-140.485l-123.03-123.03c-4.686-4.686-12.284-4.686-16.971 0L92.485 291.515c-7.56 7.56-2.206 20.485 8.485 20.485h246.059c10.691 0 16.045-12.926 8.486-20.485z"] }; +var faCaretUp = { prefix: 'fas', iconName: 'caret-up', icon: [320, 512, [], "f0d8", "M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"] }; +var faCartArrowDown = { prefix: 'fas', iconName: 'cart-arrow-down', icon: [576, 512, [], "f218", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM403.029 192H360v-60c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v60h-43.029c-10.691 0-16.045 12.926-8.485 20.485l67.029 67.029c4.686 4.686 12.284 4.686 16.971 0l67.029-67.029c7.559-7.559 2.205-20.485-8.486-20.485z"] }; +var faCartPlus = { prefix: 'fas', iconName: 'cart-plus', icon: [576, 512, [], "f217", "M504.717 320H211.572l6.545 32h268.418c15.401 0 26.816 14.301 23.403 29.319l-5.517 24.276C523.112 414.668 536 433.828 536 456c0 31.202-25.519 56.444-56.824 55.994-29.823-.429-54.35-24.631-55.155-54.447-.44-16.287 6.085-31.049 16.803-41.548H231.176C241.553 426.165 248 440.326 248 456c0 31.813-26.528 57.431-58.67 55.938-28.54-1.325-51.751-24.385-53.251-52.917-1.158-22.034 10.436-41.455 28.051-51.586L93.883 64H24C10.745 64 0 53.255 0 40V24C0 10.745 10.745 0 24 0h102.529c11.401 0 21.228 8.021 23.513 19.19L159.208 64H551.99c15.401 0 26.816 14.301 23.403 29.319l-47.273 208C525.637 312.246 515.923 320 504.717 320zM408 168h-48v-40c0-8.837-7.163-16-16-16h-16c-8.837 0-16 7.163-16 16v40h-48c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h48v40c0 8.837 7.163 16 16 16h16c8.837 0 16-7.163 16-16v-40h48c8.837 0 16-7.163 16-16v-16c0-8.837-7.163-16-16-16z"] }; +var faCertificate = { prefix: 'fas', iconName: 'certificate', icon: [512, 512, [], "f0a3", "M458.622 255.92l45.985-45.005c13.708-12.977 7.316-36.039-10.664-40.339l-62.65-15.99 17.661-62.015c4.991-17.838-11.829-34.663-29.661-29.671l-61.994 17.667-15.984-62.671C337.085.197 313.765-6.276 300.99 7.228L256 53.57 211.011 7.229c-12.63-13.351-36.047-7.234-40.325 10.668l-15.984 62.671-61.995-17.667C74.87 57.907 58.056 74.738 63.046 92.572l17.661 62.015-62.65 15.99C.069 174.878-6.31 197.944 7.392 210.915l45.985 45.005-45.985 45.004c-13.708 12.977-7.316 36.039 10.664 40.339l62.65 15.99-17.661 62.015c-4.991 17.838 11.829 34.663 29.661 29.671l61.994-17.667 15.984 62.671c4.439 18.575 27.696 24.018 40.325 10.668L256 458.61l44.989 46.001c12.5 13.488 35.987 7.486 40.325-10.668l15.984-62.671 61.994 17.667c17.836 4.994 34.651-11.837 29.661-29.671l-17.661-62.015 62.65-15.99c17.987-4.302 24.366-27.367 10.664-40.339l-45.984-45.004z"] }; +var faChartArea = { prefix: 'fas', iconName: 'chart-area', icon: [512, 512, [], "f1fe", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM372.7 159.5L288 216l-85.3-113.7c-5.1-6.8-15.5-6.3-19.9 1L96 248v104h384l-89.9-187.8c-3.2-6.5-11.4-8.7-17.4-4.7z"] }; +var faChartBar = { prefix: 'fas', iconName: 'chart-bar', icon: [512, 512, [], "f080", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zm-308-44v-72c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v72c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V204c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v136c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0V140c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v200c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0V108c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v232c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; +var faChartLine = { prefix: 'fas', iconName: 'chart-line', icon: [512, 512, [], "f201", "M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z"] }; +var faChartPie = { prefix: 'fas', iconName: 'chart-pie', icon: [576, 512, [], "f200", "M288 12.3V240h227.7c6.9 0 12.3-5.8 12-12.7-6.4-122.4-104.5-220.6-227-227-6.9-.3-12.7 5.1-12.7 12zM552.7 288c6.9 0 12.3 5.8 12 12.7-2.8 53.2-23.2 105.6-61.2 147.8-4.6 5.1-12.6 5.4-17.5.5L325 288h227.7zM401 433c4.8 4.8 4.7 12.8-.4 17.3-42.6 38.4-99 61.7-160.8 61.7C107.6 511.9-.2 403.8 0 271.5.2 143.4 100.8 38.9 227.3 32.3c6.9-.4 12.7 5.1 12.7 12V272l161 161z"] }; +var faCheck = { prefix: 'fas', iconName: 'check', icon: [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"] }; +var faCheckCircle = { prefix: 'fas', iconName: 'check-circle', icon: [512, 512, [], "f058", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"] }; +var faCheckSquare = { prefix: 'fas', iconName: 'check-square', icon: [448, 512, [], "f14a", "M400 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zm-204.686-98.059l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.248-16.379-6.249-22.628 0L184 302.745l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.25 16.379 6.25 22.628.001z"] }; +var faChevronCircleDown = { prefix: 'fas', iconName: 'chevron-circle-down', icon: [512, 512, [], "f13a", "M504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zM273 369.9l135.5-135.5c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L256 285.1 154.4 183.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L239 369.9c9.4 9.4 24.6 9.4 34 0z"] }; +var faChevronCircleLeft = { prefix: 'fas', iconName: 'chevron-circle-left', icon: [512, 512, [], "f137", "M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z"] }; +var faChevronCircleRight = { prefix: 'fas', iconName: 'chevron-circle-right', icon: [512, 512, [], "f138", "M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm113.9 231L234.4 103.5c-9.4-9.4-24.6-9.4-33.9 0l-17 17c-9.4 9.4-9.4 24.6 0 33.9L285.1 256 183.5 357.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L369.9 273c9.4-9.4 9.4-24.6 0-34z"] }; +var faChevronCircleUp = { prefix: 'fas', iconName: 'chevron-circle-up', icon: [512, 512, [], "f139", "M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"] }; +var faChevronDown = { prefix: 'fas', iconName: 'chevron-down', icon: [448, 512, [], "f078", "M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"] }; +var faChevronLeft = { prefix: 'fas', iconName: 'chevron-left', icon: [320, 512, [], "f053", "M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"] }; +var faChevronRight = { prefix: 'fas', iconName: 'chevron-right', icon: [320, 512, [], "f054", "M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"] }; +var faChevronUp = { prefix: 'fas', iconName: 'chevron-up', icon: [448, 512, [], "f077", "M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"] }; +var faChild = { prefix: 'fas', iconName: 'child', icon: [384, 512, [], "f1ae", "M120 72c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.764-32.235 72-72 72s-72-32.236-72-72zm254.627 1.373c-12.496-12.497-32.758-12.497-45.254 0L242.745 160H141.254L54.627 73.373c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255L104 213.254V480c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V368h16v112c0 17.673 14.327 32 32 32h16c17.673 0 32-14.327 32-32V213.254l94.627-94.627c12.497-12.497 12.497-32.757 0-45.254z"] }; +var faCircle = { prefix: 'fas', iconName: 'circle', icon: [512, 512, [], "f111", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"] }; +var faCircleNotch = { prefix: 'fas', iconName: 'circle-notch', icon: [512, 512, [], "f1ce", "M288 39.056v16.659c0 10.804 7.281 20.159 17.686 23.066C383.204 100.434 440 171.518 440 256c0 101.689-82.295 184-184 184-101.689 0-184-82.295-184-184 0-84.47 56.786-155.564 134.312-177.219C216.719 75.874 224 66.517 224 55.712V39.064c0-15.709-14.834-27.153-30.046-23.234C86.603 43.482 7.394 141.206 8.003 257.332c.72 137.052 111.477 246.956 248.531 246.667C393.255 503.711 504 392.788 504 256c0-115.633-79.14-212.779-186.211-240.236C302.678 11.889 288 23.456 288 39.056z"] }; +var faClipboard = { prefix: 'fas', iconName: 'clipboard', icon: [384, 512, [], "f328", "M384 112v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h80c0-35.29 28.71-64 64-64s64 28.71 64 64h80c26.51 0 48 21.49 48 48zM192 40c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24m96 114v-20a6 6 0 0 0-6-6H102a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6h180a6 6 0 0 0 6-6z"] }; +var faClock = { prefix: 'fas', iconName: 'clock', icon: [512, 512, [], "f017", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm57.1 350.1L224.9 294c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v137.7l63.5 46.2c5.4 3.9 6.5 11.4 2.6 16.8l-28.2 38.8c-3.9 5.3-11.4 6.5-16.8 2.6z"] }; +var faClone = { prefix: 'fas', iconName: 'clone', icon: [512, 512, [], "f24d", "M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z"] }; +var faClosedCaptioning = { prefix: 'fas', iconName: 'closed-captioning', icon: [512, 512, [], "f20a", "M464 64H48C21.5 64 0 85.5 0 112v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM218.1 287.7c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.6 56.8-172.8 32.1-172.8-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7l-17.5 30.5c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2.1 48 51.1 70.5 92.3 32.6zm190.4 0c2.8-2.5 7.1-2.1 9.2.9l19.5 27.7c1.7 2.4 1.5 5.6-.5 7.7-53.5 56.9-172.7 32.1-172.7-67.9 0-97.3 121.7-119.5 172.5-70.1 2.1 2 2.5 3.2 1 5.7L420 222.2c-1.9 3.1-6.2 4-9.1 1.7-40.8-32-94.6-14.9-94.6 31.2 0 48 51 70.5 92.2 32.6z"] }; +var faCloud = { prefix: 'fas', iconName: 'cloud', icon: [640, 512, [], "f0c2", "M537.585 226.56C541.725 215.836 544 204.184 544 192c0-53.019-42.981-96-96-96-19.729 0-38.065 5.954-53.316 16.159C367.042 64.248 315.288 32 256 32c-88.366 0-160 71.634-160 160 0 2.728.07 5.439.204 8.133C40.171 219.845 0 273.227 0 336c0 79.529 64.471 144 144 144h368c70.692 0 128-57.308 128-128 0-61.93-43.983-113.586-102.415-125.44z"] }; +var faCloudDownloadAlt = { prefix: 'fas', iconName: 'cloud-download-alt', icon: [640, 512, [], "f381", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-246.627-64H328V176c0-8.837-7.164-16-16-16h-48c-8.836 0-16 7.163-16 16v112h-65.373c-14.254 0-21.393 17.234-11.314 27.314l105.373 105.373c6.248 6.248 16.379 6.248 22.627 0l105.373-105.373c10.08-10.08 2.941-27.314-11.313-27.314z"] }; +var faCloudUploadAlt = { prefix: 'fas', iconName: 'cloud-upload-alt', icon: [640, 512, [], "f382", "M640 352c0 70.692-57.308 128-128 128H144C64.471 480 0 415.529 0 336c0-62.773 40.171-116.155 96.204-135.867A163.68 163.68 0 0 1 96 192c0-88.366 71.634-160 160-160 59.288 0 111.042 32.248 138.684 80.159C409.935 101.954 428.271 96 448 96c53.019 0 96 42.981 96 96 0 12.184-2.275 23.836-6.415 34.56C596.017 238.414 640 290.07 640 352zm-235.314-91.314L299.314 155.314c-6.248-6.248-16.379-6.248-22.627 0L171.314 260.686c-10.08 10.08-2.941 27.314 11.313 27.314H248v112c0 8.837 7.164 16 16 16h48c8.836 0 16-7.163 16-16V288h65.373c14.254 0 21.393-17.234 11.313-27.314z"] }; +var faCode = { prefix: 'fas', iconName: 'code', icon: [640, 512, [], "f121", "M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z"] }; +var faCodeBranch = { prefix: 'fas', iconName: 'code-branch', icon: [384, 512, [], "f126", "M384 144c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 36.4 24.3 67.1 57.5 76.8-.6 16.1-4.2 28.5-11 36.9-15.4 19.2-49.3 22.4-85.2 25.7-28.2 2.6-57.4 5.4-81.3 16.9v-144c32.5-10.2 56-40.5 56-76.3 0-44.2-35.8-80-80-80S0 35.8 0 80c0 35.8 23.5 66.1 56 76.3v199.3C23.5 365.9 0 396.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-34-21.2-63.1-51.2-74.6 3.1-5.2 7.8-9.8 14.9-13.4 16.2-8.2 40.4-10.4 66.1-12.8 42.2-3.9 90-8.4 118.2-43.4 14-17.4 21.1-39.8 21.6-67.9 31.6-10.8 54.4-40.7 54.4-75.9zM80 64c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm0 384c-8.8 0-16-7.2-16-16s7.2-16 16-16 16 7.2 16 16-7.2 16-16 16zm224-320c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16z"] }; +var faCoffee = { prefix: 'fas', iconName: 'coffee', icon: [640, 512, [], "f0f4", "M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z"] }; +var faCog = { prefix: 'fas', iconName: 'cog', icon: [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"] }; +var faCogs = { prefix: 'fas', iconName: 'cogs', icon: [640, 512, [], "f085", "M512.1 191l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0L552 6.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zm-10.5-58.8c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.7-82.4 14.3-52.8 52.8zM386.3 286.1l33.7 16.8c10.1 5.8 14.5 18.1 10.5 29.1-8.9 24.2-26.4 46.4-42.6 65.8-7.4 8.9-20.2 11.1-30.3 5.3l-29.1-16.8c-16 13.7-34.6 24.6-54.9 31.7v33.6c0 11.6-8.3 21.6-19.7 23.6-24.6 4.2-50.4 4.4-75.9 0-11.5-2-20-11.9-20-23.6V418c-20.3-7.2-38.9-18-54.9-31.7L74 403c-10 5.8-22.9 3.6-30.3-5.3-16.2-19.4-33.3-41.6-42.2-65.7-4-10.9.4-23.2 10.5-29.1l33.3-16.8c-3.9-20.9-3.9-42.4 0-63.4L12 205.8c-10.1-5.8-14.6-18.1-10.5-29 8.9-24.2 26-46.4 42.2-65.8 7.4-8.9 20.2-11.1 30.3-5.3l29.1 16.8c16-13.7 34.6-24.6 54.9-31.7V57.1c0-11.5 8.2-21.5 19.6-23.5 24.6-4.2 50.5-4.4 76-.1 11.5 2 20 11.9 20 23.6v33.6c20.3 7.2 38.9 18 54.9 31.7l29.1-16.8c10-5.8 22.9-3.6 30.3 5.3 16.2 19.4 33.2 41.6 42.1 65.8 4 10.9.1 23.2-10 29.1l-33.7 16.8c3.9 21 3.9 42.5 0 63.5zm-117.6 21.1c59.2-77-28.7-164.9-105.7-105.7-59.2 77 28.7 164.9 105.7 105.7zm243.4 182.7l-8.2 14.3c-3 5.3-9.4 7.5-15.1 5.4-11.8-4.4-22.6-10.7-32.1-18.6-4.6-3.8-5.8-10.5-2.8-15.7l8.2-14.3c-6.9-8-12.3-17.3-15.9-27.4h-16.5c-6 0-11.2-4.3-12.2-10.3-2-12-2.1-24.6 0-37.1 1-6 6.2-10.4 12.2-10.4h16.5c3.6-10.1 9-19.4 15.9-27.4l-8.2-14.3c-3-5.2-1.9-11.9 2.8-15.7 9.5-7.9 20.4-14.2 32.1-18.6 5.7-2.1 12.1.1 15.1 5.4l8.2 14.3c10.5-1.9 21.2-1.9 31.7 0l8.2-14.3c3-5.3 9.4-7.5 15.1-5.4 11.8 4.4 22.6 10.7 32.1 18.6 4.6 3.8 5.8 10.5 2.8 15.7l-8.2 14.3c6.9 8 12.3 17.3 15.9 27.4h16.5c6 0 11.2 4.3 12.2 10.3 2 12 2.1 24.6 0 37.1-1 6-6.2 10.4-12.2 10.4h-16.5c-3.6 10.1-9 19.4-15.9 27.4l8.2 14.3c3 5.2 1.9 11.9-2.8 15.7-9.5 7.9-20.4 14.2-32.1 18.6-5.7 2.1-12.1-.1-15.1-5.4l-8.2-14.3c-10.4 1.9-21.2 1.9-31.7 0zM501.6 431c38.5 29.6 82.4-14.3 52.8-52.8-38.5-29.6-82.4 14.3-52.8 52.8z"] }; +var faColumns = { prefix: 'fas', iconName: 'columns', icon: [512, 512, [], "f0db", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64V160h160v256zm224 0H288V160h160v256z"] }; +var faComment = { prefix: 'fas', iconName: 'comment', icon: [576, 512, [], "f075", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208z"] }; +var faCommentAlt = { prefix: 'fas', iconName: 'comment-alt', icon: [576, 512, [], "f27a", "M576 240c0 115-129 208-288 208-48.3 0-93.9-8.6-133.9-23.8-40.3 31.2-89.8 50.3-142.4 55.7-5.2.6-10.2-2.8-11.5-7.7-1.3-5 2.7-8.1 6.6-11.8 19.3-18.4 42.7-32.8 51.9-94.6C21.9 330.9 0 287.3 0 240 0 125.1 129 32 288 32s288 93.1 288 208zm-416-48c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48zm128 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z"] }; +var faComments = { prefix: 'fas', iconName: 'comments', icon: [576, 512, [], "f086", "M224 358.857c-37.599 0-73.027-6.763-104.143-18.7-31.375 24.549-69.869 39.508-110.764 43.796a8.632 8.632 0 0 1-.89.047c-3.736 0-7.111-2.498-8.017-6.061-.98-3.961 2.088-6.399 5.126-9.305 15.017-14.439 33.222-25.79 40.342-74.297C17.015 266.886 0 232.622 0 195.429 0 105.16 100.297 32 224 32s224 73.159 224 163.429c-.001 90.332-100.297 163.428-224 163.428zm347.067 107.174c-13.944-13.127-30.849-23.446-37.46-67.543 68.808-64.568 52.171-156.935-37.674-207.065.031 1.334.066 2.667.066 4.006 0 122.493-129.583 216.394-284.252 211.222 38.121 30.961 93.989 50.492 156.252 50.492 34.914 0 67.811-6.148 96.704-17 29.134 22.317 64.878 35.916 102.853 39.814 3.786.395 7.363-1.973 8.27-5.467.911-3.601-1.938-5.817-4.759-8.459z"] }; +var faCompass = { prefix: 'fas', iconName: 'compass', icon: [512, 512, [], "f14e", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM307.446 120.844l-102.642 97.779a23.997 23.997 0 0 0-6.772 11.729l-33.359 137.779c-5.68 23.459 22.777 39.318 39.88 23.024l102.64-97.779a23.99 23.99 0 0 0 6.772-11.729l33.359-137.779c5.618-23.198-22.591-39.493-39.878-23.024zM256 224c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faCompress = { prefix: 'fas', iconName: 'compress', icon: [448, 512, [], "f066", "M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"] }; +var faCopy = { prefix: 'fas', iconName: 'copy', icon: [448, 512, [], "f0c5", "M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"] }; +var faCopyright = { prefix: 'fas', iconName: 'copyright', icon: [512, 512, [], "f1f9", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm117.134 346.753c-1.592 1.867-39.776 45.731-109.851 45.731-84.692 0-144.484-63.26-144.484-145.567 0-81.303 62.004-143.401 143.762-143.401 66.957 0 101.965 37.315 103.422 38.904a12 12 0 0 1 1.238 14.623l-22.38 34.655c-4.049 6.267-12.774 7.351-18.234 2.295-.233-.214-26.529-23.88-61.88-23.88-46.116 0-73.916 33.575-73.916 76.082 0 39.602 25.514 79.692 74.277 79.692 38.697 0 65.28-28.338 65.544-28.625 5.132-5.565 14.059-5.033 18.508 1.053l24.547 33.572a12.001 12.001 0 0 1-.553 14.866z"] }; +var faCreditCard = { prefix: 'fas', iconName: 'credit-card', icon: [576, 512, [], "f09d", "M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z"] }; +var faCrop = { prefix: 'fas', iconName: 'crop', icon: [512, 512, [], "f125", "M488 352h-40V109.3l57-57c9.4-9.4 9.4-24.6 0-33.9L493.7 7c-9.4-9.4-24.6-9.4-33.9 0l-57 57H160V24c0-13.3-10.7-24-24-24H88C74.7 0 64 10.7 64 24v40H24C10.7 64 0 74.7 0 88v48c0 13.3 10.7 24 24 24h40v264c0 13.3 10.7 24 24 24h264v40c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24v-40h40c13.3 0 24-10.7 24-24v-48c0-13.3-10.7-24-24-24zM306.7 160L160 306.7V160h146.7zM205.3 352L352 205.3V352H205.3z"] }; +var faCrosshairs = { prefix: 'fas', iconName: 'crosshairs', icon: [512, 512, [], "f05b", "M500 224h-30.364C455.724 130.325 381.675 56.276 288 42.364V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v30.364C130.325 56.276 56.276 130.325 42.364 224H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h30.364C56.276 381.675 130.325 455.724 224 469.636V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-30.364C381.675 455.724 455.724 381.675 469.636 288H500c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zM288 404.634V364c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40.634C165.826 392.232 119.783 346.243 107.366 288H148c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40.634C119.768 165.826 165.757 119.783 224 107.366V148c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40.634C346.174 119.768 392.217 165.757 404.634 224H364c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40.634C392.232 346.174 346.243 392.217 288 404.634zM288 256c0 17.673-14.327 32-32 32s-32-14.327-32-32c0-17.673 14.327-32 32-32s32 14.327 32 32z"] }; +var faCube = { prefix: 'fas', iconName: 'cube', icon: [512, 512, [], "f1b2", "M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z"] }; +var faCubes = { prefix: 'fas', iconName: 'cubes', icon: [512, 512, [], "f1b3", "M488.6 250.2L392 214V105.5c0-15-9.3-28.4-23.4-33.7l-100-37.5c-8.1-3.1-17.1-3.1-25.3 0l-100 37.5c-14.1 5.3-23.4 18.7-23.4 33.7V214l-96.6 36.2C9.3 255.5 0 268.9 0 283.9V394c0 13.6 7.7 26.1 19.9 32.2l100 50c10.1 5.1 22.1 5.1 32.2 0l103.9-52 103.9 52c10.1 5.1 22.1 5.1 32.2 0l100-50c12.2-6.1 19.9-18.6 19.9-32.2V283.9c0-15-9.3-28.4-23.4-33.7zM358 214.8l-85 31.9v-68.2l85-37v73.3zM154 104.1l102-38.2 102 38.2v.6l-102 41.4-102-41.4v-.6zm84 291.1l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6zm240 112l-85 42.5v-79.1l85-38.8v75.4zm0-112l-102 41.4-102-41.4v-.6l102-38.2 102 38.2v.6z"] }; +var faCut = { prefix: 'fas', iconName: 'cut', icon: [448, 512, [], "f0c4", "M444.485 422.426c4.689 4.689 4.684 12.287 0 16.971-32.804 32.804-85.991 32.804-118.795 0L210.176 323.883l-24.859 24.859C189.63 359.657 192 371.552 192 384c0 53.019-42.981 96-96 96S0 437.019 0 384s42.981-96 96-96c4.536 0 8.995.322 13.363.93l32.93-32.93-32.93-32.93c-4.368.608-8.827.93-13.363.93-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96c0 12.448-2.37 24.343-6.682 35.258l24.859 24.859L325.69 72.603c32.804-32.804 85.991-32.804 118.795 0 4.684 4.684 4.689 12.282 0 16.971L278.059 256l166.426 166.426zM96 96c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m0 256c-17.645 0-32 14.355-32 32s14.355 32 32 32 32-14.355 32-32-14.355-32-32-32m112-108c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12z"] }; +var faDatabase = { prefix: 'fas', iconName: 'database', icon: [448, 512, [], "f1c0", "M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z"] }; +var faDeaf = { prefix: 'fas', iconName: 'deaf', icon: [512, 512, [], "f2a4", "M216 260c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-44.112 35.888-80 80-80s80 35.888 80 80c0 15.464-12.536 28-28 28s-28-12.536-28-28c0-13.234-10.767-24-24-24s-24 10.766-24 24zm24-176c-97.047 0-176 78.953-176 176 0 15.464 12.536 28 28 28s28-12.536 28-28c0-66.168 53.832-120 120-120s120 53.832 120 120c0 75.164-71.009 70.311-71.997 143.622L288 404c0 28.673-23.327 52-52 52-15.464 0-28 12.536-28 28s12.536 28 28 28c59.475 0 107.876-48.328 108-107.774.595-34.428 72-48.24 72-144.226 0-97.047-78.953-176-176-176zm268.485-52.201L480.2 3.515c-4.687-4.686-12.284-4.686-16.971 0L376.2 90.544c-4.686 4.686-4.686 12.284 0 16.971l28.285 28.285c4.686 4.686 12.284 4.686 16.97 0l87.03-87.029c4.687-4.688 4.687-12.286 0-16.972zM168.97 314.745c-4.686-4.686-12.284-4.686-16.97 0L3.515 463.23c-4.686 4.686-4.686 12.284 0 16.971L31.8 508.485c4.687 4.686 12.284 4.686 16.971 0L197.256 360c4.686-4.686 4.686-12.284 0-16.971l-28.286-28.284z"] }; +var faDesktop = { prefix: 'fas', iconName: 'desktop', icon: [576, 512, [], "f108", "M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z"] }; +var faDollarSign = { prefix: 'fas', iconName: 'dollar-sign', icon: [320, 512, [], "f155", "M113.411 169.375c0-23.337 21.536-38.417 54.865-38.417 26.726 0 54.116 12.263 76.461 28.333 5.88 4.229 14.13 2.354 17.575-4.017l23.552-43.549c2.649-4.898 1.596-10.991-2.575-14.68-24.281-21.477-59.135-34.09-91.289-37.806V12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v49.832c-58.627 13.29-97.299 55.917-97.299 108.639 0 123.533 184.765 110.81 184.765 169.414 0 19.823-16.311 41.158-52.124 41.158-30.751 0-62.932-15.88-87.848-35.887-5.31-4.264-13.082-3.315-17.159 2.14l-30.389 40.667c-3.627 4.854-3.075 11.657 1.302 15.847 24.049 23.02 59.249 41.255 98.751 47.973V500c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-47.438c65.72-10.215 106.176-59.186 106.176-116.516.001-119.688-184.764-103.707-184.764-166.671z"] }; +var faDotCircle = { prefix: 'fas', iconName: 'dot-circle', icon: [512, 512, [], "f192", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm80 248c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80z"] }; +var faDownload = { prefix: 'fas', iconName: 'download', icon: [512, 512, [], "f019", "M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; +var faEdit = { prefix: 'fas', iconName: 'edit', icon: [576, 512, [], "f044", "M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"] }; +var faEject = { prefix: 'fas', iconName: 'eject', icon: [448, 512, [], "f052", "M448 384v64c0 17.673-14.327 32-32 32H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h384c17.673 0 32 14.327 32 32zM48.053 320h351.886c41.651 0 63.581-49.674 35.383-80.435L259.383 47.558c-19.014-20.743-51.751-20.744-70.767 0L12.67 239.565C-15.475 270.268 6.324 320 48.053 320z"] }; +var faEllipsisH = { prefix: 'fas', iconName: 'ellipsis-h', icon: [512, 512, [], "f141", "M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"] }; +var faEllipsisV = { prefix: 'fas', iconName: 'ellipsis-v', icon: [192, 512, [], "f142", "M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z"] }; +var faEnvelope = { prefix: 'fas', iconName: 'envelope', icon: [512, 512, [], "f0e0", "M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"] }; +var faEnvelopeOpen = { prefix: 'fas', iconName: 'envelope-open', icon: [512, 512, [], "f2b6", "M512 464c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V200.724a48 48 0 0 1 18.387-37.776c24.913-19.529 45.501-35.365 164.2-121.511C199.412 29.17 232.797-.347 256 .003c23.198-.354 56.596 29.172 73.413 41.433 118.687 86.137 139.303 101.995 164.2 121.512A48 48 0 0 1 512 200.724V464zm-65.666-196.605c-2.563-3.728-7.7-4.595-11.339-1.907-22.845 16.873-55.462 40.705-105.582 77.079-16.825 12.266-50.21 41.781-73.413 41.43-23.211.344-56.559-29.143-73.413-41.43-50.114-36.37-82.734-60.204-105.582-77.079-3.639-2.688-8.776-1.821-11.339 1.907l-9.072 13.196a7.998 7.998 0 0 0 1.839 10.967c22.887 16.899 55.454 40.69 105.303 76.868 20.274 14.781 56.524 47.813 92.264 47.573 35.724.242 71.961-32.771 92.263-47.573 49.85-36.179 82.418-59.97 105.303-76.868a7.998 7.998 0 0 0 1.839-10.967l-9.071-13.196z"] }; +var faEnvelopeSquare = { prefix: 'fas', iconName: 'envelope-square', icon: [448, 512, [], "f199", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM178.117 262.104C87.429 196.287 88.353 196.121 64 177.167V152c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v25.167c-24.371 18.969-23.434 19.124-114.117 84.938-10.5 7.655-31.392 26.12-45.883 25.894-14.503.218-35.367-18.227-45.883-25.895zM384 217.775V360c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V217.775c13.958 10.794 33.329 25.236 95.303 70.214 14.162 10.341 37.975 32.145 64.694 32.01 26.887.134 51.037-22.041 64.72-32.025 61.958-44.965 81.325-59.406 95.283-70.199z"] }; +var faEraser = { prefix: 'fas', iconName: 'eraser', icon: [512, 512, [], "f12d", "M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z"] }; +var faEuroSign = { prefix: 'fas', iconName: 'euro-sign', icon: [320, 512, [], "f153", "M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z"] }; +var faExchangeAlt = { prefix: 'fas', iconName: 'exchange-alt', icon: [512, 512, [], "f362", "M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"] }; +var faExclamation = { prefix: 'fas', iconName: 'exclamation', icon: [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"] }; +var faExclamationCircle = { prefix: 'fas', iconName: 'exclamation-circle', icon: [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; +var faExclamationTriangle = { prefix: 'fas', iconName: 'exclamation-triangle', icon: [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"] }; +var faExpand = { prefix: 'fas', iconName: 'expand', icon: [448, 512, [], "f065", "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"] }; +var faExpandArrowsAlt = { prefix: 'fas', iconName: 'expand-arrows-alt', icon: [448, 512, [], "f31e", "M448.1 344v112c0 13.3-10.7 24-24 24h-112c-21.4 0-32.1-25.9-17-41l36.2-36.2L224 295.6 116.8 402.9 153 439c15.1 15.1 4.4 41-17 41H24c-13.3 0-24-10.7-24-24V344c0-21.4 25.9-32.1 41-17l36.2 36.2L184.5 256 77.2 148.7 41 185c-15.1 15.1-41 4.4-41-17V56c0-13.3 10.7-24 24-24h112c21.4 0 32.1 25.9 17 41l-36.2 36.2L224 216.4l107.3-107.3L295.1 73c-15.1-15.1-4.4-41 17-41h112c13.3 0 24 10.7 24 24v112c0 21.4-25.9 32.1-41 17l-36.2-36.2L263.6 256l107.3 107.3 36.2-36.2c15.1-15.2 41-4.5 41 16.9z"] }; +var faExternalLinkAlt = { prefix: 'fas', iconName: 'external-link-alt', icon: [576, 512, [], "f35d", "M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z"] }; +var faExternalLinkSquareAlt = { prefix: 'fas', iconName: 'external-link-square-alt', icon: [448, 512, [], "f360", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-88 16H248.029c-21.313 0-32.08 25.861-16.971 40.971l31.984 31.987L67.515 364.485c-4.686 4.686-4.686 12.284 0 16.971l31.029 31.029c4.687 4.686 12.285 4.686 16.971 0l195.526-195.526 31.988 31.991C358.058 263.977 384 253.425 384 231.979V120c0-13.255-10.745-24-24-24z"] }; +var faEye = { prefix: 'fas', iconName: 'eye', icon: [576, 512, [], "f06e", "M569.354 231.631C512.969 135.949 407.81 72 288 72 168.14 72 63.004 135.994 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.031 376.051 168.19 440 288 440c119.86 0 224.996-63.994 281.354-159.631a47.997 47.997 0 0 0 0-48.738zM288 392c-75.162 0-136-60.827-136-136 0-75.162 60.826-136 136-136 75.162 0 136 60.826 136 136 0 75.162-60.826 136-136 136zm104-136c0 57.438-46.562 104-104 104s-104-46.562-104-104c0-17.708 4.431-34.379 12.236-48.973l-.001.032c0 23.651 19.173 42.823 42.824 42.823s42.824-19.173 42.824-42.823c0-23.651-19.173-42.824-42.824-42.824l-.032.001C253.621 156.431 270.292 152 288 152c57.438 0 104 46.562 104 104z"] }; +var faEyeDropper = { prefix: 'fas', iconName: 'eye-dropper', icon: [512, 512, [], "f1fb", "M177.38 206.64L39.03 344.97A24.01 24.01 0 0 0 32 361.94V424L0 480l32 32 56-32h62.06c6.36 0 12.47-2.53 16.97-7.03l138.35-138.33-128-128zm225.552 30.47l16.952 16.95c9.37 9.37 9.37 24.57 0 33.94l-40.973 40.97c-9.292 9.312-24.506 9.434-33.94 0L183.028 167.03c-9.37-9.37-9.37-24.57 0-33.94L224 92.12c9.289-9.309 24.502-9.438 33.94 0l16.992 16.99 82.606-82.601c35.19-35.19 92.5-35.5 128 0 40.49 48.08 29.66 98.34 0 128l-82.606 82.601z"] }; +var faEyeSlash = { prefix: 'fas', iconName: 'eye-slash', icon: [576, 512, [], "f070", "M286.693 391.984l32.579 46.542A333.958 333.958 0 0 1 288 440C168.19 440 63.031 376.051 6.646 280.369a47.999 47.999 0 0 1 0-48.739c24.023-40.766 56.913-75.775 96.024-102.537l57.077 81.539C154.736 224.82 152 240.087 152 256c0 74.736 60.135 135.282 134.693 135.984zm282.661-111.615c-31.667 53.737-78.747 97.46-135.175 125.475l.011.015 41.47 59.2c7.6 10.86 4.96 25.82-5.9 33.42l-13.11 9.18c-10.86 7.6-25.82 4.96-33.42-5.9L100.34 46.94c-7.6-10.86-4.96-25.82 5.9-33.42l13.11-9.18c10.86-7.6 25.82-4.96 33.42 5.9l51.038 72.617C230.68 75.776 258.905 72 288 72c119.81 0 224.969 63.949 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM424 256c0-75.174-60.838-136-136-136-17.939 0-35.056 3.473-50.729 9.772l19.299 27.058c25.869-8.171 55.044-6.163 80.4 7.41h-.03c-23.65 0-42.82 19.17-42.82 42.82 0 23.626 19.147 42.82 42.82 42.82 23.65 0 42.82-19.17 42.82-42.82v-.03c18.462 34.49 16.312 77.914-8.25 110.95v.01l19.314 27.061C411.496 321.2 424 290.074 424 256zM262.014 356.727l-77.53-110.757c-5.014 52.387 29.314 98.354 77.53 110.757z"] }; +var faFastBackward = { prefix: 'fas', iconName: 'fast-backward', icon: [512, 512, [], "f049", "M0 436V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v151.9L235.5 71.4C256.1 54.3 288 68.6 288 96v131.9L459.5 71.4C480.1 54.3 512 68.6 512 96v320c0 27.4-31.9 41.7-52.5 24.6L288 285.3V416c0 27.4-31.9 41.7-52.5 24.6L64 285.3V436c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12z"] }; +var faFastForward = { prefix: 'fas', iconName: 'fast-forward', icon: [512, 512, [], "f050", "M512 76v360c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V284.1L276.5 440.6c-20.6 17.2-52.5 2.8-52.5-24.6V284.1L52.5 440.6C31.9 457.8 0 443.4 0 416V96c0-27.4 31.9-41.7 52.5-24.6L224 226.8V96c0-27.4 31.9-41.7 52.5-24.6L448 226.8V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12z"] }; +var faFax = { prefix: 'fas', iconName: 'fax', icon: [512, 512, [], "f1ac", "M128 144v320c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V144c0-26.51 21.49-48 48-48h32c26.51 0 48 21.49 48 48zm384 64v256c0 26.51-21.49 48-48 48H192c-26.51 0-48-21.49-48-48V40c0-22.091 17.909-40 40-40h207.432a39.996 39.996 0 0 1 28.284 11.716l48.569 48.569A39.999 39.999 0 0 1 480 88.568v74.174c18.641 6.591 32 24.36 32 45.258zm-320-16h240V96h-24c-13.203 0-24-10.797-24-24V48H192v144zm96 204c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm128 128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zm0-128c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40z"] }; +var faFemale = { prefix: 'fas', iconName: 'female', icon: [256, 512, [], "f182", "M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z"] }; +var faFighterJet = { prefix: 'fas', iconName: 'fighter-jet', icon: [640, 512, [], "f0fb", "M544 224l-128-16-48-16h-24L227.158 44h39.509C278.333 44 288 41.375 288 38s-9.667-6-21.333-6H152v12h16v164h-48l-66.667-80H18.667L8 138.667V208h8v16h48v2.666l-64 8v42.667l64 8V288H16v16H8v69.333L18.667 384h34.667L120 304h48v164h-16v12h114.667c11.667 0 21.333-2.625 21.333-6s-9.667-6-21.333-6h-39.509L344 320h24l48-16 128-16c96-21.333 96-26.583 96-32 0-5.417 0-10.667-96-32z"] }; +var faFile = { prefix: 'fas', iconName: 'file', icon: [384, 512, [], "f15b", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileAlt = { prefix: 'fas', iconName: 'file-alt', icon: [384, 512, [], "f15c", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileArchive = { prefix: 'fas', iconName: 'file-archive', icon: [384, 512, [], "f1c6", "M224 136V0h-63.6v32h-32V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zM95.9 32h32v32h-32V32zm32.3 384c-33.2 0-58-30.4-51.4-62.9L96.4 256v-32h32v-32h-32v-32h32v-32h-32V96h32V64h32v32h-32v32h32v32h-32v32h32v32h-32v32h22.1c5.7 0 10.7 4.1 11.8 9.7l17.3 87.7c6.4 32.4-18.4 62.6-51.4 62.6zm32.7-53c0 14.9-14.5 27-32.4 27S96 378 96 363c0-14.9 14.5-27 32.4-27s32.5 12.1 32.5 27zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileAudio = { prefix: 'fas', iconName: 'file-audio', icon: [384, 512, [], "f1c7", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm-64 268c0 10.7-12.9 16-20.5 8.5L104 376H76c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h28l35.5-36.5c7.6-7.6 20.5-2.2 20.5 8.5v136zm33.2-47.6c9.1-9.3 9.1-24.1 0-33.4-22.1-22.8 12.2-56.2 34.4-33.5 27.2 27.9 27.2 72.4 0 100.4-21.8 22.3-56.9-10.4-34.4-33.5zm86-117.1c54.4 55.9 54.4 144.8 0 200.8-21.8 22.4-57-10.3-34.4-33.5 36.2-37.2 36.3-96.5 0-133.8-22.1-22.8 12.3-56.3 34.4-33.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileCode = { prefix: 'fas', iconName: 'file-code', icon: [384, 512, [], "f1c9", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zM123.206 400.505a5.4 5.4 0 0 1-7.633.246l-64.866-60.812a5.4 5.4 0 0 1 0-7.879l64.866-60.812a5.4 5.4 0 0 1 7.633.246l19.579 20.885a5.4 5.4 0 0 1-.372 7.747L101.65 336l40.763 35.874a5.4 5.4 0 0 1 .372 7.747l-19.579 20.884zm51.295 50.479l-27.453-7.97a5.402 5.402 0 0 1-3.681-6.692l61.44-211.626a5.402 5.402 0 0 1 6.692-3.681l27.452 7.97a5.4 5.4 0 0 1 3.68 6.692l-61.44 211.626a5.397 5.397 0 0 1-6.69 3.681zm160.792-111.045l-64.866 60.812a5.4 5.4 0 0 1-7.633-.246l-19.58-20.885a5.4 5.4 0 0 1 .372-7.747L284.35 336l-40.763-35.874a5.4 5.4 0 0 1-.372-7.747l19.58-20.885a5.4 5.4 0 0 1 7.633-.246l64.866 60.812a5.4 5.4 0 0 1-.001 7.879z"] }; +var faFileExcel = { prefix: 'fas', iconName: 'file-excel', icon: [384, 512, [], "f1c3", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm60.1 106.5L224 336l60.1 93.5c5.1 8-.6 18.5-10.1 18.5h-34.9c-4.4 0-8.5-2.4-10.6-6.3C208.9 405.5 192 373 192 373c-6.4 14.8-10 20-36.6 68.8-2.1 3.9-6.1 6.3-10.5 6.3H110c-9.5 0-15.2-10.5-10.1-18.5l60.3-93.5-60.3-93.5c-5.2-8 .6-18.5 10.1-18.5h34.8c4.4 0 8.5 2.4 10.6 6.3 26.1 48.8 20 33.6 36.6 68.5 0 0 6.1-11.7 36.6-68.5 2.1-3.9 6.2-6.3 10.6-6.3H274c9.5-.1 15.2 10.4 10.1 18.4zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFileImage = { prefix: 'fas', iconName: 'file-image', icon: [384, 512, [], "f1c5", "M384 121.941V128H256V0h6.059a24 24 0 0 1 16.97 7.029l97.941 97.941a24.002 24.002 0 0 1 7.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"] }; +var faFilePdf = { prefix: 'fas', iconName: 'file-pdf', icon: [384, 512, [], "f1c1", "M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z"] }; +var faFilePowerpoint = { prefix: 'fas', iconName: 'file-powerpoint', icon: [384, 512, [], "f1c4", "M193.7 271.2c8.8 0 15.5 2.7 20.3 8.1 9.6 10.9 9.8 32.7-.2 44.1-4.9 5.6-11.9 8.5-21.1 8.5h-26.9v-60.7h27.9zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-153 31V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm53 165.2c0 90.3-88.8 77.6-111.1 77.6V436c0 6.6-5.4 12-12 12h-30.8c-6.6 0-12-5.4-12-12V236.2c0-6.6 5.4-12 12-12h81c44.5 0 72.9 32.8 72.9 77z"] }; +var faFileVideo = { prefix: 'fas', iconName: 'file-video', icon: [384, 512, [], "f1c8", "M384 121.941V128H256V0h6.059c6.365 0 12.47 2.529 16.971 7.029l97.941 97.941A24.005 24.005 0 0 1 384 121.941zM224 136V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248c-13.2 0-24-10.8-24-24zm96 144.016v111.963c0 21.445-25.943 31.998-40.971 16.971L224 353.941V392c0 13.255-10.745 24-24 24H88c-13.255 0-24-10.745-24-24V280c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v38.059l55.029-55.013c15.011-15.01 40.971-4.491 40.971 16.97z"] }; +var faFileWord = { prefix: 'fas', iconName: 'file-word', icon: [384, 512, [], "f1c2", "M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm57.1 120H305c7.7 0 13.4 7.1 11.7 14.7l-38 168c-1.2 5.5-6.1 9.3-11.7 9.3h-38c-5.5 0-10.3-3.8-11.6-9.1-25.8-103.5-20.8-81.2-25.6-110.5h-.5c-1.1 14.3-2.4 17.4-25.6 110.5-1.3 5.3-6.1 9.1-11.6 9.1H117c-5.6 0-10.5-3.9-11.7-9.4l-37.8-168c-1.7-7.5 4-14.6 11.7-14.6h24.5c5.7 0 10.7 4 11.8 9.7 15.6 78 20.1 109.5 21 122.2 1.6-10.2 7.3-32.7 29.4-122.7 1.3-5.4 6.1-9.1 11.7-9.1h29.1c5.6 0 10.4 3.8 11.7 9.2 24 100.4 28.8 124 29.6 129.4-.2-11.2-2.6-17.8 21.6-129.2 1-5.6 5.9-9.5 11.5-9.5zM384 121.9v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z"] }; +var faFilm = { prefix: 'fas', iconName: 'film', icon: [512, 512, [], "f008", "M488 64h-8v20c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12V64H96v20c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12V64h-8C10.7 64 0 74.7 0 88v336c0 13.3 10.7 24 24 24h8v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h320v-20c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v20h8c13.3 0 24-10.7 24-24V88c0-13.3-10.7-24-24-24zM96 372c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12H44c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm272 208c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm0-168c0 6.6-5.4 12-12 12H156c-6.6 0-12-5.4-12-12v-96c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v96zm112 152c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40zm0-96c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40z"] }; +var faFilter = { prefix: 'fas', iconName: 'filter', icon: [512, 512, [], "f0b0", "M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z"] }; +var faFire = { prefix: 'fas', iconName: 'fire', icon: [384, 512, [], "f06d", "M216 23.858c0-23.802-30.653-32.765-44.149-13.038C48 191.851 224 200 224 288c0 35.629-29.114 64.458-64.85 63.994C123.98 351.538 96 322.22 96 287.046v-85.51c0-21.703-26.471-32.225-41.432-16.504C27.801 213.158 0 261.332 0 320c0 105.869 86.131 192 192 192s192-86.131 192-192c0-170.29-168-193.003-168-296.142z"] }; +var faFireExtinguisher = { prefix: 'fas', iconName: 'fire-extinguisher', icon: [448, 512, [], "f134", "M434.027 26.329l-168 28C254.693 56.218 256 67.8 256 72h-58.332C208.353 36.108 181.446 0 144 0c-39.435 0-66.368 39.676-52.228 76.203-52.039 13.051-75.381 54.213-90.049 90.884-4.923 12.307 1.063 26.274 13.37 31.197 12.317 4.926 26.279-1.075 31.196-13.37C75.058 112.99 106.964 120 168 120v27.076c-41.543 10.862-72 49.235-72 94.129V488c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V240c0-44.731-30.596-82.312-72-92.97V120h40c0 2.974-1.703 15.716 10.027 17.671l168 28C441.342 166.89 448 161.25 448 153.834V38.166c0-7.416-6.658-13.056-13.973-11.837zM144 72c-8.822 0-16-7.178-16-16s7.178-16 16-16 16 7.178 16 16-7.178 16-16 16z"] }; +var faFlag = { prefix: 'fas', iconName: 'flag', icon: [512, 512, [], "f024", "M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z"] }; +var faFlagCheckered = { prefix: 'fas', iconName: 'flag-checkered', icon: [512, 512, [], "f11e", "M466.515 66.928C487.731 57.074 512 72.551 512 95.944v243.1c0 10.526-5.161 20.407-13.843 26.358-35.837 24.564-74.335 40.858-122.505 40.858-67.373 0-111.63-34.783-165.217-34.783-50.853 0-86.124 10.058-114.435 22.122V488c0 13.255-10.745 24-24 24H56c-13.255 0-24-10.745-24-24V101.945C17.497 91.825 8 75.026 8 56 8 24.296 34.345-1.254 66.338.048c28.468 1.158 51.779 23.968 53.551 52.404.52 8.342-.81 16.31-3.586 23.562C137.039 68.384 159.393 64 184.348 64c67.373 0 111.63 34.783 165.217 34.783 40.496 0 82.612-15.906 116.95-31.855zM96 134.63v70.49c29-10.67 51.18-17.83 73.6-20.91v-71.57c-23.5 2.17-40.44 9.79-73.6 21.99zm220.8 9.19c-26.417-4.672-49.886-13.979-73.6-21.34v67.42c24.175 6.706 47.566 16.444 73.6 22.31v-68.39zm-147.2 40.39v70.04c32.796-2.978 53.91-.635 73.6 3.8V189.9c-25.247-7.035-46.581-9.423-73.6-5.69zm73.6 142.23c26.338 4.652 49.732 13.927 73.6 21.34v-67.41c-24.277-6.746-47.54-16.45-73.6-22.32v68.39zM96 342.1c23.62-8.39 47.79-13.84 73.6-16.56v-71.29c-26.11 2.35-47.36 8.04-73.6 17.36v70.49zm368-221.6c-21.3 8.85-46.59 17.64-73.6 22.47v71.91c27.31-4.36 50.03-14.1 73.6-23.89V120.5zm0 209.96v-70.49c-22.19 14.2-48.78 22.61-73.6 26.02v71.58c25.07-2.38 48.49-11.04 73.6-27.11zM316.8 212.21v68.16c25.664 7.134 46.616 9.342 73.6 5.62v-71.11c-25.999 4.187-49.943 2.676-73.6-2.67z"] }; +var faFlask = { prefix: 'fas', iconName: 'flask', icon: [448, 512, [], "f0c3", "M437.2 403.5L320 215V64h8c13.3 0 24-10.7 24-24V24c0-13.3-10.7-24-24-24H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h8v151L10.8 403.5C-18.5 450.6 15.3 512 70.9 512h306.2c55.7 0 89.4-61.5 60.1-108.5zM137.9 320l48.2-77.6c3.7-5.2 5.8-11.6 5.8-18.4V64h64v160c0 6.9 2.2 13.2 5.8 18.4l48.2 77.6h-172z"] }; +var faFolder = { prefix: 'fas', iconName: 'folder', icon: [512, 512, [], "f07b", "M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z"] }; +var faFolderOpen = { prefix: 'fas', iconName: 'folder-open', icon: [576, 512, [], "f07c", "M572.694 292.093L500.27 416.248A63.997 63.997 0 0 1 444.989 448H45.025c-18.523 0-30.064-20.093-20.731-36.093l72.424-124.155A64 64 0 0 1 152 256h399.964c18.523 0 30.064 20.093 20.73 36.093zM152 224h328v-48c0-26.51-21.49-48-48-48H272l-64-64H48C21.49 64 0 85.49 0 112v278.046l69.077-118.418C86.214 242.25 117.989 224 152 224z"] }; +var faFont = { prefix: 'fas', iconName: 'font', icon: [448, 512, [], "f031", "M152 416h-24.013l26.586-80.782H292.8L319.386 416H296c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-26.739L275.495 42.746A16 16 0 0 0 260.382 32h-72.766a16 16 0 0 0-15.113 10.746L42.739 416H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h136c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm64.353-271.778c4.348-15.216 6.61-28.156 7.586-34.644.839 6.521 2.939 19.476 7.727 34.706l41.335 124.006h-98.619l41.971-124.068z"] }; +var faForward = { prefix: 'fas', iconName: 'forward', icon: [512, 512, [], "f04e", "M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z"] }; +var faFrown = { prefix: 'fas', iconName: 'frown', icon: [512, 512, [], "f119", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm192.551 212.66c-59.128-91.455-165.846-91.594-225.064 0-11.502 17.79 15.383 35.148 26.873 17.374 46.626-72.118 124.862-71.855 171.318 0 11.328 17.524 38.548.684 26.873-17.374z"] }; +var faFutbol = { prefix: 'fas', iconName: 'futbol', icon: [512, 512, [], "f1e3", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-48 0l-.003-.282-26.064 22.741-62.679-58.5 16.454-84.355 34.303 3.072c-24.889-34.216-60.004-60.089-100.709-73.141l13.651 31.939L256 139l-74.953-41.525 13.651-31.939c-40.631 13.028-75.78 38.87-100.709 73.141l34.565-3.073 16.192 84.355-62.678 58.5-26.064-22.741-.003.282c0 43.015 13.497 83.952 38.472 117.991l7.704-33.897 85.138 10.447 36.301 77.826-29.902 17.786c40.202 13.122 84.29 13.148 124.572 0l-29.902-17.786 36.301-77.826 85.138-10.447 7.704 33.897C442.503 339.952 456 299.015 456 256zm-248.102 69.571l-29.894-91.312L256 177.732l77.996 56.527-29.622 91.312h-96.476z"] }; +var faGamepad = { prefix: 'fas', iconName: 'gamepad', icon: [640, 512, [], "f11b", "M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; +var faGavel = { prefix: 'fas', iconName: 'gavel', icon: [512, 512, [], "f0e3", "M504.971 199.362l-22.627-22.627c-9.373-9.373-24.569-9.373-33.941 0l-5.657 5.657L329.608 69.255l5.657-5.657c9.373-9.373 9.373-24.569 0-33.941L312.638 7.029c-9.373-9.373-24.569-9.373-33.941 0L154.246 131.48c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l5.657-5.657 39.598 39.598-81.04 81.04-5.657-5.657c-12.497-12.497-32.758-12.497-45.255 0L9.373 412.118c-12.497 12.497-12.497 32.758 0 45.255l45.255 45.255c12.497 12.497 32.758 12.497 45.255 0l114.745-114.745c12.497-12.497 12.497-32.758 0-45.255l-5.657-5.657 81.04-81.04 39.598 39.598-5.657 5.657c-9.373 9.373-9.373 24.569 0 33.941l22.627 22.627c9.373 9.373 24.569 9.373 33.941 0l124.451-124.451c9.372-9.372 9.372-24.568 0-33.941z"] }; +var faGem = { prefix: 'fas', iconName: 'gem', icon: [576, 512, [], "f3a5", "M485.5 0L576 160H474.9L405.7 0h79.8zm-128 0l69.2 160H149.3L218.5 0h139zm-267 0h79.8l-69.2 160H0L90.5 0zM0 192h100.7l123 251.7c1.5 3.1-2.7 5.9-5 3.3L0 192zm148.2 0h279.6l-137 318.2c-1 2.4-4.5 2.4-5.5 0L148.2 192zm204.1 251.7l123-251.7H576L357.3 446.9c-2.3 2.7-6.5-.1-5-3.2z"] }; +var faGenderless = { prefix: 'fas', iconName: 'genderless', icon: [288, 512, [], "f22d", "M144 176c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80m0-64C64.5 112 0 176.5 0 256s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144z"] }; +var faGift = { prefix: 'fas', iconName: 'gift', icon: [512, 512, [], "f06b", "M488 192h-64.512C438.72 175.003 448 152.566 448 128c0-52.935-43.065-96-96-96-41.997 0-68.742 20.693-95.992 54.15C226.671 50.192 199.613 32 160 32c-52.935 0-96 43.065-96 96 0 24.566 9.28 47.003 24.512 64H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h8v112c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V320h8c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zm-208-32c24-56 55.324-64 72-64 17.645 0 32 14.355 32 32s-14.355 32-32 32h-72zM160 96c16.676 0 48 8 72 64h-72c-17.645 0-32-14.355-32-32s14.355-32 32-32zm48 128h96v184c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V224z"] }; +var faGlassMartini = { prefix: 'fas', iconName: 'glass-martini', icon: [512, 512, [], "f000", "M507.3 27.3c10-10 2.9-27.3-11.3-27.3H16C1.8 0-5.4 17.2 4.7 27.3L216 238.6V472h-92c-15.5 0-28 12.5-28 28 0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12 0-15.5-12.5-28-28-28h-92V238.6L507.3 27.3z"] }; +var faGlobe = { prefix: 'fas', iconName: 'globe', icon: [512, 512, [], "f0ac", "M364.215 192h131.43c5.439 20.419 8.354 41.868 8.354 64s-2.915 43.581-8.354 64h-131.43c5.154-43.049 4.939-86.746 0-128zM185.214 352c10.678 53.68 33.173 112.514 70.125 151.992.221.001.44.008.661.008s.44-.008.661-.008c37.012-39.543 59.467-98.414 70.125-151.992H185.214zm174.13-192h125.385C452.802 84.024 384.128 27.305 300.95 12.075c30.238 43.12 48.821 96.332 58.394 147.925zm-27.35 32H180.006c-5.339 41.914-5.345 86.037 0 128h151.989c5.339-41.915 5.345-86.037-.001-128zM152.656 352H27.271c31.926 75.976 100.6 132.695 183.778 147.925-30.246-43.136-48.823-96.35-58.393-147.925zm206.688 0c-9.575 51.605-28.163 104.814-58.394 147.925 83.178-15.23 151.852-71.949 183.778-147.925H359.344zm-32.558-192c-10.678-53.68-33.174-112.514-70.125-151.992-.221 0-.44-.008-.661-.008s-.44.008-.661.008C218.327 47.551 195.872 106.422 185.214 160h141.572zM16.355 192C10.915 212.419 8 233.868 8 256s2.915 43.581 8.355 64h131.43c-4.939-41.254-5.154-84.951 0-128H16.355zm136.301-32c9.575-51.602 28.161-104.81 58.394-147.925C127.872 27.305 59.198 84.024 27.271 160h125.385z"] }; +var faGraduationCap = { prefix: 'fas', iconName: 'graduation-cap', icon: [640, 512, [], "f19d", "M622.884 199.005l-275.817 85.1a96 96 0 0 1-54.134 0L92.398 222.232c-8.564 11.438-11.018 23.05-11.918 38.335C89.778 266.165 96 276.355 96 288c0 11.952-6.557 22.366-16.265 27.861l16.197 123.096c.63 4.786-3.1 9.043-7.932 9.043H40c-4.828 0-8.562-4.253-7.932-9.044L48.265 315.86C38.557 310.366 32 299.952 32 288c0-12.034 6.646-22.511 16.465-27.976.947-17.951 3.974-33.231 12.152-47.597l-43.502-13.422c-22.876-6.801-22.766-39.241 0-46.01l275.817-85.1a96 96 0 0 1 54.134 0l275.817 85.1c22.877 6.801 22.767 39.241.001 46.01zM356.503 314.682l-.207.064-.207.061a127.998 127.998 0 0 1-72.177 0l-.207-.061-.207-.064-150.914-46.57L120 352c0 35.346 89.543 64 200 64s200-28.654 200-64l-12.583-83.888-150.914 46.57z"] }; +var faHSquare = { prefix: 'fas', iconName: 'h-square', icon: [448, 512, [], "f0fd", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zm-112 48h-32c-8.837 0-16 7.163-16 16v80H160v-80c0-8.837-7.163-16-16-16h-32c-8.837 0-16 7.163-16 16v224c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16v-80h128v80c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144c0-8.837-7.163-16-16-16z"] }; +var faHandLizard = { prefix: 'fas', iconName: 'hand-lizard', icon: [576, 512, [], "f258", "M384 480h192V363.778a95.998 95.998 0 0 0-14.833-51.263L398.127 54.368A48 48 0 0 0 357.544 32H24C10.745 32 0 42.745 0 56v16c0 30.928 25.072 56 56 56h229.981c12.844 0 21.556 13.067 16.615 24.923l-21.41 51.385A32 32 0 0 1 251.648 224H128c-35.346 0-64 28.654-64 64v8c0 13.255 10.745 24 24 24h147.406a47.995 47.995 0 0 1 25.692 7.455l111.748 70.811A24.001 24.001 0 0 1 384 418.539V480z"] }; +var faHandPaper = { prefix: 'fas', iconName: 'hand-paper', icon: [448, 512, [], "f256", "M408.781 128.007C386.356 127.578 368 146.36 368 168.79V256h-8V79.79c0-22.43-18.356-41.212-40.781-40.783C297.488 39.423 280 57.169 280 79v177h-8V40.79C272 18.36 253.644-.422 231.219.007 209.488.423 192 18.169 192 40v216h-8V80.79c0-22.43-18.356-41.212-40.781-40.783C121.488 40.423 104 58.169 104 80v235.992l-31.648-43.519c-12.993-17.866-38.009-21.817-55.877-8.823-17.865 12.994-21.815 38.01-8.822 55.877l125.601 172.705A48 48 0 0 0 172.073 512h197.59c22.274 0 41.622-15.324 46.724-37.006l26.508-112.66a192.011 192.011 0 0 0 5.104-43.975V168c.001-21.831-17.487-39.577-39.218-39.993z"] }; +var faHandPeace = { prefix: 'fas', iconName: 'hand-peace', icon: [448, 512, [], "f25b", "M408 216c-22.092 0-40 17.909-40 40h-8v-32c0-22.091-17.908-40-40-40s-40 17.909-40 40v32h-8V48c0-26.51-21.49-48-48-48s-48 21.49-48 48v208h-13.572L92.688 78.449C82.994 53.774 55.134 41.63 30.461 51.324 5.787 61.017-6.356 88.877 3.337 113.551l74.765 190.342-31.09 24.872c-15.381 12.306-19.515 33.978-9.741 51.081l64 112A39.998 39.998 0 0 0 136 512h240c18.562 0 34.686-12.77 38.937-30.838l32-136A39.97 39.97 0 0 0 448 336v-80c0-22.091-17.908-40-40-40z"] }; +var faHandPointDown = { prefix: 'fas', iconName: 'hand-point-down', icon: [384, 512, [], "f0a7", "M91.826 467.2V317.966c-8.248 5.841-16.558 10.57-24.918 14.153C35.098 345.752-.014 322.222 0 288c.008-18.616 10.897-32.203 29.092-40 28.286-12.122 64.329-78.648 77.323-107.534 7.956-17.857 25.479-28.453 43.845-28.464l.001-.002h171.526c11.812 0 21.897 8.596 23.703 20.269 7.25 46.837 38.483 61.76 38.315 123.731-.007 2.724.195 13.254.195 16 0 50.654-22.122 81.574-71.263 72.6-9.297 18.597-39.486 30.738-62.315 16.45-21.177 24.645-53.896 22.639-70.944 6.299V467.2c0 24.15-20.201 44.8-43.826 44.8-23.283 0-43.826-21.35-43.826-44.8zM112 72V24c0-13.255 10.745-24 24-24h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24zm212-24c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; +var faHandPointLeft = { prefix: 'fas', iconName: 'hand-point-left', icon: [512, 512, [], "f0a5", "M44.8 155.826h149.234c-5.841-8.248-10.57-16.558-14.153-24.918C166.248 99.098 189.778 63.986 224 64c18.616.008 32.203 10.897 40 29.092 12.122 28.286 78.648 64.329 107.534 77.323 17.857 7.956 28.453 25.479 28.464 43.845l.002.001v171.526c0 11.812-8.596 21.897-20.269 23.703-46.837 7.25-61.76 38.483-123.731 38.315-2.724-.007-13.254.195-16 .195-50.654 0-81.574-22.122-72.6-71.263-18.597-9.297-30.738-39.486-16.45-62.315-24.645-21.177-22.639-53.896-6.299-70.944H44.8c-24.15 0-44.8-20.201-44.8-43.826 0-23.283 21.35-43.826 44.8-43.826zM440 176h48c13.255 0 24 10.745 24 24v192c0 13.255-10.745 24-24 24h-48c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24zm24 212c11.046 0 20-8.954 20-20s-8.954-20-20-20-20 8.954-20 20 8.954 20 20 20z"] }; +var faHandPointRight = { prefix: 'fas', iconName: 'hand-point-right', icon: [512, 512, [], "f0a4", "M512 199.652c0 23.625-20.65 43.826-44.8 43.826h-99.851c16.34 17.048 18.346 49.766-6.299 70.944 14.288 22.829 2.147 53.017-16.45 62.315C353.574 425.878 322.654 448 272 448c-2.746 0-13.276-.203-16-.195-61.971.168-76.894-31.065-123.731-38.315C120.596 407.683 112 397.599 112 385.786V214.261l.002-.001c.011-18.366 10.607-35.889 28.464-43.845 28.886-12.994 95.413-49.038 107.534-77.323 7.797-18.194 21.384-29.084 40-29.092 34.222-.014 57.752 35.098 44.119 66.908-3.583 8.359-8.312 16.67-14.153 24.918H467.2c23.45 0 44.8 20.543 44.8 43.826zM96 200v192c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V200c0-13.255 10.745-24 24-24h48c13.255 0 24 10.745 24 24zM68 368c0-11.046-8.954-20-20-20s-20 8.954-20 20 8.954 20 20 20 20-8.954 20-20z"] }; +var faHandPointUp = { prefix: 'fas', iconName: 'hand-point-up', icon: [384, 512, [], "f0a6", "M135.652 0c23.625 0 43.826 20.65 43.826 44.8v99.851c17.048-16.34 49.766-18.346 70.944 6.299 22.829-14.288 53.017-2.147 62.315 16.45C361.878 158.426 384 189.346 384 240c0 2.746-.203 13.276-.195 16 .168 61.971-31.065 76.894-38.315 123.731C343.683 391.404 333.599 400 321.786 400H150.261l-.001-.002c-18.366-.011-35.889-10.607-43.845-28.464C93.421 342.648 57.377 276.122 29.092 264 10.897 256.203.008 242.616 0 224c-.014-34.222 35.098-57.752 66.908-44.119 8.359 3.583 16.67 8.312 24.918 14.153V44.8c0-23.45 20.543-44.8 43.826-44.8zM136 416h192c13.255 0 24 10.745 24 24v48c0 13.255-10.745 24-24 24H136c-13.255 0-24-10.745-24-24v-48c0-13.255 10.745-24 24-24zm168 28c-11.046 0-20 8.954-20 20s8.954 20 20 20 20-8.954 20-20-8.954-20-20-20z"] }; +var faHandPointer = { prefix: 'fas', iconName: 'hand-pointer', icon: [448, 512, [], "f25a", "M448 240v96c0 3.084-.356 6.159-1.063 9.162l-32 136C410.686 499.23 394.562 512 376 512H168a40.004 40.004 0 0 1-32.35-16.473l-127.997-176c-12.993-17.866-9.043-42.883 8.822-55.876 17.867-12.994 42.884-9.043 55.877 8.823L104 315.992V40c0-22.091 17.908-40 40-40s40 17.909 40 40v200h8v-40c0-22.091 17.908-40 40-40s40 17.909 40 40v40h8v-24c0-22.091 17.908-40 40-40s40 17.909 40 40v24h8c0-22.091 17.908-40 40-40s40 17.909 40 40zm-256 80h-8v96h8v-96zm88 0h-8v96h8v-96zm88 0h-8v96h8v-96z"] }; +var faHandRock = { prefix: 'fas', iconName: 'hand-rock', icon: [512, 512, [], "f255", "M512 128.79c0-26.322-20.861-48.344-47.18-48.783C437.935 79.558 416 101.217 416 128h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C333.935 47.558 312 69.217 312 96v32h-8V80.79c0-26.322-20.861-48.344-47.18-48.783C229.935 31.558 208 53.217 208 80v48h-8V96.79c0-26.322-20.861-48.344-47.18-48.783C125.935 47.558 104 69.217 104 96v136l-8-7.111V176.79c0-26.322-20.861-48.344-47.18-48.783C21.935 127.558 0 149.217 0 176v66.445a95.998 95.998 0 0 0 32.221 71.751l111.668 99.261A47.999 47.999 0 0 1 160 449.333V456c0 13.255 10.745 24 24 24h240c13.255 0 24-10.745 24-24v-2.921a96.01 96.01 0 0 1 7.523-37.254l48.954-116.265A96.002 96.002 0 0 0 512 262.306V128.79z"] }; +var faHandScissors = { prefix: 'fas', iconName: 'hand-scissors', icon: [512, 512, [], "f257", "M216 440c0-22.092 17.909-40 40-40v-8h-32c-22.091 0-40-17.908-40-40s17.909-40 40-40h32v-8H48c-26.51 0-48-21.49-48-48s21.49-48 48-48h208v-13.572l-177.551-69.74c-24.674-9.694-36.818-37.555-27.125-62.228 9.693-24.674 37.554-36.817 62.228-27.124l190.342 74.765 24.872-31.09c12.306-15.381 33.978-19.515 51.081-9.741l112 64A40.002 40.002 0 0 1 512 168v240c0 18.562-12.77 34.686-30.838 38.937l-136 32A39.982 39.982 0 0 1 336 480h-80c-22.091 0-40-17.908-40-40z"] }; +var faHandSpock = { prefix: 'fas', iconName: 'hand-spock', icon: [512, 512, [], "f259", "M10.872 316.585c15.139-16.086 40.454-16.854 56.543-1.713L128 371.893v-79.405L88.995 120.865c-4.896-21.542 8.598-42.974 30.14-47.87 21.549-4.894 42.975 8.599 47.87 30.141L201.747 256h9.833L164.016 48.966c-4.946-21.531 8.498-42.994 30.028-47.94 21.532-4.95 42.994 8.498 47.94 30.028L293.664 256h15.105l48.425-193.702c5.357-21.432 27.075-34.462 48.507-29.104 21.432 5.358 34.463 27.075 29.104 48.507L391.231 256h11.08l30.768-129.265c5.117-21.491 26.685-34.768 48.177-29.647 21.491 5.117 34.765 26.686 29.647 48.177l-36.292 152.467A96.024 96.024 0 0 0 472 319.967v42.102a96.002 96.002 0 0 1-3.96 27.287l-26.174 88.287C435.825 498.022 417.101 512 395.846 512H179.172a48.002 48.002 0 0 1-32.898-13.046L12.585 373.128c-16.087-15.141-16.853-40.456-1.713-56.543z"] }; +var faHandshake = { prefix: 'fas', iconName: 'handshake', icon: [640, 512, [], "f2b5", "M72 112H24c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zM48 340c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zm568-228h-48c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24V136c0-13.255-10.745-24-24-24zm-24 228c-11.046 0-20-8.954-20-20s8.954-20 20-20 20 8.954 20 20-8.954 20-20 20zM485.94 92.67L528 140.74V320h-19.17c.56-14.96-4.38-28.98-14-39.71l-80.92-98.91c2.93-3.2 2.76-8.16-.38-11.16-2.82-2.7-7.08-2.92-10.14-.76-.42.3-60.35 62.93-60.35 62.93l-.2.21c-23.904 26.905-66.127 26.204-89.15-1.42-15.48-18.58-15.29-45.39.45-63.76l66.57-77.67C334.304 73.88 354.534 64 376.7 64h46.05a83.98 83.98 0 0 1 63.19 28.67zm-3.37 197.92c15.46 16.78 12.59 43.83-2.37 57.75-17.711 16.462-42.433 13.004-45.93 9.2 1.653 15.658-21.389 47.249-56.42 44.68-6.325 21.185-32.298 38.909-59.18 29.61-10.22 10.21-25.82 14.97-39.81 14.97-28.69 0-54.92-11.99-72.58-30.8L112 320V135.52l61.36-50.57A71.52 71.52 0 0 1 223.93 64h37.42c16.73 0 32.68 6.84 44.21 18.85l-63.57 74.16c-20.84 24.31-21.09 59.81-.59 84.42 29.375 35.247 83.007 35.853 113.31 1.92L402.82 193l79.75 97.59z"] }; +var faHashtag = { prefix: 'fas', iconName: 'hashtag', icon: [448, 512, [], "f292", "M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z"] }; +var faHdd = { prefix: 'fas', iconName: 'hdd', icon: [576, 512, [], "f0a0", "M576 304v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48zm-48-80a79.557 79.557 0 0 1 30.777 6.165L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L17.223 230.165A79.557 79.557 0 0 1 48 224h480zm-48 96c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm-96 0c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32z"] }; +var faHeading = { prefix: 'fas', iconName: 'heading', icon: [512, 512, [], "f1dc", "M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z"] }; +var faHeadphones = { prefix: 'fas', iconName: 'headphones', icon: [512, 512, [], "f025", "M256 32C114.52 32 0 146.496 0 288v48a32 32 0 0 0 17.689 28.622l14.383 7.191C34.083 431.903 83.421 480 144 480h24c13.255 0 24-10.745 24-24V280c0-13.255-10.745-24-24-24h-24c-31.342 0-59.671 12.879-80 33.627V288c0-105.869 86.131-192 192-192s192 86.131 192 192v1.627C427.671 268.879 399.342 256 368 256h-24c-13.255 0-24 10.745-24 24v176c0 13.255 10.745 24 24 24h24c60.579 0 109.917-48.098 111.928-108.187l14.382-7.191A32 32 0 0 0 512 336v-48c0-141.479-114.496-256-256-256z"] }; +var faHeart = { prefix: 'fas', iconName: 'heart', icon: [576, 512, [], "f004", "M414.9 24C361.8 24 312 65.7 288 89.3 264 65.7 214.2 24 161.1 24 70.3 24 16 76.9 16 165.5c0 72.6 66.8 133.3 69.2 135.4l187 180.8c8.8 8.5 22.8 8.5 31.6 0l186.7-180.2c2.7-2.7 69.5-63.5 69.5-136C560 76.9 505.7 24 414.9 24z"] }; +var faHeartbeat = { prefix: 'fas', iconName: 'heartbeat', icon: [576, 512, [], "f21e", "M47.9 257C31.6 232.7 16 200.5 16 165.5 16 76.9 70.3 24 161.1 24 214.2 24 264 65.7 288 89.3 312 65.7 361.8 24 414.9 24 505.7 24 560 76.9 560 165.5c0 35-15.5 67.2-31.9 91.5H408l-26.4-58.6c-4.7-8.9-17.6-8.5-21.6.7l-53.3 134.6L235.4 120c-3.7-10.6-18.7-10.7-22.6-.2l-48 137.2H47.9zm348 32c-4.5 0-8.6-2.5-10.6-6.4l-12.8-32.5-56.9 142.8c-4.4 9.9-18.7 9.4-22.3-.9l-69.7-209.2-33.6 98.4c-1.7 4.7-6.2 7.8-11.2 7.8H73.4c5.3 5.7-12.8-12 198.9 192.6 8.8 8.5 22.8 8.5 31.6 0 204.3-197.2 191-184 199-192.6h-107z"] }; +var faHistory = { prefix: 'fas', iconName: 'history', icon: [512, 512, [], "f1da", "M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"] }; +var faHome = { prefix: 'fas', iconName: 'home', icon: [576, 512, [], "f015", "M488 312.7V456c0 13.3-10.7 24-24 24H348c-6.6 0-12-5.4-12-12V356c0-6.6-5.4-12-12-12h-72c-6.6 0-12 5.4-12 12v112c0 6.6-5.4 12-12 12H112c-13.3 0-24-10.7-24-24V312.7c0-3.6 1.6-7 4.4-9.3l188-154.8c4.4-3.6 10.8-3.6 15.3 0l188 154.8c2.7 2.3 4.3 5.7 4.3 9.3zm83.6-60.9L488 182.9V44.4c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12V117l-89.5-73.7c-17.7-14.6-43.3-14.6-61 0L4.4 251.8c-5.1 4.2-5.8 11.8-1.6 16.9l25.5 31c4.2 5.1 11.8 5.8 16.9 1.6l235.2-193.7c4.4-3.6 10.8-3.6 15.3 0l235.2 193.7c5.1 4.2 12.7 3.5 16.9-1.6l25.5-31c4.2-5.2 3.4-12.7-1.7-16.9z"] }; +var faHospital = { prefix: 'fas', iconName: 'hospital', icon: [448, 512, [], "f0f8", "M448 492v20H0v-20c0-6.627 5.373-12 12-12h20V120c0-13.255 10.745-24 24-24h88V24c0-13.255 10.745-24 24-24h112c13.255 0 24 10.745 24 24v72h88c13.255 0 24 10.745 24 24v360h20c6.627 0 12 5.373 12 12zM308 192h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-168 64h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12zm104 128h-40c-6.627 0-12 5.373-12 12v84h64v-84c0-6.627-5.373-12-12-12zm64-96h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12zm-116 12c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40zM182 96h26v26a6 6 0 0 0 6 6h20a6 6 0 0 0 6-6V96h26a6 6 0 0 0 6-6V70a6 6 0 0 0-6-6h-26V38a6 6 0 0 0-6-6h-20a6 6 0 0 0-6 6v26h-26a6 6 0 0 0-6 6v20a6 6 0 0 0 6 6z"] }; +var faHourglass = { prefix: 'fas', iconName: 'hourglass', icon: [384, 512, [], "f254", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64z"] }; +var faHourglassEnd = { prefix: 'fas', iconName: 'hourglass-end', icon: [384, 512, [], "f253", "M360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64zM192 208c-57.787 0-104-66.518-104-144h208c0 77.945-46.51 144-104 144z"] }; +var faHourglassHalf = { prefix: 'fas', iconName: 'hourglass-half', icon: [384, 512, [], "f252", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-75.078 384H99.08c17.059-46.797 52.096-80 92.92-80 40.821 0 75.862 33.196 92.922 80zm.019-256H99.078C91.988 108.548 88 86.748 88 64h208c0 22.805-3.987 44.587-11.059 64z"] }; +var faHourglassStart = { prefix: 'fas', iconName: 'hourglass-start', icon: [384, 512, [], "f251", "M360 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24 0 90.965 51.016 167.734 120.842 192C75.016 280.266 24 357.035 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24 0-90.965-51.016-167.734-120.842-192C308.984 231.734 360 154.965 360 64c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24zm-64 448H88c0-77.458 46.204-144 104-144 57.786 0 104 66.517 104 144z"] }; +var faICursor = { prefix: 'fas', iconName: 'i-cursor', icon: [256, 512, [], "f246", "M256 52.048V12.065C256 5.496 250.726.148 244.158.066 211.621-.344 166.469.011 128 37.959 90.266.736 46.979-.114 11.913.114 5.318.157 0 5.519 0 12.114v39.645c0 6.687 5.458 12.078 12.145 11.998C38.111 63.447 96 67.243 96 112.182V224H60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h36v112c0 44.932-56.075 48.031-83.95 47.959C5.404 447.942 0 453.306 0 459.952v39.983c0 6.569 5.274 11.917 11.842 11.999 32.537.409 77.689.054 116.158-37.894 37.734 37.223 81.021 38.073 116.087 37.845 6.595-.043 11.913-5.405 11.913-12V460.24c0-6.687-5.458-12.078-12.145-11.998C217.889 448.553 160 444.939 160 400V288h36c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-36V112.182c0-44.932 56.075-48.213 83.95-48.142 6.646.018 12.05-5.346 12.05-11.992z"] }; +var faIdBadge = { prefix: 'fas', iconName: 'id-badge', icon: [384, 512, [], "f2c1", "M0 464V48C0 21.49 21.49 0 48 0h288c26.51 0 48 21.49 48 48v416c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm192-144c53.019 0 96-42.981 96-96s-42.981-96-96-96-96 42.981-96 96 42.981 96 96 96zm94.317 17.474l-22.954-7.173C242.437 344.413 217.802 352 192 352s-50.437-7.587-71.363-21.699l-22.954 7.173C77.644 343.736 64 362.295 64 383.289V424c0 13.255 10.745 24 24 24h208c13.255 0 24-10.745 24-24v-40.711c0-20.994-13.644-39.553-33.683-45.815zM352 52v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12z"] }; +var faIdCard = { prefix: 'fas', iconName: 'id-card', icon: [512, 512, [], "f2c2", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM160 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64m79.589 154.53l-28.281-9.427C196.458 314.532 178.856 320 160 320s-36.458-5.468-51.309-14.897L80.41 314.53A24 24 0 0 0 64 337.298V360c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24v-22.702a24 24 0 0 0-16.411-22.768zM448 340v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm0-64v-8c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h136c6.627 0 12-5.373 12-12zm32-96v-8c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h424c6.627 0 12-5.373 12-12z"] }; +var faImage = { prefix: 'fas', iconName: 'image', icon: [512, 512, [], "f03e", "M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"] }; +var faImages = { prefix: 'fas', iconName: 'images', icon: [576, 512, [], "f302", "M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z"] }; +var faInbox = { prefix: 'fas', iconName: 'inbox', icon: [576, 512, [], "f01c", "M567.938 243.908L462.25 85.374A48.003 48.003 0 0 0 422.311 64H153.689a48 48 0 0 0-39.938 21.374L8.062 243.908A47.994 47.994 0 0 0 0 270.533V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V270.533a47.994 47.994 0 0 0-8.062-26.625zM162.252 128h251.497l85.333 128H376l-32 64H232l-32-64H76.918l85.334-128z"] }; +var faIndent = { prefix: 'fas', iconName: 'indent', icon: [448, 512, [], "f03c", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm176 144h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm160-128h256c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H176c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm-52.687-111.313l-96-95.984C17.266 138.652 0 145.776 0 160.016v191.975c0 14.329 17.325 21.304 27.313 11.313l96-95.992c6.249-6.247 6.249-16.377 0-22.625z"] }; +var faIndustry = { prefix: 'fas', iconName: 'industry', icon: [512, 512, [], "f275", "M475.115 163.781L336 252.309v-68.28c0-18.916-20.931-30.399-36.885-20.248L160 252.309V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56v400c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24V184.029c0-18.917-20.931-30.399-36.885-20.248z"] }; +var faInfo = { prefix: 'fas', iconName: 'info', icon: [192, 512, [], "f129", "M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"] }; +var faInfoCircle = { prefix: 'fas', iconName: 'info-circle', icon: [512, 512, [], "f05a", "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"] }; +var faItalic = { prefix: 'fas', iconName: 'italic', icon: [320, 512, [], "f033", "M204.758 416h-33.849l62.092-320h40.725a16 16 0 0 0 15.704-12.937l6.242-32C297.599 41.184 290.034 32 279.968 32H120.235a16 16 0 0 0-15.704 12.937l-6.242 32C96.362 86.816 103.927 96 113.993 96h33.846l-62.09 320H46.278a16 16 0 0 0-15.704 12.935l-6.245 32C22.402 470.815 29.967 480 40.034 480h158.479a16 16 0 0 0 15.704-12.935l6.245-32c1.927-9.88-5.638-19.065-15.704-19.065z"] }; +var faKey = { prefix: 'fas', iconName: 'key', icon: [512, 512, [], "f084", "M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"] }; +var faKeyboard = { prefix: 'fas', iconName: 'keyboard', icon: [576, 512, [], "f11c", "M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faLanguage = { prefix: 'fas', iconName: 'language', icon: [640, 512, [], "f1ab", "M304 416H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h280v320zm-120.676-72.622A12 12 0 0 0 194.839 352h22.863c8.22 0 14.007-8.078 11.362-15.861L171.61 167.085a12 12 0 0 0-11.362-8.139h-32.489a12.001 12.001 0 0 0-11.362 8.139L58.942 336.139C56.297 343.922 62.084 352 70.304 352h22.805a12 12 0 0 0 11.535-8.693l9.118-31.807h60.211l9.351 31.878zm-39.051-140.42s4.32 21.061 7.83 33.21l10.8 37.531h-38.07l11.07-37.531c3.51-12.15 7.83-33.21 7.83-33.21h.54zM616 416H336V96h280c13.255 0 24 10.745 24 24v272c0 13.255-10.745 24-24 24zm-36-228h-64v-16c0-6.627-5.373-12-12-12h-16c-6.627 0-12 5.373-12 12v16h-64c-6.627 0-12 5.373-12 12v16c0 6.627 5.373 12 12 12h114.106c-6.263 14.299-16.518 28.972-30.023 43.206-6.56-6.898-12.397-13.91-17.365-20.933-3.639-5.144-10.585-6.675-15.995-3.446l-7.28 4.346-6.498 3.879c-5.956 3.556-7.693 11.421-3.735 17.117 6.065 8.729 13.098 17.336 20.984 25.726-8.122 6.226-16.841 12.244-26.103 17.964-5.521 3.41-7.381 10.556-4.162 16.19l7.941 13.896c3.362 5.883 10.935 7.826 16.706 4.276 12.732-7.831 24.571-16.175 35.443-24.891 10.917 8.761 22.766 17.102 35.396 24.881 5.774 3.556 13.353 1.618 16.717-4.27l7.944-13.903c3.213-5.623 1.37-12.76-4.135-16.171a312.737 312.737 0 0 1-26.06-18.019c21.024-22.425 35.768-46.289 42.713-69.85H580c6.627 0 12-5.373 12-12v-16c0-6.625-5.373-11.998-12-11.998z"] }; +var faLaptop = { prefix: 'fas', iconName: 'laptop', icon: [640, 512, [], "f109", "M512 64v256H128V64h384m16-64H112C85.5 0 64 21.5 64 48v288c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm100 416H389.5c-3 0-5.5 2.1-5.9 5.1C381.2 436.3 368 448 352 448h-64c-16 0-29.2-11.7-31.6-26.9-.5-2.9-3-5.1-5.9-5.1H12c-6.6 0-12 5.4-12 12v36c0 26.5 21.5 48 48 48h544c26.5 0 48-21.5 48-48v-36c0-6.6-5.4-12-12-12z"] }; +var faLeaf = { prefix: 'fas', iconName: 'leaf', icon: [576, 512, [], "f06c", "M395.4 420.8c-43.4 21.6-91.9 34.4-140.8 34.4-82.2 0-151.1-40.1-151.1-40.1-16.1 0-35.4 64.9-63.3 64.9-27 0-40.2-24-40.2-38.5 0-33.1 63.6-58.9 63.6-77.3 0 0-12.5-21.2-12.5-59.2 0-101.2 81.3-173.4 172.6-203.3 65.9-21.6 206 3.5 250.7-38.5C492.1 47 500.8 32 527.8 32c36.3 0 48.2 93.2 48.2 120.3 0 110.9-54.5 206.5-180.6 268.5zm-254.3-75.6c63.5-89.9 144.5-128.8 257.7-120 8.8.7 16.5-5.9 17.2-14.7.7-8.8-5.9-16.5-14.7-17.2-124-9.6-215.9 33.9-286.3 133.5-5.1 7.2-3.4 17.2 3.8 22.3 7.2 5.1 17.2 3.4 22.3-3.9z"] }; +var faLemon = { prefix: 'fas', iconName: 'lemon', icon: [512, 512, [], "f094", "M489.038 22.963C465.944-.13 434.648-5.93 413.947 6.129c-58.906 34.312-181.25-53.077-321.073 86.746S40.441 355.041 6.129 413.945c-12.059 20.702-6.26 51.999 16.833 75.093 23.095 23.095 54.392 28.891 75.095 16.832 58.901-34.31 181.246 53.079 321.068-86.743S471.56 156.96 505.871 98.056c12.059-20.702 6.261-51.999-16.833-75.093zM243.881 95.522c-58.189 14.547-133.808 90.155-148.358 148.358-1.817 7.27-8.342 12.124-15.511 12.124-1.284 0-2.59-.156-3.893-.481-8.572-2.144-13.784-10.83-11.642-19.403C81.901 166.427 166.316 81.93 236.119 64.478c8.575-2.143 17.261 3.069 19.403 11.642s-3.069 17.259-11.641 19.402z"] }; +var faLevelDownAlt = { prefix: 'fas', iconName: 'level-down-alt', icon: [320, 512, [], "f3be", "M313.553 392.331L209.587 504.334c-9.485 10.214-25.676 10.229-35.174 0L70.438 392.331C56.232 377.031 67.062 352 88.025 352H152V80H68.024a11.996 11.996 0 0 1-8.485-3.515l-56-56C-4.021 12.926 1.333 0 12.024 0H208c13.255 0 24 10.745 24 24v328h63.966c20.878 0 31.851 24.969 17.587 40.331z"] }; +var faLevelUpAlt = { prefix: 'fas', iconName: 'level-up-alt', icon: [320, 512, [], "f3bf", "M313.553 119.669L209.587 7.666c-9.485-10.214-25.676-10.229-35.174 0L70.438 119.669C56.232 134.969 67.062 160 88.025 160H152v272H68.024a11.996 11.996 0 0 0-8.485 3.515l-56 56C-4.021 499.074 1.333 512 12.024 512H208c13.255 0 24-10.745 24-24V160h63.966c20.878 0 31.851-24.969 17.587-40.331z"] }; +var faLifeRing = { prefix: 'fas', iconName: 'life-ring', icon: [512, 512, [], "f1cd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm173.696 119.559l-63.399 63.399c-10.987-18.559-26.67-34.252-45.255-45.255l63.399-63.399a218.396 218.396 0 0 1 45.255 45.255zM256 352c-53.019 0-96-42.981-96-96s42.981-96 96-96 96 42.981 96 96-42.981 96-96 96zM127.559 82.304l63.399 63.399c-18.559 10.987-34.252 26.67-45.255 45.255l-63.399-63.399a218.372 218.372 0 0 1 45.255-45.255zM82.304 384.441l63.399-63.399c10.987 18.559 26.67 34.252 45.255 45.255l-63.399 63.399a218.396 218.396 0 0 1-45.255-45.255zm302.137 45.255l-63.399-63.399c18.559-10.987 34.252-26.67 45.255-45.255l63.399 63.399a218.403 218.403 0 0 1-45.255 45.255z"] }; +var faLightbulb = { prefix: 'fas', iconName: 'lightbulb', icon: [384, 512, [], "f0eb", "M272 428v28c0 10.449-6.68 19.334-16 22.629V488c0 13.255-10.745 24-24 24h-80c-13.255 0-24-10.745-24-24v-9.371c-9.32-3.295-16-12.18-16-22.629v-28c0-6.627 5.373-12 12-12h136c6.627 0 12 5.373 12 12zm-143.107-44c-9.907 0-18.826-6.078-22.376-15.327C67.697 267.541 16 277.731 16 176 16 78.803 94.805 0 192 0s176 78.803 176 176c0 101.731-51.697 91.541-90.516 192.673-3.55 9.249-12.47 15.327-22.376 15.327H128.893zM112 176c0-44.112 35.888-80 80-80 8.837 0 16-7.164 16-16s-7.163-16-16-16c-61.757 0-112 50.243-112 112 0 8.836 7.164 16 16 16s16-7.164 16-16z"] }; +var faLink = { prefix: 'fas', iconName: 'link', icon: [512, 512, [], "f0c1", "M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"] }; +var faLiraSign = { prefix: 'fas', iconName: 'lira-sign', icon: [384, 512, [], "f195", "M371.994 256h-48.019C317.64 256 312 260.912 312 267.246 312 368 230.179 416 144 416V256.781l134.603-29.912A12 12 0 0 0 288 215.155v-40.976c0-7.677-7.109-13.38-14.603-11.714L144 191.219V160.78l134.603-29.912A12 12 0 0 0 288 119.154V78.179c0-7.677-7.109-13.38-14.603-11.714L144 95.219V44c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v68.997L9.397 125.131A12 12 0 0 0 0 136.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 178.558v30.439L9.397 221.131A12 12 0 0 0 0 232.845v40.976c0 7.677 7.109 13.38 14.603 11.714L64 274.558V468c0 6.627 5.373 12 12 12h79.583c134.091 0 223.255-77.834 228.408-211.592.261-6.782-5.211-12.408-11.997-12.408z"] }; +var faList = { prefix: 'fas', iconName: 'list', icon: [512, 512, [], "f03a", "M128 116V76c0-8.837 7.163-16 16-16h352c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H144c-8.837 0-16-7.163-16-16zm16 176h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 144h64c8.837 0 16-7.163 16-16V64c0-8.837-7.163-16-16-16H16C7.163 48 0 55.163 0 64v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16zm0 160h64c8.837 0 16-7.163 16-16v-64c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v64c0 8.837 7.163 16 16 16z"] }; +var faListAlt = { prefix: 'fas', iconName: 'list-alt', icon: [512, 512, [], "f022", "M464 480H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v352c0 26.51-21.49 48-48 48zM128 120c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm0 96c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm288-136v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12zm0 96v-32c0-6.627-5.373-12-12-12H204c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h200c6.627 0 12-5.373 12-12z"] }; +var faListOl = { prefix: 'fas', iconName: 'list-ol', icon: [512, 512, [], "f0cb", "M3.263 139.527c0-7.477 3.917-11.572 11.573-11.572h15.131V88.078c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.938C32.815 33.602 36.732 32 42.785 32H54.89c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572H14.836c-7.656 0-11.573-4.095-11.573-11.572v-8.902zM2.211 304.591c0-47.278 50.955-56.383 50.955-69.165 0-7.18-5.954-8.755-9.28-8.755-3.153 0-6.479 1.051-9.455 3.852-5.079 4.903-10.507 7.004-16.111 2.451l-8.579-6.829c-5.779-4.553-7.18-9.805-2.803-15.409C13.592 201.981 26.025 192 47.387 192c19.437 0 44.476 10.506 44.476 39.573 0 38.347-46.753 46.402-48.679 56.909h39.049c7.529 0 11.557 4.027 11.557 11.382v8.755c0 7.354-4.028 11.382-11.557 11.382h-67.94c-7.005 0-12.083-4.028-12.083-11.382v-4.028zM5.654 454.61l5.603-9.28c3.853-6.654 9.105-7.004 15.584-3.152 4.903 2.101 9.63 3.152 14.359 3.152 10.155 0 14.358-3.502 14.358-8.23 0-6.654-5.604-9.106-15.934-9.106h-4.728c-5.954 0-9.28-2.101-12.258-7.88l-1.05-1.926c-2.451-4.728-1.226-9.806 2.801-14.884l5.604-7.004c6.829-8.405 12.257-13.483 12.257-13.483v-.35s-4.203 1.051-12.608 1.051H16.685c-7.53 0-11.383-4.028-11.383-11.382v-8.755c0-7.53 3.853-11.382 11.383-11.382h58.484c7.529 0 11.382 4.027 11.382 11.382v3.327c0 5.778-1.401 9.806-5.079 14.183l-17.509 20.137c19.611 5.078 28.716 20.487 28.716 34.845 0 21.363-14.358 44.126-48.503 44.126-16.636 0-28.192-4.728-35.896-9.455-5.779-4.202-6.304-9.805-2.626-15.934zM144 132h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faListUl = { prefix: 'fas', iconName: 'list-ul', icon: [512, 512, [], "f0ca", "M96 96c0 26.51-21.49 48-48 48S0 122.51 0 96s21.49-48 48-48 48 21.49 48 48zM48 208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm0 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm96-236h352c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h352c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H144c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] }; +var faLocationArrow = { prefix: 'fas', iconName: 'location-arrow', icon: [512, 512, [], "f124", "M443.683 4.529L27.818 196.418C-18.702 217.889-3.39 288 47.933 288H224v175.993c0 51.727 70.161 66.526 91.582 20.115L507.38 68.225c18.905-40.961-23.752-82.133-63.697-63.696z"] }; +var faLock = { prefix: 'fas', iconName: 'lock', icon: [448, 512, [], "f023", "M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"] }; +var faLockOpen = { prefix: 'fas', iconName: 'lock-open', icon: [576, 512, [], "f3c1", "M423.5 0C339.5.3 272 69.5 272 153.5V224H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48h-48v-71.1c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v80c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-80C576 68 507.5-.3 423.5 0z"] }; +var faLongArrowAltDown = { prefix: 'fas', iconName: 'long-arrow-alt-down', icon: [256, 512, [], "f309", "M168 345.941V44c0-6.627-5.373-12-12-12h-56c-6.627 0-12 5.373-12 12v301.941H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.569 9.373 33.941 0l86.059-86.059c15.119-15.119 4.411-40.971-16.971-40.971H168z"] }; +var faLongArrowAltLeft = { prefix: 'fas', iconName: 'long-arrow-alt-left', icon: [448, 512, [], "f30a", "M134.059 296H436c6.627 0 12-5.373 12-12v-56c0-6.627-5.373-12-12-12H134.059v-46.059c0-21.382-25.851-32.09-40.971-16.971L7.029 239.029c-9.373 9.373-9.373 24.569 0 33.941l86.059 86.059c15.119 15.119 40.971 4.411 40.971-16.971V296z"] }; +var faLongArrowAltRight = { prefix: 'fas', iconName: 'long-arrow-alt-right', icon: [448, 512, [], "f30b", "M313.941 216H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h301.941v46.059c0 21.382 25.851 32.09 40.971 16.971l86.059-86.059c9.373-9.373 9.373-24.569 0-33.941l-86.059-86.059c-15.119-15.119-40.971-4.411-40.971 16.971V216z"] }; +var faLongArrowAltUp = { prefix: 'fas', iconName: 'long-arrow-alt-up', icon: [256, 512, [], "f30c", "M88 166.059V468c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12V166.059h46.059c21.382 0 32.09-25.851 16.971-40.971l-86.059-86.059c-9.373-9.373-24.569-9.373-33.941 0l-86.059 86.059c-15.119 15.119-4.411 40.971 16.971 40.971H88z"] }; +var faLowVision = { prefix: 'fas', iconName: 'low-vision', icon: [576, 512, [], "f2a8", "M569.344 231.631C512.96 135.949 407.81 72 288 72c-28.468 0-56.102 3.619-82.451 10.409L152.778 10.24c-7.601-10.858-22.564-13.5-33.423-5.9l-13.114 9.178c-10.86 7.601-13.502 22.566-5.9 33.426l43.131 58.395C89.449 131.73 40.228 174.683 6.682 231.581c-.01.017-.023.033-.034.05-8.765 14.875-8.964 33.528 0 48.739 38.5 65.332 99.742 115.862 172.859 141.349L55.316 244.302A272.194 272.194 0 0 1 83.61 208.39l119.4 170.58h.01l40.63 58.04a330.055 330.055 0 0 0 78.94 1.17l-189.98-271.4a277.628 277.628 0 0 1 38.777-21.563l251.836 356.544c7.601 10.858 22.564 13.499 33.423 5.9l13.114-9.178c10.86-7.601 13.502-22.567 5.9-33.426l-43.12-58.377-.007-.009c57.161-27.978 104.835-72.04 136.81-126.301a47.938 47.938 0 0 0 .001-48.739zM390.026 345.94l-19.066-27.23c24.682-32.567 27.711-76.353 8.8-111.68v.03c0 23.65-19.17 42.82-42.82 42.82-23.828 0-42.82-19.349-42.82-42.82 0-23.65 19.17-42.82 42.82-42.82h.03c-24.75-13.249-53.522-15.643-79.51-7.68l-19.068-27.237C253.758 123.306 270.488 120 288 120c75.162 0 136 60.826 136 136 0 34.504-12.833 65.975-33.974 89.94z"] }; +var faMagic = { prefix: 'fas', iconName: 'magic', icon: [512, 512, [], "f0d0", "M101.1 505L7 410.9c-9.4-9.4-9.4-24.6 0-33.9L377 7c9.4-9.4 24.6-9.4 33.9 0l94.1 94.1c9.4 9.4 9.4 24.6 0 33.9L135 505c-9.3 9.3-24.5 9.3-33.9 0zM304 159.2l48.8 48.8 89.9-89.9-48.8-48.8-89.9 89.9zM138.9 39.3l-11.7 23.8-26.2 3.8c-4.7.7-6.6 6.5-3.2 9.8l19 18.5-4.5 26.1c-.8 4.7 4.1 8.3 8.3 6.1L144 115l23.4 12.3c4.2 2.2 9.1-1.4 8.3-6.1l-4.5-26.1 19-18.5c3.4-3.3 1.5-9.1-3.2-9.8L160.8 63l-11.7-23.8c-2-4.1-8.1-4.1-10.2.1zm97.7-20.7l-7.8 15.8-17.5 2.6c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L240 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm-192 0l-7.8 15.8L19.3 37c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4L48 69l15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-3-5.4-3-6.8-.1zm416 223.5l-7.8 15.8-17.5 2.5c-3.1.5-4.4 4.3-2.1 6.5l12.6 12.3-3 17.4c-.5 3.1 2.8 5.5 5.6 4l15.6-8.2 15.6 8.2c2.8 1.5 6.1-.9 5.6-4l-3-17.4 12.6-12.3c2.3-2.2 1-6.1-2.1-6.5l-17.5-2.5-7.8-15.8c-1.4-2.8-5.4-2.8-6.8 0z"] }; +var faMagnet = { prefix: 'fas', iconName: 'magnet', icon: [512, 512, [], "f076", "M164.1 160H12c-6.6 0-12-5.4-12-12V68c0-19.9 16.1-36 36-36h104c19.9 0 36 16.1 36 36v80c.1 6.6-5.3 12-11.9 12zm348-12V67.9c0-19.9-16.1-36-36-36h-104c-19.9 0-36 16.1-36 36v80c0 6.6 5.4 12 12 12h152c6.6.1 12-5.3 12-11.9zm-164 44c-6.6 0-12 5.4-12 12v52c0 128.1-160 127.9-160 0v-52c0-6.6-5.4-12-12-12h-152c-6.7 0-12 5.4-12 12.1.1 21.4.6 40.3 0 53.3C.1 408 136.3 504 256.9 504 377.5 504 512 408 512 257.3c-.6-12.8-.2-33 0-53.2 0-6.7-5.3-12.1-12-12.1H348.1z"] }; +var faMale = { prefix: 'fas', iconName: 'male', icon: [192, 512, [], "f183", "M96 0c35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64S60.654 0 96 0m48 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H48c-26.51 0-48 21.49-48 48v136c0 13.255 10.745 24 24 24h16v136c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V352h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48z"] }; +var faMap = { prefix: 'fas', iconName: 'map', icon: [576, 512, [], "f279", "M576 56.015v335.97a23.998 23.998 0 0 1-13.267 21.466l-128 64C418.948 485.344 400 473.992 400 455.985v-335.97a23.998 23.998 0 0 1 13.267-21.466l128-64C557.052 26.656 576 38.008 576 56.015zm-206.253 42.07l-144-64c-15.751-7-33.747 4.461-33.747 21.932v335.967a24 24 0 0 0 14.253 21.931l144 64c15.751 7 33.747-4.461 33.747-21.931V120.017a24 24 0 0 0-14.253-21.932zm-228.48-63.536l-128 63.985A23.998 23.998 0 0 0 0 120v335.985c0 18.007 18.948 29.359 34.733 21.466l128-63.985A23.998 23.998 0 0 0 176 392V56.015c0-18.007-18.948-29.359-34.733-21.466z"] }; +var faMapMarker = { prefix: 'fas', iconName: 'map-marker', icon: [384, 512, [], "f041", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z"] }; +var faMapMarkerAlt = { prefix: 'fas', iconName: 'map-marker-alt', icon: [384, 512, [], "f3c5", "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"] }; +var faMapPin = { prefix: 'fas', iconName: 'map-pin', icon: [320, 512, [], "f276", "M192 300.813v172.82l-22.015 33.023c-4.75 7.125-15.219 7.125-19.969 0L128 473.633v-172.82a162.221 162.221 0 0 0 64 0zM160 0c79.529 0 144 64.471 144 144s-64.471 144-144 144S16 223.529 16 144 80.471 0 160 0M80 136c0-39.701 32.299-72 72-72a8 8 0 0 0 0-16c-48.523 0-88 39.477-88 88a8 8 0 0 0 16 0z"] }; +var faMapSigns = { prefix: 'fas', iconName: 'map-signs', icon: [512, 512, [], "f277", "M487.515 104.485L439.03 152.97a23.998 23.998 0 0 1-16.97 7.029H56c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h160v-8c0-13.255 10.745-24 24-24h32c13.255 0 24 10.745 24 24v8h126.059a24 24 0 0 1 16.97 7.029l48.485 48.485c4.687 4.687 4.687 12.285.001 16.971zM216 368v120c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V368h-80zm240-144H296v-48h-80v48H89.941a24 24 0 0 0-16.97 7.029l-48.485 48.485c-4.686 4.686-4.686 12.284 0 16.971l48.485 48.485a23.998 23.998 0 0 0 16.97 7.029H456c13.255 0 24-10.745 24-24v-80C480 234.745 469.255 224 456 224z"] }; +var faMars = { prefix: 'fas', iconName: 'mars', icon: [384, 512, [], "f222", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c0-6.6-5.4-12-12-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faMarsDouble = { prefix: 'fas', iconName: 'mars-double', icon: [512, 512, [], "f227", "M340 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C198.5 72.1 172.2 64 144 64 64.5 64 0 128.5 0 208s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.5 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 288c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80zm356-128.1h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7c-18.2-11.4-39-18.9-61.5-21.3-2.1 21.8-8.2 43.3-18.4 63.3 1.1 0 2.2-.1 3.2-.1 44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80c0-1.1 0-2.2.1-3.2-20 10.2-41.5 16.4-63.3 18.4C168.4 455.6 229.6 512 304 512c79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12v-79c0-6.7-5.4-12.1-12-12.1z"] }; +var faMarsStroke = { prefix: 'fas', iconName: 'mars-stroke', icon: [384, 512, [], "f229", "M372 64h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-17.5 17.5-14.1-14.1c-4.7-4.7-12.3-4.7-17 0L224.5 133c-4.7 4.7-4.7 12.3 0 17l14.1 14.1-18 18c-22.2-14-48.5-22.1-76.7-22.1C64.5 160 0 224.5 0 304s64.5 144 144 144 144-64.5 144-144c0-28.2-8.1-54.5-22.1-76.7l18-18 14.1 14.1c4.7 4.7 12.3 4.7 17 0l28.3-28.3c4.7-4.7 4.7-12.3 0-17L329.2 164l17.5-17.5 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V76c-.1-6.6-5.5-12-12.1-12zM144 384c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faMarsStrokeH = { prefix: 'fas', iconName: 'mars-stroke-h', icon: [480, 512, [], "f22b", "M476.2 247.5l-55.9-55.9c-7.6-7.6-20.5-2.2-20.5 8.5V224H376v-20c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v20h-27.6c-5.8-25.6-18.7-49.9-38.6-69.8C189.6 98 98.4 98 42.2 154.2c-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 19.9-19.9 32.8-44.2 38.6-69.8H312v20c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-20h23.9v23.9c0 10.7 12.9 16 20.5 8.5l55.9-55.9c4.6-4.7 4.6-12.3-.1-17zm-275.6 65.1c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; +var faMarsStrokeV = { prefix: 'fas', iconName: 'mars-stroke-v', icon: [288, 512, [], "f22a", "M245.8 234.2c-19.9-19.9-44.2-32.8-69.8-38.6v-25.4h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V81.4h23.9c10.7 0 16-12.9 8.5-20.5L152.5 5.1c-4.7-4.7-12.3-4.7-17 0L79.6 61c-7.6 7.6-2.2 20.5 8.5 20.5H112v24.7H92c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h20v25.4c-25.6 5.8-49.9 18.7-69.8 38.6-56.2 56.2-56.2 147.4 0 203.6 56.2 56.2 147.4 56.2 203.6 0 56.3-56.2 56.3-147.4 0-203.6zm-45.2 158.4c-31.2 31.2-81.9 31.2-113.1 0-31.2-31.2-31.2-81.9 0-113.1 31.2-31.2 81.9-31.2 113.1 0 31.2 31.1 31.2 81.9 0 113.1z"] }; +var faMedkit = { prefix: 'fas', iconName: 'medkit', icon: [512, 512, [], "f0fa", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352zm288-208v32c0 8.837-7.163 16-16 16h-48v48c0 8.837-7.163 16-16 16h-32c-8.837 0-16-7.163-16-16v-48h-48c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h48v-48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v48h48c8.837 0 16 7.163 16 16z"] }; +var faMeh = { prefix: 'fas', iconName: 'meh', icon: [512, 512, [], "f11a", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-396-64c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm160 208H176c-21.178 0-21.169 32 0 32h160c21.178 0 21.169-32 0-32z"] }; +var faMercury = { prefix: 'fas', iconName: 'mercury', icon: [288, 512, [], "f223", "M288 208c0-44.2-19.9-83.7-51.2-110.1 2.5-1.8 4.9-3.8 7.2-5.8 24.7-21.2 39.8-48.8 43.2-78.8.9-7.1-4.7-13.3-11.9-13.3h-40.5C229 0 224.1 4.1 223 9.8c-2.4 12.5-9.6 24.3-20.7 33.8C187 56.8 166.3 64 144 64s-43-7.2-58.4-20.4C74.5 34.1 67.4 22.3 64.9 9.8 63.8 4.1 58.9 0 53.2 0H12.7C5.5 0-.1 6.2.8 13.3 4.2 43.4 19.2 71 44 92.2c2.3 2 4.7 3.9 7.2 5.8C19.9 124.3 0 163.8 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; +var faMicrochip = { prefix: 'fas', iconName: 'microchip', icon: [512, 512, [], "f2db", "M416 48v416c0 26.51-21.49 48-48 48H144c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h224c26.51 0 48 21.49 48 48zm96 58v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42V88h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zm0 96v12a6 6 0 0 1-6 6h-18v6a6 6 0 0 1-6 6h-42v-48h42a6 6 0 0 1 6 6v6h18a6 6 0 0 1 6 6zM30 376h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6zm0-96h42v48H30a6 6 0 0 1-6-6v-6H6a6 6 0 0 1-6-6v-12a6 6 0 0 1 6-6h18v-6a6 6 0 0 1 6-6z"] }; +var faMicrophone = { prefix: 'fas', iconName: 'microphone', icon: [384, 512, [], "f130", "M96 256V96c0-53.019 42.981-96 96-96s96 42.981 96 96v160c0 53.019-42.981 96-96 96s-96-42.981-96-96zm252-56h-24c-6.627 0-12 5.373-12 12v42.68c0 66.217-53.082 120.938-119.298 121.318C126.213 376.38 72 322.402 72 256v-44c0-6.627-5.373-12-12-12H36c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c81.307-11.681 144-81.79 144-166.278v-44c0-6.627-5.373-12-12-12z"] }; +var faMicrophoneSlash = { prefix: 'fas', iconName: 'microphone-slash', icon: [512, 512, [], "f131", "M421.45 285.195L376 239.746V212c0-6.627 5.373-12 12-12h24c6.627 0 12 5.373 12 12v44c0 9.957-.881 19.71-2.55 29.195zM352 96c0-53.019-42.981-96-96-96-32.574 0-61.354 16.227-78.71 41.035L352 215.746V96zm152.971 363.716L52.284 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 18.343c-9.372 9.373-9.372 24.568 0 33.941L160 205.254v49.577c0 53.089 43.436 97.452 96.524 97.167 14.626-.078 28.471-3.44 40.854-9.366l17.746 17.746c-17.529 9.971-37.794 15.666-59.372 15.622C189.355 375.864 136 321.053 136 254.656V212c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v44c0 84.488 62.693 154.597 144 166.278V468h-68c-6.627 0-12 5.373-12 12v20c0 6.627 5.373 12 12 12h184c6.627 0 12-5.373 12-12v-20c0-6.627-5.373-12-12-12h-68v-45.722c25.625-3.682 49.396-13.172 69.942-27.083L459.717 504.97c9.373 9.373 24.569 9.373 33.941 0l11.313-11.313c9.372-9.373 9.372-24.568 0-33.941z"] }; +var faMinus = { prefix: 'fas', iconName: 'minus', icon: [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"] }; +var faMinusCircle = { prefix: 'fas', iconName: 'minus-circle', icon: [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"] }; +var faMinusSquare = { prefix: 'fas', iconName: 'minus-square', icon: [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"] }; +var faMobile = { prefix: 'fas', iconName: 'mobile', icon: [320, 512, [], "f10b", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; +var faMobileAlt = { prefix: 'fas', iconName: 'mobile-alt', icon: [320, 512, [], "f3cd", "M272 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h224c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM160 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm112-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h200c6.6 0 12 5.4 12 12v312z"] }; +var faMoneyBillAlt = { prefix: 'fas', iconName: 'money-bill-alt', icon: [640, 512, [], "f3d1", "M640 120v272c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h592c13.255 0 24 10.745 24 24zM96 384c0-35.346-28.654-64-64-64v64h64zm0-256H32v64c35.346 0 64-28.654 64-64zm304 128c0-53.021-35.816-96-80-96s-80 42.979-80 96c0 53.012 35.814 96 80 96 44.167 0 80-42.969 80-96zm208 64c-35.346 0-64 28.654-64 64h64v-64zm0-192h-64c0 35.346 28.654 64 64 64v-64zM277.563 299.527c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z"] }; +var faMoon = { prefix: 'fas', iconName: 'moon', icon: [512, 512, [], "f186", "M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"] }; +var faMotorcycle = { prefix: 'fas', iconName: 'motorcycle', icon: [640, 512, [], "f21c", "M512.949 192.003c-14.862-.108-29.14 2.322-42.434 6.874L437.589 144H520c13.255 0 24-10.745 24-24V88c0-13.255-10.745-24-24-24h-45.311a24 24 0 0 0-17.839 7.945l-37.496 41.663-22.774-37.956A24 24 0 0 0 376 64h-80c-8.837 0-16 7.163-16 16v16c0 8.837 7.163 16 16 16h66.411l19.2 32H227.904c-17.727-23.073-44.924-40-99.904-40H72.54c-13.455 0-24.791 11.011-24.536 24.464C48.252 141.505 58.9 152 72 152h56c24.504 0 38.686 10.919 47.787 24.769l-11.291 20.529c-13.006-3.865-26.871-5.736-41.251-5.21C55.857 194.549 1.565 249.605.034 317.021-1.603 389.076 56.317 448 128 448c59.642 0 109.744-40.794 123.953-96h84.236c13.673 0 24.589-11.421 23.976-25.077-2.118-47.12 17.522-93.665 56.185-125.026l12.485 20.808c-27.646 23.654-45.097 58.88-44.831 98.179.47 69.556 57.203 126.452 126.758 127.11 71.629.678 129.839-57.487 129.234-129.099-.588-69.591-57.455-126.386-127.047-126.892zM128 400c-44.112 0-80-35.888-80-80s35.888-80 80-80c4.242 0 8.405.341 12.469.982L98.97 316.434C90.187 332.407 101.762 352 120 352h81.297c-12.37 28.225-40.56 48-73.297 48zm388.351-.116C470.272 402.337 432 365.554 432 320c0-21.363 8.434-40.781 22.125-55.144l49.412 82.352c4.546 7.577 14.375 10.034 21.952 5.488l13.72-8.232c7.577-4.546 10.034-14.375 5.488-21.952l-48.556-80.927A80.005 80.005 0 0 1 512 240c45.554 0 82.338 38.273 79.884 84.352-2.16 40.558-34.974 73.372-75.533 75.532z"] }; +var faMousePointer = { prefix: 'fas', iconName: 'mouse-pointer', icon: [320, 512, [], "f245", "M302.189 329.126H196.105l55.831 135.993c3.889 9.428-.555 19.999-9.444 23.999l-49.165 21.427c-9.165 4-19.443-.571-23.332-9.714l-53.053-129.136-86.664 89.138C18.729 472.71 0 463.554 0 447.977V18.299C0 1.899 19.921-6.096 30.277 5.443l284.412 292.542c11.472 11.179 3.007 31.141-12.5 31.141z"] }; +var faMusic = { prefix: 'fas', iconName: 'music', icon: [512, 512, [], "f001", "M470.4 1.5l-304 96C153.1 101.7 144 114 144 128v264.6c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V220.5l272-85.9v194c-14.1-5.4-30.5-8.6-48-8.6-53 0-96 28.7-96 64s43 64 96 64 96-28.7 96-64V32c0-21.7-21.1-37-41.6-30.5z"] }; +var faNeuter = { prefix: 'fas', iconName: 'neuter', icon: [288, 512, [], "f22c", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V468c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V316.4c64.1-14.5 112-71.9 112-140.4zm-144 80c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faNewspaper = { prefix: 'fas', iconName: 'newspaper', icon: [576, 512, [], "f1ea", "M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z"] }; +var faObjectGroup = { prefix: 'fas', iconName: 'object-group', icon: [512, 512, [], "f247", "M480 128V96h20c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v20H64V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v40c0 6.627 5.373 12 12 12h20v320H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-20h384v20c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-20V128zM96 276V140c0-6.627 5.373-12 12-12h168c6.627 0 12 5.373 12 12v136c0 6.627-5.373 12-12 12H108c-6.627 0-12-5.373-12-12zm320 96c0 6.627-5.373 12-12 12H236c-6.627 0-12-5.373-12-12v-52h72c13.255 0 24-10.745 24-24v-72h84c6.627 0 12 5.373 12 12v136z"] }; +var faObjectUngroup = { prefix: 'fas', iconName: 'object-ungroup', icon: [576, 512, [], "f248", "M64 320v26a6 6 0 0 1-6 6H6a6 6 0 0 1-6-6v-52a6 6 0 0 1 6-6h26V96H6a6 6 0 0 1-6-6V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v26h288V38a6 6 0 0 1 6-6h52a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-26v192h26a6 6 0 0 1 6 6v52a6 6 0 0 1-6 6h-52a6 6 0 0 1-6-6v-26H64zm480-64v-32h26a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-52a6 6 0 0 0-6 6v26H408v72h8c13.255 0 24 10.745 24 24v64c0 13.255-10.745 24-24 24h-64c-13.255 0-24-10.745-24-24v-8H192v72h-26a6 6 0 0 0-6 6v52a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-26h288v26a6 6 0 0 0 6 6h52a6 6 0 0 0 6-6v-52a6 6 0 0 0-6-6h-26V256z"] }; +var faOutdent = { prefix: 'fas', iconName: 'outdent', icon: [448, 512, [], "f03b", "M0 84V44c0-8.837 7.163-16 16-16h416c8.837 0 16 7.163 16 16v40c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16zm208 144h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM16 484h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm192-128h224c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H208c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zM4.687 267.313l96 95.984C110.734 373.348 128 366.224 128 351.984V160.008c0-14.329-17.325-21.304-27.313-11.313l-96 95.992c-6.249 6.248-6.249 16.378 0 22.626z"] }; +var faPaintBrush = { prefix: 'fas', iconName: 'paint-brush', icon: [512, 512, [], "f1fc", "M269.9 364.6c1.4 6.4 2.1 13 2.1 19.7 0 81.2-54.2 127.7-134.8 127.7C41.5 512 0 435.1 0 347.6c10.4 7.1 46.9 36.5 58.7 36.5 7 0 13-4 15.5-10.6 23.6-62.2 66.5-76.5 112.9-77.4 15.6 33.8 46.1 59.6 82.8 68.5zM460.6 0c-14.4 0-27.9 6.4-38.2 15.7C228.2 190 208 194.1 208 245.4c0 48.8 40.5 90.6 90.2 90.6 59 0 93.2-43.4 200.6-244.8 7-13.7 13.2-28.5 13.2-43.9C512 19.7 487.3 0 460.6 0z"] }; +var faPaperPlane = { prefix: 'fas', iconName: 'paper-plane', icon: [512, 512, [], "f1d8", "M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z"] }; +var faPaperclip = { prefix: 'fas', iconName: 'paperclip', icon: [448, 512, [], "f0c6", "M43.246 466.142c-58.43-60.289-57.341-157.511 1.386-217.581L254.392 34c44.316-45.332 116.351-45.336 160.671 0 43.89 44.894 43.943 117.329 0 162.276L232.214 383.128c-29.855 30.537-78.633 30.111-107.982-.998-28.275-29.97-27.368-77.473 1.452-106.953l143.743-146.835c6.182-6.314 16.312-6.422 22.626-.241l22.861 22.379c6.315 6.182 6.422 16.312.241 22.626L171.427 319.927c-4.932 5.045-5.236 13.428-.648 18.292 4.372 4.634 11.245 4.711 15.688.165l182.849-186.851c19.613-20.062 19.613-52.725-.011-72.798-19.189-19.627-49.957-19.637-69.154 0L90.39 293.295c-34.763 35.56-35.299 93.12-1.191 128.313 34.01 35.093 88.985 35.137 123.058.286l172.06-175.999c6.177-6.319 16.307-6.433 22.626-.256l22.877 22.364c6.319 6.177 6.434 16.307.256 22.626l-172.06 175.998c-59.576 60.938-155.943 60.216-214.77-.485z"] }; +var faParagraph = { prefix: 'fas', iconName: 'paragraph', icon: [448, 512, [], "f1dd", "M408 32H177.531C88.948 32 16.045 103.335 16 191.918 15.956 280.321 87.607 352 176 352v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h32v344c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V112h40c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24z"] }; +var faPaste = { prefix: 'fas', iconName: 'paste', icon: [448, 512, [], "f0ea", "M128 184c0-30.879 25.122-56 56-56h136V56c0-13.255-10.745-24-24-24h-80.61C204.306 12.89 183.637 0 160 0s-44.306 12.89-55.39 32H24C10.745 32 0 42.745 0 56v336c0 13.255 10.745 24 24 24h104V184zm32-144c13.255 0 24 10.745 24 24s-10.745 24-24 24-24-10.745-24-24 10.745-24 24-24zm184 248h104v200c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h136v104c0 13.2 10.8 24 24 24zm104-38.059V256h-96v-96h6.059a24 24 0 0 1 16.97 7.029l65.941 65.941a24.002 24.002 0 0 1 7.03 16.971z"] }; +var faPause = { prefix: 'fas', iconName: 'pause', icon: [448, 512, [], "f04c", "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"] }; +var faPauseCircle = { prefix: 'fas', iconName: 'pause-circle', icon: [512, 512, [], "f28b", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"] }; +var faPaw = { prefix: 'fas', iconName: 'paw', icon: [512, 512, [], "f1b0", "M85.231 330.958C36 330.958 0 273.792 0 231.5c0-28.292 16-58.042 49.538-58.042 49.231 0 85.231 57.458 85.231 99.75 0 28.292-15.692 57.75-49.538 57.75zm348 106.167c0 37.042-32 42.875-63.385 42.875-41.231 0-74.462-26.25-113.846-26.25-41.231 0-76.308 25.958-120.923 25.958-29.847 0-56.308-9.625-56.308-42.583C78.769 368 180.616 265.333 256 265.333s177.231 102.959 177.231 171.792zM182.462 203.792c-49.847 0-80-59.5-80-100.333C102.462 70.792 120.308 32 160 32c50.154 0 80 59.5 80 100.333 0 32.667-17.846 71.459-57.538 71.459zM272 132.333C272 91.5 301.846 32 352 32c39.692 0 57.539 38.792 57.539 71.458 0 40.833-30.154 100.333-80.001 100.333C289.846 203.792 272 165 272 132.333zM512 231.5c0 42.292-36 99.458-85.231 99.458-33.847 0-49.538-29.458-49.538-57.75 0-42.291 35.999-99.75 85.231-99.75C496 173.458 512 203.208 512 231.5z"] }; +var faPenSquare = { prefix: 'fas', iconName: 'pen-square', icon: [448, 512, [], "f14b", "M400 480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zM238.1 177.9L102.4 313.6l-6.3 57.1c-.8 7.6 5.6 14.1 13.3 13.3l57.1-6.3L302.2 242c2.3-2.3 2.3-6.1 0-8.5L246.7 178c-2.5-2.4-6.3-2.4-8.6-.1zM345 165.1L314.9 135c-9.4-9.4-24.6-9.4-33.9 0l-23.1 23.1c-2.3 2.3-2.3 6.1 0 8.5l55.5 55.5c2.3 2.3 6.1 2.3 8.5 0L345 199c9.3-9.3 9.3-24.5 0-33.9z"] }; +var faPencilAlt = { prefix: 'fas', iconName: 'pencil-alt', icon: [512, 512, [], "f303", "M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"] }; +var faPercent = { prefix: 'fas', iconName: 'percent', icon: [448, 512, [], "f295", "M112 224c61.9 0 112-50.1 112-112S173.9 0 112 0 0 50.1 0 112s50.1 112 112 112zm0-160c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm224 224c-61.9 0-112 50.1-112 112s50.1 112 112 112 112-50.1 112-112-50.1-112-112-112zm0 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zM392.3.2l31.6-.1c19.4-.1 30.9 21.8 19.7 37.8L77.4 501.6a23.95 23.95 0 0 1-19.6 10.2l-33.4.1c-19.5 0-30.9-21.9-19.7-37.8l368-463.7C377.2 4 384.5.2 392.3.2z"] }; +var faPhone = { prefix: 'fas', iconName: 'phone', icon: [512, 512, [], "f095", "M493.397 24.615l-104-23.997c-11.314-2.611-22.879 3.252-27.456 13.931l-48 111.997a24 24 0 0 0 6.862 28.029l60.617 49.596c-35.973 76.675-98.938 140.508-177.249 177.248l-49.596-60.616a24 24 0 0 0-28.029-6.862l-111.997 48C3.873 366.516-1.994 378.08.618 389.397l23.997 104C27.109 504.204 36.748 512 48 512c256.087 0 464-207.532 464-464 0-11.176-7.714-20.873-18.603-23.385z"] }; +var faPhoneSquare = { prefix: 'fas', iconName: 'phone-square', icon: [448, 512, [], "f098", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM94 416c-7.033 0-13.057-4.873-14.616-11.627l-14.998-65a15 15 0 0 1 8.707-17.16l69.998-29.999a15 15 0 0 1 17.518 4.289l30.997 37.885c48.944-22.963 88.297-62.858 110.781-110.78l-37.886-30.997a15.001 15.001 0 0 1-4.289-17.518l30-69.998a15 15 0 0 1 17.16-8.707l65 14.998A14.997 14.997 0 0 1 384 126c0 160.292-129.945 290-290 290z"] }; +var faPhoneVolume = { prefix: 'fas', iconName: 'phone-volume', icon: [384, 512, [], "f2a0", "M97.333 506.966c-129.874-129.874-129.681-340.252 0-469.933 5.698-5.698 14.527-6.632 21.263-2.422l64.817 40.513a17.187 17.187 0 0 1 6.849 20.958l-32.408 81.021a17.188 17.188 0 0 1-17.669 10.719l-55.81-5.58c-21.051 58.261-20.612 122.471 0 179.515l55.811-5.581a17.188 17.188 0 0 1 17.669 10.719l32.408 81.022a17.188 17.188 0 0 1-6.849 20.958l-64.817 40.513a17.19 17.19 0 0 1-21.264-2.422zM247.126 95.473c11.832 20.047 11.832 45.008 0 65.055-3.95 6.693-13.108 7.959-18.718 2.581l-5.975-5.726c-3.911-3.748-4.793-9.622-2.261-14.41a32.063 32.063 0 0 0 0-29.945c-2.533-4.788-1.65-10.662 2.261-14.41l5.975-5.726c5.61-5.378 14.768-4.112 18.718 2.581zm91.787-91.187c60.14 71.604 60.092 175.882 0 247.428-4.474 5.327-12.53 5.746-17.552.933l-5.798-5.557c-4.56-4.371-4.977-11.529-.93-16.379 49.687-59.538 49.646-145.933 0-205.422-4.047-4.85-3.631-12.008.93-16.379l5.798-5.557c5.022-4.813 13.078-4.394 17.552.933zm-45.972 44.941c36.05 46.322 36.108 111.149 0 157.546-4.39 5.641-12.697 6.251-17.856 1.304l-5.818-5.579c-4.4-4.219-4.998-11.095-1.285-15.931 26.536-34.564 26.534-82.572 0-117.134-3.713-4.836-3.115-11.711 1.285-15.931l5.818-5.579c5.159-4.947 13.466-4.337 17.856 1.304z"] }; +var faPlane = { prefix: 'fas', iconName: 'plane', icon: [576, 512, [], "f072", "M472 200H360.211L256.013 5.711A12 12 0 0 0 245.793 0h-57.787c-7.85 0-13.586 7.413-11.616 15.011L209.624 200H99.766l-34.904-58.174A12 12 0 0 0 54.572 136H12.004c-7.572 0-13.252 6.928-11.767 14.353l21.129 105.648L.237 361.646c-1.485 7.426 4.195 14.354 11.768 14.353l42.568-.002c4.215 0 8.121-2.212 10.289-5.826L99.766 312h109.858L176.39 496.989c-1.97 7.599 3.766 15.011 11.616 15.011h57.787a12 12 0 0 0 10.22-5.711L360.212 312H472c57.438 0 104-25.072 104-56s-46.562-56-104-56z"] }; +var faPlay = { prefix: 'fas', iconName: 'play', icon: [448, 512, [], "f04b", "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"] }; +var faPlayCircle = { prefix: 'fas', iconName: 'play-circle', icon: [512, 512, [], "f144", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z"] }; +var faPlug = { prefix: 'fas', iconName: 'plug', icon: [384, 512, [], "f1e6", "M256 144V32c0-17.673 14.327-32 32-32s32 14.327 32 32v112h-64zm112 16H16c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h16v32c0 77.406 54.969 141.971 128 156.796V512h64v-99.204c73.031-14.825 128-79.39 128-156.796v-32h16c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16zm-240-16V32c0-17.673-14.327-32-32-32S64 14.327 64 32v112h64z"] }; +var faPlus = { prefix: 'fas', iconName: 'plus', icon: [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"] }; +var faPlusCircle = { prefix: 'fas', iconName: 'plus-circle', icon: [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; +var faPlusSquare = { prefix: 'fas', iconName: 'plus-square', icon: [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"] }; +var faPodcast = { prefix: 'fas', iconName: 'podcast', icon: [448, 512, [], "f2ce", "M267.429 488.563C262.286 507.573 242.858 512 224 512c-18.857 0-38.286-4.427-43.428-23.437C172.927 460.134 160 388.898 160 355.75c0-35.156 31.142-43.75 64-43.75s64 8.594 64 43.75c0 32.949-12.871 104.179-20.571 132.813zM156.867 288.554c-18.693-18.308-29.958-44.173-28.784-72.599 2.054-49.724 42.395-89.956 92.124-91.881C274.862 121.958 320 165.807 320 220c0 26.827-11.064 51.116-28.866 68.552-2.675 2.62-2.401 6.986.628 9.187 9.312 6.765 16.46 15.343 21.234 25.363 1.741 3.654 6.497 4.66 9.449 1.891 28.826-27.043 46.553-65.783 45.511-108.565-1.855-76.206-63.595-138.208-139.793-140.369C146.869 73.753 80 139.215 80 220c0 41.361 17.532 78.7 45.55 104.989 2.953 2.771 7.711 1.77 9.453-1.887 4.774-10.021 11.923-18.598 21.235-25.363 3.029-2.2 3.304-6.566.629-9.185zM224 0C100.204 0 0 100.185 0 224c0 89.992 52.602 165.647 125.739 201.408 4.333 2.118 9.267-1.544 8.535-6.31-2.382-15.512-4.342-30.946-5.406-44.339-.146-1.836-1.149-3.486-2.678-4.512-47.4-31.806-78.564-86.016-78.187-147.347.592-96.237 79.29-174.648 175.529-174.899C320.793 47.747 400 126.797 400 224c0 61.932-32.158 116.49-80.65 147.867-.999 14.037-3.069 30.588-5.624 47.23-.732 4.767 4.203 8.429 8.535 6.31C395.227 389.727 448 314.187 448 224 448 100.205 347.815 0 224 0zm0 160c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64z"] }; +var faPoundSign = { prefix: 'fas', iconName: 'pound-sign', icon: [320, 512, [], "f154", "M308 352h-45.495c-6.627 0-12 5.373-12 12v50.848H128V288h84c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-84v-63.556c0-32.266 24.562-57.086 61.792-57.086 23.658 0 45.878 11.505 57.652 18.849 5.151 3.213 11.888 2.051 15.688-2.685l28.493-35.513c4.233-5.276 3.279-13.005-2.119-17.081C273.124 54.56 236.576 32 187.931 32 106.026 32 48 84.742 48 157.961V224H20c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h28v128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h296c6.627 0 12-5.373 12-12V364c0-6.627-5.373-12-12-12z"] }; +var faPowerOff = { prefix: 'fas', iconName: 'power-off', icon: [512, 512, [], "f011", "M400 54.1c63 45 104 118.6 104 201.9 0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 173.1 48.9 99.3 111.8 54.2c11.7-8.3 28-4.8 35 7.7L162.6 90c5.9 10.5 3.1 23.8-6.6 31-41.5 30.8-68 79.6-68 134.9-.1 92.3 74.5 168.1 168 168.1 91.6 0 168.6-74.2 168-169.1-.3-51.8-24.7-101.8-68.1-134-9.7-7.2-12.4-20.5-6.5-30.9l15.8-28.1c7-12.4 23.2-16.1 34.8-7.8zM296 264V24c0-13.3-10.7-24-24-24h-32c-13.3 0-24 10.7-24 24v240c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24z"] }; +var faPrint = { prefix: 'fas', iconName: 'print', icon: [512, 512, [], "f02f", "M464 192h-16V81.941a24 24 0 0 0-7.029-16.97L383.029 7.029A24 24 0 0 0 366.059 0H88C74.745 0 64 10.745 64 24v168H48c-26.51 0-48 21.49-48 48v132c0 6.627 5.373 12 12 12h52v104c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V384h52c6.627 0 12-5.373 12-12V240c0-26.51-21.49-48-48-48zm-80 256H128v-96h256v96zM128 224V64h192v40c0 13.2 10.8 24 24 24h40v96H128zm304 72c-13.254 0-24-10.746-24-24s10.746-24 24-24 24 10.746 24 24-10.746 24-24 24z"] }; +var faPuzzlePiece = { prefix: 'fas', iconName: 'puzzle-piece', icon: [576, 512, [], "f12e", "M519.442 288.651c-41.519 0-59.5 31.593-82.058 31.593C377.409 320.244 432 144 432 144s-196.288 80-196.288-3.297c0-35.827 36.288-46.25 36.288-85.985C272 19.216 243.885 0 210.539 0c-34.654 0-66.366 18.891-66.366 56.346 0 41.364 31.711 59.277 31.711 81.75C175.885 207.719 0 166.758 0 166.758v333.237s178.635 41.047 178.635-28.662c0-22.473-40-40.107-40-81.471 0-37.456 29.25-56.346 63.577-56.346 33.673 0 61.788 19.216 61.788 54.717 0 39.735-36.288 50.158-36.288 85.985 0 60.803 129.675 25.73 181.23 25.73 0 0-34.725-120.101 25.827-120.101 35.962 0 46.423 36.152 86.308 36.152C556.712 416 576 387.99 576 354.443c0-34.199-18.962-65.792-56.558-65.792z"] }; +var faQrcode = { prefix: 'fas', iconName: 'qrcode', icon: [448, 512, [], "f029", "M0 224h192V32H0v192zM64 96h64v64H64V96zm192-64v192h192V32H256zm128 128h-64V96h64v64zM0 480h192V288H0v192zm64-128h64v64H64v-64zm352-64h32v128h-96v-32h-32v96h-64V288h96v32h64v-32zm0 160h32v32h-32v-32zm-64 0h32v32h-32v-32z"] }; +var faQuestion = { prefix: 'fas', iconName: 'question', icon: [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"] }; +var faQuestionCircle = { prefix: 'fas', iconName: 'question-circle', icon: [512, 512, [], "f059", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"] }; +var faQuoteLeft = { prefix: 'fas', iconName: 'quote-left', icon: [512, 512, [], "f10d", "M0 432V304C0 166.982 63.772 67.676 193.827 32.828 209.052 28.748 224 40.265 224 56.027v33.895c0 10.057-6.228 19.133-15.687 22.55C142.316 136.312 104 181.946 104 256h72c26.51 0 48 21.49 48 48v128c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48zm336 48h128c26.51 0 48-21.49 48-48V304c0-26.51-21.49-48-48-48h-72c0-74.054 38.316-119.688 104.313-143.528C505.772 109.055 512 99.979 512 89.922V56.027c0-15.762-14.948-27.279-30.173-23.199C351.772 67.676 288 166.982 288 304v128c0 26.51 21.49 48 48 48z"] }; +var faQuoteRight = { prefix: 'fas', iconName: 'quote-right', icon: [512, 512, [], "f10e", "M512 80v128c0 137.018-63.772 236.324-193.827 271.172-15.225 4.08-30.173-7.437-30.173-23.199v-33.895c0-10.057 6.228-19.133 15.687-22.55C369.684 375.688 408 330.054 408 256h-72c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h128c26.51 0 48 21.49 48 48zM176 32H48C21.49 32 0 53.49 0 80v128c0 26.51 21.49 48 48 48h72c0 74.054-38.316 119.688-104.313 143.528C6.228 402.945 0 412.021 0 422.078v33.895c0 15.762 14.948 27.279 30.173 23.199C160.228 444.324 224 345.018 224 208V80c0-26.51-21.49-48-48-48z"] }; +var faRandom = { prefix: 'fas', iconName: 'random', icon: [512, 512, [], "f074", "M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z"] }; +var faRecycle = { prefix: 'fas', iconName: 'recycle', icon: [512, 512, [], "f1b8", "M184.561 261.903c3.232 13.997-12.123 24.635-24.068 17.168l-40.736-25.455-50.867 81.402C55.606 356.273 70.96 384 96.012 384H148c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12H96.115c-75.334 0-121.302-83.048-81.408-146.88l50.822-81.388-40.725-25.448c-12.081-7.547-8.966-25.961 4.879-29.158l110.237-25.45c8.611-1.988 17.201 3.381 19.189 11.99l25.452 110.237zm98.561-182.915l41.289 66.076-40.74 25.457c-12.051 7.528-9 25.953 4.879 29.158l110.237 25.45c8.672 1.999 17.215-3.438 19.189-11.99l25.45-110.237c3.197-13.844-11.99-24.719-24.068-17.168l-40.687 25.424-41.263-66.082c-37.521-60.033-125.209-60.171-162.816 0l-17.963 28.766c-3.51 5.62-1.8 13.021 3.82 16.533l33.919 21.195c5.62 3.512 13.024 1.803 16.536-3.817l17.961-28.743c12.712-20.341 41.973-19.676 54.257-.022zM497.288 301.12l-27.515-44.065c-3.511-5.623-10.916-7.334-16.538-3.821l-33.861 21.159c-5.62 3.512-7.33 10.915-3.818 16.536l27.564 44.112c13.257 21.211-2.057 48.96-27.136 48.96H320V336.02c0-14.213-17.242-21.383-27.313-11.313l-80 79.981c-6.249 6.248-6.249 16.379 0 22.627l80 79.989C302.689 517.308 320 510.3 320 495.989V448h95.88c75.274 0 121.335-82.997 81.408-146.88z"] }; +var faRedo = { prefix: 'fas', iconName: 'redo', icon: [512, 512, [], "f01e", "M500.333 0h-47.411c-6.853 0-12.314 5.729-11.986 12.574l3.966 82.759C399.416 41.899 331.672 8 256.001 8 119.34 8 7.899 119.526 8 256.187 8.101 393.068 119.096 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-33.971-33.971c-4.466-4.466-11.64-4.717-16.38-.543C341.308 415.448 300.606 432 256 432c-97.267 0-176-78.716-176-176 0-97.267 78.716-176 176-176 60.892 0 114.506 30.858 146.099 77.8l-101.525-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12z"] }; +var faRedoAlt = { prefix: 'fas', iconName: 'redo-alt', icon: [512, 512, [], "f2f9", "M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"] }; +var faRegistered = { prefix: 'fas', iconName: 'registered', icon: [512, 512, [], "f25d", "M285.363 207.475c0 18.6-9.831 28.431-28.431 28.431h-29.876v-56.14h23.378c28.668 0 34.929 8.773 34.929 27.709zM504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM363.411 360.414c-46.729-84.825-43.299-78.636-44.702-80.98 23.432-15.172 37.945-42.979 37.945-74.486 0-54.244-31.5-89.252-105.498-89.252h-70.667c-13.255 0-24 10.745-24 24V372c0 13.255 10.745 24 24 24h22.567c13.255 0 24-10.745 24-24v-71.663h25.556l44.129 82.937a24.001 24.001 0 0 0 21.188 12.727h24.464c18.261-.001 29.829-19.591 21.018-35.587z"] }; +var faReply = { prefix: 'fas', iconName: 'reply', icon: [512, 512, [], "f3e5", "M8.309 189.836L184.313 37.851C199.719 24.546 224 35.347 224 56.015v80.053c160.629 1.839 288 34.032 288 186.258 0 61.441-39.581 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 45.344-145.012-21.507-183.51-176.59-185.742V360c0 20.7-24.3 31.453-39.687 18.164l-176.004-152c-11.071-9.562-11.086-26.753 0-36.328z"] }; +var faReplyAll = { prefix: 'fas', iconName: 'reply-all', icon: [576, 512, [], "f122", "M136.309 189.836L312.313 37.851C327.72 24.546 352 35.348 352 56.015v82.763c129.182 10.231 224 52.212 224 183.548 0 61.441-39.582 122.309-83.333 154.132-13.653 9.931-33.111-2.533-28.077-18.631 38.512-123.162-3.922-169.482-112.59-182.015v84.175c0 20.701-24.3 31.453-39.687 18.164L136.309 226.164c-11.071-9.561-11.086-26.753 0-36.328zm-128 36.328L184.313 378.15C199.7 391.439 224 380.687 224 359.986v-15.818l-108.606-93.785A55.96 55.96 0 0 1 96 207.998a55.953 55.953 0 0 1 19.393-42.38L224 71.832V56.015c0-20.667-24.28-31.469-39.687-18.164L8.309 189.836c-11.086 9.575-11.071 26.767 0 36.328z"] }; +var faRetweet = { prefix: 'fas', iconName: 'retweet', icon: [640, 512, [], "f079", "M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z"] }; +var faRoad = { prefix: 'fas', iconName: 'road', icon: [576, 512, [], "f018", "M567.3 383.6L429.9 78.2C426 69.5 417.4 64 408 64h-96.1l1.9 18.8c.7 7.1-4.8 13.2-11.9 13.2H274c-7.1 0-12.7-6.2-11.9-13.2L264 64h-96c-9.4 0-18 5.5-21.9 14.2L8.7 383.6C3.2 395.8 0 409.6 0 424c0 13.3 10.7 24 24 24h213.6c-7.1 0-12.7-6.2-11.9-13.2l10.8-104c.6-6.1 5.8-10.8 11.9-10.8h79.2c6.1 0 11.3 4.6 11.9 10.8l10.8 104c.7 7.1-4.8 13.2-11.9 13.2H552c13.2 0 24-10.7 24-24 0-13.9-3-27.7-8.7-40.4zM254.7 154.8l3.3-32c.6-6.1 5.8-10.8 11.9-10.8h36.2c6.1 0 11.3 4.6 11.9 10.8l3.3 32c.7 7.1-4.8 13.2-11.9 13.2h-42.8c-7.1 0-12.7-6.2-11.9-13.2zM321.8 288h-67.6c-7.1 0-12.7-6.2-11.9-13.2l7.4-72c.6-6.1 5.8-10.8 11.9-10.8h52.7c6.1 0 11.3 4.6 11.9 10.8l7.4 72c.9 7-4.7 13.2-11.8 13.2z"] }; +var faRocket = { prefix: 'fas', iconName: 'rocket', icon: [512, 512, [], "f135", "M505.1 19.1C503.8 13 499 8.2 492.9 6.9 460.7 0 435.5 0 410.4 0 307.2 0 245.3 55.2 199.1 128H94.9c-18.2 0-34.8 10.3-42.9 26.5L2.6 253.3c-8 16 3.6 34.7 21.5 34.7h95.1c-5.9 12.8-11.9 25.5-18 37.7-3.1 6.2-1.9 13.6 3 18.5l63.6 63.6c4.9 4.9 12.3 6.1 18.5 3 12.2-6.1 24.9-12 37.7-17.9V488c0 17.8 18.8 29.4 34.7 21.5l98.7-49.4c16.3-8.1 26.5-24.8 26.5-42.9V312.8c72.6-46.3 128-108.4 128-211.1.1-25.2.1-50.4-6.8-82.6zM400 160c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"] }; +var faRss = { prefix: 'fas', iconName: 'rss', icon: [448, 512, [], "f09e", "M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"] }; +var faRssSquare = { prefix: 'fas', iconName: 'rss-square', icon: [448, 512, [], "f143", "M400 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM112 416c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm157.533 0h-34.335c-6.011 0-11.051-4.636-11.442-10.634-5.214-80.05-69.243-143.92-149.123-149.123-5.997-.39-10.633-5.431-10.633-11.441v-34.335c0-6.535 5.468-11.777 11.994-11.425 110.546 5.974 198.997 94.536 204.964 204.964.352 6.526-4.89 11.994-11.425 11.994zm103.027 0h-34.334c-6.161 0-11.175-4.882-11.427-11.038-5.598-136.535-115.204-246.161-251.76-251.76C68.882 152.949 64 147.935 64 141.774V107.44c0-6.454 5.338-11.664 11.787-11.432 167.83 6.025 302.21 141.191 308.205 308.205.232 6.449-4.978 11.787-11.432 11.787z"] }; +var faRubleSign = { prefix: 'fas', iconName: 'ruble-sign', icon: [384, 512, [], "f158", "M239.36 320C324.48 320 384 260.542 384 175.071S324.48 32 239.36 32H76c-6.627 0-12 5.373-12 12v206.632H12c-6.627 0-12 5.373-12 12V308c0 6.627 5.373 12 12 12h52v32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h52v52c0 6.627 5.373 12 12 12h58.56c6.627 0 12-5.373 12-12v-52H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H146.56v-32h92.8zm-92.8-219.252h78.72c46.72 0 74.88 29.11 74.88 74.323 0 45.832-28.16 75.561-76.16 75.561h-77.44V100.748z"] }; +var faRupeeSign = { prefix: 'fas', iconName: 'rupee-sign', icon: [320, 512, [], "f156", "M308 96c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12H12C5.373 32 0 37.373 0 44v44.748c0 6.627 5.373 12 12 12h85.28c27.308 0 48.261 9.958 60.97 27.252H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h158.757c-6.217 36.086-32.961 58.632-74.757 58.632H12c-6.627 0-12 5.373-12 12v53.012c0 3.349 1.4 6.546 3.861 8.818l165.052 152.356a12.001 12.001 0 0 0 8.139 3.182h82.562c10.924 0 16.166-13.408 8.139-20.818L116.871 319.906c76.499-2.34 131.144-53.395 138.318-127.906H308c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-58.69c-3.486-11.541-8.28-22.246-14.252-32H308z"] }; +var faSave = { prefix: 'fas', iconName: 'save', icon: [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"] }; +var faSearch = { prefix: 'fas', iconName: 'search', icon: [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"] }; +var faSearchMinus = { prefix: 'fas', iconName: 'search-minus', icon: [512, 512, [], "f010", "M304 192v32c0 6.6-5.4 12-12 12H124c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; +var faSearchPlus = { prefix: 'fas', iconName: 'search-plus', icon: [512, 512, [], "f00e", "M304 192v32c0 6.6-5.4 12-12 12h-56v56c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-56h-56c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h56v-56c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v56h56c6.6 0 12 5.4 12 12zm201 284.7L476.7 505c-9.4 9.4-24.6 9.4-33.9 0L343 405.3c-4.5-4.5-7-10.6-7-17V372c-35.3 27.6-79.7 44-128 44C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208c0 48.3-16.4 92.7-44 128h16.3c6.4 0 12.5 2.5 17 7l99.7 99.7c9.3 9.4 9.3 24.6 0 34zM344 208c0-75.2-60.8-136-136-136S72 132.8 72 208s60.8 136 136 136 136-60.8 136-136z"] }; +var faServer = { prefix: 'fas', iconName: 'server', icon: [512, 512, [], "f233", "M480 160H32c-17.673 0-32-14.327-32-32V64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm112 248H32c-17.673 0-32-14.327-32-32v-64c0-17.673 14.327-32 32-32h448c17.673 0 32 14.327 32 32v64c0 17.673-14.327 32-32 32zm-48-88c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24z"] }; +var faShare = { prefix: 'fas', iconName: 'share', icon: [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"] }; +var faShareAlt = { prefix: 'fas', iconName: 'share-alt', icon: [448, 512, [], "f1e0", "M352 320c-22.608 0-43.387 7.819-59.79 20.895l-102.486-64.054a96.551 96.551 0 0 0 0-41.683l102.486-64.054C308.613 184.181 329.392 192 352 192c53.019 0 96-42.981 96-96S405.019 0 352 0s-96 42.981-96 96c0 7.158.79 14.13 2.276 20.841L155.79 180.895C139.387 167.819 118.608 160 96 160c-53.019 0-96 42.981-96 96s42.981 96 96 96c22.608 0 43.387-7.819 59.79-20.895l102.486 64.054A96.301 96.301 0 0 0 256 416c0 53.019 42.981 96 96 96s96-42.981 96-96-42.981-96-96-96z"] }; +var faShareAltSquare = { prefix: 'fas', iconName: 'share-alt-square', icon: [448, 512, [], "f1e1", "M448 80v352c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V80c0-26.51 21.49-48 48-48h352c26.51 0 48 21.49 48 48zM304 296c-14.562 0-27.823 5.561-37.783 14.671l-67.958-40.775a56.339 56.339 0 0 0 0-27.793l67.958-40.775C276.177 210.439 289.438 216 304 216c30.928 0 56-25.072 56-56s-25.072-56-56-56-56 25.072-56 56c0 4.797.605 9.453 1.74 13.897l-67.958 40.775C171.823 205.561 158.562 200 144 200c-30.928 0-56 25.072-56 56s25.072 56 56 56c14.562 0 27.823-5.561 37.783-14.671l67.958 40.775a56.088 56.088 0 0 0-1.74 13.897c0 30.928 25.072 56 56 56s56-25.072 56-56C360 321.072 334.928 296 304 296z"] }; +var faShareSquare = { prefix: 'fas', iconName: 'share-square', icon: [576, 512, [], "f14d", "M568.482 177.448L424.479 313.433C409.3 327.768 384 317.14 384 295.985v-71.963c-144.575.97-205.566 35.113-164.775 171.353 4.483 14.973-12.846 26.567-25.006 17.33C155.252 383.105 120 326.488 120 269.339c0-143.937 117.599-172.5 264-173.312V24.012c0-21.174 25.317-31.768 40.479-17.448l144.003 135.988c10.02 9.463 10.028 25.425 0 34.896zM384 379.128V448H64V128h50.916a11.99 11.99 0 0 0 8.648-3.693c14.953-15.568 32.237-27.89 51.014-37.676C185.708 80.83 181.584 64 169.033 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48v-88.806c0-8.288-8.197-14.066-16.011-11.302a71.83 71.83 0 0 1-34.189 3.377c-7.27-1.046-13.8 4.514-13.8 11.859z"] }; +var faShekelSign = { prefix: 'fas', iconName: 'shekel-sign', icon: [448, 512, [], "f20b", "M170.12 96H80v372c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V44c0-6.627 5.373-12 12-12h168.36C265.48 32 325 89.6 325 175.071V359c0 6.627-5.373 12-12 12h-44c-13.255 0-24-10.745-24-24V170.323C245 125.11 216.839 96 170.12 96zM436 32h-56c-6.627 0-12 5.373-12 12v372h-90.12c-46.72 0-74.88-29.11-74.88-74.323V165c0-13.255-10.745-24-24-24h-44c-6.627 0-12 5.373-12 12v183.929C123 422.4 182.52 480 267.64 480H436c6.627 0 12-5.373 12-12V44c0-6.627-5.373-12-12-12z"] }; +var faShieldAlt = { prefix: 'fas', iconName: 'shield-alt', icon: [512, 512, [], "f3ed", "M496 128c0 221.282-135.934 344.645-221.539 380.308a48 48 0 0 1-36.923 0C130.495 463.713 16 326.487 16 128a48 48 0 0 1 29.539-44.308l192-80a48 48 0 0 1 36.923 0l192 80A48 48 0 0 1 496 128zM256 446.313l.066.034c93.735-46.689 172.497-156.308 175.817-307.729L256 65.333v380.98z"] }; +var faShip = { prefix: 'fas', iconName: 'ship', icon: [640, 512, [], "f21a", "M496.616 372.639l70.012-70.012c16.899-16.9 9.942-45.771-12.836-53.092L512 236.102V96c0-17.673-14.327-32-32-32h-64V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v40h-64c-17.673 0-32 14.327-32 32v140.102l-41.792 13.433c-22.753 7.313-29.754 36.173-12.836 53.092l70.012 70.012C125.828 416.287 85.587 448 24 448c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24 61.023 0 107.499-20.61 143.258-59.396C181.677 487.432 216.021 512 256 512h128c39.979 0 74.323-24.568 88.742-59.396C508.495 491.384 554.968 512 616 512c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24-60.817 0-101.542-31.001-119.384-75.361zM192 128h256v87.531l-118.208-37.995a31.995 31.995 0 0 0-19.584 0L192 215.531V128z"] }; +var faShoppingBag = { prefix: 'fas', iconName: 'shopping-bag', icon: [448, 512, [], "f290", "M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z"] }; +var faShoppingBasket = { prefix: 'fas', iconName: 'shopping-basket', icon: [576, 512, [], "f291", "M576 216v16c0 13.255-10.745 24-24 24h-8l-26.113 182.788C514.509 462.435 494.257 480 470.37 480H105.63c-23.887 0-44.139-17.565-47.518-41.212L32 256h-8c-13.255 0-24-10.745-24-24v-16c0-13.255 10.745-24 24-24h67.341l106.78-146.821c10.395-14.292 30.407-17.453 44.701-7.058 14.293 10.395 17.453 30.408 7.058 44.701L170.477 192h235.046L326.12 82.821c-10.395-14.292-7.234-34.306 7.059-44.701 14.291-10.395 34.306-7.235 44.701 7.058L484.659 192H552c13.255 0 24 10.745 24 24zM312 392V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm112 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24zm-224 0V280c0-13.255-10.745-24-24-24s-24 10.745-24 24v112c0 13.255 10.745 24 24 24s24-10.745 24-24z"] }; +var faShoppingCart = { prefix: 'fas', iconName: 'shopping-cart', icon: [576, 512, [], "f07a", "M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"] }; +var faShower = { prefix: 'fas', iconName: 'shower', icon: [512, 512, [], "f2cc", "M389.66 135.6L231.6 293.66c-9.37 9.37-24.57 9.37-33.94 0l-11.32-11.32c-9.37-9.37-9.37-24.57 0-33.94l.11-.11c-34.03-40.21-35.16-98.94-3.39-140.38-11.97-7.55-26.14-11.91-41.3-11.91C98.88 96 64 130.88 64 173.76V480H0V173.76C0 95.59 63.59 32 141.76 32c36.93 0 70.61 14.2 95.86 37.42 35.9-11.51 76.5-4.5 106.67 21.03l.11-.11c9.37-9.37 24.57-9.37 33.94 0l11.32 11.32c9.37 9.37 9.37 24.57 0 33.94zM384 208c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm48-16c8.837 0 16 7.163 16 16s-7.163 16-16 16-16-7.163-16-16 7.163-16 16-16zm80 16c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-160 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm32 0c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-128 32c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm96 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-96 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm64 0c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16zm-32 32c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16z"] }; +var faSignInAlt = { prefix: 'fas', iconName: 'sign-in-alt', icon: [512, 512, [], "f2f6", "M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"] }; +var faSignLanguage = { prefix: 'fas', iconName: 'sign-language', icon: [448, 512, [], "f2a7", "M91.434 483.987c-.307-16.018 13.109-29.129 29.13-29.129h62.293v-5.714H56.993c-16.021 0-29.437-13.111-29.13-29.129C28.16 404.491 40.835 392 56.428 392h126.429v-5.714H29.136c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h154.286v-5.714H57.707c-16.021 0-29.437-13.111-29.13-29.129.297-15.522 12.973-28.013 28.566-28.013h168.566l-31.085-22.606c-12.762-9.281-15.583-27.149-6.302-39.912 9.281-12.761 27.15-15.582 39.912-6.302l123.361 89.715a34.287 34.287 0 0 1 14.12 27.728v141.136c0 15.91-10.946 29.73-26.433 33.374l-80.471 18.934a137.16 137.16 0 0 1-31.411 3.646H120c-15.593-.001-28.269-12.492-28.566-28.014zm73.249-225.701h36.423l-11.187-8.136c-18.579-13.511-20.313-40.887-3.17-56.536l-13.004-16.7c-9.843-12.641-28.43-15.171-40.88-5.088-12.065 9.771-14.133 27.447-4.553 39.75l36.371 46.71zm283.298-2.103l-5.003-152.452c-.518-15.771-13.722-28.136-29.493-27.619-15.773.518-28.137 13.722-27.619 29.493l1.262 38.415L283.565 11.019c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l76.889 98.745-4.509 3.511-94.79-121.734c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l94.443 121.288-4.509 3.511-77.675-99.754c-9.58-12.303-27.223-14.63-39.653-5.328-12.827 9.599-14.929 28.24-5.086 40.881l52.053 66.849c12.497-8.257 29.055-8.285 41.69.904l123.36 89.714c10.904 7.93 17.415 20.715 17.415 34.198v16.999l61.064-47.549a34.285 34.285 0 0 0 13.202-28.177z"] }; +var faSignOutAlt = { prefix: 'fas', iconName: 'sign-out-alt', icon: [512, 512, [], "f2f5", "M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"] }; +var faSignal = { prefix: 'fas', iconName: 'signal', icon: [640, 512, [], "f012", "M36 384h56c6.6 0 12 5.4 12 12v104c0 6.6-5.4 12-12 12H36c-6.6 0-12-5.4-12-12V396c0-6.6 5.4-12 12-12zm116-36v152c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V348c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-80v232c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V268c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zm128-112v344c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V156c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12zM536 12v488c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12h-56c-6.6 0-12 5.4-12 12z"] }; +var faSitemap = { prefix: 'fas', iconName: 'sitemap', icon: [640, 512, [], "f0e8", "M616 320h-48v-48c0-22.056-17.944-40-40-40H344v-40h48c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h48v40H112c-22.056 0-40 17.944-40 40v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-48v-40h176v40h-48c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24z"] }; +var faSlidersH = { prefix: 'fas', iconName: 'sliders-h', icon: [576, 512, [], "f1de", "M576 80v40c0 6.6-5.4 12-12 12H160v8c0 13.3-10.7 24-24 24h-16c-13.3 0-24-10.7-24-24v-8H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h84v-8c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v8h404c6.6 0 12 5.4 12 12zm-12 148h-84v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h404v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12zm0 160H288v-8c0-13.3-10.7-24-24-24h-16c-13.3 0-24 10.7-24 24v8H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h212v8c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24v-8h276c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12z"] }; +var faSmile = { prefix: 'fas', iconName: 'smile', icon: [512, 512, [], "f118", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-122.526 75.34c11.479-17.755-15.349-35.194-26.873-17.374-53.418 82.627-143.71 82.681-197.164 0-11.502-17.79-38.364-.401-26.873 17.374 66.014 102.107 184.795 102.265 250.91 0zM108 192c0 37.497 30.503 68 68 68s68-30.503 68-68-30.503-68-68-68-68 30.503-68 68zm160.5 0c0 37.221 30.279 67.5 67.5 67.5s67.5-30.279 67.5-67.5-30.279-67.5-67.5-67.5-67.5 30.279-67.5 67.5zm67.5-48a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 288 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48zm-160 0a47.789 47.789 0 0 0-22.603 5.647h.015c10.916 0 19.765 8.849 19.765 19.765s-8.849 19.765-19.765 19.765-19.765-8.849-19.765-19.765v-.015A47.789 47.789 0 0 0 128 192c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48z"] }; +var faSnowflake = { prefix: 'fas', iconName: 'snowflake', icon: [448, 512, [], "f2dc", "M444.816 301.639a24.12 24.12 0 0 0 2.661-16.978c-2.725-12.966-15.339-21.245-28.174-18.492l-87.407 25.046L264 256l67.896-35.215 87.407 25.046c12.835 2.753 25.449-5.526 28.174-18.492 2.725-12.966-5.471-25.708-18.305-28.461l-47.477-7.137 53.077-30.956c11.363-6.627 15.257-21.306 8.696-32.785-6.561-11.479-21.091-15.412-32.454-8.785l-53.077 30.956 17.621-45.104c4.057-12.606-2.768-26.146-15.247-30.245-12.478-4.099-25.883 2.797-29.94 15.402l-22.232 88.99-60.38 35.215V144l65.175-63.945c8.778-9.852 7.987-25.027-1.766-33.894-9.753-8.867-24.775-8.068-33.552 1.784l-29.857 37.967V24c0-13.255-10.637-24-23.758-24s-23.758 10.745-23.758 24v61.912l-29.857-37.967c-8.779-9.852-23.799-10.652-33.552-1.784-9.753 8.867-10.543 24.042-1.766 33.894L200.242 144v70.431l-60.38-35.215-22.232-88.99c-4.057-12.605-17.462-19.501-29.94-15.402-12.478 4.099-19.304 17.64-15.247 30.245l17.62 45.104-53.077-30.956c-11.363-6.627-25.893-2.694-32.454 8.785s-2.667 26.157 8.696 32.785l53.077 30.956-47.477 7.137C5.993 201.634-2.203 214.375.523 227.341c2.725 12.965 15.339 21.245 28.174 18.492l87.407-25.046L184 256l-67.896 35.215-87.406-25.045c-12.835-2.753-25.449 5.526-28.174 18.492-2.725 12.967 5.47 25.708 18.305 28.461l47.477 7.137-53.077 30.956C1.866 357.843-2.027 372.521 4.533 384s21.091 15.412 32.454 8.785l53.077-30.956-17.62 45.104a24.157 24.157 0 0 0 2.022 19.428c2.831 4.953 7.416 8.909 13.224 10.816 12.478 4.099 25.883-2.797 29.94-15.402l22.232-88.99 60.38-35.215V368l-65.175 63.945c-8.778 9.852-7.987 25.027 1.766 33.894 9.754 8.868 24.774 8.068 33.552-1.784l29.857-37.967V488c0 13.255 10.637 24 23.758 24s23.758-10.745 23.758-24v-61.912l29.857 37.967A23.59 23.59 0 0 0 295.282 472a23.534 23.534 0 0 0 15.885-6.161c9.753-8.867 10.544-24.042 1.766-33.894L247.758 368v-70.431l60.38 35.215 22.232 88.99c4.057 12.605 17.462 19.501 29.94 15.402 12.479-4.099 19.304-17.64 15.247-30.245l-17.621-45.104 53.077 30.956c11.363 6.627 25.893 2.694 32.454-8.785s2.667-26.157-8.696-32.785l-53.077-30.956 47.477-7.137c6.86-1.469 12.394-5.793 15.645-11.481z"] }; +var faSort = { prefix: 'fas', iconName: 'sort', icon: [320, 512, [], "f0dc", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41zm255-105L177 64c-9.4-9.4-24.6-9.4-33.9 0L24 183c-15.1 15.1-4.4 41 17 41h238c21.4 0 32.1-25.9 17-41z"] }; +var faSortAlphaDown = { prefix: 'fas', iconName: 'sort-alpha-down', icon: [448, 512, [], "f15d", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zm119.075-180.007A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; +var faSortAlphaUp = { prefix: 'fas', iconName: 'sort-alpha-up', icon: [448, 512, [], "f15e", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zm301.671 98.621A12 12 0 0 1 294.838 224h-35.717c-8.22 0-14.007-8.078-11.362-15.861l57.096-168A12 12 0 0 1 316.217 32h39.566c5.139 0 9.708 3.273 11.362 8.139l57.096 168C426.886 215.922 421.1 224 412.879 224h-35.735a12 12 0 0 1-11.515-8.622l-8.301-28.299h-42.863l-8.092 28.228zm22.857-78.697h13.367l-6.6-22.937-6.767 22.937zm12.575 287.323l67.451-95.698a12 12 0 0 0 2.192-6.913V300c0-6.627-5.373-12-12-12H274.522c-6.627 0-12 5.373-12 12v28.93c0 6.627 5.373 12 12 12h56.469c-.739.991-1.497 2.036-2.27 3.133l-67.203 95.205a12.001 12.001 0 0 0-2.196 6.92V468c0 6.627 5.373 12 12 12h129.355c6.627 0 12-5.373 12-12v-28.93c0-6.627-5.373-12-12-12h-61.146c.74-.993 1.5-2.039 2.274-3.137z"] }; +var faSortAmountDown = { prefix: 'fas', iconName: 'sort-amount-down', icon: [512, 512, [], "f160", "M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; +var faSortAmountUp = { prefix: 'fas', iconName: 'sort-amount-up', icon: [512, 512, [], "f161", "M4.702 116.686l79.984-80.002c6.248-6.247 16.383-6.245 22.627 0l79.981 80.002c10.07 10.07 2.899 27.314-11.314 27.314H128v320c0 8.837-7.163 16-16 16H80c-8.837 0-16-7.163-16-16V144H16.016c-14.241 0-21.363-17.264-11.314-27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"] }; +var faSortDown = { prefix: 'fas', iconName: 'sort-down', icon: [320, 512, [], "f0dd", "M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z"] }; +var faSortNumericDown = { prefix: 'fas', iconName: 'sort-numeric-down', icon: [448, 512, [], "f162", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM175.984 368H128V48c0-8.837-7.163-16-16-16H80c-8.837 0-16 7.163-16 16v320H16.019c-14.212 0-21.384 17.244-11.314 27.314l79.981 80.002c6.245 6.245 16.38 6.247 22.627 0l79.984-80.002c10.05-10.05 2.928-27.314-11.313-27.314z"] }; +var faSortNumericUp = { prefix: 'fas', iconName: 'sort-numeric-up', icon: [448, 512, [], "f163", "M308.811 113.787l-19.448-20.795c-4.522-4.836-4.274-12.421.556-16.95l43.443-40.741a11.999 11.999 0 0 1 8.209-3.247h31.591c6.627 0 12 5.373 12 12v127.07h25.66c6.627 0 12 5.373 12 12v28.93c0 6.627-5.373 12-12 12H301.649c-6.627 0-12-5.373-12-12v-28.93c0-6.627 5.373-12 12-12h25.414v-57.938c-7.254 6.58-14.211 4.921-18.252.601zm-30.57 238.569c0-32.653 23.865-67.356 68.094-67.356 38.253 0 79.424 28.861 79.424 92.228 0 51.276-32.237 105.772-91.983 105.772-17.836 0-30.546-3.557-38.548-6.781-5.79-2.333-8.789-8.746-6.922-14.703l9.237-29.48c2.035-6.496 9.049-9.983 15.467-7.716 13.029 4.602 27.878 5.275 38.103-4.138-38.742 5.072-72.872-25.36-72.872-67.826zm92.273 19.338c0-22.285-15.302-36.505-25.835-36.505-8.642 0-13.164 7.965-13.164 15.832 0 5.669 1.815 24.168 25.168 24.168 9.973 0 13.377-2.154 13.744-2.731.021-.046.087-.291.087-.764zM16.016 144H64v320c0 8.837 7.163 16 16 16h32c8.837 0 16-7.163 16-16V144h47.981c14.212 0 21.384-17.244 11.314-27.314l-79.981-80.002c-6.245-6.245-16.38-6.247-22.627 0L4.702 116.686C-5.347 126.736 1.775 144 16.016 144z"] }; +var faSortUp = { prefix: 'fas', iconName: 'sort-up', icon: [320, 512, [], "f0de", "M279 224H41c-21.4 0-32.1-25.9-17-41L143 64c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z"] }; +var faSpaceShuttle = { prefix: 'fas', iconName: 'space-shuttle', icon: [640, 512, [], "f197", "M592.604 208.244C559.735 192.836 515.777 184 472 184H186.327c-4.952-6.555-10.585-11.978-16.72-16H376C229.157 137.747 219.403 32 96.003 32H96v128H80V32c-26.51 0-48 28.654-48 64v64c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v16c-23.197 0-32 10.032-32 24v40c0 13.983 8.819 24 32 24v64c0 35.346 21.49 64 48 64V352h16v128h.003c123.4 0 133.154-105.747 279.997-136H169.606c6.135-4.022 11.768-9.445 16.72-16H472c43.777 0 87.735-8.836 120.604-24.244C622.282 289.845 640 271.992 640 256s-17.718-33.845-47.396-47.756zM488 296a8 8 0 0 1-8-8v-64a8 8 0 0 1 8-8c31.909 0 31.942 80 0 80z"] }; +var faSpinner = { prefix: 'fas', iconName: 'spinner', icon: [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"] }; +var faSquare = { prefix: 'fas', iconName: 'square', icon: [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; +var faStar = { prefix: 'fas', iconName: 'star', icon: [576, 512, [], "f005", "M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"] }; +var faStarHalf = { prefix: 'fas', iconName: 'star-half', icon: [576, 512, [], "f089", "M288 0c-11.4 0-22.8 5.9-28.7 17.8L194 150.2 47.9 171.4c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.1 23 46 46.4 33.7L288 439.6V0z"] }; +var faStepBackward = { prefix: 'fas', iconName: 'step-backward', icon: [448, 512, [], "f048", "M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"] }; +var faStepForward = { prefix: 'fas', iconName: 'step-forward', icon: [448, 512, [], "f051", "M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"] }; +var faStethoscope = { prefix: 'fas', iconName: 'stethoscope', icon: [512, 512, [], "f0f1", "M512 176c0-35.659-29.164-64.507-64.941-63.993-34.21.492-62.296 28.357-63.043 62.562-.531 24.282 12.476 45.558 31.984 56.848V344c0 57.346-50.243 104-112 104-60.039 0-109.189-44.096-111.878-99.24C265.005 333.847 320 269.225 320 192V36.584c0-11.44-8.075-21.29-19.293-23.534L237.81.471c-12.997-2.599-25.641 5.83-28.241 18.827l-3.138 15.689c-2.6 12.997 5.83 25.641 18.827 28.241L256 69.376v121.4c0 52.852-42.203 96.707-95.053 97.22C107.58 288.513 64 245.25 64 192V69.376l30.742-6.149c12.997-2.6 21.427-15.243 18.827-28.241l-3.138-15.689C107.831 6.3 95.188-2.129 82.19.471L19.293 13.05C8.075 15.294 0 25.144 0 36.584V192c0 77.295 55.096 141.961 128.076 156.798C130.747 439.223 208.634 512 304 512c97.047 0 176-75.364 176-168V231.417c19.124-11.068 32-31.732 32-55.417zm-64-16c8.822 0 16 7.178 16 16s-7.178 16-16 16-16-7.178-16-16 7.178-16 16-16z"] }; +var faStickyNote = { prefix: 'fas', iconName: 'sticky-note', icon: [448, 512, [], "f249", "M312 320h136V56c0-13.3-10.7-24-24-24H24C10.7 32 0 42.7 0 56v400c0 13.3 10.7 24 24 24h264V344c0-13.2 10.8-24 24-24zm129 55l-98 98c-4.5 4.5-10.6 7-17 7h-6V352h128v6.1c0 6.3-2.5 12.4-7 16.9z"] }; +var faStop = { prefix: 'fas', iconName: 'stop', icon: [448, 512, [], "f04d", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"] }; +var faStopCircle = { prefix: 'fas', iconName: 'stop-circle', icon: [512, 512, [], "f28d", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm96 328c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v160z"] }; +var faStreetView = { prefix: 'fas', iconName: 'street-view', icon: [512, 512, [], "f21d", "M192 64c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zm112 80h-11.36c-22.711 10.443-49.59 10.894-73.28 0H208c-26.51 0-48 21.49-48 48v104c0 13.255 10.745 24 24 24h16v104c0 13.255 10.745 24 24 24h64c13.255 0 24-10.745 24-24V320h16c13.255 0 24-10.745 24-24V192c0-26.51-21.49-48-48-48zm85.642 189.152a72.503 72.503 0 0 1-29.01 27.009C391.133 365.251 480 385.854 480 416c0 46.304-167.656 64-224 64-70.303 0-224-20.859-224-64 0-30.123 88.361-50.665 119.367-55.839a72.516 72.516 0 0 1-29.01-27.009C74.959 343.395 0 367.599 0 416c0 77.111 178.658 96 256 96 77.249 0 256-18.865 256-96 0-48.403-74.967-72.606-122.358-82.848z"] }; +var faStrikethrough = { prefix: 'fas', iconName: 'strikethrough', icon: [512, 512, [], "f0cc", "M496 288H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h480c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16zm-214.666 16c27.258 12.937 46.524 28.683 46.524 56.243 0 33.108-28.977 53.676-75.621 53.676-32.325 0-76.874-12.08-76.874-44.271V368c0-8.837-7.164-16-16-16H113.75c-8.836 0-16 7.163-16 16v19.204c0 66.845 77.717 101.82 154.487 101.82 88.578 0 162.013-45.438 162.013-134.424 0-19.815-3.618-36.417-10.143-50.6H281.334zm-30.952-96c-32.422-13.505-56.836-28.946-56.836-59.683 0-33.92 30.901-47.406 64.962-47.406 42.647 0 64.962 16.593 64.962 32.985V136c0 8.837 7.164 16 16 16h45.613c8.836 0 16-7.163 16-16v-30.318c0-52.438-71.725-79.875-142.575-79.875-85.203 0-150.726 40.972-150.726 125.646 0 22.71 4.665 41.176 12.777 56.547h129.823z"] }; +var faSubscript = { prefix: 'fas', iconName: 'subscript', icon: [512, 512, [], "f12c", "M395.198 416c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 256c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 96H16C7.163 96 0 88.837 0 80V48c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035A15.999 15.999 0 0 1 204.226 32H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 256H272z"] }; +var faSubway = { prefix: 'fas', iconName: 'subway', icon: [448, 512, [], "f239", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zM200 232V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm200 0V120c0-13.255-10.745-24-24-24H272c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h104c13.255 0 24-10.745 24-24zm-48 56c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm-256 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; +var faSuitcase = { prefix: 'fas', iconName: 'suitcase', icon: [512, 512, [], "f0f2", "M96 480h320V128h-32V80c0-26.51-21.49-48-48-48H176c-26.51 0-48 21.49-48 48v48H96v352zm96-384h128v32H192V96zm320 80v256c0 26.51-21.49 48-48 48h-16V128h16c26.51 0 48 21.49 48 48zM64 480H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v352z"] }; +var faSun = { prefix: 'fas', iconName: 'sun', icon: [512, 512, [], "f185", "M274.835 12.646l25.516 62.393c4.213 10.301 16.671 14.349 26.134 8.492l57.316-35.479c15.49-9.588 34.808 4.447 30.475 22.142l-16.03 65.475c-2.647 10.81 5.053 21.408 16.152 22.231l67.224 4.987c18.167 1.348 25.546 24.057 11.641 35.826L441.81 242.26c-8.495 7.19-8.495 20.289 0 27.479l51.454 43.548c13.906 11.769 6.527 34.478-11.641 35.826l-67.224 4.987c-11.099.823-18.799 11.421-16.152 22.231l16.03 65.475c4.332 17.695-14.986 31.73-30.475 22.142l-57.316-35.479c-9.463-5.858-21.922-1.81-26.134 8.492l-25.516 62.393c-6.896 16.862-30.774 16.862-37.67 0l-25.516-62.393c-4.213-10.301-16.671-14.349-26.134-8.492l-57.317 35.479c-15.49 9.588-34.808-4.447-30.475-22.142l16.03-65.475c2.647-10.81-5.053-21.408-16.152-22.231l-67.224-4.987c-18.167-1.348-25.546-24.057-11.641-35.826L70.19 269.74c8.495-7.19 8.495-20.289 0-27.479l-51.454-43.548c-13.906-11.769-6.527-34.478 11.641-35.826l67.224-4.987c11.099-.823 18.799-11.421 16.152-22.231l-16.03-65.475c-4.332-17.695 14.986-31.73 30.475-22.142l57.317 35.479c9.463 5.858 21.921 1.81 26.134-8.492l25.516-62.393c6.896-16.861 30.774-16.861 37.67 0zM392 256c0-74.991-61.01-136-136-136-74.991 0-136 61.009-136 136s61.009 136 136 136c74.99 0 136-61.009 136-136zm-32 0c0 57.346-46.654 104-104 104s-104-46.654-104-104 46.654-104 104-104 104 46.654 104 104z"] }; +var faSuperscript = { prefix: 'fas', iconName: 'superscript', icon: [512, 512, [], "f12b", "M395.198 256c3.461-10.526 18.796-21.28 36.265-32.425 16.625-10.605 35.467-22.626 50.341-38.862 17.458-19.054 25.944-40.175 25.944-64.567 0-60.562-50.702-88.146-97.81-88.146-42.491 0-76.378 22.016-94.432 50.447-4.654 7.329-2.592 17.036 4.623 21.865l30.328 20.296c7.032 4.706 16.46 3.084 21.63-3.614 8.022-10.394 18.818-18.225 31.667-18.225 19.387 0 26.266 12.901 26.266 23.948 0 36.159-119.437 57.023-119.437 160.024 0 6.654.561 13.014 1.415 19.331 1.076 7.964 7.834 13.928 15.87 13.928H496c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16H395.198zM272 416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-62.399a16 16 0 0 1-13.541-7.478l-45.701-72.615c-2.297-3.352-4.422-6.969-6.195-10.209-1.65 3.244-3.647 6.937-5.874 10.582l-44.712 72.147a15.999 15.999 0 0 1-13.6 7.572H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h26.325l56.552-82.709L46.111 256H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h68.806a16 16 0 0 1 13.645 7.644l39.882 65.126c2.072 3.523 4.053 7.171 5.727 10.37 1.777-3.244 3.92-6.954 6.237-10.537l40.332-65.035a16 16 0 0 1 13.598-7.567H272c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-27.979l-52.69 75.671L249.974 416H272z"] }; +var faSync = { prefix: 'fas', iconName: 'sync', icon: [512, 512, [], "f021", "M440.935 12.574l3.966 82.766C399.416 41.904 331.674 8 256 8 134.813 8 33.933 94.924 12.296 209.824 10.908 217.193 16.604 224 24.103 224h49.084c5.57 0 10.377-3.842 11.676-9.259C103.407 137.408 172.931 80 256 80c60.893 0 114.512 30.856 146.104 77.801l-101.53-4.865c-6.845-.328-12.574 5.133-12.574 11.986v47.411c0 6.627 5.373 12 12 12h200.333c6.627 0 12-5.373 12-12V12c0-6.627-5.373-12-12-12h-47.411c-6.853 0-12.315 5.729-11.987 12.574zM256 432c-60.895 0-114.517-30.858-146.109-77.805l101.868 4.871c6.845.327 12.573-5.134 12.573-11.986v-47.412c0-6.627-5.373-12-12-12H12c-6.627 0-12 5.373-12 12V500c0 6.627 5.373 12 12 12h47.385c6.863 0 12.328-5.745 11.985-12.599l-4.129-82.575C112.725 470.166 180.405 504 256 504c121.187 0 222.067-86.924 243.704-201.824 1.388-7.369-4.308-14.176-11.807-14.176h-49.084c-5.57 0-10.377 3.842-11.676 9.259C408.593 374.592 339.069 432 256 432z"] }; +var faSyncAlt = { prefix: 'fas', iconName: 'sync-alt', icon: [512, 512, [], "f2f1", "M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z"] }; +var faTable = { prefix: 'fas', iconName: 'table', icon: [512, 512, [], "f0ce", "M464 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V80c0-26.51-21.49-48-48-48zM224 416H64v-96h160v96zm0-160H64v-96h160v96zm224 160H288v-96h160v96zm0-160H288v-96h160v96z"] }; +var faTablet = { prefix: 'fas', iconName: 'tablet', icon: [448, 512, [], "f10a", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"] }; +var faTabletAlt = { prefix: 'fas', iconName: 'tablet-alt', icon: [448, 512, [], "f3fa", "M400 0H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM224 480c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm176-108c0 6.6-5.4 12-12 12H60c-6.6 0-12-5.4-12-12V60c0-6.6 5.4-12 12-12h328c6.6 0 12 5.4 12 12v312z"] }; +var faTachometerAlt = { prefix: 'fas', iconName: 'tachometer-alt', icon: [576, 512, [], "f3fd", "M75.694 480a48.02 48.02 0 0 1-42.448-25.571C12.023 414.3 0 368.556 0 320 0 160.942 128.942 32 288 32s288 128.942 288 288c0 48.556-12.023 94.3-33.246 134.429A48.018 48.018 0 0 1 500.306 480H75.694zM512 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zM288 128c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32zM64 288c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm65.608-158.392c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm316.784 0c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32s32-14.327 32-32c0-17.673-14.327-32-32-32zm-87.078 31.534c-12.627-4.04-26.133 2.92-30.173 15.544l-45.923 143.511C250.108 322.645 224 350.264 224 384c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-19.773-8.971-37.447-23.061-49.187l45.919-143.498c4.039-12.625-2.92-26.133-15.544-30.173z"] }; +var faTag = { prefix: 'fas', iconName: 'tag', icon: [512, 512, [], "f02b", "M0 252.118V48C0 21.49 21.49 0 48 0h204.118a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.745 18.745-49.137 18.745-67.882 0L14.059 286.059A48 48 0 0 1 0 252.118zM112 64c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48z"] }; +var faTags = { prefix: 'fas', iconName: 'tags', icon: [640, 512, [], "f02c", "M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"] }; +var faTasks = { prefix: 'fas', iconName: 'tasks', icon: [512, 512, [], "f0ae", "M208 132h288c8.8 0 16-7.2 16-16V76c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zm0 160h288c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16zM64 368c-26.5 0-48.6 21.5-48.6 48s22.1 48 48.6 48 48-21.5 48-48-21.5-48-48-48zm92.5-299l-72.2 72.2-15.6 15.6c-4.7 4.7-12.9 4.7-17.6 0L3.5 109.4c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.3c4.7-4.7 12.3-4.7 17 0l17 16.5c4.6 4.7 4.6 12.3-.1 17zm0 159.6l-72.2 72.2-15.7 15.7c-4.7 4.7-12.9 4.7-17.6 0L3.5 269c-4.7-4.7-4.7-12.3 0-17l15.7-15.7c4.7-4.7 12.3-4.7 17 0l22.7 22.1 63.7-63.7c4.7-4.7 12.3-4.7 17 0l17 17c4.6 4.6 4.6 12.2-.1 16.9z"] }; +var faTaxi = { prefix: 'fas', iconName: 'taxi', icon: [512, 512, [], "f1ba", "M461.951 243.865l-21.816-87.268A79.885 79.885 0 0 0 362.522 96H352V56c0-13.255-10.745-24-24-24H184c-13.255 0-24 10.745-24 24v40h-10.522a79.885 79.885 0 0 0-77.612 60.597L50.05 243.865C25.515 252.823 8 276.366 8 304v48c0 20.207 9.374 38.214 24 49.943V456c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-40h256v40c0 13.255 10.745 24 24 24h48c13.255 0 24-10.745 24-24v-54.057c14.626-11.729 24-29.737 24-49.943v-48c0-27.634-17.515-51.177-42.049-60.135zM149.478 160h213.045a15.975 15.975 0 0 1 15.522 12.12l16.97 67.88h-278.03l16.97-67.881A15.976 15.976 0 0 1 149.478 160zM132 336c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36zm320 0c0 19.882-16.118 36-36 36s-36-16.118-36-36 16.118-36 36-36 36 16.118 36 36z"] }; +var faTerminal = { prefix: 'fas', iconName: 'terminal', icon: [640, 512, [], "f120", "M257.981 272.971L63.638 467.314c-9.373 9.373-24.569 9.373-33.941 0L7.029 444.647c-9.357-9.357-9.375-24.522-.04-33.901L161.011 256 6.99 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L257.981 239.03c9.373 9.372 9.373 24.568 0 33.941zM640 456v-32c0-13.255-10.745-24-24-24H312c-13.255 0-24 10.745-24 24v32c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24z"] }; +var faTextHeight = { prefix: 'fas', iconName: 'text-height', icon: [576, 512, [], "f034", "M16 32h288c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96h-54.761v320H232c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H88c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm475.308 4.685l79.995 80.001C581.309 126.693 574.297 144 559.99 144H512v224h48c15.639 0 20.635 17.991 11.313 27.314l-79.995 80.001c-6.247 6.247-16.381 6.245-22.626 0l-79.995-80.001C378.691 385.307 385.703 368 400.01 368H448V144h-48c-15.639 0-20.635-17.991-11.313-27.314l79.995-80.001c6.247-6.248 16.381-6.245 22.626 0z"] }; +var faTextWidth = { prefix: 'fas', iconName: 'text-width', icon: [448, 512, [], "f035", "M16 32h416c8.837 0 16 7.163 16 16v96c0 8.837-7.163 16-16 16h-35.496c-8.837 0-16-7.163-16-16V96H261.743v128H296c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H152c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16h34.257V96H67.496v48c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16V48c0-8.837 7.163-16 16-16zm427.315 340.682l-80.001-79.995C353.991 283.365 336 288.362 336 304v48H112v-47.99c0-14.307-17.307-21.319-27.314-11.313L4.685 372.692c-6.245 6.245-6.247 16.379 0 22.626l80.001 79.995C94.009 484.635 112 479.638 112 464v-48h224v47.99c0 14.307 17.307 21.319 27.314 11.313l80.001-79.995c6.245-6.245 6.248-16.379 0-22.626z"] }; +var faTh = { prefix: 'fas', iconName: 'th', icon: [512, 512, [], "f00a", "M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z"] }; +var faThLarge = { prefix: 'fas', iconName: 'th-large', icon: [512, 512, [], "f009", "M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z"] }; +var faThList = { prefix: 'fas', iconName: 'th-list', icon: [512, 512, [], "f00b", "M149.333 216v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-80c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zM125.333 32H24C10.745 32 0 42.745 0 56v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zm80 448H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm-24-424v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24zm24 264H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24z"] }; +var faThermometerEmpty = { prefix: 'fas', iconName: 'thermometer-empty', icon: [256, 512, [], "f2cb", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerFull = { prefix: 'fas', iconName: 'thermometer-full', icon: [256, 512, [], "f2c7", "M224 96c0-53.019-42.981-96-96-96S32 42.981 32 96v203.347C12.225 321.756.166 351.136.002 383.333c-.359 70.303 56.787 128.176 127.089 128.664.299.002.61.003.909.003 70.698 0 128-57.304 128-128 0-32.459-12.088-62.09-32-84.653V96zm-96 368l-.576-.002c-43.86-.304-79.647-36.544-79.423-80.42.173-33.98 19.266-51.652 31.999-66.08V96c0-26.467 21.533-48 48-48s48 21.533 48 48v221.498c12.63 14.312 32 32.164 32 66.502 0 44.112-35.888 80-80 80zm64-80c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V96c0-17.673 14.327-32 32-32s32 14.327 32 32v232.583c19.124 11.068 32 31.732 32 55.417z"] }; +var faThermometerHalf = { prefix: 'fas', iconName: 'thermometer-half', icon: [256, 512, [], "f2c9", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V224c0-17.673 14.327-32 32-32s32 14.327 32 32v104.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerQuarter = { prefix: 'fas', iconName: 'thermometer-quarter', icon: [256, 512, [], "f2ca", "M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-23.685 12.876-44.349 32-55.417V288c0-17.673 14.327-32 32-32s32 14.327 32 32v40.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThermometerThreeQuarters = { prefix: 'fas', iconName: 'thermometer-three-quarters', icon: [256, 512, [], "f2c8", "M192 384c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64 0-23.685 12.876-44.349 32-55.417V160c0-17.673 14.327-32 32-32s32 14.327 32 32v168.583c19.124 11.068 32 31.732 32 55.417zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z"] }; +var faThumbsDown = { prefix: 'fas', iconName: 'thumbs-down', icon: [512, 512, [], "f165", "M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z"] }; +var faThumbsUp = { prefix: 'fas', iconName: 'thumbs-up', icon: [512, 512, [], "f164", "M104 224H24c-13.255 0-24 10.745-24 24v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V248c0-13.255-10.745-24-24-24zM64 472c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zM384 81.452c0 42.416-25.97 66.208-33.277 94.548h101.723c33.397 0 59.397 27.746 59.553 58.098.084 17.938-7.546 37.249-19.439 49.197l-.11.11c9.836 23.337 8.237 56.037-9.308 79.469 8.681 25.895-.069 57.704-16.382 74.757 4.298 17.598 2.244 32.575-6.148 44.632C440.202 511.587 389.616 512 346.839 512l-2.845-.001c-48.287-.017-87.806-17.598-119.56-31.725-15.957-7.099-36.821-15.887-52.651-16.178-6.54-.12-11.783-5.457-11.783-11.998v-213.77c0-3.2 1.282-6.271 3.558-8.521 39.614-39.144 56.648-80.587 89.117-113.111 14.804-14.832 20.188-37.236 25.393-58.902C282.515 39.293 291.817 0 312 0c24 0 72 8 72 81.452z"] }; +var faThumbtack = { prefix: 'fas', iconName: 'thumbtack', icon: [384, 512, [], "f08d", "M298.028 214.267L285.793 96H328c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v48c0 13.255 10.745 24 24 24h42.207L85.972 214.267C37.465 236.82 0 277.261 0 328c0 13.255 10.745 24 24 24h136v104.007c0 1.242.289 2.467.845 3.578l24 48c2.941 5.882 11.364 5.893 14.311 0l24-48a8.008 8.008 0 0 0 .845-3.578V352h136c13.255 0 24-10.745 24-24-.001-51.183-37.983-91.42-85.973-113.733z"] }; +var faTicketAlt = { prefix: 'fas', iconName: 'ticket-alt', icon: [576, 512, [], "f3ff", "M128 160h320v192H128V160zm400 96c0 26.51 21.49 48 48 48v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96c26.51 0 48-21.49 48-48s-21.49-48-48-48v-96c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v96c-26.51 0-48 21.49-48 48zm-48-104c0-13.255-10.745-24-24-24H120c-13.255 0-24 10.745-24 24v208c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V152z"] }; +var faTimes = { prefix: 'fas', iconName: 'times', icon: [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"] }; +var faTimesCircle = { prefix: 'fas', iconName: 'times-circle', icon: [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"] }; +var faTint = { prefix: 'fas', iconName: 'tint', icon: [384, 512, [], "f043", "M192 512c-98.435 0-178.087-79.652-178.087-178.087 0-111.196 101.194-154.065 148.522-311.825 9.104-30.116 51.099-28.778 59.13 0 47.546 158.486 148.522 200.069 148.522 311.825C370.087 432.348 290.435 512 192 512zm-42.522-171.826c-1.509-5.533-9.447-5.532-10.956 0-9.223 29.425-27.913 37.645-27.913 58.435C110.609 417.13 125.478 432 144 432s33.391-14.87 33.391-33.391c0-20.839-18.673-28.956-27.913-58.435z"] }; +var faToggleOff = { prefix: 'fas', iconName: 'toggle-off', icon: [576, 512, [], "f204", "M384 64H192C85.961 64 0 149.961 0 256s85.961 192 192 192h192c106.039 0 192-85.961 192-192S490.039 64 384 64zM64 256c0-70.741 57.249-128 128-128 70.741 0 128 57.249 128 128 0 70.741-57.249 128-128 128-70.741 0-128-57.249-128-128zm320 128h-48.905c65.217-72.858 65.236-183.12 0-256H384c70.741 0 128 57.249 128 128 0 70.74-57.249 128-128 128z"] }; +var faToggleOn = { prefix: 'fas', iconName: 'toggle-on', icon: [576, 512, [], "f205", "M576 256c0 106.039-85.961 192-192 192H192C85.961 448 0 362.039 0 256S85.961 64 192 64h192c106.039 0 192 85.961 192 192zM384 128c-70.741 0-128 57.249-128 128 0 70.741 57.249 128 128 128 70.741 0 128-57.249 128-128 0-70.741-57.249-128-128-128"] }; +var faTrademark = { prefix: 'fas', iconName: 'trademark', icon: [640, 512, [], "f25c", "M97.119 163.133H12c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h248.559c6.627 0 12 5.373 12 12v43.133c0 6.627-5.373 12-12 12H175.44V404c0 6.627-5.373 12-12 12h-54.322c-6.627 0-12-5.373-12-12V163.133zM329.825 96h65.425a12 12 0 0 1 11.346 8.093l43.759 127.068c7.161 20.588 16.111 52.812 16.111 52.812h.896s8.95-32.224 16.111-52.812l43.758-127.068A12 12 0 0 1 538.577 96h65.41a12 12 0 0 1 11.961 11.03l24.012 296c.567 6.987-4.951 12.97-11.961 12.97h-54.101a12 12 0 0 1-11.972-11.182l-9.082-132.93c-1.79-24.168 0-53.706 0-53.706h-.896s-10.741 33.566-17.902 53.706l-30.7 84.731a12 12 0 0 1-11.282 7.912h-50.302a12 12 0 0 1-11.282-7.912l-30.7-84.731c-7.161-20.14-17.903-53.706-17.903-53.706h-.895s1.79 29.538 0 53.706l-9.082 132.93c-.428 6.295-5.66 11.182-11.97 11.182H305.4c-7.017 0-12.536-5.994-11.959-12.987l24.425-296A11.999 11.999 0 0 1 329.825 96z"] }; +var faTrain = { prefix: 'fas', iconName: 'train', icon: [448, 512, [], "f238", "M448 96v256c0 51.815-61.624 96-130.022 96l62.98 49.721C386.905 502.417 383.562 512 376 512H72c-7.578 0-10.892-9.594-4.957-14.279L130.022 448C61.82 448 0 403.954 0 352V96C0 42.981 64 0 128 0h192c65 0 128 42.981 128 96zm-48 136V120c0-13.255-10.745-24-24-24H72c-13.255 0-24 10.745-24 24v112c0 13.255 10.745 24 24 24h304c13.255 0 24-10.745 24-24zm-176 64c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56z"] }; +var faTransgender = { prefix: 'fas', iconName: 'transgender', icon: [384, 512, [], "f224", "M372 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C198.5 104.1 172.2 96 144 96 64.5 96 0 160.5 0 240c0 68.5 47.9 125.9 112 140.4V408H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM144 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faTransgenderAlt = { prefix: 'fas', iconName: 'transgender-alt', icon: [480, 512, [], "f225", "M468 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-80.7 80.7C294.5 104.1 268.2 96 240 96c-28.2 0-54.5 8.1-76.7 22.1l-16.5-16.5 19.8-19.8c4.7-4.7 4.7-12.3 0-17l-28.3-28.3c-4.7-4.7-12.3-4.7-17 0l-19.8 19.8-19-19 16.9-16.9C107.1 12.9 101.7 0 91 0H12C5.4 0 0 5.4 0 12v79c0 10.7 12.9 16 20.5 8.5l16.9-16.9 19 19-19.8 19.8c-4.7 4.7-4.7 12.3 0 17l28.3 28.3c4.7 4.7 12.3 4.7 17 0l19.8-19.8 16.5 16.5C104.1 185.5 96 211.8 96 240c0 68.5 47.9 125.9 112 140.4V408h-36c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v28c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-28h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-27.6c64.1-14.6 112-71.9 112-140.4 0-28.2-8.1-54.5-22.1-76.7l80.7-80.7 16.9 16.9c7.6 7.6 20.5 2.2 20.5-8.5V12c0-6.6-5.4-12-12-12zM240 320c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faTrash = { prefix: 'fas', iconName: 'trash', icon: [448, 512, [], "f1f8", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm415.2 56.7L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32.8 140.7c-.4-6.9 5.1-12.7 12-12.7h358.5c6.8 0 12.3 5.8 11.9 12.7z"] }; +var faTrashAlt = { prefix: 'fas', iconName: 'trash-alt', icon: [448, 512, [], "f2ed", "M0 84V56c0-13.3 10.7-24 24-24h112l9.4-18.7c4-8.2 12.3-13.3 21.4-13.3h114.3c9.1 0 17.4 5.1 21.5 13.3L312 32h112c13.3 0 24 10.7 24 24v28c0 6.6-5.4 12-12 12H12C5.4 96 0 90.6 0 84zm416 56v324c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V140c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12zm-272 68c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208zm96 0c0-8.8-7.2-16-16-16s-16 7.2-16 16v224c0 8.8 7.2 16 16 16s16-7.2 16-16V208z"] }; +var faTree = { prefix: 'fas', iconName: 'tree', icon: [384, 512, [], "f1bb", "M377.33 375.429L293.906 288H328c21.017 0 31.872-25.207 17.448-40.479L262.79 160H296c20.878 0 31.851-24.969 17.587-40.331l-104-112.003c-9.485-10.214-25.676-10.229-35.174 0l-104 112.003C56.206 134.969 67.037 160 88 160h33.21l-82.659 87.521C24.121 262.801 34.993 288 56 288h34.094L6.665 375.429C-7.869 390.655 2.925 416 24.025 416H144c0 32.781-11.188 49.26-33.995 67.506C98.225 492.93 104.914 512 120 512h144c15.086 0 21.776-19.069 9.995-28.494-19.768-15.814-33.992-31.665-33.995-67.496V416h119.97c21.05 0 31.929-25.309 17.36-40.571z"] }; +var faTrophy = { prefix: 'fas', iconName: 'trophy', icon: [576, 512, [], "f091", "M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"] }; +var faTruck = { prefix: 'fas', iconName: 'truck', icon: [640, 512, [], "f0d1", "M592 0H272c-26.51 0-48 21.49-48 48v48h-44.118a48 48 0 0 0-33.941 14.059l-99.882 99.882A48 48 0 0 0 32 243.882V352h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h40c0 53.019 42.981 96 96 96s96-42.981 96-96h128c0 53.019 42.981 96 96 96s96-42.981 96-96h40c13.255 0 24-10.745 24-24V48c0-26.51-21.49-48-48-48zM160 464c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48zm64-208H80v-12.118L179.882 144H224v112zm256 208c-26.467 0-48-21.533-48-48s21.533-48 48-48 48 21.533 48 48-21.533 48-48 48z"] }; +var faTty = { prefix: 'fas', iconName: 'tty', icon: [512, 512, [], "f1e4", "M5.37 103.822c138.532-138.532 362.936-138.326 501.262 0 6.078 6.078 7.074 15.496 2.583 22.681l-43.214 69.138a18.332 18.332 0 0 1-22.356 7.305l-86.422-34.569a18.335 18.335 0 0 1-11.434-18.846L351.741 90c-62.145-22.454-130.636-21.986-191.483 0l5.953 59.532a18.331 18.331 0 0 1-11.434 18.846l-86.423 34.568a18.334 18.334 0 0 1-22.356-7.305L2.787 126.502a18.333 18.333 0 0 1 2.583-22.68zM96 308v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H92c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zM96 500v-40c0-6.627-5.373-12-12-12H44c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H140c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z"] }; +var faTv = { prefix: 'fas', iconName: 'tv', icon: [640, 512, [], "f26c", "M592 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h245.1v32h-160c-17.7 0-32 14.3-32 32s14.3 32 32 32h384c17.7 0 32-14.3 32-32s-14.3-32-32-32h-160v-32H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h512v288z"] }; +var faUmbrella = { prefix: 'fas', iconName: 'umbrella', icon: [576, 512, [], "f0e9", "M557.011 267.631c-51.432-45.217-107.572-43.698-158.567 30.731-5.298 7.861-14.906 7.165-19.736 0-2.483-3.624-32.218-60.808-90.708-60.808-45.766 0-70.542 31.378-90.709 60.808-4.829 7.165-14.436 7.861-19.734 0-50.904-74.285-106.613-76.406-158.567-30.731-10.21 8.264-20.912-1.109-18.696-9.481C32.146 134.573 158.516 64.612 288.001 64.612c128.793 0 256.546 69.961 287.706 193.538 2.206 8.322-8.426 17.793-18.696 9.481zM256 261.001V416c0 17.645-14.355 32-32 32s-32-14.355-32-32c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 52.935 43.065 96 96 96s96-43.065 96-96V261.288c-21.836-10.806-45.425-9.737-64-.287zm64-211.007V32c0-17.673-14.327-32-32-32s-32 14.327-32 32v17.987a372.105 372.105 0 0 1 64 .007z"] }; +var faUnderline = { prefix: 'fas', iconName: 'underline', icon: [448, 512, [], "f0cd", "M224.264 388.24c-91.669 0-156.603-51.165-156.603-151.392V64H39.37c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h137.39c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.813v172.848c0 53.699 28.314 79.444 76.317 79.444 46.966 0 75.796-25.434 75.796-79.965V64h-28.291c-8.837 0-16-7.163-16-16V16c0-8.837 7.163-16 16-16h136.868c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-28.291v172.848c0 99.405-64.881 151.392-156.082 151.392zM16 448h416c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H16c-8.837 0-16-7.163-16-16v-32c0-8.837 7.163-16 16-16z"] }; +var faUndo = { prefix: 'fas', iconName: 'undo', icon: [512, 512, [], "f0e2", "M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z"] }; +var faUndoAlt = { prefix: 'fas', iconName: 'undo-alt', icon: [512, 512, [], "f2ea", "M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z"] }; +var faUniversalAccess = { prefix: 'fas', iconName: 'universal-access', icon: [512, 512, [], "f29a", "M256 48c114.953 0 208 93.029 208 208 0 114.953-93.029 208-208 208-114.953 0-208-93.029-208-208 0-114.953 93.029-208 208-208m0-40C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 56C149.961 64 64 149.961 64 256s85.961 192 192 192 192-85.961 192-192S362.039 64 256 64zm0 44c19.882 0 36 16.118 36 36s-16.118 36-36 36-36-16.118-36-36 16.118-36 36-36zm117.741 98.023c-28.712 6.779-55.511 12.748-82.14 15.807.851 101.023 12.306 123.052 25.037 155.621 3.617 9.26-.957 19.698-10.217 23.315-9.261 3.617-19.699-.957-23.316-10.217-8.705-22.308-17.086-40.636-22.261-78.549h-9.686c-5.167 37.851-13.534 56.208-22.262 78.549-3.615 9.255-14.05 13.836-23.315 10.217-9.26-3.617-13.834-14.056-10.217-23.315 12.713-32.541 24.185-54.541 25.037-155.621-26.629-3.058-53.428-9.027-82.141-15.807-8.6-2.031-13.926-10.648-11.895-19.249s10.647-13.926 19.249-11.895c96.686 22.829 124.283 22.783 220.775 0 8.599-2.03 17.218 3.294 19.249 11.895 2.029 8.601-3.297 17.219-11.897 19.249z"] }; +var faUniversity = { prefix: 'fas', iconName: 'university', icon: [512, 512, [], "f19c", "M480 128v16a8 8 0 0 1-8 8h-24v12c0 6.627-5.373 12-12 12H44c-6.627 0-12-5.373-12-12v-12H8a8 8 0 0 1-8-8v-16a8 8 0 0 1 4.941-7.392l232-88a7.996 7.996 0 0 1 6.118 0l232 88A8 8 0 0 1 480 128zm-24 304H24c-13.255 0-24 10.745-24 24v16a8 8 0 0 0 8 8h464a8 8 0 0 0 8-8v-16c0-13.255-10.745-24-24-24zM64 192v192H44c-6.627 0-12 5.373-12 12v20h416v-20c0-6.627-5.373-12-12-12h-20V192h-64v192h-32V192h-64v192h-32V192h-64v192h-32V192H64z"] }; +var faUnlink = { prefix: 'fas', iconName: 'unlink', icon: [512, 512, [], "f127", "M304.083 405.907c4.686 4.686 4.686 12.284 0 16.971l-44.674 44.674c-59.263 59.262-155.693 59.266-214.961 0-59.264-59.265-59.264-155.696 0-214.96l44.675-44.675c4.686-4.686 12.284-4.686 16.971 0l39.598 39.598c4.686 4.686 4.686 12.284 0 16.971l-44.675 44.674c-28.072 28.073-28.072 73.75 0 101.823 28.072 28.072 73.75 28.073 101.824 0l44.674-44.674c4.686-4.686 12.284-4.686 16.971 0l39.597 39.598zm-56.568-260.216c4.686 4.686 12.284 4.686 16.971 0l44.674-44.674c28.072-28.075 73.75-28.073 101.824 0 28.072 28.073 28.072 73.75 0 101.823l-44.675 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.598 39.598c4.686 4.686 12.284 4.686 16.971 0l44.675-44.675c59.265-59.265 59.265-155.695 0-214.96-59.266-59.264-155.695-59.264-214.961 0l-44.674 44.674c-4.686 4.686-4.686 12.284 0 16.971l39.597 39.598zm234.828 359.28l22.627-22.627c9.373-9.373 9.373-24.569 0-33.941L63.598 7.029c-9.373-9.373-24.569-9.373-33.941 0L7.029 29.657c-9.373 9.373-9.373 24.569 0 33.941l441.373 441.373c9.373 9.372 24.569 9.372 33.941 0z"] }; +var faUnlock = { prefix: 'fas', iconName: 'unlock', icon: [448, 512, [], "f09c", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"] }; +var faUnlockAlt = { prefix: 'fas', iconName: 'unlock-alt', icon: [448, 512, [], "f13e", "M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zM264 408c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48z"] }; +var faUpload = { prefix: 'fas', iconName: 'upload', icon: [512, 512, [], "f093", "M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"] }; +var faUser = { prefix: 'fas', iconName: 'user', icon: [512, 512, [], "f007", "M96 160C96 71.634 167.635 0 256 0s160 71.634 160 160-71.635 160-160 160S96 248.366 96 160zm304 192h-28.556c-71.006 42.713-159.912 42.695-230.888 0H112C50.144 352 0 402.144 0 464v24c0 13.255 10.745 24 24 24h464c13.255 0 24-10.745 24-24v-24c0-61.856-50.144-112-112-112z"] }; +var faUserCircle = { prefix: 'fas', iconName: 'user-circle', icon: [512, 512, [], "f2bd", "M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zM144 208c0-61.856 50.144-112 112-112s112 50.144 112 112-50.144 112-112 112-112-50.144-112-112zm268.408 172.663c-80.346 100.411-232.375 100.53-312.817 0C117.003 362.973 141.218 352 168 352h18.204c44.03 21.336 95.495 21.368 139.592 0H344c26.782 0 50.997 10.973 68.408 28.663z"] }; +var faUserMd = { prefix: 'fas', iconName: 'user-md', icon: [448, 512, [], "f0f0", "M96 128C96 57.308 153.308 0 224 0s128 57.308 128 128-57.308 128-128 128S96 198.692 96 128zm256 160v33.61c36.471 7.433 64 39.756 64 78.39v49.441c0 11.44-8.075 21.29-19.293 23.534l-21.802 4.361c-6.499 1.3-12.821-2.915-14.12-9.414l-1.569-7.845c-1.3-6.499 2.915-12.821 9.414-14.12l15.37-3.074v-42.078c0-26.283-20.793-48.297-47.071-48.797C310.039 351.498 288 373.224 288 400v42.883l15.371 3.074c6.499 1.3 10.713 7.622 9.414 14.12l-1.569 7.845c-1.3 6.499-7.622 10.714-14.12 9.414l-21.802-4.361C264.075 470.732 256 460.882 256 449.441V400c0-38.634 27.529-70.957 64-78.39V288h-22.624c-45.669 20.945-99.331 21.749-146.752 0H128v66.025c28.495 7.361 49.359 33.906 47.931 64.977-1.506 32.778-28.097 59.392-60.874 60.926C78.383 481.644 48 452.303 48 416c0-29.767 20.427-54.852 48-61.975V288c-53.019 0-96 42.981-96 96v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-53.019-42.981-96-96-96zM80 416c0 17.645 14.355 32 32 32s32-14.355 32-32-14.355-32-32-32-32 14.355-32 32z"] }; +var faUserPlus = { prefix: 'fas', iconName: 'user-plus', icon: [640, 512, [], "f234", "M616 332c0-6.627-5.373-12-12-12h-60v-60c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v60h-60c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h60v60c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12v-60h60c6.627 0 12-5.373 12-12v-40zM448 444v15c0 11.598-9.402 21-21 21H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350a98.09 98.09 0 0 1 26 3.493V372c0 24.262 19.738 44 44 44h25.519c2.768 12.064 2.481 20.659 2.481 28zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172z"] }; +var faUserSecret = { prefix: 'fas', iconName: 'user-secret', icon: [448, 512, [], "f21b", "M388.829 295.324l20.972-55.052c2.992-7.854-2.809-16.272-11.214-16.272H340.39c7.45-16.236 11.61-34.297 11.61-53.333 0-3.631-.16-7.224-.456-10.778C391.083 152.074 416 140.684 416 128c0-13.263-27.231-25.112-69.947-32.937-9.185-32.805-27.178-65.797-40.714-82.85-9.452-11.908-25.873-15.634-39.471-8.834l-27.557 13.779a31.997 31.997 0 0 1-28.622 0l-27.557-13.78c-13.599-6.799-30.02-3.074-39.471 8.834-13.536 17.053-31.529 50.045-40.714 82.85C59.231 102.888 32 114.737 32 128c0 12.684 24.917 24.074 64.456 31.889A129.362 129.362 0 0 0 96 170.667c0 19.037 4.159 37.098 11.608 53.333h-57.41c-8.615 0-14.423 8.809-11.029 16.727l22.906 53.447C25.799 307.882 0 342.925 0 384v104c0 13.255 10.745 24 24 24h400c13.255 0 24-10.745 24-24V384c0-39.97-24.43-74.231-59.171-88.676zM184 488l-48-192 48 24 24 40-24 128zm80 0l-24-128 24-40 48-24-48 192zm54.778-303.746c-.008.043-4.299 3.231-5.125 5.771-3.861 11.864-7.026 24.572-16.514 33.359-10.071 9.327-47.957 22.405-63.996-25.029-2.837-8.395-15.447-8.398-18.285 0-16.963 50.168-56.019 32.417-63.996 25.029-9.488-8.786-12.653-21.495-16.514-33.359-.826-2.54-5.118-5.728-5.125-5.771-.554-2.925-.981-5.884-1.22-8.85-.309-3.848 10.078-3.658 11.078-3.747 26.303-2.326 52.303-.579 78.023 5.497 2.563.606 11.553.529 13.793 0 25.72-6.076 51.72-7.824 78.023-5.497 1.002.089 11.387-.102 11.078 3.747-.239 2.966-.666 5.925-1.22 8.85z"] }; +var faUserTimes = { prefix: 'fas', iconName: 'user-times', icon: [640, 512, [], "f235", "M599.681 411.397c4.686-4.686 4.686-12.284 0-16.971L557.255 352l42.426-42.426c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.971 0L512 306.745l-42.426-42.426c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971L466.745 352l-42.426 42.426c-4.686 4.686-4.686 12.284 0 16.971l28.284 28.284c4.686 4.686 12.284 4.686 16.971 0L512 397.255l42.426 42.426c4.686 4.686 12.284 4.686 16.971 0l28.284-28.284zM84 172c0-77.32 62.68-140 140-140s140 62.68 140 140-62.68 140-140 140S84 249.32 84 172zm359.737 299.645C439.904 476.712 433.843 480 427 480H21c-11.598 0-21-9.402-21-21v-21c0-54.124 43.876-98 98-98h24.986c62.104 37.358 139.897 37.374 202.027 0H350c23.366 0 44.818 8.183 61.658 21.832l-9.967 9.967c-17.156 17.156-17.156 45.07 0 62.225l28.284 28.284a43.946 43.946 0 0 0 13.762 9.337z"] }; +var faUsers = { prefix: 'fas', iconName: 'users', icon: [640, 512, [], "f0c0", "M220 164c0-55.229 44.772-100 100-100s100 44.771 100 100-44.772 100-100 100-100-44.771-100-100zM48 208c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm384 0c0-44.183 35.817-80 80-80s80 35.817 80 80-35.817 80-80 80-80-35.817-80-80zm-22 76c38.66 0 70 31.34 70 70v70c0 13.255-10.745 24-24 24H184c-13.255 0-24-10.745-24-24v-70c0-38.66 31.34-70 70-70h17.848c44.364 26.687 99.93 26.693 144.305 0H410m-282 70c0-11.975 2.081-23.472 5.889-34.156-21.93 1.152-44.122-4.121-63.611-15.844H56c-30.928 0-56 25.072-56 56v32c0 13.255 10.745 24 24 24h104v-62zm456-50h-14.278c-19.495 11.727-41.686 16.996-63.611 15.844A101.542 101.542 0 0 1 512 354v62h104c13.255 0 24-10.745 24-24v-32c0-30.928-25.072-56-56-56z"] }; +var faUtensilSpoon = { prefix: 'fas', iconName: 'utensil-spoon', icon: [512, 512, [], "f2e5", "M480.1 31.9c-55-55.1-164.9-34.5-227.8 28.5-49.3 49.3-55.1 110-28.8 160.4L9 413.2c-11.6 10.5-12.1 28.5-1 39.5L59.3 504c11 11 29.1 10.5 39.5-1.1l192.4-214.4c50.4 26.3 111.1 20.5 160.4-28.8 63-62.9 83.6-172.8 28.5-227.8z"] }; +var faUtensils = { prefix: 'fas', iconName: 'utensils', icon: [416, 512, [], "f2e7", "M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z"] }; +var faVenus = { prefix: 'fas', iconName: 'venus', icon: [288, 512, [], "f221", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80z"] }; +var faVenusDouble = { prefix: 'fas', iconName: 'venus-double', icon: [512, 512, [], "f226", "M288 176c0-79.5-64.5-144-144-144S0 96.5 0 176c0 68.5 47.9 125.9 112 140.4V368H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.5 112-71.9 112-140.4zm-224 0c0-44.1 35.9-80 80-80s80 35.9 80 80-35.9 80-80 80-80-35.9-80-80zm336 140.4V368h36c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-36v36c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-36h-36c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h36v-51.6c-21.2-4.8-40.6-14.3-57.2-27.3 14-16.7 25-36 32.1-57.1 14.5 14.8 34.7 24 57.1 24 44.1 0 80-35.9 80-80s-35.9-80-80-80c-22.3 0-42.6 9.2-57.1 24-7.1-21.1-18-40.4-32.1-57.1C303.4 43.6 334.3 32 368 32c79.5 0 144 64.5 144 144 0 68.5-47.9 125.9-112 140.4z"] }; +var faVenusMars = { prefix: 'fas', iconName: 'venus-mars', icon: [576, 512, [], "f228", "M564 0h-79c-10.7 0-16 12.9-8.5 20.5l16.9 16.9-48.7 48.7C422.5 72.1 396.2 64 368 64c-33.7 0-64.6 11.6-89.2 30.9 14 16.7 25 36 32.1 57.1 14.5-14.8 34.7-24 57.1-24 44.1 0 80 35.9 80 80s-35.9 80-80 80c-22.3 0-42.6-9.2-57.1-24-7.1 21.1-18 40.4-32.1 57.1 24.5 19.4 55.5 30.9 89.2 30.9 79.5 0 144-64.5 144-144 0-28.2-8.1-54.5-22.1-76.7l48.7-48.7 16.9 16.9c2.4 2.4 5.4 3.5 8.4 3.5 6.2 0 12.1-4.8 12.1-12V12c0-6.6-5.4-12-12-12zM144 64C64.5 64 0 128.5 0 208c0 68.5 47.9 125.9 112 140.4V400H76c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h36v36c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12v-36h36c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-36v-51.6c64.1-14.6 112-71.9 112-140.4 0-79.5-64.5-144-144-144zm0 224c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] }; +var faVideo = { prefix: 'fas', iconName: 'video', icon: [576, 512, [], "f03d", "M528 64h-12.118a48 48 0 0 0-33.941 14.059L384 176v-64c0-26.51-21.49-48-48-48H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-64l97.941 97.941A48 48 0 0 0 515.882 448H528c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48z"] }; +var faVolumeDown = { prefix: 'fas', iconName: 'volume-down', icon: [384, 512, [], "f027", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zM384 256c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; +var faVolumeOff = { prefix: 'fas', iconName: 'volume-off', icon: [256, 512, [], "f026", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971z"] }; +var faVolumeUp = { prefix: 'fas', iconName: 'volume-up', icon: [576, 512, [], "f028", "M256 88.017v335.964c0 21.438-25.943 31.998-40.971 16.971L126.059 352H24c-13.255 0-24-10.745-24-24V184c0-13.255 10.745-24 24-24h102.059l88.971-88.954c15.01-15.01 40.97-4.49 40.97 16.971zm182.056-77.876C422.982.92 403.283 5.668 394.061 20.745c-9.221 15.077-4.473 34.774 10.604 43.995C468.967 104.063 512 174.983 512 256c0 73.431-36.077 142.292-96.507 184.206-14.522 10.072-18.129 30.01-8.057 44.532 10.076 14.528 30.016 18.126 44.531 8.057C529.633 438.927 576 350.406 576 256c0-103.244-54.579-194.877-137.944-245.859zM480 256c0-68.547-36.15-129.777-91.957-163.901-15.076-9.22-34.774-4.471-43.994 10.607-9.22 15.078-4.471 34.774 10.607 43.994C393.067 170.188 416 211.048 416 256c0 41.964-20.62 81.319-55.158 105.276-14.521 10.073-18.128 30.01-8.056 44.532 6.216 8.96 16.185 13.765 26.322 13.765a31.862 31.862 0 0 0 18.21-5.709C449.091 377.953 480 318.938 480 256zm-96 0c0-33.717-17.186-64.35-45.972-81.944-15.079-9.214-34.775-4.463-43.992 10.616s-4.464 34.775 10.615 43.992C314.263 234.538 320 244.757 320 256a32.056 32.056 0 0 1-13.802 26.332c-14.524 10.069-18.136 30.006-8.067 44.53 10.07 14.525 30.008 18.136 44.53 8.067C368.546 316.983 384 287.478 384 256z"] }; +var faWheelchair = { prefix: 'fas', iconName: 'wheelchair', icon: [512, 512, [], "f193", "M496.101 385.669l14.227 28.663c3.929 7.915.697 17.516-7.218 21.445l-65.465 32.886c-16.049 7.967-35.556 1.194-43.189-15.055L331.679 320H192c-15.925 0-29.426-11.71-31.679-27.475C126.433 55.308 128.38 70.044 128 64c0-36.358 30.318-65.635 67.052-63.929 33.271 1.545 60.048 28.905 60.925 62.201.868 32.933-23.152 60.423-54.608 65.039l4.67 32.69H336c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H215.182l4.572 32H352a32 32 0 0 1 28.962 18.392L438.477 396.8l36.178-18.349c7.915-3.929 17.517-.697 21.446 7.218zM311.358 352h-24.506c-7.788 54.204-54.528 96-110.852 96-61.757 0-112-50.243-112-112 0-41.505 22.694-77.809 56.324-97.156-3.712-25.965-6.844-47.86-9.488-66.333C45.956 198.464 0 261.963 0 336c0 97.047 78.953 176 176 176 71.87 0 133.806-43.308 161.11-105.192L311.358 352z"] }; +var faWifi = { prefix: 'fas', iconName: 'wifi', icon: [640, 512, [], "f1eb", "M384 416c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm136.659-124.443c6.465-6.465 6.245-17.065-.564-23.167-113.793-101.985-286.526-101.869-400.19 0-6.809 6.102-7.029 16.702-.564 23.167l34.006 34.006c5.927 5.927 15.464 6.32 21.769.796 82.88-72.609 207.074-72.447 289.768 0 6.305 5.524 15.842 5.132 21.769-.796l34.006-34.006zm112.11-113.718c6.385-6.385 6.254-16.816-.35-22.973-175.768-163.86-449.134-163.8-624.837 0-6.604 6.157-6.735 16.589-.35 22.973l33.966 33.966c6.095 6.095 15.891 6.231 22.224.383 144.763-133.668 368.356-133.702 513.156 0 6.333 5.848 16.129 5.712 22.224-.383l33.967-33.966z"] }; +var faWindowClose = { prefix: 'fas', iconName: 'window-close', icon: [512, 512, [], "f410", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-83.6 290.5c4.8 4.8 4.8 12.6 0 17.4l-40.5 40.5c-4.8 4.8-12.6 4.8-17.4 0L256 313.3l-66.5 67.1c-4.8 4.8-12.6 4.8-17.4 0l-40.5-40.5c-4.8-4.8-4.8-12.6 0-17.4l67.1-66.5-67.1-66.5c-4.8-4.8-4.8-12.6 0-17.4l40.5-40.5c4.8-4.8 12.6-4.8 17.4 0l66.5 67.1 66.5-67.1c4.8-4.8 12.6-4.8 17.4 0l40.5 40.5c4.8 4.8 4.8 12.6 0 17.4L313.3 256l67.1 66.5z"] }; +var faWindowMaximize = { prefix: 'fas', iconName: 'window-maximize', icon: [512, 512, [], "f2d0", "M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16 160H64v-84c0-6.6 5.4-12 12-12h360c6.6 0 12 5.4 12 12v84z"] }; +var faWindowMinimize = { prefix: 'fas', iconName: 'window-minimize', icon: [512, 512, [], "f2d1", "M464 352H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-32c0-26.5-21.5-48-48-48z"] }; +var faWindowRestore = { prefix: 'fas', iconName: 'window-restore', icon: [512, 512, [], "f2d2", "M512 48v288c0 26.5-21.5 48-48 48h-48V176c0-44.1-35.9-80-80-80H128V48c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zM384 176v288c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h288c26.5 0 48 21.5 48 48zm-68 28c0-6.6-5.4-12-12-12H76c-6.6 0-12 5.4-12 12v52h252v-52z"] }; +var faWonSign = { prefix: 'fas', iconName: 'won-sign', icon: [576, 512, [], "f159", "M564 192c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-48.028l18.572-80.61c1.732-7.518-3.978-14.694-11.693-14.694h-46.107a11.998 11.998 0 0 0-11.736 9.5L450.73 128H340.839l-19.725-85.987a12 12 0 0 0-11.696-9.317H265.43a12 12 0 0 0-11.687 9.277L233.696 128H124.975L107.5 42.299a12 12 0 0 0-11.758-9.602H53.628c-7.686 0-13.39 7.124-11.709 14.624L60 128H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h62.342l7.171 32H12c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h83.856l40.927 182.624A12 12 0 0 0 148.492 480h56.767c5.583 0 10.428-3.85 11.689-9.288L259.335 288h55.086l42.386 182.712A12 12 0 0 0 368.496 480h56.826a12 12 0 0 0 11.694-9.306L479.108 288H564c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12h-70.146l7.373-32H564zm-425.976 0h80.757l-7.457 32h-66.776l-6.524-32zm45.796 150.029c-6.194 25.831-6.758 47.25-7.321 47.25h-1.126s-1.689-22.05-6.758-47.25L157.599 288h38.812l-12.591 54.029zM274.182 224l1.996-8.602c1.856-7.962 3.457-15.968 4.803-23.398h11.794c1.347 7.43 2.947 15.436 4.803 23.398l1.996 8.602h-25.392zm130.959 118.029c-5.068 25.2-6.758 47.25-6.758 47.25h-1.126c-.563 0-1.126-21.42-7.321-47.25L377.542 288h39.107l-11.508 54.029zM430.281 224h-67.42l-7.34-32h81.577l-6.817 32z"] }; +var faWrench = { prefix: 'fas', iconName: 'wrench', icon: [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"] }; +var faYenSign = { prefix: 'fas', iconName: 'yen-sign', icon: [384, 512, [], "f157", "M351.208 32h-65.277a12 12 0 0 0-10.778 6.724l-55.39 113.163c-14.513 34.704-27.133 71.932-27.133 71.932h-1.262s-12.62-37.228-27.133-71.932l-55.39-113.163A11.997 11.997 0 0 0 98.068 32H32.792c-9.057 0-14.85 9.65-10.59 17.643L102.322 200H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h88.162L152 293.228V320H44c-6.627 0-12 5.373-12 12v32c0 6.627 5.373 12 12 12h108v92c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-92h108c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12H232v-26.772L251.838 256H340c6.627 0 12-5.373 12-12v-32c0-6.627-5.373-12-12-12h-58.322l80.12-150.357C366.058 41.65 360.266 32 351.208 32z"] }; +var icons$1 = { + faAddressBook: faAddressBook, + faAddressCard: faAddressCard, + faAdjust: faAdjust, + faAlignCenter: faAlignCenter, + faAlignJustify: faAlignJustify, + faAlignLeft: faAlignLeft, + faAlignRight: faAlignRight, + faAmbulance: faAmbulance, + faAmericanSignLanguageInterpreting: faAmericanSignLanguageInterpreting, + faAnchor: faAnchor, + faAngleDoubleDown: faAngleDoubleDown, + faAngleDoubleLeft: faAngleDoubleLeft, + faAngleDoubleRight: faAngleDoubleRight, + faAngleDoubleUp: faAngleDoubleUp, + faAngleDown: faAngleDown, + faAngleLeft: faAngleLeft, + faAngleRight: faAngleRight, + faAngleUp: faAngleUp, + faArchive: faArchive, + faArrowAltCircleDown: faArrowAltCircleDown, + faArrowAltCircleLeft: faArrowAltCircleLeft, + faArrowAltCircleRight: faArrowAltCircleRight, + faArrowAltCircleUp: faArrowAltCircleUp, + faArrowCircleDown: faArrowCircleDown, + faArrowCircleLeft: faArrowCircleLeft, + faArrowCircleRight: faArrowCircleRight, + faArrowCircleUp: faArrowCircleUp, + faArrowDown: faArrowDown, + faArrowLeft: faArrowLeft, + faArrowRight: faArrowRight, + faArrowUp: faArrowUp, + faArrowsAlt: faArrowsAlt, + faArrowsAltH: faArrowsAltH, + faArrowsAltV: faArrowsAltV, + faAssistiveListeningSystems: faAssistiveListeningSystems, + faAsterisk: faAsterisk, + faAt: faAt, + faAudioDescription: faAudioDescription, + faBackward: faBackward, + faBalanceScale: faBalanceScale, + faBan: faBan, + faBarcode: faBarcode, + faBars: faBars, + faBath: faBath, + faBatteryEmpty: faBatteryEmpty, + faBatteryFull: faBatteryFull, + faBatteryHalf: faBatteryHalf, + faBatteryQuarter: faBatteryQuarter, + faBatteryThreeQuarters: faBatteryThreeQuarters, + faBed: faBed, + faBeer: faBeer, + faBell: faBell, + faBellSlash: faBellSlash, + faBicycle: faBicycle, + faBinoculars: faBinoculars, + faBirthdayCake: faBirthdayCake, + faBlind: faBlind, + faBold: faBold, + faBolt: faBolt, + faBomb: faBomb, + faBook: faBook, + faBookmark: faBookmark, + faBraille: faBraille, + faBriefcase: faBriefcase, + faBug: faBug, + faBuilding: faBuilding, + faBullhorn: faBullhorn, + faBullseye: faBullseye, + faBus: faBus, + faCalculator: faCalculator, + faCalendar: faCalendar, + faCalendarAlt: faCalendarAlt, + faCalendarCheck: faCalendarCheck, + faCalendarMinus: faCalendarMinus, + faCalendarPlus: faCalendarPlus, + faCalendarTimes: faCalendarTimes, + faCamera: faCamera, + faCameraRetro: faCameraRetro, + faCar: faCar, + faCaretDown: faCaretDown, + faCaretLeft: faCaretLeft, + faCaretRight: faCaretRight, + faCaretSquareDown: faCaretSquareDown, + faCaretSquareLeft: faCaretSquareLeft, + faCaretSquareRight: faCaretSquareRight, + faCaretSquareUp: faCaretSquareUp, + faCaretUp: faCaretUp, + faCartArrowDown: faCartArrowDown, + faCartPlus: faCartPlus, + faCertificate: faCertificate, + faChartArea: faChartArea, + faChartBar: faChartBar, + faChartLine: faChartLine, + faChartPie: faChartPie, + faCheck: faCheck, + faCheckCircle: faCheckCircle, + faCheckSquare: faCheckSquare, + faChevronCircleDown: faChevronCircleDown, + faChevronCircleLeft: faChevronCircleLeft, + faChevronCircleRight: faChevronCircleRight, + faChevronCircleUp: faChevronCircleUp, + faChevronDown: faChevronDown, + faChevronLeft: faChevronLeft, + faChevronRight: faChevronRight, + faChevronUp: faChevronUp, + faChild: faChild, + faCircle: faCircle, + faCircleNotch: faCircleNotch, + faClipboard: faClipboard, + faClock: faClock, + faClone: faClone, + faClosedCaptioning: faClosedCaptioning, + faCloud: faCloud, + faCloudDownloadAlt: faCloudDownloadAlt, + faCloudUploadAlt: faCloudUploadAlt, + faCode: faCode, + faCodeBranch: faCodeBranch, + faCoffee: faCoffee, + faCog: faCog, + faCogs: faCogs, + faColumns: faColumns, + faComment: faComment, + faCommentAlt: faCommentAlt, + faComments: faComments, + faCompass: faCompass, + faCompress: faCompress, + faCopy: faCopy, + faCopyright: faCopyright, + faCreditCard: faCreditCard, + faCrop: faCrop, + faCrosshairs: faCrosshairs, + faCube: faCube, + faCubes: faCubes, + faCut: faCut, + faDatabase: faDatabase, + faDeaf: faDeaf, + faDesktop: faDesktop, + faDollarSign: faDollarSign, + faDotCircle: faDotCircle, + faDownload: faDownload, + faEdit: faEdit, + faEject: faEject, + faEllipsisH: faEllipsisH, + faEllipsisV: faEllipsisV, + faEnvelope: faEnvelope, + faEnvelopeOpen: faEnvelopeOpen, + faEnvelopeSquare: faEnvelopeSquare, + faEraser: faEraser, + faEuroSign: faEuroSign, + faExchangeAlt: faExchangeAlt, + faExclamation: faExclamation, + faExclamationCircle: faExclamationCircle, + faExclamationTriangle: faExclamationTriangle, + faExpand: faExpand, + faExpandArrowsAlt: faExpandArrowsAlt, + faExternalLinkAlt: faExternalLinkAlt, + faExternalLinkSquareAlt: faExternalLinkSquareAlt, + faEye: faEye, + faEyeDropper: faEyeDropper, + faEyeSlash: faEyeSlash, + faFastBackward: faFastBackward, + faFastForward: faFastForward, + faFax: faFax, + faFemale: faFemale, + faFighterJet: faFighterJet, + faFile: faFile, + faFileAlt: faFileAlt, + faFileArchive: faFileArchive, + faFileAudio: faFileAudio, + faFileCode: faFileCode, + faFileExcel: faFileExcel, + faFileImage: faFileImage, + faFilePdf: faFilePdf, + faFilePowerpoint: faFilePowerpoint, + faFileVideo: faFileVideo, + faFileWord: faFileWord, + faFilm: faFilm, + faFilter: faFilter, + faFire: faFire, + faFireExtinguisher: faFireExtinguisher, + faFlag: faFlag, + faFlagCheckered: faFlagCheckered, + faFlask: faFlask, + faFolder: faFolder, + faFolderOpen: faFolderOpen, + faFont: faFont, + faForward: faForward, + faFrown: faFrown, + faFutbol: faFutbol, + faGamepad: faGamepad, + faGavel: faGavel, + faGem: faGem, + faGenderless: faGenderless, + faGift: faGift, + faGlassMartini: faGlassMartini, + faGlobe: faGlobe, + faGraduationCap: faGraduationCap, + faHSquare: faHSquare, + faHandLizard: faHandLizard, + faHandPaper: faHandPaper, + faHandPeace: faHandPeace, + faHandPointDown: faHandPointDown, + faHandPointLeft: faHandPointLeft, + faHandPointRight: faHandPointRight, + faHandPointUp: faHandPointUp, + faHandPointer: faHandPointer, + faHandRock: faHandRock, + faHandScissors: faHandScissors, + faHandSpock: faHandSpock, + faHandshake: faHandshake, + faHashtag: faHashtag, + faHdd: faHdd, + faHeading: faHeading, + faHeadphones: faHeadphones, + faHeart: faHeart, + faHeartbeat: faHeartbeat, + faHistory: faHistory, + faHome: faHome, + faHospital: faHospital, + faHourglass: faHourglass, + faHourglassEnd: faHourglassEnd, + faHourglassHalf: faHourglassHalf, + faHourglassStart: faHourglassStart, + faICursor: faICursor, + faIdBadge: faIdBadge, + faIdCard: faIdCard, + faImage: faImage, + faImages: faImages, + faInbox: faInbox, + faIndent: faIndent, + faIndustry: faIndustry, + faInfo: faInfo, + faInfoCircle: faInfoCircle, + faItalic: faItalic, + faKey: faKey, + faKeyboard: faKeyboard, + faLanguage: faLanguage, + faLaptop: faLaptop, + faLeaf: faLeaf, + faLemon: faLemon, + faLevelDownAlt: faLevelDownAlt, + faLevelUpAlt: faLevelUpAlt, + faLifeRing: faLifeRing, + faLightbulb: faLightbulb, + faLink: faLink, + faLiraSign: faLiraSign, + faList: faList, + faListAlt: faListAlt, + faListOl: faListOl, + faListUl: faListUl, + faLocationArrow: faLocationArrow, + faLock: faLock, + faLockOpen: faLockOpen, + faLongArrowAltDown: faLongArrowAltDown, + faLongArrowAltLeft: faLongArrowAltLeft, + faLongArrowAltRight: faLongArrowAltRight, + faLongArrowAltUp: faLongArrowAltUp, + faLowVision: faLowVision, + faMagic: faMagic, + faMagnet: faMagnet, + faMale: faMale, + faMap: faMap, + faMapMarker: faMapMarker, + faMapMarkerAlt: faMapMarkerAlt, + faMapPin: faMapPin, + faMapSigns: faMapSigns, + faMars: faMars, + faMarsDouble: faMarsDouble, + faMarsStroke: faMarsStroke, + faMarsStrokeH: faMarsStrokeH, + faMarsStrokeV: faMarsStrokeV, + faMedkit: faMedkit, + faMeh: faMeh, + faMercury: faMercury, + faMicrochip: faMicrochip, + faMicrophone: faMicrophone, + faMicrophoneSlash: faMicrophoneSlash, + faMinus: faMinus, + faMinusCircle: faMinusCircle, + faMinusSquare: faMinusSquare, + faMobile: faMobile, + faMobileAlt: faMobileAlt, + faMoneyBillAlt: faMoneyBillAlt, + faMoon: faMoon, + faMotorcycle: faMotorcycle, + faMousePointer: faMousePointer, + faMusic: faMusic, + faNeuter: faNeuter, + faNewspaper: faNewspaper, + faObjectGroup: faObjectGroup, + faObjectUngroup: faObjectUngroup, + faOutdent: faOutdent, + faPaintBrush: faPaintBrush, + faPaperPlane: faPaperPlane, + faPaperclip: faPaperclip, + faParagraph: faParagraph, + faPaste: faPaste, + faPause: faPause, + faPauseCircle: faPauseCircle, + faPaw: faPaw, + faPenSquare: faPenSquare, + faPencilAlt: faPencilAlt, + faPercent: faPercent, + faPhone: faPhone, + faPhoneSquare: faPhoneSquare, + faPhoneVolume: faPhoneVolume, + faPlane: faPlane, + faPlay: faPlay, + faPlayCircle: faPlayCircle, + faPlug: faPlug, + faPlus: faPlus, + faPlusCircle: faPlusCircle, + faPlusSquare: faPlusSquare, + faPodcast: faPodcast, + faPoundSign: faPoundSign, + faPowerOff: faPowerOff, + faPrint: faPrint, + faPuzzlePiece: faPuzzlePiece, + faQrcode: faQrcode, + faQuestion: faQuestion, + faQuestionCircle: faQuestionCircle, + faQuoteLeft: faQuoteLeft, + faQuoteRight: faQuoteRight, + faRandom: faRandom, + faRecycle: faRecycle, + faRedo: faRedo, + faRedoAlt: faRedoAlt, + faRegistered: faRegistered, + faReply: faReply, + faReplyAll: faReplyAll, + faRetweet: faRetweet, + faRoad: faRoad, + faRocket: faRocket, + faRss: faRss, + faRssSquare: faRssSquare, + faRubleSign: faRubleSign, + faRupeeSign: faRupeeSign, + faSave: faSave, + faSearch: faSearch, + faSearchMinus: faSearchMinus, + faSearchPlus: faSearchPlus, + faServer: faServer, + faShare: faShare, + faShareAlt: faShareAlt, + faShareAltSquare: faShareAltSquare, + faShareSquare: faShareSquare, + faShekelSign: faShekelSign, + faShieldAlt: faShieldAlt, + faShip: faShip, + faShoppingBag: faShoppingBag, + faShoppingBasket: faShoppingBasket, + faShoppingCart: faShoppingCart, + faShower: faShower, + faSignInAlt: faSignInAlt, + faSignLanguage: faSignLanguage, + faSignOutAlt: faSignOutAlt, + faSignal: faSignal, + faSitemap: faSitemap, + faSlidersH: faSlidersH, + faSmile: faSmile, + faSnowflake: faSnowflake, + faSort: faSort, + faSortAlphaDown: faSortAlphaDown, + faSortAlphaUp: faSortAlphaUp, + faSortAmountDown: faSortAmountDown, + faSortAmountUp: faSortAmountUp, + faSortDown: faSortDown, + faSortNumericDown: faSortNumericDown, + faSortNumericUp: faSortNumericUp, + faSortUp: faSortUp, + faSpaceShuttle: faSpaceShuttle, + faSpinner: faSpinner, + faSquare: faSquare, + faStar: faStar, + faStarHalf: faStarHalf, + faStepBackward: faStepBackward, + faStepForward: faStepForward, + faStethoscope: faStethoscope, + faStickyNote: faStickyNote, + faStop: faStop, + faStopCircle: faStopCircle, + faStreetView: faStreetView, + faStrikethrough: faStrikethrough, + faSubscript: faSubscript, + faSubway: faSubway, + faSuitcase: faSuitcase, + faSun: faSun, + faSuperscript: faSuperscript, + faSync: faSync, + faSyncAlt: faSyncAlt, + faTable: faTable, + faTablet: faTablet, + faTabletAlt: faTabletAlt, + faTachometerAlt: faTachometerAlt, + faTag: faTag, + faTags: faTags, + faTasks: faTasks, + faTaxi: faTaxi, + faTerminal: faTerminal, + faTextHeight: faTextHeight, + faTextWidth: faTextWidth, + faTh: faTh, + faThLarge: faThLarge, + faThList: faThList, + faThermometerEmpty: faThermometerEmpty, + faThermometerFull: faThermometerFull, + faThermometerHalf: faThermometerHalf, + faThermometerQuarter: faThermometerQuarter, + faThermometerThreeQuarters: faThermometerThreeQuarters, + faThumbsDown: faThumbsDown, + faThumbsUp: faThumbsUp, + faThumbtack: faThumbtack, + faTicketAlt: faTicketAlt, + faTimes: faTimes, + faTimesCircle: faTimesCircle, + faTint: faTint, + faToggleOff: faToggleOff, + faToggleOn: faToggleOn, + faTrademark: faTrademark, + faTrain: faTrain, + faTransgender: faTransgender, + faTransgenderAlt: faTransgenderAlt, + faTrash: faTrash, + faTrashAlt: faTrashAlt, + faTree: faTree, + faTrophy: faTrophy, + faTruck: faTruck, + faTty: faTty, + faTv: faTv, + faUmbrella: faUmbrella, + faUnderline: faUnderline, + faUndo: faUndo, + faUndoAlt: faUndoAlt, + faUniversalAccess: faUniversalAccess, + faUniversity: faUniversity, + faUnlink: faUnlink, + faUnlock: faUnlock, + faUnlockAlt: faUnlockAlt, + faUpload: faUpload, + faUser: faUser, + faUserCircle: faUserCircle, + faUserMd: faUserMd, + faUserPlus: faUserPlus, + faUserSecret: faUserSecret, + faUserTimes: faUserTimes, + faUsers: faUsers, + faUtensilSpoon: faUtensilSpoon, + faUtensils: faUtensils, + faVenus: faVenus, + faVenusDouble: faVenusDouble, + faVenusMars: faVenusMars, + faVideo: faVideo, + faVolumeDown: faVolumeDown, + faVolumeOff: faVolumeOff, + faVolumeUp: faVolumeUp, + faWheelchair: faWheelchair, + faWifi: faWifi, + faWindowClose: faWindowClose, + faWindowMaximize: faWindowMaximize, + faWindowMinimize: faWindowMinimize, + faWindowRestore: faWindowRestore, + faWonSign: faWonSign, + faWrench: faWrench, + faYenSign: faYenSign +}; + +exports['default'] = icons$1; +exports.prefix = prefix; +exports.faAddressBook = faAddressBook; +exports.faAddressCard = faAddressCard; +exports.faAdjust = faAdjust; +exports.faAlignCenter = faAlignCenter; +exports.faAlignJustify = faAlignJustify; +exports.faAlignLeft = faAlignLeft; +exports.faAlignRight = faAlignRight; +exports.faAmbulance = faAmbulance; +exports.faAmericanSignLanguageInterpreting = faAmericanSignLanguageInterpreting; +exports.faAnchor = faAnchor; +exports.faAngleDoubleDown = faAngleDoubleDown; +exports.faAngleDoubleLeft = faAngleDoubleLeft; +exports.faAngleDoubleRight = faAngleDoubleRight; +exports.faAngleDoubleUp = faAngleDoubleUp; +exports.faAngleDown = faAngleDown; +exports.faAngleLeft = faAngleLeft; +exports.faAngleRight = faAngleRight; +exports.faAngleUp = faAngleUp; +exports.faArchive = faArchive; +exports.faArrowAltCircleDown = faArrowAltCircleDown; +exports.faArrowAltCircleLeft = faArrowAltCircleLeft; +exports.faArrowAltCircleRight = faArrowAltCircleRight; +exports.faArrowAltCircleUp = faArrowAltCircleUp; +exports.faArrowCircleDown = faArrowCircleDown; +exports.faArrowCircleLeft = faArrowCircleLeft; +exports.faArrowCircleRight = faArrowCircleRight; +exports.faArrowCircleUp = faArrowCircleUp; +exports.faArrowDown = faArrowDown; +exports.faArrowLeft = faArrowLeft; +exports.faArrowRight = faArrowRight; +exports.faArrowUp = faArrowUp; +exports.faArrowsAlt = faArrowsAlt; +exports.faArrowsAltH = faArrowsAltH; +exports.faArrowsAltV = faArrowsAltV; +exports.faAssistiveListeningSystems = faAssistiveListeningSystems; +exports.faAsterisk = faAsterisk; +exports.faAt = faAt; +exports.faAudioDescription = faAudioDescription; +exports.faBackward = faBackward; +exports.faBalanceScale = faBalanceScale; +exports.faBan = faBan; +exports.faBarcode = faBarcode; +exports.faBars = faBars; +exports.faBath = faBath; +exports.faBatteryEmpty = faBatteryEmpty; +exports.faBatteryFull = faBatteryFull; +exports.faBatteryHalf = faBatteryHalf; +exports.faBatteryQuarter = faBatteryQuarter; +exports.faBatteryThreeQuarters = faBatteryThreeQuarters; +exports.faBed = faBed; +exports.faBeer = faBeer; +exports.faBell = faBell; +exports.faBellSlash = faBellSlash; +exports.faBicycle = faBicycle; +exports.faBinoculars = faBinoculars; +exports.faBirthdayCake = faBirthdayCake; +exports.faBlind = faBlind; +exports.faBold = faBold; +exports.faBolt = faBolt; +exports.faBomb = faBomb; +exports.faBook = faBook; +exports.faBookmark = faBookmark; +exports.faBraille = faBraille; +exports.faBriefcase = faBriefcase; +exports.faBug = faBug; +exports.faBuilding = faBuilding; +exports.faBullhorn = faBullhorn; +exports.faBullseye = faBullseye; +exports.faBus = faBus; +exports.faCalculator = faCalculator; +exports.faCalendar = faCalendar; +exports.faCalendarAlt = faCalendarAlt; +exports.faCalendarCheck = faCalendarCheck; +exports.faCalendarMinus = faCalendarMinus; +exports.faCalendarPlus = faCalendarPlus; +exports.faCalendarTimes = faCalendarTimes; +exports.faCamera = faCamera; +exports.faCameraRetro = faCameraRetro; +exports.faCar = faCar; +exports.faCaretDown = faCaretDown; +exports.faCaretLeft = faCaretLeft; +exports.faCaretRight = faCaretRight; +exports.faCaretSquareDown = faCaretSquareDown; +exports.faCaretSquareLeft = faCaretSquareLeft; +exports.faCaretSquareRight = faCaretSquareRight; +exports.faCaretSquareUp = faCaretSquareUp; +exports.faCaretUp = faCaretUp; +exports.faCartArrowDown = faCartArrowDown; +exports.faCartPlus = faCartPlus; +exports.faCertificate = faCertificate; +exports.faChartArea = faChartArea; +exports.faChartBar = faChartBar; +exports.faChartLine = faChartLine; +exports.faChartPie = faChartPie; +exports.faCheck = faCheck; +exports.faCheckCircle = faCheckCircle; +exports.faCheckSquare = faCheckSquare; +exports.faChevronCircleDown = faChevronCircleDown; +exports.faChevronCircleLeft = faChevronCircleLeft; +exports.faChevronCircleRight = faChevronCircleRight; +exports.faChevronCircleUp = faChevronCircleUp; +exports.faChevronDown = faChevronDown; +exports.faChevronLeft = faChevronLeft; +exports.faChevronRight = faChevronRight; +exports.faChevronUp = faChevronUp; +exports.faChild = faChild; +exports.faCircle = faCircle; +exports.faCircleNotch = faCircleNotch; +exports.faClipboard = faClipboard; +exports.faClock = faClock; +exports.faClone = faClone; +exports.faClosedCaptioning = faClosedCaptioning; +exports.faCloud = faCloud; +exports.faCloudDownloadAlt = faCloudDownloadAlt; +exports.faCloudUploadAlt = faCloudUploadAlt; +exports.faCode = faCode; +exports.faCodeBranch = faCodeBranch; +exports.faCoffee = faCoffee; +exports.faCog = faCog; +exports.faCogs = faCogs; +exports.faColumns = faColumns; +exports.faComment = faComment; +exports.faCommentAlt = faCommentAlt; +exports.faComments = faComments; +exports.faCompass = faCompass; +exports.faCompress = faCompress; +exports.faCopy = faCopy; +exports.faCopyright = faCopyright; +exports.faCreditCard = faCreditCard; +exports.faCrop = faCrop; +exports.faCrosshairs = faCrosshairs; +exports.faCube = faCube; +exports.faCubes = faCubes; +exports.faCut = faCut; +exports.faDatabase = faDatabase; +exports.faDeaf = faDeaf; +exports.faDesktop = faDesktop; +exports.faDollarSign = faDollarSign; +exports.faDotCircle = faDotCircle; +exports.faDownload = faDownload; +exports.faEdit = faEdit; +exports.faEject = faEject; +exports.faEllipsisH = faEllipsisH; +exports.faEllipsisV = faEllipsisV; +exports.faEnvelope = faEnvelope; +exports.faEnvelopeOpen = faEnvelopeOpen; +exports.faEnvelopeSquare = faEnvelopeSquare; +exports.faEraser = faEraser; +exports.faEuroSign = faEuroSign; +exports.faExchangeAlt = faExchangeAlt; +exports.faExclamation = faExclamation; +exports.faExclamationCircle = faExclamationCircle; +exports.faExclamationTriangle = faExclamationTriangle; +exports.faExpand = faExpand; +exports.faExpandArrowsAlt = faExpandArrowsAlt; +exports.faExternalLinkAlt = faExternalLinkAlt; +exports.faExternalLinkSquareAlt = faExternalLinkSquareAlt; +exports.faEye = faEye; +exports.faEyeDropper = faEyeDropper; +exports.faEyeSlash = faEyeSlash; +exports.faFastBackward = faFastBackward; +exports.faFastForward = faFastForward; +exports.faFax = faFax; +exports.faFemale = faFemale; +exports.faFighterJet = faFighterJet; +exports.faFile = faFile; +exports.faFileAlt = faFileAlt; +exports.faFileArchive = faFileArchive; +exports.faFileAudio = faFileAudio; +exports.faFileCode = faFileCode; +exports.faFileExcel = faFileExcel; +exports.faFileImage = faFileImage; +exports.faFilePdf = faFilePdf; +exports.faFilePowerpoint = faFilePowerpoint; +exports.faFileVideo = faFileVideo; +exports.faFileWord = faFileWord; +exports.faFilm = faFilm; +exports.faFilter = faFilter; +exports.faFire = faFire; +exports.faFireExtinguisher = faFireExtinguisher; +exports.faFlag = faFlag; +exports.faFlagCheckered = faFlagCheckered; +exports.faFlask = faFlask; +exports.faFolder = faFolder; +exports.faFolderOpen = faFolderOpen; +exports.faFont = faFont; +exports.faForward = faForward; +exports.faFrown = faFrown; +exports.faFutbol = faFutbol; +exports.faGamepad = faGamepad; +exports.faGavel = faGavel; +exports.faGem = faGem; +exports.faGenderless = faGenderless; +exports.faGift = faGift; +exports.faGlassMartini = faGlassMartini; +exports.faGlobe = faGlobe; +exports.faGraduationCap = faGraduationCap; +exports.faHSquare = faHSquare; +exports.faHandLizard = faHandLizard; +exports.faHandPaper = faHandPaper; +exports.faHandPeace = faHandPeace; +exports.faHandPointDown = faHandPointDown; +exports.faHandPointLeft = faHandPointLeft; +exports.faHandPointRight = faHandPointRight; +exports.faHandPointUp = faHandPointUp; +exports.faHandPointer = faHandPointer; +exports.faHandRock = faHandRock; +exports.faHandScissors = faHandScissors; +exports.faHandSpock = faHandSpock; +exports.faHandshake = faHandshake; +exports.faHashtag = faHashtag; +exports.faHdd = faHdd; +exports.faHeading = faHeading; +exports.faHeadphones = faHeadphones; +exports.faHeart = faHeart; +exports.faHeartbeat = faHeartbeat; +exports.faHistory = faHistory; +exports.faHome = faHome; +exports.faHospital = faHospital; +exports.faHourglass = faHourglass; +exports.faHourglassEnd = faHourglassEnd; +exports.faHourglassHalf = faHourglassHalf; +exports.faHourglassStart = faHourglassStart; +exports.faICursor = faICursor; +exports.faIdBadge = faIdBadge; +exports.faIdCard = faIdCard; +exports.faImage = faImage; +exports.faImages = faImages; +exports.faInbox = faInbox; +exports.faIndent = faIndent; +exports.faIndustry = faIndustry; +exports.faInfo = faInfo; +exports.faInfoCircle = faInfoCircle; +exports.faItalic = faItalic; +exports.faKey = faKey; +exports.faKeyboard = faKeyboard; +exports.faLanguage = faLanguage; +exports.faLaptop = faLaptop; +exports.faLeaf = faLeaf; +exports.faLemon = faLemon; +exports.faLevelDownAlt = faLevelDownAlt; +exports.faLevelUpAlt = faLevelUpAlt; +exports.faLifeRing = faLifeRing; +exports.faLightbulb = faLightbulb; +exports.faLink = faLink; +exports.faLiraSign = faLiraSign; +exports.faList = faList; +exports.faListAlt = faListAlt; +exports.faListOl = faListOl; +exports.faListUl = faListUl; +exports.faLocationArrow = faLocationArrow; +exports.faLock = faLock; +exports.faLockOpen = faLockOpen; +exports.faLongArrowAltDown = faLongArrowAltDown; +exports.faLongArrowAltLeft = faLongArrowAltLeft; +exports.faLongArrowAltRight = faLongArrowAltRight; +exports.faLongArrowAltUp = faLongArrowAltUp; +exports.faLowVision = faLowVision; +exports.faMagic = faMagic; +exports.faMagnet = faMagnet; +exports.faMale = faMale; +exports.faMap = faMap; +exports.faMapMarker = faMapMarker; +exports.faMapMarkerAlt = faMapMarkerAlt; +exports.faMapPin = faMapPin; +exports.faMapSigns = faMapSigns; +exports.faMars = faMars; +exports.faMarsDouble = faMarsDouble; +exports.faMarsStroke = faMarsStroke; +exports.faMarsStrokeH = faMarsStrokeH; +exports.faMarsStrokeV = faMarsStrokeV; +exports.faMedkit = faMedkit; +exports.faMeh = faMeh; +exports.faMercury = faMercury; +exports.faMicrochip = faMicrochip; +exports.faMicrophone = faMicrophone; +exports.faMicrophoneSlash = faMicrophoneSlash; +exports.faMinus = faMinus; +exports.faMinusCircle = faMinusCircle; +exports.faMinusSquare = faMinusSquare; +exports.faMobile = faMobile; +exports.faMobileAlt = faMobileAlt; +exports.faMoneyBillAlt = faMoneyBillAlt; +exports.faMoon = faMoon; +exports.faMotorcycle = faMotorcycle; +exports.faMousePointer = faMousePointer; +exports.faMusic = faMusic; +exports.faNeuter = faNeuter; +exports.faNewspaper = faNewspaper; +exports.faObjectGroup = faObjectGroup; +exports.faObjectUngroup = faObjectUngroup; +exports.faOutdent = faOutdent; +exports.faPaintBrush = faPaintBrush; +exports.faPaperPlane = faPaperPlane; +exports.faPaperclip = faPaperclip; +exports.faParagraph = faParagraph; +exports.faPaste = faPaste; +exports.faPause = faPause; +exports.faPauseCircle = faPauseCircle; +exports.faPaw = faPaw; +exports.faPenSquare = faPenSquare; +exports.faPencilAlt = faPencilAlt; +exports.faPercent = faPercent; +exports.faPhone = faPhone; +exports.faPhoneSquare = faPhoneSquare; +exports.faPhoneVolume = faPhoneVolume; +exports.faPlane = faPlane; +exports.faPlay = faPlay; +exports.faPlayCircle = faPlayCircle; +exports.faPlug = faPlug; +exports.faPlus = faPlus; +exports.faPlusCircle = faPlusCircle; +exports.faPlusSquare = faPlusSquare; +exports.faPodcast = faPodcast; +exports.faPoundSign = faPoundSign; +exports.faPowerOff = faPowerOff; +exports.faPrint = faPrint; +exports.faPuzzlePiece = faPuzzlePiece; +exports.faQrcode = faQrcode; +exports.faQuestion = faQuestion; +exports.faQuestionCircle = faQuestionCircle; +exports.faQuoteLeft = faQuoteLeft; +exports.faQuoteRight = faQuoteRight; +exports.faRandom = faRandom; +exports.faRecycle = faRecycle; +exports.faRedo = faRedo; +exports.faRedoAlt = faRedoAlt; +exports.faRegistered = faRegistered; +exports.faReply = faReply; +exports.faReplyAll = faReplyAll; +exports.faRetweet = faRetweet; +exports.faRoad = faRoad; +exports.faRocket = faRocket; +exports.faRss = faRss; +exports.faRssSquare = faRssSquare; +exports.faRubleSign = faRubleSign; +exports.faRupeeSign = faRupeeSign; +exports.faSave = faSave; +exports.faSearch = faSearch; +exports.faSearchMinus = faSearchMinus; +exports.faSearchPlus = faSearchPlus; +exports.faServer = faServer; +exports.faShare = faShare; +exports.faShareAlt = faShareAlt; +exports.faShareAltSquare = faShareAltSquare; +exports.faShareSquare = faShareSquare; +exports.faShekelSign = faShekelSign; +exports.faShieldAlt = faShieldAlt; +exports.faShip = faShip; +exports.faShoppingBag = faShoppingBag; +exports.faShoppingBasket = faShoppingBasket; +exports.faShoppingCart = faShoppingCart; +exports.faShower = faShower; +exports.faSignInAlt = faSignInAlt; +exports.faSignLanguage = faSignLanguage; +exports.faSignOutAlt = faSignOutAlt; +exports.faSignal = faSignal; +exports.faSitemap = faSitemap; +exports.faSlidersH = faSlidersH; +exports.faSmile = faSmile; +exports.faSnowflake = faSnowflake; +exports.faSort = faSort; +exports.faSortAlphaDown = faSortAlphaDown; +exports.faSortAlphaUp = faSortAlphaUp; +exports.faSortAmountDown = faSortAmountDown; +exports.faSortAmountUp = faSortAmountUp; +exports.faSortDown = faSortDown; +exports.faSortNumericDown = faSortNumericDown; +exports.faSortNumericUp = faSortNumericUp; +exports.faSortUp = faSortUp; +exports.faSpaceShuttle = faSpaceShuttle; +exports.faSpinner = faSpinner; +exports.faSquare = faSquare; +exports.faStar = faStar; +exports.faStarHalf = faStarHalf; +exports.faStepBackward = faStepBackward; +exports.faStepForward = faStepForward; +exports.faStethoscope = faStethoscope; +exports.faStickyNote = faStickyNote; +exports.faStop = faStop; +exports.faStopCircle = faStopCircle; +exports.faStreetView = faStreetView; +exports.faStrikethrough = faStrikethrough; +exports.faSubscript = faSubscript; +exports.faSubway = faSubway; +exports.faSuitcase = faSuitcase; +exports.faSun = faSun; +exports.faSuperscript = faSuperscript; +exports.faSync = faSync; +exports.faSyncAlt = faSyncAlt; +exports.faTable = faTable; +exports.faTablet = faTablet; +exports.faTabletAlt = faTabletAlt; +exports.faTachometerAlt = faTachometerAlt; +exports.faTag = faTag; +exports.faTags = faTags; +exports.faTasks = faTasks; +exports.faTaxi = faTaxi; +exports.faTerminal = faTerminal; +exports.faTextHeight = faTextHeight; +exports.faTextWidth = faTextWidth; +exports.faTh = faTh; +exports.faThLarge = faThLarge; +exports.faThList = faThList; +exports.faThermometerEmpty = faThermometerEmpty; +exports.faThermometerFull = faThermometerFull; +exports.faThermometerHalf = faThermometerHalf; +exports.faThermometerQuarter = faThermometerQuarter; +exports.faThermometerThreeQuarters = faThermometerThreeQuarters; +exports.faThumbsDown = faThumbsDown; +exports.faThumbsUp = faThumbsUp; +exports.faThumbtack = faThumbtack; +exports.faTicketAlt = faTicketAlt; +exports.faTimes = faTimes; +exports.faTimesCircle = faTimesCircle; +exports.faTint = faTint; +exports.faToggleOff = faToggleOff; +exports.faToggleOn = faToggleOn; +exports.faTrademark = faTrademark; +exports.faTrain = faTrain; +exports.faTransgender = faTransgender; +exports.faTransgenderAlt = faTransgenderAlt; +exports.faTrash = faTrash; +exports.faTrashAlt = faTrashAlt; +exports.faTree = faTree; +exports.faTrophy = faTrophy; +exports.faTruck = faTruck; +exports.faTty = faTty; +exports.faTv = faTv; +exports.faUmbrella = faUmbrella; +exports.faUnderline = faUnderline; +exports.faUndo = faUndo; +exports.faUndoAlt = faUndoAlt; +exports.faUniversalAccess = faUniversalAccess; +exports.faUniversity = faUniversity; +exports.faUnlink = faUnlink; +exports.faUnlock = faUnlock; +exports.faUnlockAlt = faUnlockAlt; +exports.faUpload = faUpload; +exports.faUser = faUser; +exports.faUserCircle = faUserCircle; +exports.faUserMd = faUserMd; +exports.faUserPlus = faUserPlus; +exports.faUserSecret = faUserSecret; +exports.faUserTimes = faUserTimes; +exports.faUsers = faUsers; +exports.faUtensilSpoon = faUtensilSpoon; +exports.faUtensils = faUtensils; +exports.faVenus = faVenus; +exports.faVenusDouble = faVenusDouble; +exports.faVenusMars = faVenusMars; +exports.faVideo = faVideo; +exports.faVolumeDown = faVolumeDown; +exports.faVolumeOff = faVolumeOff; +exports.faVolumeUp = faVolumeUp; +exports.faWheelchair = faWheelchair; +exports.faWifi = faWifi; +exports.faWindowClose = faWindowClose; +exports.faWindowMaximize = faWindowMaximize; +exports.faWindowMinimize = faWindowMinimize; +exports.faWindowRestore = faWindowRestore; +exports.faWonSign = faWonSign; +exports.faWrench = faWrench; +exports.faYenSign = faYenSign; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/package.json b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/package.json new file mode 100644 index 000000000..f9bb0e93d --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-solid/package.json @@ -0,0 +1,52 @@ +{ + "description": "The iconic font, CSS, and SVG framework", + "keywords": [ + "font", + "awesome", + "fontawesome", + "icon", + "svg", + "bootstrap" + ], + "homepage": "https://fontawesome.com", + "bugs": { + "url": "http://github.com/FortAwesome/Font-Awesome/issues" + }, + "author": { + "name": "Dave Gandy", + "email": "dave@fontawesome.com", + "web": "http://twitter.com/davegandy" + }, + "contributors": [ + { + "name": "Brian Talbot", + "web": "http://twitter.com/talbs" + }, + { + "name": "Travis Chase", + "web": "http://twitter.com/supercodepoet" + }, + { + "name": "Rob Madole", + "web": "http://twitter.com/robmadole" + }, + { + "name": "Geremia Taglialatela", + "web": "http://twitter.com/gtagliala" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome" + }, + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "version": "5.0.1", + "name": "@fortawesome/fontawesome-free-solid", + "main": "index.js", + "module": "index.es.js", + "jsnext:main": "index.es.js", + "license": "(CC-BY-4.0 AND MIT)" +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/LICENSE.txt b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-brands.css b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-brands.css new file mode 100644 index 000000000..2a8d4ad82 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-brands.css @@ -0,0 +1,9 @@ +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url("../webfonts/fa-brands-400.eot"); + src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } + +.fab { + font-family: 'Font Awesome 5 Brands'; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-regular.css b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-regular.css new file mode 100644 index 000000000..7cece4715 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-regular.css @@ -0,0 +1,10 @@ +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url("../webfonts/fa-regular-400.eot"); + src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-solid.css b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-solid.css new file mode 100644 index 000000000..45f4ee197 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fa-solid.css @@ -0,0 +1,11 @@ +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url("../webfonts/fa-solid-900.eot"); + src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fontawesome.css b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fontawesome.css new file mode 100644 index 000000000..016722a06 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/css/fontawesome.css @@ -0,0 +1,2558 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa, +.fas, +.far, +.fal, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-address-book:before { + content: "\f2b9"; } + +.fa-address-card:before { + content: "\f2bb"; } + +.fa-adjust:before { + content: "\f042"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-align-center:before { + content: "\f037"; } + +.fa-align-justify:before { + content: "\f039"; } + +.fa-align-left:before { + content: "\f036"; } + +.fa-align-right:before { + content: "\f038"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-ambulance:before { + content: "\f0f9"; } + +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-anchor:before { + content: "\f13d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angle-double-down:before { + content: "\f103"; } + +.fa-angle-double-left:before { + content: "\f100"; } + +.fa-angle-double-right:before { + content: "\f101"; } + +.fa-angle-double-up:before { + content: "\f102"; } + +.fa-angle-down:before { + content: "\f107"; } + +.fa-angle-left:before { + content: "\f104"; } + +.fa-angle-right:before { + content: "\f105"; } + +.fa-angle-up:before { + content: "\f106"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-archive:before { + content: "\f187"; } + +.fa-arrow-alt-circle-down:before { + content: "\f358"; } + +.fa-arrow-alt-circle-left:before { + content: "\f359"; } + +.fa-arrow-alt-circle-right:before { + content: "\f35a"; } + +.fa-arrow-alt-circle-up:before { + content: "\f35b"; } + +.fa-arrow-circle-down:before { + content: "\f0ab"; } + +.fa-arrow-circle-left:before { + content: "\f0a8"; } + +.fa-arrow-circle-right:before { + content: "\f0a9"; } + +.fa-arrow-circle-up:before { + content: "\f0aa"; } + +.fa-arrow-down:before { + content: "\f063"; } + +.fa-arrow-left:before { + content: "\f060"; } + +.fa-arrow-right:before { + content: "\f061"; } + +.fa-arrow-up:before { + content: "\f062"; } + +.fa-arrows-alt:before { + content: "\f0b2"; } + +.fa-arrows-alt-h:before { + content: "\f337"; } + +.fa-arrows-alt-v:before { + content: "\f338"; } + +.fa-assistive-listening-systems:before { + content: "\f2a2"; } + +.fa-asterisk:before { + content: "\f069"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-at:before { + content: "\f1fa"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-audio-description:before { + content: "\f29e"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-backward:before { + content: "\f04a"; } + +.fa-balance-scale:before { + content: "\f24e"; } + +.fa-ban:before { + content: "\f05e"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-barcode:before { + content: "\f02a"; } + +.fa-bars:before { + content: "\f0c9"; } + +.fa-bath:before { + content: "\f2cd"; } + +.fa-battery-empty:before { + content: "\f244"; } + +.fa-battery-full:before { + content: "\f240"; } + +.fa-battery-half:before { + content: "\f242"; } + +.fa-battery-quarter:before { + content: "\f243"; } + +.fa-battery-three-quarters:before { + content: "\f241"; } + +.fa-bed:before { + content: "\f236"; } + +.fa-beer:before { + content: "\f0fc"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bell:before { + content: "\f0f3"; } + +.fa-bell-slash:before { + content: "\f1f6"; } + +.fa-bicycle:before { + content: "\f206"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-binoculars:before { + content: "\f1e5"; } + +.fa-birthday-cake:before { + content: "\f1fd"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blind:before { + content: "\f29d"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bold:before { + content: "\f032"; } + +.fa-bolt:before { + content: "\f0e7"; } + +.fa-bomb:before { + content: "\f1e2"; } + +.fa-book:before { + content: "\f02d"; } + +.fa-bookmark:before { + content: "\f02e"; } + +.fa-braille:before { + content: "\f2a1"; } + +.fa-briefcase:before { + content: "\f0b1"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-bug:before { + content: "\f188"; } + +.fa-building:before { + content: "\f1ad"; } + +.fa-bullhorn:before { + content: "\f0a1"; } + +.fa-bullseye:before { + content: "\f140"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-bus:before { + content: "\f207"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-calculator:before { + content: "\f1ec"; } + +.fa-calendar:before { + content: "\f133"; } + +.fa-calendar-alt:before { + content: "\f073"; } + +.fa-calendar-check:before { + content: "\f274"; } + +.fa-calendar-minus:before { + content: "\f272"; } + +.fa-calendar-plus:before { + content: "\f271"; } + +.fa-calendar-times:before { + content: "\f273"; } + +.fa-camera:before { + content: "\f030"; } + +.fa-camera-retro:before { + content: "\f083"; } + +.fa-car:before { + content: "\f1b9"; } + +.fa-caret-down:before { + content: "\f0d7"; } + +.fa-caret-left:before { + content: "\f0d9"; } + +.fa-caret-right:before { + content: "\f0da"; } + +.fa-caret-square-down:before { + content: "\f150"; } + +.fa-caret-square-left:before { + content: "\f191"; } + +.fa-caret-square-right:before { + content: "\f152"; } + +.fa-caret-square-up:before { + content: "\f151"; } + +.fa-caret-up:before { + content: "\f0d8"; } + +.fa-cart-arrow-down:before { + content: "\f218"; } + +.fa-cart-plus:before { + content: "\f217"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-certificate:before { + content: "\f0a3"; } + +.fa-chart-area:before { + content: "\f1fe"; } + +.fa-chart-bar:before { + content: "\f080"; } + +.fa-chart-line:before { + content: "\f201"; } + +.fa-chart-pie:before { + content: "\f200"; } + +.fa-check:before { + content: "\f00c"; } + +.fa-check-circle:before { + content: "\f058"; } + +.fa-check-square:before { + content: "\f14a"; } + +.fa-chevron-circle-down:before { + content: "\f13a"; } + +.fa-chevron-circle-left:before { + content: "\f137"; } + +.fa-chevron-circle-right:before { + content: "\f138"; } + +.fa-chevron-circle-up:before { + content: "\f139"; } + +.fa-chevron-down:before { + content: "\f078"; } + +.fa-chevron-left:before { + content: "\f053"; } + +.fa-chevron-right:before { + content: "\f054"; } + +.fa-chevron-up:before { + content: "\f077"; } + +.fa-child:before { + content: "\f1ae"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-circle:before { + content: "\f111"; } + +.fa-circle-notch:before { + content: "\f1ce"; } + +.fa-clipboard:before { + content: "\f328"; } + +.fa-clock:before { + content: "\f017"; } + +.fa-clone:before { + content: "\f24d"; } + +.fa-closed-captioning:before { + content: "\f20a"; } + +.fa-cloud:before { + content: "\f0c2"; } + +.fa-cloud-download-alt:before { + content: "\f381"; } + +.fa-cloud-upload-alt:before { + content: "\f382"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-code:before { + content: "\f121"; } + +.fa-code-branch:before { + content: "\f126"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-coffee:before { + content: "\f0f4"; } + +.fa-cog:before { + content: "\f013"; } + +.fa-cogs:before { + content: "\f085"; } + +.fa-columns:before { + content: "\f0db"; } + +.fa-comment:before { + content: "\f075"; } + +.fa-comment-alt:before { + content: "\f27a"; } + +.fa-comments:before { + content: "\f086"; } + +.fa-compass:before { + content: "\f14e"; } + +.fa-compress:before { + content: "\f066"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-copy:before { + content: "\f0c5"; } + +.fa-copyright:before { + content: "\f1f9"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-credit-card:before { + content: "\f09d"; } + +.fa-crop:before { + content: "\f125"; } + +.fa-crosshairs:before { + content: "\f05b"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cube:before { + content: "\f1b2"; } + +.fa-cubes:before { + content: "\f1b3"; } + +.fa-cut:before { + content: "\f0c4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-database:before { + content: "\f1c0"; } + +.fa-deaf:before { + content: "\f2a4"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-desktop:before { + content: "\f108"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-dollar-sign:before { + content: "\f155"; } + +.fa-dot-circle:before { + content: "\f192"; } + +.fa-download:before { + content: "\f019"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edit:before { + content: "\f044"; } + +.fa-eject:before { + content: "\f052"; } + +.fa-ellipsis-h:before { + content: "\f141"; } + +.fa-ellipsis-v:before { + content: "\f142"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envelope:before { + content: "\f0e0"; } + +.fa-envelope-open:before { + content: "\f2b6"; } + +.fa-envelope-square:before { + content: "\f199"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-eraser:before { + content: "\f12d"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-euro-sign:before { + content: "\f153"; } + +.fa-exchange-alt:before { + content: "\f362"; } + +.fa-exclamation:before { + content: "\f12a"; } + +.fa-exclamation-circle:before { + content: "\f06a"; } + +.fa-exclamation-triangle:before { + content: "\f071"; } + +.fa-expand:before { + content: "\f065"; } + +.fa-expand-arrows-alt:before { + content: "\f31e"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-external-link-alt:before { + content: "\f35d"; } + +.fa-external-link-square-alt:before { + content: "\f360"; } + +.fa-eye:before { + content: "\f06e"; } + +.fa-eye-dropper:before { + content: "\f1fb"; } + +.fa-eye-slash:before { + content: "\f070"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fast-backward:before { + content: "\f049"; } + +.fa-fast-forward:before { + content: "\f050"; } + +.fa-fax:before { + content: "\f1ac"; } + +.fa-female:before { + content: "\f182"; } + +.fa-fighter-jet:before { + content: "\f0fb"; } + +.fa-file:before { + content: "\f15b"; } + +.fa-file-alt:before { + content: "\f15c"; } + +.fa-file-archive:before { + content: "\f1c6"; } + +.fa-file-audio:before { + content: "\f1c7"; } + +.fa-file-code:before { + content: "\f1c9"; } + +.fa-file-excel:before { + content: "\f1c3"; } + +.fa-file-image:before { + content: "\f1c5"; } + +.fa-file-pdf:before { + content: "\f1c1"; } + +.fa-file-powerpoint:before { + content: "\f1c4"; } + +.fa-file-video:before { + content: "\f1c8"; } + +.fa-file-word:before { + content: "\f1c2"; } + +.fa-film:before { + content: "\f008"; } + +.fa-filter:before { + content: "\f0b0"; } + +.fa-fire:before { + content: "\f06d"; } + +.fa-fire-extinguisher:before { + content: "\f134"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-flag:before { + content: "\f024"; } + +.fa-flag-checkered:before { + content: "\f11e"; } + +.fa-flask:before { + content: "\f0c3"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-folder:before { + content: "\f07b"; } + +.fa-folder-open:before { + content: "\f07c"; } + +.fa-font:before { + content: "\f031"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-font-awesome-flag:before { + content: "\f425"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-forward:before { + content: "\f04e"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-frown:before { + content: "\f119"; } + +.fa-futbol:before { + content: "\f1e3"; } + +.fa-gamepad:before { + content: "\f11b"; } + +.fa-gavel:before { + content: "\f0e3"; } + +.fa-gem:before { + content: "\f3a5"; } + +.fa-genderless:before { + content: "\f22d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-gift:before { + content: "\f06b"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glass-martini:before { + content: "\f000"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-globe:before { + content: "\f0ac"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-graduation-cap:before { + content: "\f19d"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-h-square:before { + content: "\f0fd"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hand-lizard:before { + content: "\f258"; } + +.fa-hand-paper:before { + content: "\f256"; } + +.fa-hand-peace:before { + content: "\f25b"; } + +.fa-hand-point-down:before { + content: "\f0a7"; } + +.fa-hand-point-left:before { + content: "\f0a5"; } + +.fa-hand-point-right:before { + content: "\f0a4"; } + +.fa-hand-point-up:before { + content: "\f0a6"; } + +.fa-hand-pointer:before { + content: "\f25a"; } + +.fa-hand-rock:before { + content: "\f255"; } + +.fa-hand-scissors:before { + content: "\f257"; } + +.fa-hand-spock:before { + content: "\f259"; } + +.fa-handshake:before { + content: "\f2b5"; } + +.fa-hashtag:before { + content: "\f292"; } + +.fa-hdd:before { + content: "\f0a0"; } + +.fa-heading:before { + content: "\f1dc"; } + +.fa-headphones:before { + content: "\f025"; } + +.fa-heart:before { + content: "\f004"; } + +.fa-heartbeat:before { + content: "\f21e"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-history:before { + content: "\f1da"; } + +.fa-home:before { + content: "\f015"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hospital:before { + content: "\f0f8"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-hourglass:before { + content: "\f254"; } + +.fa-hourglass-end:before { + content: "\f253"; } + +.fa-hourglass-half:before { + content: "\f252"; } + +.fa-hourglass-start:before { + content: "\f251"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-i-cursor:before { + content: "\f246"; } + +.fa-id-badge:before { + content: "\f2c1"; } + +.fa-id-card:before { + content: "\f2c2"; } + +.fa-image:before { + content: "\f03e"; } + +.fa-images:before { + content: "\f302"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-inbox:before { + content: "\f01c"; } + +.fa-indent:before { + content: "\f03c"; } + +.fa-industry:before { + content: "\f275"; } + +.fa-info:before { + content: "\f129"; } + +.fa-info-circle:before { + content: "\f05a"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-italic:before { + content: "\f033"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-key:before { + content: "\f084"; } + +.fa-keyboard:before { + content: "\f11c"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-language:before { + content: "\f1ab"; } + +.fa-laptop:before { + content: "\f109"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-leaf:before { + content: "\f06c"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-lemon:before { + content: "\f094"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-level-down-alt:before { + content: "\f3be"; } + +.fa-level-up-alt:before { + content: "\f3bf"; } + +.fa-life-ring:before { + content: "\f1cd"; } + +.fa-lightbulb:before { + content: "\f0eb"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-link:before { + content: "\f0c1"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lira-sign:before { + content: "\f195"; } + +.fa-list:before { + content: "\f03a"; } + +.fa-list-alt:before { + content: "\f022"; } + +.fa-list-ol:before { + content: "\f0cb"; } + +.fa-list-ul:before { + content: "\f0ca"; } + +.fa-location-arrow:before { + content: "\f124"; } + +.fa-lock:before { + content: "\f023"; } + +.fa-lock-open:before { + content: "\f3c1"; } + +.fa-long-arrow-alt-down:before { + content: "\f309"; } + +.fa-long-arrow-alt-left:before { + content: "\f30a"; } + +.fa-long-arrow-alt-right:before { + content: "\f30b"; } + +.fa-long-arrow-alt-up:before { + content: "\f30c"; } + +.fa-low-vision:before { + content: "\f2a8"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-magic:before { + content: "\f0d0"; } + +.fa-magnet:before { + content: "\f076"; } + +.fa-male:before { + content: "\f183"; } + +.fa-map:before { + content: "\f279"; } + +.fa-map-marker:before { + content: "\f041"; } + +.fa-map-marker-alt:before { + content: "\f3c5"; } + +.fa-map-pin:before { + content: "\f276"; } + +.fa-map-signs:before { + content: "\f277"; } + +.fa-mars:before { + content: "\f222"; } + +.fa-mars-double:before { + content: "\f227"; } + +.fa-mars-stroke:before { + content: "\f229"; } + +.fa-mars-stroke-h:before { + content: "\f22b"; } + +.fa-mars-stroke-v:before { + content: "\f22a"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f3c7"; } + +.fa-medkit:before { + content: "\f0fa"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-meh:before { + content: "\f11a"; } + +.fa-mercury:before { + content: "\f223"; } + +.fa-microchip:before { + content: "\f2db"; } + +.fa-microphone:before { + content: "\f130"; } + +.fa-microphone-slash:before { + content: "\f131"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-minus:before { + content: "\f068"; } + +.fa-minus-circle:before { + content: "\f056"; } + +.fa-minus-square:before { + content: "\f146"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-mobile:before { + content: "\f10b"; } + +.fa-mobile-alt:before { + content: "\f3cd"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-money-bill-alt:before { + content: "\f3d1"; } + +.fa-moon:before { + content: "\f186"; } + +.fa-motorcycle:before { + content: "\f21c"; } + +.fa-mouse-pointer:before { + content: "\f245"; } + +.fa-music:before { + content: "\f001"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neuter:before { + content: "\f22c"; } + +.fa-newspaper:before { + content: "\f1ea"; } + +.fa-nintendo-switch:before { + content: "\f418"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-object-group:before { + content: "\f247"; } + +.fa-object-ungroup:before { + content: "\f248"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-outdent:before { + content: "\f03b"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-paint-brush:before { + content: "\f1fc"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-paper-plane:before { + content: "\f1d8"; } + +.fa-paperclip:before { + content: "\f0c6"; } + +.fa-paragraph:before { + content: "\f1dd"; } + +.fa-paste:before { + content: "\f0ea"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-pause:before { + content: "\f04c"; } + +.fa-pause-circle:before { + content: "\f28b"; } + +.fa-paw:before { + content: "\f1b0"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-pen-square:before { + content: "\f14b"; } + +.fa-pencil-alt:before { + content: "\f303"; } + +.fa-percent:before { + content: "\f295"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phone:before { + content: "\f095"; } + +.fa-phone-square:before { + content: "\f098"; } + +.fa-phone-volume:before { + content: "\f2a0"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-plane:before { + content: "\f072"; } + +.fa-play:before { + content: "\f04b"; } + +.fa-play-circle:before { + content: "\f144"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-plug:before { + content: "\f1e6"; } + +.fa-plus:before { + content: "\f067"; } + +.fa-plus-circle:before { + content: "\f055"; } + +.fa-plus-square:before { + content: "\f0fe"; } + +.fa-podcast:before { + content: "\f2ce"; } + +.fa-pound-sign:before { + content: "\f154"; } + +.fa-power-off:before { + content: "\f011"; } + +.fa-print:before { + content: "\f02f"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-puzzle-piece:before { + content: "\f12e"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-qrcode:before { + content: "\f029"; } + +.fa-question:before { + content: "\f128"; } + +.fa-question-circle:before { + content: "\f059"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-quote-left:before { + content: "\f10d"; } + +.fa-quote-right:before { + content: "\f10e"; } + +.fa-random:before { + content: "\f074"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-recycle:before { + content: "\f1b8"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redo:before { + content: "\f01e"; } + +.fa-redo-alt:before { + content: "\f2f9"; } + +.fa-registered:before { + content: "\f25d"; } + +.fa-rendact:before { + content: "\f3e4"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-reply:before { + content: "\f3e5"; } + +.fa-reply-all:before { + content: "\f122"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-retweet:before { + content: "\f079"; } + +.fa-road:before { + content: "\f018"; } + +.fa-rocket:before { + content: "\f135"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-rss:before { + content: "\f09e"; } + +.fa-rss-square:before { + content: "\f143"; } + +.fa-ruble-sign:before { + content: "\f158"; } + +.fa-rupee-sign:before { + content: "\f156"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-save:before { + content: "\f0c7"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-search:before { + content: "\f002"; } + +.fa-search-minus:before { + content: "\f010"; } + +.fa-search-plus:before { + content: "\f00e"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-server:before { + content: "\f233"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-share:before { + content: "\f064"; } + +.fa-share-alt:before { + content: "\f1e0"; } + +.fa-share-alt-square:before { + content: "\f1e1"; } + +.fa-share-square:before { + content: "\f14d"; } + +.fa-shekel-sign:before { + content: "\f20b"; } + +.fa-shield-alt:before { + content: "\f3ed"; } + +.fa-ship:before { + content: "\f21a"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shopping-bag:before { + content: "\f290"; } + +.fa-shopping-basket:before { + content: "\f291"; } + +.fa-shopping-cart:before { + content: "\f07a"; } + +.fa-shower:before { + content: "\f2cc"; } + +.fa-sign-in-alt:before { + content: "\f2f6"; } + +.fa-sign-language:before { + content: "\f2a7"; } + +.fa-sign-out-alt:before { + content: "\f2f5"; } + +.fa-signal:before { + content: "\f012"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sitemap:before { + content: "\f0e8"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f3ef"; } + +.fa-sliders-h:before { + content: "\f1de"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-smile:before { + content: "\f118"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ac"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-snowflake:before { + content: "\f2dc"; } + +.fa-sort:before { + content: "\f0dc"; } + +.fa-sort-alpha-down:before { + content: "\f15d"; } + +.fa-sort-alpha-up:before { + content: "\f15e"; } + +.fa-sort-amount-down:before { + content: "\f160"; } + +.fa-sort-amount-up:before { + content: "\f161"; } + +.fa-sort-down:before { + content: "\f0dd"; } + +.fa-sort-numeric-down:before { + content: "\f162"; } + +.fa-sort-numeric-up:before { + content: "\f163"; } + +.fa-sort-up:before { + content: "\f0de"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-space-shuttle:before { + content: "\f197"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-spinner:before { + content: "\f110"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-square:before { + content: "\f0c8"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-star:before { + content: "\f005"; } + +.fa-star-half:before { + content: "\f089"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-step-backward:before { + content: "\f048"; } + +.fa-step-forward:before { + content: "\f051"; } + +.fa-stethoscope:before { + content: "\f0f1"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-sticky-note:before { + content: "\f249"; } + +.fa-stop:before { + content: "\f04d"; } + +.fa-stop-circle:before { + content: "\f28d"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-street-view:before { + content: "\f21d"; } + +.fa-strikethrough:before { + content: "\f0cc"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-subscript:before { + content: "\f12c"; } + +.fa-subway:before { + content: "\f239"; } + +.fa-suitcase:before { + content: "\f0f2"; } + +.fa-sun:before { + content: "\f185"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-superscript:before { + content: "\f12b"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-sync:before { + content: "\f021"; } + +.fa-sync-alt:before { + content: "\f2f1"; } + +.fa-table:before { + content: "\f0ce"; } + +.fa-tablet:before { + content: "\f10a"; } + +.fa-tablet-alt:before { + content: "\f3fa"; } + +.fa-tachometer-alt:before { + content: "\f3fd"; } + +.fa-tag:before { + content: "\f02b"; } + +.fa-tags:before { + content: "\f02c"; } + +.fa-tasks:before { + content: "\f0ae"; } + +.fa-taxi:before { + content: "\f1ba"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f3fe"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-terminal:before { + content: "\f120"; } + +.fa-text-height:before { + content: "\f034"; } + +.fa-text-width:before { + content: "\f035"; } + +.fa-th:before { + content: "\f00a"; } + +.fa-th-large:before { + content: "\f009"; } + +.fa-th-list:before { + content: "\f00b"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-thermometer-empty:before { + content: "\f2cb"; } + +.fa-thermometer-full:before { + content: "\f2c7"; } + +.fa-thermometer-half:before { + content: "\f2c9"; } + +.fa-thermometer-quarter:before { + content: "\f2ca"; } + +.fa-thermometer-three-quarters:before { + content: "\f2c8"; } + +.fa-thumbs-down:before { + content: "\f165"; } + +.fa-thumbs-up:before { + content: "\f164"; } + +.fa-thumbtack:before { + content: "\f08d"; } + +.fa-ticket-alt:before { + content: "\f3ff"; } + +.fa-times:before { + content: "\f00d"; } + +.fa-times-circle:before { + content: "\f057"; } + +.fa-tint:before { + content: "\f043"; } + +.fa-toggle-off:before { + content: "\f204"; } + +.fa-toggle-on:before { + content: "\f205"; } + +.fa-trademark:before { + content: "\f25c"; } + +.fa-train:before { + content: "\f238"; } + +.fa-transgender:before { + content: "\f224"; } + +.fa-transgender-alt:before { + content: "\f225"; } + +.fa-trash:before { + content: "\f1f8"; } + +.fa-trash-alt:before { + content: "\f2ed"; } + +.fa-tree:before { + content: "\f1bb"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-tripadvisor:before { + content: "\f262"; } + +.fa-trophy:before { + content: "\f091"; } + +.fa-truck:before { + content: "\f0d1"; } + +.fa-tty:before { + content: "\f1e4"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-tv:before { + content: "\f26c"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbrella:before { + content: "\f0e9"; } + +.fa-underline:before { + content: "\f0cd"; } + +.fa-undo:before { + content: "\f0e2"; } + +.fa-undo-alt:before { + content: "\f2ea"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-universal-access:before { + content: "\f29a"; } + +.fa-university:before { + content: "\f19c"; } + +.fa-unlink:before { + content: "\f127"; } + +.fa-unlock:before { + content: "\f09c"; } + +.fa-unlock-alt:before { + content: "\f13e"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-upload:before { + content: "\f093"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-user:before { + content: "\f007"; } + +.fa-user-circle:before { + content: "\f2bd"; } + +.fa-user-md:before { + content: "\f0f0"; } + +.fa-user-plus:before { + content: "\f234"; } + +.fa-user-secret:before { + content: "\f21b"; } + +.fa-user-times:before { + content: "\f235"; } + +.fa-users:before { + content: "\f0c0"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-utensil-spoon:before { + content: "\f2e5"; } + +.fa-utensils:before { + content: "\f2e7"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-venus:before { + content: "\f221"; } + +.fa-venus-double:before { + content: "\f226"; } + +.fa-venus-mars:before { + content: "\f228"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-video:before { + content: "\f03d"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-volume-down:before { + content: "\f027"; } + +.fa-volume-off:before { + content: "\f026"; } + +.fa-volume-up:before { + content: "\f028"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-wheelchair:before { + content: "\f193"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wifi:before { + content: "\f1eb"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-window-close:before { + content: "\f410"; } + +.fa-window-maximize:before { + content: "\f2d0"; } + +.fa-window-minimize:before { + content: "\f2d1"; } + +.fa-window-restore:before { + content: "\f2d2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-won-sign:before { + content: "\f159"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wrench:before { + content: "\f0ad"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yen-sign:before { + content: "\f157"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_animated.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_animated.less new file mode 100644 index 000000000..704ec9510 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_animated.less @@ -0,0 +1,19 @@ +// Animated Icons +// -------------------------- + +.@{fa-css-prefix}-spin { + animation: fa-spin 2s infinite linear; +} + +.@{fa-css-prefix}-pulse { + animation: fa-spin 1s infinite steps(8); +} + +@keyframes fa-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_bordered-pulled.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_bordered-pulled.less new file mode 100644 index 000000000..29a356b42 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_bordered-pulled.less @@ -0,0 +1,16 @@ +// Bordered & Pulled +// ------------------------- + +.@{fa-css-prefix}-border { + border-radius: .1em; + border: solid .08em @fa-border-color; + padding: .2em .25em .15em; +} + +.@{fa-css-prefix}-pull-left { float: left; } +.@{fa-css-prefix}-pull-right { float: right; } + +.@{fa-css-prefix}, .fas, .far, .fal, .fab { + &.@{fa-css-prefix}-pull-left { margin-right: .3em; } + &.@{fa-css-prefix}-pull-right { margin-left: .3em; } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_core.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_core.less new file mode 100644 index 000000000..82031d652 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_core.less @@ -0,0 +1,12 @@ +// Base Class Definition +// ------------------------- + +.@{fa-css-prefix}, .fas, .far, .fal, .fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_fixed-width.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_fixed-width.less new file mode 100644 index 000000000..be817c637 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_fixed-width.less @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.@{fa-css-prefix}-fw { + text-align: center; + width: (20em / 16); +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_icons.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_icons.less new file mode 100644 index 000000000..20185ec4a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_icons.less @@ -0,0 +1,787 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ + +.@{fa-css-prefix}-500px:before { content: @fa-var-500px; } +.@{fa-css-prefix}-accessible-icon:before { content: @fa-var-accessible-icon; } +.@{fa-css-prefix}-accusoft:before { content: @fa-var-accusoft; } +.@{fa-css-prefix}-address-book:before { content: @fa-var-address-book; } +.@{fa-css-prefix}-address-card:before { content: @fa-var-address-card; } +.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; } +.@{fa-css-prefix}-adn:before { content: @fa-var-adn; } +.@{fa-css-prefix}-adversal:before { content: @fa-var-adversal; } +.@{fa-css-prefix}-affiliatetheme:before { content: @fa-var-affiliatetheme; } +.@{fa-css-prefix}-algolia:before { content: @fa-var-algolia; } +.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; } +.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; } +.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; } +.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; } +.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; } +.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; } +.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; } +.@{fa-css-prefix}-amilia:before { content: @fa-var-amilia; } +.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; } +.@{fa-css-prefix}-android:before { content: @fa-var-android; } +.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; } +.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; } +.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; } +.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; } +.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; } +.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; } +.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; } +.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; } +.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; } +.@{fa-css-prefix}-angrycreative:before { content: @fa-var-angrycreative; } +.@{fa-css-prefix}-angular:before { content: @fa-var-angular; } +.@{fa-css-prefix}-app-store:before { content: @fa-var-app-store; } +.@{fa-css-prefix}-app-store-ios:before { content: @fa-var-app-store-ios; } +.@{fa-css-prefix}-apper:before { content: @fa-var-apper; } +.@{fa-css-prefix}-apple:before { content: @fa-var-apple; } +.@{fa-css-prefix}-apple-pay:before { content: @fa-var-apple-pay; } +.@{fa-css-prefix}-archive:before { content: @fa-var-archive; } +.@{fa-css-prefix}-arrow-alt-circle-down:before { content: @fa-var-arrow-alt-circle-down; } +.@{fa-css-prefix}-arrow-alt-circle-left:before { content: @fa-var-arrow-alt-circle-left; } +.@{fa-css-prefix}-arrow-alt-circle-right:before { content: @fa-var-arrow-alt-circle-right; } +.@{fa-css-prefix}-arrow-alt-circle-up:before { content: @fa-var-arrow-alt-circle-up; } +.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; } +.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; } +.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; } +.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; } +.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; } +.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; } +.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; } +.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; } +.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; } +.@{fa-css-prefix}-arrows-alt-h:before { content: @fa-var-arrows-alt-h; } +.@{fa-css-prefix}-arrows-alt-v:before { content: @fa-var-arrows-alt-v; } +.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; } +.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; } +.@{fa-css-prefix}-asymmetrik:before { content: @fa-var-asymmetrik; } +.@{fa-css-prefix}-at:before { content: @fa-var-at; } +.@{fa-css-prefix}-audible:before { content: @fa-var-audible; } +.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; } +.@{fa-css-prefix}-autoprefixer:before { content: @fa-var-autoprefixer; } +.@{fa-css-prefix}-avianex:before { content: @fa-var-avianex; } +.@{fa-css-prefix}-aviato:before { content: @fa-var-aviato; } +.@{fa-css-prefix}-aws:before { content: @fa-var-aws; } +.@{fa-css-prefix}-backward:before { content: @fa-var-backward; } +.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; } +.@{fa-css-prefix}-ban:before { content: @fa-var-ban; } +.@{fa-css-prefix}-bandcamp:before { content: @fa-var-bandcamp; } +.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; } +.@{fa-css-prefix}-bars:before { content: @fa-var-bars; } +.@{fa-css-prefix}-bath:before { content: @fa-var-bath; } +.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; } +.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; } +.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; } +.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; } +.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; } +.@{fa-css-prefix}-bed:before { content: @fa-var-bed; } +.@{fa-css-prefix}-beer:before { content: @fa-var-beer; } +.@{fa-css-prefix}-behance:before { content: @fa-var-behance; } +.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; } +.@{fa-css-prefix}-bell:before { content: @fa-var-bell; } +.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; } +.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; } +.@{fa-css-prefix}-bimobject:before { content: @fa-var-bimobject; } +.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; } +.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; } +.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; } +.@{fa-css-prefix}-bitcoin:before { content: @fa-var-bitcoin; } +.@{fa-css-prefix}-bity:before { content: @fa-var-bity; } +.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; } +.@{fa-css-prefix}-blackberry:before { content: @fa-var-blackberry; } +.@{fa-css-prefix}-blind:before { content: @fa-var-blind; } +.@{fa-css-prefix}-blogger:before { content: @fa-var-blogger; } +.@{fa-css-prefix}-blogger-b:before { content: @fa-var-blogger-b; } +.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; } +.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; } +.@{fa-css-prefix}-bold:before { content: @fa-var-bold; } +.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; } +.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; } +.@{fa-css-prefix}-book:before { content: @fa-var-book; } +.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; } +.@{fa-css-prefix}-braille:before { content: @fa-var-braille; } +.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; } +.@{fa-css-prefix}-btc:before { content: @fa-var-btc; } +.@{fa-css-prefix}-bug:before { content: @fa-var-bug; } +.@{fa-css-prefix}-building:before { content: @fa-var-building; } +.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; } +.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; } +.@{fa-css-prefix}-buromobelexperte:before { content: @fa-var-buromobelexperte; } +.@{fa-css-prefix}-bus:before { content: @fa-var-bus; } +.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; } +.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; } +.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; } +.@{fa-css-prefix}-calendar-alt:before { content: @fa-var-calendar-alt; } +.@{fa-css-prefix}-calendar-check:before { content: @fa-var-calendar-check; } +.@{fa-css-prefix}-calendar-minus:before { content: @fa-var-calendar-minus; } +.@{fa-css-prefix}-calendar-plus:before { content: @fa-var-calendar-plus; } +.@{fa-css-prefix}-calendar-times:before { content: @fa-var-calendar-times; } +.@{fa-css-prefix}-camera:before { content: @fa-var-camera; } +.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; } +.@{fa-css-prefix}-car:before { content: @fa-var-car; } +.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; } +.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; } +.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; } +.@{fa-css-prefix}-caret-square-down:before { content: @fa-var-caret-square-down; } +.@{fa-css-prefix}-caret-square-left:before { content: @fa-var-caret-square-left; } +.@{fa-css-prefix}-caret-square-right:before { content: @fa-var-caret-square-right; } +.@{fa-css-prefix}-caret-square-up:before { content: @fa-var-caret-square-up; } +.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; } +.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; } +.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; } +.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; } +.@{fa-css-prefix}-cc-apple-pay:before { content: @fa-var-cc-apple-pay; } +.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; } +.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; } +.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; } +.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; } +.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; } +.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; } +.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; } +.@{fa-css-prefix}-centercode:before { content: @fa-var-centercode; } +.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; } +.@{fa-css-prefix}-chart-area:before { content: @fa-var-chart-area; } +.@{fa-css-prefix}-chart-bar:before { content: @fa-var-chart-bar; } +.@{fa-css-prefix}-chart-line:before { content: @fa-var-chart-line; } +.@{fa-css-prefix}-chart-pie:before { content: @fa-var-chart-pie; } +.@{fa-css-prefix}-check:before { content: @fa-var-check; } +.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; } +.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; } +.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; } +.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; } +.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; } +.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; } +.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; } +.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; } +.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; } +.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; } +.@{fa-css-prefix}-child:before { content: @fa-var-child; } +.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; } +.@{fa-css-prefix}-circle:before { content: @fa-var-circle; } +.@{fa-css-prefix}-circle-notch:before { content: @fa-var-circle-notch; } +.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; } +.@{fa-css-prefix}-clock:before { content: @fa-var-clock; } +.@{fa-css-prefix}-clone:before { content: @fa-var-clone; } +.@{fa-css-prefix}-closed-captioning:before { content: @fa-var-closed-captioning; } +.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; } +.@{fa-css-prefix}-cloud-download-alt:before { content: @fa-var-cloud-download-alt; } +.@{fa-css-prefix}-cloud-upload-alt:before { content: @fa-var-cloud-upload-alt; } +.@{fa-css-prefix}-cloudscale:before { content: @fa-var-cloudscale; } +.@{fa-css-prefix}-cloudsmith:before { content: @fa-var-cloudsmith; } +.@{fa-css-prefix}-cloudversify:before { content: @fa-var-cloudversify; } +.@{fa-css-prefix}-code:before { content: @fa-var-code; } +.@{fa-css-prefix}-code-branch:before { content: @fa-var-code-branch; } +.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; } +.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; } +.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; } +.@{fa-css-prefix}-cog:before { content: @fa-var-cog; } +.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; } +.@{fa-css-prefix}-columns:before { content: @fa-var-columns; } +.@{fa-css-prefix}-comment:before { content: @fa-var-comment; } +.@{fa-css-prefix}-comment-alt:before { content: @fa-var-comment-alt; } +.@{fa-css-prefix}-comments:before { content: @fa-var-comments; } +.@{fa-css-prefix}-compass:before { content: @fa-var-compass; } +.@{fa-css-prefix}-compress:before { content: @fa-var-compress; } +.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; } +.@{fa-css-prefix}-contao:before { content: @fa-var-contao; } +.@{fa-css-prefix}-copy:before { content: @fa-var-copy; } +.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; } +.@{fa-css-prefix}-cpanel:before { content: @fa-var-cpanel; } +.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; } +.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; } +.@{fa-css-prefix}-crop:before { content: @fa-var-crop; } +.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; } +.@{fa-css-prefix}-css3:before { content: @fa-var-css3; } +.@{fa-css-prefix}-css3-alt:before { content: @fa-var-css3-alt; } +.@{fa-css-prefix}-cube:before { content: @fa-var-cube; } +.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; } +.@{fa-css-prefix}-cut:before { content: @fa-var-cut; } +.@{fa-css-prefix}-cuttlefish:before { content: @fa-var-cuttlefish; } +.@{fa-css-prefix}-d-and-d:before { content: @fa-var-d-and-d; } +.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; } +.@{fa-css-prefix}-database:before { content: @fa-var-database; } +.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; } +.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; } +.@{fa-css-prefix}-deploydog:before { content: @fa-var-deploydog; } +.@{fa-css-prefix}-deskpro:before { content: @fa-var-deskpro; } +.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; } +.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; } +.@{fa-css-prefix}-digg:before { content: @fa-var-digg; } +.@{fa-css-prefix}-digital-ocean:before { content: @fa-var-digital-ocean; } +.@{fa-css-prefix}-discord:before { content: @fa-var-discord; } +.@{fa-css-prefix}-discourse:before { content: @fa-var-discourse; } +.@{fa-css-prefix}-dochub:before { content: @fa-var-dochub; } +.@{fa-css-prefix}-docker:before { content: @fa-var-docker; } +.@{fa-css-prefix}-dollar-sign:before { content: @fa-var-dollar-sign; } +.@{fa-css-prefix}-dot-circle:before { content: @fa-var-dot-circle; } +.@{fa-css-prefix}-download:before { content: @fa-var-download; } +.@{fa-css-prefix}-draft2digital:before { content: @fa-var-draft2digital; } +.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; } +.@{fa-css-prefix}-dribbble-square:before { content: @fa-var-dribbble-square; } +.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; } +.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; } +.@{fa-css-prefix}-dyalog:before { content: @fa-var-dyalog; } +.@{fa-css-prefix}-earlybirds:before { content: @fa-var-earlybirds; } +.@{fa-css-prefix}-edge:before { content: @fa-var-edge; } +.@{fa-css-prefix}-edit:before { content: @fa-var-edit; } +.@{fa-css-prefix}-eject:before { content: @fa-var-eject; } +.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; } +.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; } +.@{fa-css-prefix}-ember:before { content: @fa-var-ember; } +.@{fa-css-prefix}-empire:before { content: @fa-var-empire; } +.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; } +.@{fa-css-prefix}-envelope-open:before { content: @fa-var-envelope-open; } +.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; } +.@{fa-css-prefix}-envira:before { content: @fa-var-envira; } +.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; } +.@{fa-css-prefix}-erlang:before { content: @fa-var-erlang; } +.@{fa-css-prefix}-etsy:before { content: @fa-var-etsy; } +.@{fa-css-prefix}-euro-sign:before { content: @fa-var-euro-sign; } +.@{fa-css-prefix}-exchange-alt:before { content: @fa-var-exchange-alt; } +.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; } +.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; } +.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; } +.@{fa-css-prefix}-expand:before { content: @fa-var-expand; } +.@{fa-css-prefix}-expand-arrows-alt:before { content: @fa-var-expand-arrows-alt; } +.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; } +.@{fa-css-prefix}-external-link-alt:before { content: @fa-var-external-link-alt; } +.@{fa-css-prefix}-external-link-square-alt:before { content: @fa-var-external-link-square-alt; } +.@{fa-css-prefix}-eye:before { content: @fa-var-eye; } +.@{fa-css-prefix}-eye-dropper:before { content: @fa-var-eye-dropper; } +.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; } +.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; } +.@{fa-css-prefix}-facebook-f:before { content: @fa-var-facebook-f; } +.@{fa-css-prefix}-facebook-messenger:before { content: @fa-var-facebook-messenger; } +.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; } +.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; } +.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; } +.@{fa-css-prefix}-fax:before { content: @fa-var-fax; } +.@{fa-css-prefix}-female:before { content: @fa-var-female; } +.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; } +.@{fa-css-prefix}-file:before { content: @fa-var-file; } +.@{fa-css-prefix}-file-alt:before { content: @fa-var-file-alt; } +.@{fa-css-prefix}-file-archive:before { content: @fa-var-file-archive; } +.@{fa-css-prefix}-file-audio:before { content: @fa-var-file-audio; } +.@{fa-css-prefix}-file-code:before { content: @fa-var-file-code; } +.@{fa-css-prefix}-file-excel:before { content: @fa-var-file-excel; } +.@{fa-css-prefix}-file-image:before { content: @fa-var-file-image; } +.@{fa-css-prefix}-file-pdf:before { content: @fa-var-file-pdf; } +.@{fa-css-prefix}-file-powerpoint:before { content: @fa-var-file-powerpoint; } +.@{fa-css-prefix}-file-video:before { content: @fa-var-file-video; } +.@{fa-css-prefix}-file-word:before { content: @fa-var-file-word; } +.@{fa-css-prefix}-film:before { content: @fa-var-film; } +.@{fa-css-prefix}-filter:before { content: @fa-var-filter; } +.@{fa-css-prefix}-fire:before { content: @fa-var-fire; } +.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; } +.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; } +.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; } +.@{fa-css-prefix}-firstdraft:before { content: @fa-var-firstdraft; } +.@{fa-css-prefix}-flag:before { content: @fa-var-flag; } +.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; } +.@{fa-css-prefix}-flask:before { content: @fa-var-flask; } +.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; } +.@{fa-css-prefix}-fly:before { content: @fa-var-fly; } +.@{fa-css-prefix}-folder:before { content: @fa-var-folder; } +.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; } +.@{fa-css-prefix}-font:before { content: @fa-var-font; } +.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; } +.@{fa-css-prefix}-font-awesome-alt:before { content: @fa-var-font-awesome-alt; } +.@{fa-css-prefix}-font-awesome-flag:before { content: @fa-var-font-awesome-flag; } +.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; } +.@{fa-css-prefix}-fonticons-fi:before { content: @fa-var-fonticons-fi; } +.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; } +.@{fa-css-prefix}-fort-awesome-alt:before { content: @fa-var-fort-awesome-alt; } +.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; } +.@{fa-css-prefix}-forward:before { content: @fa-var-forward; } +.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; } +.@{fa-css-prefix}-free-code-camp:before { content: @fa-var-free-code-camp; } +.@{fa-css-prefix}-freebsd:before { content: @fa-var-freebsd; } +.@{fa-css-prefix}-frown:before { content: @fa-var-frown; } +.@{fa-css-prefix}-futbol:before { content: @fa-var-futbol; } +.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; } +.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; } +.@{fa-css-prefix}-gem:before { content: @fa-var-gem; } +.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; } +.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; } +.@{fa-css-prefix}-gg:before { content: @fa-var-gg; } +.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; } +.@{fa-css-prefix}-gift:before { content: @fa-var-gift; } +.@{fa-css-prefix}-git:before { content: @fa-var-git; } +.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; } +.@{fa-css-prefix}-github:before { content: @fa-var-github; } +.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; } +.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; } +.@{fa-css-prefix}-gitkraken:before { content: @fa-var-gitkraken; } +.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; } +.@{fa-css-prefix}-gitter:before { content: @fa-var-gitter; } +.@{fa-css-prefix}-glass-martini:before { content: @fa-var-glass-martini; } +.@{fa-css-prefix}-glide:before { content: @fa-var-glide; } +.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; } +.@{fa-css-prefix}-globe:before { content: @fa-var-globe; } +.@{fa-css-prefix}-gofore:before { content: @fa-var-gofore; } +.@{fa-css-prefix}-goodreads:before { content: @fa-var-goodreads; } +.@{fa-css-prefix}-goodreads-g:before { content: @fa-var-goodreads-g; } +.@{fa-css-prefix}-google:before { content: @fa-var-google; } +.@{fa-css-prefix}-google-drive:before { content: @fa-var-google-drive; } +.@{fa-css-prefix}-google-play:before { content: @fa-var-google-play; } +.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; } +.@{fa-css-prefix}-google-plus-g:before { content: @fa-var-google-plus-g; } +.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; } +.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; } +.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; } +.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; } +.@{fa-css-prefix}-grav:before { content: @fa-var-grav; } +.@{fa-css-prefix}-gripfire:before { content: @fa-var-gripfire; } +.@{fa-css-prefix}-grunt:before { content: @fa-var-grunt; } +.@{fa-css-prefix}-gulp:before { content: @fa-var-gulp; } +.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; } +.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; } +.@{fa-css-prefix}-hacker-news-square:before { content: @fa-var-hacker-news-square; } +.@{fa-css-prefix}-hand-lizard:before { content: @fa-var-hand-lizard; } +.@{fa-css-prefix}-hand-paper:before { content: @fa-var-hand-paper; } +.@{fa-css-prefix}-hand-peace:before { content: @fa-var-hand-peace; } +.@{fa-css-prefix}-hand-point-down:before { content: @fa-var-hand-point-down; } +.@{fa-css-prefix}-hand-point-left:before { content: @fa-var-hand-point-left; } +.@{fa-css-prefix}-hand-point-right:before { content: @fa-var-hand-point-right; } +.@{fa-css-prefix}-hand-point-up:before { content: @fa-var-hand-point-up; } +.@{fa-css-prefix}-hand-pointer:before { content: @fa-var-hand-pointer; } +.@{fa-css-prefix}-hand-rock:before { content: @fa-var-hand-rock; } +.@{fa-css-prefix}-hand-scissors:before { content: @fa-var-hand-scissors; } +.@{fa-css-prefix}-hand-spock:before { content: @fa-var-hand-spock; } +.@{fa-css-prefix}-handshake:before { content: @fa-var-handshake; } +.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; } +.@{fa-css-prefix}-hdd:before { content: @fa-var-hdd; } +.@{fa-css-prefix}-heading:before { content: @fa-var-heading; } +.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; } +.@{fa-css-prefix}-heart:before { content: @fa-var-heart; } +.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; } +.@{fa-css-prefix}-hire-a-helper:before { content: @fa-var-hire-a-helper; } +.@{fa-css-prefix}-history:before { content: @fa-var-history; } +.@{fa-css-prefix}-home:before { content: @fa-var-home; } +.@{fa-css-prefix}-hooli:before { content: @fa-var-hooli; } +.@{fa-css-prefix}-hospital:before { content: @fa-var-hospital; } +.@{fa-css-prefix}-hotjar:before { content: @fa-var-hotjar; } +.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; } +.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; } +.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; } +.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; } +.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; } +.@{fa-css-prefix}-html5:before { content: @fa-var-html5; } +.@{fa-css-prefix}-hubspot:before { content: @fa-var-hubspot; } +.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; } +.@{fa-css-prefix}-id-badge:before { content: @fa-var-id-badge; } +.@{fa-css-prefix}-id-card:before { content: @fa-var-id-card; } +.@{fa-css-prefix}-image:before { content: @fa-var-image; } +.@{fa-css-prefix}-images:before { content: @fa-var-images; } +.@{fa-css-prefix}-imdb:before { content: @fa-var-imdb; } +.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; } +.@{fa-css-prefix}-indent:before { content: @fa-var-indent; } +.@{fa-css-prefix}-industry:before { content: @fa-var-industry; } +.@{fa-css-prefix}-info:before { content: @fa-var-info; } +.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; } +.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; } +.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; } +.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; } +.@{fa-css-prefix}-italic:before { content: @fa-var-italic; } +.@{fa-css-prefix}-itunes:before { content: @fa-var-itunes; } +.@{fa-css-prefix}-itunes-note:before { content: @fa-var-itunes-note; } +.@{fa-css-prefix}-jenkins:before { content: @fa-var-jenkins; } +.@{fa-css-prefix}-joget:before { content: @fa-var-joget; } +.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; } +.@{fa-css-prefix}-js:before { content: @fa-var-js; } +.@{fa-css-prefix}-js-square:before { content: @fa-var-js-square; } +.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; } +.@{fa-css-prefix}-key:before { content: @fa-var-key; } +.@{fa-css-prefix}-keyboard:before { content: @fa-var-keyboard; } +.@{fa-css-prefix}-keycdn:before { content: @fa-var-keycdn; } +.@{fa-css-prefix}-kickstarter:before { content: @fa-var-kickstarter; } +.@{fa-css-prefix}-kickstarter-k:before { content: @fa-var-kickstarter-k; } +.@{fa-css-prefix}-language:before { content: @fa-var-language; } +.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; } +.@{fa-css-prefix}-laravel:before { content: @fa-var-laravel; } +.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; } +.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; } +.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; } +.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; } +.@{fa-css-prefix}-lemon:before { content: @fa-var-lemon; } +.@{fa-css-prefix}-less:before { content: @fa-var-less; } +.@{fa-css-prefix}-level-down-alt:before { content: @fa-var-level-down-alt; } +.@{fa-css-prefix}-level-up-alt:before { content: @fa-var-level-up-alt; } +.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; } +.@{fa-css-prefix}-lightbulb:before { content: @fa-var-lightbulb; } +.@{fa-css-prefix}-line:before { content: @fa-var-line; } +.@{fa-css-prefix}-link:before { content: @fa-var-link; } +.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; } +.@{fa-css-prefix}-linkedin-in:before { content: @fa-var-linkedin-in; } +.@{fa-css-prefix}-linode:before { content: @fa-var-linode; } +.@{fa-css-prefix}-linux:before { content: @fa-var-linux; } +.@{fa-css-prefix}-lira-sign:before { content: @fa-var-lira-sign; } +.@{fa-css-prefix}-list:before { content: @fa-var-list; } +.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; } +.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; } +.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; } +.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; } +.@{fa-css-prefix}-lock:before { content: @fa-var-lock; } +.@{fa-css-prefix}-lock-open:before { content: @fa-var-lock-open; } +.@{fa-css-prefix}-long-arrow-alt-down:before { content: @fa-var-long-arrow-alt-down; } +.@{fa-css-prefix}-long-arrow-alt-left:before { content: @fa-var-long-arrow-alt-left; } +.@{fa-css-prefix}-long-arrow-alt-right:before { content: @fa-var-long-arrow-alt-right; } +.@{fa-css-prefix}-long-arrow-alt-up:before { content: @fa-var-long-arrow-alt-up; } +.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; } +.@{fa-css-prefix}-lyft:before { content: @fa-var-lyft; } +.@{fa-css-prefix}-magento:before { content: @fa-var-magento; } +.@{fa-css-prefix}-magic:before { content: @fa-var-magic; } +.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; } +.@{fa-css-prefix}-male:before { content: @fa-var-male; } +.@{fa-css-prefix}-map:before { content: @fa-var-map; } +.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; } +.@{fa-css-prefix}-map-marker-alt:before { content: @fa-var-map-marker-alt; } +.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; } +.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; } +.@{fa-css-prefix}-mars:before { content: @fa-var-mars; } +.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; } +.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; } +.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; } +.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; } +.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; } +.@{fa-css-prefix}-medapps:before { content: @fa-var-medapps; } +.@{fa-css-prefix}-medium:before { content: @fa-var-medium; } +.@{fa-css-prefix}-medium-m:before { content: @fa-var-medium-m; } +.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; } +.@{fa-css-prefix}-medrt:before { content: @fa-var-medrt; } +.@{fa-css-prefix}-meetup:before { content: @fa-var-meetup; } +.@{fa-css-prefix}-meh:before { content: @fa-var-meh; } +.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; } +.@{fa-css-prefix}-microchip:before { content: @fa-var-microchip; } +.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; } +.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; } +.@{fa-css-prefix}-microsoft:before { content: @fa-var-microsoft; } +.@{fa-css-prefix}-minus:before { content: @fa-var-minus; } +.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; } +.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; } +.@{fa-css-prefix}-mix:before { content: @fa-var-mix; } +.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; } +.@{fa-css-prefix}-mizuni:before { content: @fa-var-mizuni; } +.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; } +.@{fa-css-prefix}-mobile-alt:before { content: @fa-var-mobile-alt; } +.@{fa-css-prefix}-modx:before { content: @fa-var-modx; } +.@{fa-css-prefix}-monero:before { content: @fa-var-monero; } +.@{fa-css-prefix}-money-bill-alt:before { content: @fa-var-money-bill-alt; } +.@{fa-css-prefix}-moon:before { content: @fa-var-moon; } +.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; } +.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; } +.@{fa-css-prefix}-music:before { content: @fa-var-music; } +.@{fa-css-prefix}-napster:before { content: @fa-var-napster; } +.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; } +.@{fa-css-prefix}-newspaper:before { content: @fa-var-newspaper; } +.@{fa-css-prefix}-nintendo-switch:before { content: @fa-var-nintendo-switch; } +.@{fa-css-prefix}-node:before { content: @fa-var-node; } +.@{fa-css-prefix}-node-js:before { content: @fa-var-node-js; } +.@{fa-css-prefix}-npm:before { content: @fa-var-npm; } +.@{fa-css-prefix}-ns8:before { content: @fa-var-ns8; } +.@{fa-css-prefix}-nutritionix:before { content: @fa-var-nutritionix; } +.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; } +.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; } +.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; } +.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; } +.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; } +.@{fa-css-prefix}-openid:before { content: @fa-var-openid; } +.@{fa-css-prefix}-opera:before { content: @fa-var-opera; } +.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; } +.@{fa-css-prefix}-osi:before { content: @fa-var-osi; } +.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; } +.@{fa-css-prefix}-page4:before { content: @fa-var-page4; } +.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; } +.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; } +.@{fa-css-prefix}-palfed:before { content: @fa-var-palfed; } +.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; } +.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; } +.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; } +.@{fa-css-prefix}-paste:before { content: @fa-var-paste; } +.@{fa-css-prefix}-patreon:before { content: @fa-var-patreon; } +.@{fa-css-prefix}-pause:before { content: @fa-var-pause; } +.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; } +.@{fa-css-prefix}-paw:before { content: @fa-var-paw; } +.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; } +.@{fa-css-prefix}-pen-square:before { content: @fa-var-pen-square; } +.@{fa-css-prefix}-pencil-alt:before { content: @fa-var-pencil-alt; } +.@{fa-css-prefix}-percent:before { content: @fa-var-percent; } +.@{fa-css-prefix}-periscope:before { content: @fa-var-periscope; } +.@{fa-css-prefix}-phabricator:before { content: @fa-var-phabricator; } +.@{fa-css-prefix}-phoenix-framework:before { content: @fa-var-phoenix-framework; } +.@{fa-css-prefix}-phone:before { content: @fa-var-phone; } +.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; } +.@{fa-css-prefix}-phone-volume:before { content: @fa-var-phone-volume; } +.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; } +.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; } +.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; } +.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; } +.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; } +.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; } +.@{fa-css-prefix}-plane:before { content: @fa-var-plane; } +.@{fa-css-prefix}-play:before { content: @fa-var-play; } +.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; } +.@{fa-css-prefix}-playstation:before { content: @fa-var-playstation; } +.@{fa-css-prefix}-plug:before { content: @fa-var-plug; } +.@{fa-css-prefix}-plus:before { content: @fa-var-plus; } +.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; } +.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; } +.@{fa-css-prefix}-podcast:before { content: @fa-var-podcast; } +.@{fa-css-prefix}-pound-sign:before { content: @fa-var-pound-sign; } +.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; } +.@{fa-css-prefix}-print:before { content: @fa-var-print; } +.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; } +.@{fa-css-prefix}-pushed:before { content: @fa-var-pushed; } +.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; } +.@{fa-css-prefix}-python:before { content: @fa-var-python; } +.@{fa-css-prefix}-qq:before { content: @fa-var-qq; } +.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; } +.@{fa-css-prefix}-question:before { content: @fa-var-question; } +.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; } +.@{fa-css-prefix}-quora:before { content: @fa-var-quora; } +.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; } +.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; } +.@{fa-css-prefix}-random:before { content: @fa-var-random; } +.@{fa-css-prefix}-ravelry:before { content: @fa-var-ravelry; } +.@{fa-css-prefix}-react:before { content: @fa-var-react; } +.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; } +.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; } +.@{fa-css-prefix}-red-river:before { content: @fa-var-red-river; } +.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; } +.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; } +.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; } +.@{fa-css-prefix}-redo:before { content: @fa-var-redo; } +.@{fa-css-prefix}-redo-alt:before { content: @fa-var-redo-alt; } +.@{fa-css-prefix}-registered:before { content: @fa-var-registered; } +.@{fa-css-prefix}-rendact:before { content: @fa-var-rendact; } +.@{fa-css-prefix}-renren:before { content: @fa-var-renren; } +.@{fa-css-prefix}-reply:before { content: @fa-var-reply; } +.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; } +.@{fa-css-prefix}-replyd:before { content: @fa-var-replyd; } +.@{fa-css-prefix}-resolving:before { content: @fa-var-resolving; } +.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; } +.@{fa-css-prefix}-road:before { content: @fa-var-road; } +.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; } +.@{fa-css-prefix}-rocketchat:before { content: @fa-var-rocketchat; } +.@{fa-css-prefix}-rockrms:before { content: @fa-var-rockrms; } +.@{fa-css-prefix}-rss:before { content: @fa-var-rss; } +.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; } +.@{fa-css-prefix}-ruble-sign:before { content: @fa-var-ruble-sign; } +.@{fa-css-prefix}-rupee-sign:before { content: @fa-var-rupee-sign; } +.@{fa-css-prefix}-safari:before { content: @fa-var-safari; } +.@{fa-css-prefix}-sass:before { content: @fa-var-sass; } +.@{fa-css-prefix}-save:before { content: @fa-var-save; } +.@{fa-css-prefix}-schlix:before { content: @fa-var-schlix; } +.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; } +.@{fa-css-prefix}-search:before { content: @fa-var-search; } +.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; } +.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; } +.@{fa-css-prefix}-searchengin:before { content: @fa-var-searchengin; } +.@{fa-css-prefix}-sellcast:before { content: @fa-var-sellcast; } +.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; } +.@{fa-css-prefix}-server:before { content: @fa-var-server; } +.@{fa-css-prefix}-servicestack:before { content: @fa-var-servicestack; } +.@{fa-css-prefix}-share:before { content: @fa-var-share; } +.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; } +.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; } +.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; } +.@{fa-css-prefix}-shekel-sign:before { content: @fa-var-shekel-sign; } +.@{fa-css-prefix}-shield-alt:before { content: @fa-var-shield-alt; } +.@{fa-css-prefix}-ship:before { content: @fa-var-ship; } +.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; } +.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; } +.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; } +.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; } +.@{fa-css-prefix}-shower:before { content: @fa-var-shower; } +.@{fa-css-prefix}-sign-in-alt:before { content: @fa-var-sign-in-alt; } +.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; } +.@{fa-css-prefix}-sign-out-alt:before { content: @fa-var-sign-out-alt; } +.@{fa-css-prefix}-signal:before { content: @fa-var-signal; } +.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; } +.@{fa-css-prefix}-sistrix:before { content: @fa-var-sistrix; } +.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; } +.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; } +.@{fa-css-prefix}-skype:before { content: @fa-var-skype; } +.@{fa-css-prefix}-slack:before { content: @fa-var-slack; } +.@{fa-css-prefix}-slack-hash:before { content: @fa-var-slack-hash; } +.@{fa-css-prefix}-sliders-h:before { content: @fa-var-sliders-h; } +.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; } +.@{fa-css-prefix}-smile:before { content: @fa-var-smile; } +.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; } +.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; } +.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; } +.@{fa-css-prefix}-snowflake:before { content: @fa-var-snowflake; } +.@{fa-css-prefix}-sort:before { content: @fa-var-sort; } +.@{fa-css-prefix}-sort-alpha-down:before { content: @fa-var-sort-alpha-down; } +.@{fa-css-prefix}-sort-alpha-up:before { content: @fa-var-sort-alpha-up; } +.@{fa-css-prefix}-sort-amount-down:before { content: @fa-var-sort-amount-down; } +.@{fa-css-prefix}-sort-amount-up:before { content: @fa-var-sort-amount-up; } +.@{fa-css-prefix}-sort-down:before { content: @fa-var-sort-down; } +.@{fa-css-prefix}-sort-numeric-down:before { content: @fa-var-sort-numeric-down; } +.@{fa-css-prefix}-sort-numeric-up:before { content: @fa-var-sort-numeric-up; } +.@{fa-css-prefix}-sort-up:before { content: @fa-var-sort-up; } +.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; } +.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; } +.@{fa-css-prefix}-speakap:before { content: @fa-var-speakap; } +.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; } +.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; } +.@{fa-css-prefix}-square:before { content: @fa-var-square; } +.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; } +.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; } +.@{fa-css-prefix}-star:before { content: @fa-var-star; } +.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; } +.@{fa-css-prefix}-staylinked:before { content: @fa-var-staylinked; } +.@{fa-css-prefix}-steam:before { content: @fa-var-steam; } +.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; } +.@{fa-css-prefix}-steam-symbol:before { content: @fa-var-steam-symbol; } +.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; } +.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; } +.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; } +.@{fa-css-prefix}-sticker-mule:before { content: @fa-var-sticker-mule; } +.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; } +.@{fa-css-prefix}-stop:before { content: @fa-var-stop; } +.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; } +.@{fa-css-prefix}-strava:before { content: @fa-var-strava; } +.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; } +.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; } +.@{fa-css-prefix}-stripe:before { content: @fa-var-stripe; } +.@{fa-css-prefix}-stripe-s:before { content: @fa-var-stripe-s; } +.@{fa-css-prefix}-studiovinari:before { content: @fa-var-studiovinari; } +.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; } +.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; } +.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; } +.@{fa-css-prefix}-subway:before { content: @fa-var-subway; } +.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; } +.@{fa-css-prefix}-sun:before { content: @fa-var-sun; } +.@{fa-css-prefix}-superpowers:before { content: @fa-var-superpowers; } +.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; } +.@{fa-css-prefix}-supple:before { content: @fa-var-supple; } +.@{fa-css-prefix}-sync:before { content: @fa-var-sync; } +.@{fa-css-prefix}-sync-alt:before { content: @fa-var-sync-alt; } +.@{fa-css-prefix}-table:before { content: @fa-var-table; } +.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; } +.@{fa-css-prefix}-tablet-alt:before { content: @fa-var-tablet-alt; } +.@{fa-css-prefix}-tachometer-alt:before { content: @fa-var-tachometer-alt; } +.@{fa-css-prefix}-tag:before { content: @fa-var-tag; } +.@{fa-css-prefix}-tags:before { content: @fa-var-tags; } +.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; } +.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; } +.@{fa-css-prefix}-telegram:before { content: @fa-var-telegram; } +.@{fa-css-prefix}-telegram-plane:before { content: @fa-var-telegram-plane; } +.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; } +.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; } +.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; } +.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; } +.@{fa-css-prefix}-th:before { content: @fa-var-th; } +.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; } +.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; } +.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; } +.@{fa-css-prefix}-thermometer-empty:before { content: @fa-var-thermometer-empty; } +.@{fa-css-prefix}-thermometer-full:before { content: @fa-var-thermometer-full; } +.@{fa-css-prefix}-thermometer-half:before { content: @fa-var-thermometer-half; } +.@{fa-css-prefix}-thermometer-quarter:before { content: @fa-var-thermometer-quarter; } +.@{fa-css-prefix}-thermometer-three-quarters:before { content: @fa-var-thermometer-three-quarters; } +.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; } +.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; } +.@{fa-css-prefix}-thumbtack:before { content: @fa-var-thumbtack; } +.@{fa-css-prefix}-ticket-alt:before { content: @fa-var-ticket-alt; } +.@{fa-css-prefix}-times:before { content: @fa-var-times; } +.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; } +.@{fa-css-prefix}-tint:before { content: @fa-var-tint; } +.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; } +.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; } +.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; } +.@{fa-css-prefix}-train:before { content: @fa-var-train; } +.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; } +.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; } +.@{fa-css-prefix}-trash:before { content: @fa-var-trash; } +.@{fa-css-prefix}-trash-alt:before { content: @fa-var-trash-alt; } +.@{fa-css-prefix}-tree:before { content: @fa-var-tree; } +.@{fa-css-prefix}-trello:before { content: @fa-var-trello; } +.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; } +.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; } +.@{fa-css-prefix}-truck:before { content: @fa-var-truck; } +.@{fa-css-prefix}-tty:before { content: @fa-var-tty; } +.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; } +.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; } +.@{fa-css-prefix}-tv:before { content: @fa-var-tv; } +.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; } +.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; } +.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; } +.@{fa-css-prefix}-typo3:before { content: @fa-var-typo3; } +.@{fa-css-prefix}-uber:before { content: @fa-var-uber; } +.@{fa-css-prefix}-uikit:before { content: @fa-var-uikit; } +.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; } +.@{fa-css-prefix}-underline:before { content: @fa-var-underline; } +.@{fa-css-prefix}-undo:before { content: @fa-var-undo; } +.@{fa-css-prefix}-undo-alt:before { content: @fa-var-undo-alt; } +.@{fa-css-prefix}-uniregistry:before { content: @fa-var-uniregistry; } +.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; } +.@{fa-css-prefix}-university:before { content: @fa-var-university; } +.@{fa-css-prefix}-unlink:before { content: @fa-var-unlink; } +.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; } +.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; } +.@{fa-css-prefix}-untappd:before { content: @fa-var-untappd; } +.@{fa-css-prefix}-upload:before { content: @fa-var-upload; } +.@{fa-css-prefix}-usb:before { content: @fa-var-usb; } +.@{fa-css-prefix}-user:before { content: @fa-var-user; } +.@{fa-css-prefix}-user-circle:before { content: @fa-var-user-circle; } +.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; } +.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; } +.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; } +.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; } +.@{fa-css-prefix}-users:before { content: @fa-var-users; } +.@{fa-css-prefix}-ussunnah:before { content: @fa-var-ussunnah; } +.@{fa-css-prefix}-utensil-spoon:before { content: @fa-var-utensil-spoon; } +.@{fa-css-prefix}-utensils:before { content: @fa-var-utensils; } +.@{fa-css-prefix}-vaadin:before { content: @fa-var-vaadin; } +.@{fa-css-prefix}-venus:before { content: @fa-var-venus; } +.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; } +.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; } +.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; } +.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; } +.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; } +.@{fa-css-prefix}-viber:before { content: @fa-var-viber; } +.@{fa-css-prefix}-video:before { content: @fa-var-video; } +.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; } +.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; } +.@{fa-css-prefix}-vimeo-v:before { content: @fa-var-vimeo-v; } +.@{fa-css-prefix}-vine:before { content: @fa-var-vine; } +.@{fa-css-prefix}-vk:before { content: @fa-var-vk; } +.@{fa-css-prefix}-vnv:before { content: @fa-var-vnv; } +.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; } +.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; } +.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; } +.@{fa-css-prefix}-vuejs:before { content: @fa-var-vuejs; } +.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; } +.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; } +.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; } +.@{fa-css-prefix}-whatsapp-square:before { content: @fa-var-whatsapp-square; } +.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; } +.@{fa-css-prefix}-whmcs:before { content: @fa-var-whmcs; } +.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; } +.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; } +.@{fa-css-prefix}-window-close:before { content: @fa-var-window-close; } +.@{fa-css-prefix}-window-maximize:before { content: @fa-var-window-maximize; } +.@{fa-css-prefix}-window-minimize:before { content: @fa-var-window-minimize; } +.@{fa-css-prefix}-window-restore:before { content: @fa-var-window-restore; } +.@{fa-css-prefix}-windows:before { content: @fa-var-windows; } +.@{fa-css-prefix}-won-sign:before { content: @fa-var-won-sign; } +.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; } +.@{fa-css-prefix}-wordpress-simple:before { content: @fa-var-wordpress-simple; } +.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; } +.@{fa-css-prefix}-wpexplorer:before { content: @fa-var-wpexplorer; } +.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; } +.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; } +.@{fa-css-prefix}-xbox:before { content: @fa-var-xbox; } +.@{fa-css-prefix}-xing:before { content: @fa-var-xing; } +.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; } +.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; } +.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; } +.@{fa-css-prefix}-yandex:before { content: @fa-var-yandex; } +.@{fa-css-prefix}-yandex-international:before { content: @fa-var-yandex-international; } +.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; } +.@{fa-css-prefix}-yen-sign:before { content: @fa-var-yen-sign; } +.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; } +.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_larger.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_larger.less new file mode 100644 index 000000000..6cbb1ec6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_larger.less @@ -0,0 +1,27 @@ +// Icon Sizes +// ------------------------- + +.larger(@factor) when (@factor > 0) { + .larger((@factor - 1)); + + .@{fa-css-prefix}-@{factor}x { + font-size: (@factor * 1em); + } +} + +/* makes the font 33% larger relative to the icon container */ +.@{fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -.0667em; +} + +.@{fa-css-prefix}-xs { + font-size: .75em; +} + +.@{fa-css-prefix}-sm { + font-size: .875em; +} + +.larger(10); diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_list.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_list.less new file mode 100644 index 000000000..1ff7ca7f5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_list.less @@ -0,0 +1,18 @@ +// List Icons +// ------------------------- + +.@{fa-css-prefix}-ul { + list-style-type: none; + margin-left: @fa-li-width * 5/4; + padding-left: 0; + + > li { position: relative; } +} + +.@{fa-css-prefix}-li { + left: -@fa-li-width; + position: absolute; + text-align: center; + width: @fa-li-width; + line-height: inherit; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_mixins.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_mixins.less new file mode 100644 index 000000000..9404c7cc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_mixins.less @@ -0,0 +1,57 @@ +// Mixins +// -------------------------- + +.fa-icon() { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + vertical-align: -15%; +} + +.fa-icon-rotate(@degrees, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; + transform: rotate(@degrees); +} + +.fa-icon-flip(@horiz, @vert, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; + transform: scale(@horiz, @vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +.sr-only() { + border: 0; + clip: rect(0,0,0,0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +.sr-only-focusable() { + &:active, + &:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_rotated-flipped.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_rotated-flipped.less new file mode 100644 index 000000000..1ee31db19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_rotated-flipped.less @@ -0,0 +1,23 @@ +// Rotated & Flipped Icons +// ------------------------- + +.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } +.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } +.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } + +.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } +.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } +.@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root { + .@{fa-css-prefix}-rotate-90, + .@{fa-css-prefix}-rotate-180, + .@{fa-css-prefix}-rotate-270, + .@{fa-css-prefix}-flip-horizontal, + .@{fa-css-prefix}-flip-vertical { + filter: none; + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_screen-reader.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_screen-reader.less new file mode 100644 index 000000000..11c188196 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_screen-reader.less @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { .sr-only(); } +.sr-only-focusable { .sr-only-focusable(); } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_stacked.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_stacked.less new file mode 100644 index 000000000..263b5c44f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_stacked.less @@ -0,0 +1,22 @@ +// Stacked Icons +// ------------------------- + +.@{fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; +} + +.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; +} + +.@{fa-css-prefix}-stack-1x { line-height: inherit; } +.@{fa-css-prefix}-stack-2x { font-size: 2em; } +.@{fa-css-prefix}-inverse { color: @fa-inverse; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_variables.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_variables.less new file mode 100644 index 000000000..b3d88af2f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/_variables.less @@ -0,0 +1,796 @@ +// Variables +// -------------------------- + +@fa-font-path: "../webfonts"; +@fa-font-size-base: 16px; +@fa-line-height-base: 1; +@fa-css-prefix: fa; +@fa-version: "5.0.0"; +@fa-border-color: #eee; +@fa-inverse: #fff; +@fa-li-width: 2em; + +@fa-var-500px: "\f26e"; +@fa-var-accessible-icon: "\f368"; +@fa-var-accusoft: "\f369"; +@fa-var-address-book: "\f2b9"; +@fa-var-address-card: "\f2bb"; +@fa-var-adjust: "\f042"; +@fa-var-adn: "\f170"; +@fa-var-adversal: "\f36a"; +@fa-var-affiliatetheme: "\f36b"; +@fa-var-algolia: "\f36c"; +@fa-var-align-center: "\f037"; +@fa-var-align-justify: "\f039"; +@fa-var-align-left: "\f036"; +@fa-var-align-right: "\f038"; +@fa-var-amazon: "\f270"; +@fa-var-ambulance: "\f0f9"; +@fa-var-american-sign-language-interpreting: "\f2a3"; +@fa-var-amilia: "\f36d"; +@fa-var-anchor: "\f13d"; +@fa-var-android: "\f17b"; +@fa-var-angellist: "\f209"; +@fa-var-angle-double-down: "\f103"; +@fa-var-angle-double-left: "\f100"; +@fa-var-angle-double-right: "\f101"; +@fa-var-angle-double-up: "\f102"; +@fa-var-angle-down: "\f107"; +@fa-var-angle-left: "\f104"; +@fa-var-angle-right: "\f105"; +@fa-var-angle-up: "\f106"; +@fa-var-angrycreative: "\f36e"; +@fa-var-angular: "\f420"; +@fa-var-app-store: "\f36f"; +@fa-var-app-store-ios: "\f370"; +@fa-var-apper: "\f371"; +@fa-var-apple: "\f179"; +@fa-var-apple-pay: "\f415"; +@fa-var-archive: "\f187"; +@fa-var-arrow-alt-circle-down: "\f358"; +@fa-var-arrow-alt-circle-left: "\f359"; +@fa-var-arrow-alt-circle-right: "\f35a"; +@fa-var-arrow-alt-circle-up: "\f35b"; +@fa-var-arrow-circle-down: "\f0ab"; +@fa-var-arrow-circle-left: "\f0a8"; +@fa-var-arrow-circle-right: "\f0a9"; +@fa-var-arrow-circle-up: "\f0aa"; +@fa-var-arrow-down: "\f063"; +@fa-var-arrow-left: "\f060"; +@fa-var-arrow-right: "\f061"; +@fa-var-arrow-up: "\f062"; +@fa-var-arrows-alt: "\f0b2"; +@fa-var-arrows-alt-h: "\f337"; +@fa-var-arrows-alt-v: "\f338"; +@fa-var-assistive-listening-systems: "\f2a2"; +@fa-var-asterisk: "\f069"; +@fa-var-asymmetrik: "\f372"; +@fa-var-at: "\f1fa"; +@fa-var-audible: "\f373"; +@fa-var-audio-description: "\f29e"; +@fa-var-autoprefixer: "\f41c"; +@fa-var-avianex: "\f374"; +@fa-var-aviato: "\f421"; +@fa-var-aws: "\f375"; +@fa-var-backward: "\f04a"; +@fa-var-balance-scale: "\f24e"; +@fa-var-ban: "\f05e"; +@fa-var-bandcamp: "\f2d5"; +@fa-var-barcode: "\f02a"; +@fa-var-bars: "\f0c9"; +@fa-var-bath: "\f2cd"; +@fa-var-battery-empty: "\f244"; +@fa-var-battery-full: "\f240"; +@fa-var-battery-half: "\f242"; +@fa-var-battery-quarter: "\f243"; +@fa-var-battery-three-quarters: "\f241"; +@fa-var-bed: "\f236"; +@fa-var-beer: "\f0fc"; +@fa-var-behance: "\f1b4"; +@fa-var-behance-square: "\f1b5"; +@fa-var-bell: "\f0f3"; +@fa-var-bell-slash: "\f1f6"; +@fa-var-bicycle: "\f206"; +@fa-var-bimobject: "\f378"; +@fa-var-binoculars: "\f1e5"; +@fa-var-birthday-cake: "\f1fd"; +@fa-var-bitbucket: "\f171"; +@fa-var-bitcoin: "\f379"; +@fa-var-bity: "\f37a"; +@fa-var-black-tie: "\f27e"; +@fa-var-blackberry: "\f37b"; +@fa-var-blind: "\f29d"; +@fa-var-blogger: "\f37c"; +@fa-var-blogger-b: "\f37d"; +@fa-var-bluetooth: "\f293"; +@fa-var-bluetooth-b: "\f294"; +@fa-var-bold: "\f032"; +@fa-var-bolt: "\f0e7"; +@fa-var-bomb: "\f1e2"; +@fa-var-book: "\f02d"; +@fa-var-bookmark: "\f02e"; +@fa-var-braille: "\f2a1"; +@fa-var-briefcase: "\f0b1"; +@fa-var-btc: "\f15a"; +@fa-var-bug: "\f188"; +@fa-var-building: "\f1ad"; +@fa-var-bullhorn: "\f0a1"; +@fa-var-bullseye: "\f140"; +@fa-var-buromobelexperte: "\f37f"; +@fa-var-bus: "\f207"; +@fa-var-buysellads: "\f20d"; +@fa-var-calculator: "\f1ec"; +@fa-var-calendar: "\f133"; +@fa-var-calendar-alt: "\f073"; +@fa-var-calendar-check: "\f274"; +@fa-var-calendar-minus: "\f272"; +@fa-var-calendar-plus: "\f271"; +@fa-var-calendar-times: "\f273"; +@fa-var-camera: "\f030"; +@fa-var-camera-retro: "\f083"; +@fa-var-car: "\f1b9"; +@fa-var-caret-down: "\f0d7"; +@fa-var-caret-left: "\f0d9"; +@fa-var-caret-right: "\f0da"; +@fa-var-caret-square-down: "\f150"; +@fa-var-caret-square-left: "\f191"; +@fa-var-caret-square-right: "\f152"; +@fa-var-caret-square-up: "\f151"; +@fa-var-caret-up: "\f0d8"; +@fa-var-cart-arrow-down: "\f218"; +@fa-var-cart-plus: "\f217"; +@fa-var-cc-amex: "\f1f3"; +@fa-var-cc-apple-pay: "\f416"; +@fa-var-cc-diners-club: "\f24c"; +@fa-var-cc-discover: "\f1f2"; +@fa-var-cc-jcb: "\f24b"; +@fa-var-cc-mastercard: "\f1f1"; +@fa-var-cc-paypal: "\f1f4"; +@fa-var-cc-stripe: "\f1f5"; +@fa-var-cc-visa: "\f1f0"; +@fa-var-centercode: "\f380"; +@fa-var-certificate: "\f0a3"; +@fa-var-chart-area: "\f1fe"; +@fa-var-chart-bar: "\f080"; +@fa-var-chart-line: "\f201"; +@fa-var-chart-pie: "\f200"; +@fa-var-check: "\f00c"; +@fa-var-check-circle: "\f058"; +@fa-var-check-square: "\f14a"; +@fa-var-chevron-circle-down: "\f13a"; +@fa-var-chevron-circle-left: "\f137"; +@fa-var-chevron-circle-right: "\f138"; +@fa-var-chevron-circle-up: "\f139"; +@fa-var-chevron-down: "\f078"; +@fa-var-chevron-left: "\f053"; +@fa-var-chevron-right: "\f054"; +@fa-var-chevron-up: "\f077"; +@fa-var-child: "\f1ae"; +@fa-var-chrome: "\f268"; +@fa-var-circle: "\f111"; +@fa-var-circle-notch: "\f1ce"; +@fa-var-clipboard: "\f328"; +@fa-var-clock: "\f017"; +@fa-var-clone: "\f24d"; +@fa-var-closed-captioning: "\f20a"; +@fa-var-cloud: "\f0c2"; +@fa-var-cloud-download-alt: "\f381"; +@fa-var-cloud-upload-alt: "\f382"; +@fa-var-cloudscale: "\f383"; +@fa-var-cloudsmith: "\f384"; +@fa-var-cloudversify: "\f385"; +@fa-var-code: "\f121"; +@fa-var-code-branch: "\f126"; +@fa-var-codepen: "\f1cb"; +@fa-var-codiepie: "\f284"; +@fa-var-coffee: "\f0f4"; +@fa-var-cog: "\f013"; +@fa-var-cogs: "\f085"; +@fa-var-columns: "\f0db"; +@fa-var-comment: "\f075"; +@fa-var-comment-alt: "\f27a"; +@fa-var-comments: "\f086"; +@fa-var-compass: "\f14e"; +@fa-var-compress: "\f066"; +@fa-var-connectdevelop: "\f20e"; +@fa-var-contao: "\f26d"; +@fa-var-copy: "\f0c5"; +@fa-var-copyright: "\f1f9"; +@fa-var-cpanel: "\f388"; +@fa-var-creative-commons: "\f25e"; +@fa-var-credit-card: "\f09d"; +@fa-var-crop: "\f125"; +@fa-var-crosshairs: "\f05b"; +@fa-var-css3: "\f13c"; +@fa-var-css3-alt: "\f38b"; +@fa-var-cube: "\f1b2"; +@fa-var-cubes: "\f1b3"; +@fa-var-cut: "\f0c4"; +@fa-var-cuttlefish: "\f38c"; +@fa-var-d-and-d: "\f38d"; +@fa-var-dashcube: "\f210"; +@fa-var-database: "\f1c0"; +@fa-var-deaf: "\f2a4"; +@fa-var-delicious: "\f1a5"; +@fa-var-deploydog: "\f38e"; +@fa-var-deskpro: "\f38f"; +@fa-var-desktop: "\f108"; +@fa-var-deviantart: "\f1bd"; +@fa-var-digg: "\f1a6"; +@fa-var-digital-ocean: "\f391"; +@fa-var-discord: "\f392"; +@fa-var-discourse: "\f393"; +@fa-var-dochub: "\f394"; +@fa-var-docker: "\f395"; +@fa-var-dollar-sign: "\f155"; +@fa-var-dot-circle: "\f192"; +@fa-var-download: "\f019"; +@fa-var-draft2digital: "\f396"; +@fa-var-dribbble: "\f17d"; +@fa-var-dribbble-square: "\f397"; +@fa-var-dropbox: "\f16b"; +@fa-var-drupal: "\f1a9"; +@fa-var-dyalog: "\f399"; +@fa-var-earlybirds: "\f39a"; +@fa-var-edge: "\f282"; +@fa-var-edit: "\f044"; +@fa-var-eject: "\f052"; +@fa-var-ellipsis-h: "\f141"; +@fa-var-ellipsis-v: "\f142"; +@fa-var-ember: "\f423"; +@fa-var-empire: "\f1d1"; +@fa-var-envelope: "\f0e0"; +@fa-var-envelope-open: "\f2b6"; +@fa-var-envelope-square: "\f199"; +@fa-var-envira: "\f299"; +@fa-var-eraser: "\f12d"; +@fa-var-erlang: "\f39d"; +@fa-var-etsy: "\f2d7"; +@fa-var-euro-sign: "\f153"; +@fa-var-exchange-alt: "\f362"; +@fa-var-exclamation: "\f12a"; +@fa-var-exclamation-circle: "\f06a"; +@fa-var-exclamation-triangle: "\f071"; +@fa-var-expand: "\f065"; +@fa-var-expand-arrows-alt: "\f31e"; +@fa-var-expeditedssl: "\f23e"; +@fa-var-external-link-alt: "\f35d"; +@fa-var-external-link-square-alt: "\f360"; +@fa-var-eye: "\f06e"; +@fa-var-eye-dropper: "\f1fb"; +@fa-var-eye-slash: "\f070"; +@fa-var-facebook: "\f09a"; +@fa-var-facebook-f: "\f39e"; +@fa-var-facebook-messenger: "\f39f"; +@fa-var-facebook-square: "\f082"; +@fa-var-fast-backward: "\f049"; +@fa-var-fast-forward: "\f050"; +@fa-var-fax: "\f1ac"; +@fa-var-female: "\f182"; +@fa-var-fighter-jet: "\f0fb"; +@fa-var-file: "\f15b"; +@fa-var-file-alt: "\f15c"; +@fa-var-file-archive: "\f1c6"; +@fa-var-file-audio: "\f1c7"; +@fa-var-file-code: "\f1c9"; +@fa-var-file-excel: "\f1c3"; +@fa-var-file-image: "\f1c5"; +@fa-var-file-pdf: "\f1c1"; +@fa-var-file-powerpoint: "\f1c4"; +@fa-var-file-video: "\f1c8"; +@fa-var-file-word: "\f1c2"; +@fa-var-film: "\f008"; +@fa-var-filter: "\f0b0"; +@fa-var-fire: "\f06d"; +@fa-var-fire-extinguisher: "\f134"; +@fa-var-firefox: "\f269"; +@fa-var-first-order: "\f2b0"; +@fa-var-firstdraft: "\f3a1"; +@fa-var-flag: "\f024"; +@fa-var-flag-checkered: "\f11e"; +@fa-var-flask: "\f0c3"; +@fa-var-flickr: "\f16e"; +@fa-var-fly: "\f417"; +@fa-var-folder: "\f07b"; +@fa-var-folder-open: "\f07c"; +@fa-var-font: "\f031"; +@fa-var-font-awesome: "\f2b4"; +@fa-var-font-awesome-alt: "\f35c"; +@fa-var-font-awesome-flag: "\f425"; +@fa-var-fonticons: "\f280"; +@fa-var-fonticons-fi: "\f3a2"; +@fa-var-fort-awesome: "\f286"; +@fa-var-fort-awesome-alt: "\f3a3"; +@fa-var-forumbee: "\f211"; +@fa-var-forward: "\f04e"; +@fa-var-foursquare: "\f180"; +@fa-var-free-code-camp: "\f2c5"; +@fa-var-freebsd: "\f3a4"; +@fa-var-frown: "\f119"; +@fa-var-futbol: "\f1e3"; +@fa-var-gamepad: "\f11b"; +@fa-var-gavel: "\f0e3"; +@fa-var-gem: "\f3a5"; +@fa-var-genderless: "\f22d"; +@fa-var-get-pocket: "\f265"; +@fa-var-gg: "\f260"; +@fa-var-gg-circle: "\f261"; +@fa-var-gift: "\f06b"; +@fa-var-git: "\f1d3"; +@fa-var-git-square: "\f1d2"; +@fa-var-github: "\f09b"; +@fa-var-github-alt: "\f113"; +@fa-var-github-square: "\f092"; +@fa-var-gitkraken: "\f3a6"; +@fa-var-gitlab: "\f296"; +@fa-var-gitter: "\f426"; +@fa-var-glass-martini: "\f000"; +@fa-var-glide: "\f2a5"; +@fa-var-glide-g: "\f2a6"; +@fa-var-globe: "\f0ac"; +@fa-var-gofore: "\f3a7"; +@fa-var-goodreads: "\f3a8"; +@fa-var-goodreads-g: "\f3a9"; +@fa-var-google: "\f1a0"; +@fa-var-google-drive: "\f3aa"; +@fa-var-google-play: "\f3ab"; +@fa-var-google-plus: "\f2b3"; +@fa-var-google-plus-g: "\f0d5"; +@fa-var-google-plus-square: "\f0d4"; +@fa-var-google-wallet: "\f1ee"; +@fa-var-graduation-cap: "\f19d"; +@fa-var-gratipay: "\f184"; +@fa-var-grav: "\f2d6"; +@fa-var-gripfire: "\f3ac"; +@fa-var-grunt: "\f3ad"; +@fa-var-gulp: "\f3ae"; +@fa-var-h-square: "\f0fd"; +@fa-var-hacker-news: "\f1d4"; +@fa-var-hacker-news-square: "\f3af"; +@fa-var-hand-lizard: "\f258"; +@fa-var-hand-paper: "\f256"; +@fa-var-hand-peace: "\f25b"; +@fa-var-hand-point-down: "\f0a7"; +@fa-var-hand-point-left: "\f0a5"; +@fa-var-hand-point-right: "\f0a4"; +@fa-var-hand-point-up: "\f0a6"; +@fa-var-hand-pointer: "\f25a"; +@fa-var-hand-rock: "\f255"; +@fa-var-hand-scissors: "\f257"; +@fa-var-hand-spock: "\f259"; +@fa-var-handshake: "\f2b5"; +@fa-var-hashtag: "\f292"; +@fa-var-hdd: "\f0a0"; +@fa-var-heading: "\f1dc"; +@fa-var-headphones: "\f025"; +@fa-var-heart: "\f004"; +@fa-var-heartbeat: "\f21e"; +@fa-var-hire-a-helper: "\f3b0"; +@fa-var-history: "\f1da"; +@fa-var-home: "\f015"; +@fa-var-hooli: "\f427"; +@fa-var-hospital: "\f0f8"; +@fa-var-hotjar: "\f3b1"; +@fa-var-hourglass: "\f254"; +@fa-var-hourglass-end: "\f253"; +@fa-var-hourglass-half: "\f252"; +@fa-var-hourglass-start: "\f251"; +@fa-var-houzz: "\f27c"; +@fa-var-html5: "\f13b"; +@fa-var-hubspot: "\f3b2"; +@fa-var-i-cursor: "\f246"; +@fa-var-id-badge: "\f2c1"; +@fa-var-id-card: "\f2c2"; +@fa-var-image: "\f03e"; +@fa-var-images: "\f302"; +@fa-var-imdb: "\f2d8"; +@fa-var-inbox: "\f01c"; +@fa-var-indent: "\f03c"; +@fa-var-industry: "\f275"; +@fa-var-info: "\f129"; +@fa-var-info-circle: "\f05a"; +@fa-var-instagram: "\f16d"; +@fa-var-internet-explorer: "\f26b"; +@fa-var-ioxhost: "\f208"; +@fa-var-italic: "\f033"; +@fa-var-itunes: "\f3b4"; +@fa-var-itunes-note: "\f3b5"; +@fa-var-jenkins: "\f3b6"; +@fa-var-joget: "\f3b7"; +@fa-var-joomla: "\f1aa"; +@fa-var-js: "\f3b8"; +@fa-var-js-square: "\f3b9"; +@fa-var-jsfiddle: "\f1cc"; +@fa-var-key: "\f084"; +@fa-var-keyboard: "\f11c"; +@fa-var-keycdn: "\f3ba"; +@fa-var-kickstarter: "\f3bb"; +@fa-var-kickstarter-k: "\f3bc"; +@fa-var-language: "\f1ab"; +@fa-var-laptop: "\f109"; +@fa-var-laravel: "\f3bd"; +@fa-var-lastfm: "\f202"; +@fa-var-lastfm-square: "\f203"; +@fa-var-leaf: "\f06c"; +@fa-var-leanpub: "\f212"; +@fa-var-lemon: "\f094"; +@fa-var-less: "\f41d"; +@fa-var-level-down-alt: "\f3be"; +@fa-var-level-up-alt: "\f3bf"; +@fa-var-life-ring: "\f1cd"; +@fa-var-lightbulb: "\f0eb"; +@fa-var-line: "\f3c0"; +@fa-var-link: "\f0c1"; +@fa-var-linkedin: "\f08c"; +@fa-var-linkedin-in: "\f0e1"; +@fa-var-linode: "\f2b8"; +@fa-var-linux: "\f17c"; +@fa-var-lira-sign: "\f195"; +@fa-var-list: "\f03a"; +@fa-var-list-alt: "\f022"; +@fa-var-list-ol: "\f0cb"; +@fa-var-list-ul: "\f0ca"; +@fa-var-location-arrow: "\f124"; +@fa-var-lock: "\f023"; +@fa-var-lock-open: "\f3c1"; +@fa-var-long-arrow-alt-down: "\f309"; +@fa-var-long-arrow-alt-left: "\f30a"; +@fa-var-long-arrow-alt-right: "\f30b"; +@fa-var-long-arrow-alt-up: "\f30c"; +@fa-var-low-vision: "\f2a8"; +@fa-var-lyft: "\f3c3"; +@fa-var-magento: "\f3c4"; +@fa-var-magic: "\f0d0"; +@fa-var-magnet: "\f076"; +@fa-var-male: "\f183"; +@fa-var-map: "\f279"; +@fa-var-map-marker: "\f041"; +@fa-var-map-marker-alt: "\f3c5"; +@fa-var-map-pin: "\f276"; +@fa-var-map-signs: "\f277"; +@fa-var-mars: "\f222"; +@fa-var-mars-double: "\f227"; +@fa-var-mars-stroke: "\f229"; +@fa-var-mars-stroke-h: "\f22b"; +@fa-var-mars-stroke-v: "\f22a"; +@fa-var-maxcdn: "\f136"; +@fa-var-medapps: "\f3c6"; +@fa-var-medium: "\f23a"; +@fa-var-medium-m: "\f3c7"; +@fa-var-medkit: "\f0fa"; +@fa-var-medrt: "\f3c8"; +@fa-var-meetup: "\f2e0"; +@fa-var-meh: "\f11a"; +@fa-var-mercury: "\f223"; +@fa-var-microchip: "\f2db"; +@fa-var-microphone: "\f130"; +@fa-var-microphone-slash: "\f131"; +@fa-var-microsoft: "\f3ca"; +@fa-var-minus: "\f068"; +@fa-var-minus-circle: "\f056"; +@fa-var-minus-square: "\f146"; +@fa-var-mix: "\f3cb"; +@fa-var-mixcloud: "\f289"; +@fa-var-mizuni: "\f3cc"; +@fa-var-mobile: "\f10b"; +@fa-var-mobile-alt: "\f3cd"; +@fa-var-modx: "\f285"; +@fa-var-monero: "\f3d0"; +@fa-var-money-bill-alt: "\f3d1"; +@fa-var-moon: "\f186"; +@fa-var-motorcycle: "\f21c"; +@fa-var-mouse-pointer: "\f245"; +@fa-var-music: "\f001"; +@fa-var-napster: "\f3d2"; +@fa-var-neuter: "\f22c"; +@fa-var-newspaper: "\f1ea"; +@fa-var-nintendo-switch: "\f418"; +@fa-var-node: "\f419"; +@fa-var-node-js: "\f3d3"; +@fa-var-npm: "\f3d4"; +@fa-var-ns8: "\f3d5"; +@fa-var-nutritionix: "\f3d6"; +@fa-var-object-group: "\f247"; +@fa-var-object-ungroup: "\f248"; +@fa-var-odnoklassniki: "\f263"; +@fa-var-odnoklassniki-square: "\f264"; +@fa-var-opencart: "\f23d"; +@fa-var-openid: "\f19b"; +@fa-var-opera: "\f26a"; +@fa-var-optin-monster: "\f23c"; +@fa-var-osi: "\f41a"; +@fa-var-outdent: "\f03b"; +@fa-var-page4: "\f3d7"; +@fa-var-pagelines: "\f18c"; +@fa-var-paint-brush: "\f1fc"; +@fa-var-palfed: "\f3d8"; +@fa-var-paper-plane: "\f1d8"; +@fa-var-paperclip: "\f0c6"; +@fa-var-paragraph: "\f1dd"; +@fa-var-paste: "\f0ea"; +@fa-var-patreon: "\f3d9"; +@fa-var-pause: "\f04c"; +@fa-var-pause-circle: "\f28b"; +@fa-var-paw: "\f1b0"; +@fa-var-paypal: "\f1ed"; +@fa-var-pen-square: "\f14b"; +@fa-var-pencil-alt: "\f303"; +@fa-var-percent: "\f295"; +@fa-var-periscope: "\f3da"; +@fa-var-phabricator: "\f3db"; +@fa-var-phoenix-framework: "\f3dc"; +@fa-var-phone: "\f095"; +@fa-var-phone-square: "\f098"; +@fa-var-phone-volume: "\f2a0"; +@fa-var-pied-piper: "\f2ae"; +@fa-var-pied-piper-alt: "\f1a8"; +@fa-var-pied-piper-pp: "\f1a7"; +@fa-var-pinterest: "\f0d2"; +@fa-var-pinterest-p: "\f231"; +@fa-var-pinterest-square: "\f0d3"; +@fa-var-plane: "\f072"; +@fa-var-play: "\f04b"; +@fa-var-play-circle: "\f144"; +@fa-var-playstation: "\f3df"; +@fa-var-plug: "\f1e6"; +@fa-var-plus: "\f067"; +@fa-var-plus-circle: "\f055"; +@fa-var-plus-square: "\f0fe"; +@fa-var-podcast: "\f2ce"; +@fa-var-pound-sign: "\f154"; +@fa-var-power-off: "\f011"; +@fa-var-print: "\f02f"; +@fa-var-product-hunt: "\f288"; +@fa-var-pushed: "\f3e1"; +@fa-var-puzzle-piece: "\f12e"; +@fa-var-python: "\f3e2"; +@fa-var-qq: "\f1d6"; +@fa-var-qrcode: "\f029"; +@fa-var-question: "\f128"; +@fa-var-question-circle: "\f059"; +@fa-var-quora: "\f2c4"; +@fa-var-quote-left: "\f10d"; +@fa-var-quote-right: "\f10e"; +@fa-var-random: "\f074"; +@fa-var-ravelry: "\f2d9"; +@fa-var-react: "\f41b"; +@fa-var-rebel: "\f1d0"; +@fa-var-recycle: "\f1b8"; +@fa-var-red-river: "\f3e3"; +@fa-var-reddit: "\f1a1"; +@fa-var-reddit-alien: "\f281"; +@fa-var-reddit-square: "\f1a2"; +@fa-var-redo: "\f01e"; +@fa-var-redo-alt: "\f2f9"; +@fa-var-registered: "\f25d"; +@fa-var-rendact: "\f3e4"; +@fa-var-renren: "\f18b"; +@fa-var-reply: "\f3e5"; +@fa-var-reply-all: "\f122"; +@fa-var-replyd: "\f3e6"; +@fa-var-resolving: "\f3e7"; +@fa-var-retweet: "\f079"; +@fa-var-road: "\f018"; +@fa-var-rocket: "\f135"; +@fa-var-rocketchat: "\f3e8"; +@fa-var-rockrms: "\f3e9"; +@fa-var-rss: "\f09e"; +@fa-var-rss-square: "\f143"; +@fa-var-ruble-sign: "\f158"; +@fa-var-rupee-sign: "\f156"; +@fa-var-safari: "\f267"; +@fa-var-sass: "\f41e"; +@fa-var-save: "\f0c7"; +@fa-var-schlix: "\f3ea"; +@fa-var-scribd: "\f28a"; +@fa-var-search: "\f002"; +@fa-var-search-minus: "\f010"; +@fa-var-search-plus: "\f00e"; +@fa-var-searchengin: "\f3eb"; +@fa-var-sellcast: "\f2da"; +@fa-var-sellsy: "\f213"; +@fa-var-server: "\f233"; +@fa-var-servicestack: "\f3ec"; +@fa-var-share: "\f064"; +@fa-var-share-alt: "\f1e0"; +@fa-var-share-alt-square: "\f1e1"; +@fa-var-share-square: "\f14d"; +@fa-var-shekel-sign: "\f20b"; +@fa-var-shield-alt: "\f3ed"; +@fa-var-ship: "\f21a"; +@fa-var-shirtsinbulk: "\f214"; +@fa-var-shopping-bag: "\f290"; +@fa-var-shopping-basket: "\f291"; +@fa-var-shopping-cart: "\f07a"; +@fa-var-shower: "\f2cc"; +@fa-var-sign-in-alt: "\f2f6"; +@fa-var-sign-language: "\f2a7"; +@fa-var-sign-out-alt: "\f2f5"; +@fa-var-signal: "\f012"; +@fa-var-simplybuilt: "\f215"; +@fa-var-sistrix: "\f3ee"; +@fa-var-sitemap: "\f0e8"; +@fa-var-skyatlas: "\f216"; +@fa-var-skype: "\f17e"; +@fa-var-slack: "\f198"; +@fa-var-slack-hash: "\f3ef"; +@fa-var-sliders-h: "\f1de"; +@fa-var-slideshare: "\f1e7"; +@fa-var-smile: "\f118"; +@fa-var-snapchat: "\f2ab"; +@fa-var-snapchat-ghost: "\f2ac"; +@fa-var-snapchat-square: "\f2ad"; +@fa-var-snowflake: "\f2dc"; +@fa-var-sort: "\f0dc"; +@fa-var-sort-alpha-down: "\f15d"; +@fa-var-sort-alpha-up: "\f15e"; +@fa-var-sort-amount-down: "\f160"; +@fa-var-sort-amount-up: "\f161"; +@fa-var-sort-down: "\f0dd"; +@fa-var-sort-numeric-down: "\f162"; +@fa-var-sort-numeric-up: "\f163"; +@fa-var-sort-up: "\f0de"; +@fa-var-soundcloud: "\f1be"; +@fa-var-space-shuttle: "\f197"; +@fa-var-speakap: "\f3f3"; +@fa-var-spinner: "\f110"; +@fa-var-spotify: "\f1bc"; +@fa-var-square: "\f0c8"; +@fa-var-stack-exchange: "\f18d"; +@fa-var-stack-overflow: "\f16c"; +@fa-var-star: "\f005"; +@fa-var-star-half: "\f089"; +@fa-var-staylinked: "\f3f5"; +@fa-var-steam: "\f1b6"; +@fa-var-steam-square: "\f1b7"; +@fa-var-steam-symbol: "\f3f6"; +@fa-var-step-backward: "\f048"; +@fa-var-step-forward: "\f051"; +@fa-var-stethoscope: "\f0f1"; +@fa-var-sticker-mule: "\f3f7"; +@fa-var-sticky-note: "\f249"; +@fa-var-stop: "\f04d"; +@fa-var-stop-circle: "\f28d"; +@fa-var-strava: "\f428"; +@fa-var-street-view: "\f21d"; +@fa-var-strikethrough: "\f0cc"; +@fa-var-stripe: "\f429"; +@fa-var-stripe-s: "\f42a"; +@fa-var-studiovinari: "\f3f8"; +@fa-var-stumbleupon: "\f1a4"; +@fa-var-stumbleupon-circle: "\f1a3"; +@fa-var-subscript: "\f12c"; +@fa-var-subway: "\f239"; +@fa-var-suitcase: "\f0f2"; +@fa-var-sun: "\f185"; +@fa-var-superpowers: "\f2dd"; +@fa-var-superscript: "\f12b"; +@fa-var-supple: "\f3f9"; +@fa-var-sync: "\f021"; +@fa-var-sync-alt: "\f2f1"; +@fa-var-table: "\f0ce"; +@fa-var-tablet: "\f10a"; +@fa-var-tablet-alt: "\f3fa"; +@fa-var-tachometer-alt: "\f3fd"; +@fa-var-tag: "\f02b"; +@fa-var-tags: "\f02c"; +@fa-var-tasks: "\f0ae"; +@fa-var-taxi: "\f1ba"; +@fa-var-telegram: "\f2c6"; +@fa-var-telegram-plane: "\f3fe"; +@fa-var-tencent-weibo: "\f1d5"; +@fa-var-terminal: "\f120"; +@fa-var-text-height: "\f034"; +@fa-var-text-width: "\f035"; +@fa-var-th: "\f00a"; +@fa-var-th-large: "\f009"; +@fa-var-th-list: "\f00b"; +@fa-var-themeisle: "\f2b2"; +@fa-var-thermometer-empty: "\f2cb"; +@fa-var-thermometer-full: "\f2c7"; +@fa-var-thermometer-half: "\f2c9"; +@fa-var-thermometer-quarter: "\f2ca"; +@fa-var-thermometer-three-quarters: "\f2c8"; +@fa-var-thumbs-down: "\f165"; +@fa-var-thumbs-up: "\f164"; +@fa-var-thumbtack: "\f08d"; +@fa-var-ticket-alt: "\f3ff"; +@fa-var-times: "\f00d"; +@fa-var-times-circle: "\f057"; +@fa-var-tint: "\f043"; +@fa-var-toggle-off: "\f204"; +@fa-var-toggle-on: "\f205"; +@fa-var-trademark: "\f25c"; +@fa-var-train: "\f238"; +@fa-var-transgender: "\f224"; +@fa-var-transgender-alt: "\f225"; +@fa-var-trash: "\f1f8"; +@fa-var-trash-alt: "\f2ed"; +@fa-var-tree: "\f1bb"; +@fa-var-trello: "\f181"; +@fa-var-tripadvisor: "\f262"; +@fa-var-trophy: "\f091"; +@fa-var-truck: "\f0d1"; +@fa-var-tty: "\f1e4"; +@fa-var-tumblr: "\f173"; +@fa-var-tumblr-square: "\f174"; +@fa-var-tv: "\f26c"; +@fa-var-twitch: "\f1e8"; +@fa-var-twitter: "\f099"; +@fa-var-twitter-square: "\f081"; +@fa-var-typo3: "\f42b"; +@fa-var-uber: "\f402"; +@fa-var-uikit: "\f403"; +@fa-var-umbrella: "\f0e9"; +@fa-var-underline: "\f0cd"; +@fa-var-undo: "\f0e2"; +@fa-var-undo-alt: "\f2ea"; +@fa-var-uniregistry: "\f404"; +@fa-var-universal-access: "\f29a"; +@fa-var-university: "\f19c"; +@fa-var-unlink: "\f127"; +@fa-var-unlock: "\f09c"; +@fa-var-unlock-alt: "\f13e"; +@fa-var-untappd: "\f405"; +@fa-var-upload: "\f093"; +@fa-var-usb: "\f287"; +@fa-var-user: "\f007"; +@fa-var-user-circle: "\f2bd"; +@fa-var-user-md: "\f0f0"; +@fa-var-user-plus: "\f234"; +@fa-var-user-secret: "\f21b"; +@fa-var-user-times: "\f235"; +@fa-var-users: "\f0c0"; +@fa-var-ussunnah: "\f407"; +@fa-var-utensil-spoon: "\f2e5"; +@fa-var-utensils: "\f2e7"; +@fa-var-vaadin: "\f408"; +@fa-var-venus: "\f221"; +@fa-var-venus-double: "\f226"; +@fa-var-venus-mars: "\f228"; +@fa-var-viacoin: "\f237"; +@fa-var-viadeo: "\f2a9"; +@fa-var-viadeo-square: "\f2aa"; +@fa-var-viber: "\f409"; +@fa-var-video: "\f03d"; +@fa-var-vimeo: "\f40a"; +@fa-var-vimeo-square: "\f194"; +@fa-var-vimeo-v: "\f27d"; +@fa-var-vine: "\f1ca"; +@fa-var-vk: "\f189"; +@fa-var-vnv: "\f40b"; +@fa-var-volume-down: "\f027"; +@fa-var-volume-off: "\f026"; +@fa-var-volume-up: "\f028"; +@fa-var-vuejs: "\f41f"; +@fa-var-weibo: "\f18a"; +@fa-var-weixin: "\f1d7"; +@fa-var-whatsapp: "\f232"; +@fa-var-whatsapp-square: "\f40c"; +@fa-var-wheelchair: "\f193"; +@fa-var-whmcs: "\f40d"; +@fa-var-wifi: "\f1eb"; +@fa-var-wikipedia-w: "\f266"; +@fa-var-window-close: "\f410"; +@fa-var-window-maximize: "\f2d0"; +@fa-var-window-minimize: "\f2d1"; +@fa-var-window-restore: "\f2d2"; +@fa-var-windows: "\f17a"; +@fa-var-won-sign: "\f159"; +@fa-var-wordpress: "\f19a"; +@fa-var-wordpress-simple: "\f411"; +@fa-var-wpbeginner: "\f297"; +@fa-var-wpexplorer: "\f2de"; +@fa-var-wpforms: "\f298"; +@fa-var-wrench: "\f0ad"; +@fa-var-xbox: "\f412"; +@fa-var-xing: "\f168"; +@fa-var-xing-square: "\f169"; +@fa-var-y-combinator: "\f23b"; +@fa-var-yahoo: "\f19e"; +@fa-var-yandex: "\f413"; +@fa-var-yandex-international: "\f414"; +@fa-var-yelp: "\f1e9"; +@fa-var-yen-sign: "\f157"; +@fa-var-yoast: "\f2b1"; +@fa-var-youtube: "\f167"; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-brands.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-brands.less new file mode 100644 index 000000000..758d5e189 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-brands.less @@ -0,0 +1,17 @@ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url('@{fa-font-path}/fa-brands-400.eot'); + src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('@{fa-font-path}/fa-brands-400.woff') format('woff'), + url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'), + url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); +} + +.fab { + font-family: 'Font Awesome 5 Brands'; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-regular.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-regular.less new file mode 100644 index 000000000..b2985ff21 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-regular.less @@ -0,0 +1,18 @@ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url('@{fa-font-path}/fa-regular-400.eot'); + src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('@{fa-font-path}/fa-regular-400.woff') format('woff'), + url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'), + url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); +} + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-solid.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-solid.less new file mode 100644 index 000000000..d9c5aaca8 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fa-solid.less @@ -0,0 +1,19 @@ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url('@{fa-font-path}/fa-solid-900.eot'); + src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('@{fa-font-path}/fa-solid-900.woff') format('woff'), + url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'), + url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); +} + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fontawesome.less b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fontawesome.less new file mode 100644 index 000000000..2b59ee770 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/less/fontawesome.less @@ -0,0 +1,16 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import "_variables.less"; +@import "_mixins.less"; +@import "_core.less"; +@import "_larger.less"; +@import "_fixed-width.less"; +@import "_list.less"; +@import "_bordered-pulled.less"; +@import "_animated.less"; +@import "_rotated-flipped.less"; +@import "_stacked.less"; +@import "_icons.less"; +@import "_screen-reader.less"; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/package.json b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/package.json new file mode 100644 index 000000000..33feff114 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/package.json @@ -0,0 +1,51 @@ +{ + "description": "The iconic font, CSS, and SVG framework", + "keywords": [ + "font", + "awesome", + "fontawesome", + "icon", + "svg", + "bootstrap" + ], + "homepage": "https://fontawesome.com", + "bugs": { + "url": "http://github.com/FortAwesome/Font-Awesome/issues" + }, + "author": { + "name": "Dave Gandy", + "email": "dave@fontawesome.com", + "web": "http://twitter.com/davegandy" + }, + "contributors": [ + { + "name": "Brian Talbot", + "web": "http://twitter.com/talbs" + }, + { + "name": "Travis Chase", + "web": "http://twitter.com/supercodepoet" + }, + { + "name": "Rob Madole", + "web": "http://twitter.com/robmadole" + }, + { + "name": "Geremia Taglialatela", + "web": "http://twitter.com/gtagliala" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome" + }, + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "version": "1.0.0", + "name": "@fortawesome/fontawesome-free-webfonts", + "main": "css/fontawesome.css", + "style": "css/fontawesome.css", + "license": "(OFL-1.1 AND MIT)" +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_animated.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_animated.scss new file mode 100644 index 000000000..7c7c0e173 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_animated.scss @@ -0,0 +1,20 @@ +// Animated Icons +// -------------------------- + +.#{$fa-css-prefix}-spin { + animation: fa-spin 2s infinite linear; +} + +.#{$fa-css-prefix}-pulse { + animation: fa-spin 1s infinite steps(8); +} + +@keyframes fa-spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_bordered-pulled.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_bordered-pulled.scss new file mode 100644 index 000000000..c8c4274c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_bordered-pulled.scss @@ -0,0 +1,20 @@ +// Bordered & Pulled +// ------------------------- + +.#{$fa-css-prefix}-border { + border: solid .08em $fa-border-color; + border-radius: .1em; + padding: .2em .25em .15em; +} + +.#{$fa-css-prefix}-pull-left { float: left; } +.#{$fa-css-prefix}-pull-right { float: right; } + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fab { + &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } + &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_core.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_core.scss new file mode 100644 index 000000000..7fd37f855 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_core.scss @@ -0,0 +1,16 @@ +// Base Class Definition +// ------------------------- + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_fixed-width.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_fixed-width.scss new file mode 100644 index 000000000..5b33eb49a --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_fixed-width.scss @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.#{$fa-css-prefix}-fw { + text-align: center; + width: (20em / 16); +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_icons.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_icons.scss new file mode 100644 index 000000000..e7422a398 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_icons.scss @@ -0,0 +1,787 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ + +.#{$fa-css-prefix}-500px:before { content: fa-content($fa-var-500px); } +.#{$fa-css-prefix}-accessible-icon:before { content: fa-content($fa-var-accessible-icon); } +.#{$fa-css-prefix}-accusoft:before { content: fa-content($fa-var-accusoft); } +.#{$fa-css-prefix}-address-book:before { content: fa-content($fa-var-address-book); } +.#{$fa-css-prefix}-address-card:before { content: fa-content($fa-var-address-card); } +.#{$fa-css-prefix}-adjust:before { content: fa-content($fa-var-adjust); } +.#{$fa-css-prefix}-adn:before { content: fa-content($fa-var-adn); } +.#{$fa-css-prefix}-adversal:before { content: fa-content($fa-var-adversal); } +.#{$fa-css-prefix}-affiliatetheme:before { content: fa-content($fa-var-affiliatetheme); } +.#{$fa-css-prefix}-algolia:before { content: fa-content($fa-var-algolia); } +.#{$fa-css-prefix}-align-center:before { content: fa-content($fa-var-align-center); } +.#{$fa-css-prefix}-align-justify:before { content: fa-content($fa-var-align-justify); } +.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); } +.#{$fa-css-prefix}-align-right:before { content: fa-content($fa-var-align-right); } +.#{$fa-css-prefix}-amazon:before { content: fa-content($fa-var-amazon); } +.#{$fa-css-prefix}-ambulance:before { content: fa-content($fa-var-ambulance); } +.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } +.#{$fa-css-prefix}-amilia:before { content: fa-content($fa-var-amilia); } +.#{$fa-css-prefix}-anchor:before { content: fa-content($fa-var-anchor); } +.#{$fa-css-prefix}-android:before { content: fa-content($fa-var-android); } +.#{$fa-css-prefix}-angellist:before { content: fa-content($fa-var-angellist); } +.#{$fa-css-prefix}-angle-double-down:before { content: fa-content($fa-var-angle-double-down); } +.#{$fa-css-prefix}-angle-double-left:before { content: fa-content($fa-var-angle-double-left); } +.#{$fa-css-prefix}-angle-double-right:before { content: fa-content($fa-var-angle-double-right); } +.#{$fa-css-prefix}-angle-double-up:before { content: fa-content($fa-var-angle-double-up); } +.#{$fa-css-prefix}-angle-down:before { content: fa-content($fa-var-angle-down); } +.#{$fa-css-prefix}-angle-left:before { content: fa-content($fa-var-angle-left); } +.#{$fa-css-prefix}-angle-right:before { content: fa-content($fa-var-angle-right); } +.#{$fa-css-prefix}-angle-up:before { content: fa-content($fa-var-angle-up); } +.#{$fa-css-prefix}-angrycreative:before { content: fa-content($fa-var-angrycreative); } +.#{$fa-css-prefix}-angular:before { content: fa-content($fa-var-angular); } +.#{$fa-css-prefix}-app-store:before { content: fa-content($fa-var-app-store); } +.#{$fa-css-prefix}-app-store-ios:before { content: fa-content($fa-var-app-store-ios); } +.#{$fa-css-prefix}-apper:before { content: fa-content($fa-var-apper); } +.#{$fa-css-prefix}-apple:before { content: fa-content($fa-var-apple); } +.#{$fa-css-prefix}-apple-pay:before { content: fa-content($fa-var-apple-pay); } +.#{$fa-css-prefix}-archive:before { content: fa-content($fa-var-archive); } +.#{$fa-css-prefix}-arrow-alt-circle-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } +.#{$fa-css-prefix}-arrow-alt-circle-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } +.#{$fa-css-prefix}-arrow-alt-circle-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } +.#{$fa-css-prefix}-arrow-alt-circle-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } +.#{$fa-css-prefix}-arrow-circle-down:before { content: fa-content($fa-var-arrow-circle-down); } +.#{$fa-css-prefix}-arrow-circle-left:before { content: fa-content($fa-var-arrow-circle-left); } +.#{$fa-css-prefix}-arrow-circle-right:before { content: fa-content($fa-var-arrow-circle-right); } +.#{$fa-css-prefix}-arrow-circle-up:before { content: fa-content($fa-var-arrow-circle-up); } +.#{$fa-css-prefix}-arrow-down:before { content: fa-content($fa-var-arrow-down); } +.#{$fa-css-prefix}-arrow-left:before { content: fa-content($fa-var-arrow-left); } +.#{$fa-css-prefix}-arrow-right:before { content: fa-content($fa-var-arrow-right); } +.#{$fa-css-prefix}-arrow-up:before { content: fa-content($fa-var-arrow-up); } +.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-arrows-alt); } +.#{$fa-css-prefix}-arrows-alt-h:before { content: fa-content($fa-var-arrows-alt-h); } +.#{$fa-css-prefix}-arrows-alt-v:before { content: fa-content($fa-var-arrows-alt-v); } +.#{$fa-css-prefix}-assistive-listening-systems:before { content: fa-content($fa-var-assistive-listening-systems); } +.#{$fa-css-prefix}-asterisk:before { content: fa-content($fa-var-asterisk); } +.#{$fa-css-prefix}-asymmetrik:before { content: fa-content($fa-var-asymmetrik); } +.#{$fa-css-prefix}-at:before { content: fa-content($fa-var-at); } +.#{$fa-css-prefix}-audible:before { content: fa-content($fa-var-audible); } +.#{$fa-css-prefix}-audio-description:before { content: fa-content($fa-var-audio-description); } +.#{$fa-css-prefix}-autoprefixer:before { content: fa-content($fa-var-autoprefixer); } +.#{$fa-css-prefix}-avianex:before { content: fa-content($fa-var-avianex); } +.#{$fa-css-prefix}-aviato:before { content: fa-content($fa-var-aviato); } +.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); } +.#{$fa-css-prefix}-backward:before { content: fa-content($fa-var-backward); } +.#{$fa-css-prefix}-balance-scale:before { content: fa-content($fa-var-balance-scale); } +.#{$fa-css-prefix}-ban:before { content: fa-content($fa-var-ban); } +.#{$fa-css-prefix}-bandcamp:before { content: fa-content($fa-var-bandcamp); } +.#{$fa-css-prefix}-barcode:before { content: fa-content($fa-var-barcode); } +.#{$fa-css-prefix}-bars:before { content: fa-content($fa-var-bars); } +.#{$fa-css-prefix}-bath:before { content: fa-content($fa-var-bath); } +.#{$fa-css-prefix}-battery-empty:before { content: fa-content($fa-var-battery-empty); } +.#{$fa-css-prefix}-battery-full:before { content: fa-content($fa-var-battery-full); } +.#{$fa-css-prefix}-battery-half:before { content: fa-content($fa-var-battery-half); } +.#{$fa-css-prefix}-battery-quarter:before { content: fa-content($fa-var-battery-quarter); } +.#{$fa-css-prefix}-battery-three-quarters:before { content: fa-content($fa-var-battery-three-quarters); } +.#{$fa-css-prefix}-bed:before { content: fa-content($fa-var-bed); } +.#{$fa-css-prefix}-beer:before { content: fa-content($fa-var-beer); } +.#{$fa-css-prefix}-behance:before { content: fa-content($fa-var-behance); } +.#{$fa-css-prefix}-behance-square:before { content: fa-content($fa-var-behance-square); } +.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); } +.#{$fa-css-prefix}-bell-slash:before { content: fa-content($fa-var-bell-slash); } +.#{$fa-css-prefix}-bicycle:before { content: fa-content($fa-var-bicycle); } +.#{$fa-css-prefix}-bimobject:before { content: fa-content($fa-var-bimobject); } +.#{$fa-css-prefix}-binoculars:before { content: fa-content($fa-var-binoculars); } +.#{$fa-css-prefix}-birthday-cake:before { content: fa-content($fa-var-birthday-cake); } +.#{$fa-css-prefix}-bitbucket:before { content: fa-content($fa-var-bitbucket); } +.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-bitcoin); } +.#{$fa-css-prefix}-bity:before { content: fa-content($fa-var-bity); } +.#{$fa-css-prefix}-black-tie:before { content: fa-content($fa-var-black-tie); } +.#{$fa-css-prefix}-blackberry:before { content: fa-content($fa-var-blackberry); } +.#{$fa-css-prefix}-blind:before { content: fa-content($fa-var-blind); } +.#{$fa-css-prefix}-blogger:before { content: fa-content($fa-var-blogger); } +.#{$fa-css-prefix}-blogger-b:before { content: fa-content($fa-var-blogger-b); } +.#{$fa-css-prefix}-bluetooth:before { content: fa-content($fa-var-bluetooth); } +.#{$fa-css-prefix}-bluetooth-b:before { content: fa-content($fa-var-bluetooth-b); } +.#{$fa-css-prefix}-bold:before { content: fa-content($fa-var-bold); } +.#{$fa-css-prefix}-bolt:before { content: fa-content($fa-var-bolt); } +.#{$fa-css-prefix}-bomb:before { content: fa-content($fa-var-bomb); } +.#{$fa-css-prefix}-book:before { content: fa-content($fa-var-book); } +.#{$fa-css-prefix}-bookmark:before { content: fa-content($fa-var-bookmark); } +.#{$fa-css-prefix}-braille:before { content: fa-content($fa-var-braille); } +.#{$fa-css-prefix}-briefcase:before { content: fa-content($fa-var-briefcase); } +.#{$fa-css-prefix}-btc:before { content: fa-content($fa-var-btc); } +.#{$fa-css-prefix}-bug:before { content: fa-content($fa-var-bug); } +.#{$fa-css-prefix}-building:before { content: fa-content($fa-var-building); } +.#{$fa-css-prefix}-bullhorn:before { content: fa-content($fa-var-bullhorn); } +.#{$fa-css-prefix}-bullseye:before { content: fa-content($fa-var-bullseye); } +.#{$fa-css-prefix}-buromobelexperte:before { content: fa-content($fa-var-buromobelexperte); } +.#{$fa-css-prefix}-bus:before { content: fa-content($fa-var-bus); } +.#{$fa-css-prefix}-buysellads:before { content: fa-content($fa-var-buysellads); } +.#{$fa-css-prefix}-calculator:before { content: fa-content($fa-var-calculator); } +.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar); } +.#{$fa-css-prefix}-calendar-alt:before { content: fa-content($fa-var-calendar-alt); } +.#{$fa-css-prefix}-calendar-check:before { content: fa-content($fa-var-calendar-check); } +.#{$fa-css-prefix}-calendar-minus:before { content: fa-content($fa-var-calendar-minus); } +.#{$fa-css-prefix}-calendar-plus:before { content: fa-content($fa-var-calendar-plus); } +.#{$fa-css-prefix}-calendar-times:before { content: fa-content($fa-var-calendar-times); } +.#{$fa-css-prefix}-camera:before { content: fa-content($fa-var-camera); } +.#{$fa-css-prefix}-camera-retro:before { content: fa-content($fa-var-camera-retro); } +.#{$fa-css-prefix}-car:before { content: fa-content($fa-var-car); } +.#{$fa-css-prefix}-caret-down:before { content: fa-content($fa-var-caret-down); } +.#{$fa-css-prefix}-caret-left:before { content: fa-content($fa-var-caret-left); } +.#{$fa-css-prefix}-caret-right:before { content: fa-content($fa-var-caret-right); } +.#{$fa-css-prefix}-caret-square-down:before { content: fa-content($fa-var-caret-square-down); } +.#{$fa-css-prefix}-caret-square-left:before { content: fa-content($fa-var-caret-square-left); } +.#{$fa-css-prefix}-caret-square-right:before { content: fa-content($fa-var-caret-square-right); } +.#{$fa-css-prefix}-caret-square-up:before { content: fa-content($fa-var-caret-square-up); } +.#{$fa-css-prefix}-caret-up:before { content: fa-content($fa-var-caret-up); } +.#{$fa-css-prefix}-cart-arrow-down:before { content: fa-content($fa-var-cart-arrow-down); } +.#{$fa-css-prefix}-cart-plus:before { content: fa-content($fa-var-cart-plus); } +.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); } +.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); } +.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); } +.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); } +.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); } +.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); } +.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); } +.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); } +.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); } +.#{$fa-css-prefix}-centercode:before { content: fa-content($fa-var-centercode); } +.#{$fa-css-prefix}-certificate:before { content: fa-content($fa-var-certificate); } +.#{$fa-css-prefix}-chart-area:before { content: fa-content($fa-var-chart-area); } +.#{$fa-css-prefix}-chart-bar:before { content: fa-content($fa-var-chart-bar); } +.#{$fa-css-prefix}-chart-line:before { content: fa-content($fa-var-chart-line); } +.#{$fa-css-prefix}-chart-pie:before { content: fa-content($fa-var-chart-pie); } +.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); } +.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); } +.#{$fa-css-prefix}-check-square:before { content: fa-content($fa-var-check-square); } +.#{$fa-css-prefix}-chevron-circle-down:before { content: fa-content($fa-var-chevron-circle-down); } +.#{$fa-css-prefix}-chevron-circle-left:before { content: fa-content($fa-var-chevron-circle-left); } +.#{$fa-css-prefix}-chevron-circle-right:before { content: fa-content($fa-var-chevron-circle-right); } +.#{$fa-css-prefix}-chevron-circle-up:before { content: fa-content($fa-var-chevron-circle-up); } +.#{$fa-css-prefix}-chevron-down:before { content: fa-content($fa-var-chevron-down); } +.#{$fa-css-prefix}-chevron-left:before { content: fa-content($fa-var-chevron-left); } +.#{$fa-css-prefix}-chevron-right:before { content: fa-content($fa-var-chevron-right); } +.#{$fa-css-prefix}-chevron-up:before { content: fa-content($fa-var-chevron-up); } +.#{$fa-css-prefix}-child:before { content: fa-content($fa-var-child); } +.#{$fa-css-prefix}-chrome:before { content: fa-content($fa-var-chrome); } +.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); } +.#{$fa-css-prefix}-circle-notch:before { content: fa-content($fa-var-circle-notch); } +.#{$fa-css-prefix}-clipboard:before { content: fa-content($fa-var-clipboard); } +.#{$fa-css-prefix}-clock:before { content: fa-content($fa-var-clock); } +.#{$fa-css-prefix}-clone:before { content: fa-content($fa-var-clone); } +.#{$fa-css-prefix}-closed-captioning:before { content: fa-content($fa-var-closed-captioning); } +.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); } +.#{$fa-css-prefix}-cloud-download-alt:before { content: fa-content($fa-var-cloud-download-alt); } +.#{$fa-css-prefix}-cloud-upload-alt:before { content: fa-content($fa-var-cloud-upload-alt); } +.#{$fa-css-prefix}-cloudscale:before { content: fa-content($fa-var-cloudscale); } +.#{$fa-css-prefix}-cloudsmith:before { content: fa-content($fa-var-cloudsmith); } +.#{$fa-css-prefix}-cloudversify:before { content: fa-content($fa-var-cloudversify); } +.#{$fa-css-prefix}-code:before { content: fa-content($fa-var-code); } +.#{$fa-css-prefix}-code-branch:before { content: fa-content($fa-var-code-branch); } +.#{$fa-css-prefix}-codepen:before { content: fa-content($fa-var-codepen); } +.#{$fa-css-prefix}-codiepie:before { content: fa-content($fa-var-codiepie); } +.#{$fa-css-prefix}-coffee:before { content: fa-content($fa-var-coffee); } +.#{$fa-css-prefix}-cog:before { content: fa-content($fa-var-cog); } +.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); } +.#{$fa-css-prefix}-columns:before { content: fa-content($fa-var-columns); } +.#{$fa-css-prefix}-comment:before { content: fa-content($fa-var-comment); } +.#{$fa-css-prefix}-comment-alt:before { content: fa-content($fa-var-comment-alt); } +.#{$fa-css-prefix}-comments:before { content: fa-content($fa-var-comments); } +.#{$fa-css-prefix}-compass:before { content: fa-content($fa-var-compass); } +.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress); } +.#{$fa-css-prefix}-connectdevelop:before { content: fa-content($fa-var-connectdevelop); } +.#{$fa-css-prefix}-contao:before { content: fa-content($fa-var-contao); } +.#{$fa-css-prefix}-copy:before { content: fa-content($fa-var-copy); } +.#{$fa-css-prefix}-copyright:before { content: fa-content($fa-var-copyright); } +.#{$fa-css-prefix}-cpanel:before { content: fa-content($fa-var-cpanel); } +.#{$fa-css-prefix}-creative-commons:before { content: fa-content($fa-var-creative-commons); } +.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); } +.#{$fa-css-prefix}-crop:before { content: fa-content($fa-var-crop); } +.#{$fa-css-prefix}-crosshairs:before { content: fa-content($fa-var-crosshairs); } +.#{$fa-css-prefix}-css3:before { content: fa-content($fa-var-css3); } +.#{$fa-css-prefix}-css3-alt:before { content: fa-content($fa-var-css3-alt); } +.#{$fa-css-prefix}-cube:before { content: fa-content($fa-var-cube); } +.#{$fa-css-prefix}-cubes:before { content: fa-content($fa-var-cubes); } +.#{$fa-css-prefix}-cut:before { content: fa-content($fa-var-cut); } +.#{$fa-css-prefix}-cuttlefish:before { content: fa-content($fa-var-cuttlefish); } +.#{$fa-css-prefix}-d-and-d:before { content: fa-content($fa-var-d-and-d); } +.#{$fa-css-prefix}-dashcube:before { content: fa-content($fa-var-dashcube); } +.#{$fa-css-prefix}-database:before { content: fa-content($fa-var-database); } +.#{$fa-css-prefix}-deaf:before { content: fa-content($fa-var-deaf); } +.#{$fa-css-prefix}-delicious:before { content: fa-content($fa-var-delicious); } +.#{$fa-css-prefix}-deploydog:before { content: fa-content($fa-var-deploydog); } +.#{$fa-css-prefix}-deskpro:before { content: fa-content($fa-var-deskpro); } +.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); } +.#{$fa-css-prefix}-deviantart:before { content: fa-content($fa-var-deviantart); } +.#{$fa-css-prefix}-digg:before { content: fa-content($fa-var-digg); } +.#{$fa-css-prefix}-digital-ocean:before { content: fa-content($fa-var-digital-ocean); } +.#{$fa-css-prefix}-discord:before { content: fa-content($fa-var-discord); } +.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); } +.#{$fa-css-prefix}-dochub:before { content: fa-content($fa-var-dochub); } +.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); } +.#{$fa-css-prefix}-dollar-sign:before { content: fa-content($fa-var-dollar-sign); } +.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); } +.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-download); } +.#{$fa-css-prefix}-draft2digital:before { content: fa-content($fa-var-draft2digital); } +.#{$fa-css-prefix}-dribbble:before { content: fa-content($fa-var-dribbble); } +.#{$fa-css-prefix}-dribbble-square:before { content: fa-content($fa-var-dribbble-square); } +.#{$fa-css-prefix}-dropbox:before { content: fa-content($fa-var-dropbox); } +.#{$fa-css-prefix}-drupal:before { content: fa-content($fa-var-drupal); } +.#{$fa-css-prefix}-dyalog:before { content: fa-content($fa-var-dyalog); } +.#{$fa-css-prefix}-earlybirds:before { content: fa-content($fa-var-earlybirds); } +.#{$fa-css-prefix}-edge:before { content: fa-content($fa-var-edge); } +.#{$fa-css-prefix}-edit:before { content: fa-content($fa-var-edit); } +.#{$fa-css-prefix}-eject:before { content: fa-content($fa-var-eject); } +.#{$fa-css-prefix}-ellipsis-h:before { content: fa-content($fa-var-ellipsis-h); } +.#{$fa-css-prefix}-ellipsis-v:before { content: fa-content($fa-var-ellipsis-v); } +.#{$fa-css-prefix}-ember:before { content: fa-content($fa-var-ember); } +.#{$fa-css-prefix}-empire:before { content: fa-content($fa-var-empire); } +.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); } +.#{$fa-css-prefix}-envelope-open:before { content: fa-content($fa-var-envelope-open); } +.#{$fa-css-prefix}-envelope-square:before { content: fa-content($fa-var-envelope-square); } +.#{$fa-css-prefix}-envira:before { content: fa-content($fa-var-envira); } +.#{$fa-css-prefix}-eraser:before { content: fa-content($fa-var-eraser); } +.#{$fa-css-prefix}-erlang:before { content: fa-content($fa-var-erlang); } +.#{$fa-css-prefix}-etsy:before { content: fa-content($fa-var-etsy); } +.#{$fa-css-prefix}-euro-sign:before { content: fa-content($fa-var-euro-sign); } +.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); } +.#{$fa-css-prefix}-exclamation:before { content: fa-content($fa-var-exclamation); } +.#{$fa-css-prefix}-exclamation-circle:before { content: fa-content($fa-var-exclamation-circle); } +.#{$fa-css-prefix}-exclamation-triangle:before { content: fa-content($fa-var-exclamation-triangle); } +.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand); } +.#{$fa-css-prefix}-expand-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } +.#{$fa-css-prefix}-expeditedssl:before { content: fa-content($fa-var-expeditedssl); } +.#{$fa-css-prefix}-external-link-alt:before { content: fa-content($fa-var-external-link-alt); } +.#{$fa-css-prefix}-external-link-square-alt:before { content: fa-content($fa-var-external-link-square-alt); } +.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); } +.#{$fa-css-prefix}-eye-dropper:before { content: fa-content($fa-var-eye-dropper); } +.#{$fa-css-prefix}-eye-slash:before { content: fa-content($fa-var-eye-slash); } +.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook); } +.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } +.#{$fa-css-prefix}-facebook-messenger:before { content: fa-content($fa-var-facebook-messenger); } +.#{$fa-css-prefix}-facebook-square:before { content: fa-content($fa-var-facebook-square); } +.#{$fa-css-prefix}-fast-backward:before { content: fa-content($fa-var-fast-backward); } +.#{$fa-css-prefix}-fast-forward:before { content: fa-content($fa-var-fast-forward); } +.#{$fa-css-prefix}-fax:before { content: fa-content($fa-var-fax); } +.#{$fa-css-prefix}-female:before { content: fa-content($fa-var-female); } +.#{$fa-css-prefix}-fighter-jet:before { content: fa-content($fa-var-fighter-jet); } +.#{$fa-css-prefix}-file:before { content: fa-content($fa-var-file); } +.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); } +.#{$fa-css-prefix}-file-archive:before { content: fa-content($fa-var-file-archive); } +.#{$fa-css-prefix}-file-audio:before { content: fa-content($fa-var-file-audio); } +.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); } +.#{$fa-css-prefix}-file-excel:before { content: fa-content($fa-var-file-excel); } +.#{$fa-css-prefix}-file-image:before { content: fa-content($fa-var-file-image); } +.#{$fa-css-prefix}-file-pdf:before { content: fa-content($fa-var-file-pdf); } +.#{$fa-css-prefix}-file-powerpoint:before { content: fa-content($fa-var-file-powerpoint); } +.#{$fa-css-prefix}-file-video:before { content: fa-content($fa-var-file-video); } +.#{$fa-css-prefix}-file-word:before { content: fa-content($fa-var-file-word); } +.#{$fa-css-prefix}-film:before { content: fa-content($fa-var-film); } +.#{$fa-css-prefix}-filter:before { content: fa-content($fa-var-filter); } +.#{$fa-css-prefix}-fire:before { content: fa-content($fa-var-fire); } +.#{$fa-css-prefix}-fire-extinguisher:before { content: fa-content($fa-var-fire-extinguisher); } +.#{$fa-css-prefix}-firefox:before { content: fa-content($fa-var-firefox); } +.#{$fa-css-prefix}-first-order:before { content: fa-content($fa-var-first-order); } +.#{$fa-css-prefix}-firstdraft:before { content: fa-content($fa-var-firstdraft); } +.#{$fa-css-prefix}-flag:before { content: fa-content($fa-var-flag); } +.#{$fa-css-prefix}-flag-checkered:before { content: fa-content($fa-var-flag-checkered); } +.#{$fa-css-prefix}-flask:before { content: fa-content($fa-var-flask); } +.#{$fa-css-prefix}-flickr:before { content: fa-content($fa-var-flickr); } +.#{$fa-css-prefix}-fly:before { content: fa-content($fa-var-fly); } +.#{$fa-css-prefix}-folder:before { content: fa-content($fa-var-folder); } +.#{$fa-css-prefix}-folder-open:before { content: fa-content($fa-var-folder-open); } +.#{$fa-css-prefix}-font:before { content: fa-content($fa-var-font); } +.#{$fa-css-prefix}-font-awesome:before { content: fa-content($fa-var-font-awesome); } +.#{$fa-css-prefix}-font-awesome-alt:before { content: fa-content($fa-var-font-awesome-alt); } +.#{$fa-css-prefix}-font-awesome-flag:before { content: fa-content($fa-var-font-awesome-flag); } +.#{$fa-css-prefix}-fonticons:before { content: fa-content($fa-var-fonticons); } +.#{$fa-css-prefix}-fonticons-fi:before { content: fa-content($fa-var-fonticons-fi); } +.#{$fa-css-prefix}-fort-awesome:before { content: fa-content($fa-var-fort-awesome); } +.#{$fa-css-prefix}-fort-awesome-alt:before { content: fa-content($fa-var-fort-awesome-alt); } +.#{$fa-css-prefix}-forumbee:before { content: fa-content($fa-var-forumbee); } +.#{$fa-css-prefix}-forward:before { content: fa-content($fa-var-forward); } +.#{$fa-css-prefix}-foursquare:before { content: fa-content($fa-var-foursquare); } +.#{$fa-css-prefix}-free-code-camp:before { content: fa-content($fa-var-free-code-camp); } +.#{$fa-css-prefix}-freebsd:before { content: fa-content($fa-var-freebsd); } +.#{$fa-css-prefix}-frown:before { content: fa-content($fa-var-frown); } +.#{$fa-css-prefix}-futbol:before { content: fa-content($fa-var-futbol); } +.#{$fa-css-prefix}-gamepad:before { content: fa-content($fa-var-gamepad); } +.#{$fa-css-prefix}-gavel:before { content: fa-content($fa-var-gavel); } +.#{$fa-css-prefix}-gem:before { content: fa-content($fa-var-gem); } +.#{$fa-css-prefix}-genderless:before { content: fa-content($fa-var-genderless); } +.#{$fa-css-prefix}-get-pocket:before { content: fa-content($fa-var-get-pocket); } +.#{$fa-css-prefix}-gg:before { content: fa-content($fa-var-gg); } +.#{$fa-css-prefix}-gg-circle:before { content: fa-content($fa-var-gg-circle); } +.#{$fa-css-prefix}-gift:before { content: fa-content($fa-var-gift); } +.#{$fa-css-prefix}-git:before { content: fa-content($fa-var-git); } +.#{$fa-css-prefix}-git-square:before { content: fa-content($fa-var-git-square); } +.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); } +.#{$fa-css-prefix}-github-alt:before { content: fa-content($fa-var-github-alt); } +.#{$fa-css-prefix}-github-square:before { content: fa-content($fa-var-github-square); } +.#{$fa-css-prefix}-gitkraken:before { content: fa-content($fa-var-gitkraken); } +.#{$fa-css-prefix}-gitlab:before { content: fa-content($fa-var-gitlab); } +.#{$fa-css-prefix}-gitter:before { content: fa-content($fa-var-gitter); } +.#{$fa-css-prefix}-glass-martini:before { content: fa-content($fa-var-glass-martini); } +.#{$fa-css-prefix}-glide:before { content: fa-content($fa-var-glide); } +.#{$fa-css-prefix}-glide-g:before { content: fa-content($fa-var-glide-g); } +.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); } +.#{$fa-css-prefix}-gofore:before { content: fa-content($fa-var-gofore); } +.#{$fa-css-prefix}-goodreads:before { content: fa-content($fa-var-goodreads); } +.#{$fa-css-prefix}-goodreads-g:before { content: fa-content($fa-var-goodreads-g); } +.#{$fa-css-prefix}-google:before { content: fa-content($fa-var-google); } +.#{$fa-css-prefix}-google-drive:before { content: fa-content($fa-var-google-drive); } +.#{$fa-css-prefix}-google-play:before { content: fa-content($fa-var-google-play); } +.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus); } +.#{$fa-css-prefix}-google-plus-g:before { content: fa-content($fa-var-google-plus-g); } +.#{$fa-css-prefix}-google-plus-square:before { content: fa-content($fa-var-google-plus-square); } +.#{$fa-css-prefix}-google-wallet:before { content: fa-content($fa-var-google-wallet); } +.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); } +.#{$fa-css-prefix}-gratipay:before { content: fa-content($fa-var-gratipay); } +.#{$fa-css-prefix}-grav:before { content: fa-content($fa-var-grav); } +.#{$fa-css-prefix}-gripfire:before { content: fa-content($fa-var-gripfire); } +.#{$fa-css-prefix}-grunt:before { content: fa-content($fa-var-grunt); } +.#{$fa-css-prefix}-gulp:before { content: fa-content($fa-var-gulp); } +.#{$fa-css-prefix}-h-square:before { content: fa-content($fa-var-h-square); } +.#{$fa-css-prefix}-hacker-news:before { content: fa-content($fa-var-hacker-news); } +.#{$fa-css-prefix}-hacker-news-square:before { content: fa-content($fa-var-hacker-news-square); } +.#{$fa-css-prefix}-hand-lizard:before { content: fa-content($fa-var-hand-lizard); } +.#{$fa-css-prefix}-hand-paper:before { content: fa-content($fa-var-hand-paper); } +.#{$fa-css-prefix}-hand-peace:before { content: fa-content($fa-var-hand-peace); } +.#{$fa-css-prefix}-hand-point-down:before { content: fa-content($fa-var-hand-point-down); } +.#{$fa-css-prefix}-hand-point-left:before { content: fa-content($fa-var-hand-point-left); } +.#{$fa-css-prefix}-hand-point-right:before { content: fa-content($fa-var-hand-point-right); } +.#{$fa-css-prefix}-hand-point-up:before { content: fa-content($fa-var-hand-point-up); } +.#{$fa-css-prefix}-hand-pointer:before { content: fa-content($fa-var-hand-pointer); } +.#{$fa-css-prefix}-hand-rock:before { content: fa-content($fa-var-hand-rock); } +.#{$fa-css-prefix}-hand-scissors:before { content: fa-content($fa-var-hand-scissors); } +.#{$fa-css-prefix}-hand-spock:before { content: fa-content($fa-var-hand-spock); } +.#{$fa-css-prefix}-handshake:before { content: fa-content($fa-var-handshake); } +.#{$fa-css-prefix}-hashtag:before { content: fa-content($fa-var-hashtag); } +.#{$fa-css-prefix}-hdd:before { content: fa-content($fa-var-hdd); } +.#{$fa-css-prefix}-heading:before { content: fa-content($fa-var-heading); } +.#{$fa-css-prefix}-headphones:before { content: fa-content($fa-var-headphones); } +.#{$fa-css-prefix}-heart:before { content: fa-content($fa-var-heart); } +.#{$fa-css-prefix}-heartbeat:before { content: fa-content($fa-var-heartbeat); } +.#{$fa-css-prefix}-hire-a-helper:before { content: fa-content($fa-var-hire-a-helper); } +.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); } +.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); } +.#{$fa-css-prefix}-hooli:before { content: fa-content($fa-var-hooli); } +.#{$fa-css-prefix}-hospital:before { content: fa-content($fa-var-hospital); } +.#{$fa-css-prefix}-hotjar:before { content: fa-content($fa-var-hotjar); } +.#{$fa-css-prefix}-hourglass:before { content: fa-content($fa-var-hourglass); } +.#{$fa-css-prefix}-hourglass-end:before { content: fa-content($fa-var-hourglass-end); } +.#{$fa-css-prefix}-hourglass-half:before { content: fa-content($fa-var-hourglass-half); } +.#{$fa-css-prefix}-hourglass-start:before { content: fa-content($fa-var-hourglass-start); } +.#{$fa-css-prefix}-houzz:before { content: fa-content($fa-var-houzz); } +.#{$fa-css-prefix}-html5:before { content: fa-content($fa-var-html5); } +.#{$fa-css-prefix}-hubspot:before { content: fa-content($fa-var-hubspot); } +.#{$fa-css-prefix}-i-cursor:before { content: fa-content($fa-var-i-cursor); } +.#{$fa-css-prefix}-id-badge:before { content: fa-content($fa-var-id-badge); } +.#{$fa-css-prefix}-id-card:before { content: fa-content($fa-var-id-card); } +.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } +.#{$fa-css-prefix}-images:before { content: fa-content($fa-var-images); } +.#{$fa-css-prefix}-imdb:before { content: fa-content($fa-var-imdb); } +.#{$fa-css-prefix}-inbox:before { content: fa-content($fa-var-inbox); } +.#{$fa-css-prefix}-indent:before { content: fa-content($fa-var-indent); } +.#{$fa-css-prefix}-industry:before { content: fa-content($fa-var-industry); } +.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); } +.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); } +.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); } +.#{$fa-css-prefix}-internet-explorer:before { content: fa-content($fa-var-internet-explorer); } +.#{$fa-css-prefix}-ioxhost:before { content: fa-content($fa-var-ioxhost); } +.#{$fa-css-prefix}-italic:before { content: fa-content($fa-var-italic); } +.#{$fa-css-prefix}-itunes:before { content: fa-content($fa-var-itunes); } +.#{$fa-css-prefix}-itunes-note:before { content: fa-content($fa-var-itunes-note); } +.#{$fa-css-prefix}-jenkins:before { content: fa-content($fa-var-jenkins); } +.#{$fa-css-prefix}-joget:before { content: fa-content($fa-var-joget); } +.#{$fa-css-prefix}-joomla:before { content: fa-content($fa-var-joomla); } +.#{$fa-css-prefix}-js:before { content: fa-content($fa-var-js); } +.#{$fa-css-prefix}-js-square:before { content: fa-content($fa-var-js-square); } +.#{$fa-css-prefix}-jsfiddle:before { content: fa-content($fa-var-jsfiddle); } +.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); } +.#{$fa-css-prefix}-keyboard:before { content: fa-content($fa-var-keyboard); } +.#{$fa-css-prefix}-keycdn:before { content: fa-content($fa-var-keycdn); } +.#{$fa-css-prefix}-kickstarter:before { content: fa-content($fa-var-kickstarter); } +.#{$fa-css-prefix}-kickstarter-k:before { content: fa-content($fa-var-kickstarter-k); } +.#{$fa-css-prefix}-language:before { content: fa-content($fa-var-language); } +.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); } +.#{$fa-css-prefix}-laravel:before { content: fa-content($fa-var-laravel); } +.#{$fa-css-prefix}-lastfm:before { content: fa-content($fa-var-lastfm); } +.#{$fa-css-prefix}-lastfm-square:before { content: fa-content($fa-var-lastfm-square); } +.#{$fa-css-prefix}-leaf:before { content: fa-content($fa-var-leaf); } +.#{$fa-css-prefix}-leanpub:before { content: fa-content($fa-var-leanpub); } +.#{$fa-css-prefix}-lemon:before { content: fa-content($fa-var-lemon); } +.#{$fa-css-prefix}-less:before { content: fa-content($fa-var-less); } +.#{$fa-css-prefix}-level-down-alt:before { content: fa-content($fa-var-level-down-alt); } +.#{$fa-css-prefix}-level-up-alt:before { content: fa-content($fa-var-level-up-alt); } +.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); } +.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); } +.#{$fa-css-prefix}-line:before { content: fa-content($fa-var-line); } +.#{$fa-css-prefix}-link:before { content: fa-content($fa-var-link); } +.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin); } +.#{$fa-css-prefix}-linkedin-in:before { content: fa-content($fa-var-linkedin-in); } +.#{$fa-css-prefix}-linode:before { content: fa-content($fa-var-linode); } +.#{$fa-css-prefix}-linux:before { content: fa-content($fa-var-linux); } +.#{$fa-css-prefix}-lira-sign:before { content: fa-content($fa-var-lira-sign); } +.#{$fa-css-prefix}-list:before { content: fa-content($fa-var-list); } +.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); } +.#{$fa-css-prefix}-list-ol:before { content: fa-content($fa-var-list-ol); } +.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); } +.#{$fa-css-prefix}-location-arrow:before { content: fa-content($fa-var-location-arrow); } +.#{$fa-css-prefix}-lock:before { content: fa-content($fa-var-lock); } +.#{$fa-css-prefix}-lock-open:before { content: fa-content($fa-var-lock-open); } +.#{$fa-css-prefix}-long-arrow-alt-down:before { content: fa-content($fa-var-long-arrow-alt-down); } +.#{$fa-css-prefix}-long-arrow-alt-left:before { content: fa-content($fa-var-long-arrow-alt-left); } +.#{$fa-css-prefix}-long-arrow-alt-right:before { content: fa-content($fa-var-long-arrow-alt-right); } +.#{$fa-css-prefix}-long-arrow-alt-up:before { content: fa-content($fa-var-long-arrow-alt-up); } +.#{$fa-css-prefix}-low-vision:before { content: fa-content($fa-var-low-vision); } +.#{$fa-css-prefix}-lyft:before { content: fa-content($fa-var-lyft); } +.#{$fa-css-prefix}-magento:before { content: fa-content($fa-var-magento); } +.#{$fa-css-prefix}-magic:before { content: fa-content($fa-var-magic); } +.#{$fa-css-prefix}-magnet:before { content: fa-content($fa-var-magnet); } +.#{$fa-css-prefix}-male:before { content: fa-content($fa-var-male); } +.#{$fa-css-prefix}-map:before { content: fa-content($fa-var-map); } +.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker); } +.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); } +.#{$fa-css-prefix}-map-pin:before { content: fa-content($fa-var-map-pin); } +.#{$fa-css-prefix}-map-signs:before { content: fa-content($fa-var-map-signs); } +.#{$fa-css-prefix}-mars:before { content: fa-content($fa-var-mars); } +.#{$fa-css-prefix}-mars-double:before { content: fa-content($fa-var-mars-double); } +.#{$fa-css-prefix}-mars-stroke:before { content: fa-content($fa-var-mars-stroke); } +.#{$fa-css-prefix}-mars-stroke-h:before { content: fa-content($fa-var-mars-stroke-h); } +.#{$fa-css-prefix}-mars-stroke-v:before { content: fa-content($fa-var-mars-stroke-v); } +.#{$fa-css-prefix}-maxcdn:before { content: fa-content($fa-var-maxcdn); } +.#{$fa-css-prefix}-medapps:before { content: fa-content($fa-var-medapps); } +.#{$fa-css-prefix}-medium:before { content: fa-content($fa-var-medium); } +.#{$fa-css-prefix}-medium-m:before { content: fa-content($fa-var-medium-m); } +.#{$fa-css-prefix}-medkit:before { content: fa-content($fa-var-medkit); } +.#{$fa-css-prefix}-medrt:before { content: fa-content($fa-var-medrt); } +.#{$fa-css-prefix}-meetup:before { content: fa-content($fa-var-meetup); } +.#{$fa-css-prefix}-meh:before { content: fa-content($fa-var-meh); } +.#{$fa-css-prefix}-mercury:before { content: fa-content($fa-var-mercury); } +.#{$fa-css-prefix}-microchip:before { content: fa-content($fa-var-microchip); } +.#{$fa-css-prefix}-microphone:before { content: fa-content($fa-var-microphone); } +.#{$fa-css-prefix}-microphone-slash:before { content: fa-content($fa-var-microphone-slash); } +.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); } +.#{$fa-css-prefix}-minus:before { content: fa-content($fa-var-minus); } +.#{$fa-css-prefix}-minus-circle:before { content: fa-content($fa-var-minus-circle); } +.#{$fa-css-prefix}-minus-square:before { content: fa-content($fa-var-minus-square); } +.#{$fa-css-prefix}-mix:before { content: fa-content($fa-var-mix); } +.#{$fa-css-prefix}-mixcloud:before { content: fa-content($fa-var-mixcloud); } +.#{$fa-css-prefix}-mizuni:before { content: fa-content($fa-var-mizuni); } +.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile); } +.#{$fa-css-prefix}-mobile-alt:before { content: fa-content($fa-var-mobile-alt); } +.#{$fa-css-prefix}-modx:before { content: fa-content($fa-var-modx); } +.#{$fa-css-prefix}-monero:before { content: fa-content($fa-var-monero); } +.#{$fa-css-prefix}-money-bill-alt:before { content: fa-content($fa-var-money-bill-alt); } +.#{$fa-css-prefix}-moon:before { content: fa-content($fa-var-moon); } +.#{$fa-css-prefix}-motorcycle:before { content: fa-content($fa-var-motorcycle); } +.#{$fa-css-prefix}-mouse-pointer:before { content: fa-content($fa-var-mouse-pointer); } +.#{$fa-css-prefix}-music:before { content: fa-content($fa-var-music); } +.#{$fa-css-prefix}-napster:before { content: fa-content($fa-var-napster); } +.#{$fa-css-prefix}-neuter:before { content: fa-content($fa-var-neuter); } +.#{$fa-css-prefix}-newspaper:before { content: fa-content($fa-var-newspaper); } +.#{$fa-css-prefix}-nintendo-switch:before { content: fa-content($fa-var-nintendo-switch); } +.#{$fa-css-prefix}-node:before { content: fa-content($fa-var-node); } +.#{$fa-css-prefix}-node-js:before { content: fa-content($fa-var-node-js); } +.#{$fa-css-prefix}-npm:before { content: fa-content($fa-var-npm); } +.#{$fa-css-prefix}-ns8:before { content: fa-content($fa-var-ns8); } +.#{$fa-css-prefix}-nutritionix:before { content: fa-content($fa-var-nutritionix); } +.#{$fa-css-prefix}-object-group:before { content: fa-content($fa-var-object-group); } +.#{$fa-css-prefix}-object-ungroup:before { content: fa-content($fa-var-object-ungroup); } +.#{$fa-css-prefix}-odnoklassniki:before { content: fa-content($fa-var-odnoklassniki); } +.#{$fa-css-prefix}-odnoklassniki-square:before { content: fa-content($fa-var-odnoklassniki-square); } +.#{$fa-css-prefix}-opencart:before { content: fa-content($fa-var-opencart); } +.#{$fa-css-prefix}-openid:before { content: fa-content($fa-var-openid); } +.#{$fa-css-prefix}-opera:before { content: fa-content($fa-var-opera); } +.#{$fa-css-prefix}-optin-monster:before { content: fa-content($fa-var-optin-monster); } +.#{$fa-css-prefix}-osi:before { content: fa-content($fa-var-osi); } +.#{$fa-css-prefix}-outdent:before { content: fa-content($fa-var-outdent); } +.#{$fa-css-prefix}-page4:before { content: fa-content($fa-var-page4); } +.#{$fa-css-prefix}-pagelines:before { content: fa-content($fa-var-pagelines); } +.#{$fa-css-prefix}-paint-brush:before { content: fa-content($fa-var-paint-brush); } +.#{$fa-css-prefix}-palfed:before { content: fa-content($fa-var-palfed); } +.#{$fa-css-prefix}-paper-plane:before { content: fa-content($fa-var-paper-plane); } +.#{$fa-css-prefix}-paperclip:before { content: fa-content($fa-var-paperclip); } +.#{$fa-css-prefix}-paragraph:before { content: fa-content($fa-var-paragraph); } +.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-paste); } +.#{$fa-css-prefix}-patreon:before { content: fa-content($fa-var-patreon); } +.#{$fa-css-prefix}-pause:before { content: fa-content($fa-var-pause); } +.#{$fa-css-prefix}-pause-circle:before { content: fa-content($fa-var-pause-circle); } +.#{$fa-css-prefix}-paw:before { content: fa-content($fa-var-paw); } +.#{$fa-css-prefix}-paypal:before { content: fa-content($fa-var-paypal); } +.#{$fa-css-prefix}-pen-square:before { content: fa-content($fa-var-pen-square); } +.#{$fa-css-prefix}-pencil-alt:before { content: fa-content($fa-var-pencil-alt); } +.#{$fa-css-prefix}-percent:before { content: fa-content($fa-var-percent); } +.#{$fa-css-prefix}-periscope:before { content: fa-content($fa-var-periscope); } +.#{$fa-css-prefix}-phabricator:before { content: fa-content($fa-var-phabricator); } +.#{$fa-css-prefix}-phoenix-framework:before { content: fa-content($fa-var-phoenix-framework); } +.#{$fa-css-prefix}-phone:before { content: fa-content($fa-var-phone); } +.#{$fa-css-prefix}-phone-square:before { content: fa-content($fa-var-phone-square); } +.#{$fa-css-prefix}-phone-volume:before { content: fa-content($fa-var-phone-volume); } +.#{$fa-css-prefix}-pied-piper:before { content: fa-content($fa-var-pied-piper); } +.#{$fa-css-prefix}-pied-piper-alt:before { content: fa-content($fa-var-pied-piper-alt); } +.#{$fa-css-prefix}-pied-piper-pp:before { content: fa-content($fa-var-pied-piper-pp); } +.#{$fa-css-prefix}-pinterest:before { content: fa-content($fa-var-pinterest); } +.#{$fa-css-prefix}-pinterest-p:before { content: fa-content($fa-var-pinterest-p); } +.#{$fa-css-prefix}-pinterest-square:before { content: fa-content($fa-var-pinterest-square); } +.#{$fa-css-prefix}-plane:before { content: fa-content($fa-var-plane); } +.#{$fa-css-prefix}-play:before { content: fa-content($fa-var-play); } +.#{$fa-css-prefix}-play-circle:before { content: fa-content($fa-var-play-circle); } +.#{$fa-css-prefix}-playstation:before { content: fa-content($fa-var-playstation); } +.#{$fa-css-prefix}-plug:before { content: fa-content($fa-var-plug); } +.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); } +.#{$fa-css-prefix}-plus-circle:before { content: fa-content($fa-var-plus-circle); } +.#{$fa-css-prefix}-plus-square:before { content: fa-content($fa-var-plus-square); } +.#{$fa-css-prefix}-podcast:before { content: fa-content($fa-var-podcast); } +.#{$fa-css-prefix}-pound-sign:before { content: fa-content($fa-var-pound-sign); } +.#{$fa-css-prefix}-power-off:before { content: fa-content($fa-var-power-off); } +.#{$fa-css-prefix}-print:before { content: fa-content($fa-var-print); } +.#{$fa-css-prefix}-product-hunt:before { content: fa-content($fa-var-product-hunt); } +.#{$fa-css-prefix}-pushed:before { content: fa-content($fa-var-pushed); } +.#{$fa-css-prefix}-puzzle-piece:before { content: fa-content($fa-var-puzzle-piece); } +.#{$fa-css-prefix}-python:before { content: fa-content($fa-var-python); } +.#{$fa-css-prefix}-qq:before { content: fa-content($fa-var-qq); } +.#{$fa-css-prefix}-qrcode:before { content: fa-content($fa-var-qrcode); } +.#{$fa-css-prefix}-question:before { content: fa-content($fa-var-question); } +.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); } +.#{$fa-css-prefix}-quora:before { content: fa-content($fa-var-quora); } +.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); } +.#{$fa-css-prefix}-quote-right:before { content: fa-content($fa-var-quote-right); } +.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); } +.#{$fa-css-prefix}-ravelry:before { content: fa-content($fa-var-ravelry); } +.#{$fa-css-prefix}-react:before { content: fa-content($fa-var-react); } +.#{$fa-css-prefix}-rebel:before { content: fa-content($fa-var-rebel); } +.#{$fa-css-prefix}-recycle:before { content: fa-content($fa-var-recycle); } +.#{$fa-css-prefix}-red-river:before { content: fa-content($fa-var-red-river); } +.#{$fa-css-prefix}-reddit:before { content: fa-content($fa-var-reddit); } +.#{$fa-css-prefix}-reddit-alien:before { content: fa-content($fa-var-reddit-alien); } +.#{$fa-css-prefix}-reddit-square:before { content: fa-content($fa-var-reddit-square); } +.#{$fa-css-prefix}-redo:before { content: fa-content($fa-var-redo); } +.#{$fa-css-prefix}-redo-alt:before { content: fa-content($fa-var-redo-alt); } +.#{$fa-css-prefix}-registered:before { content: fa-content($fa-var-registered); } +.#{$fa-css-prefix}-rendact:before { content: fa-content($fa-var-rendact); } +.#{$fa-css-prefix}-renren:before { content: fa-content($fa-var-renren); } +.#{$fa-css-prefix}-reply:before { content: fa-content($fa-var-reply); } +.#{$fa-css-prefix}-reply-all:before { content: fa-content($fa-var-reply-all); } +.#{$fa-css-prefix}-replyd:before { content: fa-content($fa-var-replyd); } +.#{$fa-css-prefix}-resolving:before { content: fa-content($fa-var-resolving); } +.#{$fa-css-prefix}-retweet:before { content: fa-content($fa-var-retweet); } +.#{$fa-css-prefix}-road:before { content: fa-content($fa-var-road); } +.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); } +.#{$fa-css-prefix}-rocketchat:before { content: fa-content($fa-var-rocketchat); } +.#{$fa-css-prefix}-rockrms:before { content: fa-content($fa-var-rockrms); } +.#{$fa-css-prefix}-rss:before { content: fa-content($fa-var-rss); } +.#{$fa-css-prefix}-rss-square:before { content: fa-content($fa-var-rss-square); } +.#{$fa-css-prefix}-ruble-sign:before { content: fa-content($fa-var-ruble-sign); } +.#{$fa-css-prefix}-rupee-sign:before { content: fa-content($fa-var-rupee-sign); } +.#{$fa-css-prefix}-safari:before { content: fa-content($fa-var-safari); } +.#{$fa-css-prefix}-sass:before { content: fa-content($fa-var-sass); } +.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); } +.#{$fa-css-prefix}-schlix:before { content: fa-content($fa-var-schlix); } +.#{$fa-css-prefix}-scribd:before { content: fa-content($fa-var-scribd); } +.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); } +.#{$fa-css-prefix}-search-minus:before { content: fa-content($fa-var-search-minus); } +.#{$fa-css-prefix}-search-plus:before { content: fa-content($fa-var-search-plus); } +.#{$fa-css-prefix}-searchengin:before { content: fa-content($fa-var-searchengin); } +.#{$fa-css-prefix}-sellcast:before { content: fa-content($fa-var-sellcast); } +.#{$fa-css-prefix}-sellsy:before { content: fa-content($fa-var-sellsy); } +.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); } +.#{$fa-css-prefix}-servicestack:before { content: fa-content($fa-var-servicestack); } +.#{$fa-css-prefix}-share:before { content: fa-content($fa-var-share); } +.#{$fa-css-prefix}-share-alt:before { content: fa-content($fa-var-share-alt); } +.#{$fa-css-prefix}-share-alt-square:before { content: fa-content($fa-var-share-alt-square); } +.#{$fa-css-prefix}-share-square:before { content: fa-content($fa-var-share-square); } +.#{$fa-css-prefix}-shekel-sign:before { content: fa-content($fa-var-shekel-sign); } +.#{$fa-css-prefix}-shield-alt:before { content: fa-content($fa-var-shield-alt); } +.#{$fa-css-prefix}-ship:before { content: fa-content($fa-var-ship); } +.#{$fa-css-prefix}-shirtsinbulk:before { content: fa-content($fa-var-shirtsinbulk); } +.#{$fa-css-prefix}-shopping-bag:before { content: fa-content($fa-var-shopping-bag); } +.#{$fa-css-prefix}-shopping-basket:before { content: fa-content($fa-var-shopping-basket); } +.#{$fa-css-prefix}-shopping-cart:before { content: fa-content($fa-var-shopping-cart); } +.#{$fa-css-prefix}-shower:before { content: fa-content($fa-var-shower); } +.#{$fa-css-prefix}-sign-in-alt:before { content: fa-content($fa-var-sign-in-alt); } +.#{$fa-css-prefix}-sign-language:before { content: fa-content($fa-var-sign-language); } +.#{$fa-css-prefix}-sign-out-alt:before { content: fa-content($fa-var-sign-out-alt); } +.#{$fa-css-prefix}-signal:before { content: fa-content($fa-var-signal); } +.#{$fa-css-prefix}-simplybuilt:before { content: fa-content($fa-var-simplybuilt); } +.#{$fa-css-prefix}-sistrix:before { content: fa-content($fa-var-sistrix); } +.#{$fa-css-prefix}-sitemap:before { content: fa-content($fa-var-sitemap); } +.#{$fa-css-prefix}-skyatlas:before { content: fa-content($fa-var-skyatlas); } +.#{$fa-css-prefix}-skype:before { content: fa-content($fa-var-skype); } +.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); } +.#{$fa-css-prefix}-slack-hash:before { content: fa-content($fa-var-slack-hash); } +.#{$fa-css-prefix}-sliders-h:before { content: fa-content($fa-var-sliders-h); } +.#{$fa-css-prefix}-slideshare:before { content: fa-content($fa-var-slideshare); } +.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); } +.#{$fa-css-prefix}-snapchat:before { content: fa-content($fa-var-snapchat); } +.#{$fa-css-prefix}-snapchat-ghost:before { content: fa-content($fa-var-snapchat-ghost); } +.#{$fa-css-prefix}-snapchat-square:before { content: fa-content($fa-var-snapchat-square); } +.#{$fa-css-prefix}-snowflake:before { content: fa-content($fa-var-snowflake); } +.#{$fa-css-prefix}-sort:before { content: fa-content($fa-var-sort); } +.#{$fa-css-prefix}-sort-alpha-down:before { content: fa-content($fa-var-sort-alpha-down); } +.#{$fa-css-prefix}-sort-alpha-up:before { content: fa-content($fa-var-sort-alpha-up); } +.#{$fa-css-prefix}-sort-amount-down:before { content: fa-content($fa-var-sort-amount-down); } +.#{$fa-css-prefix}-sort-amount-up:before { content: fa-content($fa-var-sort-amount-up); } +.#{$fa-css-prefix}-sort-down:before { content: fa-content($fa-var-sort-down); } +.#{$fa-css-prefix}-sort-numeric-down:before { content: fa-content($fa-var-sort-numeric-down); } +.#{$fa-css-prefix}-sort-numeric-up:before { content: fa-content($fa-var-sort-numeric-up); } +.#{$fa-css-prefix}-sort-up:before { content: fa-content($fa-var-sort-up); } +.#{$fa-css-prefix}-soundcloud:before { content: fa-content($fa-var-soundcloud); } +.#{$fa-css-prefix}-space-shuttle:before { content: fa-content($fa-var-space-shuttle); } +.#{$fa-css-prefix}-speakap:before { content: fa-content($fa-var-speakap); } +.#{$fa-css-prefix}-spinner:before { content: fa-content($fa-var-spinner); } +.#{$fa-css-prefix}-spotify:before { content: fa-content($fa-var-spotify); } +.#{$fa-css-prefix}-square:before { content: fa-content($fa-var-square); } +.#{$fa-css-prefix}-stack-exchange:before { content: fa-content($fa-var-stack-exchange); } +.#{$fa-css-prefix}-stack-overflow:before { content: fa-content($fa-var-stack-overflow); } +.#{$fa-css-prefix}-star:before { content: fa-content($fa-var-star); } +.#{$fa-css-prefix}-star-half:before { content: fa-content($fa-var-star-half); } +.#{$fa-css-prefix}-staylinked:before { content: fa-content($fa-var-staylinked); } +.#{$fa-css-prefix}-steam:before { content: fa-content($fa-var-steam); } +.#{$fa-css-prefix}-steam-square:before { content: fa-content($fa-var-steam-square); } +.#{$fa-css-prefix}-steam-symbol:before { content: fa-content($fa-var-steam-symbol); } +.#{$fa-css-prefix}-step-backward:before { content: fa-content($fa-var-step-backward); } +.#{$fa-css-prefix}-step-forward:before { content: fa-content($fa-var-step-forward); } +.#{$fa-css-prefix}-stethoscope:before { content: fa-content($fa-var-stethoscope); } +.#{$fa-css-prefix}-sticker-mule:before { content: fa-content($fa-var-sticker-mule); } +.#{$fa-css-prefix}-sticky-note:before { content: fa-content($fa-var-sticky-note); } +.#{$fa-css-prefix}-stop:before { content: fa-content($fa-var-stop); } +.#{$fa-css-prefix}-stop-circle:before { content: fa-content($fa-var-stop-circle); } +.#{$fa-css-prefix}-strava:before { content: fa-content($fa-var-strava); } +.#{$fa-css-prefix}-street-view:before { content: fa-content($fa-var-street-view); } +.#{$fa-css-prefix}-strikethrough:before { content: fa-content($fa-var-strikethrough); } +.#{$fa-css-prefix}-stripe:before { content: fa-content($fa-var-stripe); } +.#{$fa-css-prefix}-stripe-s:before { content: fa-content($fa-var-stripe-s); } +.#{$fa-css-prefix}-studiovinari:before { content: fa-content($fa-var-studiovinari); } +.#{$fa-css-prefix}-stumbleupon:before { content: fa-content($fa-var-stumbleupon); } +.#{$fa-css-prefix}-stumbleupon-circle:before { content: fa-content($fa-var-stumbleupon-circle); } +.#{$fa-css-prefix}-subscript:before { content: fa-content($fa-var-subscript); } +.#{$fa-css-prefix}-subway:before { content: fa-content($fa-var-subway); } +.#{$fa-css-prefix}-suitcase:before { content: fa-content($fa-var-suitcase); } +.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); } +.#{$fa-css-prefix}-superpowers:before { content: fa-content($fa-var-superpowers); } +.#{$fa-css-prefix}-superscript:before { content: fa-content($fa-var-superscript); } +.#{$fa-css-prefix}-supple:before { content: fa-content($fa-var-supple); } +.#{$fa-css-prefix}-sync:before { content: fa-content($fa-var-sync); } +.#{$fa-css-prefix}-sync-alt:before { content: fa-content($fa-var-sync-alt); } +.#{$fa-css-prefix}-table:before { content: fa-content($fa-var-table); } +.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet); } +.#{$fa-css-prefix}-tablet-alt:before { content: fa-content($fa-var-tablet-alt); } +.#{$fa-css-prefix}-tachometer-alt:before { content: fa-content($fa-var-tachometer-alt); } +.#{$fa-css-prefix}-tag:before { content: fa-content($fa-var-tag); } +.#{$fa-css-prefix}-tags:before { content: fa-content($fa-var-tags); } +.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); } +.#{$fa-css-prefix}-taxi:before { content: fa-content($fa-var-taxi); } +.#{$fa-css-prefix}-telegram:before { content: fa-content($fa-var-telegram); } +.#{$fa-css-prefix}-telegram-plane:before { content: fa-content($fa-var-telegram-plane); } +.#{$fa-css-prefix}-tencent-weibo:before { content: fa-content($fa-var-tencent-weibo); } +.#{$fa-css-prefix}-terminal:before { content: fa-content($fa-var-terminal); } +.#{$fa-css-prefix}-text-height:before { content: fa-content($fa-var-text-height); } +.#{$fa-css-prefix}-text-width:before { content: fa-content($fa-var-text-width); } +.#{$fa-css-prefix}-th:before { content: fa-content($fa-var-th); } +.#{$fa-css-prefix}-th-large:before { content: fa-content($fa-var-th-large); } +.#{$fa-css-prefix}-th-list:before { content: fa-content($fa-var-th-list); } +.#{$fa-css-prefix}-themeisle:before { content: fa-content($fa-var-themeisle); } +.#{$fa-css-prefix}-thermometer-empty:before { content: fa-content($fa-var-thermometer-empty); } +.#{$fa-css-prefix}-thermometer-full:before { content: fa-content($fa-var-thermometer-full); } +.#{$fa-css-prefix}-thermometer-half:before { content: fa-content($fa-var-thermometer-half); } +.#{$fa-css-prefix}-thermometer-quarter:before { content: fa-content($fa-var-thermometer-quarter); } +.#{$fa-css-prefix}-thermometer-three-quarters:before { content: fa-content($fa-var-thermometer-three-quarters); } +.#{$fa-css-prefix}-thumbs-down:before { content: fa-content($fa-var-thumbs-down); } +.#{$fa-css-prefix}-thumbs-up:before { content: fa-content($fa-var-thumbs-up); } +.#{$fa-css-prefix}-thumbtack:before { content: fa-content($fa-var-thumbtack); } +.#{$fa-css-prefix}-ticket-alt:before { content: fa-content($fa-var-ticket-alt); } +.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); } +.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); } +.#{$fa-css-prefix}-tint:before { content: fa-content($fa-var-tint); } +.#{$fa-css-prefix}-toggle-off:before { content: fa-content($fa-var-toggle-off); } +.#{$fa-css-prefix}-toggle-on:before { content: fa-content($fa-var-toggle-on); } +.#{$fa-css-prefix}-trademark:before { content: fa-content($fa-var-trademark); } +.#{$fa-css-prefix}-train:before { content: fa-content($fa-var-train); } +.#{$fa-css-prefix}-transgender:before { content: fa-content($fa-var-transgender); } +.#{$fa-css-prefix}-transgender-alt:before { content: fa-content($fa-var-transgender-alt); } +.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash); } +.#{$fa-css-prefix}-trash-alt:before { content: fa-content($fa-var-trash-alt); } +.#{$fa-css-prefix}-tree:before { content: fa-content($fa-var-tree); } +.#{$fa-css-prefix}-trello:before { content: fa-content($fa-var-trello); } +.#{$fa-css-prefix}-tripadvisor:before { content: fa-content($fa-var-tripadvisor); } +.#{$fa-css-prefix}-trophy:before { content: fa-content($fa-var-trophy); } +.#{$fa-css-prefix}-truck:before { content: fa-content($fa-var-truck); } +.#{$fa-css-prefix}-tty:before { content: fa-content($fa-var-tty); } +.#{$fa-css-prefix}-tumblr:before { content: fa-content($fa-var-tumblr); } +.#{$fa-css-prefix}-tumblr-square:before { content: fa-content($fa-var-tumblr-square); } +.#{$fa-css-prefix}-tv:before { content: fa-content($fa-var-tv); } +.#{$fa-css-prefix}-twitch:before { content: fa-content($fa-var-twitch); } +.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); } +.#{$fa-css-prefix}-twitter-square:before { content: fa-content($fa-var-twitter-square); } +.#{$fa-css-prefix}-typo3:before { content: fa-content($fa-var-typo3); } +.#{$fa-css-prefix}-uber:before { content: fa-content($fa-var-uber); } +.#{$fa-css-prefix}-uikit:before { content: fa-content($fa-var-uikit); } +.#{$fa-css-prefix}-umbrella:before { content: fa-content($fa-var-umbrella); } +.#{$fa-css-prefix}-underline:before { content: fa-content($fa-var-underline); } +.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); } +.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); } +.#{$fa-css-prefix}-uniregistry:before { content: fa-content($fa-var-uniregistry); } +.#{$fa-css-prefix}-universal-access:before { content: fa-content($fa-var-universal-access); } +.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); } +.#{$fa-css-prefix}-unlink:before { content: fa-content($fa-var-unlink); } +.#{$fa-css-prefix}-unlock:before { content: fa-content($fa-var-unlock); } +.#{$fa-css-prefix}-unlock-alt:before { content: fa-content($fa-var-unlock-alt); } +.#{$fa-css-prefix}-untappd:before { content: fa-content($fa-var-untappd); } +.#{$fa-css-prefix}-upload:before { content: fa-content($fa-var-upload); } +.#{$fa-css-prefix}-usb:before { content: fa-content($fa-var-usb); } +.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); } +.#{$fa-css-prefix}-user-circle:before { content: fa-content($fa-var-user-circle); } +.#{$fa-css-prefix}-user-md:before { content: fa-content($fa-var-user-md); } +.#{$fa-css-prefix}-user-plus:before { content: fa-content($fa-var-user-plus); } +.#{$fa-css-prefix}-user-secret:before { content: fa-content($fa-var-user-secret); } +.#{$fa-css-prefix}-user-times:before { content: fa-content($fa-var-user-times); } +.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); } +.#{$fa-css-prefix}-ussunnah:before { content: fa-content($fa-var-ussunnah); } +.#{$fa-css-prefix}-utensil-spoon:before { content: fa-content($fa-var-utensil-spoon); } +.#{$fa-css-prefix}-utensils:before { content: fa-content($fa-var-utensils); } +.#{$fa-css-prefix}-vaadin:before { content: fa-content($fa-var-vaadin); } +.#{$fa-css-prefix}-venus:before { content: fa-content($fa-var-venus); } +.#{$fa-css-prefix}-venus-double:before { content: fa-content($fa-var-venus-double); } +.#{$fa-css-prefix}-venus-mars:before { content: fa-content($fa-var-venus-mars); } +.#{$fa-css-prefix}-viacoin:before { content: fa-content($fa-var-viacoin); } +.#{$fa-css-prefix}-viadeo:before { content: fa-content($fa-var-viadeo); } +.#{$fa-css-prefix}-viadeo-square:before { content: fa-content($fa-var-viadeo-square); } +.#{$fa-css-prefix}-viber:before { content: fa-content($fa-var-viber); } +.#{$fa-css-prefix}-video:before { content: fa-content($fa-var-video); } +.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo); } +.#{$fa-css-prefix}-vimeo-square:before { content: fa-content($fa-var-vimeo-square); } +.#{$fa-css-prefix}-vimeo-v:before { content: fa-content($fa-var-vimeo-v); } +.#{$fa-css-prefix}-vine:before { content: fa-content($fa-var-vine); } +.#{$fa-css-prefix}-vk:before { content: fa-content($fa-var-vk); } +.#{$fa-css-prefix}-vnv:before { content: fa-content($fa-var-vnv); } +.#{$fa-css-prefix}-volume-down:before { content: fa-content($fa-var-volume-down); } +.#{$fa-css-prefix}-volume-off:before { content: fa-content($fa-var-volume-off); } +.#{$fa-css-prefix}-volume-up:before { content: fa-content($fa-var-volume-up); } +.#{$fa-css-prefix}-vuejs:before { content: fa-content($fa-var-vuejs); } +.#{$fa-css-prefix}-weibo:before { content: fa-content($fa-var-weibo); } +.#{$fa-css-prefix}-weixin:before { content: fa-content($fa-var-weixin); } +.#{$fa-css-prefix}-whatsapp:before { content: fa-content($fa-var-whatsapp); } +.#{$fa-css-prefix}-whatsapp-square:before { content: fa-content($fa-var-whatsapp-square); } +.#{$fa-css-prefix}-wheelchair:before { content: fa-content($fa-var-wheelchair); } +.#{$fa-css-prefix}-whmcs:before { content: fa-content($fa-var-whmcs); } +.#{$fa-css-prefix}-wifi:before { content: fa-content($fa-var-wifi); } +.#{$fa-css-prefix}-wikipedia-w:before { content: fa-content($fa-var-wikipedia-w); } +.#{$fa-css-prefix}-window-close:before { content: fa-content($fa-var-window-close); } +.#{$fa-css-prefix}-window-maximize:before { content: fa-content($fa-var-window-maximize); } +.#{$fa-css-prefix}-window-minimize:before { content: fa-content($fa-var-window-minimize); } +.#{$fa-css-prefix}-window-restore:before { content: fa-content($fa-var-window-restore); } +.#{$fa-css-prefix}-windows:before { content: fa-content($fa-var-windows); } +.#{$fa-css-prefix}-won-sign:before { content: fa-content($fa-var-won-sign); } +.#{$fa-css-prefix}-wordpress:before { content: fa-content($fa-var-wordpress); } +.#{$fa-css-prefix}-wordpress-simple:before { content: fa-content($fa-var-wordpress-simple); } +.#{$fa-css-prefix}-wpbeginner:before { content: fa-content($fa-var-wpbeginner); } +.#{$fa-css-prefix}-wpexplorer:before { content: fa-content($fa-var-wpexplorer); } +.#{$fa-css-prefix}-wpforms:before { content: fa-content($fa-var-wpforms); } +.#{$fa-css-prefix}-wrench:before { content: fa-content($fa-var-wrench); } +.#{$fa-css-prefix}-xbox:before { content: fa-content($fa-var-xbox); } +.#{$fa-css-prefix}-xing:before { content: fa-content($fa-var-xing); } +.#{$fa-css-prefix}-xing-square:before { content: fa-content($fa-var-xing-square); } +.#{$fa-css-prefix}-y-combinator:before { content: fa-content($fa-var-y-combinator); } +.#{$fa-css-prefix}-yahoo:before { content: fa-content($fa-var-yahoo); } +.#{$fa-css-prefix}-yandex:before { content: fa-content($fa-var-yandex); } +.#{$fa-css-prefix}-yandex-international:before { content: fa-content($fa-var-yandex-international); } +.#{$fa-css-prefix}-yelp:before { content: fa-content($fa-var-yelp); } +.#{$fa-css-prefix}-yen-sign:before { content: fa-content($fa-var-yen-sign); } +.#{$fa-css-prefix}-yoast:before { content: fa-content($fa-var-yoast); } +.#{$fa-css-prefix}-youtube:before { content: fa-content($fa-var-youtube); } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_larger.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_larger.scss new file mode 100644 index 000000000..27c2ad5fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_larger.scss @@ -0,0 +1,23 @@ +// Icon Sizes +// ------------------------- + +// makes the font 33% larger relative to the icon container +.#{$fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -.0667em; +} + +.#{$fa-css-prefix}-xs { + font-size: .75em; +} + +.#{$fa-css-prefix}-sm { + font-size: .875em; +} + +@for $i from 1 through 10 { + .#{$fa-css-prefix}-#{$i}x { + font-size: $i * 1em; + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_list.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_list.scss new file mode 100644 index 000000000..8ebf33333 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_list.scss @@ -0,0 +1,18 @@ +// List Icons +// ------------------------- + +.#{$fa-css-prefix}-ul { + list-style-type: none; + margin-left: $fa-li-width * 5/4; + padding-left: 0; + + > li { position: relative; } +} + +.#{$fa-css-prefix}-li { + left: -$fa-li-width; + position: absolute; + text-align: center; + width: $fa-li-width; + line-height: inherit; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_mixins.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_mixins.scss new file mode 100644 index 000000000..06e549b69 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_mixins.scss @@ -0,0 +1,57 @@ +// Mixins +// -------------------------- + +@mixin fa-icon { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + vertical-align: -15%; +} + +@mixin fa-icon-rotate($degrees, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; + transform: rotate($degrees); +} + +@mixin fa-icon-flip($horiz, $vert, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; + transform: scale($horiz, $vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +@mixin sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +@mixin sr-only-focusable { + &:active, + &:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_rotated-flipped.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_rotated-flipped.scss new file mode 100644 index 000000000..995bc4cc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_rotated-flipped.scss @@ -0,0 +1,23 @@ +// Rotated & Flipped Icons +// ------------------------- + +.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } +.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } +.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } + +.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } +.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } +.#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root { + .#{$fa-css-prefix}-rotate-90, + .#{$fa-css-prefix}-rotate-180, + .#{$fa-css-prefix}-rotate-270, + .#{$fa-css-prefix}-flip-horizontal, + .#{$fa-css-prefix}-flip-vertical { + filter: none; + } +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_screen-reader.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_screen-reader.scss new file mode 100644 index 000000000..5d0ab262f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_screen-reader.scss @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { @include sr-only; } +.sr-only-focusable { @include sr-only-focusable; } diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_stacked.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_stacked.scss new file mode 100644 index 000000000..6c09d84cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_stacked.scss @@ -0,0 +1,31 @@ +// Stacked Icons +// ------------------------- + +.#{$fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; +} + +.#{$fa-css-prefix}-stack-1x, +.#{$fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; +} + +.#{$fa-css-prefix}-stack-1x { + line-height: inherit; +} + +.#{$fa-css-prefix}-stack-2x { + font-size: 2em; +} + +.#{$fa-css-prefix}-inverse { + color: $fa-inverse; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_variables.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_variables.scss new file mode 100644 index 000000000..99d2437d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/_variables.scss @@ -0,0 +1,800 @@ +// Variables +// -------------------------- + +$fa-font-path: "../webfonts" !default; +$fa-font-size-base: 16px !default; +$fa-css-prefix: fa !default; +$fa-version: "5.0.0" !default; +$fa-border-color: #eee !default; +$fa-inverse: #fff !default; +$fa-li-width: 2em !default; + +// Convenience function used to set content property +@function fa-content($fa-var) { + @return unquote("\"#{ $fa-var }\""); +} + +$fa-var-500px: \f26e; +$fa-var-accessible-icon: \f368; +$fa-var-accusoft: \f369; +$fa-var-address-book: \f2b9; +$fa-var-address-card: \f2bb; +$fa-var-adjust: \f042; +$fa-var-adn: \f170; +$fa-var-adversal: \f36a; +$fa-var-affiliatetheme: \f36b; +$fa-var-algolia: \f36c; +$fa-var-align-center: \f037; +$fa-var-align-justify: \f039; +$fa-var-align-left: \f036; +$fa-var-align-right: \f038; +$fa-var-amazon: \f270; +$fa-var-ambulance: \f0f9; +$fa-var-american-sign-language-interpreting: \f2a3; +$fa-var-amilia: \f36d; +$fa-var-anchor: \f13d; +$fa-var-android: \f17b; +$fa-var-angellist: \f209; +$fa-var-angle-double-down: \f103; +$fa-var-angle-double-left: \f100; +$fa-var-angle-double-right: \f101; +$fa-var-angle-double-up: \f102; +$fa-var-angle-down: \f107; +$fa-var-angle-left: \f104; +$fa-var-angle-right: \f105; +$fa-var-angle-up: \f106; +$fa-var-angrycreative: \f36e; +$fa-var-angular: \f420; +$fa-var-app-store: \f36f; +$fa-var-app-store-ios: \f370; +$fa-var-apper: \f371; +$fa-var-apple: \f179; +$fa-var-apple-pay: \f415; +$fa-var-archive: \f187; +$fa-var-arrow-alt-circle-down: \f358; +$fa-var-arrow-alt-circle-left: \f359; +$fa-var-arrow-alt-circle-right: \f35a; +$fa-var-arrow-alt-circle-up: \f35b; +$fa-var-arrow-circle-down: \f0ab; +$fa-var-arrow-circle-left: \f0a8; +$fa-var-arrow-circle-right: \f0a9; +$fa-var-arrow-circle-up: \f0aa; +$fa-var-arrow-down: \f063; +$fa-var-arrow-left: \f060; +$fa-var-arrow-right: \f061; +$fa-var-arrow-up: \f062; +$fa-var-arrows-alt: \f0b2; +$fa-var-arrows-alt-h: \f337; +$fa-var-arrows-alt-v: \f338; +$fa-var-assistive-listening-systems: \f2a2; +$fa-var-asterisk: \f069; +$fa-var-asymmetrik: \f372; +$fa-var-at: \f1fa; +$fa-var-audible: \f373; +$fa-var-audio-description: \f29e; +$fa-var-autoprefixer: \f41c; +$fa-var-avianex: \f374; +$fa-var-aviato: \f421; +$fa-var-aws: \f375; +$fa-var-backward: \f04a; +$fa-var-balance-scale: \f24e; +$fa-var-ban: \f05e; +$fa-var-bandcamp: \f2d5; +$fa-var-barcode: \f02a; +$fa-var-bars: \f0c9; +$fa-var-bath: \f2cd; +$fa-var-battery-empty: \f244; +$fa-var-battery-full: \f240; +$fa-var-battery-half: \f242; +$fa-var-battery-quarter: \f243; +$fa-var-battery-three-quarters: \f241; +$fa-var-bed: \f236; +$fa-var-beer: \f0fc; +$fa-var-behance: \f1b4; +$fa-var-behance-square: \f1b5; +$fa-var-bell: \f0f3; +$fa-var-bell-slash: \f1f6; +$fa-var-bicycle: \f206; +$fa-var-bimobject: \f378; +$fa-var-binoculars: \f1e5; +$fa-var-birthday-cake: \f1fd; +$fa-var-bitbucket: \f171; +$fa-var-bitcoin: \f379; +$fa-var-bity: \f37a; +$fa-var-black-tie: \f27e; +$fa-var-blackberry: \f37b; +$fa-var-blind: \f29d; +$fa-var-blogger: \f37c; +$fa-var-blogger-b: \f37d; +$fa-var-bluetooth: \f293; +$fa-var-bluetooth-b: \f294; +$fa-var-bold: \f032; +$fa-var-bolt: \f0e7; +$fa-var-bomb: \f1e2; +$fa-var-book: \f02d; +$fa-var-bookmark: \f02e; +$fa-var-braille: \f2a1; +$fa-var-briefcase: \f0b1; +$fa-var-btc: \f15a; +$fa-var-bug: \f188; +$fa-var-building: \f1ad; +$fa-var-bullhorn: \f0a1; +$fa-var-bullseye: \f140; +$fa-var-buromobelexperte: \f37f; +$fa-var-bus: \f207; +$fa-var-buysellads: \f20d; +$fa-var-calculator: \f1ec; +$fa-var-calendar: \f133; +$fa-var-calendar-alt: \f073; +$fa-var-calendar-check: \f274; +$fa-var-calendar-minus: \f272; +$fa-var-calendar-plus: \f271; +$fa-var-calendar-times: \f273; +$fa-var-camera: \f030; +$fa-var-camera-retro: \f083; +$fa-var-car: \f1b9; +$fa-var-caret-down: \f0d7; +$fa-var-caret-left: \f0d9; +$fa-var-caret-right: \f0da; +$fa-var-caret-square-down: \f150; +$fa-var-caret-square-left: \f191; +$fa-var-caret-square-right: \f152; +$fa-var-caret-square-up: \f151; +$fa-var-caret-up: \f0d8; +$fa-var-cart-arrow-down: \f218; +$fa-var-cart-plus: \f217; +$fa-var-cc-amex: \f1f3; +$fa-var-cc-apple-pay: \f416; +$fa-var-cc-diners-club: \f24c; +$fa-var-cc-discover: \f1f2; +$fa-var-cc-jcb: \f24b; +$fa-var-cc-mastercard: \f1f1; +$fa-var-cc-paypal: \f1f4; +$fa-var-cc-stripe: \f1f5; +$fa-var-cc-visa: \f1f0; +$fa-var-centercode: \f380; +$fa-var-certificate: \f0a3; +$fa-var-chart-area: \f1fe; +$fa-var-chart-bar: \f080; +$fa-var-chart-line: \f201; +$fa-var-chart-pie: \f200; +$fa-var-check: \f00c; +$fa-var-check-circle: \f058; +$fa-var-check-square: \f14a; +$fa-var-chevron-circle-down: \f13a; +$fa-var-chevron-circle-left: \f137; +$fa-var-chevron-circle-right: \f138; +$fa-var-chevron-circle-up: \f139; +$fa-var-chevron-down: \f078; +$fa-var-chevron-left: \f053; +$fa-var-chevron-right: \f054; +$fa-var-chevron-up: \f077; +$fa-var-child: \f1ae; +$fa-var-chrome: \f268; +$fa-var-circle: \f111; +$fa-var-circle-notch: \f1ce; +$fa-var-clipboard: \f328; +$fa-var-clock: \f017; +$fa-var-clone: \f24d; +$fa-var-closed-captioning: \f20a; +$fa-var-cloud: \f0c2; +$fa-var-cloud-download-alt: \f381; +$fa-var-cloud-upload-alt: \f382; +$fa-var-cloudscale: \f383; +$fa-var-cloudsmith: \f384; +$fa-var-cloudversify: \f385; +$fa-var-code: \f121; +$fa-var-code-branch: \f126; +$fa-var-codepen: \f1cb; +$fa-var-codiepie: \f284; +$fa-var-coffee: \f0f4; +$fa-var-cog: \f013; +$fa-var-cogs: \f085; +$fa-var-columns: \f0db; +$fa-var-comment: \f075; +$fa-var-comment-alt: \f27a; +$fa-var-comments: \f086; +$fa-var-compass: \f14e; +$fa-var-compress: \f066; +$fa-var-connectdevelop: \f20e; +$fa-var-contao: \f26d; +$fa-var-copy: \f0c5; +$fa-var-copyright: \f1f9; +$fa-var-cpanel: \f388; +$fa-var-creative-commons: \f25e; +$fa-var-credit-card: \f09d; +$fa-var-crop: \f125; +$fa-var-crosshairs: \f05b; +$fa-var-css3: \f13c; +$fa-var-css3-alt: \f38b; +$fa-var-cube: \f1b2; +$fa-var-cubes: \f1b3; +$fa-var-cut: \f0c4; +$fa-var-cuttlefish: \f38c; +$fa-var-d-and-d: \f38d; +$fa-var-dashcube: \f210; +$fa-var-database: \f1c0; +$fa-var-deaf: \f2a4; +$fa-var-delicious: \f1a5; +$fa-var-deploydog: \f38e; +$fa-var-deskpro: \f38f; +$fa-var-desktop: \f108; +$fa-var-deviantart: \f1bd; +$fa-var-digg: \f1a6; +$fa-var-digital-ocean: \f391; +$fa-var-discord: \f392; +$fa-var-discourse: \f393; +$fa-var-dochub: \f394; +$fa-var-docker: \f395; +$fa-var-dollar-sign: \f155; +$fa-var-dot-circle: \f192; +$fa-var-download: \f019; +$fa-var-draft2digital: \f396; +$fa-var-dribbble: \f17d; +$fa-var-dribbble-square: \f397; +$fa-var-dropbox: \f16b; +$fa-var-drupal: \f1a9; +$fa-var-dyalog: \f399; +$fa-var-earlybirds: \f39a; +$fa-var-edge: \f282; +$fa-var-edit: \f044; +$fa-var-eject: \f052; +$fa-var-ellipsis-h: \f141; +$fa-var-ellipsis-v: \f142; +$fa-var-ember: \f423; +$fa-var-empire: \f1d1; +$fa-var-envelope: \f0e0; +$fa-var-envelope-open: \f2b6; +$fa-var-envelope-square: \f199; +$fa-var-envira: \f299; +$fa-var-eraser: \f12d; +$fa-var-erlang: \f39d; +$fa-var-etsy: \f2d7; +$fa-var-euro-sign: \f153; +$fa-var-exchange-alt: \f362; +$fa-var-exclamation: \f12a; +$fa-var-exclamation-circle: \f06a; +$fa-var-exclamation-triangle: \f071; +$fa-var-expand: \f065; +$fa-var-expand-arrows-alt: \f31e; +$fa-var-expeditedssl: \f23e; +$fa-var-external-link-alt: \f35d; +$fa-var-external-link-square-alt: \f360; +$fa-var-eye: \f06e; +$fa-var-eye-dropper: \f1fb; +$fa-var-eye-slash: \f070; +$fa-var-facebook: \f09a; +$fa-var-facebook-f: \f39e; +$fa-var-facebook-messenger: \f39f; +$fa-var-facebook-square: \f082; +$fa-var-fast-backward: \f049; +$fa-var-fast-forward: \f050; +$fa-var-fax: \f1ac; +$fa-var-female: \f182; +$fa-var-fighter-jet: \f0fb; +$fa-var-file: \f15b; +$fa-var-file-alt: \f15c; +$fa-var-file-archive: \f1c6; +$fa-var-file-audio: \f1c7; +$fa-var-file-code: \f1c9; +$fa-var-file-excel: \f1c3; +$fa-var-file-image: \f1c5; +$fa-var-file-pdf: \f1c1; +$fa-var-file-powerpoint: \f1c4; +$fa-var-file-video: \f1c8; +$fa-var-file-word: \f1c2; +$fa-var-film: \f008; +$fa-var-filter: \f0b0; +$fa-var-fire: \f06d; +$fa-var-fire-extinguisher: \f134; +$fa-var-firefox: \f269; +$fa-var-first-order: \f2b0; +$fa-var-firstdraft: \f3a1; +$fa-var-flag: \f024; +$fa-var-flag-checkered: \f11e; +$fa-var-flask: \f0c3; +$fa-var-flickr: \f16e; +$fa-var-fly: \f417; +$fa-var-folder: \f07b; +$fa-var-folder-open: \f07c; +$fa-var-font: \f031; +$fa-var-font-awesome: \f2b4; +$fa-var-font-awesome-alt: \f35c; +$fa-var-font-awesome-flag: \f425; +$fa-var-fonticons: \f280; +$fa-var-fonticons-fi: \f3a2; +$fa-var-fort-awesome: \f286; +$fa-var-fort-awesome-alt: \f3a3; +$fa-var-forumbee: \f211; +$fa-var-forward: \f04e; +$fa-var-foursquare: \f180; +$fa-var-free-code-camp: \f2c5; +$fa-var-freebsd: \f3a4; +$fa-var-frown: \f119; +$fa-var-futbol: \f1e3; +$fa-var-gamepad: \f11b; +$fa-var-gavel: \f0e3; +$fa-var-gem: \f3a5; +$fa-var-genderless: \f22d; +$fa-var-get-pocket: \f265; +$fa-var-gg: \f260; +$fa-var-gg-circle: \f261; +$fa-var-gift: \f06b; +$fa-var-git: \f1d3; +$fa-var-git-square: \f1d2; +$fa-var-github: \f09b; +$fa-var-github-alt: \f113; +$fa-var-github-square: \f092; +$fa-var-gitkraken: \f3a6; +$fa-var-gitlab: \f296; +$fa-var-gitter: \f426; +$fa-var-glass-martini: \f000; +$fa-var-glide: \f2a5; +$fa-var-glide-g: \f2a6; +$fa-var-globe: \f0ac; +$fa-var-gofore: \f3a7; +$fa-var-goodreads: \f3a8; +$fa-var-goodreads-g: \f3a9; +$fa-var-google: \f1a0; +$fa-var-google-drive: \f3aa; +$fa-var-google-play: \f3ab; +$fa-var-google-plus: \f2b3; +$fa-var-google-plus-g: \f0d5; +$fa-var-google-plus-square: \f0d4; +$fa-var-google-wallet: \f1ee; +$fa-var-graduation-cap: \f19d; +$fa-var-gratipay: \f184; +$fa-var-grav: \f2d6; +$fa-var-gripfire: \f3ac; +$fa-var-grunt: \f3ad; +$fa-var-gulp: \f3ae; +$fa-var-h-square: \f0fd; +$fa-var-hacker-news: \f1d4; +$fa-var-hacker-news-square: \f3af; +$fa-var-hand-lizard: \f258; +$fa-var-hand-paper: \f256; +$fa-var-hand-peace: \f25b; +$fa-var-hand-point-down: \f0a7; +$fa-var-hand-point-left: \f0a5; +$fa-var-hand-point-right: \f0a4; +$fa-var-hand-point-up: \f0a6; +$fa-var-hand-pointer: \f25a; +$fa-var-hand-rock: \f255; +$fa-var-hand-scissors: \f257; +$fa-var-hand-spock: \f259; +$fa-var-handshake: \f2b5; +$fa-var-hashtag: \f292; +$fa-var-hdd: \f0a0; +$fa-var-heading: \f1dc; +$fa-var-headphones: \f025; +$fa-var-heart: \f004; +$fa-var-heartbeat: \f21e; +$fa-var-hire-a-helper: \f3b0; +$fa-var-history: \f1da; +$fa-var-home: \f015; +$fa-var-hooli: \f427; +$fa-var-hospital: \f0f8; +$fa-var-hotjar: \f3b1; +$fa-var-hourglass: \f254; +$fa-var-hourglass-end: \f253; +$fa-var-hourglass-half: \f252; +$fa-var-hourglass-start: \f251; +$fa-var-houzz: \f27c; +$fa-var-html5: \f13b; +$fa-var-hubspot: \f3b2; +$fa-var-i-cursor: \f246; +$fa-var-id-badge: \f2c1; +$fa-var-id-card: \f2c2; +$fa-var-image: \f03e; +$fa-var-images: \f302; +$fa-var-imdb: \f2d8; +$fa-var-inbox: \f01c; +$fa-var-indent: \f03c; +$fa-var-industry: \f275; +$fa-var-info: \f129; +$fa-var-info-circle: \f05a; +$fa-var-instagram: \f16d; +$fa-var-internet-explorer: \f26b; +$fa-var-ioxhost: \f208; +$fa-var-italic: \f033; +$fa-var-itunes: \f3b4; +$fa-var-itunes-note: \f3b5; +$fa-var-jenkins: \f3b6; +$fa-var-joget: \f3b7; +$fa-var-joomla: \f1aa; +$fa-var-js: \f3b8; +$fa-var-js-square: \f3b9; +$fa-var-jsfiddle: \f1cc; +$fa-var-key: \f084; +$fa-var-keyboard: \f11c; +$fa-var-keycdn: \f3ba; +$fa-var-kickstarter: \f3bb; +$fa-var-kickstarter-k: \f3bc; +$fa-var-language: \f1ab; +$fa-var-laptop: \f109; +$fa-var-laravel: \f3bd; +$fa-var-lastfm: \f202; +$fa-var-lastfm-square: \f203; +$fa-var-leaf: \f06c; +$fa-var-leanpub: \f212; +$fa-var-lemon: \f094; +$fa-var-less: \f41d; +$fa-var-level-down-alt: \f3be; +$fa-var-level-up-alt: \f3bf; +$fa-var-life-ring: \f1cd; +$fa-var-lightbulb: \f0eb; +$fa-var-line: \f3c0; +$fa-var-link: \f0c1; +$fa-var-linkedin: \f08c; +$fa-var-linkedin-in: \f0e1; +$fa-var-linode: \f2b8; +$fa-var-linux: \f17c; +$fa-var-lira-sign: \f195; +$fa-var-list: \f03a; +$fa-var-list-alt: \f022; +$fa-var-list-ol: \f0cb; +$fa-var-list-ul: \f0ca; +$fa-var-location-arrow: \f124; +$fa-var-lock: \f023; +$fa-var-lock-open: \f3c1; +$fa-var-long-arrow-alt-down: \f309; +$fa-var-long-arrow-alt-left: \f30a; +$fa-var-long-arrow-alt-right: \f30b; +$fa-var-long-arrow-alt-up: \f30c; +$fa-var-low-vision: \f2a8; +$fa-var-lyft: \f3c3; +$fa-var-magento: \f3c4; +$fa-var-magic: \f0d0; +$fa-var-magnet: \f076; +$fa-var-male: \f183; +$fa-var-map: \f279; +$fa-var-map-marker: \f041; +$fa-var-map-marker-alt: \f3c5; +$fa-var-map-pin: \f276; +$fa-var-map-signs: \f277; +$fa-var-mars: \f222; +$fa-var-mars-double: \f227; +$fa-var-mars-stroke: \f229; +$fa-var-mars-stroke-h: \f22b; +$fa-var-mars-stroke-v: \f22a; +$fa-var-maxcdn: \f136; +$fa-var-medapps: \f3c6; +$fa-var-medium: \f23a; +$fa-var-medium-m: \f3c7; +$fa-var-medkit: \f0fa; +$fa-var-medrt: \f3c8; +$fa-var-meetup: \f2e0; +$fa-var-meh: \f11a; +$fa-var-mercury: \f223; +$fa-var-microchip: \f2db; +$fa-var-microphone: \f130; +$fa-var-microphone-slash: \f131; +$fa-var-microsoft: \f3ca; +$fa-var-minus: \f068; +$fa-var-minus-circle: \f056; +$fa-var-minus-square: \f146; +$fa-var-mix: \f3cb; +$fa-var-mixcloud: \f289; +$fa-var-mizuni: \f3cc; +$fa-var-mobile: \f10b; +$fa-var-mobile-alt: \f3cd; +$fa-var-modx: \f285; +$fa-var-monero: \f3d0; +$fa-var-money-bill-alt: \f3d1; +$fa-var-moon: \f186; +$fa-var-motorcycle: \f21c; +$fa-var-mouse-pointer: \f245; +$fa-var-music: \f001; +$fa-var-napster: \f3d2; +$fa-var-neuter: \f22c; +$fa-var-newspaper: \f1ea; +$fa-var-nintendo-switch: \f418; +$fa-var-node: \f419; +$fa-var-node-js: \f3d3; +$fa-var-npm: \f3d4; +$fa-var-ns8: \f3d5; +$fa-var-nutritionix: \f3d6; +$fa-var-object-group: \f247; +$fa-var-object-ungroup: \f248; +$fa-var-odnoklassniki: \f263; +$fa-var-odnoklassniki-square: \f264; +$fa-var-opencart: \f23d; +$fa-var-openid: \f19b; +$fa-var-opera: \f26a; +$fa-var-optin-monster: \f23c; +$fa-var-osi: \f41a; +$fa-var-outdent: \f03b; +$fa-var-page4: \f3d7; +$fa-var-pagelines: \f18c; +$fa-var-paint-brush: \f1fc; +$fa-var-palfed: \f3d8; +$fa-var-paper-plane: \f1d8; +$fa-var-paperclip: \f0c6; +$fa-var-paragraph: \f1dd; +$fa-var-paste: \f0ea; +$fa-var-patreon: \f3d9; +$fa-var-pause: \f04c; +$fa-var-pause-circle: \f28b; +$fa-var-paw: \f1b0; +$fa-var-paypal: \f1ed; +$fa-var-pen-square: \f14b; +$fa-var-pencil-alt: \f303; +$fa-var-percent: \f295; +$fa-var-periscope: \f3da; +$fa-var-phabricator: \f3db; +$fa-var-phoenix-framework: \f3dc; +$fa-var-phone: \f095; +$fa-var-phone-square: \f098; +$fa-var-phone-volume: \f2a0; +$fa-var-pied-piper: \f2ae; +$fa-var-pied-piper-alt: \f1a8; +$fa-var-pied-piper-pp: \f1a7; +$fa-var-pinterest: \f0d2; +$fa-var-pinterest-p: \f231; +$fa-var-pinterest-square: \f0d3; +$fa-var-plane: \f072; +$fa-var-play: \f04b; +$fa-var-play-circle: \f144; +$fa-var-playstation: \f3df; +$fa-var-plug: \f1e6; +$fa-var-plus: \f067; +$fa-var-plus-circle: \f055; +$fa-var-plus-square: \f0fe; +$fa-var-podcast: \f2ce; +$fa-var-pound-sign: \f154; +$fa-var-power-off: \f011; +$fa-var-print: \f02f; +$fa-var-product-hunt: \f288; +$fa-var-pushed: \f3e1; +$fa-var-puzzle-piece: \f12e; +$fa-var-python: \f3e2; +$fa-var-qq: \f1d6; +$fa-var-qrcode: \f029; +$fa-var-question: \f128; +$fa-var-question-circle: \f059; +$fa-var-quora: \f2c4; +$fa-var-quote-left: \f10d; +$fa-var-quote-right: \f10e; +$fa-var-random: \f074; +$fa-var-ravelry: \f2d9; +$fa-var-react: \f41b; +$fa-var-rebel: \f1d0; +$fa-var-recycle: \f1b8; +$fa-var-red-river: \f3e3; +$fa-var-reddit: \f1a1; +$fa-var-reddit-alien: \f281; +$fa-var-reddit-square: \f1a2; +$fa-var-redo: \f01e; +$fa-var-redo-alt: \f2f9; +$fa-var-registered: \f25d; +$fa-var-rendact: \f3e4; +$fa-var-renren: \f18b; +$fa-var-reply: \f3e5; +$fa-var-reply-all: \f122; +$fa-var-replyd: \f3e6; +$fa-var-resolving: \f3e7; +$fa-var-retweet: \f079; +$fa-var-road: \f018; +$fa-var-rocket: \f135; +$fa-var-rocketchat: \f3e8; +$fa-var-rockrms: \f3e9; +$fa-var-rss: \f09e; +$fa-var-rss-square: \f143; +$fa-var-ruble-sign: \f158; +$fa-var-rupee-sign: \f156; +$fa-var-safari: \f267; +$fa-var-sass: \f41e; +$fa-var-save: \f0c7; +$fa-var-schlix: \f3ea; +$fa-var-scribd: \f28a; +$fa-var-search: \f002; +$fa-var-search-minus: \f010; +$fa-var-search-plus: \f00e; +$fa-var-searchengin: \f3eb; +$fa-var-sellcast: \f2da; +$fa-var-sellsy: \f213; +$fa-var-server: \f233; +$fa-var-servicestack: \f3ec; +$fa-var-share: \f064; +$fa-var-share-alt: \f1e0; +$fa-var-share-alt-square: \f1e1; +$fa-var-share-square: \f14d; +$fa-var-shekel-sign: \f20b; +$fa-var-shield-alt: \f3ed; +$fa-var-ship: \f21a; +$fa-var-shirtsinbulk: \f214; +$fa-var-shopping-bag: \f290; +$fa-var-shopping-basket: \f291; +$fa-var-shopping-cart: \f07a; +$fa-var-shower: \f2cc; +$fa-var-sign-in-alt: \f2f6; +$fa-var-sign-language: \f2a7; +$fa-var-sign-out-alt: \f2f5; +$fa-var-signal: \f012; +$fa-var-simplybuilt: \f215; +$fa-var-sistrix: \f3ee; +$fa-var-sitemap: \f0e8; +$fa-var-skyatlas: \f216; +$fa-var-skype: \f17e; +$fa-var-slack: \f198; +$fa-var-slack-hash: \f3ef; +$fa-var-sliders-h: \f1de; +$fa-var-slideshare: \f1e7; +$fa-var-smile: \f118; +$fa-var-snapchat: \f2ab; +$fa-var-snapchat-ghost: \f2ac; +$fa-var-snapchat-square: \f2ad; +$fa-var-snowflake: \f2dc; +$fa-var-sort: \f0dc; +$fa-var-sort-alpha-down: \f15d; +$fa-var-sort-alpha-up: \f15e; +$fa-var-sort-amount-down: \f160; +$fa-var-sort-amount-up: \f161; +$fa-var-sort-down: \f0dd; +$fa-var-sort-numeric-down: \f162; +$fa-var-sort-numeric-up: \f163; +$fa-var-sort-up: \f0de; +$fa-var-soundcloud: \f1be; +$fa-var-space-shuttle: \f197; +$fa-var-speakap: \f3f3; +$fa-var-spinner: \f110; +$fa-var-spotify: \f1bc; +$fa-var-square: \f0c8; +$fa-var-stack-exchange: \f18d; +$fa-var-stack-overflow: \f16c; +$fa-var-star: \f005; +$fa-var-star-half: \f089; +$fa-var-staylinked: \f3f5; +$fa-var-steam: \f1b6; +$fa-var-steam-square: \f1b7; +$fa-var-steam-symbol: \f3f6; +$fa-var-step-backward: \f048; +$fa-var-step-forward: \f051; +$fa-var-stethoscope: \f0f1; +$fa-var-sticker-mule: \f3f7; +$fa-var-sticky-note: \f249; +$fa-var-stop: \f04d; +$fa-var-stop-circle: \f28d; +$fa-var-strava: \f428; +$fa-var-street-view: \f21d; +$fa-var-strikethrough: \f0cc; +$fa-var-stripe: \f429; +$fa-var-stripe-s: \f42a; +$fa-var-studiovinari: \f3f8; +$fa-var-stumbleupon: \f1a4; +$fa-var-stumbleupon-circle: \f1a3; +$fa-var-subscript: \f12c; +$fa-var-subway: \f239; +$fa-var-suitcase: \f0f2; +$fa-var-sun: \f185; +$fa-var-superpowers: \f2dd; +$fa-var-superscript: \f12b; +$fa-var-supple: \f3f9; +$fa-var-sync: \f021; +$fa-var-sync-alt: \f2f1; +$fa-var-table: \f0ce; +$fa-var-tablet: \f10a; +$fa-var-tablet-alt: \f3fa; +$fa-var-tachometer-alt: \f3fd; +$fa-var-tag: \f02b; +$fa-var-tags: \f02c; +$fa-var-tasks: \f0ae; +$fa-var-taxi: \f1ba; +$fa-var-telegram: \f2c6; +$fa-var-telegram-plane: \f3fe; +$fa-var-tencent-weibo: \f1d5; +$fa-var-terminal: \f120; +$fa-var-text-height: \f034; +$fa-var-text-width: \f035; +$fa-var-th: \f00a; +$fa-var-th-large: \f009; +$fa-var-th-list: \f00b; +$fa-var-themeisle: \f2b2; +$fa-var-thermometer-empty: \f2cb; +$fa-var-thermometer-full: \f2c7; +$fa-var-thermometer-half: \f2c9; +$fa-var-thermometer-quarter: \f2ca; +$fa-var-thermometer-three-quarters: \f2c8; +$fa-var-thumbs-down: \f165; +$fa-var-thumbs-up: \f164; +$fa-var-thumbtack: \f08d; +$fa-var-ticket-alt: \f3ff; +$fa-var-times: \f00d; +$fa-var-times-circle: \f057; +$fa-var-tint: \f043; +$fa-var-toggle-off: \f204; +$fa-var-toggle-on: \f205; +$fa-var-trademark: \f25c; +$fa-var-train: \f238; +$fa-var-transgender: \f224; +$fa-var-transgender-alt: \f225; +$fa-var-trash: \f1f8; +$fa-var-trash-alt: \f2ed; +$fa-var-tree: \f1bb; +$fa-var-trello: \f181; +$fa-var-tripadvisor: \f262; +$fa-var-trophy: \f091; +$fa-var-truck: \f0d1; +$fa-var-tty: \f1e4; +$fa-var-tumblr: \f173; +$fa-var-tumblr-square: \f174; +$fa-var-tv: \f26c; +$fa-var-twitch: \f1e8; +$fa-var-twitter: \f099; +$fa-var-twitter-square: \f081; +$fa-var-typo3: \f42b; +$fa-var-uber: \f402; +$fa-var-uikit: \f403; +$fa-var-umbrella: \f0e9; +$fa-var-underline: \f0cd; +$fa-var-undo: \f0e2; +$fa-var-undo-alt: \f2ea; +$fa-var-uniregistry: \f404; +$fa-var-universal-access: \f29a; +$fa-var-university: \f19c; +$fa-var-unlink: \f127; +$fa-var-unlock: \f09c; +$fa-var-unlock-alt: \f13e; +$fa-var-untappd: \f405; +$fa-var-upload: \f093; +$fa-var-usb: \f287; +$fa-var-user: \f007; +$fa-var-user-circle: \f2bd; +$fa-var-user-md: \f0f0; +$fa-var-user-plus: \f234; +$fa-var-user-secret: \f21b; +$fa-var-user-times: \f235; +$fa-var-users: \f0c0; +$fa-var-ussunnah: \f407; +$fa-var-utensil-spoon: \f2e5; +$fa-var-utensils: \f2e7; +$fa-var-vaadin: \f408; +$fa-var-venus: \f221; +$fa-var-venus-double: \f226; +$fa-var-venus-mars: \f228; +$fa-var-viacoin: \f237; +$fa-var-viadeo: \f2a9; +$fa-var-viadeo-square: \f2aa; +$fa-var-viber: \f409; +$fa-var-video: \f03d; +$fa-var-vimeo: \f40a; +$fa-var-vimeo-square: \f194; +$fa-var-vimeo-v: \f27d; +$fa-var-vine: \f1ca; +$fa-var-vk: \f189; +$fa-var-vnv: \f40b; +$fa-var-volume-down: \f027; +$fa-var-volume-off: \f026; +$fa-var-volume-up: \f028; +$fa-var-vuejs: \f41f; +$fa-var-weibo: \f18a; +$fa-var-weixin: \f1d7; +$fa-var-whatsapp: \f232; +$fa-var-whatsapp-square: \f40c; +$fa-var-wheelchair: \f193; +$fa-var-whmcs: \f40d; +$fa-var-wifi: \f1eb; +$fa-var-wikipedia-w: \f266; +$fa-var-window-close: \f410; +$fa-var-window-maximize: \f2d0; +$fa-var-window-minimize: \f2d1; +$fa-var-window-restore: \f2d2; +$fa-var-windows: \f17a; +$fa-var-won-sign: \f159; +$fa-var-wordpress: \f19a; +$fa-var-wordpress-simple: \f411; +$fa-var-wpbeginner: \f297; +$fa-var-wpexplorer: \f2de; +$fa-var-wpforms: \f298; +$fa-var-wrench: \f0ad; +$fa-var-xbox: \f412; +$fa-var-xing: \f168; +$fa-var-xing-square: \f169; +$fa-var-y-combinator: \f23b; +$fa-var-yahoo: \f19e; +$fa-var-yandex: \f413; +$fa-var-yandex-international: \f414; +$fa-var-yelp: \f1e9; +$fa-var-yen-sign: \f157; +$fa-var-yoast: \f2b1; +$fa-var-youtube: \f167; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-brands.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-brands.scss new file mode 100644 index 000000000..1b3ae5019 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-brands.scss @@ -0,0 +1,17 @@ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url('#{$fa-font-path}/fa-brands-400.eot'); + src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), + url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); +} + +.fab { + font-family: 'Font Awesome 5 Brands'; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-regular.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-regular.scss new file mode 100644 index 000000000..3123f39cb --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-regular.scss @@ -0,0 +1,18 @@ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url('#{$fa-font-path}/fa-regular-400.eot'); + src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), + url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); +} + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-solid.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-solid.scss new file mode 100644 index 000000000..d63b2dac1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fa-solid.scss @@ -0,0 +1,19 @@ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url('#{$fa-font-path}/fa-solid-900.eot'); + src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), + url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), + url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); +} + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; +} diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fontawesome.scss b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fontawesome.scss new file mode 100644 index 000000000..84d23d056 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/scss/fontawesome.scss @@ -0,0 +1,16 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; +@import 'mixins'; +@import 'core'; +@import 'larger'; +@import 'fixed-width'; +@import 'list'; +@import 'bordered-pulled'; +@import 'animated'; +@import 'rotated-flipped'; +@import 'stacked'; +@import 'icons'; +@import 'screen-reader'; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.eot b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.eot new file mode 100644 index 000000000..e7b3ba742 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.eot differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.svg b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.svg new file mode 100644 index 000000000..c12b7caff --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.svg @@ -0,0 +1,974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.ttf b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.ttf new file mode 100644 index 000000000..14179efb2 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.ttf differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff new file mode 100644 index 000000000..8f0b22bd1 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff2 b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff2 new file mode 100644 index 000000000..9b7fe7075 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-brands-400.woff2 differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.eot b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.eot new file mode 100644 index 000000000..17679617a Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.eot differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.svg b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.svg new file mode 100644 index 000000000..9da9bfdda --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.svg @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.ttf b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.ttf new file mode 100644 index 000000000..3c14dbeac Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.ttf differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff new file mode 100644 index 000000000..ec743c8ed Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff2 b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff2 new file mode 100644 index 000000000..e3369f3dc Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-regular-400.woff2 differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.eot b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.eot new file mode 100644 index 000000000..caa97edb9 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.eot differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.svg b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.svg new file mode 100644 index 000000000..ad63c0732 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.svg @@ -0,0 +1,1406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.ttf b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.ttf new file mode 100644 index 000000000..f2227c8be Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.ttf differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff new file mode 100644 index 000000000..133751237 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff2 b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff2 new file mode 100644 index 000000000..f025a0092 Binary files /dev/null and b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome-free-webfonts/webfonts/fa-solid-900.woff2 differ diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/LICENSE.txt b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/LICENSE.txt new file mode 100644 index 000000000..28c1c4bc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OLF license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.es.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.es.js new file mode 100644 index 000000000..bfeaf910c --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.es.js @@ -0,0 +1,1586 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +var noop = function noop() {}; + +var _WINDOW = {}; +var _DOCUMENT = {}; +var _PERFORMANCE = { mark: noop, measure: noop }; + +try { + if (typeof window !== 'undefined') _WINDOW = window; + if (typeof document !== 'undefined') _DOCUMENT = document; + if (typeof performance !== 'undefined') _PERFORMANCE = performance; +} catch (e) {} + +var _ref = _WINDOW.navigator || {}; +var _ref$userAgent = _ref.userAgent; +var userAgent = _ref$userAgent === undefined ? '' : _ref$userAgent; + +var WINDOW = _WINDOW; +var DOCUMENT = _DOCUMENT; + +var PERFORMANCE = _PERFORMANCE; + +var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/'); + +var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___'; +var UNITS_IN_GRID = 16; +var DEFAULT_FAMILY_PREFIX = 'fa'; +var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa'; +var DATA_FA_PROCESSED = 'data-fa-processed'; +var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element'; +var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg'; + +var PRODUCTION = function () { + try { + return process.env.NODE_ENV === 'production'; + } catch (e) { + return false; + } +}(); + +var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); + + + +var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter'].concat(oneToTen.map(function (n) { + return n + 'x'; +})).concat(oneToTwenty.map(function (n) { + return 'w-' + n; +})); + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +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 function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + +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]; + } + } + } + + return target; +}; + +var objectWithoutProperties = function (obj, keys) { + var target = {}; + + for (var i in obj) { + if (keys.indexOf(i) >= 0) continue; + if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; + target[i] = obj[i]; + } + + return target; +}; + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +var _default = _extends({ + familyPrefix: DEFAULT_FAMILY_PREFIX, + replacementClass: DEFAULT_REPLACEMENT_CLASS, + autoReplaceSvg: true, + autoAddCss: true, + autoA11y: true, + searchPseudoElements: false, + observeMutations: true, + keepOriginalSource: true, + measurePerformance: false, + showMissingIcons: true +}, WINDOW.FontAwesomeConfig || {}); + +if (!_default.autoReplaceSvg) _default.observeMutations = false; + +var config = _extends({}, _default); + +WINDOW.FontAwesomeConfig = config; + +function update(newConfig) { + var validKeys = Object.keys(config); + + Object.keys(newConfig).forEach(function (configKey) { + if (~validKeys.indexOf(configKey)) { + config[configKey] = newConfig[configKey]; + } + }); +} + +var w = WINDOW || {}; + +if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; +if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; +if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; +if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + +var namespace = w[NAMESPACE_IDENTIFIER]; + +var d = UNITS_IN_GRID; + +var meaninglessTransform = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: false, + flipY: false +}; + +function isReserved(name) { + return ~RESERVED_CLASSES.indexOf(name); +} + + + +function insertCss(css) { + if (!css) { + return; + } + + if (typeof DOCUMENT.createElement === 'undefined') { + return; + } + + var style = DOCUMENT.createElement('style'); + style.setAttribute('type', 'text/css'); + style.innerHTML = css; + + var headChildren = DOCUMENT.head.childNodes; + var beforeChild = null; + + for (var i = headChildren.length - 1; i > -1; i--) { + var child = headChildren[i]; + var tagName = (child.tagName || '').toUpperCase(); + if (['STYLE', 'LINK'].indexOf(tagName) > -1) { + beforeChild = child; + } + } + + DOCUMENT.head.insertBefore(style, beforeChild); + + return css; +} + +var _uniqueId = 0; + +function nextUniqueId() { + _uniqueId++; + + return _uniqueId; +} + +function toArray(obj) { + var array = []; + + for (var i = (obj || []).length >>> 0; i--;) { + array[i] = obj[i]; + } + + return array; +} + +function classArray(node) { + if (node.classList) { + return toArray(node.classList); + } else { + return (node.getAttribute('class') || '').split(' ').filter(function (i) { + return i; + }); + } +} + +function getIconName(familyPrefix, cls) { + var parts = cls.split('-'); + var prefix = parts[0]; + var iconName = parts.slice(1).join('-'); + + if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) { + return iconName; + } else { + return null; + } +} + +function htmlEscape(str) { + return ('' + str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); +} + +function joinAttributes(attributes) { + return Object.keys(attributes || {}).reduce(function (acc, attributeName) { + return acc + (attributeName + '="' + htmlEscape(attributes[attributeName]) + '" '); + }, '').trim(); +} + +function joinStyles(styles) { + return Object.keys(styles || {}).reduce(function (acc, styleName) { + return acc + (styleName + ': ' + styles[styleName] + ';'); + }, ''); +} + +function transformIsMeaningful(transform) { + return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; +} + +function transformForSvg(_ref) { + var transform = _ref.transform, + containerWidth = _ref.containerWidth, + iconWidth = _ref.iconWidth; + + var outer = { + transform: 'translate(' + containerWidth / 2 + ' 256)' + }; + var innerTranslate = 'translate(' + transform.x * 32 + ', ' + transform.y * 32 + ') '; + var innerScale = 'scale(' + transform.size / 16 * (transform.flipX ? -1 : 1) + ', ' + transform.size / 16 * (transform.flipY ? -1 : 1) + ') '; + var innerRotate = 'rotate(' + transform.rotate + ' 0 0)'; + var inner = { + transform: innerTranslate + ' ' + innerScale + ' ' + innerRotate + }; + var path = { + transform: 'translate(' + iconWidth / 2 * -1 + ' -256)' + }; + return { + outer: outer, + inner: inner, + path: path + }; +} + +function transformForCss(_ref2) { + var transform = _ref2.transform, + _ref2$width = _ref2.width, + width = _ref2$width === undefined ? UNITS_IN_GRID : _ref2$width, + _ref2$height = _ref2.height, + height = _ref2$height === undefined ? UNITS_IN_GRID : _ref2$height, + _ref2$startCentered = _ref2.startCentered, + startCentered = _ref2$startCentered === undefined ? false : _ref2$startCentered; + + var val = ''; + + if (startCentered && IS_IE) { + val += 'translate(' + (transform.x / d - width / 2) + 'em, ' + (transform.y / d - height / 2) + 'em) '; + } else if (startCentered) { + val += 'translate(calc(-50% + ' + transform.x / d + 'em), calc(-50% + ' + transform.y / d + 'em)) '; + } else { + val += 'translate(' + transform.x / d + 'em, ' + transform.y / d + 'em) '; + } + + val += 'scale(' + transform.size / d * (transform.flipX ? -1 : 1) + ', ' + transform.size / d * (transform.flipY ? -1 : 1) + ') '; + val += 'rotate(' + transform.rotate + 'deg) '; + + return val; +} + +var ALL_SPACE = { + x: 0, + y: 0, + width: '100%', + height: '100%' +}; + +var makeIconMasking = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + mask = _ref.mask, + transform = _ref.transform; + var mainWidth = main.width, + mainPath = main.icon; + var maskWidth = mask.width, + maskPath = mask.icon; + + + var trans = transformForSvg({ transform: transform, containerWidth: maskWidth, iconWidth: mainWidth }); + + var maskRect = { + tag: 'rect', + attributes: _extends({}, ALL_SPACE, { + fill: 'white' + }) + }; + var maskInnerGroup = { + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ tag: 'path', attributes: _extends({}, mainPath.attributes, trans.path, { fill: 'black' }) }] + }; + var maskOuterGroup = { + tag: 'g', + attributes: _extends({}, trans.outer), + children: [maskInnerGroup] + }; + var maskId = 'mask-' + nextUniqueId(); + var clipId = 'clip-' + nextUniqueId(); + var maskTag = { + tag: 'mask', + attributes: _extends({}, ALL_SPACE, { + id: maskId, + maskUnits: 'userSpaceOnUse', + maskContentUnits: 'userSpaceOnUse' + }), + children: [maskRect, maskOuterGroup] + }; + var defs = { + tag: 'defs', + children: [{ tag: 'clipPath', attributes: { id: clipId }, children: [maskPath] }, maskTag] + }; + + children.push(defs, { tag: 'rect', attributes: _extends({ fill: 'currentColor', 'clip-path': 'url(#' + clipId + ')', mask: 'url(#' + maskId + ')' }, ALL_SPACE) }); + + return { + children: children, + attributes: attributes + }; +}; + +var makeIconStandard = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + transform = _ref.transform, + styles = _ref.styles; + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + if (transformIsMeaningful(transform)) { + var trans = transformForSvg({ transform: transform, containerWidth: main.width, iconWidth: main.width }); + children.push({ + tag: 'g', + attributes: _extends({}, trans.outer), + children: [{ + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ + tag: main.icon.tag, + children: main.icon.children, + attributes: _extends({}, main.icon.attributes, trans.path) + }] + }] + }); + } else { + children.push(main.icon); + } + + return { + children: children, + attributes: attributes + }; +}; + +var asIcon = function (_ref) { + var children = _ref.children, + main = _ref.main, + mask = _ref.mask, + attributes = _ref.attributes, + styles = _ref.styles, + transform = _ref.transform; + + if (transformIsMeaningful(transform) && main.found && !mask.found) { + var width = main.width, + height = main.height; + + var offset = { + x: width / height / 2, + y: 0.5 + }; + attributes['style'] = joinStyles(_extends({}, styles, { + 'transform-origin': offset.x + transform.x / 16 + 'em ' + (offset.y + transform.y / 16) + 'em' + })); + } + + return [{ + tag: 'svg', + attributes: attributes, + children: children + }]; +}; + +var asSymbol = function (_ref) { + var prefix = _ref.prefix, + iconName = _ref.iconName, + children = _ref.children, + attributes = _ref.attributes, + symbol = _ref.symbol; + + var id = symbol === true ? prefix + '-' + config.familyPrefix + '-' + iconName : symbol; + + return [{ + tag: 'svg', + attributes: { + style: 'display: none;' + }, + children: [{ + tag: 'symbol', + attributes: _extends({}, attributes, { id: id }), + children: children + }] + }]; +}; + +function makeInlineSvgAbstract(params) { + var _babelHelpers$extends; + + var _params$icons = params.icons, + main = _params$icons.main, + mask = _params$icons.mask, + prefix = params.prefix, + iconName = params.iconName, + transform = params.transform, + symbol = params.symbol, + title = params.title, + extra = params.extra; + + var _ref = mask.found ? mask : main, + width = _ref.width, + height = _ref.height; + + var widthClass = 'fa-w-' + Math.ceil(width / height * 16); + var attrClass = [config.replacementClass, iconName ? config.familyPrefix + '-' + iconName : '', widthClass].concat(extra.classes).join(' '); + + var content = { + children: [], + attributes: _extends({}, extra.attributes, (_babelHelpers$extends = {}, defineProperty(_babelHelpers$extends, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends, 'data-prefix', prefix), defineProperty(_babelHelpers$extends, 'data-icon', iconName), defineProperty(_babelHelpers$extends, 'class', attrClass), defineProperty(_babelHelpers$extends, 'role', 'img'), defineProperty(_babelHelpers$extends, 'xmlns', 'http://www.w3.org/2000/svg'), defineProperty(_babelHelpers$extends, 'viewBox', '0 0 ' + width + ' ' + height), _babelHelpers$extends)) + }; + + if (title) content.children.push({ tag: 'title', attributes: { id: content.attributes['aria-labelledby'] || 'title-' + nextUniqueId() }, children: [title] }); + + var args = _extends({}, content, { + prefix: prefix, + iconName: iconName, + main: main, + mask: mask, + transform: transform, + symbol: symbol, + styles: extra.styles + }); + + var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), + children = _ref2.children, + attributes = _ref2.attributes; + + args.children = children; + args.attributes = attributes; + + if (symbol) { + return asSymbol(args); + } else { + return asIcon(args); + } +} + +function makeLayersTextAbstract(params) { + var _babelHelpers$extends2; + + var content = params.content, + width = params.width, + height = params.height, + transform = params.transform, + title = params.title, + extra = params.extra; + + + var attributes = _extends({}, extra.attributes, title ? { 'title': title } : {}, (_babelHelpers$extends2 = {}, defineProperty(_babelHelpers$extends2, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends2, 'class', extra.classes.join(' ')), _babelHelpers$extends2)); + + var styles = _extends({}, extra.styles); + + if (transformIsMeaningful(transform)) { + styles['transform'] = transformForCss({ transform: transform, startCentered: true, width: width, height: height }); + styles['-webkit-transform'] = styles['transform']; + } + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ tag: 'span', attributes: { class: 'sr-only' }, children: [title] }); + } + + return val; +} + +var noop$2 = function noop() {}; +var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { mark: noop$2, measure: noop$2 }; +var preamble = 'FA "5.0.1"'; + +var begin = function begin(name) { + p.mark(preamble + ' ' + name + ' begins'); + return function () { + return end(name); + }; +}; + +var end = function end(name) { + p.mark(preamble + ' ' + name + ' ends'); + p.measure(preamble + ' ' + name, preamble + ' ' + name + ' begins', preamble + ' ' + name + ' ends'); +}; + +var perf = { begin: begin, end: end }; + +'use strict'; + +/** + * Internal helper to bind a function known to have 4 arguments + * to a given context. + */ +var bindInternal4 = function bindInternal4 (func, thisContext) { + return function (a, b, c, d) { + return func.call(thisContext, a, b, c, d); + }; +}; + +'use strict'; + + + +/** + * # Reduce + * + * A fast object `.reduce()` implementation. + * + * @param {Object} subject The object to reduce over. + * @param {Function} fn The reducer function. + * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0]. + * @param {Object} thisContext The context for the reducer. + * @return {mixed} The final result. + */ +var reduce = function fastReduceObject (subject, fn, initialValue, thisContext) { + var keys = Object.keys(subject), + length = keys.length, + iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn, + i, key, result; + + if (initialValue === undefined) { + i = 1; + result = subject[keys[0]]; + } + else { + i = 0; + result = initialValue; + } + + for (; i < length; i++) { + key = keys[i]; + result = iterator(result, subject[key], key, subject); + } + + return result; +}; + +var styles$2 = namespace.styles; +var shims = namespace.shims; + + +var _byUnicode = {}; +var _byLigature = {}; +var _byOldName = {}; + +var build = function build() { + var lookup = function lookup(reducer) { + return reduce(styles$2, function (o, style, prefix) { + o[prefix] = reduce(style, reducer, {}); + return o; + }, {}); + }; + + _byUnicode = lookup(function (acc, icon, iconName) { + acc[icon[3]] = iconName; + + return acc; + }); + + _byLigature = lookup(function (acc, icon, iconName) { + var ligatures = icon[2]; + + acc[iconName] = iconName; + + ligatures.forEach(function (ligature) { + acc[ligature] = iconName; + }); + + return acc; + }); + + var hasRegular = 'far' in styles$2; + + _byOldName = reduce(shims, function (acc, shim) { + var oldName = shim[0]; + var prefix = shim[1]; + var iconName = shim[2]; + + if (prefix === 'far' && !hasRegular) { + prefix = 'fas'; + } + + acc[oldName] = { prefix: prefix, iconName: iconName }; + + return acc; + }, {}); +}; + +build(); + +function byUnicode(prefix, unicode) { + return _byUnicode[prefix][unicode]; +} + +function byLigature(prefix, ligature) { + return _byLigature[prefix][ligature]; +} + +function byOldName(name) { + return _byOldName[name] || { prefix: null, iconName: null }; +} + +var styles$1 = namespace.styles; + + +var emptyCanonicalIcon = function emptyCanonicalIcon() { + return { prefix: null, iconName: null, rest: [] }; +}; + +function getCanonicalIcon(values) { + return values.reduce(function (acc, cls) { + var iconName = getIconName(config.familyPrefix, cls); + + if (styles$1[cls]) { + acc.prefix = cls; + } else if (iconName) { + var shim = acc.prefix === 'fa' ? byOldName(iconName) : {}; + + acc.iconName = shim.iconName || iconName; + acc.prefix = shim.prefix || acc.prefix; + } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) { + acc.rest.push(cls); + } + + return acc; + }, emptyCanonicalIcon()); +} + +function iconFromMapping(mapping, prefix, iconName) { + if (mapping && mapping[prefix] && mapping[prefix][iconName]) { + return { + prefix: prefix, + iconName: iconName, + icon: mapping[prefix][iconName] + }; + } +} + +function toHtml(abstractNodes) { + var tag = abstractNodes.tag, + _abstractNodes$attrib = abstractNodes.attributes, + attributes = _abstractNodes$attrib === undefined ? {} : _abstractNodes$attrib, + _abstractNodes$childr = abstractNodes.children, + children = _abstractNodes$childr === undefined ? [] : _abstractNodes$childr; + + + if (typeof abstractNodes === 'string') { + return htmlEscape(abstractNodes); + } else { + return '<' + tag + ' ' + joinAttributes(attributes) + '>' + children.map(toHtml).join('') + ''; + } +} + +var noop$1 = function noop() {}; + +function getMutator() { + if (config.autoReplaceSvg === true) { + return mutators.replace; + } + + var mutator = mutators[config.autoReplaceSvg]; + + return mutator || mutators.replace; +} + +var mutators = { + replace: function replace(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + var newOuterHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + + if (node.parentNode && node.outerHTML) { + node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? '' : ''); + } else if (node.parentNode) { + var newNode = document.createElement('span'); + node.parentNode.replaceChild(newNode, node); + newNode.outerHTML = newOuterHTML; + } + }, + nest: function nest(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + + // If we already have a replaced node we do not want to continue nesting within it. + // Short-circuit to the standard replacement + if (~classArray(node).indexOf(config.replacementClass)) { + return mutators.replace(mutation); + } + + var forSvg = new RegExp(config.familyPrefix + '-.*'); + + delete abstract[0].attributes.style; + + var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) { + if (cls === config.replacementClass || cls.match(forSvg)) { + acc.toSvg.push(cls); + } else { + acc.toNode.push(cls); + } + + return acc; + }, { toNode: [], toSvg: [] }); + + abstract[0].attributes.class = splitClasses.toSvg.join(' '); + + var newInnerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.setAttribute('class', splitClasses.toNode.join(' ')); + node.setAttribute(DATA_FA_PROCESSED, ''); + node.innerHTML = newInnerHTML; + } +}; + +function perform(mutations, callback) { + var callbackFunction = typeof callback === 'function' ? callback : noop$1; + + if (mutations.length === 0) { + callbackFunction(); + } else { + var frame = WINDOW.requestAnimationFrame || function (op) { + return op(); + }; + + frame(function () { + var mutator = getMutator(); + var mark = perf.begin('mutate'); + + mutations.map(mutator); + + mark(); + + callbackFunction(); + }); + } +} + +function disableObservation(operation) { + operation(); + +} + +var styleParser = function (node) { + var style = node.getAttribute('style'); + + var val = []; + + if (style) { + val = style.split(';').reduce(function (acc, style) { + var styles = style.split(':'); + var prop = styles[0]; + var value = styles.slice(1); + + if (prop && value.length > 0) { + acc[prop] = value.join(':').trim(); + } + + return acc; + }, {}); + } + + return val; +}; + +function toHex(unicode) { + var result = ''; + + for (var i = 0; i < unicode.length; i++) { + var hex = unicode.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + + return result; +} + +var classParser = function (node) { + var existingPrefix = node.getAttribute('data-prefix'); + var existingIconName = node.getAttribute('data-icon'); + var innerText = node.innerText !== undefined ? node.innerText.trim() : ''; + + var val = getCanonicalIcon(classArray(node)); + + if (existingPrefix && existingIconName) { + val.prefix = existingPrefix; + val.iconName = existingIconName; + } + + if (val.prefix && innerText.length > 1) { + val.iconName = byLigature(val.prefix, node.innerText); + } else if (val.prefix && innerText.length === 1) { + val.iconName = byUnicode(val.prefix, toHex(node.innerText)); + } + + return val; +}; + +var parseTransformString = function parseTransformString(transformString) { + var transform = { + size: 16, + x: 0, + y: 0, + flipX: false, + flipY: false, + rotate: 0 + }; + + if (!transformString) { + return transform; + } else { + return transformString.toLowerCase().split(' ').reduce(function (acc, n) { + var parts = n.toLowerCase().split('-'); + var first = parts[0]; + var rest = parts.slice(1).join('-'); + + if (first && rest === 'h') { + acc.flipX = true; + return acc; + } + + if (first && rest === 'v') { + acc.flipY = true; + return acc; + } + + rest = parseFloat(rest); + + if (isNaN(rest)) { + return acc; + } + + switch (first) { + case 'grow': + acc.size = acc.size + rest; + break; + case 'shrink': + acc.size = acc.size - rest; + break; + case 'left': + acc.x = acc.x - rest; + break; + case 'right': + acc.x = acc.x + rest; + break; + case 'up': + acc.y = acc.y - rest; + break; + case 'down': + acc.y = acc.y + rest; + break; + case 'rotate': + acc.rotate = acc.rotate + rest; + break; + } + + return acc; + }, transform); + } +}; + +var transformParser = function (node) { + return parseTransformString(node.getAttribute('data-fa-transform')); +}; + +var symbolParser = function (node) { + var symbol = node.getAttribute('data-fa-symbol'); + + return symbol === null ? false : symbol === '' ? true : symbol; +}; + +var attributesParser = function (node) { + var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) { + if (acc.name !== 'class' && acc.name !== 'style') { + acc[attr.name] = attr.value; + } + return acc; + }, {}); + + var title = node.getAttribute('title'); + + if (config.autoA11y) { + if (title) { + extraAttributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + extraAttributes['aria-hidden'] = 'true'; + } + } + + return extraAttributes; +}; + +var maskParser = function (node) { + var mask = node.getAttribute('data-fa-mask'); + + if (!mask) { + return emptyCanonicalIcon(); + } else { + return getCanonicalIcon(mask.split(' ').map(function (i) { + return i.trim(); + })); + } +}; + +function parseMeta(node) { + var _classParser = classParser(node), + iconName = _classParser.iconName, + prefix = _classParser.prefix, + extraClasses = _classParser.rest; + + var extraStyles = styleParser(node); + var transform = transformParser(node); + var symbol = symbolParser(node); + var extraAttributes = attributesParser(node); + var mask = maskParser(node); + + return { + iconName: iconName, + title: node.getAttribute('title'), + prefix: prefix, + transform: transform, + symbol: symbol, + mask: mask, + extra: { + classes: extraClasses, + styles: extraStyles, + attributes: extraAttributes + } + }; +} + +function MissingIcon(error) { + this.name = 'MissingIcon'; + this.message = error || 'Icon unavailable'; + this.stack = new Error().stack; +} + +MissingIcon.prototype = Object.create(Error.prototype); +MissingIcon.prototype.constructor = MissingIcon; + +var FILL = { fill: 'currentColor' }; +var ANIMATION_BASE = { + attributeType: 'XML', + repeatCount: 'indefinite', + dur: '2s' +}; +var RING = { + tag: 'path', + attributes: _extends({}, FILL, { + d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z' + }) +}; +var OPACITY_ANIMATE = _extends({}, ANIMATION_BASE, { + attributeName: 'opacity' +}); +var DOT = { + tag: 'circle', + attributes: _extends({}, FILL, { + cx: '256', + cy: '364', + r: '28' + }), + children: [{ tag: 'animate', attributes: _extends({}, ANIMATION_BASE, { attributeName: 'r', values: '28;14;28;28;14;28;' }) }, { tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;1;1;0;1;' }) }] +}; +var QUESTION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '1', + d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;0;0;0;1;' }) }] +}; +var EXCLAMATION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '0', + d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '0;0;1;1;0;0;' }) }] +}; + +var missing = { tag: 'g', children: [RING, DOT, QUESTION, EXCLAMATION] }; + +var styles = namespace.styles; + +var LAYERS_TEXT_CLASSNAME = 'fa-layers-text'; +var FONT_FAMILY_PATTERN = /Font Awesome 5 (Solid|Regular|Light|Brands)/; +var STYLE_TO_PREFIX = { + 'Solid': 'fas', + 'Regular': 'far', + 'Light': 'fal', + 'Brands': 'fab' +}; + +function findIcon(iconName, prefix) { + var val = { + found: false, + width: 512, + height: 512, + icon: missing + }; + + if (iconName && prefix && styles[prefix] && styles[prefix][iconName]) { + var icon = styles[prefix][iconName]; + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + val = { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; + } else if (iconName && prefix && !config.showMissingIcons) { + throw new MissingIcon('Icon is missing for prefix ' + prefix + ' with icon name ' + iconName); + } + + return val; +} + +function generateSvgReplacementMutation(node, nodeMeta) { + var iconName = nodeMeta.iconName, + title = nodeMeta.title, + prefix = nodeMeta.prefix, + transform = nodeMeta.transform, + symbol = nodeMeta.symbol, + mask = nodeMeta.mask, + extra = nodeMeta.extra; + + + return [node, makeInlineSvgAbstract({ + icons: { + main: findIcon(iconName, prefix), + mask: findIcon(mask.iconName, mask.prefix) + }, + prefix: prefix, + iconName: iconName, + transform: transform, + symbol: symbol, + mask: mask, + title: title, + extra: extra + })]; +} + +function generateLayersText(node, nodeMeta) { + var title = nodeMeta.title, + transform = nodeMeta.transform, + extra = nodeMeta.extra; + + + var width = null; + var height = null; + + if (IS_IE) { + var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10); + var boundingClientRect = node.getBoundingClientRect(); + width = boundingClientRect.width / computedFontSize; + height = boundingClientRect.height / computedFontSize; + } + + if (config.autoA11y && !title) { + extra.attributes['aria-hidden'] = 'true'; + } + + return [node, makeLayersTextAbstract({ + content: node.innerHTML, + width: width, + height: height, + transform: transform, + title: title, + extra: extra + })]; +} + +function generateMutation(node) { + var nodeMeta = parseMeta(node); + + if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) { + return generateLayersText(node, nodeMeta); + } else { + return generateSvgReplacementMutation(node, nodeMeta); + } +} + +function searchPseudoElements(root) { + var end = perf.begin('searchPseudoElements'); + + disableObservation(function () { + toArray(root.querySelectorAll('*')).forEach(function (node) { + [':before', ':after'].forEach(function (pos) { + var styles = WINDOW.getComputedStyle(node, pos); + var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN); + var children = toArray(node.children); + var pseudoElement = children.filter(function (c) { + return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === pos; + })[0]; + + if (!fontFamily && pseudoElement) { + pseudoElement.remove(); + } + + if (fontFamily && !pseudoElement) { + var content = styles.getPropertyValue('content'); + var i = DOCUMENT.createElement('i'); + i.setAttribute('class', '' + STYLE_TO_PREFIX[fontFamily[1]]); + i.setAttribute(DATA_FA_PSEUDO_ELEMENT, pos); + i.innerText = content.length === 3 ? content.substr(1, 1) : content; + if (pos === ':before') { + node.insertBefore(i, node.firstChild); + } else { + node.appendChild(i); + } + } + }); + }); + }); + + end(); +} + +function onTree(root) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var htmlClassList = DOCUMENT.documentElement.classList; + var hclAdd = function hclAdd(suffix) { + return htmlClassList.add(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var hclRemove = function hclRemove(suffix) { + return htmlClassList.remove(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var prefixes = Object.keys(styles); + var prefixesDomQuery = ['.' + LAYERS_TEXT_CLASSNAME + ':not([' + DATA_FA_PROCESSED + '])'].concat(prefixes.map(function (p) { + return '.' + p + ':not([' + DATA_FA_PROCESSED + '])'; + })).join(', '); + + if (prefixesDomQuery.length === 0) { + return; + } + + var candidates = toArray(root.querySelectorAll(prefixesDomQuery)); + + if (candidates.length > 0) { + hclAdd('pending'); + hclRemove('complete'); + } else { + return; + } + + var mark = perf.begin('onTree'); + + var mutations = candidates.reduce(function (acc, node) { + try { + var mutation = generateMutation(node); + + if (mutation) { + acc.push(mutation); + } + } catch (e) { + if (!PRODUCTION) { + if (e instanceof MissingIcon) { + console.error(e); + } + } + } + + return acc; + }, []); + + mark(); + + perform(mutations, function () { + hclAdd('active'); + hclAdd('complete'); + hclRemove('pending'); + + if (typeof callback === 'function') callback(); + }); +} + +var baseStyles = "svg:not(:root).svg-inline--fa {\n overflow: visible; }\n\n.svg-inline--fa {\n display: inline-block;\n font-size: inherit;\n height: 1em;\n overflow: visible;\n vertical-align: -.125em; }\n .svg-inline--fa.fa-lg {\n vertical-align: -.225em; }\n .svg-inline--fa.fa-w-1 {\n width: 0.0625em; }\n .svg-inline--fa.fa-w-2 {\n width: 0.125em; }\n .svg-inline--fa.fa-w-3 {\n width: 0.1875em; }\n .svg-inline--fa.fa-w-4 {\n width: 0.25em; }\n .svg-inline--fa.fa-w-5 {\n width: 0.3125em; }\n .svg-inline--fa.fa-w-6 {\n width: 0.375em; }\n .svg-inline--fa.fa-w-7 {\n width: 0.4375em; }\n .svg-inline--fa.fa-w-8 {\n width: 0.5em; }\n .svg-inline--fa.fa-w-9 {\n width: 0.5625em; }\n .svg-inline--fa.fa-w-10 {\n width: 0.625em; }\n .svg-inline--fa.fa-w-11 {\n width: 0.6875em; }\n .svg-inline--fa.fa-w-12 {\n width: 0.75em; }\n .svg-inline--fa.fa-w-13 {\n width: 0.8125em; }\n .svg-inline--fa.fa-w-14 {\n width: 0.875em; }\n .svg-inline--fa.fa-w-15 {\n width: 0.9375em; }\n .svg-inline--fa.fa-w-16 {\n width: 1em; }\n .svg-inline--fa.fa-w-17 {\n width: 1.0625em; }\n .svg-inline--fa.fa-w-18 {\n width: 1.125em; }\n .svg-inline--fa.fa-w-19 {\n width: 1.1875em; }\n .svg-inline--fa.fa-w-20 {\n width: 1.25em; }\n .svg-inline--fa.fa-pull-left {\n margin-right: .3em;\n width: auto; }\n .svg-inline--fa.fa-pull-right {\n margin-left: .3em;\n width: auto; }\n .svg-inline--fa.fa-border {\n height: 1.5em; }\n .svg-inline--fa.fa-li {\n width: 2em; }\n .svg-inline--fa.fa-fw {\n width: 1.25em; }\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0; }\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -12.5%;\n width: 1em; }\n .fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center; }\n\n.fa-layers-text, .fa-layers-counter {\n display: inline-block;\n position: absolute;\n text-align: center; }\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center; }\n\n.fa-layers-counter {\n background-color: #ff253a;\n border-radius: 1em;\n color: #fff;\n height: 1.5em;\n line-height: 1;\n max-width: 5em;\n min-width: 1.5em;\n overflow: hidden;\n padding: .25em;\n right: 0;\n text-overflow: ellipsis;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right; }\n\n.fa-layers-bottom-right {\n bottom: 0;\n right: 0;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right; }\n\n.fa-layers-bottom-left {\n bottom: 0;\n left: 0;\n right: auto;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left; }\n\n.fa-layers-top-right {\n right: 0;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right; }\n\n.fa-layers-top-left {\n left: 0;\n right: auto;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top left;\n transform-origin: top left; }\n\n.fa-lg {\n font-size: 1.33333em;\n line-height: 0.75em;\n vertical-align: -.0667em; }\n\n.fa-xs {\n font-size: .75em; }\n\n.fa-sm {\n font-size: .875em; }\n\n.fa-1x {\n font-size: 1em; }\n\n.fa-2x {\n font-size: 2em; }\n\n.fa-3x {\n font-size: 3em; }\n\n.fa-4x {\n font-size: 4em; }\n\n.fa-5x {\n font-size: 5em; }\n\n.fa-6x {\n font-size: 6em; }\n\n.fa-7x {\n font-size: 7em; }\n\n.fa-8x {\n font-size: 8em; }\n\n.fa-9x {\n font-size: 9em; }\n\n.fa-10x {\n font-size: 10em; }\n\n.fa-fw {\n text-align: center;\n width: 1.25em; }\n\n.fa-ul {\n list-style-type: none;\n margin-left: 2.5em;\n padding-left: 0; }\n .fa-ul > li {\n position: relative; }\n\n.fa-li {\n left: -2em;\n position: absolute;\n text-align: center;\n width: 2em;\n line-height: inherit; }\n\n.fa-border {\n border: solid 0.08em #eee;\n border-radius: .1em;\n padding: .2em .25em .15em; }\n\n.fa-pull-left {\n float: left; }\n\n.fa-pull-right {\n float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n margin-left: .3em; }\n\n.fa-spin {\n -webkit-animation: fa-spin 2s infinite linear;\n animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n -webkit-animation: fa-spin 1s infinite steps(8);\n animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg); }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg); }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg); }\n\n.fa-rotate-180 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg); }\n\n.fa-rotate-270 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1); }\n\n.fa-flip-horizontal.fa-flip-vertical {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n -webkit-filter: none;\n filter: none; }\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n position: relative;\n width: 2em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0; }\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1em; }\n\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2em; }\n\n.fa-inverse {\n color: #fff; }\n\n.sr-only {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n clip: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n position: static;\n width: auto; }\n"; + +var css = function () { + var dfp = DEFAULT_FAMILY_PREFIX; + var drc = DEFAULT_REPLACEMENT_CLASS; + var fp = config.familyPrefix; + var rc = config.replacementClass; + var s = baseStyles; + + if (fp !== dfp || rc !== drc) { + var dPatt = new RegExp('\\.' + dfp + '\\-', 'g'); + var rPatt = new RegExp('\\.' + drc, 'g'); + + s = s.replace(dPatt, '.' + fp + '-').replace(rPatt, '.' + rc); + } + + return s; +}; + +var Library = function () { + function Library() { + classCallCheck(this, Library); + + this.definitions = {}; + } + + createClass(Library, [{ + key: "add", + value: function add() { + var _this = this; + + for (var _len = arguments.length, definitions = Array(_len), _key = 0; _key < _len; _key++) { + definitions[_key] = arguments[_key]; + } + + var additions = definitions.reduce(this._pullDefinitions, {}); + + Object.keys(additions).forEach(function (key) { + _this.definitions[key] = _extends({}, _this.definitions[key] || {}, additions[key]); + }); + } + }, { + key: "reset", + value: function reset() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function _pullDefinitions(additions, definition) { + var normalized = definition.prefix && definition.iconName && definition.icon ? { 0: definition } : definition; + + Object.keys(normalized).map(function (key) { + var _normalized$key = normalized[key], + prefix = _normalized$key.prefix, + iconName = _normalized$key.iconName, + icon = _normalized$key.icon; + + + if (!additions[prefix]) additions[prefix] = {}; + + additions[prefix][iconName] = icon; + }); + + return additions; + } + }]); + return Library; +}(); + +function prepIcon(icon) { + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + return { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; +} + +var _cssInserted = false; + +function ensureCss() { + if (!config.autoAddCss) { + return; + } + + if (!_cssInserted) { + insertCss(css()); + } + + _cssInserted = true; +} + +function apiObject(val, abstractCreator) { + Object.defineProperty(val, 'abstract', { + get: abstractCreator + }); + + Object.defineProperty(val, 'html', { + get: function get() { + return val.abstract.map(function (a) { + return toHtml(a); + }); + } + }); + + Object.defineProperty(val, 'node', { + get: function get() { + if (!DOCUMENT.createElement) return; + + var container = DOCUMENT.createElement('div'); + container.innerHTML = val.html; + return container.children; + } + }); + + return val; +} + +function findIconDefinition(params) { + var _params$prefix = params.prefix, + prefix = _params$prefix === undefined ? 'fa' : _params$prefix, + iconName = params.iconName; + + + if (!iconName) return; + + return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); +} + +function resolveIcons(next) { + return function (maybeIconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); + + var mask = params.mask; + + + if (mask) { + mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); + } + + return next(iconDefinition, _extends({}, params, { mask: mask })); + }; +} + +var library = new Library(); + +var api$1 = { + dom: { + i2svg: function i2svg() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + ensureCss(); + + var _params$node = params.node, + node = _params$node === undefined ? DOCUMENT : _params$node, + _params$callback = params.callback, + callback = _params$callback === undefined ? function () {} : _params$callback; + + + if (config.searchPseudoElements) { + searchPseudoElements(node); + } + + onTree(node, callback); + }, + + css: css, + + insertCss: function insertCss$$1() { + insertCss(css()); + } + }, + + library: library, + + parse: { + transform: function transform(transformString) { + return parseTransformString(transformString); + } + }, + + findIconDefinition: findIconDefinition, + + icon: resolveIcons(function (iconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform = params.transform, + transform = _params$transform === undefined ? meaninglessTransform : _params$transform, + _params$symbol = params.symbol, + symbol = _params$symbol === undefined ? false : _params$symbol, + _params$mask = params.mask, + mask = _params$mask === undefined ? null : _params$mask, + _params$title = params.title, + title = _params$title === undefined ? null : _params$title, + _params$classes = params.classes, + classes = _params$classes === undefined ? [] : _params$classes, + _params$attributes = params.attributes, + attributes = _params$attributes === undefined ? {} : _params$attributes, + _params$styles = params.styles, + styles = _params$styles === undefined ? {} : _params$styles; + + + if (!iconDefinition) return; + + var prefix = iconDefinition.prefix, + iconName = iconDefinition.iconName, + icon = iconDefinition.icon; + + + return apiObject(_extends({ type: 'icon' }, iconDefinition), function () { + ensureCss(); + + if (config.autoA11y) { + if (title) { + attributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + attributes['aria-hidden'] = 'true'; + } + } + + return makeInlineSvgAbstract({ + icons: { + main: prepIcon(icon), + mask: mask ? prepIcon(mask.icon) : { found: false, width: null, height: null, icon: {} } + }, + prefix: prefix, + iconName: iconName, + transform: _extends({}, meaninglessTransform, transform), + symbol: symbol, + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: classes + } + }); + }); + }), + + text: function text(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform2 = params.transform, + transform = _params$transform2 === undefined ? meaninglessTransform : _params$transform2, + _params$title2 = params.title, + title = _params$title2 === undefined ? null : _params$title2, + _params$classes2 = params.classes, + classes = _params$classes2 === undefined ? [] : _params$classes2, + _params$attributes2 = params.attributes, + attributes = _params$attributes2 === undefined ? {} : _params$attributes2, + _params$styles2 = params.styles, + styles = _params$styles2 === undefined ? {} : _params$styles2; + + + return apiObject({ type: 'text', content: content }, function () { + ensureCss(); + + return makeLayersTextAbstract({ + content: content, + transform: _extends({}, meaninglessTransform, transform), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: [config.familyPrefix + '-layers-text'].concat(toConsumableArray(classes)) + } + }); + }); + }, + + layer: function layer(assembler) { + return apiObject({ type: 'layer' }, function () { + ensureCss(); + + var children = []; + + assembler(function (args) { + Array.isArray(args) ? children = args.map(function (a) { + children = children.concat(a.abstract); + }) : children = children.concat(args.abstract); + }); + + return [{ + tag: 'span', + attributes: { class: config.familyPrefix + '-layers' }, + children: children + }]; + }); + } +}; + +Object.defineProperty(api$1, 'config', { + get: function get() { + var autoReplaceSvg = config.autoReplaceSvg, + observeMutations = config.observeMutations, + showMissingIcons = config.showMissingIcons, + rest = objectWithoutProperties(config, ['autoReplaceSvg', 'observeMutations', 'showMissingIcons']); + + return rest; + }, + + set: function set(newConfig) { + update(newConfig); + } +}); + +export default api$1; diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.js b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.js new file mode 100644 index 000000000..5f3e84718 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/index.js @@ -0,0 +1,1594 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.fontawesome = factory()); +}(this, (function () { 'use strict'; + +var noop = function noop() {}; + +var _WINDOW = {}; +var _DOCUMENT = {}; +var _PERFORMANCE = { mark: noop, measure: noop }; + +try { + if (typeof window !== 'undefined') _WINDOW = window; + if (typeof document !== 'undefined') _DOCUMENT = document; + if (typeof performance !== 'undefined') _PERFORMANCE = performance; +} catch (e) {} + +var _ref = _WINDOW.navigator || {}; +var _ref$userAgent = _ref.userAgent; +var userAgent = _ref$userAgent === undefined ? '' : _ref$userAgent; + +var WINDOW = _WINDOW; +var DOCUMENT = _DOCUMENT; + +var PERFORMANCE = _PERFORMANCE; + +var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/'); + +var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___'; +var UNITS_IN_GRID = 16; +var DEFAULT_FAMILY_PREFIX = 'fa'; +var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa'; +var DATA_FA_PROCESSED = 'data-fa-processed'; +var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element'; +var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg'; + +var PRODUCTION = function () { + try { + return process.env.NODE_ENV === 'production'; + } catch (e) { + return false; + } +}(); + +var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); + + + +var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter'].concat(oneToTen.map(function (n) { + return n + 'x'; +})).concat(oneToTwenty.map(function (n) { + return 'w-' + n; +})); + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +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 function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + +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]; + } + } + } + + return target; +}; + +var objectWithoutProperties = function (obj, keys) { + var target = {}; + + for (var i in obj) { + if (keys.indexOf(i) >= 0) continue; + if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; + target[i] = obj[i]; + } + + return target; +}; + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +var _default = _extends({ + familyPrefix: DEFAULT_FAMILY_PREFIX, + replacementClass: DEFAULT_REPLACEMENT_CLASS, + autoReplaceSvg: true, + autoAddCss: true, + autoA11y: true, + searchPseudoElements: false, + observeMutations: true, + keepOriginalSource: true, + measurePerformance: false, + showMissingIcons: true +}, WINDOW.FontAwesomeConfig || {}); + +if (!_default.autoReplaceSvg) _default.observeMutations = false; + +var config = _extends({}, _default); + +WINDOW.FontAwesomeConfig = config; + +function update(newConfig) { + var validKeys = Object.keys(config); + + Object.keys(newConfig).forEach(function (configKey) { + if (~validKeys.indexOf(configKey)) { + config[configKey] = newConfig[configKey]; + } + }); +} + +var w = WINDOW || {}; + +if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; +if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; +if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; +if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + +var namespace = w[NAMESPACE_IDENTIFIER]; + +var d = UNITS_IN_GRID; + +var meaninglessTransform = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: false, + flipY: false +}; + +function isReserved(name) { + return ~RESERVED_CLASSES.indexOf(name); +} + + + +function insertCss(css) { + if (!css) { + return; + } + + if (typeof DOCUMENT.createElement === 'undefined') { + return; + } + + var style = DOCUMENT.createElement('style'); + style.setAttribute('type', 'text/css'); + style.innerHTML = css; + + var headChildren = DOCUMENT.head.childNodes; + var beforeChild = null; + + for (var i = headChildren.length - 1; i > -1; i--) { + var child = headChildren[i]; + var tagName = (child.tagName || '').toUpperCase(); + if (['STYLE', 'LINK'].indexOf(tagName) > -1) { + beforeChild = child; + } + } + + DOCUMENT.head.insertBefore(style, beforeChild); + + return css; +} + +var _uniqueId = 0; + +function nextUniqueId() { + _uniqueId++; + + return _uniqueId; +} + +function toArray(obj) { + var array = []; + + for (var i = (obj || []).length >>> 0; i--;) { + array[i] = obj[i]; + } + + return array; +} + +function classArray(node) { + if (node.classList) { + return toArray(node.classList); + } else { + return (node.getAttribute('class') || '').split(' ').filter(function (i) { + return i; + }); + } +} + +function getIconName(familyPrefix, cls) { + var parts = cls.split('-'); + var prefix = parts[0]; + var iconName = parts.slice(1).join('-'); + + if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) { + return iconName; + } else { + return null; + } +} + +function htmlEscape(str) { + return ('' + str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); +} + +function joinAttributes(attributes) { + return Object.keys(attributes || {}).reduce(function (acc, attributeName) { + return acc + (attributeName + '="' + htmlEscape(attributes[attributeName]) + '" '); + }, '').trim(); +} + +function joinStyles(styles) { + return Object.keys(styles || {}).reduce(function (acc, styleName) { + return acc + (styleName + ': ' + styles[styleName] + ';'); + }, ''); +} + +function transformIsMeaningful(transform) { + return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; +} + +function transformForSvg(_ref) { + var transform = _ref.transform, + containerWidth = _ref.containerWidth, + iconWidth = _ref.iconWidth; + + var outer = { + transform: 'translate(' + containerWidth / 2 + ' 256)' + }; + var innerTranslate = 'translate(' + transform.x * 32 + ', ' + transform.y * 32 + ') '; + var innerScale = 'scale(' + transform.size / 16 * (transform.flipX ? -1 : 1) + ', ' + transform.size / 16 * (transform.flipY ? -1 : 1) + ') '; + var innerRotate = 'rotate(' + transform.rotate + ' 0 0)'; + var inner = { + transform: innerTranslate + ' ' + innerScale + ' ' + innerRotate + }; + var path = { + transform: 'translate(' + iconWidth / 2 * -1 + ' -256)' + }; + return { + outer: outer, + inner: inner, + path: path + }; +} + +function transformForCss(_ref2) { + var transform = _ref2.transform, + _ref2$width = _ref2.width, + width = _ref2$width === undefined ? UNITS_IN_GRID : _ref2$width, + _ref2$height = _ref2.height, + height = _ref2$height === undefined ? UNITS_IN_GRID : _ref2$height, + _ref2$startCentered = _ref2.startCentered, + startCentered = _ref2$startCentered === undefined ? false : _ref2$startCentered; + + var val = ''; + + if (startCentered && IS_IE) { + val += 'translate(' + (transform.x / d - width / 2) + 'em, ' + (transform.y / d - height / 2) + 'em) '; + } else if (startCentered) { + val += 'translate(calc(-50% + ' + transform.x / d + 'em), calc(-50% + ' + transform.y / d + 'em)) '; + } else { + val += 'translate(' + transform.x / d + 'em, ' + transform.y / d + 'em) '; + } + + val += 'scale(' + transform.size / d * (transform.flipX ? -1 : 1) + ', ' + transform.size / d * (transform.flipY ? -1 : 1) + ') '; + val += 'rotate(' + transform.rotate + 'deg) '; + + return val; +} + +var ALL_SPACE = { + x: 0, + y: 0, + width: '100%', + height: '100%' +}; + +var makeIconMasking = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + mask = _ref.mask, + transform = _ref.transform; + var mainWidth = main.width, + mainPath = main.icon; + var maskWidth = mask.width, + maskPath = mask.icon; + + + var trans = transformForSvg({ transform: transform, containerWidth: maskWidth, iconWidth: mainWidth }); + + var maskRect = { + tag: 'rect', + attributes: _extends({}, ALL_SPACE, { + fill: 'white' + }) + }; + var maskInnerGroup = { + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ tag: 'path', attributes: _extends({}, mainPath.attributes, trans.path, { fill: 'black' }) }] + }; + var maskOuterGroup = { + tag: 'g', + attributes: _extends({}, trans.outer), + children: [maskInnerGroup] + }; + var maskId = 'mask-' + nextUniqueId(); + var clipId = 'clip-' + nextUniqueId(); + var maskTag = { + tag: 'mask', + attributes: _extends({}, ALL_SPACE, { + id: maskId, + maskUnits: 'userSpaceOnUse', + maskContentUnits: 'userSpaceOnUse' + }), + children: [maskRect, maskOuterGroup] + }; + var defs = { + tag: 'defs', + children: [{ tag: 'clipPath', attributes: { id: clipId }, children: [maskPath] }, maskTag] + }; + + children.push(defs, { tag: 'rect', attributes: _extends({ fill: 'currentColor', 'clip-path': 'url(#' + clipId + ')', mask: 'url(#' + maskId + ')' }, ALL_SPACE) }); + + return { + children: children, + attributes: attributes + }; +}; + +var makeIconStandard = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + transform = _ref.transform, + styles = _ref.styles; + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + if (transformIsMeaningful(transform)) { + var trans = transformForSvg({ transform: transform, containerWidth: main.width, iconWidth: main.width }); + children.push({ + tag: 'g', + attributes: _extends({}, trans.outer), + children: [{ + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ + tag: main.icon.tag, + children: main.icon.children, + attributes: _extends({}, main.icon.attributes, trans.path) + }] + }] + }); + } else { + children.push(main.icon); + } + + return { + children: children, + attributes: attributes + }; +}; + +var asIcon = function (_ref) { + var children = _ref.children, + main = _ref.main, + mask = _ref.mask, + attributes = _ref.attributes, + styles = _ref.styles, + transform = _ref.transform; + + if (transformIsMeaningful(transform) && main.found && !mask.found) { + var width = main.width, + height = main.height; + + var offset = { + x: width / height / 2, + y: 0.5 + }; + attributes['style'] = joinStyles(_extends({}, styles, { + 'transform-origin': offset.x + transform.x / 16 + 'em ' + (offset.y + transform.y / 16) + 'em' + })); + } + + return [{ + tag: 'svg', + attributes: attributes, + children: children + }]; +}; + +var asSymbol = function (_ref) { + var prefix = _ref.prefix, + iconName = _ref.iconName, + children = _ref.children, + attributes = _ref.attributes, + symbol = _ref.symbol; + + var id = symbol === true ? prefix + '-' + config.familyPrefix + '-' + iconName : symbol; + + return [{ + tag: 'svg', + attributes: { + style: 'display: none;' + }, + children: [{ + tag: 'symbol', + attributes: _extends({}, attributes, { id: id }), + children: children + }] + }]; +}; + +function makeInlineSvgAbstract(params) { + var _babelHelpers$extends; + + var _params$icons = params.icons, + main = _params$icons.main, + mask = _params$icons.mask, + prefix = params.prefix, + iconName = params.iconName, + transform = params.transform, + symbol = params.symbol, + title = params.title, + extra = params.extra; + + var _ref = mask.found ? mask : main, + width = _ref.width, + height = _ref.height; + + var widthClass = 'fa-w-' + Math.ceil(width / height * 16); + var attrClass = [config.replacementClass, iconName ? config.familyPrefix + '-' + iconName : '', widthClass].concat(extra.classes).join(' '); + + var content = { + children: [], + attributes: _extends({}, extra.attributes, (_babelHelpers$extends = {}, defineProperty(_babelHelpers$extends, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends, 'data-prefix', prefix), defineProperty(_babelHelpers$extends, 'data-icon', iconName), defineProperty(_babelHelpers$extends, 'class', attrClass), defineProperty(_babelHelpers$extends, 'role', 'img'), defineProperty(_babelHelpers$extends, 'xmlns', 'http://www.w3.org/2000/svg'), defineProperty(_babelHelpers$extends, 'viewBox', '0 0 ' + width + ' ' + height), _babelHelpers$extends)) + }; + + if (title) content.children.push({ tag: 'title', attributes: { id: content.attributes['aria-labelledby'] || 'title-' + nextUniqueId() }, children: [title] }); + + var args = _extends({}, content, { + prefix: prefix, + iconName: iconName, + main: main, + mask: mask, + transform: transform, + symbol: symbol, + styles: extra.styles + }); + + var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), + children = _ref2.children, + attributes = _ref2.attributes; + + args.children = children; + args.attributes = attributes; + + if (symbol) { + return asSymbol(args); + } else { + return asIcon(args); + } +} + +function makeLayersTextAbstract(params) { + var _babelHelpers$extends2; + + var content = params.content, + width = params.width, + height = params.height, + transform = params.transform, + title = params.title, + extra = params.extra; + + + var attributes = _extends({}, extra.attributes, title ? { 'title': title } : {}, (_babelHelpers$extends2 = {}, defineProperty(_babelHelpers$extends2, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends2, 'class', extra.classes.join(' ')), _babelHelpers$extends2)); + + var styles = _extends({}, extra.styles); + + if (transformIsMeaningful(transform)) { + styles['transform'] = transformForCss({ transform: transform, startCentered: true, width: width, height: height }); + styles['-webkit-transform'] = styles['transform']; + } + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ tag: 'span', attributes: { class: 'sr-only' }, children: [title] }); + } + + return val; +} + +var noop$2 = function noop() {}; +var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { mark: noop$2, measure: noop$2 }; +var preamble = 'FA "5.0.1"'; + +var begin = function begin(name) { + p.mark(preamble + ' ' + name + ' begins'); + return function () { + return end(name); + }; +}; + +var end = function end(name) { + p.mark(preamble + ' ' + name + ' ends'); + p.measure(preamble + ' ' + name, preamble + ' ' + name + ' begins', preamble + ' ' + name + ' ends'); +}; + +var perf = { begin: begin, end: end }; + +'use strict'; + +/** + * Internal helper to bind a function known to have 4 arguments + * to a given context. + */ +var bindInternal4 = function bindInternal4 (func, thisContext) { + return function (a, b, c, d) { + return func.call(thisContext, a, b, c, d); + }; +}; + +'use strict'; + + + +/** + * # Reduce + * + * A fast object `.reduce()` implementation. + * + * @param {Object} subject The object to reduce over. + * @param {Function} fn The reducer function. + * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0]. + * @param {Object} thisContext The context for the reducer. + * @return {mixed} The final result. + */ +var reduce = function fastReduceObject (subject, fn, initialValue, thisContext) { + var keys = Object.keys(subject), + length = keys.length, + iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn, + i, key, result; + + if (initialValue === undefined) { + i = 1; + result = subject[keys[0]]; + } + else { + i = 0; + result = initialValue; + } + + for (; i < length; i++) { + key = keys[i]; + result = iterator(result, subject[key], key, subject); + } + + return result; +}; + +var styles$2 = namespace.styles; +var shims = namespace.shims; + + +var _byUnicode = {}; +var _byLigature = {}; +var _byOldName = {}; + +var build = function build() { + var lookup = function lookup(reducer) { + return reduce(styles$2, function (o, style, prefix) { + o[prefix] = reduce(style, reducer, {}); + return o; + }, {}); + }; + + _byUnicode = lookup(function (acc, icon, iconName) { + acc[icon[3]] = iconName; + + return acc; + }); + + _byLigature = lookup(function (acc, icon, iconName) { + var ligatures = icon[2]; + + acc[iconName] = iconName; + + ligatures.forEach(function (ligature) { + acc[ligature] = iconName; + }); + + return acc; + }); + + var hasRegular = 'far' in styles$2; + + _byOldName = reduce(shims, function (acc, shim) { + var oldName = shim[0]; + var prefix = shim[1]; + var iconName = shim[2]; + + if (prefix === 'far' && !hasRegular) { + prefix = 'fas'; + } + + acc[oldName] = { prefix: prefix, iconName: iconName }; + + return acc; + }, {}); +}; + +build(); + +function byUnicode(prefix, unicode) { + return _byUnicode[prefix][unicode]; +} + +function byLigature(prefix, ligature) { + return _byLigature[prefix][ligature]; +} + +function byOldName(name) { + return _byOldName[name] || { prefix: null, iconName: null }; +} + +var styles$1 = namespace.styles; + + +var emptyCanonicalIcon = function emptyCanonicalIcon() { + return { prefix: null, iconName: null, rest: [] }; +}; + +function getCanonicalIcon(values) { + return values.reduce(function (acc, cls) { + var iconName = getIconName(config.familyPrefix, cls); + + if (styles$1[cls]) { + acc.prefix = cls; + } else if (iconName) { + var shim = acc.prefix === 'fa' ? byOldName(iconName) : {}; + + acc.iconName = shim.iconName || iconName; + acc.prefix = shim.prefix || acc.prefix; + } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) { + acc.rest.push(cls); + } + + return acc; + }, emptyCanonicalIcon()); +} + +function iconFromMapping(mapping, prefix, iconName) { + if (mapping && mapping[prefix] && mapping[prefix][iconName]) { + return { + prefix: prefix, + iconName: iconName, + icon: mapping[prefix][iconName] + }; + } +} + +function toHtml(abstractNodes) { + var tag = abstractNodes.tag, + _abstractNodes$attrib = abstractNodes.attributes, + attributes = _abstractNodes$attrib === undefined ? {} : _abstractNodes$attrib, + _abstractNodes$childr = abstractNodes.children, + children = _abstractNodes$childr === undefined ? [] : _abstractNodes$childr; + + + if (typeof abstractNodes === 'string') { + return htmlEscape(abstractNodes); + } else { + return '<' + tag + ' ' + joinAttributes(attributes) + '>' + children.map(toHtml).join('') + ''; + } +} + +var noop$1 = function noop() {}; + +function getMutator() { + if (config.autoReplaceSvg === true) { + return mutators.replace; + } + + var mutator = mutators[config.autoReplaceSvg]; + + return mutator || mutators.replace; +} + +var mutators = { + replace: function replace(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + var newOuterHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + + if (node.parentNode && node.outerHTML) { + node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? '' : ''); + } else if (node.parentNode) { + var newNode = document.createElement('span'); + node.parentNode.replaceChild(newNode, node); + newNode.outerHTML = newOuterHTML; + } + }, + nest: function nest(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + + // If we already have a replaced node we do not want to continue nesting within it. + // Short-circuit to the standard replacement + if (~classArray(node).indexOf(config.replacementClass)) { + return mutators.replace(mutation); + } + + var forSvg = new RegExp(config.familyPrefix + '-.*'); + + delete abstract[0].attributes.style; + + var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) { + if (cls === config.replacementClass || cls.match(forSvg)) { + acc.toSvg.push(cls); + } else { + acc.toNode.push(cls); + } + + return acc; + }, { toNode: [], toSvg: [] }); + + abstract[0].attributes.class = splitClasses.toSvg.join(' '); + + var newInnerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.setAttribute('class', splitClasses.toNode.join(' ')); + node.setAttribute(DATA_FA_PROCESSED, ''); + node.innerHTML = newInnerHTML; + } +}; + +function perform(mutations, callback) { + var callbackFunction = typeof callback === 'function' ? callback : noop$1; + + if (mutations.length === 0) { + callbackFunction(); + } else { + var frame = WINDOW.requestAnimationFrame || function (op) { + return op(); + }; + + frame(function () { + var mutator = getMutator(); + var mark = perf.begin('mutate'); + + mutations.map(mutator); + + mark(); + + callbackFunction(); + }); + } +} + +function disableObservation(operation) { + operation(); + +} + +var styleParser = function (node) { + var style = node.getAttribute('style'); + + var val = []; + + if (style) { + val = style.split(';').reduce(function (acc, style) { + var styles = style.split(':'); + var prop = styles[0]; + var value = styles.slice(1); + + if (prop && value.length > 0) { + acc[prop] = value.join(':').trim(); + } + + return acc; + }, {}); + } + + return val; +}; + +function toHex(unicode) { + var result = ''; + + for (var i = 0; i < unicode.length; i++) { + var hex = unicode.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + + return result; +} + +var classParser = function (node) { + var existingPrefix = node.getAttribute('data-prefix'); + var existingIconName = node.getAttribute('data-icon'); + var innerText = node.innerText !== undefined ? node.innerText.trim() : ''; + + var val = getCanonicalIcon(classArray(node)); + + if (existingPrefix && existingIconName) { + val.prefix = existingPrefix; + val.iconName = existingIconName; + } + + if (val.prefix && innerText.length > 1) { + val.iconName = byLigature(val.prefix, node.innerText); + } else if (val.prefix && innerText.length === 1) { + val.iconName = byUnicode(val.prefix, toHex(node.innerText)); + } + + return val; +}; + +var parseTransformString = function parseTransformString(transformString) { + var transform = { + size: 16, + x: 0, + y: 0, + flipX: false, + flipY: false, + rotate: 0 + }; + + if (!transformString) { + return transform; + } else { + return transformString.toLowerCase().split(' ').reduce(function (acc, n) { + var parts = n.toLowerCase().split('-'); + var first = parts[0]; + var rest = parts.slice(1).join('-'); + + if (first && rest === 'h') { + acc.flipX = true; + return acc; + } + + if (first && rest === 'v') { + acc.flipY = true; + return acc; + } + + rest = parseFloat(rest); + + if (isNaN(rest)) { + return acc; + } + + switch (first) { + case 'grow': + acc.size = acc.size + rest; + break; + case 'shrink': + acc.size = acc.size - rest; + break; + case 'left': + acc.x = acc.x - rest; + break; + case 'right': + acc.x = acc.x + rest; + break; + case 'up': + acc.y = acc.y - rest; + break; + case 'down': + acc.y = acc.y + rest; + break; + case 'rotate': + acc.rotate = acc.rotate + rest; + break; + } + + return acc; + }, transform); + } +}; + +var transformParser = function (node) { + return parseTransformString(node.getAttribute('data-fa-transform')); +}; + +var symbolParser = function (node) { + var symbol = node.getAttribute('data-fa-symbol'); + + return symbol === null ? false : symbol === '' ? true : symbol; +}; + +var attributesParser = function (node) { + var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) { + if (acc.name !== 'class' && acc.name !== 'style') { + acc[attr.name] = attr.value; + } + return acc; + }, {}); + + var title = node.getAttribute('title'); + + if (config.autoA11y) { + if (title) { + extraAttributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + extraAttributes['aria-hidden'] = 'true'; + } + } + + return extraAttributes; +}; + +var maskParser = function (node) { + var mask = node.getAttribute('data-fa-mask'); + + if (!mask) { + return emptyCanonicalIcon(); + } else { + return getCanonicalIcon(mask.split(' ').map(function (i) { + return i.trim(); + })); + } +}; + +function parseMeta(node) { + var _classParser = classParser(node), + iconName = _classParser.iconName, + prefix = _classParser.prefix, + extraClasses = _classParser.rest; + + var extraStyles = styleParser(node); + var transform = transformParser(node); + var symbol = symbolParser(node); + var extraAttributes = attributesParser(node); + var mask = maskParser(node); + + return { + iconName: iconName, + title: node.getAttribute('title'), + prefix: prefix, + transform: transform, + symbol: symbol, + mask: mask, + extra: { + classes: extraClasses, + styles: extraStyles, + attributes: extraAttributes + } + }; +} + +function MissingIcon(error) { + this.name = 'MissingIcon'; + this.message = error || 'Icon unavailable'; + this.stack = new Error().stack; +} + +MissingIcon.prototype = Object.create(Error.prototype); +MissingIcon.prototype.constructor = MissingIcon; + +var FILL = { fill: 'currentColor' }; +var ANIMATION_BASE = { + attributeType: 'XML', + repeatCount: 'indefinite', + dur: '2s' +}; +var RING = { + tag: 'path', + attributes: _extends({}, FILL, { + d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z' + }) +}; +var OPACITY_ANIMATE = _extends({}, ANIMATION_BASE, { + attributeName: 'opacity' +}); +var DOT = { + tag: 'circle', + attributes: _extends({}, FILL, { + cx: '256', + cy: '364', + r: '28' + }), + children: [{ tag: 'animate', attributes: _extends({}, ANIMATION_BASE, { attributeName: 'r', values: '28;14;28;28;14;28;' }) }, { tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;1;1;0;1;' }) }] +}; +var QUESTION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '1', + d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;0;0;0;1;' }) }] +}; +var EXCLAMATION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '0', + d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '0;0;1;1;0;0;' }) }] +}; + +var missing = { tag: 'g', children: [RING, DOT, QUESTION, EXCLAMATION] }; + +var styles = namespace.styles; + +var LAYERS_TEXT_CLASSNAME = 'fa-layers-text'; +var FONT_FAMILY_PATTERN = /Font Awesome 5 (Solid|Regular|Light|Brands)/; +var STYLE_TO_PREFIX = { + 'Solid': 'fas', + 'Regular': 'far', + 'Light': 'fal', + 'Brands': 'fab' +}; + +function findIcon(iconName, prefix) { + var val = { + found: false, + width: 512, + height: 512, + icon: missing + }; + + if (iconName && prefix && styles[prefix] && styles[prefix][iconName]) { + var icon = styles[prefix][iconName]; + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + val = { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; + } else if (iconName && prefix && !config.showMissingIcons) { + throw new MissingIcon('Icon is missing for prefix ' + prefix + ' with icon name ' + iconName); + } + + return val; +} + +function generateSvgReplacementMutation(node, nodeMeta) { + var iconName = nodeMeta.iconName, + title = nodeMeta.title, + prefix = nodeMeta.prefix, + transform = nodeMeta.transform, + symbol = nodeMeta.symbol, + mask = nodeMeta.mask, + extra = nodeMeta.extra; + + + return [node, makeInlineSvgAbstract({ + icons: { + main: findIcon(iconName, prefix), + mask: findIcon(mask.iconName, mask.prefix) + }, + prefix: prefix, + iconName: iconName, + transform: transform, + symbol: symbol, + mask: mask, + title: title, + extra: extra + })]; +} + +function generateLayersText(node, nodeMeta) { + var title = nodeMeta.title, + transform = nodeMeta.transform, + extra = nodeMeta.extra; + + + var width = null; + var height = null; + + if (IS_IE) { + var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10); + var boundingClientRect = node.getBoundingClientRect(); + width = boundingClientRect.width / computedFontSize; + height = boundingClientRect.height / computedFontSize; + } + + if (config.autoA11y && !title) { + extra.attributes['aria-hidden'] = 'true'; + } + + return [node, makeLayersTextAbstract({ + content: node.innerHTML, + width: width, + height: height, + transform: transform, + title: title, + extra: extra + })]; +} + +function generateMutation(node) { + var nodeMeta = parseMeta(node); + + if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) { + return generateLayersText(node, nodeMeta); + } else { + return generateSvgReplacementMutation(node, nodeMeta); + } +} + +function searchPseudoElements(root) { + var end = perf.begin('searchPseudoElements'); + + disableObservation(function () { + toArray(root.querySelectorAll('*')).forEach(function (node) { + [':before', ':after'].forEach(function (pos) { + var styles = WINDOW.getComputedStyle(node, pos); + var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN); + var children = toArray(node.children); + var pseudoElement = children.filter(function (c) { + return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === pos; + })[0]; + + if (!fontFamily && pseudoElement) { + pseudoElement.remove(); + } + + if (fontFamily && !pseudoElement) { + var content = styles.getPropertyValue('content'); + var i = DOCUMENT.createElement('i'); + i.setAttribute('class', '' + STYLE_TO_PREFIX[fontFamily[1]]); + i.setAttribute(DATA_FA_PSEUDO_ELEMENT, pos); + i.innerText = content.length === 3 ? content.substr(1, 1) : content; + if (pos === ':before') { + node.insertBefore(i, node.firstChild); + } else { + node.appendChild(i); + } + } + }); + }); + }); + + end(); +} + +function onTree(root) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var htmlClassList = DOCUMENT.documentElement.classList; + var hclAdd = function hclAdd(suffix) { + return htmlClassList.add(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var hclRemove = function hclRemove(suffix) { + return htmlClassList.remove(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var prefixes = Object.keys(styles); + var prefixesDomQuery = ['.' + LAYERS_TEXT_CLASSNAME + ':not([' + DATA_FA_PROCESSED + '])'].concat(prefixes.map(function (p) { + return '.' + p + ':not([' + DATA_FA_PROCESSED + '])'; + })).join(', '); + + if (prefixesDomQuery.length === 0) { + return; + } + + var candidates = toArray(root.querySelectorAll(prefixesDomQuery)); + + if (candidates.length > 0) { + hclAdd('pending'); + hclRemove('complete'); + } else { + return; + } + + var mark = perf.begin('onTree'); + + var mutations = candidates.reduce(function (acc, node) { + try { + var mutation = generateMutation(node); + + if (mutation) { + acc.push(mutation); + } + } catch (e) { + if (!PRODUCTION) { + if (e instanceof MissingIcon) { + console.error(e); + } + } + } + + return acc; + }, []); + + mark(); + + perform(mutations, function () { + hclAdd('active'); + hclAdd('complete'); + hclRemove('pending'); + + if (typeof callback === 'function') callback(); + }); +} + +var baseStyles = "svg:not(:root).svg-inline--fa {\n overflow: visible; }\n\n.svg-inline--fa {\n display: inline-block;\n font-size: inherit;\n height: 1em;\n overflow: visible;\n vertical-align: -.125em; }\n .svg-inline--fa.fa-lg {\n vertical-align: -.225em; }\n .svg-inline--fa.fa-w-1 {\n width: 0.0625em; }\n .svg-inline--fa.fa-w-2 {\n width: 0.125em; }\n .svg-inline--fa.fa-w-3 {\n width: 0.1875em; }\n .svg-inline--fa.fa-w-4 {\n width: 0.25em; }\n .svg-inline--fa.fa-w-5 {\n width: 0.3125em; }\n .svg-inline--fa.fa-w-6 {\n width: 0.375em; }\n .svg-inline--fa.fa-w-7 {\n width: 0.4375em; }\n .svg-inline--fa.fa-w-8 {\n width: 0.5em; }\n .svg-inline--fa.fa-w-9 {\n width: 0.5625em; }\n .svg-inline--fa.fa-w-10 {\n width: 0.625em; }\n .svg-inline--fa.fa-w-11 {\n width: 0.6875em; }\n .svg-inline--fa.fa-w-12 {\n width: 0.75em; }\n .svg-inline--fa.fa-w-13 {\n width: 0.8125em; }\n .svg-inline--fa.fa-w-14 {\n width: 0.875em; }\n .svg-inline--fa.fa-w-15 {\n width: 0.9375em; }\n .svg-inline--fa.fa-w-16 {\n width: 1em; }\n .svg-inline--fa.fa-w-17 {\n width: 1.0625em; }\n .svg-inline--fa.fa-w-18 {\n width: 1.125em; }\n .svg-inline--fa.fa-w-19 {\n width: 1.1875em; }\n .svg-inline--fa.fa-w-20 {\n width: 1.25em; }\n .svg-inline--fa.fa-pull-left {\n margin-right: .3em;\n width: auto; }\n .svg-inline--fa.fa-pull-right {\n margin-left: .3em;\n width: auto; }\n .svg-inline--fa.fa-border {\n height: 1.5em; }\n .svg-inline--fa.fa-li {\n width: 2em; }\n .svg-inline--fa.fa-fw {\n width: 1.25em; }\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0; }\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -12.5%;\n width: 1em; }\n .fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center; }\n\n.fa-layers-text, .fa-layers-counter {\n display: inline-block;\n position: absolute;\n text-align: center; }\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center; }\n\n.fa-layers-counter {\n background-color: #ff253a;\n border-radius: 1em;\n color: #fff;\n height: 1.5em;\n line-height: 1;\n max-width: 5em;\n min-width: 1.5em;\n overflow: hidden;\n padding: .25em;\n right: 0;\n text-overflow: ellipsis;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right; }\n\n.fa-layers-bottom-right {\n bottom: 0;\n right: 0;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right; }\n\n.fa-layers-bottom-left {\n bottom: 0;\n left: 0;\n right: auto;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left; }\n\n.fa-layers-top-right {\n right: 0;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right; }\n\n.fa-layers-top-left {\n left: 0;\n right: auto;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top left;\n transform-origin: top left; }\n\n.fa-lg {\n font-size: 1.33333em;\n line-height: 0.75em;\n vertical-align: -.0667em; }\n\n.fa-xs {\n font-size: .75em; }\n\n.fa-sm {\n font-size: .875em; }\n\n.fa-1x {\n font-size: 1em; }\n\n.fa-2x {\n font-size: 2em; }\n\n.fa-3x {\n font-size: 3em; }\n\n.fa-4x {\n font-size: 4em; }\n\n.fa-5x {\n font-size: 5em; }\n\n.fa-6x {\n font-size: 6em; }\n\n.fa-7x {\n font-size: 7em; }\n\n.fa-8x {\n font-size: 8em; }\n\n.fa-9x {\n font-size: 9em; }\n\n.fa-10x {\n font-size: 10em; }\n\n.fa-fw {\n text-align: center;\n width: 1.25em; }\n\n.fa-ul {\n list-style-type: none;\n margin-left: 2.5em;\n padding-left: 0; }\n .fa-ul > li {\n position: relative; }\n\n.fa-li {\n left: -2em;\n position: absolute;\n text-align: center;\n width: 2em;\n line-height: inherit; }\n\n.fa-border {\n border: solid 0.08em #eee;\n border-radius: .1em;\n padding: .2em .25em .15em; }\n\n.fa-pull-left {\n float: left; }\n\n.fa-pull-right {\n float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n margin-left: .3em; }\n\n.fa-spin {\n -webkit-animation: fa-spin 2s infinite linear;\n animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n -webkit-animation: fa-spin 1s infinite steps(8);\n animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg); }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg); }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg); }\n\n.fa-rotate-180 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg); }\n\n.fa-rotate-270 {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1); }\n\n.fa-flip-horizontal.fa-flip-vertical {\n -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n -webkit-filter: none;\n filter: none; }\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n position: relative;\n width: 2em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0; }\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1em; }\n\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2em; }\n\n.fa-inverse {\n color: #fff; }\n\n.sr-only {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n clip: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n position: static;\n width: auto; }\n"; + +var css = function () { + var dfp = DEFAULT_FAMILY_PREFIX; + var drc = DEFAULT_REPLACEMENT_CLASS; + var fp = config.familyPrefix; + var rc = config.replacementClass; + var s = baseStyles; + + if (fp !== dfp || rc !== drc) { + var dPatt = new RegExp('\\.' + dfp + '\\-', 'g'); + var rPatt = new RegExp('\\.' + drc, 'g'); + + s = s.replace(dPatt, '.' + fp + '-').replace(rPatt, '.' + rc); + } + + return s; +}; + +var Library = function () { + function Library() { + classCallCheck(this, Library); + + this.definitions = {}; + } + + createClass(Library, [{ + key: "add", + value: function add() { + var _this = this; + + for (var _len = arguments.length, definitions = Array(_len), _key = 0; _key < _len; _key++) { + definitions[_key] = arguments[_key]; + } + + var additions = definitions.reduce(this._pullDefinitions, {}); + + Object.keys(additions).forEach(function (key) { + _this.definitions[key] = _extends({}, _this.definitions[key] || {}, additions[key]); + }); + } + }, { + key: "reset", + value: function reset() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function _pullDefinitions(additions, definition) { + var normalized = definition.prefix && definition.iconName && definition.icon ? { 0: definition } : definition; + + Object.keys(normalized).map(function (key) { + var _normalized$key = normalized[key], + prefix = _normalized$key.prefix, + iconName = _normalized$key.iconName, + icon = _normalized$key.icon; + + + if (!additions[prefix]) additions[prefix] = {}; + + additions[prefix][iconName] = icon; + }); + + return additions; + } + }]); + return Library; +}(); + +function prepIcon(icon) { + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + return { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; +} + +var _cssInserted = false; + +function ensureCss() { + if (!config.autoAddCss) { + return; + } + + if (!_cssInserted) { + insertCss(css()); + } + + _cssInserted = true; +} + +function apiObject(val, abstractCreator) { + Object.defineProperty(val, 'abstract', { + get: abstractCreator + }); + + Object.defineProperty(val, 'html', { + get: function get() { + return val.abstract.map(function (a) { + return toHtml(a); + }); + } + }); + + Object.defineProperty(val, 'node', { + get: function get() { + if (!DOCUMENT.createElement) return; + + var container = DOCUMENT.createElement('div'); + container.innerHTML = val.html; + return container.children; + } + }); + + return val; +} + +function findIconDefinition(params) { + var _params$prefix = params.prefix, + prefix = _params$prefix === undefined ? 'fa' : _params$prefix, + iconName = params.iconName; + + + if (!iconName) return; + + return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); +} + +function resolveIcons(next) { + return function (maybeIconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); + + var mask = params.mask; + + + if (mask) { + mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); + } + + return next(iconDefinition, _extends({}, params, { mask: mask })); + }; +} + +var library = new Library(); + +var api$1 = { + dom: { + i2svg: function i2svg() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + ensureCss(); + + var _params$node = params.node, + node = _params$node === undefined ? DOCUMENT : _params$node, + _params$callback = params.callback, + callback = _params$callback === undefined ? function () {} : _params$callback; + + + if (config.searchPseudoElements) { + searchPseudoElements(node); + } + + onTree(node, callback); + }, + + css: css, + + insertCss: function insertCss$$1() { + insertCss(css()); + } + }, + + library: library, + + parse: { + transform: function transform(transformString) { + return parseTransformString(transformString); + } + }, + + findIconDefinition: findIconDefinition, + + icon: resolveIcons(function (iconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform = params.transform, + transform = _params$transform === undefined ? meaninglessTransform : _params$transform, + _params$symbol = params.symbol, + symbol = _params$symbol === undefined ? false : _params$symbol, + _params$mask = params.mask, + mask = _params$mask === undefined ? null : _params$mask, + _params$title = params.title, + title = _params$title === undefined ? null : _params$title, + _params$classes = params.classes, + classes = _params$classes === undefined ? [] : _params$classes, + _params$attributes = params.attributes, + attributes = _params$attributes === undefined ? {} : _params$attributes, + _params$styles = params.styles, + styles = _params$styles === undefined ? {} : _params$styles; + + + if (!iconDefinition) return; + + var prefix = iconDefinition.prefix, + iconName = iconDefinition.iconName, + icon = iconDefinition.icon; + + + return apiObject(_extends({ type: 'icon' }, iconDefinition), function () { + ensureCss(); + + if (config.autoA11y) { + if (title) { + attributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + attributes['aria-hidden'] = 'true'; + } + } + + return makeInlineSvgAbstract({ + icons: { + main: prepIcon(icon), + mask: mask ? prepIcon(mask.icon) : { found: false, width: null, height: null, icon: {} } + }, + prefix: prefix, + iconName: iconName, + transform: _extends({}, meaninglessTransform, transform), + symbol: symbol, + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: classes + } + }); + }); + }), + + text: function text(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform2 = params.transform, + transform = _params$transform2 === undefined ? meaninglessTransform : _params$transform2, + _params$title2 = params.title, + title = _params$title2 === undefined ? null : _params$title2, + _params$classes2 = params.classes, + classes = _params$classes2 === undefined ? [] : _params$classes2, + _params$attributes2 = params.attributes, + attributes = _params$attributes2 === undefined ? {} : _params$attributes2, + _params$styles2 = params.styles, + styles = _params$styles2 === undefined ? {} : _params$styles2; + + + return apiObject({ type: 'text', content: content }, function () { + ensureCss(); + + return makeLayersTextAbstract({ + content: content, + transform: _extends({}, meaninglessTransform, transform), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: [config.familyPrefix + '-layers-text'].concat(toConsumableArray(classes)) + } + }); + }); + }, + + layer: function layer(assembler) { + return apiObject({ type: 'layer' }, function () { + ensureCss(); + + var children = []; + + assembler(function (args) { + Array.isArray(args) ? children = args.map(function (a) { + children = children.concat(a.abstract); + }) : children = children.concat(args.abstract); + }); + + return [{ + tag: 'span', + attributes: { class: config.familyPrefix + '-layers' }, + children: children + }]; + }); + } +}; + +Object.defineProperty(api$1, 'config', { + get: function get() { + var autoReplaceSvg = config.autoReplaceSvg, + observeMutations = config.observeMutations, + showMissingIcons = config.showMissingIcons, + rest = objectWithoutProperties(config, ['autoReplaceSvg', 'observeMutations', 'showMissingIcons']); + + return rest; + }, + + set: function set(newConfig) { + update(newConfig); + } +}); + +return api$1; + +}))); diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/package.json b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/package.json new file mode 100644 index 000000000..fa0a94fc1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/package.json @@ -0,0 +1,53 @@ +{ + "description": "The iconic font, CSS, and SVG framework", + "keywords": [ + "font", + "awesome", + "fontawesome", + "icon", + "svg", + "bootstrap" + ], + "homepage": "https://fontawesome.com", + "bugs": { + "url": "http://github.com/FortAwesome/Font-Awesome/issues" + }, + "author": { + "name": "Dave Gandy", + "email": "dave@fontawesome.com", + "web": "http://twitter.com/davegandy" + }, + "contributors": [ + { + "name": "Brian Talbot", + "web": "http://twitter.com/talbs" + }, + { + "name": "Travis Chase", + "web": "http://twitter.com/supercodepoet" + }, + { + "name": "Rob Madole", + "web": "http://twitter.com/robmadole" + }, + { + "name": "Geremia Taglialatela", + "web": "http://twitter.com/gtagliala" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/FortAwesome/Font-Awesome" + }, + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "version": "1.0.1", + "name": "@fortawesome/fontawesome", + "main": "index.js", + "module": "index.es.js", + "jsnext:main": "index.es.js", + "style": "styles.css", + "license": "MIT" +} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/styles.css b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/styles.css new file mode 100644 index 000000000..0eb9ad35f --- /dev/null +++ b/backend/webif/static/js/fontawesome/advanced-options/use-with-node-js/fontawesome/styles.css @@ -0,0 +1,343 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +svg:not(:root).svg-inline--fa { + overflow: visible; } + +.svg-inline--fa { + display: inline-block; + font-size: inherit; + height: 1em; + overflow: visible; + vertical-align: -.125em; } + .svg-inline--fa.fa-lg { + vertical-align: -.225em; } + .svg-inline--fa.fa-w-1 { + width: 0.0625em; } + .svg-inline--fa.fa-w-2 { + width: 0.125em; } + .svg-inline--fa.fa-w-3 { + width: 0.1875em; } + .svg-inline--fa.fa-w-4 { + width: 0.25em; } + .svg-inline--fa.fa-w-5 { + width: 0.3125em; } + .svg-inline--fa.fa-w-6 { + width: 0.375em; } + .svg-inline--fa.fa-w-7 { + width: 0.4375em; } + .svg-inline--fa.fa-w-8 { + width: 0.5em; } + .svg-inline--fa.fa-w-9 { + width: 0.5625em; } + .svg-inline--fa.fa-w-10 { + width: 0.625em; } + .svg-inline--fa.fa-w-11 { + width: 0.6875em; } + .svg-inline--fa.fa-w-12 { + width: 0.75em; } + .svg-inline--fa.fa-w-13 { + width: 0.8125em; } + .svg-inline--fa.fa-w-14 { + width: 0.875em; } + .svg-inline--fa.fa-w-15 { + width: 0.9375em; } + .svg-inline--fa.fa-w-16 { + width: 1em; } + .svg-inline--fa.fa-w-17 { + width: 1.0625em; } + .svg-inline--fa.fa-w-18 { + width: 1.125em; } + .svg-inline--fa.fa-w-19 { + width: 1.1875em; } + .svg-inline--fa.fa-w-20 { + width: 1.25em; } + .svg-inline--fa.fa-pull-left { + margin-right: .3em; + width: auto; } + .svg-inline--fa.fa-pull-right { + margin-left: .3em; + width: auto; } + .svg-inline--fa.fa-border { + height: 1.5em; } + .svg-inline--fa.fa-li { + width: 2em; } + .svg-inline--fa.fa-fw { + width: 1.25em; } + +.fa-layers svg.svg-inline--fa { + bottom: 0; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; } + +.fa-layers { + display: inline-block; + height: 1em; + position: relative; + text-align: center; + vertical-align: -12.5%; + width: 1em; } + .fa-layers svg.svg-inline--fa { + -webkit-transform-origin: center center; + transform-origin: center center; } + +.fa-layers-text, .fa-layers-counter { + display: inline-block; + position: absolute; + text-align: center; } + +.fa-layers-text { + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + -webkit-transform-origin: center center; + transform-origin: center center; } + +.fa-layers-counter { + background-color: #ff253a; + border-radius: 1em; + color: #fff; + height: 1.5em; + line-height: 1; + max-width: 5em; + min-width: 1.5em; + overflow: hidden; + padding: .25em; + right: 0; + text-overflow: ellipsis; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top right; + transform-origin: top right; } + +.fa-layers-bottom-right { + bottom: 0; + right: 0; + top: auto; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: bottom right; + transform-origin: bottom right; } + +.fa-layers-bottom-left { + bottom: 0; + left: 0; + right: auto; + top: auto; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: bottom left; + transform-origin: bottom left; } + +.fa-layers-top-right { + right: 0; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top right; + transform-origin: top right; } + +.fa-layers-top-left { + left: 0; + right: auto; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top left; + transform-origin: top left; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + position: relative; + width: 2em; } + +.fa-stack-1x, +.fa-stack-2x { + bottom: 0; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; } + +.svg-inline--fa.fa-stack-1x { + height: 1em; + width: 1em; } + +.svg-inline--fa.fa-stack-2x { + height: 2em; + width: 2em; } + +.fa-inverse { + color: #fff; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } diff --git a/backend/webif/static/js/fontawesome/svg-with-js/css/fa-svg-with-js.css b/backend/webif/static/js/fontawesome/svg-with-js/css/fa-svg-with-js.css new file mode 100644 index 000000000..0eb9ad35f --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/css/fa-svg-with-js.css @@ -0,0 +1,343 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +svg:not(:root).svg-inline--fa { + overflow: visible; } + +.svg-inline--fa { + display: inline-block; + font-size: inherit; + height: 1em; + overflow: visible; + vertical-align: -.125em; } + .svg-inline--fa.fa-lg { + vertical-align: -.225em; } + .svg-inline--fa.fa-w-1 { + width: 0.0625em; } + .svg-inline--fa.fa-w-2 { + width: 0.125em; } + .svg-inline--fa.fa-w-3 { + width: 0.1875em; } + .svg-inline--fa.fa-w-4 { + width: 0.25em; } + .svg-inline--fa.fa-w-5 { + width: 0.3125em; } + .svg-inline--fa.fa-w-6 { + width: 0.375em; } + .svg-inline--fa.fa-w-7 { + width: 0.4375em; } + .svg-inline--fa.fa-w-8 { + width: 0.5em; } + .svg-inline--fa.fa-w-9 { + width: 0.5625em; } + .svg-inline--fa.fa-w-10 { + width: 0.625em; } + .svg-inline--fa.fa-w-11 { + width: 0.6875em; } + .svg-inline--fa.fa-w-12 { + width: 0.75em; } + .svg-inline--fa.fa-w-13 { + width: 0.8125em; } + .svg-inline--fa.fa-w-14 { + width: 0.875em; } + .svg-inline--fa.fa-w-15 { + width: 0.9375em; } + .svg-inline--fa.fa-w-16 { + width: 1em; } + .svg-inline--fa.fa-w-17 { + width: 1.0625em; } + .svg-inline--fa.fa-w-18 { + width: 1.125em; } + .svg-inline--fa.fa-w-19 { + width: 1.1875em; } + .svg-inline--fa.fa-w-20 { + width: 1.25em; } + .svg-inline--fa.fa-pull-left { + margin-right: .3em; + width: auto; } + .svg-inline--fa.fa-pull-right { + margin-left: .3em; + width: auto; } + .svg-inline--fa.fa-border { + height: 1.5em; } + .svg-inline--fa.fa-li { + width: 2em; } + .svg-inline--fa.fa-fw { + width: 1.25em; } + +.fa-layers svg.svg-inline--fa { + bottom: 0; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; } + +.fa-layers { + display: inline-block; + height: 1em; + position: relative; + text-align: center; + vertical-align: -12.5%; + width: 1em; } + .fa-layers svg.svg-inline--fa { + -webkit-transform-origin: center center; + transform-origin: center center; } + +.fa-layers-text, .fa-layers-counter { + display: inline-block; + position: absolute; + text-align: center; } + +.fa-layers-text { + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + -webkit-transform-origin: center center; + transform-origin: center center; } + +.fa-layers-counter { + background-color: #ff253a; + border-radius: 1em; + color: #fff; + height: 1.5em; + line-height: 1; + max-width: 5em; + min-width: 1.5em; + overflow: hidden; + padding: .25em; + right: 0; + text-overflow: ellipsis; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top right; + transform-origin: top right; } + +.fa-layers-bottom-right { + bottom: 0; + right: 0; + top: auto; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: bottom right; + transform-origin: bottom right; } + +.fa-layers-bottom-left { + bottom: 0; + left: 0; + right: auto; + top: auto; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: bottom left; + transform-origin: bottom left; } + +.fa-layers-top-right { + right: 0; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top right; + transform-origin: top right; } + +.fa-layers-top-left { + left: 0; + right: auto; + top: 0; + -webkit-transform: scale(0.25); + transform: scale(0.25); + -webkit-transform-origin: top left; + transform-origin: top left; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + position: relative; + width: 2em; } + +.fa-stack-1x, +.fa-stack-2x { + bottom: 0; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; } + +.svg-inline--fa.fa-stack-1x { + height: 1em; + width: 1em; } + +.svg-inline--fa.fa-stack-2x { + height: 2em; + width: 2em; } + +.fa-inverse { + color: #fff; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } diff --git a/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.js b/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.js new file mode 100644 index 000000000..58909066a --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.js @@ -0,0 +1,412 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function () { +'use strict'; + +var _WINDOW = {}; +try { + if (typeof window !== 'undefined') _WINDOW = window; + +} catch (e) {} + +var _ref = _WINDOW.navigator || {}; +var _ref$userAgent = _ref.userAgent; +var userAgent = _ref$userAgent === undefined ? '' : _ref$userAgent; + +var WINDOW = _WINDOW; + + + + +var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/'); + +var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___'; + + + + + + + + + +var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); + + + +var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter'].concat(oneToTen.map(function (n) { + return n + 'x'; +})).concat(oneToTwenty.map(function (n) { + return 'w-' + n; +})); + +function bunker(fn) { + try { + fn(); + } catch (e) { + + } +} + +var icons$1 = { + "500px": [448, 512, [], "f26e", "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"], + "accessible-icon": [448, 512, [], "f368", "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"], + "accusoft": [640, 512, [], "f369", "M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"], + "adn": [496, 512, [], "f170", "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"], + "adversal": [512, 512, [], "f36a", "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"], + "affiliatetheme": [512, 512, [], "f36b", "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"], + "algolia": [448, 512, [], "f36c", "M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"], + "amazon": [448, 512, [], "f270", "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"], + "amilia": [448, 512, [], "f36d", "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"], + "android": [448, 512, [], "f17b", "M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"], + "angellist": [448, 512, [], "f209", "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"], + "angrycreative": [640, 512, [], "f36e", "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"], + "angular": [415, 512, [], "f420", "M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"], + "app-store": [512, 512, [], "f36f", "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"], + "app-store-ios": [448, 512, [], "f370", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"], + "apper": [640, 512, [], "f371", "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"], + "apple": [448, 512, [], "f179", "M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"], + "apple-pay": [640, 512, [], "f415", "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"], + "asymmetrik": [576, 512, [], "f372", "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"], + "audible": [640, 512, [], "f373", "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"], + "autoprefixer": [640, 512, [], "f41c", "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"], + "avianex": [512, 512, [], "f374", "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"], + "aviato": [640, 512, [], "f421", "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"], + "aws": [512, 512, [], "f375", "M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"], + "bandcamp": [496, 512, [], "f2d5", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"], + "behance": [576, 512, [], "f1b4", "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"], + "behance-square": [512, 512, [], "f1b5", "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"], + "bimobject": [448, 512, [], "f378", "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"], + "bitbucket": [512, 512, [], "f171", "M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"], + "bitcoin": [512, 512, [], "f379", "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"], + "bity": [496, 512, [], "f37a", "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"], + "black-tie": [448, 512, [], "f27e", "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"], + "blackberry": [512, 512, [], "f37b", "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"], + "blogger": [448, 512, [], "f37c", "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"], + "blogger-b": [448, 512, [], "f37d", "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"], + "bluetooth": [448, 512, [], "f293", "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"], + "bluetooth-b": [320, 512, [], "f294", "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"], + "btc": [384, 512, [], "f15a", "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"], + "buromobelexperte": [448, 512, [], "f37f", "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"], + "buysellads": [448, 512, [], "f20d", "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"], + "cc-amex": [576, 512, [], "f1f3", "M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"], + "cc-apple-pay": [576, 512, [], "f416", "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"], + "cc-diners-club": [576, 512, [], "f24c", "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"], + "cc-discover": [576, 512, [], "f1f2", "M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"], + "cc-jcb": [576, 512, [], "f24b", "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"], + "cc-mastercard": [576, 512, [], "f1f1", "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"], + "cc-paypal": [576, 512, [], "f1f4", "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"], + "cc-stripe": [576, 512, [], "f1f5", "M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"], + "cc-visa": [576, 512, [], "f1f0", "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"], + "centercode": [512, 512, [], "f380", "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"], + "chrome": [496, 512, [], "f268", "M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"], + "cloudscale": [448, 512, [], "f383", "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"], + "cloudsmith": [332, 512, [], "f384", "M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"], + "cloudversify": [616, 512, [], "f385", "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"], + "codepen": [512, 512, [], "f1cb", "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"], + "codiepie": [472, 512, [], "f284", "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"], + "connectdevelop": [576, 512, [], "f20e", "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"], + "contao": [512, 512, [], "f26d", "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"], + "cpanel": [640, 512, [], "f388", "M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"], + "creative-commons": [512, 512, [], "f25e", "M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"], + "css3": [512, 512, [], "f13c", "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"], + "css3-alt": [384, 512, [], "f38b", "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"], + "cuttlefish": [440, 512, [], "f38c", "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"], + "d-and-d": [576, 512, [], "f38d", "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"], + "dashcube": [384, 512, [], "f210", "M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"], + "delicious": [448, 512, [], "f1a5", "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"], + "deploydog": [512, 512, [], "f38e", "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"], + "deskpro": [480, 512, [], "f38f", "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"], + "deviantart": [320, 512, [], "f1bd", "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"], + "digg": [512, 512, [], "f1a6", "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"], + "digital-ocean": [512, 512, [], "f391", "M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"], + "discord": [448, 512, [], "f392", "M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"], + "discourse": [448, 512, [], "f393", "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"], + "dochub": [416, 512, [], "f394", "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"], + "docker": [640, 512, [], "f395", "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"], + "draft2digital": [480, 512, [], "f396", "M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"], + "dribbble": [512, 512, [], "f17d", "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"], + "dribbble-square": [448, 512, [], "f397", "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"], + "dropbox": [528, 512, [], "f16b", "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"], + "drupal": [448, 512, [], "f1a9", "M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"], + "dyalog": [416, 512, [], "f399", "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"], + "earlybirds": [480, 512, [], "f39a", "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"], + "edge": [512, 512, [], "f282", "M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"], + "ember": [640, 512, [], "f423", "M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"], + "empire": [496, 512, [], "f1d1", "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"], + "envira": [448, 512, [], "f299", "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"], + "erlang": [640, 512, [], "f39d", "M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"], + "etsy": [384, 512, [], "f2d7", "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"], + "expeditedssl": [496, 512, [], "f23e", "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"], + "facebook": [448, 512, [], "f09a", "M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"], + "facebook-f": [264, 512, [], "f39e", "M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"], + "facebook-messenger": [448, 512, [], "f39f", "M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"], + "facebook-square": [448, 512, [], "f082", "M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"], + "firefox": [480, 512, [], "f269", "M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"], + "first-order": [448, 512, [], "f2b0", "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"], + "firstdraft": [384, 512, [], "f3a1", "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"], + "flickr": [448, 512, [], "f16e", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"], + "fly": [384, 512, [], "f417", "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"], + "font-awesome": [448, 512, [], "f2b4", "M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"], + "font-awesome-alt": [448, 512, [], "f35c", "M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"], + "font-awesome-flag": [448, 512, [], "f425", "M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"], + "fonticons": [448, 512, [], "f280", "M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"], + "fonticons-fi": [384, 512, [], "f3a2", "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"], + "fort-awesome": [448, 512, [], "f286", "M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"], + "fort-awesome-alt": [512, 512, [], "f3a3", "M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"], + "forumbee": [448, 512, [], "f211", "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"], + "foursquare": [368, 512, [], "f180", "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"], + "free-code-camp": [576, 512, [], "f2c5", "M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"], + "freebsd": [448, 512, [], "f3a4", "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"], + "get-pocket": [448, 512, [], "f265", "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"], + "gg": [512, 512, [], "f260", "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"], + "gg-circle": [512, 512, [], "f261", "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"], + "git": [448, 512, [], "f1d3", "M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"], + "git-square": [448, 512, [], "f1d2", "M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"], + "github": [496, 512, [], "f09b", "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"], + "github-alt": [480, 512, [], "f113", "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"], + "github-square": [448, 512, [], "f092", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"], + "gitkraken": [592, 512, [], "f3a6", "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"], + "gitlab": [512, 512, [], "f296", "M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"], + "gitter": [384, 512, [], "f426", "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"], + "glide": [448, 512, [], "f2a5", "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"], + "glide-g": [448, 512, [], "f2a6", "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"], + "gofore": [400, 512, [], "f3a7", "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"], + "goodreads": [448, 512, [], "f3a8", "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"], + "goodreads-g": [384, 512, [], "f3a9", "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"], + "google": [488, 512, [], "f1a0", "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"], + "google-drive": [512, 512, [], "f3aa", "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"], + "google-play": [512, 512, [], "f3ab", "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"], + "google-plus": [496, 512, [], "f2b3", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"], + "google-plus-g": [640, 512, [], "f0d5", "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"], + "google-plus-square": [448, 512, [], "f0d4", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"], + "google-wallet": [448, 512, [], "f1ee", "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"], + "gratipay": [496, 512, [], "f184", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"], + "grav": [512, 512, [], "f2d6", "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"], + "gripfire": [384, 512, [], "f3ac", "M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"], + "grunt": [384, 512, [], "f3ad", "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"], + "gulp": [256, 512, [], "f3ae", "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"], + "hacker-news": [448, 512, [], "f1d4", "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"], + "hacker-news-square": [448, 512, [], "f3af", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"], + "hire-a-helper": [512, 512, [], "f3b0", "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"], + "hooli": [640, 512, [], "f427", "M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"], + "hotjar": [448, 512, [], "f3b1", "M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"], + "houzz": [320, 512, [], "f27c", "M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"], + "html5": [384, 512, [], "f13b", "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"], + "hubspot": [512, 512, [], "f3b2", "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"], + "imdb": [448, 512, [], "f2d8", "M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"], + "instagram": [448, 512, [], "f16d", "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"], + "internet-explorer": [512, 512, [], "f26b", "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"], + "ioxhost": [640, 512, [], "f208", "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"], + "itunes": [448, 512, [], "f3b4", "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"], + "itunes-note": [384, 512, [], "f3b5", "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"], + "jenkins": [512, 512, [], "f3b6", "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"], + "joget": [496, 512, [], "f3b7", "M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"], + "joomla": [448, 512, [], "f1aa", "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"], + "js": [448, 512, [], "f3b8", "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"], + "js-square": [512, 512, [], "f3b9", "M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"], + "jsfiddle": [576, 512, [], "f1cc", "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"], + "keycdn": [512, 512, [], "f3ba", "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"], + "kickstarter": [448, 512, [], "f3bb", "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"], + "kickstarter-k": [384, 512, [], "f3bc", "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"], + "laravel": [640, 512, [], "f3bd", "M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"], + "lastfm": [512, 512, [], "f202", "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"], + "lastfm-square": [448, 512, [], "f203", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"], + "leanpub": [576, 512, [], "f212", "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"], + "less": [640, 512, [], "f41d", "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"], + "line": [448, 512, [], "f3c0", "M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"], + "linkedin": [448, 512, [], "f08c", "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"], + "linkedin-in": [448, 512, [], "f0e1", "M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"], + "linode": [448, 512, [], "f2b8", "M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"], + "linux": [448, 512, [], "f17c", "M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"], + "lyft": [512, 512, [], "f3c3", "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"], + "magento": [448, 512, [], "f3c4", "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"], + "maxcdn": [512, 512, [], "f136", "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"], + "medapps": [320, 512, [], "f3c6", "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"], + "medium": [448, 512, [], "f23a", "M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"], + "medium-m": [512, 512, [], "f3c7", "M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"], + "medrt": [544, 512, [], "f3c8", "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"], + "meetup": [512, 512, [], "f2e0", "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"], + "microsoft": [448, 512, [], "f3ca", "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"], + "mix": [416, 512, [], "f3cb", "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"], + "mixcloud": [640, 512, [], "f289", "M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"], + "mizuni": [496, 512, [], "f3cc", "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"], + "modx": [448, 512, [], "f285", "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"], + "monero": [496, 512, [], "f3d0", "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"], + "napster": [496, 512, [], "f3d2", "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"], + "nintendo-switch": [448, 512, [], "f418", "M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"], + "node": [640, 512, [], "f419", "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"], + "node-js": [448, 512, [], "f3d3", "M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"], + "npm": [576, 512, [], "f3d4", "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"], + "ns8": [640, 512, [], "f3d5", "M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"], + "nutritionix": [400, 512, [], "f3d6", "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"], + "odnoklassniki": [320, 512, [], "f263", "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"], + "odnoklassniki-square": [448, 512, [], "f264", "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"], + "opencart": [640, 512, [], "f23d", "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"], + "openid": [448, 512, [], "f19b", "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"], + "opera": [496, 512, [], "f26a", "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"], + "optin-monster": [576, 512, [], "f23c", "M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"], + "osi": [495, 512, [], "f41a", "M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"], + "page4": [496, 512, [], "f3d7", "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"], + "pagelines": [384, 512, [], "f18c", "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"], + "palfed": [560, 512, [], "f3d8", "M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"], + "patreon": [512, 512, [], "f3d9", "M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"], + "paypal": [384, 512, [], "f1ed", "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"], + "periscope": [448, 512, [], "f3da", "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"], + "phabricator": [496, 512, [], "f3db", "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"], + "phoenix-framework": [640, 512, [], "f3dc", "M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"], + "pied-piper": [640, 512, [], "f2ae", "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"], + "pied-piper-alt": [576, 512, [], "f1a8", "M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"], + "pied-piper-pp": [448, 512, [], "f1a7", "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"], + "pinterest": [496, 512, [], "f0d2", "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"], + "pinterest-p": [384, 512, [], "f231", "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"], + "pinterest-square": [448, 512, [], "f0d3", "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"], + "playstation": [576, 512, [], "f3df", "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"], + "product-hunt": [512, 512, [], "f288", "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"], + "pushed": [432, 512, [], "f3e1", "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"], + "python": [448, 512, [], "f3e2", "M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"], + "qq": [448, 512, [], "f1d6", "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"], + "quora": [448, 512, [], "f2c4", "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"], + "ravelry": [512, 512, [], "f2d9", "M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"], + "react": [512, 512, [], "f41b", "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"], + "rebel": [512, 512, [], "f1d0", "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"], + "red-river": [448, 512, [], "f3e3", "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"], + "reddit": [512, 512, [], "f1a1", "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"], + "reddit-alien": [512, 512, [], "f281", "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"], + "reddit-square": [448, 512, [], "f1a2", "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"], + "rendact": [496, 512, [], "f3e4", "M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"], + "renren": [512, 512, [], "f18b", "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"], + "replyd": [448, 512, [], "f3e6", "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"], + "resolving": [496, 512, [], "f3e7", "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"], + "rocketchat": [448, 512, [], "f3e8", "M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"], + "rockrms": [496, 512, [], "f3e9", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"], + "safari": [512, 512, [], "f267", "M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"], + "sass": [640, 512, [], "f41e", "M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"], + "schlix": [448, 512, [], "f3ea", "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"], + "scribd": [384, 512, [], "f28a", "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"], + "searchengin": [460, 512, [], "f3eb", "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"], + "sellcast": [448, 512, [], "f2da", "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"], + "sellsy": [640, 512, [], "f213", "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"], + "servicestack": [496, 512, [], "f3ec", "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"], + "shirtsinbulk": [448, 512, [], "f214", "M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"], + "simplybuilt": [512, 512, [], "f215", "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"], + "sistrix": [448, 512, [], "f3ee", "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"], + "skyatlas": [576, 512, [], "f216", "M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"], + "skype": [448, 512, [], "f17e", "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"], + "slack": [448, 512, [], "f198", "M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"], + "slack-hash": [448, 512, [], "f3ef", "M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"], + "slideshare": [512, 512, [], "f1e7", "M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"], + "snapchat": [496, 512, [], "f2ab", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"], + "snapchat-ghost": [512, 512, [], "f2ac", "M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"], + "snapchat-square": [448, 512, [], "f2ad", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"], + "soundcloud": [640, 512, [], "f1be", "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"], + "speakap": [448, 512, [], "f3f3", "M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"], + "spotify": [496, 512, [], "f1bc", "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"], + "stack-exchange": [448, 512, [], "f18d", "M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"], + "stack-overflow": [384, 512, [], "f16c", "M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"], + "staylinked": [440, 512, [], "f3f5", "M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"], + "steam": [496, 512, [], "f1b6", "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"], + "steam-square": [448, 512, [], "f1b7", "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"], + "steam-symbol": [448, 512, [], "f3f6", "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"], + "sticker-mule": [576, 512, [], "f3f7", "M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"], + "strava": [369, 512, [], "f428", "M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"], + "stripe": [640, 512, [], "f429", "M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"], + "stripe-s": [362, 512, [], "f42a", "M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"], + "studiovinari": [512, 512, [], "f3f8", "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"], + "stumbleupon": [512, 512, [], "f1a4", "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"], + "stumbleupon-circle": [496, 512, [], "f1a3", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"], + "superpowers": [448, 512, [], "f2dd", "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"], + "supple": [640, 512, [], "f3f9", "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"], + "telegram": [496, 512, [], "f2c6", "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"], + "telegram-plane": [448, 512, [], "f3fe", "M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"], + "tencent-weibo": [384, 512, [], "f1d5", "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"], + "themeisle": [512, 512, [], "f2b2", "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"], + "trello": [448, 512, [], "f181", "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"], + "tripadvisor": [576, 512, [], "f262", "M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"], + "tumblr": [320, 512, [], "f173", "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"], + "tumblr-square": [448, 512, [], "f174", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"], + "twitch": [448, 512, [], "f1e8", "M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"], + "twitter": [512, 512, [], "f099", "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"], + "twitter-square": [448, 512, [], "f081", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"], + "typo3": [433, 512, [], "f42b", "M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"], + "uber": [448, 512, [], "f402", "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"], + "uikit": [448, 512, [], "f403", "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"], + "uniregistry": [384, 512, [], "f404", "M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"], + "untappd": [640, 512, [], "f405", "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"], + "usb": [640, 512, [], "f287", "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"], + "ussunnah": [512, 512, [], "f407", "M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"], + "vaadin": [448, 512, [], "f408", "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"], + "viacoin": [384, 512, [], "f237", "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"], + "viadeo": [448, 512, [], "f2a9", "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"], + "viadeo-square": [448, 512, [], "f2aa", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"], + "viber": [512, 512, [], "f409", "M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"], + "vimeo": [448, 512, [], "f40a", "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"], + "vimeo-square": [448, 512, [], "f194", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"], + "vimeo-v": [448, 512, [], "f27d", "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"], + "vine": [384, 512, [], "f1ca", "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"], + "vk": [576, 512, [], "f189", "M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"], + "vnv": [640, 512, [], "f40b", "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"], + "vuejs": [448, 512, [], "f41f", "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"], + "weibo": [512, 512, [], "f18a", "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"], + "weixin": [576, 512, [], "f1d7", "M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"], + "whatsapp": [448, 512, [], "f232", "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"], + "whatsapp-square": [448, 512, [], "f40c", "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"], + "whmcs": [448, 512, [], "f40d", "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"], + "wikipedia-w": [640, 512, [], "f266", "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"], + "windows": [448, 512, [], "f17a", "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"], + "wordpress": [512, 512, [], "f19a", "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"], + "wordpress-simple": [512, 512, [], "f411", "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"], + "wpbeginner": [512, 512, [], "f297", "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"], + "wpexplorer": [512, 512, [], "f2de", "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"], + "wpforms": [448, 512, [], "f298", "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"], + "xbox": [512, 512, [], "f412", "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"], + "xing": [384, 512, [], "f168", "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"], + "xing-square": [448, 512, [], "f169", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"], + "y-combinator": [448, 512, [], "f23b", "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"], + "yahoo": [360, 512, [], "f19e", "M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"], + "yandex": [256, 512, [], "f413", "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"], + "yandex-international": [320, 512, [], "f414", "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"], + "yelp": [384, 512, [], "f1e9", "M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"], + "yoast": [448, 512, [], "f2b1", "M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"], + "youtube": [576, 512, [], "f167", "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"] +}; + +var w = WINDOW || {}; + +if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; +if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; +if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; +if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + +var namespace = w[NAMESPACE_IDENTIFIER]; + +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]; + } + } + } + + return target; +}; + +function define(prefix) { + if (typeof namespace.hooks.addPack === 'function') { + namespace.hooks.addPack(prefix, icons$1); + } else { + namespace.styles[prefix] = _extends({}, namespace.styles[prefix] || {}, icons$1); + } +} + +bunker(function () { + define('fab'); +}); + +}()); diff --git a/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.min.js b/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.min.js new file mode 100644 index 000000000..5cce12ae2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/js/fa-brands.min.js @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +!function(){"use strict";function c(c){"function"==typeof V.hooks.addPack?V.hooks.addPack(c,s):V.styles[c]=f({},V.styles[c]||{},s)}var z={};try{"undefined"!=typeof window&&(z=window)}catch(c){}var l=(z.navigator||{}).userAgent,h=void 0===l?"":l,v=z,m=(~h.indexOf("MSIE")||h.indexOf("Trident/"),[1,2,3,4,5,6,7,8,9,10]),M=m.concat([11,12,13,14,15,16,17,18,19,20]),s=(["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(m.map(function(c){return c+"x"})).concat(M.map(function(c){return"w-"+c})),{"500px":[448,512,[],"f26e","M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"],"accessible-icon":[448,512,[],"f368","M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"],accusoft:[640,512,[],"f369","M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"],adn:[496,512,[],"f170","M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"],adversal:[512,512,[],"f36a","M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"],affiliatetheme:[512,512,[],"f36b","M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"],algolia:[448,512,[],"f36c","M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"],amazon:[448,512,[],"f270","M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"],amilia:[448,512,[],"f36d","M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"],android:[448,512,[],"f17b","M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"],angellist:[448,512,[],"f209","M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"],angrycreative:[640,512,[],"f36e","M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"],angular:[415,512,[],"f420","M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"],"app-store":[512,512,[],"f36f","M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"],"app-store-ios":[448,512,[],"f370","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"],apper:[640,512,[],"f371","M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"],apple:[448,512,[],"f179","M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"],"apple-pay":[640,512,[],"f415","M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"],asymmetrik:[576,512,[],"f372","M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"],audible:[640,512,[],"f373","M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"],autoprefixer:[640,512,[],"f41c","M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"],avianex:[512,512,[],"f374","M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"],aviato:[640,512,[],"f421","M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"],aws:[512,512,[],"f375","M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"],bandcamp:[496,512,[],"f2d5","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"],behance:[576,512,[],"f1b4","M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"],"behance-square":[512,512,[],"f1b5","M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"],bimobject:[448,512,[],"f378","M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"],bitbucket:[512,512,[],"f171","M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"],bitcoin:[512,512,[],"f379","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"],bity:[496,512,[],"f37a","M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"],"black-tie":[448,512,[],"f27e","M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"],blackberry:[512,512,[],"f37b","M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"],blogger:[448,512,[],"f37c","M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"],"blogger-b":[448,512,[],"f37d","M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"],bluetooth:[448,512,[],"f293","M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"],"bluetooth-b":[320,512,[],"f294","M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"],btc:[384,512,[],"f15a","M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"],buromobelexperte:[448,512,[],"f37f","M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"],buysellads:[448,512,[],"f20d","M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"],"cc-amex":[576,512,[],"f1f3","M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"],"cc-apple-pay":[576,512,[],"f416","M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"],"cc-diners-club":[576,512,[],"f24c","M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"],"cc-discover":[576,512,[],"f1f2","M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"],"cc-jcb":[576,512,[],"f24b","M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"],"cc-mastercard":[576,512,[],"f1f1","M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"],"cc-paypal":[576,512,[],"f1f4","M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"],"cc-stripe":[576,512,[],"f1f5","M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"],"cc-visa":[576,512,[],"f1f0","M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"],centercode:[512,512,[],"f380","M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"],chrome:[496,512,[],"f268","M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"],cloudscale:[448,512,[],"f383","M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"],cloudsmith:[332,512,[],"f384","M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"],cloudversify:[616,512,[],"f385","M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"],codepen:[512,512,[],"f1cb","M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"],codiepie:[472,512,[],"f284","M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"],connectdevelop:[576,512,[],"f20e","M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"],contao:[512,512,[],"f26d","M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"],cpanel:[640,512,[],"f388","M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"],"creative-commons":[512,512,[],"f25e","M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"],css3:[512,512,[],"f13c","M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"],"css3-alt":[384,512,[],"f38b","M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"],cuttlefish:[440,512,[],"f38c","M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"],"d-and-d":[576,512,[],"f38d","M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"],dashcube:[384,512,[],"f210","M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"],delicious:[448,512,[],"f1a5","M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"],deploydog:[512,512,[],"f38e","M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"],deskpro:[480,512,[],"f38f","M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"],deviantart:[320,512,[],"f1bd","M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"],digg:[512,512,[],"f1a6","M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"],"digital-ocean":[512,512,[],"f391","M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"],discord:[448,512,[],"f392","M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"],discourse:[448,512,[],"f393","M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"],dochub:[416,512,[],"f394","M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"],docker:[640,512,[],"f395","M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"],draft2digital:[480,512,[],"f396","M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"],dribbble:[512,512,[],"f17d","M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"],"dribbble-square":[448,512,[],"f397","M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"],dropbox:[528,512,[],"f16b","M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"],drupal:[448,512,[],"f1a9","M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"],dyalog:[416,512,[],"f399","M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"],earlybirds:[480,512,[],"f39a","M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"],edge:[512,512,[],"f282","M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"],ember:[640,512,[],"f423","M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"],empire:[496,512,[],"f1d1","M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"],envira:[448,512,[],"f299","M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"],erlang:[640,512,[],"f39d","M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"],etsy:[384,512,[],"f2d7","M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"],expeditedssl:[496,512,[],"f23e","M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"],facebook:[448,512,[],"f09a","M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"],"facebook-f":[264,512,[],"f39e","M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"],"facebook-messenger":[448,512,[],"f39f","M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"],"facebook-square":[448,512,[],"f082","M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],firefox:[480,512,[],"f269","M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"],"first-order":[448,512,[],"f2b0","M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"],firstdraft:[384,512,[],"f3a1","M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"],flickr:[448,512,[],"f16e","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"],fly:[384,512,[],"f417","M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"],"font-awesome":[448,512,[],"f2b4","M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"],"font-awesome-alt":[448,512,[],"f35c","M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"],"font-awesome-flag":[448,512,[],"f425","M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"],fonticons:[448,512,[],"f280","M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"],"fonticons-fi":[384,512,[],"f3a2","M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"],"fort-awesome":[448,512,[],"f286","M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"],"fort-awesome-alt":[512,512,[],"f3a3","M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"],forumbee:[448,512,[],"f211","M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"],foursquare:[368,512,[],"f180","M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"],"free-code-camp":[576,512,[],"f2c5","M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"],freebsd:[448,512,[],"f3a4","M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"],"get-pocket":[448,512,[],"f265","M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"],gg:[512,512,[],"f260","M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"],"gg-circle":[512,512,[],"f261","M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"],git:[448,512,[],"f1d3","M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"],"git-square":[448,512,[],"f1d2","M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"],github:[496,512,[],"f09b","M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"],"github-alt":[480,512,[],"f113","M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"],"github-square":[448,512,[],"f092","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"],gitkraken:[592,512,[],"f3a6","M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"],gitlab:[512,512,[],"f296","M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"],gitter:[384,512,[],"f426","M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"],glide:[448,512,[],"f2a5","M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"],"glide-g":[448,512,[],"f2a6","M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"],gofore:[400,512,[],"f3a7","M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"],goodreads:[448,512,[],"f3a8","M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"],"goodreads-g":[384,512,[],"f3a9","M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"],google:[488,512,[],"f1a0","M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"],"google-drive":[512,512,[],"f3aa","M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"],"google-play":[512,512,[],"f3ab","M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"],"google-plus":[496,512,[],"f2b3","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"],"google-plus-g":[640,512,[],"f0d5","M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"],"google-plus-square":[448,512,[],"f0d4","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"],"google-wallet":[448,512,[],"f1ee","M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"],gratipay:[496,512,[],"f184","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"],grav:[512,512,[],"f2d6","M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"],gripfire:[384,512,[],"f3ac","M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"],grunt:[384,512,[],"f3ad","M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"],gulp:[256,512,[],"f3ae","M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"],"hacker-news":[448,512,[],"f1d4","M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],"hacker-news-square":[448,512,[],"f3af","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],"hire-a-helper":[512,512,[],"f3b0","M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"],hooli:[640,512,[],"f427","M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"],hotjar:[448,512,[],"f3b1","M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"],houzz:[320,512,[],"f27c","M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"],html5:[384,512,[],"f13b","M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"],hubspot:[512,512,[],"f3b2","M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"],imdb:[448,512,[],"f2d8","M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"],instagram:[448,512,[],"f16d","M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"],"internet-explorer":[512,512,[],"f26b","M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"],ioxhost:[640,512,[],"f208","M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"],itunes:[448,512,[],"f3b4","M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"],"itunes-note":[384,512,[],"f3b5","M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"],jenkins:[512,512,[],"f3b6","M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"],joget:[496,512,[],"f3b7","M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"],joomla:[448,512,[],"f1aa","M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"],js:[448,512,[],"f3b8","M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],"js-square":[512,512,[],"f3b9","M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],jsfiddle:[576,512,[],"f1cc","M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"],keycdn:[512,512,[],"f3ba","M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"],kickstarter:[448,512,[],"f3bb","M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"],"kickstarter-k":[384,512,[],"f3bc","M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"],laravel:[640,512,[],"f3bd","M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"],lastfm:[512,512,[],"f202","M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"],"lastfm-square":[448,512,[],"f203","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"],leanpub:[576,512,[],"f212","M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"],less:[640,512,[],"f41d","M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"],line:[448,512,[],"f3c0","M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"],linkedin:[448,512,[],"f08c","M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"],"linkedin-in":[448,512,[],"f0e1","M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"],linode:[448,512,[],"f2b8","M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"],linux:[448,512,[],"f17c","M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"],lyft:[512,512,[],"f3c3","M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"],magento:[448,512,[],"f3c4","M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"],maxcdn:[512,512,[],"f136","M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"],medapps:[320,512,[],"f3c6","M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"],medium:[448,512,[],"f23a","M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"],"medium-m":[512,512,[],"f3c7","M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"],medrt:[544,512,[],"f3c8","M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"],meetup:[512,512,[],"f2e0","M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"],microsoft:[448,512,[],"f3ca","M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"],mix:[416,512,[],"f3cb","M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"],mixcloud:[640,512,[],"f289","M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"],mizuni:[496,512,[],"f3cc","M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"],modx:[448,512,[],"f285","M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"],monero:[496,512,[],"f3d0","M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"],napster:[496,512,[],"f3d2","M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"],"nintendo-switch":[448,512,[],"f418","M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"],node:[640,512,[],"f419","M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"],"node-js":[448,512,[],"f3d3","M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"],npm:[576,512,[],"f3d4","M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"],ns8:[640,512,[],"f3d5","M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"],nutritionix:[400,512,[],"f3d6","M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"],odnoklassniki:[320,512,[],"f263","M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"],"odnoklassniki-square":[448,512,[],"f264","M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"],opencart:[640,512,[],"f23d","M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"],openid:[448,512,[],"f19b","M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"],opera:[496,512,[],"f26a","M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"],"optin-monster":[576,512,[],"f23c","M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"],osi:[495,512,[],"f41a","M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"],page4:[496,512,[],"f3d7","M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"],pagelines:[384,512,[],"f18c","M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"],palfed:[560,512,[],"f3d8","M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"],patreon:[512,512,[],"f3d9","M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"],paypal:[384,512,[],"f1ed","M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"],periscope:[448,512,[],"f3da","M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"],phabricator:[496,512,[],"f3db","M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"],"phoenix-framework":[640,512,[],"f3dc","M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"],"pied-piper":[640,512,[],"f2ae","M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"],"pied-piper-alt":[576,512,[],"f1a8","M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"],"pied-piper-pp":[448,512,[],"f1a7","M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"],pinterest:[496,512,[],"f0d2","M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"],"pinterest-p":[384,512,[],"f231","M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"],"pinterest-square":[448,512,[],"f0d3","M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],playstation:[576,512,[],"f3df","M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"],"product-hunt":[512,512,[],"f288","M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"],pushed:[432,512,[],"f3e1","M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"],python:[448,512,[],"f3e2","M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"],qq:[448,512,[],"f1d6","M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"],quora:[448,512,[],"f2c4","M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"],ravelry:[512,512,[],"f2d9","M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"],react:[512,512,[],"f41b","M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"],rebel:[512,512,[],"f1d0","M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"],"red-river":[448,512,[],"f3e3","M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"],reddit:[512,512,[],"f1a1","M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"],"reddit-alien":[512,512,[],"f281","M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"],"reddit-square":[448,512,[],"f1a2","M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"],rendact:[496,512,[],"f3e4","M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"],renren:[512,512,[],"f18b","M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"],replyd:[448,512,[],"f3e6","M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"],resolving:[496,512,[],"f3e7","M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"],rocketchat:[448,512,[],"f3e8","M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"],rockrms:[496,512,[],"f3e9","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"],safari:[512,512,[],"f267","M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"],sass:[640,512,[],"f41e","M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"],schlix:[448,512,[],"f3ea","M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"],scribd:[384,512,[],"f28a","M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"],searchengin:[460,512,[],"f3eb","M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"],sellcast:[448,512,[],"f2da","M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"],sellsy:[640,512,[],"f213","M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"],servicestack:[496,512,[],"f3ec","M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"],shirtsinbulk:[448,512,[],"f214","M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"],simplybuilt:[512,512,[],"f215","M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"],sistrix:[448,512,[],"f3ee","M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"],skyatlas:[576,512,[],"f216","M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"],skype:[448,512,[],"f17e","M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"],slack:[448,512,[],"f198","M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"],"slack-hash":[448,512,[],"f3ef","M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"],slideshare:[512,512,[],"f1e7","M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"],snapchat:[496,512,[],"f2ab","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],"snapchat-ghost":[512,512,[],"f2ac","M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"],"snapchat-square":[448,512,[],"f2ad","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],soundcloud:[640,512,[],"f1be","M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"],speakap:[448,512,[],"f3f3","M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"],spotify:[496,512,[],"f1bc","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"],"stack-exchange":[448,512,[],"f18d","M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"],"stack-overflow":[384,512,[],"f16c","M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"],staylinked:[440,512,[],"f3f5","M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"],steam:[496,512,[],"f1b6","M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"],"steam-square":[448,512,[],"f1b7","M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"],"steam-symbol":[448,512,[],"f3f6","M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"],"sticker-mule":[576,512,[],"f3f7","M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"],strava:[369,512,[],"f428","M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"],stripe:[640,512,[],"f429","M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"],"stripe-s":[362,512,[],"f42a","M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"],studiovinari:[512,512,[],"f3f8","M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"],stumbleupon:[512,512,[],"f1a4","M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"],"stumbleupon-circle":[496,512,[],"f1a3","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"],superpowers:[448,512,[],"f2dd","M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"],supple:[640,512,[],"f3f9","M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"],telegram:[496,512,[],"f2c6","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"],"telegram-plane":[448,512,[],"f3fe","M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"],"tencent-weibo":[384,512,[],"f1d5","M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"],themeisle:[512,512,[],"f2b2","M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"],trello:[448,512,[],"f181","M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"],tripadvisor:[576,512,[],"f262","M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"],tumblr:[320,512,[],"f173","M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"],"tumblr-square":[448,512,[],"f174","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"],twitch:[448,512,[],"f1e8","M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"],twitter:[512,512,[],"f099","M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"],"twitter-square":[448,512,[],"f081","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"],typo3:[433,512,[],"f42b","M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"],uber:[448,512,[],"f402","M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"],uikit:[448,512,[],"f403","M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"],uniregistry:[384,512,[],"f404","M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"],untappd:[640,512,[],"f405","M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"],usb:[640,512,[],"f287","M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"],ussunnah:[512,512,[],"f407","M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"],vaadin:[448,512,[],"f408","M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"],viacoin:[384,512,[],"f237","M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"],viadeo:[448,512,[],"f2a9","M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"],"viadeo-square":[448,512,[],"f2aa","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"],viber:[512,512,[],"f409","M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"],vimeo:[448,512,[],"f40a","M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"],"vimeo-square":[448,512,[],"f194","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"],"vimeo-v":[448,512,[],"f27d","M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"],vine:[384,512,[],"f1ca","M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"],vk:[576,512,[],"f189","M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"],vnv:[640,512,[],"f40b","M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"],vuejs:[448,512,[],"f41f","M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"],weibo:[512,512,[],"f18a","M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"],weixin:[576,512,[],"f1d7","M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"],whatsapp:[448,512,[],"f232","M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"],"whatsapp-square":[448,512,[],"f40c","M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"],whmcs:[448,512,[],"f40d","M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"],"wikipedia-w":[640,512,[],"f266","M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"],windows:[448,512,[],"f17a","M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"],wordpress:[512,512,[],"f19a","M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"],"wordpress-simple":[512,512,[],"f411","M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"],wpbeginner:[512,512,[],"f297","M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"],wpexplorer:[512,512,[],"f2de","M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"],wpforms:[448,512,[],"f298","M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"],xbox:[512,512,[],"f412","M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"],xing:[384,512,[],"f168","M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"],"xing-square":[448,512,[],"f169","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"],"y-combinator":[448,512,[],"f23b","M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"],yahoo:[360,512,[],"f19e","M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"],yandex:[256,512,[],"f413","M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"],"yandex-international":[320,512,[],"f414","M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"],yelp:[384,512,[],"f1e9","M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"],yoast:[448,512,[],"f2b1","M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"],youtube:[576,512,[],"f167","M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"]}),H=v||{};H.___FONT_AWESOME___||(H.___FONT_AWESOME___={}),H.___FONT_AWESOME___.styles||(H.___FONT_AWESOME___.styles={}),H.___FONT_AWESOME___.hooks||(H.___FONT_AWESOME___.hooks={}),H.___FONT_AWESOME___.shims||(H.___FONT_AWESOME___.shims=[]);var V=H.___FONT_AWESOME___,f=Object.assign||function(c){for(var z=1;z= 0) continue; + if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; + target[i] = obj[i]; + } + + return target; +}; + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +var _default = _extends({ + familyPrefix: DEFAULT_FAMILY_PREFIX, + replacementClass: DEFAULT_REPLACEMENT_CLASS, + autoReplaceSvg: true, + autoAddCss: true, + autoA11y: true, + searchPseudoElements: false, + observeMutations: true, + keepOriginalSource: true, + measurePerformance: false, + showMissingIcons: true +}, WINDOW.FontAwesomeConfig || {}); + +if (!_default.autoReplaceSvg) _default.observeMutations = false; + +var config = _extends({}, _default); + +WINDOW.FontAwesomeConfig = config; + +function update(newConfig) { + var validKeys = Object.keys(config); + + Object.keys(newConfig).forEach(function (configKey) { + if (~validKeys.indexOf(configKey)) { + config[configKey] = newConfig[configKey]; + } + }); +} + +var d = UNITS_IN_GRID; + +var meaninglessTransform = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: false, + flipY: false +}; + +function isReserved(name) { + return ~RESERVED_CLASSES.indexOf(name); +} + +function bunker(fn) { + try { + fn(); + } catch (e) { + + } +} + +function insertCss(css) { + if (!css) { + return; + } + + if (typeof DOCUMENT.createElement === 'undefined') { + return; + } + + var style = DOCUMENT.createElement('style'); + style.setAttribute('type', 'text/css'); + style.innerHTML = css; + + var headChildren = DOCUMENT.head.childNodes; + var beforeChild = null; + + for (var i = headChildren.length - 1; i > -1; i--) { + var child = headChildren[i]; + var tagName = (child.tagName || '').toUpperCase(); + if (['STYLE', 'LINK'].indexOf(tagName) > -1) { + beforeChild = child; + } + } + + DOCUMENT.head.insertBefore(style, beforeChild); + + return css; +} + +var _uniqueId = 0; + +function nextUniqueId() { + _uniqueId++; + + return _uniqueId; +} + +function toArray(obj) { + var array = []; + + for (var i = (obj || []).length >>> 0; i--;) { + array[i] = obj[i]; + } + + return array; +} + +function classArray(node) { + if (node.classList) { + return toArray(node.classList); + } else { + return (node.getAttribute('class') || '').split(' ').filter(function (i) { + return i; + }); + } +} + +function getIconName(familyPrefix, cls) { + var parts = cls.split('-'); + var prefix = parts[0]; + var iconName = parts.slice(1).join('-'); + + if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) { + return iconName; + } else { + return null; + } +} + +function htmlEscape(str) { + return ('' + str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); +} + +function joinAttributes(attributes) { + return Object.keys(attributes || {}).reduce(function (acc, attributeName) { + return acc + (attributeName + '="' + htmlEscape(attributes[attributeName]) + '" '); + }, '').trim(); +} + +function joinStyles(styles) { + return Object.keys(styles || {}).reduce(function (acc, styleName) { + return acc + (styleName + ': ' + styles[styleName] + ';'); + }, ''); +} + +function transformIsMeaningful(transform) { + return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; +} + +function transformForSvg(_ref) { + var transform = _ref.transform, + containerWidth = _ref.containerWidth, + iconWidth = _ref.iconWidth; + + var outer = { + transform: 'translate(' + containerWidth / 2 + ' 256)' + }; + var innerTranslate = 'translate(' + transform.x * 32 + ', ' + transform.y * 32 + ') '; + var innerScale = 'scale(' + transform.size / 16 * (transform.flipX ? -1 : 1) + ', ' + transform.size / 16 * (transform.flipY ? -1 : 1) + ') '; + var innerRotate = 'rotate(' + transform.rotate + ' 0 0)'; + var inner = { + transform: innerTranslate + ' ' + innerScale + ' ' + innerRotate + }; + var path = { + transform: 'translate(' + iconWidth / 2 * -1 + ' -256)' + }; + return { + outer: outer, + inner: inner, + path: path + }; +} + +function transformForCss(_ref2) { + var transform = _ref2.transform, + _ref2$width = _ref2.width, + width = _ref2$width === undefined ? UNITS_IN_GRID : _ref2$width, + _ref2$height = _ref2.height, + height = _ref2$height === undefined ? UNITS_IN_GRID : _ref2$height, + _ref2$startCentered = _ref2.startCentered, + startCentered = _ref2$startCentered === undefined ? false : _ref2$startCentered; + + var val = ''; + + if (startCentered && IS_IE) { + val += 'translate(' + (transform.x / d - width / 2) + 'em, ' + (transform.y / d - height / 2) + 'em) '; + } else if (startCentered) { + val += 'translate(calc(-50% + ' + transform.x / d + 'em), calc(-50% + ' + transform.y / d + 'em)) '; + } else { + val += 'translate(' + transform.x / d + 'em, ' + transform.y / d + 'em) '; + } + + val += 'scale(' + transform.size / d * (transform.flipX ? -1 : 1) + ', ' + transform.size / d * (transform.flipY ? -1 : 1) + ') '; + val += 'rotate(' + transform.rotate + 'deg) '; + + return val; +} + +var ALL_SPACE = { + x: 0, + y: 0, + width: '100%', + height: '100%' +}; + +var makeIconMasking = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + mask = _ref.mask, + transform = _ref.transform; + var mainWidth = main.width, + mainPath = main.icon; + var maskWidth = mask.width, + maskPath = mask.icon; + + + var trans = transformForSvg({ transform: transform, containerWidth: maskWidth, iconWidth: mainWidth }); + + var maskRect = { + tag: 'rect', + attributes: _extends({}, ALL_SPACE, { + fill: 'white' + }) + }; + var maskInnerGroup = { + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ tag: 'path', attributes: _extends({}, mainPath.attributes, trans.path, { fill: 'black' }) }] + }; + var maskOuterGroup = { + tag: 'g', + attributes: _extends({}, trans.outer), + children: [maskInnerGroup] + }; + var maskId = 'mask-' + nextUniqueId(); + var clipId = 'clip-' + nextUniqueId(); + var maskTag = { + tag: 'mask', + attributes: _extends({}, ALL_SPACE, { + id: maskId, + maskUnits: 'userSpaceOnUse', + maskContentUnits: 'userSpaceOnUse' + }), + children: [maskRect, maskOuterGroup] + }; + var defs = { + tag: 'defs', + children: [{ tag: 'clipPath', attributes: { id: clipId }, children: [maskPath] }, maskTag] + }; + + children.push(defs, { tag: 'rect', attributes: _extends({ fill: 'currentColor', 'clip-path': 'url(#' + clipId + ')', mask: 'url(#' + maskId + ')' }, ALL_SPACE) }); + + return { + children: children, + attributes: attributes + }; +}; + +var makeIconStandard = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + transform = _ref.transform, + styles = _ref.styles; + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + if (transformIsMeaningful(transform)) { + var trans = transformForSvg({ transform: transform, containerWidth: main.width, iconWidth: main.width }); + children.push({ + tag: 'g', + attributes: _extends({}, trans.outer), + children: [{ + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ + tag: main.icon.tag, + children: main.icon.children, + attributes: _extends({}, main.icon.attributes, trans.path) + }] + }] + }); + } else { + children.push(main.icon); + } + + return { + children: children, + attributes: attributes + }; +}; + +var asIcon = function (_ref) { + var children = _ref.children, + main = _ref.main, + mask = _ref.mask, + attributes = _ref.attributes, + styles = _ref.styles, + transform = _ref.transform; + + if (transformIsMeaningful(transform) && main.found && !mask.found) { + var width = main.width, + height = main.height; + + var offset = { + x: width / height / 2, + y: 0.5 + }; + attributes['style'] = joinStyles(_extends({}, styles, { + 'transform-origin': offset.x + transform.x / 16 + 'em ' + (offset.y + transform.y / 16) + 'em' + })); + } + + return [{ + tag: 'svg', + attributes: attributes, + children: children + }]; +}; + +var asSymbol = function (_ref) { + var prefix = _ref.prefix, + iconName = _ref.iconName, + children = _ref.children, + attributes = _ref.attributes, + symbol = _ref.symbol; + + var id = symbol === true ? prefix + '-' + config.familyPrefix + '-' + iconName : symbol; + + return [{ + tag: 'svg', + attributes: { + style: 'display: none;' + }, + children: [{ + tag: 'symbol', + attributes: _extends({}, attributes, { id: id }), + children: children + }] + }]; +}; + +function makeInlineSvgAbstract(params) { + var _babelHelpers$extends; + + var _params$icons = params.icons, + main = _params$icons.main, + mask = _params$icons.mask, + prefix = params.prefix, + iconName = params.iconName, + transform = params.transform, + symbol = params.symbol, + title = params.title, + extra = params.extra; + + var _ref = mask.found ? mask : main, + width = _ref.width, + height = _ref.height; + + var widthClass = 'fa-w-' + Math.ceil(width / height * 16); + var attrClass = [config.replacementClass, iconName ? config.familyPrefix + '-' + iconName : '', widthClass].concat(extra.classes).join(' '); + + var content = { + children: [], + attributes: _extends({}, extra.attributes, (_babelHelpers$extends = {}, defineProperty(_babelHelpers$extends, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends, 'data-prefix', prefix), defineProperty(_babelHelpers$extends, 'data-icon', iconName), defineProperty(_babelHelpers$extends, 'class', attrClass), defineProperty(_babelHelpers$extends, 'role', 'img'), defineProperty(_babelHelpers$extends, 'xmlns', 'http://www.w3.org/2000/svg'), defineProperty(_babelHelpers$extends, 'viewBox', '0 0 ' + width + ' ' + height), _babelHelpers$extends)) + }; + + if (title) content.children.push({ tag: 'title', attributes: { id: content.attributes['aria-labelledby'] || 'title-' + nextUniqueId() }, children: [title] }); + + var args = _extends({}, content, { + prefix: prefix, + iconName: iconName, + main: main, + mask: mask, + transform: transform, + symbol: symbol, + styles: extra.styles + }); + + var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), + children = _ref2.children, + attributes = _ref2.attributes; + + args.children = children; + args.attributes = attributes; + + if (symbol) { + return asSymbol(args); + } else { + return asIcon(args); + } +} + +function makeLayersTextAbstract(params) { + var _babelHelpers$extends2; + + var content = params.content, + width = params.width, + height = params.height, + transform = params.transform, + title = params.title, + extra = params.extra; + + + var attributes = _extends({}, extra.attributes, title ? { 'title': title } : {}, (_babelHelpers$extends2 = {}, defineProperty(_babelHelpers$extends2, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends2, 'class', extra.classes.join(' ')), _babelHelpers$extends2)); + + var styles = _extends({}, extra.styles); + + if (transformIsMeaningful(transform)) { + styles['transform'] = transformForCss({ transform: transform, startCentered: true, width: width, height: height }); + styles['-webkit-transform'] = styles['transform']; + } + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ tag: 'span', attributes: { class: 'sr-only' }, children: [title] }); + } + + return val; +} + +var w = WINDOW || {}; + +if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; +if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; +if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; +if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + +var namespace = w[NAMESPACE_IDENTIFIER]; + +var noop$2 = function noop() {}; +var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { mark: noop$2, measure: noop$2 }; +var preamble = 'FA "5.0.1"'; + +var begin = function begin(name) { + p.mark(preamble + ' ' + name + ' begins'); + return function () { + return end(name); + }; +}; + +var end = function end(name) { + p.mark(preamble + ' ' + name + ' ends'); + p.measure(preamble + ' ' + name, preamble + ' ' + name + ' begins', preamble + ' ' + name + ' ends'); +}; + +var perf = { begin: begin, end: end }; + +'use strict'; + +/** + * Internal helper to bind a function known to have 4 arguments + * to a given context. + */ +var bindInternal4 = function bindInternal4 (func, thisContext) { + return function (a, b, c, d) { + return func.call(thisContext, a, b, c, d); + }; +}; + +'use strict'; + + + +/** + * # Reduce + * + * A fast object `.reduce()` implementation. + * + * @param {Object} subject The object to reduce over. + * @param {Function} fn The reducer function. + * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0]. + * @param {Object} thisContext The context for the reducer. + * @return {mixed} The final result. + */ +var reduce = function fastReduceObject (subject, fn, initialValue, thisContext) { + var keys = Object.keys(subject), + length = keys.length, + iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn, + i, key, result; + + if (initialValue === undefined) { + i = 1; + result = subject[keys[0]]; + } + else { + i = 0; + result = initialValue; + } + + for (; i < length; i++) { + key = keys[i]; + result = iterator(result, subject[key], key, subject); + } + + return result; +}; + +var styles$2 = namespace.styles; +var shims = namespace.shims; + + +var _byUnicode = {}; +var _byLigature = {}; +var _byOldName = {}; + +var build = function build() { + var lookup = function lookup(reducer) { + return reduce(styles$2, function (o, style, prefix) { + o[prefix] = reduce(style, reducer, {}); + return o; + }, {}); + }; + + _byUnicode = lookup(function (acc, icon, iconName) { + acc[icon[3]] = iconName; + + return acc; + }); + + _byLigature = lookup(function (acc, icon, iconName) { + var ligatures = icon[2]; + + acc[iconName] = iconName; + + ligatures.forEach(function (ligature) { + acc[ligature] = iconName; + }); + + return acc; + }); + + var hasRegular = 'far' in styles$2; + + _byOldName = reduce(shims, function (acc, shim) { + var oldName = shim[0]; + var prefix = shim[1]; + var iconName = shim[2]; + + if (prefix === 'far' && !hasRegular) { + prefix = 'fas'; + } + + acc[oldName] = { prefix: prefix, iconName: iconName }; + + return acc; + }, {}); +}; + +build(); + +function byUnicode(prefix, unicode) { + return _byUnicode[prefix][unicode]; +} + +function byLigature(prefix, ligature) { + return _byLigature[prefix][ligature]; +} + +function byOldName(name) { + return _byOldName[name] || { prefix: null, iconName: null }; +} + +var styles$1 = namespace.styles; + + +var emptyCanonicalIcon = function emptyCanonicalIcon() { + return { prefix: null, iconName: null, rest: [] }; +}; + +function getCanonicalIcon(values) { + return values.reduce(function (acc, cls) { + var iconName = getIconName(config.familyPrefix, cls); + + if (styles$1[cls]) { + acc.prefix = cls; + } else if (iconName) { + var shim = acc.prefix === 'fa' ? byOldName(iconName) : {}; + + acc.iconName = shim.iconName || iconName; + acc.prefix = shim.prefix || acc.prefix; + } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) { + acc.rest.push(cls); + } + + return acc; + }, emptyCanonicalIcon()); +} + +function iconFromMapping(mapping, prefix, iconName) { + if (mapping && mapping[prefix] && mapping[prefix][iconName]) { + return { + prefix: prefix, + iconName: iconName, + icon: mapping[prefix][iconName] + }; + } +} + +function toHtml(abstractNodes) { + var tag = abstractNodes.tag, + _abstractNodes$attrib = abstractNodes.attributes, + attributes = _abstractNodes$attrib === undefined ? {} : _abstractNodes$attrib, + _abstractNodes$childr = abstractNodes.children, + children = _abstractNodes$childr === undefined ? [] : _abstractNodes$childr; + + + if (typeof abstractNodes === 'string') { + return htmlEscape(abstractNodes); + } else { + return '<' + tag + ' ' + joinAttributes(attributes) + '>' + children.map(toHtml).join('') + ''; + } +} + +var noop$1 = function noop() {}; + +function isReplaced(node) { + var nodeClass = node.getAttribute ? node.getAttribute('class') : null; + + if (nodeClass) { + return !!~nodeClass.toString().indexOf(config.replacementClass) || ~nodeClass.toString().indexOf('fa-layers-text'); + } else { + return false; + } +} + +function getMutator() { + if (config.autoReplaceSvg === true) { + return mutators.replace; + } + + var mutator = mutators[config.autoReplaceSvg]; + + return mutator || mutators.replace; +} + +var mutators = { + replace: function replace(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + var newOuterHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + + if (node.parentNode && node.outerHTML) { + node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? '' : ''); + } else if (node.parentNode) { + var newNode = document.createElement('span'); + node.parentNode.replaceChild(newNode, node); + newNode.outerHTML = newOuterHTML; + } + }, + nest: function nest(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + + // If we already have a replaced node we do not want to continue nesting within it. + // Short-circuit to the standard replacement + if (~classArray(node).indexOf(config.replacementClass)) { + return mutators.replace(mutation); + } + + var forSvg = new RegExp(config.familyPrefix + '-.*'); + + delete abstract[0].attributes.style; + + var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) { + if (cls === config.replacementClass || cls.match(forSvg)) { + acc.toSvg.push(cls); + } else { + acc.toNode.push(cls); + } + + return acc; + }, { toNode: [], toSvg: [] }); + + abstract[0].attributes.class = splitClasses.toSvg.join(' '); + + var newInnerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.setAttribute('class', splitClasses.toNode.join(' ')); + node.setAttribute(DATA_FA_PROCESSED, ''); + node.innerHTML = newInnerHTML; + } +}; + +function perform(mutations, callback) { + var callbackFunction = typeof callback === 'function' ? callback : noop$1; + + if (mutations.length === 0) { + callbackFunction(); + } else { + var frame = WINDOW.requestAnimationFrame || function (op) { + return op(); + }; + + frame(function () { + var mutator = getMutator(); + var mark = perf.begin('mutate'); + + mutations.map(mutator); + + mark(); + + callbackFunction(); + }); + } +} + +var disabled = false; + +function disableObservation(operation) { + disabled = true; + operation(); + disabled = false; +} + +function observe(options) { + if (!MUTATION_OBSERVER) return; + + var treeCallback = options.treeCallback, + nodeCallback = options.nodeCallback, + pseudoElementsCallback = options.pseudoElementsCallback; + + var mo = new MUTATION_OBSERVER(function (objects) { + if (disabled) return; + + toArray(objects).forEach(function (mutationRecord) { + if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isReplaced(mutationRecord.addedNodes[0])) { + if (config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target); + } + + treeCallback(mutationRecord.target); + } + + if (mutationRecord.type === 'attributes' && mutationRecord.attributeName === 'class' && mutationRecord.target.parentNode && config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target.parentNode); + } + + if (mutationRecord.type === 'attributes' && isReplaced(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) { + if (mutationRecord.attributeName === 'class') { + var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)), + prefix = _getCanonicalIcon.prefix, + iconName = _getCanonicalIcon.iconName; + + if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix); + if (iconName) mutationRecord.target.setAttribute('data-icon', iconName); + } else { + nodeCallback(mutationRecord.target); + } + } + }); + }); + + if (!DOCUMENT.getElementsByTagName) return; + + mo.observe(DOCUMENT.getElementsByTagName('body')[0], { + childList: true, attributes: true, characterData: true, subtree: true + }); +} + +var styleParser = function (node) { + var style = node.getAttribute('style'); + + var val = []; + + if (style) { + val = style.split(';').reduce(function (acc, style) { + var styles = style.split(':'); + var prop = styles[0]; + var value = styles.slice(1); + + if (prop && value.length > 0) { + acc[prop] = value.join(':').trim(); + } + + return acc; + }, {}); + } + + return val; +}; + +function toHex(unicode) { + var result = ''; + + for (var i = 0; i < unicode.length; i++) { + var hex = unicode.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + + return result; +} + +var classParser = function (node) { + var existingPrefix = node.getAttribute('data-prefix'); + var existingIconName = node.getAttribute('data-icon'); + var innerText = node.innerText !== undefined ? node.innerText.trim() : ''; + + var val = getCanonicalIcon(classArray(node)); + + if (existingPrefix && existingIconName) { + val.prefix = existingPrefix; + val.iconName = existingIconName; + } + + if (val.prefix && innerText.length > 1) { + val.iconName = byLigature(val.prefix, node.innerText); + } else if (val.prefix && innerText.length === 1) { + val.iconName = byUnicode(val.prefix, toHex(node.innerText)); + } + + return val; +}; + +var parseTransformString = function parseTransformString(transformString) { + var transform = { + size: 16, + x: 0, + y: 0, + flipX: false, + flipY: false, + rotate: 0 + }; + + if (!transformString) { + return transform; + } else { + return transformString.toLowerCase().split(' ').reduce(function (acc, n) { + var parts = n.toLowerCase().split('-'); + var first = parts[0]; + var rest = parts.slice(1).join('-'); + + if (first && rest === 'h') { + acc.flipX = true; + return acc; + } + + if (first && rest === 'v') { + acc.flipY = true; + return acc; + } + + rest = parseFloat(rest); + + if (isNaN(rest)) { + return acc; + } + + switch (first) { + case 'grow': + acc.size = acc.size + rest; + break; + case 'shrink': + acc.size = acc.size - rest; + break; + case 'left': + acc.x = acc.x - rest; + break; + case 'right': + acc.x = acc.x + rest; + break; + case 'up': + acc.y = acc.y - rest; + break; + case 'down': + acc.y = acc.y + rest; + break; + case 'rotate': + acc.rotate = acc.rotate + rest; + break; + } + + return acc; + }, transform); + } +}; + +var transformParser = function (node) { + return parseTransformString(node.getAttribute('data-fa-transform')); +}; + +var symbolParser = function (node) { + var symbol = node.getAttribute('data-fa-symbol'); + + return symbol === null ? false : symbol === '' ? true : symbol; +}; + +var attributesParser = function (node) { + var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) { + if (acc.name !== 'class' && acc.name !== 'style') { + acc[attr.name] = attr.value; + } + return acc; + }, {}); + + var title = node.getAttribute('title'); + + if (config.autoA11y) { + if (title) { + extraAttributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + extraAttributes['aria-hidden'] = 'true'; + } + } + + return extraAttributes; +}; + +var maskParser = function (node) { + var mask = node.getAttribute('data-fa-mask'); + + if (!mask) { + return emptyCanonicalIcon(); + } else { + return getCanonicalIcon(mask.split(' ').map(function (i) { + return i.trim(); + })); + } +}; + +function parseMeta(node) { + var _classParser = classParser(node), + iconName = _classParser.iconName, + prefix = _classParser.prefix, + extraClasses = _classParser.rest; + + var extraStyles = styleParser(node); + var transform = transformParser(node); + var symbol = symbolParser(node); + var extraAttributes = attributesParser(node); + var mask = maskParser(node); + + return { + iconName: iconName, + title: node.getAttribute('title'), + prefix: prefix, + transform: transform, + symbol: symbol, + mask: mask, + extra: { + classes: extraClasses, + styles: extraStyles, + attributes: extraAttributes + } + }; +} + +function MissingIcon(error) { + this.name = 'MissingIcon'; + this.message = error || 'Icon unavailable'; + this.stack = new Error().stack; +} + +MissingIcon.prototype = Object.create(Error.prototype); +MissingIcon.prototype.constructor = MissingIcon; + +var FILL = { fill: 'currentColor' }; +var ANIMATION_BASE = { + attributeType: 'XML', + repeatCount: 'indefinite', + dur: '2s' +}; +var RING = { + tag: 'path', + attributes: _extends({}, FILL, { + d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z' + }) +}; +var OPACITY_ANIMATE = _extends({}, ANIMATION_BASE, { + attributeName: 'opacity' +}); +var DOT = { + tag: 'circle', + attributes: _extends({}, FILL, { + cx: '256', + cy: '364', + r: '28' + }), + children: [{ tag: 'animate', attributes: _extends({}, ANIMATION_BASE, { attributeName: 'r', values: '28;14;28;28;14;28;' }) }, { tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;1;1;0;1;' }) }] +}; +var QUESTION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '1', + d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;0;0;0;1;' }) }] +}; +var EXCLAMATION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '0', + d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '0;0;1;1;0;0;' }) }] +}; + +var missing = { tag: 'g', children: [RING, DOT, QUESTION, EXCLAMATION] }; + +var styles = namespace.styles; + +var LAYERS_TEXT_CLASSNAME = 'fa-layers-text'; +var FONT_FAMILY_PATTERN = /Font Awesome 5 (Solid|Regular|Light|Brands)/; +var STYLE_TO_PREFIX = { + 'Solid': 'fas', + 'Regular': 'far', + 'Light': 'fal', + 'Brands': 'fab' +}; + +function findIcon(iconName, prefix) { + var val = { + found: false, + width: 512, + height: 512, + icon: missing + }; + + if (iconName && prefix && styles[prefix] && styles[prefix][iconName]) { + var icon = styles[prefix][iconName]; + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + val = { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; + } else if (iconName && prefix && !config.showMissingIcons) { + throw new MissingIcon('Icon is missing for prefix ' + prefix + ' with icon name ' + iconName); + } + + return val; +} + +function generateSvgReplacementMutation(node, nodeMeta) { + var iconName = nodeMeta.iconName, + title = nodeMeta.title, + prefix = nodeMeta.prefix, + transform = nodeMeta.transform, + symbol = nodeMeta.symbol, + mask = nodeMeta.mask, + extra = nodeMeta.extra; + + + return [node, makeInlineSvgAbstract({ + icons: { + main: findIcon(iconName, prefix), + mask: findIcon(mask.iconName, mask.prefix) + }, + prefix: prefix, + iconName: iconName, + transform: transform, + symbol: symbol, + mask: mask, + title: title, + extra: extra + })]; +} + +function generateLayersText(node, nodeMeta) { + var title = nodeMeta.title, + transform = nodeMeta.transform, + extra = nodeMeta.extra; + + + var width = null; + var height = null; + + if (IS_IE) { + var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10); + var boundingClientRect = node.getBoundingClientRect(); + width = boundingClientRect.width / computedFontSize; + height = boundingClientRect.height / computedFontSize; + } + + if (config.autoA11y && !title) { + extra.attributes['aria-hidden'] = 'true'; + } + + return [node, makeLayersTextAbstract({ + content: node.innerHTML, + width: width, + height: height, + transform: transform, + title: title, + extra: extra + })]; +} + +function generateMutation(node) { + var nodeMeta = parseMeta(node); + + if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) { + return generateLayersText(node, nodeMeta); + } else { + return generateSvgReplacementMutation(node, nodeMeta); + } +} + +function searchPseudoElements(root) { + var end = perf.begin('searchPseudoElements'); + + disableObservation(function () { + toArray(root.querySelectorAll('*')).forEach(function (node) { + [':before', ':after'].forEach(function (pos) { + var styles = WINDOW.getComputedStyle(node, pos); + var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN); + var children = toArray(node.children); + var pseudoElement = children.filter(function (c) { + return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === pos; + })[0]; + + if (!fontFamily && pseudoElement) { + pseudoElement.remove(); + } + + if (fontFamily && !pseudoElement) { + var content = styles.getPropertyValue('content'); + var i = DOCUMENT.createElement('i'); + i.setAttribute('class', '' + STYLE_TO_PREFIX[fontFamily[1]]); + i.setAttribute(DATA_FA_PSEUDO_ELEMENT, pos); + i.innerText = content.length === 3 ? content.substr(1, 1) : content; + if (pos === ':before') { + node.insertBefore(i, node.firstChild); + } else { + node.appendChild(i); + } + } + }); + }); + }); + + end(); +} + +function onTree(root) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var htmlClassList = DOCUMENT.documentElement.classList; + var hclAdd = function hclAdd(suffix) { + return htmlClassList.add(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var hclRemove = function hclRemove(suffix) { + return htmlClassList.remove(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var prefixes = Object.keys(styles); + var prefixesDomQuery = ['.' + LAYERS_TEXT_CLASSNAME + ':not([' + DATA_FA_PROCESSED + '])'].concat(prefixes.map(function (p) { + return '.' + p + ':not([' + DATA_FA_PROCESSED + '])'; + })).join(', '); + + if (prefixesDomQuery.length === 0) { + return; + } + + var candidates = toArray(root.querySelectorAll(prefixesDomQuery)); + + if (candidates.length > 0) { + hclAdd('pending'); + hclRemove('complete'); + } else { + return; + } + + var mark = perf.begin('onTree'); + + var mutations = candidates.reduce(function (acc, node) { + try { + var mutation = generateMutation(node); + + if (mutation) { + acc.push(mutation); + } + } catch (e) { + if (!PRODUCTION) { + if (e instanceof MissingIcon) { + console.error(e); + } + } + } + + return acc; + }, []); + + mark(); + + perform(mutations, function () { + hclAdd('active'); + hclAdd('complete'); + hclRemove('pending'); + + if (typeof callback === 'function') callback(); + }); +} + +function onNode(node) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var mutation = generateMutation(node); + + if (mutation) { + perform([mutation], callback); + } +} + +var functions = []; +var listener = function listener() { + DOCUMENT.removeEventListener('DOMContentLoaded', listener); + loaded = 1; + functions.map(function (fn) { + return fn(); + }); +}; + +var loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState); + +if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener); + +var domready = function (fn) { + if (!DOCUMENT) return; + loaded ? setTimeout(fn, 0) : functions.push(fn); +}; + +var baseStyles = "svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-12.5%;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1em}.svg-inline--fa.fa-stack-2x{height:2em;width:2em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}"; + +var css = function () { + var dfp = DEFAULT_FAMILY_PREFIX; + var drc = DEFAULT_REPLACEMENT_CLASS; + var fp = config.familyPrefix; + var rc = config.replacementClass; + var s = baseStyles; + + if (fp !== dfp || rc !== drc) { + var dPatt = new RegExp('\\.' + dfp + '\\-', 'g'); + var rPatt = new RegExp('\\.' + drc, 'g'); + + s = s.replace(dPatt, '.' + fp + '-').replace(rPatt, '.' + rc); + } + + return s; +}; + +var Library = function () { + function Library() { + classCallCheck(this, Library); + + this.definitions = {}; + } + + createClass(Library, [{ + key: "add", + value: function add() { + var _this = this; + + for (var _len = arguments.length, definitions = Array(_len), _key = 0; _key < _len; _key++) { + definitions[_key] = arguments[_key]; + } + + var additions = definitions.reduce(this._pullDefinitions, {}); + + Object.keys(additions).forEach(function (key) { + _this.definitions[key] = _extends({}, _this.definitions[key] || {}, additions[key]); + }); + } + }, { + key: "reset", + value: function reset() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function _pullDefinitions(additions, definition) { + var normalized = definition.prefix && definition.iconName && definition.icon ? { 0: definition } : definition; + + Object.keys(normalized).map(function (key) { + var _normalized$key = normalized[key], + prefix = _normalized$key.prefix, + iconName = _normalized$key.iconName, + icon = _normalized$key.icon; + + + if (!additions[prefix]) additions[prefix] = {}; + + additions[prefix][iconName] = icon; + }); + + return additions; + } + }]); + return Library; +}(); + +function prepIcon(icon) { + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + return { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; +} + +var _cssInserted = false; + +function ensureCss() { + if (!config.autoAddCss) { + return; + } + + if (!_cssInserted) { + insertCss(css()); + } + + _cssInserted = true; +} + +function apiObject(val, abstractCreator) { + Object.defineProperty(val, 'abstract', { + get: abstractCreator + }); + + Object.defineProperty(val, 'html', { + get: function get() { + return val.abstract.map(function (a) { + return toHtml(a); + }); + } + }); + + Object.defineProperty(val, 'node', { + get: function get() { + if (!DOCUMENT.createElement) return; + + var container = DOCUMENT.createElement('div'); + container.innerHTML = val.html; + return container.children; + } + }); + + return val; +} + +function findIconDefinition(params) { + var _params$prefix = params.prefix, + prefix = _params$prefix === undefined ? 'fa' : _params$prefix, + iconName = params.iconName; + + + if (!iconName) return; + + return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); +} + +function resolveIcons(next) { + return function (maybeIconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); + + var mask = params.mask; + + + if (mask) { + mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); + } + + return next(iconDefinition, _extends({}, params, { mask: mask })); + }; +} + +var library = new Library(); + +var api = { + dom: { + i2svg: function i2svg() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + ensureCss(); + + var _params$node = params.node, + node = _params$node === undefined ? DOCUMENT : _params$node, + _params$callback = params.callback, + callback = _params$callback === undefined ? function () {} : _params$callback; + + + if (config.searchPseudoElements) { + searchPseudoElements(node); + } + + onTree(node, callback); + }, + + css: css, + + insertCss: function insertCss$$1() { + insertCss(css()); + } + }, + + library: library, + + parse: { + transform: function transform(transformString) { + return parseTransformString(transformString); + } + }, + + findIconDefinition: findIconDefinition, + + icon: resolveIcons(function (iconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform = params.transform, + transform = _params$transform === undefined ? meaninglessTransform : _params$transform, + _params$symbol = params.symbol, + symbol = _params$symbol === undefined ? false : _params$symbol, + _params$mask = params.mask, + mask = _params$mask === undefined ? null : _params$mask, + _params$title = params.title, + title = _params$title === undefined ? null : _params$title, + _params$classes = params.classes, + classes = _params$classes === undefined ? [] : _params$classes, + _params$attributes = params.attributes, + attributes = _params$attributes === undefined ? {} : _params$attributes, + _params$styles = params.styles, + styles = _params$styles === undefined ? {} : _params$styles; + + + if (!iconDefinition) return; + + var prefix = iconDefinition.prefix, + iconName = iconDefinition.iconName, + icon = iconDefinition.icon; + + + return apiObject(_extends({ type: 'icon' }, iconDefinition), function () { + ensureCss(); + + if (config.autoA11y) { + if (title) { + attributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + attributes['aria-hidden'] = 'true'; + } + } + + return makeInlineSvgAbstract({ + icons: { + main: prepIcon(icon), + mask: mask ? prepIcon(mask.icon) : { found: false, width: null, height: null, icon: {} } + }, + prefix: prefix, + iconName: iconName, + transform: _extends({}, meaninglessTransform, transform), + symbol: symbol, + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: classes + } + }); + }); + }), + + text: function text(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform2 = params.transform, + transform = _params$transform2 === undefined ? meaninglessTransform : _params$transform2, + _params$title2 = params.title, + title = _params$title2 === undefined ? null : _params$title2, + _params$classes2 = params.classes, + classes = _params$classes2 === undefined ? [] : _params$classes2, + _params$attributes2 = params.attributes, + attributes = _params$attributes2 === undefined ? {} : _params$attributes2, + _params$styles2 = params.styles, + styles = _params$styles2 === undefined ? {} : _params$styles2; + + + return apiObject({ type: 'text', content: content }, function () { + ensureCss(); + + return makeLayersTextAbstract({ + content: content, + transform: _extends({}, meaninglessTransform, transform), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: [config.familyPrefix + '-layers-text'].concat(toConsumableArray(classes)) + } + }); + }); + }, + + layer: function layer(assembler) { + return apiObject({ type: 'layer' }, function () { + ensureCss(); + + var children = []; + + assembler(function (args) { + Array.isArray(args) ? children = args.map(function (a) { + children = children.concat(a.abstract); + }) : children = children.concat(args.abstract); + }); + + return [{ + tag: 'span', + attributes: { class: config.familyPrefix + '-layers' }, + children: children + }]; + }); + } +}; + +Object.defineProperty(api, 'config', { + get: function get() { + var autoReplaceSvg = config.autoReplaceSvg, + observeMutations = config.observeMutations, + showMissingIcons = config.showMissingIcons, + rest = objectWithoutProperties(config, ['autoReplaceSvg', 'observeMutations', 'showMissingIcons']); + + return rest; + }, + + set: function set(newConfig) { + update(newConfig); + } +}); + +function bootstrap() { + var autoReplace = function autoReplace() { + if (config.autoReplaceSvg) api.dom.i2svg({ node: DOCUMENT }); + }; + + if (IS_BROWSER) { + if (!WINDOW.FontAwesome) { + WINDOW.FontAwesome = api; + } + + domready(function () { + if (Object.keys(namespace.styles).length > 0) { + autoReplace(); + } + + if (config.observeMutations && typeof MutationObserver === 'function') { + observe({ + treeCallback: onTree, + nodeCallback: onNode, + pseudoElementsCallback: searchPseudoElements + }); + } + }); + } + + namespace.hooks = _extends({}, namespace.hooks, { + + addPack: function addPack(prefix, icons) { + namespace.styles[prefix] = _extends({}, namespace.styles[prefix] || {}, icons); + + build(); + autoReplace(); + }, + + addShims: function addShims(shims) { + var _namespace$shims; + + (_namespace$shims = namespace.shims).push.apply(_namespace$shims, toConsumableArray(shims)); + + build(); + autoReplace(); + } + }); +} + +bunker(bootstrap); + +}()); diff --git a/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome-all.min.js b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome-all.min.js new file mode 100644 index 000000000..3dbd3be81 --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome-all.min.js @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +!function(){"use strict";function c(c){"function"==typeof s.hooks.addPack?s.hooks.addPack(c,m):s.styles[c]=r({},s.styles[c]||{},m)}var l={};try{"undefined"!=typeof window&&(l=window)}catch(c){}var h=(l.navigator||{}).userAgent,v=void 0===h?"":h,z=l,e=(~v.indexOf("MSIE")||v.indexOf("Trident/"),[1,2,3,4,5,6,7,8,9,10]),a=e.concat([11,12,13,14,15,16,17,18,19,20]),m=(["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(e.map(function(c){return c+"x"})).concat(a.map(function(c){return"w-"+c})),{"500px":[448,512,[],"f26e","M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"],"accessible-icon":[448,512,[],"f368","M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"],accusoft:[640,512,[],"f369","M482.2 372.1C476.5 365.2 250 75 242.3 65.5c-13.7-17.2 0-16.8 19.2-16.9 9.7-.1 106.3-.6 116.5-.6 24.1-.1 28.7.6 38.4 12.8 2.1 2.7 205.1 245.8 207.2 248.3 5.5 6.7 15.2 19.1 7.2 23.4-2.4 1.3-114.6 47.7-117.8 48.9-10.1 4-17.5 6.8-30.8-9.3m114.7-5.6s-115 50.4-117.5 51.6c-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2-2.3-.3-24.6-4.7-38-7.2m-326-181.3s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3v-1l-51.2-65.8"],adn:[496,512,[],"f170","M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z"],adversal:[512,512,[],"f36a","M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"],affiliatetheme:[512,512,[],"f36b","M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z"],algolia:[448,512,[],"f36c","M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"],amazon:[448,512,[],"f270","M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"],amilia:[448,512,[],"f36d","M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm-87.9 327.7c0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5V380c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7"],android:[448,512,[],"f17b","M89.6 204.5v115.8c0 15.4-12.1 27.7-27.5 27.7-15.3 0-30.1-12.4-30.1-27.7V204.5c0-15.1 14.8-27.5 30.1-27.5 15.1 0 27.5 12.4 27.5 27.5zm10.8 157c0 16.4 13.2 29.6 29.6 29.6h19.9l.3 61.1c0 36.9 55.2 36.6 55.2 0v-61.1h37.2v61.1c0 36.7 55.5 36.8 55.5 0v-61.1h20.2c16.2 0 29.4-13.2 29.4-29.6V182.1H100.4v179.4zm248-189.1H99.3c0-42.8 25.6-80 63.6-99.4l-19.1-35.3c-2.8-4.9 4.3-8 6.7-3.8l19.4 35.6c34.9-15.5 75-14.7 108.3 0L297.5 34c2.5-4.3 9.5-1.1 6.7 3.8L285.1 73c37.7 19.4 63.3 56.6 63.3 99.4zm-170.7-55.5c0-5.7-4.6-10.5-10.5-10.5-5.7 0-10.2 4.8-10.2 10.5s4.6 10.5 10.2 10.5c5.9 0 10.5-4.8 10.5-10.5zm113.4 0c0-5.7-4.6-10.5-10.2-10.5-5.9 0-10.5 4.8-10.5 10.5s4.6 10.5 10.5 10.5c5.6 0 10.2-4.8 10.2-10.5zm94.8 60.1c-15.1 0-27.5 12.1-27.5 27.5v115.8c0 15.4 12.4 27.7 27.5 27.7 15.4 0 30.1-12.4 30.1-27.7V204.5c0-15.4-14.8-27.5-30.1-27.5z"],angellist:[448,512,[],"f209","M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"],angrycreative:[640,512,[],"f36e","M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"],angular:[415,512,[],"f420","M169.7 268.1h76.2l-38.1-91.6-38.1 91.6zM207.8 32L0 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7L207.8 32zM338 373.8h-48.6l-26.2-65.4H152.6l-26.2 65.4H77.7L207.8 81.5 338 373.8z"],"app-store":[512,512,[],"f36f","M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z"],"app-store-ios":[448,512,[],"f370","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z"],apper:[640,512,[],"f371","M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z"],apple:[448,512,[],"f179","M247.2 137.6c-6.2 1.9-15.3 3.5-27.9 4.6 1.1-56.7 29.9-96.6 88-110.1 9.3 41.6-26.1 94.1-60.1 105.5zm121.3 72.7c6.4-9.4 16.6-19.9 30.6-31.7-22.3-27.6-48.1-44.3-85.1-44.3-35.4 0-65.2 18.2-87 18.2-18.5 0-51.9-16.1-84.5-16.1-69.6 0-106.5 68.1-106.5 139C36 354.2 95.7 480 156.2 480c23.8 0 45.2-18 73.5-18 29.3 0 52.8 17.2 80.3 17.2 46 0 88.6-77.5 102-119.7-46.8-14.3-84.4-90.2-43.5-149.2z"],"apple-pay":[640,512,[],"f415","M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z"],asymmetrik:[576,512,[],"f372","M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"],audible:[640,512,[],"f373","M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z"],autoprefixer:[640,512,[],"f41c","M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z"],avianex:[512,512,[],"f374","M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"],aviato:[640,512,[],"f421","M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z"],aws:[512,512,[],"f375","M261.2 136.1c-14 57.5-13.1 54.4-25.8 107-1.6 6.5-4.1 8.4-10.7 8.5h-14.4c-5.8-.1-8.2-1.6-9.9-7.3-12.3-39.4-28.8-94.1-39.9-130.7-4.1-13.5-1.4-13.2 9.3-12.9 3.7.1 7.3 0 11 0 5.1.1 7.7 2 9.1 7.1 3.6 12.9 6 22.8 26.6 104.1.4 1.6.9 3.1 1.4 4.6h1.1c.5-2 1.1-3.9 1.6-5.9 7.8-32.9 15.5-65.9 23.3-98.8 2.4-10.2 6.7-11.2 17-11.2h7.6c6.9.1 9 1.5 10.7 8.3 6 23.4 23.5 101.8 26.7 110.4 5.1-18.3-1.8 7.9 28.5-109 2.1-8.1 4.1-9.7 12.3-9.7h12.7c5.4.1 7 1.8 5.7 7.1-2.4 9.5-2.9 9.9-41.3 132.9-3.1 9.9-4.2 10.8-14.6 10.8h-10.6c-7.3 0-9.2-1.3-11-8.4-4.3-16.2-23.3-95.7-26.4-106.9zM125.4 247.3c4.2 5.8 8.1 6.3 14.1 2.4l6.3-4.2c6.8-4.5 7.3-6.3 3.6-13.5-4.3-8.4-6.4-17.3-6.3-26.9 0-3.1.6-55.7-.9-66.8-2.7-19.3-12.5-32.8-31.7-38.7-10.7-3.4-21.7-3.3-32.7-3-15.1.4-29.4 4.6-42.8 11.4-1.8.9-3.7 3.1-4.1 4.9-.8 3.9-1.1 8.1-.7 12.1.6 5.9 2.6 7 8.2 5.1 5.1-1.7 10-3.9 15.1-5.4 14.5-4.4 29.2-6.4 44.1-1.7 7.1 2.2 11.7 6.9 14.3 13.8 3 7.9 2.4 16.1 2.4 24.2 0 5.5-.1 5.5-5.5 4.5-13.9-2.6-27.7-5-41.9-3.1-15.2 2.1-28.6 7.3-38.2 20-9.1 12-10 25.6-7.4 39.5 2.8 15 11.8 25.7 26.4 30.4 20.6 6.7 40.1 3.3 57.7-9.5 3.8-2.8 7.2-6.2 11.1-9.5 3.1 5 5.8 9.7 8.9 14zm-15.3-61.6c3 .4 4.5 1.9 4.3 5.1-.2 3.8.1 7.6-.3 11.4-1.2 11.7-7.7 19.7-17.9 24.9-8.2 4.2-16.9 5.8-26.1 5-15.2-1.3-21-13.1-19.6-26.3C51.8 193.2 59 186.2 72 184c13.8-2.4 16-1.1 38.1 1.7zm348.8 65.1c21.3-8.6 32.9-26.2 29.2-50-2.2-14.6-11.8-24.2-25.2-29.5-14.7-5.9-33.8-10.3-48.1-18.2-4.4-2.4-7.4-6.3-7.6-11.9-.4-11.1 4.2-17.2 15.4-19.8 9.3-2.1 18.8-2.2 28.1-.4 7.3 1.4 14.3 4.2 21.4 6.3 2.8.9 5.9 2.1 7.8-1.6 3.8-7.3.4-18.7-7.3-21.8-22.5-9-45.5-11.6-68.2-1.6-14.6 6.4-24.6 17.4-26 34.2-1.6 19.3 6.9 33.4 24.1 41.7 7.7 3.7 16.1 5.9 24.2 8.9 8.1 3 16.2 5.8 24.1 9.1 12.3 5.3 11.6 24.2 1.2 30-27.7 15.3-64.9-2.4-69.2-3.8-3.3-1.1-5.3.2-6.3 3.7-3 11.3.7 18.8 11.6 22.7 21.7 7.9 49.6 10.5 70.8 2zM296 413.5c50.8-5.8 98.7-20.8 142.7-47 8-4.7 15.5-10.3 23.1-15.7 7.3-5.2 3.2-18.4-11.3-12.2-54.4 23.2-111.2 36.1-170.2 38.9-30.5 1.5-60.8-.3-91.1-4.7-63.1-9.2-122.4-29.2-177.6-61.2-2.1-1.2-4.2-2.5-6.5-3-4.9-1.1-7.7 4.7-2.4 9.7 24 22.1 50.3 40.8 79.1 55.7 53.7 27.7 110.5 42.7 171.2 42 14.4-.8 28.8-.9 43-2.5zm174.7-92.2c14.8.8 19.4 5.9 15.7 20.2-3.8 14.8-9.3 29.2-13.9 43.8-.9 2.9-4.2 6.3-.8 8.8 3.7 2.6 6.5-1 9-3.3 10.2-9.5 17.4-21 22.5-33.8 5.4-13.4 9.3-27.2 8.7-41.9-.2-6.2-1.8-8.8-7.8-10.5-5.4-1.5-11-2.8-16.5-3.2-21.6-1.8-42.5.5-62 10.6-3.1 1.6-6 3.7-8.7 5.9-1.1.9-3.2 5.3 2.4 6.1 1.9.3 3.9-.1 5.9-.3 16.9-1.6 28.6-3.3 45.5-2.4z"],bandcamp:[496,512,[],"f2d5","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm48.2 326.1h-181L199.9 178h181l-84.7 156.1z"],behance:[576,512,[],"f1b4","M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z"],"behance-square":[512,512,[],"f1b5","M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z"],bimobject:[448,512,[],"f378","M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z"],bitbucket:[512,512,[],"f171","M23.1 32C14.2 31.9 7 38.9 6.9 47.8c0 .9.1 1.8.2 2.8L74.9 462c1.7 10.4 10.7 18 21.2 18.1h325.1c7.9.1 14.7-5.6 16-13.4l67.8-416c1.4-8.7-4.5-16.9-13.2-18.3-.9-.1-1.8-.2-2.8-.2L23.1 32zm285.3 297.3H204.6l-28.1-146.8h157l-25.1 146.8z"],bitcoin:[512,512,[],"f379","M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z"],bity:[496,512,[],"f37a","M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z"],"black-tie":[448,512,[],"f27e","M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z"],blackberry:[512,512,[],"f37b","M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z"],blogger:[448,512,[],"f37c","M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z"],"blogger-b":[448,512,[],"f37d","M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"],bluetooth:[448,512,[],"f293","M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z"],"bluetooth-b":[320,512,[],"f294","M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z"],btc:[384,512,[],"f15a","M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z"],buromobelexperte:[448,512,[],"f37f","M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z"],buysellads:[448,512,[],"f20d","M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z"],"cc-amex":[576,512,[],"f1f3","M576 255.4c-37.9-.2-44.2-.9-54.5 5v-5c-45.3 0-53.5-1.7-64.9 5.2v-5.2h-78.2v5.1c-11.4-6.5-21.4-5.1-75.7-5.1v5.6c-6.3-3.7-14.5-5.6-24.3-5.6h-58c-3.5 3.8-12.5 13.7-15.7 17.2-12.7-14.1-10.5-11.6-15.5-17.2h-83.1v92.3h82c3.3-3.5 12.9-13.9 16.1-17.4 12.7 14.3 10.3 11.7 15.4 17.4h48.9c0-14.7.1-8.3.1-23 11.5.2 24.3-.2 34.3-6.2 0 13.9-.1 17.1-.1 29.2h39.6c0-18.5.1-7.4.1-25.3 6.2 0 7.7 0 9.4.1.1 1.3 0 0 0 25.2 152.8 0 145.9 1.1 156.7-4.5v4.5c34.8 0 54.8 2.2 67.5-6.1V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V228.3h26.6c4.2-10.1 2.2-5.3 6.4-15.3h19.2c4.2 10 2.2 5.2 6.4 15.3h52.9v-11.4c2.2 5 1.1 2.5 5.1 11.4h29.5c2.4-5.5 2.6-5.8 5.1-11.4v11.4h135.5v-25.1c6.4 0 8-.1 9.8.2 0 0-.2 10.9.1 24.8h66.5v-8.9c7.4 5.9 17.4 8.9 29.7 8.9h26.8c4.2-10.1 2.2-5.3 6.4-15.3h19c6.5 15 .2.5 6.6 15.3h52.8v-21.9c11.8 19.7 7.8 12.9 13.2 21.9h41.6v-92h-39.9v18.4c-12.2-20.2-6.3-10.4-11.2-18.4h-43.3v20.6c-6.2-14.6-4.6-10.8-8.8-20.6h-32.4c-.4 0-2.3.2-2.3-.3h-27.6c-12.8 0-23.1 3.2-30.7 9.3v-9.3h-39.9v5.3c-10.8-6.1-20.7-5.1-64.4-5.3-.1 0-11.6-.1-11.6 0h-103c-2.5 6.1-6.8 16.4-12.6 30-2.8-6-11-23.8-13.9-30h-46V157c-7.4-17.4-4.7-11-9-21.1H22.9c-3.4 7.9-13.7 32-23.1 53.9V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48v175.4zm-186.6-80.6c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm-19.9 130.9c9.2 3.3 11 9.5 11 18.4l-.1 13.8h-16.6l.1-11.5c0-11.8-3.8-13.8-14.8-13.8h-17.6l-.1 25.3h-16.6l.1-69.3h39.4c13 0 27.1 2.3 27.1 18.7-.1 7.6-4.2 15.3-11.9 18.4zm-6.3-15.4c0-6.4-5.6-7.4-10.7-7.4h-21v15.6h20.7c5.6 0 11-1.3 11-8.2zm181.7-7.1H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-99.2-.3v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5h38.5zm42.2 40.1h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-78.1-158.7c-17.4-.3-33.2-4.1-33.2 19.7 0 11.8 2.8 19.9 16.1 19.9h7.4l23.5-54.5h24.8l27.9 65.4v-65.4h25.3l29.1 48.1v-48.1h16.9v69H524l-31.2-51.9v51.9h-33.7l-6.6-15.3h-34.3l-6.4 15.3h-19.2c-22.8 0-33-11.8-33-34 0-23.3 10.5-35.3 34-35.3h16.1v15.2zm14.3 24.5h22.8l-11.2-27.6-11.6 27.6zm-72.6-39.6h-16.9v69.3h16.9v-69.3zm-38.1 37.3c9.5 3.3 11 9.2 11 18.4v13.5h-16.6c-.3-14.8 3.6-25.1-14.8-25.1h-18v25.1h-16.4v-69.3l39.1.3c13.3 0 27.4 2 27.4 18.4.1 8-4.3 15.7-11.7 18.7zm-6.7-15.3c0-6.4-5.6-7.4-10.7-7.4h-21v15.3h20.7c5.7 0 11-1.3 11-7.9zm-59.5-7.4v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5h38.9zm-84.6 54.7v-54.2l-24 54.2H124l-24-54.2v54.2H66.2l-6.4-15.3H25.3l-6.4 15.3H1l29.7-69.3h24.5l28.1 65.7v-65.7h27.1l21.7 47 19.7-47h27.6v69.3h-16.8zM53.9 188.8l-11.5-27.6-11.2 27.6h22.7zm253 102.5c0 27.9-30.4 23.3-49.3 23.3l-.1 23.3h-32.2l-20.4-23-21.3 23h-65.4l.1-69.3h66.5l20.5 22.8 21-22.8H279c15.6 0 27.9 5.4 27.9 22.7zm-112.7 11.8l-17.9-20.2h-41.7v12.5h36.3v14.1h-36.3v13.8h40.6l19-20.2zM241 276l-25.3 27.4 25.3 28.1V276zm48.3 15.3c0-6.1-4.6-8.4-10.2-8.4h-21.5v17.6h21.2c5.9 0 10.5-2.8 10.5-9.2z"],"cc-apple-pay":[576,512,[],"f416","M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z"],"cc-diners-club":[576,512,[],"f24c","M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z"],"cc-discover":[576,512,[],"f1f2","M83 212.1c0 7.9-3.2 15.5-8.9 20.7-4.9 4.4-11.6 6.4-21.9 6.4H48V185h4.2c10.3 0 16.7 1.7 21.9 6.6 5.7 5 8.9 12.6 8.9 20.5zM504.8 184h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8 0-7.9-5.5-12.1-15.6-12.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM428 253h45.3v-13.8H444V217h28.3v-13.8H444V185h29.3v-14H428v82zm-86.2-82l35 84.2h8.6l35.5-84.2h-17.5l-22.2 55.2-21.9-55.2h-17.5zm-83 41.6c0 24.6 19.9 44.6 44.6 44.6 24.6 0 44.6-19.9 44.6-44.6 0-24.6-19.9-44.6-44.6-44.6-24.6 0-44.6 19.9-44.6 44.6zm-68-.5c0 32.5 33.6 52.5 63.3 38.2v-19c-19.3 19.3-46.8 5.8-46.8-19.2 0-23.7 26.7-39.1 46.8-19v-19c-30.2-15-63.3 6.8-63.3 38zm-33.9 28.3c-7.6 0-13.8-3.7-17.5-10.8l-10.3 9.9c17.8 26.1 56.6 18.2 56.6-11.3 0-13.1-5.4-19-23.6-25.6-9.6-3.4-12.3-5.9-12.3-10.3 0-8.7 14.5-14.1 24.9-2.5l8.4-10.8c-19.1-17.1-49.7-8.9-49.7 14.3 0 11.3 5.2 17.2 20.2 22.7 25.7 9.1 14.7 24.4 3.3 24.4zm-57.4-28.3c0-24.1-18-41.1-44.1-41.1H32v82h23.4c30.9 0 44.1-22.4 44.1-40.9zm23.4-41.1h-16v82h16v-82zM544 288c-33.3 20.8-226.4 124.4-416 160h401c8.2 0 15-6.8 15-15V288zm0-35l-25.9-34.5c12.1-2.5 18.7-10.6 18.7-23.2 0-28.5-30.3-24.4-52.9-24.4v82h16v-32.8h2.2l22.2 32.8H544z"],"cc-jcb":[576,512,[],"f24b","M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z"],"cc-mastercard":[576,512,[],"f1f1","M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z"],"cc-paypal":[576,512,[],"f1f4","M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z"],"cc-stripe":[576,512,[],"f1f5","M396.9 256.5c0 19.1-8.8 33.4-21.9 33.4-8.3 0-13.3-3-16.8-6.7l-.2-52.8c3.7-4.1 8.8-7 17-7 12.9-.1 21.9 14.5 21.9 33.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM122.2 281.1c0-42.3-54.3-34.7-54.3-50.7 0-5.5 4.6-7.7 12.1-7.7 10.8 0 24.5 3.3 35.3 9.1v-33.4c-11.8-4.7-23.5-6.5-35.3-6.5-28.8 0-48 15-48 40.2 0 39.3 54 32.9 54 49.9 0 6.6-5.7 8.7-13.6 8.7-11.8 0-26.9-4.9-38.9-11.3v33.9c13.2 5.7 26.6 8.1 38.8 8.1 29.6-.2 49.9-14.7 49.9-40.3zm68.9-86.9h-27v-30.8l-34.7 7.4-.2 113.9c0 21 15.8 36.5 36.9 36.5 11.6 0 20.2-2.1 24.9-4.7v-28.9c-4.5 1.8-27 8.3-27-12.6v-50.5h27v-30.3zm73.8 0c-4.7-1.7-21.3-4.8-29.6 10.5l-2.2-10.5h-30.7v124.5h35.5v-84.4c8.4-11 22.6-8.9 27.1-7.4v-32.7zm44.2 0h-35.7v124.5h35.7V194.2zm0-47.3l-35.7 7.6v28.9l35.7-7.6v-28.9zm122.7 108.8c0-41.3-23.5-63.8-48.4-63.8-13.9 0-22.9 6.6-27.8 11.1l-1.8-8.8h-31.3V360l35.5-7.5.1-40.2c5.1 3.7 12.7 9 25.1 9 25.4-.1 48.6-20.5 48.6-65.6zm112.2 1.2c0-36.4-17.6-65.1-51.3-65.1-33.8 0-54.3 28.7-54.3 64.9 0 42.8 24.2 64.5 58.8 64.5 17 0 29.7-3.9 39.4-9.2v-28.6c-9.7 4.9-20.8 7.9-34.9 7.9-13.8 0-26-4.9-27.6-21.5h69.5c.1-2 .4-9.4.4-12.9zm-51.6-36.1c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7z"],"cc-visa":[576,512,[],"f1f0","M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z"],centercode:[512,512,[],"f380","M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z"],chrome:[496,512,[],"f268","M131.5 217.5L55.1 100.1c47.6-59.2 119-91.8 192-92.1 42.3-.3 85.5 10.5 124.8 33.2 43.4 25.2 76.4 61.4 97.4 103L264 133.4c-58.1-3.4-113.4 29.3-132.5 84.1zm32.9 38.5c0 46.2 37.4 83.6 83.6 83.6s83.6-37.4 83.6-83.6-37.4-83.6-83.6-83.6-83.6 37.3-83.6 83.6zm314.9-89.2L339.6 174c37.9 44.3 38.5 108.2 6.6 157.2L234.1 503.6c46.5 2.5 94.4-7.7 137.8-32.9 107.4-62 150.9-192 107.4-303.9zM133.7 303.6L40.4 120.1C14.9 159.1 0 205.9 0 256c0 124 90.8 226.7 209.5 244.9l63.7-124.8c-57.6 10.8-113.2-20.8-139.5-72.5z"],cloudscale:[448,512,[],"f383","M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z"],cloudsmith:[332,512,[],"f384","M332.5 419.9c0 46.4-37.6 84.1-84 84.1s-84-37.7-84-84.1 37.6-84 84-84 84 37.6 84 84zm-84-243.9c46.4 0 80-37.6 80-84s-33.6-84-80-84-88 37.6-88 84-29.6 76-76 76-84 41.6-84 88 37.6 80 84 80 84-33.6 84-80 33.6-80 80-80z"],cloudversify:[616,512,[],"f385","M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z"],codepen:[512,512,[],"f1cb","M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z"],codiepie:[472,512,[],"f284","M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z"],connectdevelop:[576,512,[],"f20e","M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z"],contao:[512,512,[],"f26d","M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z"],cpanel:[640,512,[],"f388","M52.9 213.7h40l-6.2 23.6c-1.9 6.5-7.4 10.9-14.3 10.9H53.8c-24.9 0-24.7 37.4 0 37.4h11.3c4.2 0 7.6 3.9 6.4 8.3L64.4 320H52c-33.5 0-59-31.4-50.3-65.2 7.3-27 28.3-41.1 51.2-41.1M73.1 320L108 189.9c1.8-6.4 7.2-10.9 14.3-10.9h37c24.1 0 45.4 16.4 51 41.2 6.6 29.1-14.5 65.3-51.7 65.3h-32l6.4-23.8c1.8-6.2 7.3-10.8 14.3-10.8h10.3c12.4 0 20.8-11.7 18.3-22.6-2.1-9.2-9.9-14.8-18.3-14.8h-19.8L112 309.2c-1.9 6.2-7.4 10.7-14.2 10.7l-24.7.1m220.6-69.4c.3-1 1.9-5.3-2.1-5.3h-57.5c-9.7 0-16.6-8.9-14.2-18.5l3.5-13.4h77.9c18.8 0 33.3 17.6 28.5 36.8l-14 51.8c-2.8 10.6-12.2 17.8-23.4 17.8l-57.5-.2c-42.9 0-38.5-63.8.7-63.8H284l-3.5 13.2c-1.9 6.2-7.4 10.8-14.2 10.8h-21.6c-5.3 0-5.3 7.9 0 7.9h34.9c4.6 0 5.1-3.9 5.5-5.3l8.6-31.8m103.1-36.9c34.4 0 59.3 32.3 50.3 65.4l-8.8 33.1c-1.2 4.9-5.7 7.8-10.3 7.8h-19.1c-4.5 0-7.6-4-6.4-8.3l10.6-40c3.3-11.6-5.6-23.4-18.1-23.4h-19.8l-17.2 64c-1.2 4.8-5.6 7.8-10.4 7.8h-18.9c-4.2 0-7.6-3.9-6.4-8.3l26.2-98h48.3M498 251.6l-8 30c-.9 3.3 1.5 6.7 5.1 6.7h73.3l-5.7 21c-1.9 6.2-7.4 10.7-14.2 10.7h-66.7c-20 0-33.3-19-28.3-36.7l10.8-40c4.8-17.6 20.7-29.6 38.6-29.6h47.3c19 0 33.2 17.7 28.3 36.8l-3.2 12c-2.9 11-12.7 17.6-23.2 17.6h-53.4l3.5-13c1.6-6.2 7.2-10.8 14.2-10.8H538c2 0 3.3-1 3.9-3l.7-2.6c.7-2.7-1.3-5.1-3.9-5.1h-32.9c-4.1 0-6.9 2.1-7.8 6zm70.2 68.4l35.6-133.1c1.2-4.7 5.5-7.9 10.4-7.9h18.9c4.5 0 7.7 4 6.5 8.3l-26.5 98.2c-5.1 20.7-24.2 34.5-44.9 34.5"],"creative-commons":[512,512,[],"f25e","M255.547 8C392.884 8 504 114.439 504 256.004 504 405.979 381.106 504 255.562 504 122.319 504 8 394.557 8 256.004 8 124.825 113.486 8 255.547 8zm.899 44.734c-120.341 0-203.727 100.568-203.727 203.278 0 106.515 88.984 202.394 203.727 202.394 101.528 0 202.821-79.442 202.821-202.387-.001-114.773-91.773-203.285-202.821-203.285zm-3.108 162.093l-33.225 17.275c-5.395-11.203-15.25-19.926-27.459-19.926-22.134 0-33.217 14.609-33.217 43.842 0 23.842 9.446 43.842 33.217 43.842 14.469 0 24.653-7.091 30.566-21.259l30.551 15.5c-12.813 23.899-36.887 38.975-65.101 38.975-43.162 0-73.959-27.272-73.959-77.052 0-49.541 32.706-77.059 72.634-77.059 30.714-.013 52.701 11.946 65.993 35.862zm143.044 0l-32.775 17.275c-5.517-11.482-15.324-19.926-27.9-19.926-22.142 0-33.225 14.609-33.225 43.842 0 23.906 9.502 43.842 33.225 43.842 14.454 0 24.645-7.091 30.543-21.259l31 15.5c-13.363 23.869-37.451 38.975-65.086 38.975-43.439 0-73.959-26.988-73.959-77.052 0-49.523 32.698-77.059 72.626-77.059 30.706-.013 52.569 11.946 65.551 35.862z"],css3:[512,512,[],"f13c","M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"],"css3-alt":[384,512,[],"f38b","M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z"],cuttlefish:[440,512,[],"f38c","M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z"],"d-and-d":[576,512,[],"f38d","M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z"],dashcube:[384,512,[],"f210","M288.1 97.5H85.5C37.6 97.5 0 138.1 0 185.2v215.1C0 447.7 37.6 480 85.5 480h213c47.9 0 85.5-32.3 85.5-79.7V0l-95.9 97.5zm-161.9 293c-16.6 0-30.4-14.2-30.4-30.8v-134c0-16.6 13.8-30.5 30.4-30.5h131.9c16.6 0 30 13.9 30 30.5v115.7l47.9 49H126.2z"],delicious:[448,512,[],"f1a5","M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192v176z"],deploydog:[512,512,[],"f38e","M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z"],deskpro:[480,512,[],"f38f","M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z"],deviantart:[320,512,[],"f1bd","M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z"],digg:[512,512,[],"f1a6","M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z"],"digital-ocean":[512,512,[],"f391","M256 504v-96.1c101.8 0 180.8-100.9 141.7-208-14.3-39.6-46.1-71.4-85.8-85.7-107.1-38.8-208.1 39.9-208.1 141.7H8C8 93.7 164.9-32.8 335 20.3c74.2 23.3 133.6 82.4 156.6 156.6C544.8 347.2 418.6 504 256 504zm.3-191.4h-95.6v95.6h95.6v-95.6zm-95.6 95.6H87v73.6h73.7v-73.6zM87 346.6H25.4v61.6H87v-61.6z"],discord:[448,512,[],"f392","M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"],discourse:[448,512,[],"f393","M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z"],dochub:[416,512,[],"f394","M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z"],docker:[640,512,[],"f395","M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"],draft2digital:[480,512,[],"f396","M369.9 425.4V371l47.1 27.2-47.1 27.2zM82.4 380.6c25.5-27.3 97.7-104.7 150.9-170 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7H82.4zm51.8-219.2c0 12.4-10 22.4-22.4 22.4-12.4 0-22.4-10-22.4-22.4 0-12.4 10-22.4 22.4-22.4 12.4 0 22.4 10.1 22.4 22.4M336 315.9v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480l144-81.9-144-82.2z"],dribbble:[512,512,[],"f17d","M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z"],"dribbble-square":[448,512,[],"f397","M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z"],dropbox:[528,512,[],"f16b","M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"],drupal:[448,512,[],"f1a9","M319.5 114.7c-22.2-14-43.5-19.5-64.7-33.5-13-8.8-31.3-30-46.5-48.3-2.7 29.3-11.5 41.2-22 49.5-21.3 17-34.8 22.2-53.5 32.3C117 123 32 181.5 32 290.5 32 399.7 123.8 480 225.8 480 327.5 480 416 406 416 294c0-112.3-83-171-96.5-179.3zm2.5 325.6c-20.1 20.1-90.1 28.7-116.7 4.2-4.8-4.8.3-12 6.5-12 0 0 17 13.3 51.5 13.3 27 0 46-7.7 54.5-14 6.1-4.6 8.4 4.3 4.2 8.5zm-54.5-52.6c8.7-3.6 29-3.8 36.8 1.3 4.1 2.8 16.1 18.8 6.2 23.7-8.4 4.2-1.2-15.7-26.5-15.7-14.7 0-19.5 5.2-26.7 11-7 6-9.8 8-12.2 4.7-6-8.2 15.9-22.3 22.4-25zM360 405c-15.2-1-45.5-48.8-65-49.5-30.9-.9-104.1 80.7-161.3 42-38.8-26.6-14.6-104.8 51.8-105.2 49.5-.5 83.8 49 108.5 48.5 21.3-.3 61.8-41.8 81.8-41.8 48.7 0 23.3 109.3-15.8 106z"],dyalog:[416,512,[],"f399","M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z"],earlybirds:[480,512,[],"f39a","M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z"],edge:[512,512,[],"f282","M25.714 228.163c.111-.162.23-.323.342-.485-.021.162-.045.323-.065.485h-.277zm460.572 15.508c0-44.032-7.754-84.465-28.801-122.405C416.498 47.879 343.912 8.001 258.893 8.001 118.962 7.724 40.617 113.214 26.056 227.679c42.429-61.312 117.073-121.376 220.375-124.966 0 0 109.666 0 99.419 104.957H169.997c6.369-37.386 18.554-58.986 34.339-78.926-75.048 34.893-121.85 96.096-120.742 188.315.83 71.448 50.124 144.836 120.743 171.976 83.357 31.847 192.776 7.2 240.132-21.324V363.307c-80.864 56.494-270.871 60.925-272.255-67.572h314.073v-52.064z"],ember:[640,512,[],"f423","M639.9 311.7c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3-2.4 6.2-14.2 49.2-15 67.2 0 0-23.1 19.6-43.3 22.8-20.2 3.2-25-9.4-25-9.4s54.8-15.3 52.9-59.1c-1.9-43.8-44.2-27.6-49-24-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-18.3-11-32.8 12.1-32.8 12.1s54.5-60.7 42.5-112c-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9c-3 7.3-13.7 55.3-15 70.7 0 0-28.2 20.2-46.8 20.4s-16.7-11.8-16.7-11.8 68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9-6.4-5.4-10 0-10 0s-11.2 13.9-.1 18.2c11 4.3 28.1 6.1 28.1 6.1 1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7c11.6 2.1 16.4 1 36.5-47.9 11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7c3.5 12.9 18.8 11.6 18.8 11.6s8.3 2.4 15-21.2c6.7-23.6 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7c8.6 15.6 30.9 5.3 30.9 5.3s15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6c12.4 5.1 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2c20.4 5.9 47-13.7 47-13.7s6.4-3.7 5.3-14.4zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.9s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.1 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.5 3.6 45.5zm84.6-14.5s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5c-10.8 15.3-26.4 14.2-26.4 14.2z"],empire:[496,512,[],"f1d1","M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z"],envira:[448,512,[],"f299","M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z"],erlang:[640,512,[],"f39d","M21.7 193c-.1 86.8 29 159.5 78.7 212.1H0V.1h87.2C45.7 50.3 21.6 116.2 21.7 193zM640 .1h-83.6c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640V.1zm-80.8 405h-.2.2zM556.1.1h.3l-.1-.1-.2.1zM325.4 9.8c-45.9.1-85.1 33.5-89.2 83.2h169.9C405 43.3 371.6 9.9 325.4 9.8z"],etsy:[384,512,[],"f2d7","M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z"],expeditedssl:[496,512,[],"f23e","M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z"],facebook:[448,512,[],"f09a","M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"],"facebook-f":[264,512,[],"f39e","M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"],"facebook-messenger":[448,512,[],"f39f","M224 32C15.9 32-77.5 278 84.6 400.6V480l75.7-42c142.2 39.8 285.4-59.9 285.4-198.7C445.8 124.8 346.5 32 224 32zm23.4 278.1L190 250.5 79.6 311.6l121.1-128.5 57.4 59.6 110.4-61.1-121.1 128.5z"],"facebook-square":[448,512,[],"f082","M448 80v352c0 26.5-21.5 48-48 48h-85.3V302.8h60.6l8.7-67.6h-69.3V192c0-19.6 5.4-32.9 33.5-32.9H384V98.7c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9H184v67.6h60.9V480H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],firefox:[480,512,[],"f269","M478.1 235.3c-.7-4.5-1.4-7.1-1.4-7.1s-1.8 2-4.7 5.9c-.9-10.7-2.8-21.2-5.8-31.6-3.7-12.9-8.5-25.4-14.5-37.4-3.8-8-8.2-15.6-13.3-22.8-1.8-2.7-3.7-5.4-5.6-7.9-8.8-14.4-19-23.3-30.7-40-7.6-12.8-12.9-26.9-15.4-41.6-3.2 8.9-5.7 18-7.4 27.3-12.1-12.2-22.5-20.8-28.9-26.7C319.4 24.2 323 9.1 323 9.1S264.7 74.2 289.9 142c8.7 23 23.8 43.1 43.4 57.9 24.4 20.2 50.8 36 64.7 76.6-11.2-21.3-28.1-39.2-48.8-51.5 6.2 14.7 9.4 30.6 9.3 46.5 0 61-49.6 110.5-110.6 110.4-8.3 0-16.5-.9-24.5-2.8-9.5-1.8-18.7-4.9-27.4-9.3-12.9-7.8-24-18.1-32.8-30.3l-.2-.3 2 .7c4.6 1.6 9.2 2.8 14 3.7 18.7 4 38.3 1.7 55.6-6.6 17.5-9.7 28-16.9 36.6-14h.2c8.4 2.7 15-5.5 9-14-10.4-13.4-27.4-20-44.2-17-17.5 2.5-33.5 15-56.4 2.9-1.5-.8-2.9-1.6-4.3-2.5-1.6-.9 4.9 1.3 3.4.3-5-2.5-9.8-5.4-14.4-8.6-.3-.3 3.5 1.1 3.1.8-5.9-4-11-9.2-15-15.2-4.1-7.4-4.5-16.4-1-24.1 2.1-3.8 5.4-6.9 9.3-8.7 3 1.5 4.8 2.6 4.8 2.6s-1.3-2.5-2.1-3.8c.3-.1.5 0 .8-.2 2.6 1.1 8.3 4 11.4 5.8 2.1 1.1 3.8 2.7 5.2 4.7 0 0 1-.5.3-2.7-1.1-2.7-2.9-5-5.4-6.6h.2c2.3 1.2 4.5 2.6 6.6 4.1 1.9-4.4 2.8-9.2 2.6-14 .2-2.6-.2-5.3-1.1-7.8-.8-1.6.5-2.2 1.9-.5-.2-1.3-.7-2.5-1.2-3.7v-.1s.8-1.1 1.2-1.5c1-1 2.1-1.9 3.4-2.7 7.2-4.5 14.8-8.4 22.7-11.6 6.4-2.8 11.7-4.9 12.8-5.6 1.6-1 3.1-2.2 4.5-3.5 5.3-4.5 9-10.8 10.2-17.7.1-.9.2-1.8.3-2.8v-1.5c-.9-3.5-6.9-6.1-38.4-9.1-11.1-1.8-20-10.1-22.5-21.1v.1c-.4 1.1-.9 2.3-1.3 3.5.4-1.2.8-2.3 1.3-3.5v-.2c6-15.7 16.8-29.1 30.8-38.3.8-.7-3.2.2-2.4-.5 2.7-1.3 5.4-2.5 8.2-3.5 1.4-.6-6-3.4-12.6-2.7-4 .2-8 1.2-11.7 2.8 1.6-1.3 6.2-3.1 5.1-3.1-8.4 1.6-16.5 4.7-23.9 9 0-.8.1-1.5.5-2.2-5.9 2.5-11 6.5-15 11.5.1-.9.2-1.8.2-2.7-2.7 2-5.2 4.3-7.3 6.9l-.1.1c-17.4-6.7-36.3-8.3-54.6-4.7l-.2-.1h.2c-3.8-3.1-7.1-6.7-9.7-10.9l-.2.1-.4-.2c-1.2-1.8-2.4-3.8-3.7-6-.9-1.6-1.8-3.4-2.7-5.2 0-.1-.1-.2-.2-.2-.4 0-.6 1.7-.9 1.3v-.1c-3.2-8.3-4.7-17.2-4.4-26.2l-.2.1c-5.1 3.5-9 8.6-11.1 14.5-.9 2.1-1.6 3.3-2.2 4.5v-.5c.1-1.1.6-3.3.5-3.1-.1.2-.2.3-.3.4-1.5 1.7-2.9 3.7-3.9 5.8-.9 1.9-1.7 3.9-2.3 5.9-.1.3 0-.3 0-1s.1-2 0-1.7l-.3.7c-6.7 14.9-10.9 30.8-12.4 47.1-.4 2.8-.6 5.6-.5 8.3v.2c-4.8 5.2-9 11-12.7 17.1-12.1 20.4-21.1 42.5-26.8 65.6 4-8.8 8.8-17.2 14.3-25.1C5.5 228.5 0 257.4 0 286.6c1.8-8.6 4.2-17 7-25.3-1.7 34.5 4.9 68.9 19.4 100.3 19.4 43.5 51.6 80 92.3 104.7 16.6 11.2 34.7 19.9 53.8 25.8 2.5.9 5.1 1.8 7.7 2.7-.8-.3-1.6-.7-2.4-1 22.6 6.8 46.2 10.3 69.8 10.3 83.7 0 111.3-31.9 113.8-35 4.1-3.7 7.5-8.2 9.9-13.3 1.6-.7 3.2-1.4 4.9-2.1l1-.5 1.9-.9c12.6-5.9 24.5-13.4 35.3-22.1 16.3-11.7 27.9-28.7 32.9-48.1 3-7.1 3.1-15 .4-22.2.9-1.4 1.7-2.8 2.7-4.3 18-28.9 28.2-61.9 29.6-95.9v-2.8c0-7.3-.6-14.5-1.9-21.6z"],"first-order":[448,512,[],"f2b0","M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z"],firstdraft:[384,512,[],"f3a1","M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z"],flickr:[448,512,[],"f16e","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z"],fly:[384,512,[],"f417","M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z"],"font-awesome":[448,512,[],"f2b4","M397.8 32H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-45.4 284.3c0 4.2-3.6 6-7.8 7.8-16.7 7.2-34.6 13.7-53.8 13.7-26.9 0-39.4-16.7-71.7-16.7-23.3 0-47.8 8.4-67.5 17.3-1.2.6-2.4.6-3.6 1.2V385c0 1.8 0 3.6-.6 4.8v1.2c-2.4 8.4-10.2 14.3-19.1 14.3-11.3 0-20.3-9-20.3-20.3V166.4c-7.8-6-13.1-15.5-13.1-26.3 0-18.5 14.9-33.5 33.5-33.5 18.5 0 33.5 14.9 33.5 33.5 0 10.8-4.8 20.3-13.1 26.3v18.5c1.8-.6 3.6-1.2 5.4-2.4 18.5-7.8 40.6-14.3 61.5-14.3 22.7 0 40.6 6 60.9 13.7 4.2 1.8 8.4 2.4 13.1 2.4 22.7 0 47.8-16.1 53.8-16.1 4.8 0 9 3.6 9 7.8v140.3z"],"font-awesome-alt":[448,512,[],"f35c","M397.8 67.8c7.8 0 14.3 6.6 14.3 14.3v347.6c0 7.8-6.6 14.3-14.3 14.3H50.2c-7.8 0-14.3-6.6-14.3-14.3V82.2c0-7.8 6.6-14.3 14.3-14.3h347.6m0-35.9H50.2C22.7 32 0 54.7 0 82.2v347.6C0 457.3 22.7 480 50.2 480h347.6c27.5 0 50.2-22.7 50.2-50.2V82.2c0-27.5-22.7-50.2-50.2-50.2zm-58.5 139.2c-6 0-29.9 15.5-52.6 15.5-4.2 0-8.4-.6-12.5-2.4-19.7-7.8-37-13.7-59.1-13.7-20.3 0-41.8 6.6-59.7 13.7-1.8.6-3.6 1.2-4.8 1.8v-17.9c7.8-6 12.5-14.9 12.5-25.7 0-17.9-14.3-32.3-32.3-32.3s-32.3 14.3-32.3 32.3c0 10.2 4.8 19.7 12.5 25.7v212.1c0 10.8 9 19.7 19.7 19.7 9 0 16.1-6 18.5-13.7V385c.6-1.8.6-3 .6-4.8V336c1.2 0 2.4-.6 3-1.2 19.7-8.4 43-16.7 65.7-16.7 31.1 0 43 16.1 69.3 16.1 18.5 0 36.4-6.6 52-13.7 4.2-1.8 7.2-3.6 7.2-7.8V178.3c1.8-4.1-2.3-7.1-7.7-7.1z"],"font-awesome-flag":[448,512,[],"f425","M444.373 359.424c0 7.168-6.144 10.24-13.312 13.312-28.672 12.288-59.392 23.552-92.16 23.552-46.08 0-67.584-28.672-122.88-28.672-39.936 0-81.92 14.336-115.712 29.696-2.048 1.024-4.096 1.024-6.144 2.048v77.824c0 21.405-16.122 34.816-33.792 34.816-19.456 0-34.816-15.36-34.816-34.816V102.4C12.245 92.16 3.029 75.776 3.029 57.344 3.029 25.6 28.629 0 60.373 0s57.344 25.6 57.344 57.344c0 18.432-8.192 34.816-22.528 45.056v31.744c4.124-1.374 58.768-28.672 114.688-28.672 65.27 0 97.676 27.648 126.976 27.648 38.912 0 81.92-27.648 92.16-27.648 8.192 0 15.36 6.144 15.36 13.312v240.64z"],fonticons:[448,512,[],"f280","M0 32v448h448V32H0zm167.4 196h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4zM364 414.7H261.3v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm-21.9-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6-21.9 24.2z"],"fonticons-fi":[384,512,[],"f3a2","M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z"],"fort-awesome":[448,512,[],"f286","M412 284h-24c-2.25 0-4 1.75-4 4v28h-32V160c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28h-32v-28c0-5.25-7-4-10.25-4v-33.25c7.25-1.75 15-3 22.5-3 9.501 0 18.251 3.75 27.5 3.75 4 0 24.25-1 24.25-7V64c0-2.25-1.75-4-4-4-4.5 0-13.25 3.75-21 3.75-8.499 0-18.25-3.75-28.501-3.75-7 0-14 1-20.75 2.5v-4.25c4.75-2.25 8-7.25 8-12.5 0-18.149-27.499-18.167-27.499 0 0 5.25 3.25 10.25 8 12.5V156c-3.25 0-10.25-1.25-10.25 4v28h-32v-28c0-2.25-1.75-4-4-4h-24c-2.25 0-4 1.75-4 4v28H96v-28c0-2.25-1.75-4-4-4H68c-2.25 0-4 1.75-4 4v156H32v-28c0-2.25-1.75-4-4-4H4c-2.25 0-4 1.75-4 4v192h160v-84c0-63.507 96-63.525 96 0v84h160V288c0-2.25-1.75-4-4-4zm-252-4.001c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999zm128 0c0 2.25-1.75 4-4 4h-24c-2.25 0-4-1.75-4-4V224c0-2.25 1.75-4 4-4h24c2.25 0 4 1.75 4 4v55.999z"],"fort-awesome-alt":[512,512,[],"f3a3","M211.7 241.1v51.7c0 2.1-1.6 3.7-3.7 3.7h-22.2c-2.1 0-3.7-1.6-3.7-3.7v-51.7c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7zm114.5-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm-29.1 263.2c-.9.1-1.7.3-2.6.4-1 .2-2.1.3-3.1.5-.9.1-1.8.3-2.8.4-1 .1-2 .3-3 .4-1 .1-2 .2-2.9.3-1 .1-1.9.2-2.9.3-1 .1-2.1.2-3.1.3-.9.1-1.8.2-2.7.2-1.1.1-2.3.1-3.4.2-.8 0-1.7.1-2.5.1-1.3.1-2.6.1-3.9.1-.7 0-1.4.1-2.1.1-2 0-4 .1-6 .1s-4 0-6-.1c-.7 0-1.4 0-2.1-.1-1.3 0-2.6-.1-3.9-.1-.8 0-1.7-.1-2.5-.1-1.1-.1-2.3-.1-3.4-.2-.9-.1-1.8-.1-2.7-.2-1-.1-2.1-.2-3.1-.3-1-.1-1.9-.2-2.9-.3-1-.1-2-.2-2.9-.3-1-.1-2-.2-3-.4-.9-.1-1.8-.3-2.8-.4-1-.1-2.1-.3-3.1-.5-.9-.1-1.7-.3-2.6-.4-65.6-10.9-122.5-47.7-160-99.4-.2-.2-.3-.5-.5-.7-.8-1.1-1.6-2.2-2.3-3.3-.3-.4-.6-.8-.8-1.2-.7-1.1-1.4-2.1-2.1-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.4-2.1-2-3.2-.3-.5-.6-.9-.9-1.4-.7-1.1-1.3-2.2-2-3.3-.2-.4-.5-.8-.7-1.2-2.4-4-4.6-8.1-6.8-12.2-.1-.2-.2-.3-.3-.5-.6-1.1-1.1-2.2-1.7-3.3-.3-.6-.6-1.1-.8-1.7-.5-1-1-2.1-1.5-3.1-.3-.7-.6-1.3-.9-2-.5-1-.9-2-1.4-3l-.9-2.1c-.4-1-.9-2-1.3-3-.3-.7-.6-1.5-.9-2.2l-1.2-3c-.3-.8-.6-1.5-.9-2.3-.4-1-.8-2-1.1-3-.3-.9-.6-1.8-1-2.8-.6-1.6-1.1-3.3-1.7-4.9-.3-.9-.6-1.8-.9-2.8-.3-.9-.5-1.8-.8-2.7-.3-.9-.6-1.9-.8-2.8-.3-.9-.5-1.8-.8-2.7-.3-1-.5-1.9-.8-2.9-.2-.9-.5-1.8-.7-2.7-.3-1-.5-2-.7-3-.2-.9-.4-1.7-.6-2.6-.2-1.1-.5-2.2-.7-3.2-.2-.8-.3-1.6-.5-2.4-.3-1.3-.5-2.7-.8-4-.1-.6-.2-1.1-.3-1.7l-.9-5.7c-.1-.6-.2-1.3-.3-1.9-.2-1.3-.4-2.6-.5-3.9-.1-.8-.2-1.5-.3-2.3-.1-1.2-.3-2.4-.4-3.6-.1-.8-.2-1.6-.2-2.4-.1-1.2-.2-2.4-.3-3.5-.1-.8-.1-1.6-.2-2.4-.1-1.2-.2-2.4-.2-3.7 0-.8-.1-1.5-.1-2.3-.1-1.3-.1-2.7-.2-4 0-.7 0-1.3-.1-2 0-2-.1-4-.1-6 0-53.5 16.9-103 45.8-143.6 2.3-3.2 4.7-6.4 7.1-9.5 4.9-6.2 10.1-12.3 15.6-18 2.7-2.9 5.5-5.7 8.4-8.4 2.9-2.7 5.8-5.4 8.8-8 4.5-3.9 9.1-7.6 13.9-11.2 1.6-1.2 3.2-2.4 4.8-3.5C140 34.2 171.7 20.1 206 13c16.1-3.3 32.9-5 50-5s33.8 1.7 50 5c34.3 7 66 21.1 93.6 40.7 1.6 1.2 3.2 2.3 4.8 3.5 4.8 3.6 9.4 7.3 13.9 11.2 12 10.4 23 21.9 32.8 34.4 2.5 3.1 4.8 6.3 7.1 9.5C487.1 153 504 202.5 504 256c0 2 0 4-.1 6 0 .7 0 1.3-.1 2 0 1.3-.1 2.7-.2 4 0 .8-.1 1.5-.1 2.3-.1 1.2-.1 2.4-.2.7-.1.8-.1 1.6-.2 2.4-.1 1.2-.2 2.4-.3 3.5-.1.8-.2 1.6-.2 2.4-.1 1.2-.3 2.4-.4 3.6-.1.8-.2 1.5-.3 2.3-.2 1.3-.4 2.6-.5 3.9-.1.6-.2 1.3-.3 1.9l-.9 5.7c-.1.6-.2 1.1-.3 1.7-.2 1.3-.5 2.7-.8 4-.2.8-.3 1.6-.5 2.4-.2 1.1-.5 2.2-.7 3.2-.2.9-.4 1.7-.6 2.6-.2 1-.5 2-.7 3-.2.9-.5 1.8-.7 2.7-.3 1-.5 1.9-.8 2.9-.2.9-.5 1.8-.8 2.7-.3.9-.6 1.9-.8 2.8-.3.9-.5 1.8-.8 2.7-.3.9-.6 1.8-.9 2.8-.5 1.6-1.1 3.3-1.7 4.9-.3.9-.6 1.8-1 2.8-.4 1-.7 2-1.1 3-.3.8-.6 1.5-.9 2.3l-1.2 3c-.3.7-.6 1.5-.9 2.2-.4 1-.8 2-1.3 3l-.9 2.1c-.4 1-.9 2-1.4 3-.3.7-.6 1.3-.9 2-.5 1-1 2.1-1.5 3.1-.3.6-.6 1.1-.8 1.7-.6 1.1-1.1 2.2-1.7 3.3-.1.2-.2.3-.3.5-2.2 4.1-4.4 8.2-6.8 12.2-.2.4-.5.8-.7 1.2-.7 1.1-1.3 2.2-2 3.3-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2 3.2-.3.5-.6.9-.9 1.4-.7 1.1-1.4 2.1-2.1 3.2-.3.4-.6.8-.8 1.2-.8 1.1-1.5 2.2-2.3 3.3-.2.2-.3.5-.5.7-37.6 54.7-94.5 91.4-160.1 102.4zm117.3-86.2c13-13 24.2-27.4 33.6-42.9v-71.3c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7V326h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7H304c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-4.8-6.5-3.7-9.5-3.7v-30.7c6.7-1.6 13.8-2.8 20.8-2.8 8.8 0 16.8 3.5 25.4 3.5 3.7 0 22.4-.9 22.4-6.5V93.4c0-2.1-1.6-3.7-3.7-3.7-4.2 0-12.2 3.5-19.4 3.5-7.9 0-16.9-3.5-26.3-3.5-6.5 0-12.9.9-19.2 2.3v-3.9c4.4-2.1 7.4-6.7 7.4-11.5 0-16.8-25.4-16.8-25.4 0 0 4.8 3 9.5 7.4 11.5v90.2c-3 0-9.5-1.1-9.5 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.2c-2.1 0-3.7 1.6-3.7 3.7v25.9h-29.5V182c0-2.1-1.6-3.7-3.7-3.7h-22.1c-2.1 0-3.7 1.6-3.7 3.7v144H93.5v-25.8c0-2.1-1.6-3.7-3.7-3.7H67.7c-2.1 0-3.7 1.6-3.7 3.7v71.3c9.4 15.5 20.6 29.9 33.6 42.9 20.6 20.6 44.5 36.7 71.2 48 13.9 5.9 28.2 10.3 42.9 13.2v-75.8c0-58.6 88.6-58.6 88.6 0v75.8c14.7-2.9 29-7.4 42.9-13.2 26.7-11.3 50.6-27.4 71.2-48"],forumbee:[448,512,[],"f211","M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z"],foursquare:[368,512,[],"f180","M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z"],"free-code-camp":[576,512,[],"f2c5","M69.3 144.5c-41 68.5-36.4 163 1 227C92.5 409.7 120 423.9 120 438c0 6.8-6 13-12.8 13C87.7 451 8 375.5 8 253.2c0-111.5 78-186 97.1-186 6 0 14.9 4.8 14.9 11.1 0 12.7-28.3 28.6-50.7 66.2zm195.8 213.8c4.5 1.8 12.3 5.2 12.3-1.2 0-2.7-2.2-2.9-4.3-3.6-8.5-3.4-14-7.7-19.1-15.2-8.2-12.1-10.1-24.2-10.1-38.6 0-32.1 44.2-37.9 44.2-70 0-12.3-7.7-15.9-7.7-19.3 0-2.2.7-2.2 2.9-2.2 8 0 19.1 13.3 22.5 19.8 2.2 4.6 2.4 6 2.4 11.1 0 7-.7 14.2-.7 21.3 0 27 31.9 19.8 31.9 6.8 0-6-3.6-11.6-3.6-17.4 0-.7 0-1.2.7-1.2 3.4 0 9.4 7.7 11.1 10.1 5.8 8.9 8.5 20.8 8.5 31.4 0 32.4-29.5 49-29.5 56 0 1 2.9 7.7 12.1 1.9 29.7-15.1 53.1-47.6 53.1-89.8 0-33.6-8.7-57.7-32.1-82.6-3.9-4.1-16.4-16.9-22.5-16.9-8.2 0 7.2 18.6 7.2 31.2 0 7.2-4.8 12.3-12.3 12.3-11.6 0-14.5-25.4-15.9-33.3-5.8-33.8-12.8-58.2-46.4-74.1-10.4-5-36.5-11.8-36.5-2.2 0 2.4 2.7 4.1 4.6 5.1 9.2 5.6 19.6 21.4 19.6 38.2 0 46.1-57.7 88.2-57.7 136.2-.2 40.3 28.1 72.6 65.3 86.2zM470.4 67c-6 0-14.4 6.5-14.4 12.6 0 8.7 12.1 19.6 17.6 25.4 81.6 85.1 78.6 214.3 17.6 291-7 8.9-35.3 35.3-35.3 43.5 0 5.1 8.2 11.4 13.2 11.4 25.4 0 98.8-80.8 98.8-185.7C568 145.9 491.8 67 470.4 67zm-42.3 323.1H167c-9.4 0-15.5 7.5-15.5 16.4 0 8.5 7 15.5 15.5 15.5h261.1c9.4 0 11.9-7.5 11.9-16.4 0-8.5-3.5-15.5-11.9-15.5z"],freebsd:[448,512,[],"f3a4","M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z"],"get-pocket":[448,512,[],"f265","M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z"],gg:[512,512,[],"f260","M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z"],"gg-circle":[512,512,[],"f261","M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z"],git:[448,512,[],"f1d3","M18.8 221.7c0 25.3 16.2 60 41.5 68.5v1c-18.8 8.3-24 50.6 1 65.8v1C34 367 16 384.3 16 414.2c0 51.5 48.8 65.8 91.5 65.8 52 0 90.7-18.7 90.7-76 0-70.5-101-44.5-101-82.8 0-13.5 7.2-18.7 19.7-21.3 41.5-7.7 67.5-40 67.5-82.2 0-7.3-1.5-14.2-4-21 6.7-1.5 13.2-3.3 19.7-5.5v-50.5c-17.2 6.8-35.7 11.8-54.5 11.8-53.8-31-126.8 1.3-126.8 69.2zm87.7 163.8c17 0 41.2 3 41.2 25 0 21.8-19.5 26.3-37.7 26.3-17.3 0-43.3-2.7-43.3-25.2.1-22.3 22.1-26.1 39.8-26.1zM103.3 256c-22 0-31.3-13-31.3-33.8 0-49.3 61-48.8 61-.5 0 20.3-8 34.3-29.7 34.3zM432 305.5v49c-13.3 7.3-30.5 9.8-45.5 9.8-53.5 0-59.8-42.2-59.8-85.7v-87.7h.5v-1c-7 0-7.3-1.6-24 1v-47.5h24c0-22.3.3-31-1.5-41.2h56.7c-2 13.8-1.5 27.5-1.5 41.2h51v47.5s-19.3-1-51-1V281c0 14.8 3.3 32.8 21.8 32.8 9.8 0 21.3-2.8 29.3-8.3zM286 68.7c0 18.7-14.5 36.2-33.8 36.2-19.8 0-34.5-17.2-34.5-36.2 0-19.3 14.5-36.7 34.5-36.7C272 32 286 50 286 68.7zm-6.2 74.5c-1.8 14.6-1.6 199.8 0 217.8h-55.5c1.6-18.1 1.8-203 0-217.8h55.5z"],"git-square":[448,512,[],"f1d2","M140.1 348.5c12.1 0 29.5 2.1 29.5 17.9 0 15.5-13.9 18.8-27 18.8-12.3 0-30.9-2-30.9-18s15.7-18.7 28.4-18.7zm-24.7-116.6c0 14.8 6.6 24.1 22.3 24.1 15.5 0 21.2-10 21.2-24.5.1-34.4-43.5-34.8-43.5.4zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-241 93.7c-12.3 4.8-25.5 8.4-38.9 8.4-38.5-22.1-90.7.9-90.7 49.5 0 18 11.6 42.9 29.6 48.9v.7c-13.4 5.9-17.1 36.1.7 47v.7c-19.5 6.4-32.3 18.8-32.3 40.2 0 36.8 34.8 47 65.4 47 37.1 0 64.8-13.4 64.8-54.3 0-50.4-72.1-31.8-72.1-59.1 0-9.6 5.2-13.4 14.1-15.2 29.6-5.5 48.2-28.6 48.2-58.7 0-5.2-1.1-10.2-2.9-15 4.8-1.1 9.5-2.3 14.1-3.9v-36.2zm56.8 1.8h-39.6c1.3 10.6 1.1 142.6 0 155.5h39.6c-1.1-12.8-1.2-145.1 0-155.5zm4.5-53.3c0-13.4-10-26.2-24.1-26.2-14.3 0-24.6 12.5-24.6 26.2 0 13.6 10.5 25.9 24.6 25.9 13.7 0 24.1-12.5 24.1-25.9zm104.3 53.3h-36.4c0-9.8-.4-19.6 1.1-29.5h-40.5c1.3 7.3 1.1 13.6 1.1 29.5h-17.1v33.9c11.9-1.9 12.1-.7 17.1-.7v.7h-.4v62.7c0 31.1 4.5 61.2 42.7 61.2 10.7 0 23-1.8 32.5-7v-35c-5.7 3.9-13.9 5.9-20.9 5.9-13.2 0-15.5-12.9-15.5-23.4v-65.2c22.7 0 36.4.7 36.4.7v-33.8z"],github:[496,512,[],"f09b","M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"],"github-alt":[480,512,[],"f113","M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"],"github-square":[448,512,[],"f092","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z"],gitkraken:[592,512,[],"f3a6","M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z"],gitlab:[512,512,[],"f296","M29.782 199.732L256 493.714 8.074 309.699c-6.856-5.142-9.712-13.996-7.141-21.993l28.849-87.974zm75.405-174.806c-3.142-8.854-15.709-8.854-18.851 0L29.782 199.732h131.961L105.187 24.926zm56.556 174.806L256 493.714l94.257-293.982H161.743zm349.324 87.974l-28.849-87.974L256 493.714l247.926-184.015c6.855-5.142 9.711-13.996 7.141-21.993zm-85.404-262.78c-3.142-8.854-15.709-8.854-18.851 0l-56.555 174.806h131.961L425.663 24.926z"],gitter:[384,512,[],"f426","M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z"],glide:[448,512,[],"f2a5","M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z"],"glide-g":[448,512,[],"f2a6","M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z"],gofore:[400,512,[],"f3a7","M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z"],goodreads:[448,512,[],"f3a8","M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z"],"goodreads-g":[384,512,[],"f3a9","M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z"],google:[488,512,[],"f1a0","M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"],"google-drive":[512,512,[],"f3aa","M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"],"google-play":[512,512,[],"f3ab","M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"],"google-plus":[496,512,[],"f2b3","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124 124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9 0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1 70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8 121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z"],"google-plus-g":[640,512,[],"f0d5","M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z"],"google-plus-square":[448,512,[],"f0d4","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z"],"google-wallet":[448,512,[],"f1ee","M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z"],gratipay:[496,512,[],"f184","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z"],grav:[512,512,[],"f2d6","M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z"],gripfire:[384,512,[],"f3ac","M171.8 503.8c0-5.3 4.8-12.2 4.8-22.3 0-15.2-13-39.9-78.1-86.6C64.2 365.8 32 336.4 32 286.6 32 171.9 179.1 110.1 179.1 18c0-3.3-.2-6.7-.6-10 5.1 2.4 39.1 43.3 39.1 90.4 0 80.5-105.1 129.2-105.1 203 0 26.9 16.6 47.2 32.6 69.5 22.5 30.2 44.2 56.9 44.2 86.5-.1 14.5-4.4 29.7-17.5 46.4zm146-241.4c1.5 8.4 2.2 16.6 2.2 24.6 0 51.8-29.4 97.5-67.3 136.8-1 1-2.2 2.4-3.2 2.4-3.6 0-35.5-41.6-35.5-53.2 0 0 41.8-55.7 41.8-96.9 0-10.8-2.7-21.7-9.1-33.4-1.5 32.3-55.7 87.7-58.1 87.7-2.7 0-17.9-22-17.9-42.1 0-5.3 1-10.7 3.2-15.8 2.4-5.5 56.6-72 56.6-116.7 0-6.2-1-12-3.4-17.1l-4-7.2c16.7 6.5 82.6 64.1 94.7 130.9"],grunt:[384,512,[],"f3ad","M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm79.2 233.7c2.2 2.3 1.5 5.3.9 6.8-1.1 2.7-5.5 11.6-13 19.8-2.7 2.9-6.6 4.6-11 4.6-4.3 0-8.7-1.6-11.8-4.3-2.3-2.1-10.2-9.5-13.7-18.6-1.3-3.4-1-6.1.9-8.1 1.3-1.3 4-2.9 9.5-2.9H160c4.1 0 7 .9 8.8 2.7zm62.9-187.9c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm17.8-8.8c7.5-11.4 25.4-26 44.9-37 3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6-.1.1 0 0 0 0zM263 421.4c1.9 1.9 2.2 4.6.9 7.9-3.5 8.9-11.4 16.1-13.7 18.1-3.1 2.6-7.4 4.2-11.8 4.2s-8.3-1.6-11-4.5c-7.5-8-12-16.7-13-19.3-.6-1.5-1.3-4.4.9-6.7 1.7-1.8 4.7-2.7 8.9-2.7h29.4c5.4.1 8.1 1.7 9.4 3zm-98.3-251.5c9.9 6 18.8 8.1 27.3 8.3 8.5-.2 17.4-2.3 27.3-8.3 0 0-14.5 17.7-27.2 17.8h-.2c-12.7-.2-27.2-17.8-27.2-17.8zm184.5 147.4c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59z"],gulp:[256,512,[],"f3ae","M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z"],"hacker-news":[448,512,[],"f1d4","M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],"hacker-news-square":[448,512,[],"f3af","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z"],"hire-a-helper":[512,512,[],"f3b0","M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z"],hooli:[640,512,[],"f427","M508.4 352h57.9V156.7L508.4 184v168zm73.7-110.5V352H640V241.5h-57.9zm-250.7-8.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.9 110.9v-31c-48.8-54.6-39-76.1-35.3-79.2 13.5-11.4 37.5-8 64.4 2.1L65.2 184v63.3c13.1 14.7 30.5 31.5 53.5 50.4l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zm-39.7 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm185.7-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6 0 18.7-1.4 34.3 16.8 52.5 18.2 18.2 50.4 17.1 50.4 17.1s32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5-8.9 0-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9 3.4 0 10.7 2.1 10.7 10.9v40.4zm173.5-73c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zM144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8v16zm-21.4 0v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.5-21.7-38.5-31.5V352h57.9zm59.7.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3v5.3l-19.4.8z"],hotjar:[448,512,[],"f3b1","M414.9 161.5C340.2 29 121.1 0 121.1 0S222.2 110.4 93 197.7C11.3 252.8-21 324.4 14 402.6c26.8 59.9 83.5 84.3 144.6 93.4-29.2-55.1-6.6-122.4-4.1-129.6 57.1 86.4 165 0 110.8-93.9 71 15.4 81.6 138.6 27.1 215.5 80.5-25.3 134.1-88.9 148.8-145.6 15.5-59.3 3.7-127.9-26.3-180.9z"],houzz:[320,512,[],"f27c","M12.2 256L160 341.1 12.2 426.6V256M160 512l147.8-85.4V256L160 341.1V512zm0-512L12.2 85.4V256L160 170.6V0zm0 170.6L307.8 256V85.4L160 170.6z"],html5:[384,512,[],"f13b","M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z"],hubspot:[512,512,[],"f3b2","M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z"],imdb:[448,512,[],"f2d8","M350.5 288.7c0 5.4 1.6 14.4-6.2 14.4-1.6 0-3-.8-3.8-2.4-2.2-5.1-1.1-44.1-1.1-44.7 0-3.8-1.1-12.7 4.9-12.7 7.3 0 6.2 7.3 6.2 12.7v32.7zM265 229.9c0-9.7 1.6-16-10.3-16v83.7c12.2.3 10.3-8.7 10.3-18.4v-49.3zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM21.3 228.8c-.1.1-.2.3-.3.4h.3v-.4zM97 192H64v127.8h33V192zm113.3 0h-43.1l-7.6 59.9c-2.7-20-5.4-40.1-8.7-59.9h-42.8v127.8h29v-84.5l12.2 84.5h20.6l11.6-86.4v86.4h28.7V192zm86.3 45.3c0-8.1.3-16.8-1.4-24.4-4.3-22.5-31.4-20.9-49-20.9h-24.6v127.8c86.1.1 75 6 75-82.5zm85.9 17.3c0-17.3-.8-30.1-22.2-30.1-8.9 0-14.9 2.7-20.9 9.2V192h-31.7v127.8h29.8l1.9-8.1c5.7 6.8 11.9 9.8 20.9 9.8 19.8 0 22.2-15.2 22.2-30.9v-36z"],instagram:[448,512,[],"f16d","M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"],"internet-explorer":[512,512,[],"f26b","M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z"],ioxhost:[640,512,[],"f208","M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z"],itunes:[448,512,[],"f3b4","M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z"],"itunes-note":[384,512,[],"f3b5","M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z"],jenkins:[512,512,[],"f3b6","M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z"],joget:[496,512,[],"f3b7","M227.5 468.7c-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1M66.1 143.9C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9-55.5-1.4-81.7-20.8-58.5-48.2 23.2-27.4 51.1-40.7 68.9-51.2 17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1m-29.2-18c-71.9 116.6-35.6 269.3 81 341.2 116.6 71.9 269.3 35.6 341.2-80.9 71.9-116.6 35.6-269.4-81-341.2-40.5-25.1-85.5-37-129.9-37C165 8 83.8 49.9 36.9 125.9m244.4 110.4c-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5c10.5-6.4 31.9-14 13.4-24.6-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6"],joomla:[448,512,[],"f1aa","M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z"],js:[448,512,[],"f3b8","M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],"js-square":[512,512,[],"f3b9","M432 32H80c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM275.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L400 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z"],jsfiddle:[576,512,[],"f1cc","M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z"],keycdn:[512,512,[],"f3ba","M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160"],kickstarter:[448,512,[],"f3bb","M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z"],"kickstarter-k":[384,512,[],"f3bc","M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z"],laravel:[640,512,[],"f3bd","M637.5 204.7c-4.2-4.8-62.8-78.1-73.1-90.5-10.3-12.4-15.4-10.2-21.7-9.3s-80.5 13.4-89.1 14.8c-8.6 1.5-14 4.9-8.7 12.3 4.7 6.6 53.4 75.7 64.2 90.9l-193.7 46.4L161.2 11.7C155.1 2.6 153.8-.6 139.8.1 125.9.7 19 9.6 11.4 10.2c-7.6.6-16 4-8.4 22s129 279.6 132.4 287.2c3.4 7.6 12.2 20 32.8 15 21.1-5.1 94.3-24.2 134.3-34.7 21.1 38.3 64.2 115.9 72.2 127 10.6 14.9 18 12.4 34.3 7.4 12.8-3.9 199.6-71.1 208-74.5 8.4-3.5 13.6-5.9 7.9-14.4-4.2-6.2-53.5-72.2-79.3-106.8 17.7-4.7 80.6-21.4 87.3-23.3 7.8-1.8 8.9-5.7 4.6-10.4zm-352.2 72c-2.3.5-110.8 26.5-116.6 27.8-5.8 1.3-5.8.7-6.5-1.3-.7-2-129-266.7-130.8-270-1.8-3.3-1.7-5.9 0-5.9s102.5-9 106-9.2c3.6-.2 3.2.6 4.5 2.8 0 0 142.2 245.4 144.6 249.7 2.6 4.3 1.1 5.6-1.2 6.1zm306 57.3c1.7 2.7 3.5 4.5-2 6.4-5.4 2-183.7 62.1-187.1 63.6-3.5 1.5-6.2 2-10.6-4.5-4.5-6.4-62.4-106.8-62.4-106.8l188.8-49c4.7-1.5 6.2-2.5 9.2 2.2 2.9 4.7 62.4 85.4 64.1 88.1zm12.1-134.1c-4.2.9-73.6 18.1-73.6 18.1l-56.7-77.8c-1.6-2.2-2.9-4.5 1.1-5s68.4-12.2 71.3-12.8c2.9-.7 5.4-1.5 9 3.4 3.6 4.9 52.6 67 54.5 69.4 1.8 2.3-1.4 3.8-5.6 4.7z"],lastfm:[512,512,[],"f202","M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"],"lastfm-square":[448,512,[],"f203","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z"],leanpub:[576,512,[],"f212","M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z"],less:[640,512,[],"f41d","M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z"],line:[448,512,[],"f3c0","M272.1 204.2v71.1c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.1 0-2.1-.6-2.6-1.3l-32.6-44v42.2c0 1.8-1.4 3.2-3.2 3.2h-11.4c-1.8 0-3.2-1.4-3.2-3.2v-71.1c0-1.8 1.4-3.2 3.2-3.2H219c1 0 2.1.5 2.6 1.4l32.6 44v-42.2c0-1.8 1.4-3.2 3.2-3.2h11.4c1.8-.1 3.3 1.4 3.3 3.1zm-82-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 1.8 1.4 3.2 3.2 3.2h11.4c1.8 0 3.2-1.4 3.2-3.2v-71.1c0-1.7-1.4-3.2-3.2-3.2zm-27.5 59.6h-31.1v-56.4c0-1.8-1.4-3.2-3.2-3.2h-11.4c-1.8 0-3.2 1.4-3.2 3.2v71.1c0 .9.3 1.6.9 2.2.6.5 1.3.9 2.2.9h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.7-1.4-3.2-3.1-3.2zM332.1 201h-45.7c-1.7 0-3.2 1.4-3.2 3.2v71.1c0 1.7 1.4 3.2 3.2 3.2h45.7c1.8 0 3.2-1.4 3.2-3.2v-11.4c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2V234c0-1.8-1.4-3.2-3.2-3.2H301v-12h31.1c1.8 0 3.2-1.4 3.2-3.2v-11.4c-.1-1.7-1.5-3.2-3.2-3.2zM448 113.7V399c-.1 44.8-36.8 81.1-81.7 81H81c-44.8-.1-81.1-36.9-81-81.7V113c.1-44.8 36.9-81.1 81.7-81H367c44.8.1 81.1 36.8 81 81.7zm-61.6 122.6c0-73-73.2-132.4-163.1-132.4-89.9 0-163.1 59.4-163.1 132.4 0 65.4 58 120.2 136.4 130.6 19.1 4.1 16.9 11.1 12.6 36.8-.7 4.1-3.3 16.1 14.1 8.8 17.4-7.3 93.9-55.3 128.2-94.7 23.6-26 34.9-52.3 34.9-81.5z"],linkedin:[448,512,[],"f08c","M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"],"linkedin-in":[448,512,[],"f0e1","M100.3 480H7.4V180.9h92.9V480zM53.8 140.1C24.1 140.1 0 115.5 0 85.8 0 56.1 24.1 32 53.8 32c29.7 0 53.8 24.1 53.8 53.8 0 29.7-24.1 54.3-53.8 54.3zM448 480h-92.7V334.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V480h-92.8V180.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V480z"],linode:[448,512,[],"f2b8","M437.4 226.3c-.3-.9-.9-1.4-1.4-2l-70-38.6c-.9-.6-2-.6-3.1 0l-58.9 36c-.9.6-1.4 1.7-1.4 2.6l-.9 31.4-24-16c-.9-.6-2.3-.6-3.1 0L240 260.9l-1.4-35.1c0-.9-.6-2-1.4-2.3l-36-24.3 33.7-17.4c1.1-.6 1.7-1.7 1.7-2.9l-5.7-132.3c0-.9-.9-2-1.7-2.6L138.6.3c-.9-.3-1.7-.3-2.3-.3L12.6 38.6c-1.4.6-2.3 2-2 3.7L38 175.4c.9 3.4 34 27.4 38.6 30.9l-26.9 12.9c-1.4.9-2 2.3-1.7 3.4l20.6 100.3c.6 2.9 23.7 23.1 27.1 26.3l-17.4 10.6c-.9.6-1.7 2-1.4 3.1 1.4 7.1 15.4 77.7 16.9 79.1l65.1 69.1c.6.6 1.4.6 2.3.9.6 0 1.1-.3 1.7-.6l83.7-66.9c.9-.6 1.1-1.4 1.1-2.3l-2-46 28 23.7c1.1.9 2.9.9 4 0l66.9-53.4c.9-.6 1.1-1.4 1.1-2.3l2.3-33.4 20.3 14c1.1.9 2.6.9 3.7 0l54.6-43.7c.6-.3 1.1-1.1 1.1-2 .9-6.5 10.3-70.8 9.7-72.8zm-204.8 4.8l4 92.6-90.6 61.2-14-96.6 100.6-57.2zm-7.7-180l5.4 126-106.6 55.4L104 97.7l120.9-46.6zM44 173.1L18 48l79.7 49.4 19.4 132.9L44 173.1zm30.6 147.8L55.7 230l70 58.3 13.7 93.4-64.8-60.8zm24.3 117.7l-13.7-67.1 61.7 60.9 9.7 67.4-57.7-61.2zm64.5 64.5l-10.6-70.9 85.7-61.4 3.1 70-78.2 62.3zm82-115.1c0-3.4.9-22.9-2-25.1l-24.3-20 22.3-14.9c2.3-1.7 1.1-5.7 1.1-8l29.4 22.6.6 68.3-27.1-22.9zm94.3-25.4l-60.9 48.6-.6-68.6 65.7-46.9-4.2 66.9zm27.7-25.7l-19.1-13.4 2-34c.3-.9-.3-2-1.1-2.6L308 259.7l.6-30 64.6 40.6-5.8 66.6zm54.6-39.8l-48.3 38.3 5.7-65.1 51.1-36.6-8.5 63.4z"],linux:[448,512,[],"f17c","M196.1 123.6c-.2-1.4 1.9-2.3 3.2-2.9 1.7-.7 3.9-1 5.5-.1.4.2.8.7.6 1.1-.4 1.2-2.4 1-3.5 1.6-1 .5-1.8 1.7-3 1.7-1 .1-2.7-.4-2.8-1.4zm24.7-.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm214.7 310.2c-.5 8.2-6.5 13.8-13.9 18.3-14.9 9-37.3 15.8-50.9 32.2l-2.6-2.2 2.6 2.2c-14.2 16.9-31.7 26.6-48.3 27.9-16.5 1.3-32-6.3-40.3-23v-.1c-1.1-2.1-1.9-4.4-2.5-6.7-21.5 1.2-40.2-5.3-55.1-4.1-22 1.2-35.8 6.5-48.3 6.6-4.8 10.6-14.3 17.6-25.9 20.2-16 3.7-36.1 0-55.9-10.4l1.6-3-1.6 3c-18.5-9.8-42-8.9-59.3-12.5-8.7-1.8-16.3-5-20.1-12.3-3.7-7.3-3-17.3 2.2-31.7 1.7-5.1.4-12.7-.8-20.8-.6-3.9-1.2-7.9-1.2-11.8 0-4.3.7-8.5 2.8-12.4 4.5-8.5 11.8-12.1 18.5-14.5 6.7-2.4 12.8-4 17-8.3 5.2-5.5 10.1-14.4 16.6-20.2-2.6-17.2.2-35.4 6.2-53.3 12.6-37.9 39.2-74.2 58.1-96.7 16.1-22.9 20.8-41.3 22.5-64.7C158 103.4 132.4-.2 234.8 0c80.9.1 76.3 85.4 75.8 131.3-.3 30.1 16.3 50.5 33.4 72 15.2 18 35.1 44.3 46.5 74.4 9.3 24.6 12.9 51.8 3.7 79.1 1.4.5 2.8 1.2 4.1 2 1.4.8 2.7 1.8 4 2.9 6.6 5.6 8.7 14.3 10.5 22.4 1.9 8.1 3.6 15.7 7.2 19.7 11.1 12.4 15.9 21.5 15.5 29.7zM220.8 109.1c3.6.9 8.9 2.4 13 4.4-2.1-12.2 4.5-23.5 11.8-23 8.9.3 13.9 15.5 9.1 27.3-.8 1.9-2.8 3.4-3.9 4.6 6.7 2.3 11 4.1 12.6 4.9 7.9-9.5 10.8-26.2 4.3-40.4-9.8-21.4-34.2-21.8-44 .4-3.2 7.2-3.9 14.9-2.9 21.8zm-46.2 18.8c7.8-5.7 6.9-4.7 5.9-5.5-8-6.9-6.6-27.4 1.8-28.1 6.3-.5 10.8 10.7 9.6 19.6 3.1-2.1 6.7-3.6 10.2-4.6 1.7-19.3-9-33.5-19.1-33.5-18.9 0-24 37.5-8.4 52.1zm-9.4 20.9c1.5 4.9 6.1 10.5 14.7 15.3 7.8 4.6 12 11.5 20 15 2.6 1.1 5.7 1.9 9.6 2.1 18.4 1.1 27.1-11.3 38.2-14.9 11.7-3.7 20.1-11 22.7-18.1 3.2-8.5-2.1-14.7-10.5-18.2-11.3-4.9-16.3-5.2-22.6-9.3-10.3-6.6-18.8-8.9-25.9-8.9-14.4 0-23.2 9.8-27.9 14.2-.5.5-7.9 5.9-14.1 10.5-4.2 3.3-5.6 7.4-4.2 12.3zm-33.5 252.8L112.1 366c-6.8-9.2-13.8-14.8-21.9-16-7.7-1.2-12.6 1.4-17.7 6.9-4.8 5.1-8.8 12.3-14.3 18-7.8 6.5-9.3 6.2-19.6 9.9-6.3 2.2-11.3 4.6-14.8 11.3-2.7 5-2.1 12.2-.9 20 1.2 7.9 3 16.3.6 23.9v.2c-5 13.7-5 21.7-2.6 26.4 7.9 15.4 46.6 6.1 76.5 21.9 31.4 16.4 72.6 17.1 75.3-18 2.1-20.5-31.5-49-41-68.9zm153.9 35.8c3.2-11 6.3-21.3 6.8-29 .8-15.2 1.6-28.7 4.4-39.9 3.1-12.6 9.3-23.1 21.4-27.3 2.3-21.1 18.7-21.1 38.3-12.5 18.9 8.5 26 16 22.8 26.1 1 0 2-.1 4.2 0 5.2-16.9-14.3-28-30.7-34.8 2.9-12 2.4-24.1-.4-35.7-6-25.3-22.6-47.8-35.2-59-2.3-.1-2.1 1.9 2.6 6.5 11.6 10.7 37.1 49.2 23.3 84.9-3.9-1-7.6-1.5-10.9-1.4-5.3-29.1-17.5-53.2-23.6-64.6-11.5-21.4-29.5-65.3-37.2-95.7-4.5 6.4-12.4 11.9-22.3 15-4.7 1.5-9.7 5.5-15.9 9-13.9 8-30 8.8-42.4-1.2-4.5-3.6-8-7.6-12.6-10.3-1.6-.9-5.1-3.3-6.2-4.1-2 37.8-27.3 85.3-39.3 112.7-8.3 19.7-13.2 40.8-13.8 61.5-21.8-29.1-5.9-66.3 2.6-82.4 9.5-17.6 11-22.5 8.7-20.8-8.6 14-22 36.3-27.2 59.2-2.7 11.9-3.2 24 .3 35.2 3.5 11.2 11.1 21.5 24.6 29.9 0 0 24.8 14.3 38.3 32.5 7.4 10 9.7 18.7 7.4 24.9-2.5 6.7-9.6 8.9-16.7 8.9 4.8 6 10.3 13 14.4 19.6 37.6 25.7 82.2 15.7 114.3-7.2zM415 408.5c-10-11.3-7.2-33.1-17.1-41.6-6.9-6-13.6-5.4-22.6-5.1-7.7 8.8-25.8 19.6-38.4 16.3-11.5-2.9-18-16.3-18.8-29.5-.3.2-.7.3-1 .5-7.1 3.9-11.1 10.8-13.7 21.1-2.5 10.2-3.4 23.5-4.2 38.7-.7 11.8-6.2 26.4-9.9 40.6-3.5 13.2-5.8 25.2-1.1 36.3 7.2 14.5 19.5 20.4 33.7 19.3 14.2-1.1 30.4-9.8 43.6-25.5 22-26.6 62.3-29.7 63.2-46.5.3-5.1-3.1-13-13.7-24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4 3.9-3.4 5.9-6.3 3.1-6.6-2.8-.3-2.6 2.6-6 5.1-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2-10.4 0-18.7-4.8-24.9-9.7-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z"],lyft:[512,512,[],"f3c3","M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z"],magento:[448,512,[],"f3c4","M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z"],maxcdn:[512,512,[],"f136","M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z"],medapps:[320,512,[],"f3c6","M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z"],medium:[448,512,[],"f23a","M0 32v448h448V32H0zm372.2 106.1l-24 23c-2.1 1.6-3.1 4.2-2.7 6.7v169.3c-.4 2.6.6 5.2 2.7 6.7l23.5 23v5.1h-118V367l24.3-23.6c2.4-2.4 2.4-3.1 2.4-6.7V199.8l-67.6 171.6h-9.1L125 199.8v115c-.7 4.8 1 9.7 4.4 13.2l31.6 38.3v5.1H71.2v-5.1l31.6-38.3c3.4-3.5 4.9-8.4 4.1-13.2v-133c.4-3.7-1-7.3-3.8-9.8L75 138.1V133h87.3l67.4 148L289 133.1h83.2v5z"],"medium-m":[512,512,[],"f3c7","M71.5 142.3c.6-5.9-1.7-11.8-6.1-15.8L20.3 72.1V64h140.2l108.4 237.7L364.2 64h133.7v8.1l-38.6 37c-3.3 2.5-5 6.7-4.3 10.8v272c-.7 4.1 1 8.3 4.3 10.8l37.7 37v8.1H307.3v-8.1l39.1-37.9c3.8-3.8 3.8-5 3.8-10.8V171.2L241.5 447.1h-14.7L100.4 171.2v184.9c-1.1 7.8 1.5 15.6 7 21.2l50.8 61.6v8.1h-144v-8L65 377.3c5.4-5.6 7.9-13.5 6.5-21.2V142.3z"],medrt:[544,512,[],"f3c8","M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z"],meetup:[512,512,[],"f2e0","M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z"],microsoft:[448,512,[],"f3ca","M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z"],mix:[416,512,[],"f3cb","M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z"],mixcloud:[640,512,[],"f289","M424.43 219.729C416.124 134.727 344.135 68 256.919 68c-72.266 0-136.224 46.516-159.205 114.074-54.545 8.029-96.63 54.822-96.63 111.582 0 62.298 50.668 112.966 113.243 112.966h289.614c52.329 0 94.969-42.362 94.969-94.693 0-45.131-32.118-83.063-74.48-92.2zm-20.489 144.53H114.327c-39.04 0-70.881-31.564-70.881-70.604s31.841-70.604 70.881-70.604c18.827 0 36.548 7.475 49.838 20.766 19.963 19.963 50.133-10.227 30.18-30.18-14.675-14.398-32.672-24.365-52.053-29.349 19.935-44.3 64.79-73.926 114.628-73.926 69.496 0 125.979 56.483 125.979 125.702 0 13.568-2.215 26.857-6.369 39.594-8.943 27.517 32.133 38.939 40.147 13.29 2.769-8.306 4.984-16.889 6.369-25.472 19.381 7.476 33.502 26.303 33.502 48.453 0 28.795-23.535 52.33-52.607 52.33zm235.069-52.33c0 44.024-12.737 86.386-37.102 122.657-4.153 6.092-10.798 9.414-17.72 9.414-16.317 0-27.127-18.826-17.443-32.949 19.381-29.349 29.903-63.682 29.903-99.122s-10.521-69.773-29.903-98.845c-15.655-22.831 19.361-47.24 35.163-23.534 24.366 35.993 37.102 78.356 37.102 122.379zm-70.88 0c0 31.565-9.137 62.021-26.857 88.325-4.153 6.091-10.798 9.136-17.72 9.136-17.201 0-27.022-18.979-17.443-32.948 13.013-19.104 19.658-41.255 19.658-64.513 0-22.981-6.645-45.408-19.658-64.512-15.761-22.986 19.008-47.095 35.163-23.535 17.719 26.026 26.857 56.483 26.857 88.047z"],mizuni:[496,512,[],"f3cc","M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z"],modx:[448,512,[],"f285","M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z"],monero:[496,512,[],"f3d0","M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z"],napster:[496,512,[],"f3d2","M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z"],"nintendo-switch":[448,512,[],"f418","M95.9 33.5c-44.6 8-80.5 41-91.8 84.4C0 133.6-.3 142.8.2 264.4.4 376 .5 378.6 2.4 387.3c10.3 46.5 43.3 79.6 90.3 90.5 6.1 1.4 13.9 1.7 64.1 1.9 51.9.4 57.3.3 58.7-1.1 1.4-1.4 1.5-19.3 1.5-222.2 0-150.5-.3-221.3-.9-222.6-.9-1.7-2.5-1.8-56.9-1.7-44.2.1-57.5.4-63.3 1.4zm83.9 222.6V444l-37.8-.5c-34.8-.4-38.5-.6-45.5-2.3-29.9-7.7-52-30.7-58.3-60.7-2-9.4-2-240.1-.1-249.3 5.6-26.1 23.7-47.7 48-57.4 12.2-4.9 17.9-5.5 57.6-5.6l35.9-.1v188zm-75.9-131.2c-5.8 1.1-14.7 5.6-19.5 9.7-9.7 8.4-14.6 20.4-13.8 34.5.4 7.3.8 9.3 3.8 15.2 4.4 9 10.9 15.6 19.9 20 6.2 3.1 7.8 3.4 15.9 3.7 7.3.3 9.9 0 14.8-1.7 20.1-6.8 32.3-26.3 28.8-46.4-3.9-23.7-26.6-39.7-49.9-35zm158.2-92.3c-.4.3-.6 100.8-.6 223.5 0 202.3.1 222.8 1.5 223.4 2.5.9 74.5.6 83.4-.4 37.7-4.3 71-27.2 89-61.2 2.3-4.4 5.4-11.7 7-16.2 5.8-17.4 5.7-12.8 5.7-146.1 0-106.4-.2-122.3-1.5-129-9.2-48.3-46.1-84.8-94.5-93.1-6.5-1.1-16.5-1.4-48.8-1.4-22.4-.1-40.9.2-41.2.5zm99.1 202.1c14.5 3.8 26.3 14.8 31.2 28.9 3.1 8.7 3 21.5-.1 29.5-5.7 14.7-16.8 25-31.1 28.8-23.2 6-47.9-8-54.6-31-2-7-1.9-18.9.4-26.2 6.9-22.7 31-36.1 54.2-30z"],node:[640,512,[],"f419","M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z"],"node-js":[448,512,[],"f3d3","M224 480c-6 0-12-1.6-17.2-4.6L151.9 443c-8.2-4.6-4.2-6.2-1.5-7.1 10.9-3.8 13.1-4.7 24.8-11.3 1.2-.7 2.8-.4 4.1.3l42.1 25c1.5.8 3.7.8 5.1 0l164.2-94.8c1.5-.9 2.5-2.6 2.5-4.4V161.2c0-1.9-1-3.6-2.5-4.5L226.5 62c-1.5-.9-3.5-.9-5.1 0l-164 94.7c-1.6.9-2.6 2.7-2.6 4.5v189.5c0 1.8 1 3.5 2.6 4.4l45 26c24.4 12.2 39.3-2.2 39.3-16.6V177.4c0-2.6 2.1-4.7 4.8-4.7h20.8c2.6 0 4.8 2.1 4.8 4.7v187.1c0 32.6-17.7 51.2-48.6 51.2-9.5 0-17 0-37.8-10.3l-43.1-24.8C32 374.5 25.4 363 25.4 350.7V161.2c0-12.3 6.6-23.8 17.2-29.9l164.2-94.9c10.4-5.9 24.2-5.9 34.5 0l164.2 94.9c10.6 6.1 17.2 17.6 17.2 29.9v189.5c0 12.3-6.6 23.8-17.2 29.9l-164.2 94.8c-5.3 3-11.3 4.6-17.3 4.6zm132.5-186.8c0-35.5-24-44.9-74.4-51.6-51-6.7-56.2-10.2-56.2-22.2 0-9.9 4.4-23 42.2-23 33.7 0 46.2 7.3 51.3 30 .4 2.1 2.4 3.7 4.6 3.7h21.3c1.3 0 2.6-.6 3.5-1.5.9-1 1.4-2.3 1.3-3.7-3.3-39.2-29.3-57.4-81.9-57.4-46.8 0-74.7 19.8-74.7 52.9 0 35.9 27.8 45.9 72.7 50.3 53.8 5.3 57.9 13.1 57.9 23.7 0 18.3-14.7 26.2-49.3 26.2-43.4 0-53-10.9-56.2-32.5-.4-2.3-2.3-4-4.7-4h-21.2c-2.6 0-4.7 2.1-4.7 4.7 0 27.7 15.1 60.6 86.9 60.6 51.8.1 81.6-20.4 81.6-56.2z"],npm:[576,512,[],"f3d4","M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z"],ns8:[640,512,[],"f3d5","M187.1 159.9l-34.2 113.7-54.5-113.7H49L0 320h44.9L76 213.5 126.6 320h56.9L232 159.9h-44.9zm452.5-.9c-2.9-18-23.9-28.1-42.1-31.3-44.6-7.8-101.9 16.3-88.5 58.8v.1c-43.8 8.7-74.3 26.8-94.2 48.2-3-9.8-13.6-16.6-34-16.6h-87.6c-9.3 0-12.9-2.3-11.5-7.4 1.6-5.5 1.9-6.8 3.7-12.2 2.1-6.4 7.8-7.1 13.3-7.1h133.5l9.7-31.5c-139.7 0-144.5-.5-160.1 1.2-12.3 1.3-23.5 4.8-30.6 15-6.8 9.9-14.4 35.6-17.6 47.1-5.4 19.4-.6 28.6 32.8 28.6h87.3c7.8 0 8.8 2.7 7.7 6.6-1.1 4.4-2.8 10-4.5 14.6-1.6 4.2-4.7 7.4-13.8 7.4H216.3L204.7 320c139.9 0 145.3-.6 160.9-2.3 6.6-.7 13-2.1 18.5-4.9.2 3.7.5 7.3 1.2 10.8 5.4 30.5 27.4 52.3 56.8 59.5 48.6 11.9 108.7-16.8 135.1-68 18.7-36.2 14.1-76.2-3.4-105.5h.1c29.6-5.9 70.3-22 65.7-50.6zM530.7 263.7c-5.9 29.5-36.6 47.8-61.6 43.9-30.9-4.8-38.5-39.5-14.1-64.8 16.2-16.8 45.2-24 68.5-26.9 6.7 14.1 10.3 32 7.2 47.8zm21.8-83.1c-4.2-6-9.8-18.5-2.5-26.3 6.7-7.2 20.9-10.1 31.8-7.7 15.3 3.4 19.7 15.9 4.9 24.4-10.7 6.1-23.6 8.1-34.2 9.6z"],nutritionix:[400,512,[],"f3d6","M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z"],odnoklassniki:[320,512,[],"f263","M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z"],"odnoklassniki-square":[448,512,[],"f264","M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z"],opencart:[640,512,[],"f23d","M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z"],openid:[448,512,[],"f19b","M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z"],opera:[496,512,[],"f26a","M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z"],"optin-monster":[576,512,[],"f23c","M550.671 450.303c0 11.62-15.673 19.457-32.158 14.863-12.16-3.243-31.346-17.565-36.211-27.294-5.674-11.62 4.054-32.698 18.916-30.806 15.674 1.621 49.453 25.401 49.453 43.237zM372.86 75.223c-3.783-72.151-100.796-79.718-125.928-23.51 44.588-24.321 90.257-15.673 125.928 23.51zM74.795 407.066c-15.673 1.621-49.452 25.401-49.452 43.237 0 11.62 15.673 19.457 32.157 14.863 12.16-3.243 31.076-17.565 35.94-27.294 5.946-11.62-3.782-32.698-18.645-30.806zm497.765 14.322c1.081 3.513 1.892 7.026 1.892 10.809.81 31.616-44.317 64.045-73.503 65.125-17.295.81-34.59-8.377-42.696-23.51-113.497 4.053-226.994 4.864-340.22 0-8.377 15.133-25.672 24.05-42.967 23.51-28.915-1.081-74.043-33.509-73.503-65.125.27-3.783.811-7.296 1.892-10.809-5.566-9.463-4.845-15.282 5.405-11.62 3.243-5.134 7.026-9.458 11.08-13.782-2.57-10.917 1.27-14.094 11.079-9.188 4.594-3.243 9.998-6.485 15.944-9.188 0-15.757 11.839-11.131 17.295-5.675 12.467-1.78 20.129.709 26.753 5.675v-19.726c-12.987 0-40.641-11.375-45.94-36.212-4.974-20.725 2.607-38.075 25.132-47.56.81-5.945 8.107-14.052 14.862-15.944 7.567-1.892 12.431 4.594 14.052 10.269 7.425 0 17.757 1.465 21.078 8.107 5.405-.541 11.079-1.352 16.484-1.892-2.432-1.892-5.134-3.513-8.107-4.594-5.134-8.917-13.782-11.079-24.591-11.62 0-.81 0-1.621.27-2.702-19.727-.541-44.048-5.675-54.857-17.835-21.321-23.638-15.935-83.577 12.16-103.498 8.377-5.675 21.618-.811 22.699 9.728 2.425 20.598.399 26.833 26.212 25.942 8.107-7.836 16.755-14.592 26.483-19.997-14.862-1.352-28.914 1.621-43.778 3.783 12.752-12.48 23.953-25.442 56.748-42.427 23.511-11.89 49.993-20.808 76.205-23.239-18.646-7.837-39.993-11.891-59.721-16.484 76.475-16.214 174.569-22.159 244.289 37.562 18.105 15.403 32.427 36.211 42.696 59.992 39.799 4.853 36.47-5.581 38.643-25.132 1.081-10.269 14.322-15.403 22.699-9.458 14.862 10.539 22.159 30.806 24.59 48.101 2.162 17.835.27 41.345-12.43 55.127-10.809 12.16-34.32 17.565-53.776 18.105v2.703c-11.08.27-20.268 2.432-25.673 11.62-2.972 1.081-5.674 2.703-8.377 4.594 5.675.54 11.35 1.351 16.755 1.891 1.869-5.619 12.535-8.377 21.077-8.377 1.621-5.405 6.756-11.89 14.052-10.269s14.052 9.998 14.863 15.944c10.809 4.324 22.159 12.16 25.131 25.672 1.892 8.107 1.621 15.133.27 21.888-5.726 25.262-33.361 36.212-45.939 36.212 0 6.756 0 13.241-.27 19.726 8.01-6.006 16.367-7.158 26.752-5.675 5.919-5.919 17.565-9.41 17.565 5.675 5.675 2.703 11.349 5.945 15.944 9.188 10.1-5.051 13.669-.539 10.809 9.188 4.053 4.323 8.107 8.917 11.079 13.782 10.136-3.62 11.021 2.078 5.409 11.62zm-73.773-254.016c17.295 6.756 26.212 22.159 30.265 35.67 1.081-10.539-2.702-39.453-13.782-51.073-7.296-7.296-14.052-5.134-14.052.81.001 6.216-1.35 11.62-2.431 14.593zm-18.646 12.43c12.971 15.673 17.024 41.615 12.7 62.963 10.809-2.162 20.537-6.215 26.212-12.16 1.892-2.162 3.783-4.864 4.864-7.566-1.081-21.348-10.269-42.697-29.725-48.912-3.242 3.243-9.187 4.864-14.051 5.675zm-21.889.811c7.567 20.537 12.431 42.696 14.322 64.585 3.513 0 7.567-.27 11.62-.811 5.945-24.321-.27-51.614-14.052-63.504-3.783 0-8.107 0-11.89-.27zM77.768 167.372c-1.081-2.973-2.432-8.377-2.432-14.593 0-5.945-7.026-8.107-14.052-.81-11.35 11.62-14.863 40.534-13.782 51.073 4.053-13.512 12.971-28.915 30.266-35.67zm5.675 75.394c-4.324-21.348-.27-47.291 12.701-62.963-4.865-.811-10.809-2.432-14.052-5.675-19.457 6.215-28.375 27.563-29.726 48.912 1.351 2.702 2.972 5.404 4.864 7.566 5.675 6.215 15.403 9.998 26.213 12.16zm41.345-61.073c-5.134 1.081-9.998 2.973-14.862 4.865l-12.16 5.134v-.27c-7.296 14.052-9.999 34.319-5.405 52.965 4.594.541 8.647.811 12.7.811 2.432-22.159 9.188-43.778 19.727-63.505zm88.095-23.239c0 42.155 34.319 76.205 76.205 76.205s76.205-34.05 76.205-76.205c0-41.886-34.319-75.935-76.205-75.935s-76.205 34.049-76.205 75.935zm152.41 97.283c9.969 50.608 3.299 64.692 16.484 58.099 15.944-8.107 22.699-39.183 22.97-57.019-12.971-.81-26.213-.81-39.454-1.08zm-71.611-.541v-.27c-.27 5.134.27 38.103 4.324 41.075 11.079 5.405 39.453 4.594 51.073 1.081 5.405-1.621 2.432-37.022 1.621-41.886-18.916-.27-38.102-.27-57.018 0zm-14.053 0v-.27c-19.456.27-38.642.27-57.829.811-1.892 9.187-4.594 48.911 1.892 51.614 12.971 5.675 41.616 5.134 54.586 1.621 4.595-2.432 2.433-45.399 1.351-53.776zm-85.662 57.56c5.405 2.432 8.647 2.432 9.728-4.324 1.892-8.647 2.432-36.752 4.865-52.155-12.16.27-24.591.811-36.752 1.621-5.405 19.727.27 45.129 22.159 54.858zm-65.666-11.08c43.778 47.02 92.689 85.663 155.923 106.47 67.558-19.186 115.659-59.991 163.219-107.011-11.095-4.315-7.715-10.363-7.296-11.62-8.918-.81-17.835-1.892-26.483-2.702-9.458 32.968-35.94 52.965-46.75 31.616-2.702-5.134-3.513-11.62-4.594-16.754-3.783 8.377-13.242 8.107-24.591 8.918-13.241 1.081-31.617 1.351-44.048-2.972-2.972 12.971-11.079 12.971-26.752 14.322-14.052 1.352-48.642 4.054-54.857-10.809-1.081 28.644-35.13 9.998-45.129-7.026-3.243-5.675-5.405-11.35-7.026-17.565-7.837.81-15.673 1.621-23.511 2.702 2.443 3.663 1.549 9.052-8.105 12.431zM115.6 453.545c-5.674-23.239-18.646-49.722-33.508-54.046-22.429-6.756-68.909 23.51-66.207 54.586 12.701 19.457 39.994 35.67 59.181 36.481 17.835.81 35.94-11.08 39.724-28.914.539-2.432.81-5.134.81-8.107zm7.296-5.944c33.509-19.457 69.179-35.671 105.931-47.02-38.643-20.537-68.098-47.831-97.283-77.016-2.162 1.352-5.134 2.432-7.836 3.513-1.637 4.91 8.718 5.33 5.405 12.431-2.162 4.054-8.648 7.567-15.133 9.188-2.161 2.702-5.134 4.864-7.836 6.485h-.27c-.27 13.511-.27 27.024.27 40.535 8.939 15.964 15.426 33.314 16.752 51.884zm320.764 12.7c-36.752-21.348-74.044-41.345-115.659-52.965-13.782 6.215-27.833 11.349-42.155 15.403-2.162.811-2.162.811-4.324 0-11.89-3.783-23.239-8.107-34.859-13.241-40.265 11.62-77.286 29.185-112.416 50.803h-.27v.27c.27 0 .27 0 .27-.27 103.227 4.054 206.455 3.513 309.413 0zm27.023-64.045l-.27.27c.541-13.782.811-27.563.811-41.345-2.973-1.621-5.675-4.054-8.107-6.756-6.485-1.351-12.971-5.134-15.133-8.918-1.892-4.053 1.351-7.566 5.945-10.269-.27-.541-.541-1.621-.541-2.432-2.972-.811-5.405-1.892-7.567-3.243-31.616 29.455-65.396 56.749-103.498 76.746 38.914 11.62 75.935 28.104 111.875 47.561 1.05-14.692 7.231-35.749 16.485-51.614zm23.24 3.244c-14.593 4.323-27.834 30.806-33.509 54.046 0 23.826 21.278 37.897 40.534 37.022 19.186-.811 46.48-17.024 59.181-36.481 2.973-31.077-43.507-61.344-66.206-54.587zM290.709 134.133c.045 0 .089.003.134.003.046 0 .09-.003.136-.003h-.27zm0 96.743c28.645 0 51.884-21.618 51.884-48.371 0-36.092-40.507-58.079-72.151-44.318 9.458 2.972 16.484 11.62 16.484 21.618 0 23.257-33.291 31.955-46.48 11.35-7.297 34.067 19.368 59.721 50.263 59.721zM68.039 474.083c.54 6.486 12.16 12.701 21.618 9.458 6.756-2.703 14.593-10.539 17.295-16.214 2.973-7.026-1.081-19.997-9.728-18.375-8.917 1.621-29.725 16.754-29.185 25.131zm410.75-25.131c-8.377-1.621-12.431 11.349-9.458 18.375 2.432 5.675 10.269 13.511 17.295 16.214 9.187 3.243 21.078-2.972 21.348-9.458.811-8.377-20.267-23.51-29.185-25.131z"],osi:[495,512,[],"f41a","M0 259.2C2.3 123.4 97.4 26.8 213.8 11.1c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7-17.8-46.3-35.6-92.7-53.4-139-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8 6.4-42.4-24.5-78.7-64.5-82.2-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4-17.9 46.6-35.8 93.2-53.7 139.9-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119C1.9 318.7 1.6 280.2 0 259.2zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3 14.9-39.1 29.9-78.2 45-117.3 1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6 31.9 18.4 49.5 53.8 45.2 90.4-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6 15.2 39.2 30.2 78.4 45.2 117.7 1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161C459.8 112 354.1 14.7 218 31.5 111.9 44.5 22.7 134 20.9 257.3z"],page4:[496,512,[],"f3d7","M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z"],pagelines:[384,512,[],"f18c","M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z"],palfed:[560,512,[],"f3d8","M376.9 194.1c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.7-.1 83.3-42.9 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.1 2.4.3 3.9.6 4.6zM0 181.3s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.5s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S0 142.7 0 181.3z"],patreon:[512,512,[],"f3d9","M489.6 200.2c0 92.5-75.2 167.7-167.7 167.7-92.7 0-168.2-75.2-168.2-167.7 0-92.7 75.5-168.2 168.2-168.2 92.5 0 167.7 75.4 167.7 168.2zM22.4 480h82.1V32H22.4v448z"],paypal:[384,512,[],"f1ed","M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"],periscope:[448,512,[],"f3da","M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z"],phabricator:[496,512,[],"f3db","M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z"],"phoenix-framework":[640,512,[],"f3dc","M213.2 339.2c3.8-.1 22.9-1.4 25.6-2.2-2.4-2.7-43.6-1-68.1-49.7-4.3-8.7-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52.1-18.5 36 21.6 63.4 91.5 113.8 97.6 37.1 4.5 84.7-17 108.3-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.4 12.1-94.4 9.7-134.8-14.8-37.7-22.8-53.2-58.8-51.9-74.7 1.8-21.4 22.9-23.2 36-19.6 14.4 4 24.4 17.6 39 27.4 15.6 10.4 33 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.6-1.7C280.1 189.3 262.5 42 138.7 32.5c-44.4-3.4-99.6 8.1-136.5 35-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8-.1 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.8.3 23.9 4.3 47.8 23.1 56 76.6 5.3 34.3-.7 50.9 8 86.2 18.9 77.2 91 107.8 127.8 106.5zM75.4 59.5c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.3-4.1 36.7-4.8-1.1 14.7-22.3 21.4-35.4 6.8zm197.2 350.9c-42.9 1.2-92.1-26.8-123.7-61.5-4.6-5-16.8-20.3-18.6-23.4l.4-.4c6.6 4.1 25.7 18.7 54.9 27.1 24.2 7 48.1 6.3 71.7-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24.1 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.3 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.5-7.5-40.2-9.3-24.7-2-46.3 5.4-77.5 6.2zm175-252.2c16.4-5.2 41.4-13.4 66.6-3.3 16.1 6.5 26.2 18.7 32.1 34.7 3.5 9.4 5.1 19.7 5.1 28.8-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.7-29.9-50.2 18.6-130.5 9.7-177.2-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.5 38.3 21.9 60.4 26.2 30.6 5.9 54.7 2.6 80.1-5.4zm102.8 117.6c-32.4.2-33.8 50.2-103.7 64.4-18.3 3.7-38.7 4.6-45 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.2 22.8-22.9 19.6-20.3 41.5-42.3 82-39 23.1 1.8 29.3 8.2 36.2 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.2c-.1.2-.1.4-.2.6-29-4.4-48.1-7.9-68.6 4-17 9.9-31.5 20.6-62.1 24.4-27.1 3.4-45.2 2.4-66.2-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.5 5.2 55.6-5.9 22.4-12.9 40.2-26.7 71.4-31 29.6-3.9 51.3 2.7 71 17zM269 91.9c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.3 21.1 50.3 33 11.1 7.3 23.5 9.3 36.5 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.2-26.1 2.6-50.4-3.7-73.5-15.4-19.4-10-36.5-23-51.5-38.8zm371.8 238.7c-3.5 3.1-22.7 11.6-42.8 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.2-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.4-6.5 12.5 4.2 19.3 13.5 30.4 24.2 10.8 10.4 21 9.9 23.2 10.5.1-.1.2.1.4.4zM428 467.8c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.8-27.9-48.7-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.2.7 39 3.9 25.3 6.4 35 25.4 41.6 35.4 3.2 4.7 7.4 8.3 12.3 11z"],"pied-piper":[640,512,[],"f2ae","M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z"],"pied-piper-alt":[576,512,[],"f1a8","M242 187c6.3-11.8 13.2-17 25.9-21.8 27.3-10.3 40.2-30.5 58.9-51.1 11.9 8.4 12 24.6 31.6 23v21.8l6.3.3c37.4-14.4 74.7-30.2 106.6-54.6 48.3-36.8 52.9-50 81.3-100l2-2.6c-.6 14.1-6.3 27.3-12.4 39.9-30.5 63.8-78.7 100.3-146.8 116.7-12.4 2.9-26.4 3.2-37.6 8.9 1.4 9.8 13.2 18.1 13.2 23 0 3.4-5.5 7.2-7.5 8.6-11.2-12.9-16.1-19.3-22.7-22.1-7.6-3.5-63.9-6.4-98.8 10zm137.9 256.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9L244 246zm-12.6 31.8l24.1 61.2 21-13.8-31.3-50.9-13.8 3.5zM555.5 0l-.6 1.1-.3.9.6-.6.3-1.4zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46v27.3l11.8-3.4-2.9-23.8h-8.9zm76.1 2.9c0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3l2 12.4c9-1.5 58.4-6.6 58.4-14.1z"],"pied-piper-pp":[448,512,[],"f1a7","M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z"],pinterest:[496,512,[],"f0d2","M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z"],"pinterest-p":[384,512,[],"f231","M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z"],"pinterest-square":[448,512,[],"f0d3","M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z"],playstation:[576,512,[],"f3df","M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z"],"product-hunt":[512,512,[],"f288","M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z"],pushed:[432,512,[],"f3e1","M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z"],python:[448,512,[],"f3e2","M167.8 36.4c-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1zm-6.7 28.4c11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4zm185.2 81.4v47.5c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6-7.7-30.9-22.3-54.2-53.4-54.2h-40.1zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3z"],qq:[448,512,[],"f1d6","M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"],quora:[448,512,[],"f2c4","M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z"],ravelry:[512,512,[],"f2d9","M407.4 61.5C331.6 22.1 257.8 31 182.9 66c-11.3 5.2-15.5 10.6-19.9 19-10.3 19.2-16.2 37.4-19.9 52.7-21.2 25.6-36.4 56.1-43.3 89.9-10.6 18-20.9 41.4-23.1 71.4 0 0-.7 7.6-.5 7.9-35.3-4.6-76.2-27-76.2-27 9.1 14.5 61.3 32.3 76.3 37.9 0 0 1.7 98 64.5 131.2-11.3-17.2-13.3-20.2-13.3-20.2S94.8 369 100.4 324.7c.7 0 1.5.2 2.2.2 23.9 87.4 103.2 151.4 196.9 151.4 6.2 0 12.1-.2 18-.7 14 1.5 27.6.5 40.1-3.9 6.9-2.2 13.8-6.4 20.2-10.8 70.2-39.1 100.9-82 123.1-147.7 5.4-16 8.1-35.5 9.8-52.2 8.7-82.3-30.6-161.6-103.3-199.5zM138.8 163.2s-1.2 12.3-.7 19.7c-3.4 2.5-10.1 8.1-18.2 16.7 5.2-12.8 11.3-25.1 18.9-36.4zm-31.2 121.9c4.4-17.2 13.3-39.1 29.8-55.1 0 0 1.7 48 15.8 90.1l-41.4-6.9c-2.2-9.2-3.5-18.5-4.2-28.1zm7.9 42.8c14.8 3.2 34 7.6 43.1 9.1 27.3 76.8 108.3 124.3 108.3 124.3 1 .5 1.7.7 2.7 1-73.1-11.6-132.7-64.7-154.1-134.4zM386 444.1c-14.5 4.7-36.2 8.4-64.7 3.7 0 0-91.1-23.1-127.5-107.8 38.2.7 52.4-.2 78-3.9 39.4-5.7 79-16.2 115-33 11.8-5.4 11.1-19.4 9.6-29.8-2-12.8-11.1-12.1-21.4-4.7 0 0-82 58.6-189.8 53.7-18.7-32-26.8-110.8-26.8-110.8 41.4-35.2 83.2-59.6 168.4-52.4.2-6.4 3-27.1-20.4-28.1 0 0-93.5-11.1-146 33.5 2.5-16.5 5.9-29.3 11.1-39.4 34.2-30.8 79-49.5 128.3-49.5 106.4 0 193 87.1 193 194.5-.2 76-43.8 142-106.8 174z"],react:[512,512,[],"f41b","M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zm-130 189.1c4.6 8.8 9.3 17.5 14.3 26.1 5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5zm0-50.6c-6.3-14.9-11.6-29.5-16-43.6 14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26zm11.4 25.3c6.6-13.8 13.8-27.3 21.4-40.6 7.6-13.3 15.8-26.2 24.4-38.9 15-1.1 30.3-1.7 45.9-1.7 15.6 0 31 .6 45.9 1.7 8.5 12.6 16.6 25.5 24.3 38.7 7.7 13.2 14.9 26.7 21.7 40.4-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6-15.7 0-30.9-.5-45.6-1.4-8.7-12.7-16.9-25.7-24.6-39-7.7-13.3-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zM256 210.2c25.3 0 45.8 20.5 45.8 45.8 0 25.3-20.5 45.8-45.8 45.8-25.3 0-45.8-20.5-45.8-45.8 0-25.3 20.5-45.8 45.8-45.8"],rebel:[512,512,[],"f1d0","M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z"],"red-river":[448,512,[],"f3e3","M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z"],reddit:[512,512,[],"f1a1","M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z"],"reddit-alien":[512,512,[],"f281","M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z"],"reddit-square":[448,512,[],"f1a2","M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z"],rendact:[496,512,[],"f3e4","M248 8C111 8 0 119 0 256s111 248 248 248c18.6 0 36.7-2.1 54.1-5.9-5.6-7.4-10.8-14.4-15.9-21.3-12.4 2.1-25.2 3.3-38.3 3.3C124.3 480 24 379.7 24 256S124.3 32 248 32s224 100.3 224 224c0 71-33 134.2-84.5 175.3-25.9 18.8-39.1 21.4-83.5-44.2-78.7-112.9-48-71.1-73.7-108.3 72.8 8.9 228.5-72 168.6-168.6C314-26.8 15 93.8 59.7 226.4c3.2 9.8 14.4 38.6 45.6 38.6 2 0 2.6-.6 2-1.7-4.4-8.7-20.1-9.8-20.1-37.4 0-40.5 40.5-89.6 100.3-120 66.1-32.3 131.9-30.2 158.2 5.4 27.2 38.3-20.9 119.2-120.4 136.9 7.5-9.4 57-75.2 62.8-84 22.7-34.6 23.6-49 14-59.2-15.5-16.9-29.5-10.3-50.7-11.7-10.8-.9-113.7 181.2-136.4 216.9-5.9 9-21.2 34.1-21.2 50.9 0 21.3 2.8 51.4 20.6 51.4 10.6 0 8-18.7 8-26.6 0-12.9 27.4-49.4 74.8-104.6 20.4 36.1 57.7 114.3 130.2 209.7 98-33.1 168.5-125.8 168.5-235C496 119 385 8 248 8z"],renren:[512,512,[],"f18b","M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z"],replyd:[448,512,[],"f3e6","M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z"],resolving:[496,512,[],"f3e7","M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z"],rocketchat:[448,512,[],"f3e8","M448 256.2c0-87.2-99.6-153.3-219.8-153.3-18.8 0-37.3 1.6-55.3 4.8-11.1-10.5-24.2-20-38-27.4C61.2 44.2 0 79.4 0 79.4s56.9 47.1 47.6 88.3c-52.3 52.3-52.5 124.1 0 176.6C56.9 385.6 0 432.6 0 432.6s61.2 35.2 134.9-.8c13.8-7.5 26.9-16.9 38-27.4 18 3.2 36.5 4.8 55.3 4.8 120.3-.1 219.8-65.8 219.8-153zm-219.7 124c-23.7 0-46.3-2.8-67.3-7.8-21.3 25.8-68.1 61.7-113.6 50.1 14.8-16 36.7-43.1 32-87.6-27.3-21.4-43.6-48.7-43.6-78.5 0-68.4 86.2-123.9 192.5-123.9S420.8 188 420.8 256.4c0 68.3-86.2 123.8-192.5 123.8zm25.6-123.9c0 14.2-11.5 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.5-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm88.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.1 0 25.6 11.6 25.6 25.8zm-177.9 0c0 14.2-11.4 25.8-25.6 25.8-14.1 0-25.6-11.5-25.6-25.8 0-14.2 11.4-25.8 25.6-25.8 14.2 0 25.6 11.6 25.6 25.8z"],rockrms:[496,512,[],"f3e9","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z"],safari:[512,512,[],"f267","M236.9 256.8c0-9.1 6.6-17.7 16.3-17.7 8.9 0 17.4 6.4 17.4 16.1 0 9.1-6.4 17.7-16.1 17.7-9 0-17.6-6.7-17.6-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-26.6 0c0-122.3-99.1-221.4-221.4-221.4S34.6 133.7 34.6 256 133.7 477.4 256 477.4 477.4 378.3 477.4 256zm-72.5 96.6c0 3.6 13 10.2 16.3 12.2-27.4 41.5-69.8 71.4-117.9 83.3l-4.4-18.5c-.3-2.5-1.9-2.8-4.2-2.8-1.9 0-3 2.8-2.8 4.2l4.4 18.8c-13.3 2.8-26.8 4.2-40.4 4.2-36.3 0-72-10.2-103-29.1 1.7-2.8 12.2-18 12.2-20.2 0-1.9-1.7-3.6-3.6-3.6-3.9 0-12.2 16.6-14.7 19.9-41.8-27.7-72-70.6-83.6-119.6l19.1-4.2c2.2-.6 2.8-2.2 2.8-4.2 0-1.9-2.8-3-4.4-2.8L62 294.5c-2.5-12.7-3.9-25.5-3.9-38.5 0-37.1 10.5-73.6 30.2-104.9 2.8 1.7 16.1 10.8 18.3 10.8 1.9 0 3.6-1.4 3.6-3.3 0-3.9-14.7-11.3-18-13.6 28.2-41.2 71.1-70.9 119.8-81.9l4.2 18.5c.6 2.2 2.2 2.8 4.2 2.8s3-2.8 2.8-4.4L219 61.7c12.2-2.2 24.6-3.6 37.1-3.6 37.1 0 73.3 10.5 104.9 30.2-1.9 2.8-10.8 15.8-10.8 18 0 1.9 1.4 3.6 3.3 3.6 3.9 0 11.3-14.4 13.3-17.7 41 27.7 70.3 70 81.7 118.2l-15.5 3.3c-2.5.6-2.8 2.2-2.8 4.4 0 1.9 2.8 3 4.2 2.8l15.8-3.6c2.5 12.7 3.9 25.7 3.9 38.7 0 36.3-10 72-28.8 102.7-2.8-1.4-14.4-9.7-16.6-9.7-2.1 0-3.8 1.7-3.8 3.6zm-33.2-242.2c-13 12.2-134.2 123.7-137.6 129.5l-96.6 160.5c12.7-11.9 134.2-124 137.3-129.3l96.9-160.7z"],sass:[640,512,[],"f41e","M551.1 291.9c-22.4.1-41.8 5.5-58 13.5-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-3.8 11.1-5.3 19.1-2.3 11.7-25.8 53.5-39.1 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2c-.1-1.1-1.4-6.6-14.3-6.7-12.9-.1-24 2.5-25.3 5.9-1.3 3.4-2.7 11.4-5.3 19.1-2.6 7.7-33.9 77.3-42.1 95.4-4.2 9.2-7.8 16.6-10.4 21.6s-.2.3-.4.9c-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2-.8 0-1.4 2-1.4 2s10.1-42.4-19.4-42.4c-18.4 0-44 20.2-56.6 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.8-38.2-101.9-65.2-99.1-116.5 1-18.7 7.5-67.8 127.1-127.4 98-48.8 176.4-35.4 189.9-5.6 19.4 42.5-41.9 121.6-143.7 133-38.8 4.3-59.2-10.7-64.3-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.8 28.9 18.7 6.1 64.2 9.5 119.2-11.8C367 196.5 415.1 130.2 401 74.7 386.6 18.3 293.1-.2 204.6 31.2 151.9 49.9 94.9 79.3 53.9 117.6 5.2 163.2-2.6 202.9.6 219.5c11.4 58.9 92.6 97.3 125.1 125.7-1.6.9-3.1 1.7-4.5 2.5-16.3 8.1-78.2 40.5-93.7 74.7-17.5 38.8 2.9 66.6 16.3 70.4 41.8 11.6 84.6-9.3 107.6-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.3-4.9 16.4-9.4 23.5-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.5 5 15.4 5 13.8 0 20-11.4 26.9-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.4 0 18.8-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.6-46 16.2-31.8 31.7-71.5 31.7-71.5s1.4 9.7 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2s0 .1.1.2c-3 4-6.4 8.3-9.9 12.5-12.8 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.7 2.5 11.5-.8 19.6-3.6 23.5-5.4 6.2-2.2 13.4-5.7 20.2-10.6 12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5 19.8-28.9 35.1-60.6 35.1-60.6s1.4 9.7 6.2 25.8c2.4 8.1 7.1 17 11.4 25.7-18.6 15.1-30.1 32.6-34.1 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5 6.5-2.2 14.3-5.7 21.6-11.1 12.5-9.2 24.6-22.1 23.8-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.1-10.2 62.1-7.2 55.7 6.5 66.6 41.3 64.5 55.8-2.1 14.6-13.8 22.6-17.7 25-3.9 2.4-5.1 3.3-4.8 5.1.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.2-11.8 30.3-38.7 1.6-34-31.1-71.4-89-71.1zM121.8 436.6c-18.4 20.1-44.2 27.7-55.3 21.3C54.6 451 59.3 421.4 82 400c13.8-13 31.6-25 43.4-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.3 30.4.3 57.2-19.1 78.3zm134.4-91.4c-6.4 15.7-19.9 55.7-28.1 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.1-11.3 21.2-14.9 23.8-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.9-13.9 0 .5.1 1 .1 1.6-.1 17.9-17.3 30-25.1 34.8zm85.6-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.6-15.3 19-24.5 1.2 3.8 1.9 7.4 1.9 10.8-.1 22.5-16.2 30.9-25.9 34.4z"],schlix:[448,512,[],"f3ea","M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z"],scribd:[384,512,[],"f28a","M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z"],searchengin:[460,512,[],"f3eb","M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z"],sellcast:[448,512,[],"f2da","M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z"],sellsy:[640,512,[],"f213","M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z"],servicestack:[496,512,[],"f3ec","M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z"],shirtsinbulk:[448,512,[],"f214","M395.208 221.583H406v33.542h-10.792v-33.542zm0-9.625H406v-33.542h-10.792v33.542zm0 86.333H406V264.75h-10.792v33.541zM358.75 135.25h-33.542v10.5h33.542v-10.5zm36.458 206.208H406v-33.542h-10.792v33.542zM311.5 135.25h-33.542v10.5H311.5v-10.5zm-47.25 0H231v10.5h33.25v-10.5zm-47.25 0h-33.25v10.5H217v-10.5zm178.208 33.542H406V135.25h-33.542v10.5h22.75v23.042zm-255.792 259l30.625 13.417 4.375-9.917-30.625-13.417-4.375 9.917zM179.083 445l30.334 13.708 4.374-9.916-30.333-13.417-4.375 9.625zm216.125-60.375H406v-33.542h-10.792v33.542zm-334.833 8.167L91 406.208l4.375-9.624-30.625-13.709-4.375 9.917zm39.666 17.499l30.625 13.417 4.375-9.917-30.625-13.416-4.375 9.916zm132.417 38.501l4.375 9.916L267.459 445l-4.375-9.625-30.626 13.417zm118.417-52.208l4.375 9.624 30.624-13.416-4.374-9.917-30.625 13.709zM311.5 413.791l4.375 9.917 30.625-13.417-4.374-9.916-30.626 13.416zm-39.667 17.501l4.375 9.917 30.625-13.417-4.375-9.917-30.625 13.417zM311.5 46.583h-33.542v10.5H311.5v-10.5zm94.209 0h-33.251v10.5h33.251v-10.5zm-188.709 0h-33.25v10.5H217v-10.5zm141.75 0h-33.542v10.5h33.542v-10.5zm-94.5 0H231v10.5h33.25v-10.5zM448 3.708v406l-226.334 98.584L0 409.708v-406h448zm-29.166 116.958H29.166V390.75l192.792 85.75 196.875-85.75V120.666zm0-87.791H29.166V91.5h389.667V32.875zM75.542 46.583H42.291v10.5h33.251v-10.5zm94.5 0H136.5v10.5h33.542v-10.5zm-47.251 0H89.25v10.5h33.542v-10.5zm7.584 236.542c0-50.167 41.125-91.292 91.292-91.292 50.458 0 91.292 41.125 91.292 91.292 0 50.458-40.833 91.292-91.292 91.292-50.167-.001-91.292-40.834-91.292-91.292zm120.75 18.084c0 13.125-23.917 14.291-32.666 14.291-12.25 0-29.75-2.625-35.875-14.875h-.875L172.666 319c14.876 9.333 29.167 12.25 47.25 12.25 19.542 0 51.042-5.833 51.042-31.209 0-48.125-78.458-16.333-78.458-37.916 0-13.125 20.708-14.875 29.75-14.875 10.791 0 29.166 3.208 35.583 13.124h.875l8.751-16.916c-15.167-6.125-27.417-11.959-44.334-11.959-20.125 0-49.583 6.417-49.583 31.792 0 44.334 77.583 11.959 77.583 37.918zM122.791 135.25H89.25v10.5h33.542v-10.5zm-69.999 10.5h22.75v-10.5H42v33.542h10.792V145.75zm0 32.666H42v33.542h10.792v-33.542zm117.25-43.166H136.5v10.5h33.542v-10.5zm-117.25 86.333H42v33.542h10.792v-33.542zm0 86.334H42v33.542h10.792v-33.542zm0-43.167H42v33.542h10.792V264.75zm0 86.333H42v33.542h10.792v-33.542z"],simplybuilt:[512,512,[],"f215","M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z"],sistrix:[448,512,[],"f3ee","M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z"],skyatlas:[576,512,[],"f216","M545.7 318.5c0 56.2-44.8 97.5-100.2 97.5-141.5 0-167.6-212.9-306.7-212.9-125.2 0-125.4 180.9 4.8 180.9 36.2 0 77.5-15.2 106.8-36.2 4.8-3.5 14.4-13.9 19.5-13.9s9.3 4.3 9.3 9.3c0 6.7-11.2 16.3-16 20.5-34.9 30.4-85.5 52.2-131.9 52.2C60.2 416 0 365.6 0 292.4s57.6-127.1 130.3-127.1c158 0 189.7 209.7 308.5 209.7 85.2 0 80.8-119.1 2.9-119.1-14.9 0-29.8 9.9-40 9.9-7.2 0-13.6-6.1-13.6-13.3 0-9.9 4.5-20.2 4.5-30.9 0-56.8-43.4-97.8-99.7-97.8-45.3 0-68.2 31.4-75.7 31.4-5.3 0-9.6-4.3-9.6-9.6 0-4.8 3.5-8.8 6.7-12.3C235.9 108.8 269.5 96 302 96c67.7 0 118.6 49.8 118.6 117.5 0 5.9-.3 11.7-1.1 17.6 10.1-2.7 20.5-4 30.6-4 51.9 0 95.6 38.6 95.6 91.4z"],skype:[448,512,[],"f17e","M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z"],slack:[448,512,[],"f198","M244.2 217.5l19.3 57.7-59.8 20-19.3-57.7 59.8-20zm41.4 243.7C131.6 507.4 65 471.6 18.8 317.6S8.4 97 162.4 50.8C316.4 4.6 383 40.4 429.2 194.4c46.2 154 10.4 220.6-143.6 266.8zM366.2 265c-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-19.3-57.7 29-9.7c12.2-3.9 18.6-17.2 14.7-29.4-3.9-12.2-17.2-18.6-29.4-14.7l-29 9.7-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-59.8 20.1-10-30.1c-3.9-12.2-17.2-18.6-29.4-14.7-12.2 3.9-18.6 17.2-14.7 29.4l10 30.1-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l19.3 57.7-29 9.7c-12.2 3.9-18.6 17.2-14.7 29.4 3.2 9.3 12.2 15.4 21.5 15.8 4.3.6 7.7-1 36.9-10.7l10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 59.8-20.1 10 30.1c3.7 10.8 15.8 18.6 29.4 14.7 12.2-3.9 18.6-17.2 14.7-29.4l-10-30.1 29-9.7c12.2-4.2 18.6-17.5 14.7-29.6z"],"slack-hash":[448,512,[],"f3ef","M446.2 270.4c-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-30.3-90 45.4-15.1c19.1-6.2 29.1-26.8 23-45.9-6.2-19-26.9-29.1-46-22.9l-45.4 15.1-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-93.4 31.2-15.7-47c-6.2-19-26.9-29.1-46-22.9-19.1 6.2-29.1 26.8-23 45.9l15.7 47-45.3 15c-19.1 6.2-29.1 26.8-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l30.3 90L78 354.8c-19 6.2-29.1 26.9-23 45.9 5 14.5 19.1 24 33.6 24.6 6.8 1 12-1.6 57.7-16.8l15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 93.6-31.3 15.7 47c5.9 16.9 24.7 29 46 22.9 19.1-6.2 29.1-26.8 23-45.9l-15.7-47 45.4-15.1c19-6 29.1-26.7 22.9-45.7zm-254.1 47.2l-30.3-90.2 93.5-31.3 30.3 90.2-93.5 31.3z"],slideshare:[512,512,[],"f1e7","M249.429 211.436c0 31.716-27.715 57.717-61.717 57.717-34.001 0-61.716-26.001-61.716-57.717 0-32.001 27.715-57.716 61.716-57.716 34.001 0 61.717 25.715 61.717 57.716zm254.294 50.002c-18.286 22.573-53.144 50.288-106.289 72.003C453.722 525.163 260 555.735 263.143 457.446c0 1.714-.286-52.859-.286-93.432-4.285-.858-8.571-2-13.714-3.143 0 40.858-.286 98.289-.286 96.575C252 555.735 58.278 525.163 114.566 333.441c-53.145-21.715-88.003-49.43-106.29-72.003-9.143-13.714.858-28.287 16.001-17.715 2 1.428 4.285 2.857 6.285 4.285V49.716C30.563 22.287 51.135 0 76.565 0h359.157c25.429 0 46.002 22.287 46.002 49.716v198.293l6-4.285c15.143-10.573 25.143 4 15.999 17.714zm-46.572-189.15c0-32.858-10.572-45.716-40.859-45.716H98.566c-31.716 0-40.573 10.858-40.573 45.716v192.293c67.717 35.43 125.72 29.144 157.435 28.001 13.429-.286 22.001 2.286 27.144 7.715 1.689 1.687 10.023 9.446 20.287 17.143 1.143-15.715 10.001-25.715 33.716-24.858 32.287 1.428 91.718 7.715 160.577-29.716V72.288zM331.146 153.72c-34.002 0-61.716 25.715-61.716 57.716 0 31.716 27.715 57.717 61.716 57.717 34.287 0 61.716-26.001 61.716-57.717 0-32.001-27.429-57.716-61.716-57.716z"],snapchat:[496,512,[],"f2ab","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm169.5 338.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C183.1 100 230.7 96 244.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],"snapchat-ghost":[512,512,[],"f2ac","M510.846 392.673c-5.211 12.157-27.239 21.089-67.36 27.318-2.064 2.786-3.775 14.686-6.507 23.956-1.625 5.566-5.623 8.869-12.128 8.869l-.297-.005c-9.395 0-19.203-4.323-38.852-4.323-26.521 0-35.662 6.043-56.254 20.588-21.832 15.438-42.771 28.764-74.027 27.399-31.646 2.334-58.025-16.908-72.871-27.404-20.714-14.643-29.828-20.582-56.241-20.582-18.864 0-30.736 4.72-38.852 4.72-8.073 0-11.213-4.922-12.422-9.04-2.703-9.189-4.404-21.263-6.523-24.13-20.679-3.209-67.31-11.344-68.498-32.15a10.627 10.627 0 0 1 8.877-11.069c69.583-11.455 100.924-82.901 102.227-85.934.074-.176.155-.344.237-.515 3.713-7.537 4.544-13.849 2.463-18.753-5.05-11.896-26.872-16.164-36.053-19.796-23.715-9.366-27.015-20.128-25.612-27.504 2.437-12.836 21.725-20.735 33.002-15.453 8.919 4.181 16.843 6.297 23.547 6.297 5.022 0 8.212-1.204 9.96-2.171-2.043-35.936-7.101-87.29 5.687-115.969C158.122 21.304 229.705 15.42 250.826 15.42c.944 0 9.141-.089 10.11-.089 52.148 0 102.254 26.78 126.723 81.643 12.777 28.65 7.749 79.792 5.695 116.009 1.582.872 4.357 1.942 8.599 2.139 6.397-.286 13.815-2.389 22.069-6.257 6.085-2.846 14.406-2.461 20.48.058l.029.01c9.476 3.385 15.439 10.215 15.589 17.87.184 9.747-8.522 18.165-25.878 25.018-2.118.835-4.694 1.655-7.434 2.525-9.797 3.106-24.6 7.805-28.616 17.271-2.079 4.904-1.256 11.211 2.46 18.748.087.168.166.342.239.515 1.301 3.03 32.615 74.46 102.23 85.934 6.427 1.058 11.163 7.877 7.725 15.859z"],"snapchat-square":[448,512,[],"f2ad","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-6.5 314.9c-3.5 8.1-18.1 14-44.8 18.2-1.4 1.9-2.5 9.8-4.3 15.9-1.1 3.7-3.7 5.9-8.1 5.9h-.2c-6.2 0-12.8-2.9-25.8-2.9-17.6 0-23.7 4-37.4 13.7-14.5 10.3-28.4 19.1-49.2 18.2-21 1.6-38.6-11.2-48.5-18.2-13.8-9.7-19.8-13.7-37.4-13.7-12.5 0-20.4 3.1-25.8 3.1-5.4 0-7.5-3.3-8.3-6-1.8-6.1-2.9-14.1-4.3-16-13.8-2.1-44.8-7.5-45.5-21.4-.2-3.6 2.3-6.8 5.9-7.4 46.3-7.6 67.1-55.1 68-57.1 0-.1.1-.2.2-.3 2.5-5 3-9.2 1.6-12.5-3.4-7.9-17.9-10.7-24-13.2-15.8-6.2-18-13.4-17-18.3 1.6-8.5 14.4-13.8 21.9-10.3 5.9 2.8 11.2 4.2 15.7 4.2 3.3 0 5.5-.8 6.6-1.4-1.4-23.9-4.7-58 3.8-77.1C159.1 100 206.7 96 220.7 96c.6 0 6.1-.1 6.7-.1 34.7 0 68 17.8 84.3 54.3 8.5 19.1 5.2 53.1 3.8 77.1 1.1.6 2.9 1.3 5.7 1.4 4.3-.2 9.2-1.6 14.7-4.2 4-1.9 9.6-1.6 13.6 0 6.3 2.3 10.3 6.8 10.4 11.9.1 6.5-5.7 12.1-17.2 16.6-1.4.6-3.1 1.1-4.9 1.7-6.5 2.1-16.4 5.2-19 11.5-1.4 3.3-.8 7.5 1.6 12.5.1.1.1.2.2.3.9 2 21.7 49.5 68 57.1 4 1 7.1 5.5 4.9 10.8z"],soundcloud:[640,512,[],"f1be","M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"],speakap:[448,512,[],"f3f3","M352 32H96C43.2 32 0 75.2 0 128v256c0 52.8 43.2 96 96 96h256c52.8 0 96-43.2 96-96V128c0-52.8-43.2-96-96-96zM221 382.9c-39.6 0-81.9-17.8-81.9-53.7V302H179v17.8c0 15.1 19.5 24.5 41.9 24.5 24.2 0 41.3-10.4 41.3-29.5 0-23.8-27.2-31.9-54.7-42.6-31.9-12.4-63.1-26.2-63.1-69.1 0-48 38.6-66.4 79.9-66.4 37.6 0 75.5 14.1 75.5 41.9v31.2h-39.9v-16.1c0-12.1-17.8-18.5-35.6-18.5-19.5 0-35.6 8.1-35.6 26.2 0 22.1 22.5 29.2 47 38.9 35.9 12.4 71.1 27.2 71.1 71.5.1 48.6-40.8 71.1-85.8 71.1z"],spotify:[496,512,[],"f1bc","M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"],"stack-exchange":[448,512,[],"f18d","M43.5 322.8h361.1V342c0 33-25.7 59.5-57.2 59.5h-16.6L254.9 480v-78.5H100.6c-31.5 0-57.2-26.5-57.2-59.5v-19.2zm0-20.7h361.1v-74.4H43.5v74.4zm0-95.7h361.1V132H43.5v74.4zM347.4 32H100.6c-31.5 0-57.2 26.5-57.2 59.2v19.5h361.1V91.2c0-32.7-25.6-59.2-57.1-59.2z"],"stack-overflow":[384,512,[],"f16c","M293.7 300l-181.2-84.5 16.7-36.5 181.3 84.7-16.8 36.3zm48-76L188.2 95.7l-25.5 30.8 153.5 128.3 25.5-30.8zm39.6-31.7L262 32l-32 24 119.3 160.3 32-24zM290.7 311L95 269.7 86.8 309l195.7 41 8.2-39zm31.6 129H42.7V320h-40v160h359.5V320h-40v120zm-39.8-80h-200v39.7h200V360z"],staylinked:[440,512,[],"f3f5","M201.6 127.4c4.1-3.2 10.3-3 13.8.5l170 167.3-2.7-2.7 44.3 41.3c3.7 3.5 3.3 9-.7 12.2l-198 163.9c-9.9 7.6-17.3.8-17.3.8L2.3 314.6c-3.5-3.5-3-9 1.2-12.2l45.8-34.9c4.2-3.2 10.4-3 13.9.5l151.9 147.5c3.7 3.5 10 3.7 14.2.4l93.2-74c4.1-3.2 4.5-8.7.9-12.2l-84-81.3c-3.6-3.5-9.9-3.7-14-.5l-.1.1c-4.1 3.2-10.4 3-14-.5l-68.1-64.3c-3.5-3.5-3.1-9 1.1-12.2l57.3-43.6m14.8 257.3c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7"],steam:[496,512,[],"f1b6","M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"],"steam-square":[448,512,[],"f1b7","M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z"],"steam-symbol":[448,512,[],"f3f6","M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z"],"sticker-mule":[576,512,[],"f3f7","M353.1 509.8c-5.9 2.9-32.1 3.2-36.5-.5-4.1-3-2.2-11.9-1.5-15 2.2-15-2.5-7.9-9.8-11.5-3.1-1.5-4.1-5.5-4.6-10-.5-1.5-1-2.5-1.5-3.5-1.7-10.7 6.8-33.6 8.2-43.4 4.9-23.7-.7-37.2 1.5-46.9 3.7-16.2 4.1-3.5 4.1-29.9-1.4-25.9 3.3-36.9.5-38.9-14.8 0-64.3 10.7-112.2 2-46.1-8.9-59.4-29-65.4-30.9-10.3-4.5-23.2.5-27.3 7-.1.1-35 70.6-39.6 87.8-6.2 20.5-.5 47.4 4.1 66.8 0 .1 4.5 14.6 10.3 19.5 2.1 1.5 5.1 2.5 7.2 4.5 2.8 2.7 9.4 15.2 9.8 16 2.6 4.5 3.6 8-1.5 10.5-3.6 2-9.3 2.5-14.4 2.5-2.6.5-1.5 3.5-3.1 5-2.9 2.8-20.7 6.1-29.9 2.5-2.6-1-5.7-3-6.2-5-1.5-4 2.1-9-1-12.5-4.5-2.9-13.1-2-17-12-2.2-5.4-2.6-7.6-2.6-49.4 0-9.7-5.9-38.7-8.2-46.9-1.5-5.5-1.5-11.5 0-16 .3-.9 4.1-4.6 4.1-13-1-1.5-4.6-.5-5.1-1.5-10.4-80.6-5.9-79-7.7-98.3-1.5-16-10.9-43.9-6.7-64.3.5-2.4 3.4-21 24.2-38.9 31-26.7 48.4-38.3 159-11.5 1.1.4 66.3 21.1 110.7-9 15.5-11.3 28.8-11.3 35.5-16 .1-.1 61.7-52.1 87-65.3 47.2-29.4 69.9-16.7 75.1-18 4.7-1 13.4-25.8 17-25.8 5.5 0 1.6 20.2 3.6 25.9.5 2 3.6 5 6.2 5 2.3 0 1.7-.8 10.3-5 8.4-5.4 14.9-17.6 20.6-17 11.7 1.6-19 41.6-19 46.9 0 2 .2.8 4.6 9.5 2.6 5.5 4.6 13.5 6.2 20 8.3 29.7 5.7 14.6 13.4 36.9 20.2 50.1 20.6 45.2 20.6 52.9 0 7.5-4.1 11-7.2 16.5-1.5 3-4.6 7.5-7.2 8-2.7.7 7-1.5-13.4 2.5-7.2 1-13.4-4.5-14.9-9.5-1.6-4.7 2.8-10.1-11.8-22.9-10.3-10-21.1-11.3-31.9-17-9.8-5.7-11.9 1-18 8-18 22.9-34 46.9-52 69.8-11.8 15-24.2 30.4-33.5 47.4-3.9 6.8-9.5 28.1-10.3 29.9-6.2 17.7-5.5 25.8-16.5 68.3-3.1 10-5.7 21.4-8.7 32.4-2.2 6.8-7.4 49.3-.5 59.4 2.1 3.5 8.7 4.5 11.3 8 .1.1 9.6 18.2 9.3 20 0 6.1-9.4 5.6-11.3 6.5-4.8 2.9-3.8 5.9-6.4 7.4"],strava:[369,512,[],"f428","M301.6 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220h-67.6zM151.4 0L0 292h89.2l62.2-116.1L213.1 292h88.5L151.4 0z"],stripe:[640,512,[],"f429","M640 233.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9m-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4h-45.9zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7m-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8M346.4 96v36.2l-44.6 9.5v-36.2l44.6-9.5m-44.5 59.2h44.6v153.2h-44.6V155.2zm-47.8 13.1c10.4-19.1 31.1-15.2 37.1-13.1V196c-5.7-1.8-23.4-4.5-33.9 9.3v103.1H213V155.2h38.4l2.7 13.1m-89-13.1h33.7V193h-33.7v63.2c0 26.2 28 18 33.7 15.7v33.8c-5.9 3.2-16.6 5.9-31.2 5.9-26.3 0-46.1-17-46.1-43.3l.2-142.4 43.3-9.2.1 38.5zM44.9 200.3c0 20 67.9 10.5 67.9 63.4 0 32-25.4 47.8-62.3 47.8-15.3 0-32-3-48.5-10.1v-40c14.9 8.1 33.9 14.2 48.6 14.2 9.9 0 17-2.7 17-10.9 0-21.2-67.5-13.2-67.5-62.4 0-31.4 24-50.2 60-50.2 14.7 0 29.4 2.3 44.1 8.1V202c-13.5-7.3-30.7-11.4-44.2-11.4-9.3.1-15.1 2.8-15.1 9.7"],"stripe-s":[362,512,[],"f42a","M144.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C287.3 7.2 240.1 0 192.8 0 77.1 0 0 60.4 0 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5c53 22.8 106.8 32.4 156 32.4 118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9"],studiovinari:[512,512,[],"f3f8","M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z"],stumbleupon:[512,512,[],"f1a4","M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z"],"stumbleupon-circle":[496,512,[],"f1a3","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z"],superpowers:[448,512,[],"f2dd","M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z"],supple:[640,512,[],"f3f9","M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z"],telegram:[496,512,[],"f2c6","M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"],"telegram-plane":[448,512,[],"f3fe","M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"],"tencent-weibo":[384,512,[],"f1d5","M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z"],themeisle:[512,512,[],"f2b2","M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z"],trello:[448,512,[],"f181","M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zM194.9 371.4c0 14.8-12 26.9-26.9 26.9H85.1c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9H168c14.8 0 26.9 12 26.9 26.9v254.3zm194.9-112c0 14.8-12 26.9-26.9 26.9H280c-14.8 0-26.9-12-26.9-26.9V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v142.3z"],tripadvisor:[576,512,[],"f262","M166.4 280.521c0 13.236-10.73 23.966-23.966 23.966s-23.966-10.73-23.966-23.966 10.73-23.966 23.966-23.966 23.966 10.729 23.966 23.966zm264.962-23.956c-13.23 0-23.956 10.725-23.956 23.956 0 13.23 10.725 23.956 23.956 23.956 13.23 0 23.956-10.725 23.956-23.956-.001-13.231-10.726-23.956-23.956-23.956zm89.388 139.49c-62.667 49.104-153.276 38.109-202.379-24.559l-30.979 46.325-30.683-45.939c-48.277 60.39-135.622 71.891-197.885 26.055-64.058-47.158-77.759-137.316-30.601-201.374A186.762 186.762 0 0 0 0 139.416l90.286-.05a358.48 358.48 0 0 1 197.065-54.03 350.382 350.382 0 0 1 192.181 53.349l96.218.074a185.713 185.713 0 0 0-28.352 57.649c46.793 62.747 34.964 151.37-26.648 199.647zM259.366 281.761c-.007-63.557-51.535-115.075-115.092-115.068C80.717 166.7 29.2 218.228 29.206 281.785c.007 63.557 51.535 115.075 115.092 115.068 63.513-.075 114.984-51.539 115.068-115.052v-.04zm28.591-10.455c5.433-73.44 65.51-130.884 139.12-133.022a339.146 339.146 0 0 0-139.727-27.812 356.31 356.31 0 0 0-140.164 27.253c74.344 1.582 135.299 59.424 140.771 133.581zm251.706-28.767c-21.992-59.634-88.162-90.148-147.795-68.157-59.634 21.992-90.148 88.162-68.157 147.795v.032c22.038 59.607 88.198 90.091 147.827 68.113 59.615-22.004 90.113-88.162 68.125-147.783zm-326.039 37.975v.115c-.057 39.328-31.986 71.163-71.314 71.106-39.328-.057-71.163-31.986-71.106-71.314.057-39.328 31.986-71.163 71.314-71.106 39.259.116 71.042 31.94 71.106 71.199zm-24.512 0v-.084c-.051-25.784-20.994-46.645-46.778-46.594-25.784.051-46.645 20.994-46.594 46.777.051 25.784 20.994 46.645 46.777 46.594 25.726-.113 46.537-20.968 46.595-46.693zm313.423 0v.048c-.02 39.328-31.918 71.194-71.247 71.173s-71.194-31.918-71.173-71.247c.02-39.328 31.918-71.194 71.247-71.173 39.29.066 71.121 31.909 71.173 71.199zm-24.504-.008c-.009-25.784-20.918-46.679-46.702-46.67-25.784.009-46.679 20.918-46.67 46.702.009 25.784 20.918 46.678 46.702 46.67 25.765-.046 46.636-20.928 46.67-46.693v-.009z"],tumblr:[320,512,[],"f173","M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z"],"tumblr-square":[448,512,[],"f174","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z"],twitch:[448,512,[],"f1e8","M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"],twitter:[512,512,[],"f099","M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"],"twitter-square":[448,512,[],"f081","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"],typo3:[433,512,[],"f42b","M330.8 341c-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9 0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C0 246 106.8 480 184.1 480c36.3 0 97.3-59.5 146.7-139M294.5 32c71.8 0 138.8 11.6 138.8 52.5 0 82.6-52.5 182.3-78.8 182.3-47.9 0-101.7-132.1-101.7-198.5 0-30.9 11.6-36.3 41.7-36.3"],uber:[448,512,[],"f402","M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z"],uikit:[448,512,[],"f403","M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z"],uniregistry:[384,512,[],"f404","M281.1 220.1H384v-14.8H281.1v14.8zm0-37.1H384v-12.4H281.1V183zm0 74.2H384v-17.3H281.1v17.3zm-157.7 86.7H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8m145.7-12.4h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3m-41.5 37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8M384 32H281.1v2.5H384V32zM192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480m89.1-334.2H384V136H281.1v9.8zm0-37.1H384v-7.4H281.1v7.4zm0-37.1H384v-4.9H281.1v4.9zm-178.2 99H0V183h102.9v-12.4zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2m64.1-118.8v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4m178.2 0c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1v12.4zm-203 156h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7m24.8-376.2H0v4.9h102.9v-4.9zm0-34.7H0v2.5h102.9V32zm0 173.3H0v14.8h102.9v-14.8zm0 34.6H0v17.3h102.9v-17.3zm0-103.9H0v9.9h102.9V136zm0-34.7H0v7.4h102.9v-7.4zm2.8 207.9H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3"],untappd:[640,512,[],"f405","M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z"],usb:[640,512,[],"f287","M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z"],ussunnah:[512,512,[],"f407","M156.8 285.1l5.7 14.4h-8.2c-1.3-3.2-3.1-7.7-3.8-9.5-2.5-6.3-1.1-8.4 0-10 1.9-2.7 3.2-4.4 3.6-5.2 0 2.2.8 5.7 2.7 10.3zm297.3 18.8c-2.1 13.8-5.7 27.1-10.5 39.7l43 23.4-44.8-18.8c-5.3 13.2-12 25.6-19.9 37.2l34.2 30.2-36.8-26.4c-8.4 11.8-18 22.6-28.7 32.3l24.9 34.7-28.1-31.8c-11 9.6-23.1 18-36.1 25.1l15.7 37.2-19.3-35.3c-13.1 6.8-27 12.1-41.6 15.9l6.7 38.4-10.5-37.4c-14.3 3.4-29.2 5.3-44.5 5.4L256 512l-1.9-38.4c-15.3-.1-30.2-2-44.5-5.3L199 505.6l6.7-38.2c-14.6-3.7-28.6-9.1-41.7-15.8l-19.2 35.1 15.6-37c-13-7-25.2-15.4-36.2-25.1l-27.9 31.6 24.7-34.4c-10.7-9.7-20.4-20.5-28.8-32.3l-36.5 26.2 33.9-29.9c-7.9-11.6-14.6-24.1-20-37.3l-44.4 18.7L67.8 344c-4.8-12.7-8.4-26.1-10.5-39.9l-51 9 50.3-14.2c-1.1-8.5-1.7-17.1-1.7-25.9 0-4.7.2-9.4.5-14.1L0 256l56-2.8c1.3-13.1 3.8-25.8 7.5-38.1L6.4 199l58.9 10.4c4-12 9.1-23.5 15.2-34.4l-55.1-30 58.3 24.6C90 159 97.2 149.2 105.3 140L55.8 96.4l53.9 38.7c8.1-8.6 17-16.5 26.6-23.6l-40-55.6 45.6 51.6c9.5-6.6 19.7-12.3 30.3-17.2l-27.3-64.9 33.8 62.1c10.5-4.4 21.4-7.9 32.7-10.4L199 6.4l19.5 69.2c11-2.1 22.3-3.2 33.8-3.4L256 0l3.6 72.2c11.5.2 22.8 1.4 33.8 3.5L313 6.4l-12.4 70.7c11.3 2.6 22.2 6.1 32.6 10.5l33.9-62.2-27.4 65.1c10.6 4.9 20.7 10.7 30.2 17.2l45.8-51.8-40.1 55.9c9.5 7.1 18.4 15 26.5 23.6l54.2-38.9-49.7 43.9c8 9.1 15.2 18.9 21.5 29.4l58.7-24.7-55.5 30.2c6.1 10.9 11.1 22.3 15.1 34.3l59.3-10.4-57.5 16.2c3.7 12.2 6.2 24.9 7.5 37.9L512 256l-56 2.8c.3 4.6.5 9.3.5 14.1 0 8.7-.6 17.3-1.6 25.8l50.7 14.3-51.5-9.1zm-21.8-31c0-97.5-79-176.5-176.5-176.5s-176.5 79-176.5 176.5 79 176.5 176.5 176.5 176.5-79 176.5-176.5zm-24 0c0 84.3-68.3 152.6-152.6 152.6s-152.6-68.3-152.6-152.6 68.3-152.6 152.6-152.6 152.6 68.3 152.6 152.6zM195 241c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-40.7-19c0 2.1 1.3 3.8 3.6 5.1 3.5 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.5 6.8-9.6 10.9-9.6 12.6zm-19 0c0 2.1 1.3 3.8 3.6 5.1 3.3 1.9 6.2 4.6 8.2 8.2 2.8-5.7 4.3-9.5 4.3-11.2 0-2.2-1.1-4.4-3.2-7-2.1-2.5-3.2-5.2-3.3-7.7-6.4 6.8-9.6 10.9-9.6 12.6zm204.9 87.9c-8.4-3-8.7-6.8-8.7-15.6V182c-8.2 12.5-14.2 18.6-18 18.6 6.3 14.4 9.5 23.9 9.5 28.3v64.3c0 2.2-2.2 6.5-4.7 6.5h-18c-2.8-7.5-10.2-26.9-15.3-40.3-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3 2.6 6.7 6.4 16.5 7.9 20.2h-9.2c-3.9-10.4-9.6-25.4-11.8-31.1-2 2.5-7.2 9.2-10.7 13.7 2.4 1.6 4.1 3.6 5.2 6.3.8 2 2.8 7.3 4.3 10.9H256c-1.5-4.1-5.6-14.6-8.4-22-2 2.5-7.2 9.2-10.7 13.7 2.5 1.6 4.3 3.6 5.2 6.3.2.6.5 1.4.6 1.7H225c-4.6-13.9-11.4-27.7-11.4-34.1 0-2.2.3-5.1 1.1-8.2-8.8 10.8-14 15.9-14 25 0 7.5 10.4 28.3 10.4 33.3 0 1.7-.5 3.3-1.4 4.9-9.6-12.7-15.5-20.7-18.8-20.7h-12l-11.2-28c-3.8-9.6-5.7-16-5.7-18.8 0-3.8.5-7.7 1.7-12.2-1 1.3-3.7 4.7-5.5 7.1-.8-2.1-3.1-7.7-4.6-11.5-2.1 2.5-7.5 9.1-11.2 13.6.9 2.3 3.3 8.1 4.9 12.2-2.5 3.3-9.1 11.8-13.6 17.7-4 5.3-5.8 13.3-2.7 21.8 2.5 6.7 2 7.9-1.7 14.1H191c5.5 0 14.3 14 15.5 22 13.2-16 15.4-19.6 16.8-21.6h107c3.9 0 7.2-1.9 9.9-5.8zm20.1-26.6V181.7c-9 12.5-15.9 18.6-20.7 18.6 7.1 14.4 10.7 23.9 10.7 28.3v66.3c0 17.5 8.6 20.4 24 20.4 8.1 0 12.5-.8 13.7-2.7-4.3-1.6-7.6-2.5-9.9-3.3-8.1-3.2-17.8-7.4-17.8-26z"],vaadin:[448,512,[],"f408","M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z"],viacoin:[384,512,[],"f237","M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z"],viadeo:[448,512,[],"f2a9","M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z"],"viadeo-square":[448,512,[],"f2aa","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z"],viber:[512,512,[],"f409","M430.7 49.9C418 38.2 366.6.9 252.1.4c0 0-135.1-8.1-200.9 52.3C14.6 89.3 1.7 142.9.3 209.4c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.5-7.6-209.7-49.9-246.4zM444.6 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0C29.9 372.7 35.8 266.6 37 211.1c1.1-55.5 11.6-101 42.6-131.6C135.3 29 250 36.5 250 36.5c96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.5 211.1zm-138.9-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.2 8.6-13.1 8.2-12.9-.3zm46.9 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.8.5 133.1 51.4 133.7 139.2zM361.7 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z"],vimeo:[448,512,[],"f40a","M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z"],"vimeo-square":[448,512,[],"f194","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z"],"vimeo-v":[448,512,[],"f27d","M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z"],vine:[384,512,[],"f1ca","M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z"],vk:[576,512,[],"f189","M545 117.7c3.7-12.5 0-21.7-17.8-21.7h-58.9c-15 0-21.9 7.9-25.6 16.7 0 0-30 73.1-72.4 120.5-13.7 13.7-20 18.1-27.5 18.1-3.7 0-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4 0-15 7-15 13.5 0 14.2 21.2 17.5 23.4 57.5v86.8c0 19-3.4 22.5-10.9 22.5-20 0-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8 0-20.2 7.9-20.2 16.7 0 15.6 20 93.1 93.1 195.5C160.4 378.1 229 416 291.4 416c37.5 0 42.1-8.4 42.1-22.9 0-66.8-3.4-73.1 15.4-73.1 8.7 0 23.7 4.4 58.7 38.1 40 40 46.6 57.9 69 57.9h58.9c16.8 0 25.3-8.4 20.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2 0-26.2.1-.1 72-101.3 79.4-135.6z"],vnv:[640,512,[],"f40b","M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z"],vuejs:[448,512,[],"f41f","M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"],weibo:[512,512,[],"f18a","M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z"],weixin:[576,512,[],"f1d7","M372.3 167.6c6.4 0 12.6.3 18.8 1.1C374.4 90.3 290.3 32 194.7 32 87.6 32 0 104.8 0 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 73-154 165.4-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2 0-14.7 14.5-24.4 29.3-24.4zm-136.5 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4.1 14.6-9.6 24.2-24.4 24.2zm418.8 156.1c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S292 460.7 384.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6c39.3-29.4 68.3-68.3 68.3-112.1zm-219.2-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.6 19.6-24.4 19.6zm107.2 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3 0 10-9.9 19.6-24.4 19.6z"],whatsapp:[448,512,[],"f232","M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"],"whatsapp-square":[448,512,[],"f40c","M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"],whmcs:[448,512,[],"f40d","M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z"],"wikipedia-w":[640,512,[],"f266","M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z"],windows:[448,512,[],"f17a","M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z"],wordpress:[512,512,[],"f19a","M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"],"wordpress-simple":[512,512,[],"f411","M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z"],wpbeginner:[512,512,[],"f297","M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z"],wpexplorer:[512,512,[],"f2de","M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z"],wpforms:[448,512,[],"f298","M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z"],xbox:[512,512,[],"f412","M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z"],xing:[384,512,[],"f168","M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"],"xing-square":[448,512,[],"f169","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z"],"y-combinator":[448,512,[],"f23b","M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z"],yahoo:[360,512,[],"f19e","M204.9 288l3.5 195.5c-11.3-2-20.9-3.5-28.7-3.5-7.5 0-17 1.5-28.7 3.5l3.5-195.5C105.7 203.7 56.5 113.1 0 28.5 10.6 31.3 20.4 32 29.5 32c8 0 18.1-.7 30.3-3.5 36.4 64.2 72.9 123.2 119.9 200.4 33.2-54.7 80.9-128.1 119.9-200.4 9.8 2.6 19.6 3.5 29.2 3.5 10.2 0 20.6-.9 31.1-3.5C329.4 71.1 243 221.3 204.9 288z"],yandex:[256,512,[],"f413","M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z"],"yandex-international":[320,512,[],"f414","M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z"],yelp:[384,512,[],"f1e9","M136.9 328c-1 .3-109.2 35.7-115.8 35.7-15.2-.9-18.5-16.2-19.9-31.2-1.5-14.2-1.4-29.8.3-46.8 1.9-18.8 5.5-45.1 24.2-44 4.8 0 67.1 25.9 112.7 44.4 17.1 6.8 18.6 35.8-1.5 41.9zm57.9-113.9c1.8 38.2-25.5 48.5-47.2 14.3L41.3 60.4c-1.5-6.6.3-12.4 5.3-17.4C62.2 26.5 146 3.2 168.1 8.9c7.5 1.9 12.1 6.1 13.8 12.6 1.3 8.3 11.5 167.4 12.9 192.6zm-1.4 164.8c0 4.6.2 116.4-1.7 121.5-2.3 6-7 9.7-14.3 11.2-10.1 1.7-27.1-1.9-51-10.7-22-8.1-56.7-21.5-49.3-42.5 2.8-6.9 51.4-62.8 77.3-93.6 12-15.2 39.8-5.5 39 14.1zm180.2-117.8c-5.6 3.7-110.8 28.2-118.1 30.6l.3-.6c-18.1 4.7-35.4-18.5-23.3-34.6 3.7-3.7 65.9-92.4 72.8-97 5.2-3.6 11.3-3.8 18.3-.6 18.4 8.8 55.1 63.1 57.4 84.6-.1 2.9 1.2 11.7-7.4 17.6zm10.1 130.7c-2.7 20.6-44.5 73.4-63.8 81-6.9 2.6-12.9 2-17.7-2-5-3.5-61.8-97.1-64.9-102.3-10.9-16.2 6.8-39.8 25.6-33.2 0 0 110.5 35.7 114.7 39.4 5.2 4.1 7.2 9.8 6.1 17.1z"],yoast:[448,512,[],"f2b1","M91.265 96h186.043l-7.008 18.878H91.265c-39.658 0-71.889 31.556-71.889 70.292v205.373c0 35.401 24.882 70.311 84.001 70.311V480H91.265C41.165 480 0 439.83 0 390.544V185.17C0 135.937 40.709 96 91.265 96zm229.114-56h66.49C243.146 418.092 241.192 438.918 202.18 479.331c-20.779 21.646-49.294 31.719-78.328 32.669v-51.146c49.234-7.662 64.606-49.855 64.606-75.284 0-20.078.577-12.645-82.117-223.219h61.386l50.354 156.58L320.379 40zM448 181.465V480H233.963c6.635-9.621 10.679-16.277 12.112-19.413h182.529V181.465c0-32.543-17.097-51.945-48.194-62.914l6.733-17.578C428.763 114.636 448 144.059 448 181.465z"],youtube:[576,512,[],"f167","M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"]}),t=z||{};t.___FONT_AWESOME___||(t.___FONT_AWESOME___={}),t.___FONT_AWESOME___.styles||(t.___FONT_AWESOME___.styles={}),t.___FONT_AWESOME___.hooks||(t.___FONT_AWESOME___.hooks={}),t.___FONT_AWESOME___.shims||(t.___FONT_AWESOME___.shims=[]);var s=t.___FONT_AWESOME___,r=Object.assign||function(c){for(var l=1;l-1;z--){var e=h[z],a=(e.tagName||"").toUpperCase();["STYLE","LINK"].indexOf(a)>-1&&(v=e)}return K.head.insertBefore(l,v),c}}function v(){return++Cc}function z(c){for(var l=[],h=(c||[]).length>>>0;h--;)l[h]=c[h];return l}function e(c){return c.classList?z(c.classList):(c.getAttribute("class")||"").split(" ").filter(function(c){return c})}function a(c,h){var v=h.split("-"),z=v[0],e=v.slice(1).join("-");return z!==c||""===e||l(e)?null:e}function m(c){return(""+c).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function t(c){return Object.keys(c||{}).reduce(function(l,h){return l+(h+'="')+m(c[h])+'" '},"").trim()}function s(c){return Object.keys(c||{}).reduce(function(l,h){return l+(h+": ")+c[h]+";"},"")}function r(c){return c.size!==Vc.size||c.x!==Vc.x||c.y!==Vc.y||c.rotate!==Vc.rotate||c.flipX||c.flipY}function f(c){var l=c.transform,h=c.containerWidth,v=c.iconWidth;return{outer:{transform:"translate("+h/2+" 256)"},inner:{transform:"translate("+32*l.x+", "+32*l.y+") "+" "+("scale("+l.size/16*(l.flipX?-1:1)+", "+l.size/16*(l.flipY?-1:1)+") ")+" "+("rotate("+l.rotate+" 0 0)")},path:{transform:"translate("+v/2*-1+" -256)"}}}function M(c){var l=c.transform,h=c.width,v=void 0===h?$:h,z=c.height,e=void 0===z?$:z,a=c.startCentered,m=void 0!==a&&a,t="";return t+=m&&Z?"translate("+(l.x/oc-v/2)+"em, "+(l.y/oc-e/2)+"em) ":m?"translate(calc(-50% + "+l.x/oc+"em), calc(-50% + "+l.y/oc+"em)) ":"translate("+l.x/oc+"em, "+l.y/oc+"em) ",t+="scale("+l.size/oc*(l.flipX?-1:1)+", "+l.size/oc*(l.flipY?-1:1)+") ",t+="rotate("+l.rotate+"deg) "}function i(c){var l,h=c.icons,z=h.main,e=h.mask,a=c.prefix,m=c.iconName,t=c.transform,s=c.symbol,r=c.title,f=c.extra,M=e.found?e:z,i=M.width,n=M.height,H="fa-w-"+Math.ceil(i/n*16),o=[Hc.replacementClass,m?Hc.familyPrefix+"-"+m:"",H].concat(f.classes).join(" "),V={children:[],attributes:fc({},f.attributes,(l={},rc(l,cc,""),rc(l,"data-prefix",a),rc(l,"data-icon",m),rc(l,"class",o),rc(l,"role","img"),rc(l,"xmlns","http://www.w3.org/2000/svg"),rc(l,"viewBox","0 0 "+i+" "+n),l))};r&&V.children.push({tag:"title",attributes:{id:V.attributes["aria-labelledby"]||"title-"+v()},children:[r]});var C=fc({},V,{prefix:a,iconName:m,main:z,mask:e,transform:t,symbol:s,styles:f.styles}),L=e.found&&z.found?uc(C):dc(C),u=L.children,d=L.attributes;return C.children=u,C.attributes=d,s?gc(C):pc(C)}function n(c){var l,h=c.content,v=c.width,z=c.height,e=c.transform,a=c.title,m=c.extra,t=fc({},m.attributes,a?{title:a}:{},(l={},rc(l,cc,""),rc(l,"class",m.classes.join(" ")),l)),f=fc({},m.styles);r(e)&&(f.transform=M({transform:e,startCentered:!0,width:v,height:z}),f["-webkit-transform"]=f.transform);var i=s(f);i.length>0&&(t.style=i);var n=[];return n.push({tag:"span",attributes:t,children:[h]}),a&&n.push({tag:"span",attributes:{class:"sr-only"},children:[a]}),n}function H(c,l){return Nc[c][l]}function o(c,l){return qc[c][l]}function V(c){return Tc[c]||{prefix:null,iconName:null}}function C(c){return c.reduce(function(c,l){var h=a(Hc.familyPrefix,l);if(Fc[l])c.prefix=l;else if(h){var v="fa"===c.prefix?V(h):{};c.iconName=v.iconName||h,c.prefix=v.prefix||c.prefix}else l!==Hc.replacementClass&&0!==l.indexOf("fa-w-")&&c.rest.push(l);return c},Wc())}function L(c,l,h){if(c&&c[l]&&c[l][h])return{prefix:l,iconName:h,icon:c[l][h]}}function u(c){var l=c.tag,h=c.attributes,v=void 0===h?{}:h,z=c.children,e=void 0===z?[]:z;return"string"==typeof c?m(c):"<"+l+" "+t(v)+">"+e.map(u).join("")+""}function d(c){var l=c.getAttribute?c.getAttribute("class"):null;return!!l&&(!!~l.toString().indexOf(Hc.replacementClass)||~l.toString().indexOf("fa-layers-text"))}function p(){return!0===Hc.autoReplaceSvg?Ic.replace:Ic[Hc.autoReplaceSvg]||Ic.replace}function g(c,l){var h="function"==typeof l?l:Pc;0===c.length?h():(U.requestAnimationFrame||function(c){return c()})(function(){var l=p(),v=kc.begin("mutate");c.map(l),v(),h()})}function b(c){Rc=!0,c(),Rc=!1}function w(c){if(G){var l=c.treeCallback,h=c.nodeCallback,v=c.pseudoElementsCallback,a=new G(function(c){Rc||z(c).forEach(function(c){if("childList"===c.type&&c.addedNodes.length>0&&!d(c.addedNodes[0])&&(Hc.searchPseudoElements&&v(c.target),l(c.target)),"attributes"===c.type&&"class"===c.attributeName&&c.target.parentNode&&Hc.searchPseudoElements&&v(c.target.parentNode),"attributes"===c.type&&d(c.target)&&~ac.indexOf(c.attributeName))if("class"===c.attributeName){var z=C(e(c.target)),a=z.prefix,m=z.iconName;a&&c.target.setAttribute("data-prefix",a),m&&c.target.setAttribute("data-icon",m)}else h(c.target)})});K.getElementsByTagName&&a.observe(K.getElementsByTagName("body")[0],{childList:!0,attributes:!0,characterData:!0,subtree:!0})}}function y(c){for(var l="",h=0;h1&&void 0!==arguments[1]?arguments[1]:null,h=K.documentElement.classList,v=function(c){return h.add(hc+"-"+c)},e=function(c){return h.remove(hc+"-"+c)},a=Object.keys(ll),m=["."+hl+":not(["+cc+"])"].concat(a.map(function(c){return"."+c+":not(["+cc+"])"})).join(", ");if(0!==m.length){var t=z(c.querySelectorAll(m));if(t.length>0){v("pending"),e("complete");var s=kc.begin("onTree"),r=t.reduce(function(c,l){try{var h=O(l);h&&c.push(h)}catch(c){vc||c instanceof _&&console.error(c)}return c},[]);s(),g(r,function(){v("active"),v("complete"),e("pending"),"function"==typeof l&&l()})}}}function q(c){var l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,h=O(c);h&&g([h],l)}function T(c){return{found:!0,width:c[0],height:c[1],icon:{tag:"path",attributes:{fill:"currentColor",d:c.slice(4)[0]}}}}function j(){Hc.autoAddCss&&(sl||h(tl()),sl=!0)}function F(c,l){return Object.defineProperty(c,"abstract",{get:l}),Object.defineProperty(c,"html",{get:function(){return c.abstract.map(function(c){return u(c)})}}),Object.defineProperty(c,"node",{get:function(){if(K.createElement){var l=K.createElement("div");return l.innerHTML=c.html,l.children}}}),c}function W(c){var l=c.prefix,h=void 0===l?"fa":l,v=c.iconName;if(v)return L(rl.definitions,h,v)||L(wc.styles,h,v)}var P=function(){},I={},R={},B=null,X={mark:P,measure:P};try{"undefined"!=typeof window&&(I=window),"undefined"!=typeof document&&(R=document),"undefined"!=typeof MutationObserver&&(B=MutationObserver),"undefined"!=typeof performance&&(X=performance)}catch(c){}var Y=(I.navigator||{}).userAgent,D=void 0===Y?"":Y,U=I,K=R,G=B,J=X,Q=!!U.document,Z=~D.indexOf("MSIE")||~D.indexOf("Trident/"),$=16,cc="data-fa-processed",lc="data-fa-pseudo-element",hc="fontawesome-i2svg",vc=function(){try{return!0}catch(c){return!1}}(),zc=[1,2,3,4,5,6,7,8,9,10],ec=zc.concat([11,12,13,14,15,16,17,18,19,20]),ac=["class","data-prefix","data-icon","data-fa-transform","data-fa-mask"],mc=["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(zc.map(function(c){return c+"x"})).concat(ec.map(function(c){return"w-"+c})),tc=function(c,l){if(!(c instanceof l))throw new TypeError("Cannot call a class as a function")},sc=function(){function c(c,l){for(var h=0;h=0||Object.prototype.hasOwnProperty.call(c,v)&&(h[v]=c[v]);return h},ic=function(c){if(Array.isArray(c)){for(var l=0,h=Array(c.length);l0&&(h.style=e),r(z)){var a=f({transform:z,containerWidth:v.width,iconWidth:v.width});l.push({tag:"g",attributes:fc({},a.outer),children:[{tag:"g",attributes:fc({},a.inner),children:[{tag:v.icon.tag,children:v.icon.children,attributes:fc({},v.icon.attributes,a.path)}]}]})}else l.push(v.icon);return{children:l,attributes:h}},pc=function(c){var l=c.children,h=c.main,v=c.mask,z=c.attributes,e=c.styles,a=c.transform;if(r(a)&&h.found&&!v.found){var m={x:h.width/h.height/2,y:.5};z.style=s(fc({},e,{"transform-origin":m.x+a.x/16+"em "+(m.y+a.y/16)+"em"}))}return[{tag:"svg",attributes:z,children:l}]},gc=function(c){var l=c.prefix,h=c.iconName,v=c.children,z=c.attributes,e=c.symbol,a=!0===e?l+"-"+Hc.familyPrefix+"-"+h:e;return[{tag:"svg",attributes:{style:"display: none;"},children:[{tag:"symbol",attributes:fc({},z,{id:a}),children:v}]}]},bc=U||{};bc.___FONT_AWESOME___||(bc.___FONT_AWESOME___={}),bc.___FONT_AWESOME___.styles||(bc.___FONT_AWESOME___.styles={}),bc.___FONT_AWESOME___.hooks||(bc.___FONT_AWESOME___.hooks={}),bc.___FONT_AWESOME___.shims||(bc.___FONT_AWESOME___.shims=[]);var wc=bc.___FONT_AWESOME___,yc=function(){},Sc=Hc.measurePerformance&&J&&J.mark&&J.measure?J:{mark:yc,measure:yc},_c=function(c){Sc.mark('FA "5.0.1" '+c+" ends"),Sc.measure('FA "5.0.1" '+c,'FA "5.0.1" '+c+" begins",'FA "5.0.1" '+c+" ends")},kc={begin:function(c){return Sc.mark('FA "5.0.1" '+c+" begins"),function(){return _c(c)}},end:_c},Ac=function(c,l){return function(h,v,z,e){return c.call(l,h,v,z,e)}},xc=function(c,l,h,v){var z,e,a,m=Object.keys(c),t=m.length,s=void 0!==v?Ac(l,v):l;for(void 0===h?(z=1,a=c[m[0]]):(z=0,a=h);z0&&(c[v]=z.join(":").trim()),c},{})),h},Xc=function(c){var l=c.getAttribute("data-prefix"),h=c.getAttribute("data-icon"),v=void 0!==c.innerText?c.innerText.trim():"",z=C(e(c));return l&&h&&(z.prefix=l,z.iconName=h),z.prefix&&v.length>1?z.iconName=o(z.prefix,c.innerText):z.prefix&&1===v.length&&(z.iconName=H(z.prefix,y(c.innerText))),z},Yc=function(c){var l={size:16,x:0,y:0,flipX:!1,flipY:!1,rotate:0};return c?c.toLowerCase().split(" ").reduce(function(c,l){var h=l.toLowerCase().split("-"),v=h[0],z=h.slice(1).join("-");if(v&&"h"===z)return c.flipX=!0,c;if(v&&"v"===z)return c.flipY=!0,c;if(z=parseFloat(z),isNaN(z))return c;switch(v){case"grow":c.size=c.size+z;break;case"shrink":c.size=c.size-z;break;case"left":c.x=c.x-z;break;case"right":c.x=c.x+z;break;case"up":c.y=c.y-z;break;case"down":c.y=c.y+z;break;case"rotate":c.rotate=c.rotate+z}return c},l):l},Dc=function(c){return Yc(c.getAttribute("data-fa-transform"))},Uc=function(c){var l=c.getAttribute("data-fa-symbol");return null!==l&&(""===l||l)},Kc=function(c){var l=z(c.attributes).reduce(function(c,l){return"class"!==c.name&&"style"!==c.name&&(c[l.name]=l.value),c},{}),h=c.getAttribute("title");return Hc.autoA11y&&(h?l["aria-labelledby"]=Hc.replacementClass+"-title-"+v():l["aria-hidden"]="true"),l},Gc=function(c){var l=c.getAttribute("data-fa-mask");return l?C(l.split(" ").map(function(c){return c.trim()})):Wc()};_.prototype=Object.create(Error.prototype),_.prototype.constructor=_;var Jc={fill:"currentColor"},Qc={attributeType:"XML",repeatCount:"indefinite",dur:"2s"},Zc={tag:"path",attributes:fc({},Jc,{d:"M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z"})},$c=fc({},Qc,{attributeName:"opacity"}),cl={tag:"g",children:[Zc,{tag:"circle",attributes:fc({},Jc,{cx:"256",cy:"364",r:"28"}),children:[{tag:"animate",attributes:fc({},Qc,{attributeName:"r",values:"28;14;28;28;14;28;"})},{tag:"animate",attributes:fc({},$c,{values:"1;0;1;1;0;1;"})}]},{tag:"path",attributes:fc({},Jc,{opacity:"1",d:"M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z"}),children:[{tag:"animate",attributes:fc({},$c,{values:"1;0;0;0;0;1;"})}]},{tag:"path",attributes:fc({},Jc,{opacity:"0",d:"M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z"}),children:[{tag:"animate",attributes:fc({},$c,{values:"0;0;1;1;0;0;"})}]}]},ll=wc.styles,hl="fa-layers-text",vl=/Font Awesome 5 (Solid|Regular|Light|Brands)/,zl={Solid:"fas",Regular:"far",Light:"fal",Brands:"fab"},el=[],al=(K.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(K.readyState);al||K.addEventListener("DOMContentLoaded",function c(){K.removeEventListener("DOMContentLoaded",c),al=1,el.map(function(c){return c()})});var ml=function(c){K&&(al?setTimeout(c,0):el.push(c))},tl=function(){var c="svg-inline--fa",l=Hc.familyPrefix,h=Hc.replacementClass,v="svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-12.5%;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1em}.svg-inline--fa.fa-stack-2x{height:2em;width:2em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}";if("fa"!==l||h!==c){var z=new RegExp("\\.fa\\-","g"),e=new RegExp("\\."+c,"g");v=v.replace(z,"."+l+"-").replace(e,"."+h)}return v},sl=!1,rl=new(function(){function c(){tc(this,c),this.definitions={}}return sc(c,[{key:"add",value:function(){for(var c=this,l=arguments.length,h=Array(l),v=0;v0&&void 0!==arguments[0]?arguments[0]:{};j();var l=c.node,h=void 0===l?K:l,v=c.callback,z=void 0===v?function(){}:v;Hc.searchPseudoElements&&E(h),N(h,z)},css:tl,insertCss:function(){h(tl())}},library:rl,parse:{transform:function(c){return Yc(c)}},findIconDefinition:W,icon:function(c){return function(l){var h=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},v=(l||{}).icon?l:W(l||{}),z=h.mask;return z&&(z=(z||{}).icon?z:W(z||{})),c(v,fc({},h,{mask:z}))}}(function(c){var l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},h=l.transform,z=void 0===h?Vc:h,e=l.symbol,a=void 0!==e&&e,m=l.mask,t=void 0===m?null:m,s=l.title,r=void 0===s?null:s,f=l.classes,M=void 0===f?[]:f,n=l.attributes,H=void 0===n?{}:n,o=l.styles,V=void 0===o?{}:o;if(c){var C=c.prefix,L=c.iconName,u=c.icon;return F(fc({type:"icon"},c),function(){return j(),Hc.autoA11y&&(r?H["aria-labelledby"]=Hc.replacementClass+"-title-"+v():H["aria-hidden"]="true"),i({icons:{main:T(u),mask:t?T(t.icon):{found:!1,width:null,height:null,icon:{}}},prefix:C,iconName:L,transform:fc({},Vc,z),symbol:a,title:r,extra:{attributes:H,styles:V,classes:M}})})}}),text:function(c){var l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},h=l.transform,v=void 0===h?Vc:h,z=l.title,e=void 0===z?null:z,a=l.classes,m=void 0===a?[]:a,t=l.attributes,s=void 0===t?{}:t,r=l.styles,f=void 0===r?{}:r;return F({type:"text",content:c},function(){return j(),n({content:c,transform:fc({},Vc,v),title:e,extra:{attributes:s,styles:f,classes:[Hc.familyPrefix+"-layers-text"].concat(ic(m))}})})},layer:function(c){return F({type:"layer"},function(){j();var l=[];return c(function(c){l=Array.isArray(c)?c.map(function(c){l=l.concat(c.abstract)}):l.concat(c.abstract)}),[{tag:"span",attributes:{class:Hc.familyPrefix+"-layers"},children:l}]})}};Object.defineProperty(fl,"config",{get:function(){Hc.autoReplaceSvg,Hc.observeMutations,Hc.showMissingIcons;return Mc(Hc,["autoReplaceSvg","observeMutations","showMissingIcons"])},set:function(l){c(l)}}),function(c){try{c()}catch(c){}}(function(){var c=function(){Hc.autoReplaceSvg&&fl.dom.i2svg({node:K})};Q&&(U.FontAwesome||(U.FontAwesome=fl),ml(function(){Object.keys(wc.styles).length>0&&c(),Hc.observeMutations&&"function"==typeof MutationObserver&&w({treeCallback:N,nodeCallback:q,pseudoElementsCallback:E})})),wc.hooks=fc({},wc.hooks,{addPack:function(l,h){wc.styles[l]=fc({},wc.styles[l]||{},h),jc(),c()},addShims:function(l){var h;(h=wc.shims).push.apply(h,ic(l)),jc(),c()}})})}(); \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.js b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.js new file mode 100644 index 000000000..01794e88d --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.js @@ -0,0 +1,1730 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +(function () { +'use strict'; + +var noop = function noop() {}; + +var _WINDOW = {}; +var _DOCUMENT = {}; +var _MUTATION_OBSERVER$1 = null; +var _PERFORMANCE = { mark: noop, measure: noop }; + +try { + if (typeof window !== 'undefined') _WINDOW = window; + if (typeof document !== 'undefined') _DOCUMENT = document; + if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER$1 = MutationObserver; + if (typeof performance !== 'undefined') _PERFORMANCE = performance; +} catch (e) {} + +var _ref = _WINDOW.navigator || {}; +var _ref$userAgent = _ref.userAgent; +var userAgent = _ref$userAgent === undefined ? '' : _ref$userAgent; + +var WINDOW = _WINDOW; +var DOCUMENT = _DOCUMENT; +var MUTATION_OBSERVER = _MUTATION_OBSERVER$1; +var PERFORMANCE = _PERFORMANCE; +var IS_BROWSER = !!WINDOW.document; +var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/'); + +var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___'; +var UNITS_IN_GRID = 16; +var DEFAULT_FAMILY_PREFIX = 'fa'; +var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa'; +var DATA_FA_PROCESSED = 'data-fa-processed'; +var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element'; +var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg'; + +var PRODUCTION = function () { + try { + return "production" === 'production'; + } catch (e) { + return false; + } +}(); + +var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); + +var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask']; + +var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter'].concat(oneToTen.map(function (n) { + return n + 'x'; +})).concat(oneToTwenty.map(function (n) { + return 'w-' + n; +})); + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +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 function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + +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]; + } + } + } + + return target; +}; + +var objectWithoutProperties = function (obj, keys) { + var target = {}; + + for (var i in obj) { + if (keys.indexOf(i) >= 0) continue; + if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; + target[i] = obj[i]; + } + + return target; +}; + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +var _default = _extends({ + familyPrefix: DEFAULT_FAMILY_PREFIX, + replacementClass: DEFAULT_REPLACEMENT_CLASS, + autoReplaceSvg: true, + autoAddCss: true, + autoA11y: true, + searchPseudoElements: false, + observeMutations: true, + keepOriginalSource: true, + measurePerformance: false, + showMissingIcons: true +}, WINDOW.FontAwesomeConfig || {}); + +if (!_default.autoReplaceSvg) _default.observeMutations = false; + +var config = _extends({}, _default); + +WINDOW.FontAwesomeConfig = config; + +function update(newConfig) { + var validKeys = Object.keys(config); + + Object.keys(newConfig).forEach(function (configKey) { + if (~validKeys.indexOf(configKey)) { + config[configKey] = newConfig[configKey]; + } + }); +} + +var d = UNITS_IN_GRID; + +var meaninglessTransform = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: false, + flipY: false +}; + +function isReserved(name) { + return ~RESERVED_CLASSES.indexOf(name); +} + +function bunker(fn) { + try { + fn(); + } catch (e) { + + } +} + +function insertCss(css) { + if (!css) { + return; + } + + if (typeof DOCUMENT.createElement === 'undefined') { + return; + } + + var style = DOCUMENT.createElement('style'); + style.setAttribute('type', 'text/css'); + style.innerHTML = css; + + var headChildren = DOCUMENT.head.childNodes; + var beforeChild = null; + + for (var i = headChildren.length - 1; i > -1; i--) { + var child = headChildren[i]; + var tagName = (child.tagName || '').toUpperCase(); + if (['STYLE', 'LINK'].indexOf(tagName) > -1) { + beforeChild = child; + } + } + + DOCUMENT.head.insertBefore(style, beforeChild); + + return css; +} + +var _uniqueId = 0; + +function nextUniqueId() { + _uniqueId++; + + return _uniqueId; +} + +function toArray(obj) { + var array = []; + + for (var i = (obj || []).length >>> 0; i--;) { + array[i] = obj[i]; + } + + return array; +} + +function classArray(node) { + if (node.classList) { + return toArray(node.classList); + } else { + return (node.getAttribute('class') || '').split(' ').filter(function (i) { + return i; + }); + } +} + +function getIconName(familyPrefix, cls) { + var parts = cls.split('-'); + var prefix = parts[0]; + var iconName = parts.slice(1).join('-'); + + if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) { + return iconName; + } else { + return null; + } +} + +function htmlEscape(str) { + return ('' + str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); +} + +function joinAttributes(attributes) { + return Object.keys(attributes || {}).reduce(function (acc, attributeName) { + return acc + (attributeName + '="' + htmlEscape(attributes[attributeName]) + '" '); + }, '').trim(); +} + +function joinStyles(styles) { + return Object.keys(styles || {}).reduce(function (acc, styleName) { + return acc + (styleName + ': ' + styles[styleName] + ';'); + }, ''); +} + +function transformIsMeaningful(transform) { + return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; +} + +function transformForSvg(_ref) { + var transform = _ref.transform, + containerWidth = _ref.containerWidth, + iconWidth = _ref.iconWidth; + + var outer = { + transform: 'translate(' + containerWidth / 2 + ' 256)' + }; + var innerTranslate = 'translate(' + transform.x * 32 + ', ' + transform.y * 32 + ') '; + var innerScale = 'scale(' + transform.size / 16 * (transform.flipX ? -1 : 1) + ', ' + transform.size / 16 * (transform.flipY ? -1 : 1) + ') '; + var innerRotate = 'rotate(' + transform.rotate + ' 0 0)'; + var inner = { + transform: innerTranslate + ' ' + innerScale + ' ' + innerRotate + }; + var path = { + transform: 'translate(' + iconWidth / 2 * -1 + ' -256)' + }; + return { + outer: outer, + inner: inner, + path: path + }; +} + +function transformForCss(_ref2) { + var transform = _ref2.transform, + _ref2$width = _ref2.width, + width = _ref2$width === undefined ? UNITS_IN_GRID : _ref2$width, + _ref2$height = _ref2.height, + height = _ref2$height === undefined ? UNITS_IN_GRID : _ref2$height, + _ref2$startCentered = _ref2.startCentered, + startCentered = _ref2$startCentered === undefined ? false : _ref2$startCentered; + + var val = ''; + + if (startCentered && IS_IE) { + val += 'translate(' + (transform.x / d - width / 2) + 'em, ' + (transform.y / d - height / 2) + 'em) '; + } else if (startCentered) { + val += 'translate(calc(-50% + ' + transform.x / d + 'em), calc(-50% + ' + transform.y / d + 'em)) '; + } else { + val += 'translate(' + transform.x / d + 'em, ' + transform.y / d + 'em) '; + } + + val += 'scale(' + transform.size / d * (transform.flipX ? -1 : 1) + ', ' + transform.size / d * (transform.flipY ? -1 : 1) + ') '; + val += 'rotate(' + transform.rotate + 'deg) '; + + return val; +} + +var ALL_SPACE = { + x: 0, + y: 0, + width: '100%', + height: '100%' +}; + +var makeIconMasking = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + mask = _ref.mask, + transform = _ref.transform; + var mainWidth = main.width, + mainPath = main.icon; + var maskWidth = mask.width, + maskPath = mask.icon; + + + var trans = transformForSvg({ transform: transform, containerWidth: maskWidth, iconWidth: mainWidth }); + + var maskRect = { + tag: 'rect', + attributes: _extends({}, ALL_SPACE, { + fill: 'white' + }) + }; + var maskInnerGroup = { + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ tag: 'path', attributes: _extends({}, mainPath.attributes, trans.path, { fill: 'black' }) }] + }; + var maskOuterGroup = { + tag: 'g', + attributes: _extends({}, trans.outer), + children: [maskInnerGroup] + }; + var maskId = 'mask-' + nextUniqueId(); + var clipId = 'clip-' + nextUniqueId(); + var maskTag = { + tag: 'mask', + attributes: _extends({}, ALL_SPACE, { + id: maskId, + maskUnits: 'userSpaceOnUse', + maskContentUnits: 'userSpaceOnUse' + }), + children: [maskRect, maskOuterGroup] + }; + var defs = { + tag: 'defs', + children: [{ tag: 'clipPath', attributes: { id: clipId }, children: [maskPath] }, maskTag] + }; + + children.push(defs, { tag: 'rect', attributes: _extends({ fill: 'currentColor', 'clip-path': 'url(#' + clipId + ')', mask: 'url(#' + maskId + ')' }, ALL_SPACE) }); + + return { + children: children, + attributes: attributes + }; +}; + +var makeIconStandard = function (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + transform = _ref.transform, + styles = _ref.styles; + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + if (transformIsMeaningful(transform)) { + var trans = transformForSvg({ transform: transform, containerWidth: main.width, iconWidth: main.width }); + children.push({ + tag: 'g', + attributes: _extends({}, trans.outer), + children: [{ + tag: 'g', + attributes: _extends({}, trans.inner), + children: [{ + tag: main.icon.tag, + children: main.icon.children, + attributes: _extends({}, main.icon.attributes, trans.path) + }] + }] + }); + } else { + children.push(main.icon); + } + + return { + children: children, + attributes: attributes + }; +}; + +var asIcon = function (_ref) { + var children = _ref.children, + main = _ref.main, + mask = _ref.mask, + attributes = _ref.attributes, + styles = _ref.styles, + transform = _ref.transform; + + if (transformIsMeaningful(transform) && main.found && !mask.found) { + var width = main.width, + height = main.height; + + var offset = { + x: width / height / 2, + y: 0.5 + }; + attributes['style'] = joinStyles(_extends({}, styles, { + 'transform-origin': offset.x + transform.x / 16 + 'em ' + (offset.y + transform.y / 16) + 'em' + })); + } + + return [{ + tag: 'svg', + attributes: attributes, + children: children + }]; +}; + +var asSymbol = function (_ref) { + var prefix = _ref.prefix, + iconName = _ref.iconName, + children = _ref.children, + attributes = _ref.attributes, + symbol = _ref.symbol; + + var id = symbol === true ? prefix + '-' + config.familyPrefix + '-' + iconName : symbol; + + return [{ + tag: 'svg', + attributes: { + style: 'display: none;' + }, + children: [{ + tag: 'symbol', + attributes: _extends({}, attributes, { id: id }), + children: children + }] + }]; +}; + +function makeInlineSvgAbstract(params) { + var _babelHelpers$extends; + + var _params$icons = params.icons, + main = _params$icons.main, + mask = _params$icons.mask, + prefix = params.prefix, + iconName = params.iconName, + transform = params.transform, + symbol = params.symbol, + title = params.title, + extra = params.extra; + + var _ref = mask.found ? mask : main, + width = _ref.width, + height = _ref.height; + + var widthClass = 'fa-w-' + Math.ceil(width / height * 16); + var attrClass = [config.replacementClass, iconName ? config.familyPrefix + '-' + iconName : '', widthClass].concat(extra.classes).join(' '); + + var content = { + children: [], + attributes: _extends({}, extra.attributes, (_babelHelpers$extends = {}, defineProperty(_babelHelpers$extends, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends, 'data-prefix', prefix), defineProperty(_babelHelpers$extends, 'data-icon', iconName), defineProperty(_babelHelpers$extends, 'class', attrClass), defineProperty(_babelHelpers$extends, 'role', 'img'), defineProperty(_babelHelpers$extends, 'xmlns', 'http://www.w3.org/2000/svg'), defineProperty(_babelHelpers$extends, 'viewBox', '0 0 ' + width + ' ' + height), _babelHelpers$extends)) + }; + + if (title) content.children.push({ tag: 'title', attributes: { id: content.attributes['aria-labelledby'] || 'title-' + nextUniqueId() }, children: [title] }); + + var args = _extends({}, content, { + prefix: prefix, + iconName: iconName, + main: main, + mask: mask, + transform: transform, + symbol: symbol, + styles: extra.styles + }); + + var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), + children = _ref2.children, + attributes = _ref2.attributes; + + args.children = children; + args.attributes = attributes; + + if (symbol) { + return asSymbol(args); + } else { + return asIcon(args); + } +} + +function makeLayersTextAbstract(params) { + var _babelHelpers$extends2; + + var content = params.content, + width = params.width, + height = params.height, + transform = params.transform, + title = params.title, + extra = params.extra; + + + var attributes = _extends({}, extra.attributes, title ? { 'title': title } : {}, (_babelHelpers$extends2 = {}, defineProperty(_babelHelpers$extends2, DATA_FA_PROCESSED, ''), defineProperty(_babelHelpers$extends2, 'class', extra.classes.join(' ')), _babelHelpers$extends2)); + + var styles = _extends({}, extra.styles); + + if (transformIsMeaningful(transform)) { + styles['transform'] = transformForCss({ transform: transform, startCentered: true, width: width, height: height }); + styles['-webkit-transform'] = styles['transform']; + } + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ tag: 'span', attributes: { class: 'sr-only' }, children: [title] }); + } + + return val; +} + +var w = WINDOW || {}; + +if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; +if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; +if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; +if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + +var namespace = w[NAMESPACE_IDENTIFIER]; + +var noop$2 = function noop() {}; +var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { mark: noop$2, measure: noop$2 }; +var preamble = 'FA "5.0.1"'; + +var begin = function begin(name) { + p.mark(preamble + ' ' + name + ' begins'); + return function () { + return end(name); + }; +}; + +var end = function end(name) { + p.mark(preamble + ' ' + name + ' ends'); + p.measure(preamble + ' ' + name, preamble + ' ' + name + ' begins', preamble + ' ' + name + ' ends'); +}; + +var perf = { begin: begin, end: end }; + +'use strict'; + +/** + * Internal helper to bind a function known to have 4 arguments + * to a given context. + */ +var bindInternal4 = function bindInternal4 (func, thisContext) { + return function (a, b, c, d) { + return func.call(thisContext, a, b, c, d); + }; +}; + +'use strict'; + + + +/** + * # Reduce + * + * A fast object `.reduce()` implementation. + * + * @param {Object} subject The object to reduce over. + * @param {Function} fn The reducer function. + * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0]. + * @param {Object} thisContext The context for the reducer. + * @return {mixed} The final result. + */ +var reduce = function fastReduceObject (subject, fn, initialValue, thisContext) { + var keys = Object.keys(subject), + length = keys.length, + iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn, + i, key, result; + + if (initialValue === undefined) { + i = 1; + result = subject[keys[0]]; + } + else { + i = 0; + result = initialValue; + } + + for (; i < length; i++) { + key = keys[i]; + result = iterator(result, subject[key], key, subject); + } + + return result; +}; + +var styles$2 = namespace.styles; +var shims = namespace.shims; + + +var _byUnicode = {}; +var _byLigature = {}; +var _byOldName = {}; + +var build = function build() { + var lookup = function lookup(reducer) { + return reduce(styles$2, function (o, style, prefix) { + o[prefix] = reduce(style, reducer, {}); + return o; + }, {}); + }; + + _byUnicode = lookup(function (acc, icon, iconName) { + acc[icon[3]] = iconName; + + return acc; + }); + + _byLigature = lookup(function (acc, icon, iconName) { + var ligatures = icon[2]; + + acc[iconName] = iconName; + + ligatures.forEach(function (ligature) { + acc[ligature] = iconName; + }); + + return acc; + }); + + var hasRegular = 'far' in styles$2; + + _byOldName = reduce(shims, function (acc, shim) { + var oldName = shim[0]; + var prefix = shim[1]; + var iconName = shim[2]; + + if (prefix === 'far' && !hasRegular) { + prefix = 'fas'; + } + + acc[oldName] = { prefix: prefix, iconName: iconName }; + + return acc; + }, {}); +}; + +build(); + +function byUnicode(prefix, unicode) { + return _byUnicode[prefix][unicode]; +} + +function byLigature(prefix, ligature) { + return _byLigature[prefix][ligature]; +} + +function byOldName(name) { + return _byOldName[name] || { prefix: null, iconName: null }; +} + +var styles$1 = namespace.styles; + + +var emptyCanonicalIcon = function emptyCanonicalIcon() { + return { prefix: null, iconName: null, rest: [] }; +}; + +function getCanonicalIcon(values) { + return values.reduce(function (acc, cls) { + var iconName = getIconName(config.familyPrefix, cls); + + if (styles$1[cls]) { + acc.prefix = cls; + } else if (iconName) { + var shim = acc.prefix === 'fa' ? byOldName(iconName) : {}; + + acc.iconName = shim.iconName || iconName; + acc.prefix = shim.prefix || acc.prefix; + } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) { + acc.rest.push(cls); + } + + return acc; + }, emptyCanonicalIcon()); +} + +function iconFromMapping(mapping, prefix, iconName) { + if (mapping && mapping[prefix] && mapping[prefix][iconName]) { + return { + prefix: prefix, + iconName: iconName, + icon: mapping[prefix][iconName] + }; + } +} + +function toHtml(abstractNodes) { + var tag = abstractNodes.tag, + _abstractNodes$attrib = abstractNodes.attributes, + attributes = _abstractNodes$attrib === undefined ? {} : _abstractNodes$attrib, + _abstractNodes$childr = abstractNodes.children, + children = _abstractNodes$childr === undefined ? [] : _abstractNodes$childr; + + + if (typeof abstractNodes === 'string') { + return htmlEscape(abstractNodes); + } else { + return '<' + tag + ' ' + joinAttributes(attributes) + '>' + children.map(toHtml).join('') + ''; + } +} + +var noop$1 = function noop() {}; + +function isReplaced(node) { + var nodeClass = node.getAttribute ? node.getAttribute('class') : null; + + if (nodeClass) { + return !!~nodeClass.toString().indexOf(config.replacementClass) || ~nodeClass.toString().indexOf('fa-layers-text'); + } else { + return false; + } +} + +function getMutator() { + if (config.autoReplaceSvg === true) { + return mutators.replace; + } + + var mutator = mutators[config.autoReplaceSvg]; + + return mutator || mutators.replace; +} + +var mutators = { + replace: function replace(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + var newOuterHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + + if (node.parentNode && node.outerHTML) { + node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? '' : ''); + } else if (node.parentNode) { + var newNode = document.createElement('span'); + node.parentNode.replaceChild(newNode, node); + newNode.outerHTML = newOuterHTML; + } + }, + nest: function nest(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + + // If we already have a replaced node we do not want to continue nesting within it. + // Short-circuit to the standard replacement + if (~classArray(node).indexOf(config.replacementClass)) { + return mutators.replace(mutation); + } + + var forSvg = new RegExp(config.familyPrefix + '-.*'); + + delete abstract[0].attributes.style; + + var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) { + if (cls === config.replacementClass || cls.match(forSvg)) { + acc.toSvg.push(cls); + } else { + acc.toNode.push(cls); + } + + return acc; + }, { toNode: [], toSvg: [] }); + + abstract[0].attributes.class = splitClasses.toSvg.join(' '); + + var newInnerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.setAttribute('class', splitClasses.toNode.join(' ')); + node.setAttribute(DATA_FA_PROCESSED, ''); + node.innerHTML = newInnerHTML; + } +}; + +function perform(mutations, callback) { + var callbackFunction = typeof callback === 'function' ? callback : noop$1; + + if (mutations.length === 0) { + callbackFunction(); + } else { + var frame = WINDOW.requestAnimationFrame || function (op) { + return op(); + }; + + frame(function () { + var mutator = getMutator(); + var mark = perf.begin('mutate'); + + mutations.map(mutator); + + mark(); + + callbackFunction(); + }); + } +} + +var disabled = false; + +function disableObservation(operation) { + disabled = true; + operation(); + disabled = false; +} + +function observe(options) { + if (!MUTATION_OBSERVER) return; + + var treeCallback = options.treeCallback, + nodeCallback = options.nodeCallback, + pseudoElementsCallback = options.pseudoElementsCallback; + + var mo = new MUTATION_OBSERVER(function (objects) { + if (disabled) return; + + toArray(objects).forEach(function (mutationRecord) { + if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isReplaced(mutationRecord.addedNodes[0])) { + if (config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target); + } + + treeCallback(mutationRecord.target); + } + + if (mutationRecord.type === 'attributes' && mutationRecord.attributeName === 'class' && mutationRecord.target.parentNode && config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target.parentNode); + } + + if (mutationRecord.type === 'attributes' && isReplaced(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) { + if (mutationRecord.attributeName === 'class') { + var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)), + prefix = _getCanonicalIcon.prefix, + iconName = _getCanonicalIcon.iconName; + + if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix); + if (iconName) mutationRecord.target.setAttribute('data-icon', iconName); + } else { + nodeCallback(mutationRecord.target); + } + } + }); + }); + + if (!DOCUMENT.getElementsByTagName) return; + + mo.observe(DOCUMENT.getElementsByTagName('body')[0], { + childList: true, attributes: true, characterData: true, subtree: true + }); +} + +var styleParser = function (node) { + var style = node.getAttribute('style'); + + var val = []; + + if (style) { + val = style.split(';').reduce(function (acc, style) { + var styles = style.split(':'); + var prop = styles[0]; + var value = styles.slice(1); + + if (prop && value.length > 0) { + acc[prop] = value.join(':').trim(); + } + + return acc; + }, {}); + } + + return val; +}; + +function toHex(unicode) { + var result = ''; + + for (var i = 0; i < unicode.length; i++) { + var hex = unicode.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + + return result; +} + +var classParser = function (node) { + var existingPrefix = node.getAttribute('data-prefix'); + var existingIconName = node.getAttribute('data-icon'); + var innerText = node.innerText !== undefined ? node.innerText.trim() : ''; + + var val = getCanonicalIcon(classArray(node)); + + if (existingPrefix && existingIconName) { + val.prefix = existingPrefix; + val.iconName = existingIconName; + } + + if (val.prefix && innerText.length > 1) { + val.iconName = byLigature(val.prefix, node.innerText); + } else if (val.prefix && innerText.length === 1) { + val.iconName = byUnicode(val.prefix, toHex(node.innerText)); + } + + return val; +}; + +var parseTransformString = function parseTransformString(transformString) { + var transform = { + size: 16, + x: 0, + y: 0, + flipX: false, + flipY: false, + rotate: 0 + }; + + if (!transformString) { + return transform; + } else { + return transformString.toLowerCase().split(' ').reduce(function (acc, n) { + var parts = n.toLowerCase().split('-'); + var first = parts[0]; + var rest = parts.slice(1).join('-'); + + if (first && rest === 'h') { + acc.flipX = true; + return acc; + } + + if (first && rest === 'v') { + acc.flipY = true; + return acc; + } + + rest = parseFloat(rest); + + if (isNaN(rest)) { + return acc; + } + + switch (first) { + case 'grow': + acc.size = acc.size + rest; + break; + case 'shrink': + acc.size = acc.size - rest; + break; + case 'left': + acc.x = acc.x - rest; + break; + case 'right': + acc.x = acc.x + rest; + break; + case 'up': + acc.y = acc.y - rest; + break; + case 'down': + acc.y = acc.y + rest; + break; + case 'rotate': + acc.rotate = acc.rotate + rest; + break; + } + + return acc; + }, transform); + } +}; + +var transformParser = function (node) { + return parseTransformString(node.getAttribute('data-fa-transform')); +}; + +var symbolParser = function (node) { + var symbol = node.getAttribute('data-fa-symbol'); + + return symbol === null ? false : symbol === '' ? true : symbol; +}; + +var attributesParser = function (node) { + var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) { + if (acc.name !== 'class' && acc.name !== 'style') { + acc[attr.name] = attr.value; + } + return acc; + }, {}); + + var title = node.getAttribute('title'); + + if (config.autoA11y) { + if (title) { + extraAttributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + extraAttributes['aria-hidden'] = 'true'; + } + } + + return extraAttributes; +}; + +var maskParser = function (node) { + var mask = node.getAttribute('data-fa-mask'); + + if (!mask) { + return emptyCanonicalIcon(); + } else { + return getCanonicalIcon(mask.split(' ').map(function (i) { + return i.trim(); + })); + } +}; + +function parseMeta(node) { + var _classParser = classParser(node), + iconName = _classParser.iconName, + prefix = _classParser.prefix, + extraClasses = _classParser.rest; + + var extraStyles = styleParser(node); + var transform = transformParser(node); + var symbol = symbolParser(node); + var extraAttributes = attributesParser(node); + var mask = maskParser(node); + + return { + iconName: iconName, + title: node.getAttribute('title'), + prefix: prefix, + transform: transform, + symbol: symbol, + mask: mask, + extra: { + classes: extraClasses, + styles: extraStyles, + attributes: extraAttributes + } + }; +} + +function MissingIcon(error) { + this.name = 'MissingIcon'; + this.message = error || 'Icon unavailable'; + this.stack = new Error().stack; +} + +MissingIcon.prototype = Object.create(Error.prototype); +MissingIcon.prototype.constructor = MissingIcon; + +var FILL = { fill: 'currentColor' }; +var ANIMATION_BASE = { + attributeType: 'XML', + repeatCount: 'indefinite', + dur: '2s' +}; +var RING = { + tag: 'path', + attributes: _extends({}, FILL, { + d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z' + }) +}; +var OPACITY_ANIMATE = _extends({}, ANIMATION_BASE, { + attributeName: 'opacity' +}); +var DOT = { + tag: 'circle', + attributes: _extends({}, FILL, { + cx: '256', + cy: '364', + r: '28' + }), + children: [{ tag: 'animate', attributes: _extends({}, ANIMATION_BASE, { attributeName: 'r', values: '28;14;28;28;14;28;' }) }, { tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;1;1;0;1;' }) }] +}; +var QUESTION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '1', + d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '1;0;0;0;0;1;' }) }] +}; +var EXCLAMATION = { + tag: 'path', + attributes: _extends({}, FILL, { + opacity: '0', + d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z' + }), + children: [{ tag: 'animate', attributes: _extends({}, OPACITY_ANIMATE, { values: '0;0;1;1;0;0;' }) }] +}; + +var missing = { tag: 'g', children: [RING, DOT, QUESTION, EXCLAMATION] }; + +var styles = namespace.styles; + +var LAYERS_TEXT_CLASSNAME = 'fa-layers-text'; +var FONT_FAMILY_PATTERN = /Font Awesome 5 (Solid|Regular|Light|Brands)/; +var STYLE_TO_PREFIX = { + 'Solid': 'fas', + 'Regular': 'far', + 'Light': 'fal', + 'Brands': 'fab' +}; + +function findIcon(iconName, prefix) { + var val = { + found: false, + width: 512, + height: 512, + icon: missing + }; + + if (iconName && prefix && styles[prefix] && styles[prefix][iconName]) { + var icon = styles[prefix][iconName]; + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + val = { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; + } else if (iconName && prefix && !config.showMissingIcons) { + throw new MissingIcon('Icon is missing for prefix ' + prefix + ' with icon name ' + iconName); + } + + return val; +} + +function generateSvgReplacementMutation(node, nodeMeta) { + var iconName = nodeMeta.iconName, + title = nodeMeta.title, + prefix = nodeMeta.prefix, + transform = nodeMeta.transform, + symbol = nodeMeta.symbol, + mask = nodeMeta.mask, + extra = nodeMeta.extra; + + + return [node, makeInlineSvgAbstract({ + icons: { + main: findIcon(iconName, prefix), + mask: findIcon(mask.iconName, mask.prefix) + }, + prefix: prefix, + iconName: iconName, + transform: transform, + symbol: symbol, + mask: mask, + title: title, + extra: extra + })]; +} + +function generateLayersText(node, nodeMeta) { + var title = nodeMeta.title, + transform = nodeMeta.transform, + extra = nodeMeta.extra; + + + var width = null; + var height = null; + + if (IS_IE) { + var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10); + var boundingClientRect = node.getBoundingClientRect(); + width = boundingClientRect.width / computedFontSize; + height = boundingClientRect.height / computedFontSize; + } + + if (config.autoA11y && !title) { + extra.attributes['aria-hidden'] = 'true'; + } + + return [node, makeLayersTextAbstract({ + content: node.innerHTML, + width: width, + height: height, + transform: transform, + title: title, + extra: extra + })]; +} + +function generateMutation(node) { + var nodeMeta = parseMeta(node); + + if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) { + return generateLayersText(node, nodeMeta); + } else { + return generateSvgReplacementMutation(node, nodeMeta); + } +} + +function searchPseudoElements(root) { + var end = perf.begin('searchPseudoElements'); + + disableObservation(function () { + toArray(root.querySelectorAll('*')).forEach(function (node) { + [':before', ':after'].forEach(function (pos) { + var styles = WINDOW.getComputedStyle(node, pos); + var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN); + var children = toArray(node.children); + var pseudoElement = children.filter(function (c) { + return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === pos; + })[0]; + + if (!fontFamily && pseudoElement) { + pseudoElement.remove(); + } + + if (fontFamily && !pseudoElement) { + var content = styles.getPropertyValue('content'); + var i = DOCUMENT.createElement('i'); + i.setAttribute('class', '' + STYLE_TO_PREFIX[fontFamily[1]]); + i.setAttribute(DATA_FA_PSEUDO_ELEMENT, pos); + i.innerText = content.length === 3 ? content.substr(1, 1) : content; + if (pos === ':before') { + node.insertBefore(i, node.firstChild); + } else { + node.appendChild(i); + } + } + }); + }); + }); + + end(); +} + +function onTree(root) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var htmlClassList = DOCUMENT.documentElement.classList; + var hclAdd = function hclAdd(suffix) { + return htmlClassList.add(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var hclRemove = function hclRemove(suffix) { + return htmlClassList.remove(HTML_CLASS_I2SVG_BASE_CLASS + '-' + suffix); + }; + var prefixes = Object.keys(styles); + var prefixesDomQuery = ['.' + LAYERS_TEXT_CLASSNAME + ':not([' + DATA_FA_PROCESSED + '])'].concat(prefixes.map(function (p) { + return '.' + p + ':not([' + DATA_FA_PROCESSED + '])'; + })).join(', '); + + if (prefixesDomQuery.length === 0) { + return; + } + + var candidates = toArray(root.querySelectorAll(prefixesDomQuery)); + + if (candidates.length > 0) { + hclAdd('pending'); + hclRemove('complete'); + } else { + return; + } + + var mark = perf.begin('onTree'); + + var mutations = candidates.reduce(function (acc, node) { + try { + var mutation = generateMutation(node); + + if (mutation) { + acc.push(mutation); + } + } catch (e) { + if (!PRODUCTION) { + if (e instanceof MissingIcon) { + console.error(e); + } + } + } + + return acc; + }, []); + + mark(); + + perform(mutations, function () { + hclAdd('active'); + hclAdd('complete'); + hclRemove('pending'); + + if (typeof callback === 'function') callback(); + }); +} + +function onNode(node) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + var mutation = generateMutation(node); + + if (mutation) { + perform([mutation], callback); + } +} + +var functions = []; +var listener = function listener() { + DOCUMENT.removeEventListener('DOMContentLoaded', listener); + loaded = 1; + functions.map(function (fn) { + return fn(); + }); +}; + +var loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState); + +if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener); + +var domready = function (fn) { + if (!DOCUMENT) return; + loaded ? setTimeout(fn, 0) : functions.push(fn); +}; + +var baseStyles = "svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-12.5%;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1em}.svg-inline--fa.fa-stack-2x{height:2em;width:2em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}"; + +var css = function () { + var dfp = DEFAULT_FAMILY_PREFIX; + var drc = DEFAULT_REPLACEMENT_CLASS; + var fp = config.familyPrefix; + var rc = config.replacementClass; + var s = baseStyles; + + if (fp !== dfp || rc !== drc) { + var dPatt = new RegExp('\\.' + dfp + '\\-', 'g'); + var rPatt = new RegExp('\\.' + drc, 'g'); + + s = s.replace(dPatt, '.' + fp + '-').replace(rPatt, '.' + rc); + } + + return s; +}; + +var Library = function () { + function Library() { + classCallCheck(this, Library); + + this.definitions = {}; + } + + createClass(Library, [{ + key: "add", + value: function add() { + var _this = this; + + for (var _len = arguments.length, definitions = Array(_len), _key = 0; _key < _len; _key++) { + definitions[_key] = arguments[_key]; + } + + var additions = definitions.reduce(this._pullDefinitions, {}); + + Object.keys(additions).forEach(function (key) { + _this.definitions[key] = _extends({}, _this.definitions[key] || {}, additions[key]); + }); + } + }, { + key: "reset", + value: function reset() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function _pullDefinitions(additions, definition) { + var normalized = definition.prefix && definition.iconName && definition.icon ? { 0: definition } : definition; + + Object.keys(normalized).map(function (key) { + var _normalized$key = normalized[key], + prefix = _normalized$key.prefix, + iconName = _normalized$key.iconName, + icon = _normalized$key.icon; + + + if (!additions[prefix]) additions[prefix] = {}; + + additions[prefix][iconName] = icon; + }); + + return additions; + } + }]); + return Library; +}(); + +function prepIcon(icon) { + var width = icon[0]; + var height = icon[1]; + var vectorData = icon.slice(4); + + return { + found: true, + width: width, + height: height, + icon: { tag: 'path', attributes: { fill: 'currentColor', d: vectorData[0] } } + }; +} + +var _cssInserted = false; + +function ensureCss() { + if (!config.autoAddCss) { + return; + } + + if (!_cssInserted) { + insertCss(css()); + } + + _cssInserted = true; +} + +function apiObject(val, abstractCreator) { + Object.defineProperty(val, 'abstract', { + get: abstractCreator + }); + + Object.defineProperty(val, 'html', { + get: function get() { + return val.abstract.map(function (a) { + return toHtml(a); + }); + } + }); + + Object.defineProperty(val, 'node', { + get: function get() { + if (!DOCUMENT.createElement) return; + + var container = DOCUMENT.createElement('div'); + container.innerHTML = val.html; + return container.children; + } + }); + + return val; +} + +function findIconDefinition(params) { + var _params$prefix = params.prefix, + prefix = _params$prefix === undefined ? 'fa' : _params$prefix, + iconName = params.iconName; + + + if (!iconName) return; + + return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); +} + +function resolveIcons(next) { + return function (maybeIconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); + + var mask = params.mask; + + + if (mask) { + mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); + } + + return next(iconDefinition, _extends({}, params, { mask: mask })); + }; +} + +var library = new Library(); + +var api = { + dom: { + i2svg: function i2svg() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + ensureCss(); + + var _params$node = params.node, + node = _params$node === undefined ? DOCUMENT : _params$node, + _params$callback = params.callback, + callback = _params$callback === undefined ? function () {} : _params$callback; + + + if (config.searchPseudoElements) { + searchPseudoElements(node); + } + + onTree(node, callback); + }, + + css: css, + + insertCss: function insertCss$$1() { + insertCss(css()); + } + }, + + library: library, + + parse: { + transform: function transform(transformString) { + return parseTransformString(transformString); + } + }, + + findIconDefinition: findIconDefinition, + + icon: resolveIcons(function (iconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform = params.transform, + transform = _params$transform === undefined ? meaninglessTransform : _params$transform, + _params$symbol = params.symbol, + symbol = _params$symbol === undefined ? false : _params$symbol, + _params$mask = params.mask, + mask = _params$mask === undefined ? null : _params$mask, + _params$title = params.title, + title = _params$title === undefined ? null : _params$title, + _params$classes = params.classes, + classes = _params$classes === undefined ? [] : _params$classes, + _params$attributes = params.attributes, + attributes = _params$attributes === undefined ? {} : _params$attributes, + _params$styles = params.styles, + styles = _params$styles === undefined ? {} : _params$styles; + + + if (!iconDefinition) return; + + var prefix = iconDefinition.prefix, + iconName = iconDefinition.iconName, + icon = iconDefinition.icon; + + + return apiObject(_extends({ type: 'icon' }, iconDefinition), function () { + ensureCss(); + + if (config.autoA11y) { + if (title) { + attributes['aria-labelledby'] = config.replacementClass + '-title-' + nextUniqueId(); + } else { + attributes['aria-hidden'] = 'true'; + } + } + + return makeInlineSvgAbstract({ + icons: { + main: prepIcon(icon), + mask: mask ? prepIcon(mask.icon) : { found: false, width: null, height: null, icon: {} } + }, + prefix: prefix, + iconName: iconName, + transform: _extends({}, meaninglessTransform, transform), + symbol: symbol, + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: classes + } + }); + }); + }), + + text: function text(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform2 = params.transform, + transform = _params$transform2 === undefined ? meaninglessTransform : _params$transform2, + _params$title2 = params.title, + title = _params$title2 === undefined ? null : _params$title2, + _params$classes2 = params.classes, + classes = _params$classes2 === undefined ? [] : _params$classes2, + _params$attributes2 = params.attributes, + attributes = _params$attributes2 === undefined ? {} : _params$attributes2, + _params$styles2 = params.styles, + styles = _params$styles2 === undefined ? {} : _params$styles2; + + + return apiObject({ type: 'text', content: content }, function () { + ensureCss(); + + return makeLayersTextAbstract({ + content: content, + transform: _extends({}, meaninglessTransform, transform), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: [config.familyPrefix + '-layers-text'].concat(toConsumableArray(classes)) + } + }); + }); + }, + + layer: function layer(assembler) { + return apiObject({ type: 'layer' }, function () { + ensureCss(); + + var children = []; + + assembler(function (args) { + Array.isArray(args) ? children = args.map(function (a) { + children = children.concat(a.abstract); + }) : children = children.concat(args.abstract); + }); + + return [{ + tag: 'span', + attributes: { class: config.familyPrefix + '-layers' }, + children: children + }]; + }); + } +}; + +Object.defineProperty(api, 'config', { + get: function get() { + var autoReplaceSvg = config.autoReplaceSvg, + observeMutations = config.observeMutations, + showMissingIcons = config.showMissingIcons, + rest = objectWithoutProperties(config, ['autoReplaceSvg', 'observeMutations', 'showMissingIcons']); + + return rest; + }, + + set: function set(newConfig) { + update(newConfig); + } +}); + +function bootstrap() { + var autoReplace = function autoReplace() { + if (config.autoReplaceSvg) api.dom.i2svg({ node: DOCUMENT }); + }; + + if (IS_BROWSER) { + if (!WINDOW.FontAwesome) { + WINDOW.FontAwesome = api; + } + + domready(function () { + if (Object.keys(namespace.styles).length > 0) { + autoReplace(); + } + + if (config.observeMutations && typeof MutationObserver === 'function') { + observe({ + treeCallback: onTree, + nodeCallback: onNode, + pseudoElementsCallback: searchPseudoElements + }); + } + }); + } + + namespace.hooks = _extends({}, namespace.hooks, { + + addPack: function addPack(prefix, icons) { + namespace.styles[prefix] = _extends({}, namespace.styles[prefix] || {}, icons); + + build(); + autoReplace(); + }, + + addShims: function addShims(shims) { + var _namespace$shims; + + (_namespace$shims = namespace.shims).push.apply(_namespace$shims, toConsumableArray(shims)); + + build(); + autoReplace(); + } + }); +} + +bunker(bootstrap); + +}()); diff --git a/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.min.js b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.min.js new file mode 100644 index 000000000..c2b144c20 --- /dev/null +++ b/backend/webif/static/js/fontawesome/svg-with-js/js/fontawesome.min.js @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +!function(){"use strict";function t(t){var e=Object.keys(ht);Object.keys(t).forEach(function(n){~e.indexOf(n)&&(ht[n]=t[n])})}function e(t){return~st.indexOf(t)}function n(t){if(t&&void 0!==K.createElement){var e=K.createElement("style");e.setAttribute("type","text/css"),e.innerHTML=t;for(var n=K.head.childNodes,r=null,i=n.length-1;i>-1;i--){var a=n[i],o=(a.tagName||"").toUpperCase();["STYLE","LINK"].indexOf(o)>-1&&(r=a)}return K.head.insertBefore(e,r),t}}function r(){return++bt}function i(t){for(var e=[],n=(t||[]).length>>>0;n--;)e[n]=t[n];return e}function a(t){return t.classList?i(t.classList):(t.getAttribute("class")||"").split(" ").filter(function(t){return t})}function o(t,n){var r=n.split("-"),i=r[0],a=r.slice(1).join("-");return i!==t||""===a||e(a)?null:a}function s(t){return(""+t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function f(t){return Object.keys(t||{}).reduce(function(e,n){return e+(n+'="')+s(t[n])+'" '},"").trim()}function l(t){return Object.keys(t||{}).reduce(function(e,n){return e+(n+": ")+t[n]+";"},"")}function c(t){return t.size!==vt.size||t.x!==vt.x||t.y!==vt.y||t.rotate!==vt.rotate||t.flipX||t.flipY}function u(t){var e=t.transform,n=t.containerWidth,r=t.iconWidth;return{outer:{transform:"translate("+n/2+" 256)"},inner:{transform:"translate("+32*e.x+", "+32*e.y+") "+" "+("scale("+e.size/16*(e.flipX?-1:1)+", "+e.size/16*(e.flipY?-1:1)+") ")+" "+("rotate("+e.rotate+" 0 0)")},path:{transform:"translate("+r/2*-1+" -256)"}}}function m(t){var e=t.transform,n=t.width,r=void 0===n?$:n,i=t.height,a=void 0===i?$:i,o=t.startCentered,s=void 0!==o&&o,f="";return f+=s&&Z?"translate("+(e.x/pt-r/2)+"em, "+(e.y/pt-a/2)+"em) ":s?"translate(calc(-50% + "+e.x/pt+"em), calc(-50% + "+e.y/pt+"em)) ":"translate("+e.x/pt+"em, "+e.y/pt+"em) ",f+="scale("+e.size/pt*(e.flipX?-1:1)+", "+e.size/pt*(e.flipY?-1:1)+") ",f+="rotate("+e.rotate+"deg) "}function d(t){var e,n=t.icons,i=n.main,a=n.mask,o=t.prefix,s=t.iconName,f=t.transform,l=t.symbol,c=t.title,u=t.extra,m=a.found?a:i,d=m.width,g=m.height,h="fa-w-"+Math.ceil(d/g*16),p=[ht.replacementClass,s?ht.familyPrefix+"-"+s:"",h].concat(u.classes).join(" "),v={children:[],attributes:ut({},u.attributes,(e={},ct(e,tt,""),ct(e,"data-prefix",o),ct(e,"data-icon",s),ct(e,"class",p),ct(e,"role","img"),ct(e,"xmlns","http://www.w3.org/2000/svg"),ct(e,"viewBox","0 0 "+d+" "+g),e))};c&&v.children.push({tag:"title",attributes:{id:v.attributes["aria-labelledby"]||"title-"+r()},children:[c]});var b=ut({},v,{prefix:o,iconName:s,main:i,mask:a,transform:f,symbol:l,styles:u.styles}),y=a.found&&i.found?wt(b):xt(b),w=y.children,x=y.attributes;return b.children=w,b.attributes=x,l?_t(b):kt(b)}function g(t){var e,n=t.content,r=t.width,i=t.height,a=t.transform,o=t.title,s=t.extra,f=ut({},s.attributes,o?{title:o}:{},(e={},ct(e,tt,""),ct(e,"class",s.classes.join(" ")),e)),u=ut({},s.styles);c(a)&&(u.transform=m({transform:a,startCentered:!0,width:r,height:i}),u["-webkit-transform"]=u.transform);var d=l(u);d.length>0&&(f.style=d);var g=[];return g.push({tag:"span",attributes:f,children:[n]}),o&&g.push({tag:"span",attributes:{class:"sr-only"},children:[o]}),g}function h(t,e){return Tt[t][e]}function p(t,e){return Pt[t][e]}function v(t){return Ft[t]||{prefix:null,iconName:null}}function b(t){return t.reduce(function(t,e){var n=o(ht.familyPrefix,e);if(Rt[e])t.prefix=e;else if(n){var r="fa"===t.prefix?v(n):{};t.iconName=r.iconName||n,t.prefix=r.prefix||t.prefix}else e!==ht.replacementClass&&0!==e.indexOf("fa-w-")&&t.rest.push(e);return t},Ht())}function y(t,e,n){if(t&&t[e]&&t[e][n])return{prefix:e,iconName:n,icon:t[e][n]}}function w(t){var e=t.tag,n=t.attributes,r=void 0===n?{}:n,i=t.children,a=void 0===i?[]:i;return"string"==typeof t?s(t):"<"+e+" "+f(r)+">"+a.map(w).join("")+""}function x(t){var e=t.getAttribute?t.getAttribute("class"):null;return!!e&&(!!~e.toString().indexOf(ht.replacementClass)||~e.toString().indexOf("fa-layers-text"))}function k(){return!0===ht.autoReplaceSvg?Bt.replace:Bt[ht.autoReplaceSvg]||Bt.replace}function _(t,e){var n="function"==typeof e?e:It;0===t.length?n():(q.requestAnimationFrame||function(t){return t()})(function(){var e=k(),r=Ct.begin("mutate");t.map(e),r(),n()})}function O(t){Xt=!0,t(),Xt=!1}function A(t){if(G){var e=t.treeCallback,n=t.nodeCallback,r=t.pseudoElementsCallback,o=new G(function(t){Xt||i(t).forEach(function(t){if("childList"===t.type&&t.addedNodes.length>0&&!x(t.addedNodes[0])&&(ht.searchPseudoElements&&r(t.target),e(t.target)),"attributes"===t.type&&"class"===t.attributeName&&t.target.parentNode&&ht.searchPseudoElements&&r(t.target.parentNode),"attributes"===t.type&&x(t.target)&&~ot.indexOf(t.attributeName))if("class"===t.attributeName){var i=b(a(t.target)),o=i.prefix,s=i.iconName;o&&t.target.setAttribute("data-prefix",o),s&&t.target.setAttribute("data-icon",s)}else n(t.target)})});K.getElementsByTagName&&o.observe(K.getElementsByTagName("body")[0],{childList:!0,attributes:!0,characterData:!0,subtree:!0})}}function N(t){for(var e="",n=0;n1&&void 0!==arguments[1]?arguments[1]:null,n=K.documentElement.classList,r=function(t){return n.add(nt+"-"+t)},a=function(t){return n.remove(nt+"-"+t)},o=Object.keys(ee),s=["."+ne+":not(["+tt+"])"].concat(o.map(function(t){return"."+t+":not(["+tt+"])"})).join(", ");if(0!==s.length){var f=i(t.querySelectorAll(s));if(f.length>0){r("pending"),a("complete");var l=Ct.begin("onTree"),c=f.reduce(function(t,e){try{var n=L(e);n&&t.push(n)}catch(t){rt||t instanceof E&&console.error(t)}return t},[]);l(),_(c,function(){r("active"),r("complete"),a("pending"),"function"==typeof e&&e()})}}}function P(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=L(t);n&&_([n],e)}function F(t){return{found:!0,width:t[0],height:t[1],icon:{tag:"path",attributes:{fill:"currentColor",d:t.slice(4)[0]}}}}function W(){ht.autoAddCss&&(le||n(fe()),le=!0)}function R(t,e){return Object.defineProperty(t,"abstract",{get:e}),Object.defineProperty(t,"html",{get:function(){return t.abstract.map(function(t){return w(t)})}}),Object.defineProperty(t,"node",{get:function(){if(K.createElement){var e=K.createElement("div");return e.innerHTML=t.html,e.children}}}),t}function H(t){var e=t.prefix,n=void 0===e?"fa":e,r=t.iconName;if(r)return y(ce.definitions,n,r)||y(At.styles,n,r)}var I=function(){},B={},X={},Y=null,D={mark:I,measure:I};try{"undefined"!=typeof window&&(B=window),"undefined"!=typeof document&&(X=document),"undefined"!=typeof MutationObserver&&(Y=MutationObserver),"undefined"!=typeof performance&&(D=performance)}catch(t){}var U=(B.navigator||{}).userAgent,V=void 0===U?"":U,q=B,K=X,G=Y,J=D,Q=!!q.document,Z=~V.indexOf("MSIE")||~V.indexOf("Trident/"),$=16,tt="data-fa-processed",et="data-fa-pseudo-element",nt="fontawesome-i2svg",rt=function(){try{return!0}catch(t){return!1}}(),it=[1,2,3,4,5,6,7,8,9,10],at=it.concat([11,12,13,14,15,16,17,18,19,20]),ot=["class","data-prefix","data-icon","data-fa-transform","data-fa-mask"],st=["xs","sm","lg","fw","ul","li","border","pull-left","pull-right","spin","pulse","rotate-90","rotate-180","rotate-270","flip-horizontal","flip-vertical","stack","stack-1x","stack-2x","inverse","layers","layers-text","layers-counter"].concat(it.map(function(t){return t+"x"})).concat(at.map(function(t){return"w-"+t})),ft=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},lt=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},dt=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e0&&(n.style=a),c(i)){var o=u({transform:i,containerWidth:r.width,iconWidth:r.width});e.push({tag:"g",attributes:ut({},o.outer),children:[{tag:"g",attributes:ut({},o.inner),children:[{tag:r.icon.tag,children:r.icon.children,attributes:ut({},r.icon.attributes,o.path)}]}]})}else e.push(r.icon);return{children:e,attributes:n}},kt=function(t){var e=t.children,n=t.main,r=t.mask,i=t.attributes,a=t.styles,o=t.transform;if(c(o)&&n.found&&!r.found){var s={x:n.width/n.height/2,y:.5};i.style=l(ut({},a,{"transform-origin":s.x+o.x/16+"em "+(s.y+o.y/16)+"em"}))}return[{tag:"svg",attributes:i,children:e}]},_t=function(t){var e=t.prefix,n=t.iconName,r=t.children,i=t.attributes,a=t.symbol,o=!0===a?e+"-"+ht.familyPrefix+"-"+n:a;return[{tag:"svg",attributes:{style:"display: none;"},children:[{tag:"symbol",attributes:ut({},i,{id:o}),children:r}]}]},Ot=q||{};Ot.___FONT_AWESOME___||(Ot.___FONT_AWESOME___={}),Ot.___FONT_AWESOME___.styles||(Ot.___FONT_AWESOME___.styles={}),Ot.___FONT_AWESOME___.hooks||(Ot.___FONT_AWESOME___.hooks={}),Ot.___FONT_AWESOME___.shims||(Ot.___FONT_AWESOME___.shims=[]);var At=Ot.___FONT_AWESOME___,Nt=function(){},Mt=ht.measurePerformance&&J&&J.mark&&J.measure?J:{mark:Nt,measure:Nt},Et=function(t){Mt.mark('FA "5.0.1" '+t+" ends"),Mt.measure('FA "5.0.1" '+t,'FA "5.0.1" '+t+" begins",'FA "5.0.1" '+t+" ends")},Ct={begin:function(t){return Mt.mark('FA "5.0.1" '+t+" begins"),function(){return Et(t)}},end:Et},zt=function(t,e){return function(n,r,i,a){return t.call(e,n,r,i,a)}},St=function(t,e,n,r){var i,a,o,s=Object.keys(t),f=s.length,l=void 0!==r?zt(e,r):e;for(void 0===n?(i=1,o=t[s[0]]):(i=0,o=n);i0&&(t[r]=i.join(":").trim()),t},{})),n},Dt=function(t){var e=t.getAttribute("data-prefix"),n=t.getAttribute("data-icon"),r=void 0!==t.innerText?t.innerText.trim():"",i=b(a(t));return e&&n&&(i.prefix=e,i.iconName=n),i.prefix&&r.length>1?i.iconName=p(i.prefix,t.innerText):i.prefix&&1===r.length&&(i.iconName=h(i.prefix,N(t.innerText))),i},Ut=function(t){var e={size:16,x:0,y:0,flipX:!1,flipY:!1,rotate:0};return t?t.toLowerCase().split(" ").reduce(function(t,e){var n=e.toLowerCase().split("-"),r=n[0],i=n.slice(1).join("-");if(r&&"h"===i)return t.flipX=!0,t;if(r&&"v"===i)return t.flipY=!0,t;if(i=parseFloat(i),isNaN(i))return t;switch(r){case"grow":t.size=t.size+i;break;case"shrink":t.size=t.size-i;break;case"left":t.x=t.x-i;break;case"right":t.x=t.x+i;break;case"up":t.y=t.y-i;break;case"down":t.y=t.y+i;break;case"rotate":t.rotate=t.rotate+i}return t},e):e},Vt=function(t){return Ut(t.getAttribute("data-fa-transform"))},qt=function(t){var e=t.getAttribute("data-fa-symbol");return null!==e&&(""===e||e)},Kt=function(t){var e=i(t.attributes).reduce(function(t,e){return"class"!==t.name&&"style"!==t.name&&(t[e.name]=e.value),t},{}),n=t.getAttribute("title");return ht.autoA11y&&(n?e["aria-labelledby"]=ht.replacementClass+"-title-"+r():e["aria-hidden"]="true"),e},Gt=function(t){var e=t.getAttribute("data-fa-mask");return e?b(e.split(" ").map(function(t){return t.trim()})):Ht()};E.prototype=Object.create(Error.prototype),E.prototype.constructor=E;var Jt={fill:"currentColor"},Qt={attributeType:"XML",repeatCount:"indefinite",dur:"2s"},Zt={tag:"path",attributes:ut({},Jt,{d:"M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z"})},$t=ut({},Qt,{attributeName:"opacity"}),te={tag:"g",children:[Zt,{tag:"circle",attributes:ut({},Jt,{cx:"256",cy:"364",r:"28"}),children:[{tag:"animate",attributes:ut({},Qt,{attributeName:"r",values:"28;14;28;28;14;28;"})},{tag:"animate",attributes:ut({},$t,{values:"1;0;1;1;0;1;"})}]},{tag:"path",attributes:ut({},Jt,{opacity:"1",d:"M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z"}),children:[{tag:"animate",attributes:ut({},$t,{values:"1;0;0;0;0;1;"})}]},{tag:"path",attributes:ut({},Jt,{opacity:"0",d:"M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z"}),children:[{tag:"animate",attributes:ut({},$t,{values:"0;0;1;1;0;0;"})}]}]},ee=At.styles,ne="fa-layers-text",re=/Font Awesome 5 (Solid|Regular|Light|Brands)/,ie={Solid:"fas",Regular:"far",Light:"fal",Brands:"fab"},ae=[],oe=(K.documentElement.doScroll?/^loaded|^c/:/^loaded|^i|^c/).test(K.readyState);oe||K.addEventListener("DOMContentLoaded",function t(){K.removeEventListener("DOMContentLoaded",t),oe=1,ae.map(function(t){return t()})});var se=function(t){K&&(oe?setTimeout(t,0):ae.push(t))},fe=function(){var t="svg-inline--fa",e=ht.familyPrefix,n=ht.replacementClass,r="svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-12.5%;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1em}.svg-inline--fa.fa-stack-2x{height:2em;width:2em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}";if("fa"!==e||n!==t){var i=new RegExp("\\.fa\\-","g"),a=new RegExp("\\."+t,"g");r=r.replace(i,"."+e+"-").replace(a,"."+n)}return r},le=!1,ce=new(function(){function t(){ft(this,t),this.definitions={}}return lt(t,[{key:"add",value:function(){for(var t=this,e=arguments.length,n=Array(e),r=0;r0&&void 0!==arguments[0]?arguments[0]:{};W();var e=t.node,n=void 0===e?K:e,r=t.callback,i=void 0===r?function(){}:r;ht.searchPseudoElements&&j(n),T(n,i)},css:fe,insertCss:function(){n(fe())}},library:ce,parse:{transform:function(t){return Ut(t)}},findIconDefinition:H,icon:function(t){return function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(e||{}).icon?e:H(e||{}),i=n.mask;return i&&(i=(i||{}).icon?i:H(i||{})),t(r,ut({},n,{mask:i}))}}(function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.transform,i=void 0===n?vt:n,a=e.symbol,o=void 0!==a&&a,s=e.mask,f=void 0===s?null:s,l=e.title,c=void 0===l?null:l,u=e.classes,m=void 0===u?[]:u,g=e.attributes,h=void 0===g?{}:g,p=e.styles,v=void 0===p?{}:p;if(t){var b=t.prefix,y=t.iconName,w=t.icon;return R(ut({type:"icon"},t),function(){return W(),ht.autoA11y&&(c?h["aria-labelledby"]=ht.replacementClass+"-title-"+r():h["aria-hidden"]="true"),d({icons:{main:F(w),mask:f?F(f.icon):{found:!1,width:null,height:null,icon:{}}},prefix:b,iconName:y,transform:ut({},vt,i),symbol:o,title:c,extra:{attributes:h,styles:v,classes:m}})})}}),text:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.transform,r=void 0===n?vt:n,i=e.title,a=void 0===i?null:i,o=e.classes,s=void 0===o?[]:o,f=e.attributes,l=void 0===f?{}:f,c=e.styles,u=void 0===c?{}:c;return R({type:"text",content:t},function(){return W(),g({content:t,transform:ut({},vt,r),title:a,extra:{attributes:l,styles:u,classes:[ht.familyPrefix+"-layers-text"].concat(dt(s))}})})},layer:function(t){return R({type:"layer"},function(){W();var e=[];return t(function(t){e=Array.isArray(t)?t.map(function(t){e=e.concat(t.abstract)}):e.concat(t.abstract)}),[{tag:"span",attributes:{class:ht.familyPrefix+"-layers"},children:e}]})}};Object.defineProperty(ue,"config",{get:function(){ht.autoReplaceSvg,ht.observeMutations,ht.showMissingIcons;return mt(ht,["autoReplaceSvg","observeMutations","showMissingIcons"])},set:function(e){t(e)}}),function(t){try{t()}catch(t){}}(function(){var t=function(){ht.autoReplaceSvg&&ue.dom.i2svg({node:K})};Q&&(q.FontAwesome||(q.FontAwesome=ue),se(function(){Object.keys(At.styles).length>0&&t(),ht.observeMutations&&"function"==typeof MutationObserver&&A({treeCallback:T,nodeCallback:P,pseudoElementsCallback:j})})),At.hooks=ut({},At.hooks,{addPack:function(e,n){At.styles[e]=ut({},At.styles[e]||{},n),Wt(),t()},addShims:function(e){var n;(n=At.shims).push.apply(n,dt(e)),Wt(),t()}})})}(); \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Brands-Regular-400.otf b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Brands-Regular-400.otf new file mode 100644 index 000000000..4983479cd Binary files /dev/null and b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Brands-Regular-400.otf differ diff --git a/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Regular-400.otf b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Regular-400.otf new file mode 100644 index 000000000..cb00ca61c Binary files /dev/null and b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Regular-400.otf differ diff --git a/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Solid-900.otf b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Solid-900.otf new file mode 100644 index 000000000..909689b61 Binary files /dev/null and b/backend/webif/static/js/fontawesome/use-on-desktop/Font Awesome 5 Free-Solid-900.otf differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.css new file mode 100644 index 000000000..b1f9b0bb2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.css @@ -0,0 +1,13 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url("../webfonts/fa-brands-400.eot"); + src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } + +.fab { + font-family: 'Font Awesome 5 Brands'; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.min.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.min.css new file mode 100644 index 000000000..55bfbd325 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-brands.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face{font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:Font Awesome\ 5 Brands} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.css new file mode 100644 index 000000000..c2a6e330a --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.css @@ -0,0 +1,14 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url("../webfonts/fa-regular-400.eot"); + src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.min.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.min.css new file mode 100644 index 000000000..4968db57b --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-regular.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:Font Awesome\ 5 Free;font-weight:400} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.css new file mode 100644 index 000000000..e83f6a495 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.css @@ -0,0 +1,15 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url("../webfonts/fa-solid-900.eot"); + src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.min.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.min.css new file mode 100644 index 000000000..9fe831411 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fa-solid.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:Font Awesome\ 5 Free;font-weight:900} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.css new file mode 100644 index 000000000..37c3b9593 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.css @@ -0,0 +1,2588 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa, +.fas, +.far, +.fal, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-address-book:before { + content: "\f2b9"; } + +.fa-address-card:before { + content: "\f2bb"; } + +.fa-adjust:before { + content: "\f042"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-align-center:before { + content: "\f037"; } + +.fa-align-justify:before { + content: "\f039"; } + +.fa-align-left:before { + content: "\f036"; } + +.fa-align-right:before { + content: "\f038"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-ambulance:before { + content: "\f0f9"; } + +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-anchor:before { + content: "\f13d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angle-double-down:before { + content: "\f103"; } + +.fa-angle-double-left:before { + content: "\f100"; } + +.fa-angle-double-right:before { + content: "\f101"; } + +.fa-angle-double-up:before { + content: "\f102"; } + +.fa-angle-down:before { + content: "\f107"; } + +.fa-angle-left:before { + content: "\f104"; } + +.fa-angle-right:before { + content: "\f105"; } + +.fa-angle-up:before { + content: "\f106"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-archive:before { + content: "\f187"; } + +.fa-arrow-alt-circle-down:before { + content: "\f358"; } + +.fa-arrow-alt-circle-left:before { + content: "\f359"; } + +.fa-arrow-alt-circle-right:before { + content: "\f35a"; } + +.fa-arrow-alt-circle-up:before { + content: "\f35b"; } + +.fa-arrow-circle-down:before { + content: "\f0ab"; } + +.fa-arrow-circle-left:before { + content: "\f0a8"; } + +.fa-arrow-circle-right:before { + content: "\f0a9"; } + +.fa-arrow-circle-up:before { + content: "\f0aa"; } + +.fa-arrow-down:before { + content: "\f063"; } + +.fa-arrow-left:before { + content: "\f060"; } + +.fa-arrow-right:before { + content: "\f061"; } + +.fa-arrow-up:before { + content: "\f062"; } + +.fa-arrows-alt:before { + content: "\f0b2"; } + +.fa-arrows-alt-h:before { + content: "\f337"; } + +.fa-arrows-alt-v:before { + content: "\f338"; } + +.fa-assistive-listening-systems:before { + content: "\f2a2"; } + +.fa-asterisk:before { + content: "\f069"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-at:before { + content: "\f1fa"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-audio-description:before { + content: "\f29e"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-backward:before { + content: "\f04a"; } + +.fa-balance-scale:before { + content: "\f24e"; } + +.fa-ban:before { + content: "\f05e"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-barcode:before { + content: "\f02a"; } + +.fa-bars:before { + content: "\f0c9"; } + +.fa-bath:before { + content: "\f2cd"; } + +.fa-battery-empty:before { + content: "\f244"; } + +.fa-battery-full:before { + content: "\f240"; } + +.fa-battery-half:before { + content: "\f242"; } + +.fa-battery-quarter:before { + content: "\f243"; } + +.fa-battery-three-quarters:before { + content: "\f241"; } + +.fa-bed:before { + content: "\f236"; } + +.fa-beer:before { + content: "\f0fc"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bell:before { + content: "\f0f3"; } + +.fa-bell-slash:before { + content: "\f1f6"; } + +.fa-bicycle:before { + content: "\f206"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-binoculars:before { + content: "\f1e5"; } + +.fa-birthday-cake:before { + content: "\f1fd"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blind:before { + content: "\f29d"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bold:before { + content: "\f032"; } + +.fa-bolt:before { + content: "\f0e7"; } + +.fa-bomb:before { + content: "\f1e2"; } + +.fa-book:before { + content: "\f02d"; } + +.fa-bookmark:before { + content: "\f02e"; } + +.fa-braille:before { + content: "\f2a1"; } + +.fa-briefcase:before { + content: "\f0b1"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-bug:before { + content: "\f188"; } + +.fa-building:before { + content: "\f1ad"; } + +.fa-bullhorn:before { + content: "\f0a1"; } + +.fa-bullseye:before { + content: "\f140"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-bus:before { + content: "\f207"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-calculator:before { + content: "\f1ec"; } + +.fa-calendar:before { + content: "\f133"; } + +.fa-calendar-alt:before { + content: "\f073"; } + +.fa-calendar-check:before { + content: "\f274"; } + +.fa-calendar-minus:before { + content: "\f272"; } + +.fa-calendar-plus:before { + content: "\f271"; } + +.fa-calendar-times:before { + content: "\f273"; } + +.fa-camera:before { + content: "\f030"; } + +.fa-camera-retro:before { + content: "\f083"; } + +.fa-car:before { + content: "\f1b9"; } + +.fa-caret-down:before { + content: "\f0d7"; } + +.fa-caret-left:before { + content: "\f0d9"; } + +.fa-caret-right:before { + content: "\f0da"; } + +.fa-caret-square-down:before { + content: "\f150"; } + +.fa-caret-square-left:before { + content: "\f191"; } + +.fa-caret-square-right:before { + content: "\f152"; } + +.fa-caret-square-up:before { + content: "\f151"; } + +.fa-caret-up:before { + content: "\f0d8"; } + +.fa-cart-arrow-down:before { + content: "\f218"; } + +.fa-cart-plus:before { + content: "\f217"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-certificate:before { + content: "\f0a3"; } + +.fa-chart-area:before { + content: "\f1fe"; } + +.fa-chart-bar:before { + content: "\f080"; } + +.fa-chart-line:before { + content: "\f201"; } + +.fa-chart-pie:before { + content: "\f200"; } + +.fa-check:before { + content: "\f00c"; } + +.fa-check-circle:before { + content: "\f058"; } + +.fa-check-square:before { + content: "\f14a"; } + +.fa-chevron-circle-down:before { + content: "\f13a"; } + +.fa-chevron-circle-left:before { + content: "\f137"; } + +.fa-chevron-circle-right:before { + content: "\f138"; } + +.fa-chevron-circle-up:before { + content: "\f139"; } + +.fa-chevron-down:before { + content: "\f078"; } + +.fa-chevron-left:before { + content: "\f053"; } + +.fa-chevron-right:before { + content: "\f054"; } + +.fa-chevron-up:before { + content: "\f077"; } + +.fa-child:before { + content: "\f1ae"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-circle:before { + content: "\f111"; } + +.fa-circle-notch:before { + content: "\f1ce"; } + +.fa-clipboard:before { + content: "\f328"; } + +.fa-clock:before { + content: "\f017"; } + +.fa-clone:before { + content: "\f24d"; } + +.fa-closed-captioning:before { + content: "\f20a"; } + +.fa-cloud:before { + content: "\f0c2"; } + +.fa-cloud-download-alt:before { + content: "\f381"; } + +.fa-cloud-upload-alt:before { + content: "\f382"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-code:before { + content: "\f121"; } + +.fa-code-branch:before { + content: "\f126"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-coffee:before { + content: "\f0f4"; } + +.fa-cog:before { + content: "\f013"; } + +.fa-cogs:before { + content: "\f085"; } + +.fa-columns:before { + content: "\f0db"; } + +.fa-comment:before { + content: "\f075"; } + +.fa-comment-alt:before { + content: "\f27a"; } + +.fa-comments:before { + content: "\f086"; } + +.fa-compass:before { + content: "\f14e"; } + +.fa-compress:before { + content: "\f066"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-copy:before { + content: "\f0c5"; } + +.fa-copyright:before { + content: "\f1f9"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-credit-card:before { + content: "\f09d"; } + +.fa-crop:before { + content: "\f125"; } + +.fa-crosshairs:before { + content: "\f05b"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cube:before { + content: "\f1b2"; } + +.fa-cubes:before { + content: "\f1b3"; } + +.fa-cut:before { + content: "\f0c4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-database:before { + content: "\f1c0"; } + +.fa-deaf:before { + content: "\f2a4"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-desktop:before { + content: "\f108"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-dollar-sign:before { + content: "\f155"; } + +.fa-dot-circle:before { + content: "\f192"; } + +.fa-download:before { + content: "\f019"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edit:before { + content: "\f044"; } + +.fa-eject:before { + content: "\f052"; } + +.fa-ellipsis-h:before { + content: "\f141"; } + +.fa-ellipsis-v:before { + content: "\f142"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envelope:before { + content: "\f0e0"; } + +.fa-envelope-open:before { + content: "\f2b6"; } + +.fa-envelope-square:before { + content: "\f199"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-eraser:before { + content: "\f12d"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-euro-sign:before { + content: "\f153"; } + +.fa-exchange-alt:before { + content: "\f362"; } + +.fa-exclamation:before { + content: "\f12a"; } + +.fa-exclamation-circle:before { + content: "\f06a"; } + +.fa-exclamation-triangle:before { + content: "\f071"; } + +.fa-expand:before { + content: "\f065"; } + +.fa-expand-arrows-alt:before { + content: "\f31e"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-external-link-alt:before { + content: "\f35d"; } + +.fa-external-link-square-alt:before { + content: "\f360"; } + +.fa-eye:before { + content: "\f06e"; } + +.fa-eye-dropper:before { + content: "\f1fb"; } + +.fa-eye-slash:before { + content: "\f070"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fast-backward:before { + content: "\f049"; } + +.fa-fast-forward:before { + content: "\f050"; } + +.fa-fax:before { + content: "\f1ac"; } + +.fa-female:before { + content: "\f182"; } + +.fa-fighter-jet:before { + content: "\f0fb"; } + +.fa-file:before { + content: "\f15b"; } + +.fa-file-alt:before { + content: "\f15c"; } + +.fa-file-archive:before { + content: "\f1c6"; } + +.fa-file-audio:before { + content: "\f1c7"; } + +.fa-file-code:before { + content: "\f1c9"; } + +.fa-file-excel:before { + content: "\f1c3"; } + +.fa-file-image:before { + content: "\f1c5"; } + +.fa-file-pdf:before { + content: "\f1c1"; } + +.fa-file-powerpoint:before { + content: "\f1c4"; } + +.fa-file-video:before { + content: "\f1c8"; } + +.fa-file-word:before { + content: "\f1c2"; } + +.fa-film:before { + content: "\f008"; } + +.fa-filter:before { + content: "\f0b0"; } + +.fa-fire:before { + content: "\f06d"; } + +.fa-fire-extinguisher:before { + content: "\f134"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-flag:before { + content: "\f024"; } + +.fa-flag-checkered:before { + content: "\f11e"; } + +.fa-flask:before { + content: "\f0c3"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-folder:before { + content: "\f07b"; } + +.fa-folder-open:before { + content: "\f07c"; } + +.fa-font:before { + content: "\f031"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-font-awesome-flag:before { + content: "\f425"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-forward:before { + content: "\f04e"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-frown:before { + content: "\f119"; } + +.fa-futbol:before { + content: "\f1e3"; } + +.fa-gamepad:before { + content: "\f11b"; } + +.fa-gavel:before { + content: "\f0e3"; } + +.fa-gem:before { + content: "\f3a5"; } + +.fa-genderless:before { + content: "\f22d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-gift:before { + content: "\f06b"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glass-martini:before { + content: "\f000"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-globe:before { + content: "\f0ac"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-graduation-cap:before { + content: "\f19d"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-h-square:before { + content: "\f0fd"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hand-lizard:before { + content: "\f258"; } + +.fa-hand-paper:before { + content: "\f256"; } + +.fa-hand-peace:before { + content: "\f25b"; } + +.fa-hand-point-down:before { + content: "\f0a7"; } + +.fa-hand-point-left:before { + content: "\f0a5"; } + +.fa-hand-point-right:before { + content: "\f0a4"; } + +.fa-hand-point-up:before { + content: "\f0a6"; } + +.fa-hand-pointer:before { + content: "\f25a"; } + +.fa-hand-rock:before { + content: "\f255"; } + +.fa-hand-scissors:before { + content: "\f257"; } + +.fa-hand-spock:before { + content: "\f259"; } + +.fa-handshake:before { + content: "\f2b5"; } + +.fa-hashtag:before { + content: "\f292"; } + +.fa-hdd:before { + content: "\f0a0"; } + +.fa-heading:before { + content: "\f1dc"; } + +.fa-headphones:before { + content: "\f025"; } + +.fa-heart:before { + content: "\f004"; } + +.fa-heartbeat:before { + content: "\f21e"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-history:before { + content: "\f1da"; } + +.fa-home:before { + content: "\f015"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hospital:before { + content: "\f0f8"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-hourglass:before { + content: "\f254"; } + +.fa-hourglass-end:before { + content: "\f253"; } + +.fa-hourglass-half:before { + content: "\f252"; } + +.fa-hourglass-start:before { + content: "\f251"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-i-cursor:before { + content: "\f246"; } + +.fa-id-badge:before { + content: "\f2c1"; } + +.fa-id-card:before { + content: "\f2c2"; } + +.fa-image:before { + content: "\f03e"; } + +.fa-images:before { + content: "\f302"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-inbox:before { + content: "\f01c"; } + +.fa-indent:before { + content: "\f03c"; } + +.fa-industry:before { + content: "\f275"; } + +.fa-info:before { + content: "\f129"; } + +.fa-info-circle:before { + content: "\f05a"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-italic:before { + content: "\f033"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-key:before { + content: "\f084"; } + +.fa-keyboard:before { + content: "\f11c"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-language:before { + content: "\f1ab"; } + +.fa-laptop:before { + content: "\f109"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-leaf:before { + content: "\f06c"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-lemon:before { + content: "\f094"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-level-down-alt:before { + content: "\f3be"; } + +.fa-level-up-alt:before { + content: "\f3bf"; } + +.fa-life-ring:before { + content: "\f1cd"; } + +.fa-lightbulb:before { + content: "\f0eb"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-link:before { + content: "\f0c1"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lira-sign:before { + content: "\f195"; } + +.fa-list:before { + content: "\f03a"; } + +.fa-list-alt:before { + content: "\f022"; } + +.fa-list-ol:before { + content: "\f0cb"; } + +.fa-list-ul:before { + content: "\f0ca"; } + +.fa-location-arrow:before { + content: "\f124"; } + +.fa-lock:before { + content: "\f023"; } + +.fa-lock-open:before { + content: "\f3c1"; } + +.fa-long-arrow-alt-down:before { + content: "\f309"; } + +.fa-long-arrow-alt-left:before { + content: "\f30a"; } + +.fa-long-arrow-alt-right:before { + content: "\f30b"; } + +.fa-long-arrow-alt-up:before { + content: "\f30c"; } + +.fa-low-vision:before { + content: "\f2a8"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-magic:before { + content: "\f0d0"; } + +.fa-magnet:before { + content: "\f076"; } + +.fa-male:before { + content: "\f183"; } + +.fa-map:before { + content: "\f279"; } + +.fa-map-marker:before { + content: "\f041"; } + +.fa-map-marker-alt:before { + content: "\f3c5"; } + +.fa-map-pin:before { + content: "\f276"; } + +.fa-map-signs:before { + content: "\f277"; } + +.fa-mars:before { + content: "\f222"; } + +.fa-mars-double:before { + content: "\f227"; } + +.fa-mars-stroke:before { + content: "\f229"; } + +.fa-mars-stroke-h:before { + content: "\f22b"; } + +.fa-mars-stroke-v:before { + content: "\f22a"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f3c7"; } + +.fa-medkit:before { + content: "\f0fa"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-meh:before { + content: "\f11a"; } + +.fa-mercury:before { + content: "\f223"; } + +.fa-microchip:before { + content: "\f2db"; } + +.fa-microphone:before { + content: "\f130"; } + +.fa-microphone-slash:before { + content: "\f131"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-minus:before { + content: "\f068"; } + +.fa-minus-circle:before { + content: "\f056"; } + +.fa-minus-square:before { + content: "\f146"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-mobile:before { + content: "\f10b"; } + +.fa-mobile-alt:before { + content: "\f3cd"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-money-bill-alt:before { + content: "\f3d1"; } + +.fa-moon:before { + content: "\f186"; } + +.fa-motorcycle:before { + content: "\f21c"; } + +.fa-mouse-pointer:before { + content: "\f245"; } + +.fa-music:before { + content: "\f001"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neuter:before { + content: "\f22c"; } + +.fa-newspaper:before { + content: "\f1ea"; } + +.fa-nintendo-switch:before { + content: "\f418"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-object-group:before { + content: "\f247"; } + +.fa-object-ungroup:before { + content: "\f248"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-outdent:before { + content: "\f03b"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-paint-brush:before { + content: "\f1fc"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-paper-plane:before { + content: "\f1d8"; } + +.fa-paperclip:before { + content: "\f0c6"; } + +.fa-paragraph:before { + content: "\f1dd"; } + +.fa-paste:before { + content: "\f0ea"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-pause:before { + content: "\f04c"; } + +.fa-pause-circle:before { + content: "\f28b"; } + +.fa-paw:before { + content: "\f1b0"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-pen-square:before { + content: "\f14b"; } + +.fa-pencil-alt:before { + content: "\f303"; } + +.fa-percent:before { + content: "\f295"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phone:before { + content: "\f095"; } + +.fa-phone-square:before { + content: "\f098"; } + +.fa-phone-volume:before { + content: "\f2a0"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-plane:before { + content: "\f072"; } + +.fa-play:before { + content: "\f04b"; } + +.fa-play-circle:before { + content: "\f144"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-plug:before { + content: "\f1e6"; } + +.fa-plus:before { + content: "\f067"; } + +.fa-plus-circle:before { + content: "\f055"; } + +.fa-plus-square:before { + content: "\f0fe"; } + +.fa-podcast:before { + content: "\f2ce"; } + +.fa-pound-sign:before { + content: "\f154"; } + +.fa-power-off:before { + content: "\f011"; } + +.fa-print:before { + content: "\f02f"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-puzzle-piece:before { + content: "\f12e"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-qrcode:before { + content: "\f029"; } + +.fa-question:before { + content: "\f128"; } + +.fa-question-circle:before { + content: "\f059"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-quote-left:before { + content: "\f10d"; } + +.fa-quote-right:before { + content: "\f10e"; } + +.fa-random:before { + content: "\f074"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-recycle:before { + content: "\f1b8"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redo:before { + content: "\f01e"; } + +.fa-redo-alt:before { + content: "\f2f9"; } + +.fa-registered:before { + content: "\f25d"; } + +.fa-rendact:before { + content: "\f3e4"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-reply:before { + content: "\f3e5"; } + +.fa-reply-all:before { + content: "\f122"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-retweet:before { + content: "\f079"; } + +.fa-road:before { + content: "\f018"; } + +.fa-rocket:before { + content: "\f135"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-rss:before { + content: "\f09e"; } + +.fa-rss-square:before { + content: "\f143"; } + +.fa-ruble-sign:before { + content: "\f158"; } + +.fa-rupee-sign:before { + content: "\f156"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-save:before { + content: "\f0c7"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-search:before { + content: "\f002"; } + +.fa-search-minus:before { + content: "\f010"; } + +.fa-search-plus:before { + content: "\f00e"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-server:before { + content: "\f233"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-share:before { + content: "\f064"; } + +.fa-share-alt:before { + content: "\f1e0"; } + +.fa-share-alt-square:before { + content: "\f1e1"; } + +.fa-share-square:before { + content: "\f14d"; } + +.fa-shekel-sign:before { + content: "\f20b"; } + +.fa-shield-alt:before { + content: "\f3ed"; } + +.fa-ship:before { + content: "\f21a"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shopping-bag:before { + content: "\f290"; } + +.fa-shopping-basket:before { + content: "\f291"; } + +.fa-shopping-cart:before { + content: "\f07a"; } + +.fa-shower:before { + content: "\f2cc"; } + +.fa-sign-in-alt:before { + content: "\f2f6"; } + +.fa-sign-language:before { + content: "\f2a7"; } + +.fa-sign-out-alt:before { + content: "\f2f5"; } + +.fa-signal:before { + content: "\f012"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sitemap:before { + content: "\f0e8"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f3ef"; } + +.fa-sliders-h:before { + content: "\f1de"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-smile:before { + content: "\f118"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ac"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-snowflake:before { + content: "\f2dc"; } + +.fa-sort:before { + content: "\f0dc"; } + +.fa-sort-alpha-down:before { + content: "\f15d"; } + +.fa-sort-alpha-up:before { + content: "\f15e"; } + +.fa-sort-amount-down:before { + content: "\f160"; } + +.fa-sort-amount-up:before { + content: "\f161"; } + +.fa-sort-down:before { + content: "\f0dd"; } + +.fa-sort-numeric-down:before { + content: "\f162"; } + +.fa-sort-numeric-up:before { + content: "\f163"; } + +.fa-sort-up:before { + content: "\f0de"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-space-shuttle:before { + content: "\f197"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-spinner:before { + content: "\f110"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-square:before { + content: "\f0c8"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-star:before { + content: "\f005"; } + +.fa-star-half:before { + content: "\f089"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-step-backward:before { + content: "\f048"; } + +.fa-step-forward:before { + content: "\f051"; } + +.fa-stethoscope:before { + content: "\f0f1"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-sticky-note:before { + content: "\f249"; } + +.fa-stop:before { + content: "\f04d"; } + +.fa-stop-circle:before { + content: "\f28d"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-street-view:before { + content: "\f21d"; } + +.fa-strikethrough:before { + content: "\f0cc"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-subscript:before { + content: "\f12c"; } + +.fa-subway:before { + content: "\f239"; } + +.fa-suitcase:before { + content: "\f0f2"; } + +.fa-sun:before { + content: "\f185"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-superscript:before { + content: "\f12b"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-sync:before { + content: "\f021"; } + +.fa-sync-alt:before { + content: "\f2f1"; } + +.fa-table:before { + content: "\f0ce"; } + +.fa-tablet:before { + content: "\f10a"; } + +.fa-tablet-alt:before { + content: "\f3fa"; } + +.fa-tachometer-alt:before { + content: "\f3fd"; } + +.fa-tag:before { + content: "\f02b"; } + +.fa-tags:before { + content: "\f02c"; } + +.fa-tasks:before { + content: "\f0ae"; } + +.fa-taxi:before { + content: "\f1ba"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f3fe"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-terminal:before { + content: "\f120"; } + +.fa-text-height:before { + content: "\f034"; } + +.fa-text-width:before { + content: "\f035"; } + +.fa-th:before { + content: "\f00a"; } + +.fa-th-large:before { + content: "\f009"; } + +.fa-th-list:before { + content: "\f00b"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-thermometer-empty:before { + content: "\f2cb"; } + +.fa-thermometer-full:before { + content: "\f2c7"; } + +.fa-thermometer-half:before { + content: "\f2c9"; } + +.fa-thermometer-quarter:before { + content: "\f2ca"; } + +.fa-thermometer-three-quarters:before { + content: "\f2c8"; } + +.fa-thumbs-down:before { + content: "\f165"; } + +.fa-thumbs-up:before { + content: "\f164"; } + +.fa-thumbtack:before { + content: "\f08d"; } + +.fa-ticket-alt:before { + content: "\f3ff"; } + +.fa-times:before { + content: "\f00d"; } + +.fa-times-circle:before { + content: "\f057"; } + +.fa-tint:before { + content: "\f043"; } + +.fa-toggle-off:before { + content: "\f204"; } + +.fa-toggle-on:before { + content: "\f205"; } + +.fa-trademark:before { + content: "\f25c"; } + +.fa-train:before { + content: "\f238"; } + +.fa-transgender:before { + content: "\f224"; } + +.fa-transgender-alt:before { + content: "\f225"; } + +.fa-trash:before { + content: "\f1f8"; } + +.fa-trash-alt:before { + content: "\f2ed"; } + +.fa-tree:before { + content: "\f1bb"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-tripadvisor:before { + content: "\f262"; } + +.fa-trophy:before { + content: "\f091"; } + +.fa-truck:before { + content: "\f0d1"; } + +.fa-tty:before { + content: "\f1e4"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-tv:before { + content: "\f26c"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbrella:before { + content: "\f0e9"; } + +.fa-underline:before { + content: "\f0cd"; } + +.fa-undo:before { + content: "\f0e2"; } + +.fa-undo-alt:before { + content: "\f2ea"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-universal-access:before { + content: "\f29a"; } + +.fa-university:before { + content: "\f19c"; } + +.fa-unlink:before { + content: "\f127"; } + +.fa-unlock:before { + content: "\f09c"; } + +.fa-unlock-alt:before { + content: "\f13e"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-upload:before { + content: "\f093"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-user:before { + content: "\f007"; } + +.fa-user-circle:before { + content: "\f2bd"; } + +.fa-user-md:before { + content: "\f0f0"; } + +.fa-user-plus:before { + content: "\f234"; } + +.fa-user-secret:before { + content: "\f21b"; } + +.fa-user-times:before { + content: "\f235"; } + +.fa-users:before { + content: "\f0c0"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-utensil-spoon:before { + content: "\f2e5"; } + +.fa-utensils:before { + content: "\f2e7"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-venus:before { + content: "\f221"; } + +.fa-venus-double:before { + content: "\f226"; } + +.fa-venus-mars:before { + content: "\f228"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-video:before { + content: "\f03d"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-volume-down:before { + content: "\f027"; } + +.fa-volume-off:before { + content: "\f026"; } + +.fa-volume-up:before { + content: "\f028"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-wheelchair:before { + content: "\f193"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wifi:before { + content: "\f1eb"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-window-close:before { + content: "\f410"; } + +.fa-window-maximize:before { + content: "\f2d0"; } + +.fa-window-minimize:before { + content: "\f2d1"; } + +.fa-window-restore:before { + content: "\f2d2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-won-sign:before { + content: "\f159"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wrench:before { + content: "\f0ad"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yen-sign:before { + content: "\f157"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url("../webfonts/fa-brands-400.eot"); + src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } + +.fab { + font-family: 'Font Awesome 5 Brands'; } +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url("../webfonts/fa-regular-400.eot"); + src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; } +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url("../webfonts/fa-solid-900.eot"); + src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.min.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.min.css new file mode 100644 index 000000000..fac6746c6 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome-all.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:a 2s infinite linear;animation:a 2s infinite linear}.fa-pulse{-webkit-animation:a 1s infinite steps(8);animation:a 1s infinite steps(8)}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-amazon:before{content:"\f270"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-backward:before{content:"\f04a"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blind:before{content:"\f29d"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-braille:before{content:"\f2a1"}.fa-briefcase:before{content:"\f0b1"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-car:before{content:"\f1b9"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-certificate:before{content:"\f0a3"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-square:before{content:"\f14a"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-clipboard:before{content:"\f328"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comments:before{content:"\f086"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crosshairs:before{content:"\f05b"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-deviantart:before{content:"\f1bd"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dollar-sign:before{content:"\f155"}.fa-dot-circle:before{content:"\f192"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-eject:before{content:"\f052"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-excel:before{content:"\f1c3"}.fa-file-image:before{content:"\f1c5"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fire:before{content:"\f06d"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-order:before{content:"\f2b0"}.fa-firstdraft:before{content:"\f3a1"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frown:before{content:"\f119"}.fa-futbol:before{content:"\f1e3"}.fa-gamepad:before{content:"\f11b"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-gift:before{content:"\f06b"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-martini:before{content:"\f000"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-gofore:before{content:"\f3a7"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-handshake:before{content:"\f2b5"}.fa-hashtag:before{content:"\f292"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-heart:before{content:"\f004"}.fa-heartbeat:before{content:"\f21e"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hospital:before{content:"\f0f8"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-internet-explorer:before{content:"\f26b"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-jenkins:before{content:"\f3b6"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-key:before{content:"\f084"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-male:before{content:"\f183"}.fa-map:before{content:"\f279"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-maxcdn:before{content:"\f136"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-meh:before{content:"\f11a"}.fa-mercury:before{content:"\f223"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-moon:before{content:"\f186"}.fa-motorcycle:before{content:"\f21c"}.fa-mouse-pointer:before{content:"\f245"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-paint-brush:before{content:"\f1fc"}.fa-palfed:before{content:"\f3d8"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-paragraph:before{content:"\f1dd"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-percent:before{content:"\f295"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phone:before{content:"\f095"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-plane:before{content:"\f072"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-print:before{content:"\f02f"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-random:before{content:"\f074"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-rebel:before{content:"\f1d0"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-rendact:before{content:"\f3e4"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-resolving:before{content:"\f3e7"}.fa-retweet:before{content:"\f079"}.fa-road:before{content:"\f018"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-rupee-sign:before{content:"\f156"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-scribd:before{content:"\f28a"}.fa-search:before{content:"\f002"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shower:before{content:"\f2cc"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowflake:before{content:"\f2dc"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spinner:before{content:"\f110"}.fa-spotify:before{content:"\f1bc"}.fa-square:before{content:"\f0c8"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-star:before{content:"\f005"}.fa-star-half:before{content:"\f089"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-strava:before{content:"\f428"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-table:before{content:"\f0ce"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-trademark:before{content:"\f25c"}.fa-train:before{content:"\f238"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-circle:before{content:"\f2bd"}.fa-user-md:before{content:"\f0f0"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volume-down:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vuejs:before{content:"\f41f"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wrench:before{content:"\f0ad"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:Font Awesome\ 5 Brands}@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:Font Awesome\ 5 Free}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.css new file mode 100644 index 000000000..016722a06 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.css @@ -0,0 +1,2558 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa, +.fas, +.far, +.fal, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-address-book:before { + content: "\f2b9"; } + +.fa-address-card:before { + content: "\f2bb"; } + +.fa-adjust:before { + content: "\f042"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-align-center:before { + content: "\f037"; } + +.fa-align-justify:before { + content: "\f039"; } + +.fa-align-left:before { + content: "\f036"; } + +.fa-align-right:before { + content: "\f038"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-ambulance:before { + content: "\f0f9"; } + +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-anchor:before { + content: "\f13d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angle-double-down:before { + content: "\f103"; } + +.fa-angle-double-left:before { + content: "\f100"; } + +.fa-angle-double-right:before { + content: "\f101"; } + +.fa-angle-double-up:before { + content: "\f102"; } + +.fa-angle-down:before { + content: "\f107"; } + +.fa-angle-left:before { + content: "\f104"; } + +.fa-angle-right:before { + content: "\f105"; } + +.fa-angle-up:before { + content: "\f106"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-archive:before { + content: "\f187"; } + +.fa-arrow-alt-circle-down:before { + content: "\f358"; } + +.fa-arrow-alt-circle-left:before { + content: "\f359"; } + +.fa-arrow-alt-circle-right:before { + content: "\f35a"; } + +.fa-arrow-alt-circle-up:before { + content: "\f35b"; } + +.fa-arrow-circle-down:before { + content: "\f0ab"; } + +.fa-arrow-circle-left:before { + content: "\f0a8"; } + +.fa-arrow-circle-right:before { + content: "\f0a9"; } + +.fa-arrow-circle-up:before { + content: "\f0aa"; } + +.fa-arrow-down:before { + content: "\f063"; } + +.fa-arrow-left:before { + content: "\f060"; } + +.fa-arrow-right:before { + content: "\f061"; } + +.fa-arrow-up:before { + content: "\f062"; } + +.fa-arrows-alt:before { + content: "\f0b2"; } + +.fa-arrows-alt-h:before { + content: "\f337"; } + +.fa-arrows-alt-v:before { + content: "\f338"; } + +.fa-assistive-listening-systems:before { + content: "\f2a2"; } + +.fa-asterisk:before { + content: "\f069"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-at:before { + content: "\f1fa"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-audio-description:before { + content: "\f29e"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-backward:before { + content: "\f04a"; } + +.fa-balance-scale:before { + content: "\f24e"; } + +.fa-ban:before { + content: "\f05e"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-barcode:before { + content: "\f02a"; } + +.fa-bars:before { + content: "\f0c9"; } + +.fa-bath:before { + content: "\f2cd"; } + +.fa-battery-empty:before { + content: "\f244"; } + +.fa-battery-full:before { + content: "\f240"; } + +.fa-battery-half:before { + content: "\f242"; } + +.fa-battery-quarter:before { + content: "\f243"; } + +.fa-battery-three-quarters:before { + content: "\f241"; } + +.fa-bed:before { + content: "\f236"; } + +.fa-beer:before { + content: "\f0fc"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bell:before { + content: "\f0f3"; } + +.fa-bell-slash:before { + content: "\f1f6"; } + +.fa-bicycle:before { + content: "\f206"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-binoculars:before { + content: "\f1e5"; } + +.fa-birthday-cake:before { + content: "\f1fd"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blind:before { + content: "\f29d"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bold:before { + content: "\f032"; } + +.fa-bolt:before { + content: "\f0e7"; } + +.fa-bomb:before { + content: "\f1e2"; } + +.fa-book:before { + content: "\f02d"; } + +.fa-bookmark:before { + content: "\f02e"; } + +.fa-braille:before { + content: "\f2a1"; } + +.fa-briefcase:before { + content: "\f0b1"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-bug:before { + content: "\f188"; } + +.fa-building:before { + content: "\f1ad"; } + +.fa-bullhorn:before { + content: "\f0a1"; } + +.fa-bullseye:before { + content: "\f140"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-bus:before { + content: "\f207"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-calculator:before { + content: "\f1ec"; } + +.fa-calendar:before { + content: "\f133"; } + +.fa-calendar-alt:before { + content: "\f073"; } + +.fa-calendar-check:before { + content: "\f274"; } + +.fa-calendar-minus:before { + content: "\f272"; } + +.fa-calendar-plus:before { + content: "\f271"; } + +.fa-calendar-times:before { + content: "\f273"; } + +.fa-camera:before { + content: "\f030"; } + +.fa-camera-retro:before { + content: "\f083"; } + +.fa-car:before { + content: "\f1b9"; } + +.fa-caret-down:before { + content: "\f0d7"; } + +.fa-caret-left:before { + content: "\f0d9"; } + +.fa-caret-right:before { + content: "\f0da"; } + +.fa-caret-square-down:before { + content: "\f150"; } + +.fa-caret-square-left:before { + content: "\f191"; } + +.fa-caret-square-right:before { + content: "\f152"; } + +.fa-caret-square-up:before { + content: "\f151"; } + +.fa-caret-up:before { + content: "\f0d8"; } + +.fa-cart-arrow-down:before { + content: "\f218"; } + +.fa-cart-plus:before { + content: "\f217"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-certificate:before { + content: "\f0a3"; } + +.fa-chart-area:before { + content: "\f1fe"; } + +.fa-chart-bar:before { + content: "\f080"; } + +.fa-chart-line:before { + content: "\f201"; } + +.fa-chart-pie:before { + content: "\f200"; } + +.fa-check:before { + content: "\f00c"; } + +.fa-check-circle:before { + content: "\f058"; } + +.fa-check-square:before { + content: "\f14a"; } + +.fa-chevron-circle-down:before { + content: "\f13a"; } + +.fa-chevron-circle-left:before { + content: "\f137"; } + +.fa-chevron-circle-right:before { + content: "\f138"; } + +.fa-chevron-circle-up:before { + content: "\f139"; } + +.fa-chevron-down:before { + content: "\f078"; } + +.fa-chevron-left:before { + content: "\f053"; } + +.fa-chevron-right:before { + content: "\f054"; } + +.fa-chevron-up:before { + content: "\f077"; } + +.fa-child:before { + content: "\f1ae"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-circle:before { + content: "\f111"; } + +.fa-circle-notch:before { + content: "\f1ce"; } + +.fa-clipboard:before { + content: "\f328"; } + +.fa-clock:before { + content: "\f017"; } + +.fa-clone:before { + content: "\f24d"; } + +.fa-closed-captioning:before { + content: "\f20a"; } + +.fa-cloud:before { + content: "\f0c2"; } + +.fa-cloud-download-alt:before { + content: "\f381"; } + +.fa-cloud-upload-alt:before { + content: "\f382"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-code:before { + content: "\f121"; } + +.fa-code-branch:before { + content: "\f126"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-coffee:before { + content: "\f0f4"; } + +.fa-cog:before { + content: "\f013"; } + +.fa-cogs:before { + content: "\f085"; } + +.fa-columns:before { + content: "\f0db"; } + +.fa-comment:before { + content: "\f075"; } + +.fa-comment-alt:before { + content: "\f27a"; } + +.fa-comments:before { + content: "\f086"; } + +.fa-compass:before { + content: "\f14e"; } + +.fa-compress:before { + content: "\f066"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-copy:before { + content: "\f0c5"; } + +.fa-copyright:before { + content: "\f1f9"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-credit-card:before { + content: "\f09d"; } + +.fa-crop:before { + content: "\f125"; } + +.fa-crosshairs:before { + content: "\f05b"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cube:before { + content: "\f1b2"; } + +.fa-cubes:before { + content: "\f1b3"; } + +.fa-cut:before { + content: "\f0c4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-database:before { + content: "\f1c0"; } + +.fa-deaf:before { + content: "\f2a4"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-desktop:before { + content: "\f108"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-dollar-sign:before { + content: "\f155"; } + +.fa-dot-circle:before { + content: "\f192"; } + +.fa-download:before { + content: "\f019"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edit:before { + content: "\f044"; } + +.fa-eject:before { + content: "\f052"; } + +.fa-ellipsis-h:before { + content: "\f141"; } + +.fa-ellipsis-v:before { + content: "\f142"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envelope:before { + content: "\f0e0"; } + +.fa-envelope-open:before { + content: "\f2b6"; } + +.fa-envelope-square:before { + content: "\f199"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-eraser:before { + content: "\f12d"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-euro-sign:before { + content: "\f153"; } + +.fa-exchange-alt:before { + content: "\f362"; } + +.fa-exclamation:before { + content: "\f12a"; } + +.fa-exclamation-circle:before { + content: "\f06a"; } + +.fa-exclamation-triangle:before { + content: "\f071"; } + +.fa-expand:before { + content: "\f065"; } + +.fa-expand-arrows-alt:before { + content: "\f31e"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-external-link-alt:before { + content: "\f35d"; } + +.fa-external-link-square-alt:before { + content: "\f360"; } + +.fa-eye:before { + content: "\f06e"; } + +.fa-eye-dropper:before { + content: "\f1fb"; } + +.fa-eye-slash:before { + content: "\f070"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fast-backward:before { + content: "\f049"; } + +.fa-fast-forward:before { + content: "\f050"; } + +.fa-fax:before { + content: "\f1ac"; } + +.fa-female:before { + content: "\f182"; } + +.fa-fighter-jet:before { + content: "\f0fb"; } + +.fa-file:before { + content: "\f15b"; } + +.fa-file-alt:before { + content: "\f15c"; } + +.fa-file-archive:before { + content: "\f1c6"; } + +.fa-file-audio:before { + content: "\f1c7"; } + +.fa-file-code:before { + content: "\f1c9"; } + +.fa-file-excel:before { + content: "\f1c3"; } + +.fa-file-image:before { + content: "\f1c5"; } + +.fa-file-pdf:before { + content: "\f1c1"; } + +.fa-file-powerpoint:before { + content: "\f1c4"; } + +.fa-file-video:before { + content: "\f1c8"; } + +.fa-file-word:before { + content: "\f1c2"; } + +.fa-film:before { + content: "\f008"; } + +.fa-filter:before { + content: "\f0b0"; } + +.fa-fire:before { + content: "\f06d"; } + +.fa-fire-extinguisher:before { + content: "\f134"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-flag:before { + content: "\f024"; } + +.fa-flag-checkered:before { + content: "\f11e"; } + +.fa-flask:before { + content: "\f0c3"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-folder:before { + content: "\f07b"; } + +.fa-folder-open:before { + content: "\f07c"; } + +.fa-font:before { + content: "\f031"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-font-awesome-flag:before { + content: "\f425"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-forward:before { + content: "\f04e"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-frown:before { + content: "\f119"; } + +.fa-futbol:before { + content: "\f1e3"; } + +.fa-gamepad:before { + content: "\f11b"; } + +.fa-gavel:before { + content: "\f0e3"; } + +.fa-gem:before { + content: "\f3a5"; } + +.fa-genderless:before { + content: "\f22d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-gift:before { + content: "\f06b"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glass-martini:before { + content: "\f000"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-globe:before { + content: "\f0ac"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-graduation-cap:before { + content: "\f19d"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-h-square:before { + content: "\f0fd"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hand-lizard:before { + content: "\f258"; } + +.fa-hand-paper:before { + content: "\f256"; } + +.fa-hand-peace:before { + content: "\f25b"; } + +.fa-hand-point-down:before { + content: "\f0a7"; } + +.fa-hand-point-left:before { + content: "\f0a5"; } + +.fa-hand-point-right:before { + content: "\f0a4"; } + +.fa-hand-point-up:before { + content: "\f0a6"; } + +.fa-hand-pointer:before { + content: "\f25a"; } + +.fa-hand-rock:before { + content: "\f255"; } + +.fa-hand-scissors:before { + content: "\f257"; } + +.fa-hand-spock:before { + content: "\f259"; } + +.fa-handshake:before { + content: "\f2b5"; } + +.fa-hashtag:before { + content: "\f292"; } + +.fa-hdd:before { + content: "\f0a0"; } + +.fa-heading:before { + content: "\f1dc"; } + +.fa-headphones:before { + content: "\f025"; } + +.fa-heart:before { + content: "\f004"; } + +.fa-heartbeat:before { + content: "\f21e"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-history:before { + content: "\f1da"; } + +.fa-home:before { + content: "\f015"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hospital:before { + content: "\f0f8"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-hourglass:before { + content: "\f254"; } + +.fa-hourglass-end:before { + content: "\f253"; } + +.fa-hourglass-half:before { + content: "\f252"; } + +.fa-hourglass-start:before { + content: "\f251"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-i-cursor:before { + content: "\f246"; } + +.fa-id-badge:before { + content: "\f2c1"; } + +.fa-id-card:before { + content: "\f2c2"; } + +.fa-image:before { + content: "\f03e"; } + +.fa-images:before { + content: "\f302"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-inbox:before { + content: "\f01c"; } + +.fa-indent:before { + content: "\f03c"; } + +.fa-industry:before { + content: "\f275"; } + +.fa-info:before { + content: "\f129"; } + +.fa-info-circle:before { + content: "\f05a"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-italic:before { + content: "\f033"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-key:before { + content: "\f084"; } + +.fa-keyboard:before { + content: "\f11c"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-language:before { + content: "\f1ab"; } + +.fa-laptop:before { + content: "\f109"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-leaf:before { + content: "\f06c"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-lemon:before { + content: "\f094"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-level-down-alt:before { + content: "\f3be"; } + +.fa-level-up-alt:before { + content: "\f3bf"; } + +.fa-life-ring:before { + content: "\f1cd"; } + +.fa-lightbulb:before { + content: "\f0eb"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-link:before { + content: "\f0c1"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lira-sign:before { + content: "\f195"; } + +.fa-list:before { + content: "\f03a"; } + +.fa-list-alt:before { + content: "\f022"; } + +.fa-list-ol:before { + content: "\f0cb"; } + +.fa-list-ul:before { + content: "\f0ca"; } + +.fa-location-arrow:before { + content: "\f124"; } + +.fa-lock:before { + content: "\f023"; } + +.fa-lock-open:before { + content: "\f3c1"; } + +.fa-long-arrow-alt-down:before { + content: "\f309"; } + +.fa-long-arrow-alt-left:before { + content: "\f30a"; } + +.fa-long-arrow-alt-right:before { + content: "\f30b"; } + +.fa-long-arrow-alt-up:before { + content: "\f30c"; } + +.fa-low-vision:before { + content: "\f2a8"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-magic:before { + content: "\f0d0"; } + +.fa-magnet:before { + content: "\f076"; } + +.fa-male:before { + content: "\f183"; } + +.fa-map:before { + content: "\f279"; } + +.fa-map-marker:before { + content: "\f041"; } + +.fa-map-marker-alt:before { + content: "\f3c5"; } + +.fa-map-pin:before { + content: "\f276"; } + +.fa-map-signs:before { + content: "\f277"; } + +.fa-mars:before { + content: "\f222"; } + +.fa-mars-double:before { + content: "\f227"; } + +.fa-mars-stroke:before { + content: "\f229"; } + +.fa-mars-stroke-h:before { + content: "\f22b"; } + +.fa-mars-stroke-v:before { + content: "\f22a"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f3c7"; } + +.fa-medkit:before { + content: "\f0fa"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-meh:before { + content: "\f11a"; } + +.fa-mercury:before { + content: "\f223"; } + +.fa-microchip:before { + content: "\f2db"; } + +.fa-microphone:before { + content: "\f130"; } + +.fa-microphone-slash:before { + content: "\f131"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-minus:before { + content: "\f068"; } + +.fa-minus-circle:before { + content: "\f056"; } + +.fa-minus-square:before { + content: "\f146"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-mobile:before { + content: "\f10b"; } + +.fa-mobile-alt:before { + content: "\f3cd"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-money-bill-alt:before { + content: "\f3d1"; } + +.fa-moon:before { + content: "\f186"; } + +.fa-motorcycle:before { + content: "\f21c"; } + +.fa-mouse-pointer:before { + content: "\f245"; } + +.fa-music:before { + content: "\f001"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neuter:before { + content: "\f22c"; } + +.fa-newspaper:before { + content: "\f1ea"; } + +.fa-nintendo-switch:before { + content: "\f418"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-object-group:before { + content: "\f247"; } + +.fa-object-ungroup:before { + content: "\f248"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-outdent:before { + content: "\f03b"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-paint-brush:before { + content: "\f1fc"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-paper-plane:before { + content: "\f1d8"; } + +.fa-paperclip:before { + content: "\f0c6"; } + +.fa-paragraph:before { + content: "\f1dd"; } + +.fa-paste:before { + content: "\f0ea"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-pause:before { + content: "\f04c"; } + +.fa-pause-circle:before { + content: "\f28b"; } + +.fa-paw:before { + content: "\f1b0"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-pen-square:before { + content: "\f14b"; } + +.fa-pencil-alt:before { + content: "\f303"; } + +.fa-percent:before { + content: "\f295"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phone:before { + content: "\f095"; } + +.fa-phone-square:before { + content: "\f098"; } + +.fa-phone-volume:before { + content: "\f2a0"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-plane:before { + content: "\f072"; } + +.fa-play:before { + content: "\f04b"; } + +.fa-play-circle:before { + content: "\f144"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-plug:before { + content: "\f1e6"; } + +.fa-plus:before { + content: "\f067"; } + +.fa-plus-circle:before { + content: "\f055"; } + +.fa-plus-square:before { + content: "\f0fe"; } + +.fa-podcast:before { + content: "\f2ce"; } + +.fa-pound-sign:before { + content: "\f154"; } + +.fa-power-off:before { + content: "\f011"; } + +.fa-print:before { + content: "\f02f"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-puzzle-piece:before { + content: "\f12e"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-qrcode:before { + content: "\f029"; } + +.fa-question:before { + content: "\f128"; } + +.fa-question-circle:before { + content: "\f059"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-quote-left:before { + content: "\f10d"; } + +.fa-quote-right:before { + content: "\f10e"; } + +.fa-random:before { + content: "\f074"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-recycle:before { + content: "\f1b8"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redo:before { + content: "\f01e"; } + +.fa-redo-alt:before { + content: "\f2f9"; } + +.fa-registered:before { + content: "\f25d"; } + +.fa-rendact:before { + content: "\f3e4"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-reply:before { + content: "\f3e5"; } + +.fa-reply-all:before { + content: "\f122"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-retweet:before { + content: "\f079"; } + +.fa-road:before { + content: "\f018"; } + +.fa-rocket:before { + content: "\f135"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-rss:before { + content: "\f09e"; } + +.fa-rss-square:before { + content: "\f143"; } + +.fa-ruble-sign:before { + content: "\f158"; } + +.fa-rupee-sign:before { + content: "\f156"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-save:before { + content: "\f0c7"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-search:before { + content: "\f002"; } + +.fa-search-minus:before { + content: "\f010"; } + +.fa-search-plus:before { + content: "\f00e"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-server:before { + content: "\f233"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-share:before { + content: "\f064"; } + +.fa-share-alt:before { + content: "\f1e0"; } + +.fa-share-alt-square:before { + content: "\f1e1"; } + +.fa-share-square:before { + content: "\f14d"; } + +.fa-shekel-sign:before { + content: "\f20b"; } + +.fa-shield-alt:before { + content: "\f3ed"; } + +.fa-ship:before { + content: "\f21a"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shopping-bag:before { + content: "\f290"; } + +.fa-shopping-basket:before { + content: "\f291"; } + +.fa-shopping-cart:before { + content: "\f07a"; } + +.fa-shower:before { + content: "\f2cc"; } + +.fa-sign-in-alt:before { + content: "\f2f6"; } + +.fa-sign-language:before { + content: "\f2a7"; } + +.fa-sign-out-alt:before { + content: "\f2f5"; } + +.fa-signal:before { + content: "\f012"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sitemap:before { + content: "\f0e8"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f3ef"; } + +.fa-sliders-h:before { + content: "\f1de"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-smile:before { + content: "\f118"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ac"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-snowflake:before { + content: "\f2dc"; } + +.fa-sort:before { + content: "\f0dc"; } + +.fa-sort-alpha-down:before { + content: "\f15d"; } + +.fa-sort-alpha-up:before { + content: "\f15e"; } + +.fa-sort-amount-down:before { + content: "\f160"; } + +.fa-sort-amount-up:before { + content: "\f161"; } + +.fa-sort-down:before { + content: "\f0dd"; } + +.fa-sort-numeric-down:before { + content: "\f162"; } + +.fa-sort-numeric-up:before { + content: "\f163"; } + +.fa-sort-up:before { + content: "\f0de"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-space-shuttle:before { + content: "\f197"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-spinner:before { + content: "\f110"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-square:before { + content: "\f0c8"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-star:before { + content: "\f005"; } + +.fa-star-half:before { + content: "\f089"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-step-backward:before { + content: "\f048"; } + +.fa-step-forward:before { + content: "\f051"; } + +.fa-stethoscope:before { + content: "\f0f1"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-sticky-note:before { + content: "\f249"; } + +.fa-stop:before { + content: "\f04d"; } + +.fa-stop-circle:before { + content: "\f28d"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-street-view:before { + content: "\f21d"; } + +.fa-strikethrough:before { + content: "\f0cc"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-subscript:before { + content: "\f12c"; } + +.fa-subway:before { + content: "\f239"; } + +.fa-suitcase:before { + content: "\f0f2"; } + +.fa-sun:before { + content: "\f185"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-superscript:before { + content: "\f12b"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-sync:before { + content: "\f021"; } + +.fa-sync-alt:before { + content: "\f2f1"; } + +.fa-table:before { + content: "\f0ce"; } + +.fa-tablet:before { + content: "\f10a"; } + +.fa-tablet-alt:before { + content: "\f3fa"; } + +.fa-tachometer-alt:before { + content: "\f3fd"; } + +.fa-tag:before { + content: "\f02b"; } + +.fa-tags:before { + content: "\f02c"; } + +.fa-tasks:before { + content: "\f0ae"; } + +.fa-taxi:before { + content: "\f1ba"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f3fe"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-terminal:before { + content: "\f120"; } + +.fa-text-height:before { + content: "\f034"; } + +.fa-text-width:before { + content: "\f035"; } + +.fa-th:before { + content: "\f00a"; } + +.fa-th-large:before { + content: "\f009"; } + +.fa-th-list:before { + content: "\f00b"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-thermometer-empty:before { + content: "\f2cb"; } + +.fa-thermometer-full:before { + content: "\f2c7"; } + +.fa-thermometer-half:before { + content: "\f2c9"; } + +.fa-thermometer-quarter:before { + content: "\f2ca"; } + +.fa-thermometer-three-quarters:before { + content: "\f2c8"; } + +.fa-thumbs-down:before { + content: "\f165"; } + +.fa-thumbs-up:before { + content: "\f164"; } + +.fa-thumbtack:before { + content: "\f08d"; } + +.fa-ticket-alt:before { + content: "\f3ff"; } + +.fa-times:before { + content: "\f00d"; } + +.fa-times-circle:before { + content: "\f057"; } + +.fa-tint:before { + content: "\f043"; } + +.fa-toggle-off:before { + content: "\f204"; } + +.fa-toggle-on:before { + content: "\f205"; } + +.fa-trademark:before { + content: "\f25c"; } + +.fa-train:before { + content: "\f238"; } + +.fa-transgender:before { + content: "\f224"; } + +.fa-transgender-alt:before { + content: "\f225"; } + +.fa-trash:before { + content: "\f1f8"; } + +.fa-trash-alt:before { + content: "\f2ed"; } + +.fa-tree:before { + content: "\f1bb"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-tripadvisor:before { + content: "\f262"; } + +.fa-trophy:before { + content: "\f091"; } + +.fa-truck:before { + content: "\f0d1"; } + +.fa-tty:before { + content: "\f1e4"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-tv:before { + content: "\f26c"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbrella:before { + content: "\f0e9"; } + +.fa-underline:before { + content: "\f0cd"; } + +.fa-undo:before { + content: "\f0e2"; } + +.fa-undo-alt:before { + content: "\f2ea"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-universal-access:before { + content: "\f29a"; } + +.fa-university:before { + content: "\f19c"; } + +.fa-unlink:before { + content: "\f127"; } + +.fa-unlock:before { + content: "\f09c"; } + +.fa-unlock-alt:before { + content: "\f13e"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-upload:before { + content: "\f093"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-user:before { + content: "\f007"; } + +.fa-user-circle:before { + content: "\f2bd"; } + +.fa-user-md:before { + content: "\f0f0"; } + +.fa-user-plus:before { + content: "\f234"; } + +.fa-user-secret:before { + content: "\f21b"; } + +.fa-user-times:before { + content: "\f235"; } + +.fa-users:before { + content: "\f0c0"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-utensil-spoon:before { + content: "\f2e5"; } + +.fa-utensils:before { + content: "\f2e7"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-venus:before { + content: "\f221"; } + +.fa-venus-double:before { + content: "\f226"; } + +.fa-venus-mars:before { + content: "\f228"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-video:before { + content: "\f03d"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-volume-down:before { + content: "\f027"; } + +.fa-volume-off:before { + content: "\f026"; } + +.fa-volume-up:before { + content: "\f028"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-wheelchair:before { + content: "\f193"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wifi:before { + content: "\f1eb"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-window-close:before { + content: "\f410"; } + +.fa-window-maximize:before { + content: "\f2d0"; } + +.fa-window-minimize:before { + content: "\f2d1"; } + +.fa-window-restore:before { + content: "\f2d2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-won-sign:before { + content: "\f159"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wrench:before { + content: "\f0ad"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yen-sign:before { + content: "\f157"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.min.css b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.min.css new file mode 100644 index 000000000..92bd33f50 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/css/fontawesome.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:a 2s infinite linear;animation:a 2s infinite linear}.fa-pulse{-webkit-animation:a 1s infinite steps(8);animation:a 1s infinite steps(8)}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-amazon:before{content:"\f270"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-backward:before{content:"\f04a"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blind:before{content:"\f29d"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-braille:before{content:"\f2a1"}.fa-briefcase:before{content:"\f0b1"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-car:before{content:"\f1b9"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-certificate:before{content:"\f0a3"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-square:before{content:"\f14a"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-clipboard:before{content:"\f328"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comments:before{content:"\f086"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crosshairs:before{content:"\f05b"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-deviantart:before{content:"\f1bd"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dollar-sign:before{content:"\f155"}.fa-dot-circle:before{content:"\f192"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-eject:before{content:"\f052"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-excel:before{content:"\f1c3"}.fa-file-image:before{content:"\f1c5"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fire:before{content:"\f06d"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-order:before{content:"\f2b0"}.fa-firstdraft:before{content:"\f3a1"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frown:before{content:"\f119"}.fa-futbol:before{content:"\f1e3"}.fa-gamepad:before{content:"\f11b"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-gift:before{content:"\f06b"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-martini:before{content:"\f000"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-gofore:before{content:"\f3a7"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-handshake:before{content:"\f2b5"}.fa-hashtag:before{content:"\f292"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-heart:before{content:"\f004"}.fa-heartbeat:before{content:"\f21e"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hospital:before{content:"\f0f8"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-internet-explorer:before{content:"\f26b"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-jenkins:before{content:"\f3b6"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-key:before{content:"\f084"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-male:before{content:"\f183"}.fa-map:before{content:"\f279"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-maxcdn:before{content:"\f136"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-meh:before{content:"\f11a"}.fa-mercury:before{content:"\f223"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-moon:before{content:"\f186"}.fa-motorcycle:before{content:"\f21c"}.fa-mouse-pointer:before{content:"\f245"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-paint-brush:before{content:"\f1fc"}.fa-palfed:before{content:"\f3d8"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-paragraph:before{content:"\f1dd"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-percent:before{content:"\f295"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phone:before{content:"\f095"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-plane:before{content:"\f072"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-print:before{content:"\f02f"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-random:before{content:"\f074"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-rebel:before{content:"\f1d0"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-rendact:before{content:"\f3e4"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-resolving:before{content:"\f3e7"}.fa-retweet:before{content:"\f079"}.fa-road:before{content:"\f018"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-rupee-sign:before{content:"\f156"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-scribd:before{content:"\f28a"}.fa-search:before{content:"\f002"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shower:before{content:"\f2cc"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowflake:before{content:"\f2dc"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spinner:before{content:"\f110"}.fa-spotify:before{content:"\f1bc"}.fa-square:before{content:"\f0c8"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-star:before{content:"\f005"}.fa-star-half:before{content:"\f089"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-strava:before{content:"\f428"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-table:before{content:"\f0ce"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-trademark:before{content:"\f25c"}.fa-train:before{content:"\f238"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-circle:before{content:"\f2bd"}.fa-user-md:before{content:"\f0f0"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volume-down:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vuejs:before{content:"\f41f"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wrench:before{content:"\f0ad"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto} \ No newline at end of file diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_animated.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_animated.less new file mode 100644 index 000000000..704ec9510 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_animated.less @@ -0,0 +1,19 @@ +// Animated Icons +// -------------------------- + +.@{fa-css-prefix}-spin { + animation: fa-spin 2s infinite linear; +} + +.@{fa-css-prefix}-pulse { + animation: fa-spin 1s infinite steps(8); +} + +@keyframes fa-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_bordered-pulled.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_bordered-pulled.less new file mode 100644 index 000000000..29a356b42 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_bordered-pulled.less @@ -0,0 +1,16 @@ +// Bordered & Pulled +// ------------------------- + +.@{fa-css-prefix}-border { + border-radius: .1em; + border: solid .08em @fa-border-color; + padding: .2em .25em .15em; +} + +.@{fa-css-prefix}-pull-left { float: left; } +.@{fa-css-prefix}-pull-right { float: right; } + +.@{fa-css-prefix}, .fas, .far, .fal, .fab { + &.@{fa-css-prefix}-pull-left { margin-right: .3em; } + &.@{fa-css-prefix}-pull-right { margin-left: .3em; } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_core.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_core.less new file mode 100644 index 000000000..82031d652 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_core.less @@ -0,0 +1,12 @@ +// Base Class Definition +// ------------------------- + +.@{fa-css-prefix}, .fas, .far, .fal, .fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_fixed-width.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_fixed-width.less new file mode 100644 index 000000000..be817c637 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_fixed-width.less @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.@{fa-css-prefix}-fw { + text-align: center; + width: (20em / 16); +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_icons.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_icons.less new file mode 100644 index 000000000..20185ec4a --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_icons.less @@ -0,0 +1,787 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ + +.@{fa-css-prefix}-500px:before { content: @fa-var-500px; } +.@{fa-css-prefix}-accessible-icon:before { content: @fa-var-accessible-icon; } +.@{fa-css-prefix}-accusoft:before { content: @fa-var-accusoft; } +.@{fa-css-prefix}-address-book:before { content: @fa-var-address-book; } +.@{fa-css-prefix}-address-card:before { content: @fa-var-address-card; } +.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; } +.@{fa-css-prefix}-adn:before { content: @fa-var-adn; } +.@{fa-css-prefix}-adversal:before { content: @fa-var-adversal; } +.@{fa-css-prefix}-affiliatetheme:before { content: @fa-var-affiliatetheme; } +.@{fa-css-prefix}-algolia:before { content: @fa-var-algolia; } +.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; } +.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; } +.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; } +.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; } +.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; } +.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; } +.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; } +.@{fa-css-prefix}-amilia:before { content: @fa-var-amilia; } +.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; } +.@{fa-css-prefix}-android:before { content: @fa-var-android; } +.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; } +.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; } +.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; } +.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; } +.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; } +.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; } +.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; } +.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; } +.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; } +.@{fa-css-prefix}-angrycreative:before { content: @fa-var-angrycreative; } +.@{fa-css-prefix}-angular:before { content: @fa-var-angular; } +.@{fa-css-prefix}-app-store:before { content: @fa-var-app-store; } +.@{fa-css-prefix}-app-store-ios:before { content: @fa-var-app-store-ios; } +.@{fa-css-prefix}-apper:before { content: @fa-var-apper; } +.@{fa-css-prefix}-apple:before { content: @fa-var-apple; } +.@{fa-css-prefix}-apple-pay:before { content: @fa-var-apple-pay; } +.@{fa-css-prefix}-archive:before { content: @fa-var-archive; } +.@{fa-css-prefix}-arrow-alt-circle-down:before { content: @fa-var-arrow-alt-circle-down; } +.@{fa-css-prefix}-arrow-alt-circle-left:before { content: @fa-var-arrow-alt-circle-left; } +.@{fa-css-prefix}-arrow-alt-circle-right:before { content: @fa-var-arrow-alt-circle-right; } +.@{fa-css-prefix}-arrow-alt-circle-up:before { content: @fa-var-arrow-alt-circle-up; } +.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; } +.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; } +.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; } +.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; } +.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; } +.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; } +.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; } +.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; } +.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; } +.@{fa-css-prefix}-arrows-alt-h:before { content: @fa-var-arrows-alt-h; } +.@{fa-css-prefix}-arrows-alt-v:before { content: @fa-var-arrows-alt-v; } +.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; } +.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; } +.@{fa-css-prefix}-asymmetrik:before { content: @fa-var-asymmetrik; } +.@{fa-css-prefix}-at:before { content: @fa-var-at; } +.@{fa-css-prefix}-audible:before { content: @fa-var-audible; } +.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; } +.@{fa-css-prefix}-autoprefixer:before { content: @fa-var-autoprefixer; } +.@{fa-css-prefix}-avianex:before { content: @fa-var-avianex; } +.@{fa-css-prefix}-aviato:before { content: @fa-var-aviato; } +.@{fa-css-prefix}-aws:before { content: @fa-var-aws; } +.@{fa-css-prefix}-backward:before { content: @fa-var-backward; } +.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; } +.@{fa-css-prefix}-ban:before { content: @fa-var-ban; } +.@{fa-css-prefix}-bandcamp:before { content: @fa-var-bandcamp; } +.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; } +.@{fa-css-prefix}-bars:before { content: @fa-var-bars; } +.@{fa-css-prefix}-bath:before { content: @fa-var-bath; } +.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; } +.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; } +.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; } +.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; } +.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; } +.@{fa-css-prefix}-bed:before { content: @fa-var-bed; } +.@{fa-css-prefix}-beer:before { content: @fa-var-beer; } +.@{fa-css-prefix}-behance:before { content: @fa-var-behance; } +.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; } +.@{fa-css-prefix}-bell:before { content: @fa-var-bell; } +.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; } +.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; } +.@{fa-css-prefix}-bimobject:before { content: @fa-var-bimobject; } +.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; } +.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; } +.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; } +.@{fa-css-prefix}-bitcoin:before { content: @fa-var-bitcoin; } +.@{fa-css-prefix}-bity:before { content: @fa-var-bity; } +.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; } +.@{fa-css-prefix}-blackberry:before { content: @fa-var-blackberry; } +.@{fa-css-prefix}-blind:before { content: @fa-var-blind; } +.@{fa-css-prefix}-blogger:before { content: @fa-var-blogger; } +.@{fa-css-prefix}-blogger-b:before { content: @fa-var-blogger-b; } +.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; } +.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; } +.@{fa-css-prefix}-bold:before { content: @fa-var-bold; } +.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; } +.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; } +.@{fa-css-prefix}-book:before { content: @fa-var-book; } +.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; } +.@{fa-css-prefix}-braille:before { content: @fa-var-braille; } +.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; } +.@{fa-css-prefix}-btc:before { content: @fa-var-btc; } +.@{fa-css-prefix}-bug:before { content: @fa-var-bug; } +.@{fa-css-prefix}-building:before { content: @fa-var-building; } +.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; } +.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; } +.@{fa-css-prefix}-buromobelexperte:before { content: @fa-var-buromobelexperte; } +.@{fa-css-prefix}-bus:before { content: @fa-var-bus; } +.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; } +.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; } +.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; } +.@{fa-css-prefix}-calendar-alt:before { content: @fa-var-calendar-alt; } +.@{fa-css-prefix}-calendar-check:before { content: @fa-var-calendar-check; } +.@{fa-css-prefix}-calendar-minus:before { content: @fa-var-calendar-minus; } +.@{fa-css-prefix}-calendar-plus:before { content: @fa-var-calendar-plus; } +.@{fa-css-prefix}-calendar-times:before { content: @fa-var-calendar-times; } +.@{fa-css-prefix}-camera:before { content: @fa-var-camera; } +.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; } +.@{fa-css-prefix}-car:before { content: @fa-var-car; } +.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; } +.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; } +.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; } +.@{fa-css-prefix}-caret-square-down:before { content: @fa-var-caret-square-down; } +.@{fa-css-prefix}-caret-square-left:before { content: @fa-var-caret-square-left; } +.@{fa-css-prefix}-caret-square-right:before { content: @fa-var-caret-square-right; } +.@{fa-css-prefix}-caret-square-up:before { content: @fa-var-caret-square-up; } +.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; } +.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; } +.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; } +.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; } +.@{fa-css-prefix}-cc-apple-pay:before { content: @fa-var-cc-apple-pay; } +.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; } +.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; } +.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; } +.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; } +.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; } +.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; } +.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; } +.@{fa-css-prefix}-centercode:before { content: @fa-var-centercode; } +.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; } +.@{fa-css-prefix}-chart-area:before { content: @fa-var-chart-area; } +.@{fa-css-prefix}-chart-bar:before { content: @fa-var-chart-bar; } +.@{fa-css-prefix}-chart-line:before { content: @fa-var-chart-line; } +.@{fa-css-prefix}-chart-pie:before { content: @fa-var-chart-pie; } +.@{fa-css-prefix}-check:before { content: @fa-var-check; } +.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; } +.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; } +.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; } +.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; } +.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; } +.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; } +.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; } +.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; } +.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; } +.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; } +.@{fa-css-prefix}-child:before { content: @fa-var-child; } +.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; } +.@{fa-css-prefix}-circle:before { content: @fa-var-circle; } +.@{fa-css-prefix}-circle-notch:before { content: @fa-var-circle-notch; } +.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; } +.@{fa-css-prefix}-clock:before { content: @fa-var-clock; } +.@{fa-css-prefix}-clone:before { content: @fa-var-clone; } +.@{fa-css-prefix}-closed-captioning:before { content: @fa-var-closed-captioning; } +.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; } +.@{fa-css-prefix}-cloud-download-alt:before { content: @fa-var-cloud-download-alt; } +.@{fa-css-prefix}-cloud-upload-alt:before { content: @fa-var-cloud-upload-alt; } +.@{fa-css-prefix}-cloudscale:before { content: @fa-var-cloudscale; } +.@{fa-css-prefix}-cloudsmith:before { content: @fa-var-cloudsmith; } +.@{fa-css-prefix}-cloudversify:before { content: @fa-var-cloudversify; } +.@{fa-css-prefix}-code:before { content: @fa-var-code; } +.@{fa-css-prefix}-code-branch:before { content: @fa-var-code-branch; } +.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; } +.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; } +.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; } +.@{fa-css-prefix}-cog:before { content: @fa-var-cog; } +.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; } +.@{fa-css-prefix}-columns:before { content: @fa-var-columns; } +.@{fa-css-prefix}-comment:before { content: @fa-var-comment; } +.@{fa-css-prefix}-comment-alt:before { content: @fa-var-comment-alt; } +.@{fa-css-prefix}-comments:before { content: @fa-var-comments; } +.@{fa-css-prefix}-compass:before { content: @fa-var-compass; } +.@{fa-css-prefix}-compress:before { content: @fa-var-compress; } +.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; } +.@{fa-css-prefix}-contao:before { content: @fa-var-contao; } +.@{fa-css-prefix}-copy:before { content: @fa-var-copy; } +.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; } +.@{fa-css-prefix}-cpanel:before { content: @fa-var-cpanel; } +.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; } +.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; } +.@{fa-css-prefix}-crop:before { content: @fa-var-crop; } +.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; } +.@{fa-css-prefix}-css3:before { content: @fa-var-css3; } +.@{fa-css-prefix}-css3-alt:before { content: @fa-var-css3-alt; } +.@{fa-css-prefix}-cube:before { content: @fa-var-cube; } +.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; } +.@{fa-css-prefix}-cut:before { content: @fa-var-cut; } +.@{fa-css-prefix}-cuttlefish:before { content: @fa-var-cuttlefish; } +.@{fa-css-prefix}-d-and-d:before { content: @fa-var-d-and-d; } +.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; } +.@{fa-css-prefix}-database:before { content: @fa-var-database; } +.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; } +.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; } +.@{fa-css-prefix}-deploydog:before { content: @fa-var-deploydog; } +.@{fa-css-prefix}-deskpro:before { content: @fa-var-deskpro; } +.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; } +.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; } +.@{fa-css-prefix}-digg:before { content: @fa-var-digg; } +.@{fa-css-prefix}-digital-ocean:before { content: @fa-var-digital-ocean; } +.@{fa-css-prefix}-discord:before { content: @fa-var-discord; } +.@{fa-css-prefix}-discourse:before { content: @fa-var-discourse; } +.@{fa-css-prefix}-dochub:before { content: @fa-var-dochub; } +.@{fa-css-prefix}-docker:before { content: @fa-var-docker; } +.@{fa-css-prefix}-dollar-sign:before { content: @fa-var-dollar-sign; } +.@{fa-css-prefix}-dot-circle:before { content: @fa-var-dot-circle; } +.@{fa-css-prefix}-download:before { content: @fa-var-download; } +.@{fa-css-prefix}-draft2digital:before { content: @fa-var-draft2digital; } +.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; } +.@{fa-css-prefix}-dribbble-square:before { content: @fa-var-dribbble-square; } +.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; } +.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; } +.@{fa-css-prefix}-dyalog:before { content: @fa-var-dyalog; } +.@{fa-css-prefix}-earlybirds:before { content: @fa-var-earlybirds; } +.@{fa-css-prefix}-edge:before { content: @fa-var-edge; } +.@{fa-css-prefix}-edit:before { content: @fa-var-edit; } +.@{fa-css-prefix}-eject:before { content: @fa-var-eject; } +.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; } +.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; } +.@{fa-css-prefix}-ember:before { content: @fa-var-ember; } +.@{fa-css-prefix}-empire:before { content: @fa-var-empire; } +.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; } +.@{fa-css-prefix}-envelope-open:before { content: @fa-var-envelope-open; } +.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; } +.@{fa-css-prefix}-envira:before { content: @fa-var-envira; } +.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; } +.@{fa-css-prefix}-erlang:before { content: @fa-var-erlang; } +.@{fa-css-prefix}-etsy:before { content: @fa-var-etsy; } +.@{fa-css-prefix}-euro-sign:before { content: @fa-var-euro-sign; } +.@{fa-css-prefix}-exchange-alt:before { content: @fa-var-exchange-alt; } +.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; } +.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; } +.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; } +.@{fa-css-prefix}-expand:before { content: @fa-var-expand; } +.@{fa-css-prefix}-expand-arrows-alt:before { content: @fa-var-expand-arrows-alt; } +.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; } +.@{fa-css-prefix}-external-link-alt:before { content: @fa-var-external-link-alt; } +.@{fa-css-prefix}-external-link-square-alt:before { content: @fa-var-external-link-square-alt; } +.@{fa-css-prefix}-eye:before { content: @fa-var-eye; } +.@{fa-css-prefix}-eye-dropper:before { content: @fa-var-eye-dropper; } +.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; } +.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; } +.@{fa-css-prefix}-facebook-f:before { content: @fa-var-facebook-f; } +.@{fa-css-prefix}-facebook-messenger:before { content: @fa-var-facebook-messenger; } +.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; } +.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; } +.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; } +.@{fa-css-prefix}-fax:before { content: @fa-var-fax; } +.@{fa-css-prefix}-female:before { content: @fa-var-female; } +.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; } +.@{fa-css-prefix}-file:before { content: @fa-var-file; } +.@{fa-css-prefix}-file-alt:before { content: @fa-var-file-alt; } +.@{fa-css-prefix}-file-archive:before { content: @fa-var-file-archive; } +.@{fa-css-prefix}-file-audio:before { content: @fa-var-file-audio; } +.@{fa-css-prefix}-file-code:before { content: @fa-var-file-code; } +.@{fa-css-prefix}-file-excel:before { content: @fa-var-file-excel; } +.@{fa-css-prefix}-file-image:before { content: @fa-var-file-image; } +.@{fa-css-prefix}-file-pdf:before { content: @fa-var-file-pdf; } +.@{fa-css-prefix}-file-powerpoint:before { content: @fa-var-file-powerpoint; } +.@{fa-css-prefix}-file-video:before { content: @fa-var-file-video; } +.@{fa-css-prefix}-file-word:before { content: @fa-var-file-word; } +.@{fa-css-prefix}-film:before { content: @fa-var-film; } +.@{fa-css-prefix}-filter:before { content: @fa-var-filter; } +.@{fa-css-prefix}-fire:before { content: @fa-var-fire; } +.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; } +.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; } +.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; } +.@{fa-css-prefix}-firstdraft:before { content: @fa-var-firstdraft; } +.@{fa-css-prefix}-flag:before { content: @fa-var-flag; } +.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; } +.@{fa-css-prefix}-flask:before { content: @fa-var-flask; } +.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; } +.@{fa-css-prefix}-fly:before { content: @fa-var-fly; } +.@{fa-css-prefix}-folder:before { content: @fa-var-folder; } +.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; } +.@{fa-css-prefix}-font:before { content: @fa-var-font; } +.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; } +.@{fa-css-prefix}-font-awesome-alt:before { content: @fa-var-font-awesome-alt; } +.@{fa-css-prefix}-font-awesome-flag:before { content: @fa-var-font-awesome-flag; } +.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; } +.@{fa-css-prefix}-fonticons-fi:before { content: @fa-var-fonticons-fi; } +.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; } +.@{fa-css-prefix}-fort-awesome-alt:before { content: @fa-var-fort-awesome-alt; } +.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; } +.@{fa-css-prefix}-forward:before { content: @fa-var-forward; } +.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; } +.@{fa-css-prefix}-free-code-camp:before { content: @fa-var-free-code-camp; } +.@{fa-css-prefix}-freebsd:before { content: @fa-var-freebsd; } +.@{fa-css-prefix}-frown:before { content: @fa-var-frown; } +.@{fa-css-prefix}-futbol:before { content: @fa-var-futbol; } +.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; } +.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; } +.@{fa-css-prefix}-gem:before { content: @fa-var-gem; } +.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; } +.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; } +.@{fa-css-prefix}-gg:before { content: @fa-var-gg; } +.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; } +.@{fa-css-prefix}-gift:before { content: @fa-var-gift; } +.@{fa-css-prefix}-git:before { content: @fa-var-git; } +.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; } +.@{fa-css-prefix}-github:before { content: @fa-var-github; } +.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; } +.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; } +.@{fa-css-prefix}-gitkraken:before { content: @fa-var-gitkraken; } +.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; } +.@{fa-css-prefix}-gitter:before { content: @fa-var-gitter; } +.@{fa-css-prefix}-glass-martini:before { content: @fa-var-glass-martini; } +.@{fa-css-prefix}-glide:before { content: @fa-var-glide; } +.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; } +.@{fa-css-prefix}-globe:before { content: @fa-var-globe; } +.@{fa-css-prefix}-gofore:before { content: @fa-var-gofore; } +.@{fa-css-prefix}-goodreads:before { content: @fa-var-goodreads; } +.@{fa-css-prefix}-goodreads-g:before { content: @fa-var-goodreads-g; } +.@{fa-css-prefix}-google:before { content: @fa-var-google; } +.@{fa-css-prefix}-google-drive:before { content: @fa-var-google-drive; } +.@{fa-css-prefix}-google-play:before { content: @fa-var-google-play; } +.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; } +.@{fa-css-prefix}-google-plus-g:before { content: @fa-var-google-plus-g; } +.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; } +.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; } +.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; } +.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; } +.@{fa-css-prefix}-grav:before { content: @fa-var-grav; } +.@{fa-css-prefix}-gripfire:before { content: @fa-var-gripfire; } +.@{fa-css-prefix}-grunt:before { content: @fa-var-grunt; } +.@{fa-css-prefix}-gulp:before { content: @fa-var-gulp; } +.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; } +.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; } +.@{fa-css-prefix}-hacker-news-square:before { content: @fa-var-hacker-news-square; } +.@{fa-css-prefix}-hand-lizard:before { content: @fa-var-hand-lizard; } +.@{fa-css-prefix}-hand-paper:before { content: @fa-var-hand-paper; } +.@{fa-css-prefix}-hand-peace:before { content: @fa-var-hand-peace; } +.@{fa-css-prefix}-hand-point-down:before { content: @fa-var-hand-point-down; } +.@{fa-css-prefix}-hand-point-left:before { content: @fa-var-hand-point-left; } +.@{fa-css-prefix}-hand-point-right:before { content: @fa-var-hand-point-right; } +.@{fa-css-prefix}-hand-point-up:before { content: @fa-var-hand-point-up; } +.@{fa-css-prefix}-hand-pointer:before { content: @fa-var-hand-pointer; } +.@{fa-css-prefix}-hand-rock:before { content: @fa-var-hand-rock; } +.@{fa-css-prefix}-hand-scissors:before { content: @fa-var-hand-scissors; } +.@{fa-css-prefix}-hand-spock:before { content: @fa-var-hand-spock; } +.@{fa-css-prefix}-handshake:before { content: @fa-var-handshake; } +.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; } +.@{fa-css-prefix}-hdd:before { content: @fa-var-hdd; } +.@{fa-css-prefix}-heading:before { content: @fa-var-heading; } +.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; } +.@{fa-css-prefix}-heart:before { content: @fa-var-heart; } +.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; } +.@{fa-css-prefix}-hire-a-helper:before { content: @fa-var-hire-a-helper; } +.@{fa-css-prefix}-history:before { content: @fa-var-history; } +.@{fa-css-prefix}-home:before { content: @fa-var-home; } +.@{fa-css-prefix}-hooli:before { content: @fa-var-hooli; } +.@{fa-css-prefix}-hospital:before { content: @fa-var-hospital; } +.@{fa-css-prefix}-hotjar:before { content: @fa-var-hotjar; } +.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; } +.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; } +.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; } +.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; } +.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; } +.@{fa-css-prefix}-html5:before { content: @fa-var-html5; } +.@{fa-css-prefix}-hubspot:before { content: @fa-var-hubspot; } +.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; } +.@{fa-css-prefix}-id-badge:before { content: @fa-var-id-badge; } +.@{fa-css-prefix}-id-card:before { content: @fa-var-id-card; } +.@{fa-css-prefix}-image:before { content: @fa-var-image; } +.@{fa-css-prefix}-images:before { content: @fa-var-images; } +.@{fa-css-prefix}-imdb:before { content: @fa-var-imdb; } +.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; } +.@{fa-css-prefix}-indent:before { content: @fa-var-indent; } +.@{fa-css-prefix}-industry:before { content: @fa-var-industry; } +.@{fa-css-prefix}-info:before { content: @fa-var-info; } +.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; } +.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; } +.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; } +.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; } +.@{fa-css-prefix}-italic:before { content: @fa-var-italic; } +.@{fa-css-prefix}-itunes:before { content: @fa-var-itunes; } +.@{fa-css-prefix}-itunes-note:before { content: @fa-var-itunes-note; } +.@{fa-css-prefix}-jenkins:before { content: @fa-var-jenkins; } +.@{fa-css-prefix}-joget:before { content: @fa-var-joget; } +.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; } +.@{fa-css-prefix}-js:before { content: @fa-var-js; } +.@{fa-css-prefix}-js-square:before { content: @fa-var-js-square; } +.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; } +.@{fa-css-prefix}-key:before { content: @fa-var-key; } +.@{fa-css-prefix}-keyboard:before { content: @fa-var-keyboard; } +.@{fa-css-prefix}-keycdn:before { content: @fa-var-keycdn; } +.@{fa-css-prefix}-kickstarter:before { content: @fa-var-kickstarter; } +.@{fa-css-prefix}-kickstarter-k:before { content: @fa-var-kickstarter-k; } +.@{fa-css-prefix}-language:before { content: @fa-var-language; } +.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; } +.@{fa-css-prefix}-laravel:before { content: @fa-var-laravel; } +.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; } +.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; } +.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; } +.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; } +.@{fa-css-prefix}-lemon:before { content: @fa-var-lemon; } +.@{fa-css-prefix}-less:before { content: @fa-var-less; } +.@{fa-css-prefix}-level-down-alt:before { content: @fa-var-level-down-alt; } +.@{fa-css-prefix}-level-up-alt:before { content: @fa-var-level-up-alt; } +.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; } +.@{fa-css-prefix}-lightbulb:before { content: @fa-var-lightbulb; } +.@{fa-css-prefix}-line:before { content: @fa-var-line; } +.@{fa-css-prefix}-link:before { content: @fa-var-link; } +.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; } +.@{fa-css-prefix}-linkedin-in:before { content: @fa-var-linkedin-in; } +.@{fa-css-prefix}-linode:before { content: @fa-var-linode; } +.@{fa-css-prefix}-linux:before { content: @fa-var-linux; } +.@{fa-css-prefix}-lira-sign:before { content: @fa-var-lira-sign; } +.@{fa-css-prefix}-list:before { content: @fa-var-list; } +.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; } +.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; } +.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; } +.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; } +.@{fa-css-prefix}-lock:before { content: @fa-var-lock; } +.@{fa-css-prefix}-lock-open:before { content: @fa-var-lock-open; } +.@{fa-css-prefix}-long-arrow-alt-down:before { content: @fa-var-long-arrow-alt-down; } +.@{fa-css-prefix}-long-arrow-alt-left:before { content: @fa-var-long-arrow-alt-left; } +.@{fa-css-prefix}-long-arrow-alt-right:before { content: @fa-var-long-arrow-alt-right; } +.@{fa-css-prefix}-long-arrow-alt-up:before { content: @fa-var-long-arrow-alt-up; } +.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; } +.@{fa-css-prefix}-lyft:before { content: @fa-var-lyft; } +.@{fa-css-prefix}-magento:before { content: @fa-var-magento; } +.@{fa-css-prefix}-magic:before { content: @fa-var-magic; } +.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; } +.@{fa-css-prefix}-male:before { content: @fa-var-male; } +.@{fa-css-prefix}-map:before { content: @fa-var-map; } +.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; } +.@{fa-css-prefix}-map-marker-alt:before { content: @fa-var-map-marker-alt; } +.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; } +.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; } +.@{fa-css-prefix}-mars:before { content: @fa-var-mars; } +.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; } +.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; } +.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; } +.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; } +.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; } +.@{fa-css-prefix}-medapps:before { content: @fa-var-medapps; } +.@{fa-css-prefix}-medium:before { content: @fa-var-medium; } +.@{fa-css-prefix}-medium-m:before { content: @fa-var-medium-m; } +.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; } +.@{fa-css-prefix}-medrt:before { content: @fa-var-medrt; } +.@{fa-css-prefix}-meetup:before { content: @fa-var-meetup; } +.@{fa-css-prefix}-meh:before { content: @fa-var-meh; } +.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; } +.@{fa-css-prefix}-microchip:before { content: @fa-var-microchip; } +.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; } +.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; } +.@{fa-css-prefix}-microsoft:before { content: @fa-var-microsoft; } +.@{fa-css-prefix}-minus:before { content: @fa-var-minus; } +.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; } +.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; } +.@{fa-css-prefix}-mix:before { content: @fa-var-mix; } +.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; } +.@{fa-css-prefix}-mizuni:before { content: @fa-var-mizuni; } +.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; } +.@{fa-css-prefix}-mobile-alt:before { content: @fa-var-mobile-alt; } +.@{fa-css-prefix}-modx:before { content: @fa-var-modx; } +.@{fa-css-prefix}-monero:before { content: @fa-var-monero; } +.@{fa-css-prefix}-money-bill-alt:before { content: @fa-var-money-bill-alt; } +.@{fa-css-prefix}-moon:before { content: @fa-var-moon; } +.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; } +.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; } +.@{fa-css-prefix}-music:before { content: @fa-var-music; } +.@{fa-css-prefix}-napster:before { content: @fa-var-napster; } +.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; } +.@{fa-css-prefix}-newspaper:before { content: @fa-var-newspaper; } +.@{fa-css-prefix}-nintendo-switch:before { content: @fa-var-nintendo-switch; } +.@{fa-css-prefix}-node:before { content: @fa-var-node; } +.@{fa-css-prefix}-node-js:before { content: @fa-var-node-js; } +.@{fa-css-prefix}-npm:before { content: @fa-var-npm; } +.@{fa-css-prefix}-ns8:before { content: @fa-var-ns8; } +.@{fa-css-prefix}-nutritionix:before { content: @fa-var-nutritionix; } +.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; } +.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; } +.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; } +.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; } +.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; } +.@{fa-css-prefix}-openid:before { content: @fa-var-openid; } +.@{fa-css-prefix}-opera:before { content: @fa-var-opera; } +.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; } +.@{fa-css-prefix}-osi:before { content: @fa-var-osi; } +.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; } +.@{fa-css-prefix}-page4:before { content: @fa-var-page4; } +.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; } +.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; } +.@{fa-css-prefix}-palfed:before { content: @fa-var-palfed; } +.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; } +.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; } +.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; } +.@{fa-css-prefix}-paste:before { content: @fa-var-paste; } +.@{fa-css-prefix}-patreon:before { content: @fa-var-patreon; } +.@{fa-css-prefix}-pause:before { content: @fa-var-pause; } +.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; } +.@{fa-css-prefix}-paw:before { content: @fa-var-paw; } +.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; } +.@{fa-css-prefix}-pen-square:before { content: @fa-var-pen-square; } +.@{fa-css-prefix}-pencil-alt:before { content: @fa-var-pencil-alt; } +.@{fa-css-prefix}-percent:before { content: @fa-var-percent; } +.@{fa-css-prefix}-periscope:before { content: @fa-var-periscope; } +.@{fa-css-prefix}-phabricator:before { content: @fa-var-phabricator; } +.@{fa-css-prefix}-phoenix-framework:before { content: @fa-var-phoenix-framework; } +.@{fa-css-prefix}-phone:before { content: @fa-var-phone; } +.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; } +.@{fa-css-prefix}-phone-volume:before { content: @fa-var-phone-volume; } +.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; } +.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; } +.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; } +.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; } +.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; } +.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; } +.@{fa-css-prefix}-plane:before { content: @fa-var-plane; } +.@{fa-css-prefix}-play:before { content: @fa-var-play; } +.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; } +.@{fa-css-prefix}-playstation:before { content: @fa-var-playstation; } +.@{fa-css-prefix}-plug:before { content: @fa-var-plug; } +.@{fa-css-prefix}-plus:before { content: @fa-var-plus; } +.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; } +.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; } +.@{fa-css-prefix}-podcast:before { content: @fa-var-podcast; } +.@{fa-css-prefix}-pound-sign:before { content: @fa-var-pound-sign; } +.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; } +.@{fa-css-prefix}-print:before { content: @fa-var-print; } +.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; } +.@{fa-css-prefix}-pushed:before { content: @fa-var-pushed; } +.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; } +.@{fa-css-prefix}-python:before { content: @fa-var-python; } +.@{fa-css-prefix}-qq:before { content: @fa-var-qq; } +.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; } +.@{fa-css-prefix}-question:before { content: @fa-var-question; } +.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; } +.@{fa-css-prefix}-quora:before { content: @fa-var-quora; } +.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; } +.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; } +.@{fa-css-prefix}-random:before { content: @fa-var-random; } +.@{fa-css-prefix}-ravelry:before { content: @fa-var-ravelry; } +.@{fa-css-prefix}-react:before { content: @fa-var-react; } +.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; } +.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; } +.@{fa-css-prefix}-red-river:before { content: @fa-var-red-river; } +.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; } +.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; } +.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; } +.@{fa-css-prefix}-redo:before { content: @fa-var-redo; } +.@{fa-css-prefix}-redo-alt:before { content: @fa-var-redo-alt; } +.@{fa-css-prefix}-registered:before { content: @fa-var-registered; } +.@{fa-css-prefix}-rendact:before { content: @fa-var-rendact; } +.@{fa-css-prefix}-renren:before { content: @fa-var-renren; } +.@{fa-css-prefix}-reply:before { content: @fa-var-reply; } +.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; } +.@{fa-css-prefix}-replyd:before { content: @fa-var-replyd; } +.@{fa-css-prefix}-resolving:before { content: @fa-var-resolving; } +.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; } +.@{fa-css-prefix}-road:before { content: @fa-var-road; } +.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; } +.@{fa-css-prefix}-rocketchat:before { content: @fa-var-rocketchat; } +.@{fa-css-prefix}-rockrms:before { content: @fa-var-rockrms; } +.@{fa-css-prefix}-rss:before { content: @fa-var-rss; } +.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; } +.@{fa-css-prefix}-ruble-sign:before { content: @fa-var-ruble-sign; } +.@{fa-css-prefix}-rupee-sign:before { content: @fa-var-rupee-sign; } +.@{fa-css-prefix}-safari:before { content: @fa-var-safari; } +.@{fa-css-prefix}-sass:before { content: @fa-var-sass; } +.@{fa-css-prefix}-save:before { content: @fa-var-save; } +.@{fa-css-prefix}-schlix:before { content: @fa-var-schlix; } +.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; } +.@{fa-css-prefix}-search:before { content: @fa-var-search; } +.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; } +.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; } +.@{fa-css-prefix}-searchengin:before { content: @fa-var-searchengin; } +.@{fa-css-prefix}-sellcast:before { content: @fa-var-sellcast; } +.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; } +.@{fa-css-prefix}-server:before { content: @fa-var-server; } +.@{fa-css-prefix}-servicestack:before { content: @fa-var-servicestack; } +.@{fa-css-prefix}-share:before { content: @fa-var-share; } +.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; } +.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; } +.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; } +.@{fa-css-prefix}-shekel-sign:before { content: @fa-var-shekel-sign; } +.@{fa-css-prefix}-shield-alt:before { content: @fa-var-shield-alt; } +.@{fa-css-prefix}-ship:before { content: @fa-var-ship; } +.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; } +.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; } +.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; } +.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; } +.@{fa-css-prefix}-shower:before { content: @fa-var-shower; } +.@{fa-css-prefix}-sign-in-alt:before { content: @fa-var-sign-in-alt; } +.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; } +.@{fa-css-prefix}-sign-out-alt:before { content: @fa-var-sign-out-alt; } +.@{fa-css-prefix}-signal:before { content: @fa-var-signal; } +.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; } +.@{fa-css-prefix}-sistrix:before { content: @fa-var-sistrix; } +.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; } +.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; } +.@{fa-css-prefix}-skype:before { content: @fa-var-skype; } +.@{fa-css-prefix}-slack:before { content: @fa-var-slack; } +.@{fa-css-prefix}-slack-hash:before { content: @fa-var-slack-hash; } +.@{fa-css-prefix}-sliders-h:before { content: @fa-var-sliders-h; } +.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; } +.@{fa-css-prefix}-smile:before { content: @fa-var-smile; } +.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; } +.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; } +.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; } +.@{fa-css-prefix}-snowflake:before { content: @fa-var-snowflake; } +.@{fa-css-prefix}-sort:before { content: @fa-var-sort; } +.@{fa-css-prefix}-sort-alpha-down:before { content: @fa-var-sort-alpha-down; } +.@{fa-css-prefix}-sort-alpha-up:before { content: @fa-var-sort-alpha-up; } +.@{fa-css-prefix}-sort-amount-down:before { content: @fa-var-sort-amount-down; } +.@{fa-css-prefix}-sort-amount-up:before { content: @fa-var-sort-amount-up; } +.@{fa-css-prefix}-sort-down:before { content: @fa-var-sort-down; } +.@{fa-css-prefix}-sort-numeric-down:before { content: @fa-var-sort-numeric-down; } +.@{fa-css-prefix}-sort-numeric-up:before { content: @fa-var-sort-numeric-up; } +.@{fa-css-prefix}-sort-up:before { content: @fa-var-sort-up; } +.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; } +.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; } +.@{fa-css-prefix}-speakap:before { content: @fa-var-speakap; } +.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; } +.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; } +.@{fa-css-prefix}-square:before { content: @fa-var-square; } +.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; } +.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; } +.@{fa-css-prefix}-star:before { content: @fa-var-star; } +.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; } +.@{fa-css-prefix}-staylinked:before { content: @fa-var-staylinked; } +.@{fa-css-prefix}-steam:before { content: @fa-var-steam; } +.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; } +.@{fa-css-prefix}-steam-symbol:before { content: @fa-var-steam-symbol; } +.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; } +.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; } +.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; } +.@{fa-css-prefix}-sticker-mule:before { content: @fa-var-sticker-mule; } +.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; } +.@{fa-css-prefix}-stop:before { content: @fa-var-stop; } +.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; } +.@{fa-css-prefix}-strava:before { content: @fa-var-strava; } +.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; } +.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; } +.@{fa-css-prefix}-stripe:before { content: @fa-var-stripe; } +.@{fa-css-prefix}-stripe-s:before { content: @fa-var-stripe-s; } +.@{fa-css-prefix}-studiovinari:before { content: @fa-var-studiovinari; } +.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; } +.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; } +.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; } +.@{fa-css-prefix}-subway:before { content: @fa-var-subway; } +.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; } +.@{fa-css-prefix}-sun:before { content: @fa-var-sun; } +.@{fa-css-prefix}-superpowers:before { content: @fa-var-superpowers; } +.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; } +.@{fa-css-prefix}-supple:before { content: @fa-var-supple; } +.@{fa-css-prefix}-sync:before { content: @fa-var-sync; } +.@{fa-css-prefix}-sync-alt:before { content: @fa-var-sync-alt; } +.@{fa-css-prefix}-table:before { content: @fa-var-table; } +.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; } +.@{fa-css-prefix}-tablet-alt:before { content: @fa-var-tablet-alt; } +.@{fa-css-prefix}-tachometer-alt:before { content: @fa-var-tachometer-alt; } +.@{fa-css-prefix}-tag:before { content: @fa-var-tag; } +.@{fa-css-prefix}-tags:before { content: @fa-var-tags; } +.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; } +.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; } +.@{fa-css-prefix}-telegram:before { content: @fa-var-telegram; } +.@{fa-css-prefix}-telegram-plane:before { content: @fa-var-telegram-plane; } +.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; } +.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; } +.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; } +.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; } +.@{fa-css-prefix}-th:before { content: @fa-var-th; } +.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; } +.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; } +.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; } +.@{fa-css-prefix}-thermometer-empty:before { content: @fa-var-thermometer-empty; } +.@{fa-css-prefix}-thermometer-full:before { content: @fa-var-thermometer-full; } +.@{fa-css-prefix}-thermometer-half:before { content: @fa-var-thermometer-half; } +.@{fa-css-prefix}-thermometer-quarter:before { content: @fa-var-thermometer-quarter; } +.@{fa-css-prefix}-thermometer-three-quarters:before { content: @fa-var-thermometer-three-quarters; } +.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; } +.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; } +.@{fa-css-prefix}-thumbtack:before { content: @fa-var-thumbtack; } +.@{fa-css-prefix}-ticket-alt:before { content: @fa-var-ticket-alt; } +.@{fa-css-prefix}-times:before { content: @fa-var-times; } +.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; } +.@{fa-css-prefix}-tint:before { content: @fa-var-tint; } +.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; } +.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; } +.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; } +.@{fa-css-prefix}-train:before { content: @fa-var-train; } +.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; } +.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; } +.@{fa-css-prefix}-trash:before { content: @fa-var-trash; } +.@{fa-css-prefix}-trash-alt:before { content: @fa-var-trash-alt; } +.@{fa-css-prefix}-tree:before { content: @fa-var-tree; } +.@{fa-css-prefix}-trello:before { content: @fa-var-trello; } +.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; } +.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; } +.@{fa-css-prefix}-truck:before { content: @fa-var-truck; } +.@{fa-css-prefix}-tty:before { content: @fa-var-tty; } +.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; } +.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; } +.@{fa-css-prefix}-tv:before { content: @fa-var-tv; } +.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; } +.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; } +.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; } +.@{fa-css-prefix}-typo3:before { content: @fa-var-typo3; } +.@{fa-css-prefix}-uber:before { content: @fa-var-uber; } +.@{fa-css-prefix}-uikit:before { content: @fa-var-uikit; } +.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; } +.@{fa-css-prefix}-underline:before { content: @fa-var-underline; } +.@{fa-css-prefix}-undo:before { content: @fa-var-undo; } +.@{fa-css-prefix}-undo-alt:before { content: @fa-var-undo-alt; } +.@{fa-css-prefix}-uniregistry:before { content: @fa-var-uniregistry; } +.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; } +.@{fa-css-prefix}-university:before { content: @fa-var-university; } +.@{fa-css-prefix}-unlink:before { content: @fa-var-unlink; } +.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; } +.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; } +.@{fa-css-prefix}-untappd:before { content: @fa-var-untappd; } +.@{fa-css-prefix}-upload:before { content: @fa-var-upload; } +.@{fa-css-prefix}-usb:before { content: @fa-var-usb; } +.@{fa-css-prefix}-user:before { content: @fa-var-user; } +.@{fa-css-prefix}-user-circle:before { content: @fa-var-user-circle; } +.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; } +.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; } +.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; } +.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; } +.@{fa-css-prefix}-users:before { content: @fa-var-users; } +.@{fa-css-prefix}-ussunnah:before { content: @fa-var-ussunnah; } +.@{fa-css-prefix}-utensil-spoon:before { content: @fa-var-utensil-spoon; } +.@{fa-css-prefix}-utensils:before { content: @fa-var-utensils; } +.@{fa-css-prefix}-vaadin:before { content: @fa-var-vaadin; } +.@{fa-css-prefix}-venus:before { content: @fa-var-venus; } +.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; } +.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; } +.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; } +.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; } +.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; } +.@{fa-css-prefix}-viber:before { content: @fa-var-viber; } +.@{fa-css-prefix}-video:before { content: @fa-var-video; } +.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; } +.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; } +.@{fa-css-prefix}-vimeo-v:before { content: @fa-var-vimeo-v; } +.@{fa-css-prefix}-vine:before { content: @fa-var-vine; } +.@{fa-css-prefix}-vk:before { content: @fa-var-vk; } +.@{fa-css-prefix}-vnv:before { content: @fa-var-vnv; } +.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; } +.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; } +.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; } +.@{fa-css-prefix}-vuejs:before { content: @fa-var-vuejs; } +.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; } +.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; } +.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; } +.@{fa-css-prefix}-whatsapp-square:before { content: @fa-var-whatsapp-square; } +.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; } +.@{fa-css-prefix}-whmcs:before { content: @fa-var-whmcs; } +.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; } +.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; } +.@{fa-css-prefix}-window-close:before { content: @fa-var-window-close; } +.@{fa-css-prefix}-window-maximize:before { content: @fa-var-window-maximize; } +.@{fa-css-prefix}-window-minimize:before { content: @fa-var-window-minimize; } +.@{fa-css-prefix}-window-restore:before { content: @fa-var-window-restore; } +.@{fa-css-prefix}-windows:before { content: @fa-var-windows; } +.@{fa-css-prefix}-won-sign:before { content: @fa-var-won-sign; } +.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; } +.@{fa-css-prefix}-wordpress-simple:before { content: @fa-var-wordpress-simple; } +.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; } +.@{fa-css-prefix}-wpexplorer:before { content: @fa-var-wpexplorer; } +.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; } +.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; } +.@{fa-css-prefix}-xbox:before { content: @fa-var-xbox; } +.@{fa-css-prefix}-xing:before { content: @fa-var-xing; } +.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; } +.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; } +.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; } +.@{fa-css-prefix}-yandex:before { content: @fa-var-yandex; } +.@{fa-css-prefix}-yandex-international:before { content: @fa-var-yandex-international; } +.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; } +.@{fa-css-prefix}-yen-sign:before { content: @fa-var-yen-sign; } +.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; } +.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_larger.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_larger.less new file mode 100644 index 000000000..6cbb1ec6e --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_larger.less @@ -0,0 +1,27 @@ +// Icon Sizes +// ------------------------- + +.larger(@factor) when (@factor > 0) { + .larger((@factor - 1)); + + .@{fa-css-prefix}-@{factor}x { + font-size: (@factor * 1em); + } +} + +/* makes the font 33% larger relative to the icon container */ +.@{fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -.0667em; +} + +.@{fa-css-prefix}-xs { + font-size: .75em; +} + +.@{fa-css-prefix}-sm { + font-size: .875em; +} + +.larger(10); diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_list.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_list.less new file mode 100644 index 000000000..1ff7ca7f5 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_list.less @@ -0,0 +1,18 @@ +// List Icons +// ------------------------- + +.@{fa-css-prefix}-ul { + list-style-type: none; + margin-left: @fa-li-width * 5/4; + padding-left: 0; + + > li { position: relative; } +} + +.@{fa-css-prefix}-li { + left: -@fa-li-width; + position: absolute; + text-align: center; + width: @fa-li-width; + line-height: inherit; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_mixins.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_mixins.less new file mode 100644 index 000000000..9404c7cc2 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_mixins.less @@ -0,0 +1,57 @@ +// Mixins +// -------------------------- + +.fa-icon() { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + vertical-align: -15%; +} + +.fa-icon-rotate(@degrees, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; + transform: rotate(@degrees); +} + +.fa-icon-flip(@horiz, @vert, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; + transform: scale(@horiz, @vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +.sr-only() { + border: 0; + clip: rect(0,0,0,0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +.sr-only-focusable() { + &:active, + &:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_rotated-flipped.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_rotated-flipped.less new file mode 100644 index 000000000..1ee31db19 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_rotated-flipped.less @@ -0,0 +1,23 @@ +// Rotated & Flipped Icons +// ------------------------- + +.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } +.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } +.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } + +.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } +.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } +.@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root { + .@{fa-css-prefix}-rotate-90, + .@{fa-css-prefix}-rotate-180, + .@{fa-css-prefix}-rotate-270, + .@{fa-css-prefix}-flip-horizontal, + .@{fa-css-prefix}-flip-vertical { + filter: none; + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_screen-reader.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_screen-reader.less new file mode 100644 index 000000000..11c188196 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_screen-reader.less @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { .sr-only(); } +.sr-only-focusable { .sr-only-focusable(); } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_stacked.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_stacked.less new file mode 100644 index 000000000..263b5c44f --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_stacked.less @@ -0,0 +1,22 @@ +// Stacked Icons +// ------------------------- + +.@{fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; +} + +.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; +} + +.@{fa-css-prefix}-stack-1x { line-height: inherit; } +.@{fa-css-prefix}-stack-2x { font-size: 2em; } +.@{fa-css-prefix}-inverse { color: @fa-inverse; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_variables.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_variables.less new file mode 100644 index 000000000..b3d88af2f --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/_variables.less @@ -0,0 +1,796 @@ +// Variables +// -------------------------- + +@fa-font-path: "../webfonts"; +@fa-font-size-base: 16px; +@fa-line-height-base: 1; +@fa-css-prefix: fa; +@fa-version: "5.0.0"; +@fa-border-color: #eee; +@fa-inverse: #fff; +@fa-li-width: 2em; + +@fa-var-500px: "\f26e"; +@fa-var-accessible-icon: "\f368"; +@fa-var-accusoft: "\f369"; +@fa-var-address-book: "\f2b9"; +@fa-var-address-card: "\f2bb"; +@fa-var-adjust: "\f042"; +@fa-var-adn: "\f170"; +@fa-var-adversal: "\f36a"; +@fa-var-affiliatetheme: "\f36b"; +@fa-var-algolia: "\f36c"; +@fa-var-align-center: "\f037"; +@fa-var-align-justify: "\f039"; +@fa-var-align-left: "\f036"; +@fa-var-align-right: "\f038"; +@fa-var-amazon: "\f270"; +@fa-var-ambulance: "\f0f9"; +@fa-var-american-sign-language-interpreting: "\f2a3"; +@fa-var-amilia: "\f36d"; +@fa-var-anchor: "\f13d"; +@fa-var-android: "\f17b"; +@fa-var-angellist: "\f209"; +@fa-var-angle-double-down: "\f103"; +@fa-var-angle-double-left: "\f100"; +@fa-var-angle-double-right: "\f101"; +@fa-var-angle-double-up: "\f102"; +@fa-var-angle-down: "\f107"; +@fa-var-angle-left: "\f104"; +@fa-var-angle-right: "\f105"; +@fa-var-angle-up: "\f106"; +@fa-var-angrycreative: "\f36e"; +@fa-var-angular: "\f420"; +@fa-var-app-store: "\f36f"; +@fa-var-app-store-ios: "\f370"; +@fa-var-apper: "\f371"; +@fa-var-apple: "\f179"; +@fa-var-apple-pay: "\f415"; +@fa-var-archive: "\f187"; +@fa-var-arrow-alt-circle-down: "\f358"; +@fa-var-arrow-alt-circle-left: "\f359"; +@fa-var-arrow-alt-circle-right: "\f35a"; +@fa-var-arrow-alt-circle-up: "\f35b"; +@fa-var-arrow-circle-down: "\f0ab"; +@fa-var-arrow-circle-left: "\f0a8"; +@fa-var-arrow-circle-right: "\f0a9"; +@fa-var-arrow-circle-up: "\f0aa"; +@fa-var-arrow-down: "\f063"; +@fa-var-arrow-left: "\f060"; +@fa-var-arrow-right: "\f061"; +@fa-var-arrow-up: "\f062"; +@fa-var-arrows-alt: "\f0b2"; +@fa-var-arrows-alt-h: "\f337"; +@fa-var-arrows-alt-v: "\f338"; +@fa-var-assistive-listening-systems: "\f2a2"; +@fa-var-asterisk: "\f069"; +@fa-var-asymmetrik: "\f372"; +@fa-var-at: "\f1fa"; +@fa-var-audible: "\f373"; +@fa-var-audio-description: "\f29e"; +@fa-var-autoprefixer: "\f41c"; +@fa-var-avianex: "\f374"; +@fa-var-aviato: "\f421"; +@fa-var-aws: "\f375"; +@fa-var-backward: "\f04a"; +@fa-var-balance-scale: "\f24e"; +@fa-var-ban: "\f05e"; +@fa-var-bandcamp: "\f2d5"; +@fa-var-barcode: "\f02a"; +@fa-var-bars: "\f0c9"; +@fa-var-bath: "\f2cd"; +@fa-var-battery-empty: "\f244"; +@fa-var-battery-full: "\f240"; +@fa-var-battery-half: "\f242"; +@fa-var-battery-quarter: "\f243"; +@fa-var-battery-three-quarters: "\f241"; +@fa-var-bed: "\f236"; +@fa-var-beer: "\f0fc"; +@fa-var-behance: "\f1b4"; +@fa-var-behance-square: "\f1b5"; +@fa-var-bell: "\f0f3"; +@fa-var-bell-slash: "\f1f6"; +@fa-var-bicycle: "\f206"; +@fa-var-bimobject: "\f378"; +@fa-var-binoculars: "\f1e5"; +@fa-var-birthday-cake: "\f1fd"; +@fa-var-bitbucket: "\f171"; +@fa-var-bitcoin: "\f379"; +@fa-var-bity: "\f37a"; +@fa-var-black-tie: "\f27e"; +@fa-var-blackberry: "\f37b"; +@fa-var-blind: "\f29d"; +@fa-var-blogger: "\f37c"; +@fa-var-blogger-b: "\f37d"; +@fa-var-bluetooth: "\f293"; +@fa-var-bluetooth-b: "\f294"; +@fa-var-bold: "\f032"; +@fa-var-bolt: "\f0e7"; +@fa-var-bomb: "\f1e2"; +@fa-var-book: "\f02d"; +@fa-var-bookmark: "\f02e"; +@fa-var-braille: "\f2a1"; +@fa-var-briefcase: "\f0b1"; +@fa-var-btc: "\f15a"; +@fa-var-bug: "\f188"; +@fa-var-building: "\f1ad"; +@fa-var-bullhorn: "\f0a1"; +@fa-var-bullseye: "\f140"; +@fa-var-buromobelexperte: "\f37f"; +@fa-var-bus: "\f207"; +@fa-var-buysellads: "\f20d"; +@fa-var-calculator: "\f1ec"; +@fa-var-calendar: "\f133"; +@fa-var-calendar-alt: "\f073"; +@fa-var-calendar-check: "\f274"; +@fa-var-calendar-minus: "\f272"; +@fa-var-calendar-plus: "\f271"; +@fa-var-calendar-times: "\f273"; +@fa-var-camera: "\f030"; +@fa-var-camera-retro: "\f083"; +@fa-var-car: "\f1b9"; +@fa-var-caret-down: "\f0d7"; +@fa-var-caret-left: "\f0d9"; +@fa-var-caret-right: "\f0da"; +@fa-var-caret-square-down: "\f150"; +@fa-var-caret-square-left: "\f191"; +@fa-var-caret-square-right: "\f152"; +@fa-var-caret-square-up: "\f151"; +@fa-var-caret-up: "\f0d8"; +@fa-var-cart-arrow-down: "\f218"; +@fa-var-cart-plus: "\f217"; +@fa-var-cc-amex: "\f1f3"; +@fa-var-cc-apple-pay: "\f416"; +@fa-var-cc-diners-club: "\f24c"; +@fa-var-cc-discover: "\f1f2"; +@fa-var-cc-jcb: "\f24b"; +@fa-var-cc-mastercard: "\f1f1"; +@fa-var-cc-paypal: "\f1f4"; +@fa-var-cc-stripe: "\f1f5"; +@fa-var-cc-visa: "\f1f0"; +@fa-var-centercode: "\f380"; +@fa-var-certificate: "\f0a3"; +@fa-var-chart-area: "\f1fe"; +@fa-var-chart-bar: "\f080"; +@fa-var-chart-line: "\f201"; +@fa-var-chart-pie: "\f200"; +@fa-var-check: "\f00c"; +@fa-var-check-circle: "\f058"; +@fa-var-check-square: "\f14a"; +@fa-var-chevron-circle-down: "\f13a"; +@fa-var-chevron-circle-left: "\f137"; +@fa-var-chevron-circle-right: "\f138"; +@fa-var-chevron-circle-up: "\f139"; +@fa-var-chevron-down: "\f078"; +@fa-var-chevron-left: "\f053"; +@fa-var-chevron-right: "\f054"; +@fa-var-chevron-up: "\f077"; +@fa-var-child: "\f1ae"; +@fa-var-chrome: "\f268"; +@fa-var-circle: "\f111"; +@fa-var-circle-notch: "\f1ce"; +@fa-var-clipboard: "\f328"; +@fa-var-clock: "\f017"; +@fa-var-clone: "\f24d"; +@fa-var-closed-captioning: "\f20a"; +@fa-var-cloud: "\f0c2"; +@fa-var-cloud-download-alt: "\f381"; +@fa-var-cloud-upload-alt: "\f382"; +@fa-var-cloudscale: "\f383"; +@fa-var-cloudsmith: "\f384"; +@fa-var-cloudversify: "\f385"; +@fa-var-code: "\f121"; +@fa-var-code-branch: "\f126"; +@fa-var-codepen: "\f1cb"; +@fa-var-codiepie: "\f284"; +@fa-var-coffee: "\f0f4"; +@fa-var-cog: "\f013"; +@fa-var-cogs: "\f085"; +@fa-var-columns: "\f0db"; +@fa-var-comment: "\f075"; +@fa-var-comment-alt: "\f27a"; +@fa-var-comments: "\f086"; +@fa-var-compass: "\f14e"; +@fa-var-compress: "\f066"; +@fa-var-connectdevelop: "\f20e"; +@fa-var-contao: "\f26d"; +@fa-var-copy: "\f0c5"; +@fa-var-copyright: "\f1f9"; +@fa-var-cpanel: "\f388"; +@fa-var-creative-commons: "\f25e"; +@fa-var-credit-card: "\f09d"; +@fa-var-crop: "\f125"; +@fa-var-crosshairs: "\f05b"; +@fa-var-css3: "\f13c"; +@fa-var-css3-alt: "\f38b"; +@fa-var-cube: "\f1b2"; +@fa-var-cubes: "\f1b3"; +@fa-var-cut: "\f0c4"; +@fa-var-cuttlefish: "\f38c"; +@fa-var-d-and-d: "\f38d"; +@fa-var-dashcube: "\f210"; +@fa-var-database: "\f1c0"; +@fa-var-deaf: "\f2a4"; +@fa-var-delicious: "\f1a5"; +@fa-var-deploydog: "\f38e"; +@fa-var-deskpro: "\f38f"; +@fa-var-desktop: "\f108"; +@fa-var-deviantart: "\f1bd"; +@fa-var-digg: "\f1a6"; +@fa-var-digital-ocean: "\f391"; +@fa-var-discord: "\f392"; +@fa-var-discourse: "\f393"; +@fa-var-dochub: "\f394"; +@fa-var-docker: "\f395"; +@fa-var-dollar-sign: "\f155"; +@fa-var-dot-circle: "\f192"; +@fa-var-download: "\f019"; +@fa-var-draft2digital: "\f396"; +@fa-var-dribbble: "\f17d"; +@fa-var-dribbble-square: "\f397"; +@fa-var-dropbox: "\f16b"; +@fa-var-drupal: "\f1a9"; +@fa-var-dyalog: "\f399"; +@fa-var-earlybirds: "\f39a"; +@fa-var-edge: "\f282"; +@fa-var-edit: "\f044"; +@fa-var-eject: "\f052"; +@fa-var-ellipsis-h: "\f141"; +@fa-var-ellipsis-v: "\f142"; +@fa-var-ember: "\f423"; +@fa-var-empire: "\f1d1"; +@fa-var-envelope: "\f0e0"; +@fa-var-envelope-open: "\f2b6"; +@fa-var-envelope-square: "\f199"; +@fa-var-envira: "\f299"; +@fa-var-eraser: "\f12d"; +@fa-var-erlang: "\f39d"; +@fa-var-etsy: "\f2d7"; +@fa-var-euro-sign: "\f153"; +@fa-var-exchange-alt: "\f362"; +@fa-var-exclamation: "\f12a"; +@fa-var-exclamation-circle: "\f06a"; +@fa-var-exclamation-triangle: "\f071"; +@fa-var-expand: "\f065"; +@fa-var-expand-arrows-alt: "\f31e"; +@fa-var-expeditedssl: "\f23e"; +@fa-var-external-link-alt: "\f35d"; +@fa-var-external-link-square-alt: "\f360"; +@fa-var-eye: "\f06e"; +@fa-var-eye-dropper: "\f1fb"; +@fa-var-eye-slash: "\f070"; +@fa-var-facebook: "\f09a"; +@fa-var-facebook-f: "\f39e"; +@fa-var-facebook-messenger: "\f39f"; +@fa-var-facebook-square: "\f082"; +@fa-var-fast-backward: "\f049"; +@fa-var-fast-forward: "\f050"; +@fa-var-fax: "\f1ac"; +@fa-var-female: "\f182"; +@fa-var-fighter-jet: "\f0fb"; +@fa-var-file: "\f15b"; +@fa-var-file-alt: "\f15c"; +@fa-var-file-archive: "\f1c6"; +@fa-var-file-audio: "\f1c7"; +@fa-var-file-code: "\f1c9"; +@fa-var-file-excel: "\f1c3"; +@fa-var-file-image: "\f1c5"; +@fa-var-file-pdf: "\f1c1"; +@fa-var-file-powerpoint: "\f1c4"; +@fa-var-file-video: "\f1c8"; +@fa-var-file-word: "\f1c2"; +@fa-var-film: "\f008"; +@fa-var-filter: "\f0b0"; +@fa-var-fire: "\f06d"; +@fa-var-fire-extinguisher: "\f134"; +@fa-var-firefox: "\f269"; +@fa-var-first-order: "\f2b0"; +@fa-var-firstdraft: "\f3a1"; +@fa-var-flag: "\f024"; +@fa-var-flag-checkered: "\f11e"; +@fa-var-flask: "\f0c3"; +@fa-var-flickr: "\f16e"; +@fa-var-fly: "\f417"; +@fa-var-folder: "\f07b"; +@fa-var-folder-open: "\f07c"; +@fa-var-font: "\f031"; +@fa-var-font-awesome: "\f2b4"; +@fa-var-font-awesome-alt: "\f35c"; +@fa-var-font-awesome-flag: "\f425"; +@fa-var-fonticons: "\f280"; +@fa-var-fonticons-fi: "\f3a2"; +@fa-var-fort-awesome: "\f286"; +@fa-var-fort-awesome-alt: "\f3a3"; +@fa-var-forumbee: "\f211"; +@fa-var-forward: "\f04e"; +@fa-var-foursquare: "\f180"; +@fa-var-free-code-camp: "\f2c5"; +@fa-var-freebsd: "\f3a4"; +@fa-var-frown: "\f119"; +@fa-var-futbol: "\f1e3"; +@fa-var-gamepad: "\f11b"; +@fa-var-gavel: "\f0e3"; +@fa-var-gem: "\f3a5"; +@fa-var-genderless: "\f22d"; +@fa-var-get-pocket: "\f265"; +@fa-var-gg: "\f260"; +@fa-var-gg-circle: "\f261"; +@fa-var-gift: "\f06b"; +@fa-var-git: "\f1d3"; +@fa-var-git-square: "\f1d2"; +@fa-var-github: "\f09b"; +@fa-var-github-alt: "\f113"; +@fa-var-github-square: "\f092"; +@fa-var-gitkraken: "\f3a6"; +@fa-var-gitlab: "\f296"; +@fa-var-gitter: "\f426"; +@fa-var-glass-martini: "\f000"; +@fa-var-glide: "\f2a5"; +@fa-var-glide-g: "\f2a6"; +@fa-var-globe: "\f0ac"; +@fa-var-gofore: "\f3a7"; +@fa-var-goodreads: "\f3a8"; +@fa-var-goodreads-g: "\f3a9"; +@fa-var-google: "\f1a0"; +@fa-var-google-drive: "\f3aa"; +@fa-var-google-play: "\f3ab"; +@fa-var-google-plus: "\f2b3"; +@fa-var-google-plus-g: "\f0d5"; +@fa-var-google-plus-square: "\f0d4"; +@fa-var-google-wallet: "\f1ee"; +@fa-var-graduation-cap: "\f19d"; +@fa-var-gratipay: "\f184"; +@fa-var-grav: "\f2d6"; +@fa-var-gripfire: "\f3ac"; +@fa-var-grunt: "\f3ad"; +@fa-var-gulp: "\f3ae"; +@fa-var-h-square: "\f0fd"; +@fa-var-hacker-news: "\f1d4"; +@fa-var-hacker-news-square: "\f3af"; +@fa-var-hand-lizard: "\f258"; +@fa-var-hand-paper: "\f256"; +@fa-var-hand-peace: "\f25b"; +@fa-var-hand-point-down: "\f0a7"; +@fa-var-hand-point-left: "\f0a5"; +@fa-var-hand-point-right: "\f0a4"; +@fa-var-hand-point-up: "\f0a6"; +@fa-var-hand-pointer: "\f25a"; +@fa-var-hand-rock: "\f255"; +@fa-var-hand-scissors: "\f257"; +@fa-var-hand-spock: "\f259"; +@fa-var-handshake: "\f2b5"; +@fa-var-hashtag: "\f292"; +@fa-var-hdd: "\f0a0"; +@fa-var-heading: "\f1dc"; +@fa-var-headphones: "\f025"; +@fa-var-heart: "\f004"; +@fa-var-heartbeat: "\f21e"; +@fa-var-hire-a-helper: "\f3b0"; +@fa-var-history: "\f1da"; +@fa-var-home: "\f015"; +@fa-var-hooli: "\f427"; +@fa-var-hospital: "\f0f8"; +@fa-var-hotjar: "\f3b1"; +@fa-var-hourglass: "\f254"; +@fa-var-hourglass-end: "\f253"; +@fa-var-hourglass-half: "\f252"; +@fa-var-hourglass-start: "\f251"; +@fa-var-houzz: "\f27c"; +@fa-var-html5: "\f13b"; +@fa-var-hubspot: "\f3b2"; +@fa-var-i-cursor: "\f246"; +@fa-var-id-badge: "\f2c1"; +@fa-var-id-card: "\f2c2"; +@fa-var-image: "\f03e"; +@fa-var-images: "\f302"; +@fa-var-imdb: "\f2d8"; +@fa-var-inbox: "\f01c"; +@fa-var-indent: "\f03c"; +@fa-var-industry: "\f275"; +@fa-var-info: "\f129"; +@fa-var-info-circle: "\f05a"; +@fa-var-instagram: "\f16d"; +@fa-var-internet-explorer: "\f26b"; +@fa-var-ioxhost: "\f208"; +@fa-var-italic: "\f033"; +@fa-var-itunes: "\f3b4"; +@fa-var-itunes-note: "\f3b5"; +@fa-var-jenkins: "\f3b6"; +@fa-var-joget: "\f3b7"; +@fa-var-joomla: "\f1aa"; +@fa-var-js: "\f3b8"; +@fa-var-js-square: "\f3b9"; +@fa-var-jsfiddle: "\f1cc"; +@fa-var-key: "\f084"; +@fa-var-keyboard: "\f11c"; +@fa-var-keycdn: "\f3ba"; +@fa-var-kickstarter: "\f3bb"; +@fa-var-kickstarter-k: "\f3bc"; +@fa-var-language: "\f1ab"; +@fa-var-laptop: "\f109"; +@fa-var-laravel: "\f3bd"; +@fa-var-lastfm: "\f202"; +@fa-var-lastfm-square: "\f203"; +@fa-var-leaf: "\f06c"; +@fa-var-leanpub: "\f212"; +@fa-var-lemon: "\f094"; +@fa-var-less: "\f41d"; +@fa-var-level-down-alt: "\f3be"; +@fa-var-level-up-alt: "\f3bf"; +@fa-var-life-ring: "\f1cd"; +@fa-var-lightbulb: "\f0eb"; +@fa-var-line: "\f3c0"; +@fa-var-link: "\f0c1"; +@fa-var-linkedin: "\f08c"; +@fa-var-linkedin-in: "\f0e1"; +@fa-var-linode: "\f2b8"; +@fa-var-linux: "\f17c"; +@fa-var-lira-sign: "\f195"; +@fa-var-list: "\f03a"; +@fa-var-list-alt: "\f022"; +@fa-var-list-ol: "\f0cb"; +@fa-var-list-ul: "\f0ca"; +@fa-var-location-arrow: "\f124"; +@fa-var-lock: "\f023"; +@fa-var-lock-open: "\f3c1"; +@fa-var-long-arrow-alt-down: "\f309"; +@fa-var-long-arrow-alt-left: "\f30a"; +@fa-var-long-arrow-alt-right: "\f30b"; +@fa-var-long-arrow-alt-up: "\f30c"; +@fa-var-low-vision: "\f2a8"; +@fa-var-lyft: "\f3c3"; +@fa-var-magento: "\f3c4"; +@fa-var-magic: "\f0d0"; +@fa-var-magnet: "\f076"; +@fa-var-male: "\f183"; +@fa-var-map: "\f279"; +@fa-var-map-marker: "\f041"; +@fa-var-map-marker-alt: "\f3c5"; +@fa-var-map-pin: "\f276"; +@fa-var-map-signs: "\f277"; +@fa-var-mars: "\f222"; +@fa-var-mars-double: "\f227"; +@fa-var-mars-stroke: "\f229"; +@fa-var-mars-stroke-h: "\f22b"; +@fa-var-mars-stroke-v: "\f22a"; +@fa-var-maxcdn: "\f136"; +@fa-var-medapps: "\f3c6"; +@fa-var-medium: "\f23a"; +@fa-var-medium-m: "\f3c7"; +@fa-var-medkit: "\f0fa"; +@fa-var-medrt: "\f3c8"; +@fa-var-meetup: "\f2e0"; +@fa-var-meh: "\f11a"; +@fa-var-mercury: "\f223"; +@fa-var-microchip: "\f2db"; +@fa-var-microphone: "\f130"; +@fa-var-microphone-slash: "\f131"; +@fa-var-microsoft: "\f3ca"; +@fa-var-minus: "\f068"; +@fa-var-minus-circle: "\f056"; +@fa-var-minus-square: "\f146"; +@fa-var-mix: "\f3cb"; +@fa-var-mixcloud: "\f289"; +@fa-var-mizuni: "\f3cc"; +@fa-var-mobile: "\f10b"; +@fa-var-mobile-alt: "\f3cd"; +@fa-var-modx: "\f285"; +@fa-var-monero: "\f3d0"; +@fa-var-money-bill-alt: "\f3d1"; +@fa-var-moon: "\f186"; +@fa-var-motorcycle: "\f21c"; +@fa-var-mouse-pointer: "\f245"; +@fa-var-music: "\f001"; +@fa-var-napster: "\f3d2"; +@fa-var-neuter: "\f22c"; +@fa-var-newspaper: "\f1ea"; +@fa-var-nintendo-switch: "\f418"; +@fa-var-node: "\f419"; +@fa-var-node-js: "\f3d3"; +@fa-var-npm: "\f3d4"; +@fa-var-ns8: "\f3d5"; +@fa-var-nutritionix: "\f3d6"; +@fa-var-object-group: "\f247"; +@fa-var-object-ungroup: "\f248"; +@fa-var-odnoklassniki: "\f263"; +@fa-var-odnoklassniki-square: "\f264"; +@fa-var-opencart: "\f23d"; +@fa-var-openid: "\f19b"; +@fa-var-opera: "\f26a"; +@fa-var-optin-monster: "\f23c"; +@fa-var-osi: "\f41a"; +@fa-var-outdent: "\f03b"; +@fa-var-page4: "\f3d7"; +@fa-var-pagelines: "\f18c"; +@fa-var-paint-brush: "\f1fc"; +@fa-var-palfed: "\f3d8"; +@fa-var-paper-plane: "\f1d8"; +@fa-var-paperclip: "\f0c6"; +@fa-var-paragraph: "\f1dd"; +@fa-var-paste: "\f0ea"; +@fa-var-patreon: "\f3d9"; +@fa-var-pause: "\f04c"; +@fa-var-pause-circle: "\f28b"; +@fa-var-paw: "\f1b0"; +@fa-var-paypal: "\f1ed"; +@fa-var-pen-square: "\f14b"; +@fa-var-pencil-alt: "\f303"; +@fa-var-percent: "\f295"; +@fa-var-periscope: "\f3da"; +@fa-var-phabricator: "\f3db"; +@fa-var-phoenix-framework: "\f3dc"; +@fa-var-phone: "\f095"; +@fa-var-phone-square: "\f098"; +@fa-var-phone-volume: "\f2a0"; +@fa-var-pied-piper: "\f2ae"; +@fa-var-pied-piper-alt: "\f1a8"; +@fa-var-pied-piper-pp: "\f1a7"; +@fa-var-pinterest: "\f0d2"; +@fa-var-pinterest-p: "\f231"; +@fa-var-pinterest-square: "\f0d3"; +@fa-var-plane: "\f072"; +@fa-var-play: "\f04b"; +@fa-var-play-circle: "\f144"; +@fa-var-playstation: "\f3df"; +@fa-var-plug: "\f1e6"; +@fa-var-plus: "\f067"; +@fa-var-plus-circle: "\f055"; +@fa-var-plus-square: "\f0fe"; +@fa-var-podcast: "\f2ce"; +@fa-var-pound-sign: "\f154"; +@fa-var-power-off: "\f011"; +@fa-var-print: "\f02f"; +@fa-var-product-hunt: "\f288"; +@fa-var-pushed: "\f3e1"; +@fa-var-puzzle-piece: "\f12e"; +@fa-var-python: "\f3e2"; +@fa-var-qq: "\f1d6"; +@fa-var-qrcode: "\f029"; +@fa-var-question: "\f128"; +@fa-var-question-circle: "\f059"; +@fa-var-quora: "\f2c4"; +@fa-var-quote-left: "\f10d"; +@fa-var-quote-right: "\f10e"; +@fa-var-random: "\f074"; +@fa-var-ravelry: "\f2d9"; +@fa-var-react: "\f41b"; +@fa-var-rebel: "\f1d0"; +@fa-var-recycle: "\f1b8"; +@fa-var-red-river: "\f3e3"; +@fa-var-reddit: "\f1a1"; +@fa-var-reddit-alien: "\f281"; +@fa-var-reddit-square: "\f1a2"; +@fa-var-redo: "\f01e"; +@fa-var-redo-alt: "\f2f9"; +@fa-var-registered: "\f25d"; +@fa-var-rendact: "\f3e4"; +@fa-var-renren: "\f18b"; +@fa-var-reply: "\f3e5"; +@fa-var-reply-all: "\f122"; +@fa-var-replyd: "\f3e6"; +@fa-var-resolving: "\f3e7"; +@fa-var-retweet: "\f079"; +@fa-var-road: "\f018"; +@fa-var-rocket: "\f135"; +@fa-var-rocketchat: "\f3e8"; +@fa-var-rockrms: "\f3e9"; +@fa-var-rss: "\f09e"; +@fa-var-rss-square: "\f143"; +@fa-var-ruble-sign: "\f158"; +@fa-var-rupee-sign: "\f156"; +@fa-var-safari: "\f267"; +@fa-var-sass: "\f41e"; +@fa-var-save: "\f0c7"; +@fa-var-schlix: "\f3ea"; +@fa-var-scribd: "\f28a"; +@fa-var-search: "\f002"; +@fa-var-search-minus: "\f010"; +@fa-var-search-plus: "\f00e"; +@fa-var-searchengin: "\f3eb"; +@fa-var-sellcast: "\f2da"; +@fa-var-sellsy: "\f213"; +@fa-var-server: "\f233"; +@fa-var-servicestack: "\f3ec"; +@fa-var-share: "\f064"; +@fa-var-share-alt: "\f1e0"; +@fa-var-share-alt-square: "\f1e1"; +@fa-var-share-square: "\f14d"; +@fa-var-shekel-sign: "\f20b"; +@fa-var-shield-alt: "\f3ed"; +@fa-var-ship: "\f21a"; +@fa-var-shirtsinbulk: "\f214"; +@fa-var-shopping-bag: "\f290"; +@fa-var-shopping-basket: "\f291"; +@fa-var-shopping-cart: "\f07a"; +@fa-var-shower: "\f2cc"; +@fa-var-sign-in-alt: "\f2f6"; +@fa-var-sign-language: "\f2a7"; +@fa-var-sign-out-alt: "\f2f5"; +@fa-var-signal: "\f012"; +@fa-var-simplybuilt: "\f215"; +@fa-var-sistrix: "\f3ee"; +@fa-var-sitemap: "\f0e8"; +@fa-var-skyatlas: "\f216"; +@fa-var-skype: "\f17e"; +@fa-var-slack: "\f198"; +@fa-var-slack-hash: "\f3ef"; +@fa-var-sliders-h: "\f1de"; +@fa-var-slideshare: "\f1e7"; +@fa-var-smile: "\f118"; +@fa-var-snapchat: "\f2ab"; +@fa-var-snapchat-ghost: "\f2ac"; +@fa-var-snapchat-square: "\f2ad"; +@fa-var-snowflake: "\f2dc"; +@fa-var-sort: "\f0dc"; +@fa-var-sort-alpha-down: "\f15d"; +@fa-var-sort-alpha-up: "\f15e"; +@fa-var-sort-amount-down: "\f160"; +@fa-var-sort-amount-up: "\f161"; +@fa-var-sort-down: "\f0dd"; +@fa-var-sort-numeric-down: "\f162"; +@fa-var-sort-numeric-up: "\f163"; +@fa-var-sort-up: "\f0de"; +@fa-var-soundcloud: "\f1be"; +@fa-var-space-shuttle: "\f197"; +@fa-var-speakap: "\f3f3"; +@fa-var-spinner: "\f110"; +@fa-var-spotify: "\f1bc"; +@fa-var-square: "\f0c8"; +@fa-var-stack-exchange: "\f18d"; +@fa-var-stack-overflow: "\f16c"; +@fa-var-star: "\f005"; +@fa-var-star-half: "\f089"; +@fa-var-staylinked: "\f3f5"; +@fa-var-steam: "\f1b6"; +@fa-var-steam-square: "\f1b7"; +@fa-var-steam-symbol: "\f3f6"; +@fa-var-step-backward: "\f048"; +@fa-var-step-forward: "\f051"; +@fa-var-stethoscope: "\f0f1"; +@fa-var-sticker-mule: "\f3f7"; +@fa-var-sticky-note: "\f249"; +@fa-var-stop: "\f04d"; +@fa-var-stop-circle: "\f28d"; +@fa-var-strava: "\f428"; +@fa-var-street-view: "\f21d"; +@fa-var-strikethrough: "\f0cc"; +@fa-var-stripe: "\f429"; +@fa-var-stripe-s: "\f42a"; +@fa-var-studiovinari: "\f3f8"; +@fa-var-stumbleupon: "\f1a4"; +@fa-var-stumbleupon-circle: "\f1a3"; +@fa-var-subscript: "\f12c"; +@fa-var-subway: "\f239"; +@fa-var-suitcase: "\f0f2"; +@fa-var-sun: "\f185"; +@fa-var-superpowers: "\f2dd"; +@fa-var-superscript: "\f12b"; +@fa-var-supple: "\f3f9"; +@fa-var-sync: "\f021"; +@fa-var-sync-alt: "\f2f1"; +@fa-var-table: "\f0ce"; +@fa-var-tablet: "\f10a"; +@fa-var-tablet-alt: "\f3fa"; +@fa-var-tachometer-alt: "\f3fd"; +@fa-var-tag: "\f02b"; +@fa-var-tags: "\f02c"; +@fa-var-tasks: "\f0ae"; +@fa-var-taxi: "\f1ba"; +@fa-var-telegram: "\f2c6"; +@fa-var-telegram-plane: "\f3fe"; +@fa-var-tencent-weibo: "\f1d5"; +@fa-var-terminal: "\f120"; +@fa-var-text-height: "\f034"; +@fa-var-text-width: "\f035"; +@fa-var-th: "\f00a"; +@fa-var-th-large: "\f009"; +@fa-var-th-list: "\f00b"; +@fa-var-themeisle: "\f2b2"; +@fa-var-thermometer-empty: "\f2cb"; +@fa-var-thermometer-full: "\f2c7"; +@fa-var-thermometer-half: "\f2c9"; +@fa-var-thermometer-quarter: "\f2ca"; +@fa-var-thermometer-three-quarters: "\f2c8"; +@fa-var-thumbs-down: "\f165"; +@fa-var-thumbs-up: "\f164"; +@fa-var-thumbtack: "\f08d"; +@fa-var-ticket-alt: "\f3ff"; +@fa-var-times: "\f00d"; +@fa-var-times-circle: "\f057"; +@fa-var-tint: "\f043"; +@fa-var-toggle-off: "\f204"; +@fa-var-toggle-on: "\f205"; +@fa-var-trademark: "\f25c"; +@fa-var-train: "\f238"; +@fa-var-transgender: "\f224"; +@fa-var-transgender-alt: "\f225"; +@fa-var-trash: "\f1f8"; +@fa-var-trash-alt: "\f2ed"; +@fa-var-tree: "\f1bb"; +@fa-var-trello: "\f181"; +@fa-var-tripadvisor: "\f262"; +@fa-var-trophy: "\f091"; +@fa-var-truck: "\f0d1"; +@fa-var-tty: "\f1e4"; +@fa-var-tumblr: "\f173"; +@fa-var-tumblr-square: "\f174"; +@fa-var-tv: "\f26c"; +@fa-var-twitch: "\f1e8"; +@fa-var-twitter: "\f099"; +@fa-var-twitter-square: "\f081"; +@fa-var-typo3: "\f42b"; +@fa-var-uber: "\f402"; +@fa-var-uikit: "\f403"; +@fa-var-umbrella: "\f0e9"; +@fa-var-underline: "\f0cd"; +@fa-var-undo: "\f0e2"; +@fa-var-undo-alt: "\f2ea"; +@fa-var-uniregistry: "\f404"; +@fa-var-universal-access: "\f29a"; +@fa-var-university: "\f19c"; +@fa-var-unlink: "\f127"; +@fa-var-unlock: "\f09c"; +@fa-var-unlock-alt: "\f13e"; +@fa-var-untappd: "\f405"; +@fa-var-upload: "\f093"; +@fa-var-usb: "\f287"; +@fa-var-user: "\f007"; +@fa-var-user-circle: "\f2bd"; +@fa-var-user-md: "\f0f0"; +@fa-var-user-plus: "\f234"; +@fa-var-user-secret: "\f21b"; +@fa-var-user-times: "\f235"; +@fa-var-users: "\f0c0"; +@fa-var-ussunnah: "\f407"; +@fa-var-utensil-spoon: "\f2e5"; +@fa-var-utensils: "\f2e7"; +@fa-var-vaadin: "\f408"; +@fa-var-venus: "\f221"; +@fa-var-venus-double: "\f226"; +@fa-var-venus-mars: "\f228"; +@fa-var-viacoin: "\f237"; +@fa-var-viadeo: "\f2a9"; +@fa-var-viadeo-square: "\f2aa"; +@fa-var-viber: "\f409"; +@fa-var-video: "\f03d"; +@fa-var-vimeo: "\f40a"; +@fa-var-vimeo-square: "\f194"; +@fa-var-vimeo-v: "\f27d"; +@fa-var-vine: "\f1ca"; +@fa-var-vk: "\f189"; +@fa-var-vnv: "\f40b"; +@fa-var-volume-down: "\f027"; +@fa-var-volume-off: "\f026"; +@fa-var-volume-up: "\f028"; +@fa-var-vuejs: "\f41f"; +@fa-var-weibo: "\f18a"; +@fa-var-weixin: "\f1d7"; +@fa-var-whatsapp: "\f232"; +@fa-var-whatsapp-square: "\f40c"; +@fa-var-wheelchair: "\f193"; +@fa-var-whmcs: "\f40d"; +@fa-var-wifi: "\f1eb"; +@fa-var-wikipedia-w: "\f266"; +@fa-var-window-close: "\f410"; +@fa-var-window-maximize: "\f2d0"; +@fa-var-window-minimize: "\f2d1"; +@fa-var-window-restore: "\f2d2"; +@fa-var-windows: "\f17a"; +@fa-var-won-sign: "\f159"; +@fa-var-wordpress: "\f19a"; +@fa-var-wordpress-simple: "\f411"; +@fa-var-wpbeginner: "\f297"; +@fa-var-wpexplorer: "\f2de"; +@fa-var-wpforms: "\f298"; +@fa-var-wrench: "\f0ad"; +@fa-var-xbox: "\f412"; +@fa-var-xing: "\f168"; +@fa-var-xing-square: "\f169"; +@fa-var-y-combinator: "\f23b"; +@fa-var-yahoo: "\f19e"; +@fa-var-yandex: "\f413"; +@fa-var-yandex-international: "\f414"; +@fa-var-yelp: "\f1e9"; +@fa-var-yen-sign: "\f157"; +@fa-var-yoast: "\f2b1"; +@fa-var-youtube: "\f167"; diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-brands.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-brands.less new file mode 100644 index 000000000..16aed1444 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-brands.less @@ -0,0 +1,21 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url('@{fa-font-path}/fa-brands-400.eot'); + src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('@{fa-font-path}/fa-brands-400.woff') format('woff'), + url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'), + url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); +} + +.fab { + font-family: 'Font Awesome 5 Brands'; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-regular.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-regular.less new file mode 100644 index 000000000..66448367a --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-regular.less @@ -0,0 +1,22 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url('@{fa-font-path}/fa-regular-400.eot'); + src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('@{fa-font-path}/fa-regular-400.woff') format('woff'), + url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'), + url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); +} + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-solid.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-solid.less new file mode 100644 index 000000000..b492bd99e --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fa-solid.less @@ -0,0 +1,23 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import "_variables.less"; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url('@{fa-font-path}/fa-solid-900.eot'); + src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), + url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('@{fa-font-path}/fa-solid-900.woff') format('woff'), + url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'), + url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); +} + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fontawesome.less b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fontawesome.less new file mode 100644 index 000000000..2b59ee770 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/less/fontawesome.less @@ -0,0 +1,16 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import "_variables.less"; +@import "_mixins.less"; +@import "_core.less"; +@import "_larger.less"; +@import "_fixed-width.less"; +@import "_list.less"; +@import "_bordered-pulled.less"; +@import "_animated.less"; +@import "_rotated-flipped.less"; +@import "_stacked.less"; +@import "_icons.less"; +@import "_screen-reader.less"; diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_animated.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_animated.scss new file mode 100644 index 000000000..7c7c0e173 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_animated.scss @@ -0,0 +1,20 @@ +// Animated Icons +// -------------------------- + +.#{$fa-css-prefix}-spin { + animation: fa-spin 2s infinite linear; +} + +.#{$fa-css-prefix}-pulse { + animation: fa-spin 1s infinite steps(8); +} + +@keyframes fa-spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_bordered-pulled.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_bordered-pulled.scss new file mode 100644 index 000000000..c8c4274c4 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_bordered-pulled.scss @@ -0,0 +1,20 @@ +// Bordered & Pulled +// ------------------------- + +.#{$fa-css-prefix}-border { + border: solid .08em $fa-border-color; + border-radius: .1em; + padding: .2em .25em .15em; +} + +.#{$fa-css-prefix}-pull-left { float: left; } +.#{$fa-css-prefix}-pull-right { float: right; } + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fab { + &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } + &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_core.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_core.scss new file mode 100644 index 000000000..7fd37f855 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_core.scss @@ -0,0 +1,16 @@ +// Base Class Definition +// ------------------------- + +.#{$fa-css-prefix}, +.fas, +.far, +.fal, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_fixed-width.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_fixed-width.scss new file mode 100644 index 000000000..5b33eb49a --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_fixed-width.scss @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.#{$fa-css-prefix}-fw { + text-align: center; + width: (20em / 16); +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_icons.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_icons.scss new file mode 100644 index 000000000..e7422a398 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_icons.scss @@ -0,0 +1,787 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ + +.#{$fa-css-prefix}-500px:before { content: fa-content($fa-var-500px); } +.#{$fa-css-prefix}-accessible-icon:before { content: fa-content($fa-var-accessible-icon); } +.#{$fa-css-prefix}-accusoft:before { content: fa-content($fa-var-accusoft); } +.#{$fa-css-prefix}-address-book:before { content: fa-content($fa-var-address-book); } +.#{$fa-css-prefix}-address-card:before { content: fa-content($fa-var-address-card); } +.#{$fa-css-prefix}-adjust:before { content: fa-content($fa-var-adjust); } +.#{$fa-css-prefix}-adn:before { content: fa-content($fa-var-adn); } +.#{$fa-css-prefix}-adversal:before { content: fa-content($fa-var-adversal); } +.#{$fa-css-prefix}-affiliatetheme:before { content: fa-content($fa-var-affiliatetheme); } +.#{$fa-css-prefix}-algolia:before { content: fa-content($fa-var-algolia); } +.#{$fa-css-prefix}-align-center:before { content: fa-content($fa-var-align-center); } +.#{$fa-css-prefix}-align-justify:before { content: fa-content($fa-var-align-justify); } +.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); } +.#{$fa-css-prefix}-align-right:before { content: fa-content($fa-var-align-right); } +.#{$fa-css-prefix}-amazon:before { content: fa-content($fa-var-amazon); } +.#{$fa-css-prefix}-ambulance:before { content: fa-content($fa-var-ambulance); } +.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: fa-content($fa-var-american-sign-language-interpreting); } +.#{$fa-css-prefix}-amilia:before { content: fa-content($fa-var-amilia); } +.#{$fa-css-prefix}-anchor:before { content: fa-content($fa-var-anchor); } +.#{$fa-css-prefix}-android:before { content: fa-content($fa-var-android); } +.#{$fa-css-prefix}-angellist:before { content: fa-content($fa-var-angellist); } +.#{$fa-css-prefix}-angle-double-down:before { content: fa-content($fa-var-angle-double-down); } +.#{$fa-css-prefix}-angle-double-left:before { content: fa-content($fa-var-angle-double-left); } +.#{$fa-css-prefix}-angle-double-right:before { content: fa-content($fa-var-angle-double-right); } +.#{$fa-css-prefix}-angle-double-up:before { content: fa-content($fa-var-angle-double-up); } +.#{$fa-css-prefix}-angle-down:before { content: fa-content($fa-var-angle-down); } +.#{$fa-css-prefix}-angle-left:before { content: fa-content($fa-var-angle-left); } +.#{$fa-css-prefix}-angle-right:before { content: fa-content($fa-var-angle-right); } +.#{$fa-css-prefix}-angle-up:before { content: fa-content($fa-var-angle-up); } +.#{$fa-css-prefix}-angrycreative:before { content: fa-content($fa-var-angrycreative); } +.#{$fa-css-prefix}-angular:before { content: fa-content($fa-var-angular); } +.#{$fa-css-prefix}-app-store:before { content: fa-content($fa-var-app-store); } +.#{$fa-css-prefix}-app-store-ios:before { content: fa-content($fa-var-app-store-ios); } +.#{$fa-css-prefix}-apper:before { content: fa-content($fa-var-apper); } +.#{$fa-css-prefix}-apple:before { content: fa-content($fa-var-apple); } +.#{$fa-css-prefix}-apple-pay:before { content: fa-content($fa-var-apple-pay); } +.#{$fa-css-prefix}-archive:before { content: fa-content($fa-var-archive); } +.#{$fa-css-prefix}-arrow-alt-circle-down:before { content: fa-content($fa-var-arrow-alt-circle-down); } +.#{$fa-css-prefix}-arrow-alt-circle-left:before { content: fa-content($fa-var-arrow-alt-circle-left); } +.#{$fa-css-prefix}-arrow-alt-circle-right:before { content: fa-content($fa-var-arrow-alt-circle-right); } +.#{$fa-css-prefix}-arrow-alt-circle-up:before { content: fa-content($fa-var-arrow-alt-circle-up); } +.#{$fa-css-prefix}-arrow-circle-down:before { content: fa-content($fa-var-arrow-circle-down); } +.#{$fa-css-prefix}-arrow-circle-left:before { content: fa-content($fa-var-arrow-circle-left); } +.#{$fa-css-prefix}-arrow-circle-right:before { content: fa-content($fa-var-arrow-circle-right); } +.#{$fa-css-prefix}-arrow-circle-up:before { content: fa-content($fa-var-arrow-circle-up); } +.#{$fa-css-prefix}-arrow-down:before { content: fa-content($fa-var-arrow-down); } +.#{$fa-css-prefix}-arrow-left:before { content: fa-content($fa-var-arrow-left); } +.#{$fa-css-prefix}-arrow-right:before { content: fa-content($fa-var-arrow-right); } +.#{$fa-css-prefix}-arrow-up:before { content: fa-content($fa-var-arrow-up); } +.#{$fa-css-prefix}-arrows-alt:before { content: fa-content($fa-var-arrows-alt); } +.#{$fa-css-prefix}-arrows-alt-h:before { content: fa-content($fa-var-arrows-alt-h); } +.#{$fa-css-prefix}-arrows-alt-v:before { content: fa-content($fa-var-arrows-alt-v); } +.#{$fa-css-prefix}-assistive-listening-systems:before { content: fa-content($fa-var-assistive-listening-systems); } +.#{$fa-css-prefix}-asterisk:before { content: fa-content($fa-var-asterisk); } +.#{$fa-css-prefix}-asymmetrik:before { content: fa-content($fa-var-asymmetrik); } +.#{$fa-css-prefix}-at:before { content: fa-content($fa-var-at); } +.#{$fa-css-prefix}-audible:before { content: fa-content($fa-var-audible); } +.#{$fa-css-prefix}-audio-description:before { content: fa-content($fa-var-audio-description); } +.#{$fa-css-prefix}-autoprefixer:before { content: fa-content($fa-var-autoprefixer); } +.#{$fa-css-prefix}-avianex:before { content: fa-content($fa-var-avianex); } +.#{$fa-css-prefix}-aviato:before { content: fa-content($fa-var-aviato); } +.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); } +.#{$fa-css-prefix}-backward:before { content: fa-content($fa-var-backward); } +.#{$fa-css-prefix}-balance-scale:before { content: fa-content($fa-var-balance-scale); } +.#{$fa-css-prefix}-ban:before { content: fa-content($fa-var-ban); } +.#{$fa-css-prefix}-bandcamp:before { content: fa-content($fa-var-bandcamp); } +.#{$fa-css-prefix}-barcode:before { content: fa-content($fa-var-barcode); } +.#{$fa-css-prefix}-bars:before { content: fa-content($fa-var-bars); } +.#{$fa-css-prefix}-bath:before { content: fa-content($fa-var-bath); } +.#{$fa-css-prefix}-battery-empty:before { content: fa-content($fa-var-battery-empty); } +.#{$fa-css-prefix}-battery-full:before { content: fa-content($fa-var-battery-full); } +.#{$fa-css-prefix}-battery-half:before { content: fa-content($fa-var-battery-half); } +.#{$fa-css-prefix}-battery-quarter:before { content: fa-content($fa-var-battery-quarter); } +.#{$fa-css-prefix}-battery-three-quarters:before { content: fa-content($fa-var-battery-three-quarters); } +.#{$fa-css-prefix}-bed:before { content: fa-content($fa-var-bed); } +.#{$fa-css-prefix}-beer:before { content: fa-content($fa-var-beer); } +.#{$fa-css-prefix}-behance:before { content: fa-content($fa-var-behance); } +.#{$fa-css-prefix}-behance-square:before { content: fa-content($fa-var-behance-square); } +.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); } +.#{$fa-css-prefix}-bell-slash:before { content: fa-content($fa-var-bell-slash); } +.#{$fa-css-prefix}-bicycle:before { content: fa-content($fa-var-bicycle); } +.#{$fa-css-prefix}-bimobject:before { content: fa-content($fa-var-bimobject); } +.#{$fa-css-prefix}-binoculars:before { content: fa-content($fa-var-binoculars); } +.#{$fa-css-prefix}-birthday-cake:before { content: fa-content($fa-var-birthday-cake); } +.#{$fa-css-prefix}-bitbucket:before { content: fa-content($fa-var-bitbucket); } +.#{$fa-css-prefix}-bitcoin:before { content: fa-content($fa-var-bitcoin); } +.#{$fa-css-prefix}-bity:before { content: fa-content($fa-var-bity); } +.#{$fa-css-prefix}-black-tie:before { content: fa-content($fa-var-black-tie); } +.#{$fa-css-prefix}-blackberry:before { content: fa-content($fa-var-blackberry); } +.#{$fa-css-prefix}-blind:before { content: fa-content($fa-var-blind); } +.#{$fa-css-prefix}-blogger:before { content: fa-content($fa-var-blogger); } +.#{$fa-css-prefix}-blogger-b:before { content: fa-content($fa-var-blogger-b); } +.#{$fa-css-prefix}-bluetooth:before { content: fa-content($fa-var-bluetooth); } +.#{$fa-css-prefix}-bluetooth-b:before { content: fa-content($fa-var-bluetooth-b); } +.#{$fa-css-prefix}-bold:before { content: fa-content($fa-var-bold); } +.#{$fa-css-prefix}-bolt:before { content: fa-content($fa-var-bolt); } +.#{$fa-css-prefix}-bomb:before { content: fa-content($fa-var-bomb); } +.#{$fa-css-prefix}-book:before { content: fa-content($fa-var-book); } +.#{$fa-css-prefix}-bookmark:before { content: fa-content($fa-var-bookmark); } +.#{$fa-css-prefix}-braille:before { content: fa-content($fa-var-braille); } +.#{$fa-css-prefix}-briefcase:before { content: fa-content($fa-var-briefcase); } +.#{$fa-css-prefix}-btc:before { content: fa-content($fa-var-btc); } +.#{$fa-css-prefix}-bug:before { content: fa-content($fa-var-bug); } +.#{$fa-css-prefix}-building:before { content: fa-content($fa-var-building); } +.#{$fa-css-prefix}-bullhorn:before { content: fa-content($fa-var-bullhorn); } +.#{$fa-css-prefix}-bullseye:before { content: fa-content($fa-var-bullseye); } +.#{$fa-css-prefix}-buromobelexperte:before { content: fa-content($fa-var-buromobelexperte); } +.#{$fa-css-prefix}-bus:before { content: fa-content($fa-var-bus); } +.#{$fa-css-prefix}-buysellads:before { content: fa-content($fa-var-buysellads); } +.#{$fa-css-prefix}-calculator:before { content: fa-content($fa-var-calculator); } +.#{$fa-css-prefix}-calendar:before { content: fa-content($fa-var-calendar); } +.#{$fa-css-prefix}-calendar-alt:before { content: fa-content($fa-var-calendar-alt); } +.#{$fa-css-prefix}-calendar-check:before { content: fa-content($fa-var-calendar-check); } +.#{$fa-css-prefix}-calendar-minus:before { content: fa-content($fa-var-calendar-minus); } +.#{$fa-css-prefix}-calendar-plus:before { content: fa-content($fa-var-calendar-plus); } +.#{$fa-css-prefix}-calendar-times:before { content: fa-content($fa-var-calendar-times); } +.#{$fa-css-prefix}-camera:before { content: fa-content($fa-var-camera); } +.#{$fa-css-prefix}-camera-retro:before { content: fa-content($fa-var-camera-retro); } +.#{$fa-css-prefix}-car:before { content: fa-content($fa-var-car); } +.#{$fa-css-prefix}-caret-down:before { content: fa-content($fa-var-caret-down); } +.#{$fa-css-prefix}-caret-left:before { content: fa-content($fa-var-caret-left); } +.#{$fa-css-prefix}-caret-right:before { content: fa-content($fa-var-caret-right); } +.#{$fa-css-prefix}-caret-square-down:before { content: fa-content($fa-var-caret-square-down); } +.#{$fa-css-prefix}-caret-square-left:before { content: fa-content($fa-var-caret-square-left); } +.#{$fa-css-prefix}-caret-square-right:before { content: fa-content($fa-var-caret-square-right); } +.#{$fa-css-prefix}-caret-square-up:before { content: fa-content($fa-var-caret-square-up); } +.#{$fa-css-prefix}-caret-up:before { content: fa-content($fa-var-caret-up); } +.#{$fa-css-prefix}-cart-arrow-down:before { content: fa-content($fa-var-cart-arrow-down); } +.#{$fa-css-prefix}-cart-plus:before { content: fa-content($fa-var-cart-plus); } +.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); } +.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); } +.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); } +.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); } +.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); } +.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); } +.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); } +.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); } +.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); } +.#{$fa-css-prefix}-centercode:before { content: fa-content($fa-var-centercode); } +.#{$fa-css-prefix}-certificate:before { content: fa-content($fa-var-certificate); } +.#{$fa-css-prefix}-chart-area:before { content: fa-content($fa-var-chart-area); } +.#{$fa-css-prefix}-chart-bar:before { content: fa-content($fa-var-chart-bar); } +.#{$fa-css-prefix}-chart-line:before { content: fa-content($fa-var-chart-line); } +.#{$fa-css-prefix}-chart-pie:before { content: fa-content($fa-var-chart-pie); } +.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); } +.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); } +.#{$fa-css-prefix}-check-square:before { content: fa-content($fa-var-check-square); } +.#{$fa-css-prefix}-chevron-circle-down:before { content: fa-content($fa-var-chevron-circle-down); } +.#{$fa-css-prefix}-chevron-circle-left:before { content: fa-content($fa-var-chevron-circle-left); } +.#{$fa-css-prefix}-chevron-circle-right:before { content: fa-content($fa-var-chevron-circle-right); } +.#{$fa-css-prefix}-chevron-circle-up:before { content: fa-content($fa-var-chevron-circle-up); } +.#{$fa-css-prefix}-chevron-down:before { content: fa-content($fa-var-chevron-down); } +.#{$fa-css-prefix}-chevron-left:before { content: fa-content($fa-var-chevron-left); } +.#{$fa-css-prefix}-chevron-right:before { content: fa-content($fa-var-chevron-right); } +.#{$fa-css-prefix}-chevron-up:before { content: fa-content($fa-var-chevron-up); } +.#{$fa-css-prefix}-child:before { content: fa-content($fa-var-child); } +.#{$fa-css-prefix}-chrome:before { content: fa-content($fa-var-chrome); } +.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); } +.#{$fa-css-prefix}-circle-notch:before { content: fa-content($fa-var-circle-notch); } +.#{$fa-css-prefix}-clipboard:before { content: fa-content($fa-var-clipboard); } +.#{$fa-css-prefix}-clock:before { content: fa-content($fa-var-clock); } +.#{$fa-css-prefix}-clone:before { content: fa-content($fa-var-clone); } +.#{$fa-css-prefix}-closed-captioning:before { content: fa-content($fa-var-closed-captioning); } +.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); } +.#{$fa-css-prefix}-cloud-download-alt:before { content: fa-content($fa-var-cloud-download-alt); } +.#{$fa-css-prefix}-cloud-upload-alt:before { content: fa-content($fa-var-cloud-upload-alt); } +.#{$fa-css-prefix}-cloudscale:before { content: fa-content($fa-var-cloudscale); } +.#{$fa-css-prefix}-cloudsmith:before { content: fa-content($fa-var-cloudsmith); } +.#{$fa-css-prefix}-cloudversify:before { content: fa-content($fa-var-cloudversify); } +.#{$fa-css-prefix}-code:before { content: fa-content($fa-var-code); } +.#{$fa-css-prefix}-code-branch:before { content: fa-content($fa-var-code-branch); } +.#{$fa-css-prefix}-codepen:before { content: fa-content($fa-var-codepen); } +.#{$fa-css-prefix}-codiepie:before { content: fa-content($fa-var-codiepie); } +.#{$fa-css-prefix}-coffee:before { content: fa-content($fa-var-coffee); } +.#{$fa-css-prefix}-cog:before { content: fa-content($fa-var-cog); } +.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); } +.#{$fa-css-prefix}-columns:before { content: fa-content($fa-var-columns); } +.#{$fa-css-prefix}-comment:before { content: fa-content($fa-var-comment); } +.#{$fa-css-prefix}-comment-alt:before { content: fa-content($fa-var-comment-alt); } +.#{$fa-css-prefix}-comments:before { content: fa-content($fa-var-comments); } +.#{$fa-css-prefix}-compass:before { content: fa-content($fa-var-compass); } +.#{$fa-css-prefix}-compress:before { content: fa-content($fa-var-compress); } +.#{$fa-css-prefix}-connectdevelop:before { content: fa-content($fa-var-connectdevelop); } +.#{$fa-css-prefix}-contao:before { content: fa-content($fa-var-contao); } +.#{$fa-css-prefix}-copy:before { content: fa-content($fa-var-copy); } +.#{$fa-css-prefix}-copyright:before { content: fa-content($fa-var-copyright); } +.#{$fa-css-prefix}-cpanel:before { content: fa-content($fa-var-cpanel); } +.#{$fa-css-prefix}-creative-commons:before { content: fa-content($fa-var-creative-commons); } +.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); } +.#{$fa-css-prefix}-crop:before { content: fa-content($fa-var-crop); } +.#{$fa-css-prefix}-crosshairs:before { content: fa-content($fa-var-crosshairs); } +.#{$fa-css-prefix}-css3:before { content: fa-content($fa-var-css3); } +.#{$fa-css-prefix}-css3-alt:before { content: fa-content($fa-var-css3-alt); } +.#{$fa-css-prefix}-cube:before { content: fa-content($fa-var-cube); } +.#{$fa-css-prefix}-cubes:before { content: fa-content($fa-var-cubes); } +.#{$fa-css-prefix}-cut:before { content: fa-content($fa-var-cut); } +.#{$fa-css-prefix}-cuttlefish:before { content: fa-content($fa-var-cuttlefish); } +.#{$fa-css-prefix}-d-and-d:before { content: fa-content($fa-var-d-and-d); } +.#{$fa-css-prefix}-dashcube:before { content: fa-content($fa-var-dashcube); } +.#{$fa-css-prefix}-database:before { content: fa-content($fa-var-database); } +.#{$fa-css-prefix}-deaf:before { content: fa-content($fa-var-deaf); } +.#{$fa-css-prefix}-delicious:before { content: fa-content($fa-var-delicious); } +.#{$fa-css-prefix}-deploydog:before { content: fa-content($fa-var-deploydog); } +.#{$fa-css-prefix}-deskpro:before { content: fa-content($fa-var-deskpro); } +.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); } +.#{$fa-css-prefix}-deviantart:before { content: fa-content($fa-var-deviantart); } +.#{$fa-css-prefix}-digg:before { content: fa-content($fa-var-digg); } +.#{$fa-css-prefix}-digital-ocean:before { content: fa-content($fa-var-digital-ocean); } +.#{$fa-css-prefix}-discord:before { content: fa-content($fa-var-discord); } +.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); } +.#{$fa-css-prefix}-dochub:before { content: fa-content($fa-var-dochub); } +.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); } +.#{$fa-css-prefix}-dollar-sign:before { content: fa-content($fa-var-dollar-sign); } +.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); } +.#{$fa-css-prefix}-download:before { content: fa-content($fa-var-download); } +.#{$fa-css-prefix}-draft2digital:before { content: fa-content($fa-var-draft2digital); } +.#{$fa-css-prefix}-dribbble:before { content: fa-content($fa-var-dribbble); } +.#{$fa-css-prefix}-dribbble-square:before { content: fa-content($fa-var-dribbble-square); } +.#{$fa-css-prefix}-dropbox:before { content: fa-content($fa-var-dropbox); } +.#{$fa-css-prefix}-drupal:before { content: fa-content($fa-var-drupal); } +.#{$fa-css-prefix}-dyalog:before { content: fa-content($fa-var-dyalog); } +.#{$fa-css-prefix}-earlybirds:before { content: fa-content($fa-var-earlybirds); } +.#{$fa-css-prefix}-edge:before { content: fa-content($fa-var-edge); } +.#{$fa-css-prefix}-edit:before { content: fa-content($fa-var-edit); } +.#{$fa-css-prefix}-eject:before { content: fa-content($fa-var-eject); } +.#{$fa-css-prefix}-ellipsis-h:before { content: fa-content($fa-var-ellipsis-h); } +.#{$fa-css-prefix}-ellipsis-v:before { content: fa-content($fa-var-ellipsis-v); } +.#{$fa-css-prefix}-ember:before { content: fa-content($fa-var-ember); } +.#{$fa-css-prefix}-empire:before { content: fa-content($fa-var-empire); } +.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); } +.#{$fa-css-prefix}-envelope-open:before { content: fa-content($fa-var-envelope-open); } +.#{$fa-css-prefix}-envelope-square:before { content: fa-content($fa-var-envelope-square); } +.#{$fa-css-prefix}-envira:before { content: fa-content($fa-var-envira); } +.#{$fa-css-prefix}-eraser:before { content: fa-content($fa-var-eraser); } +.#{$fa-css-prefix}-erlang:before { content: fa-content($fa-var-erlang); } +.#{$fa-css-prefix}-etsy:before { content: fa-content($fa-var-etsy); } +.#{$fa-css-prefix}-euro-sign:before { content: fa-content($fa-var-euro-sign); } +.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); } +.#{$fa-css-prefix}-exclamation:before { content: fa-content($fa-var-exclamation); } +.#{$fa-css-prefix}-exclamation-circle:before { content: fa-content($fa-var-exclamation-circle); } +.#{$fa-css-prefix}-exclamation-triangle:before { content: fa-content($fa-var-exclamation-triangle); } +.#{$fa-css-prefix}-expand:before { content: fa-content($fa-var-expand); } +.#{$fa-css-prefix}-expand-arrows-alt:before { content: fa-content($fa-var-expand-arrows-alt); } +.#{$fa-css-prefix}-expeditedssl:before { content: fa-content($fa-var-expeditedssl); } +.#{$fa-css-prefix}-external-link-alt:before { content: fa-content($fa-var-external-link-alt); } +.#{$fa-css-prefix}-external-link-square-alt:before { content: fa-content($fa-var-external-link-square-alt); } +.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); } +.#{$fa-css-prefix}-eye-dropper:before { content: fa-content($fa-var-eye-dropper); } +.#{$fa-css-prefix}-eye-slash:before { content: fa-content($fa-var-eye-slash); } +.#{$fa-css-prefix}-facebook:before { content: fa-content($fa-var-facebook); } +.#{$fa-css-prefix}-facebook-f:before { content: fa-content($fa-var-facebook-f); } +.#{$fa-css-prefix}-facebook-messenger:before { content: fa-content($fa-var-facebook-messenger); } +.#{$fa-css-prefix}-facebook-square:before { content: fa-content($fa-var-facebook-square); } +.#{$fa-css-prefix}-fast-backward:before { content: fa-content($fa-var-fast-backward); } +.#{$fa-css-prefix}-fast-forward:before { content: fa-content($fa-var-fast-forward); } +.#{$fa-css-prefix}-fax:before { content: fa-content($fa-var-fax); } +.#{$fa-css-prefix}-female:before { content: fa-content($fa-var-female); } +.#{$fa-css-prefix}-fighter-jet:before { content: fa-content($fa-var-fighter-jet); } +.#{$fa-css-prefix}-file:before { content: fa-content($fa-var-file); } +.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); } +.#{$fa-css-prefix}-file-archive:before { content: fa-content($fa-var-file-archive); } +.#{$fa-css-prefix}-file-audio:before { content: fa-content($fa-var-file-audio); } +.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); } +.#{$fa-css-prefix}-file-excel:before { content: fa-content($fa-var-file-excel); } +.#{$fa-css-prefix}-file-image:before { content: fa-content($fa-var-file-image); } +.#{$fa-css-prefix}-file-pdf:before { content: fa-content($fa-var-file-pdf); } +.#{$fa-css-prefix}-file-powerpoint:before { content: fa-content($fa-var-file-powerpoint); } +.#{$fa-css-prefix}-file-video:before { content: fa-content($fa-var-file-video); } +.#{$fa-css-prefix}-file-word:before { content: fa-content($fa-var-file-word); } +.#{$fa-css-prefix}-film:before { content: fa-content($fa-var-film); } +.#{$fa-css-prefix}-filter:before { content: fa-content($fa-var-filter); } +.#{$fa-css-prefix}-fire:before { content: fa-content($fa-var-fire); } +.#{$fa-css-prefix}-fire-extinguisher:before { content: fa-content($fa-var-fire-extinguisher); } +.#{$fa-css-prefix}-firefox:before { content: fa-content($fa-var-firefox); } +.#{$fa-css-prefix}-first-order:before { content: fa-content($fa-var-first-order); } +.#{$fa-css-prefix}-firstdraft:before { content: fa-content($fa-var-firstdraft); } +.#{$fa-css-prefix}-flag:before { content: fa-content($fa-var-flag); } +.#{$fa-css-prefix}-flag-checkered:before { content: fa-content($fa-var-flag-checkered); } +.#{$fa-css-prefix}-flask:before { content: fa-content($fa-var-flask); } +.#{$fa-css-prefix}-flickr:before { content: fa-content($fa-var-flickr); } +.#{$fa-css-prefix}-fly:before { content: fa-content($fa-var-fly); } +.#{$fa-css-prefix}-folder:before { content: fa-content($fa-var-folder); } +.#{$fa-css-prefix}-folder-open:before { content: fa-content($fa-var-folder-open); } +.#{$fa-css-prefix}-font:before { content: fa-content($fa-var-font); } +.#{$fa-css-prefix}-font-awesome:before { content: fa-content($fa-var-font-awesome); } +.#{$fa-css-prefix}-font-awesome-alt:before { content: fa-content($fa-var-font-awesome-alt); } +.#{$fa-css-prefix}-font-awesome-flag:before { content: fa-content($fa-var-font-awesome-flag); } +.#{$fa-css-prefix}-fonticons:before { content: fa-content($fa-var-fonticons); } +.#{$fa-css-prefix}-fonticons-fi:before { content: fa-content($fa-var-fonticons-fi); } +.#{$fa-css-prefix}-fort-awesome:before { content: fa-content($fa-var-fort-awesome); } +.#{$fa-css-prefix}-fort-awesome-alt:before { content: fa-content($fa-var-fort-awesome-alt); } +.#{$fa-css-prefix}-forumbee:before { content: fa-content($fa-var-forumbee); } +.#{$fa-css-prefix}-forward:before { content: fa-content($fa-var-forward); } +.#{$fa-css-prefix}-foursquare:before { content: fa-content($fa-var-foursquare); } +.#{$fa-css-prefix}-free-code-camp:before { content: fa-content($fa-var-free-code-camp); } +.#{$fa-css-prefix}-freebsd:before { content: fa-content($fa-var-freebsd); } +.#{$fa-css-prefix}-frown:before { content: fa-content($fa-var-frown); } +.#{$fa-css-prefix}-futbol:before { content: fa-content($fa-var-futbol); } +.#{$fa-css-prefix}-gamepad:before { content: fa-content($fa-var-gamepad); } +.#{$fa-css-prefix}-gavel:before { content: fa-content($fa-var-gavel); } +.#{$fa-css-prefix}-gem:before { content: fa-content($fa-var-gem); } +.#{$fa-css-prefix}-genderless:before { content: fa-content($fa-var-genderless); } +.#{$fa-css-prefix}-get-pocket:before { content: fa-content($fa-var-get-pocket); } +.#{$fa-css-prefix}-gg:before { content: fa-content($fa-var-gg); } +.#{$fa-css-prefix}-gg-circle:before { content: fa-content($fa-var-gg-circle); } +.#{$fa-css-prefix}-gift:before { content: fa-content($fa-var-gift); } +.#{$fa-css-prefix}-git:before { content: fa-content($fa-var-git); } +.#{$fa-css-prefix}-git-square:before { content: fa-content($fa-var-git-square); } +.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); } +.#{$fa-css-prefix}-github-alt:before { content: fa-content($fa-var-github-alt); } +.#{$fa-css-prefix}-github-square:before { content: fa-content($fa-var-github-square); } +.#{$fa-css-prefix}-gitkraken:before { content: fa-content($fa-var-gitkraken); } +.#{$fa-css-prefix}-gitlab:before { content: fa-content($fa-var-gitlab); } +.#{$fa-css-prefix}-gitter:before { content: fa-content($fa-var-gitter); } +.#{$fa-css-prefix}-glass-martini:before { content: fa-content($fa-var-glass-martini); } +.#{$fa-css-prefix}-glide:before { content: fa-content($fa-var-glide); } +.#{$fa-css-prefix}-glide-g:before { content: fa-content($fa-var-glide-g); } +.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); } +.#{$fa-css-prefix}-gofore:before { content: fa-content($fa-var-gofore); } +.#{$fa-css-prefix}-goodreads:before { content: fa-content($fa-var-goodreads); } +.#{$fa-css-prefix}-goodreads-g:before { content: fa-content($fa-var-goodreads-g); } +.#{$fa-css-prefix}-google:before { content: fa-content($fa-var-google); } +.#{$fa-css-prefix}-google-drive:before { content: fa-content($fa-var-google-drive); } +.#{$fa-css-prefix}-google-play:before { content: fa-content($fa-var-google-play); } +.#{$fa-css-prefix}-google-plus:before { content: fa-content($fa-var-google-plus); } +.#{$fa-css-prefix}-google-plus-g:before { content: fa-content($fa-var-google-plus-g); } +.#{$fa-css-prefix}-google-plus-square:before { content: fa-content($fa-var-google-plus-square); } +.#{$fa-css-prefix}-google-wallet:before { content: fa-content($fa-var-google-wallet); } +.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); } +.#{$fa-css-prefix}-gratipay:before { content: fa-content($fa-var-gratipay); } +.#{$fa-css-prefix}-grav:before { content: fa-content($fa-var-grav); } +.#{$fa-css-prefix}-gripfire:before { content: fa-content($fa-var-gripfire); } +.#{$fa-css-prefix}-grunt:before { content: fa-content($fa-var-grunt); } +.#{$fa-css-prefix}-gulp:before { content: fa-content($fa-var-gulp); } +.#{$fa-css-prefix}-h-square:before { content: fa-content($fa-var-h-square); } +.#{$fa-css-prefix}-hacker-news:before { content: fa-content($fa-var-hacker-news); } +.#{$fa-css-prefix}-hacker-news-square:before { content: fa-content($fa-var-hacker-news-square); } +.#{$fa-css-prefix}-hand-lizard:before { content: fa-content($fa-var-hand-lizard); } +.#{$fa-css-prefix}-hand-paper:before { content: fa-content($fa-var-hand-paper); } +.#{$fa-css-prefix}-hand-peace:before { content: fa-content($fa-var-hand-peace); } +.#{$fa-css-prefix}-hand-point-down:before { content: fa-content($fa-var-hand-point-down); } +.#{$fa-css-prefix}-hand-point-left:before { content: fa-content($fa-var-hand-point-left); } +.#{$fa-css-prefix}-hand-point-right:before { content: fa-content($fa-var-hand-point-right); } +.#{$fa-css-prefix}-hand-point-up:before { content: fa-content($fa-var-hand-point-up); } +.#{$fa-css-prefix}-hand-pointer:before { content: fa-content($fa-var-hand-pointer); } +.#{$fa-css-prefix}-hand-rock:before { content: fa-content($fa-var-hand-rock); } +.#{$fa-css-prefix}-hand-scissors:before { content: fa-content($fa-var-hand-scissors); } +.#{$fa-css-prefix}-hand-spock:before { content: fa-content($fa-var-hand-spock); } +.#{$fa-css-prefix}-handshake:before { content: fa-content($fa-var-handshake); } +.#{$fa-css-prefix}-hashtag:before { content: fa-content($fa-var-hashtag); } +.#{$fa-css-prefix}-hdd:before { content: fa-content($fa-var-hdd); } +.#{$fa-css-prefix}-heading:before { content: fa-content($fa-var-heading); } +.#{$fa-css-prefix}-headphones:before { content: fa-content($fa-var-headphones); } +.#{$fa-css-prefix}-heart:before { content: fa-content($fa-var-heart); } +.#{$fa-css-prefix}-heartbeat:before { content: fa-content($fa-var-heartbeat); } +.#{$fa-css-prefix}-hire-a-helper:before { content: fa-content($fa-var-hire-a-helper); } +.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); } +.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); } +.#{$fa-css-prefix}-hooli:before { content: fa-content($fa-var-hooli); } +.#{$fa-css-prefix}-hospital:before { content: fa-content($fa-var-hospital); } +.#{$fa-css-prefix}-hotjar:before { content: fa-content($fa-var-hotjar); } +.#{$fa-css-prefix}-hourglass:before { content: fa-content($fa-var-hourglass); } +.#{$fa-css-prefix}-hourglass-end:before { content: fa-content($fa-var-hourglass-end); } +.#{$fa-css-prefix}-hourglass-half:before { content: fa-content($fa-var-hourglass-half); } +.#{$fa-css-prefix}-hourglass-start:before { content: fa-content($fa-var-hourglass-start); } +.#{$fa-css-prefix}-houzz:before { content: fa-content($fa-var-houzz); } +.#{$fa-css-prefix}-html5:before { content: fa-content($fa-var-html5); } +.#{$fa-css-prefix}-hubspot:before { content: fa-content($fa-var-hubspot); } +.#{$fa-css-prefix}-i-cursor:before { content: fa-content($fa-var-i-cursor); } +.#{$fa-css-prefix}-id-badge:before { content: fa-content($fa-var-id-badge); } +.#{$fa-css-prefix}-id-card:before { content: fa-content($fa-var-id-card); } +.#{$fa-css-prefix}-image:before { content: fa-content($fa-var-image); } +.#{$fa-css-prefix}-images:before { content: fa-content($fa-var-images); } +.#{$fa-css-prefix}-imdb:before { content: fa-content($fa-var-imdb); } +.#{$fa-css-prefix}-inbox:before { content: fa-content($fa-var-inbox); } +.#{$fa-css-prefix}-indent:before { content: fa-content($fa-var-indent); } +.#{$fa-css-prefix}-industry:before { content: fa-content($fa-var-industry); } +.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); } +.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); } +.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); } +.#{$fa-css-prefix}-internet-explorer:before { content: fa-content($fa-var-internet-explorer); } +.#{$fa-css-prefix}-ioxhost:before { content: fa-content($fa-var-ioxhost); } +.#{$fa-css-prefix}-italic:before { content: fa-content($fa-var-italic); } +.#{$fa-css-prefix}-itunes:before { content: fa-content($fa-var-itunes); } +.#{$fa-css-prefix}-itunes-note:before { content: fa-content($fa-var-itunes-note); } +.#{$fa-css-prefix}-jenkins:before { content: fa-content($fa-var-jenkins); } +.#{$fa-css-prefix}-joget:before { content: fa-content($fa-var-joget); } +.#{$fa-css-prefix}-joomla:before { content: fa-content($fa-var-joomla); } +.#{$fa-css-prefix}-js:before { content: fa-content($fa-var-js); } +.#{$fa-css-prefix}-js-square:before { content: fa-content($fa-var-js-square); } +.#{$fa-css-prefix}-jsfiddle:before { content: fa-content($fa-var-jsfiddle); } +.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); } +.#{$fa-css-prefix}-keyboard:before { content: fa-content($fa-var-keyboard); } +.#{$fa-css-prefix}-keycdn:before { content: fa-content($fa-var-keycdn); } +.#{$fa-css-prefix}-kickstarter:before { content: fa-content($fa-var-kickstarter); } +.#{$fa-css-prefix}-kickstarter-k:before { content: fa-content($fa-var-kickstarter-k); } +.#{$fa-css-prefix}-language:before { content: fa-content($fa-var-language); } +.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); } +.#{$fa-css-prefix}-laravel:before { content: fa-content($fa-var-laravel); } +.#{$fa-css-prefix}-lastfm:before { content: fa-content($fa-var-lastfm); } +.#{$fa-css-prefix}-lastfm-square:before { content: fa-content($fa-var-lastfm-square); } +.#{$fa-css-prefix}-leaf:before { content: fa-content($fa-var-leaf); } +.#{$fa-css-prefix}-leanpub:before { content: fa-content($fa-var-leanpub); } +.#{$fa-css-prefix}-lemon:before { content: fa-content($fa-var-lemon); } +.#{$fa-css-prefix}-less:before { content: fa-content($fa-var-less); } +.#{$fa-css-prefix}-level-down-alt:before { content: fa-content($fa-var-level-down-alt); } +.#{$fa-css-prefix}-level-up-alt:before { content: fa-content($fa-var-level-up-alt); } +.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); } +.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); } +.#{$fa-css-prefix}-line:before { content: fa-content($fa-var-line); } +.#{$fa-css-prefix}-link:before { content: fa-content($fa-var-link); } +.#{$fa-css-prefix}-linkedin:before { content: fa-content($fa-var-linkedin); } +.#{$fa-css-prefix}-linkedin-in:before { content: fa-content($fa-var-linkedin-in); } +.#{$fa-css-prefix}-linode:before { content: fa-content($fa-var-linode); } +.#{$fa-css-prefix}-linux:before { content: fa-content($fa-var-linux); } +.#{$fa-css-prefix}-lira-sign:before { content: fa-content($fa-var-lira-sign); } +.#{$fa-css-prefix}-list:before { content: fa-content($fa-var-list); } +.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); } +.#{$fa-css-prefix}-list-ol:before { content: fa-content($fa-var-list-ol); } +.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); } +.#{$fa-css-prefix}-location-arrow:before { content: fa-content($fa-var-location-arrow); } +.#{$fa-css-prefix}-lock:before { content: fa-content($fa-var-lock); } +.#{$fa-css-prefix}-lock-open:before { content: fa-content($fa-var-lock-open); } +.#{$fa-css-prefix}-long-arrow-alt-down:before { content: fa-content($fa-var-long-arrow-alt-down); } +.#{$fa-css-prefix}-long-arrow-alt-left:before { content: fa-content($fa-var-long-arrow-alt-left); } +.#{$fa-css-prefix}-long-arrow-alt-right:before { content: fa-content($fa-var-long-arrow-alt-right); } +.#{$fa-css-prefix}-long-arrow-alt-up:before { content: fa-content($fa-var-long-arrow-alt-up); } +.#{$fa-css-prefix}-low-vision:before { content: fa-content($fa-var-low-vision); } +.#{$fa-css-prefix}-lyft:before { content: fa-content($fa-var-lyft); } +.#{$fa-css-prefix}-magento:before { content: fa-content($fa-var-magento); } +.#{$fa-css-prefix}-magic:before { content: fa-content($fa-var-magic); } +.#{$fa-css-prefix}-magnet:before { content: fa-content($fa-var-magnet); } +.#{$fa-css-prefix}-male:before { content: fa-content($fa-var-male); } +.#{$fa-css-prefix}-map:before { content: fa-content($fa-var-map); } +.#{$fa-css-prefix}-map-marker:before { content: fa-content($fa-var-map-marker); } +.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); } +.#{$fa-css-prefix}-map-pin:before { content: fa-content($fa-var-map-pin); } +.#{$fa-css-prefix}-map-signs:before { content: fa-content($fa-var-map-signs); } +.#{$fa-css-prefix}-mars:before { content: fa-content($fa-var-mars); } +.#{$fa-css-prefix}-mars-double:before { content: fa-content($fa-var-mars-double); } +.#{$fa-css-prefix}-mars-stroke:before { content: fa-content($fa-var-mars-stroke); } +.#{$fa-css-prefix}-mars-stroke-h:before { content: fa-content($fa-var-mars-stroke-h); } +.#{$fa-css-prefix}-mars-stroke-v:before { content: fa-content($fa-var-mars-stroke-v); } +.#{$fa-css-prefix}-maxcdn:before { content: fa-content($fa-var-maxcdn); } +.#{$fa-css-prefix}-medapps:before { content: fa-content($fa-var-medapps); } +.#{$fa-css-prefix}-medium:before { content: fa-content($fa-var-medium); } +.#{$fa-css-prefix}-medium-m:before { content: fa-content($fa-var-medium-m); } +.#{$fa-css-prefix}-medkit:before { content: fa-content($fa-var-medkit); } +.#{$fa-css-prefix}-medrt:before { content: fa-content($fa-var-medrt); } +.#{$fa-css-prefix}-meetup:before { content: fa-content($fa-var-meetup); } +.#{$fa-css-prefix}-meh:before { content: fa-content($fa-var-meh); } +.#{$fa-css-prefix}-mercury:before { content: fa-content($fa-var-mercury); } +.#{$fa-css-prefix}-microchip:before { content: fa-content($fa-var-microchip); } +.#{$fa-css-prefix}-microphone:before { content: fa-content($fa-var-microphone); } +.#{$fa-css-prefix}-microphone-slash:before { content: fa-content($fa-var-microphone-slash); } +.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); } +.#{$fa-css-prefix}-minus:before { content: fa-content($fa-var-minus); } +.#{$fa-css-prefix}-minus-circle:before { content: fa-content($fa-var-minus-circle); } +.#{$fa-css-prefix}-minus-square:before { content: fa-content($fa-var-minus-square); } +.#{$fa-css-prefix}-mix:before { content: fa-content($fa-var-mix); } +.#{$fa-css-prefix}-mixcloud:before { content: fa-content($fa-var-mixcloud); } +.#{$fa-css-prefix}-mizuni:before { content: fa-content($fa-var-mizuni); } +.#{$fa-css-prefix}-mobile:before { content: fa-content($fa-var-mobile); } +.#{$fa-css-prefix}-mobile-alt:before { content: fa-content($fa-var-mobile-alt); } +.#{$fa-css-prefix}-modx:before { content: fa-content($fa-var-modx); } +.#{$fa-css-prefix}-monero:before { content: fa-content($fa-var-monero); } +.#{$fa-css-prefix}-money-bill-alt:before { content: fa-content($fa-var-money-bill-alt); } +.#{$fa-css-prefix}-moon:before { content: fa-content($fa-var-moon); } +.#{$fa-css-prefix}-motorcycle:before { content: fa-content($fa-var-motorcycle); } +.#{$fa-css-prefix}-mouse-pointer:before { content: fa-content($fa-var-mouse-pointer); } +.#{$fa-css-prefix}-music:before { content: fa-content($fa-var-music); } +.#{$fa-css-prefix}-napster:before { content: fa-content($fa-var-napster); } +.#{$fa-css-prefix}-neuter:before { content: fa-content($fa-var-neuter); } +.#{$fa-css-prefix}-newspaper:before { content: fa-content($fa-var-newspaper); } +.#{$fa-css-prefix}-nintendo-switch:before { content: fa-content($fa-var-nintendo-switch); } +.#{$fa-css-prefix}-node:before { content: fa-content($fa-var-node); } +.#{$fa-css-prefix}-node-js:before { content: fa-content($fa-var-node-js); } +.#{$fa-css-prefix}-npm:before { content: fa-content($fa-var-npm); } +.#{$fa-css-prefix}-ns8:before { content: fa-content($fa-var-ns8); } +.#{$fa-css-prefix}-nutritionix:before { content: fa-content($fa-var-nutritionix); } +.#{$fa-css-prefix}-object-group:before { content: fa-content($fa-var-object-group); } +.#{$fa-css-prefix}-object-ungroup:before { content: fa-content($fa-var-object-ungroup); } +.#{$fa-css-prefix}-odnoklassniki:before { content: fa-content($fa-var-odnoklassniki); } +.#{$fa-css-prefix}-odnoklassniki-square:before { content: fa-content($fa-var-odnoklassniki-square); } +.#{$fa-css-prefix}-opencart:before { content: fa-content($fa-var-opencart); } +.#{$fa-css-prefix}-openid:before { content: fa-content($fa-var-openid); } +.#{$fa-css-prefix}-opera:before { content: fa-content($fa-var-opera); } +.#{$fa-css-prefix}-optin-monster:before { content: fa-content($fa-var-optin-monster); } +.#{$fa-css-prefix}-osi:before { content: fa-content($fa-var-osi); } +.#{$fa-css-prefix}-outdent:before { content: fa-content($fa-var-outdent); } +.#{$fa-css-prefix}-page4:before { content: fa-content($fa-var-page4); } +.#{$fa-css-prefix}-pagelines:before { content: fa-content($fa-var-pagelines); } +.#{$fa-css-prefix}-paint-brush:before { content: fa-content($fa-var-paint-brush); } +.#{$fa-css-prefix}-palfed:before { content: fa-content($fa-var-palfed); } +.#{$fa-css-prefix}-paper-plane:before { content: fa-content($fa-var-paper-plane); } +.#{$fa-css-prefix}-paperclip:before { content: fa-content($fa-var-paperclip); } +.#{$fa-css-prefix}-paragraph:before { content: fa-content($fa-var-paragraph); } +.#{$fa-css-prefix}-paste:before { content: fa-content($fa-var-paste); } +.#{$fa-css-prefix}-patreon:before { content: fa-content($fa-var-patreon); } +.#{$fa-css-prefix}-pause:before { content: fa-content($fa-var-pause); } +.#{$fa-css-prefix}-pause-circle:before { content: fa-content($fa-var-pause-circle); } +.#{$fa-css-prefix}-paw:before { content: fa-content($fa-var-paw); } +.#{$fa-css-prefix}-paypal:before { content: fa-content($fa-var-paypal); } +.#{$fa-css-prefix}-pen-square:before { content: fa-content($fa-var-pen-square); } +.#{$fa-css-prefix}-pencil-alt:before { content: fa-content($fa-var-pencil-alt); } +.#{$fa-css-prefix}-percent:before { content: fa-content($fa-var-percent); } +.#{$fa-css-prefix}-periscope:before { content: fa-content($fa-var-periscope); } +.#{$fa-css-prefix}-phabricator:before { content: fa-content($fa-var-phabricator); } +.#{$fa-css-prefix}-phoenix-framework:before { content: fa-content($fa-var-phoenix-framework); } +.#{$fa-css-prefix}-phone:before { content: fa-content($fa-var-phone); } +.#{$fa-css-prefix}-phone-square:before { content: fa-content($fa-var-phone-square); } +.#{$fa-css-prefix}-phone-volume:before { content: fa-content($fa-var-phone-volume); } +.#{$fa-css-prefix}-pied-piper:before { content: fa-content($fa-var-pied-piper); } +.#{$fa-css-prefix}-pied-piper-alt:before { content: fa-content($fa-var-pied-piper-alt); } +.#{$fa-css-prefix}-pied-piper-pp:before { content: fa-content($fa-var-pied-piper-pp); } +.#{$fa-css-prefix}-pinterest:before { content: fa-content($fa-var-pinterest); } +.#{$fa-css-prefix}-pinterest-p:before { content: fa-content($fa-var-pinterest-p); } +.#{$fa-css-prefix}-pinterest-square:before { content: fa-content($fa-var-pinterest-square); } +.#{$fa-css-prefix}-plane:before { content: fa-content($fa-var-plane); } +.#{$fa-css-prefix}-play:before { content: fa-content($fa-var-play); } +.#{$fa-css-prefix}-play-circle:before { content: fa-content($fa-var-play-circle); } +.#{$fa-css-prefix}-playstation:before { content: fa-content($fa-var-playstation); } +.#{$fa-css-prefix}-plug:before { content: fa-content($fa-var-plug); } +.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); } +.#{$fa-css-prefix}-plus-circle:before { content: fa-content($fa-var-plus-circle); } +.#{$fa-css-prefix}-plus-square:before { content: fa-content($fa-var-plus-square); } +.#{$fa-css-prefix}-podcast:before { content: fa-content($fa-var-podcast); } +.#{$fa-css-prefix}-pound-sign:before { content: fa-content($fa-var-pound-sign); } +.#{$fa-css-prefix}-power-off:before { content: fa-content($fa-var-power-off); } +.#{$fa-css-prefix}-print:before { content: fa-content($fa-var-print); } +.#{$fa-css-prefix}-product-hunt:before { content: fa-content($fa-var-product-hunt); } +.#{$fa-css-prefix}-pushed:before { content: fa-content($fa-var-pushed); } +.#{$fa-css-prefix}-puzzle-piece:before { content: fa-content($fa-var-puzzle-piece); } +.#{$fa-css-prefix}-python:before { content: fa-content($fa-var-python); } +.#{$fa-css-prefix}-qq:before { content: fa-content($fa-var-qq); } +.#{$fa-css-prefix}-qrcode:before { content: fa-content($fa-var-qrcode); } +.#{$fa-css-prefix}-question:before { content: fa-content($fa-var-question); } +.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); } +.#{$fa-css-prefix}-quora:before { content: fa-content($fa-var-quora); } +.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); } +.#{$fa-css-prefix}-quote-right:before { content: fa-content($fa-var-quote-right); } +.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); } +.#{$fa-css-prefix}-ravelry:before { content: fa-content($fa-var-ravelry); } +.#{$fa-css-prefix}-react:before { content: fa-content($fa-var-react); } +.#{$fa-css-prefix}-rebel:before { content: fa-content($fa-var-rebel); } +.#{$fa-css-prefix}-recycle:before { content: fa-content($fa-var-recycle); } +.#{$fa-css-prefix}-red-river:before { content: fa-content($fa-var-red-river); } +.#{$fa-css-prefix}-reddit:before { content: fa-content($fa-var-reddit); } +.#{$fa-css-prefix}-reddit-alien:before { content: fa-content($fa-var-reddit-alien); } +.#{$fa-css-prefix}-reddit-square:before { content: fa-content($fa-var-reddit-square); } +.#{$fa-css-prefix}-redo:before { content: fa-content($fa-var-redo); } +.#{$fa-css-prefix}-redo-alt:before { content: fa-content($fa-var-redo-alt); } +.#{$fa-css-prefix}-registered:before { content: fa-content($fa-var-registered); } +.#{$fa-css-prefix}-rendact:before { content: fa-content($fa-var-rendact); } +.#{$fa-css-prefix}-renren:before { content: fa-content($fa-var-renren); } +.#{$fa-css-prefix}-reply:before { content: fa-content($fa-var-reply); } +.#{$fa-css-prefix}-reply-all:before { content: fa-content($fa-var-reply-all); } +.#{$fa-css-prefix}-replyd:before { content: fa-content($fa-var-replyd); } +.#{$fa-css-prefix}-resolving:before { content: fa-content($fa-var-resolving); } +.#{$fa-css-prefix}-retweet:before { content: fa-content($fa-var-retweet); } +.#{$fa-css-prefix}-road:before { content: fa-content($fa-var-road); } +.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); } +.#{$fa-css-prefix}-rocketchat:before { content: fa-content($fa-var-rocketchat); } +.#{$fa-css-prefix}-rockrms:before { content: fa-content($fa-var-rockrms); } +.#{$fa-css-prefix}-rss:before { content: fa-content($fa-var-rss); } +.#{$fa-css-prefix}-rss-square:before { content: fa-content($fa-var-rss-square); } +.#{$fa-css-prefix}-ruble-sign:before { content: fa-content($fa-var-ruble-sign); } +.#{$fa-css-prefix}-rupee-sign:before { content: fa-content($fa-var-rupee-sign); } +.#{$fa-css-prefix}-safari:before { content: fa-content($fa-var-safari); } +.#{$fa-css-prefix}-sass:before { content: fa-content($fa-var-sass); } +.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); } +.#{$fa-css-prefix}-schlix:before { content: fa-content($fa-var-schlix); } +.#{$fa-css-prefix}-scribd:before { content: fa-content($fa-var-scribd); } +.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); } +.#{$fa-css-prefix}-search-minus:before { content: fa-content($fa-var-search-minus); } +.#{$fa-css-prefix}-search-plus:before { content: fa-content($fa-var-search-plus); } +.#{$fa-css-prefix}-searchengin:before { content: fa-content($fa-var-searchengin); } +.#{$fa-css-prefix}-sellcast:before { content: fa-content($fa-var-sellcast); } +.#{$fa-css-prefix}-sellsy:before { content: fa-content($fa-var-sellsy); } +.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); } +.#{$fa-css-prefix}-servicestack:before { content: fa-content($fa-var-servicestack); } +.#{$fa-css-prefix}-share:before { content: fa-content($fa-var-share); } +.#{$fa-css-prefix}-share-alt:before { content: fa-content($fa-var-share-alt); } +.#{$fa-css-prefix}-share-alt-square:before { content: fa-content($fa-var-share-alt-square); } +.#{$fa-css-prefix}-share-square:before { content: fa-content($fa-var-share-square); } +.#{$fa-css-prefix}-shekel-sign:before { content: fa-content($fa-var-shekel-sign); } +.#{$fa-css-prefix}-shield-alt:before { content: fa-content($fa-var-shield-alt); } +.#{$fa-css-prefix}-ship:before { content: fa-content($fa-var-ship); } +.#{$fa-css-prefix}-shirtsinbulk:before { content: fa-content($fa-var-shirtsinbulk); } +.#{$fa-css-prefix}-shopping-bag:before { content: fa-content($fa-var-shopping-bag); } +.#{$fa-css-prefix}-shopping-basket:before { content: fa-content($fa-var-shopping-basket); } +.#{$fa-css-prefix}-shopping-cart:before { content: fa-content($fa-var-shopping-cart); } +.#{$fa-css-prefix}-shower:before { content: fa-content($fa-var-shower); } +.#{$fa-css-prefix}-sign-in-alt:before { content: fa-content($fa-var-sign-in-alt); } +.#{$fa-css-prefix}-sign-language:before { content: fa-content($fa-var-sign-language); } +.#{$fa-css-prefix}-sign-out-alt:before { content: fa-content($fa-var-sign-out-alt); } +.#{$fa-css-prefix}-signal:before { content: fa-content($fa-var-signal); } +.#{$fa-css-prefix}-simplybuilt:before { content: fa-content($fa-var-simplybuilt); } +.#{$fa-css-prefix}-sistrix:before { content: fa-content($fa-var-sistrix); } +.#{$fa-css-prefix}-sitemap:before { content: fa-content($fa-var-sitemap); } +.#{$fa-css-prefix}-skyatlas:before { content: fa-content($fa-var-skyatlas); } +.#{$fa-css-prefix}-skype:before { content: fa-content($fa-var-skype); } +.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); } +.#{$fa-css-prefix}-slack-hash:before { content: fa-content($fa-var-slack-hash); } +.#{$fa-css-prefix}-sliders-h:before { content: fa-content($fa-var-sliders-h); } +.#{$fa-css-prefix}-slideshare:before { content: fa-content($fa-var-slideshare); } +.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); } +.#{$fa-css-prefix}-snapchat:before { content: fa-content($fa-var-snapchat); } +.#{$fa-css-prefix}-snapchat-ghost:before { content: fa-content($fa-var-snapchat-ghost); } +.#{$fa-css-prefix}-snapchat-square:before { content: fa-content($fa-var-snapchat-square); } +.#{$fa-css-prefix}-snowflake:before { content: fa-content($fa-var-snowflake); } +.#{$fa-css-prefix}-sort:before { content: fa-content($fa-var-sort); } +.#{$fa-css-prefix}-sort-alpha-down:before { content: fa-content($fa-var-sort-alpha-down); } +.#{$fa-css-prefix}-sort-alpha-up:before { content: fa-content($fa-var-sort-alpha-up); } +.#{$fa-css-prefix}-sort-amount-down:before { content: fa-content($fa-var-sort-amount-down); } +.#{$fa-css-prefix}-sort-amount-up:before { content: fa-content($fa-var-sort-amount-up); } +.#{$fa-css-prefix}-sort-down:before { content: fa-content($fa-var-sort-down); } +.#{$fa-css-prefix}-sort-numeric-down:before { content: fa-content($fa-var-sort-numeric-down); } +.#{$fa-css-prefix}-sort-numeric-up:before { content: fa-content($fa-var-sort-numeric-up); } +.#{$fa-css-prefix}-sort-up:before { content: fa-content($fa-var-sort-up); } +.#{$fa-css-prefix}-soundcloud:before { content: fa-content($fa-var-soundcloud); } +.#{$fa-css-prefix}-space-shuttle:before { content: fa-content($fa-var-space-shuttle); } +.#{$fa-css-prefix}-speakap:before { content: fa-content($fa-var-speakap); } +.#{$fa-css-prefix}-spinner:before { content: fa-content($fa-var-spinner); } +.#{$fa-css-prefix}-spotify:before { content: fa-content($fa-var-spotify); } +.#{$fa-css-prefix}-square:before { content: fa-content($fa-var-square); } +.#{$fa-css-prefix}-stack-exchange:before { content: fa-content($fa-var-stack-exchange); } +.#{$fa-css-prefix}-stack-overflow:before { content: fa-content($fa-var-stack-overflow); } +.#{$fa-css-prefix}-star:before { content: fa-content($fa-var-star); } +.#{$fa-css-prefix}-star-half:before { content: fa-content($fa-var-star-half); } +.#{$fa-css-prefix}-staylinked:before { content: fa-content($fa-var-staylinked); } +.#{$fa-css-prefix}-steam:before { content: fa-content($fa-var-steam); } +.#{$fa-css-prefix}-steam-square:before { content: fa-content($fa-var-steam-square); } +.#{$fa-css-prefix}-steam-symbol:before { content: fa-content($fa-var-steam-symbol); } +.#{$fa-css-prefix}-step-backward:before { content: fa-content($fa-var-step-backward); } +.#{$fa-css-prefix}-step-forward:before { content: fa-content($fa-var-step-forward); } +.#{$fa-css-prefix}-stethoscope:before { content: fa-content($fa-var-stethoscope); } +.#{$fa-css-prefix}-sticker-mule:before { content: fa-content($fa-var-sticker-mule); } +.#{$fa-css-prefix}-sticky-note:before { content: fa-content($fa-var-sticky-note); } +.#{$fa-css-prefix}-stop:before { content: fa-content($fa-var-stop); } +.#{$fa-css-prefix}-stop-circle:before { content: fa-content($fa-var-stop-circle); } +.#{$fa-css-prefix}-strava:before { content: fa-content($fa-var-strava); } +.#{$fa-css-prefix}-street-view:before { content: fa-content($fa-var-street-view); } +.#{$fa-css-prefix}-strikethrough:before { content: fa-content($fa-var-strikethrough); } +.#{$fa-css-prefix}-stripe:before { content: fa-content($fa-var-stripe); } +.#{$fa-css-prefix}-stripe-s:before { content: fa-content($fa-var-stripe-s); } +.#{$fa-css-prefix}-studiovinari:before { content: fa-content($fa-var-studiovinari); } +.#{$fa-css-prefix}-stumbleupon:before { content: fa-content($fa-var-stumbleupon); } +.#{$fa-css-prefix}-stumbleupon-circle:before { content: fa-content($fa-var-stumbleupon-circle); } +.#{$fa-css-prefix}-subscript:before { content: fa-content($fa-var-subscript); } +.#{$fa-css-prefix}-subway:before { content: fa-content($fa-var-subway); } +.#{$fa-css-prefix}-suitcase:before { content: fa-content($fa-var-suitcase); } +.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); } +.#{$fa-css-prefix}-superpowers:before { content: fa-content($fa-var-superpowers); } +.#{$fa-css-prefix}-superscript:before { content: fa-content($fa-var-superscript); } +.#{$fa-css-prefix}-supple:before { content: fa-content($fa-var-supple); } +.#{$fa-css-prefix}-sync:before { content: fa-content($fa-var-sync); } +.#{$fa-css-prefix}-sync-alt:before { content: fa-content($fa-var-sync-alt); } +.#{$fa-css-prefix}-table:before { content: fa-content($fa-var-table); } +.#{$fa-css-prefix}-tablet:before { content: fa-content($fa-var-tablet); } +.#{$fa-css-prefix}-tablet-alt:before { content: fa-content($fa-var-tablet-alt); } +.#{$fa-css-prefix}-tachometer-alt:before { content: fa-content($fa-var-tachometer-alt); } +.#{$fa-css-prefix}-tag:before { content: fa-content($fa-var-tag); } +.#{$fa-css-prefix}-tags:before { content: fa-content($fa-var-tags); } +.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); } +.#{$fa-css-prefix}-taxi:before { content: fa-content($fa-var-taxi); } +.#{$fa-css-prefix}-telegram:before { content: fa-content($fa-var-telegram); } +.#{$fa-css-prefix}-telegram-plane:before { content: fa-content($fa-var-telegram-plane); } +.#{$fa-css-prefix}-tencent-weibo:before { content: fa-content($fa-var-tencent-weibo); } +.#{$fa-css-prefix}-terminal:before { content: fa-content($fa-var-terminal); } +.#{$fa-css-prefix}-text-height:before { content: fa-content($fa-var-text-height); } +.#{$fa-css-prefix}-text-width:before { content: fa-content($fa-var-text-width); } +.#{$fa-css-prefix}-th:before { content: fa-content($fa-var-th); } +.#{$fa-css-prefix}-th-large:before { content: fa-content($fa-var-th-large); } +.#{$fa-css-prefix}-th-list:before { content: fa-content($fa-var-th-list); } +.#{$fa-css-prefix}-themeisle:before { content: fa-content($fa-var-themeisle); } +.#{$fa-css-prefix}-thermometer-empty:before { content: fa-content($fa-var-thermometer-empty); } +.#{$fa-css-prefix}-thermometer-full:before { content: fa-content($fa-var-thermometer-full); } +.#{$fa-css-prefix}-thermometer-half:before { content: fa-content($fa-var-thermometer-half); } +.#{$fa-css-prefix}-thermometer-quarter:before { content: fa-content($fa-var-thermometer-quarter); } +.#{$fa-css-prefix}-thermometer-three-quarters:before { content: fa-content($fa-var-thermometer-three-quarters); } +.#{$fa-css-prefix}-thumbs-down:before { content: fa-content($fa-var-thumbs-down); } +.#{$fa-css-prefix}-thumbs-up:before { content: fa-content($fa-var-thumbs-up); } +.#{$fa-css-prefix}-thumbtack:before { content: fa-content($fa-var-thumbtack); } +.#{$fa-css-prefix}-ticket-alt:before { content: fa-content($fa-var-ticket-alt); } +.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); } +.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); } +.#{$fa-css-prefix}-tint:before { content: fa-content($fa-var-tint); } +.#{$fa-css-prefix}-toggle-off:before { content: fa-content($fa-var-toggle-off); } +.#{$fa-css-prefix}-toggle-on:before { content: fa-content($fa-var-toggle-on); } +.#{$fa-css-prefix}-trademark:before { content: fa-content($fa-var-trademark); } +.#{$fa-css-prefix}-train:before { content: fa-content($fa-var-train); } +.#{$fa-css-prefix}-transgender:before { content: fa-content($fa-var-transgender); } +.#{$fa-css-prefix}-transgender-alt:before { content: fa-content($fa-var-transgender-alt); } +.#{$fa-css-prefix}-trash:before { content: fa-content($fa-var-trash); } +.#{$fa-css-prefix}-trash-alt:before { content: fa-content($fa-var-trash-alt); } +.#{$fa-css-prefix}-tree:before { content: fa-content($fa-var-tree); } +.#{$fa-css-prefix}-trello:before { content: fa-content($fa-var-trello); } +.#{$fa-css-prefix}-tripadvisor:before { content: fa-content($fa-var-tripadvisor); } +.#{$fa-css-prefix}-trophy:before { content: fa-content($fa-var-trophy); } +.#{$fa-css-prefix}-truck:before { content: fa-content($fa-var-truck); } +.#{$fa-css-prefix}-tty:before { content: fa-content($fa-var-tty); } +.#{$fa-css-prefix}-tumblr:before { content: fa-content($fa-var-tumblr); } +.#{$fa-css-prefix}-tumblr-square:before { content: fa-content($fa-var-tumblr-square); } +.#{$fa-css-prefix}-tv:before { content: fa-content($fa-var-tv); } +.#{$fa-css-prefix}-twitch:before { content: fa-content($fa-var-twitch); } +.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); } +.#{$fa-css-prefix}-twitter-square:before { content: fa-content($fa-var-twitter-square); } +.#{$fa-css-prefix}-typo3:before { content: fa-content($fa-var-typo3); } +.#{$fa-css-prefix}-uber:before { content: fa-content($fa-var-uber); } +.#{$fa-css-prefix}-uikit:before { content: fa-content($fa-var-uikit); } +.#{$fa-css-prefix}-umbrella:before { content: fa-content($fa-var-umbrella); } +.#{$fa-css-prefix}-underline:before { content: fa-content($fa-var-underline); } +.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); } +.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); } +.#{$fa-css-prefix}-uniregistry:before { content: fa-content($fa-var-uniregistry); } +.#{$fa-css-prefix}-universal-access:before { content: fa-content($fa-var-universal-access); } +.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); } +.#{$fa-css-prefix}-unlink:before { content: fa-content($fa-var-unlink); } +.#{$fa-css-prefix}-unlock:before { content: fa-content($fa-var-unlock); } +.#{$fa-css-prefix}-unlock-alt:before { content: fa-content($fa-var-unlock-alt); } +.#{$fa-css-prefix}-untappd:before { content: fa-content($fa-var-untappd); } +.#{$fa-css-prefix}-upload:before { content: fa-content($fa-var-upload); } +.#{$fa-css-prefix}-usb:before { content: fa-content($fa-var-usb); } +.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); } +.#{$fa-css-prefix}-user-circle:before { content: fa-content($fa-var-user-circle); } +.#{$fa-css-prefix}-user-md:before { content: fa-content($fa-var-user-md); } +.#{$fa-css-prefix}-user-plus:before { content: fa-content($fa-var-user-plus); } +.#{$fa-css-prefix}-user-secret:before { content: fa-content($fa-var-user-secret); } +.#{$fa-css-prefix}-user-times:before { content: fa-content($fa-var-user-times); } +.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); } +.#{$fa-css-prefix}-ussunnah:before { content: fa-content($fa-var-ussunnah); } +.#{$fa-css-prefix}-utensil-spoon:before { content: fa-content($fa-var-utensil-spoon); } +.#{$fa-css-prefix}-utensils:before { content: fa-content($fa-var-utensils); } +.#{$fa-css-prefix}-vaadin:before { content: fa-content($fa-var-vaadin); } +.#{$fa-css-prefix}-venus:before { content: fa-content($fa-var-venus); } +.#{$fa-css-prefix}-venus-double:before { content: fa-content($fa-var-venus-double); } +.#{$fa-css-prefix}-venus-mars:before { content: fa-content($fa-var-venus-mars); } +.#{$fa-css-prefix}-viacoin:before { content: fa-content($fa-var-viacoin); } +.#{$fa-css-prefix}-viadeo:before { content: fa-content($fa-var-viadeo); } +.#{$fa-css-prefix}-viadeo-square:before { content: fa-content($fa-var-viadeo-square); } +.#{$fa-css-prefix}-viber:before { content: fa-content($fa-var-viber); } +.#{$fa-css-prefix}-video:before { content: fa-content($fa-var-video); } +.#{$fa-css-prefix}-vimeo:before { content: fa-content($fa-var-vimeo); } +.#{$fa-css-prefix}-vimeo-square:before { content: fa-content($fa-var-vimeo-square); } +.#{$fa-css-prefix}-vimeo-v:before { content: fa-content($fa-var-vimeo-v); } +.#{$fa-css-prefix}-vine:before { content: fa-content($fa-var-vine); } +.#{$fa-css-prefix}-vk:before { content: fa-content($fa-var-vk); } +.#{$fa-css-prefix}-vnv:before { content: fa-content($fa-var-vnv); } +.#{$fa-css-prefix}-volume-down:before { content: fa-content($fa-var-volume-down); } +.#{$fa-css-prefix}-volume-off:before { content: fa-content($fa-var-volume-off); } +.#{$fa-css-prefix}-volume-up:before { content: fa-content($fa-var-volume-up); } +.#{$fa-css-prefix}-vuejs:before { content: fa-content($fa-var-vuejs); } +.#{$fa-css-prefix}-weibo:before { content: fa-content($fa-var-weibo); } +.#{$fa-css-prefix}-weixin:before { content: fa-content($fa-var-weixin); } +.#{$fa-css-prefix}-whatsapp:before { content: fa-content($fa-var-whatsapp); } +.#{$fa-css-prefix}-whatsapp-square:before { content: fa-content($fa-var-whatsapp-square); } +.#{$fa-css-prefix}-wheelchair:before { content: fa-content($fa-var-wheelchair); } +.#{$fa-css-prefix}-whmcs:before { content: fa-content($fa-var-whmcs); } +.#{$fa-css-prefix}-wifi:before { content: fa-content($fa-var-wifi); } +.#{$fa-css-prefix}-wikipedia-w:before { content: fa-content($fa-var-wikipedia-w); } +.#{$fa-css-prefix}-window-close:before { content: fa-content($fa-var-window-close); } +.#{$fa-css-prefix}-window-maximize:before { content: fa-content($fa-var-window-maximize); } +.#{$fa-css-prefix}-window-minimize:before { content: fa-content($fa-var-window-minimize); } +.#{$fa-css-prefix}-window-restore:before { content: fa-content($fa-var-window-restore); } +.#{$fa-css-prefix}-windows:before { content: fa-content($fa-var-windows); } +.#{$fa-css-prefix}-won-sign:before { content: fa-content($fa-var-won-sign); } +.#{$fa-css-prefix}-wordpress:before { content: fa-content($fa-var-wordpress); } +.#{$fa-css-prefix}-wordpress-simple:before { content: fa-content($fa-var-wordpress-simple); } +.#{$fa-css-prefix}-wpbeginner:before { content: fa-content($fa-var-wpbeginner); } +.#{$fa-css-prefix}-wpexplorer:before { content: fa-content($fa-var-wpexplorer); } +.#{$fa-css-prefix}-wpforms:before { content: fa-content($fa-var-wpforms); } +.#{$fa-css-prefix}-wrench:before { content: fa-content($fa-var-wrench); } +.#{$fa-css-prefix}-xbox:before { content: fa-content($fa-var-xbox); } +.#{$fa-css-prefix}-xing:before { content: fa-content($fa-var-xing); } +.#{$fa-css-prefix}-xing-square:before { content: fa-content($fa-var-xing-square); } +.#{$fa-css-prefix}-y-combinator:before { content: fa-content($fa-var-y-combinator); } +.#{$fa-css-prefix}-yahoo:before { content: fa-content($fa-var-yahoo); } +.#{$fa-css-prefix}-yandex:before { content: fa-content($fa-var-yandex); } +.#{$fa-css-prefix}-yandex-international:before { content: fa-content($fa-var-yandex-international); } +.#{$fa-css-prefix}-yelp:before { content: fa-content($fa-var-yelp); } +.#{$fa-css-prefix}-yen-sign:before { content: fa-content($fa-var-yen-sign); } +.#{$fa-css-prefix}-yoast:before { content: fa-content($fa-var-yoast); } +.#{$fa-css-prefix}-youtube:before { content: fa-content($fa-var-youtube); } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_larger.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_larger.scss new file mode 100644 index 000000000..27c2ad5fc --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_larger.scss @@ -0,0 +1,23 @@ +// Icon Sizes +// ------------------------- + +// makes the font 33% larger relative to the icon container +.#{$fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -.0667em; +} + +.#{$fa-css-prefix}-xs { + font-size: .75em; +} + +.#{$fa-css-prefix}-sm { + font-size: .875em; +} + +@for $i from 1 through 10 { + .#{$fa-css-prefix}-#{$i}x { + font-size: $i * 1em; + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_list.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_list.scss new file mode 100644 index 000000000..8ebf33333 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_list.scss @@ -0,0 +1,18 @@ +// List Icons +// ------------------------- + +.#{$fa-css-prefix}-ul { + list-style-type: none; + margin-left: $fa-li-width * 5/4; + padding-left: 0; + + > li { position: relative; } +} + +.#{$fa-css-prefix}-li { + left: -$fa-li-width; + position: absolute; + text-align: center; + width: $fa-li-width; + line-height: inherit; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_mixins.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_mixins.scss new file mode 100644 index 000000000..06e549b69 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_mixins.scss @@ -0,0 +1,57 @@ +// Mixins +// -------------------------- + +@mixin fa-icon { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + vertical-align: -15%; +} + +@mixin fa-icon-rotate($degrees, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; + transform: rotate($degrees); +} + +@mixin fa-icon-flip($horiz, $vert, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; + transform: scale($horiz, $vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +@mixin sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +@mixin sr-only-focusable { + &:active, + &:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_rotated-flipped.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_rotated-flipped.scss new file mode 100644 index 000000000..995bc4cc7 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_rotated-flipped.scss @@ -0,0 +1,23 @@ +// Rotated & Flipped Icons +// ------------------------- + +.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } +.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } +.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } + +.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } +.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } +.#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root { + .#{$fa-css-prefix}-rotate-90, + .#{$fa-css-prefix}-rotate-180, + .#{$fa-css-prefix}-rotate-270, + .#{$fa-css-prefix}-flip-horizontal, + .#{$fa-css-prefix}-flip-vertical { + filter: none; + } +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_screen-reader.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_screen-reader.scss new file mode 100644 index 000000000..5d0ab262f --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_screen-reader.scss @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { @include sr-only; } +.sr-only-focusable { @include sr-only-focusable; } diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_stacked.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_stacked.scss new file mode 100644 index 000000000..6c09d84cd --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_stacked.scss @@ -0,0 +1,31 @@ +// Stacked Icons +// ------------------------- + +.#{$fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2em; +} + +.#{$fa-css-prefix}-stack-1x, +.#{$fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; +} + +.#{$fa-css-prefix}-stack-1x { + line-height: inherit; +} + +.#{$fa-css-prefix}-stack-2x { + font-size: 2em; +} + +.#{$fa-css-prefix}-inverse { + color: $fa-inverse; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_variables.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_variables.scss new file mode 100644 index 000000000..99d2437d1 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/_variables.scss @@ -0,0 +1,800 @@ +// Variables +// -------------------------- + +$fa-font-path: "../webfonts" !default; +$fa-font-size-base: 16px !default; +$fa-css-prefix: fa !default; +$fa-version: "5.0.0" !default; +$fa-border-color: #eee !default; +$fa-inverse: #fff !default; +$fa-li-width: 2em !default; + +// Convenience function used to set content property +@function fa-content($fa-var) { + @return unquote("\"#{ $fa-var }\""); +} + +$fa-var-500px: \f26e; +$fa-var-accessible-icon: \f368; +$fa-var-accusoft: \f369; +$fa-var-address-book: \f2b9; +$fa-var-address-card: \f2bb; +$fa-var-adjust: \f042; +$fa-var-adn: \f170; +$fa-var-adversal: \f36a; +$fa-var-affiliatetheme: \f36b; +$fa-var-algolia: \f36c; +$fa-var-align-center: \f037; +$fa-var-align-justify: \f039; +$fa-var-align-left: \f036; +$fa-var-align-right: \f038; +$fa-var-amazon: \f270; +$fa-var-ambulance: \f0f9; +$fa-var-american-sign-language-interpreting: \f2a3; +$fa-var-amilia: \f36d; +$fa-var-anchor: \f13d; +$fa-var-android: \f17b; +$fa-var-angellist: \f209; +$fa-var-angle-double-down: \f103; +$fa-var-angle-double-left: \f100; +$fa-var-angle-double-right: \f101; +$fa-var-angle-double-up: \f102; +$fa-var-angle-down: \f107; +$fa-var-angle-left: \f104; +$fa-var-angle-right: \f105; +$fa-var-angle-up: \f106; +$fa-var-angrycreative: \f36e; +$fa-var-angular: \f420; +$fa-var-app-store: \f36f; +$fa-var-app-store-ios: \f370; +$fa-var-apper: \f371; +$fa-var-apple: \f179; +$fa-var-apple-pay: \f415; +$fa-var-archive: \f187; +$fa-var-arrow-alt-circle-down: \f358; +$fa-var-arrow-alt-circle-left: \f359; +$fa-var-arrow-alt-circle-right: \f35a; +$fa-var-arrow-alt-circle-up: \f35b; +$fa-var-arrow-circle-down: \f0ab; +$fa-var-arrow-circle-left: \f0a8; +$fa-var-arrow-circle-right: \f0a9; +$fa-var-arrow-circle-up: \f0aa; +$fa-var-arrow-down: \f063; +$fa-var-arrow-left: \f060; +$fa-var-arrow-right: \f061; +$fa-var-arrow-up: \f062; +$fa-var-arrows-alt: \f0b2; +$fa-var-arrows-alt-h: \f337; +$fa-var-arrows-alt-v: \f338; +$fa-var-assistive-listening-systems: \f2a2; +$fa-var-asterisk: \f069; +$fa-var-asymmetrik: \f372; +$fa-var-at: \f1fa; +$fa-var-audible: \f373; +$fa-var-audio-description: \f29e; +$fa-var-autoprefixer: \f41c; +$fa-var-avianex: \f374; +$fa-var-aviato: \f421; +$fa-var-aws: \f375; +$fa-var-backward: \f04a; +$fa-var-balance-scale: \f24e; +$fa-var-ban: \f05e; +$fa-var-bandcamp: \f2d5; +$fa-var-barcode: \f02a; +$fa-var-bars: \f0c9; +$fa-var-bath: \f2cd; +$fa-var-battery-empty: \f244; +$fa-var-battery-full: \f240; +$fa-var-battery-half: \f242; +$fa-var-battery-quarter: \f243; +$fa-var-battery-three-quarters: \f241; +$fa-var-bed: \f236; +$fa-var-beer: \f0fc; +$fa-var-behance: \f1b4; +$fa-var-behance-square: \f1b5; +$fa-var-bell: \f0f3; +$fa-var-bell-slash: \f1f6; +$fa-var-bicycle: \f206; +$fa-var-bimobject: \f378; +$fa-var-binoculars: \f1e5; +$fa-var-birthday-cake: \f1fd; +$fa-var-bitbucket: \f171; +$fa-var-bitcoin: \f379; +$fa-var-bity: \f37a; +$fa-var-black-tie: \f27e; +$fa-var-blackberry: \f37b; +$fa-var-blind: \f29d; +$fa-var-blogger: \f37c; +$fa-var-blogger-b: \f37d; +$fa-var-bluetooth: \f293; +$fa-var-bluetooth-b: \f294; +$fa-var-bold: \f032; +$fa-var-bolt: \f0e7; +$fa-var-bomb: \f1e2; +$fa-var-book: \f02d; +$fa-var-bookmark: \f02e; +$fa-var-braille: \f2a1; +$fa-var-briefcase: \f0b1; +$fa-var-btc: \f15a; +$fa-var-bug: \f188; +$fa-var-building: \f1ad; +$fa-var-bullhorn: \f0a1; +$fa-var-bullseye: \f140; +$fa-var-buromobelexperte: \f37f; +$fa-var-bus: \f207; +$fa-var-buysellads: \f20d; +$fa-var-calculator: \f1ec; +$fa-var-calendar: \f133; +$fa-var-calendar-alt: \f073; +$fa-var-calendar-check: \f274; +$fa-var-calendar-minus: \f272; +$fa-var-calendar-plus: \f271; +$fa-var-calendar-times: \f273; +$fa-var-camera: \f030; +$fa-var-camera-retro: \f083; +$fa-var-car: \f1b9; +$fa-var-caret-down: \f0d7; +$fa-var-caret-left: \f0d9; +$fa-var-caret-right: \f0da; +$fa-var-caret-square-down: \f150; +$fa-var-caret-square-left: \f191; +$fa-var-caret-square-right: \f152; +$fa-var-caret-square-up: \f151; +$fa-var-caret-up: \f0d8; +$fa-var-cart-arrow-down: \f218; +$fa-var-cart-plus: \f217; +$fa-var-cc-amex: \f1f3; +$fa-var-cc-apple-pay: \f416; +$fa-var-cc-diners-club: \f24c; +$fa-var-cc-discover: \f1f2; +$fa-var-cc-jcb: \f24b; +$fa-var-cc-mastercard: \f1f1; +$fa-var-cc-paypal: \f1f4; +$fa-var-cc-stripe: \f1f5; +$fa-var-cc-visa: \f1f0; +$fa-var-centercode: \f380; +$fa-var-certificate: \f0a3; +$fa-var-chart-area: \f1fe; +$fa-var-chart-bar: \f080; +$fa-var-chart-line: \f201; +$fa-var-chart-pie: \f200; +$fa-var-check: \f00c; +$fa-var-check-circle: \f058; +$fa-var-check-square: \f14a; +$fa-var-chevron-circle-down: \f13a; +$fa-var-chevron-circle-left: \f137; +$fa-var-chevron-circle-right: \f138; +$fa-var-chevron-circle-up: \f139; +$fa-var-chevron-down: \f078; +$fa-var-chevron-left: \f053; +$fa-var-chevron-right: \f054; +$fa-var-chevron-up: \f077; +$fa-var-child: \f1ae; +$fa-var-chrome: \f268; +$fa-var-circle: \f111; +$fa-var-circle-notch: \f1ce; +$fa-var-clipboard: \f328; +$fa-var-clock: \f017; +$fa-var-clone: \f24d; +$fa-var-closed-captioning: \f20a; +$fa-var-cloud: \f0c2; +$fa-var-cloud-download-alt: \f381; +$fa-var-cloud-upload-alt: \f382; +$fa-var-cloudscale: \f383; +$fa-var-cloudsmith: \f384; +$fa-var-cloudversify: \f385; +$fa-var-code: \f121; +$fa-var-code-branch: \f126; +$fa-var-codepen: \f1cb; +$fa-var-codiepie: \f284; +$fa-var-coffee: \f0f4; +$fa-var-cog: \f013; +$fa-var-cogs: \f085; +$fa-var-columns: \f0db; +$fa-var-comment: \f075; +$fa-var-comment-alt: \f27a; +$fa-var-comments: \f086; +$fa-var-compass: \f14e; +$fa-var-compress: \f066; +$fa-var-connectdevelop: \f20e; +$fa-var-contao: \f26d; +$fa-var-copy: \f0c5; +$fa-var-copyright: \f1f9; +$fa-var-cpanel: \f388; +$fa-var-creative-commons: \f25e; +$fa-var-credit-card: \f09d; +$fa-var-crop: \f125; +$fa-var-crosshairs: \f05b; +$fa-var-css3: \f13c; +$fa-var-css3-alt: \f38b; +$fa-var-cube: \f1b2; +$fa-var-cubes: \f1b3; +$fa-var-cut: \f0c4; +$fa-var-cuttlefish: \f38c; +$fa-var-d-and-d: \f38d; +$fa-var-dashcube: \f210; +$fa-var-database: \f1c0; +$fa-var-deaf: \f2a4; +$fa-var-delicious: \f1a5; +$fa-var-deploydog: \f38e; +$fa-var-deskpro: \f38f; +$fa-var-desktop: \f108; +$fa-var-deviantart: \f1bd; +$fa-var-digg: \f1a6; +$fa-var-digital-ocean: \f391; +$fa-var-discord: \f392; +$fa-var-discourse: \f393; +$fa-var-dochub: \f394; +$fa-var-docker: \f395; +$fa-var-dollar-sign: \f155; +$fa-var-dot-circle: \f192; +$fa-var-download: \f019; +$fa-var-draft2digital: \f396; +$fa-var-dribbble: \f17d; +$fa-var-dribbble-square: \f397; +$fa-var-dropbox: \f16b; +$fa-var-drupal: \f1a9; +$fa-var-dyalog: \f399; +$fa-var-earlybirds: \f39a; +$fa-var-edge: \f282; +$fa-var-edit: \f044; +$fa-var-eject: \f052; +$fa-var-ellipsis-h: \f141; +$fa-var-ellipsis-v: \f142; +$fa-var-ember: \f423; +$fa-var-empire: \f1d1; +$fa-var-envelope: \f0e0; +$fa-var-envelope-open: \f2b6; +$fa-var-envelope-square: \f199; +$fa-var-envira: \f299; +$fa-var-eraser: \f12d; +$fa-var-erlang: \f39d; +$fa-var-etsy: \f2d7; +$fa-var-euro-sign: \f153; +$fa-var-exchange-alt: \f362; +$fa-var-exclamation: \f12a; +$fa-var-exclamation-circle: \f06a; +$fa-var-exclamation-triangle: \f071; +$fa-var-expand: \f065; +$fa-var-expand-arrows-alt: \f31e; +$fa-var-expeditedssl: \f23e; +$fa-var-external-link-alt: \f35d; +$fa-var-external-link-square-alt: \f360; +$fa-var-eye: \f06e; +$fa-var-eye-dropper: \f1fb; +$fa-var-eye-slash: \f070; +$fa-var-facebook: \f09a; +$fa-var-facebook-f: \f39e; +$fa-var-facebook-messenger: \f39f; +$fa-var-facebook-square: \f082; +$fa-var-fast-backward: \f049; +$fa-var-fast-forward: \f050; +$fa-var-fax: \f1ac; +$fa-var-female: \f182; +$fa-var-fighter-jet: \f0fb; +$fa-var-file: \f15b; +$fa-var-file-alt: \f15c; +$fa-var-file-archive: \f1c6; +$fa-var-file-audio: \f1c7; +$fa-var-file-code: \f1c9; +$fa-var-file-excel: \f1c3; +$fa-var-file-image: \f1c5; +$fa-var-file-pdf: \f1c1; +$fa-var-file-powerpoint: \f1c4; +$fa-var-file-video: \f1c8; +$fa-var-file-word: \f1c2; +$fa-var-film: \f008; +$fa-var-filter: \f0b0; +$fa-var-fire: \f06d; +$fa-var-fire-extinguisher: \f134; +$fa-var-firefox: \f269; +$fa-var-first-order: \f2b0; +$fa-var-firstdraft: \f3a1; +$fa-var-flag: \f024; +$fa-var-flag-checkered: \f11e; +$fa-var-flask: \f0c3; +$fa-var-flickr: \f16e; +$fa-var-fly: \f417; +$fa-var-folder: \f07b; +$fa-var-folder-open: \f07c; +$fa-var-font: \f031; +$fa-var-font-awesome: \f2b4; +$fa-var-font-awesome-alt: \f35c; +$fa-var-font-awesome-flag: \f425; +$fa-var-fonticons: \f280; +$fa-var-fonticons-fi: \f3a2; +$fa-var-fort-awesome: \f286; +$fa-var-fort-awesome-alt: \f3a3; +$fa-var-forumbee: \f211; +$fa-var-forward: \f04e; +$fa-var-foursquare: \f180; +$fa-var-free-code-camp: \f2c5; +$fa-var-freebsd: \f3a4; +$fa-var-frown: \f119; +$fa-var-futbol: \f1e3; +$fa-var-gamepad: \f11b; +$fa-var-gavel: \f0e3; +$fa-var-gem: \f3a5; +$fa-var-genderless: \f22d; +$fa-var-get-pocket: \f265; +$fa-var-gg: \f260; +$fa-var-gg-circle: \f261; +$fa-var-gift: \f06b; +$fa-var-git: \f1d3; +$fa-var-git-square: \f1d2; +$fa-var-github: \f09b; +$fa-var-github-alt: \f113; +$fa-var-github-square: \f092; +$fa-var-gitkraken: \f3a6; +$fa-var-gitlab: \f296; +$fa-var-gitter: \f426; +$fa-var-glass-martini: \f000; +$fa-var-glide: \f2a5; +$fa-var-glide-g: \f2a6; +$fa-var-globe: \f0ac; +$fa-var-gofore: \f3a7; +$fa-var-goodreads: \f3a8; +$fa-var-goodreads-g: \f3a9; +$fa-var-google: \f1a0; +$fa-var-google-drive: \f3aa; +$fa-var-google-play: \f3ab; +$fa-var-google-plus: \f2b3; +$fa-var-google-plus-g: \f0d5; +$fa-var-google-plus-square: \f0d4; +$fa-var-google-wallet: \f1ee; +$fa-var-graduation-cap: \f19d; +$fa-var-gratipay: \f184; +$fa-var-grav: \f2d6; +$fa-var-gripfire: \f3ac; +$fa-var-grunt: \f3ad; +$fa-var-gulp: \f3ae; +$fa-var-h-square: \f0fd; +$fa-var-hacker-news: \f1d4; +$fa-var-hacker-news-square: \f3af; +$fa-var-hand-lizard: \f258; +$fa-var-hand-paper: \f256; +$fa-var-hand-peace: \f25b; +$fa-var-hand-point-down: \f0a7; +$fa-var-hand-point-left: \f0a5; +$fa-var-hand-point-right: \f0a4; +$fa-var-hand-point-up: \f0a6; +$fa-var-hand-pointer: \f25a; +$fa-var-hand-rock: \f255; +$fa-var-hand-scissors: \f257; +$fa-var-hand-spock: \f259; +$fa-var-handshake: \f2b5; +$fa-var-hashtag: \f292; +$fa-var-hdd: \f0a0; +$fa-var-heading: \f1dc; +$fa-var-headphones: \f025; +$fa-var-heart: \f004; +$fa-var-heartbeat: \f21e; +$fa-var-hire-a-helper: \f3b0; +$fa-var-history: \f1da; +$fa-var-home: \f015; +$fa-var-hooli: \f427; +$fa-var-hospital: \f0f8; +$fa-var-hotjar: \f3b1; +$fa-var-hourglass: \f254; +$fa-var-hourglass-end: \f253; +$fa-var-hourglass-half: \f252; +$fa-var-hourglass-start: \f251; +$fa-var-houzz: \f27c; +$fa-var-html5: \f13b; +$fa-var-hubspot: \f3b2; +$fa-var-i-cursor: \f246; +$fa-var-id-badge: \f2c1; +$fa-var-id-card: \f2c2; +$fa-var-image: \f03e; +$fa-var-images: \f302; +$fa-var-imdb: \f2d8; +$fa-var-inbox: \f01c; +$fa-var-indent: \f03c; +$fa-var-industry: \f275; +$fa-var-info: \f129; +$fa-var-info-circle: \f05a; +$fa-var-instagram: \f16d; +$fa-var-internet-explorer: \f26b; +$fa-var-ioxhost: \f208; +$fa-var-italic: \f033; +$fa-var-itunes: \f3b4; +$fa-var-itunes-note: \f3b5; +$fa-var-jenkins: \f3b6; +$fa-var-joget: \f3b7; +$fa-var-joomla: \f1aa; +$fa-var-js: \f3b8; +$fa-var-js-square: \f3b9; +$fa-var-jsfiddle: \f1cc; +$fa-var-key: \f084; +$fa-var-keyboard: \f11c; +$fa-var-keycdn: \f3ba; +$fa-var-kickstarter: \f3bb; +$fa-var-kickstarter-k: \f3bc; +$fa-var-language: \f1ab; +$fa-var-laptop: \f109; +$fa-var-laravel: \f3bd; +$fa-var-lastfm: \f202; +$fa-var-lastfm-square: \f203; +$fa-var-leaf: \f06c; +$fa-var-leanpub: \f212; +$fa-var-lemon: \f094; +$fa-var-less: \f41d; +$fa-var-level-down-alt: \f3be; +$fa-var-level-up-alt: \f3bf; +$fa-var-life-ring: \f1cd; +$fa-var-lightbulb: \f0eb; +$fa-var-line: \f3c0; +$fa-var-link: \f0c1; +$fa-var-linkedin: \f08c; +$fa-var-linkedin-in: \f0e1; +$fa-var-linode: \f2b8; +$fa-var-linux: \f17c; +$fa-var-lira-sign: \f195; +$fa-var-list: \f03a; +$fa-var-list-alt: \f022; +$fa-var-list-ol: \f0cb; +$fa-var-list-ul: \f0ca; +$fa-var-location-arrow: \f124; +$fa-var-lock: \f023; +$fa-var-lock-open: \f3c1; +$fa-var-long-arrow-alt-down: \f309; +$fa-var-long-arrow-alt-left: \f30a; +$fa-var-long-arrow-alt-right: \f30b; +$fa-var-long-arrow-alt-up: \f30c; +$fa-var-low-vision: \f2a8; +$fa-var-lyft: \f3c3; +$fa-var-magento: \f3c4; +$fa-var-magic: \f0d0; +$fa-var-magnet: \f076; +$fa-var-male: \f183; +$fa-var-map: \f279; +$fa-var-map-marker: \f041; +$fa-var-map-marker-alt: \f3c5; +$fa-var-map-pin: \f276; +$fa-var-map-signs: \f277; +$fa-var-mars: \f222; +$fa-var-mars-double: \f227; +$fa-var-mars-stroke: \f229; +$fa-var-mars-stroke-h: \f22b; +$fa-var-mars-stroke-v: \f22a; +$fa-var-maxcdn: \f136; +$fa-var-medapps: \f3c6; +$fa-var-medium: \f23a; +$fa-var-medium-m: \f3c7; +$fa-var-medkit: \f0fa; +$fa-var-medrt: \f3c8; +$fa-var-meetup: \f2e0; +$fa-var-meh: \f11a; +$fa-var-mercury: \f223; +$fa-var-microchip: \f2db; +$fa-var-microphone: \f130; +$fa-var-microphone-slash: \f131; +$fa-var-microsoft: \f3ca; +$fa-var-minus: \f068; +$fa-var-minus-circle: \f056; +$fa-var-minus-square: \f146; +$fa-var-mix: \f3cb; +$fa-var-mixcloud: \f289; +$fa-var-mizuni: \f3cc; +$fa-var-mobile: \f10b; +$fa-var-mobile-alt: \f3cd; +$fa-var-modx: \f285; +$fa-var-monero: \f3d0; +$fa-var-money-bill-alt: \f3d1; +$fa-var-moon: \f186; +$fa-var-motorcycle: \f21c; +$fa-var-mouse-pointer: \f245; +$fa-var-music: \f001; +$fa-var-napster: \f3d2; +$fa-var-neuter: \f22c; +$fa-var-newspaper: \f1ea; +$fa-var-nintendo-switch: \f418; +$fa-var-node: \f419; +$fa-var-node-js: \f3d3; +$fa-var-npm: \f3d4; +$fa-var-ns8: \f3d5; +$fa-var-nutritionix: \f3d6; +$fa-var-object-group: \f247; +$fa-var-object-ungroup: \f248; +$fa-var-odnoklassniki: \f263; +$fa-var-odnoklassniki-square: \f264; +$fa-var-opencart: \f23d; +$fa-var-openid: \f19b; +$fa-var-opera: \f26a; +$fa-var-optin-monster: \f23c; +$fa-var-osi: \f41a; +$fa-var-outdent: \f03b; +$fa-var-page4: \f3d7; +$fa-var-pagelines: \f18c; +$fa-var-paint-brush: \f1fc; +$fa-var-palfed: \f3d8; +$fa-var-paper-plane: \f1d8; +$fa-var-paperclip: \f0c6; +$fa-var-paragraph: \f1dd; +$fa-var-paste: \f0ea; +$fa-var-patreon: \f3d9; +$fa-var-pause: \f04c; +$fa-var-pause-circle: \f28b; +$fa-var-paw: \f1b0; +$fa-var-paypal: \f1ed; +$fa-var-pen-square: \f14b; +$fa-var-pencil-alt: \f303; +$fa-var-percent: \f295; +$fa-var-periscope: \f3da; +$fa-var-phabricator: \f3db; +$fa-var-phoenix-framework: \f3dc; +$fa-var-phone: \f095; +$fa-var-phone-square: \f098; +$fa-var-phone-volume: \f2a0; +$fa-var-pied-piper: \f2ae; +$fa-var-pied-piper-alt: \f1a8; +$fa-var-pied-piper-pp: \f1a7; +$fa-var-pinterest: \f0d2; +$fa-var-pinterest-p: \f231; +$fa-var-pinterest-square: \f0d3; +$fa-var-plane: \f072; +$fa-var-play: \f04b; +$fa-var-play-circle: \f144; +$fa-var-playstation: \f3df; +$fa-var-plug: \f1e6; +$fa-var-plus: \f067; +$fa-var-plus-circle: \f055; +$fa-var-plus-square: \f0fe; +$fa-var-podcast: \f2ce; +$fa-var-pound-sign: \f154; +$fa-var-power-off: \f011; +$fa-var-print: \f02f; +$fa-var-product-hunt: \f288; +$fa-var-pushed: \f3e1; +$fa-var-puzzle-piece: \f12e; +$fa-var-python: \f3e2; +$fa-var-qq: \f1d6; +$fa-var-qrcode: \f029; +$fa-var-question: \f128; +$fa-var-question-circle: \f059; +$fa-var-quora: \f2c4; +$fa-var-quote-left: \f10d; +$fa-var-quote-right: \f10e; +$fa-var-random: \f074; +$fa-var-ravelry: \f2d9; +$fa-var-react: \f41b; +$fa-var-rebel: \f1d0; +$fa-var-recycle: \f1b8; +$fa-var-red-river: \f3e3; +$fa-var-reddit: \f1a1; +$fa-var-reddit-alien: \f281; +$fa-var-reddit-square: \f1a2; +$fa-var-redo: \f01e; +$fa-var-redo-alt: \f2f9; +$fa-var-registered: \f25d; +$fa-var-rendact: \f3e4; +$fa-var-renren: \f18b; +$fa-var-reply: \f3e5; +$fa-var-reply-all: \f122; +$fa-var-replyd: \f3e6; +$fa-var-resolving: \f3e7; +$fa-var-retweet: \f079; +$fa-var-road: \f018; +$fa-var-rocket: \f135; +$fa-var-rocketchat: \f3e8; +$fa-var-rockrms: \f3e9; +$fa-var-rss: \f09e; +$fa-var-rss-square: \f143; +$fa-var-ruble-sign: \f158; +$fa-var-rupee-sign: \f156; +$fa-var-safari: \f267; +$fa-var-sass: \f41e; +$fa-var-save: \f0c7; +$fa-var-schlix: \f3ea; +$fa-var-scribd: \f28a; +$fa-var-search: \f002; +$fa-var-search-minus: \f010; +$fa-var-search-plus: \f00e; +$fa-var-searchengin: \f3eb; +$fa-var-sellcast: \f2da; +$fa-var-sellsy: \f213; +$fa-var-server: \f233; +$fa-var-servicestack: \f3ec; +$fa-var-share: \f064; +$fa-var-share-alt: \f1e0; +$fa-var-share-alt-square: \f1e1; +$fa-var-share-square: \f14d; +$fa-var-shekel-sign: \f20b; +$fa-var-shield-alt: \f3ed; +$fa-var-ship: \f21a; +$fa-var-shirtsinbulk: \f214; +$fa-var-shopping-bag: \f290; +$fa-var-shopping-basket: \f291; +$fa-var-shopping-cart: \f07a; +$fa-var-shower: \f2cc; +$fa-var-sign-in-alt: \f2f6; +$fa-var-sign-language: \f2a7; +$fa-var-sign-out-alt: \f2f5; +$fa-var-signal: \f012; +$fa-var-simplybuilt: \f215; +$fa-var-sistrix: \f3ee; +$fa-var-sitemap: \f0e8; +$fa-var-skyatlas: \f216; +$fa-var-skype: \f17e; +$fa-var-slack: \f198; +$fa-var-slack-hash: \f3ef; +$fa-var-sliders-h: \f1de; +$fa-var-slideshare: \f1e7; +$fa-var-smile: \f118; +$fa-var-snapchat: \f2ab; +$fa-var-snapchat-ghost: \f2ac; +$fa-var-snapchat-square: \f2ad; +$fa-var-snowflake: \f2dc; +$fa-var-sort: \f0dc; +$fa-var-sort-alpha-down: \f15d; +$fa-var-sort-alpha-up: \f15e; +$fa-var-sort-amount-down: \f160; +$fa-var-sort-amount-up: \f161; +$fa-var-sort-down: \f0dd; +$fa-var-sort-numeric-down: \f162; +$fa-var-sort-numeric-up: \f163; +$fa-var-sort-up: \f0de; +$fa-var-soundcloud: \f1be; +$fa-var-space-shuttle: \f197; +$fa-var-speakap: \f3f3; +$fa-var-spinner: \f110; +$fa-var-spotify: \f1bc; +$fa-var-square: \f0c8; +$fa-var-stack-exchange: \f18d; +$fa-var-stack-overflow: \f16c; +$fa-var-star: \f005; +$fa-var-star-half: \f089; +$fa-var-staylinked: \f3f5; +$fa-var-steam: \f1b6; +$fa-var-steam-square: \f1b7; +$fa-var-steam-symbol: \f3f6; +$fa-var-step-backward: \f048; +$fa-var-step-forward: \f051; +$fa-var-stethoscope: \f0f1; +$fa-var-sticker-mule: \f3f7; +$fa-var-sticky-note: \f249; +$fa-var-stop: \f04d; +$fa-var-stop-circle: \f28d; +$fa-var-strava: \f428; +$fa-var-street-view: \f21d; +$fa-var-strikethrough: \f0cc; +$fa-var-stripe: \f429; +$fa-var-stripe-s: \f42a; +$fa-var-studiovinari: \f3f8; +$fa-var-stumbleupon: \f1a4; +$fa-var-stumbleupon-circle: \f1a3; +$fa-var-subscript: \f12c; +$fa-var-subway: \f239; +$fa-var-suitcase: \f0f2; +$fa-var-sun: \f185; +$fa-var-superpowers: \f2dd; +$fa-var-superscript: \f12b; +$fa-var-supple: \f3f9; +$fa-var-sync: \f021; +$fa-var-sync-alt: \f2f1; +$fa-var-table: \f0ce; +$fa-var-tablet: \f10a; +$fa-var-tablet-alt: \f3fa; +$fa-var-tachometer-alt: \f3fd; +$fa-var-tag: \f02b; +$fa-var-tags: \f02c; +$fa-var-tasks: \f0ae; +$fa-var-taxi: \f1ba; +$fa-var-telegram: \f2c6; +$fa-var-telegram-plane: \f3fe; +$fa-var-tencent-weibo: \f1d5; +$fa-var-terminal: \f120; +$fa-var-text-height: \f034; +$fa-var-text-width: \f035; +$fa-var-th: \f00a; +$fa-var-th-large: \f009; +$fa-var-th-list: \f00b; +$fa-var-themeisle: \f2b2; +$fa-var-thermometer-empty: \f2cb; +$fa-var-thermometer-full: \f2c7; +$fa-var-thermometer-half: \f2c9; +$fa-var-thermometer-quarter: \f2ca; +$fa-var-thermometer-three-quarters: \f2c8; +$fa-var-thumbs-down: \f165; +$fa-var-thumbs-up: \f164; +$fa-var-thumbtack: \f08d; +$fa-var-ticket-alt: \f3ff; +$fa-var-times: \f00d; +$fa-var-times-circle: \f057; +$fa-var-tint: \f043; +$fa-var-toggle-off: \f204; +$fa-var-toggle-on: \f205; +$fa-var-trademark: \f25c; +$fa-var-train: \f238; +$fa-var-transgender: \f224; +$fa-var-transgender-alt: \f225; +$fa-var-trash: \f1f8; +$fa-var-trash-alt: \f2ed; +$fa-var-tree: \f1bb; +$fa-var-trello: \f181; +$fa-var-tripadvisor: \f262; +$fa-var-trophy: \f091; +$fa-var-truck: \f0d1; +$fa-var-tty: \f1e4; +$fa-var-tumblr: \f173; +$fa-var-tumblr-square: \f174; +$fa-var-tv: \f26c; +$fa-var-twitch: \f1e8; +$fa-var-twitter: \f099; +$fa-var-twitter-square: \f081; +$fa-var-typo3: \f42b; +$fa-var-uber: \f402; +$fa-var-uikit: \f403; +$fa-var-umbrella: \f0e9; +$fa-var-underline: \f0cd; +$fa-var-undo: \f0e2; +$fa-var-undo-alt: \f2ea; +$fa-var-uniregistry: \f404; +$fa-var-universal-access: \f29a; +$fa-var-university: \f19c; +$fa-var-unlink: \f127; +$fa-var-unlock: \f09c; +$fa-var-unlock-alt: \f13e; +$fa-var-untappd: \f405; +$fa-var-upload: \f093; +$fa-var-usb: \f287; +$fa-var-user: \f007; +$fa-var-user-circle: \f2bd; +$fa-var-user-md: \f0f0; +$fa-var-user-plus: \f234; +$fa-var-user-secret: \f21b; +$fa-var-user-times: \f235; +$fa-var-users: \f0c0; +$fa-var-ussunnah: \f407; +$fa-var-utensil-spoon: \f2e5; +$fa-var-utensils: \f2e7; +$fa-var-vaadin: \f408; +$fa-var-venus: \f221; +$fa-var-venus-double: \f226; +$fa-var-venus-mars: \f228; +$fa-var-viacoin: \f237; +$fa-var-viadeo: \f2a9; +$fa-var-viadeo-square: \f2aa; +$fa-var-viber: \f409; +$fa-var-video: \f03d; +$fa-var-vimeo: \f40a; +$fa-var-vimeo-square: \f194; +$fa-var-vimeo-v: \f27d; +$fa-var-vine: \f1ca; +$fa-var-vk: \f189; +$fa-var-vnv: \f40b; +$fa-var-volume-down: \f027; +$fa-var-volume-off: \f026; +$fa-var-volume-up: \f028; +$fa-var-vuejs: \f41f; +$fa-var-weibo: \f18a; +$fa-var-weixin: \f1d7; +$fa-var-whatsapp: \f232; +$fa-var-whatsapp-square: \f40c; +$fa-var-wheelchair: \f193; +$fa-var-whmcs: \f40d; +$fa-var-wifi: \f1eb; +$fa-var-wikipedia-w: \f266; +$fa-var-window-close: \f410; +$fa-var-window-maximize: \f2d0; +$fa-var-window-minimize: \f2d1; +$fa-var-window-restore: \f2d2; +$fa-var-windows: \f17a; +$fa-var-won-sign: \f159; +$fa-var-wordpress: \f19a; +$fa-var-wordpress-simple: \f411; +$fa-var-wpbeginner: \f297; +$fa-var-wpexplorer: \f2de; +$fa-var-wpforms: \f298; +$fa-var-wrench: \f0ad; +$fa-var-xbox: \f412; +$fa-var-xing: \f168; +$fa-var-xing-square: \f169; +$fa-var-y-combinator: \f23b; +$fa-var-yahoo: \f19e; +$fa-var-yandex: \f413; +$fa-var-yandex-international: \f414; +$fa-var-yelp: \f1e9; +$fa-var-yen-sign: \f157; +$fa-var-yoast: \f2b1; +$fa-var-youtube: \f167; diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-brands.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-brands.scss new file mode 100644 index 000000000..ef2cbcfae --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-brands.scss @@ -0,0 +1,21 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: normal; + src: url('#{$fa-font-path}/fa-brands-400.eot'); + src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), + url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); +} + +.fab { + font-family: 'Font Awesome 5 Brands'; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-regular.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-regular.scss new file mode 100644 index 000000000..86351544f --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-regular.scss @@ -0,0 +1,22 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + src: url('#{$fa-font-path}/fa-regular-400.eot'); + src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), + url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), + url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); +} + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-solid.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-solid.scss new file mode 100644 index 000000000..768d87b1c --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fa-solid.scss @@ -0,0 +1,23 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + src: url('#{$fa-font-path}/fa-solid-900.eot'); + src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), + url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), + url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), + url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); +} + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; +} diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fontawesome.scss b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fontawesome.scss new file mode 100644 index 000000000..84d23d056 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/scss/fontawesome.scss @@ -0,0 +1,16 @@ +/*! + * Font Awesome Free 5.0.1 by @fontawesome - http://fontawesome.com + * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@import 'variables'; +@import 'mixins'; +@import 'core'; +@import 'larger'; +@import 'fixed-width'; +@import 'list'; +@import 'bordered-pulled'; +@import 'animated'; +@import 'rotated-flipped'; +@import 'stacked'; +@import 'icons'; +@import 'screen-reader'; diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.eot b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.eot new file mode 100644 index 000000000..e7b3ba742 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.eot differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.svg b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.svg new file mode 100644 index 000000000..c5a329239 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.svg @@ -0,0 +1,978 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.ttf b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.ttf new file mode 100644 index 000000000..14179efb2 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.ttf differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff new file mode 100644 index 000000000..8f0b22bd1 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff2 b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff2 new file mode 100644 index 000000000..9b7fe7075 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-brands-400.woff2 differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.eot b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.eot new file mode 100644 index 000000000..17679617a Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.eot differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.svg b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.svg new file mode 100644 index 000000000..106460700 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.svg @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.ttf b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.ttf new file mode 100644 index 000000000..3c14dbeac Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.ttf differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff new file mode 100644 index 000000000..ec743c8ed Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff2 b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff2 new file mode 100644 index 000000000..e3369f3dc Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-regular-400.woff2 differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.eot b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.eot new file mode 100644 index 000000000..caa97edb9 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.eot differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.svg b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.svg new file mode 100644 index 000000000..73a16e089 --- /dev/null +++ b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.svg @@ -0,0 +1,1410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.ttf b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.ttf new file mode 100644 index 000000000..f2227c8be Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.ttf differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff new file mode 100644 index 000000000..133751237 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff differ diff --git a/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff2 b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff2 new file mode 100644 index 000000000..f025a0092 Binary files /dev/null and b/backend/webif/static/js/fontawesome/web-fonts-with-css/webfonts/fa-solid-900.woff2 differ diff --git a/backend/webif/static/js/google-prettify/lang-aea.js b/backend/webif/static/js/google-prettify/lang-aea.js new file mode 100755 index 000000000..784ebb29c --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-aea.js @@ -0,0 +1,18 @@ +/* + + Copyright (C) 2009 Onno Hommes. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/, +null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]); diff --git a/backend/webif/static/js/google-prettify/lang-agc.js b/backend/webif/static/js/google-prettify/lang-agc.js new file mode 100755 index 000000000..784ebb29c --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-agc.js @@ -0,0 +1,18 @@ +/* + + Copyright (C) 2009 Onno Hommes. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/, +null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]); diff --git a/backend/webif/static/js/google-prettify/lang-apollo.js b/backend/webif/static/js/google-prettify/lang-apollo.js new file mode 100755 index 000000000..10df8cde0 --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-apollo.js @@ -0,0 +1,53 @@ +/** + * @license + * Copyright (C) 2009 Onno Hommes. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for the AGC/AEA Assembly Language as described + * at http://virtualagc.googlecode.com + *

                + * This file could be used by goodle code to allow syntax highlight for + * Virtual AGC SVN repository or if you don't want to commonize + * the header for the agc/aea html assembly listing. + * + * @author ohommes@alumni.cmu.edu + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // A line comment that starts with ; + [PR['PR_COMMENT'], /^#[^\r\n]*/, null, '#'], + // Whitespace + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // A double quoted, possibly multi-line, string. + [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] + ], + [ + [PR['PR_KEYWORD'], /^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,null], + [PR['PR_TYPE'], /^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null], + // A single quote possibly followed by a word that optionally ends with + // = ! or ?. + [PR['PR_LITERAL'], + /^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/], + // Any word including labels that optionally ends with = ! or ?. + [PR['PR_PLAIN'], + /^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i], + // A printable non-space non-special character + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0()\"\\\';]+/] + ]), + ['apollo', 'agc', 'aea']); diff --git a/backend/webif/static/js/google-prettify/lang-basic.js b/backend/webif/static/js/google-prettify/lang-basic.js new file mode 100755 index 000000000..d60cce31d --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-basic.js @@ -0,0 +1,49 @@ +/** + * @license + * Copyright (C) 2013 Peter Kofler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Contributed by peter dot kofler at code minus cop dot org + +/** + * @fileoverview + * Registers a language handler for Basic. + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *

                (my BASIC code)
                + * + * @author peter dot kofler at code minus cop dot org + */ + +PR.registerLangHandler( + PR.createSimpleLexer( + [ // shortcutStylePatterns + // "single-line-string" + [PR.PR_STRING, /^(?:"(?:[^\\"\r\n]|\\.)*(?:"|$))/, null, '"'], + // Whitespace + [PR.PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0'] + ], + [ // fallthroughStylePatterns + // A line comment that starts with REM + [PR.PR_COMMENT, /^REM[^\r\n]*/, null], + [PR.PR_KEYWORD, /^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/, null], + [PR.PR_PLAIN, /^[A-Z][A-Z0-9]?(?:\$|%)?/i, null], + // Literals .0, 0, 0.0 0E13 + [PR.PR_LITERAL, /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?/i, null, '0123456789'], + [PR.PR_PUNCTUATION, /^.[^\s\w\.$%"]*/, null] + // [PR.PR_PUNCTUATION, /^[-,:;!<>=\+^\/\*]+/] + ]), + ['basic','cbm']); diff --git a/backend/webif/static/js/google-prettify/lang-cbm.js b/backend/webif/static/js/google-prettify/lang-cbm.js new file mode 100755 index 000000000..2d6151dc7 --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-cbm.js @@ -0,0 +1,18 @@ +/* + + Copyright (C) 2013 Peter Kofler + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:"(?:[^\\"\r\n]|\\.)*(?:"|$))/,null,'"'],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["com",/^REM[^\r\n]*/,null],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,null],["pln",/^[A-Z][A-Z0-9]?(?:\$|%)?/i,null],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?/i, +null,"0123456789"],["pun",/^.[^\s\w\.$%"]*/,null]]),["basic","cbm"]); diff --git a/backend/webif/static/js/google-prettify/lang-cl.js b/backend/webif/static/js/google-prettify/lang-cl.js new file mode 100755 index 000000000..2f18c967e --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-cl.js @@ -0,0 +1,18 @@ +/* + + Copyright (C) 2008 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/, +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" ")); diff --git a/backend/webif/static/js/google-prettify/lang-clj.js b/backend/webif/static/js/google-prettify/lang-clj.js new file mode 100755 index 000000000..0758335f3 --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-clj.js @@ -0,0 +1,64 @@ +/** + * @license Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for Clojure. + * + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *
                (my lisp code)
                + * The lang-cl class identifies the language as common lisp. + * This file supports the following language extensions: + * lang-clj - Clojure + * + * + * I used lang-lisp.js as the basis for this adding the clojure specific + * keywords and syntax. + * + * "Name" = 'Clojure' + * "Author" = 'Rich Hickey' + * "Version" = '1.2' + * "About" = 'Clojure is a lisp for the jvm with concurrency primitives and a richer set of types.' + * + * + * I used Clojure.org Reference as + * the basis for the reserved word list. + * + * + * @author jwall@google.com + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // clojure has more paren types than minimal lisp. + ['opn', /^[\(\{\[]+/, null, '([{'], + ['clo', /^[\)\}\]]+/, null, ')]}'], + // A line comment that starts with ; + [PR['PR_COMMENT'], /^;[^\r\n]*/, null, ';'], + // Whitespace + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // A double quoted, possibly multi-line, string. + [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] + ], + [ + // clojure has a much larger set of keywords + [PR['PR_KEYWORD'], /^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/, null], + [PR['PR_TYPE'], /^:[0-9a-zA-Z\-]+/] + ]), + ['clj']); diff --git a/backend/webif/static/js/google-prettify/lang-css.js b/backend/webif/static/js/google-prettify/lang-css.js new file mode 100755 index 000000000..c6f7c36b0 --- /dev/null +++ b/backend/webif/static/js/google-prettify/lang-css.js @@ -0,0 +1,160 @@ +/** + * @license + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for CSS. + * + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *
                
                + *
                + *
                + * http://www.w3.org/TR/CSS21/grammar.html Section G2 defines the lexical
                + * grammar.  This scheme does not recognize keywords containing escapes.
                + *
                + * @author mikesamuel@gmail.com
                + */
                +
                +// This file is a call to a function defined in prettify.js which defines a
                +// lexical scanner for CSS and maps tokens to styles.
                +
                +// The call to PR['registerLangHandler'] is quoted so that Closure Compiler
                +// will not rename the call so that this language extensions can be
                +// compiled/minified separately from one another.  Other symbols defined in
                +// prettify.js are similarly quoted.
                +
                +// The call is structured thus:
                +// PR['registerLangHandler'](
                +//    PR['createSimpleLexer'](
                +//        shortcutPatterns,
                +//        fallThroughPatterns),
                +//    [languageId0, ..., languageIdN])
                +
                +// Langugage IDs
                +// =============
                +// The language IDs are typically the file extensions of source files for
                +// that language so that users can syntax highlight arbitrary files based
                +// on just the extension.  This is heuristic, but works pretty well in
                +// practice.
                +
                +// Patterns
                +// ========
                +// Lexers are typically implemented as a set of regular expressions.
                +// The SimpleLexer function takes regular expressions, styles, and some
                +// pragma-info and produces a lexer.  A token description looks like
                +//   [STYLE_NAME, /regular-expression/, pragmas]
                +
                +// Initially, simple lexer's inner loop looked like:
                +
                +//    while sourceCode is not empty:
                +//      try each regular expression in order until one matches
                +//      remove the matched portion from sourceCode
                +
                +// This was really slow for large files because some JS interpreters
                +// do a buffer copy on the matched portion which is O(n*n)
                +
                +// The current loop now looks like
                +
                +//    1. use js-modules/combinePrefixPatterns.js to 
                +//       combine all regular expressions into one 
                +//    2. use a single global regular expresion match to extract all tokens
                +//    3. for each token try regular expressions in order until one matches it
                +//       and classify it using the associated style
                +
                +// This is a lot more efficient but it does mean that lookahead and lookbehind
                +// can't be used across boundaries to classify tokens.
                +
                +// Sometimes we need lookahead and lookbehind and sometimes we want to handle
                +// embedded language -- JavaScript or CSS embedded in HTML, or inline assembly
                +// in C.
                +
                +// If a particular pattern has a numbered group, and its style pattern starts
                +// with "lang-" as in
                +//    ['lang-js', /}
                + * 
              • define style rules. See the example page for examples. + *
              • mark the {@code
                } and {@code } tags in your source with
                + *    {@code class=prettyprint.}
                + *    You can also use the (html deprecated) {@code } tag, but the pretty
                + *    printer needs to do more substantial DOM manipulations to support that, so
                + *    some css styles may not be preserved.
                + * </ol>
                + * That's it.  I wanted to keep the API as simple as possible, so there's no
                + * need to specify which language the code is in, but if you wish, you can add
                + * another class to the {@code <pre>} or {@code <code>} element to specify the
                + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
                + * starts with "lang-" followed by a file extension, specifies the file type.
                + * See the "lang-*.js" files in this directory for code that implements
                + * per-language file handlers.
                + * <p>
                + * Change log:<br>
                + * cbeust, 2006/08/22
                + * <blockquote>
                + *   Java annotations (start with "@") are now captured as literals ("lit")
                + * </blockquote>
                + * @requires console
                + */
                +
                +// JSLint declarations
                +/*global console, document, navigator, setTimeout, window, define */
                +
                +
                +/**
                + * {@type !{
                + *   'createSimpleLexer': function (Array, Array): (function (JobT)),
                + *   'registerLangHandler': function (function (JobT), Array.<string>),
                + *   'PR_ATTRIB_NAME': string,
                + *   'PR_ATTRIB_NAME': string,
                + *   'PR_ATTRIB_VALUE': string,
                + *   'PR_COMMENT': string,
                + *   'PR_DECLARATION': string,
                + *   'PR_KEYWORD': string,
                + *   'PR_LITERAL': string,
                + *   'PR_NOCODE': string,
                + *   'PR_PLAIN': string,
                + *   'PR_PUNCTUATION': string,
                + *   'PR_SOURCE': string,
                + *   'PR_STRING': string,
                + *   'PR_TAG': string,
                + *   'PR_TYPE': string,
                + *   'prettyPrintOne': function (string, string, number|boolean),
                + *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
                + * }}
                + * @const
                + */
                +var PR;
                +
                +/**
                + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
                + * UI events.
                + * If set to {@code false}, {@code prettyPrint()} is synchronous.
                + */
                +var PR_SHOULD_USE_CONTINUATION = true
                +if (typeof window !== 'undefined') {
                +  window['PR_SHOULD_USE_CONTINUATION'] = PR_SHOULD_USE_CONTINUATION;
                +}
                +
                +/**
                + * Pretty print a chunk of code.
                + * @param {string} sourceCodeHtml The HTML to pretty print.
                + * @param {string} opt_langExtension The language name to use.
                + *     Typically, a filename extension like 'cpp' or 'java'.
                + * @param {number|boolean} opt_numberLines True to number lines,
                + *     or the 1-indexed number of the first line in sourceCodeHtml.
                + * @return {string} code as html, but prettier
                + */
                +var prettyPrintOne;
                +/**
                + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                + * {@code class=prettyprint} and prettify them.
                + *
                + * @param {Function} opt_whenDone called when prettifying is done.
                + * @param {HTMLElement|HTMLDocument} opt_root an element or document
                + *   containing all the elements to pretty print.
                + *   Defaults to {@code document.body}.
                + */
                +var prettyPrint;
                +
                +
                +(function () {
                +  var win = (typeof window !== 'undefined') ? window : {};
                +  // Keyword lists for various languages.
                +  // We use things that coerce to strings to make them compact when minified
                +  // and to defeat aggressive optimizers that fold large string constants.
                +  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
                +  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
                +      "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
                +      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
                +  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
                +      "new,operator,private,protected,public,this,throw,true,try,typeof"];
                +  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
                +      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
                +      "dynamic_cast,explicit,export,friend,generic,late_check," +
                +      "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
                +      "static_cast,template,typeid,typename,using,virtual,where"];
                +  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
                +      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
                +      "throws,transient"];
                +  var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
                +      "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
                +      "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
                +      "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
                +      "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
                +  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
                +      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
                +      "throw,true,try,unless,until,when,while,yes";
                +  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,async,await,constructor,debugger,enum,eval,export,function," +
                +      "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
                +      "yield,Infinity,NaN"];
                +  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
                +      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
                +      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
                +  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
                +      "elif,except,exec,finally,from,global,import,in,is,lambda," +
                +      "nonlocal,not,or,pass,print,raise,try,with,yield," +
                +      "False,True,None"];
                +  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
                +      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
                +      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
                +      "BEGIN,END"];
                +  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
                +      "function,in,local,set,then,until"];
                +  var ALL_KEYWORDS = [
                +      CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
                +      PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
                +  var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
                +
                +  // token style names.  correspond to css classes
                +  /**
                +   * token style for a string literal
                +   * @const
                +   */
                +  var PR_STRING = 'str';
                +  /**
                +   * token style for a keyword
                +   * @const
                +   */
                +  var PR_KEYWORD = 'kwd';
                +  /**
                +   * token style for a comment
                +   * @const
                +   */
                +  var PR_COMMENT = 'com';
                +  /**
                +   * token style for a type
                +   * @const
                +   */
                +  var PR_TYPE = 'typ';
                +  /**
                +   * token style for a literal value.  e.g. 1, null, true.
                +   * @const
                +   */
                +  var PR_LITERAL = 'lit';
                +  /**
                +   * token style for a punctuation string.
                +   * @const
                +   */
                +  var PR_PUNCTUATION = 'pun';
                +  /**
                +   * token style for plain text.
                +   * @const
                +   */
                +  var PR_PLAIN = 'pln';
                +
                +  /**
                +   * token style for an sgml tag.
                +   * @const
                +   */
                +  var PR_TAG = 'tag';
                +  /**
                +   * token style for a markup declaration such as a DOCTYPE.
                +   * @const
                +   */
                +  var PR_DECLARATION = 'dec';
                +  /**
                +   * token style for embedded source.
                +   * @const
                +   */
                +  var PR_SOURCE = 'src';
                +  /**
                +   * token style for an sgml attribute name.
                +   * @const
                +   */
                +  var PR_ATTRIB_NAME = 'atn';
                +  /**
                +   * token style for an sgml attribute value.
                +   * @const
                +   */
                +  var PR_ATTRIB_VALUE = 'atv';
                +
                +  /**
                +   * A class that indicates a section of markup that is not code, e.g. to allow
                +   * embedding of line numbers within code listings.
                +   * @const
                +   */
                +  var PR_NOCODE = 'nocode';
                +
                +
                +  // Regex pattern below is automatically generated by regexpPrecederPatterns.pl
                +  // Do not modify, your changes will be erased.
                +
                +  // CAVEAT: this does not properly handle the case where a regular
                +  // expression immediately follows another since a regular expression may
                +  // have flags for case-sensitivity and the like.  Having regexp tokens
                +  // adjacent is not valid in any language I'm aware of, so I'm punting.
                +  // TODO: maybe style special characters inside a regexp as punctuation.
                +
                +  /**
                +   * A set of tokens that can precede a regular expression literal in
                +   * javascript
                +   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
                +   * has the full list, but I've removed ones that might be problematic when
                +   * seen in languages that don't support regular expression literals.
                +   *
                +   * Specifically, I've removed any keywords that can't precede a regexp
                +   * literal in a syntactically legal javascript program, and I've removed the
                +   * "in" keyword since it's not a keyword in many languages, and might be used
                +   * as a count of inches.
                +   *
                +   * The link above does not accurately describe EcmaScript rules since
                +   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
                +   * very well in practice.
                +   *
                +   * @private
                +   * @const
                +   */
                +  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
                +
                +
                +  /**
                +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
                +   * matches the union of the sets of strings matched by the input RegExp.
                +   * Since it matches globally, if the input strings have a start-of-input
                +   * anchor (/^.../), it is ignored for the purposes of unioning.
                +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
                +   * @return {RegExp} a global regex.
                +   */
                +  function combinePrefixPatterns(regexs) {
                +    var capturedGroupIndex = 0;
                +
                +    var needToFoldCase = false;
                +    var ignoreCase = false;
                +    for (var i = 0, n = regexs.length; i < n; ++i) {
                +      var regex = regexs[i];
                +      if (regex.ignoreCase) {
                +        ignoreCase = true;
                +      } else if (/[a-z]/i.test(regex.source.replace(
                +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
                +        needToFoldCase = true;
                +        ignoreCase = false;
                +        break;
                +      }
                +    }
                +
                +    var escapeCharToCodeUnit = {
                +      'b': 8,
                +      't': 9,
                +      'n': 0xa,
                +      'v': 0xb,
                +      'f': 0xc,
                +      'r': 0xd
                +    };
                +
                +    function decodeEscape(charsetPart) {
                +      var cc0 = charsetPart.charCodeAt(0);
                +      if (cc0 !== 92 /* \\ */) {
                +        return cc0;
                +      }
                +      var c1 = charsetPart.charAt(1);
                +      cc0 = escapeCharToCodeUnit[c1];
                +      if (cc0) {
                +        return cc0;
                +      } else if ('0' <= c1 && c1 <= '7') {
                +        return parseInt(charsetPart.substring(1), 8);
                +      } else if (c1 === 'u' || c1 === 'x') {
                +        return parseInt(charsetPart.substring(2), 16);
                +      } else {
                +        return charsetPart.charCodeAt(1);
                +      }
                +    }
                +
                +    function encodeEscape(charCode) {
                +      if (charCode < 0x20) {
                +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
                +      }
                +      var ch = String.fromCharCode(charCode);
                +      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
                +          ? "\\" + ch : ch;
                +    }
                +
                +    function caseFoldCharset(charSet) {
                +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
                +          new RegExp(
                +              '\\\\u[0-9A-Fa-f]{4}'
                +              + '|\\\\x[0-9A-Fa-f]{2}'
                +              + '|\\\\[0-3][0-7]{0,2}'
                +              + '|\\\\[0-7]{1,2}'
                +              + '|\\\\[\\s\\S]'
                +              + '|-'
                +              + '|[^-\\\\]',
                +              'g'));
                +      var ranges = [];
                +      var inverse = charsetParts[0] === '^';
                +
                +      var out = ['['];
                +      if (inverse) { out.push('^'); }
                +
                +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
                +        var p = charsetParts[i];
                +        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
                +          out.push(p);
                +        } else {
                +          var start = decodeEscape(p);
                +          var end;
                +          if (i + 2 < n && '-' === charsetParts[i + 1]) {
                +            end = decodeEscape(charsetParts[i + 2]);
                +            i += 2;
                +          } else {
                +            end = start;
                +          }
                +          ranges.push([start, end]);
                +          // If the range might intersect letters, then expand it.
                +          // This case handling is too simplistic.
                +          // It does not deal with non-latin case folding.
                +          // It works for latin source code identifiers though.
                +          if (!(end < 65 || start > 122)) {
                +            if (!(end < 65 || start > 90)) {
                +              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                +            }
                +            if (!(end < 97 || start > 122)) {
                +              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                +            }
                +          }
                +        }
                +      }
                +
                +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
                +      // -> [[1, 12], [14, 14], [16, 17]]
                +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
                +      var consolidatedRanges = [];
                +      var lastRange = [];
                +      for (var i = 0; i < ranges.length; ++i) {
                +        var range = ranges[i];
                +        if (range[0] <= lastRange[1] + 1) {
                +          lastRange[1] = Math.max(lastRange[1], range[1]);
                +        } else {
                +          consolidatedRanges.push(lastRange = range);
                +        }
                +      }
                +
                +      for (var i = 0; i < consolidatedRanges.length; ++i) {
                +        var range = consolidatedRanges[i];
                +        out.push(encodeEscape(range[0]));
                +        if (range[1] > range[0]) {
                +          if (range[1] + 1 > range[0]) { out.push('-'); }
                +          out.push(encodeEscape(range[1]));
                +        }
                +      }
                +      out.push(']');
                +      return out.join('');
                +    }
                +
                +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
                +      // Split into character sets, escape sequences, punctuation strings
                +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
                +      // include any of the above.
                +      var parts = regex.source.match(
                +          new RegExp(
                +              '(?:'
                +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                +              + '|\\\\[0-9]+'  // a back-reference or octal escape
                +              + '|\\\\[^ux0-9]'  // other escape sequence
                +              + '|\\(\\?[:!=]'  // start of a non-capturing group
                +              + '|[\\(\\)\\^]'  // start/end of a group, or line start
                +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                +              + ')',
                +              'g'));
                +      var n = parts.length;
                +
                +      // Maps captured group numbers to the number they will occupy in
                +      // the output or to -1 if that has not been determined, or to
                +      // undefined if they need not be capturing in the output.
                +      var capturedGroups = [];
                +
                +      // Walk over and identify back references to build the capturedGroups
                +      // mapping.
                +      for (var i = 0, groupIndex = 0; i < n; ++i) {
                +        var p = parts[i];
                +        if (p === '(') {
                +          // groups are 1-indexed, so max group index is count of '('
                +          ++groupIndex;
                +        } else if ('\\' === p.charAt(0)) {
                +          var decimalValue = +p.substring(1);
                +          if (decimalValue) {
                +            if (decimalValue <= groupIndex) {
                +              capturedGroups[decimalValue] = -1;
                +            } else {
                +              // Replace with an unambiguous escape sequence so that
                +              // an octal escape sequence does not turn into a backreference
                +              // to a capturing group from an earlier regex.
                +              parts[i] = encodeEscape(decimalValue);
                +            }
                +          }
                +        }
                +      }
                +
                +      // Renumber groups and reduce capturing groups to non-capturing groups
                +      // where possible.
                +      for (var i = 1; i < capturedGroups.length; ++i) {
                +        if (-1 === capturedGroups[i]) {
                +          capturedGroups[i] = ++capturedGroupIndex;
                +        }
                +      }
                +      for (var i = 0, groupIndex = 0; i < n; ++i) {
                +        var p = parts[i];
                +        if (p === '(') {
                +          ++groupIndex;
                +          if (!capturedGroups[groupIndex]) {
                +            parts[i] = '(?:';
                +          }
                +        } else if ('\\' === p.charAt(0)) {
                +          var decimalValue = +p.substring(1);
                +          if (decimalValue && decimalValue <= groupIndex) {
                +            parts[i] = '\\' + capturedGroups[decimalValue];
                +          }
                +        }
                +      }
                +
                +      // Remove any prefix anchors so that the output will match anywhere.
                +      // ^^ really does mean an anchored match though.
                +      for (var i = 0; i < n; ++i) {
                +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
                +      }
                +
                +      // Expand letters to groups to handle mixing of case-sensitive and
                +      // case-insensitive patterns if necessary.
                +      if (regex.ignoreCase && needToFoldCase) {
                +        for (var i = 0; i < n; ++i) {
                +          var p = parts[i];
                +          var ch0 = p.charAt(0);
                +          if (p.length >= 2 && ch0 === '[') {
                +            parts[i] = caseFoldCharset(p);
                +          } else if (ch0 !== '\\') {
                +            // TODO: handle letters in numeric escapes.
                +            parts[i] = p.replace(
                +                /[a-zA-Z]/g,
                +                function (ch) {
                +                  var cc = ch.charCodeAt(0);
                +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                +                });
                +          }
                +        }
                +      }
                +
                +      return parts.join('');
                +    }
                +
                +    var rewritten = [];
                +    for (var i = 0, n = regexs.length; i < n; ++i) {
                +      var regex = regexs[i];
                +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
                +      rewritten.push(
                +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
                +    }
                +
                +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
                +  }
                +
                +
                +  /**
                +   * Split markup into a string of source code and an array mapping ranges in
                +   * that string to the text nodes in which they appear.
                +   *
                +   * <p>
                +   * The HTML DOM structure:</p>
                +   * <pre>
                +   * (Element   "p"
                +   *   (Element "b"
                +   *     (Text  "print "))       ; #1
                +   *   (Text    "'Hello '")      ; #2
                +   *   (Element "br")            ; #3
                +   *   (Text    "  + 'World';")) ; #4
                +   * </pre>
                +   * <p>
                +   * corresponds to the HTML
                +   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
                +   *
                +   * <p>
                +   * It will produce the output:</p>
                +   * <pre>
                +   * {
                +   *   sourceCode: "print 'Hello '\n  + 'World';",
                +   *   //                     1          2
                +   *   //           012345678901234 5678901234567
                +   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
                +   * }
                +   * </pre>
                +   * <p>
                +   * where #1 is a reference to the {@code "print "} text node above, and so
                +   * on for the other text nodes.
                +   * </p>
                +   *
                +   * <p>
                +   * The {@code} spans array is an array of pairs.  Even elements are the start
                +   * indices of substrings, and odd elements are the text nodes (or BR elements)
                +   * that contain the text for those substrings.
                +   * Substrings continue until the next index or the end of the source.
                +   * </p>
                +   *
                +   * @param {Node} node an HTML DOM subtree containing source-code.
                +   * @param {boolean|number} isPreformatted truthy if white-space in
                +   *    text nodes should be considered significant.
                +   * @return {SourceSpansT} source code and the nodes in which they occur.
                +   */
                +  function extractSourceSpans(node, isPreformatted) {
                +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +
                +    var chunks = [];
                +    var length = 0;
                +    var spans = [];
                +    var k = 0;
                +
                +    function walk(node) {
                +      var type = node.nodeType;
                +      if (type == 1) {  // Element
                +        if (nocode.test(node.className)) { return; }
                +        for (var child = node.firstChild; child; child = child.nextSibling) {
                +          walk(child);
                +        }
                +        var nodeName = node.nodeName.toLowerCase();
                +        if ('br' === nodeName || 'li' === nodeName) {
                +          chunks[k] = '\n';
                +          spans[k << 1] = length++;
                +          spans[(k++ << 1) | 1] = node;
                +        }
                +      } else if (type == 3 || type == 4) {  // Text
                +        var text = node.nodeValue;
                +        if (text.length) {
                +          if (!isPreformatted) {
                +            text = text.replace(/[ \t\r\n]+/g, ' ');
                +          } else {
                +            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                +          }
                +          // TODO: handle tabs here?
                +          chunks[k] = text;
                +          spans[k << 1] = length;
                +          length += text.length;
                +          spans[(k++ << 1) | 1] = node;
                +        }
                +      }
                +    }
                +
                +    walk(node);
                +
                +    return {
                +      sourceCode: chunks.join('').replace(/\n$/, ''),
                +      spans: spans
                +    };
                +  }
                +
                +
                +  /**
                +   * Apply the given language handler to sourceCode and add the resulting
                +   * decorations to out.
                +   * @param {!Element} sourceNode
                +   * @param {number} basePos the index of sourceCode within the chunk of source
                +   *    whose decorations are already present on out.
                +   * @param {string} sourceCode
                +   * @param {function(JobT)} langHandler
                +   * @param {DecorationsT} out
                +   */
                +  function appendDecorations(
                +      sourceNode, basePos, sourceCode, langHandler, out) {
                +    if (!sourceCode) { return; }
                +    /** @type {JobT} */
                +    var job = {
                +      sourceNode: sourceNode,
                +      pre: 1,
                +      langExtension: null,
                +      numberLines: null,
                +      sourceCode: sourceCode,
                +      spans: null,
                +      basePos: basePos,
                +      decorations: null
                +    };
                +    langHandler(job);
                +    out.push.apply(out, job.decorations);
                +  }
                +
                +  var notWs = /\S/;
                +
                +  /**
                +   * Given an element, if it contains only one child element and any text nodes
                +   * it contains contain only space characters, return the sole child element.
                +   * Otherwise returns undefined.
                +   * <p>
                +   * This is meant to return the CODE element in {@code <pre><code ...>} when
                +   * there is a single child element that contains all the non-space textual
                +   * content, but not to return anything where there are multiple child elements
                +   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
                +   * is textual content.
                +   */
                +  function childContentWrapper(element) {
                +    var wrapper = undefined;
                +    for (var c = element.firstChild; c; c = c.nextSibling) {
                +      var type = c.nodeType;
                +      wrapper = (type === 1)  // Element Node
                +          ? (wrapper ? element : c)
                +          : (type === 3)  // Text Node
                +          ? (notWs.test(c.nodeValue) ? element : wrapper)
                +          : wrapper;
                +    }
                +    return wrapper === element ? undefined : wrapper;
                +  }
                +
                +  /** Given triples of [style, pattern, context] returns a lexing function,
                +    * The lexing function interprets the patterns to find token boundaries and
                +    * returns a decoration list of the form
                +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
                +    * where index_n is an index into the sourceCode, and style_n is a style
                +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
                +    * all characters in sourceCode[index_n-1:index_n].
                +    *
                +    * The stylePatterns is a list whose elements have the form
                +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
                +    *
                +    * Style is a style constant like PR_PLAIN, or can be a string of the
                +    * form 'lang-FOO', where FOO is a language extension describing the
                +    * language of the portion of the token in $1 after pattern executes.
                +    * E.g., if style is 'lang-lisp', and group 1 contains the text
                +    * '(hello (world))', then that portion of the token will be passed to the
                +    * registered lisp handler for formatting.
                +    * The text before and after group 1 will be restyled using this decorator
                +    * so decorators should take care that this doesn't result in infinite
                +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
                +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
                +    * '<script>foo()<\/script>', which would cause the current decorator to
                +    * be called with '<script>' which would not match the same rule since
                +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
                +    * the generic tag rule.  The handler registered for the 'js' extension would
                +    * then be called with 'foo()', and finally, the current decorator would
                +    * be called with '<\/script>' which would not match the original rule and
                +    * so the generic tag rule would identify it as a tag.
                +    *
                +    * Pattern must only match prefixes, and if it matches a prefix, then that
                +    * match is considered a token with the same style.
                +    *
                +    * Context is applied to the last non-whitespace, non-comment token
                +    * recognized.
                +    *
                +    * Shortcut is an optional string of characters, any of which, if the first
                +    * character, gurantee that this pattern and only this pattern matches.
                +    *
                +    * @param {Array} shortcutStylePatterns patterns that always start with
                +    *   a known character.  Must have a shortcut string.
                +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
                +    *   order if the shortcut ones fail.  May have shortcuts.
                +    *
                +    * @return {function (JobT)} a function that takes an undecorated job and
                +    *   attaches a list of decorations.
                +    */
                +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
                +    var shortcuts = {};
                +    var tokenizer;
                +    (function () {
                +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
                +      var allRegexs = [];
                +      var regexKeys = {};
                +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
                +        var patternParts = allPatterns[i];
                +        var shortcutChars = patternParts[3];
                +        if (shortcutChars) {
                +          for (var c = shortcutChars.length; --c >= 0;) {
                +            shortcuts[shortcutChars.charAt(c)] = patternParts;
                +          }
                +        }
                +        var regex = patternParts[1];
                +        var k = '' + regex;
                +        if (!regexKeys.hasOwnProperty(k)) {
                +          allRegexs.push(regex);
                +          regexKeys[k] = null;
                +        }
                +      }
                +      allRegexs.push(/[\0-\uffff]/);
                +      tokenizer = combinePrefixPatterns(allRegexs);
                +    })();
                +
                +    var nPatterns = fallthroughStylePatterns.length;
                +
                +    /**
                +     * Lexes job.sourceCode and attaches an output array job.decorations of
                +     * style classes preceded by the position at which they start in
                +     * job.sourceCode in order.
                +     *
                +     * @type{function (JobT)}
                +     */
                +    var decorate = function (job) {
                +      var sourceCode = job.sourceCode, basePos = job.basePos;
                +      var sourceNode = job.sourceNode;
                +      /** Even entries are positions in source in ascending order.  Odd enties
                +        * are style markers (e.g., PR_COMMENT) that run from that position until
                +        * the end.
                +        * @type {DecorationsT}
                +        */
                +      var decorations = [basePos, PR_PLAIN];
                +      var pos = 0;  // index into sourceCode
                +      var tokens = sourceCode.match(tokenizer) || [];
                +      var styleCache = {};
                +
                +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
                +        var token = tokens[ti];
                +        var style = styleCache[token];
                +        var match = void 0;
                +
                +        var isEmbedded;
                +        if (typeof style === 'string') {
                +          isEmbedded = false;
                +        } else {
                +          var patternParts = shortcuts[token.charAt(0)];
                +          if (patternParts) {
                +            match = token.match(patternParts[1]);
                +            style = patternParts[0];
                +          } else {
                +            for (var i = 0; i < nPatterns; ++i) {
                +              patternParts = fallthroughStylePatterns[i];
                +              match = token.match(patternParts[1]);
                +              if (match) {
                +                style = patternParts[0];
                +                break;
                +              }
                +            }
                +
                +            if (!match) {  // make sure that we make progress
                +              style = PR_PLAIN;
                +            }
                +          }
                +
                +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
                +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
                +            isEmbedded = false;
                +            style = PR_SOURCE;
                +          }
                +
                +          if (!isEmbedded) { styleCache[token] = style; }
                +        }
                +
                +        var tokenStart = pos;
                +        pos += token.length;
                +
                +        if (!isEmbedded) {
                +          decorations.push(basePos + tokenStart, style);
                +        } else {  // Treat group 1 as an embedded block of source code.
                +          var embeddedSource = match[1];
                +          var embeddedSourceStart = token.indexOf(embeddedSource);
                +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
                +          if (match[2]) {
                +            // If embeddedSource can be blank, then it would match at the
                +            // beginning which would cause us to infinitely recurse on the
                +            // entire token, so we catch the right context in match[2].
                +            embeddedSourceEnd = token.length - match[2].length;
                +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
                +          }
                +          var lang = style.substring(5);
                +          // Decorate the left of the embedded source
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart,
                +              token.substring(0, embeddedSourceStart),
                +              decorate, decorations);
                +          // Decorate the embedded source
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart + embeddedSourceStart,
                +              embeddedSource,
                +              langHandlerForExtension(lang, embeddedSource),
                +              decorations);
                +          // Decorate the right of the embedded section
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart + embeddedSourceEnd,
                +              token.substring(embeddedSourceEnd),
                +              decorate, decorations);
                +        }
                +      }
                +      job.decorations = decorations;
                +    };
                +    return decorate;
                +  }
                +
                +  /** returns a function that produces a list of decorations from source text.
                +    *
                +    * This code treats ", ', and ` as string delimiters, and \ as a string
                +    * escape.  It does not recognize perl's qq() style strings.
                +    * It has no special handling for double delimiter escapes as in basic, or
                +    * the tripled delimiters used in python, but should work on those regardless
                +    * although in those cases a single string literal may be broken up into
                +    * multiple adjacent string literals.
                +    *
                +    * It recognizes C, C++, and shell style comments.
                +    *
                +    * @param {Object} options a set of optional parameters.
                +    * @return {function (JobT)} a function that examines the source code
                +    *     in the input job and builds a decoration list which it attaches to
                +    *     the job.
                +    */
                +  function sourceDecorator(options) {
                +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
                +    if (options['tripleQuotedStrings']) {
                +      // '''multi-line-string''', 'single-line-string', and double-quoted
                +      shortcutStylePatterns.push(
                +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                +           null, '\'"']);
                +    } else if (options['multiLineStrings']) {
                +      // 'multi-line-string', "multi-line-string"
                +      shortcutStylePatterns.push(
                +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
                +           null, '\'"`']);
                +    } else {
                +      // 'single-line-string', "single-line-string"
                +      shortcutStylePatterns.push(
                +          [PR_STRING,
                +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
                +           null, '"\'']);
                +    }
                +    if (options['verbatimStrings']) {
                +      // verbatim-string-literal production from the C# grammar.  See issue 93.
                +      fallthroughStylePatterns.push(
                +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
                +    }
                +    var hc = options['hashComments'];
                +    if (hc) {
                +      if (options['cStyleComments']) {
                +        if (hc > 1) {  // multiline hash comments
                +          shortcutStylePatterns.push(
                +              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
                +        } else {
                +          // Stop C preprocessor declarations at an unclosed open comment
                +          shortcutStylePatterns.push(
                +              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
                +               null, '#']);
                +        }
                +        // #include <stdio.h>
                +        fallthroughStylePatterns.push(
                +            [PR_STRING,
                +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
                +             null]);
                +      } else {
                +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
                +      }
                +    }
                +    if (options['cStyleComments']) {
                +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
                +      fallthroughStylePatterns.push(
                +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
                +    }
                +    var regexLiterals = options['regexLiterals'];
                +    if (regexLiterals) {
                +      /**
                +       * @const
                +       */
                +      var regexExcls = regexLiterals > 1
                +        ? ''  // Multiline regex literals
                +        : '\n\r';
                +      /**
                +       * @const
                +       */
                +      var regexAny = regexExcls ? '.' : '[\\S\\s]';
                +      /**
                +       * @const
                +       */
                +      var REGEX_LITERAL = (
                +          // A regular expression literal starts with a slash that is
                +          // not followed by * or / so that it is not confused with
                +          // comments.
                +          '/(?=[^/*' + regexExcls + '])'
                +          // and then contains any number of raw characters,
                +          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
                +          // escape sequences (\x5C),
                +          +    '|\\x5C' + regexAny
                +          // or non-nesting character sets (\x5B\x5D);
                +          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
                +          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
                +          // finally closed by a /.
                +          + '/');
                +      fallthroughStylePatterns.push(
                +          ['lang-regex',
                +           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
                +           ]);
                +    }
                +
                +    var types = options['types'];
                +    if (types) {
                +      fallthroughStylePatterns.push([PR_TYPE, types]);
                +    }
                +
                +    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
                +    if (keywords.length) {
                +      fallthroughStylePatterns.push(
                +          [PR_KEYWORD,
                +           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
                +           null]);
                +    }
                +
                +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
                +
                +    var punctuation =
                +      // The Bash man page says
                +
                +      // A word is a sequence of characters considered as a single
                +      // unit by GRUB. Words are separated by metacharacters,
                +      // which are the following plus space, tab, and newline: { }
                +      // | & $ ; < >
                +      // ...
                +
                +      // A word beginning with # causes that word and all remaining
                +      // characters on that line to be ignored.
                +
                +      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
                +      // comment but empirically
                +      // $ echo {#}
                +      // {#}
                +      // $ echo \$#
                +      // $#
                +      // $ echo }#
                +      // }#
                +
                +      // so /(?:^|[|&;<>\s])/ is more appropriate.
                +
                +      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
                +      // suggests that this definition is compatible with a
                +      // default mode that tries to use a single token definition
                +      // to recognize both bash/python style comments and C
                +      // preprocessor directives.
                +
                +      // This definition of punctuation does not include # in the list of
                +      // follow-on exclusions, so # will not be broken before if preceeded
                +      // by a punctuation character.  We could try to exclude # after
                +      // [|&;<>] but that doesn't seem to cause many major problems.
                +      // If that does turn out to be a problem, we should change the below
                +      // when hc is truthy to include # in the run of punctuation characters
                +      // only when not followint [|&;<>].
                +      '^.[^\\s\\w.$@\'"`/\\\\]*';
                +    if (options['regexLiterals']) {
                +      punctuation += '(?!\s*\/)';
                +    }
                +
                +    fallthroughStylePatterns.push(
                +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
                +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
                +        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
                +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
                +        [PR_LITERAL,
                +         new RegExp(
                +             '^(?:'
                +             // A hex number
                +             + '0x[a-f0-9]+'
                +             // or an octal or decimal number,
                +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                +             // possibly in scientific notation
                +             + '(?:e[+\\-]?\\d+)?'
                +             + ')'
                +             // with an optional modifier like UL for unsigned long
                +             + '[a-z]*', 'i'),
                +         null, '0123456789'],
                +        // Don't treat escaped quotes in bash as starting strings.
                +        // See issue 144.
                +        [PR_PLAIN,       /^\\[\s\S]?/, null],
                +        [PR_PUNCTUATION, new RegExp(punctuation), null]);
                +
                +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
                +  }
                +
                +  var decorateSource = sourceDecorator({
                +        'keywords': ALL_KEYWORDS,
                +        'hashComments': true,
                +        'cStyleComments': true,
                +        'multiLineStrings': true,
                +        'regexLiterals': true
                +      });
                +
                +  /**
                +   * Given a DOM subtree, wraps it in a list, and puts each line into its own
                +   * list item.
                +   *
                +   * @param {Node} node modified in place.  Its content is pulled into an
                +   *     HTMLOListElement, and each line is moved into a separate list item.
                +   *     This requires cloning elements, so the input might not have unique
                +   *     IDs after numbering.
                +   * @param {number|null|boolean} startLineNum
                +   *     If truthy, coerced to an integer which is the 1-indexed line number
                +   *     of the first line of code.  The number of the first line will be
                +   *     attached to the list.
                +   * @param {boolean} isPreformatted true iff white-space in text nodes should
                +   *     be treated as significant.
                +   */
                +  function numberLines(node, startLineNum, isPreformatted) {
                +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +    var lineBreak = /\r\n?|\n/;
                +
                +    var document = node.ownerDocument;
                +
                +    var li = document.createElement('li');
                +    while (node.firstChild) {
                +      li.appendChild(node.firstChild);
                +    }
                +    // An array of lines.  We split below, so this is initialized to one
                +    // un-split line.
                +    var listItems = [li];
                +
                +    function walk(node) {
                +      var type = node.nodeType;
                +      if (type == 1 && !nocode.test(node.className)) {  // Element
                +        if ('br' === node.nodeName.toLowerCase()) {
                +          breakAfter(node);
                +          // Discard the <BR> since it is now flush against a </LI>.
                +          if (node.parentNode) {
                +            node.parentNode.removeChild(node);
                +          }
                +        } else {
                +          for (var child = node.firstChild; child; child = child.nextSibling) {
                +            walk(child);
                +          }
                +        }
                +      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
                +        var text = node.nodeValue;
                +        var match = text.match(lineBreak);
                +        if (match) {
                +          var firstLine = text.substring(0, match.index);
                +          node.nodeValue = firstLine;
                +          var tail = text.substring(match.index + match[0].length);
                +          if (tail) {
                +            var parent = node.parentNode;
                +            parent.insertBefore(
                +              document.createTextNode(tail), node.nextSibling);
                +          }
                +          breakAfter(node);
                +          if (!firstLine) {
                +            // Don't leave blank text nodes in the DOM.
                +            node.parentNode.removeChild(node);
                +          }
                +        }
                +      }
                +    }
                +
                +    // Split a line after the given node.
                +    function breakAfter(lineEndNode) {
                +      // If there's nothing to the right, then we can skip ending the line
                +      // here, and move root-wards since splitting just before an end-tag
                +      // would require us to create a bunch of empty copies.
                +      while (!lineEndNode.nextSibling) {
                +        lineEndNode = lineEndNode.parentNode;
                +        if (!lineEndNode) { return; }
                +      }
                +
                +      function breakLeftOf(limit, copy) {
                +        // Clone shallowly if this node needs to be on both sides of the break.
                +        var rightSide = copy ? limit.cloneNode(false) : limit;
                +        var parent = limit.parentNode;
                +        if (parent) {
                +          // We clone the parent chain.
                +          // This helps us resurrect important styling elements that cross lines.
                +          // E.g. in <i>Foo<br>Bar</i>
                +          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
                +          var parentClone = breakLeftOf(parent, 1);
                +          // Move the clone and everything to the right of the original
                +          // onto the cloned parent.
                +          var next = limit.nextSibling;
                +          parentClone.appendChild(rightSide);
                +          for (var sibling = next; sibling; sibling = next) {
                +            next = sibling.nextSibling;
                +            parentClone.appendChild(sibling);
                +          }
                +        }
                +        return rightSide;
                +      }
                +
                +      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
                +
                +      // Walk the parent chain until we reach an unattached LI.
                +      for (var parent;
                +           // Check nodeType since IE invents document fragments.
                +           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
                +        copiedListItem = parent;
                +      }
                +      // Put it on the list of lines for later processing.
                +      listItems.push(copiedListItem);
                +    }
                +
                +    // Split lines while there are lines left to split.
                +    for (var i = 0;  // Number of lines that have been split so far.
                +         i < listItems.length;  // length updated by breakAfter calls.
                +         ++i) {
                +      walk(listItems[i]);
                +    }
                +
                +    // Make sure numeric indices show correctly.
                +    if (startLineNum === (startLineNum|0)) {
                +      listItems[0].setAttribute('value', startLineNum);
                +    }
                +
                +    var ol = document.createElement('ol');
                +    ol.className = 'linenums';
                +    var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
                +    for (var i = 0, n = listItems.length; i < n; ++i) {
                +      li = listItems[i];
                +      // Stick a class on the LIs so that stylesheets can
                +      // color odd/even rows, or any other row pattern that
                +      // is co-prime with 10.
                +      li.className = 'L' + ((i + offset) % 10);
                +      if (!li.firstChild) {
                +        li.appendChild(document.createTextNode('\xA0'));
                +      }
                +      ol.appendChild(li);
                +    }
                +
                +    node.appendChild(ol);
                +  }
                +
                +
                +  /**
                +   * Breaks {@code job.sourceCode} around style boundaries in
                +   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
                +   * @param {JobT} job
                +   * @private
                +   */
                +  function recombineTagsAndDecorations(job) {
                +    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
                +    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
                +    var newlineRe = /\n/g;
                +
                +    var source = job.sourceCode;
                +    var sourceLength = source.length;
                +    // Index into source after the last code-unit recombined.
                +    var sourceIndex = 0;
                +
                +    var spans = job.spans;
                +    var nSpans = spans.length;
                +    // Index into spans after the last span which ends at or before sourceIndex.
                +    var spanIndex = 0;
                +
                +    var decorations = job.decorations;
                +    var nDecorations = decorations.length;
                +    // Index into decorations after the last decoration which ends at or before
                +    // sourceIndex.
                +    var decorationIndex = 0;
                +
                +    // Remove all zero-length decorations.
                +    decorations[nDecorations] = sourceLength;
                +    var decPos, i;
                +    for (i = decPos = 0; i < nDecorations;) {
                +      if (decorations[i] !== decorations[i + 2]) {
                +        decorations[decPos++] = decorations[i++];
                +        decorations[decPos++] = decorations[i++];
                +      } else {
                +        i += 2;
                +      }
                +    }
                +    nDecorations = decPos;
                +
                +    // Simplify decorations.
                +    for (i = decPos = 0; i < nDecorations;) {
                +      var startPos = decorations[i];
                +      // Conflate all adjacent decorations that use the same style.
                +      var startDec = decorations[i + 1];
                +      var end = i + 2;
                +      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
                +        end += 2;
                +      }
                +      decorations[decPos++] = startPos;
                +      decorations[decPos++] = startDec;
                +      i = end;
                +    }
                +
                +    nDecorations = decorations.length = decPos;
                +
                +    var sourceNode = job.sourceNode;
                +    var oldDisplay = "";
                +    if (sourceNode) {
                +      oldDisplay = sourceNode.style.display;
                +      sourceNode.style.display = 'none';
                +    }
                +    try {
                +      var decoration = null;
                +      while (spanIndex < nSpans) {
                +        var spanStart = spans[spanIndex];
                +        var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
                +            || sourceLength;
                +
                +        var decEnd = decorations[decorationIndex + 2] || sourceLength;
                +
                +        var end = Math.min(spanEnd, decEnd);
                +
                +        var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
                +        var styledText;
                +        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
                +            // Don't introduce spans around empty text nodes.
                +            && (styledText = source.substring(sourceIndex, end))) {
                +          // This may seem bizarre, and it is.  Emitting LF on IE causes the
                +          // code to display with spaces instead of line breaks.
                +          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
                +          // space to appear at the beginning of every line but the first.
                +          // Emitting an old Mac OS 9 line separator makes everything spiffy.
                +          if (isIE8OrEarlier) {
                +            styledText = styledText.replace(newlineRe, '\r');
                +          }
                +          textNode.nodeValue = styledText;
                +          var document = textNode.ownerDocument;
                +          var span = document.createElement('span');
                +          span.className = decorations[decorationIndex + 1];
                +          var parentNode = textNode.parentNode;
                +          parentNode.replaceChild(span, textNode);
                +          span.appendChild(textNode);
                +          if (sourceIndex < spanEnd) {  // Split off a text node.
                +            spans[spanIndex + 1] = textNode
                +                // TODO: Possibly optimize by using '' if there's no flicker.
                +                = document.createTextNode(source.substring(end, spanEnd));
                +            parentNode.insertBefore(textNode, span.nextSibling);
                +          }
                +        }
                +
                +        sourceIndex = end;
                +
                +        if (sourceIndex >= spanEnd) {
                +          spanIndex += 2;
                +        }
                +        if (sourceIndex >= decEnd) {
                +          decorationIndex += 2;
                +        }
                +      }
                +    } finally {
                +      if (sourceNode) {
                +        sourceNode.style.display = oldDisplay;
                +      }
                +    }
                +  }
                +
                +
                +  /** Maps language-specific file extensions to handlers. */
                +  var langHandlerRegistry = {};
                +  /** Register a language handler for the given file extensions.
                +    * @param {function (JobT)} handler a function from source code to a list
                +    *      of decorations.  Takes a single argument job which describes the
                +    *      state of the computation and attaches the decorations to it.
                +    * @param {Array.<string>} fileExtensions
                +    */
                +  function registerLangHandler(handler, fileExtensions) {
                +    for (var i = fileExtensions.length; --i >= 0;) {
                +      var ext = fileExtensions[i];
                +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
                +        langHandlerRegistry[ext] = handler;
                +      } else if (win['console']) {
                +        console['warn']('cannot override language handler %s', ext);
                +      }
                +    }
                +  }
                +  function langHandlerForExtension(extension, source) {
                +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
                +      // Treat it as markup if the first non whitespace character is a < and
                +      // the last non-whitespace character is a >.
                +      extension = /^\s*</.test(source)
                +          ? 'default-markup'
                +          : 'default-code';
                +    }
                +    return langHandlerRegistry[extension];
                +  }
                +  registerLangHandler(decorateSource, ['default-code']);
                +  registerLangHandler(
                +      createSimpleLexer(
                +          [],
                +          [
                +           [PR_PLAIN,       /^[^<?]+/],
                +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
                +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
                +           // Unescaped content in an unknown language
                +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
                +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
                +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
                +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
                +           // Unescaped content in javascript.  (Or possibly vbscript).
                +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
                +           // Contains unescaped stylesheet content
                +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
                +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
                +          ]),
                +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
                +  registerLangHandler(
                +      createSimpleLexer(
                +          [
                +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
                +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
                +           ],
                +          [
                +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
                +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
                +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
                +           [PR_PUNCTUATION,  /^[=<>\/]+/],
                +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
                +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
                +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
                +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
                +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
                +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
                +           ]),
                +      ['in.tag']);
                +  registerLangHandler(
                +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': CPP_KEYWORDS,
                +          'hashComments': true,
                +          'cStyleComments': true,
                +          'types': C_TYPES
                +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': 'null,true,false'
                +        }), ['json']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': CSHARP_KEYWORDS,
                +          'hashComments': true,
                +          'cStyleComments': true,
                +          'verbatimStrings': true,
                +          'types': C_TYPES
                +        }), ['cs']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': JAVA_KEYWORDS,
                +          'cStyleComments': true
                +        }), ['java']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': SH_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true
                +        }), ['bash', 'bsh', 'csh', 'sh']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': PYTHON_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'tripleQuotedStrings': true
                +        }), ['cv', 'py', 'python']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': PERL_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'regexLiterals': 2  // multiline regex literals
                +        }), ['perl', 'pl', 'pm']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': RUBY_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'regexLiterals': true
                +        }), ['rb', 'ruby']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': JSCRIPT_KEYWORDS,
                +          'cStyleComments': true,
                +          'regexLiterals': true
                +        }), ['javascript', 'js', 'ts', 'typescript']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': COFFEE_KEYWORDS,
                +          'hashComments': 3,  // ### style block comments
                +          'cStyleComments': true,
                +          'multilineStrings': true,
                +          'tripleQuotedStrings': true,
                +          'regexLiterals': true
                +        }), ['coffee']);
                +  registerLangHandler(
                +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
                +
                +  /** @param {JobT} job */
                +  function applyDecorator(job) {
                +    var opt_langExtension = job.langExtension;
                +
                +    try {
                +      // Extract tags, and convert the source code to plain text.
                +      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
                +      /** Plain text. @type {string} */
                +      var source = sourceAndSpans.sourceCode;
                +      job.sourceCode = source;
                +      job.spans = sourceAndSpans.spans;
                +      job.basePos = 0;
                +
                +      // Apply the appropriate language handler
                +      langHandlerForExtension(opt_langExtension, source)(job);
                +
                +      // Integrate the decorations and tags back into the source code,
                +      // modifying the sourceNode in place.
                +      recombineTagsAndDecorations(job);
                +    } catch (e) {
                +      if (win['console']) {
                +        console['log'](e && e['stack'] || e);
                +      }
                +    }
                +  }
                +
                +  /**
                +   * Pretty print a chunk of code.
                +   * @param sourceCodeHtml {string} The HTML to pretty print.
                +   * @param opt_langExtension {string} The language name to use.
                +   *     Typically, a filename extension like 'cpp' or 'java'.
                +   * @param opt_numberLines {number|boolean} True to number lines,
                +   *     or the 1-indexed number of the first line in sourceCodeHtml.
                +   */
                +  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
                +    /** @type{number|boolean} */
                +    var nl = opt_numberLines || false;
                +    /** @type{string|null} */
                +    var langExtension = opt_langExtension || null;
                +    /** @type{!Element} */
                +    var container = document.createElement('div');
                +    // This could cause images to load and onload listeners to fire.
                +    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
                +    // We assume that the inner HTML is from a trusted source.
                +    // The pre-tag is required for IE8 which strips newlines from innerHTML
                +    // when it is injected into a <pre> tag.
                +    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
                +    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
                +    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
                +    container = /** @type{!Element} */(container.firstChild);
                +    if (nl) {
                +      numberLines(container, nl, true);
                +    }
                +
                +    /** @type{JobT} */
                +    var job = {
                +      langExtension: langExtension,
                +      numberLines: nl,
                +      sourceNode: container,
                +      pre: 1,
                +      sourceCode: null,
                +      basePos: null,
                +      spans: null,
                +      decorations: null
                +    };
                +    applyDecorator(job);
                +    return container.innerHTML;
                +  }
                +
                +   /**
                +    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                +    * {@code class=prettyprint} and prettify them.
                +    *
                +    * @param {Function} opt_whenDone called when prettifying is done.
                +    * @param {HTMLElement|HTMLDocument} opt_root an element or document
                +    *   containing all the elements to pretty print.
                +    *   Defaults to {@code document.body}.
                +    */
                +  function $prettyPrint(opt_whenDone, opt_root) {
                +    var root = opt_root || document.body;
                +    var doc = root.ownerDocument || document;
                +    function byTagName(tn) { return root.getElementsByTagName(tn); }
                +    // fetch a list of nodes to rewrite
                +    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
                +    var elements = [];
                +    for (var i = 0; i < codeSegments.length; ++i) {
                +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
                +        elements.push(codeSegments[i][j]);
                +      }
                +    }
                +    codeSegments = null;
                +
                +    var clock = Date;
                +    if (!clock['now']) {
                +      clock = { 'now': function () { return +(new Date); } };
                +    }
                +
                +    // The loop is broken into a series of continuations to make sure that we
                +    // don't make the browser unresponsive when rewriting a large page.
                +    var k = 0;
                +
                +    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
                +    var prettyPrintRe = /\bprettyprint\b/;
                +    var prettyPrintedRe = /\bprettyprinted\b/;
                +    var preformattedTagNameRe = /pre|xmp/i;
                +    var codeRe = /^code$/i;
                +    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
                +    var EMPTY = {};
                +
                +    function doWork() {
                +      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
                +                     clock['now']() + 250 /* ms */ :
                +                     Infinity);
                +      for (; k < elements.length && clock['now']() < endTime; k++) {
                +        var cs = elements[k];
                +
                +        // Look for a preceding comment like
                +        // <?prettify lang="..." linenums="..."?>
                +        var attrs = EMPTY;
                +        {
                +          for (var preceder = cs; (preceder = preceder.previousSibling);) {
                +            var nt = preceder.nodeType;
                +            // <?foo?> is parsed by HTML 5 to a comment node (8)
                +            // like <!--?foo?-->, but in XML is a processing instruction
                +            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
                +            if (value
                +                ? !/^\??prettify\b/.test(value)
                +                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
                +              // Skip over white-space text nodes but not others.
                +              break;
                +            }
                +            if (value) {
                +              attrs = {};
                +              value.replace(
                +                  /\b(\w+)=([\w:.%+-]+)/g,
                +                function (_, name, value) { attrs[name] = value; });
                +              break;
                +            }
                +          }
                +        }
                +
                +        var className = cs.className;
                +        if ((attrs !== EMPTY || prettyPrintRe.test(className))
                +            // Don't redo this if we've already done it.
                +            // This allows recalling pretty print to just prettyprint elements
                +            // that have been added to the page since last call.
                +            && !prettyPrintedRe.test(className)) {
                +
                +          // make sure this is not nested in an already prettified element
                +          var nested = false;
                +          for (var p = cs.parentNode; p; p = p.parentNode) {
                +            var tn = p.tagName;
                +            if (preCodeXmpRe.test(tn)
                +                && p.className && prettyPrintRe.test(p.className)) {
                +              nested = true;
                +              break;
                +            }
                +          }
                +          if (!nested) {
                +            // Mark done.  If we fail to prettyprint for whatever reason,
                +            // we shouldn't try again.
                +            cs.className += ' prettyprinted';
                +
                +            // If the classes includes a language extensions, use it.
                +            // Language extensions can be specified like
                +            //     <pre class="prettyprint lang-cpp">
                +            // the language extension "cpp" is used to find a language handler
                +            // as passed to PR.registerLangHandler.
                +            // HTML5 recommends that a language be specified using "language-"
                +            // as the prefix instead.  Google Code Prettify supports both.
                +            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
                +            var langExtension = attrs['lang'];
                +            if (!langExtension) {
                +              langExtension = className.match(langExtensionRe);
                +              // Support <pre class="prettyprint"><code class="language-c">
                +              var wrapper;
                +              if (!langExtension && (wrapper = childContentWrapper(cs))
                +                  && codeRe.test(wrapper.tagName)) {
                +                langExtension = wrapper.className.match(langExtensionRe);
                +              }
                +
                +              if (langExtension) { langExtension = langExtension[1]; }
                +            }
                +
                +            var preformatted;
                +            if (preformattedTagNameRe.test(cs.tagName)) {
                +              preformatted = 1;
                +            } else {
                +              var currentStyle = cs['currentStyle'];
                +              var defaultView = doc.defaultView;
                +              var whitespace = (
                +                  currentStyle
                +                  ? currentStyle['whiteSpace']
                +                  : (defaultView
                +                     && defaultView.getComputedStyle)
                +                  ? defaultView.getComputedStyle(cs, null)
                +                  .getPropertyValue('white-space')
                +                  : 0);
                +              preformatted = whitespace
                +                  && 'pre' === whitespace.substring(0, 3);
                +            }
                +
                +            // Look for a class like linenums or linenums:<n> where <n> is the
                +            // 1-indexed number of the first line.
                +            var lineNums = attrs['linenums'];
                +            if (!(lineNums = lineNums === 'true' || +lineNums)) {
                +              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
                +              lineNums =
                +                lineNums
                +                ? lineNums[1] && lineNums[1].length
                +                  ? +lineNums[1] : true
                +                : false;
                +            }
                +            if (lineNums) { numberLines(cs, lineNums, preformatted); }
                +
                +            // do the pretty printing
                +            var prettyPrintingJob = {
                +              langExtension: langExtension,
                +              sourceNode: cs,
                +              numberLines: lineNums,
                +              pre: preformatted,
                +              sourceCode: null,
                +              basePos: null,
                +              spans: null,
                +              decorations: null
                +            };
                +            applyDecorator(prettyPrintingJob);
                +          }
                +        }
                +      }
                +      if (k < elements.length) {
                +        // finish up in a continuation
                +        win.setTimeout(doWork, 250);
                +      } else if ('function' === typeof opt_whenDone) {
                +        opt_whenDone();
                +      }
                +    }
                +
                +    doWork();
                +  }
                +
                +  /**
                +   * Contains functions for creating and registering new language handlers.
                +   * @type {Object}
                +   */
                +  var PR = win['PR'] = {
                +        'createSimpleLexer': createSimpleLexer,
                +        'registerLangHandler': registerLangHandler,
                +        'sourceDecorator': sourceDecorator,
                +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
                +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
                +        'PR_COMMENT': PR_COMMENT,
                +        'PR_DECLARATION': PR_DECLARATION,
                +        'PR_KEYWORD': PR_KEYWORD,
                +        'PR_LITERAL': PR_LITERAL,
                +        'PR_NOCODE': PR_NOCODE,
                +        'PR_PLAIN': PR_PLAIN,
                +        'PR_PUNCTUATION': PR_PUNCTUATION,
                +        'PR_SOURCE': PR_SOURCE,
                +        'PR_STRING': PR_STRING,
                +        'PR_TAG': PR_TAG,
                +        'PR_TYPE': PR_TYPE,
                +        'prettyPrintOne':
                +           IN_GLOBAL_SCOPE
                +             ? (win['prettyPrintOne'] = $prettyPrintOne)
                +             : (prettyPrintOne = $prettyPrintOne),
                +        'prettyPrint':
                +           IN_GLOBAL_SCOPE
                +             ? (win['prettyPrint'] = $prettyPrint)
                +             : (prettyPrint = $prettyPrint)
                +      };
                +
                +  // Make PR available via the Asynchronous Module Definition (AMD) API.
                +  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
                +  // The Asynchronous Module Definition (AMD) API specifies a
                +  // mechanism for defining modules such that the module and its
                +  // dependencies can be asynchronously loaded.
                +  // ...
                +  // To allow a clear indicator that a global define function (as
                +  // needed for script src browser loading) conforms to the AMD API,
                +  // any global define function SHOULD have a property called "amd"
                +  // whose value is an object. This helps avoid conflict with any
                +  // other existing JavaScript code that could have defined a define()
                +  // function that does not conform to the AMD API.
                +  var define = win['define'];
                +  if (typeof define === "function" && define['amd']) {
                +    define("google-code-prettify", [], function () {
                +      return PR;
                +    });
                +  }
                +})();
                +
                +
                +var path = require('path');
                +
                +module.exports = {
                +  prettyPrint: prettyPrint,
                +  prettyPrintOne: prettyPrintOne,
                +  // include paths for css preprocessor support
                +  includePaths: [
                +    __dirname,
                +    path.resolve(__dirname, '../styles')
                +  ]
                +};
                diff --git a/backend/webif/static/js/google-prettify/prettify.css b/backend/webif/static/js/google-prettify/prettify.css
                new file mode 100755
                index 000000000..f581ffacf
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/prettify.css
                @@ -0,0 +1,70 @@
                +/**
                + * @license
                + * Copyright (C) 2015 Google Inc.
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *      http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/* Pretty printing styles. Used with prettify.js. */
                +
                +
                +/* SPAN elements with the classes below are added by prettyprint. */
                +.pln { color: #000 }  /* plain text */
                +
                +@media screen {
                +  .str { color: #080 }  /* string content */
                +  .kwd { color: #008 }  /* a keyword */
                +  .com { color: #800 }  /* a comment */
                +  .typ { color: #606 }  /* a type name */
                +  .lit { color: #066 }  /* a literal value */
                +  /* punctuation, lisp open bracket, lisp close bracket */
                +  .pun, .opn, .clo { color: #660 }
                +  .tag { color: #008 }  /* a markup tag name */
                +  .atn { color: #606 }  /* a markup attribute name */
                +  .atv { color: #080 }  /* a markup attribute value */
                +  .dec, .var { color: #606 }  /* a declaration; a variable name */
                +  .fun { color: red }  /* a function name */
                +}
                +
                +/* Use higher contrast and text-weight for printable form. */
                +@media print, projection {
                +  .str { color: #060 }
                +  .kwd { color: #006; font-weight: bold }
                +  .com { color: #600; font-style: italic }
                +  .typ { color: #404; font-weight: bold }
                +  .lit { color: #044 }
                +  .pun, .opn, .clo { color: #440 }
                +  .tag { color: #006; font-weight: bold }
                +  .atn { color: #404 }
                +  .atv { color: #060 }
                +}
                +
                +/* Put a border around prettyprinted code snippets. */
                +pre.prettyprint { padding: 2px; border: 1px solid #888 }
                +
                +/* Specify class=linenums on a pre to get line numbering */
                +ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
                +li.L0,
                +li.L1,
                +li.L2,
                +li.L3,
                +li.L5,
                +li.L6,
                +li.L7,
                +li.L8 { list-style-type: none }
                +/* Alternate shading for lines */
                +li.L1,
                +li.L3,
                +li.L5,
                +li.L7,
                +li.L9 { background: #eee }
                diff --git a/backend/webif/static/js/google-prettify/prettify.js b/backend/webif/static/js/google-prettify/prettify.js
                new file mode 100755
                index 000000000..2280a4d8f
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/prettify.js
                @@ -0,0 +1,1750 @@
                +/**
                + * @license
                + * Copyright (C) 2006 Google Inc.
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *      http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview
                + * some functions for browser-side pretty printing of code contained in html.
                + *
                + * <p>
                + * For a fairly comprehensive set of languages see the
                + * <a href="https://github.com/google/code-prettify#for-which-languages-does-it-work">README</a>
                + * file that came with this source.  At a minimum, the lexer should work on a
                + * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
                + * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
                + * and a subset of Perl, but, because of commenting conventions, doesn't work on
                + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
                + * <p>
                + * Usage: <ol>
                + * <li> include this source file in an html page via
                + *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
                + * <li> define style rules.  See the example page for examples.
                + * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
                + *    {@code class=prettyprint.}
                + *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
                + *    printer needs to do more substantial DOM manipulations to support that, so
                + *    some css styles may not be preserved.
                + * </ol>
                + * That's it.  I wanted to keep the API as simple as possible, so there's no
                + * need to specify which language the code is in, but if you wish, you can add
                + * another class to the {@code <pre>} or {@code <code>} element to specify the
                + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
                + * starts with "lang-" followed by a file extension, specifies the file type.
                + * See the "lang-*.js" files in this directory for code that implements
                + * per-language file handlers.
                + * <p>
                + * Change log:<br>
                + * cbeust, 2006/08/22
                + * <blockquote>
                + *   Java annotations (start with "@") are now captured as literals ("lit")
                + * </blockquote>
                + * @requires console
                + */
                +
                +// JSLint declarations
                +/*global console, document, navigator, setTimeout, window, define */
                +
                +/**
                + * @typedef {!Array.<number|string>}
                + * Alternating indices and the decorations that should be inserted there.
                + * The indices are monotonically increasing.
                + */
                +var DecorationsT;
                +
                +/**
                + * @typedef {!{
                + *   sourceNode: !Element,
                + *   pre: !(number|boolean),
                + *   langExtension: ?string,
                + *   numberLines: ?(number|boolean),
                + *   sourceCode: ?string,
                + *   spans: ?(Array.<number|Node>),
                + *   basePos: ?number,
                + *   decorations: ?DecorationsT
                + * }}
                + * <dl>
                + *  <dt>sourceNode<dd>the element containing the source
                + *  <dt>sourceCode<dd>source as plain text
                + *  <dt>pre<dd>truthy if white-space in text nodes
                + *     should be considered significant.
                + *  <dt>spans<dd> alternating span start indices into source
                + *     and the text node or element (e.g. {@code <BR>}) corresponding to that
                + *     span.
                + *  <dt>decorations<dd>an array of style classes preceded
                + *     by the position at which they start in job.sourceCode in order
                + *  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
                + *     source.
                + * </dl>
                + */
                +var JobT;
                +
                +/**
                + * @typedef {!{
                + *   sourceCode: string,
                + *   spans: !(Array.<number|Node>)
                + * }}
                + * <dl>
                + *  <dt>sourceCode<dd>source as plain text
                + *  <dt>spans<dd> alternating span start indices into source
                + *     and the text node or element (e.g. {@code <BR>}) corresponding to that
                + *     span.
                + * </dl>
                + */
                +var SourceSpansT;
                +
                +/** @define {boolean} */
                +var IN_GLOBAL_SCOPE = true;
                +
                +
                +/**
                + * {@type !{
                + *   'createSimpleLexer': function (Array, Array): (function (JobT)),
                + *   'registerLangHandler': function (function (JobT), Array.<string>),
                + *   'PR_ATTRIB_NAME': string,
                + *   'PR_ATTRIB_NAME': string,
                + *   'PR_ATTRIB_VALUE': string,
                + *   'PR_COMMENT': string,
                + *   'PR_DECLARATION': string,
                + *   'PR_KEYWORD': string,
                + *   'PR_LITERAL': string,
                + *   'PR_NOCODE': string,
                + *   'PR_PLAIN': string,
                + *   'PR_PUNCTUATION': string,
                + *   'PR_SOURCE': string,
                + *   'PR_STRING': string,
                + *   'PR_TAG': string,
                + *   'PR_TYPE': string,
                + *   'prettyPrintOne': function (string, string, number|boolean),
                + *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
                + * }}
                + * @const
                + */
                +var PR;
                +
                +/**
                + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
                + * UI events.
                + * If set to {@code false}, {@code prettyPrint()} is synchronous.
                + */
                +var PR_SHOULD_USE_CONTINUATION = true
                +if (typeof window !== 'undefined') {
                +  window['PR_SHOULD_USE_CONTINUATION'] = PR_SHOULD_USE_CONTINUATION;
                +}
                +
                +/**
                + * Pretty print a chunk of code.
                + * @param {string} sourceCodeHtml The HTML to pretty print.
                + * @param {string} opt_langExtension The language name to use.
                + *     Typically, a filename extension like 'cpp' or 'java'.
                + * @param {number|boolean} opt_numberLines True to number lines,
                + *     or the 1-indexed number of the first line in sourceCodeHtml.
                + * @return {string} code as html, but prettier
                + */
                +var prettyPrintOne;
                +/**
                + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                + * {@code class=prettyprint} and prettify them.
                + *
                + * @param {Function} opt_whenDone called when prettifying is done.
                + * @param {HTMLElement|HTMLDocument} opt_root an element or document
                + *   containing all the elements to pretty print.
                + *   Defaults to {@code document.body}.
                + */
                +var prettyPrint;
                +
                +
                +(function () {
                +  var win = (typeof window !== 'undefined') ? window : {};
                +  // Keyword lists for various languages.
                +  // We use things that coerce to strings to make them compact when minified
                +  // and to defeat aggressive optimizers that fold large string constants.
                +  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
                +  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
                +      "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
                +      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
                +  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
                +      "new,operator,private,protected,public,this,throw,true,try,typeof"];
                +  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
                +      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
                +      "dynamic_cast,explicit,export,friend,generic,late_check," +
                +      "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
                +      "static_cast,template,typeid,typename,using,virtual,where"];
                +  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
                +      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
                +      "throws,transient"];
                +  var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
                +      "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
                +      "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
                +      "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
                +      "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
                +  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
                +      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
                +      "throw,true,try,unless,until,when,while,yes";
                +  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
                +      "abstract,async,await,constructor,debugger,enum,eval,export,function," +
                +      "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
                +      "yield,Infinity,NaN"];
                +  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
                +      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
                +      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
                +  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
                +      "elif,except,exec,finally,from,global,import,in,is,lambda," +
                +      "nonlocal,not,or,pass,print,raise,try,with,yield," +
                +      "False,True,None"];
                +  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
                +      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
                +      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
                +      "BEGIN,END"];
                +  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
                +      "function,in,local,set,then,until"];
                +  var ALL_KEYWORDS = [
                +      CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
                +      PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
                +  var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
                +
                +  // token style names.  correspond to css classes
                +  /**
                +   * token style for a string literal
                +   * @const
                +   */
                +  var PR_STRING = 'str';
                +  /**
                +   * token style for a keyword
                +   * @const
                +   */
                +  var PR_KEYWORD = 'kwd';
                +  /**
                +   * token style for a comment
                +   * @const
                +   */
                +  var PR_COMMENT = 'com';
                +  /**
                +   * token style for a type
                +   * @const
                +   */
                +  var PR_TYPE = 'typ';
                +  /**
                +   * token style for a literal value.  e.g. 1, null, true.
                +   * @const
                +   */
                +  var PR_LITERAL = 'lit';
                +  /**
                +   * token style for a punctuation string.
                +   * @const
                +   */
                +  var PR_PUNCTUATION = 'pun';
                +  /**
                +   * token style for plain text.
                +   * @const
                +   */
                +  var PR_PLAIN = 'pln';
                +
                +  /**
                +   * token style for an sgml tag.
                +   * @const
                +   */
                +  var PR_TAG = 'tag';
                +  /**
                +   * token style for a markup declaration such as a DOCTYPE.
                +   * @const
                +   */
                +  var PR_DECLARATION = 'dec';
                +  /**
                +   * token style for embedded source.
                +   * @const
                +   */
                +  var PR_SOURCE = 'src';
                +  /**
                +   * token style for an sgml attribute name.
                +   * @const
                +   */
                +  var PR_ATTRIB_NAME = 'atn';
                +  /**
                +   * token style for an sgml attribute value.
                +   * @const
                +   */
                +  var PR_ATTRIB_VALUE = 'atv';
                +
                +  /**
                +   * A class that indicates a section of markup that is not code, e.g. to allow
                +   * embedding of line numbers within code listings.
                +   * @const
                +   */
                +  var PR_NOCODE = 'nocode';
                +
                +
                +  // Regex pattern below is automatically generated by regexpPrecederPatterns.pl
                +  // Do not modify, your changes will be erased.
                +
                +  // CAVEAT: this does not properly handle the case where a regular
                +  // expression immediately follows another since a regular expression may
                +  // have flags for case-sensitivity and the like.  Having regexp tokens
                +  // adjacent is not valid in any language I'm aware of, so I'm punting.
                +  // TODO: maybe style special characters inside a regexp as punctuation.
                +
                +  /**
                +   * A set of tokens that can precede a regular expression literal in
                +   * javascript
                +   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
                +   * has the full list, but I've removed ones that might be problematic when
                +   * seen in languages that don't support regular expression literals.
                +   *
                +   * Specifically, I've removed any keywords that can't precede a regexp
                +   * literal in a syntactically legal javascript program, and I've removed the
                +   * "in" keyword since it's not a keyword in many languages, and might be used
                +   * as a count of inches.
                +   *
                +   * The link above does not accurately describe EcmaScript rules since
                +   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
                +   * very well in practice.
                +   *
                +   * @private
                +   * @const
                +   */
                +  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
                +
                +
                +  /**
                +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
                +   * matches the union of the sets of strings matched by the input RegExp.
                +   * Since it matches globally, if the input strings have a start-of-input
                +   * anchor (/^.../), it is ignored for the purposes of unioning.
                +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
                +   * @return {RegExp} a global regex.
                +   */
                +  function combinePrefixPatterns(regexs) {
                +    var capturedGroupIndex = 0;
                +
                +    var needToFoldCase = false;
                +    var ignoreCase = false;
                +    for (var i = 0, n = regexs.length; i < n; ++i) {
                +      var regex = regexs[i];
                +      if (regex.ignoreCase) {
                +        ignoreCase = true;
                +      } else if (/[a-z]/i.test(regex.source.replace(
                +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
                +        needToFoldCase = true;
                +        ignoreCase = false;
                +        break;
                +      }
                +    }
                +
                +    var escapeCharToCodeUnit = {
                +      'b': 8,
                +      't': 9,
                +      'n': 0xa,
                +      'v': 0xb,
                +      'f': 0xc,
                +      'r': 0xd
                +    };
                +
                +    function decodeEscape(charsetPart) {
                +      var cc0 = charsetPart.charCodeAt(0);
                +      if (cc0 !== 92 /* \\ */) {
                +        return cc0;
                +      }
                +      var c1 = charsetPart.charAt(1);
                +      cc0 = escapeCharToCodeUnit[c1];
                +      if (cc0) {
                +        return cc0;
                +      } else if ('0' <= c1 && c1 <= '7') {
                +        return parseInt(charsetPart.substring(1), 8);
                +      } else if (c1 === 'u' || c1 === 'x') {
                +        return parseInt(charsetPart.substring(2), 16);
                +      } else {
                +        return charsetPart.charCodeAt(1);
                +      }
                +    }
                +
                +    function encodeEscape(charCode) {
                +      if (charCode < 0x20) {
                +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
                +      }
                +      var ch = String.fromCharCode(charCode);
                +      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
                +          ? "\\" + ch : ch;
                +    }
                +
                +    function caseFoldCharset(charSet) {
                +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
                +          new RegExp(
                +              '\\\\u[0-9A-Fa-f]{4}'
                +              + '|\\\\x[0-9A-Fa-f]{2}'
                +              + '|\\\\[0-3][0-7]{0,2}'
                +              + '|\\\\[0-7]{1,2}'
                +              + '|\\\\[\\s\\S]'
                +              + '|-'
                +              + '|[^-\\\\]',
                +              'g'));
                +      var ranges = [];
                +      var inverse = charsetParts[0] === '^';
                +
                +      var out = ['['];
                +      if (inverse) { out.push('^'); }
                +
                +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
                +        var p = charsetParts[i];
                +        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
                +          out.push(p);
                +        } else {
                +          var start = decodeEscape(p);
                +          var end;
                +          if (i + 2 < n && '-' === charsetParts[i + 1]) {
                +            end = decodeEscape(charsetParts[i + 2]);
                +            i += 2;
                +          } else {
                +            end = start;
                +          }
                +          ranges.push([start, end]);
                +          // If the range might intersect letters, then expand it.
                +          // This case handling is too simplistic.
                +          // It does not deal with non-latin case folding.
                +          // It works for latin source code identifiers though.
                +          if (!(end < 65 || start > 122)) {
                +            if (!(end < 65 || start > 90)) {
                +              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                +            }
                +            if (!(end < 97 || start > 122)) {
                +              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                +            }
                +          }
                +        }
                +      }
                +
                +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
                +      // -> [[1, 12], [14, 14], [16, 17]]
                +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
                +      var consolidatedRanges = [];
                +      var lastRange = [];
                +      for (var i = 0; i < ranges.length; ++i) {
                +        var range = ranges[i];
                +        if (range[0] <= lastRange[1] + 1) {
                +          lastRange[1] = Math.max(lastRange[1], range[1]);
                +        } else {
                +          consolidatedRanges.push(lastRange = range);
                +        }
                +      }
                +
                +      for (var i = 0; i < consolidatedRanges.length; ++i) {
                +        var range = consolidatedRanges[i];
                +        out.push(encodeEscape(range[0]));
                +        if (range[1] > range[0]) {
                +          if (range[1] + 1 > range[0]) { out.push('-'); }
                +          out.push(encodeEscape(range[1]));
                +        }
                +      }
                +      out.push(']');
                +      return out.join('');
                +    }
                +
                +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
                +      // Split into character sets, escape sequences, punctuation strings
                +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
                +      // include any of the above.
                +      var parts = regex.source.match(
                +          new RegExp(
                +              '(?:'
                +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                +              + '|\\\\[0-9]+'  // a back-reference or octal escape
                +              + '|\\\\[^ux0-9]'  // other escape sequence
                +              + '|\\(\\?[:!=]'  // start of a non-capturing group
                +              + '|[\\(\\)\\^]'  // start/end of a group, or line start
                +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                +              + ')',
                +              'g'));
                +      var n = parts.length;
                +
                +      // Maps captured group numbers to the number they will occupy in
                +      // the output or to -1 if that has not been determined, or to
                +      // undefined if they need not be capturing in the output.
                +      var capturedGroups = [];
                +
                +      // Walk over and identify back references to build the capturedGroups
                +      // mapping.
                +      for (var i = 0, groupIndex = 0; i < n; ++i) {
                +        var p = parts[i];
                +        if (p === '(') {
                +          // groups are 1-indexed, so max group index is count of '('
                +          ++groupIndex;
                +        } else if ('\\' === p.charAt(0)) {
                +          var decimalValue = +p.substring(1);
                +          if (decimalValue) {
                +            if (decimalValue <= groupIndex) {
                +              capturedGroups[decimalValue] = -1;
                +            } else {
                +              // Replace with an unambiguous escape sequence so that
                +              // an octal escape sequence does not turn into a backreference
                +              // to a capturing group from an earlier regex.
                +              parts[i] = encodeEscape(decimalValue);
                +            }
                +          }
                +        }
                +      }
                +
                +      // Renumber groups and reduce capturing groups to non-capturing groups
                +      // where possible.
                +      for (var i = 1; i < capturedGroups.length; ++i) {
                +        if (-1 === capturedGroups[i]) {
                +          capturedGroups[i] = ++capturedGroupIndex;
                +        }
                +      }
                +      for (var i = 0, groupIndex = 0; i < n; ++i) {
                +        var p = parts[i];
                +        if (p === '(') {
                +          ++groupIndex;
                +          if (!capturedGroups[groupIndex]) {
                +            parts[i] = '(?:';
                +          }
                +        } else if ('\\' === p.charAt(0)) {
                +          var decimalValue = +p.substring(1);
                +          if (decimalValue && decimalValue <= groupIndex) {
                +            parts[i] = '\\' + capturedGroups[decimalValue];
                +          }
                +        }
                +      }
                +
                +      // Remove any prefix anchors so that the output will match anywhere.
                +      // ^^ really does mean an anchored match though.
                +      for (var i = 0; i < n; ++i) {
                +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
                +      }
                +
                +      // Expand letters to groups to handle mixing of case-sensitive and
                +      // case-insensitive patterns if necessary.
                +      if (regex.ignoreCase && needToFoldCase) {
                +        for (var i = 0; i < n; ++i) {
                +          var p = parts[i];
                +          var ch0 = p.charAt(0);
                +          if (p.length >= 2 && ch0 === '[') {
                +            parts[i] = caseFoldCharset(p);
                +          } else if (ch0 !== '\\') {
                +            // TODO: handle letters in numeric escapes.
                +            parts[i] = p.replace(
                +                /[a-zA-Z]/g,
                +                function (ch) {
                +                  var cc = ch.charCodeAt(0);
                +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                +                });
                +          }
                +        }
                +      }
                +
                +      return parts.join('');
                +    }
                +
                +    var rewritten = [];
                +    for (var i = 0, n = regexs.length; i < n; ++i) {
                +      var regex = regexs[i];
                +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
                +      rewritten.push(
                +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
                +    }
                +
                +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
                +  }
                +
                +
                +  /**
                +   * Split markup into a string of source code and an array mapping ranges in
                +   * that string to the text nodes in which they appear.
                +   *
                +   * <p>
                +   * The HTML DOM structure:</p>
                +   * <pre>
                +   * (Element   "p"
                +   *   (Element "b"
                +   *     (Text  "print "))       ; #1
                +   *   (Text    "'Hello '")      ; #2
                +   *   (Element "br")            ; #3
                +   *   (Text    "  + 'World';")) ; #4
                +   * </pre>
                +   * <p>
                +   * corresponds to the HTML
                +   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
                +   *
                +   * <p>
                +   * It will produce the output:</p>
                +   * <pre>
                +   * {
                +   *   sourceCode: "print 'Hello '\n  + 'World';",
                +   *   //                     1          2
                +   *   //           012345678901234 5678901234567
                +   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
                +   * }
                +   * </pre>
                +   * <p>
                +   * where #1 is a reference to the {@code "print "} text node above, and so
                +   * on for the other text nodes.
                +   * </p>
                +   *
                +   * <p>
                +   * The {@code} spans array is an array of pairs.  Even elements are the start
                +   * indices of substrings, and odd elements are the text nodes (or BR elements)
                +   * that contain the text for those substrings.
                +   * Substrings continue until the next index or the end of the source.
                +   * </p>
                +   *
                +   * @param {Node} node an HTML DOM subtree containing source-code.
                +   * @param {boolean|number} isPreformatted truthy if white-space in
                +   *    text nodes should be considered significant.
                +   * @return {SourceSpansT} source code and the nodes in which they occur.
                +   */
                +  function extractSourceSpans(node, isPreformatted) {
                +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +
                +    var chunks = [];
                +    var length = 0;
                +    var spans = [];
                +    var k = 0;
                +
                +    function walk(node) {
                +      var type = node.nodeType;
                +      if (type == 1) {  // Element
                +        if (nocode.test(node.className)) { return; }
                +        for (var child = node.firstChild; child; child = child.nextSibling) {
                +          walk(child);
                +        }
                +        var nodeName = node.nodeName.toLowerCase();
                +        if ('br' === nodeName || 'li' === nodeName) {
                +          chunks[k] = '\n';
                +          spans[k << 1] = length++;
                +          spans[(k++ << 1) | 1] = node;
                +        }
                +      } else if (type == 3 || type == 4) {  // Text
                +        var text = node.nodeValue;
                +        if (text.length) {
                +          if (!isPreformatted) {
                +            text = text.replace(/[ \t\r\n]+/g, ' ');
                +          } else {
                +            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                +          }
                +          // TODO: handle tabs here?
                +          chunks[k] = text;
                +          spans[k << 1] = length;
                +          length += text.length;
                +          spans[(k++ << 1) | 1] = node;
                +        }
                +      }
                +    }
                +
                +    walk(node);
                +
                +    return {
                +      sourceCode: chunks.join('').replace(/\n$/, ''),
                +      spans: spans
                +    };
                +  }
                +
                +
                +  /**
                +   * Apply the given language handler to sourceCode and add the resulting
                +   * decorations to out.
                +   * @param {!Element} sourceNode
                +   * @param {number} basePos the index of sourceCode within the chunk of source
                +   *    whose decorations are already present on out.
                +   * @param {string} sourceCode
                +   * @param {function(JobT)} langHandler
                +   * @param {DecorationsT} out
                +   */
                +  function appendDecorations(
                +      sourceNode, basePos, sourceCode, langHandler, out) {
                +    if (!sourceCode) { return; }
                +    /** @type {JobT} */
                +    var job = {
                +      sourceNode: sourceNode,
                +      pre: 1,
                +      langExtension: null,
                +      numberLines: null,
                +      sourceCode: sourceCode,
                +      spans: null,
                +      basePos: basePos,
                +      decorations: null
                +    };
                +    langHandler(job);
                +    out.push.apply(out, job.decorations);
                +  }
                +
                +  var notWs = /\S/;
                +
                +  /**
                +   * Given an element, if it contains only one child element and any text nodes
                +   * it contains contain only space characters, return the sole child element.
                +   * Otherwise returns undefined.
                +   * <p>
                +   * This is meant to return the CODE element in {@code <pre><code ...>} when
                +   * there is a single child element that contains all the non-space textual
                +   * content, but not to return anything where there are multiple child elements
                +   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
                +   * is textual content.
                +   */
                +  function childContentWrapper(element) {
                +    var wrapper = undefined;
                +    for (var c = element.firstChild; c; c = c.nextSibling) {
                +      var type = c.nodeType;
                +      wrapper = (type === 1)  // Element Node
                +          ? (wrapper ? element : c)
                +          : (type === 3)  // Text Node
                +          ? (notWs.test(c.nodeValue) ? element : wrapper)
                +          : wrapper;
                +    }
                +    return wrapper === element ? undefined : wrapper;
                +  }
                +
                +  /** Given triples of [style, pattern, context] returns a lexing function,
                +    * The lexing function interprets the patterns to find token boundaries and
                +    * returns a decoration list of the form
                +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
                +    * where index_n is an index into the sourceCode, and style_n is a style
                +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
                +    * all characters in sourceCode[index_n-1:index_n].
                +    *
                +    * The stylePatterns is a list whose elements have the form
                +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
                +    *
                +    * Style is a style constant like PR_PLAIN, or can be a string of the
                +    * form 'lang-FOO', where FOO is a language extension describing the
                +    * language of the portion of the token in $1 after pattern executes.
                +    * E.g., if style is 'lang-lisp', and group 1 contains the text
                +    * '(hello (world))', then that portion of the token will be passed to the
                +    * registered lisp handler for formatting.
                +    * The text before and after group 1 will be restyled using this decorator
                +    * so decorators should take care that this doesn't result in infinite
                +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
                +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
                +    * '<script>foo()<\/script>', which would cause the current decorator to
                +    * be called with '<script>' which would not match the same rule since
                +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
                +    * the generic tag rule.  The handler registered for the 'js' extension would
                +    * then be called with 'foo()', and finally, the current decorator would
                +    * be called with '<\/script>' which would not match the original rule and
                +    * so the generic tag rule would identify it as a tag.
                +    *
                +    * Pattern must only match prefixes, and if it matches a prefix, then that
                +    * match is considered a token with the same style.
                +    *
                +    * Context is applied to the last non-whitespace, non-comment token
                +    * recognized.
                +    *
                +    * Shortcut is an optional string of characters, any of which, if the first
                +    * character, gurantee that this pattern and only this pattern matches.
                +    *
                +    * @param {Array} shortcutStylePatterns patterns that always start with
                +    *   a known character.  Must have a shortcut string.
                +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
                +    *   order if the shortcut ones fail.  May have shortcuts.
                +    *
                +    * @return {function (JobT)} a function that takes an undecorated job and
                +    *   attaches a list of decorations.
                +    */
                +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
                +    var shortcuts = {};
                +    var tokenizer;
                +    (function () {
                +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
                +      var allRegexs = [];
                +      var regexKeys = {};
                +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
                +        var patternParts = allPatterns[i];
                +        var shortcutChars = patternParts[3];
                +        if (shortcutChars) {
                +          for (var c = shortcutChars.length; --c >= 0;) {
                +            shortcuts[shortcutChars.charAt(c)] = patternParts;
                +          }
                +        }
                +        var regex = patternParts[1];
                +        var k = '' + regex;
                +        if (!regexKeys.hasOwnProperty(k)) {
                +          allRegexs.push(regex);
                +          regexKeys[k] = null;
                +        }
                +      }
                +      allRegexs.push(/[\0-\uffff]/);
                +      tokenizer = combinePrefixPatterns(allRegexs);
                +    })();
                +
                +    var nPatterns = fallthroughStylePatterns.length;
                +
                +    /**
                +     * Lexes job.sourceCode and attaches an output array job.decorations of
                +     * style classes preceded by the position at which they start in
                +     * job.sourceCode in order.
                +     *
                +     * @type{function (JobT)}
                +     */
                +    var decorate = function (job) {
                +      var sourceCode = job.sourceCode, basePos = job.basePos;
                +      var sourceNode = job.sourceNode;
                +      /** Even entries are positions in source in ascending order.  Odd enties
                +        * are style markers (e.g., PR_COMMENT) that run from that position until
                +        * the end.
                +        * @type {DecorationsT}
                +        */
                +      var decorations = [basePos, PR_PLAIN];
                +      var pos = 0;  // index into sourceCode
                +      var tokens = sourceCode.match(tokenizer) || [];
                +      var styleCache = {};
                +
                +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
                +        var token = tokens[ti];
                +        var style = styleCache[token];
                +        var match = void 0;
                +
                +        var isEmbedded;
                +        if (typeof style === 'string') {
                +          isEmbedded = false;
                +        } else {
                +          var patternParts = shortcuts[token.charAt(0)];
                +          if (patternParts) {
                +            match = token.match(patternParts[1]);
                +            style = patternParts[0];
                +          } else {
                +            for (var i = 0; i < nPatterns; ++i) {
                +              patternParts = fallthroughStylePatterns[i];
                +              match = token.match(patternParts[1]);
                +              if (match) {
                +                style = patternParts[0];
                +                break;
                +              }
                +            }
                +
                +            if (!match) {  // make sure that we make progress
                +              style = PR_PLAIN;
                +            }
                +          }
                +
                +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
                +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
                +            isEmbedded = false;
                +            style = PR_SOURCE;
                +          }
                +
                +          if (!isEmbedded) { styleCache[token] = style; }
                +        }
                +
                +        var tokenStart = pos;
                +        pos += token.length;
                +
                +        if (!isEmbedded) {
                +          decorations.push(basePos + tokenStart, style);
                +        } else {  // Treat group 1 as an embedded block of source code.
                +          var embeddedSource = match[1];
                +          var embeddedSourceStart = token.indexOf(embeddedSource);
                +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
                +          if (match[2]) {
                +            // If embeddedSource can be blank, then it would match at the
                +            // beginning which would cause us to infinitely recurse on the
                +            // entire token, so we catch the right context in match[2].
                +            embeddedSourceEnd = token.length - match[2].length;
                +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
                +          }
                +          var lang = style.substring(5);
                +          // Decorate the left of the embedded source
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart,
                +              token.substring(0, embeddedSourceStart),
                +              decorate, decorations);
                +          // Decorate the embedded source
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart + embeddedSourceStart,
                +              embeddedSource,
                +              langHandlerForExtension(lang, embeddedSource),
                +              decorations);
                +          // Decorate the right of the embedded section
                +          appendDecorations(
                +              sourceNode,
                +              basePos + tokenStart + embeddedSourceEnd,
                +              token.substring(embeddedSourceEnd),
                +              decorate, decorations);
                +        }
                +      }
                +      job.decorations = decorations;
                +    };
                +    return decorate;
                +  }
                +
                +  /** returns a function that produces a list of decorations from source text.
                +    *
                +    * This code treats ", ', and ` as string delimiters, and \ as a string
                +    * escape.  It does not recognize perl's qq() style strings.
                +    * It has no special handling for double delimiter escapes as in basic, or
                +    * the tripled delimiters used in python, but should work on those regardless
                +    * although in those cases a single string literal may be broken up into
                +    * multiple adjacent string literals.
                +    *
                +    * It recognizes C, C++, and shell style comments.
                +    *
                +    * @param {Object} options a set of optional parameters.
                +    * @return {function (JobT)} a function that examines the source code
                +    *     in the input job and builds a decoration list which it attaches to
                +    *     the job.
                +    */
                +  function sourceDecorator(options) {
                +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
                +    if (options['tripleQuotedStrings']) {
                +      // '''multi-line-string''', 'single-line-string', and double-quoted
                +      shortcutStylePatterns.push(
                +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                +           null, '\'"']);
                +    } else if (options['multiLineStrings']) {
                +      // 'multi-line-string', "multi-line-string"
                +      shortcutStylePatterns.push(
                +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
                +           null, '\'"`']);
                +    } else {
                +      // 'single-line-string', "single-line-string"
                +      shortcutStylePatterns.push(
                +          [PR_STRING,
                +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
                +           null, '"\'']);
                +    }
                +    if (options['verbatimStrings']) {
                +      // verbatim-string-literal production from the C# grammar.  See issue 93.
                +      fallthroughStylePatterns.push(
                +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
                +    }
                +    var hc = options['hashComments'];
                +    if (hc) {
                +      if (options['cStyleComments']) {
                +        if (hc > 1) {  // multiline hash comments
                +          shortcutStylePatterns.push(
                +              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
                +        } else {
                +          // Stop C preprocessor declarations at an unclosed open comment
                +          shortcutStylePatterns.push(
                +              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
                +               null, '#']);
                +        }
                +        // #include <stdio.h>
                +        fallthroughStylePatterns.push(
                +            [PR_STRING,
                +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
                +             null]);
                +      } else {
                +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
                +      }
                +    }
                +    if (options['cStyleComments']) {
                +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
                +      fallthroughStylePatterns.push(
                +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
                +    }
                +    var regexLiterals = options['regexLiterals'];
                +    if (regexLiterals) {
                +      /**
                +       * @const
                +       */
                +      var regexExcls = regexLiterals > 1
                +        ? ''  // Multiline regex literals
                +        : '\n\r';
                +      /**
                +       * @const
                +       */
                +      var regexAny = regexExcls ? '.' : '[\\S\\s]';
                +      /**
                +       * @const
                +       */
                +      var REGEX_LITERAL = (
                +          // A regular expression literal starts with a slash that is
                +          // not followed by * or / so that it is not confused with
                +          // comments.
                +          '/(?=[^/*' + regexExcls + '])'
                +          // and then contains any number of raw characters,
                +          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
                +          // escape sequences (\x5C),
                +          +    '|\\x5C' + regexAny
                +          // or non-nesting character sets (\x5B\x5D);
                +          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
                +          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
                +          // finally closed by a /.
                +          + '/');
                +      fallthroughStylePatterns.push(
                +          ['lang-regex',
                +           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
                +           ]);
                +    }
                +
                +    var types = options['types'];
                +    if (types) {
                +      fallthroughStylePatterns.push([PR_TYPE, types]);
                +    }
                +
                +    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
                +    if (keywords.length) {
                +      fallthroughStylePatterns.push(
                +          [PR_KEYWORD,
                +           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
                +           null]);
                +    }
                +
                +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
                +
                +    var punctuation =
                +      // The Bash man page says
                +
                +      // A word is a sequence of characters considered as a single
                +      // unit by GRUB. Words are separated by metacharacters,
                +      // which are the following plus space, tab, and newline: { }
                +      // | & $ ; < >
                +      // ...
                +
                +      // A word beginning with # causes that word and all remaining
                +      // characters on that line to be ignored.
                +
                +      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
                +      // comment but empirically
                +      // $ echo {#}
                +      // {#}
                +      // $ echo \$#
                +      // $#
                +      // $ echo }#
                +      // }#
                +
                +      // so /(?:^|[|&;<>\s])/ is more appropriate.
                +
                +      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
                +      // suggests that this definition is compatible with a
                +      // default mode that tries to use a single token definition
                +      // to recognize both bash/python style comments and C
                +      // preprocessor directives.
                +
                +      // This definition of punctuation does not include # in the list of
                +      // follow-on exclusions, so # will not be broken before if preceeded
                +      // by a punctuation character.  We could try to exclude # after
                +      // [|&;<>] but that doesn't seem to cause many major problems.
                +      // If that does turn out to be a problem, we should change the below
                +      // when hc is truthy to include # in the run of punctuation characters
                +      // only when not followint [|&;<>].
                +      '^.[^\\s\\w.$@\'"`/\\\\]*';
                +    if (options['regexLiterals']) {
                +      punctuation += '(?!\s*\/)';
                +    }
                +
                +    fallthroughStylePatterns.push(
                +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
                +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
                +        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
                +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
                +        [PR_LITERAL,
                +         new RegExp(
                +             '^(?:'
                +             // A hex number
                +             + '0x[a-f0-9]+'
                +             // or an octal or decimal number,
                +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                +             // possibly in scientific notation
                +             + '(?:e[+\\-]?\\d+)?'
                +             + ')'
                +             // with an optional modifier like UL for unsigned long
                +             + '[a-z]*', 'i'),
                +         null, '0123456789'],
                +        // Don't treat escaped quotes in bash as starting strings.
                +        // See issue 144.
                +        [PR_PLAIN,       /^\\[\s\S]?/, null],
                +        [PR_PUNCTUATION, new RegExp(punctuation), null]);
                +
                +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
                +  }
                +
                +  var decorateSource = sourceDecorator({
                +        'keywords': ALL_KEYWORDS,
                +        'hashComments': true,
                +        'cStyleComments': true,
                +        'multiLineStrings': true,
                +        'regexLiterals': true
                +      });
                +
                +  /**
                +   * Given a DOM subtree, wraps it in a list, and puts each line into its own
                +   * list item.
                +   *
                +   * @param {Node} node modified in place.  Its content is pulled into an
                +   *     HTMLOListElement, and each line is moved into a separate list item.
                +   *     This requires cloning elements, so the input might not have unique
                +   *     IDs after numbering.
                +   * @param {number|null|boolean} startLineNum
                +   *     If truthy, coerced to an integer which is the 1-indexed line number
                +   *     of the first line of code.  The number of the first line will be
                +   *     attached to the list.
                +   * @param {boolean} isPreformatted true iff white-space in text nodes should
                +   *     be treated as significant.
                +   */
                +  function numberLines(node, startLineNum, isPreformatted) {
                +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +    var lineBreak = /\r\n?|\n/;
                +
                +    var document = node.ownerDocument;
                +
                +    var li = document.createElement('li');
                +    while (node.firstChild) {
                +      li.appendChild(node.firstChild);
                +    }
                +    // An array of lines.  We split below, so this is initialized to one
                +    // un-split line.
                +    var listItems = [li];
                +
                +    function walk(node) {
                +      var type = node.nodeType;
                +      if (type == 1 && !nocode.test(node.className)) {  // Element
                +        if ('br' === node.nodeName.toLowerCase()) {
                +          breakAfter(node);
                +          // Discard the <BR> since it is now flush against a </LI>.
                +          if (node.parentNode) {
                +            node.parentNode.removeChild(node);
                +          }
                +        } else {
                +          for (var child = node.firstChild; child; child = child.nextSibling) {
                +            walk(child);
                +          }
                +        }
                +      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
                +        var text = node.nodeValue;
                +        var match = text.match(lineBreak);
                +        if (match) {
                +          var firstLine = text.substring(0, match.index);
                +          node.nodeValue = firstLine;
                +          var tail = text.substring(match.index + match[0].length);
                +          if (tail) {
                +            var parent = node.parentNode;
                +            parent.insertBefore(
                +              document.createTextNode(tail), node.nextSibling);
                +          }
                +          breakAfter(node);
                +          if (!firstLine) {
                +            // Don't leave blank text nodes in the DOM.
                +            node.parentNode.removeChild(node);
                +          }
                +        }
                +      }
                +    }
                +
                +    // Split a line after the given node.
                +    function breakAfter(lineEndNode) {
                +      // If there's nothing to the right, then we can skip ending the line
                +      // here, and move root-wards since splitting just before an end-tag
                +      // would require us to create a bunch of empty copies.
                +      while (!lineEndNode.nextSibling) {
                +        lineEndNode = lineEndNode.parentNode;
                +        if (!lineEndNode) { return; }
                +      }
                +
                +      function breakLeftOf(limit, copy) {
                +        // Clone shallowly if this node needs to be on both sides of the break.
                +        var rightSide = copy ? limit.cloneNode(false) : limit;
                +        var parent = limit.parentNode;
                +        if (parent) {
                +          // We clone the parent chain.
                +          // This helps us resurrect important styling elements that cross lines.
                +          // E.g. in <i>Foo<br>Bar</i>
                +          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
                +          var parentClone = breakLeftOf(parent, 1);
                +          // Move the clone and everything to the right of the original
                +          // onto the cloned parent.
                +          var next = limit.nextSibling;
                +          parentClone.appendChild(rightSide);
                +          for (var sibling = next; sibling; sibling = next) {
                +            next = sibling.nextSibling;
                +            parentClone.appendChild(sibling);
                +          }
                +        }
                +        return rightSide;
                +      }
                +
                +      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
                +
                +      // Walk the parent chain until we reach an unattached LI.
                +      for (var parent;
                +           // Check nodeType since IE invents document fragments.
                +           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
                +        copiedListItem = parent;
                +      }
                +      // Put it on the list of lines for later processing.
                +      listItems.push(copiedListItem);
                +    }
                +
                +    // Split lines while there are lines left to split.
                +    for (var i = 0;  // Number of lines that have been split so far.
                +         i < listItems.length;  // length updated by breakAfter calls.
                +         ++i) {
                +      walk(listItems[i]);
                +    }
                +
                +    // Make sure numeric indices show correctly.
                +    if (startLineNum === (startLineNum|0)) {
                +      listItems[0].setAttribute('value', startLineNum);
                +    }
                +
                +    var ol = document.createElement('ol');
                +    ol.className = 'linenums';
                +    var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
                +    for (var i = 0, n = listItems.length; i < n; ++i) {
                +      li = listItems[i];
                +      // Stick a class on the LIs so that stylesheets can
                +      // color odd/even rows, or any other row pattern that
                +      // is co-prime with 10.
                +      li.className = 'L' + ((i + offset) % 10);
                +      if (!li.firstChild) {
                +        li.appendChild(document.createTextNode('\xA0'));
                +      }
                +      ol.appendChild(li);
                +    }
                +
                +    node.appendChild(ol);
                +  }
                +
                +
                +  /**
                +   * Breaks {@code job.sourceCode} around style boundaries in
                +   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
                +   * @param {JobT} job
                +   * @private
                +   */
                +  function recombineTagsAndDecorations(job) {
                +    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
                +    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
                +    var newlineRe = /\n/g;
                +
                +    var source = job.sourceCode;
                +    var sourceLength = source.length;
                +    // Index into source after the last code-unit recombined.
                +    var sourceIndex = 0;
                +
                +    var spans = job.spans;
                +    var nSpans = spans.length;
                +    // Index into spans after the last span which ends at or before sourceIndex.
                +    var spanIndex = 0;
                +
                +    var decorations = job.decorations;
                +    var nDecorations = decorations.length;
                +    // Index into decorations after the last decoration which ends at or before
                +    // sourceIndex.
                +    var decorationIndex = 0;
                +
                +    // Remove all zero-length decorations.
                +    decorations[nDecorations] = sourceLength;
                +    var decPos, i;
                +    for (i = decPos = 0; i < nDecorations;) {
                +      if (decorations[i] !== decorations[i + 2]) {
                +        decorations[decPos++] = decorations[i++];
                +        decorations[decPos++] = decorations[i++];
                +      } else {
                +        i += 2;
                +      }
                +    }
                +    nDecorations = decPos;
                +
                +    // Simplify decorations.
                +    for (i = decPos = 0; i < nDecorations;) {
                +      var startPos = decorations[i];
                +      // Conflate all adjacent decorations that use the same style.
                +      var startDec = decorations[i + 1];
                +      var end = i + 2;
                +      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
                +        end += 2;
                +      }
                +      decorations[decPos++] = startPos;
                +      decorations[decPos++] = startDec;
                +      i = end;
                +    }
                +
                +    nDecorations = decorations.length = decPos;
                +
                +    var sourceNode = job.sourceNode;
                +    var oldDisplay = "";
                +    if (sourceNode) {
                +      oldDisplay = sourceNode.style.display;
                +      sourceNode.style.display = 'none';
                +    }
                +    try {
                +      var decoration = null;
                +      while (spanIndex < nSpans) {
                +        var spanStart = spans[spanIndex];
                +        var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
                +            || sourceLength;
                +
                +        var decEnd = decorations[decorationIndex + 2] || sourceLength;
                +
                +        var end = Math.min(spanEnd, decEnd);
                +
                +        var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
                +        var styledText;
                +        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
                +            // Don't introduce spans around empty text nodes.
                +            && (styledText = source.substring(sourceIndex, end))) {
                +          // This may seem bizarre, and it is.  Emitting LF on IE causes the
                +          // code to display with spaces instead of line breaks.
                +          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
                +          // space to appear at the beginning of every line but the first.
                +          // Emitting an old Mac OS 9 line separator makes everything spiffy.
                +          if (isIE8OrEarlier) {
                +            styledText = styledText.replace(newlineRe, '\r');
                +          }
                +          textNode.nodeValue = styledText;
                +          var document = textNode.ownerDocument;
                +          var span = document.createElement('span');
                +          span.className = decorations[decorationIndex + 1];
                +          var parentNode = textNode.parentNode;
                +          parentNode.replaceChild(span, textNode);
                +          span.appendChild(textNode);
                +          if (sourceIndex < spanEnd) {  // Split off a text node.
                +            spans[spanIndex + 1] = textNode
                +                // TODO: Possibly optimize by using '' if there's no flicker.
                +                = document.createTextNode(source.substring(end, spanEnd));
                +            parentNode.insertBefore(textNode, span.nextSibling);
                +          }
                +        }
                +
                +        sourceIndex = end;
                +
                +        if (sourceIndex >= spanEnd) {
                +          spanIndex += 2;
                +        }
                +        if (sourceIndex >= decEnd) {
                +          decorationIndex += 2;
                +        }
                +      }
                +    } finally {
                +      if (sourceNode) {
                +        sourceNode.style.display = oldDisplay;
                +      }
                +    }
                +  }
                +
                +
                +  /** Maps language-specific file extensions to handlers. */
                +  var langHandlerRegistry = {};
                +  /** Register a language handler for the given file extensions.
                +    * @param {function (JobT)} handler a function from source code to a list
                +    *      of decorations.  Takes a single argument job which describes the
                +    *      state of the computation and attaches the decorations to it.
                +    * @param {Array.<string>} fileExtensions
                +    */
                +  function registerLangHandler(handler, fileExtensions) {
                +    for (var i = fileExtensions.length; --i >= 0;) {
                +      var ext = fileExtensions[i];
                +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
                +        langHandlerRegistry[ext] = handler;
                +      } else if (win['console']) {
                +        console['warn']('cannot override language handler %s', ext);
                +      }
                +    }
                +  }
                +  function langHandlerForExtension(extension, source) {
                +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
                +      // Treat it as markup if the first non whitespace character is a < and
                +      // the last non-whitespace character is a >.
                +      extension = /^\s*</.test(source)
                +          ? 'default-markup'
                +          : 'default-code';
                +    }
                +    return langHandlerRegistry[extension];
                +  }
                +  registerLangHandler(decorateSource, ['default-code']);
                +  registerLangHandler(
                +      createSimpleLexer(
                +          [],
                +          [
                +           [PR_PLAIN,       /^[^<?]+/],
                +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
                +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
                +           // Unescaped content in an unknown language
                +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
                +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
                +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
                +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
                +           // Unescaped content in javascript.  (Or possibly vbscript).
                +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
                +           // Contains unescaped stylesheet content
                +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
                +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
                +          ]),
                +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
                +  registerLangHandler(
                +      createSimpleLexer(
                +          [
                +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
                +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
                +           ],
                +          [
                +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
                +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
                +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
                +           [PR_PUNCTUATION,  /^[=<>\/]+/],
                +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
                +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
                +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
                +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
                +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
                +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
                +           ]),
                +      ['in.tag']);
                +  registerLangHandler(
                +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': CPP_KEYWORDS,
                +          'hashComments': true,
                +          'cStyleComments': true,
                +          'types': C_TYPES
                +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': 'null,true,false'
                +        }), ['json']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': CSHARP_KEYWORDS,
                +          'hashComments': true,
                +          'cStyleComments': true,
                +          'verbatimStrings': true,
                +          'types': C_TYPES
                +        }), ['cs']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': JAVA_KEYWORDS,
                +          'cStyleComments': true
                +        }), ['java']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': SH_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true
                +        }), ['bash', 'bsh', 'csh', 'sh']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': PYTHON_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'tripleQuotedStrings': true
                +        }), ['cv', 'py', 'python']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': PERL_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'regexLiterals': 2  // multiline regex literals
                +        }), ['perl', 'pl', 'pm']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': RUBY_KEYWORDS,
                +          'hashComments': true,
                +          'multiLineStrings': true,
                +          'regexLiterals': true
                +        }), ['rb', 'ruby']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': JSCRIPT_KEYWORDS,
                +          'cStyleComments': true,
                +          'regexLiterals': true
                +        }), ['javascript', 'js', 'ts', 'typescript']);
                +  registerLangHandler(sourceDecorator({
                +          'keywords': COFFEE_KEYWORDS,
                +          'hashComments': 3,  // ### style block comments
                +          'cStyleComments': true,
                +          'multilineStrings': true,
                +          'tripleQuotedStrings': true,
                +          'regexLiterals': true
                +        }), ['coffee']);
                +  registerLangHandler(
                +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
                +
                +  /** @param {JobT} job */
                +  function applyDecorator(job) {
                +    var opt_langExtension = job.langExtension;
                +
                +    try {
                +      // Extract tags, and convert the source code to plain text.
                +      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
                +      /** Plain text. @type {string} */
                +      var source = sourceAndSpans.sourceCode;
                +      job.sourceCode = source;
                +      job.spans = sourceAndSpans.spans;
                +      job.basePos = 0;
                +
                +      // Apply the appropriate language handler
                +      langHandlerForExtension(opt_langExtension, source)(job);
                +
                +      // Integrate the decorations and tags back into the source code,
                +      // modifying the sourceNode in place.
                +      recombineTagsAndDecorations(job);
                +    } catch (e) {
                +      if (win['console']) {
                +        console['log'](e && e['stack'] || e);
                +      }
                +    }
                +  }
                +
                +  /**
                +   * Pretty print a chunk of code.
                +   * @param sourceCodeHtml {string} The HTML to pretty print.
                +   * @param opt_langExtension {string} The language name to use.
                +   *     Typically, a filename extension like 'cpp' or 'java'.
                +   * @param opt_numberLines {number|boolean} True to number lines,
                +   *     or the 1-indexed number of the first line in sourceCodeHtml.
                +   */
                +  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
                +    /** @type{number|boolean} */
                +    var nl = opt_numberLines || false;
                +    /** @type{string|null} */
                +    var langExtension = opt_langExtension || null;
                +    /** @type{!Element} */
                +    var container = document.createElement('div');
                +    // This could cause images to load and onload listeners to fire.
                +    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
                +    // We assume that the inner HTML is from a trusted source.
                +    // The pre-tag is required for IE8 which strips newlines from innerHTML
                +    // when it is injected into a <pre> tag.
                +    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
                +    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
                +    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
                +    container = /** @type{!Element} */(container.firstChild);
                +    if (nl) {
                +      numberLines(container, nl, true);
                +    }
                +
                +    /** @type{JobT} */
                +    var job = {
                +      langExtension: langExtension,
                +      numberLines: nl,
                +      sourceNode: container,
                +      pre: 1,
                +      sourceCode: null,
                +      basePos: null,
                +      spans: null,
                +      decorations: null
                +    };
                +    applyDecorator(job);
                +    return container.innerHTML;
                +  }
                +
                +   /**
                +    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                +    * {@code class=prettyprint} and prettify them.
                +    *
                +    * @param {Function} opt_whenDone called when prettifying is done.
                +    * @param {HTMLElement|HTMLDocument} opt_root an element or document
                +    *   containing all the elements to pretty print.
                +    *   Defaults to {@code document.body}.
                +    */
                +  function $prettyPrint(opt_whenDone, opt_root) {
                +    var root = opt_root || document.body;
                +    var doc = root.ownerDocument || document;
                +    function byTagName(tn) { return root.getElementsByTagName(tn); }
                +    // fetch a list of nodes to rewrite
                +    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
                +    var elements = [];
                +    for (var i = 0; i < codeSegments.length; ++i) {
                +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
                +        elements.push(codeSegments[i][j]);
                +      }
                +    }
                +    codeSegments = null;
                +
                +    var clock = Date;
                +    if (!clock['now']) {
                +      clock = { 'now': function () { return +(new Date); } };
                +    }
                +
                +    // The loop is broken into a series of continuations to make sure that we
                +    // don't make the browser unresponsive when rewriting a large page.
                +    var k = 0;
                +
                +    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
                +    var prettyPrintRe = /\bprettyprint\b/;
                +    var prettyPrintedRe = /\bprettyprinted\b/;
                +    var preformattedTagNameRe = /pre|xmp/i;
                +    var codeRe = /^code$/i;
                +    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
                +    var EMPTY = {};
                +
                +    function doWork() {
                +      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
                +                     clock['now']() + 250 /* ms */ :
                +                     Infinity);
                +      for (; k < elements.length && clock['now']() < endTime; k++) {
                +        var cs = elements[k];
                +
                +        // Look for a preceding comment like
                +        // <?prettify lang="..." linenums="..."?>
                +        var attrs = EMPTY;
                +        {
                +          for (var preceder = cs; (preceder = preceder.previousSibling);) {
                +            var nt = preceder.nodeType;
                +            // <?foo?> is parsed by HTML 5 to a comment node (8)
                +            // like <!--?foo?-->, but in XML is a processing instruction
                +            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
                +            if (value
                +                ? !/^\??prettify\b/.test(value)
                +                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
                +              // Skip over white-space text nodes but not others.
                +              break;
                +            }
                +            if (value) {
                +              attrs = {};
                +              value.replace(
                +                  /\b(\w+)=([\w:.%+-]+)/g,
                +                function (_, name, value) { attrs[name] = value; });
                +              break;
                +            }
                +          }
                +        }
                +
                +        var className = cs.className;
                +        if ((attrs !== EMPTY || prettyPrintRe.test(className))
                +            // Don't redo this if we've already done it.
                +            // This allows recalling pretty print to just prettyprint elements
                +            // that have been added to the page since last call.
                +            && !prettyPrintedRe.test(className)) {
                +
                +          // make sure this is not nested in an already prettified element
                +          var nested = false;
                +          for (var p = cs.parentNode; p; p = p.parentNode) {
                +            var tn = p.tagName;
                +            if (preCodeXmpRe.test(tn)
                +                && p.className && prettyPrintRe.test(p.className)) {
                +              nested = true;
                +              break;
                +            }
                +          }
                +          if (!nested) {
                +            // Mark done.  If we fail to prettyprint for whatever reason,
                +            // we shouldn't try again.
                +            cs.className += ' prettyprinted';
                +
                +            // If the classes includes a language extensions, use it.
                +            // Language extensions can be specified like
                +            //     <pre class="prettyprint lang-cpp">
                +            // the language extension "cpp" is used to find a language handler
                +            // as passed to PR.registerLangHandler.
                +            // HTML5 recommends that a language be specified using "language-"
                +            // as the prefix instead.  Google Code Prettify supports both.
                +            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
                +            var langExtension = attrs['lang'];
                +            if (!langExtension) {
                +              langExtension = className.match(langExtensionRe);
                +              // Support <pre class="prettyprint"><code class="language-c">
                +              var wrapper;
                +              if (!langExtension && (wrapper = childContentWrapper(cs))
                +                  && codeRe.test(wrapper.tagName)) {
                +                langExtension = wrapper.className.match(langExtensionRe);
                +              }
                +
                +              if (langExtension) { langExtension = langExtension[1]; }
                +            }
                +
                +            var preformatted;
                +            if (preformattedTagNameRe.test(cs.tagName)) {
                +              preformatted = 1;
                +            } else {
                +              var currentStyle = cs['currentStyle'];
                +              var defaultView = doc.defaultView;
                +              var whitespace = (
                +                  currentStyle
                +                  ? currentStyle['whiteSpace']
                +                  : (defaultView
                +                     && defaultView.getComputedStyle)
                +                  ? defaultView.getComputedStyle(cs, null)
                +                  .getPropertyValue('white-space')
                +                  : 0);
                +              preformatted = whitespace
                +                  && 'pre' === whitespace.substring(0, 3);
                +            }
                +
                +            // Look for a class like linenums or linenums:<n> where <n> is the
                +            // 1-indexed number of the first line.
                +            var lineNums = attrs['linenums'];
                +            if (!(lineNums = lineNums === 'true' || +lineNums)) {
                +              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
                +              lineNums =
                +                lineNums
                +                ? lineNums[1] && lineNums[1].length
                +                  ? +lineNums[1] : true
                +                : false;
                +            }
                +            if (lineNums) { numberLines(cs, lineNums, preformatted); }
                +
                +            // do the pretty printing
                +            var prettyPrintingJob = {
                +              langExtension: langExtension,
                +              sourceNode: cs,
                +              numberLines: lineNums,
                +              pre: preformatted,
                +              sourceCode: null,
                +              basePos: null,
                +              spans: null,
                +              decorations: null
                +            };
                +            applyDecorator(prettyPrintingJob);
                +          }
                +        }
                +      }
                +      if (k < elements.length) {
                +        // finish up in a continuation
                +        win.setTimeout(doWork, 250);
                +      } else if ('function' === typeof opt_whenDone) {
                +        opt_whenDone();
                +      }
                +    }
                +
                +    doWork();
                +  }
                +
                +  /**
                +   * Contains functions for creating and registering new language handlers.
                +   * @type {Object}
                +   */
                +  var PR = win['PR'] = {
                +        'createSimpleLexer': createSimpleLexer,
                +        'registerLangHandler': registerLangHandler,
                +        'sourceDecorator': sourceDecorator,
                +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
                +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
                +        'PR_COMMENT': PR_COMMENT,
                +        'PR_DECLARATION': PR_DECLARATION,
                +        'PR_KEYWORD': PR_KEYWORD,
                +        'PR_LITERAL': PR_LITERAL,
                +        'PR_NOCODE': PR_NOCODE,
                +        'PR_PLAIN': PR_PLAIN,
                +        'PR_PUNCTUATION': PR_PUNCTUATION,
                +        'PR_SOURCE': PR_SOURCE,
                +        'PR_STRING': PR_STRING,
                +        'PR_TAG': PR_TAG,
                +        'PR_TYPE': PR_TYPE,
                +        'prettyPrintOne':
                +           IN_GLOBAL_SCOPE
                +             ? (win['prettyPrintOne'] = $prettyPrintOne)
                +             : (prettyPrintOne = $prettyPrintOne),
                +        'prettyPrint':
                +           IN_GLOBAL_SCOPE
                +             ? (win['prettyPrint'] = $prettyPrint)
                +             : (prettyPrint = $prettyPrint)
                +      };
                +
                +  // Make PR available via the Asynchronous Module Definition (AMD) API.
                +  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
                +  // The Asynchronous Module Definition (AMD) API specifies a
                +  // mechanism for defining modules such that the module and its
                +  // dependencies can be asynchronously loaded.
                +  // ...
                +  // To allow a clear indicator that a global define function (as
                +  // needed for script src browser loading) conforms to the AMD API,
                +  // any global define function SHOULD have a property called "amd"
                +  // whose value is an object. This helps avoid conflict with any
                +  // other existing JavaScript code that could have defined a define()
                +  // function that does not conform to the AMD API.
                +  var define = win['define'];
                +  if (typeof define === "function" && define['amd']) {
                +    define("google-code-prettify", [], function () {
                +      return PR;
                +    });
                +  }
                +})();
                diff --git a/backend/webif/static/js/google-prettify/run_prettify.js b/backend/webif/static/js/google-prettify/run_prettify.js
                new file mode 100755
                index 000000000..93e3fece7
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/run_prettify.js
                @@ -0,0 +1,2008 @@
                +/**
                + * @license
                + * Copyright (C) 2013 Google Inc.
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *      http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview
                + * <div style="white-space: pre">
                + * Looks at query parameters to decide which language handlers and style-sheets
                + * to load.
                + *
                + * Query Parameter     Format           Effect                        Default
                + * +------------------+---------------+------------------------------+--------+
                + * | autorun=         | true | false  | If true then prettyPrint()   | "true" |
                + * |                  |               | is called on page load.      |        |
                + * +------------------+---------------+------------------------------+--------+
                + * | lang=            | language name | Loads the language handler   | Can    |
                + * |                  |               | named "lang-<NAME>.js".      | appear |
                + * |                  |               | See available handlers at    | many   |
                + * |                  |               | https://github.com/google/   | times. |
                + * |                  |               | code-prettify/tree/master/   |        |
                + * |                  |               | src                          |        |
                + * +------------------+---------------+------------------------------+--------+
                + * | skin=            | skin name     | Loads the skin stylesheet    | none.  |
                + * |                  |               | named "<NAME>.css".          |        |
                + * |                  |               | https://cdn.rawgit.com/      |        |
                + * |                  |               | google/code-prettify/master/ |        |
                + * |                  |               | styles/index.html            |        |
                + * +------------------+---------------+------------------------------+--------+
                + * | callback=        | JS identifier | When "prettyPrint" finishes  | none   |
                + * |                  |               | window.exports[js_ident] is  |        |
                + * |                  |               | called.                      |        |
                + * |                  |               | The callback must be under   |        |
                + * |                  |               | exports to reduce the risk   |        |
                + * |                  |               | of XSS via query parameter   |        |
                + * |                  |               | injection.                   |        |
                + * +------------------+---------------+------------------------------+--------+
                + *
                + * Examples
                + * .../run_prettify.js?lang=css&skin=sunburst
                + *   1. Loads the CSS language handler which can be used to prettify CSS
                + *      stylesheets, HTML <style> element bodies and style="..." attributes
                + *      values.
                + *   2. Loads the sunburst.css stylesheet instead of the default prettify.css
                + *      stylesheet.
                + *      A gallery of stylesheets is available at
                + *      https://cdn.rawgit.com/google/code-prettify/master/styles/index.html
                + *   3. Since autorun=false is not specified, calls prettyPrint() on page load.
                + * </div>
                + */
                +
                +/**
                + * @typedef {!Array.<number|string>}
                + * Alternating indices and the decorations that should be inserted there.
                + * The indices are monotonically increasing.
                + */
                +var DecorationsT;
                +
                +/**
                + * @typedef {!{
                + *   sourceNode: !Element,
                + *   pre: !(number|boolean),
                + *   langExtension: ?string,
                + *   numberLines: ?(number|boolean),
                + *   sourceCode: ?string,
                + *   spans: ?(Array.<number|Node>),
                + *   basePos: ?number,
                + *   decorations: ?DecorationsT
                + * }}
                + * <dl>
                + *  <dt>sourceNode<dd>the element containing the source
                + *  <dt>sourceCode<dd>source as plain text
                + *  <dt>pre<dd>truthy if white-space in text nodes
                + *     should be considered significant.
                + *  <dt>spans<dd> alternating span start indices into source
                + *     and the text node or element (e.g. {@code <BR>}) corresponding to that
                + *     span.
                + *  <dt>decorations<dd>an array of style classes preceded
                + *     by the position at which they start in job.sourceCode in order
                + *  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
                + *     source.
                + * </dl>
                + */
                +var JobT;
                +
                +/**
                + * @typedef {!{
                + *   sourceCode: string,
                + *   spans: !(Array.<number|Node>)
                + * }}
                + * <dl>
                + *  <dt>sourceCode<dd>source as plain text
                + *  <dt>spans<dd> alternating span start indices into source
                + *     and the text node or element (e.g. {@code <BR>}) corresponding to that
                + *     span.
                + * </dl>
                + */
                +var SourceSpansT;
                +
                +/** @define {boolean} */
                +var IN_GLOBAL_SCOPE = false;
                +
                +
                +(function () {
                +  "use strict";
                +
                +  var win = window;
                +  var doc = document;
                +  var root = doc.documentElement;
                +  var head = doc['head'] || doc.getElementsByTagName("head")[0] || root;
                +
                +  // From http://javascript.nwbox.com/ContentLoaded/contentloaded.js
                +  // Author: Diego Perini (diego.perini at gmail.com)
                +  // Summary: cross-browser wrapper for DOMContentLoaded
                +  // Updated: 20101020
                +  // License: MIT
                +  // Version: 1.2
                +  function contentLoaded(callback) {
                +    var addEventListener = doc['addEventListener'];
                +    var done = false, top = true,
                +        add = addEventListener ? 'addEventListener' : 'attachEvent',
                +        rem = addEventListener ? 'removeEventListener' : 'detachEvent',
                +        pre = addEventListener ? '' : 'on',
                +
                +        init = function(e) {
                +          if (e.type == 'readystatechange' && doc.readyState != 'complete') {
                +            return;
                +          }
                +          (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
                +          if (!done && (done = true)) { callback.call(win, e.type || e); }
                +        },
                +
                +        poll = function() {
                +          try {
                +            root.doScroll('left');
                +          } catch(e) {
                +            win.setTimeout(poll, 50);
                +            return;
                +          }
                +          init('poll');
                +        };
                +
                +    if (doc.readyState == 'complete') {
                +      callback.call(win, 'lazy');
                +    } else {
                +      if (doc.createEventObject && root.doScroll) {
                +        try { top = !win.frameElement; } catch(e) { }
                +        if (top) { poll(); }
                +      }
                +      doc[add](pre + 'DOMContentLoaded', init, false);
                +      doc[add](pre + 'readystatechange', init, false);
                +      win[add](pre + 'load', init, false);
                +    }
                +  }
                +
                +  // Given a list of URLs to stylesheets, loads the first that loads without
                +  // triggering an error event.
                +  function loadStylesheetsFallingBack(stylesheets) {
                +    var n = stylesheets.length;
                +    function load(i) {
                +      if (i === n) { return; }
                +      var link = doc.createElement('link');
                +      link.rel = 'stylesheet';
                +      link.type = 'text/css';
                +      if (i + 1 < n) {
                +        // http://pieisgood.org/test/script-link-events/ indicates that many
                +        // versions of IE do not support onerror on <link>s, though
                +        // http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx
                +        // indicates that recent IEs do support error.
                +        link.error = link.onerror = function () { load(i + 1); };
                +      }
                +      link.href = stylesheets[i];
                +      head.appendChild(link);
                +    }
                +    load(0);
                +  }
                +
                +  var scriptQuery = '';
                +  // Look for the <script> node that loads this script to get its parameters.
                +  // This starts looking at the end instead of just considering the last
                +  // because deferred and async scripts run out of order.
                +  // If the script is loaded twice, then this will run in reverse order.
                +  var scripts = doc.getElementsByTagName('script');
                +  for (var i = scripts.length; --i >= 0;) {
                +    var script = scripts[i];
                +    var match = script.src.match(
                +        /^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);
                +    if (match) {
                +      scriptQuery = match[1] || '';
                +      // Remove the script from the DOM so that multiple runs at least run
                +      // multiple times even if parameter sets are interpreted in reverse
                +      // order.
                +      script.parentNode.removeChild(script);
                +      break;
                +    }
                +  }
                +
                +  // Pull parameters into local variables.
                +  var autorun = true;
                +  var langs = [];
                +  var skins = [];
                +  var callbacks = [];
                +  scriptQuery.replace(
                +      /[?&]([^&=]+)=([^&]+)/g,
                +      function (_, name, value) {
                +        value = decodeURIComponent(value);
                +        name = decodeURIComponent(name);
                +        if (name == 'autorun')   { autorun = !/^[0fn]/i.test(value); } else
                +        if (name == 'lang')      { langs.push(value);                } else
                +        if (name == 'skin')      { skins.push(value);                } else
                +        if (name == 'callback')  { callbacks.push(value);            }
                +      });
                +
                +  // Use https to avoid mixed content warnings in client pages and to
                +  // prevent a MITM from rewrite prettify mid-flight.
                +  // This only works if this script is loaded via https : something
                +  // over which we exercise no control.
                +  var LOADER_BASE_URL =
                +     'https://cdn.rawgit.com/google/code-prettify/master/loader';
                +
                +  for (var i = 0, n = langs.length; i < n; ++i) (function (lang) {
                +    var script = doc.createElement("script");
                +
                +    // Excerpted from jQuery.ajaxTransport("script") to fire events when
                +    // a script is finished loading.
                +    // Attach handlers for each script
                +    script.onload = script.onerror = script.onreadystatechange = function () {
                +      if (script && (
                +            !script.readyState || /loaded|complete/.test(script.readyState))) {
                +        // Handle memory leak in IE
                +        script.onerror = script.onload = script.onreadystatechange = null;
                +
                +        --pendingLanguages;
                +        checkPendingLanguages();
                +
                +        // Remove the script
                +        if (script.parentNode) {
                +          script.parentNode.removeChild(script);
                +        }
                +
                +        script = null;
                +      }
                +    };
                +
                +    script.type = 'text/javascript';
                +    script.src = LOADER_BASE_URL
                +      + '/lang-' + encodeURIComponent(langs[i]) + '.js';
                +
                +    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
                +    head.insertBefore(script, head.firstChild);
                +  })(langs[i]);
                +
                +  var pendingLanguages = langs.length;
                +  function checkPendingLanguages() {
                +    if (!pendingLanguages) {
                +      win.setTimeout(onLangsLoaded, 0);
                +    }
                +  }
                +
                +  var skinUrls = [];
                +  for (var i = 0, n = skins.length; i < n; ++i) {
                +    skinUrls.push(LOADER_BASE_URL
                +        + '/skins/' + encodeURIComponent(skins[i]) + '.css');
                +  }
                +  skinUrls.push(LOADER_BASE_URL + '/prettify.css');
                +  loadStylesheetsFallingBack(skinUrls);
                +
                +  var prettyPrint = (function () {
                +    /**
                +     * @license
                +     * Copyright (C) 2006 Google Inc.
                +     *
                +     * Licensed under the Apache License, Version 2.0 (the "License");
                +     * you may not use this file except in compliance with the License.
                +     * You may obtain a copy of the License at
                +     *
                +     *      http://www.apache.org/licenses/LICENSE-2.0
                +     *
                +     * Unless required by applicable law or agreed to in writing, software
                +     * distributed under the License is distributed on an "AS IS" BASIS,
                +     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +     * See the License for the specific language governing permissions and
                +     * limitations under the License.
                +     */
                +
                +    /**
                +     * @fileoverview
                +     * some functions for browser-side pretty printing of code contained in html.
                +     *
                +     * <p>
                +     * For a fairly comprehensive set of languages see the
                +     * <a href="https://github.com/google/code-prettify#for-which-languages-does-it-work">README</a>
                +     * file that came with this source.  At a minimum, the lexer should work on a
                +     * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
                +     * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
                +     * and a subset of Perl, but, because of commenting conventions, doesn't work on
                +     * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
                +     * <p>
                +     * Usage: <ol>
                +     * <li> include this source file in an html page via
                +     *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
                +     * <li> define style rules.  See the example page for examples.
                +     * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
                +     *    {@code class=prettyprint.}
                +     *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
                +     *    printer needs to do more substantial DOM manipulations to support that, so
                +     *    some css styles may not be preserved.
                +     * </ol>
                +     * That's it.  I wanted to keep the API as simple as possible, so there's no
                +     * need to specify which language the code is in, but if you wish, you can add
                +     * another class to the {@code <pre>} or {@code <code>} element to specify the
                +     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
                +     * starts with "lang-" followed by a file extension, specifies the file type.
                +     * See the "lang-*.js" files in this directory for code that implements
                +     * per-language file handlers.
                +     * <p>
                +     * Change log:<br>
                +     * cbeust, 2006/08/22
                +     * <blockquote>
                +     *   Java annotations (start with "@") are now captured as literals ("lit")
                +     * </blockquote>
                +     * @requires console
                +     */
                +
                +    // JSLint declarations
                +    /*global console, document, navigator, setTimeout, window, define */
                +
                +
                +    /**
                +     * {@type !{
                +     *   'createSimpleLexer': function (Array, Array): (function (JobT)),
                +     *   'registerLangHandler': function (function (JobT), Array.<string>),
                +     *   'PR_ATTRIB_NAME': string,
                +     *   'PR_ATTRIB_NAME': string,
                +     *   'PR_ATTRIB_VALUE': string,
                +     *   'PR_COMMENT': string,
                +     *   'PR_DECLARATION': string,
                +     *   'PR_KEYWORD': string,
                +     *   'PR_LITERAL': string,
                +     *   'PR_NOCODE': string,
                +     *   'PR_PLAIN': string,
                +     *   'PR_PUNCTUATION': string,
                +     *   'PR_SOURCE': string,
                +     *   'PR_STRING': string,
                +     *   'PR_TAG': string,
                +     *   'PR_TYPE': string,
                +     *   'prettyPrintOne': function (string, string, number|boolean),
                +     *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
                +     * }}
                +     * @const
                +     */
                +    var PR;
                +
                +    /**
                +     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
                +     * UI events.
                +     * If set to {@code false}, {@code prettyPrint()} is synchronous.
                +     */
                +    var PR_SHOULD_USE_CONTINUATION = true
                +    if (typeof window !== 'undefined') {
                +      window['PR_SHOULD_USE_CONTINUATION'] = PR_SHOULD_USE_CONTINUATION;
                +    }
                +
                +    /**
                +     * Pretty print a chunk of code.
                +     * @param {string} sourceCodeHtml The HTML to pretty print.
                +     * @param {string} opt_langExtension The language name to use.
                +     *     Typically, a filename extension like 'cpp' or 'java'.
                +     * @param {number|boolean} opt_numberLines True to number lines,
                +     *     or the 1-indexed number of the first line in sourceCodeHtml.
                +     * @return {string} code as html, but prettier
                +     */
                +    var prettyPrintOne;
                +    /**
                +     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                +     * {@code class=prettyprint} and prettify them.
                +     *
                +     * @param {Function} opt_whenDone called when prettifying is done.
                +     * @param {HTMLElement|HTMLDocument} opt_root an element or document
                +     *   containing all the elements to pretty print.
                +     *   Defaults to {@code document.body}.
                +     */
                +    var prettyPrint;
                +
                +
                +    (function () {
                +      var win = (typeof window !== 'undefined') ? window : {};
                +      // Keyword lists for various languages.
                +      // We use things that coerce to strings to make them compact when minified
                +      // and to defeat aggressive optimizers that fold large string constants.
                +      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
                +      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
                +          "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
                +          "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
                +      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
                +          "new,operator,private,protected,public,this,throw,true,try,typeof"];
                +      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
                +          "concept,concept_map,const_cast,constexpr,decltype,delegate," +
                +          "dynamic_cast,explicit,export,friend,generic,late_check," +
                +          "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
                +          "static_cast,template,typeid,typename,using,virtual,where"];
                +      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
                +          "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
                +          "instanceof,interface,null,native,package,strictfp,super,synchronized," +
                +          "throws,transient"];
                +      var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
                +          "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
                +          "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
                +          "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
                +          "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
                +          "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
                +      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
                +          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
                +          "throw,true,try,unless,until,when,while,yes";
                +      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
                +          "abstract,async,await,constructor,debugger,enum,eval,export,function," +
                +          "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
                +          "yield,Infinity,NaN"];
                +      var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
                +          "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
                +          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
                +      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
                +          "elif,except,exec,finally,from,global,import,in,is,lambda," +
                +          "nonlocal,not,or,pass,print,raise,try,with,yield," +
                +          "False,True,None"];
                +      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
                +          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
                +          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
                +          "BEGIN,END"];
                +      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
                +          "function,in,local,set,then,until"];
                +      var ALL_KEYWORDS = [
                +          CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
                +          PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
                +      var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
                +
                +      // token style names.  correspond to css classes
                +      /**
                +       * token style for a string literal
                +       * @const
                +       */
                +      var PR_STRING = 'str';
                +      /**
                +       * token style for a keyword
                +       * @const
                +       */
                +      var PR_KEYWORD = 'kwd';
                +      /**
                +       * token style for a comment
                +       * @const
                +       */
                +      var PR_COMMENT = 'com';
                +      /**
                +       * token style for a type
                +       * @const
                +       */
                +      var PR_TYPE = 'typ';
                +      /**
                +       * token style for a literal value.  e.g. 1, null, true.
                +       * @const
                +       */
                +      var PR_LITERAL = 'lit';
                +      /**
                +       * token style for a punctuation string.
                +       * @const
                +       */
                +      var PR_PUNCTUATION = 'pun';
                +      /**
                +       * token style for plain text.
                +       * @const
                +       */
                +      var PR_PLAIN = 'pln';
                +
                +      /**
                +       * token style for an sgml tag.
                +       * @const
                +       */
                +      var PR_TAG = 'tag';
                +      /**
                +       * token style for a markup declaration such as a DOCTYPE.
                +       * @const
                +       */
                +      var PR_DECLARATION = 'dec';
                +      /**
                +       * token style for embedded source.
                +       * @const
                +       */
                +      var PR_SOURCE = 'src';
                +      /**
                +       * token style for an sgml attribute name.
                +       * @const
                +       */
                +      var PR_ATTRIB_NAME = 'atn';
                +      /**
                +       * token style for an sgml attribute value.
                +       * @const
                +       */
                +      var PR_ATTRIB_VALUE = 'atv';
                +
                +      /**
                +       * A class that indicates a section of markup that is not code, e.g. to allow
                +       * embedding of line numbers within code listings.
                +       * @const
                +       */
                +      var PR_NOCODE = 'nocode';
                +
                +
                +      // Regex pattern below is automatically generated by regexpPrecederPatterns.pl
                +      // Do not modify, your changes will be erased.
                +
                +      // CAVEAT: this does not properly handle the case where a regular
                +      // expression immediately follows another since a regular expression may
                +      // have flags for case-sensitivity and the like.  Having regexp tokens
                +      // adjacent is not valid in any language I'm aware of, so I'm punting.
                +      // TODO: maybe style special characters inside a regexp as punctuation.
                +
                +      /**
                +       * A set of tokens that can precede a regular expression literal in
                +       * javascript
                +       * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
                +       * has the full list, but I've removed ones that might be problematic when
                +       * seen in languages that don't support regular expression literals.
                +       *
                +       * Specifically, I've removed any keywords that can't precede a regexp
                +       * literal in a syntactically legal javascript program, and I've removed the
                +       * "in" keyword since it's not a keyword in many languages, and might be used
                +       * as a count of inches.
                +       *
                +       * The link above does not accurately describe EcmaScript rules since
                +       * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
                +       * very well in practice.
                +       *
                +       * @private
                +       * @const
                +       */
                +      var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
                +
                +
                +      /**
                +       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
                +       * matches the union of the sets of strings matched by the input RegExp.
                +       * Since it matches globally, if the input strings have a start-of-input
                +       * anchor (/^.../), it is ignored for the purposes of unioning.
                +       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
                +       * @return {RegExp} a global regex.
                +       */
                +      function combinePrefixPatterns(regexs) {
                +        var capturedGroupIndex = 0;
                +
                +        var needToFoldCase = false;
                +        var ignoreCase = false;
                +        for (var i = 0, n = regexs.length; i < n; ++i) {
                +          var regex = regexs[i];
                +          if (regex.ignoreCase) {
                +            ignoreCase = true;
                +          } else if (/[a-z]/i.test(regex.source.replace(
                +                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
                +            needToFoldCase = true;
                +            ignoreCase = false;
                +            break;
                +          }
                +        }
                +
                +        var escapeCharToCodeUnit = {
                +          'b': 8,
                +          't': 9,
                +          'n': 0xa,
                +          'v': 0xb,
                +          'f': 0xc,
                +          'r': 0xd
                +        };
                +
                +        function decodeEscape(charsetPart) {
                +          var cc0 = charsetPart.charCodeAt(0);
                +          if (cc0 !== 92 /* \\ */) {
                +            return cc0;
                +          }
                +          var c1 = charsetPart.charAt(1);
                +          cc0 = escapeCharToCodeUnit[c1];
                +          if (cc0) {
                +            return cc0;
                +          } else if ('0' <= c1 && c1 <= '7') {
                +            return parseInt(charsetPart.substring(1), 8);
                +          } else if (c1 === 'u' || c1 === 'x') {
                +            return parseInt(charsetPart.substring(2), 16);
                +          } else {
                +            return charsetPart.charCodeAt(1);
                +          }
                +        }
                +
                +        function encodeEscape(charCode) {
                +          if (charCode < 0x20) {
                +            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
                +          }
                +          var ch = String.fromCharCode(charCode);
                +          return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
                +              ? "\\" + ch : ch;
                +        }
                +
                +        function caseFoldCharset(charSet) {
                +          var charsetParts = charSet.substring(1, charSet.length - 1).match(
                +              new RegExp(
                +                  '\\\\u[0-9A-Fa-f]{4}'
                +                  + '|\\\\x[0-9A-Fa-f]{2}'
                +                  + '|\\\\[0-3][0-7]{0,2}'
                +                  + '|\\\\[0-7]{1,2}'
                +                  + '|\\\\[\\s\\S]'
                +                  + '|-'
                +                  + '|[^-\\\\]',
                +                  'g'));
                +          var ranges = [];
                +          var inverse = charsetParts[0] === '^';
                +
                +          var out = ['['];
                +          if (inverse) { out.push('^'); }
                +
                +          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
                +            var p = charsetParts[i];
                +            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
                +              out.push(p);
                +            } else {
                +              var start = decodeEscape(p);
                +              var end;
                +              if (i + 2 < n && '-' === charsetParts[i + 1]) {
                +                end = decodeEscape(charsetParts[i + 2]);
                +                i += 2;
                +              } else {
                +                end = start;
                +              }
                +              ranges.push([start, end]);
                +              // If the range might intersect letters, then expand it.
                +              // This case handling is too simplistic.
                +              // It does not deal with non-latin case folding.
                +              // It works for latin source code identifiers though.
                +              if (!(end < 65 || start > 122)) {
                +                if (!(end < 65 || start > 90)) {
                +                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                +                }
                +                if (!(end < 97 || start > 122)) {
                +                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                +                }
                +              }
                +            }
                +          }
                +
                +          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
                +          // -> [[1, 12], [14, 14], [16, 17]]
                +          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
                +          var consolidatedRanges = [];
                +          var lastRange = [];
                +          for (var i = 0; i < ranges.length; ++i) {
                +            var range = ranges[i];
                +            if (range[0] <= lastRange[1] + 1) {
                +              lastRange[1] = Math.max(lastRange[1], range[1]);
                +            } else {
                +              consolidatedRanges.push(lastRange = range);
                +            }
                +          }
                +
                +          for (var i = 0; i < consolidatedRanges.length; ++i) {
                +            var range = consolidatedRanges[i];
                +            out.push(encodeEscape(range[0]));
                +            if (range[1] > range[0]) {
                +              if (range[1] + 1 > range[0]) { out.push('-'); }
                +              out.push(encodeEscape(range[1]));
                +            }
                +          }
                +          out.push(']');
                +          return out.join('');
                +        }
                +
                +        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
                +          // Split into character sets, escape sequences, punctuation strings
                +          // like ('(', '(?:', ')', '^'), and runs of characters that do not
                +          // include any of the above.
                +          var parts = regex.source.match(
                +              new RegExp(
                +                  '(?:'
                +                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                +                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                +                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                +                  + '|\\\\[0-9]+'  // a back-reference or octal escape
                +                  + '|\\\\[^ux0-9]'  // other escape sequence
                +                  + '|\\(\\?[:!=]'  // start of a non-capturing group
                +                  + '|[\\(\\)\\^]'  // start/end of a group, or line start
                +                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                +                  + ')',
                +                  'g'));
                +          var n = parts.length;
                +
                +          // Maps captured group numbers to the number they will occupy in
                +          // the output or to -1 if that has not been determined, or to
                +          // undefined if they need not be capturing in the output.
                +          var capturedGroups = [];
                +
                +          // Walk over and identify back references to build the capturedGroups
                +          // mapping.
                +          for (var i = 0, groupIndex = 0; i < n; ++i) {
                +            var p = parts[i];
                +            if (p === '(') {
                +              // groups are 1-indexed, so max group index is count of '('
                +              ++groupIndex;
                +            } else if ('\\' === p.charAt(0)) {
                +              var decimalValue = +p.substring(1);
                +              if (decimalValue) {
                +                if (decimalValue <= groupIndex) {
                +                  capturedGroups[decimalValue] = -1;
                +                } else {
                +                  // Replace with an unambiguous escape sequence so that
                +                  // an octal escape sequence does not turn into a backreference
                +                  // to a capturing group from an earlier regex.
                +                  parts[i] = encodeEscape(decimalValue);
                +                }
                +              }
                +            }
                +          }
                +
                +          // Renumber groups and reduce capturing groups to non-capturing groups
                +          // where possible.
                +          for (var i = 1; i < capturedGroups.length; ++i) {
                +            if (-1 === capturedGroups[i]) {
                +              capturedGroups[i] = ++capturedGroupIndex;
                +            }
                +          }
                +          for (var i = 0, groupIndex = 0; i < n; ++i) {
                +            var p = parts[i];
                +            if (p === '(') {
                +              ++groupIndex;
                +              if (!capturedGroups[groupIndex]) {
                +                parts[i] = '(?:';
                +              }
                +            } else if ('\\' === p.charAt(0)) {
                +              var decimalValue = +p.substring(1);
                +              if (decimalValue && decimalValue <= groupIndex) {
                +                parts[i] = '\\' + capturedGroups[decimalValue];
                +              }
                +            }
                +          }
                +
                +          // Remove any prefix anchors so that the output will match anywhere.
                +          // ^^ really does mean an anchored match though.
                +          for (var i = 0; i < n; ++i) {
                +            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
                +          }
                +
                +          // Expand letters to groups to handle mixing of case-sensitive and
                +          // case-insensitive patterns if necessary.
                +          if (regex.ignoreCase && needToFoldCase) {
                +            for (var i = 0; i < n; ++i) {
                +              var p = parts[i];
                +              var ch0 = p.charAt(0);
                +              if (p.length >= 2 && ch0 === '[') {
                +                parts[i] = caseFoldCharset(p);
                +              } else if (ch0 !== '\\') {
                +                // TODO: handle letters in numeric escapes.
                +                parts[i] = p.replace(
                +                    /[a-zA-Z]/g,
                +                    function (ch) {
                +                      var cc = ch.charCodeAt(0);
                +                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                +                    });
                +              }
                +            }
                +          }
                +
                +          return parts.join('');
                +        }
                +
                +        var rewritten = [];
                +        for (var i = 0, n = regexs.length; i < n; ++i) {
                +          var regex = regexs[i];
                +          if (regex.global || regex.multiline) { throw new Error('' + regex); }
                +          rewritten.push(
                +              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
                +        }
                +
                +        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
                +      }
                +
                +
                +      /**
                +       * Split markup into a string of source code and an array mapping ranges in
                +       * that string to the text nodes in which they appear.
                +       *
                +       * <p>
                +       * The HTML DOM structure:</p>
                +       * <pre>
                +       * (Element   "p"
                +       *   (Element "b"
                +       *     (Text  "print "))       ; #1
                +       *   (Text    "'Hello '")      ; #2
                +       *   (Element "br")            ; #3
                +       *   (Text    "  + 'World';")) ; #4
                +       * </pre>
                +       * <p>
                +       * corresponds to the HTML
                +       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
                +       *
                +       * <p>
                +       * It will produce the output:</p>
                +       * <pre>
                +       * {
                +       *   sourceCode: "print 'Hello '\n  + 'World';",
                +       *   //                     1          2
                +       *   //           012345678901234 5678901234567
                +       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
                +       * }
                +       * </pre>
                +       * <p>
                +       * where #1 is a reference to the {@code "print "} text node above, and so
                +       * on for the other text nodes.
                +       * </p>
                +       *
                +       * <p>
                +       * The {@code} spans array is an array of pairs.  Even elements are the start
                +       * indices of substrings, and odd elements are the text nodes (or BR elements)
                +       * that contain the text for those substrings.
                +       * Substrings continue until the next index or the end of the source.
                +       * </p>
                +       *
                +       * @param {Node} node an HTML DOM subtree containing source-code.
                +       * @param {boolean|number} isPreformatted truthy if white-space in
                +       *    text nodes should be considered significant.
                +       * @return {SourceSpansT} source code and the nodes in which they occur.
                +       */
                +      function extractSourceSpans(node, isPreformatted) {
                +        var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +
                +        var chunks = [];
                +        var length = 0;
                +        var spans = [];
                +        var k = 0;
                +
                +        function walk(node) {
                +          var type = node.nodeType;
                +          if (type == 1) {  // Element
                +            if (nocode.test(node.className)) { return; }
                +            for (var child = node.firstChild; child; child = child.nextSibling) {
                +              walk(child);
                +            }
                +            var nodeName = node.nodeName.toLowerCase();
                +            if ('br' === nodeName || 'li' === nodeName) {
                +              chunks[k] = '\n';
                +              spans[k << 1] = length++;
                +              spans[(k++ << 1) | 1] = node;
                +            }
                +          } else if (type == 3 || type == 4) {  // Text
                +            var text = node.nodeValue;
                +            if (text.length) {
                +              if (!isPreformatted) {
                +                text = text.replace(/[ \t\r\n]+/g, ' ');
                +              } else {
                +                text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                +              }
                +              // TODO: handle tabs here?
                +              chunks[k] = text;
                +              spans[k << 1] = length;
                +              length += text.length;
                +              spans[(k++ << 1) | 1] = node;
                +            }
                +          }
                +        }
                +
                +        walk(node);
                +
                +        return {
                +          sourceCode: chunks.join('').replace(/\n$/, ''),
                +          spans: spans
                +        };
                +      }
                +
                +
                +      /**
                +       * Apply the given language handler to sourceCode and add the resulting
                +       * decorations to out.
                +       * @param {!Element} sourceNode
                +       * @param {number} basePos the index of sourceCode within the chunk of source
                +       *    whose decorations are already present on out.
                +       * @param {string} sourceCode
                +       * @param {function(JobT)} langHandler
                +       * @param {DecorationsT} out
                +       */
                +      function appendDecorations(
                +          sourceNode, basePos, sourceCode, langHandler, out) {
                +        if (!sourceCode) { return; }
                +        /** @type {JobT} */
                +        var job = {
                +          sourceNode: sourceNode,
                +          pre: 1,
                +          langExtension: null,
                +          numberLines: null,
                +          sourceCode: sourceCode,
                +          spans: null,
                +          basePos: basePos,
                +          decorations: null
                +        };
                +        langHandler(job);
                +        out.push.apply(out, job.decorations);
                +      }
                +
                +      var notWs = /\S/;
                +
                +      /**
                +       * Given an element, if it contains only one child element and any text nodes
                +       * it contains contain only space characters, return the sole child element.
                +       * Otherwise returns undefined.
                +       * <p>
                +       * This is meant to return the CODE element in {@code <pre><code ...>} when
                +       * there is a single child element that contains all the non-space textual
                +       * content, but not to return anything where there are multiple child elements
                +       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
                +       * is textual content.
                +       */
                +      function childContentWrapper(element) {
                +        var wrapper = undefined;
                +        for (var c = element.firstChild; c; c = c.nextSibling) {
                +          var type = c.nodeType;
                +          wrapper = (type === 1)  // Element Node
                +              ? (wrapper ? element : c)
                +              : (type === 3)  // Text Node
                +              ? (notWs.test(c.nodeValue) ? element : wrapper)
                +              : wrapper;
                +        }
                +        return wrapper === element ? undefined : wrapper;
                +      }
                +
                +      /** Given triples of [style, pattern, context] returns a lexing function,
                +        * The lexing function interprets the patterns to find token boundaries and
                +        * returns a decoration list of the form
                +        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
                +        * where index_n is an index into the sourceCode, and style_n is a style
                +        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
                +        * all characters in sourceCode[index_n-1:index_n].
                +        *
                +        * The stylePatterns is a list whose elements have the form
                +        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
                +        *
                +        * Style is a style constant like PR_PLAIN, or can be a string of the
                +        * form 'lang-FOO', where FOO is a language extension describing the
                +        * language of the portion of the token in $1 after pattern executes.
                +        * E.g., if style is 'lang-lisp', and group 1 contains the text
                +        * '(hello (world))', then that portion of the token will be passed to the
                +        * registered lisp handler for formatting.
                +        * The text before and after group 1 will be restyled using this decorator
                +        * so decorators should take care that this doesn't result in infinite
                +        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
                +        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
                +        * '<script>foo()<\/script>', which would cause the current decorator to
                +        * be called with '<script>' which would not match the same rule since
                +        * group 1 must not be empty, so it would be instead styled as PR_TAG by
                +        * the generic tag rule.  The handler registered for the 'js' extension would
                +        * then be called with 'foo()', and finally, the current decorator would
                +        * be called with '<\/script>' which would not match the original rule and
                +        * so the generic tag rule would identify it as a tag.
                +        *
                +        * Pattern must only match prefixes, and if it matches a prefix, then that
                +        * match is considered a token with the same style.
                +        *
                +        * Context is applied to the last non-whitespace, non-comment token
                +        * recognized.
                +        *
                +        * Shortcut is an optional string of characters, any of which, if the first
                +        * character, gurantee that this pattern and only this pattern matches.
                +        *
                +        * @param {Array} shortcutStylePatterns patterns that always start with
                +        *   a known character.  Must have a shortcut string.
                +        * @param {Array} fallthroughStylePatterns patterns that will be tried in
                +        *   order if the shortcut ones fail.  May have shortcuts.
                +        *
                +        * @return {function (JobT)} a function that takes an undecorated job and
                +        *   attaches a list of decorations.
                +        */
                +      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
                +        var shortcuts = {};
                +        var tokenizer;
                +        (function () {
                +          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
                +          var allRegexs = [];
                +          var regexKeys = {};
                +          for (var i = 0, n = allPatterns.length; i < n; ++i) {
                +            var patternParts = allPatterns[i];
                +            var shortcutChars = patternParts[3];
                +            if (shortcutChars) {
                +              for (var c = shortcutChars.length; --c >= 0;) {
                +                shortcuts[shortcutChars.charAt(c)] = patternParts;
                +              }
                +            }
                +            var regex = patternParts[1];
                +            var k = '' + regex;
                +            if (!regexKeys.hasOwnProperty(k)) {
                +              allRegexs.push(regex);
                +              regexKeys[k] = null;
                +            }
                +          }
                +          allRegexs.push(/[\0-\uffff]/);
                +          tokenizer = combinePrefixPatterns(allRegexs);
                +        })();
                +
                +        var nPatterns = fallthroughStylePatterns.length;
                +
                +        /**
                +         * Lexes job.sourceCode and attaches an output array job.decorations of
                +         * style classes preceded by the position at which they start in
                +         * job.sourceCode in order.
                +         *
                +         * @type{function (JobT)}
                +         */
                +        var decorate = function (job) {
                +          var sourceCode = job.sourceCode, basePos = job.basePos;
                +          var sourceNode = job.sourceNode;
                +          /** Even entries are positions in source in ascending order.  Odd enties
                +            * are style markers (e.g., PR_COMMENT) that run from that position until
                +            * the end.
                +            * @type {DecorationsT}
                +            */
                +          var decorations = [basePos, PR_PLAIN];
                +          var pos = 0;  // index into sourceCode
                +          var tokens = sourceCode.match(tokenizer) || [];
                +          var styleCache = {};
                +
                +          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
                +            var token = tokens[ti];
                +            var style = styleCache[token];
                +            var match = void 0;
                +
                +            var isEmbedded;
                +            if (typeof style === 'string') {
                +              isEmbedded = false;
                +            } else {
                +              var patternParts = shortcuts[token.charAt(0)];
                +              if (patternParts) {
                +                match = token.match(patternParts[1]);
                +                style = patternParts[0];
                +              } else {
                +                for (var i = 0; i < nPatterns; ++i) {
                +                  patternParts = fallthroughStylePatterns[i];
                +                  match = token.match(patternParts[1]);
                +                  if (match) {
                +                    style = patternParts[0];
                +                    break;
                +                  }
                +                }
                +
                +                if (!match) {  // make sure that we make progress
                +                  style = PR_PLAIN;
                +                }
                +              }
                +
                +              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
                +              if (isEmbedded && !(match && typeof match[1] === 'string')) {
                +                isEmbedded = false;
                +                style = PR_SOURCE;
                +              }
                +
                +              if (!isEmbedded) { styleCache[token] = style; }
                +            }
                +
                +            var tokenStart = pos;
                +            pos += token.length;
                +
                +            if (!isEmbedded) {
                +              decorations.push(basePos + tokenStart, style);
                +            } else {  // Treat group 1 as an embedded block of source code.
                +              var embeddedSource = match[1];
                +              var embeddedSourceStart = token.indexOf(embeddedSource);
                +              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
                +              if (match[2]) {
                +                // If embeddedSource can be blank, then it would match at the
                +                // beginning which would cause us to infinitely recurse on the
                +                // entire token, so we catch the right context in match[2].
                +                embeddedSourceEnd = token.length - match[2].length;
                +                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
                +              }
                +              var lang = style.substring(5);
                +              // Decorate the left of the embedded source
                +              appendDecorations(
                +                  sourceNode,
                +                  basePos + tokenStart,
                +                  token.substring(0, embeddedSourceStart),
                +                  decorate, decorations);
                +              // Decorate the embedded source
                +              appendDecorations(
                +                  sourceNode,
                +                  basePos + tokenStart + embeddedSourceStart,
                +                  embeddedSource,
                +                  langHandlerForExtension(lang, embeddedSource),
                +                  decorations);
                +              // Decorate the right of the embedded section
                +              appendDecorations(
                +                  sourceNode,
                +                  basePos + tokenStart + embeddedSourceEnd,
                +                  token.substring(embeddedSourceEnd),
                +                  decorate, decorations);
                +            }
                +          }
                +          job.decorations = decorations;
                +        };
                +        return decorate;
                +      }
                +
                +      /** returns a function that produces a list of decorations from source text.
                +        *
                +        * This code treats ", ', and ` as string delimiters, and \ as a string
                +        * escape.  It does not recognize perl's qq() style strings.
                +        * It has no special handling for double delimiter escapes as in basic, or
                +        * the tripled delimiters used in python, but should work on those regardless
                +        * although in those cases a single string literal may be broken up into
                +        * multiple adjacent string literals.
                +        *
                +        * It recognizes C, C++, and shell style comments.
                +        *
                +        * @param {Object} options a set of optional parameters.
                +        * @return {function (JobT)} a function that examines the source code
                +        *     in the input job and builds a decoration list which it attaches to
                +        *     the job.
                +        */
                +      function sourceDecorator(options) {
                +        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
                +        if (options['tripleQuotedStrings']) {
                +          // '''multi-line-string''', 'single-line-string', and double-quoted
                +          shortcutStylePatterns.push(
                +              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                +               null, '\'"']);
                +        } else if (options['multiLineStrings']) {
                +          // 'multi-line-string', "multi-line-string"
                +          shortcutStylePatterns.push(
                +              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
                +               null, '\'"`']);
                +        } else {
                +          // 'single-line-string', "single-line-string"
                +          shortcutStylePatterns.push(
                +              [PR_STRING,
                +               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
                +               null, '"\'']);
                +        }
                +        if (options['verbatimStrings']) {
                +          // verbatim-string-literal production from the C# grammar.  See issue 93.
                +          fallthroughStylePatterns.push(
                +              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
                +        }
                +        var hc = options['hashComments'];
                +        if (hc) {
                +          if (options['cStyleComments']) {
                +            if (hc > 1) {  // multiline hash comments
                +              shortcutStylePatterns.push(
                +                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
                +            } else {
                +              // Stop C preprocessor declarations at an unclosed open comment
                +              shortcutStylePatterns.push(
                +                  [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
                +                   null, '#']);
                +            }
                +            // #include <stdio.h>
                +            fallthroughStylePatterns.push(
                +                [PR_STRING,
                +                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
                +                 null]);
                +          } else {
                +            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
                +          }
                +        }
                +        if (options['cStyleComments']) {
                +          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
                +          fallthroughStylePatterns.push(
                +              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
                +        }
                +        var regexLiterals = options['regexLiterals'];
                +        if (regexLiterals) {
                +          /**
                +           * @const
                +           */
                +          var regexExcls = regexLiterals > 1
                +            ? ''  // Multiline regex literals
                +            : '\n\r';
                +          /**
                +           * @const
                +           */
                +          var regexAny = regexExcls ? '.' : '[\\S\\s]';
                +          /**
                +           * @const
                +           */
                +          var REGEX_LITERAL = (
                +              // A regular expression literal starts with a slash that is
                +              // not followed by * or / so that it is not confused with
                +              // comments.
                +              '/(?=[^/*' + regexExcls + '])'
                +              // and then contains any number of raw characters,
                +              + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
                +              // escape sequences (\x5C),
                +              +    '|\\x5C' + regexAny
                +              // or non-nesting character sets (\x5B\x5D);
                +              +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
                +              +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
                +              // finally closed by a /.
                +              + '/');
                +          fallthroughStylePatterns.push(
                +              ['lang-regex',
                +               RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
                +               ]);
                +        }
                +
                +        var types = options['types'];
                +        if (types) {
                +          fallthroughStylePatterns.push([PR_TYPE, types]);
                +        }
                +
                +        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
                +        if (keywords.length) {
                +          fallthroughStylePatterns.push(
                +              [PR_KEYWORD,
                +               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
                +               null]);
                +        }
                +
                +        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
                +
                +        var punctuation =
                +          // The Bash man page says
                +
                +          // A word is a sequence of characters considered as a single
                +          // unit by GRUB. Words are separated by metacharacters,
                +          // which are the following plus space, tab, and newline: { }
                +          // | & $ ; < >
                +          // ...
                +
                +          // A word beginning with # causes that word and all remaining
                +          // characters on that line to be ignored.
                +
                +          // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
                +          // comment but empirically
                +          // $ echo {#}
                +          // {#}
                +          // $ echo \$#
                +          // $#
                +          // $ echo }#
                +          // }#
                +
                +          // so /(?:^|[|&;<>\s])/ is more appropriate.
                +
                +          // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
                +          // suggests that this definition is compatible with a
                +          // default mode that tries to use a single token definition
                +          // to recognize both bash/python style comments and C
                +          // preprocessor directives.
                +
                +          // This definition of punctuation does not include # in the list of
                +          // follow-on exclusions, so # will not be broken before if preceeded
                +          // by a punctuation character.  We could try to exclude # after
                +          // [|&;<>] but that doesn't seem to cause many major problems.
                +          // If that does turn out to be a problem, we should change the below
                +          // when hc is truthy to include # in the run of punctuation characters
                +          // only when not followint [|&;<>].
                +          '^.[^\\s\\w.$@\'"`/\\\\]*';
                +        if (options['regexLiterals']) {
                +          punctuation += '(?!\s*\/)';
                +        }
                +
                +        fallthroughStylePatterns.push(
                +            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
                +            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
                +            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
                +            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
                +            [PR_LITERAL,
                +             new RegExp(
                +                 '^(?:'
                +                 // A hex number
                +                 + '0x[a-f0-9]+'
                +                 // or an octal or decimal number,
                +                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                +                 // possibly in scientific notation
                +                 + '(?:e[+\\-]?\\d+)?'
                +                 + ')'
                +                 // with an optional modifier like UL for unsigned long
                +                 + '[a-z]*', 'i'),
                +             null, '0123456789'],
                +            // Don't treat escaped quotes in bash as starting strings.
                +            // See issue 144.
                +            [PR_PLAIN,       /^\\[\s\S]?/, null],
                +            [PR_PUNCTUATION, new RegExp(punctuation), null]);
                +
                +        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
                +      }
                +
                +      var decorateSource = sourceDecorator({
                +            'keywords': ALL_KEYWORDS,
                +            'hashComments': true,
                +            'cStyleComments': true,
                +            'multiLineStrings': true,
                +            'regexLiterals': true
                +          });
                +
                +      /**
                +       * Given a DOM subtree, wraps it in a list, and puts each line into its own
                +       * list item.
                +       *
                +       * @param {Node} node modified in place.  Its content is pulled into an
                +       *     HTMLOListElement, and each line is moved into a separate list item.
                +       *     This requires cloning elements, so the input might not have unique
                +       *     IDs after numbering.
                +       * @param {number|null|boolean} startLineNum
                +       *     If truthy, coerced to an integer which is the 1-indexed line number
                +       *     of the first line of code.  The number of the first line will be
                +       *     attached to the list.
                +       * @param {boolean} isPreformatted true iff white-space in text nodes should
                +       *     be treated as significant.
                +       */
                +      function numberLines(node, startLineNum, isPreformatted) {
                +        var nocode = /(?:^|\s)nocode(?:\s|$)/;
                +        var lineBreak = /\r\n?|\n/;
                +
                +        var document = node.ownerDocument;
                +
                +        var li = document.createElement('li');
                +        while (node.firstChild) {
                +          li.appendChild(node.firstChild);
                +        }
                +        // An array of lines.  We split below, so this is initialized to one
                +        // un-split line.
                +        var listItems = [li];
                +
                +        function walk(node) {
                +          var type = node.nodeType;
                +          if (type == 1 && !nocode.test(node.className)) {  // Element
                +            if ('br' === node.nodeName.toLowerCase()) {
                +              breakAfter(node);
                +              // Discard the <BR> since it is now flush against a </LI>.
                +              if (node.parentNode) {
                +                node.parentNode.removeChild(node);
                +              }
                +            } else {
                +              for (var child = node.firstChild; child; child = child.nextSibling) {
                +                walk(child);
                +              }
                +            }
                +          } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
                +            var text = node.nodeValue;
                +            var match = text.match(lineBreak);
                +            if (match) {
                +              var firstLine = text.substring(0, match.index);
                +              node.nodeValue = firstLine;
                +              var tail = text.substring(match.index + match[0].length);
                +              if (tail) {
                +                var parent = node.parentNode;
                +                parent.insertBefore(
                +                  document.createTextNode(tail), node.nextSibling);
                +              }
                +              breakAfter(node);
                +              if (!firstLine) {
                +                // Don't leave blank text nodes in the DOM.
                +                node.parentNode.removeChild(node);
                +              }
                +            }
                +          }
                +        }
                +
                +        // Split a line after the given node.
                +        function breakAfter(lineEndNode) {
                +          // If there's nothing to the right, then we can skip ending the line
                +          // here, and move root-wards since splitting just before an end-tag
                +          // would require us to create a bunch of empty copies.
                +          while (!lineEndNode.nextSibling) {
                +            lineEndNode = lineEndNode.parentNode;
                +            if (!lineEndNode) { return; }
                +          }
                +
                +          function breakLeftOf(limit, copy) {
                +            // Clone shallowly if this node needs to be on both sides of the break.
                +            var rightSide = copy ? limit.cloneNode(false) : limit;
                +            var parent = limit.parentNode;
                +            if (parent) {
                +              // We clone the parent chain.
                +              // This helps us resurrect important styling elements that cross lines.
                +              // E.g. in <i>Foo<br>Bar</i>
                +              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
                +              var parentClone = breakLeftOf(parent, 1);
                +              // Move the clone and everything to the right of the original
                +              // onto the cloned parent.
                +              var next = limit.nextSibling;
                +              parentClone.appendChild(rightSide);
                +              for (var sibling = next; sibling; sibling = next) {
                +                next = sibling.nextSibling;
                +                parentClone.appendChild(sibling);
                +              }
                +            }
                +            return rightSide;
                +          }
                +
                +          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
                +
                +          // Walk the parent chain until we reach an unattached LI.
                +          for (var parent;
                +               // Check nodeType since IE invents document fragments.
                +               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
                +            copiedListItem = parent;
                +          }
                +          // Put it on the list of lines for later processing.
                +          listItems.push(copiedListItem);
                +        }
                +
                +        // Split lines while there are lines left to split.
                +        for (var i = 0;  // Number of lines that have been split so far.
                +             i < listItems.length;  // length updated by breakAfter calls.
                +             ++i) {
                +          walk(listItems[i]);
                +        }
                +
                +        // Make sure numeric indices show correctly.
                +        if (startLineNum === (startLineNum|0)) {
                +          listItems[0].setAttribute('value', startLineNum);
                +        }
                +
                +        var ol = document.createElement('ol');
                +        ol.className = 'linenums';
                +        var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
                +        for (var i = 0, n = listItems.length; i < n; ++i) {
                +          li = listItems[i];
                +          // Stick a class on the LIs so that stylesheets can
                +          // color odd/even rows, or any other row pattern that
                +          // is co-prime with 10.
                +          li.className = 'L' + ((i + offset) % 10);
                +          if (!li.firstChild) {
                +            li.appendChild(document.createTextNode('\xA0'));
                +          }
                +          ol.appendChild(li);
                +        }
                +
                +        node.appendChild(ol);
                +      }
                +
                +
                +      /**
                +       * Breaks {@code job.sourceCode} around style boundaries in
                +       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
                +       * @param {JobT} job
                +       * @private
                +       */
                +      function recombineTagsAndDecorations(job) {
                +        var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
                +        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
                +        var newlineRe = /\n/g;
                +
                +        var source = job.sourceCode;
                +        var sourceLength = source.length;
                +        // Index into source after the last code-unit recombined.
                +        var sourceIndex = 0;
                +
                +        var spans = job.spans;
                +        var nSpans = spans.length;
                +        // Index into spans after the last span which ends at or before sourceIndex.
                +        var spanIndex = 0;
                +
                +        var decorations = job.decorations;
                +        var nDecorations = decorations.length;
                +        // Index into decorations after the last decoration which ends at or before
                +        // sourceIndex.
                +        var decorationIndex = 0;
                +
                +        // Remove all zero-length decorations.
                +        decorations[nDecorations] = sourceLength;
                +        var decPos, i;
                +        for (i = decPos = 0; i < nDecorations;) {
                +          if (decorations[i] !== decorations[i + 2]) {
                +            decorations[decPos++] = decorations[i++];
                +            decorations[decPos++] = decorations[i++];
                +          } else {
                +            i += 2;
                +          }
                +        }
                +        nDecorations = decPos;
                +
                +        // Simplify decorations.
                +        for (i = decPos = 0; i < nDecorations;) {
                +          var startPos = decorations[i];
                +          // Conflate all adjacent decorations that use the same style.
                +          var startDec = decorations[i + 1];
                +          var end = i + 2;
                +          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
                +            end += 2;
                +          }
                +          decorations[decPos++] = startPos;
                +          decorations[decPos++] = startDec;
                +          i = end;
                +        }
                +
                +        nDecorations = decorations.length = decPos;
                +
                +        var sourceNode = job.sourceNode;
                +        var oldDisplay = "";
                +        if (sourceNode) {
                +          oldDisplay = sourceNode.style.display;
                +          sourceNode.style.display = 'none';
                +        }
                +        try {
                +          var decoration = null;
                +          while (spanIndex < nSpans) {
                +            var spanStart = spans[spanIndex];
                +            var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
                +                || sourceLength;
                +
                +            var decEnd = decorations[decorationIndex + 2] || sourceLength;
                +
                +            var end = Math.min(spanEnd, decEnd);
                +
                +            var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
                +            var styledText;
                +            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
                +                // Don't introduce spans around empty text nodes.
                +                && (styledText = source.substring(sourceIndex, end))) {
                +              // This may seem bizarre, and it is.  Emitting LF on IE causes the
                +              // code to display with spaces instead of line breaks.
                +              // Emitting Windows standard issue linebreaks (CRLF) causes a blank
                +              // space to appear at the beginning of every line but the first.
                +              // Emitting an old Mac OS 9 line separator makes everything spiffy.
                +              if (isIE8OrEarlier) {
                +                styledText = styledText.replace(newlineRe, '\r');
                +              }
                +              textNode.nodeValue = styledText;
                +              var document = textNode.ownerDocument;
                +              var span = document.createElement('span');
                +              span.className = decorations[decorationIndex + 1];
                +              var parentNode = textNode.parentNode;
                +              parentNode.replaceChild(span, textNode);
                +              span.appendChild(textNode);
                +              if (sourceIndex < spanEnd) {  // Split off a text node.
                +                spans[spanIndex + 1] = textNode
                +                    // TODO: Possibly optimize by using '' if there's no flicker.
                +                    = document.createTextNode(source.substring(end, spanEnd));
                +                parentNode.insertBefore(textNode, span.nextSibling);
                +              }
                +            }
                +
                +            sourceIndex = end;
                +
                +            if (sourceIndex >= spanEnd) {
                +              spanIndex += 2;
                +            }
                +            if (sourceIndex >= decEnd) {
                +              decorationIndex += 2;
                +            }
                +          }
                +        } finally {
                +          if (sourceNode) {
                +            sourceNode.style.display = oldDisplay;
                +          }
                +        }
                +      }
                +
                +
                +      /** Maps language-specific file extensions to handlers. */
                +      var langHandlerRegistry = {};
                +      /** Register a language handler for the given file extensions.
                +        * @param {function (JobT)} handler a function from source code to a list
                +        *      of decorations.  Takes a single argument job which describes the
                +        *      state of the computation and attaches the decorations to it.
                +        * @param {Array.<string>} fileExtensions
                +        */
                +      function registerLangHandler(handler, fileExtensions) {
                +        for (var i = fileExtensions.length; --i >= 0;) {
                +          var ext = fileExtensions[i];
                +          if (!langHandlerRegistry.hasOwnProperty(ext)) {
                +            langHandlerRegistry[ext] = handler;
                +          } else if (win['console']) {
                +            console['warn']('cannot override language handler %s', ext);
                +          }
                +        }
                +      }
                +      function langHandlerForExtension(extension, source) {
                +        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
                +          // Treat it as markup if the first non whitespace character is a < and
                +          // the last non-whitespace character is a >.
                +          extension = /^\s*</.test(source)
                +              ? 'default-markup'
                +              : 'default-code';
                +        }
                +        return langHandlerRegistry[extension];
                +      }
                +      registerLangHandler(decorateSource, ['default-code']);
                +      registerLangHandler(
                +          createSimpleLexer(
                +              [],
                +              [
                +               [PR_PLAIN,       /^[^<?]+/],
                +               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
                +               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
                +               // Unescaped content in an unknown language
                +               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
                +               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
                +               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
                +               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
                +               // Unescaped content in javascript.  (Or possibly vbscript).
                +               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
                +               // Contains unescaped stylesheet content
                +               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
                +               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
                +              ]),
                +          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
                +      registerLangHandler(
                +          createSimpleLexer(
                +              [
                +               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
                +               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
                +               ],
                +              [
                +               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
                +               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
                +               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
                +               [PR_PUNCTUATION,  /^[=<>\/]+/],
                +               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
                +               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
                +               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
                +               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
                +               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
                +               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
                +               ]),
                +          ['in.tag']);
                +      registerLangHandler(
                +          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': CPP_KEYWORDS,
                +              'hashComments': true,
                +              'cStyleComments': true,
                +              'types': C_TYPES
                +            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': 'null,true,false'
                +            }), ['json']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': CSHARP_KEYWORDS,
                +              'hashComments': true,
                +              'cStyleComments': true,
                +              'verbatimStrings': true,
                +              'types': C_TYPES
                +            }), ['cs']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': JAVA_KEYWORDS,
                +              'cStyleComments': true
                +            }), ['java']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': SH_KEYWORDS,
                +              'hashComments': true,
                +              'multiLineStrings': true
                +            }), ['bash', 'bsh', 'csh', 'sh']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': PYTHON_KEYWORDS,
                +              'hashComments': true,
                +              'multiLineStrings': true,
                +              'tripleQuotedStrings': true
                +            }), ['cv', 'py', 'python']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': PERL_KEYWORDS,
                +              'hashComments': true,
                +              'multiLineStrings': true,
                +              'regexLiterals': 2  // multiline regex literals
                +            }), ['perl', 'pl', 'pm']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': RUBY_KEYWORDS,
                +              'hashComments': true,
                +              'multiLineStrings': true,
                +              'regexLiterals': true
                +            }), ['rb', 'ruby']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': JSCRIPT_KEYWORDS,
                +              'cStyleComments': true,
                +              'regexLiterals': true
                +            }), ['javascript', 'js', 'ts', 'typescript']);
                +      registerLangHandler(sourceDecorator({
                +              'keywords': COFFEE_KEYWORDS,
                +              'hashComments': 3,  // ### style block comments
                +              'cStyleComments': true,
                +              'multilineStrings': true,
                +              'tripleQuotedStrings': true,
                +              'regexLiterals': true
                +            }), ['coffee']);
                +      registerLangHandler(
                +          createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
                +
                +      /** @param {JobT} job */
                +      function applyDecorator(job) {
                +        var opt_langExtension = job.langExtension;
                +
                +        try {
                +          // Extract tags, and convert the source code to plain text.
                +          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
                +          /** Plain text. @type {string} */
                +          var source = sourceAndSpans.sourceCode;
                +          job.sourceCode = source;
                +          job.spans = sourceAndSpans.spans;
                +          job.basePos = 0;
                +
                +          // Apply the appropriate language handler
                +          langHandlerForExtension(opt_langExtension, source)(job);
                +
                +          // Integrate the decorations and tags back into the source code,
                +          // modifying the sourceNode in place.
                +          recombineTagsAndDecorations(job);
                +        } catch (e) {
                +          if (win['console']) {
                +            console['log'](e && e['stack'] || e);
                +          }
                +        }
                +      }
                +
                +      /**
                +       * Pretty print a chunk of code.
                +       * @param sourceCodeHtml {string} The HTML to pretty print.
                +       * @param opt_langExtension {string} The language name to use.
                +       *     Typically, a filename extension like 'cpp' or 'java'.
                +       * @param opt_numberLines {number|boolean} True to number lines,
                +       *     or the 1-indexed number of the first line in sourceCodeHtml.
                +       */
                +      function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
                +        /** @type{number|boolean} */
                +        var nl = opt_numberLines || false;
                +        /** @type{string|null} */
                +        var langExtension = opt_langExtension || null;
                +        /** @type{!Element} */
                +        var container = document.createElement('div');
                +        // This could cause images to load and onload listeners to fire.
                +        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
                +        // We assume that the inner HTML is from a trusted source.
                +        // The pre-tag is required for IE8 which strips newlines from innerHTML
                +        // when it is injected into a <pre> tag.
                +        // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
                +        // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
                +        container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
                +        container = /** @type{!Element} */(container.firstChild);
                +        if (nl) {
                +          numberLines(container, nl, true);
                +        }
                +
                +        /** @type{JobT} */
                +        var job = {
                +          langExtension: langExtension,
                +          numberLines: nl,
                +          sourceNode: container,
                +          pre: 1,
                +          sourceCode: null,
                +          basePos: null,
                +          spans: null,
                +          decorations: null
                +        };
                +        applyDecorator(job);
                +        return container.innerHTML;
                +      }
                +
                +       /**
                +        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
                +        * {@code class=prettyprint} and prettify them.
                +        *
                +        * @param {Function} opt_whenDone called when prettifying is done.
                +        * @param {HTMLElement|HTMLDocument} opt_root an element or document
                +        *   containing all the elements to pretty print.
                +        *   Defaults to {@code document.body}.
                +        */
                +      function $prettyPrint(opt_whenDone, opt_root) {
                +        var root = opt_root || document.body;
                +        var doc = root.ownerDocument || document;
                +        function byTagName(tn) { return root.getElementsByTagName(tn); }
                +        // fetch a list of nodes to rewrite
                +        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
                +        var elements = [];
                +        for (var i = 0; i < codeSegments.length; ++i) {
                +          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
                +            elements.push(codeSegments[i][j]);
                +          }
                +        }
                +        codeSegments = null;
                +
                +        var clock = Date;
                +        if (!clock['now']) {
                +          clock = { 'now': function () { return +(new Date); } };
                +        }
                +
                +        // The loop is broken into a series of continuations to make sure that we
                +        // don't make the browser unresponsive when rewriting a large page.
                +        var k = 0;
                +
                +        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
                +        var prettyPrintRe = /\bprettyprint\b/;
                +        var prettyPrintedRe = /\bprettyprinted\b/;
                +        var preformattedTagNameRe = /pre|xmp/i;
                +        var codeRe = /^code$/i;
                +        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
                +        var EMPTY = {};
                +
                +        function doWork() {
                +          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
                +                         clock['now']() + 250 /* ms */ :
                +                         Infinity);
                +          for (; k < elements.length && clock['now']() < endTime; k++) {
                +            var cs = elements[k];
                +
                +            // Look for a preceding comment like
                +            // <?prettify lang="..." linenums="..."?>
                +            var attrs = EMPTY;
                +            {
                +              for (var preceder = cs; (preceder = preceder.previousSibling);) {
                +                var nt = preceder.nodeType;
                +                // <?foo?> is parsed by HTML 5 to a comment node (8)
                +                // like <!--?foo?-->, but in XML is a processing instruction
                +                var value = (nt === 7 || nt === 8) && preceder.nodeValue;
                +                if (value
                +                    ? !/^\??prettify\b/.test(value)
                +                    : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
                +                  // Skip over white-space text nodes but not others.
                +                  break;
                +                }
                +                if (value) {
                +                  attrs = {};
                +                  value.replace(
                +                      /\b(\w+)=([\w:.%+-]+)/g,
                +                    function (_, name, value) { attrs[name] = value; });
                +                  break;
                +                }
                +              }
                +            }
                +
                +            var className = cs.className;
                +            if ((attrs !== EMPTY || prettyPrintRe.test(className))
                +                // Don't redo this if we've already done it.
                +                // This allows recalling pretty print to just prettyprint elements
                +                // that have been added to the page since last call.
                +                && !prettyPrintedRe.test(className)) {
                +
                +              // make sure this is not nested in an already prettified element
                +              var nested = false;
                +              for (var p = cs.parentNode; p; p = p.parentNode) {
                +                var tn = p.tagName;
                +                if (preCodeXmpRe.test(tn)
                +                    && p.className && prettyPrintRe.test(p.className)) {
                +                  nested = true;
                +                  break;
                +                }
                +              }
                +              if (!nested) {
                +                // Mark done.  If we fail to prettyprint for whatever reason,
                +                // we shouldn't try again.
                +                cs.className += ' prettyprinted';
                +
                +                // If the classes includes a language extensions, use it.
                +                // Language extensions can be specified like
                +                //     <pre class="prettyprint lang-cpp">
                +                // the language extension "cpp" is used to find a language handler
                +                // as passed to PR.registerLangHandler.
                +                // HTML5 recommends that a language be specified using "language-"
                +                // as the prefix instead.  Google Code Prettify supports both.
                +                // http://dev.w3.org/html5/spec-author-view/the-code-element.html
                +                var langExtension = attrs['lang'];
                +                if (!langExtension) {
                +                  langExtension = className.match(langExtensionRe);
                +                  // Support <pre class="prettyprint"><code class="language-c">
                +                  var wrapper;
                +                  if (!langExtension && (wrapper = childContentWrapper(cs))
                +                      && codeRe.test(wrapper.tagName)) {
                +                    langExtension = wrapper.className.match(langExtensionRe);
                +                  }
                +
                +                  if (langExtension) { langExtension = langExtension[1]; }
                +                }
                +
                +                var preformatted;
                +                if (preformattedTagNameRe.test(cs.tagName)) {
                +                  preformatted = 1;
                +                } else {
                +                  var currentStyle = cs['currentStyle'];
                +                  var defaultView = doc.defaultView;
                +                  var whitespace = (
                +                      currentStyle
                +                      ? currentStyle['whiteSpace']
                +                      : (defaultView
                +                         && defaultView.getComputedStyle)
                +                      ? defaultView.getComputedStyle(cs, null)
                +                      .getPropertyValue('white-space')
                +                      : 0);
                +                  preformatted = whitespace
                +                      && 'pre' === whitespace.substring(0, 3);
                +                }
                +
                +                // Look for a class like linenums or linenums:<n> where <n> is the
                +                // 1-indexed number of the first line.
                +                var lineNums = attrs['linenums'];
                +                if (!(lineNums = lineNums === 'true' || +lineNums)) {
                +                  lineNums = className.match(/\blinenums\b(?::(\d+))?/);
                +                  lineNums =
                +                    lineNums
                +                    ? lineNums[1] && lineNums[1].length
                +                      ? +lineNums[1] : true
                +                    : false;
                +                }
                +                if (lineNums) { numberLines(cs, lineNums, preformatted); }
                +
                +                // do the pretty printing
                +                var prettyPrintingJob = {
                +                  langExtension: langExtension,
                +                  sourceNode: cs,
                +                  numberLines: lineNums,
                +                  pre: preformatted,
                +                  sourceCode: null,
                +                  basePos: null,
                +                  spans: null,
                +                  decorations: null
                +                };
                +                applyDecorator(prettyPrintingJob);
                +              }
                +            }
                +          }
                +          if (k < elements.length) {
                +            // finish up in a continuation
                +            win.setTimeout(doWork, 250);
                +          } else if ('function' === typeof opt_whenDone) {
                +            opt_whenDone();
                +          }
                +        }
                +
                +        doWork();
                +      }
                +
                +      /**
                +       * Contains functions for creating and registering new language handlers.
                +       * @type {Object}
                +       */
                +      var PR = win['PR'] = {
                +            'createSimpleLexer': createSimpleLexer,
                +            'registerLangHandler': registerLangHandler,
                +            'sourceDecorator': sourceDecorator,
                +            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
                +            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
                +            'PR_COMMENT': PR_COMMENT,
                +            'PR_DECLARATION': PR_DECLARATION,
                +            'PR_KEYWORD': PR_KEYWORD,
                +            'PR_LITERAL': PR_LITERAL,
                +            'PR_NOCODE': PR_NOCODE,
                +            'PR_PLAIN': PR_PLAIN,
                +            'PR_PUNCTUATION': PR_PUNCTUATION,
                +            'PR_SOURCE': PR_SOURCE,
                +            'PR_STRING': PR_STRING,
                +            'PR_TAG': PR_TAG,
                +            'PR_TYPE': PR_TYPE,
                +            'prettyPrintOne':
                +               IN_GLOBAL_SCOPE
                +                 ? (win['prettyPrintOne'] = $prettyPrintOne)
                +                 : (prettyPrintOne = $prettyPrintOne),
                +            'prettyPrint':
                +               IN_GLOBAL_SCOPE
                +                 ? (win['prettyPrint'] = $prettyPrint)
                +                 : (prettyPrint = $prettyPrint)
                +          };
                +
                +      // Make PR available via the Asynchronous Module Definition (AMD) API.
                +      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
                +      // The Asynchronous Module Definition (AMD) API specifies a
                +      // mechanism for defining modules such that the module and its
                +      // dependencies can be asynchronously loaded.
                +      // ...
                +      // To allow a clear indicator that a global define function (as
                +      // needed for script src browser loading) conforms to the AMD API,
                +      // any global define function SHOULD have a property called "amd"
                +      // whose value is an object. This helps avoid conflict with any
                +      // other existing JavaScript code that could have defined a define()
                +      // function that does not conform to the AMD API.
                +      var define = win['define'];
                +      if (typeof define === "function" && define['amd']) {
                +        define("google-code-prettify", [], function () {
                +          return PR;
                +        });
                +      }
                +    })();
                +
                +    return prettyPrint;
                +  })();
                +
                +  // If this script is deferred or async and the document is already
                +  // loaded we need to wait for language handlers to load before performing
                +  // any autorun.
                +  function onLangsLoaded() {
                +    if (autorun) {
                +      contentLoaded(
                +        function () {
                +          var n = callbacks.length;
                +          var callback = n ? function () {
                +            for (var i = 0; i < n; ++i) {
                +              (function (i) {
                +                win.setTimeout(
                +                   function () {
                +                     win['exports'][callbacks[i]].apply(win, arguments);
                +                   }, 0);
                +               })(i);
                +            }
                +          } : void 0;
                +          prettyPrint(callback);
                +        });
                +    }
                +  }
                +  checkPendingLanguages();
                +
                +}());
                diff --git a/backend/webif/static/js/google-prettify/skins/desert.css b/backend/webif/static/js/google-prettify/skins/desert.css
                new file mode 100755
                index 000000000..b2b73cd86
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/skins/desert.css
                @@ -0,0 +1,34 @@
                +/* desert scheme ported from vim to google prettify */
                +pre.prettyprint { display: block; background-color: #333 }
                +pre .nocode { background-color: none; color: #000 }
                +pre .str { color: #ffa0a0 } /* string  - pink */
                +pre .kwd { color: #f0e68c; font-weight: bold }
                +pre .com { color: #87ceeb } /* comment - skyblue */
                +pre .typ { color: #98fb98 } /* type    - lightgreen */
                +pre .lit { color: #cd5c5c } /* literal - darkred */
                +pre .pun { color: #fff }    /* punctuation */
                +pre .pln { color: #fff }    /* plaintext */
                +pre .tag { color: #f0e68c; font-weight: bold } /* html/xml tag    - lightyellow */
                +pre .atn { color: #bdb76b; font-weight: bold } /* attribute name  - khaki */
                +pre .atv { color: #ffa0a0 } /* attribute value - pink */
                +pre .dec { color: #98fb98 } /* decimal         - lightgreen */
                +
                +/* Specify class=linenums on a pre to get line numbering */
                +ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE } /* IE indents via margin-left */
                +li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
                +/* Alternate shading for lines */
                +li.L1,li.L3,li.L5,li.L7,li.L9 { }
                +
                +@media print {
                +  pre.prettyprint { background-color: none }
                +  pre .str, code .str { color: #060 }
                +  pre .kwd, code .kwd { color: #006; font-weight: bold }
                +  pre .com, code .com { color: #600; font-style: italic }
                +  pre .typ, code .typ { color: #404; font-weight: bold }
                +  pre .lit, code .lit { color: #044 }
                +  pre .pun, code .pun { color: #440 }
                +  pre .pln, code .pln { color: #000 }
                +  pre .tag, code .tag { color: #006; font-weight: bold }
                +  pre .atn, code .atn { color: #404 }
                +  pre .atv, code .atv { color: #060 }
                +}
                diff --git a/backend/webif/static/js/google-prettify/skins/doxy.css b/backend/webif/static/js/google-prettify/skins/doxy.css
                new file mode 100755
                index 000000000..b0e89161f
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/skins/doxy.css
                @@ -0,0 +1,64 @@
                +/* Doxy pretty-printing styles. Used with prettify.js.  */
                +
                +pre .str, code .str { color: #fec243; } /* string  - eggyolk gold */
                +pre .kwd, code .kwd { color: #8470FF; } /* keyword - light slate blue */
                +pre .com, code .com { color: #32cd32; font-style: italic; } /* comment - green */
                +pre .typ, code .typ { color: #6ecbcc; } /* type - turq green */
                +pre .lit, code .lit { color: #d06; } /* literal - cherry red */
                +pre .pun, code .pun { color: #8B8970;  } /* punctuation - lemon chiffon4  */
                +pre .pln, code .pln { color: #f0f0f0; } /* plaintext - white */
                +pre .tag, code .tag { color: #9c9cff; } /* html/xml tag  (bluey)  */
                +pre .htm, code .htm { color: #dda0dd; } /* html tag  light purply*/
                +pre .xsl, code .xsl { color: #d0a0d0; } /* xslt tag  light purply*/
                +pre .atn, code .atn { color: #46eeee; font-weight: normal;} /* html/xml attribute name  - lt turquoise */
                +pre .atv, code .atv { color: #EEB4B4; } /* html/xml attribute value - rosy brown2 */
                +pre .dec, code .dec { color: #3387CC; } /* decimal - blue */
                +
                +a {
                +  text-decoration: none;
                +}
                +pre.prettyprint, code.prettyprint {
                +  font-family:'Droid Sans Mono','CPMono_v07 Bold','Droid Sans';
                +  font-weight: bold;
                +  font-size: 9pt;
                +  background-color: #0f0f0f;
                +  -moz-border-radius: 8px;
                +  -webkit-border-radius: 8px;
                +  -o-border-radius: 8px;
                +  -ms-border-radius: 8px;
                +  -khtml-border-radius: 8px;
                +  border-radius: 8px;
                +}  /*  background is black (well, just a tad less dark )  */
                +
                +pre.prettyprint {
                +  width: 95%;
                +  margin: 1em auto;
                +  padding: 1em;
                +  white-space: pre-wrap;
                +}
                +
                +pre.prettyprint a, code.prettyprint a {
                +   text-decoration:none;
                +}
                +/* Specify class=linenums on a pre to get line numbering; line numbers themselves are the same color as punctuation */
                +ol.linenums { margin-top: 0; margin-bottom: 0; color: #8B8970; } /* IE indents via margin-left */
                +li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
                +/* Alternate shading for lines */
                +li.L1,li.L3,li.L5,li.L7,li.L9 { }
                +
                +/* print is mostly unchanged from default at present  */
                +@media print {
                +  pre.prettyprint, code.prettyprint { background-color: #fff;  }
                +  pre .str, code .str { color: #088; }
                +  pre .kwd, code .kwd { color: #006; font-weight: bold; }
                +  pre .com, code .com { color: #oc3; font-style: italic; }
                +  pre .typ, code .typ { color: #404; font-weight: bold; }
                +  pre .lit, code .lit { color: #044; }
                +  pre .pun, code .pun { color: #440; }
                +  pre .pln, code .pln { color: #000; }
                +  pre .tag, code .tag { color: #b66ff7; font-weight: bold; }
                +  pre .htm, code .htm { color: #606; font-weight: bold; }
                +  pre .xsl, code .xsl { color: #606; font-weight: bold; }
                +  pre .atn, code .atn { color: #c71585;  font-weight: normal; }
                +  pre .atv, code .atv { color: #088;  font-weight: normal; }
                +}
                diff --git a/backend/webif/static/js/google-prettify/skins/sons-of-obsidian.css b/backend/webif/static/js/google-prettify/skins/sons-of-obsidian.css
                new file mode 100755
                index 000000000..8553db65d
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/skins/sons-of-obsidian.css
                @@ -0,0 +1,118 @@
                +/*
                + * Derived from einaros's Sons of Obsidian theme at
                + * http://studiostyl.es/schemes/son-of-obsidian by
                + * Alex Ford of CodeTunnel:
                + * http://CodeTunnel.com/blog/post/71/google-code-prettify-obsidian-theme
                + */
                +
                +.str
                +{
                +    color: #EC7600;
                +}
                +.kwd
                +{
                +    color: #93C763;
                +}
                +.com
                +{
                +    color: #66747B;
                +}
                +.typ
                +{
                +    color: #678CB1;
                +}
                +.lit
                +{
                +    color: #FACD22;
                +}
                +.pun
                +{
                +    color: #F1F2F3;
                +}
                +.pln
                +{
                +    color: #F1F2F3;
                +}
                +.tag
                +{
                +    color: #8AC763;
                +}
                +.atn
                +{
                +    color: #E0E2E4;
                +}
                +.atv
                +{
                +    color: #EC7600;
                +}
                +.dec
                +{
                +    color: purple;
                +}
                +pre.prettyprint
                +{
                +    border: 0px solid #888;
                +}
                +ol.linenums
                +{
                +    margin-top: 0;
                +    margin-bottom: 0;
                +}
                +.prettyprint {
                +    background: #000;
                +}
                +li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9
                +{
                +    color: #555;
                +    list-style-type: decimal;
                +}
                +li.L1, li.L3, li.L5, li.L7, li.L9 {
                +    background: #111;
                +}
                +@media print
                +{
                +    .str
                +    {
                +        color: #060;
                +    }
                +    .kwd
                +    {
                +        color: #006;
                +        font-weight: bold;
                +    }
                +    .com
                +    {
                +        color: #600;
                +        font-style: italic;
                +    }
                +    .typ
                +    {
                +        color: #404;
                +        font-weight: bold;
                +    }
                +    .lit
                +    {
                +        color: #044;
                +    }
                +    .pun
                +    {
                +        color: #440;
                +    }
                +    .pln
                +    {
                +        color: #000;
                +    }
                +    .tag
                +    {
                +        color: #006;
                +        font-weight: bold;
                +    }
                +    .atn
                +    {
                +        color: #404;
                +    }
                +    .atv
                +    {
                +        color: #060;
                +    }
                +}
                diff --git a/backend/webif/static/js/google-prettify/skins/sunburst.css b/backend/webif/static/js/google-prettify/skins/sunburst.css
                new file mode 100755
                index 000000000..ae06306a4
                --- /dev/null
                +++ b/backend/webif/static/js/google-prettify/skins/sunburst.css
                @@ -0,0 +1,46 @@
                +/* Pretty printing styles. Used with prettify.js. */
                +/* Vim sunburst theme by David Leibovic */
                +
                +pre .str, code .str { color: #65B042; } /* string  - green */
                +pre .kwd, code .kwd { color: #E28964; } /* keyword - dark pink */
                +pre .com, code .com { color: #AEAEAE; font-style: italic; } /* comment - gray */
                +pre .typ, code .typ { color: #89bdff; } /* type - light blue */
                +pre .lit, code .lit { color: #3387CC; } /* literal - blue */
                +pre .pun, code .pun { color: #fff; } /* punctuation - white */
                +pre .pln, code .pln { color: #fff; } /* plaintext - white */
                +pre .tag, code .tag { color: #89bdff; } /* html/xml tag    - light blue */
                +pre .atn, code .atn { color: #bdb76b; } /* html/xml attribute name  - khaki */
                +pre .atv, code .atv { color: #65B042; } /* html/xml attribute value - green */
                +pre .dec, code .dec { color: #3387CC; } /* decimal - blue */
                +
                +pre.prettyprint, code.prettyprint {
                +	background-color: #000;
                +	border-radius: 8px;
                +}
                +
                +pre.prettyprint {
                +	width: 95%;
                +	margin: 1em auto;
                +	padding: 1em;
                +	white-space: pre-wrap;
                +}
                +
                +
                +/* Specify class=linenums on a pre to get line numbering */
                +ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */
                +li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
                +/* Alternate shading for lines */
                +li.L1,li.L3,li.L5,li.L7,li.L9 { }
                +
                +@media print {
                +  pre .str, code .str { color: #060; }
                +  pre .kwd, code .kwd { color: #006; font-weight: bold; }
                +  pre .com, code .com { color: #600; font-style: italic; }
                +  pre .typ, code .typ { color: #404; font-weight: bold; }
                +  pre .lit, code .lit { color: #044; }
                +  pre .pun, code .pun { color: #440; }
                +  pre .pln, code .pln { color: #000; }
                +  pre .tag, code .tag { color: #006; font-weight: bold; }
                +  pre .atn, code .atn { color: #404; }
                +  pre .atv, code .atv { color: #060; }
                +}
                diff --git a/backend/webif/static/js/item_tree_functions.js b/backend/webif/static/js/item_tree_functions.js
                new file mode 100755
                index 000000000..3a98e6a1e
                --- /dev/null
                +++ b/backend/webif/static/js/item_tree_functions.js
                @@ -0,0 +1,105 @@
                +
                +function build_item_subtree_recursive(data) {
                +    var result = [];
                +    var tree_element = {};
                +    tree_element['text'] = data.path;
                +    var node_length = data.nodes.length;
                +    if (data.nodes.length > 0) {
                +        var child_nodes = [];
                +        for (var i = 0; i < node_length; i++) {
                +            var new_child_node = build_item_subtree_recursive(data.nodes[i]);
                +            child_nodes.push(new_child_node);
                +        }
                +        tree_element['tags'] = data.tags;
                +        tree_element['nodes'] = child_nodes;
                +    }
                +
                +    return tree_element;
                +}
                +
                +function reload(data) {
                +    panel = $(".panel").reload({
                +        autoReload: false,
                +        time: 3000,
                +        refreshContainer: '.refresh-container',
                +        dataContainer: '#tree_detail',
                +        beforeReload: function() {},
                +        afterReload: function() {},
                +        parseData: getDetailInfo,
                +        parameterString: data.text
                +    });
                +}
                +
                +function changeSearchButtonColor(active) {
                +    if (active) {
                +        $('#btn-search').removeClass("btn-default");
                +        $('#btn-search').addClass("btn-primary");
                +    } else {
                +        $('#btn-search').removeClass("btn-primary");
                +        $('#btn-search').addClass("btn-default");
                +    }
                +}
                +
                +function getTree() {
                +    var item_tree = [];
                +
                +    $.getJSON('items.json?mode=tree', function(result) {
                +        $.each(result, function(index, element) {
                +            item_tree.push(build_item_subtree_recursive(element));
                +        });
                +        $('#tree').treeview({
                +            data: item_tree,
                +			levels: 1,
                +            showTags: true,
                +            onNodeSelected: function(event, data) {
                +                reload(data)
                +            }
                +        });
                +    });
                +    var search = function(e) {
                +          results = [];
                +          var pattern = $('#input-search').val();
                +          var options = {
                +            ignoreCase: true,
                +            exactMatch: false,
                +            revealResults: true
                +          };
                +          var results = $('#tree').treeview('search', [ pattern, options ]);
                +          $('#search-results').html(' - Treffer: '+results.length);
                +
                +
                +          $('#btn-clear-search').on('click', function (e) {
                +            $('#tree').treeview('clearSearch');
                +            $('#tree').treeview('collapseAll', { silent: false });
                +            $('#btn-search').removeClass("btn-primary");
                +            $('#btn-search').addClass("btn-default");
                +            $('#input-search').val('');
                +            $('#search-output').html('');
                +            results = [];
                +            $('#search-results').html('');
                +          });
                +    }
                +    if ($('#input-search').val() != '') {
                +        changeSearchButtonColor(true);
                +    }
                +    $('#btn-search').on('click', search);
                +    $("#input-search").keypress(function(event){
                +        if(event.keyCode == 13){
                +            $("#btn-search").click();
                +        }
                +        if ($('#input-search').val() == '') {
                +            changeSearchButtonColor(false);
                +        } else {
                +            changeSearchButtonColor(true);
                +        }
                +    });
                +
                +    // Expand/collapse all
                +    $('#btn-expand-all').on('click', function (e) {
                +      var levels = $('#select-expand-all-levels').val();
                +      $('#tree').treeview('expandAll', { levels: levels, silent: false });
                +    });
                +    $('#btn-collapse-all').on('click', function (e) {
                +      $('#tree').treeview('collapseAll', { silent: false });
                +    });
                +}
                \ No newline at end of file
                diff --git a/backend/webif/static/js/jquery-3.2.1.js b/backend/webif/static/js/jquery-3.2.1.js
                new file mode 100755
                index 000000000..d2d8ca479
                --- /dev/null
                +++ b/backend/webif/static/js/jquery-3.2.1.js
                @@ -0,0 +1,10253 @@
                +/*!
                + * jQuery JavaScript Library v3.2.1
                + * https://jquery.com/
                + *
                + * Includes Sizzle.js
                + * https://sizzlejs.com/
                + *
                + * Copyright JS Foundation and other contributors
                + * Released under the MIT license
                + * https://jquery.org/license
                + *
                + * Date: 2017-03-20T18:59Z
                + */
                +( function( global, factory ) {
                +
                +	"use strict";
                +
                +	if ( typeof module === "object" && typeof module.exports === "object" ) {
                +
                +		// For CommonJS and CommonJS-like environments where a proper `window`
                +		// is present, execute the factory and get jQuery.
                +		// For environments that do not have a `window` with a `document`
                +		// (such as Node.js), expose a factory as module.exports.
                +		// This accentuates the need for the creation of a real `window`.
                +		// e.g. var jQuery = require("jquery")(window);
                +		// See ticket #14549 for more info.
                +		module.exports = global.document ?
                +			factory( global, true ) :
                +			function( w ) {
                +				if ( !w.document ) {
                +					throw new Error( "jQuery requires a window with a document" );
                +				}
                +				return factory( w );
                +			};
                +	} else {
                +		factory( global );
                +	}
                +
                +// Pass this if window is not defined yet
                +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
                +
                +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
                +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
                +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
                +// enough that all such attempts are guarded in a try block.
                +"use strict";
                +
                +var arr = [];
                +
                +var document = window.document;
                +
                +var getProto = Object.getPrototypeOf;
                +
                +var slice = arr.slice;
                +
                +var concat = arr.concat;
                +
                +var push = arr.push;
                +
                +var indexOf = arr.indexOf;
                +
                +var class2type = {};
                +
                +var toString = class2type.toString;
                +
                +var hasOwn = class2type.hasOwnProperty;
                +
                +var fnToString = hasOwn.toString;
                +
                +var ObjectFunctionString = fnToString.call( Object );
                +
                +var support = {};
                +
                +
                +
                +	function DOMEval( code, doc ) {
                +		doc = doc || document;
                +
                +		var script = doc.createElement( "script" );
                +
                +		script.text = code;
                +		doc.head.appendChild( script ).parentNode.removeChild( script );
                +	}
                +/* global Symbol */
                +// Defining this global in .eslintrc.json would create a danger of using the global
                +// unguarded in another place, it seems safer to define global only for this module
                +
                +
                +
                +var
                +	version = "3.2.1",
                +
                +	// Define a local copy of jQuery
                +	jQuery = function( selector, context ) {
                +
                +		// The jQuery object is actually just the init constructor 'enhanced'
                +		// Need init if jQuery is called (just allow error to be thrown if not included)
                +		return new jQuery.fn.init( selector, context );
                +	},
                +
                +	// Support: Android <=4.0 only
                +	// Make sure we trim BOM and NBSP
                +	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
                +
                +	// Matches dashed string for camelizing
                +	rmsPrefix = /^-ms-/,
                +	rdashAlpha = /-([a-z])/g,
                +
                +	// Used by jQuery.camelCase as callback to replace()
                +	fcamelCase = function( all, letter ) {
                +		return letter.toUpperCase();
                +	};
                +
                +jQuery.fn = jQuery.prototype = {
                +
                +	// The current version of jQuery being used
                +	jquery: version,
                +
                +	constructor: jQuery,
                +
                +	// The default length of a jQuery object is 0
                +	length: 0,
                +
                +	toArray: function() {
                +		return slice.call( this );
                +	},
                +
                +	// Get the Nth element in the matched element set OR
                +	// Get the whole matched element set as a clean array
                +	get: function( num ) {
                +
                +		// Return all the elements in a clean array
                +		if ( num == null ) {
                +			return slice.call( this );
                +		}
                +
                +		// Return just the one element from the set
                +		return num < 0 ? this[ num + this.length ] : this[ num ];
                +	},
                +
                +	// Take an array of elements and push it onto the stack
                +	// (returning the new matched element set)
                +	pushStack: function( elems ) {
                +
                +		// Build a new jQuery matched element set
                +		var ret = jQuery.merge( this.constructor(), elems );
                +
                +		// Add the old object onto the stack (as a reference)
                +		ret.prevObject = this;
                +
                +		// Return the newly-formed element set
                +		return ret;
                +	},
                +
                +	// Execute a callback for every element in the matched set.
                +	each: function( callback ) {
                +		return jQuery.each( this, callback );
                +	},
                +
                +	map: function( callback ) {
                +		return this.pushStack( jQuery.map( this, function( elem, i ) {
                +			return callback.call( elem, i, elem );
                +		} ) );
                +	},
                +
                +	slice: function() {
                +		return this.pushStack( slice.apply( this, arguments ) );
                +	},
                +
                +	first: function() {
                +		return this.eq( 0 );
                +	},
                +
                +	last: function() {
                +		return this.eq( -1 );
                +	},
                +
                +	eq: function( i ) {
                +		var len = this.length,
                +			j = +i + ( i < 0 ? len : 0 );
                +		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
                +	},
                +
                +	end: function() {
                +		return this.prevObject || this.constructor();
                +	},
                +
                +	// For internal use only.
                +	// Behaves like an Array's method, not like a jQuery method.
                +	push: push,
                +	sort: arr.sort,
                +	splice: arr.splice
                +};
                +
                +jQuery.extend = jQuery.fn.extend = function() {
                +	var options, name, src, copy, copyIsArray, clone,
                +		target = arguments[ 0 ] || {},
                +		i = 1,
                +		length = arguments.length,
                +		deep = false;
                +
                +	// Handle a deep copy situation
                +	if ( typeof target === "boolean" ) {
                +		deep = target;
                +
                +		// Skip the boolean and the target
                +		target = arguments[ i ] || {};
                +		i++;
                +	}
                +
                +	// Handle case when target is a string or something (possible in deep copy)
                +	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
                +		target = {};
                +	}
                +
                +	// Extend jQuery itself if only one argument is passed
                +	if ( i === length ) {
                +		target = this;
                +		i--;
                +	}
                +
                +	for ( ; i < length; i++ ) {
                +
                +		// Only deal with non-null/undefined values
                +		if ( ( options = arguments[ i ] ) != null ) {
                +
                +			// Extend the base object
                +			for ( name in options ) {
                +				src = target[ name ];
                +				copy = options[ name ];
                +
                +				// Prevent never-ending loop
                +				if ( target === copy ) {
                +					continue;
                +				}
                +
                +				// Recurse if we're merging plain objects or arrays
                +				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                +					( copyIsArray = Array.isArray( copy ) ) ) ) {
                +
                +					if ( copyIsArray ) {
                +						copyIsArray = false;
                +						clone = src && Array.isArray( src ) ? src : [];
                +
                +					} else {
                +						clone = src && jQuery.isPlainObject( src ) ? src : {};
                +					}
                +
                +					// Never move original objects, clone them
                +					target[ name ] = jQuery.extend( deep, clone, copy );
                +
                +				// Don't bring in undefined values
                +				} else if ( copy !== undefined ) {
                +					target[ name ] = copy;
                +				}
                +			}
                +		}
                +	}
                +
                +	// Return the modified object
                +	return target;
                +};
                +
                +jQuery.extend( {
                +
                +	// Unique for each copy of jQuery on the page
                +	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
                +
                +	// Assume jQuery is ready without the ready module
                +	isReady: true,
                +
                +	error: function( msg ) {
                +		throw new Error( msg );
                +	},
                +
                +	noop: function() {},
                +
                +	isFunction: function( obj ) {
                +		return jQuery.type( obj ) === "function";
                +	},
                +
                +	isWindow: function( obj ) {
                +		return obj != null && obj === obj.window;
                +	},
                +
                +	isNumeric: function( obj ) {
                +
                +		// As of jQuery 3.0, isNumeric is limited to
                +		// strings and numbers (primitives or objects)
                +		// that can be coerced to finite numbers (gh-2662)
                +		var type = jQuery.type( obj );
                +		return ( type === "number" || type === "string" ) &&
                +
                +			// parseFloat NaNs numeric-cast false positives ("")
                +			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
                +			// subtraction forces infinities to NaN
                +			!isNaN( obj - parseFloat( obj ) );
                +	},
                +
                +	isPlainObject: function( obj ) {
                +		var proto, Ctor;
                +
                +		// Detect obvious negatives
                +		// Use toString instead of jQuery.type to catch host objects
                +		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
                +			return false;
                +		}
                +
                +		proto = getProto( obj );
                +
                +		// Objects with no prototype (e.g., `Object.create( null )`) are plain
                +		if ( !proto ) {
                +			return true;
                +		}
                +
                +		// Objects with prototype are plain iff they were constructed by a global Object function
                +		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
                +		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
                +	},
                +
                +	isEmptyObject: function( obj ) {
                +
                +		/* eslint-disable no-unused-vars */
                +		// See https://github.com/eslint/eslint/issues/6125
                +		var name;
                +
                +		for ( name in obj ) {
                +			return false;
                +		}
                +		return true;
                +	},
                +
                +	type: function( obj ) {
                +		if ( obj == null ) {
                +			return obj + "";
                +		}
                +
                +		// Support: Android <=2.3 only (functionish RegExp)
                +		return typeof obj === "object" || typeof obj === "function" ?
                +			class2type[ toString.call( obj ) ] || "object" :
                +			typeof obj;
                +	},
                +
                +	// Evaluates a script in a global context
                +	globalEval: function( code ) {
                +		DOMEval( code );
                +	},
                +
                +	// Convert dashed to camelCase; used by the css and data modules
                +	// Support: IE <=9 - 11, Edge 12 - 13
                +	// Microsoft forgot to hump their vendor prefix (#9572)
                +	camelCase: function( string ) {
                +		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
                +	},
                +
                +	each: function( obj, callback ) {
                +		var length, i = 0;
                +
                +		if ( isArrayLike( obj ) ) {
                +			length = obj.length;
                +			for ( ; i < length; i++ ) {
                +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                +					break;
                +				}
                +			}
                +		} else {
                +			for ( i in obj ) {
                +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                +					break;
                +				}
                +			}
                +		}
                +
                +		return obj;
                +	},
                +
                +	// Support: Android <=4.0 only
                +	trim: function( text ) {
                +		return text == null ?
                +			"" :
                +			( text + "" ).replace( rtrim, "" );
                +	},
                +
                +	// results is for internal usage only
                +	makeArray: function( arr, results ) {
                +		var ret = results || [];
                +
                +		if ( arr != null ) {
                +			if ( isArrayLike( Object( arr ) ) ) {
                +				jQuery.merge( ret,
                +					typeof arr === "string" ?
                +					[ arr ] : arr
                +				);
                +			} else {
                +				push.call( ret, arr );
                +			}
                +		}
                +
                +		return ret;
                +	},
                +
                +	inArray: function( elem, arr, i ) {
                +		return arr == null ? -1 : indexOf.call( arr, elem, i );
                +	},
                +
                +	// Support: Android <=4.0 only, PhantomJS 1 only
                +	// push.apply(_, arraylike) throws on ancient WebKit
                +	merge: function( first, second ) {
                +		var len = +second.length,
                +			j = 0,
                +			i = first.length;
                +
                +		for ( ; j < len; j++ ) {
                +			first[ i++ ] = second[ j ];
                +		}
                +
                +		first.length = i;
                +
                +		return first;
                +	},
                +
                +	grep: function( elems, callback, invert ) {
                +		var callbackInverse,
                +			matches = [],
                +			i = 0,
                +			length = elems.length,
                +			callbackExpect = !invert;
                +
                +		// Go through the array, only saving the items
                +		// that pass the validator function
                +		for ( ; i < length; i++ ) {
                +			callbackInverse = !callback( elems[ i ], i );
                +			if ( callbackInverse !== callbackExpect ) {
                +				matches.push( elems[ i ] );
                +			}
                +		}
                +
                +		return matches;
                +	},
                +
                +	// arg is for internal usage only
                +	map: function( elems, callback, arg ) {
                +		var length, value,
                +			i = 0,
                +			ret = [];
                +
                +		// Go through the array, translating each of the items to their new values
                +		if ( isArrayLike( elems ) ) {
                +			length = elems.length;
                +			for ( ; i < length; i++ ) {
                +				value = callback( elems[ i ], i, arg );
                +
                +				if ( value != null ) {
                +					ret.push( value );
                +				}
                +			}
                +
                +		// Go through every key on the object,
                +		} else {
                +			for ( i in elems ) {
                +				value = callback( elems[ i ], i, arg );
                +
                +				if ( value != null ) {
                +					ret.push( value );
                +				}
                +			}
                +		}
                +
                +		// Flatten any nested arrays
                +		return concat.apply( [], ret );
                +	},
                +
                +	// A global GUID counter for objects
                +	guid: 1,
                +
                +	// Bind a function to a context, optionally partially applying any
                +	// arguments.
                +	proxy: function( fn, context ) {
                +		var tmp, args, proxy;
                +
                +		if ( typeof context === "string" ) {
                +			tmp = fn[ context ];
                +			context = fn;
                +			fn = tmp;
                +		}
                +
                +		// Quick check to determine if target is callable, in the spec
                +		// this throws a TypeError, but we will just return undefined.
                +		if ( !jQuery.isFunction( fn ) ) {
                +			return undefined;
                +		}
                +
                +		// Simulated bind
                +		args = slice.call( arguments, 2 );
                +		proxy = function() {
                +			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
                +		};
                +
                +		// Set the guid of unique handler to the same of original handler, so it can be removed
                +		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
                +
                +		return proxy;
                +	},
                +
                +	now: Date.now,
                +
                +	// jQuery.support is not used in Core but other projects attach their
                +	// properties to it so it needs to exist.
                +	support: support
                +} );
                +
                +if ( typeof Symbol === "function" ) {
                +	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
                +}
                +
                +// Populate the class2type map
                +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
                +function( i, name ) {
                +	class2type[ "[object " + name + "]" ] = name.toLowerCase();
                +} );
                +
                +function isArrayLike( obj ) {
                +
                +	// Support: real iOS 8.2 only (not reproducible in simulator)
                +	// `in` check used to prevent JIT error (gh-2145)
                +	// hasOwn isn't used here due to false negatives
                +	// regarding Nodelist length in IE
                +	var length = !!obj && "length" in obj && obj.length,
                +		type = jQuery.type( obj );
                +
                +	if ( type === "function" || jQuery.isWindow( obj ) ) {
                +		return false;
                +	}
                +
                +	return type === "array" || length === 0 ||
                +		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
                +}
                +var Sizzle =
                +/*!
                + * Sizzle CSS Selector Engine v2.3.3
                + * https://sizzlejs.com/
                + *
                + * Copyright jQuery Foundation and other contributors
                + * Released under the MIT license
                + * http://jquery.org/license
                + *
                + * Date: 2016-08-08
                + */
                +(function( window ) {
                +
                +var i,
                +	support,
                +	Expr,
                +	getText,
                +	isXML,
                +	tokenize,
                +	compile,
                +	select,
                +	outermostContext,
                +	sortInput,
                +	hasDuplicate,
                +
                +	// Local document vars
                +	setDocument,
                +	document,
                +	docElem,
                +	documentIsHTML,
                +	rbuggyQSA,
                +	rbuggyMatches,
                +	matches,
                +	contains,
                +
                +	// Instance-specific data
                +	expando = "sizzle" + 1 * new Date(),
                +	preferredDoc = window.document,
                +	dirruns = 0,
                +	done = 0,
                +	classCache = createCache(),
                +	tokenCache = createCache(),
                +	compilerCache = createCache(),
                +	sortOrder = function( a, b ) {
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +		}
                +		return 0;
                +	},
                +
                +	// Instance methods
                +	hasOwn = ({}).hasOwnProperty,
                +	arr = [],
                +	pop = arr.pop,
                +	push_native = arr.push,
                +	push = arr.push,
                +	slice = arr.slice,
                +	// Use a stripped-down indexOf as it's faster than native
                +	// https://jsperf.com/thor-indexof-vs-for/5
                +	indexOf = function( list, elem ) {
                +		var i = 0,
                +			len = list.length;
                +		for ( ; i < len; i++ ) {
                +			if ( list[i] === elem ) {
                +				return i;
                +			}
                +		}
                +		return -1;
                +	},
                +
                +	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                +
                +	// Regular expressions
                +
                +	// http://www.w3.org/TR/css3-selectors/#whitespace
                +	whitespace = "[\\x20\\t\\r\\n\\f]",
                +
                +	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
                +	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
                +
                +	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
                +	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
                +		// Operator (capture 2)
                +		"*([*^$|!~]?=)" + whitespace +
                +		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
                +		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
                +		"*\\]",
                +
                +	pseudos = ":(" + identifier + ")(?:\\((" +
                +		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
                +		// 1. quoted (capture 3; capture 4 or capture 5)
                +		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
                +		// 2. simple (capture 6)
                +		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
                +		// 3. anything else (capture 2)
                +		".*" +
                +		")\\)|)",
                +
                +	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
                +	rwhitespace = new RegExp( whitespace + "+", "g" ),
                +	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
                +
                +	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
                +	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
                +
                +	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
                +
                +	rpseudo = new RegExp( pseudos ),
                +	ridentifier = new RegExp( "^" + identifier + "$" ),
                +
                +	matchExpr = {
                +		"ID": new RegExp( "^#(" + identifier + ")" ),
                +		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
                +		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
                +		"ATTR": new RegExp( "^" + attributes ),
                +		"PSEUDO": new RegExp( "^" + pseudos ),
                +		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
                +			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
                +			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
                +		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
                +		// For use in libraries implementing .is()
                +		// We use this for POS matching in `select`
                +		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
                +			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
                +	},
                +
                +	rinputs = /^(?:input|select|textarea|button)$/i,
                +	rheader = /^h\d$/i,
                +
                +	rnative = /^[^{]+\{\s*\[native \w/,
                +
                +	// Easily-parseable/retrievable ID or TAG or CLASS selectors
                +	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                +
                +	rsibling = /[+~]/,
                +
                +	// CSS escapes
                +	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
                +	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
                +	funescape = function( _, escaped, escapedWhitespace ) {
                +		var high = "0x" + escaped - 0x10000;
                +		// NaN means non-codepoint
                +		// Support: Firefox<24
                +		// Workaround erroneous numeric interpretation of +"0x"
                +		return high !== high || escapedWhitespace ?
                +			escaped :
                +			high < 0 ?
                +				// BMP codepoint
                +				String.fromCharCode( high + 0x10000 ) :
                +				// Supplemental Plane codepoint (surrogate pair)
                +				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
                +	},
                +
                +	// CSS string/identifier serialization
                +	// https://drafts.csswg.org/cssom/#common-serializing-idioms
                +	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
                +	fcssescape = function( ch, asCodePoint ) {
                +		if ( asCodePoint ) {
                +
                +			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
                +			if ( ch === "\0" ) {
                +				return "\uFFFD";
                +			}
                +
                +			// Control characters and (dependent upon position) numbers get escaped as code points
                +			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
                +		}
                +
                +		// Other potentially-special ASCII characters get backslash-escaped
                +		return "\\" + ch;
                +	},
                +
                +	// Used for iframes
                +	// See setDocument()
                +	// Removing the function wrapper causes a "Permission Denied"
                +	// error in IE
                +	unloadHandler = function() {
                +		setDocument();
                +	},
                +
                +	disabledAncestor = addCombinator(
                +		function( elem ) {
                +			return elem.disabled === true && ("form" in elem || "label" in elem);
                +		},
                +		{ dir: "parentNode", next: "legend" }
                +	);
                +
                +// Optimize for push.apply( _, NodeList )
                +try {
                +	push.apply(
                +		(arr = slice.call( preferredDoc.childNodes )),
                +		preferredDoc.childNodes
                +	);
                +	// Support: Android<4.0
                +	// Detect silently failing push.apply
                +	arr[ preferredDoc.childNodes.length ].nodeType;
                +} catch ( e ) {
                +	push = { apply: arr.length ?
                +
                +		// Leverage slice if possible
                +		function( target, els ) {
                +			push_native.apply( target, slice.call(els) );
                +		} :
                +
                +		// Support: IE<9
                +		// Otherwise append directly
                +		function( target, els ) {
                +			var j = target.length,
                +				i = 0;
                +			// Can't trust NodeList.length
                +			while ( (target[j++] = els[i++]) ) {}
                +			target.length = j - 1;
                +		}
                +	};
                +}
                +
                +function Sizzle( selector, context, results, seed ) {
                +	var m, i, elem, nid, match, groups, newSelector,
                +		newContext = context && context.ownerDocument,
                +
                +		// nodeType defaults to 9, since context defaults to document
                +		nodeType = context ? context.nodeType : 9;
                +
                +	results = results || [];
                +
                +	// Return early from calls with invalid selector or context
                +	if ( typeof selector !== "string" || !selector ||
                +		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
                +
                +		return results;
                +	}
                +
                +	// Try to shortcut find operations (as opposed to filters) in HTML documents
                +	if ( !seed ) {
                +
                +		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
                +			setDocument( context );
                +		}
                +		context = context || document;
                +
                +		if ( documentIsHTML ) {
                +
                +			// If the selector is sufficiently simple, try using a "get*By*" DOM method
                +			// (excepting DocumentFragment context, where the methods don't exist)
                +			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
                +
                +				// ID selector
                +				if ( (m = match[1]) ) {
                +
                +					// Document context
                +					if ( nodeType === 9 ) {
                +						if ( (elem = context.getElementById( m )) ) {
                +
                +							// Support: IE, Opera, Webkit
                +							// TODO: identify versions
                +							// getElementById can match elements by name instead of ID
                +							if ( elem.id === m ) {
                +								results.push( elem );
                +								return results;
                +							}
                +						} else {
                +							return results;
                +						}
                +
                +					// Element context
                +					} else {
                +
                +						// Support: IE, Opera, Webkit
                +						// TODO: identify versions
                +						// getElementById can match elements by name instead of ID
                +						if ( newContext && (elem = newContext.getElementById( m )) &&
                +							contains( context, elem ) &&
                +							elem.id === m ) {
                +
                +							results.push( elem );
                +							return results;
                +						}
                +					}
                +
                +				// Type selector
                +				} else if ( match[2] ) {
                +					push.apply( results, context.getElementsByTagName( selector ) );
                +					return results;
                +
                +				// Class selector
                +				} else if ( (m = match[3]) && support.getElementsByClassName &&
                +					context.getElementsByClassName ) {
                +
                +					push.apply( results, context.getElementsByClassName( m ) );
                +					return results;
                +				}
                +			}
                +
                +			// Take advantage of querySelectorAll
                +			if ( support.qsa &&
                +				!compilerCache[ selector + " " ] &&
                +				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
                +
                +				if ( nodeType !== 1 ) {
                +					newContext = context;
                +					newSelector = selector;
                +
                +				// qSA looks outside Element context, which is not what we want
                +				// Thanks to Andrew Dupont for this workaround technique
                +				// Support: IE <=8
                +				// Exclude object elements
                +				} else if ( context.nodeName.toLowerCase() !== "object" ) {
                +
                +					// Capture the context ID, setting it first if necessary
                +					if ( (nid = context.getAttribute( "id" )) ) {
                +						nid = nid.replace( rcssescape, fcssescape );
                +					} else {
                +						context.setAttribute( "id", (nid = expando) );
                +					}
                +
                +					// Prefix every selector in the list
                +					groups = tokenize( selector );
                +					i = groups.length;
                +					while ( i-- ) {
                +						groups[i] = "#" + nid + " " + toSelector( groups[i] );
                +					}
                +					newSelector = groups.join( "," );
                +
                +					// Expand context for sibling selectors
                +					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
                +						context;
                +				}
                +
                +				if ( newSelector ) {
                +					try {
                +						push.apply( results,
                +							newContext.querySelectorAll( newSelector )
                +						);
                +						return results;
                +					} catch ( qsaError ) {
                +					} finally {
                +						if ( nid === expando ) {
                +							context.removeAttribute( "id" );
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	// All others
                +	return select( selector.replace( rtrim, "$1" ), context, results, seed );
                +}
                +
                +/**
                + * Create key-value caches of limited size
                + * @returns {function(string, object)} Returns the Object data after storing it on itself with
                + *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
                + *	deleting the oldest entry
                + */
                +function createCache() {
                +	var keys = [];
                +
                +	function cache( key, value ) {
                +		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
                +		if ( keys.push( key + " " ) > Expr.cacheLength ) {
                +			// Only keep the most recent entries
                +			delete cache[ keys.shift() ];
                +		}
                +		return (cache[ key + " " ] = value);
                +	}
                +	return cache;
                +}
                +
                +/**
                + * Mark a function for special use by Sizzle
                + * @param {Function} fn The function to mark
                + */
                +function markFunction( fn ) {
                +	fn[ expando ] = true;
                +	return fn;
                +}
                +
                +/**
                + * Support testing using an element
                + * @param {Function} fn Passed the created element and returns a boolean result
                + */
                +function assert( fn ) {
                +	var el = document.createElement("fieldset");
                +
                +	try {
                +		return !!fn( el );
                +	} catch (e) {
                +		return false;
                +	} finally {
                +		// Remove from its parent by default
                +		if ( el.parentNode ) {
                +			el.parentNode.removeChild( el );
                +		}
                +		// release memory in IE
                +		el = null;
                +	}
                +}
                +
                +/**
                + * Adds the same handler for all of the specified attrs
                + * @param {String} attrs Pipe-separated list of attributes
                + * @param {Function} handler The method that will be applied
                + */
                +function addHandle( attrs, handler ) {
                +	var arr = attrs.split("|"),
                +		i = arr.length;
                +
                +	while ( i-- ) {
                +		Expr.attrHandle[ arr[i] ] = handler;
                +	}
                +}
                +
                +/**
                + * Checks document order of two siblings
                + * @param {Element} a
                + * @param {Element} b
                + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
                + */
                +function siblingCheck( a, b ) {
                +	var cur = b && a,
                +		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
                +			a.sourceIndex - b.sourceIndex;
                +
                +	// Use IE sourceIndex if available on both nodes
                +	if ( diff ) {
                +		return diff;
                +	}
                +
                +	// Check if b follows a
                +	if ( cur ) {
                +		while ( (cur = cur.nextSibling) ) {
                +			if ( cur === b ) {
                +				return -1;
                +			}
                +		}
                +	}
                +
                +	return a ? 1 : -1;
                +}
                +
                +/**
                + * Returns a function to use in pseudos for input types
                + * @param {String} type
                + */
                +function createInputPseudo( type ) {
                +	return function( elem ) {
                +		var name = elem.nodeName.toLowerCase();
                +		return name === "input" && elem.type === type;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for buttons
                + * @param {String} type
                + */
                +function createButtonPseudo( type ) {
                +	return function( elem ) {
                +		var name = elem.nodeName.toLowerCase();
                +		return (name === "input" || name === "button") && elem.type === type;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for :enabled/:disabled
                + * @param {Boolean} disabled true for :disabled; false for :enabled
                + */
                +function createDisabledPseudo( disabled ) {
                +
                +	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
                +	return function( elem ) {
                +
                +		// Only certain elements can match :enabled or :disabled
                +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
                +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
                +		if ( "form" in elem ) {
                +
                +			// Check for inherited disabledness on relevant non-disabled elements:
                +			// * listed form-associated elements in a disabled fieldset
                +			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
                +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
                +			// * option elements in a disabled optgroup
                +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
                +			// All such elements have a "form" property.
                +			if ( elem.parentNode && elem.disabled === false ) {
                +
                +				// Option elements defer to a parent optgroup if present
                +				if ( "label" in elem ) {
                +					if ( "label" in elem.parentNode ) {
                +						return elem.parentNode.disabled === disabled;
                +					} else {
                +						return elem.disabled === disabled;
                +					}
                +				}
                +
                +				// Support: IE 6 - 11
                +				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
                +				return elem.isDisabled === disabled ||
                +
                +					// Where there is no isDisabled, check manually
                +					/* jshint -W018 */
                +					elem.isDisabled !== !disabled &&
                +						disabledAncestor( elem ) === disabled;
                +			}
                +
                +			return elem.disabled === disabled;
                +
                +		// Try to winnow out elements that can't be disabled before trusting the disabled property.
                +		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
                +		// even exist on them, let alone have a boolean value.
                +		} else if ( "label" in elem ) {
                +			return elem.disabled === disabled;
                +		}
                +
                +		// Remaining elements are neither :enabled nor :disabled
                +		return false;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for positionals
                + * @param {Function} fn
                + */
                +function createPositionalPseudo( fn ) {
                +	return markFunction(function( argument ) {
                +		argument = +argument;
                +		return markFunction(function( seed, matches ) {
                +			var j,
                +				matchIndexes = fn( [], seed.length, argument ),
                +				i = matchIndexes.length;
                +
                +			// Match elements found at the specified indexes
                +			while ( i-- ) {
                +				if ( seed[ (j = matchIndexes[i]) ] ) {
                +					seed[j] = !(matches[j] = seed[j]);
                +				}
                +			}
                +		});
                +	});
                +}
                +
                +/**
                + * Checks a node for validity as a Sizzle context
                + * @param {Element|Object=} context
                + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
                + */
                +function testContext( context ) {
                +	return context && typeof context.getElementsByTagName !== "undefined" && context;
                +}
                +
                +// Expose support vars for convenience
                +support = Sizzle.support = {};
                +
                +/**
                + * Detects XML nodes
                + * @param {Element|Object} elem An element or a document
                + * @returns {Boolean} True iff elem is a non-HTML XML node
                + */
                +isXML = Sizzle.isXML = function( elem ) {
                +	// documentElement is verified for cases where it doesn't yet exist
                +	// (such as loading iframes in IE - #4833)
                +	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
                +	return documentElement ? documentElement.nodeName !== "HTML" : false;
                +};
                +
                +/**
                + * Sets document-related variables once based on the current document
                + * @param {Element|Object} [doc] An element or document object to use to set the document
                + * @returns {Object} Returns the current document
                + */
                +setDocument = Sizzle.setDocument = function( node ) {
                +	var hasCompare, subWindow,
                +		doc = node ? node.ownerDocument || node : preferredDoc;
                +
                +	// Return early if doc is invalid or already selected
                +	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
                +		return document;
                +	}
                +
                +	// Update global variables
                +	document = doc;
                +	docElem = document.documentElement;
                +	documentIsHTML = !isXML( document );
                +
                +	// Support: IE 9-11, Edge
                +	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
                +	if ( preferredDoc !== document &&
                +		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
                +
                +		// Support: IE 11, Edge
                +		if ( subWindow.addEventListener ) {
                +			subWindow.addEventListener( "unload", unloadHandler, false );
                +
                +		// Support: IE 9 - 10 only
                +		} else if ( subWindow.attachEvent ) {
                +			subWindow.attachEvent( "onunload", unloadHandler );
                +		}
                +	}
                +
                +	/* Attributes
                +	---------------------------------------------------------------------- */
                +
                +	// Support: IE<8
                +	// Verify that getAttribute really returns attributes and not properties
                +	// (excepting IE8 booleans)
                +	support.attributes = assert(function( el ) {
                +		el.className = "i";
                +		return !el.getAttribute("className");
                +	});
                +
                +	/* getElement(s)By*
                +	---------------------------------------------------------------------- */
                +
                +	// Check if getElementsByTagName("*") returns only elements
                +	support.getElementsByTagName = assert(function( el ) {
                +		el.appendChild( document.createComment("") );
                +		return !el.getElementsByTagName("*").length;
                +	});
                +
                +	// Support: IE<9
                +	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
                +
                +	// Support: IE<10
                +	// Check if getElementById returns elements by name
                +	// The broken getElementById methods don't pick up programmatically-set names,
                +	// so use a roundabout getElementsByName test
                +	support.getById = assert(function( el ) {
                +		docElem.appendChild( el ).id = expando;
                +		return !document.getElementsByName || !document.getElementsByName( expando ).length;
                +	});
                +
                +	// ID filter and find
                +	if ( support.getById ) {
                +		Expr.filter["ID"] = function( id ) {
                +			var attrId = id.replace( runescape, funescape );
                +			return function( elem ) {
                +				return elem.getAttribute("id") === attrId;
                +			};
                +		};
                +		Expr.find["ID"] = function( id, context ) {
                +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
                +				var elem = context.getElementById( id );
                +				return elem ? [ elem ] : [];
                +			}
                +		};
                +	} else {
                +		Expr.filter["ID"] =  function( id ) {
                +			var attrId = id.replace( runescape, funescape );
                +			return function( elem ) {
                +				var node = typeof elem.getAttributeNode !== "undefined" &&
                +					elem.getAttributeNode("id");
                +				return node && node.value === attrId;
                +			};
                +		};
                +
                +		// Support: IE 6 - 7 only
                +		// getElementById is not reliable as a find shortcut
                +		Expr.find["ID"] = function( id, context ) {
                +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
                +				var node, i, elems,
                +					elem = context.getElementById( id );
                +
                +				if ( elem ) {
                +
                +					// Verify the id attribute
                +					node = elem.getAttributeNode("id");
                +					if ( node && node.value === id ) {
                +						return [ elem ];
                +					}
                +
                +					// Fall back on getElementsByName
                +					elems = context.getElementsByName( id );
                +					i = 0;
                +					while ( (elem = elems[i++]) ) {
                +						node = elem.getAttributeNode("id");
                +						if ( node && node.value === id ) {
                +							return [ elem ];
                +						}
                +					}
                +				}
                +
                +				return [];
                +			}
                +		};
                +	}
                +
                +	// Tag
                +	Expr.find["TAG"] = support.getElementsByTagName ?
                +		function( tag, context ) {
                +			if ( typeof context.getElementsByTagName !== "undefined" ) {
                +				return context.getElementsByTagName( tag );
                +
                +			// DocumentFragment nodes don't have gEBTN
                +			} else if ( support.qsa ) {
                +				return context.querySelectorAll( tag );
                +			}
                +		} :
                +
                +		function( tag, context ) {
                +			var elem,
                +				tmp = [],
                +				i = 0,
                +				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
                +				results = context.getElementsByTagName( tag );
                +
                +			// Filter out possible comments
                +			if ( tag === "*" ) {
                +				while ( (elem = results[i++]) ) {
                +					if ( elem.nodeType === 1 ) {
                +						tmp.push( elem );
                +					}
                +				}
                +
                +				return tmp;
                +			}
                +			return results;
                +		};
                +
                +	// Class
                +	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
                +		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
                +			return context.getElementsByClassName( className );
                +		}
                +	};
                +
                +	/* QSA/matchesSelector
                +	---------------------------------------------------------------------- */
                +
                +	// QSA and matchesSelector support
                +
                +	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
                +	rbuggyMatches = [];
                +
                +	// qSa(:focus) reports false when true (Chrome 21)
                +	// We allow this because of a bug in IE8/9 that throws an error
                +	// whenever `document.activeElement` is accessed on an iframe
                +	// So, we allow :focus to pass through QSA all the time to avoid the IE error
                +	// See https://bugs.jquery.com/ticket/13378
                +	rbuggyQSA = [];
                +
                +	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
                +		// Build QSA regex
                +		// Regex strategy adopted from Diego Perini
                +		assert(function( el ) {
                +			// Select is set to empty string on purpose
                +			// This is to test IE's treatment of not explicitly
                +			// setting a boolean content attribute,
                +			// since its presence should be enough
                +			// https://bugs.jquery.com/ticket/12359
                +			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
                +				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
                +				"<option selected=''></option></select>";
                +
                +			// Support: IE8, Opera 11-12.16
                +			// Nothing should be selected when empty strings follow ^= or $= or *=
                +			// The test attribute must be unknown in Opera but "safe" for WinRT
                +			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
                +			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
                +				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
                +			}
                +
                +			// Support: IE8
                +			// Boolean attributes and "value" are not treated correctly
                +			if ( !el.querySelectorAll("[selected]").length ) {
                +				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
                +			}
                +
                +			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
                +			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
                +				rbuggyQSA.push("~=");
                +			}
                +
                +			// Webkit/Opera - :checked should return selected option elements
                +			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                +			// IE8 throws error here and will not see later tests
                +			if ( !el.querySelectorAll(":checked").length ) {
                +				rbuggyQSA.push(":checked");
                +			}
                +
                +			// Support: Safari 8+, iOS 8+
                +			// https://bugs.webkit.org/show_bug.cgi?id=136851
                +			// In-page `selector#id sibling-combinator selector` fails
                +			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
                +				rbuggyQSA.push(".#.+[+~]");
                +			}
                +		});
                +
                +		assert(function( el ) {
                +			el.innerHTML = "<a href='' disabled='disabled'></a>" +
                +				"<select disabled='disabled'><option/></select>";
                +
                +			// Support: Windows 8 Native Apps
                +			// The type and name attributes are restricted during .innerHTML assignment
                +			var input = document.createElement("input");
                +			input.setAttribute( "type", "hidden" );
                +			el.appendChild( input ).setAttribute( "name", "D" );
                +
                +			// Support: IE8
                +			// Enforce case-sensitivity of name attribute
                +			if ( el.querySelectorAll("[name=d]").length ) {
                +				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
                +			}
                +
                +			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
                +			// IE8 throws error here and will not see later tests
                +			if ( el.querySelectorAll(":enabled").length !== 2 ) {
                +				rbuggyQSA.push( ":enabled", ":disabled" );
                +			}
                +
                +			// Support: IE9-11+
                +			// IE's :disabled selector does not pick up the children of disabled fieldsets
                +			docElem.appendChild( el ).disabled = true;
                +			if ( el.querySelectorAll(":disabled").length !== 2 ) {
                +				rbuggyQSA.push( ":enabled", ":disabled" );
                +			}
                +
                +			// Opera 10-11 does not throw on post-comma invalid pseudos
                +			el.querySelectorAll("*,:x");
                +			rbuggyQSA.push(",.*:");
                +		});
                +	}
                +
                +	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
                +		docElem.webkitMatchesSelector ||
                +		docElem.mozMatchesSelector ||
                +		docElem.oMatchesSelector ||
                +		docElem.msMatchesSelector) )) ) {
                +
                +		assert(function( el ) {
                +			// Check to see if it's possible to do matchesSelector
                +			// on a disconnected node (IE 9)
                +			support.disconnectedMatch = matches.call( el, "*" );
                +
                +			// This should fail with an exception
                +			// Gecko does not error, returns false instead
                +			matches.call( el, "[s!='']:x" );
                +			rbuggyMatches.push( "!=", pseudos );
                +		});
                +	}
                +
                +	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
                +	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
                +
                +	/* Contains
                +	---------------------------------------------------------------------- */
                +	hasCompare = rnative.test( docElem.compareDocumentPosition );
                +
                +	// Element contains another
                +	// Purposefully self-exclusive
                +	// As in, an element does not contain itself
                +	contains = hasCompare || rnative.test( docElem.contains ) ?
                +		function( a, b ) {
                +			var adown = a.nodeType === 9 ? a.documentElement : a,
                +				bup = b && b.parentNode;
                +			return a === bup || !!( bup && bup.nodeType === 1 && (
                +				adown.contains ?
                +					adown.contains( bup ) :
                +					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
                +			));
                +		} :
                +		function( a, b ) {
                +			if ( b ) {
                +				while ( (b = b.parentNode) ) {
                +					if ( b === a ) {
                +						return true;
                +					}
                +				}
                +			}
                +			return false;
                +		};
                +
                +	/* Sorting
                +	---------------------------------------------------------------------- */
                +
                +	// Document order sorting
                +	sortOrder = hasCompare ?
                +	function( a, b ) {
                +
                +		// Flag for duplicate removal
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +			return 0;
                +		}
                +
                +		// Sort on method existence if only one input has compareDocumentPosition
                +		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
                +		if ( compare ) {
                +			return compare;
                +		}
                +
                +		// Calculate position if both inputs belong to the same document
                +		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
                +			a.compareDocumentPosition( b ) :
                +
                +			// Otherwise we know they are disconnected
                +			1;
                +
                +		// Disconnected nodes
                +		if ( compare & 1 ||
                +			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
                +
                +			// Choose the first element that is related to our preferred document
                +			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
                +				return -1;
                +			}
                +			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
                +				return 1;
                +			}
                +
                +			// Maintain original order
                +			return sortInput ?
                +				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
                +				0;
                +		}
                +
                +		return compare & 4 ? -1 : 1;
                +	} :
                +	function( a, b ) {
                +		// Exit early if the nodes are identical
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +			return 0;
                +		}
                +
                +		var cur,
                +			i = 0,
                +			aup = a.parentNode,
                +			bup = b.parentNode,
                +			ap = [ a ],
                +			bp = [ b ];
                +
                +		// Parentless nodes are either documents or disconnected
                +		if ( !aup || !bup ) {
                +			return a === document ? -1 :
                +				b === document ? 1 :
                +				aup ? -1 :
                +				bup ? 1 :
                +				sortInput ?
                +				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
                +				0;
                +
                +		// If the nodes are siblings, we can do a quick check
                +		} else if ( aup === bup ) {
                +			return siblingCheck( a, b );
                +		}
                +
                +		// Otherwise we need full lists of their ancestors for comparison
                +		cur = a;
                +		while ( (cur = cur.parentNode) ) {
                +			ap.unshift( cur );
                +		}
                +		cur = b;
                +		while ( (cur = cur.parentNode) ) {
                +			bp.unshift( cur );
                +		}
                +
                +		// Walk down the tree looking for a discrepancy
                +		while ( ap[i] === bp[i] ) {
                +			i++;
                +		}
                +
                +		return i ?
                +			// Do a sibling check if the nodes have a common ancestor
                +			siblingCheck( ap[i], bp[i] ) :
                +
                +			// Otherwise nodes in our document sort first
                +			ap[i] === preferredDoc ? -1 :
                +			bp[i] === preferredDoc ? 1 :
                +			0;
                +	};
                +
                +	return document;
                +};
                +
                +Sizzle.matches = function( expr, elements ) {
                +	return Sizzle( expr, null, null, elements );
                +};
                +
                +Sizzle.matchesSelector = function( elem, expr ) {
                +	// Set document vars if needed
                +	if ( ( elem.ownerDocument || elem ) !== document ) {
                +		setDocument( elem );
                +	}
                +
                +	// Make sure that attribute selectors are quoted
                +	expr = expr.replace( rattributeQuotes, "='$1']" );
                +
                +	if ( support.matchesSelector && documentIsHTML &&
                +		!compilerCache[ expr + " " ] &&
                +		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
                +		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
                +
                +		try {
                +			var ret = matches.call( elem, expr );
                +
                +			// IE 9's matchesSelector returns false on disconnected nodes
                +			if ( ret || support.disconnectedMatch ||
                +					// As well, disconnected nodes are said to be in a document
                +					// fragment in IE 9
                +					elem.document && elem.document.nodeType !== 11 ) {
                +				return ret;
                +			}
                +		} catch (e) {}
                +	}
                +
                +	return Sizzle( expr, document, null, [ elem ] ).length > 0;
                +};
                +
                +Sizzle.contains = function( context, elem ) {
                +	// Set document vars if needed
                +	if ( ( context.ownerDocument || context ) !== document ) {
                +		setDocument( context );
                +	}
                +	return contains( context, elem );
                +};
                +
                +Sizzle.attr = function( elem, name ) {
                +	// Set document vars if needed
                +	if ( ( elem.ownerDocument || elem ) !== document ) {
                +		setDocument( elem );
                +	}
                +
                +	var fn = Expr.attrHandle[ name.toLowerCase() ],
                +		// Don't get fooled by Object.prototype properties (jQuery #13807)
                +		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
                +			fn( elem, name, !documentIsHTML ) :
                +			undefined;
                +
                +	return val !== undefined ?
                +		val :
                +		support.attributes || !documentIsHTML ?
                +			elem.getAttribute( name ) :
                +			(val = elem.getAttributeNode(name)) && val.specified ?
                +				val.value :
                +				null;
                +};
                +
                +Sizzle.escape = function( sel ) {
                +	return (sel + "").replace( rcssescape, fcssescape );
                +};
                +
                +Sizzle.error = function( msg ) {
                +	throw new Error( "Syntax error, unrecognized expression: " + msg );
                +};
                +
                +/**
                + * Document sorting and removing duplicates
                + * @param {ArrayLike} results
                + */
                +Sizzle.uniqueSort = function( results ) {
                +	var elem,
                +		duplicates = [],
                +		j = 0,
                +		i = 0;
                +
                +	// Unless we *know* we can detect duplicates, assume their presence
                +	hasDuplicate = !support.detectDuplicates;
                +	sortInput = !support.sortStable && results.slice( 0 );
                +	results.sort( sortOrder );
                +
                +	if ( hasDuplicate ) {
                +		while ( (elem = results[i++]) ) {
                +			if ( elem === results[ i ] ) {
                +				j = duplicates.push( i );
                +			}
                +		}
                +		while ( j-- ) {
                +			results.splice( duplicates[ j ], 1 );
                +		}
                +	}
                +
                +	// Clear input after sorting to release objects
                +	// See https://github.com/jquery/sizzle/pull/225
                +	sortInput = null;
                +
                +	return results;
                +};
                +
                +/**
                + * Utility function for retrieving the text value of an array of DOM nodes
                + * @param {Array|Element} elem
                + */
                +getText = Sizzle.getText = function( elem ) {
                +	var node,
                +		ret = "",
                +		i = 0,
                +		nodeType = elem.nodeType;
                +
                +	if ( !nodeType ) {
                +		// If no nodeType, this is expected to be an array
                +		while ( (node = elem[i++]) ) {
                +			// Do not traverse comment nodes
                +			ret += getText( node );
                +		}
                +	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
                +		// Use textContent for elements
                +		// innerText usage removed for consistency of new lines (jQuery #11153)
                +		if ( typeof elem.textContent === "string" ) {
                +			return elem.textContent;
                +		} else {
                +			// Traverse its children
                +			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                +				ret += getText( elem );
                +			}
                +		}
                +	} else if ( nodeType === 3 || nodeType === 4 ) {
                +		return elem.nodeValue;
                +	}
                +	// Do not include comment or processing instruction nodes
                +
                +	return ret;
                +};
                +
                +Expr = Sizzle.selectors = {
                +
                +	// Can be adjusted by the user
                +	cacheLength: 50,
                +
                +	createPseudo: markFunction,
                +
                +	match: matchExpr,
                +
                +	attrHandle: {},
                +
                +	find: {},
                +
                +	relative: {
                +		">": { dir: "parentNode", first: true },
                +		" ": { dir: "parentNode" },
                +		"+": { dir: "previousSibling", first: true },
                +		"~": { dir: "previousSibling" }
                +	},
                +
                +	preFilter: {
                +		"ATTR": function( match ) {
                +			match[1] = match[1].replace( runescape, funescape );
                +
                +			// Move the given value to match[3] whether quoted or unquoted
                +			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
                +
                +			if ( match[2] === "~=" ) {
                +				match[3] = " " + match[3] + " ";
                +			}
                +
                +			return match.slice( 0, 4 );
                +		},
                +
                +		"CHILD": function( match ) {
                +			/* matches from matchExpr["CHILD"]
                +				1 type (only|nth|...)
                +				2 what (child|of-type)
                +				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
                +				4 xn-component of xn+y argument ([+-]?\d*n|)
                +				5 sign of xn-component
                +				6 x of xn-component
                +				7 sign of y-component
                +				8 y of y-component
                +			*/
                +			match[1] = match[1].toLowerCase();
                +
                +			if ( match[1].slice( 0, 3 ) === "nth" ) {
                +				// nth-* requires argument
                +				if ( !match[3] ) {
                +					Sizzle.error( match[0] );
                +				}
                +
                +				// numeric x and y parameters for Expr.filter.CHILD
                +				// remember that false/true cast respectively to 0/1
                +				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
                +				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
                +
                +			// other types prohibit arguments
                +			} else if ( match[3] ) {
                +				Sizzle.error( match[0] );
                +			}
                +
                +			return match;
                +		},
                +
                +		"PSEUDO": function( match ) {
                +			var excess,
                +				unquoted = !match[6] && match[2];
                +
                +			if ( matchExpr["CHILD"].test( match[0] ) ) {
                +				return null;
                +			}
                +
                +			// Accept quoted arguments as-is
                +			if ( match[3] ) {
                +				match[2] = match[4] || match[5] || "";
                +
                +			// Strip excess characters from unquoted arguments
                +			} else if ( unquoted && rpseudo.test( unquoted ) &&
                +				// Get excess from tokenize (recursively)
                +				(excess = tokenize( unquoted, true )) &&
                +				// advance to the next closing parenthesis
                +				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
                +
                +				// excess is a negative index
                +				match[0] = match[0].slice( 0, excess );
                +				match[2] = unquoted.slice( 0, excess );
                +			}
                +
                +			// Return only captures needed by the pseudo filter method (type and argument)
                +			return match.slice( 0, 3 );
                +		}
                +	},
                +
                +	filter: {
                +
                +		"TAG": function( nodeNameSelector ) {
                +			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
                +			return nodeNameSelector === "*" ?
                +				function() { return true; } :
                +				function( elem ) {
                +					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
                +				};
                +		},
                +
                +		"CLASS": function( className ) {
                +			var pattern = classCache[ className + " " ];
                +
                +			return pattern ||
                +				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
                +				classCache( className, function( elem ) {
                +					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
                +				});
                +		},
                +
                +		"ATTR": function( name, operator, check ) {
                +			return function( elem ) {
                +				var result = Sizzle.attr( elem, name );
                +
                +				if ( result == null ) {
                +					return operator === "!=";
                +				}
                +				if ( !operator ) {
                +					return true;
                +				}
                +
                +				result += "";
                +
                +				return operator === "=" ? result === check :
                +					operator === "!=" ? result !== check :
                +					operator === "^=" ? check && result.indexOf( check ) === 0 :
                +					operator === "*=" ? check && result.indexOf( check ) > -1 :
                +					operator === "$=" ? check && result.slice( -check.length ) === check :
                +					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
                +					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
                +					false;
                +			};
                +		},
                +
                +		"CHILD": function( type, what, argument, first, last ) {
                +			var simple = type.slice( 0, 3 ) !== "nth",
                +				forward = type.slice( -4 ) !== "last",
                +				ofType = what === "of-type";
                +
                +			return first === 1 && last === 0 ?
                +
                +				// Shortcut for :nth-*(n)
                +				function( elem ) {
                +					return !!elem.parentNode;
                +				} :
                +
                +				function( elem, context, xml ) {
                +					var cache, uniqueCache, outerCache, node, nodeIndex, start,
                +						dir = simple !== forward ? "nextSibling" : "previousSibling",
                +						parent = elem.parentNode,
                +						name = ofType && elem.nodeName.toLowerCase(),
                +						useCache = !xml && !ofType,
                +						diff = false;
                +
                +					if ( parent ) {
                +
                +						// :(first|last|only)-(child|of-type)
                +						if ( simple ) {
                +							while ( dir ) {
                +								node = elem;
                +								while ( (node = node[ dir ]) ) {
                +									if ( ofType ?
                +										node.nodeName.toLowerCase() === name :
                +										node.nodeType === 1 ) {
                +
                +										return false;
                +									}
                +								}
                +								// Reverse direction for :only-* (if we haven't yet done so)
                +								start = dir = type === "only" && !start && "nextSibling";
                +							}
                +							return true;
                +						}
                +
                +						start = [ forward ? parent.firstChild : parent.lastChild ];
                +
                +						// non-xml :nth-child(...) stores cache data on `parent`
                +						if ( forward && useCache ) {
                +
                +							// Seek `elem` from a previously-cached index
                +
                +							// ...in a gzip-friendly way
                +							node = parent;
                +							outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +							// Support: IE <9 only
                +							// Defend against cloned attroperties (jQuery gh-1709)
                +							uniqueCache = outerCache[ node.uniqueID ] ||
                +								(outerCache[ node.uniqueID ] = {});
                +
                +							cache = uniqueCache[ type ] || [];
                +							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                +							diff = nodeIndex && cache[ 2 ];
                +							node = nodeIndex && parent.childNodes[ nodeIndex ];
                +
                +							while ( (node = ++nodeIndex && node && node[ dir ] ||
                +
                +								// Fallback to seeking `elem` from the start
                +								(diff = nodeIndex = 0) || start.pop()) ) {
                +
                +								// When found, cache indexes on `parent` and break
                +								if ( node.nodeType === 1 && ++diff && node === elem ) {
                +									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
                +									break;
                +								}
                +							}
                +
                +						} else {
                +							// Use previously-cached element index if available
                +							if ( useCache ) {
                +								// ...in a gzip-friendly way
                +								node = elem;
                +								outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +								// Support: IE <9 only
                +								// Defend against cloned attroperties (jQuery gh-1709)
                +								uniqueCache = outerCache[ node.uniqueID ] ||
                +									(outerCache[ node.uniqueID ] = {});
                +
                +								cache = uniqueCache[ type ] || [];
                +								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                +								diff = nodeIndex;
                +							}
                +
                +							// xml :nth-child(...)
                +							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
                +							if ( diff === false ) {
                +								// Use the same loop as above to seek `elem` from the start
                +								while ( (node = ++nodeIndex && node && node[ dir ] ||
                +									(diff = nodeIndex = 0) || start.pop()) ) {
                +
                +									if ( ( ofType ?
                +										node.nodeName.toLowerCase() === name :
                +										node.nodeType === 1 ) &&
                +										++diff ) {
                +
                +										// Cache the index of each encountered element
                +										if ( useCache ) {
                +											outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +											// Support: IE <9 only
                +											// Defend against cloned attroperties (jQuery gh-1709)
                +											uniqueCache = outerCache[ node.uniqueID ] ||
                +												(outerCache[ node.uniqueID ] = {});
                +
                +											uniqueCache[ type ] = [ dirruns, diff ];
                +										}
                +
                +										if ( node === elem ) {
                +											break;
                +										}
                +									}
                +								}
                +							}
                +						}
                +
                +						// Incorporate the offset, then check against cycle size
                +						diff -= last;
                +						return diff === first || ( diff % first === 0 && diff / first >= 0 );
                +					}
                +				};
                +		},
                +
                +		"PSEUDO": function( pseudo, argument ) {
                +			// pseudo-class names are case-insensitive
                +			// http://www.w3.org/TR/selectors/#pseudo-classes
                +			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
                +			// Remember that setFilters inherits from pseudos
                +			var args,
                +				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                +					Sizzle.error( "unsupported pseudo: " + pseudo );
                +
                +			// The user may use createPseudo to indicate that
                +			// arguments are needed to create the filter function
                +			// just as Sizzle does
                +			if ( fn[ expando ] ) {
                +				return fn( argument );
                +			}
                +
                +			// But maintain support for old signatures
                +			if ( fn.length > 1 ) {
                +				args = [ pseudo, pseudo, "", argument ];
                +				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                +					markFunction(function( seed, matches ) {
                +						var idx,
                +							matched = fn( seed, argument ),
                +							i = matched.length;
                +						while ( i-- ) {
                +							idx = indexOf( seed, matched[i] );
                +							seed[ idx ] = !( matches[ idx ] = matched[i] );
                +						}
                +					}) :
                +					function( elem ) {
                +						return fn( elem, 0, args );
                +					};
                +			}
                +
                +			return fn;
                +		}
                +	},
                +
                +	pseudos: {
                +		// Potentially complex pseudos
                +		"not": markFunction(function( selector ) {
                +			// Trim the selector passed to compile
                +			// to avoid treating leading and trailing
                +			// spaces as combinators
                +			var input = [],
                +				results = [],
                +				matcher = compile( selector.replace( rtrim, "$1" ) );
                +
                +			return matcher[ expando ] ?
                +				markFunction(function( seed, matches, context, xml ) {
                +					var elem,
                +						unmatched = matcher( seed, null, xml, [] ),
                +						i = seed.length;
                +
                +					// Match elements unmatched by `matcher`
                +					while ( i-- ) {
                +						if ( (elem = unmatched[i]) ) {
                +							seed[i] = !(matches[i] = elem);
                +						}
                +					}
                +				}) :
                +				function( elem, context, xml ) {
                +					input[0] = elem;
                +					matcher( input, null, xml, results );
                +					// Don't keep the element (issue #299)
                +					input[0] = null;
                +					return !results.pop();
                +				};
                +		}),
                +
                +		"has": markFunction(function( selector ) {
                +			return function( elem ) {
                +				return Sizzle( selector, elem ).length > 0;
                +			};
                +		}),
                +
                +		"contains": markFunction(function( text ) {
                +			text = text.replace( runescape, funescape );
                +			return function( elem ) {
                +				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
                +			};
                +		}),
                +
                +		// "Whether an element is represented by a :lang() selector
                +		// is based solely on the element's language value
                +		// being equal to the identifier C,
                +		// or beginning with the identifier C immediately followed by "-".
                +		// The matching of C against the element's language value is performed case-insensitively.
                +		// The identifier C does not have to be a valid language name."
                +		// http://www.w3.org/TR/selectors/#lang-pseudo
                +		"lang": markFunction( function( lang ) {
                +			// lang value must be a valid identifier
                +			if ( !ridentifier.test(lang || "") ) {
                +				Sizzle.error( "unsupported lang: " + lang );
                +			}
                +			lang = lang.replace( runescape, funescape ).toLowerCase();
                +			return function( elem ) {
                +				var elemLang;
                +				do {
                +					if ( (elemLang = documentIsHTML ?
                +						elem.lang :
                +						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
                +
                +						elemLang = elemLang.toLowerCase();
                +						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
                +					}
                +				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
                +				return false;
                +			};
                +		}),
                +
                +		// Miscellaneous
                +		"target": function( elem ) {
                +			var hash = window.location && window.location.hash;
                +			return hash && hash.slice( 1 ) === elem.id;
                +		},
                +
                +		"root": function( elem ) {
                +			return elem === docElem;
                +		},
                +
                +		"focus": function( elem ) {
                +			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
                +		},
                +
                +		// Boolean properties
                +		"enabled": createDisabledPseudo( false ),
                +		"disabled": createDisabledPseudo( true ),
                +
                +		"checked": function( elem ) {
                +			// In CSS3, :checked should return both checked and selected elements
                +			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                +			var nodeName = elem.nodeName.toLowerCase();
                +			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
                +		},
                +
                +		"selected": function( elem ) {
                +			// Accessing this property makes selected-by-default
                +			// options in Safari work properly
                +			if ( elem.parentNode ) {
                +				elem.parentNode.selectedIndex;
                +			}
                +
                +			return elem.selected === true;
                +		},
                +
                +		// Contents
                +		"empty": function( elem ) {
                +			// http://www.w3.org/TR/selectors/#empty-pseudo
                +			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
                +			//   but not by others (comment: 8; processing instruction: 7; etc.)
                +			// nodeType < 6 works because attributes (2) do not appear as children
                +			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                +				if ( elem.nodeType < 6 ) {
                +					return false;
                +				}
                +			}
                +			return true;
                +		},
                +
                +		"parent": function( elem ) {
                +			return !Expr.pseudos["empty"]( elem );
                +		},
                +
                +		// Element/input types
                +		"header": function( elem ) {
                +			return rheader.test( elem.nodeName );
                +		},
                +
                +		"input": function( elem ) {
                +			return rinputs.test( elem.nodeName );
                +		},
                +
                +		"button": function( elem ) {
                +			var name = elem.nodeName.toLowerCase();
                +			return name === "input" && elem.type === "button" || name === "button";
                +		},
                +
                +		"text": function( elem ) {
                +			var attr;
                +			return elem.nodeName.toLowerCase() === "input" &&
                +				elem.type === "text" &&
                +
                +				// Support: IE<8
                +				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
                +				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
                +		},
                +
                +		// Position-in-collection
                +		"first": createPositionalPseudo(function() {
                +			return [ 0 ];
                +		}),
                +
                +		"last": createPositionalPseudo(function( matchIndexes, length ) {
                +			return [ length - 1 ];
                +		}),
                +
                +		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			return [ argument < 0 ? argument + length : argument ];
                +		}),
                +
                +		"even": createPositionalPseudo(function( matchIndexes, length ) {
                +			var i = 0;
                +			for ( ; i < length; i += 2 ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"odd": createPositionalPseudo(function( matchIndexes, length ) {
                +			var i = 1;
                +			for ( ; i < length; i += 2 ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			var i = argument < 0 ? argument + length : argument;
                +			for ( ; --i >= 0; ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			var i = argument < 0 ? argument + length : argument;
                +			for ( ; ++i < length; ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		})
                +	}
                +};
                +
                +Expr.pseudos["nth"] = Expr.pseudos["eq"];
                +
                +// Add button/input type pseudos
                +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
                +	Expr.pseudos[ i ] = createInputPseudo( i );
                +}
                +for ( i in { submit: true, reset: true } ) {
                +	Expr.pseudos[ i ] = createButtonPseudo( i );
                +}
                +
                +// Easy API for creating new setFilters
                +function setFilters() {}
                +setFilters.prototype = Expr.filters = Expr.pseudos;
                +Expr.setFilters = new setFilters();
                +
                +tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
                +	var matched, match, tokens, type,
                +		soFar, groups, preFilters,
                +		cached = tokenCache[ selector + " " ];
                +
                +	if ( cached ) {
                +		return parseOnly ? 0 : cached.slice( 0 );
                +	}
                +
                +	soFar = selector;
                +	groups = [];
                +	preFilters = Expr.preFilter;
                +
                +	while ( soFar ) {
                +
                +		// Comma and first run
                +		if ( !matched || (match = rcomma.exec( soFar )) ) {
                +			if ( match ) {
                +				// Don't consume trailing commas as valid
                +				soFar = soFar.slice( match[0].length ) || soFar;
                +			}
                +			groups.push( (tokens = []) );
                +		}
                +
                +		matched = false;
                +
                +		// Combinators
                +		if ( (match = rcombinators.exec( soFar )) ) {
                +			matched = match.shift();
                +			tokens.push({
                +				value: matched,
                +				// Cast descendant combinators to space
                +				type: match[0].replace( rtrim, " " )
                +			});
                +			soFar = soFar.slice( matched.length );
                +		}
                +
                +		// Filters
                +		for ( type in Expr.filter ) {
                +			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
                +				(match = preFilters[ type ]( match ))) ) {
                +				matched = match.shift();
                +				tokens.push({
                +					value: matched,
                +					type: type,
                +					matches: match
                +				});
                +				soFar = soFar.slice( matched.length );
                +			}
                +		}
                +
                +		if ( !matched ) {
                +			break;
                +		}
                +	}
                +
                +	// Return the length of the invalid excess
                +	// if we're just parsing
                +	// Otherwise, throw an error or return tokens
                +	return parseOnly ?
                +		soFar.length :
                +		soFar ?
                +			Sizzle.error( selector ) :
                +			// Cache the tokens
                +			tokenCache( selector, groups ).slice( 0 );
                +};
                +
                +function toSelector( tokens ) {
                +	var i = 0,
                +		len = tokens.length,
                +		selector = "";
                +	for ( ; i < len; i++ ) {
                +		selector += tokens[i].value;
                +	}
                +	return selector;
                +}
                +
                +function addCombinator( matcher, combinator, base ) {
                +	var dir = combinator.dir,
                +		skip = combinator.next,
                +		key = skip || dir,
                +		checkNonElements = base && key === "parentNode",
                +		doneName = done++;
                +
                +	return combinator.first ?
                +		// Check against closest ancestor/preceding element
                +		function( elem, context, xml ) {
                +			while ( (elem = elem[ dir ]) ) {
                +				if ( elem.nodeType === 1 || checkNonElements ) {
                +					return matcher( elem, context, xml );
                +				}
                +			}
                +			return false;
                +		} :
                +
                +		// Check against all ancestor/preceding elements
                +		function( elem, context, xml ) {
                +			var oldCache, uniqueCache, outerCache,
                +				newCache = [ dirruns, doneName ];
                +
                +			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
                +			if ( xml ) {
                +				while ( (elem = elem[ dir ]) ) {
                +					if ( elem.nodeType === 1 || checkNonElements ) {
                +						if ( matcher( elem, context, xml ) ) {
                +							return true;
                +						}
                +					}
                +				}
                +			} else {
                +				while ( (elem = elem[ dir ]) ) {
                +					if ( elem.nodeType === 1 || checkNonElements ) {
                +						outerCache = elem[ expando ] || (elem[ expando ] = {});
                +
                +						// Support: IE <9 only
                +						// Defend against cloned attroperties (jQuery gh-1709)
                +						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
                +
                +						if ( skip && skip === elem.nodeName.toLowerCase() ) {
                +							elem = elem[ dir ] || elem;
                +						} else if ( (oldCache = uniqueCache[ key ]) &&
                +							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
                +
                +							// Assign to newCache so results back-propagate to previous elements
                +							return (newCache[ 2 ] = oldCache[ 2 ]);
                +						} else {
                +							// Reuse newcache so results back-propagate to previous elements
                +							uniqueCache[ key ] = newCache;
                +
                +							// A match means we're done; a fail means we have to keep checking
                +							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
                +								return true;
                +							}
                +						}
                +					}
                +				}
                +			}
                +			return false;
                +		};
                +}
                +
                +function elementMatcher( matchers ) {
                +	return matchers.length > 1 ?
                +		function( elem, context, xml ) {
                +			var i = matchers.length;
                +			while ( i-- ) {
                +				if ( !matchers[i]( elem, context, xml ) ) {
                +					return false;
                +				}
                +			}
                +			return true;
                +		} :
                +		matchers[0];
                +}
                +
                +function multipleContexts( selector, contexts, results ) {
                +	var i = 0,
                +		len = contexts.length;
                +	for ( ; i < len; i++ ) {
                +		Sizzle( selector, contexts[i], results );
                +	}
                +	return results;
                +}
                +
                +function condense( unmatched, map, filter, context, xml ) {
                +	var elem,
                +		newUnmatched = [],
                +		i = 0,
                +		len = unmatched.length,
                +		mapped = map != null;
                +
                +	for ( ; i < len; i++ ) {
                +		if ( (elem = unmatched[i]) ) {
                +			if ( !filter || filter( elem, context, xml ) ) {
                +				newUnmatched.push( elem );
                +				if ( mapped ) {
                +					map.push( i );
                +				}
                +			}
                +		}
                +	}
                +
                +	return newUnmatched;
                +}
                +
                +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
                +	if ( postFilter && !postFilter[ expando ] ) {
                +		postFilter = setMatcher( postFilter );
                +	}
                +	if ( postFinder && !postFinder[ expando ] ) {
                +		postFinder = setMatcher( postFinder, postSelector );
                +	}
                +	return markFunction(function( seed, results, context, xml ) {
                +		var temp, i, elem,
                +			preMap = [],
                +			postMap = [],
                +			preexisting = results.length,
                +
                +			// Get initial elements from seed or context
                +			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
                +
                +			// Prefilter to get matcher input, preserving a map for seed-results synchronization
                +			matcherIn = preFilter && ( seed || !selector ) ?
                +				condense( elems, preMap, preFilter, context, xml ) :
                +				elems,
                +
                +			matcherOut = matcher ?
                +				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
                +				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
                +
                +					// ...intermediate processing is necessary
                +					[] :
                +
                +					// ...otherwise use results directly
                +					results :
                +				matcherIn;
                +
                +		// Find primary matches
                +		if ( matcher ) {
                +			matcher( matcherIn, matcherOut, context, xml );
                +		}
                +
                +		// Apply postFilter
                +		if ( postFilter ) {
                +			temp = condense( matcherOut, postMap );
                +			postFilter( temp, [], context, xml );
                +
                +			// Un-match failing elements by moving them back to matcherIn
                +			i = temp.length;
                +			while ( i-- ) {
                +				if ( (elem = temp[i]) ) {
                +					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
                +				}
                +			}
                +		}
                +
                +		if ( seed ) {
                +			if ( postFinder || preFilter ) {
                +				if ( postFinder ) {
                +					// Get the final matcherOut by condensing this intermediate into postFinder contexts
                +					temp = [];
                +					i = matcherOut.length;
                +					while ( i-- ) {
                +						if ( (elem = matcherOut[i]) ) {
                +							// Restore matcherIn since elem is not yet a final match
                +							temp.push( (matcherIn[i] = elem) );
                +						}
                +					}
                +					postFinder( null, (matcherOut = []), temp, xml );
                +				}
                +
                +				// Move matched elements from seed to results to keep them synchronized
                +				i = matcherOut.length;
                +				while ( i-- ) {
                +					if ( (elem = matcherOut[i]) &&
                +						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
                +
                +						seed[temp] = !(results[temp] = elem);
                +					}
                +				}
                +			}
                +
                +		// Add elements to results, through postFinder if defined
                +		} else {
                +			matcherOut = condense(
                +				matcherOut === results ?
                +					matcherOut.splice( preexisting, matcherOut.length ) :
                +					matcherOut
                +			);
                +			if ( postFinder ) {
                +				postFinder( null, results, matcherOut, xml );
                +			} else {
                +				push.apply( results, matcherOut );
                +			}
                +		}
                +	});
                +}
                +
                +function matcherFromTokens( tokens ) {
                +	var checkContext, matcher, j,
                +		len = tokens.length,
                +		leadingRelative = Expr.relative[ tokens[0].type ],
                +		implicitRelative = leadingRelative || Expr.relative[" "],
                +		i = leadingRelative ? 1 : 0,
                +
                +		// The foundational matcher ensures that elements are reachable from top-level context(s)
                +		matchContext = addCombinator( function( elem ) {
                +			return elem === checkContext;
                +		}, implicitRelative, true ),
                +		matchAnyContext = addCombinator( function( elem ) {
                +			return indexOf( checkContext, elem ) > -1;
                +		}, implicitRelative, true ),
                +		matchers = [ function( elem, context, xml ) {
                +			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
                +				(checkContext = context).nodeType ?
                +					matchContext( elem, context, xml ) :
                +					matchAnyContext( elem, context, xml ) );
                +			// Avoid hanging onto element (issue #299)
                +			checkContext = null;
                +			return ret;
                +		} ];
                +
                +	for ( ; i < len; i++ ) {
                +		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
                +			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
                +		} else {
                +			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
                +
                +			// Return special upon seeing a positional matcher
                +			if ( matcher[ expando ] ) {
                +				// Find the next relative operator (if any) for proper handling
                +				j = ++i;
                +				for ( ; j < len; j++ ) {
                +					if ( Expr.relative[ tokens[j].type ] ) {
                +						break;
                +					}
                +				}
                +				return setMatcher(
                +					i > 1 && elementMatcher( matchers ),
                +					i > 1 && toSelector(
                +						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
                +						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
                +					).replace( rtrim, "$1" ),
                +					matcher,
                +					i < j && matcherFromTokens( tokens.slice( i, j ) ),
                +					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
                +					j < len && toSelector( tokens )
                +				);
                +			}
                +			matchers.push( matcher );
                +		}
                +	}
                +
                +	return elementMatcher( matchers );
                +}
                +
                +function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
                +	var bySet = setMatchers.length > 0,
                +		byElement = elementMatchers.length > 0,
                +		superMatcher = function( seed, context, xml, results, outermost ) {
                +			var elem, j, matcher,
                +				matchedCount = 0,
                +				i = "0",
                +				unmatched = seed && [],
                +				setMatched = [],
                +				contextBackup = outermostContext,
                +				// We must always have either seed elements or outermost context
                +				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
                +				// Use integer dirruns iff this is the outermost matcher
                +				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
                +				len = elems.length;
                +
                +			if ( outermost ) {
                +				outermostContext = context === document || context || outermost;
                +			}
                +
                +			// Add elements passing elementMatchers directly to results
                +			// Support: IE<9, Safari
                +			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
                +			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
                +				if ( byElement && elem ) {
                +					j = 0;
                +					if ( !context && elem.ownerDocument !== document ) {
                +						setDocument( elem );
                +						xml = !documentIsHTML;
                +					}
                +					while ( (matcher = elementMatchers[j++]) ) {
                +						if ( matcher( elem, context || document, xml) ) {
                +							results.push( elem );
                +							break;
                +						}
                +					}
                +					if ( outermost ) {
                +						dirruns = dirrunsUnique;
                +					}
                +				}
                +
                +				// Track unmatched elements for set filters
                +				if ( bySet ) {
                +					// They will have gone through all possible matchers
                +					if ( (elem = !matcher && elem) ) {
                +						matchedCount--;
                +					}
                +
                +					// Lengthen the array for every element, matched or not
                +					if ( seed ) {
                +						unmatched.push( elem );
                +					}
                +				}
                +			}
                +
                +			// `i` is now the count of elements visited above, and adding it to `matchedCount`
                +			// makes the latter nonnegative.
                +			matchedCount += i;
                +
                +			// Apply set filters to unmatched elements
                +			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
                +			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
                +			// no element matchers and no seed.
                +			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
                +			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
                +			// numerically zero.
                +			if ( bySet && i !== matchedCount ) {
                +				j = 0;
                +				while ( (matcher = setMatchers[j++]) ) {
                +					matcher( unmatched, setMatched, context, xml );
                +				}
                +
                +				if ( seed ) {
                +					// Reintegrate element matches to eliminate the need for sorting
                +					if ( matchedCount > 0 ) {
                +						while ( i-- ) {
                +							if ( !(unmatched[i] || setMatched[i]) ) {
                +								setMatched[i] = pop.call( results );
                +							}
                +						}
                +					}
                +
                +					// Discard index placeholder values to get only actual matches
                +					setMatched = condense( setMatched );
                +				}
                +
                +				// Add matches to results
                +				push.apply( results, setMatched );
                +
                +				// Seedless set matches succeeding multiple successful matchers stipulate sorting
                +				if ( outermost && !seed && setMatched.length > 0 &&
                +					( matchedCount + setMatchers.length ) > 1 ) {
                +
                +					Sizzle.uniqueSort( results );
                +				}
                +			}
                +
                +			// Override manipulation of globals by nested matchers
                +			if ( outermost ) {
                +				dirruns = dirrunsUnique;
                +				outermostContext = contextBackup;
                +			}
                +
                +			return unmatched;
                +		};
                +
                +	return bySet ?
                +		markFunction( superMatcher ) :
                +		superMatcher;
                +}
                +
                +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
                +	var i,
                +		setMatchers = [],
                +		elementMatchers = [],
                +		cached = compilerCache[ selector + " " ];
                +
                +	if ( !cached ) {
                +		// Generate a function of recursive functions that can be used to check each element
                +		if ( !match ) {
                +			match = tokenize( selector );
                +		}
                +		i = match.length;
                +		while ( i-- ) {
                +			cached = matcherFromTokens( match[i] );
                +			if ( cached[ expando ] ) {
                +				setMatchers.push( cached );
                +			} else {
                +				elementMatchers.push( cached );
                +			}
                +		}
                +
                +		// Cache the compiled function
                +		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
                +
                +		// Save selector and tokenization
                +		cached.selector = selector;
                +	}
                +	return cached;
                +};
                +
                +/**
                + * A low-level selection function that works with Sizzle's compiled
                + *  selector functions
                + * @param {String|Function} selector A selector or a pre-compiled
                + *  selector function built with Sizzle.compile
                + * @param {Element} context
                + * @param {Array} [results]
                + * @param {Array} [seed] A set of elements to match against
                + */
                +select = Sizzle.select = function( selector, context, results, seed ) {
                +	var i, tokens, token, type, find,
                +		compiled = typeof selector === "function" && selector,
                +		match = !seed && tokenize( (selector = compiled.selector || selector) );
                +
                +	results = results || [];
                +
                +	// Try to minimize operations if there is only one selector in the list and no seed
                +	// (the latter of which guarantees us context)
                +	if ( match.length === 1 ) {
                +
                +		// Reduce context if the leading compound selector is an ID
                +		tokens = match[0] = match[0].slice( 0 );
                +		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
                +				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
                +
                +			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
                +			if ( !context ) {
                +				return results;
                +
                +			// Precompiled matchers will still verify ancestry, so step up a level
                +			} else if ( compiled ) {
                +				context = context.parentNode;
                +			}
                +
                +			selector = selector.slice( tokens.shift().value.length );
                +		}
                +
                +		// Fetch a seed set for right-to-left matching
                +		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
                +		while ( i-- ) {
                +			token = tokens[i];
                +
                +			// Abort if we hit a combinator
                +			if ( Expr.relative[ (type = token.type) ] ) {
                +				break;
                +			}
                +			if ( (find = Expr.find[ type ]) ) {
                +				// Search, expanding context for leading sibling combinators
                +				if ( (seed = find(
                +					token.matches[0].replace( runescape, funescape ),
                +					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
                +				)) ) {
                +
                +					// If seed is empty or no tokens remain, we can return early
                +					tokens.splice( i, 1 );
                +					selector = seed.length && toSelector( tokens );
                +					if ( !selector ) {
                +						push.apply( results, seed );
                +						return results;
                +					}
                +
                +					break;
                +				}
                +			}
                +		}
                +	}
                +
                +	// Compile and execute a filtering function if one is not provided
                +	// Provide `match` to avoid retokenization if we modified the selector above
                +	( compiled || compile( selector, match ) )(
                +		seed,
                +		context,
                +		!documentIsHTML,
                +		results,
                +		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
                +	);
                +	return results;
                +};
                +
                +// One-time assignments
                +
                +// Sort stability
                +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
                +
                +// Support: Chrome 14-35+
                +// Always assume duplicates if they aren't passed to the comparison function
                +support.detectDuplicates = !!hasDuplicate;
                +
                +// Initialize against the default document
                +setDocument();
                +
                +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
                +// Detached nodes confoundingly follow *each other*
                +support.sortDetached = assert(function( el ) {
                +	// Should return 1, but returns 4 (following)
                +	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
                +});
                +
                +// Support: IE<8
                +// Prevent attribute/property "interpolation"
                +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
                +if ( !assert(function( el ) {
                +	el.innerHTML = "<a href='#'></a>";
                +	return el.firstChild.getAttribute("href") === "#" ;
                +}) ) {
                +	addHandle( "type|href|height|width", function( elem, name, isXML ) {
                +		if ( !isXML ) {
                +			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
                +		}
                +	});
                +}
                +
                +// Support: IE<9
                +// Use defaultValue in place of getAttribute("value")
                +if ( !support.attributes || !assert(function( el ) {
                +	el.innerHTML = "<input/>";
                +	el.firstChild.setAttribute( "value", "" );
                +	return el.firstChild.getAttribute( "value" ) === "";
                +}) ) {
                +	addHandle( "value", function( elem, name, isXML ) {
                +		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
                +			return elem.defaultValue;
                +		}
                +	});
                +}
                +
                +// Support: IE<9
                +// Use getAttributeNode to fetch booleans when getAttribute lies
                +if ( !assert(function( el ) {
                +	return el.getAttribute("disabled") == null;
                +}) ) {
                +	addHandle( booleans, function( elem, name, isXML ) {
                +		var val;
                +		if ( !isXML ) {
                +			return elem[ name ] === true ? name.toLowerCase() :
                +					(val = elem.getAttributeNode( name )) && val.specified ?
                +					val.value :
                +				null;
                +		}
                +	});
                +}
                +
                +return Sizzle;
                +
                +})( window );
                +
                +
                +
                +jQuery.find = Sizzle;
                +jQuery.expr = Sizzle.selectors;
                +
                +// Deprecated
                +jQuery.expr[ ":" ] = jQuery.expr.pseudos;
                +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
                +jQuery.text = Sizzle.getText;
                +jQuery.isXMLDoc = Sizzle.isXML;
                +jQuery.contains = Sizzle.contains;
                +jQuery.escapeSelector = Sizzle.escape;
                +
                +
                +
                +
                +var dir = function( elem, dir, until ) {
                +	var matched = [],
                +		truncate = until !== undefined;
                +
                +	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
                +		if ( elem.nodeType === 1 ) {
                +			if ( truncate && jQuery( elem ).is( until ) ) {
                +				break;
                +			}
                +			matched.push( elem );
                +		}
                +	}
                +	return matched;
                +};
                +
                +
                +var siblings = function( n, elem ) {
                +	var matched = [];
                +
                +	for ( ; n; n = n.nextSibling ) {
                +		if ( n.nodeType === 1 && n !== elem ) {
                +			matched.push( n );
                +		}
                +	}
                +
                +	return matched;
                +};
                +
                +
                +var rneedsContext = jQuery.expr.match.needsContext;
                +
                +
                +
                +function nodeName( elem, name ) {
                +
                +  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
                +
                +};
                +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
                +
                +
                +
                +var risSimple = /^.[^:#\[\.,]*$/;
                +
                +// Implement the identical functionality for filter and not
                +function winnow( elements, qualifier, not ) {
                +	if ( jQuery.isFunction( qualifier ) ) {
                +		return jQuery.grep( elements, function( elem, i ) {
                +			return !!qualifier.call( elem, i, elem ) !== not;
                +		} );
                +	}
                +
                +	// Single element
                +	if ( qualifier.nodeType ) {
                +		return jQuery.grep( elements, function( elem ) {
                +			return ( elem === qualifier ) !== not;
                +		} );
                +	}
                +
                +	// Arraylike of elements (jQuery, arguments, Array)
                +	if ( typeof qualifier !== "string" ) {
                +		return jQuery.grep( elements, function( elem ) {
                +			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
                +		} );
                +	}
                +
                +	// Simple selector that can be filtered directly, removing non-Elements
                +	if ( risSimple.test( qualifier ) ) {
                +		return jQuery.filter( qualifier, elements, not );
                +	}
                +
                +	// Complex selector, compare the two sets, removing non-Elements
                +	qualifier = jQuery.filter( qualifier, elements );
                +	return jQuery.grep( elements, function( elem ) {
                +		return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
                +	} );
                +}
                +
                +jQuery.filter = function( expr, elems, not ) {
                +	var elem = elems[ 0 ];
                +
                +	if ( not ) {
                +		expr = ":not(" + expr + ")";
                +	}
                +
                +	if ( elems.length === 1 && elem.nodeType === 1 ) {
                +		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
                +	}
                +
                +	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
                +		return elem.nodeType === 1;
                +	} ) );
                +};
                +
                +jQuery.fn.extend( {
                +	find: function( selector ) {
                +		var i, ret,
                +			len = this.length,
                +			self = this;
                +
                +		if ( typeof selector !== "string" ) {
                +			return this.pushStack( jQuery( selector ).filter( function() {
                +				for ( i = 0; i < len; i++ ) {
                +					if ( jQuery.contains( self[ i ], this ) ) {
                +						return true;
                +					}
                +				}
                +			} ) );
                +		}
                +
                +		ret = this.pushStack( [] );
                +
                +		for ( i = 0; i < len; i++ ) {
                +			jQuery.find( selector, self[ i ], ret );
                +		}
                +
                +		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
                +	},
                +	filter: function( selector ) {
                +		return this.pushStack( winnow( this, selector || [], false ) );
                +	},
                +	not: function( selector ) {
                +		return this.pushStack( winnow( this, selector || [], true ) );
                +	},
                +	is: function( selector ) {
                +		return !!winnow(
                +			this,
                +
                +			// If this is a positional/relative selector, check membership in the returned set
                +			// so $("p:first").is("p:last") won't return true for a doc with two "p".
                +			typeof selector === "string" && rneedsContext.test( selector ) ?
                +				jQuery( selector ) :
                +				selector || [],
                +			false
                +		).length;
                +	}
                +} );
                +
                +
                +// Initialize a jQuery object
                +
                +
                +// A central reference to the root jQuery(document)
                +var rootjQuery,
                +
                +	// A simple way to check for HTML strings
                +	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
                +	// Strict HTML recognition (#11290: must start with <)
                +	// Shortcut simple #id case for speed
                +	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
                +
                +	init = jQuery.fn.init = function( selector, context, root ) {
                +		var match, elem;
                +
                +		// HANDLE: $(""), $(null), $(undefined), $(false)
                +		if ( !selector ) {
                +			return this;
                +		}
                +
                +		// Method init() accepts an alternate rootjQuery
                +		// so migrate can support jQuery.sub (gh-2101)
                +		root = root || rootjQuery;
                +
                +		// Handle HTML strings
                +		if ( typeof selector === "string" ) {
                +			if ( selector[ 0 ] === "<" &&
                +				selector[ selector.length - 1 ] === ">" &&
                +				selector.length >= 3 ) {
                +
                +				// Assume that strings that start and end with <> are HTML and skip the regex check
                +				match = [ null, selector, null ];
                +
                +			} else {
                +				match = rquickExpr.exec( selector );
                +			}
                +
                +			// Match html or make sure no context is specified for #id
                +			if ( match && ( match[ 1 ] || !context ) ) {
                +
                +				// HANDLE: $(html) -> $(array)
                +				if ( match[ 1 ] ) {
                +					context = context instanceof jQuery ? context[ 0 ] : context;
                +
                +					// Option to run scripts is true for back-compat
                +					// Intentionally let the error be thrown if parseHTML is not present
                +					jQuery.merge( this, jQuery.parseHTML(
                +						match[ 1 ],
                +						context && context.nodeType ? context.ownerDocument || context : document,
                +						true
                +					) );
                +
                +					// HANDLE: $(html, props)
                +					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
                +						for ( match in context ) {
                +
                +							// Properties of context are called as methods if possible
                +							if ( jQuery.isFunction( this[ match ] ) ) {
                +								this[ match ]( context[ match ] );
                +
                +							// ...and otherwise set as attributes
                +							} else {
                +								this.attr( match, context[ match ] );
                +							}
                +						}
                +					}
                +
                +					return this;
                +
                +				// HANDLE: $(#id)
                +				} else {
                +					elem = document.getElementById( match[ 2 ] );
                +
                +					if ( elem ) {
                +
                +						// Inject the element directly into the jQuery object
                +						this[ 0 ] = elem;
                +						this.length = 1;
                +					}
                +					return this;
                +				}
                +
                +			// HANDLE: $(expr, $(...))
                +			} else if ( !context || context.jquery ) {
                +				return ( context || root ).find( selector );
                +
                +			// HANDLE: $(expr, context)
                +			// (which is just equivalent to: $(context).find(expr)
                +			} else {
                +				return this.constructor( context ).find( selector );
                +			}
                +
                +		// HANDLE: $(DOMElement)
                +		} else if ( selector.nodeType ) {
                +			this[ 0 ] = selector;
                +			this.length = 1;
                +			return this;
                +
                +		// HANDLE: $(function)
                +		// Shortcut for document ready
                +		} else if ( jQuery.isFunction( selector ) ) {
                +			return root.ready !== undefined ?
                +				root.ready( selector ) :
                +
                +				// Execute immediately if ready is not present
                +				selector( jQuery );
                +		}
                +
                +		return jQuery.makeArray( selector, this );
                +	};
                +
                +// Give the init function the jQuery prototype for later instantiation
                +init.prototype = jQuery.fn;
                +
                +// Initialize central reference
                +rootjQuery = jQuery( document );
                +
                +
                +var rparentsprev = /^(?:parents|prev(?:Until|All))/,
                +
                +	// Methods guaranteed to produce a unique set when starting from a unique set
                +	guaranteedUnique = {
                +		children: true,
                +		contents: true,
                +		next: true,
                +		prev: true
                +	};
                +
                +jQuery.fn.extend( {
                +	has: function( target ) {
                +		var targets = jQuery( target, this ),
                +			l = targets.length;
                +
                +		return this.filter( function() {
                +			var i = 0;
                +			for ( ; i < l; i++ ) {
                +				if ( jQuery.contains( this, targets[ i ] ) ) {
                +					return true;
                +				}
                +			}
                +		} );
                +	},
                +
                +	closest: function( selectors, context ) {
                +		var cur,
                +			i = 0,
                +			l = this.length,
                +			matched = [],
                +			targets = typeof selectors !== "string" && jQuery( selectors );
                +
                +		// Positional selectors never match, since there's no _selection_ context
                +		if ( !rneedsContext.test( selectors ) ) {
                +			for ( ; i < l; i++ ) {
                +				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
                +
                +					// Always skip document fragments
                +					if ( cur.nodeType < 11 && ( targets ?
                +						targets.index( cur ) > -1 :
                +
                +						// Don't pass non-elements to Sizzle
                +						cur.nodeType === 1 &&
                +							jQuery.find.matchesSelector( cur, selectors ) ) ) {
                +
                +						matched.push( cur );
                +						break;
                +					}
                +				}
                +			}
                +		}
                +
                +		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
                +	},
                +
                +	// Determine the position of an element within the set
                +	index: function( elem ) {
                +
                +		// No argument, return index in parent
                +		if ( !elem ) {
                +			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
                +		}
                +
                +		// Index in selector
                +		if ( typeof elem === "string" ) {
                +			return indexOf.call( jQuery( elem ), this[ 0 ] );
                +		}
                +
                +		// Locate the position of the desired element
                +		return indexOf.call( this,
                +
                +			// If it receives a jQuery object, the first element is used
                +			elem.jquery ? elem[ 0 ] : elem
                +		);
                +	},
                +
                +	add: function( selector, context ) {
                +		return this.pushStack(
                +			jQuery.uniqueSort(
                +				jQuery.merge( this.get(), jQuery( selector, context ) )
                +			)
                +		);
                +	},
                +
                +	addBack: function( selector ) {
                +		return this.add( selector == null ?
                +			this.prevObject : this.prevObject.filter( selector )
                +		);
                +	}
                +} );
                +
                +function sibling( cur, dir ) {
                +	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
                +	return cur;
                +}
                +
                +jQuery.each( {
                +	parent: function( elem ) {
                +		var parent = elem.parentNode;
                +		return parent && parent.nodeType !== 11 ? parent : null;
                +	},
                +	parents: function( elem ) {
                +		return dir( elem, "parentNode" );
                +	},
                +	parentsUntil: function( elem, i, until ) {
                +		return dir( elem, "parentNode", until );
                +	},
                +	next: function( elem ) {
                +		return sibling( elem, "nextSibling" );
                +	},
                +	prev: function( elem ) {
                +		return sibling( elem, "previousSibling" );
                +	},
                +	nextAll: function( elem ) {
                +		return dir( elem, "nextSibling" );
                +	},
                +	prevAll: function( elem ) {
                +		return dir( elem, "previousSibling" );
                +	},
                +	nextUntil: function( elem, i, until ) {
                +		return dir( elem, "nextSibling", until );
                +	},
                +	prevUntil: function( elem, i, until ) {
                +		return dir( elem, "previousSibling", until );
                +	},
                +	siblings: function( elem ) {
                +		return siblings( ( elem.parentNode || {} ).firstChild, elem );
                +	},
                +	children: function( elem ) {
                +		return siblings( elem.firstChild );
                +	},
                +	contents: function( elem ) {
                +        if ( nodeName( elem, "iframe" ) ) {
                +            return elem.contentDocument;
                +        }
                +
                +        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
                +        // Treat the template element as a regular one in browsers that
                +        // don't support it.
                +        if ( nodeName( elem, "template" ) ) {
                +            elem = elem.content || elem;
                +        }
                +
                +        return jQuery.merge( [], elem.childNodes );
                +	}
                +}, function( name, fn ) {
                +	jQuery.fn[ name ] = function( until, selector ) {
                +		var matched = jQuery.map( this, fn, until );
                +
                +		if ( name.slice( -5 ) !== "Until" ) {
                +			selector = until;
                +		}
                +
                +		if ( selector && typeof selector === "string" ) {
                +			matched = jQuery.filter( selector, matched );
                +		}
                +
                +		if ( this.length > 1 ) {
                +
                +			// Remove duplicates
                +			if ( !guaranteedUnique[ name ] ) {
                +				jQuery.uniqueSort( matched );
                +			}
                +
                +			// Reverse order for parents* and prev-derivatives
                +			if ( rparentsprev.test( name ) ) {
                +				matched.reverse();
                +			}
                +		}
                +
                +		return this.pushStack( matched );
                +	};
                +} );
                +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
                +
                +
                +
                +// Convert String-formatted options into Object-formatted ones
                +function createOptions( options ) {
                +	var object = {};
                +	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
                +		object[ flag ] = true;
                +	} );
                +	return object;
                +}
                +
                +/*
                + * Create a callback list using the following parameters:
                + *
                + *	options: an optional list of space-separated options that will change how
                + *			the callback list behaves or a more traditional option object
                + *
                + * By default a callback list will act like an event callback list and can be
                + * "fired" multiple times.
                + *
                + * Possible options:
                + *
                + *	once:			will ensure the callback list can only be fired once (like a Deferred)
                + *
                + *	memory:			will keep track of previous values and will call any callback added
                + *					after the list has been fired right away with the latest "memorized"
                + *					values (like a Deferred)
                + *
                + *	unique:			will ensure a callback can only be added once (no duplicate in the list)
                + *
                + *	stopOnFalse:	interrupt callings when a callback returns false
                + *
                + */
                +jQuery.Callbacks = function( options ) {
                +
                +	// Convert options from String-formatted to Object-formatted if needed
                +	// (we check in cache first)
                +	options = typeof options === "string" ?
                +		createOptions( options ) :
                +		jQuery.extend( {}, options );
                +
                +	var // Flag to know if list is currently firing
                +		firing,
                +
                +		// Last fire value for non-forgettable lists
                +		memory,
                +
                +		// Flag to know if list was already fired
                +		fired,
                +
                +		// Flag to prevent firing
                +		locked,
                +
                +		// Actual callback list
                +		list = [],
                +
                +		// Queue of execution data for repeatable lists
                +		queue = [],
                +
                +		// Index of currently firing callback (modified by add/remove as needed)
                +		firingIndex = -1,
                +
                +		// Fire callbacks
                +		fire = function() {
                +
                +			// Enforce single-firing
                +			locked = locked || options.once;
                +
                +			// Execute callbacks for all pending executions,
                +			// respecting firingIndex overrides and runtime changes
                +			fired = firing = true;
                +			for ( ; queue.length; firingIndex = -1 ) {
                +				memory = queue.shift();
                +				while ( ++firingIndex < list.length ) {
                +
                +					// Run callback and check for early termination
                +					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
                +						options.stopOnFalse ) {
                +
                +						// Jump to end and forget the data so .add doesn't re-fire
                +						firingIndex = list.length;
                +						memory = false;
                +					}
                +				}
                +			}
                +
                +			// Forget the data if we're done with it
                +			if ( !options.memory ) {
                +				memory = false;
                +			}
                +
                +			firing = false;
                +
                +			// Clean up if we're done firing for good
                +			if ( locked ) {
                +
                +				// Keep an empty list if we have data for future add calls
                +				if ( memory ) {
                +					list = [];
                +
                +				// Otherwise, this object is spent
                +				} else {
                +					list = "";
                +				}
                +			}
                +		},
                +
                +		// Actual Callbacks object
                +		self = {
                +
                +			// Add a callback or a collection of callbacks to the list
                +			add: function() {
                +				if ( list ) {
                +
                +					// If we have memory from a past run, we should fire after adding
                +					if ( memory && !firing ) {
                +						firingIndex = list.length - 1;
                +						queue.push( memory );
                +					}
                +
                +					( function add( args ) {
                +						jQuery.each( args, function( _, arg ) {
                +							if ( jQuery.isFunction( arg ) ) {
                +								if ( !options.unique || !self.has( arg ) ) {
                +									list.push( arg );
                +								}
                +							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
                +
                +								// Inspect recursively
                +								add( arg );
                +							}
                +						} );
                +					} )( arguments );
                +
                +					if ( memory && !firing ) {
                +						fire();
                +					}
                +				}
                +				return this;
                +			},
                +
                +			// Remove a callback from the list
                +			remove: function() {
                +				jQuery.each( arguments, function( _, arg ) {
                +					var index;
                +					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                +						list.splice( index, 1 );
                +
                +						// Handle firing indexes
                +						if ( index <= firingIndex ) {
                +							firingIndex--;
                +						}
                +					}
                +				} );
                +				return this;
                +			},
                +
                +			// Check if a given callback is in the list.
                +			// If no argument is given, return whether or not list has callbacks attached.
                +			has: function( fn ) {
                +				return fn ?
                +					jQuery.inArray( fn, list ) > -1 :
                +					list.length > 0;
                +			},
                +
                +			// Remove all callbacks from the list
                +			empty: function() {
                +				if ( list ) {
                +					list = [];
                +				}
                +				return this;
                +			},
                +
                +			// Disable .fire and .add
                +			// Abort any current/pending executions
                +			// Clear all callbacks and values
                +			disable: function() {
                +				locked = queue = [];
                +				list = memory = "";
                +				return this;
                +			},
                +			disabled: function() {
                +				return !list;
                +			},
                +
                +			// Disable .fire
                +			// Also disable .add unless we have memory (since it would have no effect)
                +			// Abort any pending executions
                +			lock: function() {
                +				locked = queue = [];
                +				if ( !memory && !firing ) {
                +					list = memory = "";
                +				}
                +				return this;
                +			},
                +			locked: function() {
                +				return !!locked;
                +			},
                +
                +			// Call all callbacks with the given context and arguments
                +			fireWith: function( context, args ) {
                +				if ( !locked ) {
                +					args = args || [];
                +					args = [ context, args.slice ? args.slice() : args ];
                +					queue.push( args );
                +					if ( !firing ) {
                +						fire();
                +					}
                +				}
                +				return this;
                +			},
                +
                +			// Call all the callbacks with the given arguments
                +			fire: function() {
                +				self.fireWith( this, arguments );
                +				return this;
                +			},
                +
                +			// To know if the callbacks have already been called at least once
                +			fired: function() {
                +				return !!fired;
                +			}
                +		};
                +
                +	return self;
                +};
                +
                +
                +function Identity( v ) {
                +	return v;
                +}
                +function Thrower( ex ) {
                +	throw ex;
                +}
                +
                +function adoptValue( value, resolve, reject, noValue ) {
                +	var method;
                +
                +	try {
                +
                +		// Check for promise aspect first to privilege synchronous behavior
                +		if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
                +			method.call( value ).done( resolve ).fail( reject );
                +
                +		// Other thenables
                +		} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
                +			method.call( value, resolve, reject );
                +
                +		// Other non-thenables
                +		} else {
                +
                +			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
                +			// * false: [ value ].slice( 0 ) => resolve( value )
                +			// * true: [ value ].slice( 1 ) => resolve()
                +			resolve.apply( undefined, [ value ].slice( noValue ) );
                +		}
                +
                +	// For Promises/A+, convert exceptions into rejections
                +	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
                +	// Deferred#then to conditionally suppress rejection.
                +	} catch ( value ) {
                +
                +		// Support: Android 4.0 only
                +		// Strict mode functions invoked without .call/.apply get global-object context
                +		reject.apply( undefined, [ value ] );
                +	}
                +}
                +
                +jQuery.extend( {
                +
                +	Deferred: function( func ) {
                +		var tuples = [
                +
                +				// action, add listener, callbacks,
                +				// ... .then handlers, argument index, [final state]
                +				[ "notify", "progress", jQuery.Callbacks( "memory" ),
                +					jQuery.Callbacks( "memory" ), 2 ],
                +				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
                +					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
                +				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
                +					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
                +			],
                +			state = "pending",
                +			promise = {
                +				state: function() {
                +					return state;
                +				},
                +				always: function() {
                +					deferred.done( arguments ).fail( arguments );
                +					return this;
                +				},
                +				"catch": function( fn ) {
                +					return promise.then( null, fn );
                +				},
                +
                +				// Keep pipe for back-compat
                +				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
                +					var fns = arguments;
                +
                +					return jQuery.Deferred( function( newDefer ) {
                +						jQuery.each( tuples, function( i, tuple ) {
                +
                +							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
                +							var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
                +
                +							// deferred.progress(function() { bind to newDefer or newDefer.notify })
                +							// deferred.done(function() { bind to newDefer or newDefer.resolve })
                +							// deferred.fail(function() { bind to newDefer or newDefer.reject })
                +							deferred[ tuple[ 1 ] ]( function() {
                +								var returned = fn && fn.apply( this, arguments );
                +								if ( returned && jQuery.isFunction( returned.promise ) ) {
                +									returned.promise()
                +										.progress( newDefer.notify )
                +										.done( newDefer.resolve )
                +										.fail( newDefer.reject );
                +								} else {
                +									newDefer[ tuple[ 0 ] + "With" ](
                +										this,
                +										fn ? [ returned ] : arguments
                +									);
                +								}
                +							} );
                +						} );
                +						fns = null;
                +					} ).promise();
                +				},
                +				then: function( onFulfilled, onRejected, onProgress ) {
                +					var maxDepth = 0;
                +					function resolve( depth, deferred, handler, special ) {
                +						return function() {
                +							var that = this,
                +								args = arguments,
                +								mightThrow = function() {
                +									var returned, then;
                +
                +									// Support: Promises/A+ section 2.3.3.3.3
                +									// https://promisesaplus.com/#point-59
                +									// Ignore double-resolution attempts
                +									if ( depth < maxDepth ) {
                +										return;
                +									}
                +
                +									returned = handler.apply( that, args );
                +
                +									// Support: Promises/A+ section 2.3.1
                +									// https://promisesaplus.com/#point-48
                +									if ( returned === deferred.promise() ) {
                +										throw new TypeError( "Thenable self-resolution" );
                +									}
                +
                +									// Support: Promises/A+ sections 2.3.3.1, 3.5
                +									// https://promisesaplus.com/#point-54
                +									// https://promisesaplus.com/#point-75
                +									// Retrieve `then` only once
                +									then = returned &&
                +
                +										// Support: Promises/A+ section 2.3.4
                +										// https://promisesaplus.com/#point-64
                +										// Only check objects and functions for thenability
                +										( typeof returned === "object" ||
                +											typeof returned === "function" ) &&
                +										returned.then;
                +
                +									// Handle a returned thenable
                +									if ( jQuery.isFunction( then ) ) {
                +
                +										// Special processors (notify) just wait for resolution
                +										if ( special ) {
                +											then.call(
                +												returned,
                +												resolve( maxDepth, deferred, Identity, special ),
                +												resolve( maxDepth, deferred, Thrower, special )
                +											);
                +
                +										// Normal processors (resolve) also hook into progress
                +										} else {
                +
                +											// ...and disregard older resolution values
                +											maxDepth++;
                +
                +											then.call(
                +												returned,
                +												resolve( maxDepth, deferred, Identity, special ),
                +												resolve( maxDepth, deferred, Thrower, special ),
                +												resolve( maxDepth, deferred, Identity,
                +													deferred.notifyWith )
                +											);
                +										}
                +
                +									// Handle all other returned values
                +									} else {
                +
                +										// Only substitute handlers pass on context
                +										// and multiple values (non-spec behavior)
                +										if ( handler !== Identity ) {
                +											that = undefined;
                +											args = [ returned ];
                +										}
                +
                +										// Process the value(s)
                +										// Default process is resolve
                +										( special || deferred.resolveWith )( that, args );
                +									}
                +								},
                +
                +								// Only normal processors (resolve) catch and reject exceptions
                +								process = special ?
                +									mightThrow :
                +									function() {
                +										try {
                +											mightThrow();
                +										} catch ( e ) {
                +
                +											if ( jQuery.Deferred.exceptionHook ) {
                +												jQuery.Deferred.exceptionHook( e,
                +													process.stackTrace );
                +											}
                +
                +											// Support: Promises/A+ section 2.3.3.3.4.1
                +											// https://promisesaplus.com/#point-61
                +											// Ignore post-resolution exceptions
                +											if ( depth + 1 >= maxDepth ) {
                +
                +												// Only substitute handlers pass on context
                +												// and multiple values (non-spec behavior)
                +												if ( handler !== Thrower ) {
                +													that = undefined;
                +													args = [ e ];
                +												}
                +
                +												deferred.rejectWith( that, args );
                +											}
                +										}
                +									};
                +
                +							// Support: Promises/A+ section 2.3.3.3.1
                +							// https://promisesaplus.com/#point-57
                +							// Re-resolve promises immediately to dodge false rejection from
                +							// subsequent errors
                +							if ( depth ) {
                +								process();
                +							} else {
                +
                +								// Call an optional hook to record the stack, in case of exception
                +								// since it's otherwise lost when execution goes async
                +								if ( jQuery.Deferred.getStackHook ) {
                +									process.stackTrace = jQuery.Deferred.getStackHook();
                +								}
                +								window.setTimeout( process );
                +							}
                +						};
                +					}
                +
                +					return jQuery.Deferred( function( newDefer ) {
                +
                +						// progress_handlers.add( ... )
                +						tuples[ 0 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onProgress ) ?
                +									onProgress :
                +									Identity,
                +								newDefer.notifyWith
                +							)
                +						);
                +
                +						// fulfilled_handlers.add( ... )
                +						tuples[ 1 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onFulfilled ) ?
                +									onFulfilled :
                +									Identity
                +							)
                +						);
                +
                +						// rejected_handlers.add( ... )
                +						tuples[ 2 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onRejected ) ?
                +									onRejected :
                +									Thrower
                +							)
                +						);
                +					} ).promise();
                +				},
                +
                +				// Get a promise for this deferred
                +				// If obj is provided, the promise aspect is added to the object
                +				promise: function( obj ) {
                +					return obj != null ? jQuery.extend( obj, promise ) : promise;
                +				}
                +			},
                +			deferred = {};
                +
                +		// Add list-specific methods
                +		jQuery.each( tuples, function( i, tuple ) {
                +			var list = tuple[ 2 ],
                +				stateString = tuple[ 5 ];
                +
                +			// promise.progress = list.add
                +			// promise.done = list.add
                +			// promise.fail = list.add
                +			promise[ tuple[ 1 ] ] = list.add;
                +
                +			// Handle state
                +			if ( stateString ) {
                +				list.add(
                +					function() {
                +
                +						// state = "resolved" (i.e., fulfilled)
                +						// state = "rejected"
                +						state = stateString;
                +					},
                +
                +					// rejected_callbacks.disable
                +					// fulfilled_callbacks.disable
                +					tuples[ 3 - i ][ 2 ].disable,
                +
                +					// progress_callbacks.lock
                +					tuples[ 0 ][ 2 ].lock
                +				);
                +			}
                +
                +			// progress_handlers.fire
                +			// fulfilled_handlers.fire
                +			// rejected_handlers.fire
                +			list.add( tuple[ 3 ].fire );
                +
                +			// deferred.notify = function() { deferred.notifyWith(...) }
                +			// deferred.resolve = function() { deferred.resolveWith(...) }
                +			// deferred.reject = function() { deferred.rejectWith(...) }
                +			deferred[ tuple[ 0 ] ] = function() {
                +				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
                +				return this;
                +			};
                +
                +			// deferred.notifyWith = list.fireWith
                +			// deferred.resolveWith = list.fireWith
                +			// deferred.rejectWith = list.fireWith
                +			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
                +		} );
                +
                +		// Make the deferred a promise
                +		promise.promise( deferred );
                +
                +		// Call given func if any
                +		if ( func ) {
                +			func.call( deferred, deferred );
                +		}
                +
                +		// All done!
                +		return deferred;
                +	},
                +
                +	// Deferred helper
                +	when: function( singleValue ) {
                +		var
                +
                +			// count of uncompleted subordinates
                +			remaining = arguments.length,
                +
                +			// count of unprocessed arguments
                +			i = remaining,
                +
                +			// subordinate fulfillment data
                +			resolveContexts = Array( i ),
                +			resolveValues = slice.call( arguments ),
                +
                +			// the master Deferred
                +			master = jQuery.Deferred(),
                +
                +			// subordinate callback factory
                +			updateFunc = function( i ) {
                +				return function( value ) {
                +					resolveContexts[ i ] = this;
                +					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
                +					if ( !( --remaining ) ) {
                +						master.resolveWith( resolveContexts, resolveValues );
                +					}
                +				};
                +			};
                +
                +		// Single- and empty arguments are adopted like Promise.resolve
                +		if ( remaining <= 1 ) {
                +			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
                +				!remaining );
                +
                +			// Use .then() to unwrap secondary thenables (cf. gh-3000)
                +			if ( master.state() === "pending" ||
                +				jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
                +
                +				return master.then();
                +			}
                +		}
                +
                +		// Multiple arguments are aggregated like Promise.all array elements
                +		while ( i-- ) {
                +			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
                +		}
                +
                +		return master.promise();
                +	}
                +} );
                +
                +
                +// These usually indicate a programmer mistake during development,
                +// warn about them ASAP rather than swallowing them by default.
                +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
                +
                +jQuery.Deferred.exceptionHook = function( error, stack ) {
                +
                +	// Support: IE 8 - 9 only
                +	// Console exists when dev tools are open, which can happen at any time
                +	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
                +		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
                +	}
                +};
                +
                +
                +
                +
                +jQuery.readyException = function( error ) {
                +	window.setTimeout( function() {
                +		throw error;
                +	} );
                +};
                +
                +
                +
                +
                +// The deferred used on DOM ready
                +var readyList = jQuery.Deferred();
                +
                +jQuery.fn.ready = function( fn ) {
                +
                +	readyList
                +		.then( fn )
                +
                +		// Wrap jQuery.readyException in a function so that the lookup
                +		// happens at the time of error handling instead of callback
                +		// registration.
                +		.catch( function( error ) {
                +			jQuery.readyException( error );
                +		} );
                +
                +	return this;
                +};
                +
                +jQuery.extend( {
                +
                +	// Is the DOM ready to be used? Set to true once it occurs.
                +	isReady: false,
                +
                +	// A counter to track how many items to wait for before
                +	// the ready event fires. See #6781
                +	readyWait: 1,
                +
                +	// Handle when the DOM is ready
                +	ready: function( wait ) {
                +
                +		// Abort if there are pending holds or we're already ready
                +		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
                +			return;
                +		}
                +
                +		// Remember that the DOM is ready
                +		jQuery.isReady = true;
                +
                +		// If a normal DOM Ready event fired, decrement, and wait if need be
                +		if ( wait !== true && --jQuery.readyWait > 0 ) {
                +			return;
                +		}
                +
                +		// If there are functions bound, to execute
                +		readyList.resolveWith( document, [ jQuery ] );
                +	}
                +} );
                +
                +jQuery.ready.then = readyList.then;
                +
                +// The ready event handler and self cleanup method
                +function completed() {
                +	document.removeEventListener( "DOMContentLoaded", completed );
                +	window.removeEventListener( "load", completed );
                +	jQuery.ready();
                +}
                +
                +// Catch cases where $(document).ready() is called
                +// after the browser event has already occurred.
                +// Support: IE <=9 - 10 only
                +// Older IE sometimes signals "interactive" too soon
                +if ( document.readyState === "complete" ||
                +	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
                +
                +	// Handle it asynchronously to allow scripts the opportunity to delay ready
                +	window.setTimeout( jQuery.ready );
                +
                +} else {
                +
                +	// Use the handy event callback
                +	document.addEventListener( "DOMContentLoaded", completed );
                +
                +	// A fallback to window.onload, that will always work
                +	window.addEventListener( "load", completed );
                +}
                +
                +
                +
                +
                +// Multifunctional method to get and set values of a collection
                +// The value/s can optionally be executed if it's a function
                +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
                +	var i = 0,
                +		len = elems.length,
                +		bulk = key == null;
                +
                +	// Sets many values
                +	if ( jQuery.type( key ) === "object" ) {
                +		chainable = true;
                +		for ( i in key ) {
                +			access( elems, fn, i, key[ i ], true, emptyGet, raw );
                +		}
                +
                +	// Sets one value
                +	} else if ( value !== undefined ) {
                +		chainable = true;
                +
                +		if ( !jQuery.isFunction( value ) ) {
                +			raw = true;
                +		}
                +
                +		if ( bulk ) {
                +
                +			// Bulk operations run against the entire set
                +			if ( raw ) {
                +				fn.call( elems, value );
                +				fn = null;
                +
                +			// ...except when executing function values
                +			} else {
                +				bulk = fn;
                +				fn = function( elem, key, value ) {
                +					return bulk.call( jQuery( elem ), value );
                +				};
                +			}
                +		}
                +
                +		if ( fn ) {
                +			for ( ; i < len; i++ ) {
                +				fn(
                +					elems[ i ], key, raw ?
                +					value :
                +					value.call( elems[ i ], i, fn( elems[ i ], key ) )
                +				);
                +			}
                +		}
                +	}
                +
                +	if ( chainable ) {
                +		return elems;
                +	}
                +
                +	// Gets
                +	if ( bulk ) {
                +		return fn.call( elems );
                +	}
                +
                +	return len ? fn( elems[ 0 ], key ) : emptyGet;
                +};
                +var acceptData = function( owner ) {
                +
                +	// Accepts only:
                +	//  - Node
                +	//    - Node.ELEMENT_NODE
                +	//    - Node.DOCUMENT_NODE
                +	//  - Object
                +	//    - Any
                +	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
                +};
                +
                +
                +
                +
                +function Data() {
                +	this.expando = jQuery.expando + Data.uid++;
                +}
                +
                +Data.uid = 1;
                +
                +Data.prototype = {
                +
                +	cache: function( owner ) {
                +
                +		// Check if the owner object already has a cache
                +		var value = owner[ this.expando ];
                +
                +		// If not, create one
                +		if ( !value ) {
                +			value = {};
                +
                +			// We can accept data for non-element nodes in modern browsers,
                +			// but we should not, see #8335.
                +			// Always return an empty object.
                +			if ( acceptData( owner ) ) {
                +
                +				// If it is a node unlikely to be stringify-ed or looped over
                +				// use plain assignment
                +				if ( owner.nodeType ) {
                +					owner[ this.expando ] = value;
                +
                +				// Otherwise secure it in a non-enumerable property
                +				// configurable must be true to allow the property to be
                +				// deleted when data is removed
                +				} else {
                +					Object.defineProperty( owner, this.expando, {
                +						value: value,
                +						configurable: true
                +					} );
                +				}
                +			}
                +		}
                +
                +		return value;
                +	},
                +	set: function( owner, data, value ) {
                +		var prop,
                +			cache = this.cache( owner );
                +
                +		// Handle: [ owner, key, value ] args
                +		// Always use camelCase key (gh-2257)
                +		if ( typeof data === "string" ) {
                +			cache[ jQuery.camelCase( data ) ] = value;
                +
                +		// Handle: [ owner, { properties } ] args
                +		} else {
                +
                +			// Copy the properties one-by-one to the cache object
                +			for ( prop in data ) {
                +				cache[ jQuery.camelCase( prop ) ] = data[ prop ];
                +			}
                +		}
                +		return cache;
                +	},
                +	get: function( owner, key ) {
                +		return key === undefined ?
                +			this.cache( owner ) :
                +
                +			// Always use camelCase key (gh-2257)
                +			owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
                +	},
                +	access: function( owner, key, value ) {
                +
                +		// In cases where either:
                +		//
                +		//   1. No key was specified
                +		//   2. A string key was specified, but no value provided
                +		//
                +		// Take the "read" path and allow the get method to determine
                +		// which value to return, respectively either:
                +		//
                +		//   1. The entire cache object
                +		//   2. The data stored at the key
                +		//
                +		if ( key === undefined ||
                +				( ( key && typeof key === "string" ) && value === undefined ) ) {
                +
                +			return this.get( owner, key );
                +		}
                +
                +		// When the key is not a string, or both a key and value
                +		// are specified, set or extend (existing objects) with either:
                +		//
                +		//   1. An object of properties
                +		//   2. A key and value
                +		//
                +		this.set( owner, key, value );
                +
                +		// Since the "set" path can have two possible entry points
                +		// return the expected data based on which path was taken[*]
                +		return value !== undefined ? value : key;
                +	},
                +	remove: function( owner, key ) {
                +		var i,
                +			cache = owner[ this.expando ];
                +
                +		if ( cache === undefined ) {
                +			return;
                +		}
                +
                +		if ( key !== undefined ) {
                +
                +			// Support array or space separated string of keys
                +			if ( Array.isArray( key ) ) {
                +
                +				// If key is an array of keys...
                +				// We always set camelCase keys, so remove that.
                +				key = key.map( jQuery.camelCase );
                +			} else {
                +				key = jQuery.camelCase( key );
                +
                +				// If a key with the spaces exists, use it.
                +				// Otherwise, create an array by matching non-whitespace
                +				key = key in cache ?
                +					[ key ] :
                +					( key.match( rnothtmlwhite ) || [] );
                +			}
                +
                +			i = key.length;
                +
                +			while ( i-- ) {
                +				delete cache[ key[ i ] ];
                +			}
                +		}
                +
                +		// Remove the expando if there's no more data
                +		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
                +
                +			// Support: Chrome <=35 - 45
                +			// Webkit & Blink performance suffers when deleting properties
                +			// from DOM nodes, so set to undefined instead
                +			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
                +			if ( owner.nodeType ) {
                +				owner[ this.expando ] = undefined;
                +			} else {
                +				delete owner[ this.expando ];
                +			}
                +		}
                +	},
                +	hasData: function( owner ) {
                +		var cache = owner[ this.expando ];
                +		return cache !== undefined && !jQuery.isEmptyObject( cache );
                +	}
                +};
                +var dataPriv = new Data();
                +
                +var dataUser = new Data();
                +
                +
                +
                +//	Implementation Summary
                +//
                +//	1. Enforce API surface and semantic compatibility with 1.9.x branch
                +//	2. Improve the module's maintainability by reducing the storage
                +//		paths to a single mechanism.
                +//	3. Use the same single mechanism to support "private" and "user" data.
                +//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
                +//	5. Avoid exposing implementation details on user objects (eg. expando properties)
                +//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
                +
                +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
                +	rmultiDash = /[A-Z]/g;
                +
                +function getData( data ) {
                +	if ( data === "true" ) {
                +		return true;
                +	}
                +
                +	if ( data === "false" ) {
                +		return false;
                +	}
                +
                +	if ( data === "null" ) {
                +		return null;
                +	}
                +
                +	// Only convert to a number if it doesn't change the string
                +	if ( data === +data + "" ) {
                +		return +data;
                +	}
                +
                +	if ( rbrace.test( data ) ) {
                +		return JSON.parse( data );
                +	}
                +
                +	return data;
                +}
                +
                +function dataAttr( elem, key, data ) {
                +	var name;
                +
                +	// If nothing was found internally, try to fetch any
                +	// data from the HTML5 data-* attribute
                +	if ( data === undefined && elem.nodeType === 1 ) {
                +		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
                +		data = elem.getAttribute( name );
                +
                +		if ( typeof data === "string" ) {
                +			try {
                +				data = getData( data );
                +			} catch ( e ) {}
                +
                +			// Make sure we set the data so it isn't changed later
                +			dataUser.set( elem, key, data );
                +		} else {
                +			data = undefined;
                +		}
                +	}
                +	return data;
                +}
                +
                +jQuery.extend( {
                +	hasData: function( elem ) {
                +		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
                +	},
                +
                +	data: function( elem, name, data ) {
                +		return dataUser.access( elem, name, data );
                +	},
                +
                +	removeData: function( elem, name ) {
                +		dataUser.remove( elem, name );
                +	},
                +
                +	// TODO: Now that all calls to _data and _removeData have been replaced
                +	// with direct calls to dataPriv methods, these can be deprecated.
                +	_data: function( elem, name, data ) {
                +		return dataPriv.access( elem, name, data );
                +	},
                +
                +	_removeData: function( elem, name ) {
                +		dataPriv.remove( elem, name );
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	data: function( key, value ) {
                +		var i, name, data,
                +			elem = this[ 0 ],
                +			attrs = elem && elem.attributes;
                +
                +		// Gets all values
                +		if ( key === undefined ) {
                +			if ( this.length ) {
                +				data = dataUser.get( elem );
                +
                +				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
                +					i = attrs.length;
                +					while ( i-- ) {
                +
                +						// Support: IE 11 only
                +						// The attrs elements can be null (#14894)
                +						if ( attrs[ i ] ) {
                +							name = attrs[ i ].name;
                +							if ( name.indexOf( "data-" ) === 0 ) {
                +								name = jQuery.camelCase( name.slice( 5 ) );
                +								dataAttr( elem, name, data[ name ] );
                +							}
                +						}
                +					}
                +					dataPriv.set( elem, "hasDataAttrs", true );
                +				}
                +			}
                +
                +			return data;
                +		}
                +
                +		// Sets multiple values
                +		if ( typeof key === "object" ) {
                +			return this.each( function() {
                +				dataUser.set( this, key );
                +			} );
                +		}
                +
                +		return access( this, function( value ) {
                +			var data;
                +
                +			// The calling jQuery object (element matches) is not empty
                +			// (and therefore has an element appears at this[ 0 ]) and the
                +			// `value` parameter was not undefined. An empty jQuery object
                +			// will result in `undefined` for elem = this[ 0 ] which will
                +			// throw an exception if an attempt to read a data cache is made.
                +			if ( elem && value === undefined ) {
                +
                +				// Attempt to get data from the cache
                +				// The key will always be camelCased in Data
                +				data = dataUser.get( elem, key );
                +				if ( data !== undefined ) {
                +					return data;
                +				}
                +
                +				// Attempt to "discover" the data in
                +				// HTML5 custom data-* attrs
                +				data = dataAttr( elem, key );
                +				if ( data !== undefined ) {
                +					return data;
                +				}
                +
                +				// We tried really hard, but the data doesn't exist.
                +				return;
                +			}
                +
                +			// Set the data...
                +			this.each( function() {
                +
                +				// We always store the camelCased key
                +				dataUser.set( this, key, value );
                +			} );
                +		}, null, value, arguments.length > 1, null, true );
                +	},
                +
                +	removeData: function( key ) {
                +		return this.each( function() {
                +			dataUser.remove( this, key );
                +		} );
                +	}
                +} );
                +
                +
                +jQuery.extend( {
                +	queue: function( elem, type, data ) {
                +		var queue;
                +
                +		if ( elem ) {
                +			type = ( type || "fx" ) + "queue";
                +			queue = dataPriv.get( elem, type );
                +
                +			// Speed up dequeue by getting out quickly if this is just a lookup
                +			if ( data ) {
                +				if ( !queue || Array.isArray( data ) ) {
                +					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
                +				} else {
                +					queue.push( data );
                +				}
                +			}
                +			return queue || [];
                +		}
                +	},
                +
                +	dequeue: function( elem, type ) {
                +		type = type || "fx";
                +
                +		var queue = jQuery.queue( elem, type ),
                +			startLength = queue.length,
                +			fn = queue.shift(),
                +			hooks = jQuery._queueHooks( elem, type ),
                +			next = function() {
                +				jQuery.dequeue( elem, type );
                +			};
                +
                +		// If the fx queue is dequeued, always remove the progress sentinel
                +		if ( fn === "inprogress" ) {
                +			fn = queue.shift();
                +			startLength--;
                +		}
                +
                +		if ( fn ) {
                +
                +			// Add a progress sentinel to prevent the fx queue from being
                +			// automatically dequeued
                +			if ( type === "fx" ) {
                +				queue.unshift( "inprogress" );
                +			}
                +
                +			// Clear up the last queue stop function
                +			delete hooks.stop;
                +			fn.call( elem, next, hooks );
                +		}
                +
                +		if ( !startLength && hooks ) {
                +			hooks.empty.fire();
                +		}
                +	},
                +
                +	// Not public - generate a queueHooks object, or return the current one
                +	_queueHooks: function( elem, type ) {
                +		var key = type + "queueHooks";
                +		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
                +			empty: jQuery.Callbacks( "once memory" ).add( function() {
                +				dataPriv.remove( elem, [ type + "queue", key ] );
                +			} )
                +		} );
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	queue: function( type, data ) {
                +		var setter = 2;
                +
                +		if ( typeof type !== "string" ) {
                +			data = type;
                +			type = "fx";
                +			setter--;
                +		}
                +
                +		if ( arguments.length < setter ) {
                +			return jQuery.queue( this[ 0 ], type );
                +		}
                +
                +		return data === undefined ?
                +			this :
                +			this.each( function() {
                +				var queue = jQuery.queue( this, type, data );
                +
                +				// Ensure a hooks for this queue
                +				jQuery._queueHooks( this, type );
                +
                +				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
                +					jQuery.dequeue( this, type );
                +				}
                +			} );
                +	},
                +	dequeue: function( type ) {
                +		return this.each( function() {
                +			jQuery.dequeue( this, type );
                +		} );
                +	},
                +	clearQueue: function( type ) {
                +		return this.queue( type || "fx", [] );
                +	},
                +
                +	// Get a promise resolved when queues of a certain type
                +	// are emptied (fx is the type by default)
                +	promise: function( type, obj ) {
                +		var tmp,
                +			count = 1,
                +			defer = jQuery.Deferred(),
                +			elements = this,
                +			i = this.length,
                +			resolve = function() {
                +				if ( !( --count ) ) {
                +					defer.resolveWith( elements, [ elements ] );
                +				}
                +			};
                +
                +		if ( typeof type !== "string" ) {
                +			obj = type;
                +			type = undefined;
                +		}
                +		type = type || "fx";
                +
                +		while ( i-- ) {
                +			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
                +			if ( tmp && tmp.empty ) {
                +				count++;
                +				tmp.empty.add( resolve );
                +			}
                +		}
                +		resolve();
                +		return defer.promise( obj );
                +	}
                +} );
                +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
                +
                +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
                +
                +
                +var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
                +
                +var isHiddenWithinTree = function( elem, el ) {
                +
                +		// isHiddenWithinTree might be called from jQuery#filter function;
                +		// in that case, element will be second argument
                +		elem = el || elem;
                +
                +		// Inline style trumps all
                +		return elem.style.display === "none" ||
                +			elem.style.display === "" &&
                +
                +			// Otherwise, check computed style
                +			// Support: Firefox <=43 - 45
                +			// Disconnected elements can have computed display: none, so first confirm that elem is
                +			// in the document.
                +			jQuery.contains( elem.ownerDocument, elem ) &&
                +
                +			jQuery.css( elem, "display" ) === "none";
                +	};
                +
                +var swap = function( elem, options, callback, args ) {
                +	var ret, name,
                +		old = {};
                +
                +	// Remember the old values, and insert the new ones
                +	for ( name in options ) {
                +		old[ name ] = elem.style[ name ];
                +		elem.style[ name ] = options[ name ];
                +	}
                +
                +	ret = callback.apply( elem, args || [] );
                +
                +	// Revert the old values
                +	for ( name in options ) {
                +		elem.style[ name ] = old[ name ];
                +	}
                +
                +	return ret;
                +};
                +
                +
                +
                +
                +function adjustCSS( elem, prop, valueParts, tween ) {
                +	var adjusted,
                +		scale = 1,
                +		maxIterations = 20,
                +		currentValue = tween ?
                +			function() {
                +				return tween.cur();
                +			} :
                +			function() {
                +				return jQuery.css( elem, prop, "" );
                +			},
                +		initial = currentValue(),
                +		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
                +
                +		// Starting value computation is required for potential unit mismatches
                +		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
                +			rcssNum.exec( jQuery.css( elem, prop ) );
                +
                +	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
                +
                +		// Trust units reported by jQuery.css
                +		unit = unit || initialInUnit[ 3 ];
                +
                +		// Make sure we update the tween properties later on
                +		valueParts = valueParts || [];
                +
                +		// Iteratively approximate from a nonzero starting point
                +		initialInUnit = +initial || 1;
                +
                +		do {
                +
                +			// If previous iteration zeroed out, double until we get *something*.
                +			// Use string for doubling so we don't accidentally see scale as unchanged below
                +			scale = scale || ".5";
                +
                +			// Adjust and apply
                +			initialInUnit = initialInUnit / scale;
                +			jQuery.style( elem, prop, initialInUnit + unit );
                +
                +		// Update scale, tolerating zero or NaN from tween.cur()
                +		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
                +		} while (
                +			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
                +		);
                +	}
                +
                +	if ( valueParts ) {
                +		initialInUnit = +initialInUnit || +initial || 0;
                +
                +		// Apply relative offset (+=/-=) if specified
                +		adjusted = valueParts[ 1 ] ?
                +			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
                +			+valueParts[ 2 ];
                +		if ( tween ) {
                +			tween.unit = unit;
                +			tween.start = initialInUnit;
                +			tween.end = adjusted;
                +		}
                +	}
                +	return adjusted;
                +}
                +
                +
                +var defaultDisplayMap = {};
                +
                +function getDefaultDisplay( elem ) {
                +	var temp,
                +		doc = elem.ownerDocument,
                +		nodeName = elem.nodeName,
                +		display = defaultDisplayMap[ nodeName ];
                +
                +	if ( display ) {
                +		return display;
                +	}
                +
                +	temp = doc.body.appendChild( doc.createElement( nodeName ) );
                +	display = jQuery.css( temp, "display" );
                +
                +	temp.parentNode.removeChild( temp );
                +
                +	if ( display === "none" ) {
                +		display = "block";
                +	}
                +	defaultDisplayMap[ nodeName ] = display;
                +
                +	return display;
                +}
                +
                +function showHide( elements, show ) {
                +	var display, elem,
                +		values = [],
                +		index = 0,
                +		length = elements.length;
                +
                +	// Determine new display value for elements that need to change
                +	for ( ; index < length; index++ ) {
                +		elem = elements[ index ];
                +		if ( !elem.style ) {
                +			continue;
                +		}
                +
                +		display = elem.style.display;
                +		if ( show ) {
                +
                +			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
                +			// check is required in this first loop unless we have a nonempty display value (either
                +			// inline or about-to-be-restored)
                +			if ( display === "none" ) {
                +				values[ index ] = dataPriv.get( elem, "display" ) || null;
                +				if ( !values[ index ] ) {
                +					elem.style.display = "";
                +				}
                +			}
                +			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
                +				values[ index ] = getDefaultDisplay( elem );
                +			}
                +		} else {
                +			if ( display !== "none" ) {
                +				values[ index ] = "none";
                +
                +				// Remember what we're overwriting
                +				dataPriv.set( elem, "display", display );
                +			}
                +		}
                +	}
                +
                +	// Set the display of the elements in a second loop to avoid constant reflow
                +	for ( index = 0; index < length; index++ ) {
                +		if ( values[ index ] != null ) {
                +			elements[ index ].style.display = values[ index ];
                +		}
                +	}
                +
                +	return elements;
                +}
                +
                +jQuery.fn.extend( {
                +	show: function() {
                +		return showHide( this, true );
                +	},
                +	hide: function() {
                +		return showHide( this );
                +	},
                +	toggle: function( state ) {
                +		if ( typeof state === "boolean" ) {
                +			return state ? this.show() : this.hide();
                +		}
                +
                +		return this.each( function() {
                +			if ( isHiddenWithinTree( this ) ) {
                +				jQuery( this ).show();
                +			} else {
                +				jQuery( this ).hide();
                +			}
                +		} );
                +	}
                +} );
                +var rcheckableType = ( /^(?:checkbox|radio)$/i );
                +
                +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
                +
                +var rscriptType = ( /^$|\/(?:java|ecma)script/i );
                +
                +
                +
                +// We have to close these tags to support XHTML (#13200)
                +var wrapMap = {
                +
                +	// Support: IE <=9 only
                +	option: [ 1, "<select multiple='multiple'>", "</select>" ],
                +
                +	// XHTML parsers do not magically insert elements in the
                +	// same way that tag soup parsers do. So we cannot shorten
                +	// this by omitting <tbody> or other required elements.
                +	thead: [ 1, "<table>", "</table>" ],
                +	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
                +	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
                +	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
                +
                +	_default: [ 0, "", "" ]
                +};
                +
                +// Support: IE <=9 only
                +wrapMap.optgroup = wrapMap.option;
                +
                +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
                +wrapMap.th = wrapMap.td;
                +
                +
                +function getAll( context, tag ) {
                +
                +	// Support: IE <=9 - 11 only
                +	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
                +	var ret;
                +
                +	if ( typeof context.getElementsByTagName !== "undefined" ) {
                +		ret = context.getElementsByTagName( tag || "*" );
                +
                +	} else if ( typeof context.querySelectorAll !== "undefined" ) {
                +		ret = context.querySelectorAll( tag || "*" );
                +
                +	} else {
                +		ret = [];
                +	}
                +
                +	if ( tag === undefined || tag && nodeName( context, tag ) ) {
                +		return jQuery.merge( [ context ], ret );
                +	}
                +
                +	return ret;
                +}
                +
                +
                +// Mark scripts as having already been evaluated
                +function setGlobalEval( elems, refElements ) {
                +	var i = 0,
                +		l = elems.length;
                +
                +	for ( ; i < l; i++ ) {
                +		dataPriv.set(
                +			elems[ i ],
                +			"globalEval",
                +			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
                +		);
                +	}
                +}
                +
                +
                +var rhtml = /<|&#?\w+;/;
                +
                +function buildFragment( elems, context, scripts, selection, ignored ) {
                +	var elem, tmp, tag, wrap, contains, j,
                +		fragment = context.createDocumentFragment(),
                +		nodes = [],
                +		i = 0,
                +		l = elems.length;
                +
                +	for ( ; i < l; i++ ) {
                +		elem = elems[ i ];
                +
                +		if ( elem || elem === 0 ) {
                +
                +			// Add nodes directly
                +			if ( jQuery.type( elem ) === "object" ) {
                +
                +				// Support: Android <=4.0 only, PhantomJS 1 only
                +				// push.apply(_, arraylike) throws on ancient WebKit
                +				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
                +
                +			// Convert non-html into a text node
                +			} else if ( !rhtml.test( elem ) ) {
                +				nodes.push( context.createTextNode( elem ) );
                +
                +			// Convert html into DOM nodes
                +			} else {
                +				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
                +
                +				// Deserialize a standard representation
                +				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
                +				wrap = wrapMap[ tag ] || wrapMap._default;
                +				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
                +
                +				// Descend through wrappers to the right content
                +				j = wrap[ 0 ];
                +				while ( j-- ) {
                +					tmp = tmp.lastChild;
                +				}
                +
                +				// Support: Android <=4.0 only, PhantomJS 1 only
                +				// push.apply(_, arraylike) throws on ancient WebKit
                +				jQuery.merge( nodes, tmp.childNodes );
                +
                +				// Remember the top-level container
                +				tmp = fragment.firstChild;
                +
                +				// Ensure the created nodes are orphaned (#12392)
                +				tmp.textContent = "";
                +			}
                +		}
                +	}
                +
                +	// Remove wrapper from fragment
                +	fragment.textContent = "";
                +
                +	i = 0;
                +	while ( ( elem = nodes[ i++ ] ) ) {
                +
                +		// Skip elements already in the context collection (trac-4087)
                +		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
                +			if ( ignored ) {
                +				ignored.push( elem );
                +			}
                +			continue;
                +		}
                +
                +		contains = jQuery.contains( elem.ownerDocument, elem );
                +
                +		// Append to fragment
                +		tmp = getAll( fragment.appendChild( elem ), "script" );
                +
                +		// Preserve script evaluation history
                +		if ( contains ) {
                +			setGlobalEval( tmp );
                +		}
                +
                +		// Capture executables
                +		if ( scripts ) {
                +			j = 0;
                +			while ( ( elem = tmp[ j++ ] ) ) {
                +				if ( rscriptType.test( elem.type || "" ) ) {
                +					scripts.push( elem );
                +				}
                +			}
                +		}
                +	}
                +
                +	return fragment;
                +}
                +
                +
                +( function() {
                +	var fragment = document.createDocumentFragment(),
                +		div = fragment.appendChild( document.createElement( "div" ) ),
                +		input = document.createElement( "input" );
                +
                +	// Support: Android 4.0 - 4.3 only
                +	// Check state lost if the name is set (#11217)
                +	// Support: Windows Web Apps (WWA)
                +	// `name` and `type` must use .setAttribute for WWA (#14901)
                +	input.setAttribute( "type", "radio" );
                +	input.setAttribute( "checked", "checked" );
                +	input.setAttribute( "name", "t" );
                +
                +	div.appendChild( input );
                +
                +	// Support: Android <=4.1 only
                +	// Older WebKit doesn't clone checked state correctly in fragments
                +	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
                +
                +	// Support: IE <=11 only
                +	// Make sure textarea (and checkbox) defaultValue is properly cloned
                +	div.innerHTML = "<textarea>x</textarea>";
                +	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
                +} )();
                +var documentElement = document.documentElement;
                +
                +
                +
                +var
                +	rkeyEvent = /^key/,
                +	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
                +	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
                +
                +function returnTrue() {
                +	return true;
                +}
                +
                +function returnFalse() {
                +	return false;
                +}
                +
                +// Support: IE <=9 only
                +// See #13393 for more info
                +function safeActiveElement() {
                +	try {
                +		return document.activeElement;
                +	} catch ( err ) { }
                +}
                +
                +function on( elem, types, selector, data, fn, one ) {
                +	var origFn, type;
                +
                +	// Types can be a map of types/handlers
                +	if ( typeof types === "object" ) {
                +
                +		// ( types-Object, selector, data )
                +		if ( typeof selector !== "string" ) {
                +
                +			// ( types-Object, data )
                +			data = data || selector;
                +			selector = undefined;
                +		}
                +		for ( type in types ) {
                +			on( elem, type, selector, data, types[ type ], one );
                +		}
                +		return elem;
                +	}
                +
                +	if ( data == null && fn == null ) {
                +
                +		// ( types, fn )
                +		fn = selector;
                +		data = selector = undefined;
                +	} else if ( fn == null ) {
                +		if ( typeof selector === "string" ) {
                +
                +			// ( types, selector, fn )
                +			fn = data;
                +			data = undefined;
                +		} else {
                +
                +			// ( types, data, fn )
                +			fn = data;
                +			data = selector;
                +			selector = undefined;
                +		}
                +	}
                +	if ( fn === false ) {
                +		fn = returnFalse;
                +	} else if ( !fn ) {
                +		return elem;
                +	}
                +
                +	if ( one === 1 ) {
                +		origFn = fn;
                +		fn = function( event ) {
                +
                +			// Can use an empty set, since event contains the info
                +			jQuery().off( event );
                +			return origFn.apply( this, arguments );
                +		};
                +
                +		// Use same guid so caller can remove using origFn
                +		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
                +	}
                +	return elem.each( function() {
                +		jQuery.event.add( this, types, fn, data, selector );
                +	} );
                +}
                +
                +/*
                + * Helper functions for managing events -- not part of the public interface.
                + * Props to Dean Edwards' addEvent library for many of the ideas.
                + */
                +jQuery.event = {
                +
                +	global: {},
                +
                +	add: function( elem, types, handler, data, selector ) {
                +
                +		var handleObjIn, eventHandle, tmp,
                +			events, t, handleObj,
                +			special, handlers, type, namespaces, origType,
                +			elemData = dataPriv.get( elem );
                +
                +		// Don't attach events to noData or text/comment nodes (but allow plain objects)
                +		if ( !elemData ) {
                +			return;
                +		}
                +
                +		// Caller can pass in an object of custom data in lieu of the handler
                +		if ( handler.handler ) {
                +			handleObjIn = handler;
                +			handler = handleObjIn.handler;
                +			selector = handleObjIn.selector;
                +		}
                +
                +		// Ensure that invalid selectors throw exceptions at attach time
                +		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
                +		if ( selector ) {
                +			jQuery.find.matchesSelector( documentElement, selector );
                +		}
                +
                +		// Make sure that the handler has a unique ID, used to find/remove it later
                +		if ( !handler.guid ) {
                +			handler.guid = jQuery.guid++;
                +		}
                +
                +		// Init the element's event structure and main handler, if this is the first
                +		if ( !( events = elemData.events ) ) {
                +			events = elemData.events = {};
                +		}
                +		if ( !( eventHandle = elemData.handle ) ) {
                +			eventHandle = elemData.handle = function( e ) {
                +
                +				// Discard the second event of a jQuery.event.trigger() and
                +				// when an event is called after a page has unloaded
                +				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
                +					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
                +			};
                +		}
                +
                +		// Handle multiple events separated by a space
                +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                +		t = types.length;
                +		while ( t-- ) {
                +			tmp = rtypenamespace.exec( types[ t ] ) || [];
                +			type = origType = tmp[ 1 ];
                +			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
                +
                +			// There *must* be a type, no attaching namespace-only handlers
                +			if ( !type ) {
                +				continue;
                +			}
                +
                +			// If event changes its type, use the special event handlers for the changed type
                +			special = jQuery.event.special[ type ] || {};
                +
                +			// If selector defined, determine special event api type, otherwise given type
                +			type = ( selector ? special.delegateType : special.bindType ) || type;
                +
                +			// Update special based on newly reset type
                +			special = jQuery.event.special[ type ] || {};
                +
                +			// handleObj is passed to all event handlers
                +			handleObj = jQuery.extend( {
                +				type: type,
                +				origType: origType,
                +				data: data,
                +				handler: handler,
                +				guid: handler.guid,
                +				selector: selector,
                +				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                +				namespace: namespaces.join( "." )
                +			}, handleObjIn );
                +
                +			// Init the event handler queue if we're the first
                +			if ( !( handlers = events[ type ] ) ) {
                +				handlers = events[ type ] = [];
                +				handlers.delegateCount = 0;
                +
                +				// Only use addEventListener if the special events handler returns false
                +				if ( !special.setup ||
                +					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                +
                +					if ( elem.addEventListener ) {
                +						elem.addEventListener( type, eventHandle );
                +					}
                +				}
                +			}
                +
                +			if ( special.add ) {
                +				special.add.call( elem, handleObj );
                +
                +				if ( !handleObj.handler.guid ) {
                +					handleObj.handler.guid = handler.guid;
                +				}
                +			}
                +
                +			// Add to the element's handler list, delegates in front
                +			if ( selector ) {
                +				handlers.splice( handlers.delegateCount++, 0, handleObj );
                +			} else {
                +				handlers.push( handleObj );
                +			}
                +
                +			// Keep track of which events have ever been used, for event optimization
                +			jQuery.event.global[ type ] = true;
                +		}
                +
                +	},
                +
                +	// Detach an event or set of events from an element
                +	remove: function( elem, types, handler, selector, mappedTypes ) {
                +
                +		var j, origCount, tmp,
                +			events, t, handleObj,
                +			special, handlers, type, namespaces, origType,
                +			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
                +
                +		if ( !elemData || !( events = elemData.events ) ) {
                +			return;
                +		}
                +
                +		// Once for each type.namespace in types; type may be omitted
                +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                +		t = types.length;
                +		while ( t-- ) {
                +			tmp = rtypenamespace.exec( types[ t ] ) || [];
                +			type = origType = tmp[ 1 ];
                +			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
                +
                +			// Unbind all events (on this namespace, if provided) for the element
                +			if ( !type ) {
                +				for ( type in events ) {
                +					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
                +				}
                +				continue;
                +			}
                +
                +			special = jQuery.event.special[ type ] || {};
                +			type = ( selector ? special.delegateType : special.bindType ) || type;
                +			handlers = events[ type ] || [];
                +			tmp = tmp[ 2 ] &&
                +				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
                +
                +			// Remove matching events
                +			origCount = j = handlers.length;
                +			while ( j-- ) {
                +				handleObj = handlers[ j ];
                +
                +				if ( ( mappedTypes || origType === handleObj.origType ) &&
                +					( !handler || handler.guid === handleObj.guid ) &&
                +					( !tmp || tmp.test( handleObj.namespace ) ) &&
                +					( !selector || selector === handleObj.selector ||
                +						selector === "**" && handleObj.selector ) ) {
                +					handlers.splice( j, 1 );
                +
                +					if ( handleObj.selector ) {
                +						handlers.delegateCount--;
                +					}
                +					if ( special.remove ) {
                +						special.remove.call( elem, handleObj );
                +					}
                +				}
                +			}
                +
                +			// Remove generic event handler if we removed something and no more handlers exist
                +			// (avoids potential for endless recursion during removal of special event handlers)
                +			if ( origCount && !handlers.length ) {
                +				if ( !special.teardown ||
                +					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
                +
                +					jQuery.removeEvent( elem, type, elemData.handle );
                +				}
                +
                +				delete events[ type ];
                +			}
                +		}
                +
                +		// Remove data and the expando if it's no longer used
                +		if ( jQuery.isEmptyObject( events ) ) {
                +			dataPriv.remove( elem, "handle events" );
                +		}
                +	},
                +
                +	dispatch: function( nativeEvent ) {
                +
                +		// Make a writable jQuery.Event from the native event object
                +		var event = jQuery.event.fix( nativeEvent );
                +
                +		var i, j, ret, matched, handleObj, handlerQueue,
                +			args = new Array( arguments.length ),
                +			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
                +			special = jQuery.event.special[ event.type ] || {};
                +
                +		// Use the fix-ed jQuery.Event rather than the (read-only) native event
                +		args[ 0 ] = event;
                +
                +		for ( i = 1; i < arguments.length; i++ ) {
                +			args[ i ] = arguments[ i ];
                +		}
                +
                +		event.delegateTarget = this;
                +
                +		// Call the preDispatch hook for the mapped type, and let it bail if desired
                +		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
                +			return;
                +		}
                +
                +		// Determine handlers
                +		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
                +
                +		// Run delegates first; they may want to stop propagation beneath us
                +		i = 0;
                +		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
                +			event.currentTarget = matched.elem;
                +
                +			j = 0;
                +			while ( ( handleObj = matched.handlers[ j++ ] ) &&
                +				!event.isImmediatePropagationStopped() ) {
                +
                +				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
                +				// a subset or equal to those in the bound event (both can have no namespace).
                +				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
                +
                +					event.handleObj = handleObj;
                +					event.data = handleObj.data;
                +
                +					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
                +						handleObj.handler ).apply( matched.elem, args );
                +
                +					if ( ret !== undefined ) {
                +						if ( ( event.result = ret ) === false ) {
                +							event.preventDefault();
                +							event.stopPropagation();
                +						}
                +					}
                +				}
                +			}
                +		}
                +
                +		// Call the postDispatch hook for the mapped type
                +		if ( special.postDispatch ) {
                +			special.postDispatch.call( this, event );
                +		}
                +
                +		return event.result;
                +	},
                +
                +	handlers: function( event, handlers ) {
                +		var i, handleObj, sel, matchedHandlers, matchedSelectors,
                +			handlerQueue = [],
                +			delegateCount = handlers.delegateCount,
                +			cur = event.target;
                +
                +		// Find delegate handlers
                +		if ( delegateCount &&
                +
                +			// Support: IE <=9
                +			// Black-hole SVG <use> instance trees (trac-13180)
                +			cur.nodeType &&
                +
                +			// Support: Firefox <=42
                +			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
                +			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
                +			// Support: IE 11 only
                +			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
                +			!( event.type === "click" && event.button >= 1 ) ) {
                +
                +			for ( ; cur !== this; cur = cur.parentNode || this ) {
                +
                +				// Don't check non-elements (#13208)
                +				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
                +				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
                +					matchedHandlers = [];
                +					matchedSelectors = {};
                +					for ( i = 0; i < delegateCount; i++ ) {
                +						handleObj = handlers[ i ];
                +
                +						// Don't conflict with Object.prototype properties (#13203)
                +						sel = handleObj.selector + " ";
                +
                +						if ( matchedSelectors[ sel ] === undefined ) {
                +							matchedSelectors[ sel ] = handleObj.needsContext ?
                +								jQuery( sel, this ).index( cur ) > -1 :
                +								jQuery.find( sel, this, null, [ cur ] ).length;
                +						}
                +						if ( matchedSelectors[ sel ] ) {
                +							matchedHandlers.push( handleObj );
                +						}
                +					}
                +					if ( matchedHandlers.length ) {
                +						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
                +					}
                +				}
                +			}
                +		}
                +
                +		// Add the remaining (directly-bound) handlers
                +		cur = this;
                +		if ( delegateCount < handlers.length ) {
                +			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
                +		}
                +
                +		return handlerQueue;
                +	},
                +
                +	addProp: function( name, hook ) {
                +		Object.defineProperty( jQuery.Event.prototype, name, {
                +			enumerable: true,
                +			configurable: true,
                +
                +			get: jQuery.isFunction( hook ) ?
                +				function() {
                +					if ( this.originalEvent ) {
                +							return hook( this.originalEvent );
                +					}
                +				} :
                +				function() {
                +					if ( this.originalEvent ) {
                +							return this.originalEvent[ name ];
                +					}
                +				},
                +
                +			set: function( value ) {
                +				Object.defineProperty( this, name, {
                +					enumerable: true,
                +					configurable: true,
                +					writable: true,
                +					value: value
                +				} );
                +			}
                +		} );
                +	},
                +
                +	fix: function( originalEvent ) {
                +		return originalEvent[ jQuery.expando ] ?
                +			originalEvent :
                +			new jQuery.Event( originalEvent );
                +	},
                +
                +	special: {
                +		load: {
                +
                +			// Prevent triggered image.load events from bubbling to window.load
                +			noBubble: true
                +		},
                +		focus: {
                +
                +			// Fire native event if possible so blur/focus sequence is correct
                +			trigger: function() {
                +				if ( this !== safeActiveElement() && this.focus ) {
                +					this.focus();
                +					return false;
                +				}
                +			},
                +			delegateType: "focusin"
                +		},
                +		blur: {
                +			trigger: function() {
                +				if ( this === safeActiveElement() && this.blur ) {
                +					this.blur();
                +					return false;
                +				}
                +			},
                +			delegateType: "focusout"
                +		},
                +		click: {
                +
                +			// For checkbox, fire native event so checked state will be right
                +			trigger: function() {
                +				if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
                +					this.click();
                +					return false;
                +				}
                +			},
                +
                +			// For cross-browser consistency, don't fire native .click() on links
                +			_default: function( event ) {
                +				return nodeName( event.target, "a" );
                +			}
                +		},
                +
                +		beforeunload: {
                +			postDispatch: function( event ) {
                +
                +				// Support: Firefox 20+
                +				// Firefox doesn't alert if the returnValue field is not set.
                +				if ( event.result !== undefined && event.originalEvent ) {
                +					event.originalEvent.returnValue = event.result;
                +				}
                +			}
                +		}
                +	}
                +};
                +
                +jQuery.removeEvent = function( elem, type, handle ) {
                +
                +	// This "if" is needed for plain objects
                +	if ( elem.removeEventListener ) {
                +		elem.removeEventListener( type, handle );
                +	}
                +};
                +
                +jQuery.Event = function( src, props ) {
                +
                +	// Allow instantiation without the 'new' keyword
                +	if ( !( this instanceof jQuery.Event ) ) {
                +		return new jQuery.Event( src, props );
                +	}
                +
                +	// Event object
                +	if ( src && src.type ) {
                +		this.originalEvent = src;
                +		this.type = src.type;
                +
                +		// Events bubbling up the document may have been marked as prevented
                +		// by a handler lower down the tree; reflect the correct value.
                +		this.isDefaultPrevented = src.defaultPrevented ||
                +				src.defaultPrevented === undefined &&
                +
                +				// Support: Android <=2.3 only
                +				src.returnValue === false ?
                +			returnTrue :
                +			returnFalse;
                +
                +		// Create target properties
                +		// Support: Safari <=6 - 7 only
                +		// Target should not be a text node (#504, #13143)
                +		this.target = ( src.target && src.target.nodeType === 3 ) ?
                +			src.target.parentNode :
                +			src.target;
                +
                +		this.currentTarget = src.currentTarget;
                +		this.relatedTarget = src.relatedTarget;
                +
                +	// Event type
                +	} else {
                +		this.type = src;
                +	}
                +
                +	// Put explicitly provided properties onto the event object
                +	if ( props ) {
                +		jQuery.extend( this, props );
                +	}
                +
                +	// Create a timestamp if incoming event doesn't have one
                +	this.timeStamp = src && src.timeStamp || jQuery.now();
                +
                +	// Mark it as fixed
                +	this[ jQuery.expando ] = true;
                +};
                +
                +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
                +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
                +jQuery.Event.prototype = {
                +	constructor: jQuery.Event,
                +	isDefaultPrevented: returnFalse,
                +	isPropagationStopped: returnFalse,
                +	isImmediatePropagationStopped: returnFalse,
                +	isSimulated: false,
                +
                +	preventDefault: function() {
                +		var e = this.originalEvent;
                +
                +		this.isDefaultPrevented = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.preventDefault();
                +		}
                +	},
                +	stopPropagation: function() {
                +		var e = this.originalEvent;
                +
                +		this.isPropagationStopped = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.stopPropagation();
                +		}
                +	},
                +	stopImmediatePropagation: function() {
                +		var e = this.originalEvent;
                +
                +		this.isImmediatePropagationStopped = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.stopImmediatePropagation();
                +		}
                +
                +		this.stopPropagation();
                +	}
                +};
                +
                +// Includes all common event props including KeyEvent and MouseEvent specific props
                +jQuery.each( {
                +	altKey: true,
                +	bubbles: true,
                +	cancelable: true,
                +	changedTouches: true,
                +	ctrlKey: true,
                +	detail: true,
                +	eventPhase: true,
                +	metaKey: true,
                +	pageX: true,
                +	pageY: true,
                +	shiftKey: true,
                +	view: true,
                +	"char": true,
                +	charCode: true,
                +	key: true,
                +	keyCode: true,
                +	button: true,
                +	buttons: true,
                +	clientX: true,
                +	clientY: true,
                +	offsetX: true,
                +	offsetY: true,
                +	pointerId: true,
                +	pointerType: true,
                +	screenX: true,
                +	screenY: true,
                +	targetTouches: true,
                +	toElement: true,
                +	touches: true,
                +
                +	which: function( event ) {
                +		var button = event.button;
                +
                +		// Add which for key events
                +		if ( event.which == null && rkeyEvent.test( event.type ) ) {
                +			return event.charCode != null ? event.charCode : event.keyCode;
                +		}
                +
                +		// Add which for click: 1 === left; 2 === middle; 3 === right
                +		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
                +			if ( button & 1 ) {
                +				return 1;
                +			}
                +
                +			if ( button & 2 ) {
                +				return 3;
                +			}
                +
                +			if ( button & 4 ) {
                +				return 2;
                +			}
                +
                +			return 0;
                +		}
                +
                +		return event.which;
                +	}
                +}, jQuery.event.addProp );
                +
                +// Create mouseenter/leave events using mouseover/out and event-time checks
                +// so that event delegation works in jQuery.
                +// Do the same for pointerenter/pointerleave and pointerover/pointerout
                +//
                +// Support: Safari 7 only
                +// Safari sends mouseenter too often; see:
                +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
                +// for the description of the bug (it existed in older Chrome versions as well).
                +jQuery.each( {
                +	mouseenter: "mouseover",
                +	mouseleave: "mouseout",
                +	pointerenter: "pointerover",
                +	pointerleave: "pointerout"
                +}, function( orig, fix ) {
                +	jQuery.event.special[ orig ] = {
                +		delegateType: fix,
                +		bindType: fix,
                +
                +		handle: function( event ) {
                +			var ret,
                +				target = this,
                +				related = event.relatedTarget,
                +				handleObj = event.handleObj;
                +
                +			// For mouseenter/leave call the handler if related is outside the target.
                +			// NB: No relatedTarget if the mouse left/entered the browser window
                +			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
                +				event.type = handleObj.origType;
                +				ret = handleObj.handler.apply( this, arguments );
                +				event.type = fix;
                +			}
                +			return ret;
                +		}
                +	};
                +} );
                +
                +jQuery.fn.extend( {
                +
                +	on: function( types, selector, data, fn ) {
                +		return on( this, types, selector, data, fn );
                +	},
                +	one: function( types, selector, data, fn ) {
                +		return on( this, types, selector, data, fn, 1 );
                +	},
                +	off: function( types, selector, fn ) {
                +		var handleObj, type;
                +		if ( types && types.preventDefault && types.handleObj ) {
                +
                +			// ( event )  dispatched jQuery.Event
                +			handleObj = types.handleObj;
                +			jQuery( types.delegateTarget ).off(
                +				handleObj.namespace ?
                +					handleObj.origType + "." + handleObj.namespace :
                +					handleObj.origType,
                +				handleObj.selector,
                +				handleObj.handler
                +			);
                +			return this;
                +		}
                +		if ( typeof types === "object" ) {
                +
                +			// ( types-object [, selector] )
                +			for ( type in types ) {
                +				this.off( type, selector, types[ type ] );
                +			}
                +			return this;
                +		}
                +		if ( selector === false || typeof selector === "function" ) {
                +
                +			// ( types [, fn] )
                +			fn = selector;
                +			selector = undefined;
                +		}
                +		if ( fn === false ) {
                +			fn = returnFalse;
                +		}
                +		return this.each( function() {
                +			jQuery.event.remove( this, types, fn, selector );
                +		} );
                +	}
                +} );
                +
                +
                +var
                +
                +	/* eslint-disable max-len */
                +
                +	// See https://github.com/eslint/eslint/issues/3229
                +	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
                +
                +	/* eslint-enable */
                +
                +	// Support: IE <=10 - 11, Edge 12 - 13
                +	// In IE/Edge using regex groups here causes severe slowdowns.
                +	// See https://connect.microsoft.com/IE/feedback/details/1736512/
                +	rnoInnerhtml = /<script|<style|<link/i,
                +
                +	// checked="checked" or checked
                +	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
                +	rscriptTypeMasked = /^true\/(.*)/,
                +	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
                +
                +// Prefer a tbody over its parent table for containing new rows
                +function manipulationTarget( elem, content ) {
                +	if ( nodeName( elem, "table" ) &&
                +		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
                +
                +		return jQuery( ">tbody", elem )[ 0 ] || elem;
                +	}
                +
                +	return elem;
                +}
                +
                +// Replace/restore the type attribute of script elements for safe DOM manipulation
                +function disableScript( elem ) {
                +	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
                +	return elem;
                +}
                +function restoreScript( elem ) {
                +	var match = rscriptTypeMasked.exec( elem.type );
                +
                +	if ( match ) {
                +		elem.type = match[ 1 ];
                +	} else {
                +		elem.removeAttribute( "type" );
                +	}
                +
                +	return elem;
                +}
                +
                +function cloneCopyEvent( src, dest ) {
                +	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
                +
                +	if ( dest.nodeType !== 1 ) {
                +		return;
                +	}
                +
                +	// 1. Copy private data: events, handlers, etc.
                +	if ( dataPriv.hasData( src ) ) {
                +		pdataOld = dataPriv.access( src );
                +		pdataCur = dataPriv.set( dest, pdataOld );
                +		events = pdataOld.events;
                +
                +		if ( events ) {
                +			delete pdataCur.handle;
                +			pdataCur.events = {};
                +
                +			for ( type in events ) {
                +				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
                +					jQuery.event.add( dest, type, events[ type ][ i ] );
                +				}
                +			}
                +		}
                +	}
                +
                +	// 2. Copy user data
                +	if ( dataUser.hasData( src ) ) {
                +		udataOld = dataUser.access( src );
                +		udataCur = jQuery.extend( {}, udataOld );
                +
                +		dataUser.set( dest, udataCur );
                +	}
                +}
                +
                +// Fix IE bugs, see support tests
                +function fixInput( src, dest ) {
                +	var nodeName = dest.nodeName.toLowerCase();
                +
                +	// Fails to persist the checked state of a cloned checkbox or radio button.
                +	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
                +		dest.checked = src.checked;
                +
                +	// Fails to return the selected option to the default selected state when cloning options
                +	} else if ( nodeName === "input" || nodeName === "textarea" ) {
                +		dest.defaultValue = src.defaultValue;
                +	}
                +}
                +
                +function domManip( collection, args, callback, ignored ) {
                +
                +	// Flatten any nested arrays
                +	args = concat.apply( [], args );
                +
                +	var fragment, first, scripts, hasScripts, node, doc,
                +		i = 0,
                +		l = collection.length,
                +		iNoClone = l - 1,
                +		value = args[ 0 ],
                +		isFunction = jQuery.isFunction( value );
                +
                +	// We can't cloneNode fragments that contain checked, in WebKit
                +	if ( isFunction ||
                +			( l > 1 && typeof value === "string" &&
                +				!support.checkClone && rchecked.test( value ) ) ) {
                +		return collection.each( function( index ) {
                +			var self = collection.eq( index );
                +			if ( isFunction ) {
                +				args[ 0 ] = value.call( this, index, self.html() );
                +			}
                +			domManip( self, args, callback, ignored );
                +		} );
                +	}
                +
                +	if ( l ) {
                +		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
                +		first = fragment.firstChild;
                +
                +		if ( fragment.childNodes.length === 1 ) {
                +			fragment = first;
                +		}
                +
                +		// Require either new content or an interest in ignored elements to invoke the callback
                +		if ( first || ignored ) {
                +			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
                +			hasScripts = scripts.length;
                +
                +			// Use the original fragment for the last item
                +			// instead of the first because it can end up
                +			// being emptied incorrectly in certain situations (#8070).
                +			for ( ; i < l; i++ ) {
                +				node = fragment;
                +
                +				if ( i !== iNoClone ) {
                +					node = jQuery.clone( node, true, true );
                +
                +					// Keep references to cloned scripts for later restoration
                +					if ( hasScripts ) {
                +
                +						// Support: Android <=4.0 only, PhantomJS 1 only
                +						// push.apply(_, arraylike) throws on ancient WebKit
                +						jQuery.merge( scripts, getAll( node, "script" ) );
                +					}
                +				}
                +
                +				callback.call( collection[ i ], node, i );
                +			}
                +
                +			if ( hasScripts ) {
                +				doc = scripts[ scripts.length - 1 ].ownerDocument;
                +
                +				// Reenable scripts
                +				jQuery.map( scripts, restoreScript );
                +
                +				// Evaluate executable scripts on first document insertion
                +				for ( i = 0; i < hasScripts; i++ ) {
                +					node = scripts[ i ];
                +					if ( rscriptType.test( node.type || "" ) &&
                +						!dataPriv.access( node, "globalEval" ) &&
                +						jQuery.contains( doc, node ) ) {
                +
                +						if ( node.src ) {
                +
                +							// Optional AJAX dependency, but won't run scripts if not present
                +							if ( jQuery._evalUrl ) {
                +								jQuery._evalUrl( node.src );
                +							}
                +						} else {
                +							DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	return collection;
                +}
                +
                +function remove( elem, selector, keepData ) {
                +	var node,
                +		nodes = selector ? jQuery.filter( selector, elem ) : elem,
                +		i = 0;
                +
                +	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
                +		if ( !keepData && node.nodeType === 1 ) {
                +			jQuery.cleanData( getAll( node ) );
                +		}
                +
                +		if ( node.parentNode ) {
                +			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
                +				setGlobalEval( getAll( node, "script" ) );
                +			}
                +			node.parentNode.removeChild( node );
                +		}
                +	}
                +
                +	return elem;
                +}
                +
                +jQuery.extend( {
                +	htmlPrefilter: function( html ) {
                +		return html.replace( rxhtmlTag, "<$1></$2>" );
                +	},
                +
                +	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
                +		var i, l, srcElements, destElements,
                +			clone = elem.cloneNode( true ),
                +			inPage = jQuery.contains( elem.ownerDocument, elem );
                +
                +		// Fix IE cloning issues
                +		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
                +				!jQuery.isXMLDoc( elem ) ) {
                +
                +			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
                +			destElements = getAll( clone );
                +			srcElements = getAll( elem );
                +
                +			for ( i = 0, l = srcElements.length; i < l; i++ ) {
                +				fixInput( srcElements[ i ], destElements[ i ] );
                +			}
                +		}
                +
                +		// Copy the events from the original to the clone
                +		if ( dataAndEvents ) {
                +			if ( deepDataAndEvents ) {
                +				srcElements = srcElements || getAll( elem );
                +				destElements = destElements || getAll( clone );
                +
                +				for ( i = 0, l = srcElements.length; i < l; i++ ) {
                +					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
                +				}
                +			} else {
                +				cloneCopyEvent( elem, clone );
                +			}
                +		}
                +
                +		// Preserve script evaluation history
                +		destElements = getAll( clone, "script" );
                +		if ( destElements.length > 0 ) {
                +			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
                +		}
                +
                +		// Return the cloned set
                +		return clone;
                +	},
                +
                +	cleanData: function( elems ) {
                +		var data, elem, type,
                +			special = jQuery.event.special,
                +			i = 0;
                +
                +		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
                +			if ( acceptData( elem ) ) {
                +				if ( ( data = elem[ dataPriv.expando ] ) ) {
                +					if ( data.events ) {
                +						for ( type in data.events ) {
                +							if ( special[ type ] ) {
                +								jQuery.event.remove( elem, type );
                +
                +							// This is a shortcut to avoid jQuery.event.remove's overhead
                +							} else {
                +								jQuery.removeEvent( elem, type, data.handle );
                +							}
                +						}
                +					}
                +
                +					// Support: Chrome <=35 - 45+
                +					// Assign undefined instead of using delete, see Data#remove
                +					elem[ dataPriv.expando ] = undefined;
                +				}
                +				if ( elem[ dataUser.expando ] ) {
                +
                +					// Support: Chrome <=35 - 45+
                +					// Assign undefined instead of using delete, see Data#remove
                +					elem[ dataUser.expando ] = undefined;
                +				}
                +			}
                +		}
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	detach: function( selector ) {
                +		return remove( this, selector, true );
                +	},
                +
                +	remove: function( selector ) {
                +		return remove( this, selector );
                +	},
                +
                +	text: function( value ) {
                +		return access( this, function( value ) {
                +			return value === undefined ?
                +				jQuery.text( this ) :
                +				this.empty().each( function() {
                +					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +						this.textContent = value;
                +					}
                +				} );
                +		}, null, value, arguments.length );
                +	},
                +
                +	append: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +				var target = manipulationTarget( this, elem );
                +				target.appendChild( elem );
                +			}
                +		} );
                +	},
                +
                +	prepend: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +				var target = manipulationTarget( this, elem );
                +				target.insertBefore( elem, target.firstChild );
                +			}
                +		} );
                +	},
                +
                +	before: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.parentNode ) {
                +				this.parentNode.insertBefore( elem, this );
                +			}
                +		} );
                +	},
                +
                +	after: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.parentNode ) {
                +				this.parentNode.insertBefore( elem, this.nextSibling );
                +			}
                +		} );
                +	},
                +
                +	empty: function() {
                +		var elem,
                +			i = 0;
                +
                +		for ( ; ( elem = this[ i ] ) != null; i++ ) {
                +			if ( elem.nodeType === 1 ) {
                +
                +				// Prevent memory leaks
                +				jQuery.cleanData( getAll( elem, false ) );
                +
                +				// Remove any remaining nodes
                +				elem.textContent = "";
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	clone: function( dataAndEvents, deepDataAndEvents ) {
                +		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                +		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
                +
                +		return this.map( function() {
                +			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                +		} );
                +	},
                +
                +	html: function( value ) {
                +		return access( this, function( value ) {
                +			var elem = this[ 0 ] || {},
                +				i = 0,
                +				l = this.length;
                +
                +			if ( value === undefined && elem.nodeType === 1 ) {
                +				return elem.innerHTML;
                +			}
                +
                +			// See if we can take a shortcut and just use innerHTML
                +			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
                +				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
                +
                +				value = jQuery.htmlPrefilter( value );
                +
                +				try {
                +					for ( ; i < l; i++ ) {
                +						elem = this[ i ] || {};
                +
                +						// Remove element nodes and prevent memory leaks
                +						if ( elem.nodeType === 1 ) {
                +							jQuery.cleanData( getAll( elem, false ) );
                +							elem.innerHTML = value;
                +						}
                +					}
                +
                +					elem = 0;
                +
                +				// If using innerHTML throws an exception, use the fallback method
                +				} catch ( e ) {}
                +			}
                +
                +			if ( elem ) {
                +				this.empty().append( value );
                +			}
                +		}, null, value, arguments.length );
                +	},
                +
                +	replaceWith: function() {
                +		var ignored = [];
                +
                +		// Make the changes, replacing each non-ignored context element with the new content
                +		return domManip( this, arguments, function( elem ) {
                +			var parent = this.parentNode;
                +
                +			if ( jQuery.inArray( this, ignored ) < 0 ) {
                +				jQuery.cleanData( getAll( this ) );
                +				if ( parent ) {
                +					parent.replaceChild( elem, this );
                +				}
                +			}
                +
                +		// Force callback invocation
                +		}, ignored );
                +	}
                +} );
                +
                +jQuery.each( {
                +	appendTo: "append",
                +	prependTo: "prepend",
                +	insertBefore: "before",
                +	insertAfter: "after",
                +	replaceAll: "replaceWith"
                +}, function( name, original ) {
                +	jQuery.fn[ name ] = function( selector ) {
                +		var elems,
                +			ret = [],
                +			insert = jQuery( selector ),
                +			last = insert.length - 1,
                +			i = 0;
                +
                +		for ( ; i <= last; i++ ) {
                +			elems = i === last ? this : this.clone( true );
                +			jQuery( insert[ i ] )[ original ]( elems );
                +
                +			// Support: Android <=4.0 only, PhantomJS 1 only
                +			// .get() because push.apply(_, arraylike) throws on ancient WebKit
                +			push.apply( ret, elems.get() );
                +		}
                +
                +		return this.pushStack( ret );
                +	};
                +} );
                +var rmargin = ( /^margin/ );
                +
                +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
                +
                +var getStyles = function( elem ) {
                +
                +		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
                +		// IE throws on elements created in popups
                +		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
                +		var view = elem.ownerDocument.defaultView;
                +
                +		if ( !view || !view.opener ) {
                +			view = window;
                +		}
                +
                +		return view.getComputedStyle( elem );
                +	};
                +
                +
                +
                +( function() {
                +
                +	// Executing both pixelPosition & boxSizingReliable tests require only one layout
                +	// so they're executed at the same time to save the second computation.
                +	function computeStyleTests() {
                +
                +		// This is a singleton, we need to execute it only once
                +		if ( !div ) {
                +			return;
                +		}
                +
                +		div.style.cssText =
                +			"box-sizing:border-box;" +
                +			"position:relative;display:block;" +
                +			"margin:auto;border:1px;padding:1px;" +
                +			"top:1%;width:50%";
                +		div.innerHTML = "";
                +		documentElement.appendChild( container );
                +
                +		var divStyle = window.getComputedStyle( div );
                +		pixelPositionVal = divStyle.top !== "1%";
                +
                +		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
                +		reliableMarginLeftVal = divStyle.marginLeft === "2px";
                +		boxSizingReliableVal = divStyle.width === "4px";
                +
                +		// Support: Android 4.0 - 4.3 only
                +		// Some styles come back with percentage values, even though they shouldn't
                +		div.style.marginRight = "50%";
                +		pixelMarginRightVal = divStyle.marginRight === "4px";
                +
                +		documentElement.removeChild( container );
                +
                +		// Nullify the div so it wouldn't be stored in the memory and
                +		// it will also be a sign that checks already performed
                +		div = null;
                +	}
                +
                +	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
                +		container = document.createElement( "div" ),
                +		div = document.createElement( "div" );
                +
                +	// Finish early in limited (non-browser) environments
                +	if ( !div.style ) {
                +		return;
                +	}
                +
                +	// Support: IE <=9 - 11 only
                +	// Style of cloned element affects source element cloned (#8908)
                +	div.style.backgroundClip = "content-box";
                +	div.cloneNode( true ).style.backgroundClip = "";
                +	support.clearCloneStyle = div.style.backgroundClip === "content-box";
                +
                +	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
                +		"padding:0;margin-top:1px;position:absolute";
                +	container.appendChild( div );
                +
                +	jQuery.extend( support, {
                +		pixelPosition: function() {
                +			computeStyleTests();
                +			return pixelPositionVal;
                +		},
                +		boxSizingReliable: function() {
                +			computeStyleTests();
                +			return boxSizingReliableVal;
                +		},
                +		pixelMarginRight: function() {
                +			computeStyleTests();
                +			return pixelMarginRightVal;
                +		},
                +		reliableMarginLeft: function() {
                +			computeStyleTests();
                +			return reliableMarginLeftVal;
                +		}
                +	} );
                +} )();
                +
                +
                +function curCSS( elem, name, computed ) {
                +	var width, minWidth, maxWidth, ret,
                +
                +		// Support: Firefox 51+
                +		// Retrieving style before computed somehow
                +		// fixes an issue with getting wrong values
                +		// on detached elements
                +		style = elem.style;
                +
                +	computed = computed || getStyles( elem );
                +
                +	// getPropertyValue is needed for:
                +	//   .css('filter') (IE 9 only, #12537)
                +	//   .css('--customProperty) (#3144)
                +	if ( computed ) {
                +		ret = computed.getPropertyValue( name ) || computed[ name ];
                +
                +		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
                +			ret = jQuery.style( elem, name );
                +		}
                +
                +		// A tribute to the "awesome hack by Dean Edwards"
                +		// Android Browser returns percentage for some values,
                +		// but width seems to be reliably pixels.
                +		// This is against the CSSOM draft spec:
                +		// https://drafts.csswg.org/cssom/#resolved-values
                +		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
                +
                +			// Remember the original values
                +			width = style.width;
                +			minWidth = style.minWidth;
                +			maxWidth = style.maxWidth;
                +
                +			// Put in the new values to get a computed value out
                +			style.minWidth = style.maxWidth = style.width = ret;
                +			ret = computed.width;
                +
                +			// Revert the changed values
                +			style.width = width;
                +			style.minWidth = minWidth;
                +			style.maxWidth = maxWidth;
                +		}
                +	}
                +
                +	return ret !== undefined ?
                +
                +		// Support: IE <=9 - 11 only
                +		// IE returns zIndex value as an integer.
                +		ret + "" :
                +		ret;
                +}
                +
                +
                +function addGetHookIf( conditionFn, hookFn ) {
                +
                +	// Define the hook, we'll check on the first run if it's really needed.
                +	return {
                +		get: function() {
                +			if ( conditionFn() ) {
                +
                +				// Hook not needed (or it's not possible to use it due
                +				// to missing dependency), remove it.
                +				delete this.get;
                +				return;
                +			}
                +
                +			// Hook needed; redefine it so that the support test is not executed again.
                +			return ( this.get = hookFn ).apply( this, arguments );
                +		}
                +	};
                +}
                +
                +
                +var
                +
                +	// Swappable if display is none or starts with table
                +	// except "table", "table-cell", or "table-caption"
                +	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
                +	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
                +	rcustomProp = /^--/,
                +	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
                +	cssNormalTransform = {
                +		letterSpacing: "0",
                +		fontWeight: "400"
                +	},
                +
                +	cssPrefixes = [ "Webkit", "Moz", "ms" ],
                +	emptyStyle = document.createElement( "div" ).style;
                +
                +// Return a css property mapped to a potentially vendor prefixed property
                +function vendorPropName( name ) {
                +
                +	// Shortcut for names that are not vendor prefixed
                +	if ( name in emptyStyle ) {
                +		return name;
                +	}
                +
                +	// Check for vendor prefixed names
                +	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
                +		i = cssPrefixes.length;
                +
                +	while ( i-- ) {
                +		name = cssPrefixes[ i ] + capName;
                +		if ( name in emptyStyle ) {
                +			return name;
                +		}
                +	}
                +}
                +
                +// Return a property mapped along what jQuery.cssProps suggests or to
                +// a vendor prefixed property.
                +function finalPropName( name ) {
                +	var ret = jQuery.cssProps[ name ];
                +	if ( !ret ) {
                +		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
                +	}
                +	return ret;
                +}
                +
                +function setPositiveNumber( elem, value, subtract ) {
                +
                +	// Any relative (+/-) values have already been
                +	// normalized at this point
                +	var matches = rcssNum.exec( value );
                +	return matches ?
                +
                +		// Guard against undefined "subtract", e.g., when used as in cssHooks
                +		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
                +		value;
                +}
                +
                +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
                +	var i,
                +		val = 0;
                +
                +	// If we already have the right measurement, avoid augmentation
                +	if ( extra === ( isBorderBox ? "border" : "content" ) ) {
                +		i = 4;
                +
                +	// Otherwise initialize for horizontal or vertical properties
                +	} else {
                +		i = name === "width" ? 1 : 0;
                +	}
                +
                +	for ( ; i < 4; i += 2 ) {
                +
                +		// Both box models exclude margin, so add it if we want it
                +		if ( extra === "margin" ) {
                +			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
                +		}
                +
                +		if ( isBorderBox ) {
                +
                +			// border-box includes padding, so remove it if we want content
                +			if ( extra === "content" ) {
                +				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
                +			}
                +
                +			// At this point, extra isn't border nor margin, so remove border
                +			if ( extra !== "margin" ) {
                +				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
                +			}
                +		} else {
                +
                +			// At this point, extra isn't content, so add padding
                +			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
                +
                +			// At this point, extra isn't content nor padding, so add border
                +			if ( extra !== "padding" ) {
                +				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
                +			}
                +		}
                +	}
                +
                +	return val;
                +}
                +
                +function getWidthOrHeight( elem, name, extra ) {
                +
                +	// Start with computed style
                +	var valueIsBorderBox,
                +		styles = getStyles( elem ),
                +		val = curCSS( elem, name, styles ),
                +		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
                +
                +	// Computed unit is not pixels. Stop here and return.
                +	if ( rnumnonpx.test( val ) ) {
                +		return val;
                +	}
                +
                +	// Check for style in case a browser which returns unreliable values
                +	// for getComputedStyle silently falls back to the reliable elem.style
                +	valueIsBorderBox = isBorderBox &&
                +		( support.boxSizingReliable() || val === elem.style[ name ] );
                +
                +	// Fall back to offsetWidth/Height when value is "auto"
                +	// This happens for inline elements with no explicit setting (gh-3571)
                +	if ( val === "auto" ) {
                +		val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
                +	}
                +
                +	// Normalize "", auto, and prepare for extra
                +	val = parseFloat( val ) || 0;
                +
                +	// Use the active box-sizing model to add/subtract irrelevant styles
                +	return ( val +
                +		augmentWidthOrHeight(
                +			elem,
                +			name,
                +			extra || ( isBorderBox ? "border" : "content" ),
                +			valueIsBorderBox,
                +			styles
                +		)
                +	) + "px";
                +}
                +
                +jQuery.extend( {
                +
                +	// Add in style property hooks for overriding the default
                +	// behavior of getting and setting a style property
                +	cssHooks: {
                +		opacity: {
                +			get: function( elem, computed ) {
                +				if ( computed ) {
                +
                +					// We should always get a number back from opacity
                +					var ret = curCSS( elem, "opacity" );
                +					return ret === "" ? "1" : ret;
                +				}
                +			}
                +		}
                +	},
                +
                +	// Don't automatically add "px" to these possibly-unitless properties
                +	cssNumber: {
                +		"animationIterationCount": true,
                +		"columnCount": true,
                +		"fillOpacity": true,
                +		"flexGrow": true,
                +		"flexShrink": true,
                +		"fontWeight": true,
                +		"lineHeight": true,
                +		"opacity": true,
                +		"order": true,
                +		"orphans": true,
                +		"widows": true,
                +		"zIndex": true,
                +		"zoom": true
                +	},
                +
                +	// Add in properties whose names you wish to fix before
                +	// setting or getting the value
                +	cssProps: {
                +		"float": "cssFloat"
                +	},
                +
                +	// Get and set the style property on a DOM Node
                +	style: function( elem, name, value, extra ) {
                +
                +		// Don't set styles on text and comment nodes
                +		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
                +			return;
                +		}
                +
                +		// Make sure that we're working with the right name
                +		var ret, type, hooks,
                +			origName = jQuery.camelCase( name ),
                +			isCustomProp = rcustomProp.test( name ),
                +			style = elem.style;
                +
                +		// Make sure that we're working with the right name. We don't
                +		// want to query the value if it is a CSS custom property
                +		// since they are user-defined.
                +		if ( !isCustomProp ) {
                +			name = finalPropName( origName );
                +		}
                +
                +		// Gets hook for the prefixed version, then unprefixed version
                +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
                +
                +		// Check if we're setting a value
                +		if ( value !== undefined ) {
                +			type = typeof value;
                +
                +			// Convert "+=" or "-=" to relative numbers (#7345)
                +			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
                +				value = adjustCSS( elem, name, ret );
                +
                +				// Fixes bug #9237
                +				type = "number";
                +			}
                +
                +			// Make sure that null and NaN values aren't set (#7116)
                +			if ( value == null || value !== value ) {
                +				return;
                +			}
                +
                +			// If a number was passed in, add the unit (except for certain CSS properties)
                +			if ( type === "number" ) {
                +				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
                +			}
                +
                +			// background-* props affect original clone's values
                +			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
                +				style[ name ] = "inherit";
                +			}
                +
                +			// If a hook was provided, use that value, otherwise just set the specified value
                +			if ( !hooks || !( "set" in hooks ) ||
                +				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
                +
                +				if ( isCustomProp ) {
                +					style.setProperty( name, value );
                +				} else {
                +					style[ name ] = value;
                +				}
                +			}
                +
                +		} else {
                +
                +			// If a hook was provided get the non-computed value from there
                +			if ( hooks && "get" in hooks &&
                +				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
                +
                +				return ret;
                +			}
                +
                +			// Otherwise just get the value from the style object
                +			return style[ name ];
                +		}
                +	},
                +
                +	css: function( elem, name, extra, styles ) {
                +		var val, num, hooks,
                +			origName = jQuery.camelCase( name ),
                +			isCustomProp = rcustomProp.test( name );
                +
                +		// Make sure that we're working with the right name. We don't
                +		// want to modify the value if it is a CSS custom property
                +		// since they are user-defined.
                +		if ( !isCustomProp ) {
                +			name = finalPropName( origName );
                +		}
                +
                +		// Try prefixed name followed by the unprefixed name
                +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
                +
                +		// If a hook was provided get the computed value from there
                +		if ( hooks && "get" in hooks ) {
                +			val = hooks.get( elem, true, extra );
                +		}
                +
                +		// Otherwise, if a way to get the computed value exists, use that
                +		if ( val === undefined ) {
                +			val = curCSS( elem, name, styles );
                +		}
                +
                +		// Convert "normal" to computed value
                +		if ( val === "normal" && name in cssNormalTransform ) {
                +			val = cssNormalTransform[ name ];
                +		}
                +
                +		// Make numeric if forced or a qualifier was provided and val looks numeric
                +		if ( extra === "" || extra ) {
                +			num = parseFloat( val );
                +			return extra === true || isFinite( num ) ? num || 0 : val;
                +		}
                +
                +		return val;
                +	}
                +} );
                +
                +jQuery.each( [ "height", "width" ], function( i, name ) {
                +	jQuery.cssHooks[ name ] = {
                +		get: function( elem, computed, extra ) {
                +			if ( computed ) {
                +
                +				// Certain elements can have dimension info if we invisibly show them
                +				// but it must have a current display style that would benefit
                +				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
                +
                +					// Support: Safari 8+
                +					// Table columns in Safari have non-zero offsetWidth & zero
                +					// getBoundingClientRect().width unless display is changed.
                +					// Support: IE <=11 only
                +					// Running getBoundingClientRect on a disconnected node
                +					// in IE throws an error.
                +					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
                +						swap( elem, cssShow, function() {
                +							return getWidthOrHeight( elem, name, extra );
                +						} ) :
                +						getWidthOrHeight( elem, name, extra );
                +			}
                +		},
                +
                +		set: function( elem, value, extra ) {
                +			var matches,
                +				styles = extra && getStyles( elem ),
                +				subtract = extra && augmentWidthOrHeight(
                +					elem,
                +					name,
                +					extra,
                +					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
                +					styles
                +				);
                +
                +			// Convert to pixels if value adjustment is needed
                +			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
                +				( matches[ 3 ] || "px" ) !== "px" ) {
                +
                +				elem.style[ name ] = value;
                +				value = jQuery.css( elem, name );
                +			}
                +
                +			return setPositiveNumber( elem, value, subtract );
                +		}
                +	};
                +} );
                +
                +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
                +	function( elem, computed ) {
                +		if ( computed ) {
                +			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
                +				elem.getBoundingClientRect().left -
                +					swap( elem, { marginLeft: 0 }, function() {
                +						return elem.getBoundingClientRect().left;
                +					} )
                +				) + "px";
                +		}
                +	}
                +);
                +
                +// These hooks are used by animate to expand properties
                +jQuery.each( {
                +	margin: "",
                +	padding: "",
                +	border: "Width"
                +}, function( prefix, suffix ) {
                +	jQuery.cssHooks[ prefix + suffix ] = {
                +		expand: function( value ) {
                +			var i = 0,
                +				expanded = {},
                +
                +				// Assumes a single number if not a string
                +				parts = typeof value === "string" ? value.split( " " ) : [ value ];
                +
                +			for ( ; i < 4; i++ ) {
                +				expanded[ prefix + cssExpand[ i ] + suffix ] =
                +					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
                +			}
                +
                +			return expanded;
                +		}
                +	};
                +
                +	if ( !rmargin.test( prefix ) ) {
                +		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	css: function( name, value ) {
                +		return access( this, function( elem, name, value ) {
                +			var styles, len,
                +				map = {},
                +				i = 0;
                +
                +			if ( Array.isArray( name ) ) {
                +				styles = getStyles( elem );
                +				len = name.length;
                +
                +				for ( ; i < len; i++ ) {
                +					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
                +				}
                +
                +				return map;
                +			}
                +
                +			return value !== undefined ?
                +				jQuery.style( elem, name, value ) :
                +				jQuery.css( elem, name );
                +		}, name, value, arguments.length > 1 );
                +	}
                +} );
                +
                +
                +function Tween( elem, options, prop, end, easing ) {
                +	return new Tween.prototype.init( elem, options, prop, end, easing );
                +}
                +jQuery.Tween = Tween;
                +
                +Tween.prototype = {
                +	constructor: Tween,
                +	init: function( elem, options, prop, end, easing, unit ) {
                +		this.elem = elem;
                +		this.prop = prop;
                +		this.easing = easing || jQuery.easing._default;
                +		this.options = options;
                +		this.start = this.now = this.cur();
                +		this.end = end;
                +		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
                +	},
                +	cur: function() {
                +		var hooks = Tween.propHooks[ this.prop ];
                +
                +		return hooks && hooks.get ?
                +			hooks.get( this ) :
                +			Tween.propHooks._default.get( this );
                +	},
                +	run: function( percent ) {
                +		var eased,
                +			hooks = Tween.propHooks[ this.prop ];
                +
                +		if ( this.options.duration ) {
                +			this.pos = eased = jQuery.easing[ this.easing ](
                +				percent, this.options.duration * percent, 0, 1, this.options.duration
                +			);
                +		} else {
                +			this.pos = eased = percent;
                +		}
                +		this.now = ( this.end - this.start ) * eased + this.start;
                +
                +		if ( this.options.step ) {
                +			this.options.step.call( this.elem, this.now, this );
                +		}
                +
                +		if ( hooks && hooks.set ) {
                +			hooks.set( this );
                +		} else {
                +			Tween.propHooks._default.set( this );
                +		}
                +		return this;
                +	}
                +};
                +
                +Tween.prototype.init.prototype = Tween.prototype;
                +
                +Tween.propHooks = {
                +	_default: {
                +		get: function( tween ) {
                +			var result;
                +
                +			// Use a property on the element directly when it is not a DOM element,
                +			// or when there is no matching style property that exists.
                +			if ( tween.elem.nodeType !== 1 ||
                +				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
                +				return tween.elem[ tween.prop ];
                +			}
                +
                +			// Passing an empty string as a 3rd parameter to .css will automatically
                +			// attempt a parseFloat and fallback to a string if the parse fails.
                +			// Simple values such as "10px" are parsed to Float;
                +			// complex values such as "rotate(1rad)" are returned as-is.
                +			result = jQuery.css( tween.elem, tween.prop, "" );
                +
                +			// Empty strings, null, undefined and "auto" are converted to 0.
                +			return !result || result === "auto" ? 0 : result;
                +		},
                +		set: function( tween ) {
                +
                +			// Use step hook for back compat.
                +			// Use cssHook if its there.
                +			// Use .style if available and use plain properties where available.
                +			if ( jQuery.fx.step[ tween.prop ] ) {
                +				jQuery.fx.step[ tween.prop ]( tween );
                +			} else if ( tween.elem.nodeType === 1 &&
                +				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
                +					jQuery.cssHooks[ tween.prop ] ) ) {
                +				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
                +			} else {
                +				tween.elem[ tween.prop ] = tween.now;
                +			}
                +		}
                +	}
                +};
                +
                +// Support: IE <=9 only
                +// Panic based approach to setting things on disconnected nodes
                +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
                +	set: function( tween ) {
                +		if ( tween.elem.nodeType && tween.elem.parentNode ) {
                +			tween.elem[ tween.prop ] = tween.now;
                +		}
                +	}
                +};
                +
                +jQuery.easing = {
                +	linear: function( p ) {
                +		return p;
                +	},
                +	swing: function( p ) {
                +		return 0.5 - Math.cos( p * Math.PI ) / 2;
                +	},
                +	_default: "swing"
                +};
                +
                +jQuery.fx = Tween.prototype.init;
                +
                +// Back compat <1.8 extension point
                +jQuery.fx.step = {};
                +
                +
                +
                +
                +var
                +	fxNow, inProgress,
                +	rfxtypes = /^(?:toggle|show|hide)$/,
                +	rrun = /queueHooks$/;
                +
                +function schedule() {
                +	if ( inProgress ) {
                +		if ( document.hidden === false && window.requestAnimationFrame ) {
                +			window.requestAnimationFrame( schedule );
                +		} else {
                +			window.setTimeout( schedule, jQuery.fx.interval );
                +		}
                +
                +		jQuery.fx.tick();
                +	}
                +}
                +
                +// Animations created synchronously will run synchronously
                +function createFxNow() {
                +	window.setTimeout( function() {
                +		fxNow = undefined;
                +	} );
                +	return ( fxNow = jQuery.now() );
                +}
                +
                +// Generate parameters to create a standard animation
                +function genFx( type, includeWidth ) {
                +	var which,
                +		i = 0,
                +		attrs = { height: type };
                +
                +	// If we include width, step value is 1 to do all cssExpand values,
                +	// otherwise step value is 2 to skip over Left and Right
                +	includeWidth = includeWidth ? 1 : 0;
                +	for ( ; i < 4; i += 2 - includeWidth ) {
                +		which = cssExpand[ i ];
                +		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
                +	}
                +
                +	if ( includeWidth ) {
                +		attrs.opacity = attrs.width = type;
                +	}
                +
                +	return attrs;
                +}
                +
                +function createTween( value, prop, animation ) {
                +	var tween,
                +		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
                +		index = 0,
                +		length = collection.length;
                +	for ( ; index < length; index++ ) {
                +		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
                +
                +			// We're done with this property
                +			return tween;
                +		}
                +	}
                +}
                +
                +function defaultPrefilter( elem, props, opts ) {
                +	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
                +		isBox = "width" in props || "height" in props,
                +		anim = this,
                +		orig = {},
                +		style = elem.style,
                +		hidden = elem.nodeType && isHiddenWithinTree( elem ),
                +		dataShow = dataPriv.get( elem, "fxshow" );
                +
                +	// Queue-skipping animations hijack the fx hooks
                +	if ( !opts.queue ) {
                +		hooks = jQuery._queueHooks( elem, "fx" );
                +		if ( hooks.unqueued == null ) {
                +			hooks.unqueued = 0;
                +			oldfire = hooks.empty.fire;
                +			hooks.empty.fire = function() {
                +				if ( !hooks.unqueued ) {
                +					oldfire();
                +				}
                +			};
                +		}
                +		hooks.unqueued++;
                +
                +		anim.always( function() {
                +
                +			// Ensure the complete handler is called before this completes
                +			anim.always( function() {
                +				hooks.unqueued--;
                +				if ( !jQuery.queue( elem, "fx" ).length ) {
                +					hooks.empty.fire();
                +				}
                +			} );
                +		} );
                +	}
                +
                +	// Detect show/hide animations
                +	for ( prop in props ) {
                +		value = props[ prop ];
                +		if ( rfxtypes.test( value ) ) {
                +			delete props[ prop ];
                +			toggle = toggle || value === "toggle";
                +			if ( value === ( hidden ? "hide" : "show" ) ) {
                +
                +				// Pretend to be hidden if this is a "show" and
                +				// there is still data from a stopped show/hide
                +				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
                +					hidden = true;
                +
                +				// Ignore all other no-op show/hide data
                +				} else {
                +					continue;
                +				}
                +			}
                +			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
                +		}
                +	}
                +
                +	// Bail out if this is a no-op like .hide().hide()
                +	propTween = !jQuery.isEmptyObject( props );
                +	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
                +		return;
                +	}
                +
                +	// Restrict "overflow" and "display" styles during box animations
                +	if ( isBox && elem.nodeType === 1 ) {
                +
                +		// Support: IE <=9 - 11, Edge 12 - 13
                +		// Record all 3 overflow attributes because IE does not infer the shorthand
                +		// from identically-valued overflowX and overflowY
                +		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
                +
                +		// Identify a display type, preferring old show/hide data over the CSS cascade
                +		restoreDisplay = dataShow && dataShow.display;
                +		if ( restoreDisplay == null ) {
                +			restoreDisplay = dataPriv.get( elem, "display" );
                +		}
                +		display = jQuery.css( elem, "display" );
                +		if ( display === "none" ) {
                +			if ( restoreDisplay ) {
                +				display = restoreDisplay;
                +			} else {
                +
                +				// Get nonempty value(s) by temporarily forcing visibility
                +				showHide( [ elem ], true );
                +				restoreDisplay = elem.style.display || restoreDisplay;
                +				display = jQuery.css( elem, "display" );
                +				showHide( [ elem ] );
                +			}
                +		}
                +
                +		// Animate inline elements as inline-block
                +		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
                +			if ( jQuery.css( elem, "float" ) === "none" ) {
                +
                +				// Restore the original display value at the end of pure show/hide animations
                +				if ( !propTween ) {
                +					anim.done( function() {
                +						style.display = restoreDisplay;
                +					} );
                +					if ( restoreDisplay == null ) {
                +						display = style.display;
                +						restoreDisplay = display === "none" ? "" : display;
                +					}
                +				}
                +				style.display = "inline-block";
                +			}
                +		}
                +	}
                +
                +	if ( opts.overflow ) {
                +		style.overflow = "hidden";
                +		anim.always( function() {
                +			style.overflow = opts.overflow[ 0 ];
                +			style.overflowX = opts.overflow[ 1 ];
                +			style.overflowY = opts.overflow[ 2 ];
                +		} );
                +	}
                +
                +	// Implement show/hide animations
                +	propTween = false;
                +	for ( prop in orig ) {
                +
                +		// General show/hide setup for this element animation
                +		if ( !propTween ) {
                +			if ( dataShow ) {
                +				if ( "hidden" in dataShow ) {
                +					hidden = dataShow.hidden;
                +				}
                +			} else {
                +				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
                +			}
                +
                +			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
                +			if ( toggle ) {
                +				dataShow.hidden = !hidden;
                +			}
                +
                +			// Show elements before animating them
                +			if ( hidden ) {
                +				showHide( [ elem ], true );
                +			}
                +
                +			/* eslint-disable no-loop-func */
                +
                +			anim.done( function() {
                +
                +			/* eslint-enable no-loop-func */
                +
                +				// The final step of a "hide" animation is actually hiding the element
                +				if ( !hidden ) {
                +					showHide( [ elem ] );
                +				}
                +				dataPriv.remove( elem, "fxshow" );
                +				for ( prop in orig ) {
                +					jQuery.style( elem, prop, orig[ prop ] );
                +				}
                +			} );
                +		}
                +
                +		// Per-property setup
                +		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
                +		if ( !( prop in dataShow ) ) {
                +			dataShow[ prop ] = propTween.start;
                +			if ( hidden ) {
                +				propTween.end = propTween.start;
                +				propTween.start = 0;
                +			}
                +		}
                +	}
                +}
                +
                +function propFilter( props, specialEasing ) {
                +	var index, name, easing, value, hooks;
                +
                +	// camelCase, specialEasing and expand cssHook pass
                +	for ( index in props ) {
                +		name = jQuery.camelCase( index );
                +		easing = specialEasing[ name ];
                +		value = props[ index ];
                +		if ( Array.isArray( value ) ) {
                +			easing = value[ 1 ];
                +			value = props[ index ] = value[ 0 ];
                +		}
                +
                +		if ( index !== name ) {
                +			props[ name ] = value;
                +			delete props[ index ];
                +		}
                +
                +		hooks = jQuery.cssHooks[ name ];
                +		if ( hooks && "expand" in hooks ) {
                +			value = hooks.expand( value );
                +			delete props[ name ];
                +
                +			// Not quite $.extend, this won't overwrite existing keys.
                +			// Reusing 'index' because we have the correct "name"
                +			for ( index in value ) {
                +				if ( !( index in props ) ) {
                +					props[ index ] = value[ index ];
                +					specialEasing[ index ] = easing;
                +				}
                +			}
                +		} else {
                +			specialEasing[ name ] = easing;
                +		}
                +	}
                +}
                +
                +function Animation( elem, properties, options ) {
                +	var result,
                +		stopped,
                +		index = 0,
                +		length = Animation.prefilters.length,
                +		deferred = jQuery.Deferred().always( function() {
                +
                +			// Don't match elem in the :animated selector
                +			delete tick.elem;
                +		} ),
                +		tick = function() {
                +			if ( stopped ) {
                +				return false;
                +			}
                +			var currentTime = fxNow || createFxNow(),
                +				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
                +
                +				// Support: Android 2.3 only
                +				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
                +				temp = remaining / animation.duration || 0,
                +				percent = 1 - temp,
                +				index = 0,
                +				length = animation.tweens.length;
                +
                +			for ( ; index < length; index++ ) {
                +				animation.tweens[ index ].run( percent );
                +			}
                +
                +			deferred.notifyWith( elem, [ animation, percent, remaining ] );
                +
                +			// If there's more to do, yield
                +			if ( percent < 1 && length ) {
                +				return remaining;
                +			}
                +
                +			// If this was an empty animation, synthesize a final progress notification
                +			if ( !length ) {
                +				deferred.notifyWith( elem, [ animation, 1, 0 ] );
                +			}
                +
                +			// Resolve the animation and report its conclusion
                +			deferred.resolveWith( elem, [ animation ] );
                +			return false;
                +		},
                +		animation = deferred.promise( {
                +			elem: elem,
                +			props: jQuery.extend( {}, properties ),
                +			opts: jQuery.extend( true, {
                +				specialEasing: {},
                +				easing: jQuery.easing._default
                +			}, options ),
                +			originalProperties: properties,
                +			originalOptions: options,
                +			startTime: fxNow || createFxNow(),
                +			duration: options.duration,
                +			tweens: [],
                +			createTween: function( prop, end ) {
                +				var tween = jQuery.Tween( elem, animation.opts, prop, end,
                +						animation.opts.specialEasing[ prop ] || animation.opts.easing );
                +				animation.tweens.push( tween );
                +				return tween;
                +			},
                +			stop: function( gotoEnd ) {
                +				var index = 0,
                +
                +					// If we are going to the end, we want to run all the tweens
                +					// otherwise we skip this part
                +					length = gotoEnd ? animation.tweens.length : 0;
                +				if ( stopped ) {
                +					return this;
                +				}
                +				stopped = true;
                +				for ( ; index < length; index++ ) {
                +					animation.tweens[ index ].run( 1 );
                +				}
                +
                +				// Resolve when we played the last frame; otherwise, reject
                +				if ( gotoEnd ) {
                +					deferred.notifyWith( elem, [ animation, 1, 0 ] );
                +					deferred.resolveWith( elem, [ animation, gotoEnd ] );
                +				} else {
                +					deferred.rejectWith( elem, [ animation, gotoEnd ] );
                +				}
                +				return this;
                +			}
                +		} ),
                +		props = animation.props;
                +
                +	propFilter( props, animation.opts.specialEasing );
                +
                +	for ( ; index < length; index++ ) {
                +		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
                +		if ( result ) {
                +			if ( jQuery.isFunction( result.stop ) ) {
                +				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
                +					jQuery.proxy( result.stop, result );
                +			}
                +			return result;
                +		}
                +	}
                +
                +	jQuery.map( props, createTween, animation );
                +
                +	if ( jQuery.isFunction( animation.opts.start ) ) {
                +		animation.opts.start.call( elem, animation );
                +	}
                +
                +	// Attach callbacks from options
                +	animation
                +		.progress( animation.opts.progress )
                +		.done( animation.opts.done, animation.opts.complete )
                +		.fail( animation.opts.fail )
                +		.always( animation.opts.always );
                +
                +	jQuery.fx.timer(
                +		jQuery.extend( tick, {
                +			elem: elem,
                +			anim: animation,
                +			queue: animation.opts.queue
                +		} )
                +	);
                +
                +	return animation;
                +}
                +
                +jQuery.Animation = jQuery.extend( Animation, {
                +
                +	tweeners: {
                +		"*": [ function( prop, value ) {
                +			var tween = this.createTween( prop, value );
                +			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
                +			return tween;
                +		} ]
                +	},
                +
                +	tweener: function( props, callback ) {
                +		if ( jQuery.isFunction( props ) ) {
                +			callback = props;
                +			props = [ "*" ];
                +		} else {
                +			props = props.match( rnothtmlwhite );
                +		}
                +
                +		var prop,
                +			index = 0,
                +			length = props.length;
                +
                +		for ( ; index < length; index++ ) {
                +			prop = props[ index ];
                +			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
                +			Animation.tweeners[ prop ].unshift( callback );
                +		}
                +	},
                +
                +	prefilters: [ defaultPrefilter ],
                +
                +	prefilter: function( callback, prepend ) {
                +		if ( prepend ) {
                +			Animation.prefilters.unshift( callback );
                +		} else {
                +			Animation.prefilters.push( callback );
                +		}
                +	}
                +} );
                +
                +jQuery.speed = function( speed, easing, fn ) {
                +	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
                +		complete: fn || !fn && easing ||
                +			jQuery.isFunction( speed ) && speed,
                +		duration: speed,
                +		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
                +	};
                +
                +	// Go to the end state if fx are off
                +	if ( jQuery.fx.off ) {
                +		opt.duration = 0;
                +
                +	} else {
                +		if ( typeof opt.duration !== "number" ) {
                +			if ( opt.duration in jQuery.fx.speeds ) {
                +				opt.duration = jQuery.fx.speeds[ opt.duration ];
                +
                +			} else {
                +				opt.duration = jQuery.fx.speeds._default;
                +			}
                +		}
                +	}
                +
                +	// Normalize opt.queue - true/undefined/null -> "fx"
                +	if ( opt.queue == null || opt.queue === true ) {
                +		opt.queue = "fx";
                +	}
                +
                +	// Queueing
                +	opt.old = opt.complete;
                +
                +	opt.complete = function() {
                +		if ( jQuery.isFunction( opt.old ) ) {
                +			opt.old.call( this );
                +		}
                +
                +		if ( opt.queue ) {
                +			jQuery.dequeue( this, opt.queue );
                +		}
                +	};
                +
                +	return opt;
                +};
                +
                +jQuery.fn.extend( {
                +	fadeTo: function( speed, to, easing, callback ) {
                +
                +		// Show any hidden elements after setting opacity to 0
                +		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
                +
                +			// Animate to the value specified
                +			.end().animate( { opacity: to }, speed, easing, callback );
                +	},
                +	animate: function( prop, speed, easing, callback ) {
                +		var empty = jQuery.isEmptyObject( prop ),
                +			optall = jQuery.speed( speed, easing, callback ),
                +			doAnimation = function() {
                +
                +				// Operate on a copy of prop so per-property easing won't be lost
                +				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
                +
                +				// Empty animations, or finishing resolves immediately
                +				if ( empty || dataPriv.get( this, "finish" ) ) {
                +					anim.stop( true );
                +				}
                +			};
                +			doAnimation.finish = doAnimation;
                +
                +		return empty || optall.queue === false ?
                +			this.each( doAnimation ) :
                +			this.queue( optall.queue, doAnimation );
                +	},
                +	stop: function( type, clearQueue, gotoEnd ) {
                +		var stopQueue = function( hooks ) {
                +			var stop = hooks.stop;
                +			delete hooks.stop;
                +			stop( gotoEnd );
                +		};
                +
                +		if ( typeof type !== "string" ) {
                +			gotoEnd = clearQueue;
                +			clearQueue = type;
                +			type = undefined;
                +		}
                +		if ( clearQueue && type !== false ) {
                +			this.queue( type || "fx", [] );
                +		}
                +
                +		return this.each( function() {
                +			var dequeue = true,
                +				index = type != null && type + "queueHooks",
                +				timers = jQuery.timers,
                +				data = dataPriv.get( this );
                +
                +			if ( index ) {
                +				if ( data[ index ] && data[ index ].stop ) {
                +					stopQueue( data[ index ] );
                +				}
                +			} else {
                +				for ( index in data ) {
                +					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
                +						stopQueue( data[ index ] );
                +					}
                +				}
                +			}
                +
                +			for ( index = timers.length; index--; ) {
                +				if ( timers[ index ].elem === this &&
                +					( type == null || timers[ index ].queue === type ) ) {
                +
                +					timers[ index ].anim.stop( gotoEnd );
                +					dequeue = false;
                +					timers.splice( index, 1 );
                +				}
                +			}
                +
                +			// Start the next in the queue if the last step wasn't forced.
                +			// Timers currently will call their complete callbacks, which
                +			// will dequeue but only if they were gotoEnd.
                +			if ( dequeue || !gotoEnd ) {
                +				jQuery.dequeue( this, type );
                +			}
                +		} );
                +	},
                +	finish: function( type ) {
                +		if ( type !== false ) {
                +			type = type || "fx";
                +		}
                +		return this.each( function() {
                +			var index,
                +				data = dataPriv.get( this ),
                +				queue = data[ type + "queue" ],
                +				hooks = data[ type + "queueHooks" ],
                +				timers = jQuery.timers,
                +				length = queue ? queue.length : 0;
                +
                +			// Enable finishing flag on private data
                +			data.finish = true;
                +
                +			// Empty the queue first
                +			jQuery.queue( this, type, [] );
                +
                +			if ( hooks && hooks.stop ) {
                +				hooks.stop.call( this, true );
                +			}
                +
                +			// Look for any active animations, and finish them
                +			for ( index = timers.length; index--; ) {
                +				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
                +					timers[ index ].anim.stop( true );
                +					timers.splice( index, 1 );
                +				}
                +			}
                +
                +			// Look for any animations in the old queue and finish them
                +			for ( index = 0; index < length; index++ ) {
                +				if ( queue[ index ] && queue[ index ].finish ) {
                +					queue[ index ].finish.call( this );
                +				}
                +			}
                +
                +			// Turn off finishing flag
                +			delete data.finish;
                +		} );
                +	}
                +} );
                +
                +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
                +	var cssFn = jQuery.fn[ name ];
                +	jQuery.fn[ name ] = function( speed, easing, callback ) {
                +		return speed == null || typeof speed === "boolean" ?
                +			cssFn.apply( this, arguments ) :
                +			this.animate( genFx( name, true ), speed, easing, callback );
                +	};
                +} );
                +
                +// Generate shortcuts for custom animations
                +jQuery.each( {
                +	slideDown: genFx( "show" ),
                +	slideUp: genFx( "hide" ),
                +	slideToggle: genFx( "toggle" ),
                +	fadeIn: { opacity: "show" },
                +	fadeOut: { opacity: "hide" },
                +	fadeToggle: { opacity: "toggle" }
                +}, function( name, props ) {
                +	jQuery.fn[ name ] = function( speed, easing, callback ) {
                +		return this.animate( props, speed, easing, callback );
                +	};
                +} );
                +
                +jQuery.timers = [];
                +jQuery.fx.tick = function() {
                +	var timer,
                +		i = 0,
                +		timers = jQuery.timers;
                +
                +	fxNow = jQuery.now();
                +
                +	for ( ; i < timers.length; i++ ) {
                +		timer = timers[ i ];
                +
                +		// Run the timer and safely remove it when done (allowing for external removal)
                +		if ( !timer() && timers[ i ] === timer ) {
                +			timers.splice( i--, 1 );
                +		}
                +	}
                +
                +	if ( !timers.length ) {
                +		jQuery.fx.stop();
                +	}
                +	fxNow = undefined;
                +};
                +
                +jQuery.fx.timer = function( timer ) {
                +	jQuery.timers.push( timer );
                +	jQuery.fx.start();
                +};
                +
                +jQuery.fx.interval = 13;
                +jQuery.fx.start = function() {
                +	if ( inProgress ) {
                +		return;
                +	}
                +
                +	inProgress = true;
                +	schedule();
                +};
                +
                +jQuery.fx.stop = function() {
                +	inProgress = null;
                +};
                +
                +jQuery.fx.speeds = {
                +	slow: 600,
                +	fast: 200,
                +
                +	// Default speed
                +	_default: 400
                +};
                +
                +
                +// Based off of the plugin by Clint Helfers, with permission.
                +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
                +jQuery.fn.delay = function( time, type ) {
                +	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
                +	type = type || "fx";
                +
                +	return this.queue( type, function( next, hooks ) {
                +		var timeout = window.setTimeout( next, time );
                +		hooks.stop = function() {
                +			window.clearTimeout( timeout );
                +		};
                +	} );
                +};
                +
                +
                +( function() {
                +	var input = document.createElement( "input" ),
                +		select = document.createElement( "select" ),
                +		opt = select.appendChild( document.createElement( "option" ) );
                +
                +	input.type = "checkbox";
                +
                +	// Support: Android <=4.3 only
                +	// Default value for a checkbox should be "on"
                +	support.checkOn = input.value !== "";
                +
                +	// Support: IE <=11 only
                +	// Must access selectedIndex to make default options select
                +	support.optSelected = opt.selected;
                +
                +	// Support: IE <=11 only
                +	// An input loses its value after becoming a radio
                +	input = document.createElement( "input" );
                +	input.value = "t";
                +	input.type = "radio";
                +	support.radioValue = input.value === "t";
                +} )();
                +
                +
                +var boolHook,
                +	attrHandle = jQuery.expr.attrHandle;
                +
                +jQuery.fn.extend( {
                +	attr: function( name, value ) {
                +		return access( this, jQuery.attr, name, value, arguments.length > 1 );
                +	},
                +
                +	removeAttr: function( name ) {
                +		return this.each( function() {
                +			jQuery.removeAttr( this, name );
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	attr: function( elem, name, value ) {
                +		var ret, hooks,
                +			nType = elem.nodeType;
                +
                +		// Don't get/set attributes on text, comment and attribute nodes
                +		if ( nType === 3 || nType === 8 || nType === 2 ) {
                +			return;
                +		}
                +
                +		// Fallback to prop when attributes are not supported
                +		if ( typeof elem.getAttribute === "undefined" ) {
                +			return jQuery.prop( elem, name, value );
                +		}
                +
                +		// Attribute hooks are determined by the lowercase version
                +		// Grab necessary hook if one is defined
                +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
                +			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
                +				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
                +		}
                +
                +		if ( value !== undefined ) {
                +			if ( value === null ) {
                +				jQuery.removeAttr( elem, name );
                +				return;
                +			}
                +
                +			if ( hooks && "set" in hooks &&
                +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                +				return ret;
                +			}
                +
                +			elem.setAttribute( name, value + "" );
                +			return value;
                +		}
                +
                +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
                +			return ret;
                +		}
                +
                +		ret = jQuery.find.attr( elem, name );
                +
                +		// Non-existent attributes return null, we normalize to undefined
                +		return ret == null ? undefined : ret;
                +	},
                +
                +	attrHooks: {
                +		type: {
                +			set: function( elem, value ) {
                +				if ( !support.radioValue && value === "radio" &&
                +					nodeName( elem, "input" ) ) {
                +					var val = elem.value;
                +					elem.setAttribute( "type", value );
                +					if ( val ) {
                +						elem.value = val;
                +					}
                +					return value;
                +				}
                +			}
                +		}
                +	},
                +
                +	removeAttr: function( elem, value ) {
                +		var name,
                +			i = 0,
                +
                +			// Attribute names can contain non-HTML whitespace characters
                +			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
                +			attrNames = value && value.match( rnothtmlwhite );
                +
                +		if ( attrNames && elem.nodeType === 1 ) {
                +			while ( ( name = attrNames[ i++ ] ) ) {
                +				elem.removeAttribute( name );
                +			}
                +		}
                +	}
                +} );
                +
                +// Hooks for boolean attributes
                +boolHook = {
                +	set: function( elem, value, name ) {
                +		if ( value === false ) {
                +
                +			// Remove boolean attributes when set to false
                +			jQuery.removeAttr( elem, name );
                +		} else {
                +			elem.setAttribute( name, name );
                +		}
                +		return name;
                +	}
                +};
                +
                +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
                +	var getter = attrHandle[ name ] || jQuery.find.attr;
                +
                +	attrHandle[ name ] = function( elem, name, isXML ) {
                +		var ret, handle,
                +			lowercaseName = name.toLowerCase();
                +
                +		if ( !isXML ) {
                +
                +			// Avoid an infinite loop by temporarily removing this function from the getter
                +			handle = attrHandle[ lowercaseName ];
                +			attrHandle[ lowercaseName ] = ret;
                +			ret = getter( elem, name, isXML ) != null ?
                +				lowercaseName :
                +				null;
                +			attrHandle[ lowercaseName ] = handle;
                +		}
                +		return ret;
                +	};
                +} );
                +
                +
                +
                +
                +var rfocusable = /^(?:input|select|textarea|button)$/i,
                +	rclickable = /^(?:a|area)$/i;
                +
                +jQuery.fn.extend( {
                +	prop: function( name, value ) {
                +		return access( this, jQuery.prop, name, value, arguments.length > 1 );
                +	},
                +
                +	removeProp: function( name ) {
                +		return this.each( function() {
                +			delete this[ jQuery.propFix[ name ] || name ];
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	prop: function( elem, name, value ) {
                +		var ret, hooks,
                +			nType = elem.nodeType;
                +
                +		// Don't get/set properties on text, comment and attribute nodes
                +		if ( nType === 3 || nType === 8 || nType === 2 ) {
                +			return;
                +		}
                +
                +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
                +
                +			// Fix name and attach hooks
                +			name = jQuery.propFix[ name ] || name;
                +			hooks = jQuery.propHooks[ name ];
                +		}
                +
                +		if ( value !== undefined ) {
                +			if ( hooks && "set" in hooks &&
                +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                +				return ret;
                +			}
                +
                +			return ( elem[ name ] = value );
                +		}
                +
                +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
                +			return ret;
                +		}
                +
                +		return elem[ name ];
                +	},
                +
                +	propHooks: {
                +		tabIndex: {
                +			get: function( elem ) {
                +
                +				// Support: IE <=9 - 11 only
                +				// elem.tabIndex doesn't always return the
                +				// correct value when it hasn't been explicitly set
                +				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
                +				// Use proper attribute retrieval(#12072)
                +				var tabindex = jQuery.find.attr( elem, "tabindex" );
                +
                +				if ( tabindex ) {
                +					return parseInt( tabindex, 10 );
                +				}
                +
                +				if (
                +					rfocusable.test( elem.nodeName ) ||
                +					rclickable.test( elem.nodeName ) &&
                +					elem.href
                +				) {
                +					return 0;
                +				}
                +
                +				return -1;
                +			}
                +		}
                +	},
                +
                +	propFix: {
                +		"for": "htmlFor",
                +		"class": "className"
                +	}
                +} );
                +
                +// Support: IE <=11 only
                +// Accessing the selectedIndex property
                +// forces the browser to respect setting selected
                +// on the option
                +// The getter ensures a default option is selected
                +// when in an optgroup
                +// eslint rule "no-unused-expressions" is disabled for this code
                +// since it considers such accessions noop
                +if ( !support.optSelected ) {
                +	jQuery.propHooks.selected = {
                +		get: function( elem ) {
                +
                +			/* eslint no-unused-expressions: "off" */
                +
                +			var parent = elem.parentNode;
                +			if ( parent && parent.parentNode ) {
                +				parent.parentNode.selectedIndex;
                +			}
                +			return null;
                +		},
                +		set: function( elem ) {
                +
                +			/* eslint no-unused-expressions: "off" */
                +
                +			var parent = elem.parentNode;
                +			if ( parent ) {
                +				parent.selectedIndex;
                +
                +				if ( parent.parentNode ) {
                +					parent.parentNode.selectedIndex;
                +				}
                +			}
                +		}
                +	};
                +}
                +
                +jQuery.each( [
                +	"tabIndex",
                +	"readOnly",
                +	"maxLength",
                +	"cellSpacing",
                +	"cellPadding",
                +	"rowSpan",
                +	"colSpan",
                +	"useMap",
                +	"frameBorder",
                +	"contentEditable"
                +], function() {
                +	jQuery.propFix[ this.toLowerCase() ] = this;
                +} );
                +
                +
                +
                +
                +	// Strip and collapse whitespace according to HTML spec
                +	// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
                +	function stripAndCollapse( value ) {
                +		var tokens = value.match( rnothtmlwhite ) || [];
                +		return tokens.join( " " );
                +	}
                +
                +
                +function getClass( elem ) {
                +	return elem.getAttribute && elem.getAttribute( "class" ) || "";
                +}
                +
                +jQuery.fn.extend( {
                +	addClass: function( value ) {
                +		var classes, elem, cur, curValue, clazz, j, finalValue,
                +			i = 0;
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( j ) {
                +				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
                +			} );
                +		}
                +
                +		if ( typeof value === "string" && value ) {
                +			classes = value.match( rnothtmlwhite ) || [];
                +
                +			while ( ( elem = this[ i++ ] ) ) {
                +				curValue = getClass( elem );
                +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
                +
                +				if ( cur ) {
                +					j = 0;
                +					while ( ( clazz = classes[ j++ ] ) ) {
                +						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
                +							cur += clazz + " ";
                +						}
                +					}
                +
                +					// Only assign if different to avoid unneeded rendering.
                +					finalValue = stripAndCollapse( cur );
                +					if ( curValue !== finalValue ) {
                +						elem.setAttribute( "class", finalValue );
                +					}
                +				}
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	removeClass: function( value ) {
                +		var classes, elem, cur, curValue, clazz, j, finalValue,
                +			i = 0;
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( j ) {
                +				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
                +			} );
                +		}
                +
                +		if ( !arguments.length ) {
                +			return this.attr( "class", "" );
                +		}
                +
                +		if ( typeof value === "string" && value ) {
                +			classes = value.match( rnothtmlwhite ) || [];
                +
                +			while ( ( elem = this[ i++ ] ) ) {
                +				curValue = getClass( elem );
                +
                +				// This expression is here for better compressibility (see addClass)
                +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
                +
                +				if ( cur ) {
                +					j = 0;
                +					while ( ( clazz = classes[ j++ ] ) ) {
                +
                +						// Remove *all* instances
                +						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
                +							cur = cur.replace( " " + clazz + " ", " " );
                +						}
                +					}
                +
                +					// Only assign if different to avoid unneeded rendering.
                +					finalValue = stripAndCollapse( cur );
                +					if ( curValue !== finalValue ) {
                +						elem.setAttribute( "class", finalValue );
                +					}
                +				}
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	toggleClass: function( value, stateVal ) {
                +		var type = typeof value;
                +
                +		if ( typeof stateVal === "boolean" && type === "string" ) {
                +			return stateVal ? this.addClass( value ) : this.removeClass( value );
                +		}
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( i ) {
                +				jQuery( this ).toggleClass(
                +					value.call( this, i, getClass( this ), stateVal ),
                +					stateVal
                +				);
                +			} );
                +		}
                +
                +		return this.each( function() {
                +			var className, i, self, classNames;
                +
                +			if ( type === "string" ) {
                +
                +				// Toggle individual class names
                +				i = 0;
                +				self = jQuery( this );
                +				classNames = value.match( rnothtmlwhite ) || [];
                +
                +				while ( ( className = classNames[ i++ ] ) ) {
                +
                +					// Check each className given, space separated list
                +					if ( self.hasClass( className ) ) {
                +						self.removeClass( className );
                +					} else {
                +						self.addClass( className );
                +					}
                +				}
                +
                +			// Toggle whole class name
                +			} else if ( value === undefined || type === "boolean" ) {
                +				className = getClass( this );
                +				if ( className ) {
                +
                +					// Store className if set
                +					dataPriv.set( this, "__className__", className );
                +				}
                +
                +				// If the element has a class name or if we're passed `false`,
                +				// then remove the whole classname (if there was one, the above saved it).
                +				// Otherwise bring back whatever was previously saved (if anything),
                +				// falling back to the empty string if nothing was stored.
                +				if ( this.setAttribute ) {
                +					this.setAttribute( "class",
                +						className || value === false ?
                +						"" :
                +						dataPriv.get( this, "__className__" ) || ""
                +					);
                +				}
                +			}
                +		} );
                +	},
                +
                +	hasClass: function( selector ) {
                +		var className, elem,
                +			i = 0;
                +
                +		className = " " + selector + " ";
                +		while ( ( elem = this[ i++ ] ) ) {
                +			if ( elem.nodeType === 1 &&
                +				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
                +					return true;
                +			}
                +		}
                +
                +		return false;
                +	}
                +} );
                +
                +
                +
                +
                +var rreturn = /\r/g;
                +
                +jQuery.fn.extend( {
                +	val: function( value ) {
                +		var hooks, ret, isFunction,
                +			elem = this[ 0 ];
                +
                +		if ( !arguments.length ) {
                +			if ( elem ) {
                +				hooks = jQuery.valHooks[ elem.type ] ||
                +					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
                +
                +				if ( hooks &&
                +					"get" in hooks &&
                +					( ret = hooks.get( elem, "value" ) ) !== undefined
                +				) {
                +					return ret;
                +				}
                +
                +				ret = elem.value;
                +
                +				// Handle most common string cases
                +				if ( typeof ret === "string" ) {
                +					return ret.replace( rreturn, "" );
                +				}
                +
                +				// Handle cases where value is null/undef or number
                +				return ret == null ? "" : ret;
                +			}
                +
                +			return;
                +		}
                +
                +		isFunction = jQuery.isFunction( value );
                +
                +		return this.each( function( i ) {
                +			var val;
                +
                +			if ( this.nodeType !== 1 ) {
                +				return;
                +			}
                +
                +			if ( isFunction ) {
                +				val = value.call( this, i, jQuery( this ).val() );
                +			} else {
                +				val = value;
                +			}
                +
                +			// Treat null/undefined as ""; convert numbers to string
                +			if ( val == null ) {
                +				val = "";
                +
                +			} else if ( typeof val === "number" ) {
                +				val += "";
                +
                +			} else if ( Array.isArray( val ) ) {
                +				val = jQuery.map( val, function( value ) {
                +					return value == null ? "" : value + "";
                +				} );
                +			}
                +
                +			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
                +
                +			// If set returns undefined, fall back to normal setting
                +			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
                +				this.value = val;
                +			}
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	valHooks: {
                +		option: {
                +			get: function( elem ) {
                +
                +				var val = jQuery.find.attr( elem, "value" );
                +				return val != null ?
                +					val :
                +
                +					// Support: IE <=10 - 11 only
                +					// option.text throws exceptions (#14686, #14858)
                +					// Strip and collapse whitespace
                +					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
                +					stripAndCollapse( jQuery.text( elem ) );
                +			}
                +		},
                +		select: {
                +			get: function( elem ) {
                +				var value, option, i,
                +					options = elem.options,
                +					index = elem.selectedIndex,
                +					one = elem.type === "select-one",
                +					values = one ? null : [],
                +					max = one ? index + 1 : options.length;
                +
                +				if ( index < 0 ) {
                +					i = max;
                +
                +				} else {
                +					i = one ? index : 0;
                +				}
                +
                +				// Loop through all the selected options
                +				for ( ; i < max; i++ ) {
                +					option = options[ i ];
                +
                +					// Support: IE <=9 only
                +					// IE8-9 doesn't update selected after form reset (#2551)
                +					if ( ( option.selected || i === index ) &&
                +
                +							// Don't return options that are disabled or in a disabled optgroup
                +							!option.disabled &&
                +							( !option.parentNode.disabled ||
                +								!nodeName( option.parentNode, "optgroup" ) ) ) {
                +
                +						// Get the specific value for the option
                +						value = jQuery( option ).val();
                +
                +						// We don't need an array for one selects
                +						if ( one ) {
                +							return value;
                +						}
                +
                +						// Multi-Selects return an array
                +						values.push( value );
                +					}
                +				}
                +
                +				return values;
                +			},
                +
                +			set: function( elem, value ) {
                +				var optionSet, option,
                +					options = elem.options,
                +					values = jQuery.makeArray( value ),
                +					i = options.length;
                +
                +				while ( i-- ) {
                +					option = options[ i ];
                +
                +					/* eslint-disable no-cond-assign */
                +
                +					if ( option.selected =
                +						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
                +					) {
                +						optionSet = true;
                +					}
                +
                +					/* eslint-enable no-cond-assign */
                +				}
                +
                +				// Force browsers to behave consistently when non-matching value is set
                +				if ( !optionSet ) {
                +					elem.selectedIndex = -1;
                +				}
                +				return values;
                +			}
                +		}
                +	}
                +} );
                +
                +// Radios and checkboxes getter/setter
                +jQuery.each( [ "radio", "checkbox" ], function() {
                +	jQuery.valHooks[ this ] = {
                +		set: function( elem, value ) {
                +			if ( Array.isArray( value ) ) {
                +				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
                +			}
                +		}
                +	};
                +	if ( !support.checkOn ) {
                +		jQuery.valHooks[ this ].get = function( elem ) {
                +			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +// Return jQuery for attributes-only inclusion
                +
                +
                +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
                +
                +jQuery.extend( jQuery.event, {
                +
                +	trigger: function( event, data, elem, onlyHandlers ) {
                +
                +		var i, cur, tmp, bubbleType, ontype, handle, special,
                +			eventPath = [ elem || document ],
                +			type = hasOwn.call( event, "type" ) ? event.type : event,
                +			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
                +
                +		cur = tmp = elem = elem || document;
                +
                +		// Don't do events on text and comment nodes
                +		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
                +			return;
                +		}
                +
                +		// focus/blur morphs to focusin/out; ensure we're not firing them right now
                +		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
                +			return;
                +		}
                +
                +		if ( type.indexOf( "." ) > -1 ) {
                +
                +			// Namespaced trigger; create a regexp to match event type in handle()
                +			namespaces = type.split( "." );
                +			type = namespaces.shift();
                +			namespaces.sort();
                +		}
                +		ontype = type.indexOf( ":" ) < 0 && "on" + type;
                +
                +		// Caller can pass in a jQuery.Event object, Object, or just an event type string
                +		event = event[ jQuery.expando ] ?
                +			event :
                +			new jQuery.Event( type, typeof event === "object" && event );
                +
                +		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
                +		event.isTrigger = onlyHandlers ? 2 : 3;
                +		event.namespace = namespaces.join( "." );
                +		event.rnamespace = event.namespace ?
                +			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
                +			null;
                +
                +		// Clean up the event in case it is being reused
                +		event.result = undefined;
                +		if ( !event.target ) {
                +			event.target = elem;
                +		}
                +
                +		// Clone any incoming data and prepend the event, creating the handler arg list
                +		data = data == null ?
                +			[ event ] :
                +			jQuery.makeArray( data, [ event ] );
                +
                +		// Allow special events to draw outside the lines
                +		special = jQuery.event.special[ type ] || {};
                +		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
                +			return;
                +		}
                +
                +		// Determine event propagation path in advance, per W3C events spec (#9951)
                +		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
                +		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
                +
                +			bubbleType = special.delegateType || type;
                +			if ( !rfocusMorph.test( bubbleType + type ) ) {
                +				cur = cur.parentNode;
                +			}
                +			for ( ; cur; cur = cur.parentNode ) {
                +				eventPath.push( cur );
                +				tmp = cur;
                +			}
                +
                +			// Only add window if we got to document (e.g., not plain obj or detached DOM)
                +			if ( tmp === ( elem.ownerDocument || document ) ) {
                +				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
                +			}
                +		}
                +
                +		// Fire handlers on the event path
                +		i = 0;
                +		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
                +
                +			event.type = i > 1 ?
                +				bubbleType :
                +				special.bindType || type;
                +
                +			// jQuery handler
                +			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
                +				dataPriv.get( cur, "handle" );
                +			if ( handle ) {
                +				handle.apply( cur, data );
                +			}
                +
                +			// Native handler
                +			handle = ontype && cur[ ontype ];
                +			if ( handle && handle.apply && acceptData( cur ) ) {
                +				event.result = handle.apply( cur, data );
                +				if ( event.result === false ) {
                +					event.preventDefault();
                +				}
                +			}
                +		}
                +		event.type = type;
                +
                +		// If nobody prevented the default action, do it now
                +		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
                +
                +			if ( ( !special._default ||
                +				special._default.apply( eventPath.pop(), data ) === false ) &&
                +				acceptData( elem ) ) {
                +
                +				// Call a native DOM method on the target with the same name as the event.
                +				// Don't do default actions on window, that's where global variables be (#6170)
                +				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
                +
                +					// Don't re-trigger an onFOO event when we call its FOO() method
                +					tmp = elem[ ontype ];
                +
                +					if ( tmp ) {
                +						elem[ ontype ] = null;
                +					}
                +
                +					// Prevent re-triggering of the same event, since we already bubbled it above
                +					jQuery.event.triggered = type;
                +					elem[ type ]();
                +					jQuery.event.triggered = undefined;
                +
                +					if ( tmp ) {
                +						elem[ ontype ] = tmp;
                +					}
                +				}
                +			}
                +		}
                +
                +		return event.result;
                +	},
                +
                +	// Piggyback on a donor event to simulate a different one
                +	// Used only for `focus(in | out)` events
                +	simulate: function( type, elem, event ) {
                +		var e = jQuery.extend(
                +			new jQuery.Event(),
                +			event,
                +			{
                +				type: type,
                +				isSimulated: true
                +			}
                +		);
                +
                +		jQuery.event.trigger( e, null, elem );
                +	}
                +
                +} );
                +
                +jQuery.fn.extend( {
                +
                +	trigger: function( type, data ) {
                +		return this.each( function() {
                +			jQuery.event.trigger( type, data, this );
                +		} );
                +	},
                +	triggerHandler: function( type, data ) {
                +		var elem = this[ 0 ];
                +		if ( elem ) {
                +			return jQuery.event.trigger( type, data, elem, true );
                +		}
                +	}
                +} );
                +
                +
                +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
                +	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
                +	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
                +	function( i, name ) {
                +
                +	// Handle event binding
                +	jQuery.fn[ name ] = function( data, fn ) {
                +		return arguments.length > 0 ?
                +			this.on( name, null, data, fn ) :
                +			this.trigger( name );
                +	};
                +} );
                +
                +jQuery.fn.extend( {
                +	hover: function( fnOver, fnOut ) {
                +		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
                +	}
                +} );
                +
                +
                +
                +
                +support.focusin = "onfocusin" in window;
                +
                +
                +// Support: Firefox <=44
                +// Firefox doesn't have focus(in | out) events
                +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
                +//
                +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
                +// focus(in | out) events fire after focus & blur events,
                +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
                +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
                +if ( !support.focusin ) {
                +	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
                +
                +		// Attach a single capturing handler on the document while someone wants focusin/focusout
                +		var handler = function( event ) {
                +			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
                +		};
                +
                +		jQuery.event.special[ fix ] = {
                +			setup: function() {
                +				var doc = this.ownerDocument || this,
                +					attaches = dataPriv.access( doc, fix );
                +
                +				if ( !attaches ) {
                +					doc.addEventListener( orig, handler, true );
                +				}
                +				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
                +			},
                +			teardown: function() {
                +				var doc = this.ownerDocument || this,
                +					attaches = dataPriv.access( doc, fix ) - 1;
                +
                +				if ( !attaches ) {
                +					doc.removeEventListener( orig, handler, true );
                +					dataPriv.remove( doc, fix );
                +
                +				} else {
                +					dataPriv.access( doc, fix, attaches );
                +				}
                +			}
                +		};
                +	} );
                +}
                +var location = window.location;
                +
                +var nonce = jQuery.now();
                +
                +var rquery = ( /\?/ );
                +
                +
                +
                +// Cross-browser xml parsing
                +jQuery.parseXML = function( data ) {
                +	var xml;
                +	if ( !data || typeof data !== "string" ) {
                +		return null;
                +	}
                +
                +	// Support: IE 9 - 11 only
                +	// IE throws on parseFromString with invalid input.
                +	try {
                +		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
                +	} catch ( e ) {
                +		xml = undefined;
                +	}
                +
                +	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
                +		jQuery.error( "Invalid XML: " + data );
                +	}
                +	return xml;
                +};
                +
                +
                +var
                +	rbracket = /\[\]$/,
                +	rCRLF = /\r?\n/g,
                +	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
                +	rsubmittable = /^(?:input|select|textarea|keygen)/i;
                +
                +function buildParams( prefix, obj, traditional, add ) {
                +	var name;
                +
                +	if ( Array.isArray( obj ) ) {
                +
                +		// Serialize array item.
                +		jQuery.each( obj, function( i, v ) {
                +			if ( traditional || rbracket.test( prefix ) ) {
                +
                +				// Treat each array item as a scalar.
                +				add( prefix, v );
                +
                +			} else {
                +
                +				// Item is non-scalar (array or object), encode its numeric index.
                +				buildParams(
                +					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
                +					v,
                +					traditional,
                +					add
                +				);
                +			}
                +		} );
                +
                +	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
                +
                +		// Serialize object item.
                +		for ( name in obj ) {
                +			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
                +		}
                +
                +	} else {
                +
                +		// Serialize scalar item.
                +		add( prefix, obj );
                +	}
                +}
                +
                +// Serialize an array of form elements or a set of
                +// key/values into a query string
                +jQuery.param = function( a, traditional ) {
                +	var prefix,
                +		s = [],
                +		add = function( key, valueOrFunction ) {
                +
                +			// If value is a function, invoke it and use its return value
                +			var value = jQuery.isFunction( valueOrFunction ) ?
                +				valueOrFunction() :
                +				valueOrFunction;
                +
                +			s[ s.length ] = encodeURIComponent( key ) + "=" +
                +				encodeURIComponent( value == null ? "" : value );
                +		};
                +
                +	// If an array was passed in, assume that it is an array of form elements.
                +	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                +
                +		// Serialize the form elements
                +		jQuery.each( a, function() {
                +			add( this.name, this.value );
                +		} );
                +
                +	} else {
                +
                +		// If traditional, encode the "old" way (the way 1.3.2 or older
                +		// did it), otherwise encode params recursively.
                +		for ( prefix in a ) {
                +			buildParams( prefix, a[ prefix ], traditional, add );
                +		}
                +	}
                +
                +	// Return the resulting serialization
                +	return s.join( "&" );
                +};
                +
                +jQuery.fn.extend( {
                +	serialize: function() {
                +		return jQuery.param( this.serializeArray() );
                +	},
                +	serializeArray: function() {
                +		return this.map( function() {
                +
                +			// Can add propHook for "elements" to filter or add form elements
                +			var elements = jQuery.prop( this, "elements" );
                +			return elements ? jQuery.makeArray( elements ) : this;
                +		} )
                +		.filter( function() {
                +			var type = this.type;
                +
                +			// Use .is( ":disabled" ) so that fieldset[disabled] works
                +			return this.name && !jQuery( this ).is( ":disabled" ) &&
                +				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
                +				( this.checked || !rcheckableType.test( type ) );
                +		} )
                +		.map( function( i, elem ) {
                +			var val = jQuery( this ).val();
                +
                +			if ( val == null ) {
                +				return null;
                +			}
                +
                +			if ( Array.isArray( val ) ) {
                +				return jQuery.map( val, function( val ) {
                +					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                +				} );
                +			}
                +
                +			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                +		} ).get();
                +	}
                +} );
                +
                +
                +var
                +	r20 = /%20/g,
                +	rhash = /#.*$/,
                +	rantiCache = /([?&])_=[^&]*/,
                +	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
                +
                +	// #7653, #8125, #8152: local protocol detection
                +	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
                +	rnoContent = /^(?:GET|HEAD)$/,
                +	rprotocol = /^\/\//,
                +
                +	/* Prefilters
                +	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
                +	 * 2) These are called:
                +	 *    - BEFORE asking for a transport
                +	 *    - AFTER param serialization (s.data is a string if s.processData is true)
                +	 * 3) key is the dataType
                +	 * 4) the catchall symbol "*" can be used
                +	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
                +	 */
                +	prefilters = {},
                +
                +	/* Transports bindings
                +	 * 1) key is the dataType
                +	 * 2) the catchall symbol "*" can be used
                +	 * 3) selection will start with transport dataType and THEN go to "*" if needed
                +	 */
                +	transports = {},
                +
                +	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
                +	allTypes = "*/".concat( "*" ),
                +
                +	// Anchor tag for parsing the document origin
                +	originAnchor = document.createElement( "a" );
                +	originAnchor.href = location.href;
                +
                +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
                +function addToPrefiltersOrTransports( structure ) {
                +
                +	// dataTypeExpression is optional and defaults to "*"
                +	return function( dataTypeExpression, func ) {
                +
                +		if ( typeof dataTypeExpression !== "string" ) {
                +			func = dataTypeExpression;
                +			dataTypeExpression = "*";
                +		}
                +
                +		var dataType,
                +			i = 0,
                +			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
                +
                +		if ( jQuery.isFunction( func ) ) {
                +
                +			// For each dataType in the dataTypeExpression
                +			while ( ( dataType = dataTypes[ i++ ] ) ) {
                +
                +				// Prepend if requested
                +				if ( dataType[ 0 ] === "+" ) {
                +					dataType = dataType.slice( 1 ) || "*";
                +					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
                +
                +				// Otherwise append
                +				} else {
                +					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
                +				}
                +			}
                +		}
                +	};
                +}
                +
                +// Base inspection function for prefilters and transports
                +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
                +
                +	var inspected = {},
                +		seekingTransport = ( structure === transports );
                +
                +	function inspect( dataType ) {
                +		var selected;
                +		inspected[ dataType ] = true;
                +		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
                +			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
                +			if ( typeof dataTypeOrTransport === "string" &&
                +				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
                +
                +				options.dataTypes.unshift( dataTypeOrTransport );
                +				inspect( dataTypeOrTransport );
                +				return false;
                +			} else if ( seekingTransport ) {
                +				return !( selected = dataTypeOrTransport );
                +			}
                +		} );
                +		return selected;
                +	}
                +
                +	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
                +}
                +
                +// A special extend for ajax options
                +// that takes "flat" options (not to be deep extended)
                +// Fixes #9887
                +function ajaxExtend( target, src ) {
                +	var key, deep,
                +		flatOptions = jQuery.ajaxSettings.flatOptions || {};
                +
                +	for ( key in src ) {
                +		if ( src[ key ] !== undefined ) {
                +			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
                +		}
                +	}
                +	if ( deep ) {
                +		jQuery.extend( true, target, deep );
                +	}
                +
                +	return target;
                +}
                +
                +/* Handles responses to an ajax request:
                + * - finds the right dataType (mediates between content-type and expected dataType)
                + * - returns the corresponding response
                + */
                +function ajaxHandleResponses( s, jqXHR, responses ) {
                +
                +	var ct, type, finalDataType, firstDataType,
                +		contents = s.contents,
                +		dataTypes = s.dataTypes;
                +
                +	// Remove auto dataType and get content-type in the process
                +	while ( dataTypes[ 0 ] === "*" ) {
                +		dataTypes.shift();
                +		if ( ct === undefined ) {
                +			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
                +		}
                +	}
                +
                +	// Check if we're dealing with a known content-type
                +	if ( ct ) {
                +		for ( type in contents ) {
                +			if ( contents[ type ] && contents[ type ].test( ct ) ) {
                +				dataTypes.unshift( type );
                +				break;
                +			}
                +		}
                +	}
                +
                +	// Check to see if we have a response for the expected dataType
                +	if ( dataTypes[ 0 ] in responses ) {
                +		finalDataType = dataTypes[ 0 ];
                +	} else {
                +
                +		// Try convertible dataTypes
                +		for ( type in responses ) {
                +			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
                +				finalDataType = type;
                +				break;
                +			}
                +			if ( !firstDataType ) {
                +				firstDataType = type;
                +			}
                +		}
                +
                +		// Or just use first one
                +		finalDataType = finalDataType || firstDataType;
                +	}
                +
                +	// If we found a dataType
                +	// We add the dataType to the list if needed
                +	// and return the corresponding response
                +	if ( finalDataType ) {
                +		if ( finalDataType !== dataTypes[ 0 ] ) {
                +			dataTypes.unshift( finalDataType );
                +		}
                +		return responses[ finalDataType ];
                +	}
                +}
                +
                +/* Chain conversions given the request and the original response
                + * Also sets the responseXXX fields on the jqXHR instance
                + */
                +function ajaxConvert( s, response, jqXHR, isSuccess ) {
                +	var conv2, current, conv, tmp, prev,
                +		converters = {},
                +
                +		// Work with a copy of dataTypes in case we need to modify it for conversion
                +		dataTypes = s.dataTypes.slice();
                +
                +	// Create converters map with lowercased keys
                +	if ( dataTypes[ 1 ] ) {
                +		for ( conv in s.converters ) {
                +			converters[ conv.toLowerCase() ] = s.converters[ conv ];
                +		}
                +	}
                +
                +	current = dataTypes.shift();
                +
                +	// Convert to each sequential dataType
                +	while ( current ) {
                +
                +		if ( s.responseFields[ current ] ) {
                +			jqXHR[ s.responseFields[ current ] ] = response;
                +		}
                +
                +		// Apply the dataFilter if provided
                +		if ( !prev && isSuccess && s.dataFilter ) {
                +			response = s.dataFilter( response, s.dataType );
                +		}
                +
                +		prev = current;
                +		current = dataTypes.shift();
                +
                +		if ( current ) {
                +
                +			// There's only work to do if current dataType is non-auto
                +			if ( current === "*" ) {
                +
                +				current = prev;
                +
                +			// Convert response if prev dataType is non-auto and differs from current
                +			} else if ( prev !== "*" && prev !== current ) {
                +
                +				// Seek a direct converter
                +				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
                +
                +				// If none found, seek a pair
                +				if ( !conv ) {
                +					for ( conv2 in converters ) {
                +
                +						// If conv2 outputs current
                +						tmp = conv2.split( " " );
                +						if ( tmp[ 1 ] === current ) {
                +
                +							// If prev can be converted to accepted input
                +							conv = converters[ prev + " " + tmp[ 0 ] ] ||
                +								converters[ "* " + tmp[ 0 ] ];
                +							if ( conv ) {
                +
                +								// Condense equivalence converters
                +								if ( conv === true ) {
                +									conv = converters[ conv2 ];
                +
                +								// Otherwise, insert the intermediate dataType
                +								} else if ( converters[ conv2 ] !== true ) {
                +									current = tmp[ 0 ];
                +									dataTypes.unshift( tmp[ 1 ] );
                +								}
                +								break;
                +							}
                +						}
                +					}
                +				}
                +
                +				// Apply converter (if not an equivalence)
                +				if ( conv !== true ) {
                +
                +					// Unless errors are allowed to bubble, catch and return them
                +					if ( conv && s.throws ) {
                +						response = conv( response );
                +					} else {
                +						try {
                +							response = conv( response );
                +						} catch ( e ) {
                +							return {
                +								state: "parsererror",
                +								error: conv ? e : "No conversion from " + prev + " to " + current
                +							};
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	return { state: "success", data: response };
                +}
                +
                +jQuery.extend( {
                +
                +	// Counter for holding the number of active queries
                +	active: 0,
                +
                +	// Last-Modified header cache for next request
                +	lastModified: {},
                +	etag: {},
                +
                +	ajaxSettings: {
                +		url: location.href,
                +		type: "GET",
                +		isLocal: rlocalProtocol.test( location.protocol ),
                +		global: true,
                +		processData: true,
                +		async: true,
                +		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                +
                +		/*
                +		timeout: 0,
                +		data: null,
                +		dataType: null,
                +		username: null,
                +		password: null,
                +		cache: null,
                +		throws: false,
                +		traditional: false,
                +		headers: {},
                +		*/
                +
                +		accepts: {
                +			"*": allTypes,
                +			text: "text/plain",
                +			html: "text/html",
                +			xml: "application/xml, text/xml",
                +			json: "application/json, text/javascript"
                +		},
                +
                +		contents: {
                +			xml: /\bxml\b/,
                +			html: /\bhtml/,
                +			json: /\bjson\b/
                +		},
                +
                +		responseFields: {
                +			xml: "responseXML",
                +			text: "responseText",
                +			json: "responseJSON"
                +		},
                +
                +		// Data converters
                +		// Keys separate source (or catchall "*") and destination types with a single space
                +		converters: {
                +
                +			// Convert anything to text
                +			"* text": String,
                +
                +			// Text to html (true = no transformation)
                +			"text html": true,
                +
                +			// Evaluate text as a json expression
                +			"text json": JSON.parse,
                +
                +			// Parse text as xml
                +			"text xml": jQuery.parseXML
                +		},
                +
                +		// For options that shouldn't be deep extended:
                +		// you can add your own custom options here if
                +		// and when you create one that shouldn't be
                +		// deep extended (see ajaxExtend)
                +		flatOptions: {
                +			url: true,
                +			context: true
                +		}
                +	},
                +
                +	// Creates a full fledged settings object into target
                +	// with both ajaxSettings and settings fields.
                +	// If target is omitted, writes into ajaxSettings.
                +	ajaxSetup: function( target, settings ) {
                +		return settings ?
                +
                +			// Building a settings object
                +			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
                +
                +			// Extending ajaxSettings
                +			ajaxExtend( jQuery.ajaxSettings, target );
                +	},
                +
                +	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
                +	ajaxTransport: addToPrefiltersOrTransports( transports ),
                +
                +	// Main method
                +	ajax: function( url, options ) {
                +
                +		// If url is an object, simulate pre-1.5 signature
                +		if ( typeof url === "object" ) {
                +			options = url;
                +			url = undefined;
                +		}
                +
                +		// Force options to be an object
                +		options = options || {};
                +
                +		var transport,
                +
                +			// URL without anti-cache param
                +			cacheURL,
                +
                +			// Response headers
                +			responseHeadersString,
                +			responseHeaders,
                +
                +			// timeout handle
                +			timeoutTimer,
                +
                +			// Url cleanup var
                +			urlAnchor,
                +
                +			// Request state (becomes false upon send and true upon completion)
                +			completed,
                +
                +			// To know if global events are to be dispatched
                +			fireGlobals,
                +
                +			// Loop variable
                +			i,
                +
                +			// uncached part of the url
                +			uncached,
                +
                +			// Create the final options object
                +			s = jQuery.ajaxSetup( {}, options ),
                +
                +			// Callbacks context
                +			callbackContext = s.context || s,
                +
                +			// Context for global events is callbackContext if it is a DOM node or jQuery collection
                +			globalEventContext = s.context &&
                +				( callbackContext.nodeType || callbackContext.jquery ) ?
                +					jQuery( callbackContext ) :
                +					jQuery.event,
                +
                +			// Deferreds
                +			deferred = jQuery.Deferred(),
                +			completeDeferred = jQuery.Callbacks( "once memory" ),
                +
                +			// Status-dependent callbacks
                +			statusCode = s.statusCode || {},
                +
                +			// Headers (they are sent all at once)
                +			requestHeaders = {},
                +			requestHeadersNames = {},
                +
                +			// Default abort message
                +			strAbort = "canceled",
                +
                +			// Fake xhr
                +			jqXHR = {
                +				readyState: 0,
                +
                +				// Builds headers hashtable if needed
                +				getResponseHeader: function( key ) {
                +					var match;
                +					if ( completed ) {
                +						if ( !responseHeaders ) {
                +							responseHeaders = {};
                +							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
                +								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
                +							}
                +						}
                +						match = responseHeaders[ key.toLowerCase() ];
                +					}
                +					return match == null ? null : match;
                +				},
                +
                +				// Raw string
                +				getAllResponseHeaders: function() {
                +					return completed ? responseHeadersString : null;
                +				},
                +
                +				// Caches the header
                +				setRequestHeader: function( name, value ) {
                +					if ( completed == null ) {
                +						name = requestHeadersNames[ name.toLowerCase() ] =
                +							requestHeadersNames[ name.toLowerCase() ] || name;
                +						requestHeaders[ name ] = value;
                +					}
                +					return this;
                +				},
                +
                +				// Overrides response content-type header
                +				overrideMimeType: function( type ) {
                +					if ( completed == null ) {
                +						s.mimeType = type;
                +					}
                +					return this;
                +				},
                +
                +				// Status-dependent callbacks
                +				statusCode: function( map ) {
                +					var code;
                +					if ( map ) {
                +						if ( completed ) {
                +
                +							// Execute the appropriate callbacks
                +							jqXHR.always( map[ jqXHR.status ] );
                +						} else {
                +
                +							// Lazy-add the new callbacks in a way that preserves old ones
                +							for ( code in map ) {
                +								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
                +							}
                +						}
                +					}
                +					return this;
                +				},
                +
                +				// Cancel the request
                +				abort: function( statusText ) {
                +					var finalText = statusText || strAbort;
                +					if ( transport ) {
                +						transport.abort( finalText );
                +					}
                +					done( 0, finalText );
                +					return this;
                +				}
                +			};
                +
                +		// Attach deferreds
                +		deferred.promise( jqXHR );
                +
                +		// Add protocol if not provided (prefilters might expect it)
                +		// Handle falsy url in the settings object (#10093: consistency with old signature)
                +		// We also use the url parameter if available
                +		s.url = ( ( url || s.url || location.href ) + "" )
                +			.replace( rprotocol, location.protocol + "//" );
                +
                +		// Alias method option to type as per ticket #12004
                +		s.type = options.method || options.type || s.method || s.type;
                +
                +		// Extract dataTypes list
                +		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
                +
                +		// A cross-domain request is in order when the origin doesn't match the current origin.
                +		if ( s.crossDomain == null ) {
                +			urlAnchor = document.createElement( "a" );
                +
                +			// Support: IE <=8 - 11, Edge 12 - 13
                +			// IE throws exception on accessing the href property if url is malformed,
                +			// e.g. http://example.com:80x/
                +			try {
                +				urlAnchor.href = s.url;
                +
                +				// Support: IE <=8 - 11 only
                +				// Anchor's host property isn't correctly set when s.url is relative
                +				urlAnchor.href = urlAnchor.href;
                +				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
                +					urlAnchor.protocol + "//" + urlAnchor.host;
                +			} catch ( e ) {
                +
                +				// If there is an error parsing the URL, assume it is crossDomain,
                +				// it can be rejected by the transport if it is invalid
                +				s.crossDomain = true;
                +			}
                +		}
                +
                +		// Convert data if not already a string
                +		if ( s.data && s.processData && typeof s.data !== "string" ) {
                +			s.data = jQuery.param( s.data, s.traditional );
                +		}
                +
                +		// Apply prefilters
                +		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
                +
                +		// If request was aborted inside a prefilter, stop there
                +		if ( completed ) {
                +			return jqXHR;
                +		}
                +
                +		// We can fire global events as of now if asked to
                +		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
                +		fireGlobals = jQuery.event && s.global;
                +
                +		// Watch for a new set of requests
                +		if ( fireGlobals && jQuery.active++ === 0 ) {
                +			jQuery.event.trigger( "ajaxStart" );
                +		}
                +
                +		// Uppercase the type
                +		s.type = s.type.toUpperCase();
                +
                +		// Determine if request has content
                +		s.hasContent = !rnoContent.test( s.type );
                +
                +		// Save the URL in case we're toying with the If-Modified-Since
                +		// and/or If-None-Match header later on
                +		// Remove hash to simplify url manipulation
                +		cacheURL = s.url.replace( rhash, "" );
                +
                +		// More options handling for requests with no content
                +		if ( !s.hasContent ) {
                +
                +			// Remember the hash so we can put it back
                +			uncached = s.url.slice( cacheURL.length );
                +
                +			// If data is available, append data to url
                +			if ( s.data ) {
                +				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
                +
                +				// #9682: remove data so that it's not used in an eventual retry
                +				delete s.data;
                +			}
                +
                +			// Add or update anti-cache param if needed
                +			if ( s.cache === false ) {
                +				cacheURL = cacheURL.replace( rantiCache, "$1" );
                +				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
                +			}
                +
                +			// Put hash and anti-cache on the URL that will be requested (gh-1732)
                +			s.url = cacheURL + uncached;
                +
                +		// Change '%20' to '+' if this is encoded form body content (gh-2658)
                +		} else if ( s.data && s.processData &&
                +			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
                +			s.data = s.data.replace( r20, "+" );
                +		}
                +
                +		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                +		if ( s.ifModified ) {
                +			if ( jQuery.lastModified[ cacheURL ] ) {
                +				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
                +			}
                +			if ( jQuery.etag[ cacheURL ] ) {
                +				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
                +			}
                +		}
                +
                +		// Set the correct header, if data is being sent
                +		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
                +			jqXHR.setRequestHeader( "Content-Type", s.contentType );
                +		}
                +
                +		// Set the Accepts header for the server, depending on the dataType
                +		jqXHR.setRequestHeader(
                +			"Accept",
                +			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
                +				s.accepts[ s.dataTypes[ 0 ] ] +
                +					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
                +				s.accepts[ "*" ]
                +		);
                +
                +		// Check for headers option
                +		for ( i in s.headers ) {
                +			jqXHR.setRequestHeader( i, s.headers[ i ] );
                +		}
                +
                +		// Allow custom headers/mimetypes and early abort
                +		if ( s.beforeSend &&
                +			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
                +
                +			// Abort if not done already and return
                +			return jqXHR.abort();
                +		}
                +
                +		// Aborting is no longer a cancellation
                +		strAbort = "abort";
                +
                +		// Install callbacks on deferreds
                +		completeDeferred.add( s.complete );
                +		jqXHR.done( s.success );
                +		jqXHR.fail( s.error );
                +
                +		// Get transport
                +		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
                +
                +		// If no transport, we auto-abort
                +		if ( !transport ) {
                +			done( -1, "No Transport" );
                +		} else {
                +			jqXHR.readyState = 1;
                +
                +			// Send global event
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
                +			}
                +
                +			// If request was aborted inside ajaxSend, stop there
                +			if ( completed ) {
                +				return jqXHR;
                +			}
                +
                +			// Timeout
                +			if ( s.async && s.timeout > 0 ) {
                +				timeoutTimer = window.setTimeout( function() {
                +					jqXHR.abort( "timeout" );
                +				}, s.timeout );
                +			}
                +
                +			try {
                +				completed = false;
                +				transport.send( requestHeaders, done );
                +			} catch ( e ) {
                +
                +				// Rethrow post-completion exceptions
                +				if ( completed ) {
                +					throw e;
                +				}
                +
                +				// Propagate others as results
                +				done( -1, e );
                +			}
                +		}
                +
                +		// Callback for when everything is done
                +		function done( status, nativeStatusText, responses, headers ) {
                +			var isSuccess, success, error, response, modified,
                +				statusText = nativeStatusText;
                +
                +			// Ignore repeat invocations
                +			if ( completed ) {
                +				return;
                +			}
                +
                +			completed = true;
                +
                +			// Clear timeout if it exists
                +			if ( timeoutTimer ) {
                +				window.clearTimeout( timeoutTimer );
                +			}
                +
                +			// Dereference transport for early garbage collection
                +			// (no matter how long the jqXHR object will be used)
                +			transport = undefined;
                +
                +			// Cache response headers
                +			responseHeadersString = headers || "";
                +
                +			// Set readyState
                +			jqXHR.readyState = status > 0 ? 4 : 0;
                +
                +			// Determine if successful
                +			isSuccess = status >= 200 && status < 300 || status === 304;
                +
                +			// Get response data
                +			if ( responses ) {
                +				response = ajaxHandleResponses( s, jqXHR, responses );
                +			}
                +
                +			// Convert no matter what (that way responseXXX fields are always set)
                +			response = ajaxConvert( s, response, jqXHR, isSuccess );
                +
                +			// If successful, handle type chaining
                +			if ( isSuccess ) {
                +
                +				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                +				if ( s.ifModified ) {
                +					modified = jqXHR.getResponseHeader( "Last-Modified" );
                +					if ( modified ) {
                +						jQuery.lastModified[ cacheURL ] = modified;
                +					}
                +					modified = jqXHR.getResponseHeader( "etag" );
                +					if ( modified ) {
                +						jQuery.etag[ cacheURL ] = modified;
                +					}
                +				}
                +
                +				// if no content
                +				if ( status === 204 || s.type === "HEAD" ) {
                +					statusText = "nocontent";
                +
                +				// if not modified
                +				} else if ( status === 304 ) {
                +					statusText = "notmodified";
                +
                +				// If we have data, let's convert it
                +				} else {
                +					statusText = response.state;
                +					success = response.data;
                +					error = response.error;
                +					isSuccess = !error;
                +				}
                +			} else {
                +
                +				// Extract error from statusText and normalize for non-aborts
                +				error = statusText;
                +				if ( status || !statusText ) {
                +					statusText = "error";
                +					if ( status < 0 ) {
                +						status = 0;
                +					}
                +				}
                +			}
                +
                +			// Set data for the fake xhr object
                +			jqXHR.status = status;
                +			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
                +
                +			// Success/Error
                +			if ( isSuccess ) {
                +				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
                +			} else {
                +				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
                +			}
                +
                +			// Status-dependent callbacks
                +			jqXHR.statusCode( statusCode );
                +			statusCode = undefined;
                +
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
                +					[ jqXHR, s, isSuccess ? success : error ] );
                +			}
                +
                +			// Complete
                +			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
                +
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
                +
                +				// Handle the global AJAX counter
                +				if ( !( --jQuery.active ) ) {
                +					jQuery.event.trigger( "ajaxStop" );
                +				}
                +			}
                +		}
                +
                +		return jqXHR;
                +	},
                +
                +	getJSON: function( url, data, callback ) {
                +		return jQuery.get( url, data, callback, "json" );
                +	},
                +
                +	getScript: function( url, callback ) {
                +		return jQuery.get( url, undefined, callback, "script" );
                +	}
                +} );
                +
                +jQuery.each( [ "get", "post" ], function( i, method ) {
                +	jQuery[ method ] = function( url, data, callback, type ) {
                +
                +		// Shift arguments if data argument was omitted
                +		if ( jQuery.isFunction( data ) ) {
                +			type = type || callback;
                +			callback = data;
                +			data = undefined;
                +		}
                +
                +		// The url can be an options object (which then must have .url)
                +		return jQuery.ajax( jQuery.extend( {
                +			url: url,
                +			type: method,
                +			dataType: type,
                +			data: data,
                +			success: callback
                +		}, jQuery.isPlainObject( url ) && url ) );
                +	};
                +} );
                +
                +
                +jQuery._evalUrl = function( url ) {
                +	return jQuery.ajax( {
                +		url: url,
                +
                +		// Make this explicit, since user can override this through ajaxSetup (#11264)
                +		type: "GET",
                +		dataType: "script",
                +		cache: true,
                +		async: false,
                +		global: false,
                +		"throws": true
                +	} );
                +};
                +
                +
                +jQuery.fn.extend( {
                +	wrapAll: function( html ) {
                +		var wrap;
                +
                +		if ( this[ 0 ] ) {
                +			if ( jQuery.isFunction( html ) ) {
                +				html = html.call( this[ 0 ] );
                +			}
                +
                +			// The elements to wrap the target around
                +			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
                +
                +			if ( this[ 0 ].parentNode ) {
                +				wrap.insertBefore( this[ 0 ] );
                +			}
                +
                +			wrap.map( function() {
                +				var elem = this;
                +
                +				while ( elem.firstElementChild ) {
                +					elem = elem.firstElementChild;
                +				}
                +
                +				return elem;
                +			} ).append( this );
                +		}
                +
                +		return this;
                +	},
                +
                +	wrapInner: function( html ) {
                +		if ( jQuery.isFunction( html ) ) {
                +			return this.each( function( i ) {
                +				jQuery( this ).wrapInner( html.call( this, i ) );
                +			} );
                +		}
                +
                +		return this.each( function() {
                +			var self = jQuery( this ),
                +				contents = self.contents();
                +
                +			if ( contents.length ) {
                +				contents.wrapAll( html );
                +
                +			} else {
                +				self.append( html );
                +			}
                +		} );
                +	},
                +
                +	wrap: function( html ) {
                +		var isFunction = jQuery.isFunction( html );
                +
                +		return this.each( function( i ) {
                +			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
                +		} );
                +	},
                +
                +	unwrap: function( selector ) {
                +		this.parent( selector ).not( "body" ).each( function() {
                +			jQuery( this ).replaceWith( this.childNodes );
                +		} );
                +		return this;
                +	}
                +} );
                +
                +
                +jQuery.expr.pseudos.hidden = function( elem ) {
                +	return !jQuery.expr.pseudos.visible( elem );
                +};
                +jQuery.expr.pseudos.visible = function( elem ) {
                +	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
                +};
                +
                +
                +
                +
                +jQuery.ajaxSettings.xhr = function() {
                +	try {
                +		return new window.XMLHttpRequest();
                +	} catch ( e ) {}
                +};
                +
                +var xhrSuccessStatus = {
                +
                +		// File protocol always yields status code 0, assume 200
                +		0: 200,
                +
                +		// Support: IE <=9 only
                +		// #1450: sometimes IE returns 1223 when it should be 204
                +		1223: 204
                +	},
                +	xhrSupported = jQuery.ajaxSettings.xhr();
                +
                +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
                +support.ajax = xhrSupported = !!xhrSupported;
                +
                +jQuery.ajaxTransport( function( options ) {
                +	var callback, errorCallback;
                +
                +	// Cross domain only allowed if supported through XMLHttpRequest
                +	if ( support.cors || xhrSupported && !options.crossDomain ) {
                +		return {
                +			send: function( headers, complete ) {
                +				var i,
                +					xhr = options.xhr();
                +
                +				xhr.open(
                +					options.type,
                +					options.url,
                +					options.async,
                +					options.username,
                +					options.password
                +				);
                +
                +				// Apply custom fields if provided
                +				if ( options.xhrFields ) {
                +					for ( i in options.xhrFields ) {
                +						xhr[ i ] = options.xhrFields[ i ];
                +					}
                +				}
                +
                +				// Override mime type if needed
                +				if ( options.mimeType && xhr.overrideMimeType ) {
                +					xhr.overrideMimeType( options.mimeType );
                +				}
                +
                +				// X-Requested-With header
                +				// For cross-domain requests, seeing as conditions for a preflight are
                +				// akin to a jigsaw puzzle, we simply never set it to be sure.
                +				// (it can always be set on a per-request basis or even using ajaxSetup)
                +				// For same-domain requests, won't change header if already provided.
                +				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
                +					headers[ "X-Requested-With" ] = "XMLHttpRequest";
                +				}
                +
                +				// Set headers
                +				for ( i in headers ) {
                +					xhr.setRequestHeader( i, headers[ i ] );
                +				}
                +
                +				// Callback
                +				callback = function( type ) {
                +					return function() {
                +						if ( callback ) {
                +							callback = errorCallback = xhr.onload =
                +								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
                +
                +							if ( type === "abort" ) {
                +								xhr.abort();
                +							} else if ( type === "error" ) {
                +
                +								// Support: IE <=9 only
                +								// On a manual native abort, IE9 throws
                +								// errors on any property access that is not readyState
                +								if ( typeof xhr.status !== "number" ) {
                +									complete( 0, "error" );
                +								} else {
                +									complete(
                +
                +										// File: protocol always yields status 0; see #8605, #14207
                +										xhr.status,
                +										xhr.statusText
                +									);
                +								}
                +							} else {
                +								complete(
                +									xhrSuccessStatus[ xhr.status ] || xhr.status,
                +									xhr.statusText,
                +
                +									// Support: IE <=9 only
                +									// IE9 has no XHR2 but throws on binary (trac-11426)
                +									// For XHR2 non-text, let the caller handle it (gh-2498)
                +									( xhr.responseType || "text" ) !== "text"  ||
                +									typeof xhr.responseText !== "string" ?
                +										{ binary: xhr.response } :
                +										{ text: xhr.responseText },
                +									xhr.getAllResponseHeaders()
                +								);
                +							}
                +						}
                +					};
                +				};
                +
                +				// Listen to events
                +				xhr.onload = callback();
                +				errorCallback = xhr.onerror = callback( "error" );
                +
                +				// Support: IE 9 only
                +				// Use onreadystatechange to replace onabort
                +				// to handle uncaught aborts
                +				if ( xhr.onabort !== undefined ) {
                +					xhr.onabort = errorCallback;
                +				} else {
                +					xhr.onreadystatechange = function() {
                +
                +						// Check readyState before timeout as it changes
                +						if ( xhr.readyState === 4 ) {
                +
                +							// Allow onerror to be called first,
                +							// but that will not handle a native abort
                +							// Also, save errorCallback to a variable
                +							// as xhr.onerror cannot be accessed
                +							window.setTimeout( function() {
                +								if ( callback ) {
                +									errorCallback();
                +								}
                +							} );
                +						}
                +					};
                +				}
                +
                +				// Create the abort callback
                +				callback = callback( "abort" );
                +
                +				try {
                +
                +					// Do send the request (this may raise an exception)
                +					xhr.send( options.hasContent && options.data || null );
                +				} catch ( e ) {
                +
                +					// #14683: Only rethrow if this hasn't been notified as an error yet
                +					if ( callback ) {
                +						throw e;
                +					}
                +				}
                +			},
                +
                +			abort: function() {
                +				if ( callback ) {
                +					callback();
                +				}
                +			}
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
                +jQuery.ajaxPrefilter( function( s ) {
                +	if ( s.crossDomain ) {
                +		s.contents.script = false;
                +	}
                +} );
                +
                +// Install script dataType
                +jQuery.ajaxSetup( {
                +	accepts: {
                +		script: "text/javascript, application/javascript, " +
                +			"application/ecmascript, application/x-ecmascript"
                +	},
                +	contents: {
                +		script: /\b(?:java|ecma)script\b/
                +	},
                +	converters: {
                +		"text script": function( text ) {
                +			jQuery.globalEval( text );
                +			return text;
                +		}
                +	}
                +} );
                +
                +// Handle cache's special case and crossDomain
                +jQuery.ajaxPrefilter( "script", function( s ) {
                +	if ( s.cache === undefined ) {
                +		s.cache = false;
                +	}
                +	if ( s.crossDomain ) {
                +		s.type = "GET";
                +	}
                +} );
                +
                +// Bind script tag hack transport
                +jQuery.ajaxTransport( "script", function( s ) {
                +
                +	// This transport only deals with cross domain requests
                +	if ( s.crossDomain ) {
                +		var script, callback;
                +		return {
                +			send: function( _, complete ) {
                +				script = jQuery( "<script>" ).prop( {
                +					charset: s.scriptCharset,
                +					src: s.url
                +				} ).on(
                +					"load error",
                +					callback = function( evt ) {
                +						script.remove();
                +						callback = null;
                +						if ( evt ) {
                +							complete( evt.type === "error" ? 404 : 200, evt.type );
                +						}
                +					}
                +				);
                +
                +				// Use native DOM manipulation to avoid our domManip AJAX trickery
                +				document.head.appendChild( script[ 0 ] );
                +			},
                +			abort: function() {
                +				if ( callback ) {
                +					callback();
                +				}
                +			}
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +var oldCallbacks = [],
                +	rjsonp = /(=)\?(?=&|$)|\?\?/;
                +
                +// Default jsonp settings
                +jQuery.ajaxSetup( {
                +	jsonp: "callback",
                +	jsonpCallback: function() {
                +		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
                +		this[ callback ] = true;
                +		return callback;
                +	}
                +} );
                +
                +// Detect, normalize options and install callbacks for jsonp requests
                +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
                +
                +	var callbackName, overwritten, responseContainer,
                +		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
                +			"url" :
                +			typeof s.data === "string" &&
                +				( s.contentType || "" )
                +					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
                +				rjsonp.test( s.data ) && "data"
                +		);
                +
                +	// Handle iff the expected data type is "jsonp" or we have a parameter to set
                +	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
                +
                +		// Get callback name, remembering preexisting value associated with it
                +		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
                +			s.jsonpCallback() :
                +			s.jsonpCallback;
                +
                +		// Insert callback into url or form data
                +		if ( jsonProp ) {
                +			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
                +		} else if ( s.jsonp !== false ) {
                +			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
                +		}
                +
                +		// Use data converter to retrieve json after script execution
                +		s.converters[ "script json" ] = function() {
                +			if ( !responseContainer ) {
                +				jQuery.error( callbackName + " was not called" );
                +			}
                +			return responseContainer[ 0 ];
                +		};
                +
                +		// Force json dataType
                +		s.dataTypes[ 0 ] = "json";
                +
                +		// Install callback
                +		overwritten = window[ callbackName ];
                +		window[ callbackName ] = function() {
                +			responseContainer = arguments;
                +		};
                +
                +		// Clean-up function (fires after converters)
                +		jqXHR.always( function() {
                +
                +			// If previous value didn't exist - remove it
                +			if ( overwritten === undefined ) {
                +				jQuery( window ).removeProp( callbackName );
                +
                +			// Otherwise restore preexisting value
                +			} else {
                +				window[ callbackName ] = overwritten;
                +			}
                +
                +			// Save back as free
                +			if ( s[ callbackName ] ) {
                +
                +				// Make sure that re-using the options doesn't screw things around
                +				s.jsonpCallback = originalSettings.jsonpCallback;
                +
                +				// Save the callback name for future use
                +				oldCallbacks.push( callbackName );
                +			}
                +
                +			// Call if it was a function and we have a response
                +			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
                +				overwritten( responseContainer[ 0 ] );
                +			}
                +
                +			responseContainer = overwritten = undefined;
                +		} );
                +
                +		// Delegate to script
                +		return "script";
                +	}
                +} );
                +
                +
                +
                +
                +// Support: Safari 8 only
                +// In Safari 8 documents created via document.implementation.createHTMLDocument
                +// collapse sibling forms: the second one becomes a child of the first one.
                +// Because of that, this security measure has to be disabled in Safari 8.
                +// https://bugs.webkit.org/show_bug.cgi?id=137337
                +support.createHTMLDocument = ( function() {
                +	var body = document.implementation.createHTMLDocument( "" ).body;
                +	body.innerHTML = "<form></form><form></form>";
                +	return body.childNodes.length === 2;
                +} )();
                +
                +
                +// Argument "data" should be string of html
                +// context (optional): If specified, the fragment will be created in this context,
                +// defaults to document
                +// keepScripts (optional): If true, will include scripts passed in the html string
                +jQuery.parseHTML = function( data, context, keepScripts ) {
                +	if ( typeof data !== "string" ) {
                +		return [];
                +	}
                +	if ( typeof context === "boolean" ) {
                +		keepScripts = context;
                +		context = false;
                +	}
                +
                +	var base, parsed, scripts;
                +
                +	if ( !context ) {
                +
                +		// Stop scripts or inline event handlers from being executed immediately
                +		// by using document.implementation
                +		if ( support.createHTMLDocument ) {
                +			context = document.implementation.createHTMLDocument( "" );
                +
                +			// Set the base href for the created document
                +			// so any parsed elements with URLs
                +			// are based on the document's URL (gh-2965)
                +			base = context.createElement( "base" );
                +			base.href = document.location.href;
                +			context.head.appendChild( base );
                +		} else {
                +			context = document;
                +		}
                +	}
                +
                +	parsed = rsingleTag.exec( data );
                +	scripts = !keepScripts && [];
                +
                +	// Single tag
                +	if ( parsed ) {
                +		return [ context.createElement( parsed[ 1 ] ) ];
                +	}
                +
                +	parsed = buildFragment( [ data ], context, scripts );
                +
                +	if ( scripts && scripts.length ) {
                +		jQuery( scripts ).remove();
                +	}
                +
                +	return jQuery.merge( [], parsed.childNodes );
                +};
                +
                +
                +/**
                + * Load a url into a page
                + */
                +jQuery.fn.load = function( url, params, callback ) {
                +	var selector, type, response,
                +		self = this,
                +		off = url.indexOf( " " );
                +
                +	if ( off > -1 ) {
                +		selector = stripAndCollapse( url.slice( off ) );
                +		url = url.slice( 0, off );
                +	}
                +
                +	// If it's a function
                +	if ( jQuery.isFunction( params ) ) {
                +
                +		// We assume that it's the callback
                +		callback = params;
                +		params = undefined;
                +
                +	// Otherwise, build a param string
                +	} else if ( params && typeof params === "object" ) {
                +		type = "POST";
                +	}
                +
                +	// If we have elements to modify, make the request
                +	if ( self.length > 0 ) {
                +		jQuery.ajax( {
                +			url: url,
                +
                +			// If "type" variable is undefined, then "GET" method will be used.
                +			// Make value of this field explicit since
                +			// user can override it through ajaxSetup method
                +			type: type || "GET",
                +			dataType: "html",
                +			data: params
                +		} ).done( function( responseText ) {
                +
                +			// Save response for use in complete callback
                +			response = arguments;
                +
                +			self.html( selector ?
                +
                +				// If a selector was specified, locate the right elements in a dummy div
                +				// Exclude scripts to avoid IE 'Permission Denied' errors
                +				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
                +
                +				// Otherwise use the full result
                +				responseText );
                +
                +		// If the request succeeds, this function gets "data", "status", "jqXHR"
                +		// but they are ignored because response was set above.
                +		// If it fails, this function gets "jqXHR", "status", "error"
                +		} ).always( callback && function( jqXHR, status ) {
                +			self.each( function() {
                +				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
                +			} );
                +		} );
                +	}
                +
                +	return this;
                +};
                +
                +
                +
                +
                +// Attach a bunch of functions for handling common AJAX events
                +jQuery.each( [
                +	"ajaxStart",
                +	"ajaxStop",
                +	"ajaxComplete",
                +	"ajaxError",
                +	"ajaxSuccess",
                +	"ajaxSend"
                +], function( i, type ) {
                +	jQuery.fn[ type ] = function( fn ) {
                +		return this.on( type, fn );
                +	};
                +} );
                +
                +
                +
                +
                +jQuery.expr.pseudos.animated = function( elem ) {
                +	return jQuery.grep( jQuery.timers, function( fn ) {
                +		return elem === fn.elem;
                +	} ).length;
                +};
                +
                +
                +
                +
                +jQuery.offset = {
                +	setOffset: function( elem, options, i ) {
                +		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
                +			position = jQuery.css( elem, "position" ),
                +			curElem = jQuery( elem ),
                +			props = {};
                +
                +		// Set position first, in-case top/left are set even on static elem
                +		if ( position === "static" ) {
                +			elem.style.position = "relative";
                +		}
                +
                +		curOffset = curElem.offset();
                +		curCSSTop = jQuery.css( elem, "top" );
                +		curCSSLeft = jQuery.css( elem, "left" );
                +		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
                +			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
                +
                +		// Need to be able to calculate position if either
                +		// top or left is auto and position is either absolute or fixed
                +		if ( calculatePosition ) {
                +			curPosition = curElem.position();
                +			curTop = curPosition.top;
                +			curLeft = curPosition.left;
                +
                +		} else {
                +			curTop = parseFloat( curCSSTop ) || 0;
                +			curLeft = parseFloat( curCSSLeft ) || 0;
                +		}
                +
                +		if ( jQuery.isFunction( options ) ) {
                +
                +			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
                +			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
                +		}
                +
                +		if ( options.top != null ) {
                +			props.top = ( options.top - curOffset.top ) + curTop;
                +		}
                +		if ( options.left != null ) {
                +			props.left = ( options.left - curOffset.left ) + curLeft;
                +		}
                +
                +		if ( "using" in options ) {
                +			options.using.call( elem, props );
                +
                +		} else {
                +			curElem.css( props );
                +		}
                +	}
                +};
                +
                +jQuery.fn.extend( {
                +	offset: function( options ) {
                +
                +		// Preserve chaining for setter
                +		if ( arguments.length ) {
                +			return options === undefined ?
                +				this :
                +				this.each( function( i ) {
                +					jQuery.offset.setOffset( this, options, i );
                +				} );
                +		}
                +
                +		var doc, docElem, rect, win,
                +			elem = this[ 0 ];
                +
                +		if ( !elem ) {
                +			return;
                +		}
                +
                +		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
                +		// Support: IE <=11 only
                +		// Running getBoundingClientRect on a
                +		// disconnected node in IE throws an error
                +		if ( !elem.getClientRects().length ) {
                +			return { top: 0, left: 0 };
                +		}
                +
                +		rect = elem.getBoundingClientRect();
                +
                +		doc = elem.ownerDocument;
                +		docElem = doc.documentElement;
                +		win = doc.defaultView;
                +
                +		return {
                +			top: rect.top + win.pageYOffset - docElem.clientTop,
                +			left: rect.left + win.pageXOffset - docElem.clientLeft
                +		};
                +	},
                +
                +	position: function() {
                +		if ( !this[ 0 ] ) {
                +			return;
                +		}
                +
                +		var offsetParent, offset,
                +			elem = this[ 0 ],
                +			parentOffset = { top: 0, left: 0 };
                +
                +		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
                +		// because it is its only offset parent
                +		if ( jQuery.css( elem, "position" ) === "fixed" ) {
                +
                +			// Assume getBoundingClientRect is there when computed position is fixed
                +			offset = elem.getBoundingClientRect();
                +
                +		} else {
                +
                +			// Get *real* offsetParent
                +			offsetParent = this.offsetParent();
                +
                +			// Get correct offsets
                +			offset = this.offset();
                +			if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
                +				parentOffset = offsetParent.offset();
                +			}
                +
                +			// Add offsetParent borders
                +			parentOffset = {
                +				top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
                +				left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
                +			};
                +		}
                +
                +		// Subtract parent offsets and element margins
                +		return {
                +			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
                +			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
                +		};
                +	},
                +
                +	// This method will return documentElement in the following cases:
                +	// 1) For the element inside the iframe without offsetParent, this method will return
                +	//    documentElement of the parent window
                +	// 2) For the hidden or detached element
                +	// 3) For body or html element, i.e. in case of the html node - it will return itself
                +	//
                +	// but those exceptions were never presented as a real life use-cases
                +	// and might be considered as more preferable results.
                +	//
                +	// This logic, however, is not guaranteed and can change at any point in the future
                +	offsetParent: function() {
                +		return this.map( function() {
                +			var offsetParent = this.offsetParent;
                +
                +			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
                +				offsetParent = offsetParent.offsetParent;
                +			}
                +
                +			return offsetParent || documentElement;
                +		} );
                +	}
                +} );
                +
                +// Create scrollLeft and scrollTop methods
                +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
                +	var top = "pageYOffset" === prop;
                +
                +	jQuery.fn[ method ] = function( val ) {
                +		return access( this, function( elem, method, val ) {
                +
                +			// Coalesce documents and windows
                +			var win;
                +			if ( jQuery.isWindow( elem ) ) {
                +				win = elem;
                +			} else if ( elem.nodeType === 9 ) {
                +				win = elem.defaultView;
                +			}
                +
                +			if ( val === undefined ) {
                +				return win ? win[ prop ] : elem[ method ];
                +			}
                +
                +			if ( win ) {
                +				win.scrollTo(
                +					!top ? val : win.pageXOffset,
                +					top ? val : win.pageYOffset
                +				);
                +
                +			} else {
                +				elem[ method ] = val;
                +			}
                +		}, method, val, arguments.length );
                +	};
                +} );
                +
                +// Support: Safari <=7 - 9.1, Chrome <=37 - 49
                +// Add the top/left cssHooks using jQuery.fn.position
                +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
                +// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
                +// getComputedStyle returns percent when specified for top/left/bottom/right;
                +// rather than make the css module depend on the offset module, just check for it here
                +jQuery.each( [ "top", "left" ], function( i, prop ) {
                +	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
                +		function( elem, computed ) {
                +			if ( computed ) {
                +				computed = curCSS( elem, prop );
                +
                +				// If curCSS returns percentage, fallback to offset
                +				return rnumnonpx.test( computed ) ?
                +					jQuery( elem ).position()[ prop ] + "px" :
                +					computed;
                +			}
                +		}
                +	);
                +} );
                +
                +
                +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
                +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
                +	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
                +		function( defaultExtra, funcName ) {
                +
                +		// Margin is only for outerHeight, outerWidth
                +		jQuery.fn[ funcName ] = function( margin, value ) {
                +			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
                +				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
                +
                +			return access( this, function( elem, type, value ) {
                +				var doc;
                +
                +				if ( jQuery.isWindow( elem ) ) {
                +
                +					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
                +					return funcName.indexOf( "outer" ) === 0 ?
                +						elem[ "inner" + name ] :
                +						elem.document.documentElement[ "client" + name ];
                +				}
                +
                +				// Get document width or height
                +				if ( elem.nodeType === 9 ) {
                +					doc = elem.documentElement;
                +
                +					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
                +					// whichever is greatest
                +					return Math.max(
                +						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
                +						elem.body[ "offset" + name ], doc[ "offset" + name ],
                +						doc[ "client" + name ]
                +					);
                +				}
                +
                +				return value === undefined ?
                +
                +					// Get width or height on the element, requesting but not forcing parseFloat
                +					jQuery.css( elem, type, extra ) :
                +
                +					// Set width or height on the element
                +					jQuery.style( elem, type, value, extra );
                +			}, type, chainable ? margin : undefined, chainable );
                +		};
                +	} );
                +} );
                +
                +
                +jQuery.fn.extend( {
                +
                +	bind: function( types, data, fn ) {
                +		return this.on( types, null, data, fn );
                +	},
                +	unbind: function( types, fn ) {
                +		return this.off( types, null, fn );
                +	},
                +
                +	delegate: function( selector, types, data, fn ) {
                +		return this.on( types, selector, data, fn );
                +	},
                +	undelegate: function( selector, types, fn ) {
                +
                +		// ( namespace ) or ( selector, types [, fn] )
                +		return arguments.length === 1 ?
                +			this.off( selector, "**" ) :
                +			this.off( types, selector || "**", fn );
                +	}
                +} );
                +
                +jQuery.holdReady = function( hold ) {
                +	if ( hold ) {
                +		jQuery.readyWait++;
                +	} else {
                +		jQuery.ready( true );
                +	}
                +};
                +jQuery.isArray = Array.isArray;
                +jQuery.parseJSON = JSON.parse;
                +jQuery.nodeName = nodeName;
                +
                +
                +
                +
                +// Register as a named AMD module, since jQuery can be concatenated with other
                +// files that may use define, but not via a proper concatenation script that
                +// understands anonymous AMD modules. A named AMD is safest and most robust
                +// way to register. Lowercase jquery is used because AMD module names are
                +// derived from file names, and jQuery is normally delivered in a lowercase
                +// file name. Do this after creating the global so that if an AMD module wants
                +// to call noConflict to hide this version of jQuery, it will work.
                +
                +// Note that for maximum portability, libraries that are not jQuery should
                +// declare themselves as anonymous modules, and avoid setting a global if an
                +// AMD loader is present. jQuery is a special case. For more information, see
                +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
                +
                +if ( typeof define === "function" && define.amd ) {
                +	define( "jquery", [], function() {
                +		return jQuery;
                +	} );
                +}
                +
                +
                +
                +
                +var
                +
                +	// Map over jQuery in case of overwrite
                +	_jQuery = window.jQuery,
                +
                +	// Map over the $ in case of overwrite
                +	_$ = window.$;
                +
                +jQuery.noConflict = function( deep ) {
                +	if ( window.$ === jQuery ) {
                +		window.$ = _$;
                +	}
                +
                +	if ( deep && window.jQuery === jQuery ) {
                +		window.jQuery = _jQuery;
                +	}
                +
                +	return jQuery;
                +};
                +
                +// Expose jQuery and $ identifiers, even in AMD
                +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
                +// and CommonJS for browser emulators (#13566)
                +if ( !noGlobal ) {
                +	window.jQuery = window.$ = jQuery;
                +}
                +
                +
                +
                +
                +return jQuery;
                +} );
                diff --git a/backend/webif/static/js/jquery-3.2.1.min.js b/backend/webif/static/js/jquery-3.2.1.min.js
                new file mode 100755
                index 000000000..644d35e27
                --- /dev/null
                +++ b/backend/webif/static/js/jquery-3.2.1.min.js
                @@ -0,0 +1,4 @@
                +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
                +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
                +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),
                +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r});
                diff --git a/backend/webif/static/js/logics_view_functions.js b/backend/webif/static/js/logics_view_functions.js
                new file mode 100755
                index 000000000..ba15426ef
                --- /dev/null
                +++ b/backend/webif/static/js/logics_view_functions.js
                @@ -0,0 +1,108 @@
                +$('#help').click(function(e) {
                +  $('#help_text').toggle();
                +  resizeCodeMirror()
                +});
                +$('#linewrapping').click(function(e) {
                +    switchLineWrapping()
                +});
                +$('#rulers').click(function(e) {
                +    switchRulers();
                +});
                +
                +window.addEventListener("resize", resizeCodeMirror, false);
                +
                +function resizeCodeMirror() {
                +    if (!logicsCodeMirror.getOption("fullScreen")) {
                +        var browserHeight = $( window ).height();
                +        offsetTop = $('.CodeMirror').offset().top;
                +        logicsCodeMirror.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) - 15 + browserHeight)+ 'px';
                +        logicsCodeMirror.refresh();
                +    }
                +}
                +
                +resizeCodeMirror();
                +
                +var dict = [];
                +function getItemDictionary() {
                +    $.getJSON('items.json?mode=list', function(result) {
                +        for (i = 0; i < result.length; i++) {
                +            dict.push("sh."+result[i]);
                +        }
                +    });
                +}
                +getItemDictionary();
                +
                +CodeMirror.registerHelper('hint', 'itemsHint', function(editor) {
                +    var cur = editor.getCursor(),
                +        curLine = editor.getLine(cur.line);
                +    var start = cur.ch,
                +        end = start;
                +
                +    var charexp =  /[\w\.$]+/;
                +    while (end < curLine.length && charexp.test(curLine.charAt(end))) ++end;
                +    while (start && charexp.test(curLine.charAt(start - 1))) --start;
                +    var curWord = start != end && curLine.slice(start, end);
                +    if (curWord.length > 1) {
                +        curWord = curWord.trim();
                +    }
                +    var regex = new RegExp('^' + curWord, 'i');
                +    if (curWord.length >= 3) {
                +        return {
                +            list: (!curWord ? [] : dict.filter(function(item) {
                +                return item.match(regex);
                +            })).sort(),
                +            from: CodeMirror.Pos(cur.line, start),
                +            to: CodeMirror.Pos(cur.line, end)
                +        }
                +    }
                +});
                +
                +CodeMirror.commands.autocomplete_item = function(cm) {
                +    CodeMirror.showHint(cm, CodeMirror.hint.itemsHint);
                +};
                +
                +function switchLineWrapping() {
                +	logicsCodeMirror.setOption('lineWrapping', !logicsCodeMirror.getOption('lineWrapping'));
                +	if (logicsCodeMirror.getOption('lineWrapping')) {
                +		$('#linewrapping').addClass('active');
                +	} else {
                +		$('#linewrapping').removeClass('active');
                +	}
                +};
                +
                +function switchRulers() {
                +
                +	if (logicsCodeMirror.getOption('rulers').length == 0) {
                +		$('#rulers').addClass('active');
                +		logicsCodeMirror.setOption('rulers', rulers);
                +	} else {
                +		$('#rulers').removeClass('active');
                +		logicsCodeMirror.setOption('rulers', []);
                +	}
                +};
                +
                +function checkChangedContent() {
                +    if ($('#original_content').val() != logicsCodeMirror.getValue() || ($('#original_cycle').val() != $('#cycle').val()) || ($('#original_crontab').val() != $('#crontab').val()) || ($('#original_watch').val() != $('#watch').val())) {
                +        return true;
                +    } else {
                +        return false;
                +    }
                +};
                +
                +function markChangedContent() {
                +    $('#savereloadtrigger').removeClass('btn-success');
                +    $('#savereload').removeClass('btn-success');
                +    $('#save').removeClass('btn-success');
                +    $('#savereloadtrigger').addClass('btn-danger');
                +    $('#savereload').addClass('btn-danger');
                +    $('#save').addClass('btn-danger');
                +}
                +
                +function markIdenticalContent() {
                +    $('#savereloadtrigger').removeClass('btn-danger');
                +    $('#savereload').removeClass('btn-danger');
                +    $('#save').removeClass('btn-danger');
                +    $('#savereloadtrigger').addClass('btn-success');
                +    $('#savereload').addClass('btn-success');
                +    $('#save').addClass('btn-success');
                +}
                \ No newline at end of file
                diff --git a/backend/webif/static/js/npm.js b/backend/webif/static/js/npm.js
                new file mode 100755
                index 000000000..bf6aa8060
                --- /dev/null
                +++ b/backend/webif/static/js/npm.js
                @@ -0,0 +1,13 @@
                +// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
                +require('../../js/transition.js')
                +require('../../js/alert.js')
                +require('../../js/button.js')
                +require('../../js/carousel.js')
                +require('../../js/collapse.js')
                +require('../../js/dropdown.js')
                +require('../../js/modal.js')
                +require('../../js/tooltip.js')
                +require('../../js/popover.js')
                +require('../../js/scrollspy.js')
                +require('../../js/tab.js')
                +require('../../js/affix.js')
                \ No newline at end of file
                diff --git a/backend/webif/templates/base.html b/backend/webif/templates/base.html
                new file mode 100755
                index 000000000..1f5b0a825
                --- /dev/null
                +++ b/backend/webif/templates/base.html
                @@ -0,0 +1,60 @@
                +{% block doc -%}
                +<!DOCTYPE html>
                +<html{% block html_attribs %}{% endblock html_attribs %}>
                +{%- block html %}
                +  <head>
                +    {%- block head %}
                +    <title>{% block title %}{% endblock title %}</title>
                +	<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1.3, minimum-scale=1" />
                +	<meta name="apple-mobile-web-app-capable" content="yes" />
                +	<meta name="apple-mobile-web-app-status-bar-style" content="black" />
                +	<meta http-equiv="expires" content="0" />
                +
                +    {%- block metas %}
                +    <meta name="viewport" content="width=1200">
                +    {#
                +	<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1.3, minimum-scale=1" />
                +	<meta http-equiv="expires" content="0" />
                +	#}
                +    {%- endblock metas %}
                +
                +    {%- block styles %}
                +    <!-- Bootstrap
                +    <link href="{ {bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')} }" rel="stylesheet">
                +    -->
                +    <link rel="icon" href="static/img/favicon.ico" type="image/png">
                +    <link rel="apple-touch-icon" href="static/img/logo_small_32x32">
                +    <link rel="apple-touch-icon" sizes="76x76" href="static/img/logo_small_76x76.png">
                +    <link rel="apple-touch-icon" sizes="120x120" href="static/img/logo_small_120x120.png">
                +    <link rel="apple-touch-icon" sizes="152x152" href="static/img/logo_small_152x152.png">
                +    <link rel="apple-touch-startup-image" href="static/img/logo_big.png">
                +
                +    <link rel="stylesheet" href="static/js/fontawesome/svg-with-js/css/fa-svg-with-js.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap-treeview.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap-reload.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/backend.css" type="text/css"/>
                +    {%- endblock styles %}
                +    {% block scripts %}
                +    <script src="static/js/fontawesome/svg-with-js/js/fontawesome-all.min.js"></script>
                +    <script src="static/js/jquery-3.2.1.min.js"></script>
                +    <script src="static/js/bootstrap.min.js"></script>
                +    <script src="static/js/bootstrap-treeview.min.js"></script>
                +    <script src="static/js/bootstrap-reload.min.js"></script>
                +    <script src="static/js/google-prettify/run_prettify.js"></script>
                +    <script src="static/js/backend.js"></script>
                +    {%- endblock scripts %}
                +    {%- endblock head %}
                +  </head>
                +  <body{% block body_attribs %}{% endblock body_attribs %}>
                +    {% block body -%}
                +    {% block navbar %}
                +    {%- endblock navbar %}
                +    {% block content -%}
                +    {%- endblock content %}
                +
                +    {%- endblock body %}
                +  </body>
                +{%- endblock html %}
                +</html>
                +{% endblock doc -%}
                diff --git a/backend/webif/templates/conf_yaml_converter.html b/backend/webif/templates/conf_yaml_converter.html
                new file mode 100755
                index 000000000..32f33edc0
                --- /dev/null
                +++ b/backend/webif/templates/conf_yaml_converter.html
                @@ -0,0 +1,79 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<script src="static/codemirror/lib/codemirror.js"></script>
                +<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
                +<link rel="stylesheet" href="static/css/codemirror_custom.css">
                +<script src="static/codemirror/mode/yaml/yaml.js"></script>
                +<script src="static/codemirror/addon/display/rulers.js"></script>
                +
                +<style>
                +li.L0, li.L1, li.L2, li.L3,
                +li.L5, li.L6, li.L7, li.L8
                +{ list-style-type: decimal !important }
                +</style>
                +
                +<form name="input" action="conf_yaml_converter.html" method="POST" enctype="multipart/form-data">
                +    <div class="container" style="width: 100%;">
                +    <div style="width: 48%; float: left; border: 1px solid #ccc; margin-bottom: 10px; margin-right: 5px;">
                +        <div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Eingabe im .CONF Format') }}</div>
                +        <textarea id="conf_code" name="conf_code">{{ conf_code }}</textarea>
                +    </div>
                +    <div style="width: 48%; float: left; border: 1px solid #ccc; margin-bottom: 10px;">
                +        <div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Ergebnis im .YAML Format') }}</div>
                +        <textarea id="yaml_code" autocomplete="off" name="yaml_code">{{ yaml_code }}</textarea>
                +    </div>
                +    </div>
                +    <div class="container" style="width: 100%;">
                +    <input name="convert" value="{{ _('Konvertieren','button') }}" type="submit" class="btn btn-default btn-xs">
                +    </div>
                +</form>
                +<script>
                +     var rulers = [];
                +     for (var i = 1; i <= 100; i++) {
                +        rulers.push({color: '#eee', column: i * 4, lineStyle: "dashed"});
                +     }
                +
                +     var myCodeMirrorConf = CodeMirror.fromTextArea(document.getElementById("conf_code"), {
                +        lineNumbers: true,
                +        lineSeparator: '\n',
                +        indentUnit: 4,
                +        rulers: rulers,
                +        lineWrapping: false,
                +        indentWithTabs: false
                +     });
                +     var myCodeMirrorYaml = CodeMirror.fromTextArea(document.getElementById("yaml_code"), {
                +        lineNumbers: true,
                +        lineSeparator: '\n',
                +        indentUnit: 4,
                +        rulers: rulers,
                +        lineWrapping: false,
                +        indentWithTabs: false,
                +        readOnly: true,
                +        mode: "yaml"
                +     });
                +
                +     function resizeCodeMirrors() {
                +        if (!myCodeMirrorConf.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorConf.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -60 + browserHeight)+ 'px';
                +            myCodeMirrorConf.refresh();
                +        }
                +        if (!myCodeMirrorYaml.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorYaml.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -60 + browserHeight)+ 'px';
                +            myCodeMirrorYaml.refresh();
                +        }
                +     }
                +
                +     window.addEventListener("resize", resizeCodeMirrors, false);
                +     resizeCodeMirrors();
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/disclosure.html b/backend/webif/templates/disclosure.html
                new file mode 100755
                index 000000000..b0616b5d6
                --- /dev/null
                +++ b/backend/webif/templates/disclosure.html
                @@ -0,0 +1,195 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +{% block content %}
                +<div class="container">
                +<h3>{{ _('disclosure_title', 'disclosure') }}</h3><br/>
                +</div>
                +<div class="container" style="border: 1px solid #ccc;">
                +<h4>{{ _('Verwendete Open Source Software Komponenten', 'disclosure') }}:</h4>
                +    <table class="table table-striped table-hover">
                +        <thead>
                +            <tr>
                +                <th>{{ _('Name', 'disclosure') }}</th>
                +                <th>{{ _('Lizenz', 'disclosure') }}</th>
                +                <th>{{ _('Link', 'disclosure') }}</th>
                +            </tr>
                +        </thead>
                +        <tbody>
                +        <tr><td width="150px;">Bootstrap 3.3.7</td><td>MIT License</td><td><a target="_blank" href="http://getbootstrap.com/">http://getbootstrap.com/</a></td></tr>
                +        <tr><td>Bootstrap Tree View</td><td>Apache License, Version 2.0</td><td><a target="_blank" href="https://github.com/jonmiles/bootstrap-treeview">https://github.com/jonmiles/bootstrap-treeview</a></td></tr>
                +        <tr><td>bootstrap-reload.js</td><td>MIT License (plugin was largely modified as original plugin did not work)</td><td><a target="_blank" href="https://github.com/Graghav/bootstrap-reload">https://github.com/Graghav/bootstrap-reload</a></td></tr>
                +        <tr><td>google-prettify</td><td>Apache License, Version 2.0</td><td><a target="_blank" href="https://github.com/google/code-prettify">https://github.com/google/code-prettify</a></td></tr>
                +        <tr><td>CodeMirror 5.32.0</td><td>MIT License</td><td><a target="_blank" href="https://codemirror.net/">https://codemirror.net/</a></td></tr>
                +        <tr><td>jQuery 3.2.1</td><td>MIT License</td><td><a target="_blank" href="https://jquery.org">https://jquery.org</a></td></tr>
                +        <tr><td>Font Awesome 5.0.1 (Free)</td><td>Font Awesome licensed under <a href="http://scripts.sil.org/OFL" target="_blank">SIL OFL 1.1</a><br/>Font Awesome CSS, LESS, and Sass files are licensed under the <a href="https://opensource.org/licenses/MIT" target="_blank">MIT License</a><br/>Font Awesome icons (all icons packaged as .svg and .js files) are licensed under the <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">CC BY 4.0 License</a></td><td><a target="_blank" href="http://fontawesome.com">http://fontawesome.com</a></td></tr>
                +        <tr><td width="150px;">{{ _('Icons/Bilder', 'disclosure') }}</td><td>{{ _('Alle Icons und Bilder kommen von', 'disclosure') }} https://openclipart.org</td><td><a target="_blank" href="https://openclipart.org">https://openclipart.org</a></td></tr>
                +        </tbody>
                +    </table>
                +</div>
                +<br style="clear: both;"/>
                +<div class="container">
                +<div><strong>Bootstrap 3.3.7:</strong></div><br/>
                +MIT License<br/>
                +<br/>
                +Copyright (c) 2011-2016 Twitter, Inc.<br/>
                +<br/>
                +Permission is hereby granted, free of charge, to any person obtaining a copy<br/>
                +of this software and associated documentation files (the "Software"), to deal<br/>
                +in the Software without restriction, including without limitation the rights<br/>
                +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br/>
                +copies of the Software, and to permit persons to whom the Software is<br/>
                +furnished to do so, subject to the following conditions:<br/>
                +<br/>
                +The above copyright notice and this permission notice shall be included in all<br/>
                +copies or substantial portions of the Software.<br/>
                +<br/>
                +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br/>
                +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br/>
                +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br/>
                +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br/>
                +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br/>
                +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
                +SOFTWARE.<br/>
                +</div>
                +<br/>
                +<div class="container">
                +    <div><strong>Bootstrap Tree View:</strong></div><br/>
                +    Copyright 2013 Jonathan Miles<br/>
                +    <br/>
                +    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at <a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a><br/>
                +    <br/>
                +    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.<br/>
                +</div>
                +<br/>
                +<div class="container">
                +    <div><strong>bootstrap-reload.js:</strong></div><br/>
                +    The MIT License (MIT)<br/>
                +    <br/>
                +    Copyright (c) 2014 Raghav<br/>
                +    <br/>
                +    Permission is hereby granted, free of charge, to any person obtaining a copy<br/>
                +    of this software and associated documentation files (the "Software"), to deal<br/>
                +    in the Software without restriction, including without limitation the rights<br/>
                +    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br/>
                +    copies of the Software, and to permit persons to whom the Software is<br/>
                +    furnished to do so, subject to the following conditions:<br/>
                +    <br/>
                +    The above copyright notice and this permission notice shall be included in all<br/>
                +    copies or substantial portions of the Software.<br/>
                +    <br/>
                +    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br/>
                +    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br/>
                +    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br/>
                +    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br/>
                +    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br/>
                +    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
                +    SOFTWARE.<br/>
                +</div>
                +<br/>
                +<div class="container">
                +<div><strong>CodeMirror 5.32.0:</strong></div><br/>
                +Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others<br/>
                +<br/>
                +Permission is hereby granted, free of charge, to any person obtaining a copy<br/>
                +of this software and associated documentation files (the "Software"), to deal<br/>
                +in the Software without restriction, including without limitation the rights<br/>
                +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br/>
                +copies of the Software, and to permit persons to whom the Software is<br/>
                +furnished to do so, subject to the following conditions:<br/>
                +<br/>
                +The above copyright notice and this permission notice shall be included in<br/>
                +all copies or substantial portions of the Software.<br/>
                +<br/>
                +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br/>
                +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br/>
                +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br/>
                +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br/>
                +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br/>
                +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br/>
                +THE SOFTWARE.<br/>
                +</div>
                +<br/>
                +<div class="container">
                +    <div><strong>Font Awesome Free License:</strong></div><br/>
                +    Font Awesome Free is free, open source, and GPL friendly. You can use it for
                +    commercial projects, open source projects, or really almost whatever you want.
                +    Full Font Awesome Free license: <a href="https://fontawesome.com/license" target="_blank">https://fontawesome.com/license</a>.
                +<br/><br/>
                +    # Icons:<br/>
                +    CC BY 4.0 License (<a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">https://creativecommons.org/licenses/by/4.0/</a>)
                +    In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
                +    packaged as SVG and JS file types.
                +<br/><br/>
                +    # Fonts:<br/>
                +    SIL OFL 1.1 License (<a href="https://scripts.sil.org/OFL" target="_blank">https://scripts.sil.org/OFL</a>)
                +    In the Font Awesome Free download, the SIL OLF license applies to all icons
                +    packaged as web and desktop font files.
                +<br/><br/>
                +    # Code:<br/>
                +    MIT License (<a href="https://opensource.org/licenses/MIT" target="_blank">https://opensource.org/licenses/MIT</a>)
                +    In the Font Awesome Free download, the MIT license applies to all non-font and
                +    non-icon files.
                +<br/><br/>
                +    # Attribution<br/>
                +    Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font
                +    Awesome Free files already contain embedded comments with sufficient
                +    attribution, so you shouldn't need to do anything additional when using these
                +    files normally.
                +<br/><br/>
                +    We've kept attribution comments terse, so we ask that you do not actively work
                +    to remove them from files, especially code. They're a great way for folks to
                +    learn about Font Awesome.
                +<br/><br/>
                +    # Brand Icons<br/>
                +    All brand icons are trademarks of their respective owners. The use of these
                +    trademarks does not indicate endorsement of the trademark holder by Font
                +    Awesome, nor vice versa. **Please do not use brand logos for any purpose except
                +    to represent the company, product, or service to which they refer.**
                +</div>
                +<br/>
                +<div class="container">
                +<div><strong>JQuery 3.2.1:</strong></div><br/>
                +MIT License<br/>
                +<br/>
                +Copyright jQuery Foundation and other contributors, https://jquery.org/<br/>
                +<br/>
                +This software consists of voluntary contributions made by many<br/>
                +individuals. For exact contribution history, see the revision history<br/>
                +available at https://github.com/jquery/jquery<br/>
                +<br/>
                +The following license applies to all parts of this software except as<br/>
                +documented below:<br/>
                +<br/>
                +<br/>
                +<br/>
                +Permission is hereby granted, free of charge, to any person obtaining<br/>
                +a copy of this software and associated documentation files (the<br/>
                +"Software"), to deal in the Software without restriction, including<br/>
                +without limitation the rights to use, copy, modify, merge, publish,<br/>
                +distribute, sublicense, and/or sell copies of the Software, and to<br/>
                +permit persons to whom the Software is furnished to do so, subject to<br/>
                +the following conditions:<br/>
                +<br/>
                +The above copyright notice and this permission notice shall be<br/>
                +included in all copies or substantial portions of the Software.<br/>
                +<br/>
                +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,<br/>
                +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br/>
                +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND<br/>
                +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE<br/>
                +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION<br/>
                +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION<br/>
                +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br/>
                +<br/>
                +<br/>
                +<br/>
                +All files located in the node_modules and external directories are<br/>
                +externally maintained libraries used by this software which have their<br/>
                +own licenses; we recommend you read them, as their terms may differ from<br/>
                +the terms above.<br/><br/>
                +    </div>
                +{% endblock %}
                \ No newline at end of file
                diff --git a/backend/webif/templates/eval_syntax_checker.html b/backend/webif/templates/eval_syntax_checker.html
                new file mode 100755
                index 000000000..aaed17275
                --- /dev/null
                +++ b/backend/webif/templates/eval_syntax_checker.html
                @@ -0,0 +1,84 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<script src="static/codemirror/lib/codemirror.js"></script>
                +<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
                +<link rel="stylesheet" href="static/css/codemirror_custom.css">
                +<script src="static/codemirror/mode/python/python.js"></script>
                +<script src="static/codemirror/addon/display/rulers.js"></script>
                +
                +<style>
                +li.L0, li.L1, li.L2, li.L3,
                +li.L5, li.L6, li.L7, li.L8
                +{ list-style-type: decimal !important }
                +</style>
                +
                +<form name="input" action="eval_syntax_checker.html" method="POST" enctype="multipart/form-data">
                +	<div class="container" style="width: 100%;">
                +		<div style="width: 600px; float: left; border: 1px solid #ccc; margin-bottom: 10px; margin-right: 5px;">
                +			<div title="{{ _('Hier den Ausdruck eingeben, der ausgewertet werden soll. Items können mit absolutem Pfad oder relativem Pfad angegeben werden.') }}">
                +				<div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Ausdruck (Eingabe im Python Eval-Format)') }}</div>
                +				<textarea id="eval_code" name="eval_code">{{ eval_code }}</textarea>
                +			</div>
                +			<div title="{{ _('Um relative Itempfade aufzulösen, hier das Item eingeben, zu dem die Pfade relativ sind.') }}">
                +				<div style="font-weight: bold; padding-left: 5px; border-top: 2px solid #ccc;">{{ _('Relativ zu (Eingabe des Item-Path)') }}</div>
                +				<input type="text" style="width: 599px; border: 1px solid #ccc;" name="relative_to" value="{{ relative_to }}"/>
                +			</div>
                +
                +			<div title="{{ _('Hier wird der Ausdruck angezeigt, nachdem die relativen Itempfade aufgelöst wurden.') }}">
                +				<div style="font-weight: bold; padding-left: 5px; border-bottom: 0px solid #ccc;">&nbsp;</div>
                +				<div style="font-weight: bold; padding-left: 5px; border-bottom: 1px solid #ccc;">{{ _('Expandierter Ausdruck') }}</div>
                +				<div style="padding-left: 5px; border-bottom: 0px solid #ccc;">{{ expanded_code }}&nbsp;</div>
                +			</div>
                +			<div title="{{ _('Hier wird das Ergebnis Ausdruck angezeigt.') }}">
                +				<div style="font-weight: bold; padding-left: 5px; border-bottom: 0px solid #ccc;">&nbsp;</div>
                +				<div style="font-weight: bold; padding-left: 5px; border-bottom: 1px solid #ccc;">{{ _('Ergebnis') }}</div>
                +				<div style="padding-left: 5px; border-bottom: 1px solid #ccc;">{{ check_result }}&nbsp;</div>
                +			</div>
                +		</div>
                +	</div>
                +    <br>
                +	<div class="container" style="width: 100%;">
                +		<input name="check" value="{{ _('Prüfen','button') }}" type="submit" class="btn btn-default btn-xs">
                +    </div>
                +</form>
                +<script>
                +     var rulers = [];
                +     for (var i = 1; i <= 100; i++) {
                +        rulers.push({color: '#eee', column: i * 4, lineStyle: "dashed"});
                +     }
                +
                +     var myCodeMirrorConf = CodeMirror.fromTextArea(document.getElementById("eval_code"), {
                +        lineNumbers: true,
                +        lineSeparator: '\n',
                +        indentUnit: 4,
                +        rulers: rulers,
                +        lineWrapping: true,
                +        indentWithTabs: false,
                +        mode: "python"
                +     });
                +
                +     function resizeCodeMirrors() {
                +        if (!myCodeMirrorConf.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorConf.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -300 + browserHeight)+ 'px';
                +            myCodeMirrorConf.refresh();
                +        }
                +        if (!myCodeMirrorYaml.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorYaml.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -300 + browserHeight)+ 'px';
                +            myCodeMirrorYaml.refresh();
                +        }
                +     }
                +
                +     window.addEventListener("resize", resizeCodeMirrors, false);
                +     resizeCodeMirrors();
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/index.html b/backend/webif/templates/index.html
                new file mode 100755
                index 000000000..73c48b394
                --- /dev/null
                +++ b/backend/webif/templates/index.html
                @@ -0,0 +1,8 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +<meta http-equiv="refresh" content="0; URL=main.html">
                +</head>
                +<body>
                +</body>
                +</html>
                \ No newline at end of file
                diff --git a/backend/webif/templates/items.html b/backend/webif/templates/items.html
                new file mode 100755
                index 000000000..2bbe8abb8
                --- /dev/null
                +++ b/backend/webif/templates/items.html
                @@ -0,0 +1,152 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +{% block content %}
                +
                + <div class="container">
                +      <strong>{{ _('Items') }} ({{ _('gesamt') }}: {{ item_count }})</strong><span id="search-results"></span><br/><br/>
                +      <div class="form-group">
                +          <input type="input" class="form-control" id="input-search" placeholder="{{ _('Itempfad suchen...') }}" value=""><br/>
                +          <button type="button" class="btn btn-default" id="btn-search"><i class="fas fa-search"></i>&nbsp;{{ _('Suchen') }}</button>
                +          <button type="button" class="btn btn-default" id="btn-clear-search"><i class="fas fa-circle-notch"></i>&nbsp;{{ _('Suche zurücksetzen') }}</button>
                +          <button type="button" class="btn btn-default" id="btn-expand-all"><i class="fas fa-folder-open"></i>&nbsp;{{ _('Alle aufklappen') }}</button>
                +          <button type="button" class="btn btn-default" id="btn-collapse-all"><i class="fas fa-folder"></i>&nbsp;{{ _('Alle zuklappen') }}</button>
                +      </div>
                +
                +      <div class="pre-scrollable" id="tree" style="float:left; border: 1px solid #ccc; height:650px; max-height:650px; width:600px;"></div>
                +      <div class=container" style="float:left; margin-left: 5px;">
                +        <!--refresh widget-->
                +        <div class="panel panel-default" data-url="item_detail_json.html?item_path=" data-item="child1">
                +          <div class="panel-heading"><a class="pull-right" href="#"><span id="refresh-element" class="fas fa-sync"></span></a> {{ _('Item-Informationen') }}</div>
                +          <div class="panel-body panel-refresh">
                +            <div class="refresh-container" style="padding-top: 220px;"><i class="refresh-spinner fa fa-spinner fa-spin fa-5x"></i></div>
                +            <div id="tree_detail" class="data-container refresh-data pre-scrollable" style="height:575px; max-height:575px; width:500px;">
                +                {{ _('Item im Baum auswählen um Details einzusehen!') }}
                +            </div>
                +          </div>
                +        </div>
                +    <!--refresh widget-->
                +     </div>
                + </div>
                +
                +<script src="static/js/item_tree_functions.js"></script>
                +<script type="text/javascript" language="javascript">
                +function getDetailInfo(result) {
                +    var temp ='';
                +    $.each(result, function(index, element) {
                +        switch (element.type) {
                +            case 'bool':
                +                var input = '<select class="form-control" id="item_value">';
                +                if (element.value == true) {
                +                    input = input + '<option selected>true</option><option>false</option></select>';
                +                } else {
                +                    input = input + '<option>true</option><option selected>false</option></select>';
                +                }
                +                break;
                +            case 'str':
                +                var input = '<textarea type="text" class="form-control" id="item_value">'+element.value+'</textarea>';
                +                break;
                +            case 'num':
                +                var input = '<input type="text" class="form-control" value="'+element.value+'" id="item_value"/>';
                +                break;
                +            case 'scene':
                +                var input = '<input type="text" class="form-control" value="'+element.value+'" id="item_value"/>';
                +                break;
                +            default:
                +                input = element.value;
                +        }
                +
                +        temp = '<div class="table-responsive"><table class="table table-striped table-hover">';
                +        temp = temp + '<thead><tr><th>{{ _('Attribut') }}</th><th>{{ _('Wert') }}</th></tr></thead><tbody>';
                +        temp = temp + '<tr><th>{{ _('path', 'items') }}</th><td>'+element.path+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('name', 'items') }}</th><td>'+element.name+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('type', 'items') }}</th><td>'+element.type+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('value', 'items') }}</th><td>'+input+'</td></tr>';
                +
                +        temp = temp + '<tr><th></th><td></td></tr>';
                +	    temp = temp + '<tr><th colspan="2">{{ _('Änderungsinformationen') }}:</th></tr>';
                +        temp = temp + '<tr><th>{{ _('Letztes Update') }}</th><td>'+element.last_update+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('Letzte Änderung') }}</th><td>'+element.last_change+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('update_age') }}</th><td>'+element.update_age+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('age') }}</th><td>'+element.age+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('Geändert durch') }}</th><td>'+element.changed_by+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('vorheriger Wert') }}</th><td>'+element.previous_value+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('previous update') }}</th><td>'+element.previous_update+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('previous change') }}</th><td>'+element.previous_change+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('previous update age') }}</th><td>'+element.previous_update_age+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('previous age') }}</th><td>'+element.previous_age+'</td></tr>';
                +
                +        temp = temp + '<tr><th></th><td></td></tr>';
                +	    temp = temp + '<tr><th colspan="2">{{ _('Evaluation und Trigger') }}:</th></tr>';
                +        temp = temp + '<tr><th>{{ _('cache', 'items') }}</th><td>'+element.cache+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('enforce_updates', 'items') }}</th><td>'+element.enforce_updates+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('eval', 'items') }}</th><td>'+element.eval+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('eval_trigger', 'items') }}</th><td>'+element.eval_trigger+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('on_update', 'items') }}</th><td>'+element.on_update+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('on_change', 'items') }}</th><td>'+element.on_change+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('cycle', 'items') }}</th><td>'+element.cycle+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('crontab', 'items') }}</th><td>'+element.crontab+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('autotimer', 'items') }}</th><td>'+element.autotimer+'</td></tr>';
                +        temp = temp + '<tr><th>{{ _('threshold', 'items') }}</th><td>'+element.threshold+'</td></tr>';
                +
                +        config = JSON.parse(element.config);
                +		if (Object.keys(config).length > 0) {
                +    	    temp = temp + '<tr><th></th><td></td></tr>';
                +	        temp = temp + '<tr><th colspan="2">{{ _('Plugin spezifische Attribute') }}:</th></tr>';
                +	        for(key in config){
                +    	        temp = temp + '<tr><th>' + key + '</th><td>' + config[key] + '</td></tr>';
                +			};
                +        };
                +
                +        logics = JSON.parse(element.logics);
                +		if (logics.length > 0) {
                +	        temp = temp + '<tr><th></th><td></td></tr>';
                +    	    temp = temp + '<tr><th colspan="2">{{ _('Verbundene Logiken') }}:</th></tr>';
                +        	for(i in logics){
                +	        	temp = temp + '<tr><td colspan="2">'+logics[i]+'</td></tr>';
                +			};
                +		};
                +
                +        triggers = JSON.parse(element.triggers);
                +		if (triggers.length > 0) {
                +	        temp = temp + '<tr><th></th><td></td></tr>';
                +    	    temp = temp + '<tr><th colspan="2">{{ _('Verbundene Trigger') }}:</th></tr>';
                +        	for(i in triggers){
                +	        	temp = temp + '<tr><td colspan="2">'+triggers[i]+'</td></tr>';
                +			};
                +		};
                +
                +        temp = temp + '</tbody></table></div>';
                +
                +        $('#tree_detail').html(temp);
                +
                +        $("#item_value" ).change(function() {
                +            if (element.type == 'num') {
                +                if (isNaN($("#item_value" ).val())) {
                +                    alert("{{ _('Die eingegebenen Daten sind kein numerischer Wert') }} !");
                +                    return
                +                }
                +            }
                +            $.ajax({
                +                url: 'item_change_value.html',
                +                type: 'POST',
                +                data: {
                +                    'item_path': element.path,
                +                    'value': $("#item_value").val()
                +                },
                +                success: function (response) {
                +                    $( ".fa-sync" ).trigger( "click" );
                +                },
                +                error: function () {
                +                    //your error code
                +                }
                +            });
                +        });
                +    });
                +}
                +getTree();
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/log_view.html b/backend/webif/templates/log_view.html
                new file mode 100755
                index 000000000..f447a8a9f
                --- /dev/null
                +++ b/backend/webif/templates/log_view.html
                @@ -0,0 +1,66 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +    <style>
                +    li.L0, li.L1, li.L2, li.L3,
                +    li.L5, li.L6, li.L7, li.L8
                +    { list-style-type: decimal !important }
                +    </style>
                +	<div class="container" style="width: 90%;">
                +    <h3>SmarthomeNG {{ _('Logfile') }}: {{ logfile }}</h3><br/>
                +    </div>
                +    <div class="container" style="width: 90%;">
                +        <div class="form-group" style="display:inline;">
                +            <div style="float:left; font-size: 20px;">{{ _('Filter') }}:</div>
                +            <input type="text" class="form-control" id="text_filter" value="{{ text_filter }}" style= "margin-left: 10px; width: 400px; float:left;"/>
                +            <select class="form-control" id="log_level_filter" style="margin-left: 10px; width: 200px; float:left;">
                +                <option {% if log_level_filter=="ALL" %}selected{% endif %} value="ALL">ALL</option>
                +                <option {% if log_level_filter=="DEBUG" %}selected{% endif %} value="DEBUG">DEBUG</option>
                +                <option {% if log_level_filter=="INFO" %}selected{% endif %} value="INFO">INFO</option>
                +                <option {% if log_level_filter=="WARNING" %}selected{% endif %} value="WARNING">WARNING</option>
                +                <option {% if log_level_filter=="ERROR" %}selected{% endif %} value="ERROR">ERROR</option>
                +                <option {% if log_level_filter=="CRITICAL" %}selected{% endif %} value="CRITICAL">CRITICAL</option>
                +            </select>
                +        </div>
                +        <button type="button" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()">{{ _('Filter anwenden','button') }}</button>
                +        <button type="button" title="{{ _('Neu Laden', 'button') }}" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()+'&page={{ current_page }}'"><i class="fa fa-refresh" aria-hidden="true"></i></button>
                +        <button type="button" title="{{ _('Nach unten scrollen', 'button') }}" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="document.getElementById('log_print').scrollTop = 9999999;"><i class="fa fa-arrow-circle-down" aria-hidden="true"></i></button>
                +    </div>
                +    <br style="clear:both;"/>
                +    <div class="container" style="width: 90%;">
                +<pre id="log_print" class="prettyprint linenums{% if current_page > 1 %}:{{ (current_page-1) * 1000 +1}}{% endif %}" style="max-height: 600px;">
                +{% if log_lines %}{% for line in log_lines %}{{ line }}{% endfor %}{% else %}{{ _('no data available') }}{% endif %}</pre></div>
                +<div class="container" style="width: 90%;">
                +<table>
                +    <tr><td style="width: 50px; text-align: center;">
                +        <button type="button" id="fast-backward" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()+'&page=1'"><i class="fa fa-fast-backward" aria-hidden="true"></i></button>
                +    </td><td style="width: 50px; text-align: center;">
                +        <button type="button" id="step-backward" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()+'&page={{ current_page-1 }}'"><i class="fa fa-step-backward" aria-hidden="true"></i></button>
                +    </td><td style="width: 80px; font-weight: bold; text-align: center;">
                +        ({{ current_page }} / {{ pages }})
                +    </td><td style="width: 50px; text-align: center;">
                +        <button type="button" id="step-forward" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()+'&page={{ current_page+1 }}'"><i class="fa fa-step-forward" aria-hidden="true"></i></button>
                +    </td><td style="width: 50px; text-align: center;">
                +        <button type="button" id="fast-forward" class="btn btn-default" style="float:left; margin-left: 10px;" onclick="location.href='log_view.html?logfile={{ logfile }}&text_filter='+$('#text_filter').val()+'&log_level_filter='+$('#log_level_filter').val()+'&page={{ pages }}'"><i class="fa fa-fast-forward" aria-hidden="true"></i></button>
                +    </td>
                +    <td style="width: 300px; text-align: right;">
                +		<button type="button" class="btn btn-default" onclick="window.open('log_dump.html?logfile={{ logfile }}')">{{ _('Logfile speichern','button') }}</button>
                +    </td>
                +    </tr>
                +</table>
                +</div>
                +<style type="text/css">
                +    li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 {
                +        margin-left: 10px
                +    }
                +</style>
                +<script type="text/javascript" language="javascript">
                + {% if current_page <= 1 %}$('#fast-backward').prop('disabled', true);$('#step-backward').prop('disabled', true);{% endif %}
                + {% if current_page >= pages %}$('#fast-forward').prop('disabled', true);$('#step-forward').prop('disabled', true);{% endif %}
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/logging.html b/backend/webif/templates/logging.html
                new file mode 100755
                index 000000000..568a6e1f0
                --- /dev/null
                +++ b/backend/webif/templates/logging.html
                @@ -0,0 +1,55 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +        <table class="table table-striped table-hover loggerList">
                +            <thead>
                +                <tr>
                +                    <th>{{ _('logger name') }}</th>
                +                    <th>{{ _('disabled') }}</th>
                +                    <th>{{ _('level') }}</th>
                +                    <th>{{ _('filters') }}</th>
                +                    <th>{{ _('handlers') }}</th>
                +                    <th>{{ _('logfiles') }}</th>
                +                </tr>
                +                
                +            </thead>
                +            <tbody>
                +                {% for l in loggers  %}
                +                <tr>
                +                    {% if l.name == 'root' %}
                +                        <th>{{ l.name }}</th>
                +                        <th>{{ l.disabled }}</th>
                +                        <th>{{ l.level }}</th>
                +                    {% else %}
                +                        <td>{{ l.name }}</td>
                +                        <td>{{ l.disabled }}</td>
                +                        <td>{{ l.level }}</td>
                +                    {% endif %}
                +                    <td>{% for f in l.filters %}
                +                        {% if (f != '') and (not loop.first) %}, {% endif %}
                +                        {{ f }}
                +                        {% endfor %}
                +                    </td>
                +                    <td>{% for h in l.handlers %}
                +                        {% if (h != '') and (not loop.first) %}, {% endif %}
                +                        {{ h }}
                +                        {% endfor %}
                +                    </td>
                +                    <td>{% for fn in l.filenames %}
                +                        {% if (fn != '') and (not loop.first) %}, {% endif %}
                +                        <a href="log_view.html?logfile={{ get_basename(fn) }}">{{ fn }}</a>
                +                        {% endfor %}
                +                    </td>
                +                </tr>
                +                {% endfor %}
                +
                +            </tbody>
                +        </table>
                +    </div>
                +{% endblock %}
                \ No newline at end of file
                diff --git a/backend/webif/templates/logics.html b/backend/webif/templates/logics.html
                new file mode 100755
                index 000000000..643c6c08a
                --- /dev/null
                +++ b/backend/webif/templates/logics.html
                @@ -0,0 +1,281 @@
                + <!DOCTYPE html>
                +
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div style="display:inline;">
                +	<ul class="nav nav-tabs">
                +		<li id="tab_userlogics" class="active"><a href="#">{{ _('Nutzerlogiken') }}</a></li>
                +		<li id="tab_systemlogics"><a href="#">{{ _('Systemlogiken') }}</a></li>
                +		{% if updates and yaml_updates %}
                +			<li style="padding-left:20px; padding-top:10px;">
                +				<button id="newPl" class="btn btn-primary btn-xs" title="{{ _('Neue Python Logik','button') }}" onclick="newPythonLogic();" ><i class="fas fa-code"></i>&nbsp;&nbsp;&nbsp;{{ _('Neue Python Logik','button') }}</button>
                +			</li>
                +			{% if blockly_loaded %}
                +			<li style="padding-left:20px; padding-top:10px;">
                +				<button id="newBl" class="btn btn-primary btn-xs" title="{{ _('Neue Blockly Logik','button') }}" onclick="newBlocklyLogic();" ><i class="fas fa-puzzle-piece"></i>&nbsp;&nbsp;&nbsp;{{ _('Neue Blockly Logik','button') }}</button>
                +			</li>
                +			{% endif %}
                +		{% endif %}
                +	 </ul>
                +</div>
                +
                +<script type="text/javascript" language="javascript">
                +
                +	function newPythonLogic() {
                +		window.location = 'logics_new.html';
                +	};
                +
                +	function newBlocklyLogic() {
                +		window.open('/blockly/edit.html?cmd=new', '_blank');
                +	};
                +
                +</script>
                +
                + <div id="userlogics">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover logicsList">
                +			<thead>
                +				<tr>
                +					<th style="width: 30px;"></th>
                +					<th style="width: 30px;">{{ _('Nr.') }}</th>
                +					<th style="width: 270px;">{{ _('Logik') }}</th>
                +					<th style="width: 200px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 70px;">{{ _('Cycle') }}</th>
                +					<th style="width: 150px;">{{ _('Crontab') }}</th>
                +					<th style="width: 70px;">{{ _('Watch_Items') }}</th>
                +					<th style="width: 250px;">{{ _('Dateiname') }}</th>
                +					{% if updates %}
                +						<th style="width:260px;">{{ _('Aktionen') }} &nbsp;  &nbsp;  &nbsp;
                +						</th>
                +					{% endif %}
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% if smarthome %}
                +					{% for logic in logics %}
                +						{% if logic.userlogic %}
                +						<tr>
                +							<td><span style="color: {% if not logic.enabled %}red{% else %}green{% endif %};" class="fas {% if not logic.enabled %}fa-pause-circle{% else %}fa-play-circle{% endif %}"></span></td>
                +							<td>{{ loop.index }}</td>
                +							<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +							<td>
                +								<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text">
                +							</td>
                +							<td>{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}{{ logic.next_exec }}{% if not logic.enabled %}</span>{% endif %}</td>
                +							<td>{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}
                +								{% if logic.cycle == None %}-{% else %}{{ logic.cycle}} {% endif %}{% if not logic.enabled %}</span>{% endif %}
                +							</td>
                +							<td>{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}
                +								{% if logic.crontab == None %}-{% else %}{{ logic.crontab}} {% endif %}{% if not logic.enabled %}</span>{% endif %}
                +							</td>
                +							<td {% if logic.watch_item_list|length > 0 %}onClick="$('#{{ logic.name }}_additional3').toggle();" style="cursor: pointer;"{% endif %}>
                +								{% if logic.watch_item_list|length == 0 %}-{% else %}{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}{{ logic.watch_item_list|length}}{% if not logic.enabled %}</span>{% endif %} <span class="fas fa-arrow-circle-down" {% if not logic.enabled %}style="color: #ddd;"{% endif %}></span>{% endif %}
                +							</td>
                +							{% if logic.logictype == 'Blockly' and blockly_loaded %}
                +								<td><a target="_blank" href="/blockly/edit.html?cmd=edit&filename={{ get_basename(logic.pathname) }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% else %}
                +								<td><a href="logics_view.html?file_path={{ logic.pathname }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% endif %}
                +							{% if updates and logic.userlogic %}
                +								<td>
                +								    <button {% if not logic.enabled %}disabled="true"{% endif %} name="trigger" title="{{ _('Auslösen','button') }}" class="btn btn-default btn-xs"><i class="fas fa-hand-pointer"></i></button>
                +									<button name="reload" title="{{ _('Neu Laden','button') }}" class="btn btn-default btn-xs"><i class="fas fa-sync"></i></button>
                +								{% if logic.enabled %}
                +									<button name="disable" title="{{ _('Deaktivieren','button') }}" class="btn btn-default btn-xs"><i class="fas fa-pause"></i></button>
                +								{% else %}
                +									<button name="enable" title="{{ _('Aktivieren','button') }}" class="btn btn-default btn-xs"><i class="fas fa-play"></i></button>
                +								{% endif %}
                +								{% if 1 == 1 %}
                +									<button name="unload" title="{{ _('Entladen', 'button') }}" class="btn btn-default btn-xs"><i class="fas fa-eject"></i></button>
                +									&nbsp; &nbsp; &nbsp;
                +									<button name="delete" title="{{ _('Löschen', 'button') }}" class="btn btn-default btn-xs" onClick="return confirm('{{_('Wollen Sie die Logik') }} \'{{ logic.name }}\' {{ _('wirklich löschen?')}}');"><i class="far fa-trash-alt" aria-hidden="true" style="color: #c40808;"></i></button>
                +								{% endif %}
                +								</td>
                +							{% else %}
                +							    <td></td>
                +							{% endif %}
                +							</form>
                +						</tr>
                +						<tr id="{{ logic.name }}_additional3" style="display: none; cursor: pointer;" onClick="$('#{{ logic.name }}_additional3').toggle();">
                +							<td colspan="{% if updates %}9{% else %}8{% endif %}">
                +								<div class="panel panel-default" style="margin-bottom: 5px;">
                +									<div class="panel-heading">{{ _('Watch_Items') }}</div>
                +  									<div class="panel-body">
                +										<table>
                +										{% for value in logic.watch_item_list %}
                +											{% set first = True %}
                +											{% if (loop.index-1) % 3 == 0 and first%}
                +											<tr>
                +											{% endif %}
                +											<td style="width: 300px;">{{ value }}</td>
                +											{% if (loop.index-1) == 0 and not first %}
                +											</tr>
                +											{% else %}
                +											{% set first = False %}
                +											{% endif %}
                +										{% endfor %}
                +										</table>
                +									</div>
                +								</div>
                +							</td>
                +						</tr>
                +						{% endif %}
                +					{% endfor %}
                +					{% if newlogics|length > 0 %}
                +    					<tr><th colspan="{% if updates %}9{% else %}8{% endif %}">{{ _('Neue Logiken (nicht geladen)') }}</th><tr>
                +						{% for logic in newlogics %}
                +							<tr>
                +								<td></td>
                +								<td></td>
                +								<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +								<td>
                +									<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text">
                +								</td>
                +								<td></td>
                +								<td></td>
                +								<td></td>
                +								<td></td>
                +
                +								{% if logic.logictype == 'Blockly' and blockly_loaded %}
                +									<td><a target="_blank" href="/blockly/edit.html?cmd=edit&filename={{ get_basename(logic.pathname) }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +								{% else %}
                +									<td><a href="logics_view.html?file_path={{ logic.filename }}&logicname={{ logic.name }}">{{ get_basename(logic.filename) }}</a></td>
                +								{% endif %}
                +								{% if updates %}
                +									<td>
                +									{% if logic.filename != '' %}
                +										<button name="add" title="{{ _('Hinzufügen','button') }}" type="submit" class="btn btn-default btn-xs"><i class="fas fa-plus"></i></button>
                +										&nbsp; &nbsp; &nbsp;
                +									{% endif %}
                +									<button name="delete" title="{{ _('Löschen', 'button') }}" class="btn btn-danger btn-default btn-xs" onClick="return confirm('{{_('Wollen Sie die Logik') }} \'{{ logic.name }}\' {{ _('wirklich löschen?')}}');"><i class="far fa-trash-alt" aria-hidden="true"></i></button>
                +									</td>
                +								{% else %}
                +									<td></td>
                +								{% endif %}
                +								</form>
                +							</tr>
                +						{% endfor %}
                +					{% endif %}
                +				{% else %}
                +					<tr>
                +						<td>{{ _('no data available') }}</td>
                +					</tr>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                + </div>
                + 
                +<div id="systemlogics" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover logicsList">
                +			<thead>
                +				<tr>
                +					<th style="width: 30px;"></th>
                +					<th style="width: 30px;">{{ _('Nr.') }}</th>
                +					<th style="width: 270px;">{{ _('Logik') }}</th>
                +					<th style="width: 200px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 70px;">{{ _('Cycle') }}</th>
                +					<th style="width: 150px;">{{ _('Crontab') }}</th>
                +					<th style="width: 70px;">{{ _('Watch_Items') }}</th>
                +					<th style="width: 250px;">{{ _('Dateiname') }}</th>
                +					{% if updates %}
                +						<th style="width:260px;">{{ _('Aktionen') }}</th>
                +					{% endif %}
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% if smarthome %}
                +					{% for logic in logics %}
                +						{% if not logic.userlogic %}
                +						<tr>
                +							<td><span style="color: {% if not logic.enabled %}red{% else %}green{% endif %};" class="fas {% if not logic.enabled %}fa-pause-circle{% else %}fa-play-circle{% endif %}"></span></td>
                +							<td>{{ loop.index }}</td>
                +							<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +							<td>
                +								<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text"></td>
                +							{% if smarthome.scheduler.return_next(logic.name) %}
                +								<td>{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}{{ smarthome.scheduler.return_next(logic.name).strftime('%Y-%m-%d %H:%M:%S%z') }}{% if not logic.enabled %}</span>{% endif %}</td>
                +							{% else %}
                +								<td></td>
                +							{% endif %}
                +							<td>
                +								{% if logic.cycle == None %}-{% else %}{{ logic.cycle}} {% endif %}
                +							</td>
                +							<td>
                +								{% if logic.crontab == None %}-{% else %}{{ logic.crontab}} {% endif %}
                +							</td>
                +							<td {% if logic.watch_item_list|length > 0 %}onClick="$('#{{ logic.name }}_additional3').toggle();" style="cursor: pointer;"{% endif %}>
                +								{% if logic.watch_item_list|length == 0 %}-{% else %}{% if not logic.enabled %}<span style="color:#bbb;">{% endif %}{{ logic.watch_item_list|length}}{% if not logic.enabled %}</span>{% endif %} <span class="fas fa-arrow-circle-down" {% if not logic.enabled %}style="color: #ddd;"{% endif %}></span>{% endif %}
                +							</td>
                +							<td><a href="logics_view.html?file_path={{ logic.pathname }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% if updates and logic.userlogic %}
                +								<td>
                +								<input {% if not logic.enabled %}disabled="true"{% endif %} name="trigger" value="{{ _('Auslösen','button') }}" type="submit" class="btn btn-default btn-xs">
                +								<input name="reload" value="{{ _('Neu Laden','button') }}" type="submit" class="btn btn-default btn-xs">
                +								<input name="enable" value="{% if logic.enabled %}{{ _('Deaktivieren','button') }}{% else %}{{ _('Aktivieren','button') }}{% endif %}" type="submit" class="btn btn-default btn-xs">
                +								{% if 1 == 2 %}
                +									<input name="unload" value="{{ 'Entladen' }}" type="submit" class="btn btn-default btn-xs">
                +									<input name="configload" value="{{ 'gemäß config laden' }}" type="submit" class="btn btn-default btn-xs">
                +								{% endif %}
                +								</td>
                +							{% else %}
                +							    <td></td>
                +							{% endif %}
                +							</form>
                +						</tr>
                +						<tr id="{{ logic.name }}_additional3" style="display: none; cursor: pointer;" onClick="$('#{{ logic.name }}_additional3').toggle();">
                +							<td colspan="{% if updates %}8{% else %}7{% endif %}">
                +								<div class="panel panel-default" style="margin-bottom: 5px;">
                +									<div class="panel-heading">{{ _('Watch_Items') }}</div>
                +  									<div class="panel-body">
                +										<table>
                +										{% set first = True %}
                +										{% for value in logic.watch_item_list %}
                +											{% if loop.index % 2 > 0 %}
                +											<tr>
                +											{% endif %}
                +											<td style="width: 300px;">{{ value }}</td>
                +											{% if loop.index % 2 > 0 and not first %}
                +											</tr>
                +											{% else %}
                +											{% set first = False %}
                +											{% endif %}
                +										{% endfor %}
                +										</table>
                +									</div>
                +								</div>
                +							</td>
                +						</tr>
                +						{% endif %}
                +					{% endfor %}
                +				{% else %}
                +					<tr>
                +						<td>{{ _('no data available') }}</td>
                +					</tr>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<script>
                +$('#tab_userlogics').on('click', function(event){
                +	$('#tab_userlogics').addClass('active');
                +	$('#tab_systemlogics').removeClass('active');
                +	$('#userlogics').show();
                +	$('#systemlogics').hide();
                +});
                +$('#tab_systemlogics').on('click', function(event){
                +	$('#tab_userlogics').removeClass('active');
                +	$('#tab_systemlogics').addClass('active');
                +	$('#userlogics').hide()
                +	$('#systemlogics').show();
                +});
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/logics.html.new b/backend/webif/templates/logics.html.new
                new file mode 100755
                index 000000000..debb1d2a2
                --- /dev/null
                +++ b/backend/webif/templates/logics.html.new
                @@ -0,0 +1,279 @@
                + <!DOCTYPE html>
                +
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                + <div style="display:inline;">
                + <div style="display:inline;">
                + <ul class="nav nav-tabs">
                +	<li id="tab_userlogics" class="active"><a href="#">{{ _('Nutzerlogiken') }}</a></li>
                +	<li id="tab_systemlogics"><a href="#">{{ _('Systemlogiken') }}</a></li>
                +	{% if updates %}
                +		<li style="padding-left:20px; padding-top:10px;">
                +		<input id="newPl" type="button" class="btn btn-primary btn-xs" value="{{ _('Neue Python Logik','button') }}" type="submit" onclick="newPythonLogic();" >
                +		</li>
                +		{% if blockly_loaded %}
                +		<li style="padding-left:20px; padding-top:10px;">
                +		<input id="newBl" type="button" class="btn btn-primary btn-xs" value="{{ _('Neue Blockly Logik','button') }}" type="submit" onclick="newBlocklyLogic();" >
                +		</li>
                +		{% endif %}
                +	{% endif %}
                + </ul>
                +
                +</div>
                +<script type="text/javascript" language="javascript">
                +
                +	function newPythonLogic() {
                +		window.location = 'logics_new.html';
                +	};
                +
                +	function newBlocklyLogic() {
                +		window.open('/blockly/edit.html?cmd=new', '_blank');
                +	};
                +
                +</script>
                +
                + <div id="userlogics">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 30px;"></th>
                +					<th style="width: 30px;">{{ _('Nr.') }}</th>
                +					<th style="width: 270px;">{{ _('Logik') }}</th>
                +					<th style="width: 200px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 70px;">{{ _('Cycle') }}</th>
                +					<th style="width: 150px;">{{ _('Crontab') }}</th>
                +					<th style="width: 70px;">{{ _('Watch_Items') }}</th>
                +					<th style="width: 250px;">{{ _('Dateiname') }}</th>
                +					{% if updates %}
                +						<th style="width:260px;">{{ _('Aktionen') }} &nbsp;  &nbsp;  &nbsp;
                +						</th>
                +					{% endif %}
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% if smarthome %}
                +					{% for logic in logics %}
                +						{% if logic.userlogic %}
                +						<tr>
                +							<td><span style="color: {% if logic.enabled == False %}red{% else %}green{% endif %};" class="fa {% if logic.enabled == False %}fa-times-circle{% else %}fa-check-circle{% endif %}"></span></td>
                +							<td>{{ loop.index }}</td>
                +							<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +							<td>
                +								<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text"></td>
                +							{% if smarthome.scheduler.return_next(logic.name) %}
                +								<td>{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}{{ smarthome.scheduler.return_next(logic.name).strftime('%Y-%m-%d %H:%M:%S%z') }}{% if logic.enabled == False %}</span>{% endif %}</td>
                +							{% else %}
                +								<td></td>
                +							{% endif %}
                +							<td>{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}
                +								{% if logic.cycle == None %}-{% else %}{{ logic.cycle}} {% endif %}{% if logic.enabled == False %}</span>{% endif %}
                +							</td>
                +							<td>{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}
                +								{% if logic.crontab == None %}-{% else %}{{ logic.crontab}} {% endif %}{% if logic.enabled = False %}</span>{% endif %}
                +							</td>
                +							<td {% if logic.watch_item_list|length > 0 %}onClick="$('#{{ logic.name }}_additional3').toggle();" style="cursor: pointer;"{% endif %}>
                +								{% if logic.watch_item_list|length == 0 %}-{% else %}{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}{{ logic.watch_item_list|length}}{% if logic.enabled == False %}</span>{% endif %} <span class="fa fa-arrow-circle-down" {% if logic.enabled == False %}style="color: #ddd;"{% endif %}></span>{% endif %}
                +							</td>
                +							{% if logic.logictype == 'Blockly' and blockly_loaded %}
                +								<td><a target="_blank" href="/blockly/edit.html?cmd=edit&filename={{ get_basename(logic.pathname) }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% else %}
                +								<td><a href="logics_view.html?file_path={{ logic.pathname }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% endif %}
                +							{% if updates and logic.userlogic %}
                +								<td>
                +								<input {% if logic.enabled == False %}disabled="true"{% endif %} name="trigger" value="{{ _('Auslösen','button') }}" type="submit" class="btn btn-default btn-xs">
                +								<input name="reload" value="{{ _('Neu Laden','button') }}" type="submit" class="btn btn-default btn-xs">
                +								{% if logic.enabled == True %}
                +									<input name="disable" value="{{ _('Deaktivieren','button') }}" type="submit" class="btn btn-default btn-xs">
                +								{% else %}
                +									<input name="enable" value="{{ _('Aktivieren','button') }}" type="submit" class="btn btn-default btn-xs">
                +								{% endif %}
                +								{% if 1 == 1 %}
                +									<input name="unload" value="{{ 'Entladen' }}" type="submit" class="btn btn-default btn-xs">
                +								{% endif %}
                +								</td>
                +							{% else %}
                +							    <td></td>
                +							{% endif %}
                +							</form>
                +						</tr>
                +						<tr id="{{ logic.name }}_additional3" style="display: none; cursor: pointer; background: #333;" onClick="$('#{{ logic.name }}_additional3').toggle();">
                +							<td colspan="{% if updates %}9{% else %}8{% endif %}">
                +								<div class="panel panel-default" style="margin-bottom: 5px;">
                +									<div class="panel-heading">{{ _('Watch_Items') }}</div>
                +  									<div class="panel-body">
                +										<table>
                +										{% set first = True %}
                +										{% for value in logic.watch_item_list %}
                +											{% if loop.index % 2 > 0 %}
                +											<tr>
                +											{% endif %}
                +											<td style="width: 300px;">{{ value }}</td>
                +											{% if loop.index % 2 > 0 and not first %}
                +											</tr>
                +											{% else %}
                +											{% set first = False %}
                +											{% endif %}
                +										{% endfor %}
                +										</table>
                +									</div>
                +								</div>
                +							</td>
                +						</tr>
                +						{% endif %}
                +					{% endfor %}
                +					{% if newlogics|length > 0 %}
                +    					<tr><th colspan="{% if updates %}9{% else %}8{% endif %}">{{ _('Neue Logiken (nicht geladen)') }}</th><tr>
                +						{% for logic in newlogics %}
                +							<tr>
                +								<td></td>
                +								<td></td>
                +								<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +								<td>
                +									<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text">
                +								</td>
                +								<td></td>
                +								<td></td>
                +								<td></td>
                +								<td></td>
                +
                +								{% if logic.logictype == 'Blockly' and blockly_loaded %}
                +									<td><a target="_blank" href="/blockly/edit.html?cmd=edit&filename={{ get_basename(logic.pathname) }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +								{% else %}
                +									<td><a href="logics_view.html?file_path={{ logic.filename }}&logicname={{ logic.name }}">{{ get_basename(logic.filename) }}</a></td>
                +								{% endif %}
                +								{% if updates %}
                +									<td>
                +									<input name="add" value="{{ _('Hinzufügen','button') }}" type="submit" class="btn btn-default btn-xs">
                +									</td>
                +								{% else %}
                +									<td></td>
                +								{% endif %}
                +								</form>
                +							</tr>
                +						{% endfor %}
                +					{% endif %}
                +				{% else %}
                +					<tr>
                +						<td>{{ _('no data available') }}</td>
                +					</tr>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                + </div>
                + 
                +<div id="systemlogics" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 30px;"></th>
                +					<th style="width: 30px;">{{ _('Nr.') }}</th>
                +					<th style="width: 270px;">{{ _('Logik') }}</th>
                +					<th style="width: 200px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 70px;">{{ _('Cycle') }}</th>
                +					<th style="width: 150px;">{{ _('Crontab') }}</th>
                +					<th style="width: 70px;">{{ _('Watch_Items') }}</th>
                +					<th style="width: 250px;">{{ _('Dateiname') }}</th>
                +					{% if updates %}
                +						<th style="width:260px;">{{ _('Aktionen') }}</th>
                +					{% endif %}
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% if smarthome %}
                +					{% for logic in logics %}
                +						{% if not logic.userlogic %}
                +						<tr>
                +							<td><span style="color: {% if not logic.enabled == True %}red{% else %}green{% endif %};" class="fa {% if logic.enabled == False %}fa-times-circle{% else %}fa-check-circle{% endif %}"></span></td>
                +							<td>{{ loop.index }}</td>
                +							<form name="input" action="logics.html" method="POST" enctype="multipart/form-data">
                +							<td>
                +								<input style="border:none; background-color:transparent; width:100%" name="logic" readonly="true" value="{{ logic.name }}" type="text"></td>
                +							{% if smarthome.scheduler.return_next(logic.name) %}
                +								<td>{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}{{ smarthome.scheduler.return_next(logic.name).strftime('%Y-%m-%d %H:%M:%S%z') }}{% if logic.enabled == False %}</span>{% endif %}</td>
                +							{% else %}
                +								<td></td>
                +							{% endif %}
                +							<td>
                +								{% if logic.cycle == None %}-{% else %}{{ logic.cycle}} {% endif %}
                +							</td>
                +							<td>
                +								{% if logic.crontab == None %}-{% else %}{{ logic.crontab}} {% endif %}
                +							</td>
                +							<td {% if logic.watch_item_list|length > 0 %}onClick="$('#{{ logic.name }}_additional3').toggle();" style="cursor: pointer;"{% endif %}>
                +								{% if logic.watch_item_list|length == 0 %}-{% else %}{% if logic.enabled == False %}<span style="color:#bbb;">{% endif %}{{ logic.watch_item_list|length}}{% if logic.enabled == False %}</span>{% endif %} <span class="fa fa-arrow-circle-down" {% if logic.enabled == False %}style="color: #ddd;"{% endif %}></span>{% endif %}
                +							</td>
                +							<td><a href="logics_view.html?file_path={{ logic.pathname }}&logicname={{ logic.name }}">{{ get_basename(logic.pathname) }}</a></td>
                +							{% if updates and logic.userlogic %}
                +								<td>
                +								<input {% if logic.enabled == False %}disabled="true"{% endif %} name="trigger" value="{{ _('Auslösen','button') }}" type="submit" class="btn btn-default btn-xs">
                +								<input name="reload" value="{{ _('Neu Laden','button') }}" type="submit" class="btn btn-default btn-xs">
                +								<input name="enable" value="{% if logic.enabled == True %}{{ _('Deaktivieren','button') }}{% else %}{{ _('Aktivieren','button') }}{% endif %}" type="submit" class="btn btn-default btn-xs">
                +								{% if 1 == 2 %}
                +									<input name="unload" value="{{ 'Entladen' }}" type="submit" class="btn btn-default btn-xs">
                +									<input name="configload" value="{{ 'gemäß config laden' }}" type="submit" class="btn btn-default btn-xs">
                +								{% endif %}
                +								</td>
                +							{% else %}
                +							    <td></td>
                +							{% endif %}
                +							</form>
                +						</tr>
                +						<tr id="{{ logic.name }}_additional3" style="display: none; cursor: pointer; background: #333;" onClick="$('#{{ logic.name }}_additional3').toggle();">
                +							<td colspan="{% if updates %}8{% else %}7{% endif %}">
                +								<div class="panel panel-default" style="margin-bottom: 5px;">
                +									<div class="panel-heading">{{ _('Watch_Items') }}</div>
                +  									<div class="panel-body">
                +										<table>
                +										{% set first = True %}
                +										{% for value in logic.watch_item_list %}
                +											{% if loop.index % 2 > 0 %}
                +											<tr>
                +											{% endif %}
                +											<td style="width: 300px;">{{ value }}</td>
                +											{% if loop.index % 2 > 0 and not first %}
                +											</tr>
                +											{% else %}
                +											{% set first = False %}
                +											{% endif %}
                +										{% endfor %}
                +										</table>
                +									</div>
                +								</div>
                +							</td>
                +						</tr>
                +						{% endif %}
                +					{% endfor %}
                +				{% else %}
                +					<tr>
                +						<td>{{ _('no data available') }}</td>
                +					</tr>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<script>
                +$('#tab_userlogics').on('click', function(event){
                +	$('#tab_userlogics').addClass('active');
                +	$('#tab_systemlogics').removeClass('active');
                +	$('#userlogics').show();
                +	$('#systemlogics').hide();
                +});
                +$('#tab_systemlogics').on('click', function(event){
                +	$('#tab_userlogics').removeClass('active');
                +	$('#tab_systemlogics').addClass('active');
                +	$('#userlogics').hide()
                +	$('#systemlogics').show();
                +});
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/logics_new.html b/backend/webif/templates/logics_new.html
                new file mode 100755
                index 000000000..57ef8fef5
                --- /dev/null
                +++ b/backend/webif/templates/logics_new.html
                @@ -0,0 +1,44 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +
                +
                +<div class="container" style="width: 90%;">
                +	<h3>SmartHomeNG: {{ _('Neue Logik erstellen') }}</h3>
                +	<strong>{{ '' }}</strong>
                +	<br/><br/>
                +</div>
                +
                +<div class="container" style="width: 90%;">
                +	<div style="margin-bottom: 5px;">
                +	{% if updates and yaml_updates %}
                +		<form name="input" action="logics_new.html" method="POST" enctype="multipart/form-data">
                +		<input id="create" name="create" value="{{ _('Erstellen','button') }}" type="submit" class="btn btn-primary btn-xs"/>
                +	{% endif %}
                +    </div>
                +
                +	<table class="table table-bordered table-hover table-striped">
                +		<tr>
                +			<td style="min-width:200px;">{{ _('Angaben für die Erzeugung einer neuen Python Logik') }}</td>
                +			<td style="width: 900px;">{{ message }}</td>
                +		</tr>
                +		<tr>
                +			<td>&nbsp; &nbsp; -&nbsp;<strong>{{ _('Dateiname') }}</strong></td>
                +			<td><input type="text" style="width: 250px; border: 1px solid #ddd;" name="filename" value="{{ filename }}"/>
                +			{{ _("Dateiname des Python Codes der Logik (ohne Extension '.py')") }}</td>
                +		</tr>
                +		<tr>
                +			<td>&nbsp; &nbsp; -&nbsp;<strong>{{ _('Logikname') }}</strong></td>
                +			<td><input type="text" style="width: 250px; border: 1px solid #ddd;" name="logicname" value="{{ logicname }}"/>
                +			{{ _('Logik-Name/Abschnittsnamen in /etc/logic.yaml) - Wenn leer, wird der Dateiname verwendet') }}</td>
                +		</tr>
                +	</table>
                +</form>
                +</div>
                +{% endblock %}
                +
                diff --git a/backend/webif/templates/logics_view 2.html b/backend/webif/templates/logics_view 2.html
                new file mode 100755
                index 000000000..e04af6cb5
                --- /dev/null
                +++ b/backend/webif/templates/logics_view 2.html	
                @@ -0,0 +1,287 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
                +<link rel="stylesheet" href="static/codemirror/addon/display/fullscreen.css">
                +<link rel="stylesheet" href="static/codemirror/addon/hint/show-hint.css">
                +<link rel="stylesheet" href="static/css/codemirror_custom.css">
                +<link rel="stylesheet" href="static/codemirror/addon/dialog/dialog.css">
                +<link rel="stylesheet" href="static/codemirror/addon/search/matchesonscrollbar.css">
                +<link rel="stylesheet" href="static/codemirror/addon/fold/foldgutter.css" />
                +<script src="static/codemirror/lib/codemirror.js"></script>
                +<script src="static/codemirror/mode/python/python.js"></script>
                +<script src="static/codemirror/mode/xml/xml.js"></script>
                +<script src="static/codemirror/addon/fold/foldcode.js"></script>
                +<script src="static/codemirror/addon/fold/foldgutter.js"></script>
                +<script src="static/codemirror/addon/fold/comment-fold.js"></script>
                +<script src="static/codemirror/addon/fold/brace-fold.js"></script>
                +<script src="static/codemirror/addon/fold/xml-fold.js"></script>
                +<script src="static/codemirror/addon/fold/indent-fold.js"></script>
                +<script src="static/codemirror/addon/display/fullscreen.js"></script>
                +<script src="static/codemirror/addon/display/rulers.js"></script>
                +<script src="static/codemirror/addon/hint/show-hint.js"></script>
                +<script src="static/codemirror/addon/hint/anyword-hint.js"></script>
                +<script src="static/codemirror/addon/dialog/dialog.js"></script>
                +<script src="static/codemirror/addon/search/searchcursor.js"></script>
                +<script src="static/codemirror/addon/search/search.js"></script>
                +<script src="static/codemirror/addon/scroll/annotatescrollbar.js"></script>
                +<script src="static/codemirror/addon/search/matchesonscrollbar.js"></script>
                +<script src="static/codemirror/addon/search/jump-to-line.js"></script>
                +
                +<div class="container" style="width: 90%;">
                +	<h3>SmartHomeNG {{ _('Logik') }}: {{ logicname }}</h3>
                +	<strong>{{ _('Dateiname') }}:</strong> {{ file_path }}
                +	<br/><br/>
                +</div>
                +
                +<div class="container" style="width: 90%;">
                +	<div style="margin-bottom: 5px;">
                +	{% if updates %}
                +		<form name="input" action="logics_view.html" method="POST" enctype="multipart/form-data">
                +		<input type="hidden" name="logicname" readonly="true" value="{{ logicname }}" type="text"/>
                +		<input type="hidden" name="file_path" readonly="true" value="{{ file_path }}" type="text"/>
                +			<button {% if not thislogic.enabled %}disabled="true"{% endif %} name="trigger" type="submit" class="btn btn-default btn-xs"><i class="fa fa-hand-pointer-o"></i> {{ _('Auslösen','button') }}</button>
                +
                +		{% if thislogic.enabled %}
                +			<button name="disable" class="btn btn-default btn-xs"><i class="fa fa-pause"></i>&nbsp;&nbsp;{{ _('Deaktivieren','button') }}</button>
                +		{% else %}
                +			<button name="enable" class="btn btn-default btn-xs"><i class="fa fa-play"></i>&nbsp;&nbsp;{{ _('Aktivieren','button') }}</button>
                +		{% endif %}
                +		&nbsp;|&nbsp;|&nbsp;
                +			<button id="save" name="save" class="btn btn-default btn-xs btn-success"><i class="fa fa-floppy-o"></i>&nbsp;&nbsp;{{ _('Speichern','button') }}</button>
                +			<button id="savereload" name="savereload" class="btn btn-default btn-xs btn-success"><i class="fa fa-floppy-o"></i>&nbsp;&nbsp;{{ _('Speichern_und_Neu_Laden','button') }}</button>
                +<!--
                +		<input id="savereloadtrigger" name="savereloadtrigger" value="{{ _('Speichern_Neu_Laden_und_Triggern','button') }}" type="submit" class="btn btn-default btn-xs btn-success"/>
                +-->
                +		 |&nbsp;|&nbsp;
                +			<button id="linewrapping" type="button" class="btn btn-default btn-xs active">{{ _('Zeilenumbruch') }}</button>
                +			<button id="rulers" type="button" class="btn btn-default btn-xs active">{{ _('Hilfslinien') }}</button>
                +			<button id="help" type="button" class="btn btn-default btn-xs"><i class="fa fa-info"></i>&nbsp;&nbsp;{{ _('Hilfe') }}</button>
                +	{% endif %}
                +    </div>
                +	<div id="help_text" style="display:none;">
                +		<p>
                +		<ul>
                +			<li>
                +			<strong>{{ _('Speichern','button') }}</strong> {{ _('sowie') }} <strong>{{ _('Speichern_und_Neu_Laden','button') }}</strong> {{ _('führen nicht zum') }} {{ _('Auslösen','button') }} {{ _('der Logik') }}. 
                +			{{ _('Bitte bei Bedarf anschließend') }} <strong>{{ _('Auslösen','button') }}</strong> {{ _('drücken') }}.<br/>
                +			</li>
                +			<li>
                +			{{ _('Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.') }}<br/>
                +			</li>
                +			<li>
                +			{{ _('Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.') }}
                +			</li>
                +			<li>{{_('Suche') }}:<ul>
                +				<li>{{ _('help_search_1') }}</li>
                +				<li>{{ _('help_search_2') }}</li>
                +				<li>{{ _('help_search_3') }}</li>
                +				<li>{{ _('help_search_4') }}</li>
                +				<li>{{ _('help_search_5') }}</li>
                +				<li>{{ _('help_search_6') }}</li>
                +				<li>{{ _('help_search_7') }}</li>
                +			</ul></li>
                +		</ul>
                +		</p>
                +	</div>
                +
                +	<table class="table table-bordered table-hover table-striped">
                +		<tr>
                +			<td style="min-width:200px;"><strong>{{ _('Status') }}:</strong></td>
                +			<td><span style="color: {% if not thislogic.enabled %}red{% else %}green{% endif %};" class="fa {% if not thislogic.enabled %}fa-pause-circle{% else %}fa-play-circle{% endif %}"></span>
                +			{% if not thislogic.enabled %}{{ _('Nicht aktiv') }}{% else %}{{ _('Aktiv') }}{% endif %}
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('letzte Ausführung') }}</strong></td>
                +			<td>{% if not thislogic.enabled %}<span style="color:#bbb;">{% endif %}
                +				{{ thislogic.last_run }}
                +				{% if not thislogic.enabled %}</span>{% endif %}
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('nächste Ausführung') }}</strong></td>
                +			<td>{% if not thislogic.enabled %}<span style="color:#bbb;">{% endif %}
                +				{{ thislogic.next_exec }}
                +				{% if not thislogic.enabled %}</span>{% endif %}
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Cycle') }}</strong></td>
                +			<td>
                +				<input type="text" autocomplete="off" id="cycle" style="width: 200px; border: 1px solid #ddd;" name="cycle" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.cycle }}"/>
                +				<input type="hidden" id="original_cycle" value="{{ thislogic.cycle }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Crontab(s)') }}</strong></td>
                +			<td>
                +				<input type="text" autocomplete="off" id="crontab" style="width: 450px; border: 1px solid #ddd;" name="crontab" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.crontab }}"/>
                +				<input type="hidden" id="original_crontab" value="{{ thislogic.crontab }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Watch_Item(s)') }}</strong></td>
                +			<td>
                +				<input type="text" autocomplete="off" id="watch" style="width: 900px; border: 1px solid #ddd;" name="watch" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.watch_item }}"/>
                +				<input type="hidden" id="original_watch" value="{{ thislogic.watch_item }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ 'visu_acl' }}</strong></td>
                +			<td>
                +				<input type="text" autocomplete="off" id="cycle" style="width: 200px; border: 1px solid #ddd;" name="cycle" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.visu_acl }}"/>
                +				<input type="hidden" id="original_visu_acl" value="{{ thislogic.visu_acl }}"/>
                +			</td>
                +		</tr>
                +	</table>
                +	<input type="hidden" id="original_content" value="{% for line in logic_lines %}{{ line }}{% endfor %}"/>
                +	<div style="border: 1px solid #ddd; margin-bottom: 10px;" {% if mode == 'python' %}class="python-tabs"{% endif %}>
                +		{% if logic_lines %}
                +			<textarea autocomplete="off" id="logics_code" name="logics_code">{% for line in logic_lines %}{{ line }}{% endfor %}</textarea>
                +			{% if updates %}</form>{% endif %}
                +		{% else %}{{ _('no data available') }}{% endif %}
                +	<script>
                +var rulers = [];
                +for (var i = 1; i <= 100; i++) {
                +	rulers.push({color: '#eee', column: i * 4, lineStyle: "dashed"});
                +}
                +
                +var logicsCodeMirror = CodeMirror.fromTextArea(document.getElementById("logics_code"), {
                +    lineNumbers: true,
                +
                +    extraKeys: {
                +        "F11": function(cm) {
                +          logicsCodeMirror.getScrollerElement().style.maxHeight = 'none';
                +          cm.setOption("fullScreen", !cm.getOption("fullScreen"));
                +          if (!cm.getOption("fullScreen")) {
                +              resizeCodeMirror();
                +          }
                +        },
                +        "Esc": function(cm, fullScreen) {
                +          if (cm.getOption("fullScreen")) {
                +              cm.setOption("fullScreen", false);
                +              resizeCodeMirror();
                +          }
                +        }{% if updates %},
                +        "Ctrl-Space": "autocomplete",
                +        "Ctrl-I": "autocomplete_item",
                +        "Alt-F": "findPersistent",
                +        "Tab": function(cm) {
                +			var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
                +			cm.replaceSelection(spaces, "end", "+input");
                +		},
                +		"Ctrl-Q": function(cm){
                +			cm.foldCode(cm.getCursor());
                +		}{% endif %}
                +    },
                +    mode: "{{ mode }}",
                +    {% if not updates %}
                +    readOnly: true,
                +    {% endif %}
                +    lineSeparator: '\n',
                +    indentUnit: 4,
                +    {% if mode == 'python' %}rulers: rulers,{% endif %}
                +    lineWrapping: true,
                +    indentWithTabs: false,
                +    foldGutter: true,
                +    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
                +});
                +
                +{% if updates %}
                +$('#crontab').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +$('#watch').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +$('#cycle').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +logicsCodeMirror.on("keyup", function (cm, event) {
                +    if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +
                +	if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/
                +		(event.keyCode != 8 &&
                +		event.keyCode != 9 &&
                +		event.keyCode != 13 &&
                +		event.keyCode != 27 &&
                +		event.keyCode != 37 &&
                +		event.keyCode != 38 &&
                +		event.keyCode != 39 &&
                +		event.keyCode != 40 &&
                +		event.keyCode != 46)) {
                +		CodeMirror.commands.autocomplete_item(cm, null, {completeSingle: false});
                +	};
                +});
                +var answer = false;
                +var unloadCheck = true;
                +$('a').click(function(e) {
                +    if(checkChangedContent()) {
                +        e.preventDefault();
                +        if(window.confirm("{{ _('Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!')}}")) {
                +        	answer=true;
                +        	location.href=e.currentTarget;
                +        }
                +    }
                +});
                +
                +var inFocus = false;
                +$('#save').click(function() {
                +  inFocus = true;
                +});
                +$('#savereload').focus(function() {
                +  inFocus = true;
                +});
                +$('#savereloadtrigger').focus(function() {
                +  inFocus = true;
                +});
                +
                +$('#save').blur(function() {
                +  inFocus = false;
                +});
                +$('#savereload').blur(function() {
                +  inFocus = false;
                +});
                +$('#savereloadtrigger').blur(function() {
                +  inFocus = false;
                +});
                +
                +window.onbeforeunload = function(e) {
                +	if (inFocus) {
                +		return;
                +	} else if (!answer && checkChangedContent()) {
                +		return '{{ _('Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!')}}';
                +    } else {
                +        return;
                +    }
                +}
                +
                +{% endif %}
                +</script>
                +</div>
                + </div>
                +<script src="static/js/logics_view_functions.js"></script>
                +{% endblock %}
                +
                diff --git a/backend/webif/templates/logics_view.html b/backend/webif/templates/logics_view.html
                new file mode 100755
                index 000000000..41d0284aa
                --- /dev/null
                +++ b/backend/webif/templates/logics_view.html
                @@ -0,0 +1,285 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
                +<link rel="stylesheet" href="static/codemirror/addon/display/fullscreen.css">
                +<link rel="stylesheet" href="static/codemirror/addon/hint/show-hint.css">
                +<link rel="stylesheet" href="static/css/codemirror_custom.css">
                +<link rel="stylesheet" href="static/codemirror/addon/dialog/dialog.css">
                +<link rel="stylesheet" href="static/codemirror/addon/search/matchesonscrollbar.css">
                +<link rel="stylesheet" href="static/codemirror/addon/fold/foldgutter.css" />
                +<script src="static/codemirror/lib/codemirror.js"></script>
                +<script src="static/codemirror/mode/python/python.js"></script>
                +<script src="static/codemirror/mode/xml/xml.js"></script>
                +<script src="static/codemirror/addon/fold/foldcode.js"></script>
                +<script src="static/codemirror/addon/fold/foldgutter.js"></script>
                +<script src="static/codemirror/addon/fold/comment-fold.js"></script>
                +<script src="static/codemirror/addon/fold/brace-fold.js"></script>
                +<script src="static/codemirror/addon/fold/xml-fold.js"></script>
                +<script src="static/codemirror/addon/fold/indent-fold.js"></script>
                +<script src="static/codemirror/addon/display/fullscreen.js"></script>
                +<script src="static/codemirror/addon/display/rulers.js"></script>
                +<script src="static/codemirror/addon/hint/show-hint.js"></script>
                +<script src="static/codemirror/addon/hint/anyword-hint.js"></script>
                +<script src="static/codemirror/addon/dialog/dialog.js"></script>
                +<script src="static/codemirror/addon/search/searchcursor.js"></script>
                +<script src="static/codemirror/addon/search/search.js"></script>
                +<script src="static/codemirror/addon/scroll/annotatescrollbar.js"></script>
                +<script src="static/codemirror/addon/search/matchesonscrollbar.js"></script>
                +<script src="static/codemirror/addon/search/jump-to-line.js"></script>
                +
                +<div class="container" style="width: 90%;">
                +	<h3>SmartHomeNG {{ _('Logik') }}: {{ logicname }}</h3>
                +	<strong>{{ _('Dateiname') }}:</strong> {{ file_path }}
                +	<br/><br/>
                +</div>
                +
                +<div class="container" style="width: 90%;">
                +	<div style="margin-bottom: 5px;">
                +	{% if updates %}
                +		<form name="input" action="logics_view.html" method="POST" enctype="multipart/form-data">
                +		<input type="hidden" name="logicname" readonly="true" value="{{ logicname }}" type="text"/>
                +		<input type="hidden" name="file_path" readonly="true" value="{{ file_path }}" type="text"/>
                +			<button {% if not thislogic.enabled %}disabled="true"{% endif %} name="trigger" type="submit" class="btn btn-default btn-xs"><i class="fas fa-hand-pointer"></i> {{ _('Auslösen','button') }}</button>
                +
                +		{% if thislogic.enabled %}
                +			<button name="disable" class="btn btn-default btn-xs"><i class="fas fa-pause"></i>&nbsp;&nbsp;{{ _('Deaktivieren','button') }}</button>
                +		{% else %}
                +			<button name="enable" class="btn btn-default btn-xs"><i class="fas fa-play"></i>&nbsp;&nbsp;{{ _('Aktivieren','button') }}</button>
                +		{% endif %}
                +		&nbsp;|&nbsp;|&nbsp;
                +			<button id="save" name="save" class="btn btn-default btn-xs btn-success"><i class="fas fa-save"></i>&nbsp;&nbsp;{{ _('Speichern','button') }}</button>
                +			<button id="savereload" name="savereload" class="btn btn-default btn-xs btn-success"><i class="fas fa-save"></i>&nbsp;&nbsp;{{ _('Speichern_und_Neu_Laden','button') }}</button>
                +<!--
                +		<input id="savereloadtrigger" name="savereloadtrigger" value="{{ _('Speichern_Neu_Laden_und_Triggern','button') }}" type="submit" class="btn btn-default btn-xs btn-success"/>
                +-->
                +		 |&nbsp;|&nbsp;
                +			<button id="linewrapping" type="button" class="btn btn-default btn-xs active">{{ _('Zeilenumbruch') }}</button>
                +			<button id="rulers" type="button" class="btn btn-default btn-xs active">{{ _('Hilfslinien') }}</button>
                +			<button id="help" type="button" class="btn btn-default btn-xs"><i class="fas fa-info"></i>&nbsp;&nbsp;{{ _('Hilfe') }}</button>
                +	{% endif %}
                +    </div>
                +	<div id="help_text" style="display:none;">
                +		<p>
                +		<ul>
                +			<li>
                +			<strong>{{ _('Speichern','button') }}</strong> {{ _('sowie') }} <strong>{{ _('Speichern_und_Neu_Laden','button') }}</strong> {{ _('führen nicht zum') }} {{ _('Auslösen','button') }} {{ _('der Logik') }}. 
                +			{{ _('Bitte bei Bedarf anschließend') }} <strong>{{ _('Auslösen','button') }}</strong> {{ _('drücken') }}.<br/>
                +			</li>
                +			<li>
                +			{{ _('Strg + Space: Autovervollständigen von Python Befehlen. Strg + i: Autovervollständigen von Item-Pfaden.') }}<br/>
                +			</li>
                +			<li>
                +			{{ _('Drücken Sie F11 für den Vollbildmodus, wenn der Cursor im Editorfenster ist. Mit F11 oder ESC verlassen Sie den Vollbildmodus wieder.') }}
                +			</li>
                +			<li>{{_('Suche') }}:<ul>
                +				<li>{{ _('help_search_1') }}</li>
                +				<li>{{ _('help_search_2') }}</li>
                +				<li>{{ _('help_search_3') }}</li>
                +				<li>{{ _('help_search_4') }}</li>
                +				<li>{{ _('help_search_5') }}</li>
                +				<li>{{ _('help_search_6') }}</li>
                +				<li>{{ _('help_search_7') }}</li>
                +			</ul></li>
                +		</ul>
                +		</p>
                +	</div>
                +
                +	<table class="table table-bordered table-hover table-striped">
                +		<tr>
                +			<td style="min-width:200px;"><strong>{{ _('Status') }}:</strong></td>
                +			<td colspan="3"><span style="color: {% if not thislogic.enabled %}red{% else %}green{% endif %};" class="fa {% if not thislogic.enabled %}fa-pause-circle{% else %}fa-play-circle{% endif %}"></span>
                +			{% if not thislogic.enabled %}{{ _('Nicht aktiv') }}{% else %}{{ _('Aktiv') }}{% endif %}
                +			</td>
                +		</tr>
                +		<tr>
                +			<td style="width:200px;"><strong>{{ _('letzte Ausführung') }}</strong></td>
                +			<td style="min-width:200px;">{% if not thislogic.enabled %}<span style="color:#bbb;">{% endif %}
                +				{{ thislogic.last_run }}
                +				{% if not thislogic.enabled %}</span>{% endif %}
                +			</td>
                +			<td style="width:200px;"><strong>{{ _('nächste Ausführung') }}</strong></td>
                +			<td style="min-width:200px;">{% if not thislogic.enabled %}<span style="color:#bbb;">{% endif %}
                +				{{ thislogic.next_exec }}
                +				{% if not thislogic.enabled %}</span>{% endif %}
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Cycle') }}</strong></td>
                +			<td colspan="3">
                +				<input type="text" autocomplete="off" id="cycle" style="width: 200px; border: 1px solid #ddd;" name="cycle" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.cycle }}"/>
                +				<input type="hidden" id="original_cycle" value="{{ thislogic.cycle }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Crontab(s)') }}</strong></td>
                +			<td colspan="3">
                +				<input type="text" autocomplete="off" id="crontab" style="width: 450px; border: 1px solid #ddd;" name="crontab" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.crontab }}"/>
                +				<input type="hidden" id="original_crontab" value="{{ thislogic.crontab }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ _('Watch_Item(s)') }}</strong></td>
                +			<td colspan="3">
                +				<input type="text" autocomplete="off" id="watch" style="width: 900px; border: 1px solid #ddd;" name="watch" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.watch_item }}"/>
                +				<input type="hidden" id="original_watch" value="{{ thislogic.watch_item }}"/>
                +			</td>
                +		</tr>
                +		<tr>
                +			<td><strong>{{ 'visu_acl' }}</strong></td>
                +			<td colspan="3">
                +				<input type="text" autocomplete="off" id="cycle" style="width: 200px; border: 1px solid #ddd;" name="visu_acl" {% if not yaml_updates or not updates %}readonly="true" disabled{% endif %} value="{{ thislogic.visu_acl }}"/>
                +				<input type="hidden" id="original_visu_acl" value="{{ thislogic.visu_acl }}"/>
                +			</td>
                +		</tr>
                +	</table>
                +	<input type="hidden" id="original_content" value="{% for line in logic_lines %}{{ line }}{% endfor %}"/>
                +	<div style="border: 1px solid #ddd; margin-bottom: 10px;" {% if mode == 'python' %}class="python-tabs"{% endif %}>
                +		{% if logic_lines %}
                +			<textarea autocomplete="off" id="logics_code" name="logics_code">{% for line in logic_lines %}{{ line }}{% endfor %}</textarea>
                +			{% if updates %}</form>{% endif %}
                +		{% else %}{{ _('no data available') }}{% endif %}
                +	<script>
                +var rulers = [];
                +for (var i = 1; i <= 100; i++) {
                +	rulers.push({color: '#eee', column: i * 4, lineStyle: "dashed"});
                +}
                +
                +var logicsCodeMirror = CodeMirror.fromTextArea(document.getElementById("logics_code"), {
                +    lineNumbers: true,
                +
                +    extraKeys: {
                +        "F11": function(cm) {
                +          logicsCodeMirror.getScrollerElement().style.maxHeight = 'none';
                +          cm.setOption("fullScreen", !cm.getOption("fullScreen"));
                +          if (!cm.getOption("fullScreen")) {
                +              resizeCodeMirror();
                +          }
                +        },
                +        "Esc": function(cm, fullScreen) {
                +          if (cm.getOption("fullScreen")) {
                +              cm.setOption("fullScreen", false);
                +              resizeCodeMirror();
                +          }
                +        }{% if updates %},
                +        "Ctrl-Space": "autocomplete",
                +        "Ctrl-I": "autocomplete_item",
                +        "Alt-F": "findPersistent",
                +        "Tab": function(cm) {
                +			var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
                +			cm.replaceSelection(spaces, "end", "+input");
                +		},
                +		"Ctrl-Q": function(cm){
                +			cm.foldCode(cm.getCursor());
                +		}{% endif %}
                +    },
                +    mode: "{{ mode }}",
                +    {% if not updates %}
                +    readOnly: true,
                +    {% endif %}
                +    lineSeparator: '\n',
                +    indentUnit: 4,
                +    {% if mode == 'python' %}rulers: rulers,{% endif %}
                +    lineWrapping: true,
                +    indentWithTabs: false,
                +    foldGutter: true,
                +    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
                +});
                +
                +{% if updates %}
                +$('#crontab').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +$('#watch').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +$('#cycle').keyup( function() {
                +	if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +});
                +logicsCodeMirror.on("keyup", function (cm, event) {
                +    if (checkChangedContent()) {
                +        markChangedContent();
                +    } else {
                +		markIdenticalContent();
                +    }
                +
                +	if (!cm.state.completionActive && /*Enables keyboard navigation in autocomplete list*/
                +		(event.keyCode != 8 &&
                +		event.keyCode != 9 &&
                +		event.keyCode != 13 &&
                +		event.keyCode != 27 &&
                +		event.keyCode != 37 &&
                +		event.keyCode != 38 &&
                +		event.keyCode != 39 &&
                +		event.keyCode != 40 &&
                +		event.keyCode != 46)) {
                +		CodeMirror.commands.autocomplete_item(cm, null, {completeSingle: false});
                +	};
                +});
                +var answer = false;
                +var unloadCheck = true;
                +$('a').click(function(e) {
                +    if(checkChangedContent()) {
                +        e.preventDefault();
                +        if(window.confirm("{{ _('Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!')}}")) {
                +        	answer=true;
                +        	location.href=e.currentTarget;
                +        }
                +    }
                +});
                +
                +var inFocus = false;
                +$('#save').click(function() {
                +  inFocus = true;
                +});
                +$('#savereload').focus(function() {
                +  inFocus = true;
                +});
                +$('#savereloadtrigger').focus(function() {
                +  inFocus = true;
                +});
                +
                +$('#save').blur(function() {
                +  inFocus = false;
                +});
                +$('#savereload').blur(function() {
                +  inFocus = false;
                +});
                +$('#savereloadtrigger').blur(function() {
                +  inFocus = false;
                +});
                +
                +window.onbeforeunload = function(e) {
                +	if (inFocus) {
                +		return;
                +	} else if (!answer && checkChangedContent()) {
                +		return '{{ _('Sie verlieren ggf. Ihre letzten, nicht gespeicherten Eingaben!')}}';
                +    } else {
                +        return;
                +    }
                +}
                +
                +{% endif %}
                +</script>
                +</div>
                + </div>
                +<script src="static/js/logics_view_functions.js"></script>
                +{% endblock %}
                +
                diff --git a/backend/webif/templates/main.html b/backend/webif/templates/main.html
                new file mode 100755
                index 000000000..84bb78be3
                --- /dev/null
                +++ b/backend/webif/templates/main.html
                @@ -0,0 +1,38 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="container">
                +		<br>
                +		<br>
                +        <div class="row">
                +            <div class="col-md-7 col-md-offset-2 panel panel-default">
                +				<h1 class="margin-base-vertical">
                +				<img src="static/img/logo_big.png" width="150" height="75">
                +	        	&nbsp; SmartHomeNG backend</h1>
                +                <p align="center">
                +                {{ _('Willkommen im Backend von') }} SmartHomeNG.
                +                </p>
                +				<br>
                +				
                +                <!--
                +                <form class="margin-base-vertical">
                +                    <p class="input-group">
                +                        <span class="input-group-addon"><span class="icon-envelope"></span></span>
                +                        <input type="text" class="form-control input-lg" name="email" placeholder="redaktion@linux-magazin.de" />
                +                    </p>
                +                    <p class="text-center">
                +                        <button type="submit" class="btn btn-success btn-lg">Funktionsloser Button</button>
                +                    </p>
                +                    </span>
                +                </form>
                +                -->
                +
                +            </div><!-- //main content -->
                +        </div><!-- //row -->
                +    </div> <!-- //container -->
                +{% endblock %}
                \ No newline at end of file
                diff --git a/backend/webif/templates/navbar.html b/backend/webif/templates/navbar.html
                new file mode 100755
                index 000000000..59bbe3766
                --- /dev/null
                +++ b/backend/webif/templates/navbar.html
                @@ -0,0 +1,55 @@
                +<!DOCTYPE html>
                +<nav class="navbar navbar-default" role="navigation">
                +	<div class="container-fluid">
                +	
                +	<!-- Brand and toggle get grouped for better mobile display -->
                +		<div class="navbar-header">
                +			<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                +				<span class="sr-only">Toggle navigation</span>
                +				<span class="icon-bar"></span>
                +				<span class="icon-bar"></span>
                +				<span class="icon-bar"></span>
                +			</button>
                +		<a class="navbar-brand" href="main.html"><img src="static/img/logo_long.png" alt="SmartHomeNG Logo"></a>
                +		</div>
                +
                +	<!-- Collect the nav links, forms, and other content for toggling -->
                +		<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                +			<ul class="nav navbar-nav">
                +				<li class="nav-item"><a href="system.html">{{ _('Systeminfo', 'menu') }}</a></li>
                +				{% if yaml_converter and 1 == 2 %}
                +				<li class="nav-item dropdown">
                +					<a class="nav-link dropdown-toggle" href="services.html" id="supportedContentDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ _('Dienste', 'menu') }}<span class="caret"></span></a>
                +				 	<ul class="dropdown-menu" aria-labelledby="supportedContentDropdown">
                +						<li><a class="dropdown-item" href="services.html">{{ _('Übersicht') }}</a></li>
                +						<li role="separator" class="divider"></li>
                +						<li><a class="dropdown-item" href="conf_yaml_converter.html">{{ _('CONF-YAML Konverter', 'menu') }}</a></li>
                +				 	</ul>
                +				</li>
                +				{% else %}
                +				<li class="nav-item"><a href="services.html">{{ _('Dienste', 'menu') }}</a></li>
                +				{% endif %}
                +				<li class="nav-item"><a href="items.html">{{ _('Items', 'menu') }}</a></li>
                +				{% if False %}
                +				<li class="nav-item dropdown">
                +					<a class="nav-link dropdown-toggle" href="logics.html" id="supportedContentDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ _('Logiken', 'menu') }}<span class="caret"></span></a>
                +				 	<ul class="dropdown-menu" aria-labelledby="supportedContentDropdown">
                +						<li><a class="dropdown-item" href="logics.html">{{ _('Übersicht', 'menu') }}</a></li>
                +						<li role="separator" class="divider"></li>
                +						<li><a class="dropdown-item" href="logics_blockly.html">{{ _('Blockly-Logiken-Editor', 'menu') }}</a></li>
                +				 	</ul>
                +				</li>
                +				{% else %}
                +				<li class="nav-item"><a href="logics.html">{{ _('Logiken', 'menu') }}</a></li>
                +				{% endif %}
                +				<li class="nav-item"><a href="schedules.html">{{ _('Scheduler', 'menu') }}</a></li>
                +				<li class="nav-item"><a href="plugins.html">{{ _('Plugins', 'menu') }}</a></li>
                +				<li class="nav-item"><a href="scenes.html">{{ _('Szenen', 'menu') }}</a></li>
                +				<li class="nav-item"><a href="threads.html">{{ _('Threads', 'menu') }}</a></li>
                +				<li class="nav-item"><a href="logging.html">{{ _('Logging', 'menu') }}</a></li>
                +				{% if visu_plugin %}<li class="nav-item"><a href="visu.html">{{ _('Visu', 'menu') }}</a></li>{% endif %}
                +				<li class="nav-item"><a href="disclosure.html">{{ _('Disclosure', 'menu') }}</a></li>
                +			</ul>
                +		</div><!-- /.navbar-collapse -->
                +	</div><!-- /.container-fluid -->
                +</nav>
                diff --git a/backend/webif/templates/plugins.html b/backend/webif/templates/plugins.html
                new file mode 100755
                index 000000000..07bef01ae
                --- /dev/null
                +++ b/backend/webif/templates/plugins.html
                @@ -0,0 +1,140 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +        <table class="table table-striped table-hover pluginList">
                +            <thead>
                +                <tr>
                +                    <th>{{ _('Nr.') }}</th>
                +                    <th></th>
                +                    <th>{{ _('Type') }}</th>
                +                    <th>{{ _('Plugin') }}</th>
                +                    <th>{{ _('Classname') }}</th>
                +                    <th>{{ _('Instanz') }}</th>
                +                    <th>{{ _('Version') }}</th>
                +                    <th>{{ _('Mehrere Instanzen möglich') }}</th>
                +                    <th>{{ _('Aktionen') }}</th>
                +                </tr>
                +            </thead>
                +            <tbody>
                +                {% for p in plugins  %}
                +                {% set outer_loop = loop %}
                +                <tr id="{{ loop.index }}_click" style="cursor: pointer;">
                +                    <td width="30px">{{ loop.index }}</td>
                +                    <td width="30px">
                +                        {% if p.metadata.get_string('type') in ['web', 'protocol', 'interface', 'gateway', 'system'] %}
                +                        <img src="static/img/{{ p.metadata.get_string('type') }}.svg" style="width: 25px;"/>
                +                        {% else %}
                +                        -
                +                        {% endif %}
                +                    </td>
                +                    <td width="30px">{% if p.smartplugin %}SmartPlugin{%else%}Classic{%endif%}
                +                    <td width="200px">{{ p.shortname }}</td>
                +                    <td width="160px">{{ p.classname }}</td>
                +                    {% if p.smartplugin %}
                +                        {% set webifs = mod_http.get_webifs_for_plugin(p.shortname) %}
                +                        <td width="200px">
                +                        {% if p.instancename %}{{ p.instancename }}{%else%}default{%endif%}
                +                        </td>
                +                        <td width="150px">{{ p.metadata.get_string('version') }}</td>
                +                        <td width="210px">{% if p.multiinstance %}{{ _('Ja') }}{%else%}{{ _('Nein') }}{%endif%}</td>
                +                        <td>
                +                            {% for webif in webifs %}
                +                            {% if webif['Instance'] == '' or webif['Instance'] == p.instancename %}
                +                            <img id="webif_link_{{outer_loop.index}}_{{loop.index}}" src="static/img/html.svg" style="width: 25px;"/>
                +                            <script>
                +                                $('#webif_link_{{outer_loop.index}}_{{loop.index}}').click(function(e){
                +                                    window.open('http://{{mod_http.get_local_ip_address()}}:{{mod_http.get_local_port()}}/{{ webif['Webifname'] }}')
                +                                    e.stopPropagation();
                +                                });
                +                            </script>
                +                            {%endif%}
                +                            {% endfor %}
                +                        </td>
                +                    {% else %}
                +                        <td>-</td>
                +                        <td>-</td>
                +                        <td>-</td>
                +                        <td>-</td>
                +                    {%endif%}
                +                </tr>
                +                <tr id="{{ loop.index }}_additional" style="display: none; cursor: pointer;">
                +                    <td colspan="9">
                +                        <div class="panel panel-default" style="margin-bottom: 5px;">
                +                            <div class="panel-heading">{{ _('Plugin spezifische Attribute') }}:</div>
                +                            <div class="panel-body">
                +                                <table style="width: 90%;">
                +                                {% set first = True %}
                +                                {% for key, value in p.attributes.items() %}
                +                                    {% if loop.index % 2 > 0 %}
                +                                    <tr>
                +                                    {% endif %}
                +                                    {% if p['metadata'].get_parameter_type(key) != 'foo' %}
                +                                        <td style="width: 50%;"><strong>{{ key }}</strong> ( {{ p['metadata'].get_parameter_type_with_subtype(key) }} ): {{ value }}
                +                                        {% if p['metadata'].get_parameter_defaultvalue(key) == value %}
                +                                        &nbsp; [default]
                +                                        {% endif %}
                +                                        </td>
                +                                    {% else %}
                +                                        <td style="width: 400px;"><strong>{{ key }}</strong>: {{ value }}</td>
                +                                    {% endif %}
                +                                    {% if loop.index % 2 > 0 and not first %}
                +                                    </tr>
                +                                    {% else %}
                +                                    {% set first = False %}
                +                                    {% endif %}
                +                                {% endfor %}
                +                                </table>
                +                            </div>
                +                            <div class="panel-heading">{{ _('Plugin Metadaten') }}:</div>
                +                            <div class="panel-body">
                +                                {% if p.metadata.get_mlstring('description') %}
                +                                <strong>{{ _('Beschreibung') }}:</strong> {{ p.metadata.get_mlstring('description') }}<br/>
                +                                {% endif %}
                +
                +                                {% if p.metadata.get_string('documentation') %}
                +                                <strong>{{ _('Documentation') }}:</strong>
                +                                <a target="_blank" href="{{ p.metadata.get_string('documentation') }}">{{ p.metadata.get_string('documentation') }}</a><br/>
                +                                {% endif %}
                +
                +                                {% if p.metadata.get_string('support') %}
                +                                <strong>{{ _('Support') }}:</strong>
                +                                <a target="_blank" href="{{ p.metadata.get_string('support') }}">{{ p.metadata.get_string('support') }}</a><br/>
                +                                {% endif %}
                +
                +                                <strong>{{ _('Wartung') }}:</strong>
                +                                {% if p.metadata.get_string('maintainer') %}
                +                                    {{ p.metadata.get_string('maintainer') }}
                +                                {% else %}
                +                                -
                +                                {% endif %}
                +                                <br/>
                +                                <strong>{{ _('Tester') }}:</strong>
                +                                {% if p.metadata.get_string('tester') %}
                +                                    {{ p.metadata.get_string('tester') }}
                +                                {% else %}
                +                                -
                +                                {% endif %}
                +                            </div>
                +                        </div>
                +                    </td>
                +                </tr>
                +                <script>
                +                    /* If foldable content: add onclick for table row, stop unfolding when clicking pypi link inside. */
                +                    $('#{{ loop.index }}_click').click(function(){
                +                        $('#{{ loop.index }}_additional').toggle();
                +                    });
                +                    $('#{{ loop.index }}_additional').click(function(){
                +                        $('#{{ loop.index }}_additional').toggle();
                +                    });
                +                </script>
                +                {% endfor %}
                +            </tbody>
                +        </table>
                +    </div>
                +{% endblock %}
                diff --git a/backend/webif/templates/scenes.html b/backend/webif/templates/scenes.html
                new file mode 100755
                index 000000000..7bafd07cf
                --- /dev/null
                +++ b/backend/webif/templates/scenes.html
                @@ -0,0 +1,74 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<col width="25px">
                +			<col width="40px">
                +			<col width="80px">
                +			<col width="400px">
                +			<col minwidth="300px">
                +			<thead>
                +				<tr>
                +					<th colspan="2">{{ _('Szene') }}</th>
                +					<th>{{ _('Lernen') }}</th>
                +					<th>{{ _('Item') }}</th>
                +					<th>{{ _('Wert') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for scene in scene_list %}
                +					<tr>
                +					    {% if scene['name'] == '' %}
                +							<td colspan="5"><strong>{{ scene['path'] }}</strong></td>
                +						{% else %}
                +							<td colspan="5"><strong>{{ scene['path'] }}</strong> &nbsp; ({{ scene['name'] }})</td>
                +						{% endif %}
                +						<td></td>
                +					</tr>
                +					{% for value in scene['values'] %}
                +						{% for action in value['action_list'] %}
                +							{% if (action == value['action_list'][0]) and (value['action_name'] != '') %}
                +								<tr>
                +									<td></td>
                +									<td colspan="3"><strong>{{ value['action'] }}</strong>: {{ value['action_name'] }}</td>
                +									<td></td>
                +									<td></td>
                +								</tr>
                +							{% endif %}
                +							<tr>
                +								<td></td>
                +								{% if (action == value['action_list'][0]) and (value['action_name'] == '') %}
                +									<td><strong>{{ value['action'] }}</strong>:</td>
                +								{% else %}
                +									<td></td>
                +								{% endif %}
                +								{% if action[2] %}
                +									<td>ja</td>
                +								{% else %}
                +									<td>nein</td>
                +								{% endif %}
                +								<td>{{ action[0] }}</td>
                +								{% if (action[3] == None) or (action[3] == action[1]) %}
                +									<td>{{ action[1] }}</td>
                +								{% else %}
                +									<td>{{ action[3] }} (default: {{ action[1] }})</td>
                +								{% endif %}
                +								<td></td>
                +							</tr>
                +						{% endfor %}
                +					{% endfor %}
                +					
                +				{% endfor %}
                +                {% if not supported %}
                +					<h2>&nbsp; You need a newer SmartHomeNG core!</h2>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                +{% endblock %}
                diff --git a/backend/webif/templates/schedules.html b/backend/webif/templates/schedules.html
                new file mode 100755
                index 000000000..6eb7020bc
                --- /dev/null
                +++ b/backend/webif/templates/schedules.html
                @@ -0,0 +1,229 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div style="display:inline;">
                +	<ul class="nav nav-tabs">
                +		<li id="tab_items"><a href="#">{{ _('Item') }} {{ _('Scheduler (plural)') }}</a></li>
                +		<li id="tab_logics"><a href="#">{{ _('Logik') }} {{ _('Scheduler (plural)') }}</a></li>
                +		<li id="tab_plugins"><a href="#">{{ _('Plugin') }} {{ _('Scheduler (plural)') }}</a></li>
                +		<li id="tab_rest"><a href="#">{{ _('sonstige') }} {{ _('Scheduler (plural)') }}</a></li>
                +<!--
                +		<li id="tab_all" class="active"><a href="#">{{ _('alle') }} {{ _('Scheduler (plural)') }}</a></li>
                +-->
                +	 </ul>
                +</div>
                +
                +
                +<div id="all_schedules" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 280px;">{{ _('Scheduler') }}</th>
                +					<th style="width: 210px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 130px;">{{ _('Cycle') }}</th>
                +					<th>{{ _('Crontab') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for entry in schedule_list	 %}
                +						<tr>
                +							<td>{{ entry['fullname'] }}</td>
                +							<td>{{ entry['next'] }}</td>
                +							<td>{{ entry['cycle'] }}</td>
                +							<td>{{ entry['cron'] }}</td>
                +
                +							<td></td>
                +						</tr>
                +
                +				{% endfor %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<div id="item_schedules">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 280px;">{{ _('Scheduler') }}</th>
                +					<th style="width: 210px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 130px;">{{ _('Cycle') }}</th>
                +					<th>{{ _('Crontab') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for entry in schedule_list	 %}
                +					{% if entry['group'] == 'items' %}
                +						<tr>
                +							<td>{{ entry['name'] }}</td>
                +							<td>{{ entry['next'] }}</td>
                +							<td>{{ entry['cycle'] }}</td>
                +							<td>{{ entry['cron'] }}</td>
                +
                +							<td></td>
                +						</tr>
                +					{% endif %}
                +				{% endfor %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<div id="logic_schedules" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 280px;">{{ _('Scheduler') }}</th>
                +					<th style="width: 210px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 130px;">{{ _('Cycle') }}</th>
                +					<th>{{ _('Crontab') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for entry in schedule_list	 %}
                +					{% if entry['group'] == 'logics' %}
                +						<tr>
                +							<td>{{ entry['name'] }}</td>
                +							<td>{{ entry['next'] }}</td>
                +							<td>{{ entry['cycle'] }}</td>
                +							<td>{{ entry['cron'] }}</td>
                +
                +							<td></td>
                +						</tr>
                +					{% endif %}
                +				{% endfor %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<div id="plugin_schedules" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 280px;">{{ _('Scheduler') }}</th>
                +					<th style="width: 210px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 130px;">{{ _('Cycle') }}</th>
                +					<th>{{ _('Crontab') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for entry in schedule_list	 %}
                +					{% if entry['group'] == 'plugins' %}
                +						<tr>
                +							<td>{{ entry['name'] }}</td>
                +							<td>{{ entry['next'] }}</td>
                +							<td>{{ entry['cycle'] }}</td>
                +							<td>{{ entry['cron'] }}</td>
                +
                +							<td></td>
                +						</tr>
                +					{% endif %}
                +				{% endfor %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<div id="rest_schedules" style="display: none;">
                +	<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th style="width: 280px;">{{ _('Scheduler') }}</th>
                +					<th style="width: 210px;">{{ _('nächste Ausführung') }}</th>
                +					<th style="width: 130px;">{{ _('Cycle') }}</th>
                +					<th>{{ _('Crontab') }}</th>
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% for entry in schedule_list	 %}
                +					{% if entry['group'] != 'items' and entry['group'] != 'logics' and entry['group'] != 'plugins' %}
                +						<tr>
                +							<td>{{ entry['fullname'] }}</td>
                +							<td>{{ entry['next'] }}</td>
                +							<td>{{ entry['cycle'] }}</td>
                +							<td>{{ entry['cron'] }}</td>
                +
                +							<td></td>
                +						</tr>
                +					{% endif %}
                +				{% endfor %}
                +			</tbody>
                +		</table>
                +	</div>
                +</div>
                +
                +<script>
                +$('#tab_all').on('click', function(event){
                +	$('#tab_all').addClass('active');
                +	$('#tab_items').removeClass('active');
                +	$('#tab_logics').removeClass('active');
                +	$('#tab_plugins').removeClass('active');
                +	$('#tab_rest').removeClass('active');
                +	$('#all_schedules').show();
                +	$('#item_schedules').hide();
                +	$('#logic_schedules').hide();
                +	$('#plugin_schedules').hide();
                +	$('#rest_schedules').hide();
                +});
                +$('#tab_items').on('click', function(event){
                +	$('#tab_all').removeClass('active');
                +	$('#tab_items').addClass('active');
                +	$('#tab_logics').removeClass('active');
                +	$('#tab_plugins').removeClass('active');
                +	$('#tab_rest').removeClass('active');
                +	$('#all_schedules').hide()
                +	$('#item_schedules').show();
                +	$('#logic_schedules').hide();
                +	$('#plugin_schedules').hide();
                +	$('#rest_schedules').hide();
                +});
                +$('#tab_logics').on('click', function(event){
                +	$('#tab_all').removeClass('active');
                +	$('#tab_items').removeClass('active');
                +	$('#tab_logics').addClass('active');
                +	$('#tab_plugins').removeClass('active');
                +	$('#tab_rest').removeClass('active');
                +	$('#all_schedules').hide()
                +	$('#item_schedules').hide();
                +	$('#logic_schedules').show();
                +	$('#plugin_schedules').hide();
                +	$('#rest_schedules').hide();
                +});
                +$('#tab_plugins').on('click', function(event){
                +	$('#tab_all').removeClass('active');
                +	$('#tab_items').removeClass('active');
                +	$('#tab_logics').removeClass('active');
                +	$('#tab_plugins').addClass('active');
                +	$('#tab_rest').removeClass('active');
                +	$('#all_schedules').hide()
                +	$('#item_schedules').hide();
                +	$('#logic_schedules').hide();
                +	$('#plugin_schedules').show();
                +	$('#rest_schedules').hide();
                +});
                +$('#tab_rest').on('click', function(event){
                +	$('#tab_all').removeClass('active');
                +	$('#tab_items').removeClass('active');
                +	$('#tab_logics').removeClass('active');
                +	$('#tab_plugins').removeClass('active');
                +	$('#tab_rest').addClass('active');
                +	$('#all_schedules').hide()
                +	$('#item_schedules').hide();
                +	$('#logic_schedules').hide();
                +	$('#plugin_schedules').hide();
                +	$('#rest_schedules').show();
                +});
                +</script>
                +
                +{% endblock %}
                diff --git a/backend/webif/templates/services.html b/backend/webif/templates/services.html
                new file mode 100755
                index 000000000..6c97d4b9a
                --- /dev/null
                +++ b/backend/webif/templates/services.html
                @@ -0,0 +1,237 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +	<table class="table table-striped">
                +		<thead>
                +			<tr>
                +				<th width="70">{{ _('Dienst') }}</th>
                +				<th style="min-width:300px;">{{ _('Status') }}</th>
                +				<th>{{ _('Aktion') }}</th>
                +			</tr>
                +		</thead>
                +		<tbody>
                +				<tr>
                +					<td><img src="static/img/languages.svg" alt="Icon languages" width="48" height="48"></td>
                +					<td style="padding-top:23px;">
                +						<div style="float:left; margin-right:15px;">{{ _('Sprache des Backends') }}:</div>
                +						<select id="language" class="form-control" onChange="location.href='reload_translation.html?lang='+$('#language').val()" style="float:left; width: 250px; margin-top:-7px;">
                +							<option {% if lang=='de' %}selected{% endif %} value="de">{% if lang!='de' %}{{ _('Auf Deutsch wechseln') }}{% else %}{{ _('Deutsch','button') }}{% endif %}</option>
                +							<option {% if lang=='en' %}selected{% endif %} value="en">{% if lang!='en' %}{{ _('Auf Englisch wechseln') }}{% else %}{{ _('Englisch','button') }}{% endif %}</option>
                +							<option {% if lang=='fr' %}selected{% endif %} value="fr">{% if lang!='fr' %}{{ _('Auf Französisch wechseln') }}{% else %}{{ _('Französisch','button') }}{% endif %}</option>
                +							<option {% if lang=='pl' %}selected{% endif %} value="pl">{% if lang!='pl' %}{{ _('Auf Polnisch wechseln') }}{% else %}{{ _('Polnisch','button') }}{% endif %}</option>
                +						</select>
                +					<td style="padding-top:15px;">
                +					{% if develop %}
                +						<button type="button" class="btn btn-default" onclick="location.href='reload_translation.html'">{{ _('Übersetzung neu laden') }}</button>
                +					{% endif %}
                +					</td>
                +				</tr>
                +			<tr>
                +<!--
                +				<td><img src="static/img/knxd_service.png" alt="Icon knxd service" width="48" height="48"></td>
                +-->
                +				<td><img src="static/img/gateway.svg" alt="Icon knxd service" width="48" height="48"></td>
                +				<td style="padding-top:23px;">{{ _('Dienst für die KNX Unterstützung') }}:&nbsp;<strong>
                +				{% if knxdeamon %}
                +					{{ knxdeamon }}
                +				{% else %}
                +					{{ _('Nicht aktiv') }}
                +				{% endif %}
                +				</strong></td>
                +				<td></td>
                +			</tr>
                +		{% if 1 == 2 %}
                +			<tr>
                +				<td><img src="static/img/logo_small_76x76.png" alt="SmartHomeNG logo small" width="48" height="48"></td>
                +				<td style="padding-top:23px;"><pre>{{ smarthome_service }}</pre>
                +				</td>
                +				<td style="padding-top:15px;">
                +					{% if knxd_active %}
                +						<form action="stop_smarthome" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('smarthomeNG beenden','button') }}"/>
                +						</form>
                +					{% else %}
                +						<form action="start_smarthome" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('smarthomeNG starten','button') }}"/>
                +						</form>
                +					{% endif %}
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/knxd_service.png" alt="Icon KNXD service" width="48" height="48"></td>
                +				<td style="padding-top:23px;"><pre>{{ knxd_service }}</pre>
                +				</td>
                +				<td style="padding-top:15px;">
                +					{% if knxd_active %}
                +						<form action="stop_knxd_service" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('knxd service beenden','button') }}"/>
                +						</form>
                +					{% else %}
                +						<form action="start_knxd" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('knxd service starten','button') }}"/>
                +						</form>
                +					{% endif %}
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/knxd_socket.png" alt="Icon KNXD socket" width="48" height="48"></td>
                +				<td style="padding-top:23px;"><pre>{{ knxd_socket }}</pre>
                +				</td>
                +				<td style="padding-top:15px;">
                +					{% if knxd_active %}
                +						<form action="stop_knxd" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('knxd socket beenden','button') }}"/>
                +						</form>
                +					{% else %}
                +						<form action="start_knxd" method="post">
                +						<input type="submit" class="btn btn-default" value="{{ _('knxd socket starten','button') }}"/>
                +						</form>
                +					{% endif %}
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/reboot.svg" alt="Icon Reboot" width="48" height="48"></td>
                +				<td style="padding-top:15px;">
                +					<form class="navbar-form navbar-left" action="reboot" method="post">
                +					<div class="form-group">
                +						<input type="password" class="form-control" name="password" maxlength="128" placeholder="{{ _('Root-Passwort') }}"/>
                +					</div>
                +						<input type="submit" class="btn btn-default" value="{{ _('Neu starten','button') }}"/>
                +					</form>
                +				</td>
                +				<td>{% if rbt1 %}
                +						{{ rbt1 }}
                +					{% else %}
                +
                +					{% endif %}</td>
                +			</tr>
                +		{% endif %}
                +		</tbody>
                +	</table>
                +	<table class="table table-striped">
                +		<thead>
                +			<tr>
                +				<th width="70">{{ _('Dienst') }}</th>
                +				<th>{{ _('Aktion') }}</th>
                +			</tr>
                +		</thead>
                +		<tbody>
                +			{% if sql_plugin %}
                +			<tr>
                +				<td><img src="static/img/db_backup.svg" alt="Icon database backup" width="48" height="48"></td>
                +				<td style="padding-top:15px;"><button type="button" class="btn btn-default" onclick="window.open('/db_dump.html?plugin=sqlite_old')">{{ _('Datenbank-Dump','button') }} (SQLite Plugin)</button></td>
                +			</tr>
                +			{% endif %}
                +			{% if database_plugin %}
                +				{% for p in database_plugin  %}
                +				<tr>
                +					<td><img src="static/img/db_backup.svg" alt="Icon database backup" width="48" height="48"></td>
                +					<td style="padding-top:15px;"><button type="button" class="btn btn-default" onclick="window.open('/db_dump.html?plugin={{ p }}')">{{ _('Datenbank-Dump','button') }} - {{ _('Instanz') }}: ({{ p }})</button></td>
                +				</tr>
                +				{% endfor %}
                +			{% endif %}
                +			<tr>
                +				<td><img src="static/img/cache.svg" alt="Icon cache" width="48" height="48"></td>
                +				<td colspan="2" style="padding-top:15px;">
                +					<span class="btn btn-default" onclick="checkCache()">{{ _('Cacheprüfung','button') }}</span>
                +					<div id="cache_check" style="margin-top: 5px; width: 1000px;"></div>
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/password.svg" alt="Icon password" width="48" height="48"></td>
                +				<td colspan="2" style="padding-top:15px;">
                +					<input type="text" style="..." id="plaintext" size="20" maxlength="50"/><input type="password" style="..." id="plainpass" size="20" maxlength="50"/>
                +					<span class="btn btn-default" onclick="createHash()">{{ _('Passwort-Hash erzeugen','button') }}</span><br/>
                +					<input type="checkbox" style="..." id="showtext"  onclick="togglePlainFields();"> {{ _('Passwort anzeigen') }}
                +					<div id="hash_value" style="margin-top: 5px; width: 900px;"></div>
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/tree.png" alt="Icon cache" width="48" height="48"></td>
                +				<td colspan="2" style="padding-top:15px;">
                +					<span class="btn btn-default" onclick="checkYaml()">{{ _('YAML Syntax Checker') }}</span>
                +					<span class="btn btn-default" onclick="convertYaml()">{{ _('CONF-YAML Konverter') }}</span>
                +					<div id="yaml_check" style="margin-top: 5px; width: 1000px;"></div>
                +				</td>
                +			</tr>
                +			<tr>
                +				<td><img src="static/img/eval.svg" alt="Icon cache" width="48" height="48"></td>
                +				<td colspan="2" style="padding-top:15px;">
                +					<span class="btn btn-default" onclick="checkEval()">{{ _('Eval Syntax Checker') }}</span>
                +					<div id="yaml_check" style="margin-top: 5px; width: 1000px;"></div>
                +				</td>
                +			</tr>
                +		</tbody>
                +	</table>
                +</div>
                +<script type="text/javascript" language="javascript">
                +function checkCache() {
                +	$.getJSON("cache_check_json.html", function(result) {
                +		var temp = '<div class="table-responsive">{{ _('Dateien ohne zugehöriges Item im /var/cache Verzeichnis') }}: '+result.length;
                +		temp = temp + '<table class="table table-striped" style="border: 1px solid #ccc;">';
                +		temp = temp + '<thead><tr><th style="width: 550px;">{{ _('Dateiname') }}</th><th>{{ _('Letzte Modifikation') }}</th><th>{{ _('Erstellungsdatum') }}</th><th>{{ _('Aktionen') }}</th></td></thead><tbody>';
                +		$.each(result, function(index, element) {
                +			temp = temp + '<tr><td>'+element.filename+'</td><td>'+element.last_modified+'</td><td>'+element.created+'</td>';
                +			temp = temp + '<td><input name="delete" value="{{ _('Löschen','button') }}" type="submit" class="btn btn-default btn-xs" onClick="deleteFromCache(\''+element.filename+'\');">';
                +		});
                +		temp = temp + '</tbody></table></div>';
                +		$('#cache_check').html(temp);
                +	});
                +}
                +
                +function convertYaml() {
                +	window.location = "conf_yaml_converter.html";
                +}
                +
                +function checkYaml() {
                +	window.location = "yaml_syntax_checker.html";
                +}
                +
                +function checkEval() {
                +	window.location = "eval_syntax_checker.html";
                +}
                +
                +function deleteFromCache(filename) {
                +	var result = $.ajax( "cache_file_delete.html?filename="+filename )
                +	  .done(function() {
                +		checkCache();
                +	  })
                +}
                +
                +function createHash() {
                +	$.ajax({
                +		url: 'create_hash_json.html',
                +		type: 'GET',
                +		data: { plaintext: $('#showtext')[0].checked ? plaintext.val() : plainpass.val()} ,
                +		contentType: 'application/json; charset=utf-8',
                +		success: function (response) {
                +			$('#hash_value').html(JSON.parse(response));
                +		},
                +		error: function () {
                +			//your error code
                +		}
                +	});
                +}
                +
                +function togglePlainFields() {
                +	plaintext = $('#plaintext')
                +	plainpass = $('#plainpass')
                +	if ($('#showtext')[0].checked) {
                +		plaintext.val(plainpass.val());
                +		plainpass.hide();
                +		plaintext.show();
                +	} else {
                +		plainpass.val(plaintext.val());
                +		plaintext.hide();
                +		plainpass.show();
                +	}
                +}
                +togglePlainFields();
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/system.html b/backend/webif/templates/system.html
                new file mode 100755
                index 000000000..a49a76fb0
                --- /dev/null
                +++ b/backend/webif/templates/system.html
                @@ -0,0 +1,280 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                + <ul id="system_tabs" class="nav nav-tabs">
                +  <li class="active"><a data-toggle="tab" href="#systemproperties">{{ _('Systemeigenschaften') }}</a></li>
                +  <li id="tab_pypi" class="disabled">
                +      <a href="#pypi">
                +          {{ _('PyPI Check') }}
                +          <i id="spinner" class="fas fa-circle-notch fa-spin fa-fw"></i>
                +  </a></li>
                + </ul>
                +<div class="tab-content">
                +    <div id="systemproperties" class="tab-pane fade in active">
                +    <div class="table-responsive">
                +        <table class="table table-striped table-hover">
                +            <thead>
                +                <tr>
                +                    <th style="width: 100px;"></th>
                +                    <th style="width: 250px;">{{ _('Eigenschaft') }}</th>
                +                    <th>{{ _('Status') }}</th>
                +                </tr>
                +            </thead>
                +        <tbody>
                +            <tr>
                +                <td><img src="static/img/logo_small_76x76.png" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('SmartHomeNG Version') }}:</td>
                +                <td style="vertical-align: middle;">{{ sh_vers }}&nbsp;{{ _('in') }}&nbsp;{{ sh_dir }}&nbsp;&nbsp;-&nbsp;&nbsp;{{ _('Benutzer') }}:&nbsp;{{ user }}</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/logo_small_76x76.png" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('SmartHomeNG Plugins Version') }}:</td>
                +                <td style="vertical-align: middle;">{{ plg_vers }}&nbsp;{{ _('in') }}&nbsp;{{ sh_dir }}/plugins</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/terminal-server.svg" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">Host:</td>
                +                <td style="vertical-align: middle;">{{ node }}&nbsp;&nbsp;-&nbsp;&nbsp;IPv4: {{ ip }}<!--&nbsp;&nbsp;-&nbsp;&nbsp;IPv6: {{ ipv6 }}--></td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/tux_hdd.svg" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('Betriebssystem') }}:</td>
                +                <td style="vertical-align: middle;">{{ system }} {{ vers }}&nbsp;&nbsp;-&nbsp;&nbsp;{{ _('Architektur') }}:&nbsp;{{ arch }}</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/python.png" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('Python Version') }}:</td>
                +                <td style="vertical-align: middle;">{{ pyversion }}</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/hd.svg" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('Freier Speicher') }}:</td>
                +                <td style="vertical-align: middle;">{{ (freespace)|round|int }} MByte</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/clock.svg" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('Datum') }} / {{ _('Zeit') }}:</td>
                +                <td style="vertical-align: middle;">{{ now }}</td>
                +            </tr>
                +            <tr>
                +                <td><img src="static/img/preferences.svg" style="width: 36px; height: 36px; margin-left: 40px;"></td>
                +                <td style="vertical-align: middle;">{{ _('Betriebszeit') }}:</td>
                +                <td style="vertical-align: middle;">Host:&nbsp;{{ uptime }}&nbsp;&nbsp;-&nbsp;&nbsp;SmartHomeNG:&nbsp;{{ sh_uptime }}</td>
                +            </tr>
                +        </tbody>
                +        </table>
                +    </div>
                +    </div>
                +    <div id="pypi" class="tab-pane fade">
                +    <div class="table-responsive" >
                +        <table id="package_check" class="table table-hover">
                +            <thead>
                +                <tr>
                +                    <th style="width: 25%;">Python Package</th>
                +                    <th style="width: 25%;">{{ _('installierte Version') }}</th>
                +                    <th style="width: 25%;">{{ _('Anforderungen') }}</th>
                +                    <th style="width: 25%;">{{ _('Neuste Version') }} (PyPI)</th>
                +                </tr>
                +            </thead>
                +            <tbody>
                +            </tbody>
                +        </table>
                +    </div>
                +    </div>
                +</div>
                + <script>
                +$(".disabled").click(function (e) {
                +        e.preventDefault();
                +        return false;
                +});
                +
                +function activateTab(selector) {
                +    $(selector).on('click.twbstab',function() { $(this).tab('show'); })
                +        .closest('.disabled').removeClass('disabled');
                +}
                +
                +
                +$.getJSON('pypi.json', function(result) {
                +    $.each(result, function(index, element) {
                +        if (index == 0) {
                +            oldSort = element['sort'].substr(0,1);
                +            newSort = element['sort'].substr(0,1);
                +        } else {
                +            oldSort = newSort;
                +            newSort = newSort = element['sort'].substr(0,1);
                +        }
                +        if (oldSort != newSort) {
                +            if (element['is_required_for_testsuite']) {
                +	            $('#package_check').find("tbody").append("<tr><td style=\"font-weight:bold; background:#eee;\" colspan=\"5\">{{ _('Pakete für die Testsuite') }}</td></tr>");
                +			} else if (element['is_required_for_docbuild']) {
                +	            $('#package_check').find("tbody").append("<tr><td style=\"font-weight:bold; background:#eee;\" colspan=\"5\">{{ _('Pakete für den Bau der Dokumentation') }}</td></tr>");
                +            } else {
                +	            $('#package_check').find("tbody").append("<tr><td style=\"font-weight:bold; background:#eee;\" colspan=\"5\">{{ _('Pakete ohne Requirements') }}</td></tr>");
                +			}
                +        }
                +
                +
                +        fontWeight = '';
                +        if (element['is_required']) {
                +            fontWeight = "font-weight: bold;";
                +        }
                +
                +        var fontColorPyPi = "black";
                +        var fontColorInstalled = "";
                +        var versionInstalledIcon = "";
                +        var versionInstalledText = "{{ _('Version nicht zulässig!') }}";
                +
                +        /* color codes and icons */
                +		if (element['is_required'] || element['is_required_for_docbuild'] || element['is_required_for_testsuite'] ) {
                +	        if (element['vers_ok']) {
                +                versionInstalledIcon = "fa-check-square";
                +                versionInstalledText = "{{ _('Version unterstützt!') }}";
                +	            if (element['vers_recent']) {
                +	    	        fontColorInstalled = "green";
                +	    	        if (element['pypi_version_ok']) {
                +	                    fontColorPyPi = "black";
                +	                } else {
                +	                    fontColorPyPi = "red";
                +	                }
                +	            } else {
                +	    	        fontColorInstalled = "black";
                +					fontColorPyPi = "green";
                +	    	    }
                +        	} else {
                +            	fontColorInstalled = "red";
                +	   	        if (!element['pypi_version_ok']) {
                +                    fontColorPyPi = "red";
                +                }
                +            	var versionInstalledIcon = "fa-times-circle";
                +	        }
                +		} else {
                +		    fontColorPyPi = "black";
                +            if (element['vers_recent']) {
                +    	        fontColorInstalled = "green";
                +    	    } else {
                +			    fontColorInstalled = "black";
                +			}
                +		}
                +
                +		/* Build String for requirements column */
                +        var reqString = '';
                +        var reqTextString = '';
                +        /* MIN and MAX filled, MIN != MAX */
                +        if (element['is_required'] || element['is_required_for_docbuild'] || element['is_required_for_testsuite'] ) {
                +            if (element['vers_req_min'] != '' && element['vers_req_max'] != '' && (element['vers_req_min'] != element['vers_req_max'])) {
                +                reqString += element['vers_req_min']+" <= <i class=\"far "+versionInstalledIcon+"\" title=\"{{ _('installierte Version') }}\"></i>"
                +                if (reqString == "") {
                +                    reqString += "<i class=\"far "+versionInstalledIcon+"\" title=\""+versionInstalledText+"\" style=\"color: "+fontColorInstalled+"\"></i>";
                +                }
                +                reqString += " <= "+element['vers_req_max'];
                +            }
                +            /* ELSE: MIN and MAX filled, MIN == MAX */
                +            else if (element['vers_req_min'] != '' && element['vers_req_max'] != '' && (element['vers_req_min'] == element['vers_req_max'])) {
                +                reqString += "<i class=\"far "+versionInstalledIcon+"\" title=\""+versionInstalledText+"\"></i> == "+element['vers_req_min'];
                +            }
                +            /* ELSE: MIN or MAX filled */
                +            else {
                +                if (element['vers_req_min'] != '') {
                +                    reqString += "<i class=\"far "+versionInstalledIcon+"\" title=\""+versionInstalledText+"\"></i> "+" >= "+element['vers_req_min'];
                +                } else if (element['vers_req_max'] != '') {
                +                    reqString += "<i class=\"far "+versionInstalledIcon+"\" title=\""+versionInstalledText+"\"></i> "+"<= "+element['vers_req_max'];
                +                }
                +            }
                +            /* Element required due to Doku, Testsuite or SmartHomeNG in general, but no MIN and MAX version -> all versions valid */
                +            if (reqString == '') {
                +                reqString = "<i class=\"far "+versionInstalledIcon+"\" title=\""+versionInstalledText+"\"></i> == *";
                +            }
                +            if (element['vers_req_source'] != '') {
                +                reqTextString = element['vers_req_source'];
                +            } else {
                +                reqTextString = "";
                +            }
                +        }
                +        /* Element not required, requirements unclear, set "-" */
                +        else {
                +            reqString = "-"
                +        }
                +
                +        /* If there is detailed content, set folding layout */
                +        var foldingElement = '';
                +        var foldingStyle = '';
                +        if (reqTextString != '') {
                +            foldingStyle = "cursor: pointer;";
                +        }
                +
                +        /* Link package PyPi URL */
                +        var packageName = element['name'];
                +        if (element['pypi_doc_url'] != '') {
                +            packageName = "<a target=\"_blank\" class=\"pypi_link\" href=\""+element['pypi_doc_url']+"\">"+packageName+"</a>";
                +        }
                +
                +        /* Build row for normal content */
                +        var table_row = '';
                +        table_row =  "<tr style=\""+foldingStyle+"\" id=\""+index+"_unfold"+"\">"+
                +            "<td style=\""+fontWeight+"\">"+packageName+"</td>"+
                +            "<td style=\"color: "+fontColorInstalled+"\">"+element['vers_installed']+"</td>"+
                +            "<td>"+reqString+"</td>"+
                +            "<td style=\"color: "+fontColorPyPi+"\">"+element['pypi_version'];
                +
                +        /* Checks for icon next to PyPi Version */
                +		if (element['vers_recent'] != true && element['pypi_version_ok']) {
                +	        if ((element['pypi_version'] != '') && (element['pypi_version'] != element['vers_installed'])) {
                +	            /* Element not required? Don't set that the PyPi version is supported */
                +	            if (!element['is_required'] && !element['is_required_for_docbuild'] && !element['is_required_for_testsuite'] ) {
                +	                table_row += "&nbsp;<i class=\"fas fa-info-circle\" title=\"{{ _('Neuste Version!') }}\"></i>";
                +	            } else {
                +	                table_row += "&nbsp;<i class=\"fas fa-check-circle\" title=\"{{ _('Version unterstützt!') }}\"></i>";
                +        	    }
                +        	}
                +        } else if (element['pypi_version'] != '-' && !element['pypi_version_ok']) {
                +            table_row += "&nbsp;<i class=\"fas fa-exclamation-circle\" title=\"{{ _('Version nicht zulässig!') }}\"></i>";
                +        }
                +
                +        /* Close table row */
                +        table_row += "</td></tr>"
                +
                +        /* Build row for foldable content */
                +        var table_row_requirements_detail = '';
                +        if (reqTextString != '') {
                +            table_row_requirements_detail =
                +                "<tr id=\""+index+"_requirements_detail\" "+
                +                "style=\"display: none; "+foldingStyle+"\">";
                +            table_row_requirements_detail +=
                +                "<td colspan=\"4\">";
                +            table_row_requirements_detail +=
                +                "<div class=\"panel panel-default\" style=\"margin-bottom: 5px;\">"+
                +                "<div class=\"panel-heading\">{{ _('Anforderungen') }} (requirements.txt)</div>"+
                +                "<div class=\"panel-body\">"+reqTextString+"</div></div>";
                +            table_row_requirements_detail +=
                +                "</td></tr>";
                +        }
                +
                +        /* Append assembled content */
                +        $('#package_check').find("tbody").append(table_row + table_row_requirements_detail);
                +
                +        /* If foldable content: add onclick for table row, stop unfolding when clicking pypi link inside. */
                +        if (reqTextString != '') {
                +            $('#'+index+'_unfold').click(function(){
                +                $('#'+index+'_requirements_detail').toggle();
                +            });
                +            $('#'+index+'_requirements_detail').click(function(){
                +                $('#'+index+'_requirements_detail').toggle();
                +            });
                +            $('#'+index+'_unfold .pypi_link').click(function(e){
                +                e.stopPropagation();
                +            });
                +        }
                +    });
                +
                +    /* Hide spinner, activate tab, show DIV with content */
                +    $('#spinner').hide();
                +    $('#tab_pypi').removeClass("disabled");
                +    activateTab('#system_tabs a[href="#pypi"]');
                +});
                +</script>
                +{% endblock %}
                diff --git a/backend/webif/templates/threads.html b/backend/webif/templates/threads.html
                new file mode 100755
                index 000000000..61f02eab9
                --- /dev/null
                +++ b/backend/webif/templates/threads.html
                @@ -0,0 +1,30 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +    {{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +        <table class="table table-striped table-hover">
                +            <thead>
                +                <tr>
                +                    <th>{{ _('Thread') }} ({{ _('gesamt') }}: {{ threads_count }})</th>
                +                    <th>{{ _('Thread-Id') }}</th>
                +                    <th>{{ _('Aktiv') }}</th>
                +                </tr>
                +            </thead>
                +            <tbody>
                +                {% for t in threads  %}
                +                <tr>
                +                    <td>{{ t.name }}</td>
                +                    <td>{{ t.id }}</td>
                +                    <td>{{ _(t.alive, 'threads') }}</td>
                +                    <td width="200px"></td>
                +                </tr>
                +                {% endfor %}
                +            </tbody>
                +        </table>
                +    </div>
                +{% endblock %}
                diff --git a/backend/webif/templates/visu.html b/backend/webif/templates/visu.html
                new file mode 100755
                index 000000000..881818c6e
                --- /dev/null
                +++ b/backend/webif/templates/visu.html
                @@ -0,0 +1,57 @@
                + <!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<div class="table-responsive">
                +		<table class="table table-striped table-hover">
                +			<thead>
                +				<tr>
                +					<th width="180px">{{ _('Visu Client') }}</th>
                +					{% if visu_plugin %}
                +						<th width="80px">{{ _('IP') }}</th>
                +						<th width="50px">{{ _('Port') }}</th>
                +						{% if visu_plugin_build > '2' %}
                +							<th width="50px">{{ _('Client Software') }}</th>
                +							<th width="50px">{{ _('Browser') }}</th>
                +							<th  width="50px">{{ '' }}</th>
                +						{% else %}
                +							<th  width="50px"></th>
                +							<th  width="50px"></th>
                +							<th  width="50px"></th>
                +						{% endif %}
                +						<th width="150px"></th>
                +					{% endif %}
                +				</tr>
                +			</thead>
                +			<tbody>
                +				{% if visu_plugin %}
                +					{% if clients %}
                +						{% for client in clients %}
                +						<tr>
                +							<td>{{ client.name }}</td>
                +							<td>{{ client.ip }}</td>
                +							<td>{{ client.port }}</td>
                +							<td>{{ client.sw }} {{ client.swversion }}</td>
                +							<td>{{ client.browser }} {{ client.browserversion }}</td>
                +							<td>{{ client.hostname }}</td>
                +							<td></td>
                +						</tr>
                +						{% endfor %}
                +					{% else %}
                +						<tr>
                +							<td colspan="7">{{ _('No active clients') }}</td>
                +						</tr>
                +					{% endif %}
                +				{% else %}
                +					<tr>
                +						<td>Plugin for visu-protocol is not configured - {{ _('no data available') }}</td>
                +					</tr>
                +				{% endif %}
                +			</tbody>
                +		</table>
                +	</div>
                +{% endblock %}
                diff --git a/backend/webif/templates/yaml_syntax_checker.html b/backend/webif/templates/yaml_syntax_checker.html
                new file mode 100755
                index 000000000..3765bd4e6
                --- /dev/null
                +++ b/backend/webif/templates/yaml_syntax_checker.html
                @@ -0,0 +1,92 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% import "navbar.html" as nav with context %}
                +{% block navbar %}
                +	{{ nav }}
                +{% endblock navbar %}
                +
                +{% block content %}
                +<script src="static/codemirror/lib/codemirror.js"></script>
                +<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
                +<link rel="stylesheet" href="static/css/codemirror_custom.css">
                +<script src="static/codemirror/mode/python/python.js"></script>
                +<script src="static/codemirror/mode/yaml/yaml.js"></script>
                +<script src="static/codemirror/addon/display/rulers.js"></script>
                +
                +<style>
                +li.L0, li.L1, li.L2, li.L3,
                +li.L5, li.L6, li.L7, li.L8
                +{ list-style-type: decimal !important }
                +</style>
                +
                +<form name="input" action="yaml_syntax_checker.html" method="POST" enctype="multipart/form-data">
                +    <div class="container" style="width: 100%;">
                +		<div style="width: 48%; float: left; border: 1px solid #ccc; margin-bottom: 10px; margin-right: 5px;">
                +			<div title="{{ _('Hier den YAML Code eingeben, der geprüft werden soll.') }}">
                +    		    <div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Eingabe im .YAML Format') }}</div>
                +				<textarea id="yaml_code" name="yaml_code">{{ yaml_code }}</textarea>
                +			</div>
                +		</div>
                +    	<div style="width: 48%; float: left; border: 1px solid #ccc; margin-bottom: 10px;">
                +			<div title="{{ _('Hier wird das Ergebnis Ausdruck angezeigt.') }}">
                +				{% if output_format == 'python' %}
                +	        		<div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Ergebnis: Aufbereitet als Python Source Code') }}</div>
                +				{% else %}
                +	        		<div style="font-weight: bold; padding-left: 5px; border-bottom: 2px solid #ccc;">{{ _('Ergebnis: Aufbereitetes .YAML Format') }}</div>
                +				{% endif %}
                +    		    <textarea id="check_result" autocomplete="off" name="check_result">{{ check_result }}</textarea>
                +		    </div>
                +	    </div>
                +    </div>
                +    <div class="container" style="width: 100%;">
                +	    <input name="check" value="{{ _('Prüfen','button') }}" type="submit" class="btn btn-default btn-xs">
                +		{% if develop %}
                +		    <input name="check2" value="{{ _('Prüfen','button') }} ({{ _('Python Code Ausgabe') }})" type="submit" class="btn btn-default btn-xs">
                +		{% endif %}
                +    </div>
                +</form>
                +<script>
                +     var rulers = [];
                +     for (var i = 1; i <= 100; i++) {
                +        rulers.push({color: '#eee', column: i * 4, lineStyle: "dashed"});
                +     }
                +
                +     var myCodeMirrorConf = CodeMirror.fromTextArea(document.getElementById("yaml_code"), {
                +        lineNumbers: true,
                +        lineSeparator: '\n',
                +        indentUnit: 4,
                +        rulers: rulers,
                +        lineWrapping: false,
                +        indentWithTabs: false,
                +        mode: "yaml"
                +     });
                +     var myCodeMirrorYaml = CodeMirror.fromTextArea(document.getElementById("check_result"), {
                +        lineNumbers: true,
                +        lineSeparator: '\n',
                +        indentUnit: 4,
                +        rulers: rulers,
                +        lineWrapping: false,
                +        indentWithTabs: false,
                +        readOnly: true,
                +        mode: "{{ output_format }}"
                +     });
                +
                +     function resizeCodeMirrors() {
                +        if (!myCodeMirrorConf.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorConf.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -60 + browserHeight)+ 'px';
                +            myCodeMirrorConf.refresh();
                +        }
                +        if (!myCodeMirrorYaml.getOption("fullScreen")) {
                +            var browserHeight = $( window ).height();
                +            offsetTop = $('.CodeMirror').offset().top;
                +            myCodeMirrorYaml.getScrollerElement().style.maxHeight = ((-1)*(offsetTop) -60 + browserHeight)+ 'px';
                +            myCodeMirrorYaml.refresh();
                +        }
                +     }
                +
                +     window.addEventListener("resize", resizeCodeMirrors, false);
                +     resizeCodeMirrors();
                +</script>
                +{% endblock %}
                diff --git a/blockly/README.md b/blockly/README.md
                new file mode 100644
                index 000000000..d2b963044
                --- /dev/null
                +++ b/blockly/README.md
                @@ -0,0 +1,33 @@
                +# Blockly Logic Editor (beyond shNG v1.3)
                +
                +## Requirements
                +
                +This plugin is running under Python >= 3.4 as well as the libs cherrypy and jinja2. You can install them with:
                +```
                +(sudo apt-get install python-cherrypy)
                +sudo pip3 install cherrypy
                +(sudo apt-get install python-jinja2)
                +sudo pip3 install jinja2
                +```
                +
                +And please pay attention that the libs are installed for Python3 and not an older Python 2.7 that is probably installed on your system.
                +
                +> Note: This plugin needs the SmartHomeNG loadable module `http` to be installed/configured.
                +
                +
                +## Configuration
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +
                +```
                +# /etc/plugin.conf
                +[Blockly]
                +	plugin_name = blockly
                +```
                +
                +```yaml
                +# /etc/plugin.yaml
                +Blockly:
                +    plugin_name: blockly
                +```
                +
                diff --git a/blockly/__init__.py b/blockly/__init__.py
                new file mode 100644
                index 000000000..a001d44c8
                --- /dev/null
                +++ b/blockly/__init__.py
                @@ -0,0 +1,526 @@
                +#!/usr/bin/env python3
                +# -*- coding: utf8 -*-
                +#########################################################################
                +# Copyright 2016-       Martin Sinn                         m.sinn@gmx.de
                +#                       René Frieß                  rene.friess@gmail.com
                +#                       Dirk Wallmeier                dirk@wallmeier.info
                +#########################################################################
                +#  Blockly plugin for SmartHomeNG
                +#
                +#  This plugin is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  This plugin is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import logging
                +import socket
                +import time
                +
                +import collections
                +import ast
                +
                +import lib.config
                +from lib.model.smartplugin import SmartPlugin
                +from lib.utils import Utils
                +from lib.logic import Logics          # für update der /etc/logic.yaml
                +from lib.logic import Logic           # für reload (bytecode)
                +#import lib.logic as logics
                +
                +from .utils import *
                +
                +import lib.shyaml as shyaml
                +#from lib.constants import (YAML_FILE, CONF_FILE)
                +
                +
                +class Blockly(SmartPlugin):
                +    """
                +    Main class of the Plugin. Does all plugin specific stuff and provides
                +    the update functions for the items
                +    """
                +    
                +    PLUGIN_VERSION='1.4.0'
                +
                +
                +    def __init__(self, sh, *args, **kwargs):
                +        """
                +        Initalizes the plugin. The parameters describe for this method are pulled from the entry in plugin.conf.
                +
                +        :param sh:  **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions **beyond** 1.3: **Don't use it**! Use the method self.get_sh() instead
                +        """
                +#        self.logger = SmartPluginLogger(__name__, self)
                +        self.logger = logging.getLogger(__name__)
                +        self.logger.debug('Blockly.__init__')
                +        
                +        # attention:
                +        # if your plugin runs standalone, sh will likely be None so do not rely on it later or check it within your code
                +        
                +#        self._init_complete = False
                +#        return
                +
                +        # Initialization code goes here
                +
                +        self.init_webinterface()
                +
                +
                +    def run(self):
                +        """
                +        Run method for the plugin
                +        """        
                +        self.logger.debug("Plugin '{}': run method called".format(self.get_shortname()))
                +        self.alive = True
                +        # if you want to create child threads, do not make them daemon = True!
                +        # They will not shutdown properly. (It's a python bug)
                +
                +
                +    def stop(self):
                +        """
                +        Stop method for the plugin
                +        """
                +        self.logger.debug("Plugin '{}': stop method called".format(self.get_shortname()))
                +        self.alive = False
                +
                +
                +    def parse_item(self, item):
                +        """
                +        Default plugin parse_item method. Is called when the plugin is initialized.
                +        The plugin can, corresponding to its attribute keywords, decide what to do with
                +        the item in future, like adding it to an internal array for future reference
                +        :param item:    The item to process.
                +        :return:        If the plugin needs to be informed of an items change you should return a call back function
                +                        like the function update_item down below. An example when this is needed is the knx plugin
                +                        where parse_item returns the update_item function when the attribute knx_send is found.
                +                        This means that when the items value is about to be updated, the call back function is called
                +                        with the item, caller, source and dest as arguments and in case of the knx plugin the value
                +                        can be sent to the knx with a knx write function within the knx plugin.
                +        """
                +        if self.has_iattr(item.conf, 'foo_itemtag'):
                +            self.logger.debug("Plugin '{}': parse item: {}".format(self.get_shortname(), item))
                +
                +        # todo
                +        # if interesting item for sending values:
                +        #   return update_item
                +
                +
                +    def parse_logic(self, logic):
                +        """
                +        Default plugin parse_logic method
                +        """
                +        if 'xxx' in logic.conf:
                +            # self.function(logic['name'])
                +            pass
                +
                +
                +    def update_item(self, item, caller=None, source=None, dest=None):
                +        """
                +        Write items values
                +        :param item: item to be updated towards the plugin
                +        :param caller: if given it represents the callers name
                +        :param source: if given it represents the source
                +        :param dest: if given it represents the dest
                +        """
                +        # todo 
                +        # change 'foo_itemtag' into your attribute name
                +        if item():
                +            if self.has_iattr(item.conf, 'foo_itemtag'):
                +                self.logger.debug("Plugin '{}': update_item ws called with item '{}' from caller '{}', source '{}' and dest '{}'".format(self.get_shortname(), item, caller, source, dest))
                +            pass
                +
                +        # PLEASE CHECK CODE HERE. The following was in the old skeleton.py and seems not to be 
                +        # valid any more 
                +        # # todo here: change 'plugin' to the plugin name
                +        # if caller != 'plugin':  
                +        #    logger.info("update item: {0}".format(item.id()))
                +
                +
                +    def init_webinterface(self):
                +        """"
                +        Initialize the web interface for this plugin
                +
                +        This method is only needed if the plugin is implementing a web interface
                +        """
                +        self.mod_http = self.get_module('http')
                +        if self.mod_http == None:
                +            self.logger.error("Not initializing the web interface")
                +            return
                +        self.logger.info("Using http-module for web interface")
                +        
                +        # set application configuration for cherrypy
                +        webif_dir = self.path_join(self.get_plugin_dir(), 'webif')
                +        self.logger.info("webif_dir = '{}'".format(webif_dir))
                +        config = {
                +            '/': {
                +                'tools.staticdir.root': webif_dir,
                +            },
                +            '/static': {
                +                'tools.staticdir.on': True,
                +                'tools.staticdir.dir': 'static'
                +            }
                +        }
                +        
                +        # Register the web interface as a cherrypy app
                +        self.mod_http.register_webif(WebInterface(webif_dir, self), 
                +                                     self.get_shortname(), 
                +                                     config, 
                +                                     self.get_classname(), self.get_instance_name(),
                +                                     description='Blockly graphical logics editor for SmartHomeNG',
                +                                     webifname='')
                +                                   
                +        return True
                +
                +
                +# ------------------------------------------
                +#    Webinterface of the plugin
                +# ------------------------------------------
                +
                +import cherrypy
                +from cherrypy.lib.static import serve_file
                +from jinja2 import Environment, FileSystemLoader
                +
                +class WebInterface:
                +
                +    logics = None
                +
                +    logicname = ''
                +    logic_filename = ''
                +    cmd = ''
                +    edit_redirect = ''
                +    
                +    def __init__(self, webif_dir, plugin):
                +        """
                +        Initialization of instance of class WebInterface
                +        
                +        :param webif_dir: directory where the webinterface of the plugin resides
                +        :param plugin: instance of the plugin
                +        :type webif_dir: str
                +        :type plugin: object
                +        """
                +        self.logger = logging.getLogger(__name__)
                +        self.webif_dir = webif_dir
                +        self.plugininstance = plugin
                +        self._sh = self.plugininstance.get_sh()
                +        self._sh_dir = self._sh.base_dir
                +        self._section_prefix = self.plugininstance._parameters.get('section_prefix','')
                +        self.logger.debug("WebInterface: section_prefix = {}".format(self._section_prefix))
                +
                +        self.logger.info('Blockly Webif.__init__')
                +
                +        self.tplenv = Environment(loader=FileSystemLoader(self.plugininstance.path_join( self.webif_dir, 'templates' ) ))
                +        self.tplenv.globals['_'] = translate
                +        
                +        self.logicname = ''
                +        self.logic_filename = ''
                +
                +
                +    def html_escape(self, str):
                +        return html_escape(str)
                +
                +
                +    @cherrypy.expose
                +    def index(self):
                +
                +        return self.index_html()
                +
                +
                +#     @cherrypy.expose
                +#     def index_html(self, cmd='', filename='', logicname='', v=0):
                +# 
                +#         self.cmd = cmd.lower()
                +#         self.logger.info("index_html: cmd = {}, filename = {}, logicname = {}".format(cmd, filename, logicname))
                +#         if self.cmd == '':
                +#             self.logic_filename = ''
                +#             self.logicname = ''
                +#         elif self.cmd == 'new':
                +#             self.logic_filename = 'new'
                +#             self.logicname = ''
                +#         elif self.cmd == 'edit':
                +#             self.logic_filename = filename
                +#             self.logicname = logicname
                +#         
                +#         language = self._sh.get_defaultlanguage()
                +#         if language != get_translation_lang():
                +#             self.logger.debug("Blockly: Language = '{}' get_translation_lang() = '{}'".format(language,get_translation_lang()))
                +#             if not load_translation(language):
                +#                 self.logger.warning("Blockly: Language '{}' not found, using standard language instead".format(language))
                +# 
                +#         tmpl = self.tplenv.get_template('blockly.html')
                +#         return tmpl.render(smarthome=self._sh,
                +#                            dyn_sh_toolbox=self._DynToolbox(self._sh), 
                +#                            cmd=self.cmd,
                +#                            logicname=logicname,
                +#                            lang=translation_lang)
                +
                +
                +    @cherrypy.expose
                +    def index_html(self, cmd='', filename='', logicname='', v=0):
                +
                +        self.logger.info("index_html: cmd = '{}', filename = '{}', logicname = '{}'".format(cmd, filename, logicname))
                +        if self.edit_redirect != '':
                +            self.edit_html(cmd='edit', logicname=self.edit_redirect)
                +
                +        if self.logics is None:
                +            self.logics = Logics.get_instance()
                +
                +        cherrypy.lib.caching.expires(0)
                +
                +        if cmd == '' and filename == '' and logicname == '':
                +            cmd = self.cmd
                +            if cmd == '':
                +                cmd = 'new'
                +                        
                +        self.cmd = cmd.lower()
                +        self.logger.info("index_html: cmd = {}, filename = {}, logicname = {}".format(cmd, filename, logicname))
                +        if self.cmd == '':
                +#            self.logic_filename = ''
                +            self.logicname = ''
                +        elif self.cmd == 'new':
                +            self.logic_filename = 'new'
                +            self.logicname = ''
                +        elif self.cmd == 'edit' and filename != '':
                +            self.logic_filename = filename
                +            self.logicname = logicname
                +        self.logger.info("index_html: self.logicname = '{}', self.logic_filename = '{}'".format(self.logicname, self.logic_filename))
                +
                +        language = self._sh.get_defaultlanguage()
                +        if language != get_translation_lang():
                +            self.logger.debug("index_html: Language = '{}' get_translation_lang() = '{}'".format(language,get_translation_lang()))
                +            if not load_translation(language):
                +                self.logger.warning("index_html: Language '{}' not found, using standard language instead".format(language))
                +
                +        tmpl = self.tplenv.get_template('blockly.html')
                +        return tmpl.render(smarthome=self._sh,
                +                           dyn_sh_toolbox=self._DynToolbox(self._sh), 
                +                           cmd=self.cmd,
                +                           logicname=logicname,
                +                           timestamp=str(time.time()),
                +                           lang=translation_lang)
                +
                +
                +    @cherrypy.expose
                +    def edit_html(self, cmd='', filename='', logicname='', v=0):
                +
                +        if self.logics is None:
                +            self.logics = Logics.get_instance()
                +
                +        cherrypy.lib.caching.expires(0)
                +
                +        if cmd == '' and filename == '' and logicname == '':
                +            cmd = self.cmd
                +            if cmd == '':
                +                cmd = 'new'
                +                        
                +        self.cmd = cmd.lower()
                +        self.logger.info("edit_html: cmd = {}, filename = {}, logicname = {}".format(cmd, filename, logicname))
                +        if self.cmd == '':
                +#            self.logic_filename = ''
                +            self.logicname = ''
                +        elif self.cmd == 'new':
                +            self.logic_filename = 'new'
                +            self.logicname = ''
                +        elif self.cmd == 'edit' and filename != '':
                +            self.logic_filename = filename
                +            self.logicname = logicname
                +        self.logger.info("edit_html: self.logicname = '{}', self.logic_filename = '{}'".format(self.logicname, self.logic_filename))
                +
                +        language = self._sh.get_defaultlanguage()
                +        if language != get_translation_lang():
                +            self.logger.debug("edit_html: Language = '{}' get_translation_lang() = '{}'".format(language,get_translation_lang()))
                +            if not load_translation(language):
                +                self.logger.warning("edit_html: Language '{}' not found, using standard language instead".format(language))
                +
                +        tmpl = self.tplenv.get_template('blockly.html')
                +        return tmpl.render(smarthome=self._sh,
                +                           dyn_sh_toolbox=self._DynToolbox(self._sh), 
                +                           cmd=self.cmd,
                +                           logicname=logicname,
                +                           timestamp=str(time.time()),
                +                           lang=translation_lang)
                +
                +
                +    def _DynToolbox(self, sh):
                +        mytree = self._build_tree()
                +        return mytree + "<sep>-</sep>\n"
                +
                +
                +    def _build_tree(self):
                +        # Get top level items
                +        toplevelitems = []
                +        allitems = sorted(self._sh.return_items(), key=lambda k: str.lower(k['_path']), reverse=False)
                +        for item in allitems:
                +            if item._path.find('.') == -1:
                +                if item._path not in ['env_daily', 'env_init', 'env_loc', 'env_stat']:
                +                    toplevelitems.append(item)
                +
                +        xml = '\n'
                +        for item in toplevelitems:
                +            xml += self._build_treelevel(item)
                +#        self.logger.info("log_tree #  xml -> '{}'".format(str(xml)))
                +        return xml
                +                
                +
                +    def _build_treelevel(self, item, parent='', level=0):
                +        """
                +        Builds one tree level of the items
                +        
                +        This methods calls itself recursively while there are further child items
                +        """
                +        childitems = sorted(item.return_children(), key=lambda k: str.lower(k['_path']), reverse=False)
                +
                +        name = remove_prefix(item._path, parent+'.')
                +        if childitems != []:
                +            xml = ''
                +            if (item.type() != 'foo') or (item() != None):
                +#                self.logger.info("item._path = '{}', item.type() = '{}', item() = '{}', childitems = '{}'".format(item._path, item.type(), str(item()), childitems))
                +                xml += self._build_leaf(name, item, level+1)
                +                xml += ''.ljust(3*(level)) + '<category name="{0} ({1})">\n'.format(name, len(childitems)+1)
                +            else:
                +                xml += ''.ljust(3*(level)) + '<category name="{0} ({1})">\n'.format(name, len(childitems))
                +            for grandchild in childitems:
                +                xml += self._build_treelevel(grandchild, item._path, level+1)
                +
                +            xml += ''.ljust(3*(level)) + '</category>  # name={}\n'.format(item._path)
                +        else:
                +            xml = self._build_leaf(name, item, level)
                +        return xml
                +
                +
                +    def _build_leaf(self, name, item, level=0):
                +        """
                +        Builds the leaf information for an entry in the item tree
                +        """
                +#        n = item._path.title().replace('.','_')
                +        n = item._path
                +        xml = ''.ljust(3*(level)) + '<block type="sh_item_obj" name="' + name + '">\n'
                +        xml += ''.ljust(3*(level+1)) + '<field name="N">' + n + '</field>>\n'
                +        xml += ''.ljust(3*(level+1)) + '<field name="P">' + item._path + '</field>>\n'
                +        xml += ''.ljust(3*(level+1)) + '<field name="T">' + item.type() + '</field>>\n'
                +        xml += ''.ljust(3*(level)) + '</block>\n'
                +        return xml
                +        
                +
                +    @cherrypy.expose
                +    def blockly_close_editor(self, content=''):
                +        self.logger.warning("blockly_close_editor: content = '{}'".format(content))
                +
                +        self.logic_filename = ''
                +        return
                +        
                +
                +    @cherrypy.expose
                +    def blockly_load_logic(self, uniq_param=''):
                +        self.logger.warning("blockly_load_logic: self.logicname = '{}', self.logic_filename = '{}'".format(self.logicname, self.logic_filename))
                +        if self.logicname == '' and self.edit_redirect == '':
                +            if self.logic_filename == 'new':
                +                fn_xml = self.plugininstance.path_join( self.webif_dir, 'templates') + '/' + "new.blockly"
                +            else:
                +                fn_xml = self._sh._logic_dir + "blockly_logics.blockly"
                +        else:
                +            if self.logic_filename == '':
                +                fn_xml = self.plugininstance.path_join( self.webif_dir, 'templates') + '/' + "new.blockly"
                +            else:
                +                fn_xml = self._sh._logic_dir + self.logic_filename
                +        self.logger.warning("blockly_load_logic: fn_xml = {}".format(fn_xml))
                +        return serve_file(fn_xml, content_type='application/xml')
                +
                +
                +    def blockly_update_config(self, code, name=''):
                +        """
                +        Fill configuration section in /etc/logic.yaml from header lines in generated code
                +        
                +        Method is called from blockly_save_logic()
                +        
                +        :param code: Python code of the logic
                +        :param name: name of configuration section, if ommited, the section name is read from the source code
                +        :type code: str
                +        :type name: str
                +        """
                +        section = ''
                +        active = False
                +        config_list = []
                +        for line in code.splitlines():
                +            if (line.startswith('#comment#')):
                +                if config_list == []:
                +                    sc, fn, ac, fnco = line[9:].split('#')
                +                    fnk, fnv = fn.split(':')
                +                    ack, acv = ac.split(':')
                +                    active = Utils.to_bool(acv.strip(), False)
                +                    if section == '':
                +                        section = sc;
                +                        self.logger.info("blockly_update_config: #comment# section = '{}'".format(section))
                +                    config_list.append([fnk.strip(), fnv.strip(), fnco])
                +            elif line.startswith('#trigger#'):
                +                sc, fn, tr, co = line[9:].split('#')
                +                trk, trv = tr.split(':')
                +                if config_list == []:
                +                    fnk, fnv = fn.split(':')
                +                    fnco = ''
                +                    config_list.append([fnk.strip(), fnv.strip(), fnco])
                +                if section == '':
                +                    section = sc;
                +                    self.logger.info("blockly_update_config: #trigger# section = '{}'".format(section))
                +                config_list.append([trk.strip(), trv.strip(),co])
                +            elif line.startswith('"""'):    # initial .rst-comment reached, stop scanning
                +                break
                +            else:                           # non-metadata lines between beginning of code and initial .rst-comment
                +                pass
                +
                +        if section == '':
                +            section = name
                +        if self._section_prefix != '':
                +            section = self._section_prefix + section
                +        self.logger.info("blockly_update_config: section = '{}'".format(section))
                +
                +        self.logics.update_config_section(active, section, config_list)
                +
                +    
                +    def pretty_print_xml(self, xml_in):
                +        import xml.dom.minidom
                +
                +        xml = xml.dom.minidom.parseString(xml_in)
                +        xml_out = xml.toprettyxml()
                +        return xml_out
                +    
                +    
                +    @cherrypy.expose
                +    def blockly_save_logic(self, py, xml, name):
                +        """
                +        Save the logic - Saves the Blocky xml and the Python code
                +        
                +        :param py:
                +        :param xml:
                +        :param name:
                +        :type py:
                +        :type xml:
                +        :type name:
                +        """
                +        self._pycode = py
                +        self._xmldata = xml
                +        fn_py = self._sh._logic_dir + name.lower() + ".py"
                +        self.logic_filename = name.lower() + ".blockly"
                +        fn_xml = self._sh._logic_dir + self.logic_filename
                +        self.logger.info("blockly_save_logic: saving blockly logic {} as file {}".format(name, fn_py))
                +        self.logger.debug("blockly_save_logic: SAVE PY blockly logic {} = {}\n '{}'".format(name, fn_py, py))
                +        with open(fn_py, 'w') as fpy:
                +            fpy.write(py)
                +        self.logger.debug("blockly_save_logic: SAVE XML blockly logic {} = {}\n '{}'".format(name, fn_xml, xml))
                +        xml = self.pretty_print_xml(xml)
                +        with open(fn_xml, 'w') as fxml:
                +            fxml.write(xml)
                +
                +        self.blockly_update_config(self._pycode, name)
                +        
                +        section = name
                +        if self._section_prefix != '':
                +            section = self._section_prefix + section
                +        
                +        self.logics.load_logic(section)
                +        self.edit_redirect = name
                +        
                diff --git a/blockly/locale/de.json b/blockly/locale/de.json
                new file mode 100644
                index 000000000..f41c669c9
                --- /dev/null
                +++ b/blockly/locale/de.json
                @@ -0,0 +1,17 @@
                +{
                +	"Logik-Editor": "Logik-Editor",
                +	"für SmartHomeNG": "für SmartHomeNG",
                +	
                +	"_button": {
                +		"Aktivieren": "Aktivieren",
                +		"Beenden" : "Beenden",
                +		"Speichern" : "Speichern",
                +		"Speichern & schließen" : "Speichern & schließen",
                +		"Blöcke speichern" : "Blöcke speichern",
                +		"Verwerfen" : "Verwerfen",
                +		"Änderungen verwerfen" : "Änderungen verwerfen",
                +		"Leeren" : "Leeren",
                +		"Schließen": "Schließen"
                +	}
                +
                +}
                diff --git a/blockly/locale/en.json b/blockly/locale/en.json
                new file mode 100644
                index 000000000..d15661d86
                --- /dev/null
                +++ b/blockly/locale/en.json
                @@ -0,0 +1,17 @@
                +{
                +	"Logik-Editor": "Logic-Editor",
                +	"für SmartHomeNG": "for SmartHomeNG",
                +	
                +	"_button": {
                +		"Aktivieren": "Enable",
                +		"Beenden" : "Stop",
                +		"Speichern" : "Save",
                +		"Speichern & schließen" : "Save & Close",
                +		"Blöcke speichern" : "Save Blocks",
                +		"Verwerfen" : "Undo Changes",
                +		"Änderungen verwerfen" : "Undo Changes",
                +		"Leeren" : "Clear",
                +		"Schließen": "Close"
                +	}
                +
                +}
                diff --git a/blockly/locale/fr.json b/blockly/locale/fr.json
                new file mode 100644
                index 000000000..f94f75c44
                --- /dev/null
                +++ b/blockly/locale/fr.json
                @@ -0,0 +1,17 @@
                +{
                +	"Logik-Editor": "Editeur de Logiques",
                +	"für SmartHomeNG": "pour SmartHomeNG",
                +	
                +	"_button": {
                +		"Aktivieren": "Activer",
                +		"Beenden" : "Terminer",
                +		"Speichern" : "Sauvegarder",
                +		"Speichern & schließen" : "Sauvegarder & Fermer",
                +		"Blöcke speichern" : "Enregistrer les blocs",
                +		"Verwerfen" : "Annuler",
                +		"Änderungen verwerfen" : "Annuler modifications",
                +		"Leeren" : "Vider",
                +		"Schließen": "Fermer"
                +	}
                +
                +}
                diff --git a/blockly/locale/pl.json b/blockly/locale/pl.json
                new file mode 100644
                index 000000000..ef99ee529
                --- /dev/null
                +++ b/blockly/locale/pl.json
                @@ -0,0 +1,17 @@
                +{
                +	"Logik-Editor": "Edytor logiki",
                +	"für SmartHomeNG": "SmartHomeNG",
                +	
                +	"_button": {
                +		"Aktivieren": "Włącz",
                +		"Beenden" : "Stop",
                +		"Speichern" : "Zapisz",
                +		"Speichern & schließen" : "Zapisz & Zamknij",
                +		"Blöcke speichern" : "Zapisz Bloki",
                +		"Verwerfen" : "Cofnij Zmiany",
                +		"Änderungen verwerfen" : "Cofnij Zmiany",
                +		"Leeren" : "Wyczyść",
                +		"Schließen": "Zamknij"
                +	}
                +
                +}
                diff --git a/blockly/plugin.yaml b/blockly/plugin.yaml
                new file mode 100644
                index 000000000..9a34171f2
                --- /dev/null
                +++ b/blockly/plugin.yaml
                @@ -0,0 +1,34 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +#    subtype: core                 # plugin subtype (if applicable)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Blockly - graphischer Editor für Logiken - Noch in der Entwicklung, nicht für die Nutzung gedacht'
                +        en: 'Blockly - graphical editor for logics - Still in development, not for use'
                +    maintainer: msinn, psilo909
                +#    tester: '?'
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/959964-support-thread-für-das-backend-plugin
                +
                +    version: 1.4.0                # Plugin version
                +    sh_minversion: 1.3b            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Blockly             # class containing the plugin
                +
                +    
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    section_prefix:
                +        type: str
                +        default: blockly_
                +        description:
                +            de: 'Prefix, der dem Sektionsnamen in /etc/logic.yaml vorangstellt wird'
                +            en: 'Prefix that is added to the beginning of the section name in /etc/logic.yaml'
                +
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/blockly/requirements.txt b/blockly/requirements.txt
                new file mode 100644
                index 000000000..eba7ee030
                --- /dev/null
                +++ b/blockly/requirements.txt
                @@ -0,0 +1,3 @@
                +cherrypy>=8.1.2
                +jinja2>=2.8
                +python-dateutil>=2.5.3
                diff --git a/blockly/tests/cptestcase.py b/blockly/tests/cptestcase.py
                new file mode 100644
                index 000000000..bdeb384eb
                --- /dev/null
                +++ b/blockly/tests/cptestcase.py
                @@ -0,0 +1,102 @@
                +# -*- coding: utf-8 -*-
                +from io import BytesIO
                +import unittest
                +import urllib.request, urllib.parse, urllib.error
                +
                +import cherrypy
                +
                +# Not strictly speaking mandatory but just makes sense
                +cherrypy.config.update({'environment': "test_suite"})
                +
                +# This is mandatory so that the HTTP server isn't started
                +# if you need to actually start (why would you?), simply
                +# subscribe it back.
                +cherrypy.server.unsubscribe()
                +
                +# simulate fake socket address... they are irrelevant in our context
                +local = cherrypy.lib.httputil.Host('127.0.0.1', 50000, "")
                +remote = cherrypy.lib.httputil.Host('127.0.0.1', 50001, "")
                +
                +class BaseCherryPyTestCase(unittest.TestCase):
                +    def request(self, path='/', method='GET', app_path='', scheme='http',
                +                proto='HTTP/1.1', data=None, headers=None, **kwargs):
                +        """
                +        CherryPy does not have a facility for serverless unit testing.
                +        However this recipe demonstrates a way of doing it by
                +        calling its internal API to simulate an incoming request.
                +        This will exercise the whole stack from there.
                +
                +        Remember a couple of things:
                +
                +        * CherryPy is multithreaded. The response you will get
                +          from this method is a thread-data object attached to
                +          the current thread. Unless you use many threads from
                +          within a unit test, you can mostly forget
                +          about the thread data aspect of the response.
                +
                +        * Responses are dispatched to a mounted application's
                +          page handler, if found. This is the reason why you
                +          must indicate which app you are targetting with
                +          this request by specifying its mount point.
                +
                +        You can simulate various request settings by setting
                +        the `headers` parameter to a dictionary of headers,
                +        the request's `scheme` or `protocol`.
                +
                +        .. seealso: http://docs.cherrypy.org/stable/refman/_cprequest.html#cherrypy._cprequest.Response
                +        """
                +        # This is a required header when running HTTP/1.1
                +        h = {'Host': '127.0.0.1'}
                +
                +        if headers is not None:
                +            h.update(headers)
                +
                +        # If we have a POST/PUT request but no data
                +        # we urlencode the named arguments in **kwargs
                +        # and set the content-type header
                +        if method in ('POST', 'PUT') and not data:
                +            data = urllib.parse.urlencode(kwargs)
                +            kwargs = None
                +            h['content-type'] = 'application/x-www-form-urlencoded'
                +
                +        # If we did have named arguments, let's
                +        # urlencode them and use them as a querystring
                +        qs = None
                +        if kwargs:
                +            qs = urllib.parse.urlencode(kwargs)
                +
                +        # if we had some data passed as the request entity
                +        # let's make sure we have the content-length set
                +        fd = None
                +        if data is not None:
                +            h['content-length'] = '%d' % len(data)
                +            #fd = StringIO(data)
                +            fd = BytesIO(data.encode())
                +
                +        # Get our application and run the request against it
                +        app = cherrypy.tree.apps.get(app_path)
                +        if not app:
                +            # XXX: perhaps not the best exception to raise?
                +            raise AssertionError("No application mounted at '%s'" % app_path)
                +
                +        # Cleanup any previous returned response
                +        # between calls to this method
                +        app.release_serving()
                +
                +        # Let's fake the local and remote addresses
                +        request, response = app.get_serving(local, remote, scheme, proto)
                +        try:
                +            h = [(k, v) for k, v in h.items()]
                +            response = request.run(method, path, qs, proto, h, fd)
                +        finally:
                +            if fd:
                +                fd.close()
                +                fd = None
                +
                +        if response.output_status.startswith(b'500'):
                +            print(response.body)
                +            raise AssertionError("Unexpected error")
                +
                +        # collapse the response into a bytestring
                +        response.collapse_body()
                +        return response
                diff --git a/blockly/tests/test_backend_blocklylogics.py b/blockly/tests/test_backend_blocklylogics.py
                new file mode 100644
                index 000000000..34e3efd62
                --- /dev/null
                +++ b/blockly/tests/test_backend_blocklylogics.py
                @@ -0,0 +1,104 @@
                +# -*- coding: utf-8 -*-
                +from tests import common
                +import cherrypy
                +from bs4 import BeautifulSoup
                +
                +import lib.item
                +
                +from plugins.backend import WebInterface as Root
                +from plugins.backend.tests.cptestcase import BaseCherryPyTestCase
                +from tests.mock.core import MockSmartHome
                +
                +
                +def setUpModule():
                +#    bs = MockBackendServer()
                +#    sh = bs._sh
                +#    cherrypy.tree.mount(Root(backendserver=bs,developer_mode=True), '/')
                +#    cherrypy.engine.start()
                +    pass
                +setup_module = setUpModule
                +
                +
                +def tearDownModule():
                +#    cherrypy.engine.exit()
                +    pass
                +teardown_module = tearDownModule
                +
                +
                +class TestCherryPyApp(BaseCherryPyTestCase):
                +    def test_blockly(self):
                +        pass
                +        # dummy, because tests are from the tightly coupled 1. try do integrate blockly 
                +        # (before it became a seperate plugin)
                +        
                +#    def test_backendIntegration(self):
                +#        response = self.request('index')
                +#        self.assertEqual(response.output_status, b'200 OK')
                +#        body = BeautifulSoup(response.body[0])
                +#        self.assertEqual( str(body.find("a", href="logics.html"))[:2], '<a' )
                +        #self.assertEqual( str(body.find("a", href="logics_blockly.html"))[:2], '<a' )
                +
                +#     def test_logics_blockly_html(self):
                +#         response = self.request('logics_blockly_html')
                +#         self.assertEqual(response.output_status, b'200 OK')
                +#         resp_body = str(response.body[0],'utf-8')
                +#         self.assertRegex(resp_body, 'xml id="toolbox"')
                +#         self.assertRegex(resp_body, 'div id="content_blocks"')
                +#         self.assertRegex(resp_body, '<category name="Trigger">')
                +#         # self.assertEqual(response.body, ['hello world'])
                +
                +#     def test_DynToolbox(self):
                +#         response = self.request('logics_blockly_html')
                +#         #resp_body = str(response.body[0],'utf-8')
                +#         bs_body = BeautifulSoup(response.body[0])
                +#         #items = bs_body.find("category", name="SmartHome Items")
                +#         shItemsCat = bs_body.xml.find_all(attrs={'name': 'SmartHome Items'})[0]
                +#         # print(shItemsCat)
                +#         # print("categories: {}".format(len(list(shItemsCat.find_all("category")))) )
                +#         # print("    blocks: {}".format(len(shItemsCat.find_all("block", type="sh_item_obj") )) )
                +#         self.assertEqual(len(list(shItemsCat.find_all("block", type="sh_item_obj") )), 9 )
                +#         self.assertEqual(len(list(shItemsCat.find_all("category") )), 6 )
                +
                +#     def test_logics_blockly_load(self):
                +#         response = self.request('logics_blockly_load')
                +#         self.assertEqual(response.output_status, b'200 OK')
                +#         resp_xml = str(response.body[0],'utf-8')
                +#         #print(resp_xml)
                +#         self.assertRegex(resp_xml, '<field name="N">Unit Test</field>')
                +#         self.assertRegex(resp_xml, '<field name="P">testen.unit.test</field>')
                +#         self.assertRegex(resp_xml, '<field name="T">bool</field>')
                +
                +
                +
                +    # def test_logics_blockly_load(self):
                +    #     with open(fn_py, 'w') as fpy:
                +    #         with open(fn_xml, 'w') as fxml:
                +    #             fpy.write(py)
                +    #             fxml.write(xml)
                +
                +    # def test_echo(self):
                +    #     response = self.request('/echo', msg="hey there")
                +    #     self.assertEqual(response.output_status, '200 OK')
                +    #     self.assertEqual(response.body, ["hey there"])
                +    #
                +    #     response = self.request('/echo', method='POST', msg="back from the future")
                +    #     self.assertEqual(response.output_status, '200 OK')
                +    #     self.assertEqual(response.body, ["back from the future"])
                +    #
                +
                +
                +class MockBackendServer():
                +    _sh = MockSmartHome()
                +
                +    def __init__(self):
                +        self._sh.with_items_from(common.BASE + "/tests/resources/blockly_items.conf")
                +
                +        # HACK: Make tests work! Backend accesses private field _logic_dir
                +        # directly instead of using a method (the field was remove in the
                +        # meantime). Setting this just to make it work again.
                +        self._sh._logic_dir = common.BASE + "/tests/resources/"
                +
                +
                +if __name__ == '__main__':
                +    import unittest
                +    unittest.main()
                diff --git a/blockly/utils.py b/blockly/utils.py
                new file mode 100644
                index 000000000..2de97a46f
                --- /dev/null
                +++ b/blockly/utils.py
                @@ -0,0 +1,235 @@
                +#!/usr/bin/env python3
                +# -*- coding: utf8 -*-
                +#########################################################################
                +# Copyright 2016-       Martin Sinn                         m.sinn@gmx.de
                +#                       René Frieß                  rene.friess@gmail.com
                +#                       Bernd Meiners
                +#########################################################################
                +#  Blockly plugin for SmartHomeNG
                +#
                +#  This plugin is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  This plugin is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import logging
                +import json
                +import os
                +import collections
                +from collections import OrderedDict
                +
                +
                +# Funktionen für Jinja2 z.Zt außerhalb der Klasse Blockly, da ich Jinja2 noch nicht mit
                +# Methoden einer Klasse zum laufen bekam
                +
                +
                +# def get_basename(p):
                +#     """
                +#     returns the filename of a full pathname
                +# 
                +#     This function extends the jinja2 template engine
                +#     """
                +#     return os.path.basename(p)
                +
                +
                +def remove_prefix(string, prefix):
                +    """
                +    Remove prefix from a string
                +    
                +    :param string: String to remove the profix from
                +    :param prefix: Prefix to remove from string
                +    :type string: str
                +    :type prefix: str
                +    
                +    :return: Strting with prefix removed
                +    :rtype: str
                +    """
                +    if string.startswith(prefix):
                +        return string[len(prefix):]
                +    return string
                +
                +
                +translation_dict = {}
                +translation_dict_en = {}
                +translation_dict_de = {}
                +translation_lang = ''
                +
                +
                +def get_translation_lang():
                +    global translation_lang
                +    return translation_lang
                +
                +
                +def load_translation_backuplanguages():
                +    global translation_dict_en  # Needed to modify global copy of translation_dict
                +    global translation_dict_de  # Needed to modify global copy of translation_dict
                +
                +    logger = logging.getLogger(__name__)
                +
                +    lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + 'en' + '.json'
                +    try:
                +        f = open(lang_filename, 'r')
                +        translation_dict_en = json.load(f)
                +    except Exception as e:
                +        translation_dict_en = {}
                +        logger.error("Blockly: load_translation language='{0}' failed: Error '{1}'".format('en', e))
                +    logger.debug("Blockly: translation_dict_en='{0}'".format(translation_dict_en))
                +
                +    lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + 'de' + '.json'
                +    try:
                +        f = open(lang_filename, 'r')
                +        translation_dict_de = json.load(f)
                +    except Exception as e:
                +        translation_dict_de = {}
                +        logger.error("Blockly: load_translation language='{0}' failed: Error '{1}'".format('de', e))
                +    logger.debug("Blockly: translation_dict_de='{0}'".format(translation_dict_de))
                +
                +    return
                +
                +
                +def load_translation(language):
                +    global translation_dict  # Needed to modify global copy of translation_dict
                +    global translation_lang  # Needed to modify global copy of translation_lang
                +
                +    logger = logging.getLogger(__name__)
                +
                +    if translation_dict_en == {}:
                +        load_translation_backuplanguages()
                +
                +    translation_lang = language.lower()
                +    if translation_lang == '':
                +        translation_dict = {}
                +    else:
                +        lang_filename = os.path.dirname(os.path.abspath(__file__)) + '/locale/' + translation_lang + '.json'
                +        try:
                +            f = open(lang_filename, 'r')
                +        except Exception as e:
                +            translation_lang = ''
                +            logger.error("Blockly: load_translation language='{0}' failed: Error '{1}'".format(translation_lang, e))
                +            return False
                +        try:
                +            translation_dict = json.load(f)
                +        except Exception as e:
                +            logger.error("Blockly: load_translation language='{0}': Error '{1}'".format(translation_lang, e))
                +            return False
                +    logger.debug("Blockly: translation_dict='{0}'".format(translation_dict))
                +    return True
                +
                +
                +def html_escape(str):
                +    str = str.rstrip().replace('<', '&lt;').replace('>', '&gt;')
                +    str = str.rstrip().replace('(', '&#40;').replace(')', '&#41;')
                +    html = str.rstrip().replace("'", '&#39;').replace('"', '&quot;')
                +    return html
                +
                +
                +def _get_translation_for_block(lang, txt, block):
                +    """
                +    """
                +    if lang == 'en':
                +        blockdict = translation_dict_en.get('_' + block, {})
                +    elif lang == 'de':
                +        blockdict = translation_dict_de.get('_' + block, {})
                +    else:
                +        blockdict = translation_dict.get('_' + block, {})
                +
                +    return blockdict.get(txt, '')
                +        
                +        
                +def _get_translation(txt, block):
                +    """
                +    Get translation with fallback to english and further fallback to german
                +    """
                +    logger = logging.getLogger(__name__)
                +
                +    if block != '':
                +        tr = _get_translation_for_block('', txt, block)
                +        if tr == '':
                +            logger.info("Blockly: Language '{0}': Translation for '{1}' is missing!".format(translation_lang, txt))
                +            tr = _get_translation_for_block('en', txt, block)
                +            if tr == '':
                +                tr = _get_translation_for_block('de', txt, block)
                +    else:
                +        tr = translation_dict.get(txt, '')
                +        if tr == '':
                +            logger.info("Blockly: Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt))
                +            tr = translation_dict_en.get(txt, '')
                +            if tr == '':
                +                logger.info("Blockly: Language '{0}': Translation for '{1}' is missing".format('en', txt))
                +                tr = translation_dict_de.get(txt, '')
                +    return tr
                +    
                +
                +def translate(txt, block=''):
                +    """
                +    returns translated text
                +    
                +    This function extends the jinja2 template engine
                +    """
                +    logger = logging.getLogger(__name__)
                +
                +    txt = str(txt)
                +    if translation_lang == '':
                +        tr = txt
                +    else:
                +        tr = _get_translation(txt, block)
                +
                +        if tr == '':
                +            logger.info("Blockly: -> Language '{0}': Translation for '{1}' is missing".format(translation_lang, txt))
                +            tr = txt
                +    return html_escape(tr)
                +
                +
                +#def create_hash(plaintext):
                +#    import hashlib
                +#    hashfunc = hashlib.sha512()
                +#    hashfunc.update(plaintext.encode())
                +#    return hashfunc.hexdigest()
                +
                +
                +#def parse_requirements(file_path):
                +#    fobj = open(file_path)
                +#    req_dict = {}
                +#    for line in fobj:
                +#        if len(line) > 0 and '#' not in line:
                +#            if ">" in line:
                +#                if line[0:line.find(">")].lower().strip() in req_dict:
                +#                    req_dict[line[0:line.find(">")].lower().strip()] += " | " + line[line.find(">"):len(
                +#                        line)].lower().strip()
                +#                else:
                +#                    req_dict[line[0:line.find(">")].lower().strip()] = line[line.find(">"):len(line)].lower().strip()
                +#            elif "<" in line:
                +#                if line[0:line.find("<")].lower().strip() in req_dict:
                +#                    req_dict[line[0:line.find("<")].lower().strip()] += " | " + line[line.find("<"):len(
                +#                        line)].lower().strip()
                +#                else:
                +#                    req_dict[line[0:line.find("<")].lower().strip()] = line[line.find("<"):len(line)].lower().strip()
                +#            elif "=" in line:
                +#                if line[0:line.find("=")].lower().strip() in req_dict:
                +#                    req_dict[line[0:line.find("=")].lower().strip()] += " | " + line[line.find("="):len(
                +#                        line)].lower().strip()
                +#                else:
                +#                    req_dict[line[0:line.find("=")].lower().strip()] = line[line.find("="):len(line)].lower().strip()
                +#    fobj.close()
                +#    return req_dict
                +
                +
                +#def strip_quotes(string):
                +#    string = string.strip()
                +#    if len(string) > 0:
                +#        if string[0] in ['"', "'"]:  # check if string starts with ' or "
                +#            if string[0] == string[-1]:  # and end with it
                +#                if string.count(string[0]) == 2:  # if they are the only one
                +#                    string = string[1:-1]  # remove them
                +#    return string
                +
                +
                diff --git a/blockly/webif/static/blockly/LICENSE b/blockly/webif/static/blockly/LICENSE
                new file mode 100644
                index 000000000..6a1992987
                --- /dev/null
                +++ b/blockly/webif/static/blockly/LICENSE
                @@ -0,0 +1,177 @@
                +
                +                                 Apache License
                +                           Version 2.0, January 2011
                +                        http://www.apache.org/licenses/
                +
                +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
                +
                +   1. Definitions.
                +
                +      "License" shall mean the terms and conditions for use, reproduction,
                +      and distribution as defined by Sections 1 through 9 of this document.
                +
                +      "Licensor" shall mean the copyright owner or entity authorized by
                +      the copyright owner that is granting the License.
                +
                +      "Legal Entity" shall mean the union of the acting entity and all
                +      other entities that control, are controlled by, or are under common
                +      control with that entity. For the purposes of this definition,
                +      "control" means (i) the power, direct or indirect, to cause the
                +      direction or management of such entity, whether by contract or
                +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
                +      outstanding shares, or (iii) beneficial ownership of such entity.
                +
                +      "You" (or "Your") shall mean an individual or Legal Entity
                +      exercising permissions granted by this License.
                +
                +      "Source" form shall mean the preferred form for making modifications,
                +      including but not limited to software source code, documentation
                +      source, and configuration files.
                +
                +      "Object" form shall mean any form resulting from mechanical
                +      transformation or translation of a Source form, including but
                +      not limited to compiled object code, generated documentation,
                +      and conversions to other media types.
                +
                +      "Work" shall mean the work of authorship, whether in Source or
                +      Object form, made available under the License, as indicated by a
                +      copyright notice that is included in or attached to the work
                +      (an example is provided in the Appendix below).
                +
                +      "Derivative Works" shall mean any work, whether in Source or Object
                +      form, that is based on (or derived from) the Work and for which the
                +      editorial revisions, annotations, elaborations, or other modifications
                +      represent, as a whole, an original work of authorship. For the purposes
                +      of this License, Derivative Works shall not include works that remain
                +      separable from, or merely link (or bind by name) to the interfaces of,
                +      the Work and Derivative Works thereof.
                +
                +      "Contribution" shall mean any work of authorship, including
                +      the original version of the Work and any modifications or additions
                +      to that Work or Derivative Works thereof, that is intentionally
                +      submitted to Licensor for inclusion in the Work by the copyright owner
                +      or by an individual or Legal Entity authorized to submit on behalf of
                +      the copyright owner. For the purposes of this definition, "submitted"
                +      means any form of electronic, verbal, or written communication sent
                +      to the Licensor or its representatives, including but not limited to
                +      communication on electronic mailing lists, source code control systems,
                +      and issue tracking systems that are managed by, or on behalf of, the
                +      Licensor for the purpose of discussing and improving the Work, but
                +      excluding communication that is conspicuously marked or otherwise
                +      designated in writing by the copyright owner as "Not a Contribution."
                +
                +      "Contributor" shall mean Licensor and any individual or Legal Entity
                +      on behalf of whom a Contribution has been received by Licensor and
                +      subsequently incorporated within the Work.
                +
                +   2. Grant of Copyright License. Subject to the terms and conditions of
                +      this License, each Contributor hereby grants to You a perpetual,
                +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +      copyright license to reproduce, prepare Derivative Works of,
                +      publicly display, publicly perform, sublicense, and distribute the
                +      Work and such Derivative Works in Source or Object form.
                +
                +   3. Grant of Patent License. Subject to the terms and conditions of
                +      this License, each Contributor hereby grants to You a perpetual,
                +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +      (except as stated in this section) patent license to make, have made,
                +      use, offer to sell, sell, import, and otherwise transfer the Work,
                +      where such license applies only to those patent claims licensable
                +      by such Contributor that are necessarily infringed by their
                +      Contribution(s) alone or by combination of their Contribution(s)
                +      with the Work to which such Contribution(s) was submitted. If You
                +      institute patent litigation against any entity (including a
                +      cross-claim or counterclaim in a lawsuit) alleging that the Work
                +      or a Contribution incorporated within the Work constitutes direct
                +      or contributory patent infringement, then any patent licenses
                +      granted to You under this License for that Work shall terminate
                +      as of the date such litigation is filed.
                +
                +   4. Redistribution. You may reproduce and distribute copies of the
                +      Work or Derivative Works thereof in any medium, with or without
                +      modifications, and in Source or Object form, provided that You
                +      meet the following conditions:
                +
                +      (a) You must give any other recipients of the Work or
                +          Derivative Works a copy of this License; and
                +
                +      (b) You must cause any modified files to carry prominent notices
                +          stating that You changed the files; and
                +
                +      (c) You must retain, in the Source form of any Derivative Works
                +          that You distribute, all copyright, patent, trademark, and
                +          attribution notices from the Source form of the Work,
                +          excluding those notices that do not pertain to any part of
                +          the Derivative Works; and
                +
                +      (d) If the Work includes a "NOTICE" text file as part of its
                +          distribution, then any Derivative Works that You distribute must
                +          include a readable copy of the attribution notices contained
                +          within such NOTICE file, excluding those notices that do not
                +          pertain to any part of the Derivative Works, in at least one
                +          of the following places: within a NOTICE text file distributed
                +          as part of the Derivative Works; within the Source form or
                +          documentation, if provided along with the Derivative Works; or,
                +          within a display generated by the Derivative Works, if and
                +          wherever such third-party notices normally appear. The contents
                +          of the NOTICE file are for informational purposes only and
                +          do not modify the License. You may add Your own attribution
                +          notices within Derivative Works that You distribute, alongside
                +          or as an addendum to the NOTICE text from the Work, provided
                +          that such additional attribution notices cannot be construed
                +          as modifying the License.
                +
                +      You may add Your own copyright statement to Your modifications and
                +      may provide additional or different license terms and conditions
                +      for use, reproduction, or distribution of Your modifications, or
                +      for any such Derivative Works as a whole, provided Your use,
                +      reproduction, and distribution of the Work otherwise complies with
                +      the conditions stated in this License.
                +
                +   5. Submission of Contributions. Unless You explicitly state otherwise,
                +      any Contribution intentionally submitted for inclusion in the Work
                +      by You to the Licensor shall be under the terms and conditions of
                +      this License, without any additional terms or conditions.
                +      Notwithstanding the above, nothing herein shall supersede or modify
                +      the terms of any separate license agreement you may have executed
                +      with Licensor regarding such Contributions.
                +
                +   6. Trademarks. This License does not grant permission to use the trade
                +      names, trademarks, service marks, or product names of the Licensor,
                +      except as required for reasonable and customary use in describing the
                +      origin of the Work and reproducing the content of the NOTICE file.
                +
                +   7. Disclaimer of Warranty. Unless required by applicable law or
                +      agreed to in writing, Licensor provides the Work (and each
                +      Contributor provides its Contributions) on an "AS IS" BASIS,
                +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
                +      implied, including, without limitation, any warranties or conditions
                +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
                +      PARTICULAR PURPOSE. You are solely responsible for determining the
                +      appropriateness of using or redistributing the Work and assume any
                +      risks associated with Your exercise of permissions under this License.
                +
                +   8. Limitation of Liability. In no event and under no legal theory,
                +      whether in tort (including negligence), contract, or otherwise,
                +      unless required by applicable law (such as deliberate and grossly
                +      negligent acts) or agreed to in writing, shall any Contributor be
                +      liable to You for damages, including any direct, indirect, special,
                +      incidental, or consequential damages of any character arising as a
                +      result of this License or out of the use or inability to use the
                +      Work (including but not limited to damages for loss of goodwill,
                +      work stoppage, computer failure or malfunction, or any and all
                +      other commercial damages or losses), even if such Contributor
                +      has been advised of the possibility of such damages.
                +
                +   9. Accepting Warranty or Additional Liability. While redistributing
                +      the Work or Derivative Works thereof, You may choose to offer,
                +      and charge a fee for, acceptance of support, warranty, indemnity,
                +      or other liability obligations and/or rights consistent with this
                +      License. However, in accepting such obligations, You may act only
                +      on Your own behalf and on Your sole responsibility, not on behalf
                +      of any other Contributor, and only if You agree to indemnify,
                +      defend, and hold each Contributor harmless for any liability
                +      incurred by, or claims asserted against, such Contributor by reason
                +      of your accepting any such warranty or additional liability.
                +
                +   END OF TERMS AND CONDITIONS
                diff --git a/blockly/webif/static/blockly/README.md b/blockly/webif/static/blockly/README.md
                new file mode 100644
                index 000000000..457fb810f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/README.md
                @@ -0,0 +1,17 @@
                +# Blockly [![Build Status]( https://travis-ci.org/google/blockly.svg?branch=master)](https://travis-ci.org/google/blockly)
                +
                +
                +Google's Blockly is a web-based, visual programming editor.  Users can drag
                +blocks together to build programs.  All code is free and open source.
                +
                +**The project page is https://developers.google.com/blockly/**
                +
                +![](https://developers.google.com/blockly/images/sample.png)
                +
                +Blockly has an active [developer forum](https://groups.google.com/forum/#!forum/blockly). Please drop by and say hello. Show us your prototypes early; collectively we have a lot of experience and can offer hints which will save you time.
                +
                +Help us focus our development efforts by telling us [what you are doing with
                +Blockly](https://developers.google.com/blockly/registration). The questionnaire only takes
                +a few minutes and will help us better support the Blockly community.
                +
                +Want to contribute? Great! First, read [our guidelines for contributors](https://developers.google.com/blockly/guides/modify/contributing).
                diff --git a/blockly/webif/static/blockly/accessible/README.md b/blockly/webif/static/blockly/accessible/README.md
                new file mode 100644
                index 000000000..a69fa6667
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/README.md
                @@ -0,0 +1,54 @@
                +Accessible Blockly
                +==================
                +
                +Google's Blockly is a web-based, visual programming editor that is accessible
                +to blind users.
                +
                +The code in this directory renders a version of the Blockly toolbox and
                +workspace that is fully keyboard-navigable, and compatible with most screen
                +readers. It is optimized for NVDA on Firefox.
                +
                +In the future, Accessible Blockly may be modified to suit accessibility needs
                +other than visual impairments. Note that deaf users are expected to continue
                +using Blockly over Accessible Blockly.
                +
                +
                +Using Accessible Blockly in Your Web App
                +----------------------------------------
                +The demo at blockly/demos/accessible covers the absolute minimum required to
                +import Accessible Blockly into your web app. You will need to import the files
                +in the same order as in the demo: utils.service.js will need to be the first
                +Angular file imported.
                +
                +When the DOMContentLoaded event fires, call ng.platform.browser.bootstrap() on
                +the main component to be loaded. This will usually be blocklyApp.AppComponent,
                +but if you have another component that wraps it, use that one instead.
                +
                +
                +Customizing the Sidebar and Audio
                +---------------------------------
                +The Accessible Blockly workspace comes with a customizable sidebar.
                +
                +To customize the sidebar, you will need to declare an ACCESSIBLE_GLOBALS object
                +in the global scope that looks like this:
                +
                +    var ACCESSIBLE_GLOBALS = {
                +      mediaPathPrefix: null,
                +      customSidebarButtons: []
                +    };
                +
                +The value of mediaPathPrefix should be the location of the accessible/media
                +folder.
                +
                +The value of 'customSidebarButtons' should be a list of objects, each
                +representing buttons on the sidebar. Each of these objects should have the
                +following keys:
                +  - 'text' (the text to display on the button)
                +  - 'action' (the function that gets run when the button is clicked)
                +  - 'id' (optional; the id of the button)
                +
                +
                +Limitations
                +-----------
                +- We do not support having multiple Accessible Blockly apps in a single webpage.
                +- Accessible Blockly does not support the use of shadow blocks.
                diff --git a/blockly/webif/static/blockly/accessible/app.component.js b/blockly/webif/static/blockly/accessible/app.component.js
                new file mode 100644
                index 000000000..c31fd4259
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/app.component.js
                @@ -0,0 +1,109 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Top-level component for the Accessible Blockly application.
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.AppComponent');
                +
                +goog.require('Blockly');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.BlockOptionsModalComponent');
                +goog.require('blocklyApp.BlockOptionsModalService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.SidebarComponent');
                +goog.require('blocklyApp.ToolboxModalComponent');
                +goog.require('blocklyApp.ToolboxModalService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +goog.require('blocklyApp.UtilsService');
                +goog.require('blocklyApp.VariableAddModalComponent');
                +goog.require('blocklyApp.VariableModalService');
                +goog.require('blocklyApp.VariableRenameModalComponent');
                +goog.require('blocklyApp.VariableRemoveModalComponent');
                +goog.require('blocklyApp.WorkspaceComponent');
                +
                +
                +blocklyApp.workspace = new Blockly.Workspace();
                +
                +blocklyApp.AppComponent = ng.core.Component({
                +  selector: 'blockly-app',
                +  template: `
                +    <blockly-workspace></blockly-workspace>
                +    <blockly-sidebar></blockly-sidebar>
                +    <!-- Warning: Hiding this when there is no content looks visually nicer,
                +    but it can have unexpected side effects. In particular, it sometimes stops
                +    screenreaders from reading anything in this div. -->
                +    <div class="blocklyAriaLiveStatus">
                +      <span aria-live="polite" role="status">{{getAriaLiveReadout()}}</span>
                +    </div>
                +
                +    <blockly-add-variable-modal></blockly-add-variable-modal>
                +    <blockly-rename-variable-modal></blockly-rename-variable-modal>
                +    <blockly-remove-variable-modal></blockly-remove-variable-modal>
                +    <blockly-toolbox-modal></blockly-toolbox-modal>
                +    <blockly-block-options-modal></blockly-block-options-modal>
                +
                +    <label id="blockly-translate-button" aria-hidden="true" hidden>
                +      {{'BUTTON'|translate}}
                +    </label>
                +    <label id="blockly-translate-workspace-block" aria-hidden="true" hidden>
                +      {{'WORKSPACE_BLOCK'|translate}}
                +    </label>
                +  `,
                +  directives: [
                +    blocklyApp.BlockOptionsModalComponent,
                +    blocklyApp.SidebarComponent,
                +    blocklyApp.ToolboxModalComponent,
                +    blocklyApp.VariableAddModalComponent,
                +    blocklyApp.VariableRenameModalComponent,
                +    blocklyApp.VariableRemoveModalComponent,
                +    blocklyApp.WorkspaceComponent
                +  ],
                +  pipes: [blocklyApp.TranslatePipe],
                +  // All services are declared here, so that all components in the application
                +  // use the same instance of the service.
                +  // https://www.sitepoint.com/angular-2-components-providers-classes-factories-values/
                +  providers: [
                +    blocklyApp.AudioService,
                +    blocklyApp.BlockConnectionService,
                +    blocklyApp.BlockOptionsModalService,
                +    blocklyApp.KeyboardInputService,
                +    blocklyApp.NotificationsService,
                +    blocklyApp.ToolboxModalService,
                +    blocklyApp.TreeService,
                +    blocklyApp.UtilsService,
                +    blocklyApp.VariableModalService
                +  ]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.NotificationsService, function(notificationsService) {
                +      this.notificationsService = notificationsService;
                +    }
                +  ],
                +  getAriaLiveReadout: function() {
                +    return this.notificationsService.getDisplayedMessage();
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/audio.service.js b/blockly/webif/static/blockly/accessible/audio.service.js
                new file mode 100644
                index 000000000..4f7eb4f08
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/audio.service.js
                @@ -0,0 +1,96 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for playing audio files.
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.AudioService');
                +
                +goog.require('blocklyApp.NotificationsService');
                +
                +
                +blocklyApp.AudioService = ng.core.Class({
                +  constructor: [
                +    blocklyApp.NotificationsService, function(notificationsService) {
                +      this.notificationsService = notificationsService;
                +
                +      // We do not play any audio unless a media path prefix is specified.
                +      this.canPlayAudio = false;
                +
                +      if (ACCESSIBLE_GLOBALS.hasOwnProperty('mediaPathPrefix')) {
                +        this.canPlayAudio = true;
                +        var mediaPathPrefix = ACCESSIBLE_GLOBALS['mediaPathPrefix'];
                +        this.AUDIO_PATHS_ = {
                +          'connect': mediaPathPrefix + 'click.mp3',
                +          'delete': mediaPathPrefix + 'delete.mp3',
                +          'oops': mediaPathPrefix + 'oops.mp3'
                +        };
                +      }
                +
                +      this.cachedAudioFiles_ = {};
                +      // Store callback references here so that they can be removed if a new
                +      // call to this.play_() comes in.
                +      this.onEndedCallbacks_ = {
                +        'connect': [],
                +        'delete': [],
                +        'oops': []
                +      };
                +    }
                +  ],
                +  play_: function(audioId, onEndedCallback) {
                +    if (this.canPlayAudio) {
                +      if (!this.cachedAudioFiles_.hasOwnProperty(audioId)) {
                +        this.cachedAudioFiles_[audioId] = new Audio(this.AUDIO_PATHS_[audioId]);
                +      }
                +
                +      if (onEndedCallback) {
                +        this.onEndedCallbacks_[audioId].push(onEndedCallback);
                +        this.cachedAudioFiles_[audioId].addEventListener(
                +            'ended', onEndedCallback);
                +      } else {
                +        var that = this;
                +        this.onEndedCallbacks_[audioId].forEach(function(callback) {
                +          that.cachedAudioFiles_[audioId].removeEventListener(
                +              'ended', callback);
                +        });
                +        this.onEndedCallbacks_[audioId].length = 0;
                +      }
                +
                +      this.cachedAudioFiles_[audioId].play();
                +    }
                +  },
                +  playConnectSound: function() {
                +    this.play_('connect');
                +  },
                +  playDeleteSound: function() {
                +    this.play_('delete');
                +  },
                +  playOopsSound: function(optionalStatusMessage) {
                +    if (optionalStatusMessage) {
                +      var that = this;
                +      this.play_('oops', function() {
                +        that.notificationsService.speak(optionalStatusMessage);
                +      });
                +    } else {
                +      this.play_('oops');
                +    }
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/block-connection.service.js b/blockly/webif/static/blockly/accessible/block-connection.service.js
                new file mode 100644
                index 000000000..c1ee03aac
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/block-connection.service.js
                @@ -0,0 +1,135 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for handling the mechanics of how blocks
                + * get connected to each other.
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.BlockConnectionService');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.NotificationsService');
                +
                +
                +blocklyApp.BlockConnectionService = ng.core.Class({
                +  constructor: [
                +      blocklyApp.NotificationsService, blocklyApp.AudioService,
                +      function(_notificationsService, _audioService) {
                +    this.notificationsService = _notificationsService;
                +    this.audioService = _audioService;
                +
                +    // When a user "adds a link" to a block, the connection representing this
                +    // link is stored here.
                +    this.markedConnection_ = null;
                +  }],
                +  findCompatibleConnection_: function(block, targetConnection) {
                +    // Locates and returns a connection on the given block that is compatible
                +    // with the target connection, if one exists. Returns null if no such
                +    // connection exists.
                +    // Note: the targetConnection is assumed to be the markedConnection_, or
                +    // possibly its counterpart (in the case where the marked connection is
                +    // currently attached to another connection). This method therefore ignores
                +    // input connections on the given block, since one doesn't usually mark an
                +    // output connection and attach a block to it.
                +    if (!targetConnection || !targetConnection.getSourceBlock().workspace) {
                +      return null;
                +    }
                +
                +    var desiredType = Blockly.OPPOSITE_TYPE[targetConnection.type];
                +    var potentialConnection = (
                +        desiredType == Blockly.OUTPUT_VALUE ? block.outputConnection :
                +        desiredType == Blockly.PREVIOUS_STATEMENT ? block.previousConnection :
                +        desiredType == Blockly.NEXT_STATEMENT ? block.nextConnection :
                +        null);
                +
                +    if (potentialConnection &&
                +        potentialConnection.checkType_(targetConnection)) {
                +      return potentialConnection;
                +    } else {
                +      return null;
                +    }
                +  },
                +  isAnyConnectionMarked: function() {
                +    return Boolean(this.markedConnection_);
                +  },
                +  getMarkedConnectionSourceBlock: function() {
                +    return this.markedConnection_ ?
                +        this.markedConnection_.getSourceBlock() : null;
                +  },
                +  canBeAttachedToMarkedConnection: function(block) {
                +    return Boolean(
                +        this.findCompatibleConnection_(block, this.markedConnection_));
                +  },
                +  canBeMovedToMarkedConnection: function(block) {
                +    if (!this.markedConnection_) {
                +      return false;
                +    }
                +
                +    // It should not be possible to move any ancestor of the block containing
                +    // the marked connection to the marked connection.
                +    var ancestorBlock = this.getMarkedConnectionSourceBlock();
                +    while (ancestorBlock) {
                +      if (ancestorBlock.id == block.id) {
                +        return false;
                +      }
                +      ancestorBlock = ancestorBlock.getParent();
                +    }
                +
                +    return this.canBeAttachedToMarkedConnection(block);
                +  },
                +  markConnection: function(connection) {
                +    this.markedConnection_ = connection;
                +    this.notificationsService.speak(Blockly.Msg.ADDED_LINK_MSG);
                +  },
                +  attachToMarkedConnection: function(block) {
                +    var xml = Blockly.Xml.blockToDom(block);
                +    var reconstitutedBlock = Blockly.Xml.domToBlock(blocklyApp.workspace, xml);
                +
                +    var targetConnection = null;
                +    if (this.markedConnection_.targetBlock() &&
                +        this.markedConnection_.type == Blockly.PREVIOUS_STATEMENT) {
                +      // Is the marked connection a 'previous' connection that is already
                +      // connected? If so, find the block that's currently connected to it, and
                +      // use that block's 'next' connection as the new marked connection.
                +      // Otherwise, splicing does not happen correctly, and inserting a block
                +      // in the middle of a group of two linked blocks will split the group.
                +      targetConnection = this.markedConnection_.targetConnection;
                +    } else {
                +      targetConnection = this.markedConnection_;
                +    }
                +
                +    var connection = this.findCompatibleConnection_(
                +      reconstitutedBlock, targetConnection);
                +    if (connection) {
                +      targetConnection.connect(connection);
                +
                +      this.markedConnection_ = null;
                +      this.audioService.playConnectSound();
                +      return reconstitutedBlock.id;
                +    } else {
                +      // We throw an error here, because we expect any UI controls that would
                +      // result in a non-connection to be disabled or hidden.
                +      throw Error(
                +          'Unable to connect block to marked connection. This should not ' +
                +          'happen.');
                +    }
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/block-options-modal.component.js b/blockly/webif/static/blockly/accessible/block-options-modal.component.js
                new file mode 100644
                index 000000000..6ac7975b5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/block-options-modal.component.js
                @@ -0,0 +1,146 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component that represents the block options modal.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.BlockOptionsModalComponent');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.BlockOptionsModalService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.TranslatePipe');
                +
                +goog.require('Blockly.CommonModal');
                +
                +
                +blocklyApp.BlockOptionsModalComponent = ng.core.Component({
                +  selector: 'blockly-block-options-modal',
                +  template: `
                +    <div *ngIf="modalIsVisible" class="blocklyModalCurtain"
                +         (click)="dismissModal()">
                +      <!-- $event.stopPropagation() prevents the modal from closing when its
                +      interior is clicked. -->
                +      <div id="blockOptionsModal" class="blocklyModal" role="alertdialog"
                +           (click)="$event.stopPropagation()" tabindex="-1"
                +           aria-labelledby="blockOptionsModalHeading">
                +        <h3 id="blockOptionsModalHeading">{{'BLOCK_OPTIONS'|translate}}</h3>
                +        <div role="document">
                +          <div class="blocklyModalButtonContainer"
                +               *ngFor="#buttonInfo of actionButtonsInfo; #buttonIndex=index">
                +            <button [id]="getOptionId(buttonIndex)"
                +                    (click)="buttonInfo.action(); hideModal();"
                +                    [ngClass]="{activeButton: activeButtonIndex == buttonIndex}">
                +              {{buttonInfo.translationIdForText|translate}}
                +            </button>
                +          </div>
                +        </div>
                +
                +        <div class="blocklyModalButtonContainer">
                +          <button [id]="getCancelOptionId()"
                +                  (click)="dismissModal()"
                +                  [ngClass]="{activeButton: activeButtonIndex == actionButtonsInfo.length}">
                +            {{'CANCEL'|translate}}
                +          </button>
                +        </div>
                +      </div>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.BlockOptionsModalService, blocklyApp.KeyboardInputService,
                +    blocklyApp.AudioService,
                +    function(blockOptionsModalService_, keyboardInputService_, audioService_) {
                +      this.blockOptionsModalService = blockOptionsModalService_;
                +      this.keyboardInputService = keyboardInputService_;
                +      this.audioService = audioService_;
                +
                +      this.modalIsVisible = false;
                +      this.actionButtonsInfo = [];
                +      this.activeButtonIndex = -1;
                +      this.onDismissCallback = null;
                +
                +      var that = this;
                +      this.blockOptionsModalService.registerPreShowHook(
                +        function(newActionButtonsInfo, onDismissCallback) {
                +          that.modalIsVisible = true;
                +          that.actionButtonsInfo = newActionButtonsInfo;
                +          that.activeActionButtonIndex = -1;
                +          that.onDismissCallback = onDismissCallback;
                +
                +          Blockly.CommonModal.setupKeyboardOverrides(that);
                +          that.keyboardInputService.addOverride('13', function(evt) {
                +              evt.preventDefault();
                +              evt.stopPropagation();
                +
                +              if (that.activeButtonIndex == -1) {
                +                return;
                +              }
                +
                +              var button = document.getElementById(
                +                  that.getOptionId(that.activeButtonIndex));
                +              if (that.activeButtonIndex <
                +                  that.actionButtonsInfo.length) {
                +                that.actionButtonsInfo[that.activeButtonIndex].action();
                +              } else {
                +                that.dismissModal();
                +              }
                +
                +              that.hideModal();
                +            });
                +
                +          setTimeout(function() {
                +            document.getElementById('blockOptionsModal').focus();
                +          }, 150);
                +        }
                +      );
                +    }
                +  ],
                +  focusOnOption: function(index) {
                +    var button = document.getElementById(this.getOptionId(index));
                +    button.focus();
                +  },
                +  // Counts the number of interactive elements for the modal.
                +  numInteractiveElements: function() {
                +    return this.actionButtonsInfo.length + 1;
                +  },
                +  // Returns the ID for the corresponding option button.
                +  getOptionId: function(index) {
                +    return 'block-options-modal-option-' + index;
                +  },
                +  // Returns the ID for the "cancel" option button.
                +  getCancelOptionId: function() {
                +    return this.getOptionId(this.actionButtonsInfo.length);
                +  },
                +  dismissModal: function() {
                +    this.onDismissCallback();
                +    this.hideModal();
                +  },
                +  // Closes the modal.
                +  hideModal: function() {
                +    this.modalIsVisible = false;
                +    this.keyboardInputService.clearOverride();
                +    this.blockOptionsModalService.hideModal();
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/block-options-modal.service.js b/blockly/webif/static/blockly/accessible/block-options-modal.service.js
                new file mode 100644
                index 000000000..ad775c6d4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/block-options-modal.service.js
                @@ -0,0 +1,62 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for the block options modal.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.BlockOptionsModalService');
                +
                +
                +blocklyApp.BlockOptionsModalService = ng.core.Class({
                +  constructor: [function() {
                +    this.actionButtonsInfo = [];
                +    // The aim of the pre-show hook is to populate the modal component with the
                +    // information it needs to display the modal (e.g., which action buttons to
                +    // display).
                +    this.preShowHook = function() {
                +      throw Error(
                +          'A pre-show hook must be defined for the block options modal ' +
                +          'before it can be shown.');
                +    };
                +    this.modalIsShown = false;
                +    this.onDismissCallback = null;
                +  }],
                +  registerPreShowHook: function(preShowHook) {
                +    var that = this;
                +    this.preShowHook = function() {
                +      preShowHook(that.actionButtonsInfo, that.onDismissCallback);
                +    };
                +  },
                +  isModalShown: function() {
                +    return this.modalIsShown;
                +  },
                +  showModal: function(actionButtonsInfo, onDismissCallback) {
                +    this.actionButtonsInfo = actionButtonsInfo;
                +    this.onDismissCallback = onDismissCallback;
                +
                +    this.preShowHook();
                +    this.modalIsShown = true;
                +  },
                +  hideModal: function() {
                +    this.modalIsShown = false;
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/commonModal.js b/blockly/webif/static/blockly/accessible/commonModal.js
                new file mode 100644
                index 000000000..57e88b529
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/commonModal.js
                @@ -0,0 +1,77 @@
                +goog.provide('Blockly.CommonModal');
                +
                +
                +Blockly.CommonModal = function() {};
                +
                +Blockly.CommonModal.setupKeyboardOverrides = function(component) {
                +  component.keyboardInputService.setOverride({
                +    // Tab key: navigates to the previous or next item in the list.
                +    '9': function(evt) {
                +      evt.preventDefault();
                +      evt.stopPropagation();
                +
                +      if (evt.shiftKey) {
                +        // Move to the previous item in the list.
                +        if (component.activeButtonIndex <= 0) {
                +          component.activeActionButtonIndex = 0;
                +          component.audioService.playOopsSound();
                +        } else {
                +          component.activeButtonIndex--;
                +        }
                +      } else {
                +        // Move to the next item in the list.
                +        if (component.activeButtonIndex == component.numInteractiveElements(component) - 1) {
                +          component.audioService.playOopsSound();
                +        } else {
                +          component.activeButtonIndex++;
                +        }
                +      }
                +
                +      component.focusOnOption(component.activeButtonIndex, component);
                +    },
                +    // Escape key: closes the modal.
                +    '27': function() {
                +      component.dismissModal();
                +    },
                +    // Up key: no-op.
                +    '38': function(evt) {
                +      evt.preventDefault();
                +    },
                +    // Down key: no-op.
                +    '40': function(evt) {
                +      evt.preventDefault();
                +    }
                +  });
                +}
                +
                +Blockly.CommonModal.getInteractiveElements = function(component) {
                +  return Array.prototype.filter.call(
                +    component.getInteractiveContainer().elements, function(element) {
                +    if (element.type === 'hidden') {
                +      return false;
                +    }
                +    if (element.disabled) {
                +      return false;
                +    }
                +    if (element.tabIndex < 0) {
                +      return false;
                +    }
                +    return true;
                +  });
                +};
                +
                +Blockly.CommonModal.numInteractiveElements = function(component) {
                +  var elements = this.getInteractiveElements(component);
                +  return elements.length;
                +};
                +
                +Blockly.CommonModal.focusOnOption = function(index, component) {
                +  var elements = this.getInteractiveElements(component);
                +  var button = elements[index];
                +  button.focus();
                +};
                +
                +Blockly.CommonModal.hideModal = function() {
                +  this.modalIsVisible = false;
                +  this.keyboardInputService.clearOverride();
                +};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/accessible/field-segment.component.js b/blockly/webif/static/blockly/accessible/field-segment.component.js
                new file mode 100644
                index 000000000..8dda20d71
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/field-segment.component.js
                @@ -0,0 +1,206 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component that renders a "field segment" (a group
                + * of non-editable Blockly.Field followed by 0 or 1 editable Blockly.Field)
                + * in a block. Also handles any interactions with the field.
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.FieldSegmentComponent');
                +
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.VariableModalService');
                +
                +
                +blocklyApp.FieldSegmentComponent = ng.core.Component({
                +  selector: 'blockly-field-segment',
                +  template: `
                +    <template [ngIf]="!mainField">
                +      <label [id]="mainFieldId">{{getPrefixText()}}</label>
                +    </template>
                +
                +    <template [ngIf]="mainField">
                +      <template [ngIf]="isTextInput()">
                +        {{getPrefixText()}}
                +        <input [id]="mainFieldId" type="text"
                +               [ngModel]="mainField.getValue()" (ngModelChange)="setTextValue($event)"
                +               [attr.aria-label]="getFieldDescription() + '. ' + ('PRESS_ENTER_TO_EDIT_TEXT'|translate)"
                +               tabindex="-1">
                +      </template>
                +
                +      <template [ngIf]="isNumberInput()">
                +        {{getPrefixText()}}
                +        <input [id]="mainFieldId" type="number"
                +               [ngModel]="mainField.getValue()" (ngModelChange)="setNumberValue($event)"
                +               [attr.aria-label]="getFieldDescription() + '. ' + ('PRESS_ENTER_TO_EDIT_NUMBER'|translate)"
                +               tabindex="-1">
                +      </template>
                +
                +      <template [ngIf]="isDropdown()">
                +        {{getPrefixText()}}
                +        <select [id]="mainFieldId" [name]="mainFieldId"
                +                [ngModel]="selectedOption" (ngModelChange)="setDropdownValue($event)"
                +                (keydown.enter)="selectOption()"
                +                tabindex="-1">
                +          <option *ngFor="#option of dropdownOptions" value="{{option.value}}">
                +            {{option.text}}
                +          </option>
                +        </select>
                +      </template>
                +    </template>
                +  `,
                +  inputs: ['prefixFields', 'mainField', 'mainFieldId', 'level'],
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +      blocklyApp.NotificationsService,
                +      blocklyApp.VariableModalService,
                +      function(notificationsService, variableModalService) {
                +    this.notificationsService = notificationsService;
                +    this.variableModalService = variableModalService;
                +    this.dropdownOptions = [];
                +    this.rawOptions = [];
                +  }],
                +  // Angular2 hook - called after initialization.
                +  ngAfterContentInit: function() {
                +    if (this.mainField) {
                +      this.mainField.initModel();
                +    }
                +  },
                +  // Angular2 hook - called to check if the cached component needs an update.
                +  ngDoCheck: function() {
                +    if (this.isDropdown() && this.shouldBreakCache()) {
                +      this.optionValue = this.mainField.getValue();
                +      this.fieldValue = this.mainField.getValue();
                +      this.rawOptions = this.mainField.getOptions();
                +      this.dropdownOptions = this.rawOptions.map(function(valueAndText) {
                +        return {
                +          text: valueAndText[0],
                +          value: valueAndText[1]
                +        };
                +      });
                +
                +      // Set the currently selected value to the variable on the field.
                +      for (var i = 0; i < this.dropdownOptions.length; i++) {
                +        if (this.dropdownOptions[i].text === this.fieldValue) {
                +          this.selectedOption = this.dropdownOptions[i].value;
                +        }
                +      }
                +    }
                +  },
                +  // Returns whether the mutable, cached information needs to be refreshed.
                +  shouldBreakCache: function() {
                +    var newOptions = this.mainField.getOptions();
                +    if (newOptions.length != this.rawOptions.length) {
                +      return true;
                +    }
                +
                +    for (var i = 0; i < this.rawOptions.length; i++) {
                +      // Compare the value of the cached options with the values in the field.
                +      if (newOptions[i][0] != this.rawOptions[i][0]) {
                +        return true;
                +      }
                +    }
                +
                +    if (this.fieldValue != this.mainField.getValue()) {
                +      return true;
                +    }
                +
                +    return false;
                +  },
                +  // Gets the prefix text, to be printed before a field.
                +  getPrefixText: function() {
                +    var prefixTexts = this.prefixFields.map(function(prefixField) {
                +      return prefixField.getText();
                +    });
                +    return prefixTexts.join(' ');
                +  },
                +  // Gets the description, for labeling a field.
                +  getFieldDescription: function() {
                +    var description = this.mainField.getText();
                +    if (this.prefixFields.length > 0) {
                +      description = this.getPrefixText() + ': ' + description;
                +    }
                +    return description;
                +  },
                +  // Returns true if the field is text input, false otherwise.
                +  isTextInput: function() {
                +    return this.mainField instanceof Blockly.FieldTextInput &&
                +        !(this.mainField instanceof Blockly.FieldNumber);
                +  },
                +  // Returns true if the field is number input, false otherwise.
                +  isNumberInput: function() {
                +    return this.mainField instanceof Blockly.FieldNumber;
                +  },
                +  // Returns true if the field is a dropdown, false otherwise.
                +  isDropdown: function() {
                +    return this.mainField instanceof Blockly.FieldDropdown;
                +  },
                +  // Sets the text value on the underlying field.
                +  setTextValue: function(newValue) {
                +    this.mainField.setValue(newValue);
                +  },
                +  // Sets the number value on the underlying field.
                +  setNumberValue: function(newValue) {
                +    // Do not permit a residual value of NaN after a backspace event.
                +    this.mainField.setValue(newValue || 0);
                +  },
                +  // Confirm a selection for dropdown fields.
                +  selectOption: function() {
                +    if (this.optionValue != Blockly.RENAME_VARIABLE_ID && this.optionValue !=
                +        Blockly.DELETE_VARIABLE_ID) {
                +      this.mainField.setValue(this.optionValue);
                +    }
                +
                +    if (this.optionValue == Blockly.RENAME_VARIABLE_ID) {
                +      this.variableModalService.showRenameModal_(this.mainField.getValue());
                +    }
                +
                +    if (this.optionValue == Blockly.DELETE_VARIABLE_ID) {
                +      this.variableModalService.showRemoveModal_(this.mainField.getValue());
                +    }
                +  },
                +  // Sets the value on a dropdown input.
                +  setDropdownValue: function(optionValue) {
                +    this.optionValue = optionValue
                +    if (this.optionValue == 'NO_ACTION') {
                +      return;
                +    }
                +
                +    var optionText = undefined;
                +    for (var i = 0; i < this.dropdownOptions.length; i++) {
                +      if (this.dropdownOptions[i].value == optionValue) {
                +        optionText = this.dropdownOptions[i].text;
                +        break;
                +      }
                +    }
                +
                +    if (!optionText) {
                +      throw Error(
                +          'There is no option text corresponding to the value: ' +
                +          this.optionValue);
                +    }
                +
                +    this.notificationsService.speak('Selected option ' + optionText);
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/keyboard-input.service.js b/blockly/webif/static/blockly/accessible/keyboard-input.service.js
                new file mode 100644
                index 000000000..638275637
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/keyboard-input.service.js
                @@ -0,0 +1,58 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for handling keyboard input.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.KeyboardInputService');
                +
                +
                +blocklyApp.KeyboardInputService = ng.core.Class({
                +  constructor: [function() {
                +    // Default custom actions for global keystrokes. The keys of this object
                +    // are string representations of the key codes.
                +    this.keysToActions = {};
                +    // Override for the default keysToActions mapping (e.g. in a modal
                +    // context).
                +    this.keysToActionsOverride = null;
                +
                +    // Attach a keydown handler to the entire window.
                +    var that = this;
                +    document.addEventListener('keydown', function(evt) {
                +      var stringifiedKeycode = String(evt.keyCode);
                +      var actionsObject = that.keysToActionsOverride || that.keysToActions;
                +
                +      if (actionsObject.hasOwnProperty(stringifiedKeycode)) {
                +        actionsObject[stringifiedKeycode](evt);
                +      }
                +    });
                +  }],
                +  setOverride: function(newKeysToActions) {
                +    this.keysToActionsOverride = newKeysToActions;
                +  },
                +  addOverride: function(keyCode, action) {
                +    this.keysToActionsOverride[keyCode] = action;
                +  },
                +  clearOverride: function() {
                +    this.keysToActionsOverride = null;
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/libs/README b/blockly/webif/static/blockly/accessible/libs/README
                new file mode 100644
                index 000000000..ebf4d96ba
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/libs/README
                @@ -0,0 +1,15 @@
                +This folder contains the following dependencies for accessible Blockly:
                +
                +* Angular2 (angular2-all.umd.min.js, angular2-polyfills.min.js)
                +* RxJava (Rx.umd.min)
                +
                +Used for data binding between the core Blockly workspace and accessible Blockly.
                +RxJava is required by Angular2.
                +Fetched from https://code.angularjs.org/
                +The current version is 2.0.0-beta.16.
                +
                +* ES6 Shim
                +
                +Required by Angular2, for Javascript files.
                +Fetched from https://github.com/paulmillr/es6-shim
                +The current version is 0.35.1.
                diff --git a/blockly/webif/static/blockly/accessible/libs/Rx.umd.min.js b/blockly/webif/static/blockly/accessible/libs/Rx.umd.min.js
                new file mode 100644
                index 000000000..38c0666b4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/libs/Rx.umd.min.js
                @@ -0,0 +1,748 @@
                +/**
                +                               Apache License
                +                         Version 2.0, January 2004
                +                      http://www.apache.org/licenses/
                +
                + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
                +
                + 1. Definitions.
                +
                +    "License" shall mean the terms and conditions for use, reproduction,
                +    and distribution as defined by Sections 1 through 9 of this document.
                +
                +    "Licensor" shall mean the copyright owner or entity authorized by
                +    the copyright owner that is granting the License.
                +
                +    "Legal Entity" shall mean the union of the acting entity and all
                +    other entities that control, are controlled by, or are under common
                +    control with that entity. For the purposes of this definition,
                +    "control" means (i) the power, direct or indirect, to cause the
                +    direction or management of such entity, whether by contract or
                +    otherwise, or (ii) ownership of fifty percent (50%) or more of the
                +    outstanding shares, or (iii) beneficial ownership of such entity.
                +
                +    "You" (or "Your") shall mean an individual or Legal Entity
                +    exercising permissions granted by this License.
                +
                +    "Source" form shall mean the preferred form for making modifications,
                +    including but not limited to software source code, documentation
                +    source, and configuration files.
                +
                +    "Object" form shall mean any form resulting from mechanical
                +    transformation or translation of a Source form, including but
                +    not limited to compiled object code, generated documentation,
                +    and conversions to other media types.
                +
                +    "Work" shall mean the work of authorship, whether in Source or
                +    Object form, made available under the License, as indicated by a
                +    copyright notice that is included in or attached to the work
                +    (an example is provided in the Appendix below).
                +
                +    "Derivative Works" shall mean any work, whether in Source or Object
                +    form, that is based on (or derived from) the Work and for which the
                +    editorial revisions, annotations, elaborations, or other modifications
                +    represent, as a whole, an original work of authorship. For the purposes
                +    of this License, Derivative Works shall not include works that remain
                +    separable from, or merely link (or bind by name) to the interfaces of,
                +    the Work and Derivative Works thereof.
                +
                +    "Contribution" shall mean any work of authorship, including
                +    the original version of the Work and any modifications or additions
                +    to that Work or Derivative Works thereof, that is intentionally
                +    submitted to Licensor for inclusion in the Work by the copyright owner
                +    or by an individual or Legal Entity authorized to submit on behalf of
                +    the copyright owner. For the purposes of this definition, "submitted"
                +    means any form of electronic, verbal, or written communication sent
                +    to the Licensor or its representatives, including but not limited to
                +    communication on electronic mailing lists, source code control systems,
                +    and issue tracking systems that are managed by, or on behalf of, the
                +    Licensor for the purpose of discussing and improving the Work, but
                +    excluding communication that is conspicuously marked or otherwise
                +    designated in writing by the copyright owner as "Not a Contribution."
                +
                +    "Contributor" shall mean Licensor and any individual or Legal Entity
                +    on behalf of whom a Contribution has been received by Licensor and
                +    subsequently incorporated within the Work.
                +
                + 2. Grant of Copyright License. Subject to the terms and conditions of
                +    this License, each Contributor hereby grants to You a perpetual,
                +    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +    copyright license to reproduce, prepare Derivative Works of,
                +    publicly display, publicly perform, sublicense, and distribute the
                +    Work and such Derivative Works in Source or Object form.
                +
                + 3. Grant of Patent License. Subject to the terms and conditions of
                +    this License, each Contributor hereby grants to You a perpetual,
                +    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +    (except as stated in this section) patent license to make, have made,
                +    use, offer to sell, sell, import, and otherwise transfer the Work,
                +    where such license applies only to those patent claims licensable
                +    by such Contributor that are necessarily infringed by their
                +    Contribution(s) alone or by combination of their Contribution(s)
                +    with the Work to which such Contribution(s) was submitted. If You
                +    institute patent litigation against any entity (including a
                +    cross-claim or counterclaim in a lawsuit) alleging that the Work
                +    or a Contribution incorporated within the Work constitutes direct
                +    or contributory patent infringement, then any patent licenses
                +    granted to You under this License for that Work shall terminate
                +    as of the date such litigation is filed.
                +
                + 4. Redistribution. You may reproduce and distribute copies of the
                +    Work or Derivative Works thereof in any medium, with or without
                +    modifications, and in Source or Object form, provided that You
                +    meet the following conditions:
                +
                +    (a) You must give any other recipients of the Work or
                +        Derivative Works a copy of this License; and
                +
                +    (b) You must cause any modified files to carry prominent notices
                +        stating that You changed the files; and
                +
                +    (c) You must retain, in the Source form of any Derivative Works
                +        that You distribute, all copyright, patent, trademark, and
                +        attribution notices from the Source form of the Work,
                +        excluding those notices that do not pertain to any part of
                +        the Derivative Works; and
                +
                +    (d) If the Work includes a "NOTICE" text file as part of its
                +        distribution, then any Derivative Works that You distribute must
                +        include a readable copy of the attribution notices contained
                +        within such NOTICE file, excluding those notices that do not
                +        pertain to any part of the Derivative Works, in at least one
                +        of the following places: within a NOTICE text file distributed
                +        as part of the Derivative Works; within the Source form or
                +        documentation, if provided along with the Derivative Works; or,
                +        within a display generated by the Derivative Works, if and
                +        wherever such third-party notices normally appear. The contents
                +        of the NOTICE file are for informational purposes only and
                +        do not modify the License. You may add Your own attribution
                +        notices within Derivative Works that You distribute, alongside
                +        or as an addendum to the NOTICE text from the Work, provided
                +        that such additional attribution notices cannot be construed
                +        as modifying the License.
                +
                +    You may add Your own copyright statement to Your modifications and
                +    may provide additional or different license terms and conditions
                +    for use, reproduction, or distribution of Your modifications, or
                +    for any such Derivative Works as a whole, provided Your use,
                +    reproduction, and distribution of the Work otherwise complies with
                +    the conditions stated in this License.
                +
                + 5. Submission of Contributions. Unless You explicitly state otherwise,
                +    any Contribution intentionally submitted for inclusion in the Work
                +    by You to the Licensor shall be under the terms and conditions of
                +    this License, without any additional terms or conditions.
                +    Notwithstanding the above, nothing herein shall supersede or modify
                +    the terms of any separate license agreement you may have executed
                +    with Licensor regarding such Contributions.
                +
                + 6. Trademarks. This License does not grant permission to use the trade
                +    names, trademarks, service marks, or product names of the Licensor,
                +    except as required for reasonable and customary use in describing the
                +    origin of the Work and reproducing the content of the NOTICE file.
                +
                + 7. Disclaimer of Warranty. Unless required by applicable law or
                +    agreed to in writing, Licensor provides the Work (and each
                +    Contributor provides its Contributions) on an "AS IS" BASIS,
                +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
                +    implied, including, without limitation, any warranties or conditions
                +    of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
                +    PARTICULAR PURPOSE. You are solely responsible for determining the
                +    appropriateness of using or redistributing the Work and assume any
                +    risks associated with Your exercise of permissions under this License.
                +
                + 8. Limitation of Liability. In no event and under no legal theory,
                +    whether in tort (including negligence), contract, or otherwise,
                +    unless required by applicable law (such as deliberate and grossly
                +    negligent acts) or agreed to in writing, shall any Contributor be
                +    liable to You for damages, including any direct, indirect, special,
                +    incidental, or consequential damages of any character arising as a
                +    result of this License or out of the use or inability to use the
                +    Work (including but not limited to damages for loss of goodwill,
                +    work stoppage, computer failure or malfunction, or any and all
                +    other commercial damages or losses), even if such Contributor
                +    has been advised of the possibility of such damages.
                +
                + 9. Accepting Warranty or Additional Liability. While redistributing
                +    the Work or Derivative Works thereof, You may choose to offer,
                +    and charge a fee for, acceptance of support, warranty, indemnity,
                +    or other liability obligations and/or rights consistent with this
                +    License. However, in accepting such obligations, You may act only
                +    on Your own behalf and on Your sole responsibility, not on behalf
                +    of any other Contributor, and only if You agree to indemnify,
                +    defend, and hold each Contributor harmless for any liability
                +    incurred by, or claims asserted against, such Contributor by reason
                +    of your accepting any such warranty or additional liability.
                +
                + END OF TERMS AND CONDITIONS
                +
                + APPENDIX: How to apply the Apache License to your work.
                +
                +    To apply the Apache License to your work, attach the following
                +    boilerplate notice, with the fields enclosed by brackets "[]"
                +    replaced with your own identifying information. (Don't include
                +    the brackets!)  The text should be enclosed in the appropriate
                +    comment syntax for the file format. We also recommend that a
                +    file or class name and description of purpose be included on the
                +    same "printed page" as the copyright notice for easier
                +    identification within third-party archives.
                +
                + Copyright 2015-2016 Netflix, Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +     http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +
                +**/
                +/**
                +  @license
                +                                 Apache License
                +                         Version 2.0, January 2004
                +                      http://www.apache.org/licenses/
                +
                + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
                +
                + 1. Definitions.
                +
                +    "License" shall mean the terms and conditions for use, reproduction,
                +    and distribution as defined by Sections 1 through 9 of this document.
                +
                +    "Licensor" shall mean the copyright owner or entity authorized by
                +    the copyright owner that is granting the License.
                +
                +    "Legal Entity" shall mean the union of the acting entity and all
                +    other entities that control, are controlled by, or are under common
                +    control with that entity. For the purposes of this definition,
                +    "control" means (i) the power, direct or indirect, to cause the
                +    direction or management of such entity, whether by contract or
                +    otherwise, or (ii) ownership of fifty percent (50%) or more of the
                +    outstanding shares, or (iii) beneficial ownership of such entity.
                +
                +    "You" (or "Your") shall mean an individual or Legal Entity
                +    exercising permissions granted by this License.
                +
                +    "Source" form shall mean the preferred form for making modifications,
                +    including but not limited to software source code, documentation
                +    source, and configuration files.
                +
                +    "Object" form shall mean any form resulting from mechanical
                +    transformation or translation of a Source form, including but
                +    not limited to compiled object code, generated documentation,
                +    and conversions to other media types.
                +
                +    "Work" shall mean the work of authorship, whether in Source or
                +    Object form, made available under the License, as indicated by a
                +    copyright notice that is included in or attached to the work
                +    (an example is provided in the Appendix below).
                +
                +    "Derivative Works" shall mean any work, whether in Source or Object
                +    form, that is based on (or derived from) the Work and for which the
                +    editorial revisions, annotations, elaborations, or other modifications
                +    represent, as a whole, an original work of authorship. For the purposes
                +    of this License, Derivative Works shall not include works that remain
                +    separable from, or merely link (or bind by name) to the interfaces of,
                +    the Work and Derivative Works thereof.
                +
                +    "Contribution" shall mean any work of authorship, including
                +    the original version of the Work and any modifications or additions
                +    to that Work or Derivative Works thereof, that is intentionally
                +    submitted to Licensor for inclusion in the Work by the copyright owner
                +    or by an individual or Legal Entity authorized to submit on behalf of
                +    the copyright owner. For the purposes of this definition, "submitted"
                +    means any form of electronic, verbal, or written communication sent
                +    to the Licensor or its representatives, including but not limited to
                +    communication on electronic mailing lists, source code control systems,
                +    and issue tracking systems that are managed by, or on behalf of, the
                +    Licensor for the purpose of discussing and improving the Work, but
                +    excluding communication that is conspicuously marked or otherwise
                +    designated in writing by the copyright owner as "Not a Contribution."
                +
                +    "Contributor" shall mean Licensor and any individual or Legal Entity
                +    on behalf of whom a Contribution has been received by Licensor and
                +    subsequently incorporated within the Work.
                +
                + 2. Grant of Copyright License. Subject to the terms and conditions of
                +    this License, each Contributor hereby grants to You a perpetual,
                +    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +    copyright license to reproduce, prepare Derivative Works of,
                +    publicly display, publicly perform, sublicense, and distribute the
                +    Work and such Derivative Works in Source or Object form.
                +
                + 3. Grant of Patent License. Subject to the terms and conditions of
                +    this License, each Contributor hereby grants to You a perpetual,
                +    worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +    (except as stated in this section) patent license to make, have made,
                +    use, offer to sell, sell, import, and otherwise transfer the Work,
                +    where such license applies only to those patent claims licensable
                +    by such Contributor that are necessarily infringed by their
                +    Contribution(s) alone or by combination of their Contribution(s)
                +    with the Work to which such Contribution(s) was submitted. If You
                +    institute patent litigation against any entity (including a
                +    cross-claim or counterclaim in a lawsuit) alleging that the Work
                +    or a Contribution incorporated within the Work constitutes direct
                +    or contributory patent infringement, then any patent licenses
                +    granted to You under this License for that Work shall terminate
                +    as of the date such litigation is filed.
                +
                + 4. Redistribution. You may reproduce and distribute copies of the
                +    Work or Derivative Works thereof in any medium, with or without
                +    modifications, and in Source or Object form, provided that You
                +    meet the following conditions:
                +
                +    (a) You must give any other recipients of the Work or
                +        Derivative Works a copy of this License; and
                +
                +    (b) You must cause any modified files to carry prominent notices
                +        stating that You changed the files; and
                +
                +    (c) You must retain, in the Source form of any Derivative Works
                +        that You distribute, all copyright, patent, trademark, and
                +        attribution notices from the Source form of the Work,
                +        excluding those notices that do not pertain to any part of
                +        the Derivative Works; and
                +
                +    (d) If the Work includes a "NOTICE" text file as part of its
                +        distribution, then any Derivative Works that You distribute must
                +        include a readable copy of the attribution notices contained
                +        within such NOTICE file, excluding those notices that do not
                +        pertain to any part of the Derivative Works, in at least one
                +        of the following places: within a NOTICE text file distributed
                +        as part of the Derivative Works; within the Source form or
                +        documentation, if provided along with the Derivative Works; or,
                +        within a display generated by the Derivative Works, if and
                +        wherever such third-party notices normally appear. The contents
                +        of the NOTICE file are for informational purposes only and
                +        do not modify the License. You may add Your own attribution
                +        notices within Derivative Works that You distribute, alongside
                +        or as an addendum to the NOTICE text from the Work, provided
                +        that such additional attribution notices cannot be construed
                +        as modifying the License.
                +
                +    You may add Your own copyright statement to Your modifications and
                +    may provide additional or different license terms and conditions
                +    for use, reproduction, or distribution of Your modifications, or
                +    for any such Derivative Works as a whole, provided Your use,
                +    reproduction, and distribution of the Work otherwise complies with
                +    the conditions stated in this License.
                +
                + 5. Submission of Contributions. Unless You explicitly state otherwise,
                +    any Contribution intentionally submitted for inclusion in the Work
                +    by You to the Licensor shall be under the terms and conditions of
                +    this License, without any additional terms or conditions.
                +    Notwithstanding the above, nothing herein shall supersede or modify
                +    the terms of any separate license agreement you may have executed
                +    with Licensor regarding such Contributions.
                +
                + 6. Trademarks. This License does not grant permission to use the trade
                +    names, trademarks, service marks, or product names of the Licensor,
                +    except as required for reasonable and customary use in describing the
                +    origin of the Work and reproducing the content of the NOTICE file.
                +
                + 7. Disclaimer of Warranty. Unless required by applicable law or
                +    agreed to in writing, Licensor provides the Work (and each
                +    Contributor provides its Contributions) on an "AS IS" BASIS,
                +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
                +    implied, including, without limitation, any warranties or conditions
                +    of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
                +    PARTICULAR PURPOSE. You are solely responsible for determining the
                +    appropriateness of using or redistributing the Work and assume any
                +    risks associated with Your exercise of permissions under this License.
                +
                + 8. Limitation of Liability. In no event and under no legal theory,
                +    whether in tort (including negligence), contract, or otherwise,
                +    unless required by applicable law (such as deliberate and grossly
                +    negligent acts) or agreed to in writing, shall any Contributor be
                +    liable to You for damages, including any direct, indirect, special,
                +    incidental, or consequential damages of any character arising as a
                +    result of this License or out of the use or inability to use the
                +    Work (including but not limited to damages for loss of goodwill,
                +    work stoppage, computer failure or malfunction, or any and all
                +    other commercial damages or losses), even if such Contributor
                +    has been advised of the possibility of such damages.
                +
                + 9. Accepting Warranty or Additional Liability. While redistributing
                +    the Work or Derivative Works thereof, You may choose to offer,
                +    and charge a fee for, acceptance of support, warranty, indemnity,
                +    or other liability obligations and/or rights consistent with this
                +    License. However, in accepting such obligations, You may act only
                +    on Your own behalf and on Your sole responsibility, not on behalf
                +    of any other Contributor, and only if You agree to indemnify,
                +    defend, and hold each Contributor harmless for any liability
                +    incurred by, or claims asserted against, such Contributor by reason
                +    of your accepting any such warranty or additional liability.
                +
                + END OF TERMS AND CONDITIONS
                +
                + APPENDIX: How to apply the Apache License to your work.
                +
                +    To apply the Apache License to your work, attach the following
                +    boilerplate notice, with the fields enclosed by brackets "[]"
                +    replaced with your own identifying information. (Don't include
                +    the brackets!)  The text should be enclosed in the appropriate
                +    comment syntax for the file format. We also recommend that a
                +    file or class name and description of purpose be included on the
                +    same "printed page" as the copyright notice for easier
                +    identification within third-party archives.
                +
                + Copyright 2015-2016 Netflix, Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +     http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +
                + **/
                +(function(w){"object"===typeof exports&&"undefined"!==typeof module?module.exports=w():"function"===typeof define&&define.amd?define([],w):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).Rx=w()})(function(){return function a(b,f,g){function k(e,d){if(!f[e]){if(!b[e]){var c="function"==typeof require&&require;if(!d&&c)return c(e,!0);if(l)return l(e,!0);c=Error("Cannot find module '"+e+"'");throw c.code="MODULE_NOT_FOUND",c;}c=f[e]={exports:{}};
                +b[e][0].call(c.exports,function(a){var c=b[e][1][a];return k(c?c:a)},c,c.exports,a,b,f,g)}return f[e].exports}for(var l="function"==typeof require&&require,h=0;h<g.length;h++)k(g[h]);return k}({1:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e,d){a.call(this);this.parent=h;this.outerValue=e;this.outerIndex=d;
                +this.index=0}g(b,a);b.prototype._next=function(a){this.parent.notifyNext(this.outerValue,a,this.outerIndex,this.index++,this)};b.prototype._error=function(a){this.parent.notifyError(a,this);this.unsubscribe()};b.prototype._complete=function(){this.parent.notifyComplete(this);this.unsubscribe()};return b}(a("./Subscriber").Subscriber);f.InnerSubscriber=a},{"./Subscriber":9}],2:[function(a,b,f){var g=a("./Observable");a=function(){function a(b,h,e){this.kind=b;this.value=h;this.exception=e;this.hasValue=
                +"N"===b}a.prototype.observe=function(a){switch(this.kind){case "N":return a.next&&a.next(this.value);case "E":return a.error&&a.error(this.exception);case "C":return a.complete&&a.complete()}};a.prototype["do"]=function(a,b,e){switch(this.kind){case "N":return a&&a(this.value);case "E":return b&&b(this.exception);case "C":return e&&e()}};a.prototype.accept=function(a,b,e){return a&&"function"===typeof a.next?this.observe(a):this["do"](a,b,e)};a.prototype.toObservable=function(){switch(this.kind){case "N":return g.Observable.of(this.value);
                +case "E":return g.Observable["throw"](this.exception);case "C":return g.Observable.empty()}};a.createNext=function(b){return"undefined"!==typeof b?new a("N",b):this.undefinedValueNotification};a.createError=function(b){return new a("E",void 0,b)};a.createComplete=function(){return this.completeNotification};a.completeNotification=new a("C");a.undefinedValueNotification=new a("N",void 0);return a}();f.Notification=a},{"./Observable":3}],3:[function(a,b,f){var g=a("./util/root"),k=a("./util/SymbolShim"),
                +l=a("./util/toSubscriber"),h=a("./util/tryCatch"),e=a("./util/errorObject");a=function(){function a(c){this._isScalar=!1;c&&(this._subscribe=c)}a.prototype.lift=function(c){var m=new a;m.source=this;m.operator=c;return m};a.prototype.subscribe=function(a,d,e){var b=this.operator;a=l.toSubscriber(a,d,e);b?a.add(this._subscribe(b.call(a))):a.add(this._subscribe(a));if(a.syncErrorThrowable&&(a.syncErrorThrowable=!1,a.syncErrorThrown))throw a.syncErrorValue;return a};a.prototype.forEach=function(a,d,
                +n){n||(g.root.Rx&&g.root.Rx.config&&g.root.Rx.config.Promise?n=g.root.Rx.config.Promise:g.root.Promise&&(n=g.root.Promise));if(!n)throw Error("no Promise impl found");var b=this;return new n(function(n,l){b.subscribe(function(n){h.tryCatch(a).call(d,n)===e.errorObject&&l(e.errorObject.e)},l,n)})};a.prototype._subscribe=function(a){return this.source.subscribe(a)};a.prototype[k.SymbolShim.observable]=function(){return this};a.create=function(c){return new a(c)};return a}();f.Observable=a},{"./util/SymbolShim":238,
                +"./util/errorObject":239,"./util/root":249,"./util/toSubscriber":252,"./util/tryCatch":253}],4:[function(a,b,f){f.empty={isUnsubscribed:!0,next:function(a){},error:function(a){throw a;},complete:function(){}}},{}],5:[function(a,b,f){var g=a("./Subscriber");a=function(){function a(){}a.prototype.call=function(a){return new g.Subscriber(a)};return a}();f.Operator=a},{"./Subscriber":9}],6:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
                +(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype.notifyNext=function(a,e,d,c,m){this.destination.next(e)};b.prototype.notifyError=function(a,e){this.destination.error(a)};b.prototype.notifyComplete=function(a){this.destination.complete()};return b}(a("./Subscriber").Subscriber);f.OuterSubscriber=a},{"./Subscriber":9}],7:[function(a,b,f){b=a("./Subject");f.Subject=b.Subject;b=a("./Observable");f.Observable=
                +b.Observable;a("./add/observable/combineLatest");a("./add/observable/concat");a("./add/observable/merge");a("./add/observable/race");a("./add/observable/bindCallback");a("./add/observable/bindNodeCallback");a("./add/observable/defer");a("./add/observable/empty");a("./add/observable/forkJoin");a("./add/observable/from");a("./add/observable/fromArray");a("./add/observable/fromEvent");a("./add/observable/fromEventPattern");a("./add/observable/fromPromise");a("./add/observable/interval");a("./add/observable/never");
                +a("./add/observable/range");a("./add/observable/throw");a("./add/observable/timer");a("./add/observable/zip");a("./add/operator/buffer");a("./add/operator/bufferCount");a("./add/operator/bufferTime");a("./add/operator/bufferToggle");a("./add/operator/bufferWhen");a("./add/operator/cache");a("./add/operator/catch");a("./add/operator/combineAll");a("./add/operator/combineLatest");a("./add/operator/concat");a("./add/operator/concatAll");a("./add/operator/concatMap");a("./add/operator/concatMapTo");a("./add/operator/count");
                +a("./add/operator/dematerialize");a("./add/operator/debounce");a("./add/operator/debounceTime");a("./add/operator/defaultIfEmpty");a("./add/operator/delay");a("./add/operator/delayWhen");a("./add/operator/distinctUntilChanged");a("./add/operator/do");a("./add/operator/expand");a("./add/operator/filter");a("./add/operator/finally");a("./add/operator/first");a("./add/operator/groupBy");a("./add/operator/ignoreElements");a("./add/operator/inspect");a("./add/operator/inspectTime");a("./add/operator/every");
                +a("./add/operator/last");a("./add/operator/let");a("./add/operator/map");a("./add/operator/mapTo");a("./add/operator/materialize");a("./add/operator/merge");a("./add/operator/mergeAll");a("./add/operator/mergeMap");a("./add/operator/mergeMapTo");a("./add/operator/multicast");a("./add/operator/observeOn");a("./add/operator/partition");a("./add/operator/pluck");a("./add/operator/publish");a("./add/operator/publishBehavior");a("./add/operator/publishReplay");a("./add/operator/publishLast");a("./add/operator/race");
                +a("./add/operator/reduce");a("./add/operator/repeat");a("./add/operator/retry");a("./add/operator/retryWhen");a("./add/operator/sample");a("./add/operator/sampleTime");a("./add/operator/scan");a("./add/operator/share");a("./add/operator/single");a("./add/operator/skip");a("./add/operator/skipUntil");a("./add/operator/skipWhile");a("./add/operator/startWith");a("./add/operator/subscribeOn");a("./add/operator/switch");a("./add/operator/switchMap");a("./add/operator/switchMapTo");a("./add/operator/take");
                +a("./add/operator/takeLast");a("./add/operator/takeUntil");a("./add/operator/takeWhile");a("./add/operator/throttle");a("./add/operator/throttleTime");a("./add/operator/timeout");a("./add/operator/timeoutWith");a("./add/operator/toArray");a("./add/operator/toPromise");a("./add/operator/window");a("./add/operator/windowCount");a("./add/operator/windowTime");a("./add/operator/windowToggle");a("./add/operator/windowWhen");a("./add/operator/withLatestFrom");a("./add/operator/zip");a("./add/operator/zipAll");
                +b=a("./Operator");f.Operator=b.Operator;b=a("./Subscription");f.Subscription=b.Subscription;f.UnsubscriptionError=b.UnsubscriptionError;b=a("./Subscriber");f.Subscriber=b.Subscriber;b=a("./subject/AsyncSubject");f.AsyncSubject=b.AsyncSubject;b=a("./subject/ReplaySubject");f.ReplaySubject=b.ReplaySubject;b=a("./subject/BehaviorSubject");f.BehaviorSubject=b.BehaviorSubject;b=a("./observable/ConnectableObservable");f.ConnectableObservable=b.ConnectableObservable;b=a("./Notification");f.Notification=
                +b.Notification;b=a("./util/EmptyError");f.EmptyError=b.EmptyError;b=a("./util/ArgumentOutOfRangeError");f.ArgumentOutOfRangeError=b.ArgumentOutOfRangeError;b=a("./util/ObjectUnsubscribedError");f.ObjectUnsubscribedError=b.ObjectUnsubscribedError;b=a("./scheduler/asap");var g=a("./scheduler/queue");a=a("./symbol/rxSubscriber");f.Scheduler={asap:b.asap,queue:g.queue};f.Symbol={rxSubscriber:a.rxSubscriber}},{"./Notification":2,"./Observable":3,"./Operator":5,"./Subject":8,"./Subscriber":9,"./Subscription":10,
                +"./add/observable/bindCallback":11,"./add/observable/bindNodeCallback":12,"./add/observable/combineLatest":13,"./add/observable/concat":14,"./add/observable/defer":15,"./add/observable/empty":16,"./add/observable/forkJoin":17,"./add/observable/from":18,"./add/observable/fromArray":19,"./add/observable/fromEvent":20,"./add/observable/fromEventPattern":21,"./add/observable/fromPromise":22,"./add/observable/interval":23,"./add/observable/merge":24,"./add/observable/never":25,"./add/observable/race":26,
                +"./add/observable/range":27,"./add/observable/throw":28,"./add/observable/timer":29,"./add/observable/zip":30,"./add/operator/buffer":31,"./add/operator/bufferCount":32,"./add/operator/bufferTime":33,"./add/operator/bufferToggle":34,"./add/operator/bufferWhen":35,"./add/operator/cache":36,"./add/operator/catch":37,"./add/operator/combineAll":38,"./add/operator/combineLatest":39,"./add/operator/concat":40,"./add/operator/concatAll":41,"./add/operator/concatMap":42,"./add/operator/concatMapTo":43,"./add/operator/count":44,
                +"./add/operator/debounce":45,"./add/operator/debounceTime":46,"./add/operator/defaultIfEmpty":47,"./add/operator/delay":48,"./add/operator/delayWhen":49,"./add/operator/dematerialize":50,"./add/operator/distinctUntilChanged":51,"./add/operator/do":52,"./add/operator/every":53,"./add/operator/expand":54,"./add/operator/filter":55,"./add/operator/finally":56,"./add/operator/first":57,"./add/operator/groupBy":58,"./add/operator/ignoreElements":59,"./add/operator/inspect":60,"./add/operator/inspectTime":61,
                +"./add/operator/last":62,"./add/operator/let":63,"./add/operator/map":64,"./add/operator/mapTo":65,"./add/operator/materialize":66,"./add/operator/merge":67,"./add/operator/mergeAll":68,"./add/operator/mergeMap":69,"./add/operator/mergeMapTo":70,"./add/operator/multicast":71,"./add/operator/observeOn":72,"./add/operator/partition":73,"./add/operator/pluck":74,"./add/operator/publish":75,"./add/operator/publishBehavior":76,"./add/operator/publishLast":77,"./add/operator/publishReplay":78,"./add/operator/race":79,
                +"./add/operator/reduce":80,"./add/operator/repeat":81,"./add/operator/retry":82,"./add/operator/retryWhen":83,"./add/operator/sample":84,"./add/operator/sampleTime":85,"./add/operator/scan":86,"./add/operator/share":87,"./add/operator/single":88,"./add/operator/skip":89,"./add/operator/skipUntil":90,"./add/operator/skipWhile":91,"./add/operator/startWith":92,"./add/operator/subscribeOn":93,"./add/operator/switch":94,"./add/operator/switchMap":95,"./add/operator/switchMapTo":96,"./add/operator/take":97,
                +"./add/operator/takeLast":98,"./add/operator/takeUntil":99,"./add/operator/takeWhile":100,"./add/operator/throttle":101,"./add/operator/throttleTime":102,"./add/operator/timeout":103,"./add/operator/timeoutWith":104,"./add/operator/toArray":105,"./add/operator/toPromise":106,"./add/operator/window":107,"./add/operator/windowCount":108,"./add/operator/windowTime":109,"./add/operator/windowToggle":110,"./add/operator/windowWhen":111,"./add/operator/withLatestFrom":112,"./add/operator/zip":113,"./add/operator/zipAll":114,
                +"./observable/ConnectableObservable":119,"./scheduler/asap":224,"./scheduler/queue":225,"./subject/AsyncSubject":226,"./subject/BehaviorSubject":227,"./subject/ReplaySubject":228,"./symbol/rxSubscriber":230,"./util/ArgumentOutOfRangeError":231,"./util/EmptyError":232,"./util/ObjectUnsubscribedError":237}],8:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var m in c)c.hasOwnProperty(m)&&(a[m]=c[m]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,
                +new d)};b=a("./Observable");var k=a("./Subscriber"),l=a("./Subscription"),h=a("./subject/SubjectSubscription"),e=a("./symbol/rxSubscriber"),d=a("./util/throwError"),c=a("./util/ObjectUnsubscribedError");a=function(a){function b(c,d){a.call(this);this.destination=c;this.source=d;this.observers=[];this.hasCompleted=this.dispatching=this.hasErrored=this.isStopped=this.isUnsubscribed=!1}g(b,a);b.prototype.lift=function(a){var c=new b(this.destination||this,this);c.operator=a;return c};b.prototype.add=
                +function(a){l.Subscription.prototype.add.call(this,a)};b.prototype.remove=function(a){l.Subscription.prototype.remove.call(this,a)};b.prototype.unsubscribe=function(){l.Subscription.prototype.unsubscribe.call(this)};b.prototype._subscribe=function(a){if(this.source)return this.source.subscribe(a);if(!a.isUnsubscribed){if(this.hasErrored)return a.error(this.errorValue);if(this.hasCompleted)return a.complete();this.throwIfUnsubscribed();var c=new h.SubjectSubscription(this,a);this.observers.push(a);
                +return c}};b.prototype._unsubscribe=function(){this.source=null;this.isStopped=!0;this.destination=this.observers=null};b.prototype.next=function(a){this.throwIfUnsubscribed();this.isStopped||(this.dispatching=!0,this._next(a),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())};b.prototype.error=function(a){this.throwIfUnsubscribed();this.isStopped||(this.hasErrored=this.isStopped=!0,this.errorValue=a,this.dispatching||this._error(a))};b.prototype.complete=
                +function(){this.throwIfUnsubscribed();this.isStopped||(this.hasCompleted=this.isStopped=!0,this.dispatching||this._complete())};b.prototype.asObservable=function(){return new m(this)};b.prototype._next=function(a){this.destination?this.destination.next(a):this._finalNext(a)};b.prototype._finalNext=function(a){for(var c=-1,d=this.observers.slice(0),m=d.length;++c<m;)d[c].next(a)};b.prototype._error=function(a){this.destination?this.destination.error(a):this._finalError(a)};b.prototype._finalError=
                +function(a){var c=-1,d=this.observers;this.observers=null;this.isUnsubscribed=!0;if(d)for(var m=d.length;++c<m;)d[c].error(a);this.isUnsubscribed=!1;this.unsubscribe()};b.prototype._complete=function(){this.destination?this.destination.complete():this._finalComplete()};b.prototype._finalComplete=function(){var a=-1,c=this.observers;this.observers=null;this.isUnsubscribed=!0;if(c)for(var d=c.length;++a<d;)c[a].complete();this.isUnsubscribed=!1;this.unsubscribe()};b.prototype.throwIfUnsubscribed=function(){this.isUnsubscribed&&
                +d.throwError(new c.ObjectUnsubscribedError)};b.prototype[e.rxSubscriber]=function(){return new k.Subscriber(this)};b.create=function(a,c){return new b(a,c)};return b}(b.Observable);f.Subject=a;var m=function(a){function c(d){a.call(this);this.source=d}g(c,a);return c}(b.Observable)},{"./Observable":3,"./Subscriber":9,"./Subscription":10,"./subject/SubjectSubscription":229,"./symbol/rxSubscriber":230,"./util/ObjectUnsubscribedError":237,"./util/throwError":251}],9:[function(a,b,f){var g=this&&this.__extends||
                +function(a,c){function m(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(m.prototype=c.prototype,new m)},k=a("./util/isFunction");b=a("./Subscription");var l=a("./symbol/rxSubscriber"),h=a("./Observer");a=function(a){function c(m,n,b){a.call(this);this.syncErrorValue=null;this.isStopped=this.syncErrorThrowable=this.syncErrorThrown=!1;switch(arguments.length){case 0:this.destination=h.empty;break;case 1:if(!m){this.destination=h.empty;break}if("object"===
                +typeof m){m instanceof c?this.destination=m:(this.syncErrorThrowable=!0,this.destination=new e(this,m));break}default:this.syncErrorThrowable=!0,this.destination=new e(this,m,n,b)}}g(c,a);c.create=function(a,d,e){a=new c(a,d,e);a.syncErrorThrowable=!1;return a};c.prototype.next=function(a){this.isStopped||this._next(a)};c.prototype.error=function(a){this.isStopped||(this.isStopped=!0,this._error(a))};c.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())};c.prototype.unsubscribe=
                +function(){this.isUnsubscribed||(this.isStopped=!0,a.prototype.unsubscribe.call(this))};c.prototype._next=function(a){this.destination.next(a)};c.prototype._error=function(a){this.destination.error(a);this.unsubscribe()};c.prototype._complete=function(){this.destination.complete();this.unsubscribe()};c.prototype[l.rxSubscriber]=function(){return this};return c}(b.Subscription);f.Subscriber=a;var e=function(a){function c(c,e,b,h){a.call(this);this._parent=c;var f;c=this;k.isFunction(e)?f=e:e&&(c=e,
                +f=e.next,b=e.error,h=e.complete);this._context=c;this._next=f;this._error=b;this._complete=h}g(c,a);c.prototype.next=function(a){if(!this.isStopped&&this._next){var c=this._parent;c.syncErrorThrowable?this.__tryOrSetError(c,this._next,a)&&this.unsubscribe():this.__tryOrUnsub(this._next,a)}};c.prototype.error=function(a){if(!this.isStopped){var c=this._parent;if(this._error)c.syncErrorThrowable?this.__tryOrSetError(c,this._error,a):this.__tryOrUnsub(this._error,a),this.unsubscribe();else if(c.syncErrorThrowable)c.syncErrorValue=
                +a,c.syncErrorThrown=!0,this.unsubscribe();else throw this.unsubscribe(),a;}};c.prototype.complete=function(){if(!this.isStopped){var a=this._parent;this._complete&&(a.syncErrorThrowable?this.__tryOrSetError(a,this._complete):this.__tryOrUnsub(this._complete));this.unsubscribe()}};c.prototype.__tryOrUnsub=function(a,c){try{a.call(this._context,c)}catch(d){throw this.unsubscribe(),d;}};c.prototype.__tryOrSetError=function(a,c,d){try{c.call(this._context,d)}catch(e){return a.syncErrorValue=e,a.syncErrorThrown=
                +!0}return!1};c.prototype._unsubscribe=function(){var a=this._parent;this._parent=this._context=null;a.unsubscribe()};return c}(a)},{"./Observer":4,"./Subscription":10,"./symbol/rxSubscriber":230,"./util/isFunction":242}],10:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("./util/isArray"),l=a("./util/isObject"),h=a("./util/isFunction"),
                +e=a("./util/tryCatch"),d=a("./util/errorObject");a=function(){function a(c){this.isUnsubscribed=!1;c&&(this._unsubscribe=c)}a.prototype.unsubscribe=function(){var a=!1,m;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var b=this._unsubscribe,f=this._subscriptions;this._subscriptions=null;if(h.isFunction(b)){var g=e.tryCatch(b).call(this);g===d.errorObject&&(a=!0,(m=m||[]).push(d.errorObject.e))}if(k.isArray(f))for(var b=-1,r=f.length;++b<r;)g=f[b],l.isObject(g)&&(g=e.tryCatch(g.unsubscribe).call(g),
                +g===d.errorObject&&(a=!0,m=m||[],g=d.errorObject.e,g instanceof c?m=m.concat(g.errors):m.push(g)));if(a)throw new c(m);}};a.prototype.add=function(c){if(c&&c!==this&&c!==a.EMPTY){var d=c;switch(typeof c){case "function":d=new a(c);case "object":d.isUnsubscribed||"function"!==typeof d.unsubscribe||(this.isUnsubscribed?d.unsubscribe():(this._subscriptions||(this._subscriptions=[])).push(d));break;default:throw Error("Unrecognized subscription "+c+" added to Subscription.");}}};a.prototype.remove=function(c){if(null!=
                +c&&c!==this&&c!==a.EMPTY){var d=this._subscriptions;d&&(c=d.indexOf(c),-1!==c&&d.splice(c,1))}};a.EMPTY=function(a){a.isUnsubscribed=!0;return a}(new a);return a}();f.Subscription=a;var c=function(a){function c(d){a.call(this,"unsubscriptoin error(s)");this.errors=d;this.name="UnsubscriptionError"}g(c,a);return c}(Error);f.UnsubscriptionError=c},{"./util/errorObject":239,"./util/isArray":240,"./util/isFunction":242,"./util/isObject":244,"./util/tryCatch":253}],11:[function(a,b,f){b=a("../../Observable");
                +a=a("../../observable/BoundCallbackObservable");b.Observable.bindCallback=a.BoundCallbackObservable.create},{"../../Observable":3,"../../observable/BoundCallbackObservable":117}],12:[function(a,b,f){b=a("../../Observable");a=a("../../observable/BoundNodeCallbackObservable");b.Observable.bindNodeCallback=a.BoundNodeCallbackObservable.create},{"../../Observable":3,"../../observable/BoundNodeCallbackObservable":118}],13:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineLatest");b.Observable.combineLatest=
                +a.combineLatestStatic},{"../../Observable":3,"../../operator/combineLatest":143}],14:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concat");b.Observable.concat=a.concatStatic},{"../../Observable":3,"../../operator/concat":144}],15:[function(a,b,f){b=a("../../Observable");a=a("../../observable/DeferObservable");b.Observable.defer=a.DeferObservable.create},{"../../Observable":3,"../../observable/DeferObservable":120}],16:[function(a,b,f){b=a("../../Observable");a=a("../../observable/EmptyObservable");
                +b.Observable.empty=a.EmptyObservable.create},{"../../Observable":3,"../../observable/EmptyObservable":121}],17:[function(a,b,f){b=a("../../Observable");a=a("../../observable/ForkJoinObservable");b.Observable.forkJoin=a.ForkJoinObservable.create},{"../../Observable":3,"../../observable/ForkJoinObservable":123}],18:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromObservable");b.Observable.from=a.FromObservable.create},{"../../Observable":3,"../../observable/FromObservable":126}],19:[function(a,
                +b,f){b=a("../../Observable");a=a("../../observable/ArrayObservable");b.Observable.fromArray=a.ArrayObservable.create;b.Observable.of=a.ArrayObservable.of},{"../../Observable":3,"../../observable/ArrayObservable":116}],20:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromEventObservable");b.Observable.fromEvent=a.FromEventObservable.create},{"../../Observable":3,"../../observable/FromEventObservable":124}],21:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromEventPatternObservable");
                +b.Observable.fromEventPattern=a.FromEventPatternObservable.create},{"../../Observable":3,"../../observable/FromEventPatternObservable":125}],22:[function(a,b,f){b=a("../../Observable");a=a("../../observable/PromiseObservable");b.Observable.fromPromise=a.PromiseObservable.create},{"../../Observable":3,"../../observable/PromiseObservable":130}],23:[function(a,b,f){b=a("../../Observable");a=a("../../observable/IntervalObservable");b.Observable.interval=a.IntervalObservable.create},{"../../Observable":3,
                +"../../observable/IntervalObservable":127}],24:[function(a,b,f){b=a("../../Observable");a=a("../../operator/merge");b.Observable.merge=a.mergeStatic},{"../../Observable":3,"../../operator/merge":171}],25:[function(a,b,f){b=a("../../Observable");a=a("../../observable/NeverObservable");b.Observable.never=a.NeverObservable.create},{"../../Observable":3,"../../observable/NeverObservable":129}],26:[function(a,b,f){b=a("../../Observable");a=a("../../operator/race");b.Observable.race=a.raceStatic},{"../../Observable":3,
                +"../../operator/race":183}],27:[function(a,b,f){b=a("../../Observable");a=a("../../observable/RangeObservable");b.Observable.range=a.RangeObservable.create},{"../../Observable":3,"../../observable/RangeObservable":131}],28:[function(a,b,f){b=a("../../Observable");a=a("../../observable/ErrorObservable");b.Observable["throw"]=a.ErrorObservable.create},{"../../Observable":3,"../../observable/ErrorObservable":122}],29:[function(a,b,f){b=a("../../Observable");a=a("../../observable/TimerObservable");b.Observable.timer=
                +a.TimerObservable.create},{"../../Observable":3,"../../observable/TimerObservable":134}],30:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zip");b.Observable.zip=a.zipStatic},{"../../Observable":3,"../../operator/zip":217}],31:[function(a,b,f){b=a("../../Observable");a=a("../../operator/buffer");b.Observable.prototype.buffer=a.buffer},{"../../Observable":3,"../../operator/buffer":135}],32:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferCount");b.Observable.prototype.bufferCount=
                +a.bufferCount},{"../../Observable":3,"../../operator/bufferCount":136}],33:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferTime");b.Observable.prototype.bufferTime=a.bufferTime},{"../../Observable":3,"../../operator/bufferTime":137}],34:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferToggle");b.Observable.prototype.bufferToggle=a.bufferToggle},{"../../Observable":3,"../../operator/bufferToggle":138}],35:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferWhen");
                +b.Observable.prototype.bufferWhen=a.bufferWhen},{"../../Observable":3,"../../operator/bufferWhen":139}],36:[function(a,b,f){b=a("../../Observable");a=a("../../operator/cache");b.Observable.prototype.cache=a.cache},{"../../Observable":3,"../../operator/cache":140}],37:[function(a,b,f){b=a("../../Observable");a=a("../../operator/catch");b.Observable.prototype["catch"]=a._catch},{"../../Observable":3,"../../operator/catch":141}],38:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineAll");
                +b.Observable.prototype.combineAll=a.combineAll},{"../../Observable":3,"../../operator/combineAll":142}],39:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineLatest");b.Observable.prototype.combineLatest=a.combineLatest},{"../../Observable":3,"../../operator/combineLatest":143}],40:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concat");b.Observable.prototype.concat=a.concat},{"../../Observable":3,"../../operator/concat":144}],41:[function(a,b,f){b=a("../../Observable");
                +a=a("../../operator/concatAll");b.Observable.prototype.concatAll=a.concatAll},{"../../Observable":3,"../../operator/concatAll":145}],42:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concatMap");b.Observable.prototype.concatMap=a.concatMap},{"../../Observable":3,"../../operator/concatMap":146}],43:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concatMapTo");b.Observable.prototype.concatMapTo=a.concatMapTo},{"../../Observable":3,"../../operator/concatMapTo":147}],44:[function(a,
                +b,f){b=a("../../Observable");a=a("../../operator/count");b.Observable.prototype.count=a.count},{"../../Observable":3,"../../operator/count":148}],45:[function(a,b,f){b=a("../../Observable");a=a("../../operator/debounce");b.Observable.prototype.debounce=a.debounce},{"../../Observable":3,"../../operator/debounce":149}],46:[function(a,b,f){b=a("../../Observable");a=a("../../operator/debounceTime");b.Observable.prototype.debounceTime=a.debounceTime},{"../../Observable":3,"../../operator/debounceTime":150}],
                +47:[function(a,b,f){b=a("../../Observable");a=a("../../operator/defaultIfEmpty");b.Observable.prototype.defaultIfEmpty=a.defaultIfEmpty},{"../../Observable":3,"../../operator/defaultIfEmpty":151}],48:[function(a,b,f){b=a("../../Observable");a=a("../../operator/delay");b.Observable.prototype.delay=a.delay},{"../../Observable":3,"../../operator/delay":152}],49:[function(a,b,f){b=a("../../Observable");a=a("../../operator/delayWhen");b.Observable.prototype.delayWhen=a.delayWhen},{"../../Observable":3,
                +"../../operator/delayWhen":153}],50:[function(a,b,f){b=a("../../Observable");a=a("../../operator/dematerialize");b.Observable.prototype.dematerialize=a.dematerialize},{"../../Observable":3,"../../operator/dematerialize":154}],51:[function(a,b,f){b=a("../../Observable");a=a("../../operator/distinctUntilChanged");b.Observable.prototype.distinctUntilChanged=a.distinctUntilChanged},{"../../Observable":3,"../../operator/distinctUntilChanged":155}],52:[function(a,b,f){b=a("../../Observable");a=a("../../operator/do");
                +b.Observable.prototype["do"]=a._do},{"../../Observable":3,"../../operator/do":156}],53:[function(a,b,f){b=a("../../Observable");a=a("../../operator/every");b.Observable.prototype.every=a.every},{"../../Observable":3,"../../operator/every":157}],54:[function(a,b,f){b=a("../../Observable");a=a("../../operator/expand");b.Observable.prototype.expand=a.expand},{"../../Observable":3,"../../operator/expand":158}],55:[function(a,b,f){b=a("../../Observable");a=a("../../operator/filter");b.Observable.prototype.filter=
                +a.filter},{"../../Observable":3,"../../operator/filter":159}],56:[function(a,b,f){b=a("../../Observable");a=a("../../operator/finally");b.Observable.prototype["finally"]=a._finally},{"../../Observable":3,"../../operator/finally":160}],57:[function(a,b,f){b=a("../../Observable");a=a("../../operator/first");b.Observable.prototype.first=a.first},{"../../Observable":3,"../../operator/first":161}],58:[function(a,b,f){b=a("../../Observable");a=a("../../operator/groupBy");b.Observable.prototype.groupBy=
                +a.groupBy},{"../../Observable":3,"../../operator/groupBy":162}],59:[function(a,b,f){b=a("../../Observable");a=a("../../operator/ignoreElements");b.Observable.prototype.ignoreElements=a.ignoreElements},{"../../Observable":3,"../../operator/ignoreElements":163}],60:[function(a,b,f){b=a("../../Observable");a=a("../../operator/inspect");b.Observable.prototype.inspect=a.inspect},{"../../Observable":3,"../../operator/inspect":164}],61:[function(a,b,f){b=a("../../Observable");a=a("../../operator/inspectTime");
                +b.Observable.prototype.inspectTime=a.inspectTime},{"../../Observable":3,"../../operator/inspectTime":165}],62:[function(a,b,f){b=a("../../Observable");a=a("../../operator/last");b.Observable.prototype.last=a.last},{"../../Observable":3,"../../operator/last":166}],63:[function(a,b,f){b=a("../../Observable");a=a("../../operator/let");b.Observable.prototype.let=a.letProto;b.Observable.prototype.letBind=a.letProto},{"../../Observable":3,"../../operator/let":167}],64:[function(a,b,f){b=a("../../Observable");
                +a=a("../../operator/map");b.Observable.prototype.map=a.map},{"../../Observable":3,"../../operator/map":168}],65:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mapTo");b.Observable.prototype.mapTo=a.mapTo},{"../../Observable":3,"../../operator/mapTo":169}],66:[function(a,b,f){b=a("../../Observable");a=a("../../operator/materialize");b.Observable.prototype.materialize=a.materialize},{"../../Observable":3,"../../operator/materialize":170}],67:[function(a,b,f){b=a("../../Observable");a=
                +a("../../operator/merge");b.Observable.prototype.merge=a.merge},{"../../Observable":3,"../../operator/merge":171}],68:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeAll");b.Observable.prototype.mergeAll=a.mergeAll},{"../../Observable":3,"../../operator/mergeAll":172}],69:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeMap");b.Observable.prototype.mergeMap=a.mergeMap;b.Observable.prototype.flatMap=a.mergeMap},{"../../Observable":3,"../../operator/mergeMap":173}],
                +70:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeMapTo");b.Observable.prototype.mergeMapTo=a.mergeMapTo},{"../../Observable":3,"../../operator/mergeMapTo":174}],71:[function(a,b,f){b=a("../../Observable");a=a("../../operator/multicast");b.Observable.prototype.multicast=a.multicast},{"../../Observable":3,"../../operator/multicast":175}],72:[function(a,b,f){b=a("../../Observable");a=a("../../operator/observeOn");b.Observable.prototype.observeOn=a.observeOn},{"../../Observable":3,
                +"../../operator/observeOn":176}],73:[function(a,b,f){b=a("../../Observable");a=a("../../operator/partition");b.Observable.prototype.partition=a.partition},{"../../Observable":3,"../../operator/partition":177}],74:[function(a,b,f){b=a("../../Observable");a=a("../../operator/pluck");b.Observable.prototype.pluck=a.pluck},{"../../Observable":3,"../../operator/pluck":178}],75:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publish");b.Observable.prototype.publish=a.publish},{"../../Observable":3,
                +"../../operator/publish":179}],76:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishBehavior");b.Observable.prototype.publishBehavior=a.publishBehavior},{"../../Observable":3,"../../operator/publishBehavior":180}],77:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishLast");b.Observable.prototype.publishLast=a.publishLast},{"../../Observable":3,"../../operator/publishLast":181}],78:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishReplay");b.Observable.prototype.publishReplay=
                +a.publishReplay},{"../../Observable":3,"../../operator/publishReplay":182}],79:[function(a,b,f){b=a("../../Observable");a=a("../../operator/race");b.Observable.prototype.race=a.race},{"../../Observable":3,"../../operator/race":183}],80:[function(a,b,f){b=a("../../Observable");a=a("../../operator/reduce");b.Observable.prototype.reduce=a.reduce},{"../../Observable":3,"../../operator/reduce":184}],81:[function(a,b,f){b=a("../../Observable");a=a("../../operator/repeat");b.Observable.prototype.repeat=
                +a.repeat},{"../../Observable":3,"../../operator/repeat":185}],82:[function(a,b,f){b=a("../../Observable");a=a("../../operator/retry");b.Observable.prototype.retry=a.retry},{"../../Observable":3,"../../operator/retry":186}],83:[function(a,b,f){b=a("../../Observable");a=a("../../operator/retryWhen");b.Observable.prototype.retryWhen=a.retryWhen},{"../../Observable":3,"../../operator/retryWhen":187}],84:[function(a,b,f){b=a("../../Observable");a=a("../../operator/sample");b.Observable.prototype.sample=
                +a.sample},{"../../Observable":3,"../../operator/sample":188}],85:[function(a,b,f){b=a("../../Observable");a=a("../../operator/sampleTime");b.Observable.prototype.sampleTime=a.sampleTime},{"../../Observable":3,"../../operator/sampleTime":189}],86:[function(a,b,f){b=a("../../Observable");a=a("../../operator/scan");b.Observable.prototype.scan=a.scan},{"../../Observable":3,"../../operator/scan":190}],87:[function(a,b,f){b=a("../../Observable");a=a("../../operator/share");b.Observable.prototype.share=
                +a.share},{"../../Observable":3,"../../operator/share":191}],88:[function(a,b,f){b=a("../../Observable");a=a("../../operator/single");b.Observable.prototype.single=a.single},{"../../Observable":3,"../../operator/single":192}],89:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skip");b.Observable.prototype.skip=a.skip},{"../../Observable":3,"../../operator/skip":193}],90:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skipUntil");b.Observable.prototype.skipUntil=a.skipUntil},
                +{"../../Observable":3,"../../operator/skipUntil":194}],91:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skipWhile");b.Observable.prototype.skipWhile=a.skipWhile},{"../../Observable":3,"../../operator/skipWhile":195}],92:[function(a,b,f){b=a("../../Observable");a=a("../../operator/startWith");b.Observable.prototype.startWith=a.startWith},{"../../Observable":3,"../../operator/startWith":196}],93:[function(a,b,f){b=a("../../Observable");a=a("../../operator/subscribeOn");b.Observable.prototype.subscribeOn=
                +a.subscribeOn},{"../../Observable":3,"../../operator/subscribeOn":197}],94:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switch");b.Observable.prototype["switch"]=a._switch},{"../../Observable":3,"../../operator/switch":198}],95:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switchMap");b.Observable.prototype.switchMap=a.switchMap},{"../../Observable":3,"../../operator/switchMap":199}],96:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switchMapTo");b.Observable.prototype.switchMapTo=
                +a.switchMapTo},{"../../Observable":3,"../../operator/switchMapTo":200}],97:[function(a,b,f){b=a("../../Observable");a=a("../../operator/take");b.Observable.prototype.take=a.take},{"../../Observable":3,"../../operator/take":201}],98:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeLast");b.Observable.prototype.takeLast=a.takeLast},{"../../Observable":3,"../../operator/takeLast":202}],99:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeUntil");b.Observable.prototype.takeUntil=
                +a.takeUntil},{"../../Observable":3,"../../operator/takeUntil":203}],100:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeWhile");b.Observable.prototype.takeWhile=a.takeWhile},{"../../Observable":3,"../../operator/takeWhile":204}],101:[function(a,b,f){b=a("../../Observable");a=a("../../operator/throttle");b.Observable.prototype.throttle=a.throttle},{"../../Observable":3,"../../operator/throttle":205}],102:[function(a,b,f){b=a("../../Observable");a=a("../../operator/throttleTime");b.Observable.prototype.throttleTime=
                +a.throttleTime},{"../../Observable":3,"../../operator/throttleTime":206}],103:[function(a,b,f){b=a("../../Observable");a=a("../../operator/timeout");b.Observable.prototype.timeout=a.timeout},{"../../Observable":3,"../../operator/timeout":207}],104:[function(a,b,f){b=a("../../Observable");a=a("../../operator/timeoutWith");b.Observable.prototype.timeoutWith=a.timeoutWith},{"../../Observable":3,"../../operator/timeoutWith":208}],105:[function(a,b,f){b=a("../../Observable");a=a("../../operator/toArray");
                +b.Observable.prototype.toArray=a.toArray},{"../../Observable":3,"../../operator/toArray":209}],106:[function(a,b,f){b=a("../../Observable");a=a("../../operator/toPromise");b.Observable.prototype.toPromise=a.toPromise},{"../../Observable":3,"../../operator/toPromise":210}],107:[function(a,b,f){b=a("../../Observable");a=a("../../operator/window");b.Observable.prototype.window=a.window},{"../../Observable":3,"../../operator/window":211}],108:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowCount");
                +b.Observable.prototype.windowCount=a.windowCount},{"../../Observable":3,"../../operator/windowCount":212}],109:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowTime");b.Observable.prototype.windowTime=a.windowTime},{"../../Observable":3,"../../operator/windowTime":213}],110:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowToggle");b.Observable.prototype.windowToggle=a.windowToggle},{"../../Observable":3,"../../operator/windowToggle":214}],111:[function(a,b,f){b=
                +a("../../Observable");a=a("../../operator/windowWhen");b.Observable.prototype.windowWhen=a.windowWhen},{"../../Observable":3,"../../operator/windowWhen":215}],112:[function(a,b,f){b=a("../../Observable");a=a("../../operator/withLatestFrom");b.Observable.prototype.withLatestFrom=a.withLatestFrom},{"../../Observable":3,"../../operator/withLatestFrom":216}],113:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zip");b.Observable.prototype.zip=a.zipProto},{"../../Observable":3,"../../operator/zip":217}],
                +114:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zipAll");b.Observable.prototype.zipAll=a.zipAll},{"../../Observable":3,"../../operator/zipAll":218}],115:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("./ScalarObservable"),l=a("./EmptyObservable");a=function(a){function e(d,c,e,n){a.call(this);
                +this.arrayLike=d;this.scheduler=n;c||n||1!==d.length||(this._isScalar=!0,this.value=d[0]);c&&(this.mapFn=c.bind(e))}g(e,a);e.create=function(a,c,m,n){var b=a.length;return 0===b?new l.EmptyObservable:1!==b||c?new e(a,c,m,n):new k.ScalarObservable(a[0],n)};e.dispatch=function(a){var c=a.arrayLike,e=a.index,n=a.length,b=a.mapFn,h=a.subscriber;h.isUnsubscribed||(e>=n?h.complete():(c=b?b(c[e],e):c[e],h.next(c),a.index=e+1,this.schedule(a)))};e.prototype._subscribe=function(a){var c=this.arrayLike,m=this.mapFn,
                +n=this.scheduler,b=c.length;if(n)return n.schedule(e.dispatch,0,{arrayLike:c,index:0,length:b,mapFn:m,subscriber:a});for(n=0;n<b&&!a.isUnsubscribed;n++){var h=m?m(c[n],n):c[n];a.next(h)}a.complete()};return e}(b.Observable);f.ArrayLikeObservable=a},{"../Observable":3,"./EmptyObservable":121,"./ScalarObservable":132}],116:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=
                +d.prototype,new c)};b=a("../Observable");var k=a("./ScalarObservable"),l=a("./EmptyObservable"),h=a("../util/isScheduler");a=function(a){function d(c,d){a.call(this);this.array=c;this.scheduler=d;d||1!==c.length||(this._isScalar=!0,this.value=c[0])}g(d,a);d.create=function(a,e){return new d(a,e)};d.of=function(){for(var a=[],e=0;e<arguments.length;e++)a[e-0]=arguments[e];e=a[a.length-1];h.isScheduler(e)?a.pop():e=null;var n=a.length;return 1<n?new d(a,e):1===n?new k.ScalarObservable(a[0],e):new l.EmptyObservable(e)};
                +d.dispatch=function(a){var d=a.array,e=a.index,b=a.subscriber;e>=a.count?b.complete():(b.next(d[e]),b.isUnsubscribed||(a.index=e+1,this.schedule(a)))};d.prototype._subscribe=function(a){var e=this.array,n=e.length,b=this.scheduler;if(b)return b.schedule(d.dispatch,0,{array:e,index:0,count:n,subscriber:a});for(b=0;b<n&&!a.isUnsubscribed;b++)a.next(e[b]);a.complete()};return d}(b.Observable);f.ArrayObservable=a},{"../Observable":3,"../util/isScheduler":246,"./EmptyObservable":121,"./ScalarObservable":132}],
                +117:[function(a,b,f){function g(a){var n=this,b=a.source;a=a.subscriber;var h=b.callbackFunc,f=b.args,g=b.scheduler,r=b.subject;if(!r){var r=b.subject=new c.AsyncSubject,v=function x(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var m=x.source,c=m.selector,m=m.subject;c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?n.add(g.schedule(l,0,{err:d.errorObject.e,subject:m})):n.add(g.schedule(k,0,{value:a,subject:m}))):n.add(g.schedule(k,0,{value:1===a.length?a[0]:a,subject:m}))};v.source=
                +b;e.tryCatch(h).apply(this,f.concat(v))===d.errorObject&&r.error(d.errorObject.e)}n.add(r.subscribe(a))}function k(a){var c=a.subject;c.next(a.value);c.complete()}function l(a){a.subject.error(a.err)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Observable");var e=a("../util/tryCatch"),d=a("../util/errorObject"),c=a("../subject/AsyncSubject");a=
                +function(a){function n(c,d,e,n){a.call(this);this.callbackFunc=c;this.selector=d;this.args=e;this.scheduler=n}h(n,a);n.create=function(a,c,d){void 0===c&&(c=void 0);return function(){for(var e=[],m=0;m<arguments.length;m++)e[m-0]=arguments[m];return new n(a,c,e,d)}};n.prototype._subscribe=function(a){var m=this.callbackFunc,n=this.args,b=this.scheduler,h=this.subject;if(b)return b.schedule(g,0,{source:this,subscriber:a});h||(h=this.subject=new c.AsyncSubject,b=function y(){for(var a=[],c=0;c<arguments.length;c++)a[c-
                +0]=arguments[c];var m=y.source,c=m.selector,m=m.subject;c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?m.error(d.errorObject.e):(m.next(a),m.complete())):(m.next(1===a.length?a[0]:a),m.complete())},b.source=this,e.tryCatch(m).apply(this,n.concat(b))===d.errorObject&&h.error(d.errorObject.e));return h.subscribe(a)};return n}(b.Observable);f.BoundCallbackObservable=a},{"../Observable":3,"../subject/AsyncSubject":226,"../util/errorObject":239,"../util/tryCatch":253}],118:[function(a,b,f){function g(a){var n=
                +this,b=a.source;a=a.subscriber;var h=b.callbackFunc,f=b.args,g=b.scheduler,r=b.subject;if(!r){var r=b.subject=new c.AsyncSubject,v=function x(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var m=x.source,c=m.selector,m=m.subject,b=a.shift();b?m.error(b):c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?n.add(g.schedule(l,0,{err:d.errorObject.e,subject:m})):n.add(g.schedule(k,0,{value:a,subject:m}))):n.add(g.schedule(k,0,{value:1===a.length?a[0]:a,subject:m}))};v.source=b;e.tryCatch(h).apply(this,
                +f.concat(v))===d.errorObject&&r.error(d.errorObject.e)}n.add(r.subscribe(a))}function k(a){var c=a.subject;c.next(a.value);c.complete()}function l(a){a.subject.error(a.err)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Observable");var e=a("../util/tryCatch"),d=a("../util/errorObject"),c=a("../subject/AsyncSubject");a=function(a){function b(c,d,
                +e,n){a.call(this);this.callbackFunc=c;this.selector=d;this.args=e;this.scheduler=n}h(b,a);b.create=function(a,c,d){void 0===c&&(c=void 0);return function(){for(var e=[],m=0;m<arguments.length;m++)e[m-0]=arguments[m];return new b(a,c,e,d)}};b.prototype._subscribe=function(a){var m=this.callbackFunc,b=this.args,n=this.scheduler,h=this.subject;if(n)return n.schedule(g,0,{source:this,subscriber:a});h||(h=this.subject=new c.AsyncSubject,n=function y(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];
                +var m=y.source,c=m.selector,m=m.subject,b=a.shift();b?m.error(b):c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?m.error(d.errorObject.e):(m.next(a),m.complete())):(m.next(1===a.length?a[0]:a),m.complete())},n.source=this,e.tryCatch(m).apply(this,b.concat(n))===d.errorObject&&h.error(d.errorObject.e));return h.subscribe(a)};return b}(b.Observable);f.BoundNodeCallbackObservable=a},{"../Observable":3,"../subject/AsyncSubject":226,"../util/errorObject":239,"../util/tryCatch":253}],119:[function(a,
                +b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)};b=a("../Observable");var k=a("../Subscriber");a=a("../Subscription");var l=function(a){function d(e,m){a.call(this);this.source=e;this.subjectFactory=m}g(d,a);d.prototype._subscribe=function(a){return this.getSubject().subscribe(a)};d.prototype.getSubject=function(){var a=this.subject;return a&&!a.isUnsubscribed?
                +a:this.subject=this.subjectFactory()};d.prototype.connect=function(){var a=this.subscription;if(a&&!a.isUnsubscribed)return a;a=this.source.subscribe(this.getSubject());a.add(new h(this));return this.subscription=a};d.prototype.refCount=function(){return new e(this)};d.prototype._closeSubscription=function(){this.subscription=this.subject=null};return d}(b.Observable);f.ConnectableObservable=l;var h=function(a){function d(e){a.call(this);this.connectable=e}g(d,a);d.prototype._unsubscribe=function(){this.connectable._closeSubscription();
                +this.connectable=null};return d}(a.Subscription),e=function(a){function e(d,m){void 0===m&&(m=0);a.call(this);this.connectable=d;this.refCount=m}g(e,a);e.prototype._subscribe=function(a){var c=this.connectable;a=new d(a,this);var e=c.subscribe(a);e.isUnsubscribed||1!==++this.refCount||(a.connection=this.connection=c.connect());return e};return e}(b.Observable),d=function(a){function d(e,m){a.call(this,null);this.destination=e;this.refCountObservable=m;this.connection=m.connection;e.add(this)}g(d,
                +a);d.prototype._next=function(a){this.destination.next(a)};d.prototype._error=function(a){this._resetConnectable();this.destination.error(a)};d.prototype._complete=function(){this._resetConnectable();this.destination.complete()};d.prototype._resetConnectable=function(){var a=this.refCountObservable,c=a.connection,d=this.connection;d&&d===c&&(a.refCount=0,c.unsubscribe(),a.connection=null,this.unsubscribe())};d.prototype._unsubscribe=function(){var a=this.refCountObservable;if(0!==a.refCount&&0===
                +--a.refCount){var c=a.connection,d=this.connection;d&&d===c&&(c.unsubscribe(),a.connection=null)}};return d}(k.Subscriber)},{"../Observable":3,"../Subscriber":9,"../Subscription":10}],120:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("../util/tryCatch"),l=a("../util/errorObject");a=function(a){function e(d){a.call(this);
                +this.observableFactory=d}g(e,a);e.create=function(a){return new e(a)};e.prototype._subscribe=function(a){var c=k.tryCatch(this.observableFactory)();c===l.errorObject?a.error(l.errorObject.e):c.subscribe(a)};return e}(b.Observable);f.DeferObservable=a},{"../Observable":3,"../util/errorObject":239,"../util/tryCatch":253}],121:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):
                +(h.prototype=b.prototype,new h)};a=function(a){function b(h){a.call(this);this.scheduler=h}g(b,a);b.create=function(a){return new b(a)};b.dispatch=function(a){a.subscriber.complete()};b.prototype._subscribe=function(a){var e=this.scheduler;if(e)return e.schedule(b.dispatch,0,{subscriber:a});a.complete()};return b}(a("../Observable").Observable);f.EmptyObservable=a},{"../Observable":3}],122:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
                +(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e){a.call(this);this.error=h;this.scheduler=e}g(b,a);b.create=function(a,e){return new b(a,e)};b.dispatch=function(a){a.subscriber.error(a.error)};b.prototype._subscribe=function(a){var e=this.error,d=this.scheduler;if(d)return d.schedule(b.dispatch,0,{error:e,subscriber:a});a.error(e)};return b}(a("../Observable").Observable);f.ErrorObservable=a},{"../Observable":3}],123:[function(a,b,f){function g(a){return null!==
                +a}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../Observable");b=a("../Subscriber");var h=a("./PromiseObservable"),e=a("./EmptyObservable"),d=a("../util/isPromise"),c=a("../util/isArray");a=function(a){function b(c,d){a.call(this);this.sources=c;this.resultSelector=d}k(b,a);b.create=function(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];
                +if(null===a||0===arguments.length)return new e.EmptyObservable;d=null;"function"===typeof a[a.length-1]&&(d=a.pop());1===a.length&&c.isArray(a[0])&&(a=a[0]);return 0===a.length?new e.EmptyObservable:new b(a,d)};b.prototype._subscribe=function(a){for(var c=this.sources,e=c.length,b=[],n=0;n<e;n++)b.push(null);b={completed:0,total:e,values:b,selector:this.resultSelector};for(n=0;n<e;n++){var q=c[n];d.isPromise(q)&&(q=new h.PromiseObservable(q));q.subscribe(new m(a,n,b))}};return b}(l.Observable);f.ForkJoinObservable=
                +a;var m=function(a){function c(d,e,m){a.call(this,d);this.index=e;this.context=m;this._value=null}k(c,a);c.prototype._next=function(a){this._value=a};c.prototype._complete=function(){var a=this.destination;null==this._value&&a.complete();var c=this.context;c.completed++;c.values[this.index]=this._value;var d=c.values;c.completed===d.length&&(d.every(g)&&(c=c.selector?c.selector.apply(this,d):d,a.next(c)),a.complete())};return c}(b.Subscriber)},{"../Observable":3,"../Subscriber":9,"../util/isArray":240,
                +"../util/isPromise":245,"./EmptyObservable":121,"./PromiseObservable":130}],124:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Observable");var k=a("../util/tryCatch"),l=a("../util/errorObject"),h=a("../Subscription");a=function(a){function d(c,d,b){a.call(this);this.sourceObj=c;this.eventName=d;this.selector=b}g(d,a);d.create=function(a,
                +e,b){return new d(a,e,b)};d.setupSubscription=function(a,e,b,q){var f;if(a&&"[object NodeList]"===a.toString()||a&&"[object HTMLCollection]"===a.toString())for(var l=0,k=a.length;l<k;l++)d.setupSubscription(a[l],e,b,q);else a&&"function"===typeof a.addEventListener&&"function"===typeof a.removeEventListener?(a.addEventListener(e,b),f=function(){return a.removeEventListener(e,b)}):a&&"function"===typeof a.on&&"function"===typeof a.off?(a.on(e,b),f=function(){return a.off(e,b)}):a&&"function"===typeof a.addListener&&
                +"function"===typeof a.removeListener&&(a.addListener(e,b),f=function(){return a.removeListener(e,b)});q.add(new h.Subscription(f))};d.prototype._subscribe=function(a){var e=this.selector;d.setupSubscription(this.sourceObj,this.eventName,e?function(){for(var d=[],b=0;b<arguments.length;b++)d[b-0]=arguments[b];d=k.tryCatch(e).apply(void 0,d);d===l.errorObject?a.error(l.errorObject.e):a.next(d)}:function(d){return a.next(d)},a)};return d}(b.Observable);f.FromEventObservable=a},{"../Observable":3,"../Subscription":10,
                +"../util/errorObject":239,"../util/tryCatch":253}],125:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Observable");var k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");a=function(a){function d(c,d,b){a.call(this);this.addHandler=c;this.removeHandler=d;this.selector=b}g(d,a);d.create=function(a,e,b){return new d(a,
                +e,b)};d.prototype._subscribe=function(a){var d=this.removeHandler,e=this.selector,b=e?function(d){var m=l.tryCatch(e).apply(null,arguments);m===h.errorObject?a.error(m.e):a.next(m)}:function(d){a.next(d)},f=l.tryCatch(this.addHandler)(b);f===h.errorObject&&a.error(f.e);a.add(new k.Subscription(function(){d(b)}))};return d}(b.Observable);f.FromEventPatternObservable=a},{"../Observable":3,"../Subscription":10,"../util/errorObject":239,"../util/tryCatch":253}],126:[function(a,b,f){var g=this&&this.__extends||
                +function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../util/isArray"),l=a("../util/isFunction"),h=a("../util/isPromise"),e=a("../util/isScheduler"),d=a("./PromiseObservable"),c=a("./IteratorObservable"),m=a("./ArrayObservable"),n=a("./ArrayLikeObservable"),q=a("../util/SymbolShim"),p=a("../Observable"),u=a("../operator/observeOn");a=function(a){function b(c,d){a.call(this,null);this.ish=
                +c;this.scheduler=d}g(b,a);b.create=function(a,f,g,u){var t=null,z=null;l.isFunction(f)?(t=u||null,z=f):e.isScheduler(t)&&(t=f);if(null!=a){if("function"===typeof a[q.SymbolShim.observable])return a instanceof p.Observable&&!t?a:new b(a,t);if(k.isArray(a))return new m.ArrayObservable(a,t);if(h.isPromise(a))return new d.PromiseObservable(a,t);if("function"===typeof a[q.SymbolShim.iterator]||"string"===typeof a)return new c.IteratorObservable(a,null,null,t);if(a&&"number"===typeof a.length)return new n.ArrayLikeObservable(a,
                +z,g,t)}throw new TypeError((null!==a&&typeof a||a)+" is not observable");};b.prototype._subscribe=function(a){var c=this.ish,d=this.scheduler;return null==d?c[q.SymbolShim.observable]().subscribe(a):c[q.SymbolShim.observable]().subscribe(new u.ObserveOnSubscriber(a,d,0))};return b}(p.Observable);f.FromObservable=a},{"../Observable":3,"../operator/observeOn":176,"../util/SymbolShim":238,"../util/isArray":240,"../util/isFunction":242,"../util/isPromise":245,"../util/isScheduler":246,"./ArrayLikeObservable":115,
                +"./ArrayObservable":116,"./IteratorObservable":128,"./PromiseObservable":130}],127:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)},k=a("../util/isNumeric");b=a("../Observable");var l=a("../scheduler/asap");a=function(a){function e(d,c){void 0===d&&(d=0);void 0===c&&(c=l.asap);a.call(this);this.period=d;this.scheduler=c;if(!k.isNumeric(d)||
                +0>d)this.period=0;c&&"function"===typeof c.schedule||(this.scheduler=l.asap)}g(e,a);e.create=function(a,c){void 0===a&&(a=0);void 0===c&&(c=l.asap);return new e(a,c)};e.dispatch=function(a){var c=a.subscriber,e=a.period;c.next(a.index);c.isUnsubscribed||(a.index+=1,this.schedule(a,e))};e.prototype._subscribe=function(a){var c=this.period;a.add(this.scheduler.schedule(e.dispatch,c,{index:0,subscriber:a,period:c}))};return e}(b.Observable);f.IntervalObservable=a},{"../Observable":3,"../scheduler/asap":224,
                +"../util/isNumeric":243}],128:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../util/root"),l=a("../util/isObject"),h=a("../util/tryCatch");b=a("../Observable");var e=a("../util/isFunction"),d=a("../util/SymbolShim"),c=a("../util/errorObject");a=function(a){function b(c,h,f,q){a.call(this);if(null==c)throw Error("iterator cannot be null.");
                +if(l.isObject(h))this.thisArg=h,this.scheduler=f;else if(e.isFunction(h))this.project=h,this.thisArg=f,this.scheduler=q;else if(null!=h)throw Error("When provided, `project` must be a function.");if((h=c[d.SymbolShim.iterator])||"string"!==typeof c)if(h||void 0===c.length){if(!h)throw new TypeError("Object is not iterable");c=c[d.SymbolShim.iterator]()}else c=new n(c);else c=new m(c);this.iterator=c}g(b,a);b.create=function(a,c,d,e){return new b(a,c,d,e)};b.dispatch=function(a){var d=a.index,e=a.thisArg,
                +m=a.project,b=a.iterator,n=a.subscriber;a.hasError?n.error(a.error):(b=b.next(),b.done?n.complete():(m?(b=h.tryCatch(m).call(e,b.value,d),b===c.errorObject?(a.error=c.errorObject.e,a.hasError=!0):(n.next(b),a.index=d+1)):(n.next(b.value),a.index=d+1),n.isUnsubscribed||this.schedule(a)))};b.prototype._subscribe=function(a){var d=0,e=this.iterator,m=this.project,n=this.thisArg,f=this.scheduler;if(f)return f.schedule(b.dispatch,0,{index:d,thisArg:n,project:m,iterator:e,subscriber:a});do{f=e.next();if(f.done){a.complete();
                +break}else if(m){f=h.tryCatch(m).call(n,f.value,d++);if(f===c.errorObject){a.error(c.errorObject.e);break}a.next(f)}else a.next(f.value);if(a.isUnsubscribed)break}while(1)};return b}(b.Observable);f.IteratorObservable=a;var m=function(){function a(c,d,e){void 0===d&&(d=0);void 0===e&&(e=c.length);this.str=c;this.idx=d;this.len=e}a.prototype[d.SymbolShim.iterator]=function(){return this};a.prototype.next=function(){return this.idx<this.len?{done:!1,value:this.str.charAt(this.idx++)}:{done:!0,value:void 0}};
                +return a}(),n=function(){function a(c,d,e){void 0===d&&(d=0);if(void 0===e)if(e=+c.length,isNaN(e))e=0;else if(0!==e&&"number"===typeof e&&k.root.isFinite(e)){var m;m=+e;m=0===m?m:isNaN(m)?m:0>m?-1:1;e=m*Math.floor(Math.abs(e));e=0>=e?0:e>q?q:e}this.arr=c;this.idx=d;this.len=e}a.prototype[d.SymbolShim.iterator]=function(){return this};a.prototype.next=function(){return this.idx<this.len?{done:!1,value:this.arr[this.idx++]}:{done:!0,value:void 0}};return a}(),q=Math.pow(2,53)-1},{"../Observable":3,
                +"../util/SymbolShim":238,"../util/errorObject":239,"../util/isFunction":242,"../util/isObject":244,"../util/root":249,"../util/tryCatch":253}],129:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)};b=a("../Observable");var k=a("../util/noop");a=function(a){function b(){a.call(this)}g(b,a);b.create=function(){return new b};b.prototype._subscribe=
                +function(a){k.noop()};return b}(b.Observable);f.NeverObservable=a},{"../Observable":3,"../util/noop":247}],130:[function(a,b,f){function g(a){var d=a.value;a=a.subscriber;a.isUnsubscribed||(a.next(d),a.complete())}function k(a){var d=a.err;a=a.subscriber;a.isUnsubscribed||a.error(d)}var l=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)},h=a("../util/root");a=function(a){function d(c,
                +d){void 0===d&&(d=null);a.call(this);this.promise=c;this.scheduler=d}l(d,a);d.create=function(a,e){void 0===e&&(e=null);return new d(a,e)};d.prototype._subscribe=function(a){var d=this,e=this.promise,b=this.scheduler;if(null==b)this._isScalar?a.isUnsubscribed||(a.next(this.value),a.complete()):e.then(function(e){d.value=e;d._isScalar=!0;a.isUnsubscribed||(a.next(e),a.complete())},function(d){a.isUnsubscribed||a.error(d)}).then(null,function(a){h.root.setTimeout(function(){throw a;})});else if(this._isScalar){if(!a.isUnsubscribed)return b.schedule(g,
                +0,{value:this.value,subscriber:a})}else e.then(function(e){d.value=e;d._isScalar=!0;a.isUnsubscribed||a.add(b.schedule(g,0,{value:e,subscriber:a}))},function(d){a.isUnsubscribed||a.add(b.schedule(k,0,{err:d,subscriber:a}))}).then(null,function(a){h.root.setTimeout(function(){throw a;})})};return d}(a("../Observable").Observable);f.PromiseObservable=a},{"../Observable":3,"../util/root":249}],131:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
                +(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e,d){a.call(this);this.start=h;this.end=e;this.scheduler=d}g(b,a);b.create=function(a,e,d){void 0===a&&(a=0);void 0===e&&(e=0);return new b(a,e,d)};b.dispatch=function(a){var e=a.start,d=a.index,c=a.subscriber;d>=a.end?c.complete():(c.next(e),c.isUnsubscribed||(a.index=d+1,a.start=e+1,this.schedule(a)))};b.prototype._subscribe=function(a){var e=0,d=this.start,c=this.end,m=this.scheduler;if(m)return m.schedule(b.dispatch,
                +0,{index:e,end:c,start:d,subscriber:a});do{if(e++>=c){a.complete();break}a.next(d++);if(a.isUnsubscribed)break}while(1)};return b}(a("../Observable").Observable);f.RangeObservable=a},{"../Observable":3}],132:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e){a.call(this);this.value=h;this.scheduler=e;this._isScalar=
                +!0}g(b,a);b.create=function(a,e){return new b(a,e)};b.dispatch=function(a){var e=a.value,d=a.subscriber;a.done?d.complete():(d.next(e),d.isUnsubscribed||(a.done=!0,this.schedule(a)))};b.prototype._subscribe=function(a){var e=this.value,d=this.scheduler;if(d)return d.schedule(b.dispatch,0,{done:!1,value:e,subscriber:a});a.next(e);a.isUnsubscribed||a.complete()};return b}(a("../Observable").Observable);f.ScalarObservable=a},{"../Observable":3}],133:[function(a,b,f){var g=this&&this.__extends||function(a,
                +e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("../scheduler/asap"),l=a("../util/isNumeric");a=function(a){function e(d,c,e){void 0===c&&(c=0);void 0===e&&(e=k.asap);a.call(this);this.source=d;this.delayTime=c;this.scheduler=e;if(!l.isNumeric(c)||0>c)this.delayTime=0;e&&"function"===typeof e.schedule||(this.scheduler=k.asap)}g(e,a);e.create=function(a,c,m){void 0===
                +c&&(c=0);void 0===m&&(m=k.asap);return new e(a,c,m)};e.dispatch=function(a){return a.source.subscribe(a.subscriber)};e.prototype._subscribe=function(a){return this.scheduler.schedule(e.dispatch,this.delayTime,{source:this.source,subscriber:a})};return e}(b.Observable);f.SubscribeOnObservable=a},{"../Observable":3,"../scheduler/asap":224,"../util/isNumeric":243}],134:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=
                +c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)},k=a("../util/isNumeric");b=a("../Observable");var l=a("../scheduler/asap"),h=a("../util/isScheduler"),e=a("../util/isDate");a=function(a){function c(c,b,f){void 0===c&&(c=0);a.call(this);this.period=-1;this.dueTime=0;k.isNumeric(b)?this.period=1>+b&&1||+b:h.isScheduler(b)&&(f=b);h.isScheduler(f)||(f=l.asap);this.scheduler=f;this.dueTime=e.isDate(c)?+c-this.scheduler.now():c}g(c,a);c.create=function(a,d,e){void 0===a&&(a=
                +0);return new c(a,d,e)};c.dispatch=function(a){var c=a.index,d=a.period,e=a.subscriber;e.next(c);if(!e.isUnsubscribed){if(-1===d)return e.complete();a.index=c+1;this.schedule(a,d)}};c.prototype._subscribe=function(a){return this.scheduler.schedule(c.dispatch,this.dueTime,{index:0,period:this.period,subscriber:a})};return c}(b.Observable);f.TimerObservable=a},{"../Observable":3,"../scheduler/asap":224,"../util/isDate":241,"../util/isNumeric":243,"../util/isScheduler":246}],135:[function(a,b,f){var g=
                +this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.buffer=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.closingNotifier=d}a.prototype.call=function(a){return new h(a,this.closingNotifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.buffer=[];this.add(k.subscribeToResult(this,
                +d))}g(d,a);d.prototype._next=function(a){this.buffer.push(a)};d.prototype.notifyNext=function(a,d,e,b,h){a=this.buffer;this.buffer=[];this.destination.next(a)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],136:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.bufferCount=function(a,
                +e){void 0===e&&(e=null);return this.lift(new k(a,e))};var k=function(){function a(e,d){this.bufferSize=e;this.startBufferEvery=d}a.prototype.call=function(a){return new l(a,this.bufferSize,this.startBufferEvery)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.bufferSize=c;this.startBufferEvery=e;this.buffers=[[]];this.count=0}g(e,a);e.prototype._next=function(a){var c=this.count+=1,e=this.destination,b=this.bufferSize,h=this.buffers,f=h.length,k=-1;0===c%(null==this.startBufferEvery?
                +b:this.startBufferEvery)&&h.push([]);for(c=0;c<f;c++){var l=h[c];l.push(a);l.length===b&&(k=c,e.next(l))}-1!==k&&h.splice(k,1)};e.prototype._complete=function(){for(var d=this.destination,c=this.buffers;0<c.length;){var e=c.shift();0<e.length&&d.next(e)}a.prototype._complete.call(this)};return e}(a.Subscriber)},{"../Subscriber":9}],137:[function(a,b,f){function g(a){var c=a.subscriber,d=a.buffer;d&&c.closeBuffer(d);a.buffer=c.openBuffer();c.isUnsubscribed||this.schedule(a,a.bufferTimeSpan)}function k(a){var c=
                +a.bufferCreationInterval,d=a.bufferTimeSpan,e=a.subscriber,b=a.scheduler,h=e.openBuffer();e.isUnsubscribed||(this.add(b.schedule(l,d,{subscriber:e,buffer:h})),this.schedule(a,c))}function l(a){a.subscriber.closeBuffer(a.buffer)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var e=a("../scheduler/asap");f.bufferTime=function(a,c,b){void 0===
                +c&&(c=null);void 0===b&&(b=e.asap);return this.lift(new d(a,c,b))};var d=function(){function a(c,d,e){this.bufferTimeSpan=c;this.bufferCreationInterval=d;this.scheduler=e}a.prototype.call=function(a){return new c(a,this.bufferTimeSpan,this.bufferCreationInterval,this.scheduler)};return a}(),c=function(a){function c(d,e,b,n){a.call(this,d);this.bufferTimeSpan=e;this.bufferCreationInterval=b;this.scheduler=n;this.buffers=[];d=this.openBuffer();if(null!==b&&0<=b){var h={bufferTimeSpan:e,bufferCreationInterval:b,
                +subscriber:this,scheduler:n};this.add(n.schedule(l,e,{subscriber:this,buffer:d}));this.add(n.schedule(k,b,h))}else this.add(n.schedule(g,e,{subscriber:this,buffer:d,bufferTimeSpan:e}))}h(c,a);c.prototype._next=function(a){for(var c=this.buffers,d=c.length,e=0;e<d;e++)c[e].push(a)};c.prototype._error=function(c){this.buffers.length=0;a.prototype._error.call(this,c)};c.prototype._complete=function(){for(var c=this.buffers,d=this.destination;0<c.length;)d.next(c.shift());a.prototype._complete.call(this)};
                +c.prototype._unsubscribe=function(){this.buffers=null};c.prototype.openBuffer=function(){var a=[];this.buffers.push(a);return a};c.prototype.closeBuffer=function(a){this.destination.next(a);var c=this.buffers;c.splice(c.indexOf(a),1)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],138:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,
                +new d)};b=a("../Subscriber");var k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");f.bufferToggle=function(a,c){return this.lift(new e(a,c))};var e=function(){function a(c,d){this.openings=c;this.closingSelector=d}a.prototype.call=function(a){return new d(a,this.openings,this.closingSelector)};return a}(),d=function(a){function d(e,b,m){a.call(this,e);this.openings=b;this.closingSelector=m;this.contexts=[];this.add(this.openings.subscribe(new c(this)))}g(d,a);d.prototype._next=
                +function(a){for(var c=this.contexts,d=c.length,e=0;e<d;e++)c[e].buffer.push(a)};d.prototype._error=function(c){for(var d=this.contexts;0<d.length;){var e=d.shift();e.subscription.unsubscribe();e.buffer=null;e.subscription=null}this.contexts=null;a.prototype._error.call(this,c)};d.prototype._complete=function(){for(var c=this.contexts;0<c.length;){var d=c.shift();this.destination.next(d.buffer);d.subscription.unsubscribe();d.buffer=null;d.subscription=null}this.contexts=null;a.prototype._complete.call(this)};
                +d.prototype.openBuffer=function(a){var c=this.contexts,d=l.tryCatch(this.closingSelector)(a);d===h.errorObject?this._error(h.errorObject.e):(a={buffer:[],subscription:new k.Subscription},c.push(a),c=new m(this,a),c=d.subscribe(c),a.subscription.add(c),this.add(c))};d.prototype.closeBuffer=function(a){var c=this.contexts;if(null!==c){var d=a.subscription;this.destination.next(a.buffer);c.splice(c.indexOf(a),1);this.remove(d);d.unsubscribe()}};return d}(b.Subscriber),c=function(a){function c(d){a.call(this,
                +null);this.parent=d}g(c,a);c.prototype._next=function(a){this.parent.openBuffer(a)};c.prototype._error=function(a){this.parent.error(a)};c.prototype._complete=function(){};return c}(b.Subscriber),m=function(a){function c(d,e){a.call(this,null);this.parent=d;this.context=e}g(c,a);c.prototype._next=function(){this.parent.closeBuffer(this.context)};c.prototype._error=function(a){this.parent.error(a)};c.prototype._complete=function(){this.parent.closeBuffer(this.context)};return c}(b.Subscriber)},{"../Subscriber":9,
                +"../Subscription":10,"../util/errorObject":239,"../util/tryCatch":253}],139:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.bufferWhen=function(a){return this.lift(new d(a))};var d=function(){function a(c){this.closingSelector=
                +c}a.prototype.call=function(a){return new c(a,this.closingSelector)};return a}(),c=function(a){function c(d,e){a.call(this,d);this.closingSelector=e;this.subscribing=!1;this.openBuffer()}g(c,a);c.prototype._next=function(a){this.buffer.push(a)};c.prototype._complete=function(){var c=this.buffer;c&&this.destination.next(c);a.prototype._complete.call(this)};c.prototype._unsubscribe=function(){this.buffer=null;this.subscribing=!1};c.prototype.notifyNext=function(a,c,d,e,b){this.openBuffer()};c.prototype.notifyComplete=
                +function(){this.subscribing?this.complete():this.openBuffer()};c.prototype.openBuffer=function(){var a=this.closingSubscription;a&&(this.remove(a),a.unsubscribe());(a=this.buffer)&&this.destination.next(a);this.buffer=[];var c=l.tryCatch(this.closingSelector)();c===h.errorObject?this.error(h.errorObject.e):(this.closingSubscription=a=new k.Subscription,this.add(a),this.subscribing=!0,a.add(e.subscribeToResult(this,c)),this.subscribing=!1)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subscription":10,
                +"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],140:[function(a,b,f){var g=a("./publishReplay");f.cache=function(a,b,h){void 0===a&&(a=Number.POSITIVE_INFINITY);void 0===b&&(b=Number.POSITIVE_INFINITY);return g.publishReplay.call(this,a,b,h).refCount()}},{"./publishReplay":182}],141:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=
                +e.prototype,new d)};a=a("../Subscriber");f._catch=function(a){a=new k(a);var e=this.lift(a);return a.caught=e};var k=function(){function a(e){this.selector=e}a.prototype.call=function(a){return new l(a,this.selector,this.caught)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.selector=c;this.caught=e}g(e,a);e.prototype.error=function(a){if(!this.isStopped){var c=void 0;try{c=this.selector(a,this.caught)}catch(e){this.destination.error(e);return}this._innerSub(c)}};e.prototype._innerSub=
                +function(a){this.unsubscribe();this.destination.remove(this);a.subscribe(this.destination)};return e}(a.Subscriber)},{"../Subscriber":9}],142:[function(a,b,f){var g=a("./combineLatest");f.combineAll=function(a){return this.lift(new g.CombineLatestOperator(a))}},{"./combineLatest":143}],143:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},
                +k=a("../observable/ArrayObservable"),l=a("../util/isArray"),h=a("../util/isScheduler");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.combineLatest=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=null;"function"===typeof a[a.length-1]&&(c=a.pop());1===a.length&&l.isArray(a[0])&&(a=a[0]);a.unshift(this);return(new k.ArrayObservable(a)).lift(new d(c))};f.combineLatestStatic=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var e=c=null;
                +h.isScheduler(a[a.length-1])&&(e=a.pop());"function"===typeof a[a.length-1]&&(c=a.pop());1===a.length&&l.isArray(a[0])&&(a=a[0]);return(new k.ArrayObservable(a,e)).lift(new d(c))};var d=function(){function a(c){this.project=c}a.prototype.call=function(a){return new c(a,this.project)};return a}();f.CombineLatestOperator=d;var c=function(a){function c(d,e){a.call(this,d);this.project=e;this.active=0;this.values=[];this.observables=[];this.toRespond=[]}g(c,a);c.prototype._next=function(a){var c=this.toRespond;
                +c.push(c.length);this.observables.push(a)};c.prototype._complete=function(){var a=this.observables,c=a.length;if(0===c)this.destination.complete();else{this.active=c;for(var d=0;d<c;d++){var b=a[d];this.add(e.subscribeToResult(this,b,b,d))}}};c.prototype.notifyComplete=function(a){0===--this.active&&this.destination.complete()};c.prototype.notifyNext=function(a,c,d,e,b){a=this.values;a[d]=c;c=this.toRespond;0<c.length&&(d=c.indexOf(d),-1!==d&&c.splice(d,1));0===c.length&&(this.project?this._tryProject(a):
                +this.destination.next(a))};c.prototype._tryProject=function(a){var c;try{c=this.project.apply(this,a)}catch(d){this.destination.error(d);return}this.destination.next(c)};return c}(b.OuterSubscriber);f.CombineLatestSubscriber=c},{"../OuterSubscriber":6,"../observable/ArrayObservable":116,"../util/isArray":240,"../util/isScheduler":246,"../util/subscribeToResult":250}],144:[function(a,b,f){function g(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];d=null;k.isScheduler(a[a.length-1])&&
                +(d=a.pop());return(new l.ArrayObservable(a,d)).lift(new h.MergeAllOperator(1))}var k=a("../util/isScheduler"),l=a("../observable/ArrayObservable"),h=a("./mergeAll");f.concat=function(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];return g.apply(void 0,[this].concat(a))};f.concatStatic=g},{"../observable/ArrayObservable":116,"../util/isScheduler":246,"./mergeAll":172}],145:[function(a,b,f){var g=a("./mergeAll");f.concatAll=function(){return this.lift(new g.MergeAllOperator(1))}},{"./mergeAll":172}],
                +146:[function(a,b,f){var g=a("./mergeMap");f.concatMap=function(a,b){return this.lift(new g.MergeMapOperator(a,b,1))}},{"./mergeMap":173}],147:[function(a,b,f){var g=a("./mergeMapTo");f.concatMapTo=function(a,b){return this.lift(new g.MergeMapToOperator(a,b,1))}},{"./mergeMapTo":174}],148:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=
                +a("../Subscriber");f.count=function(a){return this.lift(new k(a,this))};var k=function(){function a(e,d){this.predicate=e;this.source=d}a.prototype.call=function(a){return new l(a,this.predicate,this.source)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.predicate=c;this.source=e;this.index=this.count=0}g(e,a);e.prototype._next=function(a){this.predicate?this._tryPredicate(a):this.count++};e.prototype._tryPredicate=function(a){var c;try{c=this.predicate(a,this.index++,this.source)}catch(e){this.destination.error(e);
                +return}c&&this.count++};e.prototype._complete=function(){this.destination.next(this.count);this.destination.complete()};return e}(a.Subscriber)},{"../Subscriber":9}],149:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.debounce=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.durationSelector=
                +d}a.prototype.call=function(a){return new h(a,this.durationSelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.durationSelector=d;this.hasValue=!1;this.durationSubscription=null}g(d,a);d.prototype._next=function(a){try{var d=this.durationSelector.call(this,a);d&&this._tryNext(a,d)}catch(e){this.destination.error(e)}};d.prototype._complete=function(){this.emitValue();this.destination.complete()};d.prototype._tryNext=function(a,d){var e=this.durationSubscription;this.value=a;this.hasValue=
                +!0;e&&(e.unsubscribe(),this.remove(e));e=k.subscribeToResult(this,d);e.isUnsubscribed||this.add(this.durationSubscription=e)};d.prototype.notifyNext=function(a,d,e,b,h){this.emitValue()};d.prototype.notifyComplete=function(){this.emitValue()};d.prototype.emitValue=function(){if(this.hasValue){var c=this.value,d=this.durationSubscription;d&&(this.durationSubscription=null,d.unsubscribe(),this.remove(d));this.value=null;this.hasValue=!1;a.prototype._next.call(this,c)}};return d}(b.OuterSubscriber)},
                +{"../OuterSubscriber":6,"../util/subscribeToResult":250}],150:[function(a,b,f){function g(a){a.debouncedNext()}var k=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=a("../Subscriber");var l=a("../scheduler/asap");f.debounceTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.dueTime=c;this.scheduler=d}
                +a.prototype.call=function(a){return new e(a,this.dueTime,this.scheduler)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.dueTime=e;this.scheduler=b;this.lastValue=this.debouncedSubscription=null;this.hasValue=!1}k(c,a);c.prototype._next=function(a){this.clearDebounce();this.lastValue=a;this.hasValue=!0;this.add(this.debouncedSubscription=this.scheduler.schedule(g,this.dueTime,this))};c.prototype._complete=function(){this.debouncedNext();this.destination.complete()};c.prototype.debouncedNext=
                +function(){this.clearDebounce();this.hasValue&&(this.destination.next(this.lastValue),this.lastValue=null,this.hasValue=!1)};c.prototype.clearDebounce=function(){var a=this.debouncedSubscription;null!==a&&(this.remove(a),a.unsubscribe(),this.debouncedSubscription=null)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],151:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===
                +e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.defaultIfEmpty=function(a){void 0===a&&(a=null);return this.lift(new k(a))};var k=function(){function a(e){this.defaultValue=e}a.prototype.call=function(a){return new l(a,this.defaultValue)};return a}(),l=function(a){function e(d,c){a.call(this,d);this.defaultValue=c;this.isEmpty=!0}g(e,a);e.prototype._next=function(a){this.isEmpty=!1;this.destination.next(a)};e.prototype._complete=function(){this.isEmpty&&this.destination.next(this.defaultValue);
                +this.destination.complete()};return e}(a.Subscriber)},{"../Subscriber":9}],152:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../scheduler/asap"),l=a("../util/isDate");b=a("../Subscriber");var h=a("../Notification");f.delay=function(a,c){void 0===c&&(c=k.asap);var d=l.isDate(a)?+a-c.now():Math.abs(a);return this.lift(new e(d,c))};var e=
                +function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new d(a,this.delay,this.scheduler)};return a}(),d=function(a){function d(c,e,b){a.call(this,c);this.delay=e;this.scheduler=b;this.queue=[];this.errored=this.active=!1}g(d,a);d.dispatch=function(a){for(var c=a.source,d=c.queue,e=a.scheduler,b=a.destination;0<d.length&&0>=d[0].time-e.now();)d.shift().notification.observe(b);0<d.length?(c=Math.max(0,d[0].time-e.now()),this.schedule(a,c)):c.active=!1};d.prototype._schedule=
                +function(a){this.active=!0;this.add(a.schedule(d.dispatch,this.delay,{source:this,destination:this.destination,scheduler:a}))};d.prototype.scheduleNotification=function(a){if(!0!==this.errored){var d=this.scheduler;a=new c(d.now()+this.delay,a);this.queue.push(a);!1===this.active&&this._schedule(d)}};d.prototype._next=function(a){this.scheduleNotification(h.Notification.createNext(a))};d.prototype._error=function(a){this.errored=!0;this.queue=[];this.destination.error(a)};d.prototype._complete=function(){this.scheduleNotification(h.Notification.createComplete())};
                +return d}(b.Subscriber),c=function(){return function(a,c){this.time=a;this.notification=c}}()},{"../Notification":2,"../Subscriber":9,"../scheduler/asap":224,"../util/isDate":241}],153:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var k=a("../Observable"),l=a("../OuterSubscriber"),h=a("../util/subscribeToResult");f.delayWhen=
                +function(a,d){return d?(new c(this,d)).lift(new e(a)):this.lift(new e(a))};var e=function(){function a(c){this.delayDurationSelector=c}a.prototype.call=function(a){return new d(a,this.delayDurationSelector)};return a}(),d=function(a){function c(d,e){a.call(this,d);this.delayDurationSelector=e;this.completed=!1;this.delayNotifierSubscriptions=[];this.values=[]}g(c,a);c.prototype.notifyNext=function(a,c,d,e,b){this.destination.next(a);this.removeSubscription(b);this.tryComplete()};c.prototype.notifyError=
                +function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){(a=this.removeSubscription(a))&&this.destination.next(a);this.tryComplete()};c.prototype._next=function(a){try{var c=this.delayDurationSelector(a);c&&this.tryDelay(c,a)}catch(d){this.destination.error(d)}};c.prototype._complete=function(){this.completed=!0;this.tryComplete()};c.prototype.removeSubscription=function(a){a.unsubscribe();a=this.delayNotifierSubscriptions.indexOf(a);var c=null;-1!==a&&(c=this.values[a],this.delayNotifierSubscriptions.splice(a,
                +1),this.values.splice(a,1));return c};c.prototype.tryDelay=function(a,c){var d=h.subscribeToResult(this,a,c);this.add(d);this.delayNotifierSubscriptions.push(d);this.values.push(c)};c.prototype.tryComplete=function(){this.completed&&0===this.delayNotifierSubscriptions.length&&this.destination.complete()};return c}(l.OuterSubscriber),c=function(a){function c(d,e){a.call(this);this.source=d;this.subscriptionDelay=e}g(c,a);c.prototype._subscribe=function(a){this.subscriptionDelay.subscribe(new m(a,this.source))};
                +return c}(k.Observable),m=function(a){function c(d,e){a.call(this);this.parent=d;this.source=e;this.sourceSubscribed=!1}g(c,a);c.prototype._next=function(a){this.subscribeToSource()};c.prototype._error=function(a){this.unsubscribe();this.parent.error(a)};c.prototype._complete=function(){this.subscribeToSource()};c.prototype.subscribeToSource=function(){this.sourceSubscribed||(this.sourceSubscribed=!0,this.unsubscribe(),this.source.subscribe(this.parent))};return c}(b.Subscriber)},{"../Observable":3,
                +"../OuterSubscriber":6,"../Subscriber":9,"../util/subscribeToResult":250}],154:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.dematerialize=function(){return this.lift(new k)};var k=function(){function a(){}a.prototype.call=function(a){return new l(a)};return a}(),l=function(a){function e(d){a.call(this,d)}g(e,a);
                +e.prototype._next=function(a){a.observe(this.destination)};return e}(a.Subscriber)},{"../Subscriber":9}],155:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=a("../Subscriber");var k=a("../util/tryCatch"),l=a("../util/errorObject");f.distinctUntilChanged=function(a,c){return this.lift(new h(a,c))};var h=function(){function a(c,d){this.compare=
                +c;this.keySelector=d}a.prototype.call=function(a){return new e(a,this.compare,this.keySelector)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.keySelector=b;this.hasKey=!1;"function"===typeof e&&(this.compare=e)}g(c,a);c.prototype.compare=function(a,c){return a===c};c.prototype._next=function(a){var c=a;if(this.keySelector&&(c=k.tryCatch(this.keySelector)(a),c===l.errorObject))return this.destination.error(l.errorObject.e);var d=!1;if(this.hasKey){if(d=k.tryCatch(this.compare)(this.key,
                +c),d===l.errorObject)return this.destination.error(l.errorObject.e)}else this.hasKey=!0;!1===!!d&&(this.key=c,this.destination.next(a))};return c}(b.Subscriber)},{"../Subscriber":9,"../util/errorObject":239,"../util/tryCatch":253}],156:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/noop");f._do=function(a,
                +d,c){var b;a&&"object"===typeof a?(b=a.next,d=a.error,c=a.complete):b=a;return this.lift(new l(b||k.noop,d||k.noop,c||k.noop))};var l=function(){function a(d,c,e){this.next=d;this.error=c;this.complete=e}a.prototype.call=function(a){return new h(a,this.next,this.error,this.complete)};return a}(),h=function(a){function d(c,d,b,h){a.call(this,c);this.__next=d;this.__error=b;this.__complete=h}g(d,a);d.prototype._next=function(a){try{this.__next(a)}catch(d){this.destination.error(d);return}this.destination.next(a)};
                +d.prototype._error=function(a){try{this.__error(a)}catch(d){this.destination.error(d);return}this.destination.error(a)};d.prototype._complete=function(){try{this.__complete()}catch(a){this.destination.error(a);return}this.destination.complete()};return d}(b.Subscriber)},{"../Subscriber":9,"../util/noop":247}],157:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=
                +e.prototype,new d)};a=a("../Subscriber");f.every=function(a,e){return this.lift(new k(a,e,this))};var k=function(){function a(e,d,c){this.predicate=e;this.thisArg=d;this.source=c}a.prototype.call=function(a){return new l(a,this.predicate,this.thisArg,this.source)};return a}(),l=function(a){function e(d,c,e,b){a.call(this,d);this.predicate=c;this.thisArg=e;this.source=b;this.index=0;this.thisArg=e||this}g(e,a);e.prototype.notifyComplete=function(a){this.destination.next(a);this.destination.complete()};
                +e.prototype._next=function(a){var c=!1;try{c=this.predicate.call(this.thisArg,a,this.index++,this.source)}catch(e){this.destination.error(e);return}c||this.notifyComplete(!1)};e.prototype._complete=function(){this.notifyComplete(!0)};return e}(a.Subscriber)},{"../Subscriber":9}],158:[function(a,b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)},k=a("../util/tryCatch"),
                +l=a("../util/errorObject");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.expand=function(a,d,b){void 0===d&&(d=Number.POSITIVE_INFINITY);void 0===b&&(b=void 0);d=1>(d||0)?Number.POSITIVE_INFINITY:d;return this.lift(new e(a,d,b))};var e=function(){function a(c,d,e){this.project=c;this.concurrent=d;this.scheduler=e}a.prototype.call=function(a){return new d(a,this.project,this.concurrent,this.scheduler)};return a}();f.ExpandOperator=e;var d=function(a){function d(e,b,m,h){a.call(this,
                +e);this.project=b;this.concurrent=m;this.scheduler=h;this.active=this.index=0;this.hasCompleted=!1;m<Number.POSITIVE_INFINITY&&(this.buffer=[])}g(d,a);d.dispatch=function(a){a.subscriber.subscribeToProjection(a.result,a.value,a.index)};d.prototype._next=function(a){var c=this.destination;if(c.isUnsubscribed)this._complete();else{var e=this.index++;if(this.active<this.concurrent){c.next(a);var b=k.tryCatch(this.project)(a,e);b===l.errorObject?c.error(l.errorObject.e):this.scheduler?this.add(this.scheduler.schedule(d.dispatch,
                +0,{subscriber:this,result:b,value:a,index:e})):this.subscribeToProjection(b,a,e)}else this.buffer.push(a)}};d.prototype.subscribeToProjection=function(a,c,d){this.active++;this.add(h.subscribeToResult(this,a,c,d))};d.prototype._complete=function(){(this.hasCompleted=!0,0===this.active)&&this.destination.complete()};d.prototype.notifyNext=function(a,c,d,e,b){this._next(c)};d.prototype.notifyComplete=function(a){var c=this.buffer;this.remove(a);this.active--;c&&0<c.length&&this._next(c.shift());this.hasCompleted&&
                +0===this.active&&this.destination.complete()};return d}(b.OuterSubscriber);f.ExpandSubscriber=d},{"../OuterSubscriber":6,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],159:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.filter=function(a,e){return this.lift(new k(a,e))};var k=function(){function a(e,
                +d){this.select=e;this.thisArg=d}a.prototype.call=function(a){return new l(a,this.select,this.thisArg)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.select=c;this.thisArg=e;this.count=0;this.select=c}g(e,a);e.prototype._next=function(a){var c;try{c=this.select.call(this.thisArg,a,this.count++)}catch(e){this.destination.error(e);return}c&&this.destination.next(a)};return e}(a.Subscriber)},{"../Subscriber":9}],160:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=
                +a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Subscription");f._finally=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.finallySelector=d}a.prototype.call=function(a){return new h(a,this.finallySelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.add(new k.Subscription(d))}g(d,a);return d}(b.Subscriber)},{"../Subscriber":9,"../Subscription":10}],
                +161:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.first=function(a,d,c){return this.lift(new l(a,d,c,this))};var l=function(){function a(d,c,e,b){this.predicate=d;this.resultSelector=c;this.defaultValue=e;this.source=b}a.prototype.call=function(a){return new h(a,this.predicate,this.resultSelector,
                +this.defaultValue,this.source)};return a}(),h=function(a){function d(c,d,b,h,f){a.call(this,c);this.predicate=d;this.resultSelector=b;this.defaultValue=h;this.source=f;this.index=0;this.hasCompleted=!1}g(d,a);d.prototype._next=function(a){var d=this.index++;this.predicate?this._tryPredicate(a,d):this._emit(a,d)};d.prototype._tryPredicate=function(a,d){var e;try{e=this.predicate(a,d,this.source)}catch(b){this.destination.error(b);return}e&&this._emit(a,d)};d.prototype._emit=function(a,d){this.resultSelector?
                +this._tryResultSelector(a,d):this._emitFinal(a)};d.prototype._tryResultSelector=function(a,d){var e;try{e=this.resultSelector(a,d)}catch(b){this.destination.error(b);return}this._emitFinal(e)};d.prototype._emitFinal=function(a){var d=this.destination;d.next(a);d.complete();this.hasCompleted=!0};d.prototype._complete=function(){var a=this.destination;this.hasCompleted||"undefined"===typeof this.defaultValue?this.hasCompleted||a.error(new k.EmptyError):(a.next(this.defaultValue),a.complete())};return d}(b.Subscriber)},
                +{"../Subscriber":9,"../util/EmptyError":232}],162:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var k=a("../Subscription"),l=a("../Observable"),h=a("../Operator"),e=a("../Subject"),d=a("../util/Map"),c=a("../util/FastMap");f.groupBy=function(a,c,d){return this.lift(new m(this,a,c,d))};var m=function(a){function c(d,
                +e,b,m){a.call(this);this.source=d;this.keySelector=e;this.elementSelector=b;this.durationSelector=m}g(c,a);c.prototype.call=function(a){return new n(a,this.keySelector,this.elementSelector,this.durationSelector)};return c}(h.Operator),n=function(a){function b(c,d,e,m){a.call(this);this.keySelector=d;this.elementSelector=e;this.durationSelector=m;this.groups=null;this.attemptedToUnsubscribe=!1;this.count=0;this.destination=c;this.add(c)}g(b,a);b.prototype._next=function(a){var c;try{c=this.keySelector(a)}catch(d){this.error(d);
                +return}this._group(a,c)};b.prototype._group=function(a,b){var m=this.groups;m||(m=this.groups="string"===typeof b?new c.FastMap:new d.Map);var h=m.get(b);h||(m.set(b,h=new e.Subject),m=new p(b,h,this),this.durationSelector&&this._selectDuration(b,h),this.destination.next(m));this.elementSelector?this._selectElement(a,h):this.tryGroupNext(a,h)};b.prototype._selectElement=function(a,c){var d;try{d=this.elementSelector(a)}catch(e){this.error(e);return}this.tryGroupNext(d,c)};b.prototype._selectDuration=
                +function(a,c){var d;try{d=this.durationSelector(new p(a,c))}catch(e){this.error(e);return}this.add(d.subscribe(new q(a,c,this)))};b.prototype.tryGroupNext=function(a,c){c.isUnsubscribed||c.next(a)};b.prototype._error=function(a){var c=this.groups;c&&(c.forEach(function(c,d){c.error(a)}),c.clear());this.destination.error(a)};b.prototype._complete=function(){var a=this.groups;a&&(a.forEach(function(a,c){a.complete()}),a.clear());this.destination.complete()};b.prototype.removeGroup=function(a){this.groups["delete"](a)};
                +b.prototype.unsubscribe=function(){this.isUnsubscribed||this.attemptedToUnsubscribe||(this.attemptedToUnsubscribe=!0,0===this.count&&a.prototype.unsubscribe.call(this))};return b}(b.Subscriber),q=function(a){function c(d,e,b){a.call(this);this.key=d;this.group=e;this.parent=b}g(c,a);c.prototype._next=function(a){this.tryComplete()};c.prototype._error=function(a){this.tryError(a)};c.prototype._complete=function(){this.tryComplete()};c.prototype.tryError=function(a){var c=this.group;c.isUnsubscribed||
                +c.error(a);this.parent.removeGroup(this.key)};c.prototype.tryComplete=function(){var a=this.group;a.isUnsubscribed||a.complete();this.parent.removeGroup(this.key)};return c}(b.Subscriber),p=function(a){function c(d,e,b){a.call(this);this.key=d;this.groupSubject=e;this.refCountSubscription=b}g(c,a);c.prototype._subscribe=function(a){var c=new k.Subscription,d=this.refCountSubscription,e=this.groupSubject;d&&!d.isUnsubscribed&&c.add(new u(d));c.add(e.subscribe(a));return c};return c}(l.Observable);
                +f.GroupedObservable=p;var u=function(a){function c(d){a.call(this);this.parent=d;d.count++}g(c,a);c.prototype.unsubscribe=function(){var c=this.parent;c.isUnsubscribed||this.isUnsubscribed||(a.prototype.unsubscribe.call(this),--c.count,0===c.count&&c.attemptedToUnsubscribe&&c.unsubscribe())};return c}(k.Subscription)},{"../Observable":3,"../Operator":5,"../Subject":8,"../Subscriber":9,"../Subscription":10,"../util/FastMap":233,"../util/Map":235}],163:[function(a,b,f){var g=this&&this.__extends||function(a,
                +d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/noop");f.ignoreElements=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(){a.apply(this,arguments)}g(d,a);d.prototype._next=function(a){k.noop()};return d}(b.Subscriber)},{"../Subscriber":9,"../util/noop":247}],
                +164:[function(a,b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)},k=a("../util/tryCatch"),l=a("../util/errorObject");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.inspect=function(a){return this.lift(new e(a))};var e=function(){function a(c){this.durationSelector=c}a.prototype.call=function(a){return new d(a,this.durationSelector)};
                +return a}(),d=function(a){function d(e,b){a.call(this,e);this.durationSelector=b;this.hasValue=!1}g(d,a);d.prototype._next=function(a){this.value=a;this.hasValue=!0;this.throttled||(a=k.tryCatch(this.durationSelector)(a),a===l.errorObject?this.destination.error(l.errorObject.e):this.add(this.throttled=h.subscribeToResult(this,a)))};d.prototype.clearThrottle=function(){var a=this.value,c=this.hasValue,d=this.throttled;d&&(this.remove(d),this.throttled=null,d.unsubscribe());c&&(this.value=null,this.hasValue=
                +!1,this.destination.next(a))};d.prototype.notifyNext=function(a,c,d,e){this.clearThrottle()};d.prototype.notifyComplete=function(){this.clearThrottle()};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],165:[function(a,b,f){function g(a){a.clearThrottle()}var k=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):
                +(e.prototype=c.prototype,new e)},l=a("../scheduler/asap");a=a("../Subscriber");f.inspectTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.delay=e;this.scheduler=b;this.hasValue=!1}k(c,a);c.prototype._next=function(a){this.value=a;this.hasValue=!0;this.throttled||this.add(this.throttled=
                +this.scheduler.schedule(g,this.delay,this))};c.prototype.clearThrottle=function(){var a=this.value,c=this.hasValue,d=this.throttled;d&&(this.remove(d),this.throttled=null,d.unsubscribe());c&&(this.value=null,this.hasValue=!1,this.destination.next(a))};return c}(a.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],166:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):
                +(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.last=function(a,d,c){return this.lift(new l(a,d,c,this))};var l=function(){function a(d,c,e,b){this.predicate=d;this.resultSelector=c;this.defaultValue=e;this.source=b}a.prototype.call=function(a){return new h(a,this.predicate,this.resultSelector,this.defaultValue,this.source)};return a}(),h=function(a){function d(c,d,b,h,f){a.call(this,c);this.predicate=d;this.resultSelector=b;this.defaultValue=h;this.source=f;
                +this.hasValue=!1;this.index=0;"undefined"!==typeof h&&(this.lastValue=h,this.hasValue=!0)}g(d,a);d.prototype._next=function(a){var d=this.index++;this.predicate?this._tryPredicate(a,d):this.resultSelector?this._tryResultSelector(a,d):(this.lastValue=a,this.hasValue=!0)};d.prototype._tryPredicate=function(a,d){var e;try{e=this.predicate(a,d,this.source)}catch(b){this.destination.error(b);return}e&&(this.resultSelector?this._tryResultSelector(a,d):(this.lastValue=a,this.hasValue=!0))};d.prototype._tryResultSelector=
                +function(a,d){var e;try{e=this.resultSelector(a,d)}catch(b){this.destination.error(b);return}this.lastValue=e;this.hasValue=!0};d.prototype._complete=function(){var a=this.destination;this.hasValue?(a.next(this.lastValue),a.complete()):a.error(new k.EmptyError)};return d}(b.Subscriber)},{"../Subscriber":9,"../util/EmptyError":232}],167:[function(a,b,f){f.letProto=function(a){return a(this)}},{}],168:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&
                +(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.map=function(a,e){if("function"!==typeof a)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return this.lift(new k(a,e))};var k=function(){function a(e,d){this.project=e;this.thisArg=d}a.prototype.call=function(a){return new l(a,this.project,this.thisArg)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.project=c;this.count=0;this.thisArg=e||this}
                +g(e,a);e.prototype._next=function(a){var c;try{c=this.project.call(this.thisArg,a,this.count++)}catch(e){this.destination.error(e);return}this.destination.next(c)};return e}(a.Subscriber)},{"../Subscriber":9}],169:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.mapTo=function(a){return this.lift(new k(a))};var k=function(){function a(e){this.value=
                +e}a.prototype.call=function(a){return new l(a,this.value)};return a}(),l=function(a){function e(d,c){a.call(this,d);this.value=c}g(e,a);e.prototype._next=function(a){this.destination.next(this.value)};return e}(a.Subscriber)},{"../Subscriber":9}],170:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Notification");
                +f.materialize=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(c){a.call(this,c)}g(d,a);d.prototype._next=function(a){this.destination.next(k.Notification.createNext(a))};d.prototype._error=function(a){var d=this.destination;d.next(k.Notification.createError(a));d.complete()};d.prototype._complete=function(){var a=this.destination;a.next(k.Notification.createComplete());a.complete()};return d}(b.Subscriber)},
                +{"../Notification":2,"../Subscriber":9}],171:[function(a,b,f){function g(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];var d=Number.POSITIVE_INFINITY,c=null,b=a[a.length-1];h.isScheduler(b)?(c=a.pop(),1<a.length&&"number"===typeof a[a.length-1]&&(d=a.pop())):"number"===typeof b&&(d=a.pop());return 1===a.length?a[0]:(new k.ArrayObservable(a,c)).lift(new l.MergeAllOperator(d))}var k=a("../observable/ArrayObservable"),l=a("./mergeAll"),h=a("../util/isScheduler");f.merge=function(){for(var a=
                +[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];a.unshift(this);return g.apply(this,a)};f.mergeStatic=g},{"../observable/ArrayObservable":116,"../util/isScheduler":246,"./mergeAll":172}],172:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.mergeAll=function(a){void 0===a&&
                +(a=Number.POSITIVE_INFINITY);return this.lift(new l(a))};var l=function(){function a(d){this.concurrent=d}a.prototype.call=function(a){return new h(a,this.concurrent)};return a}();f.MergeAllOperator=l;var h=function(a){function d(c,d){a.call(this,c);this.concurrent=d;this.hasCompleted=!1;this.buffer=[];this.active=0}g(d,a);d.prototype._next=function(a){this.active<this.concurrent?(this.active++,this.add(k.subscribeToResult(this,a))):this.buffer.push(a)};d.prototype._complete=function(){this.hasCompleted=
                +!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(b.OuterSubscriber);f.MergeAllSubscriber=h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],173:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=
                +d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)},k=a("../util/subscribeToResult");a=a("../OuterSubscriber");f.mergeMap=function(a,d,c){void 0===c&&(c=Number.POSITIVE_INFINITY);return this.lift(new l(a,d,c))};var l=function(){function a(d,c,e){void 0===e&&(e=Number.POSITIVE_INFINITY);this.project=d;this.resultSelector=c;this.concurrent=e}a.prototype.call=function(a){return new h(a,this.project,this.resultSelector,this.concurrent)};return a}();f.MergeMapOperator=l;var h=
                +function(a){function d(c,d,b,f){void 0===f&&(f=Number.POSITIVE_INFINITY);a.call(this,c);this.project=d;this.resultSelector=b;this.concurrent=f;this.hasCompleted=!1;this.buffer=[];this.index=this.active=0}g(d,a);d.prototype._next=function(a){this.active<this.concurrent?this._tryNext(a):this.buffer.push(a)};d.prototype._tryNext=function(a){var d,e=this.index++;try{d=this.project(a,e)}catch(b){this.destination.error(b);return}this.active++;this._innerSub(d,a,e)};d.prototype._innerSub=function(a,d,e){this.add(k.subscribeToResult(this,
                +a,d,e))};d.prototype._complete=function(){this.hasCompleted=!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyNext=function(a,d,e,b,f){this.resultSelector?this._notifyResultSelector(a,d,e,b):this.destination.next(d)};d.prototype._notifyResultSelector=function(a,d,e,b){var f;try{f=this.resultSelector(a,d,e,b)}catch(h){this.destination.error(h);return}this.destination.next(f)};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;
                +0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(a.OuterSubscriber);f.MergeMapSubscriber=h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],174:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.mergeMapTo=function(a,
                +d,c){void 0===c&&(c=Number.POSITIVE_INFINITY);return this.lift(new l(a,d,c))};var l=function(){function a(d,c,e){void 0===e&&(e=Number.POSITIVE_INFINITY);this.ish=d;this.resultSelector=c;this.concurrent=e}a.prototype.call=function(a){return new h(a,this.ish,this.resultSelector,this.concurrent)};return a}();f.MergeMapToOperator=l;var h=function(a){function d(c,d,b,f){void 0===f&&(f=Number.POSITIVE_INFINITY);a.call(this,c);this.ish=d;this.resultSelector=b;this.concurrent=f;this.hasCompleted=!1;this.buffer=
                +[];this.index=this.active=0}g(d,a);d.prototype._next=function(a){if(this.active<this.concurrent){var d=this.resultSelector,e=this.index++,b=this.ish,f=this.destination;this.active++;this._innerSub(b,f,d,a,e)}else this.buffer.push(a)};d.prototype._innerSub=function(a,d,e,b,f){this.add(k.subscribeToResult(this,a,b,f))};d.prototype._complete=function(){this.hasCompleted=!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyNext=function(a,d,e,b,f){f=this.destination;
                +this.resultSelector?this.trySelectResult(a,d,e,b):f.next(d)};d.prototype.trySelectResult=function(a,d,e,b){var f=this.resultSelector,h=this.destination,k;try{k=f(a,d,e,b)}catch(l){h.error(l);return}h.next(k)};d.prototype.notifyError=function(a){this.destination.error(a)};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(b.OuterSubscriber);f.MergeMapToSubscriber=
                +h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],175:[function(a,b,f){var g=a("../observable/ConnectableObservable");f.multicast=function(a){return new g.ConnectableObservable(this,"function"===typeof a?a:function(){return a})}},{"../observable/ConnectableObservable":119}],176:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=
                +a("../Subscriber");var k=a("../Notification");f.observeOn=function(a,c){void 0===c&&(c=0);return this.lift(new l(a,c))};var l=function(){function a(c,d){void 0===d&&(d=0);this.scheduler=c;this.delay=d}a.prototype.call=function(a){return new h(a,this.scheduler,this.delay)};return a}();f.ObserveOnOperator=l;var h=function(a){function c(c,e,b){void 0===b&&(b=0);a.call(this,c);this.scheduler=e;this.delay=b}g(c,a);c.dispatch=function(a){a.notification.observe(a.destination)};c.prototype.scheduleMessage=
                +function(a){this.add(this.scheduler.schedule(c.dispatch,this.delay,new e(a,this.destination)))};c.prototype._next=function(a){this.scheduleMessage(k.Notification.createNext(a))};c.prototype._error=function(a){this.scheduleMessage(k.Notification.createError(a))};c.prototype._complete=function(){this.scheduleMessage(k.Notification.createComplete())};return c}(b.Subscriber);f.ObserveOnSubscriber=h;var e=function(){return function(a,c){this.notification=a;this.destination=c}}()},{"../Notification":2,
                +"../Subscriber":9}],177:[function(a,b,f){var g=a("../util/not"),k=a("./filter");f.partition=function(a,b){return[k.filter.call(this,a),k.filter.call(this,g.not(a,b))]}},{"../util/not":248,"./filter":159}],178:[function(a,b,f){function g(a,b){return function(e){var d=e;for(e=0;e<b;e++)if(d=d[a[e]],"undefined"===typeof d)return;return d}}var k=a("./map");f.pluck=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];b=a.length;if(0===b)throw Error("List of properties cannot be empty.");
                +return k.map.call(this,g(a,b))}},{"./map":168}],179:[function(a,b,f){var g=a("../Subject"),k=a("./multicast");f.publish=function(){return k.multicast.call(this,new g.Subject)}},{"../Subject":8,"./multicast":175}],180:[function(a,b,f){var g=a("../subject/BehaviorSubject"),k=a("./multicast");f.publishBehavior=function(a){return k.multicast.call(this,new g.BehaviorSubject(a))}},{"../subject/BehaviorSubject":227,"./multicast":175}],181:[function(a,b,f){var g=a("../subject/AsyncSubject"),k=a("./multicast");
                +f.publishLast=function(){return k.multicast.call(this,new g.AsyncSubject)}},{"../subject/AsyncSubject":226,"./multicast":175}],182:[function(a,b,f){var g=a("../subject/ReplaySubject"),k=a("./multicast");f.publishReplay=function(a,b,e){void 0===a&&(a=Number.POSITIVE_INFINITY);void 0===b&&(b=Number.POSITIVE_INFINITY);return k.multicast.call(this,new g.ReplaySubject(a,b,e))}},{"../subject/ReplaySubject":228,"./multicast":175}],183:[function(a,b,f){function g(){for(var a=[],c=0;c<arguments.length;c++)a[c-
                +0]=arguments[c];if(1===a.length)if(l.isArray(a[0]))a=a[0];else return a[0];return(new h.ArrayObservable(a)).lift(new d)}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../util/isArray"),h=a("../observable/ArrayObservable");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.race=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=
                +arguments[c];1===a.length&&l.isArray(a[0])&&(a=a[0]);a.unshift(this);return g.apply(this,a)};f.raceStatic=g;var d=function(){function a(){}a.prototype.call=function(a){return new c(a)};return a}();f.RaceOperator=d;var c=function(a){function c(d){a.call(this,d);this.hasFirst=!1;this.observables=[];this.subscriptions=[]}k(c,a);c.prototype._next=function(a){this.observables.push(a)};c.prototype._complete=function(){var a=this.observables,c=a.length;if(0===c)this.destination.complete();else{for(var d=
                +0;d<c;d++){var b=a[d],b=e.subscribeToResult(this,b,b,d);this.subscriptions.push(b);this.add(b)}this.observables=null}};c.prototype.notifyNext=function(a,c,d,e,b){if(!this.hasFirst){this.hasFirst=!0;for(a=0;a<this.subscriptions.length;a++)a!==d&&(e=this.subscriptions[a],e.unsubscribe(),this.remove(e));this.subscriptions=null}this.destination.next(c)};return c}(b.OuterSubscriber);f.RaceSubscriber=c},{"../OuterSubscriber":6,"../observable/ArrayObservable":116,"../util/isArray":240,"../util/subscribeToResult":250}],
                +184:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.reduce=function(a,e){return this.lift(new k(a,e))};var k=function(){function a(e,d){this.project=e;this.seed=d}a.prototype.call=function(a){return new l(a,this.project,this.seed)};return a}();f.ReduceOperator=k;var l=function(a){function e(d,c,e){a.call(this,d);this.hasValue=
                +!1;this.acc=e;this.project=c;this.hasSeed="undefined"!==typeof e}g(e,a);e.prototype._next=function(a){this.hasValue||(this.hasValue=this.hasSeed)?this._tryReduce(a):(this.acc=a,this.hasValue=!0)};e.prototype._tryReduce=function(a){var c;try{c=this.project(this.acc,a)}catch(e){this.destination.error(e);return}this.acc=c};e.prototype._complete=function(){(this.hasValue||this.hasSeed)&&this.destination.next(this.acc);this.destination.complete()};return e}(a.Subscriber);f.ReduceSubscriber=l},{"../Subscriber":9}],
                +185:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../observable/EmptyObservable");f.repeat=function(a){void 0===a&&(a=-1);return 0===a?new k.EmptyObservable:0>a?this.lift(new l(-1,this)):this.lift(new l(a-1,this))};var l=function(){function a(d,c){this.count=d;this.source=c}a.prototype.call=function(a){return new h(a,
                +this.count,this.source)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.count=d;this.source=b}g(d,a);d.prototype.complete=function(){if(!this.isStopped){var c=this.source,d=this.count;if(0===d)return a.prototype.complete.call(this);-1<d&&(this.count=d-1);this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;c.subscribe(this)}};return d}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121}],186:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=
                +a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.retry=function(a){void 0===a&&(a=-1);return this.lift(new k(a,this))};var k=function(){function a(e,d){this.count=e;this.source=d}a.prototype.call=function(a){return new l(a,this.count,this.source)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.count=c;this.source=e}g(e,a);e.prototype.error=function(d){if(!this.isStopped){var c=this.source,
                +e=this.count;if(0===e)return a.prototype.error.call(this,d);-1<e&&(this.count=e-1);this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;c.subscribe(this)}};return e}(a.Subscriber)},{"../Subscriber":9}],187:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");
                +var e=a("../util/subscribeToResult");f.retryWhen=function(a){return this.lift(new d(a,this))};var d=function(){function a(c,d){this.notifier=c;this.source=d}a.prototype.call=function(a){return new c(a,this.notifier,this.source)};return a}(),c=function(a){function c(d,e,b){a.call(this,d);this.notifier=e;this.source=b}g(c,a);c.prototype.error=function(c){if(!this.isStopped){var d=this.errors,b=this.retries,f=this.retriesSubscription;if(b)this.retriesSubscription=this.errors=null;else{d=new k.Subject;
                +b=l.tryCatch(this.notifier)(d);if(b===h.errorObject)return a.prototype.error.call(this,h.errorObject.e);f=e.subscribeToResult(this,b)}this.unsubscribe();this.isUnsubscribed=!1;this.errors=d;this.retries=b;this.retriesSubscription=f;d.next(c)}};c.prototype._unsubscribe=function(){var a=this.errors,c=this.retriesSubscription;a&&(a.unsubscribe(),this.errors=null);c&&(c.unsubscribe(),this.retriesSubscription=null);this.retries=null};c.prototype.notifyNext=function(a,c,d,e,b){a=this.errors;c=this.retries;
                +d=this.retriesSubscription;this.retriesSubscription=this.retries=this.errors=null;this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;this.errors=a;this.retries=c;this.retriesSubscription=d;this.source.subscribe(this)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],188:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&
                +(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.sample=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.hasValue=!1;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype._next=function(a){this.value=a;this.hasValue=!0};d.prototype.notifyNext=
                +function(a,d,b,e,f){this.emitValue()};d.prototype.notifyComplete=function(){this.emitValue()};d.prototype.emitValue=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.value))};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],189:[function(a,b,f){function g(a){var c=a.delay;a.subscriber.notifyNext();this.schedule(a,c)}var k=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=
                +null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var l=a("../scheduler/asap");f.sampleTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,b,e){a.call(this,c);this.delay=b;this.scheduler=e;this.hasValue=!1;this.add(e.schedule(g,b,{subscriber:this,delay:b}))}k(c,a);c.prototype._next=
                +function(a){this.lastValue=a;this.hasValue=!0};c.prototype.notifyNext=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.lastValue))};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],190:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.scan=function(a,b){return this.lift(new k(a,
                +b))};var k=function(){function a(b,d){this.accumulator=b;this.seed=d}a.prototype.call=function(a){return new l(a,this.accumulator,this.seed)};return a}(),l=function(a){function b(d,c,e){a.call(this,d);this.accumulator=c;this.accumulatorSet=!1;this.seed=e;this.accumulator=c;this.accumulatorSet="undefined"!==typeof e}g(b,a);Object.defineProperty(b.prototype,"seed",{get:function(){return this._seed},set:function(a){this.accumulatorSet=!0;this._seed=a},enumerable:!0,configurable:!0});b.prototype._next=
                +function(a){if(this.accumulatorSet)return this._tryNext(a);this.seed=a;this.destination.next(a)};b.prototype._tryNext=function(a){var c;try{c=this.accumulator(this.seed,a)}catch(b){this.destination.error(b)}this.seed=c;this.destination.next(c)};return b}(a.Subscriber)},{"../Subscriber":9}],191:[function(a,b,f){function g(){return new l.Subject}var k=a("./multicast"),l=a("../Subject");f.share=function(){return k.multicast.call(this,g).refCount()}},{"../Subject":8,"./multicast":175}],192:[function(a,
                +b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.single=function(a){return this.lift(new l(a,this))};var l=function(){function a(d,c){this.predicate=d;this.source=c}a.prototype.call=function(a){return new h(a,this.predicate,this.source)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.predicate=
                +d;this.source=b;this.seenValue=!1;this.index=0}g(d,a);d.prototype.applySingleValue=function(a){this.seenValue?this.destination.error("Sequence contains more than one element"):(this.seenValue=!0,this.singleValue=a)};d.prototype._next=function(a){var d=this.predicate;this.index++;d?this.tryNext(a):this.applySingleValue(a)};d.prototype.tryNext=function(a){try{this.predicate(a,this.index,this.source)&&this.applySingleValue(a)}catch(d){this.destination.error(d)}};d.prototype._complete=function(){var a=
                +this.destination;0<this.index?(a.next(this.seenValue?this.singleValue:void 0),a.complete()):a.error(new k.EmptyError)};return d}(b.Subscriber)},{"../Subscriber":9,"../util/EmptyError":232}],193:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.skip=function(a){return this.lift(new k(a))};var k=function(){function a(b){this.total=
                +b}a.prototype.call=function(a){return new l(a,this.total)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.total=c;this.count=0}g(b,a);b.prototype._next=function(a){++this.count>this.total&&this.destination.next(a)};return b}(a.Subscriber)},{"../Subscriber":9}],194:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");
                +var k=a("../util/subscribeToResult");f.skipUntil=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.isInnerStopped=this.hasValue=!1;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype._next=function(c){this.hasValue&&a.prototype._next.call(this,c)};d.prototype._complete=function(){this.isInnerStopped?a.prototype._complete.call(this):this.unsubscribe()};
                +d.prototype.notifyNext=function(a,d,b,e,f){this.hasValue=!0};d.prototype.notifyComplete=function(){this.isInnerStopped=!0;this.isStopped&&a.prototype._complete.call(this)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],195:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.skipWhile=
                +function(a){return this.lift(new k(a))};var k=function(){function a(b){this.predicate=b}a.prototype.call=function(a){return new l(a,this.predicate)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.predicate=c;this.skipping=!0;this.index=0}g(b,a);b.prototype._next=function(a){var c=this.destination;this.skipping&&this.tryCallPredicate(a);this.skipping||c.next(a)};b.prototype.tryCallPredicate=function(a){try{this.skipping=!!this.predicate(a,this.index++)}catch(c){this.destination.error(c)}};
                +return b}(a.Subscriber)},{"../Subscriber":9}],196:[function(a,b,f){var g=a("../observable/ArrayObservable"),k=a("../observable/ScalarObservable"),l=a("../observable/EmptyObservable"),h=a("./concat"),e=a("../util/isScheduler");f.startWith=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=a[a.length-1];e.isScheduler(c)?a.pop():c=null;var b=a.length;return 1===b?h.concatStatic(new k.ScalarObservable(a[0],c),this):1<b?h.concatStatic(new g.ArrayObservable(a,c),this):h.concatStatic(new l.EmptyObservable(c),
                +this)}},{"../observable/ArrayObservable":116,"../observable/EmptyObservable":121,"../observable/ScalarObservable":132,"../util/isScheduler":246,"./concat":144}],197:[function(a,b,f){var g=a("../observable/SubscribeOnObservable");f.subscribeOn=function(a,b){void 0===b&&(b=0);return new g.SubscribeOnObservable(this,b,a)}},{"../observable/SubscribeOnObservable":133}],198:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=
                +d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f._switch=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(c){a.call(this,c);this.active=0;this.hasCompleted=!1}g(d,a);d.prototype._next=function(a){this.unsubscribeInner();this.active++;this.add(this.innerSubscription=k.subscribeToResult(this,a))};d.prototype._complete=
                +function(){this.hasCompleted=!0;0===this.active&&this.destination.complete()};d.prototype.unsubscribeInner=function(){this.active=0<this.active?this.active-1:0;var a=this.innerSubscription;a&&(a.unsubscribe(),this.remove(a))};d.prototype.notifyNext=function(a,d,b,e,f){this.destination.next(d)};d.prototype.notifyError=function(a){this.destination.error(a)};d.prototype.notifyComplete=function(){this.unsubscribeInner();this.hasCompleted&&0===this.active&&this.destination.complete()};return d}(b.OuterSubscriber)},
                +{"../OuterSubscriber":6,"../util/subscribeToResult":250}],199:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.switchMap=function(a,d){return this.lift(new l(a,d))};var l=function(){function a(d,c){this.project=d;this.resultSelector=c}a.prototype.call=function(a){return new h(a,
                +this.project,this.resultSelector)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.project=d;this.resultSelector=b;this.index=0}g(d,a);d.prototype._next=function(a){var d,b=this.index++;try{d=this.project(a,b)}catch(e){this.destination.error(e);return}this._innerSub(d,a,b)};d.prototype._innerSub=function(a,d,b){var e=this.innerSubscription;e&&e.unsubscribe();this.add(this.innerSubscription=k.subscribeToResult(this,a,d,b))};d.prototype._complete=function(){var c=this.innerSubscription;
                +c&&!c.isUnsubscribed||a.prototype._complete.call(this)};d.prototype._unsubscribe=function(){this.innerSubscription=null};d.prototype.notifyComplete=function(c){this.remove(c);this.innerSubscription=null;this.isStopped&&a.prototype._complete.call(this)};d.prototype.notifyNext=function(a,d,b,e,f){this.resultSelector?this._tryNotifyNext(a,d,b,e):this.destination.next(d)};d.prototype._tryNotifyNext=function(a,d,b,e){var f;try{f=this.resultSelector(a,d,b,e)}catch(h){this.destination.error(h);return}this.destination.next(f)};
                +return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],200:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.switchMapTo=function(a,d){return this.lift(new l(a,d))};var l=function(){function a(d,c){this.observable=d;this.resultSelector=c}a.prototype.call=
                +function(a){return new h(a,this.observable,this.resultSelector)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.inner=d;this.resultSelector=b;this.index=0}g(d,a);d.prototype._next=function(a){var d=this.innerSubscription;d&&d.unsubscribe();this.add(this.innerSubscription=k.subscribeToResult(this,this.inner,a,this.index++))};d.prototype._complete=function(){var c=this.innerSubscription;c&&!c.isUnsubscribed||a.prototype._complete.call(this)};d.prototype._unsubscribe=function(){this.innerSubscription=
                +null};d.prototype.notifyComplete=function(c){this.remove(c);this.innerSubscription=null;this.isStopped&&a.prototype._complete.call(this)};d.prototype.notifyNext=function(a,d,b,e,f){f=this.destination;this.resultSelector?this.tryResultSelector(a,d,b,e):f.next(d)};d.prototype.tryResultSelector=function(a,d,b,e){var f=this.resultSelector,h=this.destination,k;try{k=f(a,d,b,e)}catch(g){h.error(g);return}h.next(k)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],
                +201:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var k=a("../util/ArgumentOutOfRangeError"),l=a("../observable/EmptyObservable");f.take=function(a){return 0===a?new l.EmptyObservable:this.lift(new h(a))};var h=function(){function a(c){this.total=c;if(0>this.total)throw new k.ArgumentOutOfRangeError;}a.prototype.call=
                +function(a){return new e(a,this.total)};return a}(),e=function(a){function c(c,b){a.call(this,c);this.total=b;this.count=0}g(c,a);c.prototype._next=function(a){var c=this.total;++this.count<=c&&(this.destination.next(a),this.count===c&&this.destination.complete())};return c}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121,"../util/ArgumentOutOfRangeError":231}],202:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&
                +(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var k=a("../util/ArgumentOutOfRangeError"),l=a("../observable/EmptyObservable");f.takeLast=function(a){return 0===a?new l.EmptyObservable:this.lift(new h(a))};var h=function(){function a(c){this.total=c;if(0>this.total)throw new k.ArgumentOutOfRangeError;}a.prototype.call=function(a){return new e(a,this.total)};return a}(),e=function(a){function c(c,b){a.call(this,c);this.total=b;this.index=this.count=
                +0;this.ring=Array(b)}g(c,a);c.prototype._next=function(a){var c=this.index,d=this.ring,b=this.total,e=this.count;1<b?e<b?(this.count=e+1,this.index=c+1):this.index=0===c?++c:c<b?c+1:c=0:e<b&&(this.count=b);d[c]=a};c.prototype._complete=function(){for(var a=-1,c=this.ring,d=this.count,b=this.total,e=this.destination,f=1===b||d<b?0:this.index-1;++a<d;)a+f===b&&(f=b-a),e.next(c[a+f]);e.complete()};return c}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121,"../util/ArgumentOutOfRangeError":231}],
                +203:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.takeUntil=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.notifier=
                +d;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype.notifyNext=function(a,d,b,e,f){this.complete()};d.prototype.notifyComplete=function(){};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],204:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.takeWhile=function(a){return this.lift(new k(a))};
                +var k=function(){function a(b){this.predicate=b}a.prototype.call=function(a){return new l(a,this.predicate)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.predicate=c;this.index=0}g(b,a);b.prototype._next=function(a){var c=this.destination,b;try{b=this.predicate(a,this.index++)}catch(e){c.error(e);return}this.nextOrComplete(a,b)};b.prototype.nextOrComplete=function(a,c){var b=this.destination;c?b.next(a):b.complete()};return b}(a.Subscriber)},{"../Subscriber":9}],205:[function(a,b,
                +f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.throttle=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.durationSelector=d}a.prototype.call=function(a){return new h(a,this.durationSelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.destination=
                +c;this.durationSelector=d}g(d,a);d.prototype._next=function(a){this.throttled||this.tryDurationSelector(a)};d.prototype.tryDurationSelector=function(a){var d=null;try{d=this.durationSelector(a)}catch(b){this.destination.error(b);return}this.emitAndThrottle(a,d)};d.prototype.emitAndThrottle=function(a,d){this.add(this.throttled=k.subscribeToResult(this,d));this.destination.next(a)};d.prototype._unsubscribe=function(){var a=this.throttled;a&&(this.remove(a),this.throttled=null,a.unsubscribe())};d.prototype.notifyNext=
                +function(a,d,b,e,f){this._unsubscribe()};d.prototype.notifyComplete=function(){this._unsubscribe()};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],206:[function(a,b,f){function g(a){a.subscriber.clearThrottle()}var k=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var l=a("../scheduler/asap");f.throttleTime=
                +function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,b,e){a.call(this,c);this.delay=b;this.scheduler=e}k(c,a);c.prototype._next=function(a){this.throttled||(this.add(this.throttled=this.scheduler.schedule(g,this.delay,{subscriber:this})),this.destination.next(a))};c.prototype.clearThrottle=function(){var a=this.throttled;
                +a&&(a.unsubscribe(),this.remove(a),this.throttled=null)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],207:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)},k=a("../scheduler/asap"),l=a("../util/isDate");a=a("../Subscriber");f.timeout=function(a,c,b){void 0===c&&(c=null);void 0===b&&(b=k.asap);var e=l.isDate(a);a=e?
                ++a-b.now():Math.abs(a);return this.lift(new h(a,e,c,b))};var h=function(){function a(c,d,b,e){this.waitFor=c;this.absoluteTimeout=d;this.errorToSend=b;this.scheduler=e}a.prototype.call=function(a){return new e(a,this.absoluteTimeout,this.waitFor,this.errorToSend,this.scheduler)};return a}(),e=function(a){function c(c,b,e,f,h){a.call(this,c);this.absoluteTimeout=b;this.waitFor=e;this.errorToSend=f;this.scheduler=h;this._previousIndex=this.index=0;this._hasCompleted=!1;this.scheduleTimeout()}g(c,a);
                +Object.defineProperty(c.prototype,"previousIndex",{get:function(){return this._previousIndex},enumerable:!0,configurable:!0});Object.defineProperty(c.prototype,"hasCompleted",{get:function(){return this._hasCompleted},enumerable:!0,configurable:!0});c.dispatchTimeout=function(a){var c=a.subscriber;a=a.index;c.hasCompleted||c.previousIndex!==a||c.notifyTimeout()};c.prototype.scheduleTimeout=function(){var a=this.index;this.scheduler.schedule(c.dispatchTimeout,this.waitFor,{subscriber:this,index:a});
                +this.index++;this._previousIndex=a};c.prototype._next=function(a){this.destination.next(a);this.absoluteTimeout||this.scheduleTimeout()};c.prototype._error=function(a){this.destination.error(a);this._hasCompleted=!0};c.prototype._complete=function(){this.destination.complete();this._hasCompleted=!0};c.prototype.notifyTimeout=function(){this.error(this.errorToSend||Error("timeout"))};return c}(a.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224,"../util/isDate":241}],208:[function(a,b,f){var g=
                +this&&this.__extends||function(a,d){function b(){this.constructor=a}for(var e in d)d.hasOwnProperty(e)&&(a[e]=d[e]);a.prototype=null===d?Object.create(d):(b.prototype=d.prototype,new b)},k=a("../scheduler/asap"),l=a("../util/isDate");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.timeoutWith=function(a,d,b){void 0===b&&(b=k.asap);var f=l.isDate(a);a=f?+a-b.now():Math.abs(a);return this.lift(new e(a,f,d,b))};var e=function(){function a(c,d,b,e){this.waitFor=c;this.absoluteTimeout=
                +d;this.withObservable=b;this.scheduler=e}a.prototype.call=function(a){return new d(a,this.absoluteTimeout,this.waitFor,this.withObservable,this.scheduler)};return a}(),d=function(a){function d(b,e,f,h,k){a.call(this);this.destination=b;this.absoluteTimeout=e;this.waitFor=f;this.withObservable=h;this.scheduler=k;this.timeoutSubscription=void 0;this._previousIndex=this.index=0;this._hasCompleted=!1;b.add(this);this.scheduleTimeout()}g(d,a);Object.defineProperty(d.prototype,"previousIndex",{get:function(){return this._previousIndex},
                +enumerable:!0,configurable:!0});Object.defineProperty(d.prototype,"hasCompleted",{get:function(){return this._hasCompleted},enumerable:!0,configurable:!0});d.dispatchTimeout=function(a){var c=a.subscriber;a=a.index;c.hasCompleted||c.previousIndex!==a||c.handleTimeout()};d.prototype.scheduleTimeout=function(){var a=this.index;this.scheduler.schedule(d.dispatchTimeout,this.waitFor,{subscriber:this,index:a});this.index++;this._previousIndex=a};d.prototype._next=function(a){this.destination.next(a);this.absoluteTimeout||
                +this.scheduleTimeout()};d.prototype._error=function(a){this.destination.error(a);this._hasCompleted=!0};d.prototype._complete=function(){this.destination.complete();this._hasCompleted=!0};d.prototype.handleTimeout=function(){if(!this.isUnsubscribed){var a=this.withObservable;this.unsubscribe();this.destination.add(this.timeoutSubscription=h.subscribeToResult(this,a))}};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../scheduler/asap":224,"../util/isDate":241,"../util/subscribeToResult":250}],
                +209:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.toArray=function(){return this.lift(new k)};var k=function(){function a(){}a.prototype.call=function(a){return new l(a)};return a}(),l=function(a){function b(d){a.call(this,d);this.array=[]}g(b,a);b.prototype._next=function(a){this.array.push(a)};b.prototype._complete=
                +function(){this.destination.next(this.array);this.destination.complete()};return b}(a.Subscriber)},{"../Subscriber":9}],210:[function(a,b,f){var g=a("../util/root");f.toPromise=function(a){var b=this;a||(g.root.Rx&&g.root.Rx.config&&g.root.Rx.config.Promise?a=g.root.Rx.config.Promise:g.root.Promise&&(a=g.root.Promise));if(!a)throw Error("no Promise impl found");return new a(function(a,e){var d;b.subscribe(function(a){return d=a},function(a){return e(a)},function(){return a(d)})})}},{"../util/root":249}],
                +211:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)},k=a("../Subject");b=a("../OuterSubscriber");var l=a("../util/subscribeToResult");f.window=function(a){return this.lift(new h(a))};var h=function(){function a(c){this.closingNotifier=c}a.prototype.call=function(a){return new e(a,this.closingNotifier)};return a}(),e=function(a){function c(c,
                +b){a.call(this,c);this.destination=c;this.closingNotifier=b;this.add(l.subscribeToResult(this,b));this.openWindow()}g(c,a);c.prototype.notifyNext=function(a,c,d,b,e){this.openWindow()};c.prototype.notifyError=function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){this._complete()};c.prototype._next=function(a){this.window.next(a)};c.prototype._error=function(a){this.window.error(a);this.destination.error(a)};c.prototype._complete=function(){this.window.complete();this.destination.complete()};
                +c.prototype.openWindow=function(){var a=this.window;a&&a.complete();var a=this.destination,c=this.window=new k.Subject;a.add(c);a.next(c)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/subscribeToResult":250}],212:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Subject");f.windowCount=
                +function(a,d){void 0===d&&(d=0);return this.lift(new l(a,d))};var l=function(){function a(d,c){this.windowSize=d;this.startWindowEvery=c}a.prototype.call=function(a){return new h(a,this.windowSize,this.startWindowEvery)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.destination=c;this.windowSize=d;this.startWindowEvery=b;this.windows=[new k.Subject];this.count=0;d=this.windows[0];c.add(d);c.next(d)}g(d,a);d.prototype._next=function(a){for(var d=0<this.startWindowEvery?this.startWindowEvery:
                +this.windowSize,b=this.destination,e=this.windowSize,f=this.windows,h=f.length,g=0;g<h;g++)f[g].next(a);a=this.count-e+1;0<=a&&0===a%d&&f.shift().complete();0===++this.count%d&&(d=new k.Subject,f.push(d),b.add(d),b.next(d))};d.prototype._error=function(a){for(var d=this.windows;0<d.length;)d.shift().error(a);this.destination.error(a)};d.prototype._complete=function(){for(var a=this.windows;0<a.length;)a.shift().complete();this.destination.complete()};return d}(b.Subscriber)},{"../Subject":8,"../Subscriber":9}],
                +213:[function(a,b,f){function g(a){var c=a.subscriber,d=a.windowTimeSpan,b=a.window;b&&b.complete();a.window=c.openWindow();this.schedule(a,d)}function k(a){var c=a.windowTimeSpan,d=a.subscriber,b=a.scheduler,e=a.windowCreationInterval,f=d.openWindow(),h={action:this,subscription:null};h.subscription=b.schedule(l,c,{subscriber:d,window:f,context:h});this.add(h.subscription);this.schedule(a,e)}function l(a){var c=a.subscriber,d=a.window;(a=a.context)&&a.action&&a.subscription&&a.action.remove(a.subscription);
                +c.closeWindow(d)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var e=a("../Subject"),d=a("../scheduler/asap");f.windowTime=function(a,b,e){void 0===b&&(b=null);void 0===e&&(e=d.asap);return this.lift(new c(a,b,e))};var c=function(){function a(c,d,b){this.windowTimeSpan=c;this.windowCreationInterval=d;this.scheduler=b}a.prototype.call=
                +function(a){return new m(a,this.windowTimeSpan,this.windowCreationInterval,this.scheduler)};return a}(),m=function(a){function c(d,b,e,f){a.call(this,d);this.destination=d;this.windowTimeSpan=b;this.windowCreationInterval=e;this.scheduler=f;this.windows=[];if(null!==e&&0<=e){d={subscriber:this,window:this.openWindow(),context:null};var h={windowTimeSpan:b,windowCreationInterval:e,subscriber:this,scheduler:f};this.add(f.schedule(l,b,d));this.add(f.schedule(k,e,h))}else e={subscriber:this,window:this.openWindow(),
                +windowTimeSpan:b},this.add(f.schedule(g,b,e))}h(c,a);c.prototype._next=function(a){for(var c=this.windows,d=c.length,b=0;b<d;b++){var e=c[b];e.isUnsubscribed||e.next(a)}};c.prototype._error=function(a){for(var c=this.windows;0<c.length;)c.shift().error(a);this.destination.error(a)};c.prototype._complete=function(){for(var a=this.windows;0<a.length;){var c=a.shift();c.isUnsubscribed||c.complete()}this.destination.complete()};c.prototype.openWindow=function(){var a=new e.Subject;this.windows.push(a);
                +var c=this.destination;c.add(a);c.next(a);return a};c.prototype.closeWindow=function(a){a.complete();var c=this.windows;c.splice(c.indexOf(a),1)};return c}(b.Subscriber)},{"../Subject":8,"../Subscriber":9,"../scheduler/asap":224}],214:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../Subscription"),h=a("../util/tryCatch"),
                +e=a("../util/errorObject");b=a("../OuterSubscriber");var d=a("../util/subscribeToResult");f.windowToggle=function(a,d){return this.lift(new c(a,d))};var c=function(){function a(c,d){this.openings=c;this.closingSelector=d}a.prototype.call=function(a){return new m(a,this.openings,this.closingSelector)};return a}(),m=function(a){function c(b,e,f){a.call(this,b);this.openings=e;this.closingSelector=f;this.contexts=[];this.add(this.openSubscription=d.subscribeToResult(this,e,e))}g(c,a);c.prototype._next=
                +function(a){var c=this.contexts;if(c)for(var d=c.length,b=0;b<d;b++)c[b].window.next(a)};c.prototype._error=function(c){var d=this.contexts;this.contexts=null;if(d)for(var b=d.length,e=-1;++e<b;){var f=d[e];f.window.error(c);f.subscription.unsubscribe()}a.prototype._error.call(this,c)};c.prototype._complete=function(){var c=this.contexts;this.contexts=null;if(c)for(var d=c.length,b=-1;++b<d;){var e=c[b];e.window.complete();e.subscription.unsubscribe()}a.prototype._complete.call(this)};c.prototype._unsubscribe=
                +function(){var a=this.contexts;this.contexts=null;if(a)for(var c=a.length,d=-1;++d<c;){var b=a[d];b.window.unsubscribe();b.subscription.unsubscribe()}};c.prototype.notifyNext=function(a,c,b,f,g){if(a===this.openings){f=h.tryCatch(this.closingSelector)(c);if(f===e.errorObject)return this.error(e.errorObject.e);a=new k.Subject;c=new l.Subscription;b={window:a,subscription:c};this.contexts.push(b);f=d.subscribeToResult(this,f,b);f.context=b;c.add(f);this.destination.next(a)}else this.closeWindow(this.contexts.indexOf(a))};
                +c.prototype.notifyError=function(a){this.error(a)};c.prototype.notifyComplete=function(a){a!==this.openSubscription&&this.closeWindow(this.contexts.indexOf(a.context))};c.prototype.closeWindow=function(a){var c=this.contexts,d=c[a],b=d.window,d=d.subscription;c.splice(a,1);b.complete();d.unsubscribe()};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../Subscription":10,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],215:[function(a,b,f){var g=
                +this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.windowWhen=function(a){return this.lift(new d(a))};var d=function(){function a(c){this.closingSelector=c}a.prototype.call=function(a){return new c(a,this.closingSelector)};return a}(),
                +c=function(a){function c(d,b){a.call(this,d);this.destination=d;this.closingSelector=b;this.openWindow()}g(c,a);c.prototype.notifyNext=function(a,c,d,b,e){this.openWindow(e)};c.prototype.notifyError=function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){this.openWindow(a)};c.prototype._next=function(a){this.window.next(a)};c.prototype._error=function(a){this.window.error(a);this.destination.error(a);this.unsubscribeClosingNotification()};c.prototype._complete=function(){this.window.complete();
                +this.destination.complete();this.unsubscribeClosingNotification()};c.prototype.unsubscribeClosingNotification=function(){this.closingNotification&&this.closingNotification.unsubscribe()};c.prototype.openWindow=function(a){void 0===a&&(a=null);a&&(this.remove(a),a.unsubscribe());(a=this.window)&&a.complete();a=this.window=new k.Subject;this.destination.next(a);var c=l.tryCatch(this.closingSelector)();c===h.errorObject?(a=h.errorObject.e,this.destination.error(a),this.window.error(a)):(this.add(this.closingNotification=
                +e.subscribeToResult(this,c)),this.add(a))};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],216:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.withLatestFrom=function(){for(var a=
                +[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];var c;"function"===typeof a[a.length-1]&&(c=a.pop());return this.lift(new l(a,c))};var l=function(){function a(d,c){this.observables=d;this.project=c}a.prototype.call=function(a){return new h(a,this.observables,this.project)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.observables=d;this.project=b;this.toRespond=[];c=d.length;this.values=Array(c);for(b=0;b<c;b++)this.toRespond.push(b);for(b=0;b<c;b++){var f=d[b];this.add(k.subscribeToResult(this,
                +f,f,b))}}g(d,a);d.prototype.notifyNext=function(a,d,b,e,f){this.values[b]=d;a=this.toRespond;0<a.length&&(b=a.indexOf(b),-1!==b&&a.splice(b,1))};d.prototype.notifyComplete=function(){};d.prototype._next=function(a){0===this.toRespond.length&&(a=[a].concat(this.values),this.project?this._tryProject(a):this.destination.next(a))};d.prototype._tryProject=function(a){var d;try{d=this.project.apply(this,a)}catch(b){this.destination.error(b);return}this.destination.next(d)};return d}(b.OuterSubscriber)},
                +{"../OuterSubscriber":6,"../util/subscribeToResult":250}],217:[function(a,b,f){function g(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=a[a.length-1];"function"===typeof c&&a.pop();return(new l.ArrayObservable(a)).lift(new m(c))}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../observable/ArrayObservable"),h=a("../util/isArray");b=
                +a("../Subscriber");var e=a("../OuterSubscriber"),d=a("../util/subscribeToResult"),c=a("../util/SymbolShim");f.zipProto=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];a.unshift(this);return g.apply(this,a)};f.zipStatic=g;var m=function(){function a(c){this.project=c}a.prototype.call=function(a){return new n(a,this.project)};return a}();f.ZipOperator=m;var n=function(a){function d(c,b,e){void 0===e&&(e=Object.create(null));a.call(this,c);this.index=0;this.iterators=[];this.active=
                +0;this.project="function"===typeof b?b:null;this.values=e}k(d,a);d.prototype._next=function(a){var d=this.iterators,b=this.index++;h.isArray(a)?d.push(new p(a)):"function"===typeof a[c.SymbolShim.iterator]?d.push(new q(a[c.SymbolShim.iterator]())):d.push(new u(this.destination,this,a,b))};d.prototype._complete=function(){var a=this.iterators,c=a.length;this.active=c;for(var d=0;d<c;d++){var b=a[d];b.stillUnsubscribed?this.add(b.subscribe(b,d)):this.active--}};d.prototype.notifyInactive=function(){this.active--;
                +0===this.active&&this.destination.complete()};d.prototype.checkIterators=function(){for(var a=this.iterators,c=a.length,d=this.destination,b=0;b<c;b++){var e=a[b];if("function"===typeof e.hasValue&&!e.hasValue())return}for(var f=!1,h=[],b=0;b<c;b++){var e=a[b],g=e.next();e.hasCompleted()&&(f=!0);if(g.done){d.complete();return}h.push(g.value)}this.project?this._tryProject(h):d.next(h);f&&d.complete()};d.prototype._tryProject=function(a){var c;try{c=this.project.apply(this,a)}catch(d){this.destination.error(d);
                +return}this.destination.next(c)};return d}(b.Subscriber);f.ZipSubscriber=n;var q=function(){function a(c){this.iterator=c;this.nextResult=c.next()}a.prototype.hasValue=function(){return!0};a.prototype.next=function(){var a=this.nextResult;this.nextResult=this.iterator.next();return a};a.prototype.hasCompleted=function(){var a=this.nextResult;return a&&a.done};return a}(),p=function(){function a(c){this.array=c;this.length=this.index=0;this.length=c.length}a.prototype[c.SymbolShim.iterator]=function(){return this};
                +a.prototype.next=function(a){a=this.index++;var c=this.array;return a<this.length?{value:c[a],done:!1}:{done:!0}};a.prototype.hasValue=function(){return this.array.length>this.index};a.prototype.hasCompleted=function(){return this.array.length===this.index};return a}(),u=function(a){function b(c,d,e,f){a.call(this,c);this.parent=d;this.observable=e;this.index=f;this.stillUnsubscribed=!0;this.buffer=[];this.isComplete=!1}k(b,a);b.prototype[c.SymbolShim.iterator]=function(){return this};b.prototype.next=
                +function(){var a=this.buffer;return 0===a.length&&this.isComplete?{done:!0}:{value:a.shift(),done:!1}};b.prototype.hasValue=function(){return 0<this.buffer.length};b.prototype.hasCompleted=function(){return 0===this.buffer.length&&this.isComplete};b.prototype.notifyComplete=function(){0<this.buffer.length?(this.isComplete=!0,this.parent.notifyInactive()):this.destination.complete()};b.prototype.notifyNext=function(a,c,d,b,e){this.buffer.push(c);this.parent.checkIterators()};b.prototype.subscribe=
                +function(a,c){return d.subscribeToResult(this,this.observable,this,c)};return b}(e.OuterSubscriber)},{"../OuterSubscriber":6,"../Subscriber":9,"../observable/ArrayObservable":116,"../util/SymbolShim":238,"../util/isArray":240,"../util/subscribeToResult":250}],218:[function(a,b,f){var g=a("./zip");f.zipAll=function(a){return this.lift(new g.ZipOperator(a))}},{"./zip":217}],219:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&
                +(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("../util/Immediate");a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype._schedule=function(b,d){void 0===d&&(d=0);if(0<d)return a.prototype._schedule.call(this,b,d);this.delay=d;this.state=b;var c=this.scheduler;c.actions.push(this);c.scheduledId||(c.scheduledId=k.Immediate.setImmediate(function(){c.scheduledId=null;c.flush()}));return this};b.prototype._unsubscribe=function(){var b=this.scheduler,
                +d=b.scheduledId,c=b.actions;a.prototype._unsubscribe.call(this);0===c.length&&(b.active=!1,null!=d&&(b.scheduledId=null,k.Immediate.clearImmediate(d)))};return b}(a("./FutureAction").FutureAction);f.AsapAction=a},{"../util/Immediate":234,"./FutureAction":221}],220:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("./AsapAction");a=function(a){function b(){a.apply(this,
                +arguments)}g(b,a);b.prototype.scheduleNow=function(a,b){return(new k.AsapAction(this,a)).schedule(b)};return b}(a("./QueueScheduler").QueueScheduler);f.AsapScheduler=a},{"./AsapAction":219,"./QueueScheduler":223}],221:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("../util/root");a=function(a){function b(e,d){a.call(this);this.scheduler=
                +e;this.work=d}g(b,a);b.prototype.execute=function(){if(this.isUnsubscribed)throw Error("How did did we execute a canceled Action?");this.work(this.state)};b.prototype.schedule=function(a,b){void 0===b&&(b=0);return this.isUnsubscribed?this:this._schedule(a,b)};b.prototype._schedule=function(a,b){var c=this;void 0===b&&(b=0);this.delay=b;this.state=a;var f=this.id;null!=f&&(this.id=void 0,k.root.clearTimeout(f));this.id=k.root.setTimeout(function(){c.id=null;var a=c.scheduler;a.actions.push(c);a.flush()},
                +b);return this};b.prototype._unsubscribe=function(){var a=this.id,b=this.scheduler.actions,c=b.indexOf(this);null!=a&&(this.id=null,k.root.clearTimeout(a));-1!==c&&b.splice(c,1);this.scheduler=this.state=this.work=null};return b}(a("../Subscription").Subscription);f.FutureAction=a},{"../Subscription":10,"../util/root":249}],222:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):
                +(f.prototype=b.prototype,new f)};a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype._schedule=function(b,e){void 0===e&&(e=0);if(0<e)return a.prototype._schedule.call(this,b,e);this.delay=e;this.state=b;var d=this.scheduler;d.actions.push(this);d.flush();return this};return b}(a("./FutureAction").FutureAction);f.QueueAction=a},{"./FutureAction":221}],223:[function(a,b,f){var g=a("./QueueAction"),k=a("./FutureAction");a=function(){function a(){this.active=!1;this.actions=[];this.scheduledId=
                +null}a.prototype.now=function(){return Date.now()};a.prototype.flush=function(){if(!this.active&&!this.scheduledId){this.active=!0;for(var a=this.actions,b=void 0;b=a.shift();)b.execute();this.active=!1}};a.prototype.schedule=function(a,b,d){void 0===b&&(b=0);return 0>=b?this.scheduleNow(a,d):this.scheduleLater(a,b,d)};a.prototype.scheduleNow=function(a,b){return(new g.QueueAction(this,a)).schedule(b)};a.prototype.scheduleLater=function(a,b,d){return(new k.FutureAction(this,a)).schedule(d,b)};return a}();
                +f.QueueScheduler=a},{"./FutureAction":221,"./QueueAction":222}],224:[function(a,b,f){a=a("./AsapScheduler");f.asap=new a.AsapScheduler},{"./AsapScheduler":220}],225:[function(a,b,f){a=a("./QueueScheduler");f.queue=new a.QueueScheduler},{"./QueueScheduler":223}],226:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.apply(this,
                +arguments);this.value=null;this.hasNext=!1}g(b,a);b.prototype._subscribe=function(b){this.hasCompleted&&this.hasNext&&b.next(this.value);return a.prototype._subscribe.call(this,b)};b.prototype._next=function(a){this.value=a;this.hasNext=!0};b.prototype._complete=function(){var a=-1,b=this.observers,d=b.length;this.isUnsubscribed=!0;if(this.hasNext)for(;++a<d;){var c=b[a];c.next(this.value);c.complete()}else for(;++a<d;)b[a].complete();this.isUnsubscribed=!1;this.unsubscribe()};return b}(a("../Subject").Subject);
                +f.AsyncSubject=a},{"../Subject":8}],227:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};b=a("../Subject");var k=a("../util/throwError"),l=a("../util/ObjectUnsubscribedError");a=function(a){function b(d){a.call(this);this._value=d}g(b,a);b.prototype.getValue=function(){if(this.hasErrored)k.throwError(this.errorValue);else if(this.isUnsubscribed)k.throwError(new l.ObjectUnsubscribedError);
                +else return this._value};Object.defineProperty(b.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0});b.prototype._subscribe=function(b){var c=a.prototype._subscribe.call(this,b);c&&!c.isUnsubscribed&&b.next(this._value);return c};b.prototype._next=function(b){a.prototype._next.call(this,this._value=b)};b.prototype._error=function(b){this.hasErrored=!0;a.prototype._error.call(this,this.errorValue=b)};return b}(b.Subject);f.BehaviorSubject=a},{"../Subject":8,"../util/ObjectUnsubscribedError":237,
                +"../util/throwError":251}],228:[function(a,b,f){var g=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var f in b)b.hasOwnProperty(f)&&(a[f]=b[f]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};b=a("../Subject");var k=a("../scheduler/queue"),l=a("../operator/observeOn");a=function(a){function b(c,d,f){void 0===c&&(c=Number.POSITIVE_INFINITY);void 0===d&&(d=Number.POSITIVE_INFINITY);a.call(this);this.events=[];this.scheduler=f;this.bufferSize=1>c?1:c;
                +this._windowTime=1>d?1:d}g(b,a);b.prototype._next=function(b){var d=this._getNow();this.events.push(new h(d,b));this._trimBufferThenGetEvents(d);a.prototype._next.call(this,b)};b.prototype._subscribe=function(b){var d=this._trimBufferThenGetEvents(this._getNow()),f=this.scheduler;f&&b.add(b=new l.ObserveOnSubscriber(b,f));for(var f=-1,g=d.length;++f<g&&!b.isUnsubscribed;)b.next(d[f].value);return a.prototype._subscribe.call(this,b)};b.prototype._getNow=function(){return(this.scheduler||k.queue).now()};
                +b.prototype._trimBufferThenGetEvents=function(a){for(var b=this.bufferSize,d=this._windowTime,e=this.events,f=e.length,g=0;g<f&&!(a-e[g].time<d);)g+=1;f>b&&(g=Math.max(g,f-b));0<g&&e.splice(0,g);return e};return b}(b.Subject);f.ReplaySubject=a;var h=function(){return function(a,b){this.time=a;this.value=b}}()},{"../Subject":8,"../operator/observeOn":176,"../scheduler/queue":225}],229:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
                +(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(f,e){a.call(this);this.subject=f;this.observer=e;this.isUnsubscribed=!1}g(b,a);b.prototype.unsubscribe=function(){if(!this.isUnsubscribed){this.isUnsubscribed=!0;var a=this.subject,b=a.observers;this.subject=null;b&&0!==b.length&&!a.isUnsubscribed&&(a=b.indexOf(this.observer),-1!==a&&b.splice(a,1))}};return b}(a("../Subscription").Subscription);f.SubjectSubscription=a},{"../Subscription":10}],
                +230:[function(a,b,f){a=a("../util/SymbolShim");f.rxSubscriber=a.SymbolShim["for"]("rxSubscriber")},{"../util/SymbolShim":238}],231:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"argument out of range");this.name="ArgumentOutOfRangeError"}g(b,a);return b}(Error);f.ArgumentOutOfRangeError=a},{}],232:[function(a,
                +b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"no elements in sequence");this.name="EmptyError"}g(b,a);return b}(Error);f.EmptyError=a},{}],233:[function(a,b,f){a=function(){function a(){this.values={}}a.prototype["delete"]=function(a){this.values[a]=null;return!0};a.prototype.set=function(a,b){this.values[a]=
                +b;return this};a.prototype.get=function(a){return this.values[a]};a.prototype.forEach=function(a,b){var f=this.values,e;for(e in f)f.hasOwnProperty(e)&&null!==f[e]&&a.call(b,f[e],e)};a.prototype.clear=function(){this.values={}};return a}();f.FastMap=a},{}],234:[function(a,b,f){a=a("./root");b=function(){function a(b){this.root=b;b.setImmediate&&"function"===typeof b.setImmediate?(this.setImmediate=b.setImmediate.bind(b),this.clearImmediate=b.clearImmediate.bind(b)):(this.nextHandle=1,this.tasksByHandle=
                +{},this.currentlyRunningATask=!1,this.canUseProcessNextTick()?this.setImmediate=this.createProcessNextTickSetImmediate():this.canUsePostMessage()?this.setImmediate=this.createPostMessageSetImmediate():this.canUseMessageChannel()?this.setImmediate=this.createMessageChannelSetImmediate():this.canUseReadyStateChange()?this.setImmediate=this.createReadyStateChangeSetImmediate():this.setImmediate=this.createSetTimeoutSetImmediate(),b=function h(a){delete h.instance.tasksByHandle[a]},b.instance=this,this.clearImmediate=
                +b)}a.prototype.identify=function(a){return this.root.Object.prototype.toString.call(a)};a.prototype.canUseProcessNextTick=function(){return"[object process]"===this.identify(this.root.process)};a.prototype.canUseMessageChannel=function(){return!!this.root.MessageChannel};a.prototype.canUseReadyStateChange=function(){var a=this.root.document;return!!(a&&"onreadystatechange"in a.createElement("script"))};a.prototype.canUsePostMessage=function(){var a=this.root;if(a.postMessage&&!a.importScripts){var b=
                +!0,f=a.onmessage;a.onmessage=function(){b=!1};a.postMessage("","*");a.onmessage=f;return b}return!1};a.prototype.partiallyApplied=function(a){for(var b=[],f=1;f<arguments.length;f++)b[f-1]=arguments[f];f=function d(){var a=d.handler,b=d.args;"function"===typeof a?a.apply(void 0,b):(new Function(""+a))()};f.handler=a;f.args=b;return f};a.prototype.addFromSetImmediateArguments=function(a){this.tasksByHandle[this.nextHandle]=this.partiallyApplied.apply(void 0,a);return this.nextHandle++};a.prototype.createProcessNextTickSetImmediate=
                +function(){var a=function h(){var a=h.instance,b=a.addFromSetImmediateArguments(arguments);a.root.process.nextTick(a.partiallyApplied(a.runIfPresent,b));return b};a.instance=this;return a};a.prototype.createPostMessageSetImmediate=function(){var a=this.root,b="setImmediate$"+a.Math.random()+"$",f=function d(c){var f=d.instance;c.source===a&&"string"===typeof c.data&&0===c.data.indexOf(b)&&f.runIfPresent(+c.data.slice(b.length))};f.instance=this;a.addEventListener("message",f,!1);f=function c(){var a=
                +c,b=a.messagePrefix,a=a.instance,f=a.addFromSetImmediateArguments(arguments);a.root.postMessage(b+f,"*");return f};f.instance=this;f.messagePrefix=b;return f};a.prototype.runIfPresent=function(a){if(this.currentlyRunningATask)this.root.setTimeout(this.partiallyApplied(this.runIfPresent,a),0);else{var b=this.tasksByHandle[a];if(b){this.currentlyRunningATask=!0;try{b()}finally{this.clearImmediate(a),this.currentlyRunningATask=!1}}}};a.prototype.createMessageChannelSetImmediate=function(){var a=this,
                +b=new this.root.MessageChannel;b.port1.onmessage=function(b){a.runIfPresent(b.data)};var f=function d(){var a=d,b=a.channel,a=a.instance.addFromSetImmediateArguments(arguments);b.port2.postMessage(a);return a};f.channel=b;f.instance=this;return f};a.prototype.createReadyStateChangeSetImmediate=function(){var a=function h(){var a=h.instance,b=a.root.document,c=b.documentElement,f=a.addFromSetImmediateArguments(arguments),g=b.createElement("script");g.onreadystatechange=function(){a.runIfPresent(f);
                +g.onreadystatechange=null;c.removeChild(g);g=null};c.appendChild(g);return f};a.instance=this;return a};a.prototype.createSetTimeoutSetImmediate=function(){var a=function h(){var a=h.instance,b=a.addFromSetImmediateArguments(arguments);a.root.setTimeout(a.partiallyApplied(a.runIfPresent,b),0);return b};a.instance=this;return a};return a}();f.ImmediateDefinition=b;f.Immediate=new b(a.root)},{"./root":249}],235:[function(a,b,f){b=a("./root");a=a("./MapPolyfill");f.Map=b.root.Map||a.MapPolyfill},{"./MapPolyfill":236,
                +"./root":249}],236:[function(a,b,f){a=function(){function a(){this.size=0;this._values=[];this._keys=[]}a.prototype.get=function(a){a=this._keys.indexOf(a);return-1===a?void 0:this._values[a]};a.prototype.set=function(a,b){var f=this._keys.indexOf(a);-1===f?(this._keys.push(a),this._values.push(b),this.size++):this._values[f]=b;return this};a.prototype["delete"]=function(a){a=this._keys.indexOf(a);if(-1===a)return!1;this._values.splice(a,1);this._keys.splice(a,1);this.size--;return!0};a.prototype.clear=
                +function(){this._keys.length=0;this.size=this._values.length=0};a.prototype.forEach=function(a,b){for(var f=0;f<this.size;f++)a.call(b,this._values[f],this._keys[f])};return a}();f.MapPolyfill=a},{}],237:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"object unsubscribed");this.name="ObjectUnsubscribedError"}
                +g(b,a);return b}(Error);f.ObjectUnsubscribedError=a},{}],238:[function(a,b,f){function g(a){var b=l(a);e(b,a);d(b);k(b);return b}function k(a){a["for"]||(a["for"]=h)}function l(a){a.Symbol||(a.Symbol=function(a){return"@@Symbol("+a+"):"+c++});return a.Symbol}function h(a){return"@@"+a}function e(a,b){if(!a.iterator)if("function"===typeof a["for"])a.iterator=a["for"]("iterator");else if(b.Set&&"function"===typeof(new b.Set)["@@iterator"])a.iterator="@@iterator";else if(b.Map)for(var c=Object.getOwnPropertyNames(b.Map.prototype),
                +d=0;d<c.length;++d){var e=c[d];if("entries"!==e&&"size"!==e&&b.Map.prototype[e]===b.Map.prototype.entries){a.iterator=e;break}}else a.iterator="@@iterator"}function d(a){a.observable||(a.observable="function"===typeof a["for"]?a["for"]("observable"):"@@observable")}a=a("./root");f.polyfillSymbol=g;f.ensureFor=k;var c=0;f.ensureSymbol=l;f.symbolForPolyfill=h;f.ensureIterator=e;f.ensureObservable=d;f.SymbolShim=g(a.root)},{"./root":249}],239:[function(a,b,f){f.errorObject={e:{}}},{}],240:[function(a,
                +b,f){f.isArray=Array.isArray||function(a){return a&&"number"===typeof a.length}},{}],241:[function(a,b,f){f.isDate=function(a){return a instanceof Date&&!isNaN(+a)}},{}],242:[function(a,b,f){f.isFunction=function(a){return"function"===typeof a}},{}],243:[function(a,b,f){var g=a("../util/isArray");f.isNumeric=function(a){return!g.isArray(a)&&0<=a-parseFloat(a)+1}},{"../util/isArray":240}],244:[function(a,b,f){f.isObject=function(a){return null!=a&&"object"===typeof a}},{}],245:[function(a,b,f){f.isPromise=
                +function(a){return a&&"function"!==typeof a.subscribe&&"function"===typeof a.then}},{}],246:[function(a,b,f){f.isScheduler=function(a){return a&&"function"===typeof a.schedule}},{}],247:[function(a,b,f){f.noop=function(){}},{}],248:[function(a,b,f){f.not=function(a,b){function f(){return!f.pred.apply(f.thisArg,arguments)}f.pred=a;f.thisArg=b;return f}},{}],249:[function(a,b,f){a="undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{};b={"boolean":!1,
                +"function":!0,object:!0,number:!1,string:!1,undefined:!1};f.root=b[typeof self]&&self||b[typeof window]&&window;!(a=b[typeof a]&&a)||a.global!==a&&a.window!==a||(f.root=a)},{}],250:[function(a,b,f){var g=a("./root"),k=a("./isArray"),l=a("./isPromise"),h=a("../Observable"),e=a("../util/SymbolShim"),d=a("../InnerSubscriber");f.subscribeToResult=function(a,b,f,q){var p=new d.InnerSubscriber(a,f,q);if(!p.isUnsubscribed){if(b instanceof h.Observable){if(b._isScalar){p.next(b.value);p.complete();return}return b.subscribe(p)}if(k.isArray(b)){a=
                +0;for(f=b.length;a<f&&!p.isUnsubscribed;a++)p.next(b[a]);p.isUnsubscribed||p.complete()}else{if(l.isPromise(b))return b.then(function(a){p.isUnsubscribed||(p.next(a),p.complete())},function(a){return p.error(a)}).then(null,function(a){g.root.setTimeout(function(){throw a;})}),p;if("function"===typeof b[e.SymbolShim.iterator]){for(a=0;a<b.length&&(p.next(b[a]),!p.isUnsubscribed);a++);p.isUnsubscribed||p.complete()}else if("function"===typeof b[e.SymbolShim.observable])if(b=b[e.SymbolShim.observable](),
                +"function"!==typeof b.subscribe)p.error("invalid observable");else return b.subscribe(new d.InnerSubscriber(a,f,q));else p.error(new TypeError("unknown type returned"))}}}},{"../InnerSubscriber":1,"../Observable":3,"../util/SymbolShim":238,"./isArray":240,"./isPromise":245,"./root":249}],251:[function(a,b,f){f.throwError=function(a){throw a;}},{}],252:[function(a,b,f){var g=a("../Subscriber"),k=a("../symbol/rxSubscriber");f.toSubscriber=function(a,b,e){if(a&&"object"===typeof a){if(a instanceof g.Subscriber)return a;
                +if("function"===typeof a[k.rxSubscriber])return a[k.rxSubscriber]()}return new g.Subscriber(a,b,e)}},{"../Subscriber":9,"../symbol/rxSubscriber":230}],253:[function(a,b,f){function g(){try{return l.apply(this,arguments)}catch(a){return k.errorObject.e=a,k.errorObject}}var k=a("./errorObject"),l;f.tryCatch=function(a){l=a;return g}},{"./errorObject":239}]},{},[7])(7)});
                +
                diff --git a/blockly/webif/static/blockly/accessible/libs/angular2-all.umd.min.js b/blockly/webif/static/blockly/accessible/libs/angular2-all.umd.min.js
                new file mode 100644
                index 000000000..9688becf9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/libs/angular2-all.umd.min.js
                @@ -0,0 +1,44 @@
                +/**
                +The MIT License
                +
                +Copyright (c) 2014-2017 Google, Inc. http://angular.io
                +
                +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(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("Rx"),require("rxjs/operator/toPromise")):"function"==typeof define&&define.amd?define(["Rx","rxjs/operator/toPromise"],e):"object"==typeof exports?exports.ng=e(require("Rx"),require("rxjs/operator/toPromise")):t.ng=e(t.Rx,t.Rx.Observable.prototype)}(this,function(t,e){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){t.exports=n(1)},function(t,e,n){e.core=n(2),e.common=n(87),e.compiler=n(137),e.platform={browser:n(201),common_dom:n(224)},e.http=n(232),e.router=n(247),e.router_link_dsl=n(278),e.instrumentation=n(280),e.upgrade=n(281)},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}r(n(3)),r(n(37)),r(n(38)),r(n(6)),r(n(39));var i=n(5);e.enableProdMode=i.enableProdMode;var o=n(59);e.createPlatform=o.createPlatform,e.assertPlatform=o.assertPlatform,e.disposePlatform=o.disposePlatform,e.getPlatform=o.getPlatform,e.coreBootstrap=o.coreBootstrap,e.coreLoadAndBootstrap=o.coreLoadAndBootstrap,e.createNgZone=o.createNgZone,e.PlatformRef=o.PlatformRef,e.ApplicationRef=o.ApplicationRef;var s=n(62);e.APP_ID=s.APP_ID,e.APP_INITIALIZER=s.APP_INITIALIZER,e.PACKAGE_ROOT_URL=s.PACKAGE_ROOT_URL,e.PLATFORM_INITIALIZER=s.PLATFORM_INITIALIZER,r(n(76)),r(n(77)),r(n(78));var a=n(83);e.DebugElement=a.DebugElement,e.DebugNode=a.DebugNode,e.asNativeElements=a.asNativeElements,r(n(63)),r(n(27)),r(n(84)),r(n(85)),r(n(86)),r(n(18))},function(t,e,n){"use strict";var r=n(4);e.QueryMetadata=r.QueryMetadata,e.ContentChildrenMetadata=r.ContentChildrenMetadata,e.ContentChildMetadata=r.ContentChildMetadata,e.ViewChildrenMetadata=r.ViewChildrenMetadata,e.ViewQueryMetadata=r.ViewQueryMetadata,e.ViewChildMetadata=r.ViewChildMetadata,e.AttributeMetadata=r.AttributeMetadata;var i=n(26);e.ComponentMetadata=i.ComponentMetadata,e.DirectiveMetadata=i.DirectiveMetadata,e.PipeMetadata=i.PipeMetadata,e.InputMetadata=i.InputMetadata,e.OutputMetadata=i.OutputMetadata,e.HostBindingMetadata=i.HostBindingMetadata,e.HostListenerMetadata=i.HostListenerMetadata;var o=n(36);e.ViewMetadata=o.ViewMetadata,e.ViewEncapsulation=o.ViewEncapsulation;var s=n(4),a=n(26),u=n(36),c=n(9);e.Component=c.makeDecorator(a.ComponentMetadata,function(t){return t.View=p}),e.Directive=c.makeDecorator(a.DirectiveMetadata);var p=c.makeDecorator(u.ViewMetadata,function(t){return t.View=p});e.Attribute=c.makeParamDecorator(s.AttributeMetadata),e.Query=c.makeParamDecorator(s.QueryMetadata),e.ContentChildren=c.makePropDecorator(s.ContentChildrenMetadata),e.ContentChild=c.makePropDecorator(s.ContentChildMetadata),e.ViewChildren=c.makePropDecorator(s.ViewChildrenMetadata),e.ViewChild=c.makePropDecorator(s.ViewChildMetadata),e.ViewQuery=c.makeParamDecorator(s.ViewQueryMetadata),e.Pipe=c.makeDecorator(a.PipeMetadata),e.Input=c.makePropDecorator(a.InputMetadata),e.Output=c.makePropDecorator(a.OutputMetadata),e.HostBinding=c.makePropDecorator(a.HostBindingMetadata),e.HostListener=c.makePropDecorator(a.HostListenerMetadata)},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(6),u=n(7),c=function(t){function e(e){t.call(this),this.attributeName=e}return r(e,t),Object.defineProperty(e.prototype,"token",{get:function(){return this},enumerable:!0,configurable:!0}),e.prototype.toString=function(){return"@Attribute("+s.stringify(this.attributeName)+")"},e=i([s.CONST(),o("design:paramtypes",[String])],e)}(u.DependencyMetadata);e.AttributeMetadata=c;var p=function(t){function e(e,n){var r=void 0===n?{}:n,i=r.descendants,o=void 0===i?!1:i,s=r.first,a=void 0===s?!1:s,u=r.read,c=void 0===u?null:u;t.call(this),this._selector=e,this.descendants=o,this.first=a,this.read=c}return r(e,t),Object.defineProperty(e.prototype,"isViewQuery",{get:function(){return!1},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"selector",{get:function(){return a.resolveForwardRef(this._selector)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isVarBindingQuery",{get:function(){return s.isString(this.selector)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"varBindings",{get:function(){return this.selector.split(",")},enumerable:!0,configurable:!0}),e.prototype.toString=function(){return"@Query("+s.stringify(this.selector)+")"},e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(u.DependencyMetadata);e.QueryMetadata=p;var l=function(t){function e(e,n){var r=void 0===n?{}:n,i=r.descendants,o=void 0===i?!1:i,s=r.read,a=void 0===s?null:s;t.call(this,e,{descendants:o,read:a})}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(p);e.ContentChildrenMetadata=l;var h=function(t){function e(e,n){var r=(void 0===n?{}:n).read,i=void 0===r?null:r;t.call(this,e,{descendants:!0,first:!0,read:i})}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(p);e.ContentChildMetadata=h;var f=function(t){function e(e,n){var r=void 0===n?{}:n,i=r.descendants,o=void 0===i?!1:i,s=r.first,a=void 0===s?!1:s,u=r.read,c=void 0===u?null:u;t.call(this,e,{descendants:o,first:a,read:c})}return r(e,t),Object.defineProperty(e.prototype,"isViewQuery",{get:function(){return!0},enumerable:!0,configurable:!0}),e.prototype.toString=function(){return"@ViewQuery("+s.stringify(this.selector)+")"},e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(p);e.ViewQueryMetadata=f;var d=function(t){function e(e,n){var r=(void 0===n?{}:n).read,i=void 0===r?null:r;t.call(this,e,{descendants:!0,read:i})}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(f);e.ViewChildrenMetadata=d;var v=function(t){function e(e,n){var r=(void 0===n?{}:n).read,i=void 0===r?null:r;t.call(this,e,{descendants:!0,first:!0,read:i})}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object,Object])],e)}(f);e.ViewChildMetadata=v},function(t,e){(function(t){"use strict";function n(t){Zone.current.scheduleMicroTask("scheduleMicrotask",t)}function r(t){return t.name?t.name:typeof t}function i(){H=!0}function o(){if(H)throw"Cannot enable prod mode after platform setup.";W=!1}function s(){return W}function a(t){return t}function u(){return function(t){return t}}function c(t){return void 0!==t&&null!==t}function p(t){return void 0===t||null===t}function l(t){return"boolean"==typeof t}function h(t){return"number"==typeof t}function f(t){return"string"==typeof t}function d(t){return"function"==typeof t}function v(t){return d(t)}function y(t){return"object"==typeof t&&null!==t}function m(t){return t instanceof U.Promise}function g(t){return Array.isArray(t)}function _(t){return t instanceof e.Date&&!isNaN(t.valueOf())}function b(){}function P(t){if("string"==typeof t)return t;if(void 0===t||null===t)return""+t;if(t.name)return t.name;if(t.overriddenName)return t.overriddenName;var e=t.toString(),n=e.indexOf("\n");return-1===n?e:e.substring(0,n)}function E(t){return t}function w(t,e){return t}function C(t,e){return t[e]}function R(t,e){return t===e||"number"==typeof t&&"number"==typeof e&&isNaN(t)&&isNaN(e)}function S(t){return t}function O(t){return p(t)?null:t}function T(t){return p(t)?!1:t}function x(t){return null!==t&&("function"==typeof t||"object"==typeof t)}function A(t){console.log(t)}function I(t,e,n){for(var r=e.split("."),i=t;r.length>1;){var o=r.shift();i=i.hasOwnProperty(o)&&c(i[o])?i[o]:i[o]={}}(void 0===i||null===i)&&(i={}),i[r.shift()]=n}function M(){if(p(Y))if(c(Symbol)&&c(Symbol.iterator))Y=Symbol.iterator;else for(var t=Object.getOwnPropertyNames(Map.prototype),e=0;e<t.length;++e){var n=t[e];"entries"!==n&&"size"!==n&&Map.prototype[n]===Map.prototype.entries&&(Y=n)}return Y}function k(t,e,n,r){var i=n+"\nreturn "+e+"\n//# sourceURL="+t,o=[],s=[];for(var a in r)o.push(a),s.push(r[a]);return(new(Function.bind.apply(Function,[void 0].concat(o.concat(i))))).apply(void 0,s)}function N(t){return!x(t)}function D(t,e){return t.constructor===e}function V(t){return t.reduce(function(t,e){return t|e})}function j(t){return t.reduce(function(t,e){return t&e})}function L(t){return U.encodeURI(t)}var B,F=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)};B="undefined"==typeof window?"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:t:window,e.scheduleMicroTask=n,e.IS_DART=!1;var U=B;e.global=U,e.Type=Function,e.getTypeNameForDebugging=r,e.Math=U.Math,e.Date=U.Date;var W=!0,H=!1;e.lockMode=i,e.enableProdMode=o,e.assertionsEnabled=s,U.assert=function(t){},e.CONST_EXPR=a,e.CONST=u,e.isPresent=c,e.isBlank=p,e.isBoolean=l,e.isNumber=h,e.isString=f,e.isFunction=d,e.isType=v,e.isStringMap=y,e.isPromise=m,e.isArray=g,e.isDate=_,e.noop=b,e.stringify=P,e.serializeEnum=E,e.deserializeEnum=w,e.resolveEnumToken=C;var X=function(){function t(){}return t.fromCharCode=function(t){return String.fromCharCode(t)},t.charCodeAt=function(t,e){return t.charCodeAt(e)},t.split=function(t,e){return t.split(e)},t.equals=function(t,e){return t===e},t.stripLeft=function(t,e){if(t&&t.length){for(var n=0,r=0;r<t.length&&t[r]==e;r++)n++;t=t.substring(n)}return t},t.stripRight=function(t,e){if(t&&t.length){for(var n=t.length,r=t.length-1;r>=0&&t[r]==e;r--)n--;t=t.substring(0,n)}return t},t.replace=function(t,e,n){return t.replace(e,n)},t.replaceAll=function(t,e,n){return t.replace(e,n)},t.slice=function(t,e,n){return void 0===e&&(e=0),void 0===n&&(n=null),t.slice(e,null===n?void 0:n)},t.replaceAllMapped=function(t,e,n){return t.replace(e,function(){for(var t=[],e=0;e<arguments.length;e++)t[e-0]=arguments[e];return t.splice(-2,2),n(t)})},t.contains=function(t,e){return-1!=t.indexOf(e)},t.compare=function(t,e){return e>t?-1:t>e?1:0},t}();e.StringWrapper=X;var q=function(){function t(t){void 0===t&&(t=[]),this.parts=t}return t.prototype.add=function(t){this.parts.push(t)},t.prototype.toString=function(){return this.parts.join("")},t}();e.StringJoiner=q;var G=function(t){function e(e){t.call(this),this.message=e}return F(e,t),e.prototype.toString=function(){return this.message},e}(Error);e.NumberParseError=G;var z=function(){function t(){}return t.toFixed=function(t,e){return t.toFixed(e)},t.equal=function(t,e){return t===e},t.parseIntAutoRadix=function(t){var e=parseInt(t);if(isNaN(e))throw new G("Invalid integer literal when parsing "+t);return e},t.parseInt=function(t,e){if(10==e){if(/^(\-|\+)?[0-9]+$/.test(t))return parseInt(t,e)}else if(16==e){if(/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(t))return parseInt(t,e)}else{var n=parseInt(t,e);if(!isNaN(n))return n}throw new G("Invalid integer literal when parsing "+t+" in base "+e)},t.parseFloat=function(t){return parseFloat(t)},Object.defineProperty(t,"NaN",{get:function(){return NaN},enumerable:!0,configurable:!0}),t.isNaN=function(t){return isNaN(t)},t.isInteger=function(t){return Number.isInteger(t)},t}();e.NumberWrapper=z,e.RegExp=U.RegExp;var K=function(){function t(){}return t.create=function(t,e){return void 0===e&&(e=""),e=e.replace(/g/g,""),new U.RegExp(t,e+"g")},t.firstMatch=function(t,e){return t.lastIndex=0,t.exec(e)},t.test=function(t,e){return t.lastIndex=0,t.test(e)},t.matcher=function(t,e){return t.lastIndex=0,{re:t,input:e}},t.replaceAll=function(t,e,n){var r=t.exec(e),i="";t.lastIndex=0;for(var o=0;r;)i+=e.substring(o,r.index),i+=n(r),o=r.index+r[0].length,t.lastIndex=o,r=t.exec(e);return i+=e.substring(o)},t}();e.RegExpWrapper=K;var $=function(){function t(){}return t.next=function(t){return t.re.exec(t.input)},t}();e.RegExpMatcherWrapper=$;var Q=function(){function t(){}return t.apply=function(t,e){return t.apply(null,e)},t}();e.FunctionWrapper=Q,e.looseIdentical=R,e.getMapKey=S,e.normalizeBlank=O,e.normalizeBool=T,e.isJsObject=x,e.print=A;var J=function(){function t(){}return t.parse=function(t){return U.JSON.parse(t)},t.stringify=function(t){return U.JSON.stringify(t,null,2)},t}();e.Json=J;var Z=function(){function t(){}return t.create=function(t,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new e.Date(t,n-1,r,i,o,s,a)},t.fromISOString=function(t){return new e.Date(t)},t.fromMillis=function(t){return new e.Date(t)},t.toMillis=function(t){return t.getTime()},t.now=function(){return new e.Date},t.toJson=function(t){return t.toJSON()},t}();e.DateWrapper=Z,e.setValueOnPath=I;var Y=null;e.getSymbolIterator=M,e.evalExpression=k,e.isPrimitive=N,e.hasConstructor=D,e.bitWiseOr=V,e.bitWiseAnd=j,e.escape=L}).call(e,function(){return this}())},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}var i=n(7);e.InjectMetadata=i.InjectMetadata,e.OptionalMetadata=i.OptionalMetadata,e.InjectableMetadata=i.InjectableMetadata,e.SelfMetadata=i.SelfMetadata,e.HostMetadata=i.HostMetadata,e.SkipSelfMetadata=i.SkipSelfMetadata,e.DependencyMetadata=i.DependencyMetadata,r(n(8));var o=n(10);e.forwardRef=o.forwardRef,e.resolveForwardRef=o.resolveForwardRef;var s=n(11);e.Injector=s.Injector;var a=n(16);e.ReflectiveInjector=a.ReflectiveInjector;var u=n(24);e.Binding=u.Binding,e.ProviderBuilder=u.ProviderBuilder,e.bind=u.bind,e.Provider=u.Provider,e.provide=u.provide;var c=n(17);e.ResolvedReflectiveFactory=c.ResolvedReflectiveFactory,e.ReflectiveDependency=c.ReflectiveDependency;var p=n(22);e.ReflectiveKey=p.ReflectiveKey;var l=n(23);e.NoProviderError=l.NoProviderError,e.AbstractProviderError=l.AbstractProviderError,e.CyclicDependencyError=l.CyclicDependencyError,e.InstantiationError=l.InstantiationError,e.InvalidProviderError=l.InvalidProviderError,e.NoAnnotationError=l.NoAnnotationError,e.OutOfBoundsError=l.OutOfBoundsError;var h=n(25);e.OpaqueToken=h.OpaqueToken},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=function(){function t(t){this.token=t}return t.prototype.toString=function(){return"@Inject("+o.stringify(this.token)+")"},t=r([o.CONST(),i("design:paramtypes",[Object])],t)}();e.InjectMetadata=s;var a=function(){function t(){}return t.prototype.toString=function(){return"@Optional()"},t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.OptionalMetadata=a;var u=function(){function t(){}return Object.defineProperty(t.prototype,"token",{get:function(){return null},enumerable:!0,configurable:!0}),t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.DependencyMetadata=u;var c=function(){function t(){}return t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.InjectableMetadata=c;var p=function(){function t(){}return t.prototype.toString=function(){return"@Self()"},t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.SelfMetadata=p;var l=function(){function t(){}return t.prototype.toString=function(){return"@SkipSelf()"},t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.SkipSelfMetadata=l;var h=function(){function t(){}return t.prototype.toString=function(){return"@Host()"},t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.HostMetadata=h},function(t,e,n){"use strict";var r=n(7),i=n(9);e.Inject=i.makeParamDecorator(r.InjectMetadata),e.Optional=i.makeParamDecorator(r.OptionalMetadata),e.Injectable=i.makeDecorator(r.InjectableMetadata),e.Self=i.makeParamDecorator(r.SelfMetadata),e.Host=i.makeParamDecorator(r.HostMetadata),e.SkipSelf=i.makeParamDecorator(r.SkipSelfMetadata)},function(t,e,n){"use strict";function r(t){return c.isFunction(t)&&t.hasOwnProperty("annotation")&&(t=t.annotation),t}function i(t,e){if(t===Object||t===String||t===Function||t===Number||t===Array)throw new Error("Can not use native "+c.stringify(t)+" as constructor");if(c.isFunction(t))return t;if(t instanceof Array){var n=t,i=t[t.length-1];if(!c.isFunction(i))throw new Error("Last position of Class method array must be Function in key "+e+" was '"+c.stringify(i)+"'");var o=n.length-1;if(o!=i.length)throw new Error("Number of annotations ("+o+") does not match number of arguments ("+i.length+") in the function: "+c.stringify(i));for(var s=[],a=0,u=n.length-1;u>a;a++){var p=[];s.push(p);var h=n[a];if(h instanceof Array)for(var f=0;f<h.length;f++)p.push(r(h[f]));else c.isFunction(h)?p.push(r(h)):p.push(h)}return l.defineMetadata("parameters",s,i),i}throw new Error("Only Function or Array is supported in Class definition for key '"+e+"' is '"+c.stringify(t)+"'")}function o(t){var e=i(t.hasOwnProperty("constructor")?t.constructor:void 0,"constructor"),n=e.prototype;if(t.hasOwnProperty("extends")){if(!c.isFunction(t["extends"]))throw new Error("Class definition 'extends' property must be a constructor function was: "+c.stringify(t["extends"]));e.prototype=n=Object.create(t["extends"].prototype)}for(var r in t)"extends"!=r&&"prototype"!=r&&t.hasOwnProperty(r)&&(n[r]=i(t[r],r));return this&&this.annotations instanceof Array&&l.defineMetadata("annotations",this.annotations,e),e.name||(e.overriddenName="class"+p++),e}function s(t,e){function n(n){var r=new t(n);if(this instanceof t)return r;var i=c.isFunction(this)&&this.annotations instanceof Array?this.annotations:[];i.push(r);var s=function(t){var e=l.getOwnMetadata("annotations",t);return e=e||[],e.push(r),l.defineMetadata("annotations",e,t),t};return s.annotations=i,s.Class=o,e&&e(s),s}return void 0===e&&(e=null),n.prototype=Object.create(t.prototype),n}function a(t){function e(){function e(t,e,n){var r=l.getMetadata("parameters",t);for(r=r||[];r.length<=n;)r.push(null);r[n]=r[n]||[];var o=r[n];return o.push(i),l.defineMetadata("parameters",r,t),t}for(var n=[],r=0;r<arguments.length;r++)n[r-0]=arguments[r];var i=Object.create(t.prototype);return t.apply(i,n),this instanceof t?i:(e.annotation=i,e)}return e.prototype=Object.create(t.prototype),e}function u(t){function e(){for(var e=[],n=0;n<arguments.length;n++)e[n-0]=arguments[n];var r=Object.create(t.prototype);return t.apply(r,e),this instanceof t?r:function(t,e){var n=l.getOwnMetadata("propMetadata",t.constructor);n=n||{},n[e]=n[e]||[],n[e].unshift(r),l.defineMetadata("propMetadata",n,t.constructor)}}return e.prototype=Object.create(t.prototype),e}var c=n(5),p=0;e.Class=o;var l=c.global.Reflect;!function(){if(!l||!l.getMetadata)throw"reflect-metadata shim is required when using class decorators"}(),e.makeDecorator=s,e.makeParamDecorator=a,e.makePropDecorator=u},function(t,e,n){"use strict";function r(t){return t.__forward_ref__=r,t.toString=function(){return o.stringify(this())},t}function i(t){return o.isFunction(t)&&t.hasOwnProperty("__forward_ref__")&&t.__forward_ref__===r?t():t}var o=n(5);e.forwardRef=r,e.resolveForwardRef=i},function(t,e,n){"use strict";var r=n(5),i=n(12),o=r.CONST_EXPR(new Object);e.THROW_IF_NOT_FOUND=o;var s=function(){function t(){}return t.prototype.get=function(t,e){return i.unimplemented()},t.THROW_IF_NOT_FOUND=o,t}();e.Injector=s},function(t,e,n){"use strict";function r(t){return new TypeError(t)}function i(){throw new c("unimplemented")}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=n(13),a=n(14),u=n(14);e.ExceptionHandler=u.ExceptionHandler;var c=function(t){function e(e){void 0===e&&(e="--"),t.call(this,e),this.message=e,this.stack=new Error(e).stack}return o(e,t),e.prototype.toString=function(){return this.message},e}(Error);e.BaseException=c;var p=function(t){function e(e,n,r,i){t.call(this,e),this._wrapperMessage=e,this._originalException=n,this._originalStack=r,this._context=i,this._wrapperStack=new Error(e).stack}return o(e,t),Object.defineProperty(e.prototype,"wrapperMessage",{get:function(){return this._wrapperMessage},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"wrapperStack",{get:function(){return this._wrapperStack},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"originalException",{get:function(){return this._originalException},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"originalStack",{get:function(){return this._originalStack},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"context",{get:function(){return this._context},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"message",{get:function(){return a.ExceptionHandler.exceptionToString(this)},enumerable:!0,configurable:!0}),e.prototype.toString=function(){return this.message},e}(s.BaseWrappedException);e.WrappedException=p,e.makeTypeError=r,e.unimplemented=i},function(t,e){"use strict";var n=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},r=function(t){function e(e){t.call(this,e)}return n(e,t),Object.defineProperty(e.prototype,"wrapperMessage",{get:function(){return""},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"wrapperStack",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"originalException",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"originalStack",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"context",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"message",{get:function(){return""},enumerable:!0,configurable:!0}),e}(Error);e.BaseWrappedException=r},function(t,e,n){"use strict";var r=n(5),i=n(13),o=n(15),s=function(){function t(){this.res=[]}return t.prototype.log=function(t){this.res.push(t)},t.prototype.logError=function(t){this.res.push(t)},t.prototype.logGroup=function(t){this.res.push(t)},t.prototype.logGroupEnd=function(){},t}(),a=function(){function t(t,e){void 0===e&&(e=!0),this._logger=t,this._rethrowException=e}return t.exceptionToString=function(e,n,r){void 0===n&&(n=null),void 0===r&&(r=null);var i=new s,o=new t(i,!1);return o.call(e,n,r),i.res.join("\n")},t.prototype.call=function(t,e,n){void 0===e&&(e=null),void 0===n&&(n=null);var i=this._findOriginalException(t),o=this._findOriginalStack(t),s=this._findContext(t);if(this._logger.logGroup("EXCEPTION: "+this._extractMessage(t)),r.isPresent(e)&&r.isBlank(o)&&(this._logger.logError("STACKTRACE:"),this._logger.logError(this._longStackTrace(e))),r.isPresent(n)&&this._logger.logError("REASON: "+n),r.isPresent(i)&&this._logger.logError("ORIGINAL EXCEPTION: "+this._extractMessage(i)),r.isPresent(o)&&(this._logger.logError("ORIGINAL STACKTRACE:"),this._logger.logError(this._longStackTrace(o))),r.isPresent(s)&&(this._logger.logError("ERROR CONTEXT:"),this._logger.logError(s)),this._logger.logGroupEnd(),this._rethrowException)throw t},t.prototype._extractMessage=function(t){return t instanceof i.BaseWrappedException?t.wrapperMessage:t.toString()},t.prototype._longStackTrace=function(t){return o.isListLikeIterable(t)?t.join("\n\n-----async gap-----\n"):t.toString()},t.prototype._findContext=function(t){try{return t instanceof i.BaseWrappedException?r.isPresent(t.context)?t.context:this._findContext(t.originalException):null}catch(e){return null}},t.prototype._findOriginalException=function(t){if(!(t instanceof i.BaseWrappedException))return null;for(var e=t.originalException;e instanceof i.BaseWrappedException&&r.isPresent(e.originalException);)e=e.originalException;return e},t.prototype._findOriginalStack=function(t){if(!(t instanceof i.BaseWrappedException))return null;for(var e=t,n=t.originalStack;e instanceof i.BaseWrappedException&&r.isPresent(e.originalException);)e=e.originalException,e instanceof i.BaseWrappedException&&r.isPresent(e.originalException)&&(n=e.originalStack);return n},t}();e.ExceptionHandler=a},function(t,e,n){"use strict";function r(t,e){if(a.isPresent(t))for(var n=0;n<t.length;n++){var i=t[n];a.isArray(i)?r(i,e):e.push(i)}return e}function i(t){return a.isJsObject(t)?a.isArray(t)||!(t instanceof e.Map)&&a.getSymbolIterator()in t:!1}function o(t,e,n){for(var r=t[a.getSymbolIterator()](),i=e[a.getSymbolIterator()]();;){var o=r.next(),s=i.next();if(o.done&&s.done)return!0;if(o.done||s.done)return!1;if(!n(o.value,s.value))return!1}}function s(t,e){if(a.isArray(t))for(var n=0;n<t.length;n++)e(t[n]);else for(var r,i=t[a.getSymbolIterator()]();!(r=i.next()).done;)e(r.value)}var a=n(5);e.Map=a.global.Map,e.Set=a.global.Set;var u=function(){try{if(1===new e.Map([[1,2]]).size)return function(t){return new e.Map(t)}}catch(t){}return function(t){for(var n=new e.Map,r=0;r<t.length;r++){var i=t[r];n.set(i[0],i[1])}return n}}(),c=function(){try{if(new e.Map(new e.Map))return function(t){return new e.Map(t)}}catch(t){}return function(t){var n=new e.Map;return t.forEach(function(t,e){n.set(e,t)}),n}}(),p=function(){return(new e.Map).keys().next?function(t){for(var e,n=t.keys();!(e=n.next()).done;)t.set(e.value,null)}:function(t){t.forEach(function(e,n){t.set(n,null)})}}(),l=function(){try{if((new e.Map).values().next)return function(t,e){return e?Array.from(t.values()):Array.from(t.keys())}}catch(t){}return function(t,e){var n=d.createFixedSize(t.size),r=0;return t.forEach(function(t,i){n[r]=e?t:i,r++}),n}}(),h=function(){function t(){}return t.clone=function(t){return c(t)},t.createFromStringMap=function(t){var n=new e.Map;for(var r in t)n.set(r,t[r]);return n},t.toStringMap=function(t){var e={};return t.forEach(function(t,n){return e[n]=t}),e},t.createFromPairs=function(t){return u(t)},t.clearValues=function(t){p(t)},t.iterable=function(t){return t},t.keys=function(t){return l(t,!1)},t.values=function(t){return l(t,!0)},t}();e.MapWrapper=h;var f=function(){function t(){}return t.create=function(){return{}},t.contains=function(t,e){return t.hasOwnProperty(e)},t.get=function(t,e){return t.hasOwnProperty(e)?t[e]:void 0},t.set=function(t,e,n){t[e]=n},t.keys=function(t){return Object.keys(t)},t.values=function(t){return Object.keys(t).reduce(function(e,n){return e.push(t[n]),e},[])},t.isEmpty=function(t){for(var e in t)return!1;return!0},t["delete"]=function(t,e){delete t[e]},t.forEach=function(t,e){for(var n in t)t.hasOwnProperty(n)&&e(t[n],n)},t.merge=function(t,e){var n={};for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);return n},t.equals=function(t,e){var n=Object.keys(t),r=Object.keys(e);if(n.length!=r.length)return!1;for(var i,o=0;o<n.length;o++)if(i=n[o],t[i]!==e[i])return!1;return!0},t}();e.StringMapWrapper=f;var d=function(){function t(){}return t.createFixedSize=function(t){return new Array(t)},t.createGrowableSize=function(t){return new Array(t)},t.clone=function(t){return t.slice(0)},t.forEachWithIndex=function(t,e){for(var n=0;n<t.length;n++)e(t[n],n)},t.first=function(t){return t?t[0]:null},t.last=function(t){return t&&0!=t.length?t[t.length-1]:null},t.indexOf=function(t,e,n){return void 0===n&&(n=0),t.indexOf(e,n)},t.contains=function(t,e){return-1!==t.indexOf(e)},t.reversed=function(e){var n=t.clone(e);return n.reverse()},t.concat=function(t,e){return t.concat(e)},t.insert=function(t,e,n){t.splice(e,0,n)},t.removeAt=function(t,e){var n=t[e];return t.splice(e,1),n},t.removeAll=function(t,e){for(var n=0;n<e.length;++n){var r=t.indexOf(e[n]);t.splice(r,1)}},t.remove=function(t,e){var n=t.indexOf(e);return n>-1?(t.splice(n,1),!0):!1},t.clear=function(t){t.length=0},t.isEmpty=function(t){return 0==t.length},t.fill=function(t,e,n,r){void 0===n&&(n=0),void 0===r&&(r=null),t.fill(e,n,null===r?t.length:r)},t.equals=function(t,e){if(t.length!=e.length)return!1;for(var n=0;n<t.length;++n)if(t[n]!==e[n])return!1;return!0},t.slice=function(t,e,n){return void 0===e&&(e=0),void 0===n&&(n=null),t.slice(e,null===n?void 0:n)},t.splice=function(t,e,n){return t.splice(e,n)},t.sort=function(t,e){a.isPresent(e)?t.sort(e):t.sort()},t.toString=function(t){return t.toString()},t.toJSON=function(t){return JSON.stringify(t)},t.maximum=function(t,e){if(0==t.length)return null;for(var n=null,r=-(1/0),i=0;i<t.length;i++){var o=t[i];if(!a.isBlank(o)){var s=e(o);s>r&&(n=o,r=s)}}return n},t.flatten=function(t){var e=[];return r(t,e),e},t.addAll=function(t,e){for(var n=0;n<e.length;n++)t.push(e[n])},t}();e.ListWrapper=d,e.isListLikeIterable=i,e.areIterablesEqual=o,e.iterateListLike=s;var v=function(){var t=new e.Set([1,2,3]);return 3===t.size?function(t){return new e.Set(t)}:function(t){var n=new e.Set(t);if(n.size!==t.length)for(var r=0;r<t.length;r++)n.add(t[r]);return n}}(),y=function(){function t(){}return t.createFromList=function(t){return v(t)},t.has=function(t,e){return t.has(e)},t["delete"]=function(t,e){t["delete"](e)},t}();e.SetWrapper=y},function(t,e,n){"use strict";function r(t,e){for(var n=[],r=0;r<t._proto.numberOfProviders;++r)n.push(e(t._proto.getProviderAtIndex(r)));return n}var i=n(15),o=n(17),s=n(23),a=n(5),u=n(12),c=n(22),p=n(7),l=n(11),h=10,f=a.CONST_EXPR(new Object),d=function(){function t(t,e){this.provider0=null,this.provider1=null,this.provider2=null,this.provider3=null,this.provider4=null,this.provider5=null,this.provider6=null,this.provider7=null,this.provider8=null,this.provider9=null,this.keyId0=null,this.keyId1=null,this.keyId2=null,this.keyId3=null,this.keyId4=null,this.keyId5=null,this.keyId6=null,this.keyId7=null,this.keyId8=null,this.keyId9=null;var n=e.length;n>0&&(this.provider0=e[0],this.keyId0=e[0].key.id),n>1&&(this.provider1=e[1],this.keyId1=e[1].key.id),n>2&&(this.provider2=e[2],this.keyId2=e[2].key.id),n>3&&(this.provider3=e[3],this.keyId3=e[3].key.id),n>4&&(this.provider4=e[4],this.keyId4=e[4].key.id),n>5&&(this.provider5=e[5],this.keyId5=e[5].key.id),n>6&&(this.provider6=e[6],this.keyId6=e[6].key.id),n>7&&(this.provider7=e[7],this.keyId7=e[7].key.id),n>8&&(this.provider8=e[8],this.keyId8=e[8].key.id),n>9&&(this.provider9=e[9],this.keyId9=e[9].key.id)}return t.prototype.getProviderAtIndex=function(t){if(0==t)return this.provider0;if(1==t)return this.provider1;if(2==t)return this.provider2;if(3==t)return this.provider3;if(4==t)return this.provider4;if(5==t)return this.provider5;if(6==t)return this.provider6;if(7==t)return this.provider7;if(8==t)return this.provider8;if(9==t)return this.provider9;throw new s.OutOfBoundsError(t)},t.prototype.createInjectorStrategy=function(t){return new m(t,this)},t}();e.ReflectiveProtoInjectorInlineStrategy=d;var v=function(){function t(t,e){this.providers=e;var n=e.length;this.keyIds=i.ListWrapper.createFixedSize(n);for(var r=0;n>r;r++)this.keyIds[r]=e[r].key.id}return t.prototype.getProviderAtIndex=function(t){if(0>t||t>=this.providers.length)throw new s.OutOfBoundsError(t);return this.providers[t]},t.prototype.createInjectorStrategy=function(t){return new g(this,t)},t}();e.ReflectiveProtoInjectorDynamicStrategy=v;var y=function(){function t(t){this.numberOfProviders=t.length,this._strategy=t.length>h?new v(this,t):new d(this,t)}return t.fromResolvedProviders=function(e){return new t(e)},t.prototype.getProviderAtIndex=function(t){return this._strategy.getProviderAtIndex(t);
                +},t}();e.ReflectiveProtoInjector=y;var m=function(){function t(t,e){this.injector=t,this.protoStrategy=e,this.obj0=f,this.obj1=f,this.obj2=f,this.obj3=f,this.obj4=f,this.obj5=f,this.obj6=f,this.obj7=f,this.obj8=f,this.obj9=f}return t.prototype.resetConstructionCounter=function(){this.injector._constructionCounter=0},t.prototype.instantiateProvider=function(t){return this.injector._new(t)},t.prototype.getObjByKeyId=function(t){var e=this.protoStrategy,n=this.injector;return e.keyId0===t?(this.obj0===f&&(this.obj0=n._new(e.provider0)),this.obj0):e.keyId1===t?(this.obj1===f&&(this.obj1=n._new(e.provider1)),this.obj1):e.keyId2===t?(this.obj2===f&&(this.obj2=n._new(e.provider2)),this.obj2):e.keyId3===t?(this.obj3===f&&(this.obj3=n._new(e.provider3)),this.obj3):e.keyId4===t?(this.obj4===f&&(this.obj4=n._new(e.provider4)),this.obj4):e.keyId5===t?(this.obj5===f&&(this.obj5=n._new(e.provider5)),this.obj5):e.keyId6===t?(this.obj6===f&&(this.obj6=n._new(e.provider6)),this.obj6):e.keyId7===t?(this.obj7===f&&(this.obj7=n._new(e.provider7)),this.obj7):e.keyId8===t?(this.obj8===f&&(this.obj8=n._new(e.provider8)),this.obj8):e.keyId9===t?(this.obj9===f&&(this.obj9=n._new(e.provider9)),this.obj9):f},t.prototype.getObjAtIndex=function(t){if(0==t)return this.obj0;if(1==t)return this.obj1;if(2==t)return this.obj2;if(3==t)return this.obj3;if(4==t)return this.obj4;if(5==t)return this.obj5;if(6==t)return this.obj6;if(7==t)return this.obj7;if(8==t)return this.obj8;if(9==t)return this.obj9;throw new s.OutOfBoundsError(t)},t.prototype.getMaxNumberOfObjects=function(){return h},t}();e.ReflectiveInjectorInlineStrategy=m;var g=function(){function t(t,e){this.protoStrategy=t,this.injector=e,this.objs=i.ListWrapper.createFixedSize(t.providers.length),i.ListWrapper.fill(this.objs,f)}return t.prototype.resetConstructionCounter=function(){this.injector._constructionCounter=0},t.prototype.instantiateProvider=function(t){return this.injector._new(t)},t.prototype.getObjByKeyId=function(t){for(var e=this.protoStrategy,n=0;n<e.keyIds.length;n++)if(e.keyIds[n]===t)return this.objs[n]===f&&(this.objs[n]=this.injector._new(e.providers[n])),this.objs[n];return f},t.prototype.getObjAtIndex=function(t){if(0>t||t>=this.objs.length)throw new s.OutOfBoundsError(t);return this.objs[t]},t.prototype.getMaxNumberOfObjects=function(){return this.objs.length},t}();e.ReflectiveInjectorDynamicStrategy=g;var _=function(){function t(){}return t.resolve=function(t){return o.resolveReflectiveProviders(t)},t.resolveAndCreate=function(e,n){void 0===n&&(n=null);var r=t.resolve(e);return t.fromResolvedProviders(r,n)},t.fromResolvedProviders=function(t,e){return void 0===e&&(e=null),new b(y.fromResolvedProviders(t),e)},t.fromResolvedBindings=function(e){return t.fromResolvedProviders(e)},Object.defineProperty(t.prototype,"parent",{get:function(){return u.unimplemented()},enumerable:!0,configurable:!0}),t.prototype.debugContext=function(){return null},t.prototype.resolveAndCreateChild=function(t){return u.unimplemented()},t.prototype.createChildFromResolved=function(t){return u.unimplemented()},t.prototype.resolveAndInstantiate=function(t){return u.unimplemented()},t.prototype.instantiateResolved=function(t){return u.unimplemented()},t}();e.ReflectiveInjector=_;var b=function(){function t(t,e,n){void 0===e&&(e=null),void 0===n&&(n=null),this._debugContext=n,this._constructionCounter=0,this._proto=t,this._parent=e,this._strategy=t._strategy.createInjectorStrategy(this)}return t.prototype.debugContext=function(){return this._debugContext()},t.prototype.get=function(t,e){return void 0===e&&(e=l.THROW_IF_NOT_FOUND),this._getByKey(c.ReflectiveKey.get(t),null,null,e)},t.prototype.getAt=function(t){return this._strategy.getObjAtIndex(t)},Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"internalStrategy",{get:function(){return this._strategy},enumerable:!0,configurable:!0}),t.prototype.resolveAndCreateChild=function(t){var e=_.resolve(t);return this.createChildFromResolved(e)},t.prototype.createChildFromResolved=function(e){var n=new y(e),r=new t(n);return r._parent=this,r},t.prototype.resolveAndInstantiate=function(t){return this.instantiateResolved(_.resolve([t])[0])},t.prototype.instantiateResolved=function(t){return this._instantiateProvider(t)},t.prototype._new=function(t){if(this._constructionCounter++>this._strategy.getMaxNumberOfObjects())throw new s.CyclicDependencyError(this,t.key);return this._instantiateProvider(t)},t.prototype._instantiateProvider=function(t){if(t.multiProvider){for(var e=i.ListWrapper.createFixedSize(t.resolvedFactories.length),n=0;n<t.resolvedFactories.length;++n)e[n]=this._instantiate(t,t.resolvedFactories[n]);return e}return this._instantiate(t,t.resolvedFactories[0])},t.prototype._instantiate=function(t,e){var n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_,b,P,E,w,C=e.factory,R=e.dependencies,S=R.length;try{n=S>0?this._getByReflectiveDependency(t,R[0]):null,r=S>1?this._getByReflectiveDependency(t,R[1]):null,i=S>2?this._getByReflectiveDependency(t,R[2]):null,o=S>3?this._getByReflectiveDependency(t,R[3]):null,a=S>4?this._getByReflectiveDependency(t,R[4]):null,c=S>5?this._getByReflectiveDependency(t,R[5]):null,p=S>6?this._getByReflectiveDependency(t,R[6]):null,l=S>7?this._getByReflectiveDependency(t,R[7]):null,h=S>8?this._getByReflectiveDependency(t,R[8]):null,f=S>9?this._getByReflectiveDependency(t,R[9]):null,d=S>10?this._getByReflectiveDependency(t,R[10]):null,v=S>11?this._getByReflectiveDependency(t,R[11]):null,y=S>12?this._getByReflectiveDependency(t,R[12]):null,m=S>13?this._getByReflectiveDependency(t,R[13]):null,g=S>14?this._getByReflectiveDependency(t,R[14]):null,_=S>15?this._getByReflectiveDependency(t,R[15]):null,b=S>16?this._getByReflectiveDependency(t,R[16]):null,P=S>17?this._getByReflectiveDependency(t,R[17]):null,E=S>18?this._getByReflectiveDependency(t,R[18]):null,w=S>19?this._getByReflectiveDependency(t,R[19]):null}catch(O){throw(O instanceof s.AbstractProviderError||O instanceof s.InstantiationError)&&O.addKey(this,t.key),O}var T;try{switch(S){case 0:T=C();break;case 1:T=C(n);break;case 2:T=C(n,r);break;case 3:T=C(n,r,i);break;case 4:T=C(n,r,i,o);break;case 5:T=C(n,r,i,o,a);break;case 6:T=C(n,r,i,o,a,c);break;case 7:T=C(n,r,i,o,a,c,p);break;case 8:T=C(n,r,i,o,a,c,p,l);break;case 9:T=C(n,r,i,o,a,c,p,l,h);break;case 10:T=C(n,r,i,o,a,c,p,l,h,f);break;case 11:T=C(n,r,i,o,a,c,p,l,h,f,d);break;case 12:T=C(n,r,i,o,a,c,p,l,h,f,d,v);break;case 13:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y);break;case 14:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m);break;case 15:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g);break;case 16:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_);break;case 17:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_,b);break;case 18:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_,b,P);break;case 19:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_,b,P,E);break;case 20:T=C(n,r,i,o,a,c,p,l,h,f,d,v,y,m,g,_,b,P,E,w);break;default:throw new u.BaseException("Cannot instantiate '"+t.key.displayName+"' because it has more than 20 dependencies")}}catch(O){throw new s.InstantiationError(this,O,O.stack,t.key)}return T},t.prototype._getByReflectiveDependency=function(t,e){return this._getByKey(e.key,e.lowerBoundVisibility,e.upperBoundVisibility,e.optional?null:l.THROW_IF_NOT_FOUND)},t.prototype._getByKey=function(t,e,n,r){return t===P?this:n instanceof p.SelfMetadata?this._getByKeySelf(t,r):this._getByKeyDefault(t,r,e)},t.prototype._throwOrNull=function(t,e){if(e!==l.THROW_IF_NOT_FOUND)return e;throw new s.NoProviderError(this,t)},t.prototype._getByKeySelf=function(t,e){var n=this._strategy.getObjByKeyId(t.id);return n!==f?n:this._throwOrNull(t,e)},t.prototype._getByKeyDefault=function(e,n,r){var i;for(i=r instanceof p.SkipSelfMetadata?this._parent:this;i instanceof t;){var o=i,s=o._strategy.getObjByKeyId(e.id);if(s!==f)return s;i=o._parent}return null!==i?i.get(e.token,n):this._throwOrNull(e,n)},Object.defineProperty(t.prototype,"displayName",{get:function(){return"ReflectiveInjector(providers: ["+r(this,function(t){return' "'+t.key.displayName+'" '}).join(", ")+"])"},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return this.displayName},t}();e.ReflectiveInjector_=b;var P=c.ReflectiveKey.get(l.Injector)},function(t,e,n){"use strict";function r(t){var e,n;if(h.isPresent(t.useClass)){var r=g.resolveForwardRef(t.useClass);e=d.reflector.factory(r),n=c(r)}else h.isPresent(t.useExisting)?(e=function(t){return t},n=[b.fromKey(v.ReflectiveKey.get(t.useExisting))]):h.isPresent(t.useFactory)?(e=t.useFactory,n=u(t.useFactory,t.dependencies)):(e=function(){return t.useValue},n=P);return new w(e,n)}function i(t){return new E(v.ReflectiveKey.get(t.token),[r(t)],t.multi)}function o(t){var e=a(t,[]),n=e.map(i);return f.MapWrapper.values(s(n,new Map))}function s(t,e){for(var n=0;n<t.length;n++){var r=t[n],i=e.get(r.key.id);if(h.isPresent(i)){if(r.multiProvider!==i.multiProvider)throw new m.MixingMultiProvidersWithRegularProvidersError(i,r);if(r.multiProvider)for(var o=0;o<r.resolvedFactories.length;o++)i.resolvedFactories.push(r.resolvedFactories[o]);else e.set(r.key.id,r)}else{var s;s=r.multiProvider?new E(r.key,f.ListWrapper.clone(r.resolvedFactories),r.multiProvider):r,e.set(r.key.id,s)}}return e}function a(t,e){return t.forEach(function(t){if(t instanceof h.Type)e.push(_.provide(t,{useClass:t}));else if(t instanceof _.Provider)e.push(t);else{if(!(t instanceof Array))throw t instanceof _.ProviderBuilder?new m.InvalidProviderError(t.token):new m.InvalidProviderError(t);a(t,e)}}),e}function u(t,e){if(h.isBlank(e))return c(t);var n=e.map(function(t){return[t]});return e.map(function(e){return p(t,e,n)})}function c(t){var e=d.reflector.parameters(t);if(h.isBlank(e))return[];if(e.some(h.isBlank))throw new m.NoAnnotationError(t,e);return e.map(function(n){return p(t,n,e)})}function p(t,e,n){var r=[],i=null,o=!1;if(!h.isArray(e))return e instanceof y.InjectMetadata?l(e.token,o,null,null,r):l(e,o,null,null,r);for(var s=null,a=null,u=0;u<e.length;++u){var c=e[u];c instanceof h.Type?i=c:c instanceof y.InjectMetadata?i=c.token:c instanceof y.OptionalMetadata?o=!0:c instanceof y.SelfMetadata?a=c:c instanceof y.HostMetadata?a=c:c instanceof y.SkipSelfMetadata?s=c:c instanceof y.DependencyMetadata&&(h.isPresent(c.token)&&(i=c.token),r.push(c))}if(i=g.resolveForwardRef(i),h.isPresent(i))return l(i,o,s,a,r);throw new m.NoAnnotationError(t,n)}function l(t,e,n,r,i){return new b(v.ReflectiveKey.get(t),e,n,r,i)}var h=n(5),f=n(15),d=n(18),v=n(22),y=n(7),m=n(23),g=n(10),_=n(24),b=function(){function t(t,e,n,r,i){this.key=t,this.optional=e,this.lowerBoundVisibility=n,this.upperBoundVisibility=r,this.properties=i}return t.fromKey=function(e){return new t(e,!1,null,null,[])},t}();e.ReflectiveDependency=b;var P=h.CONST_EXPR([]),E=function(){function t(t,e,n){this.key=t,this.resolvedFactories=e,this.multiProvider=n}return Object.defineProperty(t.prototype,"resolvedFactory",{get:function(){return this.resolvedFactories[0]},enumerable:!0,configurable:!0}),t}();e.ResolvedReflectiveProvider_=E;var w=function(){function t(t,e){this.factory=t,this.dependencies=e}return t}();e.ResolvedReflectiveFactory=w,e.resolveReflectiveFactory=r,e.resolveReflectiveProvider=i,e.resolveReflectiveProviders=o,e.mergeResolvedReflectiveProviders=s,e.constructDependencies=u},function(t,e,n){"use strict";var r=n(19),i=n(19);e.Reflector=i.Reflector,e.ReflectionInfo=i.ReflectionInfo;var o=n(21);e.reflector=new r.Reflector(new o.ReflectionCapabilities)},function(t,e,n){"use strict";function r(t,e){a.StringMapWrapper.forEach(e,function(e,n){return t.set(n,e)})}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=n(5),s=n(12),a=n(15),u=n(20),c=function(){function t(t,e,n,r,i){this.annotations=t,this.parameters=e,this.factory=n,this.interfaces=r,this.propMetadata=i}return t}();e.ReflectionInfo=c;var p=function(t){function e(e){t.call(this),this._injectableInfo=new a.Map,this._getters=new a.Map,this._setters=new a.Map,this._methods=new a.Map,this._usedKeys=null,this.reflectionCapabilities=e}return i(e,t),e.prototype.isReflectionEnabled=function(){return this.reflectionCapabilities.isReflectionEnabled()},e.prototype.trackUsage=function(){this._usedKeys=new a.Set},e.prototype.listUnusedKeys=function(){var t=this;if(null==this._usedKeys)throw new s.BaseException("Usage tracking is disabled");var e=a.MapWrapper.keys(this._injectableInfo);return e.filter(function(e){return!a.SetWrapper.has(t._usedKeys,e)})},e.prototype.registerFunction=function(t,e){this._injectableInfo.set(t,e)},e.prototype.registerType=function(t,e){this._injectableInfo.set(t,e)},e.prototype.registerGetters=function(t){r(this._getters,t)},e.prototype.registerSetters=function(t){r(this._setters,t)},e.prototype.registerMethods=function(t){r(this._methods,t)},e.prototype.factory=function(t){if(this._containsReflectionInfo(t)){var e=this._getReflectionInfo(t).factory;return o.isPresent(e)?e:null}return this.reflectionCapabilities.factory(t)},e.prototype.parameters=function(t){if(this._injectableInfo.has(t)){var e=this._getReflectionInfo(t).parameters;return o.isPresent(e)?e:[]}return this.reflectionCapabilities.parameters(t)},e.prototype.annotations=function(t){if(this._injectableInfo.has(t)){var e=this._getReflectionInfo(t).annotations;return o.isPresent(e)?e:[]}return this.reflectionCapabilities.annotations(t)},e.prototype.propMetadata=function(t){if(this._injectableInfo.has(t)){var e=this._getReflectionInfo(t).propMetadata;return o.isPresent(e)?e:{}}return this.reflectionCapabilities.propMetadata(t)},e.prototype.interfaces=function(t){if(this._injectableInfo.has(t)){var e=this._getReflectionInfo(t).interfaces;return o.isPresent(e)?e:[]}return this.reflectionCapabilities.interfaces(t)},e.prototype.getter=function(t){return this._getters.has(t)?this._getters.get(t):this.reflectionCapabilities.getter(t)},e.prototype.setter=function(t){return this._setters.has(t)?this._setters.get(t):this.reflectionCapabilities.setter(t)},e.prototype.method=function(t){return this._methods.has(t)?this._methods.get(t):this.reflectionCapabilities.method(t)},e.prototype._getReflectionInfo=function(t){return o.isPresent(this._usedKeys)&&this._usedKeys.add(t),this._injectableInfo.get(t)},e.prototype._containsReflectionInfo=function(t){return this._injectableInfo.has(t)},e.prototype.importUri=function(t){return this.reflectionCapabilities.importUri(t)},e}(u.ReflectorReader);e.Reflector=p},function(t,e){"use strict";var n=function(){function t(){}return t}();e.ReflectorReader=n},function(t,e,n){"use strict";var r=n(5),i=n(12),o=function(){function t(t){this._reflect=r.isPresent(t)?t:r.global.Reflect}return t.prototype.isReflectionEnabled=function(){return!0},t.prototype.factory=function(t){switch(t.length){case 0:return function(){return new t};case 1:return function(e){return new t(e)};case 2:return function(e,n){return new t(e,n)};case 3:return function(e,n,r){return new t(e,n,r)};case 4:return function(e,n,r,i){return new t(e,n,r,i)};case 5:return function(e,n,r,i,o){return new t(e,n,r,i,o)};case 6:return function(e,n,r,i,o,s){return new t(e,n,r,i,o,s)};case 7:return function(e,n,r,i,o,s,a){return new t(e,n,r,i,o,s,a)};case 8:return function(e,n,r,i,o,s,a,u){return new t(e,n,r,i,o,s,a,u)};case 9:return function(e,n,r,i,o,s,a,u,c){return new t(e,n,r,i,o,s,a,u,c)};case 10:return function(e,n,r,i,o,s,a,u,c,p){return new t(e,n,r,i,o,s,a,u,c,p)};case 11:return function(e,n,r,i,o,s,a,u,c,p,l){return new t(e,n,r,i,o,s,a,u,c,p,l)};case 12:return function(e,n,r,i,o,s,a,u,c,p,l,h){return new t(e,n,r,i,o,s,a,u,c,p,l,h)};case 13:return function(e,n,r,i,o,s,a,u,c,p,l,h,f){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f)};case 14:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d)};case 15:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v)};case 16:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y)};case 17:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m)};case 18:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g)};case 19:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g,_){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g,_)};case 20:return function(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g,_,b){return new t(e,n,r,i,o,s,a,u,c,p,l,h,f,d,v,y,m,g,_,b)}}throw new Error("Cannot create a factory for '"+r.stringify(t)+"' because its constructor has more than 20 arguments")},t.prototype._zipTypesAndAnnotations=function(t,e){var n;n="undefined"==typeof t?new Array(e.length):new Array(t.length);for(var i=0;i<n.length;i++)"undefined"==typeof t?n[i]=[]:t[i]!=Object?n[i]=[t[i]]:n[i]=[],r.isPresent(e)&&r.isPresent(e[i])&&(n[i]=n[i].concat(e[i]));return n},t.prototype.parameters=function(t){if(r.isPresent(t.parameters))return t.parameters;if(r.isPresent(this._reflect)&&r.isPresent(this._reflect.getMetadata)){var e=this._reflect.getMetadata("parameters",t),n=this._reflect.getMetadata("design:paramtypes",t);if(r.isPresent(n)||r.isPresent(e))return this._zipTypesAndAnnotations(n,e)}var i=new Array(t.length);return i.fill(void 0),i},t.prototype.annotations=function(t){if(r.isPresent(t.annotations)){var e=t.annotations;return r.isFunction(e)&&e.annotations&&(e=e.annotations),e}if(r.isPresent(this._reflect)&&r.isPresent(this._reflect.getMetadata)){var e=this._reflect.getMetadata("annotations",t);if(r.isPresent(e))return e}return[]},t.prototype.propMetadata=function(t){if(r.isPresent(t.propMetadata)){var e=t.propMetadata;return r.isFunction(e)&&e.propMetadata&&(e=e.propMetadata),e}if(r.isPresent(this._reflect)&&r.isPresent(this._reflect.getMetadata)){var e=this._reflect.getMetadata("propMetadata",t);if(r.isPresent(e))return e}return{}},t.prototype.interfaces=function(t){throw new i.BaseException("JavaScript does not support interfaces")},t.prototype.getter=function(t){return new Function("o","return o."+t+";")},t.prototype.setter=function(t){return new Function("o","v","return o."+t+" = v;")},t.prototype.method=function(t){var e="if (!o."+t+") throw new Error('\""+t+"\" is undefined');\n        return o."+t+".apply(o, args);";return new Function("o","args",e)},t.prototype.importUri=function(t){return"./"+r.stringify(t)},t}();e.ReflectionCapabilities=o},function(t,e,n){"use strict";var r=n(5),i=n(12),o=n(10),s=function(){function t(t,e){if(this.token=t,this.id=e,r.isBlank(t))throw new i.BaseException("Token must be defined!")}return Object.defineProperty(t.prototype,"displayName",{get:function(){return r.stringify(this.token)},enumerable:!0,configurable:!0}),t.get=function(t){return u.get(o.resolveForwardRef(t))},Object.defineProperty(t,"numberOfKeys",{get:function(){return u.numberOfKeys},enumerable:!0,configurable:!0}),t}();e.ReflectiveKey=s;var a=function(){function t(){this._allKeys=new Map}return t.prototype.get=function(t){if(t instanceof s)return t;if(this._allKeys.has(t))return this._allKeys.get(t);var e=new s(t,s.numberOfKeys);return this._allKeys.set(t,e),e},Object.defineProperty(t.prototype,"numberOfKeys",{get:function(){return this._allKeys.size},enumerable:!0,configurable:!0}),t}();e.KeyRegistry=a;var u=new a},function(t,e,n){"use strict";function r(t){for(var e=[],n=0;n<t.length;++n){if(s.ListWrapper.contains(e,t[n]))return e.push(t[n]),e;e.push(t[n])}return e}function i(t){if(t.length>1){var e=r(s.ListWrapper.reversed(t)),n=e.map(function(t){return a.stringify(t.token)});return" ("+n.join(" -> ")+")"}return""}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=n(15),a=n(5),u=n(12),c=function(t){function e(e,n,r){t.call(this,"DI Exception"),this.keys=[n],this.injectors=[e],this.constructResolvingMessage=r,this.message=this.constructResolvingMessage(this.keys)}return o(e,t),e.prototype.addKey=function(t,e){this.injectors.push(t),this.keys.push(e),this.message=this.constructResolvingMessage(this.keys)},Object.defineProperty(e.prototype,"context",{get:function(){return this.injectors[this.injectors.length-1].debugContext()},enumerable:!0,configurable:!0}),e}(u.BaseException);e.AbstractProviderError=c;var p=function(t){function e(e,n){t.call(this,e,n,function(t){var e=a.stringify(s.ListWrapper.first(t).token);return"No provider for "+e+"!"+i(t)})}return o(e,t),e}(c);e.NoProviderError=p;var l=function(t){function e(e,n){t.call(this,e,n,function(t){return"Cannot instantiate cyclic dependency!"+i(t)})}return o(e,t),e}(c);e.CyclicDependencyError=l;var h=function(t){function e(e,n,r,i){t.call(this,"DI Exception",n,r,null),this.keys=[i],this.injectors=[e]}return o(e,t),e.prototype.addKey=function(t,e){this.injectors.push(t),this.keys.push(e)},Object.defineProperty(e.prototype,"wrapperMessage",{get:function(){var t=a.stringify(s.ListWrapper.first(this.keys).token);return"Error during instantiation of "+t+"!"+i(this.keys)+"."},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"causeKey",{get:function(){return this.keys[0]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"context",{get:function(){return this.injectors[this.injectors.length-1].debugContext()},enumerable:!0,configurable:!0}),e}(u.WrappedException);e.InstantiationError=h;var f=function(t){function e(e){t.call(this,"Invalid provider - only instances of Provider and Type are allowed, got: "+e.toString())}return o(e,t),e}(u.BaseException);e.InvalidProviderError=f;var d=function(t){function e(n,r){t.call(this,e._genMessage(n,r))}return o(e,t),e._genMessage=function(t,e){for(var n=[],r=0,i=e.length;i>r;r++){var o=e[r];a.isBlank(o)||0==o.length?n.push("?"):n.push(o.map(a.stringify).join(" "))}return"Cannot resolve all parameters for '"+a.stringify(t)+"'("+n.join(", ")+"). Make sure that all the parameters are decorated with Inject or have valid type annotations and that '"+a.stringify(t)+"' is decorated with Injectable."},e}(u.BaseException);e.NoAnnotationError=d;var v=function(t){function e(e){t.call(this,"Index "+e+" is out-of-bounds.")}return o(e,t),e}(u.BaseException);e.OutOfBoundsError=v;var y=function(t){function e(e,n){t.call(this,"Cannot mix multi providers and regular providers, got: "+e.toString()+" "+n.toString())}return o(e,t),e}(u.BaseException);e.MixingMultiProvidersWithRegularProvidersError=y},function(t,e,n){"use strict";function r(t){return new h(t)}function i(t,e){var n=e.useClass,r=e.useValue,i=e.useExisting,o=e.useFactory,s=e.deps,a=e.multi;return new p(t,{useClass:n,useValue:r,useExisting:i,useFactory:o,deps:s,multi:a})}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},a=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},u=n(5),c=n(12),p=function(){function t(t,e){var n=e.useClass,r=e.useValue,i=e.useExisting,o=e.useFactory,s=e.deps,a=e.multi;this.token=t,this.useClass=n,this.useValue=r,this.useExisting=i,this.useFactory=o,this.dependencies=s,this._multi=a}return Object.defineProperty(t.prototype,"multi",{get:function(){return u.normalizeBool(this._multi)},enumerable:!0,configurable:!0}),t=s([u.CONST(),a("design:paramtypes",[Object,Object])],t)}();e.Provider=p;var l=function(t){function e(e,n){var r=n.toClass,i=n.toValue,o=n.toAlias,s=n.toFactory,a=n.deps,u=n.multi;t.call(this,e,{useClass:r,useValue:i,useExisting:o,useFactory:s,deps:a,multi:u})}return o(e,t),Object.defineProperty(e.prototype,"toClass",{get:function(){return this.useClass},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"toAlias",{get:function(){return this.useExisting},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"toFactory",{get:function(){return this.useFactory},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"toValue",{get:function(){return this.useValue},enumerable:!0,configurable:!0}),e=s([u.CONST(),a("design:paramtypes",[Object,Object])],e)}(p);e.Binding=l,e.bind=r;var h=function(){function t(t){this.token=t}return t.prototype.toClass=function(t){if(!u.isType(t))throw new c.BaseException('Trying to create a class provider but "'+u.stringify(t)+'" is not a class!');return new p(this.token,{useClass:t})},t.prototype.toValue=function(t){return new p(this.token,{useValue:t})},t.prototype.toAlias=function(t){if(u.isBlank(t))throw new c.BaseException("Can not alias "+u.stringify(this.token)+" to a blank value!");return new p(this.token,{useExisting:t})},t.prototype.toFactory=function(t,e){if(!u.isFunction(t))throw new c.BaseException('Trying to create a factory provider but "'+u.stringify(t)+'" is not a function!');return new p(this.token,{useFactory:t,deps:e})},t}();e.ProviderBuilder=h,e.provide=i},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=function(){function t(t){this._desc=t}return t.prototype.toString=function(){return"Token "+this._desc},t=r([o.CONST(),i("design:paramtypes",[String])],t)}();e.OpaqueToken=s},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(7),u=n(27),c=function(t){function e(e){var n=void 0===e?{}:e,r=n.selector,i=n.inputs,o=n.outputs,s=n.properties,a=n.events,u=n.host,c=n.bindings,p=n.providers,l=n.exportAs,h=n.queries;t.call(this),this.selector=r,this._inputs=i,this._properties=s,this._outputs=o,this._events=a,this.host=u,this.exportAs=l,this.queries=h,this._providers=p,this._bindings=c}return r(e,t),Object.defineProperty(e.prototype,"inputs",{get:function(){return s.isPresent(this._properties)&&this._properties.length>0?this._properties:this._inputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"properties",{get:function(){return this.inputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputs",{get:function(){return s.isPresent(this._events)&&this._events.length>0?this._events:this._outputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"events",{get:function(){return this.outputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"providers",{get:function(){return s.isPresent(this._bindings)&&this._bindings.length>0?this._bindings:this._providers},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"bindings",{get:function(){return this.providers},enumerable:!0,configurable:!0}),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(a.InjectableMetadata);e.DirectiveMetadata=c;var p=function(t){function e(e){var n=void 0===e?{}:e,r=n.selector,i=n.inputs,o=n.outputs,s=n.properties,a=n.events,c=n.host,p=n.exportAs,l=n.moduleId,h=n.bindings,f=n.providers,d=n.viewBindings,v=n.viewProviders,y=n.changeDetection,m=void 0===y?u.ChangeDetectionStrategy.Default:y,g=n.queries,_=n.templateUrl,b=n.template,P=n.styleUrls,E=n.styles,w=n.directives,C=n.pipes,R=n.encapsulation;t.call(this,{selector:r,inputs:i,outputs:o,properties:s,events:a,host:c,exportAs:p,bindings:h,providers:f,queries:g}),this.changeDetection=m,this._viewProviders=v,this._viewBindings=d,this.templateUrl=_,this.template=b,this.styleUrls=P,this.styles=E,this.directives=w,this.pipes=C,this.encapsulation=R,this.moduleId=l}return r(e,t),Object.defineProperty(e.prototype,"viewProviders",{get:function(){return s.isPresent(this._viewBindings)&&this._viewBindings.length>0?this._viewBindings:this._viewProviders},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"viewBindings",{get:function(){return this.viewProviders},enumerable:!0,configurable:!0}),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(c);e.ComponentMetadata=p;var l=function(t){function e(e){var n=e.name,r=e.pure;t.call(this),this.name=n,this._pure=r}return r(e,t),Object.defineProperty(e.prototype,"pure",{get:function(){return s.isPresent(this._pure)?this._pure:!0},enumerable:!0,configurable:!0}),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(a.InjectableMetadata);e.PipeMetadata=l;var h=function(){function t(t){this.bindingPropertyName=t}return t=i([s.CONST(),o("design:paramtypes",[String])],t)}();e.InputMetadata=h;var f=function(){function t(t){this.bindingPropertyName=t}return t=i([s.CONST(),o("design:paramtypes",[String])],t)}();e.OutputMetadata=f;var d=function(){function t(t){this.hostPropertyName=t}return t=i([s.CONST(),o("design:paramtypes",[String])],t)}();e.HostBindingMetadata=d;var v=function(){function t(t,e){this.eventName=t,this.args=e}return t=i([s.CONST(),o("design:paramtypes",[String,Array])],t)}();e.HostListenerMetadata=v},function(t,e,n){"use strict";var r=n(28);e.ChangeDetectionStrategy=r.ChangeDetectionStrategy,e.ChangeDetectorRef=r.ChangeDetectorRef,e.WrappedValue=r.WrappedValue,e.SimpleChange=r.SimpleChange,e.IterableDiffers=r.IterableDiffers,e.KeyValueDiffers=r.KeyValueDiffers,e.CollectionChangeRecord=r.CollectionChangeRecord,e.KeyValueChangeRecord=r.KeyValueChangeRecord},function(t,e,n){"use strict";var r=n(29),i=n(30),o=n(31),s=n(32),a=n(5),u=n(32);e.DefaultKeyValueDifferFactory=u.DefaultKeyValueDifferFactory,e.KeyValueChangeRecord=u.KeyValueChangeRecord;var c=n(30);e.DefaultIterableDifferFactory=c.DefaultIterableDifferFactory,e.CollectionChangeRecord=c.CollectionChangeRecord;var p=n(33);e.ChangeDetectionStrategy=p.ChangeDetectionStrategy,e.CHANGE_DETECTION_STRATEGY_VALUES=p.CHANGE_DETECTION_STRATEGY_VALUES,e.ChangeDetectorState=p.ChangeDetectorState,e.CHANGE_DETECTOR_STATE_VALUES=p.CHANGE_DETECTOR_STATE_VALUES,e.isDefaultChangeDetectionStrategy=p.isDefaultChangeDetectionStrategy;var l=n(34);e.ChangeDetectorRef=l.ChangeDetectorRef;var h=n(29);e.IterableDiffers=h.IterableDiffers;var f=n(31);e.KeyValueDiffers=f.KeyValueDiffers;var d=n(35);e.WrappedValue=d.WrappedValue,e.ValueUnwrapper=d.ValueUnwrapper,e.SimpleChange=d.SimpleChange,e.devModeEqual=d.devModeEqual,e.looseIdentical=d.looseIdentical,e.uninitialized=d.uninitialized,e.keyValDiff=a.CONST_EXPR([a.CONST_EXPR(new s.DefaultKeyValueDifferFactory)]),e.iterableDiff=a.CONST_EXPR([a.CONST_EXPR(new i.DefaultIterableDifferFactory)]),e.defaultIterableDiffers=a.CONST_EXPR(new r.IterableDiffers(e.iterableDiff)),e.defaultKeyValueDiffers=a.CONST_EXPR(new o.KeyValueDiffers(e.keyValDiff))},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);
                +return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(12),a=n(15),u=n(6),c=function(){function t(t){this.factories=t}return t.create=function(e,n){if(o.isPresent(n)){var r=a.ListWrapper.clone(n.factories);return e=e.concat(r),new t(e)}return new t(e)},t.extend=function(e){return new u.Provider(t,{useFactory:function(n){if(o.isBlank(n))throw new s.BaseException("Cannot extend IterableDiffers without a parent injector");return t.create(e,n)},deps:[[t,new u.SkipSelfMetadata,new u.OptionalMetadata]]})},t.prototype.find=function(t){var e=this.factories.find(function(e){return e.supports(t)});if(o.isPresent(e))return e;throw new s.BaseException("Cannot find a differ supporting object '"+t+"' of type '"+o.getTypeNameForDebugging(t)+"'")},t=r([o.CONST(),i("design:paramtypes",[Array])],t)}();e.IterableDiffers=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(12),a=n(15),u=n(5),c=function(){function t(){}return t.prototype.supports=function(t){return a.isListLikeIterable(t)},t.prototype.create=function(t,e){return new l(e)},t=r([o.CONST(),i("design:paramtypes",[])],t)}();e.DefaultIterableDifferFactory=c;var p=function(t,e){return e},l=function(){function t(t){this._trackByFn=t,this._length=null,this._collection=null,this._linkedRecords=null,this._unlinkedRecords=null,this._previousItHead=null,this._itHead=null,this._itTail=null,this._additionsHead=null,this._additionsTail=null,this._movesHead=null,this._movesTail=null,this._removalsHead=null,this._removalsTail=null,this._identityChangesHead=null,this._identityChangesTail=null,this._trackByFn=u.isPresent(this._trackByFn)?this._trackByFn:p}return Object.defineProperty(t.prototype,"collection",{get:function(){return this._collection},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"length",{get:function(){return this._length},enumerable:!0,configurable:!0}),t.prototype.forEachItem=function(t){var e;for(e=this._itHead;null!==e;e=e._next)t(e)},t.prototype.forEachPreviousItem=function(t){var e;for(e=this._previousItHead;null!==e;e=e._nextPrevious)t(e)},t.prototype.forEachAddedItem=function(t){var e;for(e=this._additionsHead;null!==e;e=e._nextAdded)t(e)},t.prototype.forEachMovedItem=function(t){var e;for(e=this._movesHead;null!==e;e=e._nextMoved)t(e)},t.prototype.forEachRemovedItem=function(t){var e;for(e=this._removalsHead;null!==e;e=e._nextRemoved)t(e)},t.prototype.forEachIdentityChange=function(t){var e;for(e=this._identityChangesHead;null!==e;e=e._nextIdentityChange)t(e)},t.prototype.diff=function(t){if(u.isBlank(t)&&(t=[]),!a.isListLikeIterable(t))throw new s.BaseException("Error trying to diff '"+t+"'");return this.check(t)?this:null},t.prototype.onDestroy=function(){},t.prototype.check=function(t){var e=this;this._reset();var n,r,i,o=this._itHead,s=!1;if(u.isArray(t)){var c=t;for(this._length=t.length,n=0;n<this._length;n++)r=c[n],i=this._trackByFn(n,r),null!==o&&u.looseIdentical(o.trackById,i)?(s&&(o=this._verifyReinsertion(o,r,i,n)),u.looseIdentical(o.item,r)||this._addIdentityChange(o,r)):(o=this._mismatch(o,r,i,n),s=!0),o=o._next}else n=0,a.iterateListLike(t,function(t){i=e._trackByFn(n,t),null!==o&&u.looseIdentical(o.trackById,i)?(s&&(o=e._verifyReinsertion(o,t,i,n)),u.looseIdentical(o.item,t)||e._addIdentityChange(o,t)):(o=e._mismatch(o,t,i,n),s=!0),o=o._next,n++}),this._length=n;return this._truncate(o),this._collection=t,this.isDirty},Object.defineProperty(t.prototype,"isDirty",{get:function(){return null!==this._additionsHead||null!==this._movesHead||null!==this._removalsHead||null!==this._identityChangesHead},enumerable:!0,configurable:!0}),t.prototype._reset=function(){if(this.isDirty){var t,e;for(t=this._previousItHead=this._itHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._additionsHead;null!==t;t=t._nextAdded)t.previousIndex=t.currentIndex;for(this._additionsHead=this._additionsTail=null,t=this._movesHead;null!==t;t=e)t.previousIndex=t.currentIndex,e=t._nextMoved;this._movesHead=this._movesTail=null,this._removalsHead=this._removalsTail=null,this._identityChangesHead=this._identityChangesTail=null}},t.prototype._mismatch=function(t,e,n,r){var i;return null===t?i=this._itTail:(i=t._prev,this._remove(t)),t=null===this._linkedRecords?null:this._linkedRecords.get(n,r),null!==t?(u.looseIdentical(t.item,e)||this._addIdentityChange(t,e),this._moveAfter(t,i,r)):(t=null===this._unlinkedRecords?null:this._unlinkedRecords.get(n),null!==t?(u.looseIdentical(t.item,e)||this._addIdentityChange(t,e),this._reinsertAfter(t,i,r)):t=this._addAfter(new h(e,n),i,r)),t},t.prototype._verifyReinsertion=function(t,e,n,r){var i=null===this._unlinkedRecords?null:this._unlinkedRecords.get(n);return null!==i?t=this._reinsertAfter(i,t._prev,r):t.currentIndex!=r&&(t.currentIndex=r,this._addToMoves(t,r)),t},t.prototype._truncate=function(t){for(;null!==t;){var e=t._next;this._addToRemovals(this._unlink(t)),t=e}null!==this._unlinkedRecords&&this._unlinkedRecords.clear(),null!==this._additionsTail&&(this._additionsTail._nextAdded=null),null!==this._movesTail&&(this._movesTail._nextMoved=null),null!==this._itTail&&(this._itTail._next=null),null!==this._removalsTail&&(this._removalsTail._nextRemoved=null),null!==this._identityChangesTail&&(this._identityChangesTail._nextIdentityChange=null)},t.prototype._reinsertAfter=function(t,e,n){null!==this._unlinkedRecords&&this._unlinkedRecords.remove(t);var r=t._prevRemoved,i=t._nextRemoved;return null===r?this._removalsHead=i:r._nextRemoved=i,null===i?this._removalsTail=r:i._prevRemoved=r,this._insertAfter(t,e,n),this._addToMoves(t,n),t},t.prototype._moveAfter=function(t,e,n){return this._unlink(t),this._insertAfter(t,e,n),this._addToMoves(t,n),t},t.prototype._addAfter=function(t,e,n){return this._insertAfter(t,e,n),null===this._additionsTail?this._additionsTail=this._additionsHead=t:this._additionsTail=this._additionsTail._nextAdded=t,t},t.prototype._insertAfter=function(t,e,n){var r=null===e?this._itHead:e._next;return t._next=r,t._prev=e,null===r?this._itTail=t:r._prev=t,null===e?this._itHead=t:e._next=t,null===this._linkedRecords&&(this._linkedRecords=new d),this._linkedRecords.put(t),t.currentIndex=n,t},t.prototype._remove=function(t){return this._addToRemovals(this._unlink(t))},t.prototype._unlink=function(t){null!==this._linkedRecords&&this._linkedRecords.remove(t);var e=t._prev,n=t._next;return null===e?this._itHead=n:e._next=n,null===n?this._itTail=e:n._prev=e,t},t.prototype._addToMoves=function(t,e){return t.previousIndex===e?t:(null===this._movesTail?this._movesTail=this._movesHead=t:this._movesTail=this._movesTail._nextMoved=t,t)},t.prototype._addToRemovals=function(t){return null===this._unlinkedRecords&&(this._unlinkedRecords=new d),this._unlinkedRecords.put(t),t.currentIndex=null,t._nextRemoved=null,null===this._removalsTail?(this._removalsTail=this._removalsHead=t,t._prevRemoved=null):(t._prevRemoved=this._removalsTail,this._removalsTail=this._removalsTail._nextRemoved=t),t},t.prototype._addIdentityChange=function(t,e){return t.item=e,null===this._identityChangesTail?this._identityChangesTail=this._identityChangesHead=t:this._identityChangesTail=this._identityChangesTail._nextIdentityChange=t,t},t.prototype.toString=function(){var t=[];this.forEachItem(function(e){return t.push(e)});var e=[];this.forEachPreviousItem(function(t){return e.push(t)});var n=[];this.forEachAddedItem(function(t){return n.push(t)});var r=[];this.forEachMovedItem(function(t){return r.push(t)});var i=[];this.forEachRemovedItem(function(t){return i.push(t)});var o=[];return this.forEachIdentityChange(function(t){return o.push(t)}),"collection: "+t.join(", ")+"\nprevious: "+e.join(", ")+"\nadditions: "+n.join(", ")+"\nmoves: "+r.join(", ")+"\nremovals: "+i.join(", ")+"\nidentityChanges: "+o.join(", ")+"\n"},t}();e.DefaultIterableDiffer=l;var h=function(){function t(t,e){this.item=t,this.trackById=e,this.currentIndex=null,this.previousIndex=null,this._nextPrevious=null,this._prev=null,this._next=null,this._prevDup=null,this._nextDup=null,this._prevRemoved=null,this._nextRemoved=null,this._nextAdded=null,this._nextMoved=null,this._nextIdentityChange=null}return t.prototype.toString=function(){return this.previousIndex===this.currentIndex?u.stringify(this.item):u.stringify(this.item)+"["+u.stringify(this.previousIndex)+"->"+u.stringify(this.currentIndex)+"]"},t}();e.CollectionChangeRecord=h;var f=function(){function t(){this._head=null,this._tail=null}return t.prototype.add=function(t){null===this._head?(this._head=this._tail=t,t._nextDup=null,t._prevDup=null):(this._tail._nextDup=t,t._prevDup=this._tail,t._nextDup=null,this._tail=t)},t.prototype.get=function(t,e){var n;for(n=this._head;null!==n;n=n._nextDup)if((null===e||e<n.currentIndex)&&u.looseIdentical(n.trackById,t))return n;return null},t.prototype.remove=function(t){var e=t._prevDup,n=t._nextDup;return null===e?this._head=n:e._nextDup=n,null===n?this._tail=e:n._prevDup=e,null===this._head},t}(),d=function(){function t(){this.map=new Map}return t.prototype.put=function(t){var e=u.getMapKey(t.trackById),n=this.map.get(e);u.isPresent(n)||(n=new f,this.map.set(e,n)),n.add(t)},t.prototype.get=function(t,e){void 0===e&&(e=null);var n=u.getMapKey(t),r=this.map.get(n);return u.isBlank(r)?null:r.get(t,e)},t.prototype.remove=function(t){var e=u.getMapKey(t.trackById),n=this.map.get(e);return n.remove(t)&&this.map["delete"](e),t},Object.defineProperty(t.prototype,"isEmpty",{get:function(){return 0===this.map.size},enumerable:!0,configurable:!0}),t.prototype.clear=function(){this.map.clear()},t.prototype.toString=function(){return"_DuplicateMap("+u.stringify(this.map)+")"},t}()},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(12),a=n(15),u=n(6),c=function(){function t(t){this.factories=t}return t.create=function(e,n){if(o.isPresent(n)){var r=a.ListWrapper.clone(n.factories);return e=e.concat(r),new t(e)}return new t(e)},t.extend=function(e){return new u.Provider(t,{useFactory:function(n){if(o.isBlank(n))throw new s.BaseException("Cannot extend KeyValueDiffers without a parent injector");return t.create(e,n)},deps:[[t,new u.SkipSelfMetadata,new u.OptionalMetadata]]})},t.prototype.find=function(t){var e=this.factories.find(function(e){return e.supports(t)});if(o.isPresent(e))return e;throw new s.BaseException("Cannot find a differ supporting object '"+t+"'")},t=r([o.CONST(),i("design:paramtypes",[Array])],t)}();e.KeyValueDiffers=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(15),s=n(5),a=n(12),u=function(){function t(){}return t.prototype.supports=function(t){return t instanceof Map||s.isJsObject(t)},t.prototype.create=function(t){return new c},t=r([s.CONST(),i("design:paramtypes",[])],t)}();e.DefaultKeyValueDifferFactory=u;var c=function(){function t(){this._records=new Map,this._mapHead=null,this._previousMapHead=null,this._changesHead=null,this._changesTail=null,this._additionsHead=null,this._additionsTail=null,this._removalsHead=null,this._removalsTail=null}return Object.defineProperty(t.prototype,"isDirty",{get:function(){return null!==this._additionsHead||null!==this._changesHead||null!==this._removalsHead},enumerable:!0,configurable:!0}),t.prototype.forEachItem=function(t){var e;for(e=this._mapHead;null!==e;e=e._next)t(e)},t.prototype.forEachPreviousItem=function(t){var e;for(e=this._previousMapHead;null!==e;e=e._nextPrevious)t(e)},t.prototype.forEachChangedItem=function(t){var e;for(e=this._changesHead;null!==e;e=e._nextChanged)t(e)},t.prototype.forEachAddedItem=function(t){var e;for(e=this._additionsHead;null!==e;e=e._nextAdded)t(e)},t.prototype.forEachRemovedItem=function(t){var e;for(e=this._removalsHead;null!==e;e=e._nextRemoved)t(e)},t.prototype.diff=function(t){if(s.isBlank(t)&&(t=o.MapWrapper.createFromPairs([])),!(t instanceof Map||s.isJsObject(t)))throw new a.BaseException("Error trying to diff '"+t+"'");return this.check(t)?this:null},t.prototype.onDestroy=function(){},t.prototype.check=function(t){var e=this;this._reset();var n=this._records,r=this._mapHead,i=null,o=null,a=!1;return this._forEach(t,function(t,u){var c;null!==r&&u===r.key?(c=r,s.looseIdentical(t,r.currentValue)||(r.previousValue=r.currentValue,r.currentValue=t,e._addToChanges(r))):(a=!0,null!==r&&(r._next=null,e._removeFromSeq(i,r),e._addToRemovals(r)),n.has(u)?c=n.get(u):(c=new p(u),n.set(u,c),c.currentValue=t,e._addToAdditions(c))),a&&(e._isInRemovals(c)&&e._removeFromRemovals(c),null==o?e._mapHead=c:o._next=c),i=r,o=c,r=null===r?null:r._next}),this._truncate(i,r),this.isDirty},t.prototype._reset=function(){if(this.isDirty){var t;for(t=this._previousMapHead=this._mapHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._changesHead;null!==t;t=t._nextChanged)t.previousValue=t.currentValue;for(t=this._additionsHead;null!=t;t=t._nextAdded)t.previousValue=t.currentValue;this._changesHead=this._changesTail=null,this._additionsHead=this._additionsTail=null,this._removalsHead=this._removalsTail=null}},t.prototype._truncate=function(t,e){for(;null!==e;){null===t?this._mapHead=null:t._next=null;var n=e._next;this._addToRemovals(e),t=e,e=n}for(var r=this._removalsHead;null!==r;r=r._nextRemoved)r.previousValue=r.currentValue,r.currentValue=null,this._records["delete"](r.key)},t.prototype._isInRemovals=function(t){return t===this._removalsHead||null!==t._nextRemoved||null!==t._prevRemoved},t.prototype._addToRemovals=function(t){null===this._removalsHead?this._removalsHead=this._removalsTail=t:(this._removalsTail._nextRemoved=t,t._prevRemoved=this._removalsTail,this._removalsTail=t)},t.prototype._removeFromSeq=function(t,e){var n=e._next;null===t?this._mapHead=n:t._next=n},t.prototype._removeFromRemovals=function(t){var e=t._prevRemoved,n=t._nextRemoved;null===e?this._removalsHead=n:e._nextRemoved=n,null===n?this._removalsTail=e:n._prevRemoved=e,t._prevRemoved=t._nextRemoved=null},t.prototype._addToAdditions=function(t){null===this._additionsHead?this._additionsHead=this._additionsTail=t:(this._additionsTail._nextAdded=t,this._additionsTail=t)},t.prototype._addToChanges=function(t){null===this._changesHead?this._changesHead=this._changesTail=t:(this._changesTail._nextChanged=t,this._changesTail=t)},t.prototype.toString=function(){var t,e=[],n=[],r=[],i=[],o=[];for(t=this._mapHead;null!==t;t=t._next)e.push(s.stringify(t));for(t=this._previousMapHead;null!==t;t=t._nextPrevious)n.push(s.stringify(t));for(t=this._changesHead;null!==t;t=t._nextChanged)r.push(s.stringify(t));for(t=this._additionsHead;null!==t;t=t._nextAdded)i.push(s.stringify(t));for(t=this._removalsHead;null!==t;t=t._nextRemoved)o.push(s.stringify(t));return"map: "+e.join(", ")+"\nprevious: "+n.join(", ")+"\nadditions: "+i.join(", ")+"\nchanges: "+r.join(", ")+"\nremovals: "+o.join(", ")+"\n"},t.prototype._forEach=function(t,e){t instanceof Map?t.forEach(e):o.StringMapWrapper.forEach(t,e)},t}();e.DefaultKeyValueDiffer=c;var p=function(){function t(t){this.key=t,this.previousValue=null,this.currentValue=null,this._nextPrevious=null,this._next=null,this._nextAdded=null,this._nextRemoved=null,this._prevRemoved=null,this._nextChanged=null}return t.prototype.toString=function(){return s.looseIdentical(this.previousValue,this.currentValue)?s.stringify(this.key):s.stringify(this.key)+"["+s.stringify(this.previousValue)+"->"+s.stringify(this.currentValue)+"]"},t}();e.KeyValueChangeRecord=p},function(t,e,n){"use strict";function r(t){return i.isBlank(t)||t===s.Default}var i=n(5);!function(t){t[t.NeverChecked=0]="NeverChecked",t[t.CheckedBefore=1]="CheckedBefore",t[t.Errored=2]="Errored"}(e.ChangeDetectorState||(e.ChangeDetectorState={}));var o=e.ChangeDetectorState;!function(t){t[t.CheckOnce=0]="CheckOnce",t[t.Checked=1]="Checked",t[t.CheckAlways=2]="CheckAlways",t[t.Detached=3]="Detached",t[t.OnPush=4]="OnPush",t[t.Default=5]="Default"}(e.ChangeDetectionStrategy||(e.ChangeDetectionStrategy={}));var s=e.ChangeDetectionStrategy;e.CHANGE_DETECTION_STRATEGY_VALUES=[s.CheckOnce,s.Checked,s.CheckAlways,s.Detached,s.OnPush,s.Default],e.CHANGE_DETECTOR_STATE_VALUES=[o.NeverChecked,o.CheckedBefore,o.Errored],e.isDefaultChangeDetectionStrategy=r},function(t,e){"use strict";var n=function(){function t(){}return t}();e.ChangeDetectorRef=n},function(t,e,n){"use strict";function r(t,e){return o.isListLikeIterable(t)&&o.isListLikeIterable(e)?o.areIterablesEqual(t,e,r):o.isListLikeIterable(t)||i.isPrimitive(t)||o.isListLikeIterable(e)||i.isPrimitive(e)?i.looseIdentical(t,e):!0}var i=n(5),o=n(15),s=n(5);e.looseIdentical=s.looseIdentical,e.uninitialized=i.CONST_EXPR(new Object),e.devModeEqual=r;var a=function(){function t(t){this.wrapped=t}return t.wrap=function(e){return new t(e)},t}();e.WrappedValue=a;var u=function(){function t(){this.hasWrappedValue=!1}return t.prototype.unwrap=function(t){return t instanceof a?(this.hasWrappedValue=!0,t.wrapped):t},t.prototype.reset=function(){this.hasWrappedValue=!1},t}();e.ValueUnwrapper=u;var c=function(){function t(t,e){this.previousValue=t,this.currentValue=e}return t.prototype.isFirstChange=function(){return this.previousValue===e.uninitialized},t}();e.SimpleChange=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5);!function(t){t[t.Emulated=0]="Emulated",t[t.Native=1]="Native",t[t.None=2]="None"}(e.ViewEncapsulation||(e.ViewEncapsulation={}));var s=e.ViewEncapsulation;e.VIEW_ENCAPSULATION_VALUES=[s.Emulated,s.Native,s.None];var a=function(){function t(t){var e=void 0===t?{}:t,n=e.templateUrl,r=e.template,i=e.directives,o=e.pipes,s=e.encapsulation,a=e.styles,u=e.styleUrls;this.templateUrl=n,this.template=r,this.styleUrls=u,this.styles=a,this.directives=i,this.pipes=o,this.encapsulation=s}return t=r([o.CONST(),i("design:paramtypes",[Object])],t)}();e.ViewMetadata=a},function(t,e,n){"use strict";var r=n(9);e.Class=r.Class},function(t,e,n){"use strict";var r=n(5);e.enableProdMode=r.enableProdMode},function(t,e,n){"use strict";var r=n(5);e.Type=r.Type;var i=n(40);e.EventEmitter=i.EventEmitter;var o=n(12);e.WrappedException=o.WrappedException;var s=n(14);e.ExceptionHandler=s.ExceptionHandler},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(41);e.PromiseWrapper=o.PromiseWrapper,e.PromiseCompleter=o.PromiseCompleter;var s=n(42),a=n(43),u=n(58),c=n(42);e.Observable=c.Observable;var p=n(42);e.Subject=p.Subject;var l=function(){function t(){}return t.setTimeout=function(t,e){return i.global.setTimeout(t,e)},t.clearTimeout=function(t){i.global.clearTimeout(t)},t.setInterval=function(t,e){return i.global.setInterval(t,e)},t.clearInterval=function(t){i.global.clearInterval(t)},t}();e.TimerWrapper=l;var h=function(){function t(){}return t.subscribe=function(t,e,n,r){return void 0===r&&(r=function(){}),n="function"==typeof n&&n||i.noop,r="function"==typeof r&&r||i.noop,t.subscribe({next:e,error:n,complete:r})},t.isObservable=function(t){return!!t.subscribe},t.hasSubscribers=function(t){return t.observers.length>0},t.dispose=function(t){t.unsubscribe()},t.callNext=function(t,e){t.next(e)},t.callEmit=function(t,e){t.emit(e)},t.callError=function(t,e){t.error(e)},t.callComplete=function(t){t.complete()},t.fromPromise=function(t){return a.PromiseObservable.create(t)},t.toPromise=function(t){return u.toPromise.call(t)},t}();e.ObservableWrapper=h;var f=function(t){function e(e){void 0===e&&(e=!0),t.call(this),this._isAsync=e}return r(e,t),e.prototype.emit=function(e){t.prototype.next.call(this,e)},e.prototype.next=function(e){t.prototype.next.call(this,e)},e.prototype.subscribe=function(e,n,r){var i,o=function(t){return null},s=function(){return null};return e&&"object"==typeof e?(i=this._isAsync?function(t){setTimeout(function(){return e.next(t)})}:function(t){e.next(t)},e.error&&(o=this._isAsync?function(t){setTimeout(function(){return e.error(t)})}:function(t){e.error(t)}),e.complete&&(s=this._isAsync?function(){setTimeout(function(){return e.complete()})}:function(){e.complete()})):(i=this._isAsync?function(t){setTimeout(function(){return e(t)})}:function(t){e(t)},n&&(o=this._isAsync?function(t){setTimeout(function(){return n(t)})}:function(t){n(t)}),r&&(s=this._isAsync?function(){setTimeout(function(){return r()})}:function(){r()})),t.prototype.subscribe.call(this,i,o,s)},e}(s.Subject);e.EventEmitter=f},function(t,e){"use strict";var n=function(){function t(){var t=this;this.promise=new Promise(function(e,n){t.resolve=e,t.reject=n})}return t}();e.PromiseCompleter=n;var r=function(){function t(){}return t.resolve=function(t){return Promise.resolve(t)},t.reject=function(t,e){return Promise.reject(t)},t.catchError=function(t,e){return t["catch"](e)},t.all=function(t){return 0==t.length?Promise.resolve([]):Promise.all(t)},t.then=function(t,e,n){return t.then(e,n)},t.wrap=function(t){return new Promise(function(e,n){try{e(t())}catch(r){n(r)}})},t.scheduleMicrotask=function(e){t.then(t.resolve(null),e,function(t){})},t.isPromise=function(t){return t instanceof Promise},t.completer=function(){return new n},t}();e.PromiseWrapper=r},function(e,n){e.exports=t},function(t,e,n){"use strict";function r(t){var e=t.value,n=t.subscriber;n.isUnsubscribed||(n.next(e),n.complete())}function i(t){var e=t.err,n=t.subscriber;n.isUnsubscribed||n.error(e)}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=n(44),a=n(46),u=function(t){function e(e,n){void 0===n&&(n=null),t.call(this),this.promise=e,this.scheduler=n}return o(e,t),e.create=function(t,n){return void 0===n&&(n=null),new e(t,n)},e.prototype._subscribe=function(t){var e=this,n=this.promise,o=this.scheduler;if(null==o)this._isScalar?t.isUnsubscribed||(t.next(this.value),t.complete()):n.then(function(n){e.value=n,e._isScalar=!0,t.isUnsubscribed||(t.next(n),t.complete())},function(e){t.isUnsubscribed||t.error(e)}).then(null,function(t){s.root.setTimeout(function(){throw t})});else if(this._isScalar){if(!t.isUnsubscribed)return o.schedule(r,0,{value:this.value,subscriber:t})}else n.then(function(n){e.value=n,e._isScalar=!0,t.isUnsubscribed||t.add(o.schedule(r,0,{value:n,subscriber:t}))},function(e){t.isUnsubscribed||t.add(o.schedule(i,0,{err:e,subscriber:t}))}).then(null,function(t){s.root.setTimeout(function(){throw t})})},e}(a.Observable);e.PromiseObservable=u},function(t,e,n){(function(t,n){"use strict";var r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1};e.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof e]&&e&&!e.nodeType&&e,r[typeof t]&&t&&!t.nodeType&&t,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(e.root=i)}).call(e,n(45)(t),function(){return this}())},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var r=n(44),i=n(47),o=n(48),s=n(54),a=n(55),u=function(){function t(t){this._isScalar=!1,t&&(this._subscribe=t)}return t.prototype.lift=function(e){var n=new t;return n.source=this,n.operator=e,n},t.prototype.subscribe=function(t,e,n){var r=this.operator,i=o.toSubscriber(t,e,n);if(r?i.add(this._subscribe(r.call(i))):i.add(this._subscribe(i)),i.syncErrorThrowable&&(i.syncErrorThrowable=!1,i.syncErrorThrown))throw i.syncErrorValue;return i},t.prototype.forEach=function(t,e,n){if(n||(r.root.Rx&&r.root.Rx.config&&r.root.Rx.config.Promise?n=r.root.Rx.config.Promise:r.root.Promise&&(n=r.root.Promise)),!n)throw new Error("no Promise impl found");var i=this;return new n(function(n,r){i.subscribe(function(n){var i=s.tryCatch(t).call(e,n);i===a.errorObject&&r(a.errorObject.e)},r,n)})},t.prototype._subscribe=function(t){return this.source.subscribe(t)},t.prototype[i.SymbolShim.observable]=function(){return this},t.create=function(e){return new t(e)},t}();e.Observable=u},function(t,e,n){"use strict";function r(t){var e=o(t);return a(e,t),u(e),i(e),e}function i(t){t["for"]||(t["for"]=s)}function o(t){return t.Symbol||(t.Symbol=function(t){return"@@Symbol("+t+"):"+p++}),t.Symbol}function s(t){return"@@"+t}function a(t,e){if(!t.iterator)if("function"==typeof t["for"])t.iterator=t["for"]("iterator");else if(e.Set&&"function"==typeof(new e.Set)["@@iterator"])t.iterator="@@iterator";else if(e.Map)for(var n=Object.getOwnPropertyNames(e.Map.prototype),r=0;r<n.length;++r){var i=n[r];if("entries"!==i&&"size"!==i&&e.Map.prototype[i]===e.Map.prototype.entries){t.iterator=i;break}}else t.iterator="@@iterator"}function u(t){t.observable||("function"==typeof t["for"]?t.observable=t["for"]("observable"):t.observable="@@observable")}var c=n(44);e.polyfillSymbol=r,e.ensureFor=i;var p=0;e.ensureSymbol=o,e.symbolForPolyfill=s,e.ensureIterator=a,e.ensureObservable=u,e.SymbolShim=r(c.root)},function(t,e,n){"use strict";function r(t,e,n){if(t&&"object"==typeof t){if(t instanceof i.Subscriber)return t;if("function"==typeof t[o.rxSubscriber])return t[o.rxSubscriber]()}return new i.Subscriber(t,e,n)}var i=n(49),o=n(56);e.toSubscriber=r},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(50),o=n(51),s=n(56),a=n(57),u=function(t){function e(n,r,i){switch(t.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!n){this.destination=a.empty;break}if("object"==typeof n){n instanceof e?this.destination=n:(this.syncErrorThrowable=!0,this.destination=new c(this,n));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,n,r,i)}}return r(e,t),e.create=function(t,n,r){var i=new e(t,n,r);return i.syncErrorThrowable=!1,i},e.prototype.next=function(t){this.isStopped||this._next(t)},e.prototype.error=function(t){this.isStopped||(this.isStopped=!0,this._error(t))},e.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},e.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,t.prototype.unsubscribe.call(this))},e.prototype._next=function(t){this.destination.next(t)},e.prototype._error=function(t){this.destination.error(t),this.unsubscribe()},e.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},e.prototype[s.rxSubscriber]=function(){return this},e}(o.Subscription);e.Subscriber=u;var c=function(t){function e(e,n,r,o){t.call(this),this._parent=e;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete),this._context=a,this._next=s,this._error=r,this._complete=o}return r(e,t),e.prototype.next=function(t){if(!this.isStopped&&this._next){var e=this._parent;e.syncErrorThrowable?this.__tryOrSetError(e,this._next,t)&&this.unsubscribe():this.__tryOrUnsub(this._next,t)}},e.prototype.error=function(t){if(!this.isStopped){var e=this._parent;if(this._error)e.syncErrorThrowable?(this.__tryOrSetError(e,this._error,t),this.unsubscribe()):(this.__tryOrUnsub(this._error,t),this.unsubscribe());else{if(!e.syncErrorThrowable)throw this.unsubscribe(),t;e.syncErrorValue=t,e.syncErrorThrown=!0,this.unsubscribe()}}},e.prototype.complete=function(){if(!this.isStopped){var t=this._parent;this._complete?t.syncErrorThrowable?(this.__tryOrSetError(t,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},e.prototype.__tryOrUnsub=function(t,e){try{t.call(this._context,e)}catch(n){throw this.unsubscribe(),n}},e.prototype.__tryOrSetError=function(t,e,n){try{e.call(this._context,n)}catch(r){return t.syncErrorValue=r,t.syncErrorThrown=!0,!0}return!1},e.prototype._unsubscribe=function(){var t=this._parent;this._context=null,this._parent=null,t.unsubscribe()},e}(u)},function(t,e){"use strict";function n(t){return"function"==typeof t}e.isFunction=n},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(52),o=n(53),s=n(50),a=n(54),u=n(55),c=function(){function t(t){this.isUnsubscribed=!1,t&&(this._unsubscribe=t)}return t.prototype.unsubscribe=function(){var t,e=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,r=n._unsubscribe,c=n._subscriptions;if(this._subscriptions=null,s.isFunction(r)){var l=a.tryCatch(r).call(this);l===u.errorObject&&(e=!0,(t=t||[]).push(u.errorObject.e))}if(i.isArray(c))for(var h=-1,f=c.length;++h<f;){var d=c[h];if(o.isObject(d)){var l=a.tryCatch(d.unsubscribe).call(d);if(l===u.errorObject){e=!0,t=t||[];var v=u.errorObject.e;v instanceof p?t=t.concat(v.errors):t.push(v)}}}if(e)throw new p(t)}},t.prototype.add=function(e){if(e&&e!==this&&e!==t.EMPTY){var n=e;switch(typeof e){case"function":n=new t(e);case"object":if(n.isUnsubscribed||"function"!=typeof n.unsubscribe)break;this.isUnsubscribed?n.unsubscribe():(this._subscriptions||(this._subscriptions=[])).push(n);break;default:throw new Error("Unrecognized subscription "+e+" added to Subscription.")}}},t.prototype.remove=function(e){if(null!=e&&e!==this&&e!==t.EMPTY){var n=this._subscriptions;if(n){var r=n.indexOf(e);-1!==r&&n.splice(r,1)}}},t.EMPTY=function(t){return t.isUnsubscribed=!0,t}(new t),t}();e.Subscription=c;var p=function(t){function e(e){t.call(this,"unsubscriptoin error(s)"),this.errors=e,this.name="UnsubscriptionError"}return r(e,t),e}(Error);e.UnsubscriptionError=p},function(t,e){"use strict";e.isArray=Array.isArray||function(t){return t&&"number"==typeof t.length}},function(t,e){"use strict";function n(t){return null!=t&&"object"==typeof t}e.isObject=n},function(t,e,n){"use strict";function r(){try{return o.apply(this,arguments)}catch(t){return s.errorObject.e=t,s.errorObject}}function i(t){return o=t,r}var o,s=n(55);e.tryCatch=i},function(t,e){"use strict";e.errorObject={e:{}}},function(t,e,n){"use strict";var r=n(47);e.rxSubscriber=r.SymbolShim["for"]("rxSubscriber");
                +},function(t,e){"use strict";e.empty={isUnsubscribed:!0,next:function(t){},error:function(t){throw t},complete:function(){}}},function(t,n){t.exports=e},function(t,e,n){"use strict";function r(){return new f.NgZone({enableLongStackTrace:d.assertionsEnabled()})}function i(t){if(R)throw new P.BaseException("Already creating a platform...");if(d.isPresent(C)&&!C.disposed)throw new P.BaseException("There can be only one platform. Destroy the previous one to create a new one.");d.lockMode(),R=!0;try{C=t.get(S)}finally{R=!1}return C}function o(t){var e=a();if(d.isBlank(e))throw new P.BaseException("Not platform exists!");if(d.isPresent(e)&&d.isBlank(e.injector.get(t,null)))throw new P.BaseException("A platform with a different configuration has been created. Please destroy it first.");return e}function s(){d.isPresent(C)&&!C.disposed&&C.dispose()}function a(){return d.isPresent(C)&&!C.disposed?C:null}function u(t,e){var n=t.get(T);return n.bootstrap(e)}function c(t,e){var n=t.get(T);return n.run(function(){var r=t.get(b.ComponentResolver);return m.PromiseWrapper.all([r.resolveComponent(e),n.waitForAsyncInitializers()]).then(function(t){return n.bootstrap(t[0])})})}var p=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},l=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},h=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},f=n(60),d=n(5),v=n(6),y=n(62),m=n(40),g=n(15),_=n(63),b=n(64),P=n(12),E=n(75),w=n(71);e.createNgZone=r;var C,R=!1;e.createPlatform=i,e.assertPlatform=o,e.disposePlatform=s,e.getPlatform=a,e.coreBootstrap=u,e.coreLoadAndBootstrap=c;var S=function(){function t(){}return Object.defineProperty(t.prototype,"injector",{get:function(){throw P.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"disposed",{get:function(){throw P.unimplemented()},enumerable:!0,configurable:!0}),t}();e.PlatformRef=S;var O=function(t){function e(e){if(t.call(this),this._injector=e,this._applications=[],this._disposeListeners=[],this._disposed=!1,!R)throw new P.BaseException("Platforms have to be created via `createPlatform`!");var n=e.get(y.PLATFORM_INITIALIZER,null);d.isPresent(n)&&n.forEach(function(t){return t()})}return p(e,t),e.prototype.registerDisposeListener=function(t){this._disposeListeners.push(t)},Object.defineProperty(e.prototype,"injector",{get:function(){return this._injector},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"disposed",{get:function(){return this._disposed},enumerable:!0,configurable:!0}),e.prototype.addApplication=function(t){this._applications.push(t)},e.prototype.dispose=function(){g.ListWrapper.clone(this._applications).forEach(function(t){return t.dispose()}),this._disposeListeners.forEach(function(t){return t()}),this._disposed=!0},e.prototype._applicationDisposed=function(t){g.ListWrapper.remove(this._applications,t)},e=l([v.Injectable(),h("design:paramtypes",[v.Injector])],e)}(S);e.PlatformRef_=O;var T=function(){function t(){}return Object.defineProperty(t.prototype,"injector",{get:function(){return P.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"zone",{get:function(){return P.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"componentTypes",{get:function(){return P.unimplemented()},enumerable:!0,configurable:!0}),t}();e.ApplicationRef=T;var x=function(t){function e(e,n,r){var i=this;t.call(this),this._platform=e,this._zone=n,this._injector=r,this._bootstrapListeners=[],this._disposeListeners=[],this._rootComponents=[],this._rootComponentTypes=[],this._changeDetectorRefs=[],this._runningTick=!1,this._enforceNoNewChanges=!1;var o=r.get(f.NgZone);this._enforceNoNewChanges=d.assertionsEnabled(),o.run(function(){i._exceptionHandler=r.get(P.ExceptionHandler)}),this._asyncInitDonePromise=this.run(function(){var t,e=r.get(y.APP_INITIALIZER,null),n=[];if(d.isPresent(e))for(var o=0;o<e.length;o++){var s=e[o]();d.isPromise(s)&&n.push(s)}return n.length>0?(t=m.PromiseWrapper.all(n).then(function(t){return i._asyncInitDone=!0}),i._asyncInitDone=!1):(i._asyncInitDone=!0,t=m.PromiseWrapper.resolve(!0)),t}),m.ObservableWrapper.subscribe(o.onError,function(t){i._exceptionHandler.call(t.error,t.stackTrace)}),m.ObservableWrapper.subscribe(this._zone.onMicrotaskEmpty,function(t){i._zone.run(function(){i.tick()})})}return p(e,t),e.prototype.registerBootstrapListener=function(t){this._bootstrapListeners.push(t)},e.prototype.registerDisposeListener=function(t){this._disposeListeners.push(t)},e.prototype.registerChangeDetector=function(t){this._changeDetectorRefs.push(t)},e.prototype.unregisterChangeDetector=function(t){g.ListWrapper.remove(this._changeDetectorRefs,t)},e.prototype.waitForAsyncInitializers=function(){return this._asyncInitDonePromise},e.prototype.run=function(t){var e,n=this,r=this.injector.get(f.NgZone),i=m.PromiseWrapper.completer();return r.run(function(){try{e=t(),d.isPromise(e)&&m.PromiseWrapper.then(e,function(t){i.resolve(t)},function(t,e){i.reject(t,e),n._exceptionHandler.call(t,e)})}catch(r){throw n._exceptionHandler.call(r,r.stack),r}}),d.isPromise(e)?i.promise:e},e.prototype.bootstrap=function(t){var e=this;if(!this._asyncInitDone)throw new P.BaseException("Cannot bootstrap as there are still asynchronous initializers running. Wait for them using waitForAsyncInitializers().");return this.run(function(){e._rootComponentTypes.push(t.componentType);var n=t.create(e._injector,[],t.selector);n.onDestroy(function(){e._unloadComponent(n)});var r=n.injector.get(_.Testability,null);d.isPresent(r)&&n.injector.get(_.TestabilityRegistry).registerApplication(n.location.nativeElement,r),e._loadComponent(n);var i=e._injector.get(E.Console);return d.assertionsEnabled()&&i.log("Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode."),n})},e.prototype._loadComponent=function(t){this._changeDetectorRefs.push(t.changeDetectorRef),this.tick(),this._rootComponents.push(t),this._bootstrapListeners.forEach(function(e){return e(t)})},e.prototype._unloadComponent=function(t){g.ListWrapper.contains(this._rootComponents,t)&&(this.unregisterChangeDetector(t.changeDetectorRef),g.ListWrapper.remove(this._rootComponents,t))},Object.defineProperty(e.prototype,"injector",{get:function(){return this._injector},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),e.prototype.tick=function(){if(this._runningTick)throw new P.BaseException("ApplicationRef.tick is called recursively");var t=e._tickScope();try{this._runningTick=!0,this._changeDetectorRefs.forEach(function(t){return t.detectChanges()}),this._enforceNoNewChanges&&this._changeDetectorRefs.forEach(function(t){return t.checkNoChanges()})}finally{this._runningTick=!1,w.wtfLeave(t)}},e.prototype.dispose=function(){g.ListWrapper.clone(this._rootComponents).forEach(function(t){return t.destroy()}),this._disposeListeners.forEach(function(t){return t()}),this._platform._applicationDisposed(this)},Object.defineProperty(e.prototype,"componentTypes",{get:function(){return this._rootComponentTypes},enumerable:!0,configurable:!0}),e._tickScope=w.wtfCreateScope("ApplicationRef#tick()"),e=l([v.Injectable(),h("design:paramtypes",[O,f.NgZone,v.Injector])],e)}(T);e.ApplicationRef_=x,e.PLATFORM_CORE_PROVIDERS=d.CONST_EXPR([O,d.CONST_EXPR(new v.Provider(S,{useExisting:O}))]),e.APPLICATION_CORE_PROVIDERS=d.CONST_EXPR([d.CONST_EXPR(new v.Provider(f.NgZone,{useFactory:r,deps:d.CONST_EXPR([])})),x,d.CONST_EXPR(new v.Provider(T,{useExisting:x}))])},function(t,e,n){"use strict";var r=n(40),i=n(61),o=n(12),s=n(61);e.NgZoneError=s.NgZoneError;var a=function(){function t(t){var e=this,n=t.enableLongStackTrace,o=void 0===n?!1:n;this._hasPendingMicrotasks=!1,this._hasPendingMacrotasks=!1,this._isStable=!0,this._nesting=0,this._onUnstable=new r.EventEmitter(!1),this._onMicrotaskEmpty=new r.EventEmitter(!1),this._onStable=new r.EventEmitter(!1),this._onErrorEvents=new r.EventEmitter(!1),this._zoneImpl=new i.NgZoneImpl({trace:o,onEnter:function(){e._nesting++,e._isStable&&(e._isStable=!1,e._onUnstable.emit(null))},onLeave:function(){e._nesting--,e._checkStable()},setMicrotask:function(t){e._hasPendingMicrotasks=t,e._checkStable()},setMacrotask:function(t){e._hasPendingMacrotasks=t},onError:function(t){return e._onErrorEvents.emit(t)}})}return t.isInAngularZone=function(){return i.NgZoneImpl.isInAngularZone()},t.assertInAngularZone=function(){if(!i.NgZoneImpl.isInAngularZone())throw new o.BaseException("Expected to be in Angular Zone, but it is not!")},t.assertNotInAngularZone=function(){if(i.NgZoneImpl.isInAngularZone())throw new o.BaseException("Expected to not be in Angular Zone, but it is!")},t.prototype._checkStable=function(){var t=this;if(0==this._nesting&&!this._hasPendingMicrotasks&&!this._isStable)try{this._nesting++,this._onMicrotaskEmpty.emit(null)}finally{if(this._nesting--,!this._hasPendingMicrotasks)try{this.runOutsideAngular(function(){return t._onStable.emit(null)})}finally{this._isStable=!0}}},Object.defineProperty(t.prototype,"onUnstable",{get:function(){return this._onUnstable},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"onMicrotaskEmpty",{get:function(){return this._onMicrotaskEmpty},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"onStable",{get:function(){return this._onStable},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"onError",{get:function(){return this._onErrorEvents},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hasPendingMicrotasks",{get:function(){return this._hasPendingMicrotasks},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hasPendingMacrotasks",{get:function(){return this._hasPendingMacrotasks},enumerable:!0,configurable:!0}),t.prototype.run=function(t){return this._zoneImpl.runInner(t)},t.prototype.runGuarded=function(t){return this._zoneImpl.runInnerGuarded(t)},t.prototype.runOutsideAngular=function(t){return this._zoneImpl.runOuter(t)},t}();e.NgZone=a},function(t,e){"use strict";var n=function(){function t(t,e){this.error=t,this.stackTrace=e}return t}();e.NgZoneError=n;var r=function(){function t(t){var e=this,r=t.trace,i=t.onEnter,o=t.onLeave,s=t.setMicrotask,a=t.setMacrotask,u=t.onError;if(this.onEnter=i,this.onLeave=o,this.setMicrotask=s,this.setMacrotask=a,this.onError=u,!Zone)throw new Error("Angular2 needs to be run with Zone.js polyfill.");this.outer=this.inner=Zone.current,Zone.wtfZoneSpec&&(this.inner=this.inner.fork(Zone.wtfZoneSpec)),r&&Zone.longStackTraceZoneSpec&&(this.inner=this.inner.fork(Zone.longStackTraceZoneSpec)),this.inner=this.inner.fork({name:"angular",properties:{isAngularZone:!0},onInvokeTask:function(t,n,r,i,o,s){try{return e.onEnter(),t.invokeTask(r,i,o,s)}finally{e.onLeave()}},onInvoke:function(t,n,r,i,o,s,a){try{return e.onEnter(),t.invoke(r,i,o,s,a)}finally{e.onLeave()}},onHasTask:function(t,n,r,i){t.hasTask(r,i),n==r&&("microTask"==i.change?e.setMicrotask(i.microTask):"macroTask"==i.change&&e.setMacrotask(i.macroTask))},onHandleError:function(t,r,i,o){return t.handleError(i,o),e.onError(new n(o,o.stack)),!1}})}return t.isInAngularZone=function(){return Zone.current.get("isAngularZone")===!0},t.prototype.runInner=function(t){return this.inner.run(t)},t.prototype.runInnerGuarded=function(t){return this.inner.runGuarded(t)},t.prototype.runOuter=function(t){return this.outer.run(t)},t}();e.NgZoneImpl=r},function(t,e,n){"use strict";function r(){return""+i()+i()+i()}function i(){return s.StringWrapper.fromCharCode(97+s.Math.floor(25*s.Math.random()))}var o=n(6),s=n(5);e.APP_ID=s.CONST_EXPR(new o.OpaqueToken("AppId")),e.APP_ID_RANDOM_PROVIDER=s.CONST_EXPR(new o.Provider(e.APP_ID,{useFactory:r,deps:[]})),e.PLATFORM_INITIALIZER=s.CONST_EXPR(new o.OpaqueToken("Platform Initializer")),e.APP_INITIALIZER=s.CONST_EXPR(new o.OpaqueToken("Application Initializer")),e.PACKAGE_ROOT_URL=s.CONST_EXPR(new o.OpaqueToken("Application Packages Root URL"))},function(t,e,n){"use strict";function r(t){v=t}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(6),a=n(15),u=n(5),c=n(12),p=n(60),l=n(40),h=function(){function t(t){this._ngZone=t,this._pendingCount=0,this._isZoneStable=!0,this._didWork=!1,this._callbacks=[],this._watchAngularEvents()}return t.prototype._watchAngularEvents=function(){var t=this;l.ObservableWrapper.subscribe(this._ngZone.onUnstable,function(e){t._didWork=!0,t._isZoneStable=!1}),this._ngZone.runOutsideAngular(function(){l.ObservableWrapper.subscribe(t._ngZone.onStable,function(e){p.NgZone.assertNotInAngularZone(),u.scheduleMicroTask(function(){t._isZoneStable=!0,t._runCallbacksIfReady()})})})},t.prototype.increasePendingRequestCount=function(){return this._pendingCount+=1,this._didWork=!0,this._pendingCount},t.prototype.decreasePendingRequestCount=function(){if(this._pendingCount-=1,this._pendingCount<0)throw new c.BaseException("pending async requests below zero");return this._runCallbacksIfReady(),this._pendingCount},t.prototype.isStable=function(){return this._isZoneStable&&0==this._pendingCount&&!this._ngZone.hasPendingMacrotasks},t.prototype._runCallbacksIfReady=function(){var t=this;this.isStable()?u.scheduleMicroTask(function(){for(;0!==t._callbacks.length;)t._callbacks.pop()(t._didWork);t._didWork=!1}):this._didWork=!0},t.prototype.whenStable=function(t){this._callbacks.push(t),this._runCallbacksIfReady()},t.prototype.getPendingRequestCount=function(){return this._pendingCount},t.prototype.findBindings=function(t,e,n){return[]},t.prototype.findProviders=function(t,e,n){return[]},t=i([s.Injectable(),o("design:paramtypes",[p.NgZone])],t)}();e.Testability=h;var f=function(){function t(){this._applications=new a.Map,v.addToWindow(this)}return t.prototype.registerApplication=function(t,e){this._applications.set(t,e)},t.prototype.getTestability=function(t){return this._applications.get(t)},t.prototype.getAllTestabilities=function(){return a.MapWrapper.values(this._applications)},t.prototype.getAllRootElements=function(){return a.MapWrapper.keys(this._applications)},t.prototype.findTestabilityInTree=function(t,e){return void 0===e&&(e=!0),v.findTestabilityInTree(this,t,e)},t=i([s.Injectable(),o("design:paramtypes",[])],t)}();e.TestabilityRegistry=f;var d=function(){function t(){}return t.prototype.addToWindow=function(t){},t.prototype.findTestabilityInTree=function(t,e,n){return null},t=i([u.CONST(),o("design:paramtypes",[])],t)}();e.setTestabilityGetter=r;var v=u.CONST_EXPR(new d)},function(t,e,n){"use strict";function r(t){return t instanceof h.ComponentFactory}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},s=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},a=n(6),u=n(5),c=n(12),p=n(40),l=n(18),h=n(65),f=function(){function t(){}return t}();e.ComponentResolver=f;var d=function(t){function e(){t.apply(this,arguments)}return i(e,t),e.prototype.resolveComponent=function(t){var e=l.reflector.annotations(t),n=e.find(r);if(u.isBlank(n))throw new c.BaseException("No precompiled component "+u.stringify(t)+" found");return p.PromiseWrapper.resolve(n)},e.prototype.clearCache=function(){},e=o([a.Injectable(),s("design:paramtypes",[])],e)}(f);e.ReflectorComponentResolver=d},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(12),u=n(66),c=function(){function t(){}return Object.defineProperty(t.prototype,"location",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"instance",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hostView",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"changeDetectorRef",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"componentType",{get:function(){return a.unimplemented()},enumerable:!0,configurable:!0}),t}();e.ComponentRef=c;var p=function(t){function e(e,n){t.call(this),this._hostElement=e,this._componentType=n}return r(e,t),Object.defineProperty(e.prototype,"location",{get:function(){return this._hostElement.elementRef},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"injector",{get:function(){return this._hostElement.injector},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"instance",{get:function(){return this._hostElement.component},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"hostView",{get:function(){return this._hostElement.parentView.ref},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"changeDetectorRef",{get:function(){return this.hostView},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"componentType",{get:function(){return this._componentType},enumerable:!0,configurable:!0}),e.prototype.destroy=function(){this._hostElement.parentView.destroy()},e.prototype.onDestroy=function(t){this.hostView.onDestroy(t)},e}(c);e.ComponentRef_=p;var l=function(){function t(t,e,n){this.selector=t,this._viewFactory=e,this._componentType=n}return Object.defineProperty(t.prototype,"componentType",{get:function(){return this._componentType},enumerable:!0,configurable:!0}),t.prototype.create=function(t,e,n){void 0===e&&(e=null),void 0===n&&(n=null);var r=t.get(u.ViewUtils);s.isBlank(e)&&(e=[]);var i=this._viewFactory(r,t,null),o=i.create(e,n);return new p(o,this._componentType)},t=i([s.CONST(),o("design:paramtypes",[String,Function,s.Type])],t)}();e.ComponentFactory=l},function(t,e,n){"use strict";function r(t){return i(t,[])}function i(t,e){for(var n=0;n<t.length;n++){var r=t[n];if(r instanceof T.AppElement){var o=r;if(e.push(o.nativeElement),R.isPresent(o.nestedViews))for(var s=0;s<o.nestedViews.length;s++)i(o.nestedViews[s].rootNodesOrAppElements,e)}else e.push(r)}return e}function o(t,e){var n;if(R.isBlank(t))n=D;else if(t.length<e){var r=t.length;n=S.ListWrapper.createFixedSize(e);for(var i=0;e>i;i++)n[i]=r>i?t[i]:D}else n=t;return n}function s(t,e,n,r,i,o,s,u,c,p,l,h,f,d,v,y,m,g,_,b){switch(t){case 1:return e+a(n)+r;case 2:return e+a(n)+r+a(i)+o;case 3:return e+a(n)+r+a(i)+o+a(s)+u;case 4:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p;case 5:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p+a(l)+h;case 6:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p+a(l)+h+a(f)+d;case 7:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p+a(l)+h+a(f)+d+a(v)+y;case 8:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p+a(l)+h+a(f)+d+a(v)+y+a(m)+g;case 9:return e+a(n)+r+a(i)+o+a(s)+u+a(c)+p+a(l)+h+a(f)+d+a(v)+y+a(m)+g+a(_)+b;default:throw new O.BaseException("Does not support more than 9 expressions")}}function a(t){return null!=t?t.toString():""}function u(t,e,n){if(t){if(!A.devModeEqual(e,n))throw new x.ExpressionChangedAfterItHasBeenCheckedException(e,n,null);return!1}return!R.looseIdentical(e,n)}function c(t,e){if(t.length!=e.length)return!1;for(var n=0;n<t.length;++n)if(!R.looseIdentical(t[n],e[n]))return!1;return!0}function p(t,e){var n=S.StringMapWrapper.keys(t),r=S.StringMapWrapper.keys(e);if(n.length!=r.length)return!1;for(var i,o=0;o<n.length;o++)if(i=n[o],!R.looseIdentical(t[i],e[i]))return!1;return!0}function l(t,e){return t}function h(t){var e,n;return n=A.uninitialized,function(r){return R.looseIdentical(n,r)||(n=r,e=t(r)),e}}function f(t){var e,n,r;return n=r=A.uninitialized,function(i,o){return R.looseIdentical(n,i)&&R.looseIdentical(r,o)||(n=i,r=o,e=t(i,o)),e}}function d(t){var e,n,r,i;return n=r=i=A.uninitialized,function(o,s,a){return R.looseIdentical(n,o)&&R.looseIdentical(r,s)&&R.looseIdentical(i,a)||(n=o,r=s,i=a,e=t(o,s,a)),e}}function v(t){var e,n,r,i,o;return n=r=i=o=A.uninitialized,function(s,a,u,c){return R.looseIdentical(n,s)&&R.looseIdentical(r,a)&&R.looseIdentical(i,u)&&R.looseIdentical(o,c)||(n=s,r=a,i=u,o=c,e=t(s,a,u,c)),e}}function y(t){var e,n,r,i,o,s;return n=r=i=o=s=A.uninitialized,function(a,u,c,p,l){return R.looseIdentical(n,a)&&R.looseIdentical(r,u)&&R.looseIdentical(i,c)&&R.looseIdentical(o,p)&&R.looseIdentical(s,l)||(n=a,r=u,i=c,o=p,s=l,e=t(a,u,c,p,l)),e}}function m(t){var e,n,r,i,o,s,a;return n=r=i=o=s=a=A.uninitialized,function(u,c,p,l,h,f){return R.looseIdentical(n,u)&&R.looseIdentical(r,c)&&R.looseIdentical(i,p)&&R.looseIdentical(o,l)&&R.looseIdentical(s,h)&&R.looseIdentical(a,f)||(n=u,r=c,i=p,o=l,s=h,a=f,e=t(u,c,p,l,h,f)),e}}function g(t){var e,n,r,i,o,s,a,u;return n=r=i=o=s=a=u=A.uninitialized,function(c,p,l,h,f,d,v){return R.looseIdentical(n,c)&&R.looseIdentical(r,p)&&R.looseIdentical(i,l)&&R.looseIdentical(o,h)&&R.looseIdentical(s,f)&&R.looseIdentical(a,d)&&R.looseIdentical(u,v)||(n=c,r=p,i=l,o=h,s=f,a=d,u=v,e=t(c,p,l,h,f,d,v)),e}}function _(t){var e,n,r,i,o,s,a,u,c;return n=r=i=o=s=a=u=c=A.uninitialized,function(p,l,h,f,d,v,y,m){return R.looseIdentical(n,p)&&R.looseIdentical(r,l)&&R.looseIdentical(i,h)&&R.looseIdentical(o,f)&&R.looseIdentical(s,d)&&R.looseIdentical(a,v)&&R.looseIdentical(u,y)&&R.looseIdentical(c,m)||(n=p,r=l,i=h,o=f,s=d,a=v,u=y,c=m,e=t(p,l,h,f,d,v,y,m)),e}}function b(t){var e,n,r,i,o,s,a,u,c,p;return n=r=i=o=s=a=u=c=p=A.uninitialized,function(l,h,f,d,v,y,m,g,_){return R.looseIdentical(n,l)&&R.looseIdentical(r,h)&&R.looseIdentical(i,f)&&R.looseIdentical(o,d)&&R.looseIdentical(s,v)&&R.looseIdentical(a,y)&&R.looseIdentical(u,m)&&R.looseIdentical(c,g)&&R.looseIdentical(p,_)||(n=l,r=h,i=f,o=d,s=v,a=y,u=m,c=g,p=_,e=t(l,h,f,d,v,y,m,g,_)),e}}function P(t){var e,n,r,i,o,s,a,u,c,p,l;return n=r=i=o=s=a=u=c=p=l=A.uninitialized,function(h,f,d,v,y,m,g,_,b,P){return R.looseIdentical(n,h)&&R.looseIdentical(r,f)&&R.looseIdentical(i,d)&&R.looseIdentical(o,v)&&R.looseIdentical(s,y)&&R.looseIdentical(a,m)&&R.looseIdentical(u,g)&&R.looseIdentical(c,_)&&R.looseIdentical(p,b)&&R.looseIdentical(l,P)||(n=h,r=f,i=d,o=v,s=y,a=m,u=g,c=_,p=b,l=P,e=t(h,f,d,v,y,m,g,_,b,P)),e}}var E=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},w=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},C=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},R=n(5),S=n(15),O=n(12),T=n(67),x=n(73),A=n(28),I=n(6),M=n(74),k=n(62),N=function(){function t(t,e){this._renderer=t,this._appId=e,this._nextCompTypeId=0}return t.prototype.createRenderComponentType=function(t,e,n,r){return new M.RenderComponentType(this._appId+"-"+this._nextCompTypeId++,t,e,n,r)},t.prototype.renderComponent=function(t){return this._renderer.renderComponent(t)},t=E([I.Injectable(),C(1,I.Inject(k.APP_ID)),w("design:paramtypes",[M.RootRenderer,String])],t)}();e.ViewUtils=N,e.flattenNestedViewRenderNodes=r;var D=R.CONST_EXPR([]);e.ensureSlotCount=o,e.MAX_INTERPOLATION_VALUES=9,e.interpolate=s,e.checkBinding=u,e.arrayLooseIdentical=c,e.mapLooseIdentical=p,e.castByValue=l,e.pureProxy1=h,e.pureProxy2=f,e.pureProxy3=d,e.pureProxy4=v,e.pureProxy5=y,e.pureProxy6=m,e.pureProxy7=g,e.pureProxy8=_,e.pureProxy9=b,e.pureProxy10=P},function(t,e,n){"use strict";var r=n(5),i=n(15),o=n(12),s=n(68),a=n(69),u=n(70),c=function(){function t(t,e,n,r){this.index=t,this.parentIndex=e,this.parentView=n,this.nativeElement=r,this.nestedViews=null,this.componentView=null}return Object.defineProperty(t.prototype,"elementRef",{get:function(){return new a.ElementRef(this.nativeElement)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"vcRef",{get:function(){return new u.ViewContainerRef_(this)},enumerable:!0,configurable:!0}),t.prototype.initComponent=function(t,e,n){this.component=t,this.componentConstructorViewQueries=e,this.componentView=n},Object.defineProperty(t.prototype,"parentInjector",{get:function(){return this.parentView.injector(this.parentIndex)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return this.parentView.injector(this.index)},enumerable:!0,configurable:!0}),t.prototype.mapNestedViews=function(t,e){var n=[];return r.isPresent(this.nestedViews)&&this.nestedViews.forEach(function(r){r.clazz===t&&n.push(e(r))}),n},t.prototype.attachView=function(t,e){if(t.type===s.ViewType.COMPONENT)throw new o.BaseException("Component views can't be moved!");var n=this.nestedViews;null==n&&(n=[],this.nestedViews=n),i.ListWrapper.insert(n,e,t);var a;if(e>0){var u=n[e-1];a=u.lastRootNode}else a=this.nativeElement;r.isPresent(a)&&t.renderer.attachViewAfter(a,t.flatRootNodes),t.addToContentChildren(this)},t.prototype.detachView=function(t){var e=i.ListWrapper.removeAt(this.nestedViews,t);if(e.type===s.ViewType.COMPONENT)throw new o.BaseException("Component views can't be moved!");return e.renderer.detachView(e.flatRootNodes),e.removeFromContentChildren(this),e},t}();e.AppElement=c},function(t,e){"use strict";!function(t){t[t.HOST=0]="HOST",t[t.COMPONENT=1]="COMPONENT",t[t.EMBEDDED=2]="EMBEDDED"}(e.ViewType||(e.ViewType={}));e.ViewType},function(t,e){"use strict";var n=function(){function t(t){this.nativeElement=t}return t}();e.ElementRef=n},function(t,e,n){"use strict";var r=n(15),i=n(12),o=n(5),s=n(71),a=function(){function t(){}return Object.defineProperty(t.prototype,"element",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parentInjector",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"length",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),t}();e.ViewContainerRef=a;var u=function(){function t(t){this._element=t,this._createComponentInContainerScope=s.wtfCreateScope("ViewContainerRef#createComponent()"),this._insertScope=s.wtfCreateScope("ViewContainerRef#insert()"),this._removeScope=s.wtfCreateScope("ViewContainerRef#remove()"),this._detachScope=s.wtfCreateScope("ViewContainerRef#detach()")}return t.prototype.get=function(t){return this._element.nestedViews[t].ref},Object.defineProperty(t.prototype,"length",{get:function(){var t=this._element.nestedViews;return o.isPresent(t)?t.length:0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"element",{get:function(){return this._element.elementRef},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return this._element.injector},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parentInjector",{get:function(){return this._element.parentInjector},enumerable:!0,configurable:!0}),t.prototype.createEmbeddedView=function(t,e){void 0===e&&(e=-1);var n=t.createEmbeddedView();return this.insert(n,e),n},t.prototype.createComponent=function(t,e,n,r){void 0===e&&(e=-1),void 0===n&&(n=null),void 0===r&&(r=null);var i=this._createComponentInContainerScope(),a=o.isPresent(n)?n:this._element.parentInjector,u=t.create(a,r);return this.insert(u.hostView,e),s.wtfLeave(i,u)},t.prototype.insert=function(t,e){void 0===e&&(e=-1);var n=this._insertScope();-1==e&&(e=this.length);var r=t;return this._element.attachView(r.internalView,e),s.wtfLeave(n,r)},t.prototype.indexOf=function(t){return r.ListWrapper.indexOf(this._element.nestedViews,t.internalView)},t.prototype.remove=function(t){void 0===t&&(t=-1);var e=this._removeScope();-1==t&&(t=this.length-1);var n=this._element.detachView(t);n.destroy(),s.wtfLeave(e)},t.prototype.detach=function(t){void 0===t&&(t=-1);var e=this._detachScope();-1==t&&(t=this.length-1);var n=this._element.detachView(t);return s.wtfLeave(e,n.ref)},t.prototype.clear=function(){for(var t=this.length-1;t>=0;t--)this.remove(t)},t}();e.ViewContainerRef_=u},function(t,e,n){"use strict";function r(t,e){return null}var i=n(72);e.wtfEnabled=i.detectWTF(),e.wtfCreateScope=e.wtfEnabled?i.createScope:function(t,e){return r},e.wtfLeave=e.wtfEnabled?i.leave:function(t,e){return e},e.wtfStartTimeRange=e.wtfEnabled?i.startTimeRange:function(t,e){return null},e.wtfEndTimeRange=e.wtfEnabled?i.endTimeRange:function(t){return null}},function(t,e,n){"use strict";function r(){var t=p.global.wtf;return t&&(u=t.trace)?(c=u.events,!0):!1}function i(t,e){return void 0===e&&(e=null),c.createScope(t,e)}function o(t,e){return u.leaveScope(t,e),e}function s(t,e){return u.beginTimeRange(t,e)}function a(t){u.endTimeRange(t)}var u,c,p=n(5);e.detectWTF=r,e.createScope=i,e.leave=o,e.startTimeRange=s,e.endTimeRange=a},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(12),o=function(t){function e(e,n,r){t.call(this,"Expression has changed after it was checked. "+("Previous value: '"+e+"'. Current value: '"+n+"'"))}return r(e,t),e}(i.BaseException);e.ExpressionChangedAfterItHasBeenCheckedException=o;var s=function(t){function e(e,n,r){t.call(this,"Error in "+r.source,e,n,r)}return r(e,t),e}(i.WrappedException);e.ViewWrappedException=s;var a=function(t){function e(e){t.call(this,"Attempt to use a destroyed view: "+e)}return r(e,t),e}(i.BaseException);e.ViewDestroyedException=a},function(t,e,n){"use strict";var r=n(12),i=function(){function t(t,e,n,r,i){this.id=t,this.templateUrl=e,this.slotCount=n,this.encapsulation=r,this.styles=i}return t}();e.RenderComponentType=i;var o=function(){function t(){}return Object.defineProperty(t.prototype,"injector",{get:function(){return r.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"component",{get:function(){
                +return r.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"providerTokens",{get:function(){return r.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"locals",{get:function(){return r.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"source",{get:function(){return r.unimplemented()},enumerable:!0,configurable:!0}),t}();e.RenderDebugInfo=o;var s=function(){function t(){}return t}();e.Renderer=s;var a=function(){function t(){}return t}();e.RootRenderer=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(6),s=n(5),a=function(){function t(){}return t.prototype.log=function(t){s.print(t)},t=r([o.Injectable(),i("design:paramtypes",[])],t)}();e.Console=a},function(t,e,n){"use strict";var r=n(60);e.NgZone=r.NgZone,e.NgZoneError=r.NgZoneError},function(t,e,n){"use strict";var r=n(74);e.RootRenderer=r.RootRenderer,e.Renderer=r.Renderer,e.RenderComponentType=r.RenderComponentType},function(t,e,n){"use strict";var r=n(64);e.ComponentResolver=r.ComponentResolver;var i=n(79);e.QueryList=i.QueryList;var o=n(80);e.DynamicComponentLoader=o.DynamicComponentLoader;var s=n(69);e.ElementRef=s.ElementRef;var a=n(81);e.TemplateRef=a.TemplateRef;var u=n(82);e.EmbeddedViewRef=u.EmbeddedViewRef,e.ViewRef=u.ViewRef;var c=n(70);e.ViewContainerRef=c.ViewContainerRef;var p=n(65);e.ComponentRef=p.ComponentRef,e.ComponentFactory=p.ComponentFactory;var l=n(73);e.ExpressionChangedAfterItHasBeenCheckedException=l.ExpressionChangedAfterItHasBeenCheckedException},function(t,e,n){"use strict";var r=n(15),i=n(5),o=n(40),s=function(){function t(){this._dirty=!0,this._results=[],this._emitter=new o.EventEmitter}return Object.defineProperty(t.prototype,"changes",{get:function(){return this._emitter},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"length",{get:function(){return this._results.length},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"first",{get:function(){return r.ListWrapper.first(this._results)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"last",{get:function(){return r.ListWrapper.last(this._results)},enumerable:!0,configurable:!0}),t.prototype.map=function(t){return this._results.map(t)},t.prototype.filter=function(t){return this._results.filter(t)},t.prototype.reduce=function(t,e){return this._results.reduce(t,e)},t.prototype.forEach=function(t){this._results.forEach(t)},t.prototype.toArray=function(){return r.ListWrapper.clone(this._results)},t.prototype[i.getSymbolIterator()]=function(){return this._results[i.getSymbolIterator()]()},t.prototype.toString=function(){return this._results.toString()},t.prototype.reset=function(t){this._results=r.ListWrapper.flatten(t),this._dirty=!1},t.prototype.notifyOnChanges=function(){this._emitter.emit(this)},t.prototype.setDirty=function(){this._dirty=!0},Object.defineProperty(t.prototype,"dirty",{get:function(){return this._dirty},enumerable:!0,configurable:!0}),t}();e.QueryList=s},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(6),a=n(64),u=n(5),c=function(){function t(){}return t}();e.DynamicComponentLoader=c;var p=function(t){function e(e){t.call(this),this._compiler=e}return r(e,t),e.prototype.loadAsRoot=function(t,e,n,r,i){return this._compiler.resolveComponent(t).then(function(t){var o=t.create(n,i,u.isPresent(e)?e:t.selector);return u.isPresent(r)&&o.onDestroy(r),o})},e.prototype.loadNextToLocation=function(t,e,n,r){return void 0===n&&(n=null),void 0===r&&(r=null),this._compiler.resolveComponent(t).then(function(t){var i=e.parentInjector,o=u.isPresent(n)&&n.length>0?s.ReflectiveInjector.fromResolvedProviders(n,i):i;return e.createComponent(t,e.length,o,r)})},e=i([s.Injectable(),o("design:paramtypes",[a.ComponentResolver])],e)}(c);e.DynamicComponentLoader_=p},function(t,e){"use strict";var n=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},r=function(){function t(){}return Object.defineProperty(t.prototype,"elementRef",{get:function(){return null},enumerable:!0,configurable:!0}),t}();e.TemplateRef=r;var i=function(t){function e(e,n){t.call(this),this._appElement=e,this._viewFactory=n}return n(e,t),e.prototype.createEmbeddedView=function(){var t=this._viewFactory(this._appElement.parentView.viewUtils,this._appElement.parentInjector,this._appElement);return t.create(null,null),t.ref},Object.defineProperty(e.prototype,"elementRef",{get:function(){return this._appElement.elementRef},enumerable:!0,configurable:!0}),e}(r);e.TemplateRef_=i},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(12),o=n(34),s=n(33),a=function(t){function e(){t.apply(this,arguments)}return r(e,t),Object.defineProperty(e.prototype,"changeDetectorRef",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"destroyed",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),e}(o.ChangeDetectorRef);e.ViewRef=a;var u=function(t){function e(){t.apply(this,arguments)}return r(e,t),Object.defineProperty(e.prototype,"rootNodes",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),e}(a);e.EmbeddedViewRef=u;var c=function(){function t(t){this._view=t,this._view=t}return Object.defineProperty(t.prototype,"internalView",{get:function(){return this._view},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"changeDetectorRef",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rootNodes",{get:function(){return this._view.flatRootNodes},enumerable:!0,configurable:!0}),t.prototype.setLocal=function(t,e){this._view.setLocal(t,e)},t.prototype.hasLocal=function(t){return this._view.hasLocal(t)},Object.defineProperty(t.prototype,"destroyed",{get:function(){return this._view.destroyed},enumerable:!0,configurable:!0}),t.prototype.markForCheck=function(){this._view.markPathToRootAsCheckOnce()},t.prototype.detach=function(){this._view.cdMode=s.ChangeDetectionStrategy.Detached},t.prototype.detectChanges=function(){this._view.detectChanges(!1)},t.prototype.checkNoChanges=function(){this._view.detectChanges(!0)},t.prototype.reattach=function(){this._view.cdMode=s.ChangeDetectionStrategy.CheckAlways,this.markForCheck()},t.prototype.onDestroy=function(t){this._view.disposables.push(t)},t.prototype.destroy=function(){this._view.destroy()},t}();e.ViewRef_=c},function(t,e,n){"use strict";function r(t){return t.map(function(t){return t.nativeElement})}function i(t,e,n){t.childNodes.forEach(function(t){t instanceof v&&(e(t)&&n.push(t),i(t,e,n))})}function o(t,e,n){t instanceof v&&t.childNodes.forEach(function(t){e(t)&&n.push(t),t instanceof v&&o(t,e,n)})}function s(t){return y.get(t)}function a(){return h.MapWrapper.values(y)}function u(t){y.set(t.nativeNode,t)}function c(t){y["delete"](t.nativeNode)}var p=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},l=n(5),h=n(15),f=function(){function t(t,e){this.name=t,this.callback=e}return t}();e.EventListener=f;var d=function(){function t(t,e,n){this._debugInfo=n,this.nativeNode=t,l.isPresent(e)&&e instanceof v?e.addChild(this):this.parent=null,this.listeners=[]}return Object.defineProperty(t.prototype,"injector",{get:function(){return l.isPresent(this._debugInfo)?this._debugInfo.injector:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"componentInstance",{get:function(){return l.isPresent(this._debugInfo)?this._debugInfo.component:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"locals",{get:function(){return l.isPresent(this._debugInfo)?this._debugInfo.locals:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"providerTokens",{get:function(){return l.isPresent(this._debugInfo)?this._debugInfo.providerTokens:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"source",{get:function(){return l.isPresent(this._debugInfo)?this._debugInfo.source:null},enumerable:!0,configurable:!0}),t.prototype.inject=function(t){return this.injector.get(t)},t.prototype.getLocal=function(t){return this.locals[t]},t}();e.DebugNode=d;var v=function(t){function e(e,n,r){t.call(this,e,n,r),this.properties={},this.attributes={},this.childNodes=[],this.nativeElement=e}return p(e,t),e.prototype.addChild=function(t){l.isPresent(t)&&(this.childNodes.push(t),t.parent=this)},e.prototype.removeChild=function(t){var e=this.childNodes.indexOf(t);-1!==e&&(t.parent=null,this.childNodes.splice(e,1))},e.prototype.insertChildrenAfter=function(t,e){var n=this.childNodes.indexOf(t);if(-1!==n){var r=this.childNodes.slice(0,n+1),i=this.childNodes.slice(n+1);this.childNodes=h.ListWrapper.concat(h.ListWrapper.concat(r,e),i);for(var o=0;o<e.length;++o){var s=e[o];l.isPresent(s.parent)&&s.parent.removeChild(s),s.parent=this}}},e.prototype.query=function(t){var e=this.queryAll(t);return e.length>0?e[0]:null},e.prototype.queryAll=function(t){var e=[];return i(this,t,e),e},e.prototype.queryAllNodes=function(t){var e=[];return o(this,t,e),e},Object.defineProperty(e.prototype,"children",{get:function(){var t=[];return this.childNodes.forEach(function(n){n instanceof e&&t.push(n)}),t},enumerable:!0,configurable:!0}),e.prototype.triggerEventHandler=function(t,e){this.listeners.forEach(function(n){n.name==t&&n.callback(e)})},e}(d);e.DebugElement=v,e.asNativeElements=r;var y=new Map;e.getDebugNode=s,e.getAllDebugNodes=a,e.indexDebugNode=u,e.removeDebugNodeFromIndex=c},function(t,e,n){"use strict";var r=n(6),i=n(5);e.PLATFORM_DIRECTIVES=i.CONST_EXPR(new r.OpaqueToken("Platform Directives")),e.PLATFORM_PIPES=i.CONST_EXPR(new r.OpaqueToken("Platform Pipes"))},function(t,e,n){"use strict";function r(){return a.reflector}var i=n(5),o=n(6),s=n(75),a=n(18),u=n(20),c=n(63),p=n(59);e.PLATFORM_COMMON_PROVIDERS=i.CONST_EXPR([p.PLATFORM_CORE_PROVIDERS,new o.Provider(a.Reflector,{useFactory:r,deps:[]}),new o.Provider(u.ReflectorReader,{useExisting:a.Reflector}),c.TestabilityRegistry,s.Console])},function(t,e,n){"use strict";var r=n(5),i=n(6),o=n(62),s=n(59),a=n(28),u=n(66),c=n(64),p=n(64),l=n(80),h=n(80);e.APPLICATION_COMMON_PROVIDERS=r.CONST_EXPR([s.APPLICATION_CORE_PROVIDERS,new i.Provider(c.ComponentResolver,{useClass:p.ReflectorComponentResolver}),o.APP_ID_RANDOM_PROVIDER,u.ViewUtils,new i.Provider(a.IterableDiffers,{useValue:a.defaultIterableDiffers}),new i.Provider(a.KeyValueDiffers,{useValue:a.defaultKeyValueDiffers}),new i.Provider(l.DynamicComponentLoader,{useClass:h.DynamicComponentLoader_})])},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}r(n(88)),r(n(102)),r(n(112)),r(n(136))},function(t,e,n){"use strict";var r=n(89);e.AsyncPipe=r.AsyncPipe;var i=n(91);e.DatePipe=i.DatePipe;var o=n(93);e.JsonPipe=o.JsonPipe;var s=n(94);e.SlicePipe=s.SlicePipe;var a=n(95);e.LowerCasePipe=a.LowerCasePipe;var u=n(96);e.NumberPipe=u.NumberPipe,e.DecimalPipe=u.DecimalPipe,e.PercentPipe=u.PercentPipe,e.CurrencyPipe=u.CurrencyPipe;var c=n(97);e.UpperCasePipe=c.UpperCasePipe;var p=n(98);e.ReplacePipe=p.ReplacePipe;var l=n(99);e.I18nPluralPipe=l.I18nPluralPipe;var h=n(100);e.I18nSelectPipe=h.I18nSelectPipe;var f=n(101);e.COMMON_PIPES=f.COMMON_PIPES},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(40),a=n(2),u=n(90),c=function(){function t(){}return t.prototype.createSubscription=function(t,e){return s.ObservableWrapper.subscribe(t,e,function(t){throw t})},t.prototype.dispose=function(t){s.ObservableWrapper.dispose(t)},t.prototype.onDestroy=function(t){s.ObservableWrapper.dispose(t)},t}(),p=function(){function t(){}return t.prototype.createSubscription=function(t,e){return t.then(e)},t.prototype.dispose=function(t){},t.prototype.onDestroy=function(t){},t}(),l=new p,h=new c,f=function(){function t(t){this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null,this._strategy=null,this._ref=t}return t.prototype.ngOnDestroy=function(){o.isPresent(this._subscription)&&this._dispose()},t.prototype.transform=function(t){return o.isBlank(this._obj)?(o.isPresent(t)&&this._subscribe(t),this._latestReturnedValue=this._latestValue,this._latestValue):t!==this._obj?(this._dispose(),this.transform(t)):this._latestValue===this._latestReturnedValue?this._latestReturnedValue:(this._latestReturnedValue=this._latestValue,a.WrappedValue.wrap(this._latestValue))},t.prototype._subscribe=function(t){var e=this;this._obj=t,this._strategy=this._selectStrategy(t),this._subscription=this._strategy.createSubscription(t,function(n){return e._updateLatestValue(t,n)})},t.prototype._selectStrategy=function(e){if(o.isPromise(e))return l;if(s.ObservableWrapper.isObservable(e))return h;throw new u.InvalidPipeArgumentException(t,e)},t.prototype._dispose=function(){this._strategy.dispose(this._subscription),this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null},t.prototype._updateLatestValue=function(t,e){t===this._obj&&(this._latestValue=e,this._ref.markForCheck())},t=r([a.Pipe({name:"async",pure:!1}),a.Injectable(),i("design:paramtypes",[a.ChangeDetectorRef])],t)}();e.AsyncPipe=f},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(12),s=function(t){function e(e,n){t.call(this,"Invalid argument '"+n+"' for pipe '"+i.stringify(e)+"'")}return r(e,t),e}(o.BaseException);e.InvalidPipeArgumentException=s},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(92),a=n(2),u=n(15),c=n(90),p="en-US",l=function(){function t(){}return t.prototype.transform=function(e,n){if(void 0===n&&(n="mediumDate"),o.isBlank(e))return null;if(!this.supports(e))throw new c.InvalidPipeArgumentException(t,e);return o.isNumber(e)&&(e=o.DateWrapper.fromMillis(e)),u.StringMapWrapper.contains(t._ALIASES,n)&&(n=u.StringMapWrapper.get(t._ALIASES,n)),s.DateFormatter.format(e,p,n)},t.prototype.supports=function(t){return o.isDate(t)||o.isNumber(t)},t._ALIASES={medium:"yMMMdjms","short":"yMdjm",fullDate:"yMMMMEEEEd",longDate:"yMMMMd",mediumDate:"yMMMd",shortDate:"yMd",mediumTime:"jms",shortTime:"jm"},t=r([o.CONST(),a.Pipe({name:"date",pure:!0}),a.Injectable(),i("design:paramtypes",[])],t)}();e.DatePipe=l},function(t,e){"use strict";function n(t){return 2==t?"2-digit":"numeric"}function r(t){return 4>t?"short":"long"}function i(t){for(var e,i={},o=0;o<t.length;){for(e=o;e<t.length&&t[e]==t[o];)e++;var s=e-o;switch(t[o]){case"G":i.era=r(s);break;case"y":i.year=n(s);break;case"M":s>=3?i.month=r(s):i.month=n(s);break;case"d":i.day=n(s);break;case"E":i.weekday=r(s);break;case"j":i.hour=n(s);break;case"h":i.hour=n(s),i.hour12=!0;break;case"H":i.hour=n(s),i.hour12=!1;break;case"m":i.minute=n(s);break;case"s":i.second=n(s);break;case"z":i.timeZoneName="long";break;case"Z":i.timeZoneName="short"}o=e}return i}!function(t){t[t.Decimal=0]="Decimal",t[t.Percent=1]="Percent",t[t.Currency=2]="Currency"}(e.NumberFormatStyle||(e.NumberFormatStyle={}));var o=e.NumberFormatStyle,s=function(){function t(){}return t.format=function(t,e,n,r){var i=void 0===r?{}:r,s=i.minimumIntegerDigits,a=void 0===s?1:s,u=i.minimumFractionDigits,c=void 0===u?0:u,p=i.maximumFractionDigits,l=void 0===p?3:p,h=i.currency,f=i.currencyAsSymbol,d=void 0===f?!1:f,v={minimumIntegerDigits:a,minimumFractionDigits:c,maximumFractionDigits:l};return v.style=o[n].toLowerCase(),n==o.Currency&&(v.currency=h,v.currencyDisplay=d?"symbol":"code"),new Intl.NumberFormat(e,v).format(t)},t}();e.NumberFormatter=s;var a=new Map,u=function(){function t(){}return t.format=function(t,e,n){var r=e+n;if(a.has(r))return a.get(r).format(t);var o=new Intl.DateTimeFormat(e,i(n));return a.set(r,o),o.format(t)},t}();e.DateFormatter=u},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=function(){function t(){}return t.prototype.transform=function(t){return o.Json.stringify(t)},t=r([o.CONST(),s.Pipe({name:"json",pure:!1}),s.Injectable(),i("design:paramtypes",[])],t)}();e.JsonPipe=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(15),a=n(2),u=n(90),c=function(){function t(){}return t.prototype.transform=function(e,n,r){if(void 0===r&&(r=null),!this.supports(e))throw new u.InvalidPipeArgumentException(t,e);return o.isBlank(e)?e:o.isString(e)?o.StringWrapper.slice(e,n,r):s.ListWrapper.slice(e,n,r)},t.prototype.supports=function(t){return o.isString(t)||o.isArray(t)},t=r([a.Pipe({name:"slice",pure:!1}),a.Injectable(),i("design:paramtypes",[])],t)}();e.SlicePipe=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=n(90),u=function(){function t(){}return t.prototype.transform=function(e){if(o.isBlank(e))return e;if(!o.isString(e))throw new a.InvalidPipeArgumentException(t,e);return e.toLowerCase()},t=r([o.CONST(),s.Pipe({name:"lowercase"}),s.Injectable(),i("design:paramtypes",[])],t)}();e.LowerCasePipe=u},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(12),u=n(92),c=n(2),p=n(90),l="en-US",h=s.RegExpWrapper.create("^(\\d+)?\\.((\\d+)(\\-(\\d+))?)?$"),f=function(){function t(){}return t._format=function(e,n,r,i,o){if(void 0===i&&(i=null),void 0===o&&(o=!1),s.isBlank(e))return null;if(!s.isNumber(e))throw new p.InvalidPipeArgumentException(t,e);var c=1,f=0,d=3;if(s.isPresent(r)){var v=s.RegExpWrapper.firstMatch(h,r);if(s.isBlank(v))throw new a.BaseException(r+" is not a valid digit info for number pipes");s.isPresent(v[1])&&(c=s.NumberWrapper.parseIntAutoRadix(v[1])),s.isPresent(v[3])&&(f=s.NumberWrapper.parseIntAutoRadix(v[3])),s.isPresent(v[5])&&(d=s.NumberWrapper.parseIntAutoRadix(v[5]))}return u.NumberFormatter.format(e,l,n,{minimumIntegerDigits:c,minimumFractionDigits:f,maximumFractionDigits:d,currency:i,currencyAsSymbol:o})},t=i([s.CONST(),c.Injectable(),o("design:paramtypes",[])],t)}();e.NumberPipe=f;var d=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.transform=function(t,e){return void 0===e&&(e=null),f._format(t,u.NumberFormatStyle.Decimal,e)},e=i([s.CONST(),c.Pipe({name:"number"}),c.Injectable(),o("design:paramtypes",[])],e)}(f);e.DecimalPipe=d;var v=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.transform=function(t,e){return void 0===e&&(e=null),f._format(t,u.NumberFormatStyle.Percent,e)},e=i([s.CONST(),c.Pipe({name:"percent"}),c.Injectable(),o("design:paramtypes",[])],e)}(f);e.PercentPipe=v;var y=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.transform=function(t,e,n,r){return void 0===e&&(e="USD"),void 0===n&&(n=!1),void 0===r&&(r=null),f._format(t,u.NumberFormatStyle.Currency,r,e,n)},e=i([s.CONST(),c.Pipe({name:"currency"}),c.Injectable(),o("design:paramtypes",[])],e)}(f);e.CurrencyPipe=y},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=n(90),u=function(){function t(){}return t.prototype.transform=function(e){if(o.isBlank(e))return e;if(!o.isString(e))throw new a.InvalidPipeArgumentException(t,e);return e.toUpperCase()},t=r([o.CONST(),s.Pipe({name:"uppercase"}),s.Injectable(),i("design:paramtypes",[])],t)}();e.UpperCasePipe=u},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=n(90),u=function(){function t(){}return t.prototype.transform=function(e,n,r){if(o.isBlank(e))return e;if(!this._supportedInput(e))throw new a.InvalidPipeArgumentException(t,e);var i=e.toString();if(!this._supportedPattern(n))throw new a.InvalidPipeArgumentException(t,n);if(!this._supportedReplacement(r))throw new a.InvalidPipeArgumentException(t,r);if(o.isFunction(r)){var s=o.isString(n)?o.RegExpWrapper.create(n):n;return o.StringWrapper.replaceAllMapped(i,s,r)}return n instanceof RegExp?o.StringWrapper.replaceAll(i,n,r):o.StringWrapper.replace(i,n,r)},t.prototype._supportedInput=function(t){return o.isString(t)||o.isNumber(t)},t.prototype._supportedPattern=function(t){return o.isString(t)||t instanceof RegExp},t.prototype._supportedReplacement=function(t){return o.isString(t)||o.isFunction(t)},t=r([s.Pipe({name:"replace"}),s.Injectable(),i("design:paramtypes",[])],t)}();e.ReplacePipe=u},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=n(90),u=o.RegExpWrapper.create("#"),c=function(){function t(){}return t.prototype.transform=function(e,n){var r,i;if(!o.isStringMap(n))throw new a.InvalidPipeArgumentException(t,n);return r=0===e||1===e?"="+e:"other",i=o.isPresent(e)?e.toString():"",o.StringWrapper.replaceAll(n[r],u,i)},t=r([o.CONST(),s.Pipe({name:"i18nPlural",pure:!0}),s.Injectable(),i("design:paramtypes",[])],t)}();e.I18nPluralPipe=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(15),a=n(2),u=n(90),c=function(){function t(){}return t.prototype.transform=function(e,n){if(!o.isStringMap(n))throw new u.InvalidPipeArgumentException(t,n);return s.StringMapWrapper.contains(n,e)?n[e]:n.other},t=r([o.CONST(),a.Pipe({name:"i18nSelect",pure:!0}),a.Injectable(),i("design:paramtypes",[])],t)}();e.I18nSelectPipe=c},function(t,e,n){"use strict";var r=n(89),i=n(97),o=n(95),s=n(93),a=n(94),u=n(91),c=n(96),p=n(98),l=n(99),h=n(100),f=n(5);e.COMMON_PIPES=f.CONST_EXPR([r.AsyncPipe,i.UpperCasePipe,o.LowerCasePipe,s.JsonPipe,a.SlicePipe,c.DecimalPipe,c.PercentPipe,c.CurrencyPipe,u.DatePipe,p.ReplacePipe,l.I18nPluralPipe,h.I18nSelectPipe])},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}var i=n(103);e.NgClass=i.NgClass;var o=n(104);e.NgFor=o.NgFor;var s=n(105);e.NgIf=s.NgIf;var a=n(106);e.NgTemplateOutlet=a.NgTemplateOutlet;var u=n(107);e.NgStyle=u.NgStyle;var c=n(108);e.NgSwitch=c.NgSwitch,e.NgSwitchWhen=c.NgSwitchWhen,e.NgSwitchDefault=c.NgSwitchDefault;var p=n(109);e.NgPlural=p.NgPlural,e.NgPluralCase=p.NgPluralCase,e.NgLocalization=p.NgLocalization,r(n(110));var l=n(111);e.CORE_DIRECTIVES=l.CORE_DIRECTIVES},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(2),a=n(15),u=function(){function t(t,e,n,r){this._iterableDiffers=t,this._keyValueDiffers=e,this._ngEl=n,this._renderer=r,this._initialClasses=[]}return Object.defineProperty(t.prototype,"initialClasses",{set:function(t){this._applyInitialClasses(!0),this._initialClasses=o.isPresent(t)&&o.isString(t)?t.split(" "):[],this._applyInitialClasses(!1),this._applyClasses(this._rawClass,!1)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rawClass",{set:function(t){this._cleanupClasses(this._rawClass),o.isString(t)&&(t=t.split(" ")),this._rawClass=t,this._iterableDiffer=null,this._keyValueDiffer=null,o.isPresent(t)&&(a.isListLikeIterable(t)?this._iterableDiffer=this._iterableDiffers.find(t).create(null):this._keyValueDiffer=this._keyValueDiffers.find(t).create(null))},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){if(o.isPresent(this._iterableDiffer)){var t=this._iterableDiffer.diff(this._rawClass);o.isPresent(t)&&this._applyIterableChanges(t)}if(o.isPresent(this._keyValueDiffer)){var t=this._keyValueDiffer.diff(this._rawClass);o.isPresent(t)&&this._applyKeyValueChanges(t)}},t.prototype.ngOnDestroy=function(){this._cleanupClasses(this._rawClass)},t.prototype._cleanupClasses=function(t){this._applyClasses(t,!0),this._applyInitialClasses(!1)},t.prototype._applyKeyValueChanges=function(t){var e=this;t.forEachAddedItem(function(t){e._toggleClass(t.key,t.currentValue)}),t.forEachChangedItem(function(t){e._toggleClass(t.key,t.currentValue)}),t.forEachRemovedItem(function(t){t.previousValue&&e._toggleClass(t.key,!1)})},t.prototype._applyIterableChanges=function(t){var e=this;t.forEachAddedItem(function(t){e._toggleClass(t.item,!0)}),t.forEachRemovedItem(function(t){e._toggleClass(t.item,!1)})},t.prototype._applyInitialClasses=function(t){var e=this;this._initialClasses.forEach(function(n){return e._toggleClass(n,!t)})},t.prototype._applyClasses=function(t,e){var n=this;o.isPresent(t)&&(o.isArray(t)?t.forEach(function(t){return n._toggleClass(t,!e)}):t instanceof Set?t.forEach(function(t){return n._toggleClass(t,!e)}):a.StringMapWrapper.forEach(t,function(t,r){o.isPresent(t)&&n._toggleClass(r,!e)}))},t.prototype._toggleClass=function(t,e){if(t=t.trim(),t.length>0)if(t.indexOf(" ")>-1)for(var n=t.split(/\s+/g),r=0,i=n.length;i>r;r++)this._renderer.setElementClass(this._ngEl.nativeElement,n[r],e);else this._renderer.setElementClass(this._ngEl.nativeElement,t,e)},t=r([s.Directive({selector:"[ngClass]",inputs:["rawClass: ngClass","initialClasses: class"]}),i("design:paramtypes",[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer])],t)}();e.NgClass=u},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(5),a=n(12),u=function(){function t(t,e,n,r){this._viewContainer=t,this._templateRef=e,this._iterableDiffers=n,this._cdr=r}return Object.defineProperty(t.prototype,"ngForOf",{
                +set:function(t){if(this._ngForOf=t,s.isBlank(this._differ)&&s.isPresent(t))try{this._differ=this._iterableDiffers.find(t).create(this._cdr,this._ngForTrackBy)}catch(e){throw new a.BaseException("Cannot find a differ supporting object '"+t+"' of type '"+s.getTypeNameForDebugging(t)+"'. NgFor only supports binding to Iterables such as Arrays.")}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngForTemplate",{set:function(t){s.isPresent(t)&&(this._templateRef=t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngForTrackBy",{set:function(t){this._ngForTrackBy=t},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){if(s.isPresent(this._differ)){var t=this._differ.diff(this._ngForOf);s.isPresent(t)&&this._applyChanges(t)}},t.prototype._applyChanges=function(t){var e=this,n=[];t.forEachRemovedItem(function(t){return n.push(new c(t,null))}),t.forEachMovedItem(function(t){return n.push(new c(t,null))});var r=this._bulkRemove(n);t.forEachAddedItem(function(t){return r.push(new c(t,null))}),this._bulkInsert(r);for(var i=0;i<r.length;i++)this._perViewChange(r[i].view,r[i].record);for(var i=0,o=this._viewContainer.length;o>i;i++){var s=this._viewContainer.get(i);s.setLocal("first",0===i),s.setLocal("last",i===o-1)}t.forEachIdentityChange(function(t){var n=e._viewContainer.get(t.currentIndex);n.setLocal("$implicit",t.item)})},t.prototype._perViewChange=function(t,e){t.setLocal("$implicit",e.item),t.setLocal("index",e.currentIndex),t.setLocal("even",e.currentIndex%2==0),t.setLocal("odd",e.currentIndex%2==1)},t.prototype._bulkRemove=function(t){t.sort(function(t,e){return t.record.previousIndex-e.record.previousIndex});for(var e=[],n=t.length-1;n>=0;n--){var r=t[n];s.isPresent(r.record.currentIndex)?(r.view=this._viewContainer.detach(r.record.previousIndex),e.push(r)):this._viewContainer.remove(r.record.previousIndex)}return e},t.prototype._bulkInsert=function(t){t.sort(function(t,e){return t.record.currentIndex-e.record.currentIndex});for(var e=0;e<t.length;e++){var n=t[e];s.isPresent(n.view)?this._viewContainer.insert(n.view,n.record.currentIndex):n.view=this._viewContainer.createEmbeddedView(this._templateRef,n.record.currentIndex)}return t},t=r([o.Directive({selector:"[ngFor][ngForOf]",inputs:["ngForTrackBy","ngForOf","ngForTemplate"]}),i("design:paramtypes",[o.ViewContainerRef,o.TemplateRef,o.IterableDiffers,o.ChangeDetectorRef])],t)}();e.NgFor=u;var c=function(){function t(t,e){this.record=t,this.view=e}return t}()},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(5),a=function(){function t(t,e){this._viewContainer=t,this._templateRef=e,this._prevCondition=null}return Object.defineProperty(t.prototype,"ngIf",{set:function(t){!t||!s.isBlank(this._prevCondition)&&this._prevCondition?t||!s.isBlank(this._prevCondition)&&!this._prevCondition||(this._prevCondition=!1,this._viewContainer.clear()):(this._prevCondition=!0,this._viewContainer.createEmbeddedView(this._templateRef))},enumerable:!0,configurable:!0}),t=r([o.Directive({selector:"[ngIf]",inputs:["ngIf"]}),i("design:paramtypes",[o.ViewContainerRef,o.TemplateRef])],t)}();e.NgIf=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(5),a=function(){function t(t){this._viewContainerRef=t}return Object.defineProperty(t.prototype,"ngTemplateOutlet",{set:function(t){s.isPresent(this._insertedViewRef)&&this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._insertedViewRef)),s.isPresent(t)&&(this._insertedViewRef=this._viewContainerRef.createEmbeddedView(t))},enumerable:!0,configurable:!0}),r([o.Input(),i("design:type",o.TemplateRef),i("design:paramtypes",[o.TemplateRef])],t.prototype,"ngTemplateOutlet",null),t=r([o.Directive({selector:"[ngTemplateOutlet]"}),i("design:paramtypes",[o.ViewContainerRef])],t)}();e.NgTemplateOutlet=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(5),a=function(){function t(t,e,n){this._differs=t,this._ngEl=e,this._renderer=n}return Object.defineProperty(t.prototype,"rawStyle",{set:function(t){this._rawStyle=t,s.isBlank(this._differ)&&s.isPresent(t)&&(this._differ=this._differs.find(this._rawStyle).create(null))},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){if(s.isPresent(this._differ)){var t=this._differ.diff(this._rawStyle);s.isPresent(t)&&this._applyChanges(t)}},t.prototype._applyChanges=function(t){var e=this;t.forEachAddedItem(function(t){e._setStyle(t.key,t.currentValue)}),t.forEachChangedItem(function(t){e._setStyle(t.key,t.currentValue)}),t.forEachRemovedItem(function(t){e._setStyle(t.key,null)})},t.prototype._setStyle=function(t,e){this._renderer.setElementStyle(this._ngEl.nativeElement,t,e)},t=r([o.Directive({selector:"[ngStyle]",inputs:["rawStyle: ngStyle"]}),i("design:paramtypes",[o.KeyValueDiffers,o.ElementRef,o.Renderer])],t)}();e.NgStyle=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(2),a=n(5),u=n(15),c=a.CONST_EXPR(new Object),p=function(){function t(t,e){this._viewContainerRef=t,this._templateRef=e}return t.prototype.create=function(){this._viewContainerRef.createEmbeddedView(this._templateRef)},t.prototype.destroy=function(){this._viewContainerRef.clear()},t}();e.SwitchView=p;var l=function(){function t(){this._useDefault=!1,this._valueViews=new u.Map,this._activeViews=[]}return Object.defineProperty(t.prototype,"ngSwitch",{set:function(t){this._emptyAllActiveViews(),this._useDefault=!1;var e=this._valueViews.get(t);a.isBlank(e)&&(this._useDefault=!0,e=a.normalizeBlank(this._valueViews.get(c))),this._activateViews(e),this._switchValue=t},enumerable:!0,configurable:!0}),t.prototype._onWhenValueChanged=function(t,e,n){this._deregisterView(t,n),this._registerView(e,n),t===this._switchValue?(n.destroy(),u.ListWrapper.remove(this._activeViews,n)):e===this._switchValue&&(this._useDefault&&(this._useDefault=!1,this._emptyAllActiveViews()),n.create(),this._activeViews.push(n)),0!==this._activeViews.length||this._useDefault||(this._useDefault=!0,this._activateViews(this._valueViews.get(c)))},t.prototype._emptyAllActiveViews=function(){for(var t=this._activeViews,e=0;e<t.length;e++)t[e].destroy();this._activeViews=[]},t.prototype._activateViews=function(t){if(a.isPresent(t)){for(var e=0;e<t.length;e++)t[e].create();this._activeViews=t}},t.prototype._registerView=function(t,e){var n=this._valueViews.get(t);a.isBlank(n)&&(n=[],this._valueViews.set(t,n)),n.push(e)},t.prototype._deregisterView=function(t,e){if(t!==c){var n=this._valueViews.get(t);1==n.length?this._valueViews["delete"](t):u.ListWrapper.remove(n,e)}},t=r([s.Directive({selector:"[ngSwitch]",inputs:["ngSwitch"]}),i("design:paramtypes",[])],t)}();e.NgSwitch=l;var h=function(){function t(t,e,n){this._value=c,this._switch=n,this._view=new p(t,e)}return Object.defineProperty(t.prototype,"ngSwitchWhen",{set:function(t){this._switch._onWhenValueChanged(this._value,t,this._view),this._value=t},enumerable:!0,configurable:!0}),t=r([s.Directive({selector:"[ngSwitchWhen]",inputs:["ngSwitchWhen"]}),o(2,s.Host()),i("design:paramtypes",[s.ViewContainerRef,s.TemplateRef,l])],t)}();e.NgSwitchWhen=h;var f=function(){function t(t,e,n){n._registerView(c,new p(t,e))}return t=r([s.Directive({selector:"[ngSwitchDefault]"}),o(2,s.Host()),i("design:paramtypes",[s.ViewContainerRef,s.TemplateRef,l])],t)}();e.NgSwitchDefault=f},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(2),a=n(5),u=n(15),c=n(108),p="other",l=function(){function t(){}return t}();e.NgLocalization=l;var h=function(){function t(t,e,n){this.value=t,this._view=new c.SwitchView(n,e)}return t=r([s.Directive({selector:"[ngPluralCase]"}),o(0,s.Attribute("ngPluralCase")),i("design:paramtypes",[String,s.TemplateRef,s.ViewContainerRef])],t)}();e.NgPluralCase=h;var f=function(){function t(t){this._localization=t,this._caseViews=new u.Map,this.cases=null}return Object.defineProperty(t.prototype,"ngPlural",{set:function(t){this._switchValue=t,this._updateView()},enumerable:!0,configurable:!0}),t.prototype.ngAfterContentInit=function(){var t=this;this.cases.forEach(function(e){t._caseViews.set(t._formatValue(e),e._view)}),this._updateView()},t.prototype._updateView=function(){this._clearViews();var t=this._caseViews.get(this._switchValue);a.isPresent(t)||(t=this._getCategoryView(this._switchValue)),this._activateView(t)},t.prototype._clearViews=function(){a.isPresent(this._activeView)&&this._activeView.destroy()},t.prototype._activateView=function(t){a.isPresent(t)&&(this._activeView=t,this._activeView.create())},t.prototype._getCategoryView=function(t){var e=this._localization.getPluralCategory(t),n=this._caseViews.get(e);return a.isPresent(n)?n:this._caseViews.get(p)},t.prototype._isValueView=function(t){return"="===t.value[0]},t.prototype._formatValue=function(t){return this._isValueView(t)?this._stripValue(t.value):t.value},t.prototype._stripValue=function(t){return a.NumberWrapper.parseInt(t.substring(1),10)},r([s.ContentChildren(h),i("design:type",s.QueryList)],t.prototype,"cases",void 0),r([s.Input(),i("design:type",Number),i("design:paramtypes",[Number])],t.prototype,"ngPlural",null),t=r([s.Directive({selector:"[ngPlural]"}),i("design:paramtypes",[l])],t)}();e.NgPlural=f},function(t,e){"use strict"},function(t,e,n){"use strict";var r=n(5),i=n(103),o=n(104),s=n(105),a=n(106),u=n(107),c=n(108),p=n(109);e.CORE_DIRECTIVES=r.CONST_EXPR([i.NgClass,o.NgFor,s.NgIf,a.NgTemplateOutlet,u.NgStyle,c.NgSwitch,c.NgSwitchWhen,c.NgSwitchDefault,p.NgPlural,p.NgPluralCase])},function(t,e,n){"use strict";var r=n(113);e.AbstractControl=r.AbstractControl,e.Control=r.Control,e.ControlGroup=r.ControlGroup,e.ControlArray=r.ControlArray;var i=n(114);e.AbstractControlDirective=i.AbstractControlDirective;var o=n(115);e.ControlContainer=o.ControlContainer;var s=n(116);e.NgControlName=s.NgControlName;var a=n(127);e.NgFormControl=a.NgFormControl;var u=n(128);e.NgModel=u.NgModel;var c=n(117);e.NgControl=c.NgControl;var p=n(129);e.NgControlGroup=p.NgControlGroup;var l=n(130);e.NgFormModel=l.NgFormModel;var h=n(131);e.NgForm=h.NgForm;var f=n(118);e.NG_VALUE_ACCESSOR=f.NG_VALUE_ACCESSOR;var d=n(121);e.DefaultValueAccessor=d.DefaultValueAccessor;var v=n(132);e.NgControlStatus=v.NgControlStatus;var y=n(123);e.CheckboxControlValueAccessor=y.CheckboxControlValueAccessor;var m=n(124);e.NgSelectOption=m.NgSelectOption,e.SelectControlValueAccessor=m.SelectControlValueAccessor;var g=n(133);e.FORM_DIRECTIVES=g.FORM_DIRECTIVES,e.RadioButtonState=g.RadioButtonState;var _=n(120);e.NG_VALIDATORS=_.NG_VALIDATORS,e.NG_ASYNC_VALIDATORS=_.NG_ASYNC_VALIDATORS,e.Validators=_.Validators;var b=n(134);e.RequiredValidator=b.RequiredValidator,e.MinLengthValidator=b.MinLengthValidator,e.MaxLengthValidator=b.MaxLengthValidator,e.PatternValidator=b.PatternValidator;var P=n(135);e.FormBuilder=P.FormBuilder;var E=n(135),w=n(125),C=n(5);e.FORM_PROVIDERS=C.CONST_EXPR([E.FormBuilder,w.RadioControlRegistry]),e.FORM_BINDINGS=e.FORM_PROVIDERS},function(t,e,n){"use strict";function r(t){return t instanceof l}function i(t,e){return a.isBlank(e)?null:(e instanceof Array||(e=e.split("/")),e instanceof Array&&p.ListWrapper.isEmpty(e)?null:e.reduce(function(t,e){if(t instanceof f)return a.isPresent(t.controls[e])?t.controls[e]:null;if(t instanceof d){var n=e;return a.isPresent(t.at(n))?t.at(n):null}return null},t))}function o(t){return c.PromiseWrapper.isPromise(t)?u.ObservableWrapper.fromPromise(t):t}var s=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},a=n(5),u=n(40),c=n(41),p=n(15);e.VALID="VALID",e.INVALID="INVALID",e.PENDING="PENDING",e.isControl=r;var l=function(){function t(t,e){this.validator=t,this.asyncValidator=e,this._pristine=!0,this._touched=!1}return Object.defineProperty(t.prototype,"value",{get:function(){return this._value},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"status",{get:function(){return this._status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valid",{get:function(){return this._status===e.VALID},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"errors",{get:function(){return this._errors},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pristine",{get:function(){return this._pristine},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"dirty",{get:function(){return!this.pristine},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"touched",{get:function(){return this._touched},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"untouched",{get:function(){return!this._touched},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valueChanges",{get:function(){return this._valueChanges},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"statusChanges",{get:function(){return this._statusChanges},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pending",{get:function(){return this._status==e.PENDING},enumerable:!0,configurable:!0}),t.prototype.markAsTouched=function(){this._touched=!0},t.prototype.markAsDirty=function(t){var e=(void 0===t?{}:t).onlySelf;e=a.normalizeBool(e),this._pristine=!1,a.isPresent(this._parent)&&!e&&this._parent.markAsDirty({onlySelf:e})},t.prototype.markAsPending=function(t){var n=(void 0===t?{}:t).onlySelf;n=a.normalizeBool(n),this._status=e.PENDING,a.isPresent(this._parent)&&!n&&this._parent.markAsPending({onlySelf:n})},t.prototype.setParent=function(t){this._parent=t},t.prototype.updateValueAndValidity=function(t){var n=void 0===t?{}:t,r=n.onlySelf,i=n.emitEvent;r=a.normalizeBool(r),i=a.isPresent(i)?i:!0,this._updateValue(),this._errors=this._runValidator(),this._status=this._calculateStatus(),(this._status==e.VALID||this._status==e.PENDING)&&this._runAsyncValidator(i),i&&(u.ObservableWrapper.callEmit(this._valueChanges,this._value),u.ObservableWrapper.callEmit(this._statusChanges,this._status)),a.isPresent(this._parent)&&!r&&this._parent.updateValueAndValidity({onlySelf:r,emitEvent:i})},t.prototype._runValidator=function(){return a.isPresent(this.validator)?this.validator(this):null},t.prototype._runAsyncValidator=function(t){var n=this;if(a.isPresent(this.asyncValidator)){this._status=e.PENDING,this._cancelExistingSubscription();var r=o(this.asyncValidator(this));this._asyncValidationSubscription=u.ObservableWrapper.subscribe(r,function(e){return n.setErrors(e,{emitEvent:t})})}},t.prototype._cancelExistingSubscription=function(){a.isPresent(this._asyncValidationSubscription)&&u.ObservableWrapper.dispose(this._asyncValidationSubscription)},t.prototype.setErrors=function(t,e){var n=(void 0===e?{}:e).emitEvent;n=a.isPresent(n)?n:!0,this._errors=t,this._status=this._calculateStatus(),n&&u.ObservableWrapper.callEmit(this._statusChanges,this._status),a.isPresent(this._parent)&&this._parent._updateControlsErrors()},t.prototype.find=function(t){return i(this,t)},t.prototype.getError=function(t,e){void 0===e&&(e=null);var n=a.isPresent(e)&&!p.ListWrapper.isEmpty(e)?this.find(e):this;return a.isPresent(n)&&a.isPresent(n._errors)?p.StringMapWrapper.get(n._errors,t):null},t.prototype.hasError=function(t,e){return void 0===e&&(e=null),a.isPresent(this.getError(t,e))},Object.defineProperty(t.prototype,"root",{get:function(){for(var t=this;a.isPresent(t._parent);)t=t._parent;return t},enumerable:!0,configurable:!0}),t.prototype._updateControlsErrors=function(){this._status=this._calculateStatus(),a.isPresent(this._parent)&&this._parent._updateControlsErrors()},t.prototype._initObservables=function(){this._valueChanges=new u.EventEmitter,this._statusChanges=new u.EventEmitter},t.prototype._calculateStatus=function(){return a.isPresent(this._errors)?e.INVALID:this._anyControlsHaveStatus(e.PENDING)?e.PENDING:this._anyControlsHaveStatus(e.INVALID)?e.INVALID:e.VALID},t}();e.AbstractControl=l;var h=function(t){function e(e,n,r){void 0===e&&(e=null),void 0===n&&(n=null),void 0===r&&(r=null),t.call(this,n,r),this._value=e,this.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),this._initObservables()}return s(e,t),e.prototype.updateValue=function(t,e){var n=void 0===e?{}:e,r=n.onlySelf,i=n.emitEvent,o=n.emitModelToViewChange;o=a.isPresent(o)?o:!0,this._value=t,a.isPresent(this._onChange)&&o&&this._onChange(this._value),this.updateValueAndValidity({onlySelf:r,emitEvent:i})},e.prototype._updateValue=function(){},e.prototype._anyControlsHaveStatus=function(t){return!1},e.prototype.registerOnChange=function(t){this._onChange=t},e}(l);e.Control=h;var f=function(t){function e(e,n,r,i){void 0===n&&(n=null),void 0===r&&(r=null),void 0===i&&(i=null),t.call(this,r,i),this.controls=e,this._optionals=a.isPresent(n)?n:{},this._initObservables(),this._setParentForControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!1})}return s(e,t),e.prototype.addControl=function(t,e){this.controls[t]=e,e.setParent(this)},e.prototype.removeControl=function(t){p.StringMapWrapper["delete"](this.controls,t)},e.prototype.include=function(t){p.StringMapWrapper.set(this._optionals,t,!0),this.updateValueAndValidity()},e.prototype.exclude=function(t){p.StringMapWrapper.set(this._optionals,t,!1),this.updateValueAndValidity()},e.prototype.contains=function(t){var e=p.StringMapWrapper.contains(this.controls,t);return e&&this._included(t)},e.prototype._setParentForControls=function(){var t=this;p.StringMapWrapper.forEach(this.controls,function(e,n){e.setParent(t)})},e.prototype._updateValue=function(){this._value=this._reduceValue()},e.prototype._anyControlsHaveStatus=function(t){var e=this,n=!1;return p.StringMapWrapper.forEach(this.controls,function(r,i){n=n||e.contains(i)&&r.status==t}),n},e.prototype._reduceValue=function(){return this._reduceChildren({},function(t,e,n){return t[n]=e.value,t})},e.prototype._reduceChildren=function(t,e){var n=this,r=t;return p.StringMapWrapper.forEach(this.controls,function(t,i){n._included(i)&&(r=e(r,t,i))}),r},e.prototype._included=function(t){var e=p.StringMapWrapper.contains(this._optionals,t);return!e||p.StringMapWrapper.get(this._optionals,t)},e}(l);e.ControlGroup=f;var d=function(t){function e(e,n,r){void 0===n&&(n=null),void 0===r&&(r=null),t.call(this,n,r),this.controls=e,this._initObservables(),this._setParentForControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!1})}return s(e,t),e.prototype.at=function(t){return this.controls[t]},e.prototype.push=function(t){this.controls.push(t),t.setParent(this),this.updateValueAndValidity()},e.prototype.insert=function(t,e){p.ListWrapper.insert(this.controls,t,e),e.setParent(this),this.updateValueAndValidity()},e.prototype.removeAt=function(t){p.ListWrapper.removeAt(this.controls,t),this.updateValueAndValidity()},Object.defineProperty(e.prototype,"length",{get:function(){return this.controls.length},enumerable:!0,configurable:!0}),e.prototype._updateValue=function(){this._value=this.controls.map(function(t){return t.value})},e.prototype._anyControlsHaveStatus=function(t){return this.controls.some(function(e){return e.status==t})},e.prototype._setParentForControls=function(){var t=this;this.controls.forEach(function(e){e.setParent(t)})},e}(l);e.ControlArray=d},function(t,e,n){"use strict";var r=n(5),i=n(12),o=function(){function t(){}return Object.defineProperty(t.prototype,"control",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{get:function(){return r.isPresent(this.control)?this.control.value:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valid",{get:function(){return r.isPresent(this.control)?this.control.valid:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"errors",{get:function(){return r.isPresent(this.control)?this.control.errors:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pristine",{get:function(){return r.isPresent(this.control)?this.control.pristine:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"dirty",{get:function(){return r.isPresent(this.control)?this.control.dirty:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"touched",{get:function(){return r.isPresent(this.control)?this.control.touched:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"untouched",{get:function(){return r.isPresent(this.control)?this.control.untouched:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),t}();e.AbstractControlDirective=o},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(114),o=function(t){function e(){t.apply(this,arguments)}return r(e,t),Object.defineProperty(e.prototype,"formDirective",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),e}(i.AbstractControlDirective);e.ControlContainer=o},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(5),u=n(40),c=n(2),p=n(115),l=n(117),h=n(118),f=n(119),d=n(120),v=a.CONST_EXPR(new c.Provider(l.NgControl,{useExisting:c.forwardRef(function(){return y})})),y=function(t){function e(e,n,r,i){t.call(this),this._parent=e,this._validators=n,this._asyncValidators=r,this.update=new u.EventEmitter,this._added=!1,this.valueAccessor=f.selectValueAccessor(this,i)}return r(e,t),e.prototype.ngOnChanges=function(t){this._added||(this.formDirective.addControl(this),this._added=!0),f.isPropertyUpdated(t,this.viewModel)&&(this.viewModel=this.model,this.formDirective.updateModel(this,this.model))},e.prototype.ngOnDestroy=function(){this.formDirective.removeControl(this)},e.prototype.viewToModelUpdate=function(t){this.viewModel=t,u.ObservableWrapper.callEmit(this.update,t)},Object.defineProperty(e.prototype,"path",{get:function(){return f.controlPath(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent.formDirective},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return f.composeValidators(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return f.composeAsyncValidators(this._asyncValidators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.formDirective.getControl(this)},enumerable:!0,configurable:!0}),e=i([c.Directive({selector:"[ngControl]",bindings:[v],inputs:["name: ngControl","model: ngModel"],outputs:["update: ngModelChange"],exportAs:"ngForm"}),s(0,c.Host()),s(0,c.SkipSelf()),s(1,c.Optional()),s(1,c.Self()),s(1,c.Inject(d.NG_VALIDATORS)),s(2,c.Optional()),s(2,c.Self()),s(2,c.Inject(d.NG_ASYNC_VALIDATORS)),s(3,c.Optional()),s(3,c.Self()),s(3,c.Inject(h.NG_VALUE_ACCESSOR)),o("design:paramtypes",[p.ControlContainer,Array,Array,Array])],e)}(l.NgControl);e.NgControlName=y},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(114),o=n(12),s=function(t){function e(){t.apply(this,arguments),this.name=null,this.valueAccessor=null}return r(e,t),Object.defineProperty(e.prototype,"validator",{get:function(){return o.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return o.unimplemented()},enumerable:!0,configurable:!0}),e}(i.AbstractControlDirective);e.NgControl=s},function(t,e,n){"use strict";var r=n(2),i=n(5);e.NG_VALUE_ACCESSOR=i.CONST_EXPR(new r.OpaqueToken("NgValueAccessor"))},function(t,e,n){"use strict";function r(t,e){var n=l.ListWrapper.clone(e.path);return n.push(t),n}function i(t,e){h.isBlank(t)&&s(e,"Cannot find control"),h.isBlank(e.valueAccessor)&&s(e,"No value accessor for"),t.validator=d.Validators.compose([t.validator,e.validator]),t.asyncValidator=d.Validators.composeAsync([t.asyncValidator,e.asyncValidator]),e.valueAccessor.writeValue(t.value),e.valueAccessor.registerOnChange(function(n){e.viewToModelUpdate(n),t.updateValue(n,{emitModelToViewChange:!1}),t.markAsDirty()}),t.registerOnChange(function(t){return e.valueAccessor.writeValue(t)}),e.valueAccessor.registerOnTouched(function(){return t.markAsTouched()})}function o(t,e){h.isBlank(t)&&s(e,"Cannot find control"),t.validator=d.Validators.compose([t.validator,e.validator]),t.asyncValidator=d.Validators.composeAsync([t.asyncValidator,e.asyncValidator])}function s(t,e){var n=t.path.join(" -> ");throw new f.BaseException(e+" '"+n+"'")}function a(t){return h.isPresent(t)?d.Validators.compose(t.map(b.normalizeValidator)):null}function u(t){return h.isPresent(t)?d.Validators.composeAsync(t.map(b.normalizeAsyncValidator)):null}function c(t,e){if(!l.StringMapWrapper.contains(t,"model"))return!1;var n=t.model;return n.isFirstChange()?!0:!h.looseIdentical(e,n.currentValue)}function p(t,e){if(h.isBlank(e))return null;var n,r,i;return e.forEach(function(e){h.hasConstructor(e,v.DefaultValueAccessor)?n=e:h.hasConstructor(e,m.CheckboxControlValueAccessor)||h.hasConstructor(e,y.NumberValueAccessor)||h.hasConstructor(e,g.SelectControlValueAccessor)||h.hasConstructor(e,_.RadioControlValueAccessor)?(h.isPresent(r)&&s(t,"More than one built-in value accessor matches"),r=e):(h.isPresent(i)&&s(t,"More than one custom value accessor matches"),i=e)}),h.isPresent(i)?i:h.isPresent(r)?r:h.isPresent(n)?n:(s(t,"No valid value accessor for"),null)}var l=n(15),h=n(5),f=n(12),d=n(120),v=n(121),y=n(122),m=n(123),g=n(124),_=n(125),b=n(126);e.controlPath=r,e.setUpControl=i,e.setUpControlGroup=o,e.composeValidators=a,e.composeAsyncValidators=u,e.isPropertyUpdated=c,e.selectValueAccessor=p},function(t,e,n){"use strict";function r(t){return u.PromiseWrapper.isPromise(t)?t:c.ObservableWrapper.toPromise(t)}function i(t,e){return e.map(function(e){return e(t)})}function o(t,e){return e.map(function(e){return e(t)})}function s(t){var e=t.reduce(function(t,e){return a.isPresent(e)?p.StringMapWrapper.merge(t,e):t},{});return p.StringMapWrapper.isEmpty(e)?null:e}var a=n(5),u=n(41),c=n(40),p=n(15),l=n(2);e.NG_VALIDATORS=a.CONST_EXPR(new l.OpaqueToken("NgValidators")),e.NG_ASYNC_VALIDATORS=a.CONST_EXPR(new l.OpaqueToken("NgAsyncValidators"));var h=function(){function t(){}return t.required=function(t){return a.isBlank(t.value)||a.isString(t.value)&&""==t.value?{required:!0}:null},t.minLength=function(e){return function(n){if(a.isPresent(t.required(n)))return null;var r=n.value;return r.length<e?{minlength:{requiredLength:e,actualLength:r.length}}:null}},t.maxLength=function(e){return function(n){if(a.isPresent(t.required(n)))return null;var r=n.value;return r.length>e?{maxlength:{requiredLength:e,actualLength:r.length}}:null}},t.pattern=function(e){return function(n){if(a.isPresent(t.required(n)))return null;var r=new RegExp("^"+e+"$"),i=n.value;return r.test(i)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:i}}}},t.nullValidator=function(t){return null},t.compose=function(t){if(a.isBlank(t))return null;var e=t.filter(a.isPresent);return 0==e.length?null:function(t){return s(i(t,e))}},t.composeAsync=function(t){if(a.isBlank(t))return null;var e=t.filter(a.isPresent);return 0==e.length?null:function(t){var n=o(t,e).map(r);return u.PromiseWrapper.all(n).then(s)}},t}();e.Validators=h},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(118),a=n(5),u=a.CONST_EXPR(new o.Provider(s.NG_VALUE_ACCESSOR,{useExisting:o.forwardRef(function(){return c}),multi:!0})),c=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){var e=a.isBlank(t)?"":t;this._renderer.setElementProperty(this._elementRef.nativeElement,"value",e)},t.prototype.registerOnChange=function(t){this.onChange=t},t.prototype.registerOnTouched=function(t){this.onTouched=t},t=r([o.Directive({selector:"input:not([type=checkbox])[ngControl],textarea[ngControl],input:not([type=checkbox])[ngFormControl],textarea[ngFormControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]",
                +host:{"(input)":"onChange($event.target.value)","(blur)":"onTouched()"},bindings:[u]}),i("design:paramtypes",[o.Renderer,o.ElementRef])],t)}();e.DefaultValueAccessor=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(118),a=n(5),u=a.CONST_EXPR(new o.Provider(s.NG_VALUE_ACCESSOR,{useExisting:o.forwardRef(function(){return c}),multi:!0})),c=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this._renderer.setElementProperty(this._elementRef.nativeElement,"value",t)},t.prototype.registerOnChange=function(t){this.onChange=function(e){t(""==e?null:a.NumberWrapper.parseFloat(e))}},t.prototype.registerOnTouched=function(t){this.onTouched=t},t=r([o.Directive({selector:"input[type=number][ngControl],input[type=number][ngFormControl],input[type=number][ngModel]",host:{"(change)":"onChange($event.target.value)","(input)":"onChange($event.target.value)","(blur)":"onTouched()"},bindings:[u]}),i("design:paramtypes",[o.Renderer,o.ElementRef])],t)}();e.NumberValueAccessor=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(118),a=n(5),u=a.CONST_EXPR(new o.Provider(s.NG_VALUE_ACCESSOR,{useExisting:o.forwardRef(function(){return c}),multi:!0})),c=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this._renderer.setElementProperty(this._elementRef.nativeElement,"checked",t)},t.prototype.registerOnChange=function(t){this.onChange=t},t.prototype.registerOnTouched=function(t){this.onTouched=t},t=r([o.Directive({selector:"input[type=checkbox][ngControl],input[type=checkbox][ngFormControl],input[type=checkbox][ngModel]",host:{"(change)":"onChange($event.target.checked)","(blur)":"onTouched()"},providers:[u]}),i("design:paramtypes",[o.Renderer,o.ElementRef])],t)}();e.CheckboxControlValueAccessor=c},function(t,e,n){"use strict";function r(t,e){return p.isBlank(t)?""+e:(p.isPrimitive(e)||(e="Object"),p.StringWrapper.slice(t+": "+e,0,50))}function i(t){return t.split(":")[0]}var o=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},s=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},a=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},u=n(2),c=n(118),p=n(5),l=n(15),h=p.CONST_EXPR(new u.Provider(c.NG_VALUE_ACCESSOR,{useExisting:u.forwardRef(function(){return f}),multi:!0})),f=function(){function t(t,e){this._renderer=t,this._elementRef=e,this._optionMap=new Map,this._idCounter=0,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this.value=t;var e=r(this._getOptionId(t),t);this._renderer.setElementProperty(this._elementRef.nativeElement,"value",e)},t.prototype.registerOnChange=function(t){var e=this;this.onChange=function(n){t(e._getOptionValue(n))}},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype._registerOption=function(){return(this._idCounter++).toString()},t.prototype._getOptionId=function(t){for(var e=0,n=l.MapWrapper.keys(this._optionMap);e<n.length;e++){var r=n[e];if(p.looseIdentical(this._optionMap.get(r),t))return r}return null},t.prototype._getOptionValue=function(t){var e=this._optionMap.get(i(t));return p.isPresent(e)?e:t},t=o([u.Directive({selector:"select[ngControl],select[ngFormControl],select[ngModel]",host:{"(change)":"onChange($event.target.value)","(blur)":"onTouched()"},providers:[h]}),s("design:paramtypes",[u.Renderer,u.ElementRef])],t)}();e.SelectControlValueAccessor=f;var d=function(){function t(t,e,n){this._element=t,this._renderer=e,this._select=n,p.isPresent(this._select)&&(this.id=this._select._registerOption())}return Object.defineProperty(t.prototype,"ngValue",{set:function(t){null!=this._select&&(this._select._optionMap.set(this.id,t),this._setElementValue(r(this.id,t)),this._select.writeValue(this._select.value))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{set:function(t){this._setElementValue(t),p.isPresent(this._select)&&this._select.writeValue(this._select.value)},enumerable:!0,configurable:!0}),t.prototype._setElementValue=function(t){this._renderer.setElementProperty(this._element.nativeElement,"value",t)},t.prototype.ngOnDestroy=function(){p.isPresent(this._select)&&(this._select._optionMap["delete"](this.id),this._select.writeValue(this._select.value))},o([u.Input("ngValue"),s("design:type",Object),s("design:paramtypes",[Object])],t.prototype,"ngValue",null),o([u.Input("value"),s("design:type",Object),s("design:paramtypes",[Object])],t.prototype,"value",null),t=o([u.Directive({selector:"option"}),a(2,u.Optional()),a(2,u.Host()),s("design:paramtypes",[u.ElementRef,u.Renderer,f])],t)}();e.NgSelectOption=d},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(118),a=n(117),u=n(5),c=n(15),p=u.CONST_EXPR(new o.Provider(s.NG_VALUE_ACCESSOR,{useExisting:o.forwardRef(function(){return f}),multi:!0})),l=function(){function t(){this._accessors=[]}return t.prototype.add=function(t,e){this._accessors.push([t,e])},t.prototype.remove=function(t){for(var e=-1,n=0;n<this._accessors.length;++n)this._accessors[n][1]===t&&(e=n);c.ListWrapper.removeAt(this._accessors,e)},t.prototype.select=function(t){this._accessors.forEach(function(e){e[0].control.root===t._control.control.root&&e[1]!==t&&e[1].fireUncheck()})},t=r([o.Injectable(),i("design:paramtypes",[])],t)}();e.RadioControlRegistry=l;var h=function(){function t(t,e){this.checked=t,this.value=e}return t}();e.RadioButtonState=h;var f=function(){function t(t,e,n,r){this._renderer=t,this._elementRef=e,this._registry=n,this._injector=r,this.onChange=function(){},this.onTouched=function(){}}return t.prototype.ngOnInit=function(){this._control=this._injector.get(a.NgControl),this._registry.add(this._control,this)},t.prototype.ngOnDestroy=function(){this._registry.remove(this)},t.prototype.writeValue=function(t){this._state=t,u.isPresent(t)&&t.checked&&this._renderer.setElementProperty(this._elementRef.nativeElement,"checked",!0)},t.prototype.registerOnChange=function(t){var e=this;this._fn=t,this.onChange=function(){t(new h(!0,e._state.value)),e._registry.select(e)}},t.prototype.fireUncheck=function(){this._fn(new h(!1,this._state.value))},t.prototype.registerOnTouched=function(t){this.onTouched=t},r([o.Input(),i("design:type",String)],t.prototype,"name",void 0),t=r([o.Directive({selector:"input[type=radio][ngControl],input[type=radio][ngFormControl],input[type=radio][ngModel]",host:{"(change)":"onChange()","(blur)":"onTouched()"},providers:[p]}),i("design:paramtypes",[o.Renderer,o.ElementRef,l,o.Injector])],t)}();e.RadioControlValueAccessor=f},function(t,e){"use strict";function n(t){return void 0!==t.validate?function(e){return t.validate(e)}:t}function r(t){return void 0!==t.validate?function(e){return Promise.resolve(t.validate(e))}:t}e.normalizeValidator=n,e.normalizeAsyncValidator=r},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(5),u=n(15),c=n(40),p=n(2),l=n(117),h=n(120),f=n(118),d=n(119),v=a.CONST_EXPR(new p.Provider(l.NgControl,{useExisting:p.forwardRef(function(){return y})})),y=function(t){function e(e,n,r){t.call(this),this._validators=e,this._asyncValidators=n,this.update=new c.EventEmitter,this.valueAccessor=d.selectValueAccessor(this,r)}return r(e,t),e.prototype.ngOnChanges=function(t){this._isControlChanged(t)&&(d.setUpControl(this.form,this),this.form.updateValueAndValidity({emitEvent:!1})),d.isPropertyUpdated(t,this.viewModel)&&(this.form.updateValue(this.model),this.viewModel=this.model)},Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return d.composeValidators(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return d.composeAsyncValidators(this._asyncValidators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),e.prototype.viewToModelUpdate=function(t){this.viewModel=t,c.ObservableWrapper.callEmit(this.update,t)},e.prototype._isControlChanged=function(t){return u.StringMapWrapper.contains(t,"form")},e=i([p.Directive({selector:"[ngFormControl]",bindings:[v],inputs:["form: ngFormControl","model: ngModel"],outputs:["update: ngModelChange"],exportAs:"ngForm"}),s(0,p.Optional()),s(0,p.Self()),s(0,p.Inject(h.NG_VALIDATORS)),s(1,p.Optional()),s(1,p.Self()),s(1,p.Inject(h.NG_ASYNC_VALIDATORS)),s(2,p.Optional()),s(2,p.Self()),s(2,p.Inject(f.NG_VALUE_ACCESSOR)),o("design:paramtypes",[Array,Array,Array])],e)}(l.NgControl);e.NgFormControl=y},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(5),u=n(40),c=n(2),p=n(118),l=n(117),h=n(113),f=n(120),d=n(119),v=a.CONST_EXPR(new c.Provider(l.NgControl,{useExisting:c.forwardRef(function(){return y})})),y=function(t){function e(e,n,r){t.call(this),this._validators=e,this._asyncValidators=n,this._control=new h.Control,this._added=!1,this.update=new u.EventEmitter,this.valueAccessor=d.selectValueAccessor(this,r)}return r(e,t),e.prototype.ngOnChanges=function(t){this._added||(d.setUpControl(this._control,this),this._control.updateValueAndValidity({emitEvent:!1}),this._added=!0),d.isPropertyUpdated(t,this.viewModel)&&(this._control.updateValue(this.model),this.viewModel=this.model)},Object.defineProperty(e.prototype,"control",{get:function(){return this._control},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return d.composeValidators(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return d.composeAsyncValidators(this._asyncValidators)},enumerable:!0,configurable:!0}),e.prototype.viewToModelUpdate=function(t){this.viewModel=t,u.ObservableWrapper.callEmit(this.update,t)},e=i([c.Directive({selector:"[ngModel]:not([ngControl]):not([ngFormControl])",bindings:[v],inputs:["model: ngModel"],outputs:["update: ngModelChange"],exportAs:"ngForm"}),s(0,c.Optional()),s(0,c.Self()),s(0,c.Inject(f.NG_VALIDATORS)),s(1,c.Optional()),s(1,c.Self()),s(1,c.Inject(f.NG_ASYNC_VALIDATORS)),s(2,c.Optional()),s(2,c.Self()),s(2,c.Inject(p.NG_VALUE_ACCESSOR)),o("design:paramtypes",[Array,Array,Array])],e)}(l.NgControl);e.NgModel=y},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(2),u=n(5),c=n(115),p=n(119),l=n(120),h=u.CONST_EXPR(new a.Provider(c.ControlContainer,{useExisting:a.forwardRef(function(){return f})})),f=function(t){function e(e,n,r){t.call(this),this._validators=n,this._asyncValidators=r,this._parent=e}return r(e,t),e.prototype.ngOnInit=function(){this.formDirective.addControlGroup(this)},e.prototype.ngOnDestroy=function(){this.formDirective.removeControlGroup(this)},Object.defineProperty(e.prototype,"control",{get:function(){return this.formDirective.getControlGroup(this)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return p.controlPath(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent.formDirective},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return p.composeValidators(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return p.composeAsyncValidators(this._asyncValidators)},enumerable:!0,configurable:!0}),e=i([a.Directive({selector:"[ngControlGroup]",providers:[h],inputs:["name: ngControlGroup"],exportAs:"ngForm"}),s(0,a.Host()),s(0,a.SkipSelf()),s(1,a.Optional()),s(1,a.Self()),s(1,a.Inject(l.NG_VALIDATORS)),s(2,a.Optional()),s(2,a.Self()),s(2,a.Inject(l.NG_ASYNC_VALIDATORS)),o("design:paramtypes",[c.ControlContainer,Array,Array])],e)}(c.ControlContainer);e.NgControlGroup=f},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(5),u=n(15),c=n(12),p=n(40),l=n(2),h=n(115),f=n(119),d=n(120),v=a.CONST_EXPR(new l.Provider(h.ControlContainer,{useExisting:l.forwardRef(function(){return y})})),y=function(t){function e(e,n){t.call(this),this._validators=e,this._asyncValidators=n,this.form=null,this.directives=[],this.ngSubmit=new p.EventEmitter}return r(e,t),e.prototype.ngOnChanges=function(t){if(this._checkFormPresent(),u.StringMapWrapper.contains(t,"form")){var e=f.composeValidators(this._validators);this.form.validator=d.Validators.compose([this.form.validator,e]);var n=f.composeAsyncValidators(this._asyncValidators);this.form.asyncValidator=d.Validators.composeAsync([this.form.asyncValidator,n]),this.form.updateValueAndValidity({onlySelf:!0,emitEvent:!1})}this._updateDomValue()},Object.defineProperty(e.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),e.prototype.addControl=function(t){var e=this.form.find(t.path);f.setUpControl(e,t),e.updateValueAndValidity({emitEvent:!1}),this.directives.push(t)},e.prototype.getControl=function(t){return this.form.find(t.path)},e.prototype.removeControl=function(t){u.ListWrapper.remove(this.directives,t)},e.prototype.addControlGroup=function(t){var e=this.form.find(t.path);f.setUpControlGroup(e,t),e.updateValueAndValidity({emitEvent:!1})},e.prototype.removeControlGroup=function(t){},e.prototype.getControlGroup=function(t){return this.form.find(t.path)},e.prototype.updateModel=function(t,e){var n=this.form.find(t.path);n.updateValue(e)},e.prototype.onSubmit=function(){return p.ObservableWrapper.callEmit(this.ngSubmit,null),!1},e.prototype._updateDomValue=function(){var t=this;this.directives.forEach(function(e){var n=t.form.find(e.path);e.valueAccessor.writeValue(n.value)})},e.prototype._checkFormPresent=function(){if(a.isBlank(this.form))throw new c.BaseException('ngFormModel expects a form. Please pass one in. Example: <form [ngFormModel]="myCoolForm">')},e=i([l.Directive({selector:"[ngFormModel]",bindings:[v],inputs:["form: ngFormModel"],host:{"(submit)":"onSubmit()"},outputs:["ngSubmit"],exportAs:"ngForm"}),s(0,l.Optional()),s(0,l.Self()),s(0,l.Inject(d.NG_VALIDATORS)),s(1,l.Optional()),s(1,l.Self()),s(1,l.Inject(d.NG_ASYNC_VALIDATORS)),o("design:paramtypes",[Array,Array])],e)}(h.ControlContainer);e.NgFormModel=y},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(40),u=n(15),c=n(5),p=n(2),l=n(115),h=n(113),f=n(119),d=n(120),v=c.CONST_EXPR(new p.Provider(l.ControlContainer,{useExisting:p.forwardRef(function(){return y})})),y=function(t){function e(e,n){t.call(this),this.ngSubmit=new a.EventEmitter,this.form=new h.ControlGroup({},null,f.composeValidators(e),f.composeAsyncValidators(n))}return r(e,t),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"controls",{get:function(){return this.form.controls},enumerable:!0,configurable:!0}),e.prototype.addControl=function(t){var e=this;a.PromiseWrapper.scheduleMicrotask(function(){var n=e._findContainer(t.path),r=new h.Control;f.setUpControl(r,t),n.addControl(t.name,r),r.updateValueAndValidity({emitEvent:!1})})},e.prototype.getControl=function(t){return this.form.find(t.path)},e.prototype.removeControl=function(t){var e=this;a.PromiseWrapper.scheduleMicrotask(function(){var n=e._findContainer(t.path);c.isPresent(n)&&(n.removeControl(t.name),n.updateValueAndValidity({emitEvent:!1}))})},e.prototype.addControlGroup=function(t){var e=this;a.PromiseWrapper.scheduleMicrotask(function(){var n=e._findContainer(t.path),r=new h.ControlGroup({});f.setUpControlGroup(r,t),n.addControl(t.name,r),r.updateValueAndValidity({emitEvent:!1})})},e.prototype.removeControlGroup=function(t){var e=this;a.PromiseWrapper.scheduleMicrotask(function(){var n=e._findContainer(t.path);c.isPresent(n)&&(n.removeControl(t.name),n.updateValueAndValidity({emitEvent:!1}))})},e.prototype.getControlGroup=function(t){return this.form.find(t.path)},e.prototype.updateModel=function(t,e){var n=this;a.PromiseWrapper.scheduleMicrotask(function(){var r=n.form.find(t.path);r.updateValue(e)})},e.prototype.onSubmit=function(){return a.ObservableWrapper.callEmit(this.ngSubmit,null),!1},e.prototype._findContainer=function(t){return t.pop(),u.ListWrapper.isEmpty(t)?this.form:this.form.find(t)},e=i([p.Directive({selector:"form:not([ngNoForm]):not([ngFormModel]),ngForm,[ngForm]",bindings:[v],host:{"(submit)":"onSubmit()"},outputs:["ngSubmit"],exportAs:"ngForm"}),s(0,p.Optional()),s(0,p.Self()),s(0,p.Inject(d.NG_VALIDATORS)),s(1,p.Optional()),s(1,p.Self()),s(1,p.Inject(d.NG_ASYNC_VALIDATORS)),o("design:paramtypes",[Array,Array])],e)}(l.ControlContainer);e.NgForm=y},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(2),a=n(117),u=n(5),c=function(){function t(t){this._cd=t}return Object.defineProperty(t.prototype,"ngClassUntouched",{get:function(){return u.isPresent(this._cd.control)?this._cd.control.untouched:!1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassTouched",{get:function(){return u.isPresent(this._cd.control)?this._cd.control.touched:!1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassPristine",{get:function(){return u.isPresent(this._cd.control)?this._cd.control.pristine:!1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassDirty",{get:function(){return u.isPresent(this._cd.control)?this._cd.control.dirty:!1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassValid",{get:function(){return u.isPresent(this._cd.control)?this._cd.control.valid:!1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassInvalid",{get:function(){return u.isPresent(this._cd.control)?!this._cd.control.valid:!1},enumerable:!0,configurable:!0}),t=r([s.Directive({selector:"[ngControl],[ngModel],[ngFormControl]",host:{"[class.ng-untouched]":"ngClassUntouched","[class.ng-touched]":"ngClassTouched","[class.ng-pristine]":"ngClassPristine","[class.ng-dirty]":"ngClassDirty","[class.ng-valid]":"ngClassValid","[class.ng-invalid]":"ngClassInvalid"}}),o(0,s.Self()),i("design:paramtypes",[a.NgControl])],t)}();e.NgControlStatus=c},function(t,e,n){"use strict";var r=n(5),i=n(116),o=n(127),s=n(128),a=n(129),u=n(130),c=n(131),p=n(121),l=n(123),h=n(122),f=n(125),d=n(132),v=n(124),y=n(134),m=n(116);e.NgControlName=m.NgControlName;var g=n(127);e.NgFormControl=g.NgFormControl;var _=n(128);e.NgModel=_.NgModel;var b=n(129);e.NgControlGroup=b.NgControlGroup;var P=n(130);e.NgFormModel=P.NgFormModel;var E=n(131);e.NgForm=E.NgForm;var w=n(121);e.DefaultValueAccessor=w.DefaultValueAccessor;var C=n(123);e.CheckboxControlValueAccessor=C.CheckboxControlValueAccessor;var R=n(125);e.RadioControlValueAccessor=R.RadioControlValueAccessor,e.RadioButtonState=R.RadioButtonState;var S=n(122);e.NumberValueAccessor=S.NumberValueAccessor;var O=n(132);e.NgControlStatus=O.NgControlStatus;var T=n(124);e.SelectControlValueAccessor=T.SelectControlValueAccessor,e.NgSelectOption=T.NgSelectOption;var x=n(134);e.RequiredValidator=x.RequiredValidator,e.MinLengthValidator=x.MinLengthValidator,e.MaxLengthValidator=x.MaxLengthValidator,e.PatternValidator=x.PatternValidator;var A=n(117);e.NgControl=A.NgControl,e.FORM_DIRECTIVES=r.CONST_EXPR([i.NgControlName,a.NgControlGroup,o.NgFormControl,s.NgModel,u.NgFormModel,c.NgForm,v.NgSelectOption,p.DefaultValueAccessor,h.NumberValueAccessor,l.CheckboxControlValueAccessor,v.SelectControlValueAccessor,f.RadioControlValueAccessor,d.NgControlStatus,y.RequiredValidator,y.MinLengthValidator,y.MaxLengthValidator,y.PatternValidator])},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(2),a=n(5),u=n(120),c=n(5),p=u.Validators.required,l=a.CONST_EXPR(new s.Provider(u.NG_VALIDATORS,{useValue:p,multi:!0})),h=function(){function t(){}return t=r([s.Directive({selector:"[required][ngControl],[required][ngFormControl],[required][ngModel]",providers:[l]}),i("design:paramtypes",[])],t)}();e.RequiredValidator=h;var f=a.CONST_EXPR(new s.Provider(u.NG_VALIDATORS,{useExisting:s.forwardRef(function(){return d}),multi:!0})),d=function(){function t(t){this._validator=u.Validators.minLength(c.NumberWrapper.parseInt(t,10))}return t.prototype.validate=function(t){return this._validator(t)},t=r([s.Directive({selector:"[minlength][ngControl],[minlength][ngFormControl],[minlength][ngModel]",providers:[f]}),o(0,s.Attribute("minlength")),i("design:paramtypes",[String])],t)}();e.MinLengthValidator=d;var v=a.CONST_EXPR(new s.Provider(u.NG_VALIDATORS,{useExisting:s.forwardRef(function(){return y}),multi:!0})),y=function(){function t(t){this._validator=u.Validators.maxLength(c.NumberWrapper.parseInt(t,10))}return t.prototype.validate=function(t){return this._validator(t)},t=r([s.Directive({selector:"[maxlength][ngControl],[maxlength][ngFormControl],[maxlength][ngModel]",providers:[v]}),o(0,s.Attribute("maxlength")),i("design:paramtypes",[String])],t)}();e.MaxLengthValidator=y;var m=a.CONST_EXPR(new s.Provider(u.NG_VALIDATORS,{useExisting:s.forwardRef(function(){return g}),multi:!0})),g=function(){function t(t){this._validator=u.Validators.pattern(t)}return t.prototype.validate=function(t){return this._validator(t)},t=r([s.Directive({selector:"[pattern][ngControl],[pattern][ngFormControl],[pattern][ngModel]",providers:[m]}),o(0,s.Attribute("pattern")),i("design:paramtypes",[String])],t)}();e.PatternValidator=g},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(15),a=n(5),u=n(113),c=function(){function t(){}return t.prototype.group=function(t,e){void 0===e&&(e=null);var n=this._reduceControls(t),r=a.isPresent(e)?s.StringMapWrapper.get(e,"optionals"):null,i=a.isPresent(e)?s.StringMapWrapper.get(e,"validator"):null,o=a.isPresent(e)?s.StringMapWrapper.get(e,"asyncValidator"):null;return new u.ControlGroup(n,r,i,o)},t.prototype.control=function(t,e,n){return void 0===e&&(e=null),void 0===n&&(n=null),new u.Control(t,e,n)},t.prototype.array=function(t,e,n){var r=this;void 0===e&&(e=null),void 0===n&&(n=null);var i=t.map(function(t){return r._createControl(t)});return new u.ControlArray(i,e,n)},t.prototype._reduceControls=function(t){var e=this,n={};return s.StringMapWrapper.forEach(t,function(t,r){n[r]=e._createControl(t)}),n},t.prototype._createControl=function(t){if(t instanceof u.Control||t instanceof u.ControlGroup||t instanceof u.ControlArray)return t;if(a.isArray(t)){var e=t[0],n=t.length>1?t[1]:null,r=t.length>2?t[2]:null;return this.control(e,n,r)}return this.control(t)},t=r([o.Injectable(),i("design:paramtypes",[])],t)}();e.FormBuilder=c},function(t,e,n){"use strict";var r=n(5),i=n(112),o=n(102);e.COMMON_DIRECTIVES=r.CONST_EXPR([o.CORE_DIRECTIVES,i.FORM_DIRECTIVES])},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}var i=n(138);e.PLATFORM_DIRECTIVES=i.PLATFORM_DIRECTIVES,e.PLATFORM_PIPES=i.PLATFORM_PIPES,e.COMPILER_PROVIDERS=i.COMPILER_PROVIDERS,e.TEMPLATE_TRANSFORMS=i.TEMPLATE_TRANSFORMS,e.CompilerConfig=i.CompilerConfig,e.RenderTypes=i.RenderTypes,e.UrlResolver=i.UrlResolver,e.DEFAULT_PACKAGE_URL_PROVIDER=i.DEFAULT_PACKAGE_URL_PROVIDER,e.createOfflineCompileUrlResolver=i.createOfflineCompileUrlResolver,e.XHR=i.XHR,e.ViewResolver=i.ViewResolver,e.DirectiveResolver=i.DirectiveResolver,e.PipeResolver=i.PipeResolver,e.SourceModule=i.SourceModule,e.NormalizedComponentWithViewDirectives=i.NormalizedComponentWithViewDirectives,e.OfflineCompiler=i.OfflineCompiler,e.CompileMetadataWithIdentifier=i.CompileMetadataWithIdentifier,e.CompileMetadataWithType=i.CompileMetadataWithType,e.CompileIdentifierMetadata=i.CompileIdentifierMetadata,e.CompileDiDependencyMetadata=i.CompileDiDependencyMetadata,e.CompileProviderMetadata=i.CompileProviderMetadata,e.CompileFactoryMetadata=i.CompileFactoryMetadata,e.CompileTokenMetadata=i.CompileTokenMetadata,e.CompileTypeMetadata=i.CompileTypeMetadata,e.CompileQueryMetadata=i.CompileQueryMetadata,e.CompileTemplateMetadata=i.CompileTemplateMetadata,e.CompileDirectiveMetadata=i.CompileDirectiveMetadata,e.CompilePipeMetadata=i.CompilePipeMetadata,r(n(139))},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}function i(){return new b.CompilerConfig(h.assertionsEnabled(),!1,!0)}var o=n(84);e.PLATFORM_DIRECTIVES=o.PLATFORM_DIRECTIVES,e.PLATFORM_PIPES=o.PLATFORM_PIPES,r(n(139));var s=n(140);e.TEMPLATE_TRANSFORMS=s.TEMPLATE_TRANSFORMS;var a=n(162);e.CompilerConfig=a.CompilerConfig,e.RenderTypes=a.RenderTypes,r(n(155)),r(n(163));var u=n(165);e.RuntimeCompiler=u.RuntimeCompiler,r(n(157)),r(n(184));var c=n(188);e.ViewResolver=c.ViewResolver;var p=n(186);
                +e.DirectiveResolver=p.DirectiveResolver;var l=n(187);e.PipeResolver=l.PipeResolver;var h=n(5),f=n(6),d=n(140),v=n(144),y=n(183),m=n(185),g=n(166),_=n(168),b=n(162),P=n(64),E=n(165),w=n(150),C=n(199),R=n(157),S=n(142),O=n(143),T=n(188),x=n(186),A=n(187);e.COMPILER_PROVIDERS=h.CONST_EXPR([O.Lexer,S.Parser,v.HtmlParser,d.TemplateParser,y.DirectiveNormalizer,m.RuntimeMetadataResolver,R.DEFAULT_PACKAGE_URL_PROVIDER,g.StyleCompiler,_.ViewCompiler,new f.Provider(b.CompilerConfig,{useFactory:i,deps:[]}),E.RuntimeCompiler,new f.Provider(P.ComponentResolver,{useExisting:E.RuntimeCompiler}),C.DomElementSchemaRegistry,new f.Provider(w.ElementSchemaRegistry,{useExisting:C.DomElementSchemaRegistry}),R.UrlResolver,T.ViewResolver,x.DirectiveResolver,A.PipeResolver])},function(t,e,n){"use strict";function r(t,e,n){void 0===n&&(n=null);var r=[];return e.forEach(function(e){var o=e.visit(t,n);i.isPresent(o)&&r.push(o)}),r}var i=n(5),o=function(){function t(t,e,n){this.value=t,this.ngContentIndex=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitText(this,e)},t}();e.TextAst=o;var s=function(){function t(t,e,n){this.value=t,this.ngContentIndex=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitBoundText(this,e)},t}();e.BoundTextAst=s;var a=function(){function t(t,e,n){this.name=t,this.value=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitAttr(this,e)},t}();e.AttrAst=a;var u=function(){function t(t,e,n,r,i){this.name=t,this.type=e,this.value=n,this.unit=r,this.sourceSpan=i}return t.prototype.visit=function(t,e){return t.visitElementProperty(this,e)},t}();e.BoundElementPropertyAst=u;var c=function(){function t(t,e,n,r){this.name=t,this.target=e,this.handler=n,this.sourceSpan=r}return t.prototype.visit=function(t,e){return t.visitEvent(this,e)},Object.defineProperty(t.prototype,"fullName",{get:function(){return i.isPresent(this.target)?this.target+":"+this.name:this.name},enumerable:!0,configurable:!0}),t}();e.BoundEventAst=c;var p=function(){function t(t,e,n){this.name=t,this.value=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitVariable(this,e)},t}();e.VariableAst=p;var l=function(){function t(t,e,n,r,i,o,s,a,u,c,p){this.name=t,this.attrs=e,this.inputs=n,this.outputs=r,this.exportAsVars=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=u,this.ngContentIndex=c,this.sourceSpan=p}return t.prototype.visit=function(t,e){return t.visitElement(this,e)},t.prototype.isBound=function(){return this.inputs.length>0||this.outputs.length>0||this.exportAsVars.length>0||this.directives.length>0},t.prototype.getComponent=function(){for(var t=0;t<this.directives.length;t++){var e=this.directives[t];if(e.directive.isComponent)return e.directive}return null},t}();e.ElementAst=l;var h=function(){function t(t,e,n,r,i,o,s,a,u){this.attrs=t,this.outputs=e,this.vars=n,this.directives=r,this.providers=i,this.hasViewContainer=o,this.children=s,this.ngContentIndex=a,this.sourceSpan=u}return t.prototype.visit=function(t,e){return t.visitEmbeddedTemplate(this,e)},t}();e.EmbeddedTemplateAst=h;var f=function(){function t(t,e,n,r){this.directiveName=t,this.templateName=e,this.value=n,this.sourceSpan=r}return t.prototype.visit=function(t,e){return t.visitDirectiveProperty(this,e)},t}();e.BoundDirectivePropertyAst=f;var d=function(){function t(t,e,n,r,i,o){this.directive=t,this.inputs=e,this.hostProperties=n,this.hostEvents=r,this.exportAsVars=i,this.sourceSpan=o}return t.prototype.visit=function(t,e){return t.visitDirective(this,e)},t}();e.DirectiveAst=d;var v=function(){function t(t,e,n,r,i,o){this.token=t,this.multiProvider=e,this.eager=n,this.providers=r,this.providerType=i,this.sourceSpan=o}return t.prototype.visit=function(t,e){return null},t}();e.ProviderAst=v,function(t){t[t.PublicService=0]="PublicService",t[t.PrivateService=1]="PrivateService",t[t.Component=2]="Component",t[t.Directive=3]="Directive",t[t.Builtin=4]="Builtin"}(e.ProviderAstType||(e.ProviderAstType={}));var y=(e.ProviderAstType,function(){function t(t,e,n){this.index=t,this.ngContentIndex=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitNgContent(this,e)},t}());e.NgContentAst=y,function(t){t[t.Property=0]="Property",t[t.Attribute=1]="Attribute",t[t.Class=2]="Class",t[t.Style=3]="Style"}(e.PropertyBindingType||(e.PropertyBindingType={}));e.PropertyBindingType;e.templateVisitAll=r},function(t,e,n){"use strict";function r(t){return l.StringWrapper.split(t.trim(),/\s+/g)}function i(t,e){var n=new E.CssSelector,i=g.splitNsName(t)[1];n.setElement(i);for(var o=0;o<e.length;o++){var s=e[o][0],a=g.splitNsName(s)[1],u=e[o][1];if(n.addAttribute(a,u),s.toLowerCase()==k){var c=r(u);c.forEach(function(t){return n.addClassName(t)})}}return n}function o(t){var e=[];return t.forEach(function(t){var n=e.filter(function(e){return e.type.name==t.type.name&&e.type.moduleUrl==t.type.moduleUrl&&e.type.runtime==t.type.runtime}).length>0;n||e.push(t)}),e}var s=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},a=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},u=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},c=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},p=n(15),l=n(5),h=n(2),f=n(5),d=n(12),v=n(141),y=n(142),m=n(144),g=n(148),_=n(147),b=n(66),P=n(139),E=n(149),w=n(150),C=n(151),R=n(152),S=n(145),O=n(153),T=n(154),x=/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g,A="template",I="template",M="*",k="class",N=".",D="attr",V="class",j="style",L=E.CssSelector.parse("*")[0];e.TEMPLATE_TRANSFORMS=f.CONST_EXPR(new h.OpaqueToken("TemplateTransforms"));var B=function(t){function e(e,n){t.call(this,n,e)}return s(e,t),e}(_.ParseError);e.TemplateParseError=B;var F=function(){function t(t,e){this.templateAst=t,this.errors=e}return t}();e.TemplateParseResult=F;var U=function(){function t(t,e,n,r){this._exprParser=t,this._schemaRegistry=e,this._htmlParser=n,this.transforms=r}return t.prototype.parse=function(t,e,n,r,i){var o=this.tryParse(t,e,n,r,i);if(l.isPresent(o.errors)){var s=o.errors.join("\n");throw new d.BaseException("Template parse errors:\n"+s)}return o.templateAst},t.prototype.tryParse=function(t,e,n,r,i){var s,a=this._htmlParser.parse(e,i),u=a.errors;if(a.rootNodes.length>0){var c=o(n),p=o(r),h=new T.ProviderViewContext(t,a.rootNodes[0].sourceSpan),f=new W(h,c,p,this._exprParser,this._schemaRegistry);s=S.htmlVisitAll(f,a.rootNodes,G),u=u.concat(f.errors).concat(h.errors)}else s=[];return u.length>0?new F(s,u):(l.isPresent(this.transforms)&&this.transforms.forEach(function(t){s=P.templateVisitAll(t,s)}),new F(s))},t=a([h.Injectable(),c(3,h.Optional()),c(3,h.Inject(e.TEMPLATE_TRANSFORMS)),u("design:paramtypes",[y.Parser,w.ElementSchemaRegistry,m.HtmlParser,Array])],t)}();e.TemplateParser=U;var W=function(){function t(t,e,n,r,i){var o=this;this.providerViewContext=t,this._exprParser=r,this._schemaRegistry=i,this.errors=[],this.directivesIndex=new Map,this.ngContentCount=0,this.selectorMatcher=new E.SelectorMatcher,p.ListWrapper.forEachWithIndex(e,function(t,e){var n=E.CssSelector.parse(t.selector);o.selectorMatcher.addSelectables(n,t),o.directivesIndex.set(t,e)}),this.pipesByName=new Map,n.forEach(function(t){return o.pipesByName.set(t.name,t)})}return t.prototype._reportError=function(t,e){this.errors.push(new B(t,e))},t.prototype._parseInterpolation=function(t,e){var n=e.start.toString();try{var r=this._exprParser.parseInterpolation(t,n);if(this._checkPipes(r,e),l.isPresent(r)&&r.ast.expressions.length>b.MAX_INTERPOLATION_VALUES)throw new d.BaseException("Only support at most "+b.MAX_INTERPOLATION_VALUES+" interpolation values!");return r}catch(i){return this._reportError(""+i,e),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},t.prototype._parseAction=function(t,e){var n=e.start.toString();try{var r=this._exprParser.parseAction(t,n);return this._checkPipes(r,e),r}catch(i){return this._reportError(""+i,e),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},t.prototype._parseBinding=function(t,e){var n=e.start.toString();try{var r=this._exprParser.parseBinding(t,n);return this._checkPipes(r,e),r}catch(i){return this._reportError(""+i,e),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},t.prototype._parseTemplateBindings=function(t,e){var n=this,r=e.start.toString();try{var i=this._exprParser.parseTemplateBindings(t,r);return i.forEach(function(t){l.isPresent(t.expression)&&n._checkPipes(t.expression,e)}),i}catch(o){return this._reportError(""+o,e),[]}},t.prototype._checkPipes=function(t,e){var n=this;if(l.isPresent(t)){var r=new K;t.visit(r),r.pipes.forEach(function(t){n.pipesByName.has(t)||n._reportError("The pipe '"+t+"' could not be found",e)})}},t.prototype.visitExpansion=function(t,e){return null},t.prototype.visitExpansionCase=function(t,e){return null},t.prototype.visitText=function(t,e){var n=e.findNgContentIndex(L),r=this._parseInterpolation(t.value,t.sourceSpan);return l.isPresent(r)?new P.BoundTextAst(r,n,t.sourceSpan):new P.TextAst(t.value,n,t.sourceSpan)},t.prototype.visitAttr=function(t,e){return new P.AttrAst(t.name,t.value,t.sourceSpan)},t.prototype.visitComment=function(t,e){return null},t.prototype.visitElement=function(t,e){var n=this,r=t.name,o=C.preparseElement(t);if(o.type===C.PreparsedElementType.SCRIPT||o.type===C.PreparsedElementType.STYLE)return null;if(o.type===C.PreparsedElementType.STYLESHEET&&R.isStyleUrlResolvable(o.hrefAttr))return null;var s=[],a=[],u=[],c=[],p=[],h=[],f=[],d=!1,v=[];t.attrs.forEach(function(t){var e=n._parseAttr(t,s,a,c,u),r=n._parseInlineTemplateBinding(t,f,p,h);e||r||(v.push(n.visitAttr(t,null)),s.push([t.name,t.value])),r&&(d=!0)});var y=g.splitNsName(r.toLowerCase())[1],m=y==A,_=i(r,s),b=this._parseDirectives(this.selectorMatcher,_),w=this._createDirectiveAsts(t.name,b,a,m?[]:u,t.sourceSpan),O=this._createElementPropertyAsts(t.name,a,w),x=e.isTemplateElement||d,I=new T.ProviderElementContext(this.providerViewContext,e.providerContext,x,w,v,u,t.sourceSpan),M=S.htmlVisitAll(o.nonBindable?z:this,t.children,q.create(m,w,m?e.providerContext:I));I.afterElement();var k,N=l.isPresent(o.projectAs)?E.CssSelector.parse(o.projectAs)[0]:_,D=e.findNgContentIndex(N);if(o.type===C.PreparsedElementType.NG_CONTENT)l.isPresent(t.children)&&t.children.length>0&&this._reportError("<ng-content> element cannot have content. <ng-content> must be immediately followed by </ng-content>",t.sourceSpan),k=new P.NgContentAst(this.ngContentCount++,d?null:D,t.sourceSpan);else if(m)this._assertAllEventsPublishedByDirectives(w,c),this._assertNoComponentsNorElementBindingsOnTemplate(w,O,t.sourceSpan),k=new P.EmbeddedTemplateAst(v,c,u,I.transformedDirectiveAsts,I.transformProviders,I.transformedHasViewContainer,M,d?null:D,t.sourceSpan);else{this._assertOnlyOneComponent(w,t.sourceSpan);var V=u.filter(function(t){return 0===t.value.length}),j=d?null:e.findNgContentIndex(N);k=new P.ElementAst(r,v,O,c,V,I.transformedDirectiveAsts,I.transformProviders,I.transformedHasViewContainer,M,d?null:j,t.sourceSpan)}if(d){var L=i(A,f),B=this._parseDirectives(this.selectorMatcher,L),F=this._createDirectiveAsts(t.name,B,p,[],t.sourceSpan),U=this._createElementPropertyAsts(t.name,p,F);this._assertNoComponentsNorElementBindingsOnTemplate(F,U,t.sourceSpan);var W=new T.ProviderElementContext(this.providerViewContext,e.providerContext,e.isTemplateElement,F,[],h,t.sourceSpan);W.afterElement(),k=new P.EmbeddedTemplateAst([],[],h,W.transformedDirectiveAsts,W.transformProviders,W.transformedHasViewContainer,[k],D,t.sourceSpan)}return k},t.prototype._parseInlineTemplateBinding=function(t,e,n,r){var i=null;if(t.name==I)i=t.value;else if(t.name.startsWith(M)){var o=t.name.substring(M.length);i=0==t.value.length?o:o+" "+t.value}if(l.isPresent(i)){for(var s=this._parseTemplateBindings(i,t.sourceSpan),a=0;a<s.length;a++){var u=s[a];u.keyIsVar?(r.push(new P.VariableAst(u.key,u.name,t.sourceSpan)),e.push([u.key,u.name])):l.isPresent(u.expression)?this._parsePropertyAst(u.key,u.expression,t.sourceSpan,e,n):(e.push([u.key,""]),this._parseLiteralAttr(u.key,null,t.sourceSpan,n))}return!0}return!1},t.prototype._parseAttr=function(t,e,n,r,i){var o=this._normalizeAttributeName(t.name),s=t.value,a=l.RegExpWrapper.firstMatch(x,o),u=!1;if(l.isPresent(a))if(u=!0,l.isPresent(a[1]))this._parseProperty(a[5],s,t.sourceSpan,e,n);else if(l.isPresent(a[2])){var c=a[5];this._parseVariable(c,s,t.sourceSpan,i)}else l.isPresent(a[3])?this._parseEvent(a[5],s,t.sourceSpan,e,r):l.isPresent(a[4])?(this._parseProperty(a[5],s,t.sourceSpan,e,n),this._parseAssignmentEvent(a[5],s,t.sourceSpan,e,r)):l.isPresent(a[6])?(this._parseProperty(a[6],s,t.sourceSpan,e,n),this._parseAssignmentEvent(a[6],s,t.sourceSpan,e,r)):l.isPresent(a[7])?this._parseProperty(a[7],s,t.sourceSpan,e,n):l.isPresent(a[8])&&this._parseEvent(a[8],s,t.sourceSpan,e,r);else u=this._parsePropertyInterpolation(o,s,t.sourceSpan,e,n);return u||this._parseLiteralAttr(o,s,t.sourceSpan,n),u},t.prototype._normalizeAttributeName=function(t){return t.toLowerCase().startsWith("data-")?t.substring(5):t},t.prototype._parseVariable=function(t,e,n,r){t.indexOf("-")>-1&&this._reportError('"-" is not allowed in variable names',n),r.push(new P.VariableAst(t,e,n))},t.prototype._parseProperty=function(t,e,n,r,i){this._parsePropertyAst(t,this._parseBinding(e,n),n,r,i)},t.prototype._parsePropertyInterpolation=function(t,e,n,r,i){var o=this._parseInterpolation(e,n);return l.isPresent(o)?(this._parsePropertyAst(t,o,n,r,i),!0):!1},t.prototype._parsePropertyAst=function(t,e,n,r,i){r.push([t,e.source]),i.push(new X(t,e,!1,n))},t.prototype._parseAssignmentEvent=function(t,e,n,r,i){this._parseEvent(t+"Change",e+"=$event",n,r,i)},t.prototype._parseEvent=function(t,e,n,r,i){var o=O.splitAtColon(t,[null,t]),s=o[0],a=o[1],u=this._parseAction(e,n);r.push([t,u.source]),i.push(new P.BoundEventAst(a,s,u,n))},t.prototype._parseLiteralAttr=function(t,e,n,r){r.push(new X(t,this._exprParser.wrapLiteralPrimitive(e,""),!0,n))},t.prototype._parseDirectives=function(t,e){var n=this,r=[];return t.match(e,function(t,e){r.push(e)}),p.ListWrapper.sort(r,function(t,e){var r=t.isComponent,i=e.isComponent;return r&&!i?-1:!r&&i?1:n.directivesIndex.get(t)-n.directivesIndex.get(e)}),r},t.prototype._createDirectiveAsts=function(t,e,n,r,i){var o=this,s=new Set,a=e.map(function(e){var a=[],u=[],c=[];o._createDirectiveHostPropertyAsts(t,e.hostProperties,i,a),o._createDirectiveHostEventAsts(e.hostListeners,i,u),o._createDirectivePropertyAsts(e.inputs,n,c);var p=[];return r.forEach(function(t){(0===t.value.length&&e.isComponent||e.exportAs==t.value)&&(p.push(t),s.add(t.name))}),new P.DirectiveAst(e,c,a,u,p,i)});return r.forEach(function(t){t.value.length>0&&!p.SetWrapper.has(s,t.name)&&o._reportError('There is no directive with "exportAs" set to "'+t.value+'"',t.sourceSpan)}),a},t.prototype._createDirectiveHostPropertyAsts=function(t,e,n,r){var i=this;l.isPresent(e)&&p.StringMapWrapper.forEach(e,function(e,o){var s=i._parseBinding(e,n);r.push(i._createElementPropertyAst(t,o,s,n))})},t.prototype._createDirectiveHostEventAsts=function(t,e,n){var r=this;l.isPresent(t)&&p.StringMapWrapper.forEach(t,function(t,i){r._parseEvent(i,t,e,[],n)})},t.prototype._createDirectivePropertyAsts=function(t,e,n){if(l.isPresent(t)){var r=new Map;e.forEach(function(t){var e=r.get(t.name);(l.isBlank(e)||e.isLiteral)&&r.set(t.name,t)}),p.StringMapWrapper.forEach(t,function(t,e){var i=r.get(t);l.isPresent(i)&&n.push(new P.BoundDirectivePropertyAst(e,i.name,i.expression,i.sourceSpan))})}},t.prototype._createElementPropertyAsts=function(t,e,n){var r=this,i=[],o=new Map;return n.forEach(function(t){t.inputs.forEach(function(t){o.set(t.templateName,t)})}),e.forEach(function(e){!e.isLiteral&&l.isBlank(o.get(e.name))&&i.push(r._createElementPropertyAst(t,e.name,e.expression,e.sourceSpan))}),i},t.prototype._createElementPropertyAst=function(t,e,n,r){var i,o,s=null,a=e.split(N);if(1===a.length)o=this._schemaRegistry.getMappedPropName(a[0]),i=P.PropertyBindingType.Property,this._schemaRegistry.hasProperty(t,o)||this._reportError("Can't bind to '"+o+"' since it isn't a known native property",r);else if(a[0]==D){o=a[1];var u=o.indexOf(":");if(u>-1){var c=o.substring(0,u),p=o.substring(u+1);o=g.mergeNsAndName(c,p)}i=P.PropertyBindingType.Attribute}else a[0]==V?(o=a[1],i=P.PropertyBindingType.Class):a[0]==j?(s=a.length>2?a[2]:null,o=a[1],i=P.PropertyBindingType.Style):(this._reportError("Invalid property name '"+e+"'",r),i=null);return new P.BoundElementPropertyAst(o,i,n,s,r)},t.prototype._findComponentDirectiveNames=function(t){var e=[];return t.forEach(function(t){var n=t.directive.type.name;t.directive.isComponent&&e.push(n)}),e},t.prototype._assertOnlyOneComponent=function(t,e){var n=this._findComponentDirectiveNames(t);n.length>1&&this._reportError("More than one component: "+n.join(","),e)},t.prototype._assertNoComponentsNorElementBindingsOnTemplate=function(t,e,n){var r=this,i=this._findComponentDirectiveNames(t);i.length>0&&this._reportError("Components on an embedded template: "+i.join(","),n),e.forEach(function(t){r._reportError("Property binding "+t.name+" not used by any directive on an embedded template",n)})},t.prototype._assertAllEventsPublishedByDirectives=function(t,e){var n=this,r=new Set;t.forEach(function(t){p.StringMapWrapper.forEach(t.directive.outputs,function(t,e){r.add(t)})}),e.forEach(function(t){(l.isPresent(t.target)||!p.SetWrapper.has(r,t.name))&&n._reportError("Event binding "+t.fullName+" not emitted by any directive on an embedded template",t.sourceSpan)})},t}(),H=function(){function t(){}return t.prototype.visitElement=function(t,e){var n=C.preparseElement(t);if(n.type===C.PreparsedElementType.SCRIPT||n.type===C.PreparsedElementType.STYLE||n.type===C.PreparsedElementType.STYLESHEET)return null;var r=t.attrs.map(function(t){return[t.name,t.value]}),o=i(t.name,r),s=e.findNgContentIndex(o),a=S.htmlVisitAll(this,t.children,G);return new P.ElementAst(t.name,S.htmlVisitAll(this,t.attrs),[],[],[],[],[],!1,a,s,t.sourceSpan)},t.prototype.visitComment=function(t,e){return null},t.prototype.visitAttr=function(t,e){return new P.AttrAst(t.name,t.value,t.sourceSpan)},t.prototype.visitText=function(t,e){var n=e.findNgContentIndex(L);return new P.TextAst(t.value,n,t.sourceSpan)},t.prototype.visitExpansion=function(t,e){return t},t.prototype.visitExpansionCase=function(t,e){return t},t}(),X=function(){function t(t,e,n,r){this.name=t,this.expression=e,this.isLiteral=n,this.sourceSpan=r}return t}();e.splitClasses=r;var q=function(){function t(t,e,n,r){this.isTemplateElement=t,this._ngContentIndexMatcher=e,this._wildcardNgContentIndex=n,this.providerContext=r}return t.create=function(e,n,r){var i=new E.SelectorMatcher,o=null;if(n.length>0&&n[0].directive.isComponent)for(var s=n[0].directive.template.ngContentSelectors,a=0;a<s.length;a++){var u=s[a];l.StringWrapper.equals(u,"*")?o=a:i.addSelectables(E.CssSelector.parse(s[a]),a)}return new t(e,i,o,r)},t.prototype.findNgContentIndex=function(t){var e=[];return this._ngContentIndexMatcher.match(t,function(t,n){e.push(n)}),p.ListWrapper.sort(e),l.isPresent(this._wildcardNgContentIndex)&&e.push(this._wildcardNgContentIndex),e.length>0?e[0]:null},t}(),G=new q(!0,new E.SelectorMatcher,null,null),z=new H,K=function(t){function e(){t.apply(this,arguments),this.pipes=new Set}return s(e,t),e.prototype.visitPipe=function(t,e){return this.pipes.add(t.name),t.exp.visit(this),this.visitAll(t.args,e),null},e}(v.RecursiveAstVisitor);e.PipeCollector=K},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(15),o=function(){function t(){}return t.prototype.visit=function(t,e){return void 0===e&&(e=null),null},t.prototype.toString=function(){return"AST"},t}();e.AST=o;var s=function(t){function e(e,n,r){t.call(this),this.prefix=e,this.uninterpretedExpression=n,this.location=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitQuote(this,e)},e.prototype.toString=function(){return"Quote"},e}(o);e.Quote=s;var a=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.visit=function(t,e){void 0===e&&(e=null)},e}(o);e.EmptyExpr=a;var u=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitImplicitReceiver(this,e)},e}(o);e.ImplicitReceiver=u;var c=function(t){function e(e){t.call(this),this.expressions=e}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitChain(this,e)},e}(o);e.Chain=c;var p=function(t){function e(e,n,r){t.call(this),this.condition=e,this.trueExp=n,this.falseExp=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitConditional(this,e)},e}(o);e.Conditional=p;var l=function(t){function e(e,n){t.call(this),this.receiver=e,this.name=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPropertyRead(this,e)},e}(o);e.PropertyRead=l;var h=function(t){function e(e,n,r){t.call(this),this.receiver=e,this.name=n,this.value=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPropertyWrite(this,e)},e}(o);e.PropertyWrite=h;var f=function(t){function e(e,n){t.call(this),this.receiver=e,this.name=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitSafePropertyRead(this,e)},e}(o);e.SafePropertyRead=f;var d=function(t){function e(e,n){t.call(this),this.obj=e,this.key=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitKeyedRead(this,e)},e}(o);e.KeyedRead=d;var v=function(t){function e(e,n,r){t.call(this),this.obj=e,this.key=n,this.value=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitKeyedWrite(this,e)},e}(o);e.KeyedWrite=v;var y=function(t){function e(e,n,r){t.call(this),this.exp=e,this.name=n,this.args=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPipe(this,e)},e}(o);e.BindingPipe=y;var m=function(t){function e(e){t.call(this),this.value=e}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralPrimitive(this,e)},e}(o);e.LiteralPrimitive=m;var g=function(t){function e(e){t.call(this),this.expressions=e}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralArray(this,e)},e}(o);e.LiteralArray=g;var _=function(t){function e(e,n){t.call(this),this.keys=e,this.values=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralMap(this,e)},e}(o);e.LiteralMap=_;var b=function(t){function e(e,n){t.call(this),this.strings=e,this.expressions=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitInterpolation(this,e)},e}(o);e.Interpolation=b;var P=function(t){function e(e,n,r){t.call(this),this.operation=e,this.left=n,this.right=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitBinary(this,e)},e}(o);e.Binary=P;var E=function(t){function e(e){t.call(this),this.expression=e}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPrefixNot(this,e)},e}(o);e.PrefixNot=E;var w=function(t){function e(e,n,r){t.call(this),this.receiver=e,this.name=n,this.args=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitMethodCall(this,e)},e}(o);e.MethodCall=w;var C=function(t){function e(e,n,r){t.call(this),this.receiver=e,this.name=n,this.args=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitSafeMethodCall(this,e)},e}(o);e.SafeMethodCall=C;var R=function(t){function e(e,n){t.call(this),this.target=e,this.args=n}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitFunctionCall(this,e)},e}(o);e.FunctionCall=R;var S=function(t){function e(e,n,r){t.call(this),this.ast=e,this.source=n,this.location=r}return r(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),this.ast.visit(t,e)},e.prototype.toString=function(){return this.source+" in "+this.location},e}(o);e.ASTWithSource=S;var O=function(){function t(t,e,n,r){this.key=t,this.keyIsVar=e,this.name=n,this.expression=r}return t}();e.TemplateBinding=O;var T=function(){function t(){}return t.prototype.visitBinary=function(t,e){return t.left.visit(this),t.right.visit(this),null},t.prototype.visitChain=function(t,e){return this.visitAll(t.expressions,e)},t.prototype.visitConditional=function(t,e){return t.condition.visit(this),t.trueExp.visit(this),t.falseExp.visit(this),null},t.prototype.visitPipe=function(t,e){return t.exp.visit(this),this.visitAll(t.args,e),null},t.prototype.visitFunctionCall=function(t,e){return t.target.visit(this),this.visitAll(t.args,e),null},t.prototype.visitImplicitReceiver=function(t,e){return null},t.prototype.visitInterpolation=function(t,e){return this.visitAll(t.expressions,e)},t.prototype.visitKeyedRead=function(t,e){return t.obj.visit(this),t.key.visit(this),null},t.prototype.visitKeyedWrite=function(t,e){return t.obj.visit(this),t.key.visit(this),t.value.visit(this),null},t.prototype.visitLiteralArray=function(t,e){return this.visitAll(t.expressions,e)},t.prototype.visitLiteralMap=function(t,e){return this.visitAll(t.values,e)},t.prototype.visitLiteralPrimitive=function(t,e){return null},t.prototype.visitMethodCall=function(t,e){return t.receiver.visit(this),this.visitAll(t.args,e)},t.prototype.visitPrefixNot=function(t,e){return t.expression.visit(this),null},t.prototype.visitPropertyRead=function(t,e){return t.receiver.visit(this),null},t.prototype.visitPropertyWrite=function(t,e){return t.receiver.visit(this),t.value.visit(this),null},t.prototype.visitSafePropertyRead=function(t,e){return t.receiver.visit(this),null},t.prototype.visitSafeMethodCall=function(t,e){return t.receiver.visit(this),this.visitAll(t.args,e)},t.prototype.visitAll=function(t,e){var n=this;return t.forEach(function(t){return t.visit(n,e)}),null},t.prototype.visitQuote=function(t,e){return null},t}();e.RecursiveAstVisitor=T;var x=function(){function t(){}return t.prototype.visitImplicitReceiver=function(t,e){return t},t.prototype.visitInterpolation=function(t,e){return new b(t.strings,this.visitAll(t.expressions))},t.prototype.visitLiteralPrimitive=function(t,e){return new m(t.value)},t.prototype.visitPropertyRead=function(t,e){return new l(t.receiver.visit(this),t.name)},t.prototype.visitPropertyWrite=function(t,e){return new h(t.receiver.visit(this),t.name,t.value)},t.prototype.visitSafePropertyRead=function(t,e){return new f(t.receiver.visit(this),t.name)},t.prototype.visitMethodCall=function(t,e){return new w(t.receiver.visit(this),t.name,this.visitAll(t.args))},t.prototype.visitSafeMethodCall=function(t,e){return new C(t.receiver.visit(this),t.name,this.visitAll(t.args))},t.prototype.visitFunctionCall=function(t,e){return new R(t.target.visit(this),this.visitAll(t.args))},t.prototype.visitLiteralArray=function(t,e){return new g(this.visitAll(t.expressions))},t.prototype.visitLiteralMap=function(t,e){return new _(t.keys,this.visitAll(t.values))},t.prototype.visitBinary=function(t,e){return new P(t.operation,t.left.visit(this),t.right.visit(this))},t.prototype.visitPrefixNot=function(t,e){return new E(t.expression.visit(this))},t.prototype.visitConditional=function(t,e){return new p(t.condition.visit(this),t.trueExp.visit(this),t.falseExp.visit(this))},t.prototype.visitPipe=function(t,e){return new y(t.exp.visit(this),t.name,this.visitAll(t.args))},t.prototype.visitKeyedRead=function(t,e){return new d(t.obj.visit(this),t.key.visit(this))},t.prototype.visitKeyedWrite=function(t,e){return new v(t.obj.visit(this),t.key.visit(this),t.value.visit(this))},t.prototype.visitAll=function(t){for(var e=i.ListWrapper.createFixedSize(t.length),n=0;n<t.length;++n)e[n]=t[n].visit(this);return e},t.prototype.visitChain=function(t,e){return new c(this.visitAll(t.expressions))},t.prototype.visitQuote=function(t,e){return new s(t.prefix,t.uninterpretedExpression,t.location)},t}();e.AstTransformer=x},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(8),a=n(5),u=n(12),c=n(15),p=n(143),l=n(141),h=new l.ImplicitReceiver,f=/\{\{([\s\S]*?)\}\}/g,d=function(t){function e(e,n,r,i){t.call(this,"Parser Error: "+e+" "+r+" ["+n+"] in "+i)}return r(e,t),e}(u.BaseException),v=function(){function t(t,e){this.strings=t,this.expressions=e}return t}();e.SplitInterpolation=v;var y=function(){function t(t){this._lexer=t}return t.prototype.parseAction=function(t,e){this._checkNoInterpolation(t,e);var n=this._lexer.tokenize(this._stripComments(t)),r=new m(t,e,n,!0).parseChain();return new l.ASTWithSource(r,t,e)},t.prototype.parseBinding=function(t,e){var n=this._parseBindingAst(t,e);return new l.ASTWithSource(n,t,e)},t.prototype.parseSimpleBinding=function(t,e){var n=this._parseBindingAst(t,e);if(!g.check(n))throw new d("Host binding expression can only contain field access and constants",t,e);return new l.ASTWithSource(n,t,e)},t.prototype._parseBindingAst=function(t,e){var n=this._parseQuote(t,e);if(a.isPresent(n))return n;this._checkNoInterpolation(t,e);var r=this._lexer.tokenize(this._stripComments(t));return new m(t,e,r,!1).parseChain()},t.prototype._parseQuote=function(t,e){if(a.isBlank(t))return null;var n=t.indexOf(":");if(-1==n)return null;var r=t.substring(0,n).trim();if(!p.isIdentifier(r))return null;var i=t.substring(n+1);return new l.Quote(r,i,e)},t.prototype.parseTemplateBindings=function(t,e){var n=this._lexer.tokenize(t);return new m(t,e,n,!1).parseTemplateBindings()},t.prototype.parseInterpolation=function(t,e){var n=this.splitInterpolation(t,e);if(null==n)return null;for(var r=[],i=0;i<n.expressions.length;++i){var o=this._lexer.tokenize(this._stripComments(n.expressions[i])),s=new m(t,e,o,!1).parseChain();r.push(s)}return new l.ASTWithSource(new l.Interpolation(n.strings,r),t,e)},t.prototype.splitInterpolation=function(t,e){var n=a.StringWrapper.split(t,f);if(n.length<=1)return null;for(var r=[],i=[],o=0;o<n.length;o++){var s=n[o];if(o%2===0)r.push(s);else{if(!(s.trim().length>0))throw new d("Blank expressions are not allowed in interpolated strings",t,"at column "+this._findInterpolationErrorColumn(n,o)+" in",e);i.push(s)}}return new v(r,i)},t.prototype.wrapLiteralPrimitive=function(t,e){return new l.ASTWithSource(new l.LiteralPrimitive(t),t,e)},t.prototype._stripComments=function(t){var e=this._commentStart(t);return a.isPresent(e)?t.substring(0,e).trim():t},t.prototype._commentStart=function(t){for(var e=null,n=0;n<t.length-1;n++){var r=a.StringWrapper.charCodeAt(t,n),i=a.StringWrapper.charCodeAt(t,n+1);if(r===p.$SLASH&&i==p.$SLASH&&a.isBlank(e))return n;e===r?e=null:a.isBlank(e)&&p.isQuote(r)&&(e=r)}return null},t.prototype._checkNoInterpolation=function(t,e){
                +var n=a.StringWrapper.split(t,f);if(n.length>1)throw new d("Got interpolation ({{}}) where expression was expected",t,"at column "+this._findInterpolationErrorColumn(n,1)+" in",e)},t.prototype._findInterpolationErrorColumn=function(t,e){for(var n="",r=0;e>r;r++)n+=r%2===0?t[r]:"{{"+t[r]+"}}";return n.length},t=i([s.Injectable(),o("design:paramtypes",[p.Lexer])],t)}();e.Parser=y;var m=function(){function t(t,e,n,r){this.input=t,this.location=e,this.tokens=n,this.parseAction=r,this.index=0}return t.prototype.peek=function(t){var e=this.index+t;return e<this.tokens.length?this.tokens[e]:p.EOF},Object.defineProperty(t.prototype,"next",{get:function(){return this.peek(0)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"inputIndex",{get:function(){return this.index<this.tokens.length?this.next.index:this.input.length},enumerable:!0,configurable:!0}),t.prototype.advance=function(){this.index++},t.prototype.optionalCharacter=function(t){return this.next.isCharacter(t)?(this.advance(),!0):!1},t.prototype.optionalKeywordVar=function(){return this.peekKeywordVar()?(this.advance(),!0):!1},t.prototype.peekKeywordVar=function(){return this.next.isKeywordVar()||this.next.isOperator("#")},t.prototype.expectCharacter=function(t){this.optionalCharacter(t)||this.error("Missing expected "+a.StringWrapper.fromCharCode(t))},t.prototype.optionalOperator=function(t){return this.next.isOperator(t)?(this.advance(),!0):!1},t.prototype.expectOperator=function(t){this.optionalOperator(t)||this.error("Missing expected operator "+t)},t.prototype.expectIdentifierOrKeyword=function(){var t=this.next;return t.isIdentifier()||t.isKeyword()||this.error("Unexpected token "+t+", expected identifier or keyword"),this.advance(),t.toString()},t.prototype.expectIdentifierOrKeywordOrString=function(){var t=this.next;return t.isIdentifier()||t.isKeyword()||t.isString()||this.error("Unexpected token "+t+", expected identifier, keyword, or string"),this.advance(),t.toString()},t.prototype.parseChain=function(){for(var t=[];this.index<this.tokens.length;){var e=this.parsePipe();if(t.push(e),this.optionalCharacter(p.$SEMICOLON))for(this.parseAction||this.error("Binding expression cannot contain chained expression");this.optionalCharacter(p.$SEMICOLON););else this.index<this.tokens.length&&this.error("Unexpected token '"+this.next+"'")}return 0==t.length?new l.EmptyExpr:1==t.length?t[0]:new l.Chain(t)},t.prototype.parsePipe=function(){var t=this.parseExpression();if(this.optionalOperator("|")){this.parseAction&&this.error("Cannot have a pipe in an action expression");do{for(var e=this.expectIdentifierOrKeyword(),n=[];this.optionalCharacter(p.$COLON);)n.push(this.parseExpression());t=new l.BindingPipe(t,e,n)}while(this.optionalOperator("|"))}return t},t.prototype.parseExpression=function(){return this.parseConditional()},t.prototype.parseConditional=function(){var t=this.inputIndex,e=this.parseLogicalOr();if(this.optionalOperator("?")){var n=this.parsePipe();if(!this.optionalCharacter(p.$COLON)){var r=this.inputIndex,i=this.input.substring(t,r);this.error("Conditional expression "+i+" requires all 3 expressions")}var o=this.parsePipe();return new l.Conditional(e,n,o)}return e},t.prototype.parseLogicalOr=function(){for(var t=this.parseLogicalAnd();this.optionalOperator("||");)t=new l.Binary("||",t,this.parseLogicalAnd());return t},t.prototype.parseLogicalAnd=function(){for(var t=this.parseEquality();this.optionalOperator("&&");)t=new l.Binary("&&",t,this.parseEquality());return t},t.prototype.parseEquality=function(){for(var t=this.parseRelational();;)if(this.optionalOperator("=="))t=new l.Binary("==",t,this.parseRelational());else if(this.optionalOperator("==="))t=new l.Binary("===",t,this.parseRelational());else if(this.optionalOperator("!="))t=new l.Binary("!=",t,this.parseRelational());else{if(!this.optionalOperator("!=="))return t;t=new l.Binary("!==",t,this.parseRelational())}},t.prototype.parseRelational=function(){for(var t=this.parseAdditive();;)if(this.optionalOperator("<"))t=new l.Binary("<",t,this.parseAdditive());else if(this.optionalOperator(">"))t=new l.Binary(">",t,this.parseAdditive());else if(this.optionalOperator("<="))t=new l.Binary("<=",t,this.parseAdditive());else{if(!this.optionalOperator(">="))return t;t=new l.Binary(">=",t,this.parseAdditive())}},t.prototype.parseAdditive=function(){for(var t=this.parseMultiplicative();;)if(this.optionalOperator("+"))t=new l.Binary("+",t,this.parseMultiplicative());else{if(!this.optionalOperator("-"))return t;t=new l.Binary("-",t,this.parseMultiplicative())}},t.prototype.parseMultiplicative=function(){for(var t=this.parsePrefix();;)if(this.optionalOperator("*"))t=new l.Binary("*",t,this.parsePrefix());else if(this.optionalOperator("%"))t=new l.Binary("%",t,this.parsePrefix());else{if(!this.optionalOperator("/"))return t;t=new l.Binary("/",t,this.parsePrefix())}},t.prototype.parsePrefix=function(){return this.optionalOperator("+")?this.parsePrefix():this.optionalOperator("-")?new l.Binary("-",new l.LiteralPrimitive(0),this.parsePrefix()):this.optionalOperator("!")?new l.PrefixNot(this.parsePrefix()):this.parseCallChain()},t.prototype.parseCallChain=function(){for(var t=this.parsePrimary();;)if(this.optionalCharacter(p.$PERIOD))t=this.parseAccessMemberOrMethodCall(t,!1);else if(this.optionalOperator("?."))t=this.parseAccessMemberOrMethodCall(t,!0);else if(this.optionalCharacter(p.$LBRACKET)){var e=this.parsePipe();if(this.expectCharacter(p.$RBRACKET),this.optionalOperator("=")){var n=this.parseConditional();t=new l.KeyedWrite(t,e,n)}else t=new l.KeyedRead(t,e)}else{if(!this.optionalCharacter(p.$LPAREN))return t;var r=this.parseCallArguments();this.expectCharacter(p.$RPAREN),t=new l.FunctionCall(t,r)}},t.prototype.parsePrimary=function(){if(this.optionalCharacter(p.$LPAREN)){var t=this.parsePipe();return this.expectCharacter(p.$RPAREN),t}if(this.next.isKeywordNull()||this.next.isKeywordUndefined())return this.advance(),new l.LiteralPrimitive(null);if(this.next.isKeywordTrue())return this.advance(),new l.LiteralPrimitive(!0);if(this.next.isKeywordFalse())return this.advance(),new l.LiteralPrimitive(!1);if(this.optionalCharacter(p.$LBRACKET)){var e=this.parseExpressionList(p.$RBRACKET);return this.expectCharacter(p.$RBRACKET),new l.LiteralArray(e)}if(this.next.isCharacter(p.$LBRACE))return this.parseLiteralMap();if(this.next.isIdentifier())return this.parseAccessMemberOrMethodCall(h,!1);if(this.next.isNumber()){var n=this.next.toNumber();return this.advance(),new l.LiteralPrimitive(n)}if(this.next.isString()){var r=this.next.toString();return this.advance(),new l.LiteralPrimitive(r)}throw this.index>=this.tokens.length?this.error("Unexpected end of expression: "+this.input):this.error("Unexpected token "+this.next),new u.BaseException("Fell through all cases in parsePrimary")},t.prototype.parseExpressionList=function(t){var e=[];if(!this.next.isCharacter(t))do e.push(this.parsePipe());while(this.optionalCharacter(p.$COMMA));return e},t.prototype.parseLiteralMap=function(){var t=[],e=[];if(this.expectCharacter(p.$LBRACE),!this.optionalCharacter(p.$RBRACE)){do{var n=this.expectIdentifierOrKeywordOrString();t.push(n),this.expectCharacter(p.$COLON),e.push(this.parsePipe())}while(this.optionalCharacter(p.$COMMA));this.expectCharacter(p.$RBRACE)}return new l.LiteralMap(t,e)},t.prototype.parseAccessMemberOrMethodCall=function(t,e){void 0===e&&(e=!1);var n=this.expectIdentifierOrKeyword();if(this.optionalCharacter(p.$LPAREN)){var r=this.parseCallArguments();return this.expectCharacter(p.$RPAREN),e?new l.SafeMethodCall(t,n,r):new l.MethodCall(t,n,r)}if(!e){if(this.optionalOperator("=")){this.parseAction||this.error("Bindings cannot contain assignments");var i=this.parseConditional();return new l.PropertyWrite(t,n,i)}return new l.PropertyRead(t,n)}return this.optionalOperator("=")?(this.error("The '?.' operator cannot be used in the assignment"),null):new l.SafePropertyRead(t,n)},t.prototype.parseCallArguments=function(){if(this.next.isCharacter(p.$RPAREN))return[];var t=[];do t.push(this.parsePipe());while(this.optionalCharacter(p.$COMMA));return t},t.prototype.parseBlockContent=function(){this.parseAction||this.error("Binding expression cannot contain chained expression");for(var t=[];this.index<this.tokens.length&&!this.next.isCharacter(p.$RBRACE);){var e=this.parseExpression();if(t.push(e),this.optionalCharacter(p.$SEMICOLON))for(;this.optionalCharacter(p.$SEMICOLON););}return 0==t.length?new l.EmptyExpr:1==t.length?t[0]:new l.Chain(t)},t.prototype.expectTemplateBindingKey=function(){var t="",e=!1;do t+=this.expectIdentifierOrKeywordOrString(),e=this.optionalOperator("-"),e&&(t+="-");while(e);return t.toString()},t.prototype.parseTemplateBindings=function(){for(var t=[],e=null;this.index<this.tokens.length;){var n=this.optionalKeywordVar(),r=this.expectTemplateBindingKey();n||(null==e?e=r:r=e+r[0].toUpperCase()+r.substring(1)),this.optionalCharacter(p.$COLON);var i=null,o=null;if(n)i=this.optionalOperator("=")?this.expectTemplateBindingKey():"$implicit";else if(this.next!==p.EOF&&!this.peekKeywordVar()){var s=this.inputIndex,a=this.parsePipe(),u=this.input.substring(s,this.inputIndex);o=new l.ASTWithSource(a,u,this.location)}t.push(new l.TemplateBinding(r,n,i,o)),this.optionalCharacter(p.$SEMICOLON)||this.optionalCharacter(p.$COMMA)}return t},t.prototype.error=function(t,e){void 0===e&&(e=null),a.isBlank(e)&&(e=this.index);var n=e<this.tokens.length?"at column "+(this.tokens[e].index+1)+" in":"at the end of the expression";throw new d(t,this.input,n,this.location)},t}();e._ParseAST=m;var g=function(){function t(){this.simple=!0}return t.check=function(e){var n=new t;return e.visit(n),n.simple},t.prototype.visitImplicitReceiver=function(t,e){},t.prototype.visitInterpolation=function(t,e){this.simple=!1},t.prototype.visitLiteralPrimitive=function(t,e){},t.prototype.visitPropertyRead=function(t,e){},t.prototype.visitPropertyWrite=function(t,e){this.simple=!1},t.prototype.visitSafePropertyRead=function(t,e){this.simple=!1},t.prototype.visitMethodCall=function(t,e){this.simple=!1},t.prototype.visitSafeMethodCall=function(t,e){this.simple=!1},t.prototype.visitFunctionCall=function(t,e){this.simple=!1},t.prototype.visitLiteralArray=function(t,e){this.visitAll(t.expressions)},t.prototype.visitLiteralMap=function(t,e){this.visitAll(t.values)},t.prototype.visitBinary=function(t,e){this.simple=!1},t.prototype.visitPrefixNot=function(t,e){this.simple=!1},t.prototype.visitConditional=function(t,e){this.simple=!1},t.prototype.visitPipe=function(t,e){this.simple=!1},t.prototype.visitKeyedRead=function(t,e){this.simple=!1},t.prototype.visitKeyedWrite=function(t,e){this.simple=!1},t.prototype.visitAll=function(t){for(var e=c.ListWrapper.createFixedSize(t.length),n=0;n<t.length;++n)e[n]=t[n].visit(this);return e},t.prototype.visitChain=function(t,e){this.simple=!1},t.prototype.visitQuote=function(t,e){this.simple=!1},t}()},function(t,e,n){"use strict";function r(t,e){return new O(t,R.Character,e,w.StringWrapper.fromCharCode(e))}function i(t,e){return new O(t,R.Identifier,0,e)}function o(t,e){return new O(t,R.Keyword,0,e)}function s(t,e){return new O(t,R.Operator,0,e)}function a(t,e){return new O(t,R.String,0,e)}function u(t,e){return new O(t,R.Number,e,"")}function c(t){return t>=e.$TAB&&t<=e.$SPACE||t==X}function p(t){return t>=D&&H>=t||t>=A&&M>=t||t==N||t==e.$$}function l(t){if(0==t.length)return!1;var n=new G(t);if(!p(n.peek))return!1;for(n.advance();n.peek!==e.$EOF;){if(!h(n.peek))return!1;n.advance()}return!0}function h(t){return t>=D&&H>=t||t>=A&&M>=t||t>=T&&x>=t||t==N||t==e.$$}function f(t){return t>=T&&x>=t}function d(t){return t==V||t==I}function v(t){return t==e.$MINUS||t==e.$PLUS}function y(t){return t===e.$SQ||t===e.$DQ||t===e.$BT}function m(t){switch(t){case L:return e.$LF;case j:return e.$FF;case B:return e.$CR;case F:return e.$TAB;case W:return e.$VTAB;default:return t}}var g=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},_=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},b=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},P=n(8),E=n(15),w=n(5),C=n(12);!function(t){t[t.Character=0]="Character",t[t.Identifier=1]="Identifier",t[t.Keyword=2]="Keyword",t[t.String=3]="String",t[t.Operator=4]="Operator",t[t.Number=5]="Number"}(e.TokenType||(e.TokenType={}));var R=e.TokenType,S=function(){function t(){}return t.prototype.tokenize=function(t){for(var e=new G(t),n=[],r=e.scanToken();null!=r;)n.push(r),r=e.scanToken();return n},t=_([P.Injectable(),b("design:paramtypes",[])],t)}();e.Lexer=S;var O=function(){function t(t,e,n,r){this.index=t,this.type=e,this.numValue=n,this.strValue=r}return t.prototype.isCharacter=function(t){return this.type==R.Character&&this.numValue==t},t.prototype.isNumber=function(){return this.type==R.Number},t.prototype.isString=function(){return this.type==R.String},t.prototype.isOperator=function(t){return this.type==R.Operator&&this.strValue==t},t.prototype.isIdentifier=function(){return this.type==R.Identifier},t.prototype.isKeyword=function(){return this.type==R.Keyword},t.prototype.isKeywordVar=function(){return this.type==R.Keyword&&"var"==this.strValue},t.prototype.isKeywordNull=function(){return this.type==R.Keyword&&"null"==this.strValue},t.prototype.isKeywordUndefined=function(){return this.type==R.Keyword&&"undefined"==this.strValue},t.prototype.isKeywordTrue=function(){return this.type==R.Keyword&&"true"==this.strValue},t.prototype.isKeywordFalse=function(){return this.type==R.Keyword&&"false"==this.strValue},t.prototype.toNumber=function(){return this.type==R.Number?this.numValue:-1},t.prototype.toString=function(){switch(this.type){case R.Character:case R.Identifier:case R.Keyword:case R.Operator:case R.String:return this.strValue;case R.Number:return this.numValue.toString();default:return null}},t}();e.Token=O,e.EOF=new O(-1,R.Character,0,""),e.$EOF=0,e.$TAB=9,e.$LF=10,e.$VTAB=11,e.$FF=12,e.$CR=13,e.$SPACE=32,e.$BANG=33,e.$DQ=34,e.$HASH=35,e.$$=36,e.$PERCENT=37,e.$AMPERSAND=38,e.$SQ=39,e.$LPAREN=40,e.$RPAREN=41,e.$STAR=42,e.$PLUS=43,e.$COMMA=44,e.$MINUS=45,e.$PERIOD=46,e.$SLASH=47,e.$COLON=58,e.$SEMICOLON=59,e.$LT=60,e.$EQ=61,e.$GT=62,e.$QUESTION=63;var T=48,x=57,A=65,I=69,M=90;e.$LBRACKET=91,e.$BACKSLASH=92,e.$RBRACKET=93;var k=94,N=95;e.$BT=96;var D=97,V=101,j=102,L=110,B=114,F=116,U=117,W=118,H=122;e.$LBRACE=123,e.$BAR=124,e.$RBRACE=125;var X=160,q=function(t){function e(e){t.call(this),this.message=e}return g(e,t),e.prototype.toString=function(){return this.message},e}(C.BaseException);e.ScannerError=q;var G=function(){function t(t){this.input=t,this.peek=0,this.index=-1,this.length=t.length,this.advance()}return t.prototype.advance=function(){this.peek=++this.index>=this.length?e.$EOF:w.StringWrapper.charCodeAt(this.input,this.index)},t.prototype.scanToken=function(){for(var t=this.input,n=this.length,i=this.peek,o=this.index;i<=e.$SPACE;){if(++o>=n){i=e.$EOF;break}i=w.StringWrapper.charCodeAt(t,o)}if(this.peek=i,this.index=o,o>=n)return null;if(p(i))return this.scanIdentifier();if(f(i))return this.scanNumber(o);var s=o;switch(i){case e.$PERIOD:return this.advance(),f(this.peek)?this.scanNumber(s):r(s,e.$PERIOD);case e.$LPAREN:case e.$RPAREN:case e.$LBRACE:case e.$RBRACE:case e.$LBRACKET:case e.$RBRACKET:case e.$COMMA:case e.$COLON:case e.$SEMICOLON:return this.scanCharacter(s,i);case e.$SQ:case e.$DQ:return this.scanString();case e.$HASH:case e.$PLUS:case e.$MINUS:case e.$STAR:case e.$SLASH:case e.$PERCENT:case k:return this.scanOperator(s,w.StringWrapper.fromCharCode(i));case e.$QUESTION:return this.scanComplexOperator(s,"?",e.$PERIOD,".");case e.$LT:case e.$GT:return this.scanComplexOperator(s,w.StringWrapper.fromCharCode(i),e.$EQ,"=");case e.$BANG:case e.$EQ:return this.scanComplexOperator(s,w.StringWrapper.fromCharCode(i),e.$EQ,"=",e.$EQ,"=");case e.$AMPERSAND:return this.scanComplexOperator(s,"&",e.$AMPERSAND,"&");case e.$BAR:return this.scanComplexOperator(s,"|",e.$BAR,"|");case X:for(;c(this.peek);)this.advance();return this.scanToken()}return this.error("Unexpected character ["+w.StringWrapper.fromCharCode(i)+"]",0),null},t.prototype.scanCharacter=function(t,e){return this.advance(),r(t,e)},t.prototype.scanOperator=function(t,e){return this.advance(),s(t,e)},t.prototype.scanComplexOperator=function(t,e,n,r,i,o){this.advance();var a=e;return this.peek==n&&(this.advance(),a+=r),w.isPresent(i)&&this.peek==i&&(this.advance(),a+=o),s(t,a)},t.prototype.scanIdentifier=function(){var t=this.index;for(this.advance();h(this.peek);)this.advance();var e=this.input.substring(t,this.index);return E.SetWrapper.has(z,e)?o(t,e):i(t,e)},t.prototype.scanNumber=function(t){var n=this.index===t;for(this.advance();;){if(f(this.peek));else if(this.peek==e.$PERIOD)n=!1;else{if(!d(this.peek))break;this.advance(),v(this.peek)&&this.advance(),f(this.peek)||this.error("Invalid exponent",-1),n=!1}this.advance()}var r=this.input.substring(t,this.index),i=n?w.NumberWrapper.parseIntAutoRadix(r):w.NumberWrapper.parseFloat(r);return u(t,i)},t.prototype.scanString=function(){var t=this.index,n=this.peek;this.advance();for(var r,i=this.index,o=this.input;this.peek!=n;)if(this.peek==e.$BACKSLASH){null==r&&(r=new w.StringJoiner),r.add(o.substring(i,this.index)),this.advance();var s;if(this.peek==U){var u=o.substring(this.index+1,this.index+5);try{s=w.NumberWrapper.parseInt(u,16)}catch(c){this.error("Invalid unicode escape [\\u"+u+"]",0)}for(var p=0;5>p;p++)this.advance()}else s=m(this.peek),this.advance();r.add(w.StringWrapper.fromCharCode(s)),i=this.index}else this.peek==e.$EOF?this.error("Unterminated quote",0):this.advance();var l=o.substring(i,this.index);this.advance();var h=l;return null!=r&&(r.add(l),h=r.toString()),a(t,h)},t.prototype.error=function(t,e){var n=this.index+e;throw new q("Lexer Error: "+t+" at column "+n+" in expression ["+this.input+"]")},t}();e.isIdentifier=l,e.isQuote=y;var z=(E.SetWrapper.createFromList(["+","-","*","/","%","^","=","==","!=","===","!==","<",">","<=",">=","&&","||","&","|","!","?","#","?."]),E.SetWrapper.createFromList(["var","null","undefined","true","false","if","else"]))},function(t,e,n){"use strict";function r(t,e,n){return u.isBlank(t)&&(t=d.getHtmlTagDefinition(e).implicitNamespacePrefix,u.isBlank(t)&&u.isPresent(n)&&(t=d.getNsPrefix(n.name))),d.mergeNsAndName(t,e)}function i(t,e){return t.length>0&&t[t.length-1]===e}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},a=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},u=n(5),c=n(15),p=n(145),l=n(6),h=n(146),f=n(147),d=n(148),v=function(t){function e(e,n,r){t.call(this,n,r),this.elementName=e}return o(e,t),e.create=function(t,n,r){return new e(t,n,r)},e}(f.ParseError);e.HtmlTreeError=v;var y=function(){function t(t,e){this.rootNodes=t,this.errors=e}return t}();e.HtmlParseTreeResult=y;var m=function(){function t(){}return t.prototype.parse=function(t,e,n){void 0===n&&(n=!1);var r=h.tokenizeHtml(t,e,n),i=new g(r.tokens).build();return new y(i.rootNodes,r.errors.concat(i.errors))},t=s([l.Injectable(),a("design:paramtypes",[])],t)}();e.HtmlParser=m;var g=function(){function t(t){this.tokens=t,this.index=-1,this.rootNodes=[],this.errors=[],this.elementStack=[],this._advance()}return t.prototype.build=function(){for(;this.peek.type!==h.HtmlTokenType.EOF;)this.peek.type===h.HtmlTokenType.TAG_OPEN_START?this._consumeStartTag(this._advance()):this.peek.type===h.HtmlTokenType.TAG_CLOSE?this._consumeEndTag(this._advance()):this.peek.type===h.HtmlTokenType.CDATA_START?(this._closeVoidElement(),this._consumeCdata(this._advance())):this.peek.type===h.HtmlTokenType.COMMENT_START?(this._closeVoidElement(),this._consumeComment(this._advance())):this.peek.type===h.HtmlTokenType.TEXT||this.peek.type===h.HtmlTokenType.RAW_TEXT||this.peek.type===h.HtmlTokenType.ESCAPABLE_RAW_TEXT?(this._closeVoidElement(),this._consumeText(this._advance())):this.peek.type===h.HtmlTokenType.EXPANSION_FORM_START?this._consumeExpansion(this._advance()):this._advance();return new y(this.rootNodes,this.errors)},t.prototype._advance=function(){var t=this.peek;return this.index<this.tokens.length-1&&this.index++,this.peek=this.tokens[this.index],t},t.prototype._advanceIf=function(t){return this.peek.type===t?this._advance():null},t.prototype._consumeCdata=function(t){this._consumeText(this._advance()),this._advanceIf(h.HtmlTokenType.CDATA_END)},t.prototype._consumeComment=function(t){var e=this._advanceIf(h.HtmlTokenType.RAW_TEXT);this._advanceIf(h.HtmlTokenType.COMMENT_END);var n=u.isPresent(e)?e.parts[0].trim():null;this._addToParent(new p.HtmlCommentAst(n,t.sourceSpan))},t.prototype._consumeExpansion=function(t){for(var e=this._advance(),n=this._advance(),r=[];this.peek.type===h.HtmlTokenType.EXPANSION_CASE_VALUE;){var i=this._parseExpansionCase();if(u.isBlank(i))return;r.push(i)}if(this.peek.type!==h.HtmlTokenType.EXPANSION_FORM_END)return void this.errors.push(v.create(null,this.peek.sourceSpan,"Invalid expansion form. Missing '}'."));this._advance();var o=new f.ParseSourceSpan(t.sourceSpan.start,this.peek.sourceSpan.end);this._addToParent(new p.HtmlExpansionAst(e.parts[0],n.parts[0],r,o,e.sourceSpan))},t.prototype._parseExpansionCase=function(){var e=this._advance();if(this.peek.type!==h.HtmlTokenType.EXPANSION_CASE_EXP_START)return this.errors.push(v.create(null,this.peek.sourceSpan,"Invalid expansion form. Missing '{'.,")),null;var n=this._advance(),r=this._collectExpansionExpTokens(n);if(u.isBlank(r))return null;var i=this._advance();r.push(new h.HtmlToken(h.HtmlTokenType.EOF,[],i.sourceSpan));var o=new t(r).build();if(o.errors.length>0)return this.errors=this.errors.concat(o.errors),null;var s=new f.ParseSourceSpan(e.sourceSpan.start,i.sourceSpan.end),a=new f.ParseSourceSpan(n.sourceSpan.start,i.sourceSpan.end);return new p.HtmlExpansionCaseAst(e.parts[0],o.rootNodes,s,e.sourceSpan,a)},t.prototype._collectExpansionExpTokens=function(t){for(var e=[],n=[h.HtmlTokenType.EXPANSION_CASE_EXP_START];;){if((this.peek.type===h.HtmlTokenType.EXPANSION_FORM_START||this.peek.type===h.HtmlTokenType.EXPANSION_CASE_EXP_START)&&n.push(this.peek.type),this.peek.type===h.HtmlTokenType.EXPANSION_CASE_EXP_END){if(!i(n,h.HtmlTokenType.EXPANSION_CASE_EXP_START))return this.errors.push(v.create(null,t.sourceSpan,"Invalid expansion form. Missing '}'.")),null;if(n.pop(),0==n.length)return e}if(this.peek.type===h.HtmlTokenType.EXPANSION_FORM_END){if(!i(n,h.HtmlTokenType.EXPANSION_FORM_START))return this.errors.push(v.create(null,t.sourceSpan,"Invalid expansion form. Missing '}'.")),null;n.pop()}if(this.peek.type===h.HtmlTokenType.EOF)return this.errors.push(v.create(null,t.sourceSpan,"Invalid expansion form. Missing '}'.")),null;e.push(this._advance())}},t.prototype._consumeText=function(t){var e=t.parts[0];if(e.length>0&&"\n"==e[0]){var n=this._getParentElement();u.isPresent(n)&&0==n.children.length&&d.getHtmlTagDefinition(n.name).ignoreFirstLf&&(e=e.substring(1))}e.length>0&&this._addToParent(new p.HtmlTextAst(e,t.sourceSpan))},t.prototype._closeVoidElement=function(){if(this.elementStack.length>0){var t=c.ListWrapper.last(this.elementStack);d.getHtmlTagDefinition(t.name).isVoid&&this.elementStack.pop()}},t.prototype._consumeStartTag=function(t){for(var e=t.parts[0],n=t.parts[1],i=[];this.peek.type===h.HtmlTokenType.ATTR_NAME;)i.push(this._consumeAttr(this._advance()));var o=r(e,n,this._getParentElement()),s=!1;this.peek.type===h.HtmlTokenType.TAG_OPEN_END_VOID?(this._advance(),s=!0,null!=d.getNsPrefix(o)||d.getHtmlTagDefinition(o).isVoid||this.errors.push(v.create(o,t.sourceSpan,'Only void and foreign elements can be self closed "'+t.parts[1]+'"'))):this.peek.type===h.HtmlTokenType.TAG_OPEN_END&&(this._advance(),s=!1);var a=this.peek.sourceSpan.start,u=new f.ParseSourceSpan(t.sourceSpan.start,a),c=new p.HtmlElementAst(o,i,[],u,u,null);this._pushElement(c),s&&(this._popElement(o),c.endSourceSpan=u)},t.prototype._pushElement=function(t){if(this.elementStack.length>0){var e=c.ListWrapper.last(this.elementStack);d.getHtmlTagDefinition(e.name).isClosedByChild(t.name)&&this.elementStack.pop()}var n=d.getHtmlTagDefinition(t.name),e=this._getParentElement();if(n.requireExtraParent(u.isPresent(e)?e.name:null)){var r=new p.HtmlElementAst(n.parentToAdd,[],[t],t.sourceSpan,t.startSourceSpan,t.endSourceSpan);this._addToParent(r),this.elementStack.push(r),this.elementStack.push(t)}else this._addToParent(t),this.elementStack.push(t)},t.prototype._consumeEndTag=function(t){var e=r(t.parts[0],t.parts[1],this._getParentElement());this._getParentElement().endSourceSpan=t.sourceSpan,d.getHtmlTagDefinition(e).isVoid?this.errors.push(v.create(e,t.sourceSpan,'Void elements do not have end tags "'+t.parts[1]+'"')):this._popElement(e)||this.errors.push(v.create(e,t.sourceSpan,'Unexpected closing tag "'+t.parts[1]+'"'))},t.prototype._popElement=function(t){for(var e=this.elementStack.length-1;e>=0;e--){var n=this.elementStack[e];if(n.name==t)return c.ListWrapper.splice(this.elementStack,e,this.elementStack.length-e),!0;if(!d.getHtmlTagDefinition(n.name).closedByParent)return!1}return!1},t.prototype._consumeAttr=function(t){var e=d.mergeNsAndName(t.parts[0],t.parts[1]),n=t.sourceSpan.end,r="";if(this.peek.type===h.HtmlTokenType.ATTR_VALUE){var i=this._advance();r=i.parts[0],n=i.sourceSpan.end}return new p.HtmlAttrAst(e,r,new f.ParseSourceSpan(t.sourceSpan.start,n))},t.prototype._getParentElement=function(){return this.elementStack.length>0?c.ListWrapper.last(this.elementStack):null},t.prototype._addToParent=function(t){var e=this._getParentElement();u.isPresent(e)?e.children.push(t):this.rootNodes.push(t)},t}()},function(t,e,n){"use strict";function r(t,e,n){void 0===n&&(n=null);var r=[];return e.forEach(function(e){var o=e.visit(t,n);i.isPresent(o)&&r.push(o)}),r}var i=n(5),o=function(){function t(t,e){this.value=t,this.sourceSpan=e}return t.prototype.visit=function(t,e){return t.visitText(this,e)},t}();e.HtmlTextAst=o;var s=function(){function t(t,e,n,r,i){this.switchValue=t,this.type=e,this.cases=n,this.sourceSpan=r,this.switchValueSourceSpan=i}return t.prototype.visit=function(t,e){return t.visitExpansion(this,e)},t}();e.HtmlExpansionAst=s;var a=function(){function t(t,e,n,r,i){this.value=t,this.expression=e,this.sourceSpan=n,this.valueSourceSpan=r,this.expSourceSpan=i}return t.prototype.visit=function(t,e){return t.visitExpansionCase(this,e)},t}();e.HtmlExpansionCaseAst=a;var u=function(){function t(t,e,n){this.name=t,this.value=e,this.sourceSpan=n}return t.prototype.visit=function(t,e){return t.visitAttr(this,e)},t}();e.HtmlAttrAst=u;var c=function(){function t(t,e,n,r,i,o){this.name=t,this.attrs=e,this.children=n,this.sourceSpan=r,this.startSourceSpan=i,this.endSourceSpan=o}return t.prototype.visit=function(t,e){return t.visitElement(this,e)},t}();e.HtmlElementAst=c;var p=function(){function t(t,e){this.value=t,this.sourceSpan=e}return t.prototype.visit=function(t,e){return t.visitComment(this,e)},t}();e.HtmlCommentAst=p,e.htmlVisitAll=r},function(t,e,n){"use strict";function r(t,e,n){return void 0===n&&(n=!1),new ut(new P.ParseSourceFile(t,e),n).tokenize()}function i(t){var e=t===O?"EOF":_.StringWrapper.fromCharCode(t);return'Unexpected character "'+e+'"'}function o(t){return'Unknown entity "'+t+'" - use the "&#<decimal>;" or  "&#x<hex>;" syntax'}function s(t){return!a(t)||t===O}function a(t){return t>=T&&I>=t||t===ot}function u(t){return a(t)||t===q||t===L||t===V||t===k||t===X}function c(t){return(et>t||t>rt)&&(J>t||t>tt)&&(B>t||t>U)}function p(t){return t==F||t==O||!d(t)}function l(t){return t==F||t==O||!f(t)}function h(t,e){return t===K&&e!=K}function f(t){return t>=et&&rt>=t||t>=J&&tt>=t}function d(t){return t>=et&&nt>=t||t>=J&&Z>=t||t>=B&&U>=t}function v(t,e){return y(t)==y(e)}function y(t){return t>=et&&rt>=t?t-et+J:t}function m(t){for(var e,n=[],r=0;r<t.length;r++){var i=t[r];_.isPresent(e)&&e.type==w.TEXT&&i.type==w.TEXT?(e.parts[0]+=i.parts[0],e.sourceSpan.end=i.sourceSpan.end):(e=i,n.push(e))}return n}var g=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},_=n(5),b=n(15),P=n(147),E=n(148);!function(t){t[t.TAG_OPEN_START=0]="TAG_OPEN_START",t[t.TAG_OPEN_END=1]="TAG_OPEN_END",t[t.TAG_OPEN_END_VOID=2]="TAG_OPEN_END_VOID",t[t.TAG_CLOSE=3]="TAG_CLOSE",t[t.TEXT=4]="TEXT",t[t.ESCAPABLE_RAW_TEXT=5]="ESCAPABLE_RAW_TEXT",t[t.RAW_TEXT=6]="RAW_TEXT",t[t.COMMENT_START=7]="COMMENT_START",t[t.COMMENT_END=8]="COMMENT_END",t[t.CDATA_START=9]="CDATA_START",t[t.CDATA_END=10]="CDATA_END",t[t.ATTR_NAME=11]="ATTR_NAME",t[t.ATTR_VALUE=12]="ATTR_VALUE",t[t.DOC_TYPE=13]="DOC_TYPE",t[t.EXPANSION_FORM_START=14]="EXPANSION_FORM_START",t[t.EXPANSION_CASE_VALUE=15]="EXPANSION_CASE_VALUE",t[t.EXPANSION_CASE_EXP_START=16]="EXPANSION_CASE_EXP_START",t[t.EXPANSION_CASE_EXP_END=17]="EXPANSION_CASE_EXP_END",t[t.EXPANSION_FORM_END=18]="EXPANSION_FORM_END",t[t.EOF=19]="EOF"}(e.HtmlTokenType||(e.HtmlTokenType={}));var w=e.HtmlTokenType,C=function(){function t(t,e,n){this.type=t,this.parts=e,this.sourceSpan=n}return t}();e.HtmlToken=C;var R=function(t){function e(e,n,r){t.call(this,r,e),this.tokenType=n}return g(e,t),e}(P.ParseError);e.HtmlTokenError=R;var S=function(){function t(t,e){this.tokens=t,this.errors=e}return t}();e.HtmlTokenizeResult=S,e.tokenizeHtml=r;var O=0,T=9,x=10,A=13,I=32,M=33,k=34,N=35,D=38,V=39,j=45,L=47,B=48,F=59,U=57,W=58,H=60,X=61,q=62,G=91,z=93,K=123,$=125,Q=44,J=65,Z=70,Y=88,tt=90,et=97,nt=102,rt=122,it=120,ot=160,st=/\r\n?/g,at=function(){function t(t){this.error=t}return t}(),ut=function(){function t(t,e){this.file=t,this.tokenizeExpansionForms=e,this.peek=-1,this.nextPeek=-1,this.index=-1,this.line=0,this.column=-1,this.expansionCaseStack=[],this.tokens=[],this.errors=[],this.input=t.content,this.length=t.content.length,this._advance()}return t.prototype._processCarriageReturns=function(t){return _.StringWrapper.replaceAll(t,st,"\n")},t.prototype.tokenize=function(){for(;this.peek!==O;){var t=this._getLocation();try{this._attemptCharCode(H)?this._attemptCharCode(M)?this._attemptCharCode(G)?this._consumeCdata(t):this._attemptCharCode(j)?this._consumeComment(t):this._consumeDocType(t):this._attemptCharCode(L)?this._consumeTagClose(t):this._consumeTagOpen(t):h(this.peek,this.nextPeek)&&this.tokenizeExpansionForms?this._consumeExpansionFormStart():this.peek===X&&this.tokenizeExpansionForms?this._consumeExpansionCaseStart():this.peek===$&&this.isInExpansionCase()&&this.tokenizeExpansionForms?this._consumeExpansionCaseEnd():this.peek===$&&this.isInExpansionForm()&&this.tokenizeExpansionForms?this._consumeExpansionFormEnd():this._consumeText()}catch(e){if(!(e instanceof at))throw e;this.errors.push(e.error)}}return this._beginToken(w.EOF),this._endToken([]),new S(m(this.tokens),this.errors)},t.prototype._getLocation=function(){return new P.ParseLocation(this.file,this.index,this.line,this.column)},t.prototype._getSpan=function(t,e){return _.isBlank(t)&&(t=this._getLocation()),
                +_.isBlank(e)&&(e=this._getLocation()),new P.ParseSourceSpan(t,e)},t.prototype._beginToken=function(t,e){void 0===e&&(e=null),_.isBlank(e)&&(e=this._getLocation()),this.currentTokenStart=e,this.currentTokenType=t},t.prototype._endToken=function(t,e){void 0===e&&(e=null),_.isBlank(e)&&(e=this._getLocation());var n=new C(this.currentTokenType,t,new P.ParseSourceSpan(this.currentTokenStart,e));return this.tokens.push(n),this.currentTokenStart=null,this.currentTokenType=null,n},t.prototype._createError=function(t,e){var n=new R(t,this.currentTokenType,e);return this.currentTokenStart=null,this.currentTokenType=null,new at(n)},t.prototype._advance=function(){if(this.index>=this.length)throw this._createError(i(O),this._getSpan());this.peek===x?(this.line++,this.column=0):this.peek!==x&&this.peek!==A&&this.column++,this.index++,this.peek=this.index>=this.length?O:_.StringWrapper.charCodeAt(this.input,this.index),this.nextPeek=this.index+1>=this.length?O:_.StringWrapper.charCodeAt(this.input,this.index+1)},t.prototype._attemptCharCode=function(t){return this.peek===t?(this._advance(),!0):!1},t.prototype._attemptCharCodeCaseInsensitive=function(t){return v(this.peek,t)?(this._advance(),!0):!1},t.prototype._requireCharCode=function(t){var e=this._getLocation();if(!this._attemptCharCode(t))throw this._createError(i(this.peek),this._getSpan(e,e))},t.prototype._attemptStr=function(t){for(var e=0;e<t.length;e++)if(!this._attemptCharCode(_.StringWrapper.charCodeAt(t,e)))return!1;return!0},t.prototype._attemptStrCaseInsensitive=function(t){for(var e=0;e<t.length;e++)if(!this._attemptCharCodeCaseInsensitive(_.StringWrapper.charCodeAt(t,e)))return!1;return!0},t.prototype._requireStr=function(t){var e=this._getLocation();if(!this._attemptStr(t))throw this._createError(i(this.peek),this._getSpan(e))},t.prototype._attemptCharCodeUntilFn=function(t){for(;!t(this.peek);)this._advance()},t.prototype._requireCharCodeUntilFn=function(t,e){var n=this._getLocation();if(this._attemptCharCodeUntilFn(t),this.index-n.offset<e)throw this._createError(i(this.peek),this._getSpan(n,n))},t.prototype._attemptUntilChar=function(t){for(;this.peek!==t;)this._advance()},t.prototype._readChar=function(t){if(t&&this.peek===D)return this._decodeEntity();var e=this.index;return this._advance(),this.input[e]},t.prototype._decodeEntity=function(){var t=this._getLocation();if(this._advance(),!this._attemptCharCode(N)){var e=this._savePosition();if(this._attemptCharCodeUntilFn(l),this.peek!=F)return this._restorePosition(e),"&";this._advance();var n=this.input.substring(t.offset+1,this.index-1),r=E.NAMED_ENTITIES[n];if(_.isBlank(r))throw this._createError(o(n),this._getSpan(t));return r}var s=this._attemptCharCode(it)||this._attemptCharCode(Y),a=this._getLocation().offset;if(this._attemptCharCodeUntilFn(p),this.peek!=F)throw this._createError(i(this.peek),this._getSpan());this._advance();var u=this.input.substring(a,this.index-1);try{var c=_.NumberWrapper.parseInt(u,s?16:10);return _.StringWrapper.fromCharCode(c)}catch(h){var f=this.input.substring(t.offset+1,this.index-1);throw this._createError(o(f),this._getSpan(t))}},t.prototype._consumeRawText=function(t,e,n){var r,i=this._getLocation();this._beginToken(t?w.ESCAPABLE_RAW_TEXT:w.RAW_TEXT,i);for(var o=[];;){if(r=this._getLocation(),this._attemptCharCode(e)&&n())break;for(this.index>r.offset&&o.push(this.input.substring(r.offset,this.index));this.peek!==e;)o.push(this._readChar(t))}return this._endToken([this._processCarriageReturns(o.join(""))],r)},t.prototype._consumeComment=function(t){var e=this;this._beginToken(w.COMMENT_START,t),this._requireCharCode(j),this._endToken([]);var n=this._consumeRawText(!1,j,function(){return e._attemptStr("->")});this._beginToken(w.COMMENT_END,n.sourceSpan.end),this._endToken([])},t.prototype._consumeCdata=function(t){var e=this;this._beginToken(w.CDATA_START,t),this._requireStr("CDATA["),this._endToken([]);var n=this._consumeRawText(!1,z,function(){return e._attemptStr("]>")});this._beginToken(w.CDATA_END,n.sourceSpan.end),this._endToken([])},t.prototype._consumeDocType=function(t){this._beginToken(w.DOC_TYPE,t),this._attemptUntilChar(q),this._advance(),this._endToken([this.input.substring(t.offset+2,this.index-1)])},t.prototype._consumePrefixAndName=function(){for(var t=this.index,e=null;this.peek!==W&&!c(this.peek);)this._advance();var n;this.peek===W?(this._advance(),e=this.input.substring(t,this.index-1),n=this.index):n=t,this._requireCharCodeUntilFn(u,this.index===n?1:0);var r=this.input.substring(n,this.index);return[e,r]},t.prototype._consumeTagOpen=function(t){var e,n=this._savePosition();try{if(!f(this.peek))throw this._createError(i(this.peek),this._getSpan());var r=this.index;for(this._consumeTagOpenStart(t),e=this.input.substring(r,this.index).toLowerCase(),this._attemptCharCodeUntilFn(s);this.peek!==L&&this.peek!==q;)this._consumeAttributeName(),this._attemptCharCodeUntilFn(s),this._attemptCharCode(X)&&(this._attemptCharCodeUntilFn(s),this._consumeAttributeValue()),this._attemptCharCodeUntilFn(s);this._consumeTagOpenEnd()}catch(o){if(o instanceof at)return this._restorePosition(n),this._beginToken(w.TEXT,t),void this._endToken(["<"]);throw o}var a=E.getHtmlTagDefinition(e).contentType;a===E.HtmlTagContentType.RAW_TEXT?this._consumeRawTextWithTagClose(e,!1):a===E.HtmlTagContentType.ESCAPABLE_RAW_TEXT&&this._consumeRawTextWithTagClose(e,!0)},t.prototype._consumeRawTextWithTagClose=function(t,e){var n=this,r=this._consumeRawText(e,H,function(){return n._attemptCharCode(L)?(n._attemptCharCodeUntilFn(s),n._attemptStrCaseInsensitive(t)?(n._attemptCharCodeUntilFn(s),n._attemptCharCode(q)?!0:!1):!1):!1});this._beginToken(w.TAG_CLOSE,r.sourceSpan.end),this._endToken([null,t])},t.prototype._consumeTagOpenStart=function(t){this._beginToken(w.TAG_OPEN_START,t);var e=this._consumePrefixAndName();this._endToken(e)},t.prototype._consumeAttributeName=function(){this._beginToken(w.ATTR_NAME);var t=this._consumePrefixAndName();this._endToken(t)},t.prototype._consumeAttributeValue=function(){this._beginToken(w.ATTR_VALUE);var t;if(this.peek===V||this.peek===k){var e=this.peek;this._advance();for(var n=[];this.peek!==e;)n.push(this._readChar(!0));t=n.join(""),this._advance()}else{var r=this.index;this._requireCharCodeUntilFn(u,1),t=this.input.substring(r,this.index)}this._endToken([this._processCarriageReturns(t)])},t.prototype._consumeTagOpenEnd=function(){var t=this._attemptCharCode(L)?w.TAG_OPEN_END_VOID:w.TAG_OPEN_END;this._beginToken(t),this._requireCharCode(q),this._endToken([])},t.prototype._consumeTagClose=function(t){this._beginToken(w.TAG_CLOSE,t),this._attemptCharCodeUntilFn(s);var e;e=this._consumePrefixAndName(),this._attemptCharCodeUntilFn(s),this._requireCharCode(q),this._endToken(e)},t.prototype._consumeExpansionFormStart=function(){this._beginToken(w.EXPANSION_FORM_START,this._getLocation()),this._requireCharCode(K),this._endToken([]),this._beginToken(w.RAW_TEXT,this._getLocation());var t=this._readUntil(Q);this._endToken([t],this._getLocation()),this._requireCharCode(Q),this._attemptCharCodeUntilFn(s),this._beginToken(w.RAW_TEXT,this._getLocation());var e=this._readUntil(Q);this._endToken([e],this._getLocation()),this._requireCharCode(Q),this._attemptCharCodeUntilFn(s),this.expansionCaseStack.push(w.EXPANSION_FORM_START)},t.prototype._consumeExpansionCaseStart=function(){this._requireCharCode(X),this._beginToken(w.EXPANSION_CASE_VALUE,this._getLocation());var t=this._readUntil(K).trim();this._endToken([t],this._getLocation()),this._attemptCharCodeUntilFn(s),this._beginToken(w.EXPANSION_CASE_EXP_START,this._getLocation()),this._requireCharCode(K),this._endToken([],this._getLocation()),this._attemptCharCodeUntilFn(s),this.expansionCaseStack.push(w.EXPANSION_CASE_EXP_START)},t.prototype._consumeExpansionCaseEnd=function(){this._beginToken(w.EXPANSION_CASE_EXP_END,this._getLocation()),this._requireCharCode($),this._endToken([],this._getLocation()),this._attemptCharCodeUntilFn(s),this.expansionCaseStack.pop()},t.prototype._consumeExpansionFormEnd=function(){this._beginToken(w.EXPANSION_FORM_END,this._getLocation()),this._requireCharCode($),this._endToken([]),this.expansionCaseStack.pop()},t.prototype._consumeText=function(){var t=this._getLocation();this._beginToken(w.TEXT,t);var e=[],n=!1;for(this.peek===K&&this.nextPeek===K?(e.push(this._readChar(!0)),e.push(this._readChar(!0)),n=!0):e.push(this._readChar(!0));!this.isTextEnd(n);)this.peek===K&&this.nextPeek===K?(e.push(this._readChar(!0)),e.push(this._readChar(!0)),n=!0):this.peek===$&&this.nextPeek===$&&n?(e.push(this._readChar(!0)),e.push(this._readChar(!0)),n=!1):e.push(this._readChar(!0));this._endToken([this._processCarriageReturns(e.join(""))])},t.prototype.isTextEnd=function(t){if(this.peek===H||this.peek===O)return!0;if(this.tokenizeExpansionForms){if(h(this.peek,this.nextPeek))return!0;if(this.peek===$&&!t&&(this.isInExpansionCase()||this.isInExpansionForm()))return!0}return!1},t.prototype._savePosition=function(){return[this.peek,this.index,this.column,this.line,this.tokens.length]},t.prototype._readUntil=function(t){var e=this.index;return this._attemptUntilChar(t),this.input.substring(e,this.index)},t.prototype._restorePosition=function(t){this.peek=t[0],this.index=t[1],this.column=t[2],this.line=t[3];var e=t[4];e<this.tokens.length&&(this.tokens=b.ListWrapper.slice(this.tokens,0,e))},t.prototype.isInExpansionCase=function(){return this.expansionCaseStack.length>0&&this.expansionCaseStack[this.expansionCaseStack.length-1]===w.EXPANSION_CASE_EXP_START},t.prototype.isInExpansionForm=function(){return this.expansionCaseStack.length>0&&this.expansionCaseStack[this.expansionCaseStack.length-1]===w.EXPANSION_FORM_START},t}()},function(t,e){"use strict";var n=function(){function t(t,e,n,r){this.file=t,this.offset=e,this.line=n,this.col=r}return t.prototype.toString=function(){return this.file.url+"@"+this.line+":"+this.col},t}();e.ParseLocation=n;var r=function(){function t(t,e){this.content=t,this.url=e}return t}();e.ParseSourceFile=r;var i=function(){function t(t,e){this.start=t,this.end=e}return t.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},t}();e.ParseSourceSpan=i;var o=function(){function t(t,e){this.span=t,this.msg=e}return t.prototype.toString=function(){var t=this.span.start.file.content,e=this.span.start.offset;e>t.length-1&&(e=t.length-1);for(var n=e,r=0,i=0;100>r&&e>0&&(e--,r++,"\n"!=t[e]||3!=++i););for(r=0,i=0;100>r&&n<t.length-1&&(n++,r++,"\n"!=t[n]||3!=++i););var o=t.substring(e,this.span.start.offset)+"[ERROR ->]"+t.substring(this.span.start.offset,n+1);return this.msg+' ("'+o+'"): '+this.span.start},t}();e.ParseError=o},function(t,e,n){"use strict";function r(t){var e=p[t.toLowerCase()];return a.isPresent(e)?e:l}function i(t){if("@"!=t[0])return[null,t];var e=a.RegExpWrapper.firstMatch(h,t);return[e[1],e[2]]}function o(t){return i(t)[0]}function s(t,e){return a.isPresent(t)?"@"+t+":"+e:e}var a=n(5);e.NAMED_ENTITIES=a.CONST_EXPR({Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",alefsym:"ℵ",Alpha:"Α",alpha:"α",amp:"&",and:"∧",ang:"∠",apos:"'",Aring:"Å",aring:"å",asymp:"≈",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",bdquo:"„",Beta:"Β",beta:"β",brvbar:"¦",bull:"•",cap:"∩",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",Chi:"Χ",chi:"χ",circ:"ˆ",clubs:"♣",cong:"≅",copy:"©",crarr:"↵",cup:"∪",curren:"¤",dagger:"†",Dagger:"‡",darr:"↓",dArr:"⇓",deg:"°",Delta:"Δ",delta:"δ",diams:"♦",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",empty:"∅",emsp:" ",ensp:" ",Epsilon:"Ε",epsilon:"ε",equiv:"≡",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",exist:"∃",fnof:"ƒ",forall:"∀",frac12:"½",frac14:"¼",frac34:"¾",frasl:"⁄",Gamma:"Γ",gamma:"γ",ge:"≥",gt:">",harr:"↔",hArr:"⇔",hearts:"♥",hellip:"…",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",image:"ℑ",infin:"∞","int":"∫",Iota:"Ι",iota:"ι",iquest:"¿",isin:"∈",Iuml:"Ï",iuml:"ï",Kappa:"Κ",kappa:"κ",Lambda:"Λ",lambda:"λ",lang:"⟨",laquo:"«",larr:"←",lArr:"⇐",lceil:"⌈",ldquo:"“",le:"≤",lfloor:"⌊",lowast:"∗",loz:"◊",lrm:"‎",lsaquo:"‹",lsquo:"‘",lt:"<",macr:"¯",mdash:"—",micro:"µ",middot:"·",minus:"−",Mu:"Μ",mu:"μ",nabla:"∇",nbsp:" ",ndash:"–",ne:"≠",ni:"∋",not:"¬",notin:"∉",nsub:"⊄",Ntilde:"Ñ",ntilde:"ñ",Nu:"Ν",nu:"ν",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",OElig:"Œ",oelig:"œ",Ograve:"Ò",ograve:"ò",oline:"‾",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",oplus:"⊕",or:"∨",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",otimes:"⊗",Ouml:"Ö",ouml:"ö",para:"¶",permil:"‰",perp:"⊥",Phi:"Φ",phi:"φ",Pi:"Π",pi:"π",piv:"ϖ",plusmn:"±",pound:"£",prime:"′",Prime:"″",prod:"∏",prop:"∝",Psi:"Ψ",psi:"ψ",quot:'"',radic:"√",rang:"⟩",raquo:"»",rarr:"→",rArr:"⇒",rceil:"⌉",rdquo:"”",real:"ℜ",reg:"®",rfloor:"⌋",Rho:"Ρ",rho:"ρ",rlm:"‏",rsaquo:"›",rsquo:"’",sbquo:"‚",Scaron:"Š",scaron:"š",sdot:"⋅",sect:"§",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sim:"∼",spades:"♠",sub:"⊂",sube:"⊆",sum:"∑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supe:"⊇",szlig:"ß",Tau:"Τ",tau:"τ",there4:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thinsp:" ",THORN:"Þ",thorn:"þ",tilde:"˜",times:"×",trade:"™",Uacute:"Ú",uacute:"ú",uarr:"↑",uArr:"⇑",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",Uuml:"Ü",uuml:"ü",weierp:"℘",Xi:"Ξ",xi:"ξ",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ",Yuml:"Ÿ",Zeta:"Ζ",zeta:"ζ",zwj:"‍",zwnj:"‌"}),function(t){t[t.RAW_TEXT=0]="RAW_TEXT",t[t.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",t[t.PARSABLE_DATA=2]="PARSABLE_DATA"}(e.HtmlTagContentType||(e.HtmlTagContentType={}));var u=e.HtmlTagContentType,c=function(){function t(t){var e=this,n=void 0===t?{}:t,r=n.closedByChildren,i=n.requiredParents,o=n.implicitNamespacePrefix,s=n.contentType,c=n.closedByParent,p=n.isVoid,l=n.ignoreFirstLf;this.closedByChildren={},this.closedByParent=!1,a.isPresent(r)&&r.length>0&&r.forEach(function(t){return e.closedByChildren[t]=!0}),this.isVoid=a.normalizeBool(p),this.closedByParent=a.normalizeBool(c)||this.isVoid,a.isPresent(i)&&i.length>0&&(this.requiredParents={},this.parentToAdd=i[0],i.forEach(function(t){return e.requiredParents[t]=!0})),this.implicitNamespacePrefix=o,this.contentType=a.isPresent(s)?s:u.PARSABLE_DATA,this.ignoreFirstLf=a.normalizeBool(l)}return t.prototype.requireExtraParent=function(t){if(a.isBlank(this.requiredParents))return!1;if(a.isBlank(t))return!0;var e=t.toLowerCase();return 1!=this.requiredParents[e]&&"template"!=e},t.prototype.isClosedByChild=function(t){return this.isVoid||a.normalizeBool(this.closedByChildren[t.toLowerCase()])},t}();e.HtmlTagDefinition=c;var p={base:new c({isVoid:!0}),meta:new c({isVoid:!0}),area:new c({isVoid:!0}),embed:new c({isVoid:!0}),link:new c({isVoid:!0}),img:new c({isVoid:!0}),input:new c({isVoid:!0}),param:new c({isVoid:!0}),hr:new c({isVoid:!0}),br:new c({isVoid:!0}),source:new c({isVoid:!0}),track:new c({isVoid:!0}),wbr:new c({isVoid:!0}),p:new c({closedByChildren:["address","article","aside","blockquote","div","dl","fieldset","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","nav","ol","p","pre","section","table","ul"],closedByParent:!0}),thead:new c({closedByChildren:["tbody","tfoot"]}),tbody:new c({closedByChildren:["tbody","tfoot"],closedByParent:!0}),tfoot:new c({closedByChildren:["tbody"],closedByParent:!0}),tr:new c({closedByChildren:["tr"],requiredParents:["tbody","tfoot","thead"],closedByParent:!0}),td:new c({closedByChildren:["td","th"],closedByParent:!0}),th:new c({closedByChildren:["td","th"],closedByParent:!0}),col:new c({requiredParents:["colgroup"],isVoid:!0}),svg:new c({implicitNamespacePrefix:"svg"}),math:new c({implicitNamespacePrefix:"math"}),li:new c({closedByChildren:["li"],closedByParent:!0}),dt:new c({closedByChildren:["dt","dd"]}),dd:new c({closedByChildren:["dt","dd"],closedByParent:!0}),rb:new c({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),rt:new c({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),rtc:new c({closedByChildren:["rb","rtc","rp"],closedByParent:!0}),rp:new c({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),optgroup:new c({closedByChildren:["optgroup"],closedByParent:!0}),option:new c({closedByChildren:["option","optgroup"],closedByParent:!0}),pre:new c({ignoreFirstLf:!0}),listing:new c({ignoreFirstLf:!0}),style:new c({contentType:u.RAW_TEXT}),script:new c({contentType:u.RAW_TEXT}),title:new c({contentType:u.ESCAPABLE_RAW_TEXT}),textarea:new c({contentType:u.ESCAPABLE_RAW_TEXT,ignoreFirstLf:!0})},l=new c;e.getHtmlTagDefinition=r;var h=/^@([^:]+):(.+)/g;e.splitNsName=i,e.getNsPrefix=o,e.mergeNsAndName=s},function(t,e,n){"use strict";var r=n(15),i=n(5),o=n(12),s="",a=i.RegExpWrapper.create("(\\:not\\()|([-\\w]+)|(?:\\.([-\\w]+))|(?:\\[([-\\w*]+)(?:=([^\\]]*))?\\])|(\\))|(\\s*,\\s*)"),u=function(){function t(){this.element=null,this.classNames=[],this.attrs=[],this.notSelectors=[]}return t.parse=function(e){for(var n,s=[],u=function(t,e){e.notSelectors.length>0&&i.isBlank(e.element)&&r.ListWrapper.isEmpty(e.classNames)&&r.ListWrapper.isEmpty(e.attrs)&&(e.element="*"),t.push(e)},c=new t,p=i.RegExpWrapper.matcher(a,e),l=c,h=!1;i.isPresent(n=i.RegExpMatcherWrapper.next(p));){if(i.isPresent(n[1])){if(h)throw new o.BaseException("Nesting :not is not allowed in a selector");h=!0,l=new t,c.notSelectors.push(l)}if(i.isPresent(n[2])&&l.setElement(n[2]),i.isPresent(n[3])&&l.addClassName(n[3]),i.isPresent(n[4])&&l.addAttribute(n[4],n[5]),i.isPresent(n[6])&&(h=!1,l=c),i.isPresent(n[7])){if(h)throw new o.BaseException("Multiple selectors in :not are not supported");u(s,c),c=l=new t}}return u(s,c),s},t.prototype.isElementSelector=function(){return i.isPresent(this.element)&&r.ListWrapper.isEmpty(this.classNames)&&r.ListWrapper.isEmpty(this.attrs)&&0===this.notSelectors.length},t.prototype.setElement=function(t){void 0===t&&(t=null),this.element=t},t.prototype.getMatchingElementTemplate=function(){for(var t=i.isPresent(this.element)?this.element:"div",e=this.classNames.length>0?' class="'+this.classNames.join(" ")+'"':"",n="",r=0;r<this.attrs.length;r+=2){var o=this.attrs[r],s=""!==this.attrs[r+1]?'="'+this.attrs[r+1]+'"':"";n+=" "+o+s}return"<"+t+e+n+"></"+t+">"},t.prototype.addAttribute=function(t,e){void 0===e&&(e=s),this.attrs.push(t),e=i.isPresent(e)?e.toLowerCase():s,this.attrs.push(e)},t.prototype.addClassName=function(t){this.classNames.push(t.toLowerCase())},t.prototype.toString=function(){var t="";if(i.isPresent(this.element)&&(t+=this.element),i.isPresent(this.classNames))for(var e=0;e<this.classNames.length;e++)t+="."+this.classNames[e];if(i.isPresent(this.attrs))for(var e=0;e<this.attrs.length;){var n=this.attrs[e++],r=this.attrs[e++];t+="["+n,r.length>0&&(t+="="+r),t+="]"}return this.notSelectors.forEach(function(e){return t+=":not("+e+")"}),t},t}();e.CssSelector=u;var c=function(){function t(){this._elementMap=new r.Map,this._elementPartialMap=new r.Map,this._classMap=new r.Map,this._classPartialMap=new r.Map,this._attrValueMap=new r.Map,this._attrValuePartialMap=new r.Map,this._listContexts=[]}return t.createNotMatcher=function(e){var n=new t;return n.addSelectables(e,null),n},t.prototype.addSelectables=function(t,e){var n=null;t.length>1&&(n=new p(t),this._listContexts.push(n));for(var r=0;r<t.length;r++)this._addSelectable(t[r],e,n)},t.prototype._addSelectable=function(t,e,n){var o=this,s=t.element,a=t.classNames,u=t.attrs,c=new l(t,e,n);if(i.isPresent(s)){var p=0===u.length&&0===a.length;p?this._addTerminal(o._elementMap,s,c):o=this._addPartial(o._elementPartialMap,s)}if(i.isPresent(a))for(var h=0;h<a.length;h++){var p=0===u.length&&h===a.length-1,f=a[h];p?this._addTerminal(o._classMap,f,c):o=this._addPartial(o._classPartialMap,f)}if(i.isPresent(u))for(var h=0;h<u.length;){var p=h===u.length-2,d=u[h++],v=u[h++];if(p){var y=o._attrValueMap,m=y.get(d);i.isBlank(m)&&(m=new r.Map,y.set(d,m)),this._addTerminal(m,v,c)}else{var g=o._attrValuePartialMap,_=g.get(d);i.isBlank(_)&&(_=new r.Map,g.set(d,_)),o=this._addPartial(_,v)}}},t.prototype._addTerminal=function(t,e,n){var r=t.get(e);i.isBlank(r)&&(r=[],t.set(e,r)),r.push(n)},t.prototype._addPartial=function(e,n){var r=e.get(n);return i.isBlank(r)&&(r=new t,e.set(n,r)),r},t.prototype.match=function(t,e){for(var n=!1,r=t.element,o=t.classNames,a=t.attrs,u=0;u<this._listContexts.length;u++)this._listContexts[u].alreadyMatched=!1;if(n=this._matchTerminal(this._elementMap,r,t,e)||n,n=this._matchPartial(this._elementPartialMap,r,t,e)||n,i.isPresent(o))for(var c=0;c<o.length;c++){var p=o[c];n=this._matchTerminal(this._classMap,p,t,e)||n,n=this._matchPartial(this._classPartialMap,p,t,e)||n}if(i.isPresent(a))for(var c=0;c<a.length;){var l=a[c++],h=a[c++],f=this._attrValueMap.get(l);i.StringWrapper.equals(h,s)||(n=this._matchTerminal(f,s,t,e)||n),n=this._matchTerminal(f,h,t,e)||n;var d=this._attrValuePartialMap.get(l);i.StringWrapper.equals(h,s)||(n=this._matchPartial(d,s,t,e)||n),n=this._matchPartial(d,h,t,e)||n}return n},t.prototype._matchTerminal=function(t,e,n,r){if(i.isBlank(t)||i.isBlank(e))return!1;var o=t.get(e),s=t.get("*");if(i.isPresent(s)&&(o=o.concat(s)),i.isBlank(o))return!1;for(var a,u=!1,c=0;c<o.length;c++)a=o[c],u=a.finalize(n,r)||u;return u},t.prototype._matchPartial=function(t,e,n,r){if(i.isBlank(t)||i.isBlank(e))return!1;var o=t.get(e);return i.isBlank(o)?!1:o.match(n,r)},t}();e.SelectorMatcher=c;var p=function(){function t(t){this.selectors=t,this.alreadyMatched=!1}return t}();e.SelectorListContext=p;var l=function(){function t(t,e,n){this.selector=t,this.cbContext=e,this.listContext=n,this.notSelectors=t.notSelectors}return t.prototype.finalize=function(t,e){var n=!0;if(this.notSelectors.length>0&&(i.isBlank(this.listContext)||!this.listContext.alreadyMatched)){var r=c.createNotMatcher(this.notSelectors);n=!r.match(t,null)}return n&&i.isPresent(e)&&(i.isBlank(this.listContext)||!this.listContext.alreadyMatched)&&(i.isPresent(this.listContext)&&(this.listContext.alreadyMatched=!0),e(this.selector,this.cbContext)),n},t}();e.SelectorContext=l},function(t,e){"use strict";var n=function(){function t(){}return t.prototype.hasProperty=function(t,e){return!0},t.prototype.getMappedPropName=function(t){return t},t}();e.ElementSchemaRegistry=n},function(t,e,n){"use strict";function r(t){var e=null,n=null,r=null,o=!1,_=null;t.attrs.forEach(function(t){var i=t.name.toLowerCase();i==a?e=t.value:i==l?n=t.value:i==p?r=t.value:t.name==v?o=!0:t.name==y&&t.value.length>0&&(_=t.value)}),e=i(e);var b=t.name.toLowerCase(),P=m.OTHER;return s.splitNsName(b)[1]==u?P=m.NG_CONTENT:b==f?P=m.STYLE:b==d?P=m.SCRIPT:b==c&&r==h&&(P=m.STYLESHEET),new g(P,e,n,o,_)}function i(t){return o.isBlank(t)||0===t.length?"*":t}var o=n(5),s=n(148),a="select",u="ng-content",c="link",p="rel",l="href",h="stylesheet",f="style",d="script",v="ngNonBindable",y="ngProjectAs";e.preparseElement=r,function(t){t[t.NG_CONTENT=0]="NG_CONTENT",t[t.STYLE=1]="STYLE",t[t.STYLESHEET=2]="STYLESHEET",t[t.SCRIPT=3]="SCRIPT",t[t.OTHER=4]="OTHER"}(e.PreparsedElementType||(e.PreparsedElementType={}));var m=e.PreparsedElementType,g=function(){function t(t,e,n,r,i){this.type=t,this.selectAttr=e,this.hrefAttr=n,this.nonBindable=r,this.projectAs=i}return t}();e.PreparsedElement=g},function(t,e,n){"use strict";function r(t){if(o.isBlank(t)||0===t.length||"/"==t[0])return!1;var e=o.RegExpWrapper.firstMatch(u,t);return o.isBlank(e)||"package"==e[1]||"asset"==e[1]}function i(t,e,n){var i=[],u=o.StringWrapper.replaceAllMapped(n,a,function(n){var s=o.isPresent(n[1])?n[1]:n[2];return r(s)?(i.push(t.resolve(e,s)),""):n[0]});return new s(u,i)}var o=n(5),s=function(){function t(t,e){this.style=t,this.styleUrls=e}return t}();e.StyleWithImports=s,e.isStyleUrlResolvable=r,e.extractStyleUrls=i;var a=/@import\s+(?:url\()?\s*(?:(?:['"]([^'"]*))|([^;\)\s]*))[^;]*;?/g,u=/^([a-zA-Z\-\+\.]+):/g},function(t,e,n){"use strict";function r(t){return a.StringWrapper.replaceAllMapped(t,u,function(t){return"-"+t[1].toLowerCase()})}function i(t){return a.StringWrapper.replaceAllMapped(t,c,function(t){return t[1].toUpperCase()})}function o(t,e){var n=a.StringWrapper.split(t.trim(),/\s*:\s*/g);return n.length>1?n:e}function s(t){return a.StringWrapper.replaceAll(t,/\W/g,"_")}var a=n(5);e.MODULE_SUFFIX=a.IS_DART?".dart":"";var u=/([A-Z])/g,c=/-([a-z])/g;e.camelCaseToDashCase=r,e.dashCaseToCamelCase=i,e.splitAtColon=o,e.sanitizeIdentifier=s},function(t,e,n){"use strict";function r(t,e){var n=e.useExisting,r=e.useValue,i=e.deps;return new v.CompileProviderMetadata({token:t.token,useClass:t.useClass,useExisting:n,useFactory:t.useFactory,useValue:r,deps:i,multi:t.multi})}function i(t,e){var n=e.eager,r=e.providers;return new d.ProviderAst(t.token,t.multiProvider,t.eager||n,r,t.providerType,t.sourceSpan)}function o(t,e,n,r){return void 0===r&&(r=null),h.isBlank(r)&&(r=[]),h.isPresent(t)&&t.forEach(function(t){if(h.isArray(t))o(t,e,n,r);else{var i;t instanceof v.CompileProviderMetadata?i=t:t instanceof v.CompileTypeMetadata?i=new v.CompileProviderMetadata({token:new v.CompileTokenMetadata({identifier:t}),useClass:t}):n.push(new g("Unknown provider type "+t,e)),h.isPresent(i)&&r.push(i)}}),r}function s(t,e,n){var r=new v.CompileTokenMap;t.forEach(function(t){var i=new v.CompileProviderMetadata({token:new v.CompileTokenMetadata({identifier:t.type}),useClass:t.type});a([i],t.isComponent?d.ProviderAstType.Component:d.ProviderAstType.Directive,!0,e,n,r)});var i=t.filter(function(t){return t.isComponent}).concat(t.filter(function(t){return!t.isComponent}));return i.forEach(function(t){a(o(t.providers,e,n),d.ProviderAstType.PublicService,!1,e,n,r),a(o(t.viewProviders,e,n),d.ProviderAstType.PrivateService,!1,e,n,r)}),r}function a(t,e,n,r,i,o){t.forEach(function(t){var s=o.get(t.token);h.isPresent(s)&&s.multiProvider!==t.multi&&i.push(new g("Mixing multi and non multi provider is not possible for token "+s.token.name,r)),h.isBlank(s)?(s=new d.ProviderAst(t.token,t.multi,n,[t],e,r),o.add(t.token,s)):(t.multi||f.ListWrapper.clear(s.providers),s.providers.push(t))})}function u(t){var e=new v.CompileTokenMap;return h.isPresent(t.viewQueries)&&t.viewQueries.forEach(function(t){return p(e,t)}),t.type.diDeps.forEach(function(t){h.isPresent(t.viewQuery)&&p(e,t.viewQuery)}),e}function c(t){var e=new v.CompileTokenMap;return t.forEach(function(t){h.isPresent(t.queries)&&t.queries.forEach(function(t){return p(e,t)}),t.type.diDeps.forEach(function(t){h.isPresent(t.query)&&p(e,t.query)})}),e}function p(t,e){e.selectors.forEach(function(n){var r=t.get(n);h.isBlank(r)&&(r=[],t.add(n,r)),r.push(e)})}var l=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},h=n(5),f=n(15),d=n(139),v=n(155),y=n(158),m=n(147),g=function(t){function e(e,n){t.call(this,n,e)}return l(e,t),e}(m.ParseError);e.ProviderError=g;var _=function(){function t(t,e){var n=this;this.component=t,this.sourceSpan=e,this.errors=[],this.viewQueries=u(t),this.viewProviders=new v.CompileTokenMap,o(t.viewProviders,e,this.errors).forEach(function(t){h.isBlank(n.viewProviders.get(t.token))&&n.viewProviders.add(t.token,!0)})}return t}();e.ProviderViewContext=_;var b=function(){function t(t,e,n,r,i,o,a){var u=this;this._viewContext=t,this._parent=e,this._isViewRoot=n,this._directiveAsts=r,this._sourceSpan=a,this._transformedProviders=new v.CompileTokenMap,this._seenProviders=new v.CompileTokenMap,this._hasViewContainer=!1,this._attrs={},i.forEach(function(t){return u._attrs[t.name]=t.value});var p=r.map(function(t){return t.directive});this._allProviders=s(p,a,t.errors),this._contentQueries=c(p);var l=new v.CompileTokenMap;this._allProviders.values().forEach(function(t){u._addQueryReadsTo(t.token,l)}),o.forEach(function(t){var e=new v.CompileTokenMetadata({value:t.name});u._addQueryReadsTo(e,l)}),h.isPresent(l.get(y.identifierToken(y.Identifiers.ViewContainerRef)))&&(this._hasViewContainer=!0),this._allProviders.values().forEach(function(t){var e=t.eager||h.isPresent(l.get(t.token));e&&u._getOrCreateLocalProvider(t.providerType,t.token,!0)})}return t.prototype.afterElement=function(){var t=this;this._allProviders.values().forEach(function(e){t._getOrCreateLocalProvider(e.providerType,e.token,!1)})},Object.defineProperty(t.prototype,"transformProviders",{get:function(){return this._transformedProviders.values()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"transformedDirectiveAsts",{get:function(){var t=this._transformedProviders.values().map(function(t){return t.token.identifier}),e=f.ListWrapper.clone(this._directiveAsts);return f.ListWrapper.sort(e,function(e,n){return t.indexOf(e.directive.type)-t.indexOf(n.directive.type)}),e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"transformedHasViewContainer",{get:function(){return this._hasViewContainer},enumerable:!0,configurable:!0}),t.prototype._addQueryReadsTo=function(t,e){this._getQueriesFor(t).forEach(function(n){var r=h.isPresent(n.read)?n.read:t;h.isBlank(e.get(r))&&e.add(r,!0)})},t.prototype._getQueriesFor=function(t){for(var e,n=[],r=this,i=0;null!==r;)e=r._contentQueries.get(t),h.isPresent(e)&&f.ListWrapper.addAll(n,e.filter(function(t){return t.descendants||1>=i})),r._directiveAsts.length>0&&i++,r=r._parent;return e=this._viewContext.viewQueries.get(t),h.isPresent(e)&&f.ListWrapper.addAll(n,e),n},t.prototype._getOrCreateLocalProvider=function(t,e,n){var o=this,s=this._allProviders.get(e);if(h.isBlank(s)||(t===d.ProviderAstType.Directive||t===d.ProviderAstType.PublicService)&&s.providerType===d.ProviderAstType.PrivateService||(t===d.ProviderAstType.PrivateService||t===d.ProviderAstType.PublicService)&&s.providerType===d.ProviderAstType.Builtin)return null;var a=this._transformedProviders.get(e);if(h.isPresent(a))return a;if(h.isPresent(this._seenProviders.get(e)))return this._viewContext.errors.push(new g("Cannot instantiate cyclic dependency! "+e.name,this._sourceSpan)),null;this._seenProviders.add(e,!0);var u=s.providers.map(function(t){var e,i=t.useValue,a=t.useExisting;if(h.isPresent(t.useExisting)){var u=o._getDependency(s.providerType,new v.CompileDiDependencyMetadata({token:t.useExisting}),n);h.isPresent(u.token)?a=u.token:(a=null,i=u.value)}else if(h.isPresent(t.useFactory)){var c=h.isPresent(t.deps)?t.deps:t.useFactory.diDeps;e=c.map(function(t){return o._getDependency(s.providerType,t,n)})}else if(h.isPresent(t.useClass)){var c=h.isPresent(t.deps)?t.deps:t.useClass.diDeps;e=c.map(function(t){return o._getDependency(s.providerType,t,n)})}return r(t,{useExisting:a,useValue:i,deps:e})});return a=i(s,{eager:n,providers:u}),this._transformedProviders.add(e,a),a},t.prototype._getLocalDependency=function(t,e,n){if(void 0===n&&(n=null),e.isAttribute){var r=this._attrs[e.token.value];return new v.CompileDiDependencyMetadata({isValue:!0,value:h.normalizeBlank(r)})}if(h.isPresent(e.query)||h.isPresent(e.viewQuery))return e;if(h.isPresent(e.token)){if(t===d.ProviderAstType.Directive||t===d.ProviderAstType.Component){if(e.token.equalsTo(y.identifierToken(y.Identifiers.Renderer))||e.token.equalsTo(y.identifierToken(y.Identifiers.ElementRef))||e.token.equalsTo(y.identifierToken(y.Identifiers.ChangeDetectorRef))||e.token.equalsTo(y.identifierToken(y.Identifiers.TemplateRef)))return e;e.token.equalsTo(y.identifierToken(y.Identifiers.ViewContainerRef))&&(this._hasViewContainer=!0)}if(e.token.equalsTo(y.identifierToken(y.Identifiers.Injector)))return e;if(h.isPresent(this._getOrCreateLocalProvider(t,e.token,n)))return e}return null},t.prototype._getDependency=function(t,e,n){void 0===n&&(n=null);var r=this,i=n,o=null;if(e.isSkipSelf||(o=this._getLocalDependency(t,e,n)),e.isSelf)h.isBlank(o)&&e.isOptional&&(o=new v.CompileDiDependencyMetadata({isValue:!0,value:null}));else{for(;h.isBlank(o)&&h.isPresent(r._parent);){var s=r;r=r._parent,s._isViewRoot&&(i=!1),o=r._getLocalDependency(d.ProviderAstType.PublicService,e,i)}h.isBlank(o)&&(o=!e.isHost||this._viewContext.component.type.isHost||y.identifierToken(this._viewContext.component.type).equalsTo(e.token)||h.isPresent(this._viewContext.viewProviders.get(e.token))?e:e.isOptional?o=new v.CompileDiDependencyMetadata({
                +isValue:!0,value:null}):null)}return h.isBlank(o)&&this._viewContext.errors.push(new g("No provider for "+e.token.name,this._sourceSpan)),o},t}();e.ProviderElementContext=b},function(t,e,n){"use strict";function r(t){return N[t["class"]](t)}function i(t,e){var n=y.CssSelector.parse(e)[0].getMatchingElementTemplate();return M.create({type:new x({runtime:Object,name:t.name+"_Host",moduleUrl:t.moduleUrl,isHost:!0}),template:new I({template:n,templateUrl:"",styles:[],styleUrls:[],ngContentSelectors:[]}),changeDetection:d.ChangeDetectionStrategy.Default,inputs:[],outputs:[],host:{},lifecycleHooks:[],isComponent:!0,selector:"*",providers:[],viewProviders:[],queries:[],viewQueries:[]})}function o(t,e){return l.isBlank(t)?null:t.map(function(t){return a(t,e)})}function s(t){return l.isBlank(t)?null:t.map(u)}function a(t,e){return l.isArray(t)?o(t,e):l.isString(t)||l.isBlank(t)||l.isBoolean(t)||l.isNumber(t)?t:e(t)}function u(t){return l.isArray(t)?s(t):l.isString(t)||l.isBlank(t)||l.isBoolean(t)||l.isNumber(t)?t:t.toJson()}function c(t){return l.isPresent(t)?t:[]}var p=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},l=n(5),h=n(12),f=n(15),d=n(28),v=n(36),y=n(149),m=n(153),g=n(156),_=n(157),b=/^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))$/g,P=function(){function t(){}return Object.defineProperty(t.prototype,"identifier",{get:function(){return h.unimplemented()},enumerable:!0,configurable:!0}),t}();e.CompileMetadataWithIdentifier=P;var E=function(t){function e(){t.apply(this,arguments)}return p(e,t),Object.defineProperty(e.prototype,"type",{get:function(){return h.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"identifier",{get:function(){return h.unimplemented()},enumerable:!0,configurable:!0}),e}(P);e.CompileMetadataWithType=E,e.metadataFromJson=r;var w=function(){function t(t){var e=void 0===t?{}:t,n=e.runtime,r=e.name,i=e.moduleUrl,o=e.prefix,s=e.value;this.runtime=n,this.name=r,this.prefix=o,this.moduleUrl=i,this.value=s}return t.fromJson=function(e){var n=l.isArray(e.value)?o(e.value,r):a(e.value,r);return new t({name:e.name,prefix:e.prefix,moduleUrl:e.moduleUrl,value:n})},t.prototype.toJson=function(){var t=l.isArray(this.value)?s(this.value):u(this.value);return{"class":"Identifier",name:this.name,moduleUrl:this.moduleUrl,prefix:this.prefix,value:t}},Object.defineProperty(t.prototype,"identifier",{get:function(){return this},enumerable:!0,configurable:!0}),t}();e.CompileIdentifierMetadata=w;var C=function(){function t(t){var e=void 0===t?{}:t,n=e.isAttribute,r=e.isSelf,i=e.isHost,o=e.isSkipSelf,s=e.isOptional,a=e.isValue,u=e.query,c=e.viewQuery,p=e.token,h=e.value;this.isAttribute=l.normalizeBool(n),this.isSelf=l.normalizeBool(r),this.isHost=l.normalizeBool(i),this.isSkipSelf=l.normalizeBool(o),this.isOptional=l.normalizeBool(s),this.isValue=l.normalizeBool(a),this.query=u,this.viewQuery=c,this.token=p,this.value=h}return t.fromJson=function(e){return new t({token:a(e.token,O.fromJson),query:a(e.query,A.fromJson),viewQuery:a(e.viewQuery,A.fromJson),value:e.value,isAttribute:e.isAttribute,isSelf:e.isSelf,isHost:e.isHost,isSkipSelf:e.isSkipSelf,isOptional:e.isOptional,isValue:e.isValue})},t.prototype.toJson=function(){return{token:u(this.token),query:u(this.query),viewQuery:u(this.viewQuery),value:this.value,isAttribute:this.isAttribute,isSelf:this.isSelf,isHost:this.isHost,isSkipSelf:this.isSkipSelf,isOptional:this.isOptional,isValue:this.isValue}},t}();e.CompileDiDependencyMetadata=C;var R=function(){function t(t){var e=t.token,n=t.useClass,r=t.useValue,i=t.useExisting,o=t.useFactory,s=t.deps,a=t.multi;this.token=e,this.useClass=n,this.useValue=r,this.useExisting=i,this.useFactory=o,this.deps=l.normalizeBlank(s),this.multi=l.normalizeBool(a)}return t.fromJson=function(e){return new t({token:a(e.token,O.fromJson),useClass:a(e.useClass,x.fromJson),useExisting:a(e.useExisting,O.fromJson),useValue:a(e.useValue,w.fromJson),useFactory:a(e.useFactory,S.fromJson),multi:e.multi,deps:o(e.deps,C.fromJson)})},t.prototype.toJson=function(){return{"class":"Provider",token:u(this.token),useClass:u(this.useClass),useExisting:u(this.useExisting),useValue:u(this.useValue),useFactory:u(this.useFactory),multi:this.multi,deps:s(this.deps)}},t}();e.CompileProviderMetadata=R;var S=function(){function t(t){var e=t.runtime,n=t.name,r=t.moduleUrl,i=t.prefix,o=t.diDeps,s=t.value;this.runtime=e,this.name=n,this.prefix=i,this.moduleUrl=r,this.diDeps=c(o),this.value=s}return Object.defineProperty(t.prototype,"identifier",{get:function(){return this},enumerable:!0,configurable:!0}),t.fromJson=function(e){return new t({name:e.name,prefix:e.prefix,moduleUrl:e.moduleUrl,value:e.value,diDeps:o(e.diDeps,C.fromJson)})},t.prototype.toJson=function(){return{"class":"Factory",name:this.name,prefix:this.prefix,moduleUrl:this.moduleUrl,value:this.value,diDeps:s(this.diDeps)}},t}();e.CompileFactoryMetadata=S;var O=function(){function t(t){var e=t.value,n=t.identifier,r=t.identifierIsInstance;this.value=e,this.identifier=n,this.identifierIsInstance=l.normalizeBool(r)}return t.fromJson=function(e){return new t({value:e.value,identifier:a(e.identifier,w.fromJson),identifierIsInstance:e.identifierIsInstance})},t.prototype.toJson=function(){return{value:this.value,identifier:u(this.identifier),identifierIsInstance:this.identifierIsInstance}},Object.defineProperty(t.prototype,"runtimeCacheKey",{get:function(){return l.isPresent(this.identifier)?this.identifier.runtime:this.value},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"assetCacheKey",{get:function(){return l.isPresent(this.identifier)?l.isPresent(this.identifier.moduleUrl)&&l.isPresent(_.getUrlScheme(this.identifier.moduleUrl))?this.identifier.name+"|"+this.identifier.moduleUrl+"|"+this.identifierIsInstance:null:this.value},enumerable:!0,configurable:!0}),t.prototype.equalsTo=function(t){var e=this.runtimeCacheKey,n=this.assetCacheKey;return l.isPresent(e)&&e==t.runtimeCacheKey||l.isPresent(n)&&n==t.assetCacheKey},Object.defineProperty(t.prototype,"name",{get:function(){return l.isPresent(this.value)?m.sanitizeIdentifier(this.value):this.identifier.name},enumerable:!0,configurable:!0}),t}();e.CompileTokenMetadata=O;var T=function(){function t(){this._valueMap=new Map,this._values=[]}return t.prototype.add=function(t,e){var n=this.get(t);if(l.isPresent(n))throw new h.BaseException("Can only add to a TokenMap! Token: "+t.name);this._values.push(e);var r=t.runtimeCacheKey;l.isPresent(r)&&this._valueMap.set(r,e);var i=t.assetCacheKey;l.isPresent(i)&&this._valueMap.set(i,e)},t.prototype.get=function(t){var e,n=t.runtimeCacheKey,r=t.assetCacheKey;return l.isPresent(n)&&(e=this._valueMap.get(n)),l.isBlank(e)&&l.isPresent(r)&&(e=this._valueMap.get(r)),e},t.prototype.values=function(){return this._values},Object.defineProperty(t.prototype,"size",{get:function(){return this._values.length},enumerable:!0,configurable:!0}),t}();e.CompileTokenMap=T;var x=function(){function t(t){var e=void 0===t?{}:t,n=e.runtime,r=e.name,i=e.moduleUrl,o=e.prefix,s=e.isHost,a=e.value,u=e.diDeps;this.runtime=n,this.name=r,this.moduleUrl=i,this.prefix=o,this.isHost=l.normalizeBool(s),this.value=a,this.diDeps=c(u)}return t.fromJson=function(e){return new t({name:e.name,moduleUrl:e.moduleUrl,prefix:e.prefix,isHost:e.isHost,value:e.value,diDeps:o(e.diDeps,C.fromJson)})},Object.defineProperty(t.prototype,"identifier",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"type",{get:function(){return this},enumerable:!0,configurable:!0}),t.prototype.toJson=function(){return{"class":"Type",name:this.name,moduleUrl:this.moduleUrl,prefix:this.prefix,isHost:this.isHost,value:this.value,diDeps:s(this.diDeps)}},t}();e.CompileTypeMetadata=x;var A=function(){function t(t){var e=void 0===t?{}:t,n=e.selectors,r=e.descendants,i=e.first,o=e.propertyName,s=e.read;this.selectors=n,this.descendants=l.normalizeBool(r),this.first=l.normalizeBool(i),this.propertyName=o,this.read=s}return t.fromJson=function(e){return new t({selectors:o(e.selectors,O.fromJson),descendants:e.descendants,first:e.first,propertyName:e.propertyName,read:a(e.read,O.fromJson)})},t.prototype.toJson=function(){return{selectors:s(this.selectors),descendants:this.descendants,first:this.first,propertyName:this.propertyName,read:u(this.read)}},t}();e.CompileQueryMetadata=A;var I=function(){function t(t){var e=void 0===t?{}:t,n=e.encapsulation,r=e.template,i=e.templateUrl,o=e.styles,s=e.styleUrls,a=e.ngContentSelectors;this.encapsulation=l.isPresent(n)?n:v.ViewEncapsulation.Emulated,this.template=r,this.templateUrl=i,this.styles=l.isPresent(o)?o:[],this.styleUrls=l.isPresent(s)?s:[],this.ngContentSelectors=l.isPresent(a)?a:[]}return t.fromJson=function(e){return new t({encapsulation:l.isPresent(e.encapsulation)?v.VIEW_ENCAPSULATION_VALUES[e.encapsulation]:e.encapsulation,template:e.template,templateUrl:e.templateUrl,styles:e.styles,styleUrls:e.styleUrls,ngContentSelectors:e.ngContentSelectors})},t.prototype.toJson=function(){return{encapsulation:l.isPresent(this.encapsulation)?l.serializeEnum(this.encapsulation):this.encapsulation,template:this.template,templateUrl:this.templateUrl,styles:this.styles,styleUrls:this.styleUrls,ngContentSelectors:this.ngContentSelectors}},t}();e.CompileTemplateMetadata=I;var M=function(){function t(t){var e=void 0===t?{}:t,n=e.type,r=e.isComponent,i=e.selector,o=e.exportAs,s=e.changeDetection,a=e.inputs,u=e.outputs,p=e.hostListeners,l=e.hostProperties,h=e.hostAttributes,f=e.lifecycleHooks,d=e.providers,v=e.viewProviders,y=e.queries,m=e.viewQueries,g=e.template;this.type=n,this.isComponent=r,this.selector=i,this.exportAs=o,this.changeDetection=s,this.inputs=a,this.outputs=u,this.hostListeners=p,this.hostProperties=l,this.hostAttributes=h,this.lifecycleHooks=c(f),this.providers=c(d),this.viewProviders=c(v),this.queries=c(y),this.viewQueries=c(m),this.template=g}return t.create=function(e){var n=void 0===e?{}:e,r=n.type,i=n.isComponent,o=n.selector,s=n.exportAs,a=n.changeDetection,u=n.inputs,c=n.outputs,p=n.host,h=n.lifecycleHooks,d=n.providers,v=n.viewProviders,y=n.queries,g=n.viewQueries,_=n.template,P={},E={},w={};l.isPresent(p)&&f.StringMapWrapper.forEach(p,function(t,e){var n=l.RegExpWrapper.firstMatch(b,e);l.isBlank(n)?w[e]=t:l.isPresent(n[1])?E[n[1]]=t:l.isPresent(n[2])&&(P[n[2]]=t)});var C={};l.isPresent(u)&&u.forEach(function(t){var e=m.splitAtColon(t,[t,t]);C[e[0]]=e[1]});var R={};return l.isPresent(c)&&c.forEach(function(t){var e=m.splitAtColon(t,[t,t]);R[e[0]]=e[1]}),new t({type:r,isComponent:l.normalizeBool(i),selector:o,exportAs:s,changeDetection:a,inputs:C,outputs:R,hostListeners:P,hostProperties:E,hostAttributes:w,lifecycleHooks:l.isPresent(h)?h:[],providers:d,viewProviders:v,queries:y,viewQueries:g,template:_})},Object.defineProperty(t.prototype,"identifier",{get:function(){return this.type},enumerable:!0,configurable:!0}),t.fromJson=function(e){return new t({isComponent:e.isComponent,selector:e.selector,exportAs:e.exportAs,type:l.isPresent(e.type)?x.fromJson(e.type):e.type,changeDetection:l.isPresent(e.changeDetection)?d.CHANGE_DETECTION_STRATEGY_VALUES[e.changeDetection]:e.changeDetection,inputs:e.inputs,outputs:e.outputs,hostListeners:e.hostListeners,hostProperties:e.hostProperties,hostAttributes:e.hostAttributes,lifecycleHooks:e.lifecycleHooks.map(function(t){return g.LIFECYCLE_HOOKS_VALUES[t]}),template:l.isPresent(e.template)?I.fromJson(e.template):e.template,providers:o(e.providers,r),viewProviders:o(e.viewProviders,r),queries:o(e.queries,A.fromJson),viewQueries:o(e.viewQueries,A.fromJson)})},t.prototype.toJson=function(){return{"class":"Directive",isComponent:this.isComponent,selector:this.selector,exportAs:this.exportAs,type:l.isPresent(this.type)?this.type.toJson():this.type,changeDetection:l.isPresent(this.changeDetection)?l.serializeEnum(this.changeDetection):this.changeDetection,inputs:this.inputs,outputs:this.outputs,hostListeners:this.hostListeners,hostProperties:this.hostProperties,hostAttributes:this.hostAttributes,lifecycleHooks:this.lifecycleHooks.map(function(t){return l.serializeEnum(t)}),template:l.isPresent(this.template)?this.template.toJson():this.template,providers:s(this.providers),viewProviders:s(this.viewProviders),queries:s(this.queries),viewQueries:s(this.viewQueries)}},t}();e.CompileDirectiveMetadata=M,e.createHostComponentMeta=i;var k=function(){function t(t){var e=void 0===t?{}:t,n=e.type,r=e.name,i=e.pure,o=e.lifecycleHooks;this.type=n,this.name=r,this.pure=l.normalizeBool(i),this.lifecycleHooks=c(o)}return Object.defineProperty(t.prototype,"identifier",{get:function(){return this.type},enumerable:!0,configurable:!0}),t.fromJson=function(e){return new t({type:l.isPresent(e.type)?x.fromJson(e.type):e.type,name:e.name,pure:e.pure})},t.prototype.toJson=function(){return{"class":"Pipe",type:l.isPresent(this.type)?this.type.toJson():null,name:this.name,pure:this.pure}},t}();e.CompilePipeMetadata=k;var N={Directive:M.fromJson,Pipe:k.fromJson,Type:x.fromJson,Provider:R.fromJson,Identifier:w.fromJson,Factory:S.fromJson}},function(t,e){"use strict";!function(t){t[t.OnInit=0]="OnInit",t[t.OnDestroy=1]="OnDestroy",t[t.DoCheck=2]="DoCheck",t[t.OnChanges=3]="OnChanges",t[t.AfterContentInit=4]="AfterContentInit",t[t.AfterContentChecked=5]="AfterContentChecked",t[t.AfterViewInit=6]="AfterViewInit",t[t.AfterViewChecked=7]="AfterViewChecked"}(e.LifecycleHooks||(e.LifecycleHooks={}));var n=e.LifecycleHooks;e.LIFECYCLE_HOOKS_VALUES=[n.OnInit,n.OnDestroy,n.DoCheck,n.OnChanges,n.AfterContentInit,n.AfterContentChecked,n.AfterViewInit,n.AfterViewChecked]},function(t,e,n){"use strict";function r(){return new _}function i(){return new _(g)}function o(t){var e=a(t);return e&&e[b.Scheme]||""}function s(t,e,n,r,i,o,s){var a=[];return v.isPresent(t)&&a.push(t+":"),v.isPresent(n)&&(a.push("//"),v.isPresent(e)&&a.push(e+"@"),a.push(n),v.isPresent(r)&&a.push(":"+r)),v.isPresent(i)&&a.push(i),v.isPresent(o)&&a.push("?"+o),v.isPresent(s)&&a.push("#"+s),a.join("")}function a(t){return v.RegExpWrapper.firstMatch(P,t)}function u(t){if("/"==t)return"/";for(var e="/"==t[0]?"/":"",n="/"===t[t.length-1]?"/":"",r=t.split("/"),i=[],o=0,s=0;s<r.length;s++){var a=r[s];switch(a){case"":case".":break;case"..":i.length>0?i.pop():o++;break;default:i.push(a)}}if(""==e){for(;o-- >0;)i.unshift("..");0===i.length&&i.push(".")}return e+i.join("/")+n}function c(t){var e=t[b.Path];return e=v.isBlank(e)?"":u(e),t[b.Path]=e,s(t[b.Scheme],t[b.UserInfo],t[b.Domain],t[b.Port],e,t[b.QueryData],t[b.Fragment])}function p(t,e){var n=a(encodeURI(e)),r=a(t);if(v.isPresent(n[b.Scheme]))return c(n);n[b.Scheme]=r[b.Scheme];for(var i=b.Scheme;i<=b.Port;i++)v.isBlank(n[i])&&(n[i]=r[i]);if("/"==n[b.Path][0])return c(n);var o=r[b.Path];v.isBlank(o)&&(o="/");var s=o.lastIndexOf("/");return o=o.substring(0,s+1)+n[b.Path],n[b.Path]=o,c(n)}var l=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},h=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},f=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},d=n(6),v=n(5),y=n(62),m=n(6),g="asset:";e.createUrlResolverWithoutPackagePrefix=r,e.createOfflineCompileUrlResolver=i,e.DEFAULT_PACKAGE_URL_PROVIDER=new m.Provider(y.PACKAGE_ROOT_URL,{useValue:"/"});var _=function(){function t(t){void 0===t&&(t=null),this._packagePrefix=t}return t.prototype.resolve=function(t,e){var n=e;v.isPresent(t)&&t.length>0&&(n=p(t,n));var r=a(n),i=this._packagePrefix;if(v.isPresent(i)&&v.isPresent(r)&&"package"==r[b.Scheme]){var o=r[b.Path];if(this._packagePrefix!==g)return i=v.StringWrapper.stripRight(i,"/"),o=v.StringWrapper.stripLeft(o,"/"),i+"/"+o;var s=o.split(/\//);n="asset:"+s[0]+"/lib/"+s.slice(1).join("/")}return n},t=l([d.Injectable(),f(0,d.Inject(y.PACKAGE_ROOT_URL)),h("design:paramtypes",[String])],t)}();e.UrlResolver=_,e.getUrlScheme=o;var b,P=v.RegExpWrapper.create("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$");!function(t){t[t.Scheme=1]="Scheme",t[t.UserInfo=2]="UserInfo",t[t.Domain=3]="Domain",t[t.Port=4]="Port",t[t.Path=5]="Path",t[t.QueryData=6]="QueryData",t[t.Fragment=7]="Fragment"}(b||(b={}))},function(t,e,n){"use strict";function r(t){return new i.CompileTokenMetadata({identifier:t})}var i=n(155),o=n(159),s=n(160),a=n(66),u=n(28),c=n(67),p=n(69),l=n(70),h=n(74),f=n(36),d=n(68),v=n(78),y=n(11),m=n(81),g=n(153),_="asset:angular2/lib/src/core/linker/view"+g.MODULE_SUFFIX,b="asset:angular2/lib/src/core/linker/view_utils"+g.MODULE_SUFFIX,P="asset:angular2/lib/src/core/change_detection/change_detection"+g.MODULE_SUFFIX,E=a.ViewUtils,w=o.AppView,C=s.DebugContext,R=c.AppElement,S=p.ElementRef,O=l.ViewContainerRef,T=u.ChangeDetectorRef,x=h.RenderComponentType,A=v.QueryList,I=m.TemplateRef,M=m.TemplateRef_,k=u.ValueUnwrapper,N=y.Injector,D=f.ViewEncapsulation,V=d.ViewType,j=u.ChangeDetectionStrategy,L=s.StaticNodeDebugInfo,B=h.Renderer,F=u.SimpleChange,U=u.uninitialized,W=u.ChangeDetectorState,H=a.flattenNestedViewRenderNodes,X=u.devModeEqual,q=a.interpolate,G=a.checkBinding,z=a.castByValue,K=function(){function t(){}return t.ViewUtils=new i.CompileIdentifierMetadata({name:"ViewUtils",moduleUrl:"asset:angular2/lib/src/core/linker/view_utils"+g.MODULE_SUFFIX,runtime:E}),t.AppView=new i.CompileIdentifierMetadata({name:"AppView",moduleUrl:_,runtime:w}),t.AppElement=new i.CompileIdentifierMetadata({name:"AppElement",moduleUrl:"asset:angular2/lib/src/core/linker/element"+g.MODULE_SUFFIX,runtime:R}),t.ElementRef=new i.CompileIdentifierMetadata({name:"ElementRef",moduleUrl:"asset:angular2/lib/src/core/linker/element_ref"+g.MODULE_SUFFIX,runtime:S}),t.ViewContainerRef=new i.CompileIdentifierMetadata({name:"ViewContainerRef",moduleUrl:"asset:angular2/lib/src/core/linker/view_container_ref"+g.MODULE_SUFFIX,runtime:O}),t.ChangeDetectorRef=new i.CompileIdentifierMetadata({name:"ChangeDetectorRef",moduleUrl:"asset:angular2/lib/src/core/change_detection/change_detector_ref"+g.MODULE_SUFFIX,runtime:T}),t.RenderComponentType=new i.CompileIdentifierMetadata({name:"RenderComponentType",moduleUrl:"asset:angular2/lib/src/core/render/api"+g.MODULE_SUFFIX,runtime:x}),t.QueryList=new i.CompileIdentifierMetadata({name:"QueryList",moduleUrl:"asset:angular2/lib/src/core/linker/query_list"+g.MODULE_SUFFIX,runtime:A}),t.TemplateRef=new i.CompileIdentifierMetadata({name:"TemplateRef",moduleUrl:"asset:angular2/lib/src/core/linker/template_ref"+g.MODULE_SUFFIX,runtime:I}),t.TemplateRef_=new i.CompileIdentifierMetadata({name:"TemplateRef_",moduleUrl:"asset:angular2/lib/src/core/linker/template_ref"+g.MODULE_SUFFIX,runtime:M}),t.ValueUnwrapper=new i.CompileIdentifierMetadata({name:"ValueUnwrapper",moduleUrl:P,runtime:k}),t.Injector=new i.CompileIdentifierMetadata({name:"Injector",moduleUrl:"asset:angular2/lib/src/core/di/injector"+g.MODULE_SUFFIX,runtime:N}),t.ViewEncapsulation=new i.CompileIdentifierMetadata({name:"ViewEncapsulation",moduleUrl:"asset:angular2/lib/src/core/metadata/view"+g.MODULE_SUFFIX,runtime:D}),t.ViewType=new i.CompileIdentifierMetadata({name:"ViewType",moduleUrl:"asset:angular2/lib/src/core/linker/view_type"+g.MODULE_SUFFIX,runtime:V}),t.ChangeDetectionStrategy=new i.CompileIdentifierMetadata({name:"ChangeDetectionStrategy",moduleUrl:P,runtime:j}),t.StaticNodeDebugInfo=new i.CompileIdentifierMetadata({name:"StaticNodeDebugInfo",moduleUrl:"asset:angular2/lib/src/core/linker/debug_context"+g.MODULE_SUFFIX,runtime:L}),t.DebugContext=new i.CompileIdentifierMetadata({name:"DebugContext",moduleUrl:"asset:angular2/lib/src/core/linker/debug_context"+g.MODULE_SUFFIX,runtime:C}),t.Renderer=new i.CompileIdentifierMetadata({name:"Renderer",moduleUrl:"asset:angular2/lib/src/core/render/api"+g.MODULE_SUFFIX,runtime:B}),t.SimpleChange=new i.CompileIdentifierMetadata({name:"SimpleChange",moduleUrl:P,runtime:F}),t.uninitialized=new i.CompileIdentifierMetadata({name:"uninitialized",moduleUrl:P,runtime:U}),t.ChangeDetectorState=new i.CompileIdentifierMetadata({name:"ChangeDetectorState",moduleUrl:P,runtime:W}),t.checkBinding=new i.CompileIdentifierMetadata({name:"checkBinding",moduleUrl:b,runtime:G}),t.flattenNestedViewRenderNodes=new i.CompileIdentifierMetadata({name:"flattenNestedViewRenderNodes",moduleUrl:b,runtime:H}),t.devModeEqual=new i.CompileIdentifierMetadata({name:"devModeEqual",moduleUrl:P,runtime:X}),t.interpolate=new i.CompileIdentifierMetadata({name:"interpolate",moduleUrl:b,runtime:q}),t.castByValue=new i.CompileIdentifierMetadata({name:"castByValue",moduleUrl:b,runtime:z}),t.pureProxies=[null,new i.CompileIdentifierMetadata({name:"pureProxy1",moduleUrl:b,runtime:a.pureProxy1}),new i.CompileIdentifierMetadata({name:"pureProxy2",moduleUrl:b,runtime:a.pureProxy2}),new i.CompileIdentifierMetadata({name:"pureProxy3",moduleUrl:b,runtime:a.pureProxy3}),new i.CompileIdentifierMetadata({name:"pureProxy4",moduleUrl:b,runtime:a.pureProxy4}),new i.CompileIdentifierMetadata({name:"pureProxy5",moduleUrl:b,runtime:a.pureProxy5}),new i.CompileIdentifierMetadata({name:"pureProxy6",moduleUrl:b,runtime:a.pureProxy6}),new i.CompileIdentifierMetadata({name:"pureProxy7",moduleUrl:b,runtime:a.pureProxy7}),new i.CompileIdentifierMetadata({name:"pureProxy8",moduleUrl:b,runtime:a.pureProxy8}),new i.CompileIdentifierMetadata({name:"pureProxy9",moduleUrl:b,runtime:a.pureProxy9}),new i.CompileIdentifierMetadata({name:"pureProxy10",moduleUrl:b,runtime:a.pureProxy10})],t}();e.Identifiers=K,e.identifierToken=r},function(t,e,n){"use strict";function r(t){var e;if(t instanceof o.AppElement){var n=t;if(e=n.nativeElement,s.isPresent(n.nestedViews))for(var i=n.nestedViews.length-1;i>=0;i--){var a=n.nestedViews[i];a.rootNodesOrAppElements.length>0&&(e=r(a.rootNodesOrAppElements[a.rootNodesOrAppElements.length-1]))}}else e=t;return e}var i=n(15),o=n(67),s=n(5),a=n(40),u=n(82),c=n(68),p=n(66),l=n(28),h=n(71),f=n(73),d=n(160),v=n(161),y=s.CONST_EXPR(new Object),m=h.wtfCreateScope("AppView#check(ascii id)"),g=function(){function t(t,e,n,r,i,o,s,a,p){this.clazz=t,this.componentType=e,this.type=n,this.locals=r,this.viewUtils=i,this.parentInjector=o,this.declarationAppElement=s,this.cdMode=a,this.staticNodeDebugInfos=p,this.contentChildren=[],this.viewChildren=[],this.viewContainerElement=null,this.cdState=l.ChangeDetectorState.NeverChecked,this.context=null,this.destroyed=!1,this._currentDebugContext=null,this.ref=new u.ViewRef_(this),n===c.ViewType.COMPONENT||n===c.ViewType.HOST?this.renderer=i.renderComponent(e):this.renderer=s.parentView.renderer}return t.prototype.create=function(t,e){var n,r;switch(this.type){case c.ViewType.COMPONENT:n=this.declarationAppElement.component,r=p.ensureSlotCount(t,this.componentType.slotCount);break;case c.ViewType.EMBEDDED:n=this.declarationAppElement.parentView.context,r=this.declarationAppElement.parentView.projectableNodes;break;case c.ViewType.HOST:n=y,r=t}if(this._hasExternalHostElement=s.isPresent(e),this.context=n,this.projectableNodes=r,!this.debugMode)return this.createInternal(e);this._resetDebug();try{return this.createInternal(e)}catch(i){throw this._rethrowWithContext(i,i.stack),i}},t.prototype.createInternal=function(t){return null},t.prototype.init=function(t,e,n,r){this.rootNodesOrAppElements=t,this.allNodes=e,this.disposables=n,this.subscriptions=r,this.type===c.ViewType.COMPONENT&&(this.declarationAppElement.parentView.viewChildren.push(this),this.renderParent=this.declarationAppElement.parentView,this.dirtyParentQueriesInternal())},t.prototype.selectOrCreateHostElement=function(t,e,n){var r;return r=s.isPresent(e)?this.renderer.selectRootElement(e,n):this.renderer.createElement(null,t,n)},t.prototype.injectorGet=function(t,e,n){if(!this.debugMode)return this.injectorGetInternal(t,e,n);this._resetDebug();try{return this.injectorGetInternal(t,e,n)}catch(r){throw this._rethrowWithContext(r,r.stack),r}},t.prototype.injectorGetInternal=function(t,e,n){return n},t.prototype.injector=function(t){return s.isPresent(t)?new v.ElementInjector(this,t):this.parentInjector},t.prototype.destroy=function(){this._hasExternalHostElement?this.renderer.detachView(this.flatRootNodes):s.isPresent(this.viewContainerElement)&&this.viewContainerElement.detachView(this.viewContainerElement.nestedViews.indexOf(this)),this._destroyRecurse()},t.prototype._destroyRecurse=function(){if(!this.destroyed){for(var t=this.contentChildren,e=0;e<t.length;e++)t[e]._destroyRecurse();t=this.viewChildren;for(var e=0;e<t.length;e++)t[e]._destroyRecurse();if(this.debugMode){this._resetDebug();try{this._destroyLocal()}catch(n){throw this._rethrowWithContext(n,n.stack),n}}else this._destroyLocal();this.destroyed=!0}},t.prototype._destroyLocal=function(){for(var t=this.type===c.ViewType.COMPONENT?this.declarationAppElement.nativeElement:null,e=0;e<this.disposables.length;e++)this.disposables[e]();for(var e=0;e<this.subscriptions.length;e++)a.ObservableWrapper.dispose(this.subscriptions[e]);this.destroyInternal(),this._hasExternalHostElement?this.renderer.detachView(this.flatRootNodes):s.isPresent(this.viewContainerElement)?this.viewContainerElement.detachView(this.viewContainerElement.nestedViews.indexOf(this)):this.dirtyParentQueriesInternal(),this.renderer.destroyView(t,this.allNodes)},t.prototype.destroyInternal=function(){},Object.defineProperty(t.prototype,"debugMode",{get:function(){return s.isPresent(this.staticNodeDebugInfos)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"changeDetectorRef",{get:function(){return this.ref},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{get:function(){return s.isPresent(this.declarationAppElement)?this.declarationAppElement.parentView:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"flatRootNodes",{get:function(){return p.flattenNestedViewRenderNodes(this.rootNodesOrAppElements)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"lastRootNode",{get:function(){var t=this.rootNodesOrAppElements.length>0?this.rootNodesOrAppElements[this.rootNodesOrAppElements.length-1]:null;return r(t)},enumerable:!0,configurable:!0}),t.prototype.hasLocal=function(t){return i.StringMapWrapper.contains(this.locals,t)},t.prototype.setLocal=function(t,e){this.locals[t]=e},t.prototype.dirtyParentQueriesInternal=function(){},t.prototype.addRenderContentChild=function(t){this.contentChildren.push(t),t.renderParent=this,t.dirtyParentQueriesInternal()},t.prototype.removeContentChild=function(t){i.ListWrapper.remove(this.contentChildren,t),t.dirtyParentQueriesInternal(),t.renderParent=null},t.prototype.detectChanges=function(t){var e=m(this.clazz);if(this.cdMode!==l.ChangeDetectionStrategy.Detached&&this.cdMode!==l.ChangeDetectionStrategy.Checked&&this.cdState!==l.ChangeDetectorState.Errored){if(this.destroyed&&this.throwDestroyedError("detectChanges"),this.debugMode){this._resetDebug();try{this.detectChangesInternal(t)}catch(n){throw this._rethrowWithContext(n,n.stack),n}}else this.detectChangesInternal(t);this.cdMode===l.ChangeDetectionStrategy.CheckOnce&&(this.cdMode=l.ChangeDetectionStrategy.Checked),this.cdState=l.ChangeDetectorState.CheckedBefore,h.wtfLeave(e)}},t.prototype.detectChangesInternal=function(t){this.detectContentChildrenChanges(t),this.detectViewChildrenChanges(t)},t.prototype.detectContentChildrenChanges=function(t){for(var e=0;e<this.contentChildren.length;++e)this.contentChildren[e].detectChanges(t)},t.prototype.detectViewChildrenChanges=function(t){for(var e=0;e<this.viewChildren.length;++e)this.viewChildren[e].detectChanges(t)},t.prototype.addToContentChildren=function(t){t.parentView.contentChildren.push(this),this.viewContainerElement=t,this.dirtyParentQueriesInternal()},t.prototype.removeFromContentChildren=function(t){i.ListWrapper.remove(t.parentView.contentChildren,this),this.dirtyParentQueriesInternal(),this.viewContainerElement=null},t.prototype.markAsCheckOnce=function(){this.cdMode=l.ChangeDetectionStrategy.CheckOnce},t.prototype.markPathToRootAsCheckOnce=function(){for(var t=this;s.isPresent(t)&&t.cdMode!==l.ChangeDetectionStrategy.Detached;)t.cdMode===l.ChangeDetectionStrategy.Checked&&(t.cdMode=l.ChangeDetectionStrategy.CheckOnce),t=t.renderParent},t.prototype._resetDebug=function(){this._currentDebugContext=null},t.prototype.debug=function(t,e,n){return this._currentDebugContext=new d.DebugContext(this,t,e,n)},t.prototype._rethrowWithContext=function(t,e){if(!(t instanceof f.ViewWrappedException)&&(t instanceof f.ExpressionChangedAfterItHasBeenCheckedException||(this.cdState=l.ChangeDetectorState.Errored),s.isPresent(this._currentDebugContext)))throw new f.ViewWrappedException(t,e,this._currentDebugContext)},t.prototype.eventHandler=function(t){var e=this;return this.debugMode?function(n){e._resetDebug();try{return t(n)}catch(r){throw e._rethrowWithContext(r,r.stack),r}}:t},t.prototype.throwDestroyedError=function(t){throw new f.ViewDestroyedException(t)},t}();e.AppView=g},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=n(15),a=n(68),u=function(){function t(t,e,n){this.providerTokens=t,this.componentToken=e,this.varTokens=n}return t=r([o.CONST(),i("design:paramtypes",[Array,Object,Object])],t)}();e.StaticNodeDebugInfo=u;var c=function(){function t(t,e,n,r){this._view=t,this._nodeIndex=e,this._tplRow=n,this._tplCol=r}return Object.defineProperty(t.prototype,"_staticNodeInfo",{get:function(){return o.isPresent(this._nodeIndex)?this._view.staticNodeDebugInfos[this._nodeIndex]:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"context",{get:function(){return this._view.context},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"component",{get:function(){var t=this._staticNodeInfo;return o.isPresent(t)&&o.isPresent(t.componentToken)?this.injector.get(t.componentToken):null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"componentRenderElement",{get:function(){for(var t=this._view;o.isPresent(t.declarationAppElement)&&t.type!==a.ViewType.COMPONENT;)t=t.declarationAppElement.parentView;return o.isPresent(t.declarationAppElement)?t.declarationAppElement.nativeElement:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return this._view.injector(this._nodeIndex)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderNode",{get:function(){return o.isPresent(this._nodeIndex)&&o.isPresent(this._view.allNodes)?this._view.allNodes[this._nodeIndex]:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"providerTokens",{get:function(){var t=this._staticNodeInfo;return o.isPresent(t)?t.providerTokens:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"source",{get:function(){return this._view.componentType.templateUrl+":"+this._tplRow+":"+this._tplCol},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"locals",{get:function(){var t=this,e={};return s.ListWrapper.forEachWithIndex(this._view.staticNodeDebugInfos,function(n,r){var i=n.varTokens;s.StringMapWrapper.forEach(i,function(n,i){var s;s=o.isBlank(n)?o.isPresent(t._view.allNodes)?t._view.allNodes[r]:null:t._view.injectorGet(n,r,null),
                +e[i]=s})}),s.StringMapWrapper.forEach(this._view.locals,function(t,n){e[n]=t}),e},enumerable:!0,configurable:!0}),t}();e.DebugContext=c},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(11),s=i.CONST_EXPR(new Object),a=function(t){function e(e,n){t.call(this),this._view=e,this._nodeIndex=n}return r(e,t),e.prototype.get=function(t,e){void 0===e&&(e=o.THROW_IF_NOT_FOUND);var n=s;return n===s&&(n=this._view.injectorGet(t,this._nodeIndex,s)),n===s&&(n=this._view.parentInjector.get(t,e)),n},e}(o.Injector);e.ElementInjector=a},function(t,e,n){"use strict";var r=n(5),i=n(12),o=n(158),s=function(){function t(t,e,n,i){void 0===i&&(i=null),this.genDebugInfo=t,this.logBindingUpdate=e,this.useJit=n,r.isBlank(i)&&(i=new u),this.renderTypes=i}return t}();e.CompilerConfig=s;var a=function(){function t(){}return Object.defineProperty(t.prototype,"renderer",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderText",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderElement",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderComment",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderNode",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"renderEvent",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),t}();e.RenderTypes=a;var u=function(){function t(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return t}();e.DefaultRenderTypes=u},function(t,e,n){"use strict";function r(t){return t.dependencies.forEach(function(t){t.factoryPlaceholder.moduleUrl=o(t.comp)}),t.statements}function i(t){return t.dependencies.forEach(function(t){t.valuePlaceholder.moduleUrl=s(t.sourceUrl,t.isShimmed)}),t.statements}function o(t){var e=t.type.moduleUrl,n=e.substring(0,e.length-f.MODULE_SUFFIX.length);return n+".ngfactory"+f.MODULE_SUFFIX}function s(t,e){return e?t+".shim"+f.MODULE_SUFFIX:""+t+f.MODULE_SUFFIX}function a(t){if(!t.isComponent)throw new c.BaseException("Could not compile '"+t.type.name+"' because it is not a component.")}var u=n(155),c=n(12),p=n(15),l=n(164),h=n(65),f=n(153),d=new u.CompileIdentifierMetadata({name:"ComponentFactory",runtime:h.ComponentFactory,moduleUrl:"asset:angular2/lib/src/core/linker/component_factory"+f.MODULE_SUFFIX}),v=function(){function t(t,e){this.moduleUrl=t,this.source=e}return t}();e.SourceModule=v;var y=function(){function t(t,e,n){this.component=t,this.directives=e,this.pipes=n}return t}();e.NormalizedComponentWithViewDirectives=y;var m=function(){function t(t,e,n,r,i){this._directiveNormalizer=t,this._templateParser=e,this._styleCompiler=n,this._viewCompiler=r,this._outputEmitter=i}return t.prototype.normalizeDirectiveMetadata=function(t){return this._directiveNormalizer.normalizeDirective(t)},t.prototype.compileTemplates=function(t){var e=this;if(0===t.length)throw new c.BaseException("No components given");var n=[],r=[],i=o(t[0].component);return t.forEach(function(t){var i=t.component;a(i);var o=e._compileComponent(i,t.directives,t.pipes,n);r.push(o);var s=u.createHostComponentMeta(i.type,i.selector),c=e._compileComponent(s,[i],[],n),p=i.type.name+"NgFactory";n.push(l.variable(p).set(l.importExpr(d).instantiate([l.literal(i.selector),l.variable(c),l.importExpr(i.type)],l.importType(d,null,[l.TypeModifier.Const]))).toDeclStmt(null,[l.StmtModifier.Final])),r.push(p)}),this._codegenSourceModule(i,n,r)},t.prototype.compileStylesheet=function(t,e){var n=this._styleCompiler.compileStylesheet(t,e,!1),r=this._styleCompiler.compileStylesheet(t,e,!0);return[this._codegenSourceModule(s(t,!1),i(n),[n.stylesVar]),this._codegenSourceModule(s(t,!0),i(r),[r.stylesVar])]},t.prototype._compileComponent=function(t,e,n,o){var s=this._styleCompiler.compileComponent(t),a=this._templateParser.parse(t,t.template.template,e,n,t.type.name),u=this._viewCompiler.compileComponent(t,a,l.variable(s.stylesVar),n);return p.ListWrapper.addAll(o,i(s)),p.ListWrapper.addAll(o,r(u)),u.viewFactoryVar},t.prototype._codegenSourceModule=function(t,e,n){return new v(t,this._outputEmitter.emitStatements(t,e,n))},t}();e.OfflineCompiler=m},function(t,e,n){"use strict";function r(t,e,n){var r=new ot(t,e);return n.visitExpression(r,null)}function i(t){var e=new st;return e.visitAllStatements(t,null),e.varNames}function o(t,e){return void 0===e&&(e=null),new C(t,e)}function s(t,e){return void 0===e&&(e=null),new M(t,null,e)}function a(t,e,n){return void 0===e&&(e=null),void 0===n&&(n=null),d.isPresent(t)?new g(t,e,n):null}function u(t,e){return void 0===e&&(e=null),new I(t,e)}function c(t,e){return void 0===e&&(e=null),new U(t,e)}function p(t,e){return void 0===e&&(e=null),new W(t,e)}function l(t){return new N(t)}function h(t,e,n){return void 0===n&&(n=null),new j(t,e,n)}var f=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},d=n(5);!function(t){t[t.Const=0]="Const"}(e.TypeModifier||(e.TypeModifier={}));var v=(e.TypeModifier,function(){function t(t){void 0===t&&(t=null),this.modifiers=t,d.isBlank(t)&&(this.modifiers=[])}return t.prototype.hasModifier=function(t){return-1!==this.modifiers.indexOf(t)},t}());e.Type=v,function(t){t[t.Dynamic=0]="Dynamic",t[t.Bool=1]="Bool",t[t.String=2]="String",t[t.Int=3]="Int",t[t.Number=4]="Number",t[t.Function=5]="Function"}(e.BuiltinTypeName||(e.BuiltinTypeName={}));var y=e.BuiltinTypeName,m=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.name=e}return f(e,t),e.prototype.visitType=function(t,e){return t.visitBuiltintType(this,e)},e}(v);e.BuiltinType=m;var g=function(t){function e(e,n,r){void 0===n&&(n=null),void 0===r&&(r=null),t.call(this,r),this.value=e,this.typeParams=n}return f(e,t),e.prototype.visitType=function(t,e){return t.visitExternalType(this,e)},e}(v);e.ExternalType=g;var _=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.of=e}return f(e,t),e.prototype.visitType=function(t,e){return t.visitArrayType(this,e)},e}(v);e.ArrayType=_;var b=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.valueType=e}return f(e,t),e.prototype.visitType=function(t,e){return t.visitMapType(this,e)},e}(v);e.MapType=b,e.DYNAMIC_TYPE=new m(y.Dynamic),e.BOOL_TYPE=new m(y.Bool),e.INT_TYPE=new m(y.Int),e.NUMBER_TYPE=new m(y.Number),e.STRING_TYPE=new m(y.String),e.FUNCTION_TYPE=new m(y.Function),function(t){t[t.Equals=0]="Equals",t[t.NotEquals=1]="NotEquals",t[t.Identical=2]="Identical",t[t.NotIdentical=3]="NotIdentical",t[t.Minus=4]="Minus",t[t.Plus=5]="Plus",t[t.Divide=6]="Divide",t[t.Multiply=7]="Multiply",t[t.Modulo=8]="Modulo",t[t.And=9]="And",t[t.Or=10]="Or",t[t.Lower=11]="Lower",t[t.LowerEquals=12]="LowerEquals",t[t.Bigger=13]="Bigger",t[t.BiggerEquals=14]="BiggerEquals"}(e.BinaryOperator||(e.BinaryOperator={}));var P=e.BinaryOperator,E=function(){function t(t){this.type=t}return t.prototype.prop=function(t){return new B(this,t)},t.prototype.key=function(t,e){return void 0===e&&(e=null),new F(this,t,e)},t.prototype.callMethod=function(t,e){return new T(this,t,e)},t.prototype.callFn=function(t){return new x(this,t)},t.prototype.instantiate=function(t,e){return void 0===e&&(e=null),new A(this,t,e)},t.prototype.conditional=function(t,e){return void 0===e&&(e=null),new k(this,t,e)},t.prototype.equals=function(t){return new L(P.Equals,this,t)},t.prototype.notEquals=function(t){return new L(P.NotEquals,this,t)},t.prototype.identical=function(t){return new L(P.Identical,this,t)},t.prototype.notIdentical=function(t){return new L(P.NotIdentical,this,t)},t.prototype.minus=function(t){return new L(P.Minus,this,t)},t.prototype.plus=function(t){return new L(P.Plus,this,t)},t.prototype.divide=function(t){return new L(P.Divide,this,t)},t.prototype.multiply=function(t){return new L(P.Multiply,this,t)},t.prototype.modulo=function(t){return new L(P.Modulo,this,t)},t.prototype.and=function(t){return new L(P.And,this,t)},t.prototype.or=function(t){return new L(P.Or,this,t)},t.prototype.lower=function(t){return new L(P.Lower,this,t)},t.prototype.lowerEquals=function(t){return new L(P.LowerEquals,this,t)},t.prototype.bigger=function(t){return new L(P.Bigger,this,t)},t.prototype.biggerEquals=function(t){return new L(P.BiggerEquals,this,t)},t.prototype.isBlank=function(){return this.equals(e.NULL_EXPR)},t.prototype.cast=function(t){return new D(this,t)},t.prototype.toStmt=function(){return new G(this)},t}();e.Expression=E,function(t){t[t.This=0]="This",t[t.Super=1]="Super",t[t.CatchError=2]="CatchError",t[t.CatchStack=3]="CatchStack"}(e.BuiltinVar||(e.BuiltinVar={}));var w=e.BuiltinVar,C=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),d.isString(e)?(this.name=e,this.builtin=null):(this.name=null,this.builtin=e)}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitReadVarExpr(this,e)},e.prototype.set=function(t){return new R(this.name,t)},e}(E);e.ReadVarExpr=C;var R=function(t){function e(e,n,r){void 0===r&&(r=null),t.call(this,d.isPresent(r)?r:n.type),this.name=e,this.value=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitWriteVarExpr(this,e)},e.prototype.toDeclStmt=function(t,e){return void 0===t&&(t=null),void 0===e&&(e=null),new X(this.name,this.value,t,e)},e}(E);e.WriteVarExpr=R;var S=function(t){function e(e,n,r,i){void 0===i&&(i=null),t.call(this,d.isPresent(i)?i:r.type),this.receiver=e,this.index=n,this.value=r}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitWriteKeyExpr(this,e)},e}(E);e.WriteKeyExpr=S;var O=function(t){function e(e,n,r,i){void 0===i&&(i=null),t.call(this,d.isPresent(i)?i:r.type),this.receiver=e,this.name=n,this.value=r}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitWritePropExpr(this,e)},e}(E);e.WritePropExpr=O,function(t){t[t.ConcatArray=0]="ConcatArray",t[t.SubscribeObservable=1]="SubscribeObservable",t[t.bind=2]="bind"}(e.BuiltinMethod||(e.BuiltinMethod={}));var T=(e.BuiltinMethod,function(t){function e(e,n,r,i){void 0===i&&(i=null),t.call(this,i),this.receiver=e,this.args=r,d.isString(n)?(this.name=n,this.builtin=null):(this.name=null,this.builtin=n)}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitInvokeMethodExpr(this,e)},e}(E));e.InvokeMethodExpr=T;var x=function(t){function e(e,n,r){void 0===r&&(r=null),t.call(this,r),this.fn=e,this.args=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitInvokeFunctionExpr(this,e)},e}(E);e.InvokeFunctionExpr=x;var A=function(t){function e(e,n,r){t.call(this,r),this.classExpr=e,this.args=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitInstantiateExpr(this,e)},e}(E);e.InstantiateExpr=A;var I=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.value=e}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitLiteralExpr(this,e)},e}(E);e.LiteralExpr=I;var M=function(t){function e(e,n,r){void 0===n&&(n=null),void 0===r&&(r=null),t.call(this,n),this.value=e,this.typeParams=r}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitExternalExpr(this,e)},e}(E);e.ExternalExpr=M;var k=function(t){function e(e,n,r,i){void 0===r&&(r=null),void 0===i&&(i=null),t.call(this,d.isPresent(i)?i:n.type),this.condition=e,this.falseCase=r,this.trueCase=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitConditionalExpr(this,e)},e}(E);e.ConditionalExpr=k;var N=function(t){function n(n){t.call(this,e.BOOL_TYPE),this.condition=n}return f(n,t),n.prototype.visitExpression=function(t,e){return t.visitNotExpr(this,e)},n}(E);e.NotExpr=N;var D=function(t){function e(e,n){t.call(this,n),this.value=e}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitCastExpr(this,e)},e}(E);e.CastExpr=D;var V=function(){function t(t,e){void 0===e&&(e=null),this.name=t,this.type=e}return t}();e.FnParam=V;var j=function(t){function e(e,n,r){void 0===r&&(r=null),t.call(this,r),this.params=e,this.statements=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitFunctionExpr(this,e)},e.prototype.toDeclStmt=function(t,e){return void 0===e&&(e=null),new q(t,this.params,this.statements,this.type,e)},e}(E);e.FunctionExpr=j;var L=function(t){function e(e,n,r,i){void 0===i&&(i=null),t.call(this,d.isPresent(i)?i:n.type),this.operator=e,this.rhs=r,this.lhs=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitBinaryOperatorExpr(this,e)},e}(E);e.BinaryOperatorExpr=L;var B=function(t){function e(e,n,r){void 0===r&&(r=null),t.call(this,r),this.receiver=e,this.name=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitReadPropExpr(this,e)},e.prototype.set=function(t){return new O(this.receiver,this.name,t)},e}(E);e.ReadPropExpr=B;var F=function(t){function e(e,n,r){void 0===r&&(r=null),t.call(this,r),this.receiver=e,this.index=n}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitReadKeyExpr(this,e)},e.prototype.set=function(t){return new S(this.receiver,this.index,t)},e}(E);e.ReadKeyExpr=F;var U=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.entries=e}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitLiteralArrayExpr(this,e)},e}(E);e.LiteralArrayExpr=U;var W=function(t){function e(e,n){void 0===n&&(n=null),t.call(this,n),this.entries=e,this.valueType=null,d.isPresent(n)&&(this.valueType=n.valueType)}return f(e,t),e.prototype.visitExpression=function(t,e){return t.visitLiteralMapExpr(this,e)},e}(E);e.LiteralMapExpr=W,e.THIS_EXPR=new C(w.This),e.SUPER_EXPR=new C(w.Super),e.CATCH_ERROR_VAR=new C(w.CatchError),e.CATCH_STACK_VAR=new C(w.CatchStack),e.NULL_EXPR=new I(null,null),function(t){t[t.Final=0]="Final",t[t.Private=1]="Private"}(e.StmtModifier||(e.StmtModifier={}));var H=(e.StmtModifier,function(){function t(t){void 0===t&&(t=null),this.modifiers=t,d.isBlank(t)&&(this.modifiers=[])}return t.prototype.hasModifier=function(t){return-1!==this.modifiers.indexOf(t)},t}());e.Statement=H;var X=function(t){function e(e,n,r,i){void 0===r&&(r=null),void 0===i&&(i=null),t.call(this,i),this.name=e,this.value=n,this.type=d.isPresent(r)?r:n.type}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitDeclareVarStmt(this,e)},e}(H);e.DeclareVarStmt=X;var q=function(t){function e(e,n,r,i,o){void 0===i&&(i=null),void 0===o&&(o=null),t.call(this,o),this.name=e,this.params=n,this.statements=r,this.type=i}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitDeclareFunctionStmt(this,e)},e}(H);e.DeclareFunctionStmt=q;var G=function(t){function e(e){t.call(this),this.expr=e}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitExpressionStmt(this,e)},e}(H);e.ExpressionStatement=G;var z=function(t){function e(e){t.call(this),this.value=e}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitReturnStmt(this,e)},e}(H);e.ReturnStatement=z;var K=function(){function t(t,e){void 0===t&&(t=null),this.type=t,this.modifiers=e,d.isBlank(e)&&(this.modifiers=[])}return t.prototype.hasModifier=function(t){return-1!==this.modifiers.indexOf(t)},t}();e.AbstractClassPart=K;var $=function(t){function e(e,n,r){void 0===n&&(n=null),void 0===r&&(r=null),t.call(this,n,r),this.name=e}return f(e,t),e}(K);e.ClassField=$;var Q=function(t){function e(e,n,r,i,o){void 0===i&&(i=null),void 0===o&&(o=null),t.call(this,i,o),this.name=e,this.params=n,this.body=r}return f(e,t),e}(K);e.ClassMethod=Q;var J=function(t){function e(e,n,r,i){void 0===r&&(r=null),void 0===i&&(i=null),t.call(this,r,i),this.name=e,this.body=n}return f(e,t),e}(K);e.ClassGetter=J;var Z=function(t){function e(e,n,r,i,o,s,a){void 0===a&&(a=null),t.call(this,a),this.name=e,this.parent=n,this.fields=r,this.getters=i,this.constructorMethod=o,this.methods=s}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitDeclareClassStmt(this,e)},e}(H);e.ClassStmt=Z;var Y=function(t){function e(e,n,r){void 0===r&&(r=d.CONST_EXPR([])),t.call(this),this.condition=e,this.trueCase=n,this.falseCase=r}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitIfStmt(this,e)},e}(H);e.IfStmt=Y;var tt=function(t){function e(e){t.call(this),this.comment=e}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitCommentStmt(this,e)},e}(H);e.CommentStmt=tt;var et=function(t){function e(e,n){t.call(this),this.bodyStmts=e,this.catchStmts=n}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitTryCatchStmt(this,e)},e}(H);e.TryCatchStmt=et;var nt=function(t){function e(e){t.call(this),this.error=e}return f(e,t),e.prototype.visitStatement=function(t,e){return t.visitThrowStmt(this,e)},e}(H);e.ThrowStmt=nt;var rt=function(){function t(){}return t.prototype.visitReadVarExpr=function(t,e){return t},t.prototype.visitWriteVarExpr=function(t,e){return new R(t.name,t.value.visitExpression(this,e))},t.prototype.visitWriteKeyExpr=function(t,e){return new S(t.receiver.visitExpression(this,e),t.index.visitExpression(this,e),t.value.visitExpression(this,e))},t.prototype.visitWritePropExpr=function(t,e){return new O(t.receiver.visitExpression(this,e),t.name,t.value.visitExpression(this,e))},t.prototype.visitInvokeMethodExpr=function(t,e){var n=d.isPresent(t.builtin)?t.builtin:t.name;return new T(t.receiver.visitExpression(this,e),n,this.visitAllExpressions(t.args,e),t.type)},t.prototype.visitInvokeFunctionExpr=function(t,e){return new x(t.fn.visitExpression(this,e),this.visitAllExpressions(t.args,e),t.type)},t.prototype.visitInstantiateExpr=function(t,e){return new A(t.classExpr.visitExpression(this,e),this.visitAllExpressions(t.args,e),t.type)},t.prototype.visitLiteralExpr=function(t,e){return t},t.prototype.visitExternalExpr=function(t,e){return t},t.prototype.visitConditionalExpr=function(t,e){return new k(t.condition.visitExpression(this,e),t.trueCase.visitExpression(this,e),t.falseCase.visitExpression(this,e))},t.prototype.visitNotExpr=function(t,e){return new N(t.condition.visitExpression(this,e))},t.prototype.visitCastExpr=function(t,e){return new D(t.value.visitExpression(this,e),e)},t.prototype.visitFunctionExpr=function(t,e){return t},t.prototype.visitBinaryOperatorExpr=function(t,e){return new L(t.operator,t.lhs.visitExpression(this,e),t.rhs.visitExpression(this,e),t.type)},t.prototype.visitReadPropExpr=function(t,e){return new B(t.receiver.visitExpression(this,e),t.name,t.type)},t.prototype.visitReadKeyExpr=function(t,e){return new F(t.receiver.visitExpression(this,e),t.index.visitExpression(this,e),t.type)},t.prototype.visitLiteralArrayExpr=function(t,e){return new U(this.visitAllExpressions(t.entries,e))},t.prototype.visitLiteralMapExpr=function(t,e){var n=this;return new W(t.entries.map(function(t){return[t[0],t[1].visitExpression(n,e)]}))},t.prototype.visitAllExpressions=function(t,e){var n=this;return t.map(function(t){return t.visitExpression(n,e)})},t.prototype.visitDeclareVarStmt=function(t,e){return new X(t.name,t.value.visitExpression(this,e),t.type,t.modifiers)},t.prototype.visitDeclareFunctionStmt=function(t,e){return t},t.prototype.visitExpressionStmt=function(t,e){return new G(t.expr.visitExpression(this,e))},t.prototype.visitReturnStmt=function(t,e){return new z(t.value.visitExpression(this,e))},t.prototype.visitDeclareClassStmt=function(t,e){return t},t.prototype.visitIfStmt=function(t,e){return new Y(t.condition.visitExpression(this,e),this.visitAllStatements(t.trueCase,e),this.visitAllStatements(t.falseCase,e))},t.prototype.visitTryCatchStmt=function(t,e){return new et(this.visitAllStatements(t.bodyStmts,e),this.visitAllStatements(t.catchStmts,e))},t.prototype.visitThrowStmt=function(t,e){return new nt(t.error.visitExpression(this,e))},t.prototype.visitCommentStmt=function(t,e){return t},t.prototype.visitAllStatements=function(t,e){var n=this;return t.map(function(t){return t.visitStatement(n,e)})},t}();e.ExpressionTransformer=rt;var it=function(){function t(){}return t.prototype.visitReadVarExpr=function(t,e){return t},t.prototype.visitWriteVarExpr=function(t,e){return t.value.visitExpression(this,e),t},t.prototype.visitWriteKeyExpr=function(t,e){return t.receiver.visitExpression(this,e),t.index.visitExpression(this,e),t.value.visitExpression(this,e),t},t.prototype.visitWritePropExpr=function(t,e){return t.receiver.visitExpression(this,e),t.value.visitExpression(this,e),t},t.prototype.visitInvokeMethodExpr=function(t,e){return t.receiver.visitExpression(this,e),this.visitAllExpressions(t.args,e),t},t.prototype.visitInvokeFunctionExpr=function(t,e){return t.fn.visitExpression(this,e),this.visitAllExpressions(t.args,e),t},t.prototype.visitInstantiateExpr=function(t,e){return t.classExpr.visitExpression(this,e),this.visitAllExpressions(t.args,e),t},t.prototype.visitLiteralExpr=function(t,e){return t},t.prototype.visitExternalExpr=function(t,e){return t},t.prototype.visitConditionalExpr=function(t,e){return t.condition.visitExpression(this,e),t.trueCase.visitExpression(this,e),t.falseCase.visitExpression(this,e),t},t.prototype.visitNotExpr=function(t,e){return t.condition.visitExpression(this,e),t},t.prototype.visitCastExpr=function(t,e){return t.value.visitExpression(this,e),t},t.prototype.visitFunctionExpr=function(t,e){return t},t.prototype.visitBinaryOperatorExpr=function(t,e){return t.lhs.visitExpression(this,e),t.rhs.visitExpression(this,e),t},t.prototype.visitReadPropExpr=function(t,e){return t.receiver.visitExpression(this,e),t},t.prototype.visitReadKeyExpr=function(t,e){return t.receiver.visitExpression(this,e),t.index.visitExpression(this,e),t},t.prototype.visitLiteralArrayExpr=function(t,e){return this.visitAllExpressions(t.entries,e),t},t.prototype.visitLiteralMapExpr=function(t,e){var n=this;return t.entries.forEach(function(t){return t[1].visitExpression(n,e)}),t},t.prototype.visitAllExpressions=function(t,e){var n=this;t.forEach(function(t){return t.visitExpression(n,e)})},t.prototype.visitDeclareVarStmt=function(t,e){return t.value.visitExpression(this,e),t},t.prototype.visitDeclareFunctionStmt=function(t,e){return t},t.prototype.visitExpressionStmt=function(t,e){return t.expr.visitExpression(this,e),t},t.prototype.visitReturnStmt=function(t,e){return t.value.visitExpression(this,e),t},t.prototype.visitDeclareClassStmt=function(t,e){return t},t.prototype.visitIfStmt=function(t,e){return t.condition.visitExpression(this,e),this.visitAllStatements(t.trueCase,e),this.visitAllStatements(t.falseCase,e),t},t.prototype.visitTryCatchStmt=function(t,e){return this.visitAllStatements(t.bodyStmts,e),this.visitAllStatements(t.catchStmts,e),t},t.prototype.visitThrowStmt=function(t,e){return t.error.visitExpression(this,e),t},t.prototype.visitCommentStmt=function(t,e){return t},t.prototype.visitAllStatements=function(t,e){var n=this;t.forEach(function(t){return t.visitStatement(n,e)})},t}();e.RecursiveExpressionVisitor=it,e.replaceVarInExpression=r;var ot=function(t){function e(e,n){t.call(this),this._varName=e,this._newValue=n}return f(e,t),e.prototype.visitReadVarExpr=function(t,e){return t.name==this._varName?this._newValue:t},e}(rt);e.findReadVarNames=i;var st=function(t){function e(){t.apply(this,arguments),this.varNames=new Set}return f(e,t),e.prototype.visitReadVarExpr=function(t,e){return this.varNames.add(t.name),null},e}(it);e.variable=o,e.importExpr=s,e.importType=a,e.literal=u,e.literalArr=c,e.literalMap=p,e.not=l,e.fn=h},function(t,e,n){"use strict";function r(t){if(!t.isComponent)throw new a.BaseException("Could not compile '"+t.type.name+"' because it is not a component.")}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(12),u=n(15),c=n(40),p=n(155),l=n(6),h=n(166),f=n(168),d=n(140),v=n(183),y=n(185),m=n(65),g=n(162),_=n(164),b=n(191),P=n(194),E=n(198),w=n(184),C=function(){function t(t,e,n,r,i,o,s){this._runtimeMetadataResolver=t,this._templateNormalizer=e,this._templateParser=n,this._styleCompiler=r,this._viewCompiler=i,this._xhr=o,this._genConfig=s,this._styleCache=new Map,this._hostCacheKeys=new Map,this._compiledTemplateCache=new Map,this._compiledTemplateDone=new Map}return t.prototype.resolveComponent=function(t){var e=this._runtimeMetadataResolver.getDirectiveMetadata(t),n=this._hostCacheKeys.get(t);if(s.isBlank(n)){n=new Object,this._hostCacheKeys.set(t,n),r(e);var i=p.createHostComponentMeta(e.type,e.selector);this._loadAndCompileComponent(n,i,[e],[],[])}return this._compiledTemplateDone.get(n).then(function(n){return new m.ComponentFactory(e.selector,n.viewFactory,t)})},t.prototype.clearCache=function(){this._styleCache.clear(),this._compiledTemplateCache.clear(),this._compiledTemplateDone.clear(),this._hostCacheKeys.clear()},t.prototype._loadAndCompileComponent=function(t,e,n,r,i){var o=this,a=this._compiledTemplateCache.get(t),u=this._compiledTemplateDone.get(t);return s.isBlank(a)&&(a=new R,this._compiledTemplateCache.set(t,a),u=c.PromiseWrapper.all([this._compileComponentStyles(e)].concat(n.map(function(t){return o._templateNormalizer.normalizeDirective(t)}))).then(function(t){var n=t.slice(1),s=t[0],u=o._templateParser.parse(e,e.template.template,n,r,e.type.name),p=[];return a.init(o._compileComponent(e,u,s,r,i,p)),c.PromiseWrapper.all(p).then(function(t){return a})}),this._compiledTemplateDone.set(t,u)),a},t.prototype._compileComponent=function(t,e,n,r,i,o){var a=this,c=this._viewCompiler.compileComponent(t,e,new _.ExternalExpr(new p.CompileIdentifierMetadata({runtime:n})),r);c.dependencies.forEach(function(t){var e=u.ListWrapper.clone(i),n=t.comp.type.runtime,r=a._runtimeMetadataResolver.getViewDirectivesMetadata(t.comp.type.runtime),s=a._runtimeMetadataResolver.getViewPipesMetadata(t.comp.type.runtime),c=u.ListWrapper.contains(e,n);e.push(n);var p=a._loadAndCompileComponent(t.comp.type.runtime,t.comp,r,s,e);t.factoryPlaceholder.runtime=p.proxyViewFactory,t.factoryPlaceholder.name="viewFactory_"+t.comp.type.name,c||o.push(a._compiledTemplateDone.get(n))});var l;return l=s.IS_DART||!this._genConfig.useJit?P.interpretStatements(c.statements,c.viewFactoryVar,new E.InterpretiveAppViewInstanceFactory):b.jitStatements(t.type.name+".template.js",c.statements,c.viewFactoryVar)},t.prototype._compileComponentStyles=function(t){var e=this._styleCompiler.compileComponent(t);return this._resolveStylesCompileResult(t.type.name,e)},t.prototype._resolveStylesCompileResult=function(t,e){var n=this,r=e.dependencies.map(function(t){return n._loadStylesheetDep(t)});return c.PromiseWrapper.all(r).then(function(t){for(var r=[],i=0;i<e.dependencies.length;i++){var o=e.dependencies[i],s=t[i],a=n._styleCompiler.compileStylesheet(o.sourceUrl,s,o.isShimmed);r.push(n._resolveStylesCompileResult(o.sourceUrl,a))}return c.PromiseWrapper.all(r)}).then(function(r){for(var i=0;i<e.dependencies.length;i++){var o=e.dependencies[i];o.valuePlaceholder.runtime=r[i],o.valuePlaceholder.name="importedStyles"+i}return s.IS_DART||!n._genConfig.useJit?P.interpretStatements(e.statements,e.stylesVar,new E.InterpretiveAppViewInstanceFactory):b.jitStatements(t+".css.js",e.statements,e.stylesVar)})},t.prototype._loadStylesheetDep=function(t){var e=""+t.sourceUrl+(t.isShimmed?".shim":""),n=this._styleCache.get(e);return s.isBlank(n)&&(n=this._xhr.get(t.sourceUrl),this._styleCache.set(e,n)),n},t=i([l.Injectable(),o("design:paramtypes",[y.RuntimeMetadataResolver,v.DirectiveNormalizer,d.TemplateParser,h.StyleCompiler,f.ViewCompiler,w.XHR,g.CompilerConfig])],t)}();e.RuntimeCompiler=C;var R=function(){function t(){var t=this;this.viewFactory=null,this.proxyViewFactory=function(e,n,r){return t.viewFactory(e,n,r)}}return t.prototype.init=function(t){this.viewFactory=t},t}()},function(t,e,n){"use strict";function r(t){var e="styles";return f.isPresent(t)&&(e+="_"+t.type.name),e}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(155),a=n(164),u=n(36),c=n(167),p=n(157),l=n(152),h=n(6),f=n(5),d="%COMP%",v="_nghost-"+d,y="_ngcontent-"+d,m=function(){function t(t,e,n){this.sourceUrl=t,this.isShimmed=e,this.valuePlaceholder=n}return t}();e.StylesCompileDependency=m;var g=function(){function t(t,e,n){this.statements=t,this.stylesVar=e,this.dependencies=n}return t}();e.StylesCompileResult=g;var _=function(){function t(t){this._urlResolver=t,this._shadowCss=new c.ShadowCss}return t.prototype.compileComponent=function(t){var e=t.template.encapsulation===u.ViewEncapsulation.Emulated;return this._compileStyles(r(t),t.template.styles,t.template.styleUrls,e)},t.prototype.compileStylesheet=function(t,e,n){var i=l.extractStyleUrls(this._urlResolver,t,e);return this._compileStyles(r(null),[i.style],i.styleUrls,n)},t.prototype._compileStyles=function(t,e,n,i){for(var o=this,u=e.map(function(t){return a.literal(o._shimIfNeeded(t,i))}),c=[],p=0;p<n.length;p++){var l=new s.CompileIdentifierMetadata({name:r(null)});c.push(new m(n[p],i,l)),u.push(new a.ExternalExpr(l))}var h=a.variable(t).set(a.literalArr(u,new a.ArrayType(a.DYNAMIC_TYPE,[a.TypeModifier.Const]))).toDeclStmt(null,[a.StmtModifier.Final]);return new g([h],t,c)},t.prototype._shimIfNeeded=function(t,e){return e?this._shadowCss.shimCssText(t,y,v):t},t=i([h.Injectable(),o("design:paramtypes",[p.UrlResolver])],t)}();e.StyleCompiler=_},function(t,e,n){"use strict";function r(t){return a.StringWrapper.replaceAllMapped(t,C,function(t){return""})}function i(t,e){var n=o(t),r=0;return a.StringWrapper.replaceAllMapped(n.escapedString,R,function(t){var i=t[2],o="",s=t[4],u="";a.isPresent(t[4])&&t[4].startsWith("{"+x)&&(o=n.blocks[r++],s=t[4].substring(x.length+1),u="{");var c=e(new A(i,o));return""+t[1]+c.selector+t[3]+u+c.content+s})}function o(t){for(var e=a.StringWrapper.split(t,S),n=[],r=[],i=0,o=[],s=0;s<e.length;s++){var u=e[s];u==T&&i--,i>0?o.push(u):(o.length>0&&(r.push(o.join("")),n.push(x),o=[]),n.push(u)),u==O&&i++}return o.length>0&&(r.push(o.join("")),n.push(x)),new I(n.join(""),r)}var s=n(15),a=n(5),u=function(){function t(){this.strictStyling=!0}return t.prototype.shimCssText=function(t,e,n){return void 0===n&&(n=""),t=r(t),t=this._insertDirectives(t),this._scopeCssText(t,e,n)},t.prototype._insertDirectives=function(t){return t=this._insertPolyfillDirectivesInCssText(t),this._insertPolyfillRulesInCssText(t)},t.prototype._insertPolyfillDirectivesInCssText=function(t){return a.StringWrapper.replaceAllMapped(t,c,function(t){return t[1]+"{"})},t.prototype._insertPolyfillRulesInCssText=function(t){return a.StringWrapper.replaceAllMapped(t,p,function(t){var e=t[0];return e=a.StringWrapper.replace(e,t[1],""),e=a.StringWrapper.replace(e,t[2],""),t[3]+e})},t.prototype._scopeCssText=function(t,e,n){var r=this._extractUnscopedRulesFromCssText(t);return t=this._insertPolyfillHostInCssText(t),t=this._convertColonHost(t),t=this._convertColonHostContext(t),t=this._convertShadowDOMSelectors(t),
                +a.isPresent(e)&&(t=this._scopeSelectors(t,e,n)),t=t+"\n"+r,t.trim()},t.prototype._extractUnscopedRulesFromCssText=function(t){for(var e,n="",r=a.RegExpWrapper.matcher(l,t);a.isPresent(e=a.RegExpMatcherWrapper.next(r));){var i=e[0];i=a.StringWrapper.replace(i,e[2],""),i=a.StringWrapper.replace(i,e[1],e[3]),n+=i+"\n\n"}return n},t.prototype._convertColonHost=function(t){return this._convertColonRule(t,v,this._colonHostPartReplacer)},t.prototype._convertColonHostContext=function(t){return this._convertColonRule(t,y,this._colonHostContextPartReplacer)},t.prototype._convertColonRule=function(t,e,n){return a.StringWrapper.replaceAllMapped(t,e,function(t){if(a.isPresent(t[2])){for(var e=t[2].split(","),r=[],i=0;i<e.length;i++){var o=e[i];if(a.isBlank(o))break;o=o.trim(),r.push(n(m,o,t[3]))}return r.join(",")}return m+t[3]})},t.prototype._colonHostContextPartReplacer=function(t,e,n){return a.StringWrapper.contains(e,h)?this._colonHostPartReplacer(t,e,n):t+e+n+", "+e+" "+t+n},t.prototype._colonHostPartReplacer=function(t,e,n){return t+a.StringWrapper.replace(e,h,"")+n},t.prototype._convertShadowDOMSelectors=function(t){for(var e=0;e<g.length;e++)t=a.StringWrapper.replaceAll(t,g[e]," ");return t},t.prototype._scopeSelectors=function(t,e,n){var r=this;return i(t,function(t){var i=t.selector,o=t.content;return"@"!=t.selector[0]||t.selector.startsWith("@page")?i=r._scopeSelector(t.selector,e,n,r.strictStyling):t.selector.startsWith("@media")&&(o=r._scopeSelectors(t.content,e,n)),new A(i,o)})},t.prototype._scopeSelector=function(t,e,n,r){for(var i=[],o=t.split(","),s=0;s<o.length;s++){var u=o[s].trim(),c=a.StringWrapper.split(u,_),p=c[0];this._selectorNeedsScoping(p,e)&&(c[0]=r&&!a.StringWrapper.contains(p,m)?this._applyStrictSelectorScope(p,e):this._applySelectorScope(p,e,n)),i.push(c.join(" "))}return i.join(", ")},t.prototype._selectorNeedsScoping=function(t,e){var n=this._makeScopeMatcher(e);return!a.isPresent(a.RegExpWrapper.firstMatch(n,t))},t.prototype._makeScopeMatcher=function(t){var e=/\[/g,n=/\]/g;return t=a.StringWrapper.replaceAll(t,e,"\\["),t=a.StringWrapper.replaceAll(t,n,"\\]"),a.RegExpWrapper.create("^("+t+")"+b,"m")},t.prototype._applySelectorScope=function(t,e,n){return this._applySimpleSelectorScope(t,e,n)},t.prototype._applySimpleSelectorScope=function(t,e,n){if(a.isPresent(a.RegExpWrapper.firstMatch(P,t))){var r=this.strictStyling?"["+n+"]":e;return t=a.StringWrapper.replace(t,m,r),a.StringWrapper.replaceAll(t,P,r+" ")}return e+" "+t},t.prototype._applyStrictSelectorScope=function(t,e){var n=/\[is=([^\]]*)\]/g;e=a.StringWrapper.replaceAllMapped(e,n,function(t){return t[1]});for(var r=[" ",">","+","~"],i=t,o="["+e+"]",u=0;u<r.length;u++){var c=r[u],p=i.split(c);i=p.map(function(t){var e=a.StringWrapper.replaceAll(t.trim(),P,"");if(e.length>0&&!s.ListWrapper.contains(r,e)&&!a.StringWrapper.contains(e,o)){var n=/([^:]*)(:*)(.*)/g,i=a.RegExpWrapper.firstMatch(n,e);a.isPresent(i)&&(t=i[1]+o+i[2]+i[3])}return t}).join(c)}return i},t.prototype._insertPolyfillHostInCssText=function(t){return t=a.StringWrapper.replaceAll(t,w,f),t=a.StringWrapper.replaceAll(t,E,h)},t}();e.ShadowCss=u;var c=/polyfill-next-selector[^}]*content:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,p=/(polyfill-rule)[^}]*(content:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,l=/(polyfill-unscoped-rule)[^}]*(content:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,h="-shadowcsshost",f="-shadowcsscontext",d=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)",v=a.RegExpWrapper.create("("+h+d,"im"),y=a.RegExpWrapper.create("("+f+d,"im"),m=h+"-no-combinator",g=[/::shadow/g,/::content/g,/\/shadow-deep\//g,/\/shadow\//g],_=/(?:>>>)|(?:\/deep\/)/g,b="([>\\s~+[.,{:][\\s\\S]*)?$",P=a.RegExpWrapper.create(h,"im"),E=/:host/gim,w=/:host-context/gim,C=/\/\*[\s\S]*?\*\//g,R=/(\s*)([^;\{\}]+?)(\s*)((?:{%BLOCK%}?\s*;?)|(?:\s*;))/g,S=/([{}])/g,O="{",T="}",x="%BLOCK%",A=function(){function t(t,e){this.selector=t,this.content=e}return t}();e.CssRule=A,e.processRules=i;var I=function(){function t(t,e){this.escapedString=t,this.blocks=e}return t}()},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(6),s=n(169),a=n(174),u=n(176),c=n(162),p=function(){function t(t,e,n){this.statements=t,this.viewFactoryVar=e,this.dependencies=n}return t}();e.ViewCompileResult=p;var l=function(){function t(t){this._genConfig=t}return t.prototype.compileComponent=function(t,e,n,r){var i=[],o=[],c=new a.CompileView(t,this._genConfig,r,n,0,s.CompileElement.createNull(),[]);return u.buildView(c,e,o,i),new p(i,c.viewFactory.name,o)},t=r([o.Injectable(),i("design:paramtypes",[c.CompilerConfig])],t)}();e.ViewCompiler=l},function(t,e,n){"use strict";function r(t,e,n,r){var i;return i=e>0?s.literal(t).lowerEquals(u.InjectMethodVars.requestNodeIndex).and(u.InjectMethodVars.requestNodeIndex.lowerEquals(s.literal(t+e))):s.literal(t).identical(u.InjectMethodVars.requestNodeIndex),new s.IfStmt(u.InjectMethodVars.token.identical(f.createDiTokenExpression(n.token)).and(i),[new s.ReturnStatement(r)])}function i(t,e,n,r,i,o){var a,u,p=o.view;if(r?(a=s.literalArr(n),u=new s.ArrayType(s.DYNAMIC_TYPE)):(a=n[0],u=n[0].type),c.isBlank(u)&&(u=s.DYNAMIC_TYPE),i)p.fields.push(new s.ClassField(t,u,[s.StmtModifier.Private])),p.createMethod.addStmt(s.THIS_EXPR.prop(t).set(a).toStmt());else{var l="_"+t;p.fields.push(new s.ClassField(l,u,[s.StmtModifier.Private]));var h=new v.CompileMethod(p);h.resetDebugInfo(o.nodeIndex,o.sourceAst),h.addStmt(new s.IfStmt(s.THIS_EXPR.prop(l).isBlank(),[s.THIS_EXPR.prop(l).set(a).toStmt()])),h.addStmt(new s.ReturnStatement(s.THIS_EXPR.prop(l))),p.getters.push(new s.ClassGetter(t,h.finish(),u))}return s.THIS_EXPR.prop(t)}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=n(164),a=n(158),u=n(170),c=n(5),p=n(15),l=n(139),h=n(155),f=n(171),d=n(172),v=n(173),y=function(){function t(t,e,n,r,i){this.parent=t,this.view=e,this.nodeIndex=n,this.renderNode=r,this.sourceAst=i}return t.prototype.isNull=function(){return c.isBlank(this.renderNode)},t.prototype.isRootElement=function(){return this.view!=this.parent.view},t}();e.CompileNode=y;var m=function(t){function e(e,n,r,i,o,u,p,l,f,d,v){t.call(this,e,n,r,i,o),this.component=u,this._directives=p,this._resolvedProvidersArray=l,this.hasViewContainer=f,this.hasEmbeddedView=d,this.variableTokens=v,this._compViewExpr=null,this._instances=new h.CompileTokenMap,this._queryCount=0,this._queries=new h.CompileTokenMap,this._componentConstructorViewQueryLists=[],this.contentNodesByNgContentIndex=null,this.elementRef=s.importExpr(a.Identifiers.ElementRef).instantiate([this.renderNode]),this._instances.add(a.identifierToken(a.Identifiers.ElementRef),this.elementRef),this.injector=s.THIS_EXPR.callMethod("injector",[s.literal(this.nodeIndex)]),this._instances.add(a.identifierToken(a.Identifiers.Injector),this.injector),this._instances.add(a.identifierToken(a.Identifiers.Renderer),s.THIS_EXPR.prop("renderer")),(this.hasViewContainer||this.hasEmbeddedView||c.isPresent(this.component))&&this._createAppElement()}return o(e,t),e.createNull=function(){return new e(null,null,null,null,null,null,[],[],!1,!1,{})},e.prototype._createAppElement=function(){var t="_appEl_"+this.nodeIndex,e=this.isRootElement()?null:this.parent.nodeIndex;this.view.fields.push(new s.ClassField(t,s.importType(a.Identifiers.AppElement),[s.StmtModifier.Private]));var n=s.THIS_EXPR.prop(t).set(s.importExpr(a.Identifiers.AppElement).instantiate([s.literal(this.nodeIndex),s.literal(e),s.THIS_EXPR,this.renderNode])).toStmt();this.view.createMethod.addStmt(n),this.appElement=s.THIS_EXPR.prop(t),this._instances.add(a.identifierToken(a.Identifiers.AppElement),this.appElement)},e.prototype.setComponentView=function(t){this._compViewExpr=t,this.contentNodesByNgContentIndex=p.ListWrapper.createFixedSize(this.component.template.ngContentSelectors.length);for(var e=0;e<this.contentNodesByNgContentIndex.length;e++)this.contentNodesByNgContentIndex[e]=[]},e.prototype.setEmbeddedView=function(t){if(this.embeddedView=t,c.isPresent(t)){var e=s.importExpr(a.Identifiers.TemplateRef_).instantiate([this.appElement,this.embeddedView.viewFactory]),n=new h.CompileProviderMetadata({token:a.identifierToken(a.Identifiers.TemplateRef),useValue:e});this._resolvedProvidersArray.unshift(new l.ProviderAst(n.token,!1,!0,[n],l.ProviderAstType.Builtin,this.sourceAst.sourceSpan))}},e.prototype.beforeChildren=function(){var t=this;this.hasViewContainer&&this._instances.add(a.identifierToken(a.Identifiers.ViewContainerRef),this.appElement.prop("vcRef")),this._resolvedProviders=new h.CompileTokenMap,this._resolvedProvidersArray.forEach(function(e){return t._resolvedProviders.add(e.token,e)}),this._resolvedProviders.values().forEach(function(e){var n=e.providers.map(function(n){if(c.isPresent(n.useExisting))return t._getDependency(e.providerType,new h.CompileDiDependencyMetadata({token:n.useExisting}));if(c.isPresent(n.useFactory)){var r=c.isPresent(n.deps)?n.deps:n.useFactory.diDeps,i=r.map(function(n){return t._getDependency(e.providerType,n)});return s.importExpr(n.useFactory).callFn(i)}if(c.isPresent(n.useClass)){var r=c.isPresent(n.deps)?n.deps:n.useClass.diDeps,i=r.map(function(n){return t._getDependency(e.providerType,n)});return s.importExpr(n.useClass).instantiate(i,s.importType(n.useClass))}return n.useValue instanceof h.CompileIdentifierMetadata?s.importExpr(n.useValue):n.useValue instanceof s.Expression?n.useValue:s.literal(n.useValue)}),r="_"+e.token.name+"_"+t.nodeIndex+"_"+t._instances.size,o=i(r,e,n,e.multiProvider,e.eager,t);t._instances.add(e.token,o)}),this.directiveInstances=this._directives.map(function(e){return t._instances.get(a.identifierToken(e.type))});for(var e=0;e<this.directiveInstances.length;e++){var n=this.directiveInstances[e],r=this._directives[e];r.queries.forEach(function(e){t._addQuery(e,n)})}var o=[];if(this._resolvedProviders.values().forEach(function(e){var n=t._getQueriesFor(e.token);p.ListWrapper.addAll(o,n.map(function(t){return new g(t,e.token)}))}),p.StringMapWrapper.forEach(this.variableTokens,function(e,n){var r,i=t.variableTokens[n];r=c.isPresent(i)?t._instances.get(i):t.renderNode,t.view.variables.set(n,r);var s=new h.CompileTokenMetadata({value:n});p.ListWrapper.addAll(o,t._getQueriesFor(s).map(function(t){return new g(t,s)}))}),o.forEach(function(e){var n;if(c.isPresent(e.read.identifier))n=t._instances.get(e.read);else{var r=t.variableTokens[e.read.value];n=c.isPresent(r)?t._instances.get(r):t.elementRef}c.isPresent(n)&&e.query.addValue(n,t.view)}),c.isPresent(this.component)){var u=c.isPresent(this.component)?s.literalArr(this._componentConstructorViewQueryLists):s.NULL_EXPR,l=c.isPresent(this.getComponent())?this.getComponent():s.NULL_EXPR;this.view.createMethod.addStmt(this.appElement.callMethod("initComponent",[l,u,this._compViewExpr]).toStmt())}},e.prototype.afterChildren=function(t){var e=this;this._resolvedProviders.values().forEach(function(n){var i=e._instances.get(n.token),o=n.providerType===l.ProviderAstType.PrivateService?0:t;e.view.injectorGetMethod.addStmt(r(e.nodeIndex,o,n,i))}),this._queries.values().forEach(function(t){return t.forEach(function(t){return t.afterChildren(e.view.updateContentQueriesMethod)})})},e.prototype.addContentNode=function(t,e){this.contentNodesByNgContentIndex[t].push(e)},e.prototype.getComponent=function(){return c.isPresent(this.component)?this._instances.get(a.identifierToken(this.component.type)):null},e.prototype.getProviderTokens=function(){return this._resolvedProviders.values().map(function(t){return f.createDiTokenExpression(t.token)})},e.prototype.getDeclaredVariablesNames=function(){var t=[];return p.StringMapWrapper.forEach(this.variableTokens,function(e,n){t.push(n)}),t},e.prototype._getQueriesFor=function(t){for(var e,n=[],r=this,i=0;!r.isNull();)e=r._queries.get(t),c.isPresent(e)&&p.ListWrapper.addAll(n,e.filter(function(t){return t.meta.descendants||1>=i})),r._directives.length>0&&i++,r=r.parent;return e=this.view.componentView.viewQueries.get(t),c.isPresent(e)&&p.ListWrapper.addAll(n,e),n},e.prototype._addQuery=function(t,e){var n="_query_"+t.selectors[0].name+"_"+this.nodeIndex+"_"+this._queryCount++,r=d.createQueryList(t,e,n,this.view),i=new d.CompileQuery(t,r,e,this.view);return d.addQueryToTokenMap(this._queries,i),i},e.prototype._getLocalDependency=function(t,e){var n=null;if(c.isBlank(n)&&c.isPresent(e.query)&&(n=this._addQuery(e.query,null).queryList),c.isBlank(n)&&c.isPresent(e.viewQuery)&&(n=d.createQueryList(e.viewQuery,null,"_viewQuery_"+e.viewQuery.selectors[0].name+"_"+this.nodeIndex+"_"+this._componentConstructorViewQueryLists.length,this.view),this._componentConstructorViewQueryLists.push(n)),c.isPresent(e.token)){if(c.isBlank(n)&&e.token.equalsTo(a.identifierToken(a.Identifiers.ChangeDetectorRef)))return t===l.ProviderAstType.Component?this._compViewExpr.prop("ref"):s.THIS_EXPR.prop("ref");c.isBlank(n)&&(n=this._instances.get(e.token))}return n},e.prototype._getDependency=function(t,e){var n=this,r=null;for(e.isValue&&(r=s.literal(e.value)),c.isBlank(r)&&!e.isSkipSelf&&(r=this._getLocalDependency(t,e));c.isBlank(r)&&!n.parent.isNull();)n=n.parent,r=n._getLocalDependency(l.ProviderAstType.PublicService,new h.CompileDiDependencyMetadata({token:e.token}));return c.isBlank(r)&&(r=f.injectFromViewParentInjector(e.token,e.isOptional)),c.isBlank(r)&&(r=s.NULL_EXPR),f.getPropertyInView(r,this.view,n.view)},e}(y);e.CompileElement=m;var g=function(){function t(t,e){this.query=t,this.read=c.isPresent(t.meta.read)?t.meta.read:e}return t}()},function(t,e,n){"use strict";function r(t,e){if(i.isBlank(e))return c.NULL_EXPR;var n=i.resolveEnumToken(t.runtime,e);return c.importExpr(new o.CompileIdentifierMetadata({name:t.name+"."+n,moduleUrl:t.moduleUrl,runtime:e}))}var i=n(5),o=n(155),s=n(28),a=n(36),u=n(68),c=n(164),p=n(158),l=function(){function t(){}return t.fromValue=function(t){return r(p.Identifiers.ViewType,t)},t.HOST=t.fromValue(u.ViewType.HOST),t.COMPONENT=t.fromValue(u.ViewType.COMPONENT),t.EMBEDDED=t.fromValue(u.ViewType.EMBEDDED),t}();e.ViewTypeEnum=l;var h=function(){function t(){}return t.fromValue=function(t){return r(p.Identifiers.ViewEncapsulation,t)},t.Emulated=t.fromValue(a.ViewEncapsulation.Emulated),t.Native=t.fromValue(a.ViewEncapsulation.Native),t.None=t.fromValue(a.ViewEncapsulation.None),t}();e.ViewEncapsulationEnum=h;var f=function(){function t(){}return t.fromValue=function(t){return r(p.Identifiers.ChangeDetectorState,t)},t.NeverChecked=t.fromValue(s.ChangeDetectorState.NeverChecked),t.CheckedBefore=t.fromValue(s.ChangeDetectorState.CheckedBefore),t.Errored=t.fromValue(s.ChangeDetectorState.Errored),t}();e.ChangeDetectorStateEnum=f;var d=function(){function t(){}return t.fromValue=function(t){return r(p.Identifiers.ChangeDetectionStrategy,t)},t.CheckOnce=t.fromValue(s.ChangeDetectionStrategy.CheckOnce),t.Checked=t.fromValue(s.ChangeDetectionStrategy.Checked),t.CheckAlways=t.fromValue(s.ChangeDetectionStrategy.CheckAlways),t.Detached=t.fromValue(s.ChangeDetectionStrategy.Detached),t.OnPush=t.fromValue(s.ChangeDetectionStrategy.OnPush),t.Default=t.fromValue(s.ChangeDetectionStrategy.Default),t}();e.ChangeDetectionStrategyEnum=d;var v=function(){function t(){}return t.viewUtils=c.variable("viewUtils"),t.parentInjector=c.variable("parentInjector"),t.declarationEl=c.variable("declarationEl"),t}();e.ViewConstructorVars=v;var y=function(){function t(){}return t.renderer=c.THIS_EXPR.prop("renderer"),t.projectableNodes=c.THIS_EXPR.prop("projectableNodes"),t.viewUtils=c.THIS_EXPR.prop("viewUtils"),t}();e.ViewProperties=y;var m=function(){function t(){}return t.event=c.variable("$event"),t}();e.EventHandlerVars=m;var g=function(){function t(){}return t.token=c.variable("token"),t.requestNodeIndex=c.variable("requestNodeIndex"),t.notFoundResult=c.variable("notFoundResult"),t}();e.InjectMethodVars=g;var _=function(){function t(){}return t.throwOnChange=c.variable("throwOnChange"),t.changes=c.variable("changes"),t.changed=c.variable("changed"),t.valUnwrapper=c.variable("valUnwrapper"),t}();e.DetectChangesVars=_},function(t,e,n){"use strict";function r(t,e,n){if(e===n)return t;for(var r=l.THIS_EXPR,i=e;i!==n&&c.isPresent(i.declarationElement.view);)i=i.declarationElement.view,r=r.prop("parent");if(i!==n)throw new p.BaseException("Internal error: Could not calculate a property in a parent view: "+t);if(t instanceof l.ReadPropExpr){var o=t;(n.fields.some(function(t){return t.name==o.name})||n.getters.some(function(t){return t.name==o.name}))&&(r=r.cast(n.classType))}return l.replaceVarInExpression(l.THIS_EXPR.name,r,t)}function i(t,e){var n=[s(t)];return e&&n.push(l.NULL_EXPR),l.THIS_EXPR.prop("parentInjector").callMethod("get",n)}function o(t,e){return"viewFactory_"+t.type.name+e}function s(t){return c.isPresent(t.value)?l.literal(t.value):t.identifierIsInstance?l.importExpr(t.identifier).instantiate([],l.importType(t.identifier,[],[l.TypeModifier.Const])):l.importExpr(t.identifier)}function a(t){for(var e=[],n=l.literalArr([]),r=0;r<t.length;r++){var i=t[r];i.type instanceof l.ArrayType?(e.length>0&&(n=n.callMethod(l.BuiltinMethod.ConcatArray,[l.literalArr(e)]),e=[]),n=n.callMethod(l.BuiltinMethod.ConcatArray,[i])):e.push(i)}return e.length>0&&(n=n.callMethod(l.BuiltinMethod.ConcatArray,[l.literalArr(e)])),n}function u(t,e,n,r){r.fields.push(new l.ClassField(n.name,null,[l.StmtModifier.Private]));var i=e<h.Identifiers.pureProxies.length?h.Identifiers.pureProxies[e]:null;if(c.isBlank(i))throw new p.BaseException("Unsupported number of argument for pure functions: "+e);r.createMethod.addStmt(l.THIS_EXPR.prop(n.name).set(l.importExpr(i).callFn([t])).toStmt())}var c=n(5),p=n(12),l=n(164),h=n(158);e.getPropertyInView=r,e.injectFromViewParentInjector=i,e.getViewFactoryName=o,e.createDiTokenExpression=s,e.createFlatArray=a,e.createPureProxy=u},function(t,e,n){"use strict";function r(t){return u.ListWrapper.flatten(t.values.map(function(t){return t instanceof h?i(t.view.declarationElement.appElement,t.view,r(t)):t}))}function i(t,e,n){var r=n.map(function(t){return c.replaceVarInExpression(c.THIS_EXPR.name,c.variable("nestedView"),t)});return t.callMethod("mapNestedViews",[c.variable(e.className),c.fn([new c.FnParam("nestedView",e.classType)],[new c.ReturnStatement(c.literalArr(r))])])}function o(t,e,n,r){r.fields.push(new c.ClassField(n,c.importType(p.Identifiers.QueryList),[c.StmtModifier.Private]));var i=c.THIS_EXPR.prop(n);return r.createMethod.addStmt(c.THIS_EXPR.prop(n).set(c.importExpr(p.Identifiers.QueryList).instantiate([])).toStmt()),i}function s(t,e){e.meta.selectors.forEach(function(n){var r=t.get(n);a.isBlank(r)&&(r=[],t.add(n,r)),r.push(e)})}var a=n(5),u=n(15),c=n(164),p=n(158),l=n(171),h=function(){function t(t,e){this.view=t,this.values=e}return t}(),f=function(){function t(t,e,n,r){this.meta=t,this.queryList=e,this.ownerDirectiveExpression=n,this.view=r,this._values=new h(r,[])}return t.prototype.addValue=function(t,e){for(var n=e,r=[];a.isPresent(n)&&n!==this.view;){var i=n.declarationElement;r.unshift(i),n=i.view}var o=l.getPropertyInView(this.queryList,e,this.view),s=this._values;r.forEach(function(t){var e=s.values.length>0?s.values[s.values.length-1]:null;if(e instanceof h&&e.view===t.embeddedView)s=e;else{var n=new h(t.embeddedView,[]);s.values.push(n),s=n}}),s.values.push(t),r.length>0&&e.dirtyParentQueriesMethod.addStmt(o.callMethod("setDirty",[]).toStmt())},t.prototype.afterChildren=function(t){var e=r(this._values),n=[this.queryList.callMethod("reset",[c.literalArr(e)]).toStmt()];if(a.isPresent(this.ownerDirectiveExpression)){var i=this.meta.first?this.queryList.prop("first"):this.queryList;n.push(this.ownerDirectiveExpression.prop(this.meta.propertyName).set(i).toStmt())}this.meta.first||n.push(this.queryList.callMethod("notifyOnChanges",[]).toStmt()),t.addStmt(new c.IfStmt(this.queryList.prop("dirty"),n))},t}();e.CompileQuery=f,e.createQueryList=o,e.addQueryToTokenMap=s},function(t,e,n){"use strict";var r=n(5),i=n(15),o=n(164),s=function(){function t(t,e){this.nodeIndex=t,this.sourceAst=e}return t}(),a=new s(null,null),u=function(){function t(t){this._view=t,this._newState=a,this._currState=a,this._bodyStatements=[],this._debugEnabled=this._view.genConfig.genDebugInfo}return t.prototype._updateDebugContextIfNeeded=function(){if(this._newState.nodeIndex!==this._currState.nodeIndex||this._newState.sourceAst!==this._currState.sourceAst){var t=this._updateDebugContext(this._newState);r.isPresent(t)&&this._bodyStatements.push(t.toStmt())}},t.prototype._updateDebugContext=function(t){if(this._currState=this._newState=t,this._debugEnabled){var e=r.isPresent(t.sourceAst)?t.sourceAst.sourceSpan.start:null;return o.THIS_EXPR.callMethod("debug",[o.literal(t.nodeIndex),r.isPresent(e)?o.literal(e.line):o.NULL_EXPR,r.isPresent(e)?o.literal(e.col):o.NULL_EXPR])}return null},t.prototype.resetDebugInfoExpr=function(t,e){var n=this._updateDebugContext(new s(t,e));return r.isPresent(n)?n:o.NULL_EXPR},t.prototype.resetDebugInfo=function(t,e){this._newState=new s(t,e)},t.prototype.addStmt=function(t){this._updateDebugContextIfNeeded(),this._bodyStatements.push(t)},t.prototype.addStmts=function(t){this._updateDebugContextIfNeeded(),i.ListWrapper.addAll(this._bodyStatements,t)},t.prototype.finish=function(){return this._bodyStatements},t.prototype.isEmpty=function(){return 0===this._bodyStatements.length},t}();e.CompileMethod=u},function(t,e,n){"use strict";function r(t,e){return e>0?l.ViewType.EMBEDDED:t.type.isHost?l.ViewType.HOST:l.ViewType.COMPONENT}var i=n(5),o=n(15),s=n(164),a=n(170),u=n(172),c=n(173),p=n(175),l=n(68),h=n(155),f=n(171),d=function(){function t(t,e,n,a,p,d,v){var y=this;this.component=t,this.genConfig=e,this.pipeMetas=n,this.styles=a,this.viewIndex=p,this.declarationElement=d,this.templateVariableBindings=v,this.nodes=[],this.rootNodesOrAppElements=[],this.bindings=[],this.classStatements=[],this.eventHandlerMethods=[],this.fields=[],this.getters=[],this.disposables=[],this.subscriptions=[],this.purePipes=new Map,this.pipes=[],this.variables=new Map,this.literalArrayCount=0,this.literalMapCount=0,this.pipeCount=0,this.createMethod=new c.CompileMethod(this),this.injectorGetMethod=new c.CompileMethod(this),this.updateContentQueriesMethod=new c.CompileMethod(this),this.dirtyParentQueriesMethod=new c.CompileMethod(this),this.updateViewQueriesMethod=new c.CompileMethod(this),this.detectChangesInInputsMethod=new c.CompileMethod(this),this.detectChangesRenderPropertiesMethod=new c.CompileMethod(this),this.afterContentLifecycleCallbacksMethod=new c.CompileMethod(this),this.afterViewLifecycleCallbacksMethod=new c.CompileMethod(this),this.destroyMethod=new c.CompileMethod(this),this.viewType=r(t,p),this.className="_View_"+t.type.name+p,this.classType=s.importType(new h.CompileIdentifierMetadata({name:this.className})),this.viewFactory=s.variable(f.getViewFactoryName(t,p)),this.viewType===l.ViewType.COMPONENT||this.viewType===l.ViewType.HOST?this.componentView=this:this.componentView=this.declarationElement.view.componentView;var m=new h.CompileTokenMap;if(this.viewType===l.ViewType.COMPONENT){var g=s.THIS_EXPR.prop("context");o.ListWrapper.forEachWithIndex(this.component.viewQueries,function(t,e){var n="_viewQuery_"+t.selectors[0].name+"_"+e,r=u.createQueryList(t,g,n,y),i=new u.CompileQuery(t,r,g,y);u.addQueryToTokenMap(m,i)});var _=0;this.component.type.diDeps.forEach(function(t){if(i.isPresent(t.viewQuery)){var e=s.THIS_EXPR.prop("declarationAppElement").prop("componentConstructorViewQueries").key(s.literal(_++)),n=new u.CompileQuery(t.viewQuery,e,null,y);u.addQueryToTokenMap(m,n)}})}this.viewQueries=m,v.forEach(function(t){y.variables.set(t[1],s.THIS_EXPR.prop("locals").key(s.literal(t[0])))}),this.declarationElement.isNull()||this.declarationElement.setEmbeddedView(this)}return t.prototype.callPipe=function(t,e,n){var r=this.componentView,o=r.purePipes.get(t);return i.isBlank(o)&&(o=new p.CompilePipe(r,t),o.pure&&r.purePipes.set(t,o),r.pipes.push(o)),o.call(this,[e].concat(n))},t.prototype.getVariable=function(t){if(t==a.EventHandlerVars.event.name)return a.EventHandlerVars.event;for(var e=this,n=e.variables.get(t);i.isBlank(n)&&i.isPresent(e.declarationElement.view);)e=e.declarationElement.view,n=e.variables.get(t);return i.isPresent(n)?f.getPropertyInView(n,this,e):null},t.prototype.createLiteralArray=function(t){for(var e=s.THIS_EXPR.prop("_arr_"+this.literalArrayCount++),n=[],r=[],i=0;i<t.length;i++){var o="p"+i;n.push(new s.FnParam(o)),r.push(s.variable(o))}return f.createPureProxy(s.fn(n,[new s.ReturnStatement(s.literalArr(r))]),t.length,e,this),e.callFn(t)},t.prototype.createLiteralMap=function(t){for(var e=s.THIS_EXPR.prop("_map_"+this.literalMapCount++),n=[],r=[],i=[],o=0;o<t.length;o++){var a="p"+o;n.push(new s.FnParam(a)),r.push([t[o][0],s.variable(a)]),i.push(t[o][1])}return f.createPureProxy(s.fn(n,[new s.ReturnStatement(s.literalMap(r))]),t.length,e,this),e.callFn(i)},t.prototype.afterNodes=function(){var t=this;this.pipes.forEach(function(t){return t.create()}),this.viewQueries.values().forEach(function(e){return e.forEach(function(e){return e.afterChildren(t.updateViewQueriesMethod)})})},t}();e.CompileView=d},function(t,e,n){"use strict";function r(t,e){for(var n=null,r=t.pipeMetas.length-1;r>=0;r--){var s=t.pipeMetas[r];if(s.name==e){n=s;break}}if(i.isBlank(n))throw new o.BaseException("Illegal state: Could not find pipe "+e+" although the parser should have detected this error!");return n}var i=n(5),o=n(12),s=n(164),a=n(158),u=n(171),c=function(){function t(t,e){this.instance=t,this.argCount=e}return t}(),p=function(){function t(t,e){this.view=t,this._purePipeProxies=[],this.meta=r(t,e),this.instance=s.THIS_EXPR.prop("_pipe_"+e+"_"+t.pipeCount++)}return Object.defineProperty(t.prototype,"pure",{get:function(){return this.meta.pure},enumerable:!0,configurable:!0}),t.prototype.create=function(){var t=this,e=this.meta.type.diDeps.map(function(t){return t.token.equalsTo(a.identifierToken(a.Identifiers.ChangeDetectorRef))?s.THIS_EXPR.prop("ref"):u.injectFromViewParentInjector(t.token,!1)});this.view.fields.push(new s.ClassField(this.instance.name,s.importType(this.meta.type),[s.StmtModifier.Private])),this.view.createMethod.resetDebugInfo(null,null),this.view.createMethod.addStmt(s.THIS_EXPR.prop(this.instance.name).set(s.importExpr(this.meta.type).instantiate(e)).toStmt()),this._purePipeProxies.forEach(function(e){u.createPureProxy(t.instance.prop("transform").callMethod(s.BuiltinMethod.bind,[t.instance]),e.argCount,e.instance,t.view)})},t.prototype.call=function(t,e){if(this.meta.pure){var n=new c(s.THIS_EXPR.prop(this.instance.name+"_"+this._purePipeProxies.length),e.length);return this._purePipeProxies.push(n),u.getPropertyInView(s.importExpr(a.Identifiers.castByValue).callFn([n.instance,this.instance.prop("transform")]),t,this.view).callFn(e)}return u.getPropertyInView(this.instance,t,this.view).callMethod("transform",e)},t}();e.CompilePipe=p},function(t,e,n){"use strict";function r(t,e,n,r){var i=new L(t,n,r);return S.templateVisitAll(i,e,t.declarationElement.isNull()?t.declarationElement:t.declarationElement.parent),I.bindView(t,e),t.afterNodes(),c(t,r),i.nestedViewCount}function i(t,e){var n={};return _.StringMapWrapper.forEach(t,function(t,e){n[e]=t}),e.forEach(function(t){_.StringMapWrapper.forEach(t.hostAttributes,function(t,e){var r=n[e];n[e]=g.isPresent(r)?a(e,r,t):t})}),u(n)}function o(t){var e={};return t.forEach(function(t){e[t.name]=t.value}),e}function s(t,e,n){var r={},i=null;return e.forEach(function(t){t.directive.isComponent&&(i=t.directive),t.exportAsVars.forEach(function(e){r[e.name]=P.identifierToken(t.directive.type)})}),t.forEach(function(t){r[t.name]=g.isPresent(i)?P.identifierToken(i.type):null}),r}function a(t,e,n){return t==k||t==N?e+" "+n:n}function u(t){var e=[];_.StringMapWrapper.forEach(t,function(t,n){e.push([n,t])}),_.ListWrapper.sort(e,function(t,e){return g.StringWrapper.compare(t[0],e[0])});var n=[];return e.forEach(function(t){n.push([t[0],t[1]])}),n}function c(t,e){var n=b.NULL_EXPR;t.genConfig.genDebugInfo&&(n=b.variable("nodeDebugInfos_"+t.component.type.name+t.viewIndex),e.push(n.set(b.literalArr(t.nodes.map(p),new b.ArrayType(new b.ExternalType(P.Identifiers.StaticNodeDebugInfo),[b.TypeModifier.Const]))).toDeclStmt(null,[b.StmtModifier.Final])));var r=b.variable("renderType_"+t.component.type.name);0===t.viewIndex&&e.push(r.set(b.NULL_EXPR).toDeclStmt(b.importType(P.Identifiers.RenderComponentType)));var i=l(t,r,n);e.push(i),e.push(h(t,i,r))}function p(t){var e=t instanceof R.CompileElement?t:null,n=[],r=b.NULL_EXPR,i=[];return g.isPresent(e)&&(n=e.getProviderTokens(),g.isPresent(e.component)&&(r=O.createDiTokenExpression(P.identifierToken(e.component.type))),_.StringMapWrapper.forEach(e.variableTokens,function(t,e){i.push([e,g.isPresent(t)?O.createDiTokenExpression(t):b.NULL_EXPR])})),b.importExpr(P.Identifiers.StaticNodeDebugInfo).instantiate([b.literalArr(n,new b.ArrayType(b.DYNAMIC_TYPE,[b.TypeModifier.Const])),r,b.literalMap(i,new b.MapType(b.DYNAMIC_TYPE,[b.TypeModifier.Const]))],b.importType(P.Identifiers.StaticNodeDebugInfo,null,[b.TypeModifier.Const]))}function l(t,e,n){var r=t.templateVariableBindings.map(function(t){return[t[0],b.NULL_EXPR]}),i=[new b.FnParam(E.ViewConstructorVars.viewUtils.name,b.importType(P.Identifiers.ViewUtils)),new b.FnParam(E.ViewConstructorVars.parentInjector.name,b.importType(P.Identifiers.Injector)),new b.FnParam(E.ViewConstructorVars.declarationEl.name,b.importType(P.Identifiers.AppElement))],o=new b.ClassMethod(null,i,[b.SUPER_EXPR.callFn([b.variable(t.className),e,E.ViewTypeEnum.fromValue(t.viewType),b.literalMap(r),E.ViewConstructorVars.viewUtils,E.ViewConstructorVars.parentInjector,E.ViewConstructorVars.declarationEl,E.ChangeDetectionStrategyEnum.fromValue(m(t)),n]).toStmt()]),s=[new b.ClassMethod("createInternal",[new b.FnParam(V.name,b.STRING_TYPE)],f(t),b.importType(P.Identifiers.AppElement)),new b.ClassMethod("injectorGetInternal",[new b.FnParam(E.InjectMethodVars.token.name,b.DYNAMIC_TYPE),new b.FnParam(E.InjectMethodVars.requestNodeIndex.name,b.NUMBER_TYPE),new b.FnParam(E.InjectMethodVars.notFoundResult.name,b.DYNAMIC_TYPE)],v(t.injectorGetMethod.finish(),E.InjectMethodVars.notFoundResult),b.DYNAMIC_TYPE),new b.ClassMethod("detectChangesInternal",[new b.FnParam(E.DetectChangesVars.throwOnChange.name,b.BOOL_TYPE)],d(t)),new b.ClassMethod("dirtyParentQueriesInternal",[],t.dirtyParentQueriesMethod.finish()),new b.ClassMethod("destroyInternal",[],t.destroyMethod.finish())].concat(t.eventHandlerMethods),a=new b.ClassStmt(t.className,b.importExpr(P.Identifiers.AppView,[y(t)]),t.fields,t.getters,o,s.filter(function(t){return t.body.length>0}));return a}function h(t,e,n){var r,i=[new b.FnParam(E.ViewConstructorVars.viewUtils.name,b.importType(P.Identifiers.ViewUtils)),new b.FnParam(E.ViewConstructorVars.parentInjector.name,b.importType(P.Identifiers.Injector)),new b.FnParam(E.ViewConstructorVars.declarationEl.name,b.importType(P.Identifiers.AppElement))],o=[];return r=t.component.template.templateUrl==t.component.type.moduleUrl?t.component.type.moduleUrl+" class "+t.component.type.name+" - inline template":t.component.template.templateUrl,0===t.viewIndex&&(o=[new b.IfStmt(n.identical(b.NULL_EXPR),[n.set(E.ViewConstructorVars.viewUtils.callMethod("createRenderComponentType",[b.literal(r),b.literal(t.component.template.ngContentSelectors.length),E.ViewEncapsulationEnum.fromValue(t.component.template.encapsulation),t.styles])).toStmt()])]),
                +b.fn(i,o.concat([new b.ReturnStatement(b.variable(e.name).instantiate(e.constructorMethod.params.map(function(t){return b.variable(t.name)})))]),b.importType(P.Identifiers.AppView,[y(t)])).toDeclStmt(t.viewFactory.name,[b.StmtModifier.Final])}function f(t){var e=b.NULL_EXPR,n=[];t.viewType===T.ViewType.COMPONENT&&(e=E.ViewProperties.renderer.callMethod("createViewRoot",[b.THIS_EXPR.prop("declarationAppElement").prop("nativeElement")]),n=[D.set(e).toDeclStmt(b.importType(t.genConfig.renderTypes.renderNode),[b.StmtModifier.Final])]);var r;return r=t.viewType===T.ViewType.HOST?t.nodes[0].appElement:b.NULL_EXPR,n.concat(t.createMethod.finish()).concat([b.THIS_EXPR.callMethod("init",[O.createFlatArray(t.rootNodesOrAppElements),b.literalArr(t.nodes.map(function(t){return t.renderNode})),b.literalArr(t.disposables),b.literalArr(t.subscriptions)]).toStmt(),new b.ReturnStatement(r)])}function d(t){var e=[];if(t.detectChangesInInputsMethod.isEmpty()&&t.updateContentQueriesMethod.isEmpty()&&t.afterContentLifecycleCallbacksMethod.isEmpty()&&t.detectChangesRenderPropertiesMethod.isEmpty()&&t.updateViewQueriesMethod.isEmpty()&&t.afterViewLifecycleCallbacksMethod.isEmpty())return e;_.ListWrapper.addAll(e,t.detectChangesInInputsMethod.finish()),e.push(b.THIS_EXPR.callMethod("detectContentChildrenChanges",[E.DetectChangesVars.throwOnChange]).toStmt());var n=t.updateContentQueriesMethod.finish().concat(t.afterContentLifecycleCallbacksMethod.finish());n.length>0&&e.push(new b.IfStmt(b.not(E.DetectChangesVars.throwOnChange),n)),_.ListWrapper.addAll(e,t.detectChangesRenderPropertiesMethod.finish()),e.push(b.THIS_EXPR.callMethod("detectViewChildrenChanges",[E.DetectChangesVars.throwOnChange]).toStmt());var r=t.updateViewQueriesMethod.finish().concat(t.afterViewLifecycleCallbacksMethod.finish());r.length>0&&e.push(new b.IfStmt(b.not(E.DetectChangesVars.throwOnChange),r));var i=[],o=b.findReadVarNames(e);return _.SetWrapper.has(o,E.DetectChangesVars.changed.name)&&i.push(E.DetectChangesVars.changed.set(b.literal(!0)).toDeclStmt(b.BOOL_TYPE)),_.SetWrapper.has(o,E.DetectChangesVars.changes.name)&&i.push(E.DetectChangesVars.changes.set(b.NULL_EXPR).toDeclStmt(new b.MapType(b.importType(P.Identifiers.SimpleChange)))),_.SetWrapper.has(o,E.DetectChangesVars.valUnwrapper.name)&&i.push(E.DetectChangesVars.valUnwrapper.set(b.importExpr(P.Identifiers.ValueUnwrapper).instantiate([])).toDeclStmt(null,[b.StmtModifier.Final])),i.concat(e)}function v(t,e){return t.length>0?t.concat([new b.ReturnStatement(e)]):t}function y(t){var e=t.component.type;return e.isHost?b.DYNAMIC_TYPE:b.importType(e)}function m(t){var e;return e=t.viewType===T.ViewType.COMPONENT?w.isDefaultChangeDetectionStrategy(t.component.changeDetection)?w.ChangeDetectionStrategy.CheckAlways:w.ChangeDetectionStrategy.CheckOnce:w.ChangeDetectionStrategy.CheckAlways}var g=n(5),_=n(15),b=n(164),P=n(158),E=n(170),w=n(28),C=n(174),R=n(169),S=n(139),O=n(171),T=n(68),x=n(36),A=n(155),I=n(177),M="$implicit",k="class",N="style",D=b.variable("parentRenderNode"),V=b.variable("rootSelector"),j=function(){function t(t,e){this.comp=t,this.factoryPlaceholder=e}return t}();e.ViewCompileDependency=j,e.buildView=r;var L=function(){function t(t,e,n){this.view=t,this.targetDependencies=e,this.targetStatements=n,this.nestedViewCount=0}return t.prototype._isRootNode=function(t){return t.view!==this.view},t.prototype._addRootNodeAndProject=function(t,e,n){var r=t instanceof R.CompileElement&&t.hasViewContainer?t.appElement:null;this._isRootNode(n)?this.view.viewType!==T.ViewType.COMPONENT&&this.view.rootNodesOrAppElements.push(g.isPresent(r)?r:t.renderNode):g.isPresent(n.component)&&g.isPresent(e)&&n.addContentNode(e,g.isPresent(r)?r:t.renderNode)},t.prototype._getParentRenderNode=function(t){return this._isRootNode(t)?this.view.viewType===T.ViewType.COMPONENT?D:b.NULL_EXPR:g.isPresent(t.component)&&t.component.template.encapsulation!==x.ViewEncapsulation.Native?b.NULL_EXPR:t.renderNode},t.prototype.visitBoundText=function(t,e){return this._visitText(t,"",t.ngContentIndex,e)},t.prototype.visitText=function(t,e){return this._visitText(t,t.value,t.ngContentIndex,e)},t.prototype._visitText=function(t,e,n,r){var i="_text_"+this.view.nodes.length;this.view.fields.push(new b.ClassField(i,b.importType(this.view.genConfig.renderTypes.renderText),[b.StmtModifier.Private]));var o=b.THIS_EXPR.prop(i),s=new R.CompileNode(r,this.view,this.view.nodes.length,o,t),a=b.THIS_EXPR.prop(i).set(E.ViewProperties.renderer.callMethod("createText",[this._getParentRenderNode(r),b.literal(e),this.view.createMethod.resetDebugInfoExpr(this.view.nodes.length,t)])).toStmt();return this.view.nodes.push(s),this.view.createMethod.addStmt(a),this._addRootNodeAndProject(s,n,r),o},t.prototype.visitNgContent=function(t,e){this.view.createMethod.resetDebugInfo(null,t);var n=this._getParentRenderNode(e),r=E.ViewProperties.projectableNodes.key(b.literal(t.index),new b.ArrayType(b.importType(this.view.genConfig.renderTypes.renderNode)));return n!==b.NULL_EXPR?this.view.createMethod.addStmt(E.ViewProperties.renderer.callMethod("projectNodes",[n,b.importExpr(P.Identifiers.flattenNestedViewRenderNodes).callFn([r])]).toStmt()):this._isRootNode(e)?this.view.viewType!==T.ViewType.COMPONENT&&this.view.rootNodesOrAppElements.push(r):g.isPresent(e.component)&&g.isPresent(t.ngContentIndex)&&e.addContentNode(t.ngContentIndex,r),null},t.prototype.visitElement=function(t,e){var n,r=this.view.nodes.length,a=this.view.createMethod.resetDebugInfoExpr(r,t);n=0===r&&this.view.viewType===T.ViewType.HOST?b.THIS_EXPR.callMethod("selectOrCreateHostElement",[b.literal(t.name),V,a]):E.ViewProperties.renderer.callMethod("createElement",[this._getParentRenderNode(e),b.literal(t.name),a]);var u="_el_"+r;this.view.fields.push(new b.ClassField(u,b.importType(this.view.genConfig.renderTypes.renderElement),[b.StmtModifier.Private])),this.view.createMethod.addStmt(b.THIS_EXPR.prop(u).set(n).toStmt());for(var c=b.THIS_EXPR.prop(u),p=t.getComponent(),l=t.directives.map(function(t){return t.directive}),h=s(t.exportAsVars,t.directives,this.view.viewType),f=o(t.attrs),d=i(f,l),v=0;v<d.length;v++){var y=d[v][0],m=d[v][1];this.view.createMethod.addStmt(E.ViewProperties.renderer.callMethod("setElementAttribute",[c,b.literal(y),b.literal(m)]).toStmt())}var _=new R.CompileElement(e,this.view,r,c,t,p,l,t.providers,t.hasViewContainer,!1,h);this.view.nodes.push(_);var P=null;if(g.isPresent(p)){var w=new A.CompileIdentifierMetadata({name:O.getViewFactoryName(p,0)});this.targetDependencies.push(new j(p,w)),P=b.variable("compView_"+r),_.setComponentView(P),this.view.createMethod.addStmt(P.set(b.importExpr(w).callFn([E.ViewProperties.viewUtils,_.injector,_.appElement])).toDeclStmt())}if(_.beforeChildren(),this._addRootNodeAndProject(_,t.ngContentIndex,e),S.templateVisitAll(this,t.children,_),_.afterChildren(this.view.nodes.length-r-1),g.isPresent(P)){var C;C=this.view.component.type.isHost?E.ViewProperties.projectableNodes:b.literalArr(_.contentNodesByNgContentIndex.map(function(t){return O.createFlatArray(t)})),this.view.createMethod.addStmt(P.callMethod("create",[C,b.NULL_EXPR]).toStmt())}return null},t.prototype.visitEmbeddedTemplate=function(t,e){var n=this.view.nodes.length,i="_anchor_"+n;this.view.fields.push(new b.ClassField(i,b.importType(this.view.genConfig.renderTypes.renderComment),[b.StmtModifier.Private])),this.view.createMethod.addStmt(b.THIS_EXPR.prop(i).set(E.ViewProperties.renderer.callMethod("createTemplateAnchor",[this._getParentRenderNode(e),this.view.createMethod.resetDebugInfoExpr(n,t)])).toStmt());var o=b.THIS_EXPR.prop(i),s=t.vars.map(function(t){return[t.value.length>0?t.value:M,t.name]}),a=t.directives.map(function(t){return t.directive}),u=new R.CompileElement(e,this.view,n,o,t,null,a,t.providers,t.hasViewContainer,!0,{});this.view.nodes.push(u),this.nestedViewCount++;var c=new C.CompileView(this.view.component,this.view.genConfig,this.view.pipeMetas,b.NULL_EXPR,this.view.viewIndex+this.nestedViewCount,u,s);return this.nestedViewCount+=r(c,t.children,this.targetDependencies,this.targetStatements),u.beforeChildren(),this._addRootNodeAndProject(u,t.ngContentIndex,e),u.afterChildren(0),null},t.prototype.visitAttr=function(t,e){return null},t.prototype.visitDirective=function(t,e){return null},t.prototype.visitEvent=function(t,e){return null},t.prototype.visitVariable=function(t,e){return null},t.prototype.visitDirectiveProperty=function(t,e){return null},t.prototype.visitElementProperty=function(t,e){return null},t}()},function(t,e,n){"use strict";function r(t,e){var n=new c(t);o.templateVisitAll(n,e),t.pipes.forEach(function(t){u.bindPipeDestroyLifecycleCallbacks(t.meta,t.instance,t.view)})}var i=n(15),o=n(139),s=n(178),a=n(181),u=n(182);e.bindView=r;var c=function(){function t(t){this.view=t,this._nodeIndex=0}return t.prototype.visitBoundText=function(t,e){var n=this.view.nodes[this._nodeIndex++];return s.bindRenderText(t,n,this.view),null},t.prototype.visitText=function(t,e){return this._nodeIndex++,null},t.prototype.visitNgContent=function(t,e){return null},t.prototype.visitElement=function(t,e){var n=this.view.nodes[this._nodeIndex++],r=a.collectEventListeners(t.outputs,t.directives,n);return s.bindRenderInputs(t.inputs,n),a.bindRenderOutputs(r),i.ListWrapper.forEachWithIndex(t.directives,function(t,e){var i=n.directiveInstances[e];s.bindDirectiveInputs(t,i,n),u.bindDirectiveDetectChangesLifecycleCallbacks(t,i,n),s.bindDirectiveHostProps(t,i,n),a.bindDirectiveOutputs(t,i,r)}),o.templateVisitAll(this,t.children,n),i.ListWrapper.forEachWithIndex(t.directives,function(t,e){var r=n.directiveInstances[e];u.bindDirectiveAfterContentLifecycleCallbacks(t.directive,r,n),u.bindDirectiveAfterViewLifecycleCallbacks(t.directive,r,n),u.bindDirectiveDestroyLifecycleCallbacks(t.directive,r,n)}),null},t.prototype.visitEmbeddedTemplate=function(t,e){var n=this.view.nodes[this._nodeIndex++],r=a.collectEventListeners(t.outputs,t.directives,n);return i.ListWrapper.forEachWithIndex(t.directives,function(t,e){var i=n.directiveInstances[e];s.bindDirectiveInputs(t,i,n),u.bindDirectiveDetectChangesLifecycleCallbacks(t,i,n),a.bindDirectiveOutputs(t,i,r),u.bindDirectiveAfterContentLifecycleCallbacks(t.directive,i,n),u.bindDirectiveAfterViewLifecycleCallbacks(t.directive,i,n),u.bindDirectiveDestroyLifecycleCallbacks(t.directive,i,n)}),null},t.prototype.visitAttr=function(t,e){return null},t.prototype.visitDirective=function(t,e){return null},t.prototype.visitEvent=function(t,e){return null},t.prototype.visitVariable=function(t,e){return null},t.prototype.visitDirectiveProperty=function(t,e){return null},t.prototype.visitElementProperty=function(t,e){return null},t}()},function(t,e,n){"use strict";function r(t){return h.THIS_EXPR.prop("_expr_"+t)}function i(t){return h.variable("currVal_"+t)}function o(t,e,n,r,i,o,s){var a=b.convertCdExpressionToIr(t,i,r,d.DetectChangesVars.valUnwrapper);if(!y.isBlank(a.expression)){if(t.fields.push(new h.ClassField(n.name,null,[h.StmtModifier.Private])),t.createMethod.addStmt(h.THIS_EXPR.prop(n.name).set(h.importExpr(f.Identifiers.uninitialized)).toStmt()),a.needsValueUnwrapper){var u=d.DetectChangesVars.valUnwrapper.callMethod("reset",[]).toStmt();s.addStmt(u)}s.addStmt(e.set(a.expression).toDeclStmt(null,[h.StmtModifier.Final]));var c=h.importExpr(f.Identifiers.checkBinding).callFn([d.DetectChangesVars.throwOnChange,n,e]);a.needsValueUnwrapper&&(c=d.DetectChangesVars.valUnwrapper.prop("hasWrappedValue").or(c)),s.addStmt(new h.IfStmt(c,o.concat([h.THIS_EXPR.prop(n.name).set(e).toStmt()])))}}function s(t,e,n){var s=n.bindings.length;n.bindings.push(new P.CompileBinding(e,t));var a=i(s),u=r(s);n.detectChangesRenderPropertiesMethod.resetDebugInfo(e.nodeIndex,t),o(n,a,u,t.value,h.THIS_EXPR.prop("context"),[h.THIS_EXPR.prop("renderer").callMethod("setText",[e.renderNode,a]).toStmt()],n.detectChangesRenderPropertiesMethod)}function a(t,e,n){var s=n.view,a=n.renderNode;t.forEach(function(t){var u=s.bindings.length;s.bindings.push(new P.CompileBinding(n,t)),s.detectChangesRenderPropertiesMethod.resetDebugInfo(n.nodeIndex,t);var c,p=r(u),f=i(u),d=f,m=[];switch(t.type){case v.PropertyBindingType.Property:c="setElementProperty",s.genConfig.logBindingUpdate&&m.push(l(a,t.name,f));break;case v.PropertyBindingType.Attribute:c="setElementAttribute",d=d.isBlank().conditional(h.NULL_EXPR,d.callMethod("toString",[]));break;case v.PropertyBindingType.Class:c="setElementClass";break;case v.PropertyBindingType.Style:c="setElementStyle";var g=d.callMethod("toString",[]);y.isPresent(t.unit)&&(g=g.plus(h.literal(t.unit))),d=d.isBlank().conditional(h.NULL_EXPR,g)}m.push(h.THIS_EXPR.prop("renderer").callMethod(c,[a,h.literal(t.name),d]).toStmt()),o(s,f,p,t.value,e,m,s.detectChangesRenderPropertiesMethod)})}function u(t,e){a(t,h.THIS_EXPR.prop("context"),e)}function c(t,e,n){a(t.hostProperties,e,n)}function p(t,e,n){if(0!==t.inputs.length){var s=n.view,a=s.detectChangesInInputsMethod;a.resetDebugInfo(n.nodeIndex,n.sourceAst);var u=t.directive.lifecycleHooks,c=-1!==u.indexOf(m.LifecycleHooks.OnChanges),p=t.directive.isComponent&&!g.isDefaultChangeDetectionStrategy(t.directive.changeDetection);c&&a.addStmt(d.DetectChangesVars.changes.set(h.NULL_EXPR).toStmt()),p&&a.addStmt(d.DetectChangesVars.changed.set(h.literal(!1)).toStmt()),t.inputs.forEach(function(t){var u=s.bindings.length;s.bindings.push(new P.CompileBinding(n,t)),a.resetDebugInfo(n.nodeIndex,t);var v=r(u),y=i(u),m=[e.prop(t.directiveName).set(y).toStmt()];c&&(m.push(new h.IfStmt(d.DetectChangesVars.changes.identical(h.NULL_EXPR),[d.DetectChangesVars.changes.set(h.literalMap([],new h.MapType(h.importType(f.Identifiers.SimpleChange)))).toStmt()])),m.push(d.DetectChangesVars.changes.key(h.literal(t.directiveName)).set(h.importExpr(f.Identifiers.SimpleChange).instantiate([v,y])).toStmt())),p&&m.push(d.DetectChangesVars.changed.set(h.literal(!0)).toStmt()),s.genConfig.logBindingUpdate&&m.push(l(n.renderNode,t.directiveName,y)),o(s,y,v,t.value,h.THIS_EXPR.prop("context"),m,a)}),p&&a.addStmt(new h.IfStmt(d.DetectChangesVars.changed,[n.appElement.prop("componentView").callMethod("markAsCheckOnce",[]).toStmt()]))}}function l(t,e,n){return h.THIS_EXPR.prop("renderer").callMethod("setBindingDebugInfo",[t,h.literal("ng-reflect-"+_.camelCaseToDashCase(e)),n.isBlank().conditional(h.NULL_EXPR,n.callMethod("toString",[]))]).toStmt()}var h=n(164),f=n(158),d=n(170),v=n(139),y=n(5),m=n(156),g=n(33),_=n(153),b=n(179),P=n(180);e.bindRenderText=s,e.bindRenderInputs=u,e.bindDirectiveHostProps=c,e.bindDirectiveInputs=p},function(t,e,n){"use strict";function r(t,e,n,r){var i=new y(t,e,r),o=n.visit(i,v.Expression);return new d(o,i.needsValueUnwrapper)}function i(t,e,n){var r=new y(t,e,null),i=[];return u(n.visit(r,v.Statement),i),i}function o(t,e){if(t!==v.Statement)throw new l.BaseException("Expected a statement, but saw "+e)}function s(t,e){if(t!==v.Expression)throw new l.BaseException("Expected an expression, but saw "+e)}function a(t,e){return t===v.Statement?e.toStmt():e}function u(t,e){h.isArray(t)?t.forEach(function(t){return u(t,e)}):e.push(t)}var c=n(164),p=n(158),l=n(12),h=n(5),f=c.variable("#implicit"),d=function(){function t(t,e){this.expression=t,this.needsValueUnwrapper=e}return t}();e.ExpressionWithWrappedValueInfo=d,e.convertCdExpressionToIr=r,e.convertCdStatementToIr=i;var v;!function(t){t[t.Statement=0]="Statement",t[t.Expression=1]="Expression"}(v||(v={}));var y=function(){function t(t,e,n){this._nameResolver=t,this._implicitReceiver=e,this._valueUnwrapper=n,this.needsValueUnwrapper=!1}return t.prototype.visitBinary=function(t,e){var n;switch(t.operation){case"+":n=c.BinaryOperator.Plus;break;case"-":n=c.BinaryOperator.Minus;break;case"*":n=c.BinaryOperator.Multiply;break;case"/":n=c.BinaryOperator.Divide;break;case"%":n=c.BinaryOperator.Modulo;break;case"&&":n=c.BinaryOperator.And;break;case"||":n=c.BinaryOperator.Or;break;case"==":n=c.BinaryOperator.Equals;break;case"!=":n=c.BinaryOperator.NotEquals;break;case"===":n=c.BinaryOperator.Identical;break;case"!==":n=c.BinaryOperator.NotIdentical;break;case"<":n=c.BinaryOperator.Lower;break;case">":n=c.BinaryOperator.Bigger;break;case"<=":n=c.BinaryOperator.LowerEquals;break;case">=":n=c.BinaryOperator.BiggerEquals;break;default:throw new l.BaseException("Unsupported operation "+t.operation)}return a(e,new c.BinaryOperatorExpr(n,t.left.visit(this,v.Expression),t.right.visit(this,v.Expression)))},t.prototype.visitChain=function(t,e){return o(e,t),this.visitAll(t.expressions,e)},t.prototype.visitConditional=function(t,e){var n=t.condition.visit(this,v.Expression);return a(e,n.conditional(t.trueExp.visit(this,v.Expression),t.falseExp.visit(this,v.Expression)))},t.prototype.visitPipe=function(t,e){var n=t.exp.visit(this,v.Expression),r=this.visitAll(t.args,v.Expression),i=this._nameResolver.callPipe(t.name,n,r);return this.needsValueUnwrapper=!0,a(e,this._valueUnwrapper.callMethod("unwrap",[i]))},t.prototype.visitFunctionCall=function(t,e){return a(e,t.target.visit(this,v.Expression).callFn(this.visitAll(t.args,v.Expression)))},t.prototype.visitImplicitReceiver=function(t,e){return s(e,t),f},t.prototype.visitInterpolation=function(t,e){s(e,t);for(var n=[c.literal(t.expressions.length)],r=0;r<t.strings.length-1;r++)n.push(c.literal(t.strings[r])),n.push(t.expressions[r].visit(this,v.Expression));return n.push(c.literal(t.strings[t.strings.length-1])),c.importExpr(p.Identifiers.interpolate).callFn(n)},t.prototype.visitKeyedRead=function(t,e){return a(e,t.obj.visit(this,v.Expression).key(t.key.visit(this,v.Expression)))},t.prototype.visitKeyedWrite=function(t,e){var n=t.obj.visit(this,v.Expression),r=t.key.visit(this,v.Expression),i=t.value.visit(this,v.Expression);return a(e,n.key(r).set(i))},t.prototype.visitLiteralArray=function(t,e){return a(e,this._nameResolver.createLiteralArray(this.visitAll(t.expressions,e)))},t.prototype.visitLiteralMap=function(t,e){for(var n=[],r=0;r<t.keys.length;r++)n.push([t.keys[r],t.values[r].visit(this,v.Expression)]);return a(e,this._nameResolver.createLiteralMap(n))},t.prototype.visitLiteralPrimitive=function(t,e){return a(e,c.literal(t.value))},t.prototype.visitMethodCall=function(t,e){var n=this.visitAll(t.args,v.Expression),r=null,i=t.receiver.visit(this,v.Expression);if(i===f){var o=this._nameResolver.getVariable(t.name);h.isPresent(o)?r=o.callFn(n):i=this._implicitReceiver}return h.isBlank(r)&&(r=i.callMethod(t.name,n)),a(e,r)},t.prototype.visitPrefixNot=function(t,e){return a(e,c.not(t.expression.visit(this,v.Expression)))},t.prototype.visitPropertyRead=function(t,e){var n=null,r=t.receiver.visit(this,v.Expression);return r===f&&(n=this._nameResolver.getVariable(t.name),h.isBlank(n)&&(r=this._implicitReceiver)),h.isBlank(n)&&(n=r.prop(t.name)),a(e,n)},t.prototype.visitPropertyWrite=function(t,e){var n=t.receiver.visit(this,v.Expression);if(n===f){var r=this._nameResolver.getVariable(t.name);if(h.isPresent(r))throw new l.BaseException("Cannot reassign a variable binding");n=this._implicitReceiver}return a(e,n.prop(t.name).set(t.value.visit(this,v.Expression)))},t.prototype.visitSafePropertyRead=function(t,e){var n=t.receiver.visit(this,v.Expression);return a(e,n.isBlank().conditional(c.NULL_EXPR,n.prop(t.name)))},t.prototype.visitSafeMethodCall=function(t,e){var n=t.receiver.visit(this,v.Expression),r=this.visitAll(t.args,v.Expression);return a(e,n.isBlank().conditional(c.NULL_EXPR,n.callMethod(t.name,r)))},t.prototype.visitAll=function(t,e){var n=this;return t.map(function(t){return t.visit(n,e)})},t.prototype.visitQuote=function(t,e){throw new l.BaseException("Quotes are not supported for evaluation!")},t}()},function(t,e){"use strict";var n=function(){function t(t,e){this.node=t,this.sourceAst=e}return t}();e.CompileBinding=n},function(t,e,n){"use strict";function r(t,e,n){var r=[];return t.forEach(function(t){n.view.bindings.push(new d.CompileBinding(n,t));var e=v.getOrCreate(n,t.target,t.name,r);e.addAction(t,null,null)}),c.ListWrapper.forEachWithIndex(e,function(t,e){var i=n.directiveInstances[e];t.hostEvents.forEach(function(e){n.view.bindings.push(new d.CompileBinding(n,e));var o=v.getOrCreate(n,e.target,e.name,r);o.addAction(e,t.directive,i)})}),r.forEach(function(t){return t.finishMethod()}),r}function i(t,e,n){c.StringMapWrapper.forEach(t.directive.outputs,function(t,r){n.filter(function(e){return e.eventName==t}).forEach(function(t){t.listenToDirective(e,r)})})}function o(t){t.forEach(function(t){return t.listenToRenderer()})}function s(t){return t instanceof l.ExpressionStatement?t.expr:t instanceof l.ReturnStatement?t.value:null}function a(t){return u.StringWrapper.replaceAll(t,/[^a-zA-Z_]/g,"_")}var u=n(5),c=n(15),p=n(170),l=n(164),h=n(173),f=n(179),d=n(180),v=function(){function t(t,e,n,r){this.compileElement=t,this.eventTarget=e,this.eventName=n,this._hasComponentHostListener=!1,this._actionResultExprs=[],this._method=new h.CompileMethod(t.view),this._methodName="_handle_"+a(n)+"_"+t.nodeIndex+"_"+r,this._eventParam=new l.FnParam(p.EventHandlerVars.event.name,l.importType(this.compileElement.view.genConfig.renderTypes.renderEvent))}return t.getOrCreate=function(e,n,r,i){var o=i.find(function(t){return t.eventTarget==n&&t.eventName==r});return u.isBlank(o)&&(o=new t(e,n,r,i.length),i.push(o)),o},t.prototype.addAction=function(t,e,n){u.isPresent(e)&&e.isComponent&&(this._hasComponentHostListener=!0),this._method.resetDebugInfo(this.compileElement.nodeIndex,t);var r=u.isPresent(n)?n:l.THIS_EXPR.prop("context"),i=f.convertCdStatementToIr(this.compileElement.view,r,t.handler),o=i.length-1;if(o>=0){var a=i[o],c=s(a),p=l.variable("pd_"+this._actionResultExprs.length);this._actionResultExprs.push(p),u.isPresent(c)&&(i[o]=p.set(c.cast(l.DYNAMIC_TYPE).notIdentical(l.literal(!1))).toDeclStmt(null,[l.StmtModifier.Final]))}this._method.addStmts(i)},t.prototype.finishMethod=function(){var t=this._hasComponentHostListener?this.compileElement.appElement.prop("componentView"):l.THIS_EXPR,e=l.literal(!0);this._actionResultExprs.forEach(function(t){e=e.and(t)});var n=[t.callMethod("markPathToRootAsCheckOnce",[]).toStmt()].concat(this._method.finish()).concat([new l.ReturnStatement(e)]);this.compileElement.view.eventHandlerMethods.push(new l.ClassMethod(this._methodName,[this._eventParam],n,l.BOOL_TYPE,[l.StmtModifier.Private]))},t.prototype.listenToRenderer=function(){var t,e=l.THIS_EXPR.callMethod("eventHandler",[l.fn([this._eventParam],[new l.ReturnStatement(l.THIS_EXPR.callMethod(this._methodName,[p.EventHandlerVars.event]))])]);t=u.isPresent(this.eventTarget)?p.ViewProperties.renderer.callMethod("listenGlobal",[l.literal(this.eventTarget),l.literal(this.eventName),e]):p.ViewProperties.renderer.callMethod("listen",[this.compileElement.renderNode,l.literal(this.eventName),e]);var n=l.variable("disposable_"+this.compileElement.view.disposables.length);this.compileElement.view.disposables.push(n),this.compileElement.view.createMethod.addStmt(n.set(t).toDeclStmt(l.FUNCTION_TYPE,[l.StmtModifier.Private]))},t.prototype.listenToDirective=function(t,e){var n=l.variable("subscription_"+this.compileElement.view.subscriptions.length);this.compileElement.view.subscriptions.push(n);var r=l.THIS_EXPR.callMethod("eventHandler",[l.fn([this._eventParam],[l.THIS_EXPR.callMethod(this._methodName,[p.EventHandlerVars.event]).toStmt()])]);this.compileElement.view.createMethod.addStmt(n.set(t.prop(e).callMethod(l.BuiltinMethod.SubscribeObservable,[r])).toDeclStmt(null,[l.StmtModifier.Final]))},t}();e.CompileEventListener=v,e.collectEventListeners=r,e.bindDirectiveOutputs=i,e.bindRenderOutputs=o},function(t,e,n){"use strict";function r(t,e,n){var r=n.view,i=r.detectChangesInInputsMethod,o=t.directive.lifecycleHooks;-1!==o.indexOf(p.LifecycleHooks.OnChanges)&&t.inputs.length>0&&i.addStmt(new u.IfStmt(c.DetectChangesVars.changes.notIdentical(u.NULL_EXPR),[e.callMethod("ngOnChanges",[c.DetectChangesVars.changes]).toStmt()])),-1!==o.indexOf(p.LifecycleHooks.OnInit)&&i.addStmt(new u.IfStmt(l.and(h),[e.callMethod("ngOnInit",[]).toStmt()])),-1!==o.indexOf(p.LifecycleHooks.DoCheck)&&i.addStmt(new u.IfStmt(h,[e.callMethod("ngDoCheck",[]).toStmt()]))}function i(t,e,n){var r=n.view,i=t.lifecycleHooks,o=r.afterContentLifecycleCallbacksMethod;o.resetDebugInfo(n.nodeIndex,n.sourceAst),-1!==i.indexOf(p.LifecycleHooks.AfterContentInit)&&o.addStmt(new u.IfStmt(l,[e.callMethod("ngAfterContentInit",[]).toStmt()])),-1!==i.indexOf(p.LifecycleHooks.AfterContentChecked)&&o.addStmt(e.callMethod("ngAfterContentChecked",[]).toStmt())}function o(t,e,n){var r=n.view,i=t.lifecycleHooks,o=r.afterViewLifecycleCallbacksMethod;o.resetDebugInfo(n.nodeIndex,n.sourceAst),-1!==i.indexOf(p.LifecycleHooks.AfterViewInit)&&o.addStmt(new u.IfStmt(l,[e.callMethod("ngAfterViewInit",[]).toStmt()])),-1!==i.indexOf(p.LifecycleHooks.AfterViewChecked)&&o.addStmt(e.callMethod("ngAfterViewChecked",[]).toStmt())}function s(t,e,n){var r=n.view.destroyMethod;r.resetDebugInfo(n.nodeIndex,n.sourceAst),-1!==t.lifecycleHooks.indexOf(p.LifecycleHooks.OnDestroy)&&r.addStmt(e.callMethod("ngOnDestroy",[]).toStmt())}function a(t,e,n){var r=n.destroyMethod;-1!==t.lifecycleHooks.indexOf(p.LifecycleHooks.OnDestroy)&&r.addStmt(e.callMethod("ngOnDestroy",[]).toStmt())}var u=n(164),c=n(170),p=n(156),l=u.THIS_EXPR.prop("cdState").identical(c.ChangeDetectorStateEnum.NeverChecked),h=u.not(c.DetectChangesVars.throwOnChange);e.bindDirectiveDetectChangesLifecycleCallbacks=r,e.bindDirectiveAfterContentLifecycleCallbacks=i,e.bindDirectiveAfterViewLifecycleCallbacks=o,e.bindDirectiveDestroyLifecycleCallbacks=s,e.bindPipeDestroyLifecycleCallbacks=a},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(155),s=n(5),a=n(12),u=n(40),c=n(184),p=n(157),l=n(152),h=n(6),f=n(36),d=n(145),v=n(144),y=n(151),m=function(){function t(t,e,n){this._xhr=t,this._urlResolver=e,this._htmlParser=n}return t.prototype.normalizeDirective=function(t){return t.isComponent?this.normalizeTemplate(t.type,t.template).then(function(e){return new o.CompileDirectiveMetadata({type:t.type,isComponent:t.isComponent,selector:t.selector,exportAs:t.exportAs,changeDetection:t.changeDetection,inputs:t.inputs,outputs:t.outputs,hostListeners:t.hostListeners,hostProperties:t.hostProperties,hostAttributes:t.hostAttributes,lifecycleHooks:t.lifecycleHooks,providers:t.providers,viewProviders:t.viewProviders,queries:t.queries,viewQueries:t.viewQueries,template:e})}):u.PromiseWrapper.resolve(t)},t.prototype.normalizeTemplate=function(t,e){var n=this;if(s.isPresent(e.template))return u.PromiseWrapper.resolve(this.normalizeLoadedTemplate(t,e,e.template,t.moduleUrl));if(s.isPresent(e.templateUrl)){var r=this._urlResolver.resolve(t.moduleUrl,e.templateUrl);return this._xhr.get(r).then(function(i){return n.normalizeLoadedTemplate(t,e,i,r)})}throw new a.BaseException("No template specified for component "+t.name)},t.prototype.normalizeLoadedTemplate=function(t,e,n,r){var i=this,s=this._htmlParser.parse(n,t.name);if(s.errors.length>0){var u=s.errors.join("\n");throw new a.BaseException("Template parse errors:\n"+u)}var c=new g;d.htmlVisitAll(c,s.rootNodes);var p=e.styles.concat(c.styles),h=c.styleUrls.filter(l.isStyleUrlResolvable).map(function(t){return i._urlResolver.resolve(r,t)}).concat(e.styleUrls.filter(l.isStyleUrlResolvable).map(function(e){return i._urlResolver.resolve(t.moduleUrl,e)})),v=p.map(function(t){var e=l.extractStyleUrls(i._urlResolver,r,t);return e.styleUrls.forEach(function(t){return h.push(t)}),e.style}),y=e.encapsulation;return y===f.ViewEncapsulation.Emulated&&0===v.length&&0===h.length&&(y=f.ViewEncapsulation.None),new o.CompileTemplateMetadata({encapsulation:y,template:n,templateUrl:r,styles:v,styleUrls:h,ngContentSelectors:c.ngContentSelectors})},t=r([h.Injectable(),i("design:paramtypes",[c.XHR,p.UrlResolver,v.HtmlParser])],t)}();e.DirectiveNormalizer=m;var g=function(){function t(){this.ngContentSelectors=[],this.styles=[],this.styleUrls=[],this.ngNonBindableStackCount=0}return t.prototype.visitElement=function(t,e){var n=y.preparseElement(t);switch(n.type){case y.PreparsedElementType.NG_CONTENT:0===this.ngNonBindableStackCount&&this.ngContentSelectors.push(n.selectAttr);break;case y.PreparsedElementType.STYLE:var r="";t.children.forEach(function(t){t instanceof d.HtmlTextAst&&(r+=t.value)}),this.styles.push(r);break;case y.PreparsedElementType.STYLESHEET:this.styleUrls.push(n.hrefAttr)}return n.nonBindable&&this.ngNonBindableStackCount++,d.htmlVisitAll(this,t.children),n.nonBindable&&this.ngNonBindableStackCount--,null},t.prototype.visitComment=function(t,e){return null},t.prototype.visitAttr=function(t,e){return null},t.prototype.visitText=function(t,e){return null},t.prototype.visitExpansion=function(t,e){return null},t.prototype.visitExpansionCase=function(t,e){return null},t}()},function(t,e){"use strict";var n=function(){function t(){}return t.prototype.get=function(t){return null},t}();e.XHR=n},function(t,e,n){"use strict";function r(t,e){var n=[];return h.isPresent(e)&&o(e,n),h.isPresent(t.directives)&&o(t.directives,n),n}function i(t,e){var n=[];return h.isPresent(e)&&o(e,n),h.isPresent(t.pipes)&&o(t.pipes,n),n}function o(t,e){for(var n=0;n<t.length;n++){var r=l.resolveForwardRef(t[n]);h.isArray(r)?o(r,e):e.push(r)}}function s(t){return h.isPresent(t)&&t instanceof h.Type}function a(t,e,n){var r=n.moduleId;if(h.isPresent(r)){var i=x.getUrlScheme(r);return h.isPresent(i)&&i.length>0?r:"package:"+r+O.MODULE_SUFFIX}return t.importUri(e)}var u=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},c=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},p=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},l=n(6),h=n(5),f=n(15),d=n(12),v=n(23),y=n(155),m=n(26),g=n(4),_=n(186),b=n(187),P=n(188),E=n(189),w=n(156),C=n(18),R=n(6),S=n(84),O=n(153),T=n(190),x=n(157),A=n(24),I=n(17),M=n(7),k=n(4),N=n(20),D=function(){function t(t,e,n,r,i,o){this._directiveResolver=t,this._pipeResolver=e,this._viewResolver=n,this._platformDirectives=r,this._platformPipes=i,this._directiveCache=new Map,this._pipeCache=new Map,this._anonymousTypes=new Map,this._anonymousTypeIndex=0,h.isPresent(o)?this._reflector=o:this._reflector=C.reflector}return t.prototype.sanitizeTokenName=function(t){var e=h.stringify(t);if(e.indexOf("(")>=0){var n=this._anonymousTypes.get(t);h.isBlank(n)&&(this._anonymousTypes.set(t,this._anonymousTypeIndex++),n=this._anonymousTypes.get(t)),e="anonymous_token_"+n+"_"}return O.sanitizeIdentifier(e)},t.prototype.getDirectiveMetadata=function(t){var e=this._directiveCache.get(t);if(h.isBlank(e)){var n=this._directiveResolver.resolve(t),r=null,i=null,o=null,s=[];if(n instanceof m.ComponentMetadata){T.assertArrayOfStrings("styles",n.styles);var u=n;r=a(this._reflector,t,u);var c=this._viewResolver.resolve(t);T.assertArrayOfStrings("styles",c.styles),i=new y.CompileTemplateMetadata({encapsulation:c.encapsulation,template:c.template,templateUrl:c.templateUrl,styles:c.styles,styleUrls:c.styleUrls}),o=u.changeDetection,h.isPresent(n.viewProviders)&&(s=this.getProvidersMetadata(n.viewProviders))}var p=[];h.isPresent(n.providers)&&(p=this.getProvidersMetadata(n.providers));var l=[],f=[];h.isPresent(n.queries)&&(l=this.getQueriesMetadata(n.queries,!1),
                +f=this.getQueriesMetadata(n.queries,!0)),e=y.CompileDirectiveMetadata.create({selector:n.selector,exportAs:n.exportAs,isComponent:h.isPresent(i),type:this.getTypeMetadata(t,r),template:i,changeDetection:o,inputs:n.inputs,outputs:n.outputs,host:n.host,lifecycleHooks:w.LIFECYCLE_HOOKS_VALUES.filter(function(e){return E.hasLifecycleHook(e,t)}),providers:p,viewProviders:s,queries:l,viewQueries:f}),this._directiveCache.set(t,e)}return e},t.prototype.getTypeMetadata=function(t,e){return new y.CompileTypeMetadata({name:this.sanitizeTokenName(t),moduleUrl:e,runtime:t,diDeps:this.getDependenciesMetadata(t,null)})},t.prototype.getFactoryMetadata=function(t,e){return new y.CompileFactoryMetadata({name:this.sanitizeTokenName(t),moduleUrl:e,runtime:t,diDeps:this.getDependenciesMetadata(t,null)})},t.prototype.getPipeMetadata=function(t){var e=this._pipeCache.get(t);if(h.isBlank(e)){var n=this._pipeResolver.resolve(t),r=this._reflector.importUri(t);e=new y.CompilePipeMetadata({type:this.getTypeMetadata(t,r),name:n.name,pure:n.pure,lifecycleHooks:w.LIFECYCLE_HOOKS_VALUES.filter(function(e){return E.hasLifecycleHook(e,t)})}),this._pipeCache.set(t,e)}return e},t.prototype.getViewDirectivesMetadata=function(t){for(var e=this,n=this._viewResolver.resolve(t),i=r(n,this._platformDirectives),o=0;o<i.length;o++)if(!s(i[o]))throw new d.BaseException("Unexpected directive value '"+h.stringify(i[o])+"' on the View of component '"+h.stringify(t)+"'");return i.map(function(t){return e.getDirectiveMetadata(t)})},t.prototype.getViewPipesMetadata=function(t){for(var e=this,n=this._viewResolver.resolve(t),r=i(n,this._platformPipes),o=0;o<r.length;o++)if(!s(r[o]))throw new d.BaseException("Unexpected piped value '"+h.stringify(r[o])+"' on the View of component '"+h.stringify(t)+"'");return r.map(function(t){return e.getPipeMetadata(t)})},t.prototype.getDependenciesMetadata=function(t,e){var n,r=this;try{n=I.constructDependencies(t,e)}catch(i){if(!(i instanceof v.NoAnnotationError))throw i;n=[]}return n.map(function(t){var e,n=t.properties.find(function(t){return t instanceof k.AttributeMetadata}),i=!1;h.isPresent(n)?(e=r.getTokenMetadata(n.attributeName),i=!0):e=r.getTokenMetadata(t.key.token);var o=null,s=t.properties.find(function(t){return t instanceof g.QueryMetadata});return h.isPresent(s)&&(o=r.getQueryMetadata(s,null)),new y.CompileDiDependencyMetadata({isAttribute:i,isHost:t.upperBoundVisibility instanceof M.HostMetadata,isSelf:t.upperBoundVisibility instanceof M.SelfMetadata,isSkipSelf:t.lowerBoundVisibility instanceof M.SkipSelfMetadata,isOptional:t.optional,query:h.isPresent(s)&&!s.isViewQuery?o:null,viewQuery:h.isPresent(s)&&s.isViewQuery?o:null,token:e})})},t.prototype.getTokenMetadata=function(t){t=l.resolveForwardRef(t);var e;return e=h.isString(t)?new y.CompileTokenMetadata({value:t}):new y.CompileTokenMetadata({identifier:new y.CompileIdentifierMetadata({runtime:t,name:this.sanitizeTokenName(t)})})},t.prototype.getProvidersMetadata=function(t){var e=this;return t.map(function(t){return t=l.resolveForwardRef(t),h.isArray(t)?e.getProvidersMetadata(t):t instanceof A.Provider?e.getProviderMetadata(t):e.getTypeMetadata(t,null)})},t.prototype.getProviderMetadata=function(t){var e;return h.isPresent(t.useClass)?e=this.getDependenciesMetadata(t.useClass,t.dependencies):h.isPresent(t.useFactory)&&(e=this.getDependenciesMetadata(t.useFactory,t.dependencies)),new y.CompileProviderMetadata({token:this.getTokenMetadata(t.token),useClass:h.isPresent(t.useClass)?this.getTypeMetadata(t.useClass,null):null,useValue:h.isPresent(t.useValue)?new y.CompileIdentifierMetadata({runtime:t.useValue}):null,useFactory:h.isPresent(t.useFactory)?this.getFactoryMetadata(t.useFactory,null):null,useExisting:h.isPresent(t.useExisting)?this.getTokenMetadata(t.useExisting):null,deps:e,multi:t.multi})},t.prototype.getQueriesMetadata=function(t,e){var n=this,r=[];return f.StringMapWrapper.forEach(t,function(t,i){t.isViewQuery===e&&r.push(n.getQueryMetadata(t,i))}),r},t.prototype.getQueryMetadata=function(t,e){var n,r=this;return n=t.isVarBindingQuery?t.varBindings.map(function(t){return r.getTokenMetadata(t)}):[this.getTokenMetadata(t.selector)],new y.CompileQueryMetadata({selectors:n,first:t.first,descendants:t.descendants,propertyName:e,read:h.isPresent(t.read)?this.getTokenMetadata(t.read):null})},t=u([R.Injectable(),p(3,R.Optional()),p(3,R.Inject(S.PLATFORM_DIRECTIVES)),p(4,R.Optional()),p(4,R.Inject(S.PLATFORM_PIPES)),c("design:paramtypes",[_.DirectiveResolver,b.PipeResolver,P.ViewResolver,Array,Array,N.ReflectorReader])],t)}();e.RuntimeMetadataResolver=D},function(t,e,n){"use strict";function r(t){return t instanceof p.DirectiveMetadata}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(6),a=n(5),u=n(12),c=n(15),p=n(3),l=n(18),h=n(20),f=function(){function t(t){a.isPresent(t)?this._reflector=t:this._reflector=l.reflector}return t.prototype.resolve=function(t){var e=this._reflector.annotations(s.resolveForwardRef(t));if(a.isPresent(e)){var n=e.find(r);if(a.isPresent(n)){var i=this._reflector.propMetadata(t);return this._mergeWithPropertyMetadata(n,i,t)}}throw new u.BaseException("No Directive annotation found on "+a.stringify(t))},t.prototype._mergeWithPropertyMetadata=function(t,e,n){var r=[],i=[],o={},s={};return c.StringMapWrapper.forEach(e,function(t,e){t.forEach(function(t){if(t instanceof p.InputMetadata&&(a.isPresent(t.bindingPropertyName)?r.push(e+": "+t.bindingPropertyName):r.push(e)),t instanceof p.OutputMetadata&&(a.isPresent(t.bindingPropertyName)?i.push(e+": "+t.bindingPropertyName):i.push(e)),t instanceof p.HostBindingMetadata&&(a.isPresent(t.hostPropertyName)?o["["+t.hostPropertyName+"]"]=e:o["["+e+"]"]=e),t instanceof p.HostListenerMetadata){var n=a.isPresent(t.args)?t.args.join(", "):"";o["("+t.eventName+")"]=e+"("+n+")"}t instanceof p.ContentChildrenMetadata&&(s[e]=t),t instanceof p.ViewChildrenMetadata&&(s[e]=t),t instanceof p.ContentChildMetadata&&(s[e]=t),t instanceof p.ViewChildMetadata&&(s[e]=t)})}),this._merge(t,r,i,o,s,n)},t.prototype._merge=function(t,e,n,r,i,o){var s,l=a.isPresent(t.inputs)?c.ListWrapper.concat(t.inputs,e):e;a.isPresent(t.outputs)?(t.outputs.forEach(function(t){if(c.ListWrapper.contains(n,t))throw new u.BaseException("Output event '"+t+"' defined multiple times in '"+a.stringify(o)+"'")}),s=c.ListWrapper.concat(t.outputs,n)):s=n;var h=a.isPresent(t.host)?c.StringMapWrapper.merge(t.host,r):r,f=a.isPresent(t.queries)?c.StringMapWrapper.merge(t.queries,i):i;return t instanceof p.ComponentMetadata?new p.ComponentMetadata({selector:t.selector,inputs:l,outputs:s,host:h,exportAs:t.exportAs,moduleId:t.moduleId,queries:f,changeDetection:t.changeDetection,providers:t.providers,viewProviders:t.viewProviders}):new p.DirectiveMetadata({selector:t.selector,inputs:l,outputs:s,host:h,exportAs:t.exportAs,queries:f,providers:t.providers})},t=i([s.Injectable(),o("design:paramtypes",[h.ReflectorReader])],t)}();e.DirectiveResolver=f,e.CODEGEN_DIRECTIVE_RESOLVER=new f(l.reflector)},function(t,e,n){"use strict";function r(t){return t instanceof c.PipeMetadata}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(6),a=n(5),u=n(12),c=n(3),p=n(20),l=n(18),h=function(){function t(t){a.isPresent(t)?this._reflector=t:this._reflector=l.reflector}return t.prototype.resolve=function(t){var e=this._reflector.annotations(s.resolveForwardRef(t));if(a.isPresent(e)){var n=e.find(r);if(a.isPresent(n))return n}throw new u.BaseException("No Pipe decorator found on "+a.stringify(t))},t=i([s.Injectable(),o("design:paramtypes",[p.ReflectorReader])],t)}();e.PipeResolver=h,e.CODEGEN_PIPE_RESOLVER=new h(l.reflector)},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(6),s=n(36),a=n(26),u=n(5),c=n(12),p=n(15),l=n(20),h=n(18),f=function(){function t(t){this._cache=new p.Map,u.isPresent(t)?this._reflector=t:this._reflector=h.reflector}return t.prototype.resolve=function(t){var e=this._cache.get(t);return u.isBlank(e)&&(e=this._resolve(t),this._cache.set(t,e)),e},t.prototype._resolve=function(t){var e,n;if(this._reflector.annotations(t).forEach(function(t){t instanceof s.ViewMetadata&&(n=t),t instanceof a.ComponentMetadata&&(e=t)}),!u.isPresent(e)){if(u.isBlank(n))throw new c.BaseException("Could not compile '"+u.stringify(t)+"' because it is not a component.");return n}if(u.isBlank(e.template)&&u.isBlank(e.templateUrl)&&u.isBlank(n))throw new c.BaseException("Component '"+u.stringify(t)+"' must have either 'template' or 'templateUrl' set.");if(u.isPresent(e.template)&&u.isPresent(n))this._throwMixingViewAndComponent("template",t);else if(u.isPresent(e.templateUrl)&&u.isPresent(n))this._throwMixingViewAndComponent("templateUrl",t);else if(u.isPresent(e.directives)&&u.isPresent(n))this._throwMixingViewAndComponent("directives",t);else if(u.isPresent(e.pipes)&&u.isPresent(n))this._throwMixingViewAndComponent("pipes",t);else if(u.isPresent(e.encapsulation)&&u.isPresent(n))this._throwMixingViewAndComponent("encapsulation",t);else if(u.isPresent(e.styles)&&u.isPresent(n))this._throwMixingViewAndComponent("styles",t);else{if(!u.isPresent(e.styleUrls)||!u.isPresent(n))return u.isPresent(n)?n:new s.ViewMetadata({templateUrl:e.templateUrl,template:e.template,directives:e.directives,pipes:e.pipes,encapsulation:e.encapsulation,styles:e.styles,styleUrls:e.styleUrls});this._throwMixingViewAndComponent("styleUrls",t)}return null},t.prototype._throwMixingViewAndComponent=function(t,e){throw new c.BaseException("Component '"+u.stringify(e)+"' cannot have both '"+t+"' and '@View' set at the same time\"")},t=r([o.Injectable(),i("design:paramtypes",[l.ReflectorReader])],t)}();e.ViewResolver=f},function(t,e,n){"use strict";function r(t,e){if(!(e instanceof i.Type))return!1;var n=e.prototype;switch(t){case o.LifecycleHooks.AfterContentInit:return!!n.ngAfterContentInit;case o.LifecycleHooks.AfterContentChecked:return!!n.ngAfterContentChecked;case o.LifecycleHooks.AfterViewInit:return!!n.ngAfterViewInit;case o.LifecycleHooks.AfterViewChecked:return!!n.ngAfterViewChecked;case o.LifecycleHooks.OnChanges:return!!n.ngOnChanges;case o.LifecycleHooks.DoCheck:return!!n.ngDoCheck;case o.LifecycleHooks.OnDestroy:return!!n.ngOnDestroy;case o.LifecycleHooks.OnInit:return!!n.ngOnInit;default:return!1}}var i=n(5),o=n(156);e.hasLifecycleHook=r},function(t,e,n){"use strict";function r(t,e){if(i.assertionsEnabled()&&!i.isBlank(e)){if(!i.isArray(e))throw new o.BaseException("Expected '"+t+"' to be an array of strings.");for(var n=0;n<e.length;n+=1)if(!i.isString(e[n]))throw new o.BaseException("Expected '"+t+"' to be an array of strings.")}}var i=n(5),o=n(12);e.assertArrayOfStrings=r},function(t,e,n){"use strict";function r(t,e,n){var r=new c,i=s.EmitterVisitorContext.createRoot([n]);return r.visitAllStatements(e,i),o.evalExpression(t,n,i.toSource(),r.getArgs())}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=n(5),s=n(192),a=n(193),u=n(153);e.jitStatements=r;var c=function(t){function e(){t.apply(this,arguments),this._evalArgNames=[],this._evalArgValues=[]}return i(e,t),e.prototype.getArgs=function(){for(var t={},e=0;e<this._evalArgNames.length;e++)t[this._evalArgNames[e]]=this._evalArgValues[e];return t},e.prototype.visitExternalExpr=function(t,e){var n=t.value.runtime,r=this._evalArgValues.indexOf(n);if(-1===r){r=this._evalArgValues.length,this._evalArgValues.push(n);var i=o.isPresent(t.value.name)?u.sanitizeIdentifier(t.value.name):"val";this._evalArgNames.push(u.sanitizeIdentifier("jit_"+i+r))}return e.print(this._evalArgNames[r]),null},e}(a.AbstractJsEmitterVisitor)},function(t,e,n){"use strict";function r(t,e){if(o.isBlank(t))return null;var n=o.StringWrapper.replaceAllMapped(t,u,function(t){return"$"==t[0]?e?"\\$":"$":"\n"==t[0]?"\\n":"\r"==t[0]?"\\r":"\\"+t[0]});return"'"+n+"'"}function i(t){for(var e="",n=0;t>n;n++)e+="  ";return e}var o=n(5),s=n(12),a=n(164),u=/'|\\|\n|\r|\$/g;e.CATCH_ERROR_VAR=a.variable("error"),e.CATCH_STACK_VAR=a.variable("stack");var c=function(){function t(){}return t}();e.OutputEmitter=c;var p=function(){function t(t){this.indent=t,this.parts=[]}return t}(),l=function(){function t(t,e){this._exportedVars=t,this._indent=e,this._classes=[],this._lines=[new p(e)]}return t.createRoot=function(e){return new t(e,0)},Object.defineProperty(t.prototype,"_currentLine",{get:function(){return this._lines[this._lines.length-1]},enumerable:!0,configurable:!0}),t.prototype.isExportedVar=function(t){return-1!==this._exportedVars.indexOf(t)},t.prototype.println=function(t){void 0===t&&(t=""),this.print(t,!0)},t.prototype.lineIsEmpty=function(){return 0===this._currentLine.parts.length},t.prototype.print=function(t,e){void 0===e&&(e=!1),t.length>0&&this._currentLine.parts.push(t),e&&this._lines.push(new p(this._indent))},t.prototype.removeEmptyLastLine=function(){this.lineIsEmpty()&&this._lines.pop()},t.prototype.incIndent=function(){this._indent++,this._currentLine.indent=this._indent},t.prototype.decIndent=function(){this._indent--,this._currentLine.indent=this._indent},t.prototype.pushClass=function(t){this._classes.push(t)},t.prototype.popClass=function(){return this._classes.pop()},Object.defineProperty(t.prototype,"currentClass",{get:function(){return this._classes.length>0?this._classes[this._classes.length-1]:null},enumerable:!0,configurable:!0}),t.prototype.toSource=function(){var t=this._lines;return 0===t[t.length-1].parts.length&&(t=t.slice(0,t.length-1)),t.map(function(t){return t.parts.length>0?i(t.indent)+t.parts.join(""):""}).join("\n")},t}();e.EmitterVisitorContext=l;var h=function(){function t(t){this._escapeDollarInStrings=t}return t.prototype.visitExpressionStmt=function(t,e){return t.expr.visitExpression(this,e),e.println(";"),null},t.prototype.visitReturnStmt=function(t,e){return e.print("return "),t.value.visitExpression(this,e),e.println(";"),null},t.prototype.visitIfStmt=function(t,e){e.print("if ("),t.condition.visitExpression(this,e),e.print(") {");var n=o.isPresent(t.falseCase)&&t.falseCase.length>0;return t.trueCase.length<=1&&!n?(e.print(" "),this.visitAllStatements(t.trueCase,e),e.removeEmptyLastLine(),e.print(" ")):(e.println(),e.incIndent(),this.visitAllStatements(t.trueCase,e),e.decIndent(),n&&(e.println("} else {"),e.incIndent(),this.visitAllStatements(t.falseCase,e),e.decIndent())),e.println("}"),null},t.prototype.visitThrowStmt=function(t,e){return e.print("throw "),t.error.visitExpression(this,e),e.println(";"),null},t.prototype.visitCommentStmt=function(t,e){var n=t.comment.split("\n");return n.forEach(function(t){e.println("// "+t)}),null},t.prototype.visitWriteVarExpr=function(t,e){var n=e.lineIsEmpty();return n||e.print("("),e.print(t.name+" = "),t.value.visitExpression(this,e),n||e.print(")"),null},t.prototype.visitWriteKeyExpr=function(t,e){var n=e.lineIsEmpty();return n||e.print("("),t.receiver.visitExpression(this,e),e.print("["),t.index.visitExpression(this,e),e.print("] = "),t.value.visitExpression(this,e),n||e.print(")"),null},t.prototype.visitWritePropExpr=function(t,e){var n=e.lineIsEmpty();return n||e.print("("),t.receiver.visitExpression(this,e),e.print("."+t.name+" = "),t.value.visitExpression(this,e),n||e.print(")"),null},t.prototype.visitInvokeMethodExpr=function(t,e){t.receiver.visitExpression(this,e);var n=t.name;return o.isPresent(t.builtin)&&(n=this.getBuiltinMethodName(t.builtin),o.isBlank(n))?null:(e.print("."+n+"("),this.visitAllExpressions(t.args,e,","),e.print(")"),null)},t.prototype.visitInvokeFunctionExpr=function(t,e){return t.fn.visitExpression(this,e),e.print("("),this.visitAllExpressions(t.args,e,","),e.print(")"),null},t.prototype.visitReadVarExpr=function(t,n){var r=t.name;if(o.isPresent(t.builtin))switch(t.builtin){case a.BuiltinVar.Super:r="super";break;case a.BuiltinVar.This:r="this";break;case a.BuiltinVar.CatchError:r=e.CATCH_ERROR_VAR.name;break;case a.BuiltinVar.CatchStack:r=e.CATCH_STACK_VAR.name;break;default:throw new s.BaseException("Unknown builtin variable "+t.builtin)}return n.print(r),null},t.prototype.visitInstantiateExpr=function(t,e){return e.print("new "),t.classExpr.visitExpression(this,e),e.print("("),this.visitAllExpressions(t.args,e,","),e.print(")"),null},t.prototype.visitLiteralExpr=function(t,e){var n=t.value;return o.isString(n)?e.print(r(n,this._escapeDollarInStrings)):o.isBlank(n)?e.print("null"):e.print(""+n),null},t.prototype.visitConditionalExpr=function(t,e){return t.condition.visitExpression(this,e),e.print("? "),t.trueCase.visitExpression(this,e),e.print(": "),t.falseCase.visitExpression(this,e),null},t.prototype.visitNotExpr=function(t,e){return e.print("!"),t.condition.visitExpression(this,e),null},t.prototype.visitBinaryOperatorExpr=function(t,e){var n;switch(t.operator){case a.BinaryOperator.Equals:n="==";break;case a.BinaryOperator.Identical:n="===";break;case a.BinaryOperator.NotEquals:n="!=";break;case a.BinaryOperator.NotIdentical:n="!==";break;case a.BinaryOperator.And:n="&&";break;case a.BinaryOperator.Or:n="||";break;case a.BinaryOperator.Plus:n="+";break;case a.BinaryOperator.Minus:n="-";break;case a.BinaryOperator.Divide:n="/";break;case a.BinaryOperator.Multiply:n="*";break;case a.BinaryOperator.Modulo:n="%";break;case a.BinaryOperator.Lower:n="<";break;case a.BinaryOperator.LowerEquals:n="<=";break;case a.BinaryOperator.Bigger:n=">";break;case a.BinaryOperator.BiggerEquals:n=">=";break;default:throw new s.BaseException("Unknown operator "+t.operator)}return e.print("("),t.lhs.visitExpression(this,e),e.print(" "+n+" "),t.rhs.visitExpression(this,e),e.print(")"),null},t.prototype.visitReadPropExpr=function(t,e){return t.receiver.visitExpression(this,e),e.print("."),e.print(t.name),null},t.prototype.visitReadKeyExpr=function(t,e){return t.receiver.visitExpression(this,e),e.print("["),t.index.visitExpression(this,e),e.print("]"),null},t.prototype.visitLiteralArrayExpr=function(t,e){var n=t.entries.length>1;return e.print("[",n),e.incIndent(),this.visitAllExpressions(t.entries,e,",",n),e.decIndent(),e.print("]",n),null},t.prototype.visitLiteralMapExpr=function(t,e){var n=this,i=t.entries.length>1;return e.print("{",i),e.incIndent(),this.visitAllObjects(function(t){e.print(r(t[0],n._escapeDollarInStrings)+": "),t[1].visitExpression(n,e)},t.entries,e,",",i),e.decIndent(),e.print("}",i),null},t.prototype.visitAllExpressions=function(t,e,n,r){var i=this;void 0===r&&(r=!1),this.visitAllObjects(function(t){return t.visitExpression(i,e)},t,e,n,r)},t.prototype.visitAllObjects=function(t,e,n,r,i){void 0===i&&(i=!1);for(var o=0;o<e.length;o++)o>0&&n.print(r,i),t(e[o]);i&&n.println()},t.prototype.visitAllStatements=function(t,e){var n=this;t.forEach(function(t){return t.visitStatement(n,e)})},t}();e.AbstractEmitterVisitor=h,e.escapeSingleQuoteString=r},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(12),s=n(164),a=n(192),u=function(t){function e(){t.call(this,!1)}return r(e,t),e.prototype.visitDeclareClassStmt=function(t,e){var n=this;return e.pushClass(t),this._visitClassConstructor(t,e),i.isPresent(t.parent)&&(e.print(t.name+".prototype = Object.create("),t.parent.visitExpression(this,e),e.println(".prototype);")),t.getters.forEach(function(r){return n._visitClassGetter(t,r,e)}),t.methods.forEach(function(r){return n._visitClassMethod(t,r,e)}),e.popClass(),null},e.prototype._visitClassConstructor=function(t,e){e.print("function "+t.name+"("),i.isPresent(t.constructorMethod)&&this._visitParams(t.constructorMethod.params,e),e.println(") {"),e.incIndent(),i.isPresent(t.constructorMethod)&&t.constructorMethod.body.length>0&&(e.println("var self = this;"),this.visitAllStatements(t.constructorMethod.body,e)),e.decIndent(),e.println("}")},e.prototype._visitClassGetter=function(t,e,n){n.println("Object.defineProperty("+t.name+".prototype, '"+e.name+"', { get: function() {"),n.incIndent(),e.body.length>0&&(n.println("var self = this;"),this.visitAllStatements(e.body,n)),n.decIndent(),n.println("}});")},e.prototype._visitClassMethod=function(t,e,n){n.print(t.name+".prototype."+e.name+" = function("),this._visitParams(e.params,n),n.println(") {"),n.incIndent(),e.body.length>0&&(n.println("var self = this;"),this.visitAllStatements(e.body,n)),n.decIndent(),n.println("};")},e.prototype.visitReadVarExpr=function(e,n){if(e.builtin===s.BuiltinVar.This)n.print("self");else{if(e.builtin===s.BuiltinVar.Super)throw new o.BaseException("'super' needs to be handled at a parent ast node, not at the variable level!");t.prototype.visitReadVarExpr.call(this,e,n)}return null},e.prototype.visitDeclareVarStmt=function(t,e){return e.print("var "+t.name+" = "),t.value.visitExpression(this,e),e.println(";"),null},e.prototype.visitCastExpr=function(t,e){return t.value.visitExpression(this,e),null},e.prototype.visitInvokeFunctionExpr=function(e,n){var r=e.fn;return r instanceof s.ReadVarExpr&&r.builtin===s.BuiltinVar.Super?(n.currentClass.parent.visitExpression(this,n),n.print(".call(this"),e.args.length>0&&(n.print(", "),this.visitAllExpressions(e.args,n,",")),n.print(")")):t.prototype.visitInvokeFunctionExpr.call(this,e,n),null},e.prototype.visitFunctionExpr=function(t,e){return e.print("function("),this._visitParams(t.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.print("}"),null},e.prototype.visitDeclareFunctionStmt=function(t,e){return e.print("function "+t.name+"("),this._visitParams(t.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.println("}"),null},e.prototype.visitTryCatchStmt=function(t,e){e.println("try {"),e.incIndent(),this.visitAllStatements(t.bodyStmts,e),e.decIndent(),e.println("} catch ("+a.CATCH_ERROR_VAR.name+") {"),e.incIndent();var n=[a.CATCH_STACK_VAR.set(a.CATCH_ERROR_VAR.prop("stack")).toDeclStmt(null,[s.StmtModifier.Final])].concat(t.catchStmts);return this.visitAllStatements(n,e),e.decIndent(),e.println("}"),null},e.prototype._visitParams=function(t,e){this.visitAllObjects(function(t){return e.print(t.name)},t,e,",")},e.prototype.getBuiltinMethodName=function(t){var e;switch(t){case s.BuiltinMethod.ConcatArray:e="concat";break;case s.BuiltinMethod.SubscribeObservable:e="subscribe";break;case s.BuiltinMethod.bind:e="bind";break;default:throw new o.BaseException("Unknown builtin method: "+t)}return e},e}(a.AbstractEmitterVisitor);e.AbstractJsEmitterVisitor=u},function(t,e,n){"use strict";function r(t,e,n){var r=t.concat([new c.ReturnStatement(c.variable(e))]),i=new y(null,null,null,null,new Map,new Map,new Map,new Map,n),o=new _,s=o.visitAllStatements(r,i);return a.isPresent(s)?s.value:null}function i(t){return a.IS_DART?t instanceof v:a.isPresent(t)&&a.isPresent(t.props)&&a.isPresent(t.getters)&&a.isPresent(t.methods)}function o(t,e,n,r,i){for(var o=r.createChildWihtLocalVars(),s=0;s<t.length;s++)o.vars.set(t[s],e[s]);var u=i.visitAllStatements(n,o);return a.isPresent(u)?u.value:null}function s(t,e,n,r){switch(t.length){case 0:return function(){return o(t,[],e,n,r)};case 1:return function(i){return o(t,[i],e,n,r)};case 2:return function(i,s){return o(t,[i,s],e,n,r)};case 3:return function(i,s,a){return o(t,[i,s,a],e,n,r)};case 4:return function(i,s,a,u){return o(t,[i,s,a,u],e,n,r)};case 5:return function(i,s,a,u,c){return o(t,[i,s,a,u,c],e,n,r)};case 6:return function(i,s,a,u,c,p){return o(t,[i,s,a,u,c,p],e,n,r)};case 7:return function(i,s,a,u,c,p,l){return o(t,[i,s,a,u,c,p,l],e,n,r)};case 8:return function(i,s,a,u,c,p,l,h){return o(t,[i,s,a,u,c,p,l,h],e,n,r)};case 9:return function(i,s,a,u,c,p,l,h,f){return o(t,[i,s,a,u,c,p,l,h,f],e,n,r)};case 10:return function(i,s,a,u,c,p,l,h,f,d){return o(t,[i,s,a,u,c,p,l,h,f,d],e,n,r)};default:throw new l.BaseException("Declaring functions with more than 10 arguments is not supported right now")}}var a=n(5),u=n(40),c=n(164),p=n(18),l=n(12),h=n(15),f=n(195),d=n(197);e.interpretStatements=r;var v=function(){function t(){}return Object.defineProperty(t.prototype,"props",{get:function(){return l.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"getters",{get:function(){return l.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"methods",{get:function(){return l.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"clazz",{get:function(){return l.unimplemented()},enumerable:!0,configurable:!0}),t}();e.DynamicInstance=v;var y=function(){function t(t,e,n,r,i,o,s,a,u){this.parent=t,this.superClass=e,this.superInstance=n,this.className=r,this.vars=i,this.props=o,this.getters=s,this.methods=a,this.instanceFactory=u}return t.prototype.createChildWihtLocalVars=function(){return new t(this,this.superClass,this.superInstance,this.className,new Map,this.props,this.getters,this.methods,this.instanceFactory)},t}(),m=function(){function t(t){this.value=t}return t}(),g=function(){function t(t,e,n){this._classStmt=t,this._ctx=e,this._visitor=n}return t.prototype.instantiate=function(t){var e=this,n=new Map,r=new Map,i=new Map,a=this._classStmt.parent.visitExpression(this._visitor,this._ctx),u=new y(this._ctx,a,null,this._classStmt.name,this._ctx.vars,n,r,i,this._ctx.instanceFactory);this._classStmt.fields.forEach(function(t){n.set(t.name,null)}),this._classStmt.getters.forEach(function(t){r.set(t.name,function(){return o([],[],t.body,u,e._visitor)})}),this._classStmt.methods.forEach(function(t){var n=t.params.map(function(t){return t.name});i.set(t.name,s(n,t.body,u,e._visitor))});var c=this._classStmt.constructorMethod.params.map(function(t){return t.name});return o(c,t,this._classStmt.constructorMethod.body,u,this._visitor),u.superInstance},t.prototype.debugAst=function(){return this._visitor.debugAst(this._classStmt)},t}(),_=function(){function t(){}return t.prototype.debugAst=function(t){return a.IS_DART?f.debugOutputAstAsDart(t):d.debugOutputAstAsTypeScript(t)},t.prototype.visitDeclareVarStmt=function(t,e){return e.vars.set(t.name,t.value.visitExpression(this,e)),null},t.prototype.visitWriteVarExpr=function(t,e){for(var n=t.value.visitExpression(this,e),r=e;null!=r;){if(r.vars.has(t.name))return r.vars.set(t.name,n),n;r=r.parent}throw new l.BaseException("Not declared variable "+t.name)},t.prototype.visitReadVarExpr=function(t,e){var n=t.name;if(a.isPresent(t.builtin))switch(t.builtin){case c.BuiltinVar.Super:case c.BuiltinVar.This:return e.superInstance;case c.BuiltinVar.CatchError:n=b;break;case c.BuiltinVar.CatchStack:n=P;break;default:throw new l.BaseException("Unknown builtin variable "+t.builtin)}for(var r=e;null!=r;){if(r.vars.has(n))return r.vars.get(n);r=r.parent}throw new l.BaseException("Not declared variable "+n)},t.prototype.visitWriteKeyExpr=function(t,e){var n=t.receiver.visitExpression(this,e),r=t.index.visitExpression(this,e),i=t.value.visitExpression(this,e);return n[r]=i,i},t.prototype.visitWritePropExpr=function(t,e){var n=t.receiver.visitExpression(this,e),r=t.value.visitExpression(this,e);if(i(n)){var o=n;o.props.has(t.name)?o.props.set(t.name,r):p.reflector.setter(t.name)(n,r)}else p.reflector.setter(t.name)(n,r);return r},t.prototype.visitInvokeMethodExpr=function(t,e){var n,r=t.receiver.visitExpression(this,e),o=this.visitAllExpressions(t.args,e);if(a.isPresent(t.builtin))switch(t.builtin){case c.BuiltinMethod.ConcatArray:n=h.ListWrapper.concat(r,o[0]);break;case c.BuiltinMethod.SubscribeObservable:n=u.ObservableWrapper.subscribe(r,o[0]);break;case c.BuiltinMethod.bind:n=a.IS_DART?r:r.bind(o[0]);break;default:throw new l.BaseException("Unknown builtin method "+t.builtin)}else if(i(r)){var s=r;n=s.methods.has(t.name)?a.FunctionWrapper.apply(s.methods.get(t.name),o):p.reflector.method(t.name)(r,o)}else n=p.reflector.method(t.name)(r,o);return n},t.prototype.visitInvokeFunctionExpr=function(t,e){var n=this.visitAllExpressions(t.args,e),r=t.fn;if(r instanceof c.ReadVarExpr&&r.builtin===c.BuiltinVar.Super)return e.superInstance=e.instanceFactory.createInstance(e.superClass,e.className,n,e.props,e.getters,e.methods),e.parent.superInstance=e.superInstance,null;var i=t.fn.visitExpression(this,e);return a.FunctionWrapper.apply(i,n)},t.prototype.visitReturnStmt=function(t,e){return new m(t.value.visitExpression(this,e))},t.prototype.visitDeclareClassStmt=function(t,e){var n=new g(t,e,this);return e.vars.set(t.name,n),null},t.prototype.visitExpressionStmt=function(t,e){return t.expr.visitExpression(this,e)},t.prototype.visitIfStmt=function(t,e){var n=t.condition.visitExpression(this,e);return n?this.visitAllStatements(t.trueCase,e):a.isPresent(t.falseCase)?this.visitAllStatements(t.falseCase,e):null},t.prototype.visitTryCatchStmt=function(t,e){try{return this.visitAllStatements(t.bodyStmts,e)}catch(n){var r=e.createChildWihtLocalVars();return r.vars.set(b,n),r.vars.set(P,n.stack),this.visitAllStatements(t.catchStmts,r)}},t.prototype.visitThrowStmt=function(t,e){throw t.error.visitExpression(this,e)},t.prototype.visitCommentStmt=function(t,e){return null},t.prototype.visitInstantiateExpr=function(t,e){var n=this.visitAllExpressions(t.args,e),r=t.classExpr.visitExpression(this,e);return r instanceof g?r.instantiate(n):a.FunctionWrapper.apply(p.reflector.factory(r),n)},t.prototype.visitLiteralExpr=function(t,e){return t.value},t.prototype.visitExternalExpr=function(t,e){return t.value.runtime},t.prototype.visitConditionalExpr=function(t,e){return t.condition.visitExpression(this,e)?t.trueCase.visitExpression(this,e):a.isPresent(t.falseCase)?t.falseCase.visitExpression(this,e):null},t.prototype.visitNotExpr=function(t,e){return!t.condition.visitExpression(this,e)},t.prototype.visitCastExpr=function(t,e){return t.value.visitExpression(this,e)},t.prototype.visitFunctionExpr=function(t,e){var n=t.params.map(function(t){return t.name});return s(n,t.statements,e,this)},t.prototype.visitDeclareFunctionStmt=function(t,e){var n=t.params.map(function(t){return t.name});return e.vars.set(t.name,s(n,t.statements,e,this)),null},t.prototype.visitBinaryOperatorExpr=function(t,e){var n=this,r=function(){return t.lhs.visitExpression(n,e)},i=function(){return t.rhs.visitExpression(n,e)};switch(t.operator){case c.BinaryOperator.Equals:return r()==i();case c.BinaryOperator.Identical:return r()===i();case c.BinaryOperator.NotEquals:return r()!=i();case c.BinaryOperator.NotIdentical:return r()!==i();case c.BinaryOperator.And:return r()&&i();case c.BinaryOperator.Or:return r()||i();case c.BinaryOperator.Plus:return r()+i();case c.BinaryOperator.Minus:return r()-i();case c.BinaryOperator.Divide:return r()/i();
                +case c.BinaryOperator.Multiply:return r()*i();case c.BinaryOperator.Modulo:return r()%i();case c.BinaryOperator.Lower:return r()<i();case c.BinaryOperator.LowerEquals:return r()<=i();case c.BinaryOperator.Bigger:return r()>i();case c.BinaryOperator.BiggerEquals:return r()>=i();default:throw new l.BaseException("Unknown operator "+t.operator)}},t.prototype.visitReadPropExpr=function(t,e){var n,r=t.receiver.visitExpression(this,e);if(i(r)){var o=r;n=o.props.has(t.name)?o.props.get(t.name):o.getters.has(t.name)?o.getters.get(t.name)():o.methods.has(t.name)?o.methods.get(t.name):p.reflector.getter(t.name)(r)}else n=p.reflector.getter(t.name)(r);return n},t.prototype.visitReadKeyExpr=function(t,e){var n=t.receiver.visitExpression(this,e),r=t.index.visitExpression(this,e);return n[r]},t.prototype.visitLiteralArrayExpr=function(t,e){return this.visitAllExpressions(t.entries,e)},t.prototype.visitLiteralMapExpr=function(t,e){var n=this,r={};return t.entries.forEach(function(t){return r[t[0]]=t[1].visitExpression(n,e)}),r},t.prototype.visitAllExpressions=function(t,e){var n=this;return t.map(function(t){return t.visitExpression(n,e)})},t.prototype.visitAllStatements=function(t,e){for(var n=0;n<t.length;n++){var r=t[n],i=r.visitStatement(this,e);if(i instanceof m)return i}return null},t}(),b="error",P="stack"},function(t,e,n){"use strict";function r(t){var e,n=new d(h),r=p.EmitterVisitorContext.createRoot([]);return e=a.isArray(t)?t:[t],e.forEach(function(t){if(t instanceof c.Statement)t.visitStatement(n,r);else if(t instanceof c.Expression)t.visitExpression(n,r);else{if(!(t instanceof c.Type))throw new u.BaseException("Don't know how to print debug info for "+t);t.visitType(n,r)}}),r.toSource()}function i(t){if(t instanceof c.ExpressionStatement){var e=t.expr;if(e instanceof c.InvokeFunctionExpr){var n=e.fn;if(n instanceof c.ReadVarExpr&&n.builtin===c.BuiltinVar.Super)return e}}return null}function o(t){return a.isPresent(t)&&t.hasModifier(c.TypeModifier.Const)}var s=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},a=n(5),u=n(12),c=n(164),p=n(192),l=n(196),h="asset://debug/lib";e.debugOutputAstAsDart=r;var f=function(){function t(){}return t.prototype.emitStatements=function(t,e,n){var r=[],i=new d(t),o=p.EmitterVisitorContext.createRoot(n);return i.visitAllStatements(e,o),i.importsWithPrefixes.forEach(function(e,n){r.push("import '"+l.getImportModulePath(t,n,l.ImportEnv.Dart)+"' as "+e+";")}),r.push(o.toSource()),r.join("\n")},t}();e.DartEmitter=f;var d=function(t){function e(e){t.call(this,!0),this._moduleUrl=e,this.importsWithPrefixes=new Map}return s(e,t),e.prototype.visitExternalExpr=function(t,e){return this._visitIdentifier(t.value,t.typeParams,e),null},e.prototype.visitDeclareVarStmt=function(t,e){return t.hasModifier(c.StmtModifier.Final)?o(t.type)?e.print("const "):e.print("final "):a.isBlank(t.type)&&e.print("var "),a.isPresent(t.type)&&(t.type.visitType(this,e),e.print(" ")),e.print(t.name+" = "),t.value.visitExpression(this,e),e.println(";"),null},e.prototype.visitCastExpr=function(t,e){return e.print("("),t.value.visitExpression(this,e),e.print(" as "),t.type.visitType(this,e),e.print(")"),null},e.prototype.visitDeclareClassStmt=function(t,e){var n=this;return e.pushClass(t),e.print("class "+t.name),a.isPresent(t.parent)&&(e.print(" extends "),t.parent.visitExpression(this,e)),e.println(" {"),e.incIndent(),t.fields.forEach(function(t){return n._visitClassField(t,e)}),a.isPresent(t.constructorMethod)&&this._visitClassConstructor(t,e),t.getters.forEach(function(t){return n._visitClassGetter(t,e)}),t.methods.forEach(function(t){return n._visitClassMethod(t,e)}),e.decIndent(),e.println("}"),e.popClass(),null},e.prototype._visitClassField=function(t,e){t.hasModifier(c.StmtModifier.Final)?e.print("final "):a.isBlank(t.type)&&e.print("var "),a.isPresent(t.type)&&(t.type.visitType(this,e),e.print(" ")),e.println(t.name+";")},e.prototype._visitClassGetter=function(t,e){a.isPresent(t.type)&&(t.type.visitType(this,e),e.print(" ")),e.println("get "+t.name+" {"),e.incIndent(),this.visitAllStatements(t.body,e),e.decIndent(),e.println("}")},e.prototype._visitClassConstructor=function(t,e){e.print(t.name+"("),this._visitParams(t.constructorMethod.params,e),e.print(")");var n=t.constructorMethod.body,r=n.length>0?i(n[0]):null;a.isPresent(r)&&(e.print(": "),r.visitExpression(this,e),n=n.slice(1)),e.println(" {"),e.incIndent(),this.visitAllStatements(n,e),e.decIndent(),e.println("}")},e.prototype._visitClassMethod=function(t,e){a.isPresent(t.type)?t.type.visitType(this,e):e.print("void"),e.print(" "+t.name+"("),this._visitParams(t.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.body,e),e.decIndent(),e.println("}")},e.prototype.visitFunctionExpr=function(t,e){return e.print("("),this._visitParams(t.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.print("}"),null},e.prototype.visitDeclareFunctionStmt=function(t,e){return a.isPresent(t.type)?t.type.visitType(this,e):e.print("void"),e.print(" "+t.name+"("),this._visitParams(t.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.println("}"),null},e.prototype.getBuiltinMethodName=function(t){var e;switch(t){case c.BuiltinMethod.ConcatArray:e=".addAll";break;case c.BuiltinMethod.SubscribeObservable:e="listen";break;case c.BuiltinMethod.bind:e=null;break;default:throw new u.BaseException("Unknown builtin method: "+t)}return e},e.prototype.visitTryCatchStmt=function(t,e){return e.println("try {"),e.incIndent(),this.visitAllStatements(t.bodyStmts,e),e.decIndent(),e.println("} catch ("+p.CATCH_ERROR_VAR.name+", "+p.CATCH_STACK_VAR.name+") {"),e.incIndent(),this.visitAllStatements(t.catchStmts,e),e.decIndent(),e.println("}"),null},e.prototype.visitBinaryOperatorExpr=function(e,n){switch(e.operator){case c.BinaryOperator.Identical:n.print("identical("),e.lhs.visitExpression(this,n),n.print(", "),e.rhs.visitExpression(this,n),n.print(")");break;case c.BinaryOperator.NotIdentical:n.print("!identical("),e.lhs.visitExpression(this,n),n.print(", "),e.rhs.visitExpression(this,n),n.print(")");break;default:t.prototype.visitBinaryOperatorExpr.call(this,e,n)}return null},e.prototype.visitLiteralArrayExpr=function(e,n){return o(e.type)&&n.print("const "),t.prototype.visitLiteralArrayExpr.call(this,e,n)},e.prototype.visitLiteralMapExpr=function(e,n){return o(e.type)&&n.print("const "),a.isPresent(e.valueType)&&(n.print("<String, "),e.valueType.visitType(this,n),n.print(">")),t.prototype.visitLiteralMapExpr.call(this,e,n)},e.prototype.visitInstantiateExpr=function(t,e){return e.print(o(t.type)?"const":"new"),e.print(" "),t.classExpr.visitExpression(this,e),e.print("("),this.visitAllExpressions(t.args,e,","),e.print(")"),null},e.prototype.visitBuiltintType=function(t,e){var n;switch(t.name){case c.BuiltinTypeName.Bool:n="bool";break;case c.BuiltinTypeName.Dynamic:n="dynamic";break;case c.BuiltinTypeName.Function:n="Function";break;case c.BuiltinTypeName.Number:n="num";break;case c.BuiltinTypeName.Int:n="int";break;case c.BuiltinTypeName.String:n="String";break;default:throw new u.BaseException("Unsupported builtin type "+t.name)}return e.print(n),null},e.prototype.visitExternalType=function(t,e){return this._visitIdentifier(t.value,t.typeParams,e),null},e.prototype.visitArrayType=function(t,e){return e.print("List<"),a.isPresent(t.of)?t.of.visitType(this,e):e.print("dynamic"),e.print(">"),null},e.prototype.visitMapType=function(t,e){return e.print("Map<String, "),a.isPresent(t.valueType)?t.valueType.visitType(this,e):e.print("dynamic"),e.print(">"),null},e.prototype._visitParams=function(t,e){var n=this;this.visitAllObjects(function(t){a.isPresent(t.type)&&(t.type.visitType(n,e),e.print(" ")),e.print(t.name)},t,e,",")},e.prototype._visitIdentifier=function(t,e,n){var r=this;if(a.isPresent(t.moduleUrl)&&t.moduleUrl!=this._moduleUrl){var i=this.importsWithPrefixes.get(t.moduleUrl);a.isBlank(i)&&(i="import"+this.importsWithPrefixes.size,this.importsWithPrefixes.set(t.moduleUrl,i)),n.print(i+".")}n.print(t.name),a.isPresent(e)&&e.length>0&&(n.print("<"),this.visitAllObjects(function(t){return t.visitType(r,n)},e,n,","),n.print(">"))},e}(p.AbstractEmitterVisitor)},function(t,e,n){"use strict";function r(t,e,n){var r=n===l.Dart?"package:":"",o=h.parse(t,!1),u=h.parse(e,!0);if(a.isBlank(u))return e;if(o.firstLevelDir==u.firstLevelDir&&o.packageName==u.packageName)return i(o.modulePath,u.modulePath,n);if("lib"==u.firstLevelDir)return""+r+u.packageName+"/"+u.modulePath;throw new s.BaseException("Can't import url "+e+" from "+t)}function i(t,e,n){for(var r=t.split(p),i=e.split(p),s=o(r,i),a=[],u=r.length-1-s,h=0;u>h;h++)a.push("..");0>=u&&n===l.JS&&a.push(".");for(var h=s;h<i.length;h++)a.push(i[h]);return a.join(c)}function o(t,e){for(var n=0,r=a.Math.min(t.length,e.length);r>n&&t[n]==e[n];)n++;return n}var s=n(12),a=n(5),u=/asset:([^\/]+)\/([^\/]+)\/(.+)/g,c="/",p=/\//g;!function(t){t[t.Dart=0]="Dart",t[t.JS=1]="JS"}(e.ImportEnv||(e.ImportEnv={}));var l=e.ImportEnv;e.getImportModulePath=r;var h=function(){function t(t,e,n){this.packageName=t,this.firstLevelDir=e,this.modulePath=n}return t.parse=function(e,n){var r=a.RegExpWrapper.firstMatch(u,e);if(a.isPresent(r))return new t(r[1],r[2],r[3]);if(n)return null;throw new s.BaseException("Url "+e+" is not a valid asset: url")},t}();e.getRelativePath=i,e.getLongestPathSegmentPrefix=o},function(t,e,n){"use strict";function r(t){var e,n=new h(p),r=u.EmitterVisitorContext.createRoot([]);return e=s.isArray(t)?t:[t],e.forEach(function(t){if(t instanceof o.Statement)t.visitStatement(n,r);else if(t instanceof o.Expression)t.visitExpression(n,r);else{if(!(t instanceof o.Type))throw new a.BaseException("Don't know how to print debug info for "+t);t.visitType(n,r)}}),r.toSource()}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=n(164),s=n(5),a=n(12),u=n(192),c=n(196),p="asset://debug/lib";e.debugOutputAstAsTypeScript=r;var l=function(){function t(){}return t.prototype.emitStatements=function(t,e,n){var r=new h(t),i=u.EmitterVisitorContext.createRoot(n);r.visitAllStatements(e,i);var o=[];return r.importsWithPrefixes.forEach(function(e,n){o.push("imp"+("ort * as "+e+" from '"+c.getImportModulePath(t,n,c.ImportEnv.JS)+"';"))}),o.push(i.toSource()),o.join("\n")},t}();e.TypeScriptEmitter=l;var h=function(t){function e(e){t.call(this,!1),this._moduleUrl=e,this.importsWithPrefixes=new Map}return i(e,t),e.prototype.visitExternalExpr=function(t,e){return this._visitIdentifier(t.value,t.typeParams,e),null},e.prototype.visitDeclareVarStmt=function(t,e){return e.isExportedVar(t.name)&&e.print("export "),t.hasModifier(o.StmtModifier.Final)?e.print("const"):e.print("var"),e.print(" "+t.name),s.isPresent(t.type)&&(e.print(":"),t.type.visitType(this,e)),e.print(" = "),t.value.visitExpression(this,e),e.println(";"),null},e.prototype.visitCastExpr=function(t,e){return e.print("(<"),t.type.visitType(this,e),e.print(">"),t.value.visitExpression(this,e),e.print(")"),null},e.prototype.visitDeclareClassStmt=function(t,e){var n=this;return e.pushClass(t),e.isExportedVar(t.name)&&e.print("export "),e.print("class "+t.name),s.isPresent(t.parent)&&(e.print(" extends "),t.parent.visitExpression(this,e)),e.println(" {"),e.incIndent(),t.fields.forEach(function(t){return n._visitClassField(t,e)}),s.isPresent(t.constructorMethod)&&this._visitClassConstructor(t,e),t.getters.forEach(function(t){return n._visitClassGetter(t,e)}),t.methods.forEach(function(t){return n._visitClassMethod(t,e)}),e.decIndent(),e.println("}"),e.popClass(),null},e.prototype._visitClassField=function(t,e){t.hasModifier(o.StmtModifier.Private)&&e.print("private "),e.print(t.name),s.isPresent(t.type)?(e.print(":"),t.type.visitType(this,e)):e.print(": any"),e.println(";")},e.prototype._visitClassGetter=function(t,e){t.hasModifier(o.StmtModifier.Private)&&e.print("private "),e.print("get "+t.name+"()"),s.isPresent(t.type)&&(e.print(":"),t.type.visitType(this,e)),e.println(" {"),e.incIndent(),this.visitAllStatements(t.body,e),e.decIndent(),e.println("}")},e.prototype._visitClassConstructor=function(t,e){e.print("constructor("),this._visitParams(t.constructorMethod.params,e),e.println(") {"),e.incIndent(),this.visitAllStatements(t.constructorMethod.body,e),e.decIndent(),e.println("}")},e.prototype._visitClassMethod=function(t,e){t.hasModifier(o.StmtModifier.Private)&&e.print("private "),e.print(t.name+"("),this._visitParams(t.params,e),e.print("):"),s.isPresent(t.type)?t.type.visitType(this,e):e.print("void"),e.println(" {"),e.incIndent(),this.visitAllStatements(t.body,e),e.decIndent(),e.println("}")},e.prototype.visitFunctionExpr=function(t,e){return e.print("("),this._visitParams(t.params,e),e.print("):"),s.isPresent(t.type)?t.type.visitType(this,e):e.print("void"),e.println(" => {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.print("}"),null},e.prototype.visitDeclareFunctionStmt=function(t,e){return e.isExportedVar(t.name)&&e.print("export "),e.print("function "+t.name+"("),this._visitParams(t.params,e),e.print("):"),s.isPresent(t.type)?t.type.visitType(this,e):e.print("void"),e.println(" {"),e.incIndent(),this.visitAllStatements(t.statements,e),e.decIndent(),e.println("}"),null},e.prototype.visitTryCatchStmt=function(t,e){e.println("try {"),e.incIndent(),this.visitAllStatements(t.bodyStmts,e),e.decIndent(),e.println("} catch ("+u.CATCH_ERROR_VAR.name+") {"),e.incIndent();var n=[u.CATCH_STACK_VAR.set(u.CATCH_ERROR_VAR.prop("stack")).toDeclStmt(null,[o.StmtModifier.Final])].concat(t.catchStmts);return this.visitAllStatements(n,e),e.decIndent(),e.println("}"),null},e.prototype.visitBuiltintType=function(t,e){var n;switch(t.name){case o.BuiltinTypeName.Bool:n="boolean";break;case o.BuiltinTypeName.Dynamic:n="any";break;case o.BuiltinTypeName.Function:n="Function";break;case o.BuiltinTypeName.Number:n="number";break;case o.BuiltinTypeName.Int:n="number";break;case o.BuiltinTypeName.String:n="string";break;default:throw new a.BaseException("Unsupported builtin type "+t.name)}return e.print(n),null},e.prototype.visitExternalType=function(t,e){return this._visitIdentifier(t.value,t.typeParams,e),null},e.prototype.visitArrayType=function(t,e){return s.isPresent(t.of)?t.of.visitType(this,e):e.print("any"),e.print("[]"),null},e.prototype.visitMapType=function(t,e){return e.print("{[key: string]:"),s.isPresent(t.valueType)?t.valueType.visitType(this,e):e.print("any"),e.print("}"),null},e.prototype.getBuiltinMethodName=function(t){var e;switch(t){case o.BuiltinMethod.ConcatArray:e="concat";break;case o.BuiltinMethod.SubscribeObservable:e="subscribe";break;case o.BuiltinMethod.bind:e="bind";break;default:throw new a.BaseException("Unknown builtin method: "+t)}return e},e.prototype._visitParams=function(t,e){var n=this;this.visitAllObjects(function(t){e.print(t.name),s.isPresent(t.type)&&(e.print(":"),t.type.visitType(n,e))},t,e,",")},e.prototype._visitIdentifier=function(t,e,n){var r=this;if(s.isPresent(t.moduleUrl)&&t.moduleUrl!=this._moduleUrl){var i=this.importsWithPrefixes.get(t.moduleUrl);s.isBlank(i)&&(i="import"+this.importsWithPrefixes.size,this.importsWithPrefixes.set(t.moduleUrl,i)),n.print(i+".")}n.print(t.name),s.isPresent(e)&&e.length>0&&(n.print("<"),this.visitAllObjects(function(t){return t.visitType(r,n)},e,n,","),n.print(">"))},e}(u.AbstractEmitterVisitor)},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(159),s=n(12),a=function(){function t(){}return t.prototype.createInstance=function(t,e,n,r,i,a){if(t===o.AppView)return new u(n,r,i,a);throw new s.BaseException("Can't instantiate class "+t+" in interpretative mode")},t}();e.InterpretiveAppViewInstanceFactory=a;var u=function(t){function e(e,n,r,i){t.call(this,e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]),this.props=n,this.getters=r,this.methods=i}return r(e,t),e.prototype.createInternal=function(e){var n=this.methods.get("createInternal");return i.isPresent(n)?n(e):t.prototype.createInternal.call(this,e)},e.prototype.injectorGetInternal=function(e,n,r){var o=this.methods.get("injectorGetInternal");return i.isPresent(o)?o(e,n,r):t.prototype.injectorGet.call(this,e,n,r)},e.prototype.destroyInternal=function(){var e=this.methods.get("destroyInternal");return i.isPresent(e)?e():t.prototype.destroyInternal.call(this)},e.prototype.dirtyParentQueriesInternal=function(){var e=this.methods.get("dirtyParentQueriesInternal");return i.isPresent(e)?e():t.prototype.dirtyParentQueriesInternal.call(this)},e.prototype.detectChangesInternal=function(e){var n=this.methods.get("detectChangesInternal");return i.isPresent(n)?n(e):t.prototype.detectChangesInternal.call(this,e)},e}(o.AppView)},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(6),a=n(5),u=n(15),c=n(200),p=n(148),l=n(150),h=a.CONST_EXPR({xlink:"http://www.w3.org/1999/xlink",svg:"http://www.w3.org/2000/svg"}),f=function(t){function e(){t.apply(this,arguments),this._protoElements=new Map}return r(e,t),e.prototype._getProtoElement=function(t){var e=this._protoElements.get(t);if(a.isBlank(e)){var n=p.splitNsName(t);e=a.isPresent(n[0])?c.DOM.createElementNS(h[n[0]],n[1]):c.DOM.createElement(n[1]),this._protoElements.set(t,e)}return e},e.prototype.hasProperty=function(t,e){if(-1!==t.indexOf("-"))return!0;var n=this._getProtoElement(t);return c.DOM.hasProperty(n,e)},e.prototype.getMappedPropName=function(t){var e=u.StringMapWrapper.get(c.DOM.attrToPropMap,t);return a.isPresent(e)?e:t},e=i([s.Injectable(),o("design:paramtypes",[])],e)}(l.ElementSchemaRegistry);e.DomElementSchemaRegistry=f},function(t,e,n){"use strict";function r(t){i.isBlank(e.DOM)&&(e.DOM=t)}var i=n(5);e.DOM=null,e.setRootDomAdapter=r;var o=function(){function t(){}return Object.defineProperty(t.prototype,"attrToPropMap",{get:function(){return this._attrToPropMap},set:function(t){this._attrToPropMap=t},enumerable:!0,configurable:!0}),t}();e.DomAdapter=o},function(t,e,n){"use strict";function r(){return s.isBlank(c.getPlatform())&&c.createPlatform(c.ReflectiveInjector.resolveAndCreate(a.BROWSER_PROVIDERS)),c.assertPlatform(a.BROWSER_PLATFORM_MARKER)}function i(t,n){c.reflector.reflectionCapabilities=new p.ReflectionCapabilities;var i=c.ReflectiveInjector.resolveAndCreate([e.BROWSER_APP_PROVIDERS,s.isPresent(n)?n:[]],r().injector);return c.coreLoadAndBootstrap(i,t)}var o=n(202);e.BROWSER_PROVIDERS=o.BROWSER_PROVIDERS,e.CACHED_TEMPLATE_PROVIDER=o.CACHED_TEMPLATE_PROVIDER,e.ELEMENT_PROBE_PROVIDERS=o.ELEMENT_PROBE_PROVIDERS,e.ELEMENT_PROBE_PROVIDERS_PROD_MODE=o.ELEMENT_PROBE_PROVIDERS_PROD_MODE,e.inspectNativeElement=o.inspectNativeElement,e.BrowserDomAdapter=o.BrowserDomAdapter,e.By=o.By,e.Title=o.Title,e.DOCUMENT=o.DOCUMENT,e.enableDebugTools=o.enableDebugTools,e.disableDebugTools=o.disableDebugTools;var s=n(5),a=n(202),u=n(137),c=n(2),p=n(21),l=n(220),h=n(137),f=n(6);e.BROWSER_APP_PROVIDERS=s.CONST_EXPR([a.BROWSER_APP_COMMON_PROVIDERS,u.COMPILER_PROVIDERS,new f.Provider(h.XHR,{useClass:l.XHRImpl})]),e.browserPlatform=r,e.bootstrap=i},function(t,e,n){"use strict";function r(){return new c.ExceptionHandler(h.DOM,!s.IS_DART)}function i(){return h.DOM.defaultDoc()}function o(){E.BrowserDomAdapter.makeCurrent(),R.wtfInit(),w.BrowserGetTestability.init()}var s=n(5),a=n(6),u=n(184),c=n(2),p=n(87),l=n(63),h=n(200),f=n(203),d=n(205),v=n(206),y=n(208),m=n(209),g=n(217),_=n(217),b=n(216),P=n(210),E=n(218),w=n(221),C=n(222),R=n(223),S=n(204),O=n(206),T=n(224),x=n(208);e.DOCUMENT=x.DOCUMENT;var A=n(228);e.Title=A.Title;var I=n(224);e.ELEMENT_PROBE_PROVIDERS=I.ELEMENT_PROBE_PROVIDERS,e.ELEMENT_PROBE_PROVIDERS_PROD_MODE=I.ELEMENT_PROBE_PROVIDERS_PROD_MODE,e.inspectNativeElement=I.inspectNativeElement,e.By=I.By;var M=n(218);e.BrowserDomAdapter=M.BrowserDomAdapter;var k=n(229);e.enableDebugTools=k.enableDebugTools,e.disableDebugTools=k.disableDebugTools;var N=n(206);e.HAMMER_GESTURE_CONFIG=N.HAMMER_GESTURE_CONFIG,e.HammerGestureConfig=N.HammerGestureConfig,e.BROWSER_PLATFORM_MARKER=s.CONST_EXPR(new a.OpaqueToken("BrowserPlatformMarker")),e.BROWSER_PROVIDERS=s.CONST_EXPR([new a.Provider(e.BROWSER_PLATFORM_MARKER,{useValue:!0}),c.PLATFORM_COMMON_PROVIDERS,new a.Provider(c.PLATFORM_INITIALIZER,{useValue:o,multi:!0})]),e.BROWSER_APP_COMMON_PROVIDERS=s.CONST_EXPR([c.APPLICATION_COMMON_PROVIDERS,p.FORM_PROVIDERS,new a.Provider(c.PLATFORM_PIPES,{useValue:p.COMMON_PIPES,multi:!0}),new a.Provider(c.PLATFORM_DIRECTIVES,{useValue:p.COMMON_DIRECTIVES,multi:!0}),new a.Provider(c.ExceptionHandler,{useFactory:r,deps:[]}),new a.Provider(y.DOCUMENT,{useFactory:i,deps:[]}),new a.Provider(S.EVENT_MANAGER_PLUGINS,{useClass:f.DomEventsPlugin,multi:!0}),new a.Provider(S.EVENT_MANAGER_PLUGINS,{useClass:d.KeyEventsPlugin,multi:!0}),new a.Provider(S.EVENT_MANAGER_PLUGINS,{useClass:v.HammerGesturesPlugin,multi:!0}),new a.Provider(O.HAMMER_GESTURE_CONFIG,{useClass:O.HammerGestureConfig}),new a.Provider(m.DomRootRenderer,{useClass:m.DomRootRenderer_}),new a.Provider(c.RootRenderer,{useExisting:m.DomRootRenderer}),new a.Provider(_.SharedStylesHost,{useExisting:g.DomSharedStylesHost}),g.DomSharedStylesHost,l.Testability,b.BrowserDetails,P.AnimationBuilder,S.EventManager,T.ELEMENT_PROBE_PROVIDERS]),e.CACHED_TEMPLATE_PROVIDER=s.CONST_EXPR([new a.Provider(u.XHR,{useClass:C.CachedXHR})]),e.initDomAdapter=o},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(200),a=n(2),u=n(204),c=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.supports=function(t){return!0},e.prototype.addEventListener=function(t,e,n){var r=this.manager.getZone(),i=function(t){return r.runGuarded(function(){return n(t)})};return this.manager.getZone().runOutsideAngular(function(){return s.DOM.onAndCancel(t,e,i)})},e.prototype.addGlobalEventListener=function(t,e,n){var r=s.DOM.getGlobalEventTarget(t),i=this.manager.getZone(),o=function(t){return i.runGuarded(function(){return n(t)})};return this.manager.getZone().runOutsideAngular(function(){return s.DOM.onAndCancel(r,e,o)})},e=i([a.Injectable(),o("design:paramtypes",[])],e)}(u.EventManagerPlugin);e.DomEventsPlugin=c},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(5),a=n(12),u=n(6),c=n(60),p=n(15);e.EVENT_MANAGER_PLUGINS=s.CONST_EXPR(new u.OpaqueToken("EventManagerPlugins"));var l=function(){function t(t,e){var n=this;this._zone=e,t.forEach(function(t){return t.manager=n}),this._plugins=p.ListWrapper.reversed(t)}return t.prototype.addEventListener=function(t,e,n){var r=this._findPluginFor(e);return r.addEventListener(t,e,n)},t.prototype.addGlobalEventListener=function(t,e,n){var r=this._findPluginFor(e);return r.addGlobalEventListener(t,e,n)},t.prototype.getZone=function(){return this._zone},t.prototype._findPluginFor=function(t){for(var e=this._plugins,n=0;n<e.length;n++){var r=e[n];if(r.supports(t))return r}throw new a.BaseException("No event manager plugin found for event "+t)},t=r([u.Injectable(),o(0,u.Inject(e.EVENT_MANAGER_PLUGINS)),i("design:paramtypes",[Array,c.NgZone])],t)}();e.EventManager=l;var h=function(){function t(){}return t.prototype.supports=function(t){return!1},t.prototype.addEventListener=function(t,e,n){throw"not implemented"},t.prototype.addGlobalEventListener=function(t,e,n){throw"not implemented"},t}();e.EventManagerPlugin=h},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(200),a=n(5),u=n(15),c=n(204),p=n(6),l=["alt","control","meta","shift"],h={alt:function(t){return t.altKey},control:function(t){return t.ctrlKey},meta:function(t){return t.metaKey},shift:function(t){return t.shiftKey}},f=function(t){function e(){t.call(this)}return r(e,t),e.prototype.supports=function(t){return a.isPresent(e.parseEventName(t))},e.prototype.addEventListener=function(t,n,r){var i=e.parseEventName(n),o=e.eventCallback(t,u.StringMapWrapper.get(i,"fullKey"),r,this.manager.getZone());return this.manager.getZone().runOutsideAngular(function(){return s.DOM.onAndCancel(t,u.StringMapWrapper.get(i,"domEventName"),o)})},e.parseEventName=function(t){var n=t.toLowerCase().split("."),r=n.shift();if(0===n.length||!a.StringWrapper.equals(r,"keydown")&&!a.StringWrapper.equals(r,"keyup"))return null;var i=e._normalizeKey(n.pop()),o="";if(l.forEach(function(t){u.ListWrapper.contains(n,t)&&(u.ListWrapper.remove(n,t),o+=t+".")}),o+=i,0!=n.length||0===i.length)return null;var s=u.StringMapWrapper.create();return u.StringMapWrapper.set(s,"domEventName",r),u.StringMapWrapper.set(s,"fullKey",o),s},e.getEventFullKey=function(t){var e="",n=s.DOM.getEventKey(t);return n=n.toLowerCase(),a.StringWrapper.equals(n," ")?n="space":a.StringWrapper.equals(n,".")&&(n="dot"),l.forEach(function(r){if(r!=n){var i=u.StringMapWrapper.get(h,r);i(t)&&(e+=r+".")}}),e+=n},e.eventCallback=function(t,n,r,i){return function(t){a.StringWrapper.equals(e.getEventFullKey(t),n)&&i.runGuarded(function(){return r(t)})}},e._normalizeKey=function(t){switch(t){case"esc":return"escape";default:return t}},e=i([p.Injectable(),o("design:paramtypes",[])],e)}(c.EventManagerPlugin);e.KeyEventsPlugin=f},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(207),u=n(5),c=n(12),p=n(2);e.HAMMER_GESTURE_CONFIG=u.CONST_EXPR(new p.OpaqueToken("HammerGestureConfig"));var l=function(){function t(){this.events=[],this.overrides={}}return t.prototype.buildHammer=function(t){var e=new Hammer(t);e.get("pinch").set({enable:!0}),e.get("rotate").set({enable:!0});for(var n in this.overrides)e.get(n).set(this.overrides[n]);return e},t=i([p.Injectable(),o("design:paramtypes",[])],t)}();e.HammerGestureConfig=l;var h=function(t){function n(e){t.call(this),this._config=e}return r(n,t),n.prototype.supports=function(e){if(!t.prototype.supports.call(this,e)&&!this.isCustomEvent(e))return!1;if(!u.isPresent(window.Hammer))throw new c.BaseException("Hammer.js is not loaded, can not bind "+e+" event");return!0},n.prototype.addEventListener=function(t,e,n){var r=this,i=this.manager.getZone();return e=e.toLowerCase(),i.runOutsideAngular(function(){var o=r._config.buildHammer(t),s=function(t){i.runGuarded(function(){n(t)})};return o.on(e,s),function(){o.off(e,s)}})},n.prototype.isCustomEvent=function(t){return this._config.events.indexOf(t)>-1},n=i([p.Injectable(),s(0,p.Inject(e.HAMMER_GESTURE_CONFIG)),o("design:paramtypes",[l])],n)}(a.HammerGesturesPluginCommon);e.HammerGesturesPlugin=h},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(204),o=n(15),s={pan:!0,panstart:!0,panmove:!0,panend:!0,pancancel:!0,panleft:!0,panright:!0,panup:!0,pandown:!0,pinch:!0,pinchstart:!0,pinchmove:!0,pinchend:!0,pinchcancel:!0,pinchin:!0,pinchout:!0,press:!0,pressup:!0,rotate:!0,rotatestart:!0,rotatemove:!0,rotateend:!0,rotatecancel:!0,swipe:!0,swipeleft:!0,swiperight:!0,swipeup:!0,swipedown:!0,tap:!0},a=function(t){function e(){t.call(this)}return r(e,t),e.prototype.supports=function(t){return t=t.toLowerCase(),o.StringMapWrapper.contains(s,t)},e}(i.EventManagerPlugin);e.HammerGesturesPluginCommon=a},function(t,e,n){"use strict";var r=n(6),i=n(5);e.DOCUMENT=i.CONST_EXPR(new r.OpaqueToken("DocumentToken"))},function(t,e,n){"use strict";function r(t,e){var n=E.DOM.parentElement(t);if(e.length>0&&y.isPresent(n)){var r=E.DOM.nextSibling(t);if(y.isPresent(r))for(var i=0;i<e.length;i++)E.DOM.insertBefore(r,e[i]);else for(var i=0;i<e.length;i++)E.DOM.appendChild(n,e[i])}}function i(t,e){for(var n=0;n<e.length;n++)E.DOM.appendChild(t,e[n])}function o(t){return function(e){var n=t(e);n===!1&&E.DOM.preventDefault(e)}}function s(t){return y.StringWrapper.replaceAll(e.CONTENT_ATTR,A,t)}function a(t){return y.StringWrapper.replaceAll(e.HOST_ATTR,A,t)}function u(t,e,n){for(var r=0;r<e.length;r++){var i=e[r];y.isArray(i)?u(t,i,n):(i=y.StringWrapper.replaceAll(i,A,t),n.push(i))}return n}function c(t){if("@"!=t[0])return[null,t];var e=y.RegExpWrapper.firstMatch(I,t);return[e[1],e[2]]}var p=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},l=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);
                +return o>3&&s&&Object.defineProperty(e,n,s),s},h=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},f=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},d=n(6),v=n(210),y=n(5),m=n(12),g=n(217),_=n(204),b=n(208),P=n(3),E=n(200),w=n(215),C=y.CONST_EXPR({xlink:"http://www.w3.org/1999/xlink",svg:"http://www.w3.org/2000/svg"}),R="template bindings={}",S=/^template bindings=(.*)$/g,O=function(){function t(t,e,n,r){this.document=t,this.eventManager=e,this.sharedStylesHost=n,this.animate=r,this._registeredComponents=new Map}return t.prototype.renderComponent=function(t){var e=this._registeredComponents.get(t.id);return y.isBlank(e)&&(e=new x(this,t),this._registeredComponents.set(t.id,e)),e},t}();e.DomRootRenderer=O;var T=function(t){function e(e,n,r,i){t.call(this,e,n,r,i)}return p(e,t),e=l([d.Injectable(),f(0,d.Inject(b.DOCUMENT)),h("design:paramtypes",[Object,_.EventManager,g.DomSharedStylesHost,v.AnimationBuilder])],e)}(O);e.DomRootRenderer_=T;var x=function(){function t(t,e){this._rootRenderer=t,this.componentProto=e,this._styles=u(e.id,e.styles,[]),e.encapsulation!==P.ViewEncapsulation.Native&&this._rootRenderer.sharedStylesHost.addStyles(this._styles),this.componentProto.encapsulation===P.ViewEncapsulation.Emulated?(this._contentAttr=s(e.id),this._hostAttr=a(e.id)):(this._contentAttr=null,this._hostAttr=null)}return t.prototype.selectRootElement=function(t,e){var n;if(y.isString(t)){if(n=E.DOM.querySelector(this._rootRenderer.document,t),y.isBlank(n))throw new m.BaseException('The selector "'+t+'" did not match any elements')}else n=t;return E.DOM.clearNodes(n),n},t.prototype.createElement=function(t,e,n){var r=c(e),i=y.isPresent(r[0])?E.DOM.createElementNS(C[r[0]],r[1]):E.DOM.createElement(r[1]);return y.isPresent(this._contentAttr)&&E.DOM.setAttribute(i,this._contentAttr,""),y.isPresent(t)&&E.DOM.appendChild(t,i),i},t.prototype.createViewRoot=function(t){var e;if(this.componentProto.encapsulation===P.ViewEncapsulation.Native){e=E.DOM.createShadowRoot(t),this._rootRenderer.sharedStylesHost.addHost(e);for(var n=0;n<this._styles.length;n++)E.DOM.appendChild(e,E.DOM.createStyleElement(this._styles[n]))}else y.isPresent(this._hostAttr)&&E.DOM.setAttribute(t,this._hostAttr,""),e=t;return e},t.prototype.createTemplateAnchor=function(t,e){var n=E.DOM.createComment(R);return y.isPresent(t)&&E.DOM.appendChild(t,n),n},t.prototype.createText=function(t,e,n){var r=E.DOM.createTextNode(e);return y.isPresent(t)&&E.DOM.appendChild(t,r),r},t.prototype.projectNodes=function(t,e){y.isBlank(t)||i(t,e)},t.prototype.attachViewAfter=function(t,e){r(t,e);for(var n=0;n<e.length;n++)this.animateNodeEnter(e[n])},t.prototype.detachView=function(t){for(var e=0;e<t.length;e++){var n=t[e];E.DOM.remove(n),this.animateNodeLeave(n)}},t.prototype.destroyView=function(t,e){this.componentProto.encapsulation===P.ViewEncapsulation.Native&&y.isPresent(t)&&this._rootRenderer.sharedStylesHost.removeHost(E.DOM.getShadowRoot(t))},t.prototype.listen=function(t,e,n){return this._rootRenderer.eventManager.addEventListener(t,e,o(n))},t.prototype.listenGlobal=function(t,e,n){return this._rootRenderer.eventManager.addGlobalEventListener(t,e,o(n))},t.prototype.setElementProperty=function(t,e,n){E.DOM.setProperty(t,e,n)},t.prototype.setElementAttribute=function(t,e,n){var r,i=c(e);y.isPresent(i[0])&&(e=i[0]+":"+i[1],r=C[i[0]]),y.isPresent(n)?y.isPresent(r)?E.DOM.setAttributeNS(t,r,e,n):E.DOM.setAttribute(t,e,n):y.isPresent(r)?E.DOM.removeAttributeNS(t,r,i[1]):E.DOM.removeAttribute(t,e)},t.prototype.setBindingDebugInfo=function(t,e,n){var r=w.camelCaseToDashCase(e);if(E.DOM.isCommentNode(t)){var i=y.RegExpWrapper.firstMatch(S,y.StringWrapper.replaceAll(E.DOM.getText(t),/\n/g,"")),o=y.Json.parse(i[1]);o[r]=n,E.DOM.setText(t,y.StringWrapper.replace(R,"{}",y.Json.stringify(o)))}else this.setElementAttribute(t,e,n)},t.prototype.setElementClass=function(t,e,n){n?E.DOM.addClass(t,e):E.DOM.removeClass(t,e)},t.prototype.setElementStyle=function(t,e,n){y.isPresent(n)?E.DOM.setStyle(t,e,y.stringify(n)):E.DOM.removeStyle(t,e)},t.prototype.invokeElementMethod=function(t,e,n){E.DOM.invoke(t,e,n)},t.prototype.setText=function(t,e){E.DOM.setText(t,e)},t.prototype.animateNodeEnter=function(t){E.DOM.isElementNode(t)&&E.DOM.hasClass(t,"ng-animate")&&(E.DOM.addClass(t,"ng-enter"),this._rootRenderer.animate.css().addAnimationClass("ng-enter-active").start(t).onComplete(function(){E.DOM.removeClass(t,"ng-enter")}))},t.prototype.animateNodeLeave=function(t){E.DOM.isElementNode(t)&&E.DOM.hasClass(t,"ng-animate")?(E.DOM.addClass(t,"ng-leave"),this._rootRenderer.animate.css().addAnimationClass("ng-leave-active").start(t).onComplete(function(){E.DOM.removeClass(t,"ng-leave"),E.DOM.remove(t)})):E.DOM.remove(t)},t}();e.DomRenderer=x;var A=/%COMP%/g;e.COMPONENT_VARIABLE="%COMP%",e.HOST_ATTR="_nghost-"+e.COMPONENT_VARIABLE,e.CONTENT_ATTR="_ngcontent-"+e.COMPONENT_VARIABLE;var I=/^@([^:]+):(.+)/g},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(6),s=n(211),a=n(216),u=function(){function t(t){this.browserDetails=t}return t.prototype.css=function(){return new s.CssAnimationBuilder(this.browserDetails)},t=r([o.Injectable(),i("design:paramtypes",[a.BrowserDetails])],t)}();e.AnimationBuilder=u},function(t,e,n){"use strict";var r=n(212),i=n(213),o=function(){function t(t){this.browserDetails=t,this.data=new r.CssAnimationOptions}return t.prototype.addAnimationClass=function(t){return this.data.animationClasses.push(t),this},t.prototype.addClass=function(t){return this.data.classesToAdd.push(t),this},t.prototype.removeClass=function(t){return this.data.classesToRemove.push(t),this},t.prototype.setDuration=function(t){return this.data.duration=t,this},t.prototype.setDelay=function(t){return this.data.delay=t,this},t.prototype.setStyles=function(t,e){return this.setFromStyles(t).setToStyles(e)},t.prototype.setFromStyles=function(t){return this.data.fromStyles=t,this},t.prototype.setToStyles=function(t){return this.data.toStyles=t,this},t.prototype.start=function(t){return new i.Animation(t,this.data,this.browserDetails)},t}();e.CssAnimationBuilder=o},function(t,e){"use strict";var n=function(){function t(){this.classesToAdd=[],this.classesToRemove=[],this.animationClasses=[]}return t}();e.CssAnimationOptions=n},function(t,e,n){"use strict";var r=n(5),i=n(214),o=n(215),s=n(15),a=n(200),u=function(){function t(t,e,n){var i=this;this.element=t,this.data=e,this.browserDetails=n,this.callbacks=[],this.eventClearFunctions=[],this.completed=!1,this._stringPrefix="",this.startTime=r.DateWrapper.toMillis(r.DateWrapper.now()),this._stringPrefix=a.DOM.getAnimationPrefix(),this.setup(),this.wait(function(t){return i.start()})}return Object.defineProperty(t.prototype,"totalTime",{get:function(){var t=null!=this.computedDelay?this.computedDelay:0,e=null!=this.computedDuration?this.computedDuration:0;return t+e},enumerable:!0,configurable:!0}),t.prototype.wait=function(t){this.browserDetails.raf(t,2)},t.prototype.setup=function(){null!=this.data.fromStyles&&this.applyStyles(this.data.fromStyles),null!=this.data.duration&&this.applyStyles({transitionDuration:this.data.duration.toString()+"ms"}),null!=this.data.delay&&this.applyStyles({transitionDelay:this.data.delay.toString()+"ms"})},t.prototype.start=function(){this.addClasses(this.data.classesToAdd),this.addClasses(this.data.animationClasses),this.removeClasses(this.data.classesToRemove),null!=this.data.toStyles&&this.applyStyles(this.data.toStyles);var t=a.DOM.getComputedStyle(this.element);this.computedDelay=i.Math.max(this.parseDurationString(t.getPropertyValue(this._stringPrefix+"transition-delay")),this.parseDurationString(this.element.style.getPropertyValue(this._stringPrefix+"transition-delay"))),this.computedDuration=i.Math.max(this.parseDurationString(t.getPropertyValue(this._stringPrefix+"transition-duration")),this.parseDurationString(this.element.style.getPropertyValue(this._stringPrefix+"transition-duration"))),this.addEvents()},t.prototype.applyStyles=function(t){var e=this;s.StringMapWrapper.forEach(t,function(t,n){var i=o.camelCaseToDashCase(n);r.isPresent(a.DOM.getStyle(e.element,i))?a.DOM.setStyle(e.element,i,t.toString()):a.DOM.setStyle(e.element,e._stringPrefix+i,t.toString())})},t.prototype.addClasses=function(t){for(var e=0,n=t.length;n>e;e++)a.DOM.addClass(this.element,t[e])},t.prototype.removeClasses=function(t){for(var e=0,n=t.length;n>e;e++)a.DOM.removeClass(this.element,t[e])},t.prototype.addEvents=function(){var t=this;this.totalTime>0?this.eventClearFunctions.push(a.DOM.onAndCancel(this.element,a.DOM.getTransitionEnd(),function(e){return t.handleAnimationEvent(e)})):this.handleAnimationCompleted()},t.prototype.handleAnimationEvent=function(t){var e=i.Math.round(1e3*t.elapsedTime);this.browserDetails.elapsedTimeIncludesDelay||(e+=this.computedDelay),t.stopPropagation(),e>=this.totalTime&&this.handleAnimationCompleted()},t.prototype.handleAnimationCompleted=function(){this.removeClasses(this.data.animationClasses),this.callbacks.forEach(function(t){return t()}),this.callbacks=[],this.eventClearFunctions.forEach(function(t){return t()}),this.eventClearFunctions=[],this.completed=!0},t.prototype.onComplete=function(t){return this.completed?t():this.callbacks.push(t),this},t.prototype.parseDurationString=function(t){var e=0;if(null==t||t.length<2)return e;if("ms"==t.substring(t.length-2)){var n=r.NumberWrapper.parseInt(this.stripLetters(t),10);n>e&&(e=n)}else if("s"==t.substring(t.length-1)){var o=1e3*r.NumberWrapper.parseFloat(this.stripLetters(t)),n=i.Math.floor(o);n>e&&(e=n)}return e},t.prototype.stripLetters=function(t){return r.StringWrapper.replaceAll(t,r.RegExpWrapper.create("[^0-9]+$",""),"")},t}();e.Animation=u},function(t,e,n){"use strict";var r=n(5);e.Math=r.global.Math,e.NaN=typeof e.NaN},function(t,e,n){"use strict";function r(t){return o.StringWrapper.replaceAllMapped(t,s,function(t){return"-"+t[1].toLowerCase()})}function i(t){return o.StringWrapper.replaceAllMapped(t,a,function(t){return t[1].toUpperCase()})}var o=n(5),s=/([A-Z])/g,a=/-([a-z])/g;e.camelCaseToDashCase=r,e.dashCaseToCamelCase=i},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(6),s=n(214),a=n(200),u=function(){function t(){this.elapsedTimeIncludesDelay=!1,this.doesElapsedTimeIncludesDelay()}return t.prototype.doesElapsedTimeIncludesDelay=function(){var t=this,e=a.DOM.createElement("div");a.DOM.setAttribute(e,"style","position: absolute; top: -9999px; left: -9999px; width: 1px;\n      height: 1px; transition: all 1ms linear 1ms;"),this.raf(function(n){a.DOM.on(e,"transitionend",function(n){var r=s.Math.round(1e3*n.elapsedTime);t.elapsedTimeIncludesDelay=2==r,a.DOM.remove(e)}),a.DOM.setStyle(e,"width","2px")},2)},t.prototype.raf=function(t,e){void 0===e&&(e=1);var n=new c(t,e);return function(){return n.cancel()}},t=r([o.Injectable(),i("design:paramtypes",[])],t)}();e.BrowserDetails=u;var c=function(){function t(t,e){this.callback=t,this.frames=e,this._raf()}return t.prototype._raf=function(){var t=this;this.currentFrameId=a.DOM.requestAnimationFrame(function(e){return t._nextFrame(e)})},t.prototype._nextFrame=function(t){this.frames--,this.frames>0?this._raf():this.callback(t)},t.prototype.cancel=function(){a.DOM.cancelAnimationFrame(this.currentFrameId),this.currentFrameId=null},t}()},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(200),u=n(6),c=n(15),p=n(208),l=function(){function t(){this._styles=[],this._stylesSet=new Set}return t.prototype.addStyles=function(t){var e=this,n=[];t.forEach(function(t){c.SetWrapper.has(e._stylesSet,t)||(e._stylesSet.add(t),e._styles.push(t),n.push(t))}),this.onStylesAdded(n)},t.prototype.onStylesAdded=function(t){},t.prototype.getAllStyles=function(){return this._styles},t=i([u.Injectable(),o("design:paramtypes",[])],t)}();e.SharedStylesHost=l;var h=function(t){function e(e){t.call(this),this._hostNodes=new Set,this._hostNodes.add(e.head)}return r(e,t),e.prototype._addStylesToHost=function(t,e){for(var n=0;n<t.length;n++){var r=t[n];a.DOM.appendChild(e,a.DOM.createStyleElement(r))}},e.prototype.addHost=function(t){this._addStylesToHost(this._styles,t),this._hostNodes.add(t)},e.prototype.removeHost=function(t){c.SetWrapper["delete"](this._hostNodes,t)},e.prototype.onStylesAdded=function(t){var e=this;this._hostNodes.forEach(function(n){e._addStylesToHost(t,n)})},e=i([u.Injectable(),s(0,u.Inject(p.DOCUMENT)),o("design:paramtypes",[Object])],e)}(l);e.DomSharedStylesHost=h},function(t,e,n){"use strict";function r(){return a.isBlank(v)&&(v=document.querySelector("base"),a.isBlank(v))?null:v.getAttribute("href")}function i(t){return a.isBlank(y)&&(y=document.createElement("a")),y.setAttribute("href",t),"/"===y.pathname.charAt(0)?y.pathname:"/"+y.pathname}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=n(15),a=n(5),u=n(200),c=n(219),p={"class":"className",innerHtml:"innerHTML",readonly:"readOnly",tabindex:"tabIndex"},l=3,h={"\b":"Backspace","	":"Tab","":"Delete","":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},f={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","":"NumLock"},d=function(t){function e(){t.apply(this,arguments)}return o(e,t),e.prototype.parse=function(t){throw new Error("parse not implemented")},e.makeCurrent=function(){u.setRootDomAdapter(new e)},e.prototype.hasProperty=function(t,e){return e in t},e.prototype.setProperty=function(t,e,n){t[e]=n},e.prototype.getProperty=function(t,e){return t[e]},e.prototype.invoke=function(t,e,n){t[e].apply(t,n)},e.prototype.logError=function(t){window.console.error?window.console.error(t):window.console.log(t)},e.prototype.log=function(t){window.console.log(t)},e.prototype.logGroup=function(t){window.console.group?(window.console.group(t),this.logError(t)):window.console.log(t)},e.prototype.logGroupEnd=function(){window.console.groupEnd&&window.console.groupEnd()},Object.defineProperty(e.prototype,"attrToPropMap",{get:function(){return p},enumerable:!0,configurable:!0}),e.prototype.query=function(t){return document.querySelector(t)},e.prototype.querySelector=function(t,e){return t.querySelector(e)},e.prototype.querySelectorAll=function(t,e){return t.querySelectorAll(e)},e.prototype.on=function(t,e,n){t.addEventListener(e,n,!1)},e.prototype.onAndCancel=function(t,e,n){return t.addEventListener(e,n,!1),function(){t.removeEventListener(e,n,!1)}},e.prototype.dispatchEvent=function(t,e){t.dispatchEvent(e)},e.prototype.createMouseEvent=function(t){var e=document.createEvent("MouseEvent");return e.initEvent(t,!0,!0),e},e.prototype.createEvent=function(t){var e=document.createEvent("Event");return e.initEvent(t,!0,!0),e},e.prototype.preventDefault=function(t){t.preventDefault(),t.returnValue=!1},e.prototype.isPrevented=function(t){return t.defaultPrevented||a.isPresent(t.returnValue)&&!t.returnValue},e.prototype.getInnerHTML=function(t){return t.innerHTML},e.prototype.getOuterHTML=function(t){return t.outerHTML},e.prototype.nodeName=function(t){return t.nodeName},e.prototype.nodeValue=function(t){return t.nodeValue},e.prototype.type=function(t){return t.type},e.prototype.content=function(t){return this.hasProperty(t,"content")?t.content:t},e.prototype.firstChild=function(t){return t.firstChild},e.prototype.nextSibling=function(t){return t.nextSibling},e.prototype.parentElement=function(t){return t.parentNode},e.prototype.childNodes=function(t){return t.childNodes},e.prototype.childNodesAsList=function(t){for(var e=t.childNodes,n=s.ListWrapper.createFixedSize(e.length),r=0;r<e.length;r++)n[r]=e[r];return n},e.prototype.clearNodes=function(t){for(;t.firstChild;)t.removeChild(t.firstChild)},e.prototype.appendChild=function(t,e){t.appendChild(e)},e.prototype.removeChild=function(t,e){t.removeChild(e)},e.prototype.replaceChild=function(t,e,n){t.replaceChild(e,n)},e.prototype.remove=function(t){return t.parentNode&&t.parentNode.removeChild(t),t},e.prototype.insertBefore=function(t,e){t.parentNode.insertBefore(e,t)},e.prototype.insertAllBefore=function(t,e){e.forEach(function(e){return t.parentNode.insertBefore(e,t)})},e.prototype.insertAfter=function(t,e){t.parentNode.insertBefore(e,t.nextSibling)},e.prototype.setInnerHTML=function(t,e){t.innerHTML=e},e.prototype.getText=function(t){return t.textContent},e.prototype.setText=function(t,e){t.textContent=e},e.prototype.getValue=function(t){return t.value},e.prototype.setValue=function(t,e){t.value=e},e.prototype.getChecked=function(t){return t.checked},e.prototype.setChecked=function(t,e){t.checked=e},e.prototype.createComment=function(t){return document.createComment(t)},e.prototype.createTemplate=function(t){var e=document.createElement("template");return e.innerHTML=t,e},e.prototype.createElement=function(t,e){return void 0===e&&(e=document),e.createElement(t)},e.prototype.createElementNS=function(t,e,n){return void 0===n&&(n=document),n.createElementNS(t,e)},e.prototype.createTextNode=function(t,e){return void 0===e&&(e=document),e.createTextNode(t)},e.prototype.createScriptTag=function(t,e,n){void 0===n&&(n=document);var r=n.createElement("SCRIPT");return r.setAttribute(t,e),r},e.prototype.createStyleElement=function(t,e){void 0===e&&(e=document);var n=e.createElement("style");return this.appendChild(n,this.createTextNode(t)),n},e.prototype.createShadowRoot=function(t){return t.createShadowRoot()},e.prototype.getShadowRoot=function(t){return t.shadowRoot},e.prototype.getHost=function(t){return t.host},e.prototype.clone=function(t){return t.cloneNode(!0)},e.prototype.getElementsByClassName=function(t,e){return t.getElementsByClassName(e)},e.prototype.getElementsByTagName=function(t,e){return t.getElementsByTagName(e)},e.prototype.classList=function(t){return Array.prototype.slice.call(t.classList,0)},e.prototype.addClass=function(t,e){t.classList.add(e)},e.prototype.removeClass=function(t,e){t.classList.remove(e)},e.prototype.hasClass=function(t,e){return t.classList.contains(e)},e.prototype.setStyle=function(t,e,n){t.style[e]=n},e.prototype.removeStyle=function(t,e){t.style[e]=null},e.prototype.getStyle=function(t,e){return t.style[e]},e.prototype.hasStyle=function(t,e,n){void 0===n&&(n=null);var r=this.getStyle(t,e)||"";return n?r==n:r.length>0},e.prototype.tagName=function(t){return t.tagName},e.prototype.attributeMap=function(t){for(var e=new Map,n=t.attributes,r=0;r<n.length;r++){var i=n[r];e.set(i.name,i.value)}return e},e.prototype.hasAttribute=function(t,e){return t.hasAttribute(e)},e.prototype.hasAttributeNS=function(t,e,n){return t.hasAttributeNS(e,n)},e.prototype.getAttribute=function(t,e){return t.getAttribute(e)},e.prototype.getAttributeNS=function(t,e,n){return t.getAttributeNS(e,n)},e.prototype.setAttribute=function(t,e,n){t.setAttribute(e,n)},e.prototype.setAttributeNS=function(t,e,n,r){t.setAttributeNS(e,n,r)},e.prototype.removeAttribute=function(t,e){t.removeAttribute(e)},e.prototype.removeAttributeNS=function(t,e,n){t.removeAttributeNS(e,n)},e.prototype.templateAwareRoot=function(t){return this.isTemplateElement(t)?this.content(t):t},e.prototype.createHtmlDocument=function(){return document.implementation.createHTMLDocument("fakeTitle")},e.prototype.defaultDoc=function(){return document},e.prototype.getBoundingClientRect=function(t){try{return t.getBoundingClientRect()}catch(e){return{top:0,bottom:0,left:0,right:0,width:0,height:0}}},e.prototype.getTitle=function(){return document.title},e.prototype.setTitle=function(t){document.title=t||""},e.prototype.elementMatches=function(t,e){var n=!1;return t instanceof HTMLElement&&(t.matches?n=t.matches(e):t.msMatchesSelector?n=t.msMatchesSelector(e):t.webkitMatchesSelector&&(n=t.webkitMatchesSelector(e))),n},e.prototype.isTemplateElement=function(t){return t instanceof HTMLElement&&"TEMPLATE"==t.nodeName},e.prototype.isTextNode=function(t){return t.nodeType===Node.TEXT_NODE},e.prototype.isCommentNode=function(t){return t.nodeType===Node.COMMENT_NODE},e.prototype.isElementNode=function(t){return t.nodeType===Node.ELEMENT_NODE},e.prototype.hasShadowRoot=function(t){return t instanceof HTMLElement&&a.isPresent(t.shadowRoot)},e.prototype.isShadowRoot=function(t){return t instanceof DocumentFragment},e.prototype.importIntoDoc=function(t){var e=t;return this.isTemplateElement(t)&&(e=this.content(t)),document.importNode(e,!0)},e.prototype.adoptNode=function(t){return document.adoptNode(t)},e.prototype.getHref=function(t){return t.href},e.prototype.getEventKey=function(t){var e=t.key;if(a.isBlank(e)){if(e=t.keyIdentifier,a.isBlank(e))return"Unidentified";e.startsWith("U+")&&(e=String.fromCharCode(parseInt(e.substring(2),16)),t.location===l&&f.hasOwnProperty(e)&&(e=f[e]))}return h.hasOwnProperty(e)&&(e=h[e]),e},e.prototype.getGlobalEventTarget=function(t){return"window"==t?window:"document"==t?document:"body"==t?document.body:void 0},e.prototype.getHistory=function(){return window.history},e.prototype.getLocation=function(){return window.location},e.prototype.getBaseHref=function(){var t=r();return a.isBlank(t)?null:i(t)},e.prototype.resetBaseElement=function(){v=null},e.prototype.getUserAgent=function(){return window.navigator.userAgent},e.prototype.setData=function(t,e,n){this.setAttribute(t,"data-"+e,n)},e.prototype.getData=function(t,e){return this.getAttribute(t,"data-"+e)},e.prototype.getComputedStyle=function(t){return getComputedStyle(t)},e.prototype.setGlobalVar=function(t,e){a.setValueOnPath(a.global,t,e)},e.prototype.requestAnimationFrame=function(t){return window.requestAnimationFrame(t)},e.prototype.cancelAnimationFrame=function(t){window.cancelAnimationFrame(t)},e.prototype.performanceNow=function(){return a.isPresent(window.performance)&&a.isPresent(window.performance.now)?window.performance.now():a.DateWrapper.toMillis(a.DateWrapper.now())},e}(c.GenericBrowserDomAdapter);e.BrowserDomAdapter=d;var v=null,y=null},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(15),o=n(5),s=n(200),a=n(220),u=function(t){function e(){var e=this;t.call(this),this._animationPrefix=null,this._transitionEnd=null;try{var n=this.createElement("div",this.defaultDoc());if(o.isPresent(this.getStyle(n,"animationName")))this._animationPrefix="";else for(var r=["Webkit","Moz","O","ms"],s=0;s<r.length;s++)if(o.isPresent(this.getStyle(n,r[s]+"AnimationName"))){this._animationPrefix="-"+r[s].toLowerCase()+"-";break}var a={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};i.StringMapWrapper.forEach(a,function(t,r){o.isPresent(e.getStyle(n,r))&&(e._transitionEnd=t)})}catch(u){this._animationPrefix=null,this._transitionEnd=null}}return r(e,t),e.prototype.getXHR=function(){return a.XHRImpl},e.prototype.getDistributedNodes=function(t){return t.getDistributedNodes()},e.prototype.resolveAndSetHref=function(t,e,n){t.href=null==n?e:e+"/../"+n},e.prototype.supportsDOMEvents=function(){return!0},e.prototype.supportsNativeShadowDOM=function(){return o.isFunction(this.defaultDoc().body.createShadowRoot)},e.prototype.getAnimationPrefix=function(){return o.isPresent(this._animationPrefix)?this._animationPrefix:""},e.prototype.getTransitionEnd=function(){return o.isPresent(this._transitionEnd)?this._transitionEnd:""},e.prototype.supportsAnimation=function(){return o.isPresent(this._animationPrefix)&&o.isPresent(this._transitionEnd)},e}(s.DomAdapter);e.GenericBrowserDomAdapter=u},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(41),o=n(5),s=n(184),a=function(t){function e(){t.apply(this,arguments)}return r(e,t),e.prototype.get=function(t){var e=i.PromiseWrapper.completer(),n=new XMLHttpRequest;return n.open("GET",t,!0),n.responseType="text",n.onload=function(){var r=o.isPresent(n.response)?n.response:n.responseText,i=1223===n.status?204:n.status;0===i&&(i=r?200:0),i>=200&&300>=i?e.resolve(r):e.reject("Failed to load "+t,null)},n.onerror=function(){e.reject("Failed to load "+t,null)},n.send(),e.promise},e}(s.XHR);e.XHRImpl=a},function(t,e,n){"use strict";var r=n(15),i=n(5),o=n(200),s=n(2),a=function(){function t(t){this._testability=t}return t.prototype.isStable=function(){return this._testability.isStable()},t.prototype.whenStable=function(t){this._testability.whenStable(t)},t.prototype.findBindings=function(t,e,n){return this.findProviders(t,e,n)},t.prototype.findProviders=function(t,e,n){return this._testability.findBindings(t,e,n)},t}(),u=function(){function t(){}return t.init=function(){s.setTestabilityGetter(new t)},t.prototype.addToWindow=function(t){i.global.getAngularTestability=function(e,n){void 0===n&&(n=!0);var r=t.findTestabilityInTree(e,n);if(null==r)throw new Error("Could not find testability for element.");return new a(r)},i.global.getAllAngularTestabilities=function(){var e=t.getAllTestabilities();return e.map(function(t){return new a(t)})},i.global.getAllAngularRootElements=function(){return t.getAllRootElements()};var e=function(t){var e=i.global.getAllAngularTestabilities(),n=e.length,r=!1,o=function(e){r=r||e,n--,0==n&&t(r)};e.forEach(function(t){t.whenStable(o)})};i.global.frameworkStabilizers||(i.global.frameworkStabilizers=r.ListWrapper.createGrowableSize(0)),i.global.frameworkStabilizers.push(e)},t.prototype.findTestabilityInTree=function(t,e,n){if(null==e)return null;var r=t.getTestability(e);return i.isPresent(r)?r:n?o.DOM.isShadowRoot(e)?this.findTestabilityInTree(t,o.DOM.getHost(e),!0):this.findTestabilityInTree(t,o.DOM.parentElement(e),!0):null},t}();e.BrowserGetTestability=u},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(184),o=n(12),s=n(5),a=n(41),u=function(t){function e(){if(t.call(this),this._cache=s.global.$templateCache,null==this._cache)throw new o.BaseException("CachedXHR: Template cache was not found in $templateCache.")}return r(e,t),e.prototype.get=function(t){return this._cache.hasOwnProperty(t)?a.PromiseWrapper.resolve(this._cache[t]):a.PromiseWrapper.reject("CachedXHR: Did not find cached template for "+t,null)},e}(i.XHR);e.CachedXHR=u},function(t,e){"use strict";function n(){}e.wtfInit=n},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}var i=n(200);e.DOM=i.DOM,e.setRootDomAdapter=i.setRootDomAdapter,e.DomAdapter=i.DomAdapter;var o=n(209);e.DomRenderer=o.DomRenderer;var s=n(208);e.DOCUMENT=s.DOCUMENT;var a=n(217);e.SharedStylesHost=a.SharedStylesHost,e.DomSharedStylesHost=a.DomSharedStylesHost;var u=n(203);e.DomEventsPlugin=u.DomEventsPlugin;var c=n(204);e.EVENT_MANAGER_PLUGINS=c.EVENT_MANAGER_PLUGINS,e.EventManager=c.EventManager,e.EventManagerPlugin=c.EventManagerPlugin,r(n(225)),r(n(226))},function(t,e,n){"use strict";var r=n(5),i=n(200),o=function(){function t(){}return t.all=function(){return function(t){return!0}},t.css=function(t){return function(e){return r.isPresent(e.nativeElement)?i.DOM.elementMatches(e.nativeElement,t):!1}},t.directive=function(t){return function(e){return-1!==e.providerTokens.indexOf(t)}},t}();e.By=o},function(t,e,n){"use strict";function r(t){return c.getDebugNode(t)}function i(t){return s.assertionsEnabled()?o(t):t}function o(t){return u.DOM.setGlobalVar(d,r),u.DOM.setGlobalVar(v,f),new h.DebugDomRootRenderer(t)}var s=n(5),a=n(6),u=n(200),c=n(83),p=n(209),l=n(2),h=n(227),f=s.CONST_EXPR({ApplicationRef:l.ApplicationRef,NgZone:l.NgZone}),d="ng.probe",v="ng.coreTokens";e.inspectNativeElement=r,e.ELEMENT_PROBE_PROVIDERS=s.CONST_EXPR([new a.Provider(l.RootRenderer,{useFactory:i,deps:[p.DomRootRenderer]})]),e.ELEMENT_PROBE_PROVIDERS_PROD_MODE=s.CONST_EXPR([new a.Provider(l.RootRenderer,{useFactory:o,deps:[p.DomRootRenderer]})])},function(t,e,n){"use strict";var r=n(5),i=n(83),o=function(){function t(t){this._delegate=t}return t.prototype.renderComponent=function(t){return new s(this._delegate.renderComponent(t))},t}();e.DebugDomRootRenderer=o;var s=function(){function t(t){this._delegate=t}return t.prototype.selectRootElement=function(t,e){var n=this._delegate.selectRootElement(t,e),r=new i.DebugElement(n,null,e);return i.indexDebugNode(r),n},t.prototype.createElement=function(t,e,n){var r=this._delegate.createElement(t,e,n),o=new i.DebugElement(r,i.getDebugNode(t),n);return o.name=e,i.indexDebugNode(o),r},t.prototype.createViewRoot=function(t){return this._delegate.createViewRoot(t)},t.prototype.createTemplateAnchor=function(t,e){var n=this._delegate.createTemplateAnchor(t,e),r=new i.DebugNode(n,i.getDebugNode(t),e);return i.indexDebugNode(r),n},t.prototype.createText=function(t,e,n){var r=this._delegate.createText(t,e,n),o=new i.DebugNode(r,i.getDebugNode(t),n);return i.indexDebugNode(o),r},t.prototype.projectNodes=function(t,e){var n=i.getDebugNode(t);if(r.isPresent(n)&&n instanceof i.DebugElement){var o=n;e.forEach(function(t){o.addChild(i.getDebugNode(t))})}this._delegate.projectNodes(t,e)},t.prototype.attachViewAfter=function(t,e){var n=i.getDebugNode(t);if(r.isPresent(n)){var o=n.parent;if(e.length>0&&r.isPresent(o)){var s=[];e.forEach(function(t){return s.push(i.getDebugNode(t))}),o.insertChildrenAfter(n,s)}}this._delegate.attachViewAfter(t,e)},t.prototype.detachView=function(t){t.forEach(function(t){var e=i.getDebugNode(t);r.isPresent(e)&&r.isPresent(e.parent)&&e.parent.removeChild(e)}),this._delegate.detachView(t)},t.prototype.destroyView=function(t,e){e.forEach(function(t){i.removeDebugNodeFromIndex(i.getDebugNode(t))}),this._delegate.destroyView(t,e)},t.prototype.listen=function(t,e,n){var o=i.getDebugNode(t);return r.isPresent(o)&&o.listeners.push(new i.EventListener(e,n)),this._delegate.listen(t,e,n)},t.prototype.listenGlobal=function(t,e,n){return this._delegate.listenGlobal(t,e,n)},t.prototype.setElementProperty=function(t,e,n){
                +var o=i.getDebugNode(t);r.isPresent(o)&&o instanceof i.DebugElement&&(o.properties[e]=n),this._delegate.setElementProperty(t,e,n)},t.prototype.setElementAttribute=function(t,e,n){var o=i.getDebugNode(t);r.isPresent(o)&&o instanceof i.DebugElement&&(o.attributes[e]=n),this._delegate.setElementAttribute(t,e,n)},t.prototype.setBindingDebugInfo=function(t,e,n){this._delegate.setBindingDebugInfo(t,e,n)},t.prototype.setElementClass=function(t,e,n){this._delegate.setElementClass(t,e,n)},t.prototype.setElementStyle=function(t,e,n){this._delegate.setElementStyle(t,e,n)},t.prototype.invokeElementMethod=function(t,e,n){this._delegate.invokeElementMethod(t,e,n)},t.prototype.setText=function(t,e){this._delegate.setText(t,e)},t}();e.DebugDomRenderer=s},function(t,e,n){"use strict";var r=n(200),i=function(){function t(){}return t.prototype.getTitle=function(){return r.DOM.getTitle()},t.prototype.setTitle=function(t){r.DOM.setTitle(t)},t}();e.Title=i},function(t,e,n){"use strict";function r(t){a.ng=new s.AngularTools(t)}function i(){delete a.ng}var o=n(5),s=n(230),a=o.global;e.enableDebugTools=r,e.disableDebugTools=i},function(t,e,n){"use strict";var r=n(59),i=n(5),o=n(231),s=n(200),a=function(){function t(t,e){this.msPerTick=t,this.numTicks=e}return t}();e.ChangeDetectionPerfRecord=a;var u=function(){function t(t){this.profiler=new c(t)}return t}();e.AngularTools=u;var c=function(){function t(t){this.appRef=t.injector.get(r.ApplicationRef)}return t.prototype.timeChangeDetection=function(t){var e=i.isPresent(t)&&t.record,n="Change Detection",r=i.isPresent(o.window.console.profile);e&&r&&o.window.console.profile(n);for(var u=s.DOM.performanceNow(),c=0;5>c||s.DOM.performanceNow()-u<500;)this.appRef.tick(),c++;var p=s.DOM.performanceNow();e&&r&&o.window.console.profileEnd(n);var l=(p-u)/c;return o.window.console.log("ran "+c+" change detection cycles"),o.window.console.log(i.NumberWrapper.toFixed(l,2)+" ms per check"),new a(l,c)},t}();e.AngularProfiler=c},function(t,e){"use strict";var n=window;e.window=n,e.document=window.document,e.location=window.location,e.gc=window.gc?function(){return window.gc()}:function(){return null},e.performance=window.performance?window.performance:null,e.Event=window.Event,e.MouseEvent=window.MouseEvent,e.KeyboardEvent=window.KeyboardEvent,e.EventTarget=window.EventTarget,e.History=window.History,e.Location=window.Location,e.EventListener=window.EventListener},function(t,e,n){"use strict";var r=n(2),i=n(233),o=n(241),s=n(245),a=n(244),u=n(246),c=n(239),p=n(243),l=n(235);e.Request=l.Request;var h=n(242);e.Response=h.Response;var f=n(234);e.Connection=f.Connection,e.ConnectionBackend=f.ConnectionBackend;var d=n(244);e.BrowserXhr=d.BrowserXhr;var v=n(239);e.BaseRequestOptions=v.BaseRequestOptions,e.RequestOptions=v.RequestOptions;var y=n(243);e.BaseResponseOptions=y.BaseResponseOptions,e.ResponseOptions=y.ResponseOptions;var m=n(241);e.XHRBackend=m.XHRBackend,e.XHRConnection=m.XHRConnection;var g=n(245);e.JSONPBackend=g.JSONPBackend,e.JSONPConnection=g.JSONPConnection;var _=n(233);e.Http=_.Http,e.Jsonp=_.Jsonp;var b=n(236);e.Headers=b.Headers;var P=n(238);e.ResponseType=P.ResponseType,e.ReadyState=P.ReadyState,e.RequestMethod=P.RequestMethod;var E=n(240);e.URLSearchParams=E.URLSearchParams,e.HTTP_PROVIDERS=[r.provide(i.Http,{useFactory:function(t,e){return new i.Http(t,e)},deps:[o.XHRBackend,c.RequestOptions]}),a.BrowserXhr,r.provide(c.RequestOptions,{useClass:c.BaseRequestOptions}),r.provide(p.ResponseOptions,{useClass:p.BaseResponseOptions}),o.XHRBackend],e.HTTP_BINDINGS=e.HTTP_PROVIDERS,e.JSONP_PROVIDERS=[r.provide(i.Jsonp,{useFactory:function(t,e){return new i.Jsonp(t,e)},deps:[s.JSONPBackend,c.RequestOptions]}),u.BrowserJsonp,r.provide(c.RequestOptions,{useClass:c.BaseRequestOptions}),r.provide(p.ResponseOptions,{useClass:p.BaseResponseOptions}),r.provide(s.JSONPBackend,{useClass:s.JSONPBackend_})],e.JSON_BINDINGS=e.JSONP_PROVIDERS},function(t,e,n){"use strict";function r(t,e){return t.createConnection(e).response}function i(t,e,n,r){var i=t;return u.isPresent(e)?i.merge(new f.RequestOptions({method:e.method||n,url:e.url||r,search:e.search,headers:e.headers,body:e.body})):u.isPresent(n)?i.merge(new f.RequestOptions({method:n,url:r})):i.merge(new f.RequestOptions({url:r}))}var o=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},s=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},a=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},u=n(5),c=n(12),p=n(2),l=n(234),h=n(235),f=n(239),d=n(238),v=function(){function t(t,e){this._backend=t,this._defaultOptions=e}return t.prototype.request=function(t,e){var n;if(u.isString(t))n=r(this._backend,new h.Request(i(this._defaultOptions,e,d.RequestMethod.Get,t)));else{if(!(t instanceof h.Request))throw c.makeTypeError("First argument must be a url string or Request instance.");n=r(this._backend,t)}return n},t.prototype.get=function(t,e){return r(this._backend,new h.Request(i(this._defaultOptions,e,d.RequestMethod.Get,t)))},t.prototype.post=function(t,e,n){return r(this._backend,new h.Request(i(this._defaultOptions.merge(new f.RequestOptions({body:e})),n,d.RequestMethod.Post,t)))},t.prototype.put=function(t,e,n){return r(this._backend,new h.Request(i(this._defaultOptions.merge(new f.RequestOptions({body:e})),n,d.RequestMethod.Put,t)))},t.prototype["delete"]=function(t,e){return r(this._backend,new h.Request(i(this._defaultOptions,e,d.RequestMethod.Delete,t)))},t.prototype.patch=function(t,e,n){return r(this._backend,new h.Request(i(this._defaultOptions.merge(new f.RequestOptions({body:e})),n,d.RequestMethod.Patch,t)))},t.prototype.head=function(t,e){return r(this._backend,new h.Request(i(this._defaultOptions,e,d.RequestMethod.Head,t)))},t=s([p.Injectable(),a("design:paramtypes",[l.ConnectionBackend,f.RequestOptions])],t)}();e.Http=v;var y=function(t){function e(e,n){t.call(this,e,n)}return o(e,t),e.prototype.request=function(t,e){var n;if(u.isString(t)&&(t=new h.Request(i(this._defaultOptions,e,d.RequestMethod.Get,t))),!(t instanceof h.Request))throw c.makeTypeError("First argument must be a url string or Request instance.");return t.method!==d.RequestMethod.Get&&c.makeTypeError("JSONP requests must use GET request method."),n=r(this._backend,t)},e=s([p.Injectable(),a("design:paramtypes",[l.ConnectionBackend,f.RequestOptions])],e)}(v);e.Jsonp=y},function(t,e){"use strict";var n=function(){function t(){}return t}();e.ConnectionBackend=n;var r=function(){function t(){}return t}();e.Connection=r},function(t,e,n){"use strict";var r=n(236),i=n(237),o=n(5),s=function(){function t(t){var e=t.url;if(this.url=t.url,o.isPresent(t.search)){var n=t.search.toString();if(n.length>0){var s="?";o.StringWrapper.contains(this.url,"?")&&(s="&"==this.url[this.url.length-1]?"":"&"),this.url=e+s+n}}this._body=t.body,this.method=i.normalizeMethodName(t.method),this.headers=new r.Headers(t.headers)}return t.prototype.text=function(){return o.isPresent(this._body)?this._body.toString():""},t}();e.Request=s},function(t,e,n){"use strict";var r=n(5),i=n(12),o=n(15),s=function(){function t(e){var n=this;return e instanceof t?void(this._headersMap=e._headersMap):(this._headersMap=new o.Map,void(r.isBlank(e)||o.StringMapWrapper.forEach(e,function(t,e){n._headersMap.set(e,o.isListLikeIterable(t)?t:[t])})))}return t.fromResponseHeaderString=function(e){return e.trim().split("\n").map(function(t){return t.split(":")}).map(function(t){var e=t[0],n=t.slice(1);return[e.trim(),n.join(":").trim()]}).reduce(function(t,e){var n=e[0],r=e[1];return!t.set(n,r)&&t},new t)},t.prototype.append=function(t,e){var n=this._headersMap.get(t),r=o.isListLikeIterable(n)?n:[];r.push(e),this._headersMap.set(t,r)},t.prototype["delete"]=function(t){this._headersMap["delete"](t)},t.prototype.forEach=function(t){this._headersMap.forEach(t)},t.prototype.get=function(t){return o.ListWrapper.first(this._headersMap.get(t))},t.prototype.has=function(t){return this._headersMap.has(t)},t.prototype.keys=function(){return o.MapWrapper.keys(this._headersMap)},t.prototype.set=function(t,e){var n=[];if(o.isListLikeIterable(e)){var r=e.join(",");n.push(r)}else n.push(e);this._headersMap.set(t,n)},t.prototype.values=function(){return o.MapWrapper.values(this._headersMap)},t.prototype.toJSON=function(){var t={};return this._headersMap.forEach(function(e,n){var r=[];o.iterateListLike(e,function(t){return r=o.ListWrapper.concat(r,t.split(","))}),t[n]=r}),t},t.prototype.getAll=function(t){var e=this._headersMap.get(t);return o.isListLikeIterable(e)?e:[]},t.prototype.entries=function(){throw new i.BaseException('"entries" method is not implemented on Headers class')},t}();e.Headers=s},function(t,e,n){"use strict";function r(t){if(o.isString(t)){var e=t;if(t=t.replace(/(\w)(\w*)/g,function(t,e,n){return e.toUpperCase()+n.toLowerCase()}),t=s.RequestMethod[t],"number"!=typeof t)throw a.makeTypeError('Invalid request method. The method "'+e+'" is not supported.')}return t}function i(t){return"responseURL"in t?t.responseURL:/^X-Request-URL:/m.test(t.getAllResponseHeaders())?t.getResponseHeader("X-Request-URL"):void 0}var o=n(5),s=n(238),a=n(12);e.normalizeMethodName=r,e.isSuccess=function(t){return t>=200&&300>t},e.getResponseURL=i;var u=n(5);e.isJsObject=u.isJsObject},function(t,e){"use strict";!function(t){t[t.Get=0]="Get",t[t.Post=1]="Post",t[t.Put=2]="Put",t[t.Delete=3]="Delete",t[t.Options=4]="Options",t[t.Head=5]="Head",t[t.Patch=6]="Patch"}(e.RequestMethod||(e.RequestMethod={}));e.RequestMethod;!function(t){t[t.Unsent=0]="Unsent",t[t.Open=1]="Open",t[t.HeadersReceived=2]="HeadersReceived",t[t.Loading=3]="Loading",t[t.Done=4]="Done",t[t.Cancelled=5]="Cancelled"}(e.ReadyState||(e.ReadyState={}));e.ReadyState;!function(t){t[t.Basic=0]="Basic",t[t.Cors=1]="Cors",t[t.Default=2]="Default",t[t.Error=3]="Error",t[t.Opaque=4]="Opaque"}(e.ResponseType||(e.ResponseType={}));e.ResponseType},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=n(236),u=n(238),c=n(2),p=n(240),l=n(237),h=function(){function t(t){var e=void 0===t?{}:t,n=e.method,r=e.headers,i=e.body,o=e.url,a=e.search;this.method=s.isPresent(n)?l.normalizeMethodName(n):null,this.headers=s.isPresent(r)?r:null,this.body=s.isPresent(i)?i:null,this.url=s.isPresent(o)?o:null,this.search=s.isPresent(a)?s.isString(a)?new p.URLSearchParams(a):a:null}return t.prototype.merge=function(e){return new t({method:s.isPresent(e)&&s.isPresent(e.method)?e.method:this.method,headers:s.isPresent(e)&&s.isPresent(e.headers)?e.headers:this.headers,body:s.isPresent(e)&&s.isPresent(e.body)?e.body:this.body,url:s.isPresent(e)&&s.isPresent(e.url)?e.url:this.url,search:s.isPresent(e)&&s.isPresent(e.search)?s.isString(e.search)?new p.URLSearchParams(e.search):e.search.clone():this.search})},t}();e.RequestOptions=h;var f=function(t){function e(){t.call(this,{method:u.RequestMethod.Get,headers:new a.Headers})}return r(e,t),e=i([c.Injectable(),o("design:paramtypes",[])],e)}(h);e.BaseRequestOptions=f},function(t,e,n){"use strict";function r(t){void 0===t&&(t="");var e=new o.Map;if(t.length>0){var n=t.split("&");n.forEach(function(t){var n=t.split("="),r=n[0],o=n[1],s=i.isPresent(e.get(r))?e.get(r):[];s.push(o),e.set(r,s)})}return e}var i=n(5),o=n(15),s=function(){function t(t){void 0===t&&(t=""),this.rawParams=t,this.paramsMap=r(t)}return t.prototype.clone=function(){var e=new t;return e.appendAll(this),e},t.prototype.has=function(t){return this.paramsMap.has(t)},t.prototype.get=function(t){var e=this.paramsMap.get(t);return o.isListLikeIterable(e)?o.ListWrapper.first(e):null},t.prototype.getAll=function(t){var e=this.paramsMap.get(t);return i.isPresent(e)?e:[]},t.prototype.set=function(t,e){var n=this.paramsMap.get(t),r=i.isPresent(n)?n:[];o.ListWrapper.clear(r),r.push(e),this.paramsMap.set(t,r)},t.prototype.setAll=function(t){var e=this;t.paramsMap.forEach(function(t,n){var r=e.paramsMap.get(n),s=i.isPresent(r)?r:[];o.ListWrapper.clear(s),s.push(t[0]),e.paramsMap.set(n,s)})},t.prototype.append=function(t,e){var n=this.paramsMap.get(t),r=i.isPresent(n)?n:[];r.push(e),this.paramsMap.set(t,r)},t.prototype.appendAll=function(t){var e=this;t.paramsMap.forEach(function(t,n){for(var r=e.paramsMap.get(n),o=i.isPresent(r)?r:[],s=0;s<t.length;++s)o.push(t[s]);e.paramsMap.set(n,o)})},t.prototype.replaceAll=function(t){var e=this;t.paramsMap.forEach(function(t,n){var r=e.paramsMap.get(n),s=i.isPresent(r)?r:[];o.ListWrapper.clear(s);for(var a=0;a<t.length;++a)s.push(t[a]);e.paramsMap.set(n,s)})},t.prototype.toString=function(){var t=[];return this.paramsMap.forEach(function(e,n){e.forEach(function(e){return t.push(n+"="+e)})}),t.join("&")},t.prototype["delete"]=function(t){this.paramsMap["delete"](t)},t}();e.URLSearchParams=s},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(238),s=n(242),a=n(236),u=n(243),c=n(2),p=n(244),l=n(5),h=n(42),f=n(237),d=function(){function t(t,e,n){var r=this;this.request=t,this.response=new h.Observable(function(i){var c=e.build();c.open(o.RequestMethod[t.method].toUpperCase(),t.url);var p=function(){var t=l.isPresent(c.response)?c.response:c.responseText,e=a.Headers.fromResponseHeaderString(c.getAllResponseHeaders()),r=f.getResponseURL(c),o=1223===c.status?204:c.status;0===o&&(o=t?200:0);var p=new u.ResponseOptions({body:t,status:o,headers:e,url:r});l.isPresent(n)&&(p=n.merge(p));var h=new s.Response(p);return f.isSuccess(o)?(i.next(h),void i.complete()):void i.error(h)},h=function(t){var e=new u.ResponseOptions({body:t,type:o.ResponseType.Error});l.isPresent(n)&&(e=n.merge(e)),i.error(new s.Response(e))};return l.isPresent(t.headers)&&t.headers.forEach(function(t,e){return c.setRequestHeader(e,t.join(","))}),c.addEventListener("load",p),c.addEventListener("error",h),c.send(r.request.text()),function(){c.removeEventListener("load",p),c.removeEventListener("error",h),c.abort()}})}return t}();e.XHRConnection=d;var v=function(){function t(t,e){this._browserXHR=t,this._baseResponseOptions=e}return t.prototype.createConnection=function(t){return new d(t,this._browserXHR,this._baseResponseOptions)},t=r([c.Injectable(),i("design:paramtypes",[p.BrowserXhr,u.ResponseOptions])],t)}();e.XHRBackend=v},function(t,e,n){"use strict";var r=n(5),i=n(12),o=n(237),s=function(){function t(t){this._body=t.body,this.status=t.status,this.ok=this.status>=200&&this.status<=299,this.statusText=t.statusText,this.headers=t.headers,this.type=t.type,this.url=t.url}return t.prototype.blob=function(){throw new i.BaseException('"blob()" method not implemented on Response superclass')},t.prototype.json=function(){var t;return o.isJsObject(this._body)?t=this._body:r.isString(this._body)&&(t=r.Json.parse(this._body)),t},t.prototype.text=function(){return this._body.toString()},t.prototype.arrayBuffer=function(){throw new i.BaseException('"arrayBuffer()" method not implemented on Response superclass')},t}();e.Response=s},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(2),a=n(5),u=n(236),c=n(238),p=function(){function t(t){var e=void 0===t?{}:t,n=e.body,r=e.status,i=e.headers,o=e.statusText,s=e.type,u=e.url;this.body=a.isPresent(n)?n:null,this.status=a.isPresent(r)?r:null,this.headers=a.isPresent(i)?i:null,this.statusText=a.isPresent(o)?o:null,this.type=a.isPresent(s)?s:null,this.url=a.isPresent(u)?u:null}return t.prototype.merge=function(e){return new t({body:a.isPresent(e)&&a.isPresent(e.body)?e.body:this.body,status:a.isPresent(e)&&a.isPresent(e.status)?e.status:this.status,headers:a.isPresent(e)&&a.isPresent(e.headers)?e.headers:this.headers,statusText:a.isPresent(e)&&a.isPresent(e.statusText)?e.statusText:this.statusText,type:a.isPresent(e)&&a.isPresent(e.type)?e.type:this.type,url:a.isPresent(e)&&a.isPresent(e.url)?e.url:this.url})},t}();e.ResponseOptions=p;var l=function(t){function e(){t.call(this,{status:200,statusText:"Ok",type:c.ResponseType.Default,headers:new u.Headers})}return r(e,t),e=i([s.Injectable(),o("design:paramtypes",[])],e)}(p);e.BaseResponseOptions=l},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=function(){function t(){}return t.prototype.build=function(){return new XMLHttpRequest},t=r([o.Injectable(),i("design:paramtypes",[])],t)}();e.BrowserXhr=s},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(234),a=n(238),u=n(242),c=n(243),p=n(2),l=n(246),h=n(12),f=n(5),d=n(42),v="JSONP injected script did not invoke callback.",y="JSONP requests must use GET request method.",m=function(){function t(){}return t}();e.JSONPConnection=m;var g=function(t){function e(e,n,r){var i=this;if(t.call(this),this._dom=n,this.baseResponseOptions=r,this._finished=!1,e.method!==a.RequestMethod.Get)throw h.makeTypeError(y);this.request=e,this.response=new d.Observable(function(t){i.readyState=a.ReadyState.Loading;var o=i._id=n.nextRequestID();n.exposeConnection(o,i);var s=n.requestCallback(i._id),p=e.url;p.indexOf("=JSONP_CALLBACK&")>-1?p=f.StringWrapper.replace(p,"=JSONP_CALLBACK&","="+s+"&"):p.lastIndexOf("=JSONP_CALLBACK")===p.length-"=JSONP_CALLBACK".length&&(p=p.substring(0,p.length-"=JSONP_CALLBACK".length)+("="+s));var l=i._script=n.build(p),h=function(e){if(i.readyState!==a.ReadyState.Cancelled){if(i.readyState=a.ReadyState.Done,n.cleanup(l),!i._finished){var o=new c.ResponseOptions({body:v,type:a.ResponseType.Error,url:p});return f.isPresent(r)&&(o=r.merge(o)),void t.error(new u.Response(o))}var s=new c.ResponseOptions({body:i._responseData,url:p});f.isPresent(i.baseResponseOptions)&&(s=i.baseResponseOptions.merge(s)),t.next(new u.Response(s)),t.complete()}},d=function(e){if(i.readyState!==a.ReadyState.Cancelled){i.readyState=a.ReadyState.Done,n.cleanup(l);var o=new c.ResponseOptions({body:e.message,type:a.ResponseType.Error});f.isPresent(r)&&(o=r.merge(o)),t.error(new u.Response(o))}};return l.addEventListener("load",h),l.addEventListener("error",d),n.send(l),function(){i.readyState=a.ReadyState.Cancelled,l.removeEventListener("load",h),l.removeEventListener("error",d),f.isPresent(l)&&i._dom.cleanup(l)}})}return r(e,t),e.prototype.finished=function(t){this._finished=!0,this._dom.removeConnection(this._id),this.readyState!==a.ReadyState.Cancelled&&(this._responseData=t)},e}(m);e.JSONPConnection_=g;var _=function(t){function e(){t.apply(this,arguments)}return r(e,t),e}(s.ConnectionBackend);e.JSONPBackend=_;var b=function(t){function e(e,n){t.call(this),this._browserJSONP=e,this._baseResponseOptions=n}return r(e,t),e.prototype.createConnection=function(t){return new g(t,this._browserJSONP,this._baseResponseOptions)},e=i([p.Injectable(),o("design:paramtypes",[l.BrowserJsonp,c.ResponseOptions])],e)}(_);e.JSONPBackend_=b},function(t,e,n){"use strict";function r(){return null===c&&(c=a.global[e.JSONP_HOME]={}),c}var i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(2),a=n(5),u=0;e.JSONP_HOME="__ng_jsonp__";var c=null,p=function(){function t(){}return t.prototype.build=function(t){var e=document.createElement("script");return e.src=t,e},t.prototype.nextRequestID=function(){return"__req"+u++},t.prototype.requestCallback=function(t){return e.JSONP_HOME+"."+t+".finished"},t.prototype.exposeConnection=function(t,e){var n=r();n[t]=e},t.prototype.removeConnection=function(t){var e=r();e[t]=null},t.prototype.send=function(t){document.body.appendChild(t)},t.prototype.cleanup=function(t){t.parentNode&&t.parentNode.removeChild(t)},t=i([s.Injectable(),o("design:paramtypes",[])],t)}();e.BrowserJsonp=p},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}var i=n(248);e.Router=i.Router;var o=n(272);e.RouterOutlet=o.RouterOutlet;var s=n(274);e.RouterLink=s.RouterLink;var a=n(260);e.RouteParams=a.RouteParams,e.RouteData=a.RouteData;var u=n(256);e.RouteRegistry=u.RouteRegistry,e.ROUTER_PRIMARY_COMPONENT=u.ROUTER_PRIMARY_COMPONENT,r(n(269));var c=n(273);e.CanActivate=c.CanActivate;var p=n(260);e.Instruction=p.Instruction,e.ComponentInstruction=p.ComponentInstruction;var l=n(2);e.OpaqueToken=l.OpaqueToken;var h=n(275);e.ROUTER_PROVIDERS_COMMON=h.ROUTER_PROVIDERS_COMMON;var f=n(276);e.ROUTER_PROVIDERS=f.ROUTER_PROVIDERS,e.ROUTER_BINDINGS=f.ROUTER_BINDINGS;var d=n(272),v=n(274),y=n(5);e.ROUTER_DIRECTIVES=y.CONST_EXPR([d.RouterOutlet,v.RouterLink])},function(t,e,n){"use strict";function r(t,e){var n=y;return p.isBlank(t.component)?n:(p.isPresent(t.child)&&(n=r(t.child,p.isPresent(e)?e.child:null)),n.then(function(n){if(0==n)return!1;if(t.component.reuse)return!0;var r=v.getCanActivateHook(t.component.componentType);return p.isPresent(r)?r(t.component,p.isPresent(e)?e.component:null):!0}))}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},s=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},a=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},u=n(40),c=n(15),p=n(5),l=n(12),h=n(249),f=n(2),d=n(256),v=n(270),y=u.PromiseWrapper.resolve(!0),m=u.PromiseWrapper.resolve(!1),g=function(){function t(t,e,n,r){this.registry=t,this.parent=e,this.hostComponent=n,this.root=r,this.navigating=!1,this.currentInstruction=null,this._currentNavigation=y,this._outlet=null,this._auxRouters=new c.Map,this._subject=new u.EventEmitter}return t.prototype.childRouter=function(t){return this._childRouter=new b(this,t)},t.prototype.auxRouter=function(t){return new b(this,t)},t.prototype.registerPrimaryOutlet=function(t){if(p.isPresent(t.name))throw new l.BaseException("registerPrimaryOutlet expects to be called with an unnamed outlet.");if(p.isPresent(this._outlet))throw new l.BaseException("Primary outlet is already registered.");return this._outlet=t,p.isPresent(this.currentInstruction)?this.commit(this.currentInstruction,!1):y},t.prototype.unregisterPrimaryOutlet=function(t){if(p.isPresent(t.name))throw new l.BaseException("registerPrimaryOutlet expects to be called with an unnamed outlet.");this._outlet=null},t.prototype.registerAuxOutlet=function(t){var e=t.name;if(p.isBlank(e))throw new l.BaseException("registerAuxOutlet expects to be called with an outlet with a name.");var n=this.auxRouter(this.hostComponent);this._auxRouters.set(e,n),n._outlet=t;var r;return p.isPresent(this.currentInstruction)&&p.isPresent(r=this.currentInstruction.auxInstruction[e])?n.commit(r):y},t.prototype.isRouteActive=function(t){var e=this,n=this;if(p.isBlank(this.currentInstruction))return!1;for(;p.isPresent(n.parent)&&p.isPresent(t.child);)n=n.parent,t=t.child;if(p.isBlank(t.component)||p.isBlank(this.currentInstruction.component)||this.currentInstruction.component.routeName!=t.component.routeName)return!1;var r=!0;return p.isPresent(this.currentInstruction.component.params)&&c.StringMapWrapper.forEach(t.component.params,function(t,n){e.currentInstruction.component.params[n]!==t&&(r=!1)}),r},t.prototype.config=function(t){var e=this;return t.forEach(function(t){e.registry.config(e.hostComponent,t)}),this.renavigate()},t.prototype.navigate=function(t){var e=this.generate(t);return this.navigateByInstruction(e,!1)},t.prototype.navigateByUrl=function(t,e){var n=this;return void 0===e&&(e=!1),this._currentNavigation=this._currentNavigation.then(function(r){return n.lastNavigationAttempt=t,n._startNavigating(),n._afterPromiseFinishNavigating(n.recognize(t).then(function(t){return p.isBlank(t)?!1:n._navigate(t,e)}))})},t.prototype.navigateByInstruction=function(t,e){var n=this;return void 0===e&&(e=!1),p.isBlank(t)?m:this._currentNavigation=this._currentNavigation.then(function(r){return n._startNavigating(),n._afterPromiseFinishNavigating(n._navigate(t,e))})},t.prototype._settleInstruction=function(t){var e=this;return t.resolveComponent().then(function(n){var r=[];return p.isPresent(t.component)&&(t.component.reuse=!1),p.isPresent(t.child)&&r.push(e._settleInstruction(t.child)),c.StringMapWrapper.forEach(t.auxInstruction,function(t,n){r.push(e._settleInstruction(t))}),u.PromiseWrapper.all(r)})},t.prototype._navigate=function(t,e){var n=this;return this._settleInstruction(t).then(function(e){return n._routerCanReuse(t)}).then(function(e){return n._canActivate(t)}).then(function(r){return r?n._routerCanDeactivate(t).then(function(r){return r?n.commit(t,e).then(function(e){return n._emitNavigationFinish(t.toRootUrl()),!0}):void 0}):!1})},t.prototype._emitNavigationFinish=function(t){u.ObservableWrapper.callEmit(this._subject,t)},t.prototype._emitNavigationFail=function(t){u.ObservableWrapper.callError(this._subject,t)},t.prototype._afterPromiseFinishNavigating=function(t){var e=this;return u.PromiseWrapper.catchError(t.then(function(t){return e._finishNavigating()}),function(t){throw e._finishNavigating(),t})},t.prototype._routerCanReuse=function(t){var e=this;return p.isBlank(this._outlet)?m:p.isBlank(t.component)?y:this._outlet.routerCanReuse(t.component).then(function(n){return t.component.reuse=n,n&&p.isPresent(e._childRouter)&&p.isPresent(t.child)?e._childRouter._routerCanReuse(t.child):void 0})},t.prototype._canActivate=function(t){return r(t,this.currentInstruction)},t.prototype._routerCanDeactivate=function(t){var e=this;if(p.isBlank(this._outlet))return y;var n,r=null,i=!1,o=null;return p.isPresent(t)&&(r=t.child,o=t.component,i=p.isBlank(t.component)||t.component.reuse),n=i?y:this._outlet.routerCanDeactivate(o),n.then(function(t){return 0==t?!1:p.isPresent(e._childRouter)?e._childRouter._routerCanDeactivate(r):!0})},t.prototype.commit=function(t,e){var n=this;void 0===e&&(e=!1),this.currentInstruction=t;var r=y;if(p.isPresent(this._outlet)&&p.isPresent(t.component)){var i=t.component;r=i.reuse?this._outlet.reuse(i):this.deactivate(t).then(function(t){return n._outlet.activate(i)}),p.isPresent(t.child)&&(r=r.then(function(e){return p.isPresent(n._childRouter)?n._childRouter.commit(t.child):void 0}))}var o=[];return this._auxRouters.forEach(function(e,n){p.isPresent(t.auxInstruction[n])&&o.push(e.commit(t.auxInstruction[n]))}),r.then(function(t){return u.PromiseWrapper.all(o)})},t.prototype._startNavigating=function(){this.navigating=!0},t.prototype._finishNavigating=function(){this.navigating=!1},t.prototype.subscribe=function(t,e){return u.ObservableWrapper.subscribe(this._subject,t,e)},t.prototype.deactivate=function(t){var e=this,n=null,r=null;p.isPresent(t)&&(n=t.child,r=t.component);var i=y;return p.isPresent(this._childRouter)&&(i=this._childRouter.deactivate(n)),p.isPresent(this._outlet)&&(i=i.then(function(t){return e._outlet.deactivate(r)})),i},t.prototype.recognize=function(t){var e=this._getAncestorInstructions();return this.registry.recognize(t,e)},t.prototype._getAncestorInstructions=function(){for(var t=[this.currentInstruction],e=this;p.isPresent(e=e.parent);)t.unshift(e.currentInstruction);return t},t.prototype.renavigate=function(){return p.isBlank(this.lastNavigationAttempt)?this._currentNavigation:this.navigateByUrl(this.lastNavigationAttempt)},t.prototype.generate=function(t){var e=this._getAncestorInstructions();return this.registry.generate(t,e)},t=o([f.Injectable(),s("design:paramtypes",[d.RouteRegistry,t,Object,t])],t)}();e.Router=g;var _=function(t){function e(e,n,r){var i=this;t.call(this,e,null,r),this.root=this,this._location=n,this._locationSub=this._location.subscribe(function(t){i.recognize(t.url).then(function(e){p.isPresent(e)?i.navigateByInstruction(e,p.isPresent(t.pop)).then(function(n){if(!p.isPresent(t.pop)||"hashchange"==t.type){var r=e.toUrlPath(),o=e.toUrlQuery();r.length>0&&"/"!=r[0]&&(r="/"+r),"hashchange"==t.type?e.toRootUrl()!=i._location.path()&&i._location.replaceState(r,o):i._location.go(r,o)}}):i._emitNavigationFail(t.url)})}),this.registry.configFromComponent(r),this.navigateByUrl(n.path())}return i(e,t),e.prototype.commit=function(e,n){var r=this;void 0===n&&(n=!1);var i=e.toUrlPath(),o=e.toUrlQuery();i.length>0&&"/"!=i[0]&&(i="/"+i);var s=t.prototype.commit.call(this,e);return n||(s=s.then(function(t){
                +r._location.go(i,o)})),s},e.prototype.dispose=function(){p.isPresent(this._locationSub)&&(u.ObservableWrapper.dispose(this._locationSub),this._locationSub=null)},e=o([f.Injectable(),a(2,f.Inject(d.ROUTER_PRIMARY_COMPONENT)),s("design:paramtypes",[d.RouteRegistry,h.Location,p.Type])],e)}(g);e.RootRouter=_;var b=function(t){function e(e,n){t.call(this,e.registry,e,n,e.root),this.parent=e}return i(e,t),e.prototype.navigateByUrl=function(t,e){return void 0===e&&(e=!1),this.parent.navigateByUrl(t,e)},e.prototype.navigateByInstruction=function(t,e){return void 0===e&&(e=!1),this.parent.navigateByInstruction(t,e)},e}(g)},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}r(n(250))},function(t,e,n){"use strict";function r(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}r(n(251)),r(n(252)),r(n(253)),r(n(255)),r(n(254))},function(t,e){"use strict";var n=function(){function t(){}return Object.defineProperty(t.prototype,"pathname",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"search",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hash",{get:function(){return null},enumerable:!0,configurable:!0}),t}();e.PlatformLocation=n},function(t,e,n){"use strict";var r=n(5),i=n(2),o=function(){function t(){}return t}();e.LocationStrategy=o,e.APP_BASE_HREF=r.CONST_EXPR(new i.OpaqueToken("appBaseHref"))},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(2),u=n(252),c=n(254),p=n(251),l=n(5),h=function(t){function e(e,n){t.call(this),this._platformLocation=e,this._baseHref="",l.isPresent(n)&&(this._baseHref=n)}return r(e,t),e.prototype.onPopState=function(t){this._platformLocation.onPopState(t),this._platformLocation.onHashChange(t)},e.prototype.getBaseHref=function(){return this._baseHref},e.prototype.path=function(){var t=this._platformLocation.hash;return l.isPresent(t)||(t="#"),t.length>0?t.substring(1):t},e.prototype.prepareExternalUrl=function(t){var e=c.Location.joinWithSlash(this._baseHref,t);return e.length>0?"#"+e:e},e.prototype.pushState=function(t,e,n,r){var i=this.prepareExternalUrl(n+c.Location.normalizeQueryParams(r));0==i.length&&(i=this._platformLocation.pathname),this._platformLocation.pushState(t,e,i)},e.prototype.replaceState=function(t,e,n,r){var i=this.prepareExternalUrl(n+c.Location.normalizeQueryParams(r));0==i.length&&(i=this._platformLocation.pathname),this._platformLocation.replaceState(t,e,i)},e.prototype.forward=function(){this._platformLocation.forward()},e.prototype.back=function(){this._platformLocation.back()},e=i([a.Injectable(),s(1,a.Optional()),s(1,a.Inject(u.APP_BASE_HREF)),o("design:paramtypes",[p.PlatformLocation,String])],e)}(u.LocationStrategy);e.HashLocationStrategy=h},function(t,e,n){"use strict";function r(t,e){return t.length>0&&e.startsWith(t)?e.substring(t.length):e}function i(t){return/\/index.html$/g.test(t)?t.substring(0,t.length-11):t}var o=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},s=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},a=n(40),u=n(2),c=n(252),p=function(){function t(e){var n=this;this.platformStrategy=e,this._subject=new a.EventEmitter;var r=this.platformStrategy.getBaseHref();this._baseHref=t.stripTrailingSlash(i(r)),this.platformStrategy.onPopState(function(t){a.ObservableWrapper.callEmit(n._subject,{url:n.path(),pop:!0,type:t.type})})}return t.prototype.path=function(){return this.normalize(this.platformStrategy.path())},t.prototype.normalize=function(e){return t.stripTrailingSlash(r(this._baseHref,i(e)))},t.prototype.prepareExternalUrl=function(t){return t.length>0&&!t.startsWith("/")&&(t="/"+t),this.platformStrategy.prepareExternalUrl(t)},t.prototype.go=function(t,e){void 0===e&&(e=""),this.platformStrategy.pushState(null,"",t,e)},t.prototype.replaceState=function(t,e){void 0===e&&(e=""),this.platformStrategy.replaceState(null,"",t,e)},t.prototype.forward=function(){this.platformStrategy.forward()},t.prototype.back=function(){this.platformStrategy.back()},t.prototype.subscribe=function(t,e,n){return void 0===e&&(e=null),void 0===n&&(n=null),a.ObservableWrapper.subscribe(this._subject,t,e,n)},t.normalizeQueryParams=function(t){return t.length>0&&"?"!=t.substring(0,1)?"?"+t:t},t.joinWithSlash=function(t,e){if(0==t.length)return e;if(0==e.length)return t;var n=0;return t.endsWith("/")&&n++,e.startsWith("/")&&n++,2==n?t+e.substring(1):1==n?t+e:t+"/"+e},t.stripTrailingSlash=function(t){return/\/$/g.test(t)&&(t=t.substring(0,t.length-1)),t},t=o([u.Injectable(),s("design:paramtypes",[c.LocationStrategy])],t)}();e.Location=p},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},a=n(2),u=n(5),c=n(12),p=n(251),l=n(252),h=n(254),f=function(t){function e(e,n){if(t.call(this),this._platformLocation=e,u.isBlank(n)&&(n=this._platformLocation.getBaseHrefFromDOM()),u.isBlank(n))throw new c.BaseException("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");this._baseHref=n}return r(e,t),e.prototype.onPopState=function(t){this._platformLocation.onPopState(t),this._platformLocation.onHashChange(t)},e.prototype.getBaseHref=function(){return this._baseHref},e.prototype.prepareExternalUrl=function(t){return h.Location.joinWithSlash(this._baseHref,t)},e.prototype.path=function(){return this._platformLocation.pathname+h.Location.normalizeQueryParams(this._platformLocation.search)},e.prototype.pushState=function(t,e,n,r){var i=this.prepareExternalUrl(n+h.Location.normalizeQueryParams(r));this._platformLocation.pushState(t,e,i)},e.prototype.replaceState=function(t,e,n,r){var i=this.prepareExternalUrl(n+h.Location.normalizeQueryParams(r));this._platformLocation.replaceState(t,e,i)},e.prototype.forward=function(){this._platformLocation.forward()},e.prototype.back=function(){this._platformLocation.back()},e=i([a.Injectable(),s(1,a.Optional()),s(1,a.Inject(l.APP_BASE_HREF)),o("design:paramtypes",[p.PlatformLocation,String])],e)}(l.LocationStrategy);e.PathLocationStrategy=f},function(t,e,n){"use strict";function r(t){var e=[];return t.forEach(function(t){if(h.isString(t)){var n=t;e=e.concat(n.split("/"))}else e.push(t)}),e}function i(t){if(t=t.filter(function(t){return h.isPresent(t)}),0==t.length)return null;if(1==t.length)return t[0];var e=t[0],n=t.slice(1);return n.reduce(function(t,e){return-1==o(e.specificity,t.specificity)?e:t},e)}function o(t,e){for(var n=h.Math.min(t.length,e.length),r=0;n>r;r+=1){var i=h.StringWrapper.charCodeAt(t,r),o=h.StringWrapper.charCodeAt(e,r),s=o-i;if(0!=s)return s}return t.length-e.length}function s(t,e){if(h.isType(t)){var n=d.reflector.annotations(t);if(h.isPresent(n))for(var r=0;r<n.length;r++){var i=n[r];if(i instanceof y.RouteConfig)throw new f.BaseException('Child routes are not allowed for "'+e+'". Use "..." on the parent\'s route path.')}}}var a=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},u=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},c=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},p=n(15),l=n(40),h=n(5),f=n(12),d=n(18),v=n(2),y=n(257),m=n(258),g=n(261),_=n(260),b=n(268),P=n(259),E=l.PromiseWrapper.resolve(null);e.ROUTER_PRIMARY_COMPONENT=h.CONST_EXPR(new v.OpaqueToken("RouterPrimaryComponent"));var w=function(){function t(t){this._rootComponent=t,this._rules=new p.Map}return t.prototype.config=function(t,e){e=b.normalizeRouteConfig(e,this),e instanceof y.Route?b.assertComponentExists(e.component,e.path):e instanceof y.AuxRoute&&b.assertComponentExists(e.component,e.path);var n=this._rules.get(t);h.isBlank(n)&&(n=new g.RuleSet,this._rules.set(t,n));var r=n.config(e);e instanceof y.Route&&(r?s(e.component,e.path):this.configFromComponent(e.component))},t.prototype.configFromComponent=function(t){var e=this;if(h.isType(t)&&!this._rules.has(t)){var n=d.reflector.annotations(t);if(h.isPresent(n))for(var r=0;r<n.length;r++){var i=n[r];if(i instanceof y.RouteConfig){var o=i.configs;o.forEach(function(n){return e.config(t,n)})}}}},t.prototype.recognize=function(t,e){var n=P.parser.parse(t);return this._recognize(n,[])},t.prototype._recognize=function(t,e,n){var r=this;void 0===n&&(n=!1);var o=p.ListWrapper.last(e),s=h.isPresent(o)?o.component.componentType:this._rootComponent,a=this._rules.get(s);if(h.isBlank(a))return E;var u=n?a.recognizeAuxiliary(t):a.recognize(t),c=u.map(function(t){return t.then(function(t){if(t instanceof m.PathMatch){var n=e.length>0?[p.ListWrapper.last(e)]:[],i=r._auxRoutesToUnresolved(t.remainingAux,n),o=new _.ResolvedInstruction(t.instruction,null,i);if(h.isBlank(t.instruction)||t.instruction.terminal)return o;var s=e.concat([o]);return r._recognize(t.remaining,s).then(function(t){return h.isBlank(t)?null:t instanceof _.RedirectInstruction?t:(o.child=t,o)})}if(t instanceof m.RedirectMatch){var o=r.generate(t.redirectTo,e.concat([null]));return new _.RedirectInstruction(o.component,o.child,o.auxInstruction,t.specificity)}})});return!h.isBlank(t)&&""!=t.path||0!=u.length?l.PromiseWrapper.all(c).then(i):l.PromiseWrapper.resolve(this.generateDefault(s))},t.prototype._auxRoutesToUnresolved=function(t,e){var n=this,r={};return t.forEach(function(t){r[t.path]=new _.UnresolvedInstruction(function(){return n._recognize(t,e,!0)})}),r},t.prototype.generate=function(t,e,n){void 0===n&&(n=!1);var i,o=r(t);if(""==p.ListWrapper.first(o))o.shift(),i=p.ListWrapper.first(e),e=[];else if(i=e.length>0?e.pop():null,"."==p.ListWrapper.first(o))o.shift();else if(".."==p.ListWrapper.first(o))for(;".."==p.ListWrapper.first(o);){if(e.length<=0)throw new f.BaseException('Link "'+p.ListWrapper.toJSON(t)+'" has too many "../" segments.');i=e.pop(),o=p.ListWrapper.slice(o,1)}else{var s=p.ListWrapper.first(o),a=this._rootComponent,u=null;if(e.length>1){var c=e[e.length-1],l=e[e.length-2];a=c.component.componentType,u=l.component.componentType}else 1==e.length&&(a=e[0].component.componentType,u=this._rootComponent);var d=this.hasRoute(s,a),v=h.isPresent(u)&&this.hasRoute(s,u);if(v&&d){var y='Link "'+p.ListWrapper.toJSON(t)+'" is ambiguous, use "./" or "../" to disambiguate.';throw new f.BaseException(y)}v&&(i=e.pop())}if(""==o[o.length-1]&&o.pop(),o.length>0&&""==o[0]&&o.shift(),o.length<1){var y='Link "'+p.ListWrapper.toJSON(t)+'" must include a route name.';throw new f.BaseException(y)}for(var m=this._generate(o,e,i,n,t),g=e.length-1;g>=0;g--){var _=e[g];if(h.isBlank(_))break;m=_.replaceChild(m)}return m},t.prototype._generate=function(t,e,n,r,i){var o=this;void 0===r&&(r=!1);var s=this._rootComponent,a=null,u={},c=p.ListWrapper.last(e);if(h.isPresent(c)&&h.isPresent(c.component)&&(s=c.component.componentType),0==t.length){var l=this.generateDefault(s);if(h.isBlank(l))throw new f.BaseException('Link "'+p.ListWrapper.toJSON(i)+'" does not resolve to a terminal instruction.');return l}h.isPresent(n)&&!r&&(u=p.StringMapWrapper.merge(n.auxInstruction,u),a=n.component);var d=this._rules.get(s);if(h.isBlank(d))throw new f.BaseException('Component "'+h.getTypeNameForDebugging(s)+'" has no route config.');var v=0,y={};if(v<t.length&&h.isString(t[v])){var m=t[v];if(""==m||"."==m||".."==m)throw new f.BaseException('"'+m+'/" is only allowed at the beginning of a link DSL.');if(v+=1,v<t.length){var g=t[v];h.isStringMap(g)&&!h.isArray(g)&&(y=g,v+=1)}var b=(r?d.auxRulesByName:d.rulesByName).get(m);if(h.isBlank(b))throw new f.BaseException('Component "'+h.getTypeNameForDebugging(s)+'" has no route named "'+m+'".');if(h.isBlank(b.handler.componentType)){var E=b.generateComponentPathValues(y);return new _.UnresolvedInstruction(function(){return b.handler.resolveComponentType().then(function(s){return o._generate(t,e,n,r,i)})},E.urlPath,P.convertUrlParamsToArray(E.urlParams))}a=r?d.generateAuxiliary(m,y):d.generate(m,y)}for(;v<t.length&&h.isArray(t[v]);){var w=[c],C=this._generate(t[v],w,null,!0,i);u[C.component.urlPath]=C,v+=1}var R=new _.ResolvedInstruction(a,null,u);if(h.isPresent(a)&&h.isPresent(a.componentType)){var S=null;if(a.terminal)v>=t.length;else{var O=e.concat([R]),T=t.slice(v);S=this._generate(T,O,null,!1,i)}R.child=S}return R},t.prototype.hasRoute=function(t,e){var n=this._rules.get(e);return h.isBlank(n)?!1:n.hasRoute(t)},t.prototype.generateDefault=function(t){var e=this;if(h.isBlank(t))return null;var n=this._rules.get(t);if(h.isBlank(n)||h.isBlank(n.defaultRule))return null;var r=null;if(h.isPresent(n.defaultRule.handler.componentType)){var i=n.defaultRule.generate({});return n.defaultRule.terminal||(r=this.generateDefault(n.defaultRule.handler.componentType)),new _.DefaultInstruction(i,r)}return new _.UnresolvedInstruction(function(){return n.defaultRule.handler.resolveComponentType().then(function(n){return e.generateDefault(t)})})},t=a([v.Injectable(),c(0,v.Inject(e.ROUTER_PRIMARY_COMPONENT)),u("design:paramtypes",[h.Type])],t)}();e.RouteRegistry=w},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(5),a=function(){function t(t){this.configs=t}return t=i([s.CONST(),o("design:paramtypes",[Array])],t)}();e.RouteConfig=a;var u=function(){function t(t){var e=t.name,n=t.useAsDefault,r=t.path,i=t.regex,o=t.serializer,s=t.data;this.name=e,this.useAsDefault=n,this.path=r,this.regex=i,this.serializer=o,this.data=s}return t=i([s.CONST(),o("design:paramtypes",[Object])],t)}();e.AbstractRoute=u;var c=function(t){function e(e){var n=e.name,r=e.useAsDefault,i=e.path,o=e.regex,s=e.serializer,a=e.data,u=e.component;t.call(this,{name:n,useAsDefault:r,path:i,regex:o,serializer:s,data:a}),this.aux=null,this.component=u}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(u);e.Route=c;var p=function(t){function e(e){var n=e.name,r=e.useAsDefault,i=e.path,o=e.regex,s=e.serializer,a=e.data,u=e.component;t.call(this,{name:n,useAsDefault:r,path:i,regex:o,serializer:s,data:a}),this.component=u}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(u);e.AuxRoute=p;var l=function(t){function e(e){var n=e.name,r=e.useAsDefault,i=e.path,o=e.regex,s=e.serializer,a=e.data,u=e.loader;t.call(this,{name:n,useAsDefault:r,path:i,regex:o,serializer:s,data:a}),this.aux=null,this.loader=u}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(u);e.AsyncRoute=l;var h=function(t){function e(e){var n=e.name,r=e.useAsDefault,i=e.path,o=e.regex,s=e.serializer,a=e.data,u=e.redirectTo;t.call(this,{name:n,useAsDefault:r,path:i,regex:o,serializer:s,data:a}),this.redirectTo=u}return r(e,t),e=i([s.CONST(),o("design:paramtypes",[Object])],e)}(u);e.Redirect=h},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(5),o=n(12),s=n(41),a=n(15),u=n(259),c=n(260),p=function(){function t(){}return t}();e.RouteMatch=p;var l=function(t){function e(e,n,r){t.call(this),this.instruction=e,this.remaining=n,this.remainingAux=r}return r(e,t),e}(p);e.PathMatch=l;var h=function(t){function e(e,n){t.call(this),this.redirectTo=e,this.specificity=n}return r(e,t),e}(p);e.RedirectMatch=h;var f=function(){function t(t,e){this._pathRecognizer=t,this.redirectTo=e,this.hash=this._pathRecognizer.hash}return Object.defineProperty(t.prototype,"path",{get:function(){return this._pathRecognizer.toString()},set:function(t){throw new o.BaseException("you cannot set the path of a RedirectRule directly")},enumerable:!0,configurable:!0}),t.prototype.recognize=function(t){var e=null;return i.isPresent(this._pathRecognizer.matchUrl(t))&&(e=new h(this.redirectTo,this._pathRecognizer.specificity)),s.PromiseWrapper.resolve(e)},t.prototype.generate=function(t){throw new o.BaseException("Tried to generate a redirect.")},t}();e.RedirectRule=f;var d=function(){function t(t,e,n){this._routePath=t,this.handler=e,this._routeName=n,this._cache=new a.Map,this.specificity=this._routePath.specificity,this.hash=this._routePath.hash,this.terminal=this._routePath.terminal}return Object.defineProperty(t.prototype,"path",{get:function(){return this._routePath.toString()},set:function(t){throw new o.BaseException("you cannot set the path of a RouteRule directly")},enumerable:!0,configurable:!0}),t.prototype.recognize=function(t){var e=this,n=this._routePath.matchUrl(t);return i.isBlank(n)?null:this.handler.resolveComponentType().then(function(t){var r=e._getInstruction(n.urlPath,n.urlParams,n.allParams);return new l(r,n.rest,n.auxiliary)})},t.prototype.generate=function(t){var e=this._routePath.generateUrl(t),n=e.urlPath,r=e.urlParams;return this._getInstruction(n,u.convertUrlParamsToArray(r),t)},t.prototype.generateComponentPathValues=function(t){return this._routePath.generateUrl(t)},t.prototype._getInstruction=function(t,e,n){if(i.isBlank(this.handler.componentType))throw new o.BaseException("Tried to get instruction before the type was loaded.");var r=t+"?"+e.join("&");if(this._cache.has(r))return this._cache.get(r);var s=new c.ComponentInstruction(t,e,this.handler.data,this.handler.componentType,this.terminal,this.specificity,n,this._routeName);return this._cache.set(r,s),s},t}();e.RouteRule=d},function(t,e,n){"use strict";function r(t){var e=[];return p.isBlank(t)?[]:(c.StringMapWrapper.forEach(t,function(t,n){e.push(t===!0?n:n+"="+t)}),e)}function i(t,e){return void 0===e&&(e="&"),r(t).join(e)}function o(t){for(var e=new h(t[t.length-1]),n=t.length-2;n>=0;n-=1)e=new h(t[n],e);return e}function s(t){var e=p.RegExpWrapper.firstMatch(d,t);return p.isPresent(e)?e[0]:""}function a(t){var e=p.RegExpWrapper.firstMatch(v,t);return p.isPresent(e)?e[0]:""}var u=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},c=n(15),p=n(5),l=n(12);e.convertUrlParamsToArray=r,e.serializeParams=i;var h=function(){function t(t,e,n,r){void 0===e&&(e=null),void 0===n&&(n=p.CONST_EXPR([])),void 0===r&&(r=p.CONST_EXPR({})),this.path=t,this.child=e,this.auxiliary=n,this.params=r}return t.prototype.toString=function(){return this.path+this._matrixParamsToString()+this._auxToString()+this._childString()},t.prototype.segmentToString=function(){return this.path+this._matrixParamsToString()},t.prototype._auxToString=function(){return this.auxiliary.length>0?"("+this.auxiliary.map(function(t){return t.toString()}).join("//")+")":""},t.prototype._matrixParamsToString=function(){var t=i(this.params,";");return t.length>0?";"+t:""},t.prototype._childString=function(){return p.isPresent(this.child)?"/"+this.child.toString():""},t}();e.Url=h;var f=function(t){function e(e,n,r,i){void 0===n&&(n=null),void 0===r&&(r=p.CONST_EXPR([])),void 0===i&&(i=null),t.call(this,e,n,r,i)}return u(e,t),e.prototype.toString=function(){return this.path+this._auxToString()+this._childString()+this._queryParamsToString()},e.prototype.segmentToString=function(){return this.path+this._queryParamsToString()},e.prototype._queryParamsToString=function(){return p.isBlank(this.params)?"":"?"+i(this.params)},e}(h);e.RootUrl=f,e.pathSegmentsToUrl=o;var d=p.RegExpWrapper.create("^[^\\/\\(\\)\\?;=&#]+"),v=p.RegExpWrapper.create("^[^\\(\\)\\?;&#]+"),y=function(){function t(){}return t.prototype.peekStartsWith=function(t){return this._remaining.startsWith(t)},t.prototype.capture=function(t){if(!this._remaining.startsWith(t))throw new l.BaseException('Expected "'+t+'".');this._remaining=this._remaining.substring(t.length)},t.prototype.parse=function(t){return this._remaining=t,""==t||"/"==t?new h(""):this.parseRoot()},t.prototype.parseRoot=function(){this.peekStartsWith("/")&&this.capture("/");var t=s(this._remaining);this.capture(t);var e=[];this.peekStartsWith("(")&&(e=this.parseAuxiliaryRoutes()),this.peekStartsWith(";")&&this.parseMatrixParams();var n=null;this.peekStartsWith("/")&&!this.peekStartsWith("//")&&(this.capture("/"),n=this.parseSegment());var r=null;return this.peekStartsWith("?")&&(r=this.parseQueryParams()),new f(t,n,e,r)},t.prototype.parseSegment=function(){if(0==this._remaining.length)return null;this.peekStartsWith("/")&&this.capture("/");var t=s(this._remaining);this.capture(t);var e=null;this.peekStartsWith(";")&&(e=this.parseMatrixParams());var n=[];this.peekStartsWith("(")&&(n=this.parseAuxiliaryRoutes());var r=null;return this.peekStartsWith("/")&&!this.peekStartsWith("//")&&(this.capture("/"),r=this.parseSegment()),new h(t,r,n,e)},t.prototype.parseQueryParams=function(){var t={};for(this.capture("?"),this.parseQueryParam(t);this._remaining.length>0&&this.peekStartsWith("&");)this.capture("&"),this.parseQueryParam(t);return t},t.prototype.parseMatrixParams=function(){for(var t={};this._remaining.length>0&&this.peekStartsWith(";");)this.capture(";"),this.parseParam(t);return t},t.prototype.parseParam=function(t){var e=s(this._remaining);if(!p.isBlank(e)){this.capture(e);var n=!0;if(this.peekStartsWith("=")){this.capture("=");var r=s(this._remaining);p.isPresent(r)&&(n=r,this.capture(n))}t[e]=n}},t.prototype.parseQueryParam=function(t){var e=s(this._remaining);if(!p.isBlank(e)){this.capture(e);var n=!0;if(this.peekStartsWith("=")){this.capture("=");var r=a(this._remaining);p.isPresent(r)&&(n=r,this.capture(n))}t[e]=n}},t.prototype.parseAuxiliaryRoutes=function(){var t=[];for(this.capture("(");!this.peekStartsWith(")")&&this._remaining.length>0;)t.push(this.parseSegment()),this.peekStartsWith("//")&&this.capture("//");return this.capture(")"),t},t}();e.UrlParser=y,e.parser=new y},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=n(15),o=n(5),s=n(40),a=function(){function t(t){this.params=t}return t.prototype.get=function(t){return o.normalizeBlank(i.StringMapWrapper.get(this.params,t))},t}();e.RouteParams=a;var u=function(){function t(t){void 0===t&&(t=o.CONST_EXPR({})),this.data=t}return t.prototype.get=function(t){return o.normalizeBlank(i.StringMapWrapper.get(this.data,t))},t}();e.RouteData=u,e.BLANK_ROUTE_DATA=new u;var c=function(){function t(t,e,n){this.component=t,this.child=e,this.auxInstruction=n}return Object.defineProperty(t.prototype,"urlPath",{get:function(){return o.isPresent(this.component)?this.component.urlPath:""},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"urlParams",{get:function(){return o.isPresent(this.component)?this.component.urlParams:[]},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"specificity",{get:function(){var t="";return o.isPresent(this.component)&&(t+=this.component.specificity),o.isPresent(this.child)&&(t+=this.child.specificity),t},enumerable:!0,configurable:!0}),t.prototype.toRootUrl=function(){return this.toUrlPath()+this.toUrlQuery()},t.prototype._toNonRootUrl=function(){return this._stringifyPathMatrixAuxPrefixed()+(o.isPresent(this.child)?this.child._toNonRootUrl():"")},t.prototype.toUrlQuery=function(){return this.urlParams.length>0?"?"+this.urlParams.join("&"):""},t.prototype.replaceChild=function(t){return new p(this.component,t,this.auxInstruction)},t.prototype.toUrlPath=function(){return this.urlPath+this._stringifyAux()+(o.isPresent(this.child)?this.child._toNonRootUrl():"")},t.prototype.toLinkUrl=function(){return this.urlPath+this._stringifyAux()+(o.isPresent(this.child)?this.child._toLinkUrl():"")+this.toUrlQuery()},t.prototype._toLinkUrl=function(){return this._stringifyPathMatrixAuxPrefixed()+(o.isPresent(this.child)?this.child._toLinkUrl():"")},t.prototype._stringifyPathMatrixAuxPrefixed=function(){var t=this._stringifyPathMatrixAux();return t.length>0&&(t="/"+t),t},t.prototype._stringifyMatrixParams=function(){return this.urlParams.length>0?";"+this.urlParams.join(";"):""},t.prototype._stringifyPathMatrixAux=function(){return o.isBlank(this.component)?"":this.urlPath+this._stringifyMatrixParams()+this._stringifyAux()},t.prototype._stringifyAux=function(){var t=[];return i.StringMapWrapper.forEach(this.auxInstruction,function(e,n){t.push(e._stringifyPathMatrixAux())}),t.length>0?"("+t.join("//")+")":""},t}();e.Instruction=c;var p=function(t){function e(e,n,r){t.call(this,e,n,r)}return r(e,t),e.prototype.resolveComponent=function(){return s.PromiseWrapper.resolve(this.component)},e}(c);e.ResolvedInstruction=p;var l=function(t){function e(e,n){t.call(this,e,n,{})}return r(e,t),e.prototype.toLinkUrl=function(){return""},e.prototype._toLinkUrl=function(){return""},e}(p);e.DefaultInstruction=l;var h=function(t){function e(e,n,r){void 0===n&&(n=""),void 0===r&&(r=o.CONST_EXPR([])),t.call(this,null,null,{}),this._resolver=e,this._urlPath=n,this._urlParams=r}return r(e,t),Object.defineProperty(e.prototype,"urlPath",{get:function(){return o.isPresent(this.component)?this.component.urlPath:o.isPresent(this._urlPath)?this._urlPath:""},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"urlParams",{get:function(){return o.isPresent(this.component)?this.component.urlParams:o.isPresent(this._urlParams)?this._urlParams:[]},enumerable:!0,configurable:!0}),e.prototype.resolveComponent=function(){var t=this;return o.isPresent(this.component)?s.PromiseWrapper.resolve(this.component):this._resolver().then(function(e){return t.child=o.isPresent(e)?e.child:null,t.component=o.isPresent(e)?e.component:null})},e}(c);e.UnresolvedInstruction=h;var f=function(t){function e(e,n,r,i){t.call(this,e,n,r),this._specificity=i}return r(e,t),Object.defineProperty(e.prototype,"specificity",{get:function(){return this._specificity},enumerable:!0,configurable:!0}),e}(p);e.RedirectInstruction=f;var d=function(){function t(t,n,r,i,s,a,u,c){void 0===u&&(u=null),this.urlPath=t,this.urlParams=n,this.componentType=i,this.terminal=s,this.specificity=a,this.params=u,this.routeName=c,this.reuse=!1,this.routeData=o.isPresent(r)?r:e.BLANK_ROUTE_DATA}return t}();e.ComponentInstruction=d},function(t,e,n){"use strict";var r=n(5),i=n(12),o=n(15),s=n(40),a=n(258),u=n(257),c=n(262),p=n(263),l=n(264),h=n(267),f=function(){function t(){this.rulesByName=new o.Map,this.auxRulesByName=new o.Map,this.auxRulesByPath=new o.Map,this.rules=[],this.defaultRule=null}return t.prototype.config=function(t){var e;if(r.isPresent(t.name)&&t.name[0].toUpperCase()!=t.name[0]){var n=t.name[0].toUpperCase()+t.name.substring(1);throw new i.BaseException('Route "'+t.path+'" with name "'+t.name+'" does not begin with an uppercase letter. Route names should be CamelCase like "'+n+'".')}if(t instanceof u.AuxRoute){e=new p.SyncRouteHandler(t.component,t.data);var o=this._getRoutePath(t),s=new a.RouteRule(o,e,t.name);return this.auxRulesByPath.set(o.toString(),s),r.isPresent(t.name)&&this.auxRulesByName.set(t.name,s),s.terminal}var l=!1;if(t instanceof u.Redirect){var h=this._getRoutePath(t),f=new a.RedirectRule(h,t.redirectTo);return this._assertNoHashCollision(f.hash,t.path),this.rules.push(f),!0}t instanceof u.Route?(e=new p.SyncRouteHandler(t.component,t.data),l=r.isPresent(t.useAsDefault)&&t.useAsDefault):t instanceof u.AsyncRoute&&(e=new c.AsyncRouteHandler(t.loader,t.data),l=r.isPresent(t.useAsDefault)&&t.useAsDefault);var d=this._getRoutePath(t),v=new a.RouteRule(d,e,t.name);if(this._assertNoHashCollision(v.hash,t.path),l){if(r.isPresent(this.defaultRule))throw new i.BaseException("Only one route can be default");this.defaultRule=v}return this.rules.push(v),r.isPresent(t.name)&&this.rulesByName.set(t.name,v),v.terminal},t.prototype.recognize=function(t){var e=[];return this.rules.forEach(function(n){var i=n.recognize(t);r.isPresent(i)&&e.push(i)}),0==e.length&&r.isPresent(t)&&t.auxiliary.length>0?[s.PromiseWrapper.resolve(new a.PathMatch(null,null,t.auxiliary))]:e},t.prototype.recognizeAuxiliary=function(t){var e=this.auxRulesByPath.get(t.path);return r.isPresent(e)?[e.recognize(t)]:[s.PromiseWrapper.resolve(null)]},t.prototype.hasRoute=function(t){return this.rulesByName.has(t)},t.prototype.componentLoaded=function(t){return this.hasRoute(t)&&r.isPresent(this.rulesByName.get(t).handler.componentType)},t.prototype.loadComponent=function(t){return this.rulesByName.get(t).handler.resolveComponentType()},t.prototype.generate=function(t,e){var n=this.rulesByName.get(t);return r.isBlank(n)?null:n.generate(e)},t.prototype.generateAuxiliary=function(t,e){var n=this.auxRulesByName.get(t);return r.isBlank(n)?null:n.generate(e)},t.prototype._assertNoHashCollision=function(t,e){this.rules.forEach(function(n){if(t==n.hash)throw new i.BaseException("Configuration '"+e+"' conflicts with existing route '"+n.path+"'")})},t.prototype._getRoutePath=function(t){if(r.isPresent(t.regex)){if(r.isFunction(t.serializer))return new h.RegexRoutePath(t.regex,t.serializer);throw new i.BaseException("Route provides a regex property, '"+t.regex+"', but no serializer property")}if(r.isPresent(t.path)){var e=t instanceof u.AuxRoute&&t.path.startsWith("/")?t.path.substring(1):t.path;return new l.ParamRoutePath(e)}throw new i.BaseException("Route must provide either a path or regex property")},t}();e.RuleSet=f},function(t,e,n){"use strict";var r=n(5),i=n(260),o=function(){function t(t,e){void 0===e&&(e=null),this._loader=t,this._resolvedComponent=null,this.data=r.isPresent(e)?new i.RouteData(e):i.BLANK_ROUTE_DATA}return t.prototype.resolveComponentType=function(){
                +var t=this;return r.isPresent(this._resolvedComponent)?this._resolvedComponent:this._resolvedComponent=this._loader().then(function(e){return t.componentType=e,e})},t}();e.AsyncRouteHandler=o},function(t,e,n){"use strict";var r=n(40),i=n(5),o=n(260),s=function(){function t(t,e){this.componentType=t,this._resolvedComponent=null,this._resolvedComponent=r.PromiseWrapper.resolve(t),this.data=i.isPresent(e)?new o.RouteData(e):o.BLANK_ROUTE_DATA}return t.prototype.resolveComponentType=function(){return this._resolvedComponent},t}();e.SyncRouteHandler=s},function(t,e,n){"use strict";function r(t){return o.isBlank(t)?null:(t=o.StringWrapper.replaceAll(t,y,"%25"),t=o.StringWrapper.replaceAll(t,m,"%2F"),t=o.StringWrapper.replaceAll(t,g,"%28"),t=o.StringWrapper.replaceAll(t,_,"%29"),t=o.StringWrapper.replaceAll(t,b,"%3B"))}function i(t){return o.isBlank(t)?null:(t=o.StringWrapper.replaceAll(t,P,";"),t=o.StringWrapper.replaceAll(t,E,")"),t=o.StringWrapper.replaceAll(t,w,"("),t=o.StringWrapper.replaceAll(t,C,"/"),t=o.StringWrapper.replaceAll(t,R,"%"))}var o=n(5),s=n(12),a=n(15),u=n(265),c=n(259),p=n(266),l=function(){function t(){this.name="",this.specificity="",this.hash="..."}return t.prototype.generate=function(t){return""},t.prototype.match=function(t){return!0},t}(),h=function(){function t(t){this.path=t,this.name="",this.specificity="2",this.hash=t}return t.prototype.match=function(t){return t==this.path},t.prototype.generate=function(t){return this.path},t}(),f=function(){function t(t){this.name=t,this.specificity="1",this.hash=":"}return t.prototype.match=function(t){return t.length>0},t.prototype.generate=function(t){if(!a.StringMapWrapper.contains(t.map,this.name))throw new s.BaseException("Route generator for '"+this.name+"' was not included in parameters passed.");return r(u.normalizeString(t.get(this.name)))},t.paramMatcher=/^:([^\/]+)$/g,t}(),d=function(){function t(t){this.name=t,this.specificity="0",this.hash="*"}return t.prototype.match=function(t){return!0},t.prototype.generate=function(t){return u.normalizeString(t.get(this.name))},t.wildcardMatcher=/^\*([^\/]+)$/g,t}(),v=function(){function t(t){this.routePath=t,this.terminal=!0,this._assertValidPath(t),this._parsePathString(t),this.specificity=this._calculateSpecificity(),this.hash=this._calculateHash();var e=this._segments[this._segments.length-1];this.terminal=!(e instanceof l)}return t.prototype.matchUrl=function(t){for(var e,n=t,r={},s=[],u=0;u<this._segments.length;u+=1){var h=this._segments[u];if(e=n,h instanceof l)break;if(o.isPresent(e)){if(h instanceof d){r[h.name]=e.toString(),s.push(e.toString()),n=null;break}if(s.push(e.path),h instanceof f)r[h.name]=i(e.path);else if(!h.match(e.path))return null;n=e.child}else if(!h.match(""))return null}if(this.terminal&&o.isPresent(n))return null;var v=s.join("/"),y=[],m=[],g=r;if(o.isPresent(e)){var _=t instanceof c.RootUrl?t:e;o.isPresent(_.params)?(g=a.StringMapWrapper.merge(_.params,r),m=c.convertUrlParamsToArray(_.params)):g=r,y=e.auxiliary}return new p.MatchedUrl(v,m,g,y,n)},t.prototype.generateUrl=function(t){for(var e=new u.TouchMap(t),n=[],r=0;r<this._segments.length;r++){var i=this._segments[r];i instanceof l||n.push(i.generate(e))}var o=n.join("/"),s=e.getUnused(),a=s;return new p.GeneratedUrl(o,a)},t.prototype.toString=function(){return this.routePath},t.prototype._parsePathString=function(t){t.startsWith("/")&&(t=t.substring(1));var e=t.split("/");this._segments=[];for(var n=e.length-1,r=0;n>=r;r++){var i,a=e[r];if(o.isPresent(i=o.RegExpWrapper.firstMatch(f.paramMatcher,a)))this._segments.push(new f(i[1]));else if(o.isPresent(i=o.RegExpWrapper.firstMatch(d.wildcardMatcher,a)))this._segments.push(new d(i[1]));else if("..."==a){if(n>r)throw new s.BaseException('Unexpected "..." before the end of the path for "'+t+'".');this._segments.push(new l)}else this._segments.push(new h(a))}},t.prototype._calculateSpecificity=function(){var t,e,n=this._segments.length;if(0==n)e+="2";else for(e="",t=0;n>t;t++)e+=this._segments[t].specificity;return e},t.prototype._calculateHash=function(){var t,e=this._segments.length,n=[];for(t=0;e>t;t++)n.push(this._segments[t].hash);return n.join("/")},t.prototype._assertValidPath=function(e){if(o.StringWrapper.contains(e,"#"))throw new s.BaseException('Path "'+e+'" should not include "#". Use "HashLocationStrategy" instead.');var n=o.RegExpWrapper.firstMatch(t.RESERVED_CHARS,e);if(o.isPresent(n))throw new s.BaseException('Path "'+e+'" contains "'+n[0]+'" which is not allowed in a route config.')},t.RESERVED_CHARS=o.RegExpWrapper.create("//|\\(|\\)|;|\\?|="),t}();e.ParamRoutePath=v;var y=/%/g,m=/\//g,g=/\(/g,_=/\)/g,b=/;/g,P=/%3B/gi,E=/%29/gi,w=/%28/gi,C=/%2F/gi,R=/%25/gi},function(t,e,n){"use strict";function r(t){return i.isBlank(t)?null:t.toString()}var i=n(5),o=n(15),s=function(){function t(t){var e=this;this.map={},this.keys={},i.isPresent(t)&&o.StringMapWrapper.forEach(t,function(t,n){e.map[n]=i.isPresent(t)?t.toString():null,e.keys[n]=!0})}return t.prototype.get=function(t){return o.StringMapWrapper["delete"](this.keys,t),this.map[t]},t.prototype.getUnused=function(){var t=this,e={},n=o.StringMapWrapper.keys(this.keys);return n.forEach(function(n){return e[n]=o.StringMapWrapper.get(t.map,n)}),e},t}();e.TouchMap=s,e.normalizeString=r},function(t,e){"use strict";var n=function(){function t(t,e,n,r,i){this.urlPath=t,this.urlParams=e,this.allParams=n,this.auxiliary=r,this.rest=i}return t}();e.MatchedUrl=n;var r=function(){function t(t,e){this.urlPath=t,this.urlParams=e}return t}();e.GeneratedUrl=r},function(t,e,n){"use strict";var r=n(5),i=n(266),o=function(){function t(t,e){this._reString=t,this._serializer=e,this.terminal=!0,this.specificity="2",this.hash=this._reString,this._regex=r.RegExpWrapper.create(this._reString)}return t.prototype.matchUrl=function(t){var e=t.toString(),n={},o=r.RegExpWrapper.matcher(this._regex,e),s=r.RegExpMatcherWrapper.next(o);if(r.isBlank(s))return null;for(var a=0;a<s.length;a+=1)n[a.toString()]=s[a];return new i.MatchedUrl(e,[],n,[],null)},t.prototype.generateUrl=function(t){return this._serializer(t)},t.prototype.toString=function(){return this._reString},t}();e.RegexRoutePath=o},function(t,e,n){"use strict";function r(t,e){if(t instanceof s.AsyncRoute){var n=i(t.loader,e);return new s.AsyncRoute({path:t.path,loader:n,name:t.name,data:t.data,useAsDefault:t.useAsDefault})}if(t instanceof s.Route||t instanceof s.Redirect||t instanceof s.AuxRoute)return t;if(+!!t.component+ +!!t.redirectTo+ +!!t.loader!=1)throw new u.BaseException('Route config should contain exactly one "component", "loader", or "redirectTo" property.');if(t.as&&t.name)throw new u.BaseException('Route config should contain exactly one "as" or "name" property.');if(t.as&&(t.name=t.as),t.loader){var n=i(t.loader,e);return new s.AsyncRoute({path:t.path,loader:n,name:t.name,data:t.data,useAsDefault:t.useAsDefault})}if(t.aux)return new s.AuxRoute({path:t.aux,component:t.component,name:t.name});if(t.component){if("object"==typeof t.component){var r=t.component;if("constructor"==r.type)return new s.Route({path:t.path,component:r.constructor,name:t.name,data:t.data,useAsDefault:t.useAsDefault});if("loader"==r.type)return new s.AsyncRoute({path:t.path,loader:r.loader,name:t.name,data:t.data,useAsDefault:t.useAsDefault});throw new u.BaseException('Invalid component type "'+r.type+'". Valid types are "constructor" and "loader".')}return new s.Route(t)}return t.redirectTo?new s.Redirect({path:t.path,redirectTo:t.redirectTo}):t}function i(t,e){return function(){return t().then(function(t){return e.configFromComponent(t),t})}}function o(t,e){if(!a.isType(t))throw new u.BaseException('Component for route "'+e+'" is not defined, or is not a class.')}var s=n(269),a=n(5),u=n(12);e.normalizeRouteConfig=r,e.assertComponentExists=o},function(t,e,n){"use strict";var r=n(257),i=n(9),o=n(257);e.Route=o.Route,e.Redirect=o.Redirect,e.AuxRoute=o.AuxRoute,e.AsyncRoute=o.AsyncRoute,e.RouteConfig=i.makeDecorator(r.RouteConfig)},function(t,e,n){"use strict";function r(t,e){return e instanceof o.Type?t.name in e.prototype:!1}function i(t){for(var e=a.reflector.annotations(t),n=0;n<e.length;n+=1){var r=e[n];if(r instanceof s.CanActivate)return r.fn}return null}var o=n(5),s=n(271),a=n(18);e.hasLifecycleHook=r,e.getCanActivateHook=i},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(5),s=function(){function t(t){this.name=t}return t=r([o.CONST(),i("design:paramtypes",[String])],t)}();e.RouteLifecycleHook=s;var a=function(){function t(t){this.fn=t}return t=r([o.CONST(),i("design:paramtypes",[Function])],t)}();e.CanActivate=a,e.routerCanReuse=o.CONST_EXPR(new s("routerCanReuse")),e.routerCanDeactivate=o.CONST_EXPR(new s("routerCanDeactivate")),e.routerOnActivate=o.CONST_EXPR(new s("routerOnActivate")),e.routerOnReuse=o.CONST_EXPR(new s("routerOnReuse")),e.routerOnDeactivate=o.CONST_EXPR(new s("routerOnDeactivate"))},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=this&&this.__param||function(t,e){return function(n,r){e(n,r,t)}},s=n(40),a=n(15),u=n(5),c=n(2),p=n(248),l=n(260),h=n(273),f=n(270),d=s.PromiseWrapper.resolve(!0),v=function(){function t(t,e,n,r){this._viewContainerRef=t,this._loader=e,this._parentRouter=n,this.name=null,this._componentRef=null,this._currentInstruction=null,this.activateEvents=new s.EventEmitter,u.isPresent(r)?(this.name=r,this._parentRouter.registerAuxOutlet(this)):this._parentRouter.registerPrimaryOutlet(this)}return t.prototype.activate=function(t){var e=this,n=this._currentInstruction;this._currentInstruction=t;var r=t.componentType,i=this._parentRouter.childRouter(r),o=c.ReflectiveInjector.resolve([c.provide(l.RouteData,{useValue:t.routeData}),c.provide(l.RouteParams,{useValue:new l.RouteParams(t.params)}),c.provide(p.Router,{useValue:i})]);return this._componentRef=this._loader.loadNextToLocation(r,this._viewContainerRef,o),this._componentRef.then(function(i){return e.activateEvents.emit(i.instance),f.hasLifecycleHook(h.routerOnActivate,r)?e._componentRef.then(function(e){return e.instance.routerOnActivate(t,n)}):i})},t.prototype.reuse=function(t){var e=this._currentInstruction;return this._currentInstruction=t,u.isBlank(this._componentRef)?this.activate(t):s.PromiseWrapper.resolve(f.hasLifecycleHook(h.routerOnReuse,this._currentInstruction.componentType)?this._componentRef.then(function(n){return n.instance.routerOnReuse(t,e)}):!0)},t.prototype.deactivate=function(t){var e=this,n=d;return u.isPresent(this._componentRef)&&u.isPresent(this._currentInstruction)&&f.hasLifecycleHook(h.routerOnDeactivate,this._currentInstruction.componentType)&&(n=this._componentRef.then(function(n){return n.instance.routerOnDeactivate(t,e._currentInstruction)})),n.then(function(t){if(u.isPresent(e._componentRef)){var n=e._componentRef.then(function(t){return t.destroy()});return e._componentRef=null,n}})},t.prototype.routerCanDeactivate=function(t){var e=this;return u.isBlank(this._currentInstruction)?d:f.hasLifecycleHook(h.routerCanDeactivate,this._currentInstruction.componentType)?this._componentRef.then(function(n){return n.instance.routerCanDeactivate(t,e._currentInstruction)}):d},t.prototype.routerCanReuse=function(t){var e,n=this;return e=u.isBlank(this._currentInstruction)||this._currentInstruction.componentType!=t.componentType?!1:f.hasLifecycleHook(h.routerCanReuse,this._currentInstruction.componentType)?this._componentRef.then(function(e){return e.instance.routerCanReuse(t,n._currentInstruction)}):t==this._currentInstruction||u.isPresent(t.params)&&u.isPresent(this._currentInstruction.params)&&a.StringMapWrapper.equals(t.params,this._currentInstruction.params),s.PromiseWrapper.resolve(e)},t.prototype.ngOnDestroy=function(){this._parentRouter.unregisterPrimaryOutlet(this)},r([c.Output("activate"),i("design:type",Object)],t.prototype,"activateEvents",void 0),t=r([c.Directive({selector:"router-outlet"}),o(3,c.Attribute("name")),i("design:paramtypes",[c.ViewContainerRef,c.DynamicComponentLoader,p.Router,String])],t)}();e.RouterOutlet=v},function(t,e,n){"use strict";var r=n(9),i=n(271),o=n(271);e.routerCanReuse=o.routerCanReuse,e.routerCanDeactivate=o.routerCanDeactivate,e.routerOnActivate=o.routerOnActivate,e.routerOnReuse=o.routerOnReuse,e.routerOnDeactivate=o.routerOnDeactivate,e.CanActivate=r.makeDecorator(i.CanActivate)},function(t,e,n){"use strict";var r=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},o=n(2),s=n(249),a=n(5),u=n(248),c=function(){function t(t,e){var n=this;this._router=t,this._location=e,this._router.subscribe(function(t){return n._updateLink()})}return t.prototype._updateLink=function(){this._navigationInstruction=this._router.generate(this._routeParams);var t=this._navigationInstruction.toLinkUrl();this.visibleHref=this._location.prepareExternalUrl(t)},Object.defineProperty(t.prototype,"isRouteActive",{get:function(){return this._router.isRouteActive(this._navigationInstruction)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"routeParams",{set:function(t){this._routeParams=t,this._updateLink()},enumerable:!0,configurable:!0}),t.prototype.onClick=function(){return a.isString(this.target)&&"_self"!=this.target?!0:(this._router.navigateByInstruction(this._navigationInstruction),!1)},t=r([o.Directive({selector:"[routerLink]",inputs:["routeParams: routerLink","target: target"],host:{"(click)":"onClick()","[attr.href]":"visibleHref","[class.router-link-active]":"isRouteActive"}}),i("design:paramtypes",[u.Router,s.Location])],t)}();e.RouterLink=c},function(t,e,n){"use strict";function r(t,e,n,r){var i=new s.RootRouter(t,e,n);return r.registerDisposeListener(function(){return i.dispose()}),i}function i(t){if(0==t.componentTypes.length)throw new p.BaseException("Bootstrap at least one component before injecting Router.");return t.componentTypes[0]}var o=n(249),s=n(248),a=n(256),u=n(5),c=n(2),p=n(12);e.ROUTER_PROVIDERS_COMMON=u.CONST_EXPR([a.RouteRegistry,u.CONST_EXPR(new c.Provider(o.LocationStrategy,{useClass:o.PathLocationStrategy})),o.Location,u.CONST_EXPR(new c.Provider(s.Router,{useFactory:r,deps:u.CONST_EXPR([a.RouteRegistry,o.Location,a.ROUTER_PRIMARY_COMPONENT,c.ApplicationRef])})),u.CONST_EXPR(new c.Provider(a.ROUTER_PRIMARY_COMPONENT,{useFactory:i,deps:u.CONST_EXPR([c.ApplicationRef])}))])},function(t,e,n){"use strict";var r=n(275),i=n(2),o=n(277),s=n(249),a=n(5);e.ROUTER_PROVIDERS=a.CONST_EXPR([r.ROUTER_PROVIDERS_COMMON,a.CONST_EXPR(new i.Provider(s.PlatformLocation,{useClass:o.BrowserPlatformLocation}))]),e.ROUTER_BINDINGS=e.ROUTER_PROVIDERS},function(t,e,n){"use strict";var r=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},i=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},o=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},s=n(8),a=n(251),u=n(200),c=function(t){function e(){t.call(this),this._init()}return r(e,t),e.prototype._init=function(){this._location=u.DOM.getLocation(),this._history=u.DOM.getHistory()},Object.defineProperty(e.prototype,"location",{get:function(){return this._location},enumerable:!0,configurable:!0}),e.prototype.getBaseHrefFromDOM=function(){return u.DOM.getBaseHref()},e.prototype.onPopState=function(t){u.DOM.getGlobalEventTarget("window").addEventListener("popstate",t,!1)},e.prototype.onHashChange=function(t){u.DOM.getGlobalEventTarget("window").addEventListener("hashchange",t,!1)},Object.defineProperty(e.prototype,"pathname",{get:function(){return this._location.pathname},set:function(t){this._location.pathname=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"search",{get:function(){return this._location.search},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"hash",{get:function(){return this._location.hash},enumerable:!0,configurable:!0}),e.prototype.pushState=function(t,e,n){this._history.pushState(t,e,n)},e.prototype.replaceState=function(t,e,n){this._history.replaceState(t,e,n)},e.prototype.forward=function(){this._history.forward()},e.prototype.back=function(){this._history.back()},e=i([s.Injectable(),o("design:paramtypes",[])],e)}(a.PlatformLocation);e.BrowserPlatformLocation=c},function(t,e,n){"use strict";var r=n(137),i=n(2),o=n(279),s=n(5),a=n(279);e.RouterLinkTransform=a.RouterLinkTransform,e.ROUTER_LINK_DSL_PROVIDER=s.CONST_EXPR(new i.Provider(r.TEMPLATE_TRANSFORMS,{useClass:o.RouterLinkTransform,multi:!0}))},function(t,e,n){"use strict";function r(t,e){var n=new y(t,e.trim()).tokenize();return new m(n).generate()}var i=this&&this.__extends||function(t,e){function n(){this.constructor=t}for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)},o=this&&this.__decorate||function(t,e,n,r){var i,o=arguments.length,s=3>o?e:null===r?r=Object.getOwnPropertyDescriptor(e,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,r);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(3>o?i(s):o>3?i(e,n,s):i(e,n))||s);return o>3&&s&&Object.defineProperty(e,n,s),s},s=this&&this.__metadata||function(t,e){return"object"==typeof Reflect&&"function"==typeof Reflect.metadata?Reflect.metadata(t,e):void 0},a=n(137),u=n(141),c=n(12),p=n(2),l=n(142),h=function(){function t(t){this.value=t}return t}(),f=function(){function t(){}return t}(),d=function(){function t(){}return t}(),v=function(){function t(t){this.ast=t}return t}(),y=function(){function t(t,e){this.parser=t,this.exp=e,this.index=0}return t.prototype.tokenize=function(){for(var t=[];this.index<this.exp.length;)t.push(this._parseToken());return t},t.prototype._parseToken=function(){var t=this.exp[this.index];return"["==t?(this.index++,new f):"]"==t?(this.index++,new d):"("==t?this._parseParams():"/"==t&&0!==this.index?(this.index++,this._parseFixedPart()):this._parseFixedPart()},t.prototype._parseParams=function(){for(var t=this.index;this.index<this.exp.length;++this.index){var e=this.exp[this.index];if(")"==e){var n=this.exp.substring(t+1,this.index);return this.index++,new v(this.parser.parseBinding("{"+n+"}",null).ast)}}throw new c.BaseException("Cannot find ')'")},t.prototype._parseFixedPart=function(){for(var t=this.index,e=!1;this.index<this.exp.length;++this.index){var n=this.exp[this.index];if("("==n||"["==n||"]"==n||"/"==n&&e)break;"."!=n&&"/"!=n&&(e=!0)}var r=this.exp.substring(t,this.index);if(t===this.index||!e||r.startsWith("//"))throw new c.BaseException("Invalid router link");return new h(r)},t}(),m=function(){function t(t){this.tokens=t,this.index=0}return t.prototype.generate=function(){return this._genAuxiliary()},t.prototype._genAuxiliary=function(){for(var t=[];this.index<this.tokens.length;this.index++){var e=this.tokens[this.index];if(e instanceof h)t.push(new u.LiteralPrimitive(e.value));else if(e instanceof v)t.push(e.ast);else{if(e instanceof d)break;e instanceof f&&(this.index++,t.push(this._genAuxiliary()))}}return new u.LiteralArray(t)},t}(),g=function(t){function e(e){t.call(this),this.parser=e}return i(e,t),e.prototype.visitQuote=function(e,n){return"route"==e.prefix?r(this.parser,e.uninterpretedExpression):t.prototype.visitQuote.call(this,e,n)},e}(u.AstTransformer);e.parseRouterLinkExpression=r;var _=function(){function t(t){this.astTransformer=new g(t)}return t.prototype.visitNgContent=function(t,e){return t},t.prototype.visitEmbeddedTemplate=function(t,e){return t},t.prototype.visitElement=function(t,e){var n=this,r=t.children.map(function(t){return t.visit(n,e)}),i=t.inputs.map(function(t){return t.visit(n,e)}),o=t.directives.map(function(t){return t.visit(n,e)});return new a.ElementAst(t.name,t.attrs,i,t.outputs,t.exportAsVars,o,t.providers,t.hasViewContainer,r,t.ngContentIndex,t.sourceSpan)},t.prototype.visitVariable=function(t,e){return t},t.prototype.visitEvent=function(t,e){return t},t.prototype.visitElementProperty=function(t,e){return t},t.prototype.visitAttr=function(t,e){return t},t.prototype.visitBoundText=function(t,e){return t},t.prototype.visitText=function(t,e){return t},t.prototype.visitDirective=function(t,e){var n=this,r=t.inputs.map(function(t){return t.visit(n,e)});return new a.DirectiveAst(t.directive,r,t.hostProperties,t.hostEvents,t.exportAsVars,t.sourceSpan)},t.prototype.visitDirectiveProperty=function(t,e){var n=t.value.visit(this.astTransformer);return new a.BoundDirectivePropertyAst(t.directiveName,t.templateName,n,t.sourceSpan)},t=o([p.Injectable(),s("design:paramtypes",[l.Parser])],t)}();e.RouterLinkTransform=_},function(t,e,n){"use strict";var r=n(71);e.wtfCreateScope=r.wtfCreateScope,e.wtfLeave=r.wtfLeave,e.wtfStartTimeRange=r.wtfStartTimeRange,e.wtfEndTimeRange=r.wtfEndTimeRange},function(t,e,n){"use strict";var r=n(282);e.UpgradeAdapter=r.UpgradeAdapter,e.UpgradeAdapterRef=r.UpgradeAdapterRef},function(t,e,n){"use strict";function r(t,e){function n(n,r){var i=n[t.selector];if(!i)throw new Error("Expecting ComponentFactory for: "+t.selector);var o=0;return{restrict:"E",require:p.REQUIRE_INJECTOR,link:{post:function(n,s,a,u,c){var p=(s[0],new l.DowngradeNg2ComponentAdapter(e+o++,t,s,a,n,u,r,i));p.setupInputs(),p.bootstrapNg2(),p.projectContent(),p.setupOutputs(),p.registerCleanup()}}}}return n.$inject=[p.NG2_COMPONENT_FACTORY_REF_MAP,p.NG1_PARSE],n}var i=n(2),o=n(5),s=n(40),a=n(201),u=n(283),c=n(284),p=n(285),l=n(286),h=n(287),f=n(288),d=0,v=function(){function t(){this.idPrefix="NG2_UPGRADE_"+d++ +"_",this.upgradedComponents=[],this.downgradedComponents={},this.providers=[]}return t.prototype.downgradeNg2Component=function(t){this.upgradedComponents.push(t);var e=u.getComponentInfo(t);return r(e,""+this.idPrefix+e.selector+"_c")},t.prototype.upgradeNg1Component=function(t){return this.downgradedComponents.hasOwnProperty(t)?this.downgradedComponents[t].type:(this.downgradedComponents[t]=new h.UpgradeNg1ComponentAdapterBuilder(t)).type},t.prototype.bootstrap=function(t,e,n){var r,u,l,d=this,v=new y,m=null,g=a.browserPlatform(),_=i.ReflectiveInjector.resolveAndCreate([a.BROWSER_APP_PROVIDERS,i.provide(p.NG1_INJECTOR,{useFactory:function(){return m}}),i.provide(p.NG1_COMPILE,{useFactory:function(){return m.get(p.NG1_COMPILE)}}),this.providers],g.injector).get(i.ApplicationRef),b=_.injector,P=b.get(i.NgZone),E=b.get(i.ComponentResolver),w=[],C={},R=f.module(this.idPrefix,e),S=null,O=null;R.value(p.NG2_INJECTOR,b).value(p.NG2_ZONE,P).value(p.NG2_COMPILER,E).value(p.NG2_COMPONENT_FACTORY_REF_MAP,C).config(["$provide",function(t){t.decorator(p.NG1_ROOT_SCOPE,["$delegate",function(t){if(u=t.constructor.prototype,!u.hasOwnProperty("$apply"))throw new Error("Failed to find '$apply' on '$rootScope'!");return r=u.$apply,u.$apply=function(t){return w.push(t)},l=t}]),t.decorator(p.NG1_TESTABILITY,["$delegate",function(t){var e=this,n=b.get(i.Testability),r=t.whenStable,o=function(t){var i=e;r.call(e,function(){n.isStable()?t.apply(this,arguments):n.whenStable(o.bind(i,t))})};return t.whenStable=o,t}])}]),O=new Promise(function(t,e){R.run(["$injector","$rootScope",function(n,r){m=n,s.ObservableWrapper.subscribe(P.onMicrotaskEmpty,function(t){return P.runOutsideAngular(function(){return r.$apply()})}),h.UpgradeNg1ComponentAdapterBuilder.resolve(d.downgradedComponents,n).then(t,e)}])});var T=o.global.angular;return T.resumeBootstrap=void 0,f.element(t).data(c.controllerKey(p.NG2_INJECTOR),b),P.run(function(){f.bootstrap(t,[d.idPrefix],n)}),S=new Promise(function(t,e){if(T.resumeBootstrap){var n=T.resumeBootstrap;T.resumeBootstrap=function(){T.resumeBootstrap=n,T.resumeBootstrap.apply(this,arguments),t()}}else t()}),Promise.all([this.compileNg2Components(E,C),S,O]).then(function(){P.run(function(){if(u){for(u.$apply=r;w.length;)l.$apply(w.shift());v._bootstrapDone(_,m),u=null}})},c.onError),v},t.prototype.addProvider=function(t){this.providers.push(t)},t.prototype.upgradeNg1Provider=function(t,e){var n=e&&e.asToken||t;this.providers.push(i.provide(n,{useFactory:function(e){return e.get(t)},deps:[p.NG1_INJECTOR]}))},t.prototype.downgradeNg2Provider=function(t){var e=function(e){return e.get(t)};return e.$inject=[p.NG2_INJECTOR],e},t.prototype.compileNg2Components=function(t,e){for(var n=this,r=[],i=this.upgradedComponents,o=0;o<i.length;o++)r.push(t.resolveComponent(i[o]));return Promise.all(r).then(function(t){for(var r=n.upgradedComponents,i=0;i<t.length;i++)e[u.getComponentInfo(r[i]).selector]=t[i];return e},c.onError)},t}();e.UpgradeAdapter=v;var y=function(){function t(){this._readyFn=null,this.ng1RootScope=null,this.ng1Injector=null,this.ng2ApplicationRef=null,this.ng2Injector=null}return t.prototype._bootstrapDone=function(t,e){this.ng2ApplicationRef=t,this.ng2Injector=t.injector,this.ng1Injector=e,this.ng1RootScope=e.get(p.NG1_ROOT_SCOPE),this._readyFn&&this._readyFn(this)},t.prototype.ready=function(t){this._readyFn=t},t.prototype.dispose=function(){this.ng1Injector.get(p.NG1_ROOT_SCOPE).$destroy(),this.ng2ApplicationRef.dispose()},t}();e.UpgradeAdapterRef=y},function(t,e,n){"use strict";function r(t){var e=u.resolve(t),n=e.selector;if(!n.match(s))throw new Error("Only selectors matching element names are supported, got: "+n);var n=n.replace(a,function(t,e){return e.toUpperCase()});return{type:t,selector:n,inputs:i(e.inputs),outputs:i(e.outputs)}}function i(t){var e=[];if(t)for(var n=0;n<t.length;n++){var r=t[n].split(":"),i=r[0].trim(),o=(r[1]||r[0]).trim(),s=o.charAt(0).toUpperCase()+o.substr(1);e.push({prop:i,attr:o,bracketAttr:"["+o+"]",parenAttr:"("+o+")",bracketParenAttr:"[("+o+")]",onAttr:"on"+s,bindAttr:"bind"+s,bindonAttr:"bindon"+s})}return e}var o=n(137),s=/^[\w|-]*$/,a=/-(\w)/g,u=new o.DirectiveResolver;e.getComponentInfo=r,e.parseFields=i},function(t,e){"use strict";function n(t){return"function"==typeof t?t.name||t.toString():""+t}function r(t){throw console.log(t,t.stack),t}function i(t){return"$"+t+"Controller"}e.stringify=n,e.onError=r,e.controllerKey=i},function(t,e){"use strict";e.NG2_COMPILER="ng2.Compiler",e.NG2_INJECTOR="ng2.Injector",e.NG2_COMPONENT_FACTORY_REF_MAP="ng2.ComponentFactoryRefMap",e.NG2_ZONE="ng2.NgZone",e.NG1_CONTROLLER="$controller",e.NG1_SCOPE="$scope",e.NG1_ROOT_SCOPE="$rootScope",e.NG1_COMPILE="$compile",e.NG1_HTTP_BACKEND="$httpBackend",e.NG1_INJECTOR="$injector",e.NG1_PARSE="$parse",e.NG1_TEMPLATE_CACHE="$templateCache",e.NG1_TESTABILITY="$$testability",e.REQUIRE_INJECTOR="^"+e.NG2_INJECTOR},function(t,e,n){"use strict";var r=n(2),i=n(285),o={__UNINITIALIZED__:!0},s=function(){function t(t,e,n,r,i,o,s,a){this.id=t,this.info=e,this.element=n,this.attrs=r,this.scope=i,this.parentInjector=o,this.parse=s,this.componentFactory=a,this.component=null,this.inputChangeCount=0,this.inputChanges=null,this.componentRef=null,this.changeDetector=null,this.contentInsertionPoint=null,this.element[0].id=t,this.componentScope=i.$new(),this.childNodes=n.contents()}return t.prototype.bootstrapNg2=function(){var t=r.ReflectiveInjector.resolveAndCreate([r.provide(i.NG1_SCOPE,{useValue:this.componentScope})],this.parentInjector);this.contentInsertionPoint=document.createComment("ng1 insertion point"),this.componentRef=this.componentFactory.create(t,[[this.contentInsertionPoint]],"#"+this.id),this.changeDetector=this.componentRef.changeDetectorRef,this.component=this.componentRef.instance},t.prototype.setupInputs=function(){for(var t=this,e=this.attrs,n=this.info.inputs,r=0;r<n.length;r++){var i=n[r],s=null;if(e.hasOwnProperty(i.attr)){var u=function(e){var n=o;return function(r){null!==t.inputChanges&&(t.inputChangeCount++,t.inputChanges[e]=new a(r,n===o?r:n),n=r),t.component[e]=r}}(i.prop);e.$observe(i.attr,u)}else e.hasOwnProperty(i.bindAttr)?s=e[i.bindAttr]:e.hasOwnProperty(i.bracketAttr)?s=e[i.bracketAttr]:e.hasOwnProperty(i.bindonAttr)?s=e[i.bindonAttr]:e.hasOwnProperty(i.bracketParenAttr)&&(s=e[i.bracketParenAttr]);if(null!=s){var c=function(e){return function(n,r){null!=t.inputChanges&&(t.inputChangeCount++,t.inputChanges[e]=new a(r,n)),t.component[e]=n}}(i.prop);this.componentScope.$watch(s,c)}}var p=this.info.type.prototype;p&&p.ngOnChanges&&(this.inputChanges={},this.componentScope.$watch(function(){return t.inputChangeCount},function(){var e=t.inputChanges;t.inputChanges={},t.component.ngOnChanges(e)})),this.componentScope.$watch(function(){return t.changeDetector&&t.changeDetector.detectChanges()})},t.prototype.projectContent=function(){var t=this.childNodes,e=this.contentInsertionPoint.parentNode;if(e)for(var n=0,r=t.length;r>n;n++)e.insertBefore(t[n],this.contentInsertionPoint)},t.prototype.setupOutputs=function(){for(var t=this,e=this.attrs,n=this.info.outputs,r=0;r<n.length;r++){var i=n[r],o=null,s=!1,a=i.bindonAttr?i.bindonAttr.substring(0,i.bindonAttr.length-6):null,u=i.bracketParenAttr?"[("+i.bracketParenAttr.substring(2,i.bracketParenAttr.length-8)+")]":null;if(e.hasOwnProperty(i.onAttr)?o=e[i.onAttr]:e.hasOwnProperty(i.parenAttr)?o=e[i.parenAttr]:e.hasOwnProperty(a)?(o=e[a],s=!0):e.hasOwnProperty(u)&&(o=e[u],s=!0),null!=o&&null!=s){var c=this.parse(o),p=c.assign;if(s&&!p)throw new Error("Expression '"+o+"' is not assignable!");var l=this.component[i.prop];if(!l)throw new Error("Missing emitter '"+i.prop+"' on component '"+this.info.selector+"'!");l.subscribe({next:s?function(e){return function(n){return e(t.scope,n)}}(p):function(e){return function(n){return e(t.scope,{$event:n})}}(c)})}}},t.prototype.registerCleanup=function(){var t=this;this.element.bind("$destroy",function(){t.componentScope.$destroy(),t.componentRef.destroy()})},t}();e.DowngradeNg2ComponentAdapter=s;var a=function(){function t(t,e){this.previousValue=t,this.currentValue=e}return t.prototype.isFirstChange=function(){return this.previousValue===this.currentValue},t}()},function(t,e,n){"use strict";var r=n(2),i=n(285),o=n(284),s=n(288),a=/([A-Z])/g,u={__UNINITIALIZED__:!0},c="NOT_SUPPORTED",p=function(){function t(t){this.name=t,this.inputs=[],this.inputsRename=[],this.outputs=[],this.outputsRename=[],this.propertyOutputs=[],this.checkProperties=[],this.propertyMap={},this.linkFn=null,this.directive=null,this.$controller=null;var e=t.replace(a,function(t,e){return"-"+e.toLowerCase()}),n=this;this.type=r.Directive({selector:e,inputs:this.inputsRename,outputs:this.outputsRename}).Class({constructor:[new r.Inject(i.NG1_SCOPE),r.ElementRef,function(t,e){return new l(n.linkFn,t,n.directive,e,n.$controller,n.inputs,n.outputs,n.propertyOutputs,n.checkProperties,n.propertyMap);
                +}],ngOnInit:function(){},ngOnChanges:function(){},ngDoCheck:function(){}})}return t.prototype.extractDirective=function(t){var e=t.get(this.name+"Directive");if(e.length>1)throw new Error("Only support single directive definition for: "+this.name);var n=e[0];n.replace&&this.notSupported("replace"),n.terminal&&this.notSupported("terminal");var r=n.link;return"object"==typeof r&&r.post&&this.notSupported("link.post"),n},t.prototype.notSupported=function(t){throw new Error("Upgraded directive '"+this.name+"' does not support '"+t+"'.")},t.prototype.extractBindings=function(){var t="object"==typeof this.directive.bindToController;if(t&&Object.keys(this.directive.scope).length)throw new Error("Binding definitions on scope and controller at the same time are not supported.");var e=t?this.directive.bindToController:this.directive.scope;if("object"==typeof e)for(var n in e)if(e.hasOwnProperty(n)){var r=e[n],i=r.charAt(0);r=r.substr(1)||n;var o="output_"+n,s=o+": "+n,a=o+": "+n+"Change",u="input_"+n,c=u+": "+n;switch(i){case"=":this.propertyOutputs.push(o),this.checkProperties.push(r),this.outputs.push(o),this.outputsRename.push(a),this.propertyMap[o]=r;case"@":case"<":this.inputs.push(u),this.inputsRename.push(c),this.propertyMap[u]=r;break;case"&":this.outputs.push(o),this.outputsRename.push(s),this.propertyMap[o]=r;break;default:var p=JSON.stringify(e);throw new Error("Unexpected mapping '"+i+"' in '"+p+"' in '"+this.name+"' directive.")}}},t.prototype.compileTemplate=function(t,e,n){function r(e){var n=document.createElement("div");return n.innerHTML=e,t(n.childNodes)}var i=this;if(void 0!==this.directive.template)this.linkFn=r(this.directive.template);else{if(!this.directive.templateUrl)throw new Error("Directive '"+this.name+"' is not a component, it is missing template.");var o=this.directive.templateUrl,s=e.get(o);if(void 0===s)return new Promise(function(t,s){n("GET",o,null,function(n,a){200==n?t(i.linkFn=r(e.put(o,a))):s("GET "+o+" returned "+n+": "+a)})});this.linkFn=r(s)}return null},t.resolve=function(t,e){var n=[],r=e.get(i.NG1_COMPILE),o=e.get(i.NG1_TEMPLATE_CACHE),s=e.get(i.NG1_HTTP_BACKEND),a=e.get(i.NG1_CONTROLLER);for(var u in t)if(t.hasOwnProperty(u)){var c=t[u];c.directive=c.extractDirective(e),c.$controller=a,c.extractBindings();var p=c.compileTemplate(r,o,s);p&&n.push(p)}return Promise.all(n)},t}();e.UpgradeNg1ComponentAdapterBuilder=p;var l=function(){function t(t,e,n,i,a,p,l,h,f,d){this.linkFn=t,this.directive=n,this.inputs=p,this.outputs=l,this.propOuts=h,this.checkProperties=f,this.propertyMap=d,this.destinationObj=null,this.checkLastValues=[],this.element=i.nativeElement,this.componentScope=e.$new(!!n.scope);var v=s.element(this.element),y=n.controller,m=null;if(y){var g={$scope:this.componentScope,$element:v};m=a(y,g,null,n.controllerAs),v.data(o.controllerKey(n.name),m)}var _=n.link;if("object"==typeof _&&(_=_.pre),_){var b=c,P=c,E=this.resolveRequired(v,n.require);n.link(this.componentScope,v,b,E,P)}this.destinationObj=n.bindToController&&m?m:this.componentScope;for(var w=0;w<p.length;w++)this[p[w]]=null;for(var C=0;C<l.length;C++){var R=this[l[C]]=new r.EventEmitter;this.setComponentProperty(l[C],function(t){return function(e){return t.emit(e)}}(R))}for(var S=0;S<h.length;S++)this[h[S]]=new r.EventEmitter,this.checkLastValues.push(u)}return t.prototype.ngOnInit=function(){for(var t,e=this,n=[];t=this.element.firstChild;)this.element.removeChild(t),n.push(t);this.linkFn(this.componentScope,function(t,n){for(var r=0,i=t.length;i>r;r++)e.element.appendChild(t[r])},{parentBoundTranscludeFn:function(t,e){e(n)}}),this.destinationObj.$onInit&&this.destinationObj.$onInit()},t.prototype.ngOnChanges=function(t){for(var e in t)if(t.hasOwnProperty(e)){var n=t[e];this.setComponentProperty(e,n.currentValue)}},t.prototype.ngDoCheck=function(){for(var t=0,e=this.destinationObj,n=this.checkLastValues,r=this.checkProperties,i=0;i<r.length;i++){var o=e[r[i]],s=n[i];if(o!==s)if("number"==typeof o&&isNaN(o)&&"number"==typeof s&&isNaN(s));else{var a=this[this.propOuts[i]];a.emit(n[i]=o)}}return t},t.prototype.setComponentProperty=function(t,e){this.destinationObj[this.propertyMap[t]]=e},t.prototype.resolveRequired=function(t,e){if(e){if("string"==typeof e){var n=e,r=!1,i=!1,s=!1;"?"==n.charAt(0)&&(r=!0,n=n.substr(1)),"^"==n.charAt(0)&&(s=!0,n=n.substr(1)),"^"==n.charAt(0)&&(i=!0,n=n.substr(1));var a=o.controllerKey(n);i&&(t=t.parent());var u=s?t.inheritedData(a):t.data(a);if(!u&&!r)throw new Error("Can not locate '"+e+"' in '"+this.directive.name+"'.");return u}if(e instanceof Array){for(var c=[],p=0;p<e.length;p++)c.push(this.resolveRequired(t,e[p]));return c}throw new Error("Directive '"+this.directive.name+"' require syntax unrecognized: "+this.directive.require)}},t}()},function(t,e){"use strict";function n(){throw new Error("AngularJS v1.x is not loaded!")}var r={bootstrap:n,module:n,element:n,version:n,resumeBootstrap:n,getTestability:n};try{window.hasOwnProperty("angular")&&(r=window.angular)}catch(i){}e.bootstrap=r.bootstrap,e.module=r.module,e.element=r.element,e.version=r.version,e.resumeBootstrap=r.resumeBootstrap,e.getTestability=r.getTestability}])});
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/accessible/libs/angular2-polyfills.min.js b/blockly/webif/static/blockly/accessible/libs/angular2-polyfills.min.js
                new file mode 100644
                index 000000000..5dde790d6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/libs/angular2-polyfills.min.js
                @@ -0,0 +1,24 @@
                +/**
                +The MIT License
                +
                +Copyright (c) 2014-2017 Google, Inc. http://angular.io
                +
                +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(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){(function(e){"use strict";function t(e){function t(e){var t=e[v];return t}function n(e){var t=e.data;t.target.addEventListener("readystatechange",function(){t.target.readyState===XMLHttpRequest.DONE&&(t.aborted||e.invoke())});var n=t.target[v];return n||(t.target[v]=e),a.apply(t.target,t.args),e}function r(){}function o(e){var t=e.data;return t.aborted=!0,i.apply(t.target,t.args)}var a=c.patchMethod(e.XMLHttpRequest.prototype,"send",function(){return function(e,t){var a=Zone.current,i={target:e,isPeriodic:!1,delay:null,args:t,aborted:!1};return a.scheduleMacroTask("XMLHttpRequest.send",r,i,n,o)}}),i=c.patchMethod(e.XMLHttpRequest.prototype,"abort",function(e){return function(e,n){var r=t(e);if(r&&"string"==typeof r.type){if(null==r.cancelFn)return;r.zone.cancelTask(r)}}})}n(1);var r=n(2),o=n(4),a=n(5),i=n(6),u=n(8),c=n(3),s="set",l="clear",f=["alert","prompt","confirm"],p="undefined"==typeof window?e:window;u.patchTimer(p,s,l,"Timeout"),u.patchTimer(p,s,l,"Interval"),u.patchTimer(p,s,l,"Immediate"),u.patchTimer(p,"request","cancelMacroTask","AnimationFrame"),u.patchTimer(p,"mozRequest","mozCancel","AnimationFrame"),u.patchTimer(p,"webkitRequest","webkitCancel","AnimationFrame");for(var h=0;h<f.length;h++){var d=f[h];c.patchMethod(p,d,function(e,t,n){return function(t,r){return Zone.current.run(e,p,r,n)}})}r.eventTargetPatch(p),i.propertyDescriptorPatch(p),c.patchClass("MutationObserver"),c.patchClass("WebKitMutationObserver"),c.patchClass("FileReader"),o.propertyPatch(),a.registerElementPatch(p),t(p);var v=c.zoneSymbol("xhrTask");p.navigator&&p.navigator.geolocation&&c.patchPrototype(p.navigator.geolocation,["getCurrentPosition","watchPosition"])}).call(t,function(){return this}())},function(e,t){(function(e){(function(e){function t(e){return"__zone_symbol__"+e}function n(){E||T||0!=w.length||(e[g]?e[g].resolve(0)[k](a):e[y](a,0))}function r(e){n(),w.push(e)}function o(e){var t=e&&e.rejection;t&&console.error("Unhandled Promise rejection:",t instanceof Error?t.message:t,"; Zone:",e.zone.name,"; Task:",e.task&&e.task.source,"; Value:",t),console.error(e)}function a(){if(!_){for(_=!0;w.length;){var e=w;w=[];for(var t=0;t<e.length;t++){var n=e[t];try{n.zone.runTask(n,null,null)}catch(r){o(r)}}}for(;b.length;){var a=b;b=[];for(var i=function(e){var t=a[e];try{t.zone.runGuarded(function(){throw t})}catch(n){o(n)}},t=0;t<a.length;t++)i(t)}_=!1,E=!1}}function i(e){return e&&e.then}function u(e){return e}function c(e){return C.reject(e)}function s(e,t){return function(n){l(e,t,n)}}function l(e,t,r){if(e[S]===P)if(r instanceof C&&r[S]!==P)f(r),l(e,r[S],r[O]);else if(i(r))r.then(s(e,t),s(e,!1));else{e[S]=t;var o=e[O];e[O]=r;for(var a=0;a<o.length;)p(e,o[a++],o[a++],o[a++],o[a++]);if(0==o.length&&t==z){e[S]=j;try{throw new Error("Uncaught (in promise): "+r)}catch(u){var c=u;c.rejection=r,c.promise=e,c.zone=h.current,c.task=h.currentTask,b.push(c),n()}}}return e}function f(e){if(e[S]===j){e[S]=z;for(var t=0;t<b.length;t++)if(e===b[t].promise){b.splice(t,1);break}}}function p(e,t,n,r,o){f(e);var a=e[S]?r||u:o||c;t.scheduleMicroTask(D,function(){try{l(n,!0,t.run(a,null,[e[O]]))}catch(r){l(n,!1,r)}})}var h=function(){function e(e,t){this._properties=null,this._parent=e,this._name=t?t.name||"unnamed":"<root>",this._properties=t&&t.properties||{},this._zoneDelegate=new d(this,this._parent&&this._parent._zoneDelegate,t)}return Object.defineProperty(e,"current",{get:function(){return m},enumerable:!0,configurable:!0}),Object.defineProperty(e,"currentTask",{get:function(){return T},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),e.prototype.get=function(e){for(var t=this;t;){if(t._properties.hasOwnProperty(e))return t._properties[e];t=t._parent}},e.prototype.fork=function(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)},e.prototype.wrap=function(e,t){if("function"!=typeof e)throw new Error("Expecting function got: "+e);var n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}},e.prototype.run=function(e,t,n,r){void 0===t&&(t=null),void 0===n&&(n=null),void 0===r&&(r=null);var o=m;m=this;try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{m=o}},e.prototype.runGuarded=function(e,t,n,r){void 0===t&&(t=null),void 0===n&&(n=null),void 0===r&&(r=null);var o=m;m=this;try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(a){if(this._zoneDelegate.handleError(this,a))throw a}}finally{m=o}},e.prototype.runTask=function(e,t,n){if(e.runCount++,e.zone!=this)throw new Error("A task can only be run in the zone which created it! (Creation: "+e.zone.name+"; Execution: "+this.name+")");var r=T;T=e;var o=m;m=this;try{"macroTask"==e.type&&e.data&&!e.data.isPeriodic&&(e.cancelFn=null);try{return this._zoneDelegate.invokeTask(this,e,t,n)}catch(a){if(this._zoneDelegate.handleError(this,a))throw a}}finally{m=o,T=r}},e.prototype.scheduleMicroTask=function(e,t,n,r){return this._zoneDelegate.scheduleTask(this,new v("microTask",this,e,t,n,r,null))},e.prototype.scheduleMacroTask=function(e,t,n,r,o){return this._zoneDelegate.scheduleTask(this,new v("macroTask",this,e,t,n,r,o))},e.prototype.scheduleEventTask=function(e,t,n,r,o){return this._zoneDelegate.scheduleTask(this,new v("eventTask",this,e,t,n,r,o))},e.prototype.cancelTask=function(e){var t=this._zoneDelegate.cancelTask(this,e);return e.runCount=-1,e.cancelFn=null,t},e.__symbol__=t,e}(),d=function(){function e(e,t,n){this._taskCounts={microTask:0,macroTask:0,eventTask:0},this.zone=e,this._parentDelegate=t,this._forkZS=n&&(n&&n.onFork?n:t._forkZS),this._forkDlgt=n&&(n.onFork?t:t._forkDlgt),this._interceptZS=n&&(n.onIntercept?n:t._interceptZS),this._interceptDlgt=n&&(n.onIntercept?t:t._interceptDlgt),this._invokeZS=n&&(n.onInvoke?n:t._invokeZS),this._invokeDlgt=n&&(n.onInvoke?t:t._invokeDlgt),this._handleErrorZS=n&&(n.onHandleError?n:t._handleErrorZS),this._handleErrorDlgt=n&&(n.onHandleError?t:t._handleErrorDlgt),this._scheduleTaskZS=n&&(n.onScheduleTask?n:t._scheduleTaskZS),this._scheduleTaskDlgt=n&&(n.onScheduleTask?t:t._scheduleTaskDlgt),this._invokeTaskZS=n&&(n.onInvokeTask?n:t._invokeTaskZS),this._invokeTaskDlgt=n&&(n.onInvokeTask?t:t._invokeTaskDlgt),this._cancelTaskZS=n&&(n.onCancelTask?n:t._cancelTaskZS),this._cancelTaskDlgt=n&&(n.onCancelTask?t:t._cancelTaskDlgt),this._hasTaskZS=n&&(n.onHasTask?n:t._hasTaskZS),this._hasTaskDlgt=n&&(n.onHasTask?t:t._hasTaskDlgt)}return e.prototype.fork=function(e,t){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,e,t):new h(e,t)},e.prototype.intercept=function(e,t,n){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this.zone,e,t,n):t},e.prototype.invoke=function(e,t,n,r,o){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this.zone,e,t,n,r,o):t.apply(n,r)},e.prototype.handleError=function(e,t){return this._handleErrorZS?this._handleErrorZS.onHandleError(this._handleErrorDlgt,this.zone,e,t):!0},e.prototype.scheduleTask=function(e,t){try{if(this._scheduleTaskZS)return this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this.zone,e,t);if(t.scheduleFn)t.scheduleFn(t);else{if("microTask"!=t.type)throw new Error("Task is missing scheduleFn.");r(t)}return t}finally{e==this.zone&&this._updateTaskCount(t.type,1)}},e.prototype.invokeTask=function(e,t,n,r){try{return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this.zone,e,t,n,r):t.callback.apply(n,r)}finally{e!=this.zone||"eventTask"==t.type||t.data&&t.data.isPeriodic||this._updateTaskCount(t.type,-1)}},e.prototype.cancelTask=function(e,t){var n;if(this._cancelTaskZS)n=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this.zone,e,t);else{if(!t.cancelFn)throw new Error("Task does not support cancellation, or is already canceled.");n=t.cancelFn(t)}return e==this.zone&&this._updateTaskCount(t.type,-1),n},e.prototype.hasTask=function(e,t){return this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this.zone,e,t)},e.prototype._updateTaskCount=function(e,t){var n=this._taskCounts,r=n[e],o=n[e]=r+t;if(0>o)throw new Error("More tasks executed then were scheduled.");if(0==r||0==o){var a={microTask:n.microTask>0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};try{this.hasTask(this.zone,a)}finally{this._parentDelegate&&this._parentDelegate._updateTaskCount(e,t)}}},e}(),v=function(){function e(e,t,n,r,o,i,u){this.runCount=0,this.type=e,this.zone=t,this.source=n,this.data=o,this.scheduleFn=i,this.cancelFn=u,this.callback=r;var c=this;this.invoke=function(){try{return t.runTask(c,this,arguments)}finally{a()}}}return e}(),y=t("setTimeout"),g=t("Promise"),k=t("then"),m=new h(null,null),T=null,w=[],_=!1,b=[],E=!1,S=t("state"),O=t("value"),D="Promise.then",P=null,M=!0,z=!1,j=0,C=function(){function e(e){var t=this;t[S]=P,t[O]=[];try{e&&e(s(t,M),s(t,z))}catch(n){l(t,!1,n)}}return e.resolve=function(e){return l(new this(null),M,e)},e.reject=function(e){return l(new this(null),z,e)},e.race=function(e){function t(e){a&&(a=r(e))}function n(e){a&&(a=o(e))}for(var r,o,a=new this(function(e,t){r=e,o=t}),u=0,c=e;u<c.length;u++){var s=c[u];i(s)||(s=this.resolve(s)),s.then(t,n)}return a},e.all=function(e){function t(e){o&&r(e),o=null}for(var n,r,o=new this(function(e,t){n=e,r=t}),a=0,u=[],c=0,s=e;c<s.length;c++){var l=s[c];i(l)||(l=this.resolve(l)),l.then(function(e){return function(t){u[e]=t,a--,o&&!a&&n(u)}}(a),t),a++}return a||n(u),o},e.prototype.then=function(t,n){var r=new e(null),o=h.current;return this[S]==P?this[O].push(o,r,t,n):p(this,o,r,t,n),r},e.prototype["catch"]=function(e){return this.then(null,e)},e}(),Z=e[t("Promise")]=e.Promise;if(e.Promise=C,Z){var I=Z.prototype,L=I[t("then")]=I.then;I.then=function(e,t){var n=this;return new C(function(e,t){L.call(n,e,t)}).then(e,t)}}return e.Zone=h})("undefined"==typeof window?e:window)}).call(t,function(){return this}())},function(e,t,n){"use strict";function r(e){var t=[],n=e.wtf;n?t=a.split(",").map(function(e){return"HTML"+e+"Element"}).concat(i):e[u]?t.push(u):t=i;for(var r=0;r<t.length;r++){var c=e[t[r]];o.patchEventTargetMethods(c&&c.prototype)}}var o=n(3),a="Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video",i="ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex".split(","),u="EventTarget";t.eventTargetPatch=r},function(e,t){(function(e){"use strict";function n(e,t){for(var n=e.length-1;n>=0;n--)"function"==typeof e[n]&&(e[n]=Zone.current.wrap(e[n],t+"_"+n));return e}function r(e,t){for(var r=e.constructor.name,o=function(o){var a=t[o],i=e[a];i&&(e[a]=function(e){return function(){return e.apply(this,n(arguments,r+"."+a))}}(i))},a=0;a<t.length;a++)o(a)}function o(e,t){var n=Object.getOwnPropertyDescriptor(e,t)||{enumerable:!0,configurable:!0};delete n.writable,delete n.value;var r=t.substr(2),o="_"+t;n.set=function(e){if(this[o]&&this.removeEventListener(r,this[o]),"function"==typeof e){var t=function(t){var n;n=e.apply(this,arguments),void 0==n||n||t.preventDefault()};this[o]=t,this.addEventListener(r,t,!1)}else this[o]=null},n.get=function(){return this[o]},Object.defineProperty(e,t,n)}function a(e,t){var n=[];for(var r in e)"on"==r.substr(0,2)&&n.push(r);for(var a=0;a<n.length;a++)o(e,n[a]);if(t)for(var i=0;i<t.length;i++)o(e,"on"+t[i])}function i(e,t,n,r,o){var a=e[g];if(a)for(var i=0;i<a.length;i++){var u=a[i],c=u.data;if(c.handler===t&&c.useCapturing===r&&c.eventName===n)return o&&a.splice(i,1),u}return null}function u(e,t){var n=e[g];n||(n=e[g]=[]),n.push(t)}function c(e){var t=e.data;return u(t.target,e),t.target[T](t.eventName,e.invoke,t.useCapturing)}function s(e){var t=e.data;i(t.target,e.invoke,t.eventName,t.useCapturing,!0),t.target[w](t.eventName,e.invoke,t.useCapturing)}function l(e,t){var n=t[0],r=t[1],o=t[2]||!1,a=e||y,u=null;"function"==typeof r?u=r:r&&r.handleEvent&&(u=function(e){return r.handleEvent(e)});var l=!1;try{l=r&&"[object FunctionWrapper]"===r.toString()}catch(f){return}if(!u||l)return a[T](n,r,o);var p=i(a,r,n,o,!1);if(p)return a[T](n,p.invoke,o);var h=Zone.current,d=a.constructor.name+".addEventListener:"+n,v={target:a,eventName:n,name:n,useCapturing:o,handler:r};h.scheduleEventTask(d,u,v,c,s)}function f(e,t){var n=t[0],r=t[1],o=t[2]||!1,a=e||y,u=i(a,r,n,o,!0);u?u.zone.cancelTask(u):a[w](n,r,o)}function p(e){return e&&e.addEventListener?(v(e,k,function(){return l}),v(e,m,function(){return f}),!0):!1}function h(e){var t=y[e];if(t){y[e]=function(){var r=n(arguments,e);switch(r.length){case 0:this[_]=new t;break;case 1:this[_]=new t(r[0]);break;case 2:this[_]=new t(r[0],r[1]);break;case 3:this[_]=new t(r[0],r[1],r[2]);break;case 4:this[_]=new t(r[0],r[1],r[2],r[3]);break;default:throw new Error("Arg list too long.")}};var r,o=new t(function(){});for(r in o)!function(t){"function"==typeof o[t]?y[e].prototype[t]=function(){return this[_][t].apply(this[_],arguments)}:Object.defineProperty(y[e].prototype,t,{set:function(n){"function"==typeof n?this[_][t]=Zone.current.wrap(n,e+"."+t):this[_][t]=n},get:function(){return this[_][t]}})}(r);for(r in t)"prototype"!==r&&t.hasOwnProperty(r)&&(y[e][r]=t[r])}}function d(e,t){try{return Function("f","return function "+e+"(){return f(this, arguments)}")(t)}catch(n){return function(){return t(this,arguments)}}}function v(e,n,r){for(var o=e;o&&!o.hasOwnProperty(n);)o=Object.getPrototypeOf(o);!o&&e[n]&&(o=e);var a,i=t.zoneSymbol(n);return o&&!(a=o[i])&&(a=o[i]=o[n],o[n]=d(n,r(a,i,n))),a}t.zoneSymbol=Zone.__symbol__;var y="undefined"==typeof window?e:window;t.bindArguments=n,t.patchPrototype=r,t.isWebWorker="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,t.isNode="undefined"!=typeof process&&"[object process]"==={}.toString.call(process),t.isBrowser=!t.isNode&&!t.isWebWorker&&!("undefined"==typeof window||!window.HTMLElement),t.patchProperty=o,t.patchOnProperties=a;var g=t.zoneSymbol("eventTasks"),k="addEventListener",m="removeEventListener",T=t.zoneSymbol(k),w=t.zoneSymbol(m);t.patchEventTargetMethods=p;var _=t.zoneSymbol("originalInstance");t.patchClass=h,t.createNamedFn=d,t.patchMethod=v}).call(t,function(){return this}())},function(e,t,n){"use strict";function r(){Object.defineProperty=function(e,t,n){if(a(e,t))throw new TypeError("Cannot assign to read only property '"+t+"' of "+e);return"prototype"!==t&&(n=i(e,t,n)),c(e,t,n)},Object.defineProperties=function(e,t){return Object.keys(t).forEach(function(n){Object.defineProperty(e,n,t[n])}),e},Object.create=function(e,t){return"object"==typeof t&&Object.keys(t).forEach(function(n){t[n]=i(e,n,t[n])}),l(e,t)},Object.getOwnPropertyDescriptor=function(e,t){var n=s(e,t);return a(e,t)&&(n.configurable=!1),n}}function o(e,t,n){return n=i(e,t,n),c(e,t,n)}function a(e,t){return e&&e[f]&&e[f][t]}function i(e,t,n){return n.configurable=!0,n.configurable||(e[f]||c(e,f,{writable:!0,value:{}}),e[f][t]=!0),n}var u=n(3),c=Object.defineProperty,s=Object.getOwnPropertyDescriptor,l=Object.create,f=u.zoneSymbol("unconfigurables");t.propertyPatch=r,t._redefineProperty=o},function(e,t,n){"use strict";function r(e){if(a.isBrowser&&"registerElement"in e.document){var t=document.registerElement,n=["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"];document.registerElement=function(e,r){return r&&r.prototype&&n.forEach(function(e){var t="Document.registerElement::"+e;if(r.prototype.hasOwnProperty(e)){var n=Object.getOwnPropertyDescriptor(r.prototype,e);n&&n.value?(n.value=Zone.current.wrap(n.value,t),o._redefineProperty(r.prototype,e,n)):r.prototype[e]=Zone.current.wrap(r.prototype[e],t)}else r.prototype[e]&&(r.prototype[e]=Zone.current.wrap(r.prototype[e],t))}),t.apply(document,[e,r])}}}var o=n(4),a=n(3);t.registerElementPatch=r},function(e,t,n){"use strict";function r(e){if(!u.isNode){var t="undefined"!=typeof WebSocket;o()?(u.isBrowser&&u.patchOnProperties(HTMLElement.prototype,c),u.patchOnProperties(XMLHttpRequest.prototype,null),"undefined"!=typeof IDBIndex&&(u.patchOnProperties(IDBIndex.prototype,null),u.patchOnProperties(IDBRequest.prototype,null),u.patchOnProperties(IDBOpenDBRequest.prototype,null),u.patchOnProperties(IDBDatabase.prototype,null),u.patchOnProperties(IDBTransaction.prototype,null),u.patchOnProperties(IDBCursor.prototype,null)),t&&u.patchOnProperties(WebSocket.prototype,null)):(a(),u.patchClass("XMLHttpRequest"),t&&i.apply(e))}}function o(){if(u.isBrowser&&!Object.getOwnPropertyDescriptor(HTMLElement.prototype,"onclick")&&"undefined"!=typeof Element){var e=Object.getOwnPropertyDescriptor(Element.prototype,"onclick");if(e&&!e.configurable)return!1}Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{get:function(){return!0}});var t=new XMLHttpRequest,n=!!t.onreadystatechange;return Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{}),n}function a(){for(var e=function(e){var t=c[e],n="on"+t;document.addEventListener(t,function(e){var t,r,o=e.target;for(r=o?o.constructor.name+"."+n:"unknown."+n;o;)o[n]&&!o[n][s]&&(t=Zone.current.wrap(o[n],r),t[s]=o[n],o[n]=t),o=o.parentElement},!0)},t=0;t<c.length;t++)e(t)}var i=n(7),u=n(3),c="copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror".split(" ");t.propertyDescriptorPatch=r;var s=u.zoneSymbol("unbound")},function(e,t,n){"use strict";function r(e){var t=e.WebSocket;e.EventTarget||o.patchEventTargetMethods(t.prototype),e.WebSocket=function(e,n){var r,a=arguments.length>1?new t(e,n):new t(e),i=Object.getOwnPropertyDescriptor(a,"onmessage");return i&&i.configurable===!1?(r=Object.create(a),["addEventListener","removeEventListener","send","close"].forEach(function(e){r[e]=function(){return a[e].apply(a,arguments)}})):r=a,o.patchOnProperties(r,["close","error","message","open"]),r};for(var n in t)e.WebSocket[n]=t[n]}var o=n(3);t.apply=r},function(e,t,n){"use strict";function r(e,t,n,r){function a(t){var n=t.data;return n.args[0]=t.invoke,n.handleId=u.apply(e,n.args),t}function i(e){return c(e.data.handleId)}var u=null,c=null;t+=r,n+=r,u=o.patchMethod(e,t,function(n){return function(o,u){if("function"==typeof u[0]){var c=Zone.current,s={handleId:null,isPeriodic:"Interval"===r,delay:"Timeout"===r||"Interval"===r?u[1]||0:null,args:u};return c.scheduleMacroTask(t,u[0],s,a,i)}return n.apply(e,u)}}),c=o.patchMethod(e,n,function(t){return function(n,r){var o=r[0];o&&"string"==typeof o.type?(o.cancelFn&&o.data.isPeriodic||0===o.runCount)&&o.zone.cancelTask(o):t.apply(e,r)}})}var o=n(3);t.patchTimer=r}]),function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t){"use strict";!function(){function e(){return new Error("STACKTRACE TRACKING")}function t(){try{throw e()}catch(t){return t}}function n(e){return e.stack?e.stack.split(u):[]}function r(e,t){for(var r=n(t),o=0;o<r.length;o++){var a=r[o];o<s.length&&s[o]===a||e.push(r[o])}}function o(e,t){var n=[t];if(e)for(var o=(new Date).getTime(),a=0;a<e.length;a++){var i=e[a],s=i.timestamp;n.push(c+" Elapsed: "+(o-s.getTime())+" ms; At: "+s+" "+c),r(n,i.error),o=s.getTime()}return n.join(u)}function a(e,t){t>0&&(e.push(n((new f).error)),a(e,t-1))}function i(){var e=[];a(e,2);for(var t=e[0],n=e[1],r=0;r<t.length;r++){var o=t[r],i=n[r];if(o!==i)break;s.push(o)}}var u="\n",c="  -------------  ",s=[],l="__creationTrace__",f=function(){function e(){this.error=d(),this.timestamp=new Date}return e}(),p=e(),h=t(),d=p.stack?e:h.stack?t:e;Zone.longStackTraceZoneSpec={name:"long-stack-trace",longStackTraceLimit:10,onScheduleTask:function(e,t,n,r){var o=Zone.currentTask,a=o&&o.data&&o.data[l]||[];return a=[new f].concat(a),a.length>this.longStackTraceLimit&&(a.length=this.longStackTraceLimit),r.data||(r.data={}),r.data[l]=a,e.scheduleTask(n,r)},onHandleError:function(e,t,n,r){var a=Zone.currentTask;if(r instanceof Error&&a){var i=Object.getOwnPropertyDescriptor(r,"stack");if(i){var u=i.get,c=i.value;i={get:function(){return o(a.data&&a.data[l],u?u.apply(this):c)}},Object.defineProperty(r,"stack",i)}else r.stack=o(a.data&&a.data[l],r.stack)}return e.handleError(n,r)}},i()}()}]);var Reflect;!function(e){function t(e,t,n,r){if(_(r)){if(_(n)){if(!b(e))throw new TypeError;if(!S(t))throw new TypeError;return f(e,t)}if(!b(e))throw new TypeError;if(!E(t))throw new TypeError;return n=D(n),h(e,t,n)}if(!b(e))throw new TypeError;if(!E(t))throw new TypeError;if(_(n))throw new TypeError;if(!E(r))throw new TypeError;return n=D(n),p(e,t,n,r)}function n(e,t){function n(n,r){if(_(r)){if(!S(n))throw new TypeError;m(e,t,n,void 0)}else{if(!E(n))throw new TypeError;r=D(r),m(e,t,n,r)}}return n}function r(e,t,n,r){if(!E(n))throw new TypeError;return _(r)||(r=D(r)),m(e,t,n,r)}function o(e,t,n){if(!E(t))throw new TypeError;return _(n)||(n=D(n)),v(e,t,n)}function a(e,t,n){if(!E(t))throw new TypeError;return _(n)||(n=D(n)),y(e,t,n)}function i(e,t,n){if(!E(t))throw new TypeError;return _(n)||(n=D(n)),g(e,t,n)}function u(e,t,n){if(!E(t))throw new TypeError;return _(n)||(n=D(n)),k(e,t,n)}function c(e,t){if(!E(e))throw new TypeError;return _(t)||(t=D(t)),T(e,t)}function s(e,t){if(!E(e))throw new TypeError;return _(t)||(t=D(t)),w(e,t)}function l(e,t,n){if(!E(t))throw new TypeError;_(n)||(n=D(n));var r=d(t,n,!1);if(_(r))return!1;if(!r["delete"](e))return!1;if(r.size>0)return!0;var o=R.get(t);return o["delete"](n),o.size>0?!0:(R["delete"](t),!0)}function f(e,t){for(var n=e.length-1;n>=0;--n){var r=e[n],o=r(t);if(!_(o)){if(!S(o))throw new TypeError;t=o}}return t}function p(e,t,n,r){for(var o=e.length-1;o>=0;--o){var a=e[o],i=a(t,n,r);if(!_(i)){if(!E(i))throw new TypeError;r=i}}return r}function h(e,t,n){for(var r=e.length-1;r>=0;--r){var o=e[r];o(t,n)}}function d(e,t,n){var r=R.get(e);if(!r){if(!n)return;r=new Z,R.set(e,r)}var o=r.get(t);if(!o){if(!n)return;o=new Z,r.set(t,o)}return o}function v(e,t,n){var r=y(e,t,n);if(r)return!0;var o=P(t);return null!==o?v(e,o,n):!1}function y(e,t,n){var r=d(t,n,!1);return void 0===r?!1:Boolean(r.has(e))}function g(e,t,n){var r=y(e,t,n);if(r)return k(e,t,n);var o=P(t);return null!==o?g(e,o,n):void 0}function k(e,t,n){var r=d(t,n,!1);if(void 0!==r)return r.get(e)}function m(e,t,n,r){var o=d(n,r,!0);o.set(e,t)}function T(e,t){var n=w(e,t),r=P(e);if(null===r)return n;var o=T(r,t);if(o.length<=0)return n;if(n.length<=0)return o;for(var a=new I,i=[],u=0;u<n.length;u++){var c=n[u],s=a.has(c);s||(a.add(c),i.push(c))}for(var l=0;l<o.length;l++){var c=o[l],s=a.has(c);s||(a.add(c),i.push(c))}return i}function w(e,t){var n=d(e,t,!1),r=[];return n&&n.forEach(function(e,t){return r.push(t)}),r}function _(e){return void 0===e}function b(e){return Array.isArray(e)}function E(e){return"object"==typeof e?null!==e:"function"==typeof e}function S(e){return"function"==typeof e}function O(e){return"symbol"==typeof e}function D(e){return O(e)?e:String(e)}function P(e){var t=Object.getPrototypeOf(e);if("function"!=typeof e||e===C)return t;if(t!==C)return t;var n=e.prototype,r=Object.getPrototypeOf(n);if(null==r||r===Object.prototype)return t;var o=r.constructor;return"function"!=typeof o?t:o===e?t:o}function M(){function e(){this._keys=[],this._values=[],this._cache=t}var t={};return e.prototype={get size(){return this._keys.length},has:function(e){return e===this._cache?!0:this._find(e)>=0?(this._cache=e,!0):!1},get:function(e){var t=this._find(e);return t>=0?(this._cache=e,this._values[t]):void 0},set:function(e,t){return this["delete"](e),this._keys.push(e),this._values.push(t),this._cache=e,this},"delete":function(e){var n=this._find(e);return n>=0?(this._keys.splice(n,1),this._values.splice(n,1),this._cache=t,!0):!1},clear:function(){this._keys.length=0,this._values.length=0,this._cache=t},forEach:function(e,t){for(var n=this.size,r=0;n>r;++r){var o=this._keys[r],a=this._values[r];this._cache=o,e.call(this,a,o,this)}},_find:function(e){for(var t=this._keys,n=t.length,r=0;n>r;++r)if(t[r]===e)return r;return-1}},e}function z(){function e(){this._map=new Z}return e.prototype={get size(){return this._map.length},has:function(e){return this._map.has(e)},add:function(e){return this._map.set(e,e),this},"delete":function(e){return this._map["delete"](e)},clear:function(){this._map.clear()},forEach:function(e,t){this._map.forEach(e,t)}},e}function j(){function e(){this._key=o()}function t(e,t){for(var n=0;t>n;++n)e[n]=255*Math.random()|0}function n(e){if(c){var n=c.randomBytes(e);return n}if("function"==typeof Uint8Array){var n=new Uint8Array(e);return"undefined"!=typeof crypto?crypto.getRandomValues(n):"undefined"!=typeof msCrypto?msCrypto.getRandomValues(n):t(n,e),n}var n=new Array(e);return t(n,e),n}function r(){var e=n(i);e[6]=79&e[6]|64,e[8]=191&e[8]|128;for(var t="",r=0;i>r;++r){var o=e[r];(4===r||6===r||8===r)&&(t+="-"),16>o&&(t+="0"),t+=o.toString(16).toLowerCase()}return t}function o(){var e;do e="@@WeakMap@@"+r();while(s.call(l,e));return l[e]=!0,e}function a(e,t){if(!s.call(e,f)){if(!t)return;Object.defineProperty(e,f,{value:Object.create(null)})}return e[f]}var i=16,u="undefined"!=typeof global&&"[object process]"===Object.prototype.toString.call(global.process),c=u&&require("crypto"),s=Object.prototype.hasOwnProperty,l={},f=o();return e.prototype={has:function(e){var t=a(e,!1);return t?this._key in t:!1},get:function(e){var t=a(e,!1);return t?t[this._key]:void 0},set:function(e,t){var n=a(e,!0);return n[this._key]=t,this},"delete":function(e){var t=a(e,!1);return t&&this._key in t?delete t[this._key]:!1},clear:function(){this._key=o()}},e}var C=Object.getPrototypeOf(Function),Z="function"==typeof Map?Map:M(),I="function"==typeof Set?Set:z(),L="function"==typeof WeakMap?WeakMap:j(),R=new L;e.decorate=t,e.metadata=n,e.defineMetadata=r,e.hasMetadata=o,e.hasOwnMetadata=a,e.getMetadata=i,e.getOwnMetadata=u,e.getMetadataKeys=c,e.getOwnMetadataKeys=s,e.deleteMetadata=l,function(t){if("undefined"!=typeof t.Reflect){if(t.Reflect!==e)for(var n in e)t.Reflect[n]=e[n]}else t.Reflect=e}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope?self:"undefined"!=typeof global?global:Function("return this;")())}(Reflect||(Reflect={}));
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/accessible/libs/es6-shim.min.js b/blockly/webif/static/blockly/accessible/libs/es6-shim.min.js
                new file mode 100644
                index 000000000..9a11646fc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/libs/es6-shim.min.js
                @@ -0,0 +1,12 @@
                +/*!
                +  * https://github.com/paulmillr/es6-shim
                +  * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
                +  *   and contributors,  MIT License
                +  * es6-shim: v0.35.1
                +  * see https://github.com/paulmillr/es6-shim/blob/0.35.1/LICENSE
                +  * Details and documentation:
                +  * https://github.com/paulmillr/es6-shim/
                +  */
                +(function(e,t){if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{e.returnExports=t()}})(this,function(){"use strict";var e=Function.call.bind(Function.apply);var t=Function.call.bind(Function.call);var r=Array.isArray;var n=Object.keys;var o=function notThunker(t){return function notThunk(){return!e(t,this,arguments)}};var i=function(e){try{e();return false}catch(t){return true}};var a=function valueOrFalseIfThrows(e){try{return e()}catch(t){return false}};var u=o(i);var f=function(){return!i(function(){Object.defineProperty({},"x",{get:function(){}})})};var s=!!Object.defineProperty&&f();var c=function foo(){}.name==="foo";var l=Function.call.bind(Array.prototype.forEach);var p=Function.call.bind(Array.prototype.reduce);var v=Function.call.bind(Array.prototype.filter);var y=Function.call.bind(Array.prototype.some);var h=function(e,t,r,n){if(!n&&t in e){return}if(s){Object.defineProperty(e,t,{configurable:true,enumerable:false,writable:true,value:r})}else{e[t]=r}};var b=function(e,t,r){l(n(t),function(n){var o=t[n];h(e,n,o,!!r)})};var g=Function.call.bind(Object.prototype.toString);var d=typeof/abc/==="function"?function IsCallableSlow(e){return typeof e==="function"&&g(e)==="[object Function]"}:function IsCallableFast(e){return typeof e==="function"};var O={getter:function(e,t,r){if(!s){throw new TypeError("getters require true ES5 support")}Object.defineProperty(e,t,{configurable:true,enumerable:false,get:r})},proxy:function(e,t,r){if(!s){throw new TypeError("getters require true ES5 support")}var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,{configurable:n.configurable,enumerable:n.enumerable,get:function getKey(){return e[t]},set:function setKey(r){e[t]=r}})},redefine:function(e,t,r){if(s){var n=Object.getOwnPropertyDescriptor(e,t);n.value=r;Object.defineProperty(e,t,n)}else{e[t]=r}},defineByDescriptor:function(e,t,r){if(s){Object.defineProperty(e,t,r)}else if("value"in r){e[t]=r.value}},preserveToString:function(e,t){if(t&&d(t.toString)){h(e,"toString",t.toString.bind(t),true)}}};var m=Object.create||function(e,t){var r=function Prototype(){};r.prototype=e;var o=new r;if(typeof t!=="undefined"){n(t).forEach(function(e){O.defineByDescriptor(o,e,t[e])})}return o};var w=function(e,t){if(!Object.setPrototypeOf){return false}return a(function(){var r=function Subclass(t){var r=new e(t);Object.setPrototypeOf(r,Subclass.prototype);return r};Object.setPrototypeOf(r,e);r.prototype=m(e.prototype,{constructor:{value:r}});return t(r)})};var j=function(){if(typeof self!=="undefined"){return self}if(typeof window!=="undefined"){return window}if(typeof global!=="undefined"){return global}throw new Error("unable to locate global object")};var S=j();var T=S.isFinite;var I=Function.call.bind(String.prototype.indexOf);var E=Function.apply.bind(Array.prototype.indexOf);var P=Function.call.bind(Array.prototype.concat);var C=Function.call.bind(String.prototype.slice);var M=Function.call.bind(Array.prototype.push);var x=Function.apply.bind(Array.prototype.push);var N=Function.call.bind(Array.prototype.shift);var A=Math.max;var R=Math.min;var _=Math.floor;var k=Math.abs;var F=Math.exp;var L=Math.log;var D=Math.sqrt;var z=Function.call.bind(Object.prototype.hasOwnProperty);var q;var W=function(){};var G=S.Symbol||{};var H=G.species||"@@species";var V=Number.isNaN||function isNaN(e){return e!==e};var B=Number.isFinite||function isFinite(e){return typeof e==="number"&&T(e)};var $=d(Math.sign)?Math.sign:function sign(e){var t=Number(e);if(t===0){return t}if(V(t)){return t}return t<0?-1:1};var U=function isArguments(e){return g(e)==="[object Arguments]"};var J=function isArguments(e){return e!==null&&typeof e==="object"&&typeof e.length==="number"&&e.length>=0&&g(e)!=="[object Array]"&&g(e.callee)==="[object Function]"};var X=U(arguments)?U:J;var K={primitive:function(e){return e===null||typeof e!=="function"&&typeof e!=="object"},string:function(e){return g(e)==="[object String]"},regex:function(e){return g(e)==="[object RegExp]"},symbol:function(e){return typeof S.Symbol==="function"&&typeof e==="symbol"}};var Z=function overrideNative(e,t,r){var n=e[t];h(e,t,r,true);O.preserveToString(e[t],n)};var Y=typeof G==="function"&&typeof G["for"]==="function"&&K.symbol(G());var Q=K.symbol(G.iterator)?G.iterator:"_es6-shim iterator_";if(S.Set&&typeof(new S.Set)["@@iterator"]==="function"){Q="@@iterator"}if(!S.Reflect){h(S,"Reflect",{},true)}var ee=S.Reflect;var te=String;var re={Call:function Call(t,r){var n=arguments.length>2?arguments[2]:[];if(!re.IsCallable(t)){throw new TypeError(t+" is not a function")}return e(t,r,n)},RequireObjectCoercible:function(e,t){if(e==null){throw new TypeError(t||"Cannot call method on "+e)}return e},TypeIsObject:function(e){if(e===void 0||e===null||e===true||e===false){return false}return typeof e==="function"||typeof e==="object"},ToObject:function(e,t){return Object(re.RequireObjectCoercible(e,t))},IsCallable:d,IsConstructor:function(e){return re.IsCallable(e)},ToInt32:function(e){return re.ToNumber(e)>>0},ToUint32:function(e){return re.ToNumber(e)>>>0},ToNumber:function(e){if(g(e)==="[object Symbol]"){throw new TypeError("Cannot convert a Symbol value to a number")}return+e},ToInteger:function(e){var t=re.ToNumber(e);if(V(t)){return 0}if(t===0||!B(t)){return t}return(t>0?1:-1)*_(k(t))},ToLength:function(e){var t=re.ToInteger(e);if(t<=0){return 0}if(t>Number.MAX_SAFE_INTEGER){return Number.MAX_SAFE_INTEGER}return t},SameValue:function(e,t){if(e===t){if(e===0){return 1/e===1/t}return true}return V(e)&&V(t)},SameValueZero:function(e,t){return e===t||V(e)&&V(t)},IsIterable:function(e){return re.TypeIsObject(e)&&(typeof e[Q]!=="undefined"||X(e))},GetIterator:function(e){if(X(e)){return new q(e,"value")}var t=re.GetMethod(e,Q);if(!re.IsCallable(t)){throw new TypeError("value is not an iterable")}var r=re.Call(t,e);if(!re.TypeIsObject(r)){throw new TypeError("bad iterator")}return r},GetMethod:function(e,t){var r=re.ToObject(e)[t];if(r===void 0||r===null){return void 0}if(!re.IsCallable(r)){throw new TypeError("Method not callable: "+t)}return r},IteratorComplete:function(e){return!!e.done},IteratorClose:function(e,t){var r=re.GetMethod(e,"return");if(r===void 0){return}var n,o;try{n=re.Call(r,e)}catch(i){o=i}if(t){return}if(o){throw o}if(!re.TypeIsObject(n)){throw new TypeError("Iterator's return method returned a non-object.")}},IteratorNext:function(e){var t=arguments.length>1?e.next(arguments[1]):e.next();if(!re.TypeIsObject(t)){throw new TypeError("bad iterator")}return t},IteratorStep:function(e){var t=re.IteratorNext(e);var r=re.IteratorComplete(t);return r?false:t},Construct:function(e,t,r,n){var o=typeof r==="undefined"?e:r;if(!n&&ee.construct){return ee.construct(e,t,o)}var i=o.prototype;if(!re.TypeIsObject(i)){i=Object.prototype}var a=m(i);var u=re.Call(e,a,t);return re.TypeIsObject(u)?u:a},SpeciesConstructor:function(e,t){var r=e.constructor;if(r===void 0){return t}if(!re.TypeIsObject(r)){throw new TypeError("Bad constructor")}var n=r[H];if(n===void 0||n===null){return t}if(!re.IsConstructor(n)){throw new TypeError("Bad @@species")}return n},CreateHTML:function(e,t,r,n){var o=re.ToString(e);var i="<"+t;if(r!==""){var a=re.ToString(n);var u=a.replace(/"/g,"&quot;");i+=" "+r+'="'+u+'"'}var f=i+">";var s=f+o;return s+"</"+t+">"},IsRegExp:function IsRegExp(e){if(!re.TypeIsObject(e)){return false}var t=e[G.match];if(typeof t!=="undefined"){return!!t}return K.regex(e)},ToString:function ToString(e){return te(e)}};if(s&&Y){var ne=function defineWellKnownSymbol(e){if(K.symbol(G[e])){return G[e]}var t=G["for"]("Symbol."+e);Object.defineProperty(G,e,{configurable:false,enumerable:false,writable:false,value:t});return t};if(!K.symbol(G.search)){var oe=ne("search");var ie=String.prototype.search;h(RegExp.prototype,oe,function search(e){return re.Call(ie,e,[this])});var ae=function search(e){var t=re.RequireObjectCoercible(this);if(e!==null&&typeof e!=="undefined"){var r=re.GetMethod(e,oe);if(typeof r!=="undefined"){return re.Call(r,e,[t])}}return re.Call(ie,t,[re.ToString(e)])};Z(String.prototype,"search",ae)}if(!K.symbol(G.replace)){var ue=ne("replace");var fe=String.prototype.replace;h(RegExp.prototype,ue,function replace(e,t){return re.Call(fe,e,[this,t])});var se=function replace(e,t){var r=re.RequireObjectCoercible(this);if(e!==null&&typeof e!=="undefined"){var n=re.GetMethod(e,ue);if(typeof n!=="undefined"){return re.Call(n,e,[r,t])}}return re.Call(fe,r,[re.ToString(e),t])};Z(String.prototype,"replace",se)}if(!K.symbol(G.split)){var ce=ne("split");var le=String.prototype.split;h(RegExp.prototype,ce,function split(e,t){return re.Call(le,e,[this,t])});var pe=function split(e,t){var r=re.RequireObjectCoercible(this);if(e!==null&&typeof e!=="undefined"){var n=re.GetMethod(e,ce);if(typeof n!=="undefined"){return re.Call(n,e,[r,t])}}return re.Call(le,r,[re.ToString(e),t])};Z(String.prototype,"split",pe)}var ve=K.symbol(G.match);var ye=ve&&function(){var e={};e[G.match]=function(){return 42};return"a".match(e)!==42}();if(!ve||ye){var he=ne("match");var be=String.prototype.match;h(RegExp.prototype,he,function match(e){return re.Call(be,e,[this])});var ge=function match(e){var t=re.RequireObjectCoercible(this);if(e!==null&&typeof e!=="undefined"){var r=re.GetMethod(e,he);if(typeof r!=="undefined"){return re.Call(r,e,[t])}}return re.Call(be,t,[re.ToString(e)])};Z(String.prototype,"match",ge)}}var de=function wrapConstructor(e,t,r){O.preserveToString(t,e);if(Object.setPrototypeOf){Object.setPrototypeOf(e,t)}if(s){l(Object.getOwnPropertyNames(e),function(n){if(n in W||r[n]){return}O.proxy(e,n,t)})}else{l(Object.keys(e),function(n){if(n in W||r[n]){return}t[n]=e[n]})}t.prototype=e.prototype;O.redefine(e.prototype,"constructor",t)};var Oe=function(){return this};var me=function(e){if(s&&!z(e,H)){O.getter(e,H,Oe)}};var we=function(e,t){var r=t||function iterator(){return this};h(e,Q,r);if(!e[Q]&&K.symbol(Q)){e[Q]=r}};var je=function createDataProperty(e,t,r){if(s){Object.defineProperty(e,t,{configurable:true,enumerable:true,writable:true,value:r})}else{e[t]=r}};var Se=function createDataPropertyOrThrow(e,t,r){je(e,t,r);if(!re.SameValue(e[t],r)){throw new TypeError("property is nonconfigurable")}};var Te=function(e,t,r,n){if(!re.TypeIsObject(e)){throw new TypeError("Constructor requires `new`: "+t.name)}var o=t.prototype;if(!re.TypeIsObject(o)){o=r}var i=m(o);for(var a in n){if(z(n,a)){var u=n[a];h(i,a,u,true)}}return i};if(String.fromCodePoint&&String.fromCodePoint.length!==1){var Ie=String.fromCodePoint;Z(String,"fromCodePoint",function fromCodePoint(e){return re.Call(Ie,this,arguments)})}var Ee={fromCodePoint:function fromCodePoint(e){var t=[];var r;for(var n=0,o=arguments.length;n<o;n++){r=Number(arguments[n]);if(!re.SameValue(r,re.ToInteger(r))||r<0||r>1114111){throw new RangeError("Invalid code point "+r)}if(r<65536){M(t,String.fromCharCode(r))}else{r-=65536;M(t,String.fromCharCode((r>>10)+55296));M(t,String.fromCharCode(r%1024+56320))}}return t.join("")},raw:function raw(e){var t=re.ToObject(e,"bad callSite");var r=re.ToObject(t.raw,"bad raw value");var n=r.length;var o=re.ToLength(n);if(o<=0){return""}var i=[];var a=0;var u,f,s,c;while(a<o){u=re.ToString(a);s=re.ToString(r[u]);M(i,s);if(a+1>=o){break}f=a+1<arguments.length?arguments[a+1]:"";c=re.ToString(f);M(i,c);a+=1}return i.join("")}};if(String.raw&&String.raw({raw:{0:"x",1:"y",length:2}})!=="xy"){Z(String,"raw",Ee.raw)}b(String,Ee);var Pe=function repeat(e,t){if(t<1){return""}if(t%2){return repeat(e,t-1)+e}var r=repeat(e,t/2);return r+r};var Ce=Infinity;var Me={repeat:function repeat(e){var t=re.ToString(re.RequireObjectCoercible(this));var r=re.ToInteger(e);if(r<0||r>=Ce){throw new RangeError("repeat count must be less than infinity and not overflow maximum string size")}return Pe(t,r)},startsWith:function startsWith(e){var t=re.ToString(re.RequireObjectCoercible(this));if(re.IsRegExp(e)){throw new TypeError('Cannot call method "startsWith" with a regex')}var r=re.ToString(e);var n;if(arguments.length>1){n=arguments[1]}var o=A(re.ToInteger(n),0);return C(t,o,o+r.length)===r},endsWith:function endsWith(e){var t=re.ToString(re.RequireObjectCoercible(this));if(re.IsRegExp(e)){throw new TypeError('Cannot call method "endsWith" with a regex')}var r=re.ToString(e);var n=t.length;var o;if(arguments.length>1){o=arguments[1]}var i=typeof o==="undefined"?n:re.ToInteger(o);var a=R(A(i,0),n);return C(t,a-r.length,a)===r},includes:function includes(e){if(re.IsRegExp(e)){throw new TypeError('"includes" does not accept a RegExp')}var t=re.ToString(e);var r;if(arguments.length>1){r=arguments[1]}return I(this,t,r)!==-1},codePointAt:function codePointAt(e){var t=re.ToString(re.RequireObjectCoercible(this));var r=re.ToInteger(e);var n=t.length;if(r>=0&&r<n){var o=t.charCodeAt(r);var i=r+1===n;if(o<55296||o>56319||i){return o}var a=t.charCodeAt(r+1);if(a<56320||a>57343){return o}return(o-55296)*1024+(a-56320)+65536}}};if(String.prototype.includes&&"a".includes("a",Infinity)!==false){Z(String.prototype,"includes",Me.includes)}if(String.prototype.startsWith&&String.prototype.endsWith){var xe=i(function(){"/a/".startsWith(/a/)});var Ne=a(function(){return"abc".startsWith("a",Infinity)===false});if(!xe||!Ne){Z(String.prototype,"startsWith",Me.startsWith);Z(String.prototype,"endsWith",Me.endsWith)}}if(Y){var Ae=a(function(){var e=/a/;e[G.match]=false;return"/a/".startsWith(e)});if(!Ae){Z(String.prototype,"startsWith",Me.startsWith)}var Re=a(function(){var e=/a/;e[G.match]=false;return"/a/".endsWith(e)});if(!Re){Z(String.prototype,"endsWith",Me.endsWith)}var _e=a(function(){var e=/a/;e[G.match]=false;return"/a/".includes(e)});if(!_e){Z(String.prototype,"includes",Me.includes)}}b(String.prototype,Me);var ke=["   \n\x0B\f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003","\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028","\u2029\ufeff"].join("");var Fe=new RegExp("(^["+ke+"]+)|(["+ke+"]+$)","g");var Le=function trim(){return re.ToString(re.RequireObjectCoercible(this)).replace(Fe,"")};var De=["\x85","\u200b","\ufffe"].join("");var ze=new RegExp("["+De+"]","g");var qe=/^[\-+]0x[0-9a-f]+$/i;var We=De.trim().length!==De.length;h(String.prototype,"trim",Le,We);var Ge=function(e){return{value:e,done:arguments.length===0}};var He=function(e){re.RequireObjectCoercible(e);this._s=re.ToString(e);this._i=0};He.prototype.next=function(){var e=this._s;var t=this._i;if(typeof e==="undefined"||t>=e.length){this._s=void 0;return Ge()}var r=e.charCodeAt(t);var n,o;if(r<55296||r>56319||t+1===e.length){o=1}else{n=e.charCodeAt(t+1);o=n<56320||n>57343?1:2}this._i=t+o;return Ge(e.substr(t,o))};we(He.prototype);we(String.prototype,function(){return new He(this)});var Ve={from:function from(e){var r=this;var n;if(arguments.length>1){n=arguments[1]}var o,i;if(typeof n==="undefined"){o=false}else{if(!re.IsCallable(n)){throw new TypeError("Array.from: when provided, the second argument must be a function")}if(arguments.length>2){i=arguments[2]}o=true}var a=typeof(X(e)||re.GetMethod(e,Q))!=="undefined";var u,f,s;if(a){f=re.IsConstructor(r)?Object(new r):[];var c=re.GetIterator(e);var l,p;s=0;while(true){l=re.IteratorStep(c);if(l===false){break}p=l.value;try{if(o){p=typeof i==="undefined"?n(p,s):t(n,i,p,s)}f[s]=p}catch(v){re.IteratorClose(c,true);throw v}s+=1}u=s}else{var y=re.ToObject(e);u=re.ToLength(y.length);f=re.IsConstructor(r)?Object(new r(u)):new Array(u);var h;for(s=0;s<u;++s){h=y[s];if(o){h=typeof i==="undefined"?n(h,s):t(n,i,h,s)}Se(f,s,h)}}f.length=u;return f},of:function of(){var e=arguments.length;var t=this;var n=r(t)||!re.IsCallable(t)?new Array(e):re.Construct(t,[e]);for(var o=0;o<e;++o){Se(n,o,arguments[o])}n.length=e;return n}};b(Array,Ve);me(Array);q=function(e,t){this.i=0;this.array=e;this.kind=t};b(q.prototype,{next:function(){var e=this.i;var t=this.array;if(!(this instanceof q)){throw new TypeError("Not an ArrayIterator")}if(typeof t!=="undefined"){var r=re.ToLength(t.length);for(;e<r;e++){var n=this.kind;var o;if(n==="key"){o=e}else if(n==="value"){o=t[e]}else if(n==="entry"){o=[e,t[e]]}this.i=e+1;return Ge(o)}}this.array=void 0;return Ge()}});we(q.prototype);var Be=Array.of===Ve.of||function(){var e=function Foo(e){this.length=e};e.prototype=[];var t=Array.of.apply(e,[1,2]);return t instanceof e&&t.length===2}();if(!Be){Z(Array,"of",Ve.of)}var $e={copyWithin:function copyWithin(e,t){var r=re.ToObject(this);var n=re.ToLength(r.length);var o=re.ToInteger(e);var i=re.ToInteger(t);var a=o<0?A(n+o,0):R(o,n);var u=i<0?A(n+i,0):R(i,n);var f;if(arguments.length>2){f=arguments[2]}var s=typeof f==="undefined"?n:re.ToInteger(f);var c=s<0?A(n+s,0):R(s,n);var l=R(c-u,n-a);var p=1;if(u<a&&a<u+l){p=-1;u+=l-1;a+=l-1}while(l>0){if(u in r){r[a]=r[u]}else{delete r[a]}u+=p;a+=p;l-=1}return r},fill:function fill(e){var t;if(arguments.length>1){t=arguments[1]}var r;if(arguments.length>2){r=arguments[2]}var n=re.ToObject(this);var o=re.ToLength(n.length);t=re.ToInteger(typeof t==="undefined"?0:t);r=re.ToInteger(typeof r==="undefined"?o:r);var i=t<0?A(o+t,0):R(t,o);var a=r<0?o+r:r;for(var u=i;u<o&&u<a;++u){n[u]=e}return n},find:function find(e){var r=re.ToObject(this);var n=re.ToLength(r.length);if(!re.IsCallable(e)){throw new TypeError("Array#find: predicate must be a function")}var o=arguments.length>1?arguments[1]:null;for(var i=0,a;i<n;i++){a=r[i];if(o){if(t(e,o,a,i,r)){return a}}else if(e(a,i,r)){return a}}},findIndex:function findIndex(e){var r=re.ToObject(this);var n=re.ToLength(r.length);if(!re.IsCallable(e)){throw new TypeError("Array#findIndex: predicate must be a function")}var o=arguments.length>1?arguments[1]:null;for(var i=0;i<n;i++){if(o){if(t(e,o,r[i],i,r)){return i}}else if(e(r[i],i,r)){return i}}return-1},keys:function keys(){return new q(this,"key")},values:function values(){return new q(this,"value")},entries:function entries(){return new q(this,"entry")}};if(Array.prototype.keys&&!re.IsCallable([1].keys().next)){delete Array.prototype.keys}if(Array.prototype.entries&&!re.IsCallable([1].entries().next)){delete Array.prototype.entries}if(Array.prototype.keys&&Array.prototype.entries&&!Array.prototype.values&&Array.prototype[Q]){b(Array.prototype,{values:Array.prototype[Q]});if(K.symbol(G.unscopables)){Array.prototype[G.unscopables].values=true}}if(c&&Array.prototype.values&&Array.prototype.values.name!=="values"){var Ue=Array.prototype.values;Z(Array.prototype,"values",function values(){return re.Call(Ue,this,arguments)});h(Array.prototype,Q,Array.prototype.values,true)}b(Array.prototype,$e);if(1/[true].indexOf(true,-0)<0){h(Array.prototype,"indexOf",function indexOf(e){var t=E(this,arguments);if(t===0&&1/t<0){return 0}return t},true)}we(Array.prototype,function(){return this.values()});if(Object.getPrototypeOf){we(Object.getPrototypeOf([].values()))}var Je=function(){return a(function(){return Array.from({length:-1}).length===0})}();var Xe=function(){var e=Array.from([0].entries());return e.length===1&&r(e[0])&&e[0][0]===0&&e[0][1]===0}();if(!Je||!Xe){Z(Array,"from",Ve.from)}var Ke=function(){return a(function(){return Array.from([0],void 0)})}();if(!Ke){var Ze=Array.from;Z(Array,"from",function from(e){if(arguments.length>1&&typeof arguments[1]!=="undefined"){return re.Call(Ze,this,arguments)}else{return t(Ze,this,e)}})}var Ye=-(Math.pow(2,32)-1);var Qe=function(e,r){var n={length:Ye};n[r?(n.length>>>0)-1:0]=true;return a(function(){t(e,n,function(){throw new RangeError("should not reach here")},[]);return true})};if(!Qe(Array.prototype.forEach)){var et=Array.prototype.forEach;Z(Array.prototype,"forEach",function forEach(e){return re.Call(et,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.map)){var tt=Array.prototype.map;Z(Array.prototype,"map",function map(e){return re.Call(tt,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.filter)){var rt=Array.prototype.filter;Z(Array.prototype,"filter",function filter(e){return re.Call(rt,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.some)){var nt=Array.prototype.some;Z(Array.prototype,"some",function some(e){return re.Call(nt,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.every)){var ot=Array.prototype.every;Z(Array.prototype,"every",function every(e){return re.Call(ot,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.reduce)){var it=Array.prototype.reduce;Z(Array.prototype,"reduce",function reduce(e){return re.Call(it,this.length>=0?this:[],arguments)},true)}if(!Qe(Array.prototype.reduceRight,true)){var at=Array.prototype.reduceRight;Z(Array.prototype,"reduceRight",function reduceRight(e){return re.Call(at,this.length>=0?this:[],arguments)},true)}var ut=Number("0o10")!==8;var ft=Number("0b10")!==2;var st=y(De,function(e){return Number(e+0+e)===0});if(ut||ft||st){var ct=Number;var lt=/^0b[01]+$/i;var pt=/^0o[0-7]+$/i;var vt=lt.test.bind(lt);var yt=pt.test.bind(pt);var ht=function(e){var t;if(typeof e.valueOf==="function"){t=e.valueOf();if(K.primitive(t)){return t}}if(typeof e.toString==="function"){t=e.toString();if(K.primitive(t)){return t}}throw new TypeError("No default value")};var bt=ze.test.bind(ze);var gt=qe.test.bind(qe);var dt=function(){var e=function Number(t){var r;if(arguments.length>0){r=K.primitive(t)?t:ht(t,"number")}else{r=0}if(typeof r==="string"){r=re.Call(Le,r);if(vt(r)){r=parseInt(C(r,2),2)}else if(yt(r)){r=parseInt(C(r,2),8)}else if(bt(r)||gt(r)){r=NaN}}var n=this;var o=a(function(){ct.prototype.valueOf.call(n);return true});if(n instanceof e&&!o){return new ct(r)}return ct(r)};return e}();de(ct,dt,{});b(dt,{NaN:ct.NaN,MAX_VALUE:ct.MAX_VALUE,MIN_VALUE:ct.MIN_VALUE,NEGATIVE_INFINITY:ct.NEGATIVE_INFINITY,POSITIVE_INFINITY:ct.POSITIVE_INFINITY});Number=dt;O.redefine(S,"Number",dt)}var Ot=Math.pow(2,53)-1;b(Number,{MAX_SAFE_INTEGER:Ot,MIN_SAFE_INTEGER:-Ot,EPSILON:2.220446049250313e-16,parseInt:S.parseInt,parseFloat:S.parseFloat,isFinite:B,isInteger:function isInteger(e){return B(e)&&re.ToInteger(e)===e},isSafeInteger:function isSafeInteger(e){return Number.isInteger(e)&&k(e)<=Number.MAX_SAFE_INTEGER},isNaN:V});h(Number,"parseInt",S.parseInt,Number.parseInt!==S.parseInt);if(![,1].find(function(e,t){return t===0})){Z(Array.prototype,"find",$e.find)}if([,1].findIndex(function(e,t){return t===0})!==0){Z(Array.prototype,"findIndex",$e.findIndex)}var mt=Function.bind.call(Function.bind,Object.prototype.propertyIsEnumerable);var wt=function ensureEnumerable(e,t){if(s&&mt(e,t)){Object.defineProperty(e,t,{enumerable:false})}};var jt=function sliceArgs(){var e=Number(this);var t=arguments.length;var r=t-e;var n=new Array(r<0?0:r);for(var o=e;o<t;++o){n[o-e]=arguments[o]}return n};var St=function assignTo(e){return function assignToSource(t,r){t[r]=e[r];return t}};var Tt=function(e,t){var r=n(Object(t));var o;if(re.IsCallable(Object.getOwnPropertySymbols)){o=v(Object.getOwnPropertySymbols(Object(t)),mt(t))}return p(P(r,o||[]),St(t),e)};var It={assign:function(e,t){var r=re.ToObject(e,"Cannot convert undefined or null to object");return p(re.Call(jt,1,arguments),Tt,r)},is:function is(e,t){return re.SameValue(e,t)}};var Et=Object.assign&&Object.preventExtensions&&function(){var e=Object.preventExtensions({1:2});try{Object.assign(e,"xy")}catch(t){return e[1]==="y"}}();if(Et){Z(Object,"assign",It.assign)}b(Object,It);if(s){var Pt={setPrototypeOf:function(e,r){var n;var o=function(e,t){if(!re.TypeIsObject(e)){throw new TypeError("cannot set prototype on a non-object")}if(!(t===null||re.TypeIsObject(t))){throw new TypeError("can only set prototype to an object or null"+t)}};var i=function(e,r){o(e,r);t(n,e,r);return e};try{n=e.getOwnPropertyDescriptor(e.prototype,r).set;t(n,{},null)}catch(a){if(e.prototype!=={}[r]){return}n=function(e){this[r]=e};i.polyfill=i(i({},null),e.prototype)instanceof e}return i}(Object,"__proto__")};b(Object,Pt)}if(Object.setPrototypeOf&&Object.getPrototypeOf&&Object.getPrototypeOf(Object.setPrototypeOf({},null))!==null&&Object.getPrototypeOf(Object.create(null))===null){(function(){var e=Object.create(null);var t=Object.getPrototypeOf;var r=Object.setPrototypeOf;Object.getPrototypeOf=function(r){var n=t(r);return n===e?null:n};Object.setPrototypeOf=function(t,n){var o=n===null?e:n;return r(t,o)};Object.setPrototypeOf.polyfill=false})()}var Ct=!i(function(){Object.keys("foo")});if(!Ct){var Mt=Object.keys;Z(Object,"keys",function keys(e){return Mt(re.ToObject(e))});n=Object.keys}var xt=i(function(){Object.keys(/a/g)});if(xt){var Nt=Object.keys;Z(Object,"keys",function keys(e){if(K.regex(e)){var t=[];for(var r in e){if(z(e,r)){M(t,r)}}return t}return Nt(e)});n=Object.keys}if(Object.getOwnPropertyNames){var At=!i(function(){Object.getOwnPropertyNames("foo")});if(!At){var Rt=typeof window==="object"?Object.getOwnPropertyNames(window):[];var _t=Object.getOwnPropertyNames;Z(Object,"getOwnPropertyNames",function getOwnPropertyNames(e){var t=re.ToObject(e);if(g(t)==="[object Window]"){try{return _t(t)}catch(r){return P([],Rt)}}return _t(t)})}}if(Object.getOwnPropertyDescriptor){var kt=!i(function(){Object.getOwnPropertyDescriptor("foo","bar")});if(!kt){var Ft=Object.getOwnPropertyDescriptor;Z(Object,"getOwnPropertyDescriptor",function getOwnPropertyDescriptor(e,t){return Ft(re.ToObject(e),t)})}}if(Object.seal){var Lt=!i(function(){Object.seal("foo")});if(!Lt){var Dt=Object.seal;Z(Object,"seal",function seal(e){if(!re.TypeIsObject(e)){return e}return Dt(e)})}}if(Object.isSealed){var zt=!i(function(){Object.isSealed("foo")});if(!zt){var qt=Object.isSealed;Z(Object,"isSealed",function isSealed(e){if(!re.TypeIsObject(e)){return true}return qt(e)})}}if(Object.freeze){var Wt=!i(function(){Object.freeze("foo")});if(!Wt){var Gt=Object.freeze;Z(Object,"freeze",function freeze(e){if(!re.TypeIsObject(e)){return e}return Gt(e)})}}if(Object.isFrozen){var Ht=!i(function(){Object.isFrozen("foo")});if(!Ht){var Vt=Object.isFrozen;Z(Object,"isFrozen",function isFrozen(e){if(!re.TypeIsObject(e)){return true}return Vt(e)})}}if(Object.preventExtensions){var Bt=!i(function(){Object.preventExtensions("foo")});if(!Bt){var $t=Object.preventExtensions;Z(Object,"preventExtensions",function preventExtensions(e){if(!re.TypeIsObject(e)){return e}return $t(e)})}}if(Object.isExtensible){var Ut=!i(function(){Object.isExtensible("foo")});if(!Ut){var Jt=Object.isExtensible;Z(Object,"isExtensible",function isExtensible(e){if(!re.TypeIsObject(e)){return false}return Jt(e)})}}if(Object.getPrototypeOf){var Xt=!i(function(){Object.getPrototypeOf("foo")});if(!Xt){var Kt=Object.getPrototypeOf;Z(Object,"getPrototypeOf",function getPrototypeOf(e){return Kt(re.ToObject(e))})}}var Zt=s&&function(){var e=Object.getOwnPropertyDescriptor(RegExp.prototype,"flags");return e&&re.IsCallable(e.get)}();if(s&&!Zt){var Yt=function flags(){if(!re.TypeIsObject(this)){throw new TypeError("Method called on incompatible type: must be an object.")}var e="";if(this.global){e+="g"}if(this.ignoreCase){e+="i"}if(this.multiline){e+="m"}if(this.unicode){e+="u"}if(this.sticky){e+="y"}return e};O.getter(RegExp.prototype,"flags",Yt)}var Qt=s&&a(function(){return String(new RegExp(/a/g,"i"))==="/a/i"});var er=Y&&s&&function(){var e=/./;e[G.match]=false;return RegExp(e)===e}();var tr=a(function(){return RegExp.prototype.toString.call({source:"abc"})==="/abc/"});var rr=tr&&a(function(){return RegExp.prototype.toString.call({source:"a",flags:"b"})==="/a/b"});if(!tr||!rr){var nr=RegExp.prototype.toString;h(RegExp.prototype,"toString",function toString(){var e=re.RequireObjectCoercible(this);if(K.regex(e)){return t(nr,e)}var r=te(e.source);var n=te(e.flags);return"/"+r+"/"+n},true);O.preserveToString(RegExp.prototype.toString,nr)}if(s&&(!Qt||er)){var or=Object.getOwnPropertyDescriptor(RegExp.prototype,"flags").get;var ir=Object.getOwnPropertyDescriptor(RegExp.prototype,"source")||{};var ar=function(){return this.source};var ur=re.IsCallable(ir.get)?ir.get:ar;var fr=RegExp;var sr=function(){return function RegExp(e,t){var r=re.IsRegExp(e);var n=this instanceof RegExp;if(!n&&r&&typeof t==="undefined"&&e.constructor===RegExp){return e}var o=e;var i=t;if(K.regex(e)){o=re.Call(ur,e);i=typeof t==="undefined"?re.Call(or,e):t;return new RegExp(o,i)}else if(r){o=e.source;i=typeof t==="undefined"?e.flags:t}return new fr(e,t)}}();de(fr,sr,{$input:true});RegExp=sr;O.redefine(S,"RegExp",sr)}if(s){var cr={input:"$_",lastMatch:"$&",lastParen:"$+",leftContext:"$`",rightContext:"$'"};l(n(cr),function(e){if(e in RegExp&&!(cr[e]in RegExp)){O.getter(RegExp,cr[e],function get(){return RegExp[e]})}})}me(RegExp);var lr=1/Number.EPSILON;var pr=function roundTiesToEven(e){return e+lr-lr};var vr=Math.pow(2,-23);var yr=Math.pow(2,127)*(2-vr);var hr=Math.pow(2,-126);var br=Math.E;var gr=Math.LOG2E;var dr=Math.LOG10E;var Or=Number.prototype.clz;delete Number.prototype.clz;var mr={acosh:function acosh(e){var t=Number(e);if(V(t)||e<1){return NaN}if(t===1){return 0}if(t===Infinity){return t}return L(t/br+D(t+1)*D(t-1)/br)+1},asinh:function asinh(e){var t=Number(e);if(t===0||!T(t)){return t}return t<0?-asinh(-t):L(t+D(t*t+1))},atanh:function atanh(e){var t=Number(e);if(V(t)||t<-1||t>1){return NaN}if(t===-1){return-Infinity}if(t===1){return Infinity}if(t===0){return t}return.5*L((1+t)/(1-t))},cbrt:function cbrt(e){var t=Number(e);if(t===0){return t}var r=t<0;var n;if(r){t=-t}if(t===Infinity){n=Infinity}else{n=F(L(t)/3);n=(t/(n*n)+2*n)/3}return r?-n:n},clz32:function clz32(e){var t=Number(e);var r=re.ToUint32(t);if(r===0){return 32}return Or?re.Call(Or,r):31-_(L(r+.5)*gr)},cosh:function cosh(e){var t=Number(e);if(t===0){return 1}if(V(t)){return NaN}if(!T(t)){return Infinity}if(t<0){t=-t}if(t>21){return F(t)/2}return(F(t)+F(-t))/2},expm1:function expm1(e){var t=Number(e);if(t===-Infinity){return-1}if(!T(t)||t===0){return t}if(k(t)>.5){return F(t)-1}var r=t;var n=0;var o=1;while(n+r!==n){n+=r;o+=1;r*=t/o}return n},hypot:function hypot(e,t){var r=0;var n=0;for(var o=0;o<arguments.length;++o){var i=k(Number(arguments[o]));if(n<i){r*=n/i*(n/i);r+=1;n=i}else{r+=i>0?i/n*(i/n):i}}return n===Infinity?Infinity:n*D(r)},log2:function log2(e){return L(e)*gr},log10:function log10(e){return L(e)*dr},log1p:function log1p(e){var t=Number(e);if(t<-1||V(t)){return NaN}if(t===0||t===Infinity){return t}if(t===-1){return-Infinity}return 1+t-1===0?t:t*(L(1+t)/(1+t-1))},sign:$,sinh:function sinh(e){var t=Number(e);if(!T(t)||t===0){return t}if(k(t)<1){return(Math.expm1(t)-Math.expm1(-t))/2}return(F(t-1)-F(-t-1))*br/2},tanh:function tanh(e){var t=Number(e);if(V(t)||t===0){return t}if(t>=20){return 1}if(t<=-20){return-1}return(Math.expm1(t)-Math.expm1(-t))/(F(t)+F(-t))},trunc:function trunc(e){var t=Number(e);return t<0?-_(-t):_(t)},imul:function imul(e,t){var r=re.ToUint32(e);var n=re.ToUint32(t);var o=r>>>16&65535;var i=r&65535;var a=n>>>16&65535;var u=n&65535;return i*u+(o*u+i*a<<16>>>0)|0},fround:function fround(e){var t=Number(e);if(t===0||t===Infinity||t===-Infinity||V(t)){return t}var r=$(t);var n=k(t);if(n<hr){return r*pr(n/hr/vr)*hr*vr}var o=(1+vr/Number.EPSILON)*n;var i=o-(o-n);if(i>yr||V(i)){return r*Infinity}return r*i}};b(Math,mr);h(Math,"log1p",mr.log1p,Math.log1p(-1e-17)!==-1e-17);h(Math,"asinh",mr.asinh,Math.asinh(-1e7)!==-Math.asinh(1e7));h(Math,"tanh",mr.tanh,Math.tanh(-2e-17)!==-2e-17);h(Math,"acosh",mr.acosh,Math.acosh(Number.MAX_VALUE)===Infinity);h(Math,"cbrt",mr.cbrt,Math.abs(1-Math.cbrt(1e-300)/1e-100)/Number.EPSILON>8);h(Math,"sinh",mr.sinh,Math.sinh(-2e-17)!==-2e-17);var wr=Math.expm1(10);h(Math,"expm1",mr.expm1,wr>22025.465794806718||wr<22025.465794806718);var jr=Math.round;var Sr=Math.round(.5-Number.EPSILON/4)===0&&Math.round(-.5+Number.EPSILON/3.99)===1;var Tr=lr+1;var Ir=2*lr-1;var Er=[Tr,Ir].every(function(e){return Math.round(e)===e});h(Math,"round",function round(e){var t=_(e);var r=t===-1?-0:t+1;return e-t<.5?t:r},!Sr||!Er);O.preserveToString(Math.round,jr);var Pr=Math.imul;if(Math.imul(4294967295,5)!==-5){Math.imul=mr.imul;O.preserveToString(Math.imul,Pr)}if(Math.imul.length!==2){Z(Math,"imul",function imul(e,t){return re.Call(Pr,Math,arguments);
                +})}var Cr=function(){var e=S.setTimeout;if(typeof e!=="function"&&typeof e!=="object"){return}re.IsPromise=function(e){if(!re.TypeIsObject(e)){return false}if(typeof e._promise==="undefined"){return false}return true};var r=function(e){if(!re.IsConstructor(e)){throw new TypeError("Bad promise constructor")}var t=this;var r=function(e,r){if(t.resolve!==void 0||t.reject!==void 0){throw new TypeError("Bad Promise implementation!")}t.resolve=e;t.reject=r};t.resolve=void 0;t.reject=void 0;t.promise=new e(r);if(!(re.IsCallable(t.resolve)&&re.IsCallable(t.reject))){throw new TypeError("Bad promise constructor")}};var n;if(typeof window!=="undefined"&&re.IsCallable(window.postMessage)){n=function(){var e=[];var t="zero-timeout-message";var r=function(r){M(e,r);window.postMessage(t,"*")};var n=function(r){if(r.source===window&&r.data===t){r.stopPropagation();if(e.length===0){return}var n=N(e);n()}};window.addEventListener("message",n,true);return r}}var o=function(){var e=S.Promise;var t=e&&e.resolve&&e.resolve();return t&&function(e){return t.then(e)}};var i=re.IsCallable(S.setImmediate)?S.setImmediate:typeof process==="object"&&process.nextTick?process.nextTick:o()||(re.IsCallable(n)?n():function(t){e(t,0)});var a=function(e){return e};var u=function(e){throw e};var f=0;var s=1;var c=2;var l=0;var p=1;var v=2;var y={};var h=function(e,t,r){i(function(){g(e,t,r)})};var g=function(e,t,r){var n,o;if(t===y){return e(r)}try{n=e(r);o=t.resolve}catch(i){n=i;o=t.reject}o(n)};var d=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.fulfillReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+l],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=s;r.reactionLength=0};var O=function(e,t){var r=e._promise;var n=r.reactionLength;if(n>0){h(r.rejectReactionHandler0,r.reactionCapability0,t);r.fulfillReactionHandler0=void 0;r.rejectReactions0=void 0;r.reactionCapability0=void 0;if(n>1){for(var o=1,i=0;o<n;o++,i+=3){h(r[i+p],r[i+v],t);e[i+l]=void 0;e[i+p]=void 0;e[i+v]=void 0}}}r.result=t;r.state=c;r.reactionLength=0};var m=function(e){var t=false;var r=function(r){var n;if(t){return}t=true;if(r===e){return O(e,new TypeError("Self resolution"))}if(!re.TypeIsObject(r)){return d(e,r)}try{n=r.then}catch(o){return O(e,o)}if(!re.IsCallable(n)){return d(e,r)}i(function(){j(e,r,n)})};var n=function(r){if(t){return}t=true;return O(e,r)};return{resolve:r,reject:n}};var w=function(e,r,n,o){if(e===I){t(e,r,n,o,y)}else{t(e,r,n,o)}};var j=function(e,t,r){var n=m(e);var o=n.resolve;var i=n.reject;try{w(r,t,o,i)}catch(a){i(a)}};var T,I;var E=function(){var e=function Promise(t){if(!(this instanceof e)){throw new TypeError('Constructor Promise requires "new"')}if(this&&this._promise){throw new TypeError("Bad construction")}if(!re.IsCallable(t)){throw new TypeError("not a valid resolver")}var r=Te(this,e,T,{_promise:{result:void 0,state:f,reactionLength:0,fulfillReactionHandler0:void 0,rejectReactionHandler0:void 0,reactionCapability0:void 0}});var n=m(r);var o=n.reject;try{t(n.resolve,o)}catch(i){o(i)}return r};return e}();T=E.prototype;var P=function(e,t,r,n){var o=false;return function(i){if(o){return}o=true;t[e]=i;if(--n.count===0){var a=r.resolve;a(t)}}};var C=function(e,t,r){var n=e.iterator;var o=[];var i={count:1};var a,u;var f=0;while(true){try{a=re.IteratorStep(n);if(a===false){e.done=true;break}u=a.value}catch(s){e.done=true;throw s}o[f]=void 0;var c=t.resolve(u);var l=P(f,o,r,i);i.count+=1;w(c.then,c,l,r.reject);f+=1}if(--i.count===0){var p=r.resolve;p(o)}return r.promise};var x=function(e,t,r){var n=e.iterator;var o,i,a;while(true){try{o=re.IteratorStep(n);if(o===false){e.done=true;break}i=o.value}catch(u){e.done=true;throw u}a=t.resolve(i);w(a.then,a,r.resolve,r.reject)}return r.promise};b(E,{all:function all(e){var t=this;if(!re.TypeIsObject(t)){throw new TypeError("Promise is not object")}var n=new r(t);var o,i;try{o=re.GetIterator(e);i={iterator:o,done:false};return C(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{re.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},race:function race(e){var t=this;if(!re.TypeIsObject(t)){throw new TypeError("Promise is not object")}var n=new r(t);var o,i;try{o=re.GetIterator(e);i={iterator:o,done:false};return x(i,t,n)}catch(a){var u=a;if(i&&!i.done){try{re.IteratorClose(o,true)}catch(f){u=f}}var s=n.reject;s(u);return n.promise}},reject:function reject(e){var t=this;if(!re.TypeIsObject(t)){throw new TypeError("Bad promise constructor")}var n=new r(t);var o=n.reject;o(e);return n.promise},resolve:function resolve(e){var t=this;if(!re.TypeIsObject(t)){throw new TypeError("Bad promise constructor")}if(re.IsPromise(e)){var n=e.constructor;if(n===t){return e}}var o=new r(t);var i=o.resolve;i(e);return o.promise}});b(T,{"catch":function(e){return this.then(null,e)},then:function then(e,t){var n=this;if(!re.IsPromise(n)){throw new TypeError("not a promise")}var o=re.SpeciesConstructor(n,E);var i;var b=arguments.length>2&&arguments[2]===y;if(b&&o===E){i=y}else{i=new r(o)}var g=re.IsCallable(e)?e:a;var d=re.IsCallable(t)?t:u;var O=n._promise;var m;if(O.state===f){if(O.reactionLength===0){O.fulfillReactionHandler0=g;O.rejectReactionHandler0=d;O.reactionCapability0=i}else{var w=3*(O.reactionLength-1);O[w+l]=g;O[w+p]=d;O[w+v]=i}O.reactionLength+=1}else if(O.state===s){m=O.result;h(g,i,m)}else if(O.state===c){m=O.result;h(d,i,m)}else{throw new TypeError("unexpected Promise state")}return i.promise}});y=new r(E);I=T.then;return E}();if(S.Promise){delete S.Promise.accept;delete S.Promise.defer;delete S.Promise.prototype.chain}if(typeof Cr==="function"){b(S,{Promise:Cr});var Mr=w(S.Promise,function(e){return e.resolve(42).then(function(){})instanceof e});var xr=!i(function(){S.Promise.reject(42).then(null,5).then(null,W)});var Nr=i(function(){S.Promise.call(3,W)});var Ar=function(e){var t=e.resolve(5);t.constructor={};var r=e.resolve(t);try{r.then(null,W).then(null,W)}catch(n){return true}return t===r}(S.Promise);var Rr=s&&function(){var e=0;var t=Object.defineProperty({},"then",{get:function(){e+=1}});Promise.resolve(t);return e===1}();var _r=function BadResolverPromise(e){var t=new Promise(e);e(3,function(){});this.then=t.then;this.constructor=BadResolverPromise};_r.prototype=Promise.prototype;_r.all=Promise.all;var kr=a(function(){return!!_r.all([1,2])});if(!Mr||!xr||!Nr||Ar||!Rr||kr){Promise=Cr;Z(S,"Promise",Cr)}if(Promise.all.length!==1){var Fr=Promise.all;Z(Promise,"all",function all(e){return re.Call(Fr,this,arguments)})}if(Promise.race.length!==1){var Lr=Promise.race;Z(Promise,"race",function race(e){return re.Call(Lr,this,arguments)})}if(Promise.resolve.length!==1){var Dr=Promise.resolve;Z(Promise,"resolve",function resolve(e){return re.Call(Dr,this,arguments)})}if(Promise.reject.length!==1){var zr=Promise.reject;Z(Promise,"reject",function reject(e){return re.Call(zr,this,arguments)})}wt(Promise,"all");wt(Promise,"race");wt(Promise,"resolve");wt(Promise,"reject");me(Promise)}var qr=function(e){var t=n(p(e,function(e,t){e[t]=true;return e},{}));return e.join(":")===t.join(":")};var Wr=qr(["z","a","bb"]);var Gr=qr(["z",1,"a","3",2]);if(s){var Hr=function fastkey(e){if(!Wr){return null}if(typeof e==="undefined"||e===null){return"^"+re.ToString(e)}else if(typeof e==="string"){return"$"+e}else if(typeof e==="number"){if(!Gr){return"n"+e}return e}else if(typeof e==="boolean"){return"b"+e}return null};var Vr=function emptyObject(){return Object.create?Object.create(null):{}};var Br=function addIterableToMap(e,n,o){if(r(o)||K.string(o)){l(o,function(e){if(!re.TypeIsObject(e)){throw new TypeError("Iterator value "+e+" is not an entry object")}n.set(e[0],e[1])})}else if(o instanceof e){t(e.prototype.forEach,o,function(e,t){n.set(t,e)})}else{var i,a;if(o!==null&&typeof o!=="undefined"){a=n.set;if(!re.IsCallable(a)){throw new TypeError("bad map")}i=re.GetIterator(o)}if(typeof i!=="undefined"){while(true){var u=re.IteratorStep(i);if(u===false){break}var f=u.value;try{if(!re.TypeIsObject(f)){throw new TypeError("Iterator value "+f+" is not an entry object")}t(a,n,f[0],f[1])}catch(s){re.IteratorClose(i,true);throw s}}}}};var $r=function addIterableToSet(e,n,o){if(r(o)||K.string(o)){l(o,function(e){n.add(e)})}else if(o instanceof e){t(e.prototype.forEach,o,function(e){n.add(e)})}else{var i,a;if(o!==null&&typeof o!=="undefined"){a=n.add;if(!re.IsCallable(a)){throw new TypeError("bad set")}i=re.GetIterator(o)}if(typeof i!=="undefined"){while(true){var u=re.IteratorStep(i);if(u===false){break}var f=u.value;try{t(a,n,f)}catch(s){re.IteratorClose(i,true);throw s}}}}};var Ur={Map:function(){var e={};var r=function MapEntry(e,t){this.key=e;this.value=t;this.next=null;this.prev=null};r.prototype.isRemoved=function isRemoved(){return this.key===e};var n=function isMap(e){return!!e._es6map};var o=function requireMapSlot(e,t){if(!re.TypeIsObject(e)||!n(e)){throw new TypeError("Method Map.prototype."+t+" called on incompatible receiver "+re.ToString(e))}};var i=function MapIterator(e,t){o(e,"[[MapIterator]]");this.head=e._head;this.i=this.head;this.kind=t};i.prototype={next:function next(){var e=this.i;var t=this.kind;var r=this.head;if(typeof this.i==="undefined"){return Ge()}while(e.isRemoved()&&e!==r){e=e.prev}var n;while(e.next!==r){e=e.next;if(!e.isRemoved()){if(t==="key"){n=e.key}else if(t==="value"){n=e.value}else{n=[e.key,e.value]}this.i=e;return Ge(n)}}this.i=void 0;return Ge()}};we(i.prototype);var a;var u=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires "new"')}if(this&&this._es6map){throw new TypeError("Bad construction")}var e=Te(this,Map,a,{_es6map:true,_head:null,_storage:Vr(),_size:0});var t=new r(null,null);t.next=t.prev=t;e._head=t;if(arguments.length>0){Br(Map,e,arguments[0])}return e};a=u.prototype;O.getter(a,"size",function(){if(typeof this._size==="undefined"){throw new TypeError("size method called on incompatible Map")}return this._size});b(a,{get:function get(e){o(this,"get");var t=Hr(e);if(t!==null){var r=this._storage[t];if(r){return r.value}else{return}}var n=this._head;var i=n;while((i=i.next)!==n){if(re.SameValueZero(i.key,e)){return i.value}}},has:function has(e){o(this,"has");var t=Hr(e);if(t!==null){return typeof this._storage[t]!=="undefined"}var r=this._head;var n=r;while((n=n.next)!==r){if(re.SameValueZero(n.key,e)){return true}}return false},set:function set(e,t){o(this,"set");var n=this._head;var i=n;var a;var u=Hr(e);if(u!==null){if(typeof this._storage[u]!=="undefined"){this._storage[u].value=t;return this}else{a=this._storage[u]=new r(e,t);i=n.prev}}while((i=i.next)!==n){if(re.SameValueZero(i.key,e)){i.value=t;return this}}a=a||new r(e,t);if(re.SameValue(-0,e)){a.key=+0}a.next=this._head;a.prev=this._head.prev;a.prev.next=a;a.next.prev=a;this._size+=1;return this},"delete":function(t){o(this,"delete");var r=this._head;var n=r;var i=Hr(t);if(i!==null){if(typeof this._storage[i]==="undefined"){return false}n=this._storage[i].prev;delete this._storage[i]}while((n=n.next)!==r){if(re.SameValueZero(n.key,t)){n.key=n.value=e;n.prev.next=n.next;n.next.prev=n.prev;this._size-=1;return true}}return false},clear:function clear(){o(this,"clear");this._size=0;this._storage=Vr();var t=this._head;var r=t;var n=r.next;while((r=n)!==t){r.key=r.value=e;n=r.next;r.next=r.prev=t}t.next=t.prev=t},keys:function keys(){o(this,"keys");return new i(this,"key")},values:function values(){o(this,"values");return new i(this,"value")},entries:function entries(){o(this,"entries");return new i(this,"key+value")},forEach:function forEach(e){o(this,"forEach");var r=arguments.length>1?arguments[1]:null;var n=this.entries();for(var i=n.next();!i.done;i=n.next()){if(r){t(e,r,i.value[1],i.value[0],this)}else{e(i.value[1],i.value[0],this)}}}});we(a,a.entries);return u}(),Set:function(){var e=function isSet(e){return e._es6set&&typeof e._storage!=="undefined"};var r=function requireSetSlot(t,r){if(!re.TypeIsObject(t)||!e(t)){throw new TypeError("Set.prototype."+r+" called on incompatible receiver "+re.ToString(t))}};var o;var i=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires "new"')}if(this&&this._es6set){throw new TypeError("Bad construction")}var e=Te(this,Set,o,{_es6set:true,"[[SetData]]":null,_storage:Vr()});if(!e._es6set){throw new TypeError("bad set")}if(arguments.length>0){$r(Set,e,arguments[0])}return e};o=i.prototype;var a=function(e){var t=e;if(t==="^null"){return null}else if(t==="^undefined"){return void 0}else{var r=t.charAt(0);if(r==="$"){return C(t,1)}else if(r==="n"){return+C(t,1)}else if(r==="b"){return t==="btrue"}}return+t};var u=function ensureMap(e){if(!e["[[SetData]]"]){var t=e["[[SetData]]"]=new Ur.Map;l(n(e._storage),function(e){var r=a(e);t.set(r,r)});e["[[SetData]]"]=t}e._storage=null};O.getter(i.prototype,"size",function(){r(this,"size");if(this._storage){return n(this._storage).length}u(this);return this["[[SetData]]"].size});b(i.prototype,{has:function has(e){r(this,"has");var t;if(this._storage&&(t=Hr(e))!==null){return!!this._storage[t]}u(this);return this["[[SetData]]"].has(e)},add:function add(e){r(this,"add");var t;if(this._storage&&(t=Hr(e))!==null){this._storage[t]=true;return this}u(this);this["[[SetData]]"].set(e,e);return this},"delete":function(e){r(this,"delete");var t;if(this._storage&&(t=Hr(e))!==null){var n=z(this._storage,t);return delete this._storage[t]&&n}u(this);return this["[[SetData]]"]["delete"](e)},clear:function clear(){r(this,"clear");if(this._storage){this._storage=Vr()}if(this["[[SetData]]"]){this["[[SetData]]"].clear()}},values:function values(){r(this,"values");u(this);return this["[[SetData]]"].values()},entries:function entries(){r(this,"entries");u(this);return this["[[SetData]]"].entries()},forEach:function forEach(e){r(this,"forEach");var n=arguments.length>1?arguments[1]:null;var o=this;u(o);this["[[SetData]]"].forEach(function(r,i){if(n){t(e,n,i,i,o)}else{e(i,i,o)}})}});h(i.prototype,"keys",i.prototype.values,true);we(i.prototype,i.prototype.values);return i}()};if(S.Map||S.Set){var Jr=a(function(){return new Map([[1,2]]).get(1)===2});if(!Jr){var Xr=S.Map;S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires "new"')}var e=new Xr;if(arguments.length>0){Br(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,S.Map.prototype);return e};S.Map.prototype=m(Xr.prototype);h(S.Map.prototype,"constructor",S.Map,true);O.preserveToString(S.Map,Xr)}var Kr=new Map;var Zr=function(){var e=new Map([[1,0],[2,0],[3,0],[4,0]]);e.set(-0,e);return e.get(0)===e&&e.get(-0)===e&&e.has(0)&&e.has(-0)}();var Yr=Kr.set(1,2)===Kr;if(!Zr||!Yr){var Qr=Map.prototype.set;Z(Map.prototype,"set",function set(e,r){t(Qr,this,e===0?0:e,r);return this})}if(!Zr){var en=Map.prototype.get;var tn=Map.prototype.has;b(Map.prototype,{get:function get(e){return t(en,this,e===0?0:e)},has:function has(e){return t(tn,this,e===0?0:e)}},true);O.preserveToString(Map.prototype.get,en);O.preserveToString(Map.prototype.has,tn)}var rn=new Set;var nn=function(e){e["delete"](0);e.add(-0);return!e.has(0)}(rn);var on=rn.add(1)===rn;if(!nn||!on){var an=Set.prototype.add;Set.prototype.add=function add(e){t(an,this,e===0?0:e);return this};O.preserveToString(Set.prototype.add,an)}if(!nn){var un=Set.prototype.has;Set.prototype.has=function has(e){return t(un,this,e===0?0:e)};O.preserveToString(Set.prototype.has,un);var fn=Set.prototype["delete"];Set.prototype["delete"]=function SetDelete(e){return t(fn,this,e===0?0:e)};O.preserveToString(Set.prototype["delete"],fn)}var sn=w(S.Map,function(e){var t=new e([]);t.set(42,42);return t instanceof e});var cn=Object.setPrototypeOf&&!sn;var ln=function(){try{return!(S.Map()instanceof S.Map)}catch(e){return e instanceof TypeError}}();if(S.Map.length!==0||cn||!ln){var pn=S.Map;S.Map=function Map(){if(!(this instanceof Map)){throw new TypeError('Constructor Map requires "new"')}var e=new pn;if(arguments.length>0){Br(Map,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Map.prototype);return e};S.Map.prototype=pn.prototype;h(S.Map.prototype,"constructor",S.Map,true);O.preserveToString(S.Map,pn)}var vn=w(S.Set,function(e){var t=new e([]);t.add(42,42);return t instanceof e});var yn=Object.setPrototypeOf&&!vn;var hn=function(){try{return!(S.Set()instanceof S.Set)}catch(e){return e instanceof TypeError}}();if(S.Set.length!==0||yn||!hn){var bn=S.Set;S.Set=function Set(){if(!(this instanceof Set)){throw new TypeError('Constructor Set requires "new"')}var e=new bn;if(arguments.length>0){$r(Set,e,arguments[0])}delete e.constructor;Object.setPrototypeOf(e,Set.prototype);return e};S.Set.prototype=bn.prototype;h(S.Set.prototype,"constructor",S.Set,true);O.preserveToString(S.Set,bn)}var gn=new S.Map;var dn=!a(function(){return gn.keys().next().done});if(typeof S.Map.prototype.clear!=="function"||(new S.Set).size!==0||gn.size!==0||typeof S.Map.prototype.keys!=="function"||typeof S.Set.prototype.keys!=="function"||typeof S.Map.prototype.forEach!=="function"||typeof S.Set.prototype.forEach!=="function"||u(S.Map)||u(S.Set)||typeof gn.keys().next!=="function"||dn||!sn){b(S,{Map:Ur.Map,Set:Ur.Set},true)}if(S.Set.prototype.keys!==S.Set.prototype.values){h(S.Set.prototype,"keys",S.Set.prototype.values,true)}we(Object.getPrototypeOf((new S.Map).keys()));we(Object.getPrototypeOf((new S.Set).keys()));if(c&&S.Set.prototype.has.name!=="has"){var On=S.Set.prototype.has;Z(S.Set.prototype,"has",function has(e){return t(On,this,e)})}}b(S,Ur);me(S.Map);me(S.Set)}var mn=function throwUnlessTargetIsObject(e){if(!re.TypeIsObject(e)){throw new TypeError("target must be an object")}};var wn={apply:function apply(){return re.Call(re.Call,null,arguments)},construct:function construct(e,t){if(!re.IsConstructor(e)){throw new TypeError("First argument must be a constructor.")}var r=arguments.length>2?arguments[2]:e;if(!re.IsConstructor(r)){throw new TypeError("new.target must be a constructor.")}return re.Construct(e,t,r,"internal")},deleteProperty:function deleteProperty(e,t){mn(e);if(s){var r=Object.getOwnPropertyDescriptor(e,t);if(r&&!r.configurable){return false}}return delete e[t]},has:function has(e,t){mn(e);return t in e}};if(Object.getOwnPropertyNames){Object.assign(wn,{ownKeys:function ownKeys(e){mn(e);var t=Object.getOwnPropertyNames(e);if(re.IsCallable(Object.getOwnPropertySymbols)){x(t,Object.getOwnPropertySymbols(e))}return t}})}var jn=function ConvertExceptionToBoolean(e){return!i(e)};if(Object.preventExtensions){Object.assign(wn,{isExtensible:function isExtensible(e){mn(e);return Object.isExtensible(e)},preventExtensions:function preventExtensions(e){mn(e);return jn(function(){Object.preventExtensions(e)})}})}if(s){var Sn=function get(e,t,r){var n=Object.getOwnPropertyDescriptor(e,t);if(!n){var o=Object.getPrototypeOf(e);if(o===null){return void 0}return Sn(o,t,r)}if("value"in n){return n.value}if(n.get){return re.Call(n.get,r)}return void 0};var Tn=function set(e,r,n,o){var i=Object.getOwnPropertyDescriptor(e,r);if(!i){var a=Object.getPrototypeOf(e);if(a!==null){return Tn(a,r,n,o)}i={value:void 0,writable:true,enumerable:true,configurable:true}}if("value"in i){if(!i.writable){return false}if(!re.TypeIsObject(o)){return false}var u=Object.getOwnPropertyDescriptor(o,r);if(u){return ee.defineProperty(o,r,{value:n})}else{return ee.defineProperty(o,r,{value:n,writable:true,enumerable:true,configurable:true})}}if(i.set){t(i.set,o,n);return true}return false};Object.assign(wn,{defineProperty:function defineProperty(e,t,r){mn(e);return jn(function(){Object.defineProperty(e,t,r)})},getOwnPropertyDescriptor:function getOwnPropertyDescriptor(e,t){mn(e);return Object.getOwnPropertyDescriptor(e,t)},get:function get(e,t){mn(e);var r=arguments.length>2?arguments[2]:e;return Sn(e,t,r)},set:function set(e,t,r){mn(e);var n=arguments.length>3?arguments[3]:e;return Tn(e,t,r,n)}})}if(Object.getPrototypeOf){var In=Object.getPrototypeOf;wn.getPrototypeOf=function getPrototypeOf(e){mn(e);return In(e)}}if(Object.setPrototypeOf&&wn.getPrototypeOf){var En=function(e,t){var r=t;while(r){if(e===r){return true}r=wn.getPrototypeOf(r)}return false};Object.assign(wn,{setPrototypeOf:function setPrototypeOf(e,t){mn(e);if(t!==null&&!re.TypeIsObject(t)){throw new TypeError("proto must be an object or null")}if(t===ee.getPrototypeOf(e)){return true}if(ee.isExtensible&&!ee.isExtensible(e)){return false}if(En(e,t)){return false}Object.setPrototypeOf(e,t);return true}})}var Pn=function(e,t){if(!re.IsCallable(S.Reflect[e])){h(S.Reflect,e,t)}else{var r=a(function(){S.Reflect[e](1);S.Reflect[e](NaN);S.Reflect[e](true);return true});if(r){Z(S.Reflect,e,t)}}};Object.keys(wn).forEach(function(e){Pn(e,wn[e])});var Cn=S.Reflect.getPrototypeOf;if(c&&Cn&&Cn.name!=="getPrototypeOf"){Z(S.Reflect,"getPrototypeOf",function getPrototypeOf(e){return t(Cn,S.Reflect,e)})}if(S.Reflect.setPrototypeOf){if(a(function(){S.Reflect.setPrototypeOf(1,{});return true})){Z(S.Reflect,"setPrototypeOf",wn.setPrototypeOf)}}if(S.Reflect.defineProperty){if(!a(function(){var e=!S.Reflect.defineProperty(1,"test",{value:1});var t=typeof Object.preventExtensions!=="function"||!S.Reflect.defineProperty(Object.preventExtensions({}),"test",{});return e&&t})){Z(S.Reflect,"defineProperty",wn.defineProperty)}}if(S.Reflect.construct){if(!a(function(){var e=function F(){};return S.Reflect.construct(function(){},[],e)instanceof e})){Z(S.Reflect,"construct",wn.construct)}}if(String(new Date(NaN))!=="Invalid Date"){var Mn=Date.prototype.toString;var xn=function toString(){var e=+this;if(e!==e){return"Invalid Date"}return re.Call(Mn,this)};Z(Date.prototype,"toString",xn)}var Nn={anchor:function anchor(e){return re.CreateHTML(this,"a","name",e)},big:function big(){return re.CreateHTML(this,"big","","")},blink:function blink(){return re.CreateHTML(this,"blink","","")},bold:function bold(){return re.CreateHTML(this,"b","","")},fixed:function fixed(){return re.CreateHTML(this,"tt","","")},fontcolor:function fontcolor(e){return re.CreateHTML(this,"font","color",e)},fontsize:function fontsize(e){return re.CreateHTML(this,"font","size",e)},italics:function italics(){return re.CreateHTML(this,"i","","")},link:function link(e){return re.CreateHTML(this,"a","href",e)},small:function small(){return re.CreateHTML(this,"small","","")},strike:function strike(){return re.CreateHTML(this,"strike","","")},sub:function sub(){return re.CreateHTML(this,"sub","","")},sup:function sub(){return re.CreateHTML(this,"sup","","")}};l(Object.keys(Nn),function(e){var r=String.prototype[e];var n=false;if(re.IsCallable(r)){var o=t(r,"",' " ');var i=P([],o.match(/"/g)).length;n=o!==o.toLowerCase()||i>2}else{n=true}if(n){Z(String.prototype,e,Nn[e])}});var An=function(){if(!Y){return false}var e=typeof JSON==="object"&&typeof JSON.stringify==="function"?JSON.stringify:null;if(!e){return false}if(typeof e(G())!=="undefined"){return true}if(e([G()])!=="[null]"){return true}var t={a:G()};t[G()]=true;if(e(t)!=="{}"){return true}return false}();var Rn=a(function(){if(!Y){return true}return JSON.stringify(Object(G()))==="{}"&&JSON.stringify([Object(G())])==="[{}]"});if(An||!Rn){var _n=JSON.stringify;Z(JSON,"stringify",function stringify(e){if(typeof e==="symbol"){return}var n;if(arguments.length>1){n=arguments[1]}var o=[e];if(!r(n)){var i=re.IsCallable(n)?n:null;var a=function(e,r){var n=i?t(i,this,e,r):r;if(typeof n!=="symbol"){if(K.symbol(n)){return St({})(n)}else{return n}}};o.push(a)}else{o.push(n)}if(arguments.length>2){o.push(arguments[2])}return _n.apply(this,o)})}return S});
                +//# sourceMappingURL=es6-shim.map
                diff --git a/blockly/webif/static/blockly/accessible/media/accessible.css b/blockly/webif/static/blockly/accessible/media/accessible.css
                new file mode 100644
                index 000000000..500ee7323
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/media/accessible.css
                @@ -0,0 +1,80 @@
                +.blocklyWorkspaceColumn {
                +  float: left;
                +  margin-right: 20px;
                +  width: 800px;
                +}
                +.blocklySidebarColumn {
                +  border-left: 1px solid #888;
                +  float: left;
                +  padding-left: 20px;
                +  margin-top: 20px;
                +  min-height: 700px;
                +  width: 200px;
                +}
                +
                +.blocklySidebarButton {
                +  background-color: #fff;
                +  border: 1px solid #333;
                +  border-radius: 4px;
                +  color: #000;
                +  font-size: 1em;
                +  margin: 10px 0 10px 30px;
                +  padding: 10px;
                +  text-align: center;
                +  vertical-align: middle;
                +  white-space: nowrap;
                +}
                +.blocklySidebarButton[disabled] {
                +  border: 1px solid #ccc;
                +  opacity: 0.5;
                +}
                +
                +.blocklyAriaLiveStatus {
                +  background: #c8f7be;
                +  border-radius: 10px;
                +  bottom: 80px;
                +  left: 20px;
                +  max-width: 275px;
                +  padding: 10px;
                +  position: fixed;
                +}
                +
                +.blocklyTree .blocklyActiveDescendant > label,
                +.blocklyTree .blocklyActiveDescendant > div > label,
                +.blocklyActiveDescendant > button,
                +.blocklyActiveDescendant > input,
                +.blocklyActiveDescendant > select,
                +.blocklyActiveDescendant > blockly-field-segment > label,
                +.blocklyActiveDescendant > blockly-field-segment > input,
                +.blocklyActiveDescendant > blockly-field-segment > select {
                +  outline: 2px dotted #00f;
                +}
                +
                +.blocklyDropdownListItem[aria-selected="true"] button {
                +  font-weight: bold;
                +}
                +
                +.blocklyModalCurtain {
                +  background-color: rgba(0,0,0,0.4);
                +  height: 100%;
                +  left: 0;
                +  overflow: auto;
                +  position: fixed;
                +  top: 0;
                +  width: 100%;
                +  z-index: 1;
                +}
                +.blocklyModal {
                +  background-color: #fefefe;
                +  border: 1px solid #888;
                +  margin: 10% auto;
                +  max-width: 600px;
                +  padding: 20px;
                +  width: 60%;
                +}
                +.blocklyModalButtonContainer {
                +  margin: 10px 0;
                +}
                +.blocklyModal .activeButton {
                +  border: 1px solid blue;
                +}
                diff --git a/blockly/webif/static/blockly/accessible/media/click.mp3 b/blockly/webif/static/blockly/accessible/media/click.mp3
                new file mode 100644
                index 000000000..4534b0ddc
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/click.mp3 differ
                diff --git a/blockly/webif/static/blockly/accessible/media/click.ogg b/blockly/webif/static/blockly/accessible/media/click.ogg
                new file mode 100644
                index 000000000..e8ae42a61
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/click.ogg differ
                diff --git a/blockly/webif/static/blockly/accessible/media/click.wav b/blockly/webif/static/blockly/accessible/media/click.wav
                new file mode 100644
                index 000000000..41a50cd76
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/click.wav differ
                diff --git a/blockly/webif/static/blockly/accessible/media/delete.mp3 b/blockly/webif/static/blockly/accessible/media/delete.mp3
                new file mode 100644
                index 000000000..1e71bdcf4
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/delete.mp3 differ
                diff --git a/blockly/webif/static/blockly/accessible/media/delete.ogg b/blockly/webif/static/blockly/accessible/media/delete.ogg
                new file mode 100644
                index 000000000..a65b11228
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/delete.ogg differ
                diff --git a/blockly/webif/static/blockly/accessible/media/delete.wav b/blockly/webif/static/blockly/accessible/media/delete.wav
                new file mode 100644
                index 000000000..455bcd3bb
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/delete.wav differ
                diff --git a/blockly/webif/static/blockly/accessible/media/oops.mp3 b/blockly/webif/static/blockly/accessible/media/oops.mp3
                new file mode 100644
                index 000000000..0c9507140
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/oops.mp3 differ
                diff --git a/blockly/webif/static/blockly/accessible/media/oops.ogg b/blockly/webif/static/blockly/accessible/media/oops.ogg
                new file mode 100644
                index 000000000..7bac05d97
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/oops.ogg differ
                diff --git a/blockly/webif/static/blockly/accessible/media/oops.wav b/blockly/webif/static/blockly/accessible/media/oops.wav
                new file mode 100644
                index 000000000..163df4f1c
                Binary files /dev/null and b/blockly/webif/static/blockly/accessible/media/oops.wav differ
                diff --git a/blockly/webif/static/blockly/accessible/messages.js b/blockly/webif/static/blockly/accessible/messages.js
                new file mode 100644
                index 000000000..60c51d344
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/messages.js
                @@ -0,0 +1,62 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Translatable string constants for Accessible Blockly.
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +'use strict';
                +
                +Blockly.Msg.WORKSPACE = 'Workspace';
                +Blockly.Msg.WORKSPACE_BLOCK =
                +    'workspace block. Move right to edit. Press Enter for more options.';
                +
                +Blockly.Msg.ATTACH_NEW_BLOCK_TO_LINK = 'Attach new block to link...';
                +Blockly.Msg.CREATE_NEW_BLOCK_GROUP = 'Create new block group...';
                +Blockly.Msg.ERASE_WORKSPACE = 'Erase Workspace';
                +Blockly.Msg.NO_BLOCKS_IN_WORKSPACE = 'There are no blocks in the workspace.';
                +
                +Blockly.Msg.COPY_BLOCK = 'Copy block';
                +Blockly.Msg.DELETE = 'Delete block';
                +Blockly.Msg.MARK_SPOT_BEFORE = 'Add link before';
                +Blockly.Msg.MARK_SPOT_AFTER = 'Add link after';
                +Blockly.Msg.MARK_THIS_SPOT = 'Add link inside';
                +Blockly.Msg.MOVE_TO_MARKED_SPOT = 'Move to existing link';
                +Blockly.Msg.PASTE_AFTER = 'Paste after';
                +Blockly.Msg.PASTE_BEFORE = 'Paste before';
                +Blockly.Msg.PASTE_INSIDE = 'Paste inside';
                +
                +Blockly.Msg.BLOCK_OPTIONS = 'Block Options';
                +Blockly.Msg.SELECT_A_BLOCK = 'Select a block...';
                +Blockly.Msg.CANCEL = 'Cancel';
                +
                +Blockly.Msg.ANY = 'any';
                +Blockly.Msg.BLOCK = 'block';
                +Blockly.Msg.BUTTON = 'Button.';
                +Blockly.Msg.FOR = 'for';
                +Blockly.Msg.VALUE = 'value';
                +
                +Blockly.Msg.ADDED_LINK_MSG = 'Added link.';
                +Blockly.Msg.ATTACHED_BLOCK_TO_LINK_MSG = 'attached to link. ';
                +Blockly.Msg.COPIED_BLOCK_MSG = 'copied. ';
                +Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG = 'pasted. ';
                +
                +Blockly.Msg.PRESS_ENTER_TO_EDIT_NUMBER = 'Press Enter to edit number. ';
                +Blockly.Msg.PRESS_ENTER_TO_EDIT_TEXT = 'Press Enter to edit text. ';
                diff --git a/blockly/webif/static/blockly/accessible/notifications.service.js b/blockly/webif/static/blockly/accessible/notifications.service.js
                new file mode 100644
                index 000000000..b1ce22b27
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/notifications.service.js
                @@ -0,0 +1,61 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for updating the ARIA live region that
                + * allows screenreaders to notify the user about actions that they have taken.
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.NotificationsService');
                +
                +
                +blocklyApp.NotificationsService = ng.core.Class({
                +  constructor: [function() {
                +    this.currentMessage = '';
                +    this.timeouts = [];
                +  }],
                +  setDisplayedMessage_: function(newMessage) {
                +    this.currentMessage = newMessage;
                +  },
                +  getDisplayedMessage: function() {
                +    return this.currentMessage;
                +  },
                +  speak: function(newMessage) {
                +    // Clear and reset any existing timeouts.
                +    this.timeouts.forEach(function(timeout) {
                +      clearTimeout(timeout);
                +    });
                +    this.timeouts.length = 0;
                +
                +    // Clear the current message, so that if, e.g., two operations of the same
                +    // type are performed, both messages will be read in succession.
                +    this.setDisplayedMessage_('');
                +
                +    // We need a non-zero timeout here, otherwise NVDA does not read the
                +    // notification messages properly.
                +    var that = this;
                +    this.timeouts.push(setTimeout(function() {
                +      that.setDisplayedMessage_(newMessage);
                +    }, 20));
                +    this.timeouts.push(setTimeout(function() {
                +      that.setDisplayedMessage_('');
                +    }, 5000));
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/sidebar.component.js b/blockly/webif/static/blockly/accessible/sidebar.component.js
                new file mode 100644
                index 000000000..66f735eda
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/sidebar.component.js
                @@ -0,0 +1,132 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component representing the sidebar that is shown next
                + * to the workspace.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.SidebarComponent');
                +
                +goog.require('blocklyApp.UtilsService');
                +
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.ToolboxModalService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +goog.require('blocklyApp.VariableModalService');
                +
                +
                +blocklyApp.SidebarComponent = ng.core.Component({
                +  selector: 'blockly-sidebar',
                +  template: `
                +    <div class="blocklySidebarColumn">
                +      <button *ngFor="#buttonConfig of customSidebarButtons"
                +              id="{{buttonConfig.id || undefined}}"
                +              (click)="buttonConfig.action()"
                +              class="blocklySidebarButton">
                +        {{buttonConfig.text}}
                +      </button>
                +      <button id="{{ID_FOR_ATTACH_TO_LINK_BUTTON}}"
                +              (click)="showToolboxModalForAttachToMarkedConnection()"
                +              [attr.disabled]="!isAnyConnectionMarked() ? 'disabled' : undefined"
                +              [attr.aria-disabled]="!isAnyConnectionMarked()"
                +              class="blocklySidebarButton">
                +        {{'ATTACH_NEW_BLOCK_TO_LINK'|translate}}
                +      </button>
                +      <button id="{{ID_FOR_CREATE_NEW_GROUP_BUTTON}}"
                +              (click)="showToolboxModalForCreateNewGroup()"
                +              class="blocklySidebarButton">
                +        {{'CREATE_NEW_BLOCK_GROUP'|translate}}
                +      </button>
                +      <button id="clear-workspace" (click)="clearWorkspace()"
                +              [attr.disabled]="isWorkspaceEmpty() ? 'disabled' : undefined"
                +              [attr.aria-disabled]="isWorkspaceEmpty()"
                +              class="blocklySidebarButton">
                +        {{'ERASE_WORKSPACE'|translate}}
                +      </button>
                +      <button *ngIf="hasVariableCategory()" id="add-variable"
                +              (click)="showAddVariableModal()"
                +              class="blocklySidebarButton">
                +        Add Variable
                +      </button>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.BlockConnectionService,
                +    blocklyApp.ToolboxModalService,
                +    blocklyApp.TreeService,
                +    blocklyApp.UtilsService,
                +    blocklyApp.VariableModalService,
                +    function(
                +        blockConnectionService, toolboxModalService, treeService,
                +        utilsService, variableService) {
                +      // ACCESSIBLE_GLOBALS is a global variable defined by the containing
                +      // page. It should contain a key, customSidebarButtons, describing
                +      // additional buttons that should be displayed after the default ones.
                +      // See README.md for details.
                +      this.customSidebarButtons =
                +          ACCESSIBLE_GLOBALS && ACCESSIBLE_GLOBALS.customSidebarButtons ?
                +          ACCESSIBLE_GLOBALS.customSidebarButtons : [];
                +
                +      this.blockConnectionService = blockConnectionService;
                +      this.toolboxModalService = toolboxModalService;
                +      this.treeService = treeService;
                +      this.utilsService = utilsService;
                +      this.variableModalService = variableService;
                +
                +      this.ID_FOR_ATTACH_TO_LINK_BUTTON = 'blocklyAttachToLinkBtn';
                +      this.ID_FOR_CREATE_NEW_GROUP_BUTTON = 'blocklyCreateNewGroupBtn';
                +    }
                +  ],
                +  isAnyConnectionMarked: function() {
                +    return this.blockConnectionService.isAnyConnectionMarked();
                +  },
                +  isWorkspaceEmpty: function() {
                +    return this.utilsService.isWorkspaceEmpty();
                +  },
                +  hasVariableCategory: function() {
                +    return this.toolboxModalService.toolboxHasVariableCategory();
                +  },
                +  clearWorkspace: function() {
                +    blocklyApp.workspace.clear();
                +    this.treeService.clearAllActiveDescs();
                +    // The timeout is needed in order to give the blocks time to be cleared
                +    // from the workspace, and for the 'workspace is empty' button to show up.
                +    setTimeout(function() {
                +      document.getElementById(blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus();
                +    }, 50);
                +  },
                +  showToolboxModalForAttachToMarkedConnection: function() {
                +    this.toolboxModalService.showToolboxModalForAttachToMarkedConnection(
                +        this.ID_FOR_ATTACH_TO_LINK_BUTTON);
                +  },
                +  showToolboxModalForCreateNewGroup: function() {
                +    this.toolboxModalService.showToolboxModalForCreateNewGroup(
                +        this.ID_FOR_CREATE_NEW_GROUP_BUTTON);
                +  },
                +  showAddVariableModal: function() {
                +    this.variableModalService.showAddModal_("item");
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/toolbox-modal.component.js b/blockly/webif/static/blockly/accessible/toolbox-modal.component.js
                new file mode 100644
                index 000000000..25358e82e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/toolbox-modal.component.js
                @@ -0,0 +1,188 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component representing the toolbox modal.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.ToolboxModalComponent');
                +
                +goog.require('Blockly.CommonModal');
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.ToolboxModalService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +goog.require('blocklyApp.UtilsService');
                +
                +
                +blocklyApp.ToolboxModalComponent = ng.core.Component({
                +  selector: 'blockly-toolbox-modal',
                +  template: `
                +    <div *ngIf="modalIsVisible" class="blocklyModalCurtain"
                +         (click)="dismissModal()">
                +      <!-- $event.stopPropagation() prevents the modal from closing when its
                +      interior is clicked. -->
                +      <div id="toolboxModal" class="blocklyModal" role="alertdialog"
                +           (click)="$event.stopPropagation()" tabindex="-1"
                +           aria-labelledby="toolboxModalHeading">
                +        <h3 id="toolboxModalHeading">{{'SELECT_A_BLOCK'|translate}}</h3>
                +
                +        <div *ngFor="#toolboxCategory of toolboxCategories; #categoryIndex=index">
                +          <h4 *ngIf="toolboxCategory.categoryName">{{toolboxCategory.categoryName}}</h4>
                +          <div class="blocklyModalButtonContainer"
                +               *ngFor="#block of toolboxCategory.blocks; #blockIndex=index">
                +            <button [id]="getOptionId(getOverallIndex(categoryIndex, blockIndex))"
                +                    (click)="selectBlock(getBlock(categoryIndex, blockIndex))"
                +                    [ngClass]="{activeButton: activeButtonIndex == getOverallIndex(categoryIndex, blockIndex)}">
                +              {{getBlockDescription(block)}}
                +            </button>
                +          </div>
                +        </div>
                +        <hr>
                +        <div class="blocklyModalButtonContainer">
                +          <button [id]="getCancelOptionId()" (click)="dismissModal()"
                +                  [ngClass]="{activeButton: activeButtonIndex == totalNumBlocks}">
                +            {{'CANCEL'|translate}}
                +          </button>
                +        </div>
                +      </div>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.ToolboxModalService, blocklyApp.KeyboardInputService,
                +    blocklyApp.AudioService, blocklyApp.UtilsService, blocklyApp.TreeService,
                +    function(
                +        toolboxModalService_, keyboardInputService_, audioService_,
                +        utilsService_, treeService_) {
                +      this.toolboxModalService = toolboxModalService_;
                +      this.keyboardInputService = keyboardInputService_;
                +      this.audioService = audioService_;
                +      this.utilsService = utilsService_;
                +      this.treeService = treeService_;
                +
                +      this.modalIsVisible = false;
                +      this.toolboxCategories = [];
                +      this.onSelectBlockCallback = null;
                +      this.onDismissCallback = null;
                +
                +      this.firstBlockIndexes = [];
                +      this.activeButtonIndex = -1;
                +      this.totalNumBlocks = 0;
                +
                +      var that = this;
                +      this.toolboxModalService.registerPreShowHook(
                +        function(
                +            toolboxCategories, onSelectBlockCallback, onDismissCallback) {
                +          that.modalIsVisible = true;
                +          that.toolboxCategories = toolboxCategories;
                +          that.onSelectBlockCallback = onSelectBlockCallback;
                +          that.onDismissCallback = onDismissCallback;
                +
                +          // The indexes of the buttons corresponding to the first block in
                +          // each category, as well as the 'cancel' button at the end.
                +          that.firstBlockIndexes = [];
                +          that.activeButtonIndex = -1;
                +          that.totalNumBlocks = 0;
                +
                +          var cumulativeIndex = 0;
                +          that.toolboxCategories.forEach(function(category) {
                +            that.firstBlockIndexes.push(cumulativeIndex);
                +            cumulativeIndex += category.blocks.length;
                +          });
                +          that.firstBlockIndexes.push(cumulativeIndex);
                +          that.totalNumBlocks = cumulativeIndex;
                +
                +          Blockly.CommonModal.setupKeyboardOverrides(that);
                +          that.keyboardInputService.addOverride('13', function(evt) {
                +              evt.preventDefault();
                +              evt.stopPropagation();
                +
                +              if (that.activeButtonIndex == -1) {
                +                return;
                +              }
                +
                +              var button = document.getElementById(
                +                  that.getOptionId(that.activeButtonIndex));
                +
                +              for (var i = 0; i < that.toolboxCategories.length; i++) {
                +                if (that.firstBlockIndexes[i + 1] > that.activeButtonIndex) {
                +                  var categoryIndex = i;
                +                  var blockIndex =
                +                      that.activeButtonIndex - that.firstBlockIndexes[i];
                +                  var block = that.getBlock(categoryIndex, blockIndex);
                +                  that.selectBlock(block);
                +                  return;
                +                }
                +              }
                +
                +              // The 'Cancel' button has been pressed.
                +              that.dismissModal();
                +            });
                +
                +          setTimeout(function() {
                +            document.getElementById('toolboxModal').focus();
                +          }, 150);
                +        }
                +      );
                +    }
                +  ],
                +  // Closes the modal (on both success and failure).
                +  hideModal_: Blockly.CommonModal.hideModal,
                +  // Focuses on the button represented by the given index.
                +  focusOnOption: function(index) {
                +    var button = document.getElementById(this.getOptionId(index));
                +    button.focus();
                +  },
                +  // Counts the number of interactive elements for the modal.
                +  numInteractiveElements: function() {
                +    return this.totalNumBlocks + 1;
                +  },
                +  getOverallIndex: function(categoryIndex, blockIndex) {
                +    return this.firstBlockIndexes[categoryIndex] + blockIndex;
                +  },
                +  getBlock: function(categoryIndex, blockIndex) {
                +    return this.toolboxCategories[categoryIndex].blocks[blockIndex];
                +  },
                +  getBlockDescription: function(block) {
                +    return this.utilsService.getBlockDescription(block);
                +  },
                +  // Returns the ID for the corresponding option button.
                +  getOptionId: function(index) {
                +    return 'toolbox-modal-option-' + index;
                +  },
                +  // Returns the ID for the "cancel" option button.
                +  getCancelOptionId: function() {
                +    return 'toolbox-modal-option-' + this.totalNumBlocks;
                +  },
                +  selectBlock: function(block) {
                +    this.onSelectBlockCallback(block);
                +    this.hideModal_();
                +  },
                +  // Dismisses and closes the modal.
                +  dismissModal: function() {
                +    this.hideModal_();
                +    this.onDismissCallback();
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/toolbox-modal.service.js b/blockly/webif/static/blockly/accessible/toolbox-modal.service.js
                new file mode 100644
                index 000000000..fa860d58d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/toolbox-modal.service.js
                @@ -0,0 +1,234 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for the toolbox modal.
                + *
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.ToolboxModalService');
                +
                +goog.require('blocklyApp.UtilsService');
                +
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.TreeService');
                +
                +
                +blocklyApp.ToolboxModalService = ng.core.Class({
                +  constructor: [
                +    blocklyApp.BlockConnectionService,
                +    blocklyApp.NotificationsService,
                +    blocklyApp.TreeService,
                +    blocklyApp.UtilsService,
                +    function(
                +        blockConnectionService, notificationsService, treeService,
                +        utilsService) {
                +      this.blockConnectionService = blockConnectionService;
                +      this.notificationsService = notificationsService;
                +      this.treeService = treeService;
                +      this.utilsService = utilsService;
                +
                +      this.modalIsShown = false;
                +
                +      this.selectedToolboxCategories = null;
                +      this.onSelectBlockCallback = null;
                +      this.onDismissCallback = null;
                +      this.hasVariableCategory = null;
                +      // The aim of the pre-show hook is to populate the modal component with
                +      // the information it needs to display the modal (e.g., which categories
                +      // and blocks to display).
                +      this.preShowHook = function() {
                +        throw Error(
                +            'A pre-show hook must be defined for the toolbox modal before it ' +
                +            'can be shown.');
                +      };
                +    }
                +  ],
                +  populateToolbox_: function() {
                +    // Populate the toolbox categories.
                +    this.allToolboxCategories = [];
                +    var toolboxXmlElt = document.getElementById('blockly-toolbox-xml');
                +    var toolboxCategoryElts = toolboxXmlElt.getElementsByTagName('category');
                +    if (toolboxCategoryElts.length) {
                +      this.allToolboxCategories = Array.from(toolboxCategoryElts).map(
                +        function(categoryElt) {
                +          var tmpWorkspace = new Blockly.Workspace();
                +          var custom = categoryElt.attributes.custom
                +          // TODO (corydiers): Implement custom flyouts once #1153 is solved.
                +          if (custom && custom.value == Blockly.VARIABLE_CATEGORY_NAME) {
                +            var varBlocks =
                +              Blockly.Variables.flyoutCategoryBlocks(blocklyApp.workspace);
                +            varBlocks.forEach(function(block) {
                +              Blockly.Xml.domToBlock(block, tmpWorkspace);
                +            });
                +          } else {
                +            Blockly.Xml.domToWorkspace(categoryElt, tmpWorkspace);
                +          }
                +          return {
                +            categoryName: categoryElt.attributes.name.value,
                +            blocks: tmpWorkspace.topBlocks_
                +          };
                +        }
                +      );
                +      this.computeCategoriesForCreateNewGroupModal_();
                +    } else {
                +      // A timeout seems to be needed in order for the .children accessor to
                +      // work correctly.
                +      var that = this;
                +      setTimeout(function() {
                +        // If there are no top-level categories, we create a single category
                +        // containing all the top-level blocks.
                +        var tmpWorkspace = new Blockly.Workspace();
                +        Array.from(toolboxXmlElt.children).forEach(function(topLevelNode) {
                +          Blockly.Xml.domToBlock(tmpWorkspace, topLevelNode);
                +        });
                +
                +        that.allToolboxCategories = [{
                +          categoryName: '',
                +          blocks: tmpWorkspace.topBlocks_
                +        }];
                +
                +        that.computeCategoriesForCreateNewGroupModal_();
                +      });
                +    }
                +  },
                +  computeCategoriesForCreateNewGroupModal_: function() {
                +    // Precompute toolbox categories for blocks that have no output
                +    // connection (and that can therefore be used as the base block of a
                +    // "create new block group" action).
                +    this.toolboxCategoriesForNewGroup = [];
                +    var that = this;
                +    this.allToolboxCategories.forEach(function(toolboxCategory) {
                +      var baseBlocks = toolboxCategory.blocks.filter(function(block) {
                +        return !block.outputConnection;
                +      });
                +
                +      if (baseBlocks.length > 0) {
                +        that.toolboxCategoriesForNewGroup.push({
                +          categoryName: toolboxCategory.categoryName,
                +          blocks: baseBlocks
                +        });
                +      }
                +    });
                +  },
                +  registerPreShowHook: function(preShowHook) {
                +    var that = this;
                +    this.preShowHook = function() {
                +      preShowHook(
                +          that.selectedToolboxCategories, that.onSelectBlockCallback,
                +          that.onDismissCallback);
                +    };
                +  },
                +  isModalShown: function() {
                +    return this.modalIsShown;
                +  },
                +  toolboxHasVariableCategory: function() {
                +    if (this.hasVariableCategory === null) {
                +      var toolboxXmlElt = document.getElementById('blockly-toolbox-xml');
                +      var toolboxCategoryElts = toolboxXmlElt.getElementsByTagName('category');
                +      var that = this;
                +      Array.from(toolboxCategoryElts).forEach(
                +        function(categoryElt) {
                +          var custom = categoryElt.attributes.custom;
                +          if (custom && custom.value == Blockly.VARIABLE_CATEGORY_NAME) {
                +            that.hasVariableCategory = true;
                +          }
                +        });
                +
                +      if (this.hasVariableCategory === null) {
                +        this.hasVariableCategory = false;
                +      }
                +    }
                +
                +    return this.hasVariableCategory;
                +  },
                +  showModal_: function(
                +      selectedToolboxCategories, onSelectBlockCallback, onDismissCallback) {
                +    this.selectedToolboxCategories = selectedToolboxCategories;
                +    this.onSelectBlockCallback = onSelectBlockCallback;
                +    this.onDismissCallback = onDismissCallback;
                +
                +    this.preShowHook();
                +    this.modalIsShown = true;
                +  },
                +  hideModal: function() {
                +    this.modalIsShown = false;
                +  },
                +  showToolboxModalForAttachToMarkedConnection: function(sourceButtonId) {
                +    var that = this;
                +
                +    var selectedToolboxCategories = [];
                +    this.populateToolbox_();
                +    this.allToolboxCategories.forEach(function(toolboxCategory) {
                +      var selectedBlocks = toolboxCategory.blocks.filter(function(block) {
                +        return that.blockConnectionService.canBeAttachedToMarkedConnection(
                +            block);
                +      });
                +
                +      if (selectedBlocks.length > 0) {
                +        selectedToolboxCategories.push({
                +          categoryName: toolboxCategory.categoryName,
                +          blocks: selectedBlocks
                +        });
                +      }
                +    });
                +
                +    this.showModal_(selectedToolboxCategories, function(block) {
                +      var blockDescription = that.utilsService.getBlockDescription(block);
                +
                +      // Clear the active desc for the destination tree, so that it can be
                +      // cleanly reinstated after the new block is attached.
                +      var destinationTreeId = that.treeService.getTreeIdForBlock(
                +          that.blockConnectionService.getMarkedConnectionSourceBlock().id);
                +      that.treeService.clearActiveDesc(destinationTreeId);
                +      var newBlockId = that.blockConnectionService.attachToMarkedConnection(
                +          block);
                +
                +      // Invoke a digest cycle, so that the DOM settles.
                +      setTimeout(function() {
                +        that.treeService.focusOnBlock(newBlockId);
                +        that.notificationsService.speak(
                +            'Attached. Now on, ' + blockDescription + ', block in workspace.');
                +      });
                +    }, function() {
                +      document.getElementById(sourceButtonId).focus();
                +    });
                +  },
                +  showToolboxModalForCreateNewGroup: function(sourceButtonId) {
                +    var that = this;
                +    this.populateToolbox_();
                +    this.showModal_(this.toolboxCategoriesForNewGroup, function(block) {
                +      var blockDescription = that.utilsService.getBlockDescription(block);
                +      var xml = Blockly.Xml.blockToDom(block);
                +      var newBlockId = Blockly.Xml.domToBlock(blocklyApp.workspace, xml).id;
                +
                +      // Invoke a digest cycle, so that the DOM settles.
                +      setTimeout(function() {
                +        that.treeService.focusOnBlock(newBlockId);
                +        that.notificationsService.speak(
                +            'Created new group in workspace. Now on, ' + blockDescription +
                +            ', block in workspace.');
                +      });
                +    }, function() {
                +      document.getElementById(sourceButtonId).focus();
                +    });
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/translate.pipe.js b/blockly/webif/static/blockly/accessible/translate.pipe.js
                new file mode 100644
                index 000000000..fef1940cd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/translate.pipe.js
                @@ -0,0 +1,36 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Pipe for internationalizing Blockly message strings.
                + * @author sll@google.com (Sean Lip)
                + */
                +
                +goog.provide('blocklyApp.TranslatePipe');
                +
                +
                +blocklyApp.TranslatePipe = ng.core.Pipe({
                +  name: 'translate'
                +})
                +.Class({
                +  constructor: function() {},
                +  transform: function(messageId) {
                +    return Blockly.Msg[messageId];
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/tree.service.js b/blockly/webif/static/blockly/accessible/tree.service.js
                new file mode 100644
                index 000000000..c5a73ac4c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/tree.service.js
                @@ -0,0 +1,609 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service that handles keyboard navigation on workspace
                + * block groups (internally represented as trees). This is a singleton service
                + * for the entire application.
                + *
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.TreeService');
                +
                +goog.require('blocklyApp.UtilsService');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.BlockOptionsModalService');
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.VariableModalService');
                +
                +
                +blocklyApp.TreeService = ng.core.Class({
                +  constructor: [
                +    blocklyApp.AudioService,
                +    blocklyApp.BlockConnectionService,
                +    blocklyApp.BlockOptionsModalService,
                +    blocklyApp.NotificationsService,
                +    blocklyApp.UtilsService,
                +    blocklyApp.VariableModalService,
                +    function(
                +        audioService, blockConnectionService, blockOptionsModalService,
                +        notificationsService, utilsService, variableModalService) {
                +      this.audioService = audioService;
                +      this.blockConnectionService = blockConnectionService;
                +      this.blockOptionsModalService = blockOptionsModalService;
                +      this.notificationsService = notificationsService;
                +      this.utilsService = utilsService;
                +      this.variableModalService = variableModalService;
                +
                +      // The suffix used for all IDs of block root elements.
                +      this.BLOCK_ROOT_ID_SUFFIX_ = blocklyApp.BLOCK_ROOT_ID_SUFFIX;
                +      // Maps tree IDs to the IDs of their active descendants.
                +      this.activeDescendantIds_ = {};
                +      // Array containing all the sidebar button elements.
                +      this.sidebarButtonElements_ = Array.from(
                +          document.querySelectorAll('button.blocklySidebarButton'));
                +    }
                +  ],
                +  scrollToElement_: function(elementId) {
                +    var element = document.getElementById(elementId);
                +    var documentElement = document.body || document.documentElement;
                +    if (element.offsetTop < documentElement.scrollTop ||
                +        element.offsetTop > documentElement.scrollTop + window.innerHeight) {
                +      window.scrollTo(0, element.offsetTop - 10);
                +    }
                +  },
                +
                +  isLi_: function(node) {
                +    return node.tagName == 'LI';
                +  },
                +  getParentLi_: function(element) {
                +    var nextNode = element.parentNode;
                +    while (nextNode && !this.isLi_(nextNode)) {
                +      nextNode = nextNode.parentNode;
                +    }
                +    return nextNode;
                +  },
                +  getFirstChildLi_: function(element) {
                +    var childList = element.children;
                +    for (var i = 0; i < childList.length; i++) {
                +      if (this.isLi_(childList[i])) {
                +        return childList[i];
                +      } else {
                +        var potentialElement = this.getFirstChildLi_(childList[i]);
                +        if (potentialElement) {
                +          return potentialElement;
                +        }
                +      }
                +    }
                +    return null;
                +  },
                +  getLastChildLi_: function(element) {
                +    var childList = element.children;
                +    for (var i = childList.length - 1; i >= 0; i--) {
                +      if (this.isLi_(childList[i])) {
                +        return childList[i];
                +      } else {
                +        var potentialElement = this.getLastChildLi_(childList[i]);
                +        if (potentialElement) {
                +          return potentialElement;
                +        }
                +      }
                +    }
                +    return null;
                +  },
                +  getInitialSiblingLi_: function(element) {
                +    while (true) {
                +      var previousSibling = this.getPreviousSiblingLi_(element);
                +      if (previousSibling && previousSibling.id != element.id) {
                +        element = previousSibling;
                +      } else {
                +        return element;
                +      }
                +    }
                +  },
                +  getPreviousSiblingLi_: function(element) {
                +    if (element.previousElementSibling) {
                +      var sibling = element.previousElementSibling;
                +      return this.isLi_(sibling) ? sibling : this.getLastChildLi_(sibling);
                +    } else {
                +      var parent = element.parentNode;
                +      while (parent && parent.tagName != 'OL') {
                +        if (parent.previousElementSibling) {
                +          var node = parent.previousElementSibling;
                +          return this.isLi_(node) ? node : this.getLastChildLi_(node);
                +        } else {
                +          parent = parent.parentNode;
                +        }
                +      }
                +      return null;
                +    }
                +  },
                +  getNextSiblingLi_: function(element) {
                +    if (element.nextElementSibling) {
                +      var sibling = element.nextElementSibling;
                +      return this.isLi_(sibling) ? sibling : this.getFirstChildLi_(sibling);
                +    } else {
                +      var parent = element.parentNode;
                +      while (parent && parent.tagName != 'OL') {
                +        if (parent.nextElementSibling) {
                +          var node = parent.nextElementSibling;
                +          return this.isLi_(node) ? node : this.getFirstChildLi_(node);
                +        } else {
                +          parent = parent.parentNode;
                +        }
                +      }
                +      return null;
                +    }
                +  },
                +  getFinalSiblingLi_: function(element) {
                +    while (true) {
                +      var nextSibling = this.getNextSiblingLi_(element);
                +      if (nextSibling && nextSibling.id != element.id) {
                +        element = nextSibling;
                +      } else {
                +        return element;
                +      }
                +    }
                +  },
                +
                +  // Returns a list of all focus targets in the workspace, including the
                +  // "Create new group" button that appears when no blocks are present.
                +  getWorkspaceFocusTargets_: function() {
                +    return Array.from(
                +        document.querySelectorAll('.blocklyWorkspaceFocusTarget'));
                +  },
                +  getAllFocusTargets_: function() {
                +    return this.getWorkspaceFocusTargets_().concat(this.sidebarButtonElements_);
                +  },
                +  getNextFocusTargetId_: function(treeId) {
                +    var trees = this.getAllFocusTargets_();
                +    for (var i = 0; i < trees.length - 1; i++) {
                +      if (trees[i].id == treeId) {
                +        return trees[i + 1].id;
                +      }
                +    }
                +    return null;
                +  },
                +  getPreviousFocusTargetId_: function(treeId) {
                +    var trees = this.getAllFocusTargets_();
                +    for (var i = trees.length - 1; i > 0; i--) {
                +      if (trees[i].id == treeId) {
                +        return trees[i - 1].id;
                +      }
                +    }
                +    return null;
                +  },
                +
                +  getActiveDescId: function(treeId) {
                +    return this.activeDescendantIds_[treeId] || '';
                +  },
                +  // Set the active desc for this tree to its first child.
                +  initActiveDesc: function(treeId) {
                +    var tree = document.getElementById(treeId);
                +    this.setActiveDesc(this.getFirstChildLi_(tree).id, treeId);
                +  },
                +  // Make a given element the active descendant of a given tree.
                +  setActiveDesc: function(newActiveDescId, treeId) {
                +    if (this.getActiveDescId(treeId)) {
                +      this.clearActiveDesc(treeId);
                +    }
                +    document.getElementById(newActiveDescId).classList.add(
                +        'blocklyActiveDescendant');
                +    this.activeDescendantIds_[treeId] = newActiveDescId;
                +
                +    // Scroll the new active desc into view, if needed. This has no effect
                +    // for blind users, but is helpful for sighted onlookers.
                +    this.scrollToElement_(newActiveDescId);
                +  },
                +  // This clears the active descendant of the given tree. It is used just
                +  // before the tree is deleted.
                +  clearActiveDesc: function(treeId) {
                +    var activeDesc = document.getElementById(this.getActiveDescId(treeId));
                +    if (activeDesc) {
                +      activeDesc.classList.remove('blocklyActiveDescendant');
                +    }
                +
                +    if (this.activeDescendantIds_[treeId]) {
                +      delete this.activeDescendantIds_[treeId];
                +    }
                +  },
                +  clearAllActiveDescs: function() {
                +    for (var treeId in this.activeDescendantIds_) {
                +      var activeDesc = document.getElementById(this.getActiveDescId(treeId));
                +      if (activeDesc) {
                +        activeDesc.classList.remove('blocklyActiveDescendant');
                +      }
                +    }
                +
                +    this.activeDescendantIds_ = {};
                +  },
                +
                +  isTreeRoot_: function(element) {
                +    return element.classList.contains('blocklyTree');
                +  },
                +  getBlockRootId_: function(blockId) {
                +    return blockId + this.BLOCK_ROOT_ID_SUFFIX_;
                +  },
                +  // Return the 'lowest' Blockly block in the DOM tree that contains the given
                +  // DOM element.
                +  getContainingBlock_: function(domElement) {
                +    var potentialBlockRoot = domElement;
                +    while (potentialBlockRoot.id.indexOf(this.BLOCK_ROOT_ID_SUFFIX_) === -1) {
                +      potentialBlockRoot = potentialBlockRoot.parentNode;
                +    }
                +
                +    var blockRootId = potentialBlockRoot.id;
                +    var blockId = blockRootId.substring(
                +        0, blockRootId.length - this.BLOCK_ROOT_ID_SUFFIX_.length);
                +    return blocklyApp.workspace.getBlockById(blockId);
                +  },
                +  isTopLevelBlock_: function(block) {
                +    return !block.getParent();
                +  },
                +  // Returns whether the given block is at the top level, and has no siblings.
                +  isIsolatedTopLevelBlock_: function(block) {
                +    var blockHasNoSiblings = (
                +        (!block.nextConnection ||
                +         !block.nextConnection.targetConnection) &&
                +        (!block.previousConnection ||
                +         !block.previousConnection.targetConnection));
                +    return this.isTopLevelBlock_(block) && blockHasNoSiblings;
                +  },
                +  safelyRemoveBlock_: function(block, deleteBlockFunc, areNextBlocksRemoved) {
                +    // Runs the given deleteBlockFunc (which should have the effect of deleting
                +    // the given block, and possibly others after it if `areNextBlocksRemoved`
                +    // is true) and then does one of two things:
                +    // - If the deleted block was an isolated top-level block, or it is a top-
                +    //   level block and the next blocks are going to be removed, this means
                +    //   the current tree has no more blocks after the deletion. So, pick a new
                +    //   tree to focus on.
                +    // - Otherwise, set the correct new active desc for the current tree.
                +    var treeId = this.getTreeIdForBlock(block.id);
                +
                +    var treeCeasesToExist = areNextBlocksRemoved ?
                +        this.isTopLevelBlock_(block) : this.isIsolatedTopLevelBlock_(block);
                +
                +    if (treeCeasesToExist) {
                +      // Find the node to focus on after the deletion happens.
                +      var nextElementToFocusOn = null;
                +      var focusTargets = this.getWorkspaceFocusTargets_();
                +      for (var i = 0; i < focusTargets.length; i++) {
                +        if (focusTargets[i].id == treeId) {
                +          if (i + 1 < focusTargets.length) {
                +            nextElementToFocusOn = focusTargets[i + 1];
                +          } else if (i > 0) {
                +            nextElementToFocusOn = focusTargets[i - 1];
                +          }
                +          break;
                +        }
                +      }
                +
                +      this.clearActiveDesc(treeId);
                +      deleteBlockFunc();
                +      // Invoke a digest cycle, so that the DOM settles (and the "Create new
                +      // group" button in the workspace shows up, if applicable).
                +      setTimeout(function() {
                +        if (nextElementToFocusOn) {
                +          nextElementToFocusOn.focus();
                +        } else {
                +          document.getElementById(
                +              blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus();
                +        }
                +      });
                +    } else {
                +      var blockRootId = this.getBlockRootId_(block.id);
                +      var blockRootElement = document.getElementById(blockRootId);
                +
                +      // Find the new active desc for the current tree by trying the following
                +      // possibilities in order: the parent, the next sibling, and the previous
                +      // sibling. (If `areNextBlocksRemoved` is true, the next sibling would be
                +      // moved together with the moved block, so we don't check it.)
                +      if (areNextBlocksRemoved) {
                +        var newActiveDesc =
                +            this.getParentLi_(blockRootElement) ||
                +            this.getPreviousSiblingLi_(blockRootElement);
                +      } else {
                +        var newActiveDesc =
                +            this.getParentLi_(blockRootElement) ||
                +            this.getNextSiblingLi_(blockRootElement) ||
                +            this.getPreviousSiblingLi_(blockRootElement);
                +      }
                +
                +      this.clearActiveDesc(treeId);
                +      deleteBlockFunc();
                +      // Invoke a digest cycle, so that the DOM settles.
                +      var that = this;
                +      setTimeout(function() {
                +        that.setActiveDesc(newActiveDesc.id, treeId);
                +        document.getElementById(treeId).focus();
                +      });
                +    }
                +  },
                +  getTreeIdForBlock: function(blockId) {
                +    // Walk up the DOM until we get to the root element of the tree.
                +    var potentialRoot = document.getElementById(this.getBlockRootId_(blockId));
                +    while (!this.isTreeRoot_(potentialRoot)) {
                +      potentialRoot = potentialRoot.parentNode;
                +    }
                +    return potentialRoot.id;
                +  },
                +  // Set focus to the tree containing the given block, and set the tree's
                +  // active desc to the root element of the given block.
                +  focusOnBlock: function(blockId) {
                +    // Invoke a digest cycle, in order to allow the ID of the newly-created
                +    // tree to be set in the DOM.
                +    var that = this;
                +    setTimeout(function() {
                +      var treeId = that.getTreeIdForBlock(blockId);
                +      document.getElementById(treeId).focus();
                +      that.setActiveDesc(that.getBlockRootId_(blockId), treeId);
                +    });
                +  },
                +  showBlockOptionsModal: function(block) {
                +    var that = this;
                +    var actionButtonsInfo = [];
                +
                +    if (block.previousConnection) {
                +      actionButtonsInfo.push({
                +        action: function() {
                +          that.blockConnectionService.markConnection(block.previousConnection);
                +          that.focusOnBlock(block.id);
                +        },
                +        translationIdForText: 'MARK_SPOT_BEFORE'
                +      });
                +    }
                +
                +    if (block.nextConnection) {
                +      actionButtonsInfo.push({
                +        action: function() {
                +          that.blockConnectionService.markConnection(block.nextConnection);
                +          that.focusOnBlock(block.id);
                +        },
                +        translationIdForText: 'MARK_SPOT_AFTER'
                +      });
                +    }
                +
                +    if (this.blockConnectionService.canBeMovedToMarkedConnection(block)) {
                +      actionButtonsInfo.push({
                +        action: function() {
                +          var blockDescription = that.utilsService.getBlockDescription(block);
                +          var oldDestinationTreeId = that.getTreeIdForBlock(
                +              that.blockConnectionService.getMarkedConnectionSourceBlock().id);
                +          that.clearActiveDesc(oldDestinationTreeId);
                +
                +          var newBlockId = that.blockConnectionService.attachToMarkedConnection(
                +              block);
                +          that.safelyRemoveBlock_(block, function() {
                +            block.dispose(false);
                +          }, true);
                +
                +          // Invoke a digest cycle, so that the DOM settles.
                +          setTimeout(function() {
                +            that.focusOnBlock(newBlockId);
                +            var newDestinationTreeId = that.getTreeIdForBlock(newBlockId);
                +
                +            if (newDestinationTreeId != oldDestinationTreeId) {
                +              // The tree ID for a moved block does not seem to behave
                +              // predictably. E.g. start with two separate groups of one block
                +              // each, add a link before the block in the second group, and
                +              // move the block in the first group to that link. The tree ID of
                +              // the resulting group ends up being the tree ID for the group
                +              // that was originally first, not second as might be expected.
                +              // Here, we double-check to ensure that all affected trees have
                +              // an active desc set.
                +              if (document.getElementById(oldDestinationTreeId)) {
                +                var activeDescId = that.getActiveDescId(oldDestinationTreeId);
                +                var activeDescTreeId = null;
                +                if (activeDescId) {
                +                  var oldDestinationBlock = that.getContainingBlock_(
                +                      document.getElementById(activeDescId));
                +                  activeDescTreeId = that.getTreeIdForBlock(
                +                      oldDestinationBlock);
                +                  if (activeDescTreeId != oldDestinationTreeId) {
                +                    that.clearActiveDesc(oldDestinationTreeId);
                +                  }
                +                }
                +                that.initActiveDesc(oldDestinationTreeId);
                +              }
                +            }
                +
                +            that.notificationsService.speak(
                +                blockDescription + ' ' +
                +                Blockly.Msg.ATTACHED_BLOCK_TO_LINK_MSG +
                +                '. Now on attached block in workspace.');
                +          });
                +        },
                +        translationIdForText: 'MOVE_TO_MARKED_SPOT'
                +      });
                +    }
                +
                +    actionButtonsInfo.push({
                +      action: function() {
                +        var blockDescription = that.utilsService.getBlockDescription(block);
                +
                +        that.safelyRemoveBlock_(block, function() {
                +          block.dispose(true);
                +          that.audioService.playDeleteSound();
                +        }, false);
                +
                +        setTimeout(function() {
                +          var message = blockDescription + ' deleted. ' + (
                +              that.utilsService.isWorkspaceEmpty() ?
                +              'Workspace is empty.' : 'Now on workspace.');
                +          that.notificationsService.speak(message);
                +        });
                +      },
                +      translationIdForText: 'DELETE'
                +    });
                +
                +    this.blockOptionsModalService.showModal(actionButtonsInfo, function() {
                +      that.focusOnBlock(block.id);
                +    });
                +  },
                +
                +  moveUpOneLevel_: function(treeId) {
                +    var activeDesc = document.getElementById(this.getActiveDescId(treeId));
                +    var nextNode = this.getParentLi_(activeDesc);
                +    if (nextNode) {
                +      this.setActiveDesc(nextNode.id, treeId);
                +    } else {
                +      this.audioService.playOopsSound();
                +    }
                +  },
                +  onKeypress: function(e, tree) {
                +    // TODO(sll): Instead of this, have a common ActiveContextService which
                +    // returns true if at least one modal is shown, and false otherwise.
                +    if (this.blockOptionsModalService.isModalShown() ||
                +        this.variableModalService.isModalShown()) {
                +      return;
                +    }
                +
                +    var treeId = tree.id;
                +    var activeDesc = document.getElementById(this.getActiveDescId(treeId));
                +    if (!activeDesc) {
                +      // The underlying Blockly instance may have decided blocks needed to
                +      // be deleted. This is not necessarily an error, but needs to be repaired.
                +      this.initActiveDesc(treeId);
                +      activeDesc = document.getElementById(this.getActiveDescId(treeId));
                +    }
                +
                +    if (e.altKey || e.ctrlKey) {
                +      // Do not intercept combinations such as Alt+Home.
                +      return;
                +    }
                +
                +    if (document.activeElement.tagName == 'INPUT' ||
                +        document.activeElement.tagName == 'SELECT') {
                +      // For input fields, Esc, Enter, and Tab keystrokes are handled specially.
                +      if (e.keyCode == 9 || e.keyCode == 13 || e.keyCode == 27) {
                +        // Return the focus to the workspace tree containing the input field.
                +        document.getElementById(treeId).focus();
                +
                +        // Note that Tab and Enter events stop propagating, this behavior is
                +        // handled on other listeners.
                +        if (e.keyCode == 27 || e.keyCode == 13) {
                +          e.preventDefault();
                +          e.stopPropagation();
                +        }
                +      }
                +    } else {
                +      // Outside an input field, Enter, Tab, Esc and navigation keys are all
                +      // recognized.
                +      if (e.keyCode == 13) {
                +        // Enter key. The user wants to interact with a button, interact with
                +        // an input field, or open the block options modal.
                +        // Algorithm to find the field: do a DFS through the children until
                +        // we find an INPUT, BUTTON or SELECT element (in which case we use it).
                +        // Truncate the search at child LI elements.
                +        e.stopPropagation();
                +
                +        var found = false;
                +        var dfsStack = Array.from(activeDesc.children);
                +        while (dfsStack.length) {
                +          var currentNode = dfsStack.shift();
                +          if (currentNode.tagName == 'BUTTON') {
                +            currentNode.click();
                +            found = true;
                +            break;
                +          } else if (currentNode.tagName == 'INPUT') {
                +            currentNode.focus();
                +            currentNode.select();
                +            this.notificationsService.speak(
                +                'Type a value, then press Escape to exit');
                +            found = true;
                +            break;
                +          } else if (currentNode.tagName == 'SELECT') {
                +            currentNode.focus();
                +            found = true;
                +            return;
                +          } else if (currentNode.tagName == 'LI') {
                +            continue;
                +          }
                +
                +          if (currentNode.children) {
                +            var reversedChildren = Array.from(currentNode.children).reverse();
                +            reversedChildren.forEach(function(childNode) {
                +              dfsStack.unshift(childNode);
                +            });
                +          }
                +        }
                +
                +        // If we cannot find a field to interact with, we open the modal for
                +        // the current block instead.
                +        if (!found) {
                +          var block = this.getContainingBlock_(activeDesc);
                +          this.showBlockOptionsModal(block);
                +        }
                +      } else if (e.keyCode == 9) {
                +        // Tab key. The event is allowed to propagate through.
                +      } else if ([27, 35, 36, 37, 38, 39, 40].indexOf(e.keyCode) !== -1) {
                +        if (e.keyCode == 27 || e.keyCode == 37) {
                +          // Esc or left arrow key. Go up a level, if possible.
                +          this.moveUpOneLevel_(treeId);
                +        } else if (e.keyCode == 35) {
                +          // End key. Go to the last sibling in the subtree.
                +          var potentialFinalSibling = this.getFinalSiblingLi_(activeDesc);
                +          if (potentialFinalSibling) {
                +            this.setActiveDesc(potentialFinalSibling.id, treeId);
                +          }
                +        } else if (e.keyCode == 36) {
                +          // Home key. Go to the first sibling in the subtree.
                +          var potentialInitialSibling = this.getInitialSiblingLi_(activeDesc);
                +          if (potentialInitialSibling) {
                +            this.setActiveDesc(potentialInitialSibling.id, treeId);
                +          }
                +        } else if (e.keyCode == 38) {
                +          // Up arrow key. Go to the previous sibling, if possible.
                +          var potentialPrevSibling = this.getPreviousSiblingLi_(activeDesc);
                +          if (potentialPrevSibling) {
                +            this.setActiveDesc(potentialPrevSibling.id, treeId);
                +          } else {
                +            var statusMessage = 'Reached top of list.';
                +            if (this.getParentLi_(activeDesc)) {
                +              statusMessage += ' Press left to go to parent list.';
                +            }
                +            this.audioService.playOopsSound(statusMessage);
                +          }
                +        } else if (e.keyCode == 39) {
                +          // Right arrow key. Go down a level, if possible.
                +          var potentialFirstChild = this.getFirstChildLi_(activeDesc);
                +          if (potentialFirstChild) {
                +            this.setActiveDesc(potentialFirstChild.id, treeId);
                +          } else {
                +            this.audioService.playOopsSound();
                +          }
                +        } else if (e.keyCode == 40) {
                +          // Down arrow key. Go to the next sibling, if possible.
                +          var potentialNextSibling = this.getNextSiblingLi_(activeDesc);
                +          if (potentialNextSibling) {
                +            this.setActiveDesc(potentialNextSibling.id, treeId);
                +          } else {
                +            this.audioService.playOopsSound('Reached bottom of list.');
                +          }
                +        }
                +
                +        e.preventDefault();
                +        e.stopPropagation();
                +      }
                +    }
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/utils.service.js b/blockly/webif/static/blockly/accessible/utils.service.js
                new file mode 100644
                index 000000000..d78472dc8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/utils.service.js
                @@ -0,0 +1,44 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 utility service for multiple components. This is a
                + * singleton service that is used for the entire application. In general, it
                + * should only be used as a stateless adapter for native Blockly functions.
                + *
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.UtilsService');
                +
                +
                +blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN = 'blocklyEmptyWorkspaceBtn';
                +blocklyApp.BLOCK_ROOT_ID_SUFFIX = '-blockRoot';
                +
                +blocklyApp.UtilsService = ng.core.Class({
                +  constructor: [function() {}],
                +  getBlockDescription: function(block) {
                +    // We use 'BLANK' instead of the default '?' so that the string is read
                +    // out. (By default, screen readers tend to ignore punctuation.)
                +    return block.toString(undefined, 'BLANK');
                +  },
                +  isWorkspaceEmpty: function() {
                +    return !blocklyApp.workspace.topBlocks_.length;
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/variable-add-modal.component.js b/blockly/webif/static/blockly/accessible/variable-add-modal.component.js
                new file mode 100644
                index 000000000..1965e4e5e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/variable-add-modal.component.js
                @@ -0,0 +1,118 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Component representing the variable rename modal.
                + *
                + * @author corydiers@google.com (Cory Diers)
                + */
                +
                +goog.provide('blocklyApp.VariableAddModalComponent');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.VariableModalService');
                +
                +goog.require('Blockly.CommonModal');
                +
                +
                +blocklyApp.VariableAddModalComponent = ng.core.Component({
                +  selector: 'blockly-add-variable-modal',
                +  template: `
                +    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"
                +         (click)="dismissModal()">
                +      <!-- $event.stopPropagation() prevents the modal from closing when its
                +      interior is clicked. -->
                +      <div id="varModal" class="blocklyModal" role="alertdialog"
                +           (click)="$event.stopPropagation()" tabindex="0"
                +           aria-labelledby="variableModalHeading">
                +          <h3 id="variableModalHeading">Add a variable...</h3>
                +
                +          <form id="varForm">
                +            <p id="inputLabel">New Variable Name:
                +              <input id="mainFieldId" type="text" [ngModel]="VALUE"
                +                     (ngModelChange)="setTextValue($event)" tabindex="0"
                +                     aria-labelledby="inputLabel" />
                +            </p>
                +            <hr>
                +            <button type="button" id="submitButton" (click)="submit()">
                +              SUBMIT
                +            </button>
                +            <button type="button" id="cancelButton" (click)="dismissModal()">
                +              CANCEL
                +            </button>
                +          </form>
                +      </div>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.AudioService, blocklyApp.KeyboardInputService, blocklyApp.VariableModalService,
                +    function(audioService, keyboardService, variableService) {
                +      this.workspace = blocklyApp.workspace;
                +      this.variableModalService = variableService;
                +      this.audioService = audioService;
                +      this.keyboardInputService = keyboardService
                +      this.modalIsVisible = false;
                +      this.activeButtonIndex = -1;
                +
                +      var that = this;
                +      this.variableModalService.registerPreAddShowHook(
                +        function() {
                +          that.modalIsVisible = true;
                +
                +          Blockly.CommonModal.setupKeyboardOverrides(that);
                +
                +          setTimeout(function() {
                +            document.getElementById('varModal').focus();
                +          }, 150);
                +        }
                +      );
                +    }
                +  ],
                +  // Caches the current text variable as the user types.
                +  setTextValue: function(newValue) {
                +    this.variableName = newValue;
                +  },
                +  // Closes the modal (on both success and failure).
                +  hideModal_: Blockly.CommonModal.hideModal,
                +  // Focuses on the button represented by the given index.
                +  focusOnOption: Blockly.CommonModal.focusOnOption,
                +  // Counts the number of interactive elements for the modal.
                +  numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
                +  // Gets all the interactive elements for the modal.
                +  getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
                +  // Gets the container with interactive elements.
                +  getInteractiveContainer: function() {
                +    return document.getElementById("varForm");
                +  },
                +  // Submits the name change for the variable.
                +  submit: function() {
                +    this.workspace.createVariable(this.variableName);
                +    this.dismissModal();
                +  },
                +  // Dismisses and closes the modal.
                +  dismissModal: function() {
                +    this.variableModalService.hideModal();
                +    this.hideModal_();
                +  }
                +})
                diff --git a/blockly/webif/static/blockly/accessible/variable-modal.service.js b/blockly/webif/static/blockly/accessible/variable-modal.service.js
                new file mode 100644
                index 000000000..df5555fae
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/variable-modal.service.js
                @@ -0,0 +1,91 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Service for the variable modal.
                + *
                + * @author corydiers@google.com (Cory Diers)
                + */
                +
                +goog.provide('blocklyApp.VariableModalService');
                +
                +blocklyApp.VariableModalService = ng.core.Class({
                +  constructor: [
                +    function() {
                +      this.modalIsShown = false;
                +    }
                +  ],
                +  // Registers a hook to be called before the add modal is shown.
                +  registerPreAddShowHook: function(preShowHook) {
                +    this.preAddShowHook = function() {
                +      preShowHook();
                +    };
                +  },
                +  // Registers a hook to be called before the rename modal is shown.
                +  registerPreRenameShowHook: function(preShowHook) {
                +    this.preRenameShowHook = function(oldName) {
                +      preShowHook(oldName);
                +    };
                +  },
                +  // Registers a hook to be called before the remove modal is shown.
                +  registerPreRemoveShowHook: function(preShowHook) {
                +    this.preRemoveShowHook = function(oldName, count) {
                +      preShowHook(oldName, count);
                +    };
                +  },
                +  // Returns true if the variable modal is shown.
                +  isModalShown: function() {
                +    return this.modalIsShown;
                +  },
                +  // Show the add variable modal.
                +  showAddModal_: function() {
                +    this.preAddShowHook();
                +    this.modalIsShown = true;
                +  },
                +  // Show the rename variable modal.
                +  showRenameModal_: function(oldName) {
                +    this.preRenameShowHook(oldName);
                +    this.modalIsShown = true;
                +  },
                +  // Show the remove variable modal.
                +  showRemoveModal_: function(oldName) {
                +    var count = this.getNumVariables(oldName);
                +    this.modalIsShown = true;
                +    if (count > 1) {
                +      this.preRemoveShowHook(oldName, count);
                +    } else {
                +      var variable = blocklyApp.workspace.getVariable(oldName);
                +      blocklyApp.workspace.deleteVariableInternal_(variable);
                +      // Allow the execution loop to finish before "closing" the modal. While
                +      // the modal never opens, its being "open" should prevent other keypresses
                +      // anyway.
                +      var that = this;
                +      setTimeout(function() {
                +        that.modalIsShown = false;
                +      });
                +    }
                +  },
                +  getNumVariables: function(oldName) {
                +    return blocklyApp.workspace.getVariableUses(oldName).length;
                +  },
                +  // Hide the variable modal.
                +  hideModal: function() {
                +    this.modalIsShown = false;
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/variable-remove-modal.component.js b/blockly/webif/static/blockly/accessible/variable-remove-modal.component.js
                new file mode 100644
                index 000000000..b542e88a5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/variable-remove-modal.component.js
                @@ -0,0 +1,125 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Component representing the variable remove modal.
                + *
                + * @author corydiers@google.com (Cory Diers)
                + */
                +
                +goog.provide('blocklyApp.VariableRemoveModalComponent');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +goog.require('blocklyApp.VariableModalService');
                +
                +goog.require('Blockly.CommonModal');
                +
                +
                +blocklyApp.VariableRemoveModalComponent = ng.core.Component({
                +  selector: 'blockly-remove-variable-modal',
                +  template: `
                +    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"
                +         (click)="dismissModal()">
                +      <!-- $event.stopPropagation() prevents the modal from closing when its
                +      interior is clicked. -->
                +      <div id="varModal" class="blocklyModal" role="alertdialog"
                +           (click)="$event.stopPropagation()" tabindex="0"
                +           aria-labelledby="variableModalHeading">
                +          <h3 id="variableModalHeading">
                +            Delete {{getNumVariables()}} uses of the "{{currentVariableName}}"
                +            variable?
                +          </h3>
                +
                +          <form id="varForm">
                +            <hr>
                +            <button type="button" id="yesButton" (click)="submit()">
                +              YES
                +            </button>
                +            <button type="button" id="noButton" (click)="dismissModal()">
                +              NO
                +            </button>
                +          </form>
                +      </div>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.AudioService,
                +    blocklyApp.KeyboardInputService,
                +    blocklyApp.TreeService,
                +    blocklyApp.VariableModalService,
                +    function(audioService, keyboardService, treeService, variableService) {
                +      this.workspace = blocklyApp.workspace;
                +      this.treeService = treeService;
                +      this.variableModalService = variableService;
                +      this.audioService = audioService;
                +      this.keyboardInputService = keyboardService
                +      this.modalIsVisible = false;
                +      this.activeButtonIndex = -1;
                +      this.currentVariableName = "";
                +      this.count = 0;
                +
                +      var that = this;
                +      this.variableModalService.registerPreRemoveShowHook(
                +        function(name, count) {
                +          that.currentVariableName = name;
                +          that.count = count
                +          that.modalIsVisible = true;
                +
                +          Blockly.CommonModal.setupKeyboardOverrides(that);
                +
                +          setTimeout(function() {
                +            document.getElementById('varModal').focus();
                +          }, 150);
                +        }
                +      );
                +    }
                +  ],
                +  // Closes the modal (on both success and failure).
                +  hideModal_: Blockly.CommonModal.hideModal,
                +  // Focuses on the button represented by the given index.
                +  focusOnOption: Blockly.CommonModal.focusOnOption,
                +  // Counts the number of interactive elements for the modal.
                +  numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
                +  // Gets all the interactive elements for the modal.
                +  getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
                +  // Gets the container with interactive elements.
                +  getInteractiveContainer: function() {
                +    return document.getElementById("varForm");
                +  },
                +  getNumVariables: function() {
                +    return this.variableModalService.getNumVariables(this.currentVariableName);
                +  },
                +  // Submits the name change for the variable.
                +  submit: function() {
                +    var variable = blocklyApp.workspace.getVariable(this.currentVariableName);
                +    blocklyApp.workspace.deleteVariableInternal_(variable);
                +    this.dismissModal();
                +  },
                +  // Dismisses and closes the modal.
                +  dismissModal: function() {
                +    this.variableModalService.hideModal();
                +    this.hideModal_();
                +  }
                +})
                diff --git a/blockly/webif/static/blockly/accessible/variable-rename-modal.component.js b/blockly/webif/static/blockly/accessible/variable-rename-modal.component.js
                new file mode 100644
                index 000000000..e276e739c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/variable-rename-modal.component.js
                @@ -0,0 +1,121 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Component representing the variable rename modal.
                + *
                + * @author corydiers@google.com (Cory Diers)
                + */
                +
                +goog.provide('blocklyApp.VariableRenameModalComponent');
                +
                +goog.require('Blockly.CommonModal');
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.VariableModalService');
                +
                +
                +blocklyApp.VariableRenameModalComponent = ng.core.Component({
                +  selector: 'blockly-rename-variable-modal',
                +  template: `
                +    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"
                +         (click)="dismissModal()">
                +      <!-- $event.stopPropagation() prevents the modal from closing when its
                +      interior is clicked. -->
                +      <div id="varModal" class="blocklyModal" role="alertdialog"
                +           (click)="$event.stopPropagation()" tabindex="0"
                +           aria-labelledby="variableModalHeading">
                +          <h3 id="variableModalHeading">
                +            Rename the "{{currentVariableName}}" variable...
                +          </h3>
                +
                +          <form id="varForm">
                +            <p id="inputLabel">New Variable Name:
                +              <input id="mainFieldId" type="text" [ngModel]="VALUE"
                +                     (ngModelChange)="setTextValue($event)" tabindex="0"
                +                     aria-labelledby="inputLabel" />
                +            </p>
                +            <hr>
                +            <button type="button" id="submitButton" (click)="submit()">
                +              SUBMIT
                +            </button>
                +            <button type="button" id="cancelButton" (click)="dismissModal()">
                +              CANCEL
                +            </button>
                +          </form>
                +      </div>
                +    </div>
                +  `,
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.AudioService, blocklyApp.KeyboardInputService, blocklyApp.VariableModalService,
                +    function(audioService, keyboardService, variableService) {
                +      this.workspace = blocklyApp.workspace;
                +      this.variableModalService = variableService;
                +      this.audioService = audioService;
                +      this.keyboardInputService = keyboardService
                +      this.modalIsVisible = false;
                +      this.activeButtonIndex = -1;
                +      this.currentVariableName = "";
                +
                +      var that = this;
                +      this.variableModalService.registerPreRenameShowHook(
                +        function(oldName) {
                +          that.currentVariableName = oldName;
                +          that.modalIsVisible = true;
                +
                +          Blockly.CommonModal.setupKeyboardOverrides(that);
                +
                +          setTimeout(function() {
                +            document.getElementById('varModal').focus();
                +          }, 150);
                +        }
                +      );
                +    }
                +  ],
                +  // Caches the current text variable as the user types.
                +  setTextValue: function(newValue) {
                +    this.variableName = newValue;
                +  },
                +  // Closes the modal (on both success and failure).
                +  hideModal_: Blockly.CommonModal.hideModal,
                +  // Focuses on the button represented by the given index.
                +  focusOnOption: Blockly.CommonModal.focusOnOption,
                +  // Counts the number of interactive elements for the modal.
                +  numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
                +  // Gets all the interactive elements for the modal.
                +  getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
                +  // Gets the container with interactive elements.
                +  getInteractiveContainer: function() {
                +    return document.getElementById("varForm");
                +  },
                +  // Submits the name change for the variable.
                +  submit: function() {
                +    this.workspace.renameVariable(this.currentVariableName, this.variableName);
                +    this.dismissModal();
                +  },
                +  // Dismisses and closes the modal.
                +  dismissModal: function() {
                +    this.variableModalService.hideModal();
                +    this.hideModal_();
                +  }
                +})
                diff --git a/blockly/webif/static/blockly/accessible/workspace-block.component.js b/blockly/webif/static/blockly/accessible/workspace-block.component.js
                new file mode 100644
                index 000000000..ca20b7fde
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/workspace-block.component.js
                @@ -0,0 +1,216 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component representing a Blockly.Block in the
                + * workspace.
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.WorkspaceBlockComponent');
                +
                +goog.require('blocklyApp.UtilsService');
                +
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.FieldSegmentComponent');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +
                +
                +blocklyApp.WorkspaceBlockComponent = ng.core.Component({
                +  selector: 'blockly-workspace-block',
                +  template: `
                +    <li [id]="componentIds.blockRoot" role="treeitem"
                +        [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.blockSummary, 'blockly-translate-workspace-block')"
                +        [attr.aria-level]="level">
                +      <label #blockSummaryLabel [id]="componentIds.blockSummary">{{getBlockDescription()}}</label>
                +
                +      <ol role="group">
                +        <template ngFor #blockInput [ngForOf]="block.inputList" #i="index">
                +          <li [id]="componentIds.inputs[i].inputLi" role="treeitem"
                +              *ngIf="blockInput.fieldRow.length"
                +              [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].fieldLabel)"
                +              [attr.aria-level]="level + 1">
                +            <blockly-field-segment *ngFor="#fieldSegment of inputListAsFieldSegments[i]"
                +                                   [prefixFields]="fieldSegment.prefixFields"
                +                                   [mainField]="fieldSegment.mainField"
                +                                   [mainFieldId]="componentIds.inputs[i].fieldLabel"
                +                                   [level]="level + 2">
                +            </blockly-field-segment>
                +          </li>
                +
                +          <template [ngIf]="blockInput.connection">
                +            <blockly-workspace-block *ngIf="blockInput.connection.targetBlock()"
                +                                     [block]="blockInput.connection.targetBlock()"
                +                                     [level]="level + 1"
                +                                     [tree]="tree">
                +            </blockly-workspace-block>
                +            <li [id]="componentIds.inputs[i].actionButtonLi" role="treeitem"
                +                *ngIf="!blockInput.connection.targetBlock()"
                +                [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].buttonLabel)"
                +                [attr.aria-level]="level + 1">
                +              <label [id]="componentIds.inputs[i].label">
                +                {{getBlockNeededLabel(blockInput)}}
                +              </label>
                +              <button [id]="componentIds.inputs[i].actionButton"
                +                      (click)="addInteriorLink(blockInput.connection)"
                +                      tabindex="-1">
                +                {{'MARK_THIS_SPOT'|translate}}
                +              </button>
                +            </li>
                +          </template>
                +        </template>
                +      </ol>
                +    </li>
                +
                +    <blockly-workspace-block *ngIf= "block.nextConnection && block.nextConnection.targetBlock()"
                +                             [block]="block.nextConnection.targetBlock()"
                +                             [level]="level" [tree]="tree">
                +    </blockly-workspace-block>
                +  `,
                +  directives: [blocklyApp.FieldSegmentComponent, ng.core.forwardRef(function() {
                +    return blocklyApp.WorkspaceBlockComponent;
                +  })],
                +  inputs: ['block', 'level', 'tree'],
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.AudioService,
                +    blocklyApp.BlockConnectionService,
                +    blocklyApp.TreeService,
                +    blocklyApp.UtilsService,
                +    function(audioService, blockConnectionService, treeService, utilsService) {
                +      this.audioService = audioService;
                +      this.blockConnectionService = blockConnectionService;
                +      this.treeService = treeService;
                +      this.utilsService = utilsService;
                +      this.cachedBlockId = null;
                +    }
                +  ],
                +  ngDoCheck: function() {
                +    // The block ID can change if, for example, a block is spliced between two
                +    // linked blocks. We need to refresh the fields and component IDs when this
                +    // happens.
                +    if (this.cachedBlockId != this.block.id) {
                +      this.cachedBlockId = this.block.id;
                +
                +      var SUPPORTED_FIELDS = [Blockly.FieldTextInput, Blockly.FieldDropdown];
                +      this.inputListAsFieldSegments = this.block.inputList.map(function(input) {
                +        // Converts the input list to an array of field segments. Each field
                +        // segment represents a user-editable field, prefixed by an arbitrary
                +        // number of non-editable fields.
                +        var fieldSegments = [];
                +
                +        var bufferedFields = [];
                +        input.fieldRow.forEach(function(field) {
                +          var fieldIsSupported = SUPPORTED_FIELDS.some(function(fieldType) {
                +            return (field instanceof fieldType);
                +          });
                +
                +          if (fieldIsSupported) {
                +            var fieldSegment = {
                +              prefixFields: [],
                +              mainField: field
                +            };
                +            bufferedFields.forEach(function(bufferedField) {
                +              fieldSegment.prefixFields.push(bufferedField);
                +            });
                +            fieldSegments.push(fieldSegment);
                +            bufferedFields = [];
                +          } else {
                +            bufferedFields.push(field);
                +          }
                +        });
                +
                +        // Handle leftover text at the end.
                +        if (bufferedFields.length) {
                +          fieldSegments.push({
                +            prefixFields: bufferedFields,
                +            mainField: null
                +          });
                +        }
                +
                +        return fieldSegments;
                +      });
                +
                +      // Generate unique IDs for elements in this component.
                +      this.componentIds = {};
                +      this.componentIds.blockRoot =
                +          this.block.id + blocklyApp.BLOCK_ROOT_ID_SUFFIX;
                +      this.componentIds.blockSummary = this.block.id + '-blockSummary';
                +
                +      var that = this;
                +      this.componentIds.inputs = this.block.inputList.map(function(input, i) {
                +        var idsToGenerate = ['inputLi', 'fieldLabel'];
                +        if (input.connection && !input.connection.targetBlock()) {
                +          idsToGenerate.push('actionButtonLi', 'actionButton', 'buttonLabel');
                +        }
                +
                +        var inputIds = {};
                +        idsToGenerate.forEach(function(idBaseString) {
                +          inputIds[idBaseString] = [that.block.id, i, idBaseString].join('-');
                +        });
                +
                +        return inputIds;
                +      });
                +    }
                +  },
                +  ngAfterViewInit: function() {
                +    // If this is a top-level tree in the workspace, ensure that it has an
                +    // active descendant. (Note that a timeout is needed here in order to
                +    // trigger Angular change detection.)
                +    var that = this;
                +    setTimeout(function() {
                +      if (that.level === 0 && !that.treeService.getActiveDescId(that.tree.id)) {
                +        that.treeService.setActiveDesc(
                +            that.componentIds.blockRoot, that.tree.id);
                +      }
                +    });
                +  },
                +  addInteriorLink: function(connection) {
                +    this.blockConnectionService.markConnection(connection);
                +  },
                +  getBlockDescription: function() {
                +    var blockDescription = this.utilsService.getBlockDescription(this.block);
                +
                +    var parentBlock = this.block.getSurroundParent();
                +    if (parentBlock) {
                +      var fullDescription = blockDescription + ' inside ' +
                +          this.utilsService.getBlockDescription(parentBlock);
                +      return fullDescription;
                +    } else {
                +      return blockDescription;
                +    }
                +  },
                +  getBlockNeededLabel: function(blockInput) {
                +    // The input type name, or 'any' if any official input type qualifies.
                +    var inputTypeLabel = (
                +        blockInput.connection.check_ ?
                +        blockInput.connection.check_.join(', ') : Blockly.Msg.ANY);
                +    var blockTypeLabel = (
                +        blockInput.type == Blockly.NEXT_STATEMENT ?
                +        Blockly.Msg.BLOCK : Blockly.Msg.VALUE);
                +    return inputTypeLabel + ' ' + blockTypeLabel + ' needed:';
                +  },
                +  generateAriaLabelledByAttr: function(mainLabel, secondLabel) {
                +    return mainLabel + (secondLabel ? ' ' + secondLabel : '');
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/accessible/workspace.component.js b/blockly/webif/static/blockly/accessible/workspace.component.js
                new file mode 100644
                index 000000000..084460117
                --- /dev/null
                +++ b/blockly/webif/static/blockly/accessible/workspace.component.js
                @@ -0,0 +1,106 @@
                +/**
                + * AccessibleBlockly
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the 'License');
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an 'AS IS' BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angular2 Component that details how a Blockly.Workspace is
                + * rendered in AccessibleBlockly.
                + *
                + * @author madeeha@google.com (Madeeha Ghori)
                + */
                +
                +goog.provide('blocklyApp.WorkspaceComponent');
                +
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.ToolboxModalService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +
                +goog.require('blocklyApp.WorkspaceBlockComponent');
                +
                +
                +blocklyApp.WorkspaceComponent = ng.core.Component({
                +  selector: 'blockly-workspace',
                +  template: `
                +    <div class="blocklyWorkspaceColumn">
                +      <h3 #workspaceTitle id="blockly-workspace-title">{{'WORKSPACE'|translate}}</h3>
                +
                +      <div *ngIf="workspace" class="blocklyWorkspace">
                +        <ol #tree *ngFor="#topBlock of workspace.topBlocks_; #groupIndex = index"
                +            [id]="tree.id || getNewTreeId()"
                +            tabindex="0" role="tree" class="blocklyTree blocklyWorkspaceFocusTarget"
                +            [attr.aria-activedescendant]="getActiveDescId(tree.id)"
                +            [attr.aria-labelledby]="workspaceTitle.id"
                +            (keydown)="onKeypress($event, tree)"
                +            (focus)="speakLocation(groupIndex, tree.id)">
                +          <blockly-workspace-block [level]="0" [block]="topBlock" [tree]="tree">
                +          </blockly-workspace-block>
                +        </ol>
                +
                +        <span *ngIf="workspace.topBlocks_.length === 0">
                +          <p id="emptyWorkspaceBtnLabel">
                +            {{'NO_BLOCKS_IN_WORKSPACE'|translate}}
                +            <button (click)="showToolboxModalForCreateNewGroup()"
                +                    class="blocklyWorkspaceFocusTarget"
                +                    id="{{ID_FOR_EMPTY_WORKSPACE_BTN}}"
                +                    aria-describedby="emptyWorkspaceBtnLabel">
                +              {{'CREATE_NEW_BLOCK_GROUP'|translate}}
                +            </button>
                +          </p>
                +        </span>
                +      </div>
                +    </div>
                +  `,
                +  directives: [blocklyApp.WorkspaceBlockComponent],
                +  pipes: [blocklyApp.TranslatePipe]
                +})
                +.Class({
                +  constructor: [
                +    blocklyApp.NotificationsService,
                +    blocklyApp.ToolboxModalService,
                +    blocklyApp.TreeService,
                +    function(notificationsService, toolboxModalService, treeService) {
                +      this.notificationsService = notificationsService;
                +      this.toolboxModalService = toolboxModalService;
                +      this.treeService = treeService;
                +
                +      this.ID_FOR_EMPTY_WORKSPACE_BTN = blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN;
                +      this.workspace = blocklyApp.workspace;
                +      this.currentTreeId = 0;
                +    }
                +  ],
                +  getNewTreeId: function() {
                +    this.currentTreeId++;
                +    return 'blockly-tree-' + this.currentTreeId;
                +  },
                +  getActiveDescId: function(treeId) {
                +    return this.treeService.getActiveDescId(treeId);
                +  },
                +  onKeypress: function(e, tree) {
                +    this.treeService.onKeypress(e, tree);
                +  },
                +  showToolboxModalForCreateNewGroup: function() {
                +    this.toolboxModalService.showToolboxModalForCreateNewGroup(
                +        this.ID_FOR_EMPTY_WORKSPACE_BTN);
                +  },
                +  speakLocation: function(groupIndex, treeId) {
                +    this.notificationsService.speak(
                +        'Now in workspace group ' + (groupIndex + 1) + ' of ' +
                +        this.workspace.topBlocks_.length);
                +  }
                +});
                diff --git a/blockly/webif/static/blockly/appengine/README.txt b/blockly/webif/static/blockly/appengine/README.txt
                new file mode 100644
                index 000000000..6ba262bba
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/README.txt
                @@ -0,0 +1,44 @@
                +
                +  Running an App Engine server
                +
                +This directory contains the files needed to setup the optional Blockly server.
                +Although Blockly itself is 100% client-side, the server enables cloud storage
                +and sharing.  Store your programs in Datastore and get a unique URL that allows
                +you to load the program on any computer.
                +
                +To run your own App Engine instance you'll need to create this directory
                +structure:
                +
                +blockly/
                + |- app.yaml
                + |- index.yaml
                + |- index_redirect.py
                + |- README.txt
                + |- storage.js
                + |- storage.py
                + |- closure-library/  (Optional)
                + `- static/
                +     |- blocks/
                +     |- core/
                +     |- demos/
                +     |- generators/
                +     |- media/
                +     |- msg/
                +     |- tests/
                +     |- blockly_compressed.js
                +     |- blockly_uncompressed.js  (Optional)
                +     |- blocks_compressed.js
                +     |- dart_compressed.js
                +     |- javascript_compressed.js
                +     |- lua_compressed.js
                +     |- php_compressed.js
                +     `- python_compressed.js
                +
                +Instructions for fetching the optional Closure library may be found here:
                +  https://developers.google.com/blockly/guides/modify/web/closure
                +
                +Go to https://appengine.google.com/ and create your App Engine application.
                +Modify the 'application' name of app.yaml to your App Engine application name.
                +
                +Finally, upload this directory structure to your App Engine account,
                +wait a minute, then go to http://YOURAPPNAME.appspot.com/
                diff --git a/blockly/webif/static/blockly/appengine/app.yaml b/blockly/webif/static/blockly/appengine/app.yaml
                new file mode 100644
                index 000000000..8938830f8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/app.yaml
                @@ -0,0 +1,87 @@
                +application: blockly-demo
                +version: 1
                +runtime: python27
                +api_version: 1
                +threadsafe: no
                +
                +handlers:
                +# Redirect obsolete URLs.
                +# Blockly files moved from /blockly to /static on 5 Dec 2012.
                +- url: /blockly/.*
                +  static_files: redirect.html
                +  upload: redirect.html
                +# Code, Maze and Turtle moved from demos on 29 Dec 2012.
                +- url: /static/demos/(maze|turtle)/.*
                +  static_files: redirect.html
                +  upload: redirect.html
                +# Apps was disbanded on 20 Nov 2014.
                +- url: /static/apps/.*
                +  static_files: redirect.html
                +  upload: redirect.html
                +
                +
                +# Storage API.
                +- url: /storage
                +  script: storage.py
                +  secure: always
                +- url: /storage\.js
                +  static_files: storage.js
                +  upload: storage\.js
                +  secure: always
                +
                +# Blockly files.
                +- url: /static
                +  static_dir: static
                +  secure: always
                +
                +# Closure library for uncompressed Blockly.
                +- url: /closure-library
                +  static_dir: closure-library
                +  secure: always
                +
                +# Redirect for root directory.
                +- url: /
                +  script: index_redirect.py
                +  secure: always
                +
                +# Favicon.
                +- url: /favicon\.ico
                +  static_files: favicon.ico
                +  upload: favicon\.ico
                +  secure: always
                +  expiration: "30d"
                +
                +# Apple icon.
                +- url: /apple-touch-icon\.png
                +  static_files: apple-touch-icon.png
                +  upload: apple-touch-icon\.png
                +  secure: always
                +  expiration: "30d"
                +
                +# robot.txt
                +- url: /robots\.txt
                +  static_files: robots.txt
                +  upload: robots\.txt
                +  secure: always
                +
                +
                +skip_files:
                +# App Engine default patterns.
                +- ^(.*/)?#.*#$
                +- ^(.*/)?.*~$
                +- ^(.*/)?.*\.py[co]$
                +- ^(.*/)?.*/RCS/.*$
                +- ^(.*/)?\..*$
                +# Custom skip patterns.
                +- ^static/appengine/.*$
                +- ^static/demos/plane/soy/.+\.jar$
                +- ^static/demos/plane/template.soy$
                +- ^static/demos/plane/xlf/.*$
                +- ^static/i18n/.*$
                +- ^static/msg/json/.*$
                +- ^.+\.soy$
                +- ^closure-library/.*_test.html$
                +- ^closure-library/.*_test.js$
                +- ^closure-library/closure/bin/.*$
                +- ^closure-library/doc/.*$
                +- ^closure-library/scripts/.*$
                diff --git a/blockly/webif/static/blockly/appengine/apple-touch-icon.png b/blockly/webif/static/blockly/appengine/apple-touch-icon.png
                new file mode 100644
                index 000000000..455abac2d
                Binary files /dev/null and b/blockly/webif/static/blockly/appengine/apple-touch-icon.png differ
                diff --git a/blockly/webif/static/blockly/appengine/favicon.ico b/blockly/webif/static/blockly/appengine/favicon.ico
                new file mode 100644
                index 000000000..683ec6d5d
                Binary files /dev/null and b/blockly/webif/static/blockly/appengine/favicon.ico differ
                diff --git a/blockly/webif/static/blockly/appengine/index.yaml b/blockly/webif/static/blockly/appengine/index.yaml
                new file mode 100644
                index 000000000..a3b9e05e3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/index.yaml
                @@ -0,0 +1,11 @@
                +indexes:
                +
                +# AUTOGENERATED
                +
                +# This index.yaml is automatically updated whenever the dev_appserver
                +# detects that a new type of query is run.  If you want to manage the
                +# index.yaml file manually, remove the above marker line (the line
                +# saying "# AUTOGENERATED").  If you want to manage some indexes
                +# manually, move them above the marker line.  The index.yaml file is
                +# automatically uploaded to the admin console when you next deploy
                +# your application using appcfg.py.
                diff --git a/blockly/webif/static/blockly/appengine/index_redirect.py b/blockly/webif/static/blockly/appengine/index_redirect.py
                new file mode 100644
                index 000000000..286a8e87c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/index_redirect.py
                @@ -0,0 +1,2 @@
                +print("Status: 302")
                +print("Location: /static/demos/index.html")
                diff --git a/blockly/webif/static/blockly/appengine/redirect.html b/blockly/webif/static/blockly/appengine/redirect.html
                new file mode 100644
                index 000000000..9c29bac59
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/redirect.html
                @@ -0,0 +1,68 @@
                +<!DOCTYPE html>
                +<html>
                +  <head>
                +    <script>
                +var loc = location.href;
                +
                +// Blockly files moved from /blockly to /static on 5 Dec 2012.
                +if (loc.match('/blockly/')) {
                +  loc = loc.replace('/blockly/', '/static/');
                +}
                +
                +// Maze and Turtle moved from demos to apps on 29 Dec 2012.
                +if (loc.match(/\/demos\/(maze|turtle)\//)) {
                +  loc = loc.replace('/demos/', '/apps/');
                +}
                +
                +// Vietnamese apps moved from vn to vi on 9 Jun 2012.
                +if (loc.match('/vn.html')) {
                +  loc = loc.replace('/vn.html', '/vi.html');
                +}
                +
                +if (loc.match('/code/code.html')) {
                +  // Code moved to index.html on 7 Aug 2013.
                +  loc = loc.replace('/code.html', '/index.html');
                +} else if (loc.match('/apps/code/zh_tw.html')) {
                +  // zh-tw was changed to zh-hans on 25 Nov 2013.
                +  loc = loc.replace('/zh_tw.html', '/index.html?lang=zh-hans');
                +} else if (loc.match('/apps/code/index.html')) {
                +  // NOP.
                +} else if (loc.match(/\/apps\/code\/[-a-z]+\.html/)) {
                +  // Code became language-agnostic on 20 Jul 2013.
                +  loc = loc.replace(/\/([-a-z]+)\.html/, '/index.html?lang=$1');
                +}
                +
                +if (loc.match('/apps/plane/plane.html')) {
                +  // Plane moved to index.html on 7 Aug 2013.
                +  loc = loc.replace('/plane.html', '/index.html');
                +} else if (loc.match('/apps/code/plane.html')) {
                +  // NOP.
                +} else if (loc.match(/\/apps\/plane\/[\d_]*[-a-z]+\.html/)) {
                +  // Plane became language-agnostic on 20 Jul 2013.
                +  loc = loc.replace('vn.html', 'vi.html');
                +  if (location.search) {
                +    loc = loc.replace(/\/[\d_]*([-a-z]+)\.html\?/, '/index.html?lang=$1&');
                +  } else {
                +    loc = loc.replace(/\/[\d_]*([-a-z]+)\.html/, '/index.html?lang=$1');
                +  }
                +}
                +
                +if (loc.match('/apps/puzzle/')) {
                +  // Puzzle moved to Blockly Games on 15 Oct 2014.
                +  loc = 'https://blockly-games.appspot.com/puzzle';
                +} else if (loc.match('/apps/maze/')) {
                +  // Maze moved to Blockly Games on 10 Nov 2014.
                +  loc = 'https://blockly-games.appspot.com/maze';
                +} else if (loc.match('/apps/turtle/')) {
                +  // Turtle moved to Blockly Games on 10 Nov 2014.
                +  loc = 'https://blockly-games.appspot.com/turtle';
                +} else if (loc.match('/apps/')) {
                +  // Remaining apps moved to demos on 20 Nov 2014.
                +  loc = loc.replace('/apps/', '/demos/');
                +}
                +
                +location = loc;
                +
                +    </script>
                +  </head>
                +</html>
                diff --git a/blockly/webif/static/blockly/appengine/robots.txt b/blockly/webif/static/blockly/appengine/robots.txt
                new file mode 100644
                index 000000000..428c409a7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/robots.txt
                @@ -0,0 +1,2 @@
                +User-agent: *
                +Disallow: /storage
                diff --git a/blockly/webif/static/blockly/appengine/storage.js b/blockly/webif/static/blockly/appengine/storage.js
                new file mode 100644
                index 000000000..8141806d5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/storage.js
                @@ -0,0 +1,194 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Loading and saving blocks with localStorage and cloud storage.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +// Create a namespace.
                +var BlocklyStorage = {};
                +
                +/**
                + * Backup code blocks to localStorage.
                + * @param {!Blockly.WorkspaceSvg} workspace Workspace.
                + * @private
                + */
                +BlocklyStorage.backupBlocks_ = function(workspace) {
                +  if ('localStorage' in window) {
                +    var xml = Blockly.Xml.workspaceToDom(workspace);
                +    // Gets the current URL, not including the hash.
                +    var url = window.location.href.split('#')[0];
                +    window.localStorage.setItem(url, Blockly.Xml.domToText(xml));
                +  }
                +};
                +
                +/**
                + * Bind the localStorage backup function to the unload event.
                + * @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
                + */
                +BlocklyStorage.backupOnUnload = function(opt_workspace) {
                +  var workspace = opt_workspace || Blockly.getMainWorkspace();
                +  window.addEventListener('unload',
                +      function() {BlocklyStorage.backupBlocks_(workspace);}, false);
                +};
                +
                +/**
                + * Restore code blocks from localStorage.
                + * @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
                + */
                +BlocklyStorage.restoreBlocks = function(opt_workspace) {
                +  var url = window.location.href.split('#')[0];
                +  if ('localStorage' in window && window.localStorage[url]) {
                +    var workspace = opt_workspace || Blockly.getMainWorkspace();
                +    var xml = Blockly.Xml.textToDom(window.localStorage[url]);
                +    Blockly.Xml.domToWorkspace(xml, workspace);
                +  }
                +};
                +
                +/**
                + * Save blocks to database and return a link containing key to XML.
                + * @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
                + */
                +BlocklyStorage.link = function(opt_workspace) {
                +  var workspace = opt_workspace || Blockly.getMainWorkspace();
                +  var xml = Blockly.Xml.workspaceToDom(workspace);
                +  var data = Blockly.Xml.domToText(xml);
                +  BlocklyStorage.makeRequest_('/storage', 'xml', data, workspace);
                +};
                +
                +/**
                + * Retrieve XML text from database using given key.
                + * @param {string} key Key to XML, obtained from href.
                + * @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
                + */
                +BlocklyStorage.retrieveXml = function(key, opt_workspace) {
                +  var workspace = opt_workspace || Blockly.getMainWorkspace();
                +  BlocklyStorage.makeRequest_('/storage', 'key', key, workspace);
                +};
                +
                +/**
                + * Global reference to current AJAX request.
                + * @type {XMLHttpRequest}
                + * @private
                + */
                +BlocklyStorage.httpRequest_ = null;
                +
                +/**
                + * Fire a new AJAX request.
                + * @param {string} url URL to fetch.
                + * @param {string} name Name of parameter.
                + * @param {string} content Content of parameter.
                + * @param {!Blockly.WorkspaceSvg} workspace Workspace.
                + * @private
                + */
                +BlocklyStorage.makeRequest_ = function(url, name, content, workspace) {
                +  if (BlocklyStorage.httpRequest_) {
                +    // AJAX call is in-flight.
                +    BlocklyStorage.httpRequest_.abort();
                +  }
                +  BlocklyStorage.httpRequest_ = new XMLHttpRequest();
                +  BlocklyStorage.httpRequest_.name = name;
                +  BlocklyStorage.httpRequest_.onreadystatechange =
                +      BlocklyStorage.handleRequest_;
                +  BlocklyStorage.httpRequest_.open('POST', url);
                +  BlocklyStorage.httpRequest_.setRequestHeader('Content-Type',
                +      'application/x-www-form-urlencoded');
                +  BlocklyStorage.httpRequest_.send(name + '=' + encodeURIComponent(content));
                +  BlocklyStorage.httpRequest_.workspace = workspace;
                +};
                +
                +/**
                + * Callback function for AJAX call.
                + * @private
                + */
                +BlocklyStorage.handleRequest_ = function() {
                +  if (BlocklyStorage.httpRequest_.readyState == 4) {
                +    if (BlocklyStorage.httpRequest_.status != 200) {
                +      BlocklyStorage.alert(BlocklyStorage.HTTPREQUEST_ERROR + '\n' +
                +          'httpRequest_.status: ' + BlocklyStorage.httpRequest_.status);
                +    } else {
                +      var data = BlocklyStorage.httpRequest_.responseText.trim();
                +      if (BlocklyStorage.httpRequest_.name == 'xml') {
                +        window.location.hash = data;
                +        BlocklyStorage.alert(BlocklyStorage.LINK_ALERT.replace('%1',
                +            window.location.href));
                +      } else if (BlocklyStorage.httpRequest_.name == 'key') {
                +        if (!data.length) {
                +          BlocklyStorage.alert(BlocklyStorage.HASH_ERROR.replace('%1',
                +              window.location.hash));
                +        } else {
                +          BlocklyStorage.loadXml_(data, BlocklyStorage.httpRequest_.workspace);
                +        }
                +      }
                +      BlocklyStorage.monitorChanges_(BlocklyStorage.httpRequest_.workspace);
                +    }
                +    BlocklyStorage.httpRequest_ = null;
                +  }
                +};
                +
                +/**
                + * Start monitoring the workspace.  If a change is made that changes the XML,
                + * clear the key from the URL.  Stop monitoring the workspace once such a
                + * change is detected.
                + * @param {!Blockly.WorkspaceSvg} workspace Workspace.
                + * @private
                + */
                +BlocklyStorage.monitorChanges_ = function(workspace) {
                +  var startXmlDom = Blockly.Xml.workspaceToDom(workspace);
                +  var startXmlText = Blockly.Xml.domToText(startXmlDom);
                +  function change() {
                +    var xmlDom = Blockly.Xml.workspaceToDom(workspace);
                +    var xmlText = Blockly.Xml.domToText(xmlDom);
                +    if (startXmlText != xmlText) {
                +      window.location.hash = '';
                +      workspace.removeChangeListener(bindData);
                +    }
                +  }
                +  var bindData = workspace.addChangeListener(change);
                +};
                +
                +/**
                + * Load blocks from XML.
                + * @param {string} xml Text representation of XML.
                + * @param {!Blockly.WorkspaceSvg} workspace Workspace.
                + * @private
                + */
                +BlocklyStorage.loadXml_ = function(xml, workspace) {
                +  try {
                +    xml = Blockly.Xml.textToDom(xml);
                +  } catch (e) {
                +    BlocklyStorage.alert(BlocklyStorage.XML_ERROR + '\nXML: ' + xml);
                +    return;
                +  }
                +  // Clear the workspace to avoid merge.
                +  workspace.clear();
                +  Blockly.Xml.domToWorkspace(xml, workspace);
                +};
                +
                +/**
                + * Present a text message to the user.
                + * Designed to be overridden if an app has custom dialogs, or a butter bar.
                + * @param {string} message Text to alert.
                + */
                +BlocklyStorage.alert = function(message) {
                +  window.alert(message);
                +};
                diff --git a/blockly/webif/static/blockly/appengine/storage.py b/blockly/webif/static/blockly/appengine/storage.py
                new file mode 100644
                index 000000000..4a572073f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/appengine/storage.py
                @@ -0,0 +1,85 @@
                +"""Blockly Demo: Storage
                +
                +Copyright 2012 Google Inc.
                +https://developers.google.com/blockly/
                +
                +Licensed under the Apache License, Version 2.0 (the "License");
                +you may not use this file except in compliance with the License.
                +You may obtain a copy of the License at
                +
                +  http://www.apache.org/licenses/LICENSE-2.0
                +
                +Unless required by applicable law or agreed to in writing, software
                +distributed under the License is distributed on an "AS IS" BASIS,
                +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +See the License for the specific language governing permissions and
                +limitations under the License.
                +"""
                +
                +"""Store and retrieve XML with App Engine.
                +"""
                +
                +__author__ = "q.neutron@gmail.com (Quynh Neutron)"
                +
                +import cgi
                +from random import randint
                +from google.appengine.ext import db
                +from google.appengine.api import memcache
                +import logging
                +
                +print "Content-Type: text/plain\n"
                +
                +def keyGen():
                +  # Generate a random string of length KEY_LEN.
                +  KEY_LEN = 6
                +  CHARS = "abcdefghijkmnopqrstuvwxyz23456789" # Exclude l, 0, 1.
                +  max_index = len(CHARS) - 1
                +  return "".join([CHARS[randint(0, max_index)] for x in range(KEY_LEN)])
                +
                +class Xml(db.Model):
                +  # A row in the database.
                +  xml_hash = db.IntegerProperty()
                +  xml_content = db.TextProperty()
                +
                +forms = cgi.FieldStorage()
                +if "xml" in forms:
                +  # Store XML and return a generated key.
                +  xml_content = forms["xml"].value
                +  xml_hash = hash(xml_content)
                +  lookup_query = db.Query(Xml)
                +  lookup_query.filter("xml_hash =", xml_hash)
                +  lookup_result = lookup_query.get()
                +  if lookup_result:
                +    xml_key = lookup_result.key().name()
                +  else:
                +    trials = 0
                +    result = True
                +    while result:
                +      trials += 1
                +      if trials == 100:
                +        raise Exception("Sorry, the generator failed to get a key for you.")
                +      xml_key = keyGen()
                +      result = db.get(db.Key.from_path("Xml", xml_key))
                +    xml = db.Text(xml_content, encoding="utf_8")
                +    row = Xml(key_name = xml_key, xml_hash = xml_hash, xml_content = xml)
                +    row.put()
                +  print xml_key
                +
                +if "key" in forms:
                +  # Retrieve stored XML based on the provided key.
                +  key_provided = forms["key"].value
                +  # Normalize the string.
                +  key_provided = key_provided.lower().strip()
                +  # Check memcache for a quick match.
                +  xml = memcache.get("XML_" + key_provided)
                +  if xml is None:
                +    # Check datastore for a definitive match.
                +    result = db.get(db.Key.from_path("Xml", key_provided))
                +    if not result:
                +      xml = ""
                +    else:
                +      xml = result.xml_content
                +    # Save to memcache for next hit.
                +    if not memcache.add("XML_" + key_provided, xml, 3600):
                +      logging.error("Memcache set failed.")
                +  print xml.encode("utf-8")
                diff --git a/blockly/webif/static/blockly/blockly_accessible_compressed.js b/blockly/webif/static/blockly/blockly_accessible_compressed.js
                new file mode 100644
                index 000000000..138f74b6a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blockly_accessible_compressed.js
                @@ -0,0 +1,1769 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +var COMPILED=!0,goog=goog||{};goog.global=this;goog.isDef=function(a){return void 0!==a};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.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]!==Object.prototype[d]?c[d]:c[d]={}};
                +goog.define=function(a,b){COMPILED||(goog.global.CLOSURE_UNCOMPILED_DEFINES&&void 0===goog.global.CLOSURE_UNCOMPILED_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES,a)?b=goog.global.CLOSURE_UNCOMPILED_DEFINES[a]:goog.global.CLOSURE_DEFINES&&void 0===goog.global.CLOSURE_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,a)&&(b=goog.global.CLOSURE_DEFINES[a]));goog.exportPath_(a,b)};goog.DEBUG=!1;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){if(a in goog.loadedModules_)return goog.loadedModules_[a];if(!goog.implicitNamespaces_[a])return a=goog.getObjectByName(a),null!=a?a:null}return 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){a=a.split(".");b=b||goog.global;for(var c;c=a.shift();)if(goog.isDefAndNotNull(b[c]))b=b[c];else return null;return b};goog.globalize=function(a,b){b=b||goog.global;for(var c in a)b[c]=a[c]};
                +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.instance_=void 0;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.isString(goog.global.CLOSURE_BASE_PATH))goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_()){var a=goog.global.document;var b=a.currentScript;a=b?[b]:a.getElementsByTagName("SCRIPT");for(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.oldIeWaiting_=!1,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.oldIeWaiting_=!1},
                +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]||{},c=b.lang||"es3";return a&&("goog"==b.module||goog.needsTranspile_(c))?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');}void 0===b?goog.IS_OLD_IE_?(goog.oldIeWaiting_=!0,b=" onreadystatechange='goog.onScriptLoad_(this, "+ ++goog.lastNonModuleScriptIndex_+")' ",c.write('<script type="text/javascript" src="'+
                +a+'"'+b+">\x3c/script>")):goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING?goog.appendScriptSrcNode_(a):goog.writeScriptSrcNode_(a):c.write('<script type="text/javascript">'+goog.protectScriptTag_(b)+"\x3c/script>");return!0}return!1},goog.protectScriptTag_=function(a){return a.replace(/<\/(SCRIPT)/ig,"\\x3c/$1")},goog.needsTranspile_=function(a){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;goog.requiresTranspilation_||(goog.requiresTranspilation_=goog.createRequiresTranspilation_());
                +if(a in goog.requiresTranspilation_)return goog.requiresTranspilation_[a];throw Error("Unknown language mode: "+a);},goog.requiresTranspilation_=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(var f=0;f<c.length;f++)a=c[f],goog.dependencies_.written[a]=!0;var g=goog.moduleLoaderState_;goog.moduleLoaderState_=null;for(f=0;f<c.length;f++)if(a=c[f]){var h=e.loadFlags[a]||{},k=goog.needsTranspile_(h.lang||"es3");"goog"==h.module||k?goog.importProcessedScript_(goog.basePath+a,"goog"==h.module,k):goog.importScript_(goog.basePath+a)}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.hasBadLetScoping=null;goog.useSafari10Workaround=function(){if(null==goog.hasBadLetScoping){try{var a=!eval('"use strict";let x = 1; function f() { return typeof x; };f() == "number";')}catch(b){a=!1}goog.hasBadLetScoping=a}return goog.hasBadLetScoping};
                +goog.workaroundSafari10EvalBug=function(a){return"(function(){"+a+"\n;})();\n"};
                +goog.loadModule=function(a){var b=goog.moduleLoaderState_;try{goog.moduleLoaderState_={moduleName:void 0,declareLegacyNamespace:!1};if(goog.isFunction(a))var c=a.call(void 0,{});else if(goog.isString(a))goog.useSafari10Workaround()&&(a=goog.workaroundSafari10EvalBug(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&&"object"==typeof c&&null!=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.oldIeWaiting_?(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);if(f){eval(f+"\n//# sourceURL="+e);if(goog.global.$gwtExport&&goog.global.$gwtExport.$jscomp&&!goog.global.$gwtExport.$jscomp.transpile)throw Error('The transpiler did not properly export the "transpile" method. $gwtExport: '+JSON.stringify(goog.global.$gwtExport));goog.global.$jscomp.transpile=goog.global.$gwtExport.$jscomp.transpile;
                +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.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};a=b?a+"-"+d(b):d(a);return goog.global.CLOSURE_CSS_NAME_MAP_FN?goog.global.CLOSURE_CSS_NAME_MAP_FN(a):a};
                +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";
                +goog.createRequiresTranspilation_=function(){function a(a,b){d?c[a]=!0:b()?c[a]=!1:d=c[a]=!0}function b(a){try{return!!eval(a)}catch(g){return!1}}var c={es3:!1},d=!1,e=goog.global.navigator&&goog.global.navigator.userAgent?goog.global.navigator.userAgent:"";a("es5",function(){return b("[1,].length==1")});a("es6",function(){var a=e.match(/Edge\/(\d+)(\.\d)*/i);return a&&15>Number(a[1])?!1:b('(()=>{"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}})()')});
                +a("es6-impl",function(){return!0});a("es7",function(){return b("2 ** 2 == 4")});a("es8",function(){return b("async () => 1, true")});return c};goog.debug={};goog.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,goog.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a));this.reportErrorToServer=!0};goog.inherits(goog.debug.Error,Error);goog.debug.Error.prototype.name="CustomError";goog.dom={};goog.dom.NodeType={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12};goog.string={};goog.string.DETECT_DOUBLE_ESCAPING=!1;goog.string.FORCE_NON_DOM_HTML_UNESCAPING=!1;goog.string.Unicode={NBSP:"\u00a0"};goog.string.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};goog.string.endsWith=function(a,b){var c=a.length-b.length;return 0<=c&&a.indexOf(b,c)==c};goog.string.caseInsensitiveStartsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(0,b.length))};
                +goog.string.caseInsensitiveEndsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(a.length-b.length,b.length))};goog.string.caseInsensitiveEquals=function(a,b){return a.toLowerCase()==b.toLowerCase()};goog.string.subs=function(a,b){for(var c=a.split("%s"),d="",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join("%s")};goog.string.collapseWhitespace=function(a){return a.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")};
                +goog.string.isEmptyOrWhitespace=function(a){return/^[\s\xa0]*$/.test(a)};goog.string.isEmptyString=function(a){return 0==a.length};goog.string.isEmpty=goog.string.isEmptyOrWhitespace;goog.string.isEmptyOrWhitespaceSafe=function(a){return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(a))};goog.string.isEmptySafe=goog.string.isEmptyOrWhitespaceSafe;goog.string.isBreakingWhitespace=function(a){return!/[^\t\n\r ]/.test(a)};goog.string.isAlpha=function(a){return!/[^a-zA-Z]/.test(a)};
                +goog.string.isNumeric=function(a){return!/[^0-9]/.test(a)};goog.string.isAlphaNumeric=function(a){return!/[^a-zA-Z0-9]/.test(a)};goog.string.isSpace=function(a){return" "==a};goog.string.isUnicodeChar=function(a){return 1==a.length&&" "<=a&&"~">=a||"\u0080"<=a&&"\ufffd">=a};goog.string.stripNewlines=function(a){return a.replace(/(\r\n|\r|\n)+/g," ")};goog.string.canonicalizeNewlines=function(a){return a.replace(/(\r\n|\r|\n)/g,"\n")};
                +goog.string.normalizeWhitespace=function(a){return a.replace(/\xa0|\s/g," ")};goog.string.normalizeSpaces=function(a){return a.replace(/\xa0|[ \t]+/g," ")};goog.string.collapseBreakingSpaces=function(a){return a.replace(/[\t\r\n ]+/g," ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g,"")};goog.string.trim=goog.TRUSTED_SITE&&String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};goog.string.trimLeft=function(a){return a.replace(/^[\s\xa0]+/,"")};
                +goog.string.trimRight=function(a){return a.replace(/[\s\xa0]+$/,"")};goog.string.caseInsensitiveCompare=function(a,b){a=String(a).toLowerCase();b=String(b).toLowerCase();return a<b?-1:a==b?0:1};
                +goog.string.numberAwareCompare_=function(a,b,c){if(a==b)return 0;if(!a)return-1;if(!b)return 1;for(var d=a.toLowerCase().match(c),e=b.toLowerCase().match(c),f=Math.min(d.length,e.length),g=0;g<f;g++){c=d[g];var h=e[g];if(c!=h)return a=parseInt(c,10),!isNaN(a)&&(b=parseInt(h,10),!isNaN(b)&&a-b)?a-b:c<h?-1:1}return d.length!=e.length?d.length-e.length:a<b?-1:1};goog.string.intAwareCompare=function(a,b){return goog.string.numberAwareCompare_(a,b,/\d+|\D+/g)};
                +goog.string.floatAwareCompare=function(a,b){return goog.string.numberAwareCompare_(a,b,/\d+|\.\d+|\D+/g)};goog.string.numerateCompare=goog.string.floatAwareCompare;goog.string.urlEncode=function(a){return encodeURIComponent(String(a))};goog.string.urlDecode=function(a){return decodeURIComponent(a.replace(/\+/g," "))};goog.string.newLineToBr=function(a,b){return a.replace(/(\r\n|\r|\n)/g,b?"<br />":"<br>")};
                +goog.string.htmlEscape=function(a,b){if(b)a=a.replace(goog.string.AMP_RE_,"&amp;").replace(goog.string.LT_RE_,"&lt;").replace(goog.string.GT_RE_,"&gt;").replace(goog.string.QUOT_RE_,"&quot;").replace(goog.string.SINGLE_QUOTE_RE_,"&#39;").replace(goog.string.NULL_RE_,"&#0;"),goog.string.DETECT_DOUBLE_ESCAPING&&(a=a.replace(goog.string.E_RE_,"&#101;"));else{if(!goog.string.ALL_RE_.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(goog.string.AMP_RE_,"&amp;"));-1!=a.indexOf("<")&&(a=a.replace(goog.string.LT_RE_,
                +"&lt;"));-1!=a.indexOf(">")&&(a=a.replace(goog.string.GT_RE_,"&gt;"));-1!=a.indexOf('"')&&(a=a.replace(goog.string.QUOT_RE_,"&quot;"));-1!=a.indexOf("'")&&(a=a.replace(goog.string.SINGLE_QUOTE_RE_,"&#39;"));-1!=a.indexOf("\x00")&&(a=a.replace(goog.string.NULL_RE_,"&#0;"));goog.string.DETECT_DOUBLE_ESCAPING&&-1!=a.indexOf("e")&&(a=a.replace(goog.string.E_RE_,"&#101;"))}return a};goog.string.AMP_RE_=/&/g;goog.string.LT_RE_=/</g;goog.string.GT_RE_=/>/g;goog.string.QUOT_RE_=/"/g;
                +goog.string.SINGLE_QUOTE_RE_=/'/g;goog.string.NULL_RE_=/\x00/g;goog.string.E_RE_=/e/g;goog.string.ALL_RE_=goog.string.DETECT_DOUBLE_ESCAPING?/[\x00&<>"'e]/:/[\x00&<>"']/;goog.string.unescapeEntities=function(a){return goog.string.contains(a,"&")?!goog.string.FORCE_NON_DOM_HTML_UNESCAPING&&"document"in goog.global?goog.string.unescapeEntitiesUsingDom_(a):goog.string.unescapePureXmlEntities_(a):a};
                +goog.string.unescapeEntitiesWithDocument=function(a,b){return goog.string.contains(a,"&")?goog.string.unescapeEntitiesUsingDom_(a,b):a};
                +goog.string.unescapeEntitiesUsingDom_=function(a,b){var c={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"'};var d=b?b.createElement("div"):goog.global.document.createElement("div");return a.replace(goog.string.HTML_ENTITY_PATTERN_,function(a,b){var e=c[a];if(e)return e;"#"==b.charAt(0)&&(b=Number("0"+b.substr(1)),isNaN(b)||(e=String.fromCharCode(b)));e||(d.innerHTML=a+" ",e=d.firstChild.nodeValue.slice(0,-1));return c[a]=e})};
                +goog.string.unescapePureXmlEntities_=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:return"#"!=c.charAt(0)||(c=Number("0"+c.substr(1)),isNaN(c))?a:String.fromCharCode(c)}})};goog.string.HTML_ENTITY_PATTERN_=/&([^;\s<&]+);?/g;goog.string.whitespaceEscape=function(a,b){return goog.string.newLineToBr(a.replace(/  /g," &#160;"),b)};
                +goog.string.preserveSpaces=function(a){return a.replace(/(^|[\n ]) /g,"$1"+goog.string.Unicode.NBSP)};goog.string.stripQuotes=function(a,b){for(var c=b.length,d=0;d<c;d++){var e=1==c?b:b.charAt(d);if(a.charAt(0)==e&&a.charAt(a.length-1)==e)return a.substring(1,a.length-1)}return a};goog.string.truncate=function(a,b,c){c&&(a=goog.string.unescapeEntities(a));a.length>b&&(a=a.substring(0,b-3)+"...");c&&(a=goog.string.htmlEscape(a));return a};
                +goog.string.truncateMiddle=function(a,b,c,d){c&&(a=goog.string.unescapeEntities(a));if(d&&a.length>b){d>b&&(d=b);var e=a.length-d;a=a.substring(0,b-d)+"..."+a.substring(e)}else a.length>b&&(d=Math.floor(b/2),e=a.length-d,a=a.substring(0,d+b%2)+"..."+a.substring(e));c&&(a=goog.string.htmlEscape(a));return a};goog.string.specialEscapeChars_={"\x00":"\\0","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\x0B",'"':'\\"',"\\":"\\\\","<":"<"};goog.string.jsEscapeCache_={"'":"\\'"};
                +goog.string.quote=function(a){a=String(a);for(var b=['"'],c=0;c<a.length;c++){var d=a.charAt(c),e=d.charCodeAt(0);b[c+1]=goog.string.specialEscapeChars_[d]||(31<e&&127>e?d:goog.string.escapeChar(d))}b.push('"');return b.join("")};goog.string.escapeString=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=goog.string.escapeChar(a.charAt(c));return b.join("")};
                +goog.string.escapeChar=function(a){if(a in goog.string.jsEscapeCache_)return goog.string.jsEscapeCache_[a];if(a in goog.string.specialEscapeChars_)return goog.string.jsEscapeCache_[a]=goog.string.specialEscapeChars_[a];var b=a.charCodeAt(0);if(31<b&&127>b)var c=a;else{if(256>b){if(c="\\x",16>b||256<b)c+="0"}else c="\\u",4096>b&&(c+="0");c+=b.toString(16).toUpperCase()}return goog.string.jsEscapeCache_[a]=c};goog.string.contains=function(a,b){return-1!=a.indexOf(b)};
                +goog.string.caseInsensitiveContains=function(a,b){return goog.string.contains(a.toLowerCase(),b.toLowerCase())};goog.string.countOf=function(a,b){return a&&b?a.split(b).length-1:0};goog.string.removeAt=function(a,b,c){var d=a;0<=b&&b<a.length&&0<c&&(d=a.substr(0,b)+a.substr(b+c,a.length-b-c));return d};goog.string.remove=function(a,b){return a.replace(b,"")};goog.string.removeAll=function(a,b){b=new RegExp(goog.string.regExpEscape(b),"g");return a.replace(b,"")};
                +goog.string.replaceAll=function(a,b,c){b=new RegExp(goog.string.regExpEscape(b),"g");return a.replace(b,c.replace(/\$/g,"$$$$"))};goog.string.regExpEscape=function(a){return String(a).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")};goog.string.repeat=String.prototype.repeat?function(a,b){return a.repeat(b)}:function(a,b){return Array(b+1).join(a)};
                +goog.string.padNumber=function(a,b,c){a=goog.isDef(c)?a.toFixed(c):String(a);c=a.indexOf(".");-1==c&&(c=a.length);return goog.string.repeat("0",Math.max(0,b-c))+a};goog.string.makeSafe=function(a){return null==a?"":String(a)};goog.string.buildString=function(a){return Array.prototype.join.call(arguments,"")};goog.string.getRandomString=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^goog.now()).toString(36)};
                +goog.string.compareVersions=function(a,b){var c=0;a=goog.string.trim(String(a)).split(".");b=goog.string.trim(String(b)).split(".");for(var d=Math.max(a.length,b.length),e=0;0==c&&e<d;e++){var f=a[e]||"",g=b[e]||"";do{f=/(\d*)(\D*)(.*)/.exec(f)||["","","",""];g=/(\d*)(\D*)(.*)/.exec(g)||["","","",""];if(0==f[0].length&&0==g[0].length)break;var c=0==f[1].length?0:parseInt(f[1],10),h=0==g[1].length?0:parseInt(g[1],10),c=goog.string.compareElements_(c,h)||goog.string.compareElements_(0==f[2].length,
                +0==g[2].length)||goog.string.compareElements_(f[2],g[2]),f=f[3],g=g[3]}while(0==c)}return c};goog.string.compareElements_=function(a,b){return a<b?-1:a>b?1:0};goog.string.hashCode=function(a){for(var b=0,c=0;c<a.length;++c)b=31*b+a.charCodeAt(c)>>>0;return b};goog.string.uniqueStringCounter_=2147483648*Math.random()|0;goog.string.createUniqueString=function(){return"goog_"+goog.string.uniqueStringCounter_++};
                +goog.string.toNumber=function(a){var b=Number(a);return 0==b&&goog.string.isEmptyOrWhitespace(a)?NaN:b};goog.string.isLowerCamelCase=function(a){return/^[a-z]+([A-Z][a-z]*)*$/.test(a)};goog.string.isUpperCamelCase=function(a){return/^([A-Z][a-z]*)+$/.test(a)};goog.string.toCamelCase=function(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};goog.string.toSelectorCase=function(a){return String(a).replace(/([A-Z])/g,"-$1").toLowerCase()};
                +goog.string.toTitleCase=function(a,b){b=goog.isString(b)?goog.string.regExpEscape(b):"\\s";return a.replace(new RegExp("(^"+(b?"|["+b+"]+":"")+")([a-z])","g"),function(a,b,e){return b+e.toUpperCase()})};goog.string.capitalize=function(a){return String(a.charAt(0)).toUpperCase()+String(a.substr(1)).toLowerCase()};goog.string.parseInt=function(a){isFinite(a)&&(a=String(a));return goog.isString(a)?/^\s*-?0x/i.test(a)?parseInt(a,16):parseInt(a,10):NaN};
                +goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.length;)d.push(a.shift()),c--;a.length&&d.push(a.join(b));return d};goog.string.lastComponent=function(a,b){if(b)"string"==typeof b&&(b=[b]);else return a;for(var c=-1,d=0;d<b.length;d++)if(""!=b[d]){var e=a.lastIndexOf(b[d]);e>c&&(c=e)}return-1==c?a:a.slice(c+1)};
                +goog.string.editDistance=function(a,b){var c=[],d=[];if(a==b)return 0;if(!a.length||!b.length)return Math.max(a.length,b.length);for(var e=0;e<b.length+1;e++)c[e]=e;for(e=0;e<a.length;e++){d[0]=e+1;for(var f=0;f<b.length;f++)d[f+1]=Math.min(d[f]+1,c[f+1]+1,c[f]+Number(a[e]!=b[f]));for(f=0;f<c.length;f++)c[f]=d[f]}return d[b.length]};goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){b.unshift(a);goog.debug.Error.call(this,goog.string.subs.apply(null,b));b.shift();this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
                +goog.asserts.doAssertFailure_=function(a,b,c,d){var e="Assertion failed";if(c){e+=": "+c;var f=d}else a&&(e+=": "+a,f=b);a=new goog.asserts.AssertionError(""+e,f||[]);goog.asserts.errorHandler_(a)};goog.asserts.setErrorHandler=function(a){goog.asserts.ENABLE_ASSERTS&&(goog.asserts.errorHandler_=a)};goog.asserts.assert=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!a&&goog.asserts.doAssertFailure_("",null,b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.fail=function(a,b){goog.asserts.ENABLE_ASSERTS&&goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1)))};goog.asserts.assertNumber=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isNumber(a)&&goog.asserts.doAssertFailure_("Expected number but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertString=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isString(a)&&goog.asserts.doAssertFailure_("Expected string but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertFunction=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isFunction(a)&&goog.asserts.doAssertFailure_("Expected function but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertObject=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isObject(a)&&goog.asserts.doAssertFailure_("Expected object but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertArray=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isArray(a)&&goog.asserts.doAssertFailure_("Expected array but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertBoolean=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isBoolean(a)&&goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertElement=function(a,b,c){!goog.asserts.ENABLE_ASSERTS||goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT||goog.asserts.doAssertFailure_("Expected Element but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertInstanceof=function(a,b,c,d){!goog.asserts.ENABLE_ASSERTS||a instanceof b||goog.asserts.doAssertFailure_("Expected instanceof %s but got %s.",[goog.asserts.getType_(b),goog.asserts.getType_(a)],c,Array.prototype.slice.call(arguments,3));return a};goog.asserts.assertObjectPrototypeIsIntact=function(){for(var a in Object.prototype)goog.asserts.fail(a+" should not be enumerable in Object.prototype.")};
                +goog.asserts.getType_=function(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};goog.debug.entryPointRegistry={};goog.debug.EntryPointMonitor=function(){};goog.debug.entryPointRegistry.refList_=[];goog.debug.entryPointRegistry.monitors_=[];goog.debug.entryPointRegistry.monitorsMayExist_=!1;goog.debug.entryPointRegistry.register=function(a){goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length]=a;if(goog.debug.entryPointRegistry.monitorsMayExist_)for(var b=goog.debug.entryPointRegistry.monitors_,c=0;c<b.length;c++)a(goog.bind(b[c].wrap,b[c]))};
                +goog.debug.entryPointRegistry.monitorAll=function(a){goog.debug.entryPointRegistry.monitorsMayExist_=!0;for(var b=goog.bind(a.wrap,a),c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](b);goog.debug.entryPointRegistry.monitors_.push(a)};
                +goog.debug.entryPointRegistry.unmonitorAllIfPossible=function(a){var b=goog.debug.entryPointRegistry.monitors_;goog.asserts.assert(a==b[b.length-1],"Only the most recent monitor can be unwrapped.");a=goog.bind(a.unwrap,a);for(var c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](a);b.length--};goog.array={};goog.NATIVE_ARRAY_PROTOTYPES=goog.TRUSTED_SITE;goog.array.ASSUME_NATIVE_FUNCTIONS=!1;goog.array.peek=function(a){return a[a.length-1]};goog.array.last=goog.array.peek;
                +goog.array.indexOf=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.indexOf)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(goog.isString(a))return goog.isString(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};
                +goog.array.lastIndexOf=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.lastIndexOf)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.lastIndexOf.call(a,b,null==c?a.length-1:c)}:function(a,b,c){c=null==c?a.length-1:c;0>c&&(c=Math.max(0,a.length+c));if(goog.isString(a))return goog.isString(b)&&1==b.length?a.lastIndexOf(b,c):-1;for(;0<=c;c--)if(c in a&&a[c]===b)return c;return-1};
                +goog.array.forEach=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.forEach)?function(a,b,c){goog.asserts.assert(null!=a.length);Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)};goog.array.forEachRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;--d)d in e&&b.call(c,e[d],d,a)};
                +goog.array.filter=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.filter)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=goog.isString(a)?a.split(""):a,h=0;h<d;h++)if(h in g){var k=g[h];b.call(c,k,h,a)&&(e[f++]=k)}return e};
                +goog.array.map=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.map)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=goog.isString(a)?a.split(""):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e};
                +goog.array.reduce=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.reduce)?function(a,b,c,d){goog.asserts.assert(null!=a.length);d&&(b=goog.bind(b,d));return Array.prototype.reduce.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEach(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
                +goog.array.reduceRight=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.reduceRight)?function(a,b,c,d){goog.asserts.assert(null!=a.length);goog.asserts.assert(null!=b);d&&(b=goog.bind(b,d));return Array.prototype.reduceRight.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEachRight(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
                +goog.array.some=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.some)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1};
                +goog.array.every=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.every)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0};goog.array.count=function(a,b,c){var d=0;goog.array.forEach(a,function(a,f,g){b.call(c,a,f,g)&&++d},c);return d};
                +goog.array.find=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};goog.array.findIndex=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return f;return-1};goog.array.findRight=function(a,b,c){b=goog.array.findIndexRight(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};
                +goog.array.findIndexRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;d--)if(d in e&&b.call(c,e[d],d,a))return d;return-1};goog.array.contains=function(a,b){return 0<=goog.array.indexOf(a,b)};goog.array.isEmpty=function(a){return 0==a.length};goog.array.clear=function(a){if(!goog.isArray(a))for(var b=a.length-1;0<=b;b--)delete a[b];a.length=0};goog.array.insert=function(a,b){goog.array.contains(a,b)||a.push(b)};
                +goog.array.insertAt=function(a,b,c){goog.array.splice(a,c,0,b)};goog.array.insertArrayAt=function(a,b,c){goog.partial(goog.array.splice,a,c,0).apply(null,b)};goog.array.insertBefore=function(a,b,c){var d;2==arguments.length||0>(d=goog.array.indexOf(a,c))?a.push(b):goog.array.insertAt(a,b,d)};goog.array.remove=function(a,b){b=goog.array.indexOf(a,b);var c;(c=0<=b)&&goog.array.removeAt(a,b);return c};
                +goog.array.removeLast=function(a,b){b=goog.array.lastIndexOf(a,b);return 0<=b?(goog.array.removeAt(a,b),!0):!1};goog.array.removeAt=function(a,b){goog.asserts.assert(null!=a.length);return 1==Array.prototype.splice.call(a,b,1).length};goog.array.removeIf=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0<=b?(goog.array.removeAt(a,b),!0):!1};goog.array.removeAllIf=function(a,b,c){var d=0;goog.array.forEachRight(a,function(e,f){b.call(c,e,f,a)&&goog.array.removeAt(a,f)&&d++});return d};
                +goog.array.concat=function(a){return Array.prototype.concat.apply([],arguments)};goog.array.join=function(a){return Array.prototype.concat.apply([],arguments)};goog.array.toArray=function(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};goog.array.clone=goog.array.toArray;goog.array.extend=function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(goog.isArrayLike(d)){var e=a.length||0,f=d.length||0;a.length=e+f;for(var g=0;g<f;g++)a[e+g]=d[g]}else a.push(d)}};
                +goog.array.splice=function(a,b,c,d){goog.asserts.assert(null!=a.length);return Array.prototype.splice.apply(a,goog.array.slice(arguments,1))};goog.array.slice=function(a,b,c){goog.asserts.assert(null!=a.length);return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};
                +goog.array.removeDuplicates=function(a,b,c){b=b||a;var d=function(a){return goog.isObject(a)?"o"+goog.getUid(a):(typeof a).charAt(0)+a};c=c||d;for(var d={},e=0,f=0;f<a.length;){var g=a[f++],h=c(g);Object.prototype.hasOwnProperty.call(d,h)||(d[h]=!0,b[e++]=g)}b.length=e};goog.array.binarySearch=function(a,b,c){return goog.array.binarySearch_(a,c||goog.array.defaultCompare,!1,b)};goog.array.binarySelect=function(a,b,c){return goog.array.binarySearch_(a,b,!0,void 0,c)};
                +goog.array.binarySearch_=function(a,b,c,d,e){for(var f=0,g=a.length,h;f<g;){var k=f+g>>1;var l=c?b.call(e,a[k],k,a):b(d,a[k]);0<l?f=k+1:(g=k,h=!l)}return h?f:~f};goog.array.sort=function(a,b){a.sort(b||goog.array.defaultCompare)};goog.array.stableSort=function(a,b){for(var c=Array(a.length),d=0;d<a.length;d++)c[d]={index:d,value:a[d]};var e=b||goog.array.defaultCompare;goog.array.sort(c,function(a,b){return e(a.value,b.value)||a.index-b.index});for(d=0;d<a.length;d++)a[d]=c[d].value};
                +goog.array.sortByKey=function(a,b,c){var d=c||goog.array.defaultCompare;goog.array.sort(a,function(a,c){return d(b(a),b(c))})};goog.array.sortObjectsByKey=function(a,b,c){goog.array.sortByKey(a,function(a){return a[b]},c)};goog.array.isSorted=function(a,b,c){b=b||goog.array.defaultCompare;for(var d=1;d<a.length;d++){var e=b(a[d-1],a[d]);if(0<e||0==e&&c)return!1}return!0};
                +goog.array.equals=function(a,b,c){if(!goog.isArrayLike(a)||!goog.isArrayLike(b)||a.length!=b.length)return!1;var d=a.length;c=c||goog.array.defaultCompareEquality;for(var e=0;e<d;e++)if(!c(a[e],b[e]))return!1;return!0};goog.array.compare3=function(a,b,c){c=c||goog.array.defaultCompare;for(var d=Math.min(a.length,b.length),e=0;e<d;e++){var f=c(a[e],b[e]);if(0!=f)return f}return goog.array.defaultCompare(a.length,b.length)};goog.array.defaultCompare=function(a,b){return a>b?1:a<b?-1:0};
                +goog.array.inverseDefaultCompare=function(a,b){return-goog.array.defaultCompare(a,b)};goog.array.defaultCompareEquality=function(a,b){return a===b};goog.array.binaryInsert=function(a,b,c){c=goog.array.binarySearch(a,b,c);return 0>c?(goog.array.insertAt(a,b,-(c+1)),!0):!1};goog.array.binaryRemove=function(a,b,c){b=goog.array.binarySearch(a,b,c);return 0<=b?goog.array.removeAt(a,b):!1};
                +goog.array.bucket=function(a,b,c){for(var d={},e=0;e<a.length;e++){var f=a[e],g=b.call(c,f,e,a);goog.isDef(g)&&(d[g]||(d[g]=[])).push(f)}return d};goog.array.toObject=function(a,b,c){var d={};goog.array.forEach(a,function(e,f){d[b.call(c,e,f,a)]=e});return d};goog.array.range=function(a,b,c){var d=[],e=0,f=a;c=c||1;void 0!==b&&(e=a,f=b);if(0>c*(f-e))return[];if(0<c)for(a=e;a<f;a+=c)d.push(a);else for(a=e;a>f;a+=c)d.push(a);return d};
                +goog.array.repeat=function(a,b){for(var c=[],d=0;d<b;d++)c[d]=a;return c};goog.array.flatten=function(a){for(var b=[],c=0;c<arguments.length;c++){var d=arguments[c];if(goog.isArray(d))for(var e=0;e<d.length;e+=8192)for(var f=goog.array.slice(d,e,e+8192),f=goog.array.flatten.apply(null,f),g=0;g<f.length;g++)b.push(f[g]);else b.push(d)}return b};
                +goog.array.rotate=function(a,b){goog.asserts.assert(null!=a.length);a.length&&(b%=a.length,0<b?Array.prototype.unshift.apply(a,a.splice(-b,b)):0>b&&Array.prototype.push.apply(a,a.splice(0,-b)));return a};goog.array.moveItem=function(a,b,c){goog.asserts.assert(0<=b&&b<a.length);goog.asserts.assert(0<=c&&c<a.length);b=Array.prototype.splice.call(a,b,1);Array.prototype.splice.call(a,c,0,b[0])};
                +goog.array.zip=function(a){if(!arguments.length)return[];for(var b=[],c=arguments[0].length,d=1;d<arguments.length;d++)arguments[d].length<c&&(c=arguments[d].length);for(d=0;d<c;d++){for(var e=[],f=0;f<arguments.length;f++)e.push(arguments[f][d]);b.push(e)}return b};goog.array.shuffle=function(a,b){b=b||Math.random;for(var c=a.length-1;0<c;c--){var d=Math.floor(b()*(c+1)),e=a[c];a[c]=a[d];a[d]=e}};goog.array.copyByIndex=function(a,b){var c=[];goog.array.forEach(b,function(b){c.push(a[b])});return c};
                +goog.array.concatMap=function(a,b,c){return goog.array.concat.apply([],goog.array.map(a,b,c))};goog.labs={};goog.labs.userAgent={};goog.labs.userAgent.util={};goog.labs.userAgent.util.getNativeUserAgentString_=function(){var a=goog.labs.userAgent.util.getNavigator_();return a&&(a=a.userAgent)?a:""};goog.labs.userAgent.util.getNavigator_=function(){return goog.global.navigator};goog.labs.userAgent.util.userAgent_=goog.labs.userAgent.util.getNativeUserAgentString_();goog.labs.userAgent.util.setUserAgent=function(a){goog.labs.userAgent.util.userAgent_=a||goog.labs.userAgent.util.getNativeUserAgentString_()};
                +goog.labs.userAgent.util.getUserAgent=function(){return goog.labs.userAgent.util.userAgent_};goog.labs.userAgent.util.matchUserAgent=function(a){var b=goog.labs.userAgent.util.getUserAgent();return goog.string.contains(b,a)};goog.labs.userAgent.util.matchUserAgentIgnoreCase=function(a){var b=goog.labs.userAgent.util.getUserAgent();return goog.string.caseInsensitiveContains(b,a)};
                +goog.labs.userAgent.util.extractVersionTuples=function(a){for(var b=/(\w[\w ]+)\/([^\s]+)\s*(?:\((.*?)\))?/g,c=[],d;d=b.exec(a);)c.push([d[1],d[2],d[3]||void 0]);return c};goog.object={};goog.object.is=function(a,b){return a===b?0!==a||1/a===1/b:a!==a&&b!==b};goog.object.forEach=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)};goog.object.filter=function(a,b,c){var d={},e;for(e in a)b.call(c,a[e],e,a)&&(d[e]=a[e]);return d};goog.object.map=function(a,b,c){var d={},e;for(e in a)d[e]=b.call(c,a[e],e,a);return d};goog.object.some=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return!0;return!1};
                +goog.object.every=function(a,b,c){for(var d in a)if(!b.call(c,a[d],d,a))return!1;return!0};goog.object.getCount=function(a){var b=0,c;for(c in a)b++;return b};goog.object.getAnyKey=function(a){for(var b in a)return b};goog.object.getAnyValue=function(a){for(var b in a)return a[b]};goog.object.contains=function(a,b){return goog.object.containsValue(a,b)};goog.object.getValues=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};
                +goog.object.getKeys=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};goog.object.getValueByKeys=function(a,b){for(var c=goog.isArrayLike(b),d=c?b:arguments,c=c?0:1;c<d.length&&(a=a[d[c]],goog.isDef(a));c++);return a};goog.object.containsKey=function(a,b){return null!==a&&b in a};goog.object.containsValue=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};goog.object.findKey=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};
                +goog.object.findValue=function(a,b,c){return(b=goog.object.findKey(a,b,c))&&a[b]};goog.object.isEmpty=function(a){for(var b in a)return!1;return!0};goog.object.clear=function(a){for(var b in a)delete a[b]};goog.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};goog.object.add=function(a,b,c){if(null!==a&&b in a)throw Error('The object already contains the key "'+b+'"');goog.object.set(a,b,c)};goog.object.get=function(a,b,c){return null!==a&&b in a?a[b]:c};
                +goog.object.set=function(a,b,c){a[b]=c};goog.object.setIfUndefined=function(a,b,c){return b in a?a[b]:a[b]=c};goog.object.setWithReturnValueIfNotSet=function(a,b,c){if(b in a)return a[b];c=c();return a[b]=c};goog.object.equals=function(a,b){for(var c in a)if(!(c in b)||a[c]!==b[c])return!1;for(c in b)if(!(c in a))return!1;return!0};goog.object.clone=function(a){var b={},c;for(c in a)b[c]=a[c];return b};
                +goog.object.unsafeClone=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if(goog.isFunction(a.clone))return a.clone();var b="array"==b?[]:{},c;for(c in a)b[c]=goog.object.unsafeClone(a[c]);return b}return a};goog.object.transpose=function(a){var b={},c;for(c in a)b[a[c]]=c;return b};goog.object.PROTOTYPE_FIELDS_="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
                +goog.object.extend=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<goog.object.PROTOTYPE_FIELDS_.length;f++)c=goog.object.PROTOTYPE_FIELDS_[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};
                +goog.object.create=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.create.apply(null,arguments[0]);if(b%2)throw Error("Uneven number of arguments");for(var c={},d=0;d<b;d+=2)c[arguments[d]]=arguments[d+1];return c};goog.object.createSet=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.createSet.apply(null,arguments[0]);for(var c={},d=0;d<b;d++)c[arguments[d]]=!0;return c};
                +goog.object.createImmutableView=function(a){var b=a;Object.isFrozen&&!Object.isFrozen(a)&&(b=Object.create(a),Object.freeze(b));return b};goog.object.isImmutableView=function(a){return!!Object.isFrozen&&Object.isFrozen(a)};
                +goog.object.getAllPropertyNames=function(a,b,c){if(!a)return[];if(!Object.getOwnPropertyNames||!Object.getPrototypeOf)return goog.object.getKeys(a);for(var d={};a&&(a!==Object.prototype||b)&&(a!==Function.prototype||c);){for(var e=Object.getOwnPropertyNames(a),f=0;f<e.length;f++)d[e[f]]=!0;a=Object.getPrototypeOf(a)}return goog.object.getKeys(d)};goog.labs.userAgent.browser={};goog.labs.userAgent.browser.matchOpera_=function(){return goog.labs.userAgent.util.matchUserAgent("Opera")};goog.labs.userAgent.browser.matchIE_=function(){return goog.labs.userAgent.util.matchUserAgent("Trident")||goog.labs.userAgent.util.matchUserAgent("MSIE")};goog.labs.userAgent.browser.matchEdge_=function(){return goog.labs.userAgent.util.matchUserAgent("Edge")};goog.labs.userAgent.browser.matchFirefox_=function(){return goog.labs.userAgent.util.matchUserAgent("Firefox")};
                +goog.labs.userAgent.browser.matchSafari_=function(){return goog.labs.userAgent.util.matchUserAgent("Safari")&&!(goog.labs.userAgent.browser.matchChrome_()||goog.labs.userAgent.browser.matchCoast_()||goog.labs.userAgent.browser.matchOpera_()||goog.labs.userAgent.browser.matchEdge_()||goog.labs.userAgent.browser.isSilk()||goog.labs.userAgent.util.matchUserAgent("Android"))};goog.labs.userAgent.browser.matchCoast_=function(){return goog.labs.userAgent.util.matchUserAgent("Coast")};
                +goog.labs.userAgent.browser.matchIosWebview_=function(){return(goog.labs.userAgent.util.matchUserAgent("iPad")||goog.labs.userAgent.util.matchUserAgent("iPhone"))&&!goog.labs.userAgent.browser.matchSafari_()&&!goog.labs.userAgent.browser.matchChrome_()&&!goog.labs.userAgent.browser.matchCoast_()&&goog.labs.userAgent.util.matchUserAgent("AppleWebKit")};
                +goog.labs.userAgent.browser.matchChrome_=function(){return(goog.labs.userAgent.util.matchUserAgent("Chrome")||goog.labs.userAgent.util.matchUserAgent("CriOS"))&&!goog.labs.userAgent.browser.matchEdge_()};goog.labs.userAgent.browser.matchAndroidBrowser_=function(){return goog.labs.userAgent.util.matchUserAgent("Android")&&!(goog.labs.userAgent.browser.isChrome()||goog.labs.userAgent.browser.isFirefox()||goog.labs.userAgent.browser.isOpera()||goog.labs.userAgent.browser.isSilk())};
                +goog.labs.userAgent.browser.isOpera=goog.labs.userAgent.browser.matchOpera_;goog.labs.userAgent.browser.isIE=goog.labs.userAgent.browser.matchIE_;goog.labs.userAgent.browser.isEdge=goog.labs.userAgent.browser.matchEdge_;goog.labs.userAgent.browser.isFirefox=goog.labs.userAgent.browser.matchFirefox_;goog.labs.userAgent.browser.isSafari=goog.labs.userAgent.browser.matchSafari_;goog.labs.userAgent.browser.isCoast=goog.labs.userAgent.browser.matchCoast_;goog.labs.userAgent.browser.isIosWebview=goog.labs.userAgent.browser.matchIosWebview_;
                +goog.labs.userAgent.browser.isChrome=goog.labs.userAgent.browser.matchChrome_;goog.labs.userAgent.browser.isAndroidBrowser=goog.labs.userAgent.browser.matchAndroidBrowser_;goog.labs.userAgent.browser.isSilk=function(){return goog.labs.userAgent.util.matchUserAgent("Silk")};
                +goog.labs.userAgent.browser.getVersion=function(){function a(a){a=goog.array.find(a,d);return c[a]||""}var b=goog.labs.userAgent.util.getUserAgent();if(goog.labs.userAgent.browser.isIE())return goog.labs.userAgent.browser.getIEVersion_(b);var b=goog.labs.userAgent.util.extractVersionTuples(b),c={};goog.array.forEach(b,function(a){c[a[0]]=a[1]});var d=goog.partial(goog.object.containsKey,c);return goog.labs.userAgent.browser.isOpera()?a(["Version","Opera"]):goog.labs.userAgent.browser.isEdge()?a(["Edge"]):
                +goog.labs.userAgent.browser.isChrome()?a(["Chrome","CriOS"]):(b=b[2])&&b[1]||""};goog.labs.userAgent.browser.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(),a)};
                +goog.labs.userAgent.browser.getIEVersion_=function(a){var b=/rv: *([\d\.]*)/.exec(a);if(b&&b[1])return b[1];var b="",c=/MSIE +([\d\.]+)/.exec(a);if(c&&c[1])if(a=/Trident\/(\d.\d)/.exec(a),"7.0"==c[1])if(a&&a[1])switch(a[1]){case "4.0":b="8.0";break;case "5.0":b="9.0";break;case "6.0":b="10.0";break;case "7.0":b="11.0"}else b="7.0";else b=c[1];return b};goog.labs.userAgent.engine={};goog.labs.userAgent.engine.isPresto=function(){return goog.labs.userAgent.util.matchUserAgent("Presto")};goog.labs.userAgent.engine.isTrident=function(){return goog.labs.userAgent.util.matchUserAgent("Trident")||goog.labs.userAgent.util.matchUserAgent("MSIE")};goog.labs.userAgent.engine.isEdge=function(){return goog.labs.userAgent.util.matchUserAgent("Edge")};
                +goog.labs.userAgent.engine.isWebKit=function(){return goog.labs.userAgent.util.matchUserAgentIgnoreCase("WebKit")&&!goog.labs.userAgent.engine.isEdge()};goog.labs.userAgent.engine.isGecko=function(){return goog.labs.userAgent.util.matchUserAgent("Gecko")&&!goog.labs.userAgent.engine.isWebKit()&&!goog.labs.userAgent.engine.isTrident()&&!goog.labs.userAgent.engine.isEdge()};
                +goog.labs.userAgent.engine.getVersion=function(){var a=goog.labs.userAgent.util.getUserAgent();if(a){var a=goog.labs.userAgent.util.extractVersionTuples(a),b=goog.labs.userAgent.engine.getEngineTuple_(a);if(b)return"Gecko"==b[0]?goog.labs.userAgent.engine.getVersionForKey_(a,"Firefox"):b[1];var a=a[0],c;if(a&&(c=a[2])&&(c=/Trident\/([^\s;]+)/.exec(c)))return c[1]}return""};
                +goog.labs.userAgent.engine.getEngineTuple_=function(a){if(!goog.labs.userAgent.engine.isEdge())return a[1];for(var b=0;b<a.length;b++){var c=a[b];if("Edge"==c[0])return c}};goog.labs.userAgent.engine.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(),a)};goog.labs.userAgent.engine.getVersionForKey_=function(a,b){return(a=goog.array.find(a,function(a){return b==a[0]}))&&a[1]||""};goog.labs.userAgent.platform={};goog.labs.userAgent.platform.isAndroid=function(){return goog.labs.userAgent.util.matchUserAgent("Android")};goog.labs.userAgent.platform.isIpod=function(){return goog.labs.userAgent.util.matchUserAgent("iPod")};goog.labs.userAgent.platform.isIphone=function(){return goog.labs.userAgent.util.matchUserAgent("iPhone")&&!goog.labs.userAgent.util.matchUserAgent("iPod")&&!goog.labs.userAgent.util.matchUserAgent("iPad")};goog.labs.userAgent.platform.isIpad=function(){return goog.labs.userAgent.util.matchUserAgent("iPad")};
                +goog.labs.userAgent.platform.isIos=function(){return goog.labs.userAgent.platform.isIphone()||goog.labs.userAgent.platform.isIpad()||goog.labs.userAgent.platform.isIpod()};goog.labs.userAgent.platform.isMacintosh=function(){return goog.labs.userAgent.util.matchUserAgent("Macintosh")};goog.labs.userAgent.platform.isLinux=function(){return goog.labs.userAgent.util.matchUserAgent("Linux")};goog.labs.userAgent.platform.isWindows=function(){return goog.labs.userAgent.util.matchUserAgent("Windows")};
                +goog.labs.userAgent.platform.isChromeOS=function(){return goog.labs.userAgent.util.matchUserAgent("CrOS")};
                +goog.labs.userAgent.platform.getVersion=function(){var a=goog.labs.userAgent.util.getUserAgent();var b="";goog.labs.userAgent.platform.isWindows()?(b=/Windows (?:NT|Phone) ([0-9.]+)/,b=(a=b.exec(a))?a[1]:"0.0"):goog.labs.userAgent.platform.isIos()?(b=/(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/,b=(a=b.exec(a))&&a[1].replace(/_/g,".")):goog.labs.userAgent.platform.isMacintosh()?(b=/Mac OS X ([0-9_.]+)/,b=(a=b.exec(a))?a[1].replace(/_/g,"."):"10"):goog.labs.userAgent.platform.isAndroid()?(b=/Android\s+([^\);]+)(\)|;)/,
                +b=(a=b.exec(a))&&a[1]):goog.labs.userAgent.platform.isChromeOS()&&(b=/(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/,b=(a=b.exec(a))&&a[1]);return b||""};goog.labs.userAgent.platform.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.platform.getVersion(),a)};goog.reflect={};goog.reflect.object=function(a,b){return b};goog.reflect.objectProperty=function(a,b){return a};goog.reflect.sinkValue=function(a){goog.reflect.sinkValue[" "](a);return a};goog.reflect.sinkValue[" "]=goog.nullFunction;goog.reflect.canAccessProperty=function(a,b){try{return goog.reflect.sinkValue(a[b]),!0}catch(c){}return!1};goog.reflect.cache=function(a,b,c,d){d=d?d(b):b;return Object.prototype.hasOwnProperty.call(a,d)?a[d]:a[d]=c(b)};goog.userAgent={};goog.userAgent.ASSUME_IE=!1;goog.userAgent.ASSUME_EDGE=!1;goog.userAgent.ASSUME_GECKO=!1;goog.userAgent.ASSUME_WEBKIT=!1;goog.userAgent.ASSUME_MOBILE_WEBKIT=!1;goog.userAgent.ASSUME_OPERA=!1;goog.userAgent.ASSUME_ANY_VERSION=!1;goog.userAgent.BROWSER_KNOWN_=goog.userAgent.ASSUME_IE||goog.userAgent.ASSUME_EDGE||goog.userAgent.ASSUME_GECKO||goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_OPERA;goog.userAgent.getUserAgentString=function(){return goog.labs.userAgent.util.getUserAgent()};
                +goog.userAgent.getNavigator=function(){return goog.global.navigator||null};goog.userAgent.OPERA=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_OPERA:goog.labs.userAgent.browser.isOpera();goog.userAgent.IE=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_IE:goog.labs.userAgent.browser.isIE();goog.userAgent.EDGE=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_EDGE:goog.labs.userAgent.engine.isEdge();goog.userAgent.EDGE_OR_IE=goog.userAgent.EDGE||goog.userAgent.IE;
                +goog.userAgent.GECKO=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_GECKO:goog.labs.userAgent.engine.isGecko();goog.userAgent.WEBKIT=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_MOBILE_WEBKIT:goog.labs.userAgent.engine.isWebKit();goog.userAgent.isMobile_=function(){return goog.userAgent.WEBKIT&&goog.labs.userAgent.util.matchUserAgent("Mobile")};goog.userAgent.MOBILE=goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.isMobile_();goog.userAgent.SAFARI=goog.userAgent.WEBKIT;
                +goog.userAgent.determinePlatform_=function(){var a=goog.userAgent.getNavigator();return a&&a.platform||""};goog.userAgent.PLATFORM=goog.userAgent.determinePlatform_();goog.userAgent.ASSUME_MAC=!1;goog.userAgent.ASSUME_WINDOWS=!1;goog.userAgent.ASSUME_LINUX=!1;goog.userAgent.ASSUME_X11=!1;goog.userAgent.ASSUME_ANDROID=!1;goog.userAgent.ASSUME_IPHONE=!1;goog.userAgent.ASSUME_IPAD=!1;goog.userAgent.ASSUME_IPOD=!1;
                +goog.userAgent.PLATFORM_KNOWN_=goog.userAgent.ASSUME_MAC||goog.userAgent.ASSUME_WINDOWS||goog.userAgent.ASSUME_LINUX||goog.userAgent.ASSUME_X11||goog.userAgent.ASSUME_ANDROID||goog.userAgent.ASSUME_IPHONE||goog.userAgent.ASSUME_IPAD||goog.userAgent.ASSUME_IPOD;goog.userAgent.MAC=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_MAC:goog.labs.userAgent.platform.isMacintosh();goog.userAgent.WINDOWS=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_WINDOWS:goog.labs.userAgent.platform.isWindows();
                +goog.userAgent.isLegacyLinux_=function(){return goog.labs.userAgent.platform.isLinux()||goog.labs.userAgent.platform.isChromeOS()};goog.userAgent.LINUX=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_LINUX:goog.userAgent.isLegacyLinux_();goog.userAgent.isX11_=function(){var a=goog.userAgent.getNavigator();return!!a&&goog.string.contains(a.appVersion||"","X11")};goog.userAgent.X11=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_X11:goog.userAgent.isX11_();
                +goog.userAgent.ANDROID=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_ANDROID:goog.labs.userAgent.platform.isAndroid();goog.userAgent.IPHONE=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPHONE:goog.labs.userAgent.platform.isIphone();goog.userAgent.IPAD=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPAD:goog.labs.userAgent.platform.isIpad();goog.userAgent.IPOD=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPOD:goog.labs.userAgent.platform.isIpod();
                +goog.userAgent.IOS=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPHONE||goog.userAgent.ASSUME_IPAD||goog.userAgent.ASSUME_IPOD:goog.labs.userAgent.platform.isIos();goog.userAgent.determineVersion_=function(){var a="",b=goog.userAgent.getVersionRegexResult_();b&&(a=b?b[1]:"");return goog.userAgent.IE&&(b=goog.userAgent.getDocumentMode_(),null!=b&&b>parseFloat(a))?String(b):a};
                +goog.userAgent.getVersionRegexResult_=function(){var a=goog.userAgent.getUserAgentString();if(goog.userAgent.GECKO)return/rv\:([^\);]+)(\)|;)/.exec(a);if(goog.userAgent.EDGE)return/Edge\/([\d\.]+)/.exec(a);if(goog.userAgent.IE)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(goog.userAgent.WEBKIT)return/WebKit\/(\S+)/.exec(a);if(goog.userAgent.OPERA)return/(?:Version)[ \/]?(\S+)/.exec(a)};goog.userAgent.getDocumentMode_=function(){var a=goog.global.document;return a?a.documentMode:void 0};
                +goog.userAgent.VERSION=goog.userAgent.determineVersion_();goog.userAgent.compare=function(a,b){return goog.string.compareVersions(a,b)};goog.userAgent.isVersionOrHigherCache_={};goog.userAgent.isVersionOrHigher=function(a){return goog.userAgent.ASSUME_ANY_VERSION||goog.reflect.cache(goog.userAgent.isVersionOrHigherCache_,a,function(){return 0<=goog.string.compareVersions(goog.userAgent.VERSION,a)})};goog.userAgent.isVersion=goog.userAgent.isVersionOrHigher;
                +goog.userAgent.isDocumentModeOrHigher=function(a){return Number(goog.userAgent.DOCUMENT_MODE)>=a};goog.userAgent.isDocumentMode=goog.userAgent.isDocumentModeOrHigher;goog.userAgent.DOCUMENT_MODE=function(){var a=goog.global.document,b=goog.userAgent.getDocumentMode_();if(a&&goog.userAgent.IE)return b||("CSS1Compat"==a.compatMode?parseInt(goog.userAgent.VERSION,10):5)}();goog.events={};
                +goog.events.BrowserFeature={HAS_W3C_BUTTON:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT||goog.userAgent.isVersionOrHigher("528"),HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9b")||goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("8")||
                +goog.userAgent.OPERA&&goog.userAgent.isVersionOrHigher("9.5")||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("528"),HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO&&!goog.userAgent.isVersionOrHigher("8")||goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),TOUCH_ENABLED:"ontouchstart"in goog.global||!!(goog.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!goog.global.navigator||!goog.global.navigator.msMaxTouchPoints)};goog.disposable={};goog.disposable.IDisposable=function(){};goog.disposable.IDisposable.prototype.dispose=goog.abstractMethod;goog.disposable.IDisposable.prototype.isDisposed=goog.abstractMethod;goog.Disposable=function(){goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF&&(goog.Disposable.INCLUDE_STACK_ON_CREATION&&(this.creationStack=Error().stack),goog.Disposable.instances_[goog.getUid(this)]=this);this.disposed_=this.disposed_;this.onDisposeCallbacks_=this.onDisposeCallbacks_};goog.Disposable.MonitoringMode={OFF:0,PERMANENT:1,INTERACTIVE:2};goog.Disposable.MONITORING_MODE=0;goog.Disposable.INCLUDE_STACK_ON_CREATION=!0;goog.Disposable.instances_={};
                +goog.Disposable.getUndisposedObjects=function(){var a=[],b;for(b in goog.Disposable.instances_)goog.Disposable.instances_.hasOwnProperty(b)&&a.push(goog.Disposable.instances_[Number(b)]);return a};goog.Disposable.clearUndisposedObjects=function(){goog.Disposable.instances_={}};goog.Disposable.prototype.disposed_=!1;goog.Disposable.prototype.isDisposed=function(){return this.disposed_};goog.Disposable.prototype.getDisposed=goog.Disposable.prototype.isDisposed;
                +goog.Disposable.prototype.dispose=function(){if(!this.disposed_&&(this.disposed_=!0,this.disposeInternal(),goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF)){var a=goog.getUid(this);if(goog.Disposable.MONITORING_MODE==goog.Disposable.MonitoringMode.PERMANENT&&!goog.Disposable.instances_.hasOwnProperty(a))throw Error(this+" did not call the goog.Disposable base constructor or was disposed of after a clearUndisposedObjects call");delete goog.Disposable.instances_[a]}};
                +goog.Disposable.prototype.registerDisposable=function(a){this.addOnDisposeCallback(goog.partial(goog.dispose,a))};goog.Disposable.prototype.addOnDisposeCallback=function(a,b){this.disposed_?goog.isDef(b)?a.call(b):a():(this.onDisposeCallbacks_||(this.onDisposeCallbacks_=[]),this.onDisposeCallbacks_.push(goog.isDef(b)?goog.bind(a,b):a))};goog.Disposable.prototype.disposeInternal=function(){if(this.onDisposeCallbacks_)for(;this.onDisposeCallbacks_.length;)this.onDisposeCallbacks_.shift()()};
                +goog.Disposable.isDisposed=function(a){return a&&"function"==typeof a.isDisposed?a.isDisposed():!1};goog.dispose=function(a){a&&"function"==typeof a.dispose&&a.dispose()};goog.disposeAll=function(a){for(var b=0,c=arguments.length;b<c;++b){var d=arguments[b];goog.isArrayLike(d)?goog.disposeAll.apply(null,d):goog.dispose(d)}};goog.events.EventId=function(a){this.id=a};goog.events.EventId.prototype.toString=function(){return this.id};goog.events.Event=function(a,b){this.type=a instanceof goog.events.EventId?String(a):a;this.currentTarget=this.target=b;this.defaultPrevented=this.propagationStopped_=!1;this.returnValue_=!0};goog.events.Event.prototype.stopPropagation=function(){this.propagationStopped_=!0};goog.events.Event.prototype.preventDefault=function(){this.defaultPrevented=!0;this.returnValue_=!1};goog.events.Event.stopPropagation=function(a){a.stopPropagation()};goog.events.Event.preventDefault=function(a){a.preventDefault()};goog.events.getVendorPrefixedName_=function(a){return goog.userAgent.WEBKIT?"webkit"+a:goog.userAgent.OPERA?"o"+a.toLowerCase():a.toLowerCase()};
                +goog.events.EventType={CLICK:"click",RIGHTCLICK:"rightclick",DBLCLICK:"dblclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",MOUSEOVER:"mouseover",MOUSEOUT:"mouseout",MOUSEMOVE:"mousemove",MOUSEENTER:"mouseenter",MOUSELEAVE:"mouseleave",SELECTIONCHANGE:"selectionchange",SELECTSTART:"selectstart",WHEEL:"wheel",KEYPRESS:"keypress",KEYDOWN:"keydown",KEYUP:"keyup",BLUR:"blur",FOCUS:"focus",DEACTIVATE:"deactivate",FOCUSIN:goog.userAgent.IE?"focusin":"DOMFocusIn",FOCUSOUT:goog.userAgent.IE?"focusout":"DOMFocusOut",
                +CHANGE:"change",RESET:"reset",SELECT:"select",SUBMIT:"submit",INPUT:"input",PROPERTYCHANGE:"propertychange",DRAGSTART:"dragstart",DRAG:"drag",DRAGENTER:"dragenter",DRAGOVER:"dragover",DRAGLEAVE:"dragleave",DROP:"drop",DRAGEND:"dragend",TOUCHSTART:"touchstart",TOUCHMOVE:"touchmove",TOUCHEND:"touchend",TOUCHCANCEL:"touchcancel",BEFOREUNLOAD:"beforeunload",CONSOLEMESSAGE:"consolemessage",CONTEXTMENU:"contextmenu",DEVICEMOTION:"devicemotion",DEVICEORIENTATION:"deviceorientation",DOMCONTENTLOADED:"DOMContentLoaded",
                +ERROR:"error",HELP:"help",LOAD:"load",LOSECAPTURE:"losecapture",ORIENTATIONCHANGE:"orientationchange",READYSTATECHANGE:"readystatechange",RESIZE:"resize",SCROLL:"scroll",UNLOAD:"unload",CANPLAY:"canplay",CANPLAYTHROUGH:"canplaythrough",DURATIONCHANGE:"durationchange",EMPTIED:"emptied",ENDED:"ended",LOADEDDATA:"loadeddata",LOADEDMETADATA:"loadedmetadata",PAUSE:"pause",PLAY:"play",PLAYING:"playing",RATECHANGE:"ratechange",SEEKED:"seeked",SEEKING:"seeking",STALLED:"stalled",SUSPEND:"suspend",TIMEUPDATE:"timeupdate",
                +VOLUMECHANGE:"volumechange",WAITING:"waiting",SOURCEOPEN:"sourceopen",SOURCEENDED:"sourceended",SOURCECLOSED:"sourceclosed",ABORT:"abort",UPDATE:"update",UPDATESTART:"updatestart",UPDATEEND:"updateend",HASHCHANGE:"hashchange",PAGEHIDE:"pagehide",PAGESHOW:"pageshow",POPSTATE:"popstate",COPY:"copy",PASTE:"paste",CUT:"cut",BEFORECOPY:"beforecopy",BEFORECUT:"beforecut",BEFOREPASTE:"beforepaste",ONLINE:"online",OFFLINE:"offline",MESSAGE:"message",CONNECT:"connect",INSTALL:"install",ACTIVATE:"activate",
                +FETCH:"fetch",FOREIGNFETCH:"foreignfetch",MESSAGEERROR:"messageerror",STATECHANGE:"statechange",UPDATEFOUND:"updatefound",CONTROLLERCHANGE:"controllerchange",ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"),ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"),ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"),TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"),POINTERDOWN:"pointerdown",POINTERUP:"pointerup",POINTERCANCEL:"pointercancel",
                +POINTERMOVE:"pointermove",POINTEROVER:"pointerover",POINTEROUT:"pointerout",POINTERENTER:"pointerenter",POINTERLEAVE:"pointerleave",GOTPOINTERCAPTURE:"gotpointercapture",LOSTPOINTERCAPTURE:"lostpointercapture",MSGESTURECHANGE:"MSGestureChange",MSGESTUREEND:"MSGestureEnd",MSGESTUREHOLD:"MSGestureHold",MSGESTURESTART:"MSGestureStart",MSGESTURETAP:"MSGestureTap",MSGOTPOINTERCAPTURE:"MSGotPointerCapture",MSINERTIASTART:"MSInertiaStart",MSLOSTPOINTERCAPTURE:"MSLostPointerCapture",MSPOINTERCANCEL:"MSPointerCancel",
                +MSPOINTERDOWN:"MSPointerDown",MSPOINTERENTER:"MSPointerEnter",MSPOINTERHOVER:"MSPointerHover",MSPOINTERLEAVE:"MSPointerLeave",MSPOINTERMOVE:"MSPointerMove",MSPOINTEROUT:"MSPointerOut",MSPOINTEROVER:"MSPointerOver",MSPOINTERUP:"MSPointerUp",TEXT:"text",TEXTINPUT:goog.userAgent.IE?"textinput":"textInput",COMPOSITIONSTART:"compositionstart",COMPOSITIONUPDATE:"compositionupdate",COMPOSITIONEND:"compositionend",BEFOREINPUT:"beforeinput",EXIT:"exit",LOADABORT:"loadabort",LOADCOMMIT:"loadcommit",LOADREDIRECT:"loadredirect",
                +LOADSTART:"loadstart",LOADSTOP:"loadstop",RESPONSIVE:"responsive",SIZECHANGED:"sizechanged",UNRESPONSIVE:"unresponsive",VISIBILITYCHANGE:"visibilitychange",STORAGE:"storage",DOMSUBTREEMODIFIED:"DOMSubtreeModified",DOMNODEINSERTED:"DOMNodeInserted",DOMNODEREMOVED:"DOMNodeRemoved",DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument",DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument",DOMATTRMODIFIED:"DOMAttrModified",DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified",BEFOREPRINT:"beforeprint",
                +AFTERPRINT:"afterprint"};goog.events.BrowserEvent=function(a,b){goog.events.Event.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.key="";this.charCode=this.keyCode=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.platformModifierKey=!1;this.event_=null;a&&this.init(a,b)};goog.inherits(goog.events.BrowserEvent,goog.events.Event);
                +goog.events.BrowserEvent.MouseButton={LEFT:0,MIDDLE:1,RIGHT:2};goog.events.BrowserEvent.IEButtonMap=[1,4,2];
                +goog.events.BrowserEvent.prototype.init=function(a,b){var c=this.type=a.type,d=a.changedTouches?a.changedTouches[0]:null;this.target=a.target||a.srcElement;this.currentTarget=b;(b=a.relatedTarget)?goog.userAgent.GECKO&&(goog.reflect.canAccessProperty(b,"nodeName")||(b=null)):c==goog.events.EventType.MOUSEOVER?b=a.fromElement:c==goog.events.EventType.MOUSEOUT&&(b=a.toElement);this.relatedTarget=b;goog.isNull(d)?(this.offsetX=goog.userAgent.WEBKIT||void 0!==a.offsetX?a.offsetX:a.layerX,this.offsetY=
                +goog.userAgent.WEBKIT||void 0!==a.offsetY?a.offsetY:a.layerY,this.clientX=void 0!==a.clientX?a.clientX:a.pageX,this.clientY=void 0!==a.clientY?a.clientY:a.pageY,this.screenX=a.screenX||0,this.screenY=a.screenY||0):(this.clientX=void 0!==d.clientX?d.clientX:d.pageX,this.clientY=void 0!==d.clientY?d.clientY:d.pageY,this.screenX=d.screenX||0,this.screenY=d.screenY||0);this.button=a.button;this.keyCode=a.keyCode||0;this.key=a.key||"";this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=
                +a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.platformModifierKey=goog.userAgent.MAC?a.metaKey:a.ctrlKey;this.state=a.state;this.event_=a;a.defaultPrevented&&this.preventDefault()};goog.events.BrowserEvent.prototype.isButton=function(a){return goog.events.BrowserFeature.HAS_W3C_BUTTON?this.event_.button==a:"click"==this.type?a==goog.events.BrowserEvent.MouseButton.LEFT:!!(this.event_.button&goog.events.BrowserEvent.IEButtonMap[a])};
                +goog.events.BrowserEvent.prototype.isMouseActionButton=function(){return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT)&&!(goog.userAgent.WEBKIT&&goog.userAgent.MAC&&this.ctrlKey)};goog.events.BrowserEvent.prototype.stopPropagation=function(){goog.events.BrowserEvent.superClass_.stopPropagation.call(this);this.event_.stopPropagation?this.event_.stopPropagation():this.event_.cancelBubble=!0};
                +goog.events.BrowserEvent.prototype.preventDefault=function(){goog.events.BrowserEvent.superClass_.preventDefault.call(this);var a=this.event_;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};goog.events.BrowserEvent.prototype.getBrowserEvent=function(){return this.event_};goog.events.Listenable=function(){};goog.events.Listenable.IMPLEMENTED_BY_PROP="closure_listenable_"+(1E6*Math.random()|0);goog.events.Listenable.addImplementation=function(a){a.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP]=!0};goog.events.Listenable.isImplementedBy=function(a){return!(!a||!a[goog.events.Listenable.IMPLEMENTED_BY_PROP])};goog.events.ListenableKey=function(){};goog.events.ListenableKey.counter_=0;goog.events.ListenableKey.reserveKey=function(){return++goog.events.ListenableKey.counter_};goog.events.Listener=function(a,b,c,d,e,f){goog.events.Listener.ENABLE_MONITORING&&(this.creationStack=Error().stack);this.listener=a;this.proxy=b;this.src=c;this.type=d;this.capture=!!e;this.handler=f;this.key=goog.events.ListenableKey.reserveKey();this.removed=this.callOnce=!1};goog.events.Listener.ENABLE_MONITORING=!1;goog.events.Listener.prototype.markAsRemoved=function(){this.removed=!0;this.handler=this.src=this.proxy=this.listener=null};goog.events.ListenerMap=function(a){this.src=a;this.listeners={};this.typeCount_=0};goog.events.ListenerMap.prototype.getTypeCount=function(){return this.typeCount_};goog.events.ListenerMap.prototype.getListenerCount=function(){var a=0,b;for(b in this.listeners)a+=this.listeners[b].length;return a};
                +goog.events.ListenerMap.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.listeners[f];a||(a=this.listeners[f]=[],this.typeCount_++);var g=goog.events.ListenerMap.findListenerIndex_(a,b,d,e);-1<g?(b=a[g],c||(b.callOnce=!1)):(b=new goog.events.Listener(b,null,this.src,f,!!d,e),b.callOnce=c,a.push(b));return b};
                +goog.events.ListenerMap.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.listeners))return!1;var e=this.listeners[a];b=goog.events.ListenerMap.findListenerIndex_(e,b,c,d);return-1<b?(e[b].markAsRemoved(),goog.array.removeAt(e,b),0==e.length&&(delete this.listeners[a],this.typeCount_--),!0):!1};
                +goog.events.ListenerMap.prototype.removeByKey=function(a){var b=a.type;if(!(b in this.listeners))return!1;var c=goog.array.remove(this.listeners[b],a);c&&(a.markAsRemoved(),0==this.listeners[b].length&&(delete this.listeners[b],this.typeCount_--));return c};goog.events.ListenerMap.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.listeners)if(!a||c==a){for(var d=this.listeners[c],e=0;e<d.length;e++)++b,d[e].markAsRemoved();delete this.listeners[c];this.typeCount_--}return b};
                +goog.events.ListenerMap.prototype.getListeners=function(a,b){a=this.listeners[a.toString()];var c=[];if(a)for(var d=0;d<a.length;++d){var e=a[d];e.capture==b&&c.push(e)}return c};goog.events.ListenerMap.prototype.getListener=function(a,b,c,d){a=this.listeners[a.toString()];var e=-1;a&&(e=goog.events.ListenerMap.findListenerIndex_(a,b,c,d));return-1<e?a[e]:null};
                +goog.events.ListenerMap.prototype.hasListener=function(a,b){var c=goog.isDef(a),d=c?a.toString():"",e=goog.isDef(b);return goog.object.some(this.listeners,function(a,g){for(g=0;g<a.length;++g)if(!(c&&a[g].type!=d||e&&a[g].capture!=b))return!0;return!1})};goog.events.ListenerMap.findListenerIndex_=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.listener==b&&f.capture==!!c&&f.handler==d)return e}return-1};goog.events.LISTENER_MAP_PROP_="closure_lm_"+(1E6*Math.random()|0);goog.events.onString_="on";goog.events.onStringMap_={};goog.events.CaptureSimulationMode={OFF_AND_FAIL:0,OFF_AND_SILENT:1,ON:2};goog.events.CAPTURE_SIMULATION_MODE=2;goog.events.listenerCountEstimate_=0;
                +goog.events.listen=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listen(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);return goog.events.Listenable.isImplementedBy(a)?a.listen(b,c,d,e):goog.events.listen_(a,b,c,!1,d,e)};
                +goog.events.listen_=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e;if(g&&!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_FAIL)return goog.asserts.fail("Can not register capture listener in IE8-."),null;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_SILENT)return null}var h=goog.events.getListenerMap_(a);h||(a[goog.events.LISTENER_MAP_PROP_]=h=new goog.events.ListenerMap(a));
                +c=h.add(b,c,d,e,f);if(c.proxy)return c;d=goog.events.getProxy();c.proxy=d;d.src=a;d.listener=c;if(a.addEventListener)a.addEventListener(b.toString(),d,g);else if(a.attachEvent)a.attachEvent(goog.events.getOnString_(b.toString()),d);else throw Error("addEventListener and attachEvent are unavailable.");goog.events.listenerCountEstimate_++;return c};
                +goog.events.getProxy=function(){var a=goog.events.handleBrowserEvent_,b=goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT?function(c){return a.call(b.src,b.listener,c)}:function(c){c=a.call(b.src,b.listener,c);if(!c)return c};return b};
                +goog.events.listenOnce=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listenOnce(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);return goog.events.Listenable.isImplementedBy(a)?a.listenOnce(b,c,d,e):goog.events.listen_(a,b,c,!0,d,e)};goog.events.listenWithWrapper=function(a,b,c,d,e){b.listen(a,c,d,e)};
                +goog.events.unlisten=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.unlisten(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);if(goog.events.Listenable.isImplementedBy(a))return a.unlisten(b,c,d,e);if(!a)return!1;d=!!d;if(a=goog.events.getListenerMap_(a))if(b=a.getListener(b,c,d,e))return goog.events.unlistenByKey(b);return!1};
                +goog.events.unlistenByKey=function(a){if(goog.isNumber(a)||!a||a.removed)return!1;var b=a.src;if(goog.events.Listenable.isImplementedBy(b))return b.unlistenByKey(a);var c=a.type,d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent&&b.detachEvent(goog.events.getOnString_(c),d);goog.events.listenerCountEstimate_--;(c=goog.events.getListenerMap_(b))?(c.removeByKey(a),0==c.getTypeCount()&&(c.src=null,b[goog.events.LISTENER_MAP_PROP_]=null)):a.markAsRemoved();return!0};
                +goog.events.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e)};goog.events.removeAll=function(a,b){if(!a)return 0;if(goog.events.Listenable.isImplementedBy(a))return a.removeAllListeners(b);a=goog.events.getListenerMap_(a);if(!a)return 0;var c=0;b=b&&b.toString();for(var d in a.listeners)if(!b||d==b)for(var e=a.listeners[d].concat(),f=0;f<e.length;++f)goog.events.unlistenByKey(e[f])&&++c;return c};
                +goog.events.getListeners=function(a,b,c){return goog.events.Listenable.isImplementedBy(a)?a.getListeners(b,c):a?(a=goog.events.getListenerMap_(a))?a.getListeners(b,c):[]:[]};goog.events.getListener=function(a,b,c,d,e){c=goog.events.wrapListener(c);d=!!d;return goog.events.Listenable.isImplementedBy(a)?a.getListener(b,c,d,e):a?(a=goog.events.getListenerMap_(a))?a.getListener(b,c,d,e):null:null};
                +goog.events.hasListener=function(a,b,c){if(goog.events.Listenable.isImplementedBy(a))return a.hasListener(b,c);a=goog.events.getListenerMap_(a);return!!a&&a.hasListener(b,c)};goog.events.expose=function(a){var b=[],c;for(c in a)a[c]&&a[c].id?b.push(c+" = "+a[c]+" ("+a[c].id+")"):b.push(c+" = "+a[c]);return b.join("\n")};goog.events.getOnString_=function(a){return a in goog.events.onStringMap_?goog.events.onStringMap_[a]:goog.events.onStringMap_[a]=goog.events.onString_+a};
                +goog.events.fireListeners=function(a,b,c,d){return goog.events.Listenable.isImplementedBy(a)?a.fireListeners(b,c,d):goog.events.fireListeners_(a,b,c,d)};goog.events.fireListeners_=function(a,b,c,d){var e=!0;if(a=goog.events.getListenerMap_(a))if(b=a.listeners[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.capture==c&&!f.removed&&(f=goog.events.fireListener(f,d),e=e&&!1!==f)}return e};
                +goog.events.fireListener=function(a,b){var c=a.listener,d=a.handler||a.src;a.callOnce&&goog.events.unlistenByKey(a);return c.call(d,b)};goog.events.getTotalListenerCount=function(){return goog.events.listenerCountEstimate_};goog.events.dispatchEvent=function(a,b){goog.asserts.assert(goog.events.Listenable.isImplementedBy(a),"Can not use goog.events.dispatchEvent with non-goog.events.Listenable instance.");return a.dispatchEvent(b)};
                +goog.events.protectBrowserEventEntryPoint=function(a){goog.events.handleBrowserEvent_=a.protectEntryPoint(goog.events.handleBrowserEvent_)};
                +goog.events.handleBrowserEvent_=function(a,b){if(a.removed)return!0;if(!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){var c=b||goog.getObjectByName("window.event");b=new goog.events.BrowserEvent(c,this);var d=!0;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.ON){if(!goog.events.isMarkedIeEvent_(c)){goog.events.markIeEvent_(c);for(var c=[],e=b.currentTarget;e;e=e.parentNode)c.push(e);for(var e=a.type,f=c.length-1;!b.propagationStopped_&&0<=f;f--)b.currentTarget=c[f],
                +a=goog.events.fireListeners_(c[f],e,!0,b),d=d&&a;for(f=0;!b.propagationStopped_&&f<c.length;f++)b.currentTarget=c[f],a=goog.events.fireListeners_(c[f],e,!1,b),d=d&&a}}else d=goog.events.fireListener(a,b);return d}return goog.events.fireListener(a,new goog.events.BrowserEvent(b,this))};goog.events.markIeEvent_=function(a){var b=!1;if(0==a.keyCode)try{a.keyCode=-1;return}catch(c){b=!0}if(b||void 0==a.returnValue)a.returnValue=!0};
                +goog.events.isMarkedIeEvent_=function(a){return 0>a.keyCode||void 0!=a.returnValue};goog.events.uniqueIdCounter_=0;goog.events.getUniqueId=function(a){return a+"_"+goog.events.uniqueIdCounter_++};goog.events.getListenerMap_=function(a){a=a[goog.events.LISTENER_MAP_PROP_];return a instanceof goog.events.ListenerMap?a:null};goog.events.LISTENER_WRAPPER_PROP_="__closure_events_fn_"+(1E9*Math.random()>>>0);
                +goog.events.wrapListener=function(a){goog.asserts.assert(a,"Listener can not be null.");if(goog.isFunction(a))return a;goog.asserts.assert(a.handleEvent,"An object listener must have handleEvent method.");a[goog.events.LISTENER_WRAPPER_PROP_]||(a[goog.events.LISTENER_WRAPPER_PROP_]=function(b){return a.handleEvent(b)});return a[goog.events.LISTENER_WRAPPER_PROP_]};goog.debug.entryPointRegistry.register(function(a){goog.events.handleBrowserEvent_=a(goog.events.handleBrowserEvent_)});goog.math={};goog.math.randomInt=function(a){return Math.floor(Math.random()*a)};goog.math.uniformRandom=function(a,b){return a+Math.random()*(b-a)};goog.math.clamp=function(a,b,c){return Math.min(Math.max(a,b),c)};goog.math.modulo=function(a,b){a%=b;return 0>a*b?a+b:a};goog.math.lerp=function(a,b,c){return a+c*(b-a)};goog.math.nearlyEquals=function(a,b,c){return Math.abs(a-b)<=(c||1E-6)};goog.math.standardAngle=function(a){return goog.math.modulo(a,360)};
                +goog.math.standardAngleInRadians=function(a){return goog.math.modulo(a,2*Math.PI)};goog.math.toRadians=function(a){return a*Math.PI/180};goog.math.toDegrees=function(a){return 180*a/Math.PI};goog.math.angleDx=function(a,b){return b*Math.cos(goog.math.toRadians(a))};goog.math.angleDy=function(a,b){return b*Math.sin(goog.math.toRadians(a))};goog.math.angle=function(a,b,c,d){return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(d-b,c-a)))};
                +goog.math.angleDifference=function(a,b){a=goog.math.standardAngle(b)-goog.math.standardAngle(a);180<a?a-=360:-180>=a&&(a=360+a);return a};goog.math.sign=function(a){return 0<a?1:0>a?-1:a};
                +goog.math.longestCommonSubsequence=function(a,b,c,d){c=c||function(a,b){return a==b};d=d||function(b,c){return a[b]};for(var e=a.length,f=b.length,g=[],h=0;h<e+1;h++)g[h]=[],g[h][0]=0;for(var k=0;k<f+1;k++)g[0][k]=0;for(h=1;h<=e;h++)for(k=1;k<=f;k++)c(a[h-1],b[k-1])?g[h][k]=g[h-1][k-1]+1:g[h][k]=Math.max(g[h-1][k],g[h][k-1]);for(var l=[],h=e,k=f;0<h&&0<k;)c(a[h-1],b[k-1])?(l.unshift(d(h-1,k-1)),h--,k--):g[h-1][k]>g[h][k-1]?h--:k--;return l};
                +goog.math.sum=function(a){return goog.array.reduce(arguments,function(a,c){return a+c},0)};goog.math.average=function(a){return goog.math.sum.apply(null,arguments)/arguments.length};goog.math.sampleVariance=function(a){var b=arguments.length;if(2>b)return 0;var c=goog.math.average.apply(null,arguments);return goog.math.sum.apply(null,goog.array.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};goog.math.standardDeviation=function(a){return Math.sqrt(goog.math.sampleVariance.apply(null,arguments))};
                +goog.math.isInt=function(a){return isFinite(a)&&0==a%1};goog.math.isFiniteNumber=function(a){return isFinite(a)};goog.math.isNegativeZero=function(a){return 0==a&&0>1/a};goog.math.log10Floor=function(a){if(0<a){var b=Math.round(Math.log(a)*Math.LOG10E);return b-(parseFloat("1e"+b)>a?1:0)}return 0==a?-Infinity:NaN};goog.math.safeFloor=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.floor(a+(b||2E-15))};
                +goog.math.safeCeil=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.ceil(a-(b||2E-15))};goog.dom.BrowserFeature={CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),CAN_USE_CHILDREN_ATTRIBUTE:!goog.userAgent.GECKO&&!goog.userAgent.IE||goog.userAgent.IE&&goog.userAgent.isDocumentModeOrHigher(9)||goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9.1"),CAN_USE_INNER_TEXT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),CAN_USE_PARENT_ELEMENT_PROPERTY:goog.userAgent.IE||goog.userAgent.OPERA||goog.userAgent.WEBKIT,INNER_HTML_NEEDS_SCOPED_ELEMENT:goog.userAgent.IE,
                +LEGACY_IE_RANGES:goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)};goog.dom.HtmlElement=function(){};goog.dom.TagName=function(a){this.tagName_=a};goog.dom.TagName.prototype.toString=function(){return this.tagName_};goog.dom.TagName.A=new goog.dom.TagName("A");goog.dom.TagName.ABBR=new goog.dom.TagName("ABBR");goog.dom.TagName.ACRONYM=new goog.dom.TagName("ACRONYM");goog.dom.TagName.ADDRESS=new goog.dom.TagName("ADDRESS");goog.dom.TagName.APPLET=new goog.dom.TagName("APPLET");goog.dom.TagName.AREA=new goog.dom.TagName("AREA");goog.dom.TagName.ARTICLE=new goog.dom.TagName("ARTICLE");
                +goog.dom.TagName.ASIDE=new goog.dom.TagName("ASIDE");goog.dom.TagName.AUDIO=new goog.dom.TagName("AUDIO");goog.dom.TagName.B=new goog.dom.TagName("B");goog.dom.TagName.BASE=new goog.dom.TagName("BASE");goog.dom.TagName.BASEFONT=new goog.dom.TagName("BASEFONT");goog.dom.TagName.BDI=new goog.dom.TagName("BDI");goog.dom.TagName.BDO=new goog.dom.TagName("BDO");goog.dom.TagName.BIG=new goog.dom.TagName("BIG");goog.dom.TagName.BLOCKQUOTE=new goog.dom.TagName("BLOCKQUOTE");goog.dom.TagName.BODY=new goog.dom.TagName("BODY");
                +goog.dom.TagName.BR=new goog.dom.TagName("BR");goog.dom.TagName.BUTTON=new goog.dom.TagName("BUTTON");goog.dom.TagName.CANVAS=new goog.dom.TagName("CANVAS");goog.dom.TagName.CAPTION=new goog.dom.TagName("CAPTION");goog.dom.TagName.CENTER=new goog.dom.TagName("CENTER");goog.dom.TagName.CITE=new goog.dom.TagName("CITE");goog.dom.TagName.CODE=new goog.dom.TagName("CODE");goog.dom.TagName.COL=new goog.dom.TagName("COL");goog.dom.TagName.COLGROUP=new goog.dom.TagName("COLGROUP");
                +goog.dom.TagName.COMMAND=new goog.dom.TagName("COMMAND");goog.dom.TagName.DATA=new goog.dom.TagName("DATA");goog.dom.TagName.DATALIST=new goog.dom.TagName("DATALIST");goog.dom.TagName.DD=new goog.dom.TagName("DD");goog.dom.TagName.DEL=new goog.dom.TagName("DEL");goog.dom.TagName.DETAILS=new goog.dom.TagName("DETAILS");goog.dom.TagName.DFN=new goog.dom.TagName("DFN");goog.dom.TagName.DIALOG=new goog.dom.TagName("DIALOG");goog.dom.TagName.DIR=new goog.dom.TagName("DIR");goog.dom.TagName.DIV=new goog.dom.TagName("DIV");
                +goog.dom.TagName.DL=new goog.dom.TagName("DL");goog.dom.TagName.DT=new goog.dom.TagName("DT");goog.dom.TagName.EM=new goog.dom.TagName("EM");goog.dom.TagName.EMBED=new goog.dom.TagName("EMBED");goog.dom.TagName.FIELDSET=new goog.dom.TagName("FIELDSET");goog.dom.TagName.FIGCAPTION=new goog.dom.TagName("FIGCAPTION");goog.dom.TagName.FIGURE=new goog.dom.TagName("FIGURE");goog.dom.TagName.FONT=new goog.dom.TagName("FONT");goog.dom.TagName.FOOTER=new goog.dom.TagName("FOOTER");goog.dom.TagName.FORM=new goog.dom.TagName("FORM");
                +goog.dom.TagName.FRAME=new goog.dom.TagName("FRAME");goog.dom.TagName.FRAMESET=new goog.dom.TagName("FRAMESET");goog.dom.TagName.H1=new goog.dom.TagName("H1");goog.dom.TagName.H2=new goog.dom.TagName("H2");goog.dom.TagName.H3=new goog.dom.TagName("H3");goog.dom.TagName.H4=new goog.dom.TagName("H4");goog.dom.TagName.H5=new goog.dom.TagName("H5");goog.dom.TagName.H6=new goog.dom.TagName("H6");goog.dom.TagName.HEAD=new goog.dom.TagName("HEAD");goog.dom.TagName.HEADER=new goog.dom.TagName("HEADER");
                +goog.dom.TagName.HGROUP=new goog.dom.TagName("HGROUP");goog.dom.TagName.HR=new goog.dom.TagName("HR");goog.dom.TagName.HTML=new goog.dom.TagName("HTML");goog.dom.TagName.I=new goog.dom.TagName("I");goog.dom.TagName.IFRAME=new goog.dom.TagName("IFRAME");goog.dom.TagName.IMG=new goog.dom.TagName("IMG");goog.dom.TagName.INPUT=new goog.dom.TagName("INPUT");goog.dom.TagName.INS=new goog.dom.TagName("INS");goog.dom.TagName.ISINDEX=new goog.dom.TagName("ISINDEX");goog.dom.TagName.KBD=new goog.dom.TagName("KBD");
                +goog.dom.TagName.KEYGEN=new goog.dom.TagName("KEYGEN");goog.dom.TagName.LABEL=new goog.dom.TagName("LABEL");goog.dom.TagName.LEGEND=new goog.dom.TagName("LEGEND");goog.dom.TagName.LI=new goog.dom.TagName("LI");goog.dom.TagName.LINK=new goog.dom.TagName("LINK");goog.dom.TagName.MAP=new goog.dom.TagName("MAP");goog.dom.TagName.MARK=new goog.dom.TagName("MARK");goog.dom.TagName.MATH=new goog.dom.TagName("MATH");goog.dom.TagName.MENU=new goog.dom.TagName("MENU");goog.dom.TagName.META=new goog.dom.TagName("META");
                +goog.dom.TagName.METER=new goog.dom.TagName("METER");goog.dom.TagName.NAV=new goog.dom.TagName("NAV");goog.dom.TagName.NOFRAMES=new goog.dom.TagName("NOFRAMES");goog.dom.TagName.NOSCRIPT=new goog.dom.TagName("NOSCRIPT");goog.dom.TagName.OBJECT=new goog.dom.TagName("OBJECT");goog.dom.TagName.OL=new goog.dom.TagName("OL");goog.dom.TagName.OPTGROUP=new goog.dom.TagName("OPTGROUP");goog.dom.TagName.OPTION=new goog.dom.TagName("OPTION");goog.dom.TagName.OUTPUT=new goog.dom.TagName("OUTPUT");
                +goog.dom.TagName.P=new goog.dom.TagName("P");goog.dom.TagName.PARAM=new goog.dom.TagName("PARAM");goog.dom.TagName.PRE=new goog.dom.TagName("PRE");goog.dom.TagName.PROGRESS=new goog.dom.TagName("PROGRESS");goog.dom.TagName.Q=new goog.dom.TagName("Q");goog.dom.TagName.RP=new goog.dom.TagName("RP");goog.dom.TagName.RT=new goog.dom.TagName("RT");goog.dom.TagName.RUBY=new goog.dom.TagName("RUBY");goog.dom.TagName.S=new goog.dom.TagName("S");goog.dom.TagName.SAMP=new goog.dom.TagName("SAMP");
                +goog.dom.TagName.SCRIPT=new goog.dom.TagName("SCRIPT");goog.dom.TagName.SECTION=new goog.dom.TagName("SECTION");goog.dom.TagName.SELECT=new goog.dom.TagName("SELECT");goog.dom.TagName.SMALL=new goog.dom.TagName("SMALL");goog.dom.TagName.SOURCE=new goog.dom.TagName("SOURCE");goog.dom.TagName.SPAN=new goog.dom.TagName("SPAN");goog.dom.TagName.STRIKE=new goog.dom.TagName("STRIKE");goog.dom.TagName.STRONG=new goog.dom.TagName("STRONG");goog.dom.TagName.STYLE=new goog.dom.TagName("STYLE");
                +goog.dom.TagName.SUB=new goog.dom.TagName("SUB");goog.dom.TagName.SUMMARY=new goog.dom.TagName("SUMMARY");goog.dom.TagName.SUP=new goog.dom.TagName("SUP");goog.dom.TagName.SVG=new goog.dom.TagName("SVG");goog.dom.TagName.TABLE=new goog.dom.TagName("TABLE");goog.dom.TagName.TBODY=new goog.dom.TagName("TBODY");goog.dom.TagName.TD=new goog.dom.TagName("TD");goog.dom.TagName.TEMPLATE=new goog.dom.TagName("TEMPLATE");goog.dom.TagName.TEXTAREA=new goog.dom.TagName("TEXTAREA");goog.dom.TagName.TFOOT=new goog.dom.TagName("TFOOT");
                +goog.dom.TagName.TH=new goog.dom.TagName("TH");goog.dom.TagName.THEAD=new goog.dom.TagName("THEAD");goog.dom.TagName.TIME=new goog.dom.TagName("TIME");goog.dom.TagName.TITLE=new goog.dom.TagName("TITLE");goog.dom.TagName.TR=new goog.dom.TagName("TR");goog.dom.TagName.TRACK=new goog.dom.TagName("TRACK");goog.dom.TagName.TT=new goog.dom.TagName("TT");goog.dom.TagName.U=new goog.dom.TagName("U");goog.dom.TagName.UL=new goog.dom.TagName("UL");goog.dom.TagName.VAR=new goog.dom.TagName("VAR");
                +goog.dom.TagName.VIDEO=new goog.dom.TagName("VIDEO");goog.dom.TagName.WBR=new goog.dom.TagName("WBR");goog.dom.tags={};goog.dom.tags.VOID_TAGS_={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};goog.dom.tags.isVoidTag=function(a){return!0===goog.dom.tags.VOID_TAGS_[a]};goog.string.TypedString=function(){};goog.string.Const=function(){this.stringConstValueWithSecurityContract__googStringSecurityPrivate_="";this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_=goog.string.Const.TYPE_MARKER_};goog.string.Const.prototype.implementsGoogStringTypedString=!0;goog.string.Const.prototype.getTypedStringValue=function(){return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_};
                +goog.string.Const.prototype.toString=function(){return"Const{"+this.stringConstValueWithSecurityContract__googStringSecurityPrivate_+"}"};goog.string.Const.unwrap=function(a){if(a instanceof goog.string.Const&&a.constructor===goog.string.Const&&a.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_===goog.string.Const.TYPE_MARKER_)return a.stringConstValueWithSecurityContract__googStringSecurityPrivate_;goog.asserts.fail("expected object of type Const, got '"+a+"'");return"type_error:Const"};
                +goog.string.Const.from=function(a){return goog.string.Const.create__googStringSecurityPrivate_(a)};goog.string.Const.TYPE_MARKER_={};goog.string.Const.create__googStringSecurityPrivate_=function(a){var b=new goog.string.Const;b.stringConstValueWithSecurityContract__googStringSecurityPrivate_=a;return b};goog.string.Const.EMPTY=goog.string.Const.from("");goog.html={};goog.html.SafeScript=function(){this.privateDoNotAccessOrElseSafeScriptWrappedValue_="";this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeScript.prototype.implementsGoogStringTypedString=!0;goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.SafeScript.fromConstant=function(a){a=goog.string.Const.unwrap(a);return 0===a.length?goog.html.SafeScript.EMPTY:goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.SafeScript.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeScriptWrappedValue_};goog.DEBUG&&(goog.html.SafeScript.prototype.toString=function(){return"SafeScript{"+this.privateDoNotAccessOrElseSafeScriptWrappedValue_+"}"});
                +goog.html.SafeScript.unwrap=function(a){if(a instanceof goog.html.SafeScript&&a.constructor===goog.html.SafeScript&&a.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeScriptWrappedValue_;goog.asserts.fail("expected object of type SafeScript, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeScript"};goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeScript).initSecurityPrivateDoNotAccessOrElse_(a)};
                +goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeScriptWrappedValue_=a;return this};goog.html.SafeScript.EMPTY=goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse("");goog.html.SafeStyle=function(){this.privateDoNotAccessOrElseSafeStyleWrappedValue_="";this.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeStyle.prototype.implementsGoogStringTypedString=!0;goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeStyle.fromConstant=function(a){a=goog.string.Const.unwrap(a);if(0===a.length)return goog.html.SafeStyle.EMPTY;goog.html.SafeStyle.checkStyle_(a);goog.asserts.assert(goog.string.endsWith(a,";"),"Last character of style string is not ';': "+a);goog.asserts.assert(goog.string.contains(a,":"),"Style string must contain at least one ':', to specify a \"name: value\" pair: "+a);return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.SafeStyle.checkStyle_=function(a){goog.asserts.assert(!/[<>]/.test(a),"Forbidden characters in style string: "+a)};goog.html.SafeStyle.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeStyleWrappedValue_};goog.DEBUG&&(goog.html.SafeStyle.prototype.toString=function(){return"SafeStyle{"+this.privateDoNotAccessOrElseSafeStyleWrappedValue_+"}"});
                +goog.html.SafeStyle.unwrap=function(a){if(a instanceof goog.html.SafeStyle&&a.constructor===goog.html.SafeStyle&&a.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeStyleWrappedValue_;goog.asserts.fail("expected object of type SafeStyle, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeStyle"};goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeStyle).initSecurityPrivateDoNotAccessOrElse_(a)};
                +goog.html.SafeStyle.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeStyleWrappedValue_=a;return this};goog.html.SafeStyle.EMPTY=goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse("");goog.html.SafeStyle.INNOCUOUS_STRING="zClosurez";
                +goog.html.SafeStyle.create=function(a){var b="",c;for(c in a){if(!/^[-_a-zA-Z0-9]+$/.test(c))throw Error("Name allows only [-_a-zA-Z0-9], got: "+c);var d=a[c];null!=d&&(d instanceof goog.string.Const?(d=goog.string.Const.unwrap(d),goog.asserts.assert(!/[{;}]/.test(d),"Value does not allow [{;}].")):goog.html.SafeStyle.VALUE_RE_.test(d)?goog.html.SafeStyle.hasBalancedQuotes_(d)||(goog.asserts.fail("String value requires balanced quotes, got: "+d),d=goog.html.SafeStyle.INNOCUOUS_STRING):(goog.asserts.fail("String value allows only [-,.\"'%_!# a-zA-Z0-9], rgb() and rgba(), got: "+
                +d),d=goog.html.SafeStyle.INNOCUOUS_STRING),b+=c+":"+d+";")}if(!b)return goog.html.SafeStyle.EMPTY;goog.html.SafeStyle.checkStyle_(b);return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b)};goog.html.SafeStyle.hasBalancedQuotes_=function(a){for(var b=!0,c=!0,d=0;d<a.length;d++){var e=a.charAt(d);"'"==e&&c?b=!b:'"'==e&&b&&(c=!c)}return b&&c};goog.html.SafeStyle.VALUE_RE_=/^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/;
                +goog.html.SafeStyle.concat=function(a){var b="",c=function(a){goog.isArray(a)?goog.array.forEach(a,c):b+=goog.html.SafeStyle.unwrap(a)};goog.array.forEach(arguments,c);return b?goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b):goog.html.SafeStyle.EMPTY};goog.html.SafeStyleSheet=function(){this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_="";this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeStyleSheet.prototype.implementsGoogStringTypedString=!0;goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeStyleSheet.concat=function(a){var b="",c=function(a){goog.isArray(a)?goog.array.forEach(a,c):b+=goog.html.SafeStyleSheet.unwrap(a)};goog.array.forEach(arguments,c);return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.SafeStyleSheet.fromConstant=function(a){a=goog.string.Const.unwrap(a);if(0===a.length)return goog.html.SafeStyleSheet.EMPTY;goog.asserts.assert(!goog.string.contains(a,"<"),"Forbidden '<' character in style sheet string: "+a);return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeStyleSheet.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_};
                +goog.DEBUG&&(goog.html.SafeStyleSheet.prototype.toString=function(){return"SafeStyleSheet{"+this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_+"}"});
                +goog.html.SafeStyleSheet.unwrap=function(a){if(a instanceof goog.html.SafeStyleSheet&&a.constructor===goog.html.SafeStyleSheet&&a.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;goog.asserts.fail("expected object of type SafeStyleSheet, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeStyleSheet"};
                +goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeStyleSheet).initSecurityPrivateDoNotAccessOrElse_(a)};goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_=a;return this};goog.html.SafeStyleSheet.EMPTY=goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse("");goog.fs={};goog.fs.url={};goog.fs.url.createObjectUrl=function(a){return goog.fs.url.getUrlObject_().createObjectURL(a)};goog.fs.url.revokeObjectUrl=function(a){goog.fs.url.getUrlObject_().revokeObjectURL(a)};goog.fs.url.getUrlObject_=function(){var a=goog.fs.url.findUrlObject_();if(null!=a)return a;throw Error("This browser doesn't seem to support blob URLs");};
                +goog.fs.url.findUrlObject_=function(){return goog.isDef(goog.global.URL)&&goog.isDef(goog.global.URL.createObjectURL)?goog.global.URL:goog.isDef(goog.global.webkitURL)&&goog.isDef(goog.global.webkitURL.createObjectURL)?goog.global.webkitURL:goog.isDef(goog.global.createObjectURL)?goog.global:null};goog.fs.url.browserSupportsObjectUrls=function(){return null!=goog.fs.url.findUrlObject_()};goog.i18n={};goog.i18n.bidi={};goog.i18n.bidi.FORCE_RTL=!1;
                +goog.i18n.bidi.IS_RTL=goog.i18n.bidi.FORCE_RTL||("ar"==goog.LOCALE.substring(0,2).toLowerCase()||"fa"==goog.LOCALE.substring(0,2).toLowerCase()||"he"==goog.LOCALE.substring(0,2).toLowerCase()||"iw"==goog.LOCALE.substring(0,2).toLowerCase()||"ps"==goog.LOCALE.substring(0,2).toLowerCase()||"sd"==goog.LOCALE.substring(0,2).toLowerCase()||"ug"==goog.LOCALE.substring(0,2).toLowerCase()||"ur"==goog.LOCALE.substring(0,2).toLowerCase()||"yi"==goog.LOCALE.substring(0,2).toLowerCase())&&(2==goog.LOCALE.length||
                +"-"==goog.LOCALE.substring(2,3)||"_"==goog.LOCALE.substring(2,3))||3<=goog.LOCALE.length&&"ckb"==goog.LOCALE.substring(0,3).toLowerCase()&&(3==goog.LOCALE.length||"-"==goog.LOCALE.substring(3,4)||"_"==goog.LOCALE.substring(3,4));goog.i18n.bidi.Format={LRE:"\u202a",RLE:"\u202b",PDF:"\u202c",LRM:"\u200e",RLM:"\u200f"};goog.i18n.bidi.Dir={LTR:1,RTL:-1,NEUTRAL:0};goog.i18n.bidi.RIGHT="right";goog.i18n.bidi.LEFT="left";goog.i18n.bidi.I18N_RIGHT=goog.i18n.bidi.IS_RTL?goog.i18n.bidi.LEFT:goog.i18n.bidi.RIGHT;
                +goog.i18n.bidi.I18N_LEFT=goog.i18n.bidi.IS_RTL?goog.i18n.bidi.RIGHT:goog.i18n.bidi.LEFT;goog.i18n.bidi.toDir=function(a,b){return"number"==typeof a?0<a?goog.i18n.bidi.Dir.LTR:0>a?goog.i18n.bidi.Dir.RTL:b?null:goog.i18n.bidi.Dir.NEUTRAL:null==a?null:a?goog.i18n.bidi.Dir.RTL:goog.i18n.bidi.Dir.LTR};goog.i18n.bidi.ltrChars_="A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff";goog.i18n.bidi.rtlChars_="\u0591-\u06ef\u06fa-\u07ff\u200f\ufb1d-\ufdff\ufe70-\ufefc";
                +goog.i18n.bidi.htmlSkipReg_=/<[^>]*>|&[^;]+;/g;goog.i18n.bidi.stripHtmlIfNeeded_=function(a,b){return b?a.replace(goog.i18n.bidi.htmlSkipReg_,""):a};goog.i18n.bidi.rtlCharReg_=new RegExp("["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.ltrCharReg_=new RegExp("["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.hasAnyRtl=function(a,b){return goog.i18n.bidi.rtlCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.hasRtlChar=goog.i18n.bidi.hasAnyRtl;
                +goog.i18n.bidi.hasAnyLtr=function(a,b){return goog.i18n.bidi.ltrCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.ltrRe_=new RegExp("^["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.rtlRe_=new RegExp("^["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.isRtlChar=function(a){return goog.i18n.bidi.rtlRe_.test(a)};goog.i18n.bidi.isLtrChar=function(a){return goog.i18n.bidi.ltrRe_.test(a)};goog.i18n.bidi.isNeutralChar=function(a){return!goog.i18n.bidi.isLtrChar(a)&&!goog.i18n.bidi.isRtlChar(a)};
                +goog.i18n.bidi.ltrDirCheckRe_=new RegExp("^[^"+goog.i18n.bidi.rtlChars_+"]*["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.rtlDirCheckRe_=new RegExp("^[^"+goog.i18n.bidi.ltrChars_+"]*["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.startsWithRtl=function(a,b){return goog.i18n.bidi.rtlDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isRtlText=goog.i18n.bidi.startsWithRtl;
                +goog.i18n.bidi.startsWithLtr=function(a,b){return goog.i18n.bidi.ltrDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isLtrText=goog.i18n.bidi.startsWithLtr;goog.i18n.bidi.isRequiredLtrRe_=/^http:\/\/.*/;goog.i18n.bidi.isNeutralText=function(a,b){a=goog.i18n.bidi.stripHtmlIfNeeded_(a,b);return goog.i18n.bidi.isRequiredLtrRe_.test(a)||!goog.i18n.bidi.hasAnyLtr(a)&&!goog.i18n.bidi.hasAnyRtl(a)};
                +goog.i18n.bidi.ltrExitDirCheckRe_=new RegExp("["+goog.i18n.bidi.ltrChars_+"][^"+goog.i18n.bidi.rtlChars_+"]*$");goog.i18n.bidi.rtlExitDirCheckRe_=new RegExp("["+goog.i18n.bidi.rtlChars_+"][^"+goog.i18n.bidi.ltrChars_+"]*$");goog.i18n.bidi.endsWithLtr=function(a,b){return goog.i18n.bidi.ltrExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isLtrExitText=goog.i18n.bidi.endsWithLtr;
                +goog.i18n.bidi.endsWithRtl=function(a,b){return goog.i18n.bidi.rtlExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isRtlExitText=goog.i18n.bidi.endsWithRtl;goog.i18n.bidi.rtlLocalesRe_=/^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)/i;goog.i18n.bidi.isRtlLanguage=function(a){return goog.i18n.bidi.rtlLocalesRe_.test(a)};goog.i18n.bidi.bracketGuardTextRe_=/(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
                +goog.i18n.bidi.guardBracketInText=function(a,b){b=(void 0===b?goog.i18n.bidi.hasAnyRtl(a):b)?goog.i18n.bidi.Format.RLM:goog.i18n.bidi.Format.LRM;return a.replace(goog.i18n.bidi.bracketGuardTextRe_,b+"$&"+b)};goog.i18n.bidi.enforceRtlInHtml=function(a){return"<"==a.charAt(0)?a.replace(/<\w+/,"$& dir=rtl"):"\n<span dir=rtl>"+a+"</span>"};goog.i18n.bidi.enforceRtlInText=function(a){return goog.i18n.bidi.Format.RLE+a+goog.i18n.bidi.Format.PDF};
                +goog.i18n.bidi.enforceLtrInHtml=function(a){return"<"==a.charAt(0)?a.replace(/<\w+/,"$& dir=ltr"):"\n<span dir=ltr>"+a+"</span>"};goog.i18n.bidi.enforceLtrInText=function(a){return goog.i18n.bidi.Format.LRE+a+goog.i18n.bidi.Format.PDF};goog.i18n.bidi.dimensionsRe_=/:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;goog.i18n.bidi.leftRe_=/left/gi;goog.i18n.bidi.rightRe_=/right/gi;goog.i18n.bidi.tempRe_=/%%%%/g;
                +goog.i18n.bidi.mirrorCSS=function(a){return a.replace(goog.i18n.bidi.dimensionsRe_,":$1 $4 $3 $2").replace(goog.i18n.bidi.leftRe_,"%%%%").replace(goog.i18n.bidi.rightRe_,goog.i18n.bidi.LEFT).replace(goog.i18n.bidi.tempRe_,goog.i18n.bidi.RIGHT)};goog.i18n.bidi.doubleQuoteSubstituteRe_=/([\u0591-\u05f2])"/g;goog.i18n.bidi.singleQuoteSubstituteRe_=/([\u0591-\u05f2])'/g;
                +goog.i18n.bidi.normalizeHebrewQuote=function(a){return a.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_,"$1\u05f4").replace(goog.i18n.bidi.singleQuoteSubstituteRe_,"$1\u05f3")};goog.i18n.bidi.wordSeparatorRe_=/\s+/;goog.i18n.bidi.hasNumeralsRe_=/[\d\u06f0-\u06f9]/;goog.i18n.bidi.rtlDetectionThreshold_=.4;
                +goog.i18n.bidi.estimateDirection=function(a,b){var c=0,d=0,e=!1;a=goog.i18n.bidi.stripHtmlIfNeeded_(a,b).split(goog.i18n.bidi.wordSeparatorRe_);for(b=0;b<a.length;b++){var f=a[b];goog.i18n.bidi.startsWithRtl(f)?(c++,d++):goog.i18n.bidi.isRequiredLtrRe_.test(f)?e=!0:goog.i18n.bidi.hasAnyLtr(f)?d++:goog.i18n.bidi.hasNumeralsRe_.test(f)&&(e=!0)}return 0==d?e?goog.i18n.bidi.Dir.LTR:goog.i18n.bidi.Dir.NEUTRAL:c/d>goog.i18n.bidi.rtlDetectionThreshold_?goog.i18n.bidi.Dir.RTL:goog.i18n.bidi.Dir.LTR};
                +goog.i18n.bidi.detectRtlDirectionality=function(a,b){return goog.i18n.bidi.estimateDirection(a,b)==goog.i18n.bidi.Dir.RTL};goog.i18n.bidi.setElementDirAndAlign=function(a,b){a&&(b=goog.i18n.bidi.toDir(b))&&(a.style.textAlign=b==goog.i18n.bidi.Dir.RTL?goog.i18n.bidi.RIGHT:goog.i18n.bidi.LEFT,a.dir=b==goog.i18n.bidi.Dir.RTL?"rtl":"ltr")};
                +goog.i18n.bidi.setElementDirByTextDirectionality=function(a,b){switch(goog.i18n.bidi.estimateDirection(b)){case goog.i18n.bidi.Dir.LTR:a.dir="ltr";break;case goog.i18n.bidi.Dir.RTL:a.dir="rtl";break;default:a.removeAttribute("dir")}};goog.i18n.bidi.DirectionalString=function(){};goog.html.TrustedResourceUrl=function(){this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_="";this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString=!0;goog.html.TrustedResourceUrl.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_};
                +goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.TrustedResourceUrl.prototype.getDirection=function(){return goog.i18n.bidi.Dir.LTR};goog.DEBUG&&(goog.html.TrustedResourceUrl.prototype.toString=function(){return"TrustedResourceUrl{"+this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_+"}"});
                +goog.html.TrustedResourceUrl.unwrap=function(a){if(a instanceof goog.html.TrustedResourceUrl&&a.constructor===goog.html.TrustedResourceUrl&&a.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;goog.asserts.fail("expected object of type TrustedResourceUrl, got '"+a+"' of type "+goog.typeOf(a));return"type_error:TrustedResourceUrl"};
                +goog.html.TrustedResourceUrl.format=function(a,b){var c=goog.string.Const.unwrap(a);if(!goog.html.TrustedResourceUrl.BASE_URL_.test(c))throw Error("Invalid TrustedResourceUrl format: "+c);a=c.replace(goog.html.TrustedResourceUrl.FORMAT_MARKER_,function(a,e){if(!Object.prototype.hasOwnProperty.call(b,e))throw Error('Found marker, "'+e+'", in format string, "'+c+'", but no valid label mapping found in args: '+JSON.stringify(b));a=b[e];return a instanceof goog.string.Const?goog.string.Const.unwrap(a):
                +encodeURIComponent(String(a))});return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.TrustedResourceUrl.FORMAT_MARKER_=/%{(\w+)}/g;goog.html.TrustedResourceUrl.BASE_URL_=/^(?:https:)?\/\/[0-9a-z.:[\]-]+\/|^\/[^\/\\]|^about:blank(#|$)/i;goog.html.TrustedResourceUrl.fromConstant=function(a){return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(a))};
                +goog.html.TrustedResourceUrl.fromConstants=function(a){for(var b="",c=0;c<a.length;c++)b+=goog.string.Const.unwrap(a[c]);return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(b)};goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse=function(a){var b=new goog.html.TrustedResourceUrl;b.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_=a;return b};goog.html.SafeUrl=function(){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_="";this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeUrl.INNOCUOUS_STRING="about:invalid#zClosurez";goog.html.SafeUrl.prototype.implementsGoogStringTypedString=!0;goog.html.SafeUrl.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_};
                +goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.SafeUrl.prototype.getDirection=function(){return goog.i18n.bidi.Dir.LTR};goog.DEBUG&&(goog.html.SafeUrl.prototype.toString=function(){return"SafeUrl{"+this.privateDoNotAccessOrElseSafeHtmlWrappedValue_+"}"});
                +goog.html.SafeUrl.unwrap=function(a){if(a instanceof goog.html.SafeUrl&&a.constructor===goog.html.SafeUrl&&a.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeHtmlWrappedValue_;goog.asserts.fail("expected object of type SafeUrl, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeUrl"};goog.html.SafeUrl.fromConstant=function(a){return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(a))};
                +goog.html.SAFE_MIME_TYPE_PATTERN_=/^(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm))$/i;goog.html.SafeUrl.fromBlob=function(a){a=goog.html.SAFE_MIME_TYPE_PATTERN_.test(a.type)?goog.fs.url.createObjectUrl(a):goog.html.SafeUrl.INNOCUOUS_STRING;return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.DATA_URL_PATTERN_=/^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;
                +goog.html.SafeUrl.fromDataUrl=function(a){var b=a.match(goog.html.DATA_URL_PATTERN_),b=b&&goog.html.SAFE_MIME_TYPE_PATTERN_.test(b[1]);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(b?a:goog.html.SafeUrl.INNOCUOUS_STRING)};goog.html.SafeUrl.fromTelUrl=function(a){goog.string.caseInsensitiveStartsWith(a,"tel:")||(a=goog.html.SafeUrl.INNOCUOUS_STRING);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeUrl.fromTrustedResourceUrl=function(a){return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.TrustedResourceUrl.unwrap(a))};
                +goog.html.SAFE_URL_PATTERN_=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;goog.html.SafeUrl.sanitize=function(a){if(a instanceof goog.html.SafeUrl)return a;a=a.implementsGoogStringTypedString?a.getTypedStringValue():String(a);goog.html.SAFE_URL_PATTERN_.test(a)||(a=goog.html.SafeUrl.INNOCUOUS_STRING);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse=function(a){var b=new goog.html.SafeUrl;b.privateDoNotAccessOrElseSafeHtmlWrappedValue_=a;return b};goog.html.SafeUrl.ABOUT_BLANK=goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse("about:blank");goog.html.SafeHtml=function(){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_="";this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;this.dir_=null};goog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.SafeHtml.prototype.getDirection=function(){return this.dir_};goog.html.SafeHtml.prototype.implementsGoogStringTypedString=!0;goog.html.SafeHtml.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_};
                +goog.DEBUG&&(goog.html.SafeHtml.prototype.toString=function(){return"SafeHtml{"+this.privateDoNotAccessOrElseSafeHtmlWrappedValue_+"}"});
                +goog.html.SafeHtml.unwrap=function(a){if(a instanceof goog.html.SafeHtml&&a.constructor===goog.html.SafeHtml&&a.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeHtmlWrappedValue_;goog.asserts.fail("expected object of type SafeHtml, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeHtml"};
                +goog.html.SafeHtml.htmlEscape=function(a){if(a instanceof goog.html.SafeHtml)return a;var b=null;a.implementsGoogI18nBidiDirectionalString&&(b=a.getDirection());a=a.implementsGoogStringTypedString?a.getTypedStringValue():String(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.htmlEscape(a),b)};
                +goog.html.SafeHtml.htmlEscapePreservingNewlines=function(a){if(a instanceof goog.html.SafeHtml)return a;a=goog.html.SafeHtml.htmlEscape(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.newLineToBr(goog.html.SafeHtml.unwrap(a)),a.getDirection())};
                +goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces=function(a){if(a instanceof goog.html.SafeHtml)return a;a=goog.html.SafeHtml.htmlEscape(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.whitespaceEscape(goog.html.SafeHtml.unwrap(a)),a.getDirection())};goog.html.SafeHtml.from=goog.html.SafeHtml.htmlEscape;goog.html.SafeHtml.VALID_NAMES_IN_TAG_=/^[a-zA-Z0-9-]+$/;
                +goog.html.SafeHtml.URL_ATTRIBUTES_={action:!0,cite:!0,data:!0,formaction:!0,href:!0,manifest:!0,poster:!0,src:!0};goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_={APPLET:!0,BASE:!0,EMBED:!0,IFRAME:!0,LINK:!0,MATH:!0,META:!0,OBJECT:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};goog.html.SafeHtml.create=function(a,b,c){goog.html.SafeHtml.verifyTagName(String(a));return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(String(a),b,c)};
                +goog.html.SafeHtml.verifyTagName=function(a){if(!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(a))throw Error("Invalid tag name <"+a+">.");if(a.toUpperCase()in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_)throw Error("Tag name <"+a+"> is not allowed for SafeHtml.");};
                +goog.html.SafeHtml.createIframe=function(a,b,c,d){a&&goog.html.TrustedResourceUrl.unwrap(a);var e={};e.src=a||null;e.srcdoc=b&&goog.html.SafeHtml.unwrap(b);a=goog.html.SafeHtml.combineAttributes(e,{sandbox:""},c);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe",a,d)};
                +goog.html.SafeHtml.createSandboxIframe=function(a,b,c,d){if(!goog.html.SafeHtml.canUseSandboxIframe())throw Error("The browser does not support sandboxed iframes.");var e={};e.src=a?goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(a)):null;e.srcdoc=b||null;e.sandbox="";a=goog.html.SafeHtml.combineAttributes(e,{},c);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe",a,d)};
                +goog.html.SafeHtml.canUseSandboxIframe=function(){return goog.global.HTMLIFrameElement&&"sandbox"in goog.global.HTMLIFrameElement.prototype};goog.html.SafeHtml.createScriptSrc=function(a,b){goog.html.TrustedResourceUrl.unwrap(a);a=goog.html.SafeHtml.combineAttributes({src:a},{},b);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script",a)};
                +goog.html.SafeHtml.createScript=function(a,b){for(var c in b){var d=c.toLowerCase();if("language"==d||"src"==d||"text"==d||"type"==d)throw Error('Cannot set "'+d+'" attribute');}c="";a=goog.array.concat(a);for(d=0;d<a.length;d++)c+=goog.html.SafeScript.unwrap(a[d]);a=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(c,goog.i18n.bidi.Dir.NEUTRAL);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script",b,a)};
                +goog.html.SafeHtml.createStyle=function(a,b){b=goog.html.SafeHtml.combineAttributes({type:"text/css"},{},b);var c="";a=goog.array.concat(a);for(var d=0;d<a.length;d++)c+=goog.html.SafeStyleSheet.unwrap(a[d]);a=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(c,goog.i18n.bidi.Dir.NEUTRAL);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("style",b,a)};
                +goog.html.SafeHtml.createMetaRefresh=function(a,b){a=goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(a));(goog.labs.userAgent.browser.isIE()||goog.labs.userAgent.browser.isEdge())&&goog.string.contains(a,";")&&(a="'"+a.replace(/'/g,"%27")+"'");return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("meta",{"http-equiv":"refresh",content:(b||0)+"; url="+a})};
                +goog.html.SafeHtml.getAttrNameAndValue_=function(a,b,c){if(c instanceof goog.string.Const)c=goog.string.Const.unwrap(c);else if("style"==b.toLowerCase())c=goog.html.SafeHtml.getStyleValue_(c);else{if(/^on/i.test(b))throw Error('Attribute "'+b+'" requires goog.string.Const value, "'+c+'" given.');if(b.toLowerCase()in goog.html.SafeHtml.URL_ATTRIBUTES_)if(c instanceof goog.html.TrustedResourceUrl)c=goog.html.TrustedResourceUrl.unwrap(c);else if(c instanceof goog.html.SafeUrl)c=goog.html.SafeUrl.unwrap(c);
                +else if(goog.isString(c))c=goog.html.SafeUrl.sanitize(c).getTypedStringValue();else throw Error('Attribute "'+b+'" on tag "'+a+'" requires goog.html.SafeUrl, goog.string.Const, or string, value "'+c+'" given.');}c.implementsGoogStringTypedString&&(c=c.getTypedStringValue());goog.asserts.assert(goog.isString(c)||goog.isNumber(c),"String or number value expected, got "+typeof c+" with value: "+c);return b+'="'+goog.string.htmlEscape(String(c))+'"'};
                +goog.html.SafeHtml.getStyleValue_=function(a){if(!goog.isObject(a))throw Error('The "style" attribute requires goog.html.SafeStyle or map of style properties, '+typeof a+" given: "+a);a instanceof goog.html.SafeStyle||(a=goog.html.SafeStyle.create(a));return goog.html.SafeStyle.unwrap(a)};goog.html.SafeHtml.createWithDir=function(a,b,c,d){b=goog.html.SafeHtml.create(b,c,d);b.dir_=a;return b};
                +goog.html.SafeHtml.concat=function(a){var b=goog.i18n.bidi.Dir.NEUTRAL,c="",d=function(a){goog.isArray(a)?goog.array.forEach(a,d):(a=goog.html.SafeHtml.htmlEscape(a),c+=goog.html.SafeHtml.unwrap(a),a=a.getDirection(),b==goog.i18n.bidi.Dir.NEUTRAL?b=a:a!=goog.i18n.bidi.Dir.NEUTRAL&&b!=a&&(b=null))};goog.array.forEach(arguments,d);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(c,b)};
                +goog.html.SafeHtml.concatWithDir=function(a,b){var c=goog.html.SafeHtml.concat(goog.array.slice(arguments,1));c.dir_=a;return c};goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse=function(a,b){return(new goog.html.SafeHtml).initSecurityPrivateDoNotAccessOrElse_(a,b)};goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a,b){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_=a;this.dir_=b;return this};
                +goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse=function(a,b,c){var d=null;var e="<"+a+goog.html.SafeHtml.stringifyAttributes(a,b);goog.isDefAndNotNull(c)?goog.isArray(c)||(c=[c]):c=[];goog.dom.tags.isVoidTag(a.toLowerCase())?(goog.asserts.assert(!c.length,"Void tag <"+a+"> does not allow content."),e+=">"):(d=goog.html.SafeHtml.concat(c),e+=">"+goog.html.SafeHtml.unwrap(d)+"</"+a+">",d=d.getDirection());(a=b&&b.dir)&&(d=/^(ltr|rtl|auto)$/i.test(a)?goog.i18n.bidi.Dir.NEUTRAL:
                +null);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(e,d)};goog.html.SafeHtml.stringifyAttributes=function(a,b){var c="";if(b)for(var d in b){if(!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(d))throw Error('Invalid attribute name "'+d+'".');var e=b[d];goog.isDefAndNotNull(e)&&(c+=" "+goog.html.SafeHtml.getAttrNameAndValue_(a,d,e))}return c};
                +goog.html.SafeHtml.combineAttributes=function(a,b,c){var d={},e;for(e in a)goog.asserts.assert(e.toLowerCase()==e,"Must be lower case"),d[e]=a[e];for(e in b)goog.asserts.assert(e.toLowerCase()==e,"Must be lower case"),d[e]=b[e];for(e in c){var f=e.toLowerCase();if(f in a)throw Error('Cannot override "'+f+'" attribute, got "'+e+'" with value "'+c[e]+'"');f in b&&delete d[f];d[e]=c[e]}return d};
                +goog.html.SafeHtml.DOCTYPE_HTML=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<!DOCTYPE html>",goog.i18n.bidi.Dir.NEUTRAL);goog.html.SafeHtml.EMPTY=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("",goog.i18n.bidi.Dir.NEUTRAL);goog.html.SafeHtml.BR=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<br>",goog.i18n.bidi.Dir.NEUTRAL);goog.dom.safe={};goog.dom.safe.InsertAdjacentHtmlPosition={AFTERBEGIN:"afterbegin",AFTEREND:"afterend",BEFOREBEGIN:"beforebegin",BEFOREEND:"beforeend"};goog.dom.safe.insertAdjacentHtml=function(a,b,c){a.insertAdjacentHTML(b,goog.html.SafeHtml.unwrap(c))};goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_={MATH:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};
                +goog.dom.safe.setInnerHtml=function(a,b){if(goog.asserts.ENABLE_ASSERTS){var c=a.tagName.toUpperCase();if(goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[c])throw Error("goog.dom.safe.setInnerHtml cannot be used to set content of "+a.tagName+".");}a.innerHTML=goog.html.SafeHtml.unwrap(b)};goog.dom.safe.setOuterHtml=function(a,b){a.outerHTML=goog.html.SafeHtml.unwrap(b)};goog.dom.safe.setStyle=function(a,b){a.style.cssText=goog.html.SafeStyle.unwrap(b)};goog.dom.safe.documentWrite=function(a,b){a.write(goog.html.SafeHtml.unwrap(b))};
                +goog.dom.safe.setAnchorHref=function(a,b){goog.dom.safe.assertIsHTMLAnchorElement_(a);b=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.href=goog.html.SafeUrl.unwrap(b)};goog.dom.safe.setImageSrc=function(a,b){goog.dom.safe.assertIsHTMLImageElement_(a);b=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.src=goog.html.SafeUrl.unwrap(b)};goog.dom.safe.setEmbedSrc=function(a,b){goog.dom.safe.assertIsHTMLEmbedElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};
                +goog.dom.safe.setFrameSrc=function(a,b){goog.dom.safe.assertIsHTMLFrameElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setIframeSrc=function(a,b){goog.dom.safe.assertIsHTMLIFrameElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setIframeSrcdoc=function(a,b){goog.dom.safe.assertIsHTMLIFrameElement_(a);a.srcdoc=goog.html.SafeHtml.unwrap(b)};
                +goog.dom.safe.setLinkHrefAndRel=function(a,b,c){goog.dom.safe.assertIsHTMLLinkElement_(a);a.rel=c;goog.string.caseInsensitiveContains(c,"stylesheet")?(goog.asserts.assert(b instanceof goog.html.TrustedResourceUrl,'URL must be TrustedResourceUrl because "rel" contains "stylesheet"'),a.href=goog.html.TrustedResourceUrl.unwrap(b)):a.href=b instanceof goog.html.TrustedResourceUrl?goog.html.TrustedResourceUrl.unwrap(b):b instanceof goog.html.SafeUrl?goog.html.SafeUrl.unwrap(b):goog.html.SafeUrl.sanitize(b).getTypedStringValue()};
                +goog.dom.safe.setObjectData=function(a,b){goog.dom.safe.assertIsHTMLObjectElement_(a);a.data=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setScriptSrc=function(a,b){goog.dom.safe.assertIsHTMLScriptElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setScriptContent=function(a,b){goog.dom.safe.assertIsHTMLScriptElement_(a);a.text=goog.html.SafeScript.unwrap(b)};
                +goog.dom.safe.setLocationHref=function(a,b){goog.dom.safe.assertIsLocation_(a);b=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.href=goog.html.SafeUrl.unwrap(b)};goog.dom.safe.openInWindow=function(a,b,c,d,e){a=a instanceof goog.html.SafeUrl?a:goog.html.SafeUrl.sanitize(a);return(b||window).open(goog.html.SafeUrl.unwrap(a),c?goog.string.Const.unwrap(c):"",d,e)};
                +goog.dom.safe.assertIsLocation_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof Location||!(a instanceof Element)),"Argument is not a Location (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLAnchorElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLAnchorElement&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLAnchorElement||!(a instanceof Location||a instanceof Element)),"Argument is not a HTMLAnchorElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLLinkElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLLinkElement&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLLinkElement||!(a instanceof Location||a instanceof Element)),"Argument is not a HTMLLinkElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLImageElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLImageElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLImageElement||!(a instanceof Element)),"Argument is not a HTMLImageElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLEmbedElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLEmbedElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLEmbedElement||!(a instanceof Element)),"Argument is not a HTMLEmbedElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLFrameElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLFrameElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLFrameElement||!(a instanceof Element)),"Argument is not a HTMLFrameElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLIFrameElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLIFrameElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLIFrameElement||!(a instanceof Element)),"Argument is not a HTMLIFrameElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLObjectElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLObjectElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLObjectElement||!(a instanceof Element)),"Argument is not a HTMLObjectElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLScriptElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLScriptElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLScriptElement||!(a instanceof Element)),"Argument is not a HTMLScriptElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.debugStringForType_=function(a){return goog.isObject(a)?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):void 0===a?"undefined":null===a?"null":typeof a};goog.html.uncheckedconversions={};goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract=function(a,b,c){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(b,c||null)};
                +goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeStyleSheetFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.trustedResourceUrlFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(b)};goog.math.Coordinate=function(a,b){this.x=goog.isDef(a)?a:0;this.y=goog.isDef(b)?b:0};goog.math.Coordinate.prototype.clone=function(){return new goog.math.Coordinate(this.x,this.y)};goog.DEBUG&&(goog.math.Coordinate.prototype.toString=function(){return"("+this.x+", "+this.y+")"});goog.math.Coordinate.prototype.equals=function(a){return a instanceof goog.math.Coordinate&&goog.math.Coordinate.equals(this,a)};goog.math.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};
                +goog.math.Coordinate.distance=function(a,b){var c=a.x-b.x;a=a.y-b.y;return Math.sqrt(c*c+a*a)};goog.math.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};goog.math.Coordinate.azimuth=function(a){return goog.math.angle(0,0,a.x,a.y)};goog.math.Coordinate.squaredDistance=function(a,b){var c=a.x-b.x;a=a.y-b.y;return c*c+a*a};goog.math.Coordinate.difference=function(a,b){return new goog.math.Coordinate(a.x-b.x,a.y-b.y)};
                +goog.math.Coordinate.sum=function(a,b){return new goog.math.Coordinate(a.x+b.x,a.y+b.y)};goog.math.Coordinate.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};goog.math.Coordinate.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};goog.math.Coordinate.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};
                +goog.math.Coordinate.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.x+=a.x,this.y+=a.y):(this.x+=Number(a),goog.isNumber(b)&&(this.y+=b));return this};goog.math.Coordinate.prototype.scale=function(a,b){b=goog.isNumber(b)?b:a;this.x*=a;this.y*=b;return this};goog.math.Coordinate.prototype.rotateRadians=function(a,b){b=b||new goog.math.Coordinate(0,0);var c=this.x,d=this.y,e=Math.cos(a);a=Math.sin(a);this.x=(c-b.x)*e-(d-b.y)*a+b.x;this.y=(c-b.x)*a+(d-b.y)*e+b.y};
                +goog.math.Coordinate.prototype.rotateDegrees=function(a,b){this.rotateRadians(goog.math.toRadians(a),b)};goog.math.Size=function(a,b){this.width=a;this.height=b};goog.math.Size.equals=function(a,b){return a==b?!0:a&&b?a.width==b.width&&a.height==b.height:!1};goog.math.Size.prototype.clone=function(){return new goog.math.Size(this.width,this.height)};goog.DEBUG&&(goog.math.Size.prototype.toString=function(){return"("+this.width+" x "+this.height+")"});goog.math.Size.prototype.getLongest=function(){return Math.max(this.width,this.height)};
                +goog.math.Size.prototype.getShortest=function(){return Math.min(this.width,this.height)};goog.math.Size.prototype.area=function(){return this.width*this.height};goog.math.Size.prototype.perimeter=function(){return 2*(this.width+this.height)};goog.math.Size.prototype.aspectRatio=function(){return this.width/this.height};goog.math.Size.prototype.isEmpty=function(){return!this.area()};goog.math.Size.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};
                +goog.math.Size.prototype.fitsInside=function(a){return this.width<=a.width&&this.height<=a.height};goog.math.Size.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};goog.math.Size.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Size.prototype.scale=function(a,b){b=goog.isNumber(b)?b:a;this.width*=a;this.height*=b;return this};
                +goog.math.Size.prototype.scaleToCover=function(a){a=this.aspectRatio()<=a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.math.Size.prototype.scaleToFit=function(a){a=this.aspectRatio()>a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)};
                +goog.dom.getElementHelper_=function(a,b){return goog.isString(b)?a.getElementById(b):b};goog.dom.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(document,a)};goog.dom.getRequiredElementHelper_=function(a,b){goog.asserts.assertString(b);a=goog.dom.getElementHelper_(a,b);return a=goog.asserts.assertElement(a,"No element found with id: "+b)};goog.dom.$=goog.dom.getElement;goog.dom.getElementsByTagName=function(a,b){return(b||document).getElementsByTagName(String(a))};
                +goog.dom.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(document,a,b,c)};goog.dom.getElementsByClass=function(a,b){var c=b||document;return goog.dom.canUseQuerySelector_(c)?c.querySelectorAll("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)};
                +goog.dom.getElementByClass=function(a,b){var c=b||document;return(c.getElementsByClassName?c.getElementsByClassName(a)[0]:goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)[0])||null};goog.dom.getRequiredElementByClass=function(a,b){b=goog.dom.getElementByClass(a,b);return goog.asserts.assert(b,"No element found with className: "+a)};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)};
                +goog.dom.getElementsByTagNameAndClass_=function(a,b,c,d){a=d||a;var e=b&&"*"!=b?String(b).toUpperCase():"";if(goog.dom.canUseQuerySelector_(a)&&(e||c))return a.querySelectorAll(e+(c?"."+c:""));if(c&&a.getElementsByClassName){d=a.getElementsByClassName(c);if(e){a={};for(var f=b=0,g;g=d[f];f++)e==g.nodeName&&(a[b++]=g);a.length=b;return a}return d}d=a.getElementsByTagName(e||"*");if(c){a={};for(f=b=0;g=d[f];f++)e=g.className,"function"==typeof e.split&&goog.array.contains(e.split(/\s+/),c)&&(a[b++]=
                +g);a.length=b;return a}return d};goog.dom.$$=goog.dom.getElementsByTagNameAndClass;goog.dom.setProperties=function(a,b){goog.object.forEach(b,function(b,d){b&&b.implementsGoogStringTypedString&&(b=b.getTypedStringValue());"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(d)?a.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[d],b):goog.string.startsWith(d,"aria-")||goog.string.startsWith(d,"data-")?a.setAttribute(d,b):a[d]=b})};
                +goog.dom.DIRECT_ATTRIBUTE_MAP_={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};goog.dom.getViewportSize=function(a){return goog.dom.getViewportSize_(a||window)};goog.dom.getViewportSize_=function(a){a=a.document;a=goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body;return new goog.math.Size(a.clientWidth,a.clientHeight)};
                +goog.dom.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(window)};goog.dom.getDocumentHeightForWindow=function(a){return goog.dom.getDocumentHeight_(a)};
                +goog.dom.getDocumentHeight_=function(a){var b=a.document,c=0;if(b){var c=b.body,d=b.documentElement;if(!d||!c)return 0;a=goog.dom.getViewportSize_(a).height;if(goog.dom.isCss1CompatMode_(b)&&d.scrollHeight)c=d.scrollHeight!=a?d.scrollHeight:d.offsetHeight;else{var b=d.scrollHeight,e=d.offsetHeight;d.clientHeight!=e&&(b=c.scrollHeight,e=c.offsetHeight);c=b>a?b>e?b:e:b<e?b:e}}return c};goog.dom.getPageScroll=function(a){return goog.dom.getDomHelper((a||goog.global||window).document).getDocumentScroll()};
                +goog.dom.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(document)};goog.dom.getDocumentScroll_=function(a){var b=goog.dom.getDocumentScrollElement_(a);a=goog.dom.getWindow_(a);return goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("10")&&a.pageYOffset!=b.scrollTop?new goog.math.Coordinate(b.scrollLeft,b.scrollTop):new goog.math.Coordinate(a.pageXOffset||b.scrollLeft,a.pageYOffset||b.scrollTop)};goog.dom.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(document)};
                +goog.dom.getDocumentScrollElement_=function(a){return a.scrollingElement?a.scrollingElement:!goog.userAgent.WEBKIT&&goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body||a.documentElement};goog.dom.getWindow=function(a){return a?goog.dom.getWindow_(a):window};goog.dom.getWindow_=function(a){return a.parentWindow||a.defaultView};goog.dom.createDom=function(a,b,c){return goog.dom.createDom_(document,arguments)};
                +goog.dom.createDom_=function(a,b){var c=String(b[0]),d=b[1];if(!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES&&d&&(d.name||d.type)){c=["<",c];d.name&&c.push(' name="',goog.string.htmlEscape(d.name),'"');if(d.type){c.push(' type="',goog.string.htmlEscape(d.type),'"');var e={};goog.object.extend(e,d);delete e.type;d=e}c.push(">");c=c.join("")}c=a.createElement(c);d&&(goog.isString(d)?c.className=d:goog.isArray(d)?c.className=d.join(" "):goog.dom.setProperties(c,d));2<b.length&&goog.dom.append_(a,
                +c,b,2);return c};goog.dom.append_=function(a,b,c,d){function e(c){c&&b.appendChild(goog.isString(c)?a.createTextNode(c):c)}for(;d<c.length;d++){var f=c[d];goog.isArrayLike(f)&&!goog.dom.isNodeLike(f)?goog.array.forEach(goog.dom.isNodeList(f)?goog.array.toArray(f):f,e):e(f)}};goog.dom.$dom=goog.dom.createDom;goog.dom.createElement=function(a){return goog.dom.createElement_(document,a)};goog.dom.createElement_=function(a,b){return a.createElement(String(b))};goog.dom.createTextNode=function(a){return document.createTextNode(String(a))};
                +goog.dom.createTable=function(a,b,c){return goog.dom.createTable_(document,a,b,!!c)};goog.dom.createTable_=function(a,b,c,d){for(var e=goog.dom.createElement_(a,"TABLE"),f=e.appendChild(goog.dom.createElement_(a,"TBODY")),g=0;g<b;g++){for(var h=goog.dom.createElement_(a,"TR"),k=0;k<c;k++){var l=goog.dom.createElement_(a,"TD");d&&goog.dom.setTextContent(l,goog.string.Unicode.NBSP);h.appendChild(l)}f.appendChild(h)}return e};
                +goog.dom.constHtmlToNode=function(a){var b=goog.array.map(arguments,goog.string.Const.unwrap),b=goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("Constant HTML string, that gets turned into a Node later, so it will be automatically balanced."),b.join(""));return goog.dom.safeHtmlToNode(b)};goog.dom.safeHtmlToNode=function(a){return goog.dom.safeHtmlToNode_(document,a)};
                +goog.dom.safeHtmlToNode_=function(a,b){var c=goog.dom.createElement_(a,"DIV");goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT?(goog.dom.safe.setInnerHtml(c,goog.html.SafeHtml.concat(goog.html.SafeHtml.BR,b)),c.removeChild(c.firstChild)):goog.dom.safe.setInnerHtml(c,b);return goog.dom.childrenToNode_(a,c)};goog.dom.childrenToNode_=function(a,b){if(1==b.childNodes.length)return b.removeChild(b.firstChild);for(a=a.createDocumentFragment();b.firstChild;)a.appendChild(b.firstChild);return a};
                +goog.dom.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(document)};goog.dom.isCss1CompatMode_=function(a){return goog.dom.COMPAT_MODE_KNOWN_?goog.dom.ASSUME_STANDARDS_MODE:"CSS1Compat"==a.compatMode};goog.dom.canHaveChildren=function(a){if(a.nodeType!=goog.dom.NodeType.ELEMENT)return!1;switch(a.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "COMMAND":case "EMBED":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "KEYGEN":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case "SCRIPT":case "SOURCE":case "STYLE":case "TRACK":case "WBR":return!1}return!0};
                +goog.dom.appendChild=function(a,b){a.appendChild(b)};goog.dom.append=function(a,b){goog.dom.append_(goog.dom.getOwnerDocument(a),a,arguments,1)};goog.dom.removeChildren=function(a){for(var b;b=a.firstChild;)a.removeChild(b)};goog.dom.insertSiblingBefore=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b)};goog.dom.insertSiblingAfter=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b.nextSibling)};goog.dom.insertChildAt=function(a,b,c){a.insertBefore(b,a.childNodes[c]||null)};
                +goog.dom.removeNode=function(a){return a&&a.parentNode?a.parentNode.removeChild(a):null};goog.dom.replaceNode=function(a,b){var c=b.parentNode;c&&c.replaceChild(a,b)};goog.dom.flattenElement=function(a){var b,c=a.parentNode;if(c&&c.nodeType!=goog.dom.NodeType.DOCUMENT_FRAGMENT){if(a.removeNode)return a.removeNode(!1);for(;b=a.firstChild;)c.insertBefore(b,a);return goog.dom.removeNode(a)}};
                +goog.dom.getChildren=function(a){return goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE&&void 0!=a.children?a.children:goog.array.filter(a.childNodes,function(a){return a.nodeType==goog.dom.NodeType.ELEMENT})};goog.dom.getFirstElementChild=function(a){return goog.isDef(a.firstElementChild)?a.firstElementChild:goog.dom.getNextElementNode_(a.firstChild,!0)};goog.dom.getLastElementChild=function(a){return goog.isDef(a.lastElementChild)?a.lastElementChild:goog.dom.getNextElementNode_(a.lastChild,!1)};
                +goog.dom.getNextElementSibling=function(a){return goog.isDef(a.nextElementSibling)?a.nextElementSibling:goog.dom.getNextElementNode_(a.nextSibling,!0)};goog.dom.getPreviousElementSibling=function(a){return goog.isDef(a.previousElementSibling)?a.previousElementSibling:goog.dom.getNextElementNode_(a.previousSibling,!1)};goog.dom.getNextElementNode_=function(a,b){for(;a&&a.nodeType!=goog.dom.NodeType.ELEMENT;)a=b?a.nextSibling:a.previousSibling;return a};
                +goog.dom.getNextNode=function(a){if(!a)return null;if(a.firstChild)return a.firstChild;for(;a&&!a.nextSibling;)a=a.parentNode;return a?a.nextSibling:null};goog.dom.getPreviousNode=function(a){if(!a)return null;if(!a.previousSibling)return a.parentNode;for(a=a.previousSibling;a&&a.lastChild;)a=a.lastChild;return a};goog.dom.isNodeLike=function(a){return goog.isObject(a)&&0<a.nodeType};goog.dom.isElement=function(a){return goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT};
                +goog.dom.isWindow=function(a){return goog.isObject(a)&&a.window==a};goog.dom.getParentElement=function(a){var b;if(goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY&&!(goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("9")&&!goog.userAgent.isVersionOrHigher("10")&&goog.global.SVGElement&&a instanceof goog.global.SVGElement)&&(b=a.parentElement))return b;b=a.parentNode;return goog.dom.isElement(b)?b:null};
                +goog.dom.contains=function(a,b){if(!a||!b)return!1;if(a.contains&&b.nodeType==goog.dom.NodeType.ELEMENT)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||!!(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};
                +goog.dom.compareNodeOrder=function(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)){if(a.nodeType==goog.dom.NodeType.DOCUMENT)return-1;if(b.nodeType==goog.dom.NodeType.DOCUMENT)return 1}if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=a.nodeType==goog.dom.NodeType.ELEMENT,d=b.nodeType==goog.dom.NodeType.ELEMENT;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,
                +f=b.parentNode;return e==f?goog.dom.compareSiblingOrder_(a,b):!c&&goog.dom.contains(e,b)?-1*goog.dom.compareParentsDescendantNodeIe_(a,b):!d&&goog.dom.contains(f,a)?goog.dom.compareParentsDescendantNodeIe_(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=goog.dom.getOwnerDocument(a);c=d.createRange();c.selectNode(a);c.collapse(!0);a=d.createRange();a.selectNode(b);a.collapse(!0);return c.compareBoundaryPoints(goog.global.Range.START_TO_END,a)};
                +goog.dom.compareParentsDescendantNodeIe_=function(a,b){var c=a.parentNode;if(c==b)return-1;for(;b.parentNode!=c;)b=b.parentNode;return goog.dom.compareSiblingOrder_(b,a)};goog.dom.compareSiblingOrder_=function(a,b){for(;b=b.previousSibling;)if(b==a)return-1;return 1};
                +goog.dom.findCommonAncestor=function(a){var b,c=arguments.length;if(!c)return null;if(1==c)return arguments[0];var d=[],e=Infinity;for(b=0;b<c;b++){for(var f=[],g=arguments[b];g;)f.unshift(g),g=g.parentNode;d.push(f);e=Math.min(e,f.length)}f=null;for(b=0;b<e;b++){for(var g=d[0][b],h=1;h<c;h++)if(g!=d[h][b])return f;f=g}return f};goog.dom.getOwnerDocument=function(a){goog.asserts.assert(a,"Node cannot be null or undefined.");return a.nodeType==goog.dom.NodeType.DOCUMENT?a:a.ownerDocument||a.document};
                +goog.dom.getFrameContentDocument=function(a){return a.contentDocument||a.contentWindow.document};goog.dom.getFrameContentWindow=function(a){try{return a.contentWindow||(a.contentDocument?goog.dom.getWindow(a.contentDocument):null)}catch(b){}return null};
                +goog.dom.setTextContent=function(a,b){goog.asserts.assert(null!=a,"goog.dom.setTextContent expects a non-null value for node");if("textContent"in a)a.textContent=b;else if(a.nodeType==goog.dom.NodeType.TEXT)a.data=b;else if(a.firstChild&&a.firstChild.nodeType==goog.dom.NodeType.TEXT){for(;a.lastChild!=a.firstChild;)a.removeChild(a.lastChild);a.firstChild.data=b}else{goog.dom.removeChildren(a);var c=goog.dom.getOwnerDocument(a);a.appendChild(c.createTextNode(String(b)))}};
                +goog.dom.getOuterHtml=function(a){goog.asserts.assert(null!==a,"goog.dom.getOuterHtml expects a non-null value for element");if("outerHTML"in a)return a.outerHTML;var b=goog.dom.getOwnerDocument(a),b=goog.dom.createElement_(b,"DIV");b.appendChild(a.cloneNode(!0));return b.innerHTML};goog.dom.findNode=function(a,b){var c=[];return goog.dom.findNodes_(a,b,c,!0)?c[0]:void 0};goog.dom.findNodes=function(a,b){var c=[];goog.dom.findNodes_(a,b,c,!1);return c};
                +goog.dom.findNodes_=function(a,b,c,d){if(null!=a)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||goog.dom.findNodes_(a,b,c,d))return!0;a=a.nextSibling}return!1};goog.dom.TAGS_TO_IGNORE_={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1};goog.dom.PREDEFINED_TAG_VALUES_={IMG:" ",BR:"\n"};goog.dom.isFocusableTabIndex=function(a){return goog.dom.hasSpecifiedTabIndex_(a)&&goog.dom.isTabIndexFocusable_(a)};goog.dom.setFocusableTabIndex=function(a,b){b?a.tabIndex=0:(a.tabIndex=-1,a.removeAttribute("tabIndex"))};
                +goog.dom.isFocusable=function(a){var b;return(b=goog.dom.nativelySupportsFocus_(a)?!a.disabled&&(!goog.dom.hasSpecifiedTabIndex_(a)||goog.dom.isTabIndexFocusable_(a)):goog.dom.isFocusableTabIndex(a))&&goog.userAgent.IE?goog.dom.hasNonZeroBoundingRect_(a):b};goog.dom.hasSpecifiedTabIndex_=function(a){return goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9")?(a=a.getAttributeNode("tabindex"),goog.isDefAndNotNull(a)&&a.specified):a.hasAttribute("tabindex")};
                +goog.dom.isTabIndexFocusable_=function(a){a=a.tabIndex;return goog.isNumber(a)&&0<=a&&32768>a};goog.dom.nativelySupportsFocus_=function(a){return"A"==a.tagName||"INPUT"==a.tagName||"TEXTAREA"==a.tagName||"SELECT"==a.tagName||"BUTTON"==a.tagName};goog.dom.hasNonZeroBoundingRect_=function(a){a=!goog.isFunction(a.getBoundingClientRect)||goog.userAgent.IE&&null==a.parentElement?{height:a.offsetHeight,width:a.offsetWidth}:a.getBoundingClientRect();return goog.isDefAndNotNull(a)&&0<a.height&&0<a.width};
                +goog.dom.getTextContent=function(a){if(goog.dom.BrowserFeature.CAN_USE_INNER_TEXT&&null!==a&&"innerText"in a)a=goog.string.canonicalizeNewlines(a.innerText);else{var b=[];goog.dom.getTextContent_(a,b,!0);a=b.join("")}a=a.replace(/ \xAD /g," ").replace(/\xAD/g,"");a=a.replace(/\u200B/g,"");goog.dom.BrowserFeature.CAN_USE_INNER_TEXT||(a=a.replace(/ +/g," "));" "!=a&&(a=a.replace(/^\s*/,""));return a};goog.dom.getRawTextContent=function(a){var b=[];goog.dom.getTextContent_(a,b,!1);return b.join("")};
                +goog.dom.getTextContent_=function(a,b,c){if(!(a.nodeName in goog.dom.TAGS_TO_IGNORE_))if(a.nodeType==goog.dom.NodeType.TEXT)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)b.push(goog.dom.PREDEFINED_TAG_VALUES_[a.nodeName]);else for(a=a.firstChild;a;)goog.dom.getTextContent_(a,b,c),a=a.nextSibling};goog.dom.getNodeTextLength=function(a){return goog.dom.getTextContent(a).length};
                +goog.dom.getNodeTextOffset=function(a,b){b=b||goog.dom.getOwnerDocument(a).body;for(var c=[];a&&a!=b;){for(var d=a;d=d.previousSibling;)c.unshift(goog.dom.getTextContent(d));a=a.parentNode}return goog.string.trimLeft(c.join("")).replace(/ +/g," ").length};
                +goog.dom.getNodeAtOffset=function(a,b,c){a=[a];for(var d=0,e=null;0<a.length&&d<b;)if(e=a.pop(),!(e.nodeName in goog.dom.TAGS_TO_IGNORE_))if(e.nodeType==goog.dom.NodeType.TEXT)var f=e.nodeValue.replace(/(\r\n|\r|\n)/g,"").replace(/ +/g," "),d=d+f.length;else if(e.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)d+=goog.dom.PREDEFINED_TAG_VALUES_[e.nodeName].length;else for(f=e.childNodes.length-1;0<=f;f--)a.push(e.childNodes[f]);goog.isObject(c)&&(c.remainder=e?e.nodeValue.length+b-d-1:0,c.node=e);return e};
                +goog.dom.isNodeList=function(a){if(a&&"number"==typeof a.length){if(goog.isObject(a))return"function"==typeof a.item||"string"==typeof a.item;if(goog.isFunction(a))return"function"==typeof a.item}return!1};goog.dom.getAncestorByTagNameAndClass=function(a,b,c,d){if(!b&&!c)return null;var e=b?String(b).toUpperCase():null;return goog.dom.getAncestor(a,function(a){return(!e||a.nodeName==e)&&(!c||goog.isString(a.className)&&goog.array.contains(a.className.split(/\s+/),c))},!0,d)};
                +goog.dom.getAncestorByClass=function(a,b,c){return goog.dom.getAncestorByTagNameAndClass(a,null,b,c)};goog.dom.getAncestor=function(a,b,c,d){a&&!c&&(a=a.parentNode);for(c=0;a&&(null==d||c<=d);){goog.asserts.assert("parentNode"!=a.name);if(b(a))return a;a=a.parentNode;c++}return null};goog.dom.getActiveElement=function(a){try{return a&&a.activeElement}catch(b){}return null};
                +goog.dom.getPixelRatio=function(){var a=goog.dom.getWindow();return goog.isDef(a.devicePixelRatio)?a.devicePixelRatio:a.matchMedia?goog.dom.matchesPixelRatio_(3)||goog.dom.matchesPixelRatio_(2)||goog.dom.matchesPixelRatio_(1.5)||goog.dom.matchesPixelRatio_(1)||.75:1};goog.dom.matchesPixelRatio_=function(a){return goog.dom.getWindow().matchMedia("(min-resolution: "+a+"dppx),(min--moz-device-pixel-ratio: "+a+"),(min-resolution: "+96*a+"dpi)").matches?a:0};goog.dom.getCanvasContext2D=function(a){return a.getContext("2d")};
                +goog.dom.DomHelper=function(a){this.document_=a||goog.global.document||document};goog.dom.DomHelper.prototype.getDomHelper=goog.dom.getDomHelper;goog.dom.DomHelper.prototype.setDocument=function(a){this.document_=a};goog.dom.DomHelper.prototype.getDocument=function(){return this.document_};goog.dom.DomHelper.prototype.getElement=function(a){return goog.dom.getElementHelper_(this.document_,a)};
                +goog.dom.DomHelper.prototype.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.$=goog.dom.DomHelper.prototype.getElement;goog.dom.DomHelper.prototype.getElementsByTagName=function(a,b){return(b||this.document_).getElementsByTagName(String(a))};goog.dom.DomHelper.prototype.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(this.document_,a,b,c)};
                +goog.dom.DomHelper.prototype.getElementsByClass=function(a,b){return goog.dom.getElementsByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getElementByClass=function(a,b){return goog.dom.getElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getRequiredElementByClass=function(a,b){return goog.dom.getRequiredElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.$$=goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
                +goog.dom.DomHelper.prototype.setProperties=goog.dom.setProperties;goog.dom.DomHelper.prototype.getViewportSize=function(a){return goog.dom.getViewportSize(a||this.getWindow())};goog.dom.DomHelper.prototype.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(this.getWindow())};goog.dom.DomHelper.prototype.createDom=function(a,b,c){return goog.dom.createDom_(this.document_,arguments)};goog.dom.DomHelper.prototype.$dom=goog.dom.DomHelper.prototype.createDom;
                +goog.dom.DomHelper.prototype.createElement=function(a){return goog.dom.createElement_(this.document_,a)};goog.dom.DomHelper.prototype.createTextNode=function(a){return this.document_.createTextNode(String(a))};goog.dom.DomHelper.prototype.createTable=function(a,b,c){return goog.dom.createTable_(this.document_,a,b,!!c)};goog.dom.DomHelper.prototype.safeHtmlToNode=function(a){return goog.dom.safeHtmlToNode_(this.document_,a)};goog.dom.DomHelper.prototype.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(this.document_)};
                +goog.dom.DomHelper.prototype.getWindow=function(){return goog.dom.getWindow_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(this.document_)};goog.dom.DomHelper.prototype.getActiveElement=function(a){return goog.dom.getActiveElement(a||this.document_)};goog.dom.DomHelper.prototype.appendChild=goog.dom.appendChild;
                +goog.dom.DomHelper.prototype.append=goog.dom.append;goog.dom.DomHelper.prototype.canHaveChildren=goog.dom.canHaveChildren;goog.dom.DomHelper.prototype.removeChildren=goog.dom.removeChildren;goog.dom.DomHelper.prototype.insertSiblingBefore=goog.dom.insertSiblingBefore;goog.dom.DomHelper.prototype.insertSiblingAfter=goog.dom.insertSiblingAfter;goog.dom.DomHelper.prototype.insertChildAt=goog.dom.insertChildAt;goog.dom.DomHelper.prototype.removeNode=goog.dom.removeNode;
                +goog.dom.DomHelper.prototype.replaceNode=goog.dom.replaceNode;goog.dom.DomHelper.prototype.flattenElement=goog.dom.flattenElement;goog.dom.DomHelper.prototype.getChildren=goog.dom.getChildren;goog.dom.DomHelper.prototype.getFirstElementChild=goog.dom.getFirstElementChild;goog.dom.DomHelper.prototype.getLastElementChild=goog.dom.getLastElementChild;goog.dom.DomHelper.prototype.getNextElementSibling=goog.dom.getNextElementSibling;goog.dom.DomHelper.prototype.getPreviousElementSibling=goog.dom.getPreviousElementSibling;
                +goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper.prototype.getPreviousNode=goog.dom.getPreviousNode;goog.dom.DomHelper.prototype.isNodeLike=goog.dom.isNodeLike;goog.dom.DomHelper.prototype.isElement=goog.dom.isElement;goog.dom.DomHelper.prototype.isWindow=goog.dom.isWindow;goog.dom.DomHelper.prototype.getParentElement=goog.dom.getParentElement;goog.dom.DomHelper.prototype.contains=goog.dom.contains;goog.dom.DomHelper.prototype.compareNodeOrder=goog.dom.compareNodeOrder;
                +goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode;
                +goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset;
                +goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.dom.DomHelper.prototype.getCanvasContext2D=goog.dom.getCanvasContext2D;goog.dom.vendor={};goog.dom.vendor.getVendorJsPrefix=function(){return goog.userAgent.WEBKIT?"Webkit":goog.userAgent.GECKO?"Moz":goog.userAgent.IE?"ms":goog.userAgent.OPERA?"O":null};goog.dom.vendor.getVendorPrefix=function(){return goog.userAgent.WEBKIT?"-webkit":goog.userAgent.GECKO?"-moz":goog.userAgent.IE?"-ms":goog.userAgent.OPERA?"-o":null};
                +goog.dom.vendor.getPrefixedPropertyName=function(a,b){if(b&&a in b)return a;var c=goog.dom.vendor.getVendorJsPrefix();return c?(c=c.toLowerCase(),a=c+goog.string.toTitleCase(a),!goog.isDef(b)||a in b?a:null):null};goog.dom.vendor.getPrefixedEventType=function(a){return((goog.dom.vendor.getVendorJsPrefix()||"")+a).toLowerCase()};goog.html.legacyconversions={};goog.html.legacyconversions.safeHtmlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(a,null)};goog.html.legacyconversions.safeStyleFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.legacyconversions.safeStyleSheetFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(a)};goog.html.legacyconversions.safeUrlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.legacyconversions.trustedResourceUrlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.legacyconversions.reportCallback_=goog.nullFunction;goog.html.legacyconversions.setReportCallback=function(a){goog.html.legacyconversions.reportCallback_=a};goog.math.Box=function(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d};goog.math.Box.boundingBox=function(a){for(var b=new goog.math.Box(arguments[0].y,arguments[0].x,arguments[0].y,arguments[0].x),c=1;c<arguments.length;c++)b.expandToIncludeCoordinate(arguments[c]);return b};goog.math.Box.prototype.getWidth=function(){return this.right-this.left};goog.math.Box.prototype.getHeight=function(){return this.bottom-this.top};
                +goog.math.Box.prototype.clone=function(){return new goog.math.Box(this.top,this.right,this.bottom,this.left)};goog.DEBUG&&(goog.math.Box.prototype.toString=function(){return"("+this.top+"t, "+this.right+"r, "+this.bottom+"b, "+this.left+"l)"});goog.math.Box.prototype.contains=function(a){return goog.math.Box.contains(this,a)};
                +goog.math.Box.prototype.expand=function(a,b,c,d){goog.isObject(a)?(this.top-=a.top,this.right+=a.right,this.bottom+=a.bottom,this.left-=a.left):(this.top-=a,this.right+=Number(b),this.bottom+=Number(c),this.left-=Number(d));return this};goog.math.Box.prototype.expandToInclude=function(a){this.left=Math.min(this.left,a.left);this.top=Math.min(this.top,a.top);this.right=Math.max(this.right,a.right);this.bottom=Math.max(this.bottom,a.bottom)};
                +goog.math.Box.prototype.expandToIncludeCoordinate=function(a){this.top=Math.min(this.top,a.y);this.right=Math.max(this.right,a.x);this.bottom=Math.max(this.bottom,a.y);this.left=Math.min(this.left,a.x)};goog.math.Box.equals=function(a,b){return a==b?!0:a&&b?a.top==b.top&&a.right==b.right&&a.bottom==b.bottom&&a.left==b.left:!1};
                +goog.math.Box.contains=function(a,b){return a&&b?b instanceof goog.math.Box?b.left>=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom:b.x>=a.left&&b.x<=a.right&&b.y>=a.top&&b.y<=a.bottom:!1};goog.math.Box.relativePositionX=function(a,b){return b.x<a.left?b.x-a.left:b.x>a.right?b.x-a.right:0};goog.math.Box.relativePositionY=function(a,b){return b.y<a.top?b.y-a.top:b.y>a.bottom?b.y-a.bottom:0};
                +goog.math.Box.distance=function(a,b){var c=goog.math.Box.relativePositionX(a,b);a=goog.math.Box.relativePositionY(a,b);return Math.sqrt(c*c+a*a)};goog.math.Box.intersects=function(a,b){return a.left<=b.right&&b.left<=a.right&&a.top<=b.bottom&&b.top<=a.bottom};goog.math.Box.intersectsWithPadding=function(a,b,c){return a.left<=b.right+c&&b.left<=a.right+c&&a.top<=b.bottom+c&&b.top<=a.bottom+c};
                +goog.math.Box.prototype.ceil=function(){this.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};goog.math.Box.prototype.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};
                +goog.math.Box.prototype.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};goog.math.Box.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(goog.asserts.assertNumber(a),this.left+=a,this.right+=a,goog.isNumber(b)&&(this.top+=b,this.bottom+=b));return this};
                +goog.math.Box.prototype.scale=function(a,b){b=goog.isNumber(b)?b:a;this.left*=a;this.right*=a;this.top*=b;this.bottom*=b;return this};goog.math.IRect=function(){};goog.math.Rect=function(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d};goog.math.Rect.prototype.clone=function(){return new goog.math.Rect(this.left,this.top,this.width,this.height)};goog.math.Rect.prototype.toBox=function(){return new goog.math.Box(this.top,this.left+this.width,this.top+this.height,this.left)};goog.math.Rect.createFromPositionAndSize=function(a,b){return new goog.math.Rect(a.x,a.y,b.width,b.height)};
                +goog.math.Rect.createFromBox=function(a){return new goog.math.Rect(a.left,a.top,a.right-a.left,a.bottom-a.top)};goog.DEBUG&&(goog.math.Rect.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"});goog.math.Rect.equals=function(a,b){return a==b?!0:a&&b?a.left==b.left&&a.width==b.width&&a.top==b.top&&a.height==b.height:!1};
                +goog.math.Rect.prototype.intersection=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,!0}return!1};
                +goog.math.Rect.intersection=function(a,b){var c=Math.max(a.left,b.left),d=Math.min(a.left+a.width,b.left+b.width);if(c<=d){var e=Math.max(a.top,b.top);a=Math.min(a.top+a.height,b.top+b.height);if(e<=a)return new goog.math.Rect(c,e,d-c,a-e)}return null};goog.math.Rect.intersects=function(a,b){return a.left<=b.left+b.width&&b.left<=a.left+a.width&&a.top<=b.top+b.height&&b.top<=a.top+a.height};goog.math.Rect.prototype.intersects=function(a){return goog.math.Rect.intersects(this,a)};
                +goog.math.Rect.difference=function(a,b){var c=goog.math.Rect.intersection(a,b);if(!c||!c.height||!c.width)return[a.clone()];var c=[],d=a.top,e=a.height,f=a.left+a.width,g=a.top+a.height,h=b.left+b.width,k=b.top+b.height;b.top>a.top&&(c.push(new goog.math.Rect(a.left,a.top,a.width,b.top-a.top)),d=b.top,e-=b.top-a.top);k<g&&(c.push(new goog.math.Rect(a.left,k,a.width,g-k)),e=k-d);b.left>a.left&&c.push(new goog.math.Rect(a.left,d,b.left-a.left,e));h<f&&c.push(new goog.math.Rect(h,d,f-h,e));return c};
                +goog.math.Rect.prototype.difference=function(a){return goog.math.Rect.difference(this,a)};goog.math.Rect.prototype.boundingRect=function(a){var b=Math.max(this.left+this.width,a.left+a.width),c=Math.max(this.top+this.height,a.top+a.height);this.left=Math.min(this.left,a.left);this.top=Math.min(this.top,a.top);this.width=b-this.left;this.height=c-this.top};goog.math.Rect.boundingRect=function(a,b){if(!a||!b)return null;a=new goog.math.Rect(a.left,a.top,a.width,a.height);a.boundingRect(b);return a};
                +goog.math.Rect.prototype.contains=function(a){return a instanceof goog.math.Coordinate?a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height:this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height};goog.math.Rect.prototype.squaredDistance=function(a){var b=a.x<this.left?this.left-a.x:Math.max(a.x-(this.left+this.width),0);a=a.y<this.top?this.top-a.y:Math.max(a.y-(this.top+this.height),0);return b*b+a*a};
                +goog.math.Rect.prototype.distance=function(a){return Math.sqrt(this.squaredDistance(a))};goog.math.Rect.prototype.getSize=function(){return new goog.math.Size(this.width,this.height)};goog.math.Rect.prototype.getTopLeft=function(){return new goog.math.Coordinate(this.left,this.top)};goog.math.Rect.prototype.getCenter=function(){return new goog.math.Coordinate(this.left+this.width/2,this.top+this.height/2)};
                +goog.math.Rect.prototype.getBottomRight=function(){return new goog.math.Coordinate(this.left+this.width,this.top+this.height)};goog.math.Rect.prototype.ceil=function(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};goog.math.Rect.prototype.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};
                +goog.math.Rect.prototype.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Rect.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.top+=a.y):(this.left+=goog.asserts.assertNumber(a),goog.isNumber(b)&&(this.top+=b));return this};
                +goog.math.Rect.prototype.scale=function(a,b){b=goog.isNumber(b)?b:a;this.left*=a;this.width*=a;this.top*=b;this.height*=b;return this};goog.style={};goog.style.setStyle=function(a,b,c){if(goog.isString(b))goog.style.setStyle_(a,c,b);else for(var d in b)goog.style.setStyle_(a,b[d],d)};goog.style.setStyle_=function(a,b,c){(c=goog.style.getVendorJsStyleName_(a,c))&&(a.style[c]=b)};goog.style.styleNameCache_={};
                +goog.style.getVendorJsStyleName_=function(a,b){var c=goog.style.styleNameCache_[b];if(!c){var d=goog.string.toCamelCase(b),c=d;void 0===a.style[d]&&(d=goog.dom.vendor.getVendorJsPrefix()+goog.string.toTitleCase(d),void 0!==a.style[d]&&(c=d));goog.style.styleNameCache_[b]=c}return c};
                +goog.style.getVendorStyleName_=function(a,b){var c=goog.string.toCamelCase(b);return void 0===a.style[c]&&(c=goog.dom.vendor.getVendorJsPrefix()+goog.string.toTitleCase(c),void 0!==a.style[c])?goog.dom.vendor.getVendorPrefix()+"-"+b:b};goog.style.getStyle=function(a,b){var c=a.style[goog.string.toCamelCase(b)];return"undefined"!==typeof c?c:a.style[goog.style.getVendorJsStyleName_(a,b)]||""};
                +goog.style.getComputedStyle=function(a,b){var c=goog.dom.getOwnerDocument(a);return c.defaultView&&c.defaultView.getComputedStyle&&(a=c.defaultView.getComputedStyle(a,null))?a[b]||a.getPropertyValue(b)||"":""};goog.style.getCascadedStyle=function(a,b){return a.currentStyle?a.currentStyle[b]:null};goog.style.getStyle_=function(a,b){return goog.style.getComputedStyle(a,b)||goog.style.getCascadedStyle(a,b)||a.style&&a.style[b]};
                +goog.style.getComputedBoxSizing=function(a){return goog.style.getStyle_(a,"boxSizing")||goog.style.getStyle_(a,"MozBoxSizing")||goog.style.getStyle_(a,"WebkitBoxSizing")||null};goog.style.getComputedPosition=function(a){return goog.style.getStyle_(a,"position")};goog.style.getBackgroundColor=function(a){return goog.style.getStyle_(a,"backgroundColor")};goog.style.getComputedOverflowX=function(a){return goog.style.getStyle_(a,"overflowX")};
                +goog.style.getComputedOverflowY=function(a){return goog.style.getStyle_(a,"overflowY")};goog.style.getComputedZIndex=function(a){return goog.style.getStyle_(a,"zIndex")};goog.style.getComputedTextAlign=function(a){return goog.style.getStyle_(a,"textAlign")};goog.style.getComputedCursor=function(a){return goog.style.getStyle_(a,"cursor")};goog.style.getComputedTransform=function(a){var b=goog.style.getVendorStyleName_(a,"transform");return goog.style.getStyle_(a,b)||goog.style.getStyle_(a,"transform")};
                +goog.style.setPosition=function(a,b,c){if(b instanceof goog.math.Coordinate){var d=b.x;b=b.y}else d=b,b=c;a.style.left=goog.style.getPixelStyleValue_(d,!1);a.style.top=goog.style.getPixelStyleValue_(b,!1)};goog.style.getPosition=function(a){return new goog.math.Coordinate(a.offsetLeft,a.offsetTop)};
                +goog.style.getClientViewportElement=function(a){a=a?goog.dom.getOwnerDocument(a):goog.dom.getDocument();return!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9)||goog.dom.getDomHelper(a).isCss1CompatMode()?a.documentElement:a.body};goog.style.getViewportPageOffset=function(a){var b=a.body;a=a.documentElement;return new goog.math.Coordinate(b.scrollLeft||a.scrollLeft,b.scrollTop||a.scrollTop)};
                +goog.style.getBoundingClientRect_=function(a){try{var b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,bottom:0}}goog.userAgent.IE&&a.ownerDocument.body&&(a=a.ownerDocument,b.left-=a.documentElement.clientLeft+a.body.clientLeft,b.top-=a.documentElement.clientTop+a.body.clientTop);return b};
                +goog.style.getOffsetParent=function(a){if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(8))return goog.asserts.assert(a&&"offsetParent"in a),a.offsetParent;var b=goog.dom.getOwnerDocument(a),c=goog.style.getStyle_(a,"position"),d="fixed"==c||"absolute"==c;for(a=a.parentNode;a&&a!=b;a=a.parentNode)if(a.nodeType==goog.dom.NodeType.DOCUMENT_FRAGMENT&&a.host&&(a=a.host),c=goog.style.getStyle_(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||
                +a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return null};
                +goog.style.getVisibleRectForElement=function(a){for(var b=new goog.math.Box(0,Infinity,Infinity,0),c=goog.dom.getDomHelper(a),d=c.getDocument().body,e=c.getDocument().documentElement,f=c.getDocumentScrollElement();a=goog.style.getOffsetParent(a);)if(!(goog.userAgent.IE&&0==a.clientWidth||goog.userAgent.WEBKIT&&0==a.clientHeight&&a==d)&&a!=d&&a!=e&&"visible"!=goog.style.getStyle_(a,"overflow")){var g=goog.style.getPageOffset(a),h=goog.style.getClientLeftTop(a);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,
                +g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=c.getViewportSize();b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&&b.bottom>b.top&&b.right>b.left?b:null};
                +goog.style.getContainerOffsetToScrollInto=function(a,b,c){var d=b||goog.dom.getDocumentScrollElement();var e=goog.style.getPageOffset(a);var f=goog.style.getPageOffset(d),g=goog.style.getBorderBox(d);d==goog.dom.getDocumentScrollElement()?(b=e.x-d.scrollLeft,e=e.y-d.scrollTop,goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(10)&&(b+=g.left,e+=g.top)):(b=e.x-f.x-g.left,e=e.y-f.y-g.top);g=goog.style.getSizeWithDisplay_(a);a=d.clientWidth-g.width;g=d.clientHeight-g.height;f=d.scrollLeft;d=d.scrollTop;
                +c?(f+=b-a/2,d+=e-g/2):(f+=Math.min(b,Math.max(b-a,0)),d+=Math.min(e,Math.max(e-g,0)));return new goog.math.Coordinate(f,d)};goog.style.scrollIntoContainerView=function(a,b,c){b=b||goog.dom.getDocumentScrollElement();a=goog.style.getContainerOffsetToScrollInto(a,b,c);b.scrollLeft=a.x;b.scrollTop=a.y};goog.style.getClientLeftTop=function(a){return new goog.math.Coordinate(a.clientLeft,a.clientTop)};
                +goog.style.getPageOffset=function(a){var b=goog.dom.getOwnerDocument(a);goog.asserts.assertObject(a,"Parameter is required");var c=new goog.math.Coordinate(0,0),d=goog.style.getClientViewportElement(b);if(a==d)return c;a=goog.style.getBoundingClientRect_(a);b=goog.dom.getDomHelper(b).getDocumentScroll();c.x=a.left+b.x;c.y=a.top+b.y;return c};goog.style.getPageOffsetLeft=function(a){return goog.style.getPageOffset(a).x};goog.style.getPageOffsetTop=function(a){return goog.style.getPageOffset(a).y};
                +goog.style.getFramedPageOffset=function(a,b){var c=new goog.math.Coordinate(0,0),d=goog.dom.getWindow(goog.dom.getOwnerDocument(a));if(!goog.reflect.canAccessProperty(d,"parent"))return c;do{var e=d==b?goog.style.getPageOffset(a):goog.style.getClientPositionForElement_(goog.asserts.assert(a));c.x+=e.x;c.y+=e.y}while(d&&d!=b&&d!=d.parent&&(a=d.frameElement)&&(d=d.parent));return c};
                +goog.style.translateRectForAnotherFrame=function(a,b,c){if(b.getDocument()!=c.getDocument()){var d=b.getDocument().body;c=goog.style.getFramedPageOffset(d,c.getWindow());c=goog.math.Coordinate.difference(c,goog.style.getPageOffset(d));!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9)||b.isCss1CompatMode()||(c=goog.math.Coordinate.difference(c,b.getDocumentScroll()));a.left+=c.x;a.top+=c.y}};
                +goog.style.getRelativePosition=function(a,b){a=goog.style.getClientPosition(a);b=goog.style.getClientPosition(b);return new goog.math.Coordinate(a.x-b.x,a.y-b.y)};goog.style.getClientPositionForElement_=function(a){a=goog.style.getBoundingClientRect_(a);return new goog.math.Coordinate(a.left,a.top)};
                +goog.style.getClientPosition=function(a){goog.asserts.assert(a);if(a.nodeType==goog.dom.NodeType.ELEMENT)return goog.style.getClientPositionForElement_(a);a=a.changedTouches?a.changedTouches[0]:a;return new goog.math.Coordinate(a.clientX,a.clientY)};goog.style.setPageOffset=function(a,b,c){var d=goog.style.getPageOffset(a);b instanceof goog.math.Coordinate&&(c=b.y,b=b.x);b=goog.asserts.assertNumber(b)-d.x;goog.style.setPosition(a,a.offsetLeft+b,a.offsetTop+(Number(c)-d.y))};
                +goog.style.setSize=function(a,b,c){if(b instanceof goog.math.Size)c=b.height,b=b.width;else if(void 0==c)throw Error("missing height argument");goog.style.setWidth(a,b);goog.style.setHeight(a,c)};goog.style.getPixelStyleValue_=function(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a};goog.style.setHeight=function(a,b){a.style.height=goog.style.getPixelStyleValue_(b,!0)};goog.style.setWidth=function(a,b){a.style.width=goog.style.getPixelStyleValue_(b,!0)};
                +goog.style.getSize=function(a){return goog.style.evaluateWithTemporaryDisplay_(goog.style.getSizeWithDisplay_,a)};goog.style.evaluateWithTemporaryDisplay_=function(a,b){if("none"!=goog.style.getStyle_(b,"display"))return a(b);var c=b.style,d=c.display,e=c.visibility,f=c.position;c.visibility="hidden";c.position="absolute";c.display="inline";a=a(b);c.display=d;c.position=f;c.visibility=e;return a};
                +goog.style.getSizeWithDisplay_=function(a){var b=a.offsetWidth,c=a.offsetHeight,d=goog.userAgent.WEBKIT&&!b&&!c;return goog.isDef(b)&&!d||!a.getBoundingClientRect?new goog.math.Size(b,c):(a=goog.style.getBoundingClientRect_(a),new goog.math.Size(a.right-a.left,a.bottom-a.top))};goog.style.getTransformedSize=function(a){if(!a.getBoundingClientRect)return null;a=goog.style.evaluateWithTemporaryDisplay_(goog.style.getBoundingClientRect_,a);return new goog.math.Size(a.right-a.left,a.bottom-a.top)};
                +goog.style.getBounds=function(a){var b=goog.style.getPageOffset(a);a=goog.style.getSize(a);return new goog.math.Rect(b.x,b.y,a.width,a.height)};goog.style.toCamelCase=function(a){return goog.string.toCamelCase(String(a))};goog.style.toSelectorCase=function(a){return goog.string.toSelectorCase(a)};
                +goog.style.getOpacity=function(a){goog.asserts.assert(a);var b=a.style;a="";"opacity"in b?a=b.opacity:"MozOpacity"in b?a=b.MozOpacity:"filter"in b&&(b=b.filter.match(/alpha\(opacity=([\d.]+)\)/))&&(a=String(b[1]/100));return""==a?a:Number(a)};goog.style.setOpacity=function(a,b){goog.asserts.assert(a);a=a.style;"opacity"in a?a.opacity=b:"MozOpacity"in a?a.MozOpacity=b:"filter"in a&&(a.filter=""===b?"":"alpha(opacity="+100*Number(b)+")")};
                +goog.style.setTransparentBackgroundImage=function(a,b){a=a.style;goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?a.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+b+'", sizingMethod="crop")':(a.backgroundImage="url("+b+")",a.backgroundPosition="top left",a.backgroundRepeat="no-repeat")};goog.style.clearTransparentBackgroundImage=function(a){a=a.style;"filter"in a?a.filter="":a.backgroundImage="none"};goog.style.showElement=function(a,b){goog.style.setElementShown(a,b)};
                +goog.style.setElementShown=function(a,b){a.style.display=b?"":"none"};goog.style.isElementShown=function(a){return"none"!=a.style.display};goog.style.installStyles=function(a,b){return goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(a),b)};
                +goog.style.installSafeStyleSheet=function(a,b){b=goog.dom.getDomHelper(b);var c=b.getDocument();if(goog.userAgent.IE&&c.createStyleSheet){var d=c.createStyleSheet();goog.style.setSafeStyleSheet(d,a)}else c=b.getElementsByTagNameAndClass("HEAD")[0],c||(d=b.getElementsByTagNameAndClass("BODY")[0],c=b.createDom("HEAD"),d.parentNode.insertBefore(c,d)),d=b.createDom("STYLE"),goog.style.setSafeStyleSheet(d,a),b.appendChild(c,d);return d};
                +goog.style.uninstallStyles=function(a){goog.dom.removeNode(a.ownerNode||a.owningElement||a)};goog.style.setStyles=function(a,b){goog.style.setSafeStyleSheet(a,goog.html.legacyconversions.safeStyleSheetFromString(b))};goog.style.setSafeStyleSheet=function(a,b){b=goog.html.SafeStyleSheet.unwrap(b);goog.userAgent.IE&&goog.isDef(a.cssText)?a.cssText=b:a.innerHTML=b};
                +goog.style.setPreWrap=function(a){a=a.style;goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?(a.whiteSpace="pre",a.wordWrap="break-word"):a.whiteSpace=goog.userAgent.GECKO?"-moz-pre-wrap":"pre-wrap"};goog.style.setInlineBlock=function(a){a=a.style;a.position="relative";goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?(a.zoom="1",a.display="inline"):a.display="inline-block"};goog.style.isRightToLeft=function(a){return"rtl"==goog.style.getStyle_(a,"direction")};
                +goog.style.unselectableStyle_=goog.userAgent.GECKO?"MozUserSelect":goog.userAgent.WEBKIT||goog.userAgent.EDGE?"WebkitUserSelect":null;goog.style.isUnselectable=function(a){return goog.style.unselectableStyle_?"none"==a.style[goog.style.unselectableStyle_].toLowerCase():goog.userAgent.IE||goog.userAgent.OPERA?"on"==a.getAttribute("unselectable"):!1};
                +goog.style.setUnselectable=function(a,b,c){c=c?null:a.getElementsByTagName("*");var d=goog.style.unselectableStyle_;if(d){if(b=b?"none":"",a.style&&(a.style[d]=b),c){a=0;for(var e;e=c[a];a++)e.style&&(e.style[d]=b)}}else if(goog.userAgent.IE||goog.userAgent.OPERA)if(b=b?"on":"",a.setAttribute("unselectable",b),c)for(a=0;e=c[a];a++)e.setAttribute("unselectable",b)};goog.style.getBorderBoxSize=function(a){return new goog.math.Size(a.offsetWidth,a.offsetHeight)};
                +goog.style.setBorderBoxSize=function(a,b){var c=goog.dom.getOwnerDocument(a),d=goog.dom.getDomHelper(c).isCss1CompatMode();!goog.userAgent.IE||goog.userAgent.isVersionOrHigher("10")||d&&goog.userAgent.isVersionOrHigher("8")?goog.style.setBoxSizingSize_(a,b,"border-box"):(c=a.style,d?(d=goog.style.getPaddingBox(a),a=goog.style.getBorderBox(a),c.pixelWidth=b.width-a.left-d.left-d.right-a.right,c.pixelHeight=b.height-a.top-d.top-d.bottom-a.bottom):(c.pixelWidth=b.width,c.pixelHeight=b.height))};
                +goog.style.getContentBoxSize=function(a){var b=goog.dom.getOwnerDocument(a),c=goog.userAgent.IE&&a.currentStyle;if(c&&goog.dom.getDomHelper(b).isCss1CompatMode()&&"auto"!=c.width&&"auto"!=c.height&&!c.boxSizing)return b=goog.style.getIePixelValue_(a,c.width,"width","pixelWidth"),a=goog.style.getIePixelValue_(a,c.height,"height","pixelHeight"),new goog.math.Size(b,a);c=goog.style.getBorderBoxSize(a);b=goog.style.getPaddingBox(a);a=goog.style.getBorderBox(a);return new goog.math.Size(c.width-a.left-
                +b.left-b.right-a.right,c.height-a.top-b.top-b.bottom-a.bottom)};
                +goog.style.setContentBoxSize=function(a,b){var c=goog.dom.getOwnerDocument(a),d=goog.dom.getDomHelper(c).isCss1CompatMode();!goog.userAgent.IE||goog.userAgent.isVersionOrHigher("10")||d&&goog.userAgent.isVersionOrHigher("8")?goog.style.setBoxSizingSize_(a,b,"content-box"):(c=a.style,d?(c.pixelWidth=b.width,c.pixelHeight=b.height):(d=goog.style.getPaddingBox(a),a=goog.style.getBorderBox(a),c.pixelWidth=b.width+a.left+d.left+d.right+a.right,c.pixelHeight=b.height+a.top+d.top+d.bottom+a.bottom))};
                +goog.style.setBoxSizingSize_=function(a,b,c){a=a.style;goog.userAgent.GECKO?a.MozBoxSizing=c:goog.userAgent.WEBKIT?a.WebkitBoxSizing=c:a.boxSizing=c;a.width=Math.max(b.width,0)+"px";a.height=Math.max(b.height,0)+"px"};goog.style.getIePixelValue_=function(a,b,c,d){if(/^\d+px?$/.test(b))return parseInt(b,10);var e=a.style[c],f=a.runtimeStyle[c];a.runtimeStyle[c]=a.currentStyle[c];a.style[c]=b;b=a.style[d];a.style[c]=e;a.runtimeStyle[c]=f;return+b};
                +goog.style.getIePixelDistance_=function(a,b){return(b=goog.style.getCascadedStyle(a,b))?goog.style.getIePixelValue_(a,b,"left","pixelLeft"):0};
                +goog.style.getBox_=function(a,b){if(goog.userAgent.IE){var c=goog.style.getIePixelDistance_(a,b+"Left");var d=goog.style.getIePixelDistance_(a,b+"Right");var e=goog.style.getIePixelDistance_(a,b+"Top");a=goog.style.getIePixelDistance_(a,b+"Bottom");return new goog.math.Box(e,d,a,c)}c=goog.style.getComputedStyle(a,b+"Left");d=goog.style.getComputedStyle(a,b+"Right");e=goog.style.getComputedStyle(a,b+"Top");a=goog.style.getComputedStyle(a,b+"Bottom");return new goog.math.Box(parseFloat(e),parseFloat(d),
                +parseFloat(a),parseFloat(c))};goog.style.getPaddingBox=function(a){return goog.style.getBox_(a,"padding")};goog.style.getMarginBox=function(a){return goog.style.getBox_(a,"margin")};goog.style.ieBorderWidthKeywords_={thin:2,medium:4,thick:6};
                +goog.style.getIePixelBorder_=function(a,b){if("none"==goog.style.getCascadedStyle(a,b+"Style"))return 0;b=goog.style.getCascadedStyle(a,b+"Width");return b in goog.style.ieBorderWidthKeywords_?goog.style.ieBorderWidthKeywords_[b]:goog.style.getIePixelValue_(a,b,"left","pixelLeft")};
                +goog.style.getBorderBox=function(a){if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)){var b=goog.style.getIePixelBorder_(a,"borderLeft");var c=goog.style.getIePixelBorder_(a,"borderRight");var d=goog.style.getIePixelBorder_(a,"borderTop");a=goog.style.getIePixelBorder_(a,"borderBottom");return new goog.math.Box(d,c,a,b)}b=goog.style.getComputedStyle(a,"borderLeftWidth");c=goog.style.getComputedStyle(a,"borderRightWidth");d=goog.style.getComputedStyle(a,"borderTopWidth");a=goog.style.getComputedStyle(a,
                +"borderBottomWidth");return new goog.math.Box(parseFloat(d),parseFloat(c),parseFloat(a),parseFloat(b))};goog.style.getFontFamily=function(a){var b=goog.dom.getOwnerDocument(a),c="";if(b.body.createTextRange&&goog.dom.contains(b,a)){b=b.body.createTextRange();b.moveToElementText(a);try{c=b.queryCommandValue("FontName")}catch(d){c=""}}c||(c=goog.style.getStyle_(a,"fontFamily"));a=c.split(",");1<a.length&&(c=a[0]);return goog.string.stripQuotes(c,"\"'")};goog.style.lengthUnitRegex_=/[^\d]+$/;
                +goog.style.getLengthUnits=function(a){return(a=a.match(goog.style.lengthUnitRegex_))&&a[0]||null};goog.style.ABSOLUTE_CSS_LENGTH_UNITS_={cm:1,"in":1,mm:1,pc:1,pt:1};goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_={em:1,ex:1};
                +goog.style.getFontSize=function(a){var b=goog.style.getStyle_(a,"fontSize"),c=goog.style.getLengthUnits(b);if(b&&"px"==c)return parseInt(b,10);if(goog.userAgent.IE){if(String(c)in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_)return goog.style.getIePixelValue_(a,b,"left","pixelLeft");if(a.parentNode&&a.parentNode.nodeType==goog.dom.NodeType.ELEMENT&&String(c)in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_)return a=a.parentNode,c=goog.style.getStyle_(a,"fontSize"),goog.style.getIePixelValue_(a,b==c?"1em":b,
                +"left","pixelLeft")}c=goog.dom.createDom("SPAN",{style:"visibility:hidden;position:absolute;line-height:0;padding:0;margin:0;border:0;height:1em;"});goog.dom.appendChild(a,c);b=c.offsetHeight;goog.dom.removeNode(c);return b};goog.style.parseStyleAttribute=function(a){var b={};goog.array.forEach(a.split(/\s*;\s*/),function(a){var c=a.match(/\s*([\w-]+)\s*\:(.+)/);c&&(a=c[1],c=goog.string.trim(c[2]),b[goog.string.toCamelCase(a.toLowerCase())]=c)});return b};
                +goog.style.toStyleAttribute=function(a){var b=[];goog.object.forEach(a,function(a,d){b.push(goog.string.toSelectorCase(d),":",a,";")});return b.join("")};goog.style.setFloat=function(a,b){a.style[goog.userAgent.IE?"styleFloat":"cssFloat"]=b};goog.style.getFloat=function(a){return a.style[goog.userAgent.IE?"styleFloat":"cssFloat"]||""};
                +goog.style.getScrollbarWidth=function(a){var b=goog.dom.createElement("DIV");a&&(b.className=a);b.style.cssText="overflow:auto;position:absolute;top:0;width:100px;height:100px";a=goog.dom.createElement("DIV");goog.style.setSize(a,"200px","200px");b.appendChild(a);goog.dom.appendChild(goog.dom.getDocument().body,b);a=b.offsetWidth-b.clientWidth;goog.dom.removeNode(b);return a};goog.style.MATRIX_TRANSLATION_REGEX_=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;
                +goog.style.getCssTranslation=function(a){a=goog.style.getComputedTransform(a);return a?(a=a.match(goog.style.MATRIX_TRANSLATION_REGEX_))?new goog.math.Coordinate(parseFloat(a[1]),parseFloat(a[2])):new goog.math.Coordinate(0,0):new goog.math.Coordinate(0,0)};goog.Thenable=function(){};goog.Thenable.prototype.then=function(a,b,c){};goog.Thenable.IMPLEMENTED_BY_PROP="$goog_Thenable";goog.Thenable.addImplementation=function(a){a.prototype.then=a.prototype.then;COMPILED?a.prototype[goog.Thenable.IMPLEMENTED_BY_PROP]=!0:a.prototype.$goog_Thenable=!0};goog.Thenable.isImplementedBy=function(a){if(!a)return!1;try{return COMPILED?!!a[goog.Thenable.IMPLEMENTED_BY_PROP]:!!a.$goog_Thenable}catch(b){return!1}};goog.async={};goog.async.FreeList=function(a,b,c){this.limit_=c;this.create_=a;this.reset_=b;this.occupants_=0;this.head_=null};goog.async.FreeList.prototype.get=function(){if(0<this.occupants_){this.occupants_--;var a=this.head_;this.head_=a.next;a.next=null}else a=this.create_();return a};goog.async.FreeList.prototype.put=function(a){this.reset_(a);this.occupants_<this.limit_&&(this.occupants_++,a.next=this.head_,this.head_=a)};goog.async.FreeList.prototype.occupants=function(){return this.occupants_};goog.async.WorkQueue=function(){this.workTail_=this.workHead_=null};goog.async.WorkQueue.DEFAULT_MAX_UNUSED=100;goog.async.WorkQueue.freelist_=new goog.async.FreeList(function(){return new goog.async.WorkItem},function(a){a.reset()},goog.async.WorkQueue.DEFAULT_MAX_UNUSED);goog.async.WorkQueue.prototype.add=function(a,b){var c=this.getUnusedItem_();c.set(a,b);this.workTail_?this.workTail_.next=c:(goog.asserts.assert(!this.workHead_),this.workHead_=c);this.workTail_=c};
                +goog.async.WorkQueue.prototype.remove=function(){var a=null;this.workHead_&&(a=this.workHead_,this.workHead_=this.workHead_.next,this.workHead_||(this.workTail_=null),a.next=null);return a};goog.async.WorkQueue.prototype.returnUnused=function(a){goog.async.WorkQueue.freelist_.put(a)};goog.async.WorkQueue.prototype.getUnusedItem_=function(){return goog.async.WorkQueue.freelist_.get()};goog.async.WorkItem=function(){this.next=this.scope=this.fn=null};
                +goog.async.WorkItem.prototype.set=function(a,b){this.fn=a;this.scope=b;this.next=null};goog.async.WorkItem.prototype.reset=function(){this.next=this.scope=this.fn=null};goog.functions={};goog.functions.constant=function(a){return function(){return a}};goog.functions.FALSE=goog.functions.constant(!1);goog.functions.TRUE=goog.functions.constant(!0);goog.functions.NULL=goog.functions.constant(null);goog.functions.identity=function(a,b){return a};goog.functions.error=function(a){return function(){throw Error(a);}};goog.functions.fail=function(a){return function(){throw a;}};
                +goog.functions.lock=function(a,b){b=b||0;return function(){return a.apply(this,Array.prototype.slice.call(arguments,0,b))}};goog.functions.nth=function(a){return function(){return arguments[a]}};goog.functions.partialRight=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.push.apply(b,c);return a.apply(this,b)}};goog.functions.withReturnValue=function(a,b){return goog.functions.sequence(a,goog.functions.constant(b))};
                +goog.functions.equalTo=function(a,b){return function(c){return b?a==c:a===c}};goog.functions.compose=function(a,b){var c=arguments,d=c.length;return function(){var a;d&&(a=c[d-1].apply(this,arguments));for(var b=d-2;0<=b;b--)a=c[b].call(this,a);return a}};goog.functions.sequence=function(a){var b=arguments,c=b.length;return function(){for(var a,e=0;e<c;e++)a=b[e].apply(this,arguments);return a}};
                +goog.functions.and=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(!b[a].apply(this,arguments))return!1;return!0}};goog.functions.or=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(b[a].apply(this,arguments))return!0;return!1}};goog.functions.not=function(a){return function(){return!a.apply(this,arguments)}};
                +goog.functions.create=function(a,b){var c=function(){};c.prototype=a.prototype;c=new c;a.apply(c,Array.prototype.slice.call(arguments,1));return c};goog.functions.CACHE_RETURN_VALUE=!0;goog.functions.cacheReturnValue=function(a){var b=!1,c;return function(){if(!goog.functions.CACHE_RETURN_VALUE)return a();b||(c=a(),b=!0);return c}};goog.functions.once=function(a){var b=a;return function(){if(b){var a=b;b=null;a()}}};
                +goog.functions.debounce=function(a,b,c){var d=0;return function(e){goog.global.clearTimeout(d);var f=arguments;d=goog.global.setTimeout(function(){a.apply(c,f)},b)}};goog.functions.throttle=function(a,b,c){var d=0,e=!1,f=[],g=function(){d=0;e&&(e=!1,h())},h=function(){d=goog.global.setTimeout(g,b);a.apply(c,f)};return function(a){f=arguments;d?e=!0:h()}};goog.functions.rateLimit=function(a,b,c){var d=0,e=function(){d=0};return function(f){d||(d=goog.global.setTimeout(e,b),a.apply(c,arguments))}};goog.async.throwException=function(a){goog.global.setTimeout(function(){throw a;},0)};goog.async.nextTick=function(a,b,c){var d=a;b&&(d=goog.bind(a,b));d=goog.async.nextTick.wrapCallback_(d);goog.isFunction(goog.global.setImmediate)&&(c||goog.async.nextTick.useSetImmediate_())?goog.global.setImmediate(d):(goog.async.nextTick.setImmediate_||(goog.async.nextTick.setImmediate_=goog.async.nextTick.getSetImmediateEmulator_()),goog.async.nextTick.setImmediate_(d))};
                +goog.async.nextTick.useSetImmediate_=function(){return goog.global.Window&&goog.global.Window.prototype&&!goog.labs.userAgent.browser.isEdge()&&goog.global.Window.prototype.setImmediate==goog.global.setImmediate?!1:!0};
                +goog.async.nextTick.getSetImmediateEmulator_=function(){var a=goog.global.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!goog.labs.userAgent.engine.isPresto()&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+
                +"//"+b.location.host,a=goog.bind(function(a){if(("*"==d||a.origin==d)&&a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!goog.labs.userAgent.browser.isIE()){var b=new a,c={},d=c;b.port1.onmessage=function(){if(goog.isDef(c.next)){c=c.next;var a=c.cb;c.cb=null;a()}};return function(a){d.next={cb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in
                +document.createElement("SCRIPT")?function(a){var b=document.createElement("SCRIPT");b.onreadystatechange=function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){goog.global.setTimeout(a,0)}};goog.async.nextTick.wrapCallback_=goog.functions.identity;goog.debug.entryPointRegistry.register(function(a){goog.async.nextTick.wrapCallback_=a});goog.async.run=function(a,b){goog.async.run.schedule_||goog.async.run.initializeRunner_();goog.async.run.workQueueScheduled_||(goog.async.run.schedule_(),goog.async.run.workQueueScheduled_=!0);goog.async.run.workQueue_.add(a,b)};goog.async.run.initializeRunner_=function(){if(-1!=String(goog.global.Promise).indexOf("[native code]")){var a=goog.global.Promise.resolve(void 0);goog.async.run.schedule_=function(){a.then(goog.async.run.processWorkQueue)}}else goog.async.run.schedule_=function(){goog.async.nextTick(goog.async.run.processWorkQueue)}};
                +goog.async.run.forceNextTick=function(a){goog.async.run.schedule_=function(){goog.async.nextTick(goog.async.run.processWorkQueue);a&&a(goog.async.run.processWorkQueue)}};goog.async.run.workQueueScheduled_=!1;goog.async.run.workQueue_=new goog.async.WorkQueue;goog.DEBUG&&(goog.async.run.resetQueue=function(){goog.async.run.workQueueScheduled_=!1;goog.async.run.workQueue_=new goog.async.WorkQueue});
                +goog.async.run.processWorkQueue=function(){for(var a;a=goog.async.run.workQueue_.remove();){try{a.fn.call(a.scope)}catch(b){goog.async.throwException(b)}goog.async.run.workQueue_.returnUnused(a)}goog.async.run.workQueueScheduled_=!1};goog.promise={};goog.promise.Resolver=function(){};goog.Promise=function(a,b){this.state_=goog.Promise.State_.PENDING;this.result_=void 0;this.callbackEntriesTail_=this.callbackEntries_=this.parent_=null;this.executing_=!1;0<goog.Promise.UNHANDLED_REJECTION_DELAY?this.unhandledRejectionId_=0:0==goog.Promise.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);goog.Promise.LONG_STACK_TRACES&&(this.stack_=[],this.addStackTrace_(Error("created")),this.currentStep_=0);if(a!=goog.nullFunction)try{var c=this;a.call(b,function(a){c.resolve_(goog.Promise.State_.FULFILLED,
                +a)},function(a){if(goog.DEBUG&&!(a instanceof goog.Promise.CancellationError))try{if(a instanceof Error)throw a;throw Error("Promise rejected.");}catch(e){}c.resolve_(goog.Promise.State_.REJECTED,a)})}catch(d){this.resolve_(goog.Promise.State_.REJECTED,d)}};goog.Promise.LONG_STACK_TRACES=!1;goog.Promise.UNHANDLED_REJECTION_DELAY=0;goog.Promise.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3};
                +goog.Promise.CallbackEntry_=function(){this.next=this.context=this.onRejected=this.onFulfilled=this.child=null;this.always=!1};goog.Promise.CallbackEntry_.prototype.reset=function(){this.context=this.onRejected=this.onFulfilled=this.child=null;this.always=!1};goog.Promise.DEFAULT_MAX_UNUSED=100;goog.Promise.freelist_=new goog.async.FreeList(function(){return new goog.Promise.CallbackEntry_},function(a){a.reset()},goog.Promise.DEFAULT_MAX_UNUSED);
                +goog.Promise.getCallbackEntry_=function(a,b,c){var d=goog.Promise.freelist_.get();d.onFulfilled=a;d.onRejected=b;d.context=c;return d};goog.Promise.returnEntry_=function(a){goog.Promise.freelist_.put(a)};goog.Promise.resolve=function(a){if(a instanceof goog.Promise)return a;var b=new goog.Promise(goog.nullFunction);b.resolve_(goog.Promise.State_.FULFILLED,a);return b};goog.Promise.reject=function(a){return new goog.Promise(function(b,c){c(a)})};
                +goog.Promise.resolveThen_=function(a,b,c){goog.Promise.maybeThen_(a,b,c,null)||goog.async.run(goog.partial(b,a))};goog.Promise.race=function(a){return new goog.Promise(function(b,c){a.length||b(void 0);for(var d=0,e;d<a.length;d++)e=a[d],goog.Promise.resolveThen_(e,b,c)})};
                +goog.Promise.all=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d)for(var f=function(a,c){d--;e[a]=c;0==d&&b(e)},g=function(a){c(a)},h=0,k;h<a.length;h++)k=a[h],goog.Promise.resolveThen_(k,goog.partial(f,h),g);else b(e)})};
                +goog.Promise.allSettled=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d){c=function(a,c,f){d--;e[a]=c?{fulfilled:!0,value:f}:{fulfilled:!1,reason:f};0==d&&b(e)};for(var f=0,g;f<a.length;f++)g=a[f],goog.Promise.resolveThen_(g,goog.partial(c,f,!0),goog.partial(c,f,!1))}else b(e)})};
                +goog.Promise.firstFulfilled=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d)for(var f=function(a){b(a)},g=function(a,b){d--;e[a]=b;0==d&&c(e)},h=0,k;h<a.length;h++)k=a[h],goog.Promise.resolveThen_(k,f,goog.partial(g,h));else b(void 0)})};goog.Promise.withResolver=function(){var a,b,c=new goog.Promise(function(c,e){a=c;b=e});return new goog.Promise.Resolver_(c,a,b)};
                +goog.Promise.prototype.then=function(a,b,c){null!=a&&goog.asserts.assertFunction(a,"opt_onFulfilled should be a function.");null!=b&&goog.asserts.assertFunction(b,"opt_onRejected should be a function. Did you pass opt_context as the second argument instead of the third?");goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("then"));return this.addChildPromise_(goog.isFunction(a)?a:null,goog.isFunction(b)?b:null,c)};goog.Thenable.addImplementation(goog.Promise);
                +goog.Promise.prototype.thenVoid=function(a,b,c){null!=a&&goog.asserts.assertFunction(a,"opt_onFulfilled should be a function.");null!=b&&goog.asserts.assertFunction(b,"opt_onRejected should be a function. Did you pass opt_context as the second argument instead of the third?");goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("then"));this.addCallbackEntry_(goog.Promise.getCallbackEntry_(a||goog.nullFunction,b||null,c))};
                +goog.Promise.prototype.thenAlways=function(a,b){goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("thenAlways"));a=goog.Promise.getCallbackEntry_(a,a,b);a.always=!0;this.addCallbackEntry_(a);return this};goog.Promise.prototype.thenCatch=function(a,b){goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("thenCatch"));return this.addChildPromise_(null,a,b)};
                +goog.Promise.prototype.cancel=function(a){this.state_==goog.Promise.State_.PENDING&&goog.async.run(function(){var b=new goog.Promise.CancellationError(a);this.cancelInternal_(b)},this)};goog.Promise.prototype.cancelInternal_=function(a){this.state_==goog.Promise.State_.PENDING&&(this.parent_?(this.parent_.cancelChild_(this,a),this.parent_=null):this.resolve_(goog.Promise.State_.REJECTED,a))};
                +goog.Promise.prototype.cancelChild_=function(a,b){if(this.callbackEntries_){for(var c=0,d=null,e=null,f=this.callbackEntries_;f&&(f.always||(c++,f.child==a&&(d=f),!(d&&1<c)));f=f.next)d||(e=f);d&&(this.state_==goog.Promise.State_.PENDING&&1==c?this.cancelInternal_(b):(e?this.removeEntryAfter_(e):this.popEntry_(),this.executeCallback_(d,goog.Promise.State_.REJECTED,b)))}};
                +goog.Promise.prototype.addCallbackEntry_=function(a){this.hasEntry_()||this.state_!=goog.Promise.State_.FULFILLED&&this.state_!=goog.Promise.State_.REJECTED||this.scheduleCallbacks_();this.queueEntry_(a)};
                +goog.Promise.prototype.addChildPromise_=function(a,b,c){var d=goog.Promise.getCallbackEntry_(null,null,null);d.child=new goog.Promise(function(e,f){d.onFulfilled=a?function(b){try{var d=a.call(c,b);e(d)}catch(k){f(k)}}:e;d.onRejected=b?function(a){try{var d=b.call(c,a);!goog.isDef(d)&&a instanceof goog.Promise.CancellationError?f(a):e(d)}catch(k){f(k)}}:f});d.child.parent_=this;this.addCallbackEntry_(d);return d.child};
                +goog.Promise.prototype.unblockAndFulfill_=function(a){goog.asserts.assert(this.state_==goog.Promise.State_.BLOCKED);this.state_=goog.Promise.State_.PENDING;this.resolve_(goog.Promise.State_.FULFILLED,a)};goog.Promise.prototype.unblockAndReject_=function(a){goog.asserts.assert(this.state_==goog.Promise.State_.BLOCKED);this.state_=goog.Promise.State_.PENDING;this.resolve_(goog.Promise.State_.REJECTED,a)};
                +goog.Promise.prototype.resolve_=function(a,b){this.state_==goog.Promise.State_.PENDING&&(this===b&&(a=goog.Promise.State_.REJECTED,b=new TypeError("Promise cannot resolve to itself")),this.state_=goog.Promise.State_.BLOCKED,goog.Promise.maybeThen_(b,this.unblockAndFulfill_,this.unblockAndReject_,this)||(this.result_=b,this.state_=a,this.parent_=null,this.scheduleCallbacks_(),a!=goog.Promise.State_.REJECTED||b instanceof goog.Promise.CancellationError||goog.Promise.addUnhandledRejection_(this,b)))};
                +goog.Promise.maybeThen_=function(a,b,c,d){if(a instanceof goog.Promise)return a.thenVoid(b,c,d),!0;if(goog.Thenable.isImplementedBy(a))return a.then(b,c,d),!0;if(goog.isObject(a))try{var e=a.then;if(goog.isFunction(e))return goog.Promise.tryThen_(a,e,b,c,d),!0}catch(f){return c.call(d,f),!0}return!1};goog.Promise.tryThen_=function(a,b,c,d,e){var f=!1,g=function(a){f||(f=!0,c.call(e,a))},h=function(a){f||(f=!0,d.call(e,a))};try{b.call(a,g,h)}catch(k){h(k)}};
                +goog.Promise.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,goog.async.run(this.executeCallbacks_,this))};goog.Promise.prototype.hasEntry_=function(){return!!this.callbackEntries_};goog.Promise.prototype.queueEntry_=function(a){goog.asserts.assert(null!=a.onFulfilled);this.callbackEntriesTail_?this.callbackEntriesTail_.next=a:this.callbackEntries_=a;this.callbackEntriesTail_=a};
                +goog.Promise.prototype.popEntry_=function(){var a=null;this.callbackEntries_&&(a=this.callbackEntries_,this.callbackEntries_=a.next,a.next=null);this.callbackEntries_||(this.callbackEntriesTail_=null);null!=a&&goog.asserts.assert(null!=a.onFulfilled);return a};goog.Promise.prototype.removeEntryAfter_=function(a){goog.asserts.assert(this.callbackEntries_);goog.asserts.assert(null!=a);a.next==this.callbackEntriesTail_&&(this.callbackEntriesTail_=a);a.next=a.next.next};
                +goog.Promise.prototype.executeCallbacks_=function(){for(var a;a=this.popEntry_();)goog.Promise.LONG_STACK_TRACES&&this.currentStep_++,this.executeCallback_(a,this.state_,this.result_);this.executing_=!1};
                +goog.Promise.prototype.executeCallback_=function(a,b,c){b==goog.Promise.State_.REJECTED&&a.onRejected&&!a.always&&this.removeUnhandledRejection_();if(a.child)a.child.parent_=null,goog.Promise.invokeCallback_(a,b,c);else try{a.always?a.onFulfilled.call(a.context):goog.Promise.invokeCallback_(a,b,c)}catch(d){goog.Promise.handleRejection_.call(null,d)}goog.Promise.returnEntry_(a)};
                +goog.Promise.invokeCallback_=function(a,b,c){b==goog.Promise.State_.FULFILLED?a.onFulfilled.call(a.context,c):a.onRejected&&a.onRejected.call(a.context,c)};goog.Promise.prototype.addStackTrace_=function(a){if(goog.Promise.LONG_STACK_TRACES&&goog.isString(a.stack)){var b=a.stack.split("\n",4)[3];a=a.message;a+=Array(11-a.length).join(" ");this.stack_.push(a+b)}};
                +goog.Promise.prototype.appendLongStack_=function(a){if(goog.Promise.LONG_STACK_TRACES&&a&&goog.isString(a.stack)&&this.stack_.length){for(var b=["Promise trace:"],c=this;c;c=c.parent_){for(var d=this.currentStep_;0<=d;d--)b.push(c.stack_[d]);b.push("Value: ["+(c.state_==goog.Promise.State_.REJECTED?"REJECTED":"FULFILLED")+"] <"+String(c.result_)+">")}a.stack+="\n\n"+b.join("\n")}};
                +goog.Promise.prototype.removeUnhandledRejection_=function(){if(0<goog.Promise.UNHANDLED_REJECTION_DELAY)for(var a=this;a&&a.unhandledRejectionId_;a=a.parent_)goog.global.clearTimeout(a.unhandledRejectionId_),a.unhandledRejectionId_=0;else if(0==goog.Promise.UNHANDLED_REJECTION_DELAY)for(a=this;a&&a.hadUnhandledRejection_;a=a.parent_)a.hadUnhandledRejection_=!1};
                +goog.Promise.addUnhandledRejection_=function(a,b){0<goog.Promise.UNHANDLED_REJECTION_DELAY?a.unhandledRejectionId_=goog.global.setTimeout(function(){a.appendLongStack_(b);goog.Promise.handleRejection_.call(null,b)},goog.Promise.UNHANDLED_REJECTION_DELAY):0==goog.Promise.UNHANDLED_REJECTION_DELAY&&(a.hadUnhandledRejection_=!0,goog.async.run(function(){a.hadUnhandledRejection_&&(a.appendLongStack_(b),goog.Promise.handleRejection_.call(null,b))}))};goog.Promise.handleRejection_=goog.async.throwException;
                +goog.Promise.setUnhandledRejectionHandler=function(a){goog.Promise.handleRejection_=a};goog.Promise.CancellationError=function(a){goog.debug.Error.call(this,a)};goog.inherits(goog.Promise.CancellationError,goog.debug.Error);goog.Promise.CancellationError.prototype.name="cancel";goog.Promise.Resolver_=function(a,b,c){this.promise=a;this.resolve=b;this.reject=c};goog.events.EventTarget=function(){goog.Disposable.call(this);this.eventTargetListeners_=new goog.events.ListenerMap(this);this.actualEventTarget_=this;this.parentEventTarget_=null};goog.inherits(goog.events.EventTarget,goog.Disposable);goog.events.Listenable.addImplementation(goog.events.EventTarget);goog.events.EventTarget.MAX_ANCESTORS_=1E3;goog.events.EventTarget.prototype.getParentEventTarget=function(){return this.parentEventTarget_};
                +goog.events.EventTarget.prototype.setParentEventTarget=function(a){this.parentEventTarget_=a};goog.events.EventTarget.prototype.addEventListener=function(a,b,c,d){goog.events.listen(this,a,b,c,d)};goog.events.EventTarget.prototype.removeEventListener=function(a,b,c,d){goog.events.unlisten(this,a,b,c,d)};
                +goog.events.EventTarget.prototype.dispatchEvent=function(a){this.assertInitialized_();var b=this.getParentEventTarget();if(b){var c=[];for(var d=1;b;b=b.getParentEventTarget())c.push(b),goog.asserts.assert(++d<goog.events.EventTarget.MAX_ANCESTORS_,"infinite loop")}return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_,a,c)};
                +goog.events.EventTarget.prototype.disposeInternal=function(){goog.events.EventTarget.superClass_.disposeInternal.call(this);this.removeAllListeners();this.parentEventTarget_=null};goog.events.EventTarget.prototype.listen=function(a,b,c,d){this.assertInitialized_();return this.eventTargetListeners_.add(String(a),b,!1,c,d)};goog.events.EventTarget.prototype.listenOnce=function(a,b,c,d){return this.eventTargetListeners_.add(String(a),b,!0,c,d)};
                +goog.events.EventTarget.prototype.unlisten=function(a,b,c,d){return this.eventTargetListeners_.remove(String(a),b,c,d)};goog.events.EventTarget.prototype.unlistenByKey=function(a){return this.eventTargetListeners_.removeByKey(a)};goog.events.EventTarget.prototype.removeAllListeners=function(a){return this.eventTargetListeners_?this.eventTargetListeners_.removeAll(a):0};
                +goog.events.EventTarget.prototype.fireListeners=function(a,b,c){a=this.eventTargetListeners_.listeners[String(a)];if(!a)return!0;a=a.concat();for(var d=!0,e=0;e<a.length;++e){var f=a[e];if(f&&!f.removed&&f.capture==b){var g=f.listener,h=f.handler||f.src;f.callOnce&&this.unlistenByKey(f);d=!1!==g.call(h,c)&&d}}return d&&0!=c.returnValue_};goog.events.EventTarget.prototype.getListeners=function(a,b){return this.eventTargetListeners_.getListeners(String(a),b)};
                +goog.events.EventTarget.prototype.getListener=function(a,b,c,d){return this.eventTargetListeners_.getListener(String(a),b,c,d)};goog.events.EventTarget.prototype.hasListener=function(a,b){a=goog.isDef(a)?String(a):void 0;return this.eventTargetListeners_.hasListener(a,b)};goog.events.EventTarget.prototype.setTargetForTesting=function(a){this.actualEventTarget_=a};goog.events.EventTarget.prototype.assertInitialized_=function(){goog.asserts.assert(this.eventTargetListeners_,"Event target is not initialized. Did you call the superclass (goog.events.EventTarget) constructor?")};
                +goog.events.EventTarget.dispatchEventInternal_=function(a,b,c){var d=b.type||b;if(goog.isString(b))b=new goog.events.Event(b,a);else if(b instanceof goog.events.Event)b.target=b.target||a;else{var e=b;b=new goog.events.Event(d,a);goog.object.extend(b,e)}var e=!0;if(c)for(var f=c.length-1;!b.propagationStopped_&&0<=f;f--){var g=b.currentTarget=c[f];e=g.fireListeners(d,!0,b)&&e}b.propagationStopped_||(g=b.currentTarget=a,e=g.fireListeners(d,!0,b)&&e,b.propagationStopped_||(e=g.fireListeners(d,!1,b)&&
                +e));if(c)for(f=0;!b.propagationStopped_&&f<c.length;f++)g=b.currentTarget=c[f],e=g.fireListeners(d,!1,b)&&e;return e};goog.Timer=function(a,b){goog.events.EventTarget.call(this);this.interval_=a||1;this.timerObject_=b||goog.Timer.defaultTimerObject;this.boundTick_=goog.bind(this.tick_,this);this.last_=goog.now()};goog.inherits(goog.Timer,goog.events.EventTarget);goog.Timer.MAX_TIMEOUT_=2147483647;goog.Timer.INVALID_TIMEOUT_ID_=-1;goog.Timer.prototype.enabled=!1;goog.Timer.defaultTimerObject=goog.global;goog.Timer.intervalScale=.8;goog.Timer.prototype.timer_=null;goog.Timer.prototype.getInterval=function(){return this.interval_};
                +goog.Timer.prototype.setInterval=function(a){this.interval_=a;this.timer_&&this.enabled?(this.stop(),this.start()):this.timer_&&this.stop()};
                +goog.Timer.prototype.tick_=function(){if(this.enabled){var a=goog.now()-this.last_;0<a&&a<this.interval_*goog.Timer.intervalScale?this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_-a):(this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null),this.dispatchTick(),this.enabled&&(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now()))}};goog.Timer.prototype.dispatchTick=function(){this.dispatchEvent(goog.Timer.TICK)};
                +goog.Timer.prototype.start=function(){this.enabled=!0;this.timer_||(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now())};goog.Timer.prototype.stop=function(){this.enabled=!1;this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null)};goog.Timer.prototype.disposeInternal=function(){goog.Timer.superClass_.disposeInternal.call(this);this.stop();delete this.timerObject_};goog.Timer.TICK="tick";
                +goog.Timer.callOnce=function(a,b,c){if(goog.isFunction(a))c&&(a=goog.bind(a,c));else if(a&&"function"==typeof a.handleEvent)a=goog.bind(a.handleEvent,a);else throw Error("Invalid listener argument");return Number(b)>goog.Timer.MAX_TIMEOUT_?goog.Timer.INVALID_TIMEOUT_ID_:goog.Timer.defaultTimerObject.setTimeout(a,b||0)};goog.Timer.clear=function(a){goog.Timer.defaultTimerObject.clearTimeout(a)};
                +goog.Timer.promise=function(a,b){var c=null;return(new goog.Promise(function(d,e){c=goog.Timer.callOnce(function(){d(b)},a);c==goog.Timer.INVALID_TIMEOUT_ID_&&e(Error("Failed to schedule timer."))})).thenCatch(function(a){goog.Timer.clear(c);throw a;})};goog.events.EventHandler=function(a){goog.Disposable.call(this);this.handler_=a;this.keys_={}};goog.inherits(goog.events.EventHandler,goog.Disposable);goog.events.EventHandler.typeArray_=[];goog.events.EventHandler.prototype.listen=function(a,b,c,d){return this.listen_(a,b,c,d)};goog.events.EventHandler.prototype.listenWithScope=function(a,b,c,d,e){return this.listen_(a,b,c,d,e)};
                +goog.events.EventHandler.prototype.listen_=function(a,b,c,d,e){goog.isArray(b)||(b&&(goog.events.EventHandler.typeArray_[0]=b.toString()),b=goog.events.EventHandler.typeArray_);for(var f=0;f<b.length;f++){var g=goog.events.listen(a,b[f],c||this.handleEvent,d||!1,e||this.handler_||this);if(!g)break;this.keys_[g.key]=g}return this};goog.events.EventHandler.prototype.listenOnce=function(a,b,c,d){return this.listenOnce_(a,b,c,d)};
                +goog.events.EventHandler.prototype.listenOnceWithScope=function(a,b,c,d,e){return this.listenOnce_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenOnce_=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.listenOnce_(a,b[f],c,d,e);else{a=goog.events.listenOnce(a,b,c||this.handleEvent,d,e||this.handler_||this);if(!a)return this;this.keys_[a.key]=a}return this};goog.events.EventHandler.prototype.listenWithWrapper=function(a,b,c,d){return this.listenWithWrapper_(a,b,c,d)};
                +goog.events.EventHandler.prototype.listenWithWrapperAndScope=function(a,b,c,d,e){return this.listenWithWrapper_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenWithWrapper_=function(a,b,c,d,e){b.listen(a,c,d,e||this.handler_||this,this);return this};goog.events.EventHandler.prototype.getListenerCount=function(){var a=0,b;for(b in this.keys_)Object.prototype.hasOwnProperty.call(this.keys_,b)&&a++;return a};
                +goog.events.EventHandler.prototype.unlisten=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.unlisten(a,b[f],c,d,e);else if(a=goog.events.getListener(a,b,c||this.handleEvent,d,e||this.handler_||this))goog.events.unlistenByKey(a),delete this.keys_[a.key];return this};goog.events.EventHandler.prototype.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e||this.handler_||this,this);return this};
                +goog.events.EventHandler.prototype.removeAll=function(){goog.object.forEach(this.keys_,function(a,b){this.keys_.hasOwnProperty(b)&&goog.events.unlistenByKey(a)},this);this.keys_={}};goog.events.EventHandler.prototype.disposeInternal=function(){goog.events.EventHandler.superClass_.disposeInternal.call(this);this.removeAll()};goog.events.EventHandler.prototype.handleEvent=function(a){throw Error("EventHandler.handleEvent not implemented");};goog.ui={};goog.ui.IdGenerator=function(){};goog.addSingletonGetter(goog.ui.IdGenerator);goog.ui.IdGenerator.prototype.nextId_=0;goog.ui.IdGenerator.prototype.getNextUniqueId=function(){return":"+(this.nextId_++).toString(36)};goog.ui.Component=function(a){goog.events.EventTarget.call(this);this.dom_=a||goog.dom.getDomHelper();this.rightToLeft_=goog.ui.Component.defaultRightToLeft_;this.id_=null;this.inDocument_=!1;this.element_=null;this.googUiComponentHandler_=void 0;this.childIndex_=this.children_=this.parent_=this.model_=null;this.wasDecorated_=!1};goog.inherits(goog.ui.Component,goog.events.EventTarget);goog.ui.Component.ALLOW_DETACHED_DECORATION=!1;goog.ui.Component.prototype.idGenerator_=goog.ui.IdGenerator.getInstance();
                +goog.ui.Component.DEFAULT_BIDI_DIR=0;goog.ui.Component.defaultRightToLeft_=1==goog.ui.Component.DEFAULT_BIDI_DIR?!1:-1==goog.ui.Component.DEFAULT_BIDI_DIR?!0:null;
                +goog.ui.Component.EventType={BEFORE_SHOW:"beforeshow",SHOW:"show",HIDE:"hide",DISABLE:"disable",ENABLE:"enable",HIGHLIGHT:"highlight",UNHIGHLIGHT:"unhighlight",ACTIVATE:"activate",DEACTIVATE:"deactivate",SELECT:"select",UNSELECT:"unselect",CHECK:"check",UNCHECK:"uncheck",FOCUS:"focus",BLUR:"blur",OPEN:"open",CLOSE:"close",ENTER:"enter",LEAVE:"leave",ACTION:"action",CHANGE:"change"};
                +goog.ui.Component.Error={NOT_SUPPORTED:"Method not supported",DECORATE_INVALID:"Invalid element to decorate",ALREADY_RENDERED:"Component already rendered",PARENT_UNABLE_TO_BE_SET:"Unable to set parent component",CHILD_INDEX_OUT_OF_BOUNDS:"Child component index out of bounds",NOT_OUR_CHILD:"Child is not in parent component",NOT_IN_DOCUMENT:"Operation not supported while component is not in document",STATE_INVALID:"Invalid component state"};
                +goog.ui.Component.State={ALL:255,DISABLED:1,HOVER:2,ACTIVE:4,SELECTED:8,CHECKED:16,FOCUSED:32,OPENED:64};
                +goog.ui.Component.getStateTransitionEvent=function(a,b){switch(a){case goog.ui.Component.State.DISABLED:return b?goog.ui.Component.EventType.DISABLE:goog.ui.Component.EventType.ENABLE;case goog.ui.Component.State.HOVER:return b?goog.ui.Component.EventType.HIGHLIGHT:goog.ui.Component.EventType.UNHIGHLIGHT;case goog.ui.Component.State.ACTIVE:return b?goog.ui.Component.EventType.ACTIVATE:goog.ui.Component.EventType.DEACTIVATE;case goog.ui.Component.State.SELECTED:return b?goog.ui.Component.EventType.SELECT:
                +goog.ui.Component.EventType.UNSELECT;case goog.ui.Component.State.CHECKED:return b?goog.ui.Component.EventType.CHECK:goog.ui.Component.EventType.UNCHECK;case goog.ui.Component.State.FOCUSED:return b?goog.ui.Component.EventType.FOCUS:goog.ui.Component.EventType.BLUR;case goog.ui.Component.State.OPENED:return b?goog.ui.Component.EventType.OPEN:goog.ui.Component.EventType.CLOSE}throw Error(goog.ui.Component.Error.STATE_INVALID);};
                +goog.ui.Component.setDefaultRightToLeft=function(a){goog.ui.Component.defaultRightToLeft_=a};goog.ui.Component.prototype.getId=function(){return this.id_||(this.id_=this.idGenerator_.getNextUniqueId())};goog.ui.Component.prototype.setId=function(a){this.parent_&&this.parent_.childIndex_&&(goog.object.remove(this.parent_.childIndex_,this.id_),goog.object.add(this.parent_.childIndex_,a,this));this.id_=a};goog.ui.Component.prototype.getElement=function(){return this.element_};
                +goog.ui.Component.prototype.getElementStrict=function(){var a=this.element_;goog.asserts.assert(a,"Can not call getElementStrict before rendering/decorating.");return a};goog.ui.Component.prototype.setElementInternal=function(a){this.element_=a};goog.ui.Component.prototype.getElementsByClass=function(a){return this.element_?this.dom_.getElementsByClass(a,this.element_):[]};goog.ui.Component.prototype.getElementByClass=function(a){return this.element_?this.dom_.getElementByClass(a,this.element_):null};
                +goog.ui.Component.prototype.getRequiredElementByClass=function(a){var b=this.getElementByClass(a);goog.asserts.assert(b,"Expected element in component with class: %s",a);return b};goog.ui.Component.prototype.getHandler=function(){this.googUiComponentHandler_||(this.googUiComponentHandler_=new goog.events.EventHandler(this));return this.googUiComponentHandler_};
                +goog.ui.Component.prototype.setParent=function(a){if(this==a)throw Error(goog.ui.Component.Error.PARENT_UNABLE_TO_BE_SET);if(a&&this.parent_&&this.id_&&this.parent_.getChild(this.id_)&&this.parent_!=a)throw Error(goog.ui.Component.Error.PARENT_UNABLE_TO_BE_SET);this.parent_=a;goog.ui.Component.superClass_.setParentEventTarget.call(this,a)};goog.ui.Component.prototype.getParent=function(){return this.parent_};
                +goog.ui.Component.prototype.setParentEventTarget=function(a){if(this.parent_&&this.parent_!=a)throw Error(goog.ui.Component.Error.NOT_SUPPORTED);goog.ui.Component.superClass_.setParentEventTarget.call(this,a)};goog.ui.Component.prototype.getDomHelper=function(){return this.dom_};goog.ui.Component.prototype.isInDocument=function(){return this.inDocument_};goog.ui.Component.prototype.createDom=function(){this.element_=this.dom_.createElement("DIV")};goog.ui.Component.prototype.render=function(a){this.render_(a)};
                +goog.ui.Component.prototype.renderBefore=function(a){this.render_(a.parentNode,a)};goog.ui.Component.prototype.render_=function(a,b){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.element_||this.createDom();a?a.insertBefore(this.element_,b||null):this.dom_.getDocument().body.appendChild(this.element_);this.parent_&&!this.parent_.isInDocument()||this.enterDocument()};
                +goog.ui.Component.prototype.decorate=function(a){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);if(a&&this.canDecorate(a)){this.wasDecorated_=!0;var b=goog.dom.getOwnerDocument(a);this.dom_&&this.dom_.getDocument()==b||(this.dom_=goog.dom.getDomHelper(a));this.decorateInternal(a);goog.ui.Component.ALLOW_DETACHED_DECORATION&&!goog.dom.contains(b,a)||this.enterDocument()}else throw Error(goog.ui.Component.Error.DECORATE_INVALID);};goog.ui.Component.prototype.canDecorate=function(a){return!0};
                +goog.ui.Component.prototype.wasDecorated=function(){return this.wasDecorated_};goog.ui.Component.prototype.decorateInternal=function(a){this.element_=a};goog.ui.Component.prototype.enterDocument=function(){this.inDocument_=!0;this.forEachChild(function(a){!a.isInDocument()&&a.getElement()&&a.enterDocument()})};
                +goog.ui.Component.prototype.exitDocument=function(){this.forEachChild(function(a){a.isInDocument()&&a.exitDocument()});this.googUiComponentHandler_&&this.googUiComponentHandler_.removeAll();this.inDocument_=!1};
                +goog.ui.Component.prototype.disposeInternal=function(){this.inDocument_&&this.exitDocument();this.googUiComponentHandler_&&(this.googUiComponentHandler_.dispose(),delete this.googUiComponentHandler_);this.forEachChild(function(a){a.dispose()});!this.wasDecorated_&&this.element_&&goog.dom.removeNode(this.element_);this.parent_=this.model_=this.element_=this.childIndex_=this.children_=null;goog.ui.Component.superClass_.disposeInternal.call(this)};
                +goog.ui.Component.prototype.makeId=function(a){return this.getId()+"."+a};goog.ui.Component.prototype.makeIds=function(a){var b={},c;for(c in a)b[c]=this.makeId(a[c]);return b};goog.ui.Component.prototype.getModel=function(){return this.model_};goog.ui.Component.prototype.setModel=function(a){this.model_=a};goog.ui.Component.prototype.getFragmentFromId=function(a){return a.substring(this.getId().length+1)};
                +goog.ui.Component.prototype.getElementByFragment=function(a){if(!this.inDocument_)throw Error(goog.ui.Component.Error.NOT_IN_DOCUMENT);return this.dom_.getElement(this.makeId(a))};goog.ui.Component.prototype.addChild=function(a,b){this.addChildAt(a,this.getChildCount(),b)};
                +goog.ui.Component.prototype.addChildAt=function(a,b,c){goog.asserts.assert(!!a,"Provided element must not be null.");if(a.inDocument_&&(c||!this.inDocument_))throw Error(goog.ui.Component.Error.ALREADY_RENDERED);if(0>b||b>this.getChildCount())throw Error(goog.ui.Component.Error.CHILD_INDEX_OUT_OF_BOUNDS);this.childIndex_&&this.children_||(this.childIndex_={},this.children_=[]);a.getParent()==this?(goog.object.set(this.childIndex_,a.getId(),a),goog.array.remove(this.children_,a)):goog.object.add(this.childIndex_,
                +a.getId(),a);a.setParent(this);goog.array.insertAt(this.children_,a,b);a.inDocument_&&this.inDocument_&&a.getParent()==this?(c=this.getContentElement(),b=c.childNodes[b]||null,b!=a.getElement()&&c.insertBefore(a.getElement(),b)):c?(this.element_||this.createDom(),b=this.getChildAt(b+1),a.render_(this.getContentElement(),b?b.element_:null)):this.inDocument_&&!a.inDocument_&&a.element_&&a.element_.parentNode&&a.element_.parentNode.nodeType==goog.dom.NodeType.ELEMENT&&a.enterDocument()};
                +goog.ui.Component.prototype.getContentElement=function(){return this.element_};goog.ui.Component.prototype.isRightToLeft=function(){null==this.rightToLeft_&&(this.rightToLeft_=goog.style.isRightToLeft(this.inDocument_?this.element_:this.dom_.getDocument().body));return this.rightToLeft_};goog.ui.Component.prototype.setRightToLeft=function(a){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.rightToLeft_=a};
                +goog.ui.Component.prototype.hasChildren=function(){return!!this.children_&&0!=this.children_.length};goog.ui.Component.prototype.getChildCount=function(){return this.children_?this.children_.length:0};goog.ui.Component.prototype.getChildIds=function(){var a=[];this.forEachChild(function(b){a.push(b.getId())});return a};goog.ui.Component.prototype.getChild=function(a){return this.childIndex_&&a?goog.object.get(this.childIndex_,a)||null:null};
                +goog.ui.Component.prototype.getChildAt=function(a){return this.children_?this.children_[a]||null:null};goog.ui.Component.prototype.forEachChild=function(a,b){this.children_&&goog.array.forEach(this.children_,a,b)};goog.ui.Component.prototype.indexOfChild=function(a){return this.children_&&a?goog.array.indexOf(this.children_,a):-1};
                +goog.ui.Component.prototype.removeChild=function(a,b){if(a){var c=goog.isString(a)?a:a.getId();a=this.getChild(c);c&&a&&(goog.object.remove(this.childIndex_,c),goog.array.remove(this.children_,a),b&&(a.exitDocument(),a.element_&&goog.dom.removeNode(a.element_)),a.setParent(null))}if(!a)throw Error(goog.ui.Component.Error.NOT_OUR_CHILD);return a};goog.ui.Component.prototype.removeChildAt=function(a,b){return this.removeChild(this.getChildAt(a),b)};
                +goog.ui.Component.prototype.removeChildren=function(a){for(var b=[];this.hasChildren();)b.push(this.removeChildAt(0,a));return b};goog.a11y={};goog.a11y.aria={};
                +goog.a11y.aria.Role={ALERT:"alert",ALERTDIALOG:"alertdialog",APPLICATION:"application",ARTICLE:"article",BANNER:"banner",BUTTON:"button",CHECKBOX:"checkbox",COLUMNHEADER:"columnheader",COMBOBOX:"combobox",COMPLEMENTARY:"complementary",CONTENTINFO:"contentinfo",DEFINITION:"definition",DIALOG:"dialog",DIRECTORY:"directory",DOCUMENT:"document",FORM:"form",GRID:"grid",GRIDCELL:"gridcell",GROUP:"group",HEADING:"heading",IMG:"img",LINK:"link",LIST:"list",LISTBOX:"listbox",LISTITEM:"listitem",LOG:"log",
                +MAIN:"main",MARQUEE:"marquee",MATH:"math",MENU:"menu",MENUBAR:"menubar",MENU_ITEM:"menuitem",MENU_ITEM_CHECKBOX:"menuitemcheckbox",MENU_ITEM_RADIO:"menuitemradio",NAVIGATION:"navigation",NOTE:"note",OPTION:"option",PRESENTATION:"presentation",PROGRESSBAR:"progressbar",RADIO:"radio",RADIOGROUP:"radiogroup",REGION:"region",ROW:"row",ROWGROUP:"rowgroup",ROWHEADER:"rowheader",SCROLLBAR:"scrollbar",SEARCH:"search",SEPARATOR:"separator",SLIDER:"slider",SPINBUTTON:"spinbutton",STATUS:"status",TAB:"tab",
                +TAB_LIST:"tablist",TAB_PANEL:"tabpanel",TEXTBOX:"textbox",TEXTINFO:"textinfo",TIMER:"timer",TOOLBAR:"toolbar",TOOLTIP:"tooltip",TREE:"tree",TREEGRID:"treegrid",TREEITEM:"treeitem"};goog.a11y.aria.State={ACTIVEDESCENDANT:"activedescendant",ATOMIC:"atomic",AUTOCOMPLETE:"autocomplete",BUSY:"busy",CHECKED:"checked",CONTROLS:"controls",DESCRIBEDBY:"describedby",DISABLED:"disabled",DROPEFFECT:"dropeffect",EXPANDED:"expanded",FLOWTO:"flowto",GRABBED:"grabbed",HASPOPUP:"haspopup",HIDDEN:"hidden",INVALID:"invalid",LABEL:"label",LABELLEDBY:"labelledby",LEVEL:"level",LIVE:"live",MULTILINE:"multiline",MULTISELECTABLE:"multiselectable",ORIENTATION:"orientation",OWNS:"owns",POSINSET:"posinset",
                +PRESSED:"pressed",READONLY:"readonly",RELEVANT:"relevant",REQUIRED:"required",SELECTED:"selected",SETSIZE:"setsize",SORT:"sort",VALUEMAX:"valuemax",VALUEMIN:"valuemin",VALUENOW:"valuenow",VALUETEXT:"valuetext"};goog.a11y.aria.AutoCompleteValues={INLINE:"inline",LIST:"list",BOTH:"both",NONE:"none"};goog.a11y.aria.DropEffectValues={COPY:"copy",MOVE:"move",LINK:"link",EXECUTE:"execute",POPUP:"popup",NONE:"none"};goog.a11y.aria.LivePriority={OFF:"off",POLITE:"polite",ASSERTIVE:"assertive"};
                +goog.a11y.aria.OrientationValues={VERTICAL:"vertical",HORIZONTAL:"horizontal"};goog.a11y.aria.RelevantValues={ADDITIONS:"additions",REMOVALS:"removals",TEXT:"text",ALL:"all"};goog.a11y.aria.SortValues={ASCENDING:"ascending",DESCENDING:"descending",NONE:"none",OTHER:"other"};goog.a11y.aria.CheckedValues={TRUE:"true",FALSE:"false",MIXED:"mixed",UNDEFINED:"undefined"};goog.a11y.aria.ExpandedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};
                +goog.a11y.aria.GrabbedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};goog.a11y.aria.InvalidValues={FALSE:"false",TRUE:"true",GRAMMAR:"grammar",SPELLING:"spelling"};goog.a11y.aria.PressedValues={TRUE:"true",FALSE:"false",MIXED:"mixed",UNDEFINED:"undefined"};goog.a11y.aria.SelectedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};goog.a11y.aria.datatables={};
                +goog.a11y.aria.datatables.getDefaultValuesMap=function(){goog.a11y.aria.DefaultStateValueMap_||(goog.a11y.aria.DefaultStateValueMap_=goog.object.create(goog.a11y.aria.State.ATOMIC,!1,goog.a11y.aria.State.AUTOCOMPLETE,"none",goog.a11y.aria.State.DROPEFFECT,"none",goog.a11y.aria.State.HASPOPUP,!1,goog.a11y.aria.State.LIVE,"off",goog.a11y.aria.State.MULTILINE,!1,goog.a11y.aria.State.MULTISELECTABLE,!1,goog.a11y.aria.State.ORIENTATION,"vertical",goog.a11y.aria.State.READONLY,!1,goog.a11y.aria.State.RELEVANT,
                +"additions text",goog.a11y.aria.State.REQUIRED,!1,goog.a11y.aria.State.SORT,"none",goog.a11y.aria.State.BUSY,!1,goog.a11y.aria.State.DISABLED,!1,goog.a11y.aria.State.HIDDEN,!1,goog.a11y.aria.State.INVALID,"false"));return goog.a11y.aria.DefaultStateValueMap_};goog.a11y.aria.ARIA_PREFIX_="aria-";goog.a11y.aria.ROLE_ATTRIBUTE_="role";goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_=goog.object.createSet("A AREA BUTTON HEAD INPUT LINK MENU META OPTGROUP OPTION PROGRESS STYLE SELECT SOURCE TEXTAREA TITLE TRACK".split(" "));
                +goog.a11y.aria.CONTAINER_ROLES_=[goog.a11y.aria.Role.COMBOBOX,goog.a11y.aria.Role.GRID,goog.a11y.aria.Role.GROUP,goog.a11y.aria.Role.LISTBOX,goog.a11y.aria.Role.MENU,goog.a11y.aria.Role.MENUBAR,goog.a11y.aria.Role.RADIOGROUP,goog.a11y.aria.Role.ROW,goog.a11y.aria.Role.ROWGROUP,goog.a11y.aria.Role.TAB_LIST,goog.a11y.aria.Role.TEXTBOX,goog.a11y.aria.Role.TOOLBAR,goog.a11y.aria.Role.TREE,goog.a11y.aria.Role.TREEGRID];
                +goog.a11y.aria.setRole=function(a,b){b?(goog.asserts.ENABLE_ASSERTS&&goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.Role,b),"No such ARIA role "+b),a.setAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_,b)):goog.a11y.aria.removeRole(a)};goog.a11y.aria.getRole=function(a){return a.getAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_)||null};goog.a11y.aria.removeRole=function(a){a.removeAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_)};
                +goog.a11y.aria.setState=function(a,b,c){goog.isArray(c)&&(c=c.join(" "));var d=goog.a11y.aria.getAriaAttributeName_(b);""===c||void 0==c?(c=goog.a11y.aria.datatables.getDefaultValuesMap(),b in c?a.setAttribute(d,c[b]):a.removeAttribute(d)):a.setAttribute(d,c)};goog.a11y.aria.toggleState=function(a,b){var c=goog.a11y.aria.getState(a,b);goog.string.isEmptyOrWhitespace(goog.string.makeSafe(c))||"true"==c||"false"==c?goog.a11y.aria.setState(a,b,"true"==c?"false":"true"):goog.a11y.aria.removeState(a,b)};
                +goog.a11y.aria.removeState=function(a,b){a.removeAttribute(goog.a11y.aria.getAriaAttributeName_(b))};goog.a11y.aria.getState=function(a,b){a=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return null==a||void 0==a?"":String(a)};goog.a11y.aria.getActiveDescendant=function(a){var b=goog.a11y.aria.getState(a,goog.a11y.aria.State.ACTIVEDESCENDANT);return goog.dom.getOwnerDocument(a).getElementById(b)};
                +goog.a11y.aria.setActiveDescendant=function(a,b){var c="";b&&(c=b.id,goog.asserts.assert(c,"The active element should have an id."));goog.a11y.aria.setState(a,goog.a11y.aria.State.ACTIVEDESCENDANT,c)};goog.a11y.aria.getLabel=function(a){return goog.a11y.aria.getState(a,goog.a11y.aria.State.LABEL)};goog.a11y.aria.setLabel=function(a,b){goog.a11y.aria.setState(a,goog.a11y.aria.State.LABEL,b)};
                +goog.a11y.aria.assertRoleIsSetInternalUtil=function(a,b){goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_[a.tagName]||(a=goog.a11y.aria.getRole(a),goog.asserts.assert(null!=a,"The element ARIA role cannot be null."),goog.asserts.assert(goog.array.contains(b,a),'Non existing or incorrect role set for element.The role set is "'+a+'". The role should be any of "'+b+'". Check the ARIA specification for more details http://www.w3.org/TR/wai-aria/roles.'))};
                +goog.a11y.aria.getStateBoolean=function(a,b){a=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert(goog.isBoolean(a)||null==a||"true"==a||"false"==a);return null==a?a:goog.isBoolean(a)?a:"true"==a};goog.a11y.aria.getStateNumber=function(a,b){a=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==a||!isNaN(Number(a)))&&!goog.isBoolean(a));return null==a?null:Number(a)};
                +goog.a11y.aria.getStateString=function(a,b){a=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==a||goog.isString(a))&&(""==a||isNaN(Number(a)))&&"true"!=a&&"false"!=a);return null==a||""==a?null:a};goog.a11y.aria.getStringArrayStateInternalUtil=function(a,b){a=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return goog.a11y.aria.splitStringOnWhitespace_(a)};goog.a11y.aria.hasState=function(a,b){return a.hasAttribute(goog.a11y.aria.getAriaAttributeName_(b))};
                +goog.a11y.aria.isContainerRole=function(a){a=goog.a11y.aria.getRole(a);return goog.array.contains(goog.a11y.aria.CONTAINER_ROLES_,a)};goog.a11y.aria.splitStringOnWhitespace_=function(a){return a?a.split(/\s+/):[]};goog.a11y.aria.getAriaAttributeName_=function(a){goog.asserts.ENABLE_ASSERTS&&(goog.asserts.assert(a,"ARIA attribute cannot be empty."),goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.State,a),"No such ARIA attribute "+a));return goog.a11y.aria.ARIA_PREFIX_+a};goog.events.KeyCodes={WIN_KEY_FF_LINUX:0,MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PLUS_SIGN:43,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,FF_SEMICOLON:59,FF_EQUALS:61,FF_DASH:173,QUESTION_MARK:63,AT_SIGN:64,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,
                +Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SCROLL_LOCK:145,FIRST_MEDIA_KEY:166,LAST_MEDIA_KEY:183,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,
                +SLASH:191,APOSTROPHE:192,TILDE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,MAC_WK_CMD_LEFT:91,MAC_WK_CMD_RIGHT:93,WIN_IME:229,VK_NONAME:252,PHANTOM:255};
                +goog.events.KeyCodes.isTextModifyingKeyEvent=function(a){if(a.altKey&&!a.ctrlKey||a.metaKey||a.keyCode>=goog.events.KeyCodes.F1&&a.keyCode<=goog.events.KeyCodes.F12)return!1;switch(a.keyCode){case goog.events.KeyCodes.ALT:case goog.events.KeyCodes.CAPS_LOCK:case goog.events.KeyCodes.CONTEXT_MENU:case goog.events.KeyCodes.CTRL:case goog.events.KeyCodes.DOWN:case goog.events.KeyCodes.END:case goog.events.KeyCodes.ESC:case goog.events.KeyCodes.HOME:case goog.events.KeyCodes.INSERT:case goog.events.KeyCodes.LEFT:case goog.events.KeyCodes.MAC_FF_META:case goog.events.KeyCodes.META:case goog.events.KeyCodes.NUMLOCK:case goog.events.KeyCodes.NUM_CENTER:case goog.events.KeyCodes.PAGE_DOWN:case goog.events.KeyCodes.PAGE_UP:case goog.events.KeyCodes.PAUSE:case goog.events.KeyCodes.PHANTOM:case goog.events.KeyCodes.PRINT_SCREEN:case goog.events.KeyCodes.RIGHT:case goog.events.KeyCodes.SCROLL_LOCK:case goog.events.KeyCodes.SHIFT:case goog.events.KeyCodes.UP:case goog.events.KeyCodes.VK_NONAME:case goog.events.KeyCodes.WIN_KEY:case goog.events.KeyCodes.WIN_KEY_RIGHT:return!1;case goog.events.KeyCodes.WIN_KEY_FF_LINUX:return!goog.userAgent.GECKO;
                +default:return a.keyCode<goog.events.KeyCodes.FIRST_MEDIA_KEY||a.keyCode>goog.events.KeyCodes.LAST_MEDIA_KEY}};
                +goog.events.KeyCodes.firesKeyPressEvent=function(a,b,c,d,e,f){if(!(goog.userAgent.IE||goog.userAgent.EDGE||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("525")))return!0;if(goog.userAgent.MAC&&e)return goog.events.KeyCodes.isCharacterKey(a);if(e&&!d)return!1;goog.isNumber(b)&&(b=goog.events.KeyCodes.normalizeKeyCode(b));e=b==goog.events.KeyCodes.CTRL||b==goog.events.KeyCodes.ALT||goog.userAgent.MAC&&b==goog.events.KeyCodes.META;f=b==goog.events.KeyCodes.SHIFT&&(d||f);if((!c||goog.userAgent.MAC)&&
                +e||goog.userAgent.MAC&&f)return!1;if((goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&d&&c)switch(a){case goog.events.KeyCodes.BACKSLASH:case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:case goog.events.KeyCodes.TILDE:case goog.events.KeyCodes.SEMICOLON:case goog.events.KeyCodes.DASH:case goog.events.KeyCodes.EQUALS:case goog.events.KeyCodes.COMMA:case goog.events.KeyCodes.PERIOD:case goog.events.KeyCodes.SLASH:case goog.events.KeyCodes.APOSTROPHE:case goog.events.KeyCodes.SINGLE_QUOTE:return!1}if(goog.userAgent.IE&&
                +d&&b==a)return!1;switch(a){case goog.events.KeyCodes.ENTER:return!0;case goog.events.KeyCodes.ESC:return!(goog.userAgent.WEBKIT||goog.userAgent.EDGE)}return goog.events.KeyCodes.isCharacterKey(a)};
                +goog.events.KeyCodes.isCharacterKey=function(a){if(a>=goog.events.KeyCodes.ZERO&&a<=goog.events.KeyCodes.NINE||a>=goog.events.KeyCodes.NUM_ZERO&&a<=goog.events.KeyCodes.NUM_MULTIPLY||a>=goog.events.KeyCodes.A&&a<=goog.events.KeyCodes.Z||(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&0==a)return!0;switch(a){case goog.events.KeyCodes.SPACE:case goog.events.KeyCodes.PLUS_SIGN:case goog.events.KeyCodes.QUESTION_MARK:case goog.events.KeyCodes.AT_SIGN:case goog.events.KeyCodes.NUM_PLUS:case goog.events.KeyCodes.NUM_MINUS:case goog.events.KeyCodes.NUM_PERIOD:case goog.events.KeyCodes.NUM_DIVISION:case goog.events.KeyCodes.SEMICOLON:case goog.events.KeyCodes.FF_SEMICOLON:case goog.events.KeyCodes.DASH:case goog.events.KeyCodes.EQUALS:case goog.events.KeyCodes.FF_EQUALS:case goog.events.KeyCodes.COMMA:case goog.events.KeyCodes.PERIOD:case goog.events.KeyCodes.SLASH:case goog.events.KeyCodes.APOSTROPHE:case goog.events.KeyCodes.SINGLE_QUOTE:case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:case goog.events.KeyCodes.BACKSLASH:case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:return!0;default:return!1}};
                +goog.events.KeyCodes.normalizeKeyCode=function(a){return goog.userAgent.GECKO?goog.events.KeyCodes.normalizeGeckoKeyCode(a):goog.userAgent.MAC&&goog.userAgent.WEBKIT?goog.events.KeyCodes.normalizeMacWebKitKeyCode(a):a};
                +goog.events.KeyCodes.normalizeGeckoKeyCode=function(a){switch(a){case goog.events.KeyCodes.FF_EQUALS:return goog.events.KeyCodes.EQUALS;case goog.events.KeyCodes.FF_SEMICOLON:return goog.events.KeyCodes.SEMICOLON;case goog.events.KeyCodes.FF_DASH:return goog.events.KeyCodes.DASH;case goog.events.KeyCodes.MAC_FF_META:return goog.events.KeyCodes.META;case goog.events.KeyCodes.WIN_KEY_FF_LINUX:return goog.events.KeyCodes.WIN_KEY;default:return a}};
                +goog.events.KeyCodes.normalizeMacWebKitKeyCode=function(a){switch(a){case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:return goog.events.KeyCodes.META;default:return a}};goog.events.KeyHandler=function(a,b){goog.events.EventTarget.call(this);a&&this.attach(a,b)};goog.inherits(goog.events.KeyHandler,goog.events.EventTarget);goog.events.KeyHandler.prototype.element_=null;goog.events.KeyHandler.prototype.keyPressKey_=null;goog.events.KeyHandler.prototype.keyDownKey_=null;goog.events.KeyHandler.prototype.keyUpKey_=null;goog.events.KeyHandler.prototype.lastKey_=-1;goog.events.KeyHandler.prototype.keyCode_=-1;goog.events.KeyHandler.prototype.altKey_=!1;
                +goog.events.KeyHandler.EventType={KEY:"key"};
                +goog.events.KeyHandler.safariKey_={3:goog.events.KeyCodes.ENTER,12:goog.events.KeyCodes.NUMLOCK,63232:goog.events.KeyCodes.UP,63233:goog.events.KeyCodes.DOWN,63234:goog.events.KeyCodes.LEFT,63235:goog.events.KeyCodes.RIGHT,63236:goog.events.KeyCodes.F1,63237:goog.events.KeyCodes.F2,63238:goog.events.KeyCodes.F3,63239:goog.events.KeyCodes.F4,63240:goog.events.KeyCodes.F5,63241:goog.events.KeyCodes.F6,63242:goog.events.KeyCodes.F7,63243:goog.events.KeyCodes.F8,63244:goog.events.KeyCodes.F9,63245:goog.events.KeyCodes.F10,
                +63246:goog.events.KeyCodes.F11,63247:goog.events.KeyCodes.F12,63248:goog.events.KeyCodes.PRINT_SCREEN,63272:goog.events.KeyCodes.DELETE,63273:goog.events.KeyCodes.HOME,63275:goog.events.KeyCodes.END,63276:goog.events.KeyCodes.PAGE_UP,63277:goog.events.KeyCodes.PAGE_DOWN,63289:goog.events.KeyCodes.NUMLOCK,63302:goog.events.KeyCodes.INSERT};
                +goog.events.KeyHandler.keyIdentifier_={Up:goog.events.KeyCodes.UP,Down:goog.events.KeyCodes.DOWN,Left:goog.events.KeyCodes.LEFT,Right:goog.events.KeyCodes.RIGHT,Enter:goog.events.KeyCodes.ENTER,F1:goog.events.KeyCodes.F1,F2:goog.events.KeyCodes.F2,F3:goog.events.KeyCodes.F3,F4:goog.events.KeyCodes.F4,F5:goog.events.KeyCodes.F5,F6:goog.events.KeyCodes.F6,F7:goog.events.KeyCodes.F7,F8:goog.events.KeyCodes.F8,F9:goog.events.KeyCodes.F9,F10:goog.events.KeyCodes.F10,F11:goog.events.KeyCodes.F11,F12:goog.events.KeyCodes.F12,
                +"U+007F":goog.events.KeyCodes.DELETE,Home:goog.events.KeyCodes.HOME,End:goog.events.KeyCodes.END,PageUp:goog.events.KeyCodes.PAGE_UP,PageDown:goog.events.KeyCodes.PAGE_DOWN,Insert:goog.events.KeyCodes.INSERT};goog.events.KeyHandler.USES_KEYDOWN_=goog.userAgent.IE||goog.userAgent.EDGE||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("525");goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_=goog.userAgent.MAC&&goog.userAgent.GECKO;
                +goog.events.KeyHandler.prototype.handleKeyDown_=function(a){(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&(this.lastKey_==goog.events.KeyCodes.CTRL&&!a.ctrlKey||this.lastKey_==goog.events.KeyCodes.ALT&&!a.altKey||goog.userAgent.MAC&&this.lastKey_==goog.events.KeyCodes.META&&!a.metaKey)&&this.resetState();-1==this.lastKey_&&(a.ctrlKey&&a.keyCode!=goog.events.KeyCodes.CTRL?this.lastKey_=goog.events.KeyCodes.CTRL:a.altKey&&a.keyCode!=goog.events.KeyCodes.ALT?this.lastKey_=goog.events.KeyCodes.ALT:a.metaKey&&
                +a.keyCode!=goog.events.KeyCodes.META&&(this.lastKey_=goog.events.KeyCodes.META));goog.events.KeyHandler.USES_KEYDOWN_&&!goog.events.KeyCodes.firesKeyPressEvent(a.keyCode,this.lastKey_,a.shiftKey,a.ctrlKey,a.altKey,a.metaKey)?this.handleEvent(a):(this.keyCode_=goog.events.KeyCodes.normalizeKeyCode(a.keyCode),goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_&&(this.altKey_=a.altKey))};goog.events.KeyHandler.prototype.resetState=function(){this.keyCode_=this.lastKey_=-1};
                +goog.events.KeyHandler.prototype.handleKeyup_=function(a){this.resetState();this.altKey_=a.altKey};
                +goog.events.KeyHandler.prototype.handleEvent=function(a){var b=a.getBrowserEvent(),c=b.altKey;if(goog.userAgent.IE&&a.type==goog.events.EventType.KEYPRESS){var d=this.keyCode_;var e=d!=goog.events.KeyCodes.ENTER&&d!=goog.events.KeyCodes.ESC?b.keyCode:0}else(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&a.type==goog.events.EventType.KEYPRESS?(d=this.keyCode_,e=0<=b.charCode&&63232>b.charCode&&goog.events.KeyCodes.isCharacterKey(d)?b.charCode:0):goog.userAgent.OPERA&&!goog.userAgent.WEBKIT?(d=this.keyCode_,
                +e=goog.events.KeyCodes.isCharacterKey(d)?b.keyCode:0):(d=b.keyCode||this.keyCode_,e=b.charCode||0,goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_&&(c=this.altKey_),goog.userAgent.MAC&&e==goog.events.KeyCodes.QUESTION_MARK&&d==goog.events.KeyCodes.WIN_KEY&&(d=goog.events.KeyCodes.SLASH));var f=d=goog.events.KeyCodes.normalizeKeyCode(d);d?63232<=d&&d in goog.events.KeyHandler.safariKey_?f=goog.events.KeyHandler.safariKey_[d]:25==d&&a.shiftKey&&(f=9):b.keyIdentifier&&b.keyIdentifier in goog.events.KeyHandler.keyIdentifier_&&
                +(f=goog.events.KeyHandler.keyIdentifier_[b.keyIdentifier]);a=f==this.lastKey_;this.lastKey_=f;b=new goog.events.KeyEvent(f,e,a,b);b.altKey=c;this.dispatchEvent(b)};goog.events.KeyHandler.prototype.getElement=function(){return this.element_};
                +goog.events.KeyHandler.prototype.attach=function(a,b){this.keyUpKey_&&this.detach();this.element_=a;this.keyPressKey_=goog.events.listen(this.element_,goog.events.EventType.KEYPRESS,this,b);this.keyDownKey_=goog.events.listen(this.element_,goog.events.EventType.KEYDOWN,this.handleKeyDown_,b,this);this.keyUpKey_=goog.events.listen(this.element_,goog.events.EventType.KEYUP,this.handleKeyup_,b,this)};
                +goog.events.KeyHandler.prototype.detach=function(){this.keyPressKey_&&(goog.events.unlistenByKey(this.keyPressKey_),goog.events.unlistenByKey(this.keyDownKey_),goog.events.unlistenByKey(this.keyUpKey_),this.keyUpKey_=this.keyDownKey_=this.keyPressKey_=null);this.element_=null;this.keyCode_=this.lastKey_=-1};goog.events.KeyHandler.prototype.disposeInternal=function(){goog.events.KeyHandler.superClass_.disposeInternal.call(this);this.detach()};
                +goog.events.KeyEvent=function(a,b,c,d){goog.events.BrowserEvent.call(this,d);this.type=goog.events.KeyHandler.EventType.KEY;this.keyCode=a;this.charCode=b;this.repeat=c};goog.inherits(goog.events.KeyEvent,goog.events.BrowserEvent);goog.dom.classlist={};goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST=!1;goog.dom.classlist.get=function(a){if(goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList)return a.classList;a=a.className;return goog.isString(a)&&a.match(/\S+/g)||[]};goog.dom.classlist.set=function(a,b){a.className=b};goog.dom.classlist.contains=function(a,b){return goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.contains(b):goog.array.contains(goog.dom.classlist.get(a),b)};
                +goog.dom.classlist.add=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.add(b):goog.dom.classlist.contains(a,b)||(a.className+=0<a.className.length?" "+b:b)};
                +goog.dom.classlist.addAll=function(a,b){if(goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList)goog.array.forEach(b,function(b){goog.dom.classlist.add(a,b)});else{var c={};goog.array.forEach(goog.dom.classlist.get(a),function(a){c[a]=!0});goog.array.forEach(b,function(a){c[a]=!0});a.className="";for(var d in c)a.className+=0<a.className.length?" "+d:d}};
                +goog.dom.classlist.remove=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.remove(b):goog.dom.classlist.contains(a,b)&&(a.className=goog.array.filter(goog.dom.classlist.get(a),function(a){return a!=b}).join(" "))};
                +goog.dom.classlist.removeAll=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?goog.array.forEach(b,function(b){goog.dom.classlist.remove(a,b)}):a.className=goog.array.filter(goog.dom.classlist.get(a),function(a){return!goog.array.contains(b,a)}).join(" ")};goog.dom.classlist.enable=function(a,b,c){c?goog.dom.classlist.add(a,b):goog.dom.classlist.remove(a,b)};goog.dom.classlist.enableAll=function(a,b,c){(c?goog.dom.classlist.addAll:goog.dom.classlist.removeAll)(a,b)};
                +goog.dom.classlist.swap=function(a,b,c){return goog.dom.classlist.contains(a,b)?(goog.dom.classlist.remove(a,b),goog.dom.classlist.add(a,c),!0):!1};goog.dom.classlist.toggle=function(a,b){var c=!goog.dom.classlist.contains(a,b);goog.dom.classlist.enable(a,b,c);return c};goog.dom.classlist.addRemove=function(a,b,c){goog.dom.classlist.remove(a,b);goog.dom.classlist.add(a,c)};goog.ui.registry={};goog.ui.registry.getDefaultRenderer=function(a){for(var b;a;){b=goog.getUid(a);if(b=goog.ui.registry.defaultRenderers_[b])break;a=a.superClass_?a.superClass_.constructor:null}return b?goog.isFunction(b.getInstance)?b.getInstance():new b:null};goog.ui.registry.setDefaultRenderer=function(a,b){if(!goog.isFunction(a))throw Error("Invalid component class "+a);if(!goog.isFunction(b))throw Error("Invalid renderer class "+b);a=goog.getUid(a);goog.ui.registry.defaultRenderers_[a]=b};
                +goog.ui.registry.getDecoratorByClassName=function(a){return a in goog.ui.registry.decoratorFunctions_?goog.ui.registry.decoratorFunctions_[a]():null};goog.ui.registry.setDecoratorByClassName=function(a,b){if(!a)throw Error("Invalid class name "+a);if(!goog.isFunction(b))throw Error("Invalid decorator function "+b);goog.ui.registry.decoratorFunctions_[a]=b};
                +goog.ui.registry.getDecorator=function(a){goog.asserts.assert(a);for(var b=goog.dom.classlist.get(a),c=0,d=b.length;c<d;c++)if(a=goog.ui.registry.getDecoratorByClassName(b[c]))return a;return null};goog.ui.registry.reset=function(){goog.ui.registry.defaultRenderers_={};goog.ui.registry.decoratorFunctions_={}};goog.ui.registry.defaultRenderers_={};goog.ui.registry.decoratorFunctions_={};goog.ui.ContainerRenderer=function(a){this.ariaRole_=a};goog.addSingletonGetter(goog.ui.ContainerRenderer);goog.ui.ContainerRenderer.getCustomRenderer=function(a,b){a=new a;a.getCssClass=function(){return b};return a};goog.ui.ContainerRenderer.CSS_CLASS="goog-container";goog.ui.ContainerRenderer.prototype.getAriaRole=function(){return this.ariaRole_};goog.ui.ContainerRenderer.prototype.enableTabIndex=function(a,b){a&&(a.tabIndex=b?0:-1)};
                +goog.ui.ContainerRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "))};goog.ui.ContainerRenderer.prototype.getContentElement=function(a){return a};goog.ui.ContainerRenderer.prototype.canDecorate=function(a){return"DIV"==a.tagName};
                +goog.ui.ContainerRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);var c=this.getCssClass(),d=!1,e=goog.dom.classlist.get(b);e&&goog.array.forEach(e,function(b){b==c?d=!0:b&&this.setStateFromClassName(a,b,c)},this);d||goog.dom.classlist.add(b,c);this.decorateChildren(a,this.getContentElement(b));return b};
                +goog.ui.ContainerRenderer.prototype.setStateFromClassName=function(a,b,c){b==c+"-disabled"?a.setEnabled(!1):b==c+"-horizontal"?a.setOrientation(goog.ui.Container.Orientation.HORIZONTAL):b==c+"-vertical"&&a.setOrientation(goog.ui.Container.Orientation.VERTICAL)};
                +goog.ui.ContainerRenderer.prototype.decorateChildren=function(a,b,c){if(b){c=c||b.firstChild;for(var d;c&&c.parentNode==b;){d=c.nextSibling;if(c.nodeType==goog.dom.NodeType.ELEMENT){var e=this.getDecoratorForChild(c);e&&(e.setElementInternal(c),a.isEnabled()||e.setEnabled(!1),a.addChild(e),e.decorate(c))}else c.nodeValue&&""!=goog.string.trim(c.nodeValue)||b.removeChild(c);c=d}}};goog.ui.ContainerRenderer.prototype.getDecoratorForChild=function(a){return goog.ui.registry.getDecorator(a)};
                +goog.ui.ContainerRenderer.prototype.initializeDom=function(a){a=a.getElement();goog.asserts.assert(a,"The container DOM element cannot be null.");goog.style.setUnselectable(a,!0,goog.userAgent.GECKO);goog.userAgent.IE&&(a.hideFocus=!0);var b=this.getAriaRole();b&&goog.a11y.aria.setRole(a,b)};goog.ui.ContainerRenderer.prototype.getKeyEventTarget=function(a){return a.getElement()};goog.ui.ContainerRenderer.prototype.getCssClass=function(){return goog.ui.ContainerRenderer.CSS_CLASS};
                +goog.ui.ContainerRenderer.prototype.getClassNames=function(a){var b=this.getCssClass(),c=a.getOrientation()==goog.ui.Container.Orientation.HORIZONTAL,c=[b,c?b+"-horizontal":b+"-vertical"];a.isEnabled()||c.push(b+"-disabled");return c};goog.ui.ContainerRenderer.prototype.getDefaultOrientation=function(){return goog.ui.Container.Orientation.VERTICAL};goog.ui.ControlRenderer=function(){};goog.addSingletonGetter(goog.ui.ControlRenderer);goog.tagUnsealableClass(goog.ui.ControlRenderer);goog.ui.ControlRenderer.getCustomRenderer=function(a,b){a=new a;a.getCssClass=function(){return b};return a};goog.ui.ControlRenderer.CSS_CLASS="goog-control";goog.ui.ControlRenderer.IE6_CLASS_COMBINATIONS=[];
                +goog.ui.ControlRenderer.TOGGLE_ARIA_STATE_MAP_=goog.object.create(goog.a11y.aria.Role.BUTTON,goog.a11y.aria.State.PRESSED,goog.a11y.aria.Role.CHECKBOX,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.MENU_ITEM,goog.a11y.aria.State.SELECTED,goog.a11y.aria.Role.MENU_ITEM_CHECKBOX,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.MENU_ITEM_RADIO,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.RADIO,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.TAB,goog.a11y.aria.State.SELECTED,goog.a11y.aria.Role.TREEITEM,
                +goog.a11y.aria.State.SELECTED);goog.ui.ControlRenderer.prototype.getAriaRole=function(){};goog.ui.ControlRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "),a.getContent())};goog.ui.ControlRenderer.prototype.getContentElement=function(a){return a};
                +goog.ui.ControlRenderer.prototype.enableClassName=function(a,b,c){if(a=a.getElement?a.getElement():a){var d=[b];goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")&&(d=this.getAppliedCombinedClassNames_(goog.dom.classlist.get(a),b),d.push(b));goog.dom.classlist.enableAll(a,d,c)}};goog.ui.ControlRenderer.prototype.enableExtraClassName=function(a,b,c){this.enableClassName(a,b,c)};goog.ui.ControlRenderer.prototype.canDecorate=function(a){return!0};
                +goog.ui.ControlRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);var c=this.getContentElement(b);c&&c.firstChild?a.setContentInternal(c.firstChild.nextSibling?goog.array.clone(c.childNodes):c.firstChild):a.setContentInternal(null);var d=0,e=this.getCssClass(),f=this.getStructuralCssClass(),g=!1,h=!1,k=!1,l=goog.array.toArray(goog.dom.classlist.get(b));goog.array.forEach(l,function(a){g||a!=e?h||a!=f?d|=this.getStateFromClass(a):h=!0:(g=!0,f==e&&(h=!0));this.getStateFromClass(a)==goog.ui.Component.State.DISABLED&&
                +(goog.asserts.assertElement(c),goog.dom.isFocusableTabIndex(c)&&goog.dom.setFocusableTabIndex(c,!1))},this);a.setStateInternal(d);g||(l.push(e),f==e&&(h=!0));h||l.push(f);(a=a.getExtraClassNames())&&l.push.apply(l,a);if(goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")){var m=this.getAppliedCombinedClassNames_(l);0<m.length&&(l.push.apply(l,m),k=!0)}g&&h&&!a&&!k||goog.dom.classlist.set(b,l.join(" "));return b};
                +goog.ui.ControlRenderer.prototype.initializeDom=function(a){a.isRightToLeft()&&this.setRightToLeft(a.getElement(),!0);a.isEnabled()&&this.setFocusable(a,a.isVisible())};goog.ui.ControlRenderer.prototype.setAriaRole=function(a,b){if(b=b||this.getAriaRole()){goog.asserts.assert(a,"The element passed as a first parameter cannot be null.");var c=goog.a11y.aria.getRole(a);b!=c&&goog.a11y.aria.setRole(a,b)}};
                +goog.ui.ControlRenderer.prototype.setAriaStates=function(a,b){goog.asserts.assert(a);goog.asserts.assert(b);var c=a.getAriaLabel();goog.isDefAndNotNull(c)&&this.setAriaLabel(b,c);a.isVisible()||goog.a11y.aria.setState(b,goog.a11y.aria.State.HIDDEN,!a.isVisible());a.isEnabled()||this.updateAriaState(b,goog.ui.Component.State.DISABLED,!a.isEnabled());a.isSupportedState(goog.ui.Component.State.SELECTED)&&this.updateAriaState(b,goog.ui.Component.State.SELECTED,a.isSelected());a.isSupportedState(goog.ui.Component.State.CHECKED)&&
                +this.updateAriaState(b,goog.ui.Component.State.CHECKED,a.isChecked());a.isSupportedState(goog.ui.Component.State.OPENED)&&this.updateAriaState(b,goog.ui.Component.State.OPENED,a.isOpen())};goog.ui.ControlRenderer.prototype.setAriaLabel=function(a,b){goog.a11y.aria.setLabel(a,b)};goog.ui.ControlRenderer.prototype.setAllowTextSelection=function(a,b){goog.style.setUnselectable(a,!b,!goog.userAgent.IE&&!goog.userAgent.OPERA)};
                +goog.ui.ControlRenderer.prototype.setRightToLeft=function(a,b){this.enableClassName(a,this.getStructuralCssClass()+"-rtl",b)};goog.ui.ControlRenderer.prototype.isFocusable=function(a){var b;return a.isSupportedState(goog.ui.Component.State.FOCUSED)&&(b=a.getKeyEventTarget())?goog.dom.isFocusableTabIndex(b):!1};
                +goog.ui.ControlRenderer.prototype.setFocusable=function(a,b){var c;if(a.isSupportedState(goog.ui.Component.State.FOCUSED)&&(c=a.getKeyEventTarget())){if(!b&&a.isFocused()){try{c.blur()}catch(d){}a.isFocused()&&a.handleBlur(null)}goog.dom.isFocusableTabIndex(c)!=b&&goog.dom.setFocusableTabIndex(c,b)}};goog.ui.ControlRenderer.prototype.setVisible=function(a,b){goog.style.setElementShown(a,b);a&&goog.a11y.aria.setState(a,goog.a11y.aria.State.HIDDEN,!b)};
                +goog.ui.ControlRenderer.prototype.setState=function(a,b,c){var d=a.getElement();if(d){var e=this.getClassForState(b);e&&this.enableClassName(a,e,c);this.updateAriaState(d,b,c)}};
                +goog.ui.ControlRenderer.prototype.updateAriaState=function(a,b,c){goog.ui.ControlRenderer.ariaAttributeMap_||(goog.ui.ControlRenderer.ariaAttributeMap_=goog.object.create(goog.ui.Component.State.DISABLED,goog.a11y.aria.State.DISABLED,goog.ui.Component.State.SELECTED,goog.a11y.aria.State.SELECTED,goog.ui.Component.State.CHECKED,goog.a11y.aria.State.CHECKED,goog.ui.Component.State.OPENED,goog.a11y.aria.State.EXPANDED));goog.asserts.assert(a,"The element passed as a first parameter cannot be null.");
                +(b=goog.ui.ControlRenderer.getAriaStateForAriaRole_(a,goog.ui.ControlRenderer.ariaAttributeMap_[b]))&&goog.a11y.aria.setState(a,b,c)};goog.ui.ControlRenderer.getAriaStateForAriaRole_=function(a,b){a=goog.a11y.aria.getRole(a);if(!a)return b;a=goog.ui.ControlRenderer.TOGGLE_ARIA_STATE_MAP_[a]||b;return goog.ui.ControlRenderer.isAriaState_(b)?a:b};goog.ui.ControlRenderer.isAriaState_=function(a){return a==goog.a11y.aria.State.CHECKED||a==goog.a11y.aria.State.SELECTED};
                +goog.ui.ControlRenderer.prototype.setContent=function(a,b){var c=this.getContentElement(a);c&&(goog.dom.removeChildren(c),b&&(goog.isString(b)?goog.dom.setTextContent(c,b):(a=function(a){if(a){var b=goog.dom.getOwnerDocument(c);c.appendChild(goog.isString(a)?b.createTextNode(a):a)}},goog.isArray(b)?goog.array.forEach(b,a):!goog.isArrayLike(b)||"nodeType"in b?a(b):goog.array.forEach(goog.array.clone(b),a))))};goog.ui.ControlRenderer.prototype.getKeyEventTarget=function(a){return a.getElement()};
                +goog.ui.ControlRenderer.prototype.getCssClass=function(){return goog.ui.ControlRenderer.CSS_CLASS};goog.ui.ControlRenderer.prototype.getIe6ClassCombinations=function(){return[]};goog.ui.ControlRenderer.prototype.getStructuralCssClass=function(){return this.getCssClass()};
                +goog.ui.ControlRenderer.prototype.getClassNames=function(a){var b=this.getCssClass(),c=[b],d=this.getStructuralCssClass();d!=b&&c.push(d);b=this.getClassNamesForState(a.getState());c.push.apply(c,b);(a=a.getExtraClassNames())&&c.push.apply(c,a);goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")&&c.push.apply(c,this.getAppliedCombinedClassNames_(c));return c};
                +goog.ui.ControlRenderer.prototype.getAppliedCombinedClassNames_=function(a,b){var c=[];b&&(a=goog.array.concat(a,[b]));goog.array.forEach(this.getIe6ClassCombinations(),function(d){!goog.array.every(d,goog.partial(goog.array.contains,a))||b&&!goog.array.contains(d,b)||c.push(d.join("_"))});return c};goog.ui.ControlRenderer.prototype.getClassNamesForState=function(a){for(var b=[];a;){var c=a&-a;b.push(this.getClassForState(c));a&=~c}return b};
                +goog.ui.ControlRenderer.prototype.getClassForState=function(a){this.classByState_||this.createClassByStateMap_();return this.classByState_[a]};goog.ui.ControlRenderer.prototype.getStateFromClass=function(a){this.stateByClass_||this.createStateByClassMap_();a=parseInt(this.stateByClass_[a],10);return isNaN(a)?0:a};
                +goog.ui.ControlRenderer.prototype.createClassByStateMap_=function(){var a=this.getStructuralCssClass(),b=!goog.string.contains(goog.string.normalizeWhitespace(a)," ");goog.asserts.assert(b,"ControlRenderer has an invalid css class: '"+a+"'");this.classByState_=goog.object.create(goog.ui.Component.State.DISABLED,a+"-disabled",goog.ui.Component.State.HOVER,a+"-hover",goog.ui.Component.State.ACTIVE,a+"-active",goog.ui.Component.State.SELECTED,a+"-selected",goog.ui.Component.State.CHECKED,a+"-checked",
                +goog.ui.Component.State.FOCUSED,a+"-focused",goog.ui.Component.State.OPENED,a+"-open")};goog.ui.ControlRenderer.prototype.createStateByClassMap_=function(){this.classByState_||this.createClassByStateMap_();this.stateByClass_=goog.object.transpose(this.classByState_)};goog.ui.Control=function(a,b,c){goog.ui.Component.call(this,c);this.renderer_=b||goog.ui.registry.getDefaultRenderer(this.constructor);this.setContentInternal(goog.isDef(a)?a:null);this.ariaLabel_=null};goog.inherits(goog.ui.Control,goog.ui.Component);goog.tagUnsealableClass(goog.ui.Control);goog.ui.Control.registerDecorator=goog.ui.registry.setDecoratorByClassName;goog.ui.Control.getDecorator=goog.ui.registry.getDecorator;goog.ui.Control.prototype.content_=null;goog.ui.Control.prototype.state_=0;
                +goog.ui.Control.prototype.supportedStates_=goog.ui.Component.State.DISABLED|goog.ui.Component.State.HOVER|goog.ui.Component.State.ACTIVE|goog.ui.Component.State.FOCUSED;goog.ui.Control.prototype.autoStates_=goog.ui.Component.State.ALL;goog.ui.Control.prototype.statesWithTransitionEvents_=0;goog.ui.Control.prototype.visible_=!0;goog.ui.Control.prototype.extraClassNames_=null;goog.ui.Control.prototype.handleMouseEvents_=!0;goog.ui.Control.prototype.allowTextSelection_=!1;
                +goog.ui.Control.prototype.preferredAriaRole_=null;goog.ui.Control.prototype.isHandleMouseEvents=function(){return this.handleMouseEvents_};goog.ui.Control.prototype.setHandleMouseEvents=function(a){this.isInDocument()&&a!=this.handleMouseEvents_&&this.enableMouseEventHandling_(a);this.handleMouseEvents_=a};goog.ui.Control.prototype.getKeyEventTarget=function(){return this.renderer_.getKeyEventTarget(this)};
                +goog.ui.Control.prototype.getKeyHandler=function(){return this.keyHandler_||(this.keyHandler_=new goog.events.KeyHandler)};goog.ui.Control.prototype.getRenderer=function(){return this.renderer_};goog.ui.Control.prototype.setRenderer=function(a){if(this.isInDocument())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.getElement()&&this.setElementInternal(null);this.renderer_=a};goog.ui.Control.prototype.getExtraClassNames=function(){return this.extraClassNames_};
                +goog.ui.Control.prototype.addClassName=function(a){a&&(this.extraClassNames_?goog.array.contains(this.extraClassNames_,a)||this.extraClassNames_.push(a):this.extraClassNames_=[a],this.renderer_.enableExtraClassName(this,a,!0))};goog.ui.Control.prototype.removeClassName=function(a){a&&this.extraClassNames_&&goog.array.remove(this.extraClassNames_,a)&&(0==this.extraClassNames_.length&&(this.extraClassNames_=null),this.renderer_.enableExtraClassName(this,a,!1))};
                +goog.ui.Control.prototype.enableClassName=function(a,b){b?this.addClassName(a):this.removeClassName(a)};goog.ui.Control.prototype.createDom=function(){var a=this.renderer_.createDom(this);this.setElementInternal(a);this.renderer_.setAriaRole(a,this.getPreferredAriaRole());this.isAllowTextSelection()||this.renderer_.setAllowTextSelection(a,!1);this.isVisible()||this.renderer_.setVisible(a,!1)};goog.ui.Control.prototype.getPreferredAriaRole=function(){return this.preferredAriaRole_};
                +goog.ui.Control.prototype.setPreferredAriaRole=function(a){this.preferredAriaRole_=a};goog.ui.Control.prototype.getAriaLabel=function(){return this.ariaLabel_};goog.ui.Control.prototype.setAriaLabel=function(a){this.ariaLabel_=a;var b=this.getElement();b&&this.renderer_.setAriaLabel(b,a)};goog.ui.Control.prototype.getContentElement=function(){return this.renderer_.getContentElement(this.getElement())};goog.ui.Control.prototype.canDecorate=function(a){return this.renderer_.canDecorate(a)};
                +goog.ui.Control.prototype.decorateInternal=function(a){a=this.renderer_.decorate(this,a);this.setElementInternal(a);this.renderer_.setAriaRole(a,this.getPreferredAriaRole());this.isAllowTextSelection()||this.renderer_.setAllowTextSelection(a,!1);this.visible_="none"!=a.style.display};
                +goog.ui.Control.prototype.enterDocument=function(){goog.ui.Control.superClass_.enterDocument.call(this);this.renderer_.setAriaStates(this,this.getElementStrict());this.renderer_.initializeDom(this);if(this.supportedStates_&~goog.ui.Component.State.DISABLED&&(this.isHandleMouseEvents()&&this.enableMouseEventHandling_(!0),this.isSupportedState(goog.ui.Component.State.FOCUSED))){var a=this.getKeyEventTarget();if(a){var b=this.getKeyHandler();b.attach(a);this.getHandler().listen(b,goog.events.KeyHandler.EventType.KEY,
                +this.handleKeyEvent).listen(a,goog.events.EventType.FOCUS,this.handleFocus).listen(a,goog.events.EventType.BLUR,this.handleBlur)}}};
                +goog.ui.Control.prototype.enableMouseEventHandling_=function(a){var b=this.getHandler(),c=this.getElement();a?(b.listen(c,goog.events.EventType.MOUSEOVER,this.handleMouseOver).listen(c,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).listen(c,goog.events.EventType.MOUSEUP,this.handleMouseUp).listen(c,goog.events.EventType.MOUSEOUT,this.handleMouseOut),this.handleContextMenu!=goog.nullFunction&&b.listen(c,goog.events.EventType.CONTEXTMENU,this.handleContextMenu),goog.userAgent.IE&&(goog.userAgent.isVersionOrHigher(9)||
                +b.listen(c,goog.events.EventType.DBLCLICK,this.handleDblClick),this.ieMouseEventSequenceSimulator_||(this.ieMouseEventSequenceSimulator_=new goog.ui.Control.IeMouseEventSequenceSimulator_(this),this.registerDisposable(this.ieMouseEventSequenceSimulator_)))):(b.unlisten(c,goog.events.EventType.MOUSEOVER,this.handleMouseOver).unlisten(c,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).unlisten(c,goog.events.EventType.MOUSEUP,this.handleMouseUp).unlisten(c,goog.events.EventType.MOUSEOUT,this.handleMouseOut),
                +this.handleContextMenu!=goog.nullFunction&&b.unlisten(c,goog.events.EventType.CONTEXTMENU,this.handleContextMenu),goog.userAgent.IE&&(goog.userAgent.isVersionOrHigher(9)||b.unlisten(c,goog.events.EventType.DBLCLICK,this.handleDblClick),goog.dispose(this.ieMouseEventSequenceSimulator_),this.ieMouseEventSequenceSimulator_=null))};
                +goog.ui.Control.prototype.exitDocument=function(){goog.ui.Control.superClass_.exitDocument.call(this);this.keyHandler_&&this.keyHandler_.detach();this.isVisible()&&this.isEnabled()&&this.renderer_.setFocusable(this,!1)};goog.ui.Control.prototype.disposeInternal=function(){goog.ui.Control.superClass_.disposeInternal.call(this);this.keyHandler_&&(this.keyHandler_.dispose(),delete this.keyHandler_);delete this.renderer_;this.ieMouseEventSequenceSimulator_=this.extraClassNames_=this.content_=null};
                +goog.ui.Control.prototype.getContent=function(){return this.content_};goog.ui.Control.prototype.setContent=function(a){this.renderer_.setContent(this.getElement(),a);this.setContentInternal(a)};goog.ui.Control.prototype.setContentInternal=function(a){this.content_=a};goog.ui.Control.prototype.getCaption=function(){var a=this.getContent();if(!a)return"";a=goog.isString(a)?a:goog.isArray(a)?goog.array.map(a,goog.dom.getRawTextContent).join(""):goog.dom.getTextContent(a);return goog.string.collapseBreakingSpaces(a)};
                +goog.ui.Control.prototype.setCaption=function(a){this.setContent(a)};goog.ui.Control.prototype.setRightToLeft=function(a){goog.ui.Control.superClass_.setRightToLeft.call(this,a);var b=this.getElement();b&&this.renderer_.setRightToLeft(b,a)};goog.ui.Control.prototype.isAllowTextSelection=function(){return this.allowTextSelection_};goog.ui.Control.prototype.setAllowTextSelection=function(a){this.allowTextSelection_=a;var b=this.getElement();b&&this.renderer_.setAllowTextSelection(b,a)};
                +goog.ui.Control.prototype.isVisible=function(){return this.visible_};goog.ui.Control.prototype.setVisible=function(a,b){return b||this.visible_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.SHOW:goog.ui.Component.EventType.HIDE)?((b=this.getElement())&&this.renderer_.setVisible(b,a),this.isEnabled()&&this.renderer_.setFocusable(this,a),this.visible_=a,!0):!1};goog.ui.Control.prototype.isEnabled=function(){return!this.hasState(goog.ui.Component.State.DISABLED)};
                +goog.ui.Control.prototype.isParentDisabled_=function(){var a=this.getParent();return!!a&&"function"==typeof a.isEnabled&&!a.isEnabled()};goog.ui.Control.prototype.setEnabled=function(a){!this.isParentDisabled_()&&this.isTransitionAllowed(goog.ui.Component.State.DISABLED,!a)&&(a||(this.setActive(!1),this.setHighlighted(!1)),this.isVisible()&&this.renderer_.setFocusable(this,a),this.setState(goog.ui.Component.State.DISABLED,!a,!0))};goog.ui.Control.prototype.isHighlighted=function(){return this.hasState(goog.ui.Component.State.HOVER)};
                +goog.ui.Control.prototype.setHighlighted=function(a){this.isTransitionAllowed(goog.ui.Component.State.HOVER,a)&&this.setState(goog.ui.Component.State.HOVER,a)};goog.ui.Control.prototype.isActive=function(){return this.hasState(goog.ui.Component.State.ACTIVE)};goog.ui.Control.prototype.setActive=function(a){this.isTransitionAllowed(goog.ui.Component.State.ACTIVE,a)&&this.setState(goog.ui.Component.State.ACTIVE,a)};goog.ui.Control.prototype.isSelected=function(){return this.hasState(goog.ui.Component.State.SELECTED)};
                +goog.ui.Control.prototype.setSelected=function(a){this.isTransitionAllowed(goog.ui.Component.State.SELECTED,a)&&this.setState(goog.ui.Component.State.SELECTED,a)};goog.ui.Control.prototype.isChecked=function(){return this.hasState(goog.ui.Component.State.CHECKED)};goog.ui.Control.prototype.setChecked=function(a){this.isTransitionAllowed(goog.ui.Component.State.CHECKED,a)&&this.setState(goog.ui.Component.State.CHECKED,a)};goog.ui.Control.prototype.isFocused=function(){return this.hasState(goog.ui.Component.State.FOCUSED)};
                +goog.ui.Control.prototype.setFocused=function(a){this.isTransitionAllowed(goog.ui.Component.State.FOCUSED,a)&&this.setState(goog.ui.Component.State.FOCUSED,a)};goog.ui.Control.prototype.isOpen=function(){return this.hasState(goog.ui.Component.State.OPENED)};goog.ui.Control.prototype.setOpen=function(a){this.isTransitionAllowed(goog.ui.Component.State.OPENED,a)&&this.setState(goog.ui.Component.State.OPENED,a)};goog.ui.Control.prototype.getState=function(){return this.state_};
                +goog.ui.Control.prototype.hasState=function(a){return!!(this.state_&a)};goog.ui.Control.prototype.setState=function(a,b,c){c||a!=goog.ui.Component.State.DISABLED?this.isSupportedState(a)&&b!=this.hasState(a)&&(this.renderer_.setState(this,a,b),this.state_=b?this.state_|a:this.state_&~a):this.setEnabled(!b)};goog.ui.Control.prototype.setStateInternal=function(a){this.state_=a};goog.ui.Control.prototype.isSupportedState=function(a){return!!(this.supportedStates_&a)};
                +goog.ui.Control.prototype.setSupportedState=function(a,b){if(this.isInDocument()&&this.hasState(a)&&!b)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);!b&&this.hasState(a)&&this.setState(a,!1);this.supportedStates_=b?this.supportedStates_|a:this.supportedStates_&~a};goog.ui.Control.prototype.isAutoState=function(a){return!!(this.autoStates_&a)&&this.isSupportedState(a)};goog.ui.Control.prototype.setAutoStates=function(a,b){this.autoStates_=b?this.autoStates_|a:this.autoStates_&~a};
                +goog.ui.Control.prototype.isDispatchTransitionEvents=function(a){return!!(this.statesWithTransitionEvents_&a)&&this.isSupportedState(a)};goog.ui.Control.prototype.setDispatchTransitionEvents=function(a,b){this.statesWithTransitionEvents_=b?this.statesWithTransitionEvents_|a:this.statesWithTransitionEvents_&~a};
                +goog.ui.Control.prototype.isTransitionAllowed=function(a,b){return this.isSupportedState(a)&&this.hasState(a)!=b&&(!(this.statesWithTransitionEvents_&a)||this.dispatchEvent(goog.ui.Component.getStateTransitionEvent(a,b)))&&!this.isDisposed()};goog.ui.Control.prototype.handleMouseOver=function(a){!goog.ui.Control.isMouseEventWithinElement_(a,this.getElement())&&this.dispatchEvent(goog.ui.Component.EventType.ENTER)&&this.isEnabled()&&this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0)};
                +goog.ui.Control.prototype.handleMouseOut=function(a){!goog.ui.Control.isMouseEventWithinElement_(a,this.getElement())&&this.dispatchEvent(goog.ui.Component.EventType.LEAVE)&&(this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1),this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!1))};goog.ui.Control.prototype.handleContextMenu=goog.nullFunction;goog.ui.Control.isMouseEventWithinElement_=function(a,b){return!!a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)};
                +goog.ui.Control.prototype.handleMouseDown=function(a){this.isEnabled()&&(this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0),a.isMouseActionButton()&&(this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!0),this.renderer_&&this.renderer_.isFocusable(this)&&this.getKeyEventTarget().focus()));!this.isAllowTextSelection()&&a.isMouseActionButton()&&a.preventDefault()};
                +goog.ui.Control.prototype.handleMouseUp=function(a){this.isEnabled()&&(this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0),this.isActive()&&this.performActionInternal(a)&&this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1))};goog.ui.Control.prototype.handleDblClick=function(a){this.isEnabled()&&this.performActionInternal(a)};
                +goog.ui.Control.prototype.performActionInternal=function(a){this.isAutoState(goog.ui.Component.State.CHECKED)&&this.setChecked(!this.isChecked());this.isAutoState(goog.ui.Component.State.SELECTED)&&this.setSelected(!0);this.isAutoState(goog.ui.Component.State.OPENED)&&this.setOpen(!this.isOpen());var b=new goog.events.Event(goog.ui.Component.EventType.ACTION,this);a&&(b.altKey=a.altKey,b.ctrlKey=a.ctrlKey,b.metaKey=a.metaKey,b.shiftKey=a.shiftKey,b.platformModifierKey=a.platformModifierKey);return this.dispatchEvent(b)};
                +goog.ui.Control.prototype.handleFocus=function(a){this.isAutoState(goog.ui.Component.State.FOCUSED)&&this.setFocused(!0)};goog.ui.Control.prototype.handleBlur=function(a){this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1);this.isAutoState(goog.ui.Component.State.FOCUSED)&&this.setFocused(!1)};goog.ui.Control.prototype.handleKeyEvent=function(a){return this.isVisible()&&this.isEnabled()&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
                +goog.ui.Control.prototype.handleKeyEventInternal=function(a){return a.keyCode==goog.events.KeyCodes.ENTER&&this.performActionInternal(a)};goog.ui.registry.setDefaultRenderer(goog.ui.Control,goog.ui.ControlRenderer);goog.ui.registry.setDecoratorByClassName(goog.ui.ControlRenderer.CSS_CLASS,function(){return new goog.ui.Control(null)});
                +goog.ui.Control.IeMouseEventSequenceSimulator_=function(a){goog.Disposable.call(this);this.control_=a;this.clickExpected_=!1;this.handler_=new goog.events.EventHandler(this);this.registerDisposable(this.handler_);a=this.control_.getElementStrict();this.handler_.listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseDown_).listen(a,goog.events.EventType.MOUSEUP,this.handleMouseUp_).listen(a,goog.events.EventType.CLICK,this.handleClick_)};
                +goog.inherits(goog.ui.Control.IeMouseEventSequenceSimulator_,goog.Disposable);goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_=!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9);goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleMouseDown_=function(){this.clickExpected_=!1};goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleMouseUp_=function(){this.clickExpected_=!0};
                +goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_=function(a,b){if(!goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_)return a.button=goog.events.BrowserEvent.MouseButton.LEFT,a.type=b,a;var c=document.createEvent("MouseEvents");c.initMouseEvent(b,a.bubbles,a.cancelable,a.view||null,a.detail,a.screenX,a.screenY,a.clientX,a.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,goog.events.BrowserEvent.MouseButton.LEFT,a.relatedTarget||null);return c};
                +goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleClick_=function(a){if(this.clickExpected_)this.clickExpected_=!1;else{var b=a.getBrowserEvent(),c=b.button,d=b.type,e=goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_(b,goog.events.EventType.MOUSEDOWN);this.control_.handleMouseDown(new goog.events.BrowserEvent(e,a.currentTarget));e=goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_(b,goog.events.EventType.MOUSEUP);this.control_.handleMouseUp(new goog.events.BrowserEvent(e,
                +a.currentTarget));goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_||(b.button=c,b.type=d)}};goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.disposeInternal=function(){this.control_=null;goog.ui.Control.IeMouseEventSequenceSimulator_.superClass_.disposeInternal.call(this)};goog.ui.Container=function(a,b,c){goog.ui.Component.call(this,c);this.renderer_=b||goog.ui.ContainerRenderer.getInstance();this.orientation_=a||this.renderer_.getDefaultOrientation()};goog.inherits(goog.ui.Container,goog.ui.Component);goog.tagUnsealableClass(goog.ui.Container);goog.ui.Container.EventType={AFTER_SHOW:"aftershow",AFTER_HIDE:"afterhide"};goog.ui.Container.Orientation={HORIZONTAL:"horizontal",VERTICAL:"vertical"};goog.ui.Container.prototype.keyEventTarget_=null;
                +goog.ui.Container.prototype.keyHandler_=null;goog.ui.Container.prototype.renderer_=null;goog.ui.Container.prototype.orientation_=null;goog.ui.Container.prototype.visible_=!0;goog.ui.Container.prototype.enabled_=!0;goog.ui.Container.prototype.focusable_=!0;goog.ui.Container.prototype.highlightedIndex_=-1;goog.ui.Container.prototype.openItem_=null;goog.ui.Container.prototype.mouseButtonPressed_=!1;goog.ui.Container.prototype.allowFocusableChildren_=!1;
                +goog.ui.Container.prototype.openFollowsHighlight_=!0;goog.ui.Container.prototype.childElementIdMap_=null;goog.ui.Container.prototype.getKeyEventTarget=function(){return this.keyEventTarget_||this.renderer_.getKeyEventTarget(this)};
                +goog.ui.Container.prototype.setKeyEventTarget=function(a){if(this.focusable_){var b=this.getKeyEventTarget(),c=this.isInDocument();this.keyEventTarget_=a;var d=this.getKeyEventTarget();c&&(this.keyEventTarget_=b,this.enableFocusHandling_(!1),this.keyEventTarget_=a,this.getKeyHandler().attach(d),this.enableFocusHandling_(!0))}else throw Error("Can't set key event target for container that doesn't support keyboard focus!");};
                +goog.ui.Container.prototype.getKeyHandler=function(){return this.keyHandler_||(this.keyHandler_=new goog.events.KeyHandler(this.getKeyEventTarget()))};goog.ui.Container.prototype.getRenderer=function(){return this.renderer_};goog.ui.Container.prototype.setRenderer=function(a){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.renderer_=a};goog.ui.Container.prototype.createDom=function(){this.setElementInternal(this.renderer_.createDom(this))};
                +goog.ui.Container.prototype.getContentElement=function(){return this.renderer_.getContentElement(this.getElement())};goog.ui.Container.prototype.canDecorate=function(a){return this.renderer_.canDecorate(a)};goog.ui.Container.prototype.decorateInternal=function(a){this.setElementInternal(this.renderer_.decorate(this,a));"none"==a.style.display&&(this.visible_=!1)};
                +goog.ui.Container.prototype.enterDocument=function(){goog.ui.Container.superClass_.enterDocument.call(this);this.forEachChild(function(a){a.isInDocument()&&this.registerChildId_(a)},this);var a=this.getElement();this.renderer_.initializeDom(this);this.setVisible(this.visible_,!0);this.getHandler().listen(this,goog.ui.Component.EventType.ENTER,this.handleEnterItem).listen(this,goog.ui.Component.EventType.HIGHLIGHT,this.handleHighlightItem).listen(this,goog.ui.Component.EventType.UNHIGHLIGHT,this.handleUnHighlightItem).listen(this,
                +goog.ui.Component.EventType.OPEN,this.handleOpenItem).listen(this,goog.ui.Component.EventType.CLOSE,this.handleCloseItem).listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).listen(goog.dom.getOwnerDocument(a),goog.events.EventType.MOUSEUP,this.handleDocumentMouseUp).listen(a,[goog.events.EventType.MOUSEDOWN,goog.events.EventType.MOUSEUP,goog.events.EventType.MOUSEOVER,goog.events.EventType.MOUSEOUT,goog.events.EventType.CONTEXTMENU],this.handleChildMouseEvents);this.isFocusable()&&this.enableFocusHandling_(!0)};
                +goog.ui.Container.prototype.enableFocusHandling_=function(a){var b=this.getHandler(),c=this.getKeyEventTarget();a?b.listen(c,goog.events.EventType.FOCUS,this.handleFocus).listen(c,goog.events.EventType.BLUR,this.handleBlur).listen(this.getKeyHandler(),goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent):b.unlisten(c,goog.events.EventType.FOCUS,this.handleFocus).unlisten(c,goog.events.EventType.BLUR,this.handleBlur).unlisten(this.getKeyHandler(),goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent)};
                +goog.ui.Container.prototype.exitDocument=function(){this.setHighlightedIndex(-1);this.openItem_&&this.openItem_.setOpen(!1);this.mouseButtonPressed_=!1;goog.ui.Container.superClass_.exitDocument.call(this)};goog.ui.Container.prototype.disposeInternal=function(){goog.ui.Container.superClass_.disposeInternal.call(this);this.keyHandler_&&(this.keyHandler_.dispose(),this.keyHandler_=null);this.renderer_=this.openItem_=this.childElementIdMap_=this.keyEventTarget_=null};
                +goog.ui.Container.prototype.handleEnterItem=function(a){return!0};
                +goog.ui.Container.prototype.handleHighlightItem=function(a){var b=this.indexOfChild(a.target);if(-1<b&&b!=this.highlightedIndex_){var c=this.getHighlighted();c&&c.setHighlighted(!1);this.highlightedIndex_=b;c=this.getHighlighted();this.isMouseButtonPressed()&&c.setActive(!0);this.openFollowsHighlight_&&this.openItem_&&c!=this.openItem_&&(c.isSupportedState(goog.ui.Component.State.OPENED)?c.setOpen(!0):this.openItem_.setOpen(!1))}b=this.getElement();goog.asserts.assert(b,"The DOM element for the container cannot be null.");
                +null!=a.target.getElement()&&goog.a11y.aria.setState(b,goog.a11y.aria.State.ACTIVEDESCENDANT,a.target.getElement().id)};goog.ui.Container.prototype.handleUnHighlightItem=function(a){a.target==this.getHighlighted()&&(this.highlightedIndex_=-1);a=this.getElement();goog.asserts.assert(a,"The DOM element for the container cannot be null.");goog.a11y.aria.removeState(a,goog.a11y.aria.State.ACTIVEDESCENDANT)};
                +goog.ui.Container.prototype.handleOpenItem=function(a){(a=a.target)&&a!=this.openItem_&&a.getParent()==this&&(this.openItem_&&this.openItem_.setOpen(!1),this.openItem_=a)};goog.ui.Container.prototype.handleCloseItem=function(a){a.target==this.openItem_&&(this.openItem_=null);var b=this.getElement(),c=a.target.getElement();b&&a.target.isHighlighted()&&c&&goog.a11y.aria.setActiveDescendant(b,c)};
                +goog.ui.Container.prototype.handleMouseDown=function(a){this.enabled_&&this.setMouseButtonPressed(!0);var b=this.getKeyEventTarget();b&&goog.dom.isFocusableTabIndex(b)?b.focus():a.preventDefault()};goog.ui.Container.prototype.handleDocumentMouseUp=function(a){this.setMouseButtonPressed(!1)};
                +goog.ui.Container.prototype.handleChildMouseEvents=function(a){var b=this.getOwnerControl(a.target);if(b)switch(a.type){case goog.events.EventType.MOUSEDOWN:b.handleMouseDown(a);break;case goog.events.EventType.MOUSEUP:b.handleMouseUp(a);break;case goog.events.EventType.MOUSEOVER:b.handleMouseOver(a);break;case goog.events.EventType.MOUSEOUT:b.handleMouseOut(a);break;case goog.events.EventType.CONTEXTMENU:b.handleContextMenu(a)}};
                +goog.ui.Container.prototype.getOwnerControl=function(a){if(this.childElementIdMap_)for(var b=this.getElement();a&&a!==b;){var c=a.id;if(c in this.childElementIdMap_)return this.childElementIdMap_[c];a=a.parentNode}return null};goog.ui.Container.prototype.handleFocus=function(a){};goog.ui.Container.prototype.handleBlur=function(a){this.setHighlightedIndex(-1);this.setMouseButtonPressed(!1);this.openItem_&&this.openItem_.setOpen(!1)};
                +goog.ui.Container.prototype.handleKeyEvent=function(a){return this.isEnabled()&&this.isVisible()&&(0!=this.getChildCount()||this.keyEventTarget_)&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
                +goog.ui.Container.prototype.handleKeyEventInternal=function(a){var b=this.getHighlighted();if(b&&"function"==typeof b.handleKeyEvent&&b.handleKeyEvent(a)||this.openItem_&&this.openItem_!=b&&"function"==typeof this.openItem_.handleKeyEvent&&this.openItem_.handleKeyEvent(a))return!0;if(a.shiftKey||a.ctrlKey||a.metaKey||a.altKey)return!1;switch(a.keyCode){case goog.events.KeyCodes.ESC:if(this.isFocusable())this.getKeyEventTarget().blur();else return!1;break;case goog.events.KeyCodes.HOME:this.highlightFirst();
                +break;case goog.events.KeyCodes.END:this.highlightLast();break;case goog.events.KeyCodes.UP:if(this.orientation_==goog.ui.Container.Orientation.VERTICAL)this.highlightPrevious();else return!1;break;case goog.events.KeyCodes.LEFT:if(this.orientation_==goog.ui.Container.Orientation.HORIZONTAL)this.isRightToLeft()?this.highlightNext():this.highlightPrevious();else return!1;break;case goog.events.KeyCodes.DOWN:if(this.orientation_==goog.ui.Container.Orientation.VERTICAL)this.highlightNext();else return!1;
                +break;case goog.events.KeyCodes.RIGHT:if(this.orientation_==goog.ui.Container.Orientation.HORIZONTAL)this.isRightToLeft()?this.highlightPrevious():this.highlightNext();else return!1;break;default:return!1}return!0};goog.ui.Container.prototype.registerChildId_=function(a){var b=a.getElement(),b=b.id||(b.id=a.getId());this.childElementIdMap_||(this.childElementIdMap_={});this.childElementIdMap_[b]=a};
                +goog.ui.Container.prototype.addChild=function(a,b){goog.asserts.assertInstanceof(a,goog.ui.Control,"The child of a container must be a control");goog.ui.Container.superClass_.addChild.call(this,a,b)};
                +goog.ui.Container.prototype.addChildAt=function(a,b,c){goog.asserts.assertInstanceof(a,goog.ui.Control);a.setDispatchTransitionEvents(goog.ui.Component.State.HOVER,!0);a.setDispatchTransitionEvents(goog.ui.Component.State.OPENED,!0);!this.isFocusable()&&this.isFocusableChildrenAllowed()||a.setSupportedState(goog.ui.Component.State.FOCUSED,!1);a.setHandleMouseEvents(!1);var d=a.getParent()==this?this.indexOfChild(a):-1;goog.ui.Container.superClass_.addChildAt.call(this,a,b,c);a.isInDocument()&&this.isInDocument()&&
                +this.registerChildId_(a);this.updateHighlightedIndex_(d,b)};goog.ui.Container.prototype.updateHighlightedIndex_=function(a,b){-1==a&&(a=this.getChildCount());a==this.highlightedIndex_?this.highlightedIndex_=Math.min(this.getChildCount()-1,b):a>this.highlightedIndex_&&b<=this.highlightedIndex_?this.highlightedIndex_++:a<this.highlightedIndex_&&b>this.highlightedIndex_&&this.highlightedIndex_--};
                +goog.ui.Container.prototype.removeChild=function(a,b){a=goog.isString(a)?this.getChild(a):a;goog.asserts.assertInstanceof(a,goog.ui.Control);if(a){var c=this.indexOfChild(a);-1!=c&&(c==this.highlightedIndex_?(a.setHighlighted(!1),this.highlightedIndex_=-1):c<this.highlightedIndex_&&this.highlightedIndex_--);(c=a.getElement())&&c.id&&this.childElementIdMap_&&goog.object.remove(this.childElementIdMap_,c.id)}a=goog.ui.Container.superClass_.removeChild.call(this,a,b);a.setHandleMouseEvents(!0);return a};
                +goog.ui.Container.prototype.getOrientation=function(){return this.orientation_};goog.ui.Container.prototype.setOrientation=function(a){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.orientation_=a};goog.ui.Container.prototype.isVisible=function(){return this.visible_};
                +goog.ui.Container.prototype.setVisible=function(a,b){if(b||this.visible_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.SHOW:goog.ui.Component.EventType.HIDE)){this.visible_=a;var c=this.getElement();c&&(goog.style.setElementShown(c,a),this.isFocusable()&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),this.enabled_&&this.visible_),b||this.dispatchEvent(this.visible_?goog.ui.Container.EventType.AFTER_SHOW:goog.ui.Container.EventType.AFTER_HIDE));return!0}return!1};
                +goog.ui.Container.prototype.isEnabled=function(){return this.enabled_};
                +goog.ui.Container.prototype.setEnabled=function(a){this.enabled_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.ENABLE:goog.ui.Component.EventType.DISABLE)&&(a?(this.enabled_=!0,this.forEachChild(function(a){a.wasDisabled?delete a.wasDisabled:a.setEnabled(!0)})):(this.forEachChild(function(a){a.isEnabled()?a.setEnabled(!1):a.wasDisabled=!0}),this.enabled_=!1,this.setMouseButtonPressed(!1)),this.isFocusable()&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),a&&this.visible_))};
                +goog.ui.Container.prototype.isFocusable=function(){return this.focusable_};goog.ui.Container.prototype.setFocusable=function(a){a!=this.focusable_&&this.isInDocument()&&this.enableFocusHandling_(a);this.focusable_=a;this.enabled_&&this.visible_&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),a)};goog.ui.Container.prototype.isFocusableChildrenAllowed=function(){return this.allowFocusableChildren_};
                +goog.ui.Container.prototype.setFocusableChildrenAllowed=function(a){this.allowFocusableChildren_=a};goog.ui.Container.prototype.isOpenFollowsHighlight=function(){return this.openFollowsHighlight_};goog.ui.Container.prototype.setOpenFollowsHighlight=function(a){this.openFollowsHighlight_=a};goog.ui.Container.prototype.getHighlightedIndex=function(){return this.highlightedIndex_};
                +goog.ui.Container.prototype.setHighlightedIndex=function(a){(a=this.getChildAt(a))?a.setHighlighted(!0):-1<this.highlightedIndex_&&this.getHighlighted().setHighlighted(!1)};goog.ui.Container.prototype.setHighlighted=function(a){this.setHighlightedIndex(this.indexOfChild(a))};goog.ui.Container.prototype.getHighlighted=function(){return this.getChildAt(this.highlightedIndex_)};
                +goog.ui.Container.prototype.highlightFirst=function(){this.highlightHelper(function(a,b){return(a+1)%b},this.getChildCount()-1)};goog.ui.Container.prototype.highlightLast=function(){this.highlightHelper(function(a,b){a--;return 0>a?b-1:a},0)};goog.ui.Container.prototype.highlightNext=function(){this.highlightHelper(function(a,b){return(a+1)%b},this.highlightedIndex_)};goog.ui.Container.prototype.highlightPrevious=function(){this.highlightHelper(function(a,b){a--;return 0>a?b-1:a},this.highlightedIndex_)};
                +goog.ui.Container.prototype.highlightHelper=function(a,b){b=0>b?this.indexOfChild(this.openItem_):b;var c=this.getChildCount();b=a.call(this,b,c);for(var d=0;d<=c;){var e=this.getChildAt(b);if(e&&this.canHighlightItem(e))return this.setHighlightedIndexFromKeyEvent(b),!0;d++;b=a.call(this,b,c)}return!1};goog.ui.Container.prototype.canHighlightItem=function(a){return a.isVisible()&&a.isEnabled()&&a.isSupportedState(goog.ui.Component.State.HOVER)};
                +goog.ui.Container.prototype.setHighlightedIndexFromKeyEvent=function(a){this.setHighlightedIndex(a)};goog.ui.Container.prototype.getOpenItem=function(){return this.openItem_};goog.ui.Container.prototype.isMouseButtonPressed=function(){return this.mouseButtonPressed_};goog.ui.Container.prototype.setMouseButtonPressed=function(a){this.mouseButtonPressed_=a};goog.ui.MenuHeaderRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.MenuHeaderRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuHeaderRenderer);goog.ui.MenuHeaderRenderer.CSS_CLASS="goog-menuheader";goog.ui.MenuHeaderRenderer.prototype.getCssClass=function(){return goog.ui.MenuHeaderRenderer.CSS_CLASS};goog.ui.MenuHeader=function(a,b,c){goog.ui.Control.call(this,a,c||goog.ui.MenuHeaderRenderer.getInstance(),b);this.setSupportedState(goog.ui.Component.State.DISABLED,!1);this.setSupportedState(goog.ui.Component.State.HOVER,!1);this.setSupportedState(goog.ui.Component.State.ACTIVE,!1);this.setSupportedState(goog.ui.Component.State.FOCUSED,!1);this.setStateInternal(goog.ui.Component.State.DISABLED)};goog.inherits(goog.ui.MenuHeader,goog.ui.Control);
                +goog.ui.registry.setDecoratorByClassName(goog.ui.MenuHeaderRenderer.CSS_CLASS,function(){return new goog.ui.MenuHeader(null)});goog.ui.MenuItemRenderer=function(){goog.ui.ControlRenderer.call(this);this.classNameCache_=[]};goog.inherits(goog.ui.MenuItemRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuItemRenderer);goog.ui.MenuItemRenderer.CSS_CLASS="goog-menuitem";goog.ui.MenuItemRenderer.CompositeCssClassIndex_={HOVER:0,CHECKBOX:1,CONTENT:2};
                +goog.ui.MenuItemRenderer.prototype.getCompositeCssClass_=function(a){var b=this.classNameCache_[a];if(!b){switch(a){case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER:b=this.getStructuralCssClass()+"-highlight";break;case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX:b=this.getStructuralCssClass()+"-checkbox";break;case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT:b=this.getStructuralCssClass()+"-content"}this.classNameCache_[a]=b}return b};
                +goog.ui.MenuItemRenderer.prototype.getAriaRole=function(){return goog.a11y.aria.Role.MENU_ITEM};goog.ui.MenuItemRenderer.prototype.createDom=function(a){var b=a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "),this.createContent(a.getContent(),a.getDomHelper()));this.setEnableCheckBoxStructure(a,b,a.isSupportedState(goog.ui.Component.State.SELECTED)||a.isSupportedState(goog.ui.Component.State.CHECKED));return b};
                +goog.ui.MenuItemRenderer.prototype.getContentElement=function(a){return a&&a.firstChild};goog.ui.MenuItemRenderer.prototype.decorate=function(a,b){goog.asserts.assert(b);this.hasContentStructure(b)||b.appendChild(this.createContent(b.childNodes,a.getDomHelper()));goog.dom.classlist.contains(b,"goog-option")&&(a.setCheckable(!0),this.setCheckable(a,b,!0));return goog.ui.MenuItemRenderer.superClass_.decorate.call(this,a,b)};
                +goog.ui.MenuItemRenderer.prototype.setContent=function(a,b){var c=this.getContentElement(a),d=this.hasCheckBoxStructure(a)?c.firstChild:null;goog.ui.MenuItemRenderer.superClass_.setContent.call(this,a,b);d&&!this.hasCheckBoxStructure(a)&&c.insertBefore(d,c.firstChild||null)};
                +goog.ui.MenuItemRenderer.prototype.hasContentStructure=function(a){a=goog.dom.getFirstElementChild(a);var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT);return!!a&&goog.dom.classlist.contains(a,b)};goog.ui.MenuItemRenderer.prototype.createContent=function(a,b){var c=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT);return b.createDom("DIV",c,a)};
                +goog.ui.MenuItemRenderer.prototype.setSelectable=function(a,b,c){a&&b&&this.setEnableCheckBoxStructure(a,b,c)};goog.ui.MenuItemRenderer.prototype.setCheckable=function(a,b,c){a&&b&&this.setEnableCheckBoxStructure(a,b,c)};goog.ui.MenuItemRenderer.prototype.hasCheckBoxStructure=function(a){if(a=this.getContentElement(a)){a=a.firstChild;var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX);return!!a&&goog.dom.isElement(a)&&goog.dom.classlist.contains(a,b)}return!1};
                +goog.ui.MenuItemRenderer.prototype.setEnableCheckBoxStructure=function(a,b,c){this.setAriaRole(b,a.getPreferredAriaRole());this.setAriaStates(a,b);c!=this.hasCheckBoxStructure(b)&&(goog.dom.classlist.enable(b,"goog-option",c),b=this.getContentElement(b),c?(c=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX),b.insertBefore(a.getDomHelper().createDom("DIV",c),b.firstChild||null)):b.removeChild(b.firstChild))};
                +goog.ui.MenuItemRenderer.prototype.getClassForState=function(a){switch(a){case goog.ui.Component.State.HOVER:return this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER);case goog.ui.Component.State.CHECKED:case goog.ui.Component.State.SELECTED:return"goog-option-selected";default:return goog.ui.MenuItemRenderer.superClass_.getClassForState.call(this,a)}};
                +goog.ui.MenuItemRenderer.prototype.getStateFromClass=function(a){var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER);switch(a){case "goog-option-selected":return goog.ui.Component.State.CHECKED;case b:return goog.ui.Component.State.HOVER;default:return goog.ui.MenuItemRenderer.superClass_.getStateFromClass.call(this,a)}};goog.ui.MenuItemRenderer.prototype.getCssClass=function(){return goog.ui.MenuItemRenderer.CSS_CLASS};goog.ui.MenuItem=function(a,b,c,d){goog.ui.Control.call(this,a,d||goog.ui.MenuItemRenderer.getInstance(),c);this.setValue(b)};goog.inherits(goog.ui.MenuItem,goog.ui.Control);goog.tagUnsealableClass(goog.ui.MenuItem);goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_="goog-menuitem-mnemonic-separator";goog.ui.MenuItem.ACCELERATOR_CLASS="goog-menuitem-accel";goog.ui.MenuItem.prototype.getValue=function(){var a=this.getModel();return null!=a?a:this.getCaption()};goog.ui.MenuItem.prototype.setValue=function(a){this.setModel(a)};
                +goog.ui.MenuItem.prototype.setSupportedState=function(a,b){goog.ui.MenuItem.superClass_.setSupportedState.call(this,a,b);switch(a){case goog.ui.Component.State.SELECTED:this.setSelectableInternal_(b);break;case goog.ui.Component.State.CHECKED:this.setCheckableInternal_(b)}};goog.ui.MenuItem.prototype.setSelectable=function(a){this.setSupportedState(goog.ui.Component.State.SELECTED,a)};
                +goog.ui.MenuItem.prototype.setSelectableInternal_=function(a){this.isChecked()&&!a&&this.setChecked(!1);var b=this.getElement();b&&this.getRenderer().setSelectable(this,b,a)};goog.ui.MenuItem.prototype.setCheckable=function(a){this.setSupportedState(goog.ui.Component.State.CHECKED,a)};goog.ui.MenuItem.prototype.setCheckableInternal_=function(a){var b=this.getElement();b&&this.getRenderer().setCheckable(this,b,a)};
                +goog.ui.MenuItem.prototype.getCaption=function(){var a=this.getContent();if(goog.isArray(a)){var b=goog.ui.MenuItem.ACCELERATOR_CLASS,c=goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_,a=goog.array.map(a,function(a){return goog.dom.isElement(a)&&(goog.dom.classlist.contains(a,b)||goog.dom.classlist.contains(a,c))?"":goog.dom.getRawTextContent(a)}).join("");return goog.string.collapseBreakingSpaces(a)}return goog.ui.MenuItem.superClass_.getCaption.call(this)};
                +goog.ui.MenuItem.prototype.getAccelerator=function(){var a=this.getDomHelper(),b=this.getContent();return goog.isArray(b)&&(b=goog.array.find(b,function(a){return goog.dom.classlist.contains(a,goog.ui.MenuItem.ACCELERATOR_CLASS)}))?a.getTextContent(b):null};
                +goog.ui.MenuItem.prototype.handleMouseUp=function(a){var b=this.getParent();if(b){var c=b.openingCoords;b.openingCoords=null;if(c&&goog.isNumber(a.clientX)&&(b=new goog.math.Coordinate(a.clientX,a.clientY),goog.math.Coordinate.equals(c,b)))return}goog.ui.MenuItem.superClass_.handleMouseUp.call(this,a)};goog.ui.MenuItem.prototype.handleKeyEventInternal=function(a){return a.keyCode==this.getMnemonic()&&this.performActionInternal(a)?!0:goog.ui.MenuItem.superClass_.handleKeyEventInternal.call(this,a)};
                +goog.ui.MenuItem.prototype.setMnemonic=function(a){this.mnemonicKey_=a};goog.ui.MenuItem.prototype.getMnemonic=function(){return this.mnemonicKey_};goog.ui.registry.setDecoratorByClassName(goog.ui.MenuItemRenderer.CSS_CLASS,function(){return new goog.ui.MenuItem(null)});
                +goog.ui.MenuItem.prototype.getPreferredAriaRole=function(){return this.isSupportedState(goog.ui.Component.State.CHECKED)?goog.a11y.aria.Role.MENU_ITEM_CHECKBOX:this.isSupportedState(goog.ui.Component.State.SELECTED)?goog.a11y.aria.Role.MENU_ITEM_RADIO:goog.ui.MenuItem.superClass_.getPreferredAriaRole.call(this)};goog.ui.MenuItem.prototype.getParent=function(){return goog.ui.Control.prototype.getParent.call(this)};goog.ui.MenuItem.prototype.getParentEventTarget=function(){return goog.ui.Control.prototype.getParentEventTarget.call(this)};goog.ui.MenuSeparatorRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.MenuSeparatorRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuSeparatorRenderer);goog.ui.MenuSeparatorRenderer.CSS_CLASS="goog-menuseparator";goog.ui.MenuSeparatorRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getCssClass())};
                +goog.ui.MenuSeparatorRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);if("HR"==b.tagName){var c=b;b=this.createDom(a);goog.dom.insertSiblingBefore(b,c);goog.dom.removeNode(c)}else goog.dom.classlist.add(b,this.getCssClass());return b};goog.ui.MenuSeparatorRenderer.prototype.setContent=function(a,b){};goog.ui.MenuSeparatorRenderer.prototype.getCssClass=function(){return goog.ui.MenuSeparatorRenderer.CSS_CLASS};goog.ui.Separator=function(a,b){goog.ui.Control.call(this,null,a||goog.ui.MenuSeparatorRenderer.getInstance(),b);this.setSupportedState(goog.ui.Component.State.DISABLED,!1);this.setSupportedState(goog.ui.Component.State.HOVER,!1);this.setSupportedState(goog.ui.Component.State.ACTIVE,!1);this.setSupportedState(goog.ui.Component.State.FOCUSED,!1);this.setStateInternal(goog.ui.Component.State.DISABLED)};goog.inherits(goog.ui.Separator,goog.ui.Control);
                +goog.ui.Separator.prototype.enterDocument=function(){goog.ui.Separator.superClass_.enterDocument.call(this);var a=this.getElement();goog.asserts.assert(a,"The DOM element for the separator cannot be null.");goog.a11y.aria.setRole(a,"separator")};goog.ui.registry.setDecoratorByClassName(goog.ui.MenuSeparatorRenderer.CSS_CLASS,function(){return new goog.ui.Separator});goog.ui.MenuRenderer=function(a){goog.ui.ContainerRenderer.call(this,a||goog.a11y.aria.Role.MENU)};goog.inherits(goog.ui.MenuRenderer,goog.ui.ContainerRenderer);goog.addSingletonGetter(goog.ui.MenuRenderer);goog.ui.MenuRenderer.CSS_CLASS="goog-menu";goog.ui.MenuRenderer.prototype.canDecorate=function(a){return"UL"==a.tagName||goog.ui.MenuRenderer.superClass_.canDecorate.call(this,a)};
                +goog.ui.MenuRenderer.prototype.getDecoratorForChild=function(a){return"HR"==a.tagName?new goog.ui.Separator:goog.ui.MenuRenderer.superClass_.getDecoratorForChild.call(this,a)};goog.ui.MenuRenderer.prototype.containsElement=function(a,b){return goog.dom.contains(a.getElement(),b)};goog.ui.MenuRenderer.prototype.getCssClass=function(){return goog.ui.MenuRenderer.CSS_CLASS};
                +goog.ui.MenuRenderer.prototype.initializeDom=function(a){goog.ui.MenuRenderer.superClass_.initializeDom.call(this,a);a=a.getElement();goog.asserts.assert(a,"The menu DOM element cannot be null.");goog.a11y.aria.setState(a,goog.a11y.aria.State.HASPOPUP,"true")};goog.ui.MenuSeparator=function(a){goog.ui.Separator.call(this,goog.ui.MenuSeparatorRenderer.getInstance(),a)};goog.inherits(goog.ui.MenuSeparator,goog.ui.Separator);goog.ui.registry.setDecoratorByClassName(goog.ui.MenuSeparatorRenderer.CSS_CLASS,function(){return new goog.ui.Separator});goog.ui.Menu=function(a,b){goog.ui.Container.call(this,goog.ui.Container.Orientation.VERTICAL,b||goog.ui.MenuRenderer.getInstance(),a);this.setFocusable(!1)};goog.inherits(goog.ui.Menu,goog.ui.Container);goog.tagUnsealableClass(goog.ui.Menu);goog.ui.Menu.EventType={BEFORE_SHOW:goog.ui.Component.EventType.BEFORE_SHOW,SHOW:goog.ui.Component.EventType.SHOW,BEFORE_HIDE:goog.ui.Component.EventType.HIDE,HIDE:goog.ui.Component.EventType.HIDE};goog.ui.Menu.CSS_CLASS=goog.ui.MenuRenderer.CSS_CLASS;
                +goog.ui.Menu.prototype.allowAutoFocus_=!0;goog.ui.Menu.prototype.allowHighlightDisabled_=!1;goog.ui.Menu.prototype.getCssClass=function(){return this.getRenderer().getCssClass()};goog.ui.Menu.prototype.containsElement=function(a){if(this.getRenderer().containsElement(this,a))return!0;for(var b=0,c=this.getChildCount();b<c;b++){var d=this.getChildAt(b);if("function"==typeof d.containsElement&&d.containsElement(a))return!0}return!1};goog.ui.Menu.prototype.addItem=function(a){this.addChild(a,!0)};
                +goog.ui.Menu.prototype.addItemAt=function(a,b){this.addChildAt(a,b,!0)};goog.ui.Menu.prototype.removeItem=function(a){(a=this.removeChild(a,!0))&&a.dispose()};goog.ui.Menu.prototype.removeItemAt=function(a){(a=this.removeChildAt(a,!0))&&a.dispose()};goog.ui.Menu.prototype.getItemAt=function(a){return this.getChildAt(a)};goog.ui.Menu.prototype.getItemCount=function(){return this.getChildCount()};goog.ui.Menu.prototype.getItems=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};
                +goog.ui.Menu.prototype.setPosition=function(a,b){var c=this.isVisible();c||goog.style.setElementShown(this.getElement(),!0);goog.style.setPageOffset(this.getElement(),a,b);c||goog.style.setElementShown(this.getElement(),!1)};goog.ui.Menu.prototype.getPosition=function(){return this.isVisible()?goog.style.getPageOffset(this.getElement()):null};goog.ui.Menu.prototype.setAllowAutoFocus=function(a){(this.allowAutoFocus_=a)&&this.setFocusable(!0)};goog.ui.Menu.prototype.getAllowAutoFocus=function(){return this.allowAutoFocus_};
                +goog.ui.Menu.prototype.setAllowHighlightDisabled=function(a){this.allowHighlightDisabled_=a};goog.ui.Menu.prototype.getAllowHighlightDisabled=function(){return this.allowHighlightDisabled_};goog.ui.Menu.prototype.setVisible=function(a,b,c){(b=goog.ui.Menu.superClass_.setVisible.call(this,a,b))&&a&&this.isInDocument()&&this.allowAutoFocus_&&this.getKeyEventTarget().focus();a&&c&&goog.isNumber(c.clientX)?this.openingCoords=new goog.math.Coordinate(c.clientX,c.clientY):this.openingCoords=null;return b};
                +goog.ui.Menu.prototype.handleEnterItem=function(a){this.allowAutoFocus_&&this.getKeyEventTarget().focus();return goog.ui.Menu.superClass_.handleEnterItem.call(this,a)};goog.ui.Menu.prototype.highlightNextPrefix=function(a){var b=new RegExp("^"+goog.string.regExpEscape(a),"i");return this.highlightHelper(function(a,d){var c=0>a?0:a,f=!1;do{++a;a==d&&(a=0,f=!0);var g=this.getChildAt(a).getCaption();if(g&&g.match(b))return a}while(!f||a!=c);return this.getHighlightedIndex()},this.getHighlightedIndex())};
                +goog.ui.Menu.prototype.canHighlightItem=function(a){return(this.allowHighlightDisabled_||a.isEnabled())&&a.isVisible()&&a.isSupportedState(goog.ui.Component.State.HOVER)};goog.ui.Menu.prototype.decorateInternal=function(a){this.decorateContent(a);goog.ui.Menu.superClass_.decorateInternal.call(this,a)};
                +goog.ui.Menu.prototype.handleKeyEventInternal=function(a){var b=goog.ui.Menu.superClass_.handleKeyEventInternal.call(this,a);b||this.forEachChild(function(c){!b&&c.getMnemonic&&c.getMnemonic()==a.keyCode&&(this.isEnabled()&&this.setHighlighted(c),b=c.handleKeyEvent(a))},this);return b};goog.ui.Menu.prototype.setHighlightedIndex=function(a){goog.ui.Menu.superClass_.setHighlightedIndex.call(this,a);(a=this.getChildAt(a))&&goog.style.scrollIntoContainerView(a.getElement(),this.getElement())};
                +goog.ui.Menu.prototype.decorateContent=function(a){var b=this.getRenderer();a=this.getDomHelper().getElementsByTagNameAndClass("DIV",b.getCssClass()+"-content",a);for(var c=a.length,d=0;d<c;d++)b.decorateChildren(this,a[d])};goog.color={};
                +goog.color.names={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",
                +darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",
                +ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",
                +lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",
                +moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",
                +seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};goog.color.parse=function(a){var b={};a=String(a);var c=goog.color.prependHashIfNecessaryHelper(a);if(goog.color.isValidHexColor_(c))return b.hex=goog.color.normalizeHex(c),b.type="hex",b;c=goog.color.isValidRgbColor_(a);if(c.length)return b.hex=goog.color.rgbArrayToHex(c),b.type="rgb",b;if(goog.color.names&&(c=goog.color.names[a.toLowerCase()]))return b.hex=c,b.type="named",b;throw Error(a+" is not a valid color string");};
                +goog.color.isValidColor=function(a){var b=goog.color.prependHashIfNecessaryHelper(a);return!!(goog.color.isValidHexColor_(b)||goog.color.isValidRgbColor_(a).length||goog.color.names&&goog.color.names[a.toLowerCase()])};goog.color.parseRgb=function(a){var b=goog.color.isValidRgbColor_(a);if(!b.length)throw Error(a+" is not a valid RGB color");return b};goog.color.hexToRgbStyle=function(a){return goog.color.rgbStyle_(goog.color.hexToRgb(a))};goog.color.hexTripletRe_=/#(.)(.)(.)/;
                +goog.color.normalizeHex=function(a){if(!goog.color.isValidHexColor_(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(goog.color.hexTripletRe_,"#$1$1$2$2$3$3"));return a.toLowerCase()};goog.color.hexToRgb=function(a){a=goog.color.normalizeHex(a);var b=parseInt(a.substr(1,2),16),c=parseInt(a.substr(3,2),16);a=parseInt(a.substr(5,2),16);return[b,c,a]};
                +goog.color.rgbToHex=function(a,b,c){a=Number(a);b=Number(b);c=Number(c);if(a!=(a&255)||b!=(b&255)||c!=(c&255))throw Error('"('+a+","+b+","+c+'") is not a valid RGB color');a=goog.color.prependZeroIfNecessaryHelper(a.toString(16));b=goog.color.prependZeroIfNecessaryHelper(b.toString(16));c=goog.color.prependZeroIfNecessaryHelper(c.toString(16));return"#"+a+b+c};goog.color.rgbArrayToHex=function(a){return goog.color.rgbToHex(a[0],a[1],a[2])};
                +goog.color.rgbToHsl=function(a,b,c){a/=255;b/=255;c/=255;var d=Math.max(a,b,c),e=Math.min(a,b,c),f=0,g=0,h=.5*(d+e);d!=e&&(d==a?f=60*(b-c)/(d-e):d==b?f=60*(c-a)/(d-e)+120:d==c&&(f=60*(a-b)/(d-e)+240),g=0<h&&.5>=h?(d-e)/(2*h):(d-e)/(2-2*h));return[Math.round(f+360)%360,g,h]};goog.color.rgbArrayToHsl=function(a){return goog.color.rgbToHsl(a[0],a[1],a[2])};goog.color.hueToRgb_=function(a,b,c){0>c?c+=1:1<c&&--c;return 1>6*c?a+6*(b-a)*c:1>2*c?b:2>3*c?a+(b-a)*(2/3-c)*6:a};
                +goog.color.hslToRgb=function(a,b,c){a/=360;if(0==b)c=b=a=255*c;else{var d=.5>c?c*(1+b):c+b-b*c;var e=2*c-d;c=255*goog.color.hueToRgb_(e,d,a+1/3);b=255*goog.color.hueToRgb_(e,d,a);a=255*goog.color.hueToRgb_(e,d,a-1/3)}return[Math.round(c),Math.round(b),Math.round(a)]};goog.color.hslArrayToRgb=function(a){return goog.color.hslToRgb(a[0],a[1],a[2])};goog.color.validHexColorRe_=/^#(?:[0-9a-f]{3}){1,2}$/i;goog.color.isValidHexColor_=function(a){return goog.color.validHexColorRe_.test(a)};
                +goog.color.normalizedHexColorRe_=/^#[0-9a-f]{6}$/;goog.color.isNormalizedHexColor_=function(a){return goog.color.normalizedHexColorRe_.test(a)};goog.color.rgbColorRe_=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;goog.color.isValidRgbColor_=function(a){var b=a.match(goog.color.rgbColorRe_);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};
                +goog.color.prependZeroIfNecessaryHelper=function(a){return 1==a.length?"0"+a:a};goog.color.prependHashIfNecessaryHelper=function(a){return"#"==a.charAt(0)?a:"#"+a};goog.color.rgbStyle_=function(a){return"rgb("+a.join(",")+")"};
                +goog.color.hsvToRgb=function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=c;else{var g=Math.floor(a/60),h=a/60-g;a=c*(1-b);var k=c*(1-b*h);b=c*(1-b*(1-h));switch(g){case 1:d=k;e=c;f=a;break;case 2:d=a;e=c;f=b;break;case 3:d=a;e=k;f=c;break;case 4:d=b;e=a;f=c;break;case 5:d=c;e=a;f=k;break;case 6:case 0:d=c,e=b,f=a}}return[Math.floor(d),Math.floor(e),Math.floor(f)]};
                +goog.color.rgbToHsv=function(a,b,c){var d=Math.max(Math.max(a,b),c),e=Math.min(Math.min(a,b),c);if(e==d)e=a=0;else{var f=d-e,e=f/d;a=60*(a==d?(b-c)/f:b==d?2+(c-a)/f:4+(a-b)/f);0>a&&(a+=360);360<a&&(a-=360)}return[a,e,d]};goog.color.rgbArrayToHsv=function(a){return goog.color.rgbToHsv(a[0],a[1],a[2])};goog.color.hsvArrayToRgb=function(a){return goog.color.hsvToRgb(a[0],a[1],a[2])};goog.color.hexToHsl=function(a){a=goog.color.hexToRgb(a);return goog.color.rgbToHsl(a[0],a[1],a[2])};
                +goog.color.hslToHex=function(a,b,c){return goog.color.rgbArrayToHex(goog.color.hslToRgb(a,b,c))};goog.color.hslArrayToHex=function(a){return goog.color.rgbArrayToHex(goog.color.hslToRgb(a[0],a[1],a[2]))};goog.color.hexToHsv=function(a){return goog.color.rgbArrayToHsv(goog.color.hexToRgb(a))};goog.color.hsvToHex=function(a,b,c){return goog.color.rgbArrayToHex(goog.color.hsvToRgb(a,b,c))};goog.color.hsvArrayToHex=function(a){return goog.color.hsvToHex(a[0],a[1],a[2])};
                +goog.color.hslDistance=function(a,b){var c=.5>=a[2]?a[1]*a[2]:a[1]*(1-a[2]);var d=.5>=b[2]?b[1]*b[2]:b[1]*(1-b[2]);return(a[2]-b[2])*(a[2]-b[2])+c*c+d*d-2*c*d*Math.cos(2*(a[0]/360-b[0]/360)*Math.PI)};goog.color.blend=function(a,b,c){c=goog.math.clamp(c,0,1);return[Math.round(c*a[0]+(1-c)*b[0]),Math.round(c*a[1]+(1-c)*b[1]),Math.round(c*a[2]+(1-c)*b[2])]};goog.color.darken=function(a,b){return goog.color.blend([0,0,0],a,b)};goog.color.lighten=function(a,b){return goog.color.blend([255,255,255],a,b)};
                +goog.color.highContrast=function(a,b){for(var c=[],d=0;d<b.length;d++)c.push({color:b[d],diff:goog.color.yiqBrightnessDiff_(b[d],a)+goog.color.colorDiff_(b[d],a)});c.sort(function(a,b){return b.diff-a.diff});return c[0].color};goog.color.yiqBrightness_=function(a){return Math.round((299*a[0]+587*a[1]+114*a[2])/1E3)};goog.color.yiqBrightnessDiff_=function(a,b){return Math.abs(goog.color.yiqBrightness_(a)-goog.color.yiqBrightness_(b))};
                +goog.color.colorDiff_=function(a,b){return Math.abs(a[0]-b[0])+Math.abs(a[1]-b[1])+Math.abs(a[2]-b[2])};goog.iter={};goog.iter.StopIteration="StopIteration"in goog.global?goog.global.StopIteration:{message:"StopIteration",stack:""};goog.iter.Iterator=function(){};goog.iter.Iterator.prototype.next=function(){throw goog.iter.StopIteration;};goog.iter.Iterator.prototype.__iterator__=function(a){return this};
                +goog.iter.toIterator=function(a){if(a instanceof goog.iter.Iterator)return a;if("function"==typeof a.__iterator__)return a.__iterator__(!1);if(goog.isArrayLike(a)){var b=0,c=new goog.iter.Iterator;c.next=function(){for(;;){if(b>=a.length)throw goog.iter.StopIteration;if(b in a)return a[b++];b++}};return c}throw Error("Not implemented");};
                +goog.iter.forEach=function(a,b,c){if(goog.isArrayLike(a))try{goog.array.forEach(a,b,c)}catch(d){if(d!==goog.iter.StopIteration)throw d;}else{a=goog.iter.toIterator(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(d){if(d!==goog.iter.StopIteration)throw d;}}};goog.iter.filter=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){for(;;){var a=d.next();if(b.call(c,a,void 0,d))return a}};return a};
                +goog.iter.filterFalse=function(a,b,c){return goog.iter.filter(a,goog.functions.not(b),c)};goog.iter.range=function(a,b,c){var d=0,e=a,f=c||1;1<arguments.length&&(d=a,e=b);if(0==f)throw Error("Range step argument must not be zero");var g=new goog.iter.Iterator;g.next=function(){if(0<f&&d>=e||0>f&&d<=e)throw goog.iter.StopIteration;var a=d;d+=f;return a};return g};goog.iter.join=function(a,b){return goog.iter.toArray(a).join(b)};
                +goog.iter.map=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=d.next();return b.call(c,a,void 0,d)};return a};goog.iter.reduce=function(a,b,c,d){var e=c;goog.iter.forEach(a,function(a){e=b.call(d,e,a)});return e};goog.iter.some=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(b.call(c,a.next(),void 0,a))return!0}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!1};
                +goog.iter.every=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(!b.call(c,a.next(),void 0,a))return!1}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!0};goog.iter.chain=function(a){return goog.iter.chainFromIterable(arguments)};
                +goog.iter.chainFromIterable=function(a){var b=goog.iter.toIterator(a);a=new goog.iter.Iterator;var c=null;a.next=function(){for(;;){if(null==c){var a=b.next();c=goog.iter.toIterator(a)}try{return c.next()}catch(e){if(e!==goog.iter.StopIteration)throw e;c=null}}};return a};goog.iter.dropWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;var e=!0;a.next=function(){for(;;){var a=d.next();if(!e||!b.call(c,a,void 0,d))return e=!1,a}};return a};
                +goog.iter.takeWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=d.next();if(b.call(c,a,void 0,d))return a;throw goog.iter.StopIteration;};return a};goog.iter.toArray=function(a){if(goog.isArrayLike(a))return goog.array.toArray(a);a=goog.iter.toIterator(a);var b=[];goog.iter.forEach(a,function(a){b.push(a)});return b};
                +goog.iter.equals=function(a,b,c){a=goog.iter.zipLongest({},a,b);var d=c||goog.array.defaultCompareEquality;return goog.iter.every(a,function(a){return d(a[0],a[1])})};goog.iter.nextOrValue=function(a,b){try{return goog.iter.toIterator(a).next()}catch(c){if(c!=goog.iter.StopIteration)throw c;return b}};
                +goog.iter.product=function(a){if(goog.array.some(arguments,function(a){return!a.length})||!arguments.length)return new goog.iter.Iterator;var b=new goog.iter.Iterator,c=arguments,d=goog.array.repeat(0,c.length);b.next=function(){if(d){for(var a=goog.array.map(d,function(a,b){return c[b][a]}),b=d.length-1;0<=b;b--){goog.asserts.assert(d);if(d[b]<c[b].length-1){d[b]++;break}if(0==b){d=null;break}d[b]=0}return a}throw goog.iter.StopIteration;};return b};
                +goog.iter.cycle=function(a){var b=goog.iter.toIterator(a),c=[],d=0;a=new goog.iter.Iterator;var e=!1;a.next=function(){var a=null;if(!e)try{return a=b.next(),c.push(a),a}catch(g){if(g!=goog.iter.StopIteration||goog.array.isEmpty(c))throw g;e=!0}a=c[d];d=(d+1)%c.length;return a};return a};goog.iter.count=function(a,b){var c=a||0,d=goog.isDef(b)?b:1;a=new goog.iter.Iterator;a.next=function(){var a=c;c+=d;return a};return a};
                +goog.iter.repeat=function(a){var b=new goog.iter.Iterator;b.next=goog.functions.constant(a);return b};goog.iter.accumulate=function(a){var b=goog.iter.toIterator(a),c=0;a=new goog.iter.Iterator;a.next=function(){return c+=b.next()};return a};goog.iter.zip=function(a){var b=arguments,c=new goog.iter.Iterator;if(0<b.length){var d=goog.array.map(b,goog.iter.toIterator);c.next=function(){return goog.array.map(d,function(a){return a.next()})}}return c};
                +goog.iter.zipLongest=function(a,b){var c=goog.array.slice(arguments,1),d=new goog.iter.Iterator;if(0<c.length){var e=goog.array.map(c,goog.iter.toIterator);d.next=function(){var b=!1,c=goog.array.map(e,function(c){try{var d=c.next();b=!0}catch(l){if(l!==goog.iter.StopIteration)throw l;d=a}return d});if(!b)throw goog.iter.StopIteration;return c}}return d};goog.iter.compress=function(a,b){var c=goog.iter.toIterator(b);return goog.iter.filter(a,function(){return!!c.next()})};
                +goog.iter.GroupByIterator_=function(a,b){this.iterator=goog.iter.toIterator(a);this.keyFunc=b||goog.functions.identity};goog.inherits(goog.iter.GroupByIterator_,goog.iter.Iterator);goog.iter.GroupByIterator_.prototype.next=function(){for(;this.currentKey==this.targetKey;)this.currentValue=this.iterator.next(),this.currentKey=this.keyFunc(this.currentValue);this.targetKey=this.currentKey;return[this.currentKey,this.groupItems_(this.targetKey)]};
                +goog.iter.GroupByIterator_.prototype.groupItems_=function(a){for(var b=[];this.currentKey==a;){b.push(this.currentValue);try{this.currentValue=this.iterator.next()}catch(c){if(c!==goog.iter.StopIteration)throw c;break}this.currentKey=this.keyFunc(this.currentValue)}return b};goog.iter.groupBy=function(a,b){return new goog.iter.GroupByIterator_(a,b)};
                +goog.iter.starMap=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=goog.iter.toArray(d.next());return b.apply(c,goog.array.concat(a,void 0,d))};return a};
                +goog.iter.tee=function(a,b){var c=goog.iter.toIterator(a);a=goog.isNumber(b)?b:2;var d=goog.array.map(goog.array.range(a),function(){return[]}),e=function(){var a=c.next();goog.array.forEach(d,function(b){b.push(a)})};return goog.array.map(d,function(a){var b=new goog.iter.Iterator;b.next=function(){goog.array.isEmpty(a)&&e();goog.asserts.assert(!goog.array.isEmpty(a));return a.shift()};return b})};goog.iter.enumerate=function(a,b){return goog.iter.zip(goog.iter.count(b),a)};
                +goog.iter.limit=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);var c=goog.iter.toIterator(a);a=new goog.iter.Iterator;var d=b;a.next=function(){if(0<d--)return c.next();throw goog.iter.StopIteration;};return a};goog.iter.consume=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);for(a=goog.iter.toIterator(a);0<b--;)goog.iter.nextOrValue(a,null);return a};
                +goog.iter.slice=function(a,b,c){goog.asserts.assert(goog.math.isInt(b)&&0<=b);a=goog.iter.consume(a,b);goog.isNumber(c)&&(goog.asserts.assert(goog.math.isInt(c)&&c>=b),a=goog.iter.limit(a,c-b));return a};goog.iter.hasDuplicates_=function(a){var b=[];goog.array.removeDuplicates(a,b);return a.length!=b.length};goog.iter.permutations=function(a,b){a=goog.iter.toArray(a);b=goog.isNumber(b)?b:a.length;b=goog.array.repeat(a,b);b=goog.iter.product.apply(void 0,b);return goog.iter.filter(b,function(a){return!goog.iter.hasDuplicates_(a)})};
                +goog.iter.combinations=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a);a=goog.iter.range(d.length);b=goog.iter.permutations(a,b);var e=goog.iter.filter(b,function(a){return goog.array.isSorted(a)});b=new goog.iter.Iterator;b.next=function(){return goog.array.map(e.next(),c)};return b};
                +goog.iter.combinationsWithReplacement=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a);a=goog.array.range(d.length);b=goog.array.repeat(a,b);b=goog.iter.product.apply(void 0,b);var e=goog.iter.filter(b,function(a){return goog.array.isSorted(a)});b=new goog.iter.Iterator;b.next=function(){return goog.array.map(e.next(),c)};return b};goog.dom.TagWalkType={START_TAG:1,OTHER:0,END_TAG:-1};goog.dom.TagIterator=function(a,b,c,d,e){this.reversed=!!b;this.node=null;this.tagType=goog.dom.TagWalkType.OTHER;this.started_=!1;this.constrained=!c;a&&this.setPosition(a,d);this.depth=void 0!=e?e:this.tagType||0;this.reversed&&(this.depth*=-1)};goog.inherits(goog.dom.TagIterator,goog.iter.Iterator);
                +goog.dom.TagIterator.prototype.setPosition=function(a,b,c){if(this.node=a)goog.isNumber(b)?this.tagType=b:this.tagType=this.node.nodeType!=goog.dom.NodeType.ELEMENT?goog.dom.TagWalkType.OTHER:this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;goog.isNumber(c)&&(this.depth=c)};goog.dom.TagIterator.prototype.copyFrom=function(a){this.node=a.node;this.tagType=a.tagType;this.depth=a.depth;this.reversed=a.reversed;this.constrained=a.constrained};
                +goog.dom.TagIterator.prototype.clone=function(){return new goog.dom.TagIterator(this.node,this.reversed,!this.constrained,this.tagType,this.depth)};goog.dom.TagIterator.prototype.skipTag=function(){var a=this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;this.tagType==a&&(this.tagType=-1*a,this.depth+=this.tagType*(this.reversed?-1:1))};
                +goog.dom.TagIterator.prototype.restartTag=function(){var a=this.reversed?goog.dom.TagWalkType.START_TAG:goog.dom.TagWalkType.END_TAG;this.tagType==a&&(this.tagType=-1*a,this.depth+=this.tagType*(this.reversed?-1:1))};
                +goog.dom.TagIterator.prototype.next=function(){if(this.started_){if(!this.node||this.constrained&&0==this.depth)throw goog.iter.StopIteration;var a=this.node;var b=this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;if(this.tagType==b){var c=this.reversed?a.lastChild:a.firstChild;c?this.setPosition(c):this.setPosition(a,-1*b)}else(c=this.reversed?a.previousSibling:a.nextSibling)?this.setPosition(c):this.setPosition(a.parentNode,-1*b);this.depth+=this.tagType*(this.reversed?-1:
                +1)}else this.started_=!0;a=this.node;if(!this.node)throw goog.iter.StopIteration;return a};goog.dom.TagIterator.prototype.isStarted=function(){return this.started_};goog.dom.TagIterator.prototype.isStartTag=function(){return this.tagType==goog.dom.TagWalkType.START_TAG};goog.dom.TagIterator.prototype.isEndTag=function(){return this.tagType==goog.dom.TagWalkType.END_TAG};goog.dom.TagIterator.prototype.isNonElement=function(){return this.tagType==goog.dom.TagWalkType.OTHER};
                +goog.dom.TagIterator.prototype.equals=function(a){return a.node==this.node&&(!this.node||a.tagType==this.tagType)};goog.dom.TagIterator.prototype.splice=function(a){var b=this.node;this.restartTag();this.reversed=!this.reversed;goog.dom.TagIterator.prototype.next.call(this);this.reversed=!this.reversed;for(var c=goog.isArrayLike(arguments[0])?arguments[0]:arguments,d=c.length-1;0<=d;d--)goog.dom.insertSiblingAfter(c[d],b);goog.dom.removeNode(b)};goog.dom.NodeIterator=function(a,b,c,d){goog.dom.TagIterator.call(this,a,b,c,null,d)};goog.inherits(goog.dom.NodeIterator,goog.dom.TagIterator);goog.dom.NodeIterator.prototype.next=function(){do goog.dom.NodeIterator.superClass_.next.call(this);while(this.isEndTag());return this.node};goog.ui.PaletteRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.PaletteRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.PaletteRenderer);goog.ui.PaletteRenderer.cellId_=0;goog.ui.PaletteRenderer.CSS_CLASS="goog-palette";goog.ui.PaletteRenderer.prototype.createDom=function(a){var b=this.getClassNames(a);a=a.getDomHelper().createDom("DIV",b,this.createGrid(a.getContent(),a.getSize(),a.getDomHelper()));goog.a11y.aria.setRole(a,goog.a11y.aria.Role.GRID);return a};
                +goog.ui.PaletteRenderer.prototype.createGrid=function(a,b,c){for(var d=[],e=0,f=0;e<b.height;e++){for(var g=[],h=0;h<b.width;h++){var k=a&&a[f++];g.push(this.createCell(k,c))}d.push(this.createRow(g,c))}return this.createTable(d,c)};goog.ui.PaletteRenderer.prototype.createTable=function(a,b){a=b.createDom("TABLE",this.getCssClass()+"-table",b.createDom("TBODY",this.getCssClass()+"-body",a));a.cellSpacing="0";a.cellPadding="0";return a};
                +goog.ui.PaletteRenderer.prototype.createRow=function(a,b){a=b.createDom("TR",this.getCssClass()+"-row",a);goog.a11y.aria.setRole(a,goog.a11y.aria.Role.ROW);return a};
                +goog.ui.PaletteRenderer.prototype.createCell=function(a,b){a=b.createDom("TD",{"class":this.getCssClass()+"-cell",id:this.getCssClass()+"-cell-"+goog.ui.PaletteRenderer.cellId_++},a);goog.a11y.aria.setRole(a,goog.a11y.aria.Role.GRIDCELL);goog.a11y.aria.setState(a,goog.a11y.aria.State.SELECTED,!1);goog.dom.getTextContent(a)||goog.a11y.aria.getLabel(a)||(b=this.findAriaLabelForCell_(a))&&goog.a11y.aria.setLabel(a,b);return a};
                +goog.ui.PaletteRenderer.prototype.findAriaLabelForCell_=function(a){a=new goog.dom.NodeIterator(a);for(var b="",c;!b&&(c=goog.iter.nextOrValue(a,null));)c.nodeType==goog.dom.NodeType.ELEMENT&&(b=goog.a11y.aria.getLabel(c)||c.title);return b};goog.ui.PaletteRenderer.prototype.canDecorate=function(a){return!1};goog.ui.PaletteRenderer.prototype.decorate=function(a,b){return null};
                +goog.ui.PaletteRenderer.prototype.setContent=function(a,b){if(a){var c=goog.dom.getElementsByTagNameAndClass("TBODY",this.getCssClass()+"-body",a)[0];if(c){var d=0;goog.array.forEach(c.rows,function(a){goog.array.forEach(a.cells,function(a){goog.dom.removeChildren(a);if(b){var c=b[d++];c&&goog.dom.appendChild(a,c)}})});if(d<b.length){for(var e=[],f=goog.dom.getDomHelper(a),g=c.rows[0].cells.length;d<b.length;){var h=b[d++];e.push(this.createCell(h,f));e.length==g&&(h=this.createRow(e,f),goog.dom.appendChild(c,
                +h),e.length=0)}if(0<e.length){for(;e.length<g;)e.push(this.createCell("",f));h=this.createRow(e,f);goog.dom.appendChild(c,h)}}}goog.style.setUnselectable(a,!0,goog.userAgent.GECKO)}};goog.ui.PaletteRenderer.prototype.getContainingItem=function(a,b){for(a=a.getElement();b&&b.nodeType==goog.dom.NodeType.ELEMENT&&b!=a;){if("TD"==b.tagName&&goog.dom.classlist.contains(b,this.getCssClass()+"-cell"))return b.firstChild;b=b.parentNode}return null};
                +goog.ui.PaletteRenderer.prototype.highlightCell=function(a,b,c){b&&(b=this.getCellForItem(b),goog.asserts.assert(b),goog.dom.classlist.enable(b,this.getCssClass()+"-cell-hover",c),c?goog.a11y.aria.setState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT,b.id):b.id==goog.a11y.aria.getState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT)&&goog.a11y.aria.removeState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT))};
                +goog.ui.PaletteRenderer.prototype.getCellForItem=function(a){return a?a.parentNode:null};goog.ui.PaletteRenderer.prototype.selectCell=function(a,b,c){b&&(a=b.parentNode,goog.dom.classlist.enable(a,this.getCssClass()+"-cell-selected",c),goog.a11y.aria.setState(a,goog.a11y.aria.State.SELECTED,c))};goog.ui.PaletteRenderer.prototype.getCssClass=function(){return goog.ui.PaletteRenderer.CSS_CLASS};goog.ui.SelectionModel=function(a){goog.events.EventTarget.call(this);this.items_=[];this.addItems(a)};goog.inherits(goog.ui.SelectionModel,goog.events.EventTarget);goog.tagUnsealableClass(goog.ui.SelectionModel);goog.ui.SelectionModel.prototype.selectedItem_=null;goog.ui.SelectionModel.prototype.selectionHandler_=null;goog.ui.SelectionModel.prototype.getSelectionHandler=function(){return this.selectionHandler_};
                +goog.ui.SelectionModel.prototype.setSelectionHandler=function(a){this.selectionHandler_=a};goog.ui.SelectionModel.prototype.getItemCount=function(){return this.items_.length};goog.ui.SelectionModel.prototype.indexOfItem=function(a){return a?goog.array.indexOf(this.items_,a):-1};goog.ui.SelectionModel.prototype.getFirst=function(){return this.items_[0]};goog.ui.SelectionModel.prototype.getLast=function(){return this.items_[this.items_.length-1]};
                +goog.ui.SelectionModel.prototype.getItemAt=function(a){return this.items_[a]||null};goog.ui.SelectionModel.prototype.addItems=function(a){a&&(goog.array.forEach(a,function(a){this.selectItem_(a,!1)},this),goog.array.extend(this.items_,a))};goog.ui.SelectionModel.prototype.addItem=function(a){this.addItemAt(a,this.getItemCount())};goog.ui.SelectionModel.prototype.addItemAt=function(a,b){a&&(this.selectItem_(a,!1),goog.array.insertAt(this.items_,a,b))};
                +goog.ui.SelectionModel.prototype.removeItem=function(a){a&&goog.array.remove(this.items_,a)&&a==this.selectedItem_&&(this.selectedItem_=null,this.dispatchEvent(goog.events.EventType.SELECT))};goog.ui.SelectionModel.prototype.removeItemAt=function(a){this.removeItem(this.getItemAt(a))};goog.ui.SelectionModel.prototype.getSelectedItem=function(){return this.selectedItem_};goog.ui.SelectionModel.prototype.getItems=function(){return goog.array.clone(this.items_)};
                +goog.ui.SelectionModel.prototype.setSelectedItem=function(a){a!=this.selectedItem_&&(this.selectItem_(this.selectedItem_,!1),this.selectedItem_=a,this.selectItem_(a,!0));this.dispatchEvent(goog.events.EventType.SELECT)};goog.ui.SelectionModel.prototype.getSelectedIndex=function(){return this.indexOfItem(this.selectedItem_)};goog.ui.SelectionModel.prototype.setSelectedIndex=function(a){this.setSelectedItem(this.getItemAt(a))};
                +goog.ui.SelectionModel.prototype.clear=function(){goog.array.clear(this.items_);this.selectedItem_=null};goog.ui.SelectionModel.prototype.disposeInternal=function(){goog.ui.SelectionModel.superClass_.disposeInternal.call(this);delete this.items_;this.selectedItem_=null};goog.ui.SelectionModel.prototype.selectItem_=function(a,b){a&&("function"==typeof this.selectionHandler_?this.selectionHandler_(a,b):"function"==typeof a.setSelected&&a.setSelected(b))};goog.ui.Palette=function(a,b,c){goog.ui.Control.call(this,a,b||goog.ui.PaletteRenderer.getInstance(),c);this.setAutoStates(goog.ui.Component.State.CHECKED|goog.ui.Component.State.SELECTED|goog.ui.Component.State.OPENED,!1);this.currentCellControl_=new goog.ui.Palette.CurrentCell_;this.currentCellControl_.setParentEventTarget(this);this.lastHighlightedIndex_=-1};goog.inherits(goog.ui.Palette,goog.ui.Control);goog.tagUnsealableClass(goog.ui.Palette);goog.ui.Palette.EventType={AFTER_HIGHLIGHT:goog.events.getUniqueId("afterhighlight")};
                +goog.ui.Palette.prototype.size_=null;goog.ui.Palette.prototype.highlightedIndex_=-1;goog.ui.Palette.prototype.selectionModel_=null;goog.ui.Palette.prototype.disposeInternal=function(){goog.ui.Palette.superClass_.disposeInternal.call(this);this.selectionModel_&&(this.selectionModel_.dispose(),this.selectionModel_=null);this.size_=null;this.currentCellControl_.dispose()};
                +goog.ui.Palette.prototype.setContentInternal=function(a){goog.ui.Palette.superClass_.setContentInternal.call(this,a);this.adjustSize_();this.selectionModel_?(this.selectionModel_.clear(),this.selectionModel_.addItems(a)):(this.selectionModel_=new goog.ui.SelectionModel(a),this.selectionModel_.setSelectionHandler(goog.bind(this.selectItem_,this)),this.getHandler().listen(this.selectionModel_,goog.events.EventType.SELECT,this.handleSelectionChange));this.highlightedIndex_=-1};
                +goog.ui.Palette.prototype.getCaption=function(){return""};goog.ui.Palette.prototype.setCaption=function(a){};goog.ui.Palette.prototype.handleMouseOver=function(a){goog.ui.Palette.superClass_.handleMouseOver.call(this,a);var b=this.getRenderer().getContainingItem(this,a.target);b&&a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)||b!=this.getHighlightedItem()&&this.setHighlightedItem(b)};
                +goog.ui.Palette.prototype.handleMouseDown=function(a){goog.ui.Palette.superClass_.handleMouseDown.call(this,a);this.isActive()&&(a=this.getRenderer().getContainingItem(this,a.target),a!=this.getHighlightedItem()&&this.setHighlightedItem(a))};goog.ui.Palette.prototype.performActionInternal=function(a){var b=this.getHighlightedItem();return b?(a&&this.shouldSelectHighlightedItem_(a)&&this.setSelectedItem(b),goog.ui.Palette.superClass_.performActionInternal.call(this,a)):!1};
                +goog.ui.Palette.prototype.shouldSelectHighlightedItem_=function(a){return this.getSelectedItem()?"mouseup"!=a.type?!0:!!this.getRenderer().getContainingItem(this,a.target):!0};
                +goog.ui.Palette.prototype.handleKeyEvent=function(a){var b=this.getContent(),b=b?b.length:0,c=this.size_.width;if(0==b||!this.isEnabled())return!1;if(a.keyCode==goog.events.KeyCodes.ENTER||a.keyCode==goog.events.KeyCodes.SPACE)return this.performActionInternal(a);if(a.keyCode==goog.events.KeyCodes.HOME)return this.setHighlightedIndex(0),!0;if(a.keyCode==goog.events.KeyCodes.END)return this.setHighlightedIndex(b-1),!0;var d=0>this.highlightedIndex_?this.getSelectedIndex():this.highlightedIndex_;switch(a.keyCode){case goog.events.KeyCodes.LEFT:if(-1==
                +d||0==d)d=b;this.setHighlightedIndex(d-1);a.preventDefault();return!0;case goog.events.KeyCodes.RIGHT:return d==b-1&&(d=-1),this.setHighlightedIndex(d+1),a.preventDefault(),!0;case goog.events.KeyCodes.UP:-1==d&&(d=b+c-1);if(d>=c)return this.setHighlightedIndex(d-c),a.preventDefault(),!0;break;case goog.events.KeyCodes.DOWN:if(-1==d&&(d=-c),d<b-c)return this.setHighlightedIndex(d+c),a.preventDefault(),!0}return!1};goog.ui.Palette.prototype.handleSelectionChange=function(a){};
                +goog.ui.Palette.prototype.getSize=function(){return this.size_};goog.ui.Palette.prototype.setSize=function(a,b){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.size_=goog.isNumber(a)?new goog.math.Size(a,b):a;this.adjustSize_()};goog.ui.Palette.prototype.getHighlightedIndex=function(){return this.highlightedIndex_};goog.ui.Palette.prototype.getHighlightedItem=function(){var a=this.getContent();return a&&a[this.highlightedIndex_]};
                +goog.ui.Palette.prototype.getHighlightedCellElement_=function(){return this.getRenderer().getCellForItem(this.getHighlightedItem())};goog.ui.Palette.prototype.setHighlightedIndex=function(a){a!=this.highlightedIndex_&&(this.highlightIndex_(this.highlightedIndex_,!1),this.lastHighlightedIndex_=this.highlightedIndex_,this.highlightedIndex_=a,this.highlightIndex_(a,!0),this.dispatchEvent(goog.ui.Palette.EventType.AFTER_HIGHLIGHT))};
                +goog.ui.Palette.prototype.setHighlightedItem=function(a){var b=this.getContent();this.setHighlightedIndex(b&&a?goog.array.indexOf(b,a):-1)};goog.ui.Palette.prototype.getSelectedIndex=function(){return this.selectionModel_?this.selectionModel_.getSelectedIndex():-1};goog.ui.Palette.prototype.getSelectedItem=function(){return this.selectionModel_?this.selectionModel_.getSelectedItem():null};goog.ui.Palette.prototype.setSelectedIndex=function(a){this.selectionModel_&&this.selectionModel_.setSelectedIndex(a)};
                +goog.ui.Palette.prototype.setSelectedItem=function(a){this.selectionModel_&&this.selectionModel_.setSelectedItem(a)};goog.ui.Palette.prototype.highlightIndex_=function(a,b){if(this.getElement()){var c=this.getContent();if(c&&0<=a&&a<c.length){var d=this.getHighlightedCellElement_();this.currentCellControl_.getElement()!=d&&this.currentCellControl_.setElementInternal(d);this.currentCellControl_.tryHighlight(b)&&this.getRenderer().highlightCell(this,c[a],b)}}};
                +goog.ui.Palette.prototype.setHighlighted=function(a){a&&-1==this.highlightedIndex_?this.setHighlightedIndex(-1<this.lastHighlightedIndex_?this.lastHighlightedIndex_:0):a||this.setHighlightedIndex(-1);goog.ui.Palette.superClass_.setHighlighted.call(this,a)};goog.ui.Palette.prototype.selectItem_=function(a,b){this.getElement()&&this.getRenderer().selectCell(this,a,b)};
                +goog.ui.Palette.prototype.adjustSize_=function(){var a=this.getContent();if(a)if(this.size_&&this.size_.width){if(a=Math.ceil(a.length/this.size_.width),!goog.isNumber(this.size_.height)||this.size_.height<a)this.size_.height=a}else a=Math.ceil(Math.sqrt(a.length)),this.size_=new goog.math.Size(a,a);else this.size_=new goog.math.Size(0,0)};goog.ui.Palette.CurrentCell_=function(){goog.ui.Control.call(this,null);this.setDispatchTransitionEvents(goog.ui.Component.State.HOVER,!0)};
                +goog.inherits(goog.ui.Palette.CurrentCell_,goog.ui.Control);goog.ui.Palette.CurrentCell_.prototype.tryHighlight=function(a){this.setHighlighted(a);return this.isHighlighted()==a};goog.ui.ColorPalette=function(a,b,c){this.colors_=a||[];goog.ui.Palette.call(this,null,b||goog.ui.PaletteRenderer.getInstance(),c);this.setColors(this.colors_)};goog.inherits(goog.ui.ColorPalette,goog.ui.Palette);goog.tagUnsealableClass(goog.ui.ColorPalette);goog.ui.ColorPalette.prototype.normalizedColors_=null;goog.ui.ColorPalette.prototype.labels_=null;goog.ui.ColorPalette.prototype.getColors=function(){return this.colors_};
                +goog.ui.ColorPalette.prototype.setColors=function(a,b){this.colors_=a;this.labels_=b||null;this.normalizedColors_=null;this.setContent(this.createColorNodes())};goog.ui.ColorPalette.prototype.getSelectedColor=function(){var a=this.getSelectedItem();return a?(a=goog.style.getStyle(a,"background-color"),goog.ui.ColorPalette.parseColor_(a)):null};
                +goog.ui.ColorPalette.prototype.setSelectedColor=function(a){a=goog.ui.ColorPalette.parseColor_(a);this.normalizedColors_||(this.normalizedColors_=goog.array.map(this.colors_,function(a){return goog.ui.ColorPalette.parseColor_(a)}));this.setSelectedIndex(a?goog.array.indexOf(this.normalizedColors_,a):-1)};
                +goog.ui.ColorPalette.prototype.createColorNodes=function(){return goog.array.map(this.colors_,function(a,b){var c=this.getDomHelper().createDom("DIV",{"class":this.getRenderer().getCssClass()+"-colorswatch",style:"background-color:"+a});c.title=this.labels_&&this.labels_[b]?this.labels_[b]:"#"==a.charAt(0)?"RGB ("+goog.color.hexToRgb(a).join(", ")+")":a;return c},this)};goog.ui.ColorPalette.parseColor_=function(a){if(a)try{return goog.color.parse(a).hex}catch(b){}return null};goog.ui.ColorPicker=function(a,b){goog.ui.Component.call(this,a);this.colorPalette_=b||null;this.getHandler().listen(this,goog.ui.Component.EventType.ACTION,this.onColorPaletteAction_)};goog.inherits(goog.ui.ColorPicker,goog.ui.Component);goog.ui.ColorPicker.DEFAULT_NUM_COLS=5;goog.ui.ColorPicker.EventType={CHANGE:"change"};goog.ui.ColorPicker.prototype.focusable_=!0;goog.ui.ColorPicker.prototype.getColors=function(){return this.colorPalette_?this.colorPalette_.getColors():null};
                +goog.ui.ColorPicker.prototype.setColors=function(a){this.colorPalette_?this.colorPalette_.setColors(a):this.createColorPalette_(a)};goog.ui.ColorPicker.prototype.addColors=function(a){this.setColors(a)};goog.ui.ColorPicker.prototype.setSize=function(a){this.colorPalette_||this.createColorPalette_([]);this.colorPalette_.setSize(a)};goog.ui.ColorPicker.prototype.getSize=function(){return this.colorPalette_?this.colorPalette_.getSize():null};goog.ui.ColorPicker.prototype.setColumnCount=function(a){this.setSize(a)};
                +goog.ui.ColorPicker.prototype.getSelectedIndex=function(){return this.colorPalette_?this.colorPalette_.getSelectedIndex():-1};goog.ui.ColorPicker.prototype.setSelectedIndex=function(a){this.colorPalette_&&this.colorPalette_.setSelectedIndex(a)};goog.ui.ColorPicker.prototype.getSelectedColor=function(){return this.colorPalette_?this.colorPalette_.getSelectedColor():null};goog.ui.ColorPicker.prototype.setSelectedColor=function(a){this.colorPalette_&&this.colorPalette_.setSelectedColor(a)};
                +goog.ui.ColorPicker.prototype.isFocusable=function(){return this.focusable_};goog.ui.ColorPicker.prototype.setFocusable=function(a){this.focusable_=a;this.colorPalette_&&this.colorPalette_.setSupportedState(goog.ui.Component.State.FOCUSED,a)};goog.ui.ColorPicker.prototype.canDecorate=function(a){return!1};
                +goog.ui.ColorPicker.prototype.enterDocument=function(){goog.ui.ColorPicker.superClass_.enterDocument.call(this);this.colorPalette_&&this.colorPalette_.render(this.getElement());this.getElement().unselectable="on"};goog.ui.ColorPicker.prototype.disposeInternal=function(){goog.ui.ColorPicker.superClass_.disposeInternal.call(this);this.colorPalette_&&(this.colorPalette_.dispose(),this.colorPalette_=null)};goog.ui.ColorPicker.prototype.focus=function(){this.colorPalette_&&this.colorPalette_.getElement().focus()};
                +goog.ui.ColorPicker.prototype.onColorPaletteAction_=function(a){a.stopPropagation();this.dispatchEvent(goog.ui.ColorPicker.EventType.CHANGE)};goog.ui.ColorPicker.prototype.createColorPalette_=function(a){a=new goog.ui.ColorPalette(a,null,this.getDomHelper());a.setSize(goog.ui.ColorPicker.DEFAULT_NUM_COLS);a.setSupportedState(goog.ui.Component.State.FOCUSED,this.focusable_);this.addChild(a);this.colorPalette_=a;this.isInDocument()&&this.colorPalette_.render(this.getElement())};
                +goog.ui.ColorPicker.createSimpleColorGrid=function(a){a=new goog.ui.ColorPicker(a);a.setSize(7);a.setColors(goog.ui.ColorPicker.SIMPLE_GRID_COLORS);return a};goog.ui.ColorPicker.SIMPLE_GRID_COLORS="#ffffff #cccccc #c0c0c0 #999999 #666666 #333333 #000000 #ffcccc #ff6666 #ff0000 #cc0000 #990000 #660000 #330000 #ffcc99 #ff9966 #ff9900 #ff6600 #cc6600 #993300 #663300 #ffff99 #ffff66 #ffcc66 #ffcc33 #cc9933 #996633 #663333 #ffffcc #ffff33 #ffff00 #ffcc00 #999900 #666600 #333300 #99ff99 #66ff99 #33ff33 #33cc00 #009900 #006600 #003300 #99ffff #33ffff #66cccc #00cccc #339999 #336666 #003333 #ccffff #66ffff #33ccff #3366ff #3333ff #000099 #000066 #ccccff #9999ff #6666cc #6633ff #6600cc #333399 #330099 #ffccff #ff99ff #cc66cc #cc33cc #993399 #663366 #330033".split(" ");goog.events.FocusHandler=function(a){goog.events.EventTarget.call(this);this.element_=a;a=goog.userAgent.IE?"focusout":"blur";this.listenKeyIn_=goog.events.listen(this.element_,goog.userAgent.IE?"focusin":"focus",this,!goog.userAgent.IE);this.listenKeyOut_=goog.events.listen(this.element_,a,this,!goog.userAgent.IE)};goog.inherits(goog.events.FocusHandler,goog.events.EventTarget);goog.events.FocusHandler.EventType={FOCUSIN:"focusin",FOCUSOUT:"focusout"};
                +goog.events.FocusHandler.prototype.handleEvent=function(a){var b=a.getBrowserEvent(),b=new goog.events.BrowserEvent(b);b.type="focusin"==a.type||"focus"==a.type?goog.events.FocusHandler.EventType.FOCUSIN:goog.events.FocusHandler.EventType.FOCUSOUT;this.dispatchEvent(b)};goog.events.FocusHandler.prototype.disposeInternal=function(){goog.events.FocusHandler.superClass_.disposeInternal.call(this);goog.events.unlistenByKey(this.listenKeyIn_);goog.events.unlistenByKey(this.listenKeyOut_);delete this.element_};goog.debug.LOGGING_ENABLED=goog.DEBUG;goog.debug.FORCE_SLOPPY_STACKS=!1;goog.debug.catchErrors=function(a,b,c){c=c||goog.global;var d=c.onerror,e=!!b;goog.userAgent.WEBKIT&&!goog.userAgent.isVersionOrHigher("535.3")&&(e=!e);c.onerror=function(b,c,h,k,l){d&&d(b,c,h,k,l);a({message:b,fileName:c,line:h,col:k,error:l});return e}};
                +goog.debug.expose=function(a,b){if("undefined"==typeof a)return"undefined";if(null==a)return"NULL";var c=[],d;for(d in a)if(b||!goog.isFunction(a[d])){var e=d+" = ";try{e+=a[d]}catch(f){e+="*** "+f+" ***"}c.push(e)}return c.join("\n")};
                +goog.debug.deepExpose=function(a,b){var c=[],d=[],e={},f=function(a,h){var g=h+"  ";try{if(goog.isDef(a))if(goog.isNull(a))c.push("NULL");else if(goog.isString(a))c.push('"'+a.replace(/\n/g,"\n"+h)+'"');else if(goog.isFunction(a))c.push(String(a).replace(/\n/g,"\n"+h));else if(goog.isObject(a)){goog.hasUid(a)||d.push(a);var l=goog.getUid(a);if(e[l])c.push("*** reference loop detected (id="+l+") ***");else{e[l]=!0;c.push("{");for(var m in a)if(b||!goog.isFunction(a[m]))c.push("\n"),c.push(g),c.push(m+
                +" = "),f(a[m],g);c.push("\n"+h+"}");delete e[l]}}else c.push(a);else c.push("undefined")}catch(n){c.push("*** "+n+" ***")}};f(a,"");for(a=0;a<d.length;a++)goog.removeUid(d[a]);return c.join("")};goog.debug.exposeArray=function(a){for(var b=[],c=0;c<a.length;c++)goog.isArray(a[c])?b.push(goog.debug.exposeArray(a[c])):b.push(a[c]);return"[ "+b.join(", ")+" ]"};
                +goog.debug.normalizeErrorObject=function(a){var b=goog.getObjectByName("window.location.href");if(goog.isString(a))return{message:a,name:"Unknown error",lineNumber:"Not available",fileName:b,stack:"Not available"};var c=!1;try{var d=a.lineNumber||a.line||"Not available"}catch(f){d="Not available",c=!0}try{var e=a.fileName||a.filename||a.sourceURL||goog.global.$googDebugFname||b}catch(f){e="Not available",c=!0}return!c&&a.lineNumber&&a.fileName&&a.stack&&a.message&&a.name?a:{message:a.message||"Not available",
                +name:a.name||"UnknownError",lineNumber:d,fileName:e,stack:a.stack||"Not available"}};goog.debug.enhanceError=function(a,b){a instanceof Error||(a=Error(a),Error.captureStackTrace&&Error.captureStackTrace(a,goog.debug.enhanceError));a.stack||(a.stack=goog.debug.getStacktrace(goog.debug.enhanceError));if(b){for(var c=0;a["message"+c];)++c;a["message"+c]=String(b)}return a};
                +goog.debug.getStacktraceSimple=function(a){if(!goog.debug.FORCE_SLOPPY_STACKS){var b=goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple);if(b)return b}for(var b=[],c=arguments.callee.caller,d=0;c&&(!a||d<a);){b.push(goog.debug.getFunctionName(c));b.push("()\n");try{c=c.caller}catch(e){b.push("[exception trying to get caller]\n");break}d++;if(d>=goog.debug.MAX_STACK_DEPTH){b.push("[...long stack...]");break}}a&&d>=a?b.push("[...reached max depth limit...]"):b.push("[end]");return b.join("")};
                +goog.debug.MAX_STACK_DEPTH=50;goog.debug.getNativeStackTrace_=function(a){var b=Error();if(Error.captureStackTrace)return Error.captureStackTrace(b,a),String(b.stack);try{throw b;}catch(c){b=c}return(a=b.stack)?String(a):null};goog.debug.getStacktrace=function(a){var b;goog.debug.FORCE_SLOPPY_STACKS||(b=goog.debug.getNativeStackTrace_(a||goog.debug.getStacktrace));b||(b=goog.debug.getStacktraceHelper_(a||arguments.callee.caller,[]));return b};
                +goog.debug.getStacktraceHelper_=function(a,b){var c=[];if(goog.array.contains(b,a))c.push("[...circular reference...]");else if(a&&b.length<goog.debug.MAX_STACK_DEPTH){c.push(goog.debug.getFunctionName(a)+"(");for(var d=a.arguments,e=0;d&&e<d.length;e++){0<e&&c.push(", ");var f=d[e];switch(typeof f){case "object":f=f?"object":"null";break;case "string":break;case "number":f=String(f);break;case "boolean":f=f?"true":"false";break;case "function":f=(f=goog.debug.getFunctionName(f))?f:"[fn]";break;default:f=
                +typeof f}40<f.length&&(f=f.substr(0,40)+"...");c.push(f)}b.push(a);c.push(")\n");try{c.push(goog.debug.getStacktraceHelper_(a.caller,b))}catch(g){c.push("[exception trying to get caller]\n")}}else a?c.push("[...long stack...]"):c.push("[end]");return c.join("")};goog.debug.setFunctionResolver=function(a){goog.debug.fnNameResolver_=a};
                +goog.debug.getFunctionName=function(a){if(goog.debug.fnNameCache_[a])return goog.debug.fnNameCache_[a];if(goog.debug.fnNameResolver_){var b=goog.debug.fnNameResolver_(a);if(b)return goog.debug.fnNameCache_[a]=b}a=String(a);goog.debug.fnNameCache_[a]||(b=/function ([^\(]+)/.exec(a),goog.debug.fnNameCache_[a]=b?b[1]:"[Anonymous]");return goog.debug.fnNameCache_[a]};
                +goog.debug.makeWhitespaceVisible=function(a){return a.replace(/ /g,"[_]").replace(/\f/g,"[f]").replace(/\n/g,"[n]\n").replace(/\r/g,"[r]").replace(/\t/g,"[t]")};goog.debug.runtimeType=function(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};goog.debug.fnNameCache_={};goog.debug.LogRecord=function(a,b,c,d,e){this.reset(a,b,c,d,e)};goog.debug.LogRecord.prototype.sequenceNumber_=0;goog.debug.LogRecord.prototype.exception_=null;goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS=!0;goog.debug.LogRecord.nextSequenceNumber_=0;
                +goog.debug.LogRecord.prototype.reset=function(a,b,c,d,e){goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS&&(this.sequenceNumber_="number"==typeof e?e:goog.debug.LogRecord.nextSequenceNumber_++);this.time_=d||goog.now();this.level_=a;this.msg_=b;this.loggerName_=c;delete this.exception_};goog.debug.LogRecord.prototype.getLoggerName=function(){return this.loggerName_};goog.debug.LogRecord.prototype.getException=function(){return this.exception_};
                +goog.debug.LogRecord.prototype.setException=function(a){this.exception_=a};goog.debug.LogRecord.prototype.setLoggerName=function(a){this.loggerName_=a};goog.debug.LogRecord.prototype.getLevel=function(){return this.level_};goog.debug.LogRecord.prototype.setLevel=function(a){this.level_=a};goog.debug.LogRecord.prototype.getMessage=function(){return this.msg_};goog.debug.LogRecord.prototype.setMessage=function(a){this.msg_=a};goog.debug.LogRecord.prototype.getMillis=function(){return this.time_};
                +goog.debug.LogRecord.prototype.setMillis=function(a){this.time_=a};goog.debug.LogRecord.prototype.getSequenceNumber=function(){return this.sequenceNumber_};goog.debug.LogBuffer=function(){goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(),"Cannot use goog.debug.LogBuffer without defining goog.debug.LogBuffer.CAPACITY.");this.clear()};goog.debug.LogBuffer.getInstance=function(){goog.debug.LogBuffer.instance_||(goog.debug.LogBuffer.instance_=new goog.debug.LogBuffer);return goog.debug.LogBuffer.instance_};goog.debug.LogBuffer.CAPACITY=0;
                +goog.debug.LogBuffer.prototype.addRecord=function(a,b,c){var d=(this.curIndex_+1)%goog.debug.LogBuffer.CAPACITY;this.curIndex_=d;if(this.isFull_)return d=this.buffer_[d],d.reset(a,b,c),d;this.isFull_=d==goog.debug.LogBuffer.CAPACITY-1;return this.buffer_[d]=new goog.debug.LogRecord(a,b,c)};goog.debug.LogBuffer.isBufferingEnabled=function(){return 0<goog.debug.LogBuffer.CAPACITY};
                +goog.debug.LogBuffer.prototype.clear=function(){this.buffer_=Array(goog.debug.LogBuffer.CAPACITY);this.curIndex_=-1;this.isFull_=!1};goog.debug.LogBuffer.prototype.forEachRecord=function(a){var b=this.buffer_;if(b[0]){var c=this.curIndex_,d=this.isFull_?c:-1;do d=(d+1)%goog.debug.LogBuffer.CAPACITY,a(b[d]);while(d!=c)}};goog.debug.Logger=function(a){this.name_=a;this.handlers_=this.children_=this.level_=this.parent_=null};goog.debug.Logger.ROOT_LOGGER_NAME="";goog.debug.Logger.ENABLE_HIERARCHY=!0;goog.debug.Logger.ENABLE_HIERARCHY||(goog.debug.Logger.rootHandlers_=[]);goog.debug.Logger.Level=function(a,b){this.name=a;this.value=b};goog.debug.Logger.Level.prototype.toString=function(){return this.name};goog.debug.Logger.Level.OFF=new goog.debug.Logger.Level("OFF",Infinity);
                +goog.debug.Logger.Level.SHOUT=new goog.debug.Logger.Level("SHOUT",1200);goog.debug.Logger.Level.SEVERE=new goog.debug.Logger.Level("SEVERE",1E3);goog.debug.Logger.Level.WARNING=new goog.debug.Logger.Level("WARNING",900);goog.debug.Logger.Level.INFO=new goog.debug.Logger.Level("INFO",800);goog.debug.Logger.Level.CONFIG=new goog.debug.Logger.Level("CONFIG",700);goog.debug.Logger.Level.FINE=new goog.debug.Logger.Level("FINE",500);goog.debug.Logger.Level.FINER=new goog.debug.Logger.Level("FINER",400);
                +goog.debug.Logger.Level.FINEST=new goog.debug.Logger.Level("FINEST",300);goog.debug.Logger.Level.ALL=new goog.debug.Logger.Level("ALL",0);goog.debug.Logger.Level.PREDEFINED_LEVELS=[goog.debug.Logger.Level.OFF,goog.debug.Logger.Level.SHOUT,goog.debug.Logger.Level.SEVERE,goog.debug.Logger.Level.WARNING,goog.debug.Logger.Level.INFO,goog.debug.Logger.Level.CONFIG,goog.debug.Logger.Level.FINE,goog.debug.Logger.Level.FINER,goog.debug.Logger.Level.FINEST,goog.debug.Logger.Level.ALL];
                +goog.debug.Logger.Level.predefinedLevelsCache_=null;goog.debug.Logger.Level.createPredefinedLevelsCache_=function(){goog.debug.Logger.Level.predefinedLevelsCache_={};for(var a=0,b;b=goog.debug.Logger.Level.PREDEFINED_LEVELS[a];a++)goog.debug.Logger.Level.predefinedLevelsCache_[b.value]=b,goog.debug.Logger.Level.predefinedLevelsCache_[b.name]=b};
                +goog.debug.Logger.Level.getPredefinedLevel=function(a){goog.debug.Logger.Level.predefinedLevelsCache_||goog.debug.Logger.Level.createPredefinedLevelsCache_();return goog.debug.Logger.Level.predefinedLevelsCache_[a]||null};
                +goog.debug.Logger.Level.getPredefinedLevelByValue=function(a){goog.debug.Logger.Level.predefinedLevelsCache_||goog.debug.Logger.Level.createPredefinedLevelsCache_();if(a in goog.debug.Logger.Level.predefinedLevelsCache_)return goog.debug.Logger.Level.predefinedLevelsCache_[a];for(var b=0;b<goog.debug.Logger.Level.PREDEFINED_LEVELS.length;++b){var c=goog.debug.Logger.Level.PREDEFINED_LEVELS[b];if(c.value<=a)return c}return null};goog.debug.Logger.getLogger=function(a){return goog.debug.LogManager.getLogger(a)};
                +goog.debug.Logger.logToProfilers=function(a){goog.global.console&&(goog.global.console.timeStamp?goog.global.console.timeStamp(a):goog.global.console.markTimeline&&goog.global.console.markTimeline(a));goog.global.msWriteProfilerMark&&goog.global.msWriteProfilerMark(a)};goog.debug.Logger.prototype.getName=function(){return this.name_};
                +goog.debug.Logger.prototype.addHandler=function(a){goog.debug.LOGGING_ENABLED&&(goog.debug.Logger.ENABLE_HIERARCHY?(this.handlers_||(this.handlers_=[]),this.handlers_.push(a)):(goog.asserts.assert(!this.name_,"Cannot call addHandler on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."),goog.debug.Logger.rootHandlers_.push(a)))};
                +goog.debug.Logger.prototype.removeHandler=function(a){if(goog.debug.LOGGING_ENABLED){var b=goog.debug.Logger.ENABLE_HIERARCHY?this.handlers_:goog.debug.Logger.rootHandlers_;return!!b&&goog.array.remove(b,a)}return!1};goog.debug.Logger.prototype.getParent=function(){return this.parent_};goog.debug.Logger.prototype.getChildren=function(){this.children_||(this.children_={});return this.children_};
                +goog.debug.Logger.prototype.setLevel=function(a){goog.debug.LOGGING_ENABLED&&(goog.debug.Logger.ENABLE_HIERARCHY?this.level_=a:(goog.asserts.assert(!this.name_,"Cannot call setLevel() on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."),goog.debug.Logger.rootLevel_=a))};goog.debug.Logger.prototype.getLevel=function(){return goog.debug.LOGGING_ENABLED?this.level_:goog.debug.Logger.Level.OFF};
                +goog.debug.Logger.prototype.getEffectiveLevel=function(){if(!goog.debug.LOGGING_ENABLED)return goog.debug.Logger.Level.OFF;if(!goog.debug.Logger.ENABLE_HIERARCHY)return goog.debug.Logger.rootLevel_;if(this.level_)return this.level_;if(this.parent_)return this.parent_.getEffectiveLevel();goog.asserts.fail("Root logger has no level set.");return null};goog.debug.Logger.prototype.isLoggable=function(a){return goog.debug.LOGGING_ENABLED&&a.value>=this.getEffectiveLevel().value};
                +goog.debug.Logger.prototype.log=function(a,b,c){goog.debug.LOGGING_ENABLED&&this.isLoggable(a)&&(goog.isFunction(b)&&(b=b()),this.doLogRecord_(this.getLogRecord(a,b,c)))};goog.debug.Logger.prototype.getLogRecord=function(a,b,c){a=goog.debug.LogBuffer.isBufferingEnabled()?goog.debug.LogBuffer.getInstance().addRecord(a,b,this.name_):new goog.debug.LogRecord(a,String(b),this.name_);c&&a.setException(c);return a};
                +goog.debug.Logger.prototype.shout=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.SHOUT,a,b)};goog.debug.Logger.prototype.severe=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.SEVERE,a,b)};goog.debug.Logger.prototype.warning=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.WARNING,a,b)};goog.debug.Logger.prototype.info=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.INFO,a,b)};
                +goog.debug.Logger.prototype.config=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.CONFIG,a,b)};goog.debug.Logger.prototype.fine=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINE,a,b)};goog.debug.Logger.prototype.finer=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINER,a,b)};goog.debug.Logger.prototype.finest=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINEST,a,b)};
                +goog.debug.Logger.prototype.logRecord=function(a){goog.debug.LOGGING_ENABLED&&this.isLoggable(a.getLevel())&&this.doLogRecord_(a)};goog.debug.Logger.prototype.doLogRecord_=function(a){goog.debug.Logger.logToProfilers("log:"+a.getMessage());if(goog.debug.Logger.ENABLE_HIERARCHY)for(var b=this;b;)b.callPublish_(a),b=b.getParent();else for(var b=0,c;c=goog.debug.Logger.rootHandlers_[b++];)c(a)};goog.debug.Logger.prototype.callPublish_=function(a){if(this.handlers_)for(var b=0,c;c=this.handlers_[b];b++)c(a)};
                +goog.debug.Logger.prototype.setParent_=function(a){this.parent_=a};goog.debug.Logger.prototype.addChild_=function(a,b){this.getChildren()[a]=b};goog.debug.LogManager={};goog.debug.LogManager.loggers_={};goog.debug.LogManager.rootLogger_=null;
                +goog.debug.LogManager.initialize=function(){goog.debug.LogManager.rootLogger_||(goog.debug.LogManager.rootLogger_=new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME),goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME]=goog.debug.LogManager.rootLogger_,goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG))};goog.debug.LogManager.getLoggers=function(){return goog.debug.LogManager.loggers_};
                +goog.debug.LogManager.getRoot=function(){goog.debug.LogManager.initialize();return goog.debug.LogManager.rootLogger_};goog.debug.LogManager.getLogger=function(a){goog.debug.LogManager.initialize();return goog.debug.LogManager.loggers_[a]||goog.debug.LogManager.createLogger_(a)};goog.debug.LogManager.createFunctionForCatchErrors=function(a){return function(b){(a||goog.debug.LogManager.getRoot()).severe("Error: "+b.message+" ("+b.fileName+" @ Line: "+b.line+")")}};
                +goog.debug.LogManager.createLogger_=function(a){var b=new goog.debug.Logger(a);if(goog.debug.Logger.ENABLE_HIERARCHY){var c=a.lastIndexOf("."),d=a.substr(0,c),c=a.substr(c+1),d=goog.debug.LogManager.getLogger(d);d.addChild_(c,b);b.setParent_(d)}return goog.debug.LogManager.loggers_[a]=b};goog.log={};goog.log.ENABLED=goog.debug.LOGGING_ENABLED;goog.log.ROOT_LOGGER_NAME=goog.debug.Logger.ROOT_LOGGER_NAME;goog.log.Logger=goog.debug.Logger;goog.log.Level=goog.debug.Logger.Level;goog.log.LogRecord=goog.debug.LogRecord;goog.log.getLogger=function(a,b){return goog.log.ENABLED?(a=goog.debug.LogManager.getLogger(a),b&&a&&a.setLevel(b),a):null};goog.log.addHandler=function(a,b){goog.log.ENABLED&&a&&a.addHandler(b)};
                +goog.log.removeHandler=function(a,b){return goog.log.ENABLED&&a?a.removeHandler(b):!1};goog.log.log=function(a,b,c,d){goog.log.ENABLED&&a&&a.log(b,c,d)};goog.log.error=function(a,b,c){goog.log.ENABLED&&a&&a.severe(b,c)};goog.log.warning=function(a,b,c){goog.log.ENABLED&&a&&a.warning(b,c)};goog.log.info=function(a,b,c){goog.log.ENABLED&&a&&a.info(b,c)};goog.log.fine=function(a,b,c){goog.log.ENABLED&&a&&a.fine(b,c)};goog.string.StringBuffer=function(a,b){null!=a&&this.append.apply(this,arguments)};goog.string.StringBuffer.prototype.buffer_="";goog.string.StringBuffer.prototype.set=function(a){this.buffer_=""+a};goog.string.StringBuffer.prototype.append=function(a,b,c){this.buffer_+=String(a);if(null!=b)for(var d=1;d<arguments.length;d++)this.buffer_+=arguments[d];return this};goog.string.StringBuffer.prototype.clear=function(){this.buffer_=""};goog.string.StringBuffer.prototype.getLength=function(){return this.buffer_.length};
                +goog.string.StringBuffer.prototype.toString=function(){return this.buffer_};goog.ui.tree={};goog.ui.tree.BaseNode=function(a,b,c){goog.ui.Component.call(this,c);this.config_=b||goog.ui.tree.BaseNode.defaultConfig;this.html_=goog.html.SafeHtml.htmlEscapePreservingNewlines(a);this.expanded_=this.selected_=!1;this.toolTip_=null;this.afterLabelHtml_=goog.html.SafeHtml.EMPTY;this.isUserCollapsible_=!0;this.depth_=-1};goog.inherits(goog.ui.tree.BaseNode,goog.ui.Component);
                +goog.ui.tree.BaseNode.EventType={BEFORE_EXPAND:"beforeexpand",EXPAND:"expand",BEFORE_COLLAPSE:"beforecollapse",COLLAPSE:"collapse"};goog.ui.tree.BaseNode.allNodes={};goog.ui.tree.BaseNode.prototype.disposeInternal=function(){goog.ui.tree.BaseNode.superClass_.disposeInternal.call(this);this.tree&&(this.tree.removeNode(this),this.tree=null);this.setElementInternal(null)};
                +goog.ui.tree.BaseNode.prototype.initAccessibility=function(){var a=this.getElement();if(a){var b=this.getLabelElement();b&&!b.id&&(b.id=this.getId()+".label");goog.a11y.aria.setRole(a,"treeitem");goog.a11y.aria.setState(a,"selected",!1);goog.a11y.aria.setState(a,"level",this.getDepth());b&&goog.a11y.aria.setState(a,"labelledby",b.id);(b=this.getIconElement())&&goog.a11y.aria.setRole(b,"presentation");(b=this.getExpandIconElement())&&goog.a11y.aria.setRole(b,"presentation");if(b=this.getChildrenElement())if(goog.a11y.aria.setRole(b,
                +"group"),b.hasChildNodes())for(goog.a11y.aria.setState(a,goog.a11y.aria.State.EXPANDED,!1),a=this.getChildCount(),b=1;b<=a;b++){var c=this.getChildAt(b-1).getElement();goog.asserts.assert(c,"The child element cannot be null");goog.a11y.aria.setState(c,"setsize",a);goog.a11y.aria.setState(c,"posinset",b)}}};goog.ui.tree.BaseNode.prototype.createDom=function(){var a=this.getDomHelper().safeHtmlToNode(this.toSafeHtml());this.setElementInternal(a)};
                +goog.ui.tree.BaseNode.prototype.enterDocument=function(){goog.ui.tree.BaseNode.superClass_.enterDocument.call(this);goog.ui.tree.BaseNode.allNodes[this.getId()]=this;this.initAccessibility()};goog.ui.tree.BaseNode.prototype.exitDocument=function(){goog.ui.tree.BaseNode.superClass_.exitDocument.call(this);delete goog.ui.tree.BaseNode.allNodes[this.getId()]};
                +goog.ui.tree.BaseNode.prototype.addChildAt=function(a,b,c){goog.asserts.assert(!a.getParent());goog.asserts.assertInstanceof(a,goog.ui.tree.BaseNode);c=this.getChildAt(b-1);var d=this.getChildAt(b);goog.ui.tree.BaseNode.superClass_.addChildAt.call(this,a,b);a.previousSibling_=c;a.nextSibling_=d;c?c.nextSibling_=a:this.firstChild_=a;d?d.previousSibling_=a:this.lastChild_=a;(b=this.getTree())&&a.setTreeInternal(b);a.setDepth_(this.getDepth()+1);if(b=this.getElement())if(this.updateExpandIcon(),goog.a11y.aria.setState(b,
                +goog.a11y.aria.State.EXPANDED,this.getExpanded()),this.getExpanded()){b=this.getChildrenElement();a.getElement()||a.createDom();var e=a.getElement(),f=d&&d.getElement();b.insertBefore(e,f);this.isInDocument()&&a.enterDocument();d||(c?c.updateExpandIcon():(goog.style.setElementShown(b,!0),this.setExpanded(this.getExpanded())))}};
                +goog.ui.tree.BaseNode.prototype.add=function(a,b){goog.asserts.assert(!b||b.getParent()==this,"Can only add nodes before siblings");a.getParent()&&a.getParent().removeChild(a);this.addChildAt(a,b?this.indexOfChild(b):this.getChildCount());return a};
                +goog.ui.tree.BaseNode.prototype.removeChild=function(a,b){var c=this.getTree();b=c?c.getSelectedItem():null;if(b==a||a.contains(b))c.hasFocus()?(this.select(),goog.Timer.callOnce(this.onTimeoutSelect_,10,this)):this.select();goog.ui.tree.BaseNode.superClass_.removeChild.call(this,a);this.lastChild_==a&&(this.lastChild_=a.previousSibling_);this.firstChild_==a&&(this.firstChild_=a.nextSibling_);a.previousSibling_&&(a.previousSibling_.nextSibling_=a.nextSibling_);a.nextSibling_&&(a.nextSibling_.previousSibling_=
                +a.previousSibling_);b=a.isLastSibling();a.tree=null;a.depth_=-1;if(c&&(c.removeNode(a),this.isInDocument())){c=this.getChildrenElement();if(a.isInDocument()){var d=a.getElement();c.removeChild(d);a.exitDocument()}b&&(b=this.getLastChild())&&b.updateExpandIcon();this.hasChildren()||(c.style.display="none",this.updateExpandIcon(),this.updateIcon_(),(b=this.getElement())&&goog.a11y.aria.removeState(b,goog.a11y.aria.State.EXPANDED))}return a};goog.ui.tree.BaseNode.prototype.remove=goog.ui.tree.BaseNode.prototype.removeChild;
                +goog.ui.tree.BaseNode.prototype.onTimeoutSelect_=function(){this.select()};goog.ui.tree.BaseNode.prototype.getTree=goog.abstractMethod;goog.ui.tree.BaseNode.prototype.getDepth=function(){var a=this.depth_;0>a&&(a=this.computeDepth_(),this.setDepth_(a));return a};goog.ui.tree.BaseNode.prototype.computeDepth_=function(){var a=this.getParent();return a?a.getDepth()+1:0};
                +goog.ui.tree.BaseNode.prototype.setDepth_=function(a){if(a!=this.depth_){this.depth_=a;var b=this.getRowElement();if(b){var c=this.getPixelIndent_()+"px";this.isRightToLeft()?b.style.paddingRight=c:b.style.paddingLeft=c}this.forEachChild(function(b){b.setDepth_(a+1)})}};goog.ui.tree.BaseNode.prototype.contains=function(a){for(;a;){if(a==this)return!0;a=a.getParent()}return!1};goog.ui.tree.BaseNode.EMPTY_CHILDREN_=[];
                +goog.ui.tree.BaseNode.prototype.getChildren=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};goog.ui.tree.BaseNode.prototype.getFirstChild=function(){return this.getChildAt(0)};goog.ui.tree.BaseNode.prototype.getLastChild=function(){return this.getChildAt(this.getChildCount()-1)};goog.ui.tree.BaseNode.prototype.getPreviousSibling=function(){return this.previousSibling_};goog.ui.tree.BaseNode.prototype.getNextSibling=function(){return this.nextSibling_};
                +goog.ui.tree.BaseNode.prototype.isLastSibling=function(){return!this.nextSibling_};goog.ui.tree.BaseNode.prototype.isSelected=function(){return this.selected_};goog.ui.tree.BaseNode.prototype.select=function(){var a=this.getTree();a&&a.setSelectedItem(this)};goog.ui.tree.BaseNode.prototype.deselect=goog.nullFunction;
                +goog.ui.tree.BaseNode.prototype.setSelectedInternal=function(a){if(this.selected_!=a){this.selected_=a;this.updateRow();var b=this.getElement();b&&(goog.a11y.aria.setState(b,"selected",a),a&&(a=this.getTree().getElement(),goog.asserts.assert(a,"The DOM element for the tree cannot be null"),goog.a11y.aria.setState(a,"activedescendant",this.getId())))}};goog.ui.tree.BaseNode.prototype.getExpanded=function(){return this.expanded_};
                +goog.ui.tree.BaseNode.prototype.setExpandedInternal=function(a){this.expanded_=a};
                +goog.ui.tree.BaseNode.prototype.setExpanded=function(a){var b=a!=this.expanded_;if(!b||this.dispatchEvent(a?goog.ui.tree.BaseNode.EventType.BEFORE_EXPAND:goog.ui.tree.BaseNode.EventType.BEFORE_COLLAPSE)){this.expanded_=a;var c=this.getTree();var d=this.getElement();if(this.hasChildren()){if(!a&&c&&this.contains(c.getSelectedItem())&&this.select(),d){if(c=this.getChildrenElement())if(goog.style.setElementShown(c,a),goog.a11y.aria.setState(d,goog.a11y.aria.State.EXPANDED,a),a&&this.isInDocument()&&
                +!c.hasChildNodes()){var e=[];this.forEachChild(function(a){e.push(a.toSafeHtml())});goog.dom.safe.setInnerHtml(c,goog.html.SafeHtml.concat(e));this.forEachChild(function(a){a.enterDocument()})}this.updateExpandIcon()}}else(c=this.getChildrenElement())&&goog.style.setElementShown(c,!1);d&&this.updateIcon_();b&&this.dispatchEvent(a?goog.ui.tree.BaseNode.EventType.EXPAND:goog.ui.tree.BaseNode.EventType.COLLAPSE)}};goog.ui.tree.BaseNode.prototype.toggle=function(){this.setExpanded(!this.getExpanded())};
                +goog.ui.tree.BaseNode.prototype.expand=function(){this.setExpanded(!0)};goog.ui.tree.BaseNode.prototype.collapse=function(){this.setExpanded(!1)};goog.ui.tree.BaseNode.prototype.collapseChildren=function(){this.forEachChild(function(a){a.collapseAll()})};goog.ui.tree.BaseNode.prototype.collapseAll=function(){this.collapseChildren();this.collapse()};goog.ui.tree.BaseNode.prototype.expandChildren=function(){this.forEachChild(function(a){a.expandAll()})};
                +goog.ui.tree.BaseNode.prototype.expandAll=function(){this.expandChildren();this.expand()};goog.ui.tree.BaseNode.prototype.reveal=function(){var a=this.getParent();a&&(a.setExpanded(!0),a.reveal())};goog.ui.tree.BaseNode.prototype.setIsUserCollapsible=function(a){(this.isUserCollapsible_=a)||this.expand();this.getElement()&&this.updateExpandIcon()};goog.ui.tree.BaseNode.prototype.isUserCollapsible=function(){return this.isUserCollapsible_};
                +goog.ui.tree.BaseNode.prototype.toSafeHtml=function(){var a=this.getTree(),b=!a.getShowLines()||a==this.getParent()&&!a.getShowRootLines()?this.config_.cssChildrenNoLines:this.config_.cssChildren,a=this.getExpanded()&&this.hasChildren(),b={"class":b,style:this.getLineStyle()},c=[];a&&this.forEachChild(function(a){c.push(a.toSafeHtml())});a=goog.html.SafeHtml.create("div",b,c);return goog.html.SafeHtml.create("div",{"class":this.config_.cssItem,id:this.getId()},[this.getRowSafeHtml(),a])};
                +goog.ui.tree.BaseNode.prototype.getPixelIndent_=function(){return Math.max(0,(this.getDepth()-1)*this.config_.indentWidth)};goog.ui.tree.BaseNode.prototype.getRowSafeHtml=function(){var a={};a["padding-"+(this.isRightToLeft()?"right":"left")]=this.getPixelIndent_()+"px";var a={"class":this.getRowClassName(),style:a},b=[this.getExpandIconSafeHtml(),this.getIconSafeHtml(),this.getLabelSafeHtml()];return goog.html.SafeHtml.create("div",a,b)};
                +goog.ui.tree.BaseNode.prototype.getRowClassName=function(){var a=this.isSelected()?" "+this.config_.cssSelectedRow:"";return this.config_.cssTreeRow+a};goog.ui.tree.BaseNode.prototype.getLabelSafeHtml=function(){var a=goog.html.SafeHtml.create("span",{"class":this.config_.cssItemLabel,title:this.getToolTip()||null},this.getSafeHtml());return goog.html.SafeHtml.concat(a,goog.html.SafeHtml.create("span",{},this.getAfterLabelSafeHtml()))};goog.ui.tree.BaseNode.prototype.getAfterLabelHtml=function(){return goog.html.SafeHtml.unwrap(this.getAfterLabelSafeHtml())};
                +goog.ui.tree.BaseNode.prototype.getAfterLabelSafeHtml=function(){return this.afterLabelHtml_};goog.ui.tree.BaseNode.prototype.setAfterLabelSafeHtml=function(a){this.afterLabelHtml_=a;var b=this.getAfterLabelElement();b&&goog.dom.safe.setInnerHtml(b,a)};goog.ui.tree.BaseNode.prototype.getIconSafeHtml=function(){return goog.html.SafeHtml.create("span",{style:{display:"inline-block"},"class":this.getCalculatedIconClass()})};goog.ui.tree.BaseNode.prototype.getCalculatedIconClass=goog.abstractMethod;
                +goog.ui.tree.BaseNode.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.create("span",{type:"expand",style:{display:"inline-block"},"class":this.getExpandIconClass()})};
                +goog.ui.tree.BaseNode.prototype.getExpandIconClass=function(){var a=this.getTree(),b=!a.getShowLines()||a==this.getParent()&&!a.getShowRootLines(),c=this.config_,d=new goog.string.StringBuffer;d.append(c.cssTreeIcon," ",c.cssExpandTreeIcon," ");if(this.hasChildren()){var e=0;a.getShowExpandIcons()&&this.isUserCollapsible_&&(e=this.getExpanded()?2:1);b||(e=this.isLastSibling()?e+4:e+8);switch(e){case 1:d.append(c.cssExpandTreeIconPlus);break;case 2:d.append(c.cssExpandTreeIconMinus);break;case 4:d.append(c.cssExpandTreeIconL);
                +break;case 5:d.append(c.cssExpandTreeIconLPlus);break;case 6:d.append(c.cssExpandTreeIconLMinus);break;case 8:d.append(c.cssExpandTreeIconT);break;case 9:d.append(c.cssExpandTreeIconTPlus);break;case 10:d.append(c.cssExpandTreeIconTMinus);break;default:d.append(c.cssExpandTreeIconBlank)}}else b?d.append(c.cssExpandTreeIconBlank):this.isLastSibling()?d.append(c.cssExpandTreeIconL):d.append(c.cssExpandTreeIconT);return d.toString()};
                +goog.ui.tree.BaseNode.prototype.getLineStyle=function(){var a=this.getExpanded()&&this.hasChildren();return goog.html.SafeStyle.create({"background-position":this.getBackgroundPosition(),display:a?null:"none"})};goog.ui.tree.BaseNode.prototype.getBackgroundPosition=function(){return(this.isLastSibling()?"-100":(this.getDepth()-1)*this.config_.indentWidth)+"px 0"};
                +goog.ui.tree.BaseNode.prototype.getElement=function(){var a=goog.ui.tree.BaseNode.superClass_.getElement.call(this);a||(a=this.getDomHelper().getElement(this.getId()),this.setElementInternal(a));return a};goog.ui.tree.BaseNode.prototype.getRowElement=function(){var a=this.getElement();return a?a.firstChild:null};goog.ui.tree.BaseNode.prototype.getExpandIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};
                +goog.ui.tree.BaseNode.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.childNodes[1]:null};goog.ui.tree.BaseNode.prototype.getLabelElement=function(){var a=this.getRowElement();return a&&a.lastChild?a.lastChild.previousSibling:null};goog.ui.tree.BaseNode.prototype.getAfterLabelElement=function(){var a=this.getRowElement();return a?a.lastChild:null};goog.ui.tree.BaseNode.prototype.getChildrenElement=function(){var a=this.getElement();return a?a.lastChild:null};
                +goog.ui.tree.BaseNode.prototype.setIconClass=function(a){this.iconClass_=a;this.isInDocument()&&this.updateIcon_()};goog.ui.tree.BaseNode.prototype.getIconClass=function(){return this.iconClass_};goog.ui.tree.BaseNode.prototype.setExpandedIconClass=function(a){this.expandedIconClass_=a;this.isInDocument()&&this.updateIcon_()};goog.ui.tree.BaseNode.prototype.getExpandedIconClass=function(){return this.expandedIconClass_};goog.ui.tree.BaseNode.prototype.setText=function(a){this.setSafeHtml(goog.html.SafeHtml.htmlEscape(a))};
                +goog.ui.tree.BaseNode.prototype.getText=function(){return goog.string.unescapeEntities(goog.html.SafeHtml.unwrap(this.html_))};goog.ui.tree.BaseNode.prototype.setSafeHtml=function(a){this.html_=a;var b=this.getLabelElement();b&&goog.dom.safe.setInnerHtml(b,a);(a=this.getTree())&&a.setNode(this)};goog.ui.tree.BaseNode.prototype.getHtml=function(){return goog.html.SafeHtml.unwrap(this.getSafeHtml())};goog.ui.tree.BaseNode.prototype.getSafeHtml=function(){return this.html_};
                +goog.ui.tree.BaseNode.prototype.setToolTip=function(a){this.toolTip_=a;var b=this.getLabelElement();b&&(b.title=a)};goog.ui.tree.BaseNode.prototype.getToolTip=function(){return this.toolTip_};goog.ui.tree.BaseNode.prototype.updateRow=function(){var a=this.getRowElement();a&&(a.className=this.getRowClassName())};
                +goog.ui.tree.BaseNode.prototype.updateExpandIcon=function(){var a=this.getExpandIconElement();a&&(a.className=this.getExpandIconClass());if(a=this.getChildrenElement())a.style.backgroundPosition=this.getBackgroundPosition()};goog.ui.tree.BaseNode.prototype.updateIcon_=function(){this.getIconElement().className=this.getCalculatedIconClass()};
                +goog.ui.tree.BaseNode.prototype.onMouseDown=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()?this.isUserCollapsible_&&this.toggle():(this.select(),this.updateRow())};goog.ui.tree.BaseNode.prototype.onClick_=goog.events.Event.preventDefault;goog.ui.tree.BaseNode.prototype.onDoubleClick_=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()||this.isUserCollapsible_&&this.toggle()};
                +goog.ui.tree.BaseNode.prototype.onKeyDown=function(a){var b=!0;switch(a.keyCode){case goog.events.KeyCodes.RIGHT:if(a.altKey)break;this.hasChildren()&&(this.getExpanded()?this.getFirstChild().select():this.setExpanded(!0));break;case goog.events.KeyCodes.LEFT:if(a.altKey)break;if(this.hasChildren()&&this.getExpanded()&&this.isUserCollapsible_)this.setExpanded(!1);else{var c=this.getParent();var d=this.getTree();c&&(d.getShowRootNode()||c!=d)&&c.select()}break;case goog.events.KeyCodes.DOWN:(d=this.getNextShownNode())&&
                +d.select();break;case goog.events.KeyCodes.UP:(d=this.getPreviousShownNode())&&d.select();break;default:b=!1}b&&(a.preventDefault(),(d=this.getTree())&&d.clearTypeAhead());return b};goog.ui.tree.BaseNode.prototype.getLastShownDescendant=function(){return this.getExpanded()&&this.hasChildren()?this.getLastChild().getLastShownDescendant():this};
                +goog.ui.tree.BaseNode.prototype.getNextShownNode=function(){if(this.hasChildren()&&this.getExpanded())return this.getFirstChild();for(var a=this,b;a!=this.getTree();){b=a.getNextSibling();if(null!=b)return b;a=a.getParent()}return null};goog.ui.tree.BaseNode.prototype.getPreviousShownNode=function(){var a=this.getPreviousSibling();if(null!=a)return a.getLastShownDescendant();var a=this.getParent(),b=this.getTree();return!b.getShowRootNode()&&a==b||this==b?null:a};
                +goog.ui.tree.BaseNode.prototype.getClientData=goog.ui.tree.BaseNode.prototype.getModel;goog.ui.tree.BaseNode.prototype.setClientData=goog.ui.tree.BaseNode.prototype.setModel;goog.ui.tree.BaseNode.prototype.getConfig=function(){return this.config_};goog.ui.tree.BaseNode.prototype.setTreeInternal=function(a){this.tree!=a&&(this.tree=a,a.setNode(this),this.forEachChild(function(b){b.setTreeInternal(a)}))};
                +goog.ui.tree.BaseNode.defaultConfig={indentWidth:19,cssRoot:"goog-tree-root goog-tree-item",cssHideRoot:"goog-tree-hide-root",cssItem:"goog-tree-item",cssChildren:"goog-tree-children",cssChildrenNoLines:"goog-tree-children-nolines",cssTreeRow:"goog-tree-row",cssItemLabel:"goog-tree-item-label",cssTreeIcon:"goog-tree-icon",cssExpandTreeIcon:"goog-tree-expand-icon",cssExpandTreeIconPlus:"goog-tree-expand-icon-plus",cssExpandTreeIconMinus:"goog-tree-expand-icon-minus",cssExpandTreeIconTPlus:"goog-tree-expand-icon-tplus",
                +cssExpandTreeIconTMinus:"goog-tree-expand-icon-tminus",cssExpandTreeIconLPlus:"goog-tree-expand-icon-lplus",cssExpandTreeIconLMinus:"goog-tree-expand-icon-lminus",cssExpandTreeIconT:"goog-tree-expand-icon-t",cssExpandTreeIconL:"goog-tree-expand-icon-l",cssExpandTreeIconBlank:"goog-tree-expand-icon-blank",cssExpandedFolderIcon:"goog-tree-expanded-folder-icon",cssCollapsedFolderIcon:"goog-tree-collapsed-folder-icon",cssFileIcon:"goog-tree-file-icon",cssExpandedRootIcon:"goog-tree-expanded-folder-icon",
                +cssCollapsedRootIcon:"goog-tree-collapsed-folder-icon",cssSelectedRow:"selected"};goog.ui.tree.TreeNode=function(a,b,c){goog.ui.tree.BaseNode.call(this,a,b,c)};goog.inherits(goog.ui.tree.TreeNode,goog.ui.tree.BaseNode);goog.ui.tree.TreeNode.prototype.getTree=function(){if(this.tree)return this.tree;var a=this.getParent();return a&&(a=a.getTree())?(this.setTreeInternal(a),a):null};
                +goog.ui.tree.TreeNode.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();if(this.hasChildren()){if(a&&b.cssExpandedFolderIcon)return b.cssTreeIcon+" "+b.cssExpandedFolderIcon;if(!a&&b.cssCollapsedFolderIcon)return b.cssTreeIcon+" "+b.cssCollapsedFolderIcon}else if(b.cssFileIcon)return b.cssTreeIcon+" "+b.cssFileIcon;return""};goog.structs={};goog.structs.getCount=function(a){return a.getCount&&"function"==typeof a.getCount?a.getCount():goog.isArrayLike(a)||goog.isString(a)?a.length:goog.object.getCount(a)};goog.structs.getValues=function(a){if(a.getValues&&"function"==typeof a.getValues)return a.getValues();if(goog.isString(a))return a.split("");if(goog.isArrayLike(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return goog.object.getValues(a)};
                +goog.structs.getKeys=function(a){if(a.getKeys&&"function"==typeof a.getKeys)return a.getKeys();if(!a.getValues||"function"!=typeof a.getValues){if(goog.isArrayLike(a)||goog.isString(a)){var b=[];a=a.length;for(var c=0;c<a;c++)b.push(c);return b}return goog.object.getKeys(a)}};
                +goog.structs.contains=function(a,b){return a.contains&&"function"==typeof a.contains?a.contains(b):a.containsValue&&"function"==typeof a.containsValue?a.containsValue(b):goog.isArrayLike(a)||goog.isString(a)?goog.array.contains(a,b):goog.object.containsValue(a,b)};goog.structs.isEmpty=function(a){return a.isEmpty&&"function"==typeof a.isEmpty?a.isEmpty():goog.isArrayLike(a)||goog.isString(a)?goog.array.isEmpty(a):goog.object.isEmpty(a)};
                +goog.structs.clear=function(a){a.clear&&"function"==typeof a.clear?a.clear():goog.isArrayLike(a)?goog.array.clear(a):goog.object.clear(a)};goog.structs.forEach=function(a,b,c){if(a.forEach&&"function"==typeof a.forEach)a.forEach(b,c);else if(goog.isArrayLike(a)||goog.isString(a))goog.array.forEach(a,b,c);else for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)b.call(c,e[g],d&&d[g],a)};
                +goog.structs.filter=function(a,b,c){if("function"==typeof a.filter)return a.filter(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.filter(a,b,c);var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length;if(d){var g={};for(var h=0;h<f;h++)b.call(c,e[h],d[h],a)&&(g[d[h]]=e[h])}else for(g=[],h=0;h<f;h++)b.call(c,e[h],void 0,a)&&g.push(e[h]);return g};
                +goog.structs.map=function(a,b,c){if("function"==typeof a.map)return a.map(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.map(a,b,c);var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length;if(d){var g={};for(var h=0;h<f;h++)g[d[h]]=b.call(c,e[h],d[h],a)}else for(g=[],h=0;h<f;h++)g[h]=b.call(c,e[h],void 0,a);return g};
                +goog.structs.some=function(a,b,c){if("function"==typeof a.some)return a.some(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.some(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(b.call(c,e[g],d&&d[g],a))return!0;return!1};
                +goog.structs.every=function(a,b,c){if("function"==typeof a.every)return a.every(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.every(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(!b.call(c,e[g],d&&d[g],a))return!1;return!0};goog.structs.Trie=function(a){this.value_=void 0;this.childNodes_={};a&&this.setAll(a)};goog.structs.Trie.prototype.set=function(a,b){this.setOrAdd_(a,b,!1)};goog.structs.Trie.prototype.add=function(a,b){this.setOrAdd_(a,b,!0)};
                +goog.structs.Trie.prototype.setOrAdd_=function(a,b,c){for(var d=this,e=0;e<a.length;e++){var f=a.charAt(e);d.childNodes_[f]||(d.childNodes_[f]=new goog.structs.Trie);d=d.childNodes_[f]}if(c&&void 0!==d.value_)throw Error('The collection already contains the key "'+a+'"');d.value_=b};goog.structs.Trie.prototype.setAll=function(a){var b=goog.structs.getKeys(a);a=goog.structs.getValues(a);for(var c=0;c<b.length;c++)this.set(b[c],a[c])};
                +goog.structs.Trie.prototype.getChildNode_=function(a){for(var b=this,c=0;c<a.length;c++){var d=a.charAt(c),b=b.childNodes_[d];if(!b)return}return b};goog.structs.Trie.prototype.get=function(a){return(a=this.getChildNode_(a))?a.value_:void 0};goog.structs.Trie.prototype.getKeyAndPrefixes=function(a,b){var c=this,d={};b=b||0;void 0!==c.value_&&(d[b]=c.value_);for(;b<a.length;b++){var e=a.charAt(b);if(!(e in c.childNodes_))break;c=c.childNodes_[e];void 0!==c.value_&&(d[b]=c.value_)}return d};
                +goog.structs.Trie.prototype.getValues=function(){var a=[];this.getValuesInternal_(a);return a};goog.structs.Trie.prototype.getValuesInternal_=function(a){void 0!==this.value_&&a.push(this.value_);for(var b in this.childNodes_)this.childNodes_[b].getValuesInternal_(a)};goog.structs.Trie.prototype.getKeys=function(a){var b=[];if(a){for(var c=this,d=0;d<a.length;d++){var e=a.charAt(d);if(!c.childNodes_[e])return[];c=c.childNodes_[e]}c.getKeysInternal_(a,b)}else this.getKeysInternal_("",b);return b};
                +goog.structs.Trie.prototype.getKeysInternal_=function(a,b){void 0!==this.value_&&b.push(a);for(var c in this.childNodes_)this.childNodes_[c].getKeysInternal_(a+c,b)};goog.structs.Trie.prototype.containsKey=function(a){return void 0!==this.get(a)};goog.structs.Trie.prototype.containsPrefix=function(a){return 0==a.length?!this.isEmpty():!!this.getChildNode_(a)};
                +goog.structs.Trie.prototype.containsValue=function(a){if(this.value_===a)return!0;for(var b in this.childNodes_)if(this.childNodes_[b].containsValue(a))return!0;return!1};goog.structs.Trie.prototype.clear=function(){this.childNodes_={};this.value_=void 0};
                +goog.structs.Trie.prototype.remove=function(a){for(var b,c=this,d=[],e=0;e<a.length;e++){b=a.charAt(e);if(!c.childNodes_[b])throw Error('The collection does not have the key "'+a+'"');d.push([c,b]);c=c.childNodes_[b]}a=c.value_;for(delete c.value_;0<d.length;)if(b=d.pop(),c=b[0],b=b[1],c.childNodes_[b].isEmpty())delete c.childNodes_[b];else break;return a};goog.structs.Trie.prototype.clone=function(){return new goog.structs.Trie(this)};goog.structs.Trie.prototype.getCount=function(){return goog.structs.getCount(this.getValues())};
                +goog.structs.Trie.prototype.isEmpty=function(){return void 0===this.value_&&goog.object.isEmpty(this.childNodes_)};goog.ui.tree.TypeAhead=function(){this.nodeMap_=new goog.structs.Trie;this.buffer_="";this.matchingNodes_=this.matchingLabels_=null;this.matchingNodeIndex_=this.matchingLabelIndex_=0};goog.ui.tree.TypeAhead.Offset={DOWN:1,UP:-1};
                +goog.ui.tree.TypeAhead.prototype.handleNavigation=function(a){var b=!1;switch(a.keyCode){case goog.events.KeyCodes.DOWN:case goog.events.KeyCodes.UP:a.ctrlKey&&(this.jumpTo_(a.keyCode==goog.events.KeyCodes.DOWN?goog.ui.tree.TypeAhead.Offset.DOWN:goog.ui.tree.TypeAhead.Offset.UP),b=!0);break;case goog.events.KeyCodes.BACKSPACE:a=this.buffer_.length-1;b=!0;0<a?(this.buffer_=this.buffer_.substring(0,a),this.jumpToLabel_(this.buffer_)):0==a?this.buffer_="":b=!1;break;case goog.events.KeyCodes.ESC:this.buffer_=
                +"",b=!0}return b};goog.ui.tree.TypeAhead.prototype.handleTypeAheadChar=function(a){var b=!1;a.ctrlKey||a.altKey||(a=String.fromCharCode(a.charCode||a.keyCode).toLowerCase(),goog.string.isUnicodeChar(a)&&(" "!=a||this.buffer_)&&(this.buffer_+=a,b=this.jumpToLabel_(this.buffer_)));return b};
                +goog.ui.tree.TypeAhead.prototype.setNodeInMap=function(a){var b=a.getText();if(b&&!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(b))){var b=b.toLowerCase(),c=this.nodeMap_.get(b);c?c.push(a):this.nodeMap_.set(b,[a])}};
                +goog.ui.tree.TypeAhead.prototype.removeNodeFromMap=function(a){var b=a.getText();if(b&&!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(b))){var b=b.toLowerCase(),c=this.nodeMap_.get(b);if(c){for(var d=a.getChildCount(),e=0;e<d;e++)this.removeNodeFromMap(a.getChildAt(e));goog.array.remove(c,a);c.length||this.nodeMap_.remove(b)}}};
                +goog.ui.tree.TypeAhead.prototype.jumpToLabel_=function(a){var b=!1;(a=this.nodeMap_.getKeys(a))&&a.length&&(this.matchingLabelIndex_=this.matchingNodeIndex_=0,b=this.nodeMap_.get(a[0]),b=this.selectMatchingNode_(b))&&(this.matchingLabels_=a);return b};
                +goog.ui.tree.TypeAhead.prototype.jumpTo_=function(a){var b=!1,c=this.matchingLabels_;if(c){var b=null,d=!1;if(this.matchingNodes_){var e=this.matchingNodeIndex_+a;0<=e&&e<this.matchingNodes_.length?(this.matchingNodeIndex_=e,b=this.matchingNodes_):d=!0}b||(e=this.matchingLabelIndex_+a,0<=e&&e<c.length&&(this.matchingLabelIndex_=e),c.length>this.matchingLabelIndex_&&(b=this.nodeMap_.get(c[this.matchingLabelIndex_])),b&&b.length&&d&&(this.matchingNodeIndex_=a==goog.ui.tree.TypeAhead.Offset.UP?b.length-
                +1:0));if(b=this.selectMatchingNode_(b))this.matchingLabels_=c}return b};goog.ui.tree.TypeAhead.prototype.selectMatchingNode_=function(a){if(a){if(this.matchingNodeIndex_<a.length){var b=a[this.matchingNodeIndex_];this.matchingNodes_=a}b&&(b.reveal(),b.select())}return!!b};goog.ui.tree.TypeAhead.prototype.clear=function(){this.buffer_=""};goog.ui.tree.TreeControl=function(a,b,c){goog.ui.tree.BaseNode.call(this,a,b,c);this.setExpandedInternal(!0);this.setSelectedInternal(!0);this.selectedItem_=this;this.typeAhead_=new goog.ui.tree.TypeAhead;this.focusHandler_=this.keyHandler_=null;this.logger_=goog.log.getLogger("this");this.focused_=!1;this.focusedNode_=null;this.showRootLines_=this.showRootNode_=this.showExpandIcons_=this.showLines_=!0;if(goog.userAgent.IE)try{document.execCommand("BackgroundImageCache",!1,!0)}catch(d){goog.log.warning(this.logger_,
                +"Failed to enable background image cache")}};goog.inherits(goog.ui.tree.TreeControl,goog.ui.tree.BaseNode);goog.ui.tree.TreeControl.prototype.getTree=function(){return this};goog.ui.tree.TreeControl.prototype.getDepth=function(){return 0};goog.ui.tree.TreeControl.prototype.reveal=function(){};goog.ui.tree.TreeControl.prototype.handleFocus_=function(a){this.focused_=!0;goog.dom.classlist.add(goog.asserts.assert(this.getElement()),"focused");this.selectedItem_&&this.selectedItem_.select()};
                +goog.ui.tree.TreeControl.prototype.handleBlur_=function(a){this.focused_=!1;goog.dom.classlist.remove(goog.asserts.assert(this.getElement()),"focused")};goog.ui.tree.TreeControl.prototype.hasFocus=function(){return this.focused_};goog.ui.tree.TreeControl.prototype.getExpanded=function(){return!this.showRootNode_||goog.ui.tree.TreeControl.superClass_.getExpanded.call(this)};
                +goog.ui.tree.TreeControl.prototype.setExpanded=function(a){this.showRootNode_?goog.ui.tree.TreeControl.superClass_.setExpanded.call(this,a):this.setExpandedInternal(a)};goog.ui.tree.TreeControl.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.EMPTY};goog.ui.tree.TreeControl.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};goog.ui.tree.TreeControl.prototype.getExpandIconElement=function(){return null};
                +goog.ui.tree.TreeControl.prototype.updateExpandIcon=function(){};goog.ui.tree.TreeControl.prototype.getRowClassName=function(){return goog.ui.tree.TreeControl.superClass_.getRowClassName.call(this)+(this.showRootNode_?"":" "+this.getConfig().cssHideRoot)};
                +goog.ui.tree.TreeControl.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();return a&&b.cssExpandedRootIcon?b.cssTreeIcon+" "+b.cssExpandedRootIcon:!a&&b.cssCollapsedRootIcon?b.cssTreeIcon+" "+b.cssCollapsedRootIcon:""};
                +goog.ui.tree.TreeControl.prototype.setSelectedItem=function(a){if(this.selectedItem_!=a){var b=!1;this.selectedItem_&&(b=this.selectedItem_==this.focusedNode_,this.selectedItem_.setSelectedInternal(!1));if(this.selectedItem_=a)a.setSelectedInternal(!0),b&&a.select();this.dispatchEvent(goog.events.EventType.CHANGE)}};goog.ui.tree.TreeControl.prototype.getSelectedItem=function(){return this.selectedItem_};
                +goog.ui.tree.TreeControl.prototype.setShowLines=function(a){this.showLines_!=a&&(this.showLines_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowLines=function(){return this.showLines_};
                +goog.ui.tree.TreeControl.prototype.updateLinesAndExpandIcons_=function(){function a(e){var f=e.getChildrenElement();if(f){var g=!c||b==e.getParent()&&!d?e.getConfig().cssChildrenNoLines:e.getConfig().cssChildren;f.className=g;if(f=e.getExpandIconElement())f.className=e.getExpandIconClass()}e.forEachChild(a)}var b=this,c=b.getShowLines(),d=b.getShowRootLines();a(this)};
                +goog.ui.tree.TreeControl.prototype.setShowRootLines=function(a){this.showRootLines_!=a&&(this.showRootLines_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowRootLines=function(){return this.showRootLines_};goog.ui.tree.TreeControl.prototype.setShowExpandIcons=function(a){this.showExpandIcons_!=a&&(this.showExpandIcons_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowExpandIcons=function(){return this.showExpandIcons_};
                +goog.ui.tree.TreeControl.prototype.setShowRootNode=function(a){if(this.showRootNode_!=a){this.showRootNode_=a;if(this.isInDocument()){var b=this.getRowElement();b&&(b.className=this.getRowClassName())}!a&&this.getSelectedItem()==this&&this.getFirstChild()&&this.setSelectedItem(this.getFirstChild())}};goog.ui.tree.TreeControl.prototype.getShowRootNode=function(){return this.showRootNode_};
                +goog.ui.tree.TreeControl.prototype.initAccessibility=function(){goog.ui.tree.TreeControl.superClass_.initAccessibility.call(this);var a=this.getElement();goog.asserts.assert(a,"The DOM element for the tree cannot be null.");goog.a11y.aria.setRole(a,"tree");goog.a11y.aria.setState(a,"labelledby",this.getLabelElement().id)};
                +goog.ui.tree.TreeControl.prototype.enterDocument=function(){goog.ui.tree.TreeControl.superClass_.enterDocument.call(this);var a=this.getElement();a.className=this.getConfig().cssRoot;a.setAttribute("hideFocus","true");this.attachEvents_();this.initAccessibility()};goog.ui.tree.TreeControl.prototype.exitDocument=function(){goog.ui.tree.TreeControl.superClass_.exitDocument.call(this);this.detachEvents_()};
                +goog.ui.tree.TreeControl.prototype.attachEvents_=function(){var a=this.getElement();a.tabIndex=0;var b=this.keyHandler_=new goog.events.KeyHandler(a),c=this.focusHandler_=new goog.events.FocusHandler(a);this.getHandler().listen(c,goog.events.FocusHandler.EventType.FOCUSOUT,this.handleBlur_).listen(c,goog.events.FocusHandler.EventType.FOCUSIN,this.handleFocus_).listen(b,goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent).listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseEvent_).listen(a,
                +goog.events.EventType.CLICK,this.handleMouseEvent_).listen(a,goog.events.EventType.DBLCLICK,this.handleMouseEvent_)};goog.ui.tree.TreeControl.prototype.detachEvents_=function(){this.keyHandler_.dispose();this.keyHandler_=null;this.focusHandler_.dispose();this.focusHandler_=null};
                +goog.ui.tree.TreeControl.prototype.handleMouseEvent_=function(a){goog.log.fine(this.logger_,"Received event "+a.type);var b=this.getNodeFromEvent_(a);if(b)switch(a.type){case goog.events.EventType.MOUSEDOWN:b.onMouseDown(a);break;case goog.events.EventType.CLICK:b.onClick_(a);break;case goog.events.EventType.DBLCLICK:b.onDoubleClick_(a)}};
                +goog.ui.tree.TreeControl.prototype.handleKeyEvent=function(a){var b;(b=this.typeAhead_.handleNavigation(a)||this.selectedItem_&&this.selectedItem_.onKeyDown(a)||this.typeAhead_.handleTypeAheadChar(a))&&a.preventDefault();return b};goog.ui.tree.TreeControl.prototype.getNodeFromEvent_=function(a){for(var b=a.target;null!=b;){if(a=goog.ui.tree.BaseNode.allNodes[b.id])return a;if(b==this.getElement())break;b=b.parentNode}return null};
                +goog.ui.tree.TreeControl.prototype.createNode=function(a){return new goog.ui.tree.TreeNode(a||goog.html.SafeHtml.EMPTY,this.getConfig(),this.getDomHelper())};goog.ui.tree.TreeControl.prototype.setNode=function(a){this.typeAhead_.setNodeInMap(a)};goog.ui.tree.TreeControl.prototype.removeNode=function(a){this.typeAhead_.removeNodeFromMap(a)};goog.ui.tree.TreeControl.prototype.clearTypeAhead=function(){this.typeAhead_.clear()};goog.ui.tree.TreeControl.defaultConfig=goog.ui.tree.BaseNode.defaultConfig;/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2013 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +var Blockly={};Blockly.Blocks=Object(null);/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2016 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Touch={};Blockly.Touch.touchIdentifier_=null;Blockly.Touch.TOUCH_MAP={};goog.events.BrowserFeature.TOUCH_ENABLED&&(Blockly.Touch.TOUCH_MAP={mousedown:["touchstart"],mousemove:["touchmove"],mouseup:["touchend","touchcancel"]});Blockly.longPid_=0;Blockly.longStart_=function(a,b){Blockly.longStop_();1==a.changedTouches.length&&(Blockly.longPid_=setTimeout(function(){a.button=2;a.clientX=a.changedTouches[0].clientX;a.clientY=a.changedTouches[0].clientY;b&&b.handleRightClick(a)},Blockly.LONGPRESS))};
                +Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)};Blockly.Touch.clearTouchIdentifier=function(){Blockly.Touch.touchIdentifier_=null};Blockly.Touch.shouldHandleEvent=function(a){return!Blockly.Touch.isMouseOrTouchEvent(a)||Blockly.Touch.checkTouchIdentifier(a)};
                +Blockly.Touch.getTouchIdentifierFromEvent=function(a){return a.changedTouches&&a.changedTouches[0]&&void 0!=a.changedTouches[0].identifier&&null!=a.changedTouches[0].identifier?a.changedTouches[0].identifier:"mouse"};
                +Blockly.Touch.checkTouchIdentifier=function(a){var b=Blockly.Touch.getTouchIdentifierFromEvent(a);return void 0!=Blockly.Touch.touchIdentifier_&&null!=Blockly.Touch.touchIdentifier_?Blockly.Touch.touchIdentifier_==b:"mousedown"==a.type||"touchstart"==a.type?(Blockly.Touch.touchIdentifier_=b,!0):!1};Blockly.Touch.setClientFromTouch=function(a){if(goog.string.startsWith(a.type,"touch")){var b=a.changedTouches[0];a.clientX=b.clientX;a.clientY=b.clientY}};
                +Blockly.Touch.isMouseOrTouchEvent=function(a){return goog.string.startsWith(a.type,"touch")||goog.string.startsWith(a.type,"mouse")};Blockly.Touch.splitEventByTouches=function(a){var b=[];if(a.changedTouches)for(var c=0;c<a.changedTouches.length;c++)b[c]={type:a.type,changedTouches:[a.changedTouches[c]],target:a.target,stopPropagation:function(){a.stopPropagation()},preventDefault:function(){a.preventDefault()}};else b.push(a);return b};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2017 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.VariableMap=function(a){this.variableMap_={};this.workspace=a};Blockly.VariableMap.prototype.clear=function(){this.variableMap_=Object(null)};
                +Blockly.VariableMap.prototype.renameVariable=function(a,b){var c=this.getVariable(b),d=-1,e=-1,f="";if(a||c)f=(a||c).type;var g=this.getVariablesOfType(f);a&&(d=g.indexOf(a));c&&(e=g.indexOf(c));-1==d&&-1==e?(this.createVariable(b,""),console.log("Tried to rename an non-existent variable.")):d==e||-1!=d&&-1==e?(a=this.variableMap_[f][d],Blockly.Events.fire(new Blockly.Events.VarRename(a,b)),a.name=b):-1!=d&&-1!=e&&(a=this.variableMap_[f][e],Blockly.Events.fire(new Blockly.Events.VarRename(a,b)),Blockly.Events.fire(new Blockly.Events.VarDelete(this.variableMap_[f][d])),
                +a.name=b,this.variableMap_[f].splice(d,1))};
                +Blockly.VariableMap.prototype.createVariable=function(a,b,c){var d=this.getVariable(a);if(d){if(b&&d.type!=b)throw Error('Variable "'+a+'" is already in use and its type is "'+d.type+'" which conflicts with the passed in type, "'+b+'".');if(c&&d.getId()!=c)throw Error('Variable "'+a+'" is already in use and its id is "'+d.getId()+'" which conflicts with the passed in id, "'+c+'".');return d}if(c&&this.getVariableById(c))throw Error('Variable id, "'+c+'", is already in use.');c=c||Blockly.utils.genUid();
                +b=b||"";d=new Blockly.VariableModel(this.workspace,a,b,c);this.variableMap_[b]?this.variableMap_[b].push(d):this.variableMap_[b]=[d];return d};Blockly.VariableMap.prototype.deleteVariable=function(a){for(var b=this.variableMap_[a.type],c=0,d;d=b[c];c++)if(d.getId()==a.getId()){b.splice(c,1);Blockly.Events.fire(new Blockly.Events.VarDelete(a));break}};
                +Blockly.VariableMap.prototype.getVariable=function(a){for(var b=Object.keys(this.variableMap_),c=0;c<b.length;c++)for(var d=b[c],e=0,f;f=this.variableMap_[d][e];e++)if(Blockly.Names.equals(f.name,a))return f;return null};Blockly.VariableMap.prototype.getVariableById=function(a){for(var b=Object.keys(this.variableMap_),c=0;c<b.length;c++)for(var d=b[c],e=0,f;f=this.variableMap_[d][e];e++)if(f.getId()==a)return f;return null};
                +Blockly.VariableMap.prototype.getVariablesOfType=function(a){return(a=this.variableMap_[a||""])?a.slice():[]};Blockly.VariableMap.prototype.getVariableTypes=function(){return Object.keys(this.variableMap_)};Blockly.VariableMap.prototype.getAllVariables=function(){for(var a=[],b=Object.keys(this.variableMap_),c=0;c<b.length;c++)a=a.concat(this.variableMap_[b[c]]);return a};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2012 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Workspace=function(a){this.id=Blockly.utils.genUid();Blockly.Workspace.WorkspaceDB_[this.id]=this;this.options=a||{};this.RTL=!!this.options.RTL;this.horizontalLayout=!!this.options.horizontalLayout;this.toolboxPosition=this.options.toolboxPosition;this.topBlocks_=[];this.listeners_=[];this.undoStack_=[];this.redoStack_=[];this.blockDB_=Object.create(null);this.variableMap_=new Blockly.VariableMap(this)};Blockly.Workspace.prototype.rendered=!1;Blockly.Workspace.prototype.MAX_UNDO=1024;
                +Blockly.Workspace.prototype.dispose=function(){this.listeners_.length=0;this.clear();delete Blockly.Workspace.WorkspaceDB_[this.id]};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);if(this.isFlyout){a=Blockly.Variables.allUsedVariables(a);for(var b=0,c;c=a[b];b++)this.getVariable(c)||this.createVariable(c)}};
                +Blockly.Workspace.prototype.removeTopBlock=function(a){if(!goog.array.remove(this.topBlocks_,a))throw"Block not present in workspace's list of top-most blocks.";};Blockly.Workspace.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1<b.length){var c=Math.sin(goog.math.toRadians(Blockly.Workspace.SCAN_ANGLE));this.RTL&&(c*=-1);b.sort(function(a,b){a=a.getRelativeToSurfaceXY();b=b.getRelativeToSurfaceXY();return a.y+c*a.x-(b.y+c*b.x)})}return b};
                +Blockly.Workspace.prototype.getAllBlocks=function(){for(var a=this.getTopBlocks(!1),b=0;b<a.length;b++)a.push.apply(a,a[b].getChildren());return a};Blockly.Workspace.prototype.clear=function(){var a=Blockly.Events.getGroup();for(a||Blockly.Events.setGroup(!0);this.topBlocks_.length;)this.topBlocks_[0].dispose();a||Blockly.Events.setGroup(!1);this.variableMap_.clear()};
                +Blockly.Workspace.prototype.updateVariableStore=function(a){if(!this.isFlyout){for(var b=Blockly.Variables.allUsedVariables(this),c=[],d=0,e;e=b[d];d++){var f=this.getVariable(e);f?c.push({name:f.name,type:f.type,id:f.getId()}):c.push({name:e,type:null,id:null})}a&&this.variableMap_.clear();for(d=0;a=c[d];d++)this.getVariable(a.name)||this.createVariable(a.name,a.type,a.id)}};
                +Blockly.Workspace.prototype.renameVariableInternal_=function(a,b){var c=this.getVariable(b);if(a&&c&&a.type!=c.type)throw Error('Variable "'+a.name+'" is type "'+a.type+'" and variable "'+b+'" is type "'+c.type+'". Both must be the same type.');if(c&&c.name!=b)var d=c.name;Blockly.Events.setGroup(!0);for(var c=this.getAllBlocks(),e=0;e<c.length;e++)c[e].renameVar(a.name,b),d&&c[e].renameVar(d,b);this.variableMap_.renameVariable(a,b);Blockly.Events.setGroup(!1)};
                +Blockly.Workspace.prototype.renameVariable=function(a,b){a=this.getVariable(a);this.renameVariableInternal_(a,b)};Blockly.Workspace.prototype.renameVariableById=function(a,b){a=this.getVariableById(a);this.renameVariableInternal_(a,b)};Blockly.Workspace.prototype.createVariable=function(a,b,c){return this.variableMap_.createVariable(a,b,c)};
                +Blockly.Workspace.prototype.getVariableUses=function(a){for(var b=[],c=this.getAllBlocks(),d=0;d<c.length;d++){var e=c[d].getVars();if(e)for(var f=0;f<e.length;f++){var g=e[f];g&&a&&Blockly.Names.equals(g,a)&&b.push(c[d])}}return b};
                +Blockly.Workspace.prototype.deleteVariable=function(a){for(var b=this.getVariableUses(a),c=0,d;d=b[c];c++)if("procedures_defnoreturn"==d.type||"procedures_defreturn"==d.type){b=d.getFieldValue("NAME");Blockly.alert(Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE.replace("%1",a).replace("%2",b));return}var e=this,f=e.getVariable(a);1<b.length?Blockly.confirm(Blockly.Msg.DELETE_VARIABLE_CONFIRMATION.replace("%1",b.length).replace("%2",a),function(a){a&&e.deleteVariableInternal_(f)}):this.deleteVariableInternal_(f)};
                +Blockly.Workspace.prototype.deleteVariableById=function(a){var b=this.getVariableById(a);b?this.deleteVariableInternal_(b):console.warn("Can't delete non-existant variable: "+a)};Blockly.Workspace.prototype.deleteVariableInternal_=function(a){var b=this.getVariableUses(a.name);Blockly.Events.setGroup(!0);for(var c=0;c<b.length;c++)b[c].dispose(!0,!1);this.variableMap_.deleteVariable(a);Blockly.Events.setGroup(!1)};
                +Blockly.Workspace.prototype.variableIndexOf=function(a){console.warn("Deprecated call to Blockly.Workspace.prototype.variableIndexOf");return-1};Blockly.Workspace.prototype.getVariable=function(a){return this.variableMap_.getVariable(a)};Blockly.Workspace.prototype.getVariableById=function(a){return this.variableMap_.getVariableById(a)};Blockly.Workspace.prototype.getWidth=function(){return 0};Blockly.Workspace.prototype.newBlock=function(a,b){return new Blockly.Block(this,a,b)};
                +Blockly.Workspace.prototype.remainingCapacity=function(){return isNaN(this.options.maxBlocks)?Infinity:this.options.maxBlocks-this.getAllBlocks().length};
                +Blockly.Workspace.prototype.undo=function(a){var b=a?this.redoStack_:this.undoStack_,c=a?this.undoStack_:this.redoStack_,d=b.pop();if(d){for(var e=[d];b.length&&d.group&&d.group==b[b.length-1].group;)e.push(b.pop());for(b=0;d=e[b];b++)c.push(d);e=Blockly.Events.filter(e,a);Blockly.Events.recordUndo=!1;try{for(b=0;d=e[b];b++)d.run(a)}finally{Blockly.Events.recordUndo=!0}}};Blockly.Workspace.prototype.clearUndo=function(){this.undoStack_.length=0;this.redoStack_.length=0;Blockly.Events.clearPendingUndo()};
                +Blockly.Workspace.prototype.addChangeListener=function(a){this.listeners_.push(a);return a};Blockly.Workspace.prototype.removeChangeListener=function(a){goog.array.remove(this.listeners_,a)};Blockly.Workspace.prototype.fireChangeListener=function(a){a.recordUndo&&(this.undoStack_.push(a),this.redoStack_.length=0,this.undoStack_.length>this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};
                +Blockly.Workspace.prototype.getBlockById=function(a){return this.blockDB_[a]||null};Blockly.Workspace.prototype.allInputsFilled=function(a){for(var b=this.getTopBlocks(!1),c=0,d;d=b[c];c++)if(!d.allInputsFilled(a))return!1;return!0};Blockly.Workspace.prototype.getVariablesOfType=function(a){return this.variableMap_.getVariablesOfType(a)};Blockly.Workspace.prototype.getVariableTypes=function(){return this.variableMap_.getVariableTypes()};Blockly.Workspace.prototype.getAllVariables=function(){return this.variableMap_.getAllVariables()};
                +Blockly.Workspace.WorkspaceDB_=Object.create(null);Blockly.Workspace.getById=function(a){return Blockly.Workspace.WorkspaceDB_[a]||null};Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear;Blockly.Workspace.prototype.clearUndo=Blockly.Workspace.prototype.clearUndo;Blockly.Workspace.prototype.addChangeListener=Blockly.Workspace.prototype.addChangeListener;Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!e||!f)));this.setAnchorLocation(d);e&&f||(b=this.content_.getBBox(),e=b.width+2*Blockly.Bubble.BORDER_WIDTH,f=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(e,f);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEventWithChecks_(this.bubbleBack_,
                +"mousedown",this,this.bubbleMouseDown_),this.resizeGroup_&&Blockly.bindEventWithChecks_(this.resizeGroup_,"mousedown",this,this.resizeMouseDown_))};Blockly.Bubble.BORDER_WIDTH=6;Blockly.Bubble.ARROW_THICKNESS=5;Blockly.Bubble.ARROW_ANGLE=20;Blockly.Bubble.ARROW_BEND=4;Blockly.Bubble.ANCHOR_RADIUS=8;Blockly.Bubble.onMouseUpWrapper_=null;Blockly.Bubble.onMouseMoveWrapper_=null;Blockly.Bubble.prototype.resizeCallback_=null;
                +Blockly.Bubble.unbindDragEvents_=function(){Blockly.Bubble.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_),Blockly.Bubble.onMouseUpWrapper_=null);Blockly.Bubble.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_),Blockly.Bubble.onMouseMoveWrapper_=null)};Blockly.Bubble.bubbleMouseUp_=function(){Blockly.Touch.clearTouchIdentifier();Blockly.Bubble.unbindDragEvents_()};Blockly.Bubble.prototype.rendered_=!1;Blockly.Bubble.prototype.anchorXY_=null;
                +Blockly.Bubble.prototype.relativeLeft_=0;Blockly.Bubble.prototype.relativeTop_=0;Blockly.Bubble.prototype.width_=0;Blockly.Bubble.prototype.height_=0;Blockly.Bubble.prototype.autoLayout_=!0;
                +Blockly.Bubble.prototype.createDom_=function(a,b){this.bubbleGroup_=Blockly.utils.createSvgElement("g",{},null);var c={filter:"url(#"+this.workspace_.options.embossFilterId+")"};-1!=goog.userAgent.getUserAgentString().indexOf("JavaFX")&&(c={});c=Blockly.utils.createSvgElement("g",c,this.bubbleGroup_);this.bubbleArrow_=Blockly.utils.createSvgElement("path",{},c);this.bubbleBack_=Blockly.utils.createSvgElement("rect",{"class":"blocklyDraggable",x:0,y:0,rx:Blockly.Bubble.BORDER_WIDTH,ry:Blockly.Bubble.BORDER_WIDTH},
                +c);b?(this.resizeGroup_=Blockly.utils.createSvgElement("g",{"class":this.workspace_.RTL?"blocklyResizeSW":"blocklyResizeSE"},this.bubbleGroup_),b=2*Blockly.Bubble.BORDER_WIDTH,Blockly.utils.createSvgElement("polygon",{points:"0,x x,x x,0".replace(/x/g,b.toString())},this.resizeGroup_),Blockly.utils.createSvgElement("line",{"class":"blocklyResizeLine",x1:b/3,y1:b-1,x2:b-1,y2:b/3},this.resizeGroup_),Blockly.utils.createSvgElement("line",{"class":"blocklyResizeLine",x1:2*b/3,y1:b-1,x2:b-1,y2:2*b/3},
                +this.resizeGroup_)):this.resizeGroup_=null;this.bubbleGroup_.appendChild(a);return this.bubbleGroup_};
                +Blockly.Bubble.prototype.bubbleMouseDown_=function(a){this.promote_();Blockly.Bubble.unbindDragEvents_();Blockly.utils.isRightButton(a)?a.stopPropagation():Blockly.utils.isTargetInput(a)||(this.workspace_.startDrag(a,new goog.math.Coordinate(this.workspace_.RTL?-this.relativeLeft_:this.relativeLeft_,this.relativeTop_)),Blockly.Bubble.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,Blockly.Bubble.bubbleMouseUp_),Blockly.Bubble.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,
                +"mousemove",this,this.bubbleMouseMove_),Blockly.hideChaff(),a.stopPropagation())};Blockly.Bubble.prototype.bubbleMouseMove_=function(a){this.autoLayout_=!1;a=this.workspace_.moveDrag(a);this.relativeLeft_=this.workspace_.RTL?-a.x:a.x;this.relativeTop_=a.y;this.positionBubble_();this.renderArrow_()};
                +Blockly.Bubble.prototype.resizeMouseDown_=function(a){this.promote_();Blockly.Bubble.unbindDragEvents_();Blockly.utils.isRightButton(a)||(this.workspace_.startDrag(a,new goog.math.Coordinate(this.workspace_.RTL?-this.width_:this.width_,this.height_)),Blockly.Bubble.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,Blockly.Bubble.bubbleMouseUp_),Blockly.Bubble.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",this,this.resizeMouseMove_),Blockly.hideChaff());
                +a.stopPropagation()};Blockly.Bubble.prototype.resizeMouseMove_=function(a){this.autoLayout_=!1;a=this.workspace_.moveDrag(a);this.setBubbleSize(this.workspace_.RTL?-a.x:a.x,a.y);this.workspace_.RTL&&this.positionBubble_()};Blockly.Bubble.prototype.registerResizeEvent=function(a){this.resizeCallback_=a};Blockly.Bubble.prototype.promote_=function(){this.bubbleGroup_.parentNode.appendChild(this.bubbleGroup_)};Blockly.Bubble.prototype.setAnchorLocation=function(a){this.anchorXY_=a;this.rendered_&&this.positionBubble_()};
                +Blockly.Bubble.prototype.layoutBubble_=function(){var a=-this.width_/4,b=-this.height_-Blockly.BlockSvg.MIN_BLOCK_Y,c=this.workspace_.getMetrics();c.viewWidth/=this.workspace_.scale;c.viewLeft/=this.workspace_.scale;var d=this.anchorXY_.x;this.workspace_.RTL?d-c.viewLeft-a-this.width_<Blockly.Scrollbar.scrollbarThickness?a=d-c.viewLeft-this.width_-Blockly.Scrollbar.scrollbarThickness:d-c.viewLeft-a>c.viewWidth&&(a=d-c.viewLeft-c.viewWidth):d+a<c.viewLeft?a=c.viewLeft-d:c.viewLeft+c.viewWidth<d+a+
                +this.width_+Blockly.BlockSvg.SEP_SPACE_X+Blockly.Scrollbar.scrollbarThickness&&(a=c.viewLeft+c.viewWidth-d-this.width_-Blockly.Scrollbar.scrollbarThickness);this.anchorXY_.y+b<c.viewTop&&(b=this.shape_.getBBox().height);this.relativeLeft_=a;this.relativeTop_=b};
                +Blockly.Bubble.prototype.positionBubble_=function(){var a=this.anchorXY_.x,a=this.workspace_.RTL?a-(this.relativeLeft_+this.width_):a+this.relativeLeft_;this.bubbleGroup_.setAttribute("transform","translate("+a+","+(this.relativeTop_+this.anchorXY_.y)+")")};Blockly.Bubble.prototype.getBubbleSize=function(){return{width:this.width_,height:this.height_}};
                +Blockly.Bubble.prototype.setBubbleSize=function(a,b){var c=2*Blockly.Bubble.BORDER_WIDTH;a=Math.max(a,c+45);b=Math.max(b,c+20);this.width_=a;this.height_=b;this.bubbleBack_.setAttribute("width",a);this.bubbleBack_.setAttribute("height",b);this.resizeGroup_&&(this.workspace_.RTL?this.resizeGroup_.setAttribute("transform","translate("+2*Blockly.Bubble.BORDER_WIDTH+","+(b-c)+") scale(-1 1)"):this.resizeGroup_.setAttribute("transform","translate("+(a-c)+","+(b-c)+")"));this.rendered_&&(this.autoLayout_&&
                +this.layoutBubble_(),this.positionBubble_(),this.renderArrow_());this.resizeCallback_&&this.resizeCallback_()};
                +Blockly.Bubble.prototype.renderArrow_=function(){var a=[],b=this.width_/2,c=this.height_/2,d=-this.relativeLeft_,e=-this.relativeTop_;if(b==d&&c==e)a.push("M "+b+","+c);else{e-=c;d-=b;this.workspace_.RTL&&(d*=-1);var f=Math.sqrt(e*e+d*d),g=Math.acos(d/f);0>e&&(g=2*Math.PI-g);var h=g+Math.PI/2;h>2*Math.PI&&(h-=2*Math.PI);var k=Math.sin(h),l=Math.cos(h),m=this.getBubbleSize(),h=(m.width+m.height)/Blockly.Bubble.ARROW_THICKNESS,h=Math.min(h,m.width,m.height)/4,m=1-Blockly.Bubble.ANCHOR_RADIUS/f,d=b+
                +m*d,e=c+m*e,m=b+h*l,n=c+h*k,b=b-h*l,c=c-h*k,k=g+this.arrow_radians_;k>2*Math.PI&&(k-=2*Math.PI);g=Math.sin(k)*f/Blockly.Bubble.ARROW_BEND;f=Math.cos(k)*f/Blockly.Bubble.ARROW_BEND;a.push("M"+m+","+n);a.push("C"+(m+f)+","+(n+g)+" "+d+","+e+" "+d+","+e);a.push("C"+d+","+e+" "+(b+f)+","+(c+g)+" "+b+","+c)}a.push("z");this.bubbleArrow_.setAttribute("d",a.join(" "))};Blockly.Bubble.prototype.setColour=function(a){this.bubbleBack_.setAttribute("fill",a);this.bubbleArrow_.setAttribute("fill",a)};
                +Blockly.Bubble.prototype.dispose=function(){Blockly.Bubble.unbindDragEvents_();goog.dom.removeNode(this.bubbleGroup_);this.shape_=this.content_=this.workspace_=this.resizeGroup_=this.bubbleBack_=this.bubbleArrow_=this.bubbleGroup_=null};Blockly.Icon=function(a){this.block_=a};Blockly.Icon.prototype.collapseHidden=!0;Blockly.Icon.prototype.SIZE=17;Blockly.Icon.prototype.bubble_=null;Blockly.Icon.prototype.iconXY_=null;
                +Blockly.Icon.prototype.createIcon=function(){this.iconGroup_||(this.iconGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyIconGroup"},null),this.block_.isInFlyout&&Blockly.utils.addClass(this.iconGroup_,"blocklyIconGroupReadonly"),this.drawIcon_(this.iconGroup_),this.block_.getSvgRoot().appendChild(this.iconGroup_),Blockly.bindEventWithChecks_(this.iconGroup_,"mouseup",this,this.iconClick_),this.updateEditable())};
                +Blockly.Icon.prototype.dispose=function(){goog.dom.removeNode(this.iconGroup_);this.iconGroup_=null;this.setVisible(!1);this.block_=null};Blockly.Icon.prototype.updateEditable=function(){};Blockly.Icon.prototype.isVisible=function(){return!!this.bubble_};Blockly.Icon.prototype.iconClick_=function(a){this.block_.workspace.isDragging()||this.block_.isInFlyout||Blockly.utils.isRightButton(a)||this.setVisible(!this.isVisible())};Blockly.Icon.prototype.updateColour=function(){this.isVisible()&&this.bubble_.setColour(this.block_.getColour())};
                +Blockly.Icon.prototype.renderIcon=function(a){if(this.collapseHidden&&this.block_.isCollapsed())return this.iconGroup_.setAttribute("display","none"),a;this.iconGroup_.setAttribute("display","block");var b=this.SIZE;this.block_.RTL&&(a-=b);this.iconGroup_.setAttribute("transform","translate("+a+",5)");this.computeIconLocation();return a=this.block_.RTL?a-Blockly.BlockSvg.SEP_SPACE_X:a+(b+Blockly.BlockSvg.SEP_SPACE_X)};
                +Blockly.Icon.prototype.setIconLocation=function(a){this.iconXY_=a;this.isVisible()&&this.bubble_.setAnchorLocation(a)};Blockly.Icon.prototype.computeIconLocation=function(){var a=this.block_.getRelativeToSurfaceXY(),b=Blockly.utils.getRelativeXY(this.iconGroup_),a=new goog.math.Coordinate(a.x+b.x+this.SIZE/2,a.y+b.y+this.SIZE/2);goog.math.Coordinate.equals(this.getIconLocation(),a)||this.setIconLocation(a)};Blockly.Icon.prototype.getIconLocation=function(){return this.iconXY_};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2011 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Comment=function(a){Blockly.Comment.superClass_.constructor.call(this,a);this.createIcon()};goog.inherits(Blockly.Comment,Blockly.Icon);Blockly.Comment.prototype.text_="";Blockly.Comment.prototype.width_=160;Blockly.Comment.prototype.height_=80;
                +Blockly.Comment.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("circle",{"class":"blocklyIconShape",r:"8",cx:"8",cy:"8"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405 0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25 -1.201,0.998 -1.201,1.528 -1.204,2.19z"},a);Blockly.utils.createSvgElement("rect",{"class":"blocklyIconSymbol",x:"6.8",y:"10.78",height:"2",width:"2"},a)};
                +Blockly.Comment.prototype.createEditor_=function(){this.foreignObject_=Blockly.utils.createSvgElement("foreignObject",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);var a=document.createElementNS(Blockly.HTML_NS,"body");a.setAttribute("xmlns",Blockly.HTML_NS);a.className="blocklyMinimalBody";var b=document.createElementNS(Blockly.HTML_NS,"textarea");b.className="blocklyCommentTextarea";b.setAttribute("dir",this.block_.RTL?"RTL":"LTR");a.appendChild(b);this.textarea_=b;this.foreignObject_.appendChild(a);
                +Blockly.bindEventWithChecks_(b,"mouseup",this,this.textareaFocus_);Blockly.bindEventWithChecks_(b,"wheel",this,function(a){a.stopPropagation()});Blockly.bindEventWithChecks_(b,"change",this,function(a){this.text_!=b.value&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this.block_,"comment",null,this.text_,b.value)),this.text_=b.value)});setTimeout(function(){b.focus()},0);return this.foreignObject_};
                +Blockly.Comment.prototype.updateEditable=function(){this.isVisible()&&(this.setVisible(!1),this.setVisible(!0));Blockly.Icon.prototype.updateEditable.call(this)};Blockly.Comment.prototype.resizeBubble_=function(){if(this.isVisible()){var a=this.bubble_.getBubbleSize(),b=2*Blockly.Bubble.BORDER_WIDTH;this.foreignObject_.setAttribute("width",a.width-b);this.foreignObject_.setAttribute("height",a.height-b);this.textarea_.style.width=a.width-b-4+"px";this.textarea_.style.height=a.height-b-4+"px"}};
                +Blockly.Comment.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"commentOpen",!a,a)),!this.block_.isEditable()&&!this.textarea_||goog.userAgent.IE)Blockly.Warning.prototype.setVisible.call(this,a);else{var b=this.getText(),c=this.getBubbleSize();a?(this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svgPath_,this.iconXY_,this.width_,this.height_),this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this)),
                +this.updateColour()):(this.bubble_.dispose(),this.foreignObject_=this.textarea_=this.bubble_=null);this.setText(b);this.setBubbleSize(c.width,c.height)}};Blockly.Comment.prototype.textareaFocus_=function(a){this.bubble_.promote_();this.textarea_.focus()};Blockly.Comment.prototype.getBubbleSize=function(){return this.isVisible()?this.bubble_.getBubbleSize():{width:this.width_,height:this.height_}};
                +Blockly.Comment.prototype.setBubbleSize=function(a,b){this.textarea_?this.bubble_.setBubbleSize(a,b):(this.width_=a,this.height_=b)};Blockly.Comment.prototype.getText=function(){return this.textarea_?this.textarea_.value:this.text_};Blockly.Comment.prototype.setText=function(a){this.text_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this.block_,"comment",null,this.text_,a)),this.text_=a);this.textarea_&&(this.textarea_.value=a)};
                +Blockly.Comment.prototype.dispose=function(){Blockly.Events.isEnabled()&&this.setText("");this.block_.comment=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Connection=function(a,b){this.sourceBlock_=a;this.type=b;a.workspace.connectionDBList&&(this.db_=a.workspace.connectionDBList[b],this.dbOpposite_=a.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[b]],this.hidden_=!this.db_)};Blockly.Connection.CAN_CONNECT=0;Blockly.Connection.REASON_SELF_CONNECTION=1;Blockly.Connection.REASON_WRONG_TYPE=2;Blockly.Connection.REASON_TARGET_NULL=3;Blockly.Connection.REASON_CHECKS_FAILED=4;Blockly.Connection.REASON_DIFFERENT_WORKSPACES=5;
                +Blockly.Connection.REASON_SHADOW_PARENT=6;Blockly.Connection.prototype.targetConnection=null;Blockly.Connection.prototype.check_=null;Blockly.Connection.prototype.shadowDom_=null;Blockly.Connection.prototype.x_=0;Blockly.Connection.prototype.y_=0;Blockly.Connection.prototype.inDB_=!1;Blockly.Connection.prototype.db_=null;Blockly.Connection.prototype.dbOpposite_=null;Blockly.Connection.prototype.hidden_=null;
                +Blockly.Connection.prototype.connect_=function(a){var b=this,c=b.getSourceBlock(),d=a.getSourceBlock();a.isConnected()&&a.disconnect();if(b.isConnected()){var e=b.targetBlock(),f=b.getShadowDom();b.setShadowDom(null);if(e.isShadow())f=Blockly.Xml.blockToDom(e),e.dispose(),e=null;else if(b.type==Blockly.INPUT_VALUE){if(!e.outputConnection)throw"Orphan block does not have an output connection.";var g=Blockly.Connection.lastConnectionInRow_(d,e);g&&(e.outputConnection.connect(g),e=null)}else if(b.type==
                +Blockly.NEXT_STATEMENT){if(!e.previousConnection)throw"Orphan block does not have a previous connection.";for(g=d;g.nextConnection;){var h=g.getNextBlock();if(h&&!h.isShadow())g=h;else{e.previousConnection.checkType_(g.nextConnection)&&(g.nextConnection.connect(e.previousConnection),e=null);break}}}if(e&&(b.disconnect(),Blockly.Events.recordUndo)){var k=Blockly.Events.getGroup();setTimeout(function(){e.workspace&&!e.getParent()&&(Blockly.Events.setGroup(k),e.outputConnection?e.outputConnection.bumpAwayFrom_(b):
                +e.previousConnection&&e.previousConnection.bumpAwayFrom_(b),Blockly.Events.setGroup(!1))},Blockly.BUMP_DELAY)}b.setShadowDom(f)}var l;Blockly.Events.isEnabled()&&(l=new Blockly.Events.BlockMove(d));Blockly.Connection.connectReciprocally_(b,a);d.setParent(c);l&&(l.recordNew(),Blockly.Events.fire(l))};Blockly.Connection.prototype.dispose=function(){if(this.isConnected())throw"Disconnect connection before disposing of it.";this.inDB_&&this.db_.removeConnection_(this);this.dbOpposite_=this.db_=null};
                +Blockly.Connection.prototype.getSourceBlock=function(){return this.sourceBlock_};Blockly.Connection.prototype.isSuperior=function(){return this.type==Blockly.INPUT_VALUE||this.type==Blockly.NEXT_STATEMENT};Blockly.Connection.prototype.isConnected=function(){return!!this.targetConnection};
                +Blockly.Connection.prototype.canConnectWithReason_=function(a){if(!a)return Blockly.Connection.REASON_TARGET_NULL;if(this.isSuperior()){var b=this.sourceBlock_;var c=a.getSourceBlock()}else c=this.sourceBlock_,b=a.getSourceBlock();return b&&b==c?Blockly.Connection.REASON_SELF_CONNECTION:a.type!=Blockly.OPPOSITE_TYPE[this.type]?Blockly.Connection.REASON_WRONG_TYPE:b&&c&&b.workspace!==c.workspace?Blockly.Connection.REASON_DIFFERENT_WORKSPACES:this.checkType_(a)?b.isShadow()&&!c.isShadow()?Blockly.Connection.REASON_SHADOW_PARENT:
                +Blockly.Connection.CAN_CONNECT:Blockly.Connection.REASON_CHECKS_FAILED};
                +Blockly.Connection.prototype.checkConnection_=function(a){switch(this.canConnectWithReason_(a)){case Blockly.Connection.CAN_CONNECT:break;case Blockly.Connection.REASON_SELF_CONNECTION:throw"Attempted to connect a block to itself.";case Blockly.Connection.REASON_DIFFERENT_WORKSPACES:throw"Blocks not on same workspace.";case Blockly.Connection.REASON_WRONG_TYPE:throw"Attempt to connect incompatible types.";case Blockly.Connection.REASON_TARGET_NULL:throw"Target connection is null.";case Blockly.Connection.REASON_CHECKS_FAILED:throw"Connection checks failed. "+
                +(this+" expected "+this.check_+", found "+a.check_);case Blockly.Connection.REASON_SHADOW_PARENT:throw"Connecting non-shadow to shadow block.";default:throw"Unknown connection failure: this should never happen!";}};
                +Blockly.Connection.prototype.isConnectionAllowed=function(a){if(this.canConnectWithReason_(a)!=Blockly.Connection.CAN_CONNECT)return!1;if(a.type==Blockly.OUTPUT_VALUE||a.type==Blockly.PREVIOUS_STATEMENT)if(a.isConnected()||this.isConnected())return!1;return a.type==Blockly.INPUT_VALUE&&a.isConnected()&&!a.targetBlock().isMovable()&&!a.targetBlock().isShadow()||this.type==Blockly.PREVIOUS_STATEMENT&&a.isConnected()&&!this.sourceBlock_.nextConnection&&!a.targetBlock().isShadow()&&a.targetBlock().nextConnection||
                +-1!=Blockly.draggingConnections_.indexOf(a)?!1:!0};Blockly.Connection.prototype.connect=function(a){this.targetConnection!=a&&(this.checkConnection_(a),this.isSuperior()?this.connect_(a):a.connect_(this))};Blockly.Connection.connectReciprocally_=function(a,b){goog.asserts.assert(a&&b,"Cannot connect null connections.");a.targetConnection=b;b.targetConnection=a};
                +Blockly.Connection.singleConnection_=function(a,b){for(var c=!1,d=0;d<a.inputList.length;d++){var e=a.inputList[d].connection;if(e&&e.type==Blockly.INPUT_VALUE&&b.outputConnection.checkType_(e)){if(c)return null;c=e}}return c};Blockly.Connection.lastConnectionInRow_=function(a,b){for(var c;c=Blockly.Connection.singleConnection_(a,b);)if(a=c.targetBlock(),!a||a.isShadow())return c;return null};
                +Blockly.Connection.prototype.disconnect=function(){var a=this.targetConnection;goog.asserts.assert(a,"Source connection not connected.");goog.asserts.assert(a.targetConnection==this,"Target connection not connected to source connection.");if(this.isSuperior()){var b=this.sourceBlock_;var c=a.getSourceBlock();a=this}else b=a.getSourceBlock(),c=this.sourceBlock_;this.disconnectInternal_(b,c);a.respawnShadow_()};
                +Blockly.Connection.prototype.disconnectInternal_=function(a,b){var c;Blockly.Events.isEnabled()&&(c=new Blockly.Events.BlockMove(b));this.targetConnection=this.targetConnection.targetConnection=null;b.setParent(null);c&&(c.recordNew(),Blockly.Events.fire(c))};
                +Blockly.Connection.prototype.respawnShadow_=function(){var a=this.getSourceBlock(),b=this.getShadowDom();if(a.workspace&&b&&Blockly.Events.recordUndo)if(a=Blockly.Xml.domToBlock(b,a.workspace),a.outputConnection)this.connect(a.outputConnection);else if(a.previousConnection)this.connect(a.previousConnection);else throw"Child block does not have output or previous statement.";};Blockly.Connection.prototype.targetBlock=function(){return this.isConnected()?this.targetConnection.getSourceBlock():null};
                +Blockly.Connection.prototype.checkType_=function(a){if(!this.check_||!a.check_)return!0;for(var b=0;b<this.check_.length;b++)if(-1!=a.check_.indexOf(this.check_[b]))return!0;return!1};Blockly.Connection.prototype.onCheckChanged_=function(){this.isConnected()&&!this.checkType_(this.targetConnection)&&(this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug()};
                +Blockly.Connection.prototype.setCheck=function(a){a?(goog.isArray(a)||(a=[a]),this.check_=a,this.onCheckChanged_()):this.check_=null;return this};Blockly.Connection.prototype.setShadowDom=function(a){this.shadowDom_=a};Blockly.Connection.prototype.getShadowDom=function(){return this.shadowDom_};Blockly.Connection.prototype.neighbours_=function(){return[]};
                +Blockly.Connection.prototype.toString=function(){var a=this.sourceBlock_;if(a)if(a.outputConnection==this)var b="Output Connection of ";else if(a.previousConnection==this)b="Previous Connection of ";else if(a.nextConnection==this)b="Next Connection of ";else if(b=goog.array.find(a.inputList,function(a){return a.connection==this},this))b='Input "'+b.name+'" connection on ';else return console.warn("Connection not actually connected to sourceBlock_"),"Orphan Connection";else return"Orphan Connection";
                +return b+a.toDevString()};Blockly.Extensions={};Blockly.Extensions.ALL_={};Blockly.Extensions.MUTATOR_PROPERTIES_=["domToMutation","mutationToDom","compose","decompose"];Blockly.Extensions.register=function(a,b){if(!goog.isString(a)||goog.string.isEmptyOrWhitespace(a))throw Error('Error: Invalid extension name "'+a+'"');if(Blockly.Extensions.ALL_[a])throw Error('Error: Extension "'+a+'" is already registered.');if(!goog.isFunction(b))throw Error('Error: Extension "'+a+'" must be a function');Blockly.Extensions.ALL_[a]=b};
                +Blockly.Extensions.registerMixin=function(a,b){Blockly.Extensions.register(a,function(){this.mixin(b)})};
                +Blockly.Extensions.registerMutator=function(a,b,c,d){var e='Error when registering mutator "'+a+'": ';Blockly.Extensions.checkHasFunction_(e,b.domToMutation,"domToMutation");Blockly.Extensions.checkHasFunction_(e,b.mutationToDom,"mutationToDom");var f=Blockly.Extensions.checkMutatorDialog_(b,e);if(c&&!goog.isFunction(c))throw Error('Extension "'+a+'" is not a function');Blockly.Extensions.register(a,function(){f&&this.setMutator(new Blockly.Mutator(d));this.mixin(b);c&&c.apply(this)})};
                +Blockly.Extensions.apply=function(a,b,c){var d,e=Blockly.Extensions.ALL_[a];if(!goog.isFunction(e))throw Error('Error: Extension "'+a+'" not found.');c?Blockly.Extensions.checkNoMutatorProperties_(a,b):d=Blockly.Extensions.getMutatorProperties_(b);e.apply(b);if(c)Blockly.Extensions.checkBlockHasMutatorProperties_(a,b,'Error after applying mutator "'+a+'": ');else if(!Blockly.Extensions.mutatorPropertiesMatch_(d,b))throw Error('Error when applying extension "'+a+'": mutation properties changed when applying a non-mutator extension.');
                +};Blockly.Extensions.checkHasFunction_=function(a,b,c){if(!b)throw Error(a+'missing required property "'+c+'"');if("function"!=typeof b)throw Error(a+'" required property "'+c+'" must be a function');};
                +Blockly.Extensions.checkNoMutatorProperties_=function(a,b){for(var c=0;c<Blockly.Extensions.MUTATOR_PROPERTIES_.length;c++){var d=Blockly.Extensions.MUTATOR_PROPERTIES_[c];if(b.hasOwnProperty(d))throw Error('Error: tried to apply mutation "'+a+'" to a block that already has a "'+d+'" function.  Block id: '+b.id);}};
                +Blockly.Extensions.checkMutatorDialog_=function(a,b){var c=a.hasOwnProperty("compose"),d=a.hasOwnProperty("decompose");if(c&&d){if("function"!==typeof a.compose)throw Error(b+"compose must be a function.");if("function"!==typeof a.decompose)throw Error(b+"decompose must be a function.");return!0}if(c||d)throw Error(b+'Must have both or neither of "compose" and "decompose"');return!1};
                +Blockly.Extensions.checkBlockHasMutatorProperties_=function(a,b){if(!b.hasOwnProperty("domToMutation"))throw Error(a+'Applying a mutator didn\'t add "domToMutation"');if(!b.hasOwnProperty("mutationToDom"))throw Error(a+'Applying a mutator didn\'t add "mutationToDom"');Blockly.Extensions.checkMutatorDialog_(b,a)};Blockly.Extensions.getMutatorProperties_=function(a){for(var b=[],c=0;c<Blockly.Extensions.MUTATOR_PROPERTIES_.length;c++)b.push(a[Blockly.Extensions.MUTATOR_PROPERTIES_[c]]);return b};
                +Blockly.Extensions.mutatorPropertiesMatch_=function(a,b){var c=!0;b=Blockly.Extensions.getMutatorProperties_(b);if(b.length!=a.length)c=!1;else for(var d=0;d<b.length;d++)a[d]!=b[d]&&(c=!1);return c};
                +Blockly.Extensions.buildTooltipForDropdown=function(a,b){var c=[];document&&Blockly.utils.runAfterPageLoad(function(){for(var a in b)Blockly.utils.checkMessageReferences(b[a])});return function(){this.type&&-1===c.indexOf(this.type)&&(Blockly.Extensions.checkDropdownOptionsInTable_(this,a,b),c.push(this.type));this.setTooltip(function(){var d=this.getFieldValue(a),e=b[d];null==e?-1===c.indexOf(this.type)&&(d="No tooltip mapping for value "+d+" of field "+a,null!=this.type&&(d+=" of block type "+this.type),
                +console.warn(d+".")):e=Blockly.utils.replaceMessageReferences(e);return e}.bind(this))}};Blockly.Extensions.checkDropdownOptionsInTable_=function(a,b,c){var d=a.getField(b);if(!d.isOptionListDynamic())for(var d=d.getOptions(),e=0;e<d.length;++e){var f=d[e][1];null==c[f]&&console.warn("No tooltip mapping for value "+f+" of field "+b+" of block type "+a.type)}};
                +Blockly.Extensions.buildTooltipWithFieldValue=function(a,b){document&&Blockly.utils.runAfterPageLoad(function(){Blockly.utils.checkMessageReferences(a)});return function(){this.setTooltip(function(){return Blockly.utils.replaceMessageReferences(a).replace("%1",this.getFieldValue(b))}.bind(this))}};Blockly.Extensions.extensionParentTooltip_=function(){this.tooltipWhenNotConnected_=this.tooltip;this.setTooltip(function(){var a=this.getParent();return a&&a.getInputsInline()&&a.tooltip||this.tooltipWhenNotConnected_}.bind(this))};
                +Blockly.Extensions.register("parent_tooltip_when_inline",Blockly.Extensions.extensionParentTooltip_);Blockly.RenderedConnection=function(a,b){Blockly.RenderedConnection.superClass_.constructor.call(this,a,b);this.offsetInBlock_=new goog.math.Coordinate(0,0)};goog.inherits(Blockly.RenderedConnection,Blockly.Connection);Blockly.RenderedConnection.prototype.distanceFrom=function(a){var b=this.x_-a.x_;a=this.y_-a.y_;return Math.sqrt(b*b+a*a)};
                +Blockly.RenderedConnection.prototype.bumpAwayFrom_=function(a){if(!this.sourceBlock_.workspace.isDragging()){var b=this.sourceBlock_.getRootBlock();if(!b.isInFlyout){var c=!1;if(!b.isMovable()){b=a.getSourceBlock().getRootBlock();if(!b.isMovable())return;a=this;c=!0}var d=Blockly.selected==b;d||b.addSelect();var e=a.x_+Blockly.SNAP_RADIUS-this.x_;a=a.y_+Blockly.SNAP_RADIUS-this.y_;c&&(a=-a);b.RTL&&(e=-e);b.moveBy(e,a);d||b.removeSelect()}}};
                +Blockly.RenderedConnection.prototype.moveTo=function(a,b){this.inDB_&&this.db_.removeConnection_(this);this.x_=a;this.y_=b;this.hidden_||this.db_.addConnection(this)};Blockly.RenderedConnection.prototype.moveBy=function(a,b){this.moveTo(this.x_+a,this.y_+b)};Blockly.RenderedConnection.prototype.moveToOffset=function(a){this.moveTo(a.x+this.offsetInBlock_.x,a.y+this.offsetInBlock_.y)};
                +Blockly.RenderedConnection.prototype.setOffsetInBlock=function(a,b){this.offsetInBlock_.x=a;this.offsetInBlock_.y=b};Blockly.RenderedConnection.prototype.tighten_=function(){var a=this.targetConnection.x_-this.x_,b=this.targetConnection.y_-this.y_;if(0!=a||0!=b){var c=this.targetBlock(),d=c.getSvgRoot();if(!d)throw"block is not rendered.";d=Blockly.utils.getRelativeXY(d);c.getSvgRoot().setAttribute("transform","translate("+(d.x-a)+","+(d.y-b)+")");c.moveConnections_(-a,-b)}};
                +Blockly.RenderedConnection.prototype.closest=function(a,b,c){return this.dbOpposite_.searchForClosest(this,a,b,c)};
                +Blockly.RenderedConnection.prototype.highlight=function(){var a=this.type==Blockly.INPUT_VALUE||this.type==Blockly.OUTPUT_VALUE?"m 0,0 "+Blockly.BlockSvg.TAB_PATH_DOWN+" v 5":"m -20,0 h 5 "+Blockly.BlockSvg.NOTCH_PATH_LEFT+" h 5";var b=this.sourceBlock_.getRelativeToSurfaceXY();Blockly.Connection.highlightedPath_=Blockly.utils.createSvgElement("path",{"class":"blocklyHighlightedConnectionPath",d:a,transform:"translate("+(this.x_-b.x)+","+(this.y_-b.y)+")"+(this.sourceBlock_.RTL?" scale(-1 1)":"")},
                +this.sourceBlock_.getSvgRoot())};
                +Blockly.RenderedConnection.prototype.unhideAll=function(){this.setHidden(!1);var a=[];if(this.type!=Blockly.INPUT_VALUE&&this.type!=Blockly.NEXT_STATEMENT)return a;var b=this.targetBlock();if(b){if(b.isCollapsed()){var c=[];b.outputConnection&&c.push(b.outputConnection);b.nextConnection&&c.push(b.nextConnection);b.previousConnection&&c.push(b.previousConnection)}else c=b.getConnections_(!0);for(var d=0;d<c.length;d++)a.push.apply(a,c[d].unhideAll());a.length||(a[0]=b)}return a};
                +Blockly.RenderedConnection.prototype.unhighlight=function(){goog.dom.removeNode(Blockly.Connection.highlightedPath_);delete Blockly.Connection.highlightedPath_};Blockly.RenderedConnection.prototype.setHidden=function(a){(this.hidden_=a)&&this.inDB_?this.db_.removeConnection_(this):a||this.inDB_||this.db_.addConnection(this)};
                +Blockly.RenderedConnection.prototype.hideAll=function(){this.setHidden(!0);if(this.targetConnection)for(var a=this.targetBlock().getDescendants(),b=0;b<a.length;b++){for(var c=a[b],d=c.getConnections_(!0),e=0;e<d.length;e++)d[e].setHidden(!0);c=c.getIcons();for(e=0;e<c.length;e++)c[e].setVisible(!1)}};Blockly.RenderedConnection.prototype.isConnectionAllowed=function(a,b){return this.distanceFrom(a)>b?!1:Blockly.RenderedConnection.superClass_.isConnectionAllowed.call(this,a)};
                +Blockly.RenderedConnection.prototype.disconnectInternal_=function(a,b){Blockly.RenderedConnection.superClass_.disconnectInternal_.call(this,a,b);a.rendered&&a.render();b.rendered&&(b.updateDisabled(),b.render())};
                +Blockly.RenderedConnection.prototype.respawnShadow_=function(){var a=this.getSourceBlock(),b=this.getShadowDom();if(a.workspace&&b&&Blockly.Events.recordUndo){Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);b=this.targetBlock();if(!b)throw"Couldn't respawn the shadow block that should exist here.";b.initSvg();b.render(!1);a.rendered&&a.render()}};Blockly.RenderedConnection.prototype.neighbours_=function(a){return this.dbOpposite_.getNeighbours(this,a)};
                +Blockly.RenderedConnection.prototype.connect_=function(a){Blockly.RenderedConnection.superClass_.connect_.call(this,a);var b=this.getSourceBlock();a=a.getSourceBlock();b.rendered&&b.updateDisabled();a.rendered&&a.updateDisabled();b.rendered&&a.rendered&&(this.type==Blockly.NEXT_STATEMENT||this.type==Blockly.PREVIOUS_STATEMENT?a.render():b.render())};
                +Blockly.RenderedConnection.prototype.onCheckChanged_=function(){this.isConnected()&&!this.checkType_(this.targetConnection)&&((this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug(),this.sourceBlock_.bumpNeighbours_())};Blockly.DraggedConnectionManager=function(a){this.topBlock_=Blockly.selected=a;this.workspace_=a.workspace;this.availableConnections_=this.initAvailableConnections_();this.localConnection_=this.closestConnection_=null;this.radiusConnection_=0;this.wouldDeleteBlock_=!1};Blockly.DraggedConnectionManager.prototype.dispose=function(){this.workspace_=this.topBlock_=null;this.availableConnections_.length=0;this.localConnection_=this.closestConnection_=null};
                +Blockly.DraggedConnectionManager.prototype.wouldDeleteBlock=function(){return this.wouldDeleteBlock_};Blockly.DraggedConnectionManager.prototype.applyConnections=function(){this.closestConnection_&&(this.localConnection_.connect(this.closestConnection_),this.topBlock_.rendered&&(this.localConnection_.isSuperior()?this.closestConnection_:this.localConnection_).getSourceBlock().connectionUiEffect(),this.removeHighlighting_())};
                +Blockly.DraggedConnectionManager.prototype.update=function(a,b){var c=this.closestConnection_;(a=this.updateClosest_(a))&&c&&c.unhighlight();c=!!this.closestConnection_&&b!=Blockly.DELETE_AREA_TOOLBOX;this.wouldDeleteBlock_=!!b&&!this.topBlock_.getParent()&&this.topBlock_.isDeletable()&&!c;!this.wouldDeleteBlock_&&a&&this.closestConnection_&&this.addHighlighting_()};Blockly.DraggedConnectionManager.prototype.removeHighlighting_=function(){this.closestConnection_&&this.closestConnection_.unhighlight()};
                +Blockly.DraggedConnectionManager.prototype.addHighlighting_=function(){this.closestConnection_&&this.closestConnection_.highlight()};Blockly.DraggedConnectionManager.prototype.initAvailableConnections_=function(){var a=this.topBlock_.getConnections_(!1),b=this.topBlock_.lastConnectionInStack_();b&&b!=this.topBlock_.nextConnection&&a.push(b);return a};
                +Blockly.DraggedConnectionManager.prototype.updateClosest_=function(a){var b=this.closestConnection_;this.localConnection_=this.closestConnection_=null;this.radiusConnection_=Blockly.SNAP_RADIUS;for(var c=0;c<this.availableConnections_.length;c++){var d=this.availableConnections_[c],e=d.closest(this.radiusConnection_,a);e.connection&&(this.closestConnection_=e.connection,this.localConnection_=d,this.radiusConnection_=e.radius)}return b!=this.closestConnection_};Blockly.BlockDragger=function(a,b){this.draggingBlock_=a;this.workspace_=b;this.draggedConnectionManager_=new Blockly.DraggedConnectionManager(this.draggingBlock_);this.deleteArea_=null;this.wouldDeleteBlock_=!1;this.startXY_=this.draggingBlock_.getRelativeToSurfaceXY();this.dragIconData_=Blockly.BlockDragger.initIconData_(a)};
                +Blockly.BlockDragger.prototype.dispose=function(){this.startWorkspace_=this.workspace_=this.draggingBlock_=null;this.dragIconData_.length=0;this.draggedConnectionManager_&&(this.draggedConnectionManager_.dispose(),this.draggedConnectionManager_=null)};Blockly.BlockDragger.initIconData_=function(a){var b=[];a=a.getDescendants();for(var c=0,d;d=a[c];c++){d=d.getIcons();for(var e=0;e<d.length;e++){var f={location:d[e].getIconLocation(),icon:d[e]};b.push(f)}}return b};
                +Blockly.BlockDragger.prototype.startBlockDrag=function(a){Blockly.Events.getGroup()||Blockly.Events.setGroup(!0);this.workspace_.setResizesEnabled(!1);Blockly.BlockSvg.disconnectUiStop_();this.draggingBlock_.getParent()&&(this.draggingBlock_.unplug(),a=this.pixelsToWorkspaceUnits_(a),a=goog.math.Coordinate.sum(this.startXY_,a),this.draggingBlock_.translate(a.x,a.y),this.draggingBlock_.disconnectUiEffect());this.draggingBlock_.setDragging(!0);this.draggingBlock_.moveToDragSurface_();this.workspace_.toolbox_&&
                +this.workspace_.toolbox_.addDeleteStyle()};Blockly.BlockDragger.prototype.dragBlock=function(a,b){b=this.pixelsToWorkspaceUnits_(b);var c=goog.math.Coordinate.sum(this.startXY_,b);this.draggingBlock_.moveDuringDrag(c);this.dragIcons_(b);this.deleteArea_=this.workspace_.isDeleteArea(a);this.draggedConnectionManager_.update(b,this.deleteArea_);this.updateCursorDuringBlockDrag_()};
                +Blockly.BlockDragger.prototype.endBlockDrag=function(a,b){this.dragBlock(a,b);this.dragIconData_=[];Blockly.BlockSvg.disconnectUiStop_();a=this.pixelsToWorkspaceUnits_(b);b=goog.math.Coordinate.sum(this.startXY_,a);this.draggingBlock_.moveOffDragSurface_(b);this.maybeDeleteBlock_()||(this.draggingBlock_.moveConnections_(a.x,a.y),this.draggingBlock_.setDragging(!1),this.draggedConnectionManager_.applyConnections(),this.draggingBlock_.render(),this.fireMoveEvent_(),this.draggingBlock_.scheduleSnapAndBump());
                +this.workspace_.setResizesEnabled(!0);this.workspace_.toolbox_&&this.workspace_.toolbox_.removeDeleteStyle();Blockly.Events.setGroup(!1)};Blockly.BlockDragger.prototype.fireMoveEvent_=function(){var a=new Blockly.Events.BlockMove(this.draggingBlock_);a.oldCoordinate=this.startXY_;a.recordNew();Blockly.Events.fire(a)};
                +Blockly.BlockDragger.prototype.maybeDeleteBlock_=function(){var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(a&&goog.Timer.callOnce(a.close,100,a),this.fireMoveEvent_(),this.draggingBlock_.dispose(!1,!0)):a&&a.close();return this.wouldDeleteBlock_};
                +Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_=function(){this.wouldDeleteBlock_=this.draggedConnectionManager_.wouldDeleteBlock();var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(this.draggingBlock_.setDeleteStyle(!0),this.deleteArea_==Blockly.DELETE_AREA_TRASH&&a&&a.setOpen_(!0)):(this.draggingBlock_.setDeleteStyle(!1),a&&a.setOpen_(!1))};
                +Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_=function(a){a=new goog.math.Coordinate(a.x/this.workspace_.scale,a.y/this.workspace_.scale);this.workspace_.isMutator&&(a=a.scale(1/this.workspace_.options.parentWorkspace.scale));return a};Blockly.BlockDragger.prototype.dragIcons_=function(a){for(var b=0;b<this.dragIconData_.length;b++){var c=this.dragIconData_[b];c.icon.setIconLocation(goog.math.Coordinate.sum(c.location,a))}};Blockly.constants={};Blockly.DRAG_RADIUS=5;Blockly.FLYOUT_DRAG_RADIUS=10;Blockly.SNAP_RADIUS=20;Blockly.BUMP_DELAY=250;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.DRAG_STACK=!0;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;Blockly.SPRITE={width:96,height:124,url:"sprites.png"};Blockly.SVG_NS="http://www.w3.org/2000/svg";Blockly.HTML_NS="http://www.w3.org/1999/xhtml";Blockly.INPUT_VALUE=1;Blockly.OUTPUT_VALUE=2;Blockly.NEXT_STATEMENT=3;
                +Blockly.PREVIOUS_STATEMENT=4;Blockly.DUMMY_INPUT=5;Blockly.ALIGN_LEFT=-1;Blockly.ALIGN_CENTRE=0;Blockly.ALIGN_RIGHT=1;Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE]=Blockly.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE]=Blockly.INPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT]=Blockly.PREVIOUS_STATEMENT;Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT]=Blockly.NEXT_STATEMENT;
                +Blockly.TOOLBOX_AT_TOP=0;Blockly.TOOLBOX_AT_BOTTOM=1;Blockly.TOOLBOX_AT_LEFT=2;Blockly.TOOLBOX_AT_RIGHT=3;Blockly.DELETE_AREA_NONE=null;Blockly.DELETE_AREA_TRASH=1;Blockly.DELETE_AREA_TOOLBOX=2;Blockly.VARIABLE_CATEGORY_NAME="VARIABLE";Blockly.PROCEDURE_CATEGORY_NAME="PROCEDURE";Blockly.RENAME_VARIABLE_ID="RENAME_VARIABLE_ID";Blockly.DELETE_VARIABLE_ID="DELETE_VARIABLE_ID";Blockly.WorkspaceDragger=function(a){this.workspace_=a;this.startDragMetrics_=a.getMetrics();this.startScrollXY_=new goog.math.Coordinate(a.scrollX,a.scrollY)};Blockly.WorkspaceDragger.prototype.dispose=function(){this.workspace_=null};Blockly.WorkspaceDragger.prototype.startDrag=function(){Blockly.selected&&Blockly.selected.unselect();this.workspace_.setupDragSurface()};Blockly.WorkspaceDragger.prototype.endDrag=function(a){this.drag(a);this.workspace_.resetDragSurface()};
                +Blockly.WorkspaceDragger.prototype.drag=function(a){var b=this.startDragMetrics_,c=goog.math.Coordinate.sum(this.startScrollXY_,a);a=Math.min(c.x,-b.contentLeft);c=Math.min(c.y,-b.contentTop);a=Math.max(a,b.viewWidth-b.contentLeft-b.contentWidth);c=Math.max(c,b.viewHeight-b.contentTop-b.contentHeight);a=-a-b.contentLeft;c=-c-b.contentTop;this.updateScroll_(a,c)};Blockly.WorkspaceDragger.prototype.updateScroll_=function(a,b){this.workspace_.scrollbar.set(a,b)};Blockly.FlyoutDragger=function(a){Blockly.FlyoutDragger.superClass_.constructor.call(this,a.getWorkspace());this.scrollbar_=a.scrollbar_;this.horizontalLayout_=a.horizontalLayout_};goog.inherits(Blockly.FlyoutDragger,Blockly.WorkspaceDragger);Blockly.FlyoutDragger.prototype.updateScroll_=function(a,b){this.horizontalLayout_?this.scrollbar_.set(a):this.scrollbar_.set(b)};Blockly.Tooltip={};Blockly.Tooltip.visible=!1;Blockly.Tooltip.blocked_=!1;Blockly.Tooltip.LIMIT=50;Blockly.Tooltip.mouseOutPid_=0;Blockly.Tooltip.showPid_=0;Blockly.Tooltip.lastX_=0;Blockly.Tooltip.lastY_=0;Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.OFFSET_X=0;Blockly.Tooltip.OFFSET_Y=10;Blockly.Tooltip.RADIUS_OK=10;Blockly.Tooltip.HOVER_MS=750;Blockly.Tooltip.MARGINS=5;Blockly.Tooltip.DIV=null;
                +Blockly.Tooltip.createDom=function(){Blockly.Tooltip.DIV||(Blockly.Tooltip.DIV=goog.dom.createDom("DIV","blocklyTooltipDiv"),document.body.appendChild(Blockly.Tooltip.DIV))};Blockly.Tooltip.bindMouseEvents=function(a){Blockly.bindEvent_(a,"mouseover",null,Blockly.Tooltip.onMouseOver_);Blockly.bindEvent_(a,"mouseout",null,Blockly.Tooltip.onMouseOut_);a.addEventListener("mousemove",Blockly.Tooltip.onMouseMove_,!1)};
                +Blockly.Tooltip.onMouseOver_=function(a){if(!Blockly.Tooltip.blocked_){for(a=a.target;!goog.isString(a.tooltip)&&!goog.isFunction(a.tooltip);)a=a.tooltip;Blockly.Tooltip.element_!=a&&(Blockly.Tooltip.hide(),Blockly.Tooltip.poisonedElement_=null,Blockly.Tooltip.element_=a);clearTimeout(Blockly.Tooltip.mouseOutPid_)}};
                +Blockly.Tooltip.onMouseOut_=function(a){Blockly.Tooltip.blocked_||(Blockly.Tooltip.mouseOutPid_=setTimeout(function(){Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.hide()},1),clearTimeout(Blockly.Tooltip.showPid_))};
                +Blockly.Tooltip.onMouseMove_=function(a){if(Blockly.Tooltip.element_&&Blockly.Tooltip.element_.tooltip&&!Blockly.WidgetDiv.isVisible()&&!Blockly.Tooltip.blocked_)if(Blockly.Tooltip.visible){var b=Blockly.Tooltip.lastX_-a.pageX;a=Blockly.Tooltip.lastY_-a.pageY;Math.sqrt(b*b+a*a)>Blockly.Tooltip.RADIUS_OK&&Blockly.Tooltip.hide()}else Blockly.Tooltip.poisonedElement_!=Blockly.Tooltip.element_&&(clearTimeout(Blockly.Tooltip.showPid_),Blockly.Tooltip.lastX_=a.pageX,Blockly.Tooltip.lastY_=a.pageY,Blockly.Tooltip.showPid_=
                +setTimeout(Blockly.Tooltip.show_,Blockly.Tooltip.HOVER_MS))};Blockly.Tooltip.hide=function(){Blockly.Tooltip.visible&&(Blockly.Tooltip.visible=!1,Blockly.Tooltip.DIV&&(Blockly.Tooltip.DIV.style.display="none"));clearTimeout(Blockly.Tooltip.showPid_)};Blockly.Tooltip.block=function(){Blockly.Tooltip.hide();Blockly.Tooltip.blocked_=!0};Blockly.Tooltip.unblock=function(){Blockly.Tooltip.blocked_=!1};
                +Blockly.Tooltip.show_=function(){if(!Blockly.Tooltip.blocked_&&(Blockly.Tooltip.poisonedElement_=Blockly.Tooltip.element_,Blockly.Tooltip.DIV)){goog.dom.removeChildren(Blockly.Tooltip.DIV);for(var a=Blockly.Tooltip.element_.tooltip;goog.isFunction(a);)a=a();for(var a=Blockly.utils.wrap(a,Blockly.Tooltip.LIMIT),a=a.split("\n"),b=0;b<a.length;b++){var c=document.createElement("div");c.appendChild(document.createTextNode(a[b]));Blockly.Tooltip.DIV.appendChild(c)}a=Blockly.Tooltip.element_.RTL;b=goog.dom.getViewportSize();
                +Blockly.Tooltip.DIV.style.direction=a?"rtl":"ltr";Blockly.Tooltip.DIV.style.display="block";Blockly.Tooltip.visible=!0;var c=Blockly.Tooltip.lastX_,c=a?c-(Blockly.Tooltip.OFFSET_X+Blockly.Tooltip.DIV.offsetWidth):c+Blockly.Tooltip.OFFSET_X,d=Blockly.Tooltip.lastY_+Blockly.Tooltip.OFFSET_Y;d+Blockly.Tooltip.DIV.offsetHeight>b.height+window.scrollY&&(d-=Blockly.Tooltip.DIV.offsetHeight+2*Blockly.Tooltip.OFFSET_Y);a?c=Math.max(Blockly.Tooltip.MARGINS-window.scrollX,c):c+Blockly.Tooltip.DIV.offsetWidth>
                +b.width+window.scrollX-2*Blockly.Tooltip.MARGINS&&(c=b.width-Blockly.Tooltip.DIV.offsetWidth-2*Blockly.Tooltip.MARGINS);Blockly.Tooltip.DIV.style.top=d+"px";Blockly.Tooltip.DIV.style.left=c+"px"}};Blockly.Gesture=function(a,b){this.mouseDownXY_=null;this.currentDragDeltaXY_=0;this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=null;this.creatorWorkspace_=b;this.isDraggingBlock_=this.isDraggingWorkspace_=this.hasExceededDragRadius_=!1;this.mostRecentEvent_=a;this.flyout_=this.workspaceDragger_=this.blockDragger_=this.onUpWrapper_=this.onMoveWrapper_=null;this.isEnding_=this.hasStarted_=this.calledUpdateIsDragging_=!1};
                +Blockly.Gesture.prototype.dispose=function(){Blockly.Touch.clearTouchIdentifier();Blockly.Tooltip.unblock();this.creatorWorkspace_.clearGesture();this.onMoveWrapper_&&Blockly.unbindEvent_(this.onMoveWrapper_);this.onUpWrapper_&&Blockly.unbindEvent_(this.onUpWrapper_);this.flyout_=this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=null;this.blockDragger_&&(this.blockDragger_.dispose(),this.blockDragger_=null);this.workspaceDragger_&&(this.workspaceDragger_.dispose(),this.workspaceDragger_=
                +null)};Blockly.Gesture.prototype.updateFromEvent_=function(a){var b=new goog.math.Coordinate(a.clientX,a.clientY);this.updateDragDelta_(b)&&(this.updateIsDragging_(),Blockly.longStop_());this.mostRecentEvent_=a};
                +Blockly.Gesture.prototype.updateDragDelta_=function(a){this.currentDragDeltaXY_=goog.math.Coordinate.difference(a,this.mouseDownXY_);return this.hasExceededDragRadius_?!1:this.hasExceededDragRadius_=goog.math.Coordinate.magnitude(this.currentDragDeltaXY_)>(this.flyout_?Blockly.FLYOUT_DRAG_RADIUS:Blockly.DRAG_RADIUS)};
                +Blockly.Gesture.prototype.updateIsDraggingFromFlyout_=function(){return this.targetBlock_.disabled?!1:!this.flyout_.isScrollable()||this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)?(this.startWorkspace_=this.flyout_.targetWorkspace_,this.startWorkspace_.updateScreenCalculationsIfScrolled(),Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.startBlock_=null,this.targetBlock_=this.flyout_.createBlock(this.targetBlock_),this.targetBlock_.select(),!0):!1};
                +Blockly.Gesture.prototype.updateIsDraggingBlock_=function(){if(!this.targetBlock_)return!1;this.flyout_?this.isDraggingBlock_=this.updateIsDraggingFromFlyout_():this.targetBlock_.isMovable()&&(this.isDraggingBlock_=!0);return this.isDraggingBlock_?(this.startDraggingBlock_(),!0):!1};
                +Blockly.Gesture.prototype.updateIsDraggingWorkspace_=function(){if(this.flyout_?this.flyout_.isScrollable():this.startWorkspace_&&this.startWorkspace_.isDraggable())this.workspaceDragger_=this.flyout_?new Blockly.FlyoutDragger(this.flyout_):new Blockly.WorkspaceDragger(this.startWorkspace_),this.isDraggingWorkspace_=!0,this.workspaceDragger_.startDrag()};
                +Blockly.Gesture.prototype.updateIsDragging_=function(){goog.asserts.assert(!this.calledUpdateIsDragging_,"updateIsDragging_ should only be called once per gesture.");this.calledUpdateIsDragging_=!0;this.updateIsDraggingBlock_()||this.updateIsDraggingWorkspace_()};
                +Blockly.Gesture.prototype.startDraggingBlock_=function(){this.blockDragger_=new Blockly.BlockDragger(this.targetBlock_,this.startWorkspace_);this.blockDragger_.startBlockDrag(this.currentDragDeltaXY_);this.blockDragger_.dragBlock(this.mostRecentEvent_,this.currentDragDeltaXY_)};
                +Blockly.Gesture.prototype.doStart=function(a){Blockly.utils.isTargetInput(a)?this.cancel():(this.hasStarted_=!0,Blockly.BlockSvg.disconnectUiStop_(),this.startWorkspace_.updateScreenCalculationsIfScrolled(),this.startWorkspace_.isMutator&&this.startWorkspace_.resize(),this.startWorkspace_.markFocused(),this.mostRecentEvent_=a,Blockly.hideChaff(!!this.flyout_),Blockly.Tooltip.block(),this.targetBlock_&&this.targetBlock_.select(),Blockly.utils.isRightButton(a)?this.handleRightClick(a):(goog.string.caseInsensitiveEquals(a.type,
                +"touchstart")&&Blockly.longStart_(a,this),this.mouseDownXY_=new goog.math.Coordinate(a.clientX,a.clientY),this.onMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",null,this.handleMove.bind(this)),this.onUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",null,this.handleUp.bind(this)),a.preventDefault(),a.stopPropagation()))};
                +Blockly.Gesture.prototype.handleMove=function(a){this.updateFromEvent_(a);this.isDraggingWorkspace_?this.workspaceDragger_.drag(this.currentDragDeltaXY_):this.isDraggingBlock_&&this.blockDragger_.dragBlock(this.mostRecentEvent_,this.currentDragDeltaXY_);a.preventDefault();a.stopPropagation()};
                +Blockly.Gesture.prototype.handleUp=function(a){this.updateFromEvent_(a);Blockly.longStop_();this.isEnding_?console.log("Trying to end a gesture recursively."):(this.isEnding_=!0,this.isDraggingBlock_?this.blockDragger_.endBlockDrag(a,this.currentDragDeltaXY_):this.isDraggingWorkspace_?this.workspaceDragger_.endDrag(this.currentDragDeltaXY_):this.isFieldClick_()?this.doFieldClick_():this.isBlockClick_()?this.doBlockClick_():this.isWorkspaceClick_()&&this.doWorkspaceClick_(),a.preventDefault(),a.stopPropagation(),
                +this.dispose())};Blockly.Gesture.prototype.cancel=function(){this.isEnding_||(Blockly.longStop_(),this.isDraggingBlock_?this.blockDragger_.endBlockDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingWorkspace_&&this.workspaceDragger_.endDrag(this.currentDragDeltaXY_),this.dispose())};
                +Blockly.Gesture.prototype.handleRightClick=function(a){this.targetBlock_?(this.bringBlockToFront_(),Blockly.hideChaff(this.flyout_),this.targetBlock_.showContextMenu_(a)):this.startWorkspace_&&!this.flyout_&&(Blockly.hideChaff(),this.startWorkspace_.showContextMenu_(a));a.preventDefault();a.stopPropagation();this.dispose()};
                +Blockly.Gesture.prototype.handleWsStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleWsStart, but the gesture had already been started.");this.setStartWorkspace_(b);this.mostRecentEvent_=a;this.doStart(a)};Blockly.Gesture.prototype.handleFlyoutStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleFlyoutStart, but the gesture had already been started.");this.setStartFlyout_(b);this.handleWsStart(a,b.getWorkspace())};
                +Blockly.Gesture.prototype.handleBlockStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleBlockStart, but the gesture had already been started.");this.setStartBlock(b);this.mostRecentEvent_=a};Blockly.Gesture.prototype.doFieldClick_=function(){this.startField_.showEditor_();this.bringBlockToFront_()};
                +Blockly.Gesture.prototype.doBlockClick_=function(){this.flyout_&&this.flyout_.autoClose?this.targetBlock_.disabled||(Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.flyout_.createBlock(this.targetBlock_).scheduleSnapAndBump()):Blockly.Events.fire(new Blockly.Events.Ui(this.startBlock_,"click",void 0,void 0));this.bringBlockToFront_();Blockly.Events.setGroup(!1)};Blockly.Gesture.prototype.doWorkspaceClick_=function(){Blockly.selected&&Blockly.selected.unselect()};
                +Blockly.Gesture.prototype.bringBlockToFront_=function(){this.targetBlock_&&!this.flyout_&&this.targetBlock_.bringToFront()};Blockly.Gesture.prototype.setStartField=function(a){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.setStartField, but the gesture had already been started.");this.startField_||(this.startField_=a)};Blockly.Gesture.prototype.setStartBlock=function(a){this.startBlock_||(this.startBlock_=a,a.isInFlyout&&a!=a.getRootBlock()?this.setTargetBlock_(a.getRootBlock()):this.setTargetBlock_(a))};
                +Blockly.Gesture.prototype.setTargetBlock_=function(a){a.isShadow()?this.setTargetBlock_(a.getParent()):this.targetBlock_=a};Blockly.Gesture.prototype.setStartWorkspace_=function(a){this.startWorkspace_||(this.startWorkspace_=a)};Blockly.Gesture.prototype.setStartFlyout_=function(a){this.flyout_||(this.flyout_=a)};Blockly.Gesture.prototype.isBlockClick_=function(){return!!this.startBlock_&&!this.hasExceededDragRadius_&&!this.isFieldClick_()};
                +Blockly.Gesture.prototype.isFieldClick_=function(){return(this.startField_?this.startField_.isCurrentlyEditable():!1)&&!this.hasExceededDragRadius_&&(!this.flyout_||!this.flyout_.autoClose)};Blockly.Gesture.prototype.isWorkspaceClick_=function(){return!this.startBlock_&&!this.startField_&&!this.hasExceededDragRadius_};Blockly.Gesture.prototype.isDragging=function(){return this.isDraggingWorkspace_||this.isDraggingBlock_};Blockly.Gesture.prototype.hasStarted=function(){return this.hasStarted_};Blockly.Field=function(a,b){this.size_=new goog.math.Size(0,Blockly.BlockSvg.MIN_BLOCK_Y);this.setValue(a);this.setValidator(b)};Blockly.Field.cacheWidths_=null;Blockly.Field.cacheReference_=0;Blockly.Field.prototype.name=void 0;Blockly.Field.prototype.maxDisplayLength=50;Blockly.Field.prototype.text_="";Blockly.Field.prototype.sourceBlock_=null;Blockly.Field.prototype.visible_=!0;Blockly.Field.prototype.validator_=null;Blockly.Field.NBSP="\u00a0";Blockly.Field.prototype.EDITABLE=!0;
                +Blockly.Field.prototype.setSourceBlock=function(a){goog.asserts.assert(!this.sourceBlock_,"Field already bound to a block.");this.sourceBlock_=a};
                +Blockly.Field.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=Blockly.utils.createSvgElement("g",{},null),this.visible_||(this.fieldGroup_.style.display="none"),this.borderRect_=Blockly.utils.createSvgElement("rect",{rx:4,ry:4,x:-Blockly.BlockSvg.SEP_SPACE_X/2,y:0,height:16},this.fieldGroup_,this.sourceBlock_.workspace),this.textElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText",y:this.size_.height-12.5},this.fieldGroup_),this.updateEditable(),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),
                +this.mouseDownWrapper_=Blockly.bindEventWithChecks_(this.fieldGroup_,"mousedown",this,this.onMouseDown_),this.render_())};Blockly.Field.prototype.initModel=function(){};Blockly.Field.prototype.dispose=function(){this.mouseDownWrapper_&&(Blockly.unbindEvent_(this.mouseDownWrapper_),this.mouseDownWrapper_=null);this.sourceBlock_=null;goog.dom.removeNode(this.fieldGroup_);this.validator_=this.borderRect_=this.textElement_=this.fieldGroup_=null};
                +Blockly.Field.prototype.updateEditable=function(){var a=this.fieldGroup_;this.EDITABLE&&a&&(this.sourceBlock_.isEditable()?(Blockly.utils.addClass(a,"blocklyEditableText"),Blockly.utils.removeClass(a,"blocklyNonEditableText"),this.fieldGroup_.style.cursor=this.CURSOR):(Blockly.utils.addClass(a,"blocklyNonEditableText"),Blockly.utils.removeClass(a,"blocklyEditableText"),this.fieldGroup_.style.cursor=""))};
                +Blockly.Field.prototype.isCurrentlyEditable=function(){return this.EDITABLE&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()};Blockly.Field.prototype.isVisible=function(){return this.visible_};Blockly.Field.prototype.setVisible=function(a){if(this.visible_!=a){this.visible_=a;var b=this.getSvgRoot();b&&(b.style.display=a?"block":"none",this.render_())}};Blockly.Field.prototype.setValidator=function(a){this.validator_=a};Blockly.Field.prototype.getValidator=function(){return this.validator_};
                +Blockly.Field.prototype.classValidator=function(a){return a};Blockly.Field.prototype.callValidator=function(a){var b=this.classValidator(a);if(null===b)return null;void 0!==b&&(a=b);if(b=this.getValidator()){b=b.call(this,a);if(null===b)return null;void 0!==b&&(a=b)}return a};Blockly.Field.prototype.getSvgRoot=function(){return this.fieldGroup_};
                +Blockly.Field.prototype.render_=function(){if(this.visible_){goog.dom.removeChildren(this.textElement_);var a=document.createTextNode(this.getDisplayText_());this.textElement_.appendChild(a);this.updateWidth()}else this.size_.width=0};Blockly.Field.prototype.updateWidth=function(){var a=Blockly.Field.getCachedWidth(this.textElement_);this.borderRect_&&this.borderRect_.setAttribute("width",a+Blockly.BlockSvg.SEP_SPACE_X);this.size_.width=a};
                +Blockly.Field.getCachedWidth=function(a){var b=a.textContent+"\n"+a.className.baseVal,c;if(Blockly.Field.cacheWidths_&&(c=Blockly.Field.cacheWidths_[b]))return c;try{c=a.getComputedTextLength()}catch(d){return 8*a.textContent.length}Blockly.Field.cacheWidths_&&(Blockly.Field.cacheWidths_[b]=c);return c};Blockly.Field.startCache=function(){Blockly.Field.cacheReference_++;Blockly.Field.cacheWidths_||(Blockly.Field.cacheWidths_={})};
                +Blockly.Field.stopCache=function(){Blockly.Field.cacheReference_--;Blockly.Field.cacheReference_||(Blockly.Field.cacheWidths_=null)};Blockly.Field.prototype.getSize=function(){this.size_.width||this.render_();return this.size_};Blockly.Field.prototype.getScaledBBox_=function(){var a=this.borderRect_.getBBox();return new goog.math.Size(a.width*this.sourceBlock_.workspace.scale,a.height*this.sourceBlock_.workspace.scale)};
                +Blockly.Field.prototype.getDisplayText_=function(){var a=this.text_;if(!a)return Blockly.Field.NBSP;a.length>this.maxDisplayLength&&(a=a.substring(0,this.maxDisplayLength-2)+"\u2026");a=a.replace(/\s/g,Blockly.Field.NBSP);this.sourceBlock_.RTL&&(a+="\u200f");return a};Blockly.Field.prototype.getText=function(){return this.text_};
                +Blockly.Field.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.text_=a,this.size_.width=0,this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_())))};Blockly.Field.prototype.getValue=function(){return this.getText()};
                +Blockly.Field.prototype.setValue=function(a){if(null!==a){var b=this.getValue();b!=a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,b,a)),this.setText(a))}};Blockly.Field.prototype.onMouseDown_=function(a){this.sourceBlock_&&this.sourceBlock_.workspace&&(a=this.sourceBlock_.workspace.getGesture(a))&&a.setStartField(this)};Blockly.Field.prototype.setTooltip=function(a){};
                +Blockly.Field.prototype.getAbsoluteXY_=function(){return goog.style.getPageOffset(this.borderRect_)};Blockly.FieldLabel=function(a,b){this.size_=new goog.math.Size(0,17.5);this.class_=b;this.setValue(a)};goog.inherits(Blockly.FieldLabel,Blockly.Field);Blockly.FieldLabel.prototype.EDITABLE=!1;
                +Blockly.FieldLabel.prototype.init=function(){this.textElement_||(this.textElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText",y:this.size_.height-5},null),this.class_&&Blockly.utils.addClass(this.textElement_,this.class_),this.visible_||(this.textElement_.style.display="none"),this.sourceBlock_.getSvgRoot().appendChild(this.textElement_),this.textElement_.tooltip=this.sourceBlock_,Blockly.Tooltip.bindMouseEvents(this.textElement_),this.render_())};
                +Blockly.FieldLabel.prototype.dispose=function(){goog.dom.removeNode(this.textElement_);this.textElement_=null};Blockly.FieldLabel.prototype.getSvgRoot=function(){return this.textElement_};Blockly.FieldLabel.prototype.setTooltip=function(a){this.textElement_.tooltip=a};Blockly.Input=function(a,b,c,d){if(a!=Blockly.DUMMY_INPUT&&!b)throw"Value inputs and statement inputs must have non-empty name.";this.type=a;this.name=b;this.sourceBlock_=c;this.connection=d;this.fieldRow=[]};Blockly.Input.prototype.align=Blockly.ALIGN_LEFT;Blockly.Input.prototype.visible_=!0;Blockly.Input.prototype.appendField=function(a,b){this.insertFieldAt(this.fieldRow.length,a,b);return this};
                +Blockly.Input.prototype.insertFieldAt=function(a,b,c){if(0>a||a>this.fieldRow.length)throw Error("index "+a+" out of bounds.");if(!b&&!c)return this;goog.isString(b)&&(b=new Blockly.FieldLabel(b));b.setSourceBlock(this.sourceBlock_);this.sourceBlock_.rendered&&b.init();b.name=c;b.prefixField&&(a=this.insertFieldAt(a,b.prefixField));this.fieldRow.splice(a,0,b);++a;b.suffixField&&(a=this.insertFieldAt(a,b.suffixField));this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());
                +return a};Blockly.Input.prototype.removeField=function(a){for(var b=0,c;c=this.fieldRow[b];b++)if(c.name===a){c.dispose();this.fieldRow.splice(b,1);this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());return}goog.asserts.fail('Field "%s" not found.',a)};Blockly.Input.prototype.isVisible=function(){return this.visible_};
                +Blockly.Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;for(var c=(this.visible_=a)?"block":"none",d=0,e;e=this.fieldRow[d];d++)e.setVisible(a);this.connection&&(a?b=this.connection.unhideAll():this.connection.hideAll(),d=this.connection.targetBlock())&&(d.getSvgRoot().style.display=c,a||(d.rendered=!1));return b};Blockly.Input.prototype.setCheck=function(a){if(!this.connection)throw"This input does not have a connection.";this.connection.setCheck(a);return this};
                +Blockly.Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&this.sourceBlock_.render();return this};Blockly.Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;a<this.fieldRow.length;a++)this.fieldRow[a].init()};Blockly.Input.prototype.dispose=function(){for(var a=0,b;b=this.fieldRow[a];a++)b.dispose();this.connection&&this.connection.dispose();this.sourceBlock_=null};Blockly.ConnectionDB=function(){};Blockly.ConnectionDB.prototype=[];Blockly.ConnectionDB.constructor=Blockly.ConnectionDB;Blockly.ConnectionDB.prototype.addConnection=function(a){if(a.inDB_)throw"Connection already in database.";if(!a.getSourceBlock().isInFlyout){var b=this.findPositionForConnection_(a);this.splice(b,0,a);a.inDB_=!0}};
                +Blockly.ConnectionDB.prototype.findConnection=function(a){if(!this.length)return-1;var b=this.findPositionForConnection_(a);if(b>=this.length)return-1;for(var c=a.y_,d=b;0<=d&&this[d].y_==c;){if(this[d]==a)return d;d--}for(;b<this.length&&this[b].y_==c;){if(this[b]==a)return b;b++}return-1};
                +Blockly.ConnectionDB.prototype.findPositionForConnection_=function(a){if(!this.length)return 0;for(var b=0,c=this.length;b<c;){var d=Math.floor((b+c)/2);if(this[d].y_<a.y_)b=d+1;else if(this[d].y_>a.y_)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection_=function(a){if(!a.inDB_)throw"Connection not in database.";var b=this.findConnection(a);if(-1==b)throw"Unable to find connection in connectionDB.";a.inDB_=!1;this.splice(b,1)};
                +Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x_,g=f-d[a].y_;Math.sqrt(c*c+g*g)<=b&&k.push(d[a]);return g<b}var d=this,e=a.x_,f=a.y_;a=0;for(var g=d.length-2,h=g;a<h;)d[h].y_<f?a=h:g=h,h=Math.floor((a+g)/2);var k=[],g=a=h;if(d.length){for(;0<=a&&c(a);)a--;do g++;while(g<d.length&&c(g))}return k};Blockly.ConnectionDB.prototype.isInYRange_=function(a,b,c){return Math.abs(this[a].y_-b)<=c};
                +Blockly.ConnectionDB.prototype.searchForClosest=function(a,b,c){if(!this.length)return{connection:null,radius:b};var d=a.y_,e=a.x_;a.x_=e+c.x;a.y_=d+c.y;var f=this.findPositionForConnection_(a);c=null;for(var g=b,h,k=f-1;0<=k&&this.isInYRange_(k,a.y_,b);)h=this[k],a.isConnectionAllowed(h,g)&&(c=h,g=h.distanceFrom(a)),k--;for(;f<this.length&&this.isInYRange_(f,a.y_,b);)h=this[f],a.isConnectionAllowed(h,g)&&(c=h,g=h.distanceFrom(a)),f++;a.x_=e;a.y_=d;return{connection:c,radius:g}};
                +Blockly.ConnectionDB.init=function(a){var b=[];b[Blockly.INPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.OUTPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.NEXT_STATEMENT]=new Blockly.ConnectionDB;b[Blockly.PREVIOUS_STATEMENT]=new Blockly.ConnectionDB;a.connectionDBList=b};Blockly.utils={};Blockly.utils.removeAttribute=function(a,b){goog.userAgent.IE&&goog.userAgent.isVersion("10.0")?a.setAttribute(b,null):a.removeAttribute(b)};Blockly.utils.addClass=function(a,b){var c=a.getAttribute("class")||"";if(-1!=(" "+c+" ").indexOf(" "+b+" "))return!1;c&&(c+=" ");a.setAttribute("class",c+b);return!0};
                +Blockly.utils.removeClass=function(a,b){var c=a.getAttribute("class");if(-1==(" "+c+" ").indexOf(" "+b+" "))return!1;for(var c=c.split(/\s+/),d=0;d<c.length;d++)c[d]&&c[d]!=b||(c.splice(d,1),d--);c.length?a.setAttribute("class",c.join(" ")):Blockly.utils.removeAttribute(a,"class");return!0};Blockly.utils.hasClass=function(a,b){return-1!=(" "+a.getAttribute("class")+" ").indexOf(" "+b+" ")};Blockly.utils.noEvent=function(a){a.preventDefault();a.stopPropagation()};
                +Blockly.utils.isTargetInput=function(a){return"textarea"==a.target.type||"text"==a.target.type||"number"==a.target.type||"email"==a.target.type||"password"==a.target.type||"search"==a.target.type||"tel"==a.target.type||"url"==a.target.type||a.target.isContentEditable};
                +Blockly.utils.getRelativeXY=function(a){var b=new goog.math.Coordinate(0,0),c=a.getAttribute("x");c&&(b.x=parseInt(c,10));if(c=a.getAttribute("y"))b.y=parseInt(c,10);if(c=(c=a.getAttribute("transform"))&&c.match(Blockly.utils.getRelativeXY.XY_REGEX_))b.x+=parseFloat(c[1]),c[3]&&(b.y+=parseFloat(c[3]));(a=a.getAttribute("style"))&&-1<a.indexOf("translate")&&((c=a.match(Blockly.utils.getRelativeXY.XY_2D_REGEX_))||(c=a.match(Blockly.utils.getRelativeXY.XY_3D_REGEX_)),c&&(b.x+=parseFloat(c[1]),c[3]&&
                +(b.y+=parseFloat(c[3]))));return b};Blockly.utils.getInjectionDivXY_=function(a){for(var b=0,c=0,d;a;){var e=Blockly.utils.getRelativeXY(a);d=Blockly.utils.getScale_(a);b=b*d+e.x;c=c*d+e.y;if(-1!=(" "+(a.getAttribute("class")||"")+" ").indexOf(" injectionDiv "))break;a=a.parentNode}return new goog.math.Coordinate(b,c)};Blockly.utils.getScale_=function(a){var b=1;(a=a.getAttribute("transform"))&&(a=a.match(Blockly.utils.getScale_.REGEXP_))&&a[0]&&(b=parseFloat(a[0]));return b};
                +Blockly.utils.getRelativeXY.XY_REGEX_=/translate\(\s*([-+\d.e]+)([ ,]\s*([-+\d.e]+)\s*\))?/;Blockly.utils.getScale_REGEXP_=/scale\(\s*([-+\d.e]+)\s*\)/;Blockly.utils.getRelativeXY.XY_3D_REGEX_=/transform:\s*translate3d\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;Blockly.utils.getRelativeXY.XY_2D_REGEX_=/transform:\s*translate\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;
                +Blockly.utils.createSvgElement=function(a,b,c){a=document.createElementNS(Blockly.SVG_NS,a);for(var d in b)a.setAttribute(d,b[d]);document.body.runtimeStyle&&(a.runtimeStyle=a.currentStyle=a.style);c&&c.appendChild(a);return a};Blockly.utils.isRightButton=function(a){return a.ctrlKey&&goog.userAgent.MAC?!0:2==a.button};Blockly.utils.mouseToSvg=function(a,b,c){var d=b.createSVGPoint();d.x=a.clientX;d.y=a.clientY;c||(c=b.getScreenCTM().inverse());return d.matrixTransform(c)};
                +Blockly.utils.shortestStringLength=function(a){return a.length?a.reduce(function(a,c){return a.length<c.length?a:c}).length:0};Blockly.utils.commonWordPrefix=function(a,b){if(!a.length)return 0;if(1==a.length)return a[0].length;for(var c=0,d=b||Blockly.utils.shortestStringLength(a),e=0;e<d;e++){b=a[0][e];for(var f=1;f<a.length;f++)if(b!=a[f][e])return c;" "==b&&(c=e+1)}for(f=1;f<a.length;f++)if((b=a[f][e])&&" "!=b)return c;return d};
                +Blockly.utils.commonWordSuffix=function(a,b){if(!a.length)return 0;if(1==a.length)return a[0].length;for(var c=0,d=b||Blockly.utils.shortestStringLength(a),e=0;e<d;e++){b=a[0].substr(-e-1,1);for(var f=1;f<a.length;f++)if(b!=a[f].substr(-e-1,1))return c;" "==b&&(c=e+1)}for(f=1;f<a.length;f++)if((b=a[f].charAt(a[f].length-e-1))&&" "!=b)return c;return d};Blockly.utils.tokenizeInterpolation=function(a){return Blockly.utils.tokenizeInterpolation_(a,!0)};
                +Blockly.utils.replaceMessageReferences=function(a){if(!goog.isString(a))return a;a=Blockly.utils.tokenizeInterpolation_(a,!1);return a.length?a[0]:""};Blockly.utils.checkMessageReferences=function(a){for(var b=!0,c=/%{BKY_([a-zA-Z][a-zA-Z0-9_]*)}/g,d=c.exec(a);null!=d;){var e=d[1];null==Blockly.Msg[e]&&(console.log("WARNING: No message string for %{BKY_"+e+"}."),b=!1);a=a.substring(d.index+e.length+1);d=c.exec(a)}return b};
                +Blockly.utils.tokenizeInterpolation_=function(a,b){var c=[],d=a.split("");d.push("");var e=0;a=[];for(var f=null,g=0;g<d.length;g++){var h=d[g];0==e?"%"==h?((h=a.join(""))&&c.push(h),a.length=0,e=1):a.push(h):1==e?"%"==h?(a.push(h),e=0):b&&"0"<=h&&"9">=h?(e=2,f=h,(h=a.join(""))&&c.push(h),a.length=0):"{"==h?e=3:(a.push("%",h),e=0):2==e?"0"<=h&&"9">=h?f+=h:(c.push(parseInt(f,10)),g--,e=0):3==e&&(""==h?(a.splice(0,0,"%{"),g--,e=0):"}"!=h?a.push(h):(h=a.join(""),/[a-zA-Z][a-zA-Z0-9_]*/.test(h)?(e=h.toUpperCase(),
                +(e=goog.string.startsWith(e,"BKY_")?e.substring(4):null)&&e in Blockly.Msg?(h=Blockly.Msg[e],goog.isString(h)?Array.prototype.push.apply(c,Blockly.utils.tokenizeInterpolation(h)):b?c.push(String(h)):c.push(h)):c.push("%{"+h+"}")):c.push("%{"+h+"}"),e=a.length=0))}(h=a.join(""))&&c.push(h);b=[];for(g=a.length=0;g<c.length;++g)"string"==typeof c[g]?a.push(c[g]):((h=a.join(""))&&b.push(h),a.length=0,b.push(c[g]));(h=a.join(""))&&b.push(h);a.length=0;return b};
                +Blockly.utils.genUid=function(){for(var a=Blockly.utils.genUid.soup_.length,b=[],c=0;20>c;c++)b[c]=Blockly.utils.genUid.soup_.charAt(Math.random()*a);return b.join("")};Blockly.utils.genUid.soup_="!#$%()*+,-./:;=?@[]^_`{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Blockly.utils.wrap=function(a,b){a=a.split("\n");for(var c=0;c<a.length;c++)a[c]=Blockly.utils.wrapLine_(a[c],b);return a.join("\n")};
                +Blockly.utils.wrapLine_=function(a,b){if(a.length<=b)return a;for(var c=a.trim().split(/\s+/),d=0;d<c.length;d++)c[d].length>b&&(b=c[d].length);var d=-Infinity,e=1;do{var f=d;var g=a;a=[];for(var h=c.length/e,k=1,d=0;d<c.length-1;d++)k<(d+1.5)/h?(k++,a[d]=!0):a[d]=!1;a=Blockly.utils.wrapMutate_(c,a,b);d=Blockly.utils.wrapScore_(c,a,b);a=Blockly.utils.wrapToText_(c,a);e++}while(d>f);return g};
                +Blockly.utils.wrapScore_=function(a,b,c){for(var d=[0],e=[],f=0;f<a.length;f++)d[d.length-1]+=a[f].length,!0===b[f]?(d.push(0),e.push(a[f].charAt(a[f].length-1))):!1===b[f]&&d[d.length-1]++;a=Math.max.apply(Math,d);for(f=b=0;f<d.length;f++)b-=2*Math.pow(Math.abs(c-d[f]),1.5),b-=Math.pow(a-d[f],1.5),-1!=".?!".indexOf(e[f])?b+=c/3:-1!=",;)]}".indexOf(e[f])&&(b+=c/4);1<d.length&&d[d.length-1]<=d[d.length-2]&&(b+=.5);return b};
                +Blockly.utils.wrapMutate_=function(a,b,c){for(var d=Blockly.utils.wrapScore_(a,b,c),e,f=0;f<b.length-1;f++)if(b[f]!=b[f+1]){var g=[].concat(b);g[f]=!g[f];g[f+1]=!g[f+1];var h=Blockly.utils.wrapScore_(a,g,c);h>d&&(d=h,e=g)}return e?Blockly.utils.wrapMutate_(a,e,c):b};Blockly.utils.wrapToText_=function(a,b){for(var c=[],d=0;d<a.length;d++)c.push(a[d]),void 0!==b[d]&&c.push(b[d]?"\n":" ");return c.join("")};
                +Blockly.utils.is3dSupported=function(){if(void 0!==Blockly.utils.is3dSupported.cached_)return Blockly.utils.is3dSupported.cached_;if(!goog.global.getComputedStyle)return!1;var a=document.createElement("p"),b="none",c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(a,null);for(var d in c)if(void 0!==a.style[d]){a.style[d]="translate3d(1px,1px,1px)";b=goog.global.getComputedStyle(a);
                +if(!b)return document.body.removeChild(a),!1;b=b.getPropertyValue(c[d])}document.body.removeChild(a);Blockly.utils.is3dSupported.cached_="none"!==b;return Blockly.utils.is3dSupported.cached_};Blockly.utils.insertAfter_=function(a,b){var c=b.nextSibling;b=b.parentNode;if(!b)throw"Reference node has no parent.";c?b.insertBefore(a,c):b.appendChild(a)};
                +Blockly.utils.runAfterPageLoad=function(a){if(!document)throw Error("Blockly.utils.runAfterPageLoad() requires browser document.");if("complete"===document.readyState)a();else var b=setInterval(function(){"complete"===document.readyState&&(clearInterval(b),a())},10)};Blockly.utils.setCssTransform=function(a,b){a.style.transform=b;a.style["-webkit-transform"]=b};Blockly.Grid=function(a,b){this.gridPattern_=a;this.spacing_=b.spacing;this.length_=b.length;this.line2_=(this.line1_=a.firstChild)&&this.line1_.nextSibling;this.snapToGrid_=b.snap};Blockly.Grid.prototype.scale_=1;Blockly.Grid.prototype.dispose=function(){this.gridPattern_=null};Blockly.Grid.prototype.shouldSnap=function(){return this.snapToGrid_};Blockly.Grid.prototype.getSpacing=function(){return this.spacing_};Blockly.Grid.prototype.getPatternId=function(){return this.gridPattern_.id};
                +Blockly.Grid.prototype.update=function(a){this.scale_=a;var b=this.spacing_*a||100;this.gridPattern_.setAttribute("width",b);this.gridPattern_.setAttribute("height",b);var b=Math.floor(this.spacing_/2)+.5,c=b-this.length_/2,d=b+this.length_/2,b=b*a,c=c*a,d=d*a;this.setLineAttributes_(this.line1_,a,c,d,b,b);this.setLineAttributes_(this.line2_,a,b,b,c,d)};
                +Blockly.Grid.prototype.setLineAttributes_=function(a,b,c,d,e,f){a&&(a.setAttribute("stroke-width",b),a.setAttribute("x1",c),a.setAttribute("y1",e),a.setAttribute("x2",d),a.setAttribute("y2",f))};Blockly.Grid.prototype.moveTo=function(a,b){this.gridPattern_.setAttribute("x",a);this.gridPattern_.setAttribute("y",b);(goog.userAgent.IE||goog.userAgent.EDGE)&&this.update(this.scale_)};
                +Blockly.Grid.createDom=function(a,b,c){a=Blockly.utils.createSvgElement("pattern",{id:"blocklyGridPattern"+a,patternUnits:"userSpaceOnUse"},c);0<b.length&&0<b.spacing&&(Blockly.utils.createSvgElement("line",{stroke:b.colour},a),1<b.length&&Blockly.utils.createSvgElement("line",{stroke:b.colour},a));return a};Blockly.Options=function(a){var b,c,d,e,f,g=!!a.readOnly;if(g){var h=null;var k=b=c=d=e=f=!1}else h=Blockly.Options.parseToolboxTree(a.toolbox),f=!(!h||!h.getElementsByTagName("category").length),e=a.trashcan,void 0===e&&(e=f),d=a.collapse,void 0===d&&(d=f),c=a.comments,void 0===c&&(c=f),b=a.disable,void 0===b&&(b=f),k=a.sounds,void 0===k&&(k=!0);var l=!!a.rtl,m=a.horizontalLayout;void 0===m&&(m=!1);var n=a.toolboxPosition;n="end"===n?!1:!0;var p=m?n?Blockly.TOOLBOX_AT_TOP:Blockly.TOOLBOX_AT_BOTTOM:
                +n==l?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT;var q=a.scrollbars;void 0===q&&(q=f);var t=a.css;void 0===t&&(t=!0);var r="https://blockly-demo.appspot.com/static/media/";a.media?r=a.media:a.path&&(r=a.path+"media/");n=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex;this.RTL=l;this.oneBasedIndex=n;this.collapse=d;this.comments=c;this.disable=b;this.readOnly=g;this.maxBlocks=a.maxBlocks||Infinity;this.pathToMedia=r;this.hasCategories=f;this.hasScrollbars=q;this.hasTrashcan=e;this.hasSounds=k;this.hasCss=
                +t;this.horizontalLayout=m;this.languageTree=h;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=p};Blockly.Options.prototype.parentWorkspace=null;Blockly.Options.prototype.setMetrics=null;Blockly.Options.prototype.getMetrics=null;
                +Blockly.Options.parseZoomOptions_=function(a){a=a.zoom||{};var b={};b.controls=void 0===a.controls?!1:!!a.controls;b.wheel=void 0===a.wheel?!1:!!a.wheel;b.startScale=void 0===a.startScale?1:parseFloat(a.startScale);b.maxScale=void 0===a.maxScale?3:parseFloat(a.maxScale);b.minScale=void 0===a.minScale?.3:parseFloat(a.minScale);b.scaleSpeed=void 0===a.scaleSpeed?1.2:parseFloat(a.scaleSpeed);return b};
                +Blockly.Options.parseGridOptions_=function(a){a=a.grid||{};var b={};b.spacing=parseFloat(a.spacing)||0;b.colour=a.colour||"#888";b.length=parseFloat(a.length)||1;b.snap=0<b.spacing&&!!a.snap;return b};Blockly.Options.parseToolboxTree=function(a){a?("string"!=typeof a&&("undefined"==typeof XSLTProcessor&&a.outerHTML?a=a.outerHTML:a instanceof Element||(a=null)),"string"==typeof a&&(a=Blockly.Xml.textToDom(a))):a=null;return a};Blockly.ScrollbarPair=function(a){this.workspace_=a;this.hScroll=new Blockly.Scrollbar(a,!0,!0,"blocklyMainWorkspaceScrollbar");this.vScroll=new Blockly.Scrollbar(a,!1,!0,"blocklyMainWorkspaceScrollbar");this.corner_=Blockly.utils.createSvgElement("rect",{height:Blockly.Scrollbar.scrollbarThickness,width:Blockly.Scrollbar.scrollbarThickness,"class":"blocklyScrollbarBackground"},null);Blockly.utils.insertAfter_(this.corner_,a.getBubbleCanvas())};Blockly.ScrollbarPair.prototype.oldHostMetrics_=null;
                +Blockly.ScrollbarPair.prototype.dispose=function(){goog.dom.removeNode(this.corner_);this.oldHostMetrics_=this.workspace_=this.corner_=null;this.hScroll.dispose();this.hScroll=null;this.vScroll.dispose();this.vScroll=null};
                +Blockly.ScrollbarPair.prototype.resize=function(){var a=this.workspace_.getMetrics();if(a){var b=!1,c=!1;this.oldHostMetrics_&&this.oldHostMetrics_.viewWidth==a.viewWidth&&this.oldHostMetrics_.viewHeight==a.viewHeight&&this.oldHostMetrics_.absoluteTop==a.absoluteTop&&this.oldHostMetrics_.absoluteLeft==a.absoluteLeft?(this.oldHostMetrics_&&this.oldHostMetrics_.contentWidth==a.contentWidth&&this.oldHostMetrics_.viewLeft==a.viewLeft&&this.oldHostMetrics_.contentLeft==a.contentLeft||(b=!0),this.oldHostMetrics_&&
                +this.oldHostMetrics_.contentHeight==a.contentHeight&&this.oldHostMetrics_.viewTop==a.viewTop&&this.oldHostMetrics_.contentTop==a.contentTop||(c=!0)):c=b=!0;b&&this.hScroll.resize(a);c&&this.vScroll.resize(a);this.oldHostMetrics_&&this.oldHostMetrics_.viewWidth==a.viewWidth&&this.oldHostMetrics_.absoluteLeft==a.absoluteLeft||this.corner_.setAttribute("x",this.vScroll.position_.x);this.oldHostMetrics_&&this.oldHostMetrics_.viewHeight==a.viewHeight&&this.oldHostMetrics_.absoluteTop==a.absoluteTop||this.corner_.setAttribute("y",
                +this.hScroll.position_.y);this.oldHostMetrics_=a}};Blockly.ScrollbarPair.prototype.set=function(a,b){var c={};a*=this.hScroll.ratio_;b*=this.vScroll.ratio_;var d=this.vScroll.scrollViewSize_;c.x=this.getRatio_(a,this.hScroll.scrollViewSize_);c.y=this.getRatio_(b,d);this.workspace_.setMetrics(c);this.hScroll.setHandlePosition(a);this.vScroll.setHandlePosition(b)};Blockly.ScrollbarPair.prototype.getRatio_=function(a,b){a/=b;return isNaN(a)?0:a};
                +Blockly.Scrollbar=function(a,b,c,d){this.workspace_=a;this.pair_=c||!1;this.horizontal_=b;this.oldHostMetrics_=null;this.createDom_(d);this.position_=new goog.math.Coordinate(0,0);b?(this.svgBackground_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness),this.outerSvg_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness),this.svgHandle_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness-5),this.svgHandle_.setAttribute("y",2.5),this.lengthAttribute_="width",this.positionAttribute_=
                +"x"):(this.svgBackground_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness),this.outerSvg_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness),this.svgHandle_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness-5),this.svgHandle_.setAttribute("x",2.5),this.lengthAttribute_="height",this.positionAttribute_="y");this.onMouseDownBarWrapper_=Blockly.bindEventWithChecks_(this.svgBackground_,"mousedown",this,this.onMouseDownBar_);this.onMouseDownHandleWrapper_=Blockly.bindEventWithChecks_(this.svgHandle_,
                +"mousedown",this,this.onMouseDownHandle_)};Blockly.Scrollbar.prototype.origin_=new goog.math.Coordinate(0,0);Blockly.Scrollbar.prototype.scrollViewSize_=0;Blockly.Scrollbar.prototype.handleLength_=0;Blockly.Scrollbar.prototype.handlePosition_=0;Blockly.Scrollbar.prototype.isVisible_=!0;Blockly.Scrollbar.prototype.containerVisible_=!0;Blockly.Scrollbar.scrollbarThickness=15;goog.events.BrowserFeature.TOUCH_ENABLED&&(Blockly.Scrollbar.scrollbarThickness=25);
                +Blockly.Scrollbar.metricsAreEquivalent_=function(a,b){return a&&b&&a.viewWidth==b.viewWidth&&a.viewHeight==b.viewHeight&&a.viewLeft==b.viewLeft&&a.viewTop==b.viewTop&&a.absoluteTop==b.absoluteTop&&a.absoluteLeft==b.absoluteLeft&&a.contentWidth==b.contentWidth&&a.contentHeight==b.contentHeight&&a.contentLeft==b.contentLeft&&a.contentTop==b.contentTop?!0:!1};
                +Blockly.Scrollbar.prototype.dispose=function(){this.cleanUp_();Blockly.unbindEvent_(this.onMouseDownBarWrapper_);this.onMouseDownBarWrapper_=null;Blockly.unbindEvent_(this.onMouseDownHandleWrapper_);this.onMouseDownHandleWrapper_=null;goog.dom.removeNode(this.outerSvg_);this.workspace_=this.svgHandle_=this.svgBackground_=this.svgGroup_=this.outerSvg_=null};Blockly.Scrollbar.prototype.setHandleLength_=function(a){this.handleLength_=a;this.svgHandle_.setAttribute(this.lengthAttribute_,this.handleLength_)};
                +Blockly.Scrollbar.prototype.setHandlePosition=function(a){this.handlePosition_=a;this.svgHandle_.setAttribute(this.positionAttribute_,this.handlePosition_)};Blockly.Scrollbar.prototype.setScrollViewSize_=function(a){this.scrollViewSize_=a;this.outerSvg_.setAttribute(this.lengthAttribute_,this.scrollViewSize_);this.svgBackground_.setAttribute(this.lengthAttribute_,this.scrollViewSize_)};Blockly.ScrollbarPair.prototype.setContainerVisible=function(a){this.hScroll.setContainerVisible(a);this.vScroll.setContainerVisible(a)};
                +Blockly.Scrollbar.prototype.setPosition=function(a,b){this.position_.x=a;this.position_.y=b;Blockly.utils.setCssTransform(this.outerSvg_,"translate("+(this.position_.x+this.origin_.x)+"px,"+(this.position_.y+this.origin_.y)+"px)")};Blockly.Scrollbar.prototype.resize=function(a){if(!a&&(a=this.workspace_.getMetrics(),!a))return;Blockly.Scrollbar.metricsAreEquivalent_(a,this.oldHostMetrics_)||(this.oldHostMetrics_=a,this.horizontal_?this.resizeHorizontal_(a):this.resizeVertical_(a),this.onScroll_())};
                +Blockly.Scrollbar.prototype.resizeHorizontal_=function(a){this.resizeViewHorizontal(a)};Blockly.Scrollbar.prototype.resizeViewHorizontal=function(a){var b=a.viewWidth-1;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollViewSize_(Math.max(0,b));b=a.absoluteLeft+.5;this.pair_&&this.workspace_.RTL&&(b+=Blockly.Scrollbar.scrollbarThickness);this.setPosition(b,a.absoluteTop+a.viewHeight-Blockly.Scrollbar.scrollbarThickness-.5);this.resizeContentHorizontal(a)};
                +Blockly.Scrollbar.prototype.resizeContentHorizontal=function(a){this.pair_||this.setVisible(this.scrollViewSize_<a.contentWidth);this.ratio_=this.scrollViewSize_/a.contentWidth;if(-Infinity==this.ratio_||Infinity==this.ratio_||isNaN(this.ratio_))this.ratio_=0;this.setHandleLength_(Math.max(0,a.viewWidth*this.ratio_));this.setHandlePosition(this.constrainHandle_((a.viewLeft-a.contentLeft)*this.ratio_))};Blockly.Scrollbar.prototype.resizeVertical_=function(a){this.resizeViewVertical(a)};
                +Blockly.Scrollbar.prototype.resizeViewVertical=function(a){var b=a.viewHeight-1;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollViewSize_(Math.max(0,b));b=a.absoluteLeft+.5;this.workspace_.RTL||(b+=a.viewWidth-Blockly.Scrollbar.scrollbarThickness-1);this.setPosition(b,a.absoluteTop+.5);this.resizeContentVertical(a)};
                +Blockly.Scrollbar.prototype.resizeContentVertical=function(a){this.pair_||this.setVisible(this.scrollViewSize_<a.contentHeight);this.ratio_=this.scrollViewSize_/a.contentHeight;if(-Infinity==this.ratio_||Infinity==this.ratio_||isNaN(this.ratio_))this.ratio_=0;this.setHandleLength_(Math.max(0,a.viewHeight*this.ratio_));this.setHandlePosition(this.constrainHandle_((a.viewTop-a.contentTop)*this.ratio_))};
                +Blockly.Scrollbar.prototype.createDom_=function(a){var b="blocklyScrollbar"+(this.horizontal_?"Horizontal":"Vertical");a&&(b+=" "+a);this.outerSvg_=Blockly.utils.createSvgElement("svg",{"class":b},null);this.svgGroup_=Blockly.utils.createSvgElement("g",{},this.outerSvg_);this.svgBackground_=Blockly.utils.createSvgElement("rect",{"class":"blocklyScrollbarBackground"},this.svgGroup_);a=Math.floor((Blockly.Scrollbar.scrollbarThickness-5)/2);this.svgHandle_=Blockly.utils.createSvgElement("rect",{"class":"blocklyScrollbarHandle",
                +rx:a,ry:a},this.svgGroup_);Blockly.utils.insertAfter_(this.outerSvg_,this.workspace_.getParentSvg())};Blockly.Scrollbar.prototype.isVisible=function(){return this.isVisible_};Blockly.Scrollbar.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};Blockly.Scrollbar.prototype.setVisible=function(a){var b=a!=this.isVisible();if(this.pair_)throw"Unable to toggle visibility of paired scrollbars.";this.isVisible_=a;b&&this.updateDisplay_()};
                +Blockly.Scrollbar.prototype.updateDisplay_=function(){this.containerVisible_&&this.isVisible()?this.outerSvg_.setAttribute("display","block"):this.outerSvg_.setAttribute("display","none")};
                +Blockly.Scrollbar.prototype.onMouseDownBar_=function(a){this.workspace_.markFocused();Blockly.Touch.clearTouchIdentifier();this.cleanUp_();if(Blockly.utils.isRightButton(a))a.stopPropagation();else{var b=Blockly.utils.mouseToSvg(a,this.workspace_.getParentSvg(),this.workspace_.getInverseScreenCTM()),b=this.horizontal_?b.x:b.y,c=Blockly.utils.getInjectionDivXY_(this.svgHandle_),c=this.horizontal_?c.x:c.y,d=this.handlePosition_,e=.95*this.handleLength_;b<=c?d-=e:b>=c+this.handleLength_&&(d+=e);this.setHandlePosition(this.constrainHandle_(d));
                +this.onScroll_();a.stopPropagation();a.preventDefault()}};
                +Blockly.Scrollbar.prototype.onMouseDownHandle_=function(a){this.workspace_.markFocused();this.cleanUp_();Blockly.utils.isRightButton(a)?a.stopPropagation():(this.startDragHandle=this.handlePosition_,this.workspace_.setupDragSurface(),this.startDragMouse=this.horizontal_?a.clientX:a.clientY,Blockly.Scrollbar.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,this.onMouseUpHandle_),Blockly.Scrollbar.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",this,this.onMouseMoveHandle_),
                +a.stopPropagation(),a.preventDefault())};Blockly.Scrollbar.prototype.onMouseMoveHandle_=function(a){this.setHandlePosition(this.constrainHandle_(this.startDragHandle+((this.horizontal_?a.clientX:a.clientY)-this.startDragMouse)));this.onScroll_()};Blockly.Scrollbar.prototype.onMouseUpHandle_=function(){this.workspace_.resetDragSurface();Blockly.Touch.clearTouchIdentifier();this.cleanUp_()};
                +Blockly.Scrollbar.prototype.cleanUp_=function(){Blockly.hideChaff(!0);Blockly.Scrollbar.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_),Blockly.Scrollbar.onMouseUpWrapper_=null);Blockly.Scrollbar.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseMoveWrapper_),Blockly.Scrollbar.onMouseMoveWrapper_=null)};
                +Blockly.Scrollbar.prototype.constrainHandle_=function(a){return a=0>=a||isNaN(a)||this.scrollViewSize_<this.handleLength_?0:Math.min(a,this.scrollViewSize_-this.handleLength_)};Blockly.Scrollbar.prototype.onScroll_=function(){var a=this.handlePosition_/this.scrollViewSize_;isNaN(a)&&(a=0);var b={};this.horizontal_?b.x=a:b.y=a;this.workspace_.setMetrics(b)};Blockly.Scrollbar.prototype.set=function(a){this.setHandlePosition(this.constrainHandle_(a*this.ratio_));this.onScroll_()};
                +Blockly.Scrollbar.prototype.setOrigin=function(a,b){this.origin_=new goog.math.Coordinate(a,b)};Blockly.Trashcan=function(a){this.workspace_=a};Blockly.Trashcan.prototype.WIDTH_=47;Blockly.Trashcan.prototype.BODY_HEIGHT_=44;Blockly.Trashcan.prototype.LID_HEIGHT_=16;Blockly.Trashcan.prototype.MARGIN_BOTTOM_=20;Blockly.Trashcan.prototype.MARGIN_SIDE_=20;Blockly.Trashcan.prototype.MARGIN_HOTSPOT_=10;Blockly.Trashcan.prototype.SPRITE_LEFT_=0;Blockly.Trashcan.prototype.SPRITE_TOP_=32;Blockly.Trashcan.prototype.isOpen=!1;Blockly.Trashcan.prototype.svgGroup_=null;
                +Blockly.Trashcan.prototype.svgLid_=null;Blockly.Trashcan.prototype.lidTask_=0;Blockly.Trashcan.prototype.lidOpen_=0;Blockly.Trashcan.prototype.left_=0;Blockly.Trashcan.prototype.top_=0;
                +Blockly.Trashcan.prototype.createDom=function(){this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyTrash"},null);var a=String(Math.random()).substring(2);var b=Blockly.utils.createSvgElement("clipPath",{id:"blocklyTrashBodyClipPath"+a},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:this.WIDTH_,height:this.BODY_HEIGHT_,y:this.LID_HEIGHT_},b);Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,y:-this.SPRITE_TOP_,
                +"clip-path":"url(#blocklyTrashBodyClipPath"+a+")"},this.svgGroup_).setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);b=Blockly.utils.createSvgElement("clipPath",{id:"blocklyTrashLidClipPath"+a},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:this.WIDTH_,height:this.LID_HEIGHT_},b);this.svgLid_=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,y:-this.SPRITE_TOP_,
                +"clip-path":"url(#blocklyTrashLidClipPath"+a+")"},this.svgGroup_);this.svgLid_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.click);this.animateLid_();return this.svgGroup_};Blockly.Trashcan.prototype.init=function(a){this.bottom_=this.MARGIN_BOTTOM_+a;this.setOpen_(!1);return this.bottom_+this.BODY_HEIGHT_+this.LID_HEIGHT_};
                +Blockly.Trashcan.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.workspace_=this.svgLid_=null;goog.Timer.clear(this.lidTask_)};
                +Blockly.Trashcan.prototype.position=function(){var a=this.workspace_.getMetrics();a&&(this.workspace_.RTL?(this.left_=this.MARGIN_SIDE_+Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(this.left_+=a.flyoutWidth,this.workspace_.toolbox_&&(this.left_+=a.absoluteLeft))):(this.left_=a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_-Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(this.left_-=a.flyoutWidth)),this.top_=a.viewHeight+
                +a.absoluteTop-(this.BODY_HEIGHT_+this.LID_HEIGHT_)-this.bottom_,a.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM&&(this.top_-=a.flyoutHeight),this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")"))};
                +Blockly.Trashcan.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect();return new goog.math.Rect(a.left+this.SPRITE_LEFT_-this.MARGIN_HOTSPOT_,a.top+this.SPRITE_TOP_-this.MARGIN_HOTSPOT_,this.WIDTH_+2*this.MARGIN_HOTSPOT_,this.LID_HEIGHT_+this.BODY_HEIGHT_+2*this.MARGIN_HOTSPOT_)};Blockly.Trashcan.prototype.setOpen_=function(a){this.isOpen!=a&&(goog.Timer.clear(this.lidTask_),this.isOpen=a,this.animateLid_())};
                +Blockly.Trashcan.prototype.animateLid_=function(){this.lidOpen_+=this.isOpen?.2:-.2;this.lidOpen_=goog.math.clamp(this.lidOpen_,0,1);var a=45*this.lidOpen_;this.svgLid_.setAttribute("transform","rotate("+(this.workspace_.RTL?-a:a)+","+(this.workspace_.RTL?4:this.WIDTH_-4)+","+(this.LID_HEIGHT_-2)+")");a=goog.math.lerp(.4,.8,this.lidOpen_);this.svgGroup_.style.opacity=a;0<this.lidOpen_&&1>this.lidOpen_&&(this.lidTask_=goog.Timer.callOnce(this.animateLid_,20,this))};
                +Blockly.Trashcan.prototype.close=function(){this.setOpen_(!1)};Blockly.Trashcan.prototype.click=function(){var a=this.workspace_.startScrollX-this.workspace_.scrollX,b=this.workspace_.startScrollY-this.workspace_.scrollY;Math.sqrt(a*a+b*b)>Blockly.DRAG_RADIUS||console.log("TODO: Inspect trash.")};Blockly.WorkspaceAudio=function(a){this.parentWorkspace_=a;this.SOUNDS_=Object.create(null)};Blockly.WorkspaceAudio.prototype.lastSound_=null;Blockly.WorkspaceAudio.prototype.dispose=function(){this.SOUNDS_=this.parentWorkspace_=null};Blockly.WorkspaceAudio.prototype.load=function(a,b){if(a.length){try{var c=new window.Audio}catch(h){return}for(var d,e=0;e<a.length;e++){var f=a[e],g=f.match(/\.(\w+)$/);if(g&&c.canPlayType("audio/"+g[1])){d=new window.Audio(f);break}}d&&d.play&&(this.SOUNDS_[b]=d)}};
                +Blockly.WorkspaceAudio.prototype.preload=function(){for(var a in this.SOUNDS_){var b=this.SOUNDS_[a];b.volume=.01;b.play();b.pause();if(goog.userAgent.IPAD||goog.userAgent.IPHONE)break}};
                +Blockly.WorkspaceAudio.prototype.play=function(a,b){var c=this.SOUNDS_[a];c?(a=new Date,null!=this.lastSound_&&a-this.lastSound_<Blockly.SOUND_LIMIT||(this.lastSound_=a,c=goog.userAgent.DOCUMENT_MODE&&9===goog.userAgent.DOCUMENT_MODE||goog.userAgent.IPAD||goog.userAgent.ANDROID?c:c.cloneNode(),c.volume=void 0===b?1:b,c.play())):this.parentWorkspace_&&this.parentWorkspace_.getAudioManager().play(a,b)};Blockly.WorkspaceDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.dragGroup_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.container_=null;
                +Blockly.WorkspaceDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=Blockly.utils.createSvgElement("svg",{xmlns:Blockly.SVG_NS,"xmlns:html":Blockly.HTML_NS,"xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklyWsDragSurface"},null),this.container_.appendChild(this.SVG_))};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.translateSurface=function(a,b){a=a.toFixed(0);b=b.toFixed(0);this.SVG_.style.display="block";Blockly.utils.setCssTransform(this.SVG_,"translate3d("+a+"px, "+b+"px, 0px)")};Blockly.WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation=function(){return Blockly.utils.getRelativeXY(this.SVG_)};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide=function(a){var b=this.SVG_.childNodes[0],c=this.SVG_.childNodes[1];if(!(b&&c&&Blockly.utils.hasClass(b,"blocklyBlockCanvas")&&Blockly.utils.hasClass(c,"blocklyBubbleCanvas")))throw"Couldn't clear and hide the drag surface.  A node was missing.";null!=this.previousSibling_?Blockly.utils.insertAfter_(b,this.previousSibling_):a.insertBefore(b,a.firstChild);Blockly.utils.insertAfter_(c,b);this.SVG_.style.display="none";goog.asserts.assert(0==this.SVG_.childNodes.length,
                +"Drag surface was not cleared.");Blockly.utils.setCssTransform(this.SVG_,"");this.previousSibling_=null};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.setContentsAndShow=function(a,b,c,d,e,f){goog.asserts.assert(0==this.SVG_.childNodes.length,"Already dragging a block.");this.previousSibling_=c;a.setAttribute("transform","translate(0, 0) scale("+f+")");b.setAttribute("transform","translate(0, 0) scale("+f+")");this.SVG_.setAttribute("width",d);this.SVG_.setAttribute("height",e);this.SVG_.appendChild(a);this.SVG_.appendChild(b);this.SVG_.style.display="block"};Blockly.Xml={};Blockly.Xml.workspaceToDom=function(a,b){var c=goog.dom.createDom("xml");c.appendChild(Blockly.Xml.variablesToDom(a.getAllVariables()));a=a.getTopBlocks(!0);for(var d=0,e;e=a[d];d++)c.appendChild(Blockly.Xml.blockToDomWithXY(e,b));return c};Blockly.Xml.variablesToDom=function(a){for(var b=goog.dom.createDom("variables"),c=0,d;d=a[c];c++){var e=goog.dom.createDom("variable",null,d.name);e.setAttribute("type",d.type);e.setAttribute("id",d.getId());b.appendChild(e)}return b};
                +Blockly.Xml.blockToDomWithXY=function(a,b){var c;a.workspace.RTL&&(c=a.workspace.getWidth());b=Blockly.Xml.blockToDom(a,b);var d=a.getRelativeToSurfaceXY();b.setAttribute("x",Math.round(a.workspace.RTL?c-d.x:d.x));b.setAttribute("y",Math.round(d.y));return b};
                +Blockly.Xml.blockToDom=function(a,b){var c,d=goog.dom.createDom(a.isShadow()?"shadow":"block");d.setAttribute("type",a.type);b||d.setAttribute("id",a.id);if(a.mutationToDom){var e=a.mutationToDom();e&&(e.hasChildNodes()||e.hasAttributes())&&d.appendChild(e)}for(var e=0,f;f=a.inputList[e];e++){var g=0;for(var h;h=f.fieldRow[g];g++){var k=h;k.name&&k.EDITABLE&&(h=goog.dom.createDom("field",null,k.getValue()),h.setAttribute("name",k.name),k instanceof Blockly.FieldVariable&&(k=a.workspace.getVariable(k.getValue()))&&
                +(h.setAttribute("id",k.getId()),h.setAttribute("variableType",k.type)),d.appendChild(h))}}if(e=a.getCommentText())e=goog.dom.createDom("comment",null,e),"object"==typeof a.comment&&(e.setAttribute("pinned",a.comment.isVisible()),f=a.comment.getBubbleSize(),e.setAttribute("h",f.height),e.setAttribute("w",f.width)),d.appendChild(e);a.data&&(e=goog.dom.createDom("data",null,a.data),d.appendChild(e));for(e=0;f=a.inputList[e];e++)h=!0,f.type!=Blockly.DUMMY_INPUT&&(k=f.connection.targetBlock(),f.type==
                +Blockly.INPUT_VALUE?c=goog.dom.createDom("value"):f.type==Blockly.NEXT_STATEMENT&&(c=goog.dom.createDom("statement")),g=f.connection.getShadowDom(),!g||k&&k.isShadow()||c.appendChild(Blockly.Xml.cloneShadow_(g)),k&&(c.appendChild(Blockly.Xml.blockToDom(k,b)),h=!1),c.setAttribute("name",f.name),h||d.appendChild(c));a.inputsInlineDefault!=a.inputsInline&&d.setAttribute("inline",a.inputsInline);a.isCollapsed()&&d.setAttribute("collapsed",!0);a.disabled&&d.setAttribute("disabled",!0);a.isDeletable()||
                +a.isShadow()||d.setAttribute("deletable",!1);a.isMovable()||a.isShadow()||d.setAttribute("movable",!1);a.isEditable()||d.setAttribute("editable",!1);if(e=a.getNextBlock())c=goog.dom.createDom("next",null,Blockly.Xml.blockToDom(e,b)),d.appendChild(c);g=a.nextConnection&&a.nextConnection.getShadowDom();!g||e&&e.isShadow()||c.appendChild(Blockly.Xml.cloneShadow_(g));return d};
                +Blockly.Xml.cloneShadow_=function(a){for(var b=a=a.cloneNode(!0),c;b;)if(b.firstChild)b=b.firstChild;else{for(;b&&!b.nextSibling;)c=b,b=b.parentNode,3==c.nodeType&&""==c.data.trim()&&b.firstChild!=c&&goog.dom.removeNode(c);b&&(c=b,b=b.nextSibling,3==c.nodeType&&""==c.data.trim()&&goog.dom.removeNode(c))}return a};Blockly.Xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};
                +Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c<a.length;c++){var d=a[c];"/"==d[0]&&(b=b.substring(2));a[c]=b+"<"+d;"/"!=d[0]&&"/>"!=d.slice(-2)&&(b+="  ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1</$2>");return a.replace(/^\n/,"")};
                +Blockly.Xml.textToDom=function(a){(a=(new DOMParser).parseFromString(a,"text/xml"))&&a.firstChild&&"xml"==a.firstChild.nodeName.toLowerCase()&&a.firstChild===a.lastChild||goog.asserts.fail("Blockly.Xml.textToDom did not obtain a valid XML tree.");return a.firstChild};
                +Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];Blockly.Field.startCache();var e=a.childNodes.length,f=Blockly.Events.getGroup();f||Blockly.Events.setGroup(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var g=!0;try{for(var h=0;h<e;h++){var k=a.childNodes[h],l=k.nodeName.toLowerCase();if("block"==l||"shadow"==l&&!Blockly.Events.recordUndo){var m=
                +Blockly.Xml.domToBlock(k,b);c.push(m.id);var n=parseInt(k.getAttribute("x"),10),p=parseInt(k.getAttribute("y"),10);isNaN(n)||isNaN(p)||m.moveBy(b.RTL?d-n:n,p);g=!1}else if("shadow"==l)goog.asserts.fail("Shadow block cannot be a top-level block."),g=!1;else if("variables"==l){if(g)Blockly.Xml.domToVariables(k,b);else throw Error("'variables' tag must exist once before block and shadow tag elements in the workspace XML, but it was found in another location.");g=!1}}}finally{f||Blockly.Events.setGroup(!1),
                +Blockly.Field.stopCache()}b.updateVariableStore(!1);b.setResizesEnabled&&b.setResizesEnabled(!0);return c};
                +Blockly.Xml.appendDomToWorkspace=function(a,b){if(b.hasOwnProperty("scale")){var c=Blockly.BlockSvg.TAB_WIDTH;try{Blockly.BlockSvg.TAB_WIDTH=0;var d=b.getBlocksBoundingBox()}finally{Blockly.BlockSvg.TAB_WIDTH=c}}a=Blockly.Xml.domToWorkspace(a,b);if(d&&d.height){var c=d.y+d.height;var e=d.x;var f=Infinity,g=Infinity;for(d=0;d<a.length;d++){var h=b.getBlockById(a[d]).getRelativeToSurfaceXY();h.y<g&&(g=h.y);h.x<f&&(f=h.x)}c=c-g+Blockly.BlockSvg.SEP_SPACE_Y;e-=f;var k;b.RTL&&(k=b.getWidth());for(d=0;d<
                +a.length;d++)b.getBlockById(a[d]).moveBy(b.RTL?k-e:e,c)}return a};
                +Blockly.Xml.domToBlock=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToBlock, swap the arguments.")}Blockly.Events.disable();try{var d=Blockly.Xml.domToBlockHeadless_(a,b);if(b.rendered){d.setConnectionsHidden(!0);for(var e=d.getDescendants(),f=e.length-1;0<=f;f--)e[f].initSvg();for(f=e.length-1;0<=f;f--)e[f].render(!1);setTimeout(function(){d.workspace&&d.setConnectionsHidden(!1)},1);d.updateDisabled();b.resizeContents()}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&
                +Blockly.Events.fire(new Blockly.Events.BlockCreate(d));return d};Blockly.Xml.domToVariables=function(a,b){for(var c=0,d;d=a.children[c];c++){var e=d.getAttribute("type"),f=d.getAttribute("id");d=d.textContent;if(null===e)throw Error("Variable with id, "+f+" is without a type");b.createVariable(d,e,f)}};
                +Blockly.Xml.domToBlockHeadless_=function(a,b){var c=null,d=a.getAttribute("type");goog.asserts.assert(d,"Block type unspecified: %s",a.outerHTML);for(var e=a.getAttribute("id"),c=b.newBlock(d,e),f=null,g=0,h;h=a.childNodes[g];g++)if(3!=h.nodeType){for(var k=null,l=null,f=0,m;m=h.childNodes[f];f++)1==m.nodeType&&("block"==m.nodeName.toLowerCase()?k=m:"shadow"==m.nodeName.toLowerCase()&&(l=m));!k&&l&&(k=l);f=h.getAttribute("name");switch(h.nodeName.toLowerCase()){case "mutation":c.domToMutation&&(c.domToMutation(h),
                +c.initSvg&&c.initSvg());break;case "comment":c.setCommentText(h.textContent);var n=h.getAttribute("pinned");n&&!c.isInFlyout&&setTimeout(function(){c.comment&&c.comment.setVisible&&c.comment.setVisible("true"==n)},1);f=parseInt(h.getAttribute("w"),10);h=parseInt(h.getAttribute("h"),10);!isNaN(f)&&!isNaN(h)&&c.comment&&c.comment.setVisible&&c.comment.setBubbleSize(f,h);break;case "data":c.data=h.textContent;break;case "title":case "field":k=c.getField(f);l=h.textContent;if(k instanceof Blockly.FieldVariable){m=
                +h.getAttribute("variableType")||"";var p=b.getVariable(l);p||(p=b.createVariable(l,m,h.getAttribute(e)));if(null!==m&&m!==p.type)throw Error("Serialized variable type with id '"+p.getId()+"' had type "+p.type+", and does not match variable field that references it: "+Blockly.Xml.domToText(h)+".");}if(!k){console.warn("Ignoring non-existent field "+f+" in block "+d);break}k.setValue(l);break;case "value":case "statement":h=c.getInput(f);if(!h){console.warn("Ignoring non-existent input "+f+" in block "+
                +d);break}l&&h.connection.setShadowDom(l);k&&(f=Blockly.Xml.domToBlockHeadless_(k,b),f.outputConnection?h.connection.connect(f.outputConnection):f.previousConnection?h.connection.connect(f.previousConnection):goog.asserts.fail("Child block does not have output or previous statement."));break;case "next":l&&c.nextConnection&&c.nextConnection.setShadowDom(l);k&&(goog.asserts.assert(c.nextConnection,"Next statement does not exist."),goog.asserts.assert(!c.nextConnection.isConnected(),"Next statement is already connected."),
                +f=Blockly.Xml.domToBlockHeadless_(k,b),goog.asserts.assert(f.previousConnection,"Next block does not have previous statement."),c.nextConnection.connect(f.previousConnection));break;default:console.warn("Ignoring unknown tag: "+h.nodeName)}}(g=a.getAttribute("inline"))&&c.setInputsInline("true"==g);(g=a.getAttribute("disabled"))&&c.setDisabled("true"==g);(g=a.getAttribute("deletable"))&&c.setDeletable("true"==g);(g=a.getAttribute("movable"))&&c.setMovable("true"==g);(g=a.getAttribute("editable"))&&
                +c.setEditable("true"==g);(g=a.getAttribute("collapsed"))&&c.setCollapsed("true"==g);if("shadow"==a.nodeName.toLowerCase()){a=c.getChildren();for(g=0;b=a[g];g++)goog.asserts.assert(b.isShadow(),"Shadow block not allowed non-shadow child.");goog.asserts.assert(0==c.getVars().length,"Shadow blocks cannot have variable fields.");c.setShadow(!0)}return c};Blockly.Xml.deleteNext=function(a){for(var b=0,c;c=a.childNodes[b];b++)if("next"==c.nodeName.toLowerCase()){a.removeChild(c);break}};
                +goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Xml||(goog.global.Blockly.Xml={});goog.global.Blockly.Xml.domToText=Blockly.Xml.domToText;goog.global.Blockly.Xml.domToWorkspace=Blockly.Xml.domToWorkspace;goog.global.Blockly.Xml.textToDom=Blockly.Xml.textToDom;goog.global.Blockly.Xml.workspaceToDom=Blockly.Xml.workspaceToDom;/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2015 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.ZoomControls=function(a){this.workspace_=a};Blockly.ZoomControls.prototype.WIDTH_=32;Blockly.ZoomControls.prototype.HEIGHT_=110;Blockly.ZoomControls.prototype.MARGIN_BOTTOM_=20;Blockly.ZoomControls.prototype.MARGIN_SIDE_=20;Blockly.ZoomControls.prototype.svgGroup_=null;Blockly.ZoomControls.prototype.left_=0;Blockly.ZoomControls.prototype.top_=0;
                +Blockly.ZoomControls.prototype.createDom=function(){var a=this.workspace_;this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyZoom"},null);var b=String(Math.random()).substring(2);var c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoomoutClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32,y:77},c);var d=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-64,y:-15,"clip-path":"url(#blocklyZoomoutClipPath"+
                +b+")"},this.svgGroup_);d.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoominClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32,y:43},c);var e=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-32,y:-49,"clip-path":"url(#blocklyZoominClipPath"+b+")"},this.svgGroup_);e.setAttributeNS("http://www.w3.org/1999/xlink",
                +"xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoomresetClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32},c);c=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,y:-92,"clip-path":"url(#blocklyZoomresetClipPath"+b+")"},this.svgGroup_);c.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);Blockly.bindEventWithChecks_(c,
                +"mousedown",null,function(b){a.markFocused();a.setScale(a.options.zoomOptions.startScale);a.scrollCenter();Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()});Blockly.bindEventWithChecks_(e,"mousedown",null,function(b){a.markFocused();a.zoomCenter(1);Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()});Blockly.bindEventWithChecks_(d,"mousedown",null,function(b){a.markFocused();a.zoomCenter(-1);Blockly.Touch.clearTouchIdentifier();b.stopPropagation();
                +b.preventDefault()});return this.svgGroup_};Blockly.ZoomControls.prototype.init=function(a){this.bottom_=this.MARGIN_BOTTOM_+a;return this.bottom_+this.HEIGHT_};Blockly.ZoomControls.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.workspace_=null};
                +Blockly.ZoomControls.prototype.position=function(){var a=this.workspace_.getMetrics();a&&(this.workspace_.RTL?(this.left_=this.MARGIN_SIDE_+Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(this.left_+=a.flyoutWidth,this.workspace_.toolbox_&&(this.left_+=a.absoluteLeft))):(this.left_=a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_-Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(this.left_-=a.flyoutWidth)),this.top_=a.viewHeight+
                +a.absoluteTop-this.HEIGHT_-this.bottom_,a.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM&&(this.top_-=a.flyoutHeight),this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")"))};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2014 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.WorkspaceSvg=function(a,b,c){Blockly.WorkspaceSvg.superClass_.constructor.call(this,a);this.getMetrics=a.getMetrics||Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_;this.setMetrics=a.setMetrics||Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_;Blockly.ConnectionDB.init(this);b&&(this.blockDragSurface_=b);c&&(this.workspaceDragSurface_=c);this.useWorkspaceDragSurface_=this.workspaceDragSurface_&&Blockly.utils.is3dSupported();this.highlightedBlocks_=[];this.audioManager_=new Blockly.WorkspaceAudio(a.parentWorkspace);
                +this.grid_=this.options.gridPattern?new Blockly.Grid(a.gridPattern,a.gridOptions):null;this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,Blockly.Variables.flyoutCategory);this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME,Blockly.Procedures.flyoutCategory)};goog.inherits(Blockly.WorkspaceSvg,Blockly.Workspace);Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_=null;Blockly.WorkspaceSvg.prototype.rendered=!0;Blockly.WorkspaceSvg.prototype.isFlyout=!1;
                +Blockly.WorkspaceSvg.prototype.isMutator=!1;Blockly.WorkspaceSvg.prototype.resizesEnabled_=!0;Blockly.WorkspaceSvg.prototype.scrollX=0;Blockly.WorkspaceSvg.prototype.scrollY=0;Blockly.WorkspaceSvg.prototype.startScrollX=0;Blockly.WorkspaceSvg.prototype.startScrollY=0;Blockly.WorkspaceSvg.prototype.dragDeltaXY_=null;Blockly.WorkspaceSvg.prototype.scale=1;Blockly.WorkspaceSvg.prototype.trashcan=null;Blockly.WorkspaceSvg.prototype.scrollbar=null;Blockly.WorkspaceSvg.prototype.currentGesture_=null;
                +Blockly.WorkspaceSvg.prototype.blockDragSurface_=null;Blockly.WorkspaceSvg.prototype.workspaceDragSurface_=null;Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_=!1;Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_=!1;Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_=null;Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_={};Blockly.WorkspaceSvg.prototype.toolboxCategoryCallbacks_={};Blockly.WorkspaceSvg.prototype.inverseScreenCTM_=null;
                +Blockly.WorkspaceSvg.prototype.getInverseScreenCTM=function(){return this.inverseScreenCTM_};Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM=function(){var a=this.getParentSvg().getScreenCTM();a&&(this.inverseScreenCTM_=a.inverse())};
                +Blockly.WorkspaceSvg.prototype.getSvgXY=function(a){var b=0,c=0,d=1;if(goog.dom.contains(this.getCanvas(),a)||goog.dom.contains(this.getBubbleCanvas(),a))d=this.scale;do{var e=Blockly.utils.getRelativeXY(a);if(a==this.getCanvas()||a==this.getBubbleCanvas())d=1;b+=e.x*d;c+=e.y*d;a=a.parentNode}while(a&&a!=this.getParentSvg());return new goog.math.Coordinate(b,c)};Blockly.WorkspaceSvg.prototype.getOriginOffsetInPixels=function(){return Blockly.utils.getInjectionDivXY_(this.svgBlockCanvas_)};
                +Blockly.WorkspaceSvg.prototype.setResizeHandlerWrapper=function(a){this.resizeHandlerWrapper_=a};
                +Blockly.WorkspaceSvg.prototype.createDom=function(a){this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyWorkspace"},null);a&&(this.svgBackground_=Blockly.utils.createSvgElement("rect",{height:"100%",width:"100%","class":a},this.svgGroup_),"blocklyMainBackground"==a&&this.grid_&&(this.svgBackground_.style.fill="url(#"+this.grid_.getPatternId()+")"));this.svgBlockCanvas_=Blockly.utils.createSvgElement("g",{"class":"blocklyBlockCanvas"},this.svgGroup_,this);this.svgBubbleCanvas_=Blockly.utils.createSvgElement("g",
                +{"class":"blocklyBubbleCanvas"},this.svgGroup_,this);a=Blockly.Scrollbar.scrollbarThickness;this.options.hasTrashcan&&(a=this.addTrashcan_(a));this.options.zoomOptions&&this.options.zoomOptions.controls&&this.addZoomControls_(a);this.isFlyout||(Blockly.bindEventWithChecks_(this.svgGroup_,"mousedown",this,this.onMouseDown_),this.options.zoomOptions&&this.options.zoomOptions.wheel&&Blockly.bindEventWithChecks_(this.svgGroup_,"wheel",this,this.onMouseWheel_));this.options.hasCategories&&(this.toolbox_=
                +new Blockly.Toolbox(this));this.grid_&&this.grid_.update(this.scale);this.recordDeleteAreas();return this.svgGroup_};
                +Blockly.WorkspaceSvg.prototype.dispose=function(){this.rendered=!1;this.currentGesture_&&this.currentGesture_.cancel();Blockly.WorkspaceSvg.superClass_.dispose.call(this);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.svgBubbleCanvas_=this.svgBlockCanvas_=null;this.toolbox_&&(this.toolbox_.dispose(),this.toolbox_=null);this.flyout_&&(this.flyout_.dispose(),this.flyout_=null);this.trashcan&&(this.trashcan.dispose(),this.trashcan=null);this.scrollbar&&(this.scrollbar.dispose(),
                +this.scrollbar=null);this.zoomControls_&&(this.zoomControls_.dispose(),this.zoomControls_=null);this.audioManager_&&(this.audioManager_.dispose(),this.audioManager_=null);this.grid_&&(this.grid_.dispose(),this.grid_=null);this.toolboxCategoryCallbacks_&&(this.toolboxCategoryCallbacks_=null);this.flyoutButtonCallbacks_&&(this.flyoutButtonCallbacks_=null);this.options.parentWorkspace||goog.dom.removeNode(this.getParentSvg().parentNode);this.resizeHandlerWrapper_&&(Blockly.unbindEvent_(this.resizeHandlerWrapper_),
                +this.resizeHandlerWrapper_=null)};Blockly.WorkspaceSvg.prototype.newBlock=function(a,b){return new Blockly.BlockSvg(this,a,b)};Blockly.WorkspaceSvg.prototype.addTrashcan_=function(a){this.trashcan=new Blockly.Trashcan(this);var b=this.trashcan.createDom();this.svgGroup_.insertBefore(b,this.svgBlockCanvas_);return this.trashcan.init(a)};
                +Blockly.WorkspaceSvg.prototype.addZoomControls_=function(a){this.zoomControls_=new Blockly.ZoomControls(this);var b=this.zoomControls_.createDom();this.svgGroup_.appendChild(b);return this.zoomControls_.init(a)};
                +Blockly.WorkspaceSvg.prototype.addFlyout_=function(a){var b={disabledPatternId:this.options.disabledPatternId,parentWorkspace:this,RTL:this.RTL,oneBasedIndex:this.options.oneBasedIndex,horizontalLayout:this.horizontalLayout,toolboxPosition:this.options.toolboxPosition};this.flyout_=null;this.flyout_=this.horizontalLayout?new Blockly.HorizontalFlyout(b):new Blockly.VerticalFlyout(b);this.flyout_.autoClose=!1;return this.flyout_.createDom(a)};
                +Blockly.WorkspaceSvg.prototype.getFlyout_=function(){return this.flyout_?this.flyout_:this.toolbox_?this.toolbox_.flyout_:null};Blockly.WorkspaceSvg.prototype.updateScreenCalculations_=function(){this.updateInverseScreenCTM();this.recordDeleteAreas()};Blockly.WorkspaceSvg.prototype.resizeContents=function(){this.resizesEnabled_&&this.rendered&&(this.scrollbar&&this.scrollbar.resize(),this.updateInverseScreenCTM())};
                +Blockly.WorkspaceSvg.prototype.resize=function(){this.toolbox_&&this.toolbox_.position();this.flyout_&&this.flyout_.position();this.trashcan&&this.trashcan.position();this.zoomControls_&&this.zoomControls_.position();this.scrollbar&&this.scrollbar.resize();this.updateScreenCalculations_()};Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled=function(){var a=goog.dom.getDocumentScroll();goog.math.Coordinate.equals(this.lastRecordedPageScroll_,a)||(this.lastRecordedPageScroll_=a,this.updateScreenCalculations_())};
                +Blockly.WorkspaceSvg.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.WorkspaceSvg.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};Blockly.WorkspaceSvg.prototype.getParentSvg=function(){if(this.cachedParentSvg_)return this.cachedParentSvg_;for(var a=this.svgGroup_;a;){if("svg"==a.tagName)return this.cachedParentSvg_=a;a=a.parentNode}return null};
                +Blockly.WorkspaceSvg.prototype.translate=function(a,b){if(this.useWorkspaceDragSurface_&&this.isDragSurfaceActive_)this.workspaceDragSurface_.translateSurface(a,b);else{var c="translate("+a+","+b+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",c);this.svgBubbleCanvas_.setAttribute("transform",c)}this.blockDragSurface_&&this.blockDragSurface_.translateAndScaleGroup(a,b,this.scale)};
                +Blockly.WorkspaceSvg.prototype.resetDragSurface=function(){if(this.useWorkspaceDragSurface_){this.isDragSurfaceActive_=!1;var a=this.workspaceDragSurface_.getSurfaceTranslation();this.workspaceDragSurface_.clearAndHide(this.svgGroup_);a="translate("+a.x+","+a.y+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",a);this.svgBubbleCanvas_.setAttribute("transform",a)}};
                +Blockly.WorkspaceSvg.prototype.setupDragSurface=function(){if(this.useWorkspaceDragSurface_&&!this.isDragSurfaceActive_){this.isDragSurfaceActive_=!0;var a=this.svgBlockCanvas_.previousSibling,b=this.getParentSvg().getAttribute("width"),c=this.getParentSvg().getAttribute("height"),d=Blockly.utils.getRelativeXY(this.svgBlockCanvas_);this.workspaceDragSurface_.setContentsAndShow(this.svgBlockCanvas_,this.svgBubbleCanvas_,a,b,c,this.scale);this.workspaceDragSurface_.translateSurface(d.x,d.y)}};
                +Blockly.WorkspaceSvg.prototype.getWidth=function(){var a=this.getMetrics();return a?a.viewWidth/this.scale:0};Blockly.WorkspaceSvg.prototype.setVisible=function(a){this.scrollbar&&this.scrollbar.setContainerVisible(a);this.getFlyout_()&&this.getFlyout_().setContainerVisible(a);this.getParentSvg().style.display=a?"block":"none";this.toolbox_&&(this.toolbox_.HtmlDiv.style.display=a?"block":"none");a?(this.render(),this.toolbox_&&this.toolbox_.position()):Blockly.hideChaff(!0)};
                +Blockly.WorkspaceSvg.prototype.render=function(){for(var a=this.getAllBlocks(),b=a.length-1;0<=b;b--)a[b].render(!1)};Blockly.WorkspaceSvg.prototype.traceOn=function(){console.warn("Deprecated call to traceOn, delete this.")};
                +Blockly.WorkspaceSvg.prototype.highlightBlock=function(a,b){if(void 0===b){for(var c=0,d;d=this.highlightedBlocks_[c];c++)d.setHighlighted(!1);this.highlightedBlocks_.length=0}if(d=a?this.getBlockById(a):null)(a=void 0===b||b)?-1==this.highlightedBlocks_.indexOf(d)&&this.highlightedBlocks_.push(d):goog.array.remove(this.highlightedBlocks_,d),d.setHighlighted(a)};
                +Blockly.WorkspaceSvg.prototype.paste=function(a){if(this.rendered&&!(a.getElementsByTagName("block").length>=this.remainingCapacity())){this.currentGesture_&&this.currentGesture_.cancel();Blockly.Events.disable();try{var b=Blockly.Xml.domToBlock(a,this);if(goog.userAgent.IE||goog.userAgent.EDGE)for(var c=b.getDescendants(),d=c.length-1;0<=d;d--)c[d].render(!1);var e=parseInt(a.getAttribute("x"),10),f=parseInt(a.getAttribute("y"),10);if(!isNaN(e)&&!isNaN(f)){this.RTL&&(e=-e);do{var g=!1;for(var h=
                +this.getAllBlocks(),d=0,k;k=h[d];d++){var l=k.getRelativeToSurfaceXY();if(1>=Math.abs(e-l.x)&&1>=Math.abs(f-l.y)){g=!0;break}}if(!g)for(var m=b.getConnections_(!1),d=0,n;n=m[d];d++)if(n.closest(Blockly.SNAP_RADIUS,new goog.math.Coordinate(e,f)).connection){g=!0;break}g&&(e=this.RTL?e-Blockly.SNAP_RADIUS:e+Blockly.SNAP_RADIUS,f+=2*Blockly.SNAP_RADIUS)}while(g);b.moveBy(e,f)}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(b));
                +b.select()}};Blockly.WorkspaceSvg.prototype.refreshToolboxSelection_=function(){this.toolbox_&&this.toolbox_.flyout_&&!this.currentGesture_&&this.toolbox_.refreshSelection()};Blockly.WorkspaceSvg.prototype.renameVariable=function(a,b){Blockly.WorkspaceSvg.superClass_.renameVariable.call(this,a,b);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.renameVariableById=function(a,b){Blockly.WorkspaceSvg.superClass_.renameVariableById.call(this,a,b);this.refreshToolboxSelection_()};
                +Blockly.WorkspaceSvg.prototype.deleteVariable=function(a){Blockly.WorkspaceSvg.superClass_.deleteVariable.call(this,a);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.deleteVariableById=function(a){Blockly.WorkspaceSvg.superClass_.deleteVariableById.call(this,a);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.createVariable=function(a,b,c){a=Blockly.WorkspaceSvg.superClass_.createVariable.call(this,a,b,c);this.refreshToolboxSelection_();return a};
                +Blockly.WorkspaceSvg.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getClientRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getClientRect():this.toolbox_?this.toolbox_.getClientRect():null};
                +Blockly.WorkspaceSvg.prototype.isDeleteArea=function(a){a=new goog.math.Coordinate(a.clientX,a.clientY);return this.deleteAreaTrash_&&this.deleteAreaTrash_.contains(a)?Blockly.DELETE_AREA_TRASH:this.deleteAreaToolbox_&&this.deleteAreaToolbox_.contains(a)?Blockly.DELETE_AREA_TOOLBOX:Blockly.DELETE_AREA_NONE};Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){var b=this.getGesture(a);b&&b.handleWsStart(a,this)};
                +Blockly.WorkspaceSvg.prototype.startDrag=function(a,b){a=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;this.dragDeltaXY_=goog.math.Coordinate.difference(b,a)};Blockly.WorkspaceSvg.prototype.moveDrag=function(a){a=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;return goog.math.Coordinate.sum(this.dragDeltaXY_,a)};
                +Blockly.WorkspaceSvg.prototype.isDragging=function(){return this.currentGesture_&&this.currentGesture_.isDragging()};Blockly.WorkspaceSvg.prototype.isDraggable=function(){return!!this.scrollbar};Blockly.WorkspaceSvg.prototype.onMouseWheel_=function(a){this.currentGesture_&&this.currentGesture_.cancel();var b=-a.deltaY/50,c=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());this.zoom(c.x,c.y,b);a.preventDefault()};
                +Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox=function(){var a=this.getTopBlocks(!1);if(!a.length)return{x:0,y:0,width:0,height:0};for(var b=a[0].getBoundingRectangle(),c=1;c<a.length;c++){var d=a[c].getBoundingRectangle();d.topLeft.x<b.topLeft.x&&(b.topLeft.x=d.topLeft.x);d.bottomRight.x>b.bottomRight.x&&(b.bottomRight.x=d.bottomRight.x);d.topLeft.y<b.topLeft.y&&(b.topLeft.y=d.topLeft.y);d.bottomRight.y>b.bottomRight.y&&(b.bottomRight.y=d.bottomRight.y)}return{x:b.topLeft.x,y:b.topLeft.y,width:b.bottomRight.x-
                +b.topLeft.x,height:b.bottomRight.y-b.topLeft.y}};Blockly.WorkspaceSvg.prototype.cleanUp=function(){Blockly.Events.setGroup(!0);for(var a=this.getTopBlocks(!0),b=0,c=0,d;d=a[c];c++){var e=d.getRelativeToSurfaceXY();d.moveBy(-e.x,b-e.y);d.snapToGrid();b=d.getRelativeToSurfaceXY().y+d.getHeightWidth().height+Blockly.BlockSvg.MIN_BLOCK_Y}Blockly.Events.setGroup(!1);this.resizeContents()};
                +Blockly.WorkspaceSvg.prototype.showContextMenu_=function(a){function b(a){if(a.isDeletable())p=p.concat(a.getDescendants());else{a=a.getChildren();for(var c=0;c<a.length;c++)b(a[c])}}function c(){Blockly.Events.setGroup(f);var a=p.shift();a&&(a.workspace?(a.dispose(!1,!0),setTimeout(c,10)):c());Blockly.Events.setGroup(!1)}if(!this.options.readOnly&&!this.isFlyout){var d=[],e=this.getTopBlocks(!0),f=Blockly.utils.genUid(),g=this,h={};h.text=Blockly.Msg.UNDO;h.enabled=0<this.undoStack_.length;h.callback=
                +this.undo.bind(this,!1);d.push(h);h={};h.text=Blockly.Msg.REDO;h.enabled=0<this.redoStack_.length;h.callback=this.undo.bind(this,!0);d.push(h);this.scrollbar&&(h={},h.text=Blockly.Msg.CLEAN_UP,h.enabled=1<e.length,h.callback=this.cleanUp.bind(this),d.push(h));if(this.options.collapse){for(var k=h=!1,l=0;l<e.length;l++)for(var m=e[l];m;)m.isCollapsed()?h=!0:k=!0,m=m.getNextBlock();var n=function(a){for(var b=0,c=0;c<e.length;c++)for(var d=e[c];d;)setTimeout(d.setCollapsed.bind(d,a),b),d=d.getNextBlock(),
                +b+=10},k={enabled:k};k.text=Blockly.Msg.COLLAPSE_ALL;k.callback=function(){n(!0)};d.push(k);h={enabled:h};h.text=Blockly.Msg.EXPAND_ALL;h.callback=function(){n(!1)};d.push(h)}for(var p=[],l=0;l<e.length;l++)b(e[l]);h={text:1==p.length?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(p.length)),enabled:0<p.length,callback:function(){g.currentGesture_&&g.currentGesture_.cancel();2>p.length?c():Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",p.length),function(a){a&&
                +c()})}};d.push(h);Blockly.ContextMenu.show(a,d,this.RTL)}};
                +Blockly.WorkspaceSvg.prototype.updateToolbox=function(a){if(a=Blockly.Options.parseToolboxTree(a)){if(!this.options.languageTree)throw"Existing toolbox is null.  Can't create new toolbox.";if(a.getElementsByTagName("category").length){if(!this.toolbox_)throw"Existing toolbox has no categories.  Can't change mode.";this.options.languageTree=a;this.toolbox_.populate_(a);this.toolbox_.addColour_()}else{if(!this.flyout_)throw"Existing toolbox has categories.  Can't change mode.";this.options.languageTree=
                +a;this.flyout_.show(a.childNodes)}}else if(this.options.languageTree)throw"Can't nullify an existing toolbox.";};Blockly.WorkspaceSvg.prototype.markFocused=function(){this.options.parentWorkspace?this.options.parentWorkspace.markFocused():(Blockly.mainWorkspace=this,this.setBrowserFocus())};Blockly.WorkspaceSvg.prototype.setBrowserFocus=function(){document.activeElement&&document.activeElement.blur();try{this.getParentSvg().focus()}catch(a){try{this.getParentSvg().parentNode.setActive()}catch(b){this.getParentSvg().parentNode.focus()}}};
                +Blockly.WorkspaceSvg.prototype.zoom=function(a,b,c){var d=this.options.zoomOptions.scaleSpeed,e=this.getMetrics(),f=this.getParentSvg().createSVGPoint();f.x=a;f.y=b;f=f.matrixTransform(this.getCanvas().getCTM().inverse());a=f.x;b=f.y;f=this.getCanvas();d=Math.pow(d,c);c=this.scale*d;c>this.options.zoomOptions.maxScale?d=this.options.zoomOptions.maxScale/this.scale:c<this.options.zoomOptions.minScale&&(d=this.options.zoomOptions.minScale/this.scale);this.scale!=c&&(this.scrollbar&&(a=f.getCTM().translate(a*
                +(1-d),b*(1-d)).scale(d),this.scrollX=a.e-e.absoluteLeft,this.scrollY=a.f-e.absoluteTop),this.setScale(c))};Blockly.WorkspaceSvg.prototype.zoomCenter=function(a){var b=this.getMetrics();this.zoom(b.viewWidth/2,b.viewHeight/2,a)};
                +Blockly.WorkspaceSvg.prototype.zoomToFit=function(){var a=this.getMetrics(),b=this.getBlocksBoundingBox(),c=b.width,b=b.height;if(c){var d=a.viewWidth,e=a.viewHeight;this.flyout_&&(d-=this.flyout_.width_);this.scrollbar||(c+=a.contentLeft,b+=a.contentTop);this.setScale(Math.min(d/c,e/b));this.scrollCenter()}};
                +Blockly.WorkspaceSvg.prototype.scrollCenter=function(){if(this.scrollbar){var a=this.getMetrics(),b=(a.contentWidth-a.viewWidth)/2;this.flyout_&&(b-=this.flyout_.width_/2);this.scrollbar.set(b,(a.contentHeight-a.viewHeight)/2)}};
                +Blockly.WorkspaceSvg.prototype.setScale=function(a){this.options.zoomOptions.maxScale&&a>this.options.zoomOptions.maxScale?a=this.options.zoomOptions.maxScale:this.options.zoomOptions.minScale&&a<this.options.zoomOptions.minScale&&(a=this.options.zoomOptions.minScale);this.scale=a;this.grid_&&this.grid_.update(this.scale);this.scrollbar?this.scrollbar.resize():this.translate(this.scrollX,this.scrollY);Blockly.hideChaff(!1);this.flyout_&&this.flyout_.reflow()};
                +Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_=function(){var a=Blockly.svgSize(this.getParentSvg());if(this.toolbox_)if(this.toolboxPosition==Blockly.TOOLBOX_AT_TOP||this.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM)a.height-=this.toolbox_.getHeight();else if(this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT||this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT)a.width-=this.toolbox_.getWidth();var b=Blockly.Flyout.prototype.CORNER_RADIUS-1;var c=a.width-b;var d=a.height-b;var e=this.getBlocksBoundingBox();
                +var f=e.width*this.scale;var g=e.height*this.scale,h=e.x*this.scale,k=e.y*this.scale;this.scrollbar?(b=Math.min(h-c/2,h+f-c),f=Math.max(h+f+c/2,h+c),c=Math.min(k-d/2,k+g-d),d=Math.max(k+g+d/2,k+d)):(b=e.x,f=b+e.width,c=e.y,d=c+e.height);e=0;this.toolbox_&&this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(e=this.toolbox_.getWidth());g=0;this.toolbox_&&this.toolboxPosition==Blockly.TOOLBOX_AT_TOP&&(g=this.toolbox_.getHeight());return{viewHeight:a.height,viewWidth:a.width,contentHeight:d-c,contentWidth:f-
                +b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:c,contentLeft:b,absoluteTop:g,absoluteLeft:e,toolboxWidth:this.toolbox_?this.toolbox_.getWidth():0,toolboxHeight:this.toolbox_?this.toolbox_.getHeight():0,flyoutWidth:this.flyout_?this.flyout_.getWidth():0,flyoutHeight:this.flyout_?this.flyout_.getHeight():0,toolboxPosition:this.toolboxPosition}};
                +Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_=function(a){if(!this.scrollbar)throw"Attempt to set top level workspace scroll without scrollbars.";var b=this.getMetrics();goog.isNumber(a.x)&&(this.scrollX=-b.contentWidth*a.x-b.contentLeft);goog.isNumber(a.y)&&(this.scrollY=-b.contentHeight*a.y-b.contentTop);a=this.scrollX+b.absoluteLeft;b=this.scrollY+b.absoluteTop;this.translate(a,b);this.grid_&&this.grid_.moveTo(a,b)};
                +Blockly.WorkspaceSvg.prototype.setResizesEnabled=function(a){var b=!this.resizesEnabled_&&a;this.resizesEnabled_=a;b&&this.resizeContents()};Blockly.WorkspaceSvg.prototype.clear=function(){this.setResizesEnabled(!1);Blockly.WorkspaceSvg.superClass_.clear.call(this);this.setResizesEnabled(!0)};Blockly.WorkspaceSvg.prototype.registerButtonCallback=function(a,b){goog.asserts.assert(goog.isFunction(b),"Button callbacks must be functions.");this.flyoutButtonCallbacks_[a]=b};
                +Blockly.WorkspaceSvg.prototype.getButtonCallback=function(a){return(a=this.flyoutButtonCallbacks_[a])?a:null};Blockly.WorkspaceSvg.prototype.removeButtonCallback=function(a){this.flyoutButtonCallbacks_[a]=null};Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback=function(a,b){goog.asserts.assert(goog.isFunction(b),"Toolbox category callbacks must be functions.");this.toolboxCategoryCallbacks_[a]=b};
                +Blockly.WorkspaceSvg.prototype.getToolboxCategoryCallback=function(a){return(a=this.toolboxCategoryCallbacks_[a])?a:null};Blockly.WorkspaceSvg.prototype.removeToolboxCategoryCallback=function(a){this.toolboxCategoryCallbacks_[a]=null};
                +Blockly.WorkspaceSvg.prototype.getGesture=function(a){var b="mousedown"==a.type||"touchstart"==a.type,c=this.currentGesture_;return c?b&&c.hasStarted()?(console.warn("tried to start the same gesture twice"),c.cancel(),null):c:b?this.currentGesture_=new Blockly.Gesture(a,this):null};Blockly.WorkspaceSvg.prototype.clearGesture=function(){this.currentGesture_=null};Blockly.WorkspaceSvg.prototype.cancelCurrentGesture=function(){this.currentGesture_&&this.currentGesture_.cancel()};
                +Blockly.WorkspaceSvg.prototype.getAudioManager=function(){return this.audioManager_};Blockly.WorkspaceSvg.prototype.getGrid=function(){return this.grid_};Blockly.WorkspaceSvg.prototype.setVisible=Blockly.WorkspaceSvg.prototype.setVisible;Blockly.Mutator=function(a){Blockly.Mutator.superClass_.constructor.call(this,null);this.quarkNames_=a};goog.inherits(Blockly.Mutator,Blockly.Icon);Blockly.Mutator.prototype.workspaceWidth_=0;Blockly.Mutator.prototype.workspaceHeight_=0;
                +Blockly.Mutator.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("rect",{"class":"blocklyIconShape",rx:"4",ry:"4",height:"16",width:"16"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 -0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z"},a);
                +Blockly.utils.createSvgElement("circle",{"class":"blocklyIconShape",r:"2.7",cx:"8",cy:"8"},a)};Blockly.Mutator.prototype.iconClick_=function(a){this.block_.isEditable()&&Blockly.Icon.prototype.iconClick_.call(this,a)};
                +Blockly.Mutator.prototype.createEditor_=function(){this.svgDialog_=Blockly.utils.createSvgElement("svg",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);if(this.quarkNames_.length){var a=goog.dom.createDom("xml");for(var b=0,c;c=this.quarkNames_[b];b++)a.appendChild(goog.dom.createDom("block",{type:c}))}else a=null;a={languageTree:a,parentWorkspace:this.block_.workspace,pathToMedia:this.block_.workspace.options.pathToMedia,RTL:this.block_.RTL,toolboxPosition:this.block_.RTL?Blockly.TOOLBOX_AT_RIGHT:
                +Blockly.TOOLBOX_AT_LEFT,horizontalLayout:!1,getMetrics:this.getFlyoutMetrics_.bind(this),setMetrics:null};this.workspace_=new Blockly.WorkspaceSvg(a);this.workspace_.isMutator=!0;a=this.workspace_.addFlyout_("g");b=this.workspace_.createDom("blocklyMutatorBackground");b.insertBefore(a,this.workspace_.svgBlockCanvas_);this.svgDialog_.appendChild(b);return this.svgDialog_};
                +Blockly.Mutator.prototype.updateEditable=function(){this.block_.isInFlyout||(this.block_.isEditable()?this.iconGroup_&&Blockly.utils.removeClass(this.iconGroup_,"blocklyIconGroupReadonly"):(this.setVisible(!1),this.iconGroup_&&Blockly.utils.addClass(this.iconGroup_,"blocklyIconGroupReadonly")));Blockly.Icon.prototype.updateEditable.call(this)};
                +Blockly.Mutator.prototype.resizeBubble_=function(){var a=2*Blockly.Bubble.BORDER_WIDTH,b=this.workspace_.getCanvas().getBBox();var c=this.block_.RTL?-b.x:b.width+b.x;b=b.height+3*a;if(this.workspace_.flyout_)var d=this.workspace_.flyout_.getMetrics_(),b=Math.max(b,d.contentHeight+20);c+=3*a;if(Math.abs(this.workspaceWidth_-c)>a||Math.abs(this.workspaceHeight_-b)>a)this.workspaceWidth_=c,this.workspaceHeight_=b,this.bubble_.setBubbleSize(c+a,b+a),this.svgDialog_.setAttribute("width",this.workspaceWidth_),
                +this.svgDialog_.setAttribute("height",this.workspaceHeight_);this.block_.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a));this.workspace_.resize()};
                +Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"mutatorOpen",!a,a)),a){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svgPath_,this.iconXY_,null,null);if(a=this.workspace_.options.languageTree)this.workspace_.flyout_.init(this.workspace_),this.workspace_.flyout_.show(a.childNodes);this.rootBlock_=this.block_.decompose(this.workspace_);a=this.rootBlock_.getDescendants();var b=0;
                +for(var c;c=a[b];b++)c.render();this.rootBlock_.setMovable(!1);this.rootBlock_.setDeletable(!1);this.workspace_.flyout_?(b=2*this.workspace_.flyout_.CORNER_RADIUS,a=this.workspace_.flyout_.width_+b):a=b=16;this.block_.RTL&&(a=-a);this.rootBlock_.moveBy(a,b);if(this.block_.saveConnections){var d=this;this.block_.saveConnections(this.rootBlock_);this.sourceListener_=function(){d.block_.saveConnections(d.rootBlock_)};this.block_.workspace.addChangeListener(this.sourceListener_)}this.resizeBubble_();
                +this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));this.updateColour()}else this.svgDialog_=null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(this.block_.workspace.removeChangeListener(this.sourceListener_),this.sourceListener_=null)};
                +Blockly.Mutator.prototype.workspaceChanged_=function(){var a;if(!this.workspace_.isDragging())for(var b=this.workspace_.getTopBlocks(!1),c=0;a=b[c];c++){var d=a.getRelativeToSurfaceXY(),e=a.getHeightWidth();20>d.y+e.height&&a.moveBy(0,20-e.height-d.y)}if(this.rootBlock_.workspace==this.workspace_){Blockly.Events.setGroup(!0);a=this.block_;b=(b=a.mutationToDom())&&Blockly.Xml.domToText(b);c=a.rendered;a.rendered=!1;a.compose(this.rootBlock_);a.rendered=c;a.initSvg();c=(c=a.mutationToDom())&&Blockly.Xml.domToText(c);
                +if(b!=c){Blockly.Events.fire(new Blockly.Events.BlockChange(a,"mutation",null,b,c));var f=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(f);a.bumpNeighbours_();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY)}a.rendered&&a.render();this.workspace_.isDragging()||this.resizeBubble_();Blockly.Events.setGroup(!1)}};Blockly.Mutator.prototype.getFlyoutMetrics_=function(){return{viewHeight:this.workspaceHeight_,viewWidth:this.workspaceWidth_,absoluteTop:0,absoluteLeft:0}};
                +Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Mutator.reconnect=function(a,b,c){if(!a||!a.getSourceBlock().workspace)return!1;c=b.getInput(c).connection;var d=a.targetBlock();return d&&d!=b||c.targetConnection==a?!1:(c.isConnected()&&c.disconnect(),c.connect(a),!0)};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Mutator||(goog.global.Blockly.Mutator={});goog.global.Blockly.Mutator.reconnect=Blockly.Mutator.reconnect;Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_={}};goog.inherits(Blockly.Warning,Blockly.Icon);Blockly.Warning.prototype.collapseHidden=!1;
                +Blockly.Warning.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("path",{"class":"blocklyIconShape",d:"M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z"},a);Blockly.utils.createSvgElement("rect",{"class":"blocklyIconSymbol",x:"7",y:"11",height:"2",width:"2"},a)};
                +Blockly.Warning.textToDom_=function(a){var b=Blockly.utils.createSvgElement("text",{"class":"blocklyText blocklyBubbleText",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c<a.length;c++){var d=Blockly.utils.createSvgElement("tspan",{dy:"1em",x:Blockly.Bubble.BORDER_WIDTH},b),e=document.createTextNode(a[c]);d.appendChild(e)}return b};
                +Blockly.Warning.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"warningOpen",!a,a)),a){a=Blockly.Warning.textToDom_(this.getText());this.bubble_=new Blockly.Bubble(this.block_.workspace,a,this.block_.svgPath_,this.iconXY_,null,null);if(this.block_.RTL)for(var b=a.getBBox().width,c=0,d;d=a.childNodes[c];c++)d.setAttribute("text-anchor","end"),d.setAttribute("x",b+Blockly.Bubble.BORDER_WIDTH);this.updateColour();a=this.bubble_.getBubbleSize();
                +this.bubble_.setBubbleSize(a.width,a.height)}else this.bubble_.dispose(),this.body_=this.bubble_=null};Blockly.Warning.prototype.bodyFocus_=function(a){this.bubble_.promote_()};Blockly.Warning.prototype.setText=function(a,b){this.text_[b]!=a&&(a?this.text_[b]=a:delete this.text_[b],this.isVisible()&&(this.setVisible(!1),this.setVisible(!0)))};Blockly.Warning.prototype.getText=function(){var a=[],b;for(b in this.text_)a.push(this.text_[b]);return a.join("\n")};
                +Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Block=function(a,b,c){this.id=c&&!a.getBlockById(c)?c:Blockly.utils.genUid();a.blockDB_[this.id]=this;this.previousConnection=this.nextConnection=this.outputConnection=null;this.inputList=[];this.inputsInline=void 0;this.disabled=!1;this.tooltip="";this.contextMenu=!0;this.parentBlock_=null;this.childBlocks_=[];this.editable_=this.movable_=this.deletable_=!0;this.collapsed_=this.isShadow_=!1;this.comment=null;this.xy_=new goog.math.Coordinate(0,0);this.workspace=a;this.isInFlyout=a.isFlyout;
                +this.isInMutator=a.isMutator;this.RTL=a.RTL;b&&(this.type=b,c=Blockly.Blocks[b],goog.asserts.assertObject(c,'Error: Unknown block type "%s".',b),goog.mixin(this,c));a.addTopBlock(this);goog.isFunction(this.init)&&this.init();this.inputsInlineDefault=this.inputsInline;Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(this));goog.isFunction(this.onchange)&&this.setOnChange(this.onchange)};
                +Blockly.Block.obtain=function(a,b){console.warn("Deprecated call to Blockly.Block.obtain, use workspace.newBlock instead.");return a.newBlock(b)};Blockly.Block.prototype.data=null;Blockly.Block.prototype.colour_="#000000";
                +Blockly.Block.prototype.dispose=function(a){if(this.workspace){this.onchangeWrapper_&&this.workspace.removeChangeListener(this.onchangeWrapper_);this.unplug(a);Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockDelete(this));Blockly.Events.disable();try{this.workspace&&(this.workspace.removeTopBlock(this),delete this.workspace.blockDB_[this.id],this.workspace=null);for(var b=this.childBlocks_.length-1;0<=b;b--)this.childBlocks_[b].dispose(!1);for(var b=0,c;c=this.inputList[b];b++)c.dispose();
                +this.inputList.length=0;for(var d=this.getConnections_(!0),b=0;b<d.length;b++){var e=d[b];e.isConnected()&&e.disconnect();d[b].dispose()}}finally{Blockly.Events.enable()}}};
                +Blockly.Block.prototype.unplug=function(a){if(this.outputConnection)this.outputConnection.isConnected()&&this.outputConnection.disconnect();else if(this.previousConnection){var b=null;this.previousConnection.isConnected()&&(b=this.previousConnection.targetConnection,this.previousConnection.disconnect());var c=this.getNextBlock();a&&c&&(a=this.nextConnection.targetConnection,a.disconnect(),b&&b.checkType_(a)&&b.connect(a))}};
                +Blockly.Block.prototype.getConnections_=function(){var a=[];this.outputConnection&&a.push(this.outputConnection);this.previousConnection&&a.push(this.previousConnection);this.nextConnection&&a.push(this.nextConnection);for(var b=0,c;c=this.inputList[b];b++)c.connection&&a.push(c.connection);return a};Blockly.Block.prototype.lastConnectionInStack_=function(){for(var a=this.nextConnection;a;){var b=a.targetBlock();if(!b)return a;a=b.nextConnection}return null};
                +Blockly.Block.prototype.bumpNeighbours_=function(){console.warn("Not expected to reach this bumpNeighbours_ function. The BlockSvg function for bumpNeighbours_ was expected to be called instead.")};Blockly.Block.prototype.getParent=function(){return this.parentBlock_};Blockly.Block.prototype.getInputWithBlock=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&c.connection.targetBlock()==a)return c;return null};
                +Blockly.Block.prototype.getSurroundParent=function(){var a=this;do{var b=a;a=a.getParent();if(!a)return null}while(a.getNextBlock()==b);return a};Blockly.Block.prototype.getNextBlock=function(){return this.nextConnection&&this.nextConnection.targetBlock()};Blockly.Block.prototype.getRootBlock=function(){var a=this;do{var b=a;a=b.parentBlock_}while(a);return b};Blockly.Block.prototype.getChildren=function(){return this.childBlocks_};
                +Blockly.Block.prototype.setParent=function(a){if(a!=this.parentBlock_){if(this.parentBlock_){goog.array.remove(this.parentBlock_.childBlocks_,this);if(this.previousConnection&&this.previousConnection.isConnected())throw"Still connected to previous block.";if(this.outputConnection&&this.outputConnection.isConnected())throw"Still connected to parent block.";this.parentBlock_=null}else this.workspace.removeTopBlock(this);(this.parentBlock_=a)?a.childBlocks_.push(this):this.workspace.addTopBlock(this)}};
                +Blockly.Block.prototype.getDescendants=function(){for(var a=[this],b,c=0;b=this.childBlocks_[c];c++)a.push.apply(a,b.getDescendants());return a};Blockly.Block.prototype.isDeletable=function(){return this.deletable_&&!this.isShadow_&&!(this.workspace&&this.workspace.options.readOnly)};Blockly.Block.prototype.setDeletable=function(a){this.deletable_=a};Blockly.Block.prototype.isMovable=function(){return this.movable_&&!this.isShadow_&&!(this.workspace&&this.workspace.options.readOnly)};
                +Blockly.Block.prototype.setMovable=function(a){this.movable_=a};Blockly.Block.prototype.isShadow=function(){return this.isShadow_};Blockly.Block.prototype.setShadow=function(a){this.isShadow_=a};Blockly.Block.prototype.isEditable=function(){return this.editable_&&!(this.workspace&&this.workspace.options.readOnly)};Blockly.Block.prototype.setEditable=function(a){this.editable_=a;a=0;for(var b;b=this.inputList[a];a++)for(var c=0,d;d=b.fieldRow[c];c++)d.updateEditable()};
                +Blockly.Block.prototype.setConnectionsHidden=function(a){var b;if(!a&&this.isCollapsed())this.outputConnection&&this.outputConnection.setHidden(a),this.previousConnection&&this.previousConnection.setHidden(a),this.nextConnection&&(this.nextConnection.setHidden(a),(b=this.nextConnection.targetBlock())&&b.setConnectionsHidden(a));else for(var c=this.getConnections_(!0),d=0;b=c[d];d++)b.setHidden(a),b.isSuperior()&&(b=b.targetBlock())&&b.setConnectionsHidden(a)};
                +Blockly.Block.prototype.setHelpUrl=function(a){this.helpUrl=a};Blockly.Block.prototype.setTooltip=function(a){this.tooltip=a};Blockly.Block.prototype.getColour=function(){return this.colour_};Blockly.Block.prototype.setColour=function(a){var b=Number(a);if(isNaN(b))if(goog.isString(a)&&a.match(/^#[0-9a-fA-F]{6}$/))this.colour_=a;else throw"Invalid colour: "+a;else this.colour_=Blockly.hueToRgb(b)};
                +Blockly.Block.prototype.setOnChange=function(a){if(a&&!goog.isFunction(a))throw Error("onchange must be a function.");this.onchangeWrapper_&&this.workspace.removeChangeListener(this.onchangeWrapper_);if(this.onchange=a)this.onchangeWrapper_=a.bind(this),this.workspace.addChangeListener(this.onchangeWrapper_)};Blockly.Block.prototype.getField=function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(e.name===a)return e;return null};
                +Blockly.Block.prototype.getVars=function(){for(var a=[],b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)e instanceof Blockly.FieldVariable&&a.push(e.getValue());return a};Blockly.Block.prototype.renameVar=function(a,b){for(var c=0,d;d=this.inputList[c];c++)for(var e=0,f;f=d.fieldRow[e];e++)f instanceof Blockly.FieldVariable&&Blockly.Names.equals(a,f.getValue())&&f.setValue(b)};Blockly.Block.prototype.getFieldValue=function(a){return(a=this.getField(a))?a.getValue():null};
                +Blockly.Block.prototype.setFieldValue=function(a,b){var c=this.getField(b);goog.asserts.assertObject(c,'Field "%s" not found.',b);c.setValue(a)};
                +Blockly.Block.prototype.setPreviousStatement=function(a,b){a?(void 0===b&&(b=null),this.previousConnection||(goog.asserts.assert(!this.outputConnection,"Remove output connection prior to adding previous connection."),this.previousConnection=this.makeConnection_(Blockly.PREVIOUS_STATEMENT)),this.previousConnection.setCheck(b)):this.previousConnection&&(goog.asserts.assert(!this.previousConnection.isConnected(),"Must disconnect previous statement before removing connection."),this.previousConnection.dispose(),
                +this.previousConnection=null)};Blockly.Block.prototype.setNextStatement=function(a,b){a?(void 0===b&&(b=null),this.nextConnection||(this.nextConnection=this.makeConnection_(Blockly.NEXT_STATEMENT)),this.nextConnection.setCheck(b)):this.nextConnection&&(goog.asserts.assert(!this.nextConnection.isConnected(),"Must disconnect next statement before removing connection."),this.nextConnection.dispose(),this.nextConnection=null)};
                +Blockly.Block.prototype.setOutput=function(a,b){a?(void 0===b&&(b=null),this.outputConnection||(goog.asserts.assert(!this.previousConnection,"Remove previous connection prior to adding output connection."),this.outputConnection=this.makeConnection_(Blockly.OUTPUT_VALUE)),this.outputConnection.setCheck(b)):this.outputConnection&&(goog.asserts.assert(!this.outputConnection.isConnected(),"Must disconnect output value before removing connection."),this.outputConnection.dispose(),this.outputConnection=
                +null)};Blockly.Block.prototype.setInputsInline=function(a){this.inputsInline!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"inline",null,this.inputsInline,a)),this.inputsInline=a)};
                +Blockly.Block.prototype.getInputsInline=function(){if(void 0!=this.inputsInline)return this.inputsInline;for(var a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.DUMMY_INPUT&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!1;for(a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.INPUT_VALUE&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!0;return!1};
                +Blockly.Block.prototype.setDisabled=function(a){this.disabled!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"disabled",null,this.disabled,a)),this.disabled=a)};Blockly.Block.prototype.getInheritedDisabled=function(){for(var a=this.getSurroundParent();a;){if(a.disabled)return!0;a=a.getSurroundParent()}return!1};Blockly.Block.prototype.isCollapsed=function(){return this.collapsed_};
                +Blockly.Block.prototype.setCollapsed=function(a){this.collapsed_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"collapsed",null,this.collapsed_,a)),this.collapsed_=a)};
                +Blockly.Block.prototype.toString=function(a,b){var c=[],d=b||"?";if(this.collapsed_)c.push(this.getInput("_TEMP_COLLAPSED_INPUT").fieldRow[0].text_);else for(var e=0,f;f=this.inputList[e];e++){for(var g=0,h;h=f.fieldRow[g];g++)h instanceof Blockly.FieldDropdown&&!h.getValue()?c.push(d):c.push(h.getText());f.connection&&((f=f.connection.targetBlock())?c.push(f.toString(void 0,b)):c.push(d))}c=goog.string.trim(c.join(" "))||"???";a&&(c=goog.string.truncate(c,a));return c};
                +Blockly.Block.prototype.appendValueInput=function(a){return this.appendInput_(Blockly.INPUT_VALUE,a)};Blockly.Block.prototype.appendStatementInput=function(a){return this.appendInput_(Blockly.NEXT_STATEMENT,a)};Blockly.Block.prototype.appendDummyInput=function(a){return this.appendInput_(Blockly.DUMMY_INPUT,a||"")};
                +Blockly.Block.prototype.jsonInit=function(a){goog.asserts.assert(void 0==a.output||void 0==a.previousStatement,"Must not have both an output and a previousStatement.");if(void 0!==a.colour){var b=a.colour;b=goog.isString(b)?Blockly.utils.replaceMessageReferences(b):b;this.setColour(b)}for(b=0;void 0!==a["message"+b];)this.interpolate_(a["message"+b],a["args"+b]||[],a["lastDummyAlign"+b]),b++;void 0!==a.inputsInline&&this.setInputsInline(a.inputsInline);void 0!==a.output&&this.setOutput(!0,a.output);
                +void 0!==a.previousStatement&&this.setPreviousStatement(!0,a.previousStatement);void 0!==a.nextStatement&&this.setNextStatement(!0,a.nextStatement);void 0!==a.tooltip&&(b=a.tooltip,b=Blockly.utils.replaceMessageReferences(b),this.setTooltip(b));void 0!==a.enableContextMenu&&(b=a.enableContextMenu,this.contextMenu=!!b);void 0!==a.helpUrl&&(b=a.helpUrl,b=Blockly.utils.replaceMessageReferences(b),this.setHelpUrl(b));goog.isString(a.extensions)&&(console.warn("JSON attribute 'extensions' should be an array of strings. Found raw string in JSON for '"+
                +a.type+"' block."),a.extensions=[a.extensions]);void 0!==a.mutator&&Blockly.Extensions.apply(a.mutator,this,!0);if(Array.isArray(a.extensions))for(a=a.extensions,b=0;b<a.length;++b)Blockly.Extensions.apply(a[b],this,!1)};
                +Blockly.Block.prototype.mixin=function(a,b){if(goog.isDef(b)&&!goog.isBoolean(b))throw Error("opt_disableCheck must be a boolean if provided");if(!b){b=[];for(var c in a)void 0!==this[c]&&b.push(c);if(b.length)throw Error("Mixin will overwrite block members: "+JSON.stringify(b));}goog.mixin(this,a)};
                +Blockly.Block.prototype.interpolate_=function(a,b,c){var d=Blockly.utils.tokenizeInterpolation(a);var e=[];var f=0;a=[];for(var g=0;g<d.length;g++){var h=d[g];if("number"==typeof h){if(0>=h||h>b.length)throw Error('Block "'+this.type+'": Message index %'+h+" out of range.");if(e[h])throw Error('Block "'+this.type+'": Message index %'+h+" duplicated.");e[h]=!0;f++;a.push(b[h-1])}else(h=h.trim())&&a.push(h)}if(f!=b.length)throw Error('Block "'+this.type+'": Message does not reference all '+b.length+
                +" arg(s).");a.length&&("string"==typeof a[a.length-1]||goog.string.startsWith(a[a.length-1].type,"field_"))&&(g={type:"input_dummy"},c&&(g.align=c),a.push(g));c={LEFT:Blockly.ALIGN_LEFT,RIGHT:Blockly.ALIGN_RIGHT,CENTRE:Blockly.ALIGN_CENTRE};b=[];for(g=0;g<a.length;g++)if(f=a[g],"string"==typeof f)b.push([f,void 0]);else{d=h=null;do if(e=!1,"string"==typeof f)h=new Blockly.FieldLabel(f);else switch(f.type){case "input_value":d=this.appendValueInput(f.name);break;case "input_statement":d=this.appendStatementInput(f.name);
                +break;case "input_dummy":d=this.appendDummyInput(f.name);break;case "field_label":h=Blockly.Block.newFieldLabelFromJson_(f);break;case "field_input":h=Blockly.Block.newFieldTextInputFromJson_(f);break;case "field_angle":h=new Blockly.FieldAngle(f.angle);break;case "field_checkbox":h=new Blockly.FieldCheckbox(f.checked?"TRUE":"FALSE");break;case "field_colour":h=new Blockly.FieldColour(f.colour);break;case "field_variable":h=Blockly.Block.newFieldVariableFromJson_(f);break;case "field_dropdown":h=
                +new Blockly.FieldDropdown(f.options);break;case "field_image":h=Blockly.Block.newFieldImageFromJson_(f);break;case "field_number":h=new Blockly.FieldNumber(f.value,f.min,f.max,f.precision);break;case "field_date":if(Blockly.FieldDate){h=new Blockly.FieldDate(f.date);break}default:f.alt&&(f=f.alt,e=!0)}while(e);if(h)b.push([h,f.name]);else if(d){f.check&&d.setCheck(f.check);f.align&&d.setAlign(c[f.align]);for(e=0;e<b.length;e++)d.appendField(b[e][0],b[e][1]);b.length=0}}};
                +Blockly.Block.newFieldImageFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.src),c=Number(Blockly.utils.replaceMessageReferences(a.width)),d=Number(Blockly.utils.replaceMessageReferences(a.height));a=Blockly.utils.replaceMessageReferences(a.alt);return new Blockly.FieldImage(b,c,d,a)};Blockly.Block.newFieldLabelFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldLabel(b,a["class"])};
                +Blockly.Block.newFieldTextInputFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.text),b=new Blockly.FieldTextInput(b,a["class"]);"boolean"==typeof a.spellcheck&&b.setSpellcheck(a.spellcheck);return b};Blockly.Block.newFieldVariableFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.variable);return new Blockly.FieldVariable(b,null,a.variableTypes)};
                +Blockly.Block.prototype.appendInput_=function(a,b){var c=null;if(a==Blockly.INPUT_VALUE||a==Blockly.NEXT_STATEMENT)c=this.makeConnection_(a);a=new Blockly.Input(a,b,this,c);this.inputList.push(a);return a};
                +Blockly.Block.prototype.moveInputBefore=function(a,b){if(a!=b){for(var c=-1,d=b?-1:this.inputList.length,e=0,f;f=this.inputList[e];e++)if(f.name==a){if(c=e,-1!=d)break}else if(b&&f.name==b&&(d=e,-1!=c))break;goog.asserts.assert(-1!=c,'Named input "%s" not found.',a);goog.asserts.assert(-1!=d,'Reference input "%s" not found.',b);this.moveNumberedInputBefore(c,d)}};
                +Blockly.Block.prototype.moveNumberedInputBefore=function(a,b){goog.asserts.assert(a!=b,"Can't move input to itself.");goog.asserts.assert(a<this.inputList.length,"Input index "+a+" out of bounds.");goog.asserts.assert(b<=this.inputList.length,"Reference input "+b+" out of bounds.");var c=this.inputList[a];this.inputList.splice(a,1);a<b&&b--;this.inputList.splice(b,0,c)};
                +Blockly.Block.prototype.removeInput=function(a,b){for(var c=0,d;d=this.inputList[c];c++)if(d.name==a){d.connection&&d.connection.isConnected()&&(d.connection.setShadowDom(null),a=d.connection.targetBlock(),a.isShadow()?a.dispose():a.unplug());d.dispose();this.inputList.splice(c,1);return}b||goog.asserts.fail('Input "%s" not found.',a)};Blockly.Block.prototype.getInput=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.name==a)return c;return null};
                +Blockly.Block.prototype.getInputTargetBlock=function(a){return(a=this.getInput(a))&&a.connection&&a.connection.targetBlock()};Blockly.Block.prototype.getCommentText=function(){return this.comment||""};Blockly.Block.prototype.setCommentText=function(a){this.comment!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"comment",null,this.comment,a||"")),this.comment=a)};Blockly.Block.prototype.setWarningText=function(){};Blockly.Block.prototype.setMutator=function(){};
                +Blockly.Block.prototype.getRelativeToSurfaceXY=function(){return this.xy_};Blockly.Block.prototype.moveBy=function(a,b){goog.asserts.assert(!this.parentBlock_,"Block has parent.");var c=new Blockly.Events.BlockMove(this);this.xy_.translate(a,b);c.recordNew();Blockly.Events.fire(c)};Blockly.Block.prototype.makeConnection_=function(a){return new Blockly.Connection(this,a)};
                +Blockly.Block.prototype.allInputsFilled=function(a){void 0===a&&(a=!0);if(!a&&this.isShadow())return!1;for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&(c=c.connection.targetBlock(),!c||!c.allInputsFilled(a)))return!1;return(b=this.getNextBlock())?b.allInputsFilled(a):!0};Blockly.Block.prototype.toDevString=function(){var a=this.type?'"'+this.type+'" block':"Block";this.id&&(a+=' (id="'+this.id+'")');return a};Blockly.ContextMenu={};Blockly.ContextMenu.currentBlock=null;Blockly.ContextMenu.eventWrapper_=null;Blockly.ContextMenu.show=function(a,b,c){Blockly.WidgetDiv.show(Blockly.ContextMenu,c,null);if(b.length){var d=Blockly.ContextMenu.populate_(b,c);goog.events.listen(d,goog.ui.Component.EventType.ACTION,Blockly.ContextMenu.hide);Blockly.ContextMenu.position_(d,a,c);setTimeout(function(){d.getElement().focus()},1);Blockly.ContextMenu.currentBlock=null}else Blockly.ContextMenu.hide()};
                +Blockly.ContextMenu.populate_=function(a,b){var c=new goog.ui.Menu;c.setAllowAutoFocus(!0);c.setRightToLeft(b);for(var d=0,e;e=a[d];d++){var f=new goog.ui.MenuItem(e.text);f.setRightToLeft(b);c.addChild(f,!0);f.setEnabled(e.enabled);e.enabled&&(goog.events.listen(f,goog.ui.Component.EventType.ACTION,e.callback),f.handleContextMenu=function(){goog.events.dispatchEvent(this,goog.ui.Component.EventType.ACTION)})}return c};
                +Blockly.ContextMenu.position_=function(a,b,c){var d=goog.dom.getViewportSize(),e=goog.style.getViewportPageOffset(document);a.render(Blockly.WidgetDiv.DIV);a=a.getElement();Blockly.utils.addClass(a,"blocklyContextMenu");Blockly.bindEventWithChecks_(a,"contextmenu",null,Blockly.utils.noEvent);a=goog.style.getSize(a);var f=b.clientX+e.x,g=b.clientY+e.y;b.clientY+a.height>=d.height&&(g-=a.height);c?a.width>=b.clientX&&(f+=a.width):b.clientX+a.width>=d.width&&(f-=a.width);Blockly.WidgetDiv.position(f,
                +g,d,e,c)};Blockly.ContextMenu.hide=function(){Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu);Blockly.ContextMenu.currentBlock=null;Blockly.ContextMenu.eventWrapper_&&Blockly.unbindEvent_(Blockly.ContextMenu.eventWrapper_)};
                +Blockly.ContextMenu.callbackFactory=function(a,b){return function(){Blockly.Events.disable();try{var c=Blockly.Xml.domToBlock(b,a.workspace);var d=a.getRelativeToSurfaceXY();d.x=a.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y)}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!c.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(c));c.select()}};Blockly.BlockSvg=function(a,b,c){this.svgGroup_=Blockly.utils.createSvgElement("g",{},null);this.svgGroup_.translate_="";this.svgPathDark_=Blockly.utils.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgGroup_);this.svgPath_=Blockly.utils.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPathLight_=Blockly.utils.createSvgElement("path",{"class":"blocklyPathLight"},this.svgGroup_);this.svgPath_.tooltip=this;this.rendered=!1;this.useDragSurface_=
                +Blockly.utils.is3dSupported()&&!!a.blockDragSurface_;Blockly.Tooltip.bindMouseEvents(this.svgPath_);Blockly.BlockSvg.superClass_.constructor.call(this,a,b,c)};goog.inherits(Blockly.BlockSvg,Blockly.Block);Blockly.BlockSvg.prototype.height=0;Blockly.BlockSvg.prototype.width=0;Blockly.BlockSvg.prototype.dragStartXY_=null;Blockly.BlockSvg.INLINE=-1;
                +Blockly.BlockSvg.prototype.initSvg=function(){goog.asserts.assert(this.workspace.rendered,"Workspace is headless.");for(var a=0,b;b=this.inputList[a];a++)b.init();b=this.getIcons();for(a=0;a<b.length;a++)b[a].createIcon();this.updateColour();this.updateMovable();this.workspace.options.readOnly||this.eventsInit_||Blockly.bindEventWithChecks_(this.getSvgRoot(),"mousedown",this,this.onMouseDown_);this.eventsInit_=!0;this.getSvgRoot().parentNode||this.workspace.getCanvas().appendChild(this.getSvgRoot())};
                +Blockly.BlockSvg.prototype.select=function(){if(this.isShadow()&&this.getParent())this.getParent().select();else if(Blockly.selected!=this){var a=null;if(Blockly.selected){a=Blockly.selected.id;Blockly.Events.disable();try{Blockly.selected.unselect()}finally{Blockly.Events.enable()}}a=new Blockly.Events.Ui(null,"selected",a,this.id);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=this;this.addSelect()}};
                +Blockly.BlockSvg.prototype.unselect=function(){if(Blockly.selected==this){var a=new Blockly.Events.Ui(null,"selected",this.id,null);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=null;this.removeSelect()}};Blockly.BlockSvg.prototype.mutator=null;Blockly.BlockSvg.prototype.comment=null;Blockly.BlockSvg.prototype.warning=null;
                +Blockly.BlockSvg.prototype.getIcons=function(){var a=[];this.mutator&&a.push(this.mutator);this.comment&&a.push(this.comment);this.warning&&a.push(this.warning);return a};
                +Blockly.BlockSvg.prototype.setParent=function(a){if(a!=this.parentBlock_){var b=this.getSvgRoot();if(this.parentBlock_&&b){var c=this.getRelativeToSurfaceXY();this.workspace.getCanvas().appendChild(b);b.setAttribute("transform","translate("+c.x+","+c.y+")")}Blockly.Field.startCache();Blockly.BlockSvg.superClass_.setParent.call(this,a);Blockly.Field.stopCache();a&&(c=this.getRelativeToSurfaceXY(),a.getSvgRoot().appendChild(b),a=this.getRelativeToSurfaceXY(),this.moveConnections_(a.x-c.x,a.y-c.y))}};
                +Blockly.BlockSvg.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0,c=this.useDragSurface_?this.workspace.blockDragSurface_.getGroup():null,d=this.getSvgRoot();if(d){do{var e=Blockly.utils.getRelativeXY(d),a=a+e.x,b=b+e.y;this.useDragSurface_&&this.workspace.blockDragSurface_.getCurrentBlock()==d&&(e=this.workspace.blockDragSurface_.getSurfaceTranslation(),a+=e.x,b+=e.y);d=d.parentNode}while(d&&d!=this.workspace.getCanvas()&&d!=c)}return new goog.math.Coordinate(a,b)};
                +Blockly.BlockSvg.prototype.moveBy=function(a,b){goog.asserts.assert(!this.parentBlock_,"Block has parent.");var c=new Blockly.Events.BlockMove(this),d=this.getRelativeToSurfaceXY();this.translate(d.x+a,d.y+b);this.moveConnections_(a,b);c.recordNew();this.workspace.resizeContents();Blockly.Events.fire(c)};Blockly.BlockSvg.prototype.translate=function(a,b){this.getSvgRoot().setAttribute("transform","translate("+a+","+b+")")};
                +Blockly.BlockSvg.prototype.moveToDragSurface_=function(){if(this.useDragSurface_){var a=this.getRelativeToSurfaceXY();this.clearTransformAttributes_();this.workspace.blockDragSurface_.translateSurface(a.x,a.y);this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot())}};Blockly.BlockSvg.prototype.moveOffDragSurface_=function(a){this.useDragSurface_&&(this.translate(a.x,a.y),this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas()))};
                +Blockly.BlockSvg.prototype.moveDuringDrag=function(a){this.useDragSurface_?this.workspace.blockDragSurface_.translateSurface(a.x,a.y):(this.svgGroup_.translate_="translate("+a.x+","+a.y+")",this.svgGroup_.setAttribute("transform",this.svgGroup_.translate_+this.svgGroup_.skew_))};Blockly.BlockSvg.prototype.clearTransformAttributes_=function(){Blockly.utils.removeAttribute(this.getSvgRoot(),"transform")};
                +Blockly.BlockSvg.prototype.snapToGrid=function(){if(this.workspace&&!this.workspace.isDragging()&&!this.getParent()&&!this.isInFlyout){var a=this.workspace.getGrid();if(a&&a.shouldSnap()){var b=a.getSpacing(),c=b/2,d=this.getRelativeToSurfaceXY(),a=Math.round((d.x-c)/b)*b+c-d.x,b=Math.round((d.y-c)/b)*b+c-d.y,a=Math.round(a),b=Math.round(b);0==a&&0==b||this.moveBy(a,b)}}};
                +Blockly.BlockSvg.prototype.getBoundingRectangle=function(){var a=this.getRelativeToSurfaceXY(this),b=this.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0,c=this.getHeightWidth();if(this.RTL){var d=new goog.math.Coordinate(a.x-(c.width-b),a.y);a=new goog.math.Coordinate(a.x+b,a.y+c.height)}else d=new goog.math.Coordinate(a.x-b,a.y),a=new goog.math.Coordinate(a.x+c.width-b,a.y+c.height);return{topLeft:d,bottomRight:a}};
                +Blockly.BlockSvg.prototype.setCollapsed=function(a){if(this.collapsed_!=a){for(var b=[],c=0,d;d=this.inputList[c];c++)b.push.apply(b,d.setVisible(!a));if(a){d=this.getIcons();for(c=0;c<d.length;c++)d[c].setVisible(!1);c=this.toString(Blockly.COLLAPSE_CHARS);this.appendDummyInput("_TEMP_COLLAPSED_INPUT").appendField(c).init()}else this.removeInput("_TEMP_COLLAPSED_INPUT"),this.setWarningText(null);Blockly.BlockSvg.superClass_.setCollapsed.call(this,a);b.length||(b[0]=this);if(this.rendered)for(c=0;a=
                +b[c];c++)a.render()}};Blockly.BlockSvg.prototype.tab=function(a,b){for(var c=[],d=0,e;e=this.inputList[d];d++){for(var f=0,g;g=e.fieldRow[f];f++)g instanceof Blockly.FieldTextInput&&c.push(g);e.connection&&(e=e.connection.targetBlock())&&c.push(e)}d=c.indexOf(a);-1==d&&(d=b?-1:c.length);(a=c[b?d+1:d-1])?a instanceof Blockly.Field?a.showEditor_():a.tab(null,b):(a=this.getParent())&&a.tab(this,b)};
                +Blockly.BlockSvg.prototype.onMouseDown_=function(a){var b=this.workspace.getGesture(a);b&&b.handleBlockStart(a,this)};Blockly.BlockSvg.prototype.showHelp_=function(){var a=goog.isFunction(this.helpUrl)?this.helpUrl():this.helpUrl;a&&window.open(a)};
                +Blockly.BlockSvg.prototype.showContextMenu_=function(a){if(!this.workspace.options.readOnly&&this.contextMenu){var b=this,c=[];if(this.isDeletable()&&this.isMovable()&&!b.isInFlyout){var d={text:Blockly.Msg.DUPLICATE_BLOCK,enabled:!0,callback:function(){Blockly.duplicate_(b)}};this.getDescendants().length>this.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&this.workspace.options.comments&&(d={enabled:!goog.userAgent.IE},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT,
                +d.callback=function(){b.setCommentText(null)}):(d.text=Blockly.Msg.ADD_COMMENT,d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=1;d<this.inputList.length;d++)if(this.inputList[d-1].type!=Blockly.NEXT_STATEMENT&&this.inputList[d].type!=Blockly.NEXT_STATEMENT){var d={enabled:!0},e=this.getInputsInline();d.text=e?Blockly.Msg.EXTERNAL_INPUTS:Blockly.Msg.INLINE_INPUTS;d.callback=function(){b.setInputsInline(!e)};c.push(d);break}this.workspace.options.collapse&&(this.collapsed_?
                +(d={enabled:!0},d.text=Blockly.Msg.EXPAND_BLOCK,d.callback=function(){b.setCollapsed(!1)}):(d={enabled:!0},d.text=Blockly.Msg.COLLAPSE_BLOCK,d.callback=function(){b.setCollapsed(!0)}),c.push(d));this.workspace.options.disable&&(d={text:this.disabled?Blockly.Msg.ENABLE_BLOCK:Blockly.Msg.DISABLE_BLOCK,enabled:!this.getInheritedDisabled(),callback:function(){b.setDisabled(!b.disabled)}},c.push(d));var d=this.getDescendants().length,f=this.getNextBlock();f&&(d-=f.getDescendants().length);d={text:1==d?
                +Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(d)),enabled:!0,callback:function(){Blockly.Events.setGroup(!0);b.dispose(!0,!0);Blockly.Events.setGroup(!1)}};c.push(d)}d={enabled:!(goog.isFunction(this.helpUrl)?!this.helpUrl():!this.helpUrl)};d.text=Blockly.Msg.HELP;d.callback=function(){b.showHelp_()};c.push(d);this.customContextMenu&&this.customContextMenu(c);Blockly.ContextMenu.show(a,c,this.RTL);Blockly.ContextMenu.currentBlock=this}};
                +Blockly.BlockSvg.prototype.moveConnections_=function(a,b){if(this.rendered){for(var c=this.getConnections_(!1),d=0;d<c.length;d++)c[d].moveBy(a,b);c=this.getIcons();for(d=0;d<c.length;d++)c[d].computeIconLocation();for(d=0;d<this.childBlocks_.length;d++)this.childBlocks_[d].moveConnections_(a,b)}};
                +Blockly.BlockSvg.prototype.setDragging=function(a){if(a){var b=this.getSvgRoot();b.translate_="";b.skew_="";Blockly.draggingConnections_=Blockly.draggingConnections_.concat(this.getConnections_(!0));Blockly.utils.addClass(this.svgGroup_,"blocklyDragging")}else Blockly.draggingConnections_=[],Blockly.utils.removeClass(this.svgGroup_,"blocklyDragging");for(b=0;b<this.childBlocks_.length;b++)this.childBlocks_[b].setDragging(a)};
                +Blockly.BlockSvg.prototype.updateMovable=function(){this.isMovable()?Blockly.utils.addClass(this.svgGroup_,"blocklyDraggable"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDraggable")};Blockly.BlockSvg.prototype.setMovable=function(a){Blockly.BlockSvg.superClass_.setMovable.call(this,a);this.updateMovable()};Blockly.BlockSvg.prototype.setEditable=function(a){Blockly.BlockSvg.superClass_.setEditable.call(this,a);a=this.getIcons();for(var b=0;b<a.length;b++)a[b].updateEditable()};
                +Blockly.BlockSvg.prototype.setShadow=function(a){Blockly.BlockSvg.superClass_.setShadow.call(this,a);this.updateColour()};Blockly.BlockSvg.prototype.getSvgRoot=function(){return this.svgGroup_};
                +Blockly.BlockSvg.prototype.dispose=function(a,b){if(this.workspace){Blockly.Tooltip.hide();Blockly.Field.startCache();var c=this.workspace;Blockly.selected==this&&(this.unselect(),this.workspace.cancelCurrentGesture());Blockly.ContextMenu.currentBlock==this&&Blockly.ContextMenu.hide();b&&this.rendered&&(this.unplug(a),this.disposeUiEffect());this.rendered=!1;Blockly.Events.disable();try{var d=this.getIcons();for(b=0;b<d.length;b++)d[b].dispose()}finally{Blockly.Events.enable()}Blockly.BlockSvg.superClass_.dispose.call(this,
                +a);goog.dom.removeNode(this.svgGroup_);c.resizeContents();this.svgPathDark_=this.svgPathLight_=this.svgPath_=this.svgGroup_=null;Blockly.Field.stopCache()}};
                +Blockly.BlockSvg.prototype.disposeUiEffect=function(){this.workspace.getAudioManager().play("delete");var a=this.workspace.getSvgXY(this.svgGroup_),b=this.svgGroup_.cloneNode(!0);b.translateX_=a.x;b.translateY_=a.y;b.setAttribute("transform","translate("+b.translateX_+","+b.translateY_+")");this.workspace.getParentSvg().appendChild(b);b.bBox_=b.getBBox();Blockly.BlockSvg.disposeUiStep_(b,this.RTL,new Date,this.workspace.scale)};
                +Blockly.BlockSvg.disposeUiStep_=function(a,b,c,d){var e=(new Date-c)/150;1<e?goog.dom.removeNode(a):(a.setAttribute("transform","translate("+(a.translateX_+(b?-1:1)*a.bBox_.width*d/2*e)+","+(a.translateY_+a.bBox_.height*d*e)+") scale("+(1-e)*d+")"),setTimeout(Blockly.BlockSvg.disposeUiStep_,10,a,b,c,d))};
                +Blockly.BlockSvg.prototype.connectionUiEffect=function(){this.workspace.getAudioManager().play("click");if(!(1>this.workspace.scale)){var a=this.workspace.getSvgXY(this.svgGroup_);this.outputConnection?(a.x+=(this.RTL?3:-3)*this.workspace.scale,a.y+=13*this.workspace.scale):this.previousConnection&&(a.x+=(this.RTL?-23:23)*this.workspace.scale,a.y+=3*this.workspace.scale);a=Blockly.utils.createSvgElement("circle",{cx:a.x,cy:a.y,r:0,fill:"none",stroke:"#888","stroke-width":10},this.workspace.getParentSvg());
                +Blockly.BlockSvg.connectionUiStep_(a,new Date,this.workspace.scale)}};Blockly.BlockSvg.connectionUiStep_=function(a,b,c){var d=(new Date-b)/150;1<d?goog.dom.removeNode(a):(a.setAttribute("r",25*d*c),a.style.opacity=1-d,Blockly.BlockSvg.disconnectUiStop_.pid_=setTimeout(Blockly.BlockSvg.connectionUiStep_,10,a,b,c))};
                +Blockly.BlockSvg.prototype.disconnectUiEffect=function(){this.workspace.getAudioManager().play("disconnect");if(!(1>this.workspace.scale)){var a=this.getHeightWidth().height,a=Math.atan(10/a)/Math.PI*180;this.RTL||(a*=-1);Blockly.BlockSvg.disconnectUiStep_(this.svgGroup_,a,new Date)}};
                +Blockly.BlockSvg.disconnectUiStep_=function(a,b,c){var d=(new Date-c)/200;1<d?a.skew_="":(a.skew_="skewX("+Math.round(Math.sin(d*Math.PI*3)*(1-d)*b)+")",Blockly.BlockSvg.disconnectUiStop_.group=a,Blockly.BlockSvg.disconnectUiStop_.pid=setTimeout(Blockly.BlockSvg.disconnectUiStep_,10,a,b,c));a.setAttribute("transform",a.translate_+a.skew_)};
                +Blockly.BlockSvg.disconnectUiStop_=function(){if(Blockly.BlockSvg.disconnectUiStop_.group){clearTimeout(Blockly.BlockSvg.disconnectUiStop_.pid);var a=Blockly.BlockSvg.disconnectUiStop_.group;a.skew_="";a.setAttribute("transform",a.translate_);Blockly.BlockSvg.disconnectUiStop_.group=null}};Blockly.BlockSvg.disconnectUiStop_.pid=0;Blockly.BlockSvg.disconnectUiStop_.group=null;
                +Blockly.BlockSvg.prototype.updateColour=function(){if(!this.disabled){var a=this.getColour(),b=goog.color.hexToRgb(a);if(this.isShadow())b=goog.color.lighten(b,.6),a=goog.color.rgbArrayToHex(b),this.svgPathLight_.style.display="none",this.svgPathDark_.setAttribute("fill",a);else{this.svgPathLight_.style.display="";var c=goog.color.rgbArrayToHex(goog.color.lighten(b,.3)),b=goog.color.rgbArrayToHex(goog.color.darken(b,.2));this.svgPathLight_.setAttribute("stroke",c);this.svgPathDark_.setAttribute("fill",
                +b)}this.svgPath_.setAttribute("fill",a);a=this.getIcons();for(c=0;c<a.length;c++)a[c].updateColour();for(a=0;c=this.inputList[a];a++)for(var b=0,d;d=c.fieldRow[b];b++)d.setText(null)}};
                +Blockly.BlockSvg.prototype.updateDisabled=function(){this.disabled||this.getInheritedDisabled()?Blockly.utils.addClass(this.svgGroup_,"blocklyDisabled")&&this.svgPath_.setAttribute("fill","url(#"+this.workspace.options.disabledPatternId+")"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDisabled")&&this.updateColour();for(var a=this.getChildren(),b=0,c;c=a[b];b++)c.updateDisabled()};
                +Blockly.BlockSvg.prototype.getCommentText=function(){return this.comment?this.comment.getText().replace(/\s+$/,"").replace(/ +\n/g,"\n"):""};Blockly.BlockSvg.prototype.setCommentText=function(a){var b=!1;goog.isString(a)?(this.comment||(this.comment=new Blockly.Comment(this),b=!0),this.comment.setText(a)):this.comment&&(this.comment.dispose(),b=!0);b&&this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.setWarningText=function(a,b){this.setWarningText.pid_||(this.setWarningText.pid_=Object.create(null));var c=b||"";if(c)this.setWarningText.pid_[c]&&(clearTimeout(this.setWarningText.pid_[c]),delete this.setWarningText.pid_[c]);else for(var d in this.setWarningText.pid_)clearTimeout(this.setWarningText.pid_[d]),delete this.setWarningText.pid_[d];if(this.workspace.isDragging()){var e=this;this.setWarningText.pid_[c]=setTimeout(function(){e.workspace&&(delete e.setWarningText.pid_[c],
                +e.setWarningText(a,c))},100)}else{this.isInFlyout&&(a=null);b=this.getSurroundParent();for(d=null;b;)b.isCollapsed()&&(d=b),b=b.getSurroundParent();d&&d.setWarningText(a,"collapsed "+this.id+" "+c);b=!1;goog.isString(a)?(this.warning||(this.warning=new Blockly.Warning(this),b=!0),this.warning.setText(a,c)):this.warning&&!c?(this.warning.dispose(),b=!0):this.warning&&(b=this.warning.getText(),this.warning.setText("",c),(d=this.warning.getText())||this.warning.dispose(),b=b!=d);b&&this.rendered&&(this.render(),
                +this.bumpNeighbours_())}};Blockly.BlockSvg.prototype.setMutator=function(a){this.mutator&&this.mutator!==a&&this.mutator.dispose();a&&(a.block_=this,this.mutator=a,a.createIcon())};Blockly.BlockSvg.prototype.setDisabled=function(a){this.disabled!=a&&(Blockly.BlockSvg.superClass_.setDisabled.call(this,a),this.rendered&&this.updateDisabled())};
                +Blockly.BlockSvg.prototype.setHighlighted=function(a){this.rendered&&(a?(this.svgPath_.setAttribute("filter","url(#"+this.workspace.options.embossFilterId+")"),this.svgPathLight_.style.display="none"):(Blockly.utils.removeAttribute(this.svgPath_,"filter"),delete this.svgPathLight_.style.display))};Blockly.BlockSvg.prototype.addSelect=function(){Blockly.utils.addClass(this.svgGroup_,"blocklySelected")};Blockly.BlockSvg.prototype.removeSelect=function(){Blockly.utils.removeClass(this.svgGroup_,"blocklySelected")};
                +Blockly.BlockSvg.prototype.setDeleteStyle=function(a){a?Blockly.utils.addClass(this.svgGroup_,"blocklyDraggingDelete"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDraggingDelete")};Blockly.BlockSvg.prototype.setColour=function(a){Blockly.BlockSvg.superClass_.setColour.call(this,a);this.rendered&&this.updateColour()};Blockly.BlockSvg.prototype.bringToFront=function(){var a=this;do{var b=a.getSvgRoot();b.parentNode.appendChild(b);a=a.getParent()}while(a)};
                +Blockly.BlockSvg.prototype.setPreviousStatement=function(a,b){Blockly.BlockSvg.superClass_.setPreviousStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.setNextStatement=function(a,b){Blockly.BlockSvg.superClass_.setNextStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.setOutput=function(a,b){Blockly.BlockSvg.superClass_.setOutput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.setInputsInline=function(a){Blockly.BlockSvg.superClass_.setInputsInline.call(this,a);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.removeInput=function(a,b){Blockly.BlockSvg.superClass_.removeInput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.moveNumberedInputBefore=function(a,b){Blockly.BlockSvg.superClass_.moveNumberedInputBefore.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.appendInput_=function(a,b){a=Blockly.BlockSvg.superClass_.appendInput_.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_());return a};Blockly.BlockSvg.prototype.getConnections_=function(a){var b=[];if(a||this.rendered)if(this.outputConnection&&b.push(this.outputConnection),this.previousConnection&&b.push(this.previousConnection),this.nextConnection&&b.push(this.nextConnection),a||!this.collapsed_){a=0;for(var c;c=this.inputList[a];a++)c.connection&&b.push(c.connection)}return b};
                +Blockly.BlockSvg.prototype.makeConnection_=function(a){return new Blockly.RenderedConnection(this,a)};
                +Blockly.BlockSvg.prototype.bumpNeighbours_=function(){if(this.workspace&&Blockly.dragMode_==Blockly.DRAG_NONE){var a=this.getRootBlock();if(!a.isInFlyout)for(var b=this.getConnections_(!1),c=0,d;d=b[c];c++){d.isConnected()&&d.isSuperior()&&d.targetBlock().bumpNeighbours_();for(var e=d.neighbours_(Blockly.SNAP_RADIUS),f=0,g;g=e[f];f++)d.isConnected()&&g.isConnected()||g.getSourceBlock().getRootBlock()!=a&&(d.isSuperior()?g.bumpAwayFrom_(d):d.bumpAwayFrom_(g))}}};
                +Blockly.BlockSvg.prototype.scheduleSnapAndBump=function(){var a=this,b=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(b);a.snapToGrid();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY/2);setTimeout(function(){Blockly.Events.setGroup(b);a.bumpNeighbours_();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY)};Blockly.BlockSvg.render={};Blockly.BlockSvg.SEP_SPACE_X=10;Blockly.BlockSvg.SEP_SPACE_Y=10;Blockly.BlockSvg.INLINE_PADDING_Y=5;Blockly.BlockSvg.MIN_BLOCK_Y=25;Blockly.BlockSvg.TAB_HEIGHT=20;Blockly.BlockSvg.TAB_WIDTH=8;Blockly.BlockSvg.NOTCH_WIDTH=30;Blockly.BlockSvg.CORNER_RADIUS=8;Blockly.BlockSvg.START_HAT=!1;Blockly.BlockSvg.START_HAT_HEIGHT=15;Blockly.BlockSvg.START_HAT_PATH="c 30,-"+Blockly.BlockSvg.START_HAT_HEIGHT+" 70,-"+Blockly.BlockSvg.START_HAT_HEIGHT+" 100,0";
                +Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR="c 17.8,-9.2 45.3,-14.9 75,-8.7 M 100.5,0.5";Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL="m 25,-8.7 c 29.7,-6.2 57.2,-0.5 75,8.7";Blockly.BlockSvg.DISTANCE_45_INSIDE=(1-Math.SQRT1_2)*(Blockly.BlockSvg.CORNER_RADIUS-.5)+.5;Blockly.BlockSvg.DISTANCE_45_OUTSIDE=(1-Math.SQRT1_2)*(Blockly.BlockSvg.CORNER_RADIUS+.5)-.5;Blockly.BlockSvg.NOTCH_PATH_LEFT="l 6,4 3,0 6,-4";Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT="l 6,4 3,0 6,-4";Blockly.BlockSvg.NOTCH_PATH_RIGHT="l -6,4 -3,0 -6,-4";
                +Blockly.BlockSvg.JAGGED_TEETH="l 8,0 0,4 8,4 -16,8 8,4";Blockly.BlockSvg.JAGGED_TEETH_HEIGHT=20;Blockly.BlockSvg.JAGGED_TEETH_WIDTH=15;Blockly.BlockSvg.TAB_PATH_DOWN="v 5 c 0,10 -"+Blockly.BlockSvg.TAB_WIDTH+",-8 -"+Blockly.BlockSvg.TAB_WIDTH+",7.5 s "+Blockly.BlockSvg.TAB_WIDTH+",-2.5 "+Blockly.BlockSvg.TAB_WIDTH+",7.5";
                +Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL="v 6.5 m -"+.97*Blockly.BlockSvg.TAB_WIDTH+",3 q -"+.05*Blockly.BlockSvg.TAB_WIDTH+",10 "+.3*Blockly.BlockSvg.TAB_WIDTH+",9.5 m "+.67*Blockly.BlockSvg.TAB_WIDTH+",-1.9 v 1.4";Blockly.BlockSvg.TOP_LEFT_CORNER_START="m 0,"+Blockly.BlockSvg.CORNER_RADIUS;Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL="m "+Blockly.BlockSvg.DISTANCE_45_INSIDE+","+Blockly.BlockSvg.DISTANCE_45_INSIDE;
                +Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR="m 0.5,"+(Blockly.BlockSvg.CORNER_RADIUS-.5);Blockly.BlockSvg.TOP_LEFT_CORNER="A "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,1 "+Blockly.BlockSvg.CORNER_RADIUS+",0";Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT="A "+(Blockly.BlockSvg.CORNER_RADIUS-.5)+","+(Blockly.BlockSvg.CORNER_RADIUS-.5)+" 0 0,1 "+Blockly.BlockSvg.CORNER_RADIUS+",0.5";
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER=Blockly.BlockSvg.NOTCH_PATH_RIGHT+" h -"+(Blockly.BlockSvg.NOTCH_WIDTH-15-Blockly.BlockSvg.CORNER_RADIUS)+" a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 -"+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS;Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER="a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS;
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL="a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 "+(-Blockly.BlockSvg.DISTANCE_45_OUTSIDE-.5)+","+(Blockly.BlockSvg.CORNER_RADIUS-Blockly.BlockSvg.DISTANCE_45_OUTSIDE);Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL="a "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5)+" 0 0,0 "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5);
                +Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR="a "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5)+" 0 0,0 "+(Blockly.BlockSvg.CORNER_RADIUS-Blockly.BlockSvg.DISTANCE_45_OUTSIDE)+","+(Blockly.BlockSvg.DISTANCE_45_OUTSIDE+.5);Blockly.BlockSvg.prototype.getHeightWidth=function(){var a=this.height,b=this.width,c=this.getNextBlock();c?(c=c.getHeightWidth(),a+=c.height-4,b=Math.max(b,c.width)):this.nextConnection||this.outputConnection||(a+=2);return{height:a,width:b}};
                +Blockly.BlockSvg.prototype.render=function(a){Blockly.Field.startCache();this.rendered=!0;var b=Blockly.BlockSvg.SEP_SPACE_X;this.RTL&&(b=-b);for(var c=this.getIcons(),d=0;d<c.length;d++)b=c[d].renderIcon(b);b+=this.RTL?Blockly.BlockSvg.SEP_SPACE_X:-Blockly.BlockSvg.SEP_SPACE_X;c=this.renderCompute_(b);this.renderDraw_(b,c);this.renderMoveConnections_();!1!==a&&((a=this.getParent())?a.render(!0):this.workspace.resizeContents());Blockly.Field.stopCache()};
                +Blockly.BlockSvg.prototype.renderFields_=function(a,b,c){c+=Blockly.BlockSvg.INLINE_PADDING_Y;this.RTL&&(b=-b);for(var d=0,e;e=a[d];d++){var f=e.getSvgRoot();f&&((goog.userAgent.IE||goog.userAgent.EDGE)&&e.updateWidth(),this.RTL?(b-=e.renderSep+e.renderWidth,f.setAttribute("transform","translate("+b+","+c+")"),e.renderWidth&&(b-=Blockly.BlockSvg.SEP_SPACE_X)):(f.setAttribute("transform","translate("+(b+e.renderSep)+","+c+")"),e.renderWidth&&(b+=e.renderSep+e.renderWidth+Blockly.BlockSvg.SEP_SPACE_X)))}return this.RTL?
                +-b:b};
                +Blockly.BlockSvg.prototype.renderCompute_=function(a){var b=this.inputList,c=[];c.rightEdge=a+2*Blockly.BlockSvg.SEP_SPACE_X;if(this.previousConnection||this.nextConnection)c.rightEdge=Math.max(c.rightEdge,Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.SEP_SPACE_X);for(var d=0,e=0,f=!1,g=!1,h=!1,k=void 0,l=this.getInputsInline()&&!this.isCollapsed(),m=0,n;n=b[m];m++)if(n.isVisible()){if(l&&k&&k!=Blockly.NEXT_STATEMENT&&n.type!=Blockly.NEXT_STATEMENT)var p=c[c.length-1];else k=n.type,p=[],p.type=l&&
                +n.type!=Blockly.NEXT_STATEMENT?Blockly.BlockSvg.INLINE:n.type,p.height=0,c.push(p);p.push(n);n.renderHeight=Blockly.BlockSvg.MIN_BLOCK_Y;n.renderWidth=l&&n.type==Blockly.INPUT_VALUE?Blockly.BlockSvg.TAB_WIDTH+1.25*Blockly.BlockSvg.SEP_SPACE_X:0;if(n.connection&&n.connection.isConnected()){var q=n.connection.targetBlock().getHeightWidth();n.renderHeight=Math.max(n.renderHeight,q.height);n.renderWidth=Math.max(n.renderWidth,q.width)}l||m!=b.length-1?!l&&n.type==Blockly.INPUT_VALUE&&b[m+1]&&b[m+1].type==
                +Blockly.NEXT_STATEMENT&&n.renderHeight--:n.renderHeight--;p.height=Math.max(p.height,n.renderHeight);n.fieldWidth=0;1==c.length&&(n.fieldWidth+=this.RTL?-a:a);for(var q=!1,t=0,r;r=n.fieldRow[t];t++){0!=t&&(n.fieldWidth+=Blockly.BlockSvg.SEP_SPACE_X);var u=r.getSize();r.renderWidth=u.width;r.renderSep=q&&r.EDITABLE?Blockly.BlockSvg.SEP_SPACE_X:0;n.fieldWidth+=r.renderWidth+r.renderSep;p.height=Math.max(p.height,u.height);q=r.EDITABLE}p.type!=Blockly.BlockSvg.INLINE&&(p.type==Blockly.NEXT_STATEMENT?
                +(g=!0,e=Math.max(e,n.fieldWidth)):(p.type==Blockly.INPUT_VALUE?f=!0:p.type==Blockly.DUMMY_INPUT&&(h=!0),d=Math.max(d,n.fieldWidth)))}for(a=0;p=c[a];a++)if(p.thicker=!1,p.type==Blockly.BlockSvg.INLINE)for(b=0;n=p[b];b++)if(n.type==Blockly.INPUT_VALUE){p.height+=2*Blockly.BlockSvg.INLINE_PADDING_Y;p.thicker=!0;break}c.statementEdge=2*Blockly.BlockSvg.SEP_SPACE_X+e;g&&(c.rightEdge=Math.max(c.rightEdge,c.statementEdge+Blockly.BlockSvg.NOTCH_WIDTH));f?c.rightEdge=Math.max(c.rightEdge,d+2*Blockly.BlockSvg.SEP_SPACE_X+
                +Blockly.BlockSvg.TAB_WIDTH):h&&(c.rightEdge=Math.max(c.rightEdge,d+2*Blockly.BlockSvg.SEP_SPACE_X));c.hasValue=f;c.hasStatement=g;c.hasDummy=h;return c};
                +Blockly.BlockSvg.prototype.renderDraw_=function(a,b){this.startHat_=!1;this.height=0;if(this.outputConnection)this.squareBottomLeftCorner_=this.squareTopLeftCorner_=!0;else{this.squareBottomLeftCorner_=this.squareTopLeftCorner_=!1;if(this.previousConnection){var c=this.previousConnection.targetBlock();c&&c.getNextBlock()==this&&(this.squareTopLeftCorner_=!0)}else Blockly.BlockSvg.START_HAT&&(this.startHat_=this.squareTopLeftCorner_=!0,this.height+=Blockly.BlockSvg.START_HAT_HEIGHT,b.rightEdge=Math.max(b.rightEdge,
                +100));this.getNextBlock()&&(this.squareBottomLeftCorner_=!0)}var d=[],e=[],c=[],f=[];this.renderDrawTop_(d,c,b.rightEdge);a=this.renderDrawRight_(d,c,e,f,b,a);this.renderDrawBottom_(d,c,a);this.renderDrawLeft_(d,c);a=d.join(" ")+"\n"+e.join(" ");this.svgPath_.setAttribute("d",a);this.svgPathDark_.setAttribute("d",a);a=c.join(" ")+"\n"+f.join(" ");this.svgPathLight_.setAttribute("d",a);this.RTL&&(this.svgPath_.setAttribute("transform","scale(-1 1)"),this.svgPathLight_.setAttribute("transform","scale(-1 1)"),
                +this.svgPathDark_.setAttribute("transform","translate(1,1) scale(-1 1)"))};
                +Blockly.BlockSvg.prototype.renderMoveConnections_=function(){var a=this.getRelativeToSurfaceXY();this.previousConnection&&this.previousConnection.moveToOffset(a);this.outputConnection&&this.outputConnection.moveToOffset(a);for(var b=0;b<this.inputList.length;b++){var c=this.inputList[b].connection;c&&(c.moveToOffset(a),c.isConnected()&&c.tighten_())}this.nextConnection&&(this.nextConnection.moveToOffset(a),this.nextConnection.isConnected()&&this.nextConnection.tighten_())};
                +Blockly.BlockSvg.prototype.renderDrawTop_=function(a,b,c){this.squareTopLeftCorner_?(a.push("m 0,0"),b.push("m 0.5,0.5"),this.startHat_&&(a.push(Blockly.BlockSvg.START_HAT_PATH),b.push(this.RTL?Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL:Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR))):(a.push(Blockly.BlockSvg.TOP_LEFT_CORNER_START),b.push(this.RTL?Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL:Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR),a.push(Blockly.BlockSvg.TOP_LEFT_CORNER),b.push(Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT));
                +this.previousConnection&&(a.push("H",Blockly.BlockSvg.NOTCH_WIDTH-15),b.push("H",Blockly.BlockSvg.NOTCH_WIDTH-15),a.push(Blockly.BlockSvg.NOTCH_PATH_LEFT),b.push(Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT),this.previousConnection.setOffsetInBlock(this.RTL?-Blockly.BlockSvg.NOTCH_WIDTH:Blockly.BlockSvg.NOTCH_WIDTH,0));a.push("H",c);b.push("H",c-.5);this.width=c};
                +Blockly.BlockSvg.prototype.renderDrawRight_=function(a,b,c,d,e,f){for(var g,h,k,l,m=0,n,p=0,q;q=e[p];p++){h=Blockly.BlockSvg.SEP_SPACE_X;0==p&&(h+=this.RTL?-f:f);b.push("M",e.rightEdge-.5+","+(m+.5));if(this.isCollapsed())l=q[0],k=h,h=m,this.renderFields_(l.fieldRow,k,h),a.push(Blockly.BlockSvg.JAGGED_TEETH),b.push("h 8"),l=q.height-Blockly.BlockSvg.JAGGED_TEETH_HEIGHT,a.push("v",l),this.RTL&&(b.push("v 3.9 l 7.2,3.4 m -14.5,8.9 l 7.3,3.5"),b.push("v",l-.7)),this.width+=Blockly.BlockSvg.JAGGED_TEETH_WIDTH;
                +else if(q.type==Blockly.BlockSvg.INLINE){for(g=0;l=q[g];g++)k=h,h=m,q.thicker&&(h+=Blockly.BlockSvg.INLINE_PADDING_Y),h=this.renderFields_(l.fieldRow,k,h),l.type!=Blockly.DUMMY_INPUT&&(h+=l.renderWidth+Blockly.BlockSvg.SEP_SPACE_X),l.type==Blockly.INPUT_VALUE&&(c.push("M",h-Blockly.BlockSvg.SEP_SPACE_X+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y)),c.push("h",Blockly.BlockSvg.TAB_WIDTH-2-l.renderWidth),c.push(Blockly.BlockSvg.TAB_PATH_DOWN),c.push("v",l.renderHeight+1-Blockly.BlockSvg.TAB_HEIGHT),c.push("h",
                +l.renderWidth+2-Blockly.BlockSvg.TAB_WIDTH),c.push("z"),this.RTL?(d.push("M",h-Blockly.BlockSvg.SEP_SPACE_X-2.5+Blockly.BlockSvg.TAB_WIDTH-l.renderWidth+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+.5)),d.push(Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL),d.push("v",l.renderHeight-Blockly.BlockSvg.TAB_HEIGHT+2.5),d.push("h",l.renderWidth-Blockly.BlockSvg.TAB_WIDTH+2)):(d.push("M",h-Blockly.BlockSvg.SEP_SPACE_X+.5+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+.5)),d.push("v",l.renderHeight+1),d.push("h",Blockly.BlockSvg.TAB_WIDTH-
                +2-l.renderWidth),d.push("M",h-l.renderWidth-Blockly.BlockSvg.SEP_SPACE_X+.9+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+Blockly.BlockSvg.TAB_HEIGHT-.7)),d.push("l",.46*Blockly.BlockSvg.TAB_WIDTH+",-2.1")),k=this.RTL?-h-Blockly.BlockSvg.TAB_WIDTH+Blockly.BlockSvg.SEP_SPACE_X+l.renderWidth+1:h+Blockly.BlockSvg.TAB_WIDTH-Blockly.BlockSvg.SEP_SPACE_X-l.renderWidth-1,n=m+Blockly.BlockSvg.INLINE_PADDING_Y+1,l.connection.setOffsetInBlock(k,n));h=Math.max(h,e.rightEdge);this.width=Math.max(this.width,h);a.push("H",
                +h);b.push("H",h-.5);a.push("v",q.height);this.RTL&&b.push("v",q.height-1)}else q.type==Blockly.INPUT_VALUE?(l=q[0],k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.rightEdge-l.fieldWidth-Blockly.BlockSvg.TAB_WIDTH-2*Blockly.BlockSvg.SEP_SPACE_X,l.align==Blockly.ALIGN_RIGHT?k+=g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),a.push(Blockly.BlockSvg.TAB_PATH_DOWN),g=q.height-Blockly.BlockSvg.TAB_HEIGHT,a.push("v",g),this.RTL?(b.push(Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL),
                +b.push("v",g+.5)):(b.push("M",e.rightEdge-5+","+(m+Blockly.BlockSvg.TAB_HEIGHT-.7)),b.push("l",.46*Blockly.BlockSvg.TAB_WIDTH+",-2.1")),k=this.RTL?-e.rightEdge-1:e.rightEdge+1,l.connection.setOffsetInBlock(k,m),l.connection.isConnected()&&(this.width=Math.max(this.width,e.rightEdge+l.connection.targetBlock().getHeightWidth().width-Blockly.BlockSvg.TAB_WIDTH+1))):q.type==Blockly.DUMMY_INPUT?(l=q[0],k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.rightEdge-l.fieldWidth-2*Blockly.BlockSvg.SEP_SPACE_X,e.hasValue&&
                +(g-=Blockly.BlockSvg.TAB_WIDTH),l.align==Blockly.ALIGN_RIGHT?k+=g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),a.push("v",q.height),this.RTL&&b.push("v",q.height-1)):q.type==Blockly.NEXT_STATEMENT&&(l=q[0],0==p&&(a.push("v",Blockly.BlockSvg.SEP_SPACE_Y),this.RTL&&b.push("v",Blockly.BlockSvg.SEP_SPACE_Y-1),m+=Blockly.BlockSvg.SEP_SPACE_Y),k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.statementEdge-l.fieldWidth-2*Blockly.BlockSvg.SEP_SPACE_X,l.align==Blockly.ALIGN_RIGHT?k+=
                +g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),h=e.statementEdge+Blockly.BlockSvg.NOTCH_WIDTH,a.push("H",h),a.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER),a.push("v",q.height-2*Blockly.BlockSvg.CORNER_RADIUS),a.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER),a.push("H",e.rightEdge),this.RTL?(b.push("M",h-Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.DISTANCE_45_OUTSIDE+","+(m+Blockly.BlockSvg.DISTANCE_45_OUTSIDE)),b.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL),
                +b.push("v",q.height-2*Blockly.BlockSvg.CORNER_RADIUS),b.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL)):(b.push("M",h-Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.DISTANCE_45_OUTSIDE+","+(m+q.height-Blockly.BlockSvg.DISTANCE_45_OUTSIDE)),b.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR)),b.push("H",e.rightEdge-.5),k=this.RTL?-h:h+1,l.connection.setOffsetInBlock(k,m+1),l.connection.isConnected()&&(this.width=Math.max(this.width,e.statementEdge+l.connection.targetBlock().getHeightWidth().width)),
                +p==e.length-1||e[p+1].type==Blockly.NEXT_STATEMENT)&&(a.push("v",Blockly.BlockSvg.SEP_SPACE_Y),this.RTL&&b.push("v",Blockly.BlockSvg.SEP_SPACE_Y-1),m+=Blockly.BlockSvg.SEP_SPACE_Y);m+=q.height}e.length||(m=Blockly.BlockSvg.MIN_BLOCK_Y,a.push("V",m),this.RTL&&b.push("V",m-1));return m};
                +Blockly.BlockSvg.prototype.renderDrawBottom_=function(a,b,c){this.height+=c+1;this.nextConnection&&(a.push("H",Blockly.BlockSvg.NOTCH_WIDTH+(this.RTL?.5:-.5)+" "+Blockly.BlockSvg.NOTCH_PATH_RIGHT),this.nextConnection.setOffsetInBlock(this.RTL?-Blockly.BlockSvg.NOTCH_WIDTH:Blockly.BlockSvg.NOTCH_WIDTH,c+1),this.height+=4);this.squareBottomLeftCorner_?(a.push("H 0"),this.RTL||b.push("M","0.5,"+(c-.5))):(a.push("H",Blockly.BlockSvg.CORNER_RADIUS),a.push("a",Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+
                +" 0 0,1 -"+Blockly.BlockSvg.CORNER_RADIUS+",-"+Blockly.BlockSvg.CORNER_RADIUS),this.RTL||(b.push("M",Blockly.BlockSvg.DISTANCE_45_INSIDE+","+(c-Blockly.BlockSvg.DISTANCE_45_INSIDE)),b.push("A",Blockly.BlockSvg.CORNER_RADIUS-.5+","+(Blockly.BlockSvg.CORNER_RADIUS-.5)+" 0 0,1 0.5,"+(c-Blockly.BlockSvg.CORNER_RADIUS))))};
                +Blockly.BlockSvg.prototype.renderDrawLeft_=function(a,b){this.outputConnection?(this.outputConnection.setOffsetInBlock(0,0),a.push("V",Blockly.BlockSvg.TAB_HEIGHT),a.push("c 0,-10 -"+Blockly.BlockSvg.TAB_WIDTH+",8 -"+Blockly.BlockSvg.TAB_WIDTH+",-7.5 s "+Blockly.BlockSvg.TAB_WIDTH+",2.5 "+Blockly.BlockSvg.TAB_WIDTH+",-7.5"),this.RTL?(b.push("M",-.25*Blockly.BlockSvg.TAB_WIDTH+",8.4"),b.push("l",-.45*Blockly.BlockSvg.TAB_WIDTH+",-2.1")):(b.push("V",Blockly.BlockSvg.TAB_HEIGHT-1.5),b.push("m",-.92*
                +Blockly.BlockSvg.TAB_WIDTH+",-0.5 q "+-.19*Blockly.BlockSvg.TAB_WIDTH+",-5.5 0,-11"),b.push("m",.92*Blockly.BlockSvg.TAB_WIDTH+",1 V 0.5 H 1")),this.width+=Blockly.BlockSvg.TAB_WIDTH):this.RTL||(this.squareTopLeftCorner_?b.push("V",.5):b.push("V",Blockly.BlockSvg.CORNER_RADIUS));a.push("z")};Blockly.Events={};Blockly.Events.group_="";Blockly.Events.recordUndo=!0;Blockly.Events.disabled_=0;Blockly.Events.CREATE="create";Blockly.Events.BLOCK_CREATE=Blockly.Events.CREATE;Blockly.Events.DELETE="delete";Blockly.Events.BLOCK_DELETE=Blockly.Events.DELETE;Blockly.Events.CHANGE="change";Blockly.Events.BLOCK_CHANGE=Blockly.Events.CHANGE;Blockly.Events.MOVE="move";Blockly.Events.BLOCK_MOVE=Blockly.Events.MOVE;Blockly.Events.VAR_CREATE="var_create";Blockly.Events.VAR_DELETE="var_delete";
                +Blockly.Events.VAR_RENAME="var_rename";Blockly.Events.UI="ui";Blockly.Events.FIRE_QUEUE_=[];Blockly.Events.fire=function(a){Blockly.Events.isEnabled()&&(Blockly.Events.FIRE_QUEUE_.length||setTimeout(Blockly.Events.fireNow_,0),Blockly.Events.FIRE_QUEUE_.push(a))};Blockly.Events.fireNow_=function(){for(var a=Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_,!0),b=Blockly.Events.FIRE_QUEUE_.length=0,c;c=a[b];b++){var d=Blockly.Workspace.getById(c.workspaceId);d&&d.fireChangeListener(c)}};
                +Blockly.Events.filter=function(a,b){a=goog.array.clone(a);b||a.reverse();for(var c=0,d;d=a[c];c++)for(var e=c+1,f;f=a[e];e++)d.type==f.type&&d.blockId==f.blockId&&d.workspaceId==f.workspaceId&&(d.type==Blockly.Events.MOVE?(d.newParentId=f.newParentId,d.newInputName=f.newInputName,d.newCoordinate=f.newCoordinate,a.splice(e,1),e--):d.type==Blockly.Events.CHANGE&&d.element==f.element&&d.name==f.name?(d.newValue=f.newValue,a.splice(e,1),e--):d.type!=Blockly.Events.UI||"click"!=f.element||"commentOpen"!=
                +d.element&&"mutatorOpen"!=d.element&&"warningOpen"!=d.element||(d.newValue=f.newValue,a.splice(e,1),e--));for(c=a.length-1;0<=c;c--)a[c].isNull()&&a.splice(c,1);b||a.reverse();for(c=1;b=a[c];c++)b.type==Blockly.Events.CHANGE&&"mutation"==b.element&&a.unshift(a.splice(c,1)[0]);return a};Blockly.Events.clearPendingUndo=function(){for(var a=0,b;b=Blockly.Events.FIRE_QUEUE_[a];a++)b.recordUndo=!1};Blockly.Events.disable=function(){Blockly.Events.disabled_++};Blockly.Events.enable=function(){Blockly.Events.disabled_--};
                +Blockly.Events.isEnabled=function(){return 0==Blockly.Events.disabled_};Blockly.Events.getGroup=function(){return Blockly.Events.group_};Blockly.Events.setGroup=function(a){Blockly.Events.group_="boolean"==typeof a?a?Blockly.utils.genUid():"":a};Blockly.Events.getDescendantIds_=function(a){var b=[];a=a.getDescendants();for(var c=0,d;d=a[c];c++)b[c]=d.id;return b};
                +Blockly.Events.fromJson=function(a,b){switch(a.type){case Blockly.Events.CREATE:var c=new Blockly.Events.Create(null);break;case Blockly.Events.DELETE:c=new Blockly.Events.Delete(null);break;case Blockly.Events.CHANGE:c=new Blockly.Events.Change(null);break;case Blockly.Events.MOVE:c=new Blockly.Events.Move(null);break;case Blockly.Events.VAR_CREATE:c=new Blockly.Events.VarCreate(null);break;case Blockly.Events.VAR_DELETE:c=new Blockly.Events.VarDelete(null);break;case Blockly.Events.VAR_RENAME:c=
                +new Blockly.Events.VarRename(null);break;case Blockly.Events.UI:c=new Blockly.Events.Ui(null);break;default:throw"Unknown event type.";}c.fromJson(a);c.workspaceId=b.id;return c};Blockly.Events.Abstract=function(a){a instanceof Blockly.Block?(this.blockId=a.id,this.workspaceId=a.workspace.id):a instanceof Blockly.VariableModel&&(this.workspaceId=a.workspace.id,this.varId=a.getId());this.group=Blockly.Events.group_;this.recordUndo=Blockly.Events.recordUndo};
                +Blockly.Events.Abstract.prototype.toJson=function(){var a={type:this.type};this.blockId&&(a.blockId=this.blockId);this.varId&&(a.varId=this.varId);this.group&&(a.group=this.group);return a};Blockly.Events.Abstract.prototype.fromJson=function(a){this.blockId=a.blockId;this.varId=a.varId;this.group=a.group};Blockly.Events.Abstract.prototype.isNull=function(){return!1};Blockly.Events.Abstract.prototype.run=function(a){};
                +Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.Events.Create=function(a){a&&(Blockly.Events.Create.superClass_.constructor.call(this,a),this.xml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a),this.ids=Blockly.Events.getDescendantIds_(a))};goog.inherits(Blockly.Events.Create,Blockly.Events.Abstract);
                +Blockly.Events.BlockCreate=Blockly.Events.Create;Blockly.Events.Create.prototype.type=Blockly.Events.CREATE;Blockly.Events.Create.prototype.toJson=function(){var a=Blockly.Events.Create.superClass_.toJson.call(this);a.xml=Blockly.Xml.domToText(this.xml);a.ids=this.ids;return a};Blockly.Events.Create.prototype.fromJson=function(a){Blockly.Events.Create.superClass_.fromJson.call(this,a);this.xml=Blockly.Xml.textToDom("<xml>"+a.xml+"</xml>").firstChild;this.ids=a.ids};
                +Blockly.Events.Create.prototype.run=function(a){var b=this.getEventWorkspace_();if(a)a=goog.dom.createDom("xml"),a.appendChild(this.xml),Blockly.Xml.domToWorkspace(a,b);else{a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1,!1):c==this.blockId&&console.warn("Can't uncreate non-existant block: "+c)}}};
                +Blockly.Events.Delete=function(a){if(a){if(a.getParent())throw"Connected blocks cannot be deleted.";Blockly.Events.Delete.superClass_.constructor.call(this,a);this.oldXml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a);this.ids=Blockly.Events.getDescendantIds_(a)}};goog.inherits(Blockly.Events.Delete,Blockly.Events.Abstract);Blockly.Events.BlockDelete=Blockly.Events.Delete;Blockly.Events.Delete.prototype.type=Blockly.Events.DELETE;
                +Blockly.Events.Delete.prototype.toJson=function(){var a=Blockly.Events.Delete.superClass_.toJson.call(this);a.ids=this.ids;return a};Blockly.Events.Delete.prototype.fromJson=function(a){Blockly.Events.Delete.superClass_.fromJson.call(this,a);this.ids=a.ids};
                +Blockly.Events.Delete.prototype.run=function(a){var b=this.getEventWorkspace_();if(a){a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1,!1):c==this.blockId&&console.warn("Can't delete non-existant block: "+c)}}else a=goog.dom.createDom("xml"),a.appendChild(this.oldXml),Blockly.Xml.domToWorkspace(a,b)};Blockly.Events.Change=function(a,b,c,d,e){a&&(Blockly.Events.Change.superClass_.constructor.call(this,a),this.element=b,this.name=c,this.oldValue=d,this.newValue=e)};
                +goog.inherits(Blockly.Events.Change,Blockly.Events.Abstract);Blockly.Events.BlockChange=Blockly.Events.Change;Blockly.Events.Change.prototype.type=Blockly.Events.CHANGE;Blockly.Events.Change.prototype.toJson=function(){var a=Blockly.Events.Change.superClass_.toJson.call(this);a.element=this.element;this.name&&(a.name=this.name);a.newValue=this.newValue;return a};
                +Blockly.Events.Change.prototype.fromJson=function(a){Blockly.Events.Change.superClass_.fromJson.call(this,a);this.element=a.element;this.name=a.name;this.newValue=a.newValue};Blockly.Events.Change.prototype.isNull=function(){return this.oldValue==this.newValue};
                +Blockly.Events.Change.prototype.run=function(a){var b=this.getEventWorkspace_().getBlockById(this.blockId);if(b)switch(b.mutator&&b.mutator.setVisible(!1),a=a?this.newValue:this.oldValue,this.element){case "field":(b=b.getField(this.name))?(b.callValidator(a),b.setValue(a)):console.warn("Can't set non-existant field: "+this.name);break;case "comment":b.setCommentText(a||null);break;case "collapsed":b.setCollapsed(a);break;case "disabled":b.setDisabled(a);break;case "inline":b.setInputsInline(a);break;
                +case "mutation":var c="";b.mutationToDom&&(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){a=a||"<mutation></mutation>";var d=Blockly.Xml.textToDom("<xml>"+a+"</xml>");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a));break;default:console.warn("Unknown change type: "+this.element)}else console.warn("Can't change non-existant block: "+this.blockId)};
                +Blockly.Events.Move=function(a){a&&(Blockly.Events.Move.superClass_.constructor.call(this,a),a=this.currentLocation_(),this.oldParentId=a.parentId,this.oldInputName=a.inputName,this.oldCoordinate=a.coordinate)};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract);Blockly.Events.BlockMove=Blockly.Events.Move;Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;
                +Blockly.Events.Move.prototype.toJson=function(){var a=Blockly.Events.Move.superClass_.toJson.call(this);this.newParentId&&(a.newParentId=this.newParentId);this.newInputName&&(a.newInputName=this.newInputName);this.newCoordinate&&(a.newCoordinate=Math.round(this.newCoordinate.x)+","+Math.round(this.newCoordinate.y));return a};
                +Blockly.Events.Move.prototype.fromJson=function(a){Blockly.Events.Move.superClass_.fromJson.call(this,a);this.newParentId=a.newParentId;this.newInputName=a.newInputName;a.newCoordinate&&(a=a.newCoordinate.split(","),this.newCoordinate=new goog.math.Coordinate(parseFloat(a[0]),parseFloat(a[1])))};Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};
                +Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Workspace.getById(this.workspaceId).getBlockById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)};
                +Blockly.Events.Move.prototype.run=function(a){var b=this.getEventWorkspace_(),c=b.getBlockById(this.blockId);if(c){var d=a?this.newParentId:this.oldParentId,e=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var f=null;if(d&&(f=b.getBlockById(d),!f)){console.warn("Can't connect to non-existant block: "+d);return}c.getParent()&&c.unplug();if(a)e=c.getRelativeToSurfaceXY(),c.moveBy(a.x-e.x,a.y-e.y);else{var c=c.outputConnection||c.previousConnection;if(e){if(b=f.getInput(e))var g=
                +b.connection}else c.type==Blockly.PREVIOUS_STATEMENT&&(g=f.nextConnection);g?c.connect(g):console.warn("Can't connect to non-existant input: "+e)}}else console.warn("Can't move non-existant block: "+this.blockId)};Blockly.Events.Ui=function(a,b,c,d){Blockly.Events.Ui.superClass_.constructor.call(this,a);this.element=b;this.oldValue=c;this.newValue=d;this.recordUndo=!1};goog.inherits(Blockly.Events.Ui,Blockly.Events.Abstract);Blockly.Events.Ui.prototype.type=Blockly.Events.UI;
                +Blockly.Events.Ui.prototype.toJson=function(){var a=Blockly.Events.Ui.superClass_.toJson.call(this);a.element=this.element;void 0!==this.newValue&&(a.newValue=this.newValue);return a};Blockly.Events.Ui.prototype.fromJson=function(a){Blockly.Events.Ui.superClass_.fromJson.call(this,a);this.element=a.element;this.newValue=a.newValue};Blockly.Events.VarCreate=function(a){a&&(Blockly.Events.VarCreate.superClass_.constructor.call(this,a),this.varType=a.type,this.varName=a.name)};
                +goog.inherits(Blockly.Events.VarCreate,Blockly.Events.Abstract);Blockly.Events.VarCreate.prototype.type=Blockly.Events.VAR_CREATE;Blockly.Events.VarCreate.prototype.toJson=function(){var a=Blockly.Events.VarCreate.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a};Blockly.Events.VarCreate.prototype.fromJson=function(a){Blockly.Events.VarCreate.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};
                +Blockly.Events.VarCreate.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.createVariable(this.varName,this.varType,this.varId):b.deleteVariableById(this.varId)};Blockly.Events.VarDelete=function(a){a&&(Blockly.Events.VarDelete.superClass_.constructor.call(this,a),this.varType=a.type,this.varName=a.name)};goog.inherits(Blockly.Events.VarDelete,Blockly.Events.Abstract);Blockly.Events.VarDelete.prototype.type=Blockly.Events.VAR_DELETE;
                +Blockly.Events.VarDelete.prototype.toJson=function(){var a=Blockly.Events.VarDelete.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a};Blockly.Events.VarDelete.prototype.fromJson=function(a){Blockly.Events.VarDelete.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};Blockly.Events.VarDelete.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.deleteVariableById(this.varId):b.createVariable(this.varName,this.varType,this.varId)};
                +Blockly.Events.VarRename=function(a,b){a&&(Blockly.Events.VarRename.superClass_.constructor.call(this,a),this.oldName=a.name,this.newName=b)};goog.inherits(Blockly.Events.VarRename,Blockly.Events.Abstract);Blockly.Events.VarRename.prototype.type=Blockly.Events.VAR_RENAME;Blockly.Events.VarRename.prototype.toJson=function(){var a=Blockly.Events.VarRename.superClass_.toJson.call(this);a.oldName=this.oldName;a.newName=this.newName;return a};
                +Blockly.Events.VarRename.prototype.fromJson=function(a){Blockly.Events.VarRename.superClass_.fromJson.call(this,a);this.oldName=a.oldName;this.newName=a.newName};Blockly.Events.VarRename.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.renameVariableById(this.varId,this.newName):b.renameVariableById(this.varId,this.oldName)};
                +Blockly.Events.disableOrphans=function(a){if(a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE){Blockly.Events.disable();var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId))if(a.getParent()&&!a.getParent().disabled){b=a.getDescendants();a=0;for(var c;c=b[a];a++)c.setDisabled(!1)}else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setDisabled(!0),a=a.getNextBlock();while(a)}Blockly.Events.enable()}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
                +Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_){var b=this.callValidator(a);null!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.text_,a)),Blockly.Field.prototype.setText.call(this,a)))};
                +Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};
                +Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;if(!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)){var b=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(a){b.sourceBlock_&&(a=b.callValidator(a));b.setValue(a)})}else{Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var c=Blockly.WidgetDiv.DIV,d=goog.dom.createDom("INPUT","blocklyHtmlInput");d.setAttribute("spellcheck",
                +this.spellcheck_);var e=Blockly.FieldTextInput.FONTSIZE*this.workspace_.scale+"pt";c.style.fontSize=e;d.style.fontSize=e;Blockly.FieldTextInput.htmlInput_=d;c.appendChild(d);d.value=d.defaultValue=this.text_;d.oldValue_=null;this.validate_();this.resizeEditor_();a||(d.focus(),d.select());d.onKeyDownWrapper_=Blockly.bindEventWithChecks_(d,"keydown",this,this.onHtmlInputKeyDown_);d.onKeyUpWrapper_=Blockly.bindEventWithChecks_(d,"keyup",this,this.onHtmlInputChange_);d.onKeyPressWrapper_=Blockly.bindEventWithChecks_(d,
                +"keypress",this,this.onHtmlInputChange_);d.onWorkspaceChangeWrapper_=this.resizeEditor_.bind(this);this.workspace_.addChangeListener(d.onWorkspaceChangeWrapper_)}};Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_=function(a){var b=Blockly.FieldTextInput.htmlInput_;13==a.keyCode?Blockly.WidgetDiv.hide():27==a.keyCode?(b.value=b.defaultValue,Blockly.WidgetDiv.hide()):9==a.keyCode&&(Blockly.WidgetDiv.hide(),this.sourceBlock_.tab(this,!a.shiftKey),a.preventDefault())};
                +Blockly.FieldTextInput.prototype.onHtmlInputChange_=function(a){a=Blockly.FieldTextInput.htmlInput_;var b=a.value;b!==a.oldValue_?(a.oldValue_=b,this.setValue(b),this.validate_()):goog.userAgent.WEBKIT&&this.sourceBlock_.render();this.resizeEditor_();Blockly.svgResize(this.sourceBlock_.workspace)};
                +Blockly.FieldTextInput.prototype.validate_=function(){var a=!0;goog.asserts.assertObject(Blockly.FieldTextInput.htmlInput_);var b=Blockly.FieldTextInput.htmlInput_;this.sourceBlock_&&(a=this.callValidator(b.value));null===a?Blockly.utils.addClass(b,"blocklyInvalidInput"):Blockly.utils.removeClass(b,"blocklyInvalidInput")};
                +Blockly.FieldTextInput.prototype.resizeEditor_=function(){var a=Blockly.WidgetDiv.DIV,b=this.fieldGroup_.getBBox();a.style.width=b.width*this.workspace_.scale+"px";a.style.height=b.height*this.workspace_.scale+"px";b=this.getAbsoluteXY_();if(this.sourceBlock_.RTL){var c=this.getScaledBBox_();b.x+=c.width;b.x-=a.offsetWidth}b.y+=1;goog.userAgent.GECKO&&Blockly.WidgetDiv.DIV.style.top&&(--b.x,--b.y);goog.userAgent.WEBKIT&&(b.y-=3);a.style.left=b.x+"px";a.style.top=b.y+"px"};
                +Blockly.FieldTextInput.prototype.widgetDispose_=function(){var a=this;return function(){var b=Blockly.FieldTextInput.htmlInput_,c=b.value;if(a.sourceBlock_)if(c=a.callValidator(c),null===c)c=b.defaultValue;else if(a.onFinishEditing_)a.onFinishEditing_(c);a.setText(c);a.sourceBlock_.rendered&&a.sourceBlock_.render();Blockly.unbindEvent_(b.onKeyDownWrapper_);Blockly.unbindEvent_(b.onKeyUpWrapper_);Blockly.unbindEvent_(b.onKeyPressWrapper_);a.workspace_.removeChangeListener(b.onWorkspaceChangeWrapper_);
                +Blockly.FieldTextInput.htmlInput_=null;Blockly.Events.setGroup(!1);b=Blockly.WidgetDiv.DIV.style;b.width="auto";b.height="auto";b.fontSize=""}};Blockly.FieldTextInput.numberValidator=function(a){console.warn("Blockly.FieldTextInput.numberValidator is deprecated. Use Blockly.FieldNumber instead.");if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=parseFloat(a||0);return isNaN(a)?null:String(a)};
                +Blockly.FieldTextInput.nonnegativeIntegerValidator=function(a){(a=Blockly.FieldTextInput.numberValidator(a))&&(a=String(Math.max(0,Math.floor(a))));return a};Blockly.FieldAngle=function(a,b){this.symbol_=Blockly.utils.createSvgElement("tspan",{},null);this.symbol_.appendChild(document.createTextNode("\u00b0"));a=a&&!isNaN(a)?String(a):"0";Blockly.FieldAngle.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldAngle,Blockly.FieldTextInput);Blockly.FieldAngle.ROUND=15;Blockly.FieldAngle.HALF=50;Blockly.FieldAngle.CLOCKWISE=!1;Blockly.FieldAngle.OFFSET=0;Blockly.FieldAngle.WRAP=360;Blockly.FieldAngle.RADIUS=Blockly.FieldAngle.HALF-1;
                +Blockly.FieldAngle.prototype.render_=function(){this.visible_?(this.textElement_.textContent=this.getDisplayText_(),this.sourceBlock_.RTL?this.textElement_.insertBefore(this.symbol_,this.textElement_.firstChild):this.textElement_.appendChild(this.symbol_),this.updateWidth()):this.size_.width=0};
                +Blockly.FieldAngle.prototype.dispose_=function(){var a=this;return function(){Blockly.FieldAngle.superClass_.dispose_.call(a)();a.gauge_=null;a.clickWrapper_&&Blockly.unbindEvent_(a.clickWrapper_);a.moveWrapper1_&&Blockly.unbindEvent_(a.moveWrapper1_);a.moveWrapper2_&&Blockly.unbindEvent_(a.moveWrapper2_)}};
                +Blockly.FieldAngle.prototype.showEditor_=function(){Blockly.FieldAngle.superClass_.showEditor_.call(this,goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD);var a=Blockly.WidgetDiv.DIV;if(a.firstChild){var a=Blockly.utils.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1",height:2*Blockly.FieldAngle.HALF+"px",width:2*Blockly.FieldAngle.HALF+"px"},a),b=Blockly.utils.createSvgElement("circle",
                +{cx:Blockly.FieldAngle.HALF,cy:Blockly.FieldAngle.HALF,r:Blockly.FieldAngle.RADIUS,"class":"blocklyAngleCircle"},a);this.gauge_=Blockly.utils.createSvgElement("path",{"class":"blocklyAngleGauge"},a);this.line_=Blockly.utils.createSvgElement("line",{x1:Blockly.FieldAngle.HALF,y1:Blockly.FieldAngle.HALF,"class":"blocklyAngleLine"},a);for(var c=0;360>c;c+=15)Blockly.utils.createSvgElement("line",{x1:Blockly.FieldAngle.HALF+Blockly.FieldAngle.RADIUS,y1:Blockly.FieldAngle.HALF,x2:Blockly.FieldAngle.HALF+
                +Blockly.FieldAngle.RADIUS-(0==c%45?10:5),y2:Blockly.FieldAngle.HALF,"class":"blocklyAngleMarks",transform:"rotate("+c+","+Blockly.FieldAngle.HALF+","+Blockly.FieldAngle.HALF+")"},a);a.style.marginLeft=15-Blockly.FieldAngle.RADIUS+"px";this.clickWrapper_=Blockly.bindEvent_(a,"click",this,Blockly.WidgetDiv.hide);this.moveWrapper1_=Blockly.bindEvent_(b,"mousemove",this,this.onMouseMove);this.moveWrapper2_=Blockly.bindEvent_(this.gauge_,"mousemove",this,this.onMouseMove);this.updateGraph_()}};
                +Blockly.FieldAngle.prototype.onMouseMove=function(a){var b=this.gauge_.ownerSVGElement.getBoundingClientRect(),c=a.clientX-b.left-Blockly.FieldAngle.HALF;a=a.clientY-b.top-Blockly.FieldAngle.HALF;b=Math.atan(-a/c);isNaN(b)||(b=goog.math.toDegrees(b),0>c?b+=180:0<a&&(b+=360),b=Blockly.FieldAngle.CLOCKWISE?Blockly.FieldAngle.OFFSET+360-b:b-Blockly.FieldAngle.OFFSET,Blockly.FieldAngle.ROUND&&(b=Math.round(b/Blockly.FieldAngle.ROUND)*Blockly.FieldAngle.ROUND),b=this.callValidator(b),Blockly.FieldTextInput.htmlInput_.value=
                +b,this.setValue(b),this.validate_(),this.resizeEditor_())};Blockly.FieldAngle.prototype.setText=function(a){Blockly.FieldAngle.superClass_.setText.call(this,a);this.textElement_&&(this.updateGraph_(),this.size_.width=0)};
                +Blockly.FieldAngle.prototype.updateGraph_=function(){if(this.gauge_){var a=Number(this.getText())+Blockly.FieldAngle.OFFSET,b=goog.math.toRadians(a),a=["M ",Blockly.FieldAngle.HALF,",",Blockly.FieldAngle.HALF],c=Blockly.FieldAngle.HALF,d=Blockly.FieldAngle.HALF;if(!isNaN(b)){var e=goog.math.toRadians(Blockly.FieldAngle.OFFSET),f=Math.cos(e)*Blockly.FieldAngle.RADIUS,g=Math.sin(e)*-Blockly.FieldAngle.RADIUS;Blockly.FieldAngle.CLOCKWISE&&(b=2*e-b);c+=Math.cos(b)*Blockly.FieldAngle.RADIUS;d-=Math.sin(b)*
                +Blockly.FieldAngle.RADIUS;b=Math.abs(Math.floor((b-e)/Math.PI)%2);Blockly.FieldAngle.CLOCKWISE&&(b=1-b);a.push(" l ",f,",",g," A ",Blockly.FieldAngle.RADIUS,",",Blockly.FieldAngle.RADIUS," 0 ",b," ",Number(Blockly.FieldAngle.CLOCKWISE)," ",c,",",d," z")}this.gauge_.setAttribute("d",a.join(""));this.line_.setAttribute("x2",c);this.line_.setAttribute("y2",d)}};
                +Blockly.FieldAngle.prototype.classValidator=function(a){if(null===a)return null;a=parseFloat(a||0);if(isNaN(a))return null;a%=360;0>a&&(a+=360);a>Blockly.FieldAngle.WRAP&&(a-=360);return String(a)};Blockly.FieldCheckbox=function(a,b){Blockly.FieldCheckbox.superClass_.constructor.call(this,"",b);this.setValue(a)};goog.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.CHECK_CHAR="\u2713";Blockly.FieldCheckbox.prototype.CURSOR="default";
                +Blockly.FieldCheckbox.prototype.init=function(){if(!this.fieldGroup_){Blockly.FieldCheckbox.superClass_.init.call(this);this.checkElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText blocklyCheckbox",x:-3,y:14},this.fieldGroup_);var a=document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR);this.checkElement_.appendChild(a);this.checkElement_.style.display=this.state_?"block":"none"}};Blockly.FieldCheckbox.prototype.getValue=function(){return String(this.state_).toUpperCase()};
                +Blockly.FieldCheckbox.prototype.setValue=function(a){a="string"==typeof a?"TRUE"==a.toUpperCase():!!a;this.state_!==a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.state_,a)),this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;this.sourceBlock_&&(a=this.callValidator(a));null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(){Blockly.FieldColour.superClass_.init.call(this);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())};Blockly.FieldColour.prototype.CURSOR="default";
                +Blockly.FieldColour.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldColour.superClass_.dispose.call(this)};Blockly.FieldColour.prototype.getValue=function(){return this.colour_};Blockly.FieldColour.prototype.setValue=function(a){this.sourceBlock_&&Blockly.Events.isEnabled()&&this.colour_!=a&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.colour_,a));this.colour_=a;this.borderRect_&&(this.borderRect_.style.fill=a)};
                +Blockly.FieldColour.prototype.getText=function(){var a=this.colour_,b=a.match(/^#(.)\1(.)\2(.)\3$/);b&&(a="#"+b[1]+b[2]+b[3]);return a};Blockly.FieldColour.COLOURS=goog.ui.ColorPicker.SIMPLE_GRID_COLORS;Blockly.FieldColour.COLUMNS=7;Blockly.FieldColour.prototype.setColours=function(a){this.colours_=a;return this};Blockly.FieldColour.prototype.setColumns=function(a){this.columns_=a;return this};
                +Blockly.FieldColour.prototype.showEditor_=function(){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,Blockly.FieldColour.widgetDispose_);var a=new goog.ui.ColorPicker;a.setSize(this.columns_||Blockly.FieldColour.COLUMNS);a.setColors(this.colours_||Blockly.FieldColour.COLOURS);var b=goog.dom.getViewportSize(),c=goog.style.getViewportPageOffset(document),d=this.getAbsoluteXY_(),e=this.getScaledBBox_();a.render(Blockly.WidgetDiv.DIV);a.setSelectedColor(this.getValue());var f=goog.style.getSize(a.getElement());
                +d.y=d.y+f.height+e.height>=b.height+c.y?d.y-(f.height-1):d.y+(e.height-1);this.sourceBlock_.RTL?(d.x+=e.width,d.x-=f.width,d.x<c.x&&(d.x=c.x)):d.x>b.width+c.x-f.width&&(d.x=b.width+c.x-f.width);Blockly.WidgetDiv.position(d.x,d.y,b,c,this.sourceBlock_.RTL);var g=this;Blockly.FieldColour.changeEventKey_=goog.events.listen(a,goog.ui.ColorPicker.EventType.CHANGE,function(a){a=a.target.getSelectedColor()||"#000000";Blockly.WidgetDiv.hide();g.sourceBlock_&&(a=g.callValidator(a));null!==a&&g.setValue(a)})};
                +Blockly.FieldColour.widgetDispose_=function(){Blockly.FieldColour.changeEventKey_&&goog.events.unlistenByKey(Blockly.FieldColour.changeEventKey_);Blockly.Events.setGroup(!1)};Blockly.FieldDropdown=function(a,b){this.menuGenerator_=a;this.trimOptions_();a=this.getOptions()[0];Blockly.FieldDropdown.superClass_.constructor.call(this,a[1],b)};goog.inherits(Blockly.FieldDropdown,Blockly.Field);Blockly.FieldDropdown.CHECKMARK_OVERHANG=25;Blockly.FieldDropdown.ARROW_CHAR=goog.userAgent.ANDROID?"\u25bc":"\u25be";Blockly.FieldDropdown.prototype.CURSOR="default";Blockly.FieldDropdown.prototype.value_="";Blockly.FieldDropdown.prototype.imageElement_=null;
                +Blockly.FieldDropdown.prototype.imageJson_=null;Blockly.FieldDropdown.prototype.init=function(){if(!this.fieldGroup_){this.arrow_=Blockly.utils.createSvgElement("tspan",{},null);this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL?Blockly.FieldDropdown.ARROW_CHAR+" ":" "+Blockly.FieldDropdown.ARROW_CHAR));Blockly.FieldDropdown.superClass_.init.call(this);var a=this.text_;this.text_=null;this.setText(a)}};
                +Blockly.FieldDropdown.prototype.showEditor_=function(){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,null);var a=this,b=new goog.ui.Menu;b.setRightToLeft(this.sourceBlock_.RTL);for(var c=this.getOptions(),d=0;d<c.length;d++){var e=c[d][0],f=c[d][1];if("object"==typeof e){var g=new Image(e.width,e.height);g.src=e.src;g.alt=e.alt||"";e=g}e=new goog.ui.MenuItem(e);e.setRightToLeft(this.sourceBlock_.RTL);e.setValue(f);e.setCheckable(!0);b.addChild(e,!0);e.setChecked(f==this.value_)}goog.events.listen(b,
                +goog.ui.Component.EventType.ACTION,function(b){if(b=b.target)a.onItemSelected(this,b);Blockly.WidgetDiv.hideIfOwner(a);Blockly.Events.setGroup(!1)});b.getHandler().listen(b.getElement(),goog.events.EventType.TOUCHSTART,function(a){this.getOwnerControl(a.target).handleMouseDown(a)});b.getHandler().listen(b.getElement(),goog.events.EventType.TOUCHEND,function(a){this.getOwnerControl(a.target).performActionInternal(a)});c=goog.dom.getViewportSize();d=goog.style.getViewportPageOffset(document);f=this.getAbsoluteXY_();
                +e=this.getScaledBBox_();b.render(Blockly.WidgetDiv.DIV);g=b.getElement();Blockly.utils.addClass(g,"blocklyDropdownMenu");var h=goog.style.getSize(g);h.height=g.scrollHeight;f.y=f.y+h.height+e.height>=c.height+d.y?f.y-(h.height+2):f.y+e.height;this.sourceBlock_.RTL?(f.x+=e.width,f.x+=Blockly.FieldDropdown.CHECKMARK_OVERHANG,f.x<d.x+h.width&&(f.x=d.x+h.width)):(f.x-=Blockly.FieldDropdown.CHECKMARK_OVERHANG,f.x>c.width+d.x-h.width&&(f.x=c.width+d.x-h.width));Blockly.WidgetDiv.position(f.x,f.y,c,d,this.sourceBlock_.RTL);
                +b.setAllowAutoFocus(!0);g.focus()};Blockly.FieldDropdown.prototype.onItemSelected=function(a,b){a=b.getValue();this.sourceBlock_&&(a=this.callValidator(a));null!==a&&this.setValue(a)};
                +Blockly.FieldDropdown.prototype.trimOptions_=function(){this.suffixField=this.prefixField=null;var a=this.menuGenerator_;if(goog.isArray(a)){for(var b=!1,c=0;c<a.length;c++){var d=a[c][0];"string"==typeof d?a[c][0]=Blockly.utils.replaceMessageReferences(d):(null!=d.alt&&(a[c][0].alt=Blockly.utils.replaceMessageReferences(d.alt)),b=!0)}if(!(b||2>a.length)){for(var e=[],c=0;c<a.length;c++)e.push(a[c][0]);c=Blockly.utils.shortestStringLength(e);b=Blockly.utils.commonWordPrefix(e,c);d=Blockly.utils.commonWordSuffix(e,
                +c);if((b||d)&&!(c<=b+d)){b&&(this.prefixField=e[0].substring(0,b-1));d&&(this.suffixField=e[0].substr(1-d));e=[];for(c=0;c<a.length;c++){var f=a[c][0],g=a[c][1],f=f.substring(b,f.length-d);e[c]=[f,g]}this.menuGenerator_=e}}}};Blockly.FieldDropdown.prototype.isOptionListDynamic=function(){return goog.isFunction(this.menuGenerator_)};Blockly.FieldDropdown.prototype.getOptions=function(){return goog.isFunction(this.menuGenerator_)?this.menuGenerator_.call(this):this.menuGenerator_};
                +Blockly.FieldDropdown.prototype.getValue=function(){return this.value_};Blockly.FieldDropdown.prototype.setValue=function(a){if(null!==a&&a!==this.value_){this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.value_,a));this.value_=a;for(var b=this.getOptions(),c=0;c<b.length;c++)if(b[c][1]==a){a=b[c][0];"object"==typeof a?(this.imageJson_=a,this.setText(a.alt)):(this.imageJson_=null,this.setText(a));return}this.setText(a)}};
                +Blockly.FieldDropdown.prototype.render_=function(){if(this.visible_){this.sourceBlock_&&this.arrow_&&(this.arrow_.style.fill=this.sourceBlock_.getColour());goog.dom.removeChildren(this.textElement_);goog.dom.removeNode(this.imageElement_);this.imageElement_=null;if(this.imageJson_){this.imageElement_=Blockly.utils.createSvgElement("image",{y:5,height:this.imageJson_.height+"px",width:this.imageJson_.width+"px"},this.fieldGroup_);this.imageElement_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",
                +this.imageJson_.src);this.textElement_.appendChild(this.arrow_);var a=Blockly.Field.getCachedWidth(this.arrow_);this.size_.height=Number(this.imageJson_.height)+19;this.size_.width=Number(this.imageJson_.width)+a;this.sourceBlock_.RTL?(this.imageElement_.setAttribute("x",a),this.textElement_.setAttribute("x",-1)):(this.textElement_.setAttribute("text-anchor","end"),this.textElement_.setAttribute("x",this.size_.width+1))}else a=document.createTextNode(this.getDisplayText_()),this.textElement_.appendChild(a),
                +this.sourceBlock_.RTL?this.textElement_.insertBefore(this.arrow_,this.textElement_.firstChild):this.textElement_.appendChild(this.arrow_),this.textElement_.setAttribute("text-anchor","start"),this.textElement_.setAttribute("x",0),this.size_.height=Blockly.BlockSvg.MIN_BLOCK_Y,this.size_.width=Blockly.Field.getCachedWidth(this.textElement_);this.borderRect_.setAttribute("height",this.size_.height-9);this.borderRect_.setAttribute("width",this.size_.width+Blockly.BlockSvg.SEP_SPACE_X)}else this.size_.width=
                +0};Blockly.FieldDropdown.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldDropdown.superClass_.dispose.call(this)};Blockly.FieldImage=function(a,b,c,d,e){this.sourceBlock_=null;this.height_=Number(c);this.width_=Number(b);this.size_=new goog.math.Size(this.width_,this.height_+2*Blockly.BlockSvg.INLINE_PADDING_Y);this.text_=d||"";this.setValue(a);"function"===typeof e&&(this.clickHandler_=e)};goog.inherits(Blockly.FieldImage,Blockly.Field);Blockly.FieldImage.prototype.EDITABLE=!1;
                +Blockly.FieldImage.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=Blockly.utils.createSvgElement("g",{},null),this.visible_||(this.fieldGroup_.style.display="none"),this.imageElement_=Blockly.utils.createSvgElement("image",{height:this.height_+"px",width:this.width_+"px"},this.fieldGroup_),this.setValue(this.src_),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),this.setTooltip(this.sourceBlock_),Blockly.Tooltip.bindMouseEvents(this.imageElement_))};
                +Blockly.FieldImage.prototype.dispose=function(){goog.dom.removeNode(this.fieldGroup_);this.imageElement_=this.fieldGroup_=null};Blockly.FieldImage.prototype.setTooltip=function(a){this.imageElement_.tooltip=a};Blockly.FieldImage.prototype.getValue=function(){return this.src_};Blockly.FieldImage.prototype.setValue=function(a){null!==a&&(this.src_=a,this.imageElement_&&this.imageElement_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a||""))};
                +Blockly.FieldImage.prototype.setText=function(a){null!==a&&(this.text_=a)};Blockly.FieldImage.prototype.render_=function(){};Blockly.FieldImage.prototype.updateWidth=function(){};Blockly.FieldImage.prototype.showEditor=function(){this.clickHandler_&&this.clickHandler_(this)};Blockly.FieldNumber=function(a,b,c,d,e){a=a&&!isNaN(a)?String(a):"0";Blockly.FieldNumber.superClass_.constructor.call(this,a,e);this.setConstraints(b,c,d)};goog.inherits(Blockly.FieldNumber,Blockly.FieldTextInput);Blockly.FieldNumber.prototype.setConstraints=function(a,b,c){c=parseFloat(c);this.precision_=isNaN(c)?0:c;a=parseFloat(a);this.min_=isNaN(a)?-Infinity:a;b=parseFloat(b);this.max_=isNaN(b)?Infinity:b;this.setValue(this.callValidator(this.getValue()))};
                +Blockly.FieldNumber.prototype.classValidator=function(a){if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=parseFloat(a||0);if(isNaN(a))return null;this.precision_&&isFinite(a)&&(a=Math.round(a/this.precision_)*this.precision_);a=goog.math.clamp(a,this.min_,this.max_);return String(a)};Blockly.VariableModel=function(a,b,c,d){this.workspace=a;this.name=b;this.type=c||"";this.id_=d||Blockly.utils.genUid();Blockly.Events.fire(new Blockly.Events.VarCreate(this))};Blockly.VariableModel.prototype.getId=function(){return this.id_};Blockly.VariableModel.compareByName=function(a,b){return goog.string.caseInsensitiveCompare(a.name,b.name)};Blockly.Variables={};Blockly.Variables.NAME_TYPE=Blockly.VARIABLE_CATEGORY_NAME;Blockly.Variables.allUsedVariables=function(a){if(a instanceof Blockly.Block)var b=a.getDescendants();else if(a.getAllBlocks)b=a.getAllBlocks();else throw"Not Block or Workspace: "+a;a=Object.create(null);for(var c=0;c<b.length;c++){var d=b[c].getVars();if(d)for(var e=0;e<d.length;e++){var f=d[e];f&&(a[f.toLowerCase()]=f)}}b=[];for(var g in a)b.push(a[g]);return b};
                +Blockly.Variables.allVariables=function(a){return a instanceof Blockly.Block?(console.warn("Deprecated call to Blockly.Variables.allVariables with a block instead of a workspace.  You may want Blockly.Variables.allUsedVariables"),{}):a.getAllVariables()};
                +Blockly.Variables.flyoutCategory=function(a){var b=[],c=goog.dom.createDom("button");c.setAttribute("text",Blockly.Msg.NEW_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE");a.registerButtonCallback("CREATE_VARIABLE",function(a){Blockly.Variables.createVariable(a.getTargetWorkspace())});b.push(c);a=Blockly.Variables.flyoutCategoryBlocks(a);return b=b.concat(a)};
                +Blockly.Variables.flyoutCategoryBlocks=function(a){a=a.getVariablesOfType("");a.sort(Blockly.VariableModel.compareByName);var b=[];if(0<a.length){var c=a[0];if(Blockly.Blocks.variables_set){var d=Blockly.Blocks.math_change?8:24;d='<xml><block type="variables_set" gap="'+d+'">'+Blockly.Variables.generateVariableFieldXml_(c)+"</block></xml>";d=Blockly.Xml.textToDom(d).firstChild;b.push(d)}Blockly.Blocks.math_change&&(d=Blockly.Blocks.variables_get?20:8,d='<xml><block type="math_change" gap="'+d+'">'+
                +Blockly.Variables.generateVariableFieldXml_(c)+'<value name="DELTA"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block></xml>',d=Blockly.Xml.textToDom(d).firstChild,b.push(d));for(c=0;d=a[c];c++)Blockly.Blocks.variables_get&&(d='<xml><block type="variables_get" gap="8">'+Blockly.Variables.generateVariableFieldXml_(d)+"</block></xml>",d=Blockly.Xml.textToDom(d).firstChild,b.push(d))}return b};
                +Blockly.Variables.generateUniqueName=function(a){a=a.getAllVariables();var b="";if(a.length)for(var c=1,d=0,e="ijkmnopqrstuvwxyzabcdefgh".charAt(d);!b;){for(var f=!1,g=0;g<a.length;g++)if(a[g].name.toLowerCase()==e){f=!0;break}f?(d++,25==d&&(d=0,c++),e="ijkmnopqrstuvwxyzabcdefgh".charAt(d),1<c&&(e+=c)):b=e}else b="i";return b};
                +Blockly.Variables.createVariable=function(a,b,c){var d=function(e){Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE,e,function(e){e?a.getVariable(e)?Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):Blockly.Procedures.isNameUsed(e,a)?Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):(a.createVariable(e,c),b&&b(e)):b&&b(null)})};d("")};
                +Blockly.Variables.renameVariable=function(a,b,c){var d=function(e){Blockly.Variables.promptName(Blockly.Msg.RENAME_VARIABLE_TITLE.replace("%1",b.name),e,function(e){if(e){var f=a.getVariable(e);f&&f.type!=b.type?Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE.replace("%1",e.toLowerCase()).replace("%2",f.type),function(){d(e)}):Blockly.Procedures.isNameUsed(e,a)?Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):(a.renameVariable(b.name,
                +e),c&&c(e))}else c&&c(null)})};d("")};Blockly.Variables.promptName=function(a,b,c){Blockly.prompt(a,b,function(a){a&&(a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,""),a==Blockly.Msg.RENAME_VARIABLE||a==Blockly.Msg.NEW_VARIABLE)&&(a=null);c(a)})};Blockly.Variables.generateVariableFieldXml_=function(a){return'<field name="VAR" variableType="'+a.type+'" id="'+a.getId()+'">'+a.name+"</field>"};Blockly.FieldVariable=function(a,b,c){Blockly.FieldVariable.superClass_.constructor.call(this,Blockly.FieldVariable.dropdownCreate,b);this.setValue(a||"");this.variableTypes=c};goog.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);Blockly.FieldVariable.prototype.init=function(){this.fieldGroup_||(Blockly.FieldVariable.superClass_.init.call(this),this.initModel())};
                +Blockly.FieldVariable.prototype.initModel=function(){this.getValue()||this.setValue(Blockly.Variables.generateUniqueName(this.sourceBlock_.isInFlyout?this.sourceBlock_.workspace.targetWorkspace:this.sourceBlock_.workspace));this.sourceBlock_.isInFlyout||this.sourceBlock_.workspace.createVariable(this.getValue())};
                +Blockly.FieldVariable.prototype.setSourceBlock=function(a){goog.asserts.assert(!a.isShadow(),"Variable fields are not allowed to exist on shadow blocks.");Blockly.FieldVariable.superClass_.setSourceBlock.call(this,a)};Blockly.FieldVariable.prototype.getValue=function(){return this.getText()};
                +Blockly.FieldVariable.prototype.setValue=function(a){var b=a,c=a;if(this.sourceBlock_){var d=this.sourceBlock_.workspace.getVariableById(a);if(d)c=d.name;else if(d=this.sourceBlock_.workspace.getVariable(a))b=d.getId();Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.value_,b))}this.value_=b;this.setText(c)};
                +Blockly.FieldVariable.prototype.getVariableTypes_=function(){var a=this.variableTypes;if(null===a&&this.sourceBlock_)return this.sourceBlock_.workspace.getVariableTypes();a=a||[""];if(0==a.length)throw a=this.getText(),Error("'variableTypes' of field variable "+a+" was an empty list");return a};
                +Blockly.FieldVariable.dropdownCreate=function(){var a=[];var b=this.getText(),c=b?!0:!1,d=null;this.sourceBlock_&&(d=this.sourceBlock_.workspace);if(d){var e=this.getVariableTypes_();a=[];for(var f=0;f<e.length;f++){var g=d.getVariablesOfType(e[f]);a=a.concat(g)}for(f=0;f<a.length;f++)if(c&&goog.string.caseInsensitiveEquals(a[f].name,b)){c=!1;break}}c&&d&&(f=d.createVariable(b),a.push(f));a.sort(Blockly.VariableModel.compareByName);c=[];for(f=0;f<a.length;f++)c[f]=[a[f].name,a[f].getId()];c.push([Blockly.Msg.RENAME_VARIABLE,
                +Blockly.RENAME_VARIABLE_ID]);Blockly.Msg.DELETE_VARIABLE&&c.push([Blockly.Msg.DELETE_VARIABLE.replace("%1",b),Blockly.DELETE_VARIABLE_ID]);return c};
                +Blockly.FieldVariable.prototype.onItemSelected=function(a,b){b=b.getValue();if(this.sourceBlock_&&this.sourceBlock_.workspace){a=this.sourceBlock_.workspace;var c=a.getVariableById(b);if(c)var d=c.name;else{if(b==Blockly.RENAME_VARIABLE_ID){d=this.getText();c=a.getVariable(d);Blockly.Variables.renameVariable(a,c);return}if(b==Blockly.DELETE_VARIABLE_ID){a.deleteVariable(this.getText());return}}d=this.callValidator(d)}null!==d&&this.setValue(d)};Blockly.Generator=function(a){this.name_=a;this.FUNCTION_NAME_PLACEHOLDER_REGEXP_=new RegExp(this.FUNCTION_NAME_PLACEHOLDER_,"g")};Blockly.Generator.NAME_TYPE="generated_function";Blockly.Generator.prototype.INFINITE_LOOP_TRAP=null;Blockly.Generator.prototype.STATEMENT_PREFIX=null;Blockly.Generator.prototype.INDENT="  ";Blockly.Generator.prototype.COMMENT_WRAP=60;Blockly.Generator.prototype.ORDER_OVERRIDES=[];
                +Blockly.Generator.prototype.workspaceToCode=function(a){a||(console.warn("No workspace specified in workspaceToCode call.  Guessing."),a=Blockly.getMainWorkspace());var b=[];this.init(a);a=a.getTopBlocks(!0);for(var c=0,d;d=a[c];c++){var e=this.blockToCode(d);goog.isArray(e)&&(e=e[0]);e&&(d.outputConnection&&this.scrubNakedValue&&(e=this.scrubNakedValue(e)),b.push(e))}b=b.join("\n");b=this.finish(b);b=b.replace(/^\s+\n/,"");b=b.replace(/\n\s+$/,"\n");return b=b.replace(/[ \t]+\n/g,"\n")};
                +Blockly.Generator.prototype.prefixLines=function(a,b){return b+a.replace(/(?!\n$)\n/g,"\n"+b)};Blockly.Generator.prototype.allNestedComments=function(a){var b=[];a=a.getDescendants();for(var c=0;c<a.length;c++){var d=a[c].getCommentText();d&&b.push(d)}b.length&&b.push("");return b.join("\n")};
                +Blockly.Generator.prototype.blockToCode=function(a){if(!a)return"";if(a.disabled)return this.blockToCode(a.getNextBlock());var b=this[a.type];goog.asserts.assertFunction(b,'Language "%s" does not know how to generate code for block type "%s".',this.name_,a.type);b=b.call(a,a);if(goog.isArray(b))return goog.asserts.assert(a.outputConnection,'Expecting string from statement block "%s".',a.type),[this.scrub_(a,b[0]),b[1]];if(goog.isString(b)){var c=a.id.replace(/\$/g,"$$$$");this.STATEMENT_PREFIX&&(b=
                +this.STATEMENT_PREFIX.replace(/%1/g,"'"+c+"'")+b);return this.scrub_(a,b)}if(null===b)return"";goog.asserts.fail("Invalid code generated: %s",b)};
                +Blockly.Generator.prototype.valueToCode=function(a,b,c){isNaN(c)&&goog.asserts.fail('Expecting valid order from block "%s".',a.type);var d=a.getInputTargetBlock(b);if(!d)return"";b=this.blockToCode(d);if(""===b)return"";goog.asserts.assertArray(b,'Expecting tuple from value block "%s".',d.type);a=b[0];b=b[1];isNaN(b)&&goog.asserts.fail('Expecting valid order from value block "%s".',d.type);if(!a)return"";var d=!1,e=Math.floor(c),f=Math.floor(b);if(e<=f&&(e!=f||0!=e&&99!=e))for(d=!0,e=0;e<this.ORDER_OVERRIDES.length;e++)if(this.ORDER_OVERRIDES[e][0]==
                +c&&this.ORDER_OVERRIDES[e][1]==b){d=!1;break}d&&(a="("+a+")");return a};Blockly.Generator.prototype.statementToCode=function(a,b){a=a.getInputTargetBlock(b);b=this.blockToCode(a);goog.asserts.assertString(b,'Expecting code from statement block "%s".',a&&a.type);b&&(b=this.prefixLines(b,this.INDENT));return b};
                +Blockly.Generator.prototype.addLoopTrap=function(a,b){b=b.replace(/\$/g,"$$$$");this.INFINITE_LOOP_TRAP&&(a=this.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+b+"'")+a);this.STATEMENT_PREFIX&&(a+=this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,"'"+b+"'"),this.INDENT));return a};Blockly.Generator.prototype.RESERVED_WORDS_="";Blockly.Generator.prototype.addReservedWords=function(a){this.RESERVED_WORDS_+=a+","};Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_="{leCUI8hutHZI4480Dc}";
                +Blockly.Generator.prototype.provideFunction_=function(a,b){if(!this.definitions_[a]){var c=this.variableDB_.getDistinctName(a,Blockly.Procedures.NAME_TYPE);this.functionNames_[a]=c;b=b.join("\n").replace(this.FUNCTION_NAME_PLACEHOLDER_REGEXP_,c);for(var d;d!=b;)d=b,b=b.replace(/^((  )*)  /gm,"$1\x00");b=b.replace(/\0/g,this.INDENT);this.definitions_[a]=b}return this.functionNames_[a]};Blockly.Generator.prototype.init=void 0;Blockly.Generator.prototype.scrub_=void 0;
                +Blockly.Generator.prototype.finish=void 0;Blockly.Generator.prototype.scrubNakedValue=void 0;Blockly.Names=function(a,b){this.variablePrefix_=b||"";this.reservedDict_=Object.create(null);if(a)for(a=a.split(","),b=0;b<a.length;b++)this.reservedDict_[a[b]]=!0;this.reset()};Blockly.Names.prototype.reset=function(){this.db_=Object.create(null);this.dbReverse_=Object.create(null)};
                +Blockly.Names.prototype.getName=function(a,b){var c=a.toLowerCase()+"_"+b,d=b==Blockly.Variables.NAME_TYPE?this.variablePrefix_:"";if(c in this.db_)return d+this.db_[c];a=this.getDistinctName(a,b);this.db_[c]=a.substr(d.length);return a};Blockly.Names.prototype.getDistinctName=function(a,b){a=this.safeName_(a);for(var c="";this.dbReverse_[a+c]||a+c in this.reservedDict_;)c=c?c+1:2;a+=c;this.dbReverse_[a]=!0;return(b==Blockly.Variables.NAME_TYPE?this.variablePrefix_:"")+a};
                +Blockly.Names.prototype.safeName_=function(a){a?(a=encodeURI(a.replace(/ /g,"_")).replace(/[^\w]/g,"_"),-1!="0123456789".indexOf(a[0])&&(a="my_"+a)):a="unnamed";return a};Blockly.Names.equals=function(a,b){return a.toLowerCase()==b.toLowerCase()};Blockly.Procedures={};Blockly.Procedures.NAME_TYPE=Blockly.PROCEDURE_CATEGORY_NAME;Blockly.Procedures.allProcedures=function(a){a=a.getAllBlocks();for(var b=[],c=[],d=0;d<a.length;d++)if(a[d].getProcedureDef){var e=a[d].getProcedureDef();e&&(e[2]?b.push(e):c.push(e))}c.sort(Blockly.Procedures.procTupleComparator_);b.sort(Blockly.Procedures.procTupleComparator_);return[c,b]};Blockly.Procedures.procTupleComparator_=function(a,b){return a[0].toLowerCase().localeCompare(b[0].toLowerCase())};
                +Blockly.Procedures.findLegalName=function(a,b){if(b.isInFlyout)return a;for(;!Blockly.Procedures.isLegalName_(a,b.workspace,b);){var c=a.match(/^(.*?)(\d+)$/);a=c?c[1]+(parseInt(c[2],10)+1):a+"2"}return a};Blockly.Procedures.isLegalName_=function(a,b,c){return!Blockly.Procedures.isNameUsed(a,b,c)};Blockly.Procedures.isNameUsed=function(a,b,c){b=b.getAllBlocks();for(var d=0;d<b.length;d++)if(b[d]!=c&&b[d].getProcedureDef){var e=b[d].getProcedureDef();if(Blockly.Names.equals(e[0],a))return!0}return!1};
                +Blockly.Procedures.rename=function(a){a=a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"");var b=Blockly.Procedures.findLegalName(a,this.sourceBlock_),c=this.text_;if(c!=a&&c!=b){a=this.sourceBlock_.workspace.getAllBlocks();for(var d=0;d<a.length;d++)a[d].renameProcedure&&a[d].renameProcedure(c,b)}return b};
                +Blockly.Procedures.flyoutCategory=function(a){function b(a,b){for(var d=0;d<a.length;d++){var e=a[d][0],f=a[d][1],g=goog.dom.createDom("block");g.setAttribute("type",b);g.setAttribute("gap",16);var n=goog.dom.createDom("mutation");n.setAttribute("name",e);g.appendChild(n);for(e=0;e<f.length;e++){var p=goog.dom.createDom("arg");p.setAttribute("name",f[e]);n.appendChild(p)}c.push(g)}}var c=[];if(Blockly.Blocks.procedures_defnoreturn){var d=goog.dom.createDom("block");d.setAttribute("type","procedures_defnoreturn");
                +d.setAttribute("gap",16);var e=goog.dom.createDom("field",null,Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE);e.setAttribute("name","NAME");d.appendChild(e);c.push(d)}Blockly.Blocks.procedures_defreturn&&(d=goog.dom.createDom("block"),d.setAttribute("type","procedures_defreturn"),d.setAttribute("gap",16),e=goog.dom.createDom("field",null,Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE),e.setAttribute("name","NAME"),d.appendChild(e),c.push(d));Blockly.Blocks.procedures_ifreturn&&(d=goog.dom.createDom("block"),
                +d.setAttribute("type","procedures_ifreturn"),d.setAttribute("gap",16),c.push(d));c.length&&c[c.length-1].setAttribute("gap",24);a=Blockly.Procedures.allProcedures(a);b(a[0],"procedures_callnoreturn");b(a[1],"procedures_callreturn");return c};Blockly.Procedures.getCallers=function(a,b){var c=[];b=b.getAllBlocks();for(var d=0;d<b.length;d++)if(b[d].getProcedureCall){var e=b[d].getProcedureCall();e&&Blockly.Names.equals(e,a)&&c.push(b[d])}return c};
                +Blockly.Procedures.mutateCallers=function(a){var b=Blockly.Events.recordUndo,c=a.getProcedureDef()[0],d=a.mutationToDom(!0);a=Blockly.Procedures.getCallers(c,a.workspace);for(var c=0,e;e=a[c];c++){var f=e.mutationToDom(),f=f&&Blockly.Xml.domToText(f);e.domToMutation(d);var g=e.mutationToDom(),g=g&&Blockly.Xml.domToText(g);f!=g&&(Blockly.Events.recordUndo=!1,Blockly.Events.fire(new Blockly.Events.BlockChange(e,"mutation",null,f,g)),Blockly.Events.recordUndo=b)}};
                +Blockly.Procedures.getDefinition=function(a,b){b=b.getTopBlocks(!1);for(var c=0;c<b.length;c++)if(b[c].getProcedureDef){var d=b[c].getProcedureDef();if(d&&Blockly.Names.equals(d[0],a))return b[c]}return null};Blockly.FlyoutButton=function(a,b,c,d){this.workspace_=a;this.targetWorkspace_=b;this.text_=c.getAttribute("text");this.position_=new goog.math.Coordinate(0,0);this.isLabel_=d;this.callback_=null;a=c.getAttribute("callbackKey");this.isLabel_&&a?console.warn("Labels should not have callbacks. Label text: "+this.text_):this.isLabel_||a&&b.getButtonCallback(a)?this.callback_=b.getButtonCallback(a):console.warn("Buttons should have callbacks. Button text: "+this.text_);this.cssClass_=c.getAttribute("web-class")||
                +null};Blockly.FlyoutButton.MARGIN=5;Blockly.FlyoutButton.prototype.width=0;Blockly.FlyoutButton.prototype.height=0;Blockly.FlyoutButton.prototype.onMouseUpWrapper_=null;
                +Blockly.FlyoutButton.prototype.createDom=function(){var a,b=this.isLabel_?"blocklyFlyoutLabel":"blocklyFlyoutButton";this.cssClass_&&(b+=" "+this.cssClass_);this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":b},this.workspace_.getCanvas());this.isLabel_||(a=Blockly.utils.createSvgElement("rect",{"class":"blocklyFlyoutButtonShadow",rx:4,ry:4,x:1,y:1},this.svgGroup_));var b=Blockly.utils.createSvgElement("rect",{"class":this.isLabel_?"blocklyFlyoutLabelBackground":"blocklyFlyoutButtonBackground",
                +rx:4,ry:4},this.svgGroup_),c=Blockly.utils.createSvgElement("text",{"class":this.isLabel_?"blocklyFlyoutLabelText":"blocklyText",x:0,y:0,"text-anchor":"middle"},this.svgGroup_);c.textContent=this.text_;this.width=c.getComputedTextLength()+2*Blockly.FlyoutButton.MARGIN;this.height=20;this.isLabel_||(a.setAttribute("width",this.width),a.setAttribute("height",this.height));b.setAttribute("width",this.width);b.setAttribute("height",this.height);c.setAttribute("x",this.width/2);c.setAttribute("y",this.height-
                +Blockly.FlyoutButton.MARGIN);this.updateTransform_();this.mouseUpWrapper_=Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.onMouseUp_);return this.svgGroup_};Blockly.FlyoutButton.prototype.show=function(){this.updateTransform_();this.svgGroup_.setAttribute("display","block")};Blockly.FlyoutButton.prototype.updateTransform_=function(){this.svgGroup_.setAttribute("transform","translate("+this.position_.x+","+this.position_.y+")")};
                +Blockly.FlyoutButton.prototype.moveTo=function(a,b){this.position_.x=a;this.position_.y=b;this.updateTransform_()};Blockly.FlyoutButton.prototype.getTargetWorkspace=function(){return this.targetWorkspace_};Blockly.FlyoutButton.prototype.dispose=function(){this.onMouseUpWrapper_&&Blockly.unbindEvent_(this.onMouseUpWrapper_);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.targetWorkspace_=this.workspace_=null};
                +Blockly.FlyoutButton.prototype.onMouseUp_=function(a){(a=this.targetWorkspace_.getGesture(a))&&a.cancel();this.callback_&&this.callback_(this)};Blockly.Flyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);this.workspace_=new Blockly.WorkspaceSvg(a);this.workspace_.isFlyout=!0;this.RTL=!!a.RTL;this.toolboxPosition_=a.toolboxPosition;this.eventWrappers_=[];this.backgroundButtons_=[];this.buttons_=[];this.listeners_=[];this.permanentlyDisabled_=[]};Blockly.Flyout.prototype.autoClose=!0;Blockly.Flyout.prototype.isVisible_=!1;Blockly.Flyout.prototype.containerVisible_=!0;
                +Blockly.Flyout.prototype.CORNER_RADIUS=8;Blockly.Flyout.prototype.MARGIN=Blockly.Flyout.prototype.CORNER_RADIUS;Blockly.Flyout.prototype.GAP_X=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.GAP_Y=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.SCROLLBAR_PADDING=2;Blockly.Flyout.prototype.width_=0;Blockly.Flyout.prototype.height_=0;Blockly.Flyout.prototype.dragAngleRange_=70;
                +Blockly.Flyout.prototype.createDom=function(a){this.svgGroup_=Blockly.utils.createSvgElement(a,{"class":"blocklyFlyout",style:"display: none"},null);this.svgBackground_=Blockly.utils.createSvgElement("path",{"class":"blocklyFlyoutBackground"},this.svgGroup_);this.svgGroup_.appendChild(this.workspace_.createDom());return this.svgGroup_};
                +Blockly.Flyout.prototype.init=function(a){this.targetWorkspace_=a;this.workspace_.targetWorkspace=a;this.scrollbar_=new Blockly.Scrollbar(this.workspace_,this.horizontalLayout_,!1,"blocklyFlyoutScrollbar");this.hide();Array.prototype.push.apply(this.eventWrappers_,Blockly.bindEventWithChecks_(this.svgGroup_,"wheel",this,this.wheel_));this.autoClose||(this.filterWrapper_=this.filterForCapacity_.bind(this),this.targetWorkspace_.addChangeListener(this.filterWrapper_));Array.prototype.push.apply(this.eventWrappers_,
                +Blockly.bindEventWithChecks_(this.svgBackground_,"mousedown",this,this.onMouseDown_));this.workspace_.getGesture=this.targetWorkspace_.getGesture.bind(this.targetWorkspace_);this.workspace_.getVariable=this.targetWorkspace_.getVariable.bind(this.targetWorkspace_);this.workspace_.getVariableById=this.targetWorkspace_.getVariableById.bind(this.targetWorkspace_);this.workspace_.getVariablesOfType=this.targetWorkspace_.getVariablesOfType.bind(this.targetWorkspace_);this.workspace_.deleteVariable=this.targetWorkspace_.deleteVariable.bind(this.targetWorkspace_);
                +this.workspace_.deleteVariableById=this.targetWorkspace_.deleteVariableById.bind(this.targetWorkspace_);this.workspace_.renameVariable=this.targetWorkspace_.renameVariable.bind(this.targetWorkspace_);this.workspace_.renameVariableById=this.targetWorkspace_.renameVariableById.bind(this.targetWorkspace_)};
                +Blockly.Flyout.prototype.dispose=function(){this.hide();Blockly.unbindEvent_(this.eventWrappers_);this.filterWrapper_&&(this.targetWorkspace_.removeChangeListener(this.filterWrapper_),this.filterWrapper_=null);this.scrollbar_&&(this.scrollbar_.dispose(),this.scrollbar_=null);this.workspace_&&(this.workspace_.targetWorkspace=null,this.workspace_.dispose(),this.workspace_=null);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.targetWorkspace_=this.svgBackground_=null};
                +Blockly.Flyout.prototype.getWidth=function(){return this.width_};Blockly.Flyout.prototype.getHeight=function(){return this.height_};Blockly.Flyout.prototype.getWorkspace=function(){return this.workspace_};Blockly.Flyout.prototype.isVisible=function(){return this.isVisible_};Blockly.Flyout.prototype.setVisible=function(a){var b=a!=this.isVisible();this.isVisible_=a;b&&this.updateDisplay_()};
                +Blockly.Flyout.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};Blockly.Flyout.prototype.updateDisplay_=function(){var a=this.containerVisible_?this.isVisible():!1;this.svgGroup_.style.display=a?"block":"none";this.scrollbar_.setContainerVisible(a)};
                +Blockly.Flyout.prototype.positionAt_=function(a,b,c,d){this.svgGroup_.setAttribute("width",a);this.svgGroup_.setAttribute("height",b);Blockly.utils.setCssTransform(this.svgGroup_,"translate("+c+"px,"+d+"px)");this.scrollbar_&&(this.scrollbar_.setOrigin(c,d),this.scrollbar_.resize())};
                +Blockly.Flyout.prototype.hide=function(){if(this.isVisible()){this.setVisible(!1);for(var a=0,b;b=this.listeners_[a];a++)Blockly.unbindEvent_(b);this.listeners_.length=0;this.reflowWrapper_&&(this.workspace_.removeChangeListener(this.reflowWrapper_),this.reflowWrapper_=null)}};
                +Blockly.Flyout.prototype.show=function(a){this.workspace_.setResizesEnabled(!1);this.hide();this.clearOldBlocks_();"string"==typeof a&&(a=this.workspace_.targetWorkspace.getToolboxCategoryCallback(a),goog.asserts.assert(goog.isFunction(a),"Couldn't find a callback function when opening a toolbox category."),a=a(this.workspace_.targetWorkspace),goog.asserts.assert(goog.isArray(a),"The result of a toolbox category callback must be an array."));this.setVisible(!0);for(var b=[],c=[],d=this.permanentlyDisabled_.length=
                +0,e;e=a[d];d++)if(e.tagName){var f=e.tagName.toUpperCase(),g=this.horizontalLayout_?this.GAP_X:this.GAP_Y;if("BLOCK"==f)f=Blockly.Xml.domToBlock(e,this.workspace_),f.disabled&&this.permanentlyDisabled_.push(f),b.push({type:"block",block:f}),e=parseInt(e.getAttribute("gap"),10),c.push(isNaN(e)?g:e);else if("SEP"==e.tagName.toUpperCase())e=parseInt(e.getAttribute("gap"),10),!isNaN(e)&&0<c.length?c[c.length-1]=e:c.push(g);else if("BUTTON"==f||"LABEL"==f)e=new Blockly.FlyoutButton(this.workspace_,this.targetWorkspace_,
                +e,"LABEL"==f),b.push({type:"button",button:e}),c.push(g)}this.layout_(b,c);this.listeners_.push(Blockly.bindEventWithChecks_(this.svgBackground_,"mouseover",this,function(){for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++)c.removeSelect()}));this.horizontalLayout_?this.height_=0:this.width_=0;this.workspace_.setResizesEnabled(!0);this.reflow();this.filterForCapacity_();this.position();this.reflowWrapper_=this.reflow.bind(this);this.workspace_.addChangeListener(this.reflowWrapper_)};
                +Blockly.Flyout.prototype.clearOldBlocks_=function(){for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++)c.workspace==this.workspace_&&c.dispose(!1,!1);for(b=0;a=this.backgroundButtons_[b];b++)goog.dom.removeNode(a);for(b=this.backgroundButtons_.length=0;a=this.buttons_[b];b++)a.dispose();this.buttons_.length=0};
                +Blockly.Flyout.prototype.addBlockListeners_=function(a,b,c){this.listeners_.push(Blockly.bindEventWithChecks_(a,"mousedown",null,this.blockMouseDown_(b)));this.listeners_.push(Blockly.bindEventWithChecks_(c,"mousedown",null,this.blockMouseDown_(b)));this.listeners_.push(Blockly.bindEvent_(a,"mouseover",b,b.addSelect));this.listeners_.push(Blockly.bindEvent_(a,"mouseout",b,b.removeSelect));this.listeners_.push(Blockly.bindEvent_(c,"mouseover",b,b.addSelect));this.listeners_.push(Blockly.bindEvent_(c,
                +"mouseout",b,b.removeSelect))};Blockly.Flyout.prototype.blockMouseDown_=function(a){var b=this;return function(c){var d=b.targetWorkspace_.getGesture(c);d&&(d.setStartBlock(a),d.handleFlyoutStart(c,b))}};Blockly.Flyout.prototype.onMouseDown_=function(a){var b=this.targetWorkspace_.getGesture(a);b&&b.handleFlyoutStart(a,this)};
                +Blockly.Flyout.prototype.createBlock=function(a){var b=null;Blockly.Events.disable();this.targetWorkspace_.setResizesEnabled(!1);try{b=this.placeNewBlock_(a);if(goog.userAgent.IE||goog.userAgent.EDGE)for(var c=b.getDescendants(),d=c.length-1;0<=d;d--)c[d].render(!1);Blockly.hideChaff()}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&(Blockly.Events.setGroup(!0),Blockly.Events.fire(new Blockly.Events.Create(b)));this.autoClose?this.hide():this.filterForCapacity_();return b};
                +Blockly.Flyout.prototype.initFlyoutButton_=function(a,b,c){var d=a.createDom();a.moveTo(b,c);a.show();this.listeners_.push(Blockly.bindEventWithChecks_(d,"mousedown",this,this.onMouseDown_));this.buttons_.push(a)};
                +Blockly.Flyout.prototype.createRect_=function(a,b,c,d,e){b=Blockly.utils.createSvgElement("rect",{"fill-opacity":0,x:b,y:c,height:d.height,width:d.width},null);b.tooltip=a;Blockly.Tooltip.bindMouseEvents(b);this.workspace_.getCanvas().insertBefore(b,a.getSvgRoot());a.flyoutRect_=b;return this.backgroundButtons_[e]=b};
                +Blockly.Flyout.prototype.moveRectToBlock_=function(a,b){var c=b.getHeightWidth();a.setAttribute("width",c.width);a.setAttribute("height",c.height);var d=b.startHat_?Blockly.BlockSvg.START_HAT_HEIGHT:0;d&&b.moveBy(0,d);d=b.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0;b=b.getRelativeToSurfaceXY();a.setAttribute("y",b.y);a.setAttribute("x",this.RTL?b.x-c.width+d:b.x-d)};
                +Blockly.Flyout.prototype.filterForCapacity_=function(){for(var a=this.targetWorkspace_.remainingCapacity(),b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++)if(-1==this.permanentlyDisabled_.indexOf(d)){var e=d.getDescendants();d.setDisabled(e.length>a)}};Blockly.Flyout.prototype.reflow=function(){this.reflowWrapper_&&this.workspace_.removeChangeListener(this.reflowWrapper_);var a=this.workspace_.getTopBlocks(!1);this.reflowInternal_(a);this.reflowWrapper_&&this.workspace_.addChangeListener(this.reflowWrapper_)};
                +Blockly.Flyout.prototype.isScrollable=function(){return this.scrollbar_?this.scrollbar_.isVisible():!1};
                +Blockly.Flyout.prototype.placeNewBlock_=function(a){var b=this.targetWorkspace_;if(!a.getSvgRoot())throw"oldBlock is not rendered.";var c=Blockly.Xml.blockToDom(a);b.setResizesEnabled(!1);c=Blockly.Xml.domToBlock(c,b);if(!c.getSvgRoot())throw"block is not rendered.";var d=b.getOriginOffsetInPixels(),e=this.workspace_.getOriginOffsetInPixels();a=a.getRelativeToSurfaceXY().scale(this.workspace_.scale);a=goog.math.Coordinate.sum(e,a);b=goog.math.Coordinate.difference(a,d).scale(1/b.scale);c.moveBy(b.x,
                +b.y);return c};Blockly.HorizontalFlyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);Blockly.HorizontalFlyout.superClass_.constructor.call(this,a);this.horizontalLayout_=!0};goog.inherits(Blockly.HorizontalFlyout,Blockly.Flyout);
                +Blockly.HorizontalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.SCROLLBAR_PADDING;this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM&&(b=0);var d=this.height_;this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP&&(d-=this.SCROLLBAR_PADDING);return{viewHeight:d,viewWidth:this.width_-2*this.SCROLLBAR_PADDING,contentHeight:(a.height+2*this.MARGIN)*this.workspace_.scale,
                +contentWidth:(a.width+2*this.MARGIN)*this.workspace_.scale,viewTop:-this.workspace_.scrollY,viewLeft:-this.workspace_.scrollX,contentTop:a.y,contentLeft:a.x,absoluteTop:b,absoluteLeft:c}};Blockly.HorizontalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&(goog.isNumber(a.x)&&(this.workspace_.scrollX=-b.contentWidth*a.x),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
                +Blockly.HorizontalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace_.getMetrics();if(a){this.width_=a.viewWidth;this.setBackgroundPath_(a.viewWidth-2*this.CORNER_RADIUS,this.height_-this.CORNER_RADIUS);var b=a.absoluteLeft,c=a.absoluteTop;this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM&&(c+=a.viewHeight-this.height_);this.positionAt_(this.width_,this.height_,b,c)}}};
                +Blockly.HorizontalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP,d=["M 0,"+(c?0:this.CORNER_RADIUS)];c?(d.push("h",a+2*this.CORNER_RADIUS),d.push("v",b),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("h",-1*a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,-this.CORNER_RADIUS)):(d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,-this.CORNER_RADIUS),
                +d.push("h",a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("v",b),d.push("h",-a-2*this.CORNER_RADIUS));d.push("z");this.svgBackground_.setAttribute("d",d.join(" "))};Blockly.HorizontalFlyout.prototype.scrollToStart=function(){this.scrollbar_.set(this.RTL?Infinity:0)};
                +Blockly.HorizontalFlyout.prototype.wheel_=function(a){var b=a.deltaX;if(b){goog.userAgent.GECKO&&(b*=10);var c=this.getMetrics_(),b=c.viewLeft+b,b=Math.min(b,c.contentWidth-c.viewWidth),b=Math.max(b,0);this.scrollbar_.set(b);Blockly.WidgetDiv.hide()}a.preventDefault();a.stopPropagation()};
                +Blockly.HorizontalFlyout.prototype.layout_=function(a,b){var c;this.workspace_.scale=this.targetWorkspace_.scale;var d=this.MARGIN,e=this.RTL?d:d+Blockly.BlockSvg.TAB_WIDTH;this.RTL&&(a=a.reverse());for(var f=0,g;g=a[f];f++)if("block"==g.type){g=g.block;for(var h=g.getDescendants(),k=0;c=h[k];k++)c.isInFlyout=!0;g.render();h=g.getSvgRoot();k=g.getHeightWidth();c=g.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0;c=this.RTL?e+k.width:e+c;g.moveBy(c,d);c=this.createRect_(g,c,d,k,f);e+=k.width+b[f];this.addBlockListeners_(h,
                +g,c)}else"button"==g.type&&(this.initFlyoutButton_(g.button,e,d),e+=g.button.width+b[f])};Blockly.HorizontalFlyout.prototype.isDragTowardWorkspace=function(a){a=Math.atan2(a.y,a.x)/Math.PI*180;var b=this.dragAngleRange_;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP){if(a<90+b&&a>90-b)return!0}else if(a>-90-b&&a<-90+b)return!0;return!1};
                +Blockly.HorizontalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.top,a=a.height;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP)return new goog.math.Rect(-1E9,b-1E9,2E9,1E9+a);if(this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM)return new goog.math.Rect(-1E9,b,2E9,1E9+a)};
                +Blockly.HorizontalFlyout.prototype.reflowInternal_=function(a){this.workspace_.scale=this.targetWorkspace_.scale;for(var b=0,c=0,d;d=a[c];c++)b=Math.max(b,d.getHeightWidth().height);b+=1.5*this.MARGIN;b*=this.workspace_.scale;b+=Blockly.Scrollbar.scrollbarThickness;if(this.height_!=b){for(c=0;d=a[c];c++)d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d);this.height_=b;this.targetWorkspace_.resize()}};Blockly.VerticalFlyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);Blockly.VerticalFlyout.superClass_.constructor.call(this,a);this.horizontalLayout_=!1};goog.inherits(Blockly.VerticalFlyout,Blockly.Flyout);
                +Blockly.VerticalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.height_-2*this.SCROLLBAR_PADDING,d=this.width_;this.RTL||(d-=this.SCROLLBAR_PADDING);return{viewHeight:c,viewWidth:d,contentHeight:a.height*this.workspace_.scale+2*this.MARGIN,contentWidth:a.width*this.workspace_.scale+2*this.MARGIN,viewTop:-this.workspace_.scrollY+a.y,viewLeft:-this.workspace_.scrollX,
                +contentTop:a.y,contentLeft:a.x,absoluteTop:b,absoluteLeft:0}};Blockly.VerticalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&(goog.isNumber(a.y)&&(this.workspace_.scrollY=-b.contentHeight*a.y),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
                +Blockly.VerticalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace_.getMetrics();if(a){this.height_=a.viewHeight;this.setBackgroundPath_(this.width_-this.CORNER_RADIUS,a.viewHeight-2*this.CORNER_RADIUS);var b=a.absoluteTop,c=a.absoluteLeft;this.toolboxPosition_==Blockly.TOOLBOX_AT_RIGHT&&(c+=a.viewWidth-this.width_);this.positionAt_(this.width_,this.height_,c,b)}}};
                +Blockly.VerticalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_RIGHT,d=a+this.CORNER_RADIUS,d=["M "+(c?d:0)+",0"];d.push("h",c?-a:a);d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?-this.CORNER_RADIUS:this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("v",Math.max(0,b));d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?this.CORNER_RADIUS:-this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("h",c?a:-a);d.push("z");this.svgBackground_.setAttribute("d",
                +d.join(" "))};Blockly.VerticalFlyout.prototype.scrollToStart=function(){this.scrollbar_.set(0)};Blockly.VerticalFlyout.prototype.wheel_=function(a){var b=a.deltaY;if(b){goog.userAgent.GECKO&&(b*=10);var c=this.getMetrics_(),b=c.viewTop+b,b=Math.min(b,c.contentHeight-c.viewHeight),b=Math.max(b,0);this.scrollbar_.set(b);Blockly.WidgetDiv.hide()}a.preventDefault();a.stopPropagation()};
                +Blockly.VerticalFlyout.prototype.layout_=function(a,b){this.workspace_.scale=this.targetWorkspace_.scale;for(var c=this.MARGIN,d=this.RTL?c:c+Blockly.BlockSvg.TAB_WIDTH,e=0,f;f=a[e];e++)if("block"==f.type){f=f.block;for(var g=f.getDescendants(),h=0,k;k=g[h];h++)k.isInFlyout=!0;f.render();g=f.getSvgRoot();h=f.getHeightWidth();f.moveBy(d,c);k=this.createRect_(f,this.RTL?d-h.width:d,c,h,e);this.addBlockListeners_(g,f,k);c+=h.height+b[e]}else"button"==f.type&&(this.initFlyoutButton_(f.button,d,c),c+=
                +f.button.height+b[e])};Blockly.VerticalFlyout.prototype.isDragTowardWorkspace=function(a){a=Math.atan2(a.y,a.x)/Math.PI*180;var b=this.dragAngleRange_;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT){if(a<b&&a>-b)return!0}else if(a<-180+b||a>180-b)return!0;return!1};
                +Blockly.VerticalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.left,a=a.width;return this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?new goog.math.Rect(b-1E9,-1E9,1E9+a,2E9):new goog.math.Rect(b,-1E9,1E9+a,2E9)};
                +Blockly.VerticalFlyout.prototype.reflowInternal_=function(a){this.workspace_.scale=this.targetWorkspace_.scale;for(var b=0,c=0,d;d=a[c];c++){var e=d.getHeightWidth().width;d.outputConnection&&(e-=Blockly.BlockSvg.TAB_WIDTH);b=Math.max(b,e)}for(c=0;d=this.buttons_[c];c++)b=Math.max(b,d.width);b+=1.5*this.MARGIN+Blockly.BlockSvg.TAB_WIDTH;b*=this.workspace_.scale;b+=Blockly.Scrollbar.scrollbarThickness;if(this.width_!=b){for(c=0;d=a[c];c++){if(this.RTL){var e=d.getRelativeToSurfaceXY().x,f=b/this.workspace_.scale-
                +this.MARGIN,f=f-Blockly.BlockSvg.TAB_WIDTH;d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}this.width_=b;this.targetWorkspace_.resize()}};Blockly.Toolbox=function(a){this.workspace_=a;this.RTL=a.options.RTL;this.horizontalLayout_=a.options.horizontalLayout;this.toolboxPosition=a.options.toolboxPosition;this.config_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssItem:"",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"};this.treeSeparatorConfig_={cssTreeRow:"blocklyTreeSeparator"};
                +this.horizontalLayout_&&(this.config_.cssTreeRow+=a.RTL?" blocklyHorizontalTreeRtl":" blocklyHorizontalTree",this.treeSeparatorConfig_.cssTreeRow="blocklyTreeSeparatorHorizontal "+(a.RTL?"blocklyHorizontalTreeRtl":"blocklyHorizontalTree"),this.config_.cssTreeIcon="")};Blockly.Toolbox.prototype.width=0;Blockly.Toolbox.prototype.height=0;Blockly.Toolbox.prototype.selectedOption_=null;Blockly.Toolbox.prototype.lastCategory_=null;
                +Blockly.Toolbox.prototype.init=function(){var a=this.workspace_,b=this.workspace_.getParentSvg();this.HtmlDiv=goog.dom.createDom("DIV","blocklyToolboxDiv");this.HtmlDiv.setAttribute("dir",a.RTL?"RTL":"LTR");b.parentNode.insertBefore(this.HtmlDiv,b);Blockly.bindEventWithChecks_(this.HtmlDiv,"mousedown",this,function(a){Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0);Blockly.Touch.clearTouchIdentifier()});b={disabledPatternId:a.options.disabledPatternId,
                +parentWorkspace:a,RTL:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,toolboxPosition:a.options.toolboxPosition};this.flyout_=null;this.flyout_=a.horizontalLayout?new Blockly.HorizontalFlyout(b):new Blockly.VerticalFlyout(b);goog.dom.insertSiblingAfter(this.flyout_.createDom("svg"),this.workspace_.getParentSvg());this.flyout_.init(a);this.config_.cleardotPath=a.options.pathToMedia+"1x1.gif";this.config_.cssCollapsedFolderIcon="blocklyTreeIconClosed"+(a.RTL?"Rtl":"Ltr");
                +this.tree_=b=new Blockly.Toolbox.TreeControl(this,this.config_);b.setShowRootNode(!1);b.setShowLines(!1);b.setShowExpandIcons(!1);b.setSelectedItem(null);a=this.populate_(a.options.languageTree);b.render(this.HtmlDiv);a&&b.setSelectedItem(a);this.addColour_();this.position()};Blockly.Toolbox.prototype.dispose=function(){this.flyout_.dispose();this.tree_.dispose();goog.dom.removeNode(this.HtmlDiv);this.lastCategory_=this.workspace_=null};Blockly.Toolbox.prototype.getWidth=function(){return this.width};
                +Blockly.Toolbox.prototype.getHeight=function(){return this.height};
                +Blockly.Toolbox.prototype.position=function(){var a=this.HtmlDiv;if(a){var b=this.workspace_.getParentSvg(),b=Blockly.svgSize(b);this.horizontalLayout_?(a.style.left="0",a.style.height="auto",a.style.width=b.width+"px",this.height=a.offsetHeight,this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?a.style.top="0":a.style.bottom="0"):(this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?a.style.right="0":a.style.left="0",a.style.height=b.height+"px",this.width=a.offsetWidth);this.flyout_.position()}};
                +Blockly.Toolbox.prototype.populate_=function(a){this.tree_.removeChildren();this.tree_.blocks=[];this.hasColours_=!1;a=this.syncTrees_(a,this.tree_,this.workspace_.options.pathToMedia);if(this.tree_.blocks.length)throw"Toolbox cannot have both blocks and categories in the root level.";this.workspace_.resizeContents();return a};
                +Blockly.Toolbox.prototype.syncTrees_=function(a,b,c){for(var d=null,e=null,f=0,g;g=a.childNodes[f];f++)if(g.tagName)switch(g.tagName.toUpperCase()){case "CATEGORY":e=Blockly.utils.replaceMessageReferences(g.getAttribute("name"));e=this.tree_.createNode(e);e.blocks=[];b.add(e);var h=g.getAttribute("custom");h?e.blocks=h:(h=this.syncTrees_(g,e,c))&&(d=h);h=Blockly.utils.replaceMessageReferences(g.getAttribute("colour"));goog.isString(h)?(h.match(/^#[0-9a-fA-F]{6}$/)?e.hexColour=h:e.hexColour=Blockly.hueToRgb(h),
                +this.hasColours_=!0):e.hexColour="";"true"==g.getAttribute("expanded")?(e.blocks.length&&(d=e),e.setExpanded(!0)):e.setExpanded(!1);e=g;break;case "SEP":e&&("CATEGORY"==e.tagName.toUpperCase()?b.add(new Blockly.Toolbox.TreeSeparator(this.treeSeparatorConfig_)):(g=parseFloat(g.getAttribute("gap")),!isNaN(g)&&e&&e.setAttribute("gap",g)));break;case "BLOCK":case "SHADOW":case "LABEL":case "BUTTON":b.blocks.push(g),e=g}return d};
                +Blockly.Toolbox.prototype.addColour_=function(a){for(var b=(a||this.tree_).getChildren(),c=0,d;d=b[c];c++){var e=d.getRowElement();e&&(a=this.hasColours_?"8px solid "+(d.hexColour||"#ddd"):"none",this.workspace_.RTL?e.style.borderRight=a:e.style.borderLeft=a);this.addColour_(d)}};Blockly.Toolbox.prototype.clearSelection=function(){this.tree_.setSelectedItem(null)};Blockly.Toolbox.prototype.addDeleteStyle=function(){Blockly.utils.addClass(this.HtmlDiv,"blocklyToolboxDelete")};
                +Blockly.Toolbox.prototype.removeDeleteStyle=function(){Blockly.utils.removeClass(this.HtmlDiv,"blocklyToolboxDelete")};
                +Blockly.Toolbox.prototype.getClientRect=function(){if(!this.HtmlDiv)return null;var a=this.HtmlDiv.getBoundingClientRect(),b=a.left,c=a.top,d=a.width,a=a.height;return this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT?new goog.math.Rect(-1E7,-1E7,1E7+b+d,2E7):this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?new goog.math.Rect(b,-1E7,1E7+d,2E7):this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?new goog.math.Rect(-1E7,-1E7,2E7,1E7+c+a):new goog.math.Rect(0,c,2E7,1E7+d)};
                +Blockly.Toolbox.prototype.refreshSelection=function(){var a=this.tree_.getSelectedItem();a&&a.blocks&&this.flyout_.show(a.blocks)};Blockly.Toolbox.TreeControl=function(a,b){this.toolbox_=a;goog.ui.tree.TreeControl.call(this,goog.html.SafeHtml.EMPTY,b)};goog.inherits(Blockly.Toolbox.TreeControl,goog.ui.tree.TreeControl);
                +Blockly.Toolbox.TreeControl.prototype.enterDocument=function(){Blockly.Toolbox.TreeControl.superClass_.enterDocument.call(this);if(goog.events.BrowserFeature.TOUCH_ENABLED){var a=this.getElement();Blockly.bindEventWithChecks_(a,goog.events.EventType.TOUCHSTART,this,this.handleTouchEvent_)}};Blockly.Toolbox.TreeControl.prototype.handleTouchEvent_=function(a){a.preventDefault();var b=this.getNodeFromEvent_(a);b&&a.type===goog.events.EventType.TOUCHSTART&&setTimeout(function(){b.onMouseDown(a)},1)};
                +Blockly.Toolbox.TreeControl.prototype.createNode=function(a){return new Blockly.Toolbox.TreeNode(this.toolbox_,a?goog.html.SafeHtml.htmlEscape(a):goog.html.SafeHtml.EMPTY,this.getConfig(),this.getDomHelper())};
                +Blockly.Toolbox.TreeControl.prototype.setSelectedItem=function(a){var b=this.toolbox_;if(a!=this.selectedItem_&&a!=b.tree_){b.lastCategory_&&(b.lastCategory_.getRowElement().style.backgroundColor="");if(a){var c=a.hexColour||"#57e";a.getRowElement().style.backgroundColor=c;b.addColour_(a)}c=this.getSelectedItem();goog.ui.tree.TreeControl.prototype.setSelectedItem.call(this,a);a&&a.blocks&&a.blocks.length?(b.flyout_.show(a.blocks),b.lastCategory_!=a&&b.flyout_.scrollToStart()):b.flyout_.hide();c!=
                +a&&c!=this&&(c=new Blockly.Events.Ui(null,"category",c&&c.getHtml(),a&&a.getHtml()),c.workspaceId=b.workspace_.id,Blockly.Events.fire(c));a&&(b.lastCategory_=a)}};Blockly.Toolbox.TreeNode=function(a,b,c,d){goog.ui.tree.TreeNode.call(this,b,c,d);a&&(b=function(){Blockly.svgResize(a.workspace_)},goog.events.listen(a.tree_,goog.ui.tree.BaseNode.EventType.EXPAND,b),goog.events.listen(a.tree_,goog.ui.tree.BaseNode.EventType.COLLAPSE,b))};goog.inherits(Blockly.Toolbox.TreeNode,goog.ui.tree.TreeNode);
                +Blockly.Toolbox.TreeNode.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.create("span")};Blockly.Toolbox.TreeNode.prototype.onMouseDown=function(a){this.hasChildren()&&this.isUserCollapsible_?(this.toggle(),this.select()):this.isSelected()?this.getTree().setSelectedItem(null):this.select();this.updateRow()};Blockly.Toolbox.TreeNode.prototype.onDoubleClick_=function(a){};
                +Blockly.Toolbox.TreeNode.prototype.onKeyDown=function(a){if(this.tree.toolbox_.horizontalLayout_){var b={},c=goog.events.KeyCodes.DOWN,d=goog.events.KeyCodes.UP;b[goog.events.KeyCodes.RIGHT]=this.rightToLeft_?d:c;b[goog.events.KeyCodes.LEFT]=this.rightToLeft_?c:d;b[goog.events.KeyCodes.UP]=goog.events.KeyCodes.LEFT;b[goog.events.KeyCodes.DOWN]=goog.events.KeyCodes.RIGHT;a.keyCode=b[a.keyCode]||a.keyCode}return Blockly.Toolbox.TreeNode.superClass_.onKeyDown.call(this,a)};
                +Blockly.Toolbox.TreeSeparator=function(a){Blockly.Toolbox.TreeNode.call(this,null,"",a)};goog.inherits(Blockly.Toolbox.TreeSeparator,Blockly.Toolbox.TreeNode);Blockly.Css={};Blockly.Css.Cursor={OPEN:"handopen",CLOSED:"handclosed",DELETE:"handdelete"};Blockly.Css.currentCursor_="";Blockly.Css.styleSheet_=null;Blockly.Css.mediaPath_="";
                +Blockly.Css.inject=function(a,b){if(!Blockly.Css.styleSheet_){var c=".blocklyDraggable {}\n";a&&(c+=Blockly.Css.CONTENT.join("\n"),Blockly.FieldDate&&(c+=Blockly.FieldDate.CSS.join("\n")));Blockly.Css.mediaPath_=b.replace(/[\\\/]$/,"");c=c.replace(/<<<PATH>>>/g,Blockly.Css.mediaPath_);a=document.createElement("style");document.head.insertBefore(a,document.head.firstChild);c=document.createTextNode(c);a.appendChild(c);Blockly.Css.styleSheet_=a.sheet}};Blockly.Css.setCursor=function(a){console.warn("Deprecated call to Blockly.Css.setCursor.See https://github.com/google/blockly/issues/981 for context")};
                +Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;","overflow: hidden;","position: absolute;","display: block;","}",".blocklyWidgetDiv {","display: none;","position: absolute;","z-index: 99999;","}",".injectionDiv {","height: 100%;","position: relative;","overflow: hidden;","touch-action: none","}",".blocklyNonSelectable {","user-select: none;","-moz-user-select: none;","-webkit-user-select: none;","-ms-user-select: none;","}",".blocklyWsDragSurface {","display: none;",
                +"position: absolute;","overflow: visible;","top: 0;","left: 0;","}",".blocklyBlockDragSurface {","display: none;","position: absolute;","top: 0;","left: 0;","right: 0;","bottom: 0;","overflow: visible !important;","z-index: 50;","}",".blocklyTooltipDiv {","background-color: #ffffc7;","border: 1px solid #ddc;","box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);","color: #000;","display: none;","font-family: sans-serif;","font-size: 9pt;","opacity: 0.9;","padding: 2px;","position: absolute;","z-index: 100000;",
                +"}",".blocklyResizeSE {","cursor: se-resize;","fill: #aaa;","}",".blocklyResizeSW {","cursor: sw-resize;","fill: #aaa;","}",".blocklyResizeLine {","stroke: #888;","stroke-width: 1;","}",".blocklyHighlightedConnectionPath {","fill: none;","stroke: #fc3;","stroke-width: 4px;","}",".blocklyPathLight {","fill: none;","stroke-linecap: round;","stroke-width: 1;","}",".blocklySelected>.blocklyPath {","stroke: #fc3;","stroke-width: 3px;","}",".blocklySelected>.blocklyPathLight {","display: none;","}",".blocklyDraggable {",
                +'cursor: url("<<<PATH>>>/handopen.cur"), auto;',"cursor: grab;","cursor: -webkit-grab;","cursor: -moz-grab;","}",".blocklyDragging {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyDraggable:active {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyBlockDragSurface .blocklyDraggable {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
                +"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyDragging.blocklyDraggingDelete {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyToolboxDelete {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {","fill-opacity: .8;","stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {","display: none;","}",".blocklyDisabled>.blocklyPath {","fill-opacity: .5;","stroke-opacity: .5;",
                +"}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {","display: none;","}",".blocklyText {","cursor: default;","fill: #fff;","font-family: sans-serif;","font-size: 11pt;","}",".blocklyNonEditableText>text {","pointer-events: none;","}",".blocklyNonEditableText>rect,",".blocklyEditableText>rect {","fill: #fff;","fill-opacity: .6;","}",".blocklyNonEditableText>text,",".blocklyEditableText>text {","fill: #000;","}",".blocklyEditableText:hover>rect {","stroke: #fff;","stroke-width: 2;",
                +"}",".blocklyBubbleText {","fill: #000;","}",".blocklyFlyout {","position: absolute;","z-index: 20;","}",".blocklyFlyoutButton {","fill: #888;","cursor: default;","}",".blocklyFlyoutButtonShadow {","fill: #666;","}",".blocklyFlyoutButton:hover {","fill: #aaa;","}",".blocklyFlyoutLabel {","cursor: default;","}",".blocklyFlyoutLabelBackground {","opacity: 0;","}",".blocklyFlyoutLabelText {","fill: #000;","}",".blocklySvg text, .blocklyBlockDragSurface text {","user-select: none;","-moz-user-select: none;",
                +"-webkit-user-select: none;","cursor: inherit;","}",".blocklyHidden {","display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {","display: block;","}",".blocklyIconGroup {","cursor: default;","}",".blocklyIconGroup:not(:hover),",".blocklyIconGroupReadonly {","opacity: .6;","}",".blocklyIconShape {","fill: #00f;","stroke: #fff;","stroke-width: 1px;","}",".blocklyIconSymbol {","fill: #fff;","}",".blocklyMinimalBody {","margin: 0;","padding: 0;","}",".blocklyCommentTextarea {","background-color: #ffc;",
                +"border: 0;","margin: 0;","padding: 2px;","resize: none;","}",".blocklyHtmlInput {","border: none;","border-radius: 4px;","font-family: sans-serif;","height: 100%;","margin: 0;","outline: none;","padding: 0 1px;","width: 100%","}",".blocklyMainBackground {","stroke-width: 1;","stroke: #c6c6c6;","}",".blocklyMutatorBackground {","fill: #fff;","stroke: #ddd;","stroke-width: 1;","}",".blocklyFlyoutBackground {","fill: #ddd;","fill-opacity: .8;","}",".blocklyTransparentBackground {","opacity: 0;","}",
                +".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyZoom>image {","opacity: .4;","}",".blocklyZoom>image:hover {","opacity: .6;","}",
                +".blocklyZoom>image:active {","opacity: .8;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyAngleCircle {","stroke: #444;","stroke-width: 1;","fill: #ddd;","fill-opacity: .8;","}",".blocklyAngleMarks {","stroke: #444;","stroke-width: 1;","}",".blocklyAngleGauge {","fill: #f88;","fill-opacity: .8;",
                +"}",".blocklyAngleLine {","stroke: #f00;","stroke-width: 2;","stroke-linecap: round;","pointer-events: none;","}",".blocklyContextMenu {","border-radius: 4px;","}",".blocklyDropdownMenu {","padding: 0 !important;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;","}",".blocklyToolboxDiv {","background-color: #ddd;","overflow-x: visible;",
                +"overflow-y: auto;","position: absolute;","z-index: 70;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {",
                +"background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;","}",".blocklyTreeIconClosedRtl {","background-position: 0px -1px;",
                +"}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {","background-position: -32px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedRtl {","background-position: 0px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeIconNone,",".blocklyTreeSelected>.blocklyTreeIconNone {","background-position: -48px -1px;","}",".blocklyTreeLabel {","cursor: default;","font-family: sans-serif;",
                +"font-size: 16px;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}",".blocklyWidgetDiv .goog-palette {","outline: none;","cursor: default;","}",".blocklyWidgetDiv .goog-palette-table {","border: 1px solid #666;","border-collapse: collapse;","}",".blocklyWidgetDiv .goog-palette-cell {","height: 13px;","width: 15px;","margin: 0;","border: 0;",
                +"text-align: center;","vertical-align: middle;","border-right: 1px solid #666;","font-size: 1px;","}",".blocklyWidgetDiv .goog-palette-colorswatch {","position: relative;","height: 13px;","width: 15px;","border: 1px solid #666;","}",".blocklyWidgetDiv .goog-palette-cell-hover .goog-palette-colorswatch {","border: 1px solid #FFF;","}",".blocklyWidgetDiv .goog-palette-cell-selected .goog-palette-colorswatch {","border: 1px solid #000;","color: #fff;","}",".blocklyWidgetDiv .goog-menu {","background: #fff;",
                +"border-color: #ccc #666 #666 #ccc;","border-style: solid;","border-width: 1px;","cursor: default;","font: normal 13px Arial, sans-serif;","margin: 0;","outline: none;","padding: 4px 0;","position: absolute;","overflow-y: auto;","overflow-x: hidden;","max-height: 100%;","z-index: 20000;","}",".blocklyWidgetDiv .goog-menuitem {","color: #000;","font: normal 13px Arial, sans-serif;","list-style: none;","margin: 0;","padding: 4px 7em 4px 28px;","white-space: nowrap;","}",".blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl {",
                +"padding-left: 7em;","padding-right: 28px;","}",".blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem,",".blocklyWidgetDiv .goog-menu-noicon .goog-menuitem {","padding-left: 12px;","}",".blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem {","padding-right: 20px;","}",".blocklyWidgetDiv .goog-menuitem-content {","color: #000;","font: normal 13px Arial, sans-serif;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel,",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content {",
                +"color: #ccc !important;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon {","opacity: 0.3;","-moz-opacity: 0.3;","filter: alpha(opacity=30);","}",".blocklyWidgetDiv .goog-menuitem-highlight,",".blocklyWidgetDiv .goog-menuitem-hover {","background-color: #d6e9f8;","border-color: #d6e9f8;","border-style: dotted;","border-width: 1px 0;","padding-bottom: 3px;","padding-top: 3px;","}",".blocklyWidgetDiv .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-icon {","background-repeat: no-repeat;",
                +"height: 16px;","left: 6px;","position: absolute;","right: auto;","vertical-align: middle;","width: 16px;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon {","left: auto;","right: 6px;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0;","}",".blocklyWidgetDiv .goog-menuitem-accel {",
                +"color: #999;","direction: ltr;","left: auto;","padding: 0 6px;","position: absolute;","right: 0;","text-align: right;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel {","left: 0;","right: auto;","text-align: left;","}",".blocklyWidgetDiv .goog-menuitem-mnemonic-hint {","text-decoration: underline;","}",".blocklyWidgetDiv .goog-menuitem-mnemonic-separator {","color: #999;","font-size: 12px;","padding-left: 4px;","}",".blocklyWidgetDiv .goog-menuseparator {","border-top: 1px solid #ccc;",
                +"margin: 4px 0;","padding: 0;","}",""];Blockly.WidgetDiv={};Blockly.WidgetDiv.DIV=null;Blockly.WidgetDiv.owner_=null;Blockly.WidgetDiv.dispose_=null;Blockly.WidgetDiv.createDom=function(){Blockly.WidgetDiv.DIV||(Blockly.WidgetDiv.DIV=goog.dom.createDom("DIV","blocklyWidgetDiv"),document.body.appendChild(Blockly.WidgetDiv.DIV))};
                +Blockly.WidgetDiv.show=function(a,b,c){Blockly.WidgetDiv.hide();Blockly.WidgetDiv.owner_=a;Blockly.WidgetDiv.dispose_=c;a=goog.style.getViewportPageOffset(document);Blockly.WidgetDiv.DIV.style.top=a.y+"px";Blockly.WidgetDiv.DIV.style.direction=b?"rtl":"ltr";Blockly.WidgetDiv.DIV.style.display="block"};
                +Blockly.WidgetDiv.hide=function(){Blockly.WidgetDiv.owner_&&(Blockly.WidgetDiv.owner_=null,Blockly.WidgetDiv.DIV.style.display="none",Blockly.WidgetDiv.DIV.style.left="",Blockly.WidgetDiv.DIV.style.top="",Blockly.WidgetDiv.dispose_&&Blockly.WidgetDiv.dispose_(),Blockly.WidgetDiv.dispose_=null,goog.dom.removeChildren(Blockly.WidgetDiv.DIV))};Blockly.WidgetDiv.isVisible=function(){return!!Blockly.WidgetDiv.owner_};Blockly.WidgetDiv.hideIfOwner=function(a){Blockly.WidgetDiv.owner_==a&&Blockly.WidgetDiv.hide()};
                +Blockly.WidgetDiv.position=function(a,b,c,d,e){b<d.y&&(b=d.y);e?a>c.width+d.x&&(a=c.width+d.x):a<d.x&&(a=d.x);Blockly.WidgetDiv.DIV.style.left=a+"px";Blockly.WidgetDiv.DIV.style.top=b+"px";Blockly.WidgetDiv.DIV.style.height=c.height+"px"};Blockly.BlockDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.BlockDragSurfaceSvg.prototype.SVG_=null;Blockly.BlockDragSurfaceSvg.prototype.dragGroup_=null;Blockly.BlockDragSurfaceSvg.prototype.container_=null;Blockly.BlockDragSurfaceSvg.prototype.scale_=1;Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_=null;
                +Blockly.BlockDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=Blockly.utils.createSvgElement("svg",{xmlns:Blockly.SVG_NS,"xmlns:html":Blockly.HTML_NS,"xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklyBlockDragSurface"},this.container_),this.dragGroup_=Blockly.utils.createSvgElement("g",{},this.SVG_))};
                +Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow=function(a){goog.asserts.assert(0==this.dragGroup_.childNodes.length,"Already dragging a block.");this.dragGroup_.appendChild(a);this.SVG_.style.display="block";this.surfaceXY_=new goog.math.Coordinate(0,0)};Blockly.BlockDragSurfaceSvg.prototype.translateAndScaleGroup=function(a,b,c){this.scale_=c;a=a.toFixed(0);b=b.toFixed(0);this.dragGroup_.setAttribute("transform","translate("+a+","+b+") scale("+c+")")};
                +Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_=function(){var a=this.surfaceXY_.x,b=this.surfaceXY_.y,a=a.toFixed(0),b=b.toFixed(0);this.SVG_.style.display="block";Blockly.utils.setCssTransform(this.SVG_,"translate3d("+a+"px, "+b+"px, 0px)")};Blockly.BlockDragSurfaceSvg.prototype.translateSurface=function(a,b){this.surfaceXY_=new goog.math.Coordinate(a*this.scale_,b*this.scale_);this.translateSurfaceInternal_()};
                +Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation=function(){var a=Blockly.utils.getRelativeXY(this.SVG_);return new goog.math.Coordinate(a.x/this.scale_,a.y/this.scale_)};Blockly.BlockDragSurfaceSvg.prototype.getGroup=function(){return this.dragGroup_};Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock=function(){return this.dragGroup_.firstChild};
                +Blockly.BlockDragSurfaceSvg.prototype.clearAndHide=function(a){a?a.appendChild(this.getCurrentBlock()):this.dragGroup_.removeChild(this.getCurrentBlock());this.SVG_.style.display="none";goog.asserts.assert(0==this.dragGroup_.childNodes.length,"Drag group was not cleared.");this.surfaceXY_=null};Blockly.inject=function(a,b){goog.isString(a)&&(a=document.getElementById(a)||document.querySelector(a));if(!goog.dom.contains(document,a))throw"Error: container is not in current document.";b=new Blockly.Options(b||{});var c=goog.dom.createDom("div","injectionDiv");a.appendChild(c);a=Blockly.createDom_(c,b);var d=new Blockly.BlockDragSurfaceSvg(c),c=new Blockly.WorkspaceDragSurfaceSvg(c);b=Blockly.createMainWorkspace_(a,b,d,c);Blockly.init_(b);Blockly.mainWorkspace=b;Blockly.svgResize(b);return b};
                +Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");goog.ui.Component.setDefaultRightToLeft(b.RTL);Blockly.Css.inject(b.hasCss,b.pathToMedia);a=Blockly.utils.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklySvg"},a);var c=Blockly.utils.createSvgElement("defs",{},a),d=String(Math.random()).substring(2),e=Blockly.utils.createSvgElement("filter",{id:"blocklyEmbossFilter"+
                +d},c);Blockly.utils.createSvgElement("feGaussianBlur",{"in":"SourceAlpha",stdDeviation:1,result:"blur"},e);var f=Blockly.utils.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",result:"specOut"},e);Blockly.utils.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},f);Blockly.utils.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},e);Blockly.utils.createSvgElement("feComposite",
                +{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1,k4:0},e);b.embossFilterId=e.id;e=Blockly.utils.createSvgElement("pattern",{id:"blocklyDisabledPattern"+d,patternUnits:"userSpaceOnUse",width:10,height:10},c);Blockly.utils.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},e);Blockly.utils.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},e);b.disabledPatternId=e.id;b.gridPattern=Blockly.Grid.createDom(d,b.gridOptions,c);return a};
                +Blockly.createMainWorkspace_=function(a,b,c,d){b.parentWorkspace=null;var e=new Blockly.WorkspaceSvg(b,c,d);e.scale=b.zoomOptions.startScale;a.appendChild(e.createDom("blocklyMainBackground"));!b.hasCategories&&b.languageTree&&(c=e.addFlyout_("svg"),Blockly.utils.insertAfter_(c,a));e.translate(0,0);Blockly.mainWorkspace=e;b.readOnly||b.hasScrollbars||e.addChangeListener(function(){if(!e.isDragging()){var a=e.getMetrics(),c=a.viewLeft+a.absoluteLeft,d=a.viewTop+a.absoluteTop;if(a.contentTop<d||a.contentTop+
                +a.contentHeight>a.viewHeight+d||a.contentLeft<(b.RTL?a.viewLeft:c)||a.contentLeft+a.contentWidth>(b.RTL?a.viewWidth:a.viewWidth+c))for(var k=e.getTopBlocks(!1),l=0,m;m=k[l];l++){var n=m.getRelativeToSurfaceXY(),p=m.getHeightWidth(),q=d+25-p.height-n.y;0<q&&m.moveBy(0,q);q=d+a.viewHeight-25-n.y;0>q&&m.moveBy(0,q);q=25+c-n.x-(b.RTL?0:p.width);0<q&&m.moveBy(q,0);n=c+a.viewWidth-25-n.x+(b.RTL?p.width:0);0>n&&m.moveBy(n,0)}}});Blockly.svgResize(e);Blockly.WidgetDiv.createDom();Blockly.Tooltip.createDom();
                +return e};
                +Blockly.init_=function(a){var b=a.options,c=a.getParentSvg();Blockly.bindEventWithChecks_(c.parentNode,"contextmenu",null,function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()});c=Blockly.bindEventWithChecks_(window,"resize",null,function(){Blockly.hideChaff(!0);Blockly.svgResize(a)});a.setResizeHandlerWrapper(c);Blockly.inject.bindDocumentEvents_();b.languageTree&&(a.toolbox_?a.toolbox_.init(a):a.flyout_&&(a.flyout_.init(a),a.flyout_.show(b.languageTree.childNodes),a.flyout_.scrollToStart(),a.scrollX=
                +a.flyout_.width_,b.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(a.scrollX*=-1),a.translate(a.scrollX,0)));b.hasScrollbars&&(a.scrollbar=new Blockly.ScrollbarPair(a),a.scrollbar.resize());b.hasSounds&&Blockly.inject.loadSounds_(b.pathToMedia,a)};
                +Blockly.inject.bindDocumentEvents_=function(){Blockly.documentEventsBound_||(Blockly.bindEventWithChecks_(document,"keydown",null,Blockly.onKeyDown_),Blockly.bindEvent_(document,"touchend",null,Blockly.longStop_),Blockly.bindEvent_(document,"touchcancel",null,Blockly.longStop_),goog.userAgent.IPAD&&Blockly.bindEventWithChecks_(window,"orientationchange",document,function(){Blockly.svgResize(Blockly.getMainWorkspace())}));Blockly.documentEventsBound_=!0};
                +Blockly.inject.loadSounds_=function(a,b){var c=b.getAudioManager();c.load([a+"click.mp3",a+"click.wav",a+"click.ogg"],"click");c.load([a+"disconnect.wav",a+"disconnect.mp3",a+"disconnect.ogg"],"disconnect");c.load([a+"delete.mp3",a+"delete.ogg",a+"delete.wav"],"delete");var d=[];a=function(){for(;d.length;)Blockly.unbindEvent_(d.pop());c.preload()};d.push(Blockly.bindEventWithChecks_(document,"mousemove",null,a,!0));d.push(Blockly.bindEventWithChecks_(document,"touchstart",null,a,!0))};
                +Blockly.updateToolbox=function(a){console.warn("Deprecated call to Blockly.updateToolbox, use workspace.updateToolbox instead.");Blockly.getMainWorkspace().updateToolbox(a)};var CLOSURE_DEFINES={"goog.DEBUG":!1};Blockly.mainWorkspace=null;Blockly.selected=null;Blockly.draggingConnections_=[];Blockly.clipboardXml_=null;Blockly.clipboardSource_=null;Blockly.cache3dSupported_=null;Blockly.hueToRgb=function(a){return goog.color.hsvToHex(a,Blockly.HSV_SATURATION,255*Blockly.HSV_VALUE)};Blockly.svgSize=function(a){return{width:a.cachedWidth_,height:a.cachedHeight_}};Blockly.resizeSvgContents=function(a){a.resizeContents()};
                +Blockly.svgResize=function(a){for(;a.options.parentWorkspace;)a=a.options.parentWorkspace;var b=a.getParentSvg(),c=b.parentNode;if(c){var d=c.offsetWidth,c=c.offsetHeight;b.cachedWidth_!=d&&(b.setAttribute("width",d+"px"),b.cachedWidth_=d);b.cachedHeight_!=c&&(b.setAttribute("height",c+"px"),b.cachedHeight_=c);a.resize()}};
                +Blockly.onKeyDown_=function(a){if(!Blockly.mainWorkspace.options.readOnly&&!Blockly.utils.isTargetInput(a)){var b=!1;if(27==a.keyCode)Blockly.hideChaff();else if(8==a.keyCode||46==a.keyCode){a.preventDefault();if(Blockly.mainWorkspace.isDragging())return;Blockly.selected&&Blockly.selected.isDeletable()&&(b=!0)}else if(a.altKey||a.ctrlKey||a.metaKey){if(Blockly.mainWorkspace.isDragging())return;Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()&&(67==a.keyCode?(Blockly.hideChaff(),
                +Blockly.copy_(Blockly.selected)):88==a.keyCode&&(Blockly.copy_(Blockly.selected),b=!0));86==a.keyCode?Blockly.clipboardXml_&&(Blockly.Events.setGroup(!0),Blockly.clipboardSource_.paste(Blockly.clipboardXml_),Blockly.Events.setGroup(!1)):90==a.keyCode&&(Blockly.hideChaff(),Blockly.mainWorkspace.undo(a.shiftKey))}b&&(Blockly.Events.setGroup(!0),Blockly.hideChaff(),Blockly.selected.dispose(!0,!0),Blockly.Events.setGroup(!1))}};
                +Blockly.copy_=function(a){var b=Blockly.Xml.blockToDom(a);Blockly.Xml.deleteNext(b);var c=a.getRelativeToSurfaceXY();b.setAttribute("x",a.RTL?-c.x:c.x);b.setAttribute("y",c.y);Blockly.clipboardXml_=b;Blockly.clipboardSource_=a.workspace};Blockly.duplicate_=function(a){var b=Blockly.clipboardXml_,c=Blockly.clipboardSource_;Blockly.copy_(a);a.workspace.paste(Blockly.clipboardXml_);Blockly.clipboardXml_=b;Blockly.clipboardSource_=c};
                +Blockly.onContextMenu_=function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()};Blockly.hideChaff=function(a){Blockly.Tooltip.hide();Blockly.WidgetDiv.hide();a||(a=Blockly.getMainWorkspace(),a.toolbox_&&a.toolbox_.flyout_&&a.toolbox_.flyout_.autoClose&&a.toolbox_.clearSelection())};Blockly.addChangeListener=function(a){console.warn("Deprecated call to Blockly.addChangeListener, use workspace.addChangeListener instead.");return Blockly.getMainWorkspace().addChangeListener(a)};
                +Blockly.getMainWorkspace=function(){return Blockly.mainWorkspace};Blockly.alert=function(a,b){window.alert(a);b&&b()};Blockly.confirm=function(a,b){b(window.confirm(a))};Blockly.prompt=function(a,b,c){c(window.prompt(a,b))};Blockly.jsonInitFactory_=function(a){return function(){this.jsonInit(a)}};
                +Blockly.defineBlocksWithJsonArray=function(a){for(var b=0,c;c=a[b];b++){var d=c.type;null==d||""===d?console.warn("Block definition #"+b+" in JSON array is missing a type attribute. Skipping."):(Blockly.Blocks[d]&&console.warn("Block definition #"+b+' in JSON array overwrites prior definition of "'+d+'".'),Blockly.Blocks[d]={init:Blockly.jsonInitFactory_(c)})}};
                +Blockly.bindEventWithChecks_=function(a,b,c,d,e){var f=!1,g=function(a){var b=!e;a=Blockly.Touch.splitEventByTouches(a);for(var g=0,h;h=a[g];g++)if(!b||Blockly.Touch.shouldHandleEvent(h))Blockly.Touch.setClientFromTouch(h),c?d.call(c,h):d(h),f=!0};a.addEventListener(b,g,!1);var h=[[a,b,g]];if(b in Blockly.Touch.TOUCH_MAP)for(var k=function(a){g(a);f&&a.preventDefault()},l=0,m;m=Blockly.Touch.TOUCH_MAP[b][l];l++)a.addEventListener(m,k,!1),h.push([a,m,k]);return h};
                +Blockly.bindEvent_=function(a,b,c,d){var e=function(a){c?d.call(c,a):d(a)};a.addEventListener(b,e,!1);var f=[[a,b,e]];if(b in Blockly.Touch.TOUCH_MAP)for(var g=function(a){if(1==a.changedTouches.length){var b=a.changedTouches[0];a.clientX=b.clientX;a.clientY=b.clientY}e(a);a.preventDefault()},h=0,k;k=Blockly.Touch.TOUCH_MAP[b][h];h++)a.addEventListener(k,g,!1),f.push([a,k,g]);return f};
                +Blockly.unbindEvent_=function(a){for(var b;a.length;){b=a.pop();var c=b[0],d=b[1];b=b[2];c.removeEventListener(d,b,!1)}return b};Blockly.isNumber=function(a){return!!a.match(/^\s*-?\d+(\.\d+)?\s*$/)};goog.global.console||(goog.global.console={log:function(){},warn:function(){}});goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.getMainWorkspace=Blockly.getMainWorkspace;goog.global.Blockly.addChangeListener=Blockly.addChangeListener;var blocklyApp={};
                +blocklyApp.NotificationsService=ng.core.Class({constructor:[function(){this.currentMessage="";this.timeouts=[]}],setDisplayedMessage_:function(a){this.currentMessage=a},getDisplayedMessage:function(){return this.currentMessage},speak:function(a){this.timeouts.forEach(function(a){clearTimeout(a)});this.timeouts.length=0;this.setDisplayedMessage_("");var b=this;this.timeouts.push(setTimeout(function(){b.setDisplayedMessage_(a)},20));this.timeouts.push(setTimeout(function(){b.setDisplayedMessage_("")},5E3))}});blocklyApp.AudioService=ng.core.Class({constructor:[blocklyApp.NotificationsService,function(a){this.notificationsService=a;this.canPlayAudio=!1;ACCESSIBLE_GLOBALS.hasOwnProperty("mediaPathPrefix")&&(this.canPlayAudio=!0,a=ACCESSIBLE_GLOBALS.mediaPathPrefix,this.AUDIO_PATHS_={connect:a+"click.mp3","delete":a+"delete.mp3",oops:a+"oops.mp3"});this.cachedAudioFiles_={};this.onEndedCallbacks_={connect:[],"delete":[],oops:[]}}],play_:function(a,b){if(this.canPlayAudio){this.cachedAudioFiles_.hasOwnProperty(a)||
                +(this.cachedAudioFiles_[a]=new Audio(this.AUDIO_PATHS_[a]));if(b)this.onEndedCallbacks_[a].push(b),this.cachedAudioFiles_[a].addEventListener("ended",b);else{var c=this;this.onEndedCallbacks_[a].forEach(function(b){c.cachedAudioFiles_[a].removeEventListener("ended",b)});this.onEndedCallbacks_[a].length=0}this.cachedAudioFiles_[a].play()}},playConnectSound:function(){this.play_("connect")},playDeleteSound:function(){this.play_("delete")},playOopsSound:function(a){if(a){var b=this;this.play_("oops",
                +function(){b.notificationsService.speak(a)})}else this.play_("oops")}});blocklyApp.BlockConnectionService=ng.core.Class({constructor:[blocklyApp.NotificationsService,blocklyApp.AudioService,function(a,b){this.notificationsService=a;this.audioService=b;this.markedConnection_=null}],findCompatibleConnection_:function(a,b){if(!b||!b.getSourceBlock().workspace)return null;var c=Blockly.OPPOSITE_TYPE[b.type];return(a=c==Blockly.OUTPUT_VALUE?a.outputConnection:c==Blockly.PREVIOUS_STATEMENT?a.previousConnection:c==Blockly.NEXT_STATEMENT?a.nextConnection:null)&&a.checkType_(b)?
                +a:null},isAnyConnectionMarked:function(){return!!this.markedConnection_},getMarkedConnectionSourceBlock:function(){return this.markedConnection_?this.markedConnection_.getSourceBlock():null},canBeAttachedToMarkedConnection:function(a){return!!this.findCompatibleConnection_(a,this.markedConnection_)},canBeMovedToMarkedConnection:function(a){if(!this.markedConnection_)return!1;for(var b=this.getMarkedConnectionSourceBlock();b;){if(b.id==a.id)return!1;b=b.getParent()}return this.canBeAttachedToMarkedConnection(a)},
                +markConnection:function(a){this.markedConnection_=a;this.notificationsService.speak(Blockly.Msg.ADDED_LINK_MSG)},attachToMarkedConnection:function(a){a=Blockly.Xml.blockToDom(a);a=Blockly.Xml.domToBlock(blocklyApp.workspace,a);var b=this.markedConnection_.targetBlock()&&this.markedConnection_.type==Blockly.PREVIOUS_STATEMENT?this.markedConnection_.targetConnection:this.markedConnection_;var c=this.findCompatibleConnection_(a,b);if(c)return b.connect(c),this.markedConnection_=null,this.audioService.playConnectSound(),
                +a.id;throw Error("Unable to connect block to marked connection. This should not happen.");}});blocklyApp.BlockOptionsModalService=ng.core.Class({constructor:[function(){this.actionButtonsInfo=[];this.preShowHook=function(){throw Error("A pre-show hook must be defined for the block options modal before it can be shown.");};this.modalIsShown=!1;this.onDismissCallback=null}],registerPreShowHook:function(a){var b=this;this.preShowHook=function(){a(b.actionButtonsInfo,b.onDismissCallback)}},isModalShown:function(){return this.modalIsShown},showModal:function(a,b){this.actionButtonsInfo=a;this.onDismissCallback=
                +b;this.preShowHook();this.modalIsShown=!0},hideModal:function(){this.modalIsShown=!1}});blocklyApp.KeyboardInputService=ng.core.Class({constructor:[function(){this.keysToActions={};this.keysToActionsOverride=null;var a=this;document.addEventListener("keydown",function(b){var c=String(b.keyCode),d=a.keysToActionsOverride||a.keysToActions;if(d.hasOwnProperty(c))d[c](b)})}],setOverride:function(a){this.keysToActionsOverride=a},addOverride:function(a,b){this.keysToActionsOverride[a]=b},clearOverride:function(){this.keysToActionsOverride=null}});blocklyApp.TranslatePipe=ng.core.Pipe({name:"translate"}).Class({constructor:function(){},transform:function(a){return Blockly.Msg[a]}});Blockly.CommonModal=function(){};
                +Blockly.CommonModal.setupKeyboardOverrides=function(a){a.keyboardInputService.setOverride({9:function(b){b.preventDefault();b.stopPropagation();b.shiftKey?0>=a.activeButtonIndex?(a.activeActionButtonIndex=0,a.audioService.playOopsSound()):a.activeButtonIndex--:a.activeButtonIndex==a.numInteractiveElements(a)-1?a.audioService.playOopsSound():a.activeButtonIndex++;a.focusOnOption(a.activeButtonIndex,a)},27:function(){a.dismissModal()},38:function(a){a.preventDefault()},40:function(a){a.preventDefault()}})};
                +Blockly.CommonModal.getInteractiveElements=function(a){return Array.prototype.filter.call(a.getInteractiveContainer().elements,function(a){return"hidden"===a.type||a.disabled||0>a.tabIndex?!1:!0})};Blockly.CommonModal.numInteractiveElements=function(a){return this.getInteractiveElements(a).length};Blockly.CommonModal.focusOnOption=function(a,b){this.getInteractiveElements(b)[a].focus()};Blockly.CommonModal.hideModal=function(){this.modalIsVisible=!1;this.keyboardInputService.clearOverride()};blocklyApp.BlockOptionsModalComponent=ng.core.Component({selector:"blockly-block-options-modal",template:'\n    <div *ngIf="modalIsVisible" class="blocklyModalCurtain"\n         (click)="dismissModal()">\n      \x3c!-- $event.stopPropagation() prevents the modal from closing when its\n      interior is clicked. --\x3e\n      <div id="blockOptionsModal" class="blocklyModal" role="alertdialog"\n           (click)="$event.stopPropagation()" tabindex="-1"\n           aria-labelledby="blockOptionsModalHeading">\n        <h3 id="blockOptionsModalHeading">{{\'BLOCK_OPTIONS\'|translate}}</h3>\n        <div role="document">\n          <div class="blocklyModalButtonContainer"\n               *ngFor="#buttonInfo of actionButtonsInfo; #buttonIndex=index">\n            <button [id]="getOptionId(buttonIndex)"\n                    (click)="buttonInfo.action(); hideModal();"\n                    [ngClass]="{activeButton: activeButtonIndex == buttonIndex}">\n              {{buttonInfo.translationIdForText|translate}}\n            </button>\n          </div>\n        </div>\n\n        <div class="blocklyModalButtonContainer">\n          <button [id]="getCancelOptionId()"\n                  (click)="dismissModal()"\n                  [ngClass]="{activeButton: activeButtonIndex == actionButtonsInfo.length}">\n            {{\'CANCEL\'|translate}}\n          </button>\n        </div>\n      </div>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.BlockOptionsModalService,blocklyApp.KeyboardInputService,blocklyApp.AudioService,function(a,b,c){this.blockOptionsModalService=a;this.keyboardInputService=b;this.audioService=c;this.modalIsVisible=!1;this.actionButtonsInfo=[];this.activeButtonIndex=-1;this.onDismissCallback=null;var d=this;this.blockOptionsModalService.registerPreShowHook(function(a,b){d.modalIsVisible=!0;d.actionButtonsInfo=a;d.activeActionButtonIndex=-1;d.onDismissCallback=
                +b;Blockly.CommonModal.setupKeyboardOverrides(d);d.keyboardInputService.addOverride("13",function(a){a.preventDefault();a.stopPropagation();-1!=d.activeButtonIndex&&(document.getElementById(d.getOptionId(d.activeButtonIndex)),d.activeButtonIndex<d.actionButtonsInfo.length?d.actionButtonsInfo[d.activeButtonIndex].action():d.dismissModal(),d.hideModal())});setTimeout(function(){document.getElementById("blockOptionsModal").focus()},150)})}],focusOnOption:function(a){document.getElementById(this.getOptionId(a)).focus()},
                +numInteractiveElements:function(){return this.actionButtonsInfo.length+1},getOptionId:function(a){return"block-options-modal-option-"+a},getCancelOptionId:function(){return this.getOptionId(this.actionButtonsInfo.length)},dismissModal:function(){this.onDismissCallback();this.hideModal()},hideModal:function(){this.modalIsVisible=!1;this.keyboardInputService.clearOverride();this.blockOptionsModalService.hideModal()}});blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN="blocklyEmptyWorkspaceBtn";blocklyApp.BLOCK_ROOT_ID_SUFFIX="-blockRoot";blocklyApp.UtilsService=ng.core.Class({constructor:[function(){}],getBlockDescription:function(a){return a.toString(void 0,"BLANK")},isWorkspaceEmpty:function(){return!blocklyApp.workspace.topBlocks_.length}});blocklyApp.VariableModalService=ng.core.Class({constructor:[function(){this.modalIsShown=!1}],registerPreAddShowHook:function(a){this.preAddShowHook=function(){a()}},registerPreRenameShowHook:function(a){this.preRenameShowHook=function(b){a(b)}},registerPreRemoveShowHook:function(a){this.preRemoveShowHook=function(b,c){a(b,c)}},isModalShown:function(){return this.modalIsShown},showAddModal_:function(){this.preAddShowHook();this.modalIsShown=!0},showRenameModal_:function(a){this.preRenameShowHook(a);
                +this.modalIsShown=!0},showRemoveModal_:function(a){var b=this.getNumVariables(a);this.modalIsShown=!0;if(1<b)this.preRemoveShowHook(a,b);else{a=blocklyApp.workspace.getVariable(a);blocklyApp.workspace.deleteVariableInternal_(a);var c=this;setTimeout(function(){c.modalIsShown=!1})}},getNumVariables:function(a){return blocklyApp.workspace.getVariableUses(a).length},hideModal:function(){this.modalIsShown=!1}});blocklyApp.TreeService=ng.core.Class({constructor:[blocklyApp.AudioService,blocklyApp.BlockConnectionService,blocklyApp.BlockOptionsModalService,blocklyApp.NotificationsService,blocklyApp.UtilsService,blocklyApp.VariableModalService,function(a,b,c,d,e,f){this.audioService=a;this.blockConnectionService=b;this.blockOptionsModalService=c;this.notificationsService=d;this.utilsService=e;this.variableModalService=f;this.BLOCK_ROOT_ID_SUFFIX_=blocklyApp.BLOCK_ROOT_ID_SUFFIX;this.activeDescendantIds_={};
                +this.sidebarButtonElements_=Array.from(document.querySelectorAll("button.blocklySidebarButton"))}],scrollToElement_:function(a){a=document.getElementById(a);var b=document.body||document.documentElement;(a.offsetTop<b.scrollTop||a.offsetTop>b.scrollTop+window.innerHeight)&&window.scrollTo(0,a.offsetTop-10)},isLi_:function(a){return"LI"==a.tagName},getParentLi_:function(a){for(a=a.parentNode;a&&!this.isLi_(a);)a=a.parentNode;return a},getFirstChildLi_:function(a){a=a.children;for(var b=0;b<a.length;b++){if(this.isLi_(a[b]))return a[b];
                +var c=this.getFirstChildLi_(a[b]);if(c)return c}return null},getLastChildLi_:function(a){a=a.children;for(var b=a.length-1;0<=b;b--){if(this.isLi_(a[b]))return a[b];var c=this.getLastChildLi_(a[b]);if(c)return c}return null},getInitialSiblingLi_:function(a){for(;;){var b=this.getPreviousSiblingLi_(a);if(b&&b.id!=a.id)a=b;else return a}},getPreviousSiblingLi_:function(a){if(a.previousElementSibling)return a=a.previousElementSibling,this.isLi_(a)?a:this.getLastChildLi_(a);for(a=a.parentNode;a&&"OL"!=
                +a.tagName;){if(a.previousElementSibling)return a=a.previousElementSibling,this.isLi_(a)?a:this.getLastChildLi_(a);a=a.parentNode}return null},getNextSiblingLi_:function(a){if(a.nextElementSibling)return a=a.nextElementSibling,this.isLi_(a)?a:this.getFirstChildLi_(a);for(a=a.parentNode;a&&"OL"!=a.tagName;){if(a.nextElementSibling)return a=a.nextElementSibling,this.isLi_(a)?a:this.getFirstChildLi_(a);a=a.parentNode}return null},getFinalSiblingLi_:function(a){for(;;){var b=this.getNextSiblingLi_(a);
                +if(b&&b.id!=a.id)a=b;else return a}},getWorkspaceFocusTargets_:function(){return Array.from(document.querySelectorAll(".blocklyWorkspaceFocusTarget"))},getAllFocusTargets_:function(){return this.getWorkspaceFocusTargets_().concat(this.sidebarButtonElements_)},getNextFocusTargetId_:function(a){for(var b=this.getAllFocusTargets_(),c=0;c<b.length-1;c++)if(b[c].id==a)return b[c+1].id;return null},getPreviousFocusTargetId_:function(a){for(var b=this.getAllFocusTargets_(),c=b.length-1;0<c;c--)if(b[c].id==
                +a)return b[c-1].id;return null},getActiveDescId:function(a){return this.activeDescendantIds_[a]||""},initActiveDesc:function(a){var b=document.getElementById(a);this.setActiveDesc(this.getFirstChildLi_(b).id,a)},setActiveDesc:function(a,b){this.getActiveDescId(b)&&this.clearActiveDesc(b);document.getElementById(a).classList.add("blocklyActiveDescendant");this.activeDescendantIds_[b]=a;this.scrollToElement_(a)},clearActiveDesc:function(a){var b=document.getElementById(this.getActiveDescId(a));b&&b.classList.remove("blocklyActiveDescendant");
                +this.activeDescendantIds_[a]&&delete this.activeDescendantIds_[a]},clearAllActiveDescs:function(){for(var a in this.activeDescendantIds_){var b=document.getElementById(this.getActiveDescId(a));b&&b.classList.remove("blocklyActiveDescendant")}this.activeDescendantIds_={}},isTreeRoot_:function(a){return a.classList.contains("blocklyTree")},getBlockRootId_:function(a){return a+this.BLOCK_ROOT_ID_SUFFIX_},getContainingBlock_:function(a){for(;-1===a.id.indexOf(this.BLOCK_ROOT_ID_SUFFIX_);)a=a.parentNode;
                +a=a.id;a=a.substring(0,a.length-this.BLOCK_ROOT_ID_SUFFIX_.length);return blocklyApp.workspace.getBlockById(a)},isTopLevelBlock_:function(a){return!a.getParent()},isIsolatedTopLevelBlock_:function(a){var b=(!a.nextConnection||!a.nextConnection.targetConnection)&&(!a.previousConnection||!a.previousConnection.targetConnection);return this.isTopLevelBlock_(a)&&b},safelyRemoveBlock_:function(a,b,c){var d=this.getTreeIdForBlock(a.id);if(c?this.isTopLevelBlock_(a):this.isIsolatedTopLevelBlock_(a)){var e=
                +null;c=this.getWorkspaceFocusTargets_();for(a=0;a<c.length;a++)if(c[a].id==d){a+1<c.length?e=c[a+1]:0<a&&(e=c[a-1]);break}this.clearActiveDesc(d);b();setTimeout(function(){e?e.focus():document.getElementById(blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus()})}else{a=this.getBlockRootId_(a.id);a=document.getElementById(a);var f=c?this.getParentLi_(a)||this.getPreviousSiblingLi_(a):this.getParentLi_(a)||this.getNextSiblingLi_(a)||this.getPreviousSiblingLi_(a);this.clearActiveDesc(d);b();var g=this;setTimeout(function(){g.setActiveDesc(f.id,
                +d);document.getElementById(d).focus()})}},getTreeIdForBlock:function(a){for(a=document.getElementById(this.getBlockRootId_(a));!this.isTreeRoot_(a);)a=a.parentNode;return a.id},focusOnBlock:function(a){var b=this;setTimeout(function(){var c=b.getTreeIdForBlock(a);document.getElementById(c).focus();b.setActiveDesc(b.getBlockRootId_(a),c)})},showBlockOptionsModal:function(a){var b=this,c=[];a.previousConnection&&c.push({action:function(){b.blockConnectionService.markConnection(a.previousConnection);
                +b.focusOnBlock(a.id)},translationIdForText:"MARK_SPOT_BEFORE"});a.nextConnection&&c.push({action:function(){b.blockConnectionService.markConnection(a.nextConnection);b.focusOnBlock(a.id)},translationIdForText:"MARK_SPOT_AFTER"});this.blockConnectionService.canBeMovedToMarkedConnection(a)&&c.push({action:function(){var c=b.utilsService.getBlockDescription(a),e=b.getTreeIdForBlock(b.blockConnectionService.getMarkedConnectionSourceBlock().id);b.clearActiveDesc(e);var f=b.blockConnectionService.attachToMarkedConnection(a);
                +b.safelyRemoveBlock_(a,function(){a.dispose(!1)},!0);setTimeout(function(){b.focusOnBlock(f);if(b.getTreeIdForBlock(f)!=e&&document.getElementById(e)){var a=b.getActiveDescId(e);a&&(a=b.getContainingBlock_(document.getElementById(a)),a=b.getTreeIdForBlock(a),a!=e&&b.clearActiveDesc(e));b.initActiveDesc(e)}b.notificationsService.speak(c+" "+Blockly.Msg.ATTACHED_BLOCK_TO_LINK_MSG+". Now on attached block in workspace.")})},translationIdForText:"MOVE_TO_MARKED_SPOT"});c.push({action:function(){var c=
                +b.utilsService.getBlockDescription(a);b.safelyRemoveBlock_(a,function(){a.dispose(!0);b.audioService.playDeleteSound()},!1);setTimeout(function(){var a=c+" deleted. "+(b.utilsService.isWorkspaceEmpty()?"Workspace is empty.":"Now on workspace.");b.notificationsService.speak(a)})},translationIdForText:"DELETE"});this.blockOptionsModalService.showModal(c,function(){b.focusOnBlock(a.id)})},moveUpOneLevel_:function(a){var b=document.getElementById(this.getActiveDescId(a));(b=this.getParentLi_(b))?this.setActiveDesc(b.id,
                +a):this.audioService.playOopsSound()},onKeypress:function(a,b){if(!this.blockOptionsModalService.isModalShown()&&!this.variableModalService.isModalShown()){b=b.id;var c=document.getElementById(this.getActiveDescId(b));c||(this.initActiveDesc(b),c=document.getElementById(this.getActiveDescId(b)));if(!a.altKey&&!a.ctrlKey)if("INPUT"==document.activeElement.tagName||"SELECT"==document.activeElement.tagName){if(9==a.keyCode||13==a.keyCode||27==a.keyCode)if(document.getElementById(b).focus(),27==a.keyCode||
                +13==a.keyCode)a.preventDefault(),a.stopPropagation()}else if(13==a.keyCode){a.stopPropagation();a=!1;for(var d=Array.from(c.children);d.length;){b=d.shift();if("BUTTON"==b.tagName){b.click();a=!0;break}else if("INPUT"==b.tagName){b.focus();b.select();this.notificationsService.speak("Type a value, then press Escape to exit");a=!0;break}else{if("SELECT"==b.tagName){b.focus();a=!0;return}if("LI"==b.tagName)continue}b.children&&Array.from(b.children).reverse().forEach(function(a){d.unshift(a)})}a||(a=
                +this.getContainingBlock_(c),this.showBlockOptionsModal(a))}else if(9!=a.keyCode&&-1!==[27,35,36,37,38,39,40].indexOf(a.keyCode)){if(27==a.keyCode||37==a.keyCode)this.moveUpOneLevel_(b);else if(35==a.keyCode)(c=this.getFinalSiblingLi_(c))&&this.setActiveDesc(c.id,b);else if(36==a.keyCode)(c=this.getInitialSiblingLi_(c))&&this.setActiveDesc(c.id,b);else if(38==a.keyCode){var e=this.getPreviousSiblingLi_(c);e?this.setActiveDesc(e.id,b):(b="Reached top of list.",this.getParentLi_(c)&&(b+=" Press left to go to parent list."),
                +this.audioService.playOopsSound(b))}else 39==a.keyCode?(c=this.getFirstChildLi_(c))?this.setActiveDesc(c.id,b):this.audioService.playOopsSound():40==a.keyCode&&((c=this.getNextSiblingLi_(c))?this.setActiveDesc(c.id,b):this.audioService.playOopsSound("Reached bottom of list."));a.preventDefault();a.stopPropagation()}}}});blocklyApp.ToolboxModalService=ng.core.Class({constructor:[blocklyApp.BlockConnectionService,blocklyApp.NotificationsService,blocklyApp.TreeService,blocklyApp.UtilsService,function(a,b,c,d){this.blockConnectionService=a;this.notificationsService=b;this.treeService=c;this.utilsService=d;this.modalIsShown=!1;this.hasVariableCategory=this.onDismissCallback=this.onSelectBlockCallback=this.selectedToolboxCategories=null;this.preShowHook=function(){throw Error("A pre-show hook must be defined for the toolbox modal before it can be shown.");
                +}}],populateToolbox_:function(){this.allToolboxCategories=[];var a=document.getElementById("blockly-toolbox-xml"),b=a.getElementsByTagName("category");if(b.length)this.allToolboxCategories=Array.from(b).map(function(a){var b=new Blockly.Workspace,c=a.attributes.custom;c&&c.value==Blockly.VARIABLE_CATEGORY_NAME?Blockly.Variables.flyoutCategoryBlocks(blocklyApp.workspace).forEach(function(a){Blockly.Xml.domToBlock(a,b)}):Blockly.Xml.domToWorkspace(a,b);return{categoryName:a.attributes.name.value,blocks:b.topBlocks_}}),
                +this.computeCategoriesForCreateNewGroupModal_();else{var c=this;setTimeout(function(){var b=new Blockly.Workspace;Array.from(a.children).forEach(function(a){Blockly.Xml.domToBlock(b,a)});c.allToolboxCategories=[{categoryName:"",blocks:b.topBlocks_}];c.computeCategoriesForCreateNewGroupModal_()})}},computeCategoriesForCreateNewGroupModal_:function(){this.toolboxCategoriesForNewGroup=[];var a=this;this.allToolboxCategories.forEach(function(b){var c=b.blocks.filter(function(a){return!a.outputConnection});
                +0<c.length&&a.toolboxCategoriesForNewGroup.push({categoryName:b.categoryName,blocks:c})})},registerPreShowHook:function(a){var b=this;this.preShowHook=function(){a(b.selectedToolboxCategories,b.onSelectBlockCallback,b.onDismissCallback)}},isModalShown:function(){return this.modalIsShown},toolboxHasVariableCategory:function(){if(null===this.hasVariableCategory){var a=document.getElementById("blockly-toolbox-xml").getElementsByTagName("category"),b=this;Array.from(a).forEach(function(a){(a=a.attributes.custom)&&
                +a.value==Blockly.VARIABLE_CATEGORY_NAME&&(b.hasVariableCategory=!0)});null===this.hasVariableCategory&&(this.hasVariableCategory=!1)}return this.hasVariableCategory},showModal_:function(a,b,c){this.selectedToolboxCategories=a;this.onSelectBlockCallback=b;this.onDismissCallback=c;this.preShowHook();this.modalIsShown=!0},hideModal:function(){this.modalIsShown=!1},showToolboxModalForAttachToMarkedConnection:function(a){var b=this,c=[];this.populateToolbox_();this.allToolboxCategories.forEach(function(a){var d=
                +a.blocks.filter(function(a){return b.blockConnectionService.canBeAttachedToMarkedConnection(a)});0<d.length&&c.push({categoryName:a.categoryName,blocks:d})});this.showModal_(c,function(a){var c=b.utilsService.getBlockDescription(a),d=b.treeService.getTreeIdForBlock(b.blockConnectionService.getMarkedConnectionSourceBlock().id);b.treeService.clearActiveDesc(d);var g=b.blockConnectionService.attachToMarkedConnection(a);setTimeout(function(){b.treeService.focusOnBlock(g);b.notificationsService.speak("Attached. Now on, "+
                +c+", block in workspace.")})},function(){document.getElementById(a).focus()})},showToolboxModalForCreateNewGroup:function(a){var b=this;this.populateToolbox_();this.showModal_(this.toolboxCategoriesForNewGroup,function(a){var c=b.utilsService.getBlockDescription(a);a=Blockly.Xml.blockToDom(a);var e=Blockly.Xml.domToBlock(blocklyApp.workspace,a).id;setTimeout(function(){b.treeService.focusOnBlock(e);b.notificationsService.speak("Created new group in workspace. Now on, "+c+", block in workspace.")})},
                +function(){document.getElementById(a).focus()})}});blocklyApp.SidebarComponent=ng.core.Component({selector:"blockly-sidebar",template:'\n    <div class="blocklySidebarColumn">\n      <button *ngFor="#buttonConfig of customSidebarButtons"\n              id="{{buttonConfig.id || undefined}}"\n              (click)="buttonConfig.action()"\n              class="blocklySidebarButton">\n        {{buttonConfig.text}}\n      </button>\n      <button id="{{ID_FOR_ATTACH_TO_LINK_BUTTON}}"\n              (click)="showToolboxModalForAttachToMarkedConnection()"\n              [attr.disabled]="!isAnyConnectionMarked() ? \'disabled\' : undefined"\n              [attr.aria-disabled]="!isAnyConnectionMarked()"\n              class="blocklySidebarButton">\n        {{\'ATTACH_NEW_BLOCK_TO_LINK\'|translate}}\n      </button>\n      <button id="{{ID_FOR_CREATE_NEW_GROUP_BUTTON}}"\n              (click)="showToolboxModalForCreateNewGroup()"\n              class="blocklySidebarButton">\n        {{\'CREATE_NEW_BLOCK_GROUP\'|translate}}\n      </button>\n      <button id="clear-workspace" (click)="clearWorkspace()"\n              [attr.disabled]="isWorkspaceEmpty() ? \'disabled\' : undefined"\n              [attr.aria-disabled]="isWorkspaceEmpty()"\n              class="blocklySidebarButton">\n        {{\'ERASE_WORKSPACE\'|translate}}\n      </button>\n      <button *ngIf="hasVariableCategory()" id="add-variable"\n              (click)="showAddVariableModal()"\n              class="blocklySidebarButton">\n        Add Variable\n      </button>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.BlockConnectionService,blocklyApp.ToolboxModalService,blocklyApp.TreeService,blocklyApp.UtilsService,blocklyApp.VariableModalService,function(a,b,c,d,e){this.customSidebarButtons=ACCESSIBLE_GLOBALS&&ACCESSIBLE_GLOBALS.customSidebarButtons?ACCESSIBLE_GLOBALS.customSidebarButtons:[];this.blockConnectionService=a;this.toolboxModalService=b;this.treeService=c;this.utilsService=d;this.variableModalService=e;this.ID_FOR_ATTACH_TO_LINK_BUTTON=
                +"blocklyAttachToLinkBtn";this.ID_FOR_CREATE_NEW_GROUP_BUTTON="blocklyCreateNewGroupBtn"}],isAnyConnectionMarked:function(){return this.blockConnectionService.isAnyConnectionMarked()},isWorkspaceEmpty:function(){return this.utilsService.isWorkspaceEmpty()},hasVariableCategory:function(){return this.toolboxModalService.toolboxHasVariableCategory()},clearWorkspace:function(){blocklyApp.workspace.clear();this.treeService.clearAllActiveDescs();setTimeout(function(){document.getElementById(blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus()},
                +50)},showToolboxModalForAttachToMarkedConnection:function(){this.toolboxModalService.showToolboxModalForAttachToMarkedConnection(this.ID_FOR_ATTACH_TO_LINK_BUTTON)},showToolboxModalForCreateNewGroup:function(){this.toolboxModalService.showToolboxModalForCreateNewGroup(this.ID_FOR_CREATE_NEW_GROUP_BUTTON)},showAddVariableModal:function(){this.variableModalService.showAddModal_("item")}});blocklyApp.ToolboxModalComponent=ng.core.Component({selector:"blockly-toolbox-modal",template:'\n    <div *ngIf="modalIsVisible" class="blocklyModalCurtain"\n         (click)="dismissModal()">\n      \x3c!-- $event.stopPropagation() prevents the modal from closing when its\n      interior is clicked. --\x3e\n      <div id="toolboxModal" class="blocklyModal" role="alertdialog"\n           (click)="$event.stopPropagation()" tabindex="-1"\n           aria-labelledby="toolboxModalHeading">\n        <h3 id="toolboxModalHeading">{{\'SELECT_A_BLOCK\'|translate}}</h3>\n\n        <div *ngFor="#toolboxCategory of toolboxCategories; #categoryIndex=index">\n          <h4 *ngIf="toolboxCategory.categoryName">{{toolboxCategory.categoryName}}</h4>\n          <div class="blocklyModalButtonContainer"\n               *ngFor="#block of toolboxCategory.blocks; #blockIndex=index">\n            <button [id]="getOptionId(getOverallIndex(categoryIndex, blockIndex))"\n                    (click)="selectBlock(getBlock(categoryIndex, blockIndex))"\n                    [ngClass]="{activeButton: activeButtonIndex == getOverallIndex(categoryIndex, blockIndex)}">\n              {{getBlockDescription(block)}}\n            </button>\n          </div>\n        </div>\n        <hr>\n        <div class="blocklyModalButtonContainer">\n          <button [id]="getCancelOptionId()" (click)="dismissModal()"\n                  [ngClass]="{activeButton: activeButtonIndex == totalNumBlocks}">\n            {{\'CANCEL\'|translate}}\n          </button>\n        </div>\n      </div>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.ToolboxModalService,blocklyApp.KeyboardInputService,blocklyApp.AudioService,blocklyApp.UtilsService,blocklyApp.TreeService,function(a,b,c,d,e){this.toolboxModalService=a;this.keyboardInputService=b;this.audioService=c;this.utilsService=d;this.treeService=e;this.modalIsVisible=!1;this.toolboxCategories=[];this.onDismissCallback=this.onSelectBlockCallback=null;this.firstBlockIndexes=[];this.activeButtonIndex=-1;this.totalNumBlocks=0;
                +var f=this;this.toolboxModalService.registerPreShowHook(function(a,b,c){f.modalIsVisible=!0;f.toolboxCategories=a;f.onSelectBlockCallback=b;f.onDismissCallback=c;f.firstBlockIndexes=[];f.activeButtonIndex=-1;var d=f.totalNumBlocks=0;f.toolboxCategories.forEach(function(a){f.firstBlockIndexes.push(d);d+=a.blocks.length});f.firstBlockIndexes.push(d);f.totalNumBlocks=d;Blockly.CommonModal.setupKeyboardOverrides(f);f.keyboardInputService.addOverride("13",function(a){a.preventDefault();a.stopPropagation();
                +if(-1!=f.activeButtonIndex){document.getElementById(f.getOptionId(f.activeButtonIndex));for(a=0;a<f.toolboxCategories.length;a++)if(f.firstBlockIndexes[a+1]>f.activeButtonIndex){a=f.getBlock(a,f.activeButtonIndex-f.firstBlockIndexes[a]);f.selectBlock(a);return}f.dismissModal()}});setTimeout(function(){document.getElementById("toolboxModal").focus()},150)})}],hideModal_:Blockly.CommonModal.hideModal,focusOnOption:function(a){document.getElementById(this.getOptionId(a)).focus()},numInteractiveElements:function(){return this.totalNumBlocks+
                +1},getOverallIndex:function(a,b){return this.firstBlockIndexes[a]+b},getBlock:function(a,b){return this.toolboxCategories[a].blocks[b]},getBlockDescription:function(a){return this.utilsService.getBlockDescription(a)},getOptionId:function(a){return"toolbox-modal-option-"+a},getCancelOptionId:function(){return"toolbox-modal-option-"+this.totalNumBlocks},selectBlock:function(a){this.onSelectBlockCallback(a);this.hideModal_()},dismissModal:function(){this.hideModal_();this.onDismissCallback()}});blocklyApp.VariableAddModalComponent=ng.core.Component({selector:"blockly-add-variable-modal",template:'\n    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"\n         (click)="dismissModal()">\n      \x3c!-- $event.stopPropagation() prevents the modal from closing when its\n      interior is clicked. --\x3e\n      <div id="varModal" class="blocklyModal" role="alertdialog"\n           (click)="$event.stopPropagation()" tabindex="0"\n           aria-labelledby="variableModalHeading">\n          <h3 id="variableModalHeading">Add a variable...</h3>\n\n          <form id="varForm">\n            <p id="inputLabel">New Variable Name:\n              <input id="mainFieldId" type="text" [ngModel]="VALUE"\n                     (ngModelChange)="setTextValue($event)" tabindex="0"\n                     aria-labelledby="inputLabel" />\n            </p>\n            <hr>\n            <button type="button" id="submitButton" (click)="submit()">\n              SUBMIT\n            </button>\n            <button type="button" id="cancelButton" (click)="dismissModal()">\n              CANCEL\n            </button>\n          </form>\n      </div>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.AudioService,blocklyApp.KeyboardInputService,blocklyApp.VariableModalService,function(a,b,c){this.workspace=blocklyApp.workspace;this.variableModalService=c;this.audioService=a;this.keyboardInputService=b;this.modalIsVisible=!1;this.activeButtonIndex=-1;var d=this;this.variableModalService.registerPreAddShowHook(function(){d.modalIsVisible=!0;Blockly.CommonModal.setupKeyboardOverrides(d);setTimeout(function(){document.getElementById("varModal").focus()},
                +150)})}],setTextValue:function(a){this.variableName=a},hideModal_:Blockly.CommonModal.hideModal,focusOnOption:Blockly.CommonModal.focusOnOption,numInteractiveElements:Blockly.CommonModal.numInteractiveElements,getInteractiveElements:Blockly.CommonModal.getInteractiveElements,getInteractiveContainer:function(){return document.getElementById("varForm")},submit:function(){this.workspace.createVariable(this.variableName);this.dismissModal()},dismissModal:function(){this.variableModalService.hideModal();
                +this.hideModal_()}});blocklyApp.VariableRenameModalComponent=ng.core.Component({selector:"blockly-rename-variable-modal",template:'\n    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"\n         (click)="dismissModal()">\n      \x3c!-- $event.stopPropagation() prevents the modal from closing when its\n      interior is clicked. --\x3e\n      <div id="varModal" class="blocklyModal" role="alertdialog"\n           (click)="$event.stopPropagation()" tabindex="0"\n           aria-labelledby="variableModalHeading">\n          <h3 id="variableModalHeading">\n            Rename the "{{currentVariableName}}" variable...\n          </h3>\n\n          <form id="varForm">\n            <p id="inputLabel">New Variable Name:\n              <input id="mainFieldId" type="text" [ngModel]="VALUE"\n                     (ngModelChange)="setTextValue($event)" tabindex="0"\n                     aria-labelledby="inputLabel" />\n            </p>\n            <hr>\n            <button type="button" id="submitButton" (click)="submit()">\n              SUBMIT\n            </button>\n            <button type="button" id="cancelButton" (click)="dismissModal()">\n              CANCEL\n            </button>\n          </form>\n      </div>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.AudioService,blocklyApp.KeyboardInputService,blocklyApp.VariableModalService,function(a,b,c){this.workspace=blocklyApp.workspace;this.variableModalService=c;this.audioService=a;this.keyboardInputService=b;this.modalIsVisible=!1;this.activeButtonIndex=-1;this.currentVariableName="";var d=this;this.variableModalService.registerPreRenameShowHook(function(a){d.currentVariableName=a;d.modalIsVisible=!0;Blockly.CommonModal.setupKeyboardOverrides(d);
                +setTimeout(function(){document.getElementById("varModal").focus()},150)})}],setTextValue:function(a){this.variableName=a},hideModal_:Blockly.CommonModal.hideModal,focusOnOption:Blockly.CommonModal.focusOnOption,numInteractiveElements:Blockly.CommonModal.numInteractiveElements,getInteractiveElements:Blockly.CommonModal.getInteractiveElements,getInteractiveContainer:function(){return document.getElementById("varForm")},submit:function(){this.workspace.renameVariable(this.currentVariableName,this.variableName);
                +this.dismissModal()},dismissModal:function(){this.variableModalService.hideModal();this.hideModal_()}});blocklyApp.VariableRemoveModalComponent=ng.core.Component({selector:"blockly-remove-variable-modal",template:'\n    <div *ngIf="modalIsVisible"class="blocklyModalCurtain"\n         (click)="dismissModal()">\n      \x3c!-- $event.stopPropagation() prevents the modal from closing when its\n      interior is clicked. --\x3e\n      <div id="varModal" class="blocklyModal" role="alertdialog"\n           (click)="$event.stopPropagation()" tabindex="0"\n           aria-labelledby="variableModalHeading">\n          <h3 id="variableModalHeading">\n            Delete {{getNumVariables()}} uses of the "{{currentVariableName}}"\n            variable?\n          </h3>\n\n          <form id="varForm">\n            <hr>\n            <button type="button" id="yesButton" (click)="submit()">\n              YES\n            </button>\n            <button type="button" id="noButton" (click)="dismissModal()">\n              NO\n            </button>\n          </form>\n      </div>\n    </div>\n  ',
                +pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.AudioService,blocklyApp.KeyboardInputService,blocklyApp.TreeService,blocklyApp.VariableModalService,function(a,b,c,d){this.workspace=blocklyApp.workspace;this.treeService=c;this.variableModalService=d;this.audioService=a;this.keyboardInputService=b;this.modalIsVisible=!1;this.activeButtonIndex=-1;this.currentVariableName="";this.count=0;var e=this;this.variableModalService.registerPreRemoveShowHook(function(a,b){e.currentVariableName=
                +a;e.count=b;e.modalIsVisible=!0;Blockly.CommonModal.setupKeyboardOverrides(e);setTimeout(function(){document.getElementById("varModal").focus()},150)})}],hideModal_:Blockly.CommonModal.hideModal,focusOnOption:Blockly.CommonModal.focusOnOption,numInteractiveElements:Blockly.CommonModal.numInteractiveElements,getInteractiveElements:Blockly.CommonModal.getInteractiveElements,getInteractiveContainer:function(){return document.getElementById("varForm")},getNumVariables:function(){return this.variableModalService.getNumVariables(this.currentVariableName)},
                +submit:function(){var a=blocklyApp.workspace.getVariable(this.currentVariableName);blocklyApp.workspace.deleteVariableInternal_(a);this.dismissModal()},dismissModal:function(){this.variableModalService.hideModal();this.hideModal_()}});blocklyApp.FieldSegmentComponent=ng.core.Component({selector:"blockly-field-segment",template:'\n    <template [ngIf]="!mainField">\n      <label [id]="mainFieldId">{{getPrefixText()}}</label>\n    </template>\n\n    <template [ngIf]="mainField">\n      <template [ngIf]="isTextInput()">\n        {{getPrefixText()}}\n        <input [id]="mainFieldId" type="text"\n               [ngModel]="mainField.getValue()" (ngModelChange)="setTextValue($event)"\n               [attr.aria-label]="getFieldDescription() + \'. \' + (\'PRESS_ENTER_TO_EDIT_TEXT\'|translate)"\n               tabindex="-1">\n      </template>\n\n      <template [ngIf]="isNumberInput()">\n        {{getPrefixText()}}\n        <input [id]="mainFieldId" type="number"\n               [ngModel]="mainField.getValue()" (ngModelChange)="setNumberValue($event)"\n               [attr.aria-label]="getFieldDescription() + \'. \' + (\'PRESS_ENTER_TO_EDIT_NUMBER\'|translate)"\n               tabindex="-1">\n      </template>\n\n      <template [ngIf]="isDropdown()">\n        {{getPrefixText()}}\n        <select [id]="mainFieldId" [name]="mainFieldId"\n                [ngModel]="selectedOption" (ngModelChange)="setDropdownValue($event)"\n                (keydown.enter)="selectOption()"\n                tabindex="-1">\n          <option *ngFor="#option of dropdownOptions" value="{{option.value}}">\n            {{option.text}}\n          </option>\n        </select>\n      </template>\n    </template>\n  ',
                +inputs:["prefixFields","mainField","mainFieldId","level"],pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.NotificationsService,blocklyApp.VariableModalService,function(a,b){this.notificationsService=a;this.variableModalService=b;this.dropdownOptions=[];this.rawOptions=[]}],ngAfterContentInit:function(){this.mainField&&this.mainField.initModel()},ngDoCheck:function(){if(this.isDropdown()&&this.shouldBreakCache()){this.optionValue=this.mainField.getValue();this.fieldValue=this.mainField.getValue();
                +this.rawOptions=this.mainField.getOptions();this.dropdownOptions=this.rawOptions.map(function(a){return{text:a[0],value:a[1]}});for(var a=0;a<this.dropdownOptions.length;a++)this.dropdownOptions[a].text===this.fieldValue&&(this.selectedOption=this.dropdownOptions[a].value)}},shouldBreakCache:function(){var a=this.mainField.getOptions();if(a.length!=this.rawOptions.length)return!0;for(var b=0;b<this.rawOptions.length;b++)if(a[b][0]!=this.rawOptions[b][0])return!0;return this.fieldValue!=this.mainField.getValue()?
                +!0:!1},getPrefixText:function(){return this.prefixFields.map(function(a){return a.getText()}).join(" ")},getFieldDescription:function(){var a=this.mainField.getText();0<this.prefixFields.length&&(a=this.getPrefixText()+": "+a);return a},isTextInput:function(){return this.mainField instanceof Blockly.FieldTextInput&&!(this.mainField instanceof Blockly.FieldNumber)},isNumberInput:function(){return this.mainField instanceof Blockly.FieldNumber},isDropdown:function(){return this.mainField instanceof Blockly.FieldDropdown},
                +setTextValue:function(a){this.mainField.setValue(a)},setNumberValue:function(a){this.mainField.setValue(a||0)},selectOption:function(){this.optionValue!=Blockly.RENAME_VARIABLE_ID&&this.optionValue!=Blockly.DELETE_VARIABLE_ID&&this.mainField.setValue(this.optionValue);this.optionValue==Blockly.RENAME_VARIABLE_ID&&this.variableModalService.showRenameModal_(this.mainField.getValue());this.optionValue==Blockly.DELETE_VARIABLE_ID&&this.variableModalService.showRemoveModal_(this.mainField.getValue())},
                +setDropdownValue:function(a){this.optionValue=a;if("NO_ACTION"!=this.optionValue){for(var b=void 0,c=0;c<this.dropdownOptions.length;c++)if(this.dropdownOptions[c].value==a){b=this.dropdownOptions[c].text;break}if(!b)throw Error("There is no option text corresponding to the value: "+this.optionValue);this.notificationsService.speak("Selected option "+b)}}});blocklyApp.WorkspaceBlockComponent=ng.core.Component({selector:"blockly-workspace-block",template:'\n    <li [id]="componentIds.blockRoot" role="treeitem"\n        [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.blockSummary, \'blockly-translate-workspace-block\')"\n        [attr.aria-level]="level">\n      <label #blockSummaryLabel [id]="componentIds.blockSummary">{{getBlockDescription()}}</label>\n\n      <ol role="group">\n        <template ngFor #blockInput [ngForOf]="block.inputList" #i="index">\n          <li [id]="componentIds.inputs[i].inputLi" role="treeitem"\n              *ngIf="blockInput.fieldRow.length"\n              [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].fieldLabel)"\n              [attr.aria-level]="level + 1">\n            <blockly-field-segment *ngFor="#fieldSegment of inputListAsFieldSegments[i]"\n                                   [prefixFields]="fieldSegment.prefixFields"\n                                   [mainField]="fieldSegment.mainField"\n                                   [mainFieldId]="componentIds.inputs[i].fieldLabel"\n                                   [level]="level + 2">\n            </blockly-field-segment>\n          </li>\n\n          <template [ngIf]="blockInput.connection">\n            <blockly-workspace-block *ngIf="blockInput.connection.targetBlock()"\n                                     [block]="blockInput.connection.targetBlock()"\n                                     [level]="level + 1"\n                                     [tree]="tree">\n            </blockly-workspace-block>\n            <li [id]="componentIds.inputs[i].actionButtonLi" role="treeitem"\n                *ngIf="!blockInput.connection.targetBlock()"\n                [attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].buttonLabel)"\n                [attr.aria-level]="level + 1">\n              <label [id]="componentIds.inputs[i].label">\n                {{getBlockNeededLabel(blockInput)}}\n              </label>\n              <button [id]="componentIds.inputs[i].actionButton"\n                      (click)="addInteriorLink(blockInput.connection)"\n                      tabindex="-1">\n                {{\'MARK_THIS_SPOT\'|translate}}\n              </button>\n            </li>\n          </template>\n        </template>\n      </ol>\n    </li>\n\n    <blockly-workspace-block *ngIf= "block.nextConnection && block.nextConnection.targetBlock()"\n                             [block]="block.nextConnection.targetBlock()"\n                             [level]="level" [tree]="tree">\n    </blockly-workspace-block>\n  ',
                +directives:[blocklyApp.FieldSegmentComponent,ng.core.forwardRef(function(){return blocklyApp.WorkspaceBlockComponent})],inputs:["block","level","tree"],pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.AudioService,blocklyApp.BlockConnectionService,blocklyApp.TreeService,blocklyApp.UtilsService,function(a,b,c,d){this.audioService=a;this.blockConnectionService=b;this.treeService=c;this.utilsService=d;this.cachedBlockId=null}],ngDoCheck:function(){if(this.cachedBlockId!=this.block.id){this.cachedBlockId=
                +this.block.id;var a=[Blockly.FieldTextInput,Blockly.FieldDropdown];this.inputListAsFieldSegments=this.block.inputList.map(function(b){var c=[],e=[];b.fieldRow.forEach(function(b){if(a.some(function(a){return b instanceof a})){var d={prefixFields:[],mainField:b};e.forEach(function(a){d.prefixFields.push(a)});c.push(d);e=[]}else e.push(b)});e.length&&c.push({prefixFields:e,mainField:null});return c});this.componentIds={};this.componentIds.blockRoot=this.block.id+blocklyApp.BLOCK_ROOT_ID_SUFFIX;this.componentIds.blockSummary=
                +this.block.id+"-blockSummary";var b=this;this.componentIds.inputs=this.block.inputList.map(function(a,d){var c=["inputLi","fieldLabel"];a.connection&&!a.connection.targetBlock()&&c.push("actionButtonLi","actionButton","buttonLabel");var f={};c.forEach(function(a){f[a]=[b.block.id,d,a].join("-")});return f})}},ngAfterViewInit:function(){var a=this;setTimeout(function(){0!==a.level||a.treeService.getActiveDescId(a.tree.id)||a.treeService.setActiveDesc(a.componentIds.blockRoot,a.tree.id)})},addInteriorLink:function(a){this.blockConnectionService.markConnection(a)},
                +getBlockDescription:function(){var a=this.utilsService.getBlockDescription(this.block),b=this.block.getSurroundParent();return b?a+" inside "+this.utilsService.getBlockDescription(b):a},getBlockNeededLabel:function(a){return(a.connection.check_?a.connection.check_.join(", "):Blockly.Msg.ANY)+" "+(a.type==Blockly.NEXT_STATEMENT?Blockly.Msg.BLOCK:Blockly.Msg.VALUE)+" needed:"},generateAriaLabelledByAttr:function(a,b){return a+(b?" "+b:"")}});blocklyApp.WorkspaceComponent=ng.core.Component({selector:"blockly-workspace",template:'\n    <div class="blocklyWorkspaceColumn">\n      <h3 #workspaceTitle id="blockly-workspace-title">{{\'WORKSPACE\'|translate}}</h3>\n\n      <div *ngIf="workspace" class="blocklyWorkspace">\n        <ol #tree *ngFor="#topBlock of workspace.topBlocks_; #groupIndex = index"\n            [id]="tree.id || getNewTreeId()"\n            tabindex="0" role="tree" class="blocklyTree blocklyWorkspaceFocusTarget"\n            [attr.aria-activedescendant]="getActiveDescId(tree.id)"\n            [attr.aria-labelledby]="workspaceTitle.id"\n            (keydown)="onKeypress($event, tree)"\n            (focus)="speakLocation(groupIndex, tree.id)">\n          <blockly-workspace-block [level]="0" [block]="topBlock" [tree]="tree">\n          </blockly-workspace-block>\n        </ol>\n\n        <span *ngIf="workspace.topBlocks_.length === 0">\n          <p id="emptyWorkspaceBtnLabel">\n            {{\'NO_BLOCKS_IN_WORKSPACE\'|translate}}\n            <button (click)="showToolboxModalForCreateNewGroup()"\n                    class="blocklyWorkspaceFocusTarget"\n                    id="{{ID_FOR_EMPTY_WORKSPACE_BTN}}"\n                    aria-describedby="emptyWorkspaceBtnLabel">\n              {{\'CREATE_NEW_BLOCK_GROUP\'|translate}}\n            </button>\n          </p>\n        </span>\n      </div>\n    </div>\n  ',
                +directives:[blocklyApp.WorkspaceBlockComponent],pipes:[blocklyApp.TranslatePipe]}).Class({constructor:[blocklyApp.NotificationsService,blocklyApp.ToolboxModalService,blocklyApp.TreeService,function(a,b,c){this.notificationsService=a;this.toolboxModalService=b;this.treeService=c;this.ID_FOR_EMPTY_WORKSPACE_BTN=blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN;this.workspace=blocklyApp.workspace;this.currentTreeId=0}],getNewTreeId:function(){this.currentTreeId++;return"blockly-tree-"+this.currentTreeId},getActiveDescId:function(a){return this.treeService.getActiveDescId(a)},
                +onKeypress:function(a,b){this.treeService.onKeypress(a,b)},showToolboxModalForCreateNewGroup:function(){this.toolboxModalService.showToolboxModalForCreateNewGroup(this.ID_FOR_EMPTY_WORKSPACE_BTN)},speakLocation:function(a,b){this.notificationsService.speak("Now in workspace group "+(a+1)+" of "+this.workspace.topBlocks_.length)}});blocklyApp.workspace=new Blockly.Workspace;
                +blocklyApp.AppComponent=ng.core.Component({selector:"blockly-app",template:'\n    <blockly-workspace></blockly-workspace>\n    <blockly-sidebar></blockly-sidebar>\n    \x3c!-- Warning: Hiding this when there is no content looks visually nicer,\n    but it can have unexpected side effects. In particular, it sometimes stops\n    screenreaders from reading anything in this div. --\x3e\n    <div class="blocklyAriaLiveStatus">\n      <span aria-live="polite" role="status">{{getAriaLiveReadout()}}</span>\n    </div>\n\n    <blockly-add-variable-modal></blockly-add-variable-modal>\n    <blockly-rename-variable-modal></blockly-rename-variable-modal>\n    <blockly-remove-variable-modal></blockly-remove-variable-modal>\n    <blockly-toolbox-modal></blockly-toolbox-modal>\n    <blockly-block-options-modal></blockly-block-options-modal>\n\n    <label id="blockly-translate-button" aria-hidden="true" hidden>\n      {{\'BUTTON\'|translate}}\n    </label>\n    <label id="blockly-translate-workspace-block" aria-hidden="true" hidden>\n      {{\'WORKSPACE_BLOCK\'|translate}}\n    </label>\n  ',directives:[blocklyApp.BlockOptionsModalComponent,
                +blocklyApp.SidebarComponent,blocklyApp.ToolboxModalComponent,blocklyApp.VariableAddModalComponent,blocklyApp.VariableRenameModalComponent,blocklyApp.VariableRemoveModalComponent,blocklyApp.WorkspaceComponent],pipes:[blocklyApp.TranslatePipe],providers:[blocklyApp.AudioService,blocklyApp.BlockConnectionService,blocklyApp.BlockOptionsModalService,blocklyApp.KeyboardInputService,blocklyApp.NotificationsService,blocklyApp.ToolboxModalService,blocklyApp.TreeService,blocklyApp.UtilsService,blocklyApp.VariableModalService]}).Class({constructor:[blocklyApp.NotificationsService,
                +function(a){this.notificationsService=a}],getAriaLiveReadout:function(){return this.notificationsService.getDisplayedMessage()}});
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/blockly_accessible_uncompressed.js b/blockly/webif/static/blockly/blockly_accessible_uncompressed.js
                new file mode 100644
                index 000000000..918477d1a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blockly_accessible_uncompressed.js
                @@ -0,0 +1,1794 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +var isNodeJS = !!(typeof module !== 'undefined' && module.exports &&
                +                  typeof window === 'undefined');
                +
                +if (isNodeJS) {
                +  var window = {};
                +  require('closure-library');
                +}
                +
                +window.BLOCKLY_DIR = (function() {
                +  if (!isNodeJS) {
                +    // Find name of current directory.
                +    var scripts = document.getElementsByTagName('script');
                +    var re = new RegExp('(.+)[\/]blockly_(.*)uncompressed\.js$');
                +    for (var i = 0, script; script = scripts[i]; i++) {
                +      var match = re.exec(script.src);
                +      if (match) {
                +        return match[1];
                +      }
                +    }
                +    alert('Could not detect Blockly\'s directory name.');
                +  }
                +  return '';
                +})();
                +
                +window.BLOCKLY_BOOT = function() {
                +  var dir = '';
                +  if (isNodeJS) {
                +    require('closure-library');
                +    dir = 'blockly';
                +  } else {
                +    // Execute after Closure has loaded.
                +    if (!window.goog) {
                +      alert('Error: Closure not found.  Read this:\n' +
                +            'developers.google.com/blockly/guides/modify/web/closure');
                +    }
                +    dir = window.BLOCKLY_DIR.match(/[^\/]+$/)[0];
                +  }
                +goog.addDependency("../../../gblockly-rr/accessible/app.component.js", ['blocklyApp.AppComponent'], ['Blockly', 'blocklyApp.AudioService', 'blocklyApp.BlockConnectionService', 'blocklyApp.BlockOptionsModalComponent', 'blocklyApp.BlockOptionsModalService', 'blocklyApp.KeyboardInputService', 'blocklyApp.NotificationsService', 'blocklyApp.SidebarComponent', 'blocklyApp.ToolboxModalComponent', 'blocklyApp.ToolboxModalService', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService', 'blocklyApp.UtilsService', 'blocklyApp.VariableAddModalComponent', 'blocklyApp.VariableModalService', 'blocklyApp.VariableRenameModalComponent', 'blocklyApp.VariableRemoveModalComponent', 'blocklyApp.WorkspaceComponent']);
                +goog.addDependency("../../../gblockly-rr/accessible/audio.service.js", ['blocklyApp.AudioService'], ['blocklyApp.NotificationsService']);
                +goog.addDependency("../../../gblockly-rr/accessible/block-connection.service.js", ['blocklyApp.BlockConnectionService'], ['blocklyApp.AudioService', 'blocklyApp.NotificationsService']);
                +goog.addDependency("../../../gblockly-rr/accessible/block-options-modal.component.js", ['blocklyApp.BlockOptionsModalComponent'], ['blocklyApp.AudioService', 'blocklyApp.BlockOptionsModalService', 'blocklyApp.KeyboardInputService', 'blocklyApp.TranslatePipe', 'Blockly.CommonModal']);
                +goog.addDependency("../../../gblockly-rr/accessible/block-options-modal.service.js", ['blocklyApp.BlockOptionsModalService'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/commonModal.js", ['Blockly.CommonModal'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/field-segment.component.js", ['blocklyApp.FieldSegmentComponent'], ['blocklyApp.NotificationsService', 'blocklyApp.TranslatePipe', 'blocklyApp.VariableModalService']);
                +goog.addDependency("../../../gblockly-rr/accessible/keyboard-input.service.js", ['blocklyApp.KeyboardInputService'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/libs/Rx.umd.min.js", [], []);
                +goog.addDependency("../../../gblockly-rr/accessible/libs/angular2-all.umd.min.js", [], []);
                +goog.addDependency("../../../gblockly-rr/accessible/libs/angular2-polyfills.min.js", [], []);
                +goog.addDependency("../../../gblockly-rr/accessible/libs/es6-shim.min.js", [], []);
                +goog.addDependency("../../../gblockly-rr/accessible/messages.js", [], []);
                +goog.addDependency("../../../gblockly-rr/accessible/notifications.service.js", ['blocklyApp.NotificationsService'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/sidebar.component.js", ['blocklyApp.SidebarComponent'], ['blocklyApp.UtilsService', 'blocklyApp.BlockConnectionService', 'blocklyApp.ToolboxModalService', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService', 'blocklyApp.VariableModalService']);
                +goog.addDependency("../../../gblockly-rr/accessible/toolbox-modal.component.js", ['blocklyApp.ToolboxModalComponent'], ['Blockly.CommonModal', 'blocklyApp.AudioService', 'blocklyApp.KeyboardInputService', 'blocklyApp.ToolboxModalService', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService', 'blocklyApp.UtilsService']);
                +goog.addDependency("../../../gblockly-rr/accessible/toolbox-modal.service.js", ['blocklyApp.ToolboxModalService'], ['blocklyApp.UtilsService', 'blocklyApp.BlockConnectionService', 'blocklyApp.NotificationsService', 'blocklyApp.TreeService']);
                +goog.addDependency("../../../gblockly-rr/accessible/translate.pipe.js", ['blocklyApp.TranslatePipe'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/tree.service.js", ['blocklyApp.TreeService'], ['blocklyApp.UtilsService', 'blocklyApp.AudioService', 'blocklyApp.BlockConnectionService', 'blocklyApp.BlockOptionsModalService', 'blocklyApp.NotificationsService', 'blocklyApp.VariableModalService']);
                +goog.addDependency("../../../gblockly-rr/accessible/utils.service.js", ['blocklyApp.UtilsService'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/variable-add-modal.component.js", ['blocklyApp.VariableAddModalComponent'], ['blocklyApp.AudioService', 'blocklyApp.KeyboardInputService', 'blocklyApp.TranslatePipe', 'blocklyApp.VariableModalService', 'Blockly.CommonModal']);
                +goog.addDependency("../../../gblockly-rr/accessible/variable-modal.service.js", ['blocklyApp.VariableModalService'], []);
                +goog.addDependency("../../../gblockly-rr/accessible/variable-remove-modal.component.js", ['blocklyApp.VariableRemoveModalComponent'], ['blocklyApp.AudioService', 'blocklyApp.KeyboardInputService', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService', 'blocklyApp.VariableModalService', 'Blockly.CommonModal']);
                +goog.addDependency("../../../gblockly-rr/accessible/variable-rename-modal.component.js", ['blocklyApp.VariableRenameModalComponent'], ['Blockly.CommonModal', 'blocklyApp.AudioService', 'blocklyApp.KeyboardInputService', 'blocklyApp.TranslatePipe', 'blocklyApp.VariableModalService']);
                +goog.addDependency("../../../gblockly-rr/accessible/workspace-block.component.js", ['blocklyApp.WorkspaceBlockComponent'], ['blocklyApp.UtilsService', 'blocklyApp.AudioService', 'blocklyApp.BlockConnectionService', 'blocklyApp.FieldSegmentComponent', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService']);
                +goog.addDependency("../../../gblockly-rr/accessible/workspace.component.js", ['blocklyApp.WorkspaceComponent'], ['blocklyApp.NotificationsService', 'blocklyApp.ToolboxModalService', 'blocklyApp.TranslatePipe', 'blocklyApp.TreeService', 'blocklyApp.WorkspaceBlockComponent']);
                +goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Mutator', 'Blockly.Warning', 'Blockly.Workspace', 'Blockly.Xml', 'goog.array', 'goog.asserts', 'goog.math.Coordinate', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/block_drag_surface.js", ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/block_dragger.js", ['Blockly.BlockDragger'], ['Blockly.DraggedConnectionManager', 'goog.math.Coordinate', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/block_render_svg.js", ['Blockly.BlockSvg.render'], ['Blockly.BlockSvg', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['Blockly.Block', 'Blockly.ContextMenu', 'Blockly.Grid', 'Blockly.RenderedConnection', 'Blockly.Touch', 'Blockly.utils', 'goog.Timer', 'goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/blockly.js", ['Blockly'], ['Blockly.BlockSvg.render', 'Blockly.Events', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldTextInput', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.Generator', 'Blockly.Msg', 'Blockly.Procedures', 'Blockly.Toolbox', 'Blockly.Touch', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.constants', 'Blockly.inject', 'Blockly.utils', 'goog.color', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/blocks.js", ['Blockly.Blocks'], []);
                +goog.addDependency("../../../" + dir + "/core/bubble.js", ['Blockly.Bubble'], ['Blockly.Touch', 'Blockly.Workspace', 'goog.dom', 'goog.math', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/comment.js", ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Icon', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/connection.js", ['Blockly.Connection'], ['goog.asserts', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/connection_db.js", ['Blockly.ConnectionDB'], ['Blockly.Connection']);
                +goog.addDependency("../../../" + dir + "/core/constants.js", ['Blockly.constants'], []);
                +goog.addDependency("../../../" + dir + "/core/contextmenu.js", ['Blockly.ContextMenu'], ['goog.dom', 'goog.events', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItem']);
                +goog.addDependency("../../../" + dir + "/core/css.js", ['Blockly.Css'], []);
                +goog.addDependency("../../../" + dir + "/core/dragged_connection_manager.js", ['Blockly.DraggedConnectionManager'], ['Blockly.RenderedConnection', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/events.js", ['Blockly.Events'], ['goog.array', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/extensions.js", ['Blockly.Extensions'], []);
                +goog.addDependency("../../../" + dir + "/core/field.js", ['Blockly.Field'], ['Blockly.Gesture', 'goog.asserts', 'goog.dom', 'goog.math.Size', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_angle.js", ['Blockly.FieldAngle'], ['Blockly.FieldTextInput', 'goog.math', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_checkbox.js", ['Blockly.FieldCheckbox'], ['Blockly.Field']);
                +goog.addDependency("../../../" + dir + "/core/field_colour.js", ['Blockly.FieldColour'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.ColorPicker']);
                +goog.addDependency("../../../" + dir + "/core/field_date.js", ['Blockly.FieldDate'], ['Blockly.Field', 'goog.date', 'goog.dom', 'goog.events', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_he', 'goog.style', 'goog.ui.DatePicker']);
                +goog.addDependency("../../../" + dir + "/core/field_dropdown.js", ['Blockly.FieldDropdown'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_image.js", ['Blockly.FieldImage'], ['Blockly.Field', 'goog.dom', 'goog.math.Size', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_label.js", ['Blockly.FieldLabel'], ['Blockly.Field', 'Blockly.Tooltip', 'goog.dom', 'goog.math.Size']);
                +goog.addDependency("../../../" + dir + "/core/field_number.js", ['Blockly.FieldNumber'], ['Blockly.FieldTextInput', 'goog.math']);
                +goog.addDependency("../../../" + dir + "/core/field_textinput.js", ['Blockly.FieldTextInput'], ['Blockly.Field', 'Blockly.Msg', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_variable.js", ['Blockly.FieldVariable'], ['Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.VariableModel', 'goog.asserts', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/flyout_base.js", ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.FlyoutButton', 'Blockly.Gesture', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/flyout_button.js", ['Blockly.FlyoutButton'], ['goog.dom', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/flyout_dragger.js", ['Blockly.FlyoutDragger'], ['Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/flyout_horizontal.js", ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.FlyoutButton', 'Blockly.Flyout', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/flyout_vertical.js", ['Blockly.VerticalFlyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.Flyout', 'Blockly.FlyoutButton', 'Blockly.utils', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/generator.js", ['Blockly.Generator'], ['Blockly.Block', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/gesture.js", ['Blockly.Gesture'], ['Blockly.BlockDragger', 'Blockly.constants', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/grid.js", ['Blockly.Grid'], ['Blockly.utils', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/icon.js", ['Blockly.Icon'], ['goog.dom', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.Grid', 'Blockly.Options', 'Blockly.WorkspaceSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'goog.dom', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/input.js", ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/msg.js", ['Blockly.Msg'], []);
                +goog.addDependency("../../../" + dir + "/core/mutator.js", ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'goog.Timer', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/names.js", ['Blockly.Names'], []);
                +goog.addDependency("../../../" + dir + "/core/options.js", ['Blockly.Options'], []);
                +goog.addDependency("../../../" + dir + "/core/procedures.js", ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.Field', 'Blockly.Names', 'Blockly.Workspace']);
                +goog.addDependency("../../../" + dir + "/core/rendered_connection.js", ['Blockly.RenderedConnection'], ['Blockly.Connection']);
                +goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['goog.dom', 'goog.events']);
                +goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Flyout', 'Blockly.HorizontalFlyout', 'Blockly.Touch', 'Blockly.VerticalFlyout', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserFeature', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.math.Rect', 'goog.style', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']);
                +goog.addDependency("../../../" + dir + "/core/tooltip.js", ['Blockly.Tooltip'], ['goog.dom', 'goog.dom.TagName']);
                +goog.addDependency("../../../" + dir + "/core/touch.js", ['Blockly.Touch'], ['goog.events', 'goog.events.BrowserFeature', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/trashcan.js", ['Blockly.Trashcan'], ['goog.Timer', 'goog.dom', 'goog.math', 'goog.math.Rect']);
                +goog.addDependency("../../../" + dir + "/core/utils.js", ['Blockly.utils'], ['Blockly.Touch', 'goog.dom', 'goog.events.BrowserFeature', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/variable_map.js", ['Blockly.VariableMap'], []);
                +goog.addDependency("../../../" + dir + "/core/variable_model.js", ['Blockly.VariableModel'], ['goog.string']);
                +goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.VariableModel', 'Blockly.Workspace', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/warning.js", ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Icon']);
                +goog.addDependency("../../../" + dir + "/core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.Css', 'goog.dom', 'goog.dom.TagName', 'goog.style']);
                +goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.VariableMap', 'goog.array', 'goog.math']);
                +goog.addDependency("../../../" + dir + "/core/workspace_audio.js", ['Blockly.WorkspaceAudio'], []);
                +goog.addDependency("../../../" + dir + "/core/workspace_drag_surface_svg.js", ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/workspace_dragger.js", ['Blockly.WorkspaceDragger'], ['goog.math.Coordinate', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.constants', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Touch', 'Blockly.Trashcan', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'goog.array', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], ['goog.asserts', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/zoom_controls.js", ['Blockly.ZoomControls'], ['Blockly.Touch', 'goog.dom']);
                +goog.addDependency("../../alltests.js", [], []);
                +goog.addDependency("../../browser_capabilities.js", [], []);
                +goog.addDependency("../../doc/js/article.js", [], []);
                +goog.addDependency("../../protractor.conf.js", [], []);
                +goog.addDependency("../../protractor_spec.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/base.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/caja/string/html/htmlparser.js", ['goog.string.html', 'goog.string.html.HtmlParser', 'goog.string.html.HtmlParser.EFlags', 'goog.string.html.HtmlParser.Elements', 'goog.string.html.HtmlParser.Entities', 'goog.string.html.HtmlSaxHandler'], []);
                +goog.addDependency("../../third_party/closure/goog/caja/string/html/htmlsanitizer.js", ['goog.string.html.HtmlSanitizer', 'goog.string.html.HtmlSanitizer.AttributeType', 'goog.string.html.HtmlSanitizer.Attributes', 'goog.string.html.htmlSanitize'], ['goog.string.StringBuffer', 'goog.string.html.HtmlParser', 'goog.string.html.HtmlSaxHandler']);
                +goog.addDependency("../../third_party/closure/goog/deps.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/dojo/dom/query.js", ['goog.dom.query'], ['goog.array', 'goog.dom', 'goog.functions', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("../../third_party/closure/goog/dojo/dom/query_test.js", [], ['goog.dom', 'goog.dom.query', 'goog.userAgent']);
                +goog.addDependency("../../third_party/closure/goog/loremipsum/text/loremipsum.js", ['goog.text.LoremIpsum'], ['goog.array', 'goog.math', 'goog.string', 'goog.structs.Map', 'goog.structs.Set']);
                +goog.addDependency("../../third_party/closure/goog/mochikit/async/deferred.js", ['goog.async.Deferred', 'goog.async.Deferred.AlreadyCalledError', 'goog.async.Deferred.CanceledError'], ['goog.Promise', 'goog.Thenable', 'goog.array', 'goog.asserts', 'goog.debug.Error']);
                +goog.addDependency("../../third_party/closure/goog/mochikit/async/deferredlist.js", ['goog.async.DeferredList'], ['goog.async.Deferred']);
                +goog.addDependency("../../third_party/closure/goog/svgpan/svgpan.js", ['svgpan.SvgPan'], ['goog.Disposable', 'goog.events', 'goog.events.EventType', 'goog.events.MouseWheelHandler']);
                +goog.addDependency("a11y/aria/announcer.js", ['goog.a11y.aria.Announcer'], ['goog.Disposable', 'goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.object']);
                +goog.addDependency("a11y/aria/announcer_test.js", ['goog.a11y.aria.AnnouncerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Announcer', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.iframe', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("a11y/aria/aria.js", ['goog.a11y.aria'], ['goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.a11y.aria.datatables', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.object', 'goog.string']);
                +goog.addDependency("a11y/aria/aria_test.js", ['goog.a11y.ariaTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("a11y/aria/attributes.js", ['goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.CheckedValues', 'goog.a11y.aria.DropEffectValues', 'goog.a11y.aria.ExpandedValues', 'goog.a11y.aria.GrabbedValues', 'goog.a11y.aria.InvalidValues', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.OrientationValues', 'goog.a11y.aria.PressedValues', 'goog.a11y.aria.RelevantValues', 'goog.a11y.aria.SelectedValues', 'goog.a11y.aria.SortValues', 'goog.a11y.aria.State'], []);
                +goog.addDependency("a11y/aria/datatables.js", ['goog.a11y.aria.datatables'], ['goog.a11y.aria.State', 'goog.object']);
                +goog.addDependency("a11y/aria/roles.js", ['goog.a11y.aria.Role'], []);
                +goog.addDependency("array/array.js", ['goog.array'], ['goog.asserts']);
                +goog.addDependency("array/array_test.js", ['goog.arrayTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("asserts/asserts.js", ['goog.asserts', 'goog.asserts.AssertionError'], ['goog.debug.Error', 'goog.dom.NodeType', 'goog.string']);
                +goog.addDependency("asserts/asserts_test.js", ['goog.assertsTest'], ['goog.asserts', 'goog.asserts.AssertionError', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.string', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("async/animationdelay.js", ['goog.async.AnimationDelay'], ['goog.Disposable', 'goog.events', 'goog.functions']);
                +goog.addDependency("async/animationdelay_test.js", [], []);
                +goog.addDependency("async/conditionaldelay.js", ['goog.async.ConditionalDelay'], ['goog.Disposable', 'goog.async.Delay']);
                +goog.addDependency("async/conditionaldelay_test.js", ['goog.async.ConditionalDelayTest'], ['goog.async.ConditionalDelay', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/debouncer.js", ['goog.async.Debouncer'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/debouncer_test.js", ['goog.async.DebouncerTest'], ['goog.array', 'goog.async.Debouncer', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("async/delay.js", ['goog.Delay', 'goog.async.Delay'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/delay_test.js", ['goog.async.DelayTest'], ['goog.async.Delay', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/freelist.js", ['goog.async.FreeList'], []);
                +goog.addDependency("async/freelist_test.js", ['goog.async.FreeListTest'], ['goog.async.FreeList', 'goog.testing.jsunit']);
                +goog.addDependency("async/nexttick.js", ['goog.async.nextTick', 'goog.async.throwException'], ['goog.debug.entryPointRegistry', 'goog.dom.TagName', 'goog.functions', 'goog.labs.userAgent.browser', 'goog.labs.userAgent.engine']);
                +goog.addDependency("async/nexttick_test.js", ['goog.async.nextTickTest'], ['goog.Promise', 'goog.Timer', 'goog.async.nextTick', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("async/run.js", ['goog.async.run'], ['goog.async.WorkQueue', 'goog.async.nextTick', 'goog.async.throwException']);
                +goog.addDependency("async/run_test.js", ['goog.async.runTest'], ['goog.async.run', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("async/throttle.js", ['goog.Throttle', 'goog.async.Throttle'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/throttle_test.js", ['goog.async.ThrottleTest'], ['goog.async.Throttle', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/workqueue.js", ['goog.async.WorkItem', 'goog.async.WorkQueue'], ['goog.asserts', 'goog.async.FreeList']);
                +goog.addDependency("async/workqueue_test.js", ['goog.async.WorkQueueTest'], ['goog.async.WorkQueue', 'goog.testing.jsunit']);
                +goog.addDependency("base.js", [], []);
                +goog.addDependency("base_module_test.js", [], []);
                +goog.addDependency("base_test.js", ['goog.baseTest'], ['goog.Promise', 'goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.object', 'goog.test_module', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("bootstrap/nodejs.js", [], []);
                +goog.addDependency("bootstrap/webworkers.js", [], []);
                +goog.addDependency("color/alpha.js", ['goog.color.alpha'], ['goog.color']);
                +goog.addDependency("color/alpha_test.js", ['goog.color.alphaTest'], ['goog.array', 'goog.color', 'goog.color.alpha', 'goog.testing.jsunit']);
                +goog.addDependency("color/color.js", ['goog.color', 'goog.color.Hsl', 'goog.color.Hsv', 'goog.color.Rgb'], ['goog.color.names', 'goog.math']);
                +goog.addDependency("color/color_test.js", ['goog.colorTest'], ['goog.array', 'goog.color', 'goog.color.names', 'goog.testing.jsunit']);
                +goog.addDependency("color/names.js", ['goog.color.names'], []);
                +goog.addDependency("crypt/aes.js", ['goog.crypt.Aes'], ['goog.asserts', 'goog.crypt.BlockCipher']);
                +goog.addDependency("crypt/aes_test.js", ['goog.crypt.AesTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/arc4.js", ['goog.crypt.Arc4'], ['goog.asserts']);
                +goog.addDependency("crypt/arc4_test.js", ['goog.crypt.Arc4Test'], ['goog.array', 'goog.crypt.Arc4', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/base64.js", ['goog.crypt.base64'], ['goog.asserts', 'goog.crypt', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("crypt/base64_test.js", ['goog.crypt.base64Test'], ['goog.crypt', 'goog.crypt.base64', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/basen.js", ['goog.crypt.baseN'], []);
                +goog.addDependency("crypt/basen_test.js", ['goog.crypt.baseNTest'], ['goog.crypt.baseN', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/blobhasher.js", ['goog.crypt.BlobHasher', 'goog.crypt.BlobHasher.EventType'], ['goog.asserts', 'goog.events.EventTarget', 'goog.fs', 'goog.log']);
                +goog.addDependency("crypt/blobhasher_test.js", ['goog.crypt.BlobHasherTest'], ['goog.crypt', 'goog.crypt.BlobHasher', 'goog.crypt.Md5', 'goog.events', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/blockcipher.js", ['goog.crypt.BlockCipher'], []);
                +goog.addDependency("crypt/bytestring_perf.js", ['goog.crypt.byteArrayToStringPerf'], ['goog.array', 'goog.dom', 'goog.testing.PerformanceTable']);
                +goog.addDependency("crypt/cbc.js", ['goog.crypt.Cbc'], ['goog.array', 'goog.asserts', 'goog.crypt']);
                +goog.addDependency("crypt/cbc_test.js", ['goog.crypt.CbcTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.crypt.Cbc', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/crypt.js", ['goog.crypt'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("crypt/crypt_test.js", ['goog.cryptTest'], ['goog.crypt', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/ctr.js", ['goog.crypt.Ctr'], ['goog.array', 'goog.asserts', 'goog.crypt']);
                +goog.addDependency("crypt/ctr_test.js", ['goog.crypt.CtrTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.crypt.Ctr', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/hash.js", ['goog.crypt.Hash'], []);
                +goog.addDependency("crypt/hash32.js", ['goog.crypt.hash32'], ['goog.crypt']);
                +goog.addDependency("crypt/hash32_test.js", ['goog.crypt.hash32Test'], ['goog.crypt.hash32', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/hashtester.js", ['goog.crypt.hashTester'], ['goog.array', 'goog.crypt', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTable', 'goog.testing.PseudoRandom', 'goog.testing.asserts']);
                +goog.addDependency("crypt/hmac.js", ['goog.crypt.Hmac'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/hmac_test.js", ['goog.crypt.HmacTest'], ['goog.crypt.Hmac', 'goog.crypt.Sha1', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/md5.js", ['goog.crypt.Md5'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/md5_test.js", ['goog.crypt.Md5Test'], ['goog.crypt', 'goog.crypt.Md5', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/pbkdf2.js", ['goog.crypt.pbkdf2'], ['goog.array', 'goog.asserts', 'goog.crypt', 'goog.crypt.Hmac', 'goog.crypt.Sha1']);
                +goog.addDependency("crypt/pbkdf2_test.js", ['goog.crypt.pbkdf2Test'], ['goog.crypt', 'goog.crypt.pbkdf2', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha1.js", ['goog.crypt.Sha1'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/sha1_test.js", ['goog.crypt.Sha1Test'], ['goog.crypt', 'goog.crypt.Sha1', 'goog.crypt.hashTester', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha2.js", ['goog.crypt.Sha2'], ['goog.array', 'goog.asserts', 'goog.crypt.Hash']);
                +goog.addDependency("crypt/sha224.js", ['goog.crypt.Sha224'], ['goog.crypt.Sha2']);
                +goog.addDependency("crypt/sha224_test.js", ['goog.crypt.Sha224Test'], ['goog.crypt', 'goog.crypt.Sha224', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/sha256.js", ['goog.crypt.Sha256'], ['goog.crypt.Sha2']);
                +goog.addDependency("crypt/sha256_test.js", ['goog.crypt.Sha256Test'], ['goog.crypt', 'goog.crypt.Sha256', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/sha2_64bit.js", ['goog.crypt.Sha2_64bit'], ['goog.array', 'goog.asserts', 'goog.crypt.Hash', 'goog.math.Long']);
                +goog.addDependency("crypt/sha2_64bit_test.js", ['goog.crypt.Sha2_64bit_test'], ['goog.array', 'goog.crypt', 'goog.crypt.Sha384', 'goog.crypt.Sha512', 'goog.crypt.Sha512_256', 'goog.crypt.hashTester', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha384.js", ['goog.crypt.Sha384'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("crypt/sha512.js", ['goog.crypt.Sha512'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("crypt/sha512_256.js", ['goog.crypt.Sha512_256'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("cssom/cssom.js", ['goog.cssom', 'goog.cssom.CssRuleType'], ['goog.array', 'goog.dom', 'goog.dom.TagName']);
                +goog.addDependency("cssom/cssom_test.js", ['goog.cssomTest'], ['goog.array', 'goog.cssom', 'goog.cssom.CssRuleType', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("cssom/iframe/style.js", ['goog.cssom.iframe.style'], ['goog.asserts', 'goog.cssom', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("cssom/iframe/style_test.js", ['goog.cssom.iframe.styleTest'], ['goog.cssom', 'goog.cssom.iframe.style', 'goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("datasource/datamanager.js", ['goog.ds.DataManager'], ['goog.ds.BasicNodeList', 'goog.ds.DataNode', 'goog.ds.Expr', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.Map']);
                +goog.addDependency("datasource/datasource.js", ['goog.ds.BaseDataNode', 'goog.ds.BasicNodeList', 'goog.ds.DataNode', 'goog.ds.DataNodeList', 'goog.ds.EmptyNodeList', 'goog.ds.LoadState', 'goog.ds.SortedNodeList', 'goog.ds.Util', 'goog.ds.logger'], ['goog.array', 'goog.log']);
                +goog.addDependency("datasource/datasource_test.js", ['goog.ds.JsDataSourceTest'], ['goog.dom.xml', 'goog.ds.DataManager', 'goog.ds.JsDataSource', 'goog.ds.SortedNodeList', 'goog.ds.XmlDataSource', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/expr.js", ['goog.ds.Expr'], ['goog.ds.BasicNodeList', 'goog.ds.EmptyNodeList', 'goog.string']);
                +goog.addDependency("datasource/expr_test.js", ['goog.ds.ExprTest'], ['goog.ds.DataManager', 'goog.ds.Expr', 'goog.ds.JsDataSource', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/fastdatanode.js", ['goog.ds.AbstractFastDataNode', 'goog.ds.FastDataNode', 'goog.ds.FastListNode', 'goog.ds.PrimitiveFastDataNode'], ['goog.ds.DataManager', 'goog.ds.DataNodeList', 'goog.ds.EmptyNodeList', 'goog.string']);
                +goog.addDependency("datasource/fastdatanode_test.js", ['goog.ds.FastDataNodeTest'], ['goog.array', 'goog.ds.DataManager', 'goog.ds.Expr', 'goog.ds.FastDataNode', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/jsdatasource.js", ['goog.ds.JsDataSource', 'goog.ds.JsPropertyDataSource'], ['goog.ds.BaseDataNode', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.EmptyNodeList', 'goog.ds.LoadState']);
                +goog.addDependency("datasource/jsondatasource.js", ['goog.ds.JsonDataSource'], ['goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.ds.DataManager', 'goog.ds.JsDataSource', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log']);
                +goog.addDependency("datasource/jsxmlhttpdatasource.js", ['goog.ds.JsXmlHttpDataSource'], ['goog.Uri', 'goog.ds.DataManager', 'goog.ds.FastDataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.events', 'goog.json', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("datasource/jsxmlhttpdatasource_test.js", ['goog.ds.JsXmlHttpDataSourceTest'], ['goog.ds.JsXmlHttpDataSource', 'goog.testing.TestQueue', 'goog.testing.jsunit', 'goog.testing.net.XhrIo']);
                +goog.addDependency("datasource/xmldatasource.js", ['goog.ds.XmlDataSource', 'goog.ds.XmlHttpDataSource'], ['goog.Uri', 'goog.dom.NodeType', 'goog.dom.xml', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log', 'goog.net.XhrIo', 'goog.string']);
                +goog.addDependency("date/date.js", ['goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval', 'goog.date.month', 'goog.date.weekDay'], ['goog.asserts', 'goog.date.DateLike', 'goog.i18n.DateTimeSymbols', 'goog.string']);
                +goog.addDependency("date/date_test.js", ['goog.dateTest'], ['goog.array', 'goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval', 'goog.date.month', 'goog.date.weekDay', 'goog.i18n.DateTimeSymbols', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.platform', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("date/datelike.js", ['goog.date.DateLike'], []);
                +goog.addDependency("date/daterange.js", ['goog.date.DateRange', 'goog.date.DateRange.Iterator', 'goog.date.DateRange.StandardDateRangeKeys'], ['goog.date.Date', 'goog.date.Interval', 'goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("date/daterange_test.js", ['goog.date.DateRangeTest'], ['goog.date.Date', 'goog.date.DateRange', 'goog.date.Interval', 'goog.i18n.DateTimeSymbols', 'goog.testing.jsunit']);
                +goog.addDependency("date/duration.js", ['goog.date.duration'], ['goog.i18n.DateTimeFormat', 'goog.i18n.MessageFormat']);
                +goog.addDependency("date/duration_test.js", ['goog.date.durationTest'], ['goog.date.duration', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.testing.jsunit']);
                +goog.addDependency("date/relative.js", ['goog.date.relative', 'goog.date.relative.TimeDeltaFormatter', 'goog.date.relative.Unit'], ['goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns']);
                +goog.addDependency("date/relative_test.js", ['goog.date.relativeTest'], ['goog.date.DateTime', 'goog.date.relative', 'goog.i18n.DateTimeFormat', 'goog.testing.jsunit']);
                +goog.addDependency("date/relativewithplurals.js", ['goog.date.relativeWithPlurals'], ['goog.date.relative', 'goog.date.relative.Unit', 'goog.i18n.MessageFormat']);
                +goog.addDependency("date/relativewithplurals_test.js", ['goog.date.relativeWithPluralsTest'], ['goog.date.relative', 'goog.date.relativeTest', 'goog.date.relativeWithPlurals', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_bn', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_fa']);
                +goog.addDependency("date/utcdatetime.js", ['goog.date.UtcDateTime'], ['goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval']);
                +goog.addDependency("date/utcdatetime_test.js", ['goog.date.UtcDateTimeTest'], ['goog.date.Interval', 'goog.date.UtcDateTime', 'goog.date.month', 'goog.date.weekDay', 'goog.testing.jsunit']);
                +goog.addDependency("db/cursor.js", ['goog.db.Cursor'], ['goog.async.Deferred', 'goog.db.Error', 'goog.db.KeyRange', 'goog.debug', 'goog.events.EventTarget']);
                +goog.addDependency("db/db.js", ['goog.db', 'goog.db.BlockedCallback', 'goog.db.UpgradeNeededCallback'], ['goog.asserts', 'goog.async.Deferred', 'goog.db.Error', 'goog.db.IndexedDb', 'goog.db.Transaction']);
                +goog.addDependency("db/db_test.js", ['goog.dbTest'], ['goog.Disposable', 'goog.Promise', 'goog.array', 'goog.db', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.IndexedDb', 'goog.db.KeyRange', 'goog.db.Transaction', 'goog.events', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent.product']);
                +goog.addDependency("db/error.js", ['goog.db.DomErrorLike', 'goog.db.Error', 'goog.db.Error.ErrorCode', 'goog.db.Error.ErrorName', 'goog.db.Error.VersionChangeBlockedError'], ['goog.debug.Error']);
                +goog.addDependency("db/index.js", ['goog.db.Index'], ['goog.async.Deferred', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.KeyRange', 'goog.debug']);
                +goog.addDependency("db/indexeddb.js", ['goog.db.IndexedDb'], ['goog.db.Error', 'goog.db.ObjectStore', 'goog.db.Transaction', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget']);
                +goog.addDependency("db/keyrange.js", ['goog.db.KeyRange'], []);
                +goog.addDependency("db/objectstore.js", ['goog.db.ObjectStore'], ['goog.async.Deferred', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.Index', 'goog.db.KeyRange', 'goog.debug', 'goog.events']);
                +goog.addDependency("db/transaction.js", ['goog.db.Transaction', 'goog.db.Transaction.TransactionMode'], ['goog.async.Deferred', 'goog.db.Error', 'goog.db.ObjectStore', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget']);
                +goog.addDependency("debug/console.js", ['goog.debug.Console'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.debug.TextFormatter']);
                +goog.addDependency("debug/console_test.js", ['goog.debug.ConsoleTest'], ['goog.debug.Console', 'goog.debug.LogRecord', 'goog.debug.Logger', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("debug/debug.js", ['goog.debug'], ['goog.array', 'goog.structs.Set', 'goog.userAgent']);
                +goog.addDependency("debug/debug_test.js", ['goog.debugTest'], ['goog.debug', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("debug/debugwindow.js", ['goog.debug.DebugWindow'], ['goog.debug.HtmlFormatter', 'goog.debug.LogManager', 'goog.debug.Logger', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.string.Const', 'goog.structs.CircularBuffer', 'goog.userAgent']);
                +goog.addDependency("debug/debugwindow_test.js", ['goog.debug.DebugWindowTest'], ['goog.debug.DebugWindow', 'goog.testing.jsunit']);
                +goog.addDependency("debug/devcss/devcss.js", ['goog.debug.DevCss', 'goog.debug.DevCss.UserAgent'], ['goog.asserts', 'goog.cssom', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("debug/devcss/devcss_test.js", ['goog.debug.DevCssTest'], ['goog.debug.DevCss', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("debug/devcss/devcssrunner.js", ['goog.debug.devCssRunner'], ['goog.debug.DevCss']);
                +goog.addDependency("debug/divconsole.js", ['goog.debug.DivConsole'], ['goog.debug.HtmlFormatter', 'goog.debug.LogManager', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.string.Const', 'goog.style']);
                +goog.addDependency("debug/enhanceerror_test.js", ['goog.debugEnhanceErrorTest'], ['goog.debug', 'goog.testing.jsunit']);
                +goog.addDependency("debug/entrypointregistry.js", ['goog.debug.EntryPointMonitor', 'goog.debug.entryPointRegistry'], ['goog.asserts']);
                +goog.addDependency("debug/entrypointregistry_test.js", ['goog.debug.entryPointRegistryTest'], ['goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.testing.jsunit']);
                +goog.addDependency("debug/error.js", ['goog.debug.Error'], []);
                +goog.addDependency("debug/error_test.js", ['goog.debug.ErrorTest'], ['goog.debug.Error', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("debug/errorhandler.js", ['goog.debug.ErrorHandler', 'goog.debug.ErrorHandler.ProtectedFunctionError'], ['goog.Disposable', 'goog.asserts', 'goog.debug', 'goog.debug.EntryPointMonitor', 'goog.debug.Error', 'goog.debug.Trace']);
                +goog.addDependency("debug/errorhandler_async_test.js", ['goog.debug.ErrorHandlerAsyncTest'], ['goog.Promise', 'goog.debug.ErrorHandler', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("debug/errorhandler_test.js", ['goog.debug.ErrorHandlerTest'], ['goog.debug.ErrorHandler', 'goog.testing.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("debug/errorhandlerweakdep.js", ['goog.debug.errorHandlerWeakDep'], []);
                +goog.addDependency("debug/errorreporter.js", ['goog.debug.ErrorReporter', 'goog.debug.ErrorReporter.ExceptionEvent'], ['goog.asserts', 'goog.debug', 'goog.debug.Error', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.log', 'goog.net.XhrIo', 'goog.object', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("debug/errorreporter_test.js", ['goog.debug.ErrorReporterTest'], ['goog.debug.Error', 'goog.debug.ErrorReporter', 'goog.events', 'goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("debug/fancywindow.js", ['goog.debug.FancyWindow'], ['goog.array', 'goog.asserts', 'goog.debug.DebugWindow', 'goog.debug.LogManager', 'goog.debug.Logger', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("debug/formatter.js", ['goog.debug.Formatter', 'goog.debug.HtmlFormatter', 'goog.debug.TextFormatter'], ['goog.debug', 'goog.debug.Logger', 'goog.debug.RelativeTimeProvider', 'goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.string.Const']);
                +goog.addDependency("debug/formatter_test.js", ['goog.debug.FormatterTest'], ['goog.debug.HtmlFormatter', 'goog.debug.LogRecord', 'goog.debug.Logger', 'goog.html.SafeHtml', 'goog.testing.jsunit']);
                +goog.addDependency("debug/fpsdisplay.js", ['goog.debug.FpsDisplay'], ['goog.asserts', 'goog.async.AnimationDelay', 'goog.dom', 'goog.dom.TagName', 'goog.ui.Component']);
                +goog.addDependency("debug/fpsdisplay_test.js", ['goog.debug.FpsDisplayTest'], ['goog.Timer', 'goog.debug.FpsDisplay', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logbuffer.js", ['goog.debug.LogBuffer'], ['goog.asserts', 'goog.debug.LogRecord']);
                +goog.addDependency("debug/logbuffer_test.js", ['goog.debug.LogBufferTest'], ['goog.debug.LogBuffer', 'goog.debug.Logger', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logger.js", ['goog.debug.LogManager', 'goog.debug.Loggable', 'goog.debug.Logger', 'goog.debug.Logger.Level'], ['goog.array', 'goog.asserts', 'goog.debug', 'goog.debug.LogBuffer', 'goog.debug.LogRecord']);
                +goog.addDependency("debug/logger_test.js", ['goog.debug.LoggerTest'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logrecord.js", ['goog.debug.LogRecord'], []);
                +goog.addDependency("debug/logrecordserializer.js", ['goog.debug.logRecordSerializer'], ['goog.debug.LogRecord', 'goog.debug.Logger', 'goog.json', 'goog.object']);
                +goog.addDependency("debug/logrecordserializer_test.js", ['goog.debug.logRecordSerializerTest'], ['goog.debug.LogRecord', 'goog.debug.Logger', 'goog.debug.logRecordSerializer', 'goog.testing.jsunit']);
                +goog.addDependency("debug/relativetimeprovider.js", ['goog.debug.RelativeTimeProvider'], []);
                +goog.addDependency("debug/tracer.js", ['goog.debug.Trace'], ['goog.array', 'goog.debug.Logger', 'goog.iter', 'goog.log', 'goog.structs.Map', 'goog.structs.SimplePool']);
                +goog.addDependency("debug/tracer_test.js", ['goog.debug.TraceTest'], ['goog.debug.Trace', 'goog.testing.jsunit']);
                +goog.addDependency("defineclass_test.js", ['goog.defineClassTest'], ['goog.testing.jsunit']);
                +goog.addDependency("demos/autocompleteremotedata.js", [], []);
                +goog.addDependency("demos/autocompleterichremotedata.js", [], []);
                +goog.addDependency("demos/editor/deps.js", [], []);
                +goog.addDependency("demos/editor/helloworld.js", ['goog.demos.editor.HelloWorld'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Plugin']);
                +goog.addDependency("demos/editor/helloworld_test.js", ['goog.demos.editor.HelloWorldTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.demos.editor.HelloWorld', 'goog.testing.editor.TestHelper', 'goog.testing.editor.FieldMock']);
                +goog.addDependency("demos/editor/helloworlddialog.js", ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent'], ['goog.dom.TagName', 'goog.events.Event', 'goog.string', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("demos/editor/helloworlddialog_test.js", ['goog.demos.editor.HelloWorldDialogTest'], ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent', 'goog.dom.DomHelper', 'goog.events.EventHandler', 'goog.testing.LooseMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog.EventType']);
                +goog.addDependency("demos/editor/helloworlddialogplugin.js", ['goog.demos.editor.HelloWorldDialogPlugin', 'goog.demos.editor.HelloWorldDialogPlugin.Command'], ['goog.demos.editor.HelloWorldDialog', 'goog.dom.TagName', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.range', 'goog.functions', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("demos/editor/helloworlddialogplugin_test.js", ['goog.demos.editor.HelloWorldDialogPluginTest'], ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent', 'goog.demos.editor.HelloWorldDialogPlugin', 'goog.demos.editor.HelloWorldDialogPlugin.Command', 'goog.dom', 'goog.dom.NodeType', 'goog.testing.ExpectedFailures', 'goog.testing.MockControl', 'goog.testing.MockRange', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.editor.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.userAgent']);
                +goog.addDependency("demos/graphics/tigerdata.js", [], []);
                +goog.addDependency("demos/samplecomponent.js", ['goog.demos.SampleComponent'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.ui.Component']);
                +goog.addDependency("demos/tree/testdata.js", [], []);
                +goog.addDependency("demos/xpc/xpcdemo.js", ['xpcdemo'], ['goog.Uri', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.json', 'goog.log', 'goog.log.Level', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel']);
                +goog.addDependency("deps.js", [], []);
                +goog.addDependency("disposable/disposable.js", ['goog.Disposable', 'goog.dispose', 'goog.disposeAll'], ['goog.disposable.IDisposable']);
                +goog.addDependency("disposable/disposable_test.js", ['goog.DisposableTest'], ['goog.Disposable', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("disposable/idisposable.js", ['goog.disposable.IDisposable'], []);
                +goog.addDependency("dom/abstractmultirange.js", ['goog.dom.AbstractMultiRange'], ['goog.array', 'goog.dom', 'goog.dom.AbstractRange', 'goog.dom.TextRange']);
                +goog.addDependency("dom/abstractrange.js", ['goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.SavedCaretRange', 'goog.dom.TagIterator', 'goog.userAgent']);
                +goog.addDependency("dom/abstractrange_test.js", ['goog.dom.AbstractRangeTest'], ['goog.dom', 'goog.dom.AbstractRange', 'goog.dom.Range', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/animationframe/animationframe.js", ['goog.dom.animationFrame', 'goog.dom.animationFrame.Spec', 'goog.dom.animationFrame.State'], ['goog.dom.animationFrame.polyfill']);
                +goog.addDependency("dom/animationframe/animationframe_test.js", [], ['goog.dom.animationFrame', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("dom/animationframe/polyfill.js", ['goog.dom.animationFrame.polyfill'], []);
                +goog.addDependency("dom/annotate.js", ['goog.dom.annotate', 'goog.dom.annotate.AnnotateFn'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.object']);
                +goog.addDependency("dom/annotate_test.js", ['goog.dom.annotateTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.annotate', 'goog.html.SafeHtml', 'goog.testing.jsunit']);
                +goog.addDependency("dom/attr.js", ['goog.dom.Attr'], []);
                +goog.addDependency("dom/browserfeature.js", ['goog.dom.BrowserFeature'], ['goog.userAgent']);
                +goog.addDependency("dom/browserrange/abstractrange.js", ['goog.dom.browserrange.AbstractRange'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.iter', 'goog.math.Coordinate', 'goog.string', 'goog.string.StringBuffer', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/browserrange.js", ['goog.dom.browserrange', 'goog.dom.browserrange.Error'], ['goog.dom', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.browserrange.GeckoRange', 'goog.dom.browserrange.IeRange', 'goog.dom.browserrange.OperaRange', 'goog.dom.browserrange.W3cRange', 'goog.dom.browserrange.WebKitRange', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/browserrange_test.js", ['goog.dom.browserrangeTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange', 'goog.html.testing', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/geckorange.js", ['goog.dom.browserrange.GeckoRange'], ['goog.dom.browserrange.W3cRange']);
                +goog.addDependency("dom/browserrange/ierange.js", ['goog.dom.browserrange.IeRange'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange.AbstractRange', 'goog.log', 'goog.string']);
                +goog.addDependency("dom/browserrange/operarange.js", ['goog.dom.browserrange.OperaRange'], ['goog.dom.browserrange.W3cRange']);
                +goog.addDependency("dom/browserrange/w3crange.js", ['goog.dom.browserrange.W3cRange'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange.AbstractRange', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/webkitrange.js", ['goog.dom.browserrange.WebKitRange'], ['goog.dom.RangeEndpoint', 'goog.dom.browserrange.W3cRange', 'goog.userAgent']);
                +goog.addDependency("dom/bufferedviewportsizemonitor.js", ['goog.dom.BufferedViewportSizeMonitor'], ['goog.asserts', 'goog.async.Delay', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("dom/bufferedviewportsizemonitor_test.js", ['goog.dom.BufferedViewportSizeMonitorTest'], ['goog.dom.BufferedViewportSizeMonitor', 'goog.dom.ViewportSizeMonitor', 'goog.events', 'goog.events.EventType', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit']);
                +goog.addDependency("dom/classes.js", ['goog.dom.classes'], ['goog.array']);
                +goog.addDependency("dom/classes_test.js", ['goog.dom.classes_test'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classes', 'goog.testing.jsunit']);
                +goog.addDependency("dom/classlist.js", ['goog.dom.classlist'], ['goog.array']);
                +goog.addDependency("dom/classlist_test.js", ['goog.dom.classlist_test'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit']);
                +goog.addDependency("dom/controlrange.js", ['goog.dom.ControlRange', 'goog.dom.ControlRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TagWalkType', 'goog.dom.TextRange', 'goog.iter.StopIteration', 'goog.userAgent']);
                +goog.addDependency("dom/controlrange_test.js", ['goog.dom.ControlRangeTest'], ['goog.dom', 'goog.dom.ControlRange', 'goog.dom.RangeType', 'goog.dom.TagName', 'goog.dom.TextRange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/dataset.js", ['goog.dom.dataset'], ['goog.labs.userAgent.browser', 'goog.string', 'goog.userAgent.product']);
                +goog.addDependency("dom/dataset_test.js", ['goog.dom.datasetTest'], ['goog.dom', 'goog.dom.dataset', 'goog.testing.jsunit']);
                +goog.addDependency("dom/dom.js", ['goog.dom', 'goog.dom.Appendable', 'goog.dom.DomHelper'], ['goog.array', 'goog.asserts', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.uncheckedconversions', 'goog.math.Coordinate', 'goog.math.Size', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']);
                +goog.addDependency("dom/dom_compile_test.js", [], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/dom_test.js", ['goog.dom.dom_test'], ['goog.array', 'goog.dom', 'goog.dom.BrowserFeature', 'goog.dom.DomHelper', 'goog.dom.InputType', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.html.SafeUrl', 'goog.html.testing', 'goog.object', 'goog.string.Const', 'goog.string.Unicode', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("dom/fontsizemonitor.js", ['goog.dom.FontSizeMonitor', 'goog.dom.FontSizeMonitor.EventType'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.userAgent']);
                +goog.addDependency("dom/fontsizemonitor_test.js", ['goog.dom.FontSizeMonitorTest'], ['goog.dom', 'goog.dom.FontSizeMonitor', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/forms.js", ['goog.dom.forms'], ['goog.dom.InputType', 'goog.dom.TagName', 'goog.structs.Map', 'goog.window']);
                +goog.addDependency("dom/forms_test.js", ['goog.dom.formsTest'], ['goog.dom', 'goog.dom.forms', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("dom/fullscreen.js", ['goog.dom.fullscreen', 'goog.dom.fullscreen.EventType'], ['goog.dom', 'goog.userAgent']);
                +goog.addDependency("dom/fullscreen_test.js", ['goog.dom.fullscreen_test'], ['goog.dom.DomHelper', 'goog.dom.fullscreen', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("dom/iframe.js", ['goog.dom.iframe'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.userAgent']);
                +goog.addDependency("dom/iframe_test.js", ['goog.dom.iframeTest'], ['goog.dom', 'goog.dom.iframe', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("dom/inputtype.js", ['goog.dom.InputType'], []);
                +goog.addDependency("dom/inputtype_test.js", ['goog.dom.InputTypeTest'], ['goog.dom.InputType', 'goog.object']);
                +goog.addDependency("dom/iter.js", ['goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator'], ['goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/iter_test.js", ['goog.dom.iterTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/multirange.js", ['goog.dom.MultiRange', 'goog.dom.MultiRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TextRange', 'goog.iter', 'goog.iter.StopIteration', 'goog.log']);
                +goog.addDependency("dom/multirange_test.js", ['goog.dom.MultiRangeTest'], ['goog.dom', 'goog.dom.MultiRange', 'goog.dom.Range', 'goog.iter', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodeiterator.js", ['goog.dom.NodeIterator'], ['goog.dom.TagIterator']);
                +goog.addDependency("dom/nodeiterator_test.js", ['goog.dom.NodeIteratorTest'], ['goog.dom', 'goog.dom.NodeIterator', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodeoffset.js", ['goog.dom.NodeOffset'], ['goog.Disposable', 'goog.dom.TagName']);
                +goog.addDependency("dom/nodeoffset_test.js", ['goog.dom.NodeOffsetTest'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodetype.js", ['goog.dom.NodeType'], []);
                +goog.addDependency("dom/pattern/abstractpattern.js", ['goog.dom.pattern.AbstractPattern'], ['goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/allchildren.js", ['goog.dom.pattern.AllChildren'], ['goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/callback/callback.js", ['goog.dom.pattern.callback'], ['goog.dom', 'goog.dom.TagWalkType', 'goog.iter']);
                +goog.addDependency("dom/pattern/callback/counter.js", ['goog.dom.pattern.callback.Counter'], []);
                +goog.addDependency("dom/pattern/callback/test.js", ['goog.dom.pattern.callback.Test'], ['goog.iter.StopIteration']);
                +goog.addDependency("dom/pattern/childmatches.js", ['goog.dom.pattern.ChildMatches'], ['goog.dom.pattern.AllChildren', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/endtag.js", ['goog.dom.pattern.EndTag'], ['goog.dom.TagWalkType', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/fulltag.js", ['goog.dom.pattern.FullTag'], ['goog.dom.pattern.MatchType', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/matcher.js", ['goog.dom.pattern.Matcher'], ['goog.dom.TagIterator', 'goog.dom.pattern.MatchType', 'goog.iter']);
                +goog.addDependency("dom/pattern/matcher_test.js", ['goog.dom.pattern.matcherTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.pattern.EndTag', 'goog.dom.pattern.FullTag', 'goog.dom.pattern.Matcher', 'goog.dom.pattern.Repeat', 'goog.dom.pattern.Sequence', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.callback.Counter', 'goog.dom.pattern.callback.Test', 'goog.iter.StopIteration', 'goog.testing.jsunit']);
                +goog.addDependency("dom/pattern/nodetype.js", ['goog.dom.pattern.NodeType'], ['goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/pattern.js", ['goog.dom.pattern', 'goog.dom.pattern.MatchType'], []);
                +goog.addDependency("dom/pattern/pattern_test.js", ['goog.dom.patternTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagWalkType', 'goog.dom.pattern.AllChildren', 'goog.dom.pattern.ChildMatches', 'goog.dom.pattern.EndTag', 'goog.dom.pattern.FullTag', 'goog.dom.pattern.MatchType', 'goog.dom.pattern.NodeType', 'goog.dom.pattern.Repeat', 'goog.dom.pattern.Sequence', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.Text', 'goog.testing.jsunit']);
                +goog.addDependency("dom/pattern/repeat.js", ['goog.dom.pattern.Repeat'], ['goog.dom.NodeType', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/sequence.js", ['goog.dom.pattern.Sequence'], ['goog.dom.NodeType', 'goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/starttag.js", ['goog.dom.pattern.StartTag'], ['goog.dom.TagWalkType', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/tag.js", ['goog.dom.pattern.Tag'], ['goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType', 'goog.object']);
                +goog.addDependency("dom/pattern/text.js", ['goog.dom.pattern.Text'], ['goog.dom.NodeType', 'goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/range.js", ['goog.dom.Range'], ['goog.dom', 'goog.dom.AbstractRange', 'goog.dom.BrowserFeature', 'goog.dom.ControlRange', 'goog.dom.MultiRange', 'goog.dom.NodeType', 'goog.dom.TextRange']);
                +goog.addDependency("dom/range_test.js", ['goog.dom.RangeTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeType', 'goog.dom.TagName', 'goog.dom.TextRange', 'goog.dom.browserrange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/rangeendpoint.js", ['goog.dom.RangeEndpoint'], []);
                +goog.addDependency("dom/safe.js", ['goog.dom.safe', 'goog.dom.safe.InsertAdjacentHtmlPosition'], ['goog.asserts', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("dom/safe_test.js", ['goog.dom.safeTest'], ['goog.dom.safe', 'goog.dom.safe.InsertAdjacentHtmlPosition', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.testing', 'goog.string', 'goog.string.Const', 'goog.testing', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/savedcaretrange.js", ['goog.dom.SavedCaretRange'], ['goog.array', 'goog.dom', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.string']);
                +goog.addDependency("dom/savedcaretrange_test.js", ['goog.dom.SavedCaretRangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.SavedCaretRange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/savedrange.js", ['goog.dom.SavedRange'], ['goog.Disposable', 'goog.log']);
                +goog.addDependency("dom/savedrange_test.js", ['goog.dom.SavedRangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/selection.js", ['goog.dom.selection'], ['goog.dom.InputType', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/selection_test.js", ['goog.dom.selectionTest'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.selection', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/tagiterator.js", ['goog.dom.TagIterator', 'goog.dom.TagWalkType'], ['goog.dom', 'goog.dom.NodeType', 'goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/tagiterator_test.js", ['goog.dom.TagIteratorTest'], ['goog.dom', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.dom.TagWalkType', 'goog.iter', 'goog.iter.StopIteration', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/tagname.js", ['goog.dom.TagName'], []);
                +goog.addDependency("dom/tagname_test.js", ['goog.dom.TagNameTest'], ['goog.dom.TagName', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("dom/tags.js", ['goog.dom.tags'], ['goog.object']);
                +goog.addDependency("dom/tags_test.js", ['goog.dom.tagsTest'], ['goog.dom.tags', 'goog.testing.jsunit']);
                +goog.addDependency("dom/textrange.js", ['goog.dom.TextRange'], ['goog.array', 'goog.dom', 'goog.dom.AbstractRange', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.dom.browserrange', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/textrange_test.js", ['goog.dom.TextRangeTest'], ['goog.dom', 'goog.dom.ControlRange', 'goog.dom.Range', 'goog.dom.TextRange', 'goog.math.Coordinate', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("dom/textrangeiterator.js", ['goog.dom.TextRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeIterator', 'goog.dom.TagName', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/textrangeiterator_test.js", ['goog.dom.TextRangeIteratorTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.iter.StopIteration', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/vendor.js", ['goog.dom.vendor'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/vendor_test.js", ['goog.dom.vendorTest'], ['goog.array', 'goog.dom.vendor', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil']);
                +goog.addDependency("dom/viewportsizemonitor.js", ['goog.dom.ViewportSizeMonitor'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Size']);
                +goog.addDependency("dom/viewportsizemonitor_test.js", ['goog.dom.ViewportSizeMonitorTest'], ['goog.dom.ViewportSizeMonitor', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("dom/xml.js", ['goog.dom.xml'], ['goog.dom', 'goog.dom.NodeType', 'goog.userAgent']);
                +goog.addDependency("dom/xml_test.js", ['goog.dom.xmlTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.xml', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/browserfeature.js", ['goog.editor.BrowserFeature'], ['goog.editor.defines', 'goog.labs.userAgent.browser', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("editor/browserfeature_test.js", ['goog.editor.BrowserFeatureTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit']);
                +goog.addDependency("editor/clicktoeditwrapper.js", ['goog.editor.ClickToEditWrapper'], ['goog.Disposable', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.range', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventType']);
                +goog.addDependency("editor/clicktoeditwrapper_test.js", ['goog.editor.ClickToEditWrapperTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.ClickToEditWrapper', 'goog.editor.SeamlessField', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/command.js", ['goog.editor.Command'], []);
                +goog.addDependency("editor/contenteditablefield.js", ['goog.editor.ContentEditableField'], ['goog.asserts', 'goog.editor.Field', 'goog.log']);
                +goog.addDependency("editor/contenteditablefield_test.js", ['goog.editor.ContentEditableFieldTest'], ['goog.dom', 'goog.editor.ContentEditableField', 'goog.editor.field_test', 'goog.testing.jsunit']);
                +goog.addDependency("editor/defines.js", ['goog.editor.defines'], []);
                +goog.addDependency("editor/field.js", ['goog.editor.Field', 'goog.editor.Field.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.array', 'goog.asserts', 'goog.async.Delay', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Plugin', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.editor.node', 'goog.editor.range', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.html.SafeHtml', 'goog.html.legacyconversions', 'goog.log', 'goog.log.Level', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/field_test.js", ['goog.editor.field_test'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.range', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.LooseMock', 'goog.testing.MockClock', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("editor/focus.js", ['goog.editor.focus'], ['goog.dom.selection']);
                +goog.addDependency("editor/focus_test.js", ['goog.editor.focusTest'], ['goog.dom.selection', 'goog.editor.BrowserFeature', 'goog.editor.focus', 'goog.testing.jsunit']);
                +goog.addDependency("editor/icontent.js", ['goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo'], ['goog.dom', 'goog.editor.BrowserFeature', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/icontent_test.js", ['goog.editor.icontentTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/link.js", ['goog.editor.Link'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.node', 'goog.editor.range', 'goog.string', 'goog.string.Unicode', 'goog.uri.utils', 'goog.uri.utils.ComponentIndex']);
                +goog.addDependency("editor/link_test.js", ['goog.editor.LinkTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Link', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/node.js", ['goog.editor.node'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator', 'goog.iter', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']);
                +goog.addDependency("editor/node_test.js", ['goog.editor.nodeTest'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.node', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugin.js", ['goog.editor.Plugin'], ['goog.events.EventTarget', 'goog.functions', 'goog.log', 'goog.object', 'goog.reflect', 'goog.userAgent']);
                +goog.addDependency("editor/plugin_test.js", ['goog.editor.PluginTest'], ['goog.editor.Field', 'goog.editor.Plugin', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractbubbleplugin.js", ['goog.editor.plugins.AbstractBubblePlugin'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.Plugin', 'goog.editor.style', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.actionEventWrapper', 'goog.functions', 'goog.string.Unicode', 'goog.ui.Component', 'goog.ui.editor.Bubble', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractbubbleplugin_test.js", ['goog.editor.plugins.AbstractBubblePluginTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.style', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.editor.Bubble', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractdialogplugin.js", ['goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.plugins.AbstractDialogPlugin.EventType'], ['goog.dom', 'goog.dom.Range', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.range', 'goog.events', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("editor/plugins/abstractdialogplugin_test.js", ['goog.editor.plugins.AbstractDialogPluginTest'], ['goog.dom', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.events.Event', 'goog.events.EventHandler', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstracttabhandler.js", ['goog.editor.plugins.AbstractTabHandler'], ['goog.editor.Plugin', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstracttabhandler_test.js", ['goog.editor.plugins.AbstractTabHandlerTest'], ['goog.editor.Field', 'goog.editor.plugins.AbstractTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/basictextformatter.js", ['goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.BasicTextFormatter.COMMAND'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.editor.style', 'goog.iter', 'goog.iter.StopIteration', 'goog.log', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/basictextformatter_test.js", ['goog.editor.plugins.BasicTextFormatterTest'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.BasicTextFormatter', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.LooseMock', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/blockquote.js", ['goog.editor.plugins.Blockquote'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Plugin', 'goog.editor.node', 'goog.functions', 'goog.log']);
                +goog.addDependency("editor/plugins/blockquote_test.js", ['goog.editor.plugins.BlockquoteTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.plugins.Blockquote', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/emoticons.js", ['goog.editor.plugins.Emoticons'], ['goog.dom.TagName', 'goog.editor.Plugin', 'goog.editor.range', 'goog.functions', 'goog.ui.emoji.Emoji', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/emoticons_test.js", ['goog.editor.plugins.EmoticonsTest'], ['goog.Uri', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.Emoticons', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/enterhandler.js", ['goog.editor.plugins.EnterHandler'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.plugins.Blockquote', 'goog.editor.range', 'goog.editor.style', 'goog.events.KeyCodes', 'goog.functions', 'goog.object', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/enterhandler_test.js", ['goog.editor.plugins.EnterHandlerTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.Blockquote', 'goog.editor.plugins.EnterHandler', 'goog.editor.range', 'goog.events', 'goog.events.KeyCodes', 'goog.testing.ExpectedFailures', 'goog.testing.MockClock', 'goog.testing.dom', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/firststrong.js", ['goog.editor.plugins.FirstStrong'], ['goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.i18n.bidi', 'goog.i18n.uChar', 'goog.iter', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/firststrong_test.js", ['goog.editor.plugins.FirstStrongTest'], ['goog.dom.Range', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.plugins.FirstStrong', 'goog.editor.range', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/headerformatter.js", ['goog.editor.plugins.HeaderFormatter'], ['goog.editor.Command', 'goog.editor.Plugin', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/headerformatter_test.js", ['goog.editor.plugins.HeaderFormatterTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.HeaderFormatter', 'goog.events.BrowserEvent', 'goog.testing.LooseMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkbubble.js", ['goog.editor.plugins.LinkBubble', 'goog.editor.plugins.LinkBubble.Action'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.functions', 'goog.string', 'goog.style', 'goog.ui.editor.messages', 'goog.uri.utils', 'goog.window']);
                +goog.addDependency("editor/plugins/linkbubble_test.js", ['goog.editor.plugins.LinkBubbleTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.plugins.LinkBubble', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.string', 'goog.style', 'goog.testing.FunctionMock', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkdialogplugin.js", ['goog.editor.plugins.LinkDialogPlugin'], ['goog.array', 'goog.dom', 'goog.editor.Command', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.events.EventHandler', 'goog.functions', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.uri.utils']);
                +goog.addDependency("editor/plugins/linkdialogplugin_test.js", ['goog.ui.editor.plugins.LinkDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Link', 'goog.editor.plugins.LinkDialogPlugin', 'goog.string', 'goog.string.Unicode', 'goog.testing.MockControl', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.editor.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkshortcutplugin.js", ['goog.editor.plugins.LinkShortcutPlugin'], ['goog.editor.Command', 'goog.editor.Plugin']);
                +goog.addDependency("editor/plugins/linkshortcutplugin_test.js", ['goog.editor.plugins.LinkShortcutPluginTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.LinkBubble', 'goog.editor.plugins.LinkShortcutPlugin', 'goog.events.KeyCodes', 'goog.testing.PropertyReplacer', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/listtabhandler.js", ['goog.editor.plugins.ListTabHandler'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.plugins.AbstractTabHandler', 'goog.iter']);
                +goog.addDependency("editor/plugins/listtabhandler_test.js", ['goog.editor.plugins.ListTabHandlerTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.plugins.ListTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/loremipsum.js", ['goog.editor.plugins.LoremIpsum'], ['goog.asserts', 'goog.dom', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.functions', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/loremipsum_test.js", ['goog.editor.plugins.LoremIpsumTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.plugins.LoremIpsum', 'goog.string.Unicode', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/removeformatting.js", ['goog.editor.plugins.RemoveFormatting'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/removeformatting_test.js", ['goog.editor.plugins.RemoveFormattingTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.plugins.RemoveFormatting', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.dom', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/spacestabhandler.js", ['goog.editor.plugins.SpacesTabHandler'], ['goog.dom.TagName', 'goog.editor.plugins.AbstractTabHandler', 'goog.editor.range']);
                +goog.addDependency("editor/plugins/spacestabhandler_test.js", ['goog.editor.plugins.SpacesTabHandlerTest'], ['goog.dom', 'goog.dom.Range', 'goog.editor.plugins.SpacesTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/tableeditor.js", ['goog.editor.plugins.TableEditor'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Plugin', 'goog.editor.Table', 'goog.editor.node', 'goog.editor.range', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tableeditor_test.js", ['goog.editor.plugins.TableEditorTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.plugins.TableEditor', 'goog.object', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tagonenterhandler.js", ['goog.editor.plugins.TagOnEnterHandler'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.node', 'goog.editor.plugins.EnterHandler', 'goog.editor.range', 'goog.editor.style', 'goog.events.KeyCodes', 'goog.functions', 'goog.string.Unicode', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tagonenterhandler_test.js", ['goog.editor.plugins.TagOnEnterHandlerTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.TagOnEnterHandler', 'goog.events.KeyCodes', 'goog.string.Unicode', 'goog.testing.dom', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/undoredo.js", ['goog.editor.plugins.UndoRedo'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.Range', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.events.EventHandler', 'goog.log', 'goog.object']);
                +goog.addDependency("editor/plugins/undoredo_test.js", ['goog.editor.plugins.UndoRedoTest'], ['goog.array', 'goog.dom', 'goog.dom.browserrange', 'goog.editor.Field', 'goog.editor.plugins.LoremIpsum', 'goog.editor.plugins.UndoRedo', 'goog.events', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/undoredomanager.js", ['goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoManager.EventType'], ['goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.events.EventTarget']);
                +goog.addDependency("editor/plugins/undoredomanager_test.js", ['goog.editor.plugins.UndoRedoManagerTest'], ['goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/undoredostate.js", ['goog.editor.plugins.UndoRedoState'], ['goog.events.EventTarget']);
                +goog.addDependency("editor/plugins/undoredostate_test.js", ['goog.editor.plugins.UndoRedoStateTest'], ['goog.editor.plugins.UndoRedoState', 'goog.testing.jsunit']);
                +goog.addDependency("editor/range.js", ['goog.editor.range', 'goog.editor.range.Point'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeEndpoint', 'goog.dom.SavedCaretRange', 'goog.editor.node', 'goog.editor.style', 'goog.iter', 'goog.userAgent']);
                +goog.addDependency("editor/range_test.js", ['goog.editor.rangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.range', 'goog.editor.range.Point', 'goog.string', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/seamlessfield.js", ['goog.editor.SeamlessField'], ['goog.cssom.iframe.style', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.safe', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.editor.node', 'goog.events', 'goog.events.EventType', 'goog.html.uncheckedconversions', 'goog.log', 'goog.string.Const', 'goog.style']);
                +goog.addDependency("editor/seamlessfield_test.js", ['goog.editor.seamlessfield_test'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.SeamlessField', 'goog.events', 'goog.functions', 'goog.style', 'goog.testing.MockClock', 'goog.testing.MockRange', 'goog.testing.jsunit']);
                +goog.addDependency("editor/style.js", ['goog.editor.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.object', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/style_test.js", ['goog.editor.styleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.style', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.style', 'goog.testing.LooseMock', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("editor/table.js", ['goog.editor.Table', 'goog.editor.TableCell', 'goog.editor.TableRow'], ['goog.asserts', 'goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.log', 'goog.string.Unicode', 'goog.style']);
                +goog.addDependency("editor/table_test.js", ['goog.editor.TableTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Table', 'goog.testing.jsunit']);
                +goog.addDependency("events/actioneventwrapper.js", ['goog.events.actionEventWrapper'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.EventWrapper', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/actioneventwrapper_test.js", ['goog.events.actionEventWrapperTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.events', 'goog.events.EventHandler', 'goog.events.KeyCodes', 'goog.events.actionEventWrapper', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("events/actionhandler.js", ['goog.events.ActionEvent', 'goog.events.ActionHandler', 'goog.events.ActionHandler.EventType', 'goog.events.BeforeActionEvent'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/actionhandler_test.js", ['goog.events.ActionHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.ActionHandler', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("events/browserevent.js", ['goog.events.BrowserEvent', 'goog.events.BrowserEvent.MouseButton'], ['goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventType', 'goog.reflect', 'goog.userAgent']);
                +goog.addDependency("events/browserevent_test.js", ['goog.events.BrowserEventTest'], ['goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.math.Coordinate', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/browserfeature.js", ['goog.events.BrowserFeature'], ['goog.userAgent']);
                +goog.addDependency("events/event.js", ['goog.events.Event', 'goog.events.EventLike'], ['goog.Disposable', 'goog.events.EventId']);
                +goog.addDependency("events/event_test.js", ['goog.events.EventTest'], ['goog.events.Event', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventhandler.js", ['goog.events.EventHandler'], ['goog.Disposable', 'goog.events', 'goog.object']);
                +goog.addDependency("events/eventhandler_test.js", ['goog.events.EventHandlerTest'], ['goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventid.js", ['goog.events.EventId'], []);
                +goog.addDependency("events/events.js", ['goog.events', 'goog.events.CaptureSimulationMode', 'goog.events.Key', 'goog.events.ListenableType'], ['goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.Listenable', 'goog.events.ListenerMap']);
                +goog.addDependency("events/events_test.js", ['goog.eventsTest'], ['goog.asserts.AssertionError', 'goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserFeature', 'goog.events.CaptureSimulationMode', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.Listener', 'goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventtarget.js", ['goog.events.EventTarget'], ['goog.Disposable', 'goog.asserts', 'goog.events', 'goog.events.Event', 'goog.events.Listenable', 'goog.events.ListenerMap', 'goog.object']);
                +goog.addDependency("events/eventtarget_test.js", ['goog.events.EventTargetTest'], ['goog.events.EventTarget', 'goog.events.Listenable', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtarget_via_googevents_test.js", ['goog.events.EventTargetGoogEventsTest'], ['goog.events', 'goog.events.EventTarget', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtarget_via_w3cinterface_test.js", ['goog.events.EventTargetW3CTest'], ['goog.events.EventTarget', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtargettester.js", ['goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType'], ['goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.testing.asserts', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventtype.js", ['goog.events.EventType'], ['goog.userAgent']);
                +goog.addDependency("events/eventwrapper.js", ['goog.events.EventWrapper'], []);
                +goog.addDependency("events/filedrophandler.js", ['goog.events.FileDropHandler', 'goog.events.FileDropHandler.EventType'], ['goog.array', 'goog.dom', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.log', 'goog.log.Level']);
                +goog.addDependency("events/filedrophandler_test.js", ['goog.events.FileDropHandlerTest'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.FileDropHandler', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/focushandler.js", ['goog.events.FocusHandler', 'goog.events.FocusHandler.EventType'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.userAgent']);
                +goog.addDependency("events/imehandler.js", ['goog.events.ImeHandler', 'goog.events.ImeHandler.Event', 'goog.events.ImeHandler.EventType'], ['goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/imehandler_test.js", ['goog.events.ImeHandlerTest'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.ImeHandler', 'goog.events.KeyCodes', 'goog.object', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/inputhandler.js", ['goog.events.InputHandler', 'goog.events.InputHandler.EventType'], ['goog.Timer', 'goog.dom.TagName', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/inputhandler_test.js", ['goog.events.InputHandlerTest'], ['goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("events/keycodes.js", ['goog.events.KeyCodes'], ['goog.userAgent']);
                +goog.addDependency("events/keycodes_test.js", ['goog.events.KeyCodesTest'], ['goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/keyhandler.js", ['goog.events.KeyEvent', 'goog.events.KeyHandler', 'goog.events.KeyHandler.EventType'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/keyhandler_test.js", ['goog.events.KeyEventTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/keynames.js", ['goog.events.KeyNames'], []);
                +goog.addDependency("events/keys.js", ['goog.events.Keys'], []);
                +goog.addDependency("events/listenable.js", ['goog.events.Listenable', 'goog.events.ListenableKey'], ['goog.events.EventId']);
                +goog.addDependency("events/listenable_test.js", ['goog.events.ListenableTest'], ['goog.events.Listenable', 'goog.testing.jsunit']);
                +goog.addDependency("events/listener.js", ['goog.events.Listener'], ['goog.events.ListenableKey']);
                +goog.addDependency("events/listenermap.js", ['goog.events.ListenerMap'], ['goog.array', 'goog.events.Listener', 'goog.object']);
                +goog.addDependency("events/listenermap_test.js", ['goog.events.ListenerMapTest'], ['goog.dispose', 'goog.events', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.events.ListenerMap', 'goog.testing.jsunit']);
                +goog.addDependency("events/mousewheelhandler.js", ['goog.events.MouseWheelEvent', 'goog.events.MouseWheelHandler', 'goog.events.MouseWheelHandler.EventType'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.math', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("events/mousewheelhandler_test.js", ['goog.events.MouseWheelHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.MouseWheelEvent', 'goog.events.MouseWheelHandler', 'goog.functions', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/onlinehandler.js", ['goog.events.OnlineHandler', 'goog.events.OnlineHandler.EventType'], ['goog.Timer', 'goog.events.BrowserFeature', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.net.NetworkStatusMonitor']);
                +goog.addDependency("events/onlinelistener_test.js", ['goog.events.OnlineHandlerTest'], ['goog.events', 'goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.OnlineHandler', 'goog.net.NetworkStatusMonitor', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/pastehandler.js", ['goog.events.PasteHandler', 'goog.events.PasteHandler.EventType', 'goog.events.PasteHandler.State'], ['goog.Timer', 'goog.async.ConditionalDelay', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.log', 'goog.userAgent']);
                +goog.addDependency("events/pastehandler_test.js", ['goog.events.PasteHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.PasteHandler', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/wheelevent.js", ['goog.events.WheelEvent'], ['goog.asserts', 'goog.events.BrowserEvent']);
                +goog.addDependency("events/wheelhandler.js", ['goog.events.WheelHandler'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.WheelEvent', 'goog.style', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("events/wheelhandler_test.js", ['goog.events.WheelHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.WheelEvent', 'goog.events.WheelHandler', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("format/emailaddress.js", ['goog.format.EmailAddress'], ['goog.string']);
                +goog.addDependency("format/emailaddress_test.js", ['goog.format.EmailAddressTest'], ['goog.array', 'goog.format.EmailAddress', 'goog.testing.jsunit']);
                +goog.addDependency("format/format.js", ['goog.format'], ['goog.i18n.GraphemeBreak', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("format/format_test.js", ['goog.formatTest'], ['goog.dom', 'goog.dom.TagName', 'goog.format', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("format/htmlprettyprinter.js", ['goog.format.HtmlPrettyPrinter', 'goog.format.HtmlPrettyPrinter.Buffer'], ['goog.dom.TagName', 'goog.object', 'goog.string.StringBuffer']);
                +goog.addDependency("format/htmlprettyprinter_test.js", ['goog.format.HtmlPrettyPrinterTest'], ['goog.format.HtmlPrettyPrinter', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("format/internationalizedemailaddress.js", ['goog.format.InternationalizedEmailAddress'], ['goog.format.EmailAddress', 'goog.string']);
                +goog.addDependency("format/internationalizedemailaddress_test.js", ['goog.format.InternationalizedEmailAddressTest'], ['goog.array', 'goog.format.InternationalizedEmailAddress', 'goog.testing.jsunit']);
                +goog.addDependency("format/jsonprettyprinter.js", ['goog.format.JsonPrettyPrinter', 'goog.format.JsonPrettyPrinter.SafeHtmlDelimiters', 'goog.format.JsonPrettyPrinter.TextDelimiters'], ['goog.html.SafeHtml', 'goog.json', 'goog.json.Serializer', 'goog.string', 'goog.string.format']);
                +goog.addDependency("format/jsonprettyprinter_test.js", ['goog.format.JsonPrettyPrinterTest'], ['goog.format.JsonPrettyPrinter', 'goog.testing.jsunit']);
                +goog.addDependency("fs/entry.js", ['goog.fs.DirectoryEntry', 'goog.fs.DirectoryEntry.Behavior', 'goog.fs.Entry', 'goog.fs.FileEntry'], []);
                +goog.addDependency("fs/entryimpl.js", ['goog.fs.DirectoryEntryImpl', 'goog.fs.EntryImpl', 'goog.fs.FileEntryImpl'], ['goog.array', 'goog.async.Deferred', 'goog.fs.DirectoryEntry', 'goog.fs.Entry', 'goog.fs.Error', 'goog.fs.FileEntry', 'goog.fs.FileWriter', 'goog.functions', 'goog.string']);
                +goog.addDependency("fs/error.js", ['goog.fs.DOMErrorLike', 'goog.fs.Error', 'goog.fs.Error.ErrorCode'], ['goog.asserts', 'goog.debug.Error', 'goog.object', 'goog.string']);
                +goog.addDependency("fs/filereader.js", ['goog.fs.FileReader', 'goog.fs.FileReader.EventType', 'goog.fs.FileReader.ReadyState'], ['goog.async.Deferred', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.ProgressEvent']);
                +goog.addDependency("fs/filesaver.js", ['goog.fs.FileSaver', 'goog.fs.FileSaver.EventType', 'goog.fs.FileSaver.ReadyState'], ['goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.ProgressEvent']);
                +goog.addDependency("fs/filesystem.js", ['goog.fs.FileSystem'], []);
                +goog.addDependency("fs/filesystemimpl.js", ['goog.fs.FileSystemImpl'], ['goog.fs.DirectoryEntryImpl', 'goog.fs.FileSystem']);
                +goog.addDependency("fs/filewriter.js", ['goog.fs.FileWriter'], ['goog.fs.Error', 'goog.fs.FileSaver']);
                +goog.addDependency("fs/fs.js", ['goog.fs'], ['goog.array', 'goog.async.Deferred', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.fs.FileSystemImpl', 'goog.fs.url', 'goog.userAgent']);
                +goog.addDependency("fs/fs_test.js", ['goog.fsTest'], ['goog.Promise', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.fs.FileSaver', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("fs/progressevent.js", ['goog.fs.ProgressEvent'], ['goog.events.Event']);
                +goog.addDependency("fs/url.js", ['goog.fs.url'], []);
                +goog.addDependency("fs/url_test.js", ['goog.urlTest'], ['goog.fs.url', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("functions/functions.js", ['goog.functions'], []);
                +goog.addDependency("functions/functions_test.js", ['goog.functionsTest'], ['goog.array', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("fx/abstractdragdrop.js", ['goog.fx.AbstractDragDrop', 'goog.fx.AbstractDragDrop.EventType', 'goog.fx.DragDropEvent', 'goog.fx.DragDropItem'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style']);
                +goog.addDependency("fx/abstractdragdrop_test.js", ['goog.fx.AbstractDragDropTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.functions', 'goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit']);
                +goog.addDependency("fx/anim/anim.js", ['goog.fx.anim', 'goog.fx.anim.Animated'], ['goog.async.AnimationDelay', 'goog.async.Delay', 'goog.object']);
                +goog.addDependency("fx/anim/anim_test.js", ['goog.fx.animTest'], ['goog.async.AnimationDelay', 'goog.async.Delay', 'goog.events', 'goog.functions', 'goog.fx.Animation', 'goog.fx.anim', 'goog.object', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("fx/animation.js", ['goog.fx.Animation', 'goog.fx.Animation.EventType', 'goog.fx.Animation.State', 'goog.fx.AnimationEvent'], ['goog.array', 'goog.asserts', 'goog.events.Event', 'goog.fx.Transition', 'goog.fx.TransitionBase', 'goog.fx.anim', 'goog.fx.anim.Animated']);
                +goog.addDependency("fx/animation_test.js", ['goog.fx.AnimationTest'], ['goog.events', 'goog.fx.Animation', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/animationqueue.js", ['goog.fx.AnimationParallelQueue', 'goog.fx.AnimationQueue', 'goog.fx.AnimationSerialQueue'], ['goog.array', 'goog.asserts', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.TransitionBase']);
                +goog.addDependency("fx/animationqueue_test.js", ['goog.fx.AnimationQueueTest'], ['goog.events', 'goog.fx.Animation', 'goog.fx.AnimationParallelQueue', 'goog.fx.AnimationSerialQueue', 'goog.fx.Transition', 'goog.fx.anim', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/css3/fx.js", ['goog.fx.css3'], ['goog.fx.css3.Transition']);
                +goog.addDependency("fx/css3/transition.js", ['goog.fx.css3.Transition'], ['goog.Timer', 'goog.asserts', 'goog.fx.TransitionBase', 'goog.style', 'goog.style.transition']);
                +goog.addDependency("fx/css3/transition_test.js", ['goog.fx.css3.TransitionTest'], ['goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fx.Transition', 'goog.fx.css3.Transition', 'goog.style.transition', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("fx/cssspriteanimation.js", ['goog.fx.CssSpriteAnimation'], ['goog.fx.Animation']);
                +goog.addDependency("fx/cssspriteanimation_test.js", ['goog.fx.CssSpriteAnimationTest'], ['goog.fx.CssSpriteAnimation', 'goog.math.Box', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dom.js", ['goog.fx.dom', 'goog.fx.dom.BgColorTransform', 'goog.fx.dom.ColorTransform', 'goog.fx.dom.Fade', 'goog.fx.dom.FadeIn', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOut', 'goog.fx.dom.FadeOutAndHide', 'goog.fx.dom.PredefinedEffect', 'goog.fx.dom.Resize', 'goog.fx.dom.ResizeHeight', 'goog.fx.dom.ResizeWidth', 'goog.fx.dom.Scroll', 'goog.fx.dom.Slide', 'goog.fx.dom.SlideFrom', 'goog.fx.dom.Swipe'], ['goog.color', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.style', 'goog.style.bidi']);
                +goog.addDependency("fx/dragdrop.js", ['goog.fx.DragDrop'], ['goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem']);
                +goog.addDependency("fx/dragdropgroup.js", ['goog.fx.DragDropGroup'], ['goog.dom', 'goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem']);
                +goog.addDependency("fx/dragdropgroup_test.js", ['goog.fx.DragDropGroupTest'], ['goog.events', 'goog.fx.DragDropGroup', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dragger.js", ['goog.fx.DragEvent', 'goog.fx.Dragger', 'goog.fx.Dragger.EventType'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.style', 'goog.style.bidi', 'goog.userAgent']);
                +goog.addDependency("fx/dragger_test.js", ['goog.fx.DraggerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Rect', 'goog.style.bidi', 'goog.testing.StrictMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("fx/draglistgroup.js", ['goog.fx.DragListDirection', 'goog.fx.DragListGroup', 'goog.fx.DragListGroup.EventType', 'goog.fx.DragListGroupEvent'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Coordinate', 'goog.string', 'goog.style']);
                +goog.addDependency("fx/draglistgroup_test.js", ['goog.fx.DragListGroupTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventType', 'goog.fx.DragEvent', 'goog.fx.DragListDirection', 'goog.fx.DragListGroup', 'goog.fx.Dragger', 'goog.math.Coordinate', 'goog.object', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dragscrollsupport.js", ['goog.fx.DragScrollSupport'], ['goog.Disposable', 'goog.Timer', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.style']);
                +goog.addDependency("fx/dragscrollsupport_test.js", ['goog.fx.DragScrollSupportTest'], ['goog.fx.DragScrollSupport', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("fx/easing.js", ['goog.fx.easing'], []);
                +goog.addDependency("fx/easing_test.js", ['goog.fx.easingTest'], ['goog.fx.easing', 'goog.testing.jsunit']);
                +goog.addDependency("fx/fx.js", ['goog.fx'], ['goog.asserts', 'goog.fx.Animation', 'goog.fx.Animation.EventType', 'goog.fx.Animation.State', 'goog.fx.AnimationEvent', 'goog.fx.Transition.EventType', 'goog.fx.easing']);
                +goog.addDependency("fx/fx_test.js", ['goog.fxTest'], ['goog.fx.Animation', 'goog.object', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("fx/transition.js", ['goog.fx.Transition', 'goog.fx.Transition.EventType'], []);
                +goog.addDependency("fx/transitionbase.js", ['goog.fx.TransitionBase', 'goog.fx.TransitionBase.State'], ['goog.events.EventTarget', 'goog.fx.Transition']);
                +goog.addDependency("graphics/abstractgraphics.js", ['goog.graphics.AbstractGraphics'], ['goog.dom', 'goog.graphics.AffineTransform', 'goog.graphics.Element', 'goog.graphics.EllipseElement', 'goog.graphics.Fill', 'goog.graphics.Font', 'goog.graphics.GroupElement', 'goog.graphics.Path', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.Stroke', 'goog.graphics.StrokeAndFillElement', 'goog.graphics.TextElement', 'goog.math.Coordinate', 'goog.math.Size', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("graphics/affinetransform.js", ['goog.graphics.AffineTransform'], []);
                +goog.addDependency("graphics/affinetransform_test.js", ['goog.graphics.AffineTransformTest'], ['goog.graphics', 'goog.graphics.AffineTransform', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/canvaselement.js", ['goog.graphics.CanvasEllipseElement', 'goog.graphics.CanvasGroupElement', 'goog.graphics.CanvasImageElement', 'goog.graphics.CanvasPathElement', 'goog.graphics.CanvasRectElement', 'goog.graphics.CanvasTextElement'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.graphics.EllipseElement', 'goog.graphics.Font', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.Path', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement', 'goog.html.SafeHtml', 'goog.html.uncheckedconversions', 'goog.math', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("graphics/canvasgraphics.js", ['goog.graphics.CanvasGraphics'], ['goog.dom.TagName', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.CanvasEllipseElement', 'goog.graphics.CanvasGroupElement', 'goog.graphics.CanvasImageElement', 'goog.graphics.CanvasPathElement', 'goog.graphics.CanvasRectElement', 'goog.graphics.CanvasTextElement', 'goog.graphics.Font', 'goog.graphics.SolidFill', 'goog.math.Size', 'goog.style']);
                +goog.addDependency("graphics/canvasgraphics_test.js", ['goog.graphics.CanvasGraphicsTest'], ['goog.dom', 'goog.graphics.CanvasGraphics', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/element.js", ['goog.graphics.Element'], ['goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.events.Listenable', 'goog.graphics.AffineTransform', 'goog.math']);
                +goog.addDependency("graphics/ellipseelement.js", ['goog.graphics.EllipseElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/coordinates.js", ['goog.graphics.ext.coordinates'], ['goog.string']);
                +goog.addDependency("graphics/ext/coordinates_test.js", ['goog.graphics.ext.coordinatesTest'], ['goog.graphics', 'goog.graphics.ext.coordinates', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/element.js", ['goog.graphics.ext.Element'], ['goog.events.EventTarget', 'goog.functions', 'goog.graphics.ext.coordinates']);
                +goog.addDependency("graphics/ext/element_test.js", ['goog.graphics.ext.ElementTest'], ['goog.graphics', 'goog.graphics.ext', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/ellipse.js", ['goog.graphics.ext.Ellipse'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/ext.js", ['goog.graphics.ext'], ['goog.graphics.ext.Ellipse', 'goog.graphics.ext.Graphics', 'goog.graphics.ext.Group', 'goog.graphics.ext.Image', 'goog.graphics.ext.Rectangle', 'goog.graphics.ext.Shape', 'goog.graphics.ext.coordinates']);
                +goog.addDependency("graphics/ext/graphics.js", ['goog.graphics.ext.Graphics'], ['goog.events', 'goog.events.EventType', 'goog.graphics', 'goog.graphics.ext.Group']);
                +goog.addDependency("graphics/ext/group.js", ['goog.graphics.ext.Group'], ['goog.array', 'goog.graphics.ext.Element']);
                +goog.addDependency("graphics/ext/image.js", ['goog.graphics.ext.Image'], ['goog.graphics.ext.Element']);
                +goog.addDependency("graphics/ext/path.js", ['goog.graphics.ext.Path'], ['goog.graphics.AffineTransform', 'goog.graphics.Path', 'goog.math.Rect']);
                +goog.addDependency("graphics/ext/path_test.js", ['goog.graphics.ext.PathTest'], ['goog.graphics', 'goog.graphics.ext.Path', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/rectangle.js", ['goog.graphics.ext.Rectangle'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/shape.js", ['goog.graphics.ext.Shape'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/strokeandfillelement.js", ['goog.graphics.ext.StrokeAndFillElement'], ['goog.graphics.ext.Element']);
                +goog.addDependency("graphics/fill.js", ['goog.graphics.Fill'], []);
                +goog.addDependency("graphics/font.js", ['goog.graphics.Font'], []);
                +goog.addDependency("graphics/graphics.js", ['goog.graphics'], ['goog.dom', 'goog.graphics.CanvasGraphics', 'goog.graphics.SvgGraphics', 'goog.graphics.VmlGraphics', 'goog.userAgent']);
                +goog.addDependency("graphics/groupelement.js", ['goog.graphics.GroupElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/imageelement.js", ['goog.graphics.ImageElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/lineargradient.js", ['goog.graphics.LinearGradient'], ['goog.asserts', 'goog.graphics.Fill']);
                +goog.addDependency("graphics/path.js", ['goog.graphics.Path', 'goog.graphics.Path.Segment'], ['goog.array', 'goog.graphics.AffineTransform', 'goog.math']);
                +goog.addDependency("graphics/path_test.js", ['goog.graphics.PathTest'], ['goog.array', 'goog.math', 'goog.graphics.Path', 'goog.graphics.AffineTransform', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/pathelement.js", ['goog.graphics.PathElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/paths.js", ['goog.graphics.paths'], ['goog.graphics.Path', 'goog.math.Coordinate']);
                +goog.addDependency("graphics/paths_test.js", ['goog.graphics.pathsTest'], ['goog.dom', 'goog.graphics', 'goog.graphics.paths', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/rectelement.js", ['goog.graphics.RectElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/solidfill.js", ['goog.graphics.SolidFill'], ['goog.graphics.Fill']);
                +goog.addDependency("graphics/solidfill_test.js", ['goog.graphics.SolidFillTest'], ['goog.graphics.SolidFill', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/stroke.js", ['goog.graphics.Stroke'], []);
                +goog.addDependency("graphics/strokeandfillelement.js", ['goog.graphics.StrokeAndFillElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/svgelement.js", ['goog.graphics.SvgEllipseElement', 'goog.graphics.SvgGroupElement', 'goog.graphics.SvgImageElement', 'goog.graphics.SvgPathElement', 'goog.graphics.SvgRectElement', 'goog.graphics.SvgTextElement'], ['goog.dom', 'goog.graphics.EllipseElement', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement']);
                +goog.addDependency("graphics/svggraphics.js", ['goog.graphics.SvgGraphics'], ['goog.Timer', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.Font', 'goog.graphics.LinearGradient', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.graphics.SvgEllipseElement', 'goog.graphics.SvgGroupElement', 'goog.graphics.SvgImageElement', 'goog.graphics.SvgPathElement', 'goog.graphics.SvgRectElement', 'goog.graphics.SvgTextElement', 'goog.math', 'goog.math.Size', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("graphics/svggraphics_test.js", ['goog.graphics.SvgGraphicsTest'], ['goog.dom', 'goog.graphics.SvgGraphics', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/textelement.js", ['goog.graphics.TextElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/vmlelement.js", ['goog.graphics.VmlEllipseElement', 'goog.graphics.VmlGroupElement', 'goog.graphics.VmlImageElement', 'goog.graphics.VmlPathElement', 'goog.graphics.VmlRectElement', 'goog.graphics.VmlTextElement'], ['goog.dom', 'goog.graphics.EllipseElement', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement']);
                +goog.addDependency("graphics/vmlgraphics.js", ['goog.graphics.VmlGraphics'], ['goog.array', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.Font', 'goog.graphics.LinearGradient', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.VmlEllipseElement', 'goog.graphics.VmlGroupElement', 'goog.graphics.VmlImageElement', 'goog.graphics.VmlPathElement', 'goog.graphics.VmlRectElement', 'goog.graphics.VmlTextElement', 'goog.html.uncheckedconversions', 'goog.math', 'goog.math.Size', 'goog.reflect', 'goog.string', 'goog.string.Const', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("history/event.js", ['goog.history.Event'], ['goog.events.Event', 'goog.history.EventType']);
                +goog.addDependency("history/eventtype.js", ['goog.history.EventType'], []);
                +goog.addDependency("history/history.js", ['goog.History', 'goog.History.Event', 'goog.History.EventType'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.safe', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.history.Event', 'goog.history.EventType', 'goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.labs.userAgent.device', 'goog.memoize', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("history/history_test.js", ['goog.HistoryTest'], ['goog.History', 'goog.dispose', 'goog.dom', 'goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("history/html5history.js", ['goog.history.Html5History', 'goog.history.Html5History.TokenTransformer'], ['goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.history.Event']);
                +goog.addDependency("history/html5history_test.js", ['goog.history.Html5HistoryTest'], ['goog.Timer', 'goog.events', 'goog.events.EventType', 'goog.history.EventType', 'goog.history.Html5History', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.recordFunction']);
                +goog.addDependency("html/flash.js", ['goog.html.flash'], ['goog.asserts', 'goog.html.SafeHtml']);
                +goog.addDependency("html/flash_test.js", ['goog.html.flashTest'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/legacyconversions.js", ['goog.html.legacyconversions'], ['goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("html/legacyconversions_test.js", ['goog.html.legacyconversionsTest'], ['goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.legacyconversions', 'goog.testing.jsunit']);
                +goog.addDependency("html/safehtml.js", ['goog.html.SafeHtml'], ['goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.tags', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.labs.userAgent.browser', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safehtml_test.js", ['goog.html.safeHtmlTest'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.testing', 'goog.i18n.bidi.Dir', 'goog.labs.userAgent.browser', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safehtmlformatter.js", ['goog.html.SafeHtmlFormatter'], ['goog.asserts', 'goog.dom.tags', 'goog.html.SafeHtml', 'goog.string']);
                +goog.addDependency("html/safehtmlformatter_test.js", ['goog.html.safeHtmlFormatterTest'], ['goog.html.SafeHtml', 'goog.html.SafeHtmlFormatter', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("html/safescript.js", ['goog.html.SafeScript'], ['goog.asserts', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safescript_test.js", ['goog.html.safeScriptTest'], ['goog.html.SafeScript', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safestyle.js", ['goog.html.SafeStyle'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safestyle_test.js", ['goog.html.safeStyleTest'], ['goog.html.SafeStyle', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safestylesheet.js", ['goog.html.SafeStyleSheet'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safestylesheet_test.js", ['goog.html.safeStyleSheetTest'], ['goog.html.SafeStyleSheet', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safeurl.js", ['goog.html.SafeUrl'], ['goog.asserts', 'goog.fs.url', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safeurl_test.js", ['goog.html.safeUrlTest'], ['goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/attributewhitelist.js", ['goog.html.sanitizer.AttributeSanitizedWhitelist', 'goog.html.sanitizer.AttributeWhitelist'], []);
                +goog.addDependency("html/sanitizer/csssanitizer.js", ['goog.html.sanitizer.CssSanitizer'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.SafeStyle', 'goog.html.uncheckedconversions', 'goog.object', 'goog.string']);
                +goog.addDependency("html/sanitizer/csssanitizer_test.js", [], ['goog.array', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.sanitizer.CssSanitizer', 'goog.string', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("html/sanitizer/htmlsanitizer.js", ['goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.html.sanitizer.HtmlSanitizerPolicy', 'goog.html.sanitizer.HtmlSanitizerPolicyContext', 'goog.html.sanitizer.HtmlSanitizerPolicyHints'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.functions', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.sanitizer.AttributeSanitizedWhitelist', 'goog.html.sanitizer.AttributeWhitelist', 'goog.html.sanitizer.CssSanitizer', 'goog.html.sanitizer.TagBlacklist', 'goog.html.sanitizer.TagWhitelist', 'goog.html.uncheckedconversions', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/htmlsanitizer_test.js", [], ['goog.array', 'goog.dom', 'goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.html.sanitizer.TagWhitelist', 'goog.html.sanitizer.unsafe', 'goog.html.testing', 'goog.object', 'goog.string.Const', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/tagblacklist.js", ['goog.html.sanitizer.TagBlacklist'], []);
                +goog.addDependency("html/sanitizer/tagwhitelist.js", ['goog.html.sanitizer.TagWhitelist'], []);
                +goog.addDependency("html/sanitizer/unsafe.js", ['goog.html.sanitizer.unsafe'], ['goog.asserts', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("html/sanitizer/unsafe_test.js", [], ['goog.html.SafeHtml', 'goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.TagBlacklist', 'goog.html.sanitizer.unsafe', 'goog.string.Const', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/silverlight.js", ['goog.html.silverlight'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.string.Const']);
                +goog.addDependency("html/silverlight_test.js", ['goog.html.silverlightTest'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.silverlight', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/testing.js", ['goog.html.testing'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("html/trustedresourceurl.js", ['goog.html.TrustedResourceUrl'], ['goog.asserts', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/trustedresourceurl_test.js", ['goog.html.trustedResourceUrlTest'], ['goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/uncheckedconversions.js", ['goog.html.uncheckedconversions'], ['goog.asserts', 'goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("html/uncheckedconversions_test.js", ['goog.html.uncheckedconversionsTest'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.uncheckedconversions', 'goog.i18n.bidi.Dir', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/utils.js", ['goog.html.utils'], ['goog.string']);
                +goog.addDependency("html/utils_test.js", ['goog.html.UtilsTest'], ['goog.array', 'goog.dom.TagName', 'goog.html.utils', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/bidi.js", ['goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.i18n.bidi.Format'], []);
                +goog.addDependency("i18n/bidi_test.js", ['goog.i18n.bidiTest'], ['goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/bidiformatter.js", ['goog.i18n.BidiFormatter'], ['goog.html.SafeHtml', 'goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.Format']);
                +goog.addDependency("i18n/bidiformatter_test.js", ['goog.i18n.BidiFormatterTest'], ['goog.html.SafeHtml', 'goog.html.testing', 'goog.i18n.BidiFormatter', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.Format', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/charlistdecompressor.js", ['goog.i18n.CharListDecompressor'], ['goog.array', 'goog.i18n.uChar']);
                +goog.addDependency("i18n/charlistdecompressor_test.js", ['goog.i18n.CharListDecompressorTest'], ['goog.i18n.CharListDecompressor', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/charpickerdata.js", ['goog.i18n.CharPickerData'], []);
                +goog.addDependency("i18n/collation.js", ['goog.i18n.collation'], []);
                +goog.addDependency("i18n/collation_test.js", ['goog.i18n.collationTest'], ['goog.i18n.collation', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("i18n/compactnumberformatsymbols.js", ['goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.CompactNumberFormatSymbols_af', 'goog.i18n.CompactNumberFormatSymbols_am', 'goog.i18n.CompactNumberFormatSymbols_ar', 'goog.i18n.CompactNumberFormatSymbols_ar_DZ', 'goog.i18n.CompactNumberFormatSymbols_az', 'goog.i18n.CompactNumberFormatSymbols_be', 'goog.i18n.CompactNumberFormatSymbols_bg', 'goog.i18n.CompactNumberFormatSymbols_bn', 'goog.i18n.CompactNumberFormatSymbols_br', 'goog.i18n.CompactNumberFormatSymbols_bs', 'goog.i18n.CompactNumberFormatSymbols_ca', 'goog.i18n.CompactNumberFormatSymbols_chr', 'goog.i18n.CompactNumberFormatSymbols_cs', 'goog.i18n.CompactNumberFormatSymbols_cy', 'goog.i18n.CompactNumberFormatSymbols_da', 'goog.i18n.CompactNumberFormatSymbols_de', 'goog.i18n.CompactNumberFormatSymbols_de_AT', 'goog.i18n.CompactNumberFormatSymbols_de_CH', 'goog.i18n.CompactNumberFormatSymbols_el', 'goog.i18n.CompactNumberFormatSymbols_en', 'goog.i18n.CompactNumberFormatSymbols_en_AU', 'goog.i18n.CompactNumberFormatSymbols_en_CA', 'goog.i18n.CompactNumberFormatSymbols_en_GB', 'goog.i18n.CompactNumberFormatSymbols_en_IE', 'goog.i18n.CompactNumberFormatSymbols_en_IN', 'goog.i18n.CompactNumberFormatSymbols_en_SG', 'goog.i18n.CompactNumberFormatSymbols_en_US', 'goog.i18n.CompactNumberFormatSymbols_en_ZA', 'goog.i18n.CompactNumberFormatSymbols_es', 'goog.i18n.CompactNumberFormatSymbols_es_419', 'goog.i18n.CompactNumberFormatSymbols_es_ES', 'goog.i18n.CompactNumberFormatSymbols_es_MX', 'goog.i18n.CompactNumberFormatSymbols_es_US', 'goog.i18n.CompactNumberFormatSymbols_et', 'goog.i18n.CompactNumberFormatSymbols_eu', 'goog.i18n.CompactNumberFormatSymbols_fa', 'goog.i18n.CompactNumberFormatSymbols_fi', 'goog.i18n.CompactNumberFormatSymbols_fil', 'goog.i18n.CompactNumberFormatSymbols_fr', 'goog.i18n.CompactNumberFormatSymbols_fr_CA', 'goog.i18n.CompactNumberFormatSymbols_ga', 'goog.i18n.CompactNumberFormatSymbols_gl', 'goog.i18n.CompactNumberFormatSymbols_gsw', 'goog.i18n.CompactNumberFormatSymbols_gu', 'goog.i18n.CompactNumberFormatSymbols_haw', 'goog.i18n.CompactNumberFormatSymbols_he', 'goog.i18n.CompactNumberFormatSymbols_hi', 'goog.i18n.CompactNumberFormatSymbols_hr', 'goog.i18n.CompactNumberFormatSymbols_hu', 'goog.i18n.CompactNumberFormatSymbols_hy', 'goog.i18n.CompactNumberFormatSymbols_id', 'goog.i18n.CompactNumberFormatSymbols_in', 'goog.i18n.CompactNumberFormatSymbols_is', 'goog.i18n.CompactNumberFormatSymbols_it', 'goog.i18n.CompactNumberFormatSymbols_iw', 'goog.i18n.CompactNumberFormatSymbols_ja', 'goog.i18n.CompactNumberFormatSymbols_ka', 'goog.i18n.CompactNumberFormatSymbols_kk', 'goog.i18n.CompactNumberFormatSymbols_km', 'goog.i18n.CompactNumberFormatSymbols_kn', 'goog.i18n.CompactNumberFormatSymbols_ko', 'goog.i18n.CompactNumberFormatSymbols_ky', 'goog.i18n.CompactNumberFormatSymbols_ln', 'goog.i18n.CompactNumberFormatSymbols_lo', 'goog.i18n.CompactNumberFormatSymbols_lt', 'goog.i18n.CompactNumberFormatSymbols_lv', 'goog.i18n.CompactNumberFormatSymbols_mk', 'goog.i18n.CompactNumberFormatSymbols_ml', 'goog.i18n.CompactNumberFormatSymbols_mn', 'goog.i18n.CompactNumberFormatSymbols_mo', 'goog.i18n.CompactNumberFormatSymbols_mr', 'goog.i18n.CompactNumberFormatSymbols_ms', 'goog.i18n.CompactNumberFormatSymbols_mt', 'goog.i18n.CompactNumberFormatSymbols_my', 'goog.i18n.CompactNumberFormatSymbols_nb', 'goog.i18n.CompactNumberFormatSymbols_ne', 'goog.i18n.CompactNumberFormatSymbols_nl', 'goog.i18n.CompactNumberFormatSymbols_no', 'goog.i18n.CompactNumberFormatSymbols_no_NO', 'goog.i18n.CompactNumberFormatSymbols_or', 'goog.i18n.CompactNumberFormatSymbols_pa', 'goog.i18n.CompactNumberFormatSymbols_pl', 'goog.i18n.CompactNumberFormatSymbols_pt', 'goog.i18n.CompactNumberFormatSymbols_pt_BR', 'goog.i18n.CompactNumberFormatSymbols_pt_PT', 'goog.i18n.CompactNumberFormatSymbols_ro', 'goog.i18n.CompactNumberFormatSymbols_ru', 'goog.i18n.CompactNumberFormatSymbols_sh', 'goog.i18n.CompactNumberFormatSymbols_si', 'goog.i18n.CompactNumberFormatSymbols_sk', 'goog.i18n.CompactNumberFormatSymbols_sl', 'goog.i18n.CompactNumberFormatSymbols_sq', 'goog.i18n.CompactNumberFormatSymbols_sr', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn', 'goog.i18n.CompactNumberFormatSymbols_sv', 'goog.i18n.CompactNumberFormatSymbols_sw', 'goog.i18n.CompactNumberFormatSymbols_ta', 'goog.i18n.CompactNumberFormatSymbols_te', 'goog.i18n.CompactNumberFormatSymbols_th', 'goog.i18n.CompactNumberFormatSymbols_tl', 'goog.i18n.CompactNumberFormatSymbols_tr', 'goog.i18n.CompactNumberFormatSymbols_uk', 'goog.i18n.CompactNumberFormatSymbols_ur', 'goog.i18n.CompactNumberFormatSymbols_uz', 'goog.i18n.CompactNumberFormatSymbols_vi', 'goog.i18n.CompactNumberFormatSymbols_zh', 'goog.i18n.CompactNumberFormatSymbols_zh_CN', 'goog.i18n.CompactNumberFormatSymbols_zh_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_TW', 'goog.i18n.CompactNumberFormatSymbols_zu'], []);
                +goog.addDependency("i18n/compactnumberformatsymbolsext.js", ['goog.i18n.CompactNumberFormatSymbolsExt', 'goog.i18n.CompactNumberFormatSymbols_af_NA', 'goog.i18n.CompactNumberFormatSymbols_af_ZA', 'goog.i18n.CompactNumberFormatSymbols_agq', 'goog.i18n.CompactNumberFormatSymbols_agq_CM', 'goog.i18n.CompactNumberFormatSymbols_ak', 'goog.i18n.CompactNumberFormatSymbols_ak_GH', 'goog.i18n.CompactNumberFormatSymbols_am_ET', 'goog.i18n.CompactNumberFormatSymbols_ar_001', 'goog.i18n.CompactNumberFormatSymbols_ar_AE', 'goog.i18n.CompactNumberFormatSymbols_ar_BH', 'goog.i18n.CompactNumberFormatSymbols_ar_DJ', 'goog.i18n.CompactNumberFormatSymbols_ar_EG', 'goog.i18n.CompactNumberFormatSymbols_ar_EH', 'goog.i18n.CompactNumberFormatSymbols_ar_ER', 'goog.i18n.CompactNumberFormatSymbols_ar_IL', 'goog.i18n.CompactNumberFormatSymbols_ar_IQ', 'goog.i18n.CompactNumberFormatSymbols_ar_JO', 'goog.i18n.CompactNumberFormatSymbols_ar_KM', 'goog.i18n.CompactNumberFormatSymbols_ar_KW', 'goog.i18n.CompactNumberFormatSymbols_ar_LB', 'goog.i18n.CompactNumberFormatSymbols_ar_LY', 'goog.i18n.CompactNumberFormatSymbols_ar_MA', 'goog.i18n.CompactNumberFormatSymbols_ar_MR', 'goog.i18n.CompactNumberFormatSymbols_ar_OM', 'goog.i18n.CompactNumberFormatSymbols_ar_PS', 'goog.i18n.CompactNumberFormatSymbols_ar_QA', 'goog.i18n.CompactNumberFormatSymbols_ar_SA', 'goog.i18n.CompactNumberFormatSymbols_ar_SD', 'goog.i18n.CompactNumberFormatSymbols_ar_SO', 'goog.i18n.CompactNumberFormatSymbols_ar_SS', 'goog.i18n.CompactNumberFormatSymbols_ar_SY', 'goog.i18n.CompactNumberFormatSymbols_ar_TD', 'goog.i18n.CompactNumberFormatSymbols_ar_TN', 'goog.i18n.CompactNumberFormatSymbols_ar_XB', 'goog.i18n.CompactNumberFormatSymbols_ar_YE', 'goog.i18n.CompactNumberFormatSymbols_as', 'goog.i18n.CompactNumberFormatSymbols_as_IN', 'goog.i18n.CompactNumberFormatSymbols_asa', 'goog.i18n.CompactNumberFormatSymbols_asa_TZ', 'goog.i18n.CompactNumberFormatSymbols_ast', 'goog.i18n.CompactNumberFormatSymbols_ast_ES', 'goog.i18n.CompactNumberFormatSymbols_az_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_az_Cyrl_AZ', 'goog.i18n.CompactNumberFormatSymbols_az_Latn', 'goog.i18n.CompactNumberFormatSymbols_az_Latn_AZ', 'goog.i18n.CompactNumberFormatSymbols_bas', 'goog.i18n.CompactNumberFormatSymbols_bas_CM', 'goog.i18n.CompactNumberFormatSymbols_be_BY', 'goog.i18n.CompactNumberFormatSymbols_bem', 'goog.i18n.CompactNumberFormatSymbols_bem_ZM', 'goog.i18n.CompactNumberFormatSymbols_bez', 'goog.i18n.CompactNumberFormatSymbols_bez_TZ', 'goog.i18n.CompactNumberFormatSymbols_bg_BG', 'goog.i18n.CompactNumberFormatSymbols_bm', 'goog.i18n.CompactNumberFormatSymbols_bm_ML', 'goog.i18n.CompactNumberFormatSymbols_bn_BD', 'goog.i18n.CompactNumberFormatSymbols_bn_IN', 'goog.i18n.CompactNumberFormatSymbols_bo', 'goog.i18n.CompactNumberFormatSymbols_bo_CN', 'goog.i18n.CompactNumberFormatSymbols_bo_IN', 'goog.i18n.CompactNumberFormatSymbols_br_FR', 'goog.i18n.CompactNumberFormatSymbols_brx', 'goog.i18n.CompactNumberFormatSymbols_brx_IN', 'goog.i18n.CompactNumberFormatSymbols_bs_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_bs_Cyrl_BA', 'goog.i18n.CompactNumberFormatSymbols_bs_Latn', 'goog.i18n.CompactNumberFormatSymbols_bs_Latn_BA', 'goog.i18n.CompactNumberFormatSymbols_ca_AD', 'goog.i18n.CompactNumberFormatSymbols_ca_ES', 'goog.i18n.CompactNumberFormatSymbols_ca_FR', 'goog.i18n.CompactNumberFormatSymbols_ca_IT', 'goog.i18n.CompactNumberFormatSymbols_ce', 'goog.i18n.CompactNumberFormatSymbols_ce_RU', 'goog.i18n.CompactNumberFormatSymbols_cgg', 'goog.i18n.CompactNumberFormatSymbols_cgg_UG', 'goog.i18n.CompactNumberFormatSymbols_chr_US', 'goog.i18n.CompactNumberFormatSymbols_ckb', 'goog.i18n.CompactNumberFormatSymbols_ckb_IQ', 'goog.i18n.CompactNumberFormatSymbols_ckb_IR', 'goog.i18n.CompactNumberFormatSymbols_cs_CZ', 'goog.i18n.CompactNumberFormatSymbols_cy_GB', 'goog.i18n.CompactNumberFormatSymbols_da_DK', 'goog.i18n.CompactNumberFormatSymbols_da_GL', 'goog.i18n.CompactNumberFormatSymbols_dav', 'goog.i18n.CompactNumberFormatSymbols_dav_KE', 'goog.i18n.CompactNumberFormatSymbols_de_BE', 'goog.i18n.CompactNumberFormatSymbols_de_DE', 'goog.i18n.CompactNumberFormatSymbols_de_IT', 'goog.i18n.CompactNumberFormatSymbols_de_LI', 'goog.i18n.CompactNumberFormatSymbols_de_LU', 'goog.i18n.CompactNumberFormatSymbols_dje', 'goog.i18n.CompactNumberFormatSymbols_dje_NE', 'goog.i18n.CompactNumberFormatSymbols_dsb', 'goog.i18n.CompactNumberFormatSymbols_dsb_DE', 'goog.i18n.CompactNumberFormatSymbols_dua', 'goog.i18n.CompactNumberFormatSymbols_dua_CM', 'goog.i18n.CompactNumberFormatSymbols_dyo', 'goog.i18n.CompactNumberFormatSymbols_dyo_SN', 'goog.i18n.CompactNumberFormatSymbols_dz', 'goog.i18n.CompactNumberFormatSymbols_dz_BT', 'goog.i18n.CompactNumberFormatSymbols_ebu', 'goog.i18n.CompactNumberFormatSymbols_ebu_KE', 'goog.i18n.CompactNumberFormatSymbols_ee', 'goog.i18n.CompactNumberFormatSymbols_ee_GH', 'goog.i18n.CompactNumberFormatSymbols_ee_TG', 'goog.i18n.CompactNumberFormatSymbols_el_CY', 'goog.i18n.CompactNumberFormatSymbols_el_GR', 'goog.i18n.CompactNumberFormatSymbols_en_001', 'goog.i18n.CompactNumberFormatSymbols_en_150', 'goog.i18n.CompactNumberFormatSymbols_en_AG', 'goog.i18n.CompactNumberFormatSymbols_en_AI', 'goog.i18n.CompactNumberFormatSymbols_en_AS', 'goog.i18n.CompactNumberFormatSymbols_en_AT', 'goog.i18n.CompactNumberFormatSymbols_en_BB', 'goog.i18n.CompactNumberFormatSymbols_en_BE', 'goog.i18n.CompactNumberFormatSymbols_en_BI', 'goog.i18n.CompactNumberFormatSymbols_en_BM', 'goog.i18n.CompactNumberFormatSymbols_en_BS', 'goog.i18n.CompactNumberFormatSymbols_en_BW', 'goog.i18n.CompactNumberFormatSymbols_en_BZ', 'goog.i18n.CompactNumberFormatSymbols_en_CC', 'goog.i18n.CompactNumberFormatSymbols_en_CH', 'goog.i18n.CompactNumberFormatSymbols_en_CK', 'goog.i18n.CompactNumberFormatSymbols_en_CM', 'goog.i18n.CompactNumberFormatSymbols_en_CX', 'goog.i18n.CompactNumberFormatSymbols_en_CY', 'goog.i18n.CompactNumberFormatSymbols_en_DE', 'goog.i18n.CompactNumberFormatSymbols_en_DG', 'goog.i18n.CompactNumberFormatSymbols_en_DK', 'goog.i18n.CompactNumberFormatSymbols_en_DM', 'goog.i18n.CompactNumberFormatSymbols_en_ER', 'goog.i18n.CompactNumberFormatSymbols_en_FI', 'goog.i18n.CompactNumberFormatSymbols_en_FJ', 'goog.i18n.CompactNumberFormatSymbols_en_FK', 'goog.i18n.CompactNumberFormatSymbols_en_FM', 'goog.i18n.CompactNumberFormatSymbols_en_GD', 'goog.i18n.CompactNumberFormatSymbols_en_GG', 'goog.i18n.CompactNumberFormatSymbols_en_GH', 'goog.i18n.CompactNumberFormatSymbols_en_GI', 'goog.i18n.CompactNumberFormatSymbols_en_GM', 'goog.i18n.CompactNumberFormatSymbols_en_GU', 'goog.i18n.CompactNumberFormatSymbols_en_GY', 'goog.i18n.CompactNumberFormatSymbols_en_HK', 'goog.i18n.CompactNumberFormatSymbols_en_IL', 'goog.i18n.CompactNumberFormatSymbols_en_IM', 'goog.i18n.CompactNumberFormatSymbols_en_IO', 'goog.i18n.CompactNumberFormatSymbols_en_JE', 'goog.i18n.CompactNumberFormatSymbols_en_JM', 'goog.i18n.CompactNumberFormatSymbols_en_KE', 'goog.i18n.CompactNumberFormatSymbols_en_KI', 'goog.i18n.CompactNumberFormatSymbols_en_KN', 'goog.i18n.CompactNumberFormatSymbols_en_KY', 'goog.i18n.CompactNumberFormatSymbols_en_LC', 'goog.i18n.CompactNumberFormatSymbols_en_LR', 'goog.i18n.CompactNumberFormatSymbols_en_LS', 'goog.i18n.CompactNumberFormatSymbols_en_MG', 'goog.i18n.CompactNumberFormatSymbols_en_MH', 'goog.i18n.CompactNumberFormatSymbols_en_MO', 'goog.i18n.CompactNumberFormatSymbols_en_MP', 'goog.i18n.CompactNumberFormatSymbols_en_MS', 'goog.i18n.CompactNumberFormatSymbols_en_MT', 'goog.i18n.CompactNumberFormatSymbols_en_MU', 'goog.i18n.CompactNumberFormatSymbols_en_MW', 'goog.i18n.CompactNumberFormatSymbols_en_MY', 'goog.i18n.CompactNumberFormatSymbols_en_NA', 'goog.i18n.CompactNumberFormatSymbols_en_NF', 'goog.i18n.CompactNumberFormatSymbols_en_NG', 'goog.i18n.CompactNumberFormatSymbols_en_NL', 'goog.i18n.CompactNumberFormatSymbols_en_NR', 'goog.i18n.CompactNumberFormatSymbols_en_NU', 'goog.i18n.CompactNumberFormatSymbols_en_NZ', 'goog.i18n.CompactNumberFormatSymbols_en_PG', 'goog.i18n.CompactNumberFormatSymbols_en_PH', 'goog.i18n.CompactNumberFormatSymbols_en_PK', 'goog.i18n.CompactNumberFormatSymbols_en_PN', 'goog.i18n.CompactNumberFormatSymbols_en_PR', 'goog.i18n.CompactNumberFormatSymbols_en_PW', 'goog.i18n.CompactNumberFormatSymbols_en_RW', 'goog.i18n.CompactNumberFormatSymbols_en_SB', 'goog.i18n.CompactNumberFormatSymbols_en_SC', 'goog.i18n.CompactNumberFormatSymbols_en_SD', 'goog.i18n.CompactNumberFormatSymbols_en_SE', 'goog.i18n.CompactNumberFormatSymbols_en_SH', 'goog.i18n.CompactNumberFormatSymbols_en_SI', 'goog.i18n.CompactNumberFormatSymbols_en_SL', 'goog.i18n.CompactNumberFormatSymbols_en_SS', 'goog.i18n.CompactNumberFormatSymbols_en_SX', 'goog.i18n.CompactNumberFormatSymbols_en_SZ', 'goog.i18n.CompactNumberFormatSymbols_en_TC', 'goog.i18n.CompactNumberFormatSymbols_en_TK', 'goog.i18n.CompactNumberFormatSymbols_en_TO', 'goog.i18n.CompactNumberFormatSymbols_en_TT', 'goog.i18n.CompactNumberFormatSymbols_en_TV', 'goog.i18n.CompactNumberFormatSymbols_en_TZ', 'goog.i18n.CompactNumberFormatSymbols_en_UG', 'goog.i18n.CompactNumberFormatSymbols_en_UM', 'goog.i18n.CompactNumberFormatSymbols_en_US_POSIX', 'goog.i18n.CompactNumberFormatSymbols_en_VC', 'goog.i18n.CompactNumberFormatSymbols_en_VG', 'goog.i18n.CompactNumberFormatSymbols_en_VI', 'goog.i18n.CompactNumberFormatSymbols_en_VU', 'goog.i18n.CompactNumberFormatSymbols_en_WS', 'goog.i18n.CompactNumberFormatSymbols_en_XA', 'goog.i18n.CompactNumberFormatSymbols_en_ZM', 'goog.i18n.CompactNumberFormatSymbols_en_ZW', 'goog.i18n.CompactNumberFormatSymbols_eo', 'goog.i18n.CompactNumberFormatSymbols_es_AR', 'goog.i18n.CompactNumberFormatSymbols_es_BO', 'goog.i18n.CompactNumberFormatSymbols_es_BR', 'goog.i18n.CompactNumberFormatSymbols_es_CL', 'goog.i18n.CompactNumberFormatSymbols_es_CO', 'goog.i18n.CompactNumberFormatSymbols_es_CR', 'goog.i18n.CompactNumberFormatSymbols_es_CU', 'goog.i18n.CompactNumberFormatSymbols_es_DO', 'goog.i18n.CompactNumberFormatSymbols_es_EA', 'goog.i18n.CompactNumberFormatSymbols_es_EC', 'goog.i18n.CompactNumberFormatSymbols_es_GQ', 'goog.i18n.CompactNumberFormatSymbols_es_GT', 'goog.i18n.CompactNumberFormatSymbols_es_HN', 'goog.i18n.CompactNumberFormatSymbols_es_IC', 'goog.i18n.CompactNumberFormatSymbols_es_NI', 'goog.i18n.CompactNumberFormatSymbols_es_PA', 'goog.i18n.CompactNumberFormatSymbols_es_PE', 'goog.i18n.CompactNumberFormatSymbols_es_PH', 'goog.i18n.CompactNumberFormatSymbols_es_PR', 'goog.i18n.CompactNumberFormatSymbols_es_PY', 'goog.i18n.CompactNumberFormatSymbols_es_SV', 'goog.i18n.CompactNumberFormatSymbols_es_UY', 'goog.i18n.CompactNumberFormatSymbols_es_VE', 'goog.i18n.CompactNumberFormatSymbols_et_EE', 'goog.i18n.CompactNumberFormatSymbols_eu_ES', 'goog.i18n.CompactNumberFormatSymbols_ewo', 'goog.i18n.CompactNumberFormatSymbols_ewo_CM', 'goog.i18n.CompactNumberFormatSymbols_fa_AF', 'goog.i18n.CompactNumberFormatSymbols_fa_IR', 'goog.i18n.CompactNumberFormatSymbols_ff', 'goog.i18n.CompactNumberFormatSymbols_ff_CM', 'goog.i18n.CompactNumberFormatSymbols_ff_GN', 'goog.i18n.CompactNumberFormatSymbols_ff_MR', 'goog.i18n.CompactNumberFormatSymbols_ff_SN', 'goog.i18n.CompactNumberFormatSymbols_fi_FI', 'goog.i18n.CompactNumberFormatSymbols_fil_PH', 'goog.i18n.CompactNumberFormatSymbols_fo', 'goog.i18n.CompactNumberFormatSymbols_fo_DK', 'goog.i18n.CompactNumberFormatSymbols_fo_FO', 'goog.i18n.CompactNumberFormatSymbols_fr_BE', 'goog.i18n.CompactNumberFormatSymbols_fr_BF', 'goog.i18n.CompactNumberFormatSymbols_fr_BI', 'goog.i18n.CompactNumberFormatSymbols_fr_BJ', 'goog.i18n.CompactNumberFormatSymbols_fr_BL', 'goog.i18n.CompactNumberFormatSymbols_fr_CD', 'goog.i18n.CompactNumberFormatSymbols_fr_CF', 'goog.i18n.CompactNumberFormatSymbols_fr_CG', 'goog.i18n.CompactNumberFormatSymbols_fr_CH', 'goog.i18n.CompactNumberFormatSymbols_fr_CI', 'goog.i18n.CompactNumberFormatSymbols_fr_CM', 'goog.i18n.CompactNumberFormatSymbols_fr_DJ', 'goog.i18n.CompactNumberFormatSymbols_fr_DZ', 'goog.i18n.CompactNumberFormatSymbols_fr_FR', 'goog.i18n.CompactNumberFormatSymbols_fr_GA', 'goog.i18n.CompactNumberFormatSymbols_fr_GF', 'goog.i18n.CompactNumberFormatSymbols_fr_GN', 'goog.i18n.CompactNumberFormatSymbols_fr_GP', 'goog.i18n.CompactNumberFormatSymbols_fr_GQ', 'goog.i18n.CompactNumberFormatSymbols_fr_HT', 'goog.i18n.CompactNumberFormatSymbols_fr_KM', 'goog.i18n.CompactNumberFormatSymbols_fr_LU', 'goog.i18n.CompactNumberFormatSymbols_fr_MA', 'goog.i18n.CompactNumberFormatSymbols_fr_MC', 'goog.i18n.CompactNumberFormatSymbols_fr_MF', 'goog.i18n.CompactNumberFormatSymbols_fr_MG', 'goog.i18n.CompactNumberFormatSymbols_fr_ML', 'goog.i18n.CompactNumberFormatSymbols_fr_MQ', 'goog.i18n.CompactNumberFormatSymbols_fr_MR', 'goog.i18n.CompactNumberFormatSymbols_fr_MU', 'goog.i18n.CompactNumberFormatSymbols_fr_NC', 'goog.i18n.CompactNumberFormatSymbols_fr_NE', 'goog.i18n.CompactNumberFormatSymbols_fr_PF', 'goog.i18n.CompactNumberFormatSymbols_fr_PM', 'goog.i18n.CompactNumberFormatSymbols_fr_RE', 'goog.i18n.CompactNumberFormatSymbols_fr_RW', 'goog.i18n.CompactNumberFormatSymbols_fr_SC', 'goog.i18n.CompactNumberFormatSymbols_fr_SN', 'goog.i18n.CompactNumberFormatSymbols_fr_SY', 'goog.i18n.CompactNumberFormatSymbols_fr_TD', 'goog.i18n.CompactNumberFormatSymbols_fr_TG', 'goog.i18n.CompactNumberFormatSymbols_fr_TN', 'goog.i18n.CompactNumberFormatSymbols_fr_VU', 'goog.i18n.CompactNumberFormatSymbols_fr_WF', 'goog.i18n.CompactNumberFormatSymbols_fr_YT', 'goog.i18n.CompactNumberFormatSymbols_fur', 'goog.i18n.CompactNumberFormatSymbols_fur_IT', 'goog.i18n.CompactNumberFormatSymbols_fy', 'goog.i18n.CompactNumberFormatSymbols_fy_NL', 'goog.i18n.CompactNumberFormatSymbols_ga_IE', 'goog.i18n.CompactNumberFormatSymbols_gd', 'goog.i18n.CompactNumberFormatSymbols_gd_GB', 'goog.i18n.CompactNumberFormatSymbols_gl_ES', 'goog.i18n.CompactNumberFormatSymbols_gsw_CH', 'goog.i18n.CompactNumberFormatSymbols_gsw_FR', 'goog.i18n.CompactNumberFormatSymbols_gsw_LI', 'goog.i18n.CompactNumberFormatSymbols_gu_IN', 'goog.i18n.CompactNumberFormatSymbols_guz', 'goog.i18n.CompactNumberFormatSymbols_guz_KE', 'goog.i18n.CompactNumberFormatSymbols_gv', 'goog.i18n.CompactNumberFormatSymbols_gv_IM', 'goog.i18n.CompactNumberFormatSymbols_ha', 'goog.i18n.CompactNumberFormatSymbols_ha_GH', 'goog.i18n.CompactNumberFormatSymbols_ha_NE', 'goog.i18n.CompactNumberFormatSymbols_ha_NG', 'goog.i18n.CompactNumberFormatSymbols_haw_US', 'goog.i18n.CompactNumberFormatSymbols_he_IL', 'goog.i18n.CompactNumberFormatSymbols_hi_IN', 'goog.i18n.CompactNumberFormatSymbols_hr_BA', 'goog.i18n.CompactNumberFormatSymbols_hr_HR', 'goog.i18n.CompactNumberFormatSymbols_hsb', 'goog.i18n.CompactNumberFormatSymbols_hsb_DE', 'goog.i18n.CompactNumberFormatSymbols_hu_HU', 'goog.i18n.CompactNumberFormatSymbols_hy_AM', 'goog.i18n.CompactNumberFormatSymbols_id_ID', 'goog.i18n.CompactNumberFormatSymbols_ig', 'goog.i18n.CompactNumberFormatSymbols_ig_NG', 'goog.i18n.CompactNumberFormatSymbols_ii', 'goog.i18n.CompactNumberFormatSymbols_ii_CN', 'goog.i18n.CompactNumberFormatSymbols_is_IS', 'goog.i18n.CompactNumberFormatSymbols_it_CH', 'goog.i18n.CompactNumberFormatSymbols_it_IT', 'goog.i18n.CompactNumberFormatSymbols_it_SM', 'goog.i18n.CompactNumberFormatSymbols_ja_JP', 'goog.i18n.CompactNumberFormatSymbols_jgo', 'goog.i18n.CompactNumberFormatSymbols_jgo_CM', 'goog.i18n.CompactNumberFormatSymbols_jmc', 'goog.i18n.CompactNumberFormatSymbols_jmc_TZ', 'goog.i18n.CompactNumberFormatSymbols_ka_GE', 'goog.i18n.CompactNumberFormatSymbols_kab', 'goog.i18n.CompactNumberFormatSymbols_kab_DZ', 'goog.i18n.CompactNumberFormatSymbols_kam', 'goog.i18n.CompactNumberFormatSymbols_kam_KE', 'goog.i18n.CompactNumberFormatSymbols_kde', 'goog.i18n.CompactNumberFormatSymbols_kde_TZ', 'goog.i18n.CompactNumberFormatSymbols_kea', 'goog.i18n.CompactNumberFormatSymbols_kea_CV', 'goog.i18n.CompactNumberFormatSymbols_khq', 'goog.i18n.CompactNumberFormatSymbols_khq_ML', 'goog.i18n.CompactNumberFormatSymbols_ki', 'goog.i18n.CompactNumberFormatSymbols_ki_KE', 'goog.i18n.CompactNumberFormatSymbols_kk_KZ', 'goog.i18n.CompactNumberFormatSymbols_kkj', 'goog.i18n.CompactNumberFormatSymbols_kkj_CM', 'goog.i18n.CompactNumberFormatSymbols_kl', 'goog.i18n.CompactNumberFormatSymbols_kl_GL', 'goog.i18n.CompactNumberFormatSymbols_kln', 'goog.i18n.CompactNumberFormatSymbols_kln_KE', 'goog.i18n.CompactNumberFormatSymbols_km_KH', 'goog.i18n.CompactNumberFormatSymbols_kn_IN', 'goog.i18n.CompactNumberFormatSymbols_ko_KP', 'goog.i18n.CompactNumberFormatSymbols_ko_KR', 'goog.i18n.CompactNumberFormatSymbols_kok', 'goog.i18n.CompactNumberFormatSymbols_kok_IN', 'goog.i18n.CompactNumberFormatSymbols_ks', 'goog.i18n.CompactNumberFormatSymbols_ks_IN', 'goog.i18n.CompactNumberFormatSymbols_ksb', 'goog.i18n.CompactNumberFormatSymbols_ksb_TZ', 'goog.i18n.CompactNumberFormatSymbols_ksf', 'goog.i18n.CompactNumberFormatSymbols_ksf_CM', 'goog.i18n.CompactNumberFormatSymbols_ksh', 'goog.i18n.CompactNumberFormatSymbols_ksh_DE', 'goog.i18n.CompactNumberFormatSymbols_kw', 'goog.i18n.CompactNumberFormatSymbols_kw_GB', 'goog.i18n.CompactNumberFormatSymbols_ky_KG', 'goog.i18n.CompactNumberFormatSymbols_lag', 'goog.i18n.CompactNumberFormatSymbols_lag_TZ', 'goog.i18n.CompactNumberFormatSymbols_lb', 'goog.i18n.CompactNumberFormatSymbols_lb_LU', 'goog.i18n.CompactNumberFormatSymbols_lg', 'goog.i18n.CompactNumberFormatSymbols_lg_UG', 'goog.i18n.CompactNumberFormatSymbols_lkt', 'goog.i18n.CompactNumberFormatSymbols_lkt_US', 'goog.i18n.CompactNumberFormatSymbols_ln_AO', 'goog.i18n.CompactNumberFormatSymbols_ln_CD', 'goog.i18n.CompactNumberFormatSymbols_ln_CF', 'goog.i18n.CompactNumberFormatSymbols_ln_CG', 'goog.i18n.CompactNumberFormatSymbols_lo_LA', 'goog.i18n.CompactNumberFormatSymbols_lrc', 'goog.i18n.CompactNumberFormatSymbols_lrc_IQ', 'goog.i18n.CompactNumberFormatSymbols_lrc_IR', 'goog.i18n.CompactNumberFormatSymbols_lt_LT', 'goog.i18n.CompactNumberFormatSymbols_lu', 'goog.i18n.CompactNumberFormatSymbols_lu_CD', 'goog.i18n.CompactNumberFormatSymbols_luo', 'goog.i18n.CompactNumberFormatSymbols_luo_KE', 'goog.i18n.CompactNumberFormatSymbols_luy', 'goog.i18n.CompactNumberFormatSymbols_luy_KE', 'goog.i18n.CompactNumberFormatSymbols_lv_LV', 'goog.i18n.CompactNumberFormatSymbols_mas', 'goog.i18n.CompactNumberFormatSymbols_mas_KE', 'goog.i18n.CompactNumberFormatSymbols_mas_TZ', 'goog.i18n.CompactNumberFormatSymbols_mer', 'goog.i18n.CompactNumberFormatSymbols_mer_KE', 'goog.i18n.CompactNumberFormatSymbols_mfe', 'goog.i18n.CompactNumberFormatSymbols_mfe_MU', 'goog.i18n.CompactNumberFormatSymbols_mg', 'goog.i18n.CompactNumberFormatSymbols_mg_MG', 'goog.i18n.CompactNumberFormatSymbols_mgh', 'goog.i18n.CompactNumberFormatSymbols_mgh_MZ', 'goog.i18n.CompactNumberFormatSymbols_mgo', 'goog.i18n.CompactNumberFormatSymbols_mgo_CM', 'goog.i18n.CompactNumberFormatSymbols_mk_MK', 'goog.i18n.CompactNumberFormatSymbols_ml_IN', 'goog.i18n.CompactNumberFormatSymbols_mn_MN', 'goog.i18n.CompactNumberFormatSymbols_mr_IN', 'goog.i18n.CompactNumberFormatSymbols_ms_BN', 'goog.i18n.CompactNumberFormatSymbols_ms_MY', 'goog.i18n.CompactNumberFormatSymbols_ms_SG', 'goog.i18n.CompactNumberFormatSymbols_mt_MT', 'goog.i18n.CompactNumberFormatSymbols_mua', 'goog.i18n.CompactNumberFormatSymbols_mua_CM', 'goog.i18n.CompactNumberFormatSymbols_my_MM', 'goog.i18n.CompactNumberFormatSymbols_mzn', 'goog.i18n.CompactNumberFormatSymbols_mzn_IR', 'goog.i18n.CompactNumberFormatSymbols_naq', 'goog.i18n.CompactNumberFormatSymbols_naq_NA', 'goog.i18n.CompactNumberFormatSymbols_nb_NO', 'goog.i18n.CompactNumberFormatSymbols_nb_SJ', 'goog.i18n.CompactNumberFormatSymbols_nd', 'goog.i18n.CompactNumberFormatSymbols_nd_ZW', 'goog.i18n.CompactNumberFormatSymbols_nds', 'goog.i18n.CompactNumberFormatSymbols_nds_DE', 'goog.i18n.CompactNumberFormatSymbols_nds_NL', 'goog.i18n.CompactNumberFormatSymbols_ne_IN', 'goog.i18n.CompactNumberFormatSymbols_ne_NP', 'goog.i18n.CompactNumberFormatSymbols_nl_AW', 'goog.i18n.CompactNumberFormatSymbols_nl_BE', 'goog.i18n.CompactNumberFormatSymbols_nl_BQ', 'goog.i18n.CompactNumberFormatSymbols_nl_CW', 'goog.i18n.CompactNumberFormatSymbols_nl_NL', 'goog.i18n.CompactNumberFormatSymbols_nl_SR', 'goog.i18n.CompactNumberFormatSymbols_nl_SX', 'goog.i18n.CompactNumberFormatSymbols_nmg', 'goog.i18n.CompactNumberFormatSymbols_nmg_CM', 'goog.i18n.CompactNumberFormatSymbols_nn', 'goog.i18n.CompactNumberFormatSymbols_nn_NO', 'goog.i18n.CompactNumberFormatSymbols_nnh', 'goog.i18n.CompactNumberFormatSymbols_nnh_CM', 'goog.i18n.CompactNumberFormatSymbols_nus', 'goog.i18n.CompactNumberFormatSymbols_nus_SS', 'goog.i18n.CompactNumberFormatSymbols_nyn', 'goog.i18n.CompactNumberFormatSymbols_nyn_UG', 'goog.i18n.CompactNumberFormatSymbols_om', 'goog.i18n.CompactNumberFormatSymbols_om_ET', 'goog.i18n.CompactNumberFormatSymbols_om_KE', 'goog.i18n.CompactNumberFormatSymbols_or_IN', 'goog.i18n.CompactNumberFormatSymbols_os', 'goog.i18n.CompactNumberFormatSymbols_os_GE', 'goog.i18n.CompactNumberFormatSymbols_os_RU', 'goog.i18n.CompactNumberFormatSymbols_pa_Arab', 'goog.i18n.CompactNumberFormatSymbols_pa_Arab_PK', 'goog.i18n.CompactNumberFormatSymbols_pa_Guru', 'goog.i18n.CompactNumberFormatSymbols_pa_Guru_IN', 'goog.i18n.CompactNumberFormatSymbols_pl_PL', 'goog.i18n.CompactNumberFormatSymbols_ps', 'goog.i18n.CompactNumberFormatSymbols_ps_AF', 'goog.i18n.CompactNumberFormatSymbols_pt_AO', 'goog.i18n.CompactNumberFormatSymbols_pt_CH', 'goog.i18n.CompactNumberFormatSymbols_pt_CV', 'goog.i18n.CompactNumberFormatSymbols_pt_GQ', 'goog.i18n.CompactNumberFormatSymbols_pt_GW', 'goog.i18n.CompactNumberFormatSymbols_pt_LU', 'goog.i18n.CompactNumberFormatSymbols_pt_MO', 'goog.i18n.CompactNumberFormatSymbols_pt_MZ', 'goog.i18n.CompactNumberFormatSymbols_pt_ST', 'goog.i18n.CompactNumberFormatSymbols_pt_TL', 'goog.i18n.CompactNumberFormatSymbols_qu', 'goog.i18n.CompactNumberFormatSymbols_qu_BO', 'goog.i18n.CompactNumberFormatSymbols_qu_EC', 'goog.i18n.CompactNumberFormatSymbols_qu_PE', 'goog.i18n.CompactNumberFormatSymbols_rm', 'goog.i18n.CompactNumberFormatSymbols_rm_CH', 'goog.i18n.CompactNumberFormatSymbols_rn', 'goog.i18n.CompactNumberFormatSymbols_rn_BI', 'goog.i18n.CompactNumberFormatSymbols_ro_MD', 'goog.i18n.CompactNumberFormatSymbols_ro_RO', 'goog.i18n.CompactNumberFormatSymbols_rof', 'goog.i18n.CompactNumberFormatSymbols_rof_TZ', 'goog.i18n.CompactNumberFormatSymbols_ru_BY', 'goog.i18n.CompactNumberFormatSymbols_ru_KG', 'goog.i18n.CompactNumberFormatSymbols_ru_KZ', 'goog.i18n.CompactNumberFormatSymbols_ru_MD', 'goog.i18n.CompactNumberFormatSymbols_ru_RU', 'goog.i18n.CompactNumberFormatSymbols_ru_UA', 'goog.i18n.CompactNumberFormatSymbols_rw', 'goog.i18n.CompactNumberFormatSymbols_rw_RW', 'goog.i18n.CompactNumberFormatSymbols_rwk', 'goog.i18n.CompactNumberFormatSymbols_rwk_TZ', 'goog.i18n.CompactNumberFormatSymbols_sah', 'goog.i18n.CompactNumberFormatSymbols_sah_RU', 'goog.i18n.CompactNumberFormatSymbols_saq', 'goog.i18n.CompactNumberFormatSymbols_saq_KE', 'goog.i18n.CompactNumberFormatSymbols_sbp', 'goog.i18n.CompactNumberFormatSymbols_sbp_TZ', 'goog.i18n.CompactNumberFormatSymbols_se', 'goog.i18n.CompactNumberFormatSymbols_se_FI', 'goog.i18n.CompactNumberFormatSymbols_se_NO', 'goog.i18n.CompactNumberFormatSymbols_se_SE', 'goog.i18n.CompactNumberFormatSymbols_seh', 'goog.i18n.CompactNumberFormatSymbols_seh_MZ', 'goog.i18n.CompactNumberFormatSymbols_ses', 'goog.i18n.CompactNumberFormatSymbols_ses_ML', 'goog.i18n.CompactNumberFormatSymbols_sg', 'goog.i18n.CompactNumberFormatSymbols_sg_CF', 'goog.i18n.CompactNumberFormatSymbols_shi', 'goog.i18n.CompactNumberFormatSymbols_shi_Latn', 'goog.i18n.CompactNumberFormatSymbols_shi_Latn_MA', 'goog.i18n.CompactNumberFormatSymbols_shi_Tfng', 'goog.i18n.CompactNumberFormatSymbols_shi_Tfng_MA', 'goog.i18n.CompactNumberFormatSymbols_si_LK', 'goog.i18n.CompactNumberFormatSymbols_sk_SK', 'goog.i18n.CompactNumberFormatSymbols_sl_SI', 'goog.i18n.CompactNumberFormatSymbols_smn', 'goog.i18n.CompactNumberFormatSymbols_smn_FI', 'goog.i18n.CompactNumberFormatSymbols_sn', 'goog.i18n.CompactNumberFormatSymbols_sn_ZW', 'goog.i18n.CompactNumberFormatSymbols_so', 'goog.i18n.CompactNumberFormatSymbols_so_DJ', 'goog.i18n.CompactNumberFormatSymbols_so_ET', 'goog.i18n.CompactNumberFormatSymbols_so_KE', 'goog.i18n.CompactNumberFormatSymbols_so_SO', 'goog.i18n.CompactNumberFormatSymbols_sq_AL', 'goog.i18n.CompactNumberFormatSymbols_sq_MK', 'goog.i18n.CompactNumberFormatSymbols_sq_XK', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_BA', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_ME', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_RS', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_XK', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_BA', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_ME', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_RS', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_XK', 'goog.i18n.CompactNumberFormatSymbols_sv_AX', 'goog.i18n.CompactNumberFormatSymbols_sv_FI', 'goog.i18n.CompactNumberFormatSymbols_sv_SE', 'goog.i18n.CompactNumberFormatSymbols_sw_CD', 'goog.i18n.CompactNumberFormatSymbols_sw_KE', 'goog.i18n.CompactNumberFormatSymbols_sw_TZ', 'goog.i18n.CompactNumberFormatSymbols_sw_UG', 'goog.i18n.CompactNumberFormatSymbols_ta_IN', 'goog.i18n.CompactNumberFormatSymbols_ta_LK', 'goog.i18n.CompactNumberFormatSymbols_ta_MY', 'goog.i18n.CompactNumberFormatSymbols_ta_SG', 'goog.i18n.CompactNumberFormatSymbols_te_IN', 'goog.i18n.CompactNumberFormatSymbols_teo', 'goog.i18n.CompactNumberFormatSymbols_teo_KE', 'goog.i18n.CompactNumberFormatSymbols_teo_UG', 'goog.i18n.CompactNumberFormatSymbols_th_TH', 'goog.i18n.CompactNumberFormatSymbols_ti', 'goog.i18n.CompactNumberFormatSymbols_ti_ER', 'goog.i18n.CompactNumberFormatSymbols_ti_ET', 'goog.i18n.CompactNumberFormatSymbols_to', 'goog.i18n.CompactNumberFormatSymbols_to_TO', 'goog.i18n.CompactNumberFormatSymbols_tr_CY', 'goog.i18n.CompactNumberFormatSymbols_tr_TR', 'goog.i18n.CompactNumberFormatSymbols_twq', 'goog.i18n.CompactNumberFormatSymbols_twq_NE', 'goog.i18n.CompactNumberFormatSymbols_tzm', 'goog.i18n.CompactNumberFormatSymbols_tzm_MA', 'goog.i18n.CompactNumberFormatSymbols_ug', 'goog.i18n.CompactNumberFormatSymbols_ug_CN', 'goog.i18n.CompactNumberFormatSymbols_uk_UA', 'goog.i18n.CompactNumberFormatSymbols_ur_IN', 'goog.i18n.CompactNumberFormatSymbols_ur_PK', 'goog.i18n.CompactNumberFormatSymbols_uz_Arab', 'goog.i18n.CompactNumberFormatSymbols_uz_Arab_AF', 'goog.i18n.CompactNumberFormatSymbols_uz_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_uz_Cyrl_UZ', 'goog.i18n.CompactNumberFormatSymbols_uz_Latn', 'goog.i18n.CompactNumberFormatSymbols_uz_Latn_UZ', 'goog.i18n.CompactNumberFormatSymbols_vai', 'goog.i18n.CompactNumberFormatSymbols_vai_Latn', 'goog.i18n.CompactNumberFormatSymbols_vai_Latn_LR', 'goog.i18n.CompactNumberFormatSymbols_vai_Vaii', 'goog.i18n.CompactNumberFormatSymbols_vai_Vaii_LR', 'goog.i18n.CompactNumberFormatSymbols_vi_VN', 'goog.i18n.CompactNumberFormatSymbols_vun', 'goog.i18n.CompactNumberFormatSymbols_vun_TZ', 'goog.i18n.CompactNumberFormatSymbols_wae', 'goog.i18n.CompactNumberFormatSymbols_wae_CH', 'goog.i18n.CompactNumberFormatSymbols_xog', 'goog.i18n.CompactNumberFormatSymbols_xog_UG', 'goog.i18n.CompactNumberFormatSymbols_yav', 'goog.i18n.CompactNumberFormatSymbols_yav_CM', 'goog.i18n.CompactNumberFormatSymbols_yi', 'goog.i18n.CompactNumberFormatSymbols_yi_001', 'goog.i18n.CompactNumberFormatSymbols_yo', 'goog.i18n.CompactNumberFormatSymbols_yo_BJ', 'goog.i18n.CompactNumberFormatSymbols_yo_NG', 'goog.i18n.CompactNumberFormatSymbols_yue', 'goog.i18n.CompactNumberFormatSymbols_yue_HK', 'goog.i18n.CompactNumberFormatSymbols_zgh', 'goog.i18n.CompactNumberFormatSymbols_zgh_MA', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_CN', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_MO', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_SG', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_MO', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_TW', 'goog.i18n.CompactNumberFormatSymbols_zu_ZA'], ['goog.i18n.CompactNumberFormatSymbols']);
                +goog.addDependency("i18n/currency.js", ['goog.i18n.currency', 'goog.i18n.currency.CurrencyInfo', 'goog.i18n.currency.CurrencyInfoTier2'], []);
                +goog.addDependency("i18n/currency_test.js", ['goog.i18n.currencyTest'], ['goog.i18n.NumberFormat', 'goog.i18n.currency', 'goog.i18n.currency.CurrencyInfo', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/currencycodemap.js", ['goog.i18n.currencyCodeMap', 'goog.i18n.currencyCodeMapTier2'], []);
                +goog.addDependency("i18n/dateintervalformat.js", [], []);
                +goog.addDependency("i18n/dateintervalformat_test.js", [], []);
                +goog.addDependency("i18n/dateintervalpatterns.js", [], []);
                +goog.addDependency("i18n/dateintervalpatternsext.js", [], []);
                +goog.addDependency("i18n/dateintervalsymbols.js", [], []);
                +goog.addDependency("i18n/dateintervalsymbolsext.js", [], []);
                +goog.addDependency("i18n/datetimeformat.js", ['goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeFormat.Format'], ['goog.asserts', 'goog.date', 'goog.i18n.DateTimeSymbols', 'goog.i18n.TimeZone', 'goog.string']);
                +goog.addDependency("i18n/datetimeformat_test.js", ['goog.i18n.DateTimeFormatTest'], ['goog.date.Date', 'goog.date.DateTime', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns', 'goog.i18n.DateTimePatterns_ar', 'goog.i18n.DateTimePatterns_de', 'goog.i18n.DateTimePatterns_en', 'goog.i18n.DateTimePatterns_fa', 'goog.i18n.DateTimePatterns_fr', 'goog.i18n.DateTimePatterns_ja', 'goog.i18n.DateTimePatterns_sv', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_ar', 'goog.i18n.DateTimeSymbols_ar_AE', 'goog.i18n.DateTimeSymbols_ar_SA', 'goog.i18n.DateTimeSymbols_bn_BD', 'goog.i18n.DateTimeSymbols_de', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_en_GB', 'goog.i18n.DateTimeSymbols_en_IE', 'goog.i18n.DateTimeSymbols_en_IN', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_fr_DJ', 'goog.i18n.DateTimeSymbols_he_IL', 'goog.i18n.DateTimeSymbols_ja', 'goog.i18n.DateTimeSymbols_ro_RO', 'goog.i18n.DateTimeSymbols_sv', 'goog.i18n.TimeZone', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/datetimeparse.js", ['goog.i18n.DateTimeParse'], ['goog.asserts', 'goog.date', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols']);
                +goog.addDependency("i18n/datetimeparse_test.js", ['goog.i18n.DateTimeParseTest'], ['goog.date.Date', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeParse', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_pl', 'goog.i18n.DateTimeSymbols_zh', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("i18n/datetimepatterns.js", ['goog.i18n.DateTimePatterns', 'goog.i18n.DateTimePatterns_af', 'goog.i18n.DateTimePatterns_am', 'goog.i18n.DateTimePatterns_ar', 'goog.i18n.DateTimePatterns_ar_DZ', 'goog.i18n.DateTimePatterns_az', 'goog.i18n.DateTimePatterns_be', 'goog.i18n.DateTimePatterns_bg', 'goog.i18n.DateTimePatterns_bn', 'goog.i18n.DateTimePatterns_br', 'goog.i18n.DateTimePatterns_bs', 'goog.i18n.DateTimePatterns_ca', 'goog.i18n.DateTimePatterns_chr', 'goog.i18n.DateTimePatterns_cs', 'goog.i18n.DateTimePatterns_cy', 'goog.i18n.DateTimePatterns_da', 'goog.i18n.DateTimePatterns_de', 'goog.i18n.DateTimePatterns_de_AT', 'goog.i18n.DateTimePatterns_de_CH', 'goog.i18n.DateTimePatterns_el', 'goog.i18n.DateTimePatterns_en', 'goog.i18n.DateTimePatterns_en_AU', 'goog.i18n.DateTimePatterns_en_CA', 'goog.i18n.DateTimePatterns_en_GB', 'goog.i18n.DateTimePatterns_en_IE', 'goog.i18n.DateTimePatterns_en_IN', 'goog.i18n.DateTimePatterns_en_SG', 'goog.i18n.DateTimePatterns_en_US', 'goog.i18n.DateTimePatterns_en_ZA', 'goog.i18n.DateTimePatterns_es', 'goog.i18n.DateTimePatterns_es_419', 'goog.i18n.DateTimePatterns_es_ES', 'goog.i18n.DateTimePatterns_es_MX', 'goog.i18n.DateTimePatterns_es_US', 'goog.i18n.DateTimePatterns_et', 'goog.i18n.DateTimePatterns_eu', 'goog.i18n.DateTimePatterns_fa', 'goog.i18n.DateTimePatterns_fi', 'goog.i18n.DateTimePatterns_fil', 'goog.i18n.DateTimePatterns_fr', 'goog.i18n.DateTimePatterns_fr_CA', 'goog.i18n.DateTimePatterns_ga', 'goog.i18n.DateTimePatterns_gl', 'goog.i18n.DateTimePatterns_gsw', 'goog.i18n.DateTimePatterns_gu', 'goog.i18n.DateTimePatterns_haw', 'goog.i18n.DateTimePatterns_he', 'goog.i18n.DateTimePatterns_hi', 'goog.i18n.DateTimePatterns_hr', 'goog.i18n.DateTimePatterns_hu', 'goog.i18n.DateTimePatterns_hy', 'goog.i18n.DateTimePatterns_id', 'goog.i18n.DateTimePatterns_in', 'goog.i18n.DateTimePatterns_is', 'goog.i18n.DateTimePatterns_it', 'goog.i18n.DateTimePatterns_iw', 'goog.i18n.DateTimePatterns_ja', 'goog.i18n.DateTimePatterns_ka', 'goog.i18n.DateTimePatterns_kk', 'goog.i18n.DateTimePatterns_km', 'goog.i18n.DateTimePatterns_kn', 'goog.i18n.DateTimePatterns_ko', 'goog.i18n.DateTimePatterns_ky', 'goog.i18n.DateTimePatterns_ln', 'goog.i18n.DateTimePatterns_lo', 'goog.i18n.DateTimePatterns_lt', 'goog.i18n.DateTimePatterns_lv', 'goog.i18n.DateTimePatterns_mk', 'goog.i18n.DateTimePatterns_ml', 'goog.i18n.DateTimePatterns_mn', 'goog.i18n.DateTimePatterns_mo', 'goog.i18n.DateTimePatterns_mr', 'goog.i18n.DateTimePatterns_ms', 'goog.i18n.DateTimePatterns_mt', 'goog.i18n.DateTimePatterns_my', 'goog.i18n.DateTimePatterns_nb', 'goog.i18n.DateTimePatterns_ne', 'goog.i18n.DateTimePatterns_nl', 'goog.i18n.DateTimePatterns_no', 'goog.i18n.DateTimePatterns_no_NO', 'goog.i18n.DateTimePatterns_or', 'goog.i18n.DateTimePatterns_pa', 'goog.i18n.DateTimePatterns_pl', 'goog.i18n.DateTimePatterns_pt', 'goog.i18n.DateTimePatterns_pt_BR', 'goog.i18n.DateTimePatterns_pt_PT', 'goog.i18n.DateTimePatterns_ro', 'goog.i18n.DateTimePatterns_ru', 'goog.i18n.DateTimePatterns_sh', 'goog.i18n.DateTimePatterns_si', 'goog.i18n.DateTimePatterns_sk', 'goog.i18n.DateTimePatterns_sl', 'goog.i18n.DateTimePatterns_sq', 'goog.i18n.DateTimePatterns_sr', 'goog.i18n.DateTimePatterns_sr_Latn', 'goog.i18n.DateTimePatterns_sv', 'goog.i18n.DateTimePatterns_sw', 'goog.i18n.DateTimePatterns_ta', 'goog.i18n.DateTimePatterns_te', 'goog.i18n.DateTimePatterns_th', 'goog.i18n.DateTimePatterns_tl', 'goog.i18n.DateTimePatterns_tr', 'goog.i18n.DateTimePatterns_uk', 'goog.i18n.DateTimePatterns_ur', 'goog.i18n.DateTimePatterns_uz', 'goog.i18n.DateTimePatterns_vi', 'goog.i18n.DateTimePatterns_zh', 'goog.i18n.DateTimePatterns_zh_CN', 'goog.i18n.DateTimePatterns_zh_HK', 'goog.i18n.DateTimePatterns_zh_TW', 'goog.i18n.DateTimePatterns_zu'], []);
                +goog.addDependency("i18n/datetimepatternsext.js", ['goog.i18n.DateTimePatternsExt', 'goog.i18n.DateTimePatterns_af_NA', 'goog.i18n.DateTimePatterns_af_ZA', 'goog.i18n.DateTimePatterns_agq', 'goog.i18n.DateTimePatterns_agq_CM', 'goog.i18n.DateTimePatterns_ak', 'goog.i18n.DateTimePatterns_ak_GH', 'goog.i18n.DateTimePatterns_am_ET', 'goog.i18n.DateTimePatterns_ar_001', 'goog.i18n.DateTimePatterns_ar_AE', 'goog.i18n.DateTimePatterns_ar_BH', 'goog.i18n.DateTimePatterns_ar_DJ', 'goog.i18n.DateTimePatterns_ar_EG', 'goog.i18n.DateTimePatterns_ar_EH', 'goog.i18n.DateTimePatterns_ar_ER', 'goog.i18n.DateTimePatterns_ar_IL', 'goog.i18n.DateTimePatterns_ar_IQ', 'goog.i18n.DateTimePatterns_ar_JO', 'goog.i18n.DateTimePatterns_ar_KM', 'goog.i18n.DateTimePatterns_ar_KW', 'goog.i18n.DateTimePatterns_ar_LB', 'goog.i18n.DateTimePatterns_ar_LY', 'goog.i18n.DateTimePatterns_ar_MA', 'goog.i18n.DateTimePatterns_ar_MR', 'goog.i18n.DateTimePatterns_ar_OM', 'goog.i18n.DateTimePatterns_ar_PS', 'goog.i18n.DateTimePatterns_ar_QA', 'goog.i18n.DateTimePatterns_ar_SA', 'goog.i18n.DateTimePatterns_ar_SD', 'goog.i18n.DateTimePatterns_ar_SO', 'goog.i18n.DateTimePatterns_ar_SS', 'goog.i18n.DateTimePatterns_ar_SY', 'goog.i18n.DateTimePatterns_ar_TD', 'goog.i18n.DateTimePatterns_ar_TN', 'goog.i18n.DateTimePatterns_ar_XB', 'goog.i18n.DateTimePatterns_ar_YE', 'goog.i18n.DateTimePatterns_as', 'goog.i18n.DateTimePatterns_as_IN', 'goog.i18n.DateTimePatterns_asa', 'goog.i18n.DateTimePatterns_asa_TZ', 'goog.i18n.DateTimePatterns_ast', 'goog.i18n.DateTimePatterns_ast_ES', 'goog.i18n.DateTimePatterns_az_Cyrl', 'goog.i18n.DateTimePatterns_az_Cyrl_AZ', 'goog.i18n.DateTimePatterns_az_Latn', 'goog.i18n.DateTimePatterns_az_Latn_AZ', 'goog.i18n.DateTimePatterns_bas', 'goog.i18n.DateTimePatterns_bas_CM', 'goog.i18n.DateTimePatterns_be_BY', 'goog.i18n.DateTimePatterns_bem', 'goog.i18n.DateTimePatterns_bem_ZM', 'goog.i18n.DateTimePatterns_bez', 'goog.i18n.DateTimePatterns_bez_TZ', 'goog.i18n.DateTimePatterns_bg_BG', 'goog.i18n.DateTimePatterns_bm', 'goog.i18n.DateTimePatterns_bm_ML', 'goog.i18n.DateTimePatterns_bn_BD', 'goog.i18n.DateTimePatterns_bn_IN', 'goog.i18n.DateTimePatterns_bo', 'goog.i18n.DateTimePatterns_bo_CN', 'goog.i18n.DateTimePatterns_bo_IN', 'goog.i18n.DateTimePatterns_br_FR', 'goog.i18n.DateTimePatterns_brx', 'goog.i18n.DateTimePatterns_brx_IN', 'goog.i18n.DateTimePatterns_bs_Cyrl', 'goog.i18n.DateTimePatterns_bs_Cyrl_BA', 'goog.i18n.DateTimePatterns_bs_Latn', 'goog.i18n.DateTimePatterns_bs_Latn_BA', 'goog.i18n.DateTimePatterns_ca_AD', 'goog.i18n.DateTimePatterns_ca_ES', 'goog.i18n.DateTimePatterns_ca_FR', 'goog.i18n.DateTimePatterns_ca_IT', 'goog.i18n.DateTimePatterns_ce', 'goog.i18n.DateTimePatterns_ce_RU', 'goog.i18n.DateTimePatterns_cgg', 'goog.i18n.DateTimePatterns_cgg_UG', 'goog.i18n.DateTimePatterns_chr_US', 'goog.i18n.DateTimePatterns_ckb', 'goog.i18n.DateTimePatterns_ckb_IQ', 'goog.i18n.DateTimePatterns_ckb_IR', 'goog.i18n.DateTimePatterns_cs_CZ', 'goog.i18n.DateTimePatterns_cy_GB', 'goog.i18n.DateTimePatterns_da_DK', 'goog.i18n.DateTimePatterns_da_GL', 'goog.i18n.DateTimePatterns_dav', 'goog.i18n.DateTimePatterns_dav_KE', 'goog.i18n.DateTimePatterns_de_BE', 'goog.i18n.DateTimePatterns_de_DE', 'goog.i18n.DateTimePatterns_de_IT', 'goog.i18n.DateTimePatterns_de_LI', 'goog.i18n.DateTimePatterns_de_LU', 'goog.i18n.DateTimePatterns_dje', 'goog.i18n.DateTimePatterns_dje_NE', 'goog.i18n.DateTimePatterns_dsb', 'goog.i18n.DateTimePatterns_dsb_DE', 'goog.i18n.DateTimePatterns_dua', 'goog.i18n.DateTimePatterns_dua_CM', 'goog.i18n.DateTimePatterns_dyo', 'goog.i18n.DateTimePatterns_dyo_SN', 'goog.i18n.DateTimePatterns_dz', 'goog.i18n.DateTimePatterns_dz_BT', 'goog.i18n.DateTimePatterns_ebu', 'goog.i18n.DateTimePatterns_ebu_KE', 'goog.i18n.DateTimePatterns_ee', 'goog.i18n.DateTimePatterns_ee_GH', 'goog.i18n.DateTimePatterns_ee_TG', 'goog.i18n.DateTimePatterns_el_CY', 'goog.i18n.DateTimePatterns_el_GR', 'goog.i18n.DateTimePatterns_en_001', 'goog.i18n.DateTimePatterns_en_150', 'goog.i18n.DateTimePatterns_en_AG', 'goog.i18n.DateTimePatterns_en_AI', 'goog.i18n.DateTimePatterns_en_AS', 'goog.i18n.DateTimePatterns_en_AT', 'goog.i18n.DateTimePatterns_en_BB', 'goog.i18n.DateTimePatterns_en_BE', 'goog.i18n.DateTimePatterns_en_BI', 'goog.i18n.DateTimePatterns_en_BM', 'goog.i18n.DateTimePatterns_en_BS', 'goog.i18n.DateTimePatterns_en_BW', 'goog.i18n.DateTimePatterns_en_BZ', 'goog.i18n.DateTimePatterns_en_CC', 'goog.i18n.DateTimePatterns_en_CH', 'goog.i18n.DateTimePatterns_en_CK', 'goog.i18n.DateTimePatterns_en_CM', 'goog.i18n.DateTimePatterns_en_CX', 'goog.i18n.DateTimePatterns_en_CY', 'goog.i18n.DateTimePatterns_en_DE', 'goog.i18n.DateTimePatterns_en_DG', 'goog.i18n.DateTimePatterns_en_DK', 'goog.i18n.DateTimePatterns_en_DM', 'goog.i18n.DateTimePatterns_en_ER', 'goog.i18n.DateTimePatterns_en_FI', 'goog.i18n.DateTimePatterns_en_FJ', 'goog.i18n.DateTimePatterns_en_FK', 'goog.i18n.DateTimePatterns_en_FM', 'goog.i18n.DateTimePatterns_en_GD', 'goog.i18n.DateTimePatterns_en_GG', 'goog.i18n.DateTimePatterns_en_GH', 'goog.i18n.DateTimePatterns_en_GI', 'goog.i18n.DateTimePatterns_en_GM', 'goog.i18n.DateTimePatterns_en_GU', 'goog.i18n.DateTimePatterns_en_GY', 'goog.i18n.DateTimePatterns_en_HK', 'goog.i18n.DateTimePatterns_en_IL', 'goog.i18n.DateTimePatterns_en_IM', 'goog.i18n.DateTimePatterns_en_IO', 'goog.i18n.DateTimePatterns_en_JE', 'goog.i18n.DateTimePatterns_en_JM', 'goog.i18n.DateTimePatterns_en_KE', 'goog.i18n.DateTimePatterns_en_KI', 'goog.i18n.DateTimePatterns_en_KN', 'goog.i18n.DateTimePatterns_en_KY', 'goog.i18n.DateTimePatterns_en_LC', 'goog.i18n.DateTimePatterns_en_LR', 'goog.i18n.DateTimePatterns_en_LS', 'goog.i18n.DateTimePatterns_en_MG', 'goog.i18n.DateTimePatterns_en_MH', 'goog.i18n.DateTimePatterns_en_MO', 'goog.i18n.DateTimePatterns_en_MP', 'goog.i18n.DateTimePatterns_en_MS', 'goog.i18n.DateTimePatterns_en_MT', 'goog.i18n.DateTimePatterns_en_MU', 'goog.i18n.DateTimePatterns_en_MW', 'goog.i18n.DateTimePatterns_en_MY', 'goog.i18n.DateTimePatterns_en_NA', 'goog.i18n.DateTimePatterns_en_NF', 'goog.i18n.DateTimePatterns_en_NG', 'goog.i18n.DateTimePatterns_en_NL', 'goog.i18n.DateTimePatterns_en_NR', 'goog.i18n.DateTimePatterns_en_NU', 'goog.i18n.DateTimePatterns_en_NZ', 'goog.i18n.DateTimePatterns_en_PG', 'goog.i18n.DateTimePatterns_en_PH', 'goog.i18n.DateTimePatterns_en_PK', 'goog.i18n.DateTimePatterns_en_PN', 'goog.i18n.DateTimePatterns_en_PR', 'goog.i18n.DateTimePatterns_en_PW', 'goog.i18n.DateTimePatterns_en_RW', 'goog.i18n.DateTimePatterns_en_SB', 'goog.i18n.DateTimePatterns_en_SC', 'goog.i18n.DateTimePatterns_en_SD', 'goog.i18n.DateTimePatterns_en_SE', 'goog.i18n.DateTimePatterns_en_SH', 'goog.i18n.DateTimePatterns_en_SI', 'goog.i18n.DateTimePatterns_en_SL', 'goog.i18n.DateTimePatterns_en_SS', 'goog.i18n.DateTimePatterns_en_SX', 'goog.i18n.DateTimePatterns_en_SZ', 'goog.i18n.DateTimePatterns_en_TC', 'goog.i18n.DateTimePatterns_en_TK', 'goog.i18n.DateTimePatterns_en_TO', 'goog.i18n.DateTimePatterns_en_TT', 'goog.i18n.DateTimePatterns_en_TV', 'goog.i18n.DateTimePatterns_en_TZ', 'goog.i18n.DateTimePatterns_en_UG', 'goog.i18n.DateTimePatterns_en_UM', 'goog.i18n.DateTimePatterns_en_US_POSIX', 'goog.i18n.DateTimePatterns_en_VC', 'goog.i18n.DateTimePatterns_en_VG', 'goog.i18n.DateTimePatterns_en_VI', 'goog.i18n.DateTimePatterns_en_VU', 'goog.i18n.DateTimePatterns_en_WS', 'goog.i18n.DateTimePatterns_en_XA', 'goog.i18n.DateTimePatterns_en_ZM', 'goog.i18n.DateTimePatterns_en_ZW', 'goog.i18n.DateTimePatterns_eo', 'goog.i18n.DateTimePatterns_es_AR', 'goog.i18n.DateTimePatterns_es_BO', 'goog.i18n.DateTimePatterns_es_BR', 'goog.i18n.DateTimePatterns_es_CL', 'goog.i18n.DateTimePatterns_es_CO', 'goog.i18n.DateTimePatterns_es_CR', 'goog.i18n.DateTimePatterns_es_CU', 'goog.i18n.DateTimePatterns_es_DO', 'goog.i18n.DateTimePatterns_es_EA', 'goog.i18n.DateTimePatterns_es_EC', 'goog.i18n.DateTimePatterns_es_GQ', 'goog.i18n.DateTimePatterns_es_GT', 'goog.i18n.DateTimePatterns_es_HN', 'goog.i18n.DateTimePatterns_es_IC', 'goog.i18n.DateTimePatterns_es_NI', 'goog.i18n.DateTimePatterns_es_PA', 'goog.i18n.DateTimePatterns_es_PE', 'goog.i18n.DateTimePatterns_es_PH', 'goog.i18n.DateTimePatterns_es_PR', 'goog.i18n.DateTimePatterns_es_PY', 'goog.i18n.DateTimePatterns_es_SV', 'goog.i18n.DateTimePatterns_es_UY', 'goog.i18n.DateTimePatterns_es_VE', 'goog.i18n.DateTimePatterns_et_EE', 'goog.i18n.DateTimePatterns_eu_ES', 'goog.i18n.DateTimePatterns_ewo', 'goog.i18n.DateTimePatterns_ewo_CM', 'goog.i18n.DateTimePatterns_fa_AF', 'goog.i18n.DateTimePatterns_fa_IR', 'goog.i18n.DateTimePatterns_ff', 'goog.i18n.DateTimePatterns_ff_CM', 'goog.i18n.DateTimePatterns_ff_GN', 'goog.i18n.DateTimePatterns_ff_MR', 'goog.i18n.DateTimePatterns_ff_SN', 'goog.i18n.DateTimePatterns_fi_FI', 'goog.i18n.DateTimePatterns_fil_PH', 'goog.i18n.DateTimePatterns_fo', 'goog.i18n.DateTimePatterns_fo_DK', 'goog.i18n.DateTimePatterns_fo_FO', 'goog.i18n.DateTimePatterns_fr_BE', 'goog.i18n.DateTimePatterns_fr_BF', 'goog.i18n.DateTimePatterns_fr_BI', 'goog.i18n.DateTimePatterns_fr_BJ', 'goog.i18n.DateTimePatterns_fr_BL', 'goog.i18n.DateTimePatterns_fr_CD', 'goog.i18n.DateTimePatterns_fr_CF', 'goog.i18n.DateTimePatterns_fr_CG', 'goog.i18n.DateTimePatterns_fr_CH', 'goog.i18n.DateTimePatterns_fr_CI', 'goog.i18n.DateTimePatterns_fr_CM', 'goog.i18n.DateTimePatterns_fr_DJ', 'goog.i18n.DateTimePatterns_fr_DZ', 'goog.i18n.DateTimePatterns_fr_FR', 'goog.i18n.DateTimePatterns_fr_GA', 'goog.i18n.DateTimePatterns_fr_GF', 'goog.i18n.DateTimePatterns_fr_GN', 'goog.i18n.DateTimePatterns_fr_GP', 'goog.i18n.DateTimePatterns_fr_GQ', 'goog.i18n.DateTimePatterns_fr_HT', 'goog.i18n.DateTimePatterns_fr_KM', 'goog.i18n.DateTimePatterns_fr_LU', 'goog.i18n.DateTimePatterns_fr_MA', 'goog.i18n.DateTimePatterns_fr_MC', 'goog.i18n.DateTimePatterns_fr_MF', 'goog.i18n.DateTimePatterns_fr_MG', 'goog.i18n.DateTimePatterns_fr_ML', 'goog.i18n.DateTimePatterns_fr_MQ', 'goog.i18n.DateTimePatterns_fr_MR', 'goog.i18n.DateTimePatterns_fr_MU', 'goog.i18n.DateTimePatterns_fr_NC', 'goog.i18n.DateTimePatterns_fr_NE', 'goog.i18n.DateTimePatterns_fr_PF', 'goog.i18n.DateTimePatterns_fr_PM', 'goog.i18n.DateTimePatterns_fr_RE', 'goog.i18n.DateTimePatterns_fr_RW', 'goog.i18n.DateTimePatterns_fr_SC', 'goog.i18n.DateTimePatterns_fr_SN', 'goog.i18n.DateTimePatterns_fr_SY', 'goog.i18n.DateTimePatterns_fr_TD', 'goog.i18n.DateTimePatterns_fr_TG', 'goog.i18n.DateTimePatterns_fr_TN', 'goog.i18n.DateTimePatterns_fr_VU', 'goog.i18n.DateTimePatterns_fr_WF', 'goog.i18n.DateTimePatterns_fr_YT', 'goog.i18n.DateTimePatterns_fur', 'goog.i18n.DateTimePatterns_fur_IT', 'goog.i18n.DateTimePatterns_fy', 'goog.i18n.DateTimePatterns_fy_NL', 'goog.i18n.DateTimePatterns_ga_IE', 'goog.i18n.DateTimePatterns_gd', 'goog.i18n.DateTimePatterns_gd_GB', 'goog.i18n.DateTimePatterns_gl_ES', 'goog.i18n.DateTimePatterns_gsw_CH', 'goog.i18n.DateTimePatterns_gsw_FR', 'goog.i18n.DateTimePatterns_gsw_LI', 'goog.i18n.DateTimePatterns_gu_IN', 'goog.i18n.DateTimePatterns_guz', 'goog.i18n.DateTimePatterns_guz_KE', 'goog.i18n.DateTimePatterns_gv', 'goog.i18n.DateTimePatterns_gv_IM', 'goog.i18n.DateTimePatterns_ha', 'goog.i18n.DateTimePatterns_ha_GH', 'goog.i18n.DateTimePatterns_ha_NE', 'goog.i18n.DateTimePatterns_ha_NG', 'goog.i18n.DateTimePatterns_haw_US', 'goog.i18n.DateTimePatterns_he_IL', 'goog.i18n.DateTimePatterns_hi_IN', 'goog.i18n.DateTimePatterns_hr_BA', 'goog.i18n.DateTimePatterns_hr_HR', 'goog.i18n.DateTimePatterns_hsb', 'goog.i18n.DateTimePatterns_hsb_DE', 'goog.i18n.DateTimePatterns_hu_HU', 'goog.i18n.DateTimePatterns_hy_AM', 'goog.i18n.DateTimePatterns_id_ID', 'goog.i18n.DateTimePatterns_ig', 'goog.i18n.DateTimePatterns_ig_NG', 'goog.i18n.DateTimePatterns_ii', 'goog.i18n.DateTimePatterns_ii_CN', 'goog.i18n.DateTimePatterns_is_IS', 'goog.i18n.DateTimePatterns_it_CH', 'goog.i18n.DateTimePatterns_it_IT', 'goog.i18n.DateTimePatterns_it_SM', 'goog.i18n.DateTimePatterns_ja_JP', 'goog.i18n.DateTimePatterns_jgo', 'goog.i18n.DateTimePatterns_jgo_CM', 'goog.i18n.DateTimePatterns_jmc', 'goog.i18n.DateTimePatterns_jmc_TZ', 'goog.i18n.DateTimePatterns_ka_GE', 'goog.i18n.DateTimePatterns_kab', 'goog.i18n.DateTimePatterns_kab_DZ', 'goog.i18n.DateTimePatterns_kam', 'goog.i18n.DateTimePatterns_kam_KE', 'goog.i18n.DateTimePatterns_kde', 'goog.i18n.DateTimePatterns_kde_TZ', 'goog.i18n.DateTimePatterns_kea', 'goog.i18n.DateTimePatterns_kea_CV', 'goog.i18n.DateTimePatterns_khq', 'goog.i18n.DateTimePatterns_khq_ML', 'goog.i18n.DateTimePatterns_ki', 'goog.i18n.DateTimePatterns_ki_KE', 'goog.i18n.DateTimePatterns_kk_KZ', 'goog.i18n.DateTimePatterns_kkj', 'goog.i18n.DateTimePatterns_kkj_CM', 'goog.i18n.DateTimePatterns_kl', 'goog.i18n.DateTimePatterns_kl_GL', 'goog.i18n.DateTimePatterns_kln', 'goog.i18n.DateTimePatterns_kln_KE', 'goog.i18n.DateTimePatterns_km_KH', 'goog.i18n.DateTimePatterns_kn_IN', 'goog.i18n.DateTimePatterns_ko_KP', 'goog.i18n.DateTimePatterns_ko_KR', 'goog.i18n.DateTimePatterns_kok', 'goog.i18n.DateTimePatterns_kok_IN', 'goog.i18n.DateTimePatterns_ks', 'goog.i18n.DateTimePatterns_ks_IN', 'goog.i18n.DateTimePatterns_ksb', 'goog.i18n.DateTimePatterns_ksb_TZ', 'goog.i18n.DateTimePatterns_ksf', 'goog.i18n.DateTimePatterns_ksf_CM', 'goog.i18n.DateTimePatterns_ksh', 'goog.i18n.DateTimePatterns_ksh_DE', 'goog.i18n.DateTimePatterns_kw', 'goog.i18n.DateTimePatterns_kw_GB', 'goog.i18n.DateTimePatterns_ky_KG', 'goog.i18n.DateTimePatterns_lag', 'goog.i18n.DateTimePatterns_lag_TZ', 'goog.i18n.DateTimePatterns_lb', 'goog.i18n.DateTimePatterns_lb_LU', 'goog.i18n.DateTimePatterns_lg', 'goog.i18n.DateTimePatterns_lg_UG', 'goog.i18n.DateTimePatterns_lkt', 'goog.i18n.DateTimePatterns_lkt_US', 'goog.i18n.DateTimePatterns_ln_AO', 'goog.i18n.DateTimePatterns_ln_CD', 'goog.i18n.DateTimePatterns_ln_CF', 'goog.i18n.DateTimePatterns_ln_CG', 'goog.i18n.DateTimePatterns_lo_LA', 'goog.i18n.DateTimePatterns_lrc', 'goog.i18n.DateTimePatterns_lrc_IQ', 'goog.i18n.DateTimePatterns_lrc_IR', 'goog.i18n.DateTimePatterns_lt_LT', 'goog.i18n.DateTimePatterns_lu', 'goog.i18n.DateTimePatterns_lu_CD', 'goog.i18n.DateTimePatterns_luo', 'goog.i18n.DateTimePatterns_luo_KE', 'goog.i18n.DateTimePatterns_luy', 'goog.i18n.DateTimePatterns_luy_KE', 'goog.i18n.DateTimePatterns_lv_LV', 'goog.i18n.DateTimePatterns_mas', 'goog.i18n.DateTimePatterns_mas_KE', 'goog.i18n.DateTimePatterns_mas_TZ', 'goog.i18n.DateTimePatterns_mer', 'goog.i18n.DateTimePatterns_mer_KE', 'goog.i18n.DateTimePatterns_mfe', 'goog.i18n.DateTimePatterns_mfe_MU', 'goog.i18n.DateTimePatterns_mg', 'goog.i18n.DateTimePatterns_mg_MG', 'goog.i18n.DateTimePatterns_mgh', 'goog.i18n.DateTimePatterns_mgh_MZ', 'goog.i18n.DateTimePatterns_mgo', 'goog.i18n.DateTimePatterns_mgo_CM', 'goog.i18n.DateTimePatterns_mk_MK', 'goog.i18n.DateTimePatterns_ml_IN', 'goog.i18n.DateTimePatterns_mn_MN', 'goog.i18n.DateTimePatterns_mr_IN', 'goog.i18n.DateTimePatterns_ms_BN', 'goog.i18n.DateTimePatterns_ms_MY', 'goog.i18n.DateTimePatterns_ms_SG', 'goog.i18n.DateTimePatterns_mt_MT', 'goog.i18n.DateTimePatterns_mua', 'goog.i18n.DateTimePatterns_mua_CM', 'goog.i18n.DateTimePatterns_my_MM', 'goog.i18n.DateTimePatterns_mzn', 'goog.i18n.DateTimePatterns_mzn_IR', 'goog.i18n.DateTimePatterns_naq', 'goog.i18n.DateTimePatterns_naq_NA', 'goog.i18n.DateTimePatterns_nb_NO', 'goog.i18n.DateTimePatterns_nb_SJ', 'goog.i18n.DateTimePatterns_nd', 'goog.i18n.DateTimePatterns_nd_ZW', 'goog.i18n.DateTimePatterns_nds', 'goog.i18n.DateTimePatterns_nds_DE', 'goog.i18n.DateTimePatterns_nds_NL', 'goog.i18n.DateTimePatterns_ne_IN', 'goog.i18n.DateTimePatterns_ne_NP', 'goog.i18n.DateTimePatterns_nl_AW', 'goog.i18n.DateTimePatterns_nl_BE', 'goog.i18n.DateTimePatterns_nl_BQ', 'goog.i18n.DateTimePatterns_nl_CW', 'goog.i18n.DateTimePatterns_nl_NL', 'goog.i18n.DateTimePatterns_nl_SR', 'goog.i18n.DateTimePatterns_nl_SX', 'goog.i18n.DateTimePatterns_nmg', 'goog.i18n.DateTimePatterns_nmg_CM', 'goog.i18n.DateTimePatterns_nn', 'goog.i18n.DateTimePatterns_nn_NO', 'goog.i18n.DateTimePatterns_nnh', 'goog.i18n.DateTimePatterns_nnh_CM', 'goog.i18n.DateTimePatterns_nus', 'goog.i18n.DateTimePatterns_nus_SS', 'goog.i18n.DateTimePatterns_nyn', 'goog.i18n.DateTimePatterns_nyn_UG', 'goog.i18n.DateTimePatterns_om', 'goog.i18n.DateTimePatterns_om_ET', 'goog.i18n.DateTimePatterns_om_KE', 'goog.i18n.DateTimePatterns_or_IN', 'goog.i18n.DateTimePatterns_os', 'goog.i18n.DateTimePatterns_os_GE', 'goog.i18n.DateTimePatterns_os_RU', 'goog.i18n.DateTimePatterns_pa_Arab', 'goog.i18n.DateTimePatterns_pa_Arab_PK', 'goog.i18n.DateTimePatterns_pa_Guru', 'goog.i18n.DateTimePatterns_pa_Guru_IN', 'goog.i18n.DateTimePatterns_pl_PL', 'goog.i18n.DateTimePatterns_ps', 'goog.i18n.DateTimePatterns_ps_AF', 'goog.i18n.DateTimePatterns_pt_AO', 'goog.i18n.DateTimePatterns_pt_CH', 'goog.i18n.DateTimePatterns_pt_CV', 'goog.i18n.DateTimePatterns_pt_GQ', 'goog.i18n.DateTimePatterns_pt_GW', 'goog.i18n.DateTimePatterns_pt_LU', 'goog.i18n.DateTimePatterns_pt_MO', 'goog.i18n.DateTimePatterns_pt_MZ', 'goog.i18n.DateTimePatterns_pt_ST', 'goog.i18n.DateTimePatterns_pt_TL', 'goog.i18n.DateTimePatterns_qu', 'goog.i18n.DateTimePatterns_qu_BO', 'goog.i18n.DateTimePatterns_qu_EC', 'goog.i18n.DateTimePatterns_qu_PE', 'goog.i18n.DateTimePatterns_rm', 'goog.i18n.DateTimePatterns_rm_CH', 'goog.i18n.DateTimePatterns_rn', 'goog.i18n.DateTimePatterns_rn_BI', 'goog.i18n.DateTimePatterns_ro_MD', 'goog.i18n.DateTimePatterns_ro_RO', 'goog.i18n.DateTimePatterns_rof', 'goog.i18n.DateTimePatterns_rof_TZ', 'goog.i18n.DateTimePatterns_ru_BY', 'goog.i18n.DateTimePatterns_ru_KG', 'goog.i18n.DateTimePatterns_ru_KZ', 'goog.i18n.DateTimePatterns_ru_MD', 'goog.i18n.DateTimePatterns_ru_RU', 'goog.i18n.DateTimePatterns_ru_UA', 'goog.i18n.DateTimePatterns_rw', 'goog.i18n.DateTimePatterns_rw_RW', 'goog.i18n.DateTimePatterns_rwk', 'goog.i18n.DateTimePatterns_rwk_TZ', 'goog.i18n.DateTimePatterns_sah', 'goog.i18n.DateTimePatterns_sah_RU', 'goog.i18n.DateTimePatterns_saq', 'goog.i18n.DateTimePatterns_saq_KE', 'goog.i18n.DateTimePatterns_sbp', 'goog.i18n.DateTimePatterns_sbp_TZ', 'goog.i18n.DateTimePatterns_se', 'goog.i18n.DateTimePatterns_se_FI', 'goog.i18n.DateTimePatterns_se_NO', 'goog.i18n.DateTimePatterns_se_SE', 'goog.i18n.DateTimePatterns_seh', 'goog.i18n.DateTimePatterns_seh_MZ', 'goog.i18n.DateTimePatterns_ses', 'goog.i18n.DateTimePatterns_ses_ML', 'goog.i18n.DateTimePatterns_sg', 'goog.i18n.DateTimePatterns_sg_CF', 'goog.i18n.DateTimePatterns_shi', 'goog.i18n.DateTimePatterns_shi_Latn', 'goog.i18n.DateTimePatterns_shi_Latn_MA', 'goog.i18n.DateTimePatterns_shi_Tfng', 'goog.i18n.DateTimePatterns_shi_Tfng_MA', 'goog.i18n.DateTimePatterns_si_LK', 'goog.i18n.DateTimePatterns_sk_SK', 'goog.i18n.DateTimePatterns_sl_SI', 'goog.i18n.DateTimePatterns_smn', 'goog.i18n.DateTimePatterns_smn_FI', 'goog.i18n.DateTimePatterns_sn', 'goog.i18n.DateTimePatterns_sn_ZW', 'goog.i18n.DateTimePatterns_so', 'goog.i18n.DateTimePatterns_so_DJ', 'goog.i18n.DateTimePatterns_so_ET', 'goog.i18n.DateTimePatterns_so_KE', 'goog.i18n.DateTimePatterns_so_SO', 'goog.i18n.DateTimePatterns_sq_AL', 'goog.i18n.DateTimePatterns_sq_MK', 'goog.i18n.DateTimePatterns_sq_XK', 'goog.i18n.DateTimePatterns_sr_Cyrl', 'goog.i18n.DateTimePatterns_sr_Cyrl_BA', 'goog.i18n.DateTimePatterns_sr_Cyrl_ME', 'goog.i18n.DateTimePatterns_sr_Cyrl_RS', 'goog.i18n.DateTimePatterns_sr_Cyrl_XK', 'goog.i18n.DateTimePatterns_sr_Latn_BA', 'goog.i18n.DateTimePatterns_sr_Latn_ME', 'goog.i18n.DateTimePatterns_sr_Latn_RS', 'goog.i18n.DateTimePatterns_sr_Latn_XK', 'goog.i18n.DateTimePatterns_sv_AX', 'goog.i18n.DateTimePatterns_sv_FI', 'goog.i18n.DateTimePatterns_sv_SE', 'goog.i18n.DateTimePatterns_sw_CD', 'goog.i18n.DateTimePatterns_sw_KE', 'goog.i18n.DateTimePatterns_sw_TZ', 'goog.i18n.DateTimePatterns_sw_UG', 'goog.i18n.DateTimePatterns_ta_IN', 'goog.i18n.DateTimePatterns_ta_LK', 'goog.i18n.DateTimePatterns_ta_MY', 'goog.i18n.DateTimePatterns_ta_SG', 'goog.i18n.DateTimePatterns_te_IN', 'goog.i18n.DateTimePatterns_teo', 'goog.i18n.DateTimePatterns_teo_KE', 'goog.i18n.DateTimePatterns_teo_UG', 'goog.i18n.DateTimePatterns_th_TH', 'goog.i18n.DateTimePatterns_ti', 'goog.i18n.DateTimePatterns_ti_ER', 'goog.i18n.DateTimePatterns_ti_ET', 'goog.i18n.DateTimePatterns_to', 'goog.i18n.DateTimePatterns_to_TO', 'goog.i18n.DateTimePatterns_tr_CY', 'goog.i18n.DateTimePatterns_tr_TR', 'goog.i18n.DateTimePatterns_twq', 'goog.i18n.DateTimePatterns_twq_NE', 'goog.i18n.DateTimePatterns_tzm', 'goog.i18n.DateTimePatterns_tzm_MA', 'goog.i18n.DateTimePatterns_ug', 'goog.i18n.DateTimePatterns_ug_CN', 'goog.i18n.DateTimePatterns_uk_UA', 'goog.i18n.DateTimePatterns_ur_IN', 'goog.i18n.DateTimePatterns_ur_PK', 'goog.i18n.DateTimePatterns_uz_Arab', 'goog.i18n.DateTimePatterns_uz_Arab_AF', 'goog.i18n.DateTimePatterns_uz_Cyrl', 'goog.i18n.DateTimePatterns_uz_Cyrl_UZ', 'goog.i18n.DateTimePatterns_uz_Latn', 'goog.i18n.DateTimePatterns_uz_Latn_UZ', 'goog.i18n.DateTimePatterns_vai', 'goog.i18n.DateTimePatterns_vai_Latn', 'goog.i18n.DateTimePatterns_vai_Latn_LR', 'goog.i18n.DateTimePatterns_vai_Vaii', 'goog.i18n.DateTimePatterns_vai_Vaii_LR', 'goog.i18n.DateTimePatterns_vi_VN', 'goog.i18n.DateTimePatterns_vun', 'goog.i18n.DateTimePatterns_vun_TZ', 'goog.i18n.DateTimePatterns_wae', 'goog.i18n.DateTimePatterns_wae_CH', 'goog.i18n.DateTimePatterns_xog', 'goog.i18n.DateTimePatterns_xog_UG', 'goog.i18n.DateTimePatterns_yav', 'goog.i18n.DateTimePatterns_yav_CM', 'goog.i18n.DateTimePatterns_yi', 'goog.i18n.DateTimePatterns_yi_001', 'goog.i18n.DateTimePatterns_yo', 'goog.i18n.DateTimePatterns_yo_BJ', 'goog.i18n.DateTimePatterns_yo_NG', 'goog.i18n.DateTimePatterns_yue', 'goog.i18n.DateTimePatterns_yue_HK', 'goog.i18n.DateTimePatterns_zgh', 'goog.i18n.DateTimePatterns_zgh_MA', 'goog.i18n.DateTimePatterns_zh_Hans', 'goog.i18n.DateTimePatterns_zh_Hans_CN', 'goog.i18n.DateTimePatterns_zh_Hans_HK', 'goog.i18n.DateTimePatterns_zh_Hans_MO', 'goog.i18n.DateTimePatterns_zh_Hans_SG', 'goog.i18n.DateTimePatterns_zh_Hant', 'goog.i18n.DateTimePatterns_zh_Hant_HK', 'goog.i18n.DateTimePatterns_zh_Hant_MO', 'goog.i18n.DateTimePatterns_zh_Hant_TW', 'goog.i18n.DateTimePatterns_zu_ZA'], ['goog.i18n.DateTimePatterns']);
                +goog.addDependency("i18n/datetimesymbols.js", ['goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbolsType', 'goog.i18n.DateTimeSymbols_en_ISO', 'goog.i18n.DateTimeSymbols_af', 'goog.i18n.DateTimeSymbols_am', 'goog.i18n.DateTimeSymbols_ar', 'goog.i18n.DateTimeSymbols_ar_DZ', 'goog.i18n.DateTimeSymbols_az', 'goog.i18n.DateTimeSymbols_be', 'goog.i18n.DateTimeSymbols_bg', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_br', 'goog.i18n.DateTimeSymbols_bs', 'goog.i18n.DateTimeSymbols_ca', 'goog.i18n.DateTimeSymbols_chr', 'goog.i18n.DateTimeSymbols_cs', 'goog.i18n.DateTimeSymbols_cy', 'goog.i18n.DateTimeSymbols_da', 'goog.i18n.DateTimeSymbols_de', 'goog.i18n.DateTimeSymbols_de_AT', 'goog.i18n.DateTimeSymbols_de_CH', 'goog.i18n.DateTimeSymbols_el', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_en_AU', 'goog.i18n.DateTimeSymbols_en_CA', 'goog.i18n.DateTimeSymbols_en_GB', 'goog.i18n.DateTimeSymbols_en_IE', 'goog.i18n.DateTimeSymbols_en_IN', 'goog.i18n.DateTimeSymbols_en_SG', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_en_ZA', 'goog.i18n.DateTimeSymbols_es', 'goog.i18n.DateTimeSymbols_es_419', 'goog.i18n.DateTimeSymbols_es_ES', 'goog.i18n.DateTimeSymbols_es_MX', 'goog.i18n.DateTimeSymbols_es_US', 'goog.i18n.DateTimeSymbols_et', 'goog.i18n.DateTimeSymbols_eu', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fi', 'goog.i18n.DateTimeSymbols_fil', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_fr_CA', 'goog.i18n.DateTimeSymbols_ga', 'goog.i18n.DateTimeSymbols_gl', 'goog.i18n.DateTimeSymbols_gsw', 'goog.i18n.DateTimeSymbols_gu', 'goog.i18n.DateTimeSymbols_haw', 'goog.i18n.DateTimeSymbols_he', 'goog.i18n.DateTimeSymbols_hi', 'goog.i18n.DateTimeSymbols_hr', 'goog.i18n.DateTimeSymbols_hu', 'goog.i18n.DateTimeSymbols_hy', 'goog.i18n.DateTimeSymbols_id', 'goog.i18n.DateTimeSymbols_in', 'goog.i18n.DateTimeSymbols_is', 'goog.i18n.DateTimeSymbols_it', 'goog.i18n.DateTimeSymbols_iw', 'goog.i18n.DateTimeSymbols_ja', 'goog.i18n.DateTimeSymbols_ka', 'goog.i18n.DateTimeSymbols_kk', 'goog.i18n.DateTimeSymbols_km', 'goog.i18n.DateTimeSymbols_kn', 'goog.i18n.DateTimeSymbols_ko', 'goog.i18n.DateTimeSymbols_ky', 'goog.i18n.DateTimeSymbols_ln', 'goog.i18n.DateTimeSymbols_lo', 'goog.i18n.DateTimeSymbols_lt', 'goog.i18n.DateTimeSymbols_lv', 'goog.i18n.DateTimeSymbols_mk', 'goog.i18n.DateTimeSymbols_ml', 'goog.i18n.DateTimeSymbols_mn', 'goog.i18n.DateTimeSymbols_mo', 'goog.i18n.DateTimeSymbols_mr', 'goog.i18n.DateTimeSymbols_ms', 'goog.i18n.DateTimeSymbols_mt', 'goog.i18n.DateTimeSymbols_my', 'goog.i18n.DateTimeSymbols_nb', 'goog.i18n.DateTimeSymbols_ne', 'goog.i18n.DateTimeSymbols_nl', 'goog.i18n.DateTimeSymbols_no', 'goog.i18n.DateTimeSymbols_no_NO', 'goog.i18n.DateTimeSymbols_or', 'goog.i18n.DateTimeSymbols_pa', 'goog.i18n.DateTimeSymbols_pl', 'goog.i18n.DateTimeSymbols_pt', 'goog.i18n.DateTimeSymbols_pt_BR', 'goog.i18n.DateTimeSymbols_pt_PT', 'goog.i18n.DateTimeSymbols_ro', 'goog.i18n.DateTimeSymbols_ru', 'goog.i18n.DateTimeSymbols_sh', 'goog.i18n.DateTimeSymbols_si', 'goog.i18n.DateTimeSymbols_sk', 'goog.i18n.DateTimeSymbols_sl', 'goog.i18n.DateTimeSymbols_sq', 'goog.i18n.DateTimeSymbols_sr', 'goog.i18n.DateTimeSymbols_sr_Latn', 'goog.i18n.DateTimeSymbols_sv', 'goog.i18n.DateTimeSymbols_sw', 'goog.i18n.DateTimeSymbols_ta', 'goog.i18n.DateTimeSymbols_te', 'goog.i18n.DateTimeSymbols_th', 'goog.i18n.DateTimeSymbols_tl', 'goog.i18n.DateTimeSymbols_tr', 'goog.i18n.DateTimeSymbols_uk', 'goog.i18n.DateTimeSymbols_ur', 'goog.i18n.DateTimeSymbols_uz', 'goog.i18n.DateTimeSymbols_vi', 'goog.i18n.DateTimeSymbols_zh', 'goog.i18n.DateTimeSymbols_zh_CN', 'goog.i18n.DateTimeSymbols_zh_HK', 'goog.i18n.DateTimeSymbols_zh_TW', 'goog.i18n.DateTimeSymbols_zu'], []);
                +goog.addDependency("i18n/datetimesymbolsext.js", ['goog.i18n.DateTimeSymbolsExt', 'goog.i18n.DateTimeSymbols_af_NA', 'goog.i18n.DateTimeSymbols_af_ZA', 'goog.i18n.DateTimeSymbols_agq', 'goog.i18n.DateTimeSymbols_agq_CM', 'goog.i18n.DateTimeSymbols_ak', 'goog.i18n.DateTimeSymbols_ak_GH', 'goog.i18n.DateTimeSymbols_am_ET', 'goog.i18n.DateTimeSymbols_ar_001', 'goog.i18n.DateTimeSymbols_ar_AE', 'goog.i18n.DateTimeSymbols_ar_BH', 'goog.i18n.DateTimeSymbols_ar_DJ', 'goog.i18n.DateTimeSymbols_ar_EG', 'goog.i18n.DateTimeSymbols_ar_EH', 'goog.i18n.DateTimeSymbols_ar_ER', 'goog.i18n.DateTimeSymbols_ar_IL', 'goog.i18n.DateTimeSymbols_ar_IQ', 'goog.i18n.DateTimeSymbols_ar_JO', 'goog.i18n.DateTimeSymbols_ar_KM', 'goog.i18n.DateTimeSymbols_ar_KW', 'goog.i18n.DateTimeSymbols_ar_LB', 'goog.i18n.DateTimeSymbols_ar_LY', 'goog.i18n.DateTimeSymbols_ar_MA', 'goog.i18n.DateTimeSymbols_ar_MR', 'goog.i18n.DateTimeSymbols_ar_OM', 'goog.i18n.DateTimeSymbols_ar_PS', 'goog.i18n.DateTimeSymbols_ar_QA', 'goog.i18n.DateTimeSymbols_ar_SA', 'goog.i18n.DateTimeSymbols_ar_SD', 'goog.i18n.DateTimeSymbols_ar_SO', 'goog.i18n.DateTimeSymbols_ar_SS', 'goog.i18n.DateTimeSymbols_ar_SY', 'goog.i18n.DateTimeSymbols_ar_TD', 'goog.i18n.DateTimeSymbols_ar_TN', 'goog.i18n.DateTimeSymbols_ar_XB', 'goog.i18n.DateTimeSymbols_ar_YE', 'goog.i18n.DateTimeSymbols_as', 'goog.i18n.DateTimeSymbols_as_IN', 'goog.i18n.DateTimeSymbols_asa', 'goog.i18n.DateTimeSymbols_asa_TZ', 'goog.i18n.DateTimeSymbols_ast', 'goog.i18n.DateTimeSymbols_ast_ES', 'goog.i18n.DateTimeSymbols_az_Cyrl', 'goog.i18n.DateTimeSymbols_az_Cyrl_AZ', 'goog.i18n.DateTimeSymbols_az_Latn', 'goog.i18n.DateTimeSymbols_az_Latn_AZ', 'goog.i18n.DateTimeSymbols_bas', 'goog.i18n.DateTimeSymbols_bas_CM', 'goog.i18n.DateTimeSymbols_be_BY', 'goog.i18n.DateTimeSymbols_bem', 'goog.i18n.DateTimeSymbols_bem_ZM', 'goog.i18n.DateTimeSymbols_bez', 'goog.i18n.DateTimeSymbols_bez_TZ', 'goog.i18n.DateTimeSymbols_bg_BG', 'goog.i18n.DateTimeSymbols_bm', 'goog.i18n.DateTimeSymbols_bm_ML', 'goog.i18n.DateTimeSymbols_bn_BD', 'goog.i18n.DateTimeSymbols_bn_IN', 'goog.i18n.DateTimeSymbols_bo', 'goog.i18n.DateTimeSymbols_bo_CN', 'goog.i18n.DateTimeSymbols_bo_IN', 'goog.i18n.DateTimeSymbols_br_FR', 'goog.i18n.DateTimeSymbols_brx', 'goog.i18n.DateTimeSymbols_brx_IN', 'goog.i18n.DateTimeSymbols_bs_Cyrl', 'goog.i18n.DateTimeSymbols_bs_Cyrl_BA', 'goog.i18n.DateTimeSymbols_bs_Latn', 'goog.i18n.DateTimeSymbols_bs_Latn_BA', 'goog.i18n.DateTimeSymbols_ca_AD', 'goog.i18n.DateTimeSymbols_ca_ES', 'goog.i18n.DateTimeSymbols_ca_FR', 'goog.i18n.DateTimeSymbols_ca_IT', 'goog.i18n.DateTimeSymbols_ce', 'goog.i18n.DateTimeSymbols_ce_RU', 'goog.i18n.DateTimeSymbols_cgg', 'goog.i18n.DateTimeSymbols_cgg_UG', 'goog.i18n.DateTimeSymbols_chr_US', 'goog.i18n.DateTimeSymbols_ckb', 'goog.i18n.DateTimeSymbols_ckb_IQ', 'goog.i18n.DateTimeSymbols_ckb_IR', 'goog.i18n.DateTimeSymbols_cs_CZ', 'goog.i18n.DateTimeSymbols_cy_GB', 'goog.i18n.DateTimeSymbols_da_DK', 'goog.i18n.DateTimeSymbols_da_GL', 'goog.i18n.DateTimeSymbols_dav', 'goog.i18n.DateTimeSymbols_dav_KE', 'goog.i18n.DateTimeSymbols_de_BE', 'goog.i18n.DateTimeSymbols_de_DE', 'goog.i18n.DateTimeSymbols_de_IT', 'goog.i18n.DateTimeSymbols_de_LI', 'goog.i18n.DateTimeSymbols_de_LU', 'goog.i18n.DateTimeSymbols_dje', 'goog.i18n.DateTimeSymbols_dje_NE', 'goog.i18n.DateTimeSymbols_dsb', 'goog.i18n.DateTimeSymbols_dsb_DE', 'goog.i18n.DateTimeSymbols_dua', 'goog.i18n.DateTimeSymbols_dua_CM', 'goog.i18n.DateTimeSymbols_dyo', 'goog.i18n.DateTimeSymbols_dyo_SN', 'goog.i18n.DateTimeSymbols_dz', 'goog.i18n.DateTimeSymbols_dz_BT', 'goog.i18n.DateTimeSymbols_ebu', 'goog.i18n.DateTimeSymbols_ebu_KE', 'goog.i18n.DateTimeSymbols_ee', 'goog.i18n.DateTimeSymbols_ee_GH', 'goog.i18n.DateTimeSymbols_ee_TG', 'goog.i18n.DateTimeSymbols_el_CY', 'goog.i18n.DateTimeSymbols_el_GR', 'goog.i18n.DateTimeSymbols_en_001', 'goog.i18n.DateTimeSymbols_en_150', 'goog.i18n.DateTimeSymbols_en_AG', 'goog.i18n.DateTimeSymbols_en_AI', 'goog.i18n.DateTimeSymbols_en_AS', 'goog.i18n.DateTimeSymbols_en_AT', 'goog.i18n.DateTimeSymbols_en_BB', 'goog.i18n.DateTimeSymbols_en_BE', 'goog.i18n.DateTimeSymbols_en_BI', 'goog.i18n.DateTimeSymbols_en_BM', 'goog.i18n.DateTimeSymbols_en_BS', 'goog.i18n.DateTimeSymbols_en_BW', 'goog.i18n.DateTimeSymbols_en_BZ', 'goog.i18n.DateTimeSymbols_en_CC', 'goog.i18n.DateTimeSymbols_en_CH', 'goog.i18n.DateTimeSymbols_en_CK', 'goog.i18n.DateTimeSymbols_en_CM', 'goog.i18n.DateTimeSymbols_en_CX', 'goog.i18n.DateTimeSymbols_en_CY', 'goog.i18n.DateTimeSymbols_en_DE', 'goog.i18n.DateTimeSymbols_en_DG', 'goog.i18n.DateTimeSymbols_en_DK', 'goog.i18n.DateTimeSymbols_en_DM', 'goog.i18n.DateTimeSymbols_en_ER', 'goog.i18n.DateTimeSymbols_en_FI', 'goog.i18n.DateTimeSymbols_en_FJ', 'goog.i18n.DateTimeSymbols_en_FK', 'goog.i18n.DateTimeSymbols_en_FM', 'goog.i18n.DateTimeSymbols_en_GD', 'goog.i18n.DateTimeSymbols_en_GG', 'goog.i18n.DateTimeSymbols_en_GH', 'goog.i18n.DateTimeSymbols_en_GI', 'goog.i18n.DateTimeSymbols_en_GM', 'goog.i18n.DateTimeSymbols_en_GU', 'goog.i18n.DateTimeSymbols_en_GY', 'goog.i18n.DateTimeSymbols_en_HK', 'goog.i18n.DateTimeSymbols_en_IL', 'goog.i18n.DateTimeSymbols_en_IM', 'goog.i18n.DateTimeSymbols_en_IO', 'goog.i18n.DateTimeSymbols_en_JE', 'goog.i18n.DateTimeSymbols_en_JM', 'goog.i18n.DateTimeSymbols_en_KE', 'goog.i18n.DateTimeSymbols_en_KI', 'goog.i18n.DateTimeSymbols_en_KN', 'goog.i18n.DateTimeSymbols_en_KY', 'goog.i18n.DateTimeSymbols_en_LC', 'goog.i18n.DateTimeSymbols_en_LR', 'goog.i18n.DateTimeSymbols_en_LS', 'goog.i18n.DateTimeSymbols_en_MG', 'goog.i18n.DateTimeSymbols_en_MH', 'goog.i18n.DateTimeSymbols_en_MO', 'goog.i18n.DateTimeSymbols_en_MP', 'goog.i18n.DateTimeSymbols_en_MS', 'goog.i18n.DateTimeSymbols_en_MT', 'goog.i18n.DateTimeSymbols_en_MU', 'goog.i18n.DateTimeSymbols_en_MW', 'goog.i18n.DateTimeSymbols_en_MY', 'goog.i18n.DateTimeSymbols_en_NA', 'goog.i18n.DateTimeSymbols_en_NF', 'goog.i18n.DateTimeSymbols_en_NG', 'goog.i18n.DateTimeSymbols_en_NL', 'goog.i18n.DateTimeSymbols_en_NR', 'goog.i18n.DateTimeSymbols_en_NU', 'goog.i18n.DateTimeSymbols_en_NZ', 'goog.i18n.DateTimeSymbols_en_PG', 'goog.i18n.DateTimeSymbols_en_PH', 'goog.i18n.DateTimeSymbols_en_PK', 'goog.i18n.DateTimeSymbols_en_PN', 'goog.i18n.DateTimeSymbols_en_PR', 'goog.i18n.DateTimeSymbols_en_PW', 'goog.i18n.DateTimeSymbols_en_RW', 'goog.i18n.DateTimeSymbols_en_SB', 'goog.i18n.DateTimeSymbols_en_SC', 'goog.i18n.DateTimeSymbols_en_SD', 'goog.i18n.DateTimeSymbols_en_SE', 'goog.i18n.DateTimeSymbols_en_SH', 'goog.i18n.DateTimeSymbols_en_SI', 'goog.i18n.DateTimeSymbols_en_SL', 'goog.i18n.DateTimeSymbols_en_SS', 'goog.i18n.DateTimeSymbols_en_SX', 'goog.i18n.DateTimeSymbols_en_SZ', 'goog.i18n.DateTimeSymbols_en_TC', 'goog.i18n.DateTimeSymbols_en_TK', 'goog.i18n.DateTimeSymbols_en_TO', 'goog.i18n.DateTimeSymbols_en_TT', 'goog.i18n.DateTimeSymbols_en_TV', 'goog.i18n.DateTimeSymbols_en_TZ', 'goog.i18n.DateTimeSymbols_en_UG', 'goog.i18n.DateTimeSymbols_en_UM', 'goog.i18n.DateTimeSymbols_en_US_POSIX', 'goog.i18n.DateTimeSymbols_en_VC', 'goog.i18n.DateTimeSymbols_en_VG', 'goog.i18n.DateTimeSymbols_en_VI', 'goog.i18n.DateTimeSymbols_en_VU', 'goog.i18n.DateTimeSymbols_en_WS', 'goog.i18n.DateTimeSymbols_en_XA', 'goog.i18n.DateTimeSymbols_en_ZM', 'goog.i18n.DateTimeSymbols_en_ZW', 'goog.i18n.DateTimeSymbols_eo', 'goog.i18n.DateTimeSymbols_es_AR', 'goog.i18n.DateTimeSymbols_es_BO', 'goog.i18n.DateTimeSymbols_es_BR', 'goog.i18n.DateTimeSymbols_es_CL', 'goog.i18n.DateTimeSymbols_es_CO', 'goog.i18n.DateTimeSymbols_es_CR', 'goog.i18n.DateTimeSymbols_es_CU', 'goog.i18n.DateTimeSymbols_es_DO', 'goog.i18n.DateTimeSymbols_es_EA', 'goog.i18n.DateTimeSymbols_es_EC', 'goog.i18n.DateTimeSymbols_es_GQ', 'goog.i18n.DateTimeSymbols_es_GT', 'goog.i18n.DateTimeSymbols_es_HN', 'goog.i18n.DateTimeSymbols_es_IC', 'goog.i18n.DateTimeSymbols_es_NI', 'goog.i18n.DateTimeSymbols_es_PA', 'goog.i18n.DateTimeSymbols_es_PE', 'goog.i18n.DateTimeSymbols_es_PH', 'goog.i18n.DateTimeSymbols_es_PR', 'goog.i18n.DateTimeSymbols_es_PY', 'goog.i18n.DateTimeSymbols_es_SV', 'goog.i18n.DateTimeSymbols_es_UY', 'goog.i18n.DateTimeSymbols_es_VE', 'goog.i18n.DateTimeSymbols_et_EE', 'goog.i18n.DateTimeSymbols_eu_ES', 'goog.i18n.DateTimeSymbols_ewo', 'goog.i18n.DateTimeSymbols_ewo_CM', 'goog.i18n.DateTimeSymbols_fa_AF', 'goog.i18n.DateTimeSymbols_fa_IR', 'goog.i18n.DateTimeSymbols_ff', 'goog.i18n.DateTimeSymbols_ff_CM', 'goog.i18n.DateTimeSymbols_ff_GN', 'goog.i18n.DateTimeSymbols_ff_MR', 'goog.i18n.DateTimeSymbols_ff_SN', 'goog.i18n.DateTimeSymbols_fi_FI', 'goog.i18n.DateTimeSymbols_fil_PH', 'goog.i18n.DateTimeSymbols_fo', 'goog.i18n.DateTimeSymbols_fo_DK', 'goog.i18n.DateTimeSymbols_fo_FO', 'goog.i18n.DateTimeSymbols_fr_BE', 'goog.i18n.DateTimeSymbols_fr_BF', 'goog.i18n.DateTimeSymbols_fr_BI', 'goog.i18n.DateTimeSymbols_fr_BJ', 'goog.i18n.DateTimeSymbols_fr_BL', 'goog.i18n.DateTimeSymbols_fr_CD', 'goog.i18n.DateTimeSymbols_fr_CF', 'goog.i18n.DateTimeSymbols_fr_CG', 'goog.i18n.DateTimeSymbols_fr_CH', 'goog.i18n.DateTimeSymbols_fr_CI', 'goog.i18n.DateTimeSymbols_fr_CM', 'goog.i18n.DateTimeSymbols_fr_DJ', 'goog.i18n.DateTimeSymbols_fr_DZ', 'goog.i18n.DateTimeSymbols_fr_FR', 'goog.i18n.DateTimeSymbols_fr_GA', 'goog.i18n.DateTimeSymbols_fr_GF', 'goog.i18n.DateTimeSymbols_fr_GN', 'goog.i18n.DateTimeSymbols_fr_GP', 'goog.i18n.DateTimeSymbols_fr_GQ', 'goog.i18n.DateTimeSymbols_fr_HT', 'goog.i18n.DateTimeSymbols_fr_KM', 'goog.i18n.DateTimeSymbols_fr_LU', 'goog.i18n.DateTimeSymbols_fr_MA', 'goog.i18n.DateTimeSymbols_fr_MC', 'goog.i18n.DateTimeSymbols_fr_MF', 'goog.i18n.DateTimeSymbols_fr_MG', 'goog.i18n.DateTimeSymbols_fr_ML', 'goog.i18n.DateTimeSymbols_fr_MQ', 'goog.i18n.DateTimeSymbols_fr_MR', 'goog.i18n.DateTimeSymbols_fr_MU', 'goog.i18n.DateTimeSymbols_fr_NC', 'goog.i18n.DateTimeSymbols_fr_NE', 'goog.i18n.DateTimeSymbols_fr_PF', 'goog.i18n.DateTimeSymbols_fr_PM', 'goog.i18n.DateTimeSymbols_fr_RE', 'goog.i18n.DateTimeSymbols_fr_RW', 'goog.i18n.DateTimeSymbols_fr_SC', 'goog.i18n.DateTimeSymbols_fr_SN', 'goog.i18n.DateTimeSymbols_fr_SY', 'goog.i18n.DateTimeSymbols_fr_TD', 'goog.i18n.DateTimeSymbols_fr_TG', 'goog.i18n.DateTimeSymbols_fr_TN', 'goog.i18n.DateTimeSymbols_fr_VU', 'goog.i18n.DateTimeSymbols_fr_WF', 'goog.i18n.DateTimeSymbols_fr_YT', 'goog.i18n.DateTimeSymbols_fur', 'goog.i18n.DateTimeSymbols_fur_IT', 'goog.i18n.DateTimeSymbols_fy', 'goog.i18n.DateTimeSymbols_fy_NL', 'goog.i18n.DateTimeSymbols_ga_IE', 'goog.i18n.DateTimeSymbols_gd', 'goog.i18n.DateTimeSymbols_gd_GB', 'goog.i18n.DateTimeSymbols_gl_ES', 'goog.i18n.DateTimeSymbols_gsw_CH', 'goog.i18n.DateTimeSymbols_gsw_FR', 'goog.i18n.DateTimeSymbols_gsw_LI', 'goog.i18n.DateTimeSymbols_gu_IN', 'goog.i18n.DateTimeSymbols_guz', 'goog.i18n.DateTimeSymbols_guz_KE', 'goog.i18n.DateTimeSymbols_gv', 'goog.i18n.DateTimeSymbols_gv_IM', 'goog.i18n.DateTimeSymbols_ha', 'goog.i18n.DateTimeSymbols_ha_GH', 'goog.i18n.DateTimeSymbols_ha_NE', 'goog.i18n.DateTimeSymbols_ha_NG', 'goog.i18n.DateTimeSymbols_haw_US', 'goog.i18n.DateTimeSymbols_he_IL', 'goog.i18n.DateTimeSymbols_hi_IN', 'goog.i18n.DateTimeSymbols_hr_BA', 'goog.i18n.DateTimeSymbols_hr_HR', 'goog.i18n.DateTimeSymbols_hsb', 'goog.i18n.DateTimeSymbols_hsb_DE', 'goog.i18n.DateTimeSymbols_hu_HU', 'goog.i18n.DateTimeSymbols_hy_AM', 'goog.i18n.DateTimeSymbols_id_ID', 'goog.i18n.DateTimeSymbols_ig', 'goog.i18n.DateTimeSymbols_ig_NG', 'goog.i18n.DateTimeSymbols_ii', 'goog.i18n.DateTimeSymbols_ii_CN', 'goog.i18n.DateTimeSymbols_is_IS', 'goog.i18n.DateTimeSymbols_it_CH', 'goog.i18n.DateTimeSymbols_it_IT', 'goog.i18n.DateTimeSymbols_it_SM', 'goog.i18n.DateTimeSymbols_ja_JP', 'goog.i18n.DateTimeSymbols_jgo', 'goog.i18n.DateTimeSymbols_jgo_CM', 'goog.i18n.DateTimeSymbols_jmc', 'goog.i18n.DateTimeSymbols_jmc_TZ', 'goog.i18n.DateTimeSymbols_ka_GE', 'goog.i18n.DateTimeSymbols_kab', 'goog.i18n.DateTimeSymbols_kab_DZ', 'goog.i18n.DateTimeSymbols_kam', 'goog.i18n.DateTimeSymbols_kam_KE', 'goog.i18n.DateTimeSymbols_kde', 'goog.i18n.DateTimeSymbols_kde_TZ', 'goog.i18n.DateTimeSymbols_kea', 'goog.i18n.DateTimeSymbols_kea_CV', 'goog.i18n.DateTimeSymbols_khq', 'goog.i18n.DateTimeSymbols_khq_ML', 'goog.i18n.DateTimeSymbols_ki', 'goog.i18n.DateTimeSymbols_ki_KE', 'goog.i18n.DateTimeSymbols_kk_KZ', 'goog.i18n.DateTimeSymbols_kkj', 'goog.i18n.DateTimeSymbols_kkj_CM', 'goog.i18n.DateTimeSymbols_kl', 'goog.i18n.DateTimeSymbols_kl_GL', 'goog.i18n.DateTimeSymbols_kln', 'goog.i18n.DateTimeSymbols_kln_KE', 'goog.i18n.DateTimeSymbols_km_KH', 'goog.i18n.DateTimeSymbols_kn_IN', 'goog.i18n.DateTimeSymbols_ko_KP', 'goog.i18n.DateTimeSymbols_ko_KR', 'goog.i18n.DateTimeSymbols_kok', 'goog.i18n.DateTimeSymbols_kok_IN', 'goog.i18n.DateTimeSymbols_ks', 'goog.i18n.DateTimeSymbols_ks_IN', 'goog.i18n.DateTimeSymbols_ksb', 'goog.i18n.DateTimeSymbols_ksb_TZ', 'goog.i18n.DateTimeSymbols_ksf', 'goog.i18n.DateTimeSymbols_ksf_CM', 'goog.i18n.DateTimeSymbols_ksh', 'goog.i18n.DateTimeSymbols_ksh_DE', 'goog.i18n.DateTimeSymbols_kw', 'goog.i18n.DateTimeSymbols_kw_GB', 'goog.i18n.DateTimeSymbols_ky_KG', 'goog.i18n.DateTimeSymbols_lag', 'goog.i18n.DateTimeSymbols_lag_TZ', 'goog.i18n.DateTimeSymbols_lb', 'goog.i18n.DateTimeSymbols_lb_LU', 'goog.i18n.DateTimeSymbols_lg', 'goog.i18n.DateTimeSymbols_lg_UG', 'goog.i18n.DateTimeSymbols_lkt', 'goog.i18n.DateTimeSymbols_lkt_US', 'goog.i18n.DateTimeSymbols_ln_AO', 'goog.i18n.DateTimeSymbols_ln_CD', 'goog.i18n.DateTimeSymbols_ln_CF', 'goog.i18n.DateTimeSymbols_ln_CG', 'goog.i18n.DateTimeSymbols_lo_LA', 'goog.i18n.DateTimeSymbols_lrc', 'goog.i18n.DateTimeSymbols_lrc_IQ', 'goog.i18n.DateTimeSymbols_lrc_IR', 'goog.i18n.DateTimeSymbols_lt_LT', 'goog.i18n.DateTimeSymbols_lu', 'goog.i18n.DateTimeSymbols_lu_CD', 'goog.i18n.DateTimeSymbols_luo', 'goog.i18n.DateTimeSymbols_luo_KE', 'goog.i18n.DateTimeSymbols_luy', 'goog.i18n.DateTimeSymbols_luy_KE', 'goog.i18n.DateTimeSymbols_lv_LV', 'goog.i18n.DateTimeSymbols_mas', 'goog.i18n.DateTimeSymbols_mas_KE', 'goog.i18n.DateTimeSymbols_mas_TZ', 'goog.i18n.DateTimeSymbols_mer', 'goog.i18n.DateTimeSymbols_mer_KE', 'goog.i18n.DateTimeSymbols_mfe', 'goog.i18n.DateTimeSymbols_mfe_MU', 'goog.i18n.DateTimeSymbols_mg', 'goog.i18n.DateTimeSymbols_mg_MG', 'goog.i18n.DateTimeSymbols_mgh', 'goog.i18n.DateTimeSymbols_mgh_MZ', 'goog.i18n.DateTimeSymbols_mgo', 'goog.i18n.DateTimeSymbols_mgo_CM', 'goog.i18n.DateTimeSymbols_mk_MK', 'goog.i18n.DateTimeSymbols_ml_IN', 'goog.i18n.DateTimeSymbols_mn_MN', 'goog.i18n.DateTimeSymbols_mr_IN', 'goog.i18n.DateTimeSymbols_ms_BN', 'goog.i18n.DateTimeSymbols_ms_MY', 'goog.i18n.DateTimeSymbols_ms_SG', 'goog.i18n.DateTimeSymbols_mt_MT', 'goog.i18n.DateTimeSymbols_mua', 'goog.i18n.DateTimeSymbols_mua_CM', 'goog.i18n.DateTimeSymbols_my_MM', 'goog.i18n.DateTimeSymbols_mzn', 'goog.i18n.DateTimeSymbols_mzn_IR', 'goog.i18n.DateTimeSymbols_naq', 'goog.i18n.DateTimeSymbols_naq_NA', 'goog.i18n.DateTimeSymbols_nb_NO', 'goog.i18n.DateTimeSymbols_nb_SJ', 'goog.i18n.DateTimeSymbols_nd', 'goog.i18n.DateTimeSymbols_nd_ZW', 'goog.i18n.DateTimeSymbols_nds', 'goog.i18n.DateTimeSymbols_nds_DE', 'goog.i18n.DateTimeSymbols_nds_NL', 'goog.i18n.DateTimeSymbols_ne_IN', 'goog.i18n.DateTimeSymbols_ne_NP', 'goog.i18n.DateTimeSymbols_nl_AW', 'goog.i18n.DateTimeSymbols_nl_BE', 'goog.i18n.DateTimeSymbols_nl_BQ', 'goog.i18n.DateTimeSymbols_nl_CW', 'goog.i18n.DateTimeSymbols_nl_NL', 'goog.i18n.DateTimeSymbols_nl_SR', 'goog.i18n.DateTimeSymbols_nl_SX', 'goog.i18n.DateTimeSymbols_nmg', 'goog.i18n.DateTimeSymbols_nmg_CM', 'goog.i18n.DateTimeSymbols_nn', 'goog.i18n.DateTimeSymbols_nn_NO', 'goog.i18n.DateTimeSymbols_nnh', 'goog.i18n.DateTimeSymbols_nnh_CM', 'goog.i18n.DateTimeSymbols_nus', 'goog.i18n.DateTimeSymbols_nus_SS', 'goog.i18n.DateTimeSymbols_nyn', 'goog.i18n.DateTimeSymbols_nyn_UG', 'goog.i18n.DateTimeSymbols_om', 'goog.i18n.DateTimeSymbols_om_ET', 'goog.i18n.DateTimeSymbols_om_KE', 'goog.i18n.DateTimeSymbols_or_IN', 'goog.i18n.DateTimeSymbols_os', 'goog.i18n.DateTimeSymbols_os_GE', 'goog.i18n.DateTimeSymbols_os_RU', 'goog.i18n.DateTimeSymbols_pa_Arab', 'goog.i18n.DateTimeSymbols_pa_Arab_PK', 'goog.i18n.DateTimeSymbols_pa_Guru', 'goog.i18n.DateTimeSymbols_pa_Guru_IN', 'goog.i18n.DateTimeSymbols_pl_PL', 'goog.i18n.DateTimeSymbols_ps', 'goog.i18n.DateTimeSymbols_ps_AF', 'goog.i18n.DateTimeSymbols_pt_AO', 'goog.i18n.DateTimeSymbols_pt_CH', 'goog.i18n.DateTimeSymbols_pt_CV', 'goog.i18n.DateTimeSymbols_pt_GQ', 'goog.i18n.DateTimeSymbols_pt_GW', 'goog.i18n.DateTimeSymbols_pt_LU', 'goog.i18n.DateTimeSymbols_pt_MO', 'goog.i18n.DateTimeSymbols_pt_MZ', 'goog.i18n.DateTimeSymbols_pt_ST', 'goog.i18n.DateTimeSymbols_pt_TL', 'goog.i18n.DateTimeSymbols_qu', 'goog.i18n.DateTimeSymbols_qu_BO', 'goog.i18n.DateTimeSymbols_qu_EC', 'goog.i18n.DateTimeSymbols_qu_PE', 'goog.i18n.DateTimeSymbols_rm', 'goog.i18n.DateTimeSymbols_rm_CH', 'goog.i18n.DateTimeSymbols_rn', 'goog.i18n.DateTimeSymbols_rn_BI', 'goog.i18n.DateTimeSymbols_ro_MD', 'goog.i18n.DateTimeSymbols_ro_RO', 'goog.i18n.DateTimeSymbols_rof', 'goog.i18n.DateTimeSymbols_rof_TZ', 'goog.i18n.DateTimeSymbols_ru_BY', 'goog.i18n.DateTimeSymbols_ru_KG', 'goog.i18n.DateTimeSymbols_ru_KZ', 'goog.i18n.DateTimeSymbols_ru_MD', 'goog.i18n.DateTimeSymbols_ru_RU', 'goog.i18n.DateTimeSymbols_ru_UA', 'goog.i18n.DateTimeSymbols_rw', 'goog.i18n.DateTimeSymbols_rw_RW', 'goog.i18n.DateTimeSymbols_rwk', 'goog.i18n.DateTimeSymbols_rwk_TZ', 'goog.i18n.DateTimeSymbols_sah', 'goog.i18n.DateTimeSymbols_sah_RU', 'goog.i18n.DateTimeSymbols_saq', 'goog.i18n.DateTimeSymbols_saq_KE', 'goog.i18n.DateTimeSymbols_sbp', 'goog.i18n.DateTimeSymbols_sbp_TZ', 'goog.i18n.DateTimeSymbols_se', 'goog.i18n.DateTimeSymbols_se_FI', 'goog.i18n.DateTimeSymbols_se_NO', 'goog.i18n.DateTimeSymbols_se_SE', 'goog.i18n.DateTimeSymbols_seh', 'goog.i18n.DateTimeSymbols_seh_MZ', 'goog.i18n.DateTimeSymbols_ses', 'goog.i18n.DateTimeSymbols_ses_ML', 'goog.i18n.DateTimeSymbols_sg', 'goog.i18n.DateTimeSymbols_sg_CF', 'goog.i18n.DateTimeSymbols_shi', 'goog.i18n.DateTimeSymbols_shi_Latn', 'goog.i18n.DateTimeSymbols_shi_Latn_MA', 'goog.i18n.DateTimeSymbols_shi_Tfng', 'goog.i18n.DateTimeSymbols_shi_Tfng_MA', 'goog.i18n.DateTimeSymbols_si_LK', 'goog.i18n.DateTimeSymbols_sk_SK', 'goog.i18n.DateTimeSymbols_sl_SI', 'goog.i18n.DateTimeSymbols_smn', 'goog.i18n.DateTimeSymbols_smn_FI', 'goog.i18n.DateTimeSymbols_sn', 'goog.i18n.DateTimeSymbols_sn_ZW', 'goog.i18n.DateTimeSymbols_so', 'goog.i18n.DateTimeSymbols_so_DJ', 'goog.i18n.DateTimeSymbols_so_ET', 'goog.i18n.DateTimeSymbols_so_KE', 'goog.i18n.DateTimeSymbols_so_SO', 'goog.i18n.DateTimeSymbols_sq_AL', 'goog.i18n.DateTimeSymbols_sq_MK', 'goog.i18n.DateTimeSymbols_sq_XK', 'goog.i18n.DateTimeSymbols_sr_Cyrl', 'goog.i18n.DateTimeSymbols_sr_Cyrl_BA', 'goog.i18n.DateTimeSymbols_sr_Cyrl_ME', 'goog.i18n.DateTimeSymbols_sr_Cyrl_RS', 'goog.i18n.DateTimeSymbols_sr_Cyrl_XK', 'goog.i18n.DateTimeSymbols_sr_Latn_BA', 'goog.i18n.DateTimeSymbols_sr_Latn_ME', 'goog.i18n.DateTimeSymbols_sr_Latn_RS', 'goog.i18n.DateTimeSymbols_sr_Latn_XK', 'goog.i18n.DateTimeSymbols_sv_AX', 'goog.i18n.DateTimeSymbols_sv_FI', 'goog.i18n.DateTimeSymbols_sv_SE', 'goog.i18n.DateTimeSymbols_sw_CD', 'goog.i18n.DateTimeSymbols_sw_KE', 'goog.i18n.DateTimeSymbols_sw_TZ', 'goog.i18n.DateTimeSymbols_sw_UG', 'goog.i18n.DateTimeSymbols_ta_IN', 'goog.i18n.DateTimeSymbols_ta_LK', 'goog.i18n.DateTimeSymbols_ta_MY', 'goog.i18n.DateTimeSymbols_ta_SG', 'goog.i18n.DateTimeSymbols_te_IN', 'goog.i18n.DateTimeSymbols_teo', 'goog.i18n.DateTimeSymbols_teo_KE', 'goog.i18n.DateTimeSymbols_teo_UG', 'goog.i18n.DateTimeSymbols_th_TH', 'goog.i18n.DateTimeSymbols_ti', 'goog.i18n.DateTimeSymbols_ti_ER', 'goog.i18n.DateTimeSymbols_ti_ET', 'goog.i18n.DateTimeSymbols_to', 'goog.i18n.DateTimeSymbols_to_TO', 'goog.i18n.DateTimeSymbols_tr_CY', 'goog.i18n.DateTimeSymbols_tr_TR', 'goog.i18n.DateTimeSymbols_twq', 'goog.i18n.DateTimeSymbols_twq_NE', 'goog.i18n.DateTimeSymbols_tzm', 'goog.i18n.DateTimeSymbols_tzm_MA', 'goog.i18n.DateTimeSymbols_ug', 'goog.i18n.DateTimeSymbols_ug_CN', 'goog.i18n.DateTimeSymbols_uk_UA', 'goog.i18n.DateTimeSymbols_ur_IN', 'goog.i18n.DateTimeSymbols_ur_PK', 'goog.i18n.DateTimeSymbols_uz_Arab', 'goog.i18n.DateTimeSymbols_uz_Arab_AF', 'goog.i18n.DateTimeSymbols_uz_Cyrl', 'goog.i18n.DateTimeSymbols_uz_Cyrl_UZ', 'goog.i18n.DateTimeSymbols_uz_Latn', 'goog.i18n.DateTimeSymbols_uz_Latn_UZ', 'goog.i18n.DateTimeSymbols_vai', 'goog.i18n.DateTimeSymbols_vai_Latn', 'goog.i18n.DateTimeSymbols_vai_Latn_LR', 'goog.i18n.DateTimeSymbols_vai_Vaii', 'goog.i18n.DateTimeSymbols_vai_Vaii_LR', 'goog.i18n.DateTimeSymbols_vi_VN', 'goog.i18n.DateTimeSymbols_vun', 'goog.i18n.DateTimeSymbols_vun_TZ', 'goog.i18n.DateTimeSymbols_wae', 'goog.i18n.DateTimeSymbols_wae_CH', 'goog.i18n.DateTimeSymbols_xog', 'goog.i18n.DateTimeSymbols_xog_UG', 'goog.i18n.DateTimeSymbols_yav', 'goog.i18n.DateTimeSymbols_yav_CM', 'goog.i18n.DateTimeSymbols_yi', 'goog.i18n.DateTimeSymbols_yi_001', 'goog.i18n.DateTimeSymbols_yo', 'goog.i18n.DateTimeSymbols_yo_BJ', 'goog.i18n.DateTimeSymbols_yo_NG', 'goog.i18n.DateTimeSymbols_yue', 'goog.i18n.DateTimeSymbols_yue_HK', 'goog.i18n.DateTimeSymbols_zgh', 'goog.i18n.DateTimeSymbols_zgh_MA', 'goog.i18n.DateTimeSymbols_zh_Hans', 'goog.i18n.DateTimeSymbols_zh_Hans_CN', 'goog.i18n.DateTimeSymbols_zh_Hans_HK', 'goog.i18n.DateTimeSymbols_zh_Hans_MO', 'goog.i18n.DateTimeSymbols_zh_Hans_SG', 'goog.i18n.DateTimeSymbols_zh_Hant', 'goog.i18n.DateTimeSymbols_zh_Hant_HK', 'goog.i18n.DateTimeSymbols_zh_Hant_MO', 'goog.i18n.DateTimeSymbols_zh_Hant_TW', 'goog.i18n.DateTimeSymbols_zu_ZA'], ['goog.i18n.DateTimeSymbols']);
                +goog.addDependency("i18n/graphemebreak.js", ['goog.i18n.GraphemeBreak'], ['goog.structs.InversionMap']);
                +goog.addDependency("i18n/graphemebreak_test.js", ['goog.i18n.GraphemeBreakTest'], ['goog.i18n.GraphemeBreak', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/messageformat.js", ['goog.i18n.MessageFormat'], ['goog.array', 'goog.asserts', 'goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.NumberFormat', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.ordinalRules', 'goog.i18n.pluralRules']);
                +goog.addDependency("i18n/messageformat_test.js", ['goog.i18n.MessageFormatTest'], ['goog.i18n.MessageFormat', 'goog.i18n.NumberFormatSymbols_hr', 'goog.i18n.pluralRules', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/mime.js", ['goog.i18n.mime', 'goog.i18n.mime.encode'], ['goog.array']);
                +goog.addDependency("i18n/mime_test.js", ['goog.i18n.mime.encodeTest'], ['goog.i18n.mime.encode', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/numberformat.js", ['goog.i18n.NumberFormat', 'goog.i18n.NumberFormat.CurrencyStyle', 'goog.i18n.NumberFormat.Format'], ['goog.asserts', 'goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.currency', 'goog.math']);
                +goog.addDependency("i18n/numberformat_test.js", ['goog.i18n.NumberFormatTest'], ['goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.CompactNumberFormatSymbols_de', 'goog.i18n.CompactNumberFormatSymbols_en', 'goog.i18n.CompactNumberFormatSymbols_fr', 'goog.i18n.NumberFormat', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_de', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_fr', 'goog.i18n.NumberFormatSymbols_pl', 'goog.i18n.NumberFormatSymbols_ro', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("i18n/numberformatsymbols.js", ['goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_af', 'goog.i18n.NumberFormatSymbols_am', 'goog.i18n.NumberFormatSymbols_ar', 'goog.i18n.NumberFormatSymbols_ar_DZ', 'goog.i18n.NumberFormatSymbols_az', 'goog.i18n.NumberFormatSymbols_be', 'goog.i18n.NumberFormatSymbols_bg', 'goog.i18n.NumberFormatSymbols_bn', 'goog.i18n.NumberFormatSymbols_br', 'goog.i18n.NumberFormatSymbols_bs', 'goog.i18n.NumberFormatSymbols_ca', 'goog.i18n.NumberFormatSymbols_chr', 'goog.i18n.NumberFormatSymbols_cs', 'goog.i18n.NumberFormatSymbols_cy', 'goog.i18n.NumberFormatSymbols_da', 'goog.i18n.NumberFormatSymbols_de', 'goog.i18n.NumberFormatSymbols_de_AT', 'goog.i18n.NumberFormatSymbols_de_CH', 'goog.i18n.NumberFormatSymbols_el', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_en_AU', 'goog.i18n.NumberFormatSymbols_en_CA', 'goog.i18n.NumberFormatSymbols_en_GB', 'goog.i18n.NumberFormatSymbols_en_IE', 'goog.i18n.NumberFormatSymbols_en_IN', 'goog.i18n.NumberFormatSymbols_en_SG', 'goog.i18n.NumberFormatSymbols_en_US', 'goog.i18n.NumberFormatSymbols_en_ZA', 'goog.i18n.NumberFormatSymbols_es', 'goog.i18n.NumberFormatSymbols_es_419', 'goog.i18n.NumberFormatSymbols_es_ES', 'goog.i18n.NumberFormatSymbols_es_MX', 'goog.i18n.NumberFormatSymbols_es_US', 'goog.i18n.NumberFormatSymbols_et', 'goog.i18n.NumberFormatSymbols_eu', 'goog.i18n.NumberFormatSymbols_fa', 'goog.i18n.NumberFormatSymbols_fi', 'goog.i18n.NumberFormatSymbols_fil', 'goog.i18n.NumberFormatSymbols_fr', 'goog.i18n.NumberFormatSymbols_fr_CA', 'goog.i18n.NumberFormatSymbols_ga', 'goog.i18n.NumberFormatSymbols_gl', 'goog.i18n.NumberFormatSymbols_gsw', 'goog.i18n.NumberFormatSymbols_gu', 'goog.i18n.NumberFormatSymbols_haw', 'goog.i18n.NumberFormatSymbols_he', 'goog.i18n.NumberFormatSymbols_hi', 'goog.i18n.NumberFormatSymbols_hr', 'goog.i18n.NumberFormatSymbols_hu', 'goog.i18n.NumberFormatSymbols_hy', 'goog.i18n.NumberFormatSymbols_id', 'goog.i18n.NumberFormatSymbols_in', 'goog.i18n.NumberFormatSymbols_is', 'goog.i18n.NumberFormatSymbols_it', 'goog.i18n.NumberFormatSymbols_iw', 'goog.i18n.NumberFormatSymbols_ja', 'goog.i18n.NumberFormatSymbols_ka', 'goog.i18n.NumberFormatSymbols_kk', 'goog.i18n.NumberFormatSymbols_km', 'goog.i18n.NumberFormatSymbols_kn', 'goog.i18n.NumberFormatSymbols_ko', 'goog.i18n.NumberFormatSymbols_ky', 'goog.i18n.NumberFormatSymbols_ln', 'goog.i18n.NumberFormatSymbols_lo', 'goog.i18n.NumberFormatSymbols_lt', 'goog.i18n.NumberFormatSymbols_lv', 'goog.i18n.NumberFormatSymbols_mk', 'goog.i18n.NumberFormatSymbols_ml', 'goog.i18n.NumberFormatSymbols_mn', 'goog.i18n.NumberFormatSymbols_mo', 'goog.i18n.NumberFormatSymbols_mr', 'goog.i18n.NumberFormatSymbols_ms', 'goog.i18n.NumberFormatSymbols_mt', 'goog.i18n.NumberFormatSymbols_my', 'goog.i18n.NumberFormatSymbols_nb', 'goog.i18n.NumberFormatSymbols_ne', 'goog.i18n.NumberFormatSymbols_nl', 'goog.i18n.NumberFormatSymbols_no', 'goog.i18n.NumberFormatSymbols_no_NO', 'goog.i18n.NumberFormatSymbols_or', 'goog.i18n.NumberFormatSymbols_pa', 'goog.i18n.NumberFormatSymbols_pl', 'goog.i18n.NumberFormatSymbols_pt', 'goog.i18n.NumberFormatSymbols_pt_BR', 'goog.i18n.NumberFormatSymbols_pt_PT', 'goog.i18n.NumberFormatSymbols_ro', 'goog.i18n.NumberFormatSymbols_ru', 'goog.i18n.NumberFormatSymbols_sh', 'goog.i18n.NumberFormatSymbols_si', 'goog.i18n.NumberFormatSymbols_sk', 'goog.i18n.NumberFormatSymbols_sl', 'goog.i18n.NumberFormatSymbols_sq', 'goog.i18n.NumberFormatSymbols_sr', 'goog.i18n.NumberFormatSymbols_sr_Latn', 'goog.i18n.NumberFormatSymbols_sv', 'goog.i18n.NumberFormatSymbols_sw', 'goog.i18n.NumberFormatSymbols_ta', 'goog.i18n.NumberFormatSymbols_te', 'goog.i18n.NumberFormatSymbols_th', 'goog.i18n.NumberFormatSymbols_tl', 'goog.i18n.NumberFormatSymbols_tr', 'goog.i18n.NumberFormatSymbols_uk', 'goog.i18n.NumberFormatSymbols_ur', 'goog.i18n.NumberFormatSymbols_uz', 'goog.i18n.NumberFormatSymbols_vi', 'goog.i18n.NumberFormatSymbols_zh', 'goog.i18n.NumberFormatSymbols_zh_CN', 'goog.i18n.NumberFormatSymbols_zh_HK', 'goog.i18n.NumberFormatSymbols_zh_TW', 'goog.i18n.NumberFormatSymbols_zu'], []);
                +goog.addDependency("i18n/numberformatsymbolsext.js", ['goog.i18n.NumberFormatSymbolsExt', 'goog.i18n.NumberFormatSymbols_af_NA', 'goog.i18n.NumberFormatSymbols_af_ZA', 'goog.i18n.NumberFormatSymbols_agq', 'goog.i18n.NumberFormatSymbols_agq_CM', 'goog.i18n.NumberFormatSymbols_ak', 'goog.i18n.NumberFormatSymbols_ak_GH', 'goog.i18n.NumberFormatSymbols_am_ET', 'goog.i18n.NumberFormatSymbols_ar_001', 'goog.i18n.NumberFormatSymbols_ar_AE', 'goog.i18n.NumberFormatSymbols_ar_BH', 'goog.i18n.NumberFormatSymbols_ar_DJ', 'goog.i18n.NumberFormatSymbols_ar_EG', 'goog.i18n.NumberFormatSymbols_ar_EH', 'goog.i18n.NumberFormatSymbols_ar_ER', 'goog.i18n.NumberFormatSymbols_ar_IL', 'goog.i18n.NumberFormatSymbols_ar_IQ', 'goog.i18n.NumberFormatSymbols_ar_JO', 'goog.i18n.NumberFormatSymbols_ar_KM', 'goog.i18n.NumberFormatSymbols_ar_KW', 'goog.i18n.NumberFormatSymbols_ar_LB', 'goog.i18n.NumberFormatSymbols_ar_LY', 'goog.i18n.NumberFormatSymbols_ar_MA', 'goog.i18n.NumberFormatSymbols_ar_MR', 'goog.i18n.NumberFormatSymbols_ar_OM', 'goog.i18n.NumberFormatSymbols_ar_PS', 'goog.i18n.NumberFormatSymbols_ar_QA', 'goog.i18n.NumberFormatSymbols_ar_SA', 'goog.i18n.NumberFormatSymbols_ar_SD', 'goog.i18n.NumberFormatSymbols_ar_SO', 'goog.i18n.NumberFormatSymbols_ar_SS', 'goog.i18n.NumberFormatSymbols_ar_SY', 'goog.i18n.NumberFormatSymbols_ar_TD', 'goog.i18n.NumberFormatSymbols_ar_TN', 'goog.i18n.NumberFormatSymbols_ar_XB', 'goog.i18n.NumberFormatSymbols_ar_YE', 'goog.i18n.NumberFormatSymbols_as', 'goog.i18n.NumberFormatSymbols_as_IN', 'goog.i18n.NumberFormatSymbols_asa', 'goog.i18n.NumberFormatSymbols_asa_TZ', 'goog.i18n.NumberFormatSymbols_ast', 'goog.i18n.NumberFormatSymbols_ast_ES', 'goog.i18n.NumberFormatSymbols_az_Cyrl', 'goog.i18n.NumberFormatSymbols_az_Cyrl_AZ', 'goog.i18n.NumberFormatSymbols_az_Latn', 'goog.i18n.NumberFormatSymbols_az_Latn_AZ', 'goog.i18n.NumberFormatSymbols_bas', 'goog.i18n.NumberFormatSymbols_bas_CM', 'goog.i18n.NumberFormatSymbols_be_BY', 'goog.i18n.NumberFormatSymbols_bem', 'goog.i18n.NumberFormatSymbols_bem_ZM', 'goog.i18n.NumberFormatSymbols_bez', 'goog.i18n.NumberFormatSymbols_bez_TZ', 'goog.i18n.NumberFormatSymbols_bg_BG', 'goog.i18n.NumberFormatSymbols_bm', 'goog.i18n.NumberFormatSymbols_bm_ML', 'goog.i18n.NumberFormatSymbols_bn_BD', 'goog.i18n.NumberFormatSymbols_bn_IN', 'goog.i18n.NumberFormatSymbols_bo', 'goog.i18n.NumberFormatSymbols_bo_CN', 'goog.i18n.NumberFormatSymbols_bo_IN', 'goog.i18n.NumberFormatSymbols_br_FR', 'goog.i18n.NumberFormatSymbols_brx', 'goog.i18n.NumberFormatSymbols_brx_IN', 'goog.i18n.NumberFormatSymbols_bs_Cyrl', 'goog.i18n.NumberFormatSymbols_bs_Cyrl_BA', 'goog.i18n.NumberFormatSymbols_bs_Latn', 'goog.i18n.NumberFormatSymbols_bs_Latn_BA', 'goog.i18n.NumberFormatSymbols_ca_AD', 'goog.i18n.NumberFormatSymbols_ca_ES', 'goog.i18n.NumberFormatSymbols_ca_FR', 'goog.i18n.NumberFormatSymbols_ca_IT', 'goog.i18n.NumberFormatSymbols_ce', 'goog.i18n.NumberFormatSymbols_ce_RU', 'goog.i18n.NumberFormatSymbols_cgg', 'goog.i18n.NumberFormatSymbols_cgg_UG', 'goog.i18n.NumberFormatSymbols_chr_US', 'goog.i18n.NumberFormatSymbols_ckb', 'goog.i18n.NumberFormatSymbols_ckb_IQ', 'goog.i18n.NumberFormatSymbols_ckb_IR', 'goog.i18n.NumberFormatSymbols_cs_CZ', 'goog.i18n.NumberFormatSymbols_cy_GB', 'goog.i18n.NumberFormatSymbols_da_DK', 'goog.i18n.NumberFormatSymbols_da_GL', 'goog.i18n.NumberFormatSymbols_dav', 'goog.i18n.NumberFormatSymbols_dav_KE', 'goog.i18n.NumberFormatSymbols_de_BE', 'goog.i18n.NumberFormatSymbols_de_DE', 'goog.i18n.NumberFormatSymbols_de_IT', 'goog.i18n.NumberFormatSymbols_de_LI', 'goog.i18n.NumberFormatSymbols_de_LU', 'goog.i18n.NumberFormatSymbols_dje', 'goog.i18n.NumberFormatSymbols_dje_NE', 'goog.i18n.NumberFormatSymbols_dsb', 'goog.i18n.NumberFormatSymbols_dsb_DE', 'goog.i18n.NumberFormatSymbols_dua', 'goog.i18n.NumberFormatSymbols_dua_CM', 'goog.i18n.NumberFormatSymbols_dyo', 'goog.i18n.NumberFormatSymbols_dyo_SN', 'goog.i18n.NumberFormatSymbols_dz', 'goog.i18n.NumberFormatSymbols_dz_BT', 'goog.i18n.NumberFormatSymbols_ebu', 'goog.i18n.NumberFormatSymbols_ebu_KE', 'goog.i18n.NumberFormatSymbols_ee', 'goog.i18n.NumberFormatSymbols_ee_GH', 'goog.i18n.NumberFormatSymbols_ee_TG', 'goog.i18n.NumberFormatSymbols_el_CY', 'goog.i18n.NumberFormatSymbols_el_GR', 'goog.i18n.NumberFormatSymbols_en_001', 'goog.i18n.NumberFormatSymbols_en_150', 'goog.i18n.NumberFormatSymbols_en_AG', 'goog.i18n.NumberFormatSymbols_en_AI', 'goog.i18n.NumberFormatSymbols_en_AS', 'goog.i18n.NumberFormatSymbols_en_AT', 'goog.i18n.NumberFormatSymbols_en_BB', 'goog.i18n.NumberFormatSymbols_en_BE', 'goog.i18n.NumberFormatSymbols_en_BI', 'goog.i18n.NumberFormatSymbols_en_BM', 'goog.i18n.NumberFormatSymbols_en_BS', 'goog.i18n.NumberFormatSymbols_en_BW', 'goog.i18n.NumberFormatSymbols_en_BZ', 'goog.i18n.NumberFormatSymbols_en_CC', 'goog.i18n.NumberFormatSymbols_en_CH', 'goog.i18n.NumberFormatSymbols_en_CK', 'goog.i18n.NumberFormatSymbols_en_CM', 'goog.i18n.NumberFormatSymbols_en_CX', 'goog.i18n.NumberFormatSymbols_en_CY', 'goog.i18n.NumberFormatSymbols_en_DE', 'goog.i18n.NumberFormatSymbols_en_DG', 'goog.i18n.NumberFormatSymbols_en_DK', 'goog.i18n.NumberFormatSymbols_en_DM', 'goog.i18n.NumberFormatSymbols_en_ER', 'goog.i18n.NumberFormatSymbols_en_FI', 'goog.i18n.NumberFormatSymbols_en_FJ', 'goog.i18n.NumberFormatSymbols_en_FK', 'goog.i18n.NumberFormatSymbols_en_FM', 'goog.i18n.NumberFormatSymbols_en_GD', 'goog.i18n.NumberFormatSymbols_en_GG', 'goog.i18n.NumberFormatSymbols_en_GH', 'goog.i18n.NumberFormatSymbols_en_GI', 'goog.i18n.NumberFormatSymbols_en_GM', 'goog.i18n.NumberFormatSymbols_en_GU', 'goog.i18n.NumberFormatSymbols_en_GY', 'goog.i18n.NumberFormatSymbols_en_HK', 'goog.i18n.NumberFormatSymbols_en_IL', 'goog.i18n.NumberFormatSymbols_en_IM', 'goog.i18n.NumberFormatSymbols_en_IO', 'goog.i18n.NumberFormatSymbols_en_JE', 'goog.i18n.NumberFormatSymbols_en_JM', 'goog.i18n.NumberFormatSymbols_en_KE', 'goog.i18n.NumberFormatSymbols_en_KI', 'goog.i18n.NumberFormatSymbols_en_KN', 'goog.i18n.NumberFormatSymbols_en_KY', 'goog.i18n.NumberFormatSymbols_en_LC', 'goog.i18n.NumberFormatSymbols_en_LR', 'goog.i18n.NumberFormatSymbols_en_LS', 'goog.i18n.NumberFormatSymbols_en_MG', 'goog.i18n.NumberFormatSymbols_en_MH', 'goog.i18n.NumberFormatSymbols_en_MO', 'goog.i18n.NumberFormatSymbols_en_MP', 'goog.i18n.NumberFormatSymbols_en_MS', 'goog.i18n.NumberFormatSymbols_en_MT', 'goog.i18n.NumberFormatSymbols_en_MU', 'goog.i18n.NumberFormatSymbols_en_MW', 'goog.i18n.NumberFormatSymbols_en_MY', 'goog.i18n.NumberFormatSymbols_en_NA', 'goog.i18n.NumberFormatSymbols_en_NF', 'goog.i18n.NumberFormatSymbols_en_NG', 'goog.i18n.NumberFormatSymbols_en_NL', 'goog.i18n.NumberFormatSymbols_en_NR', 'goog.i18n.NumberFormatSymbols_en_NU', 'goog.i18n.NumberFormatSymbols_en_NZ', 'goog.i18n.NumberFormatSymbols_en_PG', 'goog.i18n.NumberFormatSymbols_en_PH', 'goog.i18n.NumberFormatSymbols_en_PK', 'goog.i18n.NumberFormatSymbols_en_PN', 'goog.i18n.NumberFormatSymbols_en_PR', 'goog.i18n.NumberFormatSymbols_en_PW', 'goog.i18n.NumberFormatSymbols_en_RW', 'goog.i18n.NumberFormatSymbols_en_SB', 'goog.i18n.NumberFormatSymbols_en_SC', 'goog.i18n.NumberFormatSymbols_en_SD', 'goog.i18n.NumberFormatSymbols_en_SE', 'goog.i18n.NumberFormatSymbols_en_SH', 'goog.i18n.NumberFormatSymbols_en_SI', 'goog.i18n.NumberFormatSymbols_en_SL', 'goog.i18n.NumberFormatSymbols_en_SS', 'goog.i18n.NumberFormatSymbols_en_SX', 'goog.i18n.NumberFormatSymbols_en_SZ', 'goog.i18n.NumberFormatSymbols_en_TC', 'goog.i18n.NumberFormatSymbols_en_TK', 'goog.i18n.NumberFormatSymbols_en_TO', 'goog.i18n.NumberFormatSymbols_en_TT', 'goog.i18n.NumberFormatSymbols_en_TV', 'goog.i18n.NumberFormatSymbols_en_TZ', 'goog.i18n.NumberFormatSymbols_en_UG', 'goog.i18n.NumberFormatSymbols_en_UM', 'goog.i18n.NumberFormatSymbols_en_US_POSIX', 'goog.i18n.NumberFormatSymbols_en_VC', 'goog.i18n.NumberFormatSymbols_en_VG', 'goog.i18n.NumberFormatSymbols_en_VI', 'goog.i18n.NumberFormatSymbols_en_VU', 'goog.i18n.NumberFormatSymbols_en_WS', 'goog.i18n.NumberFormatSymbols_en_XA', 'goog.i18n.NumberFormatSymbols_en_ZM', 'goog.i18n.NumberFormatSymbols_en_ZW', 'goog.i18n.NumberFormatSymbols_eo', 'goog.i18n.NumberFormatSymbols_es_AR', 'goog.i18n.NumberFormatSymbols_es_BO', 'goog.i18n.NumberFormatSymbols_es_BR', 'goog.i18n.NumberFormatSymbols_es_CL', 'goog.i18n.NumberFormatSymbols_es_CO', 'goog.i18n.NumberFormatSymbols_es_CR', 'goog.i18n.NumberFormatSymbols_es_CU', 'goog.i18n.NumberFormatSymbols_es_DO', 'goog.i18n.NumberFormatSymbols_es_EA', 'goog.i18n.NumberFormatSymbols_es_EC', 'goog.i18n.NumberFormatSymbols_es_GQ', 'goog.i18n.NumberFormatSymbols_es_GT', 'goog.i18n.NumberFormatSymbols_es_HN', 'goog.i18n.NumberFormatSymbols_es_IC', 'goog.i18n.NumberFormatSymbols_es_NI', 'goog.i18n.NumberFormatSymbols_es_PA', 'goog.i18n.NumberFormatSymbols_es_PE', 'goog.i18n.NumberFormatSymbols_es_PH', 'goog.i18n.NumberFormatSymbols_es_PR', 'goog.i18n.NumberFormatSymbols_es_PY', 'goog.i18n.NumberFormatSymbols_es_SV', 'goog.i18n.NumberFormatSymbols_es_UY', 'goog.i18n.NumberFormatSymbols_es_VE', 'goog.i18n.NumberFormatSymbols_et_EE', 'goog.i18n.NumberFormatSymbols_eu_ES', 'goog.i18n.NumberFormatSymbols_ewo', 'goog.i18n.NumberFormatSymbols_ewo_CM', 'goog.i18n.NumberFormatSymbols_fa_AF', 'goog.i18n.NumberFormatSymbols_fa_IR', 'goog.i18n.NumberFormatSymbols_ff', 'goog.i18n.NumberFormatSymbols_ff_CM', 'goog.i18n.NumberFormatSymbols_ff_GN', 'goog.i18n.NumberFormatSymbols_ff_MR', 'goog.i18n.NumberFormatSymbols_ff_SN', 'goog.i18n.NumberFormatSymbols_fi_FI', 'goog.i18n.NumberFormatSymbols_fil_PH', 'goog.i18n.NumberFormatSymbols_fo', 'goog.i18n.NumberFormatSymbols_fo_DK', 'goog.i18n.NumberFormatSymbols_fo_FO', 'goog.i18n.NumberFormatSymbols_fr_BE', 'goog.i18n.NumberFormatSymbols_fr_BF', 'goog.i18n.NumberFormatSymbols_fr_BI', 'goog.i18n.NumberFormatSymbols_fr_BJ', 'goog.i18n.NumberFormatSymbols_fr_BL', 'goog.i18n.NumberFormatSymbols_fr_CD', 'goog.i18n.NumberFormatSymbols_fr_CF', 'goog.i18n.NumberFormatSymbols_fr_CG', 'goog.i18n.NumberFormatSymbols_fr_CH', 'goog.i18n.NumberFormatSymbols_fr_CI', 'goog.i18n.NumberFormatSymbols_fr_CM', 'goog.i18n.NumberFormatSymbols_fr_DJ', 'goog.i18n.NumberFormatSymbols_fr_DZ', 'goog.i18n.NumberFormatSymbols_fr_FR', 'goog.i18n.NumberFormatSymbols_fr_GA', 'goog.i18n.NumberFormatSymbols_fr_GF', 'goog.i18n.NumberFormatSymbols_fr_GN', 'goog.i18n.NumberFormatSymbols_fr_GP', 'goog.i18n.NumberFormatSymbols_fr_GQ', 'goog.i18n.NumberFormatSymbols_fr_HT', 'goog.i18n.NumberFormatSymbols_fr_KM', 'goog.i18n.NumberFormatSymbols_fr_LU', 'goog.i18n.NumberFormatSymbols_fr_MA', 'goog.i18n.NumberFormatSymbols_fr_MC', 'goog.i18n.NumberFormatSymbols_fr_MF', 'goog.i18n.NumberFormatSymbols_fr_MG', 'goog.i18n.NumberFormatSymbols_fr_ML', 'goog.i18n.NumberFormatSymbols_fr_MQ', 'goog.i18n.NumberFormatSymbols_fr_MR', 'goog.i18n.NumberFormatSymbols_fr_MU', 'goog.i18n.NumberFormatSymbols_fr_NC', 'goog.i18n.NumberFormatSymbols_fr_NE', 'goog.i18n.NumberFormatSymbols_fr_PF', 'goog.i18n.NumberFormatSymbols_fr_PM', 'goog.i18n.NumberFormatSymbols_fr_RE', 'goog.i18n.NumberFormatSymbols_fr_RW', 'goog.i18n.NumberFormatSymbols_fr_SC', 'goog.i18n.NumberFormatSymbols_fr_SN', 'goog.i18n.NumberFormatSymbols_fr_SY', 'goog.i18n.NumberFormatSymbols_fr_TD', 'goog.i18n.NumberFormatSymbols_fr_TG', 'goog.i18n.NumberFormatSymbols_fr_TN', 'goog.i18n.NumberFormatSymbols_fr_VU', 'goog.i18n.NumberFormatSymbols_fr_WF', 'goog.i18n.NumberFormatSymbols_fr_YT', 'goog.i18n.NumberFormatSymbols_fur', 'goog.i18n.NumberFormatSymbols_fur_IT', 'goog.i18n.NumberFormatSymbols_fy', 'goog.i18n.NumberFormatSymbols_fy_NL', 'goog.i18n.NumberFormatSymbols_ga_IE', 'goog.i18n.NumberFormatSymbols_gd', 'goog.i18n.NumberFormatSymbols_gd_GB', 'goog.i18n.NumberFormatSymbols_gl_ES', 'goog.i18n.NumberFormatSymbols_gsw_CH', 'goog.i18n.NumberFormatSymbols_gsw_FR', 'goog.i18n.NumberFormatSymbols_gsw_LI', 'goog.i18n.NumberFormatSymbols_gu_IN', 'goog.i18n.NumberFormatSymbols_guz', 'goog.i18n.NumberFormatSymbols_guz_KE', 'goog.i18n.NumberFormatSymbols_gv', 'goog.i18n.NumberFormatSymbols_gv_IM', 'goog.i18n.NumberFormatSymbols_ha', 'goog.i18n.NumberFormatSymbols_ha_GH', 'goog.i18n.NumberFormatSymbols_ha_NE', 'goog.i18n.NumberFormatSymbols_ha_NG', 'goog.i18n.NumberFormatSymbols_haw_US', 'goog.i18n.NumberFormatSymbols_he_IL', 'goog.i18n.NumberFormatSymbols_hi_IN', 'goog.i18n.NumberFormatSymbols_hr_BA', 'goog.i18n.NumberFormatSymbols_hr_HR', 'goog.i18n.NumberFormatSymbols_hsb', 'goog.i18n.NumberFormatSymbols_hsb_DE', 'goog.i18n.NumberFormatSymbols_hu_HU', 'goog.i18n.NumberFormatSymbols_hy_AM', 'goog.i18n.NumberFormatSymbols_id_ID', 'goog.i18n.NumberFormatSymbols_ig', 'goog.i18n.NumberFormatSymbols_ig_NG', 'goog.i18n.NumberFormatSymbols_ii', 'goog.i18n.NumberFormatSymbols_ii_CN', 'goog.i18n.NumberFormatSymbols_is_IS', 'goog.i18n.NumberFormatSymbols_it_CH', 'goog.i18n.NumberFormatSymbols_it_IT', 'goog.i18n.NumberFormatSymbols_it_SM', 'goog.i18n.NumberFormatSymbols_ja_JP', 'goog.i18n.NumberFormatSymbols_jgo', 'goog.i18n.NumberFormatSymbols_jgo_CM', 'goog.i18n.NumberFormatSymbols_jmc', 'goog.i18n.NumberFormatSymbols_jmc_TZ', 'goog.i18n.NumberFormatSymbols_ka_GE', 'goog.i18n.NumberFormatSymbols_kab', 'goog.i18n.NumberFormatSymbols_kab_DZ', 'goog.i18n.NumberFormatSymbols_kam', 'goog.i18n.NumberFormatSymbols_kam_KE', 'goog.i18n.NumberFormatSymbols_kde', 'goog.i18n.NumberFormatSymbols_kde_TZ', 'goog.i18n.NumberFormatSymbols_kea', 'goog.i18n.NumberFormatSymbols_kea_CV', 'goog.i18n.NumberFormatSymbols_khq', 'goog.i18n.NumberFormatSymbols_khq_ML', 'goog.i18n.NumberFormatSymbols_ki', 'goog.i18n.NumberFormatSymbols_ki_KE', 'goog.i18n.NumberFormatSymbols_kk_KZ', 'goog.i18n.NumberFormatSymbols_kkj', 'goog.i18n.NumberFormatSymbols_kkj_CM', 'goog.i18n.NumberFormatSymbols_kl', 'goog.i18n.NumberFormatSymbols_kl_GL', 'goog.i18n.NumberFormatSymbols_kln', 'goog.i18n.NumberFormatSymbols_kln_KE', 'goog.i18n.NumberFormatSymbols_km_KH', 'goog.i18n.NumberFormatSymbols_kn_IN', 'goog.i18n.NumberFormatSymbols_ko_KP', 'goog.i18n.NumberFormatSymbols_ko_KR', 'goog.i18n.NumberFormatSymbols_kok', 'goog.i18n.NumberFormatSymbols_kok_IN', 'goog.i18n.NumberFormatSymbols_ks', 'goog.i18n.NumberFormatSymbols_ks_IN', 'goog.i18n.NumberFormatSymbols_ksb', 'goog.i18n.NumberFormatSymbols_ksb_TZ', 'goog.i18n.NumberFormatSymbols_ksf', 'goog.i18n.NumberFormatSymbols_ksf_CM', 'goog.i18n.NumberFormatSymbols_ksh', 'goog.i18n.NumberFormatSymbols_ksh_DE', 'goog.i18n.NumberFormatSymbols_kw', 'goog.i18n.NumberFormatSymbols_kw_GB', 'goog.i18n.NumberFormatSymbols_ky_KG', 'goog.i18n.NumberFormatSymbols_lag', 'goog.i18n.NumberFormatSymbols_lag_TZ', 'goog.i18n.NumberFormatSymbols_lb', 'goog.i18n.NumberFormatSymbols_lb_LU', 'goog.i18n.NumberFormatSymbols_lg', 'goog.i18n.NumberFormatSymbols_lg_UG', 'goog.i18n.NumberFormatSymbols_lkt', 'goog.i18n.NumberFormatSymbols_lkt_US', 'goog.i18n.NumberFormatSymbols_ln_AO', 'goog.i18n.NumberFormatSymbols_ln_CD', 'goog.i18n.NumberFormatSymbols_ln_CF', 'goog.i18n.NumberFormatSymbols_ln_CG', 'goog.i18n.NumberFormatSymbols_lo_LA', 'goog.i18n.NumberFormatSymbols_lrc', 'goog.i18n.NumberFormatSymbols_lrc_IQ', 'goog.i18n.NumberFormatSymbols_lrc_IR', 'goog.i18n.NumberFormatSymbols_lt_LT', 'goog.i18n.NumberFormatSymbols_lu', 'goog.i18n.NumberFormatSymbols_lu_CD', 'goog.i18n.NumberFormatSymbols_luo', 'goog.i18n.NumberFormatSymbols_luo_KE', 'goog.i18n.NumberFormatSymbols_luy', 'goog.i18n.NumberFormatSymbols_luy_KE', 'goog.i18n.NumberFormatSymbols_lv_LV', 'goog.i18n.NumberFormatSymbols_mas', 'goog.i18n.NumberFormatSymbols_mas_KE', 'goog.i18n.NumberFormatSymbols_mas_TZ', 'goog.i18n.NumberFormatSymbols_mer', 'goog.i18n.NumberFormatSymbols_mer_KE', 'goog.i18n.NumberFormatSymbols_mfe', 'goog.i18n.NumberFormatSymbols_mfe_MU', 'goog.i18n.NumberFormatSymbols_mg', 'goog.i18n.NumberFormatSymbols_mg_MG', 'goog.i18n.NumberFormatSymbols_mgh', 'goog.i18n.NumberFormatSymbols_mgh_MZ', 'goog.i18n.NumberFormatSymbols_mgo', 'goog.i18n.NumberFormatSymbols_mgo_CM', 'goog.i18n.NumberFormatSymbols_mk_MK', 'goog.i18n.NumberFormatSymbols_ml_IN', 'goog.i18n.NumberFormatSymbols_mn_MN', 'goog.i18n.NumberFormatSymbols_mr_IN', 'goog.i18n.NumberFormatSymbols_ms_BN', 'goog.i18n.NumberFormatSymbols_ms_MY', 'goog.i18n.NumberFormatSymbols_ms_SG', 'goog.i18n.NumberFormatSymbols_mt_MT', 'goog.i18n.NumberFormatSymbols_mua', 'goog.i18n.NumberFormatSymbols_mua_CM', 'goog.i18n.NumberFormatSymbols_my_MM', 'goog.i18n.NumberFormatSymbols_mzn', 'goog.i18n.NumberFormatSymbols_mzn_IR', 'goog.i18n.NumberFormatSymbols_naq', 'goog.i18n.NumberFormatSymbols_naq_NA', 'goog.i18n.NumberFormatSymbols_nb_NO', 'goog.i18n.NumberFormatSymbols_nb_SJ', 'goog.i18n.NumberFormatSymbols_nd', 'goog.i18n.NumberFormatSymbols_nd_ZW', 'goog.i18n.NumberFormatSymbols_nds', 'goog.i18n.NumberFormatSymbols_nds_DE', 'goog.i18n.NumberFormatSymbols_nds_NL', 'goog.i18n.NumberFormatSymbols_ne_IN', 'goog.i18n.NumberFormatSymbols_ne_NP', 'goog.i18n.NumberFormatSymbols_nl_AW', 'goog.i18n.NumberFormatSymbols_nl_BE', 'goog.i18n.NumberFormatSymbols_nl_BQ', 'goog.i18n.NumberFormatSymbols_nl_CW', 'goog.i18n.NumberFormatSymbols_nl_NL', 'goog.i18n.NumberFormatSymbols_nl_SR', 'goog.i18n.NumberFormatSymbols_nl_SX', 'goog.i18n.NumberFormatSymbols_nmg', 'goog.i18n.NumberFormatSymbols_nmg_CM', 'goog.i18n.NumberFormatSymbols_nn', 'goog.i18n.NumberFormatSymbols_nn_NO', 'goog.i18n.NumberFormatSymbols_nnh', 'goog.i18n.NumberFormatSymbols_nnh_CM', 'goog.i18n.NumberFormatSymbols_nus', 'goog.i18n.NumberFormatSymbols_nus_SS', 'goog.i18n.NumberFormatSymbols_nyn', 'goog.i18n.NumberFormatSymbols_nyn_UG', 'goog.i18n.NumberFormatSymbols_om', 'goog.i18n.NumberFormatSymbols_om_ET', 'goog.i18n.NumberFormatSymbols_om_KE', 'goog.i18n.NumberFormatSymbols_or_IN', 'goog.i18n.NumberFormatSymbols_os', 'goog.i18n.NumberFormatSymbols_os_GE', 'goog.i18n.NumberFormatSymbols_os_RU', 'goog.i18n.NumberFormatSymbols_pa_Arab', 'goog.i18n.NumberFormatSymbols_pa_Arab_PK', 'goog.i18n.NumberFormatSymbols_pa_Guru', 'goog.i18n.NumberFormatSymbols_pa_Guru_IN', 'goog.i18n.NumberFormatSymbols_pl_PL', 'goog.i18n.NumberFormatSymbols_ps', 'goog.i18n.NumberFormatSymbols_ps_AF', 'goog.i18n.NumberFormatSymbols_pt_AO', 'goog.i18n.NumberFormatSymbols_pt_CH', 'goog.i18n.NumberFormatSymbols_pt_CV', 'goog.i18n.NumberFormatSymbols_pt_GQ', 'goog.i18n.NumberFormatSymbols_pt_GW', 'goog.i18n.NumberFormatSymbols_pt_LU', 'goog.i18n.NumberFormatSymbols_pt_MO', 'goog.i18n.NumberFormatSymbols_pt_MZ', 'goog.i18n.NumberFormatSymbols_pt_ST', 'goog.i18n.NumberFormatSymbols_pt_TL', 'goog.i18n.NumberFormatSymbols_qu', 'goog.i18n.NumberFormatSymbols_qu_BO', 'goog.i18n.NumberFormatSymbols_qu_EC', 'goog.i18n.NumberFormatSymbols_qu_PE', 'goog.i18n.NumberFormatSymbols_rm', 'goog.i18n.NumberFormatSymbols_rm_CH', 'goog.i18n.NumberFormatSymbols_rn', 'goog.i18n.NumberFormatSymbols_rn_BI', 'goog.i18n.NumberFormatSymbols_ro_MD', 'goog.i18n.NumberFormatSymbols_ro_RO', 'goog.i18n.NumberFormatSymbols_rof', 'goog.i18n.NumberFormatSymbols_rof_TZ', 'goog.i18n.NumberFormatSymbols_ru_BY', 'goog.i18n.NumberFormatSymbols_ru_KG', 'goog.i18n.NumberFormatSymbols_ru_KZ', 'goog.i18n.NumberFormatSymbols_ru_MD', 'goog.i18n.NumberFormatSymbols_ru_RU', 'goog.i18n.NumberFormatSymbols_ru_UA', 'goog.i18n.NumberFormatSymbols_rw', 'goog.i18n.NumberFormatSymbols_rw_RW', 'goog.i18n.NumberFormatSymbols_rwk', 'goog.i18n.NumberFormatSymbols_rwk_TZ', 'goog.i18n.NumberFormatSymbols_sah', 'goog.i18n.NumberFormatSymbols_sah_RU', 'goog.i18n.NumberFormatSymbols_saq', 'goog.i18n.NumberFormatSymbols_saq_KE', 'goog.i18n.NumberFormatSymbols_sbp', 'goog.i18n.NumberFormatSymbols_sbp_TZ', 'goog.i18n.NumberFormatSymbols_se', 'goog.i18n.NumberFormatSymbols_se_FI', 'goog.i18n.NumberFormatSymbols_se_NO', 'goog.i18n.NumberFormatSymbols_se_SE', 'goog.i18n.NumberFormatSymbols_seh', 'goog.i18n.NumberFormatSymbols_seh_MZ', 'goog.i18n.NumberFormatSymbols_ses', 'goog.i18n.NumberFormatSymbols_ses_ML', 'goog.i18n.NumberFormatSymbols_sg', 'goog.i18n.NumberFormatSymbols_sg_CF', 'goog.i18n.NumberFormatSymbols_shi', 'goog.i18n.NumberFormatSymbols_shi_Latn', 'goog.i18n.NumberFormatSymbols_shi_Latn_MA', 'goog.i18n.NumberFormatSymbols_shi_Tfng', 'goog.i18n.NumberFormatSymbols_shi_Tfng_MA', 'goog.i18n.NumberFormatSymbols_si_LK', 'goog.i18n.NumberFormatSymbols_sk_SK', 'goog.i18n.NumberFormatSymbols_sl_SI', 'goog.i18n.NumberFormatSymbols_smn', 'goog.i18n.NumberFormatSymbols_smn_FI', 'goog.i18n.NumberFormatSymbols_sn', 'goog.i18n.NumberFormatSymbols_sn_ZW', 'goog.i18n.NumberFormatSymbols_so', 'goog.i18n.NumberFormatSymbols_so_DJ', 'goog.i18n.NumberFormatSymbols_so_ET', 'goog.i18n.NumberFormatSymbols_so_KE', 'goog.i18n.NumberFormatSymbols_so_SO', 'goog.i18n.NumberFormatSymbols_sq_AL', 'goog.i18n.NumberFormatSymbols_sq_MK', 'goog.i18n.NumberFormatSymbols_sq_XK', 'goog.i18n.NumberFormatSymbols_sr_Cyrl', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_BA', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_ME', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_RS', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_XK', 'goog.i18n.NumberFormatSymbols_sr_Latn_BA', 'goog.i18n.NumberFormatSymbols_sr_Latn_ME', 'goog.i18n.NumberFormatSymbols_sr_Latn_RS', 'goog.i18n.NumberFormatSymbols_sr_Latn_XK', 'goog.i18n.NumberFormatSymbols_sv_AX', 'goog.i18n.NumberFormatSymbols_sv_FI', 'goog.i18n.NumberFormatSymbols_sv_SE', 'goog.i18n.NumberFormatSymbols_sw_CD', 'goog.i18n.NumberFormatSymbols_sw_KE', 'goog.i18n.NumberFormatSymbols_sw_TZ', 'goog.i18n.NumberFormatSymbols_sw_UG', 'goog.i18n.NumberFormatSymbols_ta_IN', 'goog.i18n.NumberFormatSymbols_ta_LK', 'goog.i18n.NumberFormatSymbols_ta_MY', 'goog.i18n.NumberFormatSymbols_ta_SG', 'goog.i18n.NumberFormatSymbols_te_IN', 'goog.i18n.NumberFormatSymbols_teo', 'goog.i18n.NumberFormatSymbols_teo_KE', 'goog.i18n.NumberFormatSymbols_teo_UG', 'goog.i18n.NumberFormatSymbols_th_TH', 'goog.i18n.NumberFormatSymbols_ti', 'goog.i18n.NumberFormatSymbols_ti_ER', 'goog.i18n.NumberFormatSymbols_ti_ET', 'goog.i18n.NumberFormatSymbols_to', 'goog.i18n.NumberFormatSymbols_to_TO', 'goog.i18n.NumberFormatSymbols_tr_CY', 'goog.i18n.NumberFormatSymbols_tr_TR', 'goog.i18n.NumberFormatSymbols_twq', 'goog.i18n.NumberFormatSymbols_twq_NE', 'goog.i18n.NumberFormatSymbols_tzm', 'goog.i18n.NumberFormatSymbols_tzm_MA', 'goog.i18n.NumberFormatSymbols_ug', 'goog.i18n.NumberFormatSymbols_ug_CN', 'goog.i18n.NumberFormatSymbols_uk_UA', 'goog.i18n.NumberFormatSymbols_ur_IN', 'goog.i18n.NumberFormatSymbols_ur_PK', 'goog.i18n.NumberFormatSymbols_uz_Arab', 'goog.i18n.NumberFormatSymbols_uz_Arab_AF', 'goog.i18n.NumberFormatSymbols_uz_Cyrl', 'goog.i18n.NumberFormatSymbols_uz_Cyrl_UZ', 'goog.i18n.NumberFormatSymbols_uz_Latn', 'goog.i18n.NumberFormatSymbols_uz_Latn_UZ', 'goog.i18n.NumberFormatSymbols_vai', 'goog.i18n.NumberFormatSymbols_vai_Latn', 'goog.i18n.NumberFormatSymbols_vai_Latn_LR', 'goog.i18n.NumberFormatSymbols_vai_Vaii', 'goog.i18n.NumberFormatSymbols_vai_Vaii_LR', 'goog.i18n.NumberFormatSymbols_vi_VN', 'goog.i18n.NumberFormatSymbols_vun', 'goog.i18n.NumberFormatSymbols_vun_TZ', 'goog.i18n.NumberFormatSymbols_wae', 'goog.i18n.NumberFormatSymbols_wae_CH', 'goog.i18n.NumberFormatSymbols_xog', 'goog.i18n.NumberFormatSymbols_xog_UG', 'goog.i18n.NumberFormatSymbols_yav', 'goog.i18n.NumberFormatSymbols_yav_CM', 'goog.i18n.NumberFormatSymbols_yi', 'goog.i18n.NumberFormatSymbols_yi_001', 'goog.i18n.NumberFormatSymbols_yo', 'goog.i18n.NumberFormatSymbols_yo_BJ', 'goog.i18n.NumberFormatSymbols_yo_NG', 'goog.i18n.NumberFormatSymbols_yue', 'goog.i18n.NumberFormatSymbols_yue_HK', 'goog.i18n.NumberFormatSymbols_zgh', 'goog.i18n.NumberFormatSymbols_zgh_MA', 'goog.i18n.NumberFormatSymbols_zh_Hans', 'goog.i18n.NumberFormatSymbols_zh_Hans_CN', 'goog.i18n.NumberFormatSymbols_zh_Hans_HK', 'goog.i18n.NumberFormatSymbols_zh_Hans_MO', 'goog.i18n.NumberFormatSymbols_zh_Hans_SG', 'goog.i18n.NumberFormatSymbols_zh_Hant', 'goog.i18n.NumberFormatSymbols_zh_Hant_HK', 'goog.i18n.NumberFormatSymbols_zh_Hant_MO', 'goog.i18n.NumberFormatSymbols_zh_Hant_TW', 'goog.i18n.NumberFormatSymbols_zu_ZA'], ['goog.i18n.NumberFormatSymbols']);
                +goog.addDependency("i18n/ordinalrules.js", ['goog.i18n.ordinalRules'], []);
                +goog.addDependency("i18n/pluralrules.js", ['goog.i18n.pluralRules'], []);
                +goog.addDependency("i18n/pluralrules_test.js", ['goog.i18n.pluralRulesTest'], ['goog.i18n.pluralRules', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/timezone.js", ['goog.i18n.TimeZone'], ['goog.array', 'goog.date.DateLike', 'goog.object', 'goog.string']);
                +goog.addDependency("i18n/timezone_test.js", ['goog.i18n.TimeZoneTest'], ['goog.i18n.TimeZone', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/uchar.js", ['goog.i18n.uChar'], []);
                +goog.addDependency("i18n/uchar/localnamefetcher.js", ['goog.i18n.uChar.LocalNameFetcher'], ['goog.i18n.uChar.NameFetcher', 'goog.i18n.uCharNames', 'goog.log']);
                +goog.addDependency("i18n/uchar/localnamefetcher_test.js", ['goog.i18n.uChar.LocalNameFetcherTest'], ['goog.i18n.uChar.LocalNameFetcher', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("i18n/uchar/namefetcher.js", ['goog.i18n.uChar.NameFetcher'], []);
                +goog.addDependency("i18n/uchar/remotenamefetcher.js", ['goog.i18n.uChar.RemoteNameFetcher'], ['goog.Disposable', 'goog.Uri', 'goog.events', 'goog.i18n.uChar', 'goog.i18n.uChar.NameFetcher', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.structs.Map']);
                +goog.addDependency("i18n/uchar/remotenamefetcher_test.js", ['goog.i18n.uChar.RemoteNameFetcherTest'], ['goog.i18n.uChar.RemoteNameFetcher', 'goog.net.XhrIo', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("i18n/uchar_test.js", ['goog.i18n.uCharTest'], ['goog.i18n.uChar', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/ucharnames.js", ['goog.i18n.uCharNames'], ['goog.i18n.uChar']);
                +goog.addDependency("i18n/ucharnames_test.js", ['goog.i18n.uCharNamesTest'], ['goog.i18n.uCharNames', 'goog.testing.jsunit']);
                +goog.addDependency("iter/iter.js", ['goog.iter', 'goog.iter.Iterable', 'goog.iter.Iterator', 'goog.iter.StopIteration'], ['goog.array', 'goog.asserts', 'goog.functions', 'goog.math']);
                +goog.addDependency("iter/iter_test.js", ['goog.iterTest'], ['goog.iter', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.testing.jsunit']);
                +goog.addDependency("json/evaljsonprocessor.js", ['goog.json.EvalJsonProcessor'], ['goog.json', 'goog.json.Processor', 'goog.json.Serializer']);
                +goog.addDependency("json/hybrid.js", ['goog.json.hybrid'], ['goog.asserts', 'goog.json']);
                +goog.addDependency("json/hybrid_test.js", ['goog.json.hybridTest'], ['goog.json', 'goog.json.hybrid', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("json/hybridjsonprocessor.js", ['goog.json.HybridJsonProcessor'], ['goog.json.Processor', 'goog.json.hybrid']);
                +goog.addDependency("json/hybridjsonprocessor_test.js", ['goog.json.HybridJsonProcessorTest'], ['goog.json.HybridJsonProcessor', 'goog.json.hybrid', 'goog.testing.jsunit']);
                +goog.addDependency("json/json.js", ['goog.json', 'goog.json.Replacer', 'goog.json.Reviver', 'goog.json.Serializer'], []);
                +goog.addDependency("json/json_perf.js", ['goog.jsonPerf'], ['goog.dom', 'goog.json', 'goog.math', 'goog.string', 'goog.testing.PerformanceTable', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("json/json_test.js", ['goog.jsonTest'], ['goog.functions', 'goog.json', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("json/nativejsonprocessor.js", ['goog.json.NativeJsonProcessor'], ['goog.asserts', 'goog.json.Processor']);
                +goog.addDependency("json/processor.js", ['goog.json.Processor'], ['goog.string.Parser', 'goog.string.Stringifier']);
                +goog.addDependency("json/processor_test.js", ['goog.json.processorTest'], ['goog.json.EvalJsonProcessor', 'goog.json.NativeJsonProcessor', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("labs/dom/pagevisibilitymonitor.js", ['goog.labs.dom.PageVisibilityEvent', 'goog.labs.dom.PageVisibilityMonitor', 'goog.labs.dom.PageVisibilityState'], ['goog.dom', 'goog.dom.vendor', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.memoize']);
                +goog.addDependency("labs/dom/pagevisibilitymonitor_test.js", ['goog.labs.dom.PageVisibilityMonitorTest'], ['goog.events', 'goog.functions', 'goog.labs.dom.PageVisibilityMonitor', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/events/nondisposableeventtarget.js", ['goog.labs.events.NonDisposableEventTarget'], ['goog.array', 'goog.asserts', 'goog.events.Event', 'goog.events.Listenable', 'goog.events.ListenerMap', 'goog.object']);
                +goog.addDependency("labs/events/nondisposableeventtarget_test.js", ['goog.labs.events.NonDisposableEventTargetTest'], ['goog.events.Listenable', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.labs.events.NonDisposableEventTarget', 'goog.testing.jsunit']);
                +goog.addDependency("labs/events/nondisposableeventtarget_via_googevents_test.js", ['goog.labs.events.NonDisposableEventTargetGoogEventsTest'], ['goog.events', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.labs.events.NonDisposableEventTarget', 'goog.testing', 'goog.testing.jsunit']);
                +goog.addDependency("labs/events/touch.js", ['goog.labs.events.touch', 'goog.labs.events.touch.TouchData'], ['goog.array', 'goog.asserts', 'goog.events.EventType', 'goog.string']);
                +goog.addDependency("labs/events/touch_test.js", ['goog.labs.events.touchTest'], ['goog.labs.events.touch', 'goog.testing.jsunit']);
                +goog.addDependency("labs/format/csv.js", ['goog.labs.format.csv', 'goog.labs.format.csv.ParseError', 'goog.labs.format.csv.Token'], ['goog.array', 'goog.asserts', 'goog.debug.Error', 'goog.object', 'goog.string', 'goog.string.newlines']);
                +goog.addDependency("labs/format/csv_test.js", ['goog.labs.format.csvTest'], ['goog.labs.format.csv', 'goog.labs.format.csv.ParseError', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/i18n/listformat.js", ['goog.labs.i18n.GenderInfo', 'goog.labs.i18n.GenderInfo.Gender', 'goog.labs.i18n.ListFormat'], ['goog.asserts', 'goog.labs.i18n.ListFormatSymbols']);
                +goog.addDependency("labs/i18n/listformat_test.js", ['goog.labs.i18n.ListFormatTest'], ['goog.labs.i18n.GenderInfo', 'goog.labs.i18n.ListFormat', 'goog.labs.i18n.ListFormatSymbols', 'goog.labs.i18n.ListFormatSymbols_el', 'goog.labs.i18n.ListFormatSymbols_en', 'goog.labs.i18n.ListFormatSymbols_fr', 'goog.labs.i18n.ListFormatSymbols_ml', 'goog.labs.i18n.ListFormatSymbols_zu', 'goog.testing.jsunit']);
                +goog.addDependency("labs/i18n/listsymbols.js", ['goog.labs.i18n.ListFormatSymbols', 'goog.labs.i18n.ListFormatSymbols_af', 'goog.labs.i18n.ListFormatSymbols_am', 'goog.labs.i18n.ListFormatSymbols_ar', 'goog.labs.i18n.ListFormatSymbols_ar_DZ', 'goog.labs.i18n.ListFormatSymbols_az', 'goog.labs.i18n.ListFormatSymbols_be', 'goog.labs.i18n.ListFormatSymbols_bg', 'goog.labs.i18n.ListFormatSymbols_bn', 'goog.labs.i18n.ListFormatSymbols_br', 'goog.labs.i18n.ListFormatSymbols_bs', 'goog.labs.i18n.ListFormatSymbols_ca', 'goog.labs.i18n.ListFormatSymbols_chr', 'goog.labs.i18n.ListFormatSymbols_cs', 'goog.labs.i18n.ListFormatSymbols_cy', 'goog.labs.i18n.ListFormatSymbols_da', 'goog.labs.i18n.ListFormatSymbols_de', 'goog.labs.i18n.ListFormatSymbols_de_AT', 'goog.labs.i18n.ListFormatSymbols_de_CH', 'goog.labs.i18n.ListFormatSymbols_el', 'goog.labs.i18n.ListFormatSymbols_en', 'goog.labs.i18n.ListFormatSymbols_en_AU', 'goog.labs.i18n.ListFormatSymbols_en_CA', 'goog.labs.i18n.ListFormatSymbols_en_GB', 'goog.labs.i18n.ListFormatSymbols_en_IE', 'goog.labs.i18n.ListFormatSymbols_en_IN', 'goog.labs.i18n.ListFormatSymbols_en_SG', 'goog.labs.i18n.ListFormatSymbols_en_US', 'goog.labs.i18n.ListFormatSymbols_en_ZA', 'goog.labs.i18n.ListFormatSymbols_es', 'goog.labs.i18n.ListFormatSymbols_es_419', 'goog.labs.i18n.ListFormatSymbols_es_ES', 'goog.labs.i18n.ListFormatSymbols_es_MX', 'goog.labs.i18n.ListFormatSymbols_es_US', 'goog.labs.i18n.ListFormatSymbols_et', 'goog.labs.i18n.ListFormatSymbols_eu', 'goog.labs.i18n.ListFormatSymbols_fa', 'goog.labs.i18n.ListFormatSymbols_fi', 'goog.labs.i18n.ListFormatSymbols_fil', 'goog.labs.i18n.ListFormatSymbols_fr', 'goog.labs.i18n.ListFormatSymbols_fr_CA', 'goog.labs.i18n.ListFormatSymbols_ga', 'goog.labs.i18n.ListFormatSymbols_gl', 'goog.labs.i18n.ListFormatSymbols_gsw', 'goog.labs.i18n.ListFormatSymbols_gu', 'goog.labs.i18n.ListFormatSymbols_haw', 'goog.labs.i18n.ListFormatSymbols_he', 'goog.labs.i18n.ListFormatSymbols_hi', 'goog.labs.i18n.ListFormatSymbols_hr', 'goog.labs.i18n.ListFormatSymbols_hu', 'goog.labs.i18n.ListFormatSymbols_hy', 'goog.labs.i18n.ListFormatSymbols_id', 'goog.labs.i18n.ListFormatSymbols_in', 'goog.labs.i18n.ListFormatSymbols_is', 'goog.labs.i18n.ListFormatSymbols_it', 'goog.labs.i18n.ListFormatSymbols_iw', 'goog.labs.i18n.ListFormatSymbols_ja', 'goog.labs.i18n.ListFormatSymbols_ka', 'goog.labs.i18n.ListFormatSymbols_kk', 'goog.labs.i18n.ListFormatSymbols_km', 'goog.labs.i18n.ListFormatSymbols_kn', 'goog.labs.i18n.ListFormatSymbols_ko', 'goog.labs.i18n.ListFormatSymbols_ky', 'goog.labs.i18n.ListFormatSymbols_ln', 'goog.labs.i18n.ListFormatSymbols_lo', 'goog.labs.i18n.ListFormatSymbols_lt', 'goog.labs.i18n.ListFormatSymbols_lv', 'goog.labs.i18n.ListFormatSymbols_mk', 'goog.labs.i18n.ListFormatSymbols_ml', 'goog.labs.i18n.ListFormatSymbols_mn', 'goog.labs.i18n.ListFormatSymbols_mo', 'goog.labs.i18n.ListFormatSymbols_mr', 'goog.labs.i18n.ListFormatSymbols_ms', 'goog.labs.i18n.ListFormatSymbols_mt', 'goog.labs.i18n.ListFormatSymbols_my', 'goog.labs.i18n.ListFormatSymbols_nb', 'goog.labs.i18n.ListFormatSymbols_ne', 'goog.labs.i18n.ListFormatSymbols_nl', 'goog.labs.i18n.ListFormatSymbols_no', 'goog.labs.i18n.ListFormatSymbols_no_NO', 'goog.labs.i18n.ListFormatSymbols_or', 'goog.labs.i18n.ListFormatSymbols_pa', 'goog.labs.i18n.ListFormatSymbols_pl', 'goog.labs.i18n.ListFormatSymbols_pt', 'goog.labs.i18n.ListFormatSymbols_pt_BR', 'goog.labs.i18n.ListFormatSymbols_pt_PT', 'goog.labs.i18n.ListFormatSymbols_ro', 'goog.labs.i18n.ListFormatSymbols_ru', 'goog.labs.i18n.ListFormatSymbols_sh', 'goog.labs.i18n.ListFormatSymbols_si', 'goog.labs.i18n.ListFormatSymbols_sk', 'goog.labs.i18n.ListFormatSymbols_sl', 'goog.labs.i18n.ListFormatSymbols_sq', 'goog.labs.i18n.ListFormatSymbols_sr', 'goog.labs.i18n.ListFormatSymbols_sr_Latn', 'goog.labs.i18n.ListFormatSymbols_sv', 'goog.labs.i18n.ListFormatSymbols_sw', 'goog.labs.i18n.ListFormatSymbols_ta', 'goog.labs.i18n.ListFormatSymbols_te', 'goog.labs.i18n.ListFormatSymbols_th', 'goog.labs.i18n.ListFormatSymbols_tl', 'goog.labs.i18n.ListFormatSymbols_tr', 'goog.labs.i18n.ListFormatSymbols_uk', 'goog.labs.i18n.ListFormatSymbols_ur', 'goog.labs.i18n.ListFormatSymbols_uz', 'goog.labs.i18n.ListFormatSymbols_vi', 'goog.labs.i18n.ListFormatSymbols_zh', 'goog.labs.i18n.ListFormatSymbols_zh_CN', 'goog.labs.i18n.ListFormatSymbols_zh_HK', 'goog.labs.i18n.ListFormatSymbols_zh_TW', 'goog.labs.i18n.ListFormatSymbols_zu'], []);
                +goog.addDependency("labs/i18n/listsymbolsext.js", ['goog.labs.i18n.ListFormatSymbolsExt', 'goog.labs.i18n.ListFormatSymbols_af_NA', 'goog.labs.i18n.ListFormatSymbols_af_ZA', 'goog.labs.i18n.ListFormatSymbols_agq', 'goog.labs.i18n.ListFormatSymbols_agq_CM', 'goog.labs.i18n.ListFormatSymbols_ak', 'goog.labs.i18n.ListFormatSymbols_ak_GH', 'goog.labs.i18n.ListFormatSymbols_am_ET', 'goog.labs.i18n.ListFormatSymbols_ar_001', 'goog.labs.i18n.ListFormatSymbols_ar_AE', 'goog.labs.i18n.ListFormatSymbols_ar_BH', 'goog.labs.i18n.ListFormatSymbols_ar_DJ', 'goog.labs.i18n.ListFormatSymbols_ar_EG', 'goog.labs.i18n.ListFormatSymbols_ar_EH', 'goog.labs.i18n.ListFormatSymbols_ar_ER', 'goog.labs.i18n.ListFormatSymbols_ar_IL', 'goog.labs.i18n.ListFormatSymbols_ar_IQ', 'goog.labs.i18n.ListFormatSymbols_ar_JO', 'goog.labs.i18n.ListFormatSymbols_ar_KM', 'goog.labs.i18n.ListFormatSymbols_ar_KW', 'goog.labs.i18n.ListFormatSymbols_ar_LB', 'goog.labs.i18n.ListFormatSymbols_ar_LY', 'goog.labs.i18n.ListFormatSymbols_ar_MA', 'goog.labs.i18n.ListFormatSymbols_ar_MR', 'goog.labs.i18n.ListFormatSymbols_ar_OM', 'goog.labs.i18n.ListFormatSymbols_ar_PS', 'goog.labs.i18n.ListFormatSymbols_ar_QA', 'goog.labs.i18n.ListFormatSymbols_ar_SA', 'goog.labs.i18n.ListFormatSymbols_ar_SD', 'goog.labs.i18n.ListFormatSymbols_ar_SO', 'goog.labs.i18n.ListFormatSymbols_ar_SS', 'goog.labs.i18n.ListFormatSymbols_ar_SY', 'goog.labs.i18n.ListFormatSymbols_ar_TD', 'goog.labs.i18n.ListFormatSymbols_ar_TN', 'goog.labs.i18n.ListFormatSymbols_ar_XB', 'goog.labs.i18n.ListFormatSymbols_ar_YE', 'goog.labs.i18n.ListFormatSymbols_as', 'goog.labs.i18n.ListFormatSymbols_as_IN', 'goog.labs.i18n.ListFormatSymbols_asa', 'goog.labs.i18n.ListFormatSymbols_asa_TZ', 'goog.labs.i18n.ListFormatSymbols_ast', 'goog.labs.i18n.ListFormatSymbols_ast_ES', 'goog.labs.i18n.ListFormatSymbols_az_Cyrl', 'goog.labs.i18n.ListFormatSymbols_az_Cyrl_AZ', 'goog.labs.i18n.ListFormatSymbols_az_Latn', 'goog.labs.i18n.ListFormatSymbols_az_Latn_AZ', 'goog.labs.i18n.ListFormatSymbols_bas', 'goog.labs.i18n.ListFormatSymbols_bas_CM', 'goog.labs.i18n.ListFormatSymbols_be_BY', 'goog.labs.i18n.ListFormatSymbols_bem', 'goog.labs.i18n.ListFormatSymbols_bem_ZM', 'goog.labs.i18n.ListFormatSymbols_bez', 'goog.labs.i18n.ListFormatSymbols_bez_TZ', 'goog.labs.i18n.ListFormatSymbols_bg_BG', 'goog.labs.i18n.ListFormatSymbols_bm', 'goog.labs.i18n.ListFormatSymbols_bm_ML', 'goog.labs.i18n.ListFormatSymbols_bn_BD', 'goog.labs.i18n.ListFormatSymbols_bn_IN', 'goog.labs.i18n.ListFormatSymbols_bo', 'goog.labs.i18n.ListFormatSymbols_bo_CN', 'goog.labs.i18n.ListFormatSymbols_bo_IN', 'goog.labs.i18n.ListFormatSymbols_br_FR', 'goog.labs.i18n.ListFormatSymbols_brx', 'goog.labs.i18n.ListFormatSymbols_brx_IN', 'goog.labs.i18n.ListFormatSymbols_bs_Cyrl', 'goog.labs.i18n.ListFormatSymbols_bs_Cyrl_BA', 'goog.labs.i18n.ListFormatSymbols_bs_Latn', 'goog.labs.i18n.ListFormatSymbols_bs_Latn_BA', 'goog.labs.i18n.ListFormatSymbols_ca_AD', 'goog.labs.i18n.ListFormatSymbols_ca_ES', 'goog.labs.i18n.ListFormatSymbols_ca_FR', 'goog.labs.i18n.ListFormatSymbols_ca_IT', 'goog.labs.i18n.ListFormatSymbols_ce', 'goog.labs.i18n.ListFormatSymbols_ce_RU', 'goog.labs.i18n.ListFormatSymbols_cgg', 'goog.labs.i18n.ListFormatSymbols_cgg_UG', 'goog.labs.i18n.ListFormatSymbols_chr_US', 'goog.labs.i18n.ListFormatSymbols_ckb', 'goog.labs.i18n.ListFormatSymbols_ckb_IQ', 'goog.labs.i18n.ListFormatSymbols_ckb_IR', 'goog.labs.i18n.ListFormatSymbols_cs_CZ', 'goog.labs.i18n.ListFormatSymbols_cy_GB', 'goog.labs.i18n.ListFormatSymbols_da_DK', 'goog.labs.i18n.ListFormatSymbols_da_GL', 'goog.labs.i18n.ListFormatSymbols_dav', 'goog.labs.i18n.ListFormatSymbols_dav_KE', 'goog.labs.i18n.ListFormatSymbols_de_BE', 'goog.labs.i18n.ListFormatSymbols_de_DE', 'goog.labs.i18n.ListFormatSymbols_de_IT', 'goog.labs.i18n.ListFormatSymbols_de_LI', 'goog.labs.i18n.ListFormatSymbols_de_LU', 'goog.labs.i18n.ListFormatSymbols_dje', 'goog.labs.i18n.ListFormatSymbols_dje_NE', 'goog.labs.i18n.ListFormatSymbols_dsb', 'goog.labs.i18n.ListFormatSymbols_dsb_DE', 'goog.labs.i18n.ListFormatSymbols_dua', 'goog.labs.i18n.ListFormatSymbols_dua_CM', 'goog.labs.i18n.ListFormatSymbols_dyo', 'goog.labs.i18n.ListFormatSymbols_dyo_SN', 'goog.labs.i18n.ListFormatSymbols_dz', 'goog.labs.i18n.ListFormatSymbols_dz_BT', 'goog.labs.i18n.ListFormatSymbols_ebu', 'goog.labs.i18n.ListFormatSymbols_ebu_KE', 'goog.labs.i18n.ListFormatSymbols_ee', 'goog.labs.i18n.ListFormatSymbols_ee_GH', 'goog.labs.i18n.ListFormatSymbols_ee_TG', 'goog.labs.i18n.ListFormatSymbols_el_CY', 'goog.labs.i18n.ListFormatSymbols_el_GR', 'goog.labs.i18n.ListFormatSymbols_en_001', 'goog.labs.i18n.ListFormatSymbols_en_150', 'goog.labs.i18n.ListFormatSymbols_en_AG', 'goog.labs.i18n.ListFormatSymbols_en_AI', 'goog.labs.i18n.ListFormatSymbols_en_AS', 'goog.labs.i18n.ListFormatSymbols_en_AT', 'goog.labs.i18n.ListFormatSymbols_en_BB', 'goog.labs.i18n.ListFormatSymbols_en_BE', 'goog.labs.i18n.ListFormatSymbols_en_BI', 'goog.labs.i18n.ListFormatSymbols_en_BM', 'goog.labs.i18n.ListFormatSymbols_en_BS', 'goog.labs.i18n.ListFormatSymbols_en_BW', 'goog.labs.i18n.ListFormatSymbols_en_BZ', 'goog.labs.i18n.ListFormatSymbols_en_CC', 'goog.labs.i18n.ListFormatSymbols_en_CH', 'goog.labs.i18n.ListFormatSymbols_en_CK', 'goog.labs.i18n.ListFormatSymbols_en_CM', 'goog.labs.i18n.ListFormatSymbols_en_CX', 'goog.labs.i18n.ListFormatSymbols_en_CY', 'goog.labs.i18n.ListFormatSymbols_en_DE', 'goog.labs.i18n.ListFormatSymbols_en_DG', 'goog.labs.i18n.ListFormatSymbols_en_DK', 'goog.labs.i18n.ListFormatSymbols_en_DM', 'goog.labs.i18n.ListFormatSymbols_en_ER', 'goog.labs.i18n.ListFormatSymbols_en_FI', 'goog.labs.i18n.ListFormatSymbols_en_FJ', 'goog.labs.i18n.ListFormatSymbols_en_FK', 'goog.labs.i18n.ListFormatSymbols_en_FM', 'goog.labs.i18n.ListFormatSymbols_en_GD', 'goog.labs.i18n.ListFormatSymbols_en_GG', 'goog.labs.i18n.ListFormatSymbols_en_GH', 'goog.labs.i18n.ListFormatSymbols_en_GI', 'goog.labs.i18n.ListFormatSymbols_en_GM', 'goog.labs.i18n.ListFormatSymbols_en_GU', 'goog.labs.i18n.ListFormatSymbols_en_GY', 'goog.labs.i18n.ListFormatSymbols_en_HK', 'goog.labs.i18n.ListFormatSymbols_en_IL', 'goog.labs.i18n.ListFormatSymbols_en_IM', 'goog.labs.i18n.ListFormatSymbols_en_IO', 'goog.labs.i18n.ListFormatSymbols_en_JE', 'goog.labs.i18n.ListFormatSymbols_en_JM', 'goog.labs.i18n.ListFormatSymbols_en_KE', 'goog.labs.i18n.ListFormatSymbols_en_KI', 'goog.labs.i18n.ListFormatSymbols_en_KN', 'goog.labs.i18n.ListFormatSymbols_en_KY', 'goog.labs.i18n.ListFormatSymbols_en_LC', 'goog.labs.i18n.ListFormatSymbols_en_LR', 'goog.labs.i18n.ListFormatSymbols_en_LS', 'goog.labs.i18n.ListFormatSymbols_en_MG', 'goog.labs.i18n.ListFormatSymbols_en_MH', 'goog.labs.i18n.ListFormatSymbols_en_MO', 'goog.labs.i18n.ListFormatSymbols_en_MP', 'goog.labs.i18n.ListFormatSymbols_en_MS', 'goog.labs.i18n.ListFormatSymbols_en_MT', 'goog.labs.i18n.ListFormatSymbols_en_MU', 'goog.labs.i18n.ListFormatSymbols_en_MW', 'goog.labs.i18n.ListFormatSymbols_en_MY', 'goog.labs.i18n.ListFormatSymbols_en_NA', 'goog.labs.i18n.ListFormatSymbols_en_NF', 'goog.labs.i18n.ListFormatSymbols_en_NG', 'goog.labs.i18n.ListFormatSymbols_en_NL', 'goog.labs.i18n.ListFormatSymbols_en_NR', 'goog.labs.i18n.ListFormatSymbols_en_NU', 'goog.labs.i18n.ListFormatSymbols_en_NZ', 'goog.labs.i18n.ListFormatSymbols_en_PG', 'goog.labs.i18n.ListFormatSymbols_en_PH', 'goog.labs.i18n.ListFormatSymbols_en_PK', 'goog.labs.i18n.ListFormatSymbols_en_PN', 'goog.labs.i18n.ListFormatSymbols_en_PR', 'goog.labs.i18n.ListFormatSymbols_en_PW', 'goog.labs.i18n.ListFormatSymbols_en_RW', 'goog.labs.i18n.ListFormatSymbols_en_SB', 'goog.labs.i18n.ListFormatSymbols_en_SC', 'goog.labs.i18n.ListFormatSymbols_en_SD', 'goog.labs.i18n.ListFormatSymbols_en_SE', 'goog.labs.i18n.ListFormatSymbols_en_SH', 'goog.labs.i18n.ListFormatSymbols_en_SI', 'goog.labs.i18n.ListFormatSymbols_en_SL', 'goog.labs.i18n.ListFormatSymbols_en_SS', 'goog.labs.i18n.ListFormatSymbols_en_SX', 'goog.labs.i18n.ListFormatSymbols_en_SZ', 'goog.labs.i18n.ListFormatSymbols_en_TC', 'goog.labs.i18n.ListFormatSymbols_en_TK', 'goog.labs.i18n.ListFormatSymbols_en_TO', 'goog.labs.i18n.ListFormatSymbols_en_TT', 'goog.labs.i18n.ListFormatSymbols_en_TV', 'goog.labs.i18n.ListFormatSymbols_en_TZ', 'goog.labs.i18n.ListFormatSymbols_en_UG', 'goog.labs.i18n.ListFormatSymbols_en_UM', 'goog.labs.i18n.ListFormatSymbols_en_US_POSIX', 'goog.labs.i18n.ListFormatSymbols_en_VC', 'goog.labs.i18n.ListFormatSymbols_en_VG', 'goog.labs.i18n.ListFormatSymbols_en_VI', 'goog.labs.i18n.ListFormatSymbols_en_VU', 'goog.labs.i18n.ListFormatSymbols_en_WS', 'goog.labs.i18n.ListFormatSymbols_en_XA', 'goog.labs.i18n.ListFormatSymbols_en_ZM', 'goog.labs.i18n.ListFormatSymbols_en_ZW', 'goog.labs.i18n.ListFormatSymbols_eo', 'goog.labs.i18n.ListFormatSymbols_es_AR', 'goog.labs.i18n.ListFormatSymbols_es_BO', 'goog.labs.i18n.ListFormatSymbols_es_BR', 'goog.labs.i18n.ListFormatSymbols_es_CL', 'goog.labs.i18n.ListFormatSymbols_es_CO', 'goog.labs.i18n.ListFormatSymbols_es_CR', 'goog.labs.i18n.ListFormatSymbols_es_CU', 'goog.labs.i18n.ListFormatSymbols_es_DO', 'goog.labs.i18n.ListFormatSymbols_es_EA', 'goog.labs.i18n.ListFormatSymbols_es_EC', 'goog.labs.i18n.ListFormatSymbols_es_GQ', 'goog.labs.i18n.ListFormatSymbols_es_GT', 'goog.labs.i18n.ListFormatSymbols_es_HN', 'goog.labs.i18n.ListFormatSymbols_es_IC', 'goog.labs.i18n.ListFormatSymbols_es_NI', 'goog.labs.i18n.ListFormatSymbols_es_PA', 'goog.labs.i18n.ListFormatSymbols_es_PE', 'goog.labs.i18n.ListFormatSymbols_es_PH', 'goog.labs.i18n.ListFormatSymbols_es_PR', 'goog.labs.i18n.ListFormatSymbols_es_PY', 'goog.labs.i18n.ListFormatSymbols_es_SV', 'goog.labs.i18n.ListFormatSymbols_es_UY', 'goog.labs.i18n.ListFormatSymbols_es_VE', 'goog.labs.i18n.ListFormatSymbols_et_EE', 'goog.labs.i18n.ListFormatSymbols_eu_ES', 'goog.labs.i18n.ListFormatSymbols_ewo', 'goog.labs.i18n.ListFormatSymbols_ewo_CM', 'goog.labs.i18n.ListFormatSymbols_fa_AF', 'goog.labs.i18n.ListFormatSymbols_fa_IR', 'goog.labs.i18n.ListFormatSymbols_ff', 'goog.labs.i18n.ListFormatSymbols_ff_CM', 'goog.labs.i18n.ListFormatSymbols_ff_GN', 'goog.labs.i18n.ListFormatSymbols_ff_MR', 'goog.labs.i18n.ListFormatSymbols_ff_SN', 'goog.labs.i18n.ListFormatSymbols_fi_FI', 'goog.labs.i18n.ListFormatSymbols_fil_PH', 'goog.labs.i18n.ListFormatSymbols_fo', 'goog.labs.i18n.ListFormatSymbols_fo_DK', 'goog.labs.i18n.ListFormatSymbols_fo_FO', 'goog.labs.i18n.ListFormatSymbols_fr_BE', 'goog.labs.i18n.ListFormatSymbols_fr_BF', 'goog.labs.i18n.ListFormatSymbols_fr_BI', 'goog.labs.i18n.ListFormatSymbols_fr_BJ', 'goog.labs.i18n.ListFormatSymbols_fr_BL', 'goog.labs.i18n.ListFormatSymbols_fr_CD', 'goog.labs.i18n.ListFormatSymbols_fr_CF', 'goog.labs.i18n.ListFormatSymbols_fr_CG', 'goog.labs.i18n.ListFormatSymbols_fr_CH', 'goog.labs.i18n.ListFormatSymbols_fr_CI', 'goog.labs.i18n.ListFormatSymbols_fr_CM', 'goog.labs.i18n.ListFormatSymbols_fr_DJ', 'goog.labs.i18n.ListFormatSymbols_fr_DZ', 'goog.labs.i18n.ListFormatSymbols_fr_FR', 'goog.labs.i18n.ListFormatSymbols_fr_GA', 'goog.labs.i18n.ListFormatSymbols_fr_GF', 'goog.labs.i18n.ListFormatSymbols_fr_GN', 'goog.labs.i18n.ListFormatSymbols_fr_GP', 'goog.labs.i18n.ListFormatSymbols_fr_GQ', 'goog.labs.i18n.ListFormatSymbols_fr_HT', 'goog.labs.i18n.ListFormatSymbols_fr_KM', 'goog.labs.i18n.ListFormatSymbols_fr_LU', 'goog.labs.i18n.ListFormatSymbols_fr_MA', 'goog.labs.i18n.ListFormatSymbols_fr_MC', 'goog.labs.i18n.ListFormatSymbols_fr_MF', 'goog.labs.i18n.ListFormatSymbols_fr_MG', 'goog.labs.i18n.ListFormatSymbols_fr_ML', 'goog.labs.i18n.ListFormatSymbols_fr_MQ', 'goog.labs.i18n.ListFormatSymbols_fr_MR', 'goog.labs.i18n.ListFormatSymbols_fr_MU', 'goog.labs.i18n.ListFormatSymbols_fr_NC', 'goog.labs.i18n.ListFormatSymbols_fr_NE', 'goog.labs.i18n.ListFormatSymbols_fr_PF', 'goog.labs.i18n.ListFormatSymbols_fr_PM', 'goog.labs.i18n.ListFormatSymbols_fr_RE', 'goog.labs.i18n.ListFormatSymbols_fr_RW', 'goog.labs.i18n.ListFormatSymbols_fr_SC', 'goog.labs.i18n.ListFormatSymbols_fr_SN', 'goog.labs.i18n.ListFormatSymbols_fr_SY', 'goog.labs.i18n.ListFormatSymbols_fr_TD', 'goog.labs.i18n.ListFormatSymbols_fr_TG', 'goog.labs.i18n.ListFormatSymbols_fr_TN', 'goog.labs.i18n.ListFormatSymbols_fr_VU', 'goog.labs.i18n.ListFormatSymbols_fr_WF', 'goog.labs.i18n.ListFormatSymbols_fr_YT', 'goog.labs.i18n.ListFormatSymbols_fur', 'goog.labs.i18n.ListFormatSymbols_fur_IT', 'goog.labs.i18n.ListFormatSymbols_fy', 'goog.labs.i18n.ListFormatSymbols_fy_NL', 'goog.labs.i18n.ListFormatSymbols_ga_IE', 'goog.labs.i18n.ListFormatSymbols_gd', 'goog.labs.i18n.ListFormatSymbols_gd_GB', 'goog.labs.i18n.ListFormatSymbols_gl_ES', 'goog.labs.i18n.ListFormatSymbols_gsw_CH', 'goog.labs.i18n.ListFormatSymbols_gsw_FR', 'goog.labs.i18n.ListFormatSymbols_gsw_LI', 'goog.labs.i18n.ListFormatSymbols_gu_IN', 'goog.labs.i18n.ListFormatSymbols_guz', 'goog.labs.i18n.ListFormatSymbols_guz_KE', 'goog.labs.i18n.ListFormatSymbols_gv', 'goog.labs.i18n.ListFormatSymbols_gv_IM', 'goog.labs.i18n.ListFormatSymbols_ha', 'goog.labs.i18n.ListFormatSymbols_ha_GH', 'goog.labs.i18n.ListFormatSymbols_ha_NE', 'goog.labs.i18n.ListFormatSymbols_ha_NG', 'goog.labs.i18n.ListFormatSymbols_haw_US', 'goog.labs.i18n.ListFormatSymbols_he_IL', 'goog.labs.i18n.ListFormatSymbols_hi_IN', 'goog.labs.i18n.ListFormatSymbols_hr_BA', 'goog.labs.i18n.ListFormatSymbols_hr_HR', 'goog.labs.i18n.ListFormatSymbols_hsb', 'goog.labs.i18n.ListFormatSymbols_hsb_DE', 'goog.labs.i18n.ListFormatSymbols_hu_HU', 'goog.labs.i18n.ListFormatSymbols_hy_AM', 'goog.labs.i18n.ListFormatSymbols_id_ID', 'goog.labs.i18n.ListFormatSymbols_ig', 'goog.labs.i18n.ListFormatSymbols_ig_NG', 'goog.labs.i18n.ListFormatSymbols_ii', 'goog.labs.i18n.ListFormatSymbols_ii_CN', 'goog.labs.i18n.ListFormatSymbols_is_IS', 'goog.labs.i18n.ListFormatSymbols_it_CH', 'goog.labs.i18n.ListFormatSymbols_it_IT', 'goog.labs.i18n.ListFormatSymbols_it_SM', 'goog.labs.i18n.ListFormatSymbols_ja_JP', 'goog.labs.i18n.ListFormatSymbols_jgo', 'goog.labs.i18n.ListFormatSymbols_jgo_CM', 'goog.labs.i18n.ListFormatSymbols_jmc', 'goog.labs.i18n.ListFormatSymbols_jmc_TZ', 'goog.labs.i18n.ListFormatSymbols_ka_GE', 'goog.labs.i18n.ListFormatSymbols_kab', 'goog.labs.i18n.ListFormatSymbols_kab_DZ', 'goog.labs.i18n.ListFormatSymbols_kam', 'goog.labs.i18n.ListFormatSymbols_kam_KE', 'goog.labs.i18n.ListFormatSymbols_kde', 'goog.labs.i18n.ListFormatSymbols_kde_TZ', 'goog.labs.i18n.ListFormatSymbols_kea', 'goog.labs.i18n.ListFormatSymbols_kea_CV', 'goog.labs.i18n.ListFormatSymbols_khq', 'goog.labs.i18n.ListFormatSymbols_khq_ML', 'goog.labs.i18n.ListFormatSymbols_ki', 'goog.labs.i18n.ListFormatSymbols_ki_KE', 'goog.labs.i18n.ListFormatSymbols_kk_KZ', 'goog.labs.i18n.ListFormatSymbols_kkj', 'goog.labs.i18n.ListFormatSymbols_kkj_CM', 'goog.labs.i18n.ListFormatSymbols_kl', 'goog.labs.i18n.ListFormatSymbols_kl_GL', 'goog.labs.i18n.ListFormatSymbols_kln', 'goog.labs.i18n.ListFormatSymbols_kln_KE', 'goog.labs.i18n.ListFormatSymbols_km_KH', 'goog.labs.i18n.ListFormatSymbols_kn_IN', 'goog.labs.i18n.ListFormatSymbols_ko_KP', 'goog.labs.i18n.ListFormatSymbols_ko_KR', 'goog.labs.i18n.ListFormatSymbols_kok', 'goog.labs.i18n.ListFormatSymbols_kok_IN', 'goog.labs.i18n.ListFormatSymbols_ks', 'goog.labs.i18n.ListFormatSymbols_ks_IN', 'goog.labs.i18n.ListFormatSymbols_ksb', 'goog.labs.i18n.ListFormatSymbols_ksb_TZ', 'goog.labs.i18n.ListFormatSymbols_ksf', 'goog.labs.i18n.ListFormatSymbols_ksf_CM', 'goog.labs.i18n.ListFormatSymbols_ksh', 'goog.labs.i18n.ListFormatSymbols_ksh_DE', 'goog.labs.i18n.ListFormatSymbols_kw', 'goog.labs.i18n.ListFormatSymbols_kw_GB', 'goog.labs.i18n.ListFormatSymbols_ky_KG', 'goog.labs.i18n.ListFormatSymbols_lag', 'goog.labs.i18n.ListFormatSymbols_lag_TZ', 'goog.labs.i18n.ListFormatSymbols_lb', 'goog.labs.i18n.ListFormatSymbols_lb_LU', 'goog.labs.i18n.ListFormatSymbols_lg', 'goog.labs.i18n.ListFormatSymbols_lg_UG', 'goog.labs.i18n.ListFormatSymbols_lkt', 'goog.labs.i18n.ListFormatSymbols_lkt_US', 'goog.labs.i18n.ListFormatSymbols_ln_AO', 'goog.labs.i18n.ListFormatSymbols_ln_CD', 'goog.labs.i18n.ListFormatSymbols_ln_CF', 'goog.labs.i18n.ListFormatSymbols_ln_CG', 'goog.labs.i18n.ListFormatSymbols_lo_LA', 'goog.labs.i18n.ListFormatSymbols_lrc', 'goog.labs.i18n.ListFormatSymbols_lrc_IQ', 'goog.labs.i18n.ListFormatSymbols_lrc_IR', 'goog.labs.i18n.ListFormatSymbols_lt_LT', 'goog.labs.i18n.ListFormatSymbols_lu', 'goog.labs.i18n.ListFormatSymbols_lu_CD', 'goog.labs.i18n.ListFormatSymbols_luo', 'goog.labs.i18n.ListFormatSymbols_luo_KE', 'goog.labs.i18n.ListFormatSymbols_luy', 'goog.labs.i18n.ListFormatSymbols_luy_KE', 'goog.labs.i18n.ListFormatSymbols_lv_LV', 'goog.labs.i18n.ListFormatSymbols_mas', 'goog.labs.i18n.ListFormatSymbols_mas_KE', 'goog.labs.i18n.ListFormatSymbols_mas_TZ', 'goog.labs.i18n.ListFormatSymbols_mer', 'goog.labs.i18n.ListFormatSymbols_mer_KE', 'goog.labs.i18n.ListFormatSymbols_mfe', 'goog.labs.i18n.ListFormatSymbols_mfe_MU', 'goog.labs.i18n.ListFormatSymbols_mg', 'goog.labs.i18n.ListFormatSymbols_mg_MG', 'goog.labs.i18n.ListFormatSymbols_mgh', 'goog.labs.i18n.ListFormatSymbols_mgh_MZ', 'goog.labs.i18n.ListFormatSymbols_mgo', 'goog.labs.i18n.ListFormatSymbols_mgo_CM', 'goog.labs.i18n.ListFormatSymbols_mk_MK', 'goog.labs.i18n.ListFormatSymbols_ml_IN', 'goog.labs.i18n.ListFormatSymbols_mn_MN', 'goog.labs.i18n.ListFormatSymbols_mr_IN', 'goog.labs.i18n.ListFormatSymbols_ms_BN', 'goog.labs.i18n.ListFormatSymbols_ms_MY', 'goog.labs.i18n.ListFormatSymbols_ms_SG', 'goog.labs.i18n.ListFormatSymbols_mt_MT', 'goog.labs.i18n.ListFormatSymbols_mua', 'goog.labs.i18n.ListFormatSymbols_mua_CM', 'goog.labs.i18n.ListFormatSymbols_my_MM', 'goog.labs.i18n.ListFormatSymbols_mzn', 'goog.labs.i18n.ListFormatSymbols_mzn_IR', 'goog.labs.i18n.ListFormatSymbols_naq', 'goog.labs.i18n.ListFormatSymbols_naq_NA', 'goog.labs.i18n.ListFormatSymbols_nb_NO', 'goog.labs.i18n.ListFormatSymbols_nb_SJ', 'goog.labs.i18n.ListFormatSymbols_nd', 'goog.labs.i18n.ListFormatSymbols_nd_ZW', 'goog.labs.i18n.ListFormatSymbols_nds', 'goog.labs.i18n.ListFormatSymbols_nds_DE', 'goog.labs.i18n.ListFormatSymbols_nds_NL', 'goog.labs.i18n.ListFormatSymbols_ne_IN', 'goog.labs.i18n.ListFormatSymbols_ne_NP', 'goog.labs.i18n.ListFormatSymbols_nl_AW', 'goog.labs.i18n.ListFormatSymbols_nl_BE', 'goog.labs.i18n.ListFormatSymbols_nl_BQ', 'goog.labs.i18n.ListFormatSymbols_nl_CW', 'goog.labs.i18n.ListFormatSymbols_nl_NL', 'goog.labs.i18n.ListFormatSymbols_nl_SR', 'goog.labs.i18n.ListFormatSymbols_nl_SX', 'goog.labs.i18n.ListFormatSymbols_nmg', 'goog.labs.i18n.ListFormatSymbols_nmg_CM', 'goog.labs.i18n.ListFormatSymbols_nn', 'goog.labs.i18n.ListFormatSymbols_nn_NO', 'goog.labs.i18n.ListFormatSymbols_nnh', 'goog.labs.i18n.ListFormatSymbols_nnh_CM', 'goog.labs.i18n.ListFormatSymbols_nus', 'goog.labs.i18n.ListFormatSymbols_nus_SS', 'goog.labs.i18n.ListFormatSymbols_nyn', 'goog.labs.i18n.ListFormatSymbols_nyn_UG', 'goog.labs.i18n.ListFormatSymbols_om', 'goog.labs.i18n.ListFormatSymbols_om_ET', 'goog.labs.i18n.ListFormatSymbols_om_KE', 'goog.labs.i18n.ListFormatSymbols_or_IN', 'goog.labs.i18n.ListFormatSymbols_os', 'goog.labs.i18n.ListFormatSymbols_os_GE', 'goog.labs.i18n.ListFormatSymbols_os_RU', 'goog.labs.i18n.ListFormatSymbols_pa_Arab', 'goog.labs.i18n.ListFormatSymbols_pa_Arab_PK', 'goog.labs.i18n.ListFormatSymbols_pa_Guru', 'goog.labs.i18n.ListFormatSymbols_pa_Guru_IN', 'goog.labs.i18n.ListFormatSymbols_pl_PL', 'goog.labs.i18n.ListFormatSymbols_ps', 'goog.labs.i18n.ListFormatSymbols_ps_AF', 'goog.labs.i18n.ListFormatSymbols_pt_AO', 'goog.labs.i18n.ListFormatSymbols_pt_CH', 'goog.labs.i18n.ListFormatSymbols_pt_CV', 'goog.labs.i18n.ListFormatSymbols_pt_GQ', 'goog.labs.i18n.ListFormatSymbols_pt_GW', 'goog.labs.i18n.ListFormatSymbols_pt_LU', 'goog.labs.i18n.ListFormatSymbols_pt_MO', 'goog.labs.i18n.ListFormatSymbols_pt_MZ', 'goog.labs.i18n.ListFormatSymbols_pt_ST', 'goog.labs.i18n.ListFormatSymbols_pt_TL', 'goog.labs.i18n.ListFormatSymbols_qu', 'goog.labs.i18n.ListFormatSymbols_qu_BO', 'goog.labs.i18n.ListFormatSymbols_qu_EC', 'goog.labs.i18n.ListFormatSymbols_qu_PE', 'goog.labs.i18n.ListFormatSymbols_rm', 'goog.labs.i18n.ListFormatSymbols_rm_CH', 'goog.labs.i18n.ListFormatSymbols_rn', 'goog.labs.i18n.ListFormatSymbols_rn_BI', 'goog.labs.i18n.ListFormatSymbols_ro_MD', 'goog.labs.i18n.ListFormatSymbols_ro_RO', 'goog.labs.i18n.ListFormatSymbols_rof', 'goog.labs.i18n.ListFormatSymbols_rof_TZ', 'goog.labs.i18n.ListFormatSymbols_ru_BY', 'goog.labs.i18n.ListFormatSymbols_ru_KG', 'goog.labs.i18n.ListFormatSymbols_ru_KZ', 'goog.labs.i18n.ListFormatSymbols_ru_MD', 'goog.labs.i18n.ListFormatSymbols_ru_RU', 'goog.labs.i18n.ListFormatSymbols_ru_UA', 'goog.labs.i18n.ListFormatSymbols_rw', 'goog.labs.i18n.ListFormatSymbols_rw_RW', 'goog.labs.i18n.ListFormatSymbols_rwk', 'goog.labs.i18n.ListFormatSymbols_rwk_TZ', 'goog.labs.i18n.ListFormatSymbols_sah', 'goog.labs.i18n.ListFormatSymbols_sah_RU', 'goog.labs.i18n.ListFormatSymbols_saq', 'goog.labs.i18n.ListFormatSymbols_saq_KE', 'goog.labs.i18n.ListFormatSymbols_sbp', 'goog.labs.i18n.ListFormatSymbols_sbp_TZ', 'goog.labs.i18n.ListFormatSymbols_se', 'goog.labs.i18n.ListFormatSymbols_se_FI', 'goog.labs.i18n.ListFormatSymbols_se_NO', 'goog.labs.i18n.ListFormatSymbols_se_SE', 'goog.labs.i18n.ListFormatSymbols_seh', 'goog.labs.i18n.ListFormatSymbols_seh_MZ', 'goog.labs.i18n.ListFormatSymbols_ses', 'goog.labs.i18n.ListFormatSymbols_ses_ML', 'goog.labs.i18n.ListFormatSymbols_sg', 'goog.labs.i18n.ListFormatSymbols_sg_CF', 'goog.labs.i18n.ListFormatSymbols_shi', 'goog.labs.i18n.ListFormatSymbols_shi_Latn', 'goog.labs.i18n.ListFormatSymbols_shi_Latn_MA', 'goog.labs.i18n.ListFormatSymbols_shi_Tfng', 'goog.labs.i18n.ListFormatSymbols_shi_Tfng_MA', 'goog.labs.i18n.ListFormatSymbols_si_LK', 'goog.labs.i18n.ListFormatSymbols_sk_SK', 'goog.labs.i18n.ListFormatSymbols_sl_SI', 'goog.labs.i18n.ListFormatSymbols_smn', 'goog.labs.i18n.ListFormatSymbols_smn_FI', 'goog.labs.i18n.ListFormatSymbols_sn', 'goog.labs.i18n.ListFormatSymbols_sn_ZW', 'goog.labs.i18n.ListFormatSymbols_so', 'goog.labs.i18n.ListFormatSymbols_so_DJ', 'goog.labs.i18n.ListFormatSymbols_so_ET', 'goog.labs.i18n.ListFormatSymbols_so_KE', 'goog.labs.i18n.ListFormatSymbols_so_SO', 'goog.labs.i18n.ListFormatSymbols_sq_AL', 'goog.labs.i18n.ListFormatSymbols_sq_MK', 'goog.labs.i18n.ListFormatSymbols_sq_XK', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_BA', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_ME', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_RS', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_XK', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_BA', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_ME', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_RS', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_XK', 'goog.labs.i18n.ListFormatSymbols_sv_AX', 'goog.labs.i18n.ListFormatSymbols_sv_FI', 'goog.labs.i18n.ListFormatSymbols_sv_SE', 'goog.labs.i18n.ListFormatSymbols_sw_CD', 'goog.labs.i18n.ListFormatSymbols_sw_KE', 'goog.labs.i18n.ListFormatSymbols_sw_TZ', 'goog.labs.i18n.ListFormatSymbols_sw_UG', 'goog.labs.i18n.ListFormatSymbols_ta_IN', 'goog.labs.i18n.ListFormatSymbols_ta_LK', 'goog.labs.i18n.ListFormatSymbols_ta_MY', 'goog.labs.i18n.ListFormatSymbols_ta_SG', 'goog.labs.i18n.ListFormatSymbols_te_IN', 'goog.labs.i18n.ListFormatSymbols_teo', 'goog.labs.i18n.ListFormatSymbols_teo_KE', 'goog.labs.i18n.ListFormatSymbols_teo_UG', 'goog.labs.i18n.ListFormatSymbols_th_TH', 'goog.labs.i18n.ListFormatSymbols_ti', 'goog.labs.i18n.ListFormatSymbols_ti_ER', 'goog.labs.i18n.ListFormatSymbols_ti_ET', 'goog.labs.i18n.ListFormatSymbols_to', 'goog.labs.i18n.ListFormatSymbols_to_TO', 'goog.labs.i18n.ListFormatSymbols_tr_CY', 'goog.labs.i18n.ListFormatSymbols_tr_TR', 'goog.labs.i18n.ListFormatSymbols_twq', 'goog.labs.i18n.ListFormatSymbols_twq_NE', 'goog.labs.i18n.ListFormatSymbols_tzm', 'goog.labs.i18n.ListFormatSymbols_tzm_MA', 'goog.labs.i18n.ListFormatSymbols_ug', 'goog.labs.i18n.ListFormatSymbols_ug_CN', 'goog.labs.i18n.ListFormatSymbols_uk_UA', 'goog.labs.i18n.ListFormatSymbols_ur_IN', 'goog.labs.i18n.ListFormatSymbols_ur_PK', 'goog.labs.i18n.ListFormatSymbols_uz_Arab', 'goog.labs.i18n.ListFormatSymbols_uz_Arab_AF', 'goog.labs.i18n.ListFormatSymbols_uz_Cyrl', 'goog.labs.i18n.ListFormatSymbols_uz_Cyrl_UZ', 'goog.labs.i18n.ListFormatSymbols_uz_Latn', 'goog.labs.i18n.ListFormatSymbols_uz_Latn_UZ', 'goog.labs.i18n.ListFormatSymbols_vai', 'goog.labs.i18n.ListFormatSymbols_vai_Latn', 'goog.labs.i18n.ListFormatSymbols_vai_Latn_LR', 'goog.labs.i18n.ListFormatSymbols_vai_Vaii', 'goog.labs.i18n.ListFormatSymbols_vai_Vaii_LR', 'goog.labs.i18n.ListFormatSymbols_vi_VN', 'goog.labs.i18n.ListFormatSymbols_vun', 'goog.labs.i18n.ListFormatSymbols_vun_TZ', 'goog.labs.i18n.ListFormatSymbols_wae', 'goog.labs.i18n.ListFormatSymbols_wae_CH', 'goog.labs.i18n.ListFormatSymbols_xog', 'goog.labs.i18n.ListFormatSymbols_xog_UG', 'goog.labs.i18n.ListFormatSymbols_yav', 'goog.labs.i18n.ListFormatSymbols_yav_CM', 'goog.labs.i18n.ListFormatSymbols_yi', 'goog.labs.i18n.ListFormatSymbols_yi_001', 'goog.labs.i18n.ListFormatSymbols_yo', 'goog.labs.i18n.ListFormatSymbols_yo_BJ', 'goog.labs.i18n.ListFormatSymbols_yo_NG', 'goog.labs.i18n.ListFormatSymbols_yue', 'goog.labs.i18n.ListFormatSymbols_yue_HK', 'goog.labs.i18n.ListFormatSymbols_zgh', 'goog.labs.i18n.ListFormatSymbols_zgh_MA', 'goog.labs.i18n.ListFormatSymbols_zh_Hans', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_CN', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_HK', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_MO', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_SG', 'goog.labs.i18n.ListFormatSymbols_zh_Hant', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_HK', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_MO', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_TW', 'goog.labs.i18n.ListFormatSymbols_zu_ZA'], ['goog.labs.i18n.ListFormatSymbols']);
                +goog.addDependency("labs/iterable/iterable.js", [], []);
                +goog.addDependency("labs/iterable/iterable_test.js", [], ['goog.testing.jsunit']);
                +goog.addDependency("labs/mock/mock.js", ['goog.labs.mock', 'goog.labs.mock.VerificationError'], ['goog.array', 'goog.asserts', 'goog.debug', 'goog.debug.Error', 'goog.functions', 'goog.labs.mock.verification', 'goog.labs.mock.verification.VerificationMode', 'goog.object']);
                +goog.addDependency("labs/mock/mock_test.js", ['goog.labs.mockTest'], ['goog.array', 'goog.labs.mock', 'goog.labs.mock.VerificationError', 'goog.labs.testing.AnythingMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("labs/mock/verificationmode.js", ['goog.labs.mock.verification', 'goog.labs.mock.verification.VerificationMode'], []);
                +goog.addDependency("labs/mock/verificationmode_test.js", [], []);
                +goog.addDependency("labs/net/image.js", ['goog.labs.net.image'], ['goog.Promise', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.net.EventType', 'goog.userAgent']);
                +goog.addDependency("labs/net/image_test.js", ['goog.labs.net.imageTest'], ['goog.labs.net.image', 'goog.string', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/net/webchannel.js", ['goog.net.WebChannel'], ['goog.events', 'goog.events.Event']);
                +goog.addDependency("labs/net/webchannel/basetestchannel.js", ['goog.labs.net.webChannel.BaseTestChannel'], ['goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.net.WebChannel']);
                +goog.addDependency("labs/net/webchannel/channel.js", ['goog.labs.net.webChannel.Channel'], []);
                +goog.addDependency("labs/net/webchannel/channelrequest.js", ['goog.labs.net.webChannel.ChannelRequest'], ['goog.Timer', 'goog.async.Throttle', 'goog.events.EventHandler', 'goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("labs/net/webchannel/channelrequest_test.js", ['goog.labs.net.webChannel.channelRequestTest'], ['goog.Uri', 'goog.functions', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/net/webchannel/connectionstate.js", ['goog.labs.net.webChannel.ConnectionState'], []);
                +goog.addDependency("labs/net/webchannel/forwardchannelrequestpool.js", ['goog.labs.net.webChannel.ForwardChannelRequestPool'], ['goog.array', 'goog.string', 'goog.structs.Set']);
                +goog.addDependency("labs/net/webchannel/forwardchannelrequestpool_test.js", ['goog.labs.net.webChannel.forwardChannelRequestPoolTest'], ['goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/netutils.js", ['goog.labs.net.webChannel.netUtils'], ['goog.Uri', 'goog.labs.net.webChannel.WebChannelDebug']);
                +goog.addDependency("labs/net/webchannel/requeststats.js", ['goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Event', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.labs.net.webChannel.requestStats.ServerReachabilityEvent', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.labs.net.webChannel.requestStats.StatEvent', 'goog.labs.net.webChannel.requestStats.TimingEvent'], ['goog.events.Event', 'goog.events.EventTarget']);
                +goog.addDependency("labs/net/webchannel/webchannelbase.js", ['goog.labs.net.webChannel.WebChannelBase'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.TextFormatter', 'goog.json', 'goog.labs.net.webChannel.BaseTestChannel', 'goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ConnectionState', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.Wire', 'goog.labs.net.webChannel.WireV8', 'goog.labs.net.webChannel.netUtils', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.log', 'goog.net.WebChannel', 'goog.net.XhrIo', 'goog.net.rpc.HttpCors', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.CircularBuffer']);
                +goog.addDependency("labs/net/webchannel/webchannelbase_test.js", ['goog.labs.net.webChannel.webChannelBaseTest'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.functions', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.labs.net.webChannel.WebChannelBase', 'goog.labs.net.webChannel.WebChannelBaseTransport', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.Wire', 'goog.labs.net.webChannel.netUtils', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/webchannelbasetransport.js", ['goog.labs.net.webChannel.WebChannelBaseTransport'], ['goog.asserts', 'goog.events.EventTarget', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelBase', 'goog.log', 'goog.net.WebChannel', 'goog.net.WebChannelTransport', 'goog.object', 'goog.string', 'goog.string.path']);
                +goog.addDependency("labs/net/webchannel/webchannelbasetransport_test.js", ['goog.labs.net.webChannel.webChannelBaseTransportTest'], ['goog.events', 'goog.functions', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelBase', 'goog.labs.net.webChannel.WebChannelBaseTransport', 'goog.net.WebChannel', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/webchanneldebug.js", ['goog.labs.net.webChannel.WebChannelDebug'], ['goog.json', 'goog.log']);
                +goog.addDependency("labs/net/webchannel/wire.js", ['goog.labs.net.webChannel.Wire'], []);
                +goog.addDependency("labs/net/webchannel/wirev8.js", ['goog.labs.net.webChannel.WireV8'], ['goog.asserts', 'goog.json', 'goog.json.NativeJsonProcessor', 'goog.labs.net.webChannel.Wire', 'goog.structs']);
                +goog.addDependency("labs/net/webchannel/wirev8_test.js", ['goog.labs.net.webChannel.WireV8Test'], ['goog.labs.net.webChannel.WireV8', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchanneltransport.js", ['goog.net.WebChannelTransport'], []);
                +goog.addDependency("labs/net/webchanneltransportfactory.js", ['goog.net.createWebChannelTransport'], ['goog.functions', 'goog.labs.net.webChannel.WebChannelBaseTransport']);
                +goog.addDependency("labs/net/xhr.js", ['goog.labs.net.xhr', 'goog.labs.net.xhr.Error', 'goog.labs.net.xhr.HttpError', 'goog.labs.net.xhr.Options', 'goog.labs.net.xhr.PostData', 'goog.labs.net.xhr.ResponseType', 'goog.labs.net.xhr.TimeoutError'], ['goog.Promise', 'goog.asserts', 'goog.debug.Error', 'goog.json', 'goog.net.HttpStatus', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("labs/net/xhr_test.js", ['goog.labs.net.xhrTest'], ['goog.Promise', 'goog.events', 'goog.events.EventType', 'goog.labs.net.xhr', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XmlHttp', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("labs/promise/promise.js", [], []);
                +goog.addDependency("labs/promise/promise_test.js", [], ['goog.testing.jsunit']);
                +goog.addDependency("labs/pubsub/broadcastpubsub.js", ['goog.labs.pubsub.BroadcastPubSub'], ['goog.Disposable', 'goog.Timer', 'goog.array', 'goog.async.run', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.math', 'goog.pubsub.PubSub', 'goog.storage.Storage', 'goog.storage.mechanism.HTML5LocalStorage', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("labs/pubsub/broadcastpubsub_test.js", ['goog.labs.pubsub.BroadcastPubSubTest'], ['goog.array', 'goog.debug.Logger', 'goog.json', 'goog.labs.pubsub.BroadcastPubSub', 'goog.storage.Storage', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("labs/storage/boundedcollectablestorage.js", ['goog.labs.storage.BoundedCollectableStorage'], ['goog.array', 'goog.asserts', 'goog.iter', 'goog.storage.CollectableStorage', 'goog.storage.ErrorCode', 'goog.storage.ExpiringStorage']);
                +goog.addDependency("labs/storage/boundedcollectablestorage_test.js", ['goog.labs.storage.BoundedCollectableStorageTest'], ['goog.labs.storage.BoundedCollectableStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("labs/structs/map.js", ['goog.labs.structs.Map'], ['goog.array', 'goog.asserts', 'goog.object']);
                +goog.addDependency("labs/structs/map_perf.js", ['goog.labs.structs.MapPerf'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.labs.structs.Map', 'goog.structs.Map', 'goog.testing.PerformanceTable', 'goog.testing.jsunit']);
                +goog.addDependency("labs/structs/map_test.js", ['goog.labs.structs.MapTest'], ['goog.labs.structs.Map', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/structs/multimap.js", ['goog.labs.structs.Multimap'], ['goog.array', 'goog.labs.structs.Map', 'goog.object']);
                +goog.addDependency("labs/structs/multimap_test.js", ['goog.labs.structs.MultimapTest'], ['goog.labs.structs.Map', 'goog.labs.structs.Multimap', 'goog.testing.jsunit']);
                +goog.addDependency("labs/style/pixeldensitymonitor.js", ['goog.labs.style.PixelDensityMonitor', 'goog.labs.style.PixelDensityMonitor.Density', 'goog.labs.style.PixelDensityMonitor.EventType'], ['goog.events', 'goog.events.EventTarget']);
                +goog.addDependency("labs/style/pixeldensitymonitor_test.js", ['goog.labs.style.PixelDensityMonitorTest'], ['goog.array', 'goog.dom.DomHelper', 'goog.events', 'goog.labs.style.PixelDensityMonitor', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/testing/assertthat.js", ['goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat'], ['goog.debug.Error']);
                +goog.addDependency("labs/testing/assertthat_test.js", ['goog.labs.testing.assertThatTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/testing/decoratormatcher.js", ['goog.labs.testing.AnythingMatcher'], ['goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/decoratormatcher_test.js", ['goog.labs.testing.decoratorMatcherTest'], ['goog.labs.testing.AnythingMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/dictionarymatcher.js", ['goog.labs.testing.HasEntriesMatcher', 'goog.labs.testing.HasEntryMatcher', 'goog.labs.testing.HasKeyMatcher', 'goog.labs.testing.HasValueMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher', 'goog.object']);
                +goog.addDependency("labs/testing/dictionarymatcher_test.js", ['goog.labs.testing.dictionaryMatcherTest'], ['goog.labs.testing.HasEntryMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/environment.js", ['goog.labs.testing.Environment'], ['goog.Thenable', 'goog.array', 'goog.asserts', 'goog.debug.Console', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/environment_test.js", ['goog.labs.testing.environmentTest'], ['goog.Promise', 'goog.labs.testing.Environment', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.testSuite']);
                +goog.addDependency("labs/testing/environment_usage_test.js", ['goog.labs.testing.environmentUsageTest'], ['goog.labs.testing.Environment']);
                +goog.addDependency("labs/testing/json_fuzzing.js", ['goog.labs.testing.JsonFuzzing'], ['goog.string', 'goog.testing.PseudoRandom']);
                +goog.addDependency("labs/testing/json_fuzzing_test.js", ['goog.labs.testing.JsonFuzzingTest'], ['goog.json', 'goog.labs.testing.JsonFuzzing', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/logicmatcher.js", ['goog.labs.testing.AllOfMatcher', 'goog.labs.testing.AnyOfMatcher', 'goog.labs.testing.IsNotMatcher'], ['goog.array', 'goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/logicmatcher_test.js", ['goog.labs.testing.logicMatcherTest'], ['goog.labs.testing.AllOfMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/matcher.js", ['goog.labs.testing.Matcher'], []);
                +goog.addDependency("labs/testing/numbermatcher.js", ['goog.labs.testing.AnyNumberMatcher', 'goog.labs.testing.CloseToMatcher', 'goog.labs.testing.EqualToMatcher', 'goog.labs.testing.GreaterThanEqualToMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.LessThanEqualToMatcher', 'goog.labs.testing.LessThanMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/numbermatcher_test.js", ['goog.labs.testing.numberMatcherTest'], ['goog.labs.testing.LessThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/objectmatcher.js", ['goog.labs.testing.AnyObjectMatcher', 'goog.labs.testing.HasPropertyMatcher', 'goog.labs.testing.InstanceOfMatcher', 'goog.labs.testing.IsNullMatcher', 'goog.labs.testing.IsNullOrUndefinedMatcher', 'goog.labs.testing.IsUndefinedMatcher', 'goog.labs.testing.ObjectEqualsMatcher'], ['goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/objectmatcher_test.js", ['goog.labs.testing.objectMatcherTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.ObjectEqualsMatcher', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/stringmatcher.js", ['goog.labs.testing.AnyStringMatcher', 'goog.labs.testing.ContainsStringMatcher', 'goog.labs.testing.EndsWithMatcher', 'goog.labs.testing.EqualToIgnoringWhitespaceMatcher', 'goog.labs.testing.EqualsMatcher', 'goog.labs.testing.RegexMatcher', 'goog.labs.testing.StartsWithMatcher', 'goog.labs.testing.StringContainsInOrderMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher', 'goog.string']);
                +goog.addDependency("labs/testing/stringmatcher_test.js", ['goog.labs.testing.stringMatcherTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.StringContainsInOrderMatcher', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/browser.js", ['goog.labs.userAgent.browser'], ['goog.array', 'goog.labs.userAgent.util', 'goog.object', 'goog.string']);
                +goog.addDependency("labs/useragent/browser_test.js", ['goog.labs.userAgent.browserTest'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/device.js", ['goog.labs.userAgent.device'], ['goog.labs.userAgent.util']);
                +goog.addDependency("labs/useragent/device_test.js", ['goog.labs.userAgent.deviceTest'], ['goog.labs.userAgent.device', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/engine.js", ['goog.labs.userAgent.engine'], ['goog.array', 'goog.labs.userAgent.util', 'goog.string']);
                +goog.addDependency("labs/useragent/engine_test.js", ['goog.labs.userAgent.engineTest'], ['goog.labs.userAgent.engine', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/platform.js", ['goog.labs.userAgent.platform'], ['goog.labs.userAgent.util', 'goog.string']);
                +goog.addDependency("labs/useragent/platform_test.js", ['goog.labs.userAgent.platformTest'], ['goog.labs.userAgent.platform', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/test_agents.js", ['goog.labs.userAgent.testAgents'], []);
                +goog.addDependency("labs/useragent/util.js", ['goog.labs.userAgent.util'], ['goog.string']);
                +goog.addDependency("labs/useragent/util_test.js", ['goog.labs.userAgent.utilTest'], ['goog.functions', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/verifier.js", ['goog.labs.useragent.verifier'], []);
                +goog.addDependency("labs/useragent/verifier_test.js", [], []);
                +goog.addDependency("locale/countries.js", ['goog.locale.countries'], []);
                +goog.addDependency("locale/countrylanguagenames_test.js", ['goog.locale.countryLanguageNamesTest'], ['goog.locale', 'goog.testing.jsunit']);
                +goog.addDependency("locale/defaultlocalenameconstants.js", ['goog.locale.defaultLocaleNameConstants'], []);
                +goog.addDependency("locale/genericfontnames.js", ['goog.locale.genericFontNames'], []);
                +goog.addDependency("locale/genericfontnames_test.js", ['goog.locale.genericFontNamesTest'], ['goog.locale.genericFontNames', 'goog.testing.jsunit']);
                +goog.addDependency("locale/genericfontnamesdata.js", ['goog.locale.genericFontNamesData'], []);
                +goog.addDependency("locale/locale.js", ['goog.locale'], ['goog.locale.nativeNameConstants']);
                +goog.addDependency("locale/nativenameconstants.js", ['goog.locale.nativeNameConstants'], []);
                +goog.addDependency("locale/scriptToLanguages.js", ['goog.locale.scriptToLanguages'], ['goog.locale']);
                +goog.addDependency("locale/timezonedetection.js", ['goog.locale.timeZoneDetection'], ['goog.locale.TimeZoneFingerprint']);
                +goog.addDependency("locale/timezonedetection_test.js", ['goog.locale.timeZoneDetectionTest'], ['goog.locale.timeZoneDetection', 'goog.testing.jsunit']);
                +goog.addDependency("locale/timezonefingerprint.js", ['goog.locale.TimeZoneFingerprint'], []);
                +goog.addDependency("locale/timezonelist.js", ['goog.locale.TimeZoneList'], ['goog.locale']);
                +goog.addDependency("locale/timezonelist_test.js", ['goog.locale.TimeZoneListTest'], ['goog.locale', 'goog.locale.TimeZoneList', 'goog.testing.jsunit']);
                +goog.addDependency("log/log.js", ['goog.log', 'goog.log.Level', 'goog.log.LogRecord', 'goog.log.Logger'], ['goog.debug', 'goog.debug.LogManager', 'goog.debug.LogRecord', 'goog.debug.Logger']);
                +goog.addDependency("log/log_test.js", ['goog.logTest'], ['goog.debug.LogManager', 'goog.log', 'goog.log.Level', 'goog.testing.jsunit']);
                +goog.addDependency("math/affinetransform.js", ['goog.math.AffineTransform'], []);
                +goog.addDependency("math/affinetransform_test.js", ['goog.math.AffineTransformTest'], ['goog.array', 'goog.math', 'goog.math.AffineTransform', 'goog.testing.jsunit']);
                +goog.addDependency("math/bezier.js", ['goog.math.Bezier'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/bezier_test.js", ['goog.math.BezierTest'], ['goog.math', 'goog.math.Bezier', 'goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/box.js", ['goog.math.Box'], ['goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("math/box_test.js", ['goog.math.BoxTest'], ['goog.math.Box', 'goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/coordinate.js", ['goog.math.Coordinate'], ['goog.math']);
                +goog.addDependency("math/coordinate3.js", ['goog.math.Coordinate3'], []);
                +goog.addDependency("math/coordinate3_test.js", ['goog.math.Coordinate3Test'], ['goog.math.Coordinate3', 'goog.testing.jsunit']);
                +goog.addDependency("math/coordinate_test.js", ['goog.math.CoordinateTest'], ['goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/exponentialbackoff.js", ['goog.math.ExponentialBackoff'], ['goog.asserts']);
                +goog.addDependency("math/exponentialbackoff_test.js", ['goog.math.ExponentialBackoffTest'], ['goog.math.ExponentialBackoff', 'goog.testing.jsunit']);
                +goog.addDependency("math/integer.js", ['goog.math.Integer'], []);
                +goog.addDependency("math/integer_test.js", ['goog.math.IntegerTest'], ['goog.math.Integer', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/interpolator1.js", ['goog.math.interpolator.Interpolator1'], []);
                +goog.addDependency("math/interpolator/linear1.js", ['goog.math.interpolator.Linear1'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.interpolator.Interpolator1']);
                +goog.addDependency("math/interpolator/linear1_test.js", ['goog.math.interpolator.Linear1Test'], ['goog.math.interpolator.Linear1', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/pchip1.js", ['goog.math.interpolator.Pchip1'], ['goog.math', 'goog.math.interpolator.Spline1']);
                +goog.addDependency("math/interpolator/pchip1_test.js", ['goog.math.interpolator.Pchip1Test'], ['goog.math.interpolator.Pchip1', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/spline1.js", ['goog.math.interpolator.Spline1'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.interpolator.Interpolator1', 'goog.math.tdma']);
                +goog.addDependency("math/interpolator/spline1_test.js", ['goog.math.interpolator.Spline1Test'], ['goog.math.interpolator.Spline1', 'goog.testing.jsunit']);
                +goog.addDependency("math/irect.js", ['goog.math.IRect'], []);
                +goog.addDependency("math/line.js", ['goog.math.Line'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/line_test.js", ['goog.math.LineTest'], ['goog.math.Coordinate', 'goog.math.Line', 'goog.testing.jsunit']);
                +goog.addDependency("math/long.js", ['goog.math.Long'], ['goog.asserts', 'goog.reflect']);
                +goog.addDependency("math/long_test.js", ['goog.math.LongTest'], ['goog.asserts', 'goog.math.Long', 'goog.testing.jsunit']);
                +goog.addDependency("math/math.js", ['goog.math'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("math/math_test.js", ['goog.mathTest'], ['goog.math', 'goog.testing.jsunit']);
                +goog.addDependency("math/matrix.js", ['goog.math.Matrix'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.Size', 'goog.string']);
                +goog.addDependency("math/matrix_test.js", ['goog.math.MatrixTest'], ['goog.math.Matrix', 'goog.testing.jsunit']);
                +goog.addDependency("math/path.js", ['goog.math.Path', 'goog.math.Path.Segment'], ['goog.array', 'goog.math', 'goog.math.AffineTransform']);
                +goog.addDependency("math/path_test.js", ['goog.math.PathTest'], ['goog.array', 'goog.math.AffineTransform', 'goog.math.Path', 'goog.testing.jsunit']);
                +goog.addDependency("math/paths.js", ['goog.math.paths'], ['goog.math.Coordinate', 'goog.math.Path']);
                +goog.addDependency("math/paths_test.js", ['goog.math.pathsTest'], ['goog.math.Coordinate', 'goog.math.paths', 'goog.testing.jsunit']);
                +goog.addDependency("math/range.js", ['goog.math.Range'], ['goog.asserts']);
                +goog.addDependency("math/range_test.js", ['goog.math.RangeTest'], ['goog.math.Range', 'goog.testing.jsunit']);
                +goog.addDependency("math/rangeset.js", ['goog.math.RangeSet'], ['goog.array', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.math.Range']);
                +goog.addDependency("math/rangeset_test.js", ['goog.math.RangeSetTest'], ['goog.iter', 'goog.math.Range', 'goog.math.RangeSet', 'goog.testing.jsunit']);
                +goog.addDependency("math/rect.js", ['goog.math.Rect'], ['goog.asserts', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.IRect', 'goog.math.Size']);
                +goog.addDependency("math/rect_test.js", ['goog.math.RectTest'], ['goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.testing.jsunit']);
                +goog.addDependency("math/size.js", ['goog.math.Size'], []);
                +goog.addDependency("math/size_test.js", ['goog.math.SizeTest'], ['goog.math.Size', 'goog.testing.jsunit']);
                +goog.addDependency("math/tdma.js", ['goog.math.tdma'], []);
                +goog.addDependency("math/tdma_test.js", ['goog.math.tdmaTest'], ['goog.math.tdma', 'goog.testing.jsunit']);
                +goog.addDependency("math/vec2.js", ['goog.math.Vec2'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/vec2_test.js", ['goog.math.Vec2Test'], ['goog.math.Vec2', 'goog.testing.jsunit']);
                +goog.addDependency("math/vec3.js", ['goog.math.Vec3'], ['goog.math', 'goog.math.Coordinate3']);
                +goog.addDependency("math/vec3_test.js", ['goog.math.Vec3Test'], ['goog.math.Coordinate3', 'goog.math.Vec3', 'goog.testing.jsunit']);
                +goog.addDependency("memoize/memoize.js", ['goog.memoize'], []);
                +goog.addDependency("memoize/memoize_test.js", ['goog.memoizeTest'], ['goog.memoize', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/abstractchannel.js", ['goog.messaging.AbstractChannel'], ['goog.Disposable', 'goog.json', 'goog.log', 'goog.messaging.MessageChannel']);
                +goog.addDependency("messaging/abstractchannel_test.js", ['goog.messaging.AbstractChannelTest'], ['goog.messaging.AbstractChannel', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/bufferedchannel.js", ['goog.messaging.BufferedChannel'], ['goog.Disposable', 'goog.Timer', 'goog.events', 'goog.log', 'goog.messaging.MessageChannel', 'goog.messaging.MultiChannel']);
                +goog.addDependency("messaging/bufferedchannel_test.js", ['goog.messaging.BufferedChannelTest'], ['goog.debug.Console', 'goog.dom', 'goog.dom.TagName', 'goog.log', 'goog.log.Level', 'goog.messaging.BufferedChannel', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/deferredchannel.js", ['goog.messaging.DeferredChannel'], ['goog.Disposable', 'goog.messaging.MessageChannel']);
                +goog.addDependency("messaging/deferredchannel_test.js", ['goog.messaging.DeferredChannelTest'], ['goog.async.Deferred', 'goog.messaging.DeferredChannel', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/loggerclient.js", ['goog.messaging.LoggerClient'], ['goog.Disposable', 'goog.debug', 'goog.debug.LogManager', 'goog.debug.Logger']);
                +goog.addDependency("messaging/loggerclient_test.js", ['goog.messaging.LoggerClientTest'], ['goog.debug', 'goog.debug.Logger', 'goog.messaging.LoggerClient', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/loggerserver.js", ['goog.messaging.LoggerServer'], ['goog.Disposable', 'goog.log', 'goog.log.Level']);
                +goog.addDependency("messaging/loggerserver_test.js", ['goog.messaging.LoggerServerTest'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.log', 'goog.log.Level', 'goog.messaging.LoggerServer', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/messagechannel.js", ['goog.messaging.MessageChannel'], []);
                +goog.addDependency("messaging/messaging.js", ['goog.messaging'], []);
                +goog.addDependency("messaging/messaging_test.js", ['goog.testing.messaging.MockMessageChannelTest'], ['goog.messaging', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/multichannel.js", ['goog.messaging.MultiChannel', 'goog.messaging.MultiChannel.VirtualChannel'], ['goog.Disposable', 'goog.log', 'goog.messaging.MessageChannel', 'goog.object']);
                +goog.addDependency("messaging/multichannel_test.js", ['goog.messaging.MultiChannelTest'], ['goog.messaging.MultiChannel', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel', 'goog.testing.mockmatchers.IgnoreArgument']);
                +goog.addDependency("messaging/portcaller.js", ['goog.messaging.PortCaller'], ['goog.Disposable', 'goog.async.Deferred', 'goog.messaging.DeferredChannel', 'goog.messaging.PortChannel', 'goog.messaging.PortNetwork', 'goog.object']);
                +goog.addDependency("messaging/portcaller_test.js", ['goog.messaging.PortCallerTest'], ['goog.events.EventTarget', 'goog.messaging.PortCaller', 'goog.messaging.PortNetwork', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/portchannel.js", ['goog.messaging.PortChannel'], ['goog.Timer', 'goog.array', 'goog.async.Deferred', 'goog.debug', 'goog.events', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.messaging.AbstractChannel', 'goog.messaging.DeferredChannel', 'goog.object', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("messaging/portchannel_test.js", ['goog.messaging.PortChannelTest'], ['goog.Promise', 'goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.json', 'goog.messaging.PortChannel', 'goog.testing.MockControl', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageEvent']);
                +goog.addDependency("messaging/portnetwork.js", ['goog.messaging.PortNetwork'], []);
                +goog.addDependency("messaging/portnetwork_test.js", ['goog.messaging.PortNetworkTest'], ['goog.Promise', 'goog.Timer', 'goog.labs.userAgent.browser', 'goog.messaging.PortChannel', 'goog.messaging.PortOperator', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/portoperator.js", ['goog.messaging.PortOperator'], ['goog.Disposable', 'goog.asserts', 'goog.log', 'goog.messaging.PortChannel', 'goog.messaging.PortNetwork', 'goog.object']);
                +goog.addDependency("messaging/portoperator_test.js", ['goog.messaging.PortOperatorTest'], ['goog.messaging.PortNetwork', 'goog.messaging.PortOperator', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel', 'goog.testing.messaging.MockMessagePort']);
                +goog.addDependency("messaging/respondingchannel.js", ['goog.messaging.RespondingChannel'], ['goog.Disposable', 'goog.log', 'goog.messaging.MultiChannel']);
                +goog.addDependency("messaging/respondingchannel_test.js", ['goog.messaging.RespondingChannelTest'], ['goog.messaging.RespondingChannel', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/testdata/portchannel_worker.js", ['goog.messaging.testdata.portchannel_worker'], ['goog.messaging.PortChannel']);
                +goog.addDependency("messaging/testdata/portnetwork_worker1.js", ['goog.messaging.testdata.portnetwork_worker1'], ['goog.messaging.PortCaller', 'goog.messaging.PortChannel']);
                +goog.addDependency("messaging/testdata/portnetwork_worker2.js", ['goog.messaging.testdata.portnetwork_worker2'], ['goog.messaging.PortCaller', 'goog.messaging.PortChannel']);
                +goog.addDependency("module/abstractmoduleloader.js", ['goog.module.AbstractModuleLoader'], ['goog.module', 'goog.module.ModuleInfo']);
                +goog.addDependency("module/basemodule.js", ['goog.module.BaseModule'], ['goog.Disposable', 'goog.module']);
                +goog.addDependency("module/loader.js", ['goog.module.Loader'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.module', 'goog.object']);
                +goog.addDependency("module/module.js", ['goog.module'], []);
                +goog.addDependency("module/moduleinfo.js", ['goog.module.ModuleInfo'], ['goog.Disposable', 'goog.async.throwException', 'goog.functions', 'goog.module', 'goog.module.BaseModule', 'goog.module.ModuleLoadCallback']);
                +goog.addDependency("module/moduleinfo_test.js", ['goog.module.ModuleInfoTest'], ['goog.module.BaseModule', 'goog.module.ModuleInfo', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("module/moduleloadcallback.js", ['goog.module.ModuleLoadCallback'], ['goog.debug.entryPointRegistry', 'goog.module']);
                +goog.addDependency("module/moduleloadcallback_test.js", ['goog.module.ModuleLoadCallbackTest'], ['goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.functions', 'goog.module.ModuleLoadCallback', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("module/moduleloader.js", ['goog.module.ModuleLoader'], ['goog.Timer', 'goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.labs.userAgent.browser', 'goog.log', 'goog.module.AbstractModuleLoader', 'goog.net.BulkLoader', 'goog.net.EventType', 'goog.net.jsloader', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("module/moduleloader_test.js", ['goog.module.ModuleLoaderTest'], ['goog.Promise', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.functions', 'goog.module.ModuleLoader', 'goog.module.ModuleManager', 'goog.net.BulkLoader', 'goog.net.XmlHttp', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.events.EventObserver', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("module/modulemanager.js", ['goog.module.ModuleManager', 'goog.module.ModuleManager.CallbackType', 'goog.module.ModuleManager.FailureType'], ['goog.Disposable', 'goog.array', 'goog.asserts', 'goog.async.Deferred', 'goog.debug.Trace', 'goog.dispose', 'goog.log', 'goog.module', 'goog.module.AbstractModuleLoader', 'goog.module.ModuleInfo', 'goog.module.ModuleLoadCallback', 'goog.object']);
                +goog.addDependency("module/modulemanager_test.js", ['goog.module.ModuleManagerTest'], ['goog.array', 'goog.functions', 'goog.module.BaseModule', 'goog.module.ModuleManager', 'goog.testing', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("module/testdata/modA_1.js", ['goog.module.testdata.modA_1'], []);
                +goog.addDependency("module/testdata/modA_2.js", ['goog.module.testdata.modA_2'], ['goog.module.ModuleManager']);
                +goog.addDependency("module/testdata/modB_1.js", ['goog.module.testdata.modB_1'], ['goog.module.ModuleManager']);
                +goog.addDependency("net/browserchannel.js", ['goog.net.BrowserChannel', 'goog.net.BrowserChannel.Error', 'goog.net.BrowserChannel.Event', 'goog.net.BrowserChannel.Handler', 'goog.net.BrowserChannel.LogSaver', 'goog.net.BrowserChannel.QueuedMap', 'goog.net.BrowserChannel.ServerReachability', 'goog.net.BrowserChannel.ServerReachabilityEvent', 'goog.net.BrowserChannel.Stat', 'goog.net.BrowserChannel.StatEvent', 'goog.net.BrowserChannel.State', 'goog.net.BrowserChannel.TimingEvent'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.TextFormatter', 'goog.events.Event', 'goog.events.EventTarget', 'goog.json', 'goog.json.EvalJsonProcessor', 'goog.log', 'goog.net.BrowserTestChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.net.XhrIo', 'goog.net.tmpnetwork', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.CircularBuffer']);
                +goog.addDependency("net/browserchannel_test.js", ['goog.net.BrowserChannelTest'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.functions', 'goog.json', 'goog.net.BrowserChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.net.tmpnetwork', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/browsertestchannel.js", ['goog.net.BrowserTestChannel'], ['goog.json.EvalJsonProcessor', 'goog.net.ChannelRequest', 'goog.net.ChannelRequest.Error', 'goog.net.tmpnetwork', 'goog.string.Parser']);
                +goog.addDependency("net/bulkloader.js", ['goog.net.BulkLoader'], ['goog.events.EventHandler', 'goog.events.EventTarget', 'goog.log', 'goog.net.BulkLoaderHelper', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("net/bulkloader_test.js", ['goog.net.BulkLoaderTest'], ['goog.events.Event', 'goog.events.EventHandler', 'goog.net.BulkLoader', 'goog.net.EventType', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("net/bulkloaderhelper.js", ['goog.net.BulkLoaderHelper'], ['goog.Disposable']);
                +goog.addDependency("net/channeldebug.js", ['goog.net.ChannelDebug'], ['goog.json', 'goog.log']);
                +goog.addDependency("net/channelrequest.js", ['goog.net.ChannelRequest', 'goog.net.ChannelRequest.Error'], ['goog.Timer', 'goog.async.Throttle', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events.EventHandler', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("net/channelrequest_test.js", ['goog.net.ChannelRequestTest'], ['goog.Uri', 'goog.functions', 'goog.net.BrowserChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("net/cookies.js", ['goog.net.Cookies', 'goog.net.cookies'], ['goog.string']);
                +goog.addDependency("net/cookies_test.js", ['goog.net.cookiesTest'], ['goog.array', 'goog.net.cookies', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("net/corsxmlhttpfactory.js", ['goog.net.CorsXmlHttpFactory', 'goog.net.IeCorsXhrAdapter'], ['goog.net.HttpStatus', 'goog.net.XhrLike', 'goog.net.XmlHttp', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/corsxmlhttpfactory_test.js", ['goog.net.CorsXmlHttpFactoryTest'], ['goog.net.CorsXmlHttpFactory', 'goog.net.IeCorsXhrAdapter', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("net/crossdomainrpc.js", ['goog.net.CrossDomainRpc'], ['goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.json', 'goog.log', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("net/crossdomainrpc_test.js", ['goog.net.CrossDomainRpcTest'], ['goog.Promise', 'goog.log', 'goog.net.CrossDomainRpc', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("net/errorcode.js", ['goog.net.ErrorCode'], []);
                +goog.addDependency("net/eventtype.js", ['goog.net.EventType'], []);
                +goog.addDependency("net/fetchxmlhttpfactory.js", ['goog.net.FetchXmlHttp', 'goog.net.FetchXmlHttpFactory'], ['goog.asserts', 'goog.events.EventTarget', 'goog.functions', 'goog.log', 'goog.net.XhrLike', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/fetchxmlhttpfactory_test.js", ['goog.net.FetchXmlHttpFactoryTest'], ['goog.net.FetchXmlHttp', 'goog.net.FetchXmlHttpFactory', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("net/filedownloader.js", ['goog.net.FileDownloader', 'goog.net.FileDownloader.Error'], ['goog.Disposable', 'goog.asserts', 'goog.async.Deferred', 'goog.crypt.hash32', 'goog.debug.Error', 'goog.events', 'goog.events.EventHandler', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrIoPool', 'goog.object']);
                +goog.addDependency("net/filedownloader_test.js", ['goog.net.FileDownloaderTest'], ['goog.fs.Error', 'goog.net.ErrorCode', 'goog.net.FileDownloader', 'goog.net.XhrIo', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.fs', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit', 'goog.testing.net.XhrIoPool']);
                +goog.addDependency("net/httpstatus.js", ['goog.net.HttpStatus'], []);
                +goog.addDependency("net/httpstatusname.js", ['goog.net.HttpStatusName'], []);
                +goog.addDependency("net/iframeio.js", ['goog.net.IframeIo', 'goog.net.IframeIo.IncrementalDataEvent'], ['goog.Timer', 'goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.HtmlFormatter', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.html.uncheckedconversions', 'goog.json', 'goog.log', 'goog.log.Level', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.reflect', 'goog.string', 'goog.string.Const', 'goog.structs', 'goog.userAgent']);
                +goog.addDependency("net/iframeio_different_base_test.js", ['goog.net.iframeIoDifferentBaseTest'], ['goog.Promise', 'goog.events', 'goog.net.EventType', 'goog.net.IframeIo', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/iframeio_test.js", ['goog.net.IframeIoTest'], ['goog.debug', 'goog.debug.DivConsole', 'goog.debug.LogManager', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.log', 'goog.log.Level', 'goog.net.IframeIo', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("net/iframeloadmonitor.js", ['goog.net.IframeLoadMonitor'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.userAgent']);
                +goog.addDependency("net/iframeloadmonitor_test.js", [], []);
                +goog.addDependency("net/imageloader.js", ['goog.net.ImageLoader'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.net.EventType', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("net/imageloader_test.js", ['goog.net.ImageLoaderTest'], ['goog.Promise', 'goog.Timer', 'goog.array', 'goog.dispose', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.net.EventType', 'goog.net.ImageLoader', 'goog.object', 'goog.string', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/ipaddress.js", ['goog.net.IpAddress', 'goog.net.Ipv4Address', 'goog.net.Ipv6Address'], ['goog.array', 'goog.math.Integer', 'goog.object', 'goog.string']);
                +goog.addDependency("net/ipaddress_test.js", ['goog.net.IpAddressTest'], ['goog.array', 'goog.math.Integer', 'goog.net.IpAddress', 'goog.net.Ipv4Address', 'goog.net.Ipv6Address', 'goog.testing.jsunit']);
                +goog.addDependency("net/jsloader.js", ['goog.net.jsloader', 'goog.net.jsloader.Error', 'goog.net.jsloader.ErrorCode', 'goog.net.jsloader.Options'], ['goog.array', 'goog.async.Deferred', 'goog.debug.Error', 'goog.dom', 'goog.dom.TagName', 'goog.html.TrustedResourceUrl', 'goog.html.legacyconversions', 'goog.object']);
                +goog.addDependency("net/jsloader_test.js", ['goog.net.jsloaderTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.TrustedResourceUrl', 'goog.net.jsloader', 'goog.net.jsloader.ErrorCode', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("net/jsonp.js", ['goog.net.Jsonp'], ['goog.Uri', 'goog.net.jsloader']);
                +goog.addDependency("net/jsonp_test.js", ['goog.net.JsonpTest'], ['goog.net.Jsonp', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("net/mockiframeio.js", ['goog.net.MockIFrameIo'], ['goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.IframeIo']);
                +goog.addDependency("net/multiiframeloadmonitor.js", ['goog.net.MultiIframeLoadMonitor'], ['goog.events', 'goog.net.IframeLoadMonitor']);
                +goog.addDependency("net/multiiframeloadmonitor_test.js", [], []);
                +goog.addDependency("net/networkstatusmonitor.js", ['goog.net.NetworkStatusMonitor'], ['goog.events.Listenable']);
                +goog.addDependency("net/networktester.js", ['goog.net.NetworkTester'], ['goog.Timer', 'goog.Uri', 'goog.log']);
                +goog.addDependency("net/networktester_test.js", ['goog.net.NetworkTesterTest'], ['goog.Uri', 'goog.net.NetworkTester', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("net/rpc/httpcors.js", [], []);
                +goog.addDependency("net/rpc/httpcors_test.js", [], []);
                +goog.addDependency("net/streams/base64pbstreamparser.js", [], []);
                +goog.addDependency("net/streams/base64pbstreamparser_test.js", [], []);
                +goog.addDependency("net/streams/base64streamdecoder.js", ['goog.net.streams.Base64StreamDecoder'], ['goog.asserts', 'goog.crypt.base64']);
                +goog.addDependency("net/streams/base64streamdecoder_test.js", ['goog.net.streams.Base64StreamDecoderTest'], ['goog.net.streams.Base64StreamDecoder', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/jsonstreamparser.js", ['goog.net.streams.JsonStreamParser', 'goog.net.streams.JsonStreamParser.Options'], ['goog.asserts', 'goog.json', 'goog.net.streams.StreamParser', 'goog.net.streams.utils']);
                +goog.addDependency("net/streams/jsonstreamparser_test.js", ['goog.net.streams.JsonStreamParserTest'], ['goog.array', 'goog.json', 'goog.labs.testing.JsonFuzzing', 'goog.net.streams.JsonStreamParser', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.uri.utils']);
                +goog.addDependency("net/streams/nodereadablestream.js", ['goog.net.streams.NodeReadableStream'], []);
                +goog.addDependency("net/streams/pbjsonstreamparser.js", [], []);
                +goog.addDependency("net/streams/pbjsonstreamparser_test.js", [], []);
                +goog.addDependency("net/streams/pbstreamparser.js", ['goog.net.streams.PbStreamParser'], ['goog.asserts', 'goog.net.streams.StreamParser']);
                +goog.addDependency("net/streams/pbstreamparser_test.js", ['goog.net.streams.PbStreamParserTest'], ['goog.net.streams.PbStreamParser', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/streamfactory.js", ['goog.net.streams.createXhrNodeReadableStream'], ['goog.asserts', 'goog.net.streams.XhrNodeReadableStream', 'goog.net.streams.XhrStreamReader']);
                +goog.addDependency("net/streams/streamparser.js", ['goog.net.streams.StreamParser'], []);
                +goog.addDependency("net/streams/utils.js", [], []);
                +goog.addDependency("net/streams/xhrnodereadablestream.js", ['goog.net.streams.XhrNodeReadableStream'], ['goog.array', 'goog.log', 'goog.net.streams.NodeReadableStream', 'goog.net.streams.XhrStreamReader']);
                +goog.addDependency("net/streams/xhrnodereadablestream_test.js", ['goog.net.streams.XhrNodeReadableStreamTest'], ['goog.net.streams.NodeReadableStream', 'goog.net.streams.XhrNodeReadableStream', 'goog.net.streams.XhrStreamReader', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/xhrstreamreader.js", ['goog.net.streams.XhrStreamReader'], ['goog.events.EventHandler', 'goog.log', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.net.streams.Base64PbStreamParser', 'goog.net.streams.JsonStreamParser', 'goog.net.streams.PbJsonStreamParser', 'goog.net.streams.PbStreamParser', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("net/streams/xhrstreamreader_test.js", ['goog.net.streams.XhrStreamReaderTest'], ['goog.net.ErrorCode', 'goog.net.XmlHttp', 'goog.net.streams.Base64PbStreamParser', 'goog.net.streams.JsonStreamParser', 'goog.net.streams.PbJsonStreamParser', 'goog.net.streams.PbStreamParser', 'goog.net.streams.XhrStreamReader', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.net.XhrIo']);
                +goog.addDependency("net/testdata/jsloader_test1.js", ['goog.net.testdata.jsloader_test1'], []);
                +goog.addDependency("net/testdata/jsloader_test2.js", ['goog.net.testdata.jsloader_test2'], []);
                +goog.addDependency("net/testdata/jsloader_test3.js", ['goog.net.testdata.jsloader_test3'], []);
                +goog.addDependency("net/testdata/jsloader_test4.js", ['goog.net.testdata.jsloader_test4'], []);
                +goog.addDependency("net/tmpnetwork.js", ['goog.net.tmpnetwork'], ['goog.Uri', 'goog.net.ChannelDebug']);
                +goog.addDependency("net/websocket.js", ['goog.net.WebSocket', 'goog.net.WebSocket.ErrorEvent', 'goog.net.WebSocket.EventType', 'goog.net.WebSocket.MessageEvent'], ['goog.Timer', 'goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.log']);
                +goog.addDependency("net/websocket_test.js", ['goog.net.WebSocketTest'], ['goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.functions', 'goog.net.WebSocket', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/wrapperxmlhttpfactory.js", ['goog.net.WrapperXmlHttpFactory'], ['goog.net.XhrLike', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/xhrio.js", ['goog.net.XhrIo', 'goog.net.XhrIo.ResponseType'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events.EventTarget', 'goog.json', 'goog.log', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XmlHttp', 'goog.string', 'goog.structs', 'goog.structs.Map', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("net/xhrio_test.js", ['goog.net.XhrIoTest'], ['goog.Uri', 'goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.functions', 'goog.net.EventType', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction', 'goog.userAgent.product']);
                +goog.addDependency("net/xhriopool.js", ['goog.net.XhrIoPool'], ['goog.net.XhrIo', 'goog.structs.PriorityPool']);
                +goog.addDependency("net/xhriopool_test.js", ['goog.net.XhrIoPoolTest'], ['goog.net.XhrIoPool', 'goog.structs.Map', 'goog.testing.jsunit']);
                +goog.addDependency("net/xhrlike.js", ['goog.net.XhrLike'], []);
                +goog.addDependency("net/xhrmanager.js", ['goog.net.XhrManager', 'goog.net.XhrManager.Event', 'goog.net.XhrManager.Request'], ['goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrIoPool', 'goog.structs.Map']);
                +goog.addDependency("net/xhrmanager_test.js", ['goog.net.XhrManagerTest'], ['goog.events', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrManager', 'goog.testing.jsunit', 'goog.testing.net.XhrIoPool', 'goog.testing.recordFunction']);
                +goog.addDependency("net/xmlhttp.js", ['goog.net.DefaultXmlHttpFactory', 'goog.net.XmlHttp', 'goog.net.XmlHttp.OptionType', 'goog.net.XmlHttp.ReadyState', 'goog.net.XmlHttpDefines'], ['goog.asserts', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/xmlhttpfactory.js", ['goog.net.XmlHttpFactory'], ['goog.net.XhrLike']);
                +goog.addDependency("net/xpc/crosspagechannel.js", ['goog.net.xpc.CrossPageChannel'], ['goog.Uri', 'goog.async.Deferred', 'goog.async.Delay', 'goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.messaging.AbstractChannel', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.ChannelStates', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.DirectTransport', 'goog.net.xpc.FrameElementMethodTransport', 'goog.net.xpc.IframePollingTransport', 'goog.net.xpc.IframeRelayTransport', 'goog.net.xpc.NativeMessagingTransport', 'goog.net.xpc.NixTransport', 'goog.net.xpc.TransportTypes', 'goog.net.xpc.UriCfgFields', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("net/xpc/crosspagechannel_test.js", ['goog.net.xpc.CrossPageChannelTest'], ['goog.Disposable', 'goog.Promise', 'goog.Timer', 'goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/crosspagechannelrole.js", ['goog.net.xpc.CrossPageChannelRole'], []);
                +goog.addDependency("net/xpc/directtransport.js", ['goog.net.xpc.DirectTransport'], ['goog.Timer', 'goog.async.Deferred', 'goog.events.EventHandler', 'goog.log', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.object']);
                +goog.addDependency("net/xpc/directtransport_test.js", ['goog.net.xpc.DirectTransportTest'], ['goog.Promise', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/frameelementmethodtransport.js", ['goog.net.xpc.FrameElementMethodTransport'], ['goog.log', 'goog.net.xpc', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes']);
                +goog.addDependency("net/xpc/iframepollingtransport.js", ['goog.net.xpc.IframePollingTransport', 'goog.net.xpc.IframePollingTransport.Receiver', 'goog.net.xpc.IframePollingTransport.Sender'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.userAgent']);
                +goog.addDependency("net/xpc/iframepollingtransport_test.js", ['goog.net.xpc.IframePollingTransportTest'], ['goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.object', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/xpc/iframerelaytransport.js", ['goog.net.xpc.IframeRelayTransport'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.html.SafeHtml', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("net/xpc/nativemessagingtransport.js", ['goog.net.xpc.NativeMessagingTransport'], ['goog.Timer', 'goog.asserts', 'goog.async.Deferred', 'goog.events', 'goog.events.EventHandler', 'goog.log', 'goog.net.xpc', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes']);
                +goog.addDependency("net/xpc/nativemessagingtransport_test.js", ['goog.net.xpc.NativeMessagingTransportTest'], ['goog.dom', 'goog.events', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.NativeMessagingTransport', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/nixtransport.js", ['goog.net.xpc.NixTransport'], ['goog.log', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.reflect']);
                +goog.addDependency("net/xpc/relay.js", ['goog.net.xpc.relay'], []);
                +goog.addDependency("net/xpc/transport.js", ['goog.net.xpc.Transport'], ['goog.Disposable', 'goog.dom', 'goog.net.xpc.TransportNames']);
                +goog.addDependency("net/xpc/xpc.js", ['goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.ChannelStates', 'goog.net.xpc.TransportNames', 'goog.net.xpc.TransportTypes', 'goog.net.xpc.UriCfgFields'], ['goog.log']);
                +goog.addDependency("object/object.js", ['goog.object'], []);
                +goog.addDependency("object/object_test.js", ['goog.objectTest'], ['goog.array', 'goog.functions', 'goog.object', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("positioning/absoluteposition.js", ['goog.positioning.AbsolutePosition'], ['goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition']);
                +goog.addDependency("positioning/abstractposition.js", ['goog.positioning.AbstractPosition'], []);
                +goog.addDependency("positioning/anchoredposition.js", ['goog.positioning.AnchoredPosition'], ['goog.positioning', 'goog.positioning.AbstractPosition']);
                +goog.addDependency("positioning/anchoredposition_test.js", ['goog.positioning.AnchoredPositionTest'], ['goog.dom', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/anchoredviewportposition.js", ['goog.positioning.AnchoredViewportPosition'], ['goog.positioning', 'goog.positioning.AnchoredPosition', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus']);
                +goog.addDependency("positioning/anchoredviewportposition_test.js", ['goog.positioning.AnchoredViewportPositionTest'], ['goog.dom', 'goog.math.Box', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.positioning.OverflowStatus', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/clientposition.js", ['goog.positioning.ClientPosition'], ['goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition', 'goog.style']);
                +goog.addDependency("positioning/clientposition_test.js", ['goog.positioning.clientPositionTest'], ['goog.dom', 'goog.dom.TagName', 'goog.positioning.ClientPosition', 'goog.positioning.Corner', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/menuanchoredposition.js", ['goog.positioning.MenuAnchoredPosition'], ['goog.positioning.AnchoredViewportPosition', 'goog.positioning.Overflow']);
                +goog.addDependency("positioning/menuanchoredposition_test.js", ['goog.positioning.MenuAnchoredPositionTest'], ['goog.dom', 'goog.dom.TagName', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/positioning.js", ['goog.positioning', 'goog.positioning.Corner', 'goog.positioning.CornerBit', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.style', 'goog.style.bidi']);
                +goog.addDependency("positioning/positioning_test.js", ['goog.positioningTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Size', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("positioning/viewportclientposition.js", ['goog.positioning.ViewportClientPosition'], ['goog.dom', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.ClientPosition', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.style']);
                +goog.addDependency("positioning/viewportclientposition_test.js", ['goog.positioning.ViewportClientPositionTest'], ['goog.dom', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.ViewportClientPosition', 'goog.style', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("positioning/viewportposition.js", ['goog.positioning.ViewportPosition'], ['goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition', 'goog.positioning.Corner', 'goog.style']);
                +goog.addDependency("promise/promise.js", ['goog.Promise'], ['goog.Thenable', 'goog.asserts', 'goog.async.FreeList', 'goog.async.run', 'goog.async.throwException', 'goog.debug.Error', 'goog.promise.Resolver']);
                +goog.addDependency("promise/promise_test.js", ['goog.PromiseTest'], ['goog.Promise', 'goog.Thenable', 'goog.Timer', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("promise/resolver.js", ['goog.promise.Resolver'], []);
                +goog.addDependency("promise/testsuiteadapter.js", ['goog.promise.testSuiteAdapter'], ['goog.Promise']);
                +goog.addDependency("promise/thenable.js", ['goog.Thenable'], []);
                +goog.addDependency("proto/proto.js", ['goog.proto'], ['goog.proto.Serializer']);
                +goog.addDependency("proto/serializer.js", ['goog.proto.Serializer'], ['goog.json.Serializer', 'goog.string']);
                +goog.addDependency("proto/serializer_test.js", ['goog.protoTest'], ['goog.proto', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/descriptor.js", ['goog.proto2.Descriptor', 'goog.proto2.Metadata'], ['goog.array', 'goog.asserts', 'goog.object', 'goog.string']);
                +goog.addDependency("proto2/descriptor_test.js", ['goog.proto2.DescriptorTest'], ['goog.proto2.Descriptor', 'goog.proto2.Message', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/fielddescriptor.js", ['goog.proto2.FieldDescriptor'], ['goog.asserts', 'goog.string']);
                +goog.addDependency("proto2/fielddescriptor_test.js", ['goog.proto2.FieldDescriptorTest'], ['goog.proto2.FieldDescriptor', 'goog.proto2.Message', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/lazydeserializer.js", ['goog.proto2.LazyDeserializer'], ['goog.asserts', 'goog.proto2.Message', 'goog.proto2.Serializer']);
                +goog.addDependency("proto2/message.js", ['goog.proto2.Message'], ['goog.asserts', 'goog.proto2.Descriptor', 'goog.proto2.FieldDescriptor']);
                +goog.addDependency("proto2/message_test.js", ['goog.proto2.MessageTest'], ['goog.testing.TestCase', 'goog.testing.jsunit', 'proto2.TestAllTypes', 'proto2.TestAllTypes.NestedEnum', 'proto2.TestAllTypes.NestedMessage', 'proto2.TestAllTypes.OptionalGroup', 'proto2.TestAllTypes.RepeatedGroup']);
                +goog.addDependency("proto2/objectserializer.js", ['goog.proto2.ObjectSerializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.Serializer', 'goog.string']);
                +goog.addDependency("proto2/objectserializer_test.js", ['goog.proto2.ObjectSerializerTest'], ['goog.proto2.ObjectSerializer', 'goog.proto2.Serializer', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/package_test.pb.js", ['someprotopackage.TestPackageTypes'], ['goog.proto2.Message', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/pbliteserializer.js", ['goog.proto2.PbLiteSerializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.LazyDeserializer', 'goog.proto2.Serializer']);
                +goog.addDependency("proto2/pbliteserializer_test.js", ['goog.proto2.PbLiteSerializerTest'], ['goog.proto2.PbLiteSerializer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/proto_test.js", ['goog.proto2.messageTest'], ['goog.proto2.FieldDescriptor', 'goog.testing.jsunit', 'proto2.TestAllTypes', 'proto2.TestDefaultParent', 'someprotopackage.TestPackageTypes']);
                +goog.addDependency("proto2/serializer.js", ['goog.proto2.Serializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.Message']);
                +goog.addDependency("proto2/test.pb.js", ['proto2.TestAllTypes', 'proto2.TestAllTypes.NestedEnum', 'proto2.TestAllTypes.NestedMessage', 'proto2.TestAllTypes.OptionalGroup', 'proto2.TestAllTypes.RepeatedGroup', 'proto2.TestDefaultChild', 'proto2.TestDefaultParent'], ['goog.proto2.Message']);
                +goog.addDependency("proto2/textformatserializer.js", ['goog.proto2.TextFormatSerializer'], ['goog.array', 'goog.asserts', 'goog.json', 'goog.math', 'goog.object', 'goog.proto2.FieldDescriptor', 'goog.proto2.Message', 'goog.proto2.Serializer', 'goog.string']);
                +goog.addDependency("proto2/textformatserializer_test.js", ['goog.proto2.TextFormatSerializerTest'], ['goog.proto2.ObjectSerializer', 'goog.proto2.TextFormatSerializer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/util.js", ['goog.proto2.Util'], ['goog.asserts']);
                +goog.addDependency("pubsub/pubsub.js", ['goog.pubsub.PubSub'], ['goog.Disposable', 'goog.array', 'goog.async.run']);
                +goog.addDependency("pubsub/pubsub_test.js", ['goog.pubsub.PubSubTest'], ['goog.array', 'goog.pubsub.PubSub', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("pubsub/topicid.js", ['goog.pubsub.TopicId'], []);
                +goog.addDependency("pubsub/typedpubsub.js", ['goog.pubsub.TypedPubSub'], ['goog.Disposable', 'goog.pubsub.PubSub']);
                +goog.addDependency("pubsub/typedpubsub_test.js", ['goog.pubsub.TypedPubSubTest'], ['goog.array', 'goog.pubsub.TopicId', 'goog.pubsub.TypedPubSub', 'goog.testing.jsunit']);
                +goog.addDependency("reflect/reflect.js", ['goog.reflect'], []);
                +goog.addDependency("reflect/reflect_test.js", ['goog.reflectTest'], ['goog.object', 'goog.reflect', 'goog.testing.jsunit']);
                +goog.addDependency("result/chain_test.js", ['goog.result.chainTest'], ['goog.Timer', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/combine_test.js", ['goog.result.combineTest'], ['goog.Timer', 'goog.array', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/deferredadaptor.js", ['goog.result.DeferredAdaptor'], ['goog.async.Deferred', 'goog.result', 'goog.result.Result']);
                +goog.addDependency("result/deferredadaptor_test.js", ['goog.result.DeferredAdaptorTest'], ['goog.result', 'goog.result.DeferredAdaptor', 'goog.result.SimpleResult', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/dependentresult.js", ['goog.result.DependentResult'], ['goog.result.Result']);
                +goog.addDependency("result/result_interface.js", ['goog.result.Result'], ['goog.Thenable']);
                +goog.addDependency("result/resultutil.js", ['goog.result'], ['goog.array', 'goog.result.DependentResult', 'goog.result.Result', 'goog.result.SimpleResult']);
                +goog.addDependency("result/resultutil_test.js", ['goog.resultTest'], ['goog.result', 'goog.testing.jsunit']);
                +goog.addDependency("result/simpleresult.js", ['goog.result.SimpleResult', 'goog.result.SimpleResult.StateError'], ['goog.Promise', 'goog.Thenable', 'goog.debug.Error', 'goog.result.Result']);
                +goog.addDependency("result/simpleresult_test.js", ['goog.result.SimpleResultTest'], ['goog.Timer', 'goog.Promise', 'goog.Thenable', 'goog.result', 'goog.testing.MockClock', 'goog.testing.recordFunction', 'goog.testing.jsunit']);
                +goog.addDependency("result/transform_test.js", ['goog.result.transformTest'], ['goog.Timer', 'goog.result.SimpleResult', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/wait_test.js", ['goog.result.waitTest'], ['goog.Timer', 'goog.result.SimpleResult', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("soy/data.js", ['goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.soy.data.SanitizedCss', 'goog.soy.data.SanitizedHtml', 'goog.soy.data.SanitizedHtmlAttribute', 'goog.soy.data.SanitizedJs', 'goog.soy.data.SanitizedTrustedResourceUri', 'goog.soy.data.SanitizedUri', 'goog.soy.data.UnsanitizedText'], ['goog.Uri', 'goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.uncheckedconversions', 'goog.i18n.bidi.Dir', 'goog.string.Const']);
                +goog.addDependency("soy/data_test.js", ['goog.soy.dataTest'], ['goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.soy.testHelper', 'goog.testing.jsunit']);
                +goog.addDependency("soy/renderer.js", ['goog.soy.InjectedDataSupplier', 'goog.soy.Renderer'], ['goog.asserts', 'goog.dom', 'goog.html.uncheckedconversions', 'goog.soy', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string.Const']);
                +goog.addDependency("soy/renderer_test.js", ['goog.soy.RendererTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.SafeHtml', 'goog.i18n.bidi.Dir', 'goog.soy.Renderer', 'goog.soy.data.SanitizedContentKind', 'goog.soy.testHelper', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("soy/soy.js", ['goog.soy'], ['goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.legacyconversions', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string']);
                +goog.addDependency("soy/soy_test.js", ['goog.soyTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.soy', 'goog.soy.testHelper', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("soy/soy_testhelper.js", ['goog.soy.testHelper'], ['goog.dom', 'goog.dom.TagName', 'goog.i18n.bidi.Dir', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("spell/spellcheck.js", ['goog.spell.SpellCheck', 'goog.spell.SpellCheck.WordChangedEvent'], ['goog.Timer', 'goog.events.Event', 'goog.events.EventTarget', 'goog.structs.Set']);
                +goog.addDependency("spell/spellcheck_test.js", ['goog.spell.SpellCheckTest'], ['goog.spell.SpellCheck', 'goog.testing.jsunit']);
                +goog.addDependency("stats/basicstat.js", ['goog.stats.BasicStat'], ['goog.asserts', 'goog.log', 'goog.string.format', 'goog.structs.CircularBuffer']);
                +goog.addDependency("stats/basicstat_test.js", ['goog.stats.BasicStatTest'], ['goog.array', 'goog.stats.BasicStat', 'goog.string.format', 'goog.testing.PseudoRandom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/collectablestorage.js", ['goog.storage.CollectableStorage'], ['goog.array', 'goog.iter', 'goog.storage.ErrorCode', 'goog.storage.ExpiringStorage', 'goog.storage.RichStorage']);
                +goog.addDependency("storage/collectablestorage_test.js", ['goog.storage.CollectableStorageTest'], ['goog.storage.CollectableStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/collectablestoragetester.js", ['goog.storage.collectableStorageTester'], ['goog.testing.asserts']);
                +goog.addDependency("storage/encryptedstorage.js", ['goog.storage.EncryptedStorage'], ['goog.crypt', 'goog.crypt.Arc4', 'goog.crypt.Sha1', 'goog.crypt.base64', 'goog.json', 'goog.json.Serializer', 'goog.storage.CollectableStorage', 'goog.storage.ErrorCode', 'goog.storage.RichStorage']);
                +goog.addDependency("storage/encryptedstorage_test.js", ['goog.storage.EncryptedStorageTest'], ['goog.json', 'goog.storage.EncryptedStorage', 'goog.storage.ErrorCode', 'goog.storage.RichStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.PseudoRandom', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/errorcode.js", ['goog.storage.ErrorCode'], []);
                +goog.addDependency("storage/expiringstorage.js", ['goog.storage.ExpiringStorage'], ['goog.storage.RichStorage']);
                +goog.addDependency("storage/expiringstorage_test.js", ['goog.storage.ExpiringStorageTest'], ['goog.storage.ExpiringStorage', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/mechanism/errorcode.js", ['goog.storage.mechanism.ErrorCode'], []);
                +goog.addDependency("storage/mechanism/errorhandlingmechanism.js", ['goog.storage.mechanism.ErrorHandlingMechanism'], ['goog.storage.mechanism.Mechanism']);
                +goog.addDependency("storage/mechanism/errorhandlingmechanism_test.js", ['goog.storage.mechanism.ErrorHandlingMechanismTest'], ['goog.storage.mechanism.ErrorHandlingMechanism', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("storage/mechanism/html5localstorage.js", ['goog.storage.mechanism.HTML5LocalStorage'], ['goog.storage.mechanism.HTML5WebStorage']);
                +goog.addDependency("storage/mechanism/html5localstorage_test.js", ['goog.storage.mechanism.HTML5LocalStorageTest'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/html5sessionstorage.js", ['goog.storage.mechanism.HTML5SessionStorage'], ['goog.storage.mechanism.HTML5WebStorage']);
                +goog.addDependency("storage/mechanism/html5sessionstorage_test.js", ['goog.storage.mechanism.HTML5SessionStorageTest'], ['goog.storage.mechanism.HTML5SessionStorage', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/html5webstorage.js", ['goog.storage.mechanism.HTML5WebStorage'], ['goog.asserts', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.IterableMechanism']);
                +goog.addDependency("storage/mechanism/html5webstorage_test.js", ['goog.storage.mechanism.HTML5MockStorage', 'goog.storage.mechanism.HTML5WebStorageTest', 'goog.storage.mechanism.MockThrowableStorage'], ['goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.HTML5WebStorage', 'goog.testing.jsunit']);
                +goog.addDependency("storage/mechanism/ieuserdata.js", ['goog.storage.mechanism.IEUserData'], ['goog.asserts', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.IterableMechanism', 'goog.structs.Map', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/ieuserdata_test.js", ['goog.storage.mechanism.IEUserDataTest'], ['goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/iterablemechanism.js", ['goog.storage.mechanism.IterableMechanism'], ['goog.array', 'goog.asserts', 'goog.iter', 'goog.storage.mechanism.Mechanism']);
                +goog.addDependency("storage/mechanism/iterablemechanismtester.js", ['goog.storage.mechanism.iterableMechanismTester'], ['goog.iter', 'goog.iter.StopIteration', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanism.js", ['goog.storage.mechanism.Mechanism'], []);
                +goog.addDependency("storage/mechanism/mechanismfactory.js", ['goog.storage.mechanism.mechanismfactory'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.HTML5SessionStorage', 'goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.PrefixedMechanism']);
                +goog.addDependency("storage/mechanism/mechanismfactory_test.js", ['goog.storage.mechanism.mechanismfactoryTest'], ['goog.storage.mechanism.mechanismfactory', 'goog.testing.jsunit']);
                +goog.addDependency("storage/mechanism/mechanismseparationtester.js", ['goog.storage.mechanism.mechanismSeparationTester'], ['goog.iter.StopIteration', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanismsharingtester.js", ['goog.storage.mechanism.mechanismSharingTester'], ['goog.iter.StopIteration', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanismtestdefinition.js", ['goog.storage.mechanism.mechanismTestDefinition'], []);
                +goog.addDependency("storage/mechanism/mechanismtester.js", ['goog.storage.mechanism.mechanismTester'], ['goog.storage.mechanism.ErrorCode', 'goog.testing.asserts', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("storage/mechanism/prefixedmechanism.js", ['goog.storage.mechanism.PrefixedMechanism'], ['goog.iter.Iterator', 'goog.storage.mechanism.IterableMechanism']);
                +goog.addDependency("storage/mechanism/prefixedmechanism_test.js", ['goog.storage.mechanism.PrefixedMechanismTest'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.PrefixedMechanism', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.testing.jsunit']);
                +goog.addDependency("storage/richstorage.js", ['goog.storage.RichStorage', 'goog.storage.RichStorage.Wrapper'], ['goog.storage.ErrorCode', 'goog.storage.Storage']);
                +goog.addDependency("storage/richstorage_test.js", ['goog.storage.RichStorageTest'], ['goog.storage.ErrorCode', 'goog.storage.RichStorage', 'goog.storage.storageTester', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/storage.js", ['goog.storage.Storage'], ['goog.json', 'goog.storage.ErrorCode']);
                +goog.addDependency("storage/storage_test.js", ['goog.storage.storage_test'], ['goog.functions', 'goog.storage.ErrorCode', 'goog.storage.Storage', 'goog.storage.mechanism.mechanismfactory', 'goog.storage.storageTester', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/storagetester.js", ['goog.storage.storageTester'], ['goog.storage.Storage', 'goog.structs.Map', 'goog.testing.asserts']);
                +goog.addDependency("string/const.js", ['goog.string.Const'], ['goog.asserts', 'goog.string.TypedString']);
                +goog.addDependency("string/const_test.js", ['goog.string.constTest'], ['goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("string/linkify.js", ['goog.string.linkify'], ['goog.html.SafeHtml', 'goog.string']);
                +goog.addDependency("string/linkify_test.js", ['goog.string.linkifyTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.string', 'goog.string.linkify', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("string/newlines.js", ['goog.string.newlines', 'goog.string.newlines.Line'], ['goog.array']);
                +goog.addDependency("string/newlines_test.js", ['goog.string.newlinesTest'], ['goog.string.newlines', 'goog.testing.jsunit']);
                +goog.addDependency("string/parser.js", ['goog.string.Parser'], []);
                +goog.addDependency("string/path.js", ['goog.string.path'], ['goog.array', 'goog.string']);
                +goog.addDependency("string/path_test.js", ['goog.string.pathTest'], ['goog.string.path', 'goog.testing.jsunit']);
                +goog.addDependency("string/string.js", ['goog.string', 'goog.string.Unicode'], []);
                +goog.addDependency("string/string_test.js", ['goog.stringTest'], ['goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringbuffer.js", ['goog.string.StringBuffer'], []);
                +goog.addDependency("string/stringbuffer_test.js", ['goog.string.StringBufferTest'], ['goog.string.StringBuffer', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringformat.js", ['goog.string.format'], ['goog.string']);
                +goog.addDependency("string/stringformat_test.js", ['goog.string.formatTest'], ['goog.string.format', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringifier.js", ['goog.string.Stringifier'], []);
                +goog.addDependency("string/typedstring.js", ['goog.string.TypedString'], []);
                +goog.addDependency("structs/avltree.js", ['goog.structs.AvlTree', 'goog.structs.AvlTree.Node'], ['goog.structs.Collection']);
                +goog.addDependency("structs/avltree_test.js", ['goog.structs.AvlTreeTest'], ['goog.array', 'goog.structs.AvlTree', 'goog.testing.jsunit']);
                +goog.addDependency("structs/circularbuffer.js", ['goog.structs.CircularBuffer'], []);
                +goog.addDependency("structs/circularbuffer_test.js", ['goog.structs.CircularBufferTest'], ['goog.structs.CircularBuffer', 'goog.testing.jsunit']);
                +goog.addDependency("structs/collection.js", ['goog.structs.Collection'], []);
                +goog.addDependency("structs/collection_test.js", ['goog.structs.CollectionTest'], ['goog.structs.AvlTree', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/heap.js", ['goog.structs.Heap'], ['goog.array', 'goog.object', 'goog.structs.Node']);
                +goog.addDependency("structs/heap_test.js", ['goog.structs.HeapTest'], ['goog.structs', 'goog.structs.Heap', 'goog.testing.jsunit']);
                +goog.addDependency("structs/inversionmap.js", ['goog.structs.InversionMap'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("structs/inversionmap_test.js", ['goog.structs.InversionMapTest'], ['goog.structs.InversionMap', 'goog.testing.jsunit']);
                +goog.addDependency("structs/linkedmap.js", ['goog.structs.LinkedMap'], ['goog.structs.Map']);
                +goog.addDependency("structs/linkedmap_test.js", ['goog.structs.LinkedMapTest'], ['goog.structs.LinkedMap', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("structs/map.js", ['goog.structs.Map'], ['goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.object']);
                +goog.addDependency("structs/map_test.js", ['goog.structs.MapTest'], ['goog.iter', 'goog.structs', 'goog.structs.Map', 'goog.testing.jsunit']);
                +goog.addDependency("structs/node.js", ['goog.structs.Node'], []);
                +goog.addDependency("structs/pool.js", ['goog.structs.Pool'], ['goog.Disposable', 'goog.structs.Queue', 'goog.structs.Set']);
                +goog.addDependency("structs/pool_test.js", ['goog.structs.PoolTest'], ['goog.structs.Pool', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("structs/prioritypool.js", ['goog.structs.PriorityPool'], ['goog.structs.Pool', 'goog.structs.PriorityQueue']);
                +goog.addDependency("structs/prioritypool_test.js", ['goog.structs.PriorityPoolTest'], ['goog.structs.PriorityPool', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("structs/priorityqueue.js", ['goog.structs.PriorityQueue'], ['goog.structs.Heap']);
                +goog.addDependency("structs/priorityqueue_test.js", ['goog.structs.PriorityQueueTest'], ['goog.structs', 'goog.structs.PriorityQueue', 'goog.testing.jsunit']);
                +goog.addDependency("structs/quadtree.js", ['goog.structs.QuadTree', 'goog.structs.QuadTree.Node', 'goog.structs.QuadTree.Point'], ['goog.math.Coordinate']);
                +goog.addDependency("structs/quadtree_test.js", ['goog.structs.QuadTreeTest'], ['goog.structs', 'goog.structs.QuadTree', 'goog.testing.jsunit']);
                +goog.addDependency("structs/queue.js", ['goog.structs.Queue'], ['goog.array']);
                +goog.addDependency("structs/queue_test.js", ['goog.structs.QueueTest'], ['goog.structs.Queue', 'goog.testing.jsunit']);
                +goog.addDependency("structs/set.js", ['goog.structs.Set'], ['goog.structs', 'goog.structs.Collection', 'goog.structs.Map']);
                +goog.addDependency("structs/set_test.js", ['goog.structs.SetTest'], ['goog.iter', 'goog.structs', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/simplepool.js", ['goog.structs.SimplePool'], ['goog.Disposable']);
                +goog.addDependency("structs/stringset.js", ['goog.structs.StringSet'], ['goog.asserts', 'goog.iter']);
                +goog.addDependency("structs/stringset_test.js", ['goog.structs.StringSetTest'], ['goog.array', 'goog.iter', 'goog.structs.StringSet', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("structs/structs.js", ['goog.structs'], ['goog.array', 'goog.object']);
                +goog.addDependency("structs/structs_test.js", ['goog.structsTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.structs', 'goog.structs.Map', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/treenode.js", ['goog.structs.TreeNode'], ['goog.array', 'goog.asserts', 'goog.structs.Node']);
                +goog.addDependency("structs/treenode_test.js", ['goog.structs.TreeNodeTest'], ['goog.structs.TreeNode', 'goog.testing.jsunit']);
                +goog.addDependency("structs/trie.js", ['goog.structs.Trie'], ['goog.object', 'goog.structs']);
                +goog.addDependency("structs/trie_test.js", ['goog.structs.TrieTest'], ['goog.object', 'goog.structs', 'goog.structs.Trie', 'goog.testing.jsunit']);
                +goog.addDependency("structs/weak/weak.js", ['goog.structs.weak'], ['goog.userAgent']);
                +goog.addDependency("structs/weak/weak_test.js", ['goog.structs.weakTest'], ['goog.array', 'goog.structs.weak', 'goog.testing.jsunit']);
                +goog.addDependency("style/bidi.js", ['goog.style.bidi'], ['goog.dom', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("style/bidi_test.js", ['goog.style.bidiTest'], ['goog.dom', 'goog.style', 'goog.style.bidi', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/cursor.js", ['goog.style.cursor'], ['goog.userAgent']);
                +goog.addDependency("style/cursor_test.js", ['goog.style.cursorTest'], ['goog.style.cursor', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/style.js", ['goog.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.vendor', 'goog.html.SafeStyleSheet', 'goog.html.legacyconversions', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.object', 'goog.reflect', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("style/style_document_scroll_test.js", ['goog.style.style_document_scroll_test'], ['goog.dom', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("style/style_test.js", ['goog.style_test'], ['goog.array', 'goog.color', 'goog.dom', 'goog.dom.TagName', 'goog.events.BrowserEvent', 'goog.html.testing', 'goog.labs.userAgent.util', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.MockUserAgent', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil', 'goog.userAgentTestUtil.UserAgents']);
                +goog.addDependency("style/style_webkit_scrollbars_test.js", ['goog.style.webkitScrollbarsTest'], ['goog.asserts', 'goog.style', 'goog.styleScrollbarTester', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/stylescrollbartester.js", ['goog.styleScrollbarTester'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.asserts']);
                +goog.addDependency("style/transform.js", ['goog.style.transform'], ['goog.functions', 'goog.math.Coordinate', 'goog.math.Coordinate3', 'goog.style', 'goog.userAgent', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("style/transform_test.js", ['goog.style.transformTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.style.transform', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("style/transition.js", ['goog.style.transition', 'goog.style.transition.Css3Property'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.dom.vendor', 'goog.functions', 'goog.html.SafeHtml', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("style/transition_test.js", ['goog.style.transitionTest'], ['goog.style', 'goog.style.transition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("test_module.js", [], []);
                +goog.addDependency("test_module_dep.js", [], []);
                +goog.addDependency("testing/asserts.js", ['goog.testing.asserts'], ['goog.testing.JsUnitException']);
                +goog.addDependency("testing/asserts_test.js", ['goog.testing.assertsTest'], ['goog.array', 'goog.dom', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.labs.userAgent.browser', 'goog.string', 'goog.structs.Map', 'goog.structs.Set', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("testing/async/mockcontrol.js", ['goog.testing.async.MockControl'], ['goog.asserts', 'goog.async.Deferred', 'goog.debug', 'goog.testing.asserts', 'goog.testing.mockmatchers.IgnoreArgument']);
                +goog.addDependency("testing/async/mockcontrol_test.js", ['goog.testing.async.MockControlTest'], ['goog.async.Deferred', 'goog.testing.MockControl', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.async.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase.js", ['goog.testing.AsyncTestCase', 'goog.testing.AsyncTestCase.ControlBreakingException'], ['goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/asynctestcase_async_test.js", ['goog.testing.AsyncTestCaseAsyncTest'], ['goog.testing.AsyncTestCase', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase_noasync_test.js", ['goog.testing.AsyncTestCaseSyncTest'], ['goog.testing.AsyncTestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase_test.js", ['goog.testing.AsyncTestCaseTest'], ['goog.debug.Error', 'goog.testing.AsyncTestCase', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("testing/benchmark.js", ['goog.testing.benchmark'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTable', 'goog.testing.PerformanceTimer', 'goog.testing.TestCase']);
                +goog.addDependency("testing/continuationtestcase.js", ['goog.testing.ContinuationTestCase', 'goog.testing.ContinuationTestCase.ContinuationTest', 'goog.testing.ContinuationTestCase.Step'], ['goog.array', 'goog.events.EventHandler', 'goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/continuationtestcase_test.js", ['goog.testing.ContinuationTestCaseTest'], ['goog.events', 'goog.events.EventTarget', 'goog.testing.ContinuationTestCase', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/deferredtestcase.js", ['goog.testing.DeferredTestCase'], ['goog.testing.AsyncTestCase', 'goog.testing.TestCase']);
                +goog.addDependency("testing/deferredtestcase_test.js", ['goog.testing.DeferredTestCaseTest'], ['goog.async.Deferred', 'goog.testing.DeferredTestCase', 'goog.testing.TestCase', 'goog.testing.TestRunner', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/dom.js", ['goog.testing.dom'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.NodeIterator', 'goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.iter', 'goog.object', 'goog.string', 'goog.style', 'goog.testing.asserts', 'goog.userAgent']);
                +goog.addDependency("testing/dom_test.js", ['goog.testing.domTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.TestCase', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/editor/dom.js", ['goog.testing.editor.dom'], ['goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagWalkType', 'goog.iter', 'goog.string', 'goog.testing.asserts']);
                +goog.addDependency("testing/editor/dom_test.js", ['goog.testing.editor.domTest'], ['goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.testing.TestCase', 'goog.testing.editor.dom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/editor/fieldmock.js", ['goog.testing.editor.FieldMock'], ['goog.dom', 'goog.dom.Range', 'goog.editor.Field', 'goog.testing.LooseMock', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/editor/testhelper.js", ['goog.testing.editor.TestHelper'], ['goog.Disposable', 'goog.dom', 'goog.dom.Range', 'goog.editor.BrowserFeature', 'goog.editor.node', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.testing.dom']);
                +goog.addDependency("testing/editor/testhelper_test.js", ['goog.testing.editor.TestHelperTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.node', 'goog.testing.TestCase', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/events/eventobserver.js", ['goog.testing.events.EventObserver'], ['goog.array']);
                +goog.addDependency("testing/events/eventobserver_test.js", ['goog.testing.events.EventObserverTest'], ['goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.testing.events.EventObserver', 'goog.testing.jsunit']);
                +goog.addDependency("testing/events/events.js", ['goog.testing.events', 'goog.testing.events.Event'], ['goog.Disposable', 'goog.asserts', 'goog.dom.NodeType', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.object', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("testing/events/events_test.js", ['goog.testing.eventsTest'], ['goog.array', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("testing/events/matchers.js", ['goog.testing.events.EventMatcher'], ['goog.events.Event', 'goog.testing.mockmatchers.ArgumentMatcher']);
                +goog.addDependency("testing/events/matchers_test.js", ['goog.testing.events.EventMatcherTest'], ['goog.events.Event', 'goog.testing.events.EventMatcher', 'goog.testing.jsunit']);
                +goog.addDependency("testing/events/onlinehandler.js", ['goog.testing.events.OnlineHandler'], ['goog.events.EventTarget', 'goog.net.NetworkStatusMonitor']);
                +goog.addDependency("testing/events/onlinehandler_test.js", ['goog.testing.events.OnlineHandlerTest'], ['goog.events', 'goog.net.NetworkStatusMonitor', 'goog.testing.events.EventObserver', 'goog.testing.events.OnlineHandler', 'goog.testing.jsunit']);
                +goog.addDependency("testing/expectedfailures.js", ['goog.testing.ExpectedFailures'], ['goog.asserts', 'goog.debug.DivConsole', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.log', 'goog.style', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/expectedfailures_test.js", ['goog.testing.ExpectedFailuresTest'], ['goog.debug.Logger', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/blob.js", ['goog.testing.fs.Blob'], ['goog.crypt', 'goog.crypt.base64']);
                +goog.addDependency("testing/fs/blob_test.js", ['goog.testing.fs.BlobTest'], ['goog.dom', 'goog.testing.fs.Blob', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/directoryentry_test.js", ['goog.testing.fs.DirectoryEntryTest'], ['goog.array', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/entry.js", ['goog.testing.fs.DirectoryEntry', 'goog.testing.fs.Entry', 'goog.testing.fs.FileEntry'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.async.Deferred', 'goog.fs.DirectoryEntry', 'goog.fs.DirectoryEntryImpl', 'goog.fs.Entry', 'goog.fs.Error', 'goog.fs.FileEntry', 'goog.functions', 'goog.object', 'goog.string', 'goog.testing.fs.File', 'goog.testing.fs.FileWriter']);
                +goog.addDependency("testing/fs/entry_test.js", ['goog.testing.fs.EntryTest'], ['goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/file.js", ['goog.testing.fs.File'], ['goog.testing.fs.Blob']);
                +goog.addDependency("testing/fs/fileentry_test.js", ['goog.testing.fs.FileEntryTest'], ['goog.testing.MockClock', 'goog.testing.fs.FileEntry', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/filereader.js", ['goog.testing.fs.FileReader'], ['goog.Timer', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.testing.fs.ProgressEvent']);
                +goog.addDependency("testing/fs/filereader_test.js", ['goog.testing.fs.FileReaderTest'], ['goog.Promise', 'goog.array', 'goog.events', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.object', 'goog.testing.events.EventObserver', 'goog.testing.fs.FileReader', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/filesystem.js", ['goog.testing.fs.FileSystem'], ['goog.fs.FileSystem', 'goog.testing.fs.DirectoryEntry']);
                +goog.addDependency("testing/fs/filewriter.js", ['goog.testing.fs.FileWriter'], ['goog.Timer', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.string', 'goog.testing.fs.ProgressEvent']);
                +goog.addDependency("testing/fs/filewriter_test.js", ['goog.testing.fs.FileWriterTest'], ['goog.Promise', 'goog.array', 'goog.events', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.object', 'goog.testing.MockClock', 'goog.testing.events.EventObserver', 'goog.testing.fs.Blob', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/fs.js", ['goog.testing.fs'], ['goog.Timer', 'goog.array', 'goog.async.Deferred', 'goog.fs', 'goog.testing.fs.Blob', 'goog.testing.fs.FileSystem']);
                +goog.addDependency("testing/fs/fs_test.js", ['goog.testing.fsTest'], ['goog.testing.fs', 'goog.testing.fs.Blob', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/integration_test.js", ['goog.testing.fs.integrationTest'], ['goog.Promise', 'goog.events', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.testing.PropertyReplacer', 'goog.testing.fs', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/progressevent.js", ['goog.testing.fs.ProgressEvent'], ['goog.events.Event']);
                +goog.addDependency("testing/functionmock.js", ['goog.testing', 'goog.testing.FunctionMock', 'goog.testing.GlobalFunctionMock', 'goog.testing.MethodMock'], ['goog.object', 'goog.testing.LooseMock', 'goog.testing.Mock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock']);
                +goog.addDependency("testing/functionmock_test.js", ['goog.testing.FunctionMockTest'], ['goog.array', 'goog.string', 'goog.testing', 'goog.testing.FunctionMock', 'goog.testing.Mock', 'goog.testing.ObjectPropertyString', 'goog.testing.StrictMock', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/graphics.js", ['goog.testing.graphics'], ['goog.graphics.Path', 'goog.testing.asserts']);
                +goog.addDependency("testing/i18n/asserts.js", ['goog.testing.i18n.asserts'], ['goog.testing.jsunit']);
                +goog.addDependency("testing/i18n/asserts_test.js", ['goog.testing.i18n.assertsTest'], ['goog.testing.ExpectedFailures', 'goog.testing.i18n.asserts']);
                +goog.addDependency("testing/jstdasyncwrapper.js", ['goog.testing.JsTdAsyncWrapper'], ['goog.Promise']);
                +goog.addDependency("testing/jstdtestcaseadapter.js", ['goog.testing.JsTdTestCaseAdapter'], ['goog.async.run', 'goog.functions', 'goog.testing.JsTdAsyncWrapper', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/jsunit.js", ['goog.testing.jsunit'], ['goog.dom.TagName', 'goog.testing.TestCase', 'goog.testing.TestRunner']);
                +goog.addDependency("testing/jsunitexception.js", ['goog.testing.JsUnitException'], ['goog.testing.stacktrace']);
                +goog.addDependency("testing/loosemock.js", ['goog.testing.LooseExpectationCollection', 'goog.testing.LooseMock'], ['goog.array', 'goog.structs.Map', 'goog.testing.Mock']);
                +goog.addDependency("testing/loosemock_test.js", ['goog.testing.LooseMockTest'], ['goog.testing.LooseMock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/messaging/mockmessagechannel.js", ['goog.testing.messaging.MockMessageChannel'], ['goog.messaging.AbstractChannel', 'goog.testing.asserts']);
                +goog.addDependency("testing/messaging/mockmessageevent.js", ['goog.testing.messaging.MockMessageEvent'], ['goog.events.BrowserEvent', 'goog.events.EventType', 'goog.testing.events.Event']);
                +goog.addDependency("testing/messaging/mockmessageport.js", ['goog.testing.messaging.MockMessagePort'], ['goog.events.EventTarget']);
                +goog.addDependency("testing/messaging/mockportnetwork.js", ['goog.testing.messaging.MockPortNetwork'], ['goog.messaging.PortNetwork', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("testing/mock.js", ['goog.testing.Mock', 'goog.testing.MockExpectation'], ['goog.array', 'goog.object', 'goog.testing.JsUnitException', 'goog.testing.MockInterface', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/mock_test.js", ['goog.testing.MockTest'], ['goog.array', 'goog.testing', 'goog.testing.Mock', 'goog.testing.MockControl', 'goog.testing.MockExpectation', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockclassfactory.js", ['goog.testing.MockClassFactory', 'goog.testing.MockClassRecord'], ['goog.array', 'goog.object', 'goog.testing.LooseMock', 'goog.testing.StrictMock', 'goog.testing.TestCase', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/mockclassfactory_test.js", ['fake.BaseClass', 'fake.ChildClass', 'goog.testing.MockClassFactoryTest'], ['goog.testing', 'goog.testing.MockClassFactory', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockclock.js", ['goog.testing.MockClock'], ['goog.Disposable', 'goog.Promise', 'goog.Thenable', 'goog.async.run', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event']);
                +goog.addDependency("testing/mockclock_test.js", ['goog.testing.MockClockTest'], ['goog.Promise', 'goog.Timer', 'goog.events', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/mockcontrol.js", ['goog.testing.MockControl'], ['goog.array', 'goog.testing', 'goog.testing.LooseMock', 'goog.testing.StrictMock']);
                +goog.addDependency("testing/mockcontrol_test.js", ['goog.testing.MockControlTest'], ['goog.testing.Mock', 'goog.testing.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockinterface.js", ['goog.testing.MockInterface'], []);
                +goog.addDependency("testing/mockmatchers.js", ['goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.testing.mockmatchers.IgnoreArgument', 'goog.testing.mockmatchers.InstanceOf', 'goog.testing.mockmatchers.ObjectEquals', 'goog.testing.mockmatchers.RegexpMatch', 'goog.testing.mockmatchers.SaveArgument', 'goog.testing.mockmatchers.TypeOf'], ['goog.array', 'goog.dom', 'goog.testing.asserts']);
                +goog.addDependency("testing/mockmatchers_test.js", ['goog.testing.mockmatchersTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher']);
                +goog.addDependency("testing/mockrandom.js", ['goog.testing.MockRandom'], ['goog.Disposable']);
                +goog.addDependency("testing/mockrandom_test.js", ['goog.testing.MockRandomTest'], ['goog.testing.MockRandom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockrange.js", ['goog.testing.MockRange'], ['goog.dom.AbstractRange', 'goog.testing.LooseMock']);
                +goog.addDependency("testing/mockrange_test.js", ['goog.testing.MockRangeTest'], ['goog.testing.MockRange', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockstorage.js", ['goog.testing.MockStorage'], ['goog.structs.Map']);
                +goog.addDependency("testing/mockstorage_test.js", ['goog.testing.MockStorageTest'], ['goog.testing.MockStorage', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockuseragent.js", ['goog.testing.MockUserAgent'], ['goog.Disposable', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.userAgent']);
                +goog.addDependency("testing/mockuseragent_test.js", ['goog.testing.MockUserAgentTest'], ['goog.dispose', 'goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/multitestrunner.js", ['goog.testing.MultiTestRunner', 'goog.testing.MultiTestRunner.TestFrame'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.functions', 'goog.object', 'goog.string', 'goog.ui.Component', 'goog.ui.ServerChart', 'goog.ui.TableSorter']);
                +goog.addDependency("testing/multitestrunner_test.js", [], []);
                +goog.addDependency("testing/net/mockiframeio.js", ['goog.testing.net.MockIFrameIo'], ['goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.IframeIo', 'goog.testing.TestQueue']);
                +goog.addDependency("testing/net/xhrio.js", ['goog.testing.net.XhrIo'], ['goog.array', 'goog.dom.xml', 'goog.events', 'goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.object', 'goog.structs', 'goog.structs.Map', 'goog.testing.TestQueue', 'goog.uri.utils']);
                +goog.addDependency("testing/net/xhrio_test.js", ['goog.testing.net.XhrIoTest'], ['goog.dom.xml', 'goog.events', 'goog.events.Event', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.testing.MockControl', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.mockmatchers.InstanceOf', 'goog.testing.net.XhrIo']);
                +goog.addDependency("testing/net/xhriopool.js", ['goog.testing.net.XhrIoPool'], ['goog.net.XhrIoPool', 'goog.testing.net.XhrIo']);
                +goog.addDependency("testing/objectpropertystring.js", ['goog.testing.ObjectPropertyString'], []);
                +goog.addDependency("testing/parallel_closure_test_suite.js", [], []);
                +goog.addDependency("testing/parallel_closure_test_suite_test.js", [], []);
                +goog.addDependency("testing/performancetable.js", ['goog.testing.PerformanceTable'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTimer']);
                +goog.addDependency("testing/performancetimer.js", ['goog.testing.PerformanceTimer', 'goog.testing.PerformanceTimer.Task'], ['goog.array', 'goog.async.Deferred', 'goog.math']);
                +goog.addDependency("testing/performancetimer_test.js", ['goog.testing.PerformanceTimerTest'], ['goog.async.Deferred', 'goog.dom', 'goog.math', 'goog.testing.MockClock', 'goog.testing.PerformanceTimer', 'goog.testing.jsunit']);
                +goog.addDependency("testing/propertyreplacer.js", ['goog.testing.PropertyReplacer'], ['goog.testing.ObjectPropertyString', 'goog.userAgent']);
                +goog.addDependency("testing/propertyreplacer_test.js", ['goog.testing.PropertyReplacerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("testing/proto2/proto2.js", ['goog.testing.proto2'], ['goog.proto2.Message', 'goog.proto2.ObjectSerializer', 'goog.testing.asserts']);
                +goog.addDependency("testing/proto2/proto2_test.js", ['goog.testing.proto2Test'], ['goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.proto2', 'proto2.TestAllTypes']);
                +goog.addDependency("testing/pseudorandom.js", ['goog.testing.PseudoRandom'], ['goog.Disposable']);
                +goog.addDependency("testing/pseudorandom_test.js", ['goog.testing.PseudoRandomTest'], ['goog.testing.PseudoRandom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/recordfunction.js", ['goog.testing.FunctionCall', 'goog.testing.recordConstructor', 'goog.testing.recordFunction'], ['goog.testing.asserts']);
                +goog.addDependency("testing/recordfunction_test.js", ['goog.testing.recordFunctionTest'], ['goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordConstructor', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/shardingtestcase.js", ['goog.testing.ShardingTestCase'], ['goog.asserts', 'goog.testing.TestCase']);
                +goog.addDependency("testing/shardingtestcase_test.js", ['goog.testing.ShardingTestCaseTest'], ['goog.testing.ShardingTestCase', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("testing/singleton.js", ['goog.testing.singleton'], []);
                +goog.addDependency("testing/singleton_test.js", ['goog.testing.singletonTest'], ['goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.singleton']);
                +goog.addDependency("testing/stacktrace.js", ['goog.testing.stacktrace', 'goog.testing.stacktrace.Frame'], []);
                +goog.addDependency("testing/stacktrace_test.js", ['goog.testing.stacktraceTest'], ['goog.functions', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.stacktrace', 'goog.testing.stacktrace.Frame', 'goog.userAgent']);
                +goog.addDependency("testing/storage/fakemechanism.js", ['goog.testing.storage.FakeMechanism'], ['goog.storage.mechanism.IterableMechanism', 'goog.structs.Map']);
                +goog.addDependency("testing/strictmock.js", ['goog.testing.StrictMock'], ['goog.array', 'goog.testing.Mock']);
                +goog.addDependency("testing/strictmock_test.js", ['goog.testing.StrictMockTest'], ['goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("testing/style/layoutasserts.js", ['goog.testing.style.layoutasserts'], ['goog.style', 'goog.testing.asserts', 'goog.testing.style']);
                +goog.addDependency("testing/style/layoutasserts_test.js", ['goog.testing.style.layoutassertsTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.style.layoutasserts']);
                +goog.addDependency("testing/style/style.js", ['goog.testing.style'], ['goog.dom', 'goog.math.Rect', 'goog.style']);
                +goog.addDependency("testing/style/style_test.js", ['goog.testing.styleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.jsunit', 'goog.testing.style']);
                +goog.addDependency("testing/testcase.js", ['goog.testing.TestCase', 'goog.testing.TestCase.Error', 'goog.testing.TestCase.Order', 'goog.testing.TestCase.Result', 'goog.testing.TestCase.Test'], ['goog.Promise', 'goog.Thenable', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.json', 'goog.object', 'goog.testing.JsUnitException', 'goog.testing.asserts']);
                +goog.addDependency("testing/testcase_test.js", ['goog.testing.TestCaseTest'], ['goog.Promise', 'goog.Timer', 'goog.functions', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.MethodMock', 'goog.testing.MockRandom', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/testqueue.js", ['goog.testing.TestQueue'], []);
                +goog.addDependency("testing/testrunner.js", ['goog.testing.TestRunner'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.TestCase']);
                +goog.addDependency("testing/testsuite.js", ['goog.testing.testSuite'], ['goog.labs.testing.Environment', 'goog.testing.TestCase']);
                +goog.addDependency("testing/ui/rendererasserts.js", ['goog.testing.ui.rendererasserts'], ['goog.testing.asserts', 'goog.ui.ControlRenderer']);
                +goog.addDependency("testing/ui/rendererasserts_test.js", ['goog.testing.ui.rendererassertsTest'], ['goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.ControlRenderer']);
                +goog.addDependency("testing/ui/rendererharness.js", ['goog.testing.ui.RendererHarness'], ['goog.Disposable', 'goog.dom.NodeType', 'goog.testing.asserts', 'goog.testing.dom']);
                +goog.addDependency("testing/ui/style.js", ['goog.testing.ui.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.testing.asserts']);
                +goog.addDependency("testing/ui/style_test.js", ['goog.testing.ui.styleTest'], ['goog.dom', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.ui.style']);
                +goog.addDependency("timer/timer.js", ['goog.Timer'], ['goog.Promise', 'goog.events.EventTarget']);
                +goog.addDependency("timer/timer_test.js", ['goog.TimerTest'], ['goog.Promise', 'goog.Timer', 'goog.events', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("transpile.js", [], []);
                +goog.addDependency("tweak/entries.js", ['goog.tweak.BaseEntry', 'goog.tweak.BasePrimitiveSetting', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting'], ['goog.array', 'goog.asserts', 'goog.log', 'goog.object']);
                +goog.addDependency("tweak/entries_test.js", ['goog.tweak.BaseEntryTest'], ['goog.testing.MockControl', 'goog.testing.jsunit', 'goog.tweak.testhelpers']);
                +goog.addDependency("tweak/registry.js", ['goog.tweak.Registry'], ['goog.array', 'goog.asserts', 'goog.log', 'goog.string', 'goog.tweak.BasePrimitiveSetting', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting', 'goog.uri.utils']);
                +goog.addDependency("tweak/registry_test.js", ['goog.tweak.RegistryTest'], ['goog.asserts.AssertionError', 'goog.testing.jsunit', 'goog.tweak', 'goog.tweak.testhelpers']);
                +goog.addDependency("tweak/testhelpers.js", ['goog.tweak.testhelpers'], ['goog.tweak', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.Registry', 'goog.tweak.StringSetting']);
                +goog.addDependency("tweak/tweak.js", ['goog.tweak', 'goog.tweak.ConfigParams'], ['goog.asserts', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.Registry', 'goog.tweak.StringSetting']);
                +goog.addDependency("tweak/tweakui.js", ['goog.tweak.EntriesPanel', 'goog.tweak.TweakUi'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.object', 'goog.string.Const', 'goog.style', 'goog.tweak', 'goog.tweak.BaseEntry', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting', 'goog.ui.Zippy', 'goog.userAgent']);
                +goog.addDependency("tweak/tweakui_test.js", ['goog.tweak.TweakUiTest'], ['goog.dom', 'goog.dom.TagName', 'goog.string', 'goog.testing.jsunit', 'goog.tweak', 'goog.tweak.TweakUi', 'goog.tweak.testhelpers']);
                +goog.addDependency("ui/abstractspellchecker.js", ['goog.ui.AbstractSpellChecker', 'goog.ui.AbstractSpellChecker.AsyncResult'], ['goog.a11y.aria', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.selection', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.spell.SpellCheck', 'goog.structs.Set', 'goog.style', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuSeparator', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/ac/ac.js", ['goog.ui.ac'], ['goog.ui.ac.ArrayMatcher', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/ac_test.js", ['goog.ui.acTest'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.classlist', 'goog.dom.selection', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.ac', 'goog.userAgent']);
                +goog.addDependency("ui/ac/arraymatcher.js", ['goog.ui.ac.ArrayMatcher'], ['goog.string']);
                +goog.addDependency("ui/ac/arraymatcher_test.js", ['goog.ui.ac.ArrayMatcherTest'], ['goog.testing.jsunit', 'goog.ui.ac.ArrayMatcher']);
                +goog.addDependency("ui/ac/autocomplete.js", ['goog.ui.ac.AutoComplete', 'goog.ui.ac.AutoComplete.EventType'], ['goog.array', 'goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.object', 'goog.ui.ac.RenderOptions']);
                +goog.addDependency("ui/ac/autocomplete_test.js", ['goog.ui.ac.AutoCompleteTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.string', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.RenderOptions', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/cachingmatcher.js", ['goog.ui.ac.CachingMatcher'], ['goog.array', 'goog.async.Throttle', 'goog.ui.ac.ArrayMatcher', 'goog.ui.ac.RenderOptions']);
                +goog.addDependency("ui/ac/cachingmatcher_test.js", ['goog.ui.ac.CachingMatcherTest'], ['goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.ac.CachingMatcher']);
                +goog.addDependency("ui/ac/inputhandler.js", ['goog.ui.ac.InputHandler'], ['goog.Disposable', 'goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.selection', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/ac/inputhandler_test.js", ['goog.ui.ac.InputHandlerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.selection', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.KeyCodes', 'goog.functions', 'goog.object', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.ac.InputHandler', 'goog.userAgent']);
                +goog.addDependency("ui/ac/remote.js", ['goog.ui.ac.Remote'], ['goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.RemoteArrayMatcher', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/remotearraymatcher.js", ['goog.ui.ac.RemoteArrayMatcher'], ['goog.Disposable', 'goog.Uri', 'goog.events', 'goog.json', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("ui/ac/remotearraymatcher_test.js", ['goog.ui.ac.RemoteArrayMatcherTest'], ['goog.json', 'goog.net.XhrIo', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.ui.ac.RemoteArrayMatcher']);
                +goog.addDependency("ui/ac/renderer.js", ['goog.ui.ac.Renderer', 'goog.ui.ac.Renderer.CustomRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dispose', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOutAndHide', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.string', 'goog.style', 'goog.ui.IdGenerator', 'goog.ui.ac.AutoComplete']);
                +goog.addDependency("ui/ac/renderer_test.js", ['goog.ui.ac.RendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOutAndHide', 'goog.string', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/renderoptions.js", ['goog.ui.ac.RenderOptions'], []);
                +goog.addDependency("ui/ac/richinputhandler.js", ['goog.ui.ac.RichInputHandler'], ['goog.ui.ac.InputHandler']);
                +goog.addDependency("ui/ac/richremote.js", ['goog.ui.ac.RichRemote'], ['goog.ui.ac.AutoComplete', 'goog.ui.ac.Remote', 'goog.ui.ac.Renderer', 'goog.ui.ac.RichInputHandler', 'goog.ui.ac.RichRemoteArrayMatcher']);
                +goog.addDependency("ui/ac/richremotearraymatcher.js", ['goog.ui.ac.RichRemoteArrayMatcher'], ['goog.dom', 'goog.ui.ac.RemoteArrayMatcher']);
                +goog.addDependency("ui/activitymonitor.js", ['goog.ui.ActivityMonitor'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("ui/activitymonitor_test.js", ['goog.ui.ActivityMonitorTest'], ['goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/advancedtooltip.js", ['goog.ui.AdvancedTooltip'], ['goog.events', 'goog.events.EventType', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/advancedtooltip_test.js", ['goog.ui.AdvancedTooltipTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventType', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.AdvancedTooltip', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/animatedzippy.js", ['goog.ui.AnimatedZippy'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.easing', 'goog.ui.Zippy', 'goog.ui.ZippyEvent']);
                +goog.addDependency("ui/animatedzippy_test.js", ['goog.ui.AnimatedZippyTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events', 'goog.functions', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.ui.AnimatedZippy', 'goog.ui.Zippy']);
                +goog.addDependency("ui/attachablemenu.js", ['goog.ui.AttachableMenu'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.string', 'goog.style', 'goog.ui.ItemEvent', 'goog.ui.MenuBase', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/bidiinput.js", ['goog.ui.BidiInput'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.InputHandler', 'goog.i18n.bidi', 'goog.ui.Component']);
                +goog.addDependency("ui/bidiinput_test.js", ['goog.ui.BidiInputTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.BidiInput']);
                +goog.addDependency("ui/bubble.js", ['goog.ui.Bubble'], ['goog.Timer', 'goog.dom.safe', 'goog.events', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.math.Box', 'goog.positioning', 'goog.positioning.AbsolutePosition', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.CornerBit', 'goog.string.Const', 'goog.style', 'goog.ui.Component', 'goog.ui.Popup']);
                +goog.addDependency("ui/button.js", ['goog.ui.Button', 'goog.ui.Button.Side'], ['goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.NativeButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/button_test.js", ['goog.ui.ButtonTest'], ['goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.NativeButtonRenderer']);
                +goog.addDependency("ui/buttonrenderer.js", ['goog.ui.ButtonRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/buttonrenderer_test.js", ['goog.ui.ButtonRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/buttonside.js", ['goog.ui.ButtonSide'], []);
                +goog.addDependency("ui/charcounter.js", ['goog.ui.CharCounter', 'goog.ui.CharCounter.Display'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.InputHandler']);
                +goog.addDependency("ui/charcounter_test.js", ['goog.ui.CharCounterTest'], ['goog.dom', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.ui.CharCounter', 'goog.userAgent']);
                +goog.addDependency("ui/charpicker.js", ['goog.ui.CharPicker'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.i18n.CharListDecompressor', 'goog.i18n.CharPickerData', 'goog.i18n.uChar', 'goog.i18n.uChar.NameFetcher', 'goog.structs.Set', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.ContainerScroller', 'goog.ui.FlatButtonRenderer', 'goog.ui.HoverCard', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.Tooltip']);
                +goog.addDependency("ui/charpicker_test.js", ['goog.ui.CharPickerTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dispose', 'goog.dom', 'goog.events.Event', 'goog.events.EventType', 'goog.i18n.CharPickerData', 'goog.i18n.uChar.NameFetcher', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.CharPicker', 'goog.ui.FlatButtonRenderer']);
                +goog.addDependency("ui/checkbox.js", ['goog.ui.Checkbox', 'goog.ui.Checkbox.State'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.string', 'goog.ui.CheckboxRenderer', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.registry']);
                +goog.addDependency("ui/checkbox_test.js", ['goog.ui.CheckboxTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Checkbox', 'goog.ui.CheckboxRenderer', 'goog.ui.Component', 'goog.ui.ControlRenderer', 'goog.ui.decorate']);
                +goog.addDependency("ui/checkboxmenuitem.js", ['goog.ui.CheckBoxMenuItem'], ['goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/checkboxrenderer.js", ['goog.ui.CheckboxRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/colormenubutton.js", ['goog.ui.ColorMenuButton'], ['goog.array', 'goog.object', 'goog.ui.ColorMenuButtonRenderer', 'goog.ui.ColorPalette', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.registry']);
                +goog.addDependency("ui/colormenubuttonrenderer.js", ['goog.ui.ColorMenuButtonRenderer'], ['goog.asserts', 'goog.color', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.MenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/colormenubuttonrenderer_test.js", ['goog.ui.ColorMenuButtonTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.testing.ui.RendererHarness', 'goog.testing.ui.rendererasserts', 'goog.ui.ColorMenuButton', 'goog.ui.ColorMenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/colorpalette.js", ['goog.ui.ColorPalette'], ['goog.array', 'goog.color', 'goog.dom.TagName', 'goog.style', 'goog.ui.Palette', 'goog.ui.PaletteRenderer']);
                +goog.addDependency("ui/colorpalette_test.js", ['goog.ui.ColorPaletteTest'], ['goog.color', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.ColorPalette']);
                +goog.addDependency("ui/colorpicker.js", ['goog.ui.ColorPicker', 'goog.ui.ColorPicker.EventType'], ['goog.ui.ColorPalette', 'goog.ui.Component']);
                +goog.addDependency("ui/combobox.js", ['goog.ui.ComboBox', 'goog.ui.ComboBoxItem'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.log', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.ItemEvent', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.MenuSeparator', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/combobox_test.js", ['goog.ui.ComboBoxTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ComboBox', 'goog.ui.ComboBoxItem', 'goog.ui.Component', 'goog.ui.ControlRenderer', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuItem']);
                +goog.addDependency("ui/component.js", ['goog.ui.Component', 'goog.ui.Component.Error', 'goog.ui.Component.EventType', 'goog.ui.Component.State'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.object', 'goog.style', 'goog.ui.IdGenerator']);
                +goog.addDependency("ui/component_test.js", ['goog.ui.ComponentTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.events.EventTarget', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component']);
                +goog.addDependency("ui/container.js", ['goog.ui.Container', 'goog.ui.Container.EventType', 'goog.ui.Container.Orientation'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.object', 'goog.style', 'goog.ui.Component', 'goog.ui.ContainerRenderer', 'goog.ui.Control']);
                +goog.addDependency("ui/container_test.js", ['goog.ui.ContainerTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.events.KeyEvent', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Control']);
                +goog.addDependency("ui/containerrenderer.js", ['goog.ui.ContainerRenderer'], ['goog.a11y.aria', 'goog.array', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.style', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/containerrenderer_test.js", ['goog.ui.ContainerRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Container', 'goog.ui.ContainerRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/containerscroller.js", ['goog.ui.ContainerScroller'], ['goog.Disposable', 'goog.Timer', 'goog.events.EventHandler', 'goog.style', 'goog.ui.Component', 'goog.ui.Container']);
                +goog.addDependency("ui/containerscroller_test.js", ['goog.ui.ContainerScrollerTest'], ['goog.dom', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Container', 'goog.ui.ContainerScroller']);
                +goog.addDependency("ui/control.js", ['goog.ui.Control'], ['goog.Disposable', 'goog.array', 'goog.dom', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.string', 'goog.ui.Component', 'goog.ui.ControlContent', 'goog.ui.ControlRenderer', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/control_test.js", ['goog.ui.ControlTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.html.testing', 'goog.object', 'goog.string', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/controlcontent.js", ['goog.ui.ControlContent'], []);
                +goog.addDependency("ui/controlrenderer.js", ['goog.ui.ControlRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/controlrenderer_test.js", ['goog.ui.ControlRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/cookieeditor.js", ['goog.ui.CookieEditor'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventType', 'goog.net.cookies', 'goog.string', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("ui/cookieeditor_test.js", ['goog.ui.CookieEditorTest'], ['goog.dom', 'goog.events.Event', 'goog.events.EventType', 'goog.net.cookies', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.CookieEditor']);
                +goog.addDependency("ui/css3buttonrenderer.js", ['goog.ui.Css3ButtonRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.Component', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/css3menubuttonrenderer.js", ['goog.ui.Css3MenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/cssnames.js", ['goog.ui.INLINE_BLOCK_CLASSNAME'], []);
                +goog.addDependency("ui/custombutton.js", ['goog.ui.CustomButton'], ['goog.ui.Button', 'goog.ui.CustomButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/custombuttonrenderer.js", ['goog.ui.CustomButtonRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.ui.ButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME']);
                +goog.addDependency("ui/customcolorpalette.js", ['goog.ui.CustomColorPalette'], ['goog.color', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.ColorPalette', 'goog.ui.Component']);
                +goog.addDependency("ui/customcolorpalette_test.js", ['goog.ui.CustomColorPaletteTest'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.ui.CustomColorPalette']);
                +goog.addDependency("ui/datepicker.js", ['goog.ui.DatePicker', 'goog.ui.DatePicker.Events', 'goog.ui.DatePickerEvent'], ['goog.a11y.aria', 'goog.asserts', 'goog.date.Date', 'goog.date.DateRange', 'goog.date.Interval', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyHandler', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns', 'goog.i18n.DateTimeSymbols', 'goog.style', 'goog.ui.Component', 'goog.ui.DefaultDatePickerRenderer', 'goog.ui.IdGenerator']);
                +goog.addDependency("ui/datepicker_test.js", ['goog.ui.DatePickerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.date.Date', 'goog.date.DateRange', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_zh_HK', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.DatePicker']);
                +goog.addDependency("ui/datepickerrenderer.js", ['goog.ui.DatePickerRenderer'], []);
                +goog.addDependency("ui/decorate.js", ['goog.ui.decorate'], ['goog.ui.registry']);
                +goog.addDependency("ui/decorate_test.js", ['goog.ui.decorateTest'], ['goog.testing.jsunit', 'goog.ui.decorate', 'goog.ui.registry']);
                +goog.addDependency("ui/defaultdatepickerrenderer.js", ['goog.ui.DefaultDatePickerRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.DatePickerRenderer']);
                +goog.addDependency("ui/dialog.js", ['goog.ui.Dialog', 'goog.ui.Dialog.ButtonSet', 'goog.ui.Dialog.ButtonSet.DefaultButtons', 'goog.ui.Dialog.DefaultButtonCaptions', 'goog.ui.Dialog.DefaultButtonKeys', 'goog.ui.Dialog.Event', 'goog.ui.Dialog.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.safe', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Dragger', 'goog.html.SafeHtml', 'goog.math.Rect', 'goog.string', 'goog.structs.Map', 'goog.style', 'goog.ui.ModalPopup']);
                +goog.addDependency("ui/dialog_test.js", ['goog.ui.DialogTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.css3', 'goog.html.SafeHtml', 'goog.html.testing', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Dialog', 'goog.userAgent']);
                +goog.addDependency("ui/dimensionpicker.js", ['goog.ui.DimensionPicker'], ['goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.DimensionPickerRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/dimensionpicker_test.js", ['goog.ui.DimensionPickerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.DimensionPicker', 'goog.ui.DimensionPickerRenderer']);
                +goog.addDependency("ui/dimensionpickerrenderer.js", ['goog.ui.DimensionPickerRenderer'], ['goog.a11y.aria.Announcer', 'goog.a11y.aria.LivePriority', 'goog.dom', 'goog.dom.TagName', 'goog.i18n.bidi', 'goog.style', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/dimensionpickerrenderer_test.js", ['goog.ui.DimensionPickerRendererTest'], ['goog.a11y.aria.LivePriority', 'goog.array', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.DimensionPicker', 'goog.ui.DimensionPickerRenderer']);
                +goog.addDependency("ui/dragdropdetector.js", ['goog.ui.DragDropDetector', 'goog.ui.DragDropDetector.EventType', 'goog.ui.DragDropDetector.ImageDropEvent', 'goog.ui.DragDropDetector.LinkDropEvent'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("ui/drilldownrow.js", ['goog.ui.DrilldownRow'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.string.Unicode', 'goog.ui.Component']);
                +goog.addDependency("ui/drilldownrow_test.js", ['goog.ui.DrilldownRowTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.SafeHtml', 'goog.testing.jsunit', 'goog.ui.DrilldownRow']);
                +goog.addDependency("ui/editor/abstractdialog.js", ['goog.ui.editor.AbstractDialog', 'goog.ui.editor.AbstractDialog.Builder', 'goog.ui.editor.AbstractDialog.EventType'], ['goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventTarget', 'goog.string', 'goog.ui.Dialog', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/editor/abstractdialog_test.js", ['goog.ui.editor.AbstractDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.KeyCodes', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.userAgent']);
                +goog.addDependency("ui/editor/bubble.js", ['goog.ui.editor.Bubble'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.ViewportSizeMonitor', 'goog.dom.classlist', 'goog.editor.style', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.functions', 'goog.log', 'goog.math.Box', 'goog.object', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/editor/bubble_test.js", ['goog.ui.editor.BubbleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.positioning.Corner', 'goog.positioning.OverflowStatus', 'goog.string', 'goog.style', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.editor.Bubble', 'goog.userAgent.product']);
                +goog.addDependency("ui/editor/defaulttoolbar.js", ['goog.ui.editor.ButtonDescriptor', 'goog.ui.editor.DefaultToolbar'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.Command', 'goog.style', 'goog.ui.editor.ToolbarFactory', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("ui/editor/linkdialog.js", ['goog.ui.editor.LinkDialog', 'goog.ui.editor.LinkDialog.BeforeTestLinkEvent', 'goog.ui.editor.LinkDialog.EventType', 'goog.ui.editor.LinkDialog.OkEvent'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.editor.BrowserFeature', 'goog.editor.Link', 'goog.editor.focus', 'goog.editor.node', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.InputHandler', 'goog.html.SafeHtml', 'goog.html.SafeHtmlFormatter', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.LinkButtonRenderer', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.TabPane', 'goog.ui.editor.messages', 'goog.userAgent', 'goog.window']);
                +goog.addDependency("ui/editor/linkdialog_test.js", ['goog.ui.editor.LinkDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Link', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("ui/editor/messages.js", ['goog.ui.editor.messages'], ['goog.html.uncheckedconversions', 'goog.string.Const']);
                +goog.addDependency("ui/editor/tabpane.js", ['goog.ui.editor.TabPane'], ['goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.Tab', 'goog.ui.TabBar']);
                +goog.addDependency("ui/editor/toolbarcontroller.js", ['goog.ui.editor.ToolbarController'], ['goog.editor.Field', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.ui.Component']);
                +goog.addDependency("ui/editor/toolbarfactory.js", ['goog.ui.editor.ToolbarFactory'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Option', 'goog.ui.Toolbar', 'goog.ui.ToolbarButton', 'goog.ui.ToolbarColorMenuButton', 'goog.ui.ToolbarMenuButton', 'goog.ui.ToolbarRenderer', 'goog.ui.ToolbarSelect', 'goog.userAgent']);
                +goog.addDependency("ui/editor/toolbarfactory_test.js", ['goog.ui.editor.ToolbarFactoryTest'], ['goog.dom', 'goog.testing.ExpectedFailures', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.ui.editor.ToolbarFactory', 'goog.userAgent']);
                +goog.addDependency("ui/emoji/emoji.js", ['goog.ui.emoji.Emoji'], []);
                +goog.addDependency("ui/emoji/emojipalette.js", ['goog.ui.emoji.EmojiPalette'], ['goog.events.EventType', 'goog.net.ImageLoader', 'goog.ui.Palette', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/emojipaletterenderer.js", ['goog.ui.emoji.EmojiPaletteRenderer'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.style', 'goog.ui.PaletteRenderer', 'goog.ui.emoji.Emoji']);
                +goog.addDependency("ui/emoji/emojipicker.js", ['goog.ui.emoji.EmojiPicker'], ['goog.dom.TagName', 'goog.style', 'goog.ui.Component', 'goog.ui.TabPane', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPalette', 'goog.ui.emoji.EmojiPaletteRenderer', 'goog.ui.emoji.ProgressiveEmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/emojipicker_test.js", ['goog.ui.emoji.EmojiPickerTest'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/fast_nonprogressive_emojipicker_test.js", ['goog.ui.emoji.FastNonProgressiveEmojiPickerTest'], ['goog.Promise', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.net.EventType', 'goog.style', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/fast_progressive_emojipicker_test.js", ['goog.ui.emoji.FastProgressiveEmojiPickerTest'], ['goog.Promise', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.net.EventType', 'goog.style', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/popupemojipicker.js", ['goog.ui.emoji.PopupEmojiPicker'], ['goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.ui.Component', 'goog.ui.Popup', 'goog.ui.emoji.EmojiPicker']);
                +goog.addDependency("ui/emoji/popupemojipicker_test.js", ['goog.ui.emoji.PopupEmojiPickerTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.emoji.PopupEmojiPicker']);
                +goog.addDependency("ui/emoji/progressiveemojipaletterenderer.js", ['goog.ui.emoji.ProgressiveEmojiPaletteRenderer'], ['goog.dom.TagName', 'goog.style', 'goog.ui.emoji.EmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/spriteinfo.js", ['goog.ui.emoji.SpriteInfo'], []);
                +goog.addDependency("ui/emoji/spriteinfo_test.js", ['goog.ui.emoji.SpriteInfoTest'], ['goog.testing.jsunit', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/filteredmenu.js", ['goog.ui.FilteredMenu'], ['goog.a11y.aria', 'goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.object', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.FilterObservingMenuItem', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.userAgent']);
                +goog.addDependency("ui/filteredmenu_test.js", ['goog.ui.FilteredMenuTest'], ['goog.a11y.aria', 'goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Rect', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.FilteredMenu', 'goog.ui.MenuItem']);
                +goog.addDependency("ui/filterobservingmenuitem.js", ['goog.ui.FilterObservingMenuItem'], ['goog.ui.FilterObservingMenuItemRenderer', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/filterobservingmenuitemrenderer.js", ['goog.ui.FilterObservingMenuItemRenderer'], ['goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/flatbuttonrenderer.js", ['goog.ui.FlatButtonRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/flatmenubuttonrenderer.js", ['goog.ui.FlatMenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.FlatButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/formpost.js", ['goog.ui.FormPost'], ['goog.array', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.ui.Component']);
                +goog.addDependency("ui/formpost_test.js", ['goog.ui.FormPostTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.object', 'goog.testing.jsunit', 'goog.ui.FormPost', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("ui/gauge.js", ['goog.ui.Gauge', 'goog.ui.GaugeColoredRange'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.TagName', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.easing', 'goog.graphics', 'goog.graphics.Font', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.math', 'goog.ui.Component', 'goog.ui.GaugeTheme']);
                +goog.addDependency("ui/gaugetheme.js", ['goog.ui.GaugeTheme'], ['goog.graphics.LinearGradient', 'goog.graphics.SolidFill', 'goog.graphics.Stroke']);
                +goog.addDependency("ui/hovercard.js", ['goog.ui.HoverCard', 'goog.ui.HoverCard.EventType', 'goog.ui.HoverCard.TriggerEvent'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.ui.AdvancedTooltip', 'goog.ui.PopupBase', 'goog.ui.Tooltip']);
                +goog.addDependency("ui/hovercard_test.js", ['goog.ui.HoverCardTest'], ['goog.dom', 'goog.events', 'goog.math.Coordinate', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.HoverCard']);
                +goog.addDependency("ui/hsvapalette.js", ['goog.ui.HsvaPalette'], ['goog.array', 'goog.color.alpha', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.HsvPalette']);
                +goog.addDependency("ui/hsvapalette_test.js", ['goog.ui.HsvaPaletteTest'], ['goog.color.alpha', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.math.Coordinate', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.HsvaPalette', 'goog.userAgent']);
                +goog.addDependency("ui/hsvpalette.js", ['goog.ui.HsvPalette'], ['goog.color', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.style', 'goog.style.bidi', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/hsvpalette_test.js", ['goog.ui.HsvPaletteTest'], ['goog.color', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.math.Coordinate', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.HsvPalette', 'goog.userAgent']);
                +goog.addDependency("ui/idgenerator.js", ['goog.ui.IdGenerator'], []);
                +goog.addDependency("ui/idletimer.js", ['goog.ui.IdleTimer'], ['goog.Timer', 'goog.events', 'goog.events.EventTarget', 'goog.structs.Set', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/idletimer_test.js", ['goog.ui.IdleTimerTest'], ['goog.events', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.IdleTimer', 'goog.ui.MockActivityMonitor']);
                +goog.addDependency("ui/iframemask.js", ['goog.ui.IframeMask'], ['goog.Disposable', 'goog.Timer', 'goog.dom', 'goog.dom.iframe', 'goog.events.EventHandler', 'goog.structs.Pool', 'goog.style']);
                +goog.addDependency("ui/iframemask_test.js", ['goog.ui.IframeMaskTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.iframe', 'goog.structs.Pool', 'goog.style', 'goog.testing.MockClock', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.ui.IframeMask', 'goog.ui.Popup', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/imagelessbuttonrenderer.js", ['goog.ui.ImagelessButtonRenderer'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/imagelessmenubuttonrenderer.js", ['goog.ui.ImagelessMenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/inputdatepicker.js", ['goog.ui.InputDatePicker'], ['goog.date.DateTime', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.i18n.DateTimeParse', 'goog.string', 'goog.ui.Component', 'goog.ui.DatePicker', 'goog.ui.LabelInput', 'goog.ui.PopupBase', 'goog.ui.PopupDatePicker']);
                +goog.addDependency("ui/inputdatepicker_test.js", ['goog.ui.InputDatePickerTest'], ['goog.dom', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeParse', 'goog.testing.jsunit', 'goog.ui.InputDatePicker']);
                +goog.addDependency("ui/itemevent.js", ['goog.ui.ItemEvent'], ['goog.events.Event']);
                +goog.addDependency("ui/keyboardshortcuthandler.js", ['goog.ui.KeyboardShortcutEvent', 'goog.ui.KeyboardShortcutHandler', 'goog.ui.KeyboardShortcutHandler.EventType', 'goog.ui.KeyboardShortcutHandler.Modifiers'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyNames', 'goog.events.Keys', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("ui/keyboardshortcuthandler_test.js", ['goog.ui.KeyboardShortcutHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.KeyboardShortcutHandler', 'goog.userAgent']);
                +goog.addDependency("ui/labelinput.js", ['goog.ui.LabelInput'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/labelinput_test.js", ['goog.ui.LabelInputTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventType', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.LabelInput', 'goog.userAgent']);
                +goog.addDependency("ui/linkbuttonrenderer.js", ['goog.ui.LinkButtonRenderer'], ['goog.ui.Button', 'goog.ui.FlatButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/media/flashobject.js", ['goog.ui.media.FlashObject', 'goog.ui.media.FlashObject.ScriptAccessLevel', 'goog.ui.media.FlashObject.Wmodes'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.log', 'goog.object', 'goog.string', 'goog.structs.Map', 'goog.style', 'goog.ui.Component', 'goog.userAgent', 'goog.userAgent.flash']);
                +goog.addDependency("ui/media/flashobject_test.js", ['goog.ui.media.FlashObjectTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.html.testing', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.userAgent']);
                +goog.addDependency("ui/media/flickr.js", ['goog.ui.media.FlickrSet', 'goog.ui.media.FlickrSetModel'], ['goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/flickr_test.js", ['goog.ui.media.FlickrSetTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.FlickrSet', 'goog.ui.media.FlickrSetModel', 'goog.ui.media.Media']);
                +goog.addDependency("ui/media/googlevideo.js", ['goog.ui.media.GoogleVideo', 'goog.ui.media.GoogleVideoModel'], ['goog.html.uncheckedconversions', 'goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/googlevideo_test.js", ['goog.ui.media.GoogleVideoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.GoogleVideo', 'goog.ui.media.GoogleVideoModel', 'goog.ui.media.Media']);
                +goog.addDependency("ui/media/media.js", ['goog.ui.media.Media', 'goog.ui.media.MediaRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.style', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/media/media_test.js", ['goog.ui.media.MediaTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.math.Size', 'goog.testing.jsunit', 'goog.ui.ControlRenderer', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/mediamodel.js", ['goog.ui.media.MediaModel', 'goog.ui.media.MediaModel.Category', 'goog.ui.media.MediaModel.Credit', 'goog.ui.media.MediaModel.Credit.Role', 'goog.ui.media.MediaModel.Credit.Scheme', 'goog.ui.media.MediaModel.Medium', 'goog.ui.media.MediaModel.MimeType', 'goog.ui.media.MediaModel.Player', 'goog.ui.media.MediaModel.SubTitle', 'goog.ui.media.MediaModel.Thumbnail'], ['goog.array', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("ui/media/mediamodel_test.js", ['goog.ui.media.MediaModelTest'], ['goog.testing.jsunit', 'goog.ui.media.MediaModel']);
                +goog.addDependency("ui/media/mp3.js", ['goog.ui.media.Mp3'], ['goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/mp3_test.js", ['goog.ui.media.Mp3Test'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.Mp3']);
                +goog.addDependency("ui/media/photo.js", ['goog.ui.media.Photo'], ['goog.dom.TagName', 'goog.ui.media.Media', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/photo_test.js", ['goog.ui.media.PhotoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.MediaModel', 'goog.ui.media.Photo']);
                +goog.addDependency("ui/media/picasa.js", ['goog.ui.media.PicasaAlbum', 'goog.ui.media.PicasaAlbumModel'], ['goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/picasa_test.js", ['goog.ui.media.PicasaTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.PicasaAlbum', 'goog.ui.media.PicasaAlbumModel']);
                +goog.addDependency("ui/media/vimeo.js", ['goog.ui.media.Vimeo', 'goog.ui.media.VimeoModel'], ['goog.html.uncheckedconversions', 'goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/vimeo_test.js", ['goog.ui.media.VimeoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.Vimeo', 'goog.ui.media.VimeoModel']);
                +goog.addDependency("ui/media/youtube.js", ['goog.ui.media.Youtube', 'goog.ui.media.YoutubeModel'], ['goog.dom.TagName', 'goog.html.uncheckedconversions', 'goog.string', 'goog.ui.Component', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/youtube_test.js", ['goog.ui.media.YoutubeTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Youtube', 'goog.ui.media.YoutubeModel']);
                +goog.addDependency("ui/menu.js", ['goog.ui.Menu', 'goog.ui.Menu.EventType'], ['goog.dom.TagName', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.ui.Component.EventType', 'goog.ui.Component.State', 'goog.ui.Container', 'goog.ui.Container.Orientation', 'goog.ui.MenuHeader', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.MenuSeparator']);
                +goog.addDependency("ui/menu_test.js", ['goog.ui.MenuTest'], ['goog.dom', 'goog.events', 'goog.math.Coordinate', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Menu']);
                +goog.addDependency("ui/menubar.js", ['goog.ui.menuBar'], ['goog.ui.Container', 'goog.ui.MenuBarRenderer']);
                +goog.addDependency("ui/menubardecorator.js", ['goog.ui.menuBarDecorator'], ['goog.ui.MenuBarRenderer', 'goog.ui.menuBar', 'goog.ui.registry']);
                +goog.addDependency("ui/menubarrenderer.js", ['goog.ui.MenuBarRenderer'], ['goog.a11y.aria.Role', 'goog.ui.Container', 'goog.ui.ContainerRenderer']);
                +goog.addDependency("ui/menubase.js", ['goog.ui.MenuBase'], ['goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyHandler', 'goog.ui.Popup']);
                +goog.addDependency("ui/menubutton.js", ['goog.ui.MenuButton'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.math.Box', 'goog.math.Rect', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.IdGenerator', 'goog.ui.Menu', 'goog.ui.MenuButtonRenderer', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.registry', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/menubutton_test.js", ['goog.ui.MenuButtonTest'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.SubMenu', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("ui/menubuttonrenderer.js", ['goog.ui.MenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.Menu', 'goog.ui.MenuRenderer']);
                +goog.addDependency("ui/menubuttonrenderer_test.js", ['goog.ui.MenuButtonRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/menuheader.js", ['goog.ui.MenuHeader'], ['goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuHeaderRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/menuheaderrenderer.js", ['goog.ui.MenuHeaderRenderer'], ['goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuitem.js", ['goog.ui.MenuItem'], ['goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.classlist', 'goog.math.Coordinate', 'goog.string', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuItemRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/menuitem_test.js", ['goog.ui.MenuItemTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.html.testing', 'goog.math.Coordinate', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/menuitemrenderer.js", ['goog.ui.MenuItemRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuitemrenderer_test.js", ['goog.ui.MenuItemRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/menurenderer.js", ['goog.ui.MenuRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.ui.ContainerRenderer', 'goog.ui.Separator']);
                +goog.addDependency("ui/menuseparator.js", ['goog.ui.MenuSeparator'], ['goog.ui.MenuSeparatorRenderer', 'goog.ui.Separator', 'goog.ui.registry']);
                +goog.addDependency("ui/menuseparatorrenderer.js", ['goog.ui.MenuSeparatorRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuseparatorrenderer_test.js", ['goog.ui.MenuSeparatorRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.MenuSeparator', 'goog.ui.MenuSeparatorRenderer']);
                +goog.addDependency("ui/mockactivitymonitor.js", ['goog.ui.MockActivityMonitor'], ['goog.events.EventType', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/mockactivitymonitor_test.js", ['goog.ui.MockActivityMonitorTest'], ['goog.events', 'goog.functions', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.ActivityMonitor', 'goog.ui.MockActivityMonitor']);
                +goog.addDependency("ui/modalariavisibilityhelper.js", ['goog.ui.ModalAriaVisibilityHelper'], ['goog.a11y.aria', 'goog.a11y.aria.State']);
                +goog.addDependency("ui/modalariavisibilityhelper_test.js", ['goog.ui.ModalAriaVisibilityHelperTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.string', 'goog.testing.jsunit', 'goog.ui.ModalAriaVisibilityHelper']);
                +goog.addDependency("ui/modalpopup.js", ['goog.ui.ModalPopup'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.animationFrame', 'goog.dom.classlist', 'goog.dom.iframe', 'goog.events', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.fx.Transition', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.ModalAriaVisibilityHelper', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/modalpopup_test.js", ['goog.ui.ModalPopupTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Transition', 'goog.fx.css3', 'goog.string', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ModalPopup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/nativebuttonrenderer.js", ['goog.ui.NativeButtonRenderer'], ['goog.asserts', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.ui.ButtonRenderer', 'goog.ui.Component']);
                +goog.addDependency("ui/nativebuttonrenderer_test.js", ['goog.ui.NativeButtonRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.testing.ExpectedFailures', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.NativeButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/option.js", ['goog.ui.Option'], ['goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/palette.js", ['goog.ui.Palette'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.PaletteRenderer', 'goog.ui.SelectionModel']);
                +goog.addDependency("ui/palette_test.js", ['goog.ui.PaletteTest'], ['goog.a11y.aria', 'goog.dom', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyEvent', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Palette']);
                +goog.addDependency("ui/paletterenderer.js", ['goog.ui.PaletteRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeIterator', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.iter', 'goog.style', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/paletterenderer_test.js", ['goog.ui.PaletteRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.Palette', 'goog.ui.PaletteRenderer']);
                +goog.addDependency("ui/plaintextspellchecker.js", ['goog.ui.PlainTextSpellChecker'], ['goog.Timer', 'goog.a11y.aria', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.spell.SpellCheck', 'goog.style', 'goog.ui.AbstractSpellChecker', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/plaintextspellchecker_test.js", ['goog.ui.PlainTextSpellCheckerTest'], ['goog.Timer', 'goog.dom', 'goog.events.KeyCodes', 'goog.spell.SpellCheck', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.PlainTextSpellChecker']);
                +goog.addDependency("ui/popup.js", ['goog.ui.Popup'], ['goog.math.Box', 'goog.positioning.AbstractPosition', 'goog.positioning.Corner', 'goog.style', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popup_test.js", ['goog.ui.PopupTest'], ['goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.style', 'goog.testing.jsunit', 'goog.ui.Popup', 'goog.userAgent']);
                +goog.addDependency("ui/popupbase.js", ['goog.ui.PopupBase', 'goog.ui.PopupBase.EventType', 'goog.ui.PopupBase.Type'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Transition', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("ui/popupbase_test.js", ['goog.ui.PopupBaseTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Transition', 'goog.fx.css3', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupcolorpicker.js", ['goog.ui.PopupColorPicker'], ['goog.asserts', 'goog.dom.classlist', 'goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.ui.ColorPicker', 'goog.ui.Component', 'goog.ui.Popup']);
                +goog.addDependency("ui/popupcolorpicker_test.js", ['goog.ui.PopupColorPickerTest'], ['goog.dom', 'goog.events', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ColorPicker', 'goog.ui.PopupColorPicker']);
                +goog.addDependency("ui/popupdatepicker.js", ['goog.ui.PopupDatePicker'], ['goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.style', 'goog.ui.Component', 'goog.ui.DatePicker', 'goog.ui.Popup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupdatepicker_test.js", ['goog.ui.PopupDatePickerTest'], ['goog.date.Date', 'goog.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.PopupBase', 'goog.ui.PopupDatePicker']);
                +goog.addDependency("ui/popupmenu.js", ['goog.ui.PopupMenu'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.positioning.ViewportClientPosition', 'goog.structs.Map', 'goog.style', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupmenu_test.js", ['goog.ui.PopupMenuTest'], ['goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Box', 'goog.math.Coordinate', 'goog.positioning.Corner', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/progressbar.js", ['goog.ui.ProgressBar', 'goog.ui.ProgressBar.Orientation'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.ui.Component', 'goog.ui.RangeModel', 'goog.userAgent']);
                +goog.addDependency("ui/prompt.js", ['goog.ui.Prompt'], ['goog.Timer', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.functions', 'goog.html.SafeHtml', 'goog.ui.Component', 'goog.ui.Dialog', 'goog.userAgent']);
                +goog.addDependency("ui/prompt_test.js", ['goog.ui.PromptTest'], ['goog.dom.selection', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.functions', 'goog.string', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.BidiInput', 'goog.ui.Dialog', 'goog.ui.Prompt', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/rangemodel.js", ['goog.ui.RangeModel'], ['goog.events.EventTarget', 'goog.ui.Component']);
                +goog.addDependency("ui/rangemodel_test.js", ['goog.ui.RangeModelTest'], ['goog.testing.jsunit', 'goog.ui.RangeModel']);
                +goog.addDependency("ui/ratings.js", ['goog.ui.Ratings', 'goog.ui.Ratings.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.ui.Component']);
                +goog.addDependency("ui/registry.js", ['goog.ui.registry'], ['goog.asserts', 'goog.dom.classlist']);
                +goog.addDependency("ui/registry_test.js", ['goog.ui.registryTest'], ['goog.object', 'goog.testing.jsunit', 'goog.ui.registry']);
                +goog.addDependency("ui/richtextspellchecker.js", ['goog.ui.RichTextSpellChecker'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.math.Coordinate', 'goog.spell.SpellCheck', 'goog.string.StringBuffer', 'goog.style', 'goog.ui.AbstractSpellChecker', 'goog.ui.Component', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/richtextspellchecker_test.js", ['goog.ui.RichTextSpellCheckerTest'], ['goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.object', 'goog.spell.SpellCheck', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.RichTextSpellChecker']);
                +goog.addDependency("ui/roundedpanel.js", ['goog.ui.BaseRoundedPanel', 'goog.ui.CssRoundedPanel', 'goog.ui.GraphicsRoundedPanel', 'goog.ui.RoundedPanel', 'goog.ui.RoundedPanel.Corner'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.graphics', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.math', 'goog.math.Coordinate', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/roundedpanel_test.js", ['goog.ui.RoundedPanelTest'], ['goog.testing.jsunit', 'goog.ui.CssRoundedPanel', 'goog.ui.GraphicsRoundedPanel', 'goog.ui.RoundedPanel', 'goog.userAgent']);
                +goog.addDependency("ui/roundedtabrenderer.js", ['goog.ui.RoundedTabRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.Tab', 'goog.ui.TabBar', 'goog.ui.TabRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/scrollfloater.js", ['goog.ui.ScrollFloater', 'goog.ui.ScrollFloater.EventType'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/scrollfloater_test.js", ['goog.ui.ScrollFloaterTest'], ['goog.dom', 'goog.events', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.ScrollFloater']);
                +goog.addDependency("ui/select.js", ['goog.ui.Select'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.events.EventType', 'goog.ui.Component', 'goog.ui.IdGenerator', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.SelectionModel', 'goog.ui.registry']);
                +goog.addDependency("ui/select_test.js", ['goog.ui.SelectTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.Select', 'goog.ui.Separator']);
                +goog.addDependency("ui/selectionmenubutton.js", ['goog.ui.SelectionMenuButton', 'goog.ui.SelectionMenuButton.SelectionState'], ['goog.dom.InputType', 'goog.dom.TagName', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/selectionmenubutton_test.js", ['goog.ui.SelectionMenuButtonTest'], ['goog.dom', 'goog.events', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.SelectionMenuButton']);
                +goog.addDependency("ui/selectionmodel.js", ['goog.ui.SelectionModel'], ['goog.array', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("ui/selectionmodel_test.js", ['goog.ui.SelectionModelTest'], ['goog.array', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.SelectionModel']);
                +goog.addDependency("ui/separator.js", ['goog.ui.Separator'], ['goog.a11y.aria', 'goog.asserts', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuSeparatorRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/serverchart.js", ['goog.ui.ServerChart', 'goog.ui.ServerChart.AxisDisplayType', 'goog.ui.ServerChart.ChartType', 'goog.ui.ServerChart.EncodingType', 'goog.ui.ServerChart.Event', 'goog.ui.ServerChart.LegendPosition', 'goog.ui.ServerChart.MaximumValue', 'goog.ui.ServerChart.MultiAxisAlignment', 'goog.ui.ServerChart.MultiAxisType', 'goog.ui.ServerChart.UriParam', 'goog.ui.ServerChart.UriTooLongEvent'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.events.Event', 'goog.string', 'goog.ui.Component']);
                +goog.addDependency("ui/serverchart_test.js", ['goog.ui.ServerChartTest'], ['goog.Uri', 'goog.events', 'goog.testing.jsunit', 'goog.ui.ServerChart']);
                +goog.addDependency("ui/slider.js", ['goog.ui.Slider', 'goog.ui.Slider.Orientation'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.ui.SliderBase']);
                +goog.addDependency("ui/sliderbase.js", ['goog.ui.SliderBase', 'goog.ui.SliderBase.AnimationFactory', 'goog.ui.SliderBase.Orientation'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.events.MouseWheelHandler', 'goog.functions', 'goog.fx.AnimationParallelQueue', 'goog.fx.Dragger', 'goog.fx.Transition', 'goog.fx.dom.ResizeHeight', 'goog.fx.dom.ResizeWidth', 'goog.fx.dom.Slide', 'goog.math', 'goog.math.Coordinate', 'goog.style', 'goog.style.bidi', 'goog.ui.Component', 'goog.ui.RangeModel']);
                +goog.addDependency("ui/sliderbase_test.js", ['goog.ui.SliderBaseTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Animation', 'goog.math.Coordinate', 'goog.style', 'goog.style.bidi', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.SliderBase', 'goog.userAgent']);
                +goog.addDependency("ui/splitpane.js", ['goog.ui.SplitPane', 'goog.ui.SplitPane.Orientation'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Rect', 'goog.math.Size', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/splitpane_test.js", ['goog.ui.SplitPaneTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.math.Size', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.SplitPane']);
                +goog.addDependency("ui/style/app/buttonrenderer.js", ['goog.ui.style.app.ButtonRenderer'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/style/app/buttonrenderer_test.js", ['goog.ui.style.app.ButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.style.app.ButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/style/app/menubuttonrenderer.js", ['goog.ui.style.app.MenuButtonRenderer'], ['goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuRenderer', 'goog.ui.style.app.ButtonRenderer']);
                +goog.addDependency("ui/style/app/menubuttonrenderer_test.js", ['goog.ui.style.app.MenuButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Component', 'goog.ui.MenuButton', 'goog.ui.style.app.MenuButtonRenderer']);
                +goog.addDependency("ui/style/app/primaryactionbuttonrenderer.js", ['goog.ui.style.app.PrimaryActionButtonRenderer'], ['goog.ui.Button', 'goog.ui.registry', 'goog.ui.style.app.ButtonRenderer']);
                +goog.addDependency("ui/style/app/primaryactionbuttonrenderer_test.js", ['goog.ui.style.app.PrimaryActionButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.style.app.PrimaryActionButtonRenderer']);
                +goog.addDependency("ui/submenu.js", ['goog.ui.SubMenu'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.style', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.SubMenuRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/submenu_test.js", ['goog.ui.SubMenuTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.functions', 'goog.positioning', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.SubMenu', 'goog.ui.SubMenuRenderer']);
                +goog.addDependency("ui/submenurenderer.js", ['goog.ui.SubMenuRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/tab.js", ['goog.ui.Tab'], ['goog.ui.Component', 'goog.ui.Control', 'goog.ui.TabRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tab_test.js", ['goog.ui.TabTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Tab', 'goog.ui.TabRenderer']);
                +goog.addDependency("ui/tabbar.js", ['goog.ui.TabBar', 'goog.ui.TabBar.Location'], ['goog.ui.Component.EventType', 'goog.ui.Container', 'goog.ui.Container.Orientation', 'goog.ui.Tab', 'goog.ui.TabBarRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tabbar_test.js", ['goog.ui.TabBarTest'], ['goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Tab', 'goog.ui.TabBar', 'goog.ui.TabBarRenderer']);
                +goog.addDependency("ui/tabbarrenderer.js", ['goog.ui.TabBarRenderer'], ['goog.a11y.aria.Role', 'goog.object', 'goog.ui.ContainerRenderer']);
                +goog.addDependency("ui/tabbarrenderer_test.js", ['goog.ui.TabBarRendererTest'], ['goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Container', 'goog.ui.TabBar', 'goog.ui.TabBarRenderer']);
                +goog.addDependency("ui/tablesorter.js", ['goog.ui.TableSorter', 'goog.ui.TableSorter.EventType'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.functions', 'goog.ui.Component']);
                +goog.addDependency("ui/tablesorter_test.js", ['goog.ui.TableSorterTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.TableSorter']);
                +goog.addDependency("ui/tabpane.js", ['goog.ui.TabPane', 'goog.ui.TabPane.Events', 'goog.ui.TabPane.TabLocation', 'goog.ui.TabPane.TabPage', 'goog.ui.TabPaneEvent'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style']);
                +goog.addDependency("ui/tabpane_test.js", ['goog.ui.TabPaneTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.TabPane']);
                +goog.addDependency("ui/tabrenderer.js", ['goog.ui.TabRenderer'], ['goog.a11y.aria.Role', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/tabrenderer_test.js", ['goog.ui.TabRendererTest'], ['goog.a11y.aria.Role', 'goog.dom', 'goog.dom.classlist', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Tab', 'goog.ui.TabRenderer']);
                +goog.addDependency("ui/textarea.js", ['goog.ui.Textarea', 'goog.ui.Textarea.EventType'], ['goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventType', 'goog.style', 'goog.ui.Control', 'goog.ui.TextareaRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/textarea_test.js", ['goog.ui.TextareaTest'], ['goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.events.EventObserver', 'goog.testing.jsunit', 'goog.ui.Textarea', 'goog.ui.TextareaRenderer', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/textarearenderer.js", ['goog.ui.TextareaRenderer'], ['goog.dom.TagName', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/togglebutton.js", ['goog.ui.ToggleButton'], ['goog.ui.Button', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbar.js", ['goog.ui.Toolbar'], ['goog.ui.Container', 'goog.ui.ToolbarRenderer']);
                +goog.addDependency("ui/toolbar_test.js", ['goog.ui.ToolbarTest'], ['goog.a11y.aria', 'goog.dom', 'goog.events.EventType', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.Toolbar', 'goog.ui.ToolbarMenuButton']);
                +goog.addDependency("ui/toolbarbutton.js", ['goog.ui.ToolbarButton'], ['goog.ui.Button', 'goog.ui.ToolbarButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarbuttonrenderer.js", ['goog.ui.ToolbarButtonRenderer'], ['goog.ui.CustomButtonRenderer']);
                +goog.addDependency("ui/toolbarcolormenubutton.js", ['goog.ui.ToolbarColorMenuButton'], ['goog.ui.ColorMenuButton', 'goog.ui.ToolbarColorMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarcolormenubuttonrenderer.js", ['goog.ui.ToolbarColorMenuButtonRenderer'], ['goog.asserts', 'goog.dom.classlist', 'goog.ui.ColorMenuButtonRenderer', 'goog.ui.MenuButtonRenderer', 'goog.ui.ToolbarMenuButtonRenderer']);
                +goog.addDependency("ui/toolbarcolormenubuttonrenderer_test.js", ['goog.ui.ToolbarColorMenuButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.RendererHarness', 'goog.testing.ui.rendererasserts', 'goog.ui.ToolbarColorMenuButton', 'goog.ui.ToolbarColorMenuButtonRenderer']);
                +goog.addDependency("ui/toolbarmenubutton.js", ['goog.ui.ToolbarMenuButton'], ['goog.ui.MenuButton', 'goog.ui.ToolbarMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarmenubuttonrenderer.js", ['goog.ui.ToolbarMenuButtonRenderer'], ['goog.ui.MenuButtonRenderer']);
                +goog.addDependency("ui/toolbarrenderer.js", ['goog.ui.ToolbarRenderer'], ['goog.a11y.aria.Role', 'goog.dom.TagName', 'goog.ui.Container', 'goog.ui.ContainerRenderer', 'goog.ui.Separator', 'goog.ui.ToolbarSeparatorRenderer']);
                +goog.addDependency("ui/toolbarselect.js", ['goog.ui.ToolbarSelect'], ['goog.ui.Select', 'goog.ui.ToolbarMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarseparator.js", ['goog.ui.ToolbarSeparator'], ['goog.ui.Separator', 'goog.ui.ToolbarSeparatorRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarseparatorrenderer.js", ['goog.ui.ToolbarSeparatorRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuSeparatorRenderer']);
                +goog.addDependency("ui/toolbarseparatorrenderer_test.js", ['goog.ui.ToolbarSeparatorRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.ToolbarSeparator', 'goog.ui.ToolbarSeparatorRenderer']);
                +goog.addDependency("ui/toolbartogglebutton.js", ['goog.ui.ToolbarToggleButton'], ['goog.ui.ToggleButton', 'goog.ui.ToolbarButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tooltip.js", ['goog.ui.Tooltip', 'goog.ui.Tooltip.CursorTooltipPosition', 'goog.ui.Tooltip.ElementTooltipPosition', 'goog.ui.Tooltip.State'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.math.Box', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.positioning.ViewportPosition', 'goog.structs.Set', 'goog.style', 'goog.ui.Popup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/tooltip_test.js", ['goog.ui.TooltipTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.html.testing', 'goog.math.Coordinate', 'goog.positioning.AbsolutePosition', 'goog.style', 'goog.testing.MockClock', 'goog.testing.TestQueue', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.PopupBase', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/tree/basenode.js", ['goog.ui.tree.BaseNode', 'goog.ui.tree.BaseNode.EventType'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom.safe', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.string', 'goog.string.StringBuffer', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("ui/tree/basenode_test.js", ['goog.ui.tree.BaseNodeTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.tree.BaseNode', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']);
                +goog.addDependency("ui/tree/treecontrol.js", ['goog.ui.tree.TreeControl'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.events.KeyHandler', 'goog.html.SafeHtml', 'goog.log', 'goog.ui.tree.BaseNode', 'goog.ui.tree.TreeNode', 'goog.ui.tree.TypeAhead', 'goog.userAgent']);
                +goog.addDependency("ui/tree/treecontrol_test.js", ['goog.ui.tree.TreeControlTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.tree.TreeControl']);
                +goog.addDependency("ui/tree/treenode.js", ['goog.ui.tree.TreeNode'], ['goog.ui.tree.BaseNode']);
                +goog.addDependency("ui/tree/typeahead.js", ['goog.ui.tree.TypeAhead', 'goog.ui.tree.TypeAhead.Offset'], ['goog.array', 'goog.events.KeyCodes', 'goog.string', 'goog.structs.Trie']);
                +goog.addDependency("ui/tree/typeahead_test.js", ['goog.ui.tree.TypeAheadTest'], ['goog.dom', 'goog.events.KeyCodes', 'goog.testing.jsunit', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TypeAhead']);
                +goog.addDependency("ui/tristatemenuitem.js", ['goog.ui.TriStateMenuItem', 'goog.ui.TriStateMenuItem.State'], ['goog.dom.classlist', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.TriStateMenuItemRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tristatemenuitemrenderer.js", ['goog.ui.TriStateMenuItemRenderer'], ['goog.asserts', 'goog.dom.classlist', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/twothumbslider.js", ['goog.ui.TwoThumbSlider'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.ui.SliderBase']);
                +goog.addDependency("ui/twothumbslider_test.js", ['goog.ui.TwoThumbSliderTest'], ['goog.testing.jsunit', 'goog.ui.SliderBase', 'goog.ui.TwoThumbSlider']);
                +goog.addDependency("ui/zippy.js", ['goog.ui.Zippy', 'goog.ui.Zippy.Events', 'goog.ui.ZippyEvent'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.style']);
                +goog.addDependency("ui/zippy_test.js", ['goog.ui.ZippyTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.object', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Zippy']);
                +goog.addDependency("uri/uri.js", ['goog.Uri', 'goog.Uri.QueryData'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.structs', 'goog.structs.Map', 'goog.uri.utils', 'goog.uri.utils.ComponentIndex', 'goog.uri.utils.StandardQueryParam']);
                +goog.addDependency("uri/uri_test.js", ['goog.UriTest'], ['goog.Uri', 'goog.testing.jsunit']);
                +goog.addDependency("uri/utils.js", ['goog.uri.utils', 'goog.uri.utils.ComponentIndex', 'goog.uri.utils.QueryArray', 'goog.uri.utils.QueryValue', 'goog.uri.utils.StandardQueryParam'], ['goog.asserts', 'goog.string']);
                +goog.addDependency("uri/utils_test.js", ['goog.uri.utilsTest'], ['goog.functions', 'goog.string', 'goog.testing.jsunit', 'goog.uri.utils']);
                +goog.addDependency("useragent/adobereader.js", ['goog.userAgent.adobeReader'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/adobereader_test.js", ['goog.userAgent.adobeReaderTest'], ['goog.testing.jsunit', 'goog.userAgent.adobeReader']);
                +goog.addDependency("useragent/flash.js", ['goog.userAgent.flash'], ['goog.string']);
                +goog.addDependency("useragent/flash_test.js", ['goog.userAgent.flashTest'], ['goog.testing.jsunit', 'goog.userAgent.flash']);
                +goog.addDependency("useragent/iphoto.js", ['goog.userAgent.iphoto'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/jscript.js", ['goog.userAgent.jscript'], ['goog.string']);
                +goog.addDependency("useragent/jscript_test.js", ['goog.userAgent.jscriptTest'], ['goog.testing.jsunit', 'goog.userAgent.jscript']);
                +goog.addDependency("useragent/keyboard.js", ['goog.userAgent.keyboard'], ['goog.labs.userAgent.platform']);
                +goog.addDependency("useragent/keyboard_test.js", ['goog.userAgent.keyboardTest'], ['goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent.keyboard', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/platform.js", ['goog.userAgent.platform'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/platform_test.js", ['goog.userAgent.platformTest'], ['goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.platform', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/product.js", ['goog.userAgent.product'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.platform', 'goog.userAgent']);
                +goog.addDependency("useragent/product_isversion.js", ['goog.userAgent.product.isVersion'], ['goog.labs.userAgent.platform', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("useragent/product_test.js", ['goog.userAgent.productTest'], ['goog.array', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/useragent.js", ['goog.userAgent'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.labs.userAgent.util', 'goog.reflect', 'goog.string']);
                +goog.addDependency("useragent/useragent_quirks_test.js", ['goog.userAgentQuirksTest'], ['goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("useragent/useragent_test.js", ['goog.userAgentTest'], ['goog.array', 'goog.labs.userAgent.platform', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/useragenttestutil.js", ['goog.userAgentTestUtil', 'goog.userAgentTestUtil.UserAgents'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.object', 'goog.userAgent', 'goog.userAgent.keyboard', 'goog.userAgent.platform', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("vec/float32array.js", ['goog.vec.Float32Array'], []);
                +goog.addDependency("vec/float32array_test.js", ['goog.vec.Float32ArrayTest'], ['goog.vec.Float32Array', 'goog.testing.jsunit']);
                +goog.addDependency("vec/float64array.js", ['goog.vec.Float64Array'], []);
                +goog.addDependency("vec/float64array_test.js", ['goog.vec.Float64ArrayTest'], ['goog.vec.Float64Array', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3.js", ['goog.vec.Mat3'], ['goog.vec']);
                +goog.addDependency("vec/mat3_test.js", ['goog.vec.Mat3Test'], ['goog.vec.Mat3', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3d.js", ['goog.vec.mat3d', 'goog.vec.mat3d.Type'], ['goog.vec', 'goog.vec.vec3d.Type']);
                +goog.addDependency("vec/mat3d_test.js", ['goog.vec.mat3dTest'], ['goog.vec.mat3d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3f.js", ['goog.vec.mat3f', 'goog.vec.mat3f.Type'], ['goog.vec', 'goog.vec.vec3f.Type']);
                +goog.addDependency("vec/mat3f_test.js", ['goog.vec.mat3fTest'], ['goog.vec.mat3f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4.js", ['goog.vec.Mat4'], ['goog.vec', 'goog.vec.Vec3', 'goog.vec.Vec4']);
                +goog.addDependency("vec/mat4_test.js", ['goog.vec.Mat4Test'], ['goog.vec.Mat4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4d.js", ['goog.vec.mat4d', 'goog.vec.mat4d.Type'], ['goog.vec', 'goog.vec.Quaternion', 'goog.vec.vec3d', 'goog.vec.vec4d']);
                +goog.addDependency("vec/mat4d_test.js", ['goog.vec.mat4dTest'], ['goog.vec.Quaternion', 'goog.vec.mat4d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4f.js", ['goog.vec.mat4f', 'goog.vec.mat4f.Type'], ['goog.vec', 'goog.vec.Quaternion', 'goog.vec.vec3f', 'goog.vec.vec4f']);
                +goog.addDependency("vec/mat4f_test.js", ['goog.vec.mat4fTest'], ['goog.vec.Quaternion', 'goog.vec.mat4f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/quaternion.js", ['goog.vec.Quaternion', 'goog.vec.Quaternion.AnyType'], ['goog.vec', 'goog.vec.Vec3', 'goog.vec.Vec4']);
                +goog.addDependency("vec/quaternion_test.js", ['goog.vec.QuaternionTest'], ['goog.vec.Float32Array', 'goog.vec.Mat3', 'goog.vec.Mat4', 'goog.vec.Quaternion', 'goog.vec.Vec3', 'goog.vec.vec3f', 'goog.vec.Vec4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/ray.js", ['goog.vec.Ray'], ['goog.vec.Vec3']);
                +goog.addDependency("vec/ray_test.js", ['goog.vec.RayTest'], ['goog.vec.Float32Array', 'goog.vec.Ray', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec.js", ['goog.vec', 'goog.vec.AnyType', 'goog.vec.ArrayType', 'goog.vec.Float32', 'goog.vec.Float64', 'goog.vec.Number'], ['goog.vec.Float32Array', 'goog.vec.Float64Array']);
                +goog.addDependency("vec/vec2.js", ['goog.vec.Vec2'], ['goog.vec']);
                +goog.addDependency("vec/vec2_test.js", ['goog.vec.Vec2Test'], ['goog.vec.Float32Array', 'goog.vec.Vec2', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec2d.js", ['goog.vec.vec2d', 'goog.vec.vec2d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec2d_test.js", ['goog.vec.vec2dTest'], ['goog.vec.Float64Array', 'goog.vec.vec2d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec2f.js", ['goog.vec.vec2f', 'goog.vec.vec2f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec2f_test.js", ['goog.vec.vec2fTest'], ['goog.vec.Float32Array', 'goog.vec.vec2f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3.js", ['goog.vec.Vec3'], ['goog.vec']);
                +goog.addDependency("vec/vec3_test.js", ['goog.vec.Vec3Test'], ['goog.vec.Float32Array', 'goog.vec.Vec3', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3d.js", ['goog.vec.vec3d', 'goog.vec.vec3d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec3d_test.js", ['goog.vec.vec3dTest'], ['goog.vec.Float64Array', 'goog.vec.vec3d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3f.js", ['goog.vec.vec3f', 'goog.vec.vec3f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec3f_test.js", ['goog.vec.vec3fTest'], ['goog.vec.Float32Array', 'goog.vec.vec3f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4.js", ['goog.vec.Vec4'], ['goog.vec']);
                +goog.addDependency("vec/vec4_test.js", ['goog.vec.Vec4Test'], ['goog.vec.Float32Array', 'goog.vec.Vec4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4d.js", ['goog.vec.vec4d', 'goog.vec.vec4d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec4d_test.js", ['goog.vec.vec4dTest'], ['goog.vec.Float64Array', 'goog.vec.vec4d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4f.js", ['goog.vec.vec4f', 'goog.vec.vec4f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec4f_test.js", ['goog.vec.vec4fTest'], ['goog.vec.Float32Array', 'goog.vec.vec4f', 'goog.testing.jsunit']);
                +goog.addDependency("webgl/webgl.js", ['goog.webgl'], []);
                +goog.addDependency("window/window.js", ['goog.window'], ['goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.labs.userAgent.platform', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("window/window_test.js", ['goog.windowTest'], ['goog.Promise', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.functions', 'goog.html.SafeUrl', 'goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.window']);
                +
                +// Load Blockly.
                +goog.require('Blockly');
                +goog.require('Blockly.Block');
                +goog.require('Blockly.BlockDragSurfaceSvg');
                +goog.require('Blockly.BlockDragger');
                +goog.require('Blockly.BlockSvg');
                +goog.require('Blockly.BlockSvg.render');
                +goog.require('Blockly.Blocks');
                +goog.require('Blockly.Bubble');
                +goog.require('Blockly.Comment');
                +goog.require('Blockly.CommonModal');
                +goog.require('Blockly.Connection');
                +goog.require('Blockly.ConnectionDB');
                +goog.require('Blockly.ContextMenu');
                +goog.require('Blockly.Css');
                +goog.require('Blockly.DraggedConnectionManager');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.Extensions');
                +goog.require('Blockly.Field');
                +goog.require('Blockly.FieldAngle');
                +goog.require('Blockly.FieldCheckbox');
                +goog.require('Blockly.FieldColour');
                +goog.require('Blockly.FieldDate');
                +goog.require('Blockly.FieldDropdown');
                +goog.require('Blockly.FieldImage');
                +goog.require('Blockly.FieldLabel');
                +goog.require('Blockly.FieldNumber');
                +goog.require('Blockly.FieldTextInput');
                +goog.require('Blockly.FieldVariable');
                +goog.require('Blockly.Flyout');
                +goog.require('Blockly.FlyoutButton');
                +goog.require('Blockly.FlyoutDragger');
                +goog.require('Blockly.Generator');
                +goog.require('Blockly.Gesture');
                +goog.require('Blockly.Grid');
                +goog.require('Blockly.HorizontalFlyout');
                +goog.require('Blockly.Icon');
                +goog.require('Blockly.Input');
                +goog.require('Blockly.Msg');
                +goog.require('Blockly.Mutator');
                +goog.require('Blockly.Names');
                +goog.require('Blockly.Options');
                +goog.require('Blockly.Procedures');
                +goog.require('Blockly.RenderedConnection');
                +goog.require('Blockly.Scrollbar');
                +goog.require('Blockly.ScrollbarPair');
                +goog.require('Blockly.Toolbox');
                +goog.require('Blockly.Tooltip');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.Trashcan');
                +goog.require('Blockly.VariableMap');
                +goog.require('Blockly.VariableModel');
                +goog.require('Blockly.Variables');
                +goog.require('Blockly.VerticalFlyout');
                +goog.require('Blockly.Warning');
                +goog.require('Blockly.WidgetDiv');
                +goog.require('Blockly.Workspace');
                +goog.require('Blockly.WorkspaceAudio');
                +goog.require('Blockly.WorkspaceDragSurfaceSvg');
                +goog.require('Blockly.WorkspaceDragger');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('Blockly.Xml');
                +goog.require('Blockly.ZoomControls');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.inject');
                +goog.require('Blockly.utils');
                +goog.require('blocklyApp.AppComponent');
                +goog.require('blocklyApp.AudioService');
                +goog.require('blocklyApp.BlockConnectionService');
                +goog.require('blocklyApp.BlockOptionsModalComponent');
                +goog.require('blocklyApp.BlockOptionsModalService');
                +goog.require('blocklyApp.FieldSegmentComponent');
                +goog.require('blocklyApp.KeyboardInputService');
                +goog.require('blocklyApp.NotificationsService');
                +goog.require('blocklyApp.SidebarComponent');
                +goog.require('blocklyApp.ToolboxModalComponent');
                +goog.require('blocklyApp.ToolboxModalService');
                +goog.require('blocklyApp.TranslatePipe');
                +goog.require('blocklyApp.TreeService');
                +goog.require('blocklyApp.UtilsService');
                +goog.require('blocklyApp.VariableAddModalComponent');
                +goog.require('blocklyApp.VariableModalService');
                +goog.require('blocklyApp.VariableRemoveModalComponent');
                +goog.require('blocklyApp.VariableRenameModalComponent');
                +goog.require('blocklyApp.WorkspaceBlockComponent');
                +goog.require('blocklyApp.WorkspaceComponent');
                +
                +delete this.BLOCKLY_DIR;
                +delete this.BLOCKLY_BOOT;
                +};
                +
                +if (isNodeJS) {
                +  window.BLOCKLY_BOOT();
                +  module.exports = Blockly;
                +} else {
                +  // Delete any existing Closure (e.g. Soy's nogoog_shim).
                +  document.write('<script>var goog = undefined;</script>');
                +  // Load fresh Closure Library.
                +  document.write('<script src="' + window.BLOCKLY_DIR +
                +      '/../closure-library/closure/goog/base.js"></script>');
                +  document.write('<script>window.BLOCKLY_BOOT();</script>');
                +}
                diff --git a/blockly/webif/static/blockly/blockly_compressed.js b/blockly/webif/static/blockly/blockly_compressed.js
                new file mode 100644
                index 000000000..f7bd9a422
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blockly_compressed.js
                @@ -0,0 +1,1705 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +var COMPILED=!0,goog=goog||{};goog.global=this;goog.isDef=function(a){return void 0!==a};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.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]!==Object.prototype[d]?c[d]:c[d]={}};
                +goog.define=function(a,b){var c=b;COMPILED||(goog.global.CLOSURE_UNCOMPILED_DEFINES&&void 0===goog.global.CLOSURE_UNCOMPILED_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES,a)?c=goog.global.CLOSURE_UNCOMPILED_DEFINES[a]:goog.global.CLOSURE_DEFINES&&void 0===goog.global.CLOSURE_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,a)&&(c=goog.global.CLOSURE_DEFINES[a]));goog.exportPath_(a,c)};goog.DEBUG=!1;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){if(a in goog.loadedModules_)return goog.loadedModules_[a];if(!goog.implicitNamespaces_[a])return a=goog.getObjectByName(a),null!=a?a:null}return 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.instance_=void 0;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.isString(goog.global.CLOSURE_BASE_PATH))goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_()){var a=goog.global.document;var b=a.currentScript;a=b?[b]:a.getElementsByTagName("SCRIPT");for(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.oldIeWaiting_=!1,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.oldIeWaiting_=!1},
                +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]||{},c=b.lang||"es3";return a&&("goog"==b.module||goog.needsTranspile_(c))?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_){goog.oldIeWaiting_=!0;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">'+goog.protectScriptTag_(b)+"\x3c/script>");return!0}return!1},goog.protectScriptTag_=function(a){return a.replace(/<\/(SCRIPT)/ig,"\\x3c/$1")},goog.needsTranspile_=function(a){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;goog.requiresTranspilation_||(goog.requiresTranspilation_=goog.createRequiresTranspilation_());
                +if(a in goog.requiresTranspilation_)return goog.requiresTranspilation_[a];throw Error("Unknown language mode: "+a);},goog.requiresTranspilation_=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(var f=0;f<c.length;f++)a=c[f],goog.dependencies_.written[a]=!0;var g=goog.moduleLoaderState_;goog.moduleLoaderState_=null;for(f=0;f<c.length;f++)if(a=c[f]){var h=e.loadFlags[a]||{},k=goog.needsTranspile_(h.lang||"es3");"goog"==h.module||k?goog.importProcessedScript_(goog.basePath+a,"goog"==h.module,k):goog.importScript_(goog.basePath+a)}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.hasBadLetScoping=null;goog.useSafari10Workaround=function(){if(null==goog.hasBadLetScoping){try{var a=!eval('"use strict";let x = 1; function f() { return typeof x; };f() == "number";')}catch(b){a=!1}goog.hasBadLetScoping=a}return goog.hasBadLetScoping};
                +goog.workaroundSafari10EvalBug=function(a){return"(function(){"+a+"\n;})();\n"};
                +goog.loadModule=function(a){var b=goog.moduleLoaderState_;try{goog.moduleLoaderState_={moduleName:void 0,declareLegacyNamespace:!1};if(goog.isFunction(a))var c=a.call(void 0,{});else if(goog.isString(a))goog.useSafari10Workaround()&&(a=goog.workaroundSafari10EvalBug(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&&"object"==typeof c&&null!=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.oldIeWaiting_?(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);if(f){eval(f+"\n//# sourceURL="+e);if(goog.global.$gwtExport&&goog.global.$gwtExport.$jscomp&&!goog.global.$gwtExport.$jscomp.transpile)throw Error('The transpiler did not properly export the "transpile" method. $gwtExport: '+JSON.stringify(goog.global.$gwtExport));goog.global.$jscomp.transpile=goog.global.$gwtExport.$jscomp.transpile;
                +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.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";
                +goog.createRequiresTranspilation_=function(){function a(a,b){d?c[a]=!0:b()?c[a]=!1:d=c[a]=!0}function b(a){try{return!!eval(a)}catch(g){return!1}}var c={es3:!1},d=!1,e=goog.global.navigator&&goog.global.navigator.userAgent?goog.global.navigator.userAgent:"";a("es5",function(){return b("[1,].length==1")});a("es6",function(){var a=e.match(/Edge\/(\d+)(\.\d)*/i);return a&&15>Number(a[1])?!1:b('(()=>{"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}})()')});
                +a("es6-impl",function(){return!0});a("es7",function(){return b("2 ** 2 == 4")});a("es8",function(){return b("async () => 1, true")});return c};goog.debug={};goog.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,goog.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a));this.reportErrorToServer=!0};goog.inherits(goog.debug.Error,Error);goog.debug.Error.prototype.name="CustomError";goog.dom={};goog.dom.NodeType={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12};goog.string={};goog.string.DETECT_DOUBLE_ESCAPING=!1;goog.string.FORCE_NON_DOM_HTML_UNESCAPING=!1;goog.string.Unicode={NBSP:"\u00a0"};goog.string.startsWith=function(a,b){return 0==a.lastIndexOf(b,0)};goog.string.endsWith=function(a,b){var c=a.length-b.length;return 0<=c&&a.indexOf(b,c)==c};goog.string.caseInsensitiveStartsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(0,b.length))};
                +goog.string.caseInsensitiveEndsWith=function(a,b){return 0==goog.string.caseInsensitiveCompare(b,a.substr(a.length-b.length,b.length))};goog.string.caseInsensitiveEquals=function(a,b){return a.toLowerCase()==b.toLowerCase()};goog.string.subs=function(a,b){for(var c=a.split("%s"),d="",e=Array.prototype.slice.call(arguments,1);e.length&&1<c.length;)d+=c.shift()+e.shift();return d+c.join("%s")};goog.string.collapseWhitespace=function(a){return a.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")};
                +goog.string.isEmptyOrWhitespace=function(a){return/^[\s\xa0]*$/.test(a)};goog.string.isEmptyString=function(a){return 0==a.length};goog.string.isEmpty=goog.string.isEmptyOrWhitespace;goog.string.isEmptyOrWhitespaceSafe=function(a){return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(a))};goog.string.isEmptySafe=goog.string.isEmptyOrWhitespaceSafe;goog.string.isBreakingWhitespace=function(a){return!/[^\t\n\r ]/.test(a)};goog.string.isAlpha=function(a){return!/[^a-zA-Z]/.test(a)};
                +goog.string.isNumeric=function(a){return!/[^0-9]/.test(a)};goog.string.isAlphaNumeric=function(a){return!/[^a-zA-Z0-9]/.test(a)};goog.string.isSpace=function(a){return" "==a};goog.string.isUnicodeChar=function(a){return 1==a.length&&" "<=a&&"~">=a||"\u0080"<=a&&"\ufffd">=a};goog.string.stripNewlines=function(a){return a.replace(/(\r\n|\r|\n)+/g," ")};goog.string.canonicalizeNewlines=function(a){return a.replace(/(\r\n|\r|\n)/g,"\n")};
                +goog.string.normalizeWhitespace=function(a){return a.replace(/\xa0|\s/g," ")};goog.string.normalizeSpaces=function(a){return a.replace(/\xa0|[ \t]+/g," ")};goog.string.collapseBreakingSpaces=function(a){return a.replace(/[\t\r\n ]+/g," ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g,"")};goog.string.trim=goog.TRUSTED_SITE&&String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};goog.string.trimLeft=function(a){return a.replace(/^[\s\xa0]+/,"")};
                +goog.string.trimRight=function(a){return a.replace(/[\s\xa0]+$/,"")};goog.string.caseInsensitiveCompare=function(a,b){var c=String(a).toLowerCase(),d=String(b).toLowerCase();return c<d?-1:c==d?0:1};
                +goog.string.numberAwareCompare_=function(a,b,c){if(a==b)return 0;if(!a)return-1;if(!b)return 1;for(var d=a.toLowerCase().match(c),e=b.toLowerCase().match(c),f=Math.min(d.length,e.length),g=0;g<f;g++){c=d[g];var h=e[g];if(c!=h)return a=parseInt(c,10),!isNaN(a)&&(b=parseInt(h,10),!isNaN(b)&&a-b)?a-b:c<h?-1:1}return d.length!=e.length?d.length-e.length:a<b?-1:1};goog.string.intAwareCompare=function(a,b){return goog.string.numberAwareCompare_(a,b,/\d+|\D+/g)};
                +goog.string.floatAwareCompare=function(a,b){return goog.string.numberAwareCompare_(a,b,/\d+|\.\d+|\D+/g)};goog.string.numerateCompare=goog.string.floatAwareCompare;goog.string.urlEncode=function(a){return encodeURIComponent(String(a))};goog.string.urlDecode=function(a){return decodeURIComponent(a.replace(/\+/g," "))};goog.string.newLineToBr=function(a,b){return a.replace(/(\r\n|\r|\n)/g,b?"<br />":"<br>")};
                +goog.string.htmlEscape=function(a,b){if(b)a=a.replace(goog.string.AMP_RE_,"&amp;").replace(goog.string.LT_RE_,"&lt;").replace(goog.string.GT_RE_,"&gt;").replace(goog.string.QUOT_RE_,"&quot;").replace(goog.string.SINGLE_QUOTE_RE_,"&#39;").replace(goog.string.NULL_RE_,"&#0;"),goog.string.DETECT_DOUBLE_ESCAPING&&(a=a.replace(goog.string.E_RE_,"&#101;"));else{if(!goog.string.ALL_RE_.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(goog.string.AMP_RE_,"&amp;"));-1!=a.indexOf("<")&&(a=a.replace(goog.string.LT_RE_,
                +"&lt;"));-1!=a.indexOf(">")&&(a=a.replace(goog.string.GT_RE_,"&gt;"));-1!=a.indexOf('"')&&(a=a.replace(goog.string.QUOT_RE_,"&quot;"));-1!=a.indexOf("'")&&(a=a.replace(goog.string.SINGLE_QUOTE_RE_,"&#39;"));-1!=a.indexOf("\x00")&&(a=a.replace(goog.string.NULL_RE_,"&#0;"));goog.string.DETECT_DOUBLE_ESCAPING&&-1!=a.indexOf("e")&&(a=a.replace(goog.string.E_RE_,"&#101;"))}return a};goog.string.AMP_RE_=/&/g;goog.string.LT_RE_=/</g;goog.string.GT_RE_=/>/g;goog.string.QUOT_RE_=/"/g;
                +goog.string.SINGLE_QUOTE_RE_=/'/g;goog.string.NULL_RE_=/\x00/g;goog.string.E_RE_=/e/g;goog.string.ALL_RE_=goog.string.DETECT_DOUBLE_ESCAPING?/[\x00&<>"'e]/:/[\x00&<>"']/;goog.string.unescapeEntities=function(a){return goog.string.contains(a,"&")?!goog.string.FORCE_NON_DOM_HTML_UNESCAPING&&"document"in goog.global?goog.string.unescapeEntitiesUsingDom_(a):goog.string.unescapePureXmlEntities_(a):a};
                +goog.string.unescapeEntitiesWithDocument=function(a,b){return goog.string.contains(a,"&")?goog.string.unescapeEntitiesUsingDom_(a,b):a};
                +goog.string.unescapeEntitiesUsingDom_=function(a,b){var c={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"'};var d=b?b.createElement("div"):goog.global.document.createElement("div");return a.replace(goog.string.HTML_ENTITY_PATTERN_,function(a,b){var e=c[a];if(e)return e;if("#"==b.charAt(0)){var f=Number("0"+b.substr(1));isNaN(f)||(e=String.fromCharCode(f))}e||(d.innerHTML=a+" ",e=d.firstChild.nodeValue.slice(0,-1));return c[a]=e})};
                +goog.string.unescapePureXmlEntities_=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:if("#"==c.charAt(0)){var b=Number("0"+c.substr(1));if(!isNaN(b))return String.fromCharCode(b)}return a}})};goog.string.HTML_ENTITY_PATTERN_=/&([^;\s<&]+);?/g;goog.string.whitespaceEscape=function(a,b){return goog.string.newLineToBr(a.replace(/  /g," &#160;"),b)};
                +goog.string.preserveSpaces=function(a){return a.replace(/(^|[\n ]) /g,"$1"+goog.string.Unicode.NBSP)};goog.string.stripQuotes=function(a,b){for(var c=b.length,d=0;d<c;d++){var e=1==c?b:b.charAt(d);if(a.charAt(0)==e&&a.charAt(a.length-1)==e)return a.substring(1,a.length-1)}return a};goog.string.truncate=function(a,b,c){c&&(a=goog.string.unescapeEntities(a));a.length>b&&(a=a.substring(0,b-3)+"...");c&&(a=goog.string.htmlEscape(a));return a};
                +goog.string.truncateMiddle=function(a,b,c,d){c&&(a=goog.string.unescapeEntities(a));if(d&&a.length>b){d>b&&(d=b);var e=a.length-d;a=a.substring(0,b-d)+"..."+a.substring(e)}else a.length>b&&(d=Math.floor(b/2),e=a.length-d,a=a.substring(0,d+b%2)+"..."+a.substring(e));c&&(a=goog.string.htmlEscape(a));return a};goog.string.specialEscapeChars_={"\x00":"\\0","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\x0B",'"':'\\"',"\\":"\\\\","<":"<"};goog.string.jsEscapeCache_={"'":"\\'"};
                +goog.string.quote=function(a){a=String(a);for(var b=['"'],c=0;c<a.length;c++){var d=a.charAt(c),e=d.charCodeAt(0);b[c+1]=goog.string.specialEscapeChars_[d]||(31<e&&127>e?d:goog.string.escapeChar(d))}b.push('"');return b.join("")};goog.string.escapeString=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=goog.string.escapeChar(a.charAt(c));return b.join("")};
                +goog.string.escapeChar=function(a){if(a in goog.string.jsEscapeCache_)return goog.string.jsEscapeCache_[a];if(a in goog.string.specialEscapeChars_)return goog.string.jsEscapeCache_[a]=goog.string.specialEscapeChars_[a];var b=a.charCodeAt(0);if(31<b&&127>b)var c=a;else{if(256>b){if(c="\\x",16>b||256<b)c+="0"}else c="\\u",4096>b&&(c+="0");c+=b.toString(16).toUpperCase()}return goog.string.jsEscapeCache_[a]=c};goog.string.contains=function(a,b){return-1!=a.indexOf(b)};
                +goog.string.caseInsensitiveContains=function(a,b){return goog.string.contains(a.toLowerCase(),b.toLowerCase())};goog.string.countOf=function(a,b){return a&&b?a.split(b).length-1:0};goog.string.removeAt=function(a,b,c){var d=a;0<=b&&b<a.length&&0<c&&(d=a.substr(0,b)+a.substr(b+c,a.length-b-c));return d};goog.string.remove=function(a,b){return a.replace(b,"")};goog.string.removeAll=function(a,b){var c=new RegExp(goog.string.regExpEscape(b),"g");return a.replace(c,"")};
                +goog.string.replaceAll=function(a,b,c){b=new RegExp(goog.string.regExpEscape(b),"g");return a.replace(b,c.replace(/\$/g,"$$$$"))};goog.string.regExpEscape=function(a){return String(a).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")};goog.string.repeat=String.prototype.repeat?function(a,b){return a.repeat(b)}:function(a,b){return Array(b+1).join(a)};
                +goog.string.padNumber=function(a,b,c){a=goog.isDef(c)?a.toFixed(c):String(a);c=a.indexOf(".");-1==c&&(c=a.length);return goog.string.repeat("0",Math.max(0,b-c))+a};goog.string.makeSafe=function(a){return null==a?"":String(a)};goog.string.buildString=function(a){return Array.prototype.join.call(arguments,"")};goog.string.getRandomString=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^goog.now()).toString(36)};
                +goog.string.compareVersions=function(a,b){for(var c=0,d=goog.string.trim(String(a)).split("."),e=goog.string.trim(String(b)).split("."),f=Math.max(d.length,e.length),g=0;0==c&&g<f;g++){var h=d[g]||"",k=e[g]||"";do{h=/(\d*)(\D*)(.*)/.exec(h)||["","","",""];k=/(\d*)(\D*)(.*)/.exec(k)||["","","",""];if(0==h[0].length&&0==k[0].length)break;var c=0==h[1].length?0:parseInt(h[1],10),l=0==k[1].length?0:parseInt(k[1],10),c=goog.string.compareElements_(c,l)||goog.string.compareElements_(0==h[2].length,0==k[2].length)||
                +goog.string.compareElements_(h[2],k[2]),h=h[3],k=k[3]}while(0==c)}return c};goog.string.compareElements_=function(a,b){return a<b?-1:a>b?1:0};goog.string.hashCode=function(a){for(var b=0,c=0;c<a.length;++c)b=31*b+a.charCodeAt(c)>>>0;return b};goog.string.uniqueStringCounter_=2147483648*Math.random()|0;goog.string.createUniqueString=function(){return"goog_"+goog.string.uniqueStringCounter_++};goog.string.toNumber=function(a){var b=Number(a);return 0==b&&goog.string.isEmptyOrWhitespace(a)?NaN:b};
                +goog.string.isLowerCamelCase=function(a){return/^[a-z]+([A-Z][a-z]*)*$/.test(a)};goog.string.isUpperCamelCase=function(a){return/^([A-Z][a-z]*)+$/.test(a)};goog.string.toCamelCase=function(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};goog.string.toSelectorCase=function(a){return String(a).replace(/([A-Z])/g,"-$1").toLowerCase()};
                +goog.string.toTitleCase=function(a,b){var c=goog.isString(b)?goog.string.regExpEscape(b):"\\s";return a.replace(new RegExp("(^"+(c?"|["+c+"]+":"")+")([a-z])","g"),function(a,b,c){return b+c.toUpperCase()})};goog.string.capitalize=function(a){return String(a.charAt(0)).toUpperCase()+String(a.substr(1)).toLowerCase()};goog.string.parseInt=function(a){isFinite(a)&&(a=String(a));return goog.isString(a)?/^\s*-?0x/i.test(a)?parseInt(a,16):parseInt(a,10):NaN};
                +goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.length;)d.push(a.shift()),c--;a.length&&d.push(a.join(b));return d};goog.string.lastComponent=function(a,b){if(b)"string"==typeof b&&(b=[b]);else return a;for(var c=-1,d=0;d<b.length;d++)if(""!=b[d]){var e=a.lastIndexOf(b[d]);e>c&&(c=e)}return-1==c?a:a.slice(c+1)};
                +goog.string.editDistance=function(a,b){var c=[],d=[];if(a==b)return 0;if(!a.length||!b.length)return Math.max(a.length,b.length);for(var e=0;e<b.length+1;e++)c[e]=e;for(e=0;e<a.length;e++){d[0]=e+1;for(var f=0;f<b.length;f++)d[f+1]=Math.min(d[f]+1,c[f+1]+1,c[f]+Number(a[e]!=b[f]));for(f=0;f<c.length;f++)c[f]=d[f]}return d[b.length]};goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){b.unshift(a);goog.debug.Error.call(this,goog.string.subs.apply(null,b));b.shift();this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
                +goog.asserts.doAssertFailure_=function(a,b,c,d){var e="Assertion failed";if(c){e+=": "+c;var f=d}else a&&(e+=": "+a,f=b);a=new goog.asserts.AssertionError(""+e,f||[]);goog.asserts.errorHandler_(a)};goog.asserts.setErrorHandler=function(a){goog.asserts.ENABLE_ASSERTS&&(goog.asserts.errorHandler_=a)};goog.asserts.assert=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!a&&goog.asserts.doAssertFailure_("",null,b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.fail=function(a,b){goog.asserts.ENABLE_ASSERTS&&goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1)))};goog.asserts.assertNumber=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isNumber(a)&&goog.asserts.doAssertFailure_("Expected number but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertString=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isString(a)&&goog.asserts.doAssertFailure_("Expected string but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertFunction=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isFunction(a)&&goog.asserts.doAssertFailure_("Expected function but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertObject=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isObject(a)&&goog.asserts.doAssertFailure_("Expected object but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertArray=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isArray(a)&&goog.asserts.doAssertFailure_("Expected array but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertBoolean=function(a,b,c){goog.asserts.ENABLE_ASSERTS&&!goog.isBoolean(a)&&goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};goog.asserts.assertElement=function(a,b,c){!goog.asserts.ENABLE_ASSERTS||goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT||goog.asserts.doAssertFailure_("Expected Element but got %s: %s.",[goog.typeOf(a),a],b,Array.prototype.slice.call(arguments,2));return a};
                +goog.asserts.assertInstanceof=function(a,b,c,d){!goog.asserts.ENABLE_ASSERTS||a instanceof b||goog.asserts.doAssertFailure_("Expected instanceof %s but got %s.",[goog.asserts.getType_(b),goog.asserts.getType_(a)],c,Array.prototype.slice.call(arguments,3));return a};goog.asserts.assertObjectPrototypeIsIntact=function(){for(var a in Object.prototype)goog.asserts.fail(a+" should not be enumerable in Object.prototype.")};
                +goog.asserts.getType_=function(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};goog.array={};goog.NATIVE_ARRAY_PROTOTYPES=goog.TRUSTED_SITE;goog.array.ASSUME_NATIVE_FUNCTIONS=!1;goog.array.peek=function(a){return a[a.length-1]};goog.array.last=goog.array.peek;
                +goog.array.indexOf=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.indexOf)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(goog.isString(a))return goog.isString(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};
                +goog.array.lastIndexOf=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.lastIndexOf)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.lastIndexOf.call(a,b,null==c?a.length-1:c)}:function(a,b,c){c=null==c?a.length-1:c;0>c&&(c=Math.max(0,a.length+c));if(goog.isString(a))return goog.isString(b)&&1==b.length?a.lastIndexOf(b,c):-1;for(;0<=c;c--)if(c in a&&a[c]===b)return c;return-1};
                +goog.array.forEach=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.forEach)?function(a,b,c){goog.asserts.assert(null!=a.length);Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)};goog.array.forEachRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;--d)d in e&&b.call(c,e[d],d,a)};
                +goog.array.filter=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.filter)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=goog.isString(a)?a.split(""):a,h=0;h<d;h++)if(h in g){var k=g[h];b.call(c,k,h,a)&&(e[f++]=k)}return e};
                +goog.array.map=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.map)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=goog.isString(a)?a.split(""):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e};
                +goog.array.reduce=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.reduce)?function(a,b,c,d){goog.asserts.assert(null!=a.length);d&&(b=goog.bind(b,d));return Array.prototype.reduce.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEach(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
                +goog.array.reduceRight=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.reduceRight)?function(a,b,c,d){goog.asserts.assert(null!=a.length);goog.asserts.assert(null!=b);d&&(b=goog.bind(b,d));return Array.prototype.reduceRight.call(a,b,c)}:function(a,b,c,d){var e=c;goog.array.forEachRight(a,function(c,g){e=b.call(d,e,c,g,a)});return e};
                +goog.array.some=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.some)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.some.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return!0;return!1};
                +goog.array.every=goog.NATIVE_ARRAY_PROTOTYPES&&(goog.array.ASSUME_NATIVE_FUNCTIONS||Array.prototype.every)?function(a,b,c){goog.asserts.assert(null!=a.length);return Array.prototype.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0};goog.array.count=function(a,b,c){var d=0;goog.array.forEach(a,function(a,f,g){b.call(c,a,f,g)&&++d},c);return d};
                +goog.array.find=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};goog.array.findIndex=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return f;return-1};goog.array.findRight=function(a,b,c){b=goog.array.findIndexRight(a,b,c);return 0>b?null:goog.isString(a)?a.charAt(b):a[b]};
                +goog.array.findIndexRight=function(a,b,c){for(var d=a.length,e=goog.isString(a)?a.split(""):a,d=d-1;0<=d;d--)if(d in e&&b.call(c,e[d],d,a))return d;return-1};goog.array.contains=function(a,b){return 0<=goog.array.indexOf(a,b)};goog.array.isEmpty=function(a){return 0==a.length};goog.array.clear=function(a){if(!goog.isArray(a))for(var b=a.length-1;0<=b;b--)delete a[b];a.length=0};goog.array.insert=function(a,b){goog.array.contains(a,b)||a.push(b)};
                +goog.array.insertAt=function(a,b,c){goog.array.splice(a,c,0,b)};goog.array.insertArrayAt=function(a,b,c){goog.partial(goog.array.splice,a,c,0).apply(null,b)};goog.array.insertBefore=function(a,b,c){var d;2==arguments.length||0>(d=goog.array.indexOf(a,c))?a.push(b):goog.array.insertAt(a,b,d)};goog.array.remove=function(a,b){var c=goog.array.indexOf(a,b),d;(d=0<=c)&&goog.array.removeAt(a,c);return d};
                +goog.array.removeLast=function(a,b){var c=goog.array.lastIndexOf(a,b);return 0<=c?(goog.array.removeAt(a,c),!0):!1};goog.array.removeAt=function(a,b){goog.asserts.assert(null!=a.length);return 1==Array.prototype.splice.call(a,b,1).length};goog.array.removeIf=function(a,b,c){b=goog.array.findIndex(a,b,c);return 0<=b?(goog.array.removeAt(a,b),!0):!1};goog.array.removeAllIf=function(a,b,c){var d=0;goog.array.forEachRight(a,function(e,f){b.call(c,e,f,a)&&goog.array.removeAt(a,f)&&d++});return d};
                +goog.array.concat=function(a){return Array.prototype.concat.apply([],arguments)};goog.array.join=function(a){return Array.prototype.concat.apply([],arguments)};goog.array.toArray=function(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};goog.array.clone=goog.array.toArray;goog.array.extend=function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(goog.isArrayLike(d)){var e=a.length||0,f=d.length||0;a.length=e+f;for(var g=0;g<f;g++)a[e+g]=d[g]}else a.push(d)}};
                +goog.array.splice=function(a,b,c,d){goog.asserts.assert(null!=a.length);return Array.prototype.splice.apply(a,goog.array.slice(arguments,1))};goog.array.slice=function(a,b,c){goog.asserts.assert(null!=a.length);return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};
                +goog.array.removeDuplicates=function(a,b,c){b=b||a;var d=function(a){return goog.isObject(a)?"o"+goog.getUid(a):(typeof a).charAt(0)+a};c=c||d;for(var d={},e=0,f=0;f<a.length;){var g=a[f++],h=c(g);Object.prototype.hasOwnProperty.call(d,h)||(d[h]=!0,b[e++]=g)}b.length=e};goog.array.binarySearch=function(a,b,c){return goog.array.binarySearch_(a,c||goog.array.defaultCompare,!1,b)};goog.array.binarySelect=function(a,b,c){return goog.array.binarySearch_(a,b,!0,void 0,c)};
                +goog.array.binarySearch_=function(a,b,c,d,e){for(var f=0,g=a.length,h;f<g;){var k=f+g>>1;var l=c?b.call(e,a[k],k,a):b(d,a[k]);0<l?f=k+1:(g=k,h=!l)}return h?f:~f};goog.array.sort=function(a,b){a.sort(b||goog.array.defaultCompare)};goog.array.stableSort=function(a,b){for(var c=Array(a.length),d=0;d<a.length;d++)c[d]={index:d,value:a[d]};var e=b||goog.array.defaultCompare;goog.array.sort(c,function(a,b){return e(a.value,b.value)||a.index-b.index});for(d=0;d<a.length;d++)a[d]=c[d].value};
                +goog.array.sortByKey=function(a,b,c){var d=c||goog.array.defaultCompare;goog.array.sort(a,function(a,c){return d(b(a),b(c))})};goog.array.sortObjectsByKey=function(a,b,c){goog.array.sortByKey(a,function(a){return a[b]},c)};goog.array.isSorted=function(a,b,c){b=b||goog.array.defaultCompare;for(var d=1;d<a.length;d++){var e=b(a[d-1],a[d]);if(0<e||0==e&&c)return!1}return!0};
                +goog.array.equals=function(a,b,c){if(!goog.isArrayLike(a)||!goog.isArrayLike(b)||a.length!=b.length)return!1;var d=a.length;c=c||goog.array.defaultCompareEquality;for(var e=0;e<d;e++)if(!c(a[e],b[e]))return!1;return!0};goog.array.compare3=function(a,b,c){c=c||goog.array.defaultCompare;for(var d=Math.min(a.length,b.length),e=0;e<d;e++){var f=c(a[e],b[e]);if(0!=f)return f}return goog.array.defaultCompare(a.length,b.length)};goog.array.defaultCompare=function(a,b){return a>b?1:a<b?-1:0};
                +goog.array.inverseDefaultCompare=function(a,b){return-goog.array.defaultCompare(a,b)};goog.array.defaultCompareEquality=function(a,b){return a===b};goog.array.binaryInsert=function(a,b,c){c=goog.array.binarySearch(a,b,c);return 0>c?(goog.array.insertAt(a,b,-(c+1)),!0):!1};goog.array.binaryRemove=function(a,b,c){b=goog.array.binarySearch(a,b,c);return 0<=b?goog.array.removeAt(a,b):!1};
                +goog.array.bucket=function(a,b,c){for(var d={},e=0;e<a.length;e++){var f=a[e],g=b.call(c,f,e,a);goog.isDef(g)&&(d[g]||(d[g]=[])).push(f)}return d};goog.array.toObject=function(a,b,c){var d={};goog.array.forEach(a,function(e,f){d[b.call(c,e,f,a)]=e});return d};goog.array.range=function(a,b,c){var d=[],e=0,f=a;c=c||1;void 0!==b&&(e=a,f=b);if(0>c*(f-e))return[];if(0<c)for(a=e;a<f;a+=c)d.push(a);else for(a=e;a>f;a+=c)d.push(a);return d};
                +goog.array.repeat=function(a,b){for(var c=[],d=0;d<b;d++)c[d]=a;return c};goog.array.flatten=function(a){for(var b=[],c=0;c<arguments.length;c++){var d=arguments[c];if(goog.isArray(d))for(var e=0;e<d.length;e+=8192)for(var f=goog.array.slice(d,e,e+8192),f=goog.array.flatten.apply(null,f),g=0;g<f.length;g++)b.push(f[g]);else b.push(d)}return b};
                +goog.array.rotate=function(a,b){goog.asserts.assert(null!=a.length);a.length&&(b%=a.length,0<b?Array.prototype.unshift.apply(a,a.splice(-b,b)):0>b&&Array.prototype.push.apply(a,a.splice(0,-b)));return a};goog.array.moveItem=function(a,b,c){goog.asserts.assert(0<=b&&b<a.length);goog.asserts.assert(0<=c&&c<a.length);b=Array.prototype.splice.call(a,b,1);Array.prototype.splice.call(a,c,0,b[0])};
                +goog.array.zip=function(a){if(!arguments.length)return[];for(var b=[],c=arguments[0].length,d=1;d<arguments.length;d++)arguments[d].length<c&&(c=arguments[d].length);for(d=0;d<c;d++){for(var e=[],f=0;f<arguments.length;f++)e.push(arguments[f][d]);b.push(e)}return b};goog.array.shuffle=function(a,b){for(var c=b||Math.random,d=a.length-1;0<d;d--){var e=Math.floor(c()*(d+1)),f=a[d];a[d]=a[e];a[e]=f}};goog.array.copyByIndex=function(a,b){var c=[];goog.array.forEach(b,function(b){c.push(a[b])});return c};
                +goog.array.concatMap=function(a,b,c){return goog.array.concat.apply([],goog.array.map(a,b,c))};goog.math={};goog.math.randomInt=function(a){return Math.floor(Math.random()*a)};goog.math.uniformRandom=function(a,b){return a+Math.random()*(b-a)};goog.math.clamp=function(a,b,c){return Math.min(Math.max(a,b),c)};goog.math.modulo=function(a,b){var c=a%b;return 0>c*b?c+b:c};goog.math.lerp=function(a,b,c){return a+c*(b-a)};goog.math.nearlyEquals=function(a,b,c){return Math.abs(a-b)<=(c||1E-6)};goog.math.standardAngle=function(a){return goog.math.modulo(a,360)};
                +goog.math.standardAngleInRadians=function(a){return goog.math.modulo(a,2*Math.PI)};goog.math.toRadians=function(a){return a*Math.PI/180};goog.math.toDegrees=function(a){return 180*a/Math.PI};goog.math.angleDx=function(a,b){return b*Math.cos(goog.math.toRadians(a))};goog.math.angleDy=function(a,b){return b*Math.sin(goog.math.toRadians(a))};goog.math.angle=function(a,b,c,d){return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(d-b,c-a)))};
                +goog.math.angleDifference=function(a,b){var c=goog.math.standardAngle(b)-goog.math.standardAngle(a);180<c?c-=360:-180>=c&&(c=360+c);return c};goog.math.sign=function(a){return 0<a?1:0>a?-1:a};
                +goog.math.longestCommonSubsequence=function(a,b,c,d){c=c||function(a,b){return a==b};d=d||function(b,c){return a[b]};for(var e=a.length,f=b.length,g=[],h=0;h<e+1;h++)g[h]=[],g[h][0]=0;for(var k=0;k<f+1;k++)g[0][k]=0;for(h=1;h<=e;h++)for(k=1;k<=f;k++)c(a[h-1],b[k-1])?g[h][k]=g[h-1][k-1]+1:g[h][k]=Math.max(g[h-1][k],g[h][k-1]);for(var l=[],h=e,k=f;0<h&&0<k;)c(a[h-1],b[k-1])?(l.unshift(d(h-1,k-1)),h--,k--):g[h-1][k]>g[h][k-1]?h--:k--;return l};
                +goog.math.sum=function(a){return goog.array.reduce(arguments,function(a,c){return a+c},0)};goog.math.average=function(a){return goog.math.sum.apply(null,arguments)/arguments.length};goog.math.sampleVariance=function(a){var b=arguments.length;if(2>b)return 0;var c=goog.math.average.apply(null,arguments);return goog.math.sum.apply(null,goog.array.map(arguments,function(a){return Math.pow(a-c,2)}))/(b-1)};goog.math.standardDeviation=function(a){return Math.sqrt(goog.math.sampleVariance.apply(null,arguments))};
                +goog.math.isInt=function(a){return isFinite(a)&&0==a%1};goog.math.isFiniteNumber=function(a){return isFinite(a)};goog.math.isNegativeZero=function(a){return 0==a&&0>1/a};goog.math.log10Floor=function(a){if(0<a){var b=Math.round(Math.log(a)*Math.LOG10E);return b-(parseFloat("1e"+b)>a?1:0)}return 0==a?-Infinity:NaN};goog.math.safeFloor=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.floor(a+(b||2E-15))};
                +goog.math.safeCeil=function(a,b){goog.asserts.assert(!goog.isDef(b)||0<b);return Math.ceil(a-(b||2E-15))};goog.math.Coordinate=function(a,b){this.x=goog.isDef(a)?a:0;this.y=goog.isDef(b)?b:0};goog.math.Coordinate.prototype.clone=function(){return new goog.math.Coordinate(this.x,this.y)};goog.DEBUG&&(goog.math.Coordinate.prototype.toString=function(){return"("+this.x+", "+this.y+")"});goog.math.Coordinate.prototype.equals=function(a){return a instanceof goog.math.Coordinate&&goog.math.Coordinate.equals(this,a)};goog.math.Coordinate.equals=function(a,b){return a==b?!0:a&&b?a.x==b.x&&a.y==b.y:!1};
                +goog.math.Coordinate.distance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)};goog.math.Coordinate.magnitude=function(a){return Math.sqrt(a.x*a.x+a.y*a.y)};goog.math.Coordinate.azimuth=function(a){return goog.math.angle(0,0,a.x,a.y)};goog.math.Coordinate.squaredDistance=function(a,b){var c=a.x-b.x,d=a.y-b.y;return c*c+d*d};goog.math.Coordinate.difference=function(a,b){return new goog.math.Coordinate(a.x-b.x,a.y-b.y)};
                +goog.math.Coordinate.sum=function(a,b){return new goog.math.Coordinate(a.x+b.x,a.y+b.y)};goog.math.Coordinate.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};goog.math.Coordinate.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};goog.math.Coordinate.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};
                +goog.math.Coordinate.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.x+=a.x,this.y+=a.y):(this.x+=Number(a),goog.isNumber(b)&&(this.y+=b));return this};goog.math.Coordinate.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.x*=a;this.y*=c;return this};goog.math.Coordinate.prototype.rotateRadians=function(a,b){var c=b||new goog.math.Coordinate(0,0),d=this.x,e=this.y,f=Math.cos(a),g=Math.sin(a);this.x=(d-c.x)*f-(e-c.y)*g+c.x;this.y=(d-c.x)*g+(e-c.y)*f+c.y};
                +goog.math.Coordinate.prototype.rotateDegrees=function(a,b){this.rotateRadians(goog.math.toRadians(a),b)};goog.labs={};goog.labs.userAgent={};goog.labs.userAgent.util={};goog.labs.userAgent.util.getNativeUserAgentString_=function(){var a=goog.labs.userAgent.util.getNavigator_();return a&&(a=a.userAgent)?a:""};goog.labs.userAgent.util.getNavigator_=function(){return goog.global.navigator};goog.labs.userAgent.util.userAgent_=goog.labs.userAgent.util.getNativeUserAgentString_();goog.labs.userAgent.util.setUserAgent=function(a){goog.labs.userAgent.util.userAgent_=a||goog.labs.userAgent.util.getNativeUserAgentString_()};
                +goog.labs.userAgent.util.getUserAgent=function(){return goog.labs.userAgent.util.userAgent_};goog.labs.userAgent.util.matchUserAgent=function(a){var b=goog.labs.userAgent.util.getUserAgent();return goog.string.contains(b,a)};goog.labs.userAgent.util.matchUserAgentIgnoreCase=function(a){var b=goog.labs.userAgent.util.getUserAgent();return goog.string.caseInsensitiveContains(b,a)};
                +goog.labs.userAgent.util.extractVersionTuples=function(a){for(var b=RegExp("(\\w[\\w ]+)/([^\\s]+)\\s*(?:\\((.*?)\\))?","g"),c=[],d;d=b.exec(a);)c.push([d[1],d[2],d[3]||void 0]);return c};goog.object={};goog.object.is=function(a,b){return a===b?0!==a||1/a===1/b:a!==a&&b!==b};goog.object.forEach=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)};goog.object.filter=function(a,b,c){var d={},e;for(e in a)b.call(c,a[e],e,a)&&(d[e]=a[e]);return d};goog.object.map=function(a,b,c){var d={},e;for(e in a)d[e]=b.call(c,a[e],e,a);return d};goog.object.some=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return!0;return!1};
                +goog.object.every=function(a,b,c){for(var d in a)if(!b.call(c,a[d],d,a))return!1;return!0};goog.object.getCount=function(a){var b=0,c;for(c in a)b++;return b};goog.object.getAnyKey=function(a){for(var b in a)return b};goog.object.getAnyValue=function(a){for(var b in a)return a[b]};goog.object.contains=function(a,b){return goog.object.containsValue(a,b)};goog.object.getValues=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};
                +goog.object.getKeys=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};goog.object.getValueByKeys=function(a,b){for(var c=goog.isArrayLike(b),d=c?b:arguments,c=c?0:1;c<d.length&&(a=a[d[c]],goog.isDef(a));c++);return a};goog.object.containsKey=function(a,b){return null!==a&&b in a};goog.object.containsValue=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};goog.object.findKey=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};
                +goog.object.findValue=function(a,b,c){return(b=goog.object.findKey(a,b,c))&&a[b]};goog.object.isEmpty=function(a){for(var b in a)return!1;return!0};goog.object.clear=function(a){for(var b in a)delete a[b]};goog.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};goog.object.add=function(a,b,c){if(null!==a&&b in a)throw Error('The object already contains the key "'+b+'"');goog.object.set(a,b,c)};goog.object.get=function(a,b,c){return null!==a&&b in a?a[b]:c};
                +goog.object.set=function(a,b,c){a[b]=c};goog.object.setIfUndefined=function(a,b,c){return b in a?a[b]:a[b]=c};goog.object.setWithReturnValueIfNotSet=function(a,b,c){if(b in a)return a[b];c=c();return a[b]=c};goog.object.equals=function(a,b){for(var c in a)if(!(c in b)||a[c]!==b[c])return!1;for(c in b)if(!(c in a))return!1;return!0};goog.object.clone=function(a){var b={},c;for(c in a)b[c]=a[c];return b};
                +goog.object.unsafeClone=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if(goog.isFunction(a.clone))return a.clone();var b="array"==b?[]:{},c;for(c in a)b[c]=goog.object.unsafeClone(a[c]);return b}return a};goog.object.transpose=function(a){var b={},c;for(c in a)b[a[c]]=c;return b};goog.object.PROTOTYPE_FIELDS_="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
                +goog.object.extend=function(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<goog.object.PROTOTYPE_FIELDS_.length;f++)c=goog.object.PROTOTYPE_FIELDS_[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};
                +goog.object.create=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.create.apply(null,arguments[0]);if(b%2)throw Error("Uneven number of arguments");for(var c={},d=0;d<b;d+=2)c[arguments[d]]=arguments[d+1];return c};goog.object.createSet=function(a){var b=arguments.length;if(1==b&&goog.isArray(arguments[0]))return goog.object.createSet.apply(null,arguments[0]);for(var c={},d=0;d<b;d++)c[arguments[d]]=!0;return c};
                +goog.object.createImmutableView=function(a){var b=a;Object.isFrozen&&!Object.isFrozen(a)&&(b=Object.create(a),Object.freeze(b));return b};goog.object.isImmutableView=function(a){return!!Object.isFrozen&&Object.isFrozen(a)};
                +goog.object.getAllPropertyNames=function(a,b,c){if(!a)return[];if(!Object.getOwnPropertyNames||!Object.getPrototypeOf)return goog.object.getKeys(a);for(var d={};a&&(a!==Object.prototype||b)&&(a!==Function.prototype||c);){for(var e=Object.getOwnPropertyNames(a),f=0;f<e.length;f++)d[e[f]]=!0;a=Object.getPrototypeOf(a)}return goog.object.getKeys(d)};goog.labs.userAgent.browser={};goog.labs.userAgent.browser.matchOpera_=function(){return goog.labs.userAgent.util.matchUserAgent("Opera")};goog.labs.userAgent.browser.matchIE_=function(){return goog.labs.userAgent.util.matchUserAgent("Trident")||goog.labs.userAgent.util.matchUserAgent("MSIE")};goog.labs.userAgent.browser.matchEdge_=function(){return goog.labs.userAgent.util.matchUserAgent("Edge")};goog.labs.userAgent.browser.matchFirefox_=function(){return goog.labs.userAgent.util.matchUserAgent("Firefox")};
                +goog.labs.userAgent.browser.matchSafari_=function(){return goog.labs.userAgent.util.matchUserAgent("Safari")&&!(goog.labs.userAgent.browser.matchChrome_()||goog.labs.userAgent.browser.matchCoast_()||goog.labs.userAgent.browser.matchOpera_()||goog.labs.userAgent.browser.matchEdge_()||goog.labs.userAgent.browser.isSilk()||goog.labs.userAgent.util.matchUserAgent("Android"))};goog.labs.userAgent.browser.matchCoast_=function(){return goog.labs.userAgent.util.matchUserAgent("Coast")};
                +goog.labs.userAgent.browser.matchIosWebview_=function(){return(goog.labs.userAgent.util.matchUserAgent("iPad")||goog.labs.userAgent.util.matchUserAgent("iPhone"))&&!goog.labs.userAgent.browser.matchSafari_()&&!goog.labs.userAgent.browser.matchChrome_()&&!goog.labs.userAgent.browser.matchCoast_()&&goog.labs.userAgent.util.matchUserAgent("AppleWebKit")};
                +goog.labs.userAgent.browser.matchChrome_=function(){return(goog.labs.userAgent.util.matchUserAgent("Chrome")||goog.labs.userAgent.util.matchUserAgent("CriOS"))&&!goog.labs.userAgent.browser.matchEdge_()};goog.labs.userAgent.browser.matchAndroidBrowser_=function(){return goog.labs.userAgent.util.matchUserAgent("Android")&&!(goog.labs.userAgent.browser.isChrome()||goog.labs.userAgent.browser.isFirefox()||goog.labs.userAgent.browser.isOpera()||goog.labs.userAgent.browser.isSilk())};
                +goog.labs.userAgent.browser.isOpera=goog.labs.userAgent.browser.matchOpera_;goog.labs.userAgent.browser.isIE=goog.labs.userAgent.browser.matchIE_;goog.labs.userAgent.browser.isEdge=goog.labs.userAgent.browser.matchEdge_;goog.labs.userAgent.browser.isFirefox=goog.labs.userAgent.browser.matchFirefox_;goog.labs.userAgent.browser.isSafari=goog.labs.userAgent.browser.matchSafari_;goog.labs.userAgent.browser.isCoast=goog.labs.userAgent.browser.matchCoast_;goog.labs.userAgent.browser.isIosWebview=goog.labs.userAgent.browser.matchIosWebview_;
                +goog.labs.userAgent.browser.isChrome=goog.labs.userAgent.browser.matchChrome_;goog.labs.userAgent.browser.isAndroidBrowser=goog.labs.userAgent.browser.matchAndroidBrowser_;goog.labs.userAgent.browser.isSilk=function(){return goog.labs.userAgent.util.matchUserAgent("Silk")};
                +goog.labs.userAgent.browser.getVersion=function(){function a(a){a=goog.array.find(a,d);return c[a]||""}var b=goog.labs.userAgent.util.getUserAgent();if(goog.labs.userAgent.browser.isIE())return goog.labs.userAgent.browser.getIEVersion_(b);var b=goog.labs.userAgent.util.extractVersionTuples(b),c={};goog.array.forEach(b,function(a){c[a[0]]=a[1]});var d=goog.partial(goog.object.containsKey,c);return goog.labs.userAgent.browser.isOpera()?a(["Version","Opera"]):goog.labs.userAgent.browser.isEdge()?a(["Edge"]):
                +goog.labs.userAgent.browser.isChrome()?a(["Chrome","CriOS"]):(b=b[2])&&b[1]||""};goog.labs.userAgent.browser.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(),a)};
                +goog.labs.userAgent.browser.getIEVersion_=function(a){var b=/rv: *([\d\.]*)/.exec(a);if(b&&b[1])return b[1];var b="",c=/MSIE +([\d\.]+)/.exec(a);if(c&&c[1])if(a=/Trident\/(\d.\d)/.exec(a),"7.0"==c[1])if(a&&a[1])switch(a[1]){case "4.0":b="8.0";break;case "5.0":b="9.0";break;case "6.0":b="10.0";break;case "7.0":b="11.0"}else b="7.0";else b=c[1];return b};goog.labs.userAgent.engine={};goog.labs.userAgent.engine.isPresto=function(){return goog.labs.userAgent.util.matchUserAgent("Presto")};goog.labs.userAgent.engine.isTrident=function(){return goog.labs.userAgent.util.matchUserAgent("Trident")||goog.labs.userAgent.util.matchUserAgent("MSIE")};goog.labs.userAgent.engine.isEdge=function(){return goog.labs.userAgent.util.matchUserAgent("Edge")};
                +goog.labs.userAgent.engine.isWebKit=function(){return goog.labs.userAgent.util.matchUserAgentIgnoreCase("WebKit")&&!goog.labs.userAgent.engine.isEdge()};goog.labs.userAgent.engine.isGecko=function(){return goog.labs.userAgent.util.matchUserAgent("Gecko")&&!goog.labs.userAgent.engine.isWebKit()&&!goog.labs.userAgent.engine.isTrident()&&!goog.labs.userAgent.engine.isEdge()};
                +goog.labs.userAgent.engine.getVersion=function(){var a=goog.labs.userAgent.util.getUserAgent();if(a){var a=goog.labs.userAgent.util.extractVersionTuples(a),b=goog.labs.userAgent.engine.getEngineTuple_(a);if(b)return"Gecko"==b[0]?goog.labs.userAgent.engine.getVersionForKey_(a,"Firefox"):b[1];var a=a[0],c;if(a&&(c=a[2])&&(c=/Trident\/([^\s;]+)/.exec(c)))return c[1]}return""};
                +goog.labs.userAgent.engine.getEngineTuple_=function(a){if(!goog.labs.userAgent.engine.isEdge())return a[1];for(var b=0;b<a.length;b++){var c=a[b];if("Edge"==c[0])return c}};goog.labs.userAgent.engine.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(),a)};goog.labs.userAgent.engine.getVersionForKey_=function(a,b){var c=goog.array.find(a,function(a){return b==a[0]});return c&&c[1]||""};goog.labs.userAgent.platform={};goog.labs.userAgent.platform.isAndroid=function(){return goog.labs.userAgent.util.matchUserAgent("Android")};goog.labs.userAgent.platform.isIpod=function(){return goog.labs.userAgent.util.matchUserAgent("iPod")};goog.labs.userAgent.platform.isIphone=function(){return goog.labs.userAgent.util.matchUserAgent("iPhone")&&!goog.labs.userAgent.util.matchUserAgent("iPod")&&!goog.labs.userAgent.util.matchUserAgent("iPad")};goog.labs.userAgent.platform.isIpad=function(){return goog.labs.userAgent.util.matchUserAgent("iPad")};
                +goog.labs.userAgent.platform.isIos=function(){return goog.labs.userAgent.platform.isIphone()||goog.labs.userAgent.platform.isIpad()||goog.labs.userAgent.platform.isIpod()};goog.labs.userAgent.platform.isMacintosh=function(){return goog.labs.userAgent.util.matchUserAgent("Macintosh")};goog.labs.userAgent.platform.isLinux=function(){return goog.labs.userAgent.util.matchUserAgent("Linux")};goog.labs.userAgent.platform.isWindows=function(){return goog.labs.userAgent.util.matchUserAgent("Windows")};
                +goog.labs.userAgent.platform.isChromeOS=function(){return goog.labs.userAgent.util.matchUserAgent("CrOS")};
                +goog.labs.userAgent.platform.getVersion=function(){var a=goog.labs.userAgent.util.getUserAgent();var b="";goog.labs.userAgent.platform.isWindows()?(b=/Windows (?:NT|Phone) ([0-9.]+)/,b=(a=b.exec(a))?a[1]:"0.0"):goog.labs.userAgent.platform.isIos()?(b=/(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/,b=(a=b.exec(a))&&a[1].replace(/_/g,".")):goog.labs.userAgent.platform.isMacintosh()?(b=/Mac OS X ([0-9_.]+)/,b=(a=b.exec(a))?a[1].replace(/_/g,"."):"10"):goog.labs.userAgent.platform.isAndroid()?(b=/Android\s+([^\);]+)(\)|;)/,
                +b=(a=b.exec(a))&&a[1]):goog.labs.userAgent.platform.isChromeOS()&&(b=/(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/,b=(a=b.exec(a))&&a[1]);return b||""};goog.labs.userAgent.platform.isVersionOrHigher=function(a){return 0<=goog.string.compareVersions(goog.labs.userAgent.platform.getVersion(),a)};goog.reflect={};goog.reflect.object=function(a,b){return b};goog.reflect.objectProperty=function(a,b){return a};goog.reflect.sinkValue=function(a){goog.reflect.sinkValue[" "](a);return a};goog.reflect.sinkValue[" "]=goog.nullFunction;goog.reflect.canAccessProperty=function(a,b){try{return goog.reflect.sinkValue(a[b]),!0}catch(c){}return!1};goog.reflect.cache=function(a,b,c,d){d=d?d(b):b;return Object.prototype.hasOwnProperty.call(a,d)?a[d]:a[d]=c(b)};goog.userAgent={};goog.userAgent.ASSUME_IE=!1;goog.userAgent.ASSUME_EDGE=!1;goog.userAgent.ASSUME_GECKO=!1;goog.userAgent.ASSUME_WEBKIT=!1;goog.userAgent.ASSUME_MOBILE_WEBKIT=!1;goog.userAgent.ASSUME_OPERA=!1;goog.userAgent.ASSUME_ANY_VERSION=!1;goog.userAgent.BROWSER_KNOWN_=goog.userAgent.ASSUME_IE||goog.userAgent.ASSUME_EDGE||goog.userAgent.ASSUME_GECKO||goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_OPERA;goog.userAgent.getUserAgentString=function(){return goog.labs.userAgent.util.getUserAgent()};
                +goog.userAgent.getNavigator=function(){return goog.global.navigator||null};goog.userAgent.OPERA=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_OPERA:goog.labs.userAgent.browser.isOpera();goog.userAgent.IE=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_IE:goog.labs.userAgent.browser.isIE();goog.userAgent.EDGE=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_EDGE:goog.labs.userAgent.engine.isEdge();goog.userAgent.EDGE_OR_IE=goog.userAgent.EDGE||goog.userAgent.IE;
                +goog.userAgent.GECKO=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_GECKO:goog.labs.userAgent.engine.isGecko();goog.userAgent.WEBKIT=goog.userAgent.BROWSER_KNOWN_?goog.userAgent.ASSUME_WEBKIT||goog.userAgent.ASSUME_MOBILE_WEBKIT:goog.labs.userAgent.engine.isWebKit();goog.userAgent.isMobile_=function(){return goog.userAgent.WEBKIT&&goog.labs.userAgent.util.matchUserAgent("Mobile")};goog.userAgent.MOBILE=goog.userAgent.ASSUME_MOBILE_WEBKIT||goog.userAgent.isMobile_();goog.userAgent.SAFARI=goog.userAgent.WEBKIT;
                +goog.userAgent.determinePlatform_=function(){var a=goog.userAgent.getNavigator();return a&&a.platform||""};goog.userAgent.PLATFORM=goog.userAgent.determinePlatform_();goog.userAgent.ASSUME_MAC=!1;goog.userAgent.ASSUME_WINDOWS=!1;goog.userAgent.ASSUME_LINUX=!1;goog.userAgent.ASSUME_X11=!1;goog.userAgent.ASSUME_ANDROID=!1;goog.userAgent.ASSUME_IPHONE=!1;goog.userAgent.ASSUME_IPAD=!1;goog.userAgent.ASSUME_IPOD=!1;
                +goog.userAgent.PLATFORM_KNOWN_=goog.userAgent.ASSUME_MAC||goog.userAgent.ASSUME_WINDOWS||goog.userAgent.ASSUME_LINUX||goog.userAgent.ASSUME_X11||goog.userAgent.ASSUME_ANDROID||goog.userAgent.ASSUME_IPHONE||goog.userAgent.ASSUME_IPAD||goog.userAgent.ASSUME_IPOD;goog.userAgent.MAC=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_MAC:goog.labs.userAgent.platform.isMacintosh();goog.userAgent.WINDOWS=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_WINDOWS:goog.labs.userAgent.platform.isWindows();
                +goog.userAgent.isLegacyLinux_=function(){return goog.labs.userAgent.platform.isLinux()||goog.labs.userAgent.platform.isChromeOS()};goog.userAgent.LINUX=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_LINUX:goog.userAgent.isLegacyLinux_();goog.userAgent.isX11_=function(){var a=goog.userAgent.getNavigator();return!!a&&goog.string.contains(a.appVersion||"","X11")};goog.userAgent.X11=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_X11:goog.userAgent.isX11_();
                +goog.userAgent.ANDROID=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_ANDROID:goog.labs.userAgent.platform.isAndroid();goog.userAgent.IPHONE=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPHONE:goog.labs.userAgent.platform.isIphone();goog.userAgent.IPAD=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPAD:goog.labs.userAgent.platform.isIpad();goog.userAgent.IPOD=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPOD:goog.labs.userAgent.platform.isIpod();
                +goog.userAgent.IOS=goog.userAgent.PLATFORM_KNOWN_?goog.userAgent.ASSUME_IPHONE||goog.userAgent.ASSUME_IPAD||goog.userAgent.ASSUME_IPOD:goog.labs.userAgent.platform.isIos();goog.userAgent.determineVersion_=function(){var a="",b=goog.userAgent.getVersionRegexResult_();b&&(a=b?b[1]:"");return goog.userAgent.IE&&(b=goog.userAgent.getDocumentMode_(),null!=b&&b>parseFloat(a))?String(b):a};
                +goog.userAgent.getVersionRegexResult_=function(){var a=goog.userAgent.getUserAgentString();if(goog.userAgent.GECKO)return/rv\:([^\);]+)(\)|;)/.exec(a);if(goog.userAgent.EDGE)return/Edge\/([\d\.]+)/.exec(a);if(goog.userAgent.IE)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(goog.userAgent.WEBKIT)return/WebKit\/(\S+)/.exec(a);if(goog.userAgent.OPERA)return/(?:Version)[ \/]?(\S+)/.exec(a)};goog.userAgent.getDocumentMode_=function(){var a=goog.global.document;return a?a.documentMode:void 0};
                +goog.userAgent.VERSION=goog.userAgent.determineVersion_();goog.userAgent.compare=function(a,b){return goog.string.compareVersions(a,b)};goog.userAgent.isVersionOrHigherCache_={};goog.userAgent.isVersionOrHigher=function(a){return goog.userAgent.ASSUME_ANY_VERSION||goog.reflect.cache(goog.userAgent.isVersionOrHigherCache_,a,function(){return 0<=goog.string.compareVersions(goog.userAgent.VERSION,a)})};goog.userAgent.isVersion=goog.userAgent.isVersionOrHigher;
                +goog.userAgent.isDocumentModeOrHigher=function(a){return Number(goog.userAgent.DOCUMENT_MODE)>=a};goog.userAgent.isDocumentMode=goog.userAgent.isDocumentModeOrHigher;goog.userAgent.DOCUMENT_MODE=function(){var a=goog.global.document,b=goog.userAgent.getDocumentMode_();if(a&&goog.userAgent.IE)return b||("CSS1Compat"==a.compatMode?parseInt(goog.userAgent.VERSION,10):5)}();goog.Thenable=function(){};goog.Thenable.prototype.then=function(a,b,c){};goog.Thenable.IMPLEMENTED_BY_PROP="$goog_Thenable";goog.Thenable.addImplementation=function(a){a.prototype.then=a.prototype.then;COMPILED?a.prototype[goog.Thenable.IMPLEMENTED_BY_PROP]=!0:a.prototype.$goog_Thenable=!0};goog.Thenable.isImplementedBy=function(a){if(!a)return!1;try{return COMPILED?!!a[goog.Thenable.IMPLEMENTED_BY_PROP]:!!a.$goog_Thenable}catch(b){return!1}};goog.async={};goog.async.FreeList=function(a,b,c){this.limit_=c;this.create_=a;this.reset_=b;this.occupants_=0;this.head_=null};goog.async.FreeList.prototype.get=function(){if(0<this.occupants_){this.occupants_--;var a=this.head_;this.head_=a.next;a.next=null}else a=this.create_();return a};goog.async.FreeList.prototype.put=function(a){this.reset_(a);this.occupants_<this.limit_&&(this.occupants_++,a.next=this.head_,this.head_=a)};goog.async.FreeList.prototype.occupants=function(){return this.occupants_};goog.async.WorkQueue=function(){this.workTail_=this.workHead_=null};goog.async.WorkQueue.DEFAULT_MAX_UNUSED=100;goog.async.WorkQueue.freelist_=new goog.async.FreeList(function(){return new goog.async.WorkItem},function(a){a.reset()},goog.async.WorkQueue.DEFAULT_MAX_UNUSED);goog.async.WorkQueue.prototype.add=function(a,b){var c=this.getUnusedItem_();c.set(a,b);this.workTail_?this.workTail_.next=c:(goog.asserts.assert(!this.workHead_),this.workHead_=c);this.workTail_=c};
                +goog.async.WorkQueue.prototype.remove=function(){var a=null;this.workHead_&&(a=this.workHead_,this.workHead_=this.workHead_.next,this.workHead_||(this.workTail_=null),a.next=null);return a};goog.async.WorkQueue.prototype.returnUnused=function(a){goog.async.WorkQueue.freelist_.put(a)};goog.async.WorkQueue.prototype.getUnusedItem_=function(){return goog.async.WorkQueue.freelist_.get()};goog.async.WorkItem=function(){this.next=this.scope=this.fn=null};
                +goog.async.WorkItem.prototype.set=function(a,b){this.fn=a;this.scope=b;this.next=null};goog.async.WorkItem.prototype.reset=function(){this.next=this.scope=this.fn=null};goog.debug.entryPointRegistry={};goog.debug.EntryPointMonitor=function(){};goog.debug.entryPointRegistry.refList_=[];goog.debug.entryPointRegistry.monitors_=[];goog.debug.entryPointRegistry.monitorsMayExist_=!1;goog.debug.entryPointRegistry.register=function(a){goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length]=a;if(goog.debug.entryPointRegistry.monitorsMayExist_)for(var b=goog.debug.entryPointRegistry.monitors_,c=0;c<b.length;c++)a(goog.bind(b[c].wrap,b[c]))};
                +goog.debug.entryPointRegistry.monitorAll=function(a){goog.debug.entryPointRegistry.monitorsMayExist_=!0;for(var b=goog.bind(a.wrap,a),c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](b);goog.debug.entryPointRegistry.monitors_.push(a)};
                +goog.debug.entryPointRegistry.unmonitorAllIfPossible=function(a){var b=goog.debug.entryPointRegistry.monitors_;goog.asserts.assert(a==b[b.length-1],"Only the most recent monitor can be unwrapped.");a=goog.bind(a.unwrap,a);for(var c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](a);b.length--};goog.dom.HtmlElement=function(){};goog.dom.TagName=function(a){this.tagName_=a};goog.dom.TagName.prototype.toString=function(){return this.tagName_};goog.dom.TagName.A=new goog.dom.TagName("A");goog.dom.TagName.ABBR=new goog.dom.TagName("ABBR");goog.dom.TagName.ACRONYM=new goog.dom.TagName("ACRONYM");goog.dom.TagName.ADDRESS=new goog.dom.TagName("ADDRESS");goog.dom.TagName.APPLET=new goog.dom.TagName("APPLET");goog.dom.TagName.AREA=new goog.dom.TagName("AREA");goog.dom.TagName.ARTICLE=new goog.dom.TagName("ARTICLE");
                +goog.dom.TagName.ASIDE=new goog.dom.TagName("ASIDE");goog.dom.TagName.AUDIO=new goog.dom.TagName("AUDIO");goog.dom.TagName.B=new goog.dom.TagName("B");goog.dom.TagName.BASE=new goog.dom.TagName("BASE");goog.dom.TagName.BASEFONT=new goog.dom.TagName("BASEFONT");goog.dom.TagName.BDI=new goog.dom.TagName("BDI");goog.dom.TagName.BDO=new goog.dom.TagName("BDO");goog.dom.TagName.BIG=new goog.dom.TagName("BIG");goog.dom.TagName.BLOCKQUOTE=new goog.dom.TagName("BLOCKQUOTE");goog.dom.TagName.BODY=new goog.dom.TagName("BODY");
                +goog.dom.TagName.BR=new goog.dom.TagName("BR");goog.dom.TagName.BUTTON=new goog.dom.TagName("BUTTON");goog.dom.TagName.CANVAS=new goog.dom.TagName("CANVAS");goog.dom.TagName.CAPTION=new goog.dom.TagName("CAPTION");goog.dom.TagName.CENTER=new goog.dom.TagName("CENTER");goog.dom.TagName.CITE=new goog.dom.TagName("CITE");goog.dom.TagName.CODE=new goog.dom.TagName("CODE");goog.dom.TagName.COL=new goog.dom.TagName("COL");goog.dom.TagName.COLGROUP=new goog.dom.TagName("COLGROUP");
                +goog.dom.TagName.COMMAND=new goog.dom.TagName("COMMAND");goog.dom.TagName.DATA=new goog.dom.TagName("DATA");goog.dom.TagName.DATALIST=new goog.dom.TagName("DATALIST");goog.dom.TagName.DD=new goog.dom.TagName("DD");goog.dom.TagName.DEL=new goog.dom.TagName("DEL");goog.dom.TagName.DETAILS=new goog.dom.TagName("DETAILS");goog.dom.TagName.DFN=new goog.dom.TagName("DFN");goog.dom.TagName.DIALOG=new goog.dom.TagName("DIALOG");goog.dom.TagName.DIR=new goog.dom.TagName("DIR");goog.dom.TagName.DIV=new goog.dom.TagName("DIV");
                +goog.dom.TagName.DL=new goog.dom.TagName("DL");goog.dom.TagName.DT=new goog.dom.TagName("DT");goog.dom.TagName.EM=new goog.dom.TagName("EM");goog.dom.TagName.EMBED=new goog.dom.TagName("EMBED");goog.dom.TagName.FIELDSET=new goog.dom.TagName("FIELDSET");goog.dom.TagName.FIGCAPTION=new goog.dom.TagName("FIGCAPTION");goog.dom.TagName.FIGURE=new goog.dom.TagName("FIGURE");goog.dom.TagName.FONT=new goog.dom.TagName("FONT");goog.dom.TagName.FOOTER=new goog.dom.TagName("FOOTER");goog.dom.TagName.FORM=new goog.dom.TagName("FORM");
                +goog.dom.TagName.FRAME=new goog.dom.TagName("FRAME");goog.dom.TagName.FRAMESET=new goog.dom.TagName("FRAMESET");goog.dom.TagName.H1=new goog.dom.TagName("H1");goog.dom.TagName.H2=new goog.dom.TagName("H2");goog.dom.TagName.H3=new goog.dom.TagName("H3");goog.dom.TagName.H4=new goog.dom.TagName("H4");goog.dom.TagName.H5=new goog.dom.TagName("H5");goog.dom.TagName.H6=new goog.dom.TagName("H6");goog.dom.TagName.HEAD=new goog.dom.TagName("HEAD");goog.dom.TagName.HEADER=new goog.dom.TagName("HEADER");
                +goog.dom.TagName.HGROUP=new goog.dom.TagName("HGROUP");goog.dom.TagName.HR=new goog.dom.TagName("HR");goog.dom.TagName.HTML=new goog.dom.TagName("HTML");goog.dom.TagName.I=new goog.dom.TagName("I");goog.dom.TagName.IFRAME=new goog.dom.TagName("IFRAME");goog.dom.TagName.IMG=new goog.dom.TagName("IMG");goog.dom.TagName.INPUT=new goog.dom.TagName("INPUT");goog.dom.TagName.INS=new goog.dom.TagName("INS");goog.dom.TagName.ISINDEX=new goog.dom.TagName("ISINDEX");goog.dom.TagName.KBD=new goog.dom.TagName("KBD");
                +goog.dom.TagName.KEYGEN=new goog.dom.TagName("KEYGEN");goog.dom.TagName.LABEL=new goog.dom.TagName("LABEL");goog.dom.TagName.LEGEND=new goog.dom.TagName("LEGEND");goog.dom.TagName.LI=new goog.dom.TagName("LI");goog.dom.TagName.LINK=new goog.dom.TagName("LINK");goog.dom.TagName.MAP=new goog.dom.TagName("MAP");goog.dom.TagName.MARK=new goog.dom.TagName("MARK");goog.dom.TagName.MATH=new goog.dom.TagName("MATH");goog.dom.TagName.MENU=new goog.dom.TagName("MENU");goog.dom.TagName.META=new goog.dom.TagName("META");
                +goog.dom.TagName.METER=new goog.dom.TagName("METER");goog.dom.TagName.NAV=new goog.dom.TagName("NAV");goog.dom.TagName.NOFRAMES=new goog.dom.TagName("NOFRAMES");goog.dom.TagName.NOSCRIPT=new goog.dom.TagName("NOSCRIPT");goog.dom.TagName.OBJECT=new goog.dom.TagName("OBJECT");goog.dom.TagName.OL=new goog.dom.TagName("OL");goog.dom.TagName.OPTGROUP=new goog.dom.TagName("OPTGROUP");goog.dom.TagName.OPTION=new goog.dom.TagName("OPTION");goog.dom.TagName.OUTPUT=new goog.dom.TagName("OUTPUT");
                +goog.dom.TagName.P=new goog.dom.TagName("P");goog.dom.TagName.PARAM=new goog.dom.TagName("PARAM");goog.dom.TagName.PRE=new goog.dom.TagName("PRE");goog.dom.TagName.PROGRESS=new goog.dom.TagName("PROGRESS");goog.dom.TagName.Q=new goog.dom.TagName("Q");goog.dom.TagName.RP=new goog.dom.TagName("RP");goog.dom.TagName.RT=new goog.dom.TagName("RT");goog.dom.TagName.RUBY=new goog.dom.TagName("RUBY");goog.dom.TagName.S=new goog.dom.TagName("S");goog.dom.TagName.SAMP=new goog.dom.TagName("SAMP");
                +goog.dom.TagName.SCRIPT=new goog.dom.TagName("SCRIPT");goog.dom.TagName.SECTION=new goog.dom.TagName("SECTION");goog.dom.TagName.SELECT=new goog.dom.TagName("SELECT");goog.dom.TagName.SMALL=new goog.dom.TagName("SMALL");goog.dom.TagName.SOURCE=new goog.dom.TagName("SOURCE");goog.dom.TagName.SPAN=new goog.dom.TagName("SPAN");goog.dom.TagName.STRIKE=new goog.dom.TagName("STRIKE");goog.dom.TagName.STRONG=new goog.dom.TagName("STRONG");goog.dom.TagName.STYLE=new goog.dom.TagName("STYLE");
                +goog.dom.TagName.SUB=new goog.dom.TagName("SUB");goog.dom.TagName.SUMMARY=new goog.dom.TagName("SUMMARY");goog.dom.TagName.SUP=new goog.dom.TagName("SUP");goog.dom.TagName.SVG=new goog.dom.TagName("SVG");goog.dom.TagName.TABLE=new goog.dom.TagName("TABLE");goog.dom.TagName.TBODY=new goog.dom.TagName("TBODY");goog.dom.TagName.TD=new goog.dom.TagName("TD");goog.dom.TagName.TEMPLATE=new goog.dom.TagName("TEMPLATE");goog.dom.TagName.TEXTAREA=new goog.dom.TagName("TEXTAREA");goog.dom.TagName.TFOOT=new goog.dom.TagName("TFOOT");
                +goog.dom.TagName.TH=new goog.dom.TagName("TH");goog.dom.TagName.THEAD=new goog.dom.TagName("THEAD");goog.dom.TagName.TIME=new goog.dom.TagName("TIME");goog.dom.TagName.TITLE=new goog.dom.TagName("TITLE");goog.dom.TagName.TR=new goog.dom.TagName("TR");goog.dom.TagName.TRACK=new goog.dom.TagName("TRACK");goog.dom.TagName.TT=new goog.dom.TagName("TT");goog.dom.TagName.U=new goog.dom.TagName("U");goog.dom.TagName.UL=new goog.dom.TagName("UL");goog.dom.TagName.VAR=new goog.dom.TagName("VAR");
                +goog.dom.TagName.VIDEO=new goog.dom.TagName("VIDEO");goog.dom.TagName.WBR=new goog.dom.TagName("WBR");goog.functions={};goog.functions.constant=function(a){return function(){return a}};goog.functions.FALSE=goog.functions.constant(!1);goog.functions.TRUE=goog.functions.constant(!0);goog.functions.NULL=goog.functions.constant(null);goog.functions.identity=function(a,b){return a};goog.functions.error=function(a){return function(){throw Error(a);}};goog.functions.fail=function(a){return function(){throw a;}};
                +goog.functions.lock=function(a,b){b=b||0;return function(){return a.apply(this,Array.prototype.slice.call(arguments,0,b))}};goog.functions.nth=function(a){return function(){return arguments[a]}};goog.functions.partialRight=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.push.apply(b,c);return a.apply(this,b)}};goog.functions.withReturnValue=function(a,b){return goog.functions.sequence(a,goog.functions.constant(b))};
                +goog.functions.equalTo=function(a,b){return function(c){return b?a==c:a===c}};goog.functions.compose=function(a,b){var c=arguments,d=c.length;return function(){var a;d&&(a=c[d-1].apply(this,arguments));for(var b=d-2;0<=b;b--)a=c[b].call(this,a);return a}};goog.functions.sequence=function(a){var b=arguments,c=b.length;return function(){for(var a,e=0;e<c;e++)a=b[e].apply(this,arguments);return a}};
                +goog.functions.and=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(!b[a].apply(this,arguments))return!1;return!0}};goog.functions.or=function(a){var b=arguments,c=b.length;return function(){for(var a=0;a<c;a++)if(b[a].apply(this,arguments))return!0;return!1}};goog.functions.not=function(a){return function(){return!a.apply(this,arguments)}};
                +goog.functions.create=function(a,b){var c=function(){};c.prototype=a.prototype;c=new c;a.apply(c,Array.prototype.slice.call(arguments,1));return c};goog.functions.CACHE_RETURN_VALUE=!0;goog.functions.cacheReturnValue=function(a){var b=!1,c;return function(){if(!goog.functions.CACHE_RETURN_VALUE)return a();b||(c=a(),b=!0);return c}};goog.functions.once=function(a){var b=a;return function(){if(b){var a=b;b=null;a()}}};
                +goog.functions.debounce=function(a,b,c){var d=0;return function(e){goog.global.clearTimeout(d);var f=arguments;d=goog.global.setTimeout(function(){a.apply(c,f)},b)}};goog.functions.throttle=function(a,b,c){var d=0,e=!1,f=[],g=function(){d=0;e&&(e=!1,h())},h=function(){d=goog.global.setTimeout(g,b);a.apply(c,f)};return function(a){f=arguments;d?e=!0:h()}};goog.functions.rateLimit=function(a,b,c){var d=0,e=function(){d=0};return function(f){d||(d=goog.global.setTimeout(e,b),a.apply(c,arguments))}};goog.async.throwException=function(a){goog.global.setTimeout(function(){throw a;},0)};goog.async.nextTick=function(a,b,c){var d=a;b&&(d=goog.bind(a,b));d=goog.async.nextTick.wrapCallback_(d);goog.isFunction(goog.global.setImmediate)&&(c||goog.async.nextTick.useSetImmediate_())?goog.global.setImmediate(d):(goog.async.nextTick.setImmediate_||(goog.async.nextTick.setImmediate_=goog.async.nextTick.getSetImmediateEmulator_()),goog.async.nextTick.setImmediate_(d))};
                +goog.async.nextTick.useSetImmediate_=function(){return goog.global.Window&&goog.global.Window.prototype&&!goog.labs.userAgent.browser.isEdge()&&goog.global.Window.prototype.setImmediate==goog.global.setImmediate?!1:!0};
                +goog.async.nextTick.getSetImmediateEmulator_=function(){var a=goog.global.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!goog.labs.userAgent.engine.isPresto()&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var b=a.contentWindow,a=b.document;a.open();a.write("");a.close();var c="callImmediate"+Math.random(),d="file:"==b.location.protocol?"*":b.location.protocol+
                +"//"+b.location.host,a=goog.bind(function(a){if(("*"==d||a.origin==d)&&a.data==c)this.port1.onmessage()},this);b.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){b.postMessage(c,d)}}});if("undefined"!==typeof a&&!goog.labs.userAgent.browser.isIE()){var b=new a,c={},d=c;b.port1.onmessage=function(){if(goog.isDef(c.next)){c=c.next;var a=c.cb;c.cb=null;a()}};return function(a){d.next={cb:a};d=d.next;b.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in
                +document.createElement("SCRIPT")?function(a){var b=document.createElement("SCRIPT");b.onreadystatechange=function(){b.onreadystatechange=null;b.parentNode.removeChild(b);b=null;a();a=null};document.documentElement.appendChild(b)}:function(a){goog.global.setTimeout(a,0)}};goog.async.nextTick.wrapCallback_=goog.functions.identity;goog.debug.entryPointRegistry.register(function(a){goog.async.nextTick.wrapCallback_=a});goog.async.run=function(a,b){goog.async.run.schedule_||goog.async.run.initializeRunner_();goog.async.run.workQueueScheduled_||(goog.async.run.schedule_(),goog.async.run.workQueueScheduled_=!0);goog.async.run.workQueue_.add(a,b)};goog.async.run.initializeRunner_=function(){if(-1!=String(goog.global.Promise).indexOf("[native code]")){var a=goog.global.Promise.resolve(void 0);goog.async.run.schedule_=function(){a.then(goog.async.run.processWorkQueue)}}else goog.async.run.schedule_=function(){goog.async.nextTick(goog.async.run.processWorkQueue)}};
                +goog.async.run.forceNextTick=function(a){goog.async.run.schedule_=function(){goog.async.nextTick(goog.async.run.processWorkQueue);a&&a(goog.async.run.processWorkQueue)}};goog.async.run.workQueueScheduled_=!1;goog.async.run.workQueue_=new goog.async.WorkQueue;goog.DEBUG&&(goog.async.run.resetQueue=function(){goog.async.run.workQueueScheduled_=!1;goog.async.run.workQueue_=new goog.async.WorkQueue});
                +goog.async.run.processWorkQueue=function(){for(var a;a=goog.async.run.workQueue_.remove();){try{a.fn.call(a.scope)}catch(b){goog.async.throwException(b)}goog.async.run.workQueue_.returnUnused(a)}goog.async.run.workQueueScheduled_=!1};goog.promise={};goog.promise.Resolver=function(){};goog.Promise=function(a,b){this.state_=goog.Promise.State_.PENDING;this.result_=void 0;this.callbackEntriesTail_=this.callbackEntries_=this.parent_=null;this.executing_=!1;0<goog.Promise.UNHANDLED_REJECTION_DELAY?this.unhandledRejectionId_=0:0==goog.Promise.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);goog.Promise.LONG_STACK_TRACES&&(this.stack_=[],this.addStackTrace_(Error("created")),this.currentStep_=0);if(a!=goog.nullFunction)try{var c=this;a.call(b,function(a){c.resolve_(goog.Promise.State_.FULFILLED,
                +a)},function(a){if(goog.DEBUG&&!(a instanceof goog.Promise.CancellationError))try{if(a instanceof Error)throw a;throw Error("Promise rejected.");}catch(e){}c.resolve_(goog.Promise.State_.REJECTED,a)})}catch(d){this.resolve_(goog.Promise.State_.REJECTED,d)}};goog.Promise.LONG_STACK_TRACES=!1;goog.Promise.UNHANDLED_REJECTION_DELAY=0;goog.Promise.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3};
                +goog.Promise.CallbackEntry_=function(){this.next=this.context=this.onRejected=this.onFulfilled=this.child=null;this.always=!1};goog.Promise.CallbackEntry_.prototype.reset=function(){this.context=this.onRejected=this.onFulfilled=this.child=null;this.always=!1};goog.Promise.DEFAULT_MAX_UNUSED=100;goog.Promise.freelist_=new goog.async.FreeList(function(){return new goog.Promise.CallbackEntry_},function(a){a.reset()},goog.Promise.DEFAULT_MAX_UNUSED);
                +goog.Promise.getCallbackEntry_=function(a,b,c){var d=goog.Promise.freelist_.get();d.onFulfilled=a;d.onRejected=b;d.context=c;return d};goog.Promise.returnEntry_=function(a){goog.Promise.freelist_.put(a)};goog.Promise.resolve=function(a){if(a instanceof goog.Promise)return a;var b=new goog.Promise(goog.nullFunction);b.resolve_(goog.Promise.State_.FULFILLED,a);return b};goog.Promise.reject=function(a){return new goog.Promise(function(b,c){c(a)})};
                +goog.Promise.resolveThen_=function(a,b,c){goog.Promise.maybeThen_(a,b,c,null)||goog.async.run(goog.partial(b,a))};goog.Promise.race=function(a){return new goog.Promise(function(b,c){a.length||b(void 0);for(var d=0,e;d<a.length;d++)e=a[d],goog.Promise.resolveThen_(e,b,c)})};
                +goog.Promise.all=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d)for(var f=function(a,c){d--;e[a]=c;0==d&&b(e)},g=function(a){c(a)},h=0,k;h<a.length;h++)k=a[h],goog.Promise.resolveThen_(k,goog.partial(f,h),g);else b(e)})};
                +goog.Promise.allSettled=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d)for(var f=function(a,c,f){d--;e[a]=c?{fulfilled:!0,value:f}:{fulfilled:!1,reason:f};0==d&&b(e)},g=0,h;g<a.length;g++)h=a[g],goog.Promise.resolveThen_(h,goog.partial(f,g,!0),goog.partial(f,g,!1));else b(e)})};
                +goog.Promise.firstFulfilled=function(a){return new goog.Promise(function(b,c){var d=a.length,e=[];if(d)for(var f=function(a){b(a)},g=function(a,b){d--;e[a]=b;0==d&&c(e)},h=0,k;h<a.length;h++)k=a[h],goog.Promise.resolveThen_(k,f,goog.partial(g,h));else b(void 0)})};goog.Promise.withResolver=function(){var a,b,c=new goog.Promise(function(c,e){a=c;b=e});return new goog.Promise.Resolver_(c,a,b)};
                +goog.Promise.prototype.then=function(a,b,c){null!=a&&goog.asserts.assertFunction(a,"opt_onFulfilled should be a function.");null!=b&&goog.asserts.assertFunction(b,"opt_onRejected should be a function. Did you pass opt_context as the second argument instead of the third?");goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("then"));return this.addChildPromise_(goog.isFunction(a)?a:null,goog.isFunction(b)?b:null,c)};goog.Thenable.addImplementation(goog.Promise);
                +goog.Promise.prototype.thenVoid=function(a,b,c){null!=a&&goog.asserts.assertFunction(a,"opt_onFulfilled should be a function.");null!=b&&goog.asserts.assertFunction(b,"opt_onRejected should be a function. Did you pass opt_context as the second argument instead of the third?");goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("then"));this.addCallbackEntry_(goog.Promise.getCallbackEntry_(a||goog.nullFunction,b||null,c))};
                +goog.Promise.prototype.thenAlways=function(a,b){goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("thenAlways"));var c=goog.Promise.getCallbackEntry_(a,a,b);c.always=!0;this.addCallbackEntry_(c);return this};goog.Promise.prototype.thenCatch=function(a,b){goog.Promise.LONG_STACK_TRACES&&this.addStackTrace_(Error("thenCatch"));return this.addChildPromise_(null,a,b)};
                +goog.Promise.prototype.cancel=function(a){this.state_==goog.Promise.State_.PENDING&&goog.async.run(function(){var b=new goog.Promise.CancellationError(a);this.cancelInternal_(b)},this)};goog.Promise.prototype.cancelInternal_=function(a){this.state_==goog.Promise.State_.PENDING&&(this.parent_?(this.parent_.cancelChild_(this,a),this.parent_=null):this.resolve_(goog.Promise.State_.REJECTED,a))};
                +goog.Promise.prototype.cancelChild_=function(a,b){if(this.callbackEntries_){for(var c=0,d=null,e=null,f=this.callbackEntries_;f&&(f.always||(c++,f.child==a&&(d=f),!(d&&1<c)));f=f.next)d||(e=f);d&&(this.state_==goog.Promise.State_.PENDING&&1==c?this.cancelInternal_(b):(e?this.removeEntryAfter_(e):this.popEntry_(),this.executeCallback_(d,goog.Promise.State_.REJECTED,b)))}};
                +goog.Promise.prototype.addCallbackEntry_=function(a){this.hasEntry_()||this.state_!=goog.Promise.State_.FULFILLED&&this.state_!=goog.Promise.State_.REJECTED||this.scheduleCallbacks_();this.queueEntry_(a)};
                +goog.Promise.prototype.addChildPromise_=function(a,b,c){var d=goog.Promise.getCallbackEntry_(null,null,null);d.child=new goog.Promise(function(e,f){d.onFulfilled=a?function(b){try{var d=a.call(c,b);e(d)}catch(k){f(k)}}:e;d.onRejected=b?function(a){try{var d=b.call(c,a);!goog.isDef(d)&&a instanceof goog.Promise.CancellationError?f(a):e(d)}catch(k){f(k)}}:f});d.child.parent_=this;this.addCallbackEntry_(d);return d.child};
                +goog.Promise.prototype.unblockAndFulfill_=function(a){goog.asserts.assert(this.state_==goog.Promise.State_.BLOCKED);this.state_=goog.Promise.State_.PENDING;this.resolve_(goog.Promise.State_.FULFILLED,a)};goog.Promise.prototype.unblockAndReject_=function(a){goog.asserts.assert(this.state_==goog.Promise.State_.BLOCKED);this.state_=goog.Promise.State_.PENDING;this.resolve_(goog.Promise.State_.REJECTED,a)};
                +goog.Promise.prototype.resolve_=function(a,b){this.state_==goog.Promise.State_.PENDING&&(this===b&&(a=goog.Promise.State_.REJECTED,b=new TypeError("Promise cannot resolve to itself")),this.state_=goog.Promise.State_.BLOCKED,goog.Promise.maybeThen_(b,this.unblockAndFulfill_,this.unblockAndReject_,this)||(this.result_=b,this.state_=a,this.parent_=null,this.scheduleCallbacks_(),a!=goog.Promise.State_.REJECTED||b instanceof goog.Promise.CancellationError||goog.Promise.addUnhandledRejection_(this,b)))};
                +goog.Promise.maybeThen_=function(a,b,c,d){if(a instanceof goog.Promise)return a.thenVoid(b,c,d),!0;if(goog.Thenable.isImplementedBy(a))return a.then(b,c,d),!0;if(goog.isObject(a))try{var e=a.then;if(goog.isFunction(e))return goog.Promise.tryThen_(a,e,b,c,d),!0}catch(f){return c.call(d,f),!0}return!1};goog.Promise.tryThen_=function(a,b,c,d,e){var f=!1,g=function(a){f||(f=!0,c.call(e,a))},h=function(a){f||(f=!0,d.call(e,a))};try{b.call(a,g,h)}catch(k){h(k)}};
                +goog.Promise.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,goog.async.run(this.executeCallbacks_,this))};goog.Promise.prototype.hasEntry_=function(){return!!this.callbackEntries_};goog.Promise.prototype.queueEntry_=function(a){goog.asserts.assert(null!=a.onFulfilled);this.callbackEntriesTail_?this.callbackEntriesTail_.next=a:this.callbackEntries_=a;this.callbackEntriesTail_=a};
                +goog.Promise.prototype.popEntry_=function(){var a=null;this.callbackEntries_&&(a=this.callbackEntries_,this.callbackEntries_=a.next,a.next=null);this.callbackEntries_||(this.callbackEntriesTail_=null);null!=a&&goog.asserts.assert(null!=a.onFulfilled);return a};goog.Promise.prototype.removeEntryAfter_=function(a){goog.asserts.assert(this.callbackEntries_);goog.asserts.assert(null!=a);a.next==this.callbackEntriesTail_&&(this.callbackEntriesTail_=a);a.next=a.next.next};
                +goog.Promise.prototype.executeCallbacks_=function(){for(var a;a=this.popEntry_();)goog.Promise.LONG_STACK_TRACES&&this.currentStep_++,this.executeCallback_(a,this.state_,this.result_);this.executing_=!1};
                +goog.Promise.prototype.executeCallback_=function(a,b,c){b==goog.Promise.State_.REJECTED&&a.onRejected&&!a.always&&this.removeUnhandledRejection_();if(a.child)a.child.parent_=null,goog.Promise.invokeCallback_(a,b,c);else try{a.always?a.onFulfilled.call(a.context):goog.Promise.invokeCallback_(a,b,c)}catch(d){goog.Promise.handleRejection_.call(null,d)}goog.Promise.returnEntry_(a)};
                +goog.Promise.invokeCallback_=function(a,b,c){b==goog.Promise.State_.FULFILLED?a.onFulfilled.call(a.context,c):a.onRejected&&a.onRejected.call(a.context,c)};goog.Promise.prototype.addStackTrace_=function(a){if(goog.Promise.LONG_STACK_TRACES&&goog.isString(a.stack)){var b=a.stack.split("\n",4)[3];a=a.message;a+=Array(11-a.length).join(" ");this.stack_.push(a+b)}};
                +goog.Promise.prototype.appendLongStack_=function(a){if(goog.Promise.LONG_STACK_TRACES&&a&&goog.isString(a.stack)&&this.stack_.length){for(var b=["Promise trace:"],c=this;c;c=c.parent_){for(var d=this.currentStep_;0<=d;d--)b.push(c.stack_[d]);b.push("Value: ["+(c.state_==goog.Promise.State_.REJECTED?"REJECTED":"FULFILLED")+"] <"+String(c.result_)+">")}a.stack+="\n\n"+b.join("\n")}};
                +goog.Promise.prototype.removeUnhandledRejection_=function(){if(0<goog.Promise.UNHANDLED_REJECTION_DELAY)for(var a=this;a&&a.unhandledRejectionId_;a=a.parent_)goog.global.clearTimeout(a.unhandledRejectionId_),a.unhandledRejectionId_=0;else if(0==goog.Promise.UNHANDLED_REJECTION_DELAY)for(a=this;a&&a.hadUnhandledRejection_;a=a.parent_)a.hadUnhandledRejection_=!1};
                +goog.Promise.addUnhandledRejection_=function(a,b){0<goog.Promise.UNHANDLED_REJECTION_DELAY?a.unhandledRejectionId_=goog.global.setTimeout(function(){a.appendLongStack_(b);goog.Promise.handleRejection_.call(null,b)},goog.Promise.UNHANDLED_REJECTION_DELAY):0==goog.Promise.UNHANDLED_REJECTION_DELAY&&(a.hadUnhandledRejection_=!0,goog.async.run(function(){a.hadUnhandledRejection_&&(a.appendLongStack_(b),goog.Promise.handleRejection_.call(null,b))}))};goog.Promise.handleRejection_=goog.async.throwException;
                +goog.Promise.setUnhandledRejectionHandler=function(a){goog.Promise.handleRejection_=a};goog.Promise.CancellationError=function(a){goog.debug.Error.call(this,a)};goog.inherits(goog.Promise.CancellationError,goog.debug.Error);goog.Promise.CancellationError.prototype.name="cancel";goog.Promise.Resolver_=function(a,b,c){this.promise=a;this.resolve=b;this.reject=c};goog.disposable={};goog.disposable.IDisposable=function(){};goog.disposable.IDisposable.prototype.dispose=goog.abstractMethod;goog.disposable.IDisposable.prototype.isDisposed=goog.abstractMethod;goog.Disposable=function(){goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF&&(goog.Disposable.INCLUDE_STACK_ON_CREATION&&(this.creationStack=Error().stack),goog.Disposable.instances_[goog.getUid(this)]=this);this.disposed_=this.disposed_;this.onDisposeCallbacks_=this.onDisposeCallbacks_};goog.Disposable.MonitoringMode={OFF:0,PERMANENT:1,INTERACTIVE:2};goog.Disposable.MONITORING_MODE=0;goog.Disposable.INCLUDE_STACK_ON_CREATION=!0;goog.Disposable.instances_={};
                +goog.Disposable.getUndisposedObjects=function(){var a=[],b;for(b in goog.Disposable.instances_)goog.Disposable.instances_.hasOwnProperty(b)&&a.push(goog.Disposable.instances_[Number(b)]);return a};goog.Disposable.clearUndisposedObjects=function(){goog.Disposable.instances_={}};goog.Disposable.prototype.disposed_=!1;goog.Disposable.prototype.isDisposed=function(){return this.disposed_};goog.Disposable.prototype.getDisposed=goog.Disposable.prototype.isDisposed;
                +goog.Disposable.prototype.dispose=function(){if(!this.disposed_&&(this.disposed_=!0,this.disposeInternal(),goog.Disposable.MONITORING_MODE!=goog.Disposable.MonitoringMode.OFF)){var a=goog.getUid(this);if(goog.Disposable.MONITORING_MODE==goog.Disposable.MonitoringMode.PERMANENT&&!goog.Disposable.instances_.hasOwnProperty(a))throw Error(this+" did not call the goog.Disposable base constructor or was disposed of after a clearUndisposedObjects call");delete goog.Disposable.instances_[a]}};
                +goog.Disposable.prototype.registerDisposable=function(a){this.addOnDisposeCallback(goog.partial(goog.dispose,a))};goog.Disposable.prototype.addOnDisposeCallback=function(a,b){this.disposed_?goog.isDef(b)?a.call(b):a():(this.onDisposeCallbacks_||(this.onDisposeCallbacks_=[]),this.onDisposeCallbacks_.push(goog.isDef(b)?goog.bind(a,b):a))};goog.Disposable.prototype.disposeInternal=function(){if(this.onDisposeCallbacks_)for(;this.onDisposeCallbacks_.length;)this.onDisposeCallbacks_.shift()()};
                +goog.Disposable.isDisposed=function(a){return a&&"function"==typeof a.isDisposed?a.isDisposed():!1};goog.dispose=function(a){a&&"function"==typeof a.dispose&&a.dispose()};goog.disposeAll=function(a){for(var b=0,c=arguments.length;b<c;++b){var d=arguments[b];goog.isArrayLike(d)?goog.disposeAll.apply(null,d):goog.dispose(d)}};goog.events={};
                +goog.events.BrowserFeature={HAS_W3C_BUTTON:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT||goog.userAgent.isVersionOrHigher("528"),HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9b")||goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("8")||
                +goog.userAgent.OPERA&&goog.userAgent.isVersionOrHigher("9.5")||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("528"),HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO&&!goog.userAgent.isVersionOrHigher("8")||goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),TOUCH_ENABLED:"ontouchstart"in goog.global||!!(goog.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!goog.global.navigator||!goog.global.navigator.msMaxTouchPoints)};goog.events.EventId=function(a){this.id=a};goog.events.EventId.prototype.toString=function(){return this.id};goog.events.Event=function(a,b){this.type=a instanceof goog.events.EventId?String(a):a;this.currentTarget=this.target=b;this.defaultPrevented=this.propagationStopped_=!1;this.returnValue_=!0};goog.events.Event.prototype.stopPropagation=function(){this.propagationStopped_=!0};goog.events.Event.prototype.preventDefault=function(){this.defaultPrevented=!0;this.returnValue_=!1};goog.events.Event.stopPropagation=function(a){a.stopPropagation()};goog.events.Event.preventDefault=function(a){a.preventDefault()};goog.events.getVendorPrefixedName_=function(a){return goog.userAgent.WEBKIT?"webkit"+a:goog.userAgent.OPERA?"o"+a.toLowerCase():a.toLowerCase()};
                +goog.events.EventType={CLICK:"click",RIGHTCLICK:"rightclick",DBLCLICK:"dblclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",MOUSEOVER:"mouseover",MOUSEOUT:"mouseout",MOUSEMOVE:"mousemove",MOUSEENTER:"mouseenter",MOUSELEAVE:"mouseleave",SELECTIONCHANGE:"selectionchange",SELECTSTART:"selectstart",WHEEL:"wheel",KEYPRESS:"keypress",KEYDOWN:"keydown",KEYUP:"keyup",BLUR:"blur",FOCUS:"focus",DEACTIVATE:"deactivate",FOCUSIN:goog.userAgent.IE?"focusin":"DOMFocusIn",FOCUSOUT:goog.userAgent.IE?"focusout":"DOMFocusOut",
                +CHANGE:"change",RESET:"reset",SELECT:"select",SUBMIT:"submit",INPUT:"input",PROPERTYCHANGE:"propertychange",DRAGSTART:"dragstart",DRAG:"drag",DRAGENTER:"dragenter",DRAGOVER:"dragover",DRAGLEAVE:"dragleave",DROP:"drop",DRAGEND:"dragend",TOUCHSTART:"touchstart",TOUCHMOVE:"touchmove",TOUCHEND:"touchend",TOUCHCANCEL:"touchcancel",BEFOREUNLOAD:"beforeunload",CONSOLEMESSAGE:"consolemessage",CONTEXTMENU:"contextmenu",DEVICEMOTION:"devicemotion",DEVICEORIENTATION:"deviceorientation",DOMCONTENTLOADED:"DOMContentLoaded",
                +ERROR:"error",HELP:"help",LOAD:"load",LOSECAPTURE:"losecapture",ORIENTATIONCHANGE:"orientationchange",READYSTATECHANGE:"readystatechange",RESIZE:"resize",SCROLL:"scroll",UNLOAD:"unload",CANPLAY:"canplay",CANPLAYTHROUGH:"canplaythrough",DURATIONCHANGE:"durationchange",EMPTIED:"emptied",ENDED:"ended",LOADEDDATA:"loadeddata",LOADEDMETADATA:"loadedmetadata",PAUSE:"pause",PLAY:"play",PLAYING:"playing",RATECHANGE:"ratechange",SEEKED:"seeked",SEEKING:"seeking",STALLED:"stalled",SUSPEND:"suspend",TIMEUPDATE:"timeupdate",
                +VOLUMECHANGE:"volumechange",WAITING:"waiting",SOURCEOPEN:"sourceopen",SOURCEENDED:"sourceended",SOURCECLOSED:"sourceclosed",ABORT:"abort",UPDATE:"update",UPDATESTART:"updatestart",UPDATEEND:"updateend",HASHCHANGE:"hashchange",PAGEHIDE:"pagehide",PAGESHOW:"pageshow",POPSTATE:"popstate",COPY:"copy",PASTE:"paste",CUT:"cut",BEFORECOPY:"beforecopy",BEFORECUT:"beforecut",BEFOREPASTE:"beforepaste",ONLINE:"online",OFFLINE:"offline",MESSAGE:"message",CONNECT:"connect",INSTALL:"install",ACTIVATE:"activate",
                +FETCH:"fetch",FOREIGNFETCH:"foreignfetch",MESSAGEERROR:"messageerror",STATECHANGE:"statechange",UPDATEFOUND:"updatefound",CONTROLLERCHANGE:"controllerchange",ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"),ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"),ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"),TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"),POINTERDOWN:"pointerdown",POINTERUP:"pointerup",POINTERCANCEL:"pointercancel",
                +POINTERMOVE:"pointermove",POINTEROVER:"pointerover",POINTEROUT:"pointerout",POINTERENTER:"pointerenter",POINTERLEAVE:"pointerleave",GOTPOINTERCAPTURE:"gotpointercapture",LOSTPOINTERCAPTURE:"lostpointercapture",MSGESTURECHANGE:"MSGestureChange",MSGESTUREEND:"MSGestureEnd",MSGESTUREHOLD:"MSGestureHold",MSGESTURESTART:"MSGestureStart",MSGESTURETAP:"MSGestureTap",MSGOTPOINTERCAPTURE:"MSGotPointerCapture",MSINERTIASTART:"MSInertiaStart",MSLOSTPOINTERCAPTURE:"MSLostPointerCapture",MSPOINTERCANCEL:"MSPointerCancel",
                +MSPOINTERDOWN:"MSPointerDown",MSPOINTERENTER:"MSPointerEnter",MSPOINTERHOVER:"MSPointerHover",MSPOINTERLEAVE:"MSPointerLeave",MSPOINTERMOVE:"MSPointerMove",MSPOINTEROUT:"MSPointerOut",MSPOINTEROVER:"MSPointerOver",MSPOINTERUP:"MSPointerUp",TEXT:"text",TEXTINPUT:goog.userAgent.IE?"textinput":"textInput",COMPOSITIONSTART:"compositionstart",COMPOSITIONUPDATE:"compositionupdate",COMPOSITIONEND:"compositionend",BEFOREINPUT:"beforeinput",EXIT:"exit",LOADABORT:"loadabort",LOADCOMMIT:"loadcommit",LOADREDIRECT:"loadredirect",
                +LOADSTART:"loadstart",LOADSTOP:"loadstop",RESPONSIVE:"responsive",SIZECHANGED:"sizechanged",UNRESPONSIVE:"unresponsive",VISIBILITYCHANGE:"visibilitychange",STORAGE:"storage",DOMSUBTREEMODIFIED:"DOMSubtreeModified",DOMNODEINSERTED:"DOMNodeInserted",DOMNODEREMOVED:"DOMNodeRemoved",DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument",DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument",DOMATTRMODIFIED:"DOMAttrModified",DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified",BEFOREPRINT:"beforeprint",
                +AFTERPRINT:"afterprint"};goog.events.BrowserEvent=function(a,b){goog.events.Event.call(this,a?a.type:"");this.relatedTarget=this.currentTarget=this.target=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.key="";this.charCode=this.keyCode=0;this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.platformModifierKey=!1;this.event_=null;a&&this.init(a,b)};goog.inherits(goog.events.BrowserEvent,goog.events.Event);
                +goog.events.BrowserEvent.MouseButton={LEFT:0,MIDDLE:1,RIGHT:2};goog.events.BrowserEvent.IEButtonMap=[1,4,2];
                +goog.events.BrowserEvent.prototype.init=function(a,b){var c=this.type=a.type,d=a.changedTouches?a.changedTouches[0]:null;this.target=a.target||a.srcElement;this.currentTarget=b;var e=a.relatedTarget;e?goog.userAgent.GECKO&&(goog.reflect.canAccessProperty(e,"nodeName")||(e=null)):c==goog.events.EventType.MOUSEOVER?e=a.fromElement:c==goog.events.EventType.MOUSEOUT&&(e=a.toElement);this.relatedTarget=e;goog.isNull(d)?(this.offsetX=goog.userAgent.WEBKIT||void 0!==a.offsetX?a.offsetX:a.layerX,this.offsetY=
                +goog.userAgent.WEBKIT||void 0!==a.offsetY?a.offsetY:a.layerY,this.clientX=void 0!==a.clientX?a.clientX:a.pageX,this.clientY=void 0!==a.clientY?a.clientY:a.pageY,this.screenX=a.screenX||0,this.screenY=a.screenY||0):(this.clientX=void 0!==d.clientX?d.clientX:d.pageX,this.clientY=void 0!==d.clientY?d.clientY:d.pageY,this.screenX=d.screenX||0,this.screenY=d.screenY||0);this.button=a.button;this.keyCode=a.keyCode||0;this.key=a.key||"";this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=
                +a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.platformModifierKey=goog.userAgent.MAC?a.metaKey:a.ctrlKey;this.state=a.state;this.event_=a;a.defaultPrevented&&this.preventDefault()};goog.events.BrowserEvent.prototype.isButton=function(a){return goog.events.BrowserFeature.HAS_W3C_BUTTON?this.event_.button==a:"click"==this.type?a==goog.events.BrowserEvent.MouseButton.LEFT:!!(this.event_.button&goog.events.BrowserEvent.IEButtonMap[a])};
                +goog.events.BrowserEvent.prototype.isMouseActionButton=function(){return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT)&&!(goog.userAgent.WEBKIT&&goog.userAgent.MAC&&this.ctrlKey)};goog.events.BrowserEvent.prototype.stopPropagation=function(){goog.events.BrowserEvent.superClass_.stopPropagation.call(this);this.event_.stopPropagation?this.event_.stopPropagation():this.event_.cancelBubble=!0};
                +goog.events.BrowserEvent.prototype.preventDefault=function(){goog.events.BrowserEvent.superClass_.preventDefault.call(this);var a=this.event_;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};goog.events.BrowserEvent.prototype.getBrowserEvent=function(){return this.event_};goog.events.Listenable=function(){};goog.events.Listenable.IMPLEMENTED_BY_PROP="closure_listenable_"+(1E6*Math.random()|0);goog.events.Listenable.addImplementation=function(a){a.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP]=!0};goog.events.Listenable.isImplementedBy=function(a){return!(!a||!a[goog.events.Listenable.IMPLEMENTED_BY_PROP])};goog.events.ListenableKey=function(){};goog.events.ListenableKey.counter_=0;goog.events.ListenableKey.reserveKey=function(){return++goog.events.ListenableKey.counter_};goog.events.Listener=function(a,b,c,d,e,f){goog.events.Listener.ENABLE_MONITORING&&(this.creationStack=Error().stack);this.listener=a;this.proxy=b;this.src=c;this.type=d;this.capture=!!e;this.handler=f;this.key=goog.events.ListenableKey.reserveKey();this.removed=this.callOnce=!1};goog.events.Listener.ENABLE_MONITORING=!1;goog.events.Listener.prototype.markAsRemoved=function(){this.removed=!0;this.handler=this.src=this.proxy=this.listener=null};goog.events.ListenerMap=function(a){this.src=a;this.listeners={};this.typeCount_=0};goog.events.ListenerMap.prototype.getTypeCount=function(){return this.typeCount_};goog.events.ListenerMap.prototype.getListenerCount=function(){var a=0,b;for(b in this.listeners)a+=this.listeners[b].length;return a};
                +goog.events.ListenerMap.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.listeners[f];a||(a=this.listeners[f]=[],this.typeCount_++);var g=goog.events.ListenerMap.findListenerIndex_(a,b,d,e);-1<g?(b=a[g],c||(b.callOnce=!1)):(b=new goog.events.Listener(b,null,this.src,f,!!d,e),b.callOnce=c,a.push(b));return b};
                +goog.events.ListenerMap.prototype.remove=function(a,b,c,d){a=a.toString();if(!(a in this.listeners))return!1;var e=this.listeners[a];b=goog.events.ListenerMap.findListenerIndex_(e,b,c,d);return-1<b?(e[b].markAsRemoved(),goog.array.removeAt(e,b),0==e.length&&(delete this.listeners[a],this.typeCount_--),!0):!1};
                +goog.events.ListenerMap.prototype.removeByKey=function(a){var b=a.type;if(!(b in this.listeners))return!1;var c=goog.array.remove(this.listeners[b],a);c&&(a.markAsRemoved(),0==this.listeners[b].length&&(delete this.listeners[b],this.typeCount_--));return c};goog.events.ListenerMap.prototype.removeAll=function(a){a=a&&a.toString();var b=0,c;for(c in this.listeners)if(!a||c==a){for(var d=this.listeners[c],e=0;e<d.length;e++)++b,d[e].markAsRemoved();delete this.listeners[c];this.typeCount_--}return b};
                +goog.events.ListenerMap.prototype.getListeners=function(a,b){var c=this.listeners[a.toString()],d=[];if(c)for(var e=0;e<c.length;++e){var f=c[e];f.capture==b&&d.push(f)}return d};goog.events.ListenerMap.prototype.getListener=function(a,b,c,d){a=this.listeners[a.toString()];var e=-1;a&&(e=goog.events.ListenerMap.findListenerIndex_(a,b,c,d));return-1<e?a[e]:null};
                +goog.events.ListenerMap.prototype.hasListener=function(a,b){var c=goog.isDef(a),d=c?a.toString():"",e=goog.isDef(b);return goog.object.some(this.listeners,function(a,g){for(var f=0;f<a.length;++f)if(!(c&&a[f].type!=d||e&&a[f].capture!=b))return!0;return!1})};goog.events.ListenerMap.findListenerIndex_=function(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e];if(!f.removed&&f.listener==b&&f.capture==!!c&&f.handler==d)return e}return-1};goog.events.LISTENER_MAP_PROP_="closure_lm_"+(1E6*Math.random()|0);goog.events.onString_="on";goog.events.onStringMap_={};goog.events.CaptureSimulationMode={OFF_AND_FAIL:0,OFF_AND_SILENT:1,ON:2};goog.events.CAPTURE_SIMULATION_MODE=2;goog.events.listenerCountEstimate_=0;
                +goog.events.listen=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listen(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);return goog.events.Listenable.isImplementedBy(a)?a.listen(b,c,d,e):goog.events.listen_(a,b,c,!1,d,e)};
                +goog.events.listen_=function(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=!!e;if(g&&!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_FAIL)return goog.asserts.fail("Can not register capture listener in IE8-."),null;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.OFF_AND_SILENT)return null}var h=goog.events.getListenerMap_(a);h||(a[goog.events.LISTENER_MAP_PROP_]=h=new goog.events.ListenerMap(a));
                +c=h.add(b,c,d,e,f);if(c.proxy)return c;d=goog.events.getProxy();c.proxy=d;d.src=a;d.listener=c;if(a.addEventListener)a.addEventListener(b.toString(),d,g);else if(a.attachEvent)a.attachEvent(goog.events.getOnString_(b.toString()),d);else throw Error("addEventListener and attachEvent are unavailable.");goog.events.listenerCountEstimate_++;return c};
                +goog.events.getProxy=function(){var a=goog.events.handleBrowserEvent_,b=goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT?function(c){return a.call(b.src,b.listener,c)}:function(c){c=a.call(b.src,b.listener,c);if(!c)return c};return b};
                +goog.events.listenOnce=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.listenOnce(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);return goog.events.Listenable.isImplementedBy(a)?a.listenOnce(b,c,d,e):goog.events.listen_(a,b,c,!0,d,e)};goog.events.listenWithWrapper=function(a,b,c,d,e){b.listen(a,c,d,e)};
                +goog.events.unlisten=function(a,b,c,d,e){if(goog.isArray(b)){for(var f=0;f<b.length;f++)goog.events.unlisten(a,b[f],c,d,e);return null}c=goog.events.wrapListener(c);if(goog.events.Listenable.isImplementedBy(a))return a.unlisten(b,c,d,e);if(!a)return!1;d=!!d;if(a=goog.events.getListenerMap_(a))if(b=a.getListener(b,c,d,e))return goog.events.unlistenByKey(b);return!1};
                +goog.events.unlistenByKey=function(a){if(goog.isNumber(a)||!a||a.removed)return!1;var b=a.src;if(goog.events.Listenable.isImplementedBy(b))return b.unlistenByKey(a);var c=a.type,d=a.proxy;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent&&b.detachEvent(goog.events.getOnString_(c),d);goog.events.listenerCountEstimate_--;(c=goog.events.getListenerMap_(b))?(c.removeByKey(a),0==c.getTypeCount()&&(c.src=null,b[goog.events.LISTENER_MAP_PROP_]=null)):a.markAsRemoved();return!0};
                +goog.events.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e)};goog.events.removeAll=function(a,b){if(!a)return 0;if(goog.events.Listenable.isImplementedBy(a))return a.removeAllListeners(b);var c=goog.events.getListenerMap_(a);if(!c)return 0;var d=0,e=b&&b.toString(),f;for(f in c.listeners)if(!e||f==e)for(var g=c.listeners[f].concat(),h=0;h<g.length;++h)goog.events.unlistenByKey(g[h])&&++d;return d};
                +goog.events.getListeners=function(a,b,c){return goog.events.Listenable.isImplementedBy(a)?a.getListeners(b,c):a?(a=goog.events.getListenerMap_(a))?a.getListeners(b,c):[]:[]};goog.events.getListener=function(a,b,c,d,e){c=goog.events.wrapListener(c);d=!!d;return goog.events.Listenable.isImplementedBy(a)?a.getListener(b,c,d,e):a?(a=goog.events.getListenerMap_(a))?a.getListener(b,c,d,e):null:null};
                +goog.events.hasListener=function(a,b,c){if(goog.events.Listenable.isImplementedBy(a))return a.hasListener(b,c);a=goog.events.getListenerMap_(a);return!!a&&a.hasListener(b,c)};goog.events.expose=function(a){var b=[],c;for(c in a)a[c]&&a[c].id?b.push(c+" = "+a[c]+" ("+a[c].id+")"):b.push(c+" = "+a[c]);return b.join("\n")};goog.events.getOnString_=function(a){return a in goog.events.onStringMap_?goog.events.onStringMap_[a]:goog.events.onStringMap_[a]=goog.events.onString_+a};
                +goog.events.fireListeners=function(a,b,c,d){return goog.events.Listenable.isImplementedBy(a)?a.fireListeners(b,c,d):goog.events.fireListeners_(a,b,c,d)};goog.events.fireListeners_=function(a,b,c,d){var e=!0;if(a=goog.events.getListenerMap_(a))if(b=a.listeners[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.capture==c&&!f.removed&&(f=goog.events.fireListener(f,d),e=e&&!1!==f)}return e};
                +goog.events.fireListener=function(a,b){var c=a.listener,d=a.handler||a.src;a.callOnce&&goog.events.unlistenByKey(a);return c.call(d,b)};goog.events.getTotalListenerCount=function(){return goog.events.listenerCountEstimate_};goog.events.dispatchEvent=function(a,b){goog.asserts.assert(goog.events.Listenable.isImplementedBy(a),"Can not use goog.events.dispatchEvent with non-goog.events.Listenable instance.");return a.dispatchEvent(b)};
                +goog.events.protectBrowserEventEntryPoint=function(a){goog.events.handleBrowserEvent_=a.protectEntryPoint(goog.events.handleBrowserEvent_)};
                +goog.events.handleBrowserEvent_=function(a,b){var c;if(a.removed)return!0;if(!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT){var d=b||goog.getObjectByName("window.event"),e=new goog.events.BrowserEvent(d,this),f=!0;if(goog.events.CAPTURE_SIMULATION_MODE==goog.events.CaptureSimulationMode.ON){if(!goog.events.isMarkedIeEvent_(d)){goog.events.markIeEvent_(d);d=[];for(c=e.currentTarget;c;c=c.parentNode)d.push(c);for(var g=a.type,h=d.length-1;!e.propagationStopped_&&0<=h;h--)e.currentTarget=d[h],c=
                +goog.events.fireListeners_(d[h],g,!0,e),f=f&&c;for(h=0;!e.propagationStopped_&&h<d.length;h++)e.currentTarget=d[h],c=goog.events.fireListeners_(d[h],g,!1,e),f=f&&c}}else f=goog.events.fireListener(a,e);return f}return goog.events.fireListener(a,new goog.events.BrowserEvent(b,this))};goog.events.markIeEvent_=function(a){var b=!1;if(0==a.keyCode)try{a.keyCode=-1;return}catch(c){b=!0}if(b||void 0==a.returnValue)a.returnValue=!0};goog.events.isMarkedIeEvent_=function(a){return 0>a.keyCode||void 0!=a.returnValue};
                +goog.events.uniqueIdCounter_=0;goog.events.getUniqueId=function(a){return a+"_"+goog.events.uniqueIdCounter_++};goog.events.getListenerMap_=function(a){a=a[goog.events.LISTENER_MAP_PROP_];return a instanceof goog.events.ListenerMap?a:null};goog.events.LISTENER_WRAPPER_PROP_="__closure_events_fn_"+(1E9*Math.random()>>>0);
                +goog.events.wrapListener=function(a){goog.asserts.assert(a,"Listener can not be null.");if(goog.isFunction(a))return a;goog.asserts.assert(a.handleEvent,"An object listener must have handleEvent method.");a[goog.events.LISTENER_WRAPPER_PROP_]||(a[goog.events.LISTENER_WRAPPER_PROP_]=function(b){return a.handleEvent(b)});return a[goog.events.LISTENER_WRAPPER_PROP_]};goog.debug.entryPointRegistry.register(function(a){goog.events.handleBrowserEvent_=a(goog.events.handleBrowserEvent_)});goog.events.EventTarget=function(){goog.Disposable.call(this);this.eventTargetListeners_=new goog.events.ListenerMap(this);this.actualEventTarget_=this;this.parentEventTarget_=null};goog.inherits(goog.events.EventTarget,goog.Disposable);goog.events.Listenable.addImplementation(goog.events.EventTarget);goog.events.EventTarget.MAX_ANCESTORS_=1E3;goog.events.EventTarget.prototype.getParentEventTarget=function(){return this.parentEventTarget_};
                +goog.events.EventTarget.prototype.setParentEventTarget=function(a){this.parentEventTarget_=a};goog.events.EventTarget.prototype.addEventListener=function(a,b,c,d){goog.events.listen(this,a,b,c,d)};goog.events.EventTarget.prototype.removeEventListener=function(a,b,c,d){goog.events.unlisten(this,a,b,c,d)};
                +goog.events.EventTarget.prototype.dispatchEvent=function(a){this.assertInitialized_();var b=this.getParentEventTarget();if(b){var c=[];for(var d=1;b;b=b.getParentEventTarget())c.push(b),goog.asserts.assert(++d<goog.events.EventTarget.MAX_ANCESTORS_,"infinite loop")}return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_,a,c)};
                +goog.events.EventTarget.prototype.disposeInternal=function(){goog.events.EventTarget.superClass_.disposeInternal.call(this);this.removeAllListeners();this.parentEventTarget_=null};goog.events.EventTarget.prototype.listen=function(a,b,c,d){this.assertInitialized_();return this.eventTargetListeners_.add(String(a),b,!1,c,d)};goog.events.EventTarget.prototype.listenOnce=function(a,b,c,d){return this.eventTargetListeners_.add(String(a),b,!0,c,d)};
                +goog.events.EventTarget.prototype.unlisten=function(a,b,c,d){return this.eventTargetListeners_.remove(String(a),b,c,d)};goog.events.EventTarget.prototype.unlistenByKey=function(a){return this.eventTargetListeners_.removeByKey(a)};goog.events.EventTarget.prototype.removeAllListeners=function(a){return this.eventTargetListeners_?this.eventTargetListeners_.removeAll(a):0};
                +goog.events.EventTarget.prototype.fireListeners=function(a,b,c){a=this.eventTargetListeners_.listeners[String(a)];if(!a)return!0;a=a.concat();for(var d=!0,e=0;e<a.length;++e){var f=a[e];if(f&&!f.removed&&f.capture==b){var g=f.listener,h=f.handler||f.src;f.callOnce&&this.unlistenByKey(f);d=!1!==g.call(h,c)&&d}}return d&&0!=c.returnValue_};goog.events.EventTarget.prototype.getListeners=function(a,b){return this.eventTargetListeners_.getListeners(String(a),b)};
                +goog.events.EventTarget.prototype.getListener=function(a,b,c,d){return this.eventTargetListeners_.getListener(String(a),b,c,d)};goog.events.EventTarget.prototype.hasListener=function(a,b){var c=goog.isDef(a)?String(a):void 0;return this.eventTargetListeners_.hasListener(c,b)};goog.events.EventTarget.prototype.setTargetForTesting=function(a){this.actualEventTarget_=a};goog.events.EventTarget.prototype.assertInitialized_=function(){goog.asserts.assert(this.eventTargetListeners_,"Event target is not initialized. Did you call the superclass (goog.events.EventTarget) constructor?")};
                +goog.events.EventTarget.dispatchEventInternal_=function(a,b,c){var d=b.type||b;if(goog.isString(b))b=new goog.events.Event(b,a);else if(b instanceof goog.events.Event)b.target=b.target||a;else{var e=b;b=new goog.events.Event(d,a);goog.object.extend(b,e)}var e=!0;if(c)for(var f=c.length-1;!b.propagationStopped_&&0<=f;f--){var g=b.currentTarget=c[f];e=g.fireListeners(d,!0,b)&&e}b.propagationStopped_||(g=b.currentTarget=a,e=g.fireListeners(d,!0,b)&&e,b.propagationStopped_||(e=g.fireListeners(d,!1,b)&&
                +e));if(c)for(f=0;!b.propagationStopped_&&f<c.length;f++)g=b.currentTarget=c[f],e=g.fireListeners(d,!1,b)&&e;return e};goog.Timer=function(a,b){goog.events.EventTarget.call(this);this.interval_=a||1;this.timerObject_=b||goog.Timer.defaultTimerObject;this.boundTick_=goog.bind(this.tick_,this);this.last_=goog.now()};goog.inherits(goog.Timer,goog.events.EventTarget);goog.Timer.MAX_TIMEOUT_=2147483647;goog.Timer.INVALID_TIMEOUT_ID_=-1;goog.Timer.prototype.enabled=!1;goog.Timer.defaultTimerObject=goog.global;goog.Timer.intervalScale=.8;goog.Timer.prototype.timer_=null;goog.Timer.prototype.getInterval=function(){return this.interval_};
                +goog.Timer.prototype.setInterval=function(a){this.interval_=a;this.timer_&&this.enabled?(this.stop(),this.start()):this.timer_&&this.stop()};
                +goog.Timer.prototype.tick_=function(){if(this.enabled){var a=goog.now()-this.last_;0<a&&a<this.interval_*goog.Timer.intervalScale?this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_-a):(this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null),this.dispatchTick(),this.enabled&&(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now()))}};goog.Timer.prototype.dispatchTick=function(){this.dispatchEvent(goog.Timer.TICK)};
                +goog.Timer.prototype.start=function(){this.enabled=!0;this.timer_||(this.timer_=this.timerObject_.setTimeout(this.boundTick_,this.interval_),this.last_=goog.now())};goog.Timer.prototype.stop=function(){this.enabled=!1;this.timer_&&(this.timerObject_.clearTimeout(this.timer_),this.timer_=null)};goog.Timer.prototype.disposeInternal=function(){goog.Timer.superClass_.disposeInternal.call(this);this.stop();delete this.timerObject_};goog.Timer.TICK="tick";
                +goog.Timer.callOnce=function(a,b,c){if(goog.isFunction(a))c&&(a=goog.bind(a,c));else if(a&&"function"==typeof a.handleEvent)a=goog.bind(a.handleEvent,a);else throw Error("Invalid listener argument");return Number(b)>goog.Timer.MAX_TIMEOUT_?goog.Timer.INVALID_TIMEOUT_ID_:goog.Timer.defaultTimerObject.setTimeout(a,b||0)};goog.Timer.clear=function(a){goog.Timer.defaultTimerObject.clearTimeout(a)};
                +goog.Timer.promise=function(a,b){var c=null;return(new goog.Promise(function(d,e){c=goog.Timer.callOnce(function(){d(b)},a);c==goog.Timer.INVALID_TIMEOUT_ID_&&e(Error("Failed to schedule timer."))})).thenCatch(function(a){goog.Timer.clear(c);throw a;})};goog.dom.BrowserFeature={CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),CAN_USE_CHILDREN_ATTRIBUTE:!goog.userAgent.GECKO&&!goog.userAgent.IE||goog.userAgent.IE&&goog.userAgent.isDocumentModeOrHigher(9)||goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9.1"),CAN_USE_INNER_TEXT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),CAN_USE_PARENT_ELEMENT_PROPERTY:goog.userAgent.IE||goog.userAgent.OPERA||goog.userAgent.WEBKIT,INNER_HTML_NEEDS_SCOPED_ELEMENT:goog.userAgent.IE,
                +LEGACY_IE_RANGES:goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)};goog.dom.tags={};goog.dom.tags.VOID_TAGS_={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};goog.dom.tags.isVoidTag=function(a){return!0===goog.dom.tags.VOID_TAGS_[a]};goog.string.TypedString=function(){};goog.string.Const=function(){this.stringConstValueWithSecurityContract__googStringSecurityPrivate_="";this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_=goog.string.Const.TYPE_MARKER_};goog.string.Const.prototype.implementsGoogStringTypedString=!0;goog.string.Const.prototype.getTypedStringValue=function(){return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_};
                +goog.string.Const.prototype.toString=function(){return"Const{"+this.stringConstValueWithSecurityContract__googStringSecurityPrivate_+"}"};goog.string.Const.unwrap=function(a){if(a instanceof goog.string.Const&&a.constructor===goog.string.Const&&a.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_===goog.string.Const.TYPE_MARKER_)return a.stringConstValueWithSecurityContract__googStringSecurityPrivate_;goog.asserts.fail("expected object of type Const, got '"+a+"'");return"type_error:Const"};
                +goog.string.Const.from=function(a){return goog.string.Const.create__googStringSecurityPrivate_(a)};goog.string.Const.TYPE_MARKER_={};goog.string.Const.create__googStringSecurityPrivate_=function(a){var b=new goog.string.Const;b.stringConstValueWithSecurityContract__googStringSecurityPrivate_=a;return b};goog.string.Const.EMPTY=goog.string.Const.from("");goog.html={};goog.html.SafeScript=function(){this.privateDoNotAccessOrElseSafeScriptWrappedValue_="";this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeScript.prototype.implementsGoogStringTypedString=!0;goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.SafeScript.fromConstant=function(a){a=goog.string.Const.unwrap(a);return 0===a.length?goog.html.SafeScript.EMPTY:goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.SafeScript.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeScriptWrappedValue_};goog.DEBUG&&(goog.html.SafeScript.prototype.toString=function(){return"SafeScript{"+this.privateDoNotAccessOrElseSafeScriptWrappedValue_+"}"});
                +goog.html.SafeScript.unwrap=function(a){if(a instanceof goog.html.SafeScript&&a.constructor===goog.html.SafeScript&&a.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeScriptWrappedValue_;goog.asserts.fail("expected object of type SafeScript, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeScript"};goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeScript).initSecurityPrivateDoNotAccessOrElse_(a)};
                +goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeScriptWrappedValue_=a;return this};goog.html.SafeScript.EMPTY=goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse("");goog.html.SafeStyle=function(){this.privateDoNotAccessOrElseSafeStyleWrappedValue_="";this.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeStyle.prototype.implementsGoogStringTypedString=!0;goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeStyle.fromConstant=function(a){a=goog.string.Const.unwrap(a);if(0===a.length)return goog.html.SafeStyle.EMPTY;goog.html.SafeStyle.checkStyle_(a);goog.asserts.assert(goog.string.endsWith(a,";"),"Last character of style string is not ';': "+a);goog.asserts.assert(goog.string.contains(a,":"),"Style string must contain at least one ':', to specify a \"name: value\" pair: "+a);return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.SafeStyle.checkStyle_=function(a){goog.asserts.assert(!/[<>]/.test(a),"Forbidden characters in style string: "+a)};goog.html.SafeStyle.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeStyleWrappedValue_};goog.DEBUG&&(goog.html.SafeStyle.prototype.toString=function(){return"SafeStyle{"+this.privateDoNotAccessOrElseSafeStyleWrappedValue_+"}"});
                +goog.html.SafeStyle.unwrap=function(a){if(a instanceof goog.html.SafeStyle&&a.constructor===goog.html.SafeStyle&&a.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeStyleWrappedValue_;goog.asserts.fail("expected object of type SafeStyle, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeStyle"};goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeStyle).initSecurityPrivateDoNotAccessOrElse_(a)};
                +goog.html.SafeStyle.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeStyleWrappedValue_=a;return this};goog.html.SafeStyle.EMPTY=goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse("");goog.html.SafeStyle.INNOCUOUS_STRING="zClosurez";
                +goog.html.SafeStyle.create=function(a){var b="",c;for(c in a){if(!/^[-_a-zA-Z0-9]+$/.test(c))throw Error("Name allows only [-_a-zA-Z0-9], got: "+c);var d=a[c];null!=d&&(d instanceof goog.string.Const?(d=goog.string.Const.unwrap(d),goog.asserts.assert(!/[{;}]/.test(d),"Value does not allow [{;}].")):goog.html.SafeStyle.VALUE_RE_.test(d)?goog.html.SafeStyle.hasBalancedQuotes_(d)||(goog.asserts.fail("String value requires balanced quotes, got: "+d),d=goog.html.SafeStyle.INNOCUOUS_STRING):(goog.asserts.fail("String value allows only [-,.\"'%_!# a-zA-Z0-9], rgb() and rgba(), got: "+
                +d),d=goog.html.SafeStyle.INNOCUOUS_STRING),b+=c+":"+d+";")}if(!b)return goog.html.SafeStyle.EMPTY;goog.html.SafeStyle.checkStyle_(b);return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b)};goog.html.SafeStyle.hasBalancedQuotes_=function(a){for(var b=!0,c=!0,d=0;d<a.length;d++){var e=a.charAt(d);"'"==e&&c?b=!b:'"'==e&&b&&(c=!c)}return b&&c};goog.html.SafeStyle.VALUE_RE_=/^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/;
                +goog.html.SafeStyle.concat=function(a){var b="",c=function(a){goog.isArray(a)?goog.array.forEach(a,c):b+=goog.html.SafeStyle.unwrap(a)};goog.array.forEach(arguments,c);return b?goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b):goog.html.SafeStyle.EMPTY};goog.html.SafeStyleSheet=function(){this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_="";this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeStyleSheet.prototype.implementsGoogStringTypedString=!0;goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeStyleSheet.concat=function(a){var b="",c=function(a){goog.isArray(a)?goog.array.forEach(a,c):b+=goog.html.SafeStyleSheet.unwrap(a)};goog.array.forEach(arguments,c);return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.SafeStyleSheet.fromConstant=function(a){a=goog.string.Const.unwrap(a);if(0===a.length)return goog.html.SafeStyleSheet.EMPTY;goog.asserts.assert(!goog.string.contains(a,"<"),"Forbidden '<' character in style sheet string: "+a);return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeStyleSheet.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_};
                +goog.DEBUG&&(goog.html.SafeStyleSheet.prototype.toString=function(){return"SafeStyleSheet{"+this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_+"}"});
                +goog.html.SafeStyleSheet.unwrap=function(a){if(a instanceof goog.html.SafeStyleSheet&&a.constructor===goog.html.SafeStyleSheet&&a.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;goog.asserts.fail("expected object of type SafeStyleSheet, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeStyleSheet"};
                +goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse=function(a){return(new goog.html.SafeStyleSheet).initSecurityPrivateDoNotAccessOrElse_(a)};goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a){this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_=a;return this};goog.html.SafeStyleSheet.EMPTY=goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse("");goog.fs={};goog.fs.url={};goog.fs.url.createObjectUrl=function(a){return goog.fs.url.getUrlObject_().createObjectURL(a)};goog.fs.url.revokeObjectUrl=function(a){goog.fs.url.getUrlObject_().revokeObjectURL(a)};goog.fs.url.getUrlObject_=function(){var a=goog.fs.url.findUrlObject_();if(null!=a)return a;throw Error("This browser doesn't seem to support blob URLs");};
                +goog.fs.url.findUrlObject_=function(){return goog.isDef(goog.global.URL)&&goog.isDef(goog.global.URL.createObjectURL)?goog.global.URL:goog.isDef(goog.global.webkitURL)&&goog.isDef(goog.global.webkitURL.createObjectURL)?goog.global.webkitURL:goog.isDef(goog.global.createObjectURL)?goog.global:null};goog.fs.url.browserSupportsObjectUrls=function(){return null!=goog.fs.url.findUrlObject_()};goog.i18n={};goog.i18n.bidi={};goog.i18n.bidi.FORCE_RTL=!1;
                +goog.i18n.bidi.IS_RTL=goog.i18n.bidi.FORCE_RTL||("ar"==goog.LOCALE.substring(0,2).toLowerCase()||"fa"==goog.LOCALE.substring(0,2).toLowerCase()||"he"==goog.LOCALE.substring(0,2).toLowerCase()||"iw"==goog.LOCALE.substring(0,2).toLowerCase()||"ps"==goog.LOCALE.substring(0,2).toLowerCase()||"sd"==goog.LOCALE.substring(0,2).toLowerCase()||"ug"==goog.LOCALE.substring(0,2).toLowerCase()||"ur"==goog.LOCALE.substring(0,2).toLowerCase()||"yi"==goog.LOCALE.substring(0,2).toLowerCase())&&(2==goog.LOCALE.length||
                +"-"==goog.LOCALE.substring(2,3)||"_"==goog.LOCALE.substring(2,3))||3<=goog.LOCALE.length&&"ckb"==goog.LOCALE.substring(0,3).toLowerCase()&&(3==goog.LOCALE.length||"-"==goog.LOCALE.substring(3,4)||"_"==goog.LOCALE.substring(3,4));goog.i18n.bidi.Format={LRE:"\u202a",RLE:"\u202b",PDF:"\u202c",LRM:"\u200e",RLM:"\u200f"};goog.i18n.bidi.Dir={LTR:1,RTL:-1,NEUTRAL:0};goog.i18n.bidi.RIGHT="right";goog.i18n.bidi.LEFT="left";goog.i18n.bidi.I18N_RIGHT=goog.i18n.bidi.IS_RTL?goog.i18n.bidi.LEFT:goog.i18n.bidi.RIGHT;
                +goog.i18n.bidi.I18N_LEFT=goog.i18n.bidi.IS_RTL?goog.i18n.bidi.RIGHT:goog.i18n.bidi.LEFT;goog.i18n.bidi.toDir=function(a,b){return"number"==typeof a?0<a?goog.i18n.bidi.Dir.LTR:0>a?goog.i18n.bidi.Dir.RTL:b?null:goog.i18n.bidi.Dir.NEUTRAL:null==a?null:a?goog.i18n.bidi.Dir.RTL:goog.i18n.bidi.Dir.LTR};goog.i18n.bidi.ltrChars_="A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff";goog.i18n.bidi.rtlChars_="\u0591-\u06ef\u06fa-\u07ff\u200f\ufb1d-\ufdff\ufe70-\ufefc";
                +goog.i18n.bidi.htmlSkipReg_=/<[^>]*>|&[^;]+;/g;goog.i18n.bidi.stripHtmlIfNeeded_=function(a,b){return b?a.replace(goog.i18n.bidi.htmlSkipReg_,""):a};goog.i18n.bidi.rtlCharReg_=new RegExp("["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.ltrCharReg_=new RegExp("["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.hasAnyRtl=function(a,b){return goog.i18n.bidi.rtlCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.hasRtlChar=goog.i18n.bidi.hasAnyRtl;
                +goog.i18n.bidi.hasAnyLtr=function(a,b){return goog.i18n.bidi.ltrCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.ltrRe_=new RegExp("^["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.rtlRe_=new RegExp("^["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.isRtlChar=function(a){return goog.i18n.bidi.rtlRe_.test(a)};goog.i18n.bidi.isLtrChar=function(a){return goog.i18n.bidi.ltrRe_.test(a)};goog.i18n.bidi.isNeutralChar=function(a){return!goog.i18n.bidi.isLtrChar(a)&&!goog.i18n.bidi.isRtlChar(a)};
                +goog.i18n.bidi.ltrDirCheckRe_=new RegExp("^[^"+goog.i18n.bidi.rtlChars_+"]*["+goog.i18n.bidi.ltrChars_+"]");goog.i18n.bidi.rtlDirCheckRe_=new RegExp("^[^"+goog.i18n.bidi.ltrChars_+"]*["+goog.i18n.bidi.rtlChars_+"]");goog.i18n.bidi.startsWithRtl=function(a,b){return goog.i18n.bidi.rtlDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isRtlText=goog.i18n.bidi.startsWithRtl;
                +goog.i18n.bidi.startsWithLtr=function(a,b){return goog.i18n.bidi.ltrDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isLtrText=goog.i18n.bidi.startsWithLtr;goog.i18n.bidi.isRequiredLtrRe_=/^http:\/\/.*/;goog.i18n.bidi.isNeutralText=function(a,b){a=goog.i18n.bidi.stripHtmlIfNeeded_(a,b);return goog.i18n.bidi.isRequiredLtrRe_.test(a)||!goog.i18n.bidi.hasAnyLtr(a)&&!goog.i18n.bidi.hasAnyRtl(a)};
                +goog.i18n.bidi.ltrExitDirCheckRe_=new RegExp("["+goog.i18n.bidi.ltrChars_+"][^"+goog.i18n.bidi.rtlChars_+"]*$");goog.i18n.bidi.rtlExitDirCheckRe_=new RegExp("["+goog.i18n.bidi.rtlChars_+"][^"+goog.i18n.bidi.ltrChars_+"]*$");goog.i18n.bidi.endsWithLtr=function(a,b){return goog.i18n.bidi.ltrExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isLtrExitText=goog.i18n.bidi.endsWithLtr;
                +goog.i18n.bidi.endsWithRtl=function(a,b){return goog.i18n.bidi.rtlExitDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_(a,b))};goog.i18n.bidi.isRtlExitText=goog.i18n.bidi.endsWithRtl;goog.i18n.bidi.rtlLocalesRe_=/^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)/i;goog.i18n.bidi.isRtlLanguage=function(a){return goog.i18n.bidi.rtlLocalesRe_.test(a)};goog.i18n.bidi.bracketGuardTextRe_=/(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
                +goog.i18n.bidi.guardBracketInText=function(a,b){var c=(void 0===b?goog.i18n.bidi.hasAnyRtl(a):b)?goog.i18n.bidi.Format.RLM:goog.i18n.bidi.Format.LRM;return a.replace(goog.i18n.bidi.bracketGuardTextRe_,c+"$&"+c)};goog.i18n.bidi.enforceRtlInHtml=function(a){return"<"==a.charAt(0)?a.replace(/<\w+/,"$& dir=rtl"):"\n<span dir=rtl>"+a+"</span>"};goog.i18n.bidi.enforceRtlInText=function(a){return goog.i18n.bidi.Format.RLE+a+goog.i18n.bidi.Format.PDF};
                +goog.i18n.bidi.enforceLtrInHtml=function(a){return"<"==a.charAt(0)?a.replace(/<\w+/,"$& dir=ltr"):"\n<span dir=ltr>"+a+"</span>"};goog.i18n.bidi.enforceLtrInText=function(a){return goog.i18n.bidi.Format.LRE+a+goog.i18n.bidi.Format.PDF};goog.i18n.bidi.dimensionsRe_=/:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;goog.i18n.bidi.leftRe_=/left/gi;goog.i18n.bidi.rightRe_=/right/gi;goog.i18n.bidi.tempRe_=/%%%%/g;
                +goog.i18n.bidi.mirrorCSS=function(a){return a.replace(goog.i18n.bidi.dimensionsRe_,":$1 $4 $3 $2").replace(goog.i18n.bidi.leftRe_,"%%%%").replace(goog.i18n.bidi.rightRe_,goog.i18n.bidi.LEFT).replace(goog.i18n.bidi.tempRe_,goog.i18n.bidi.RIGHT)};goog.i18n.bidi.doubleQuoteSubstituteRe_=/([\u0591-\u05f2])"/g;goog.i18n.bidi.singleQuoteSubstituteRe_=/([\u0591-\u05f2])'/g;
                +goog.i18n.bidi.normalizeHebrewQuote=function(a){return a.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_,"$1\u05f4").replace(goog.i18n.bidi.singleQuoteSubstituteRe_,"$1\u05f3")};goog.i18n.bidi.wordSeparatorRe_=/\s+/;goog.i18n.bidi.hasNumeralsRe_=/[\d\u06f0-\u06f9]/;goog.i18n.bidi.rtlDetectionThreshold_=.4;
                +goog.i18n.bidi.estimateDirection=function(a,b){for(var c=0,d=0,e=!1,f=goog.i18n.bidi.stripHtmlIfNeeded_(a,b).split(goog.i18n.bidi.wordSeparatorRe_),g=0;g<f.length;g++){var h=f[g];goog.i18n.bidi.startsWithRtl(h)?(c++,d++):goog.i18n.bidi.isRequiredLtrRe_.test(h)?e=!0:goog.i18n.bidi.hasAnyLtr(h)?d++:goog.i18n.bidi.hasNumeralsRe_.test(h)&&(e=!0)}return 0==d?e?goog.i18n.bidi.Dir.LTR:goog.i18n.bidi.Dir.NEUTRAL:c/d>goog.i18n.bidi.rtlDetectionThreshold_?goog.i18n.bidi.Dir.RTL:goog.i18n.bidi.Dir.LTR};
                +goog.i18n.bidi.detectRtlDirectionality=function(a,b){return goog.i18n.bidi.estimateDirection(a,b)==goog.i18n.bidi.Dir.RTL};goog.i18n.bidi.setElementDirAndAlign=function(a,b){a&&(b=goog.i18n.bidi.toDir(b))&&(a.style.textAlign=b==goog.i18n.bidi.Dir.RTL?goog.i18n.bidi.RIGHT:goog.i18n.bidi.LEFT,a.dir=b==goog.i18n.bidi.Dir.RTL?"rtl":"ltr")};
                +goog.i18n.bidi.setElementDirByTextDirectionality=function(a,b){switch(goog.i18n.bidi.estimateDirection(b)){case goog.i18n.bidi.Dir.LTR:a.dir="ltr";break;case goog.i18n.bidi.Dir.RTL:a.dir="rtl";break;default:a.removeAttribute("dir")}};goog.i18n.bidi.DirectionalString=function(){};goog.html.TrustedResourceUrl=function(){this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_="";this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString=!0;goog.html.TrustedResourceUrl.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_};
                +goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.TrustedResourceUrl.prototype.getDirection=function(){return goog.i18n.bidi.Dir.LTR};goog.DEBUG&&(goog.html.TrustedResourceUrl.prototype.toString=function(){return"TrustedResourceUrl{"+this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_+"}"});
                +goog.html.TrustedResourceUrl.unwrap=function(a){if(a instanceof goog.html.TrustedResourceUrl&&a.constructor===goog.html.TrustedResourceUrl&&a.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;goog.asserts.fail("expected object of type TrustedResourceUrl, got '"+a+"' of type "+goog.typeOf(a));return"type_error:TrustedResourceUrl"};
                +goog.html.TrustedResourceUrl.format=function(a,b){var c=goog.string.Const.unwrap(a);if(!goog.html.TrustedResourceUrl.BASE_URL_.test(c))throw Error("Invalid TrustedResourceUrl format: "+c);var d=c.replace(goog.html.TrustedResourceUrl.FORMAT_MARKER_,function(a,d){if(!Object.prototype.hasOwnProperty.call(b,d))throw Error('Found marker, "'+d+'", in format string, "'+c+'", but no valid label mapping found in args: '+JSON.stringify(b));var e=b[d];return e instanceof goog.string.Const?goog.string.Const.unwrap(e):
                +encodeURIComponent(String(e))});return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(d)};goog.html.TrustedResourceUrl.FORMAT_MARKER_=/%{(\w+)}/g;goog.html.TrustedResourceUrl.BASE_URL_=/^(?:https:)?\/\/[0-9a-z.:[\]-]+\/|^\/[^\/\\]|^about:blank(#|$)/i;goog.html.TrustedResourceUrl.fromConstant=function(a){return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(a))};
                +goog.html.TrustedResourceUrl.fromConstants=function(a){for(var b="",c=0;c<a.length;c++)b+=goog.string.Const.unwrap(a[c]);return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(b)};goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse=function(a){var b=new goog.html.TrustedResourceUrl;b.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_=a;return b};goog.html.SafeUrl=function(){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_="";this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_};goog.html.SafeUrl.INNOCUOUS_STRING="about:invalid#zClosurez";goog.html.SafeUrl.prototype.implementsGoogStringTypedString=!0;goog.html.SafeUrl.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_};
                +goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.SafeUrl.prototype.getDirection=function(){return goog.i18n.bidi.Dir.LTR};goog.DEBUG&&(goog.html.SafeUrl.prototype.toString=function(){return"SafeUrl{"+this.privateDoNotAccessOrElseSafeHtmlWrappedValue_+"}"});
                +goog.html.SafeUrl.unwrap=function(a){if(a instanceof goog.html.SafeUrl&&a.constructor===goog.html.SafeUrl&&a.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeHtmlWrappedValue_;goog.asserts.fail("expected object of type SafeUrl, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeUrl"};goog.html.SafeUrl.fromConstant=function(a){return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(a))};
                +goog.html.SAFE_MIME_TYPE_PATTERN_=/^(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm))$/i;goog.html.SafeUrl.fromBlob=function(a){a=goog.html.SAFE_MIME_TYPE_PATTERN_.test(a.type)?goog.fs.url.createObjectUrl(a):goog.html.SafeUrl.INNOCUOUS_STRING;return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.DATA_URL_PATTERN_=/^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;
                +goog.html.SafeUrl.fromDataUrl=function(a){var b=a.match(goog.html.DATA_URL_PATTERN_),b=b&&goog.html.SAFE_MIME_TYPE_PATTERN_.test(b[1]);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(b?a:goog.html.SafeUrl.INNOCUOUS_STRING)};goog.html.SafeUrl.fromTelUrl=function(a){goog.string.caseInsensitiveStartsWith(a,"tel:")||(a=goog.html.SafeUrl.INNOCUOUS_STRING);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeUrl.fromTrustedResourceUrl=function(a){return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.TrustedResourceUrl.unwrap(a))};
                +goog.html.SAFE_URL_PATTERN_=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;goog.html.SafeUrl.sanitize=function(a){if(a instanceof goog.html.SafeUrl)return a;a=a.implementsGoogStringTypedString?a.getTypedStringValue():String(a);goog.html.SAFE_URL_PATTERN_.test(a)||(a=goog.html.SafeUrl.INNOCUOUS_STRING);return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};
                +goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse=function(a){var b=new goog.html.SafeUrl;b.privateDoNotAccessOrElseSafeHtmlWrappedValue_=a;return b};goog.html.SafeUrl.ABOUT_BLANK=goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse("about:blank");goog.html.SafeHtml=function(){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_="";this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_=goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;this.dir_=null};goog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString=!0;goog.html.SafeHtml.prototype.getDirection=function(){return this.dir_};goog.html.SafeHtml.prototype.implementsGoogStringTypedString=!0;goog.html.SafeHtml.prototype.getTypedStringValue=function(){return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_};
                +goog.DEBUG&&(goog.html.SafeHtml.prototype.toString=function(){return"SafeHtml{"+this.privateDoNotAccessOrElseSafeHtmlWrappedValue_+"}"});
                +goog.html.SafeHtml.unwrap=function(a){if(a instanceof goog.html.SafeHtml&&a.constructor===goog.html.SafeHtml&&a.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_===goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_)return a.privateDoNotAccessOrElseSafeHtmlWrappedValue_;goog.asserts.fail("expected object of type SafeHtml, got '"+a+"' of type "+goog.typeOf(a));return"type_error:SafeHtml"};
                +goog.html.SafeHtml.htmlEscape=function(a){if(a instanceof goog.html.SafeHtml)return a;var b=null;a.implementsGoogI18nBidiDirectionalString&&(b=a.getDirection());a=a.implementsGoogStringTypedString?a.getTypedStringValue():String(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.htmlEscape(a),b)};
                +goog.html.SafeHtml.htmlEscapePreservingNewlines=function(a){if(a instanceof goog.html.SafeHtml)return a;a=goog.html.SafeHtml.htmlEscape(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.newLineToBr(goog.html.SafeHtml.unwrap(a)),a.getDirection())};
                +goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces=function(a){if(a instanceof goog.html.SafeHtml)return a;a=goog.html.SafeHtml.htmlEscape(a);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(goog.string.whitespaceEscape(goog.html.SafeHtml.unwrap(a)),a.getDirection())};goog.html.SafeHtml.from=goog.html.SafeHtml.htmlEscape;goog.html.SafeHtml.VALID_NAMES_IN_TAG_=/^[a-zA-Z0-9-]+$/;
                +goog.html.SafeHtml.URL_ATTRIBUTES_={action:!0,cite:!0,data:!0,formaction:!0,href:!0,manifest:!0,poster:!0,src:!0};goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_={APPLET:!0,BASE:!0,EMBED:!0,IFRAME:!0,LINK:!0,MATH:!0,META:!0,OBJECT:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};goog.html.SafeHtml.create=function(a,b,c){goog.html.SafeHtml.verifyTagName(String(a));return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(String(a),b,c)};
                +goog.html.SafeHtml.verifyTagName=function(a){if(!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(a))throw Error("Invalid tag name <"+a+">.");if(a.toUpperCase()in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_)throw Error("Tag name <"+a+"> is not allowed for SafeHtml.");};
                +goog.html.SafeHtml.createIframe=function(a,b,c,d){a&&goog.html.TrustedResourceUrl.unwrap(a);var e={};e.src=a||null;e.srcdoc=b&&goog.html.SafeHtml.unwrap(b);a=goog.html.SafeHtml.combineAttributes(e,{sandbox:""},c);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe",a,d)};
                +goog.html.SafeHtml.createSandboxIframe=function(a,b,c,d){if(!goog.html.SafeHtml.canUseSandboxIframe())throw Error("The browser does not support sandboxed iframes.");var e={};e.src=a?goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(a)):null;e.srcdoc=b||null;e.sandbox="";a=goog.html.SafeHtml.combineAttributes(e,{},c);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("iframe",a,d)};
                +goog.html.SafeHtml.canUseSandboxIframe=function(){return goog.global.HTMLIFrameElement&&"sandbox"in goog.global.HTMLIFrameElement.prototype};goog.html.SafeHtml.createScriptSrc=function(a,b){goog.html.TrustedResourceUrl.unwrap(a);var c=goog.html.SafeHtml.combineAttributes({src:a},{},b);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script",c)};
                +goog.html.SafeHtml.createScript=function(a,b){for(var c in b){var d=c.toLowerCase();if("language"==d||"src"==d||"text"==d||"type"==d)throw Error('Cannot set "'+d+'" attribute');}c="";a=goog.array.concat(a);for(d=0;d<a.length;d++)c+=goog.html.SafeScript.unwrap(a[d]);c=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(c,goog.i18n.bidi.Dir.NEUTRAL);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("script",b,c)};
                +goog.html.SafeHtml.createStyle=function(a,b){var c=goog.html.SafeHtml.combineAttributes({type:"text/css"},{},b),d="";a=goog.array.concat(a);for(var e=0;e<a.length;e++)d+=goog.html.SafeStyleSheet.unwrap(a[e]);d=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(d,goog.i18n.bidi.Dir.NEUTRAL);return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("style",c,d)};
                +goog.html.SafeHtml.createMetaRefresh=function(a,b){var c=goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(a));(goog.labs.userAgent.browser.isIE()||goog.labs.userAgent.browser.isEdge())&&goog.string.contains(c,";")&&(c="'"+c.replace(/'/g,"%27")+"'");return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse("meta",{"http-equiv":"refresh",content:(b||0)+"; url="+c})};
                +goog.html.SafeHtml.getAttrNameAndValue_=function(a,b,c){if(c instanceof goog.string.Const)c=goog.string.Const.unwrap(c);else if("style"==b.toLowerCase())c=goog.html.SafeHtml.getStyleValue_(c);else{if(/^on/i.test(b))throw Error('Attribute "'+b+'" requires goog.string.Const value, "'+c+'" given.');if(b.toLowerCase()in goog.html.SafeHtml.URL_ATTRIBUTES_)if(c instanceof goog.html.TrustedResourceUrl)c=goog.html.TrustedResourceUrl.unwrap(c);else if(c instanceof goog.html.SafeUrl)c=goog.html.SafeUrl.unwrap(c);
                +else if(goog.isString(c))c=goog.html.SafeUrl.sanitize(c).getTypedStringValue();else throw Error('Attribute "'+b+'" on tag "'+a+'" requires goog.html.SafeUrl, goog.string.Const, or string, value "'+c+'" given.');}c.implementsGoogStringTypedString&&(c=c.getTypedStringValue());goog.asserts.assert(goog.isString(c)||goog.isNumber(c),"String or number value expected, got "+typeof c+" with value: "+c);return b+'="'+goog.string.htmlEscape(String(c))+'"'};
                +goog.html.SafeHtml.getStyleValue_=function(a){if(!goog.isObject(a))throw Error('The "style" attribute requires goog.html.SafeStyle or map of style properties, '+typeof a+" given: "+a);a instanceof goog.html.SafeStyle||(a=goog.html.SafeStyle.create(a));return goog.html.SafeStyle.unwrap(a)};goog.html.SafeHtml.createWithDir=function(a,b,c,d){b=goog.html.SafeHtml.create(b,c,d);b.dir_=a;return b};
                +goog.html.SafeHtml.concat=function(a){var b=goog.i18n.bidi.Dir.NEUTRAL,c="",d=function(a){goog.isArray(a)?goog.array.forEach(a,d):(a=goog.html.SafeHtml.htmlEscape(a),c+=goog.html.SafeHtml.unwrap(a),a=a.getDirection(),b==goog.i18n.bidi.Dir.NEUTRAL?b=a:a!=goog.i18n.bidi.Dir.NEUTRAL&&b!=a&&(b=null))};goog.array.forEach(arguments,d);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(c,b)};
                +goog.html.SafeHtml.concatWithDir=function(a,b){var c=goog.html.SafeHtml.concat(goog.array.slice(arguments,1));c.dir_=a;return c};goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_={};goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse=function(a,b){return(new goog.html.SafeHtml).initSecurityPrivateDoNotAccessOrElse_(a,b)};goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_=function(a,b){this.privateDoNotAccessOrElseSafeHtmlWrappedValue_=a;this.dir_=b;return this};
                +goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse=function(a,b,c){var d=null;var e="<"+a+goog.html.SafeHtml.stringifyAttributes(a,b);goog.isDefAndNotNull(c)?goog.isArray(c)||(c=[c]):c=[];goog.dom.tags.isVoidTag(a.toLowerCase())?(goog.asserts.assert(!c.length,"Void tag <"+a+"> does not allow content."),e+=">"):(d=goog.html.SafeHtml.concat(c),e+=">"+goog.html.SafeHtml.unwrap(d)+"</"+a+">",d=d.getDirection());(a=b&&b.dir)&&(d=/^(ltr|rtl|auto)$/i.test(a)?goog.i18n.bidi.Dir.NEUTRAL:
                +null);return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(e,d)};goog.html.SafeHtml.stringifyAttributes=function(a,b){var c="";if(b)for(var d in b){if(!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(d))throw Error('Invalid attribute name "'+d+'".');var e=b[d];goog.isDefAndNotNull(e)&&(c+=" "+goog.html.SafeHtml.getAttrNameAndValue_(a,d,e))}return c};
                +goog.html.SafeHtml.combineAttributes=function(a,b,c){var d={},e;for(e in a)goog.asserts.assert(e.toLowerCase()==e,"Must be lower case"),d[e]=a[e];for(e in b)goog.asserts.assert(e.toLowerCase()==e,"Must be lower case"),d[e]=b[e];for(e in c){var f=e.toLowerCase();if(f in a)throw Error('Cannot override "'+f+'" attribute, got "'+e+'" with value "'+c[e]+'"');f in b&&delete d[f];d[e]=c[e]}return d};
                +goog.html.SafeHtml.DOCTYPE_HTML=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<!DOCTYPE html>",goog.i18n.bidi.Dir.NEUTRAL);goog.html.SafeHtml.EMPTY=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("",goog.i18n.bidi.Dir.NEUTRAL);goog.html.SafeHtml.BR=goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse("<br>",goog.i18n.bidi.Dir.NEUTRAL);goog.dom.safe={};goog.dom.safe.InsertAdjacentHtmlPosition={AFTERBEGIN:"afterbegin",AFTEREND:"afterend",BEFOREBEGIN:"beforebegin",BEFOREEND:"beforeend"};goog.dom.safe.insertAdjacentHtml=function(a,b,c){a.insertAdjacentHTML(b,goog.html.SafeHtml.unwrap(c))};goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_={MATH:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};
                +goog.dom.safe.setInnerHtml=function(a,b){if(goog.asserts.ENABLE_ASSERTS){var c=a.tagName.toUpperCase();if(goog.dom.safe.SET_INNER_HTML_DISALLOWED_TAGS_[c])throw Error("goog.dom.safe.setInnerHtml cannot be used to set content of "+a.tagName+".");}a.innerHTML=goog.html.SafeHtml.unwrap(b)};goog.dom.safe.setOuterHtml=function(a,b){a.outerHTML=goog.html.SafeHtml.unwrap(b)};goog.dom.safe.setStyle=function(a,b){a.style.cssText=goog.html.SafeStyle.unwrap(b)};goog.dom.safe.documentWrite=function(a,b){a.write(goog.html.SafeHtml.unwrap(b))};
                +goog.dom.safe.setAnchorHref=function(a,b){goog.dom.safe.assertIsHTMLAnchorElement_(a);var c=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.href=goog.html.SafeUrl.unwrap(c)};goog.dom.safe.setImageSrc=function(a,b){goog.dom.safe.assertIsHTMLImageElement_(a);var c=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.src=goog.html.SafeUrl.unwrap(c)};goog.dom.safe.setEmbedSrc=function(a,b){goog.dom.safe.assertIsHTMLEmbedElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};
                +goog.dom.safe.setFrameSrc=function(a,b){goog.dom.safe.assertIsHTMLFrameElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setIframeSrc=function(a,b){goog.dom.safe.assertIsHTMLIFrameElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setIframeSrcdoc=function(a,b){goog.dom.safe.assertIsHTMLIFrameElement_(a);a.srcdoc=goog.html.SafeHtml.unwrap(b)};
                +goog.dom.safe.setLinkHrefAndRel=function(a,b,c){goog.dom.safe.assertIsHTMLLinkElement_(a);a.rel=c;goog.string.caseInsensitiveContains(c,"stylesheet")?(goog.asserts.assert(b instanceof goog.html.TrustedResourceUrl,'URL must be TrustedResourceUrl because "rel" contains "stylesheet"'),a.href=goog.html.TrustedResourceUrl.unwrap(b)):a.href=b instanceof goog.html.TrustedResourceUrl?goog.html.TrustedResourceUrl.unwrap(b):b instanceof goog.html.SafeUrl?goog.html.SafeUrl.unwrap(b):goog.html.SafeUrl.sanitize(b).getTypedStringValue()};
                +goog.dom.safe.setObjectData=function(a,b){goog.dom.safe.assertIsHTMLObjectElement_(a);a.data=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setScriptSrc=function(a,b){goog.dom.safe.assertIsHTMLScriptElement_(a);a.src=goog.html.TrustedResourceUrl.unwrap(b)};goog.dom.safe.setScriptContent=function(a,b){goog.dom.safe.assertIsHTMLScriptElement_(a);a.text=goog.html.SafeScript.unwrap(b)};
                +goog.dom.safe.setLocationHref=function(a,b){goog.dom.safe.assertIsLocation_(a);var c=b instanceof goog.html.SafeUrl?b:goog.html.SafeUrl.sanitize(b);a.href=goog.html.SafeUrl.unwrap(c)};goog.dom.safe.openInWindow=function(a,b,c,d,e){a=a instanceof goog.html.SafeUrl?a:goog.html.SafeUrl.sanitize(a);return(b||window).open(goog.html.SafeUrl.unwrap(a),c?goog.string.Const.unwrap(c):"",d,e)};
                +goog.dom.safe.assertIsLocation_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof Location||!(a instanceof Element)),"Argument is not a Location (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLAnchorElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLAnchorElement&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLAnchorElement||!(a instanceof Location||a instanceof Element)),"Argument is not a HTMLAnchorElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLLinkElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLLinkElement&&"undefined"!=typeof Location&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLLinkElement||!(a instanceof Location||a instanceof Element)),"Argument is not a HTMLLinkElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLImageElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLImageElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLImageElement||!(a instanceof Element)),"Argument is not a HTMLImageElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLEmbedElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLEmbedElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLEmbedElement||!(a instanceof Element)),"Argument is not a HTMLEmbedElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLFrameElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLFrameElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLFrameElement||!(a instanceof Element)),"Argument is not a HTMLFrameElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLIFrameElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLIFrameElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLIFrameElement||!(a instanceof Element)),"Argument is not a HTMLIFrameElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLObjectElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLObjectElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLObjectElement||!(a instanceof Element)),"Argument is not a HTMLObjectElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.assertIsHTMLScriptElement_=function(a){goog.asserts.ENABLE_ASSERTS&&"undefined"!=typeof HTMLScriptElement&&"undefined"!=typeof Element&&goog.asserts.assert(a&&(a instanceof HTMLScriptElement||!(a instanceof Element)),"Argument is not a HTMLScriptElement (or a non-Element mock); got: %s",goog.dom.safe.debugStringForType_(a));return a};
                +goog.dom.safe.debugStringForType_=function(a){return goog.isObject(a)?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):void 0===a?"undefined":null===a?"null":typeof a};goog.html.uncheckedconversions={};goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract=function(a,b,c){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(b,c||null)};
                +goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeStyleSheetFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(b)};
                +goog.html.uncheckedconversions.trustedResourceUrlFromStringKnownToSatisfyTypeContract=function(a,b){goog.asserts.assertString(goog.string.Const.unwrap(a),"must provide justification");goog.asserts.assert(!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(a)),"must provide non-empty justification");return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(b)};goog.math.Size=function(a,b){this.width=a;this.height=b};goog.math.Size.equals=function(a,b){return a==b?!0:a&&b?a.width==b.width&&a.height==b.height:!1};goog.math.Size.prototype.clone=function(){return new goog.math.Size(this.width,this.height)};goog.DEBUG&&(goog.math.Size.prototype.toString=function(){return"("+this.width+" x "+this.height+")"});goog.math.Size.prototype.getLongest=function(){return Math.max(this.width,this.height)};
                +goog.math.Size.prototype.getShortest=function(){return Math.min(this.width,this.height)};goog.math.Size.prototype.area=function(){return this.width*this.height};goog.math.Size.prototype.perimeter=function(){return 2*(this.width+this.height)};goog.math.Size.prototype.aspectRatio=function(){return this.width/this.height};goog.math.Size.prototype.isEmpty=function(){return!this.area()};goog.math.Size.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};
                +goog.math.Size.prototype.fitsInside=function(a){return this.width<=a.width&&this.height<=a.height};goog.math.Size.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};goog.math.Size.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Size.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.width*=a;this.height*=c;return this};
                +goog.math.Size.prototype.scaleToCover=function(a){a=this.aspectRatio()<=a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.math.Size.prototype.scaleToFit=function(a){a=this.aspectRatio()>a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)};
                +goog.dom.getElementHelper_=function(a,b){return goog.isString(b)?a.getElementById(b):b};goog.dom.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(document,a)};goog.dom.getRequiredElementHelper_=function(a,b){goog.asserts.assertString(b);var c=goog.dom.getElementHelper_(a,b);return c=goog.asserts.assertElement(c,"No element found with id: "+b)};goog.dom.$=goog.dom.getElement;goog.dom.getElementsByTagName=function(a,b){return(b||document).getElementsByTagName(String(a))};
                +goog.dom.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(document,a,b,c)};goog.dom.getElementsByClass=function(a,b){var c=b||document;return goog.dom.canUseQuerySelector_(c)?c.querySelectorAll("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)};
                +goog.dom.getElementByClass=function(a,b){var c=b||document;return(c.getElementsByClassName?c.getElementsByClassName(a)[0]:goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)[0])||null};goog.dom.getRequiredElementByClass=function(a,b){var c=goog.dom.getElementByClass(a,b);return goog.asserts.assert(c,"No element found with className: "+a)};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)};
                +goog.dom.getElementsByTagNameAndClass_=function(a,b,c,d){a=d||a;var e=b&&"*"!=b?String(b).toUpperCase():"";if(goog.dom.canUseQuerySelector_(a)&&(e||c))return a.querySelectorAll(e+(c?"."+c:""));if(c&&a.getElementsByClassName){d=a.getElementsByClassName(c);if(e){a={};for(var f=b=0,g;g=d[f];f++)e==g.nodeName&&(a[b++]=g);a.length=b;return a}return d}d=a.getElementsByTagName(e||"*");if(c){a={};for(f=b=0;g=d[f];f++)e=g.className,"function"==typeof e.split&&goog.array.contains(e.split(/\s+/),c)&&(a[b++]=
                +g);a.length=b;return a}return d};goog.dom.$$=goog.dom.getElementsByTagNameAndClass;goog.dom.setProperties=function(a,b){goog.object.forEach(b,function(b,d){b&&b.implementsGoogStringTypedString&&(b=b.getTypedStringValue());"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(d)?a.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[d],b):goog.string.startsWith(d,"aria-")||goog.string.startsWith(d,"data-")?a.setAttribute(d,b):a[d]=b})};
                +goog.dom.DIRECT_ATTRIBUTE_MAP_={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};goog.dom.getViewportSize=function(a){return goog.dom.getViewportSize_(a||window)};goog.dom.getViewportSize_=function(a){a=a.document;a=goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body;return new goog.math.Size(a.clientWidth,a.clientHeight)};
                +goog.dom.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(window)};goog.dom.getDocumentHeightForWindow=function(a){return goog.dom.getDocumentHeight_(a)};
                +goog.dom.getDocumentHeight_=function(a){var b=a.document,c=0;if(b){var c=b.body,d=b.documentElement;if(!d||!c)return 0;a=goog.dom.getViewportSize_(a).height;if(goog.dom.isCss1CompatMode_(b)&&d.scrollHeight)c=d.scrollHeight!=a?d.scrollHeight:d.offsetHeight;else{var b=d.scrollHeight,e=d.offsetHeight;d.clientHeight!=e&&(b=c.scrollHeight,e=c.offsetHeight);c=b>a?b>e?b:e:b<e?b:e}}return c};goog.dom.getPageScroll=function(a){return goog.dom.getDomHelper((a||goog.global||window).document).getDocumentScroll()};
                +goog.dom.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(document)};goog.dom.getDocumentScroll_=function(a){var b=goog.dom.getDocumentScrollElement_(a);a=goog.dom.getWindow_(a);return goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("10")&&a.pageYOffset!=b.scrollTop?new goog.math.Coordinate(b.scrollLeft,b.scrollTop):new goog.math.Coordinate(a.pageXOffset||b.scrollLeft,a.pageYOffset||b.scrollTop)};goog.dom.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(document)};
                +goog.dom.getDocumentScrollElement_=function(a){return a.scrollingElement?a.scrollingElement:!goog.userAgent.WEBKIT&&goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body||a.documentElement};goog.dom.getWindow=function(a){return a?goog.dom.getWindow_(a):window};goog.dom.getWindow_=function(a){return a.parentWindow||a.defaultView};goog.dom.createDom=function(a,b,c){return goog.dom.createDom_(document,arguments)};
                +goog.dom.createDom_=function(a,b){var c=String(b[0]),d=b[1];if(!goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES&&d&&(d.name||d.type)){c=["<",c];d.name&&c.push(' name="',goog.string.htmlEscape(d.name),'"');if(d.type){c.push(' type="',goog.string.htmlEscape(d.type),'"');var e={};goog.object.extend(e,d);delete e.type;d=e}c.push(">");c=c.join("")}c=a.createElement(c);d&&(goog.isString(d)?c.className=d:goog.isArray(d)?c.className=d.join(" "):goog.dom.setProperties(c,d));2<b.length&&goog.dom.append_(a,
                +c,b,2);return c};goog.dom.append_=function(a,b,c,d){function e(c){c&&b.appendChild(goog.isString(c)?a.createTextNode(c):c)}for(;d<c.length;d++){var f=c[d];goog.isArrayLike(f)&&!goog.dom.isNodeLike(f)?goog.array.forEach(goog.dom.isNodeList(f)?goog.array.toArray(f):f,e):e(f)}};goog.dom.$dom=goog.dom.createDom;goog.dom.createElement=function(a){return goog.dom.createElement_(document,a)};goog.dom.createElement_=function(a,b){return a.createElement(String(b))};goog.dom.createTextNode=function(a){return document.createTextNode(String(a))};
                +goog.dom.createTable=function(a,b,c){return goog.dom.createTable_(document,a,b,!!c)};goog.dom.createTable_=function(a,b,c,d){for(var e=goog.dom.createElement_(a,"TABLE"),f=e.appendChild(goog.dom.createElement_(a,"TBODY")),g=0;g<b;g++){for(var h=goog.dom.createElement_(a,"TR"),k=0;k<c;k++){var l=goog.dom.createElement_(a,"TD");d&&goog.dom.setTextContent(l,goog.string.Unicode.NBSP);h.appendChild(l)}f.appendChild(h)}return e};
                +goog.dom.constHtmlToNode=function(a){var b=goog.array.map(arguments,goog.string.Const.unwrap),b=goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from("Constant HTML string, that gets turned into a Node later, so it will be automatically balanced."),b.join(""));return goog.dom.safeHtmlToNode(b)};goog.dom.safeHtmlToNode=function(a){return goog.dom.safeHtmlToNode_(document,a)};
                +goog.dom.safeHtmlToNode_=function(a,b){var c=goog.dom.createElement_(a,"DIV");goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT?(goog.dom.safe.setInnerHtml(c,goog.html.SafeHtml.concat(goog.html.SafeHtml.BR,b)),c.removeChild(c.firstChild)):goog.dom.safe.setInnerHtml(c,b);return goog.dom.childrenToNode_(a,c)};goog.dom.childrenToNode_=function(a,b){if(1==b.childNodes.length)return b.removeChild(b.firstChild);for(var c=a.createDocumentFragment();b.firstChild;)c.appendChild(b.firstChild);return c};
                +goog.dom.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(document)};goog.dom.isCss1CompatMode_=function(a){return goog.dom.COMPAT_MODE_KNOWN_?goog.dom.ASSUME_STANDARDS_MODE:"CSS1Compat"==a.compatMode};goog.dom.canHaveChildren=function(a){if(a.nodeType!=goog.dom.NodeType.ELEMENT)return!1;switch(a.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "COMMAND":case "EMBED":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "KEYGEN":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case "SCRIPT":case "SOURCE":case "STYLE":case "TRACK":case "WBR":return!1}return!0};
                +goog.dom.appendChild=function(a,b){a.appendChild(b)};goog.dom.append=function(a,b){goog.dom.append_(goog.dom.getOwnerDocument(a),a,arguments,1)};goog.dom.removeChildren=function(a){for(var b;b=a.firstChild;)a.removeChild(b)};goog.dom.insertSiblingBefore=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b)};goog.dom.insertSiblingAfter=function(a,b){b.parentNode&&b.parentNode.insertBefore(a,b.nextSibling)};goog.dom.insertChildAt=function(a,b,c){a.insertBefore(b,a.childNodes[c]||null)};
                +goog.dom.removeNode=function(a){return a&&a.parentNode?a.parentNode.removeChild(a):null};goog.dom.replaceNode=function(a,b){var c=b.parentNode;c&&c.replaceChild(a,b)};goog.dom.flattenElement=function(a){var b,c=a.parentNode;if(c&&c.nodeType!=goog.dom.NodeType.DOCUMENT_FRAGMENT){if(a.removeNode)return a.removeNode(!1);for(;b=a.firstChild;)c.insertBefore(b,a);return goog.dom.removeNode(a)}};
                +goog.dom.getChildren=function(a){return goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE&&void 0!=a.children?a.children:goog.array.filter(a.childNodes,function(a){return a.nodeType==goog.dom.NodeType.ELEMENT})};goog.dom.getFirstElementChild=function(a){return goog.isDef(a.firstElementChild)?a.firstElementChild:goog.dom.getNextElementNode_(a.firstChild,!0)};goog.dom.getLastElementChild=function(a){return goog.isDef(a.lastElementChild)?a.lastElementChild:goog.dom.getNextElementNode_(a.lastChild,!1)};
                +goog.dom.getNextElementSibling=function(a){return goog.isDef(a.nextElementSibling)?a.nextElementSibling:goog.dom.getNextElementNode_(a.nextSibling,!0)};goog.dom.getPreviousElementSibling=function(a){return goog.isDef(a.previousElementSibling)?a.previousElementSibling:goog.dom.getNextElementNode_(a.previousSibling,!1)};goog.dom.getNextElementNode_=function(a,b){for(;a&&a.nodeType!=goog.dom.NodeType.ELEMENT;)a=b?a.nextSibling:a.previousSibling;return a};
                +goog.dom.getNextNode=function(a){if(!a)return null;if(a.firstChild)return a.firstChild;for(;a&&!a.nextSibling;)a=a.parentNode;return a?a.nextSibling:null};goog.dom.getPreviousNode=function(a){if(!a)return null;if(!a.previousSibling)return a.parentNode;for(a=a.previousSibling;a&&a.lastChild;)a=a.lastChild;return a};goog.dom.isNodeLike=function(a){return goog.isObject(a)&&0<a.nodeType};goog.dom.isElement=function(a){return goog.isObject(a)&&a.nodeType==goog.dom.NodeType.ELEMENT};
                +goog.dom.isWindow=function(a){return goog.isObject(a)&&a.window==a};goog.dom.getParentElement=function(a){var b;if(goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY&&!(goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("9")&&!goog.userAgent.isVersionOrHigher("10")&&goog.global.SVGElement&&a instanceof goog.global.SVGElement)&&(b=a.parentElement))return b;b=a.parentNode;return goog.dom.isElement(b)?b:null};
                +goog.dom.contains=function(a,b){if(!a||!b)return!1;if(a.contains&&b.nodeType==goog.dom.NodeType.ELEMENT)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||!!(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};
                +goog.dom.compareNodeOrder=function(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)){if(a.nodeType==goog.dom.NodeType.DOCUMENT)return-1;if(b.nodeType==goog.dom.NodeType.DOCUMENT)return 1}if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=a.nodeType==goog.dom.NodeType.ELEMENT,d=b.nodeType==goog.dom.NodeType.ELEMENT;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,
                +f=b.parentNode;return e==f?goog.dom.compareSiblingOrder_(a,b):!c&&goog.dom.contains(e,b)?-1*goog.dom.compareParentsDescendantNodeIe_(a,b):!d&&goog.dom.contains(f,a)?goog.dom.compareParentsDescendantNodeIe_(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=goog.dom.getOwnerDocument(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0);return c.compareBoundaryPoints(goog.global.Range.START_TO_END,d)};
                +goog.dom.compareParentsDescendantNodeIe_=function(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return goog.dom.compareSiblingOrder_(d,a)};goog.dom.compareSiblingOrder_=function(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1};
                +goog.dom.findCommonAncestor=function(a){var b,c=arguments.length;if(!c)return null;if(1==c)return arguments[0];var d=[],e=Infinity;for(b=0;b<c;b++){for(var f=[],g=arguments[b];g;)f.unshift(g),g=g.parentNode;d.push(f);e=Math.min(e,f.length)}f=null;for(b=0;b<e;b++){for(var g=d[0][b],h=1;h<c;h++)if(g!=d[h][b])return f;f=g}return f};goog.dom.getOwnerDocument=function(a){goog.asserts.assert(a,"Node cannot be null or undefined.");return a.nodeType==goog.dom.NodeType.DOCUMENT?a:a.ownerDocument||a.document};
                +goog.dom.getFrameContentDocument=function(a){return a.contentDocument||a.contentWindow.document};goog.dom.getFrameContentWindow=function(a){try{return a.contentWindow||(a.contentDocument?goog.dom.getWindow(a.contentDocument):null)}catch(b){}return null};
                +goog.dom.setTextContent=function(a,b){goog.asserts.assert(null!=a,"goog.dom.setTextContent expects a non-null value for node");if("textContent"in a)a.textContent=b;else if(a.nodeType==goog.dom.NodeType.TEXT)a.data=b;else if(a.firstChild&&a.firstChild.nodeType==goog.dom.NodeType.TEXT){for(;a.lastChild!=a.firstChild;)a.removeChild(a.lastChild);a.firstChild.data=b}else{goog.dom.removeChildren(a);var c=goog.dom.getOwnerDocument(a);a.appendChild(c.createTextNode(String(b)))}};
                +goog.dom.getOuterHtml=function(a){goog.asserts.assert(null!==a,"goog.dom.getOuterHtml expects a non-null value for element");if("outerHTML"in a)return a.outerHTML;var b=goog.dom.getOwnerDocument(a),b=goog.dom.createElement_(b,"DIV");b.appendChild(a.cloneNode(!0));return b.innerHTML};goog.dom.findNode=function(a,b){var c=[];return goog.dom.findNodes_(a,b,c,!0)?c[0]:void 0};goog.dom.findNodes=function(a,b){var c=[];goog.dom.findNodes_(a,b,c,!1);return c};
                +goog.dom.findNodes_=function(a,b,c,d){if(null!=a)for(a=a.firstChild;a;){if(b(a)&&(c.push(a),d)||goog.dom.findNodes_(a,b,c,d))return!0;a=a.nextSibling}return!1};goog.dom.TAGS_TO_IGNORE_={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1};goog.dom.PREDEFINED_TAG_VALUES_={IMG:" ",BR:"\n"};goog.dom.isFocusableTabIndex=function(a){return goog.dom.hasSpecifiedTabIndex_(a)&&goog.dom.isTabIndexFocusable_(a)};goog.dom.setFocusableTabIndex=function(a,b){b?a.tabIndex=0:(a.tabIndex=-1,a.removeAttribute("tabIndex"))};
                +goog.dom.isFocusable=function(a){var b;return(b=goog.dom.nativelySupportsFocus_(a)?!a.disabled&&(!goog.dom.hasSpecifiedTabIndex_(a)||goog.dom.isTabIndexFocusable_(a)):goog.dom.isFocusableTabIndex(a))&&goog.userAgent.IE?goog.dom.hasNonZeroBoundingRect_(a):b};goog.dom.hasSpecifiedTabIndex_=function(a){return goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9")?(a=a.getAttributeNode("tabindex"),goog.isDefAndNotNull(a)&&a.specified):a.hasAttribute("tabindex")};
                +goog.dom.isTabIndexFocusable_=function(a){a=a.tabIndex;return goog.isNumber(a)&&0<=a&&32768>a};goog.dom.nativelySupportsFocus_=function(a){return"A"==a.tagName||"INPUT"==a.tagName||"TEXTAREA"==a.tagName||"SELECT"==a.tagName||"BUTTON"==a.tagName};goog.dom.hasNonZeroBoundingRect_=function(a){a=!goog.isFunction(a.getBoundingClientRect)||goog.userAgent.IE&&null==a.parentElement?{height:a.offsetHeight,width:a.offsetWidth}:a.getBoundingClientRect();return goog.isDefAndNotNull(a)&&0<a.height&&0<a.width};
                +goog.dom.getTextContent=function(a){if(goog.dom.BrowserFeature.CAN_USE_INNER_TEXT&&null!==a&&"innerText"in a)a=goog.string.canonicalizeNewlines(a.innerText);else{var b=[];goog.dom.getTextContent_(a,b,!0);a=b.join("")}a=a.replace(/ \xAD /g," ").replace(/\xAD/g,"");a=a.replace(/\u200B/g,"");goog.dom.BrowserFeature.CAN_USE_INNER_TEXT||(a=a.replace(/ +/g," "));" "!=a&&(a=a.replace(/^\s*/,""));return a};goog.dom.getRawTextContent=function(a){var b=[];goog.dom.getTextContent_(a,b,!1);return b.join("")};
                +goog.dom.getTextContent_=function(a,b,c){if(!(a.nodeName in goog.dom.TAGS_TO_IGNORE_))if(a.nodeType==goog.dom.NodeType.TEXT)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)b.push(goog.dom.PREDEFINED_TAG_VALUES_[a.nodeName]);else for(a=a.firstChild;a;)goog.dom.getTextContent_(a,b,c),a=a.nextSibling};goog.dom.getNodeTextLength=function(a){return goog.dom.getTextContent(a).length};
                +goog.dom.getNodeTextOffset=function(a,b){for(var c=b||goog.dom.getOwnerDocument(a).body,d=[];a&&a!=c;){for(var e=a;e=e.previousSibling;)d.unshift(goog.dom.getTextContent(e));a=a.parentNode}return goog.string.trimLeft(d.join("")).replace(/ +/g," ").length};
                +goog.dom.getNodeAtOffset=function(a,b,c){a=[a];for(var d=0,e=null;0<a.length&&d<b;)if(e=a.pop(),!(e.nodeName in goog.dom.TAGS_TO_IGNORE_))if(e.nodeType==goog.dom.NodeType.TEXT)var f=e.nodeValue.replace(/(\r\n|\r|\n)/g,"").replace(/ +/g," "),d=d+f.length;else if(e.nodeName in goog.dom.PREDEFINED_TAG_VALUES_)d+=goog.dom.PREDEFINED_TAG_VALUES_[e.nodeName].length;else for(f=e.childNodes.length-1;0<=f;f--)a.push(e.childNodes[f]);goog.isObject(c)&&(c.remainder=e?e.nodeValue.length+b-d-1:0,c.node=e);return e};
                +goog.dom.isNodeList=function(a){if(a&&"number"==typeof a.length){if(goog.isObject(a))return"function"==typeof a.item||"string"==typeof a.item;if(goog.isFunction(a))return"function"==typeof a.item}return!1};goog.dom.getAncestorByTagNameAndClass=function(a,b,c,d){if(!b&&!c)return null;var e=b?String(b).toUpperCase():null;return goog.dom.getAncestor(a,function(a){return(!e||a.nodeName==e)&&(!c||goog.isString(a.className)&&goog.array.contains(a.className.split(/\s+/),c))},!0,d)};
                +goog.dom.getAncestorByClass=function(a,b,c){return goog.dom.getAncestorByTagNameAndClass(a,null,b,c)};goog.dom.getAncestor=function(a,b,c,d){a&&!c&&(a=a.parentNode);for(c=0;a&&(null==d||c<=d);){goog.asserts.assert("parentNode"!=a.name);if(b(a))return a;a=a.parentNode;c++}return null};goog.dom.getActiveElement=function(a){try{return a&&a.activeElement}catch(b){}return null};
                +goog.dom.getPixelRatio=function(){var a=goog.dom.getWindow();return goog.isDef(a.devicePixelRatio)?a.devicePixelRatio:a.matchMedia?goog.dom.matchesPixelRatio_(3)||goog.dom.matchesPixelRatio_(2)||goog.dom.matchesPixelRatio_(1.5)||goog.dom.matchesPixelRatio_(1)||.75:1};goog.dom.matchesPixelRatio_=function(a){return goog.dom.getWindow().matchMedia("(min-resolution: "+a+"dppx),(min--moz-device-pixel-ratio: "+a+"),(min-resolution: "+96*a+"dpi)").matches?a:0};goog.dom.getCanvasContext2D=function(a){return a.getContext("2d")};
                +goog.dom.DomHelper=function(a){this.document_=a||goog.global.document||document};goog.dom.DomHelper.prototype.getDomHelper=goog.dom.getDomHelper;goog.dom.DomHelper.prototype.setDocument=function(a){this.document_=a};goog.dom.DomHelper.prototype.getDocument=function(){return this.document_};goog.dom.DomHelper.prototype.getElement=function(a){return goog.dom.getElementHelper_(this.document_,a)};
                +goog.dom.DomHelper.prototype.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.$=goog.dom.DomHelper.prototype.getElement;goog.dom.DomHelper.prototype.getElementsByTagName=function(a,b){return(b||this.document_).getElementsByTagName(String(a))};goog.dom.DomHelper.prototype.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(this.document_,a,b,c)};
                +goog.dom.DomHelper.prototype.getElementsByClass=function(a,b){return goog.dom.getElementsByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getElementByClass=function(a,b){return goog.dom.getElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getRequiredElementByClass=function(a,b){return goog.dom.getRequiredElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.$$=goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
                +goog.dom.DomHelper.prototype.setProperties=goog.dom.setProperties;goog.dom.DomHelper.prototype.getViewportSize=function(a){return goog.dom.getViewportSize(a||this.getWindow())};goog.dom.DomHelper.prototype.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(this.getWindow())};goog.dom.DomHelper.prototype.createDom=function(a,b,c){return goog.dom.createDom_(this.document_,arguments)};goog.dom.DomHelper.prototype.$dom=goog.dom.DomHelper.prototype.createDom;
                +goog.dom.DomHelper.prototype.createElement=function(a){return goog.dom.createElement_(this.document_,a)};goog.dom.DomHelper.prototype.createTextNode=function(a){return this.document_.createTextNode(String(a))};goog.dom.DomHelper.prototype.createTable=function(a,b,c){return goog.dom.createTable_(this.document_,a,b,!!c)};goog.dom.DomHelper.prototype.safeHtmlToNode=function(a){return goog.dom.safeHtmlToNode_(this.document_,a)};goog.dom.DomHelper.prototype.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(this.document_)};
                +goog.dom.DomHelper.prototype.getWindow=function(){return goog.dom.getWindow_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(this.document_)};goog.dom.DomHelper.prototype.getActiveElement=function(a){return goog.dom.getActiveElement(a||this.document_)};goog.dom.DomHelper.prototype.appendChild=goog.dom.appendChild;
                +goog.dom.DomHelper.prototype.append=goog.dom.append;goog.dom.DomHelper.prototype.canHaveChildren=goog.dom.canHaveChildren;goog.dom.DomHelper.prototype.removeChildren=goog.dom.removeChildren;goog.dom.DomHelper.prototype.insertSiblingBefore=goog.dom.insertSiblingBefore;goog.dom.DomHelper.prototype.insertSiblingAfter=goog.dom.insertSiblingAfter;goog.dom.DomHelper.prototype.insertChildAt=goog.dom.insertChildAt;goog.dom.DomHelper.prototype.removeNode=goog.dom.removeNode;
                +goog.dom.DomHelper.prototype.replaceNode=goog.dom.replaceNode;goog.dom.DomHelper.prototype.flattenElement=goog.dom.flattenElement;goog.dom.DomHelper.prototype.getChildren=goog.dom.getChildren;goog.dom.DomHelper.prototype.getFirstElementChild=goog.dom.getFirstElementChild;goog.dom.DomHelper.prototype.getLastElementChild=goog.dom.getLastElementChild;goog.dom.DomHelper.prototype.getNextElementSibling=goog.dom.getNextElementSibling;goog.dom.DomHelper.prototype.getPreviousElementSibling=goog.dom.getPreviousElementSibling;
                +goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper.prototype.getPreviousNode=goog.dom.getPreviousNode;goog.dom.DomHelper.prototype.isNodeLike=goog.dom.isNodeLike;goog.dom.DomHelper.prototype.isElement=goog.dom.isElement;goog.dom.DomHelper.prototype.isWindow=goog.dom.isWindow;goog.dom.DomHelper.prototype.getParentElement=goog.dom.getParentElement;goog.dom.DomHelper.prototype.contains=goog.dom.contains;goog.dom.DomHelper.prototype.compareNodeOrder=goog.dom.compareNodeOrder;
                +goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode;
                +goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset;
                +goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.dom.DomHelper.prototype.getCanvasContext2D=goog.dom.getCanvasContext2D;goog.color={};
                +goog.color.names={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",
                +darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",
                +ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",
                +lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",
                +moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",
                +seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};goog.color.parse=function(a){var b={};a=String(a);var c=goog.color.prependHashIfNecessaryHelper(a);if(goog.color.isValidHexColor_(c))return b.hex=goog.color.normalizeHex(c),b.type="hex",b;c=goog.color.isValidRgbColor_(a);if(c.length)return b.hex=goog.color.rgbArrayToHex(c),b.type="rgb",b;if(goog.color.names&&(c=goog.color.names[a.toLowerCase()]))return b.hex=c,b.type="named",b;throw Error(a+" is not a valid color string");};
                +goog.color.isValidColor=function(a){var b=goog.color.prependHashIfNecessaryHelper(a);return!!(goog.color.isValidHexColor_(b)||goog.color.isValidRgbColor_(a).length||goog.color.names&&goog.color.names[a.toLowerCase()])};goog.color.parseRgb=function(a){var b=goog.color.isValidRgbColor_(a);if(!b.length)throw Error(a+" is not a valid RGB color");return b};goog.color.hexToRgbStyle=function(a){return goog.color.rgbStyle_(goog.color.hexToRgb(a))};goog.color.hexTripletRe_=/#(.)(.)(.)/;
                +goog.color.normalizeHex=function(a){if(!goog.color.isValidHexColor_(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(goog.color.hexTripletRe_,"#$1$1$2$2$3$3"));return a.toLowerCase()};goog.color.hexToRgb=function(a){a=goog.color.normalizeHex(a);var b=parseInt(a.substr(1,2),16),c=parseInt(a.substr(3,2),16);a=parseInt(a.substr(5,2),16);return[b,c,a]};
                +goog.color.rgbToHex=function(a,b,c){a=Number(a);b=Number(b);c=Number(c);if(a!=(a&255)||b!=(b&255)||c!=(c&255))throw Error('"('+a+","+b+","+c+'") is not a valid RGB color');a=goog.color.prependZeroIfNecessaryHelper(a.toString(16));b=goog.color.prependZeroIfNecessaryHelper(b.toString(16));c=goog.color.prependZeroIfNecessaryHelper(c.toString(16));return"#"+a+b+c};goog.color.rgbArrayToHex=function(a){return goog.color.rgbToHex(a[0],a[1],a[2])};
                +goog.color.rgbToHsl=function(a,b,c){a/=255;b/=255;c/=255;var d=Math.max(a,b,c),e=Math.min(a,b,c),f=0,g=0,h=.5*(d+e);d!=e&&(d==a?f=60*(b-c)/(d-e):d==b?f=60*(c-a)/(d-e)+120:d==c&&(f=60*(a-b)/(d-e)+240),g=0<h&&.5>=h?(d-e)/(2*h):(d-e)/(2-2*h));return[Math.round(f+360)%360,g,h]};goog.color.rgbArrayToHsl=function(a){return goog.color.rgbToHsl(a[0],a[1],a[2])};goog.color.hueToRgb_=function(a,b,c){0>c?c+=1:1<c&&--c;return 1>6*c?a+6*(b-a)*c:1>2*c?b:2>3*c?a+(b-a)*(2/3-c)*6:a};
                +goog.color.hslToRgb=function(a,b,c){a/=360;if(0==b)c=b=a=255*c;else{var d=.5>c?c*(1+b):c+b-b*c;var e=2*c-d;c=255*goog.color.hueToRgb_(e,d,a+1/3);b=255*goog.color.hueToRgb_(e,d,a);a=255*goog.color.hueToRgb_(e,d,a-1/3)}return[Math.round(c),Math.round(b),Math.round(a)]};goog.color.hslArrayToRgb=function(a){return goog.color.hslToRgb(a[0],a[1],a[2])};goog.color.validHexColorRe_=/^#(?:[0-9a-f]{3}){1,2}$/i;goog.color.isValidHexColor_=function(a){return goog.color.validHexColorRe_.test(a)};
                +goog.color.normalizedHexColorRe_=/^#[0-9a-f]{6}$/;goog.color.isNormalizedHexColor_=function(a){return goog.color.normalizedHexColorRe_.test(a)};goog.color.rgbColorRe_=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;goog.color.isValidRgbColor_=function(a){var b=a.match(goog.color.rgbColorRe_);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};
                +goog.color.prependZeroIfNecessaryHelper=function(a){return 1==a.length?"0"+a:a};goog.color.prependHashIfNecessaryHelper=function(a){return"#"==a.charAt(0)?a:"#"+a};goog.color.rgbStyle_=function(a){return"rgb("+a.join(",")+")"};
                +goog.color.hsvToRgb=function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=c;else{var g=Math.floor(a/60),h=a/60-g;a=c*(1-b);var k=c*(1-b*h);b=c*(1-b*(1-h));switch(g){case 1:d=k;e=c;f=a;break;case 2:d=a;e=c;f=b;break;case 3:d=a;e=k;f=c;break;case 4:d=b;e=a;f=c;break;case 5:d=c;e=a;f=k;break;case 6:case 0:d=c,e=b,f=a}}return[Math.floor(d),Math.floor(e),Math.floor(f)]};
                +goog.color.rgbToHsv=function(a,b,c){var d=Math.max(Math.max(a,b),c),e=Math.min(Math.min(a,b),c);if(e==d)e=a=0;else{var f=d-e,e=f/d;a=60*(a==d?(b-c)/f:b==d?2+(c-a)/f:4+(a-b)/f);0>a&&(a+=360);360<a&&(a-=360)}return[a,e,d]};goog.color.rgbArrayToHsv=function(a){return goog.color.rgbToHsv(a[0],a[1],a[2])};goog.color.hsvArrayToRgb=function(a){return goog.color.hsvToRgb(a[0],a[1],a[2])};goog.color.hexToHsl=function(a){a=goog.color.hexToRgb(a);return goog.color.rgbToHsl(a[0],a[1],a[2])};
                +goog.color.hslToHex=function(a,b,c){return goog.color.rgbArrayToHex(goog.color.hslToRgb(a,b,c))};goog.color.hslArrayToHex=function(a){return goog.color.rgbArrayToHex(goog.color.hslToRgb(a[0],a[1],a[2]))};goog.color.hexToHsv=function(a){return goog.color.rgbArrayToHsv(goog.color.hexToRgb(a))};goog.color.hsvToHex=function(a,b,c){return goog.color.rgbArrayToHex(goog.color.hsvToRgb(a,b,c))};goog.color.hsvArrayToHex=function(a){return goog.color.hsvToHex(a[0],a[1],a[2])};
                +goog.color.hslDistance=function(a,b){var c=.5>=a[2]?a[1]*a[2]:a[1]*(1-a[2]);var d=.5>=b[2]?b[1]*b[2]:b[1]*(1-b[2]);return(a[2]-b[2])*(a[2]-b[2])+c*c+d*d-2*c*d*Math.cos(2*(a[0]/360-b[0]/360)*Math.PI)};goog.color.blend=function(a,b,c){c=goog.math.clamp(c,0,1);return[Math.round(c*a[0]+(1-c)*b[0]),Math.round(c*a[1]+(1-c)*b[1]),Math.round(c*a[2]+(1-c)*b[2])]};goog.color.darken=function(a,b){return goog.color.blend([0,0,0],a,b)};goog.color.lighten=function(a,b){return goog.color.blend([255,255,255],a,b)};
                +goog.color.highContrast=function(a,b){for(var c=[],d=0;d<b.length;d++)c.push({color:b[d],diff:goog.color.yiqBrightnessDiff_(b[d],a)+goog.color.colorDiff_(b[d],a)});c.sort(function(a,b){return b.diff-a.diff});return c[0].color};goog.color.yiqBrightness_=function(a){return Math.round((299*a[0]+587*a[1]+114*a[2])/1E3)};goog.color.yiqBrightnessDiff_=function(a,b){return Math.abs(goog.color.yiqBrightness_(a)-goog.color.yiqBrightness_(b))};
                +goog.color.colorDiff_=function(a,b){return Math.abs(a[0]-b[0])+Math.abs(a[1]-b[1])+Math.abs(a[2]-b[2])};goog.dom.vendor={};goog.dom.vendor.getVendorJsPrefix=function(){return goog.userAgent.WEBKIT?"Webkit":goog.userAgent.GECKO?"Moz":goog.userAgent.IE?"ms":goog.userAgent.OPERA?"O":null};goog.dom.vendor.getVendorPrefix=function(){return goog.userAgent.WEBKIT?"-webkit":goog.userAgent.GECKO?"-moz":goog.userAgent.IE?"-ms":goog.userAgent.OPERA?"-o":null};
                +goog.dom.vendor.getPrefixedPropertyName=function(a,b){if(b&&a in b)return a;var c=goog.dom.vendor.getVendorJsPrefix();return c?(c=c.toLowerCase(),c+=goog.string.toTitleCase(a),!goog.isDef(b)||c in b?c:null):null};goog.dom.vendor.getPrefixedEventType=function(a){return((goog.dom.vendor.getVendorJsPrefix()||"")+a).toLowerCase()};goog.html.legacyconversions={};goog.html.legacyconversions.safeHtmlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(a,null)};goog.html.legacyconversions.safeStyleFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.legacyconversions.safeStyleSheetFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(a)};goog.html.legacyconversions.safeUrlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(a)};goog.html.legacyconversions.trustedResourceUrlFromString=function(a){goog.html.legacyconversions.reportCallback_();return goog.html.TrustedResourceUrl.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(a)};
                +goog.html.legacyconversions.reportCallback_=goog.nullFunction;goog.html.legacyconversions.setReportCallback=function(a){goog.html.legacyconversions.reportCallback_=a};goog.math.Box=function(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d};goog.math.Box.boundingBox=function(a){for(var b=new goog.math.Box(arguments[0].y,arguments[0].x,arguments[0].y,arguments[0].x),c=1;c<arguments.length;c++)b.expandToIncludeCoordinate(arguments[c]);return b};goog.math.Box.prototype.getWidth=function(){return this.right-this.left};goog.math.Box.prototype.getHeight=function(){return this.bottom-this.top};
                +goog.math.Box.prototype.clone=function(){return new goog.math.Box(this.top,this.right,this.bottom,this.left)};goog.DEBUG&&(goog.math.Box.prototype.toString=function(){return"("+this.top+"t, "+this.right+"r, "+this.bottom+"b, "+this.left+"l)"});goog.math.Box.prototype.contains=function(a){return goog.math.Box.contains(this,a)};
                +goog.math.Box.prototype.expand=function(a,b,c,d){goog.isObject(a)?(this.top-=a.top,this.right+=a.right,this.bottom+=a.bottom,this.left-=a.left):(this.top-=a,this.right+=Number(b),this.bottom+=Number(c),this.left-=Number(d));return this};goog.math.Box.prototype.expandToInclude=function(a){this.left=Math.min(this.left,a.left);this.top=Math.min(this.top,a.top);this.right=Math.max(this.right,a.right);this.bottom=Math.max(this.bottom,a.bottom)};
                +goog.math.Box.prototype.expandToIncludeCoordinate=function(a){this.top=Math.min(this.top,a.y);this.right=Math.max(this.right,a.x);this.bottom=Math.max(this.bottom,a.y);this.left=Math.min(this.left,a.x)};goog.math.Box.equals=function(a,b){return a==b?!0:a&&b?a.top==b.top&&a.right==b.right&&a.bottom==b.bottom&&a.left==b.left:!1};
                +goog.math.Box.contains=function(a,b){return a&&b?b instanceof goog.math.Box?b.left>=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom:b.x>=a.left&&b.x<=a.right&&b.y>=a.top&&b.y<=a.bottom:!1};goog.math.Box.relativePositionX=function(a,b){return b.x<a.left?b.x-a.left:b.x>a.right?b.x-a.right:0};goog.math.Box.relativePositionY=function(a,b){return b.y<a.top?b.y-a.top:b.y>a.bottom?b.y-a.bottom:0};
                +goog.math.Box.distance=function(a,b){var c=goog.math.Box.relativePositionX(a,b),d=goog.math.Box.relativePositionY(a,b);return Math.sqrt(c*c+d*d)};goog.math.Box.intersects=function(a,b){return a.left<=b.right&&b.left<=a.right&&a.top<=b.bottom&&b.top<=a.bottom};goog.math.Box.intersectsWithPadding=function(a,b,c){return a.left<=b.right+c&&b.left<=a.right+c&&a.top<=b.bottom+c&&b.top<=a.bottom+c};
                +goog.math.Box.prototype.ceil=function(){this.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};goog.math.Box.prototype.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};
                +goog.math.Box.prototype.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};goog.math.Box.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(goog.asserts.assertNumber(a),this.left+=a,this.right+=a,goog.isNumber(b)&&(this.top+=b,this.bottom+=b));return this};
                +goog.math.Box.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};goog.math.IRect=function(){};goog.math.Rect=function(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d};goog.math.Rect.prototype.clone=function(){return new goog.math.Rect(this.left,this.top,this.width,this.height)};goog.math.Rect.prototype.toBox=function(){return new goog.math.Box(this.top,this.left+this.width,this.top+this.height,this.left)};goog.math.Rect.createFromPositionAndSize=function(a,b){return new goog.math.Rect(a.x,a.y,b.width,b.height)};
                +goog.math.Rect.createFromBox=function(a){return new goog.math.Rect(a.left,a.top,a.right-a.left,a.bottom-a.top)};goog.DEBUG&&(goog.math.Rect.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"});goog.math.Rect.equals=function(a,b){return a==b?!0:a&&b?a.left==b.left&&a.width==b.width&&a.top==b.top&&a.height==b.height:!1};
                +goog.math.Rect.prototype.intersection=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,!0}return!1};
                +goog.math.Rect.intersection=function(a,b){var c=Math.max(a.left,b.left),d=Math.min(a.left+a.width,b.left+b.width);if(c<=d){var e=Math.max(a.top,b.top),f=Math.min(a.top+a.height,b.top+b.height);if(e<=f)return new goog.math.Rect(c,e,d-c,f-e)}return null};goog.math.Rect.intersects=function(a,b){return a.left<=b.left+b.width&&b.left<=a.left+a.width&&a.top<=b.top+b.height&&b.top<=a.top+a.height};goog.math.Rect.prototype.intersects=function(a){return goog.math.Rect.intersects(this,a)};
                +goog.math.Rect.difference=function(a,b){var c=goog.math.Rect.intersection(a,b);if(!c||!c.height||!c.width)return[a.clone()];var c=[],d=a.top,e=a.height,f=a.left+a.width,g=a.top+a.height,h=b.left+b.width,k=b.top+b.height;b.top>a.top&&(c.push(new goog.math.Rect(a.left,a.top,a.width,b.top-a.top)),d=b.top,e-=b.top-a.top);k<g&&(c.push(new goog.math.Rect(a.left,k,a.width,g-k)),e=k-d);b.left>a.left&&c.push(new goog.math.Rect(a.left,d,b.left-a.left,e));h<f&&c.push(new goog.math.Rect(h,d,f-h,e));return c};
                +goog.math.Rect.prototype.difference=function(a){return goog.math.Rect.difference(this,a)};goog.math.Rect.prototype.boundingRect=function(a){var b=Math.max(this.left+this.width,a.left+a.width),c=Math.max(this.top+this.height,a.top+a.height);this.left=Math.min(this.left,a.left);this.top=Math.min(this.top,a.top);this.width=b-this.left;this.height=c-this.top};goog.math.Rect.boundingRect=function(a,b){if(!a||!b)return null;var c=new goog.math.Rect(a.left,a.top,a.width,a.height);c.boundingRect(b);return c};
                +goog.math.Rect.prototype.contains=function(a){return a instanceof goog.math.Coordinate?a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height:this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height};goog.math.Rect.prototype.squaredDistance=function(a){var b=a.x<this.left?this.left-a.x:Math.max(a.x-(this.left+this.width),0);a=a.y<this.top?this.top-a.y:Math.max(a.y-(this.top+this.height),0);return b*b+a*a};
                +goog.math.Rect.prototype.distance=function(a){return Math.sqrt(this.squaredDistance(a))};goog.math.Rect.prototype.getSize=function(){return new goog.math.Size(this.width,this.height)};goog.math.Rect.prototype.getTopLeft=function(){return new goog.math.Coordinate(this.left,this.top)};goog.math.Rect.prototype.getCenter=function(){return new goog.math.Coordinate(this.left+this.width/2,this.top+this.height/2)};
                +goog.math.Rect.prototype.getBottomRight=function(){return new goog.math.Coordinate(this.left+this.width,this.top+this.height)};goog.math.Rect.prototype.ceil=function(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};goog.math.Rect.prototype.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};
                +goog.math.Rect.prototype.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};goog.math.Rect.prototype.translate=function(a,b){a instanceof goog.math.Coordinate?(this.left+=a.x,this.top+=a.y):(this.left+=goog.asserts.assertNumber(a),goog.isNumber(b)&&(this.top+=b));return this};
                +goog.math.Rect.prototype.scale=function(a,b){var c=goog.isNumber(b)?b:a;this.left*=a;this.width*=a;this.top*=c;this.height*=c;return this};goog.style={};goog.style.setStyle=function(a,b,c){if(goog.isString(b))goog.style.setStyle_(a,c,b);else for(var d in b)goog.style.setStyle_(a,b[d],d)};goog.style.setStyle_=function(a,b,c){(c=goog.style.getVendorJsStyleName_(a,c))&&(a.style[c]=b)};goog.style.styleNameCache_={};
                +goog.style.getVendorJsStyleName_=function(a,b){var c=goog.style.styleNameCache_[b];if(!c){var d=goog.string.toCamelCase(b),c=d;void 0===a.style[d]&&(d=goog.dom.vendor.getVendorJsPrefix()+goog.string.toTitleCase(d),void 0!==a.style[d]&&(c=d));goog.style.styleNameCache_[b]=c}return c};
                +goog.style.getVendorStyleName_=function(a,b){var c=goog.string.toCamelCase(b);return void 0===a.style[c]&&(c=goog.dom.vendor.getVendorJsPrefix()+goog.string.toTitleCase(c),void 0!==a.style[c])?goog.dom.vendor.getVendorPrefix()+"-"+b:b};goog.style.getStyle=function(a,b){var c=a.style[goog.string.toCamelCase(b)];return"undefined"!==typeof c?c:a.style[goog.style.getVendorJsStyleName_(a,b)]||""};
                +goog.style.getComputedStyle=function(a,b){var c=goog.dom.getOwnerDocument(a);return c.defaultView&&c.defaultView.getComputedStyle&&(c=c.defaultView.getComputedStyle(a,null))?c[b]||c.getPropertyValue(b)||"":""};goog.style.getCascadedStyle=function(a,b){return a.currentStyle?a.currentStyle[b]:null};goog.style.getStyle_=function(a,b){return goog.style.getComputedStyle(a,b)||goog.style.getCascadedStyle(a,b)||a.style&&a.style[b]};
                +goog.style.getComputedBoxSizing=function(a){return goog.style.getStyle_(a,"boxSizing")||goog.style.getStyle_(a,"MozBoxSizing")||goog.style.getStyle_(a,"WebkitBoxSizing")||null};goog.style.getComputedPosition=function(a){return goog.style.getStyle_(a,"position")};goog.style.getBackgroundColor=function(a){return goog.style.getStyle_(a,"backgroundColor")};goog.style.getComputedOverflowX=function(a){return goog.style.getStyle_(a,"overflowX")};
                +goog.style.getComputedOverflowY=function(a){return goog.style.getStyle_(a,"overflowY")};goog.style.getComputedZIndex=function(a){return goog.style.getStyle_(a,"zIndex")};goog.style.getComputedTextAlign=function(a){return goog.style.getStyle_(a,"textAlign")};goog.style.getComputedCursor=function(a){return goog.style.getStyle_(a,"cursor")};goog.style.getComputedTransform=function(a){var b=goog.style.getVendorStyleName_(a,"transform");return goog.style.getStyle_(a,b)||goog.style.getStyle_(a,"transform")};
                +goog.style.setPosition=function(a,b,c){if(b instanceof goog.math.Coordinate){var d=b.x;b=b.y}else d=b,b=c;a.style.left=goog.style.getPixelStyleValue_(d,!1);a.style.top=goog.style.getPixelStyleValue_(b,!1)};goog.style.getPosition=function(a){return new goog.math.Coordinate(a.offsetLeft,a.offsetTop)};
                +goog.style.getClientViewportElement=function(a){a=a?goog.dom.getOwnerDocument(a):goog.dom.getDocument();return!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9)||goog.dom.getDomHelper(a).isCss1CompatMode()?a.documentElement:a.body};goog.style.getViewportPageOffset=function(a){var b=a.body;a=a.documentElement;return new goog.math.Coordinate(b.scrollLeft||a.scrollLeft,b.scrollTop||a.scrollTop)};
                +goog.style.getBoundingClientRect_=function(a){try{var b=a.getBoundingClientRect()}catch(c){return{left:0,top:0,right:0,bottom:0}}goog.userAgent.IE&&a.ownerDocument.body&&(a=a.ownerDocument,b.left-=a.documentElement.clientLeft+a.body.clientLeft,b.top-=a.documentElement.clientTop+a.body.clientTop);return b};
                +goog.style.getOffsetParent=function(a){if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(8))return goog.asserts.assert(a&&"offsetParent"in a),a.offsetParent;var b=goog.dom.getOwnerDocument(a),c=goog.style.getStyle_(a,"position"),d="fixed"==c||"absolute"==c;for(a=a.parentNode;a&&a!=b;a=a.parentNode)if(a.nodeType==goog.dom.NodeType.DOCUMENT_FRAGMENT&&a.host&&(a=a.host),c=goog.style.getStyle_(a,"position"),d=d&&"static"==c&&a!=b.documentElement&&a!=b.body,!d&&(a.scrollWidth>a.clientWidth||
                +a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return null};
                +goog.style.getVisibleRectForElement=function(a){for(var b=new goog.math.Box(0,Infinity,Infinity,0),c=goog.dom.getDomHelper(a),d=c.getDocument().body,e=c.getDocument().documentElement,f=c.getDocumentScrollElement();a=goog.style.getOffsetParent(a);)if(!(goog.userAgent.IE&&0==a.clientWidth||goog.userAgent.WEBKIT&&0==a.clientHeight&&a==d)&&a!=d&&a!=e&&"visible"!=goog.style.getStyle_(a,"overflow")){var g=goog.style.getPageOffset(a),h=goog.style.getClientLeftTop(a);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,
                +g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=c.getViewportSize();b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&&b.bottom>b.top&&b.right>b.left?b:null};
                +goog.style.getContainerOffsetToScrollInto=function(a,b,c){var d=b||goog.dom.getDocumentScrollElement();var e=goog.style.getPageOffset(a);var f=goog.style.getPageOffset(d),g=goog.style.getBorderBox(d);d==goog.dom.getDocumentScrollElement()?(b=e.x-d.scrollLeft,e=e.y-d.scrollTop,goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(10)&&(b+=g.left,e+=g.top)):(b=e.x-f.x-g.left,e=e.y-f.y-g.top);g=goog.style.getSizeWithDisplay_(a);a=d.clientWidth-g.width;g=d.clientHeight-g.height;f=d.scrollLeft;d=d.scrollTop;
                +c?(f+=b-a/2,d+=e-g/2):(f+=Math.min(b,Math.max(b-a,0)),d+=Math.min(e,Math.max(e-g,0)));return new goog.math.Coordinate(f,d)};goog.style.scrollIntoContainerView=function(a,b,c){b=b||goog.dom.getDocumentScrollElement();a=goog.style.getContainerOffsetToScrollInto(a,b,c);b.scrollLeft=a.x;b.scrollTop=a.y};goog.style.getClientLeftTop=function(a){return new goog.math.Coordinate(a.clientLeft,a.clientTop)};
                +goog.style.getPageOffset=function(a){var b=goog.dom.getOwnerDocument(a);goog.asserts.assertObject(a,"Parameter is required");var c=new goog.math.Coordinate(0,0),d=goog.style.getClientViewportElement(b);if(a==d)return c;a=goog.style.getBoundingClientRect_(a);b=goog.dom.getDomHelper(b).getDocumentScroll();c.x=a.left+b.x;c.y=a.top+b.y;return c};goog.style.getPageOffsetLeft=function(a){return goog.style.getPageOffset(a).x};goog.style.getPageOffsetTop=function(a){return goog.style.getPageOffset(a).y};
                +goog.style.getFramedPageOffset=function(a,b){var c=new goog.math.Coordinate(0,0),d=goog.dom.getWindow(goog.dom.getOwnerDocument(a));if(!goog.reflect.canAccessProperty(d,"parent"))return c;var e=a;do{var f=d==b?goog.style.getPageOffset(e):goog.style.getClientPositionForElement_(goog.asserts.assert(e));c.x+=f.x;c.y+=f.y}while(d&&d!=b&&d!=d.parent&&(e=d.frameElement)&&(d=d.parent));return c};
                +goog.style.translateRectForAnotherFrame=function(a,b,c){if(b.getDocument()!=c.getDocument()){var d=b.getDocument().body;c=goog.style.getFramedPageOffset(d,c.getWindow());c=goog.math.Coordinate.difference(c,goog.style.getPageOffset(d));!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9)||b.isCss1CompatMode()||(c=goog.math.Coordinate.difference(c,b.getDocumentScroll()));a.left+=c.x;a.top+=c.y}};
                +goog.style.getRelativePosition=function(a,b){var c=goog.style.getClientPosition(a),d=goog.style.getClientPosition(b);return new goog.math.Coordinate(c.x-d.x,c.y-d.y)};goog.style.getClientPositionForElement_=function(a){a=goog.style.getBoundingClientRect_(a);return new goog.math.Coordinate(a.left,a.top)};
                +goog.style.getClientPosition=function(a){goog.asserts.assert(a);if(a.nodeType==goog.dom.NodeType.ELEMENT)return goog.style.getClientPositionForElement_(a);a=a.changedTouches?a.changedTouches[0]:a;return new goog.math.Coordinate(a.clientX,a.clientY)};goog.style.setPageOffset=function(a,b,c){var d=goog.style.getPageOffset(a);b instanceof goog.math.Coordinate&&(c=b.y,b=b.x);b=goog.asserts.assertNumber(b)-d.x;goog.style.setPosition(a,a.offsetLeft+b,a.offsetTop+(Number(c)-d.y))};
                +goog.style.setSize=function(a,b,c){if(b instanceof goog.math.Size)c=b.height,b=b.width;else if(void 0==c)throw Error("missing height argument");goog.style.setWidth(a,b);goog.style.setHeight(a,c)};goog.style.getPixelStyleValue_=function(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a};goog.style.setHeight=function(a,b){a.style.height=goog.style.getPixelStyleValue_(b,!0)};goog.style.setWidth=function(a,b){a.style.width=goog.style.getPixelStyleValue_(b,!0)};
                +goog.style.getSize=function(a){return goog.style.evaluateWithTemporaryDisplay_(goog.style.getSizeWithDisplay_,a)};goog.style.evaluateWithTemporaryDisplay_=function(a,b){if("none"!=goog.style.getStyle_(b,"display"))return a(b);var c=b.style,d=c.display,e=c.visibility,f=c.position;c.visibility="hidden";c.position="absolute";c.display="inline";var g=a(b);c.display=d;c.position=f;c.visibility=e;return g};
                +goog.style.getSizeWithDisplay_=function(a){var b=a.offsetWidth,c=a.offsetHeight,d=goog.userAgent.WEBKIT&&!b&&!c;return goog.isDef(b)&&!d||!a.getBoundingClientRect?new goog.math.Size(b,c):(a=goog.style.getBoundingClientRect_(a),new goog.math.Size(a.right-a.left,a.bottom-a.top))};goog.style.getTransformedSize=function(a){if(!a.getBoundingClientRect)return null;a=goog.style.evaluateWithTemporaryDisplay_(goog.style.getBoundingClientRect_,a);return new goog.math.Size(a.right-a.left,a.bottom-a.top)};
                +goog.style.getBounds=function(a){var b=goog.style.getPageOffset(a);a=goog.style.getSize(a);return new goog.math.Rect(b.x,b.y,a.width,a.height)};goog.style.toCamelCase=function(a){return goog.string.toCamelCase(String(a))};goog.style.toSelectorCase=function(a){return goog.string.toSelectorCase(a)};
                +goog.style.getOpacity=function(a){goog.asserts.assert(a);var b=a.style;a="";"opacity"in b?a=b.opacity:"MozOpacity"in b?a=b.MozOpacity:"filter"in b&&(b=b.filter.match(/alpha\(opacity=([\d.]+)\)/))&&(a=String(b[1]/100));return""==a?a:Number(a)};goog.style.setOpacity=function(a,b){goog.asserts.assert(a);var c=a.style;"opacity"in c?c.opacity=b:"MozOpacity"in c?c.MozOpacity=b:"filter"in c&&(c.filter=""===b?"":"alpha(opacity="+100*Number(b)+")")};
                +goog.style.setTransparentBackgroundImage=function(a,b){var c=a.style;goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?c.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+b+'", sizingMethod="crop")':(c.backgroundImage="url("+b+")",c.backgroundPosition="top left",c.backgroundRepeat="no-repeat")};goog.style.clearTransparentBackgroundImage=function(a){a=a.style;"filter"in a?a.filter="":a.backgroundImage="none"};
                +goog.style.showElement=function(a,b){goog.style.setElementShown(a,b)};goog.style.setElementShown=function(a,b){a.style.display=b?"":"none"};goog.style.isElementShown=function(a){return"none"!=a.style.display};goog.style.installStyles=function(a,b){return goog.style.installSafeStyleSheet(goog.html.legacyconversions.safeStyleSheetFromString(a),b)};
                +goog.style.installSafeStyleSheet=function(a,b){var c=goog.dom.getDomHelper(b),d=c.getDocument();if(goog.userAgent.IE&&d.createStyleSheet){var e=d.createStyleSheet();goog.style.setSafeStyleSheet(e,a)}else d=c.getElementsByTagNameAndClass("HEAD")[0],d||(e=c.getElementsByTagNameAndClass("BODY")[0],d=c.createDom("HEAD"),e.parentNode.insertBefore(d,e)),e=c.createDom("STYLE"),goog.style.setSafeStyleSheet(e,a),c.appendChild(d,e);return e};
                +goog.style.uninstallStyles=function(a){goog.dom.removeNode(a.ownerNode||a.owningElement||a)};goog.style.setStyles=function(a,b){goog.style.setSafeStyleSheet(a,goog.html.legacyconversions.safeStyleSheetFromString(b))};goog.style.setSafeStyleSheet=function(a,b){var c=goog.html.SafeStyleSheet.unwrap(b);goog.userAgent.IE&&goog.isDef(a.cssText)?a.cssText=c:a.innerHTML=c};
                +goog.style.setPreWrap=function(a){a=a.style;goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?(a.whiteSpace="pre",a.wordWrap="break-word"):a.whiteSpace=goog.userAgent.GECKO?"-moz-pre-wrap":"pre-wrap"};goog.style.setInlineBlock=function(a){a=a.style;a.position="relative";goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("8")?(a.zoom="1",a.display="inline"):a.display="inline-block"};goog.style.isRightToLeft=function(a){return"rtl"==goog.style.getStyle_(a,"direction")};
                +goog.style.unselectableStyle_=goog.userAgent.GECKO?"MozUserSelect":goog.userAgent.WEBKIT||goog.userAgent.EDGE?"WebkitUserSelect":null;goog.style.isUnselectable=function(a){return goog.style.unselectableStyle_?"none"==a.style[goog.style.unselectableStyle_].toLowerCase():goog.userAgent.IE||goog.userAgent.OPERA?"on"==a.getAttribute("unselectable"):!1};
                +goog.style.setUnselectable=function(a,b,c){c=c?null:a.getElementsByTagName("*");var d=goog.style.unselectableStyle_;if(d){if(b=b?"none":"",a.style&&(a.style[d]=b),c){a=0;for(var e;e=c[a];a++)e.style&&(e.style[d]=b)}}else if(goog.userAgent.IE||goog.userAgent.OPERA)if(b=b?"on":"",a.setAttribute("unselectable",b),c)for(a=0;e=c[a];a++)e.setAttribute("unselectable",b)};goog.style.getBorderBoxSize=function(a){return new goog.math.Size(a.offsetWidth,a.offsetHeight)};
                +goog.style.setBorderBoxSize=function(a,b){var c=goog.dom.getOwnerDocument(a),d=goog.dom.getDomHelper(c).isCss1CompatMode();if(!goog.userAgent.IE||goog.userAgent.isVersionOrHigher("10")||d&&goog.userAgent.isVersionOrHigher("8"))goog.style.setBoxSizingSize_(a,b,"border-box");else if(c=a.style,d){var d=goog.style.getPaddingBox(a),e=goog.style.getBorderBox(a);c.pixelWidth=b.width-e.left-d.left-d.right-e.right;c.pixelHeight=b.height-e.top-d.top-d.bottom-e.bottom}else c.pixelWidth=b.width,c.pixelHeight=
                +b.height};
                +goog.style.getContentBoxSize=function(a){var b=goog.dom.getOwnerDocument(a),c=goog.userAgent.IE&&a.currentStyle;if(c&&goog.dom.getDomHelper(b).isCss1CompatMode()&&"auto"!=c.width&&"auto"!=c.height&&!c.boxSizing)return b=goog.style.getIePixelValue_(a,c.width,"width","pixelWidth"),a=goog.style.getIePixelValue_(a,c.height,"height","pixelHeight"),new goog.math.Size(b,a);c=goog.style.getBorderBoxSize(a);b=goog.style.getPaddingBox(a);a=goog.style.getBorderBox(a);return new goog.math.Size(c.width-a.left-
                +b.left-b.right-a.right,c.height-a.top-b.top-b.bottom-a.bottom)};
                +goog.style.setContentBoxSize=function(a,b){var c=goog.dom.getOwnerDocument(a),d=goog.dom.getDomHelper(c).isCss1CompatMode();if(!goog.userAgent.IE||goog.userAgent.isVersionOrHigher("10")||d&&goog.userAgent.isVersionOrHigher("8"))goog.style.setBoxSizingSize_(a,b,"content-box");else if(c=a.style,d)c.pixelWidth=b.width,c.pixelHeight=b.height;else{var d=goog.style.getPaddingBox(a),e=goog.style.getBorderBox(a);c.pixelWidth=b.width+e.left+d.left+d.right+e.right;c.pixelHeight=b.height+e.top+d.top+d.bottom+
                +e.bottom}};goog.style.setBoxSizingSize_=function(a,b,c){a=a.style;goog.userAgent.GECKO?a.MozBoxSizing=c:goog.userAgent.WEBKIT?a.WebkitBoxSizing=c:a.boxSizing=c;a.width=Math.max(b.width,0)+"px";a.height=Math.max(b.height,0)+"px"};goog.style.getIePixelValue_=function(a,b,c,d){if(/^\d+px?$/.test(b))return parseInt(b,10);var e=a.style[c],f=a.runtimeStyle[c];a.runtimeStyle[c]=a.currentStyle[c];a.style[c]=b;b=a.style[d];a.style[c]=e;a.runtimeStyle[c]=f;return+b};
                +goog.style.getIePixelDistance_=function(a,b){var c=goog.style.getCascadedStyle(a,b);return c?goog.style.getIePixelValue_(a,c,"left","pixelLeft"):0};
                +goog.style.getBox_=function(a,b){if(goog.userAgent.IE){var c=goog.style.getIePixelDistance_(a,b+"Left");var d=goog.style.getIePixelDistance_(a,b+"Right");var e=goog.style.getIePixelDistance_(a,b+"Top");var f=goog.style.getIePixelDistance_(a,b+"Bottom");return new goog.math.Box(e,d,f,c)}c=goog.style.getComputedStyle(a,b+"Left");d=goog.style.getComputedStyle(a,b+"Right");e=goog.style.getComputedStyle(a,b+"Top");f=goog.style.getComputedStyle(a,b+"Bottom");return new goog.math.Box(parseFloat(e),parseFloat(d),
                +parseFloat(f),parseFloat(c))};goog.style.getPaddingBox=function(a){return goog.style.getBox_(a,"padding")};goog.style.getMarginBox=function(a){return goog.style.getBox_(a,"margin")};goog.style.ieBorderWidthKeywords_={thin:2,medium:4,thick:6};
                +goog.style.getIePixelBorder_=function(a,b){if("none"==goog.style.getCascadedStyle(a,b+"Style"))return 0;var c=goog.style.getCascadedStyle(a,b+"Width");return c in goog.style.ieBorderWidthKeywords_?goog.style.ieBorderWidthKeywords_[c]:goog.style.getIePixelValue_(a,c,"left","pixelLeft")};
                +goog.style.getBorderBox=function(a){if(goog.userAgent.IE&&!goog.userAgent.isDocumentModeOrHigher(9)){var b=goog.style.getIePixelBorder_(a,"borderLeft");var c=goog.style.getIePixelBorder_(a,"borderRight");var d=goog.style.getIePixelBorder_(a,"borderTop");a=goog.style.getIePixelBorder_(a,"borderBottom");return new goog.math.Box(d,c,a,b)}b=goog.style.getComputedStyle(a,"borderLeftWidth");c=goog.style.getComputedStyle(a,"borderRightWidth");d=goog.style.getComputedStyle(a,"borderTopWidth");a=goog.style.getComputedStyle(a,
                +"borderBottomWidth");return new goog.math.Box(parseFloat(d),parseFloat(c),parseFloat(a),parseFloat(b))};goog.style.getFontFamily=function(a){var b=goog.dom.getOwnerDocument(a),c="";if(b.body.createTextRange&&goog.dom.contains(b,a)){b=b.body.createTextRange();b.moveToElementText(a);try{c=b.queryCommandValue("FontName")}catch(d){c=""}}c||(c=goog.style.getStyle_(a,"fontFamily"));a=c.split(",");1<a.length&&(c=a[0]);return goog.string.stripQuotes(c,"\"'")};goog.style.lengthUnitRegex_=/[^\d]+$/;
                +goog.style.getLengthUnits=function(a){return(a=a.match(goog.style.lengthUnitRegex_))&&a[0]||null};goog.style.ABSOLUTE_CSS_LENGTH_UNITS_={cm:1,"in":1,mm:1,pc:1,pt:1};goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_={em:1,ex:1};
                +goog.style.getFontSize=function(a){var b=goog.style.getStyle_(a,"fontSize"),c=goog.style.getLengthUnits(b);if(b&&"px"==c)return parseInt(b,10);if(goog.userAgent.IE){if(String(c)in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_)return goog.style.getIePixelValue_(a,b,"left","pixelLeft");if(a.parentNode&&a.parentNode.nodeType==goog.dom.NodeType.ELEMENT&&String(c)in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_)return a=a.parentNode,c=goog.style.getStyle_(a,"fontSize"),goog.style.getIePixelValue_(a,b==c?"1em":b,
                +"left","pixelLeft")}c=goog.dom.createDom("SPAN",{style:"visibility:hidden;position:absolute;line-height:0;padding:0;margin:0;border:0;height:1em;"});goog.dom.appendChild(a,c);b=c.offsetHeight;goog.dom.removeNode(c);return b};goog.style.parseStyleAttribute=function(a){var b={};goog.array.forEach(a.split(/\s*;\s*/),function(a){var c=a.match(/\s*([\w-]+)\s*\:(.+)/);c&&(a=c[1],c=goog.string.trim(c[2]),b[goog.string.toCamelCase(a.toLowerCase())]=c)});return b};
                +goog.style.toStyleAttribute=function(a){var b=[];goog.object.forEach(a,function(a,d){b.push(goog.string.toSelectorCase(d),":",a,";")});return b.join("")};goog.style.setFloat=function(a,b){a.style[goog.userAgent.IE?"styleFloat":"cssFloat"]=b};goog.style.getFloat=function(a){return a.style[goog.userAgent.IE?"styleFloat":"cssFloat"]||""};
                +goog.style.getScrollbarWidth=function(a){var b=goog.dom.createElement("DIV");a&&(b.className=a);b.style.cssText="overflow:auto;position:absolute;top:0;width:100px;height:100px";a=goog.dom.createElement("DIV");goog.style.setSize(a,"200px","200px");b.appendChild(a);goog.dom.appendChild(goog.dom.getDocument().body,b);a=b.offsetWidth-b.clientWidth;goog.dom.removeNode(b);return a};goog.style.MATRIX_TRANSLATION_REGEX_=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;
                +goog.style.getCssTranslation=function(a){a=goog.style.getComputedTransform(a);return a?(a=a.match(goog.style.MATRIX_TRANSLATION_REGEX_))?new goog.math.Coordinate(parseFloat(a[1]),parseFloat(a[2])):new goog.math.Coordinate(0,0):new goog.math.Coordinate(0,0)};goog.events.EventHandler=function(a){goog.Disposable.call(this);this.handler_=a;this.keys_={}};goog.inherits(goog.events.EventHandler,goog.Disposable);goog.events.EventHandler.typeArray_=[];goog.events.EventHandler.prototype.listen=function(a,b,c,d){return this.listen_(a,b,c,d)};goog.events.EventHandler.prototype.listenWithScope=function(a,b,c,d,e){return this.listen_(a,b,c,d,e)};
                +goog.events.EventHandler.prototype.listen_=function(a,b,c,d,e){goog.isArray(b)||(b&&(goog.events.EventHandler.typeArray_[0]=b.toString()),b=goog.events.EventHandler.typeArray_);for(var f=0;f<b.length;f++){var g=goog.events.listen(a,b[f],c||this.handleEvent,d||!1,e||this.handler_||this);if(!g)break;this.keys_[g.key]=g}return this};goog.events.EventHandler.prototype.listenOnce=function(a,b,c,d){return this.listenOnce_(a,b,c,d)};
                +goog.events.EventHandler.prototype.listenOnceWithScope=function(a,b,c,d,e){return this.listenOnce_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenOnce_=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.listenOnce_(a,b[f],c,d,e);else{a=goog.events.listenOnce(a,b,c||this.handleEvent,d,e||this.handler_||this);if(!a)return this;this.keys_[a.key]=a}return this};goog.events.EventHandler.prototype.listenWithWrapper=function(a,b,c,d){return this.listenWithWrapper_(a,b,c,d)};
                +goog.events.EventHandler.prototype.listenWithWrapperAndScope=function(a,b,c,d,e){return this.listenWithWrapper_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenWithWrapper_=function(a,b,c,d,e){b.listen(a,c,d,e||this.handler_||this,this);return this};goog.events.EventHandler.prototype.getListenerCount=function(){var a=0,b;for(b in this.keys_)Object.prototype.hasOwnProperty.call(this.keys_,b)&&a++;return a};
                +goog.events.EventHandler.prototype.unlisten=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.unlisten(a,b[f],c,d,e);else if(a=goog.events.getListener(a,b,c||this.handleEvent,d,e||this.handler_||this))goog.events.unlistenByKey(a),delete this.keys_[a.key];return this};goog.events.EventHandler.prototype.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e||this.handler_||this,this);return this};
                +goog.events.EventHandler.prototype.removeAll=function(){goog.object.forEach(this.keys_,function(a,b){this.keys_.hasOwnProperty(b)&&goog.events.unlistenByKey(a)},this);this.keys_={}};goog.events.EventHandler.prototype.disposeInternal=function(){goog.events.EventHandler.superClass_.disposeInternal.call(this);this.removeAll()};goog.events.EventHandler.prototype.handleEvent=function(a){throw Error("EventHandler.handleEvent not implemented");};goog.ui={};goog.ui.IdGenerator=function(){};goog.addSingletonGetter(goog.ui.IdGenerator);goog.ui.IdGenerator.prototype.nextId_=0;goog.ui.IdGenerator.prototype.getNextUniqueId=function(){return":"+(this.nextId_++).toString(36)};goog.ui.Component=function(a){goog.events.EventTarget.call(this);this.dom_=a||goog.dom.getDomHelper();this.rightToLeft_=goog.ui.Component.defaultRightToLeft_;this.id_=null;this.inDocument_=!1;this.element_=null;this.googUiComponentHandler_=void 0;this.childIndex_=this.children_=this.parent_=this.model_=null;this.wasDecorated_=!1};goog.inherits(goog.ui.Component,goog.events.EventTarget);goog.ui.Component.ALLOW_DETACHED_DECORATION=!1;goog.ui.Component.prototype.idGenerator_=goog.ui.IdGenerator.getInstance();
                +goog.ui.Component.DEFAULT_BIDI_DIR=0;goog.ui.Component.defaultRightToLeft_=1==goog.ui.Component.DEFAULT_BIDI_DIR?!1:-1==goog.ui.Component.DEFAULT_BIDI_DIR?!0:null;
                +goog.ui.Component.EventType={BEFORE_SHOW:"beforeshow",SHOW:"show",HIDE:"hide",DISABLE:"disable",ENABLE:"enable",HIGHLIGHT:"highlight",UNHIGHLIGHT:"unhighlight",ACTIVATE:"activate",DEACTIVATE:"deactivate",SELECT:"select",UNSELECT:"unselect",CHECK:"check",UNCHECK:"uncheck",FOCUS:"focus",BLUR:"blur",OPEN:"open",CLOSE:"close",ENTER:"enter",LEAVE:"leave",ACTION:"action",CHANGE:"change"};
                +goog.ui.Component.Error={NOT_SUPPORTED:"Method not supported",DECORATE_INVALID:"Invalid element to decorate",ALREADY_RENDERED:"Component already rendered",PARENT_UNABLE_TO_BE_SET:"Unable to set parent component",CHILD_INDEX_OUT_OF_BOUNDS:"Child component index out of bounds",NOT_OUR_CHILD:"Child is not in parent component",NOT_IN_DOCUMENT:"Operation not supported while component is not in document",STATE_INVALID:"Invalid component state"};
                +goog.ui.Component.State={ALL:255,DISABLED:1,HOVER:2,ACTIVE:4,SELECTED:8,CHECKED:16,FOCUSED:32,OPENED:64};
                +goog.ui.Component.getStateTransitionEvent=function(a,b){switch(a){case goog.ui.Component.State.DISABLED:return b?goog.ui.Component.EventType.DISABLE:goog.ui.Component.EventType.ENABLE;case goog.ui.Component.State.HOVER:return b?goog.ui.Component.EventType.HIGHLIGHT:goog.ui.Component.EventType.UNHIGHLIGHT;case goog.ui.Component.State.ACTIVE:return b?goog.ui.Component.EventType.ACTIVATE:goog.ui.Component.EventType.DEACTIVATE;case goog.ui.Component.State.SELECTED:return b?goog.ui.Component.EventType.SELECT:
                +goog.ui.Component.EventType.UNSELECT;case goog.ui.Component.State.CHECKED:return b?goog.ui.Component.EventType.CHECK:goog.ui.Component.EventType.UNCHECK;case goog.ui.Component.State.FOCUSED:return b?goog.ui.Component.EventType.FOCUS:goog.ui.Component.EventType.BLUR;case goog.ui.Component.State.OPENED:return b?goog.ui.Component.EventType.OPEN:goog.ui.Component.EventType.CLOSE}throw Error(goog.ui.Component.Error.STATE_INVALID);};
                +goog.ui.Component.setDefaultRightToLeft=function(a){goog.ui.Component.defaultRightToLeft_=a};goog.ui.Component.prototype.getId=function(){return this.id_||(this.id_=this.idGenerator_.getNextUniqueId())};goog.ui.Component.prototype.setId=function(a){this.parent_&&this.parent_.childIndex_&&(goog.object.remove(this.parent_.childIndex_,this.id_),goog.object.add(this.parent_.childIndex_,a,this));this.id_=a};goog.ui.Component.prototype.getElement=function(){return this.element_};
                +goog.ui.Component.prototype.getElementStrict=function(){var a=this.element_;goog.asserts.assert(a,"Can not call getElementStrict before rendering/decorating.");return a};goog.ui.Component.prototype.setElementInternal=function(a){this.element_=a};goog.ui.Component.prototype.getElementsByClass=function(a){return this.element_?this.dom_.getElementsByClass(a,this.element_):[]};goog.ui.Component.prototype.getElementByClass=function(a){return this.element_?this.dom_.getElementByClass(a,this.element_):null};
                +goog.ui.Component.prototype.getRequiredElementByClass=function(a){var b=this.getElementByClass(a);goog.asserts.assert(b,"Expected element in component with class: %s",a);return b};goog.ui.Component.prototype.getHandler=function(){this.googUiComponentHandler_||(this.googUiComponentHandler_=new goog.events.EventHandler(this));return this.googUiComponentHandler_};
                +goog.ui.Component.prototype.setParent=function(a){if(this==a)throw Error(goog.ui.Component.Error.PARENT_UNABLE_TO_BE_SET);if(a&&this.parent_&&this.id_&&this.parent_.getChild(this.id_)&&this.parent_!=a)throw Error(goog.ui.Component.Error.PARENT_UNABLE_TO_BE_SET);this.parent_=a;goog.ui.Component.superClass_.setParentEventTarget.call(this,a)};goog.ui.Component.prototype.getParent=function(){return this.parent_};
                +goog.ui.Component.prototype.setParentEventTarget=function(a){if(this.parent_&&this.parent_!=a)throw Error(goog.ui.Component.Error.NOT_SUPPORTED);goog.ui.Component.superClass_.setParentEventTarget.call(this,a)};goog.ui.Component.prototype.getDomHelper=function(){return this.dom_};goog.ui.Component.prototype.isInDocument=function(){return this.inDocument_};goog.ui.Component.prototype.createDom=function(){this.element_=this.dom_.createElement("DIV")};goog.ui.Component.prototype.render=function(a){this.render_(a)};
                +goog.ui.Component.prototype.renderBefore=function(a){this.render_(a.parentNode,a)};goog.ui.Component.prototype.render_=function(a,b){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.element_||this.createDom();a?a.insertBefore(this.element_,b||null):this.dom_.getDocument().body.appendChild(this.element_);this.parent_&&!this.parent_.isInDocument()||this.enterDocument()};
                +goog.ui.Component.prototype.decorate=function(a){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);if(a&&this.canDecorate(a)){this.wasDecorated_=!0;var b=goog.dom.getOwnerDocument(a);this.dom_&&this.dom_.getDocument()==b||(this.dom_=goog.dom.getDomHelper(a));this.decorateInternal(a);goog.ui.Component.ALLOW_DETACHED_DECORATION&&!goog.dom.contains(b,a)||this.enterDocument()}else throw Error(goog.ui.Component.Error.DECORATE_INVALID);};goog.ui.Component.prototype.canDecorate=function(a){return!0};
                +goog.ui.Component.prototype.wasDecorated=function(){return this.wasDecorated_};goog.ui.Component.prototype.decorateInternal=function(a){this.element_=a};goog.ui.Component.prototype.enterDocument=function(){this.inDocument_=!0;this.forEachChild(function(a){!a.isInDocument()&&a.getElement()&&a.enterDocument()})};
                +goog.ui.Component.prototype.exitDocument=function(){this.forEachChild(function(a){a.isInDocument()&&a.exitDocument()});this.googUiComponentHandler_&&this.googUiComponentHandler_.removeAll();this.inDocument_=!1};
                +goog.ui.Component.prototype.disposeInternal=function(){this.inDocument_&&this.exitDocument();this.googUiComponentHandler_&&(this.googUiComponentHandler_.dispose(),delete this.googUiComponentHandler_);this.forEachChild(function(a){a.dispose()});!this.wasDecorated_&&this.element_&&goog.dom.removeNode(this.element_);this.parent_=this.model_=this.element_=this.childIndex_=this.children_=null;goog.ui.Component.superClass_.disposeInternal.call(this)};
                +goog.ui.Component.prototype.makeId=function(a){return this.getId()+"."+a};goog.ui.Component.prototype.makeIds=function(a){var b={},c;for(c in a)b[c]=this.makeId(a[c]);return b};goog.ui.Component.prototype.getModel=function(){return this.model_};goog.ui.Component.prototype.setModel=function(a){this.model_=a};goog.ui.Component.prototype.getFragmentFromId=function(a){return a.substring(this.getId().length+1)};
                +goog.ui.Component.prototype.getElementByFragment=function(a){if(!this.inDocument_)throw Error(goog.ui.Component.Error.NOT_IN_DOCUMENT);return this.dom_.getElement(this.makeId(a))};goog.ui.Component.prototype.addChild=function(a,b){this.addChildAt(a,this.getChildCount(),b)};
                +goog.ui.Component.prototype.addChildAt=function(a,b,c){goog.asserts.assert(!!a,"Provided element must not be null.");if(a.inDocument_&&(c||!this.inDocument_))throw Error(goog.ui.Component.Error.ALREADY_RENDERED);if(0>b||b>this.getChildCount())throw Error(goog.ui.Component.Error.CHILD_INDEX_OUT_OF_BOUNDS);this.childIndex_&&this.children_||(this.childIndex_={},this.children_=[]);a.getParent()==this?(goog.object.set(this.childIndex_,a.getId(),a),goog.array.remove(this.children_,a)):goog.object.add(this.childIndex_,
                +a.getId(),a);a.setParent(this);goog.array.insertAt(this.children_,a,b);a.inDocument_&&this.inDocument_&&a.getParent()==this?(c=this.getContentElement(),b=c.childNodes[b]||null,b!=a.getElement()&&c.insertBefore(a.getElement(),b)):c?(this.element_||this.createDom(),b=this.getChildAt(b+1),a.render_(this.getContentElement(),b?b.element_:null)):this.inDocument_&&!a.inDocument_&&a.element_&&a.element_.parentNode&&a.element_.parentNode.nodeType==goog.dom.NodeType.ELEMENT&&a.enterDocument()};
                +goog.ui.Component.prototype.getContentElement=function(){return this.element_};goog.ui.Component.prototype.isRightToLeft=function(){null==this.rightToLeft_&&(this.rightToLeft_=goog.style.isRightToLeft(this.inDocument_?this.element_:this.dom_.getDocument().body));return this.rightToLeft_};goog.ui.Component.prototype.setRightToLeft=function(a){if(this.inDocument_)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.rightToLeft_=a};
                +goog.ui.Component.prototype.hasChildren=function(){return!!this.children_&&0!=this.children_.length};goog.ui.Component.prototype.getChildCount=function(){return this.children_?this.children_.length:0};goog.ui.Component.prototype.getChildIds=function(){var a=[];this.forEachChild(function(b){a.push(b.getId())});return a};goog.ui.Component.prototype.getChild=function(a){return this.childIndex_&&a?goog.object.get(this.childIndex_,a)||null:null};
                +goog.ui.Component.prototype.getChildAt=function(a){return this.children_?this.children_[a]||null:null};goog.ui.Component.prototype.forEachChild=function(a,b){this.children_&&goog.array.forEach(this.children_,a,b)};goog.ui.Component.prototype.indexOfChild=function(a){return this.children_&&a?goog.array.indexOf(this.children_,a):-1};
                +goog.ui.Component.prototype.removeChild=function(a,b){if(a){var c=goog.isString(a)?a:a.getId();a=this.getChild(c);c&&a&&(goog.object.remove(this.childIndex_,c),goog.array.remove(this.children_,a),b&&(a.exitDocument(),a.element_&&goog.dom.removeNode(a.element_)),a.setParent(null))}if(!a)throw Error(goog.ui.Component.Error.NOT_OUR_CHILD);return a};goog.ui.Component.prototype.removeChildAt=function(a,b){return this.removeChild(this.getChildAt(a),b)};
                +goog.ui.Component.prototype.removeChildren=function(a){for(var b=[];this.hasChildren();)b.push(this.removeChildAt(0,a));return b};goog.a11y={};goog.a11y.aria={};
                +goog.a11y.aria.Role={ALERT:"alert",ALERTDIALOG:"alertdialog",APPLICATION:"application",ARTICLE:"article",BANNER:"banner",BUTTON:"button",CHECKBOX:"checkbox",COLUMNHEADER:"columnheader",COMBOBOX:"combobox",COMPLEMENTARY:"complementary",CONTENTINFO:"contentinfo",DEFINITION:"definition",DIALOG:"dialog",DIRECTORY:"directory",DOCUMENT:"document",FORM:"form",GRID:"grid",GRIDCELL:"gridcell",GROUP:"group",HEADING:"heading",IMG:"img",LINK:"link",LIST:"list",LISTBOX:"listbox",LISTITEM:"listitem",LOG:"log",
                +MAIN:"main",MARQUEE:"marquee",MATH:"math",MENU:"menu",MENUBAR:"menubar",MENU_ITEM:"menuitem",MENU_ITEM_CHECKBOX:"menuitemcheckbox",MENU_ITEM_RADIO:"menuitemradio",NAVIGATION:"navigation",NOTE:"note",OPTION:"option",PRESENTATION:"presentation",PROGRESSBAR:"progressbar",RADIO:"radio",RADIOGROUP:"radiogroup",REGION:"region",ROW:"row",ROWGROUP:"rowgroup",ROWHEADER:"rowheader",SCROLLBAR:"scrollbar",SEARCH:"search",SEPARATOR:"separator",SLIDER:"slider",SPINBUTTON:"spinbutton",STATUS:"status",TAB:"tab",
                +TAB_LIST:"tablist",TAB_PANEL:"tabpanel",TEXTBOX:"textbox",TEXTINFO:"textinfo",TIMER:"timer",TOOLBAR:"toolbar",TOOLTIP:"tooltip",TREE:"tree",TREEGRID:"treegrid",TREEITEM:"treeitem"};goog.a11y.aria.State={ACTIVEDESCENDANT:"activedescendant",ATOMIC:"atomic",AUTOCOMPLETE:"autocomplete",BUSY:"busy",CHECKED:"checked",CONTROLS:"controls",DESCRIBEDBY:"describedby",DISABLED:"disabled",DROPEFFECT:"dropeffect",EXPANDED:"expanded",FLOWTO:"flowto",GRABBED:"grabbed",HASPOPUP:"haspopup",HIDDEN:"hidden",INVALID:"invalid",LABEL:"label",LABELLEDBY:"labelledby",LEVEL:"level",LIVE:"live",MULTILINE:"multiline",MULTISELECTABLE:"multiselectable",ORIENTATION:"orientation",OWNS:"owns",POSINSET:"posinset",
                +PRESSED:"pressed",READONLY:"readonly",RELEVANT:"relevant",REQUIRED:"required",SELECTED:"selected",SETSIZE:"setsize",SORT:"sort",VALUEMAX:"valuemax",VALUEMIN:"valuemin",VALUENOW:"valuenow",VALUETEXT:"valuetext"};goog.a11y.aria.AutoCompleteValues={INLINE:"inline",LIST:"list",BOTH:"both",NONE:"none"};goog.a11y.aria.DropEffectValues={COPY:"copy",MOVE:"move",LINK:"link",EXECUTE:"execute",POPUP:"popup",NONE:"none"};goog.a11y.aria.LivePriority={OFF:"off",POLITE:"polite",ASSERTIVE:"assertive"};
                +goog.a11y.aria.OrientationValues={VERTICAL:"vertical",HORIZONTAL:"horizontal"};goog.a11y.aria.RelevantValues={ADDITIONS:"additions",REMOVALS:"removals",TEXT:"text",ALL:"all"};goog.a11y.aria.SortValues={ASCENDING:"ascending",DESCENDING:"descending",NONE:"none",OTHER:"other"};goog.a11y.aria.CheckedValues={TRUE:"true",FALSE:"false",MIXED:"mixed",UNDEFINED:"undefined"};goog.a11y.aria.ExpandedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};
                +goog.a11y.aria.GrabbedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};goog.a11y.aria.InvalidValues={FALSE:"false",TRUE:"true",GRAMMAR:"grammar",SPELLING:"spelling"};goog.a11y.aria.PressedValues={TRUE:"true",FALSE:"false",MIXED:"mixed",UNDEFINED:"undefined"};goog.a11y.aria.SelectedValues={TRUE:"true",FALSE:"false",UNDEFINED:"undefined"};goog.a11y.aria.datatables={};
                +goog.a11y.aria.datatables.getDefaultValuesMap=function(){goog.a11y.aria.DefaultStateValueMap_||(goog.a11y.aria.DefaultStateValueMap_=goog.object.create(goog.a11y.aria.State.ATOMIC,!1,goog.a11y.aria.State.AUTOCOMPLETE,"none",goog.a11y.aria.State.DROPEFFECT,"none",goog.a11y.aria.State.HASPOPUP,!1,goog.a11y.aria.State.LIVE,"off",goog.a11y.aria.State.MULTILINE,!1,goog.a11y.aria.State.MULTISELECTABLE,!1,goog.a11y.aria.State.ORIENTATION,"vertical",goog.a11y.aria.State.READONLY,!1,goog.a11y.aria.State.RELEVANT,
                +"additions text",goog.a11y.aria.State.REQUIRED,!1,goog.a11y.aria.State.SORT,"none",goog.a11y.aria.State.BUSY,!1,goog.a11y.aria.State.DISABLED,!1,goog.a11y.aria.State.HIDDEN,!1,goog.a11y.aria.State.INVALID,"false"));return goog.a11y.aria.DefaultStateValueMap_};goog.a11y.aria.ARIA_PREFIX_="aria-";goog.a11y.aria.ROLE_ATTRIBUTE_="role";goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_=goog.object.createSet("A AREA BUTTON HEAD INPUT LINK MENU META OPTGROUP OPTION PROGRESS STYLE SELECT SOURCE TEXTAREA TITLE TRACK".split(" "));
                +goog.a11y.aria.CONTAINER_ROLES_=[goog.a11y.aria.Role.COMBOBOX,goog.a11y.aria.Role.GRID,goog.a11y.aria.Role.GROUP,goog.a11y.aria.Role.LISTBOX,goog.a11y.aria.Role.MENU,goog.a11y.aria.Role.MENUBAR,goog.a11y.aria.Role.RADIOGROUP,goog.a11y.aria.Role.ROW,goog.a11y.aria.Role.ROWGROUP,goog.a11y.aria.Role.TAB_LIST,goog.a11y.aria.Role.TEXTBOX,goog.a11y.aria.Role.TOOLBAR,goog.a11y.aria.Role.TREE,goog.a11y.aria.Role.TREEGRID];
                +goog.a11y.aria.setRole=function(a,b){b?(goog.asserts.ENABLE_ASSERTS&&goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.Role,b),"No such ARIA role "+b),a.setAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_,b)):goog.a11y.aria.removeRole(a)};goog.a11y.aria.getRole=function(a){return a.getAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_)||null};goog.a11y.aria.removeRole=function(a){a.removeAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_)};
                +goog.a11y.aria.setState=function(a,b,c){goog.isArray(c)&&(c=c.join(" "));var d=goog.a11y.aria.getAriaAttributeName_(b);""===c||void 0==c?(c=goog.a11y.aria.datatables.getDefaultValuesMap(),b in c?a.setAttribute(d,c[b]):a.removeAttribute(d)):a.setAttribute(d,c)};goog.a11y.aria.toggleState=function(a,b){var c=goog.a11y.aria.getState(a,b);goog.string.isEmptyOrWhitespace(goog.string.makeSafe(c))||"true"==c||"false"==c?goog.a11y.aria.setState(a,b,"true"==c?"false":"true"):goog.a11y.aria.removeState(a,b)};
                +goog.a11y.aria.removeState=function(a,b){a.removeAttribute(goog.a11y.aria.getAriaAttributeName_(b))};goog.a11y.aria.getState=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return null==c||void 0==c?"":String(c)};goog.a11y.aria.getActiveDescendant=function(a){var b=goog.a11y.aria.getState(a,goog.a11y.aria.State.ACTIVEDESCENDANT);return goog.dom.getOwnerDocument(a).getElementById(b)};
                +goog.a11y.aria.setActiveDescendant=function(a,b){var c="";b&&(c=b.id,goog.asserts.assert(c,"The active element should have an id."));goog.a11y.aria.setState(a,goog.a11y.aria.State.ACTIVEDESCENDANT,c)};goog.a11y.aria.getLabel=function(a){return goog.a11y.aria.getState(a,goog.a11y.aria.State.LABEL)};goog.a11y.aria.setLabel=function(a,b){goog.a11y.aria.setState(a,goog.a11y.aria.State.LABEL,b)};
                +goog.a11y.aria.assertRoleIsSetInternalUtil=function(a,b){if(!goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_[a.tagName]){var c=goog.a11y.aria.getRole(a);goog.asserts.assert(null!=c,"The element ARIA role cannot be null.");goog.asserts.assert(goog.array.contains(b,c),'Non existing or incorrect role set for element.The role set is "'+c+'". The role should be any of "'+b+'". Check the ARIA specification for more details http://www.w3.org/TR/wai-aria/roles.')}};
                +goog.a11y.aria.getStateBoolean=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert(goog.isBoolean(c)||null==c||"true"==c||"false"==c);return null==c?c:goog.isBoolean(c)?c:"true"==c};goog.a11y.aria.getStateNumber=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==c||!isNaN(Number(c)))&&!goog.isBoolean(c));return null==c?null:Number(c)};
                +goog.a11y.aria.getStateString=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==c||goog.isString(c))&&(""==c||isNaN(Number(c)))&&"true"!=c&&"false"!=c);return null==c||""==c?null:c};goog.a11y.aria.getStringArrayStateInternalUtil=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return goog.a11y.aria.splitStringOnWhitespace_(c)};goog.a11y.aria.hasState=function(a,b){return a.hasAttribute(goog.a11y.aria.getAriaAttributeName_(b))};
                +goog.a11y.aria.isContainerRole=function(a){a=goog.a11y.aria.getRole(a);return goog.array.contains(goog.a11y.aria.CONTAINER_ROLES_,a)};goog.a11y.aria.splitStringOnWhitespace_=function(a){return a?a.split(/\s+/):[]};goog.a11y.aria.getAriaAttributeName_=function(a){goog.asserts.ENABLE_ASSERTS&&(goog.asserts.assert(a,"ARIA attribute cannot be empty."),goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.State,a),"No such ARIA attribute "+a));return goog.a11y.aria.ARIA_PREFIX_+a};goog.events.KeyCodes={WIN_KEY_FF_LINUX:0,MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PLUS_SIGN:43,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,FF_SEMICOLON:59,FF_EQUALS:61,FF_DASH:173,QUESTION_MARK:63,AT_SIGN:64,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,
                +Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SCROLL_LOCK:145,FIRST_MEDIA_KEY:166,LAST_MEDIA_KEY:183,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,
                +SLASH:191,APOSTROPHE:192,TILDE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,MAC_WK_CMD_LEFT:91,MAC_WK_CMD_RIGHT:93,WIN_IME:229,VK_NONAME:252,PHANTOM:255};
                +goog.events.KeyCodes.isTextModifyingKeyEvent=function(a){if(a.altKey&&!a.ctrlKey||a.metaKey||a.keyCode>=goog.events.KeyCodes.F1&&a.keyCode<=goog.events.KeyCodes.F12)return!1;switch(a.keyCode){case goog.events.KeyCodes.ALT:case goog.events.KeyCodes.CAPS_LOCK:case goog.events.KeyCodes.CONTEXT_MENU:case goog.events.KeyCodes.CTRL:case goog.events.KeyCodes.DOWN:case goog.events.KeyCodes.END:case goog.events.KeyCodes.ESC:case goog.events.KeyCodes.HOME:case goog.events.KeyCodes.INSERT:case goog.events.KeyCodes.LEFT:case goog.events.KeyCodes.MAC_FF_META:case goog.events.KeyCodes.META:case goog.events.KeyCodes.NUMLOCK:case goog.events.KeyCodes.NUM_CENTER:case goog.events.KeyCodes.PAGE_DOWN:case goog.events.KeyCodes.PAGE_UP:case goog.events.KeyCodes.PAUSE:case goog.events.KeyCodes.PHANTOM:case goog.events.KeyCodes.PRINT_SCREEN:case goog.events.KeyCodes.RIGHT:case goog.events.KeyCodes.SCROLL_LOCK:case goog.events.KeyCodes.SHIFT:case goog.events.KeyCodes.UP:case goog.events.KeyCodes.VK_NONAME:case goog.events.KeyCodes.WIN_KEY:case goog.events.KeyCodes.WIN_KEY_RIGHT:return!1;case goog.events.KeyCodes.WIN_KEY_FF_LINUX:return!goog.userAgent.GECKO;
                +default:return a.keyCode<goog.events.KeyCodes.FIRST_MEDIA_KEY||a.keyCode>goog.events.KeyCodes.LAST_MEDIA_KEY}};
                +goog.events.KeyCodes.firesKeyPressEvent=function(a,b,c,d,e,f){if(!(goog.userAgent.IE||goog.userAgent.EDGE||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("525")))return!0;if(goog.userAgent.MAC&&e)return goog.events.KeyCodes.isCharacterKey(a);if(e&&!d)return!1;goog.isNumber(b)&&(b=goog.events.KeyCodes.normalizeKeyCode(b));e=b==goog.events.KeyCodes.CTRL||b==goog.events.KeyCodes.ALT||goog.userAgent.MAC&&b==goog.events.KeyCodes.META;f=b==goog.events.KeyCodes.SHIFT&&(d||f);if((!c||goog.userAgent.MAC)&&
                +e||goog.userAgent.MAC&&f)return!1;if((goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&d&&c)switch(a){case goog.events.KeyCodes.BACKSLASH:case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:case goog.events.KeyCodes.TILDE:case goog.events.KeyCodes.SEMICOLON:case goog.events.KeyCodes.DASH:case goog.events.KeyCodes.EQUALS:case goog.events.KeyCodes.COMMA:case goog.events.KeyCodes.PERIOD:case goog.events.KeyCodes.SLASH:case goog.events.KeyCodes.APOSTROPHE:case goog.events.KeyCodes.SINGLE_QUOTE:return!1}if(goog.userAgent.IE&&
                +d&&b==a)return!1;switch(a){case goog.events.KeyCodes.ENTER:return!0;case goog.events.KeyCodes.ESC:return!(goog.userAgent.WEBKIT||goog.userAgent.EDGE)}return goog.events.KeyCodes.isCharacterKey(a)};
                +goog.events.KeyCodes.isCharacterKey=function(a){if(a>=goog.events.KeyCodes.ZERO&&a<=goog.events.KeyCodes.NINE||a>=goog.events.KeyCodes.NUM_ZERO&&a<=goog.events.KeyCodes.NUM_MULTIPLY||a>=goog.events.KeyCodes.A&&a<=goog.events.KeyCodes.Z||(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&0==a)return!0;switch(a){case goog.events.KeyCodes.SPACE:case goog.events.KeyCodes.PLUS_SIGN:case goog.events.KeyCodes.QUESTION_MARK:case goog.events.KeyCodes.AT_SIGN:case goog.events.KeyCodes.NUM_PLUS:case goog.events.KeyCodes.NUM_MINUS:case goog.events.KeyCodes.NUM_PERIOD:case goog.events.KeyCodes.NUM_DIVISION:case goog.events.KeyCodes.SEMICOLON:case goog.events.KeyCodes.FF_SEMICOLON:case goog.events.KeyCodes.DASH:case goog.events.KeyCodes.EQUALS:case goog.events.KeyCodes.FF_EQUALS:case goog.events.KeyCodes.COMMA:case goog.events.KeyCodes.PERIOD:case goog.events.KeyCodes.SLASH:case goog.events.KeyCodes.APOSTROPHE:case goog.events.KeyCodes.SINGLE_QUOTE:case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:case goog.events.KeyCodes.BACKSLASH:case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:return!0;default:return!1}};
                +goog.events.KeyCodes.normalizeKeyCode=function(a){return goog.userAgent.GECKO?goog.events.KeyCodes.normalizeGeckoKeyCode(a):goog.userAgent.MAC&&goog.userAgent.WEBKIT?goog.events.KeyCodes.normalizeMacWebKitKeyCode(a):a};
                +goog.events.KeyCodes.normalizeGeckoKeyCode=function(a){switch(a){case goog.events.KeyCodes.FF_EQUALS:return goog.events.KeyCodes.EQUALS;case goog.events.KeyCodes.FF_SEMICOLON:return goog.events.KeyCodes.SEMICOLON;case goog.events.KeyCodes.FF_DASH:return goog.events.KeyCodes.DASH;case goog.events.KeyCodes.MAC_FF_META:return goog.events.KeyCodes.META;case goog.events.KeyCodes.WIN_KEY_FF_LINUX:return goog.events.KeyCodes.WIN_KEY;default:return a}};
                +goog.events.KeyCodes.normalizeMacWebKitKeyCode=function(a){switch(a){case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:return goog.events.KeyCodes.META;default:return a}};goog.events.KeyHandler=function(a,b){goog.events.EventTarget.call(this);a&&this.attach(a,b)};goog.inherits(goog.events.KeyHandler,goog.events.EventTarget);goog.events.KeyHandler.prototype.element_=null;goog.events.KeyHandler.prototype.keyPressKey_=null;goog.events.KeyHandler.prototype.keyDownKey_=null;goog.events.KeyHandler.prototype.keyUpKey_=null;goog.events.KeyHandler.prototype.lastKey_=-1;goog.events.KeyHandler.prototype.keyCode_=-1;goog.events.KeyHandler.prototype.altKey_=!1;
                +goog.events.KeyHandler.EventType={KEY:"key"};
                +goog.events.KeyHandler.safariKey_={3:goog.events.KeyCodes.ENTER,12:goog.events.KeyCodes.NUMLOCK,63232:goog.events.KeyCodes.UP,63233:goog.events.KeyCodes.DOWN,63234:goog.events.KeyCodes.LEFT,63235:goog.events.KeyCodes.RIGHT,63236:goog.events.KeyCodes.F1,63237:goog.events.KeyCodes.F2,63238:goog.events.KeyCodes.F3,63239:goog.events.KeyCodes.F4,63240:goog.events.KeyCodes.F5,63241:goog.events.KeyCodes.F6,63242:goog.events.KeyCodes.F7,63243:goog.events.KeyCodes.F8,63244:goog.events.KeyCodes.F9,63245:goog.events.KeyCodes.F10,
                +63246:goog.events.KeyCodes.F11,63247:goog.events.KeyCodes.F12,63248:goog.events.KeyCodes.PRINT_SCREEN,63272:goog.events.KeyCodes.DELETE,63273:goog.events.KeyCodes.HOME,63275:goog.events.KeyCodes.END,63276:goog.events.KeyCodes.PAGE_UP,63277:goog.events.KeyCodes.PAGE_DOWN,63289:goog.events.KeyCodes.NUMLOCK,63302:goog.events.KeyCodes.INSERT};
                +goog.events.KeyHandler.keyIdentifier_={Up:goog.events.KeyCodes.UP,Down:goog.events.KeyCodes.DOWN,Left:goog.events.KeyCodes.LEFT,Right:goog.events.KeyCodes.RIGHT,Enter:goog.events.KeyCodes.ENTER,F1:goog.events.KeyCodes.F1,F2:goog.events.KeyCodes.F2,F3:goog.events.KeyCodes.F3,F4:goog.events.KeyCodes.F4,F5:goog.events.KeyCodes.F5,F6:goog.events.KeyCodes.F6,F7:goog.events.KeyCodes.F7,F8:goog.events.KeyCodes.F8,F9:goog.events.KeyCodes.F9,F10:goog.events.KeyCodes.F10,F11:goog.events.KeyCodes.F11,F12:goog.events.KeyCodes.F12,
                +"U+007F":goog.events.KeyCodes.DELETE,Home:goog.events.KeyCodes.HOME,End:goog.events.KeyCodes.END,PageUp:goog.events.KeyCodes.PAGE_UP,PageDown:goog.events.KeyCodes.PAGE_DOWN,Insert:goog.events.KeyCodes.INSERT};goog.events.KeyHandler.USES_KEYDOWN_=goog.userAgent.IE||goog.userAgent.EDGE||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("525");goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_=goog.userAgent.MAC&&goog.userAgent.GECKO;
                +goog.events.KeyHandler.prototype.handleKeyDown_=function(a){(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&(this.lastKey_==goog.events.KeyCodes.CTRL&&!a.ctrlKey||this.lastKey_==goog.events.KeyCodes.ALT&&!a.altKey||goog.userAgent.MAC&&this.lastKey_==goog.events.KeyCodes.META&&!a.metaKey)&&this.resetState();-1==this.lastKey_&&(a.ctrlKey&&a.keyCode!=goog.events.KeyCodes.CTRL?this.lastKey_=goog.events.KeyCodes.CTRL:a.altKey&&a.keyCode!=goog.events.KeyCodes.ALT?this.lastKey_=goog.events.KeyCodes.ALT:a.metaKey&&
                +a.keyCode!=goog.events.KeyCodes.META&&(this.lastKey_=goog.events.KeyCodes.META));goog.events.KeyHandler.USES_KEYDOWN_&&!goog.events.KeyCodes.firesKeyPressEvent(a.keyCode,this.lastKey_,a.shiftKey,a.ctrlKey,a.altKey,a.metaKey)?this.handleEvent(a):(this.keyCode_=goog.events.KeyCodes.normalizeKeyCode(a.keyCode),goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_&&(this.altKey_=a.altKey))};goog.events.KeyHandler.prototype.resetState=function(){this.keyCode_=this.lastKey_=-1};
                +goog.events.KeyHandler.prototype.handleKeyup_=function(a){this.resetState();this.altKey_=a.altKey};
                +goog.events.KeyHandler.prototype.handleEvent=function(a){var b=a.getBrowserEvent(),c=b.altKey;if(goog.userAgent.IE&&a.type==goog.events.EventType.KEYPRESS){var d=this.keyCode_;var e=d!=goog.events.KeyCodes.ENTER&&d!=goog.events.KeyCodes.ESC?b.keyCode:0}else(goog.userAgent.WEBKIT||goog.userAgent.EDGE)&&a.type==goog.events.EventType.KEYPRESS?(d=this.keyCode_,e=0<=b.charCode&&63232>b.charCode&&goog.events.KeyCodes.isCharacterKey(d)?b.charCode:0):goog.userAgent.OPERA&&!goog.userAgent.WEBKIT?(d=this.keyCode_,
                +e=goog.events.KeyCodes.isCharacterKey(d)?b.keyCode:0):(d=b.keyCode||this.keyCode_,e=b.charCode||0,goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_&&(c=this.altKey_),goog.userAgent.MAC&&e==goog.events.KeyCodes.QUESTION_MARK&&d==goog.events.KeyCodes.WIN_KEY&&(d=goog.events.KeyCodes.SLASH));var f=d=goog.events.KeyCodes.normalizeKeyCode(d);d?63232<=d&&d in goog.events.KeyHandler.safariKey_?f=goog.events.KeyHandler.safariKey_[d]:25==d&&a.shiftKey&&(f=9):b.keyIdentifier&&b.keyIdentifier in goog.events.KeyHandler.keyIdentifier_&&
                +(f=goog.events.KeyHandler.keyIdentifier_[b.keyIdentifier]);a=f==this.lastKey_;this.lastKey_=f;b=new goog.events.KeyEvent(f,e,a,b);b.altKey=c;this.dispatchEvent(b)};goog.events.KeyHandler.prototype.getElement=function(){return this.element_};
                +goog.events.KeyHandler.prototype.attach=function(a,b){this.keyUpKey_&&this.detach();this.element_=a;this.keyPressKey_=goog.events.listen(this.element_,goog.events.EventType.KEYPRESS,this,b);this.keyDownKey_=goog.events.listen(this.element_,goog.events.EventType.KEYDOWN,this.handleKeyDown_,b,this);this.keyUpKey_=goog.events.listen(this.element_,goog.events.EventType.KEYUP,this.handleKeyup_,b,this)};
                +goog.events.KeyHandler.prototype.detach=function(){this.keyPressKey_&&(goog.events.unlistenByKey(this.keyPressKey_),goog.events.unlistenByKey(this.keyDownKey_),goog.events.unlistenByKey(this.keyUpKey_),this.keyUpKey_=this.keyDownKey_=this.keyPressKey_=null);this.element_=null;this.keyCode_=this.lastKey_=-1};goog.events.KeyHandler.prototype.disposeInternal=function(){goog.events.KeyHandler.superClass_.disposeInternal.call(this);this.detach()};
                +goog.events.KeyEvent=function(a,b,c,d){goog.events.BrowserEvent.call(this,d);this.type=goog.events.KeyHandler.EventType.KEY;this.keyCode=a;this.charCode=b;this.repeat=c};goog.inherits(goog.events.KeyEvent,goog.events.BrowserEvent);goog.dom.classlist={};goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST=!1;goog.dom.classlist.get=function(a){if(goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList)return a.classList;a=a.className;return goog.isString(a)&&a.match(/\S+/g)||[]};goog.dom.classlist.set=function(a,b){a.className=b};goog.dom.classlist.contains=function(a,b){return goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.contains(b):goog.array.contains(goog.dom.classlist.get(a),b)};
                +goog.dom.classlist.add=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.add(b):goog.dom.classlist.contains(a,b)||(a.className+=0<a.className.length?" "+b:b)};
                +goog.dom.classlist.addAll=function(a,b){if(goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList)goog.array.forEach(b,function(b){goog.dom.classlist.add(a,b)});else{var c={};goog.array.forEach(goog.dom.classlist.get(a),function(a){c[a]=!0});goog.array.forEach(b,function(a){c[a]=!0});a.className="";for(var d in c)a.className+=0<a.className.length?" "+d:d}};
                +goog.dom.classlist.remove=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?a.classList.remove(b):goog.dom.classlist.contains(a,b)&&(a.className=goog.array.filter(goog.dom.classlist.get(a),function(a){return a!=b}).join(" "))};
                +goog.dom.classlist.removeAll=function(a,b){goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST||a.classList?goog.array.forEach(b,function(b){goog.dom.classlist.remove(a,b)}):a.className=goog.array.filter(goog.dom.classlist.get(a),function(a){return!goog.array.contains(b,a)}).join(" ")};goog.dom.classlist.enable=function(a,b,c){c?goog.dom.classlist.add(a,b):goog.dom.classlist.remove(a,b)};goog.dom.classlist.enableAll=function(a,b,c){(c?goog.dom.classlist.addAll:goog.dom.classlist.removeAll)(a,b)};
                +goog.dom.classlist.swap=function(a,b,c){return goog.dom.classlist.contains(a,b)?(goog.dom.classlist.remove(a,b),goog.dom.classlist.add(a,c),!0):!1};goog.dom.classlist.toggle=function(a,b){var c=!goog.dom.classlist.contains(a,b);goog.dom.classlist.enable(a,b,c);return c};goog.dom.classlist.addRemove=function(a,b,c){goog.dom.classlist.remove(a,b);goog.dom.classlist.add(a,c)};goog.ui.registry={};goog.ui.registry.getDefaultRenderer=function(a){for(var b;a;){b=goog.getUid(a);if(b=goog.ui.registry.defaultRenderers_[b])break;a=a.superClass_?a.superClass_.constructor:null}return b?goog.isFunction(b.getInstance)?b.getInstance():new b:null};
                +goog.ui.registry.setDefaultRenderer=function(a,b){if(!goog.isFunction(a))throw Error("Invalid component class "+a);if(!goog.isFunction(b))throw Error("Invalid renderer class "+b);var c=goog.getUid(a);goog.ui.registry.defaultRenderers_[c]=b};goog.ui.registry.getDecoratorByClassName=function(a){return a in goog.ui.registry.decoratorFunctions_?goog.ui.registry.decoratorFunctions_[a]():null};
                +goog.ui.registry.setDecoratorByClassName=function(a,b){if(!a)throw Error("Invalid class name "+a);if(!goog.isFunction(b))throw Error("Invalid decorator function "+b);goog.ui.registry.decoratorFunctions_[a]=b};goog.ui.registry.getDecorator=function(a){goog.asserts.assert(a);for(var b=goog.dom.classlist.get(a),c=0,d=b.length;c<d;c++)if(a=goog.ui.registry.getDecoratorByClassName(b[c]))return a;return null};
                +goog.ui.registry.reset=function(){goog.ui.registry.defaultRenderers_={};goog.ui.registry.decoratorFunctions_={}};goog.ui.registry.defaultRenderers_={};goog.ui.registry.decoratorFunctions_={};goog.ui.ContainerRenderer=function(a){this.ariaRole_=a};goog.addSingletonGetter(goog.ui.ContainerRenderer);goog.ui.ContainerRenderer.getCustomRenderer=function(a,b){var c=new a;c.getCssClass=function(){return b};return c};goog.ui.ContainerRenderer.CSS_CLASS="goog-container";goog.ui.ContainerRenderer.prototype.getAriaRole=function(){return this.ariaRole_};goog.ui.ContainerRenderer.prototype.enableTabIndex=function(a,b){a&&(a.tabIndex=b?0:-1)};
                +goog.ui.ContainerRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "))};goog.ui.ContainerRenderer.prototype.getContentElement=function(a){return a};goog.ui.ContainerRenderer.prototype.canDecorate=function(a){return"DIV"==a.tagName};
                +goog.ui.ContainerRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);var c=this.getCssClass(),d=!1,e=goog.dom.classlist.get(b);e&&goog.array.forEach(e,function(b){b==c?d=!0:b&&this.setStateFromClassName(a,b,c)},this);d||goog.dom.classlist.add(b,c);this.decorateChildren(a,this.getContentElement(b));return b};
                +goog.ui.ContainerRenderer.prototype.setStateFromClassName=function(a,b,c){b==c+"-disabled"?a.setEnabled(!1):b==c+"-horizontal"?a.setOrientation(goog.ui.Container.Orientation.HORIZONTAL):b==c+"-vertical"&&a.setOrientation(goog.ui.Container.Orientation.VERTICAL)};
                +goog.ui.ContainerRenderer.prototype.decorateChildren=function(a,b,c){if(b){c=c||b.firstChild;for(var d;c&&c.parentNode==b;){d=c.nextSibling;if(c.nodeType==goog.dom.NodeType.ELEMENT){var e=this.getDecoratorForChild(c);e&&(e.setElementInternal(c),a.isEnabled()||e.setEnabled(!1),a.addChild(e),e.decorate(c))}else c.nodeValue&&""!=goog.string.trim(c.nodeValue)||b.removeChild(c);c=d}}};goog.ui.ContainerRenderer.prototype.getDecoratorForChild=function(a){return goog.ui.registry.getDecorator(a)};
                +goog.ui.ContainerRenderer.prototype.initializeDom=function(a){a=a.getElement();goog.asserts.assert(a,"The container DOM element cannot be null.");goog.style.setUnselectable(a,!0,goog.userAgent.GECKO);goog.userAgent.IE&&(a.hideFocus=!0);var b=this.getAriaRole();b&&goog.a11y.aria.setRole(a,b)};goog.ui.ContainerRenderer.prototype.getKeyEventTarget=function(a){return a.getElement()};goog.ui.ContainerRenderer.prototype.getCssClass=function(){return goog.ui.ContainerRenderer.CSS_CLASS};
                +goog.ui.ContainerRenderer.prototype.getClassNames=function(a){var b=this.getCssClass(),c=a.getOrientation()==goog.ui.Container.Orientation.HORIZONTAL,c=[b,c?b+"-horizontal":b+"-vertical"];a.isEnabled()||c.push(b+"-disabled");return c};goog.ui.ContainerRenderer.prototype.getDefaultOrientation=function(){return goog.ui.Container.Orientation.VERTICAL};goog.ui.ControlRenderer=function(){};goog.addSingletonGetter(goog.ui.ControlRenderer);goog.tagUnsealableClass(goog.ui.ControlRenderer);goog.ui.ControlRenderer.getCustomRenderer=function(a,b){var c=new a;c.getCssClass=function(){return b};return c};goog.ui.ControlRenderer.CSS_CLASS="goog-control";goog.ui.ControlRenderer.IE6_CLASS_COMBINATIONS=[];
                +goog.ui.ControlRenderer.TOGGLE_ARIA_STATE_MAP_=goog.object.create(goog.a11y.aria.Role.BUTTON,goog.a11y.aria.State.PRESSED,goog.a11y.aria.Role.CHECKBOX,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.MENU_ITEM,goog.a11y.aria.State.SELECTED,goog.a11y.aria.Role.MENU_ITEM_CHECKBOX,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.MENU_ITEM_RADIO,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.RADIO,goog.a11y.aria.State.CHECKED,goog.a11y.aria.Role.TAB,goog.a11y.aria.State.SELECTED,goog.a11y.aria.Role.TREEITEM,
                +goog.a11y.aria.State.SELECTED);goog.ui.ControlRenderer.prototype.getAriaRole=function(){};goog.ui.ControlRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "),a.getContent())};goog.ui.ControlRenderer.prototype.getContentElement=function(a){return a};
                +goog.ui.ControlRenderer.prototype.enableClassName=function(a,b,c){if(a=a.getElement?a.getElement():a){var d=[b];goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")&&(d=this.getAppliedCombinedClassNames_(goog.dom.classlist.get(a),b),d.push(b));goog.dom.classlist.enableAll(a,d,c)}};goog.ui.ControlRenderer.prototype.enableExtraClassName=function(a,b,c){this.enableClassName(a,b,c)};goog.ui.ControlRenderer.prototype.canDecorate=function(a){return!0};
                +goog.ui.ControlRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);var c=this.getContentElement(b);c&&c.firstChild?a.setContentInternal(c.firstChild.nextSibling?goog.array.clone(c.childNodes):c.firstChild):a.setContentInternal(null);var d=0,e=this.getCssClass(),f=this.getStructuralCssClass(),g=!1,h=!1,k=!1,l=goog.array.toArray(goog.dom.classlist.get(b));goog.array.forEach(l,function(a){g||a!=e?h||a!=f?d|=this.getStateFromClass(a):h=!0:(g=!0,f==e&&(h=!0));this.getStateFromClass(a)==goog.ui.Component.State.DISABLED&&
                +(goog.asserts.assertElement(c),goog.dom.isFocusableTabIndex(c)&&goog.dom.setFocusableTabIndex(c,!1))},this);a.setStateInternal(d);g||(l.push(e),f==e&&(h=!0));h||l.push(f);var m=a.getExtraClassNames();m&&l.push.apply(l,m);if(goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")){var n=this.getAppliedCombinedClassNames_(l);0<n.length&&(l.push.apply(l,n),k=!0)}g&&h&&!m&&!k||goog.dom.classlist.set(b,l.join(" "));return b};
                +goog.ui.ControlRenderer.prototype.initializeDom=function(a){a.isRightToLeft()&&this.setRightToLeft(a.getElement(),!0);a.isEnabled()&&this.setFocusable(a,a.isVisible())};goog.ui.ControlRenderer.prototype.setAriaRole=function(a,b){var c=b||this.getAriaRole();if(c){goog.asserts.assert(a,"The element passed as a first parameter cannot be null.");var d=goog.a11y.aria.getRole(a);c!=d&&goog.a11y.aria.setRole(a,c)}};
                +goog.ui.ControlRenderer.prototype.setAriaStates=function(a,b){goog.asserts.assert(a);goog.asserts.assert(b);var c=a.getAriaLabel();goog.isDefAndNotNull(c)&&this.setAriaLabel(b,c);a.isVisible()||goog.a11y.aria.setState(b,goog.a11y.aria.State.HIDDEN,!a.isVisible());a.isEnabled()||this.updateAriaState(b,goog.ui.Component.State.DISABLED,!a.isEnabled());a.isSupportedState(goog.ui.Component.State.SELECTED)&&this.updateAriaState(b,goog.ui.Component.State.SELECTED,a.isSelected());a.isSupportedState(goog.ui.Component.State.CHECKED)&&
                +this.updateAriaState(b,goog.ui.Component.State.CHECKED,a.isChecked());a.isSupportedState(goog.ui.Component.State.OPENED)&&this.updateAriaState(b,goog.ui.Component.State.OPENED,a.isOpen())};goog.ui.ControlRenderer.prototype.setAriaLabel=function(a,b){goog.a11y.aria.setLabel(a,b)};goog.ui.ControlRenderer.prototype.setAllowTextSelection=function(a,b){goog.style.setUnselectable(a,!b,!goog.userAgent.IE&&!goog.userAgent.OPERA)};
                +goog.ui.ControlRenderer.prototype.setRightToLeft=function(a,b){this.enableClassName(a,this.getStructuralCssClass()+"-rtl",b)};goog.ui.ControlRenderer.prototype.isFocusable=function(a){var b;return a.isSupportedState(goog.ui.Component.State.FOCUSED)&&(b=a.getKeyEventTarget())?goog.dom.isFocusableTabIndex(b):!1};
                +goog.ui.ControlRenderer.prototype.setFocusable=function(a,b){var c;if(a.isSupportedState(goog.ui.Component.State.FOCUSED)&&(c=a.getKeyEventTarget())){if(!b&&a.isFocused()){try{c.blur()}catch(d){}a.isFocused()&&a.handleBlur(null)}goog.dom.isFocusableTabIndex(c)!=b&&goog.dom.setFocusableTabIndex(c,b)}};goog.ui.ControlRenderer.prototype.setVisible=function(a,b){goog.style.setElementShown(a,b);a&&goog.a11y.aria.setState(a,goog.a11y.aria.State.HIDDEN,!b)};
                +goog.ui.ControlRenderer.prototype.setState=function(a,b,c){var d=a.getElement();if(d){var e=this.getClassForState(b);e&&this.enableClassName(a,e,c);this.updateAriaState(d,b,c)}};
                +goog.ui.ControlRenderer.prototype.updateAriaState=function(a,b,c){goog.ui.ControlRenderer.ariaAttributeMap_||(goog.ui.ControlRenderer.ariaAttributeMap_=goog.object.create(goog.ui.Component.State.DISABLED,goog.a11y.aria.State.DISABLED,goog.ui.Component.State.SELECTED,goog.a11y.aria.State.SELECTED,goog.ui.Component.State.CHECKED,goog.a11y.aria.State.CHECKED,goog.ui.Component.State.OPENED,goog.a11y.aria.State.EXPANDED));goog.asserts.assert(a,"The element passed as a first parameter cannot be null.");
                +(b=goog.ui.ControlRenderer.getAriaStateForAriaRole_(a,goog.ui.ControlRenderer.ariaAttributeMap_[b]))&&goog.a11y.aria.setState(a,b,c)};goog.ui.ControlRenderer.getAriaStateForAriaRole_=function(a,b){var c=goog.a11y.aria.getRole(a);if(!c)return b;c=goog.ui.ControlRenderer.TOGGLE_ARIA_STATE_MAP_[c]||b;return goog.ui.ControlRenderer.isAriaState_(b)?c:b};goog.ui.ControlRenderer.isAriaState_=function(a){return a==goog.a11y.aria.State.CHECKED||a==goog.a11y.aria.State.SELECTED};
                +goog.ui.ControlRenderer.prototype.setContent=function(a,b){var c=this.getContentElement(a);if(c&&(goog.dom.removeChildren(c),b))if(goog.isString(b))goog.dom.setTextContent(c,b);else{var d=function(a){if(a){var b=goog.dom.getOwnerDocument(c);c.appendChild(goog.isString(a)?b.createTextNode(a):a)}};goog.isArray(b)?goog.array.forEach(b,d):!goog.isArrayLike(b)||"nodeType"in b?d(b):goog.array.forEach(goog.array.clone(b),d)}};goog.ui.ControlRenderer.prototype.getKeyEventTarget=function(a){return a.getElement()};
                +goog.ui.ControlRenderer.prototype.getCssClass=function(){return goog.ui.ControlRenderer.CSS_CLASS};goog.ui.ControlRenderer.prototype.getIe6ClassCombinations=function(){return[]};goog.ui.ControlRenderer.prototype.getStructuralCssClass=function(){return this.getCssClass()};
                +goog.ui.ControlRenderer.prototype.getClassNames=function(a){var b=this.getCssClass(),c=[b],d=this.getStructuralCssClass();d!=b&&c.push(d);b=this.getClassNamesForState(a.getState());c.push.apply(c,b);(a=a.getExtraClassNames())&&c.push.apply(c,a);goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("7")&&c.push.apply(c,this.getAppliedCombinedClassNames_(c));return c};
                +goog.ui.ControlRenderer.prototype.getAppliedCombinedClassNames_=function(a,b){var c=[];b&&(a=goog.array.concat(a,[b]));goog.array.forEach(this.getIe6ClassCombinations(),function(d){!goog.array.every(d,goog.partial(goog.array.contains,a))||b&&!goog.array.contains(d,b)||c.push(d.join("_"))});return c};goog.ui.ControlRenderer.prototype.getClassNamesForState=function(a){for(var b=[];a;){var c=a&-a;b.push(this.getClassForState(c));a&=~c}return b};
                +goog.ui.ControlRenderer.prototype.getClassForState=function(a){this.classByState_||this.createClassByStateMap_();return this.classByState_[a]};goog.ui.ControlRenderer.prototype.getStateFromClass=function(a){this.stateByClass_||this.createStateByClassMap_();a=parseInt(this.stateByClass_[a],10);return isNaN(a)?0:a};
                +goog.ui.ControlRenderer.prototype.createClassByStateMap_=function(){var a=this.getStructuralCssClass(),b=!goog.string.contains(goog.string.normalizeWhitespace(a)," ");goog.asserts.assert(b,"ControlRenderer has an invalid css class: '"+a+"'");this.classByState_=goog.object.create(goog.ui.Component.State.DISABLED,a+"-disabled",goog.ui.Component.State.HOVER,a+"-hover",goog.ui.Component.State.ACTIVE,a+"-active",goog.ui.Component.State.SELECTED,a+"-selected",goog.ui.Component.State.CHECKED,a+"-checked",
                +goog.ui.Component.State.FOCUSED,a+"-focused",goog.ui.Component.State.OPENED,a+"-open")};goog.ui.ControlRenderer.prototype.createStateByClassMap_=function(){this.classByState_||this.createClassByStateMap_();this.stateByClass_=goog.object.transpose(this.classByState_)};goog.ui.Control=function(a,b,c){goog.ui.Component.call(this,c);this.renderer_=b||goog.ui.registry.getDefaultRenderer(this.constructor);this.setContentInternal(goog.isDef(a)?a:null);this.ariaLabel_=null};goog.inherits(goog.ui.Control,goog.ui.Component);goog.tagUnsealableClass(goog.ui.Control);goog.ui.Control.registerDecorator=goog.ui.registry.setDecoratorByClassName;goog.ui.Control.getDecorator=goog.ui.registry.getDecorator;goog.ui.Control.prototype.content_=null;goog.ui.Control.prototype.state_=0;
                +goog.ui.Control.prototype.supportedStates_=goog.ui.Component.State.DISABLED|goog.ui.Component.State.HOVER|goog.ui.Component.State.ACTIVE|goog.ui.Component.State.FOCUSED;goog.ui.Control.prototype.autoStates_=goog.ui.Component.State.ALL;goog.ui.Control.prototype.statesWithTransitionEvents_=0;goog.ui.Control.prototype.visible_=!0;goog.ui.Control.prototype.extraClassNames_=null;goog.ui.Control.prototype.handleMouseEvents_=!0;goog.ui.Control.prototype.allowTextSelection_=!1;
                +goog.ui.Control.prototype.preferredAriaRole_=null;goog.ui.Control.prototype.isHandleMouseEvents=function(){return this.handleMouseEvents_};goog.ui.Control.prototype.setHandleMouseEvents=function(a){this.isInDocument()&&a!=this.handleMouseEvents_&&this.enableMouseEventHandling_(a);this.handleMouseEvents_=a};goog.ui.Control.prototype.getKeyEventTarget=function(){return this.renderer_.getKeyEventTarget(this)};
                +goog.ui.Control.prototype.getKeyHandler=function(){return this.keyHandler_||(this.keyHandler_=new goog.events.KeyHandler)};goog.ui.Control.prototype.getRenderer=function(){return this.renderer_};goog.ui.Control.prototype.setRenderer=function(a){if(this.isInDocument())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.getElement()&&this.setElementInternal(null);this.renderer_=a};goog.ui.Control.prototype.getExtraClassNames=function(){return this.extraClassNames_};
                +goog.ui.Control.prototype.addClassName=function(a){a&&(this.extraClassNames_?goog.array.contains(this.extraClassNames_,a)||this.extraClassNames_.push(a):this.extraClassNames_=[a],this.renderer_.enableExtraClassName(this,a,!0))};goog.ui.Control.prototype.removeClassName=function(a){a&&this.extraClassNames_&&goog.array.remove(this.extraClassNames_,a)&&(0==this.extraClassNames_.length&&(this.extraClassNames_=null),this.renderer_.enableExtraClassName(this,a,!1))};
                +goog.ui.Control.prototype.enableClassName=function(a,b){b?this.addClassName(a):this.removeClassName(a)};goog.ui.Control.prototype.createDom=function(){var a=this.renderer_.createDom(this);this.setElementInternal(a);this.renderer_.setAriaRole(a,this.getPreferredAriaRole());this.isAllowTextSelection()||this.renderer_.setAllowTextSelection(a,!1);this.isVisible()||this.renderer_.setVisible(a,!1)};goog.ui.Control.prototype.getPreferredAriaRole=function(){return this.preferredAriaRole_};
                +goog.ui.Control.prototype.setPreferredAriaRole=function(a){this.preferredAriaRole_=a};goog.ui.Control.prototype.getAriaLabel=function(){return this.ariaLabel_};goog.ui.Control.prototype.setAriaLabel=function(a){this.ariaLabel_=a;var b=this.getElement();b&&this.renderer_.setAriaLabel(b,a)};goog.ui.Control.prototype.getContentElement=function(){return this.renderer_.getContentElement(this.getElement())};goog.ui.Control.prototype.canDecorate=function(a){return this.renderer_.canDecorate(a)};
                +goog.ui.Control.prototype.decorateInternal=function(a){a=this.renderer_.decorate(this,a);this.setElementInternal(a);this.renderer_.setAriaRole(a,this.getPreferredAriaRole());this.isAllowTextSelection()||this.renderer_.setAllowTextSelection(a,!1);this.visible_="none"!=a.style.display};
                +goog.ui.Control.prototype.enterDocument=function(){goog.ui.Control.superClass_.enterDocument.call(this);this.renderer_.setAriaStates(this,this.getElementStrict());this.renderer_.initializeDom(this);if(this.supportedStates_&~goog.ui.Component.State.DISABLED&&(this.isHandleMouseEvents()&&this.enableMouseEventHandling_(!0),this.isSupportedState(goog.ui.Component.State.FOCUSED))){var a=this.getKeyEventTarget();if(a){var b=this.getKeyHandler();b.attach(a);this.getHandler().listen(b,goog.events.KeyHandler.EventType.KEY,
                +this.handleKeyEvent).listen(a,goog.events.EventType.FOCUS,this.handleFocus).listen(a,goog.events.EventType.BLUR,this.handleBlur)}}};
                +goog.ui.Control.prototype.enableMouseEventHandling_=function(a){var b=this.getHandler(),c=this.getElement();a?(b.listen(c,goog.events.EventType.MOUSEOVER,this.handleMouseOver).listen(c,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).listen(c,goog.events.EventType.MOUSEUP,this.handleMouseUp).listen(c,goog.events.EventType.MOUSEOUT,this.handleMouseOut),this.handleContextMenu!=goog.nullFunction&&b.listen(c,goog.events.EventType.CONTEXTMENU,this.handleContextMenu),goog.userAgent.IE&&(goog.userAgent.isVersionOrHigher(9)||
                +b.listen(c,goog.events.EventType.DBLCLICK,this.handleDblClick),this.ieMouseEventSequenceSimulator_||(this.ieMouseEventSequenceSimulator_=new goog.ui.Control.IeMouseEventSequenceSimulator_(this),this.registerDisposable(this.ieMouseEventSequenceSimulator_)))):(b.unlisten(c,goog.events.EventType.MOUSEOVER,this.handleMouseOver).unlisten(c,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).unlisten(c,goog.events.EventType.MOUSEUP,this.handleMouseUp).unlisten(c,goog.events.EventType.MOUSEOUT,this.handleMouseOut),
                +this.handleContextMenu!=goog.nullFunction&&b.unlisten(c,goog.events.EventType.CONTEXTMENU,this.handleContextMenu),goog.userAgent.IE&&(goog.userAgent.isVersionOrHigher(9)||b.unlisten(c,goog.events.EventType.DBLCLICK,this.handleDblClick),goog.dispose(this.ieMouseEventSequenceSimulator_),this.ieMouseEventSequenceSimulator_=null))};
                +goog.ui.Control.prototype.exitDocument=function(){goog.ui.Control.superClass_.exitDocument.call(this);this.keyHandler_&&this.keyHandler_.detach();this.isVisible()&&this.isEnabled()&&this.renderer_.setFocusable(this,!1)};goog.ui.Control.prototype.disposeInternal=function(){goog.ui.Control.superClass_.disposeInternal.call(this);this.keyHandler_&&(this.keyHandler_.dispose(),delete this.keyHandler_);delete this.renderer_;this.ieMouseEventSequenceSimulator_=this.extraClassNames_=this.content_=null};
                +goog.ui.Control.prototype.getContent=function(){return this.content_};goog.ui.Control.prototype.setContent=function(a){this.renderer_.setContent(this.getElement(),a);this.setContentInternal(a)};goog.ui.Control.prototype.setContentInternal=function(a){this.content_=a};goog.ui.Control.prototype.getCaption=function(){var a=this.getContent();if(!a)return"";a=goog.isString(a)?a:goog.isArray(a)?goog.array.map(a,goog.dom.getRawTextContent).join(""):goog.dom.getTextContent(a);return goog.string.collapseBreakingSpaces(a)};
                +goog.ui.Control.prototype.setCaption=function(a){this.setContent(a)};goog.ui.Control.prototype.setRightToLeft=function(a){goog.ui.Control.superClass_.setRightToLeft.call(this,a);var b=this.getElement();b&&this.renderer_.setRightToLeft(b,a)};goog.ui.Control.prototype.isAllowTextSelection=function(){return this.allowTextSelection_};goog.ui.Control.prototype.setAllowTextSelection=function(a){this.allowTextSelection_=a;var b=this.getElement();b&&this.renderer_.setAllowTextSelection(b,a)};
                +goog.ui.Control.prototype.isVisible=function(){return this.visible_};goog.ui.Control.prototype.setVisible=function(a,b){if(b||this.visible_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.SHOW:goog.ui.Component.EventType.HIDE)){var c=this.getElement();c&&this.renderer_.setVisible(c,a);this.isEnabled()&&this.renderer_.setFocusable(this,a);this.visible_=a;return!0}return!1};goog.ui.Control.prototype.isEnabled=function(){return!this.hasState(goog.ui.Component.State.DISABLED)};
                +goog.ui.Control.prototype.isParentDisabled_=function(){var a=this.getParent();return!!a&&"function"==typeof a.isEnabled&&!a.isEnabled()};goog.ui.Control.prototype.setEnabled=function(a){!this.isParentDisabled_()&&this.isTransitionAllowed(goog.ui.Component.State.DISABLED,!a)&&(a||(this.setActive(!1),this.setHighlighted(!1)),this.isVisible()&&this.renderer_.setFocusable(this,a),this.setState(goog.ui.Component.State.DISABLED,!a,!0))};goog.ui.Control.prototype.isHighlighted=function(){return this.hasState(goog.ui.Component.State.HOVER)};
                +goog.ui.Control.prototype.setHighlighted=function(a){this.isTransitionAllowed(goog.ui.Component.State.HOVER,a)&&this.setState(goog.ui.Component.State.HOVER,a)};goog.ui.Control.prototype.isActive=function(){return this.hasState(goog.ui.Component.State.ACTIVE)};goog.ui.Control.prototype.setActive=function(a){this.isTransitionAllowed(goog.ui.Component.State.ACTIVE,a)&&this.setState(goog.ui.Component.State.ACTIVE,a)};goog.ui.Control.prototype.isSelected=function(){return this.hasState(goog.ui.Component.State.SELECTED)};
                +goog.ui.Control.prototype.setSelected=function(a){this.isTransitionAllowed(goog.ui.Component.State.SELECTED,a)&&this.setState(goog.ui.Component.State.SELECTED,a)};goog.ui.Control.prototype.isChecked=function(){return this.hasState(goog.ui.Component.State.CHECKED)};goog.ui.Control.prototype.setChecked=function(a){this.isTransitionAllowed(goog.ui.Component.State.CHECKED,a)&&this.setState(goog.ui.Component.State.CHECKED,a)};goog.ui.Control.prototype.isFocused=function(){return this.hasState(goog.ui.Component.State.FOCUSED)};
                +goog.ui.Control.prototype.setFocused=function(a){this.isTransitionAllowed(goog.ui.Component.State.FOCUSED,a)&&this.setState(goog.ui.Component.State.FOCUSED,a)};goog.ui.Control.prototype.isOpen=function(){return this.hasState(goog.ui.Component.State.OPENED)};goog.ui.Control.prototype.setOpen=function(a){this.isTransitionAllowed(goog.ui.Component.State.OPENED,a)&&this.setState(goog.ui.Component.State.OPENED,a)};goog.ui.Control.prototype.getState=function(){return this.state_};
                +goog.ui.Control.prototype.hasState=function(a){return!!(this.state_&a)};goog.ui.Control.prototype.setState=function(a,b,c){c||a!=goog.ui.Component.State.DISABLED?this.isSupportedState(a)&&b!=this.hasState(a)&&(this.renderer_.setState(this,a,b),this.state_=b?this.state_|a:this.state_&~a):this.setEnabled(!b)};goog.ui.Control.prototype.setStateInternal=function(a){this.state_=a};goog.ui.Control.prototype.isSupportedState=function(a){return!!(this.supportedStates_&a)};
                +goog.ui.Control.prototype.setSupportedState=function(a,b){if(this.isInDocument()&&this.hasState(a)&&!b)throw Error(goog.ui.Component.Error.ALREADY_RENDERED);!b&&this.hasState(a)&&this.setState(a,!1);this.supportedStates_=b?this.supportedStates_|a:this.supportedStates_&~a};goog.ui.Control.prototype.isAutoState=function(a){return!!(this.autoStates_&a)&&this.isSupportedState(a)};goog.ui.Control.prototype.setAutoStates=function(a,b){this.autoStates_=b?this.autoStates_|a:this.autoStates_&~a};
                +goog.ui.Control.prototype.isDispatchTransitionEvents=function(a){return!!(this.statesWithTransitionEvents_&a)&&this.isSupportedState(a)};goog.ui.Control.prototype.setDispatchTransitionEvents=function(a,b){this.statesWithTransitionEvents_=b?this.statesWithTransitionEvents_|a:this.statesWithTransitionEvents_&~a};
                +goog.ui.Control.prototype.isTransitionAllowed=function(a,b){return this.isSupportedState(a)&&this.hasState(a)!=b&&(!(this.statesWithTransitionEvents_&a)||this.dispatchEvent(goog.ui.Component.getStateTransitionEvent(a,b)))&&!this.isDisposed()};goog.ui.Control.prototype.handleMouseOver=function(a){!goog.ui.Control.isMouseEventWithinElement_(a,this.getElement())&&this.dispatchEvent(goog.ui.Component.EventType.ENTER)&&this.isEnabled()&&this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0)};
                +goog.ui.Control.prototype.handleMouseOut=function(a){!goog.ui.Control.isMouseEventWithinElement_(a,this.getElement())&&this.dispatchEvent(goog.ui.Component.EventType.LEAVE)&&(this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1),this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!1))};goog.ui.Control.prototype.handleContextMenu=goog.nullFunction;goog.ui.Control.isMouseEventWithinElement_=function(a,b){return!!a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)};
                +goog.ui.Control.prototype.handleMouseDown=function(a){this.isEnabled()&&(this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0),a.isMouseActionButton()&&(this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!0),this.renderer_&&this.renderer_.isFocusable(this)&&this.getKeyEventTarget().focus()));!this.isAllowTextSelection()&&a.isMouseActionButton()&&a.preventDefault()};
                +goog.ui.Control.prototype.handleMouseUp=function(a){this.isEnabled()&&(this.isAutoState(goog.ui.Component.State.HOVER)&&this.setHighlighted(!0),this.isActive()&&this.performActionInternal(a)&&this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1))};goog.ui.Control.prototype.handleDblClick=function(a){this.isEnabled()&&this.performActionInternal(a)};
                +goog.ui.Control.prototype.performActionInternal=function(a){this.isAutoState(goog.ui.Component.State.CHECKED)&&this.setChecked(!this.isChecked());this.isAutoState(goog.ui.Component.State.SELECTED)&&this.setSelected(!0);this.isAutoState(goog.ui.Component.State.OPENED)&&this.setOpen(!this.isOpen());var b=new goog.events.Event(goog.ui.Component.EventType.ACTION,this);a&&(b.altKey=a.altKey,b.ctrlKey=a.ctrlKey,b.metaKey=a.metaKey,b.shiftKey=a.shiftKey,b.platformModifierKey=a.platformModifierKey);return this.dispatchEvent(b)};
                +goog.ui.Control.prototype.handleFocus=function(a){this.isAutoState(goog.ui.Component.State.FOCUSED)&&this.setFocused(!0)};goog.ui.Control.prototype.handleBlur=function(a){this.isAutoState(goog.ui.Component.State.ACTIVE)&&this.setActive(!1);this.isAutoState(goog.ui.Component.State.FOCUSED)&&this.setFocused(!1)};goog.ui.Control.prototype.handleKeyEvent=function(a){return this.isVisible()&&this.isEnabled()&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
                +goog.ui.Control.prototype.handleKeyEventInternal=function(a){return a.keyCode==goog.events.KeyCodes.ENTER&&this.performActionInternal(a)};goog.ui.registry.setDefaultRenderer(goog.ui.Control,goog.ui.ControlRenderer);goog.ui.registry.setDecoratorByClassName(goog.ui.ControlRenderer.CSS_CLASS,function(){return new goog.ui.Control(null)});
                +goog.ui.Control.IeMouseEventSequenceSimulator_=function(a){goog.Disposable.call(this);this.control_=a;this.clickExpected_=!1;this.handler_=new goog.events.EventHandler(this);this.registerDisposable(this.handler_);a=this.control_.getElementStrict();this.handler_.listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseDown_).listen(a,goog.events.EventType.MOUSEUP,this.handleMouseUp_).listen(a,goog.events.EventType.CLICK,this.handleClick_)};
                +goog.inherits(goog.ui.Control.IeMouseEventSequenceSimulator_,goog.Disposable);goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_=!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9);goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleMouseDown_=function(){this.clickExpected_=!1};goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleMouseUp_=function(){this.clickExpected_=!0};
                +goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_=function(a,b){if(!goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_)return a.button=goog.events.BrowserEvent.MouseButton.LEFT,a.type=b,a;var c=document.createEvent("MouseEvents");c.initMouseEvent(b,a.bubbles,a.cancelable,a.view||null,a.detail,a.screenX,a.screenY,a.clientX,a.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,goog.events.BrowserEvent.MouseButton.LEFT,a.relatedTarget||null);return c};
                +goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.handleClick_=function(a){if(this.clickExpected_)this.clickExpected_=!1;else{var b=a.getBrowserEvent(),c=b.button,d=b.type,e=goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_(b,goog.events.EventType.MOUSEDOWN);this.control_.handleMouseDown(new goog.events.BrowserEvent(e,a.currentTarget));e=goog.ui.Control.IeMouseEventSequenceSimulator_.makeLeftMouseEvent_(b,goog.events.EventType.MOUSEUP);this.control_.handleMouseUp(new goog.events.BrowserEvent(e,
                +a.currentTarget));goog.ui.Control.IeMouseEventSequenceSimulator_.SYNTHETIC_EVENTS_||(b.button=c,b.type=d)}};goog.ui.Control.IeMouseEventSequenceSimulator_.prototype.disposeInternal=function(){this.control_=null;goog.ui.Control.IeMouseEventSequenceSimulator_.superClass_.disposeInternal.call(this)};goog.ui.Container=function(a,b,c){goog.ui.Component.call(this,c);this.renderer_=b||goog.ui.ContainerRenderer.getInstance();this.orientation_=a||this.renderer_.getDefaultOrientation()};goog.inherits(goog.ui.Container,goog.ui.Component);goog.tagUnsealableClass(goog.ui.Container);goog.ui.Container.EventType={AFTER_SHOW:"aftershow",AFTER_HIDE:"afterhide"};goog.ui.Container.Orientation={HORIZONTAL:"horizontal",VERTICAL:"vertical"};goog.ui.Container.prototype.keyEventTarget_=null;
                +goog.ui.Container.prototype.keyHandler_=null;goog.ui.Container.prototype.renderer_=null;goog.ui.Container.prototype.orientation_=null;goog.ui.Container.prototype.visible_=!0;goog.ui.Container.prototype.enabled_=!0;goog.ui.Container.prototype.focusable_=!0;goog.ui.Container.prototype.highlightedIndex_=-1;goog.ui.Container.prototype.openItem_=null;goog.ui.Container.prototype.mouseButtonPressed_=!1;goog.ui.Container.prototype.allowFocusableChildren_=!1;
                +goog.ui.Container.prototype.openFollowsHighlight_=!0;goog.ui.Container.prototype.childElementIdMap_=null;goog.ui.Container.prototype.getKeyEventTarget=function(){return this.keyEventTarget_||this.renderer_.getKeyEventTarget(this)};
                +goog.ui.Container.prototype.setKeyEventTarget=function(a){if(this.focusable_){var b=this.getKeyEventTarget(),c=this.isInDocument();this.keyEventTarget_=a;var d=this.getKeyEventTarget();c&&(this.keyEventTarget_=b,this.enableFocusHandling_(!1),this.keyEventTarget_=a,this.getKeyHandler().attach(d),this.enableFocusHandling_(!0))}else throw Error("Can't set key event target for container that doesn't support keyboard focus!");};
                +goog.ui.Container.prototype.getKeyHandler=function(){return this.keyHandler_||(this.keyHandler_=new goog.events.KeyHandler(this.getKeyEventTarget()))};goog.ui.Container.prototype.getRenderer=function(){return this.renderer_};goog.ui.Container.prototype.setRenderer=function(a){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.renderer_=a};goog.ui.Container.prototype.createDom=function(){this.setElementInternal(this.renderer_.createDom(this))};
                +goog.ui.Container.prototype.getContentElement=function(){return this.renderer_.getContentElement(this.getElement())};goog.ui.Container.prototype.canDecorate=function(a){return this.renderer_.canDecorate(a)};goog.ui.Container.prototype.decorateInternal=function(a){this.setElementInternal(this.renderer_.decorate(this,a));"none"==a.style.display&&(this.visible_=!1)};
                +goog.ui.Container.prototype.enterDocument=function(){goog.ui.Container.superClass_.enterDocument.call(this);this.forEachChild(function(a){a.isInDocument()&&this.registerChildId_(a)},this);var a=this.getElement();this.renderer_.initializeDom(this);this.setVisible(this.visible_,!0);this.getHandler().listen(this,goog.ui.Component.EventType.ENTER,this.handleEnterItem).listen(this,goog.ui.Component.EventType.HIGHLIGHT,this.handleHighlightItem).listen(this,goog.ui.Component.EventType.UNHIGHLIGHT,this.handleUnHighlightItem).listen(this,
                +goog.ui.Component.EventType.OPEN,this.handleOpenItem).listen(this,goog.ui.Component.EventType.CLOSE,this.handleCloseItem).listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseDown).listen(goog.dom.getOwnerDocument(a),goog.events.EventType.MOUSEUP,this.handleDocumentMouseUp).listen(a,[goog.events.EventType.MOUSEDOWN,goog.events.EventType.MOUSEUP,goog.events.EventType.MOUSEOVER,goog.events.EventType.MOUSEOUT,goog.events.EventType.CONTEXTMENU],this.handleChildMouseEvents);this.isFocusable()&&this.enableFocusHandling_(!0)};
                +goog.ui.Container.prototype.enableFocusHandling_=function(a){var b=this.getHandler(),c=this.getKeyEventTarget();a?b.listen(c,goog.events.EventType.FOCUS,this.handleFocus).listen(c,goog.events.EventType.BLUR,this.handleBlur).listen(this.getKeyHandler(),goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent):b.unlisten(c,goog.events.EventType.FOCUS,this.handleFocus).unlisten(c,goog.events.EventType.BLUR,this.handleBlur).unlisten(this.getKeyHandler(),goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent)};
                +goog.ui.Container.prototype.exitDocument=function(){this.setHighlightedIndex(-1);this.openItem_&&this.openItem_.setOpen(!1);this.mouseButtonPressed_=!1;goog.ui.Container.superClass_.exitDocument.call(this)};goog.ui.Container.prototype.disposeInternal=function(){goog.ui.Container.superClass_.disposeInternal.call(this);this.keyHandler_&&(this.keyHandler_.dispose(),this.keyHandler_=null);this.renderer_=this.openItem_=this.childElementIdMap_=this.keyEventTarget_=null};
                +goog.ui.Container.prototype.handleEnterItem=function(a){return!0};
                +goog.ui.Container.prototype.handleHighlightItem=function(a){var b=this.indexOfChild(a.target);if(-1<b&&b!=this.highlightedIndex_){var c=this.getHighlighted();c&&c.setHighlighted(!1);this.highlightedIndex_=b;c=this.getHighlighted();this.isMouseButtonPressed()&&c.setActive(!0);this.openFollowsHighlight_&&this.openItem_&&c!=this.openItem_&&(c.isSupportedState(goog.ui.Component.State.OPENED)?c.setOpen(!0):this.openItem_.setOpen(!1))}b=this.getElement();goog.asserts.assert(b,"The DOM element for the container cannot be null.");
                +null!=a.target.getElement()&&goog.a11y.aria.setState(b,goog.a11y.aria.State.ACTIVEDESCENDANT,a.target.getElement().id)};goog.ui.Container.prototype.handleUnHighlightItem=function(a){a.target==this.getHighlighted()&&(this.highlightedIndex_=-1);a=this.getElement();goog.asserts.assert(a,"The DOM element for the container cannot be null.");goog.a11y.aria.removeState(a,goog.a11y.aria.State.ACTIVEDESCENDANT)};
                +goog.ui.Container.prototype.handleOpenItem=function(a){(a=a.target)&&a!=this.openItem_&&a.getParent()==this&&(this.openItem_&&this.openItem_.setOpen(!1),this.openItem_=a)};goog.ui.Container.prototype.handleCloseItem=function(a){a.target==this.openItem_&&(this.openItem_=null);var b=this.getElement(),c=a.target.getElement();b&&a.target.isHighlighted()&&c&&goog.a11y.aria.setActiveDescendant(b,c)};
                +goog.ui.Container.prototype.handleMouseDown=function(a){this.enabled_&&this.setMouseButtonPressed(!0);var b=this.getKeyEventTarget();b&&goog.dom.isFocusableTabIndex(b)?b.focus():a.preventDefault()};goog.ui.Container.prototype.handleDocumentMouseUp=function(a){this.setMouseButtonPressed(!1)};
                +goog.ui.Container.prototype.handleChildMouseEvents=function(a){var b=this.getOwnerControl(a.target);if(b)switch(a.type){case goog.events.EventType.MOUSEDOWN:b.handleMouseDown(a);break;case goog.events.EventType.MOUSEUP:b.handleMouseUp(a);break;case goog.events.EventType.MOUSEOVER:b.handleMouseOver(a);break;case goog.events.EventType.MOUSEOUT:b.handleMouseOut(a);break;case goog.events.EventType.CONTEXTMENU:b.handleContextMenu(a)}};
                +goog.ui.Container.prototype.getOwnerControl=function(a){if(this.childElementIdMap_)for(var b=this.getElement();a&&a!==b;){var c=a.id;if(c in this.childElementIdMap_)return this.childElementIdMap_[c];a=a.parentNode}return null};goog.ui.Container.prototype.handleFocus=function(a){};goog.ui.Container.prototype.handleBlur=function(a){this.setHighlightedIndex(-1);this.setMouseButtonPressed(!1);this.openItem_&&this.openItem_.setOpen(!1)};
                +goog.ui.Container.prototype.handleKeyEvent=function(a){return this.isEnabled()&&this.isVisible()&&(0!=this.getChildCount()||this.keyEventTarget_)&&this.handleKeyEventInternal(a)?(a.preventDefault(),a.stopPropagation(),!0):!1};
                +goog.ui.Container.prototype.handleKeyEventInternal=function(a){var b=this.getHighlighted();if(b&&"function"==typeof b.handleKeyEvent&&b.handleKeyEvent(a)||this.openItem_&&this.openItem_!=b&&"function"==typeof this.openItem_.handleKeyEvent&&this.openItem_.handleKeyEvent(a))return!0;if(a.shiftKey||a.ctrlKey||a.metaKey||a.altKey)return!1;switch(a.keyCode){case goog.events.KeyCodes.ESC:if(this.isFocusable())this.getKeyEventTarget().blur();else return!1;break;case goog.events.KeyCodes.HOME:this.highlightFirst();
                +break;case goog.events.KeyCodes.END:this.highlightLast();break;case goog.events.KeyCodes.UP:if(this.orientation_==goog.ui.Container.Orientation.VERTICAL)this.highlightPrevious();else return!1;break;case goog.events.KeyCodes.LEFT:if(this.orientation_==goog.ui.Container.Orientation.HORIZONTAL)this.isRightToLeft()?this.highlightNext():this.highlightPrevious();else return!1;break;case goog.events.KeyCodes.DOWN:if(this.orientation_==goog.ui.Container.Orientation.VERTICAL)this.highlightNext();else return!1;
                +break;case goog.events.KeyCodes.RIGHT:if(this.orientation_==goog.ui.Container.Orientation.HORIZONTAL)this.isRightToLeft()?this.highlightPrevious():this.highlightNext();else return!1;break;default:return!1}return!0};goog.ui.Container.prototype.registerChildId_=function(a){var b=a.getElement(),b=b.id||(b.id=a.getId());this.childElementIdMap_||(this.childElementIdMap_={});this.childElementIdMap_[b]=a};
                +goog.ui.Container.prototype.addChild=function(a,b){goog.asserts.assertInstanceof(a,goog.ui.Control,"The child of a container must be a control");goog.ui.Container.superClass_.addChild.call(this,a,b)};
                +goog.ui.Container.prototype.addChildAt=function(a,b,c){goog.asserts.assertInstanceof(a,goog.ui.Control);a.setDispatchTransitionEvents(goog.ui.Component.State.HOVER,!0);a.setDispatchTransitionEvents(goog.ui.Component.State.OPENED,!0);!this.isFocusable()&&this.isFocusableChildrenAllowed()||a.setSupportedState(goog.ui.Component.State.FOCUSED,!1);a.setHandleMouseEvents(!1);var d=a.getParent()==this?this.indexOfChild(a):-1;goog.ui.Container.superClass_.addChildAt.call(this,a,b,c);a.isInDocument()&&this.isInDocument()&&
                +this.registerChildId_(a);this.updateHighlightedIndex_(d,b)};goog.ui.Container.prototype.updateHighlightedIndex_=function(a,b){-1==a&&(a=this.getChildCount());a==this.highlightedIndex_?this.highlightedIndex_=Math.min(this.getChildCount()-1,b):a>this.highlightedIndex_&&b<=this.highlightedIndex_?this.highlightedIndex_++:a<this.highlightedIndex_&&b>this.highlightedIndex_&&this.highlightedIndex_--};
                +goog.ui.Container.prototype.removeChild=function(a,b){a=goog.isString(a)?this.getChild(a):a;goog.asserts.assertInstanceof(a,goog.ui.Control);if(a){var c=this.indexOfChild(a);-1!=c&&(c==this.highlightedIndex_?(a.setHighlighted(!1),this.highlightedIndex_=-1):c<this.highlightedIndex_&&this.highlightedIndex_--);(c=a.getElement())&&c.id&&this.childElementIdMap_&&goog.object.remove(this.childElementIdMap_,c.id)}a=goog.ui.Container.superClass_.removeChild.call(this,a,b);a.setHandleMouseEvents(!0);return a};
                +goog.ui.Container.prototype.getOrientation=function(){return this.orientation_};goog.ui.Container.prototype.setOrientation=function(a){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.orientation_=a};goog.ui.Container.prototype.isVisible=function(){return this.visible_};
                +goog.ui.Container.prototype.setVisible=function(a,b){if(b||this.visible_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.SHOW:goog.ui.Component.EventType.HIDE)){this.visible_=a;var c=this.getElement();c&&(goog.style.setElementShown(c,a),this.isFocusable()&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),this.enabled_&&this.visible_),b||this.dispatchEvent(this.visible_?goog.ui.Container.EventType.AFTER_SHOW:goog.ui.Container.EventType.AFTER_HIDE));return!0}return!1};
                +goog.ui.Container.prototype.isEnabled=function(){return this.enabled_};
                +goog.ui.Container.prototype.setEnabled=function(a){this.enabled_!=a&&this.dispatchEvent(a?goog.ui.Component.EventType.ENABLE:goog.ui.Component.EventType.DISABLE)&&(a?(this.enabled_=!0,this.forEachChild(function(a){a.wasDisabled?delete a.wasDisabled:a.setEnabled(!0)})):(this.forEachChild(function(a){a.isEnabled()?a.setEnabled(!1):a.wasDisabled=!0}),this.enabled_=!1,this.setMouseButtonPressed(!1)),this.isFocusable()&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),a&&this.visible_))};
                +goog.ui.Container.prototype.isFocusable=function(){return this.focusable_};goog.ui.Container.prototype.setFocusable=function(a){a!=this.focusable_&&this.isInDocument()&&this.enableFocusHandling_(a);this.focusable_=a;this.enabled_&&this.visible_&&this.renderer_.enableTabIndex(this.getKeyEventTarget(),a)};goog.ui.Container.prototype.isFocusableChildrenAllowed=function(){return this.allowFocusableChildren_};
                +goog.ui.Container.prototype.setFocusableChildrenAllowed=function(a){this.allowFocusableChildren_=a};goog.ui.Container.prototype.isOpenFollowsHighlight=function(){return this.openFollowsHighlight_};goog.ui.Container.prototype.setOpenFollowsHighlight=function(a){this.openFollowsHighlight_=a};goog.ui.Container.prototype.getHighlightedIndex=function(){return this.highlightedIndex_};
                +goog.ui.Container.prototype.setHighlightedIndex=function(a){(a=this.getChildAt(a))?a.setHighlighted(!0):-1<this.highlightedIndex_&&this.getHighlighted().setHighlighted(!1)};goog.ui.Container.prototype.setHighlighted=function(a){this.setHighlightedIndex(this.indexOfChild(a))};goog.ui.Container.prototype.getHighlighted=function(){return this.getChildAt(this.highlightedIndex_)};
                +goog.ui.Container.prototype.highlightFirst=function(){this.highlightHelper(function(a,b){return(a+1)%b},this.getChildCount()-1)};goog.ui.Container.prototype.highlightLast=function(){this.highlightHelper(function(a,b){a--;return 0>a?b-1:a},0)};goog.ui.Container.prototype.highlightNext=function(){this.highlightHelper(function(a,b){return(a+1)%b},this.highlightedIndex_)};goog.ui.Container.prototype.highlightPrevious=function(){this.highlightHelper(function(a,b){a--;return 0>a?b-1:a},this.highlightedIndex_)};
                +goog.ui.Container.prototype.highlightHelper=function(a,b){for(var c=0>b?this.indexOfChild(this.openItem_):b,d=this.getChildCount(),c=a.call(this,c,d),e=0;e<=d;){var f=this.getChildAt(c);if(f&&this.canHighlightItem(f))return this.setHighlightedIndexFromKeyEvent(c),!0;e++;c=a.call(this,c,d)}return!1};goog.ui.Container.prototype.canHighlightItem=function(a){return a.isVisible()&&a.isEnabled()&&a.isSupportedState(goog.ui.Component.State.HOVER)};
                +goog.ui.Container.prototype.setHighlightedIndexFromKeyEvent=function(a){this.setHighlightedIndex(a)};goog.ui.Container.prototype.getOpenItem=function(){return this.openItem_};goog.ui.Container.prototype.isMouseButtonPressed=function(){return this.mouseButtonPressed_};goog.ui.Container.prototype.setMouseButtonPressed=function(a){this.mouseButtonPressed_=a};goog.ui.MenuHeaderRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.MenuHeaderRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuHeaderRenderer);goog.ui.MenuHeaderRenderer.CSS_CLASS="goog-menuheader";goog.ui.MenuHeaderRenderer.prototype.getCssClass=function(){return goog.ui.MenuHeaderRenderer.CSS_CLASS};goog.ui.MenuHeader=function(a,b,c){goog.ui.Control.call(this,a,c||goog.ui.MenuHeaderRenderer.getInstance(),b);this.setSupportedState(goog.ui.Component.State.DISABLED,!1);this.setSupportedState(goog.ui.Component.State.HOVER,!1);this.setSupportedState(goog.ui.Component.State.ACTIVE,!1);this.setSupportedState(goog.ui.Component.State.FOCUSED,!1);this.setStateInternal(goog.ui.Component.State.DISABLED)};goog.inherits(goog.ui.MenuHeader,goog.ui.Control);
                +goog.ui.registry.setDecoratorByClassName(goog.ui.MenuHeaderRenderer.CSS_CLASS,function(){return new goog.ui.MenuHeader(null)});goog.ui.MenuItemRenderer=function(){goog.ui.ControlRenderer.call(this);this.classNameCache_=[]};goog.inherits(goog.ui.MenuItemRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuItemRenderer);goog.ui.MenuItemRenderer.CSS_CLASS="goog-menuitem";goog.ui.MenuItemRenderer.CompositeCssClassIndex_={HOVER:0,CHECKBOX:1,CONTENT:2};
                +goog.ui.MenuItemRenderer.prototype.getCompositeCssClass_=function(a){var b=this.classNameCache_[a];if(!b){switch(a){case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER:b=this.getStructuralCssClass()+"-highlight";break;case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX:b=this.getStructuralCssClass()+"-checkbox";break;case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT:b=this.getStructuralCssClass()+"-content"}this.classNameCache_[a]=b}return b};
                +goog.ui.MenuItemRenderer.prototype.getAriaRole=function(){return goog.a11y.aria.Role.MENU_ITEM};goog.ui.MenuItemRenderer.prototype.createDom=function(a){var b=a.getDomHelper().createDom("DIV",this.getClassNames(a).join(" "),this.createContent(a.getContent(),a.getDomHelper()));this.setEnableCheckBoxStructure(a,b,a.isSupportedState(goog.ui.Component.State.SELECTED)||a.isSupportedState(goog.ui.Component.State.CHECKED));return b};
                +goog.ui.MenuItemRenderer.prototype.getContentElement=function(a){return a&&a.firstChild};goog.ui.MenuItemRenderer.prototype.decorate=function(a,b){goog.asserts.assert(b);this.hasContentStructure(b)||b.appendChild(this.createContent(b.childNodes,a.getDomHelper()));goog.dom.classlist.contains(b,"goog-option")&&(a.setCheckable(!0),this.setCheckable(a,b,!0));return goog.ui.MenuItemRenderer.superClass_.decorate.call(this,a,b)};
                +goog.ui.MenuItemRenderer.prototype.setContent=function(a,b){var c=this.getContentElement(a),d=this.hasCheckBoxStructure(a)?c.firstChild:null;goog.ui.MenuItemRenderer.superClass_.setContent.call(this,a,b);d&&!this.hasCheckBoxStructure(a)&&c.insertBefore(d,c.firstChild||null)};
                +goog.ui.MenuItemRenderer.prototype.hasContentStructure=function(a){a=goog.dom.getFirstElementChild(a);var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT);return!!a&&goog.dom.classlist.contains(a,b)};goog.ui.MenuItemRenderer.prototype.createContent=function(a,b){var c=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT);return b.createDom("DIV",c,a)};
                +goog.ui.MenuItemRenderer.prototype.setSelectable=function(a,b,c){a&&b&&this.setEnableCheckBoxStructure(a,b,c)};goog.ui.MenuItemRenderer.prototype.setCheckable=function(a,b,c){a&&b&&this.setEnableCheckBoxStructure(a,b,c)};goog.ui.MenuItemRenderer.prototype.hasCheckBoxStructure=function(a){if(a=this.getContentElement(a)){a=a.firstChild;var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX);return!!a&&goog.dom.isElement(a)&&goog.dom.classlist.contains(a,b)}return!1};
                +goog.ui.MenuItemRenderer.prototype.setEnableCheckBoxStructure=function(a,b,c){this.setAriaRole(b,a.getPreferredAriaRole());this.setAriaStates(a,b);c!=this.hasCheckBoxStructure(b)&&(goog.dom.classlist.enable(b,"goog-option",c),b=this.getContentElement(b),c?(c=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX),b.insertBefore(a.getDomHelper().createDom("DIV",c),b.firstChild||null)):b.removeChild(b.firstChild))};
                +goog.ui.MenuItemRenderer.prototype.getClassForState=function(a){switch(a){case goog.ui.Component.State.HOVER:return this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER);case goog.ui.Component.State.CHECKED:case goog.ui.Component.State.SELECTED:return"goog-option-selected";default:return goog.ui.MenuItemRenderer.superClass_.getClassForState.call(this,a)}};
                +goog.ui.MenuItemRenderer.prototype.getStateFromClass=function(a){var b=this.getCompositeCssClass_(goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER);switch(a){case "goog-option-selected":return goog.ui.Component.State.CHECKED;case b:return goog.ui.Component.State.HOVER;default:return goog.ui.MenuItemRenderer.superClass_.getStateFromClass.call(this,a)}};goog.ui.MenuItemRenderer.prototype.getCssClass=function(){return goog.ui.MenuItemRenderer.CSS_CLASS};goog.ui.MenuItem=function(a,b,c,d){goog.ui.Control.call(this,a,d||goog.ui.MenuItemRenderer.getInstance(),c);this.setValue(b)};goog.inherits(goog.ui.MenuItem,goog.ui.Control);goog.tagUnsealableClass(goog.ui.MenuItem);goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_="goog-menuitem-mnemonic-separator";goog.ui.MenuItem.ACCELERATOR_CLASS="goog-menuitem-accel";goog.ui.MenuItem.prototype.getValue=function(){var a=this.getModel();return null!=a?a:this.getCaption()};goog.ui.MenuItem.prototype.setValue=function(a){this.setModel(a)};
                +goog.ui.MenuItem.prototype.setSupportedState=function(a,b){goog.ui.MenuItem.superClass_.setSupportedState.call(this,a,b);switch(a){case goog.ui.Component.State.SELECTED:this.setSelectableInternal_(b);break;case goog.ui.Component.State.CHECKED:this.setCheckableInternal_(b)}};goog.ui.MenuItem.prototype.setSelectable=function(a){this.setSupportedState(goog.ui.Component.State.SELECTED,a)};
                +goog.ui.MenuItem.prototype.setSelectableInternal_=function(a){this.isChecked()&&!a&&this.setChecked(!1);var b=this.getElement();b&&this.getRenderer().setSelectable(this,b,a)};goog.ui.MenuItem.prototype.setCheckable=function(a){this.setSupportedState(goog.ui.Component.State.CHECKED,a)};goog.ui.MenuItem.prototype.setCheckableInternal_=function(a){var b=this.getElement();b&&this.getRenderer().setCheckable(this,b,a)};
                +goog.ui.MenuItem.prototype.getCaption=function(){var a=this.getContent();if(goog.isArray(a)){var b=goog.ui.MenuItem.ACCELERATOR_CLASS,c=goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_,a=goog.array.map(a,function(a){return goog.dom.isElement(a)&&(goog.dom.classlist.contains(a,b)||goog.dom.classlist.contains(a,c))?"":goog.dom.getRawTextContent(a)}).join("");return goog.string.collapseBreakingSpaces(a)}return goog.ui.MenuItem.superClass_.getCaption.call(this)};
                +goog.ui.MenuItem.prototype.getAccelerator=function(){var a=this.getDomHelper(),b=this.getContent();return goog.isArray(b)&&(b=goog.array.find(b,function(a){return goog.dom.classlist.contains(a,goog.ui.MenuItem.ACCELERATOR_CLASS)}))?a.getTextContent(b):null};
                +goog.ui.MenuItem.prototype.handleMouseUp=function(a){var b=this.getParent();if(b){var c=b.openingCoords;b.openingCoords=null;if(c&&goog.isNumber(a.clientX)&&(b=new goog.math.Coordinate(a.clientX,a.clientY),goog.math.Coordinate.equals(c,b)))return}goog.ui.MenuItem.superClass_.handleMouseUp.call(this,a)};goog.ui.MenuItem.prototype.handleKeyEventInternal=function(a){return a.keyCode==this.getMnemonic()&&this.performActionInternal(a)?!0:goog.ui.MenuItem.superClass_.handleKeyEventInternal.call(this,a)};
                +goog.ui.MenuItem.prototype.setMnemonic=function(a){this.mnemonicKey_=a};goog.ui.MenuItem.prototype.getMnemonic=function(){return this.mnemonicKey_};goog.ui.registry.setDecoratorByClassName(goog.ui.MenuItemRenderer.CSS_CLASS,function(){return new goog.ui.MenuItem(null)});
                +goog.ui.MenuItem.prototype.getPreferredAriaRole=function(){return this.isSupportedState(goog.ui.Component.State.CHECKED)?goog.a11y.aria.Role.MENU_ITEM_CHECKBOX:this.isSupportedState(goog.ui.Component.State.SELECTED)?goog.a11y.aria.Role.MENU_ITEM_RADIO:goog.ui.MenuItem.superClass_.getPreferredAriaRole.call(this)};goog.ui.MenuItem.prototype.getParent=function(){return goog.ui.Control.prototype.getParent.call(this)};goog.ui.MenuItem.prototype.getParentEventTarget=function(){return goog.ui.Control.prototype.getParentEventTarget.call(this)};goog.ui.MenuSeparatorRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.MenuSeparatorRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.MenuSeparatorRenderer);goog.ui.MenuSeparatorRenderer.CSS_CLASS="goog-menuseparator";goog.ui.MenuSeparatorRenderer.prototype.createDom=function(a){return a.getDomHelper().createDom("DIV",this.getCssClass())};
                +goog.ui.MenuSeparatorRenderer.prototype.decorate=function(a,b){b.id&&a.setId(b.id);if("HR"==b.tagName){var c=b;b=this.createDom(a);goog.dom.insertSiblingBefore(b,c);goog.dom.removeNode(c)}else goog.dom.classlist.add(b,this.getCssClass());return b};goog.ui.MenuSeparatorRenderer.prototype.setContent=function(a,b){};goog.ui.MenuSeparatorRenderer.prototype.getCssClass=function(){return goog.ui.MenuSeparatorRenderer.CSS_CLASS};goog.ui.Separator=function(a,b){goog.ui.Control.call(this,null,a||goog.ui.MenuSeparatorRenderer.getInstance(),b);this.setSupportedState(goog.ui.Component.State.DISABLED,!1);this.setSupportedState(goog.ui.Component.State.HOVER,!1);this.setSupportedState(goog.ui.Component.State.ACTIVE,!1);this.setSupportedState(goog.ui.Component.State.FOCUSED,!1);this.setStateInternal(goog.ui.Component.State.DISABLED)};goog.inherits(goog.ui.Separator,goog.ui.Control);
                +goog.ui.Separator.prototype.enterDocument=function(){goog.ui.Separator.superClass_.enterDocument.call(this);var a=this.getElement();goog.asserts.assert(a,"The DOM element for the separator cannot be null.");goog.a11y.aria.setRole(a,"separator")};goog.ui.registry.setDecoratorByClassName(goog.ui.MenuSeparatorRenderer.CSS_CLASS,function(){return new goog.ui.Separator});goog.ui.MenuRenderer=function(a){goog.ui.ContainerRenderer.call(this,a||goog.a11y.aria.Role.MENU)};goog.inherits(goog.ui.MenuRenderer,goog.ui.ContainerRenderer);goog.addSingletonGetter(goog.ui.MenuRenderer);goog.ui.MenuRenderer.CSS_CLASS="goog-menu";goog.ui.MenuRenderer.prototype.canDecorate=function(a){return"UL"==a.tagName||goog.ui.MenuRenderer.superClass_.canDecorate.call(this,a)};
                +goog.ui.MenuRenderer.prototype.getDecoratorForChild=function(a){return"HR"==a.tagName?new goog.ui.Separator:goog.ui.MenuRenderer.superClass_.getDecoratorForChild.call(this,a)};goog.ui.MenuRenderer.prototype.containsElement=function(a,b){return goog.dom.contains(a.getElement(),b)};goog.ui.MenuRenderer.prototype.getCssClass=function(){return goog.ui.MenuRenderer.CSS_CLASS};
                +goog.ui.MenuRenderer.prototype.initializeDom=function(a){goog.ui.MenuRenderer.superClass_.initializeDom.call(this,a);a=a.getElement();goog.asserts.assert(a,"The menu DOM element cannot be null.");goog.a11y.aria.setState(a,goog.a11y.aria.State.HASPOPUP,"true")};goog.ui.MenuSeparator=function(a){goog.ui.Separator.call(this,goog.ui.MenuSeparatorRenderer.getInstance(),a)};goog.inherits(goog.ui.MenuSeparator,goog.ui.Separator);goog.ui.registry.setDecoratorByClassName(goog.ui.MenuSeparatorRenderer.CSS_CLASS,function(){return new goog.ui.Separator});goog.ui.Menu=function(a,b){goog.ui.Container.call(this,goog.ui.Container.Orientation.VERTICAL,b||goog.ui.MenuRenderer.getInstance(),a);this.setFocusable(!1)};goog.inherits(goog.ui.Menu,goog.ui.Container);goog.tagUnsealableClass(goog.ui.Menu);goog.ui.Menu.EventType={BEFORE_SHOW:goog.ui.Component.EventType.BEFORE_SHOW,SHOW:goog.ui.Component.EventType.SHOW,BEFORE_HIDE:goog.ui.Component.EventType.HIDE,HIDE:goog.ui.Component.EventType.HIDE};goog.ui.Menu.CSS_CLASS=goog.ui.MenuRenderer.CSS_CLASS;
                +goog.ui.Menu.prototype.allowAutoFocus_=!0;goog.ui.Menu.prototype.allowHighlightDisabled_=!1;goog.ui.Menu.prototype.getCssClass=function(){return this.getRenderer().getCssClass()};goog.ui.Menu.prototype.containsElement=function(a){if(this.getRenderer().containsElement(this,a))return!0;for(var b=0,c=this.getChildCount();b<c;b++){var d=this.getChildAt(b);if("function"==typeof d.containsElement&&d.containsElement(a))return!0}return!1};goog.ui.Menu.prototype.addItem=function(a){this.addChild(a,!0)};
                +goog.ui.Menu.prototype.addItemAt=function(a,b){this.addChildAt(a,b,!0)};goog.ui.Menu.prototype.removeItem=function(a){(a=this.removeChild(a,!0))&&a.dispose()};goog.ui.Menu.prototype.removeItemAt=function(a){(a=this.removeChildAt(a,!0))&&a.dispose()};goog.ui.Menu.prototype.getItemAt=function(a){return this.getChildAt(a)};goog.ui.Menu.prototype.getItemCount=function(){return this.getChildCount()};goog.ui.Menu.prototype.getItems=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};
                +goog.ui.Menu.prototype.setPosition=function(a,b){var c=this.isVisible();c||goog.style.setElementShown(this.getElement(),!0);goog.style.setPageOffset(this.getElement(),a,b);c||goog.style.setElementShown(this.getElement(),!1)};goog.ui.Menu.prototype.getPosition=function(){return this.isVisible()?goog.style.getPageOffset(this.getElement()):null};goog.ui.Menu.prototype.setAllowAutoFocus=function(a){(this.allowAutoFocus_=a)&&this.setFocusable(!0)};goog.ui.Menu.prototype.getAllowAutoFocus=function(){return this.allowAutoFocus_};
                +goog.ui.Menu.prototype.setAllowHighlightDisabled=function(a){this.allowHighlightDisabled_=a};goog.ui.Menu.prototype.getAllowHighlightDisabled=function(){return this.allowHighlightDisabled_};goog.ui.Menu.prototype.setVisible=function(a,b,c){(b=goog.ui.Menu.superClass_.setVisible.call(this,a,b))&&a&&this.isInDocument()&&this.allowAutoFocus_&&this.getKeyEventTarget().focus();a&&c&&goog.isNumber(c.clientX)?this.openingCoords=new goog.math.Coordinate(c.clientX,c.clientY):this.openingCoords=null;return b};
                +goog.ui.Menu.prototype.handleEnterItem=function(a){this.allowAutoFocus_&&this.getKeyEventTarget().focus();return goog.ui.Menu.superClass_.handleEnterItem.call(this,a)};goog.ui.Menu.prototype.highlightNextPrefix=function(a){var b=new RegExp("^"+goog.string.regExpEscape(a),"i");return this.highlightHelper(function(a,d){var c=0>a?0:a,f=!1;do{++a;a==d&&(a=0,f=!0);var g=this.getChildAt(a).getCaption();if(g&&g.match(b))return a}while(!f||a!=c);return this.getHighlightedIndex()},this.getHighlightedIndex())};
                +goog.ui.Menu.prototype.canHighlightItem=function(a){return(this.allowHighlightDisabled_||a.isEnabled())&&a.isVisible()&&a.isSupportedState(goog.ui.Component.State.HOVER)};goog.ui.Menu.prototype.decorateInternal=function(a){this.decorateContent(a);goog.ui.Menu.superClass_.decorateInternal.call(this,a)};
                +goog.ui.Menu.prototype.handleKeyEventInternal=function(a){var b=goog.ui.Menu.superClass_.handleKeyEventInternal.call(this,a);b||this.forEachChild(function(c){!b&&c.getMnemonic&&c.getMnemonic()==a.keyCode&&(this.isEnabled()&&this.setHighlighted(c),b=c.handleKeyEvent(a))},this);return b};goog.ui.Menu.prototype.setHighlightedIndex=function(a){goog.ui.Menu.superClass_.setHighlightedIndex.call(this,a);(a=this.getChildAt(a))&&goog.style.scrollIntoContainerView(a.getElement(),this.getElement())};
                +goog.ui.Menu.prototype.decorateContent=function(a){var b=this.getRenderer();a=this.getDomHelper().getElementsByTagNameAndClass("DIV",b.getCssClass()+"-content",a);for(var c=a.length,d=0;d<c;d++)b.decorateChildren(this,a[d])};goog.iter={};goog.iter.StopIteration="StopIteration"in goog.global?goog.global.StopIteration:{message:"StopIteration",stack:""};goog.iter.Iterator=function(){};goog.iter.Iterator.prototype.next=function(){throw goog.iter.StopIteration;};goog.iter.Iterator.prototype.__iterator__=function(a){return this};
                +goog.iter.toIterator=function(a){if(a instanceof goog.iter.Iterator)return a;if("function"==typeof a.__iterator__)return a.__iterator__(!1);if(goog.isArrayLike(a)){var b=0,c=new goog.iter.Iterator;c.next=function(){for(;;){if(b>=a.length)throw goog.iter.StopIteration;if(b in a)return a[b++];b++}};return c}throw Error("Not implemented");};
                +goog.iter.forEach=function(a,b,c){if(goog.isArrayLike(a))try{goog.array.forEach(a,b,c)}catch(d){if(d!==goog.iter.StopIteration)throw d;}else{a=goog.iter.toIterator(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(d){if(d!==goog.iter.StopIteration)throw d;}}};goog.iter.filter=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){for(;;){var a=d.next();if(b.call(c,a,void 0,d))return a}};return a};
                +goog.iter.filterFalse=function(a,b,c){return goog.iter.filter(a,goog.functions.not(b),c)};goog.iter.range=function(a,b,c){var d=0,e=a,f=c||1;1<arguments.length&&(d=a,e=b);if(0==f)throw Error("Range step argument must not be zero");var g=new goog.iter.Iterator;g.next=function(){if(0<f&&d>=e||0>f&&d<=e)throw goog.iter.StopIteration;var a=d;d+=f;return a};return g};goog.iter.join=function(a,b){return goog.iter.toArray(a).join(b)};
                +goog.iter.map=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=d.next();return b.call(c,a,void 0,d)};return a};goog.iter.reduce=function(a,b,c,d){var e=c;goog.iter.forEach(a,function(a){e=b.call(d,e,a)});return e};goog.iter.some=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(b.call(c,a.next(),void 0,a))return!0}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!1};
                +goog.iter.every=function(a,b,c){a=goog.iter.toIterator(a);try{for(;;)if(!b.call(c,a.next(),void 0,a))return!1}catch(d){if(d!==goog.iter.StopIteration)throw d;}return!0};goog.iter.chain=function(a){return goog.iter.chainFromIterable(arguments)};
                +goog.iter.chainFromIterable=function(a){var b=goog.iter.toIterator(a);a=new goog.iter.Iterator;var c=null;a.next=function(){for(;;){if(null==c){var a=b.next();c=goog.iter.toIterator(a)}try{return c.next()}catch(e){if(e!==goog.iter.StopIteration)throw e;c=null}}};return a};goog.iter.dropWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;var e=!0;a.next=function(){for(;;){var a=d.next();if(!e||!b.call(c,a,void 0,d))return e=!1,a}};return a};
                +goog.iter.takeWhile=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=d.next();if(b.call(c,a,void 0,d))return a;throw goog.iter.StopIteration;};return a};goog.iter.toArray=function(a){if(goog.isArrayLike(a))return goog.array.toArray(a);a=goog.iter.toIterator(a);var b=[];goog.iter.forEach(a,function(a){b.push(a)});return b};
                +goog.iter.equals=function(a,b,c){a=goog.iter.zipLongest({},a,b);var d=c||goog.array.defaultCompareEquality;return goog.iter.every(a,function(a){return d(a[0],a[1])})};goog.iter.nextOrValue=function(a,b){try{return goog.iter.toIterator(a).next()}catch(c){if(c!=goog.iter.StopIteration)throw c;return b}};
                +goog.iter.product=function(a){if(goog.array.some(arguments,function(a){return!a.length})||!arguments.length)return new goog.iter.Iterator;var b=new goog.iter.Iterator,c=arguments,d=goog.array.repeat(0,c.length);b.next=function(){if(d){for(var a=goog.array.map(d,function(a,b){return c[b][a]}),b=d.length-1;0<=b;b--){goog.asserts.assert(d);if(d[b]<c[b].length-1){d[b]++;break}if(0==b){d=null;break}d[b]=0}return a}throw goog.iter.StopIteration;};return b};
                +goog.iter.cycle=function(a){var b=goog.iter.toIterator(a),c=[],d=0;a=new goog.iter.Iterator;var e=!1;a.next=function(){var a=null;if(!e)try{return a=b.next(),c.push(a),a}catch(g){if(g!=goog.iter.StopIteration||goog.array.isEmpty(c))throw g;e=!0}a=c[d];d=(d+1)%c.length;return a};return a};goog.iter.count=function(a,b){var c=a||0,d=goog.isDef(b)?b:1,e=new goog.iter.Iterator;e.next=function(){var a=c;c+=d;return a};return e};
                +goog.iter.repeat=function(a){var b=new goog.iter.Iterator;b.next=goog.functions.constant(a);return b};goog.iter.accumulate=function(a){var b=goog.iter.toIterator(a),c=0;a=new goog.iter.Iterator;a.next=function(){return c+=b.next()};return a};goog.iter.zip=function(a){var b=arguments,c=new goog.iter.Iterator;if(0<b.length){var d=goog.array.map(b,goog.iter.toIterator);c.next=function(){return goog.array.map(d,function(a){return a.next()})}}return c};
                +goog.iter.zipLongest=function(a,b){var c=goog.array.slice(arguments,1),d=new goog.iter.Iterator;if(0<c.length){var e=goog.array.map(c,goog.iter.toIterator);d.next=function(){var b=!1,c=goog.array.map(e,function(c){try{var d=c.next();b=!0}catch(l){if(l!==goog.iter.StopIteration)throw l;d=a}return d});if(!b)throw goog.iter.StopIteration;return c}}return d};goog.iter.compress=function(a,b){var c=goog.iter.toIterator(b);return goog.iter.filter(a,function(){return!!c.next()})};
                +goog.iter.GroupByIterator_=function(a,b){this.iterator=goog.iter.toIterator(a);this.keyFunc=b||goog.functions.identity};goog.inherits(goog.iter.GroupByIterator_,goog.iter.Iterator);goog.iter.GroupByIterator_.prototype.next=function(){for(;this.currentKey==this.targetKey;)this.currentValue=this.iterator.next(),this.currentKey=this.keyFunc(this.currentValue);this.targetKey=this.currentKey;return[this.currentKey,this.groupItems_(this.targetKey)]};
                +goog.iter.GroupByIterator_.prototype.groupItems_=function(a){for(var b=[];this.currentKey==a;){b.push(this.currentValue);try{this.currentValue=this.iterator.next()}catch(c){if(c!==goog.iter.StopIteration)throw c;break}this.currentKey=this.keyFunc(this.currentValue)}return b};goog.iter.groupBy=function(a,b){return new goog.iter.GroupByIterator_(a,b)};
                +goog.iter.starMap=function(a,b,c){var d=goog.iter.toIterator(a);a=new goog.iter.Iterator;a.next=function(){var a=goog.iter.toArray(d.next());return b.apply(c,goog.array.concat(a,void 0,d))};return a};
                +goog.iter.tee=function(a,b){var c=goog.iter.toIterator(a),d=goog.isNumber(b)?b:2,e=goog.array.map(goog.array.range(d),function(){return[]}),f=function(){var a=c.next();goog.array.forEach(e,function(b){b.push(a)})};return goog.array.map(e,function(a){var b=new goog.iter.Iterator;b.next=function(){goog.array.isEmpty(a)&&f();goog.asserts.assert(!goog.array.isEmpty(a));return a.shift()};return b})};goog.iter.enumerate=function(a,b){return goog.iter.zip(goog.iter.count(b),a)};
                +goog.iter.limit=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);var c=goog.iter.toIterator(a),d=new goog.iter.Iterator,e=b;d.next=function(){if(0<e--)return c.next();throw goog.iter.StopIteration;};return d};goog.iter.consume=function(a,b){goog.asserts.assert(goog.math.isInt(b)&&0<=b);for(var c=goog.iter.toIterator(a);0<b--;)goog.iter.nextOrValue(c,null);return c};
                +goog.iter.slice=function(a,b,c){goog.asserts.assert(goog.math.isInt(b)&&0<=b);a=goog.iter.consume(a,b);goog.isNumber(c)&&(goog.asserts.assert(goog.math.isInt(c)&&c>=b),a=goog.iter.limit(a,c-b));return a};goog.iter.hasDuplicates_=function(a){var b=[];goog.array.removeDuplicates(a,b);return a.length!=b.length};goog.iter.permutations=function(a,b){var c=goog.iter.toArray(a),d=goog.isNumber(b)?b:c.length,c=goog.array.repeat(c,d),c=goog.iter.product.apply(void 0,c);return goog.iter.filter(c,function(a){return!goog.iter.hasDuplicates_(a)})};
                +goog.iter.combinations=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a),e=goog.iter.range(d.length),e=goog.iter.permutations(e,b),f=goog.iter.filter(e,function(a){return goog.array.isSorted(a)}),e=new goog.iter.Iterator;e.next=function(){return goog.array.map(f.next(),c)};return e};
                +goog.iter.combinationsWithReplacement=function(a,b){function c(a){return d[a]}var d=goog.iter.toArray(a),e=goog.array.range(d.length),e=goog.array.repeat(e,b),e=goog.iter.product.apply(void 0,e),f=goog.iter.filter(e,function(a){return goog.array.isSorted(a)}),e=new goog.iter.Iterator;e.next=function(){return goog.array.map(f.next(),c)};return e};goog.dom.TagWalkType={START_TAG:1,OTHER:0,END_TAG:-1};goog.dom.TagIterator=function(a,b,c,d,e){this.reversed=!!b;this.node=null;this.tagType=goog.dom.TagWalkType.OTHER;this.started_=!1;this.constrained=!c;a&&this.setPosition(a,d);this.depth=void 0!=e?e:this.tagType||0;this.reversed&&(this.depth*=-1)};goog.inherits(goog.dom.TagIterator,goog.iter.Iterator);
                +goog.dom.TagIterator.prototype.setPosition=function(a,b,c){if(this.node=a)goog.isNumber(b)?this.tagType=b:this.tagType=this.node.nodeType!=goog.dom.NodeType.ELEMENT?goog.dom.TagWalkType.OTHER:this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;goog.isNumber(c)&&(this.depth=c)};goog.dom.TagIterator.prototype.copyFrom=function(a){this.node=a.node;this.tagType=a.tagType;this.depth=a.depth;this.reversed=a.reversed;this.constrained=a.constrained};
                +goog.dom.TagIterator.prototype.clone=function(){return new goog.dom.TagIterator(this.node,this.reversed,!this.constrained,this.tagType,this.depth)};goog.dom.TagIterator.prototype.skipTag=function(){var a=this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;this.tagType==a&&(this.tagType=-1*a,this.depth+=this.tagType*(this.reversed?-1:1))};
                +goog.dom.TagIterator.prototype.restartTag=function(){var a=this.reversed?goog.dom.TagWalkType.START_TAG:goog.dom.TagWalkType.END_TAG;this.tagType==a&&(this.tagType=-1*a,this.depth+=this.tagType*(this.reversed?-1:1))};
                +goog.dom.TagIterator.prototype.next=function(){if(this.started_){if(!this.node||this.constrained&&0==this.depth)throw goog.iter.StopIteration;var a=this.node;var b=this.reversed?goog.dom.TagWalkType.END_TAG:goog.dom.TagWalkType.START_TAG;if(this.tagType==b){var c=this.reversed?a.lastChild:a.firstChild;c?this.setPosition(c):this.setPosition(a,-1*b)}else(c=this.reversed?a.previousSibling:a.nextSibling)?this.setPosition(c):this.setPosition(a.parentNode,-1*b);this.depth+=this.tagType*(this.reversed?-1:
                +1)}else this.started_=!0;a=this.node;if(!this.node)throw goog.iter.StopIteration;return a};goog.dom.TagIterator.prototype.isStarted=function(){return this.started_};goog.dom.TagIterator.prototype.isStartTag=function(){return this.tagType==goog.dom.TagWalkType.START_TAG};goog.dom.TagIterator.prototype.isEndTag=function(){return this.tagType==goog.dom.TagWalkType.END_TAG};goog.dom.TagIterator.prototype.isNonElement=function(){return this.tagType==goog.dom.TagWalkType.OTHER};
                +goog.dom.TagIterator.prototype.equals=function(a){return a.node==this.node&&(!this.node||a.tagType==this.tagType)};goog.dom.TagIterator.prototype.splice=function(a){var b=this.node;this.restartTag();this.reversed=!this.reversed;goog.dom.TagIterator.prototype.next.call(this);this.reversed=!this.reversed;for(var c=goog.isArrayLike(arguments[0])?arguments[0]:arguments,d=c.length-1;0<=d;d--)goog.dom.insertSiblingAfter(c[d],b);goog.dom.removeNode(b)};goog.dom.NodeIterator=function(a,b,c,d){goog.dom.TagIterator.call(this,a,b,c,null,d)};goog.inherits(goog.dom.NodeIterator,goog.dom.TagIterator);goog.dom.NodeIterator.prototype.next=function(){do goog.dom.NodeIterator.superClass_.next.call(this);while(this.isEndTag());return this.node};goog.ui.PaletteRenderer=function(){goog.ui.ControlRenderer.call(this)};goog.inherits(goog.ui.PaletteRenderer,goog.ui.ControlRenderer);goog.addSingletonGetter(goog.ui.PaletteRenderer);goog.ui.PaletteRenderer.cellId_=0;goog.ui.PaletteRenderer.CSS_CLASS="goog-palette";goog.ui.PaletteRenderer.prototype.createDom=function(a){var b=this.getClassNames(a);a=a.getDomHelper().createDom("DIV",b,this.createGrid(a.getContent(),a.getSize(),a.getDomHelper()));goog.a11y.aria.setRole(a,goog.a11y.aria.Role.GRID);return a};
                +goog.ui.PaletteRenderer.prototype.createGrid=function(a,b,c){for(var d=[],e=0,f=0;e<b.height;e++){for(var g=[],h=0;h<b.width;h++){var k=a&&a[f++];g.push(this.createCell(k,c))}d.push(this.createRow(g,c))}return this.createTable(d,c)};goog.ui.PaletteRenderer.prototype.createTable=function(a,b){var c=b.createDom("TABLE",this.getCssClass()+"-table",b.createDom("TBODY",this.getCssClass()+"-body",a));c.cellSpacing="0";c.cellPadding="0";return c};
                +goog.ui.PaletteRenderer.prototype.createRow=function(a,b){var c=b.createDom("TR",this.getCssClass()+"-row",a);goog.a11y.aria.setRole(c,goog.a11y.aria.Role.ROW);return c};
                +goog.ui.PaletteRenderer.prototype.createCell=function(a,b){var c=b.createDom("TD",{"class":this.getCssClass()+"-cell",id:this.getCssClass()+"-cell-"+goog.ui.PaletteRenderer.cellId_++},a);goog.a11y.aria.setRole(c,goog.a11y.aria.Role.GRIDCELL);goog.a11y.aria.setState(c,goog.a11y.aria.State.SELECTED,!1);if(!goog.dom.getTextContent(c)&&!goog.a11y.aria.getLabel(c)){var d=this.findAriaLabelForCell_(c);d&&goog.a11y.aria.setLabel(c,d)}return c};
                +goog.ui.PaletteRenderer.prototype.findAriaLabelForCell_=function(a){a=new goog.dom.NodeIterator(a);for(var b="",c;!b&&(c=goog.iter.nextOrValue(a,null));)c.nodeType==goog.dom.NodeType.ELEMENT&&(b=goog.a11y.aria.getLabel(c)||c.title);return b};goog.ui.PaletteRenderer.prototype.canDecorate=function(a){return!1};goog.ui.PaletteRenderer.prototype.decorate=function(a,b){return null};
                +goog.ui.PaletteRenderer.prototype.setContent=function(a,b){if(a){var c=goog.dom.getElementsByTagNameAndClass("TBODY",this.getCssClass()+"-body",a)[0];if(c){var d=0;goog.array.forEach(c.rows,function(a){goog.array.forEach(a.cells,function(a){goog.dom.removeChildren(a);if(b){var c=b[d++];c&&goog.dom.appendChild(a,c)}})});if(d<b.length){for(var e=[],f=goog.dom.getDomHelper(a),g=c.rows[0].cells.length;d<b.length;){var h=b[d++];e.push(this.createCell(h,f));e.length==g&&(h=this.createRow(e,f),goog.dom.appendChild(c,
                +h),e.length=0)}if(0<e.length){for(;e.length<g;)e.push(this.createCell("",f));h=this.createRow(e,f);goog.dom.appendChild(c,h)}}}goog.style.setUnselectable(a,!0,goog.userAgent.GECKO)}};goog.ui.PaletteRenderer.prototype.getContainingItem=function(a,b){for(var c=a.getElement();b&&b.nodeType==goog.dom.NodeType.ELEMENT&&b!=c;){if("TD"==b.tagName&&goog.dom.classlist.contains(b,this.getCssClass()+"-cell"))return b.firstChild;b=b.parentNode}return null};
                +goog.ui.PaletteRenderer.prototype.highlightCell=function(a,b,c){b&&(b=this.getCellForItem(b),goog.asserts.assert(b),goog.dom.classlist.enable(b,this.getCssClass()+"-cell-hover",c),c?goog.a11y.aria.setState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT,b.id):b.id==goog.a11y.aria.getState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT)&&goog.a11y.aria.removeState(a.getElementStrict(),goog.a11y.aria.State.ACTIVEDESCENDANT))};
                +goog.ui.PaletteRenderer.prototype.getCellForItem=function(a){return a?a.parentNode:null};goog.ui.PaletteRenderer.prototype.selectCell=function(a,b,c){b&&(a=b.parentNode,goog.dom.classlist.enable(a,this.getCssClass()+"-cell-selected",c),goog.a11y.aria.setState(a,goog.a11y.aria.State.SELECTED,c))};goog.ui.PaletteRenderer.prototype.getCssClass=function(){return goog.ui.PaletteRenderer.CSS_CLASS};goog.ui.SelectionModel=function(a){goog.events.EventTarget.call(this);this.items_=[];this.addItems(a)};goog.inherits(goog.ui.SelectionModel,goog.events.EventTarget);goog.tagUnsealableClass(goog.ui.SelectionModel);goog.ui.SelectionModel.prototype.selectedItem_=null;goog.ui.SelectionModel.prototype.selectionHandler_=null;goog.ui.SelectionModel.prototype.getSelectionHandler=function(){return this.selectionHandler_};
                +goog.ui.SelectionModel.prototype.setSelectionHandler=function(a){this.selectionHandler_=a};goog.ui.SelectionModel.prototype.getItemCount=function(){return this.items_.length};goog.ui.SelectionModel.prototype.indexOfItem=function(a){return a?goog.array.indexOf(this.items_,a):-1};goog.ui.SelectionModel.prototype.getFirst=function(){return this.items_[0]};goog.ui.SelectionModel.prototype.getLast=function(){return this.items_[this.items_.length-1]};
                +goog.ui.SelectionModel.prototype.getItemAt=function(a){return this.items_[a]||null};goog.ui.SelectionModel.prototype.addItems=function(a){a&&(goog.array.forEach(a,function(a){this.selectItem_(a,!1)},this),goog.array.extend(this.items_,a))};goog.ui.SelectionModel.prototype.addItem=function(a){this.addItemAt(a,this.getItemCount())};goog.ui.SelectionModel.prototype.addItemAt=function(a,b){a&&(this.selectItem_(a,!1),goog.array.insertAt(this.items_,a,b))};
                +goog.ui.SelectionModel.prototype.removeItem=function(a){a&&goog.array.remove(this.items_,a)&&a==this.selectedItem_&&(this.selectedItem_=null,this.dispatchEvent(goog.events.EventType.SELECT))};goog.ui.SelectionModel.prototype.removeItemAt=function(a){this.removeItem(this.getItemAt(a))};goog.ui.SelectionModel.prototype.getSelectedItem=function(){return this.selectedItem_};goog.ui.SelectionModel.prototype.getItems=function(){return goog.array.clone(this.items_)};
                +goog.ui.SelectionModel.prototype.setSelectedItem=function(a){a!=this.selectedItem_&&(this.selectItem_(this.selectedItem_,!1),this.selectedItem_=a,this.selectItem_(a,!0));this.dispatchEvent(goog.events.EventType.SELECT)};goog.ui.SelectionModel.prototype.getSelectedIndex=function(){return this.indexOfItem(this.selectedItem_)};goog.ui.SelectionModel.prototype.setSelectedIndex=function(a){this.setSelectedItem(this.getItemAt(a))};
                +goog.ui.SelectionModel.prototype.clear=function(){goog.array.clear(this.items_);this.selectedItem_=null};goog.ui.SelectionModel.prototype.disposeInternal=function(){goog.ui.SelectionModel.superClass_.disposeInternal.call(this);delete this.items_;this.selectedItem_=null};goog.ui.SelectionModel.prototype.selectItem_=function(a,b){a&&("function"==typeof this.selectionHandler_?this.selectionHandler_(a,b):"function"==typeof a.setSelected&&a.setSelected(b))};goog.ui.Palette=function(a,b,c){goog.ui.Control.call(this,a,b||goog.ui.PaletteRenderer.getInstance(),c);this.setAutoStates(goog.ui.Component.State.CHECKED|goog.ui.Component.State.SELECTED|goog.ui.Component.State.OPENED,!1);this.currentCellControl_=new goog.ui.Palette.CurrentCell_;this.currentCellControl_.setParentEventTarget(this);this.lastHighlightedIndex_=-1};goog.inherits(goog.ui.Palette,goog.ui.Control);goog.tagUnsealableClass(goog.ui.Palette);goog.ui.Palette.EventType={AFTER_HIGHLIGHT:goog.events.getUniqueId("afterhighlight")};
                +goog.ui.Palette.prototype.size_=null;goog.ui.Palette.prototype.highlightedIndex_=-1;goog.ui.Palette.prototype.selectionModel_=null;goog.ui.Palette.prototype.disposeInternal=function(){goog.ui.Palette.superClass_.disposeInternal.call(this);this.selectionModel_&&(this.selectionModel_.dispose(),this.selectionModel_=null);this.size_=null;this.currentCellControl_.dispose()};
                +goog.ui.Palette.prototype.setContentInternal=function(a){goog.ui.Palette.superClass_.setContentInternal.call(this,a);this.adjustSize_();this.selectionModel_?(this.selectionModel_.clear(),this.selectionModel_.addItems(a)):(this.selectionModel_=new goog.ui.SelectionModel(a),this.selectionModel_.setSelectionHandler(goog.bind(this.selectItem_,this)),this.getHandler().listen(this.selectionModel_,goog.events.EventType.SELECT,this.handleSelectionChange));this.highlightedIndex_=-1};
                +goog.ui.Palette.prototype.getCaption=function(){return""};goog.ui.Palette.prototype.setCaption=function(a){};goog.ui.Palette.prototype.handleMouseOver=function(a){goog.ui.Palette.superClass_.handleMouseOver.call(this,a);var b=this.getRenderer().getContainingItem(this,a.target);b&&a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)||b!=this.getHighlightedItem()&&this.setHighlightedItem(b)};
                +goog.ui.Palette.prototype.handleMouseDown=function(a){goog.ui.Palette.superClass_.handleMouseDown.call(this,a);this.isActive()&&(a=this.getRenderer().getContainingItem(this,a.target),a!=this.getHighlightedItem()&&this.setHighlightedItem(a))};goog.ui.Palette.prototype.performActionInternal=function(a){var b=this.getHighlightedItem();return b?(a&&this.shouldSelectHighlightedItem_(a)&&this.setSelectedItem(b),goog.ui.Palette.superClass_.performActionInternal.call(this,a)):!1};
                +goog.ui.Palette.prototype.shouldSelectHighlightedItem_=function(a){return this.getSelectedItem()?"mouseup"!=a.type?!0:!!this.getRenderer().getContainingItem(this,a.target):!0};
                +goog.ui.Palette.prototype.handleKeyEvent=function(a){var b=this.getContent(),b=b?b.length:0,c=this.size_.width;if(0==b||!this.isEnabled())return!1;if(a.keyCode==goog.events.KeyCodes.ENTER||a.keyCode==goog.events.KeyCodes.SPACE)return this.performActionInternal(a);if(a.keyCode==goog.events.KeyCodes.HOME)return this.setHighlightedIndex(0),!0;if(a.keyCode==goog.events.KeyCodes.END)return this.setHighlightedIndex(b-1),!0;var d=0>this.highlightedIndex_?this.getSelectedIndex():this.highlightedIndex_;switch(a.keyCode){case goog.events.KeyCodes.LEFT:if(-1==
                +d||0==d)d=b;this.setHighlightedIndex(d-1);a.preventDefault();return!0;case goog.events.KeyCodes.RIGHT:return d==b-1&&(d=-1),this.setHighlightedIndex(d+1),a.preventDefault(),!0;case goog.events.KeyCodes.UP:-1==d&&(d=b+c-1);if(d>=c)return this.setHighlightedIndex(d-c),a.preventDefault(),!0;break;case goog.events.KeyCodes.DOWN:if(-1==d&&(d=-c),d<b-c)return this.setHighlightedIndex(d+c),a.preventDefault(),!0}return!1};goog.ui.Palette.prototype.handleSelectionChange=function(a){};
                +goog.ui.Palette.prototype.getSize=function(){return this.size_};goog.ui.Palette.prototype.setSize=function(a,b){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.size_=goog.isNumber(a)?new goog.math.Size(a,b):a;this.adjustSize_()};goog.ui.Palette.prototype.getHighlightedIndex=function(){return this.highlightedIndex_};goog.ui.Palette.prototype.getHighlightedItem=function(){var a=this.getContent();return a&&a[this.highlightedIndex_]};
                +goog.ui.Palette.prototype.getHighlightedCellElement_=function(){return this.getRenderer().getCellForItem(this.getHighlightedItem())};goog.ui.Palette.prototype.setHighlightedIndex=function(a){a!=this.highlightedIndex_&&(this.highlightIndex_(this.highlightedIndex_,!1),this.lastHighlightedIndex_=this.highlightedIndex_,this.highlightedIndex_=a,this.highlightIndex_(a,!0),this.dispatchEvent(goog.ui.Palette.EventType.AFTER_HIGHLIGHT))};
                +goog.ui.Palette.prototype.setHighlightedItem=function(a){var b=this.getContent();this.setHighlightedIndex(b&&a?goog.array.indexOf(b,a):-1)};goog.ui.Palette.prototype.getSelectedIndex=function(){return this.selectionModel_?this.selectionModel_.getSelectedIndex():-1};goog.ui.Palette.prototype.getSelectedItem=function(){return this.selectionModel_?this.selectionModel_.getSelectedItem():null};goog.ui.Palette.prototype.setSelectedIndex=function(a){this.selectionModel_&&this.selectionModel_.setSelectedIndex(a)};
                +goog.ui.Palette.prototype.setSelectedItem=function(a){this.selectionModel_&&this.selectionModel_.setSelectedItem(a)};goog.ui.Palette.prototype.highlightIndex_=function(a,b){if(this.getElement()){var c=this.getContent();if(c&&0<=a&&a<c.length){var d=this.getHighlightedCellElement_();this.currentCellControl_.getElement()!=d&&this.currentCellControl_.setElementInternal(d);this.currentCellControl_.tryHighlight(b)&&this.getRenderer().highlightCell(this,c[a],b)}}};
                +goog.ui.Palette.prototype.setHighlighted=function(a){a&&-1==this.highlightedIndex_?this.setHighlightedIndex(-1<this.lastHighlightedIndex_?this.lastHighlightedIndex_:0):a||this.setHighlightedIndex(-1);goog.ui.Palette.superClass_.setHighlighted.call(this,a)};goog.ui.Palette.prototype.selectItem_=function(a,b){this.getElement()&&this.getRenderer().selectCell(this,a,b)};
                +goog.ui.Palette.prototype.adjustSize_=function(){var a=this.getContent();if(a)if(this.size_&&this.size_.width){if(a=Math.ceil(a.length/this.size_.width),!goog.isNumber(this.size_.height)||this.size_.height<a)this.size_.height=a}else a=Math.ceil(Math.sqrt(a.length)),this.size_=new goog.math.Size(a,a);else this.size_=new goog.math.Size(0,0)};goog.ui.Palette.CurrentCell_=function(){goog.ui.Control.call(this,null);this.setDispatchTransitionEvents(goog.ui.Component.State.HOVER,!0)};
                +goog.inherits(goog.ui.Palette.CurrentCell_,goog.ui.Control);goog.ui.Palette.CurrentCell_.prototype.tryHighlight=function(a){this.setHighlighted(a);return this.isHighlighted()==a};goog.ui.ColorPalette=function(a,b,c){this.colors_=a||[];goog.ui.Palette.call(this,null,b||goog.ui.PaletteRenderer.getInstance(),c);this.setColors(this.colors_)};goog.inherits(goog.ui.ColorPalette,goog.ui.Palette);goog.tagUnsealableClass(goog.ui.ColorPalette);goog.ui.ColorPalette.prototype.normalizedColors_=null;goog.ui.ColorPalette.prototype.labels_=null;goog.ui.ColorPalette.prototype.getColors=function(){return this.colors_};
                +goog.ui.ColorPalette.prototype.setColors=function(a,b){this.colors_=a;this.labels_=b||null;this.normalizedColors_=null;this.setContent(this.createColorNodes())};goog.ui.ColorPalette.prototype.getSelectedColor=function(){var a=this.getSelectedItem();return a?(a=goog.style.getStyle(a,"background-color"),goog.ui.ColorPalette.parseColor_(a)):null};
                +goog.ui.ColorPalette.prototype.setSelectedColor=function(a){a=goog.ui.ColorPalette.parseColor_(a);this.normalizedColors_||(this.normalizedColors_=goog.array.map(this.colors_,function(a){return goog.ui.ColorPalette.parseColor_(a)}));this.setSelectedIndex(a?goog.array.indexOf(this.normalizedColors_,a):-1)};
                +goog.ui.ColorPalette.prototype.createColorNodes=function(){return goog.array.map(this.colors_,function(a,b){var c=this.getDomHelper().createDom("DIV",{"class":this.getRenderer().getCssClass()+"-colorswatch",style:"background-color:"+a});c.title=this.labels_&&this.labels_[b]?this.labels_[b]:"#"==a.charAt(0)?"RGB ("+goog.color.hexToRgb(a).join(", ")+")":a;return c},this)};goog.ui.ColorPalette.parseColor_=function(a){if(a)try{return goog.color.parse(a).hex}catch(b){}return null};goog.ui.ColorPicker=function(a,b){goog.ui.Component.call(this,a);this.colorPalette_=b||null;this.getHandler().listen(this,goog.ui.Component.EventType.ACTION,this.onColorPaletteAction_)};goog.inherits(goog.ui.ColorPicker,goog.ui.Component);goog.ui.ColorPicker.DEFAULT_NUM_COLS=5;goog.ui.ColorPicker.EventType={CHANGE:"change"};goog.ui.ColorPicker.prototype.focusable_=!0;goog.ui.ColorPicker.prototype.getColors=function(){return this.colorPalette_?this.colorPalette_.getColors():null};
                +goog.ui.ColorPicker.prototype.setColors=function(a){this.colorPalette_?this.colorPalette_.setColors(a):this.createColorPalette_(a)};goog.ui.ColorPicker.prototype.addColors=function(a){this.setColors(a)};goog.ui.ColorPicker.prototype.setSize=function(a){this.colorPalette_||this.createColorPalette_([]);this.colorPalette_.setSize(a)};goog.ui.ColorPicker.prototype.getSize=function(){return this.colorPalette_?this.colorPalette_.getSize():null};goog.ui.ColorPicker.prototype.setColumnCount=function(a){this.setSize(a)};
                +goog.ui.ColorPicker.prototype.getSelectedIndex=function(){return this.colorPalette_?this.colorPalette_.getSelectedIndex():-1};goog.ui.ColorPicker.prototype.setSelectedIndex=function(a){this.colorPalette_&&this.colorPalette_.setSelectedIndex(a)};goog.ui.ColorPicker.prototype.getSelectedColor=function(){return this.colorPalette_?this.colorPalette_.getSelectedColor():null};goog.ui.ColorPicker.prototype.setSelectedColor=function(a){this.colorPalette_&&this.colorPalette_.setSelectedColor(a)};
                +goog.ui.ColorPicker.prototype.isFocusable=function(){return this.focusable_};goog.ui.ColorPicker.prototype.setFocusable=function(a){this.focusable_=a;this.colorPalette_&&this.colorPalette_.setSupportedState(goog.ui.Component.State.FOCUSED,a)};goog.ui.ColorPicker.prototype.canDecorate=function(a){return!1};
                +goog.ui.ColorPicker.prototype.enterDocument=function(){goog.ui.ColorPicker.superClass_.enterDocument.call(this);this.colorPalette_&&this.colorPalette_.render(this.getElement());this.getElement().unselectable="on"};goog.ui.ColorPicker.prototype.disposeInternal=function(){goog.ui.ColorPicker.superClass_.disposeInternal.call(this);this.colorPalette_&&(this.colorPalette_.dispose(),this.colorPalette_=null)};goog.ui.ColorPicker.prototype.focus=function(){this.colorPalette_&&this.colorPalette_.getElement().focus()};
                +goog.ui.ColorPicker.prototype.onColorPaletteAction_=function(a){a.stopPropagation();this.dispatchEvent(goog.ui.ColorPicker.EventType.CHANGE)};goog.ui.ColorPicker.prototype.createColorPalette_=function(a){a=new goog.ui.ColorPalette(a,null,this.getDomHelper());a.setSize(goog.ui.ColorPicker.DEFAULT_NUM_COLS);a.setSupportedState(goog.ui.Component.State.FOCUSED,this.focusable_);this.addChild(a);this.colorPalette_=a;this.isInDocument()&&this.colorPalette_.render(this.getElement())};
                +goog.ui.ColorPicker.createSimpleColorGrid=function(a){a=new goog.ui.ColorPicker(a);a.setSize(7);a.setColors(goog.ui.ColorPicker.SIMPLE_GRID_COLORS);return a};goog.ui.ColorPicker.SIMPLE_GRID_COLORS="#ffffff #cccccc #c0c0c0 #999999 #666666 #333333 #000000 #ffcccc #ff6666 #ff0000 #cc0000 #990000 #660000 #330000 #ffcc99 #ff9966 #ff9900 #ff6600 #cc6600 #993300 #663300 #ffff99 #ffff66 #ffcc66 #ffcc33 #cc9933 #996633 #663333 #ffffcc #ffff33 #ffff00 #ffcc00 #999900 #666600 #333300 #99ff99 #66ff99 #33ff33 #33cc00 #009900 #006600 #003300 #99ffff #33ffff #66cccc #00cccc #339999 #336666 #003333 #ccffff #66ffff #33ccff #3366ff #3333ff #000099 #000066 #ccccff #9999ff #6666cc #6633ff #6600cc #333399 #330099 #ffccff #ff99ff #cc66cc #cc33cc #993399 #663366 #330033".split(" ");goog.events.FocusHandler=function(a){goog.events.EventTarget.call(this);this.element_=a;a=goog.userAgent.IE?"focusout":"blur";this.listenKeyIn_=goog.events.listen(this.element_,goog.userAgent.IE?"focusin":"focus",this,!goog.userAgent.IE);this.listenKeyOut_=goog.events.listen(this.element_,a,this,!goog.userAgent.IE)};goog.inherits(goog.events.FocusHandler,goog.events.EventTarget);goog.events.FocusHandler.EventType={FOCUSIN:"focusin",FOCUSOUT:"focusout"};
                +goog.events.FocusHandler.prototype.handleEvent=function(a){var b=a.getBrowserEvent(),b=new goog.events.BrowserEvent(b);b.type="focusin"==a.type||"focus"==a.type?goog.events.FocusHandler.EventType.FOCUSIN:goog.events.FocusHandler.EventType.FOCUSOUT;this.dispatchEvent(b)};goog.events.FocusHandler.prototype.disposeInternal=function(){goog.events.FocusHandler.superClass_.disposeInternal.call(this);goog.events.unlistenByKey(this.listenKeyIn_);goog.events.unlistenByKey(this.listenKeyOut_);delete this.element_};goog.debug.LOGGING_ENABLED=goog.DEBUG;goog.debug.FORCE_SLOPPY_STACKS=!1;goog.debug.catchErrors=function(a,b,c){c=c||goog.global;var d=c.onerror,e=!!b;goog.userAgent.WEBKIT&&!goog.userAgent.isVersionOrHigher("535.3")&&(e=!e);c.onerror=function(b,c,h,k,l){d&&d(b,c,h,k,l);a({message:b,fileName:c,line:h,col:k,error:l});return e}};
                +goog.debug.expose=function(a,b){if("undefined"==typeof a)return"undefined";if(null==a)return"NULL";var c=[],d;for(d in a)if(b||!goog.isFunction(a[d])){var e=d+" = ";try{e+=a[d]}catch(f){e+="*** "+f+" ***"}c.push(e)}return c.join("\n")};
                +goog.debug.deepExpose=function(a,b){var c=[],d=[],e={},f=function(a,g){var h=g+"  ";try{if(goog.isDef(a))if(goog.isNull(a))c.push("NULL");else if(goog.isString(a))c.push('"'+a.replace(/\n/g,"\n"+g)+'"');else if(goog.isFunction(a))c.push(String(a).replace(/\n/g,"\n"+g));else if(goog.isObject(a)){goog.hasUid(a)||d.push(a);var k=goog.getUid(a);if(e[k])c.push("*** reference loop detected (id="+k+") ***");else{e[k]=!0;c.push("{");for(var n in a)if(b||!goog.isFunction(a[n]))c.push("\n"),c.push(h),c.push(n+
                +" = "),f(a[n],h);c.push("\n"+g+"}");delete e[k]}}else c.push(a);else c.push("undefined")}catch(p){c.push("*** "+p+" ***")}};f(a,"");for(var g=0;g<d.length;g++)goog.removeUid(d[g]);return c.join("")};goog.debug.exposeArray=function(a){for(var b=[],c=0;c<a.length;c++)goog.isArray(a[c])?b.push(goog.debug.exposeArray(a[c])):b.push(a[c]);return"[ "+b.join(", ")+" ]"};
                +goog.debug.normalizeErrorObject=function(a){var b=goog.getObjectByName("window.location.href");if(goog.isString(a))return{message:a,name:"Unknown error",lineNumber:"Not available",fileName:b,stack:"Not available"};var c=!1;try{var d=a.lineNumber||a.line||"Not available"}catch(f){d="Not available",c=!0}try{var e=a.fileName||a.filename||a.sourceURL||goog.global.$googDebugFname||b}catch(f){e="Not available",c=!0}return!c&&a.lineNumber&&a.fileName&&a.stack&&a.message&&a.name?a:{message:a.message||"Not available",
                +name:a.name||"UnknownError",lineNumber:d,fileName:e,stack:a.stack||"Not available"}};goog.debug.enhanceError=function(a,b){if(a instanceof Error)var c=a;else c=Error(a),Error.captureStackTrace&&Error.captureStackTrace(c,goog.debug.enhanceError);c.stack||(c.stack=goog.debug.getStacktrace(goog.debug.enhanceError));if(b){for(var d=0;c["message"+d];)++d;c["message"+d]=String(b)}return c};
                +goog.debug.getStacktraceSimple=function(a){if(!goog.debug.FORCE_SLOPPY_STACKS){var b=goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple);if(b)return b}for(var b=[],c=arguments.callee.caller,d=0;c&&(!a||d<a);){b.push(goog.debug.getFunctionName(c));b.push("()\n");try{c=c.caller}catch(e){b.push("[exception trying to get caller]\n");break}d++;if(d>=goog.debug.MAX_STACK_DEPTH){b.push("[...long stack...]");break}}a&&d>=a?b.push("[...reached max depth limit...]"):b.push("[end]");return b.join("")};
                +goog.debug.MAX_STACK_DEPTH=50;goog.debug.getNativeStackTrace_=function(a){var b=Error();if(Error.captureStackTrace)return Error.captureStackTrace(b,a),String(b.stack);try{throw b;}catch(c){b=c}return(a=b.stack)?String(a):null};goog.debug.getStacktrace=function(a){var b;goog.debug.FORCE_SLOPPY_STACKS||(b=goog.debug.getNativeStackTrace_(a||goog.debug.getStacktrace));b||(b=goog.debug.getStacktraceHelper_(a||arguments.callee.caller,[]));return b};
                +goog.debug.getStacktraceHelper_=function(a,b){var c=[];if(goog.array.contains(b,a))c.push("[...circular reference...]");else if(a&&b.length<goog.debug.MAX_STACK_DEPTH){c.push(goog.debug.getFunctionName(a)+"(");for(var d=a.arguments,e=0;d&&e<d.length;e++){0<e&&c.push(", ");var f=d[e];switch(typeof f){case "object":f=f?"object":"null";break;case "string":break;case "number":f=String(f);break;case "boolean":f=f?"true":"false";break;case "function":f=(f=goog.debug.getFunctionName(f))?f:"[fn]";break;default:f=
                +typeof f}40<f.length&&(f=f.substr(0,40)+"...");c.push(f)}b.push(a);c.push(")\n");try{c.push(goog.debug.getStacktraceHelper_(a.caller,b))}catch(g){c.push("[exception trying to get caller]\n")}}else a?c.push("[...long stack...]"):c.push("[end]");return c.join("")};goog.debug.setFunctionResolver=function(a){goog.debug.fnNameResolver_=a};
                +goog.debug.getFunctionName=function(a){if(goog.debug.fnNameCache_[a])return goog.debug.fnNameCache_[a];if(goog.debug.fnNameResolver_){var b=goog.debug.fnNameResolver_(a);if(b)return goog.debug.fnNameCache_[a]=b}a=String(a);goog.debug.fnNameCache_[a]||(b=/function ([^\(]+)/.exec(a),goog.debug.fnNameCache_[a]=b?b[1]:"[Anonymous]");return goog.debug.fnNameCache_[a]};
                +goog.debug.makeWhitespaceVisible=function(a){return a.replace(/ /g,"[_]").replace(/\f/g,"[f]").replace(/\n/g,"[n]\n").replace(/\r/g,"[r]").replace(/\t/g,"[t]")};goog.debug.runtimeType=function(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};goog.debug.fnNameCache_={};goog.debug.LogRecord=function(a,b,c,d,e){this.reset(a,b,c,d,e)};goog.debug.LogRecord.prototype.sequenceNumber_=0;goog.debug.LogRecord.prototype.exception_=null;goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS=!0;goog.debug.LogRecord.nextSequenceNumber_=0;
                +goog.debug.LogRecord.prototype.reset=function(a,b,c,d,e){goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS&&(this.sequenceNumber_="number"==typeof e?e:goog.debug.LogRecord.nextSequenceNumber_++);this.time_=d||goog.now();this.level_=a;this.msg_=b;this.loggerName_=c;delete this.exception_};goog.debug.LogRecord.prototype.getLoggerName=function(){return this.loggerName_};goog.debug.LogRecord.prototype.getException=function(){return this.exception_};
                +goog.debug.LogRecord.prototype.setException=function(a){this.exception_=a};goog.debug.LogRecord.prototype.setLoggerName=function(a){this.loggerName_=a};goog.debug.LogRecord.prototype.getLevel=function(){return this.level_};goog.debug.LogRecord.prototype.setLevel=function(a){this.level_=a};goog.debug.LogRecord.prototype.getMessage=function(){return this.msg_};goog.debug.LogRecord.prototype.setMessage=function(a){this.msg_=a};goog.debug.LogRecord.prototype.getMillis=function(){return this.time_};
                +goog.debug.LogRecord.prototype.setMillis=function(a){this.time_=a};goog.debug.LogRecord.prototype.getSequenceNumber=function(){return this.sequenceNumber_};goog.debug.LogBuffer=function(){goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(),"Cannot use goog.debug.LogBuffer without defining goog.debug.LogBuffer.CAPACITY.");this.clear()};goog.debug.LogBuffer.getInstance=function(){goog.debug.LogBuffer.instance_||(goog.debug.LogBuffer.instance_=new goog.debug.LogBuffer);return goog.debug.LogBuffer.instance_};goog.debug.LogBuffer.CAPACITY=0;
                +goog.debug.LogBuffer.prototype.addRecord=function(a,b,c){var d=(this.curIndex_+1)%goog.debug.LogBuffer.CAPACITY;this.curIndex_=d;if(this.isFull_)return d=this.buffer_[d],d.reset(a,b,c),d;this.isFull_=d==goog.debug.LogBuffer.CAPACITY-1;return this.buffer_[d]=new goog.debug.LogRecord(a,b,c)};goog.debug.LogBuffer.isBufferingEnabled=function(){return 0<goog.debug.LogBuffer.CAPACITY};
                +goog.debug.LogBuffer.prototype.clear=function(){this.buffer_=Array(goog.debug.LogBuffer.CAPACITY);this.curIndex_=-1;this.isFull_=!1};goog.debug.LogBuffer.prototype.forEachRecord=function(a){var b=this.buffer_;if(b[0]){var c=this.curIndex_,d=this.isFull_?c:-1;do d=(d+1)%goog.debug.LogBuffer.CAPACITY,a(b[d]);while(d!=c)}};goog.debug.Logger=function(a){this.name_=a;this.handlers_=this.children_=this.level_=this.parent_=null};goog.debug.Logger.ROOT_LOGGER_NAME="";goog.debug.Logger.ENABLE_HIERARCHY=!0;goog.debug.Logger.ENABLE_HIERARCHY||(goog.debug.Logger.rootHandlers_=[]);goog.debug.Logger.Level=function(a,b){this.name=a;this.value=b};goog.debug.Logger.Level.prototype.toString=function(){return this.name};goog.debug.Logger.Level.OFF=new goog.debug.Logger.Level("OFF",Infinity);
                +goog.debug.Logger.Level.SHOUT=new goog.debug.Logger.Level("SHOUT",1200);goog.debug.Logger.Level.SEVERE=new goog.debug.Logger.Level("SEVERE",1E3);goog.debug.Logger.Level.WARNING=new goog.debug.Logger.Level("WARNING",900);goog.debug.Logger.Level.INFO=new goog.debug.Logger.Level("INFO",800);goog.debug.Logger.Level.CONFIG=new goog.debug.Logger.Level("CONFIG",700);goog.debug.Logger.Level.FINE=new goog.debug.Logger.Level("FINE",500);goog.debug.Logger.Level.FINER=new goog.debug.Logger.Level("FINER",400);
                +goog.debug.Logger.Level.FINEST=new goog.debug.Logger.Level("FINEST",300);goog.debug.Logger.Level.ALL=new goog.debug.Logger.Level("ALL",0);goog.debug.Logger.Level.PREDEFINED_LEVELS=[goog.debug.Logger.Level.OFF,goog.debug.Logger.Level.SHOUT,goog.debug.Logger.Level.SEVERE,goog.debug.Logger.Level.WARNING,goog.debug.Logger.Level.INFO,goog.debug.Logger.Level.CONFIG,goog.debug.Logger.Level.FINE,goog.debug.Logger.Level.FINER,goog.debug.Logger.Level.FINEST,goog.debug.Logger.Level.ALL];
                +goog.debug.Logger.Level.predefinedLevelsCache_=null;goog.debug.Logger.Level.createPredefinedLevelsCache_=function(){goog.debug.Logger.Level.predefinedLevelsCache_={};for(var a=0,b;b=goog.debug.Logger.Level.PREDEFINED_LEVELS[a];a++)goog.debug.Logger.Level.predefinedLevelsCache_[b.value]=b,goog.debug.Logger.Level.predefinedLevelsCache_[b.name]=b};
                +goog.debug.Logger.Level.getPredefinedLevel=function(a){goog.debug.Logger.Level.predefinedLevelsCache_||goog.debug.Logger.Level.createPredefinedLevelsCache_();return goog.debug.Logger.Level.predefinedLevelsCache_[a]||null};
                +goog.debug.Logger.Level.getPredefinedLevelByValue=function(a){goog.debug.Logger.Level.predefinedLevelsCache_||goog.debug.Logger.Level.createPredefinedLevelsCache_();if(a in goog.debug.Logger.Level.predefinedLevelsCache_)return goog.debug.Logger.Level.predefinedLevelsCache_[a];for(var b=0;b<goog.debug.Logger.Level.PREDEFINED_LEVELS.length;++b){var c=goog.debug.Logger.Level.PREDEFINED_LEVELS[b];if(c.value<=a)return c}return null};goog.debug.Logger.getLogger=function(a){return goog.debug.LogManager.getLogger(a)};
                +goog.debug.Logger.logToProfilers=function(a){goog.global.console&&(goog.global.console.timeStamp?goog.global.console.timeStamp(a):goog.global.console.markTimeline&&goog.global.console.markTimeline(a));goog.global.msWriteProfilerMark&&goog.global.msWriteProfilerMark(a)};goog.debug.Logger.prototype.getName=function(){return this.name_};
                +goog.debug.Logger.prototype.addHandler=function(a){goog.debug.LOGGING_ENABLED&&(goog.debug.Logger.ENABLE_HIERARCHY?(this.handlers_||(this.handlers_=[]),this.handlers_.push(a)):(goog.asserts.assert(!this.name_,"Cannot call addHandler on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."),goog.debug.Logger.rootHandlers_.push(a)))};
                +goog.debug.Logger.prototype.removeHandler=function(a){if(goog.debug.LOGGING_ENABLED){var b=goog.debug.Logger.ENABLE_HIERARCHY?this.handlers_:goog.debug.Logger.rootHandlers_;return!!b&&goog.array.remove(b,a)}return!1};goog.debug.Logger.prototype.getParent=function(){return this.parent_};goog.debug.Logger.prototype.getChildren=function(){this.children_||(this.children_={});return this.children_};
                +goog.debug.Logger.prototype.setLevel=function(a){goog.debug.LOGGING_ENABLED&&(goog.debug.Logger.ENABLE_HIERARCHY?this.level_=a:(goog.asserts.assert(!this.name_,"Cannot call setLevel() on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."),goog.debug.Logger.rootLevel_=a))};goog.debug.Logger.prototype.getLevel=function(){return goog.debug.LOGGING_ENABLED?this.level_:goog.debug.Logger.Level.OFF};
                +goog.debug.Logger.prototype.getEffectiveLevel=function(){if(!goog.debug.LOGGING_ENABLED)return goog.debug.Logger.Level.OFF;if(!goog.debug.Logger.ENABLE_HIERARCHY)return goog.debug.Logger.rootLevel_;if(this.level_)return this.level_;if(this.parent_)return this.parent_.getEffectiveLevel();goog.asserts.fail("Root logger has no level set.");return null};goog.debug.Logger.prototype.isLoggable=function(a){return goog.debug.LOGGING_ENABLED&&a.value>=this.getEffectiveLevel().value};
                +goog.debug.Logger.prototype.log=function(a,b,c){goog.debug.LOGGING_ENABLED&&this.isLoggable(a)&&(goog.isFunction(b)&&(b=b()),this.doLogRecord_(this.getLogRecord(a,b,c)))};goog.debug.Logger.prototype.getLogRecord=function(a,b,c){a=goog.debug.LogBuffer.isBufferingEnabled()?goog.debug.LogBuffer.getInstance().addRecord(a,b,this.name_):new goog.debug.LogRecord(a,String(b),this.name_);c&&a.setException(c);return a};
                +goog.debug.Logger.prototype.shout=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.SHOUT,a,b)};goog.debug.Logger.prototype.severe=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.SEVERE,a,b)};goog.debug.Logger.prototype.warning=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.WARNING,a,b)};goog.debug.Logger.prototype.info=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.INFO,a,b)};
                +goog.debug.Logger.prototype.config=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.CONFIG,a,b)};goog.debug.Logger.prototype.fine=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINE,a,b)};goog.debug.Logger.prototype.finer=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINER,a,b)};goog.debug.Logger.prototype.finest=function(a,b){goog.debug.LOGGING_ENABLED&&this.log(goog.debug.Logger.Level.FINEST,a,b)};
                +goog.debug.Logger.prototype.logRecord=function(a){goog.debug.LOGGING_ENABLED&&this.isLoggable(a.getLevel())&&this.doLogRecord_(a)};goog.debug.Logger.prototype.doLogRecord_=function(a){goog.debug.Logger.logToProfilers("log:"+a.getMessage());if(goog.debug.Logger.ENABLE_HIERARCHY)for(var b=this;b;)b.callPublish_(a),b=b.getParent();else for(var b=0,c;c=goog.debug.Logger.rootHandlers_[b++];)c(a)};goog.debug.Logger.prototype.callPublish_=function(a){if(this.handlers_)for(var b=0,c;c=this.handlers_[b];b++)c(a)};
                +goog.debug.Logger.prototype.setParent_=function(a){this.parent_=a};goog.debug.Logger.prototype.addChild_=function(a,b){this.getChildren()[a]=b};goog.debug.LogManager={};goog.debug.LogManager.loggers_={};goog.debug.LogManager.rootLogger_=null;
                +goog.debug.LogManager.initialize=function(){goog.debug.LogManager.rootLogger_||(goog.debug.LogManager.rootLogger_=new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME),goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME]=goog.debug.LogManager.rootLogger_,goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG))};goog.debug.LogManager.getLoggers=function(){return goog.debug.LogManager.loggers_};
                +goog.debug.LogManager.getRoot=function(){goog.debug.LogManager.initialize();return goog.debug.LogManager.rootLogger_};goog.debug.LogManager.getLogger=function(a){goog.debug.LogManager.initialize();return goog.debug.LogManager.loggers_[a]||goog.debug.LogManager.createLogger_(a)};goog.debug.LogManager.createFunctionForCatchErrors=function(a){return function(b){(a||goog.debug.LogManager.getRoot()).severe("Error: "+b.message+" ("+b.fileName+" @ Line: "+b.line+")")}};
                +goog.debug.LogManager.createLogger_=function(a){var b=new goog.debug.Logger(a);if(goog.debug.Logger.ENABLE_HIERARCHY){var c=a.lastIndexOf("."),d=a.substr(0,c),c=a.substr(c+1),d=goog.debug.LogManager.getLogger(d);d.addChild_(c,b);b.setParent_(d)}return goog.debug.LogManager.loggers_[a]=b};goog.log={};goog.log.ENABLED=goog.debug.LOGGING_ENABLED;goog.log.ROOT_LOGGER_NAME=goog.debug.Logger.ROOT_LOGGER_NAME;goog.log.Logger=goog.debug.Logger;goog.log.Level=goog.debug.Logger.Level;goog.log.LogRecord=goog.debug.LogRecord;goog.log.getLogger=function(a,b){if(goog.log.ENABLED){var c=goog.debug.LogManager.getLogger(a);b&&c&&c.setLevel(b);return c}return null};goog.log.addHandler=function(a,b){goog.log.ENABLED&&a&&a.addHandler(b)};
                +goog.log.removeHandler=function(a,b){return goog.log.ENABLED&&a?a.removeHandler(b):!1};goog.log.log=function(a,b,c,d){goog.log.ENABLED&&a&&a.log(b,c,d)};goog.log.error=function(a,b,c){goog.log.ENABLED&&a&&a.severe(b,c)};goog.log.warning=function(a,b,c){goog.log.ENABLED&&a&&a.warning(b,c)};goog.log.info=function(a,b,c){goog.log.ENABLED&&a&&a.info(b,c)};goog.log.fine=function(a,b,c){goog.log.ENABLED&&a&&a.fine(b,c)};goog.string.StringBuffer=function(a,b){null!=a&&this.append.apply(this,arguments)};goog.string.StringBuffer.prototype.buffer_="";goog.string.StringBuffer.prototype.set=function(a){this.buffer_=""+a};goog.string.StringBuffer.prototype.append=function(a,b,c){this.buffer_+=String(a);if(null!=b)for(var d=1;d<arguments.length;d++)this.buffer_+=arguments[d];return this};goog.string.StringBuffer.prototype.clear=function(){this.buffer_=""};goog.string.StringBuffer.prototype.getLength=function(){return this.buffer_.length};
                +goog.string.StringBuffer.prototype.toString=function(){return this.buffer_};goog.ui.tree={};goog.ui.tree.BaseNode=function(a,b,c){goog.ui.Component.call(this,c);this.config_=b||goog.ui.tree.BaseNode.defaultConfig;this.html_=goog.html.SafeHtml.htmlEscapePreservingNewlines(a);this.expanded_=this.selected_=!1;this.toolTip_=null;this.afterLabelHtml_=goog.html.SafeHtml.EMPTY;this.isUserCollapsible_=!0;this.depth_=-1};goog.inherits(goog.ui.tree.BaseNode,goog.ui.Component);
                +goog.ui.tree.BaseNode.EventType={BEFORE_EXPAND:"beforeexpand",EXPAND:"expand",BEFORE_COLLAPSE:"beforecollapse",COLLAPSE:"collapse"};goog.ui.tree.BaseNode.allNodes={};goog.ui.tree.BaseNode.prototype.disposeInternal=function(){goog.ui.tree.BaseNode.superClass_.disposeInternal.call(this);this.tree&&(this.tree.removeNode(this),this.tree=null);this.setElementInternal(null)};
                +goog.ui.tree.BaseNode.prototype.initAccessibility=function(){var a=this.getElement();if(a){var b=this.getLabelElement();b&&!b.id&&(b.id=this.getId()+".label");goog.a11y.aria.setRole(a,"treeitem");goog.a11y.aria.setState(a,"selected",!1);goog.a11y.aria.setState(a,"level",this.getDepth());b&&goog.a11y.aria.setState(a,"labelledby",b.id);(b=this.getIconElement())&&goog.a11y.aria.setRole(b,"presentation");(b=this.getExpandIconElement())&&goog.a11y.aria.setRole(b,"presentation");if(b=this.getChildrenElement())if(goog.a11y.aria.setRole(b,
                +"group"),b.hasChildNodes())for(goog.a11y.aria.setState(a,goog.a11y.aria.State.EXPANDED,!1),a=this.getChildCount(),b=1;b<=a;b++){var c=this.getChildAt(b-1).getElement();goog.asserts.assert(c,"The child element cannot be null");goog.a11y.aria.setState(c,"setsize",a);goog.a11y.aria.setState(c,"posinset",b)}}};goog.ui.tree.BaseNode.prototype.createDom=function(){var a=this.getDomHelper().safeHtmlToNode(this.toSafeHtml());this.setElementInternal(a)};
                +goog.ui.tree.BaseNode.prototype.enterDocument=function(){goog.ui.tree.BaseNode.superClass_.enterDocument.call(this);goog.ui.tree.BaseNode.allNodes[this.getId()]=this;this.initAccessibility()};goog.ui.tree.BaseNode.prototype.exitDocument=function(){goog.ui.tree.BaseNode.superClass_.exitDocument.call(this);delete goog.ui.tree.BaseNode.allNodes[this.getId()]};
                +goog.ui.tree.BaseNode.prototype.addChildAt=function(a,b,c){goog.asserts.assert(!a.getParent());goog.asserts.assertInstanceof(a,goog.ui.tree.BaseNode);c=this.getChildAt(b-1);var d=this.getChildAt(b);goog.ui.tree.BaseNode.superClass_.addChildAt.call(this,a,b);a.previousSibling_=c;a.nextSibling_=d;c?c.nextSibling_=a:this.firstChild_=a;d?d.previousSibling_=a:this.lastChild_=a;(b=this.getTree())&&a.setTreeInternal(b);a.setDepth_(this.getDepth()+1);if(b=this.getElement())if(this.updateExpandIcon(),goog.a11y.aria.setState(b,
                +goog.a11y.aria.State.EXPANDED,this.getExpanded()),this.getExpanded()){b=this.getChildrenElement();a.getElement()||a.createDom();var e=a.getElement(),f=d&&d.getElement();b.insertBefore(e,f);this.isInDocument()&&a.enterDocument();d||(c?c.updateExpandIcon():(goog.style.setElementShown(b,!0),this.setExpanded(this.getExpanded())))}};
                +goog.ui.tree.BaseNode.prototype.add=function(a,b){goog.asserts.assert(!b||b.getParent()==this,"Can only add nodes before siblings");a.getParent()&&a.getParent().removeChild(a);this.addChildAt(a,b?this.indexOfChild(b):this.getChildCount());return a};
                +goog.ui.tree.BaseNode.prototype.removeChild=function(a,b){var c=this.getTree(),d=c?c.getSelectedItem():null;if(d==a||a.contains(d))c.hasFocus()?(this.select(),goog.Timer.callOnce(this.onTimeoutSelect_,10,this)):this.select();goog.ui.tree.BaseNode.superClass_.removeChild.call(this,a);this.lastChild_==a&&(this.lastChild_=a.previousSibling_);this.firstChild_==a&&(this.firstChild_=a.nextSibling_);a.previousSibling_&&(a.previousSibling_.nextSibling_=a.nextSibling_);a.nextSibling_&&(a.nextSibling_.previousSibling_=
                +a.previousSibling_);d=a.isLastSibling();a.tree=null;a.depth_=-1;if(c&&(c.removeNode(a),this.isInDocument())){c=this.getChildrenElement();if(a.isInDocument()){var e=a.getElement();c.removeChild(e);a.exitDocument()}d&&(d=this.getLastChild())&&d.updateExpandIcon();this.hasChildren()||(c.style.display="none",this.updateExpandIcon(),this.updateIcon_(),(d=this.getElement())&&goog.a11y.aria.removeState(d,goog.a11y.aria.State.EXPANDED))}return a};goog.ui.tree.BaseNode.prototype.remove=goog.ui.tree.BaseNode.prototype.removeChild;
                +goog.ui.tree.BaseNode.prototype.onTimeoutSelect_=function(){this.select()};goog.ui.tree.BaseNode.prototype.getTree=goog.abstractMethod;goog.ui.tree.BaseNode.prototype.getDepth=function(){var a=this.depth_;0>a&&(a=this.computeDepth_(),this.setDepth_(a));return a};goog.ui.tree.BaseNode.prototype.computeDepth_=function(){var a=this.getParent();return a?a.getDepth()+1:0};
                +goog.ui.tree.BaseNode.prototype.setDepth_=function(a){if(a!=this.depth_){this.depth_=a;var b=this.getRowElement();if(b){var c=this.getPixelIndent_()+"px";this.isRightToLeft()?b.style.paddingRight=c:b.style.paddingLeft=c}this.forEachChild(function(b){b.setDepth_(a+1)})}};goog.ui.tree.BaseNode.prototype.contains=function(a){for(;a;){if(a==this)return!0;a=a.getParent()}return!1};goog.ui.tree.BaseNode.EMPTY_CHILDREN_=[];
                +goog.ui.tree.BaseNode.prototype.getChildren=function(){var a=[];this.forEachChild(function(b){a.push(b)});return a};goog.ui.tree.BaseNode.prototype.getFirstChild=function(){return this.getChildAt(0)};goog.ui.tree.BaseNode.prototype.getLastChild=function(){return this.getChildAt(this.getChildCount()-1)};goog.ui.tree.BaseNode.prototype.getPreviousSibling=function(){return this.previousSibling_};goog.ui.tree.BaseNode.prototype.getNextSibling=function(){return this.nextSibling_};
                +goog.ui.tree.BaseNode.prototype.isLastSibling=function(){return!this.nextSibling_};goog.ui.tree.BaseNode.prototype.isSelected=function(){return this.selected_};goog.ui.tree.BaseNode.prototype.select=function(){var a=this.getTree();a&&a.setSelectedItem(this)};goog.ui.tree.BaseNode.prototype.deselect=goog.nullFunction;
                +goog.ui.tree.BaseNode.prototype.setSelectedInternal=function(a){if(this.selected_!=a){this.selected_=a;this.updateRow();var b=this.getElement();b&&(goog.a11y.aria.setState(b,"selected",a),a&&(a=this.getTree().getElement(),goog.asserts.assert(a,"The DOM element for the tree cannot be null"),goog.a11y.aria.setState(a,"activedescendant",this.getId())))}};goog.ui.tree.BaseNode.prototype.getExpanded=function(){return this.expanded_};
                +goog.ui.tree.BaseNode.prototype.setExpandedInternal=function(a){this.expanded_=a};
                +goog.ui.tree.BaseNode.prototype.setExpanded=function(a){var b=a!=this.expanded_;if(!b||this.dispatchEvent(a?goog.ui.tree.BaseNode.EventType.BEFORE_EXPAND:goog.ui.tree.BaseNode.EventType.BEFORE_COLLAPSE)){this.expanded_=a;var c=this.getTree();var d=this.getElement();if(this.hasChildren()){if(!a&&c&&this.contains(c.getSelectedItem())&&this.select(),d){if(c=this.getChildrenElement())if(goog.style.setElementShown(c,a),goog.a11y.aria.setState(d,goog.a11y.aria.State.EXPANDED,a),a&&this.isInDocument()&&
                +!c.hasChildNodes()){var e=[];this.forEachChild(function(a){e.push(a.toSafeHtml())});goog.dom.safe.setInnerHtml(c,goog.html.SafeHtml.concat(e));this.forEachChild(function(a){a.enterDocument()})}this.updateExpandIcon()}}else(c=this.getChildrenElement())&&goog.style.setElementShown(c,!1);d&&this.updateIcon_();b&&this.dispatchEvent(a?goog.ui.tree.BaseNode.EventType.EXPAND:goog.ui.tree.BaseNode.EventType.COLLAPSE)}};goog.ui.tree.BaseNode.prototype.toggle=function(){this.setExpanded(!this.getExpanded())};
                +goog.ui.tree.BaseNode.prototype.expand=function(){this.setExpanded(!0)};goog.ui.tree.BaseNode.prototype.collapse=function(){this.setExpanded(!1)};goog.ui.tree.BaseNode.prototype.collapseChildren=function(){this.forEachChild(function(a){a.collapseAll()})};goog.ui.tree.BaseNode.prototype.collapseAll=function(){this.collapseChildren();this.collapse()};goog.ui.tree.BaseNode.prototype.expandChildren=function(){this.forEachChild(function(a){a.expandAll()})};
                +goog.ui.tree.BaseNode.prototype.expandAll=function(){this.expandChildren();this.expand()};goog.ui.tree.BaseNode.prototype.reveal=function(){var a=this.getParent();a&&(a.setExpanded(!0),a.reveal())};goog.ui.tree.BaseNode.prototype.setIsUserCollapsible=function(a){(this.isUserCollapsible_=a)||this.expand();this.getElement()&&this.updateExpandIcon()};goog.ui.tree.BaseNode.prototype.isUserCollapsible=function(){return this.isUserCollapsible_};
                +goog.ui.tree.BaseNode.prototype.toSafeHtml=function(){var a=this.getTree(),b=!a.getShowLines()||a==this.getParent()&&!a.getShowRootLines()?this.config_.cssChildrenNoLines:this.config_.cssChildren,a=this.getExpanded()&&this.hasChildren(),b={"class":b,style:this.getLineStyle()},c=[];a&&this.forEachChild(function(a){c.push(a.toSafeHtml())});a=goog.html.SafeHtml.create("div",b,c);return goog.html.SafeHtml.create("div",{"class":this.config_.cssItem,id:this.getId()},[this.getRowSafeHtml(),a])};
                +goog.ui.tree.BaseNode.prototype.getPixelIndent_=function(){return Math.max(0,(this.getDepth()-1)*this.config_.indentWidth)};goog.ui.tree.BaseNode.prototype.getRowSafeHtml=function(){var a={};a["padding-"+(this.isRightToLeft()?"right":"left")]=this.getPixelIndent_()+"px";var a={"class":this.getRowClassName(),style:a},b=[this.getExpandIconSafeHtml(),this.getIconSafeHtml(),this.getLabelSafeHtml()];return goog.html.SafeHtml.create("div",a,b)};
                +goog.ui.tree.BaseNode.prototype.getRowClassName=function(){var a=this.isSelected()?" "+this.config_.cssSelectedRow:"";return this.config_.cssTreeRow+a};goog.ui.tree.BaseNode.prototype.getLabelSafeHtml=function(){var a=goog.html.SafeHtml.create("span",{"class":this.config_.cssItemLabel,title:this.getToolTip()||null},this.getSafeHtml());return goog.html.SafeHtml.concat(a,goog.html.SafeHtml.create("span",{},this.getAfterLabelSafeHtml()))};goog.ui.tree.BaseNode.prototype.getAfterLabelHtml=function(){return goog.html.SafeHtml.unwrap(this.getAfterLabelSafeHtml())};
                +goog.ui.tree.BaseNode.prototype.getAfterLabelSafeHtml=function(){return this.afterLabelHtml_};goog.ui.tree.BaseNode.prototype.setAfterLabelSafeHtml=function(a){this.afterLabelHtml_=a;var b=this.getAfterLabelElement();b&&goog.dom.safe.setInnerHtml(b,a)};goog.ui.tree.BaseNode.prototype.getIconSafeHtml=function(){return goog.html.SafeHtml.create("span",{style:{display:"inline-block"},"class":this.getCalculatedIconClass()})};goog.ui.tree.BaseNode.prototype.getCalculatedIconClass=goog.abstractMethod;
                +goog.ui.tree.BaseNode.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.create("span",{type:"expand",style:{display:"inline-block"},"class":this.getExpandIconClass()})};
                +goog.ui.tree.BaseNode.prototype.getExpandIconClass=function(){var a=this.getTree(),b=!a.getShowLines()||a==this.getParent()&&!a.getShowRootLines(),c=this.config_,d=new goog.string.StringBuffer;d.append(c.cssTreeIcon," ",c.cssExpandTreeIcon," ");if(this.hasChildren()){var e=0;a.getShowExpandIcons()&&this.isUserCollapsible_&&(e=this.getExpanded()?2:1);b||(e=this.isLastSibling()?e+4:e+8);switch(e){case 1:d.append(c.cssExpandTreeIconPlus);break;case 2:d.append(c.cssExpandTreeIconMinus);break;case 4:d.append(c.cssExpandTreeIconL);
                +break;case 5:d.append(c.cssExpandTreeIconLPlus);break;case 6:d.append(c.cssExpandTreeIconLMinus);break;case 8:d.append(c.cssExpandTreeIconT);break;case 9:d.append(c.cssExpandTreeIconTPlus);break;case 10:d.append(c.cssExpandTreeIconTMinus);break;default:d.append(c.cssExpandTreeIconBlank)}}else b?d.append(c.cssExpandTreeIconBlank):this.isLastSibling()?d.append(c.cssExpandTreeIconL):d.append(c.cssExpandTreeIconT);return d.toString()};
                +goog.ui.tree.BaseNode.prototype.getLineStyle=function(){var a=this.getExpanded()&&this.hasChildren();return goog.html.SafeStyle.create({"background-position":this.getBackgroundPosition(),display:a?null:"none"})};goog.ui.tree.BaseNode.prototype.getBackgroundPosition=function(){return(this.isLastSibling()?"-100":(this.getDepth()-1)*this.config_.indentWidth)+"px 0"};
                +goog.ui.tree.BaseNode.prototype.getElement=function(){var a=goog.ui.tree.BaseNode.superClass_.getElement.call(this);a||(a=this.getDomHelper().getElement(this.getId()),this.setElementInternal(a));return a};goog.ui.tree.BaseNode.prototype.getRowElement=function(){var a=this.getElement();return a?a.firstChild:null};goog.ui.tree.BaseNode.prototype.getExpandIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};
                +goog.ui.tree.BaseNode.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.childNodes[1]:null};goog.ui.tree.BaseNode.prototype.getLabelElement=function(){var a=this.getRowElement();return a&&a.lastChild?a.lastChild.previousSibling:null};goog.ui.tree.BaseNode.prototype.getAfterLabelElement=function(){var a=this.getRowElement();return a?a.lastChild:null};goog.ui.tree.BaseNode.prototype.getChildrenElement=function(){var a=this.getElement();return a?a.lastChild:null};
                +goog.ui.tree.BaseNode.prototype.setIconClass=function(a){this.iconClass_=a;this.isInDocument()&&this.updateIcon_()};goog.ui.tree.BaseNode.prototype.getIconClass=function(){return this.iconClass_};goog.ui.tree.BaseNode.prototype.setExpandedIconClass=function(a){this.expandedIconClass_=a;this.isInDocument()&&this.updateIcon_()};goog.ui.tree.BaseNode.prototype.getExpandedIconClass=function(){return this.expandedIconClass_};goog.ui.tree.BaseNode.prototype.setText=function(a){this.setSafeHtml(goog.html.SafeHtml.htmlEscape(a))};
                +goog.ui.tree.BaseNode.prototype.getText=function(){return goog.string.unescapeEntities(goog.html.SafeHtml.unwrap(this.html_))};goog.ui.tree.BaseNode.prototype.setSafeHtml=function(a){this.html_=a;var b=this.getLabelElement();b&&goog.dom.safe.setInnerHtml(b,a);(a=this.getTree())&&a.setNode(this)};goog.ui.tree.BaseNode.prototype.getHtml=function(){return goog.html.SafeHtml.unwrap(this.getSafeHtml())};goog.ui.tree.BaseNode.prototype.getSafeHtml=function(){return this.html_};
                +goog.ui.tree.BaseNode.prototype.setToolTip=function(a){this.toolTip_=a;var b=this.getLabelElement();b&&(b.title=a)};goog.ui.tree.BaseNode.prototype.getToolTip=function(){return this.toolTip_};goog.ui.tree.BaseNode.prototype.updateRow=function(){var a=this.getRowElement();a&&(a.className=this.getRowClassName())};
                +goog.ui.tree.BaseNode.prototype.updateExpandIcon=function(){var a=this.getExpandIconElement();a&&(a.className=this.getExpandIconClass());if(a=this.getChildrenElement())a.style.backgroundPosition=this.getBackgroundPosition()};goog.ui.tree.BaseNode.prototype.updateIcon_=function(){this.getIconElement().className=this.getCalculatedIconClass()};
                +goog.ui.tree.BaseNode.prototype.onMouseDown=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()?this.isUserCollapsible_&&this.toggle():(this.select(),this.updateRow())};goog.ui.tree.BaseNode.prototype.onClick_=goog.events.Event.preventDefault;goog.ui.tree.BaseNode.prototype.onDoubleClick_=function(a){"expand"==a.target.getAttribute("type")&&this.hasChildren()||this.isUserCollapsible_&&this.toggle()};
                +goog.ui.tree.BaseNode.prototype.onKeyDown=function(a){var b=!0;switch(a.keyCode){case goog.events.KeyCodes.RIGHT:if(a.altKey)break;this.hasChildren()&&(this.getExpanded()?this.getFirstChild().select():this.setExpanded(!0));break;case goog.events.KeyCodes.LEFT:if(a.altKey)break;if(this.hasChildren()&&this.getExpanded()&&this.isUserCollapsible_)this.setExpanded(!1);else{var c=this.getParent();var d=this.getTree();c&&(d.getShowRootNode()||c!=d)&&c.select()}break;case goog.events.KeyCodes.DOWN:(d=this.getNextShownNode())&&
                +d.select();break;case goog.events.KeyCodes.UP:(d=this.getPreviousShownNode())&&d.select();break;default:b=!1}b&&(a.preventDefault(),(d=this.getTree())&&d.clearTypeAhead());return b};goog.ui.tree.BaseNode.prototype.getLastShownDescendant=function(){return this.getExpanded()&&this.hasChildren()?this.getLastChild().getLastShownDescendant():this};
                +goog.ui.tree.BaseNode.prototype.getNextShownNode=function(){if(this.hasChildren()&&this.getExpanded())return this.getFirstChild();for(var a=this,b;a!=this.getTree();){b=a.getNextSibling();if(null!=b)return b;a=a.getParent()}return null};goog.ui.tree.BaseNode.prototype.getPreviousShownNode=function(){var a=this.getPreviousSibling();if(null!=a)return a.getLastShownDescendant();var a=this.getParent(),b=this.getTree();return!b.getShowRootNode()&&a==b||this==b?null:a};
                +goog.ui.tree.BaseNode.prototype.getClientData=goog.ui.tree.BaseNode.prototype.getModel;goog.ui.tree.BaseNode.prototype.setClientData=goog.ui.tree.BaseNode.prototype.setModel;goog.ui.tree.BaseNode.prototype.getConfig=function(){return this.config_};goog.ui.tree.BaseNode.prototype.setTreeInternal=function(a){this.tree!=a&&(this.tree=a,a.setNode(this),this.forEachChild(function(b){b.setTreeInternal(a)}))};
                +goog.ui.tree.BaseNode.defaultConfig={indentWidth:19,cssRoot:"goog-tree-root goog-tree-item",cssHideRoot:"goog-tree-hide-root",cssItem:"goog-tree-item",cssChildren:"goog-tree-children",cssChildrenNoLines:"goog-tree-children-nolines",cssTreeRow:"goog-tree-row",cssItemLabel:"goog-tree-item-label",cssTreeIcon:"goog-tree-icon",cssExpandTreeIcon:"goog-tree-expand-icon",cssExpandTreeIconPlus:"goog-tree-expand-icon-plus",cssExpandTreeIconMinus:"goog-tree-expand-icon-minus",cssExpandTreeIconTPlus:"goog-tree-expand-icon-tplus",
                +cssExpandTreeIconTMinus:"goog-tree-expand-icon-tminus",cssExpandTreeIconLPlus:"goog-tree-expand-icon-lplus",cssExpandTreeIconLMinus:"goog-tree-expand-icon-lminus",cssExpandTreeIconT:"goog-tree-expand-icon-t",cssExpandTreeIconL:"goog-tree-expand-icon-l",cssExpandTreeIconBlank:"goog-tree-expand-icon-blank",cssExpandedFolderIcon:"goog-tree-expanded-folder-icon",cssCollapsedFolderIcon:"goog-tree-collapsed-folder-icon",cssFileIcon:"goog-tree-file-icon",cssExpandedRootIcon:"goog-tree-expanded-folder-icon",
                +cssCollapsedRootIcon:"goog-tree-collapsed-folder-icon",cssSelectedRow:"selected"};goog.ui.tree.TreeNode=function(a,b,c){goog.ui.tree.BaseNode.call(this,a,b,c)};goog.inherits(goog.ui.tree.TreeNode,goog.ui.tree.BaseNode);goog.ui.tree.TreeNode.prototype.getTree=function(){if(this.tree)return this.tree;var a=this.getParent();return a&&(a=a.getTree())?(this.setTreeInternal(a),a):null};
                +goog.ui.tree.TreeNode.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();if(this.hasChildren()){if(a&&b.cssExpandedFolderIcon)return b.cssTreeIcon+" "+b.cssExpandedFolderIcon;if(!a&&b.cssCollapsedFolderIcon)return b.cssTreeIcon+" "+b.cssCollapsedFolderIcon}else if(b.cssFileIcon)return b.cssTreeIcon+" "+b.cssFileIcon;return""};goog.structs={};goog.structs.getCount=function(a){return a.getCount&&"function"==typeof a.getCount?a.getCount():goog.isArrayLike(a)||goog.isString(a)?a.length:goog.object.getCount(a)};goog.structs.getValues=function(a){if(a.getValues&&"function"==typeof a.getValues)return a.getValues();if(goog.isString(a))return a.split("");if(goog.isArrayLike(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return goog.object.getValues(a)};
                +goog.structs.getKeys=function(a){if(a.getKeys&&"function"==typeof a.getKeys)return a.getKeys();if(!a.getValues||"function"!=typeof a.getValues){if(goog.isArrayLike(a)||goog.isString(a)){var b=[];a=a.length;for(var c=0;c<a;c++)b.push(c);return b}return goog.object.getKeys(a)}};
                +goog.structs.contains=function(a,b){return a.contains&&"function"==typeof a.contains?a.contains(b):a.containsValue&&"function"==typeof a.containsValue?a.containsValue(b):goog.isArrayLike(a)||goog.isString(a)?goog.array.contains(a,b):goog.object.containsValue(a,b)};goog.structs.isEmpty=function(a){return a.isEmpty&&"function"==typeof a.isEmpty?a.isEmpty():goog.isArrayLike(a)||goog.isString(a)?goog.array.isEmpty(a):goog.object.isEmpty(a)};
                +goog.structs.clear=function(a){a.clear&&"function"==typeof a.clear?a.clear():goog.isArrayLike(a)?goog.array.clear(a):goog.object.clear(a)};goog.structs.forEach=function(a,b,c){if(a.forEach&&"function"==typeof a.forEach)a.forEach(b,c);else if(goog.isArrayLike(a)||goog.isString(a))goog.array.forEach(a,b,c);else for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)b.call(c,e[g],d&&d[g],a)};
                +goog.structs.filter=function(a,b,c){if("function"==typeof a.filter)return a.filter(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.filter(a,b,c);var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length;if(d){var g={};for(var h=0;h<f;h++)b.call(c,e[h],d[h],a)&&(g[d[h]]=e[h])}else for(g=[],h=0;h<f;h++)b.call(c,e[h],void 0,a)&&g.push(e[h]);return g};
                +goog.structs.map=function(a,b,c){if("function"==typeof a.map)return a.map(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.map(a,b,c);var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length;if(d){var g={};for(var h=0;h<f;h++)g[d[h]]=b.call(c,e[h],d[h],a)}else for(g=[],h=0;h<f;h++)g[h]=b.call(c,e[h],void 0,a);return g};
                +goog.structs.some=function(a,b,c){if("function"==typeof a.some)return a.some(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.some(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(b.call(c,e[g],d&&d[g],a))return!0;return!1};
                +goog.structs.every=function(a,b,c){if("function"==typeof a.every)return a.every(b,c);if(goog.isArrayLike(a)||goog.isString(a))return goog.array.every(a,b,c);for(var d=goog.structs.getKeys(a),e=goog.structs.getValues(a),f=e.length,g=0;g<f;g++)if(!b.call(c,e[g],d&&d[g],a))return!1;return!0};goog.structs.Trie=function(a){this.value_=void 0;this.childNodes_={};a&&this.setAll(a)};goog.structs.Trie.prototype.set=function(a,b){this.setOrAdd_(a,b,!1)};goog.structs.Trie.prototype.add=function(a,b){this.setOrAdd_(a,b,!0)};
                +goog.structs.Trie.prototype.setOrAdd_=function(a,b,c){for(var d=this,e=0;e<a.length;e++){var f=a.charAt(e);d.childNodes_[f]||(d.childNodes_[f]=new goog.structs.Trie);d=d.childNodes_[f]}if(c&&void 0!==d.value_)throw Error('The collection already contains the key "'+a+'"');d.value_=b};goog.structs.Trie.prototype.setAll=function(a){var b=goog.structs.getKeys(a);a=goog.structs.getValues(a);for(var c=0;c<b.length;c++)this.set(b[c],a[c])};
                +goog.structs.Trie.prototype.getChildNode_=function(a){for(var b=this,c=0;c<a.length;c++){var d=a.charAt(c),b=b.childNodes_[d];if(!b)return}return b};goog.structs.Trie.prototype.get=function(a){return(a=this.getChildNode_(a))?a.value_:void 0};goog.structs.Trie.prototype.getKeyAndPrefixes=function(a,b){var c=this,d={},e=b||0;void 0!==c.value_&&(d[e]=c.value_);for(;e<a.length;e++){var f=a.charAt(e);if(!(f in c.childNodes_))break;c=c.childNodes_[f];void 0!==c.value_&&(d[e]=c.value_)}return d};
                +goog.structs.Trie.prototype.getValues=function(){var a=[];this.getValuesInternal_(a);return a};goog.structs.Trie.prototype.getValuesInternal_=function(a){void 0!==this.value_&&a.push(this.value_);for(var b in this.childNodes_)this.childNodes_[b].getValuesInternal_(a)};goog.structs.Trie.prototype.getKeys=function(a){var b=[];if(a){for(var c=this,d=0;d<a.length;d++){var e=a.charAt(d);if(!c.childNodes_[e])return[];c=c.childNodes_[e]}c.getKeysInternal_(a,b)}else this.getKeysInternal_("",b);return b};
                +goog.structs.Trie.prototype.getKeysInternal_=function(a,b){void 0!==this.value_&&b.push(a);for(var c in this.childNodes_)this.childNodes_[c].getKeysInternal_(a+c,b)};goog.structs.Trie.prototype.containsKey=function(a){return void 0!==this.get(a)};goog.structs.Trie.prototype.containsPrefix=function(a){return 0==a.length?!this.isEmpty():!!this.getChildNode_(a)};
                +goog.structs.Trie.prototype.containsValue=function(a){if(this.value_===a)return!0;for(var b in this.childNodes_)if(this.childNodes_[b].containsValue(a))return!0;return!1};goog.structs.Trie.prototype.clear=function(){this.childNodes_={};this.value_=void 0};
                +goog.structs.Trie.prototype.remove=function(a){for(var b,c=this,d=[],e=0;e<a.length;e++){b=a.charAt(e);if(!c.childNodes_[b])throw Error('The collection does not have the key "'+a+'"');d.push([c,b]);c=c.childNodes_[b]}a=c.value_;for(delete c.value_;0<d.length;)if(b=d.pop(),c=b[0],b=b[1],c.childNodes_[b].isEmpty())delete c.childNodes_[b];else break;return a};goog.structs.Trie.prototype.clone=function(){return new goog.structs.Trie(this)};goog.structs.Trie.prototype.getCount=function(){return goog.structs.getCount(this.getValues())};
                +goog.structs.Trie.prototype.isEmpty=function(){return void 0===this.value_&&goog.object.isEmpty(this.childNodes_)};goog.ui.tree.TypeAhead=function(){this.nodeMap_=new goog.structs.Trie;this.buffer_="";this.matchingNodes_=this.matchingLabels_=null;this.matchingNodeIndex_=this.matchingLabelIndex_=0};goog.ui.tree.TypeAhead.Offset={DOWN:1,UP:-1};
                +goog.ui.tree.TypeAhead.prototype.handleNavigation=function(a){var b=!1;switch(a.keyCode){case goog.events.KeyCodes.DOWN:case goog.events.KeyCodes.UP:a.ctrlKey&&(this.jumpTo_(a.keyCode==goog.events.KeyCodes.DOWN?goog.ui.tree.TypeAhead.Offset.DOWN:goog.ui.tree.TypeAhead.Offset.UP),b=!0);break;case goog.events.KeyCodes.BACKSPACE:a=this.buffer_.length-1;b=!0;0<a?(this.buffer_=this.buffer_.substring(0,a),this.jumpToLabel_(this.buffer_)):0==a?this.buffer_="":b=!1;break;case goog.events.KeyCodes.ESC:this.buffer_=
                +"",b=!0}return b};goog.ui.tree.TypeAhead.prototype.handleTypeAheadChar=function(a){var b=!1;a.ctrlKey||a.altKey||(a=String.fromCharCode(a.charCode||a.keyCode).toLowerCase(),goog.string.isUnicodeChar(a)&&(" "!=a||this.buffer_)&&(this.buffer_+=a,b=this.jumpToLabel_(this.buffer_)));return b};
                +goog.ui.tree.TypeAhead.prototype.setNodeInMap=function(a){var b=a.getText();if(b&&!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(b))){var b=b.toLowerCase(),c=this.nodeMap_.get(b);c?c.push(a):this.nodeMap_.set(b,[a])}};
                +goog.ui.tree.TypeAhead.prototype.removeNodeFromMap=function(a){var b=a.getText();if(b&&!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(b))){var b=b.toLowerCase(),c=this.nodeMap_.get(b);if(c){for(var d=a.getChildCount(),e=0;e<d;e++)this.removeNodeFromMap(a.getChildAt(e));goog.array.remove(c,a);c.length||this.nodeMap_.remove(b)}}};
                +goog.ui.tree.TypeAhead.prototype.jumpToLabel_=function(a){var b=!1;(a=this.nodeMap_.getKeys(a))&&a.length&&(this.matchingLabelIndex_=this.matchingNodeIndex_=0,b=this.nodeMap_.get(a[0]),b=this.selectMatchingNode_(b))&&(this.matchingLabels_=a);return b};
                +goog.ui.tree.TypeAhead.prototype.jumpTo_=function(a){var b=!1,c=this.matchingLabels_;if(c){var b=null,d=!1;if(this.matchingNodes_){var e=this.matchingNodeIndex_+a;0<=e&&e<this.matchingNodes_.length?(this.matchingNodeIndex_=e,b=this.matchingNodes_):d=!0}b||(e=this.matchingLabelIndex_+a,0<=e&&e<c.length&&(this.matchingLabelIndex_=e),c.length>this.matchingLabelIndex_&&(b=this.nodeMap_.get(c[this.matchingLabelIndex_])),b&&b.length&&d&&(this.matchingNodeIndex_=a==goog.ui.tree.TypeAhead.Offset.UP?b.length-
                +1:0));if(b=this.selectMatchingNode_(b))this.matchingLabels_=c}return b};goog.ui.tree.TypeAhead.prototype.selectMatchingNode_=function(a){if(a){if(this.matchingNodeIndex_<a.length){var b=a[this.matchingNodeIndex_];this.matchingNodes_=a}b&&(b.reveal(),b.select())}return!!b};goog.ui.tree.TypeAhead.prototype.clear=function(){this.buffer_=""};goog.ui.tree.TreeControl=function(a,b,c){goog.ui.tree.BaseNode.call(this,a,b,c);this.setExpandedInternal(!0);this.setSelectedInternal(!0);this.selectedItem_=this;this.typeAhead_=new goog.ui.tree.TypeAhead;this.focusHandler_=this.keyHandler_=null;this.logger_=goog.log.getLogger("this");this.focused_=!1;this.focusedNode_=null;this.showRootLines_=this.showRootNode_=this.showExpandIcons_=this.showLines_=!0;if(goog.userAgent.IE)try{document.execCommand("BackgroundImageCache",!1,!0)}catch(d){goog.log.warning(this.logger_,
                +"Failed to enable background image cache")}};goog.inherits(goog.ui.tree.TreeControl,goog.ui.tree.BaseNode);goog.ui.tree.TreeControl.prototype.getTree=function(){return this};goog.ui.tree.TreeControl.prototype.getDepth=function(){return 0};goog.ui.tree.TreeControl.prototype.reveal=function(){};goog.ui.tree.TreeControl.prototype.handleFocus_=function(a){this.focused_=!0;goog.dom.classlist.add(goog.asserts.assert(this.getElement()),"focused");this.selectedItem_&&this.selectedItem_.select()};
                +goog.ui.tree.TreeControl.prototype.handleBlur_=function(a){this.focused_=!1;goog.dom.classlist.remove(goog.asserts.assert(this.getElement()),"focused")};goog.ui.tree.TreeControl.prototype.hasFocus=function(){return this.focused_};goog.ui.tree.TreeControl.prototype.getExpanded=function(){return!this.showRootNode_||goog.ui.tree.TreeControl.superClass_.getExpanded.call(this)};
                +goog.ui.tree.TreeControl.prototype.setExpanded=function(a){this.showRootNode_?goog.ui.tree.TreeControl.superClass_.setExpanded.call(this,a):this.setExpandedInternal(a)};goog.ui.tree.TreeControl.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.EMPTY};goog.ui.tree.TreeControl.prototype.getIconElement=function(){var a=this.getRowElement();return a?a.firstChild:null};goog.ui.tree.TreeControl.prototype.getExpandIconElement=function(){return null};
                +goog.ui.tree.TreeControl.prototype.updateExpandIcon=function(){};goog.ui.tree.TreeControl.prototype.getRowClassName=function(){return goog.ui.tree.TreeControl.superClass_.getRowClassName.call(this)+(this.showRootNode_?"":" "+this.getConfig().cssHideRoot)};
                +goog.ui.tree.TreeControl.prototype.getCalculatedIconClass=function(){var a=this.getExpanded(),b=this.getExpandedIconClass();if(a&&b)return b;b=this.getIconClass();if(!a&&b)return b;b=this.getConfig();return a&&b.cssExpandedRootIcon?b.cssTreeIcon+" "+b.cssExpandedRootIcon:!a&&b.cssCollapsedRootIcon?b.cssTreeIcon+" "+b.cssCollapsedRootIcon:""};
                +goog.ui.tree.TreeControl.prototype.setSelectedItem=function(a){if(this.selectedItem_!=a){var b=!1;this.selectedItem_&&(b=this.selectedItem_==this.focusedNode_,this.selectedItem_.setSelectedInternal(!1));if(this.selectedItem_=a)a.setSelectedInternal(!0),b&&a.select();this.dispatchEvent(goog.events.EventType.CHANGE)}};goog.ui.tree.TreeControl.prototype.getSelectedItem=function(){return this.selectedItem_};
                +goog.ui.tree.TreeControl.prototype.setShowLines=function(a){this.showLines_!=a&&(this.showLines_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowLines=function(){return this.showLines_};
                +goog.ui.tree.TreeControl.prototype.updateLinesAndExpandIcons_=function(){function a(e){var f=e.getChildrenElement();if(f){var g=!c||b==e.getParent()&&!d?e.getConfig().cssChildrenNoLines:e.getConfig().cssChildren;f.className=g;if(f=e.getExpandIconElement())f.className=e.getExpandIconClass()}e.forEachChild(a)}var b=this,c=b.getShowLines(),d=b.getShowRootLines();a(this)};
                +goog.ui.tree.TreeControl.prototype.setShowRootLines=function(a){this.showRootLines_!=a&&(this.showRootLines_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowRootLines=function(){return this.showRootLines_};goog.ui.tree.TreeControl.prototype.setShowExpandIcons=function(a){this.showExpandIcons_!=a&&(this.showExpandIcons_=a,this.isInDocument()&&this.updateLinesAndExpandIcons_())};goog.ui.tree.TreeControl.prototype.getShowExpandIcons=function(){return this.showExpandIcons_};
                +goog.ui.tree.TreeControl.prototype.setShowRootNode=function(a){if(this.showRootNode_!=a){this.showRootNode_=a;if(this.isInDocument()){var b=this.getRowElement();b&&(b.className=this.getRowClassName())}!a&&this.getSelectedItem()==this&&this.getFirstChild()&&this.setSelectedItem(this.getFirstChild())}};goog.ui.tree.TreeControl.prototype.getShowRootNode=function(){return this.showRootNode_};
                +goog.ui.tree.TreeControl.prototype.initAccessibility=function(){goog.ui.tree.TreeControl.superClass_.initAccessibility.call(this);var a=this.getElement();goog.asserts.assert(a,"The DOM element for the tree cannot be null.");goog.a11y.aria.setRole(a,"tree");goog.a11y.aria.setState(a,"labelledby",this.getLabelElement().id)};
                +goog.ui.tree.TreeControl.prototype.enterDocument=function(){goog.ui.tree.TreeControl.superClass_.enterDocument.call(this);var a=this.getElement();a.className=this.getConfig().cssRoot;a.setAttribute("hideFocus","true");this.attachEvents_();this.initAccessibility()};goog.ui.tree.TreeControl.prototype.exitDocument=function(){goog.ui.tree.TreeControl.superClass_.exitDocument.call(this);this.detachEvents_()};
                +goog.ui.tree.TreeControl.prototype.attachEvents_=function(){var a=this.getElement();a.tabIndex=0;var b=this.keyHandler_=new goog.events.KeyHandler(a),c=this.focusHandler_=new goog.events.FocusHandler(a);this.getHandler().listen(c,goog.events.FocusHandler.EventType.FOCUSOUT,this.handleBlur_).listen(c,goog.events.FocusHandler.EventType.FOCUSIN,this.handleFocus_).listen(b,goog.events.KeyHandler.EventType.KEY,this.handleKeyEvent).listen(a,goog.events.EventType.MOUSEDOWN,this.handleMouseEvent_).listen(a,
                +goog.events.EventType.CLICK,this.handleMouseEvent_).listen(a,goog.events.EventType.DBLCLICK,this.handleMouseEvent_)};goog.ui.tree.TreeControl.prototype.detachEvents_=function(){this.keyHandler_.dispose();this.keyHandler_=null;this.focusHandler_.dispose();this.focusHandler_=null};
                +goog.ui.tree.TreeControl.prototype.handleMouseEvent_=function(a){goog.log.fine(this.logger_,"Received event "+a.type);var b=this.getNodeFromEvent_(a);if(b)switch(a.type){case goog.events.EventType.MOUSEDOWN:b.onMouseDown(a);break;case goog.events.EventType.CLICK:b.onClick_(a);break;case goog.events.EventType.DBLCLICK:b.onDoubleClick_(a)}};
                +goog.ui.tree.TreeControl.prototype.handleKeyEvent=function(a){var b;(b=this.typeAhead_.handleNavigation(a)||this.selectedItem_&&this.selectedItem_.onKeyDown(a)||this.typeAhead_.handleTypeAheadChar(a))&&a.preventDefault();return b};goog.ui.tree.TreeControl.prototype.getNodeFromEvent_=function(a){for(var b=a.target;null!=b;){if(a=goog.ui.tree.BaseNode.allNodes[b.id])return a;if(b==this.getElement())break;b=b.parentNode}return null};
                +goog.ui.tree.TreeControl.prototype.createNode=function(a){return new goog.ui.tree.TreeNode(a||goog.html.SafeHtml.EMPTY,this.getConfig(),this.getDomHelper())};goog.ui.tree.TreeControl.prototype.setNode=function(a){this.typeAhead_.setNodeInMap(a)};goog.ui.tree.TreeControl.prototype.removeNode=function(a){this.typeAhead_.removeNodeFromMap(a)};goog.ui.tree.TreeControl.prototype.clearTypeAhead=function(){this.typeAhead_.clear()};goog.ui.tree.TreeControl.defaultConfig=goog.ui.tree.BaseNode.defaultConfig;/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2013 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +var Blockly={};Blockly.Blocks=Object(null);/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2016 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Touch={};Blockly.Touch.touchIdentifier_=null;Blockly.Touch.TOUCH_MAP={};goog.events.BrowserFeature.TOUCH_ENABLED&&(Blockly.Touch.TOUCH_MAP={mousedown:["touchstart"],mousemove:["touchmove"],mouseup:["touchend","touchcancel"]});Blockly.longPid_=0;Blockly.longStart_=function(a,b){Blockly.longStop_();1==a.changedTouches.length&&(Blockly.longPid_=setTimeout(function(){a.button=2;a.clientX=a.changedTouches[0].clientX;a.clientY=a.changedTouches[0].clientY;b&&b.handleRightClick(a)},Blockly.LONGPRESS))};
                +Blockly.longStop_=function(){Blockly.longPid_&&(clearTimeout(Blockly.longPid_),Blockly.longPid_=0)};Blockly.Touch.clearTouchIdentifier=function(){Blockly.Touch.touchIdentifier_=null};Blockly.Touch.shouldHandleEvent=function(a){return!Blockly.Touch.isMouseOrTouchEvent(a)||Blockly.Touch.checkTouchIdentifier(a)};
                +Blockly.Touch.getTouchIdentifierFromEvent=function(a){return a.changedTouches&&a.changedTouches[0]&&void 0!=a.changedTouches[0].identifier&&null!=a.changedTouches[0].identifier?a.changedTouches[0].identifier:"mouse"};
                +Blockly.Touch.checkTouchIdentifier=function(a){var b=Blockly.Touch.getTouchIdentifierFromEvent(a);return void 0!=Blockly.Touch.touchIdentifier_&&null!=Blockly.Touch.touchIdentifier_?Blockly.Touch.touchIdentifier_==b:"mousedown"==a.type||"touchstart"==a.type?(Blockly.Touch.touchIdentifier_=b,!0):!1};Blockly.Touch.setClientFromTouch=function(a){if(goog.string.startsWith(a.type,"touch")){var b=a.changedTouches[0];a.clientX=b.clientX;a.clientY=b.clientY}};
                +Blockly.Touch.isMouseOrTouchEvent=function(a){return goog.string.startsWith(a.type,"touch")||goog.string.startsWith(a.type,"mouse")};Blockly.Touch.splitEventByTouches=function(a){var b=[];if(a.changedTouches)for(var c=0;c<a.changedTouches.length;c++)b[c]={type:a.type,changedTouches:[a.changedTouches[c]],target:a.target,stopPropagation:function(){a.stopPropagation()},preventDefault:function(){a.preventDefault()}};else b.push(a);return b};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2017 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.VariableMap=function(a){this.variableMap_={};this.workspace=a};Blockly.VariableMap.prototype.clear=function(){this.variableMap_=Object(null)};
                +Blockly.VariableMap.prototype.renameVariable=function(a,b){var c=this.getVariable(b);var d=-1,e=-1,f="";if(a||c)f=(a||c).type;var g=this.getVariablesOfType(f);a&&(d=g.indexOf(a));c&&(e=g.indexOf(c));-1==d&&-1==e?(this.createVariable(b,""),console.log("Tried to rename an non-existent variable.")):d==e||-1!=d&&-1==e?(c=this.variableMap_[f][d],Blockly.Events.fire(new Blockly.Events.VarRename(c,b)),c.name=b):-1!=d&&-1!=e&&(c=this.variableMap_[f][e],Blockly.Events.fire(new Blockly.Events.VarRename(c,b)),
                +Blockly.Events.fire(new Blockly.Events.VarDelete(this.variableMap_[f][d])),c.name=b,this.variableMap_[f].splice(d,1))};
                +Blockly.VariableMap.prototype.createVariable=function(a,b,c){var d=this.getVariable(a);if(d){if(b&&d.type!=b)throw Error('Variable "'+a+'" is already in use and its type is "'+d.type+'" which conflicts with the passed in type, "'+b+'".');if(c&&d.getId()!=c)throw Error('Variable "'+a+'" is already in use and its id is "'+d.getId()+'" which conflicts with the passed in id, "'+c+'".');return d}if(c&&this.getVariableById(c))throw Error('Variable id, "'+c+'", is already in use.');c=c||Blockly.utils.genUid();
                +b=b||"";d=new Blockly.VariableModel(this.workspace,a,b,c);this.variableMap_[b]?this.variableMap_[b].push(d):this.variableMap_[b]=[d];return d};Blockly.VariableMap.prototype.deleteVariable=function(a){for(var b=this.variableMap_[a.type],c=0,d;d=b[c];c++)if(d.getId()==a.getId()){b.splice(c,1);Blockly.Events.fire(new Blockly.Events.VarDelete(a));break}};
                +Blockly.VariableMap.prototype.getVariable=function(a){for(var b=Object.keys(this.variableMap_),c=0;c<b.length;c++)for(var d=b[c],e=0,f;f=this.variableMap_[d][e];e++)if(Blockly.Names.equals(f.name,a))return f;return null};Blockly.VariableMap.prototype.getVariableById=function(a){for(var b=Object.keys(this.variableMap_),c=0;c<b.length;c++)for(var d=b[c],e=0,f;f=this.variableMap_[d][e];e++)if(f.getId()==a)return f;return null};
                +Blockly.VariableMap.prototype.getVariablesOfType=function(a){return(a=this.variableMap_[a||""])?a.slice():[]};Blockly.VariableMap.prototype.getVariableTypes=function(){return Object.keys(this.variableMap_)};Blockly.VariableMap.prototype.getAllVariables=function(){for(var a=[],b=Object.keys(this.variableMap_),c=0;c<b.length;c++)a=a.concat(this.variableMap_[b[c]]);return a};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2012 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Workspace=function(a){this.id=Blockly.utils.genUid();Blockly.Workspace.WorkspaceDB_[this.id]=this;this.options=a||{};this.RTL=!!this.options.RTL;this.horizontalLayout=!!this.options.horizontalLayout;this.toolboxPosition=this.options.toolboxPosition;this.topBlocks_=[];this.listeners_=[];this.undoStack_=[];this.redoStack_=[];this.blockDB_=Object.create(null);this.variableMap_=new Blockly.VariableMap(this)};Blockly.Workspace.prototype.rendered=!1;Blockly.Workspace.prototype.MAX_UNDO=1024;
                +Blockly.Workspace.prototype.dispose=function(){this.listeners_.length=0;this.clear();delete Blockly.Workspace.WorkspaceDB_[this.id]};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);if(this.isFlyout){a=Blockly.Variables.allUsedVariables(a);for(var b=0,c;c=a[b];b++)this.getVariable(c)||this.createVariable(c)}};
                +Blockly.Workspace.prototype.removeTopBlock=function(a){if(!goog.array.remove(this.topBlocks_,a))throw"Block not present in workspace's list of top-most blocks.";};Blockly.Workspace.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1<b.length){var c=Math.sin(goog.math.toRadians(Blockly.Workspace.SCAN_ANGLE));this.RTL&&(c*=-1);b.sort(function(a,b){var d=a.getRelativeToSurfaceXY(),e=b.getRelativeToSurfaceXY();return d.y+c*d.x-(e.y+c*e.x)})}return b};
                +Blockly.Workspace.prototype.getAllBlocks=function(){for(var a=this.getTopBlocks(!1),b=0;b<a.length;b++)a.push.apply(a,a[b].getChildren());return a};Blockly.Workspace.prototype.clear=function(){var a=Blockly.Events.getGroup();for(a||Blockly.Events.setGroup(!0);this.topBlocks_.length;)this.topBlocks_[0].dispose();a||Blockly.Events.setGroup(!1);this.variableMap_.clear()};
                +Blockly.Workspace.prototype.updateVariableStore=function(a){if(!this.isFlyout){for(var b=Blockly.Variables.allUsedVariables(this),c=[],d=0,e;e=b[d];d++){var f=this.getVariable(e);f?c.push({name:f.name,type:f.type,id:f.getId()}):c.push({name:e,type:null,id:null})}a&&this.variableMap_.clear();for(d=0;a=c[d];d++)this.getVariable(a.name)||this.createVariable(a.name,a.type,a.id)}};
                +Blockly.Workspace.prototype.renameVariableInternal_=function(a,b){var c=this.getVariable(b);if(a&&c&&a.type!=c.type)throw Error('Variable "'+a.name+'" is type "'+a.type+'" and variable "'+b+'" is type "'+c.type+'". Both must be the same type.');if(c&&c.name!=b)var d=c.name;Blockly.Events.setGroup(!0);for(var c=this.getAllBlocks(),e=0;e<c.length;e++)c[e].renameVar(a.name,b),d&&c[e].renameVar(d,b);this.variableMap_.renameVariable(a,b);Blockly.Events.setGroup(!1)};
                +Blockly.Workspace.prototype.renameVariable=function(a,b){var c=this.getVariable(a);this.renameVariableInternal_(c,b)};Blockly.Workspace.prototype.renameVariableById=function(a,b){var c=this.getVariableById(a);this.renameVariableInternal_(c,b)};Blockly.Workspace.prototype.createVariable=function(a,b,c){return this.variableMap_.createVariable(a,b,c)};
                +Blockly.Workspace.prototype.getVariableUses=function(a){for(var b=[],c=this.getAllBlocks(),d=0;d<c.length;d++){var e=c[d].getVars();if(e)for(var f=0;f<e.length;f++){var g=e[f];g&&a&&Blockly.Names.equals(g,a)&&b.push(c[d])}}return b};
                +Blockly.Workspace.prototype.deleteVariable=function(a){for(var b=this.getVariableUses(a),c=0,d;d=b[c];c++)if("procedures_defnoreturn"==d.type||"procedures_defreturn"==d.type){b=d.getFieldValue("NAME");Blockly.alert(Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE.replace("%1",a).replace("%2",b));return}var e=this,f=e.getVariable(a);1<b.length?Blockly.confirm(Blockly.Msg.DELETE_VARIABLE_CONFIRMATION.replace("%1",b.length).replace("%2",a),function(a){a&&e.deleteVariableInternal_(f)}):this.deleteVariableInternal_(f)};
                +Blockly.Workspace.prototype.deleteVariableById=function(a){var b=this.getVariableById(a);b?this.deleteVariableInternal_(b):console.warn("Can't delete non-existant variable: "+a)};Blockly.Workspace.prototype.deleteVariableInternal_=function(a){var b=this.getVariableUses(a.name);Blockly.Events.setGroup(!0);for(var c=0;c<b.length;c++)b[c].dispose(!0,!1);this.variableMap_.deleteVariable(a);Blockly.Events.setGroup(!1)};
                +Blockly.Workspace.prototype.variableIndexOf=function(a){console.warn("Deprecated call to Blockly.Workspace.prototype.variableIndexOf");return-1};Blockly.Workspace.prototype.getVariable=function(a){return this.variableMap_.getVariable(a)};Blockly.Workspace.prototype.getVariableById=function(a){return this.variableMap_.getVariableById(a)};Blockly.Workspace.prototype.getWidth=function(){return 0};Blockly.Workspace.prototype.newBlock=function(a,b){return new Blockly.Block(this,a,b)};
                +Blockly.Workspace.prototype.remainingCapacity=function(){return isNaN(this.options.maxBlocks)?Infinity:this.options.maxBlocks-this.getAllBlocks().length};
                +Blockly.Workspace.prototype.undo=function(a){var b=a?this.redoStack_:this.undoStack_,c=a?this.undoStack_:this.redoStack_,d=b.pop();if(d){for(var e=[d];b.length&&d.group&&d.group==b[b.length-1].group;)e.push(b.pop());for(b=0;d=e[b];b++)c.push(d);e=Blockly.Events.filter(e,a);Blockly.Events.recordUndo=!1;try{for(b=0;d=e[b];b++)d.run(a)}finally{Blockly.Events.recordUndo=!0}}};Blockly.Workspace.prototype.clearUndo=function(){this.undoStack_.length=0;this.redoStack_.length=0;Blockly.Events.clearPendingUndo()};
                +Blockly.Workspace.prototype.addChangeListener=function(a){this.listeners_.push(a);return a};Blockly.Workspace.prototype.removeChangeListener=function(a){goog.array.remove(this.listeners_,a)};Blockly.Workspace.prototype.fireChangeListener=function(a){a.recordUndo&&(this.undoStack_.push(a),this.redoStack_.length=0,this.undoStack_.length>this.MAX_UNDO&&this.undoStack_.unshift());for(var b=0,c;c=this.listeners_[b];b++)c(a)};
                +Blockly.Workspace.prototype.getBlockById=function(a){return this.blockDB_[a]||null};Blockly.Workspace.prototype.allInputsFilled=function(a){for(var b=this.getTopBlocks(!1),c=0,d;d=b[c];c++)if(!d.allInputsFilled(a))return!1;return!0};Blockly.Workspace.prototype.getVariablesOfType=function(a){return this.variableMap_.getVariablesOfType(a)};Blockly.Workspace.prototype.getVariableTypes=function(){return this.variableMap_.getVariableTypes()};Blockly.Workspace.prototype.getAllVariables=function(){return this.variableMap_.getAllVariables()};
                +Blockly.Workspace.WorkspaceDB_=Object.create(null);Blockly.Workspace.getById=function(a){return Blockly.Workspace.WorkspaceDB_[a]||null};Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear;Blockly.Workspace.prototype.clearUndo=Blockly.Workspace.prototype.clearUndo;Blockly.Workspace.prototype.addChangeListener=Blockly.Workspace.prototype.addChangeListener;Blockly.Workspace.prototype.removeChangeListener=Blockly.Workspace.prototype.removeChangeListener;Blockly.Bubble=function(a,b,c,d,e,f){this.workspace_=a;this.content_=b;this.shape_=c;c=Blockly.Bubble.ARROW_ANGLE;this.workspace_.RTL&&(c=-c);this.arrow_radians_=goog.math.toRadians(c);a.getBubbleCanvas().appendChild(this.createDom_(b,!(!e||!f)));this.setAnchorLocation(d);e&&f||(b=this.content_.getBBox(),e=b.width+2*Blockly.Bubble.BORDER_WIDTH,f=b.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(e,f);this.positionBubble_();this.renderArrow_();this.rendered_=!0;a.options.readOnly||(Blockly.bindEventWithChecks_(this.bubbleBack_,
                +"mousedown",this,this.bubbleMouseDown_),this.resizeGroup_&&Blockly.bindEventWithChecks_(this.resizeGroup_,"mousedown",this,this.resizeMouseDown_))};Blockly.Bubble.BORDER_WIDTH=6;Blockly.Bubble.ARROW_THICKNESS=5;Blockly.Bubble.ARROW_ANGLE=20;Blockly.Bubble.ARROW_BEND=4;Blockly.Bubble.ANCHOR_RADIUS=8;Blockly.Bubble.onMouseUpWrapper_=null;Blockly.Bubble.onMouseMoveWrapper_=null;Blockly.Bubble.prototype.resizeCallback_=null;
                +Blockly.Bubble.unbindDragEvents_=function(){Blockly.Bubble.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_),Blockly.Bubble.onMouseUpWrapper_=null);Blockly.Bubble.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_),Blockly.Bubble.onMouseMoveWrapper_=null)};Blockly.Bubble.bubbleMouseUp_=function(){Blockly.Touch.clearTouchIdentifier();Blockly.Bubble.unbindDragEvents_()};Blockly.Bubble.prototype.rendered_=!1;Blockly.Bubble.prototype.anchorXY_=null;
                +Blockly.Bubble.prototype.relativeLeft_=0;Blockly.Bubble.prototype.relativeTop_=0;Blockly.Bubble.prototype.width_=0;Blockly.Bubble.prototype.height_=0;Blockly.Bubble.prototype.autoLayout_=!0;
                +Blockly.Bubble.prototype.createDom_=function(a,b){this.bubbleGroup_=Blockly.utils.createSvgElement("g",{},null);var c={filter:"url(#"+this.workspace_.options.embossFilterId+")"};-1!=goog.userAgent.getUserAgentString().indexOf("JavaFX")&&(c={});c=Blockly.utils.createSvgElement("g",c,this.bubbleGroup_);this.bubbleArrow_=Blockly.utils.createSvgElement("path",{},c);this.bubbleBack_=Blockly.utils.createSvgElement("rect",{"class":"blocklyDraggable",x:0,y:0,rx:Blockly.Bubble.BORDER_WIDTH,ry:Blockly.Bubble.BORDER_WIDTH},
                +c);b?(this.resizeGroup_=Blockly.utils.createSvgElement("g",{"class":this.workspace_.RTL?"blocklyResizeSW":"blocklyResizeSE"},this.bubbleGroup_),c=2*Blockly.Bubble.BORDER_WIDTH,Blockly.utils.createSvgElement("polygon",{points:"0,x x,x x,0".replace(/x/g,c.toString())},this.resizeGroup_),Blockly.utils.createSvgElement("line",{"class":"blocklyResizeLine",x1:c/3,y1:c-1,x2:c-1,y2:c/3},this.resizeGroup_),Blockly.utils.createSvgElement("line",{"class":"blocklyResizeLine",x1:2*c/3,y1:c-1,x2:c-1,y2:2*c/3},
                +this.resizeGroup_)):this.resizeGroup_=null;this.bubbleGroup_.appendChild(a);return this.bubbleGroup_};
                +Blockly.Bubble.prototype.bubbleMouseDown_=function(a){this.promote_();Blockly.Bubble.unbindDragEvents_();Blockly.utils.isRightButton(a)?a.stopPropagation():Blockly.utils.isTargetInput(a)||(this.workspace_.startDrag(a,new goog.math.Coordinate(this.workspace_.RTL?-this.relativeLeft_:this.relativeLeft_,this.relativeTop_)),Blockly.Bubble.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,Blockly.Bubble.bubbleMouseUp_),Blockly.Bubble.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,
                +"mousemove",this,this.bubbleMouseMove_),Blockly.hideChaff(),a.stopPropagation())};Blockly.Bubble.prototype.bubbleMouseMove_=function(a){this.autoLayout_=!1;a=this.workspace_.moveDrag(a);this.relativeLeft_=this.workspace_.RTL?-a.x:a.x;this.relativeTop_=a.y;this.positionBubble_();this.renderArrow_()};
                +Blockly.Bubble.prototype.resizeMouseDown_=function(a){this.promote_();Blockly.Bubble.unbindDragEvents_();Blockly.utils.isRightButton(a)||(this.workspace_.startDrag(a,new goog.math.Coordinate(this.workspace_.RTL?-this.width_:this.width_,this.height_)),Blockly.Bubble.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,Blockly.Bubble.bubbleMouseUp_),Blockly.Bubble.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",this,this.resizeMouseMove_),Blockly.hideChaff());
                +a.stopPropagation()};Blockly.Bubble.prototype.resizeMouseMove_=function(a){this.autoLayout_=!1;a=this.workspace_.moveDrag(a);this.setBubbleSize(this.workspace_.RTL?-a.x:a.x,a.y);this.workspace_.RTL&&this.positionBubble_()};Blockly.Bubble.prototype.registerResizeEvent=function(a){this.resizeCallback_=a};Blockly.Bubble.prototype.promote_=function(){this.bubbleGroup_.parentNode.appendChild(this.bubbleGroup_)};Blockly.Bubble.prototype.setAnchorLocation=function(a){this.anchorXY_=a;this.rendered_&&this.positionBubble_()};
                +Blockly.Bubble.prototype.layoutBubble_=function(){var a=-this.width_/4,b=-this.height_-Blockly.BlockSvg.MIN_BLOCK_Y,c=this.workspace_.getMetrics();c.viewWidth/=this.workspace_.scale;c.viewLeft/=this.workspace_.scale;var d=this.anchorXY_.x;this.workspace_.RTL?d-c.viewLeft-a-this.width_<Blockly.Scrollbar.scrollbarThickness?a=d-c.viewLeft-this.width_-Blockly.Scrollbar.scrollbarThickness:d-c.viewLeft-a>c.viewWidth&&(a=d-c.viewLeft-c.viewWidth):d+a<c.viewLeft?a=c.viewLeft-d:c.viewLeft+c.viewWidth<d+a+
                +this.width_+Blockly.BlockSvg.SEP_SPACE_X+Blockly.Scrollbar.scrollbarThickness&&(a=c.viewLeft+c.viewWidth-d-this.width_-Blockly.Scrollbar.scrollbarThickness);this.anchorXY_.y+b<c.viewTop&&(b=this.shape_.getBBox().height);this.relativeLeft_=a;this.relativeTop_=b};
                +Blockly.Bubble.prototype.positionBubble_=function(){var a=this.anchorXY_.x,a=this.workspace_.RTL?a-(this.relativeLeft_+this.width_):a+this.relativeLeft_;this.bubbleGroup_.setAttribute("transform","translate("+a+","+(this.relativeTop_+this.anchorXY_.y)+")")};Blockly.Bubble.prototype.getBubbleSize=function(){return{width:this.width_,height:this.height_}};
                +Blockly.Bubble.prototype.setBubbleSize=function(a,b){var c=2*Blockly.Bubble.BORDER_WIDTH;a=Math.max(a,c+45);b=Math.max(b,c+20);this.width_=a;this.height_=b;this.bubbleBack_.setAttribute("width",a);this.bubbleBack_.setAttribute("height",b);this.resizeGroup_&&(this.workspace_.RTL?this.resizeGroup_.setAttribute("transform","translate("+2*Blockly.Bubble.BORDER_WIDTH+","+(b-c)+") scale(-1 1)"):this.resizeGroup_.setAttribute("transform","translate("+(a-c)+","+(b-c)+")"));this.rendered_&&(this.autoLayout_&&
                +this.layoutBubble_(),this.positionBubble_(),this.renderArrow_());this.resizeCallback_&&this.resizeCallback_()};
                +Blockly.Bubble.prototype.renderArrow_=function(){var a=[],b=this.width_/2,c=this.height_/2,d=-this.relativeLeft_,e=-this.relativeTop_;if(b==d&&c==e)a.push("M "+b+","+c);else{e-=c;d-=b;this.workspace_.RTL&&(d*=-1);var f=Math.sqrt(e*e+d*d),g=Math.acos(d/f);0>e&&(g=2*Math.PI-g);var h=g+Math.PI/2;h>2*Math.PI&&(h-=2*Math.PI);var k=Math.sin(h),l=Math.cos(h),m=this.getBubbleSize(),h=(m.width+m.height)/Blockly.Bubble.ARROW_THICKNESS,h=Math.min(h,m.width,m.height)/4,m=1-Blockly.Bubble.ANCHOR_RADIUS/f,d=b+
                +m*d,e=c+m*e,m=b+h*l,n=c+h*k,b=b-h*l,c=c-h*k,k=g+this.arrow_radians_;k>2*Math.PI&&(k-=2*Math.PI);g=Math.sin(k)*f/Blockly.Bubble.ARROW_BEND;f=Math.cos(k)*f/Blockly.Bubble.ARROW_BEND;a.push("M"+m+","+n);a.push("C"+(m+f)+","+(n+g)+" "+d+","+e+" "+d+","+e);a.push("C"+d+","+e+" "+(b+f)+","+(c+g)+" "+b+","+c)}a.push("z");this.bubbleArrow_.setAttribute("d",a.join(" "))};Blockly.Bubble.prototype.setColour=function(a){this.bubbleBack_.setAttribute("fill",a);this.bubbleArrow_.setAttribute("fill",a)};
                +Blockly.Bubble.prototype.dispose=function(){Blockly.Bubble.unbindDragEvents_();goog.dom.removeNode(this.bubbleGroup_);this.shape_=this.content_=this.workspace_=this.resizeGroup_=this.bubbleBack_=this.bubbleArrow_=this.bubbleGroup_=null};Blockly.Icon=function(a){this.block_=a};Blockly.Icon.prototype.collapseHidden=!0;Blockly.Icon.prototype.SIZE=17;Blockly.Icon.prototype.bubble_=null;Blockly.Icon.prototype.iconXY_=null;
                +Blockly.Icon.prototype.createIcon=function(){this.iconGroup_||(this.iconGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyIconGroup"},null),this.block_.isInFlyout&&Blockly.utils.addClass(this.iconGroup_,"blocklyIconGroupReadonly"),this.drawIcon_(this.iconGroup_),this.block_.getSvgRoot().appendChild(this.iconGroup_),Blockly.bindEventWithChecks_(this.iconGroup_,"mouseup",this,this.iconClick_),this.updateEditable())};
                +Blockly.Icon.prototype.dispose=function(){goog.dom.removeNode(this.iconGroup_);this.iconGroup_=null;this.setVisible(!1);this.block_=null};Blockly.Icon.prototype.updateEditable=function(){};Blockly.Icon.prototype.isVisible=function(){return!!this.bubble_};Blockly.Icon.prototype.iconClick_=function(a){this.block_.workspace.isDragging()||this.block_.isInFlyout||Blockly.utils.isRightButton(a)||this.setVisible(!this.isVisible())};Blockly.Icon.prototype.updateColour=function(){this.isVisible()&&this.bubble_.setColour(this.block_.getColour())};
                +Blockly.Icon.prototype.renderIcon=function(a){if(this.collapseHidden&&this.block_.isCollapsed())return this.iconGroup_.setAttribute("display","none"),a;this.iconGroup_.setAttribute("display","block");var b=this.SIZE;this.block_.RTL&&(a-=b);this.iconGroup_.setAttribute("transform","translate("+a+",5)");this.computeIconLocation();return a=this.block_.RTL?a-Blockly.BlockSvg.SEP_SPACE_X:a+(b+Blockly.BlockSvg.SEP_SPACE_X)};
                +Blockly.Icon.prototype.setIconLocation=function(a){this.iconXY_=a;this.isVisible()&&this.bubble_.setAnchorLocation(a)};Blockly.Icon.prototype.computeIconLocation=function(){var a=this.block_.getRelativeToSurfaceXY(),b=Blockly.utils.getRelativeXY(this.iconGroup_),a=new goog.math.Coordinate(a.x+b.x+this.SIZE/2,a.y+b.y+this.SIZE/2);goog.math.Coordinate.equals(this.getIconLocation(),a)||this.setIconLocation(a)};Blockly.Icon.prototype.getIconLocation=function(){return this.iconXY_};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2011 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Comment=function(a){Blockly.Comment.superClass_.constructor.call(this,a);this.createIcon()};goog.inherits(Blockly.Comment,Blockly.Icon);Blockly.Comment.prototype.text_="";Blockly.Comment.prototype.width_=160;Blockly.Comment.prototype.height_=80;
                +Blockly.Comment.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("circle",{"class":"blocklyIconShape",r:"8",cx:"8",cy:"8"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405 0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25 -1.201,0.998 -1.201,1.528 -1.204,2.19z"},a);Blockly.utils.createSvgElement("rect",{"class":"blocklyIconSymbol",x:"6.8",y:"10.78",height:"2",width:"2"},a)};
                +Blockly.Comment.prototype.createEditor_=function(){this.foreignObject_=Blockly.utils.createSvgElement("foreignObject",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);var a=document.createElementNS(Blockly.HTML_NS,"body");a.setAttribute("xmlns",Blockly.HTML_NS);a.className="blocklyMinimalBody";var b=document.createElementNS(Blockly.HTML_NS,"textarea");b.className="blocklyCommentTextarea";b.setAttribute("dir",this.block_.RTL?"RTL":"LTR");a.appendChild(b);this.textarea_=b;this.foreignObject_.appendChild(a);
                +Blockly.bindEventWithChecks_(b,"mouseup",this,this.textareaFocus_);Blockly.bindEventWithChecks_(b,"wheel",this,function(a){a.stopPropagation()});Blockly.bindEventWithChecks_(b,"change",this,function(a){this.text_!=b.value&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this.block_,"comment",null,this.text_,b.value)),this.text_=b.value)});setTimeout(function(){b.focus()},0);return this.foreignObject_};
                +Blockly.Comment.prototype.updateEditable=function(){this.isVisible()&&(this.setVisible(!1),this.setVisible(!0));Blockly.Icon.prototype.updateEditable.call(this)};Blockly.Comment.prototype.resizeBubble_=function(){if(this.isVisible()){var a=this.bubble_.getBubbleSize(),b=2*Blockly.Bubble.BORDER_WIDTH;this.foreignObject_.setAttribute("width",a.width-b);this.foreignObject_.setAttribute("height",a.height-b);this.textarea_.style.width=a.width-b-4+"px";this.textarea_.style.height=a.height-b-4+"px"}};
                +Blockly.Comment.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"commentOpen",!a,a)),!this.block_.isEditable()&&!this.textarea_||goog.userAgent.IE)Blockly.Warning.prototype.setVisible.call(this,a);else{var b=this.getText(),c=this.getBubbleSize();a?(this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svgPath_,this.iconXY_,this.width_,this.height_),this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this)),
                +this.updateColour()):(this.bubble_.dispose(),this.foreignObject_=this.textarea_=this.bubble_=null);this.setText(b);this.setBubbleSize(c.width,c.height)}};Blockly.Comment.prototype.textareaFocus_=function(a){this.bubble_.promote_();this.textarea_.focus()};Blockly.Comment.prototype.getBubbleSize=function(){return this.isVisible()?this.bubble_.getBubbleSize():{width:this.width_,height:this.height_}};
                +Blockly.Comment.prototype.setBubbleSize=function(a,b){this.textarea_?this.bubble_.setBubbleSize(a,b):(this.width_=a,this.height_=b)};Blockly.Comment.prototype.getText=function(){return this.textarea_?this.textarea_.value:this.text_};Blockly.Comment.prototype.setText=function(a){this.text_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this.block_,"comment",null,this.text_,a)),this.text_=a);this.textarea_&&(this.textarea_.value=a)};
                +Blockly.Comment.prototype.dispose=function(){Blockly.Events.isEnabled()&&this.setText("");this.block_.comment=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Connection=function(a,b){this.sourceBlock_=a;this.type=b;a.workspace.connectionDBList&&(this.db_=a.workspace.connectionDBList[b],this.dbOpposite_=a.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[b]],this.hidden_=!this.db_)};Blockly.Connection.CAN_CONNECT=0;Blockly.Connection.REASON_SELF_CONNECTION=1;Blockly.Connection.REASON_WRONG_TYPE=2;Blockly.Connection.REASON_TARGET_NULL=3;Blockly.Connection.REASON_CHECKS_FAILED=4;Blockly.Connection.REASON_DIFFERENT_WORKSPACES=5;
                +Blockly.Connection.REASON_SHADOW_PARENT=6;Blockly.Connection.prototype.targetConnection=null;Blockly.Connection.prototype.check_=null;Blockly.Connection.prototype.shadowDom_=null;Blockly.Connection.prototype.x_=0;Blockly.Connection.prototype.y_=0;Blockly.Connection.prototype.inDB_=!1;Blockly.Connection.prototype.db_=null;Blockly.Connection.prototype.dbOpposite_=null;Blockly.Connection.prototype.hidden_=null;
                +Blockly.Connection.prototype.connect_=function(a){var b=this,c=b.getSourceBlock(),d=a.getSourceBlock();a.isConnected()&&a.disconnect();if(b.isConnected()){var e=b.targetBlock(),f=b.getShadowDom();b.setShadowDom(null);if(e.isShadow())f=Blockly.Xml.blockToDom(e),e.dispose(),e=null;else if(b.type==Blockly.INPUT_VALUE){if(!e.outputConnection)throw"Orphan block does not have an output connection.";var g=Blockly.Connection.lastConnectionInRow_(d,e);g&&(e.outputConnection.connect(g),e=null)}else if(b.type==
                +Blockly.NEXT_STATEMENT){if(!e.previousConnection)throw"Orphan block does not have a previous connection.";for(g=d;g.nextConnection;){var h=g.getNextBlock();if(h&&!h.isShadow())g=h;else{e.previousConnection.checkType_(g.nextConnection)&&(g.nextConnection.connect(e.previousConnection),e=null);break}}}if(e&&(b.disconnect(),Blockly.Events.recordUndo)){var k=Blockly.Events.getGroup();setTimeout(function(){e.workspace&&!e.getParent()&&(Blockly.Events.setGroup(k),e.outputConnection?e.outputConnection.bumpAwayFrom_(b):
                +e.previousConnection&&e.previousConnection.bumpAwayFrom_(b),Blockly.Events.setGroup(!1))},Blockly.BUMP_DELAY)}b.setShadowDom(f)}var l;Blockly.Events.isEnabled()&&(l=new Blockly.Events.BlockMove(d));Blockly.Connection.connectReciprocally_(b,a);d.setParent(c);l&&(l.recordNew(),Blockly.Events.fire(l))};Blockly.Connection.prototype.dispose=function(){if(this.isConnected())throw"Disconnect connection before disposing of it.";this.inDB_&&this.db_.removeConnection_(this);this.dbOpposite_=this.db_=null};
                +Blockly.Connection.prototype.getSourceBlock=function(){return this.sourceBlock_};Blockly.Connection.prototype.isSuperior=function(){return this.type==Blockly.INPUT_VALUE||this.type==Blockly.NEXT_STATEMENT};Blockly.Connection.prototype.isConnected=function(){return!!this.targetConnection};
                +Blockly.Connection.prototype.canConnectWithReason_=function(a){if(!a)return Blockly.Connection.REASON_TARGET_NULL;if(this.isSuperior()){var b=this.sourceBlock_;var c=a.getSourceBlock()}else c=this.sourceBlock_,b=a.getSourceBlock();return b&&b==c?Blockly.Connection.REASON_SELF_CONNECTION:a.type!=Blockly.OPPOSITE_TYPE[this.type]?Blockly.Connection.REASON_WRONG_TYPE:b&&c&&b.workspace!==c.workspace?Blockly.Connection.REASON_DIFFERENT_WORKSPACES:this.checkType_(a)?b.isShadow()&&!c.isShadow()?Blockly.Connection.REASON_SHADOW_PARENT:
                +Blockly.Connection.CAN_CONNECT:Blockly.Connection.REASON_CHECKS_FAILED};
                +Blockly.Connection.prototype.checkConnection_=function(a){switch(this.canConnectWithReason_(a)){case Blockly.Connection.CAN_CONNECT:break;case Blockly.Connection.REASON_SELF_CONNECTION:throw"Attempted to connect a block to itself.";case Blockly.Connection.REASON_DIFFERENT_WORKSPACES:throw"Blocks not on same workspace.";case Blockly.Connection.REASON_WRONG_TYPE:throw"Attempt to connect incompatible types.";case Blockly.Connection.REASON_TARGET_NULL:throw"Target connection is null.";case Blockly.Connection.REASON_CHECKS_FAILED:throw"Connection checks failed. "+
                +(this+" expected "+this.check_+", found "+a.check_);case Blockly.Connection.REASON_SHADOW_PARENT:throw"Connecting non-shadow to shadow block.";default:throw"Unknown connection failure: this should never happen!";}};
                +Blockly.Connection.prototype.isConnectionAllowed=function(a){if(this.canConnectWithReason_(a)!=Blockly.Connection.CAN_CONNECT)return!1;if(a.type==Blockly.OUTPUT_VALUE||a.type==Blockly.PREVIOUS_STATEMENT)if(a.isConnected()||this.isConnected())return!1;return a.type==Blockly.INPUT_VALUE&&a.isConnected()&&!a.targetBlock().isMovable()&&!a.targetBlock().isShadow()||this.type==Blockly.PREVIOUS_STATEMENT&&a.isConnected()&&!this.sourceBlock_.nextConnection&&!a.targetBlock().isShadow()&&a.targetBlock().nextConnection||
                +-1!=Blockly.draggingConnections_.indexOf(a)?!1:!0};Blockly.Connection.prototype.connect=function(a){this.targetConnection!=a&&(this.checkConnection_(a),this.isSuperior()?this.connect_(a):a.connect_(this))};Blockly.Connection.connectReciprocally_=function(a,b){goog.asserts.assert(a&&b,"Cannot connect null connections.");a.targetConnection=b;b.targetConnection=a};
                +Blockly.Connection.singleConnection_=function(a,b){for(var c=!1,d=0;d<a.inputList.length;d++){var e=a.inputList[d].connection;if(e&&e.type==Blockly.INPUT_VALUE&&b.outputConnection.checkType_(e)){if(c)return null;c=e}}return c};Blockly.Connection.lastConnectionInRow_=function(a,b){for(var c=a,d;d=Blockly.Connection.singleConnection_(c,b);)if(c=d.targetBlock(),!c||c.isShadow())return d;return null};
                +Blockly.Connection.prototype.disconnect=function(){var a=this.targetConnection;goog.asserts.assert(a,"Source connection not connected.");goog.asserts.assert(a.targetConnection==this,"Target connection not connected to source connection.");if(this.isSuperior()){var b=this.sourceBlock_;var c=a.getSourceBlock();a=this}else b=a.getSourceBlock(),c=this.sourceBlock_;this.disconnectInternal_(b,c);a.respawnShadow_()};
                +Blockly.Connection.prototype.disconnectInternal_=function(a,b){var c;Blockly.Events.isEnabled()&&(c=new Blockly.Events.BlockMove(b));this.targetConnection=this.targetConnection.targetConnection=null;b.setParent(null);c&&(c.recordNew(),Blockly.Events.fire(c))};
                +Blockly.Connection.prototype.respawnShadow_=function(){var a=this.getSourceBlock(),b=this.getShadowDom();if(a.workspace&&b&&Blockly.Events.recordUndo)if(a=Blockly.Xml.domToBlock(b,a.workspace),a.outputConnection)this.connect(a.outputConnection);else if(a.previousConnection)this.connect(a.previousConnection);else throw"Child block does not have output or previous statement.";};Blockly.Connection.prototype.targetBlock=function(){return this.isConnected()?this.targetConnection.getSourceBlock():null};
                +Blockly.Connection.prototype.checkType_=function(a){if(!this.check_||!a.check_)return!0;for(var b=0;b<this.check_.length;b++)if(-1!=a.check_.indexOf(this.check_[b]))return!0;return!1};Blockly.Connection.prototype.onCheckChanged_=function(){this.isConnected()&&!this.checkType_(this.targetConnection)&&(this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug()};
                +Blockly.Connection.prototype.setCheck=function(a){a?(goog.isArray(a)||(a=[a]),this.check_=a,this.onCheckChanged_()):this.check_=null;return this};Blockly.Connection.prototype.setShadowDom=function(a){this.shadowDom_=a};Blockly.Connection.prototype.getShadowDom=function(){return this.shadowDom_};Blockly.Connection.prototype.neighbours_=function(){return[]};
                +Blockly.Connection.prototype.toString=function(){var a=this.sourceBlock_;if(a)if(a.outputConnection==this)var b="Output Connection of ";else if(a.previousConnection==this)b="Previous Connection of ";else if(a.nextConnection==this)b="Next Connection of ";else if(b=goog.array.find(a.inputList,function(a){return a.connection==this},this))b='Input "'+b.name+'" connection on ';else return console.warn("Connection not actually connected to sourceBlock_"),"Orphan Connection";else return"Orphan Connection";
                +return b+a.toDevString()};Blockly.Extensions={};Blockly.Extensions.ALL_={};Blockly.Extensions.MUTATOR_PROPERTIES_=["domToMutation","mutationToDom","compose","decompose"];Blockly.Extensions.register=function(a,b){if(!goog.isString(a)||goog.string.isEmptyOrWhitespace(a))throw Error('Error: Invalid extension name "'+a+'"');if(Blockly.Extensions.ALL_[a])throw Error('Error: Extension "'+a+'" is already registered.');if(!goog.isFunction(b))throw Error('Error: Extension "'+a+'" must be a function');Blockly.Extensions.ALL_[a]=b};
                +Blockly.Extensions.registerMixin=function(a,b){Blockly.Extensions.register(a,function(){this.mixin(b)})};
                +Blockly.Extensions.registerMutator=function(a,b,c,d){var e='Error when registering mutator "'+a+'": ';Blockly.Extensions.checkHasFunction_(e,b.domToMutation,"domToMutation");Blockly.Extensions.checkHasFunction_(e,b.mutationToDom,"mutationToDom");var f=Blockly.Extensions.checkMutatorDialog_(b,e);if(c&&!goog.isFunction(c))throw Error('Extension "'+a+'" is not a function');Blockly.Extensions.register(a,function(){f&&this.setMutator(new Blockly.Mutator(d));this.mixin(b);c&&c.apply(this)})};
                +Blockly.Extensions.apply=function(a,b,c){var d,e=Blockly.Extensions.ALL_[a];if(!goog.isFunction(e))throw Error('Error: Extension "'+a+'" not found.');c?Blockly.Extensions.checkNoMutatorProperties_(a,b):d=Blockly.Extensions.getMutatorProperties_(b);e.apply(b);if(c)Blockly.Extensions.checkBlockHasMutatorProperties_(a,b,'Error after applying mutator "'+a+'": ');else if(!Blockly.Extensions.mutatorPropertiesMatch_(d,b))throw Error('Error when applying extension "'+a+'": mutation properties changed when applying a non-mutator extension.');
                +};Blockly.Extensions.checkHasFunction_=function(a,b,c){if(!b)throw Error(a+'missing required property "'+c+'"');if("function"!=typeof b)throw Error(a+'" required property "'+c+'" must be a function');};
                +Blockly.Extensions.checkNoMutatorProperties_=function(a,b){for(var c=0;c<Blockly.Extensions.MUTATOR_PROPERTIES_.length;c++){var d=Blockly.Extensions.MUTATOR_PROPERTIES_[c];if(b.hasOwnProperty(d))throw Error('Error: tried to apply mutation "'+a+'" to a block that already has a "'+d+'" function.  Block id: '+b.id);}};
                +Blockly.Extensions.checkMutatorDialog_=function(a,b){var c=a.hasOwnProperty("compose"),d=a.hasOwnProperty("decompose");if(c&&d){if("function"!==typeof a.compose)throw Error(b+"compose must be a function.");if("function"!==typeof a.decompose)throw Error(b+"decompose must be a function.");return!0}if(c||d)throw Error(b+'Must have both or neither of "compose" and "decompose"');return!1};
                +Blockly.Extensions.checkBlockHasMutatorProperties_=function(a,b){if(!b.hasOwnProperty("domToMutation"))throw Error(a+'Applying a mutator didn\'t add "domToMutation"');if(!b.hasOwnProperty("mutationToDom"))throw Error(a+'Applying a mutator didn\'t add "mutationToDom"');Blockly.Extensions.checkMutatorDialog_(b,a)};Blockly.Extensions.getMutatorProperties_=function(a){for(var b=[],c=0;c<Blockly.Extensions.MUTATOR_PROPERTIES_.length;c++)b.push(a[Blockly.Extensions.MUTATOR_PROPERTIES_[c]]);return b};
                +Blockly.Extensions.mutatorPropertiesMatch_=function(a,b){var c=!0,d=Blockly.Extensions.getMutatorProperties_(b);if(d.length!=a.length)c=!1;else for(var e=0;e<d.length;e++)a[e]!=d[e]&&(c=!1);return c};
                +Blockly.Extensions.buildTooltipForDropdown=function(a,b){var c=[];document&&Blockly.utils.runAfterPageLoad(function(){for(var a in b)Blockly.utils.checkMessageReferences(b[a])});return function(){this.type&&-1===c.indexOf(this.type)&&(Blockly.Extensions.checkDropdownOptionsInTable_(this,a,b),c.push(this.type));this.setTooltip(function(){var d=this.getFieldValue(a),e=b[d];null==e?-1===c.indexOf(this.type)&&(d="No tooltip mapping for value "+d+" of field "+a,null!=this.type&&(d+=" of block type "+this.type),
                +console.warn(d+".")):e=Blockly.utils.replaceMessageReferences(e);return e}.bind(this))}};Blockly.Extensions.checkDropdownOptionsInTable_=function(a,b,c){var d=a.getField(b);if(!d.isOptionListDynamic())for(var d=d.getOptions(),e=0;e<d.length;++e){var f=d[e][1];null==c[f]&&console.warn("No tooltip mapping for value "+f+" of field "+b+" of block type "+a.type)}};
                +Blockly.Extensions.buildTooltipWithFieldValue=function(a,b){document&&Blockly.utils.runAfterPageLoad(function(){Blockly.utils.checkMessageReferences(a)});return function(){this.setTooltip(function(){return Blockly.utils.replaceMessageReferences(a).replace("%1",this.getFieldValue(b))}.bind(this))}};Blockly.Extensions.extensionParentTooltip_=function(){this.tooltipWhenNotConnected_=this.tooltip;this.setTooltip(function(){var a=this.getParent();return a&&a.getInputsInline()&&a.tooltip||this.tooltipWhenNotConnected_}.bind(this))};
                +Blockly.Extensions.register("parent_tooltip_when_inline",Blockly.Extensions.extensionParentTooltip_);Blockly.RenderedConnection=function(a,b){Blockly.RenderedConnection.superClass_.constructor.call(this,a,b);this.offsetInBlock_=new goog.math.Coordinate(0,0)};goog.inherits(Blockly.RenderedConnection,Blockly.Connection);Blockly.RenderedConnection.prototype.distanceFrom=function(a){var b=this.x_-a.x_;a=this.y_-a.y_;return Math.sqrt(b*b+a*a)};
                +Blockly.RenderedConnection.prototype.bumpAwayFrom_=function(a){if(!this.sourceBlock_.workspace.isDragging()){var b=this.sourceBlock_.getRootBlock();if(!b.isInFlyout){var c=!1;if(!b.isMovable()){b=a.getSourceBlock().getRootBlock();if(!b.isMovable())return;a=this;c=!0}var d=Blockly.selected==b;d||b.addSelect();var e=a.x_+Blockly.SNAP_RADIUS-this.x_;a=a.y_+Blockly.SNAP_RADIUS-this.y_;c&&(a=-a);b.RTL&&(e=-e);b.moveBy(e,a);d||b.removeSelect()}}};
                +Blockly.RenderedConnection.prototype.moveTo=function(a,b){this.inDB_&&this.db_.removeConnection_(this);this.x_=a;this.y_=b;this.hidden_||this.db_.addConnection(this)};Blockly.RenderedConnection.prototype.moveBy=function(a,b){this.moveTo(this.x_+a,this.y_+b)};Blockly.RenderedConnection.prototype.moveToOffset=function(a){this.moveTo(a.x+this.offsetInBlock_.x,a.y+this.offsetInBlock_.y)};
                +Blockly.RenderedConnection.prototype.setOffsetInBlock=function(a,b){this.offsetInBlock_.x=a;this.offsetInBlock_.y=b};Blockly.RenderedConnection.prototype.tighten_=function(){var a=this.targetConnection.x_-this.x_,b=this.targetConnection.y_-this.y_;if(0!=a||0!=b){var c=this.targetBlock(),d=c.getSvgRoot();if(!d)throw"block is not rendered.";d=Blockly.utils.getRelativeXY(d);c.getSvgRoot().setAttribute("transform","translate("+(d.x-a)+","+(d.y-b)+")");c.moveConnections_(-a,-b)}};
                +Blockly.RenderedConnection.prototype.closest=function(a,b,c){return this.dbOpposite_.searchForClosest(this,a,b,c)};
                +Blockly.RenderedConnection.prototype.highlight=function(){var a=this.type==Blockly.INPUT_VALUE||this.type==Blockly.OUTPUT_VALUE?"m 0,0 "+Blockly.BlockSvg.TAB_PATH_DOWN+" v 5":"m -20,0 h 5 "+Blockly.BlockSvg.NOTCH_PATH_LEFT+" h 5";var b=this.sourceBlock_.getRelativeToSurfaceXY();Blockly.Connection.highlightedPath_=Blockly.utils.createSvgElement("path",{"class":"blocklyHighlightedConnectionPath",d:a,transform:"translate("+(this.x_-b.x)+","+(this.y_-b.y)+")"+(this.sourceBlock_.RTL?" scale(-1 1)":"")},
                +this.sourceBlock_.getSvgRoot())};
                +Blockly.RenderedConnection.prototype.unhideAll=function(){this.setHidden(!1);var a=[];if(this.type!=Blockly.INPUT_VALUE&&this.type!=Blockly.NEXT_STATEMENT)return a;var b=this.targetBlock();if(b){if(b.isCollapsed()){var c=[];b.outputConnection&&c.push(b.outputConnection);b.nextConnection&&c.push(b.nextConnection);b.previousConnection&&c.push(b.previousConnection)}else c=b.getConnections_(!0);for(var d=0;d<c.length;d++)a.push.apply(a,c[d].unhideAll());a.length||(a[0]=b)}return a};
                +Blockly.RenderedConnection.prototype.unhighlight=function(){goog.dom.removeNode(Blockly.Connection.highlightedPath_);delete Blockly.Connection.highlightedPath_};Blockly.RenderedConnection.prototype.setHidden=function(a){(this.hidden_=a)&&this.inDB_?this.db_.removeConnection_(this):a||this.inDB_||this.db_.addConnection(this)};
                +Blockly.RenderedConnection.prototype.hideAll=function(){this.setHidden(!0);if(this.targetConnection)for(var a=this.targetBlock().getDescendants(),b=0;b<a.length;b++){for(var c=a[b],d=c.getConnections_(!0),e=0;e<d.length;e++)d[e].setHidden(!0);c=c.getIcons();for(e=0;e<c.length;e++)c[e].setVisible(!1)}};Blockly.RenderedConnection.prototype.isConnectionAllowed=function(a,b){return this.distanceFrom(a)>b?!1:Blockly.RenderedConnection.superClass_.isConnectionAllowed.call(this,a)};
                +Blockly.RenderedConnection.prototype.disconnectInternal_=function(a,b){Blockly.RenderedConnection.superClass_.disconnectInternal_.call(this,a,b);a.rendered&&a.render();b.rendered&&(b.updateDisabled(),b.render())};
                +Blockly.RenderedConnection.prototype.respawnShadow_=function(){var a=this.getSourceBlock(),b=this.getShadowDom();if(a.workspace&&b&&Blockly.Events.recordUndo){Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);b=this.targetBlock();if(!b)throw"Couldn't respawn the shadow block that should exist here.";b.initSvg();b.render(!1);a.rendered&&a.render()}};Blockly.RenderedConnection.prototype.neighbours_=function(a){return this.dbOpposite_.getNeighbours(this,a)};
                +Blockly.RenderedConnection.prototype.connect_=function(a){Blockly.RenderedConnection.superClass_.connect_.call(this,a);var b=this.getSourceBlock();a=a.getSourceBlock();b.rendered&&b.updateDisabled();a.rendered&&a.updateDisabled();b.rendered&&a.rendered&&(this.type==Blockly.NEXT_STATEMENT||this.type==Blockly.PREVIOUS_STATEMENT?a.render():b.render())};
                +Blockly.RenderedConnection.prototype.onCheckChanged_=function(){this.isConnected()&&!this.checkType_(this.targetConnection)&&((this.isSuperior()?this.targetBlock():this.sourceBlock_).unplug(),this.sourceBlock_.bumpNeighbours_())};Blockly.DraggedConnectionManager=function(a){this.topBlock_=Blockly.selected=a;this.workspace_=a.workspace;this.availableConnections_=this.initAvailableConnections_();this.localConnection_=this.closestConnection_=null;this.radiusConnection_=0;this.wouldDeleteBlock_=!1};Blockly.DraggedConnectionManager.prototype.dispose=function(){this.workspace_=this.topBlock_=null;this.availableConnections_.length=0;this.localConnection_=this.closestConnection_=null};
                +Blockly.DraggedConnectionManager.prototype.wouldDeleteBlock=function(){return this.wouldDeleteBlock_};Blockly.DraggedConnectionManager.prototype.applyConnections=function(){this.closestConnection_&&(this.localConnection_.connect(this.closestConnection_),this.topBlock_.rendered&&(this.localConnection_.isSuperior()?this.closestConnection_:this.localConnection_).getSourceBlock().connectionUiEffect(),this.removeHighlighting_())};
                +Blockly.DraggedConnectionManager.prototype.update=function(a,b){var c=this.closestConnection_,d=this.updateClosest_(a);d&&c&&c.unhighlight();c=!!this.closestConnection_&&b!=Blockly.DELETE_AREA_TOOLBOX;this.wouldDeleteBlock_=!!b&&!this.topBlock_.getParent()&&this.topBlock_.isDeletable()&&!c;!this.wouldDeleteBlock_&&d&&this.closestConnection_&&this.addHighlighting_()};Blockly.DraggedConnectionManager.prototype.removeHighlighting_=function(){this.closestConnection_&&this.closestConnection_.unhighlight()};
                +Blockly.DraggedConnectionManager.prototype.addHighlighting_=function(){this.closestConnection_&&this.closestConnection_.highlight()};Blockly.DraggedConnectionManager.prototype.initAvailableConnections_=function(){var a=this.topBlock_.getConnections_(!1),b=this.topBlock_.lastConnectionInStack_();b&&b!=this.topBlock_.nextConnection&&a.push(b);return a};
                +Blockly.DraggedConnectionManager.prototype.updateClosest_=function(a){var b=this.closestConnection_;this.localConnection_=this.closestConnection_=null;this.radiusConnection_=Blockly.SNAP_RADIUS;for(var c=0;c<this.availableConnections_.length;c++){var d=this.availableConnections_[c],e=d.closest(this.radiusConnection_,a);e.connection&&(this.closestConnection_=e.connection,this.localConnection_=d,this.radiusConnection_=e.radius)}return b!=this.closestConnection_};Blockly.BlockDragger=function(a,b){this.draggingBlock_=a;this.workspace_=b;this.draggedConnectionManager_=new Blockly.DraggedConnectionManager(this.draggingBlock_);this.deleteArea_=null;this.wouldDeleteBlock_=!1;this.startXY_=this.draggingBlock_.getRelativeToSurfaceXY();this.dragIconData_=Blockly.BlockDragger.initIconData_(a)};
                +Blockly.BlockDragger.prototype.dispose=function(){this.startWorkspace_=this.workspace_=this.draggingBlock_=null;this.dragIconData_.length=0;this.draggedConnectionManager_&&(this.draggedConnectionManager_.dispose(),this.draggedConnectionManager_=null)};Blockly.BlockDragger.initIconData_=function(a){var b=[];a=a.getDescendants();for(var c=0,d;d=a[c];c++){d=d.getIcons();for(var e=0;e<d.length;e++){var f={location:d[e].getIconLocation(),icon:d[e]};b.push(f)}}return b};
                +Blockly.BlockDragger.prototype.startBlockDrag=function(a){Blockly.Events.getGroup()||Blockly.Events.setGroup(!0);this.workspace_.setResizesEnabled(!1);Blockly.BlockSvg.disconnectUiStop_();this.draggingBlock_.getParent()&&(this.draggingBlock_.unplug(),a=this.pixelsToWorkspaceUnits_(a),a=goog.math.Coordinate.sum(this.startXY_,a),this.draggingBlock_.translate(a.x,a.y),this.draggingBlock_.disconnectUiEffect());this.draggingBlock_.setDragging(!0);this.draggingBlock_.moveToDragSurface_();this.workspace_.toolbox_&&
                +this.workspace_.toolbox_.addDeleteStyle()};Blockly.BlockDragger.prototype.dragBlock=function(a,b){var c=this.pixelsToWorkspaceUnits_(b),d=goog.math.Coordinate.sum(this.startXY_,c);this.draggingBlock_.moveDuringDrag(d);this.dragIcons_(c);this.deleteArea_=this.workspace_.isDeleteArea(a);this.draggedConnectionManager_.update(c,this.deleteArea_);this.updateCursorDuringBlockDrag_()};
                +Blockly.BlockDragger.prototype.endBlockDrag=function(a,b){this.dragBlock(a,b);this.dragIconData_=[];Blockly.BlockSvg.disconnectUiStop_();var c=this.pixelsToWorkspaceUnits_(b),d=goog.math.Coordinate.sum(this.startXY_,c);this.draggingBlock_.moveOffDragSurface_(d);this.maybeDeleteBlock_()||(this.draggingBlock_.moveConnections_(c.x,c.y),this.draggingBlock_.setDragging(!1),this.draggedConnectionManager_.applyConnections(),this.draggingBlock_.render(),this.fireMoveEvent_(),this.draggingBlock_.scheduleSnapAndBump());
                +this.workspace_.setResizesEnabled(!0);this.workspace_.toolbox_&&this.workspace_.toolbox_.removeDeleteStyle();Blockly.Events.setGroup(!1)};Blockly.BlockDragger.prototype.fireMoveEvent_=function(){var a=new Blockly.Events.BlockMove(this.draggingBlock_);a.oldCoordinate=this.startXY_;a.recordNew();Blockly.Events.fire(a)};
                +Blockly.BlockDragger.prototype.maybeDeleteBlock_=function(){var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(a&&goog.Timer.callOnce(a.close,100,a),this.fireMoveEvent_(),this.draggingBlock_.dispose(!1,!0)):a&&a.close();return this.wouldDeleteBlock_};
                +Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_=function(){this.wouldDeleteBlock_=this.draggedConnectionManager_.wouldDeleteBlock();var a=this.workspace_.trashcan;this.wouldDeleteBlock_?(this.draggingBlock_.setDeleteStyle(!0),this.deleteArea_==Blockly.DELETE_AREA_TRASH&&a&&a.setOpen_(!0)):(this.draggingBlock_.setDeleteStyle(!1),a&&a.setOpen_(!1))};
                +Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_=function(a){a=new goog.math.Coordinate(a.x/this.workspace_.scale,a.y/this.workspace_.scale);this.workspace_.isMutator&&(a=a.scale(1/this.workspace_.options.parentWorkspace.scale));return a};Blockly.BlockDragger.prototype.dragIcons_=function(a){for(var b=0;b<this.dragIconData_.length;b++){var c=this.dragIconData_[b];c.icon.setIconLocation(goog.math.Coordinate.sum(c.location,a))}};Blockly.constants={};Blockly.DRAG_RADIUS=5;Blockly.FLYOUT_DRAG_RADIUS=10;Blockly.SNAP_RADIUS=20;Blockly.BUMP_DELAY=250;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.DRAG_STACK=!0;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;Blockly.SPRITE={width:96,height:124,url:"sprites.png"};Blockly.SVG_NS="http://www.w3.org/2000/svg";Blockly.HTML_NS="http://www.w3.org/1999/xhtml";Blockly.INPUT_VALUE=1;Blockly.OUTPUT_VALUE=2;Blockly.NEXT_STATEMENT=3;
                +Blockly.PREVIOUS_STATEMENT=4;Blockly.DUMMY_INPUT=5;Blockly.ALIGN_LEFT=-1;Blockly.ALIGN_CENTRE=0;Blockly.ALIGN_RIGHT=1;Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE]=Blockly.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE]=Blockly.INPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT]=Blockly.PREVIOUS_STATEMENT;Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT]=Blockly.NEXT_STATEMENT;
                +Blockly.TOOLBOX_AT_TOP=0;Blockly.TOOLBOX_AT_BOTTOM=1;Blockly.TOOLBOX_AT_LEFT=2;Blockly.TOOLBOX_AT_RIGHT=3;Blockly.DELETE_AREA_NONE=null;Blockly.DELETE_AREA_TRASH=1;Blockly.DELETE_AREA_TOOLBOX=2;Blockly.VARIABLE_CATEGORY_NAME="VARIABLE";Blockly.PROCEDURE_CATEGORY_NAME="PROCEDURE";Blockly.RENAME_VARIABLE_ID="RENAME_VARIABLE_ID";Blockly.DELETE_VARIABLE_ID="DELETE_VARIABLE_ID";Blockly.WorkspaceDragger=function(a){this.workspace_=a;this.startDragMetrics_=a.getMetrics();this.startScrollXY_=new goog.math.Coordinate(a.scrollX,a.scrollY)};Blockly.WorkspaceDragger.prototype.dispose=function(){this.workspace_=null};Blockly.WorkspaceDragger.prototype.startDrag=function(){Blockly.selected&&Blockly.selected.unselect();this.workspace_.setupDragSurface()};Blockly.WorkspaceDragger.prototype.endDrag=function(a){this.drag(a);this.workspace_.resetDragSurface()};
                +Blockly.WorkspaceDragger.prototype.drag=function(a){var b=this.startDragMetrics_,c=goog.math.Coordinate.sum(this.startScrollXY_,a);a=Math.min(c.x,-b.contentLeft);c=Math.min(c.y,-b.contentTop);a=Math.max(a,b.viewWidth-b.contentLeft-b.contentWidth);c=Math.max(c,b.viewHeight-b.contentTop-b.contentHeight);a=-a-b.contentLeft;c=-c-b.contentTop;this.updateScroll_(a,c)};Blockly.WorkspaceDragger.prototype.updateScroll_=function(a,b){this.workspace_.scrollbar.set(a,b)};Blockly.FlyoutDragger=function(a){Blockly.FlyoutDragger.superClass_.constructor.call(this,a.getWorkspace());this.scrollbar_=a.scrollbar_;this.horizontalLayout_=a.horizontalLayout_};goog.inherits(Blockly.FlyoutDragger,Blockly.WorkspaceDragger);Blockly.FlyoutDragger.prototype.updateScroll_=function(a,b){this.horizontalLayout_?this.scrollbar_.set(a):this.scrollbar_.set(b)};Blockly.Tooltip={};Blockly.Tooltip.visible=!1;Blockly.Tooltip.blocked_=!1;Blockly.Tooltip.LIMIT=50;Blockly.Tooltip.mouseOutPid_=0;Blockly.Tooltip.showPid_=0;Blockly.Tooltip.lastX_=0;Blockly.Tooltip.lastY_=0;Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.OFFSET_X=0;Blockly.Tooltip.OFFSET_Y=10;Blockly.Tooltip.RADIUS_OK=10;Blockly.Tooltip.HOVER_MS=750;Blockly.Tooltip.MARGINS=5;Blockly.Tooltip.DIV=null;
                +Blockly.Tooltip.createDom=function(){Blockly.Tooltip.DIV||(Blockly.Tooltip.DIV=goog.dom.createDom("DIV","blocklyTooltipDiv"),document.body.appendChild(Blockly.Tooltip.DIV))};Blockly.Tooltip.bindMouseEvents=function(a){Blockly.bindEvent_(a,"mouseover",null,Blockly.Tooltip.onMouseOver_);Blockly.bindEvent_(a,"mouseout",null,Blockly.Tooltip.onMouseOut_);a.addEventListener("mousemove",Blockly.Tooltip.onMouseMove_,!1)};
                +Blockly.Tooltip.onMouseOver_=function(a){if(!Blockly.Tooltip.blocked_){for(a=a.target;!goog.isString(a.tooltip)&&!goog.isFunction(a.tooltip);)a=a.tooltip;Blockly.Tooltip.element_!=a&&(Blockly.Tooltip.hide(),Blockly.Tooltip.poisonedElement_=null,Blockly.Tooltip.element_=a);clearTimeout(Blockly.Tooltip.mouseOutPid_)}};
                +Blockly.Tooltip.onMouseOut_=function(a){Blockly.Tooltip.blocked_||(Blockly.Tooltip.mouseOutPid_=setTimeout(function(){Blockly.Tooltip.element_=null;Blockly.Tooltip.poisonedElement_=null;Blockly.Tooltip.hide()},1),clearTimeout(Blockly.Tooltip.showPid_))};
                +Blockly.Tooltip.onMouseMove_=function(a){if(Blockly.Tooltip.element_&&Blockly.Tooltip.element_.tooltip&&!Blockly.WidgetDiv.isVisible()&&!Blockly.Tooltip.blocked_)if(Blockly.Tooltip.visible){var b=Blockly.Tooltip.lastX_-a.pageX;a=Blockly.Tooltip.lastY_-a.pageY;Math.sqrt(b*b+a*a)>Blockly.Tooltip.RADIUS_OK&&Blockly.Tooltip.hide()}else Blockly.Tooltip.poisonedElement_!=Blockly.Tooltip.element_&&(clearTimeout(Blockly.Tooltip.showPid_),Blockly.Tooltip.lastX_=a.pageX,Blockly.Tooltip.lastY_=a.pageY,Blockly.Tooltip.showPid_=
                +setTimeout(Blockly.Tooltip.show_,Blockly.Tooltip.HOVER_MS))};Blockly.Tooltip.hide=function(){Blockly.Tooltip.visible&&(Blockly.Tooltip.visible=!1,Blockly.Tooltip.DIV&&(Blockly.Tooltip.DIV.style.display="none"));clearTimeout(Blockly.Tooltip.showPid_)};Blockly.Tooltip.block=function(){Blockly.Tooltip.hide();Blockly.Tooltip.blocked_=!0};Blockly.Tooltip.unblock=function(){Blockly.Tooltip.blocked_=!1};
                +Blockly.Tooltip.show_=function(){if(!Blockly.Tooltip.blocked_&&(Blockly.Tooltip.poisonedElement_=Blockly.Tooltip.element_,Blockly.Tooltip.DIV)){goog.dom.removeChildren(Blockly.Tooltip.DIV);for(var a=Blockly.Tooltip.element_.tooltip;goog.isFunction(a);)a=a();for(var a=Blockly.utils.wrap(a,Blockly.Tooltip.LIMIT),a=a.split("\n"),b=0;b<a.length;b++){var c=document.createElement("div");c.appendChild(document.createTextNode(a[b]));Blockly.Tooltip.DIV.appendChild(c)}a=Blockly.Tooltip.element_.RTL;b=goog.dom.getViewportSize();
                +Blockly.Tooltip.DIV.style.direction=a?"rtl":"ltr";Blockly.Tooltip.DIV.style.display="block";Blockly.Tooltip.visible=!0;var c=Blockly.Tooltip.lastX_,c=a?c-(Blockly.Tooltip.OFFSET_X+Blockly.Tooltip.DIV.offsetWidth):c+Blockly.Tooltip.OFFSET_X,d=Blockly.Tooltip.lastY_+Blockly.Tooltip.OFFSET_Y;d+Blockly.Tooltip.DIV.offsetHeight>b.height+window.scrollY&&(d-=Blockly.Tooltip.DIV.offsetHeight+2*Blockly.Tooltip.OFFSET_Y);a?c=Math.max(Blockly.Tooltip.MARGINS-window.scrollX,c):c+Blockly.Tooltip.DIV.offsetWidth>
                +b.width+window.scrollX-2*Blockly.Tooltip.MARGINS&&(c=b.width-Blockly.Tooltip.DIV.offsetWidth-2*Blockly.Tooltip.MARGINS);Blockly.Tooltip.DIV.style.top=d+"px";Blockly.Tooltip.DIV.style.left=c+"px"}};Blockly.Gesture=function(a,b){this.mouseDownXY_=null;this.currentDragDeltaXY_=0;this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=null;this.creatorWorkspace_=b;this.isDraggingBlock_=this.isDraggingWorkspace_=this.hasExceededDragRadius_=!1;this.mostRecentEvent_=a;this.flyout_=this.workspaceDragger_=this.blockDragger_=this.onUpWrapper_=this.onMoveWrapper_=null;this.isEnding_=this.hasStarted_=this.calledUpdateIsDragging_=!1};
                +Blockly.Gesture.prototype.dispose=function(){Blockly.Touch.clearTouchIdentifier();Blockly.Tooltip.unblock();this.creatorWorkspace_.clearGesture();this.onMoveWrapper_&&Blockly.unbindEvent_(this.onMoveWrapper_);this.onUpWrapper_&&Blockly.unbindEvent_(this.onUpWrapper_);this.flyout_=this.startWorkspace_=this.targetBlock_=this.startBlock_=this.startField_=null;this.blockDragger_&&(this.blockDragger_.dispose(),this.blockDragger_=null);this.workspaceDragger_&&(this.workspaceDragger_.dispose(),this.workspaceDragger_=
                +null)};Blockly.Gesture.prototype.updateFromEvent_=function(a){var b=new goog.math.Coordinate(a.clientX,a.clientY);this.updateDragDelta_(b)&&(this.updateIsDragging_(),Blockly.longStop_());this.mostRecentEvent_=a};
                +Blockly.Gesture.prototype.updateDragDelta_=function(a){this.currentDragDeltaXY_=goog.math.Coordinate.difference(a,this.mouseDownXY_);return this.hasExceededDragRadius_?!1:this.hasExceededDragRadius_=goog.math.Coordinate.magnitude(this.currentDragDeltaXY_)>(this.flyout_?Blockly.FLYOUT_DRAG_RADIUS:Blockly.DRAG_RADIUS)};
                +Blockly.Gesture.prototype.updateIsDraggingFromFlyout_=function(){return this.targetBlock_.disabled?!1:!this.flyout_.isScrollable()||this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)?(this.startWorkspace_=this.flyout_.targetWorkspace_,this.startWorkspace_.updateScreenCalculationsIfScrolled(),Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.startBlock_=null,this.targetBlock_=this.flyout_.createBlock(this.targetBlock_),this.targetBlock_.select(),!0):!1};
                +Blockly.Gesture.prototype.updateIsDraggingBlock_=function(){if(!this.targetBlock_)return!1;this.flyout_?this.isDraggingBlock_=this.updateIsDraggingFromFlyout_():this.targetBlock_.isMovable()&&(this.isDraggingBlock_=!0);return this.isDraggingBlock_?(this.startDraggingBlock_(),!0):!1};
                +Blockly.Gesture.prototype.updateIsDraggingWorkspace_=function(){if(this.flyout_?this.flyout_.isScrollable():this.startWorkspace_&&this.startWorkspace_.isDraggable())this.workspaceDragger_=this.flyout_?new Blockly.FlyoutDragger(this.flyout_):new Blockly.WorkspaceDragger(this.startWorkspace_),this.isDraggingWorkspace_=!0,this.workspaceDragger_.startDrag()};
                +Blockly.Gesture.prototype.updateIsDragging_=function(){goog.asserts.assert(!this.calledUpdateIsDragging_,"updateIsDragging_ should only be called once per gesture.");this.calledUpdateIsDragging_=!0;this.updateIsDraggingBlock_()||this.updateIsDraggingWorkspace_()};
                +Blockly.Gesture.prototype.startDraggingBlock_=function(){this.blockDragger_=new Blockly.BlockDragger(this.targetBlock_,this.startWorkspace_);this.blockDragger_.startBlockDrag(this.currentDragDeltaXY_);this.blockDragger_.dragBlock(this.mostRecentEvent_,this.currentDragDeltaXY_)};
                +Blockly.Gesture.prototype.doStart=function(a){Blockly.utils.isTargetInput(a)?this.cancel():(this.hasStarted_=!0,Blockly.BlockSvg.disconnectUiStop_(),this.startWorkspace_.updateScreenCalculationsIfScrolled(),this.startWorkspace_.isMutator&&this.startWorkspace_.resize(),this.startWorkspace_.markFocused(),this.mostRecentEvent_=a,Blockly.hideChaff(!!this.flyout_),Blockly.Tooltip.block(),this.targetBlock_&&this.targetBlock_.select(),Blockly.utils.isRightButton(a)?this.handleRightClick(a):(goog.string.caseInsensitiveEquals(a.type,
                +"touchstart")&&Blockly.longStart_(a,this),this.mouseDownXY_=new goog.math.Coordinate(a.clientX,a.clientY),this.onMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",null,this.handleMove.bind(this)),this.onUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",null,this.handleUp.bind(this)),a.preventDefault(),a.stopPropagation()))};
                +Blockly.Gesture.prototype.handleMove=function(a){this.updateFromEvent_(a);this.isDraggingWorkspace_?this.workspaceDragger_.drag(this.currentDragDeltaXY_):this.isDraggingBlock_&&this.blockDragger_.dragBlock(this.mostRecentEvent_,this.currentDragDeltaXY_);a.preventDefault();a.stopPropagation()};
                +Blockly.Gesture.prototype.handleUp=function(a){this.updateFromEvent_(a);Blockly.longStop_();this.isEnding_?console.log("Trying to end a gesture recursively."):(this.isEnding_=!0,this.isDraggingBlock_?this.blockDragger_.endBlockDrag(a,this.currentDragDeltaXY_):this.isDraggingWorkspace_?this.workspaceDragger_.endDrag(this.currentDragDeltaXY_):this.isFieldClick_()?this.doFieldClick_():this.isBlockClick_()?this.doBlockClick_():this.isWorkspaceClick_()&&this.doWorkspaceClick_(),a.preventDefault(),a.stopPropagation(),
                +this.dispose())};Blockly.Gesture.prototype.cancel=function(){this.isEnding_||(Blockly.longStop_(),this.isDraggingBlock_?this.blockDragger_.endBlockDrag(this.mostRecentEvent_,this.currentDragDeltaXY_):this.isDraggingWorkspace_&&this.workspaceDragger_.endDrag(this.currentDragDeltaXY_),this.dispose())};
                +Blockly.Gesture.prototype.handleRightClick=function(a){this.targetBlock_?(this.bringBlockToFront_(),Blockly.hideChaff(this.flyout_),this.targetBlock_.showContextMenu_(a)):this.startWorkspace_&&!this.flyout_&&(Blockly.hideChaff(),this.startWorkspace_.showContextMenu_(a));a.preventDefault();a.stopPropagation();this.dispose()};
                +Blockly.Gesture.prototype.handleWsStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleWsStart, but the gesture had already been started.");this.setStartWorkspace_(b);this.mostRecentEvent_=a;this.doStart(a)};Blockly.Gesture.prototype.handleFlyoutStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleFlyoutStart, but the gesture had already been started.");this.setStartFlyout_(b);this.handleWsStart(a,b.getWorkspace())};
                +Blockly.Gesture.prototype.handleBlockStart=function(a,b){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.handleBlockStart, but the gesture had already been started.");this.setStartBlock(b);this.mostRecentEvent_=a};Blockly.Gesture.prototype.doFieldClick_=function(){this.startField_.showEditor_();this.bringBlockToFront_()};
                +Blockly.Gesture.prototype.doBlockClick_=function(){this.flyout_&&this.flyout_.autoClose?this.targetBlock_.disabled||(Blockly.Events.getGroup()||Blockly.Events.setGroup(!0),this.flyout_.createBlock(this.targetBlock_).scheduleSnapAndBump()):Blockly.Events.fire(new Blockly.Events.Ui(this.startBlock_,"click",void 0,void 0));this.bringBlockToFront_();Blockly.Events.setGroup(!1)};Blockly.Gesture.prototype.doWorkspaceClick_=function(){Blockly.selected&&Blockly.selected.unselect()};
                +Blockly.Gesture.prototype.bringBlockToFront_=function(){this.targetBlock_&&!this.flyout_&&this.targetBlock_.bringToFront()};Blockly.Gesture.prototype.setStartField=function(a){goog.asserts.assert(!this.hasStarted_,"Tried to call gesture.setStartField, but the gesture had already been started.");this.startField_||(this.startField_=a)};Blockly.Gesture.prototype.setStartBlock=function(a){this.startBlock_||(this.startBlock_=a,a.isInFlyout&&a!=a.getRootBlock()?this.setTargetBlock_(a.getRootBlock()):this.setTargetBlock_(a))};
                +Blockly.Gesture.prototype.setTargetBlock_=function(a){a.isShadow()?this.setTargetBlock_(a.getParent()):this.targetBlock_=a};Blockly.Gesture.prototype.setStartWorkspace_=function(a){this.startWorkspace_||(this.startWorkspace_=a)};Blockly.Gesture.prototype.setStartFlyout_=function(a){this.flyout_||(this.flyout_=a)};Blockly.Gesture.prototype.isBlockClick_=function(){return!!this.startBlock_&&!this.hasExceededDragRadius_&&!this.isFieldClick_()};
                +Blockly.Gesture.prototype.isFieldClick_=function(){return(this.startField_?this.startField_.isCurrentlyEditable():!1)&&!this.hasExceededDragRadius_&&(!this.flyout_||!this.flyout_.autoClose)};Blockly.Gesture.prototype.isWorkspaceClick_=function(){return!this.startBlock_&&!this.startField_&&!this.hasExceededDragRadius_};Blockly.Gesture.prototype.isDragging=function(){return this.isDraggingWorkspace_||this.isDraggingBlock_};Blockly.Gesture.prototype.hasStarted=function(){return this.hasStarted_};Blockly.Field=function(a,b){this.size_=new goog.math.Size(0,Blockly.BlockSvg.MIN_BLOCK_Y);this.setValue(a);this.setValidator(b)};Blockly.Field.cacheWidths_=null;Blockly.Field.cacheReference_=0;Blockly.Field.prototype.name=void 0;Blockly.Field.prototype.maxDisplayLength=50;Blockly.Field.prototype.text_="";Blockly.Field.prototype.sourceBlock_=null;Blockly.Field.prototype.visible_=!0;Blockly.Field.prototype.validator_=null;Blockly.Field.NBSP="\u00a0";Blockly.Field.prototype.EDITABLE=!0;
                +Blockly.Field.prototype.setSourceBlock=function(a){goog.asserts.assert(!this.sourceBlock_,"Field already bound to a block.");this.sourceBlock_=a};
                +Blockly.Field.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=Blockly.utils.createSvgElement("g",{},null),this.visible_||(this.fieldGroup_.style.display="none"),this.borderRect_=Blockly.utils.createSvgElement("rect",{rx:4,ry:4,x:-Blockly.BlockSvg.SEP_SPACE_X/2,y:0,height:16},this.fieldGroup_,this.sourceBlock_.workspace),this.textElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText",y:this.size_.height-12.5},this.fieldGroup_),this.updateEditable(),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),
                +this.mouseDownWrapper_=Blockly.bindEventWithChecks_(this.fieldGroup_,"mousedown",this,this.onMouseDown_),this.render_())};Blockly.Field.prototype.initModel=function(){};Blockly.Field.prototype.dispose=function(){this.mouseDownWrapper_&&(Blockly.unbindEvent_(this.mouseDownWrapper_),this.mouseDownWrapper_=null);this.sourceBlock_=null;goog.dom.removeNode(this.fieldGroup_);this.validator_=this.borderRect_=this.textElement_=this.fieldGroup_=null};
                +Blockly.Field.prototype.updateEditable=function(){var a=this.fieldGroup_;this.EDITABLE&&a&&(this.sourceBlock_.isEditable()?(Blockly.utils.addClass(a,"blocklyEditableText"),Blockly.utils.removeClass(a,"blocklyNonEditableText"),this.fieldGroup_.style.cursor=this.CURSOR):(Blockly.utils.addClass(a,"blocklyNonEditableText"),Blockly.utils.removeClass(a,"blocklyEditableText"),this.fieldGroup_.style.cursor=""))};
                +Blockly.Field.prototype.isCurrentlyEditable=function(){return this.EDITABLE&&!!this.sourceBlock_&&this.sourceBlock_.isEditable()};Blockly.Field.prototype.isVisible=function(){return this.visible_};Blockly.Field.prototype.setVisible=function(a){if(this.visible_!=a){this.visible_=a;var b=this.getSvgRoot();b&&(b.style.display=a?"block":"none",this.render_())}};Blockly.Field.prototype.setValidator=function(a){this.validator_=a};Blockly.Field.prototype.getValidator=function(){return this.validator_};
                +Blockly.Field.prototype.classValidator=function(a){return a};Blockly.Field.prototype.callValidator=function(a){var b=this.classValidator(a);if(null===b)return null;void 0!==b&&(a=b);if(b=this.getValidator()){b=b.call(this,a);if(null===b)return null;void 0!==b&&(a=b)}return a};Blockly.Field.prototype.getSvgRoot=function(){return this.fieldGroup_};
                +Blockly.Field.prototype.render_=function(){if(this.visible_){goog.dom.removeChildren(this.textElement_);var a=document.createTextNode(this.getDisplayText_());this.textElement_.appendChild(a);this.updateWidth()}else this.size_.width=0};Blockly.Field.prototype.updateWidth=function(){var a=Blockly.Field.getCachedWidth(this.textElement_);this.borderRect_&&this.borderRect_.setAttribute("width",a+Blockly.BlockSvg.SEP_SPACE_X);this.size_.width=a};
                +Blockly.Field.getCachedWidth=function(a){var b=a.textContent+"\n"+a.className.baseVal,c;if(Blockly.Field.cacheWidths_&&(c=Blockly.Field.cacheWidths_[b]))return c;try{c=a.getComputedTextLength()}catch(d){return 8*a.textContent.length}Blockly.Field.cacheWidths_&&(Blockly.Field.cacheWidths_[b]=c);return c};Blockly.Field.startCache=function(){Blockly.Field.cacheReference_++;Blockly.Field.cacheWidths_||(Blockly.Field.cacheWidths_={})};
                +Blockly.Field.stopCache=function(){Blockly.Field.cacheReference_--;Blockly.Field.cacheReference_||(Blockly.Field.cacheWidths_=null)};Blockly.Field.prototype.getSize=function(){this.size_.width||this.render_();return this.size_};Blockly.Field.prototype.getScaledBBox_=function(){var a=this.borderRect_.getBBox();return new goog.math.Size(a.width*this.sourceBlock_.workspace.scale,a.height*this.sourceBlock_.workspace.scale)};
                +Blockly.Field.prototype.getDisplayText_=function(){var a=this.text_;if(!a)return Blockly.Field.NBSP;a.length>this.maxDisplayLength&&(a=a.substring(0,this.maxDisplayLength-2)+"\u2026");a=a.replace(/\s/g,Blockly.Field.NBSP);this.sourceBlock_.RTL&&(a+="\u200f");return a};Blockly.Field.prototype.getText=function(){return this.text_};
                +Blockly.Field.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.text_=a,this.size_.width=0,this.sourceBlock_&&this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_())))};Blockly.Field.prototype.getValue=function(){return this.getText()};
                +Blockly.Field.prototype.setValue=function(a){if(null!==a){var b=this.getValue();b!=a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,b,a)),this.setText(a))}};Blockly.Field.prototype.onMouseDown_=function(a){this.sourceBlock_&&this.sourceBlock_.workspace&&(a=this.sourceBlock_.workspace.getGesture(a))&&a.setStartField(this)};Blockly.Field.prototype.setTooltip=function(a){};
                +Blockly.Field.prototype.getAbsoluteXY_=function(){return goog.style.getPageOffset(this.borderRect_)};Blockly.FieldLabel=function(a,b){this.size_=new goog.math.Size(0,17.5);this.class_=b;this.setValue(a)};goog.inherits(Blockly.FieldLabel,Blockly.Field);Blockly.FieldLabel.prototype.EDITABLE=!1;
                +Blockly.FieldLabel.prototype.init=function(){this.textElement_||(this.textElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText",y:this.size_.height-5},null),this.class_&&Blockly.utils.addClass(this.textElement_,this.class_),this.visible_||(this.textElement_.style.display="none"),this.sourceBlock_.getSvgRoot().appendChild(this.textElement_),this.textElement_.tooltip=this.sourceBlock_,Blockly.Tooltip.bindMouseEvents(this.textElement_),this.render_())};
                +Blockly.FieldLabel.prototype.dispose=function(){goog.dom.removeNode(this.textElement_);this.textElement_=null};Blockly.FieldLabel.prototype.getSvgRoot=function(){return this.textElement_};Blockly.FieldLabel.prototype.setTooltip=function(a){this.textElement_.tooltip=a};Blockly.Input=function(a,b,c,d){if(a!=Blockly.DUMMY_INPUT&&!b)throw"Value inputs and statement inputs must have non-empty name.";this.type=a;this.name=b;this.sourceBlock_=c;this.connection=d;this.fieldRow=[]};Blockly.Input.prototype.align=Blockly.ALIGN_LEFT;Blockly.Input.prototype.visible_=!0;Blockly.Input.prototype.appendField=function(a,b){this.insertFieldAt(this.fieldRow.length,a,b);return this};
                +Blockly.Input.prototype.insertFieldAt=function(a,b,c){if(0>a||a>this.fieldRow.length)throw Error("index "+a+" out of bounds.");if(!b&&!c)return this;goog.isString(b)&&(b=new Blockly.FieldLabel(b));b.setSourceBlock(this.sourceBlock_);this.sourceBlock_.rendered&&b.init();b.name=c;b.prefixField&&(a=this.insertFieldAt(a,b.prefixField));this.fieldRow.splice(a,0,b);++a;b.suffixField&&(a=this.insertFieldAt(a,b.suffixField));this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());
                +return a};Blockly.Input.prototype.removeField=function(a){for(var b=0,c;c=this.fieldRow[b];b++)if(c.name===a){c.dispose();this.fieldRow.splice(b,1);this.sourceBlock_.rendered&&(this.sourceBlock_.render(),this.sourceBlock_.bumpNeighbours_());return}goog.asserts.fail('Field "%s" not found.',a)};Blockly.Input.prototype.isVisible=function(){return this.visible_};
                +Blockly.Input.prototype.setVisible=function(a){var b=[];if(this.visible_==a)return b;for(var c=(this.visible_=a)?"block":"none",d=0,e;e=this.fieldRow[d];d++)e.setVisible(a);this.connection&&(a?b=this.connection.unhideAll():this.connection.hideAll(),d=this.connection.targetBlock())&&(d.getSvgRoot().style.display=c,a||(d.rendered=!1));return b};Blockly.Input.prototype.setCheck=function(a){if(!this.connection)throw"This input does not have a connection.";this.connection.setCheck(a);return this};
                +Blockly.Input.prototype.setAlign=function(a){this.align=a;this.sourceBlock_.rendered&&this.sourceBlock_.render();return this};Blockly.Input.prototype.init=function(){if(this.sourceBlock_.workspace.rendered)for(var a=0;a<this.fieldRow.length;a++)this.fieldRow[a].init()};Blockly.Input.prototype.dispose=function(){for(var a=0,b;b=this.fieldRow[a];a++)b.dispose();this.connection&&this.connection.dispose();this.sourceBlock_=null};Blockly.ConnectionDB=function(){};Blockly.ConnectionDB.prototype=[];Blockly.ConnectionDB.constructor=Blockly.ConnectionDB;Blockly.ConnectionDB.prototype.addConnection=function(a){if(a.inDB_)throw"Connection already in database.";if(!a.getSourceBlock().isInFlyout){var b=this.findPositionForConnection_(a);this.splice(b,0,a);a.inDB_=!0}};
                +Blockly.ConnectionDB.prototype.findConnection=function(a){if(!this.length)return-1;var b=this.findPositionForConnection_(a);if(b>=this.length)return-1;for(var c=a.y_,d=b;0<=d&&this[d].y_==c;){if(this[d]==a)return d;d--}for(;b<this.length&&this[b].y_==c;){if(this[b]==a)return b;b++}return-1};
                +Blockly.ConnectionDB.prototype.findPositionForConnection_=function(a){if(!this.length)return 0;for(var b=0,c=this.length;b<c;){var d=Math.floor((b+c)/2);if(this[d].y_<a.y_)b=d+1;else if(this[d].y_>a.y_)c=d;else{b=d;break}}return b};Blockly.ConnectionDB.prototype.removeConnection_=function(a){if(!a.inDB_)throw"Connection not in database.";var b=this.findConnection(a);if(-1==b)throw"Unable to find connection in connectionDB.";a.inDB_=!1;this.splice(b,1)};
                +Blockly.ConnectionDB.prototype.getNeighbours=function(a,b){function c(a){var c=e-d[a].x_,g=f-d[a].y_;Math.sqrt(c*c+g*g)<=b&&l.push(d[a]);return g<b}for(var d=this,e=a.x_,f=a.y_,g=0,h=d.length-2,k=h;g<k;)d[k].y_<f?g=k:h=k,k=Math.floor((g+h)/2);var l=[],h=g=k;if(d.length){for(;0<=g&&c(g);)g--;do h++;while(h<d.length&&c(h))}return l};Blockly.ConnectionDB.prototype.isInYRange_=function(a,b,c){return Math.abs(this[a].y_-b)<=c};
                +Blockly.ConnectionDB.prototype.searchForClosest=function(a,b,c){if(!this.length)return{connection:null,radius:b};var d=a.y_,e=a.x_;a.x_=e+c.x;a.y_=d+c.y;var f=this.findPositionForConnection_(a);c=null;for(var g=b,h,k=f-1;0<=k&&this.isInYRange_(k,a.y_,b);)h=this[k],a.isConnectionAllowed(h,g)&&(c=h,g=h.distanceFrom(a)),k--;for(;f<this.length&&this.isInYRange_(f,a.y_,b);)h=this[f],a.isConnectionAllowed(h,g)&&(c=h,g=h.distanceFrom(a)),f++;a.x_=e;a.y_=d;return{connection:c,radius:g}};
                +Blockly.ConnectionDB.init=function(a){var b=[];b[Blockly.INPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.OUTPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.NEXT_STATEMENT]=new Blockly.ConnectionDB;b[Blockly.PREVIOUS_STATEMENT]=new Blockly.ConnectionDB;a.connectionDBList=b};Blockly.utils={};Blockly.utils.removeAttribute=function(a,b){goog.userAgent.IE&&goog.userAgent.isVersion("10.0")?a.setAttribute(b,null):a.removeAttribute(b)};Blockly.utils.addClass=function(a,b){var c=a.getAttribute("class")||"";if(-1!=(" "+c+" ").indexOf(" "+b+" "))return!1;c&&(c+=" ");a.setAttribute("class",c+b);return!0};
                +Blockly.utils.removeClass=function(a,b){var c=a.getAttribute("class");if(-1==(" "+c+" ").indexOf(" "+b+" "))return!1;for(var c=c.split(/\s+/),d=0;d<c.length;d++)c[d]&&c[d]!=b||(c.splice(d,1),d--);c.length?a.setAttribute("class",c.join(" ")):Blockly.utils.removeAttribute(a,"class");return!0};Blockly.utils.hasClass=function(a,b){return-1!=(" "+a.getAttribute("class")+" ").indexOf(" "+b+" ")};Blockly.utils.noEvent=function(a){a.preventDefault();a.stopPropagation()};
                +Blockly.utils.isTargetInput=function(a){return"textarea"==a.target.type||"text"==a.target.type||"number"==a.target.type||"email"==a.target.type||"password"==a.target.type||"search"==a.target.type||"tel"==a.target.type||"url"==a.target.type||a.target.isContentEditable};
                +Blockly.utils.getRelativeXY=function(a){var b=new goog.math.Coordinate(0,0),c=a.getAttribute("x");c&&(b.x=parseInt(c,10));if(c=a.getAttribute("y"))b.y=parseInt(c,10);if(c=(c=a.getAttribute("transform"))&&c.match(Blockly.utils.getRelativeXY.XY_REGEX_))b.x+=parseFloat(c[1]),c[3]&&(b.y+=parseFloat(c[3]));(a=a.getAttribute("style"))&&-1<a.indexOf("translate")&&((c=a.match(Blockly.utils.getRelativeXY.XY_2D_REGEX_))||(c=a.match(Blockly.utils.getRelativeXY.XY_3D_REGEX_)),c&&(b.x+=parseFloat(c[1]),c[3]&&
                +(b.y+=parseFloat(c[3]))));return b};Blockly.utils.getInjectionDivXY_=function(a){for(var b=0,c=0,d;a;){var e=Blockly.utils.getRelativeXY(a);d=Blockly.utils.getScale_(a);b=b*d+e.x;c=c*d+e.y;if(-1!=(" "+(a.getAttribute("class")||"")+" ").indexOf(" injectionDiv "))break;a=a.parentNode}return new goog.math.Coordinate(b,c)};Blockly.utils.getScale_=function(a){var b=1;(a=a.getAttribute("transform"))&&(a=a.match(Blockly.utils.getScale_.REGEXP_))&&a[0]&&(b=parseFloat(a[0]));return b};
                +Blockly.utils.getRelativeXY.XY_REGEX_=/translate\(\s*([-+\d.e]+)([ ,]\s*([-+\d.e]+)\s*\))?/;Blockly.utils.getScale_REGEXP_=/scale\(\s*([-+\d.e]+)\s*\)/;Blockly.utils.getRelativeXY.XY_3D_REGEX_=/transform:\s*translate3d\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;Blockly.utils.getRelativeXY.XY_2D_REGEX_=/transform:\s*translate\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;
                +Blockly.utils.createSvgElement=function(a,b,c){a=document.createElementNS(Blockly.SVG_NS,a);for(var d in b)a.setAttribute(d,b[d]);document.body.runtimeStyle&&(a.runtimeStyle=a.currentStyle=a.style);c&&c.appendChild(a);return a};Blockly.utils.isRightButton=function(a){return a.ctrlKey&&goog.userAgent.MAC?!0:2==a.button};Blockly.utils.mouseToSvg=function(a,b,c){var d=b.createSVGPoint();d.x=a.clientX;d.y=a.clientY;c||(c=b.getScreenCTM().inverse());return d.matrixTransform(c)};
                +Blockly.utils.shortestStringLength=function(a){return a.length?a.reduce(function(a,c){return a.length<c.length?a:c}).length:0};Blockly.utils.commonWordPrefix=function(a,b){if(!a.length)return 0;if(1==a.length)return a[0].length;for(var c=0,d=b||Blockly.utils.shortestStringLength(a),e=0;e<d;e++){var f=a[0][e];for(var g=1;g<a.length;g++)if(f!=a[g][e])return c;" "==f&&(c=e+1)}for(g=1;g<a.length;g++)if((f=a[g][e])&&" "!=f)return c;return d};
                +Blockly.utils.commonWordSuffix=function(a,b){if(!a.length)return 0;if(1==a.length)return a[0].length;for(var c=0,d=b||Blockly.utils.shortestStringLength(a),e=0;e<d;e++){var f=a[0].substr(-e-1,1);for(var g=1;g<a.length;g++)if(f!=a[g].substr(-e-1,1))return c;" "==f&&(c=e+1)}for(g=1;g<a.length;g++)if((f=a[g].charAt(a[g].length-e-1))&&" "!=f)return c;return d};Blockly.utils.tokenizeInterpolation=function(a){return Blockly.utils.tokenizeInterpolation_(a,!0)};
                +Blockly.utils.replaceMessageReferences=function(a){if(!goog.isString(a))return a;a=Blockly.utils.tokenizeInterpolation_(a,!1);return a.length?a[0]:""};Blockly.utils.checkMessageReferences=function(a){for(var b=!0,c=/%{BKY_([a-zA-Z][a-zA-Z0-9_]*)}/g,d=c.exec(a);null!=d;){var e=d[1];null==Blockly.Msg[e]&&(console.log("WARNING: No message string for %{BKY_"+e+"}."),b=!1);a=a.substring(d.index+e.length+1);d=c.exec(a)}return b};
                +Blockly.utils.tokenizeInterpolation_=function(a,b){var c=[],d=a.split("");d.push("");for(var e=0,f=[],g=null,h=0;h<d.length;h++){var k=d[h];0==e?"%"==k?((k=f.join(""))&&c.push(k),f.length=0,e=1):f.push(k):1==e?"%"==k?(f.push(k),e=0):b&&"0"<=k&&"9">=k?(e=2,g=k,(k=f.join(""))&&c.push(k),f.length=0):"{"==k?e=3:(f.push("%",k),e=0):2==e?"0"<=k&&"9">=k?g+=k:(c.push(parseInt(g,10)),h--,e=0):3==e&&(""==k?(f.splice(0,0,"%{"),h--,e=0):"}"!=k?f.push(k):(k=f.join(""),/[a-zA-Z][a-zA-Z0-9_]*/.test(k)?(e=k.toUpperCase(),
                +(e=goog.string.startsWith(e,"BKY_")?e.substring(4):null)&&e in Blockly.Msg?(k=Blockly.Msg[e],goog.isString(k)?Array.prototype.push.apply(c,Blockly.utils.tokenizeInterpolation(k)):b?c.push(String(k)):c.push(k)):c.push("%{"+k+"}")):c.push("%{"+k+"}"),e=f.length=0))}(k=f.join(""))&&c.push(k);d=[];for(h=f.length=0;h<c.length;++h)"string"==typeof c[h]?f.push(c[h]):((k=f.join(""))&&d.push(k),f.length=0,d.push(c[h]));(k=f.join(""))&&d.push(k);f.length=0;return d};
                +Blockly.utils.genUid=function(){for(var a=Blockly.utils.genUid.soup_.length,b=[],c=0;20>c;c++)b[c]=Blockly.utils.genUid.soup_.charAt(Math.random()*a);return b.join("")};Blockly.utils.genUid.soup_="!#$%()*+,-./:;=?@[]^_`{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Blockly.utils.wrap=function(a,b){for(var c=a.split("\n"),d=0;d<c.length;d++)c[d]=Blockly.utils.wrapLine_(c[d],b);return c.join("\n")};
                +Blockly.utils.wrapLine_=function(a,b){if(a.length<=b)return a;for(var c=a.trim().split(/\s+/),d=0;d<c.length;d++)c[d].length>b&&(b=c[d].length);var d=-Infinity,e=1;do{var f=d;var g=a;for(var h=[],k=c.length/e,l=1,d=0;d<c.length-1;d++)l<(d+1.5)/k?(l++,h[d]=!0):h[d]=!1;h=Blockly.utils.wrapMutate_(c,h,b);d=Blockly.utils.wrapScore_(c,h,b);a=Blockly.utils.wrapToText_(c,h);e++}while(d>f);return g};
                +Blockly.utils.wrapScore_=function(a,b,c){for(var d=[0],e=[],f=0;f<a.length;f++)d[d.length-1]+=a[f].length,!0===b[f]?(d.push(0),e.push(a[f].charAt(a[f].length-1))):!1===b[f]&&d[d.length-1]++;a=Math.max.apply(Math,d);for(f=b=0;f<d.length;f++)b-=2*Math.pow(Math.abs(c-d[f]),1.5),b-=Math.pow(a-d[f],1.5),-1!=".?!".indexOf(e[f])?b+=c/3:-1!=",;)]}".indexOf(e[f])&&(b+=c/4);1<d.length&&d[d.length-1]<=d[d.length-2]&&(b+=.5);return b};
                +Blockly.utils.wrapMutate_=function(a,b,c){for(var d=Blockly.utils.wrapScore_(a,b,c),e,f=0;f<b.length-1;f++)if(b[f]!=b[f+1]){var g=[].concat(b);g[f]=!g[f];g[f+1]=!g[f+1];var h=Blockly.utils.wrapScore_(a,g,c);h>d&&(d=h,e=g)}return e?Blockly.utils.wrapMutate_(a,e,c):b};Blockly.utils.wrapToText_=function(a,b){for(var c=[],d=0;d<a.length;d++)c.push(a[d]),void 0!==b[d]&&c.push(b[d]?"\n":" ");return c.join("")};
                +Blockly.utils.is3dSupported=function(){if(void 0!==Blockly.utils.is3dSupported.cached_)return Blockly.utils.is3dSupported.cached_;if(!goog.global.getComputedStyle)return!1;var a=document.createElement("p"),b="none",c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(a,null);for(var d in c)if(void 0!==a.style[d]){a.style[d]="translate3d(1px,1px,1px)";b=goog.global.getComputedStyle(a);
                +if(!b)return document.body.removeChild(a),!1;b=b.getPropertyValue(c[d])}document.body.removeChild(a);Blockly.utils.is3dSupported.cached_="none"!==b;return Blockly.utils.is3dSupported.cached_};Blockly.utils.insertAfter_=function(a,b){var c=b.nextSibling,d=b.parentNode;if(!d)throw"Reference node has no parent.";c?d.insertBefore(a,c):d.appendChild(a)};
                +Blockly.utils.runAfterPageLoad=function(a){if(!document)throw Error("Blockly.utils.runAfterPageLoad() requires browser document.");if("complete"===document.readyState)a();else var b=setInterval(function(){"complete"===document.readyState&&(clearInterval(b),a())},10)};Blockly.utils.setCssTransform=function(a,b){a.style.transform=b;a.style["-webkit-transform"]=b};Blockly.Grid=function(a,b){this.gridPattern_=a;this.spacing_=b.spacing;this.length_=b.length;this.line2_=(this.line1_=a.firstChild)&&this.line1_.nextSibling;this.snapToGrid_=b.snap};Blockly.Grid.prototype.scale_=1;Blockly.Grid.prototype.dispose=function(){this.gridPattern_=null};Blockly.Grid.prototype.shouldSnap=function(){return this.snapToGrid_};Blockly.Grid.prototype.getSpacing=function(){return this.spacing_};Blockly.Grid.prototype.getPatternId=function(){return this.gridPattern_.id};
                +Blockly.Grid.prototype.update=function(a){this.scale_=a;var b=this.spacing_*a||100;this.gridPattern_.setAttribute("width",b);this.gridPattern_.setAttribute("height",b);var b=Math.floor(this.spacing_/2)+.5,c=b-this.length_/2,d=b+this.length_/2,b=b*a,c=c*a,d=d*a;this.setLineAttributes_(this.line1_,a,c,d,b,b);this.setLineAttributes_(this.line2_,a,b,b,c,d)};
                +Blockly.Grid.prototype.setLineAttributes_=function(a,b,c,d,e,f){a&&(a.setAttribute("stroke-width",b),a.setAttribute("x1",c),a.setAttribute("y1",e),a.setAttribute("x2",d),a.setAttribute("y2",f))};Blockly.Grid.prototype.moveTo=function(a,b){this.gridPattern_.setAttribute("x",a);this.gridPattern_.setAttribute("y",b);(goog.userAgent.IE||goog.userAgent.EDGE)&&this.update(this.scale_)};
                +Blockly.Grid.createDom=function(a,b,c){a=Blockly.utils.createSvgElement("pattern",{id:"blocklyGridPattern"+a,patternUnits:"userSpaceOnUse"},c);0<b.length&&0<b.spacing&&(Blockly.utils.createSvgElement("line",{stroke:b.colour},a),1<b.length&&Blockly.utils.createSvgElement("line",{stroke:b.colour},a));return a};Blockly.Options=function(a){var b,c,d,e,f,g=!!a.readOnly;if(g){var h=null;var k=b=c=d=e=f=!1}else h=Blockly.Options.parseToolboxTree(a.toolbox),f=!(!h||!h.getElementsByTagName("category").length),e=a.trashcan,void 0===e&&(e=f),d=a.collapse,void 0===d&&(d=f),c=a.comments,void 0===c&&(c=f),b=a.disable,void 0===b&&(b=f),k=a.sounds,void 0===k&&(k=!0);var l=!!a.rtl,m=a.horizontalLayout;void 0===m&&(m=!1);var n=a.toolboxPosition;n="end"===n?!1:!0;var p=m?n?Blockly.TOOLBOX_AT_TOP:Blockly.TOOLBOX_AT_BOTTOM:
                +n==l?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT;var q=a.scrollbars;void 0===q&&(q=f);var t=a.css;void 0===t&&(t=!0);var r="https://blockly-demo.appspot.com/static/media/";a.media?r=a.media:a.path&&(r=a.path+"media/");n=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex;this.RTL=l;this.oneBasedIndex=n;this.collapse=d;this.comments=c;this.disable=b;this.readOnly=g;this.maxBlocks=a.maxBlocks||Infinity;this.pathToMedia=r;this.hasCategories=f;this.hasScrollbars=q;this.hasTrashcan=e;this.hasSounds=k;this.hasCss=
                +t;this.horizontalLayout=m;this.languageTree=h;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=p};Blockly.Options.prototype.parentWorkspace=null;Blockly.Options.prototype.setMetrics=null;Blockly.Options.prototype.getMetrics=null;
                +Blockly.Options.parseZoomOptions_=function(a){a=a.zoom||{};var b={};b.controls=void 0===a.controls?!1:!!a.controls;b.wheel=void 0===a.wheel?!1:!!a.wheel;b.startScale=void 0===a.startScale?1:parseFloat(a.startScale);b.maxScale=void 0===a.maxScale?3:parseFloat(a.maxScale);b.minScale=void 0===a.minScale?.3:parseFloat(a.minScale);b.scaleSpeed=void 0===a.scaleSpeed?1.2:parseFloat(a.scaleSpeed);return b};
                +Blockly.Options.parseGridOptions_=function(a){a=a.grid||{};var b={};b.spacing=parseFloat(a.spacing)||0;b.colour=a.colour||"#888";b.length=parseFloat(a.length)||1;b.snap=0<b.spacing&&!!a.snap;return b};Blockly.Options.parseToolboxTree=function(a){a?("string"!=typeof a&&("undefined"==typeof XSLTProcessor&&a.outerHTML?a=a.outerHTML:a instanceof Element||(a=null)),"string"==typeof a&&(a=Blockly.Xml.textToDom(a))):a=null;return a};Blockly.ScrollbarPair=function(a){this.workspace_=a;this.hScroll=new Blockly.Scrollbar(a,!0,!0,"blocklyMainWorkspaceScrollbar");this.vScroll=new Blockly.Scrollbar(a,!1,!0,"blocklyMainWorkspaceScrollbar");this.corner_=Blockly.utils.createSvgElement("rect",{height:Blockly.Scrollbar.scrollbarThickness,width:Blockly.Scrollbar.scrollbarThickness,"class":"blocklyScrollbarBackground"},null);Blockly.utils.insertAfter_(this.corner_,a.getBubbleCanvas())};Blockly.ScrollbarPair.prototype.oldHostMetrics_=null;
                +Blockly.ScrollbarPair.prototype.dispose=function(){goog.dom.removeNode(this.corner_);this.oldHostMetrics_=this.workspace_=this.corner_=null;this.hScroll.dispose();this.hScroll=null;this.vScroll.dispose();this.vScroll=null};
                +Blockly.ScrollbarPair.prototype.resize=function(){var a=this.workspace_.getMetrics();if(a){var b=!1,c=!1;this.oldHostMetrics_&&this.oldHostMetrics_.viewWidth==a.viewWidth&&this.oldHostMetrics_.viewHeight==a.viewHeight&&this.oldHostMetrics_.absoluteTop==a.absoluteTop&&this.oldHostMetrics_.absoluteLeft==a.absoluteLeft?(this.oldHostMetrics_&&this.oldHostMetrics_.contentWidth==a.contentWidth&&this.oldHostMetrics_.viewLeft==a.viewLeft&&this.oldHostMetrics_.contentLeft==a.contentLeft||(b=!0),this.oldHostMetrics_&&
                +this.oldHostMetrics_.contentHeight==a.contentHeight&&this.oldHostMetrics_.viewTop==a.viewTop&&this.oldHostMetrics_.contentTop==a.contentTop||(c=!0)):c=b=!0;b&&this.hScroll.resize(a);c&&this.vScroll.resize(a);this.oldHostMetrics_&&this.oldHostMetrics_.viewWidth==a.viewWidth&&this.oldHostMetrics_.absoluteLeft==a.absoluteLeft||this.corner_.setAttribute("x",this.vScroll.position_.x);this.oldHostMetrics_&&this.oldHostMetrics_.viewHeight==a.viewHeight&&this.oldHostMetrics_.absoluteTop==a.absoluteTop||this.corner_.setAttribute("y",
                +this.hScroll.position_.y);this.oldHostMetrics_=a}};Blockly.ScrollbarPair.prototype.set=function(a,b){var c={},d=a*this.hScroll.ratio_,e=b*this.vScroll.ratio_,f=this.vScroll.scrollViewSize_;c.x=this.getRatio_(d,this.hScroll.scrollViewSize_);c.y=this.getRatio_(e,f);this.workspace_.setMetrics(c);this.hScroll.setHandlePosition(d);this.vScroll.setHandlePosition(e)};Blockly.ScrollbarPair.prototype.getRatio_=function(a,b){var c=a/b;return isNaN(c)?0:c};
                +Blockly.Scrollbar=function(a,b,c,d){this.workspace_=a;this.pair_=c||!1;this.horizontal_=b;this.oldHostMetrics_=null;this.createDom_(d);this.position_=new goog.math.Coordinate(0,0);b?(this.svgBackground_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness),this.outerSvg_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness),this.svgHandle_.setAttribute("height",Blockly.Scrollbar.scrollbarThickness-5),this.svgHandle_.setAttribute("y",2.5),this.lengthAttribute_="width",this.positionAttribute_=
                +"x"):(this.svgBackground_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness),this.outerSvg_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness),this.svgHandle_.setAttribute("width",Blockly.Scrollbar.scrollbarThickness-5),this.svgHandle_.setAttribute("x",2.5),this.lengthAttribute_="height",this.positionAttribute_="y");this.onMouseDownBarWrapper_=Blockly.bindEventWithChecks_(this.svgBackground_,"mousedown",this,this.onMouseDownBar_);this.onMouseDownHandleWrapper_=Blockly.bindEventWithChecks_(this.svgHandle_,
                +"mousedown",this,this.onMouseDownHandle_)};Blockly.Scrollbar.prototype.origin_=new goog.math.Coordinate(0,0);Blockly.Scrollbar.prototype.scrollViewSize_=0;Blockly.Scrollbar.prototype.handleLength_=0;Blockly.Scrollbar.prototype.handlePosition_=0;Blockly.Scrollbar.prototype.isVisible_=!0;Blockly.Scrollbar.prototype.containerVisible_=!0;Blockly.Scrollbar.scrollbarThickness=15;goog.events.BrowserFeature.TOUCH_ENABLED&&(Blockly.Scrollbar.scrollbarThickness=25);
                +Blockly.Scrollbar.metricsAreEquivalent_=function(a,b){return a&&b&&a.viewWidth==b.viewWidth&&a.viewHeight==b.viewHeight&&a.viewLeft==b.viewLeft&&a.viewTop==b.viewTop&&a.absoluteTop==b.absoluteTop&&a.absoluteLeft==b.absoluteLeft&&a.contentWidth==b.contentWidth&&a.contentHeight==b.contentHeight&&a.contentLeft==b.contentLeft&&a.contentTop==b.contentTop?!0:!1};
                +Blockly.Scrollbar.prototype.dispose=function(){this.cleanUp_();Blockly.unbindEvent_(this.onMouseDownBarWrapper_);this.onMouseDownBarWrapper_=null;Blockly.unbindEvent_(this.onMouseDownHandleWrapper_);this.onMouseDownHandleWrapper_=null;goog.dom.removeNode(this.outerSvg_);this.workspace_=this.svgHandle_=this.svgBackground_=this.svgGroup_=this.outerSvg_=null};Blockly.Scrollbar.prototype.setHandleLength_=function(a){this.handleLength_=a;this.svgHandle_.setAttribute(this.lengthAttribute_,this.handleLength_)};
                +Blockly.Scrollbar.prototype.setHandlePosition=function(a){this.handlePosition_=a;this.svgHandle_.setAttribute(this.positionAttribute_,this.handlePosition_)};Blockly.Scrollbar.prototype.setScrollViewSize_=function(a){this.scrollViewSize_=a;this.outerSvg_.setAttribute(this.lengthAttribute_,this.scrollViewSize_);this.svgBackground_.setAttribute(this.lengthAttribute_,this.scrollViewSize_)};Blockly.ScrollbarPair.prototype.setContainerVisible=function(a){this.hScroll.setContainerVisible(a);this.vScroll.setContainerVisible(a)};
                +Blockly.Scrollbar.prototype.setPosition=function(a,b){this.position_.x=a;this.position_.y=b;Blockly.utils.setCssTransform(this.outerSvg_,"translate("+(this.position_.x+this.origin_.x)+"px,"+(this.position_.y+this.origin_.y)+"px)")};Blockly.Scrollbar.prototype.resize=function(a){if(!a&&(a=this.workspace_.getMetrics(),!a))return;Blockly.Scrollbar.metricsAreEquivalent_(a,this.oldHostMetrics_)||(this.oldHostMetrics_=a,this.horizontal_?this.resizeHorizontal_(a):this.resizeVertical_(a),this.onScroll_())};
                +Blockly.Scrollbar.prototype.resizeHorizontal_=function(a){this.resizeViewHorizontal(a)};Blockly.Scrollbar.prototype.resizeViewHorizontal=function(a){var b=a.viewWidth-1;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollViewSize_(Math.max(0,b));b=a.absoluteLeft+.5;this.pair_&&this.workspace_.RTL&&(b+=Blockly.Scrollbar.scrollbarThickness);this.setPosition(b,a.absoluteTop+a.viewHeight-Blockly.Scrollbar.scrollbarThickness-.5);this.resizeContentHorizontal(a)};
                +Blockly.Scrollbar.prototype.resizeContentHorizontal=function(a){this.pair_||this.setVisible(this.scrollViewSize_<a.contentWidth);this.ratio_=this.scrollViewSize_/a.contentWidth;if(-Infinity==this.ratio_||Infinity==this.ratio_||isNaN(this.ratio_))this.ratio_=0;this.setHandleLength_(Math.max(0,a.viewWidth*this.ratio_));this.setHandlePosition(this.constrainHandle_((a.viewLeft-a.contentLeft)*this.ratio_))};Blockly.Scrollbar.prototype.resizeVertical_=function(a){this.resizeViewVertical(a)};
                +Blockly.Scrollbar.prototype.resizeViewVertical=function(a){var b=a.viewHeight-1;this.pair_&&(b-=Blockly.Scrollbar.scrollbarThickness);this.setScrollViewSize_(Math.max(0,b));b=a.absoluteLeft+.5;this.workspace_.RTL||(b+=a.viewWidth-Blockly.Scrollbar.scrollbarThickness-1);this.setPosition(b,a.absoluteTop+.5);this.resizeContentVertical(a)};
                +Blockly.Scrollbar.prototype.resizeContentVertical=function(a){this.pair_||this.setVisible(this.scrollViewSize_<a.contentHeight);this.ratio_=this.scrollViewSize_/a.contentHeight;if(-Infinity==this.ratio_||Infinity==this.ratio_||isNaN(this.ratio_))this.ratio_=0;this.setHandleLength_(Math.max(0,a.viewHeight*this.ratio_));this.setHandlePosition(this.constrainHandle_((a.viewTop-a.contentTop)*this.ratio_))};
                +Blockly.Scrollbar.prototype.createDom_=function(a){var b="blocklyScrollbar"+(this.horizontal_?"Horizontal":"Vertical");a&&(b+=" "+a);this.outerSvg_=Blockly.utils.createSvgElement("svg",{"class":b},null);this.svgGroup_=Blockly.utils.createSvgElement("g",{},this.outerSvg_);this.svgBackground_=Blockly.utils.createSvgElement("rect",{"class":"blocklyScrollbarBackground"},this.svgGroup_);a=Math.floor((Blockly.Scrollbar.scrollbarThickness-5)/2);this.svgHandle_=Blockly.utils.createSvgElement("rect",{"class":"blocklyScrollbarHandle",
                +rx:a,ry:a},this.svgGroup_);Blockly.utils.insertAfter_(this.outerSvg_,this.workspace_.getParentSvg())};Blockly.Scrollbar.prototype.isVisible=function(){return this.isVisible_};Blockly.Scrollbar.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};Blockly.Scrollbar.prototype.setVisible=function(a){var b=a!=this.isVisible();if(this.pair_)throw"Unable to toggle visibility of paired scrollbars.";this.isVisible_=a;b&&this.updateDisplay_()};
                +Blockly.Scrollbar.prototype.updateDisplay_=function(){this.containerVisible_&&this.isVisible()?this.outerSvg_.setAttribute("display","block"):this.outerSvg_.setAttribute("display","none")};
                +Blockly.Scrollbar.prototype.onMouseDownBar_=function(a){this.workspace_.markFocused();Blockly.Touch.clearTouchIdentifier();this.cleanUp_();if(Blockly.utils.isRightButton(a))a.stopPropagation();else{var b=Blockly.utils.mouseToSvg(a,this.workspace_.getParentSvg(),this.workspace_.getInverseScreenCTM()),b=this.horizontal_?b.x:b.y,c=Blockly.utils.getInjectionDivXY_(this.svgHandle_),c=this.horizontal_?c.x:c.y,d=this.handlePosition_,e=.95*this.handleLength_;b<=c?d-=e:b>=c+this.handleLength_&&(d+=e);this.setHandlePosition(this.constrainHandle_(d));
                +this.onScroll_();a.stopPropagation();a.preventDefault()}};
                +Blockly.Scrollbar.prototype.onMouseDownHandle_=function(a){this.workspace_.markFocused();this.cleanUp_();Blockly.utils.isRightButton(a)?a.stopPropagation():(this.startDragHandle=this.handlePosition_,this.workspace_.setupDragSurface(),this.startDragMouse=this.horizontal_?a.clientX:a.clientY,Blockly.Scrollbar.onMouseUpWrapper_=Blockly.bindEventWithChecks_(document,"mouseup",this,this.onMouseUpHandle_),Blockly.Scrollbar.onMouseMoveWrapper_=Blockly.bindEventWithChecks_(document,"mousemove",this,this.onMouseMoveHandle_),
                +a.stopPropagation(),a.preventDefault())};Blockly.Scrollbar.prototype.onMouseMoveHandle_=function(a){this.setHandlePosition(this.constrainHandle_(this.startDragHandle+((this.horizontal_?a.clientX:a.clientY)-this.startDragMouse)));this.onScroll_()};Blockly.Scrollbar.prototype.onMouseUpHandle_=function(){this.workspace_.resetDragSurface();Blockly.Touch.clearTouchIdentifier();this.cleanUp_()};
                +Blockly.Scrollbar.prototype.cleanUp_=function(){Blockly.hideChaff(!0);Blockly.Scrollbar.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_),Blockly.Scrollbar.onMouseUpWrapper_=null);Blockly.Scrollbar.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Scrollbar.onMouseMoveWrapper_),Blockly.Scrollbar.onMouseMoveWrapper_=null)};
                +Blockly.Scrollbar.prototype.constrainHandle_=function(a){return a=0>=a||isNaN(a)||this.scrollViewSize_<this.handleLength_?0:Math.min(a,this.scrollViewSize_-this.handleLength_)};Blockly.Scrollbar.prototype.onScroll_=function(){var a=this.handlePosition_/this.scrollViewSize_;isNaN(a)&&(a=0);var b={};this.horizontal_?b.x=a:b.y=a;this.workspace_.setMetrics(b)};Blockly.Scrollbar.prototype.set=function(a){this.setHandlePosition(this.constrainHandle_(a*this.ratio_));this.onScroll_()};
                +Blockly.Scrollbar.prototype.setOrigin=function(a,b){this.origin_=new goog.math.Coordinate(a,b)};Blockly.Trashcan=function(a){this.workspace_=a};Blockly.Trashcan.prototype.WIDTH_=47;Blockly.Trashcan.prototype.BODY_HEIGHT_=44;Blockly.Trashcan.prototype.LID_HEIGHT_=16;Blockly.Trashcan.prototype.MARGIN_BOTTOM_=20;Blockly.Trashcan.prototype.MARGIN_SIDE_=20;Blockly.Trashcan.prototype.MARGIN_HOTSPOT_=10;Blockly.Trashcan.prototype.SPRITE_LEFT_=0;Blockly.Trashcan.prototype.SPRITE_TOP_=32;Blockly.Trashcan.prototype.isOpen=!1;Blockly.Trashcan.prototype.svgGroup_=null;
                +Blockly.Trashcan.prototype.svgLid_=null;Blockly.Trashcan.prototype.lidTask_=0;Blockly.Trashcan.prototype.lidOpen_=0;Blockly.Trashcan.prototype.left_=0;Blockly.Trashcan.prototype.top_=0;
                +Blockly.Trashcan.prototype.createDom=function(){this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyTrash"},null);var a=String(Math.random()).substring(2);var b=Blockly.utils.createSvgElement("clipPath",{id:"blocklyTrashBodyClipPath"+a},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:this.WIDTH_,height:this.BODY_HEIGHT_,y:this.LID_HEIGHT_},b);Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,y:-this.SPRITE_TOP_,
                +"clip-path":"url(#blocklyTrashBodyClipPath"+a+")"},this.svgGroup_).setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);b=Blockly.utils.createSvgElement("clipPath",{id:"blocklyTrashLidClipPath"+a},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:this.WIDTH_,height:this.LID_HEIGHT_},b);this.svgLid_=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,x:-this.SPRITE_LEFT_,height:Blockly.SPRITE.height,y:-this.SPRITE_TOP_,
                +"clip-path":"url(#blocklyTrashLidClipPath"+a+")"},this.svgGroup_);this.svgLid_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",this.workspace_.options.pathToMedia+Blockly.SPRITE.url);Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.click);this.animateLid_();return this.svgGroup_};Blockly.Trashcan.prototype.init=function(a){this.bottom_=this.MARGIN_BOTTOM_+a;this.setOpen_(!1);return this.bottom_+this.BODY_HEIGHT_+this.LID_HEIGHT_};
                +Blockly.Trashcan.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.workspace_=this.svgLid_=null;goog.Timer.clear(this.lidTask_)};
                +Blockly.Trashcan.prototype.position=function(){var a=this.workspace_.getMetrics();a&&(this.workspace_.RTL?(this.left_=this.MARGIN_SIDE_+Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(this.left_+=a.flyoutWidth,this.workspace_.toolbox_&&(this.left_+=a.absoluteLeft))):(this.left_=a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_-Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(this.left_-=a.flyoutWidth)),this.top_=a.viewHeight+
                +a.absoluteTop-(this.BODY_HEIGHT_+this.LID_HEIGHT_)-this.bottom_,a.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM&&(this.top_-=a.flyoutHeight),this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")"))};
                +Blockly.Trashcan.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect();return new goog.math.Rect(a.left+this.SPRITE_LEFT_-this.MARGIN_HOTSPOT_,a.top+this.SPRITE_TOP_-this.MARGIN_HOTSPOT_,this.WIDTH_+2*this.MARGIN_HOTSPOT_,this.LID_HEIGHT_+this.BODY_HEIGHT_+2*this.MARGIN_HOTSPOT_)};Blockly.Trashcan.prototype.setOpen_=function(a){this.isOpen!=a&&(goog.Timer.clear(this.lidTask_),this.isOpen=a,this.animateLid_())};
                +Blockly.Trashcan.prototype.animateLid_=function(){this.lidOpen_+=this.isOpen?.2:-.2;this.lidOpen_=goog.math.clamp(this.lidOpen_,0,1);var a=45*this.lidOpen_;this.svgLid_.setAttribute("transform","rotate("+(this.workspace_.RTL?-a:a)+","+(this.workspace_.RTL?4:this.WIDTH_-4)+","+(this.LID_HEIGHT_-2)+")");a=goog.math.lerp(.4,.8,this.lidOpen_);this.svgGroup_.style.opacity=a;0<this.lidOpen_&&1>this.lidOpen_&&(this.lidTask_=goog.Timer.callOnce(this.animateLid_,20,this))};
                +Blockly.Trashcan.prototype.close=function(){this.setOpen_(!1)};Blockly.Trashcan.prototype.click=function(){var a=this.workspace_.startScrollX-this.workspace_.scrollX,b=this.workspace_.startScrollY-this.workspace_.scrollY;Math.sqrt(a*a+b*b)>Blockly.DRAG_RADIUS||console.log("TODO: Inspect trash.")};Blockly.WorkspaceAudio=function(a){this.parentWorkspace_=a;this.SOUNDS_=Object.create(null)};Blockly.WorkspaceAudio.prototype.lastSound_=null;Blockly.WorkspaceAudio.prototype.dispose=function(){this.SOUNDS_=this.parentWorkspace_=null};Blockly.WorkspaceAudio.prototype.load=function(a,b){if(a.length){try{var c=new window.Audio}catch(h){return}for(var d,e=0;e<a.length;e++){var f=a[e],g=f.match(/\.(\w+)$/);if(g&&c.canPlayType("audio/"+g[1])){d=new window.Audio(f);break}}d&&d.play&&(this.SOUNDS_[b]=d)}};
                +Blockly.WorkspaceAudio.prototype.preload=function(){for(var a in this.SOUNDS_){var b=this.SOUNDS_[a];b.volume=.01;b.play();b.pause();if(goog.userAgent.IPAD||goog.userAgent.IPHONE)break}};
                +Blockly.WorkspaceAudio.prototype.play=function(a,b){var c=this.SOUNDS_[a];if(c){var d=new Date;null!=this.lastSound_&&d-this.lastSound_<Blockly.SOUND_LIMIT||(this.lastSound_=d,c=goog.userAgent.DOCUMENT_MODE&&9===goog.userAgent.DOCUMENT_MODE||goog.userAgent.IPAD||goog.userAgent.ANDROID?c:c.cloneNode(),c.volume=void 0===b?1:b,c.play())}else this.parentWorkspace_&&this.parentWorkspace_.getAudioManager().play(a,b)};Blockly.WorkspaceDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.dragGroup_=null;Blockly.WorkspaceDragSurfaceSvg.prototype.container_=null;
                +Blockly.WorkspaceDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=Blockly.utils.createSvgElement("svg",{xmlns:Blockly.SVG_NS,"xmlns:html":Blockly.HTML_NS,"xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklyWsDragSurface"},null),this.container_.appendChild(this.SVG_))};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.translateSurface=function(a,b){a=a.toFixed(0);b=b.toFixed(0);this.SVG_.style.display="block";Blockly.utils.setCssTransform(this.SVG_,"translate3d("+a+"px, "+b+"px, 0px)")};Blockly.WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation=function(){return Blockly.utils.getRelativeXY(this.SVG_)};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide=function(a){var b=this.SVG_.childNodes[0],c=this.SVG_.childNodes[1];if(!(b&&c&&Blockly.utils.hasClass(b,"blocklyBlockCanvas")&&Blockly.utils.hasClass(c,"blocklyBubbleCanvas")))throw"Couldn't clear and hide the drag surface.  A node was missing.";null!=this.previousSibling_?Blockly.utils.insertAfter_(b,this.previousSibling_):a.insertBefore(b,a.firstChild);Blockly.utils.insertAfter_(c,b);this.SVG_.style.display="none";goog.asserts.assert(0==this.SVG_.childNodes.length,
                +"Drag surface was not cleared.");Blockly.utils.setCssTransform(this.SVG_,"");this.previousSibling_=null};
                +Blockly.WorkspaceDragSurfaceSvg.prototype.setContentsAndShow=function(a,b,c,d,e,f){goog.asserts.assert(0==this.SVG_.childNodes.length,"Already dragging a block.");this.previousSibling_=c;a.setAttribute("transform","translate(0, 0) scale("+f+")");b.setAttribute("transform","translate(0, 0) scale("+f+")");this.SVG_.setAttribute("width",d);this.SVG_.setAttribute("height",e);this.SVG_.appendChild(a);this.SVG_.appendChild(b);this.SVG_.style.display="block"};Blockly.Xml={};Blockly.Xml.workspaceToDom=function(a,b){var c=goog.dom.createDom("xml");c.appendChild(Blockly.Xml.variablesToDom(a.getAllVariables()));for(var d=a.getTopBlocks(!0),e=0,f;f=d[e];e++)c.appendChild(Blockly.Xml.blockToDomWithXY(f,b));return c};Blockly.Xml.variablesToDom=function(a){for(var b=goog.dom.createDom("variables"),c=0,d;d=a[c];c++){var e=goog.dom.createDom("variable",null,d.name);e.setAttribute("type",d.type);e.setAttribute("id",d.getId());b.appendChild(e)}return b};
                +Blockly.Xml.blockToDomWithXY=function(a,b){var c;a.workspace.RTL&&(c=a.workspace.getWidth());var d=Blockly.Xml.blockToDom(a,b),e=a.getRelativeToSurfaceXY();d.setAttribute("x",Math.round(a.workspace.RTL?c-e.x:e.x));d.setAttribute("y",Math.round(e.y));return d};
                +Blockly.Xml.blockToDom=function(a,b){var c,d=goog.dom.createDom(a.isShadow()?"shadow":"block");d.setAttribute("type",a.type);b||d.setAttribute("id",a.id);if(a.mutationToDom){var e=a.mutationToDom();e&&(e.hasChildNodes()||e.hasAttributes())&&d.appendChild(e)}for(var e=0,f;f=a.inputList[e];e++){var g=0;for(var h;h=f.fieldRow[g];g++){var k=h;k.name&&k.EDITABLE&&(h=goog.dom.createDom("field",null,k.getValue()),h.setAttribute("name",k.name),k instanceof Blockly.FieldVariable&&(k=a.workspace.getVariable(k.getValue()))&&
                +(h.setAttribute("id",k.getId()),h.setAttribute("variableType",k.type)),d.appendChild(h))}}if(e=a.getCommentText())e=goog.dom.createDom("comment",null,e),"object"==typeof a.comment&&(e.setAttribute("pinned",a.comment.isVisible()),f=a.comment.getBubbleSize(),e.setAttribute("h",f.height),e.setAttribute("w",f.width)),d.appendChild(e);a.data&&(e=goog.dom.createDom("data",null,a.data),d.appendChild(e));for(e=0;f=a.inputList[e];e++)h=!0,f.type!=Blockly.DUMMY_INPUT&&(k=f.connection.targetBlock(),f.type==
                +Blockly.INPUT_VALUE?c=goog.dom.createDom("value"):f.type==Blockly.NEXT_STATEMENT&&(c=goog.dom.createDom("statement")),g=f.connection.getShadowDom(),!g||k&&k.isShadow()||c.appendChild(Blockly.Xml.cloneShadow_(g)),k&&(c.appendChild(Blockly.Xml.blockToDom(k,b)),h=!1),c.setAttribute("name",f.name),h||d.appendChild(c));a.inputsInlineDefault!=a.inputsInline&&d.setAttribute("inline",a.inputsInline);a.isCollapsed()&&d.setAttribute("collapsed",!0);a.disabled&&d.setAttribute("disabled",!0);a.isDeletable()||
                +a.isShadow()||d.setAttribute("deletable",!1);a.isMovable()||a.isShadow()||d.setAttribute("movable",!1);a.isEditable()||d.setAttribute("editable",!1);if(e=a.getNextBlock())c=goog.dom.createDom("next",null,Blockly.Xml.blockToDom(e,b)),d.appendChild(c);g=a.nextConnection&&a.nextConnection.getShadowDom();!g||e&&e.isShadow()||c.appendChild(Blockly.Xml.cloneShadow_(g));return d};
                +Blockly.Xml.cloneShadow_=function(a){for(var b=a=a.cloneNode(!0),c;b;)if(b.firstChild)b=b.firstChild;else{for(;b&&!b.nextSibling;)c=b,b=b.parentNode,3==c.nodeType&&""==c.data.trim()&&b.firstChild!=c&&goog.dom.removeNode(c);b&&(c=b,b=b.nextSibling,3==c.nodeType&&""==c.data.trim()&&goog.dom.removeNode(c))}return a};Blockly.Xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};
                +Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c<a.length;c++){var d=a[c];"/"==d[0]&&(b=b.substring(2));a[c]=b+"<"+d;"/"!=d[0]&&"/>"!=d.slice(-2)&&(b+="  ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1</$2>");return a.replace(/^\n/,"")};
                +Blockly.Xml.textToDom=function(a){(a=(new DOMParser).parseFromString(a,"text/xml"))&&a.firstChild&&"xml"==a.firstChild.nodeName.toLowerCase()&&a.firstChild===a.lastChild||goog.asserts.fail("Blockly.Xml.textToDom did not obtain a valid XML tree.");return a.firstChild};
                +Blockly.Xml.domToWorkspace=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToWorkspace, swap the arguments.")}var d;b.RTL&&(d=b.getWidth());c=[];Blockly.Field.startCache();var e=a.childNodes.length,f=Blockly.Events.getGroup();f||Blockly.Events.setGroup(!0);b.setResizesEnabled&&b.setResizesEnabled(!1);var g=!0;try{for(var h=0;h<e;h++){var k=a.childNodes[h],l=k.nodeName.toLowerCase();if("block"==l||"shadow"==l&&!Blockly.Events.recordUndo){var m=
                +Blockly.Xml.domToBlock(k,b);c.push(m.id);var n=parseInt(k.getAttribute("x"),10),p=parseInt(k.getAttribute("y"),10);isNaN(n)||isNaN(p)||m.moveBy(b.RTL?d-n:n,p);g=!1}else if("shadow"==l)goog.asserts.fail("Shadow block cannot be a top-level block."),g=!1;else if("variables"==l){if(g)Blockly.Xml.domToVariables(k,b);else throw Error("'variables' tag must exist once before block and shadow tag elements in the workspace XML, but it was found in another location.");g=!1}}}finally{f||Blockly.Events.setGroup(!1),
                +Blockly.Field.stopCache()}b.updateVariableStore(!1);b.setResizesEnabled&&b.setResizesEnabled(!0);return c};
                +Blockly.Xml.appendDomToWorkspace=function(a,b){if(b.hasOwnProperty("scale")){var c=Blockly.BlockSvg.TAB_WIDTH;try{Blockly.BlockSvg.TAB_WIDTH=0;var d=b.getBlocksBoundingBox()}finally{Blockly.BlockSvg.TAB_WIDTH=c}}c=Blockly.Xml.domToWorkspace(a,b);if(d&&d.height){var e=d.y+d.height;var f=d.x;var g=Infinity,h=Infinity;for(d=0;d<c.length;d++){var k=b.getBlockById(c[d]).getRelativeToSurfaceXY();k.y<h&&(h=k.y);k.x<g&&(g=k.x)}e=e-h+Blockly.BlockSvg.SEP_SPACE_Y;f-=g;var l;b.RTL&&(l=b.getWidth());for(d=0;d<
                +c.length;d++)b.getBlockById(c[d]).moveBy(b.RTL?l-f:f,e)}return c};
                +Blockly.Xml.domToBlock=function(a,b){if(a instanceof Blockly.Workspace){var c=a;a=b;b=c;console.warn("Deprecated call to Blockly.Xml.domToBlock, swap the arguments.")}Blockly.Events.disable();try{var d=Blockly.Xml.domToBlockHeadless_(a,b);if(b.rendered){d.setConnectionsHidden(!0);for(var e=d.getDescendants(),f=e.length-1;0<=f;f--)e[f].initSvg();for(f=e.length-1;0<=f;f--)e[f].render(!1);setTimeout(function(){d.workspace&&d.setConnectionsHidden(!1)},1);d.updateDisabled();b.resizeContents()}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&
                +Blockly.Events.fire(new Blockly.Events.BlockCreate(d));return d};Blockly.Xml.domToVariables=function(a,b){for(var c=0,d;d=a.children[c];c++){var e=d.getAttribute("type"),f=d.getAttribute("id");d=d.textContent;if(null===e)throw Error("Variable with id, "+f+" is without a type");b.createVariable(d,e,f)}};
                +Blockly.Xml.domToBlockHeadless_=function(a,b){var c=null,d=a.getAttribute("type");goog.asserts.assert(d,"Block type unspecified: %s",a.outerHTML);for(var e=a.getAttribute("id"),c=b.newBlock(d,e),f=null,g=0,h;h=a.childNodes[g];g++)if(3!=h.nodeType){for(var k=null,l=null,f=0,m;m=h.childNodes[f];f++)1==m.nodeType&&("block"==m.nodeName.toLowerCase()?k=m:"shadow"==m.nodeName.toLowerCase()&&(l=m));!k&&l&&(k=l);f=h.getAttribute("name");switch(h.nodeName.toLowerCase()){case "mutation":c.domToMutation&&(c.domToMutation(h),
                +c.initSvg&&c.initSvg());break;case "comment":c.setCommentText(h.textContent);var n=h.getAttribute("pinned");n&&!c.isInFlyout&&setTimeout(function(){c.comment&&c.comment.setVisible&&c.comment.setVisible("true"==n)},1);f=parseInt(h.getAttribute("w"),10);h=parseInt(h.getAttribute("h"),10);!isNaN(f)&&!isNaN(h)&&c.comment&&c.comment.setVisible&&c.comment.setBubbleSize(f,h);break;case "data":c.data=h.textContent;break;case "title":case "field":k=c.getField(f);l=h.textContent;if(k instanceof Blockly.FieldVariable){m=
                +h.getAttribute("variableType")||"";var p=b.getVariable(l);p||(p=b.createVariable(l,m,h.getAttribute(e)));if(null!==m&&m!==p.type)throw Error("Serialized variable type with id '"+p.getId()+"' had type "+p.type+", and does not match variable field that references it: "+Blockly.Xml.domToText(h)+".");}if(!k){console.warn("Ignoring non-existent field "+f+" in block "+d);break}k.setValue(l);break;case "value":case "statement":h=c.getInput(f);if(!h){console.warn("Ignoring non-existent input "+f+" in block "+
                +d);break}l&&h.connection.setShadowDom(l);k&&(f=Blockly.Xml.domToBlockHeadless_(k,b),f.outputConnection?h.connection.connect(f.outputConnection):f.previousConnection?h.connection.connect(f.previousConnection):goog.asserts.fail("Child block does not have output or previous statement."));break;case "next":l&&c.nextConnection&&c.nextConnection.setShadowDom(l);k&&(goog.asserts.assert(c.nextConnection,"Next statement does not exist."),goog.asserts.assert(!c.nextConnection.isConnected(),"Next statement is already connected."),
                +f=Blockly.Xml.domToBlockHeadless_(k,b),goog.asserts.assert(f.previousConnection,"Next block does not have previous statement."),c.nextConnection.connect(f.previousConnection));break;default:console.warn("Ignoring unknown tag: "+h.nodeName)}}(g=a.getAttribute("inline"))&&c.setInputsInline("true"==g);(g=a.getAttribute("disabled"))&&c.setDisabled("true"==g);(g=a.getAttribute("deletable"))&&c.setDeletable("true"==g);(g=a.getAttribute("movable"))&&c.setMovable("true"==g);(g=a.getAttribute("editable"))&&
                +c.setEditable("true"==g);(g=a.getAttribute("collapsed"))&&c.setCollapsed("true"==g);if("shadow"==a.nodeName.toLowerCase()){d=c.getChildren();for(g=0;e=d[g];g++)goog.asserts.assert(e.isShadow(),"Shadow block not allowed non-shadow child.");goog.asserts.assert(0==c.getVars().length,"Shadow blocks cannot have variable fields.");c.setShadow(!0)}return c};Blockly.Xml.deleteNext=function(a){for(var b=0,c;c=a.childNodes[b];b++)if("next"==c.nodeName.toLowerCase()){a.removeChild(c);break}};
                +goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Xml||(goog.global.Blockly.Xml={});goog.global.Blockly.Xml.domToText=Blockly.Xml.domToText;goog.global.Blockly.Xml.domToWorkspace=Blockly.Xml.domToWorkspace;goog.global.Blockly.Xml.textToDom=Blockly.Xml.textToDom;goog.global.Blockly.Xml.workspaceToDom=Blockly.Xml.workspaceToDom;/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2015 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.ZoomControls=function(a){this.workspace_=a};Blockly.ZoomControls.prototype.WIDTH_=32;Blockly.ZoomControls.prototype.HEIGHT_=110;Blockly.ZoomControls.prototype.MARGIN_BOTTOM_=20;Blockly.ZoomControls.prototype.MARGIN_SIDE_=20;Blockly.ZoomControls.prototype.svgGroup_=null;Blockly.ZoomControls.prototype.left_=0;Blockly.ZoomControls.prototype.top_=0;
                +Blockly.ZoomControls.prototype.createDom=function(){var a=this.workspace_;this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyZoom"},null);var b=String(Math.random()).substring(2);var c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoomoutClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32,y:77},c);var d=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-64,y:-15,"clip-path":"url(#blocklyZoomoutClipPath"+
                +b+")"},this.svgGroup_);d.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoominClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32,y:43},c);var e=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,x:-32,y:-49,"clip-path":"url(#blocklyZoominClipPath"+b+")"},this.svgGroup_);e.setAttributeNS("http://www.w3.org/1999/xlink",
                +"xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);c=Blockly.utils.createSvgElement("clipPath",{id:"blocklyZoomresetClipPath"+b},this.svgGroup_);Blockly.utils.createSvgElement("rect",{width:32,height:32},c);c=Blockly.utils.createSvgElement("image",{width:Blockly.SPRITE.width,height:Blockly.SPRITE.height,y:-92,"clip-path":"url(#blocklyZoomresetClipPath"+b+")"},this.svgGroup_);c.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a.options.pathToMedia+Blockly.SPRITE.url);Blockly.bindEventWithChecks_(c,
                +"mousedown",null,function(b){a.markFocused();a.setScale(a.options.zoomOptions.startScale);a.scrollCenter();Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()});Blockly.bindEventWithChecks_(e,"mousedown",null,function(b){a.markFocused();a.zoomCenter(1);Blockly.Touch.clearTouchIdentifier();b.stopPropagation();b.preventDefault()});Blockly.bindEventWithChecks_(d,"mousedown",null,function(b){a.markFocused();a.zoomCenter(-1);Blockly.Touch.clearTouchIdentifier();b.stopPropagation();
                +b.preventDefault()});return this.svgGroup_};Blockly.ZoomControls.prototype.init=function(a){this.bottom_=this.MARGIN_BOTTOM_+a;return this.bottom_+this.HEIGHT_};Blockly.ZoomControls.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.workspace_=null};
                +Blockly.ZoomControls.prototype.position=function(){var a=this.workspace_.getMetrics();a&&(this.workspace_.RTL?(this.left_=this.MARGIN_SIDE_+Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(this.left_+=a.flyoutWidth,this.workspace_.toolbox_&&(this.left_+=a.absoluteLeft))):(this.left_=a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_-Blockly.Scrollbar.scrollbarThickness,a.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(this.left_-=a.flyoutWidth)),this.top_=a.viewHeight+
                +a.absoluteTop-this.HEIGHT_-this.bottom_,a.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM&&(this.top_-=a.flyoutHeight),this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")"))};/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2014 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.WorkspaceSvg=function(a,b,c){Blockly.WorkspaceSvg.superClass_.constructor.call(this,a);this.getMetrics=a.getMetrics||Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_;this.setMetrics=a.setMetrics||Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_;Blockly.ConnectionDB.init(this);b&&(this.blockDragSurface_=b);c&&(this.workspaceDragSurface_=c);this.useWorkspaceDragSurface_=this.workspaceDragSurface_&&Blockly.utils.is3dSupported();this.highlightedBlocks_=[];this.audioManager_=new Blockly.WorkspaceAudio(a.parentWorkspace);
                +this.grid_=this.options.gridPattern?new Blockly.Grid(a.gridPattern,a.gridOptions):null;this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,Blockly.Variables.flyoutCategory);this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME,Blockly.Procedures.flyoutCategory)};goog.inherits(Blockly.WorkspaceSvg,Blockly.Workspace);Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_=null;Blockly.WorkspaceSvg.prototype.rendered=!0;Blockly.WorkspaceSvg.prototype.isFlyout=!1;
                +Blockly.WorkspaceSvg.prototype.isMutator=!1;Blockly.WorkspaceSvg.prototype.resizesEnabled_=!0;Blockly.WorkspaceSvg.prototype.scrollX=0;Blockly.WorkspaceSvg.prototype.scrollY=0;Blockly.WorkspaceSvg.prototype.startScrollX=0;Blockly.WorkspaceSvg.prototype.startScrollY=0;Blockly.WorkspaceSvg.prototype.dragDeltaXY_=null;Blockly.WorkspaceSvg.prototype.scale=1;Blockly.WorkspaceSvg.prototype.trashcan=null;Blockly.WorkspaceSvg.prototype.scrollbar=null;Blockly.WorkspaceSvg.prototype.currentGesture_=null;
                +Blockly.WorkspaceSvg.prototype.blockDragSurface_=null;Blockly.WorkspaceSvg.prototype.workspaceDragSurface_=null;Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_=!1;Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_=!1;Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_=null;Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_={};Blockly.WorkspaceSvg.prototype.toolboxCategoryCallbacks_={};Blockly.WorkspaceSvg.prototype.inverseScreenCTM_=null;
                +Blockly.WorkspaceSvg.prototype.getInverseScreenCTM=function(){return this.inverseScreenCTM_};Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM=function(){var a=this.getParentSvg().getScreenCTM();a&&(this.inverseScreenCTM_=a.inverse())};
                +Blockly.WorkspaceSvg.prototype.getSvgXY=function(a){var b=0,c=0,d=1;if(goog.dom.contains(this.getCanvas(),a)||goog.dom.contains(this.getBubbleCanvas(),a))d=this.scale;do{var e=Blockly.utils.getRelativeXY(a);if(a==this.getCanvas()||a==this.getBubbleCanvas())d=1;b+=e.x*d;c+=e.y*d;a=a.parentNode}while(a&&a!=this.getParentSvg());return new goog.math.Coordinate(b,c)};Blockly.WorkspaceSvg.prototype.getOriginOffsetInPixels=function(){return Blockly.utils.getInjectionDivXY_(this.svgBlockCanvas_)};
                +Blockly.WorkspaceSvg.prototype.setResizeHandlerWrapper=function(a){this.resizeHandlerWrapper_=a};
                +Blockly.WorkspaceSvg.prototype.createDom=function(a){this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":"blocklyWorkspace"},null);a&&(this.svgBackground_=Blockly.utils.createSvgElement("rect",{height:"100%",width:"100%","class":a},this.svgGroup_),"blocklyMainBackground"==a&&this.grid_&&(this.svgBackground_.style.fill="url(#"+this.grid_.getPatternId()+")"));this.svgBlockCanvas_=Blockly.utils.createSvgElement("g",{"class":"blocklyBlockCanvas"},this.svgGroup_,this);this.svgBubbleCanvas_=Blockly.utils.createSvgElement("g",
                +{"class":"blocklyBubbleCanvas"},this.svgGroup_,this);a=Blockly.Scrollbar.scrollbarThickness;this.options.hasTrashcan&&(a=this.addTrashcan_(a));this.options.zoomOptions&&this.options.zoomOptions.controls&&this.addZoomControls_(a);this.isFlyout||(Blockly.bindEventWithChecks_(this.svgGroup_,"mousedown",this,this.onMouseDown_),this.options.zoomOptions&&this.options.zoomOptions.wheel&&Blockly.bindEventWithChecks_(this.svgGroup_,"wheel",this,this.onMouseWheel_));this.options.hasCategories&&(this.toolbox_=
                +new Blockly.Toolbox(this));this.grid_&&this.grid_.update(this.scale);this.recordDeleteAreas();return this.svgGroup_};
                +Blockly.WorkspaceSvg.prototype.dispose=function(){this.rendered=!1;this.currentGesture_&&this.currentGesture_.cancel();Blockly.WorkspaceSvg.superClass_.dispose.call(this);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.svgBubbleCanvas_=this.svgBlockCanvas_=null;this.toolbox_&&(this.toolbox_.dispose(),this.toolbox_=null);this.flyout_&&(this.flyout_.dispose(),this.flyout_=null);this.trashcan&&(this.trashcan.dispose(),this.trashcan=null);this.scrollbar&&(this.scrollbar.dispose(),
                +this.scrollbar=null);this.zoomControls_&&(this.zoomControls_.dispose(),this.zoomControls_=null);this.audioManager_&&(this.audioManager_.dispose(),this.audioManager_=null);this.grid_&&(this.grid_.dispose(),this.grid_=null);this.toolboxCategoryCallbacks_&&(this.toolboxCategoryCallbacks_=null);this.flyoutButtonCallbacks_&&(this.flyoutButtonCallbacks_=null);this.options.parentWorkspace||goog.dom.removeNode(this.getParentSvg().parentNode);this.resizeHandlerWrapper_&&(Blockly.unbindEvent_(this.resizeHandlerWrapper_),
                +this.resizeHandlerWrapper_=null)};Blockly.WorkspaceSvg.prototype.newBlock=function(a,b){return new Blockly.BlockSvg(this,a,b)};Blockly.WorkspaceSvg.prototype.addTrashcan_=function(a){this.trashcan=new Blockly.Trashcan(this);var b=this.trashcan.createDom();this.svgGroup_.insertBefore(b,this.svgBlockCanvas_);return this.trashcan.init(a)};
                +Blockly.WorkspaceSvg.prototype.addZoomControls_=function(a){this.zoomControls_=new Blockly.ZoomControls(this);var b=this.zoomControls_.createDom();this.svgGroup_.appendChild(b);return this.zoomControls_.init(a)};
                +Blockly.WorkspaceSvg.prototype.addFlyout_=function(a){var b={disabledPatternId:this.options.disabledPatternId,parentWorkspace:this,RTL:this.RTL,oneBasedIndex:this.options.oneBasedIndex,horizontalLayout:this.horizontalLayout,toolboxPosition:this.options.toolboxPosition};this.flyout_=null;this.flyout_=this.horizontalLayout?new Blockly.HorizontalFlyout(b):new Blockly.VerticalFlyout(b);this.flyout_.autoClose=!1;return this.flyout_.createDom(a)};
                +Blockly.WorkspaceSvg.prototype.getFlyout_=function(){return this.flyout_?this.flyout_:this.toolbox_?this.toolbox_.flyout_:null};Blockly.WorkspaceSvg.prototype.updateScreenCalculations_=function(){this.updateInverseScreenCTM();this.recordDeleteAreas()};Blockly.WorkspaceSvg.prototype.resizeContents=function(){this.resizesEnabled_&&this.rendered&&(this.scrollbar&&this.scrollbar.resize(),this.updateInverseScreenCTM())};
                +Blockly.WorkspaceSvg.prototype.resize=function(){this.toolbox_&&this.toolbox_.position();this.flyout_&&this.flyout_.position();this.trashcan&&this.trashcan.position();this.zoomControls_&&this.zoomControls_.position();this.scrollbar&&this.scrollbar.resize();this.updateScreenCalculations_()};Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled=function(){var a=goog.dom.getDocumentScroll();goog.math.Coordinate.equals(this.lastRecordedPageScroll_,a)||(this.lastRecordedPageScroll_=a,this.updateScreenCalculations_())};
                +Blockly.WorkspaceSvg.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.WorkspaceSvg.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};Blockly.WorkspaceSvg.prototype.getParentSvg=function(){if(this.cachedParentSvg_)return this.cachedParentSvg_;for(var a=this.svgGroup_;a;){if("svg"==a.tagName)return this.cachedParentSvg_=a;a=a.parentNode}return null};
                +Blockly.WorkspaceSvg.prototype.translate=function(a,b){if(this.useWorkspaceDragSurface_&&this.isDragSurfaceActive_)this.workspaceDragSurface_.translateSurface(a,b);else{var c="translate("+a+","+b+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",c);this.svgBubbleCanvas_.setAttribute("transform",c)}this.blockDragSurface_&&this.blockDragSurface_.translateAndScaleGroup(a,b,this.scale)};
                +Blockly.WorkspaceSvg.prototype.resetDragSurface=function(){if(this.useWorkspaceDragSurface_){this.isDragSurfaceActive_=!1;var a=this.workspaceDragSurface_.getSurfaceTranslation();this.workspaceDragSurface_.clearAndHide(this.svgGroup_);a="translate("+a.x+","+a.y+") scale("+this.scale+")";this.svgBlockCanvas_.setAttribute("transform",a);this.svgBubbleCanvas_.setAttribute("transform",a)}};
                +Blockly.WorkspaceSvg.prototype.setupDragSurface=function(){if(this.useWorkspaceDragSurface_&&!this.isDragSurfaceActive_){this.isDragSurfaceActive_=!0;var a=this.svgBlockCanvas_.previousSibling,b=this.getParentSvg().getAttribute("width"),c=this.getParentSvg().getAttribute("height"),d=Blockly.utils.getRelativeXY(this.svgBlockCanvas_);this.workspaceDragSurface_.setContentsAndShow(this.svgBlockCanvas_,this.svgBubbleCanvas_,a,b,c,this.scale);this.workspaceDragSurface_.translateSurface(d.x,d.y)}};
                +Blockly.WorkspaceSvg.prototype.getWidth=function(){var a=this.getMetrics();return a?a.viewWidth/this.scale:0};Blockly.WorkspaceSvg.prototype.setVisible=function(a){this.scrollbar&&this.scrollbar.setContainerVisible(a);this.getFlyout_()&&this.getFlyout_().setContainerVisible(a);this.getParentSvg().style.display=a?"block":"none";this.toolbox_&&(this.toolbox_.HtmlDiv.style.display=a?"block":"none");a?(this.render(),this.toolbox_&&this.toolbox_.position()):Blockly.hideChaff(!0)};
                +Blockly.WorkspaceSvg.prototype.render=function(){for(var a=this.getAllBlocks(),b=a.length-1;0<=b;b--)a[b].render(!1)};Blockly.WorkspaceSvg.prototype.traceOn=function(){console.warn("Deprecated call to traceOn, delete this.")};
                +Blockly.WorkspaceSvg.prototype.highlightBlock=function(a,b){if(void 0===b){for(var c=0,d;d=this.highlightedBlocks_[c];c++)d.setHighlighted(!1);this.highlightedBlocks_.length=0}if(d=a?this.getBlockById(a):null)(c=void 0===b||b)?-1==this.highlightedBlocks_.indexOf(d)&&this.highlightedBlocks_.push(d):goog.array.remove(this.highlightedBlocks_,d),d.setHighlighted(c)};
                +Blockly.WorkspaceSvg.prototype.paste=function(a){if(this.rendered&&!(a.getElementsByTagName("block").length>=this.remainingCapacity())){this.currentGesture_&&this.currentGesture_.cancel();Blockly.Events.disable();try{var b=Blockly.Xml.domToBlock(a,this);if(goog.userAgent.IE||goog.userAgent.EDGE)for(var c=b.getDescendants(),d=c.length-1;0<=d;d--)c[d].render(!1);var e=parseInt(a.getAttribute("x"),10),f=parseInt(a.getAttribute("y"),10);if(!isNaN(e)&&!isNaN(f)){this.RTL&&(e=-e);do{var g=!1;for(var h=
                +this.getAllBlocks(),d=0,k;k=h[d];d++){var l=k.getRelativeToSurfaceXY();if(1>=Math.abs(e-l.x)&&1>=Math.abs(f-l.y)){g=!0;break}}if(!g)for(var m=b.getConnections_(!1),d=0,n;n=m[d];d++)if(n.closest(Blockly.SNAP_RADIUS,new goog.math.Coordinate(e,f)).connection){g=!0;break}g&&(e=this.RTL?e-Blockly.SNAP_RADIUS:e+Blockly.SNAP_RADIUS,f+=2*Blockly.SNAP_RADIUS)}while(g);b.moveBy(e,f)}}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!b.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(b));
                +b.select()}};Blockly.WorkspaceSvg.prototype.refreshToolboxSelection_=function(){this.toolbox_&&this.toolbox_.flyout_&&!this.currentGesture_&&this.toolbox_.refreshSelection()};Blockly.WorkspaceSvg.prototype.renameVariable=function(a,b){Blockly.WorkspaceSvg.superClass_.renameVariable.call(this,a,b);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.renameVariableById=function(a,b){Blockly.WorkspaceSvg.superClass_.renameVariableById.call(this,a,b);this.refreshToolboxSelection_()};
                +Blockly.WorkspaceSvg.prototype.deleteVariable=function(a){Blockly.WorkspaceSvg.superClass_.deleteVariable.call(this,a);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.deleteVariableById=function(a){Blockly.WorkspaceSvg.superClass_.deleteVariableById.call(this,a);this.refreshToolboxSelection_()};Blockly.WorkspaceSvg.prototype.createVariable=function(a,b,c){a=Blockly.WorkspaceSvg.superClass_.createVariable.call(this,a,b,c);this.refreshToolboxSelection_();return a};
                +Blockly.WorkspaceSvg.prototype.recordDeleteAreas=function(){this.deleteAreaTrash_=this.trashcan?this.trashcan.getClientRect():null;this.deleteAreaToolbox_=this.flyout_?this.flyout_.getClientRect():this.toolbox_?this.toolbox_.getClientRect():null};
                +Blockly.WorkspaceSvg.prototype.isDeleteArea=function(a){a=new goog.math.Coordinate(a.clientX,a.clientY);return this.deleteAreaTrash_&&this.deleteAreaTrash_.contains(a)?Blockly.DELETE_AREA_TRASH:this.deleteAreaToolbox_&&this.deleteAreaToolbox_.contains(a)?Blockly.DELETE_AREA_TOOLBOX:Blockly.DELETE_AREA_NONE};Blockly.WorkspaceSvg.prototype.onMouseDown_=function(a){var b=this.getGesture(a);b&&b.handleWsStart(a,this)};
                +Blockly.WorkspaceSvg.prototype.startDrag=function(a,b){var c=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());c.x/=this.scale;c.y/=this.scale;this.dragDeltaXY_=goog.math.Coordinate.difference(b,c)};Blockly.WorkspaceSvg.prototype.moveDrag=function(a){a=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());a.x/=this.scale;a.y/=this.scale;return goog.math.Coordinate.sum(this.dragDeltaXY_,a)};
                +Blockly.WorkspaceSvg.prototype.isDragging=function(){return this.currentGesture_&&this.currentGesture_.isDragging()};Blockly.WorkspaceSvg.prototype.isDraggable=function(){return!!this.scrollbar};Blockly.WorkspaceSvg.prototype.onMouseWheel_=function(a){this.currentGesture_&&this.currentGesture_.cancel();var b=-a.deltaY/50,c=Blockly.utils.mouseToSvg(a,this.getParentSvg(),this.getInverseScreenCTM());this.zoom(c.x,c.y,b);a.preventDefault()};
                +Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox=function(){var a=this.getTopBlocks(!1);if(!a.length)return{x:0,y:0,width:0,height:0};for(var b=a[0].getBoundingRectangle(),c=1;c<a.length;c++){var d=a[c].getBoundingRectangle();d.topLeft.x<b.topLeft.x&&(b.topLeft.x=d.topLeft.x);d.bottomRight.x>b.bottomRight.x&&(b.bottomRight.x=d.bottomRight.x);d.topLeft.y<b.topLeft.y&&(b.topLeft.y=d.topLeft.y);d.bottomRight.y>b.bottomRight.y&&(b.bottomRight.y=d.bottomRight.y)}return{x:b.topLeft.x,y:b.topLeft.y,width:b.bottomRight.x-
                +b.topLeft.x,height:b.bottomRight.y-b.topLeft.y}};Blockly.WorkspaceSvg.prototype.cleanUp=function(){Blockly.Events.setGroup(!0);for(var a=this.getTopBlocks(!0),b=0,c=0,d;d=a[c];c++){var e=d.getRelativeToSurfaceXY();d.moveBy(-e.x,b-e.y);d.snapToGrid();b=d.getRelativeToSurfaceXY().y+d.getHeightWidth().height+Blockly.BlockSvg.MIN_BLOCK_Y}Blockly.Events.setGroup(!1);this.resizeContents()};
                +Blockly.WorkspaceSvg.prototype.showContextMenu_=function(a){function b(a){if(a.isDeletable())p=p.concat(a.getDescendants());else{a=a.getChildren();for(var c=0;c<a.length;c++)b(a[c])}}function c(){Blockly.Events.setGroup(f);var a=p.shift();a&&(a.workspace?(a.dispose(!1,!0),setTimeout(c,10)):c());Blockly.Events.setGroup(!1)}if(!this.options.readOnly&&!this.isFlyout){var d=[],e=this.getTopBlocks(!0),f=Blockly.utils.genUid(),g=this,h={};h.text=Blockly.Msg.UNDO;h.enabled=0<this.undoStack_.length;h.callback=
                +this.undo.bind(this,!1);d.push(h);h={};h.text=Blockly.Msg.REDO;h.enabled=0<this.redoStack_.length;h.callback=this.undo.bind(this,!0);d.push(h);this.scrollbar&&(h={},h.text=Blockly.Msg.CLEAN_UP,h.enabled=1<e.length,h.callback=this.cleanUp.bind(this),d.push(h));if(this.options.collapse){for(var k=h=!1,l=0;l<e.length;l++)for(var m=e[l];m;)m.isCollapsed()?h=!0:k=!0,m=m.getNextBlock();var n=function(a){for(var b=0,c=0;c<e.length;c++)for(var d=e[c];d;)setTimeout(d.setCollapsed.bind(d,a),b),d=d.getNextBlock(),
                +b+=10},k={enabled:k};k.text=Blockly.Msg.COLLAPSE_ALL;k.callback=function(){n(!0)};d.push(k);h={enabled:h};h.text=Blockly.Msg.EXPAND_ALL;h.callback=function(){n(!1)};d.push(h)}for(var p=[],l=0;l<e.length;l++)b(e[l]);h={text:1==p.length?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(p.length)),enabled:0<p.length,callback:function(){g.currentGesture_&&g.currentGesture_.cancel();2>p.length?c():Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace("%1",p.length),function(a){a&&
                +c()})}};d.push(h);Blockly.ContextMenu.show(a,d,this.RTL)}};
                +Blockly.WorkspaceSvg.prototype.updateToolbox=function(a){if(a=Blockly.Options.parseToolboxTree(a)){if(!this.options.languageTree)throw"Existing toolbox is null.  Can't create new toolbox.";if(a.getElementsByTagName("category").length){if(!this.toolbox_)throw"Existing toolbox has no categories.  Can't change mode.";this.options.languageTree=a;this.toolbox_.populate_(a);this.toolbox_.addColour_()}else{if(!this.flyout_)throw"Existing toolbox has categories.  Can't change mode.";this.options.languageTree=
                +a;this.flyout_.show(a.childNodes)}}else if(this.options.languageTree)throw"Can't nullify an existing toolbox.";};Blockly.WorkspaceSvg.prototype.markFocused=function(){this.options.parentWorkspace?this.options.parentWorkspace.markFocused():(Blockly.mainWorkspace=this,this.setBrowserFocus())};Blockly.WorkspaceSvg.prototype.setBrowserFocus=function(){document.activeElement&&document.activeElement.blur();try{this.getParentSvg().focus()}catch(a){try{this.getParentSvg().parentNode.setActive()}catch(b){this.getParentSvg().parentNode.focus()}}};
                +Blockly.WorkspaceSvg.prototype.zoom=function(a,b,c){var d=this.options.zoomOptions.scaleSpeed,e=this.getMetrics(),f=this.getParentSvg().createSVGPoint();f.x=a;f.y=b;f=f.matrixTransform(this.getCanvas().getCTM().inverse());a=f.x;b=f.y;f=this.getCanvas();d=Math.pow(d,c);c=this.scale*d;c>this.options.zoomOptions.maxScale?d=this.options.zoomOptions.maxScale/this.scale:c<this.options.zoomOptions.minScale&&(d=this.options.zoomOptions.minScale/this.scale);this.scale!=c&&(this.scrollbar&&(a=f.getCTM().translate(a*
                +(1-d),b*(1-d)).scale(d),this.scrollX=a.e-e.absoluteLeft,this.scrollY=a.f-e.absoluteTop),this.setScale(c))};Blockly.WorkspaceSvg.prototype.zoomCenter=function(a){var b=this.getMetrics();this.zoom(b.viewWidth/2,b.viewHeight/2,a)};
                +Blockly.WorkspaceSvg.prototype.zoomToFit=function(){var a=this.getMetrics(),b=this.getBlocksBoundingBox(),c=b.width,b=b.height;if(c){var d=a.viewWidth,e=a.viewHeight;this.flyout_&&(d-=this.flyout_.width_);this.scrollbar||(c+=a.contentLeft,b+=a.contentTop);this.setScale(Math.min(d/c,e/b));this.scrollCenter()}};
                +Blockly.WorkspaceSvg.prototype.scrollCenter=function(){if(this.scrollbar){var a=this.getMetrics(),b=(a.contentWidth-a.viewWidth)/2;this.flyout_&&(b-=this.flyout_.width_/2);this.scrollbar.set(b,(a.contentHeight-a.viewHeight)/2)}};
                +Blockly.WorkspaceSvg.prototype.setScale=function(a){this.options.zoomOptions.maxScale&&a>this.options.zoomOptions.maxScale?a=this.options.zoomOptions.maxScale:this.options.zoomOptions.minScale&&a<this.options.zoomOptions.minScale&&(a=this.options.zoomOptions.minScale);this.scale=a;this.grid_&&this.grid_.update(this.scale);this.scrollbar?this.scrollbar.resize():this.translate(this.scrollX,this.scrollY);Blockly.hideChaff(!1);this.flyout_&&this.flyout_.reflow()};
                +Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_=function(){var a=Blockly.svgSize(this.getParentSvg());if(this.toolbox_)if(this.toolboxPosition==Blockly.TOOLBOX_AT_TOP||this.toolboxPosition==Blockly.TOOLBOX_AT_BOTTOM)a.height-=this.toolbox_.getHeight();else if(this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT||this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT)a.width-=this.toolbox_.getWidth();var b=Blockly.Flyout.prototype.CORNER_RADIUS-1;var c=a.width-b;var d=a.height-b;var e=this.getBlocksBoundingBox();
                +var f=e.width*this.scale;var g=e.height*this.scale,h=e.x*this.scale,k=e.y*this.scale;this.scrollbar?(b=Math.min(h-c/2,h+f-c),f=Math.max(h+f+c/2,h+c),c=Math.min(k-d/2,k+g-d),d=Math.max(k+g+d/2,k+d)):(b=e.x,f=b+e.width,c=e.y,d=c+e.height);e=0;this.toolbox_&&this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT&&(e=this.toolbox_.getWidth());g=0;this.toolbox_&&this.toolboxPosition==Blockly.TOOLBOX_AT_TOP&&(g=this.toolbox_.getHeight());return{viewHeight:a.height,viewWidth:a.width,contentHeight:d-c,contentWidth:f-
                +b,viewTop:-this.scrollY,viewLeft:-this.scrollX,contentTop:c,contentLeft:b,absoluteTop:g,absoluteLeft:e,toolboxWidth:this.toolbox_?this.toolbox_.getWidth():0,toolboxHeight:this.toolbox_?this.toolbox_.getHeight():0,flyoutWidth:this.flyout_?this.flyout_.getWidth():0,flyoutHeight:this.flyout_?this.flyout_.getHeight():0,toolboxPosition:this.toolboxPosition}};
                +Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_=function(a){if(!this.scrollbar)throw"Attempt to set top level workspace scroll without scrollbars.";var b=this.getMetrics();goog.isNumber(a.x)&&(this.scrollX=-b.contentWidth*a.x-b.contentLeft);goog.isNumber(a.y)&&(this.scrollY=-b.contentHeight*a.y-b.contentTop);a=this.scrollX+b.absoluteLeft;b=this.scrollY+b.absoluteTop;this.translate(a,b);this.grid_&&this.grid_.moveTo(a,b)};
                +Blockly.WorkspaceSvg.prototype.setResizesEnabled=function(a){var b=!this.resizesEnabled_&&a;this.resizesEnabled_=a;b&&this.resizeContents()};Blockly.WorkspaceSvg.prototype.clear=function(){this.setResizesEnabled(!1);Blockly.WorkspaceSvg.superClass_.clear.call(this);this.setResizesEnabled(!0)};Blockly.WorkspaceSvg.prototype.registerButtonCallback=function(a,b){goog.asserts.assert(goog.isFunction(b),"Button callbacks must be functions.");this.flyoutButtonCallbacks_[a]=b};
                +Blockly.WorkspaceSvg.prototype.getButtonCallback=function(a){return(a=this.flyoutButtonCallbacks_[a])?a:null};Blockly.WorkspaceSvg.prototype.removeButtonCallback=function(a){this.flyoutButtonCallbacks_[a]=null};Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback=function(a,b){goog.asserts.assert(goog.isFunction(b),"Toolbox category callbacks must be functions.");this.toolboxCategoryCallbacks_[a]=b};
                +Blockly.WorkspaceSvg.prototype.getToolboxCategoryCallback=function(a){return(a=this.toolboxCategoryCallbacks_[a])?a:null};Blockly.WorkspaceSvg.prototype.removeToolboxCategoryCallback=function(a){this.toolboxCategoryCallbacks_[a]=null};
                +Blockly.WorkspaceSvg.prototype.getGesture=function(a){var b="mousedown"==a.type||"touchstart"==a.type,c=this.currentGesture_;return c?b&&c.hasStarted()?(console.warn("tried to start the same gesture twice"),c.cancel(),null):c:b?this.currentGesture_=new Blockly.Gesture(a,this):null};Blockly.WorkspaceSvg.prototype.clearGesture=function(){this.currentGesture_=null};Blockly.WorkspaceSvg.prototype.cancelCurrentGesture=function(){this.currentGesture_&&this.currentGesture_.cancel()};
                +Blockly.WorkspaceSvg.prototype.getAudioManager=function(){return this.audioManager_};Blockly.WorkspaceSvg.prototype.getGrid=function(){return this.grid_};Blockly.WorkspaceSvg.prototype.setVisible=Blockly.WorkspaceSvg.prototype.setVisible;Blockly.Mutator=function(a){Blockly.Mutator.superClass_.constructor.call(this,null);this.quarkNames_=a};goog.inherits(Blockly.Mutator,Blockly.Icon);Blockly.Mutator.prototype.workspaceWidth_=0;Blockly.Mutator.prototype.workspaceHeight_=0;
                +Blockly.Mutator.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("rect",{"class":"blocklyIconShape",rx:"4",ry:"4",height:"16",width:"16"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 -0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z"},a);
                +Blockly.utils.createSvgElement("circle",{"class":"blocklyIconShape",r:"2.7",cx:"8",cy:"8"},a)};Blockly.Mutator.prototype.iconClick_=function(a){this.block_.isEditable()&&Blockly.Icon.prototype.iconClick_.call(this,a)};
                +Blockly.Mutator.prototype.createEditor_=function(){this.svgDialog_=Blockly.utils.createSvgElement("svg",{x:Blockly.Bubble.BORDER_WIDTH,y:Blockly.Bubble.BORDER_WIDTH},null);if(this.quarkNames_.length){var a=goog.dom.createDom("xml");for(var b=0,c;c=this.quarkNames_[b];b++)a.appendChild(goog.dom.createDom("block",{type:c}))}else a=null;a={languageTree:a,parentWorkspace:this.block_.workspace,pathToMedia:this.block_.workspace.options.pathToMedia,RTL:this.block_.RTL,toolboxPosition:this.block_.RTL?Blockly.TOOLBOX_AT_RIGHT:
                +Blockly.TOOLBOX_AT_LEFT,horizontalLayout:!1,getMetrics:this.getFlyoutMetrics_.bind(this),setMetrics:null};this.workspace_=new Blockly.WorkspaceSvg(a);this.workspace_.isMutator=!0;a=this.workspace_.addFlyout_("g");b=this.workspace_.createDom("blocklyMutatorBackground");b.insertBefore(a,this.workspace_.svgBlockCanvas_);this.svgDialog_.appendChild(b);return this.svgDialog_};
                +Blockly.Mutator.prototype.updateEditable=function(){this.block_.isInFlyout||(this.block_.isEditable()?this.iconGroup_&&Blockly.utils.removeClass(this.iconGroup_,"blocklyIconGroupReadonly"):(this.setVisible(!1),this.iconGroup_&&Blockly.utils.addClass(this.iconGroup_,"blocklyIconGroupReadonly")));Blockly.Icon.prototype.updateEditable.call(this)};
                +Blockly.Mutator.prototype.resizeBubble_=function(){var a=2*Blockly.Bubble.BORDER_WIDTH,b=this.workspace_.getCanvas().getBBox();var c=this.block_.RTL?-b.x:b.width+b.x;b=b.height+3*a;if(this.workspace_.flyout_)var d=this.workspace_.flyout_.getMetrics_(),b=Math.max(b,d.contentHeight+20);c+=3*a;if(Math.abs(this.workspaceWidth_-c)>a||Math.abs(this.workspaceHeight_-b)>a)this.workspaceWidth_=c,this.workspaceHeight_=b,this.bubble_.setBubbleSize(c+a,b+a),this.svgDialog_.setAttribute("width",this.workspaceWidth_),
                +this.svgDialog_.setAttribute("height",this.workspaceHeight_);this.block_.RTL&&(a="translate("+this.workspaceWidth_+",0)",this.workspace_.getCanvas().setAttribute("transform",a));this.workspace_.resize()};
                +Blockly.Mutator.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"mutatorOpen",!a,a)),a){this.bubble_=new Blockly.Bubble(this.block_.workspace,this.createEditor_(),this.block_.svgPath_,this.iconXY_,null,null);if(a=this.workspace_.options.languageTree)this.workspace_.flyout_.init(this.workspace_),this.workspace_.flyout_.show(a.childNodes);this.rootBlock_=this.block_.decompose(this.workspace_);a=this.rootBlock_.getDescendants();var b=0;
                +for(var c;c=a[b];b++)c.render();this.rootBlock_.setMovable(!1);this.rootBlock_.setDeletable(!1);this.workspace_.flyout_?(b=2*this.workspace_.flyout_.CORNER_RADIUS,a=this.workspace_.flyout_.width_+b):a=b=16;this.block_.RTL&&(a=-a);this.rootBlock_.moveBy(a,b);if(this.block_.saveConnections){var d=this;this.block_.saveConnections(this.rootBlock_);this.sourceListener_=function(){d.block_.saveConnections(d.rootBlock_)};this.block_.workspace.addChangeListener(this.sourceListener_)}this.resizeBubble_();
                +this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));this.updateColour()}else this.svgDialog_=null,this.workspace_.dispose(),this.rootBlock_=this.workspace_=null,this.bubble_.dispose(),this.bubble_=null,this.workspaceHeight_=this.workspaceWidth_=0,this.sourceListener_&&(this.block_.workspace.removeChangeListener(this.sourceListener_),this.sourceListener_=null)};
                +Blockly.Mutator.prototype.workspaceChanged_=function(){var a;if(!this.workspace_.isDragging())for(var b=this.workspace_.getTopBlocks(!1),c=0;a=b[c];c++){var d=a.getRelativeToSurfaceXY(),e=a.getHeightWidth();20>d.y+e.height&&a.moveBy(0,20-e.height-d.y)}if(this.rootBlock_.workspace==this.workspace_){Blockly.Events.setGroup(!0);a=this.block_;b=(b=a.mutationToDom())&&Blockly.Xml.domToText(b);c=a.rendered;a.rendered=!1;a.compose(this.rootBlock_);a.rendered=c;a.initSvg();c=(c=a.mutationToDom())&&Blockly.Xml.domToText(c);
                +if(b!=c){Blockly.Events.fire(new Blockly.Events.BlockChange(a,"mutation",null,b,c));var f=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(f);a.bumpNeighbours_();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY)}a.rendered&&a.render();this.workspace_.isDragging()||this.resizeBubble_();Blockly.Events.setGroup(!1)}};Blockly.Mutator.prototype.getFlyoutMetrics_=function(){return{viewHeight:this.workspaceHeight_,viewWidth:this.workspaceWidth_,absoluteTop:0,absoluteLeft:0}};
                +Blockly.Mutator.prototype.dispose=function(){this.block_.mutator=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Mutator.reconnect=function(a,b,c){if(!a||!a.getSourceBlock().workspace)return!1;c=b.getInput(c).connection;var d=a.targetBlock();return d&&d!=b||c.targetConnection==a?!1:(c.isConnected()&&c.disconnect(),c.connect(a),!0)};goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.Mutator||(goog.global.Blockly.Mutator={});goog.global.Blockly.Mutator.reconnect=Blockly.Mutator.reconnect;Blockly.Warning=function(a){Blockly.Warning.superClass_.constructor.call(this,a);this.createIcon();this.text_={}};goog.inherits(Blockly.Warning,Blockly.Icon);Blockly.Warning.prototype.collapseHidden=!1;
                +Blockly.Warning.prototype.drawIcon_=function(a){Blockly.utils.createSvgElement("path",{"class":"blocklyIconShape",d:"M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z"},a);Blockly.utils.createSvgElement("path",{"class":"blocklyIconSymbol",d:"m7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z"},a);Blockly.utils.createSvgElement("rect",{"class":"blocklyIconSymbol",x:"7",y:"11",height:"2",width:"2"},a)};
                +Blockly.Warning.textToDom_=function(a){var b=Blockly.utils.createSvgElement("text",{"class":"blocklyText blocklyBubbleText",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c<a.length;c++){var d=Blockly.utils.createSvgElement("tspan",{dy:"1em",x:Blockly.Bubble.BORDER_WIDTH},b),e=document.createTextNode(a[c]);d.appendChild(e)}return b};
                +Blockly.Warning.prototype.setVisible=function(a){if(a!=this.isVisible())if(Blockly.Events.fire(new Blockly.Events.Ui(this.block_,"warningOpen",!a,a)),a){a=Blockly.Warning.textToDom_(this.getText());this.bubble_=new Blockly.Bubble(this.block_.workspace,a,this.block_.svgPath_,this.iconXY_,null,null);if(this.block_.RTL)for(var b=a.getBBox().width,c=0,d;d=a.childNodes[c];c++)d.setAttribute("text-anchor","end"),d.setAttribute("x",b+Blockly.Bubble.BORDER_WIDTH);this.updateColour();a=this.bubble_.getBubbleSize();
                +this.bubble_.setBubbleSize(a.width,a.height)}else this.bubble_.dispose(),this.body_=this.bubble_=null};Blockly.Warning.prototype.bodyFocus_=function(a){this.bubble_.promote_()};Blockly.Warning.prototype.setText=function(a,b){this.text_[b]!=a&&(a?this.text_[b]=a:delete this.text_[b],this.isVisible()&&(this.setVisible(!1),this.setVisible(!0)))};Blockly.Warning.prototype.getText=function(){var a=[],b;for(b in this.text_)a.push(this.text_[b]);return a.join("\n")};
                +Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.Block=function(a,b,c){this.id=c&&!a.getBlockById(c)?c:Blockly.utils.genUid();a.blockDB_[this.id]=this;this.previousConnection=this.nextConnection=this.outputConnection=null;this.inputList=[];this.inputsInline=void 0;this.disabled=!1;this.tooltip="";this.contextMenu=!0;this.parentBlock_=null;this.childBlocks_=[];this.editable_=this.movable_=this.deletable_=!0;this.collapsed_=this.isShadow_=!1;this.comment=null;this.xy_=new goog.math.Coordinate(0,0);this.workspace=a;this.isInFlyout=a.isFlyout;
                +this.isInMutator=a.isMutator;this.RTL=a.RTL;b&&(this.type=b,c=Blockly.Blocks[b],goog.asserts.assertObject(c,'Error: Unknown block type "%s".',b),goog.mixin(this,c));a.addTopBlock(this);goog.isFunction(this.init)&&this.init();this.inputsInlineDefault=this.inputsInline;Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(this));goog.isFunction(this.onchange)&&this.setOnChange(this.onchange)};
                +Blockly.Block.obtain=function(a,b){console.warn("Deprecated call to Blockly.Block.obtain, use workspace.newBlock instead.");return a.newBlock(b)};Blockly.Block.prototype.data=null;Blockly.Block.prototype.colour_="#000000";
                +Blockly.Block.prototype.dispose=function(a){if(this.workspace){this.onchangeWrapper_&&this.workspace.removeChangeListener(this.onchangeWrapper_);this.unplug(a);Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockDelete(this));Blockly.Events.disable();try{this.workspace&&(this.workspace.removeTopBlock(this),delete this.workspace.blockDB_[this.id],this.workspace=null);for(var b=this.childBlocks_.length-1;0<=b;b--)this.childBlocks_[b].dispose(!1);for(var b=0,c;c=this.inputList[b];b++)c.dispose();
                +this.inputList.length=0;for(var d=this.getConnections_(!0),b=0;b<d.length;b++){var e=d[b];e.isConnected()&&e.disconnect();d[b].dispose()}}finally{Blockly.Events.enable()}}};
                +Blockly.Block.prototype.unplug=function(a){if(this.outputConnection)this.outputConnection.isConnected()&&this.outputConnection.disconnect();else if(this.previousConnection){var b=null;this.previousConnection.isConnected()&&(b=this.previousConnection.targetConnection,this.previousConnection.disconnect());var c=this.getNextBlock();a&&c&&(a=this.nextConnection.targetConnection,a.disconnect(),b&&b.checkType_(a)&&b.connect(a))}};
                +Blockly.Block.prototype.getConnections_=function(){var a=[];this.outputConnection&&a.push(this.outputConnection);this.previousConnection&&a.push(this.previousConnection);this.nextConnection&&a.push(this.nextConnection);for(var b=0,c;c=this.inputList[b];b++)c.connection&&a.push(c.connection);return a};Blockly.Block.prototype.lastConnectionInStack_=function(){for(var a=this.nextConnection;a;){var b=a.targetBlock();if(!b)return a;a=b.nextConnection}return null};
                +Blockly.Block.prototype.bumpNeighbours_=function(){console.warn("Not expected to reach this bumpNeighbours_ function. The BlockSvg function for bumpNeighbours_ was expected to be called instead.")};Blockly.Block.prototype.getParent=function(){return this.parentBlock_};Blockly.Block.prototype.getInputWithBlock=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&c.connection.targetBlock()==a)return c;return null};
                +Blockly.Block.prototype.getSurroundParent=function(){var a=this;do{var b=a;a=a.getParent();if(!a)return null}while(a.getNextBlock()==b);return a};Blockly.Block.prototype.getNextBlock=function(){return this.nextConnection&&this.nextConnection.targetBlock()};Blockly.Block.prototype.getRootBlock=function(){var a=this;do{var b=a;a=b.parentBlock_}while(a);return b};Blockly.Block.prototype.getChildren=function(){return this.childBlocks_};
                +Blockly.Block.prototype.setParent=function(a){if(a!=this.parentBlock_){if(this.parentBlock_){goog.array.remove(this.parentBlock_.childBlocks_,this);if(this.previousConnection&&this.previousConnection.isConnected())throw"Still connected to previous block.";if(this.outputConnection&&this.outputConnection.isConnected())throw"Still connected to parent block.";this.parentBlock_=null}else this.workspace.removeTopBlock(this);(this.parentBlock_=a)?a.childBlocks_.push(this):this.workspace.addTopBlock(this)}};
                +Blockly.Block.prototype.getDescendants=function(){for(var a=[this],b,c=0;b=this.childBlocks_[c];c++)a.push.apply(a,b.getDescendants());return a};Blockly.Block.prototype.isDeletable=function(){return this.deletable_&&!this.isShadow_&&!(this.workspace&&this.workspace.options.readOnly)};Blockly.Block.prototype.setDeletable=function(a){this.deletable_=a};Blockly.Block.prototype.isMovable=function(){return this.movable_&&!this.isShadow_&&!(this.workspace&&this.workspace.options.readOnly)};
                +Blockly.Block.prototype.setMovable=function(a){this.movable_=a};Blockly.Block.prototype.isShadow=function(){return this.isShadow_};Blockly.Block.prototype.setShadow=function(a){this.isShadow_=a};Blockly.Block.prototype.isEditable=function(){return this.editable_&&!(this.workspace&&this.workspace.options.readOnly)};Blockly.Block.prototype.setEditable=function(a){this.editable_=a;a=0;for(var b;b=this.inputList[a];a++)for(var c=0,d;d=b.fieldRow[c];c++)d.updateEditable()};
                +Blockly.Block.prototype.setConnectionsHidden=function(a){var b;if(!a&&this.isCollapsed())this.outputConnection&&this.outputConnection.setHidden(a),this.previousConnection&&this.previousConnection.setHidden(a),this.nextConnection&&(this.nextConnection.setHidden(a),(b=this.nextConnection.targetBlock())&&b.setConnectionsHidden(a));else for(var c=this.getConnections_(!0),d=0;b=c[d];d++)b.setHidden(a),b.isSuperior()&&(b=b.targetBlock())&&b.setConnectionsHidden(a)};
                +Blockly.Block.prototype.setHelpUrl=function(a){this.helpUrl=a};Blockly.Block.prototype.setTooltip=function(a){this.tooltip=a};Blockly.Block.prototype.getColour=function(){return this.colour_};Blockly.Block.prototype.setColour=function(a){var b=Number(a);if(isNaN(b))if(goog.isString(a)&&a.match(/^#[0-9a-fA-F]{6}$/))this.colour_=a;else throw"Invalid colour: "+a;else this.colour_=Blockly.hueToRgb(b)};
                +Blockly.Block.prototype.setOnChange=function(a){if(a&&!goog.isFunction(a))throw Error("onchange must be a function.");this.onchangeWrapper_&&this.workspace.removeChangeListener(this.onchangeWrapper_);if(this.onchange=a)this.onchangeWrapper_=a.bind(this),this.workspace.addChangeListener(this.onchangeWrapper_)};Blockly.Block.prototype.getField=function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(e.name===a)return e;return null};
                +Blockly.Block.prototype.getVars=function(){for(var a=[],b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)e instanceof Blockly.FieldVariable&&a.push(e.getValue());return a};Blockly.Block.prototype.renameVar=function(a,b){for(var c=0,d;d=this.inputList[c];c++)for(var e=0,f;f=d.fieldRow[e];e++)f instanceof Blockly.FieldVariable&&Blockly.Names.equals(a,f.getValue())&&f.setValue(b)};Blockly.Block.prototype.getFieldValue=function(a){return(a=this.getField(a))?a.getValue():null};
                +Blockly.Block.prototype.setFieldValue=function(a,b){var c=this.getField(b);goog.asserts.assertObject(c,'Field "%s" not found.',b);c.setValue(a)};
                +Blockly.Block.prototype.setPreviousStatement=function(a,b){a?(void 0===b&&(b=null),this.previousConnection||(goog.asserts.assert(!this.outputConnection,"Remove output connection prior to adding previous connection."),this.previousConnection=this.makeConnection_(Blockly.PREVIOUS_STATEMENT)),this.previousConnection.setCheck(b)):this.previousConnection&&(goog.asserts.assert(!this.previousConnection.isConnected(),"Must disconnect previous statement before removing connection."),this.previousConnection.dispose(),
                +this.previousConnection=null)};Blockly.Block.prototype.setNextStatement=function(a,b){a?(void 0===b&&(b=null),this.nextConnection||(this.nextConnection=this.makeConnection_(Blockly.NEXT_STATEMENT)),this.nextConnection.setCheck(b)):this.nextConnection&&(goog.asserts.assert(!this.nextConnection.isConnected(),"Must disconnect next statement before removing connection."),this.nextConnection.dispose(),this.nextConnection=null)};
                +Blockly.Block.prototype.setOutput=function(a,b){a?(void 0===b&&(b=null),this.outputConnection||(goog.asserts.assert(!this.previousConnection,"Remove previous connection prior to adding output connection."),this.outputConnection=this.makeConnection_(Blockly.OUTPUT_VALUE)),this.outputConnection.setCheck(b)):this.outputConnection&&(goog.asserts.assert(!this.outputConnection.isConnected(),"Must disconnect output value before removing connection."),this.outputConnection.dispose(),this.outputConnection=
                +null)};Blockly.Block.prototype.setInputsInline=function(a){this.inputsInline!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"inline",null,this.inputsInline,a)),this.inputsInline=a)};
                +Blockly.Block.prototype.getInputsInline=function(){if(void 0!=this.inputsInline)return this.inputsInline;for(var a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.DUMMY_INPUT&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!1;for(a=1;a<this.inputList.length;a++)if(this.inputList[a-1].type==Blockly.INPUT_VALUE&&this.inputList[a].type==Blockly.DUMMY_INPUT)return!0;return!1};
                +Blockly.Block.prototype.setDisabled=function(a){this.disabled!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"disabled",null,this.disabled,a)),this.disabled=a)};Blockly.Block.prototype.getInheritedDisabled=function(){for(var a=this.getSurroundParent();a;){if(a.disabled)return!0;a=a.getSurroundParent()}return!1};Blockly.Block.prototype.isCollapsed=function(){return this.collapsed_};
                +Blockly.Block.prototype.setCollapsed=function(a){this.collapsed_!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"collapsed",null,this.collapsed_,a)),this.collapsed_=a)};
                +Blockly.Block.prototype.toString=function(a,b){var c=[],d=b||"?";if(this.collapsed_)c.push(this.getInput("_TEMP_COLLAPSED_INPUT").fieldRow[0].text_);else for(var e=0,f;f=this.inputList[e];e++){for(var g=0,h;h=f.fieldRow[g];g++)h instanceof Blockly.FieldDropdown&&!h.getValue()?c.push(d):c.push(h.getText());f.connection&&((f=f.connection.targetBlock())?c.push(f.toString(void 0,b)):c.push(d))}c=goog.string.trim(c.join(" "))||"???";a&&(c=goog.string.truncate(c,a));return c};
                +Blockly.Block.prototype.appendValueInput=function(a){return this.appendInput_(Blockly.INPUT_VALUE,a)};Blockly.Block.prototype.appendStatementInput=function(a){return this.appendInput_(Blockly.NEXT_STATEMENT,a)};Blockly.Block.prototype.appendDummyInput=function(a){return this.appendInput_(Blockly.DUMMY_INPUT,a||"")};
                +Blockly.Block.prototype.jsonInit=function(a){goog.asserts.assert(void 0==a.output||void 0==a.previousStatement,"Must not have both an output and a previousStatement.");if(void 0!==a.colour){var b=a.colour;b=goog.isString(b)?Blockly.utils.replaceMessageReferences(b):b;this.setColour(b)}for(b=0;void 0!==a["message"+b];)this.interpolate_(a["message"+b],a["args"+b]||[],a["lastDummyAlign"+b]),b++;void 0!==a.inputsInline&&this.setInputsInline(a.inputsInline);void 0!==a.output&&this.setOutput(!0,a.output);
                +void 0!==a.previousStatement&&this.setPreviousStatement(!0,a.previousStatement);void 0!==a.nextStatement&&this.setNextStatement(!0,a.nextStatement);void 0!==a.tooltip&&(b=a.tooltip,b=Blockly.utils.replaceMessageReferences(b),this.setTooltip(b));void 0!==a.enableContextMenu&&(b=a.enableContextMenu,this.contextMenu=!!b);void 0!==a.helpUrl&&(b=a.helpUrl,b=Blockly.utils.replaceMessageReferences(b),this.setHelpUrl(b));goog.isString(a.extensions)&&(console.warn("JSON attribute 'extensions' should be an array of strings. Found raw string in JSON for '"+
                +a.type+"' block."),a.extensions=[a.extensions]);void 0!==a.mutator&&Blockly.Extensions.apply(a.mutator,this,!0);if(Array.isArray(a.extensions))for(a=a.extensions,b=0;b<a.length;++b)Blockly.Extensions.apply(a[b],this,!1)};
                +Blockly.Block.prototype.mixin=function(a,b){if(goog.isDef(b)&&!goog.isBoolean(b))throw Error("opt_disableCheck must be a boolean if provided");if(!b){var c=[],d;for(d in a)void 0!==this[d]&&c.push(d);if(c.length)throw Error("Mixin will overwrite block members: "+JSON.stringify(c));}goog.mixin(this,a)};
                +Blockly.Block.prototype.interpolate_=function(a,b,c){var d=Blockly.utils.tokenizeInterpolation(a);var e=[];var f=0;a=[];for(var g=0;g<d.length;g++){var h=d[g];if("number"==typeof h){if(0>=h||h>b.length)throw Error('Block "'+this.type+'": Message index %'+h+" out of range.");if(e[h])throw Error('Block "'+this.type+'": Message index %'+h+" duplicated.");e[h]=!0;f++;a.push(b[h-1])}else(h=h.trim())&&a.push(h)}if(f!=b.length)throw Error('Block "'+this.type+'": Message does not reference all '+b.length+
                +" arg(s).");a.length&&("string"==typeof a[a.length-1]||goog.string.startsWith(a[a.length-1].type,"field_"))&&(g={type:"input_dummy"},c&&(g.align=c),a.push(g));c={LEFT:Blockly.ALIGN_LEFT,RIGHT:Blockly.ALIGN_RIGHT,CENTRE:Blockly.ALIGN_CENTRE};b=[];for(g=0;g<a.length;g++)if(f=a[g],"string"==typeof f)b.push([f,void 0]);else{d=h=null;do if(e=!1,"string"==typeof f)h=new Blockly.FieldLabel(f);else switch(f.type){case "input_value":d=this.appendValueInput(f.name);break;case "input_statement":d=this.appendStatementInput(f.name);
                +break;case "input_dummy":d=this.appendDummyInput(f.name);break;case "field_label":h=Blockly.Block.newFieldLabelFromJson_(f);break;case "field_input":h=Blockly.Block.newFieldTextInputFromJson_(f);break;case "field_angle":h=new Blockly.FieldAngle(f.angle);break;case "field_checkbox":h=new Blockly.FieldCheckbox(f.checked?"TRUE":"FALSE");break;case "field_colour":h=new Blockly.FieldColour(f.colour);break;case "field_variable":h=Blockly.Block.newFieldVariableFromJson_(f);break;case "field_dropdown":h=
                +new Blockly.FieldDropdown(f.options);break;case "field_image":h=Blockly.Block.newFieldImageFromJson_(f);break;case "field_number":h=new Blockly.FieldNumber(f.value,f.min,f.max,f.precision);break;case "field_date":if(Blockly.FieldDate){h=new Blockly.FieldDate(f.date);break}default:f.alt&&(f=f.alt,e=!0)}while(e);if(h)b.push([h,f.name]);else if(d){f.check&&d.setCheck(f.check);f.align&&d.setAlign(c[f.align]);for(e=0;e<b.length;e++)d.appendField(b[e][0],b[e][1]);b.length=0}}};
                +Blockly.Block.newFieldImageFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.src),c=Number(Blockly.utils.replaceMessageReferences(a.width)),d=Number(Blockly.utils.replaceMessageReferences(a.height));a=Blockly.utils.replaceMessageReferences(a.alt);return new Blockly.FieldImage(b,c,d,a)};Blockly.Block.newFieldLabelFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.text);return new Blockly.FieldLabel(b,a["class"])};
                +Blockly.Block.newFieldTextInputFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.text),b=new Blockly.FieldTextInput(b,a["class"]);"boolean"==typeof a.spellcheck&&b.setSpellcheck(a.spellcheck);return b};Blockly.Block.newFieldVariableFromJson_=function(a){var b=Blockly.utils.replaceMessageReferences(a.variable);return new Blockly.FieldVariable(b,null,a.variableTypes)};
                +Blockly.Block.prototype.appendInput_=function(a,b){var c=null;if(a==Blockly.INPUT_VALUE||a==Blockly.NEXT_STATEMENT)c=this.makeConnection_(a);c=new Blockly.Input(a,b,this,c);this.inputList.push(c);return c};
                +Blockly.Block.prototype.moveInputBefore=function(a,b){if(a!=b){for(var c=-1,d=b?-1:this.inputList.length,e=0,f;f=this.inputList[e];e++)if(f.name==a){if(c=e,-1!=d)break}else if(b&&f.name==b&&(d=e,-1!=c))break;goog.asserts.assert(-1!=c,'Named input "%s" not found.',a);goog.asserts.assert(-1!=d,'Reference input "%s" not found.',b);this.moveNumberedInputBefore(c,d)}};
                +Blockly.Block.prototype.moveNumberedInputBefore=function(a,b){goog.asserts.assert(a!=b,"Can't move input to itself.");goog.asserts.assert(a<this.inputList.length,"Input index "+a+" out of bounds.");goog.asserts.assert(b<=this.inputList.length,"Reference input "+b+" out of bounds.");var c=this.inputList[a];this.inputList.splice(a,1);a<b&&b--;this.inputList.splice(b,0,c)};
                +Blockly.Block.prototype.removeInput=function(a,b){for(var c=0,d;d=this.inputList[c];c++)if(d.name==a){if(d.connection&&d.connection.isConnected()){d.connection.setShadowDom(null);var e=d.connection.targetBlock();e.isShadow()?e.dispose():e.unplug()}d.dispose();this.inputList.splice(c,1);return}b||goog.asserts.fail('Input "%s" not found.',a)};Blockly.Block.prototype.getInput=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.name==a)return c;return null};
                +Blockly.Block.prototype.getInputTargetBlock=function(a){return(a=this.getInput(a))&&a.connection&&a.connection.targetBlock()};Blockly.Block.prototype.getCommentText=function(){return this.comment||""};Blockly.Block.prototype.setCommentText=function(a){this.comment!=a&&(Blockly.Events.fire(new Blockly.Events.BlockChange(this,"comment",null,this.comment,a||"")),this.comment=a)};Blockly.Block.prototype.setWarningText=function(){};Blockly.Block.prototype.setMutator=function(){};
                +Blockly.Block.prototype.getRelativeToSurfaceXY=function(){return this.xy_};Blockly.Block.prototype.moveBy=function(a,b){goog.asserts.assert(!this.parentBlock_,"Block has parent.");var c=new Blockly.Events.BlockMove(this);this.xy_.translate(a,b);c.recordNew();Blockly.Events.fire(c)};Blockly.Block.prototype.makeConnection_=function(a){return new Blockly.Connection(this,a)};
                +Blockly.Block.prototype.allInputsFilled=function(a){void 0===a&&(a=!0);if(!a&&this.isShadow())return!1;for(var b=0,c;c=this.inputList[b];b++)if(c.connection&&(c=c.connection.targetBlock(),!c||!c.allInputsFilled(a)))return!1;return(b=this.getNextBlock())?b.allInputsFilled(a):!0};Blockly.Block.prototype.toDevString=function(){var a=this.type?'"'+this.type+'" block':"Block";this.id&&(a+=' (id="'+this.id+'")');return a};Blockly.BlockDragSurfaceSvg=function(a){this.container_=a;this.createDom()};Blockly.BlockDragSurfaceSvg.prototype.SVG_=null;Blockly.BlockDragSurfaceSvg.prototype.dragGroup_=null;Blockly.BlockDragSurfaceSvg.prototype.container_=null;Blockly.BlockDragSurfaceSvg.prototype.scale_=1;Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_=null;
                +Blockly.BlockDragSurfaceSvg.prototype.createDom=function(){this.SVG_||(this.SVG_=Blockly.utils.createSvgElement("svg",{xmlns:Blockly.SVG_NS,"xmlns:html":Blockly.HTML_NS,"xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklyBlockDragSurface"},this.container_),this.dragGroup_=Blockly.utils.createSvgElement("g",{},this.SVG_))};
                +Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow=function(a){goog.asserts.assert(0==this.dragGroup_.childNodes.length,"Already dragging a block.");this.dragGroup_.appendChild(a);this.SVG_.style.display="block";this.surfaceXY_=new goog.math.Coordinate(0,0)};Blockly.BlockDragSurfaceSvg.prototype.translateAndScaleGroup=function(a,b,c){this.scale_=c;a=a.toFixed(0);b=b.toFixed(0);this.dragGroup_.setAttribute("transform","translate("+a+","+b+") scale("+c+")")};
                +Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_=function(){var a=this.surfaceXY_.x,b=this.surfaceXY_.y,a=a.toFixed(0),b=b.toFixed(0);this.SVG_.style.display="block";Blockly.utils.setCssTransform(this.SVG_,"translate3d("+a+"px, "+b+"px, 0px)")};Blockly.BlockDragSurfaceSvg.prototype.translateSurface=function(a,b){this.surfaceXY_=new goog.math.Coordinate(a*this.scale_,b*this.scale_);this.translateSurfaceInternal_()};
                +Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation=function(){var a=Blockly.utils.getRelativeXY(this.SVG_);return new goog.math.Coordinate(a.x/this.scale_,a.y/this.scale_)};Blockly.BlockDragSurfaceSvg.prototype.getGroup=function(){return this.dragGroup_};Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock=function(){return this.dragGroup_.firstChild};
                +Blockly.BlockDragSurfaceSvg.prototype.clearAndHide=function(a){a?a.appendChild(this.getCurrentBlock()):this.dragGroup_.removeChild(this.getCurrentBlock());this.SVG_.style.display="none";goog.asserts.assert(0==this.dragGroup_.childNodes.length,"Drag group was not cleared.");this.surfaceXY_=null};Blockly.ContextMenu={};Blockly.ContextMenu.currentBlock=null;Blockly.ContextMenu.eventWrapper_=null;Blockly.ContextMenu.show=function(a,b,c){Blockly.WidgetDiv.show(Blockly.ContextMenu,c,null);if(b.length){var d=Blockly.ContextMenu.populate_(b,c);goog.events.listen(d,goog.ui.Component.EventType.ACTION,Blockly.ContextMenu.hide);Blockly.ContextMenu.position_(d,a,c);setTimeout(function(){d.getElement().focus()},1);Blockly.ContextMenu.currentBlock=null}else Blockly.ContextMenu.hide()};
                +Blockly.ContextMenu.populate_=function(a,b){var c=new goog.ui.Menu;c.setAllowAutoFocus(!0);c.setRightToLeft(b);for(var d=0,e;e=a[d];d++){var f=new goog.ui.MenuItem(e.text);f.setRightToLeft(b);c.addChild(f,!0);f.setEnabled(e.enabled);e.enabled&&(goog.events.listen(f,goog.ui.Component.EventType.ACTION,e.callback),f.handleContextMenu=function(){goog.events.dispatchEvent(this,goog.ui.Component.EventType.ACTION)})}return c};
                +Blockly.ContextMenu.position_=function(a,b,c){var d=goog.dom.getViewportSize(),e=goog.style.getViewportPageOffset(document);a.render(Blockly.WidgetDiv.DIV);a=a.getElement();Blockly.utils.addClass(a,"blocklyContextMenu");Blockly.bindEventWithChecks_(a,"contextmenu",null,Blockly.utils.noEvent);a=goog.style.getSize(a);var f=b.clientX+e.x,g=b.clientY+e.y;b.clientY+a.height>=d.height&&(g-=a.height);c?a.width>=b.clientX&&(f+=a.width):b.clientX+a.width>=d.width&&(f-=a.width);Blockly.WidgetDiv.position(f,
                +g,d,e,c)};Blockly.ContextMenu.hide=function(){Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu);Blockly.ContextMenu.currentBlock=null;Blockly.ContextMenu.eventWrapper_&&Blockly.unbindEvent_(Blockly.ContextMenu.eventWrapper_)};
                +Blockly.ContextMenu.callbackFactory=function(a,b){return function(){Blockly.Events.disable();try{var c=Blockly.Xml.domToBlock(b,a.workspace);var d=a.getRelativeToSurfaceXY();d.x=a.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y)}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&!c.isShadow()&&Blockly.Events.fire(new Blockly.Events.BlockCreate(c));c.select()}};Blockly.BlockSvg=function(a,b,c){this.svgGroup_=Blockly.utils.createSvgElement("g",{},null);this.svgGroup_.translate_="";this.svgPathDark_=Blockly.utils.createSvgElement("path",{"class":"blocklyPathDark",transform:"translate(1,1)"},this.svgGroup_);this.svgPath_=Blockly.utils.createSvgElement("path",{"class":"blocklyPath"},this.svgGroup_);this.svgPathLight_=Blockly.utils.createSvgElement("path",{"class":"blocklyPathLight"},this.svgGroup_);this.svgPath_.tooltip=this;this.rendered=!1;this.useDragSurface_=
                +Blockly.utils.is3dSupported()&&!!a.blockDragSurface_;Blockly.Tooltip.bindMouseEvents(this.svgPath_);Blockly.BlockSvg.superClass_.constructor.call(this,a,b,c)};goog.inherits(Blockly.BlockSvg,Blockly.Block);Blockly.BlockSvg.prototype.height=0;Blockly.BlockSvg.prototype.width=0;Blockly.BlockSvg.prototype.dragStartXY_=null;Blockly.BlockSvg.INLINE=-1;
                +Blockly.BlockSvg.prototype.initSvg=function(){goog.asserts.assert(this.workspace.rendered,"Workspace is headless.");for(var a=0,b;b=this.inputList[a];a++)b.init();b=this.getIcons();for(a=0;a<b.length;a++)b[a].createIcon();this.updateColour();this.updateMovable();this.workspace.options.readOnly||this.eventsInit_||Blockly.bindEventWithChecks_(this.getSvgRoot(),"mousedown",this,this.onMouseDown_);this.eventsInit_=!0;this.getSvgRoot().parentNode||this.workspace.getCanvas().appendChild(this.getSvgRoot())};
                +Blockly.BlockSvg.prototype.select=function(){if(this.isShadow()&&this.getParent())this.getParent().select();else if(Blockly.selected!=this){var a=null;if(Blockly.selected){a=Blockly.selected.id;Blockly.Events.disable();try{Blockly.selected.unselect()}finally{Blockly.Events.enable()}}a=new Blockly.Events.Ui(null,"selected",a,this.id);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=this;this.addSelect()}};
                +Blockly.BlockSvg.prototype.unselect=function(){if(Blockly.selected==this){var a=new Blockly.Events.Ui(null,"selected",this.id,null);a.workspaceId=this.workspace.id;Blockly.Events.fire(a);Blockly.selected=null;this.removeSelect()}};Blockly.BlockSvg.prototype.mutator=null;Blockly.BlockSvg.prototype.comment=null;Blockly.BlockSvg.prototype.warning=null;
                +Blockly.BlockSvg.prototype.getIcons=function(){var a=[];this.mutator&&a.push(this.mutator);this.comment&&a.push(this.comment);this.warning&&a.push(this.warning);return a};
                +Blockly.BlockSvg.prototype.setParent=function(a){if(a!=this.parentBlock_){var b=this.getSvgRoot();if(this.parentBlock_&&b){var c=this.getRelativeToSurfaceXY();this.workspace.getCanvas().appendChild(b);b.setAttribute("transform","translate("+c.x+","+c.y+")")}Blockly.Field.startCache();Blockly.BlockSvg.superClass_.setParent.call(this,a);Blockly.Field.stopCache();a&&(c=this.getRelativeToSurfaceXY(),a.getSvgRoot().appendChild(b),a=this.getRelativeToSurfaceXY(),this.moveConnections_(a.x-c.x,a.y-c.y))}};
                +Blockly.BlockSvg.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0,c=this.useDragSurface_?this.workspace.blockDragSurface_.getGroup():null,d=this.getSvgRoot();if(d){do{var e=Blockly.utils.getRelativeXY(d),a=a+e.x,b=b+e.y;this.useDragSurface_&&this.workspace.blockDragSurface_.getCurrentBlock()==d&&(e=this.workspace.blockDragSurface_.getSurfaceTranslation(),a+=e.x,b+=e.y);d=d.parentNode}while(d&&d!=this.workspace.getCanvas()&&d!=c)}return new goog.math.Coordinate(a,b)};
                +Blockly.BlockSvg.prototype.moveBy=function(a,b){goog.asserts.assert(!this.parentBlock_,"Block has parent.");var c=new Blockly.Events.BlockMove(this),d=this.getRelativeToSurfaceXY();this.translate(d.x+a,d.y+b);this.moveConnections_(a,b);c.recordNew();this.workspace.resizeContents();Blockly.Events.fire(c)};Blockly.BlockSvg.prototype.translate=function(a,b){this.getSvgRoot().setAttribute("transform","translate("+a+","+b+")")};
                +Blockly.BlockSvg.prototype.moveToDragSurface_=function(){if(this.useDragSurface_){var a=this.getRelativeToSurfaceXY();this.clearTransformAttributes_();this.workspace.blockDragSurface_.translateSurface(a.x,a.y);this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot())}};Blockly.BlockSvg.prototype.moveOffDragSurface_=function(a){this.useDragSurface_&&(this.translate(a.x,a.y),this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas()))};
                +Blockly.BlockSvg.prototype.moveDuringDrag=function(a){this.useDragSurface_?this.workspace.blockDragSurface_.translateSurface(a.x,a.y):(this.svgGroup_.translate_="translate("+a.x+","+a.y+")",this.svgGroup_.setAttribute("transform",this.svgGroup_.translate_+this.svgGroup_.skew_))};Blockly.BlockSvg.prototype.clearTransformAttributes_=function(){Blockly.utils.removeAttribute(this.getSvgRoot(),"transform")};
                +Blockly.BlockSvg.prototype.snapToGrid=function(){if(this.workspace&&!this.workspace.isDragging()&&!this.getParent()&&!this.isInFlyout){var a=this.workspace.getGrid();if(a&&a.shouldSnap()){var b=a.getSpacing(),c=b/2,d=this.getRelativeToSurfaceXY(),a=Math.round((d.x-c)/b)*b+c-d.x,b=Math.round((d.y-c)/b)*b+c-d.y,a=Math.round(a),b=Math.round(b);0==a&&0==b||this.moveBy(a,b)}}};
                +Blockly.BlockSvg.prototype.getBoundingRectangle=function(){var a=this.getRelativeToSurfaceXY(this),b=this.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0,c=this.getHeightWidth();if(this.RTL){var d=new goog.math.Coordinate(a.x-(c.width-b),a.y);a=new goog.math.Coordinate(a.x+b,a.y+c.height)}else d=new goog.math.Coordinate(a.x-b,a.y),a=new goog.math.Coordinate(a.x+c.width-b,a.y+c.height);return{topLeft:d,bottomRight:a}};
                +Blockly.BlockSvg.prototype.setCollapsed=function(a){if(this.collapsed_!=a){for(var b=[],c=0,d;d=this.inputList[c];c++)b.push.apply(b,d.setVisible(!a));if(a){d=this.getIcons();for(c=0;c<d.length;c++)d[c].setVisible(!1);c=this.toString(Blockly.COLLAPSE_CHARS);this.appendDummyInput("_TEMP_COLLAPSED_INPUT").appendField(c).init()}else this.removeInput("_TEMP_COLLAPSED_INPUT"),this.setWarningText(null);Blockly.BlockSvg.superClass_.setCollapsed.call(this,a);b.length||(b[0]=this);if(this.rendered)for(c=0;a=
                +b[c];c++)a.render()}};Blockly.BlockSvg.prototype.tab=function(a,b){for(var c=[],d=0,e;e=this.inputList[d];d++){for(var f=0,g;g=e.fieldRow[f];f++)g instanceof Blockly.FieldTextInput&&c.push(g);e.connection&&(e=e.connection.targetBlock())&&c.push(e)}d=c.indexOf(a);-1==d&&(d=b?-1:c.length);(c=c[b?d+1:d-1])?c instanceof Blockly.Field?c.showEditor_():c.tab(null,b):(c=this.getParent())&&c.tab(this,b)};
                +Blockly.BlockSvg.prototype.onMouseDown_=function(a){var b=this.workspace.getGesture(a);b&&b.handleBlockStart(a,this)};Blockly.BlockSvg.prototype.showHelp_=function(){var a=goog.isFunction(this.helpUrl)?this.helpUrl():this.helpUrl;a&&window.open(a)};
                +Blockly.BlockSvg.prototype.showContextMenu_=function(a){if(!this.workspace.options.readOnly&&this.contextMenu){var b=this,c=[];if(this.isDeletable()&&this.isMovable()&&!b.isInFlyout){var d={text:Blockly.Msg.DUPLICATE_BLOCK,enabled:!0,callback:function(){Blockly.duplicate_(b)}};this.getDescendants().length>this.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&this.workspace.options.comments&&(d={enabled:!goog.userAgent.IE},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT,
                +d.callback=function(){b.setCommentText(null)}):(d.text=Blockly.Msg.ADD_COMMENT,d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=1;d<this.inputList.length;d++)if(this.inputList[d-1].type!=Blockly.NEXT_STATEMENT&&this.inputList[d].type!=Blockly.NEXT_STATEMENT){var d={enabled:!0},e=this.getInputsInline();d.text=e?Blockly.Msg.EXTERNAL_INPUTS:Blockly.Msg.INLINE_INPUTS;d.callback=function(){b.setInputsInline(!e)};c.push(d);break}this.workspace.options.collapse&&(this.collapsed_?
                +(d={enabled:!0},d.text=Blockly.Msg.EXPAND_BLOCK,d.callback=function(){b.setCollapsed(!1)}):(d={enabled:!0},d.text=Blockly.Msg.COLLAPSE_BLOCK,d.callback=function(){b.setCollapsed(!0)}),c.push(d));this.workspace.options.disable&&(d={text:this.disabled?Blockly.Msg.ENABLE_BLOCK:Blockly.Msg.DISABLE_BLOCK,enabled:!this.getInheritedDisabled(),callback:function(){b.setDisabled(!b.disabled)}},c.push(d));var d=this.getDescendants().length,f=this.getNextBlock();f&&(d-=f.getDescendants().length);d={text:1==d?
                +Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",String(d)),enabled:!0,callback:function(){Blockly.Events.setGroup(!0);b.dispose(!0,!0);Blockly.Events.setGroup(!1)}};c.push(d)}d={enabled:!(goog.isFunction(this.helpUrl)?!this.helpUrl():!this.helpUrl)};d.text=Blockly.Msg.HELP;d.callback=function(){b.showHelp_()};c.push(d);this.customContextMenu&&this.customContextMenu(c);Blockly.ContextMenu.show(a,c,this.RTL);Blockly.ContextMenu.currentBlock=this}};
                +Blockly.BlockSvg.prototype.moveConnections_=function(a,b){if(this.rendered){for(var c=this.getConnections_(!1),d=0;d<c.length;d++)c[d].moveBy(a,b);c=this.getIcons();for(d=0;d<c.length;d++)c[d].computeIconLocation();for(d=0;d<this.childBlocks_.length;d++)this.childBlocks_[d].moveConnections_(a,b)}};
                +Blockly.BlockSvg.prototype.setDragging=function(a){if(a){var b=this.getSvgRoot();b.translate_="";b.skew_="";Blockly.draggingConnections_=Blockly.draggingConnections_.concat(this.getConnections_(!0));Blockly.utils.addClass(this.svgGroup_,"blocklyDragging")}else Blockly.draggingConnections_=[],Blockly.utils.removeClass(this.svgGroup_,"blocklyDragging");for(b=0;b<this.childBlocks_.length;b++)this.childBlocks_[b].setDragging(a)};
                +Blockly.BlockSvg.prototype.updateMovable=function(){this.isMovable()?Blockly.utils.addClass(this.svgGroup_,"blocklyDraggable"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDraggable")};Blockly.BlockSvg.prototype.setMovable=function(a){Blockly.BlockSvg.superClass_.setMovable.call(this,a);this.updateMovable()};Blockly.BlockSvg.prototype.setEditable=function(a){Blockly.BlockSvg.superClass_.setEditable.call(this,a);a=this.getIcons();for(var b=0;b<a.length;b++)a[b].updateEditable()};
                +Blockly.BlockSvg.prototype.setShadow=function(a){Blockly.BlockSvg.superClass_.setShadow.call(this,a);this.updateColour()};Blockly.BlockSvg.prototype.getSvgRoot=function(){return this.svgGroup_};
                +Blockly.BlockSvg.prototype.dispose=function(a,b){if(this.workspace){Blockly.Tooltip.hide();Blockly.Field.startCache();var c=this.workspace;Blockly.selected==this&&(this.unselect(),this.workspace.cancelCurrentGesture());Blockly.ContextMenu.currentBlock==this&&Blockly.ContextMenu.hide();b&&this.rendered&&(this.unplug(a),this.disposeUiEffect());this.rendered=!1;Blockly.Events.disable();try{for(var d=this.getIcons(),e=0;e<d.length;e++)d[e].dispose()}finally{Blockly.Events.enable()}Blockly.BlockSvg.superClass_.dispose.call(this,
                +a);goog.dom.removeNode(this.svgGroup_);c.resizeContents();this.svgPathDark_=this.svgPathLight_=this.svgPath_=this.svgGroup_=null;Blockly.Field.stopCache()}};
                +Blockly.BlockSvg.prototype.disposeUiEffect=function(){this.workspace.getAudioManager().play("delete");var a=this.workspace.getSvgXY(this.svgGroup_),b=this.svgGroup_.cloneNode(!0);b.translateX_=a.x;b.translateY_=a.y;b.setAttribute("transform","translate("+b.translateX_+","+b.translateY_+")");this.workspace.getParentSvg().appendChild(b);b.bBox_=b.getBBox();Blockly.BlockSvg.disposeUiStep_(b,this.RTL,new Date,this.workspace.scale)};
                +Blockly.BlockSvg.disposeUiStep_=function(a,b,c,d){var e=(new Date-c)/150;1<e?goog.dom.removeNode(a):(a.setAttribute("transform","translate("+(a.translateX_+(b?-1:1)*a.bBox_.width*d/2*e)+","+(a.translateY_+a.bBox_.height*d*e)+") scale("+(1-e)*d+")"),setTimeout(Blockly.BlockSvg.disposeUiStep_,10,a,b,c,d))};
                +Blockly.BlockSvg.prototype.connectionUiEffect=function(){this.workspace.getAudioManager().play("click");if(!(1>this.workspace.scale)){var a=this.workspace.getSvgXY(this.svgGroup_);this.outputConnection?(a.x+=(this.RTL?3:-3)*this.workspace.scale,a.y+=13*this.workspace.scale):this.previousConnection&&(a.x+=(this.RTL?-23:23)*this.workspace.scale,a.y+=3*this.workspace.scale);a=Blockly.utils.createSvgElement("circle",{cx:a.x,cy:a.y,r:0,fill:"none",stroke:"#888","stroke-width":10},this.workspace.getParentSvg());
                +Blockly.BlockSvg.connectionUiStep_(a,new Date,this.workspace.scale)}};Blockly.BlockSvg.connectionUiStep_=function(a,b,c){var d=(new Date-b)/150;1<d?goog.dom.removeNode(a):(a.setAttribute("r",25*d*c),a.style.opacity=1-d,Blockly.BlockSvg.disconnectUiStop_.pid_=setTimeout(Blockly.BlockSvg.connectionUiStep_,10,a,b,c))};
                +Blockly.BlockSvg.prototype.disconnectUiEffect=function(){this.workspace.getAudioManager().play("disconnect");if(!(1>this.workspace.scale)){var a=this.getHeightWidth().height,a=Math.atan(10/a)/Math.PI*180;this.RTL||(a*=-1);Blockly.BlockSvg.disconnectUiStep_(this.svgGroup_,a,new Date)}};
                +Blockly.BlockSvg.disconnectUiStep_=function(a,b,c){var d=(new Date-c)/200;1<d?a.skew_="":(a.skew_="skewX("+Math.round(Math.sin(d*Math.PI*3)*(1-d)*b)+")",Blockly.BlockSvg.disconnectUiStop_.group=a,Blockly.BlockSvg.disconnectUiStop_.pid=setTimeout(Blockly.BlockSvg.disconnectUiStep_,10,a,b,c));a.setAttribute("transform",a.translate_+a.skew_)};
                +Blockly.BlockSvg.disconnectUiStop_=function(){if(Blockly.BlockSvg.disconnectUiStop_.group){clearTimeout(Blockly.BlockSvg.disconnectUiStop_.pid);var a=Blockly.BlockSvg.disconnectUiStop_.group;a.skew_="";a.setAttribute("transform",a.translate_);Blockly.BlockSvg.disconnectUiStop_.group=null}};Blockly.BlockSvg.disconnectUiStop_.pid=0;Blockly.BlockSvg.disconnectUiStop_.group=null;
                +Blockly.BlockSvg.prototype.updateColour=function(){if(!this.disabled){var a=this.getColour(),b=goog.color.hexToRgb(a);if(this.isShadow())b=goog.color.lighten(b,.6),a=goog.color.rgbArrayToHex(b),this.svgPathLight_.style.display="none",this.svgPathDark_.setAttribute("fill",a);else{this.svgPathLight_.style.display="";var c=goog.color.rgbArrayToHex(goog.color.lighten(b,.3)),b=goog.color.rgbArrayToHex(goog.color.darken(b,.2));this.svgPathLight_.setAttribute("stroke",c);this.svgPathDark_.setAttribute("fill",
                +b)}this.svgPath_.setAttribute("fill",a);a=this.getIcons();for(c=0;c<a.length;c++)a[c].updateColour();for(a=0;c=this.inputList[a];a++)for(var b=0,d;d=c.fieldRow[b];b++)d.setText(null)}};
                +Blockly.BlockSvg.prototype.updateDisabled=function(){this.disabled||this.getInheritedDisabled()?Blockly.utils.addClass(this.svgGroup_,"blocklyDisabled")&&this.svgPath_.setAttribute("fill","url(#"+this.workspace.options.disabledPatternId+")"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDisabled")&&this.updateColour();for(var a=this.getChildren(),b=0,c;c=a[b];b++)c.updateDisabled()};
                +Blockly.BlockSvg.prototype.getCommentText=function(){return this.comment?this.comment.getText().replace(/\s+$/,"").replace(/ +\n/g,"\n"):""};Blockly.BlockSvg.prototype.setCommentText=function(a){var b=!1;goog.isString(a)?(this.comment||(this.comment=new Blockly.Comment(this),b=!0),this.comment.setText(a)):this.comment&&(this.comment.dispose(),b=!0);b&&this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.setWarningText=function(a,b){this.setWarningText.pid_||(this.setWarningText.pid_=Object.create(null));var c=b||"";if(c)this.setWarningText.pid_[c]&&(clearTimeout(this.setWarningText.pid_[c]),delete this.setWarningText.pid_[c]);else for(var d in this.setWarningText.pid_)clearTimeout(this.setWarningText.pid_[d]),delete this.setWarningText.pid_[d];if(this.workspace.isDragging()){var e=this;this.setWarningText.pid_[c]=setTimeout(function(){e.workspace&&(delete e.setWarningText.pid_[c],
                +e.setWarningText(a,c))},100)}else{this.isInFlyout&&(a=null);d=this.getSurroundParent();for(var f=null;d;)d.isCollapsed()&&(f=d),d=d.getSurroundParent();f&&f.setWarningText(a,"collapsed "+this.id+" "+c);d=!1;goog.isString(a)?(this.warning||(this.warning=new Blockly.Warning(this),d=!0),this.warning.setText(a,c)):this.warning&&!c?(this.warning.dispose(),d=!0):this.warning&&(d=this.warning.getText(),this.warning.setText("",c),(f=this.warning.getText())||this.warning.dispose(),d=d!=f);d&&this.rendered&&
                +(this.render(),this.bumpNeighbours_())}};Blockly.BlockSvg.prototype.setMutator=function(a){this.mutator&&this.mutator!==a&&this.mutator.dispose();a&&(a.block_=this,this.mutator=a,a.createIcon())};Blockly.BlockSvg.prototype.setDisabled=function(a){this.disabled!=a&&(Blockly.BlockSvg.superClass_.setDisabled.call(this,a),this.rendered&&this.updateDisabled())};
                +Blockly.BlockSvg.prototype.setHighlighted=function(a){this.rendered&&(a?(this.svgPath_.setAttribute("filter","url(#"+this.workspace.options.embossFilterId+")"),this.svgPathLight_.style.display="none"):(Blockly.utils.removeAttribute(this.svgPath_,"filter"),delete this.svgPathLight_.style.display))};Blockly.BlockSvg.prototype.addSelect=function(){Blockly.utils.addClass(this.svgGroup_,"blocklySelected")};Blockly.BlockSvg.prototype.removeSelect=function(){Blockly.utils.removeClass(this.svgGroup_,"blocklySelected")};
                +Blockly.BlockSvg.prototype.setDeleteStyle=function(a){a?Blockly.utils.addClass(this.svgGroup_,"blocklyDraggingDelete"):Blockly.utils.removeClass(this.svgGroup_,"blocklyDraggingDelete")};Blockly.BlockSvg.prototype.setColour=function(a){Blockly.BlockSvg.superClass_.setColour.call(this,a);this.rendered&&this.updateColour()};Blockly.BlockSvg.prototype.bringToFront=function(){var a=this;do{var b=a.getSvgRoot();b.parentNode.appendChild(b);a=a.getParent()}while(a)};
                +Blockly.BlockSvg.prototype.setPreviousStatement=function(a,b){Blockly.BlockSvg.superClass_.setPreviousStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.setNextStatement=function(a,b){Blockly.BlockSvg.superClass_.setNextStatement.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.setOutput=function(a,b){Blockly.BlockSvg.superClass_.setOutput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.setInputsInline=function(a){Blockly.BlockSvg.superClass_.setInputsInline.call(this,a);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.removeInput=function(a,b){Blockly.BlockSvg.superClass_.removeInput.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.BlockSvg.prototype.moveNumberedInputBefore=function(a,b){Blockly.BlockSvg.superClass_.moveNumberedInputBefore.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_())};
                +Blockly.BlockSvg.prototype.appendInput_=function(a,b){var c=Blockly.BlockSvg.superClass_.appendInput_.call(this,a,b);this.rendered&&(this.render(),this.bumpNeighbours_());return c};Blockly.BlockSvg.prototype.getConnections_=function(a){var b=[];if(a||this.rendered)if(this.outputConnection&&b.push(this.outputConnection),this.previousConnection&&b.push(this.previousConnection),this.nextConnection&&b.push(this.nextConnection),a||!this.collapsed_){a=0;for(var c;c=this.inputList[a];a++)c.connection&&b.push(c.connection)}return b};
                +Blockly.BlockSvg.prototype.makeConnection_=function(a){return new Blockly.RenderedConnection(this,a)};
                +Blockly.BlockSvg.prototype.bumpNeighbours_=function(){if(this.workspace&&Blockly.dragMode_==Blockly.DRAG_NONE){var a=this.getRootBlock();if(!a.isInFlyout)for(var b=this.getConnections_(!1),c=0,d;d=b[c];c++){d.isConnected()&&d.isSuperior()&&d.targetBlock().bumpNeighbours_();for(var e=d.neighbours_(Blockly.SNAP_RADIUS),f=0,g;g=e[f];f++)d.isConnected()&&g.isConnected()||g.getSourceBlock().getRootBlock()!=a&&(d.isSuperior()?g.bumpAwayFrom_(d):d.bumpAwayFrom_(g))}}};
                +Blockly.BlockSvg.prototype.scheduleSnapAndBump=function(){var a=this,b=Blockly.Events.getGroup();setTimeout(function(){Blockly.Events.setGroup(b);a.snapToGrid();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY/2);setTimeout(function(){Blockly.Events.setGroup(b);a.bumpNeighbours_();Blockly.Events.setGroup(!1)},Blockly.BUMP_DELAY)};Blockly.BlockSvg.render={};Blockly.BlockSvg.SEP_SPACE_X=10;Blockly.BlockSvg.SEP_SPACE_Y=10;Blockly.BlockSvg.INLINE_PADDING_Y=5;Blockly.BlockSvg.MIN_BLOCK_Y=25;Blockly.BlockSvg.TAB_HEIGHT=20;Blockly.BlockSvg.TAB_WIDTH=8;Blockly.BlockSvg.NOTCH_WIDTH=30;Blockly.BlockSvg.CORNER_RADIUS=8;Blockly.BlockSvg.START_HAT=!1;Blockly.BlockSvg.START_HAT_HEIGHT=15;Blockly.BlockSvg.START_HAT_PATH="c 30,-"+Blockly.BlockSvg.START_HAT_HEIGHT+" 70,-"+Blockly.BlockSvg.START_HAT_HEIGHT+" 100,0";
                +Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR="c 17.8,-9.2 45.3,-14.9 75,-8.7 M 100.5,0.5";Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL="m 25,-8.7 c 29.7,-6.2 57.2,-0.5 75,8.7";Blockly.BlockSvg.DISTANCE_45_INSIDE=(1-Math.SQRT1_2)*(Blockly.BlockSvg.CORNER_RADIUS-.5)+.5;Blockly.BlockSvg.DISTANCE_45_OUTSIDE=(1-Math.SQRT1_2)*(Blockly.BlockSvg.CORNER_RADIUS+.5)-.5;Blockly.BlockSvg.NOTCH_PATH_LEFT="l 6,4 3,0 6,-4";Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT="l 6,4 3,0 6,-4";Blockly.BlockSvg.NOTCH_PATH_RIGHT="l -6,4 -3,0 -6,-4";
                +Blockly.BlockSvg.JAGGED_TEETH="l 8,0 0,4 8,4 -16,8 8,4";Blockly.BlockSvg.JAGGED_TEETH_HEIGHT=20;Blockly.BlockSvg.JAGGED_TEETH_WIDTH=15;Blockly.BlockSvg.TAB_PATH_DOWN="v 5 c 0,10 -"+Blockly.BlockSvg.TAB_WIDTH+",-8 -"+Blockly.BlockSvg.TAB_WIDTH+",7.5 s "+Blockly.BlockSvg.TAB_WIDTH+",-2.5 "+Blockly.BlockSvg.TAB_WIDTH+",7.5";
                +Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL="v 6.5 m -"+.97*Blockly.BlockSvg.TAB_WIDTH+",3 q -"+.05*Blockly.BlockSvg.TAB_WIDTH+",10 "+.3*Blockly.BlockSvg.TAB_WIDTH+",9.5 m "+.67*Blockly.BlockSvg.TAB_WIDTH+",-1.9 v 1.4";Blockly.BlockSvg.TOP_LEFT_CORNER_START="m 0,"+Blockly.BlockSvg.CORNER_RADIUS;Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL="m "+Blockly.BlockSvg.DISTANCE_45_INSIDE+","+Blockly.BlockSvg.DISTANCE_45_INSIDE;
                +Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR="m 0.5,"+(Blockly.BlockSvg.CORNER_RADIUS-.5);Blockly.BlockSvg.TOP_LEFT_CORNER="A "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,1 "+Blockly.BlockSvg.CORNER_RADIUS+",0";Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT="A "+(Blockly.BlockSvg.CORNER_RADIUS-.5)+","+(Blockly.BlockSvg.CORNER_RADIUS-.5)+" 0 0,1 "+Blockly.BlockSvg.CORNER_RADIUS+",0.5";
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER=Blockly.BlockSvg.NOTCH_PATH_RIGHT+" h -"+(Blockly.BlockSvg.NOTCH_WIDTH-15-Blockly.BlockSvg.CORNER_RADIUS)+" a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 -"+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS;Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER="a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS;
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL="a "+Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+" 0 0,0 "+(-Blockly.BlockSvg.DISTANCE_45_OUTSIDE-.5)+","+(Blockly.BlockSvg.CORNER_RADIUS-Blockly.BlockSvg.DISTANCE_45_OUTSIDE);Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL="a "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5)+" 0 0,0 "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5);
                +Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR="a "+(Blockly.BlockSvg.CORNER_RADIUS+.5)+","+(Blockly.BlockSvg.CORNER_RADIUS+.5)+" 0 0,0 "+(Blockly.BlockSvg.CORNER_RADIUS-Blockly.BlockSvg.DISTANCE_45_OUTSIDE)+","+(Blockly.BlockSvg.DISTANCE_45_OUTSIDE+.5);Blockly.BlockSvg.prototype.getHeightWidth=function(){var a=this.height,b=this.width,c=this.getNextBlock();c?(c=c.getHeightWidth(),a+=c.height-4,b=Math.max(b,c.width)):this.nextConnection||this.outputConnection||(a+=2);return{height:a,width:b}};
                +Blockly.BlockSvg.prototype.render=function(a){Blockly.Field.startCache();this.rendered=!0;var b=Blockly.BlockSvg.SEP_SPACE_X;this.RTL&&(b=-b);for(var c=this.getIcons(),d=0;d<c.length;d++)b=c[d].renderIcon(b);b+=this.RTL?Blockly.BlockSvg.SEP_SPACE_X:-Blockly.BlockSvg.SEP_SPACE_X;c=this.renderCompute_(b);this.renderDraw_(b,c);this.renderMoveConnections_();!1!==a&&((a=this.getParent())?a.render(!0):this.workspace.resizeContents());Blockly.Field.stopCache()};
                +Blockly.BlockSvg.prototype.renderFields_=function(a,b,c){c+=Blockly.BlockSvg.INLINE_PADDING_Y;this.RTL&&(b=-b);for(var d=0,e;e=a[d];d++){var f=e.getSvgRoot();f&&((goog.userAgent.IE||goog.userAgent.EDGE)&&e.updateWidth(),this.RTL?(b-=e.renderSep+e.renderWidth,f.setAttribute("transform","translate("+b+","+c+")"),e.renderWidth&&(b-=Blockly.BlockSvg.SEP_SPACE_X)):(f.setAttribute("transform","translate("+(b+e.renderSep)+","+c+")"),e.renderWidth&&(b+=e.renderSep+e.renderWidth+Blockly.BlockSvg.SEP_SPACE_X)))}return this.RTL?
                +-b:b};
                +Blockly.BlockSvg.prototype.renderCompute_=function(a){var b=this.inputList,c=[];c.rightEdge=a+2*Blockly.BlockSvg.SEP_SPACE_X;if(this.previousConnection||this.nextConnection)c.rightEdge=Math.max(c.rightEdge,Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.SEP_SPACE_X);for(var d=0,e=0,f=!1,g=!1,h=!1,k=void 0,l=this.getInputsInline()&&!this.isCollapsed(),m=0,n;n=b[m];m++)if(n.isVisible()){if(l&&k&&k!=Blockly.NEXT_STATEMENT&&n.type!=Blockly.NEXT_STATEMENT)var p=c[c.length-1];else k=n.type,p=[],p.type=l&&
                +n.type!=Blockly.NEXT_STATEMENT?Blockly.BlockSvg.INLINE:n.type,p.height=0,c.push(p);p.push(n);n.renderHeight=Blockly.BlockSvg.MIN_BLOCK_Y;n.renderWidth=l&&n.type==Blockly.INPUT_VALUE?Blockly.BlockSvg.TAB_WIDTH+1.25*Blockly.BlockSvg.SEP_SPACE_X:0;if(n.connection&&n.connection.isConnected()){var q=n.connection.targetBlock().getHeightWidth();n.renderHeight=Math.max(n.renderHeight,q.height);n.renderWidth=Math.max(n.renderWidth,q.width)}l||m!=b.length-1?!l&&n.type==Blockly.INPUT_VALUE&&b[m+1]&&b[m+1].type==
                +Blockly.NEXT_STATEMENT&&n.renderHeight--:n.renderHeight--;p.height=Math.max(p.height,n.renderHeight);n.fieldWidth=0;1==c.length&&(n.fieldWidth+=this.RTL?-a:a);for(var q=!1,t=0,r;r=n.fieldRow[t];t++){0!=t&&(n.fieldWidth+=Blockly.BlockSvg.SEP_SPACE_X);var u=r.getSize();r.renderWidth=u.width;r.renderSep=q&&r.EDITABLE?Blockly.BlockSvg.SEP_SPACE_X:0;n.fieldWidth+=r.renderWidth+r.renderSep;p.height=Math.max(p.height,u.height);q=r.EDITABLE}p.type!=Blockly.BlockSvg.INLINE&&(p.type==Blockly.NEXT_STATEMENT?
                +(g=!0,e=Math.max(e,n.fieldWidth)):(p.type==Blockly.INPUT_VALUE?f=!0:p.type==Blockly.DUMMY_INPUT&&(h=!0),d=Math.max(d,n.fieldWidth)))}for(a=0;p=c[a];a++)if(p.thicker=!1,p.type==Blockly.BlockSvg.INLINE)for(b=0;n=p[b];b++)if(n.type==Blockly.INPUT_VALUE){p.height+=2*Blockly.BlockSvg.INLINE_PADDING_Y;p.thicker=!0;break}c.statementEdge=2*Blockly.BlockSvg.SEP_SPACE_X+e;g&&(c.rightEdge=Math.max(c.rightEdge,c.statementEdge+Blockly.BlockSvg.NOTCH_WIDTH));f?c.rightEdge=Math.max(c.rightEdge,d+2*Blockly.BlockSvg.SEP_SPACE_X+
                +Blockly.BlockSvg.TAB_WIDTH):h&&(c.rightEdge=Math.max(c.rightEdge,d+2*Blockly.BlockSvg.SEP_SPACE_X));c.hasValue=f;c.hasStatement=g;c.hasDummy=h;return c};
                +Blockly.BlockSvg.prototype.renderDraw_=function(a,b){this.startHat_=!1;this.height=0;if(this.outputConnection)this.squareBottomLeftCorner_=this.squareTopLeftCorner_=!0;else{this.squareBottomLeftCorner_=this.squareTopLeftCorner_=!1;if(this.previousConnection){var c=this.previousConnection.targetBlock();c&&c.getNextBlock()==this&&(this.squareTopLeftCorner_=!0)}else Blockly.BlockSvg.START_HAT&&(this.startHat_=this.squareTopLeftCorner_=!0,this.height+=Blockly.BlockSvg.START_HAT_HEIGHT,b.rightEdge=Math.max(b.rightEdge,
                +100));this.getNextBlock()&&(this.squareBottomLeftCorner_=!0)}var d=[],e=[],c=[],f=[];this.renderDrawTop_(d,c,b.rightEdge);var g=this.renderDrawRight_(d,c,e,f,b,a);this.renderDrawBottom_(d,c,g);this.renderDrawLeft_(d,c);d=d.join(" ")+"\n"+e.join(" ");this.svgPath_.setAttribute("d",d);this.svgPathDark_.setAttribute("d",d);d=c.join(" ")+"\n"+f.join(" ");this.svgPathLight_.setAttribute("d",d);this.RTL&&(this.svgPath_.setAttribute("transform","scale(-1 1)"),this.svgPathLight_.setAttribute("transform",
                +"scale(-1 1)"),this.svgPathDark_.setAttribute("transform","translate(1,1) scale(-1 1)"))};
                +Blockly.BlockSvg.prototype.renderMoveConnections_=function(){var a=this.getRelativeToSurfaceXY();this.previousConnection&&this.previousConnection.moveToOffset(a);this.outputConnection&&this.outputConnection.moveToOffset(a);for(var b=0;b<this.inputList.length;b++){var c=this.inputList[b].connection;c&&(c.moveToOffset(a),c.isConnected()&&c.tighten_())}this.nextConnection&&(this.nextConnection.moveToOffset(a),this.nextConnection.isConnected()&&this.nextConnection.tighten_())};
                +Blockly.BlockSvg.prototype.renderDrawTop_=function(a,b,c){this.squareTopLeftCorner_?(a.push("m 0,0"),b.push("m 0.5,0.5"),this.startHat_&&(a.push(Blockly.BlockSvg.START_HAT_PATH),b.push(this.RTL?Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL:Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR))):(a.push(Blockly.BlockSvg.TOP_LEFT_CORNER_START),b.push(this.RTL?Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL:Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR),a.push(Blockly.BlockSvg.TOP_LEFT_CORNER),b.push(Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT));
                +this.previousConnection&&(a.push("H",Blockly.BlockSvg.NOTCH_WIDTH-15),b.push("H",Blockly.BlockSvg.NOTCH_WIDTH-15),a.push(Blockly.BlockSvg.NOTCH_PATH_LEFT),b.push(Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT),this.previousConnection.setOffsetInBlock(this.RTL?-Blockly.BlockSvg.NOTCH_WIDTH:Blockly.BlockSvg.NOTCH_WIDTH,0));a.push("H",c);b.push("H",c-.5);this.width=c};
                +Blockly.BlockSvg.prototype.renderDrawRight_=function(a,b,c,d,e,f){for(var g,h,k,l,m=0,n,p=0,q;q=e[p];p++){h=Blockly.BlockSvg.SEP_SPACE_X;0==p&&(h+=this.RTL?-f:f);b.push("M",e.rightEdge-.5+","+(m+.5));if(this.isCollapsed())l=q[0],k=h,h=m,this.renderFields_(l.fieldRow,k,h),a.push(Blockly.BlockSvg.JAGGED_TEETH),b.push("h 8"),l=q.height-Blockly.BlockSvg.JAGGED_TEETH_HEIGHT,a.push("v",l),this.RTL&&(b.push("v 3.9 l 7.2,3.4 m -14.5,8.9 l 7.3,3.5"),b.push("v",l-.7)),this.width+=Blockly.BlockSvg.JAGGED_TEETH_WIDTH;
                +else if(q.type==Blockly.BlockSvg.INLINE){for(g=0;l=q[g];g++)k=h,h=m,q.thicker&&(h+=Blockly.BlockSvg.INLINE_PADDING_Y),h=this.renderFields_(l.fieldRow,k,h),l.type!=Blockly.DUMMY_INPUT&&(h+=l.renderWidth+Blockly.BlockSvg.SEP_SPACE_X),l.type==Blockly.INPUT_VALUE&&(c.push("M",h-Blockly.BlockSvg.SEP_SPACE_X+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y)),c.push("h",Blockly.BlockSvg.TAB_WIDTH-2-l.renderWidth),c.push(Blockly.BlockSvg.TAB_PATH_DOWN),c.push("v",l.renderHeight+1-Blockly.BlockSvg.TAB_HEIGHT),c.push("h",
                +l.renderWidth+2-Blockly.BlockSvg.TAB_WIDTH),c.push("z"),this.RTL?(d.push("M",h-Blockly.BlockSvg.SEP_SPACE_X-2.5+Blockly.BlockSvg.TAB_WIDTH-l.renderWidth+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+.5)),d.push(Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL),d.push("v",l.renderHeight-Blockly.BlockSvg.TAB_HEIGHT+2.5),d.push("h",l.renderWidth-Blockly.BlockSvg.TAB_WIDTH+2)):(d.push("M",h-Blockly.BlockSvg.SEP_SPACE_X+.5+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+.5)),d.push("v",l.renderHeight+1),d.push("h",Blockly.BlockSvg.TAB_WIDTH-
                +2-l.renderWidth),d.push("M",h-l.renderWidth-Blockly.BlockSvg.SEP_SPACE_X+.9+","+(m+Blockly.BlockSvg.INLINE_PADDING_Y+Blockly.BlockSvg.TAB_HEIGHT-.7)),d.push("l",.46*Blockly.BlockSvg.TAB_WIDTH+",-2.1")),k=this.RTL?-h-Blockly.BlockSvg.TAB_WIDTH+Blockly.BlockSvg.SEP_SPACE_X+l.renderWidth+1:h+Blockly.BlockSvg.TAB_WIDTH-Blockly.BlockSvg.SEP_SPACE_X-l.renderWidth-1,n=m+Blockly.BlockSvg.INLINE_PADDING_Y+1,l.connection.setOffsetInBlock(k,n));h=Math.max(h,e.rightEdge);this.width=Math.max(this.width,h);a.push("H",
                +h);b.push("H",h-.5);a.push("v",q.height);this.RTL&&b.push("v",q.height-1)}else q.type==Blockly.INPUT_VALUE?(l=q[0],k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.rightEdge-l.fieldWidth-Blockly.BlockSvg.TAB_WIDTH-2*Blockly.BlockSvg.SEP_SPACE_X,l.align==Blockly.ALIGN_RIGHT?k+=g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),a.push(Blockly.BlockSvg.TAB_PATH_DOWN),g=q.height-Blockly.BlockSvg.TAB_HEIGHT,a.push("v",g),this.RTL?(b.push(Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL),
                +b.push("v",g+.5)):(b.push("M",e.rightEdge-5+","+(m+Blockly.BlockSvg.TAB_HEIGHT-.7)),b.push("l",.46*Blockly.BlockSvg.TAB_WIDTH+",-2.1")),k=this.RTL?-e.rightEdge-1:e.rightEdge+1,l.connection.setOffsetInBlock(k,m),l.connection.isConnected()&&(this.width=Math.max(this.width,e.rightEdge+l.connection.targetBlock().getHeightWidth().width-Blockly.BlockSvg.TAB_WIDTH+1))):q.type==Blockly.DUMMY_INPUT?(l=q[0],k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.rightEdge-l.fieldWidth-2*Blockly.BlockSvg.SEP_SPACE_X,e.hasValue&&
                +(g-=Blockly.BlockSvg.TAB_WIDTH),l.align==Blockly.ALIGN_RIGHT?k+=g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),a.push("v",q.height),this.RTL&&b.push("v",q.height-1)):q.type==Blockly.NEXT_STATEMENT&&(l=q[0],0==p&&(a.push("v",Blockly.BlockSvg.SEP_SPACE_Y),this.RTL&&b.push("v",Blockly.BlockSvg.SEP_SPACE_Y-1),m+=Blockly.BlockSvg.SEP_SPACE_Y),k=h,h=m,l.align!=Blockly.ALIGN_LEFT&&(g=e.statementEdge-l.fieldWidth-2*Blockly.BlockSvg.SEP_SPACE_X,l.align==Blockly.ALIGN_RIGHT?k+=
                +g:l.align==Blockly.ALIGN_CENTRE&&(k+=g/2)),this.renderFields_(l.fieldRow,k,h),h=e.statementEdge+Blockly.BlockSvg.NOTCH_WIDTH,a.push("H",h),a.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER),a.push("v",q.height-2*Blockly.BlockSvg.CORNER_RADIUS),a.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER),a.push("H",e.rightEdge),this.RTL?(b.push("M",h-Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.DISTANCE_45_OUTSIDE+","+(m+Blockly.BlockSvg.DISTANCE_45_OUTSIDE)),b.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL),
                +b.push("v",q.height-2*Blockly.BlockSvg.CORNER_RADIUS),b.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL)):(b.push("M",h-Blockly.BlockSvg.NOTCH_WIDTH+Blockly.BlockSvg.DISTANCE_45_OUTSIDE+","+(m+q.height-Blockly.BlockSvg.DISTANCE_45_OUTSIDE)),b.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR)),b.push("H",e.rightEdge-.5),k=this.RTL?-h:h+1,l.connection.setOffsetInBlock(k,m+1),l.connection.isConnected()&&(this.width=Math.max(this.width,e.statementEdge+l.connection.targetBlock().getHeightWidth().width)),
                +p==e.length-1||e[p+1].type==Blockly.NEXT_STATEMENT)&&(a.push("v",Blockly.BlockSvg.SEP_SPACE_Y),this.RTL&&b.push("v",Blockly.BlockSvg.SEP_SPACE_Y-1),m+=Blockly.BlockSvg.SEP_SPACE_Y);m+=q.height}e.length||(m=Blockly.BlockSvg.MIN_BLOCK_Y,a.push("V",m),this.RTL&&b.push("V",m-1));return m};
                +Blockly.BlockSvg.prototype.renderDrawBottom_=function(a,b,c){this.height+=c+1;this.nextConnection&&(a.push("H",Blockly.BlockSvg.NOTCH_WIDTH+(this.RTL?.5:-.5)+" "+Blockly.BlockSvg.NOTCH_PATH_RIGHT),this.nextConnection.setOffsetInBlock(this.RTL?-Blockly.BlockSvg.NOTCH_WIDTH:Blockly.BlockSvg.NOTCH_WIDTH,c+1),this.height+=4);this.squareBottomLeftCorner_?(a.push("H 0"),this.RTL||b.push("M","0.5,"+(c-.5))):(a.push("H",Blockly.BlockSvg.CORNER_RADIUS),a.push("a",Blockly.BlockSvg.CORNER_RADIUS+","+Blockly.BlockSvg.CORNER_RADIUS+
                +" 0 0,1 -"+Blockly.BlockSvg.CORNER_RADIUS+",-"+Blockly.BlockSvg.CORNER_RADIUS),this.RTL||(b.push("M",Blockly.BlockSvg.DISTANCE_45_INSIDE+","+(c-Blockly.BlockSvg.DISTANCE_45_INSIDE)),b.push("A",Blockly.BlockSvg.CORNER_RADIUS-.5+","+(Blockly.BlockSvg.CORNER_RADIUS-.5)+" 0 0,1 0.5,"+(c-Blockly.BlockSvg.CORNER_RADIUS))))};
                +Blockly.BlockSvg.prototype.renderDrawLeft_=function(a,b){this.outputConnection?(this.outputConnection.setOffsetInBlock(0,0),a.push("V",Blockly.BlockSvg.TAB_HEIGHT),a.push("c 0,-10 -"+Blockly.BlockSvg.TAB_WIDTH+",8 -"+Blockly.BlockSvg.TAB_WIDTH+",-7.5 s "+Blockly.BlockSvg.TAB_WIDTH+",2.5 "+Blockly.BlockSvg.TAB_WIDTH+",-7.5"),this.RTL?(b.push("M",-.25*Blockly.BlockSvg.TAB_WIDTH+",8.4"),b.push("l",-.45*Blockly.BlockSvg.TAB_WIDTH+",-2.1")):(b.push("V",Blockly.BlockSvg.TAB_HEIGHT-1.5),b.push("m",-.92*
                +Blockly.BlockSvg.TAB_WIDTH+",-0.5 q "+-.19*Blockly.BlockSvg.TAB_WIDTH+",-5.5 0,-11"),b.push("m",.92*Blockly.BlockSvg.TAB_WIDTH+",1 V 0.5 H 1")),this.width+=Blockly.BlockSvg.TAB_WIDTH):this.RTL||(this.squareTopLeftCorner_?b.push("V",.5):b.push("V",Blockly.BlockSvg.CORNER_RADIUS));a.push("z")};Blockly.Events={};Blockly.Events.group_="";Blockly.Events.recordUndo=!0;Blockly.Events.disabled_=0;Blockly.Events.CREATE="create";Blockly.Events.BLOCK_CREATE=Blockly.Events.CREATE;Blockly.Events.DELETE="delete";Blockly.Events.BLOCK_DELETE=Blockly.Events.DELETE;Blockly.Events.CHANGE="change";Blockly.Events.BLOCK_CHANGE=Blockly.Events.CHANGE;Blockly.Events.MOVE="move";Blockly.Events.BLOCK_MOVE=Blockly.Events.MOVE;Blockly.Events.VAR_CREATE="var_create";Blockly.Events.VAR_DELETE="var_delete";
                +Blockly.Events.VAR_RENAME="var_rename";Blockly.Events.UI="ui";Blockly.Events.FIRE_QUEUE_=[];Blockly.Events.fire=function(a){Blockly.Events.isEnabled()&&(Blockly.Events.FIRE_QUEUE_.length||setTimeout(Blockly.Events.fireNow_,0),Blockly.Events.FIRE_QUEUE_.push(a))};Blockly.Events.fireNow_=function(){for(var a=Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_,!0),b=Blockly.Events.FIRE_QUEUE_.length=0,c;c=a[b];b++){var d=Blockly.Workspace.getById(c.workspaceId);d&&d.fireChangeListener(c)}};
                +Blockly.Events.filter=function(a,b){var c=goog.array.clone(a);b||c.reverse();for(var d=0,e;e=c[d];d++)for(var f=d+1,g;g=c[f];f++)e.type==g.type&&e.blockId==g.blockId&&e.workspaceId==g.workspaceId&&(e.type==Blockly.Events.MOVE?(e.newParentId=g.newParentId,e.newInputName=g.newInputName,e.newCoordinate=g.newCoordinate,c.splice(f,1),f--):e.type==Blockly.Events.CHANGE&&e.element==g.element&&e.name==g.name?(e.newValue=g.newValue,c.splice(f,1),f--):e.type!=Blockly.Events.UI||"click"!=g.element||"commentOpen"!=
                +e.element&&"mutatorOpen"!=e.element&&"warningOpen"!=e.element||(e.newValue=g.newValue,c.splice(f,1),f--));for(d=c.length-1;0<=d;d--)c[d].isNull()&&c.splice(d,1);b||c.reverse();for(d=1;e=c[d];d++)e.type==Blockly.Events.CHANGE&&"mutation"==e.element&&c.unshift(c.splice(d,1)[0]);return c};Blockly.Events.clearPendingUndo=function(){for(var a=0,b;b=Blockly.Events.FIRE_QUEUE_[a];a++)b.recordUndo=!1};Blockly.Events.disable=function(){Blockly.Events.disabled_++};Blockly.Events.enable=function(){Blockly.Events.disabled_--};
                +Blockly.Events.isEnabled=function(){return 0==Blockly.Events.disabled_};Blockly.Events.getGroup=function(){return Blockly.Events.group_};Blockly.Events.setGroup=function(a){Blockly.Events.group_="boolean"==typeof a?a?Blockly.utils.genUid():"":a};Blockly.Events.getDescendantIds_=function(a){var b=[];a=a.getDescendants();for(var c=0,d;d=a[c];c++)b[c]=d.id;return b};
                +Blockly.Events.fromJson=function(a,b){switch(a.type){case Blockly.Events.CREATE:var c=new Blockly.Events.Create(null);break;case Blockly.Events.DELETE:c=new Blockly.Events.Delete(null);break;case Blockly.Events.CHANGE:c=new Blockly.Events.Change(null);break;case Blockly.Events.MOVE:c=new Blockly.Events.Move(null);break;case Blockly.Events.VAR_CREATE:c=new Blockly.Events.VarCreate(null);break;case Blockly.Events.VAR_DELETE:c=new Blockly.Events.VarDelete(null);break;case Blockly.Events.VAR_RENAME:c=
                +new Blockly.Events.VarRename(null);break;case Blockly.Events.UI:c=new Blockly.Events.Ui(null);break;default:throw"Unknown event type.";}c.fromJson(a);c.workspaceId=b.id;return c};Blockly.Events.Abstract=function(a){a instanceof Blockly.Block?(this.blockId=a.id,this.workspaceId=a.workspace.id):a instanceof Blockly.VariableModel&&(this.workspaceId=a.workspace.id,this.varId=a.getId());this.group=Blockly.Events.group_;this.recordUndo=Blockly.Events.recordUndo};
                +Blockly.Events.Abstract.prototype.toJson=function(){var a={type:this.type};this.blockId&&(a.blockId=this.blockId);this.varId&&(a.varId=this.varId);this.group&&(a.group=this.group);return a};Blockly.Events.Abstract.prototype.fromJson=function(a){this.blockId=a.blockId;this.varId=a.varId;this.group=a.group};Blockly.Events.Abstract.prototype.isNull=function(){return!1};Blockly.Events.Abstract.prototype.run=function(a){};
                +Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.Events.Create=function(a){a&&(Blockly.Events.Create.superClass_.constructor.call(this,a),this.xml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a),this.ids=Blockly.Events.getDescendantIds_(a))};goog.inherits(Blockly.Events.Create,Blockly.Events.Abstract);
                +Blockly.Events.BlockCreate=Blockly.Events.Create;Blockly.Events.Create.prototype.type=Blockly.Events.CREATE;Blockly.Events.Create.prototype.toJson=function(){var a=Blockly.Events.Create.superClass_.toJson.call(this);a.xml=Blockly.Xml.domToText(this.xml);a.ids=this.ids;return a};Blockly.Events.Create.prototype.fromJson=function(a){Blockly.Events.Create.superClass_.fromJson.call(this,a);this.xml=Blockly.Xml.textToDom("<xml>"+a.xml+"</xml>").firstChild;this.ids=a.ids};
                +Blockly.Events.Create.prototype.run=function(a){var b=this.getEventWorkspace_();if(a)a=goog.dom.createDom("xml"),a.appendChild(this.xml),Blockly.Xml.domToWorkspace(a,b);else{a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1,!1):c==this.blockId&&console.warn("Can't uncreate non-existant block: "+c)}}};
                +Blockly.Events.Delete=function(a){if(a){if(a.getParent())throw"Connected blocks cannot be deleted.";Blockly.Events.Delete.superClass_.constructor.call(this,a);this.oldXml=a.workspace.rendered?Blockly.Xml.blockToDomWithXY(a):Blockly.Xml.blockToDom(a);this.ids=Blockly.Events.getDescendantIds_(a)}};goog.inherits(Blockly.Events.Delete,Blockly.Events.Abstract);Blockly.Events.BlockDelete=Blockly.Events.Delete;Blockly.Events.Delete.prototype.type=Blockly.Events.DELETE;
                +Blockly.Events.Delete.prototype.toJson=function(){var a=Blockly.Events.Delete.superClass_.toJson.call(this);a.ids=this.ids;return a};Blockly.Events.Delete.prototype.fromJson=function(a){Blockly.Events.Delete.superClass_.fromJson.call(this,a);this.ids=a.ids};
                +Blockly.Events.Delete.prototype.run=function(a){var b=this.getEventWorkspace_();if(a){a=0;for(var c;c=this.ids[a];a++){var d=b.getBlockById(c);d?d.dispose(!1,!1):c==this.blockId&&console.warn("Can't delete non-existant block: "+c)}}else a=goog.dom.createDom("xml"),a.appendChild(this.oldXml),Blockly.Xml.domToWorkspace(a,b)};Blockly.Events.Change=function(a,b,c,d,e){a&&(Blockly.Events.Change.superClass_.constructor.call(this,a),this.element=b,this.name=c,this.oldValue=d,this.newValue=e)};
                +goog.inherits(Blockly.Events.Change,Blockly.Events.Abstract);Blockly.Events.BlockChange=Blockly.Events.Change;Blockly.Events.Change.prototype.type=Blockly.Events.CHANGE;Blockly.Events.Change.prototype.toJson=function(){var a=Blockly.Events.Change.superClass_.toJson.call(this);a.element=this.element;this.name&&(a.name=this.name);a.newValue=this.newValue;return a};
                +Blockly.Events.Change.prototype.fromJson=function(a){Blockly.Events.Change.superClass_.fromJson.call(this,a);this.element=a.element;this.name=a.name;this.newValue=a.newValue};Blockly.Events.Change.prototype.isNull=function(){return this.oldValue==this.newValue};
                +Blockly.Events.Change.prototype.run=function(a){var b=this.getEventWorkspace_().getBlockById(this.blockId);if(b)switch(b.mutator&&b.mutator.setVisible(!1),a=a?this.newValue:this.oldValue,this.element){case "field":(b=b.getField(this.name))?(b.callValidator(a),b.setValue(a)):console.warn("Can't set non-existant field: "+this.name);break;case "comment":b.setCommentText(a||null);break;case "collapsed":b.setCollapsed(a);break;case "disabled":b.setDisabled(a);break;case "inline":b.setInputsInline(a);break;
                +case "mutation":var c="";b.mutationToDom&&(c=(c=b.mutationToDom())&&Blockly.Xml.domToText(c));if(b.domToMutation){a=a||"<mutation></mutation>";var d=Blockly.Xml.textToDom("<xml>"+a+"</xml>");b.domToMutation(d.firstChild)}Blockly.Events.fire(new Blockly.Events.Change(b,"mutation",null,c,a));break;default:console.warn("Unknown change type: "+this.element)}else console.warn("Can't change non-existant block: "+this.blockId)};
                +Blockly.Events.Move=function(a){a&&(Blockly.Events.Move.superClass_.constructor.call(this,a),a=this.currentLocation_(),this.oldParentId=a.parentId,this.oldInputName=a.inputName,this.oldCoordinate=a.coordinate)};goog.inherits(Blockly.Events.Move,Blockly.Events.Abstract);Blockly.Events.BlockMove=Blockly.Events.Move;Blockly.Events.Move.prototype.type=Blockly.Events.MOVE;
                +Blockly.Events.Move.prototype.toJson=function(){var a=Blockly.Events.Move.superClass_.toJson.call(this);this.newParentId&&(a.newParentId=this.newParentId);this.newInputName&&(a.newInputName=this.newInputName);this.newCoordinate&&(a.newCoordinate=Math.round(this.newCoordinate.x)+","+Math.round(this.newCoordinate.y));return a};
                +Blockly.Events.Move.prototype.fromJson=function(a){Blockly.Events.Move.superClass_.fromJson.call(this,a);this.newParentId=a.newParentId;this.newInputName=a.newInputName;a.newCoordinate&&(a=a.newCoordinate.split(","),this.newCoordinate=new goog.math.Coordinate(parseFloat(a[0]),parseFloat(a[1])))};Blockly.Events.Move.prototype.recordNew=function(){var a=this.currentLocation_();this.newParentId=a.parentId;this.newInputName=a.inputName;this.newCoordinate=a.coordinate};
                +Blockly.Events.Move.prototype.currentLocation_=function(){var a=Blockly.Workspace.getById(this.workspaceId).getBlockById(this.blockId),b={},c=a.getParent();if(c){if(b.parentId=c.id,a=c.getInputWithBlock(a))b.inputName=a.name}else b.coordinate=a.getRelativeToSurfaceXY();return b};Blockly.Events.Move.prototype.isNull=function(){return this.oldParentId==this.newParentId&&this.oldInputName==this.newInputName&&goog.math.Coordinate.equals(this.oldCoordinate,this.newCoordinate)};
                +Blockly.Events.Move.prototype.run=function(a){var b=this.getEventWorkspace_(),c=b.getBlockById(this.blockId);if(c){var d=a?this.newParentId:this.oldParentId,e=a?this.newInputName:this.oldInputName;a=a?this.newCoordinate:this.oldCoordinate;var f=null;if(d&&(f=b.getBlockById(d),!f)){console.warn("Can't connect to non-existant block: "+d);return}c.getParent()&&c.unplug();if(a)e=c.getRelativeToSurfaceXY(),c.moveBy(a.x-e.x,a.y-e.y);else{var c=c.outputConnection||c.previousConnection;if(e){if(b=f.getInput(e))var g=
                +b.connection}else c.type==Blockly.PREVIOUS_STATEMENT&&(g=f.nextConnection);g?c.connect(g):console.warn("Can't connect to non-existant input: "+e)}}else console.warn("Can't move non-existant block: "+this.blockId)};Blockly.Events.Ui=function(a,b,c,d){Blockly.Events.Ui.superClass_.constructor.call(this,a);this.element=b;this.oldValue=c;this.newValue=d;this.recordUndo=!1};goog.inherits(Blockly.Events.Ui,Blockly.Events.Abstract);Blockly.Events.Ui.prototype.type=Blockly.Events.UI;
                +Blockly.Events.Ui.prototype.toJson=function(){var a=Blockly.Events.Ui.superClass_.toJson.call(this);a.element=this.element;void 0!==this.newValue&&(a.newValue=this.newValue);return a};Blockly.Events.Ui.prototype.fromJson=function(a){Blockly.Events.Ui.superClass_.fromJson.call(this,a);this.element=a.element;this.newValue=a.newValue};Blockly.Events.VarCreate=function(a){a&&(Blockly.Events.VarCreate.superClass_.constructor.call(this,a),this.varType=a.type,this.varName=a.name)};
                +goog.inherits(Blockly.Events.VarCreate,Blockly.Events.Abstract);Blockly.Events.VarCreate.prototype.type=Blockly.Events.VAR_CREATE;Blockly.Events.VarCreate.prototype.toJson=function(){var a=Blockly.Events.VarCreate.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a};Blockly.Events.VarCreate.prototype.fromJson=function(a){Blockly.Events.VarCreate.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};
                +Blockly.Events.VarCreate.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.createVariable(this.varName,this.varType,this.varId):b.deleteVariableById(this.varId)};Blockly.Events.VarDelete=function(a){a&&(Blockly.Events.VarDelete.superClass_.constructor.call(this,a),this.varType=a.type,this.varName=a.name)};goog.inherits(Blockly.Events.VarDelete,Blockly.Events.Abstract);Blockly.Events.VarDelete.prototype.type=Blockly.Events.VAR_DELETE;
                +Blockly.Events.VarDelete.prototype.toJson=function(){var a=Blockly.Events.VarDelete.superClass_.toJson.call(this);a.varType=this.varType;a.varName=this.varName;return a};Blockly.Events.VarDelete.prototype.fromJson=function(a){Blockly.Events.VarDelete.superClass_.fromJson.call(this,a);this.varType=a.varType;this.varName=a.varName};Blockly.Events.VarDelete.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.deleteVariableById(this.varId):b.createVariable(this.varName,this.varType,this.varId)};
                +Blockly.Events.VarRename=function(a,b){a&&(Blockly.Events.VarRename.superClass_.constructor.call(this,a),this.oldName=a.name,this.newName=b)};goog.inherits(Blockly.Events.VarRename,Blockly.Events.Abstract);Blockly.Events.VarRename.prototype.type=Blockly.Events.VAR_RENAME;Blockly.Events.VarRename.prototype.toJson=function(){var a=Blockly.Events.VarRename.superClass_.toJson.call(this);a.oldName=this.oldName;a.newName=this.newName;return a};
                +Blockly.Events.VarRename.prototype.fromJson=function(a){Blockly.Events.VarRename.superClass_.fromJson.call(this,a);this.oldName=a.oldName;this.newName=a.newName};Blockly.Events.VarRename.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.renameVariableById(this.varId,this.newName):b.renameVariableById(this.varId,this.oldName)};
                +Blockly.Events.disableOrphans=function(a){if(a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE){Blockly.Events.disable();var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId))if(a.getParent()&&!a.getParent().disabled){b=a.getDescendants();a=0;for(var c;c=b[a];a++)c.setDisabled(!1)}else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setDisabled(!0),a=a.getNextBlock();while(a)}Blockly.Events.enable()}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
                +Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_){var b=this.callValidator(a);null!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.text_,a)),Blockly.Field.prototype.setText.call(this,a)))};
                +Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};
                +Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;if(!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)){var b=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(a){b.sourceBlock_&&(a=b.callValidator(a));b.setValue(a)})}else{Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var c=Blockly.WidgetDiv.DIV,d=goog.dom.createDom("INPUT","blocklyHtmlInput");d.setAttribute("spellcheck",
                +this.spellcheck_);var e=Blockly.FieldTextInput.FONTSIZE*this.workspace_.scale+"pt";c.style.fontSize=e;d.style.fontSize=e;Blockly.FieldTextInput.htmlInput_=d;c.appendChild(d);d.value=d.defaultValue=this.text_;d.oldValue_=null;this.validate_();this.resizeEditor_();a||(d.focus(),d.select());d.onKeyDownWrapper_=Blockly.bindEventWithChecks_(d,"keydown",this,this.onHtmlInputKeyDown_);d.onKeyUpWrapper_=Blockly.bindEventWithChecks_(d,"keyup",this,this.onHtmlInputChange_);d.onKeyPressWrapper_=Blockly.bindEventWithChecks_(d,
                +"keypress",this,this.onHtmlInputChange_);d.onWorkspaceChangeWrapper_=this.resizeEditor_.bind(this);this.workspace_.addChangeListener(d.onWorkspaceChangeWrapper_)}};Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_=function(a){var b=Blockly.FieldTextInput.htmlInput_;13==a.keyCode?Blockly.WidgetDiv.hide():27==a.keyCode?(b.value=b.defaultValue,Blockly.WidgetDiv.hide()):9==a.keyCode&&(Blockly.WidgetDiv.hide(),this.sourceBlock_.tab(this,!a.shiftKey),a.preventDefault())};
                +Blockly.FieldTextInput.prototype.onHtmlInputChange_=function(a){a=Blockly.FieldTextInput.htmlInput_;var b=a.value;b!==a.oldValue_?(a.oldValue_=b,this.setValue(b),this.validate_()):goog.userAgent.WEBKIT&&this.sourceBlock_.render();this.resizeEditor_();Blockly.svgResize(this.sourceBlock_.workspace)};
                +Blockly.FieldTextInput.prototype.validate_=function(){var a=!0;goog.asserts.assertObject(Blockly.FieldTextInput.htmlInput_);var b=Blockly.FieldTextInput.htmlInput_;this.sourceBlock_&&(a=this.callValidator(b.value));null===a?Blockly.utils.addClass(b,"blocklyInvalidInput"):Blockly.utils.removeClass(b,"blocklyInvalidInput")};
                +Blockly.FieldTextInput.prototype.resizeEditor_=function(){var a=Blockly.WidgetDiv.DIV,b=this.fieldGroup_.getBBox();a.style.width=b.width*this.workspace_.scale+"px";a.style.height=b.height*this.workspace_.scale+"px";b=this.getAbsoluteXY_();if(this.sourceBlock_.RTL){var c=this.getScaledBBox_();b.x+=c.width;b.x-=a.offsetWidth}b.y+=1;goog.userAgent.GECKO&&Blockly.WidgetDiv.DIV.style.top&&(--b.x,--b.y);goog.userAgent.WEBKIT&&(b.y-=3);a.style.left=b.x+"px";a.style.top=b.y+"px"};
                +Blockly.FieldTextInput.prototype.widgetDispose_=function(){var a=this;return function(){var b=Blockly.FieldTextInput.htmlInput_,c=b.value;if(a.sourceBlock_)if(c=a.callValidator(c),null===c)c=b.defaultValue;else if(a.onFinishEditing_)a.onFinishEditing_(c);a.setText(c);a.sourceBlock_.rendered&&a.sourceBlock_.render();Blockly.unbindEvent_(b.onKeyDownWrapper_);Blockly.unbindEvent_(b.onKeyUpWrapper_);Blockly.unbindEvent_(b.onKeyPressWrapper_);a.workspace_.removeChangeListener(b.onWorkspaceChangeWrapper_);
                +Blockly.FieldTextInput.htmlInput_=null;Blockly.Events.setGroup(!1);b=Blockly.WidgetDiv.DIV.style;b.width="auto";b.height="auto";b.fontSize=""}};Blockly.FieldTextInput.numberValidator=function(a){console.warn("Blockly.FieldTextInput.numberValidator is deprecated. Use Blockly.FieldNumber instead.");if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=parseFloat(a||0);return isNaN(a)?null:String(a)};
                +Blockly.FieldTextInput.nonnegativeIntegerValidator=function(a){(a=Blockly.FieldTextInput.numberValidator(a))&&(a=String(Math.max(0,Math.floor(a))));return a};Blockly.FieldAngle=function(a,b){this.symbol_=Blockly.utils.createSvgElement("tspan",{},null);this.symbol_.appendChild(document.createTextNode("\u00b0"));a=a&&!isNaN(a)?String(a):"0";Blockly.FieldAngle.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldAngle,Blockly.FieldTextInput);Blockly.FieldAngle.ROUND=15;Blockly.FieldAngle.HALF=50;Blockly.FieldAngle.CLOCKWISE=!1;Blockly.FieldAngle.OFFSET=0;Blockly.FieldAngle.WRAP=360;Blockly.FieldAngle.RADIUS=Blockly.FieldAngle.HALF-1;
                +Blockly.FieldAngle.prototype.render_=function(){this.visible_?(this.textElement_.textContent=this.getDisplayText_(),this.sourceBlock_.RTL?this.textElement_.insertBefore(this.symbol_,this.textElement_.firstChild):this.textElement_.appendChild(this.symbol_),this.updateWidth()):this.size_.width=0};
                +Blockly.FieldAngle.prototype.dispose_=function(){var a=this;return function(){Blockly.FieldAngle.superClass_.dispose_.call(a)();a.gauge_=null;a.clickWrapper_&&Blockly.unbindEvent_(a.clickWrapper_);a.moveWrapper1_&&Blockly.unbindEvent_(a.moveWrapper1_);a.moveWrapper2_&&Blockly.unbindEvent_(a.moveWrapper2_)}};
                +Blockly.FieldAngle.prototype.showEditor_=function(){Blockly.FieldAngle.superClass_.showEditor_.call(this,goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD);var a=Blockly.WidgetDiv.DIV;if(a.firstChild){var a=Blockly.utils.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1",height:2*Blockly.FieldAngle.HALF+"px",width:2*Blockly.FieldAngle.HALF+"px"},a),b=Blockly.utils.createSvgElement("circle",
                +{cx:Blockly.FieldAngle.HALF,cy:Blockly.FieldAngle.HALF,r:Blockly.FieldAngle.RADIUS,"class":"blocklyAngleCircle"},a);this.gauge_=Blockly.utils.createSvgElement("path",{"class":"blocklyAngleGauge"},a);this.line_=Blockly.utils.createSvgElement("line",{x1:Blockly.FieldAngle.HALF,y1:Blockly.FieldAngle.HALF,"class":"blocklyAngleLine"},a);for(var c=0;360>c;c+=15)Blockly.utils.createSvgElement("line",{x1:Blockly.FieldAngle.HALF+Blockly.FieldAngle.RADIUS,y1:Blockly.FieldAngle.HALF,x2:Blockly.FieldAngle.HALF+
                +Blockly.FieldAngle.RADIUS-(0==c%45?10:5),y2:Blockly.FieldAngle.HALF,"class":"blocklyAngleMarks",transform:"rotate("+c+","+Blockly.FieldAngle.HALF+","+Blockly.FieldAngle.HALF+")"},a);a.style.marginLeft=15-Blockly.FieldAngle.RADIUS+"px";this.clickWrapper_=Blockly.bindEvent_(a,"click",this,Blockly.WidgetDiv.hide);this.moveWrapper1_=Blockly.bindEvent_(b,"mousemove",this,this.onMouseMove);this.moveWrapper2_=Blockly.bindEvent_(this.gauge_,"mousemove",this,this.onMouseMove);this.updateGraph_()}};
                +Blockly.FieldAngle.prototype.onMouseMove=function(a){var b=this.gauge_.ownerSVGElement.getBoundingClientRect(),c=a.clientX-b.left-Blockly.FieldAngle.HALF;a=a.clientY-b.top-Blockly.FieldAngle.HALF;b=Math.atan(-a/c);isNaN(b)||(b=goog.math.toDegrees(b),0>c?b+=180:0<a&&(b+=360),b=Blockly.FieldAngle.CLOCKWISE?Blockly.FieldAngle.OFFSET+360-b:b-Blockly.FieldAngle.OFFSET,Blockly.FieldAngle.ROUND&&(b=Math.round(b/Blockly.FieldAngle.ROUND)*Blockly.FieldAngle.ROUND),b=this.callValidator(b),Blockly.FieldTextInput.htmlInput_.value=
                +b,this.setValue(b),this.validate_(),this.resizeEditor_())};Blockly.FieldAngle.prototype.setText=function(a){Blockly.FieldAngle.superClass_.setText.call(this,a);this.textElement_&&(this.updateGraph_(),this.size_.width=0)};
                +Blockly.FieldAngle.prototype.updateGraph_=function(){if(this.gauge_){var a=Number(this.getText())+Blockly.FieldAngle.OFFSET,b=goog.math.toRadians(a),a=["M ",Blockly.FieldAngle.HALF,",",Blockly.FieldAngle.HALF],c=Blockly.FieldAngle.HALF,d=Blockly.FieldAngle.HALF;if(!isNaN(b)){var e=goog.math.toRadians(Blockly.FieldAngle.OFFSET),f=Math.cos(e)*Blockly.FieldAngle.RADIUS,g=Math.sin(e)*-Blockly.FieldAngle.RADIUS;Blockly.FieldAngle.CLOCKWISE&&(b=2*e-b);c+=Math.cos(b)*Blockly.FieldAngle.RADIUS;d-=Math.sin(b)*
                +Blockly.FieldAngle.RADIUS;b=Math.abs(Math.floor((b-e)/Math.PI)%2);Blockly.FieldAngle.CLOCKWISE&&(b=1-b);a.push(" l ",f,",",g," A ",Blockly.FieldAngle.RADIUS,",",Blockly.FieldAngle.RADIUS," 0 ",b," ",Number(Blockly.FieldAngle.CLOCKWISE)," ",c,",",d," z")}this.gauge_.setAttribute("d",a.join(""));this.line_.setAttribute("x2",c);this.line_.setAttribute("y2",d)}};
                +Blockly.FieldAngle.prototype.classValidator=function(a){if(null===a)return null;a=parseFloat(a||0);if(isNaN(a))return null;a%=360;0>a&&(a+=360);a>Blockly.FieldAngle.WRAP&&(a-=360);return String(a)};Blockly.FieldCheckbox=function(a,b){Blockly.FieldCheckbox.superClass_.constructor.call(this,"",b);this.setValue(a)};goog.inherits(Blockly.FieldCheckbox,Blockly.Field);Blockly.FieldCheckbox.CHECK_CHAR="\u2713";Blockly.FieldCheckbox.prototype.CURSOR="default";
                +Blockly.FieldCheckbox.prototype.init=function(){if(!this.fieldGroup_){Blockly.FieldCheckbox.superClass_.init.call(this);this.checkElement_=Blockly.utils.createSvgElement("text",{"class":"blocklyText blocklyCheckbox",x:-3,y:14},this.fieldGroup_);var a=document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR);this.checkElement_.appendChild(a);this.checkElement_.style.display=this.state_?"block":"none"}};Blockly.FieldCheckbox.prototype.getValue=function(){return String(this.state_).toUpperCase()};
                +Blockly.FieldCheckbox.prototype.setValue=function(a){a="string"==typeof a?"TRUE"==a.toUpperCase():!!a;this.state_!==a&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.state_,a)),this.state_=a,this.checkElement_&&(this.checkElement_.style.display=a?"block":"none"))};Blockly.FieldCheckbox.prototype.showEditor_=function(){var a=!this.state_;this.sourceBlock_&&(a=this.callValidator(a));null!==a&&this.setValue(String(a).toUpperCase())};Blockly.FieldColour=function(a,b){Blockly.FieldColour.superClass_.constructor.call(this,a,b);this.setText(Blockly.Field.NBSP+Blockly.Field.NBSP+Blockly.Field.NBSP)};goog.inherits(Blockly.FieldColour,Blockly.Field);Blockly.FieldColour.prototype.colours_=null;Blockly.FieldColour.prototype.columns_=0;Blockly.FieldColour.prototype.init=function(){Blockly.FieldColour.superClass_.init.call(this);this.borderRect_.style.fillOpacity=1;this.setValue(this.getValue())};Blockly.FieldColour.prototype.CURSOR="default";
                +Blockly.FieldColour.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldColour.superClass_.dispose.call(this)};Blockly.FieldColour.prototype.getValue=function(){return this.colour_};Blockly.FieldColour.prototype.setValue=function(a){this.sourceBlock_&&Blockly.Events.isEnabled()&&this.colour_!=a&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.colour_,a));this.colour_=a;this.borderRect_&&(this.borderRect_.style.fill=a)};
                +Blockly.FieldColour.prototype.getText=function(){var a=this.colour_,b=a.match(/^#(.)\1(.)\2(.)\3$/);b&&(a="#"+b[1]+b[2]+b[3]);return a};Blockly.FieldColour.COLOURS=goog.ui.ColorPicker.SIMPLE_GRID_COLORS;Blockly.FieldColour.COLUMNS=7;Blockly.FieldColour.prototype.setColours=function(a){this.colours_=a;return this};Blockly.FieldColour.prototype.setColumns=function(a){this.columns_=a;return this};
                +Blockly.FieldColour.prototype.showEditor_=function(){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,Blockly.FieldColour.widgetDispose_);var a=new goog.ui.ColorPicker;a.setSize(this.columns_||Blockly.FieldColour.COLUMNS);a.setColors(this.colours_||Blockly.FieldColour.COLOURS);var b=goog.dom.getViewportSize(),c=goog.style.getViewportPageOffset(document),d=this.getAbsoluteXY_(),e=this.getScaledBBox_();a.render(Blockly.WidgetDiv.DIV);a.setSelectedColor(this.getValue());var f=goog.style.getSize(a.getElement());
                +d.y=d.y+f.height+e.height>=b.height+c.y?d.y-(f.height-1):d.y+(e.height-1);this.sourceBlock_.RTL?(d.x+=e.width,d.x-=f.width,d.x<c.x&&(d.x=c.x)):d.x>b.width+c.x-f.width&&(d.x=b.width+c.x-f.width);Blockly.WidgetDiv.position(d.x,d.y,b,c,this.sourceBlock_.RTL);var g=this;Blockly.FieldColour.changeEventKey_=goog.events.listen(a,goog.ui.ColorPicker.EventType.CHANGE,function(a){a=a.target.getSelectedColor()||"#000000";Blockly.WidgetDiv.hide();g.sourceBlock_&&(a=g.callValidator(a));null!==a&&g.setValue(a)})};
                +Blockly.FieldColour.widgetDispose_=function(){Blockly.FieldColour.changeEventKey_&&goog.events.unlistenByKey(Blockly.FieldColour.changeEventKey_);Blockly.Events.setGroup(!1)};Blockly.FieldDropdown=function(a,b){this.menuGenerator_=a;this.trimOptions_();var c=this.getOptions()[0];Blockly.FieldDropdown.superClass_.constructor.call(this,c[1],b)};goog.inherits(Blockly.FieldDropdown,Blockly.Field);Blockly.FieldDropdown.CHECKMARK_OVERHANG=25;Blockly.FieldDropdown.ARROW_CHAR=goog.userAgent.ANDROID?"\u25bc":"\u25be";Blockly.FieldDropdown.prototype.CURSOR="default";Blockly.FieldDropdown.prototype.value_="";Blockly.FieldDropdown.prototype.imageElement_=null;
                +Blockly.FieldDropdown.prototype.imageJson_=null;Blockly.FieldDropdown.prototype.init=function(){if(!this.fieldGroup_){this.arrow_=Blockly.utils.createSvgElement("tspan",{},null);this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL?Blockly.FieldDropdown.ARROW_CHAR+" ":" "+Blockly.FieldDropdown.ARROW_CHAR));Blockly.FieldDropdown.superClass_.init.call(this);var a=this.text_;this.text_=null;this.setText(a)}};
                +Blockly.FieldDropdown.prototype.showEditor_=function(){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,null);var a=this,b=new goog.ui.Menu;b.setRightToLeft(this.sourceBlock_.RTL);for(var c=this.getOptions(),d=0;d<c.length;d++){var e=c[d][0],f=c[d][1];if("object"==typeof e){var g=new Image(e.width,e.height);g.src=e.src;g.alt=e.alt||"";e=g}e=new goog.ui.MenuItem(e);e.setRightToLeft(this.sourceBlock_.RTL);e.setValue(f);e.setCheckable(!0);b.addChild(e,!0);e.setChecked(f==this.value_)}goog.events.listen(b,
                +goog.ui.Component.EventType.ACTION,function(b){if(b=b.target)a.onItemSelected(this,b);Blockly.WidgetDiv.hideIfOwner(a);Blockly.Events.setGroup(!1)});b.getHandler().listen(b.getElement(),goog.events.EventType.TOUCHSTART,function(a){this.getOwnerControl(a.target).handleMouseDown(a)});b.getHandler().listen(b.getElement(),goog.events.EventType.TOUCHEND,function(a){this.getOwnerControl(a.target).performActionInternal(a)});c=goog.dom.getViewportSize();d=goog.style.getViewportPageOffset(document);f=this.getAbsoluteXY_();
                +e=this.getScaledBBox_();b.render(Blockly.WidgetDiv.DIV);g=b.getElement();Blockly.utils.addClass(g,"blocklyDropdownMenu");var h=goog.style.getSize(g);h.height=g.scrollHeight;f.y=f.y+h.height+e.height>=c.height+d.y?f.y-(h.height+2):f.y+e.height;this.sourceBlock_.RTL?(f.x+=e.width,f.x+=Blockly.FieldDropdown.CHECKMARK_OVERHANG,f.x<d.x+h.width&&(f.x=d.x+h.width)):(f.x-=Blockly.FieldDropdown.CHECKMARK_OVERHANG,f.x>c.width+d.x-h.width&&(f.x=c.width+d.x-h.width));Blockly.WidgetDiv.position(f.x,f.y,c,d,this.sourceBlock_.RTL);
                +b.setAllowAutoFocus(!0);g.focus()};Blockly.FieldDropdown.prototype.onItemSelected=function(a,b){var c=b.getValue();this.sourceBlock_&&(c=this.callValidator(c));null!==c&&this.setValue(c)};
                +Blockly.FieldDropdown.prototype.trimOptions_=function(){this.suffixField=this.prefixField=null;var a=this.menuGenerator_;if(goog.isArray(a)){for(var b=!1,c=0;c<a.length;c++){var d=a[c][0];"string"==typeof d?a[c][0]=Blockly.utils.replaceMessageReferences(d):(null!=d.alt&&(a[c][0].alt=Blockly.utils.replaceMessageReferences(d.alt)),b=!0)}if(!(b||2>a.length)){for(var e=[],c=0;c<a.length;c++)e.push(a[c][0]);c=Blockly.utils.shortestStringLength(e);b=Blockly.utils.commonWordPrefix(e,c);d=Blockly.utils.commonWordSuffix(e,
                +c);if((b||d)&&!(c<=b+d)){b&&(this.prefixField=e[0].substring(0,b-1));d&&(this.suffixField=e[0].substr(1-d));e=[];for(c=0;c<a.length;c++){var f=a[c][0],g=a[c][1],f=f.substring(b,f.length-d);e[c]=[f,g]}this.menuGenerator_=e}}}};Blockly.FieldDropdown.prototype.isOptionListDynamic=function(){return goog.isFunction(this.menuGenerator_)};Blockly.FieldDropdown.prototype.getOptions=function(){return goog.isFunction(this.menuGenerator_)?this.menuGenerator_.call(this):this.menuGenerator_};
                +Blockly.FieldDropdown.prototype.getValue=function(){return this.value_};Blockly.FieldDropdown.prototype.setValue=function(a){if(null!==a&&a!==this.value_){this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.value_,a));this.value_=a;for(var b=this.getOptions(),c=0;c<b.length;c++)if(b[c][1]==a){a=b[c][0];"object"==typeof a?(this.imageJson_=a,this.setText(a.alt)):(this.imageJson_=null,this.setText(a));return}this.setText(a)}};
                +Blockly.FieldDropdown.prototype.render_=function(){if(this.visible_){this.sourceBlock_&&this.arrow_&&(this.arrow_.style.fill=this.sourceBlock_.getColour());goog.dom.removeChildren(this.textElement_);goog.dom.removeNode(this.imageElement_);this.imageElement_=null;if(this.imageJson_){this.imageElement_=Blockly.utils.createSvgElement("image",{y:5,height:this.imageJson_.height+"px",width:this.imageJson_.width+"px"},this.fieldGroup_);this.imageElement_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",
                +this.imageJson_.src);this.textElement_.appendChild(this.arrow_);var a=Blockly.Field.getCachedWidth(this.arrow_);this.size_.height=Number(this.imageJson_.height)+19;this.size_.width=Number(this.imageJson_.width)+a;this.sourceBlock_.RTL?(this.imageElement_.setAttribute("x",a),this.textElement_.setAttribute("x",-1)):(this.textElement_.setAttribute("text-anchor","end"),this.textElement_.setAttribute("x",this.size_.width+1))}else a=document.createTextNode(this.getDisplayText_()),this.textElement_.appendChild(a),
                +this.sourceBlock_.RTL?this.textElement_.insertBefore(this.arrow_,this.textElement_.firstChild):this.textElement_.appendChild(this.arrow_),this.textElement_.setAttribute("text-anchor","start"),this.textElement_.setAttribute("x",0),this.size_.height=Blockly.BlockSvg.MIN_BLOCK_Y,this.size_.width=Blockly.Field.getCachedWidth(this.textElement_);this.borderRect_.setAttribute("height",this.size_.height-9);this.borderRect_.setAttribute("width",this.size_.width+Blockly.BlockSvg.SEP_SPACE_X)}else this.size_.width=
                +0};Blockly.FieldDropdown.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldDropdown.superClass_.dispose.call(this)};Blockly.FieldImage=function(a,b,c,d,e){this.sourceBlock_=null;this.height_=Number(c);this.width_=Number(b);this.size_=new goog.math.Size(this.width_,this.height_+2*Blockly.BlockSvg.INLINE_PADDING_Y);this.text_=d||"";this.setValue(a);"function"===typeof e&&(this.clickHandler_=e)};goog.inherits(Blockly.FieldImage,Blockly.Field);Blockly.FieldImage.prototype.EDITABLE=!1;
                +Blockly.FieldImage.prototype.init=function(){this.fieldGroup_||(this.fieldGroup_=Blockly.utils.createSvgElement("g",{},null),this.visible_||(this.fieldGroup_.style.display="none"),this.imageElement_=Blockly.utils.createSvgElement("image",{height:this.height_+"px",width:this.width_+"px"},this.fieldGroup_),this.setValue(this.src_),this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_),this.setTooltip(this.sourceBlock_),Blockly.Tooltip.bindMouseEvents(this.imageElement_))};
                +Blockly.FieldImage.prototype.dispose=function(){goog.dom.removeNode(this.fieldGroup_);this.imageElement_=this.fieldGroup_=null};Blockly.FieldImage.prototype.setTooltip=function(a){this.imageElement_.tooltip=a};Blockly.FieldImage.prototype.getValue=function(){return this.src_};Blockly.FieldImage.prototype.setValue=function(a){null!==a&&(this.src_=a,this.imageElement_&&this.imageElement_.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",a||""))};
                +Blockly.FieldImage.prototype.setText=function(a){null!==a&&(this.text_=a)};Blockly.FieldImage.prototype.render_=function(){};Blockly.FieldImage.prototype.updateWidth=function(){};Blockly.FieldImage.prototype.showEditor=function(){this.clickHandler_&&this.clickHandler_(this)};Blockly.FieldNumber=function(a,b,c,d,e){a=a&&!isNaN(a)?String(a):"0";Blockly.FieldNumber.superClass_.constructor.call(this,a,e);this.setConstraints(b,c,d)};goog.inherits(Blockly.FieldNumber,Blockly.FieldTextInput);Blockly.FieldNumber.prototype.setConstraints=function(a,b,c){c=parseFloat(c);this.precision_=isNaN(c)?0:c;a=parseFloat(a);this.min_=isNaN(a)?-Infinity:a;b=parseFloat(b);this.max_=isNaN(b)?Infinity:b;this.setValue(this.callValidator(this.getValue()))};
                +Blockly.FieldNumber.prototype.classValidator=function(a){if(null===a)return null;a=String(a);a=a.replace(/O/ig,"0");a=a.replace(/,/g,"");a=parseFloat(a||0);if(isNaN(a))return null;this.precision_&&isFinite(a)&&(a=Math.round(a/this.precision_)*this.precision_);a=goog.math.clamp(a,this.min_,this.max_);return String(a)};Blockly.VariableModel=function(a,b,c,d){this.workspace=a;this.name=b;this.type=c||"";this.id_=d||Blockly.utils.genUid();Blockly.Events.fire(new Blockly.Events.VarCreate(this))};Blockly.VariableModel.prototype.getId=function(){return this.id_};Blockly.VariableModel.compareByName=function(a,b){return goog.string.caseInsensitiveCompare(a.name,b.name)};Blockly.Variables={};Blockly.Variables.NAME_TYPE=Blockly.VARIABLE_CATEGORY_NAME;Blockly.Variables.allUsedVariables=function(a){if(a instanceof Blockly.Block)var b=a.getDescendants();else if(a.getAllBlocks)b=a.getAllBlocks();else throw"Not Block or Workspace: "+a;a=Object.create(null);for(var c=0;c<b.length;c++){var d=b[c].getVars();if(d)for(var e=0;e<d.length;e++){var f=d[e];f&&(a[f.toLowerCase()]=f)}}b=[];for(var g in a)b.push(a[g]);return b};
                +Blockly.Variables.allVariables=function(a){return a instanceof Blockly.Block?(console.warn("Deprecated call to Blockly.Variables.allVariables with a block instead of a workspace.  You may want Blockly.Variables.allUsedVariables"),{}):a.getAllVariables()};
                +Blockly.Variables.flyoutCategory=function(a){var b=[],c=goog.dom.createDom("button");c.setAttribute("text",Blockly.Msg.NEW_VARIABLE);c.setAttribute("callbackKey","CREATE_VARIABLE");a.registerButtonCallback("CREATE_VARIABLE",function(a){Blockly.Variables.createVariable(a.getTargetWorkspace())});b.push(c);a=Blockly.Variables.flyoutCategoryBlocks(a);return b=b.concat(a)};
                +Blockly.Variables.flyoutCategoryBlocks=function(a){a=a.getVariablesOfType("");a.sort(Blockly.VariableModel.compareByName);var b=[];if(0<a.length){var c=a[0];if(Blockly.Blocks.variables_set){var d=Blockly.Blocks.math_change?8:24;d='<xml><block type="variables_set" gap="'+d+'">'+Blockly.Variables.generateVariableFieldXml_(c)+"</block></xml>";d=Blockly.Xml.textToDom(d).firstChild;b.push(d)}Blockly.Blocks.math_change&&(d=Blockly.Blocks.variables_get?20:8,d='<xml><block type="math_change" gap="'+d+'">'+
                +Blockly.Variables.generateVariableFieldXml_(c)+'<value name="DELTA"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block></xml>',d=Blockly.Xml.textToDom(d).firstChild,b.push(d));for(c=0;d=a[c];c++)Blockly.Blocks.variables_get&&(d='<xml><block type="variables_get" gap="8">'+Blockly.Variables.generateVariableFieldXml_(d)+"</block></xml>",d=Blockly.Xml.textToDom(d).firstChild,b.push(d))}return b};
                +Blockly.Variables.generateUniqueName=function(a){a=a.getAllVariables();var b="";if(a.length)for(var c=1,d=0,e="ijkmnopqrstuvwxyzabcdefgh".charAt(d);!b;){for(var f=!1,g=0;g<a.length;g++)if(a[g].name.toLowerCase()==e){f=!0;break}f?(d++,25==d&&(d=0,c++),e="ijkmnopqrstuvwxyzabcdefgh".charAt(d),1<c&&(e+=c)):b=e}else b="i";return b};
                +Blockly.Variables.createVariable=function(a,b,c){var d=function(e){Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE,e,function(e){e?a.getVariable(e)?Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):Blockly.Procedures.isNameUsed(e,a)?Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):(a.createVariable(e,c),b&&b(e)):b&&b(null)})};d("")};
                +Blockly.Variables.renameVariable=function(a,b,c){var d=function(e){Blockly.Variables.promptName(Blockly.Msg.RENAME_VARIABLE_TITLE.replace("%1",b.name),e,function(e){if(e){var f=a.getVariable(e);f&&f.type!=b.type?Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE.replace("%1",e.toLowerCase()).replace("%2",f.type),function(){d(e)}):Blockly.Procedures.isNameUsed(e,a)?Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace("%1",e.toLowerCase()),function(){d(e)}):(a.renameVariable(b.name,
                +e),c&&c(e))}else c&&c(null)})};d("")};Blockly.Variables.promptName=function(a,b,c){Blockly.prompt(a,b,function(a){a&&(a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,""),a==Blockly.Msg.RENAME_VARIABLE||a==Blockly.Msg.NEW_VARIABLE)&&(a=null);c(a)})};Blockly.Variables.generateVariableFieldXml_=function(a){return'<field name="VAR" variableType="'+a.type+'" id="'+a.getId()+'">'+a.name+"</field>"};Blockly.FieldVariable=function(a,b,c){Blockly.FieldVariable.superClass_.constructor.call(this,Blockly.FieldVariable.dropdownCreate,b);this.setValue(a||"");this.variableTypes=c};goog.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);Blockly.FieldVariable.prototype.init=function(){this.fieldGroup_||(Blockly.FieldVariable.superClass_.init.call(this),this.initModel())};
                +Blockly.FieldVariable.prototype.initModel=function(){this.getValue()||this.setValue(Blockly.Variables.generateUniqueName(this.sourceBlock_.isInFlyout?this.sourceBlock_.workspace.targetWorkspace:this.sourceBlock_.workspace));this.sourceBlock_.isInFlyout||this.sourceBlock_.workspace.createVariable(this.getValue())};
                +Blockly.FieldVariable.prototype.setSourceBlock=function(a){goog.asserts.assert(!a.isShadow(),"Variable fields are not allowed to exist on shadow blocks.");Blockly.FieldVariable.superClass_.setSourceBlock.call(this,a)};Blockly.FieldVariable.prototype.getValue=function(){return this.getText()};
                +Blockly.FieldVariable.prototype.setValue=function(a){var b=a,c=a;if(this.sourceBlock_){var d=this.sourceBlock_.workspace.getVariableById(a);if(d)c=d.name;else if(d=this.sourceBlock_.workspace.getVariable(a))b=d.getId();Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.value_,b))}this.value_=b;this.setText(c)};
                +Blockly.FieldVariable.prototype.getVariableTypes_=function(){var a=this.variableTypes;if(null===a&&this.sourceBlock_)return this.sourceBlock_.workspace.getVariableTypes();a=a||[""];if(0==a.length)throw a=this.getText(),Error("'variableTypes' of field variable "+a+" was an empty list");return a};
                +Blockly.FieldVariable.dropdownCreate=function(){var a=[];var b=this.getText(),c=b?!0:!1,d=null;this.sourceBlock_&&(d=this.sourceBlock_.workspace);if(d){var e=this.getVariableTypes_();a=[];for(var f=0;f<e.length;f++){var g=d.getVariablesOfType(e[f]);a=a.concat(g)}for(f=0;f<a.length;f++)if(c&&goog.string.caseInsensitiveEquals(a[f].name,b)){c=!1;break}}c&&d&&(f=d.createVariable(b),a.push(f));a.sort(Blockly.VariableModel.compareByName);c=[];for(f=0;f<a.length;f++)c[f]=[a[f].name,a[f].getId()];c.push([Blockly.Msg.RENAME_VARIABLE,
                +Blockly.RENAME_VARIABLE_ID]);Blockly.Msg.DELETE_VARIABLE&&c.push([Blockly.Msg.DELETE_VARIABLE.replace("%1",b),Blockly.DELETE_VARIABLE_ID]);return c};
                +Blockly.FieldVariable.prototype.onItemSelected=function(a,b){var c=b.getValue();if(this.sourceBlock_&&this.sourceBlock_.workspace){var d=this.sourceBlock_.workspace,e=d.getVariableById(c);if(e)var f=e.name;else{if(c==Blockly.RENAME_VARIABLE_ID){c=this.getText();e=d.getVariable(c);Blockly.Variables.renameVariable(d,e);return}if(c==Blockly.DELETE_VARIABLE_ID){d.deleteVariable(this.getText());return}}f=this.callValidator(f)}null!==f&&this.setValue(f)};Blockly.Generator=function(a){this.name_=a;this.FUNCTION_NAME_PLACEHOLDER_REGEXP_=new RegExp(this.FUNCTION_NAME_PLACEHOLDER_,"g")};Blockly.Generator.NAME_TYPE="generated_function";Blockly.Generator.prototype.INFINITE_LOOP_TRAP=null;Blockly.Generator.prototype.STATEMENT_PREFIX=null;Blockly.Generator.prototype.INDENT="  ";Blockly.Generator.prototype.COMMENT_WRAP=60;Blockly.Generator.prototype.ORDER_OVERRIDES=[];
                +Blockly.Generator.prototype.workspaceToCode=function(a){a||(console.warn("No workspace specified in workspaceToCode call.  Guessing."),a=Blockly.getMainWorkspace());var b=[];this.init(a);a=a.getTopBlocks(!0);for(var c=0,d;d=a[c];c++){var e=this.blockToCode(d);goog.isArray(e)&&(e=e[0]);e&&(d.outputConnection&&this.scrubNakedValue&&(e=this.scrubNakedValue(e)),b.push(e))}b=b.join("\n");b=this.finish(b);b=b.replace(/^\s+\n/,"");b=b.replace(/\n\s+$/,"\n");return b=b.replace(/[ \t]+\n/g,"\n")};
                +Blockly.Generator.prototype.prefixLines=function(a,b){return b+a.replace(/(?!\n$)\n/g,"\n"+b)};Blockly.Generator.prototype.allNestedComments=function(a){var b=[];a=a.getDescendants();for(var c=0;c<a.length;c++){var d=a[c].getCommentText();d&&b.push(d)}b.length&&b.push("");return b.join("\n")};
                +Blockly.Generator.prototype.blockToCode=function(a){if(!a)return"";if(a.disabled)return this.blockToCode(a.getNextBlock());var b=this[a.type];goog.asserts.assertFunction(b,'Language "%s" does not know how to generate code for block type "%s".',this.name_,a.type);b=b.call(a,a);if(goog.isArray(b))return goog.asserts.assert(a.outputConnection,'Expecting string from statement block "%s".',a.type),[this.scrub_(a,b[0]),b[1]];if(goog.isString(b)){var c=a.id.replace(/\$/g,"$$$$");this.STATEMENT_PREFIX&&(b=
                +this.STATEMENT_PREFIX.replace(/%1/g,"'"+c+"'")+b);return this.scrub_(a,b)}if(null===b)return"";goog.asserts.fail("Invalid code generated: %s",b)};
                +Blockly.Generator.prototype.valueToCode=function(a,b,c){isNaN(c)&&goog.asserts.fail('Expecting valid order from block "%s".',a.type);var d=a.getInputTargetBlock(b);if(!d)return"";b=this.blockToCode(d);if(""===b)return"";goog.asserts.assertArray(b,'Expecting tuple from value block "%s".',d.type);a=b[0];b=b[1];isNaN(b)&&goog.asserts.fail('Expecting valid order from value block "%s".',d.type);if(!a)return"";var d=!1,e=Math.floor(c),f=Math.floor(b);if(e<=f&&(e!=f||0!=e&&99!=e))for(d=!0,e=0;e<this.ORDER_OVERRIDES.length;e++)if(this.ORDER_OVERRIDES[e][0]==
                +c&&this.ORDER_OVERRIDES[e][1]==b){d=!1;break}d&&(a="("+a+")");return a};Blockly.Generator.prototype.statementToCode=function(a,b){var c=a.getInputTargetBlock(b),d=this.blockToCode(c);goog.asserts.assertString(d,'Expecting code from statement block "%s".',c&&c.type);d&&(d=this.prefixLines(d,this.INDENT));return d};
                +Blockly.Generator.prototype.addLoopTrap=function(a,b){b=b.replace(/\$/g,"$$$$");this.INFINITE_LOOP_TRAP&&(a=this.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+b+"'")+a);this.STATEMENT_PREFIX&&(a+=this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,"'"+b+"'"),this.INDENT));return a};Blockly.Generator.prototype.RESERVED_WORDS_="";Blockly.Generator.prototype.addReservedWords=function(a){this.RESERVED_WORDS_+=a+","};Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_="{leCUI8hutHZI4480Dc}";
                +Blockly.Generator.prototype.provideFunction_=function(a,b){if(!this.definitions_[a]){var c=this.variableDB_.getDistinctName(a,Blockly.Procedures.NAME_TYPE);this.functionNames_[a]=c;for(var c=b.join("\n").replace(this.FUNCTION_NAME_PLACEHOLDER_REGEXP_,c),d;d!=c;)d=c,c=c.replace(/^((  )*)  /gm,"$1\x00");c=c.replace(/\0/g,this.INDENT);this.definitions_[a]=c}return this.functionNames_[a]};Blockly.Generator.prototype.init=void 0;Blockly.Generator.prototype.scrub_=void 0;
                +Blockly.Generator.prototype.finish=void 0;Blockly.Generator.prototype.scrubNakedValue=void 0;Blockly.Names=function(a,b){this.variablePrefix_=b||"";this.reservedDict_=Object.create(null);if(a)for(var c=a.split(","),d=0;d<c.length;d++)this.reservedDict_[c[d]]=!0;this.reset()};Blockly.Names.prototype.reset=function(){this.db_=Object.create(null);this.dbReverse_=Object.create(null)};
                +Blockly.Names.prototype.getName=function(a,b){var c=a.toLowerCase()+"_"+b,d=b==Blockly.Variables.NAME_TYPE?this.variablePrefix_:"";if(c in this.db_)return d+this.db_[c];var e=this.getDistinctName(a,b);this.db_[c]=e.substr(d.length);return e};Blockly.Names.prototype.getDistinctName=function(a,b){for(var c=this.safeName_(a),d="";this.dbReverse_[c+d]||c+d in this.reservedDict_;)d=d?d+1:2;c+=d;this.dbReverse_[c]=!0;return(b==Blockly.Variables.NAME_TYPE?this.variablePrefix_:"")+c};
                +Blockly.Names.prototype.safeName_=function(a){a?(a=encodeURI(a.replace(/ /g,"_")).replace(/[^\w]/g,"_"),-1!="0123456789".indexOf(a[0])&&(a="my_"+a)):a="unnamed";return a};Blockly.Names.equals=function(a,b){return a.toLowerCase()==b.toLowerCase()};Blockly.Procedures={};Blockly.Procedures.NAME_TYPE=Blockly.PROCEDURE_CATEGORY_NAME;Blockly.Procedures.allProcedures=function(a){a=a.getAllBlocks();for(var b=[],c=[],d=0;d<a.length;d++)if(a[d].getProcedureDef){var e=a[d].getProcedureDef();e&&(e[2]?b.push(e):c.push(e))}c.sort(Blockly.Procedures.procTupleComparator_);b.sort(Blockly.Procedures.procTupleComparator_);return[c,b]};Blockly.Procedures.procTupleComparator_=function(a,b){return a[0].toLowerCase().localeCompare(b[0].toLowerCase())};
                +Blockly.Procedures.findLegalName=function(a,b){if(b.isInFlyout)return a;for(;!Blockly.Procedures.isLegalName_(a,b.workspace,b);){var c=a.match(/^(.*?)(\d+)$/);a=c?c[1]+(parseInt(c[2],10)+1):a+"2"}return a};Blockly.Procedures.isLegalName_=function(a,b,c){return!Blockly.Procedures.isNameUsed(a,b,c)};Blockly.Procedures.isNameUsed=function(a,b,c){b=b.getAllBlocks();for(var d=0;d<b.length;d++)if(b[d]!=c&&b[d].getProcedureDef){var e=b[d].getProcedureDef();if(Blockly.Names.equals(e[0],a))return!0}return!1};
                +Blockly.Procedures.rename=function(a){a=a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"");var b=Blockly.Procedures.findLegalName(a,this.sourceBlock_),c=this.text_;if(c!=a&&c!=b){a=this.sourceBlock_.workspace.getAllBlocks();for(var d=0;d<a.length;d++)a[d].renameProcedure&&a[d].renameProcedure(c,b)}return b};
                +Blockly.Procedures.flyoutCategory=function(a){function b(a,b){for(var d=0;d<a.length;d++){var e=a[d][0],f=a[d][1],g=goog.dom.createDom("block");g.setAttribute("type",b);g.setAttribute("gap",16);var n=goog.dom.createDom("mutation");n.setAttribute("name",e);g.appendChild(n);for(e=0;e<f.length;e++){var p=goog.dom.createDom("arg");p.setAttribute("name",f[e]);n.appendChild(p)}c.push(g)}}var c=[];if(Blockly.Blocks.procedures_defnoreturn){var d=goog.dom.createDom("block");d.setAttribute("type","procedures_defnoreturn");
                +d.setAttribute("gap",16);var e=goog.dom.createDom("field",null,Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE);e.setAttribute("name","NAME");d.appendChild(e);c.push(d)}Blockly.Blocks.procedures_defreturn&&(d=goog.dom.createDom("block"),d.setAttribute("type","procedures_defreturn"),d.setAttribute("gap",16),e=goog.dom.createDom("field",null,Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE),e.setAttribute("name","NAME"),d.appendChild(e),c.push(d));Blockly.Blocks.procedures_ifreturn&&(d=goog.dom.createDom("block"),
                +d.setAttribute("type","procedures_ifreturn"),d.setAttribute("gap",16),c.push(d));c.length&&c[c.length-1].setAttribute("gap",24);a=Blockly.Procedures.allProcedures(a);b(a[0],"procedures_callnoreturn");b(a[1],"procedures_callreturn");return c};Blockly.Procedures.getCallers=function(a,b){for(var c=[],d=b.getAllBlocks(),e=0;e<d.length;e++)if(d[e].getProcedureCall){var f=d[e].getProcedureCall();f&&Blockly.Names.equals(f,a)&&c.push(d[e])}return c};
                +Blockly.Procedures.mutateCallers=function(a){var b=Blockly.Events.recordUndo,c=a.getProcedureDef()[0],d=a.mutationToDom(!0);a=Blockly.Procedures.getCallers(c,a.workspace);for(var c=0,e;e=a[c];c++){var f=e.mutationToDom(),f=f&&Blockly.Xml.domToText(f);e.domToMutation(d);var g=e.mutationToDom(),g=g&&Blockly.Xml.domToText(g);f!=g&&(Blockly.Events.recordUndo=!1,Blockly.Events.fire(new Blockly.Events.BlockChange(e,"mutation",null,f,g)),Blockly.Events.recordUndo=b)}};
                +Blockly.Procedures.getDefinition=function(a,b){for(var c=b.getTopBlocks(!1),d=0;d<c.length;d++)if(c[d].getProcedureDef){var e=c[d].getProcedureDef();if(e&&Blockly.Names.equals(e[0],a))return c[d]}return null};Blockly.FlyoutButton=function(a,b,c,d){this.workspace_=a;this.targetWorkspace_=b;this.text_=c.getAttribute("text");this.position_=new goog.math.Coordinate(0,0);this.isLabel_=d;this.callback_=null;a=c.getAttribute("callbackKey");this.isLabel_&&a?console.warn("Labels should not have callbacks. Label text: "+this.text_):this.isLabel_||a&&b.getButtonCallback(a)?this.callback_=b.getButtonCallback(a):console.warn("Buttons should have callbacks. Button text: "+this.text_);this.cssClass_=c.getAttribute("web-class")||
                +null};Blockly.FlyoutButton.MARGIN=5;Blockly.FlyoutButton.prototype.width=0;Blockly.FlyoutButton.prototype.height=0;Blockly.FlyoutButton.prototype.onMouseUpWrapper_=null;
                +Blockly.FlyoutButton.prototype.createDom=function(){var a,b=this.isLabel_?"blocklyFlyoutLabel":"blocklyFlyoutButton";this.cssClass_&&(b+=" "+this.cssClass_);this.svgGroup_=Blockly.utils.createSvgElement("g",{"class":b},this.workspace_.getCanvas());this.isLabel_||(a=Blockly.utils.createSvgElement("rect",{"class":"blocklyFlyoutButtonShadow",rx:4,ry:4,x:1,y:1},this.svgGroup_));var b=Blockly.utils.createSvgElement("rect",{"class":this.isLabel_?"blocklyFlyoutLabelBackground":"blocklyFlyoutButtonBackground",
                +rx:4,ry:4},this.svgGroup_),c=Blockly.utils.createSvgElement("text",{"class":this.isLabel_?"blocklyFlyoutLabelText":"blocklyText",x:0,y:0,"text-anchor":"middle"},this.svgGroup_);c.textContent=this.text_;this.width=c.getComputedTextLength()+2*Blockly.FlyoutButton.MARGIN;this.height=20;this.isLabel_||(a.setAttribute("width",this.width),a.setAttribute("height",this.height));b.setAttribute("width",this.width);b.setAttribute("height",this.height);c.setAttribute("x",this.width/2);c.setAttribute("y",this.height-
                +Blockly.FlyoutButton.MARGIN);this.updateTransform_();this.mouseUpWrapper_=Blockly.bindEventWithChecks_(this.svgGroup_,"mouseup",this,this.onMouseUp_);return this.svgGroup_};Blockly.FlyoutButton.prototype.show=function(){this.updateTransform_();this.svgGroup_.setAttribute("display","block")};Blockly.FlyoutButton.prototype.updateTransform_=function(){this.svgGroup_.setAttribute("transform","translate("+this.position_.x+","+this.position_.y+")")};
                +Blockly.FlyoutButton.prototype.moveTo=function(a,b){this.position_.x=a;this.position_.y=b;this.updateTransform_()};Blockly.FlyoutButton.prototype.getTargetWorkspace=function(){return this.targetWorkspace_};Blockly.FlyoutButton.prototype.dispose=function(){this.onMouseUpWrapper_&&Blockly.unbindEvent_(this.onMouseUpWrapper_);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.targetWorkspace_=this.workspace_=null};
                +Blockly.FlyoutButton.prototype.onMouseUp_=function(a){(a=this.targetWorkspace_.getGesture(a))&&a.cancel();this.callback_&&this.callback_(this)};Blockly.Flyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);this.workspace_=new Blockly.WorkspaceSvg(a);this.workspace_.isFlyout=!0;this.RTL=!!a.RTL;this.toolboxPosition_=a.toolboxPosition;this.eventWrappers_=[];this.backgroundButtons_=[];this.buttons_=[];this.listeners_=[];this.permanentlyDisabled_=[]};Blockly.Flyout.prototype.autoClose=!0;Blockly.Flyout.prototype.isVisible_=!1;Blockly.Flyout.prototype.containerVisible_=!0;
                +Blockly.Flyout.prototype.CORNER_RADIUS=8;Blockly.Flyout.prototype.MARGIN=Blockly.Flyout.prototype.CORNER_RADIUS;Blockly.Flyout.prototype.GAP_X=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.GAP_Y=3*Blockly.Flyout.prototype.MARGIN;Blockly.Flyout.prototype.SCROLLBAR_PADDING=2;Blockly.Flyout.prototype.width_=0;Blockly.Flyout.prototype.height_=0;Blockly.Flyout.prototype.dragAngleRange_=70;
                +Blockly.Flyout.prototype.createDom=function(a){this.svgGroup_=Blockly.utils.createSvgElement(a,{"class":"blocklyFlyout",style:"display: none"},null);this.svgBackground_=Blockly.utils.createSvgElement("path",{"class":"blocklyFlyoutBackground"},this.svgGroup_);this.svgGroup_.appendChild(this.workspace_.createDom());return this.svgGroup_};
                +Blockly.Flyout.prototype.init=function(a){this.targetWorkspace_=a;this.workspace_.targetWorkspace=a;this.scrollbar_=new Blockly.Scrollbar(this.workspace_,this.horizontalLayout_,!1,"blocklyFlyoutScrollbar");this.hide();Array.prototype.push.apply(this.eventWrappers_,Blockly.bindEventWithChecks_(this.svgGroup_,"wheel",this,this.wheel_));this.autoClose||(this.filterWrapper_=this.filterForCapacity_.bind(this),this.targetWorkspace_.addChangeListener(this.filterWrapper_));Array.prototype.push.apply(this.eventWrappers_,
                +Blockly.bindEventWithChecks_(this.svgBackground_,"mousedown",this,this.onMouseDown_));this.workspace_.getGesture=this.targetWorkspace_.getGesture.bind(this.targetWorkspace_);this.workspace_.getVariable=this.targetWorkspace_.getVariable.bind(this.targetWorkspace_);this.workspace_.getVariableById=this.targetWorkspace_.getVariableById.bind(this.targetWorkspace_);this.workspace_.getVariablesOfType=this.targetWorkspace_.getVariablesOfType.bind(this.targetWorkspace_);this.workspace_.deleteVariable=this.targetWorkspace_.deleteVariable.bind(this.targetWorkspace_);
                +this.workspace_.deleteVariableById=this.targetWorkspace_.deleteVariableById.bind(this.targetWorkspace_);this.workspace_.renameVariable=this.targetWorkspace_.renameVariable.bind(this.targetWorkspace_);this.workspace_.renameVariableById=this.targetWorkspace_.renameVariableById.bind(this.targetWorkspace_)};
                +Blockly.Flyout.prototype.dispose=function(){this.hide();Blockly.unbindEvent_(this.eventWrappers_);this.filterWrapper_&&(this.targetWorkspace_.removeChangeListener(this.filterWrapper_),this.filterWrapper_=null);this.scrollbar_&&(this.scrollbar_.dispose(),this.scrollbar_=null);this.workspace_&&(this.workspace_.targetWorkspace=null,this.workspace_.dispose(),this.workspace_=null);this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.targetWorkspace_=this.svgBackground_=null};
                +Blockly.Flyout.prototype.getWidth=function(){return this.width_};Blockly.Flyout.prototype.getHeight=function(){return this.height_};Blockly.Flyout.prototype.getWorkspace=function(){return this.workspace_};Blockly.Flyout.prototype.isVisible=function(){return this.isVisible_};Blockly.Flyout.prototype.setVisible=function(a){var b=a!=this.isVisible();this.isVisible_=a;b&&this.updateDisplay_()};
                +Blockly.Flyout.prototype.setContainerVisible=function(a){var b=a!=this.containerVisible_;this.containerVisible_=a;b&&this.updateDisplay_()};Blockly.Flyout.prototype.updateDisplay_=function(){var a=this.containerVisible_?this.isVisible():!1;this.svgGroup_.style.display=a?"block":"none";this.scrollbar_.setContainerVisible(a)};
                +Blockly.Flyout.prototype.positionAt_=function(a,b,c,d){this.svgGroup_.setAttribute("width",a);this.svgGroup_.setAttribute("height",b);Blockly.utils.setCssTransform(this.svgGroup_,"translate("+c+"px,"+d+"px)");this.scrollbar_&&(this.scrollbar_.setOrigin(c,d),this.scrollbar_.resize())};
                +Blockly.Flyout.prototype.hide=function(){if(this.isVisible()){this.setVisible(!1);for(var a=0,b;b=this.listeners_[a];a++)Blockly.unbindEvent_(b);this.listeners_.length=0;this.reflowWrapper_&&(this.workspace_.removeChangeListener(this.reflowWrapper_),this.reflowWrapper_=null)}};
                +Blockly.Flyout.prototype.show=function(a){this.workspace_.setResizesEnabled(!1);this.hide();this.clearOldBlocks_();"string"==typeof a&&(a=this.workspace_.targetWorkspace.getToolboxCategoryCallback(a),goog.asserts.assert(goog.isFunction(a),"Couldn't find a callback function when opening a toolbox category."),a=a(this.workspace_.targetWorkspace),goog.asserts.assert(goog.isArray(a),"The result of a toolbox category callback must be an array."));this.setVisible(!0);for(var b=[],c=[],d=this.permanentlyDisabled_.length=
                +0,e;e=a[d];d++)if(e.tagName){var f=e.tagName.toUpperCase(),g=this.horizontalLayout_?this.GAP_X:this.GAP_Y;if("BLOCK"==f)f=Blockly.Xml.domToBlock(e,this.workspace_),f.disabled&&this.permanentlyDisabled_.push(f),b.push({type:"block",block:f}),e=parseInt(e.getAttribute("gap"),10),c.push(isNaN(e)?g:e);else if("SEP"==e.tagName.toUpperCase())e=parseInt(e.getAttribute("gap"),10),!isNaN(e)&&0<c.length?c[c.length-1]=e:c.push(g);else if("BUTTON"==f||"LABEL"==f)e=new Blockly.FlyoutButton(this.workspace_,this.targetWorkspace_,
                +e,"LABEL"==f),b.push({type:"button",button:e}),c.push(g)}this.layout_(b,c);this.listeners_.push(Blockly.bindEventWithChecks_(this.svgBackground_,"mouseover",this,function(){for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++)c.removeSelect()}));this.horizontalLayout_?this.height_=0:this.width_=0;this.workspace_.setResizesEnabled(!0);this.reflow();this.filterForCapacity_();this.position();this.reflowWrapper_=this.reflow.bind(this);this.workspace_.addChangeListener(this.reflowWrapper_)};
                +Blockly.Flyout.prototype.clearOldBlocks_=function(){for(var a=this.workspace_.getTopBlocks(!1),b=0,c;c=a[b];b++)c.workspace==this.workspace_&&c.dispose(!1,!1);for(b=0;a=this.backgroundButtons_[b];b++)goog.dom.removeNode(a);for(b=this.backgroundButtons_.length=0;a=this.buttons_[b];b++)a.dispose();this.buttons_.length=0};
                +Blockly.Flyout.prototype.addBlockListeners_=function(a,b,c){this.listeners_.push(Blockly.bindEventWithChecks_(a,"mousedown",null,this.blockMouseDown_(b)));this.listeners_.push(Blockly.bindEventWithChecks_(c,"mousedown",null,this.blockMouseDown_(b)));this.listeners_.push(Blockly.bindEvent_(a,"mouseover",b,b.addSelect));this.listeners_.push(Blockly.bindEvent_(a,"mouseout",b,b.removeSelect));this.listeners_.push(Blockly.bindEvent_(c,"mouseover",b,b.addSelect));this.listeners_.push(Blockly.bindEvent_(c,
                +"mouseout",b,b.removeSelect))};Blockly.Flyout.prototype.blockMouseDown_=function(a){var b=this;return function(c){var d=b.targetWorkspace_.getGesture(c);d&&(d.setStartBlock(a),d.handleFlyoutStart(c,b))}};Blockly.Flyout.prototype.onMouseDown_=function(a){var b=this.targetWorkspace_.getGesture(a);b&&b.handleFlyoutStart(a,this)};
                +Blockly.Flyout.prototype.createBlock=function(a){var b=null;Blockly.Events.disable();this.targetWorkspace_.setResizesEnabled(!1);try{b=this.placeNewBlock_(a);if(goog.userAgent.IE||goog.userAgent.EDGE)for(var c=b.getDescendants(),d=c.length-1;0<=d;d--)c[d].render(!1);Blockly.hideChaff()}finally{Blockly.Events.enable()}Blockly.Events.isEnabled()&&(Blockly.Events.setGroup(!0),Blockly.Events.fire(new Blockly.Events.Create(b)));this.autoClose?this.hide():this.filterForCapacity_();return b};
                +Blockly.Flyout.prototype.initFlyoutButton_=function(a,b,c){var d=a.createDom();a.moveTo(b,c);a.show();this.listeners_.push(Blockly.bindEventWithChecks_(d,"mousedown",this,this.onMouseDown_));this.buttons_.push(a)};
                +Blockly.Flyout.prototype.createRect_=function(a,b,c,d,e){b=Blockly.utils.createSvgElement("rect",{"fill-opacity":0,x:b,y:c,height:d.height,width:d.width},null);b.tooltip=a;Blockly.Tooltip.bindMouseEvents(b);this.workspace_.getCanvas().insertBefore(b,a.getSvgRoot());a.flyoutRect_=b;return this.backgroundButtons_[e]=b};
                +Blockly.Flyout.prototype.moveRectToBlock_=function(a,b){var c=b.getHeightWidth();a.setAttribute("width",c.width);a.setAttribute("height",c.height);var d=b.startHat_?Blockly.BlockSvg.START_HAT_HEIGHT:0;d&&b.moveBy(0,d);var d=b.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0,e=b.getRelativeToSurfaceXY();a.setAttribute("y",e.y);a.setAttribute("x",this.RTL?e.x-c.width+d:e.x-d)};
                +Blockly.Flyout.prototype.filterForCapacity_=function(){for(var a=this.targetWorkspace_.remainingCapacity(),b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++)if(-1==this.permanentlyDisabled_.indexOf(d)){var e=d.getDescendants();d.setDisabled(e.length>a)}};Blockly.Flyout.prototype.reflow=function(){this.reflowWrapper_&&this.workspace_.removeChangeListener(this.reflowWrapper_);var a=this.workspace_.getTopBlocks(!1);this.reflowInternal_(a);this.reflowWrapper_&&this.workspace_.addChangeListener(this.reflowWrapper_)};
                +Blockly.Flyout.prototype.isScrollable=function(){return this.scrollbar_?this.scrollbar_.isVisible():!1};
                +Blockly.Flyout.prototype.placeNewBlock_=function(a){var b=this.targetWorkspace_;if(!a.getSvgRoot())throw"oldBlock is not rendered.";var c=Blockly.Xml.blockToDom(a);b.setResizesEnabled(!1);c=Blockly.Xml.domToBlock(c,b);if(!c.getSvgRoot())throw"block is not rendered.";var d=b.getOriginOffsetInPixels(),e=this.workspace_.getOriginOffsetInPixels();a=a.getRelativeToSurfaceXY().scale(this.workspace_.scale);a=goog.math.Coordinate.sum(e,a);b=goog.math.Coordinate.difference(a,d).scale(1/b.scale);c.moveBy(b.x,
                +b.y);return c};Blockly.HorizontalFlyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);Blockly.HorizontalFlyout.superClass_.constructor.call(this,a);this.horizontalLayout_=!0};goog.inherits(Blockly.HorizontalFlyout,Blockly.Flyout);
                +Blockly.HorizontalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.SCROLLBAR_PADDING;this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM&&(b=0);var d=this.height_;this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP&&(d-=this.SCROLLBAR_PADDING);return{viewHeight:d,viewWidth:this.width_-2*this.SCROLLBAR_PADDING,contentHeight:(a.height+2*this.MARGIN)*this.workspace_.scale,
                +contentWidth:(a.width+2*this.MARGIN)*this.workspace_.scale,viewTop:-this.workspace_.scrollY,viewLeft:-this.workspace_.scrollX,contentTop:a.y,contentLeft:a.x,absoluteTop:b,absoluteLeft:c}};Blockly.HorizontalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&(goog.isNumber(a.x)&&(this.workspace_.scrollX=-b.contentWidth*a.x),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
                +Blockly.HorizontalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace_.getMetrics();if(a){this.width_=a.viewWidth;this.setBackgroundPath_(a.viewWidth-2*this.CORNER_RADIUS,this.height_-this.CORNER_RADIUS);var b=a.absoluteLeft,c=a.absoluteTop;this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM&&(c+=a.viewHeight-this.height_);this.positionAt_(this.width_,this.height_,b,c)}}};
                +Blockly.HorizontalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP,d=["M 0,"+(c?0:this.CORNER_RADIUS)];c?(d.push("h",a+2*this.CORNER_RADIUS),d.push("v",b),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("h",-1*a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,-this.CORNER_RADIUS,-this.CORNER_RADIUS)):(d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,-this.CORNER_RADIUS),
                +d.push("h",a),d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,1,this.CORNER_RADIUS,this.CORNER_RADIUS),d.push("v",b),d.push("h",-a-2*this.CORNER_RADIUS));d.push("z");this.svgBackground_.setAttribute("d",d.join(" "))};Blockly.HorizontalFlyout.prototype.scrollToStart=function(){this.scrollbar_.set(this.RTL?Infinity:0)};
                +Blockly.HorizontalFlyout.prototype.wheel_=function(a){var b=a.deltaX;if(b){goog.userAgent.GECKO&&(b*=10);var c=this.getMetrics_(),b=c.viewLeft+b,b=Math.min(b,c.contentWidth-c.viewWidth),b=Math.max(b,0);this.scrollbar_.set(b);Blockly.WidgetDiv.hide()}a.preventDefault();a.stopPropagation()};
                +Blockly.HorizontalFlyout.prototype.layout_=function(a,b){var c;this.workspace_.scale=this.targetWorkspace_.scale;var d=this.MARGIN,e=this.RTL?d:d+Blockly.BlockSvg.TAB_WIDTH;this.RTL&&(a=a.reverse());for(var f=0,g;g=a[f];f++)if("block"==g.type){g=g.block;for(var h=g.getDescendants(),k=0;c=h[k];k++)c.isInFlyout=!0;g.render();h=g.getSvgRoot();k=g.getHeightWidth();c=g.outputConnection?Blockly.BlockSvg.TAB_WIDTH:0;c=this.RTL?e+k.width:e+c;g.moveBy(c,d);c=this.createRect_(g,c,d,k,f);e+=k.width+b[f];this.addBlockListeners_(h,
                +g,c)}else"button"==g.type&&(this.initFlyoutButton_(g.button,e,d),e+=g.button.width+b[f])};Blockly.HorizontalFlyout.prototype.isDragTowardWorkspace=function(a){a=Math.atan2(a.y,a.x)/Math.PI*180;var b=this.dragAngleRange_;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP){if(a<90+b&&a>90-b)return!0}else if(a>-90-b&&a<-90+b)return!0;return!1};
                +Blockly.HorizontalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.top,a=a.height;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_TOP)return new goog.math.Rect(-1E9,b-1E9,2E9,1E9+a);if(this.toolboxPosition_==Blockly.TOOLBOX_AT_BOTTOM)return new goog.math.Rect(-1E9,b,2E9,1E9+a)};
                +Blockly.HorizontalFlyout.prototype.reflowInternal_=function(a){this.workspace_.scale=this.targetWorkspace_.scale;for(var b=0,c=0,d;d=a[c];c++)b=Math.max(b,d.getHeightWidth().height);b+=1.5*this.MARGIN;b*=this.workspace_.scale;b+=Blockly.Scrollbar.scrollbarThickness;if(this.height_!=b){for(c=0;d=a[c];c++)d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d);this.height_=b;this.targetWorkspace_.resize()}};Blockly.VerticalFlyout=function(a){a.getMetrics=this.getMetrics_.bind(this);a.setMetrics=this.setMetrics_.bind(this);Blockly.VerticalFlyout.superClass_.constructor.call(this,a);this.horizontalLayout_=!1};goog.inherits(Blockly.VerticalFlyout,Blockly.Flyout);
                +Blockly.VerticalFlyout.prototype.getMetrics_=function(){if(!this.isVisible())return null;try{var a=this.workspace_.getCanvas().getBBox()}catch(e){a={height:0,y:0,width:0,x:0}}var b=this.SCROLLBAR_PADDING,c=this.height_-2*this.SCROLLBAR_PADDING,d=this.width_;this.RTL||(d-=this.SCROLLBAR_PADDING);return{viewHeight:c,viewWidth:d,contentHeight:a.height*this.workspace_.scale+2*this.MARGIN,contentWidth:a.width*this.workspace_.scale+2*this.MARGIN,viewTop:-this.workspace_.scrollY+a.y,viewLeft:-this.workspace_.scrollX,
                +contentTop:a.y,contentLeft:a.x,absoluteTop:b,absoluteLeft:0}};Blockly.VerticalFlyout.prototype.setMetrics_=function(a){var b=this.getMetrics_();b&&(goog.isNumber(a.y)&&(this.workspace_.scrollY=-b.contentHeight*a.y),this.workspace_.translate(this.workspace_.scrollX+b.absoluteLeft,this.workspace_.scrollY+b.absoluteTop))};
                +Blockly.VerticalFlyout.prototype.position=function(){if(this.isVisible()){var a=this.targetWorkspace_.getMetrics();if(a){this.height_=a.viewHeight;this.setBackgroundPath_(this.width_-this.CORNER_RADIUS,a.viewHeight-2*this.CORNER_RADIUS);var b=a.absoluteTop,c=a.absoluteLeft;this.toolboxPosition_==Blockly.TOOLBOX_AT_RIGHT&&(c+=a.viewWidth-this.width_);this.positionAt_(this.width_,this.height_,c,b)}}};
                +Blockly.VerticalFlyout.prototype.setBackgroundPath_=function(a,b){var c=this.toolboxPosition_==Blockly.TOOLBOX_AT_RIGHT,d=a+this.CORNER_RADIUS,d=["M "+(c?d:0)+",0"];d.push("h",c?-a:a);d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?-this.CORNER_RADIUS:this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("v",Math.max(0,b));d.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,c?0:1,c?this.CORNER_RADIUS:-this.CORNER_RADIUS,this.CORNER_RADIUS);d.push("h",c?a:-a);d.push("z");this.svgBackground_.setAttribute("d",
                +d.join(" "))};Blockly.VerticalFlyout.prototype.scrollToStart=function(){this.scrollbar_.set(0)};Blockly.VerticalFlyout.prototype.wheel_=function(a){var b=a.deltaY;if(b){goog.userAgent.GECKO&&(b*=10);var c=this.getMetrics_(),b=c.viewTop+b,b=Math.min(b,c.contentHeight-c.viewHeight),b=Math.max(b,0);this.scrollbar_.set(b);Blockly.WidgetDiv.hide()}a.preventDefault();a.stopPropagation()};
                +Blockly.VerticalFlyout.prototype.layout_=function(a,b){this.workspace_.scale=this.targetWorkspace_.scale;for(var c=this.MARGIN,d=this.RTL?c:c+Blockly.BlockSvg.TAB_WIDTH,e=0,f;f=a[e];e++)if("block"==f.type){f=f.block;for(var g=f.getDescendants(),h=0,k;k=g[h];h++)k.isInFlyout=!0;f.render();g=f.getSvgRoot();h=f.getHeightWidth();f.moveBy(d,c);k=this.createRect_(f,this.RTL?d-h.width:d,c,h,e);this.addBlockListeners_(g,f,k);c+=h.height+b[e]}else"button"==f.type&&(this.initFlyoutButton_(f.button,d,c),c+=
                +f.button.height+b[e])};Blockly.VerticalFlyout.prototype.isDragTowardWorkspace=function(a){a=Math.atan2(a.y,a.x)/Math.PI*180;var b=this.dragAngleRange_;if(this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT){if(a<b&&a>-b)return!0}else if(a<-180+b||a>180-b)return!0;return!1};
                +Blockly.VerticalFlyout.prototype.getClientRect=function(){if(!this.svgGroup_)return null;var a=this.svgGroup_.getBoundingClientRect(),b=a.left,a=a.width;return this.toolboxPosition_==Blockly.TOOLBOX_AT_LEFT?new goog.math.Rect(b-1E9,-1E9,1E9+a,2E9):new goog.math.Rect(b,-1E9,1E9+a,2E9)};
                +Blockly.VerticalFlyout.prototype.reflowInternal_=function(a){this.workspace_.scale=this.targetWorkspace_.scale;for(var b=0,c=0,d;d=a[c];c++){var e=d.getHeightWidth().width;d.outputConnection&&(e-=Blockly.BlockSvg.TAB_WIDTH);b=Math.max(b,e)}for(c=0;d=this.buttons_[c];c++)b=Math.max(b,d.width);b+=1.5*this.MARGIN+Blockly.BlockSvg.TAB_WIDTH;b*=this.workspace_.scale;b+=Blockly.Scrollbar.scrollbarThickness;if(this.width_!=b){for(c=0;d=a[c];c++){if(this.RTL){var e=d.getRelativeToSurfaceXY().x,f=b/this.workspace_.scale-
                +this.MARGIN,f=f-Blockly.BlockSvg.TAB_WIDTH;d.moveBy(f-e,0)}d.flyoutRect_&&this.moveRectToBlock_(d.flyoutRect_,d)}this.width_=b;this.targetWorkspace_.resize()}};Blockly.Toolbox=function(a){this.workspace_=a;this.RTL=a.options.RTL;this.horizontalLayout_=a.options.horizontalLayout;this.toolboxPosition=a.options.toolboxPosition;this.config_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssItem:"",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"};this.treeSeparatorConfig_={cssTreeRow:"blocklyTreeSeparator"};
                +this.horizontalLayout_&&(this.config_.cssTreeRow+=a.RTL?" blocklyHorizontalTreeRtl":" blocklyHorizontalTree",this.treeSeparatorConfig_.cssTreeRow="blocklyTreeSeparatorHorizontal "+(a.RTL?"blocklyHorizontalTreeRtl":"blocklyHorizontalTree"),this.config_.cssTreeIcon="")};Blockly.Toolbox.prototype.width=0;Blockly.Toolbox.prototype.height=0;Blockly.Toolbox.prototype.selectedOption_=null;Blockly.Toolbox.prototype.lastCategory_=null;
                +Blockly.Toolbox.prototype.init=function(){var a=this.workspace_,b=this.workspace_.getParentSvg();this.HtmlDiv=goog.dom.createDom("DIV","blocklyToolboxDiv");this.HtmlDiv.setAttribute("dir",a.RTL?"RTL":"LTR");b.parentNode.insertBefore(this.HtmlDiv,b);Blockly.bindEventWithChecks_(this.HtmlDiv,"mousedown",this,function(a){Blockly.utils.isRightButton(a)||a.target==this.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0);Blockly.Touch.clearTouchIdentifier()});b={disabledPatternId:a.options.disabledPatternId,
                +parentWorkspace:a,RTL:a.RTL,oneBasedIndex:a.options.oneBasedIndex,horizontalLayout:a.horizontalLayout,toolboxPosition:a.options.toolboxPosition};this.flyout_=null;this.flyout_=a.horizontalLayout?new Blockly.HorizontalFlyout(b):new Blockly.VerticalFlyout(b);goog.dom.insertSiblingAfter(this.flyout_.createDom("svg"),this.workspace_.getParentSvg());this.flyout_.init(a);this.config_.cleardotPath=a.options.pathToMedia+"1x1.gif";this.config_.cssCollapsedFolderIcon="blocklyTreeIconClosed"+(a.RTL?"Rtl":"Ltr");
                +this.tree_=b=new Blockly.Toolbox.TreeControl(this,this.config_);b.setShowRootNode(!1);b.setShowLines(!1);b.setShowExpandIcons(!1);b.setSelectedItem(null);a=this.populate_(a.options.languageTree);b.render(this.HtmlDiv);a&&b.setSelectedItem(a);this.addColour_();this.position()};Blockly.Toolbox.prototype.dispose=function(){this.flyout_.dispose();this.tree_.dispose();goog.dom.removeNode(this.HtmlDiv);this.lastCategory_=this.workspace_=null};Blockly.Toolbox.prototype.getWidth=function(){return this.width};
                +Blockly.Toolbox.prototype.getHeight=function(){return this.height};
                +Blockly.Toolbox.prototype.position=function(){var a=this.HtmlDiv;if(a){var b=this.workspace_.getParentSvg(),b=Blockly.svgSize(b);this.horizontalLayout_?(a.style.left="0",a.style.height="auto",a.style.width=b.width+"px",this.height=a.offsetHeight,this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?a.style.top="0":a.style.bottom="0"):(this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?a.style.right="0":a.style.left="0",a.style.height=b.height+"px",this.width=a.offsetWidth);this.flyout_.position()}};
                +Blockly.Toolbox.prototype.populate_=function(a){this.tree_.removeChildren();this.tree_.blocks=[];this.hasColours_=!1;a=this.syncTrees_(a,this.tree_,this.workspace_.options.pathToMedia);if(this.tree_.blocks.length)throw"Toolbox cannot have both blocks and categories in the root level.";this.workspace_.resizeContents();return a};
                +Blockly.Toolbox.prototype.syncTrees_=function(a,b,c){for(var d=null,e=null,f=0,g;g=a.childNodes[f];f++)if(g.tagName)switch(g.tagName.toUpperCase()){case "CATEGORY":e=Blockly.utils.replaceMessageReferences(g.getAttribute("name"));e=this.tree_.createNode(e);e.blocks=[];b.add(e);var h=g.getAttribute("custom");h?e.blocks=h:(h=this.syncTrees_(g,e,c))&&(d=h);h=Blockly.utils.replaceMessageReferences(g.getAttribute("colour"));goog.isString(h)?(h.match(/^#[0-9a-fA-F]{6}$/)?e.hexColour=h:e.hexColour=Blockly.hueToRgb(h),
                +this.hasColours_=!0):e.hexColour="";"true"==g.getAttribute("expanded")?(e.blocks.length&&(d=e),e.setExpanded(!0)):e.setExpanded(!1);e=g;break;case "SEP":e&&("CATEGORY"==e.tagName.toUpperCase()?b.add(new Blockly.Toolbox.TreeSeparator(this.treeSeparatorConfig_)):(g=parseFloat(g.getAttribute("gap")),!isNaN(g)&&e&&e.setAttribute("gap",g)));break;case "BLOCK":case "SHADOW":case "LABEL":case "BUTTON":b.blocks.push(g),e=g}return d};
                +Blockly.Toolbox.prototype.addColour_=function(a){for(var b=(a||this.tree_).getChildren(),c=0,d;d=b[c];c++){var e=d.getRowElement();e&&(a=this.hasColours_?"8px solid "+(d.hexColour||"#ddd"):"none",this.workspace_.RTL?e.style.borderRight=a:e.style.borderLeft=a);this.addColour_(d)}};Blockly.Toolbox.prototype.clearSelection=function(){this.tree_.setSelectedItem(null)};Blockly.Toolbox.prototype.addDeleteStyle=function(){Blockly.utils.addClass(this.HtmlDiv,"blocklyToolboxDelete")};
                +Blockly.Toolbox.prototype.removeDeleteStyle=function(){Blockly.utils.removeClass(this.HtmlDiv,"blocklyToolboxDelete")};
                +Blockly.Toolbox.prototype.getClientRect=function(){if(!this.HtmlDiv)return null;var a=this.HtmlDiv.getBoundingClientRect(),b=a.left,c=a.top,d=a.width,a=a.height;return this.toolboxPosition==Blockly.TOOLBOX_AT_LEFT?new goog.math.Rect(-1E7,-1E7,1E7+b+d,2E7):this.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT?new goog.math.Rect(b,-1E7,1E7+d,2E7):this.toolboxPosition==Blockly.TOOLBOX_AT_TOP?new goog.math.Rect(-1E7,-1E7,2E7,1E7+c+a):new goog.math.Rect(0,c,2E7,1E7+d)};
                +Blockly.Toolbox.prototype.refreshSelection=function(){var a=this.tree_.getSelectedItem();a&&a.blocks&&this.flyout_.show(a.blocks)};Blockly.Toolbox.TreeControl=function(a,b){this.toolbox_=a;goog.ui.tree.TreeControl.call(this,goog.html.SafeHtml.EMPTY,b)};goog.inherits(Blockly.Toolbox.TreeControl,goog.ui.tree.TreeControl);
                +Blockly.Toolbox.TreeControl.prototype.enterDocument=function(){Blockly.Toolbox.TreeControl.superClass_.enterDocument.call(this);if(goog.events.BrowserFeature.TOUCH_ENABLED){var a=this.getElement();Blockly.bindEventWithChecks_(a,goog.events.EventType.TOUCHSTART,this,this.handleTouchEvent_)}};Blockly.Toolbox.TreeControl.prototype.handleTouchEvent_=function(a){a.preventDefault();var b=this.getNodeFromEvent_(a);b&&a.type===goog.events.EventType.TOUCHSTART&&setTimeout(function(){b.onMouseDown(a)},1)};
                +Blockly.Toolbox.TreeControl.prototype.createNode=function(a){return new Blockly.Toolbox.TreeNode(this.toolbox_,a?goog.html.SafeHtml.htmlEscape(a):goog.html.SafeHtml.EMPTY,this.getConfig(),this.getDomHelper())};
                +Blockly.Toolbox.TreeControl.prototype.setSelectedItem=function(a){var b=this.toolbox_;if(a!=this.selectedItem_&&a!=b.tree_){b.lastCategory_&&(b.lastCategory_.getRowElement().style.backgroundColor="");if(a){var c=a.hexColour||"#57e";a.getRowElement().style.backgroundColor=c;b.addColour_(a)}c=this.getSelectedItem();goog.ui.tree.TreeControl.prototype.setSelectedItem.call(this,a);a&&a.blocks&&a.blocks.length?(b.flyout_.show(a.blocks),b.lastCategory_!=a&&b.flyout_.scrollToStart()):b.flyout_.hide();c!=
                +a&&c!=this&&(c=new Blockly.Events.Ui(null,"category",c&&c.getHtml(),a&&a.getHtml()),c.workspaceId=b.workspace_.id,Blockly.Events.fire(c));a&&(b.lastCategory_=a)}};Blockly.Toolbox.TreeNode=function(a,b,c,d){goog.ui.tree.TreeNode.call(this,b,c,d);a&&(b=function(){Blockly.svgResize(a.workspace_)},goog.events.listen(a.tree_,goog.ui.tree.BaseNode.EventType.EXPAND,b),goog.events.listen(a.tree_,goog.ui.tree.BaseNode.EventType.COLLAPSE,b))};goog.inherits(Blockly.Toolbox.TreeNode,goog.ui.tree.TreeNode);
                +Blockly.Toolbox.TreeNode.prototype.getExpandIconSafeHtml=function(){return goog.html.SafeHtml.create("span")};Blockly.Toolbox.TreeNode.prototype.onMouseDown=function(a){this.hasChildren()&&this.isUserCollapsible_?(this.toggle(),this.select()):this.isSelected()?this.getTree().setSelectedItem(null):this.select();this.updateRow()};Blockly.Toolbox.TreeNode.prototype.onDoubleClick_=function(a){};
                +Blockly.Toolbox.TreeNode.prototype.onKeyDown=function(a){if(this.tree.toolbox_.horizontalLayout_){var b={},c=goog.events.KeyCodes.DOWN,d=goog.events.KeyCodes.UP;b[goog.events.KeyCodes.RIGHT]=this.rightToLeft_?d:c;b[goog.events.KeyCodes.LEFT]=this.rightToLeft_?c:d;b[goog.events.KeyCodes.UP]=goog.events.KeyCodes.LEFT;b[goog.events.KeyCodes.DOWN]=goog.events.KeyCodes.RIGHT;a.keyCode=b[a.keyCode]||a.keyCode}return Blockly.Toolbox.TreeNode.superClass_.onKeyDown.call(this,a)};
                +Blockly.Toolbox.TreeSeparator=function(a){Blockly.Toolbox.TreeNode.call(this,null,"",a)};goog.inherits(Blockly.Toolbox.TreeSeparator,Blockly.Toolbox.TreeNode);Blockly.Css={};Blockly.Css.Cursor={OPEN:"handopen",CLOSED:"handclosed",DELETE:"handdelete"};Blockly.Css.currentCursor_="";Blockly.Css.styleSheet_=null;Blockly.Css.mediaPath_="";
                +Blockly.Css.inject=function(a,b){if(!Blockly.Css.styleSheet_){var c=".blocklyDraggable {}\n";a&&(c+=Blockly.Css.CONTENT.join("\n"),Blockly.FieldDate&&(c+=Blockly.FieldDate.CSS.join("\n")));Blockly.Css.mediaPath_=b.replace(/[\\\/]$/,"");var c=c.replace(/<<<PATH>>>/g,Blockly.Css.mediaPath_),d=document.createElement("style");document.head.insertBefore(d,document.head.firstChild);c=document.createTextNode(c);d.appendChild(c);Blockly.Css.styleSheet_=d.sheet}};Blockly.Css.setCursor=function(a){console.warn("Deprecated call to Blockly.Css.setCursor.See https://github.com/google/blockly/issues/981 for context")};
                +Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;","overflow: hidden;","position: absolute;","display: block;","}",".blocklyWidgetDiv {","display: none;","position: absolute;","z-index: 99999;","}",".injectionDiv {","height: 100%;","position: relative;","overflow: hidden;","touch-action: none","}",".blocklyNonSelectable {","user-select: none;","-moz-user-select: none;","-webkit-user-select: none;","-ms-user-select: none;","}",".blocklyWsDragSurface {","display: none;",
                +"position: absolute;","overflow: visible;","top: 0;","left: 0;","}",".blocklyBlockDragSurface {","display: none;","position: absolute;","top: 0;","left: 0;","right: 0;","bottom: 0;","overflow: visible !important;","z-index: 50;","}",".blocklyTooltipDiv {","background-color: #ffffc7;","border: 1px solid #ddc;","box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);","color: #000;","display: none;","font-family: sans-serif;","font-size: 9pt;","opacity: 0.9;","padding: 2px;","position: absolute;","z-index: 100000;",
                +"}",".blocklyResizeSE {","cursor: se-resize;","fill: #aaa;","}",".blocklyResizeSW {","cursor: sw-resize;","fill: #aaa;","}",".blocklyResizeLine {","stroke: #888;","stroke-width: 1;","}",".blocklyHighlightedConnectionPath {","fill: none;","stroke: #fc3;","stroke-width: 4px;","}",".blocklyPathLight {","fill: none;","stroke-linecap: round;","stroke-width: 1;","}",".blocklySelected>.blocklyPath {","stroke: #fc3;","stroke-width: 3px;","}",".blocklySelected>.blocklyPathLight {","display: none;","}",".blocklyDraggable {",
                +'cursor: url("<<<PATH>>>/handopen.cur"), auto;',"cursor: grab;","cursor: -webkit-grab;","cursor: -moz-grab;","}",".blocklyDragging {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyDraggable:active {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyBlockDragSurface .blocklyDraggable {",'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
                +"cursor: grabbing;","cursor: -webkit-grabbing;","cursor: -moz-grabbing;","}",".blocklyDragging.blocklyDraggingDelete {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyToolboxDelete {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {","fill-opacity: .8;","stroke-opacity: .8;","}",".blocklyDragging>.blocklyPathDark {","display: none;","}",".blocklyDisabled>.blocklyPath {","fill-opacity: .5;","stroke-opacity: .5;",
                +"}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {","display: none;","}",".blocklyText {","cursor: default;","fill: #fff;","font-family: sans-serif;","font-size: 11pt;","}",".blocklyNonEditableText>text {","pointer-events: none;","}",".blocklyNonEditableText>rect,",".blocklyEditableText>rect {","fill: #fff;","fill-opacity: .6;","}",".blocklyNonEditableText>text,",".blocklyEditableText>text {","fill: #000;","}",".blocklyEditableText:hover>rect {","stroke: #fff;","stroke-width: 2;",
                +"}",".blocklyBubbleText {","fill: #000;","}",".blocklyFlyout {","position: absolute;","z-index: 20;","}",".blocklyFlyoutButton {","fill: #888;","cursor: default;","}",".blocklyFlyoutButtonShadow {","fill: #666;","}",".blocklyFlyoutButton:hover {","fill: #aaa;","}",".blocklyFlyoutLabel {","cursor: default;","}",".blocklyFlyoutLabelBackground {","opacity: 0;","}",".blocklyFlyoutLabelText {","fill: #000;","}",".blocklySvg text, .blocklyBlockDragSurface text {","user-select: none;","-moz-user-select: none;",
                +"-webkit-user-select: none;","cursor: inherit;","}",".blocklyHidden {","display: none;","}",".blocklyFieldDropdown:not(.blocklyHidden) {","display: block;","}",".blocklyIconGroup {","cursor: default;","}",".blocklyIconGroup:not(:hover),",".blocklyIconGroupReadonly {","opacity: .6;","}",".blocklyIconShape {","fill: #00f;","stroke: #fff;","stroke-width: 1px;","}",".blocklyIconSymbol {","fill: #fff;","}",".blocklyMinimalBody {","margin: 0;","padding: 0;","}",".blocklyCommentTextarea {","background-color: #ffc;",
                +"border: 0;","margin: 0;","padding: 2px;","resize: none;","}",".blocklyHtmlInput {","border: none;","border-radius: 4px;","font-family: sans-serif;","height: 100%;","margin: 0;","outline: none;","padding: 0 1px;","width: 100%","}",".blocklyMainBackground {","stroke-width: 1;","stroke: #c6c6c6;","}",".blocklyMutatorBackground {","fill: #fff;","stroke: #ddd;","stroke-width: 1;","}",".blocklyFlyoutBackground {","fill: #ddd;","fill-opacity: .8;","}",".blocklyTransparentBackground {","opacity: 0;","}",
                +".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyZoom>image {","opacity: .4;","}",".blocklyZoom>image:hover {","opacity: .6;","}",
                +".blocklyZoom>image:active {","opacity: .8;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyAngleCircle {","stroke: #444;","stroke-width: 1;","fill: #ddd;","fill-opacity: .8;","}",".blocklyAngleMarks {","stroke: #444;","stroke-width: 1;","}",".blocklyAngleGauge {","fill: #f88;","fill-opacity: .8;",
                +"}",".blocklyAngleLine {","stroke: #f00;","stroke-width: 2;","stroke-linecap: round;","pointer-events: none;","}",".blocklyContextMenu {","border-radius: 4px;","}",".blocklyDropdownMenu {","padding: 0 !important;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;","}",".blocklyToolboxDiv {","background-color: #ddd;","overflow-x: visible;",
                +"overflow-y: auto;","position: absolute;","z-index: 70;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {",
                +"background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;","}",".blocklyTreeIconClosedRtl {","background-position: 0px -1px;",
                +"}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {","background-position: -32px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedRtl {","background-position: 0px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeIconNone,",".blocklyTreeSelected>.blocklyTreeIconNone {","background-position: -48px -1px;","}",".blocklyTreeLabel {","cursor: default;","font-family: sans-serif;",
                +"font-size: 16px;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}",".blocklyWidgetDiv .goog-palette {","outline: none;","cursor: default;","}",".blocklyWidgetDiv .goog-palette-table {","border: 1px solid #666;","border-collapse: collapse;","}",".blocklyWidgetDiv .goog-palette-cell {","height: 13px;","width: 15px;","margin: 0;","border: 0;",
                +"text-align: center;","vertical-align: middle;","border-right: 1px solid #666;","font-size: 1px;","}",".blocklyWidgetDiv .goog-palette-colorswatch {","position: relative;","height: 13px;","width: 15px;","border: 1px solid #666;","}",".blocklyWidgetDiv .goog-palette-cell-hover .goog-palette-colorswatch {","border: 1px solid #FFF;","}",".blocklyWidgetDiv .goog-palette-cell-selected .goog-palette-colorswatch {","border: 1px solid #000;","color: #fff;","}",".blocklyWidgetDiv .goog-menu {","background: #fff;",
                +"border-color: #ccc #666 #666 #ccc;","border-style: solid;","border-width: 1px;","cursor: default;","font: normal 13px Arial, sans-serif;","margin: 0;","outline: none;","padding: 4px 0;","position: absolute;","overflow-y: auto;","overflow-x: hidden;","max-height: 100%;","z-index: 20000;","}",".blocklyWidgetDiv .goog-menuitem {","color: #000;","font: normal 13px Arial, sans-serif;","list-style: none;","margin: 0;","padding: 4px 7em 4px 28px;","white-space: nowrap;","}",".blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl {",
                +"padding-left: 7em;","padding-right: 28px;","}",".blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem,",".blocklyWidgetDiv .goog-menu-noicon .goog-menuitem {","padding-left: 12px;","}",".blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem {","padding-right: 20px;","}",".blocklyWidgetDiv .goog-menuitem-content {","color: #000;","font: normal 13px Arial, sans-serif;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel,",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content {",
                +"color: #ccc !important;","}",".blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon {","opacity: 0.3;","-moz-opacity: 0.3;","filter: alpha(opacity=30);","}",".blocklyWidgetDiv .goog-menuitem-highlight,",".blocklyWidgetDiv .goog-menuitem-hover {","background-color: #d6e9f8;","border-color: #d6e9f8;","border-style: dotted;","border-width: 1px 0;","padding-bottom: 3px;","padding-top: 3px;","}",".blocklyWidgetDiv .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-icon {","background-repeat: no-repeat;",
                +"height: 16px;","left: 6px;","position: absolute;","right: auto;","vertical-align: middle;","width: 16px;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon {","left: auto;","right: 6px;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0;","}",".blocklyWidgetDiv .goog-menuitem-accel {",
                +"color: #999;","direction: ltr;","left: auto;","padding: 0 6px;","position: absolute;","right: 0;","text-align: right;","}",".blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel {","left: 0;","right: auto;","text-align: left;","}",".blocklyWidgetDiv .goog-menuitem-mnemonic-hint {","text-decoration: underline;","}",".blocklyWidgetDiv .goog-menuitem-mnemonic-separator {","color: #999;","font-size: 12px;","padding-left: 4px;","}",".blocklyWidgetDiv .goog-menuseparator {","border-top: 1px solid #ccc;",
                +"margin: 4px 0;","padding: 0;","}",""];Blockly.WidgetDiv={};Blockly.WidgetDiv.DIV=null;Blockly.WidgetDiv.owner_=null;Blockly.WidgetDiv.dispose_=null;Blockly.WidgetDiv.createDom=function(){Blockly.WidgetDiv.DIV||(Blockly.WidgetDiv.DIV=goog.dom.createDom("DIV","blocklyWidgetDiv"),document.body.appendChild(Blockly.WidgetDiv.DIV))};
                +Blockly.WidgetDiv.show=function(a,b,c){Blockly.WidgetDiv.hide();Blockly.WidgetDiv.owner_=a;Blockly.WidgetDiv.dispose_=c;a=goog.style.getViewportPageOffset(document);Blockly.WidgetDiv.DIV.style.top=a.y+"px";Blockly.WidgetDiv.DIV.style.direction=b?"rtl":"ltr";Blockly.WidgetDiv.DIV.style.display="block"};
                +Blockly.WidgetDiv.hide=function(){Blockly.WidgetDiv.owner_&&(Blockly.WidgetDiv.owner_=null,Blockly.WidgetDiv.DIV.style.display="none",Blockly.WidgetDiv.DIV.style.left="",Blockly.WidgetDiv.DIV.style.top="",Blockly.WidgetDiv.dispose_&&Blockly.WidgetDiv.dispose_(),Blockly.WidgetDiv.dispose_=null,goog.dom.removeChildren(Blockly.WidgetDiv.DIV))};Blockly.WidgetDiv.isVisible=function(){return!!Blockly.WidgetDiv.owner_};Blockly.WidgetDiv.hideIfOwner=function(a){Blockly.WidgetDiv.owner_==a&&Blockly.WidgetDiv.hide()};
                +Blockly.WidgetDiv.position=function(a,b,c,d,e){b<d.y&&(b=d.y);e?a>c.width+d.x&&(a=c.width+d.x):a<d.x&&(a=d.x);Blockly.WidgetDiv.DIV.style.left=a+"px";Blockly.WidgetDiv.DIV.style.top=b+"px";Blockly.WidgetDiv.DIV.style.height=c.height+"px"};Blockly.inject=function(a,b){goog.isString(a)&&(a=document.getElementById(a)||document.querySelector(a));if(!goog.dom.contains(document,a))throw"Error: container is not in current document.";var c=new Blockly.Options(b||{}),d=goog.dom.createDom("div","injectionDiv");a.appendChild(d);var e=Blockly.createDom_(d,c),f=new Blockly.BlockDragSurfaceSvg(d),d=new Blockly.WorkspaceDragSurfaceSvg(d),c=Blockly.createMainWorkspace_(e,c,f,d);Blockly.init_(c);Blockly.mainWorkspace=c;Blockly.svgResize(c);return c};
                +Blockly.createDom_=function(a,b){a.setAttribute("dir","LTR");goog.ui.Component.setDefaultRightToLeft(b.RTL);Blockly.Css.inject(b.hasCss,b.pathToMedia);var c=Blockly.utils.createSvgElement("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:html":"http://www.w3.org/1999/xhtml","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1","class":"blocklySvg"},a),d=Blockly.utils.createSvgElement("defs",{},c),e=String(Math.random()).substring(2),f=Blockly.utils.createSvgElement("filter",{id:"blocklyEmbossFilter"+
                +e},d);Blockly.utils.createSvgElement("feGaussianBlur",{"in":"SourceAlpha",stdDeviation:1,result:"blur"},f);var g=Blockly.utils.createSvgElement("feSpecularLighting",{"in":"blur",surfaceScale:1,specularConstant:.5,specularExponent:10,"lighting-color":"white",result:"specOut"},f);Blockly.utils.createSvgElement("fePointLight",{x:-5E3,y:-1E4,z:2E4},g);Blockly.utils.createSvgElement("feComposite",{"in":"specOut",in2:"SourceAlpha",operator:"in",result:"specOut"},f);Blockly.utils.createSvgElement("feComposite",
                +{"in":"SourceGraphic",in2:"specOut",operator:"arithmetic",k1:0,k2:1,k3:1,k4:0},f);b.embossFilterId=f.id;f=Blockly.utils.createSvgElement("pattern",{id:"blocklyDisabledPattern"+e,patternUnits:"userSpaceOnUse",width:10,height:10},d);Blockly.utils.createSvgElement("rect",{width:10,height:10,fill:"#aaa"},f);Blockly.utils.createSvgElement("path",{d:"M 0 0 L 10 10 M 10 0 L 0 10",stroke:"#cc0"},f);b.disabledPatternId=f.id;b.gridPattern=Blockly.Grid.createDom(e,b.gridOptions,d);return c};
                +Blockly.createMainWorkspace_=function(a,b,c,d){b.parentWorkspace=null;var e=new Blockly.WorkspaceSvg(b,c,d);e.scale=b.zoomOptions.startScale;a.appendChild(e.createDom("blocklyMainBackground"));!b.hasCategories&&b.languageTree&&(c=e.addFlyout_("svg"),Blockly.utils.insertAfter_(c,a));e.translate(0,0);Blockly.mainWorkspace=e;b.readOnly||b.hasScrollbars||e.addChangeListener(function(){if(!e.isDragging()){var a=e.getMetrics(),c=a.viewLeft+a.absoluteLeft,d=a.viewTop+a.absoluteTop;if(a.contentTop<d||a.contentTop+
                +a.contentHeight>a.viewHeight+d||a.contentLeft<(b.RTL?a.viewLeft:c)||a.contentLeft+a.contentWidth>(b.RTL?a.viewWidth:a.viewWidth+c))for(var k=e.getTopBlocks(!1),l=0,m;m=k[l];l++){var n=m.getRelativeToSurfaceXY(),p=m.getHeightWidth(),q=d+25-p.height-n.y;0<q&&m.moveBy(0,q);q=d+a.viewHeight-25-n.y;0>q&&m.moveBy(0,q);q=25+c-n.x-(b.RTL?0:p.width);0<q&&m.moveBy(q,0);n=c+a.viewWidth-25-n.x+(b.RTL?p.width:0);0>n&&m.moveBy(n,0)}}});Blockly.svgResize(e);Blockly.WidgetDiv.createDom();Blockly.Tooltip.createDom();
                +return e};
                +Blockly.init_=function(a){var b=a.options,c=a.getParentSvg();Blockly.bindEventWithChecks_(c.parentNode,"contextmenu",null,function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()});c=Blockly.bindEventWithChecks_(window,"resize",null,function(){Blockly.hideChaff(!0);Blockly.svgResize(a)});a.setResizeHandlerWrapper(c);Blockly.inject.bindDocumentEvents_();b.languageTree&&(a.toolbox_?a.toolbox_.init(a):a.flyout_&&(a.flyout_.init(a),a.flyout_.show(b.languageTree.childNodes),a.flyout_.scrollToStart(),a.scrollX=
                +a.flyout_.width_,b.toolboxPosition==Blockly.TOOLBOX_AT_RIGHT&&(a.scrollX*=-1),a.translate(a.scrollX,0)));b.hasScrollbars&&(a.scrollbar=new Blockly.ScrollbarPair(a),a.scrollbar.resize());b.hasSounds&&Blockly.inject.loadSounds_(b.pathToMedia,a)};
                +Blockly.inject.bindDocumentEvents_=function(){Blockly.documentEventsBound_||(Blockly.bindEventWithChecks_(document,"keydown",null,Blockly.onKeyDown_),Blockly.bindEvent_(document,"touchend",null,Blockly.longStop_),Blockly.bindEvent_(document,"touchcancel",null,Blockly.longStop_),goog.userAgent.IPAD&&Blockly.bindEventWithChecks_(window,"orientationchange",document,function(){Blockly.svgResize(Blockly.getMainWorkspace())}));Blockly.documentEventsBound_=!0};
                +Blockly.inject.loadSounds_=function(a,b){var c=b.getAudioManager();c.load([a+"click.mp3",a+"click.wav",a+"click.ogg"],"click");c.load([a+"disconnect.wav",a+"disconnect.mp3",a+"disconnect.ogg"],"disconnect");c.load([a+"delete.mp3",a+"delete.ogg",a+"delete.wav"],"delete");var d=[],e=function(){for(;d.length;)Blockly.unbindEvent_(d.pop());c.preload()};d.push(Blockly.bindEventWithChecks_(document,"mousemove",null,e,!0));d.push(Blockly.bindEventWithChecks_(document,"touchstart",null,e,!0))};
                +Blockly.updateToolbox=function(a){console.warn("Deprecated call to Blockly.updateToolbox, use workspace.updateToolbox instead.");Blockly.getMainWorkspace().updateToolbox(a)};var CLOSURE_DEFINES={"goog.DEBUG":!1};Blockly.mainWorkspace=null;Blockly.selected=null;Blockly.draggingConnections_=[];Blockly.clipboardXml_=null;Blockly.clipboardSource_=null;Blockly.cache3dSupported_=null;Blockly.hueToRgb=function(a){return goog.color.hsvToHex(a,Blockly.HSV_SATURATION,255*Blockly.HSV_VALUE)};Blockly.svgSize=function(a){return{width:a.cachedWidth_,height:a.cachedHeight_}};Blockly.resizeSvgContents=function(a){a.resizeContents()};
                +Blockly.svgResize=function(a){for(;a.options.parentWorkspace;)a=a.options.parentWorkspace;var b=a.getParentSvg(),c=b.parentNode;if(c){var d=c.offsetWidth,c=c.offsetHeight;b.cachedWidth_!=d&&(b.setAttribute("width",d+"px"),b.cachedWidth_=d);b.cachedHeight_!=c&&(b.setAttribute("height",c+"px"),b.cachedHeight_=c);a.resize()}};
                +Blockly.onKeyDown_=function(a){if(!Blockly.mainWorkspace.options.readOnly&&!Blockly.utils.isTargetInput(a)){var b=!1;if(27==a.keyCode)Blockly.hideChaff();else if(8==a.keyCode||46==a.keyCode){a.preventDefault();if(Blockly.mainWorkspace.isDragging())return;Blockly.selected&&Blockly.selected.isDeletable()&&(b=!0)}else if(a.altKey||a.ctrlKey||a.metaKey){if(Blockly.mainWorkspace.isDragging())return;Blockly.selected&&Blockly.selected.isDeletable()&&Blockly.selected.isMovable()&&(67==a.keyCode?(Blockly.hideChaff(),
                +Blockly.copy_(Blockly.selected)):88==a.keyCode&&(Blockly.copy_(Blockly.selected),b=!0));86==a.keyCode?Blockly.clipboardXml_&&(Blockly.Events.setGroup(!0),Blockly.clipboardSource_.paste(Blockly.clipboardXml_),Blockly.Events.setGroup(!1)):90==a.keyCode&&(Blockly.hideChaff(),Blockly.mainWorkspace.undo(a.shiftKey))}b&&(Blockly.Events.setGroup(!0),Blockly.hideChaff(),Blockly.selected.dispose(!0,!0),Blockly.Events.setGroup(!1))}};
                +Blockly.copy_=function(a){var b=Blockly.Xml.blockToDom(a);Blockly.Xml.deleteNext(b);var c=a.getRelativeToSurfaceXY();b.setAttribute("x",a.RTL?-c.x:c.x);b.setAttribute("y",c.y);Blockly.clipboardXml_=b;Blockly.clipboardSource_=a.workspace};Blockly.duplicate_=function(a){var b=Blockly.clipboardXml_,c=Blockly.clipboardSource_;Blockly.copy_(a);a.workspace.paste(Blockly.clipboardXml_);Blockly.clipboardXml_=b;Blockly.clipboardSource_=c};
                +Blockly.onContextMenu_=function(a){Blockly.utils.isTargetInput(a)||a.preventDefault()};Blockly.hideChaff=function(a){Blockly.Tooltip.hide();Blockly.WidgetDiv.hide();a||(a=Blockly.getMainWorkspace(),a.toolbox_&&a.toolbox_.flyout_&&a.toolbox_.flyout_.autoClose&&a.toolbox_.clearSelection())};Blockly.addChangeListener=function(a){console.warn("Deprecated call to Blockly.addChangeListener, use workspace.addChangeListener instead.");return Blockly.getMainWorkspace().addChangeListener(a)};
                +Blockly.getMainWorkspace=function(){return Blockly.mainWorkspace};Blockly.alert=function(a,b){window.alert(a);b&&b()};Blockly.confirm=function(a,b){b(window.confirm(a))};Blockly.prompt=function(a,b,c){c(window.prompt(a,b))};Blockly.jsonInitFactory_=function(a){return function(){this.jsonInit(a)}};
                +Blockly.defineBlocksWithJsonArray=function(a){for(var b=0,c;c=a[b];b++){var d=c.type;null==d||""===d?console.warn("Block definition #"+b+" in JSON array is missing a type attribute. Skipping."):(Blockly.Blocks[d]&&console.warn("Block definition #"+b+' in JSON array overwrites prior definition of "'+d+'".'),Blockly.Blocks[d]={init:Blockly.jsonInitFactory_(c)})}};
                +Blockly.bindEventWithChecks_=function(a,b,c,d,e){var f=!1,g=function(a){var b=!e;a=Blockly.Touch.splitEventByTouches(a);for(var g=0,h;h=a[g];g++)if(!b||Blockly.Touch.shouldHandleEvent(h))Blockly.Touch.setClientFromTouch(h),c?d.call(c,h):d(h),f=!0};a.addEventListener(b,g,!1);var h=[[a,b,g]];if(b in Blockly.Touch.TOUCH_MAP)for(var k=function(a){g(a);f&&a.preventDefault()},l=0,m;m=Blockly.Touch.TOUCH_MAP[b][l];l++)a.addEventListener(m,k,!1),h.push([a,m,k]);return h};
                +Blockly.bindEvent_=function(a,b,c,d){var e=function(a){c?d.call(c,a):d(a)};a.addEventListener(b,e,!1);var f=[[a,b,e]];if(b in Blockly.Touch.TOUCH_MAP)for(var g=function(a){if(1==a.changedTouches.length){var b=a.changedTouches[0];a.clientX=b.clientX;a.clientY=b.clientY}e(a);a.preventDefault()},h=0,k;k=Blockly.Touch.TOUCH_MAP[b][h];h++)a.addEventListener(k,g,!1),f.push([a,k,g]);return f};
                +Blockly.unbindEvent_=function(a){for(var b;a.length;){b=a.pop();var c=b[0],d=b[1];b=b[2];c.removeEventListener(d,b,!1)}return b};Blockly.isNumber=function(a){return!!a.match(/^\s*-?\d+(\.\d+)?\s*$/)};goog.global.console||(goog.global.console={log:function(){},warn:function(){}});goog.global.Blockly||(goog.global.Blockly={});goog.global.Blockly.getMainWorkspace=Blockly.getMainWorkspace;goog.global.Blockly.addChangeListener=Blockly.addChangeListener;
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/blockly_uncompressed.js b/blockly/webif/static/blockly/blockly_uncompressed.js
                new file mode 100644
                index 000000000..fac0e7d96
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blockly_uncompressed.js
                @@ -0,0 +1,1747 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +var isNodeJS = !!(typeof module !== 'undefined' && module.exports &&
                +                  typeof window === 'undefined');
                +
                +if (isNodeJS) {
                +  var window = {};
                +  require('closure-library');
                +}
                +
                +window.BLOCKLY_DIR = (function() {
                +  if (!isNodeJS) {
                +    // Find name of current directory.
                +    var scripts = document.getElementsByTagName('script');
                +    var re = new RegExp('(.+)[\/]blockly_(.*)uncompressed\.js$');
                +    for (var i = 0, script; script = scripts[i]; i++) {
                +      var match = re.exec(script.src);
                +      if (match) {
                +        return match[1];
                +      }
                +    }
                +    alert('Could not detect Blockly\'s directory name.');
                +  }
                +  return '';
                +})();
                +
                +window.BLOCKLY_BOOT = function() {
                +  var dir = '';
                +  if (isNodeJS) {
                +    require('closure-library');
                +    dir = 'blockly';
                +  } else {
                +    // Execute after Closure has loaded.
                +    if (!window.goog) {
                +      alert('Error: Closure not found.  Read this:\n' +
                +            'developers.google.com/blockly/guides/modify/web/closure');
                +    }
                +    dir = window.BLOCKLY_DIR.match(/[^\/]+$/)[0];
                +  }
                +goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Mutator', 'Blockly.Warning', 'Blockly.Workspace', 'Blockly.Xml', 'goog.array', 'goog.asserts', 'goog.math.Coordinate', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/block_drag_surface.js", ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/block_dragger.js", ['Blockly.BlockDragger'], ['Blockly.DraggedConnectionManager', 'goog.math.Coordinate', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/block_render_svg.js", ['Blockly.BlockSvg.render'], ['Blockly.BlockSvg', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['Blockly.Block', 'Blockly.ContextMenu', 'Blockly.Grid', 'Blockly.RenderedConnection', 'Blockly.Touch', 'Blockly.utils', 'goog.Timer', 'goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/blockly.js", ['Blockly'], ['Blockly.BlockSvg.render', 'Blockly.Events', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldTextInput', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.Generator', 'Blockly.Msg', 'Blockly.Procedures', 'Blockly.Toolbox', 'Blockly.Touch', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.constants', 'Blockly.inject', 'Blockly.utils', 'goog.color', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/blocks.js", ['Blockly.Blocks'], []);
                +goog.addDependency("../../../" + dir + "/core/bubble.js", ['Blockly.Bubble'], ['Blockly.Touch', 'Blockly.Workspace', 'goog.dom', 'goog.math', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/comment.js", ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Icon', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/connection.js", ['Blockly.Connection'], ['goog.asserts', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/connection_db.js", ['Blockly.ConnectionDB'], ['Blockly.Connection']);
                +goog.addDependency("../../../" + dir + "/core/constants.js", ['Blockly.constants'], []);
                +goog.addDependency("../../../" + dir + "/core/contextmenu.js", ['Blockly.ContextMenu'], ['goog.dom', 'goog.events', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItem']);
                +goog.addDependency("../../../" + dir + "/core/css.js", ['Blockly.Css'], []);
                +goog.addDependency("../../../" + dir + "/core/dragged_connection_manager.js", ['Blockly.DraggedConnectionManager'], ['Blockly.RenderedConnection', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/events.js", ['Blockly.Events'], ['goog.array', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/extensions.js", ['Blockly.Extensions'], []);
                +goog.addDependency("../../../" + dir + "/core/field.js", ['Blockly.Field'], ['Blockly.Gesture', 'goog.asserts', 'goog.dom', 'goog.math.Size', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_angle.js", ['Blockly.FieldAngle'], ['Blockly.FieldTextInput', 'goog.math', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_checkbox.js", ['Blockly.FieldCheckbox'], ['Blockly.Field']);
                +goog.addDependency("../../../" + dir + "/core/field_colour.js", ['Blockly.FieldColour'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.ColorPicker']);
                +goog.addDependency("../../../" + dir + "/core/field_date.js", ['Blockly.FieldDate'], ['Blockly.Field', 'goog.date', 'goog.dom', 'goog.events', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_he', 'goog.style', 'goog.ui.DatePicker']);
                +goog.addDependency("../../../" + dir + "/core/field_dropdown.js", ['Blockly.FieldDropdown'], ['Blockly.Field', 'goog.dom', 'goog.events', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_image.js", ['Blockly.FieldImage'], ['Blockly.Field', 'goog.dom', 'goog.math.Size', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_label.js", ['Blockly.FieldLabel'], ['Blockly.Field', 'Blockly.Tooltip', 'goog.dom', 'goog.math.Size']);
                +goog.addDependency("../../../" + dir + "/core/field_number.js", ['Blockly.FieldNumber'], ['Blockly.FieldTextInput', 'goog.math']);
                +goog.addDependency("../../../" + dir + "/core/field_textinput.js", ['Blockly.FieldTextInput'], ['Blockly.Field', 'Blockly.Msg', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/field_variable.js", ['Blockly.FieldVariable'], ['Blockly.FieldDropdown', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Variables', 'Blockly.VariableModel', 'goog.asserts', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/flyout_base.js", ['Blockly.Flyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.FlyoutButton', 'Blockly.Gesture', 'Blockly.Touch', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/flyout_button.js", ['Blockly.FlyoutButton'], ['goog.dom', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/flyout_dragger.js", ['Blockly.FlyoutDragger'], ['Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/flyout_horizontal.js", ['Blockly.HorizontalFlyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.FlyoutButton', 'Blockly.Flyout', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/flyout_vertical.js", ['Blockly.VerticalFlyout'], ['Blockly.Block', 'Blockly.Events', 'Blockly.Flyout', 'Blockly.FlyoutButton', 'Blockly.utils', 'Blockly.WorkspaceSvg', 'goog.dom', 'goog.events', 'goog.math.Rect', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/generator.js", ['Blockly.Generator'], ['Blockly.Block', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/gesture.js", ['Blockly.Gesture'], ['Blockly.BlockDragger', 'Blockly.constants', 'Blockly.FlyoutDragger', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.WorkspaceDragger', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/grid.js", ['Blockly.Grid'], ['Blockly.utils', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/icon.js", ['Blockly.Icon'], ['goog.dom', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/inject.js", ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Css', 'Blockly.Grid', 'Blockly.Options', 'Blockly.WorkspaceSvg', 'Blockly.WorkspaceDragSurfaceSvg', 'goog.dom', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/input.js", ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/msg.js", ['Blockly.Msg'], []);
                +goog.addDependency("../../../" + dir + "/core/mutator.js", ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'goog.Timer', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/names.js", ['Blockly.Names'], []);
                +goog.addDependency("../../../" + dir + "/core/options.js", ['Blockly.Options'], []);
                +goog.addDependency("../../../" + dir + "/core/procedures.js", ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.Field', 'Blockly.Names', 'Blockly.Workspace']);
                +goog.addDependency("../../../" + dir + "/core/rendered_connection.js", ['Blockly.RenderedConnection'], ['Blockly.Connection']);
                +goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['goog.dom', 'goog.events']);
                +goog.addDependency("../../../" + dir + "/core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Flyout', 'Blockly.HorizontalFlyout', 'Blockly.Touch', 'Blockly.VerticalFlyout', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserFeature', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.math.Rect', 'goog.style', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']);
                +goog.addDependency("../../../" + dir + "/core/tooltip.js", ['Blockly.Tooltip'], ['goog.dom', 'goog.dom.TagName']);
                +goog.addDependency("../../../" + dir + "/core/touch.js", ['Blockly.Touch'], ['goog.events', 'goog.events.BrowserFeature', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/trashcan.js", ['Blockly.Trashcan'], ['goog.Timer', 'goog.dom', 'goog.math', 'goog.math.Rect']);
                +goog.addDependency("../../../" + dir + "/core/utils.js", ['Blockly.utils'], ['Blockly.Touch', 'goog.dom', 'goog.events.BrowserFeature', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/variable_map.js", ['Blockly.VariableMap'], []);
                +goog.addDependency("../../../" + dir + "/core/variable_model.js", ['Blockly.VariableModel'], ['goog.string']);
                +goog.addDependency("../../../" + dir + "/core/variables.js", ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.VariableModel', 'Blockly.Workspace', 'goog.string']);
                +goog.addDependency("../../../" + dir + "/core/warning.js", ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Icon']);
                +goog.addDependency("../../../" + dir + "/core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.Css', 'goog.dom', 'goog.dom.TagName', 'goog.style']);
                +goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.VariableMap', 'goog.array', 'goog.math']);
                +goog.addDependency("../../../" + dir + "/core/workspace_audio.js", ['Blockly.WorkspaceAudio'], []);
                +goog.addDependency("../../../" + dir + "/core/workspace_drag_surface_svg.js", ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("../../../" + dir + "/core/workspace_dragger.js", ['Blockly.WorkspaceDragger'], ['goog.math.Coordinate', 'goog.asserts']);
                +goog.addDependency("../../../" + dir + "/core/workspace_svg.js", ['Blockly.WorkspaceSvg'], ['Blockly.ConnectionDB', 'Blockly.constants', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Touch', 'Blockly.Trashcan', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.ZoomControls', 'goog.array', 'goog.dom', 'goog.math.Coordinate', 'goog.userAgent']);
                +goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], ['goog.asserts', 'goog.dom']);
                +goog.addDependency("../../../" + dir + "/core/zoom_controls.js", ['Blockly.ZoomControls'], ['Blockly.Touch', 'goog.dom']);
                +goog.addDependency("../../alltests.js", [], []);
                +goog.addDependency("../../browser_capabilities.js", [], []);
                +goog.addDependency("../../doc/js/article.js", [], []);
                +goog.addDependency("../../protractor.conf.js", [], []);
                +goog.addDependency("../../protractor_spec.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/base.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/caja/string/html/htmlparser.js", ['goog.string.html', 'goog.string.html.HtmlParser', 'goog.string.html.HtmlParser.EFlags', 'goog.string.html.HtmlParser.Elements', 'goog.string.html.HtmlParser.Entities', 'goog.string.html.HtmlSaxHandler'], []);
                +goog.addDependency("../../third_party/closure/goog/caja/string/html/htmlsanitizer.js", ['goog.string.html.HtmlSanitizer', 'goog.string.html.HtmlSanitizer.AttributeType', 'goog.string.html.HtmlSanitizer.Attributes', 'goog.string.html.htmlSanitize'], ['goog.string.StringBuffer', 'goog.string.html.HtmlParser', 'goog.string.html.HtmlSaxHandler']);
                +goog.addDependency("../../third_party/closure/goog/deps.js", [], []);
                +goog.addDependency("../../third_party/closure/goog/dojo/dom/query.js", ['goog.dom.query'], ['goog.array', 'goog.dom', 'goog.functions', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("../../third_party/closure/goog/dojo/dom/query_test.js", [], ['goog.dom', 'goog.dom.query', 'goog.userAgent']);
                +goog.addDependency("../../third_party/closure/goog/loremipsum/text/loremipsum.js", ['goog.text.LoremIpsum'], ['goog.array', 'goog.math', 'goog.string', 'goog.structs.Map', 'goog.structs.Set']);
                +goog.addDependency("../../third_party/closure/goog/mochikit/async/deferred.js", ['goog.async.Deferred', 'goog.async.Deferred.AlreadyCalledError', 'goog.async.Deferred.CanceledError'], ['goog.Promise', 'goog.Thenable', 'goog.array', 'goog.asserts', 'goog.debug.Error']);
                +goog.addDependency("../../third_party/closure/goog/mochikit/async/deferredlist.js", ['goog.async.DeferredList'], ['goog.async.Deferred']);
                +goog.addDependency("../../third_party/closure/goog/svgpan/svgpan.js", ['svgpan.SvgPan'], ['goog.Disposable', 'goog.events', 'goog.events.EventType', 'goog.events.MouseWheelHandler']);
                +goog.addDependency("a11y/aria/announcer.js", ['goog.a11y.aria.Announcer'], ['goog.Disposable', 'goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.object']);
                +goog.addDependency("a11y/aria/announcer_test.js", ['goog.a11y.aria.AnnouncerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Announcer', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.iframe', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("a11y/aria/aria.js", ['goog.a11y.aria'], ['goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.a11y.aria.datatables', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.object', 'goog.string']);
                +goog.addDependency("a11y/aria/aria_test.js", ['goog.a11y.ariaTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("a11y/aria/attributes.js", ['goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.CheckedValues', 'goog.a11y.aria.DropEffectValues', 'goog.a11y.aria.ExpandedValues', 'goog.a11y.aria.GrabbedValues', 'goog.a11y.aria.InvalidValues', 'goog.a11y.aria.LivePriority', 'goog.a11y.aria.OrientationValues', 'goog.a11y.aria.PressedValues', 'goog.a11y.aria.RelevantValues', 'goog.a11y.aria.SelectedValues', 'goog.a11y.aria.SortValues', 'goog.a11y.aria.State'], []);
                +goog.addDependency("a11y/aria/datatables.js", ['goog.a11y.aria.datatables'], ['goog.a11y.aria.State', 'goog.object']);
                +goog.addDependency("a11y/aria/roles.js", ['goog.a11y.aria.Role'], []);
                +goog.addDependency("array/array.js", ['goog.array'], ['goog.asserts']);
                +goog.addDependency("array/array_test.js", ['goog.arrayTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("asserts/asserts.js", ['goog.asserts', 'goog.asserts.AssertionError'], ['goog.debug.Error', 'goog.dom.NodeType', 'goog.string']);
                +goog.addDependency("asserts/asserts_test.js", ['goog.assertsTest'], ['goog.asserts', 'goog.asserts.AssertionError', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.string', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("async/animationdelay.js", ['goog.async.AnimationDelay'], ['goog.Disposable', 'goog.events', 'goog.functions']);
                +goog.addDependency("async/animationdelay_test.js", [], []);
                +goog.addDependency("async/conditionaldelay.js", ['goog.async.ConditionalDelay'], ['goog.Disposable', 'goog.async.Delay']);
                +goog.addDependency("async/conditionaldelay_test.js", ['goog.async.ConditionalDelayTest'], ['goog.async.ConditionalDelay', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/debouncer.js", ['goog.async.Debouncer'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/debouncer_test.js", ['goog.async.DebouncerTest'], ['goog.array', 'goog.async.Debouncer', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("async/delay.js", ['goog.Delay', 'goog.async.Delay'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/delay_test.js", ['goog.async.DelayTest'], ['goog.async.Delay', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/freelist.js", ['goog.async.FreeList'], []);
                +goog.addDependency("async/freelist_test.js", ['goog.async.FreeListTest'], ['goog.async.FreeList', 'goog.testing.jsunit']);
                +goog.addDependency("async/nexttick.js", ['goog.async.nextTick', 'goog.async.throwException'], ['goog.debug.entryPointRegistry', 'goog.dom.TagName', 'goog.functions', 'goog.labs.userAgent.browser', 'goog.labs.userAgent.engine']);
                +goog.addDependency("async/nexttick_test.js", ['goog.async.nextTickTest'], ['goog.Promise', 'goog.Timer', 'goog.async.nextTick', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("async/run.js", ['goog.async.run'], ['goog.async.WorkQueue', 'goog.async.nextTick', 'goog.async.throwException']);
                +goog.addDependency("async/run_test.js", ['goog.async.runTest'], ['goog.async.run', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("async/throttle.js", ['goog.Throttle', 'goog.async.Throttle'], ['goog.Disposable', 'goog.Timer']);
                +goog.addDependency("async/throttle_test.js", ['goog.async.ThrottleTest'], ['goog.async.Throttle', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("async/workqueue.js", ['goog.async.WorkItem', 'goog.async.WorkQueue'], ['goog.asserts', 'goog.async.FreeList']);
                +goog.addDependency("async/workqueue_test.js", ['goog.async.WorkQueueTest'], ['goog.async.WorkQueue', 'goog.testing.jsunit']);
                +goog.addDependency("base.js", [], []);
                +goog.addDependency("base_module_test.js", [], []);
                +goog.addDependency("base_test.js", ['goog.baseTest'], ['goog.Promise', 'goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.object', 'goog.test_module', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("bootstrap/nodejs.js", [], []);
                +goog.addDependency("bootstrap/webworkers.js", [], []);
                +goog.addDependency("color/alpha.js", ['goog.color.alpha'], ['goog.color']);
                +goog.addDependency("color/alpha_test.js", ['goog.color.alphaTest'], ['goog.array', 'goog.color', 'goog.color.alpha', 'goog.testing.jsunit']);
                +goog.addDependency("color/color.js", ['goog.color', 'goog.color.Hsl', 'goog.color.Hsv', 'goog.color.Rgb'], ['goog.color.names', 'goog.math']);
                +goog.addDependency("color/color_test.js", ['goog.colorTest'], ['goog.array', 'goog.color', 'goog.color.names', 'goog.testing.jsunit']);
                +goog.addDependency("color/names.js", ['goog.color.names'], []);
                +goog.addDependency("crypt/aes.js", ['goog.crypt.Aes'], ['goog.asserts', 'goog.crypt.BlockCipher']);
                +goog.addDependency("crypt/aes_test.js", ['goog.crypt.AesTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/arc4.js", ['goog.crypt.Arc4'], ['goog.asserts']);
                +goog.addDependency("crypt/arc4_test.js", ['goog.crypt.Arc4Test'], ['goog.array', 'goog.crypt.Arc4', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/base64.js", ['goog.crypt.base64'], ['goog.asserts', 'goog.crypt', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("crypt/base64_test.js", ['goog.crypt.base64Test'], ['goog.crypt', 'goog.crypt.base64', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/basen.js", ['goog.crypt.baseN'], []);
                +goog.addDependency("crypt/basen_test.js", ['goog.crypt.baseNTest'], ['goog.crypt.baseN', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/blobhasher.js", ['goog.crypt.BlobHasher', 'goog.crypt.BlobHasher.EventType'], ['goog.asserts', 'goog.events.EventTarget', 'goog.fs', 'goog.log']);
                +goog.addDependency("crypt/blobhasher_test.js", ['goog.crypt.BlobHasherTest'], ['goog.crypt', 'goog.crypt.BlobHasher', 'goog.crypt.Md5', 'goog.events', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/blockcipher.js", ['goog.crypt.BlockCipher'], []);
                +goog.addDependency("crypt/bytestring_perf.js", ['goog.crypt.byteArrayToStringPerf'], ['goog.array', 'goog.dom', 'goog.testing.PerformanceTable']);
                +goog.addDependency("crypt/cbc.js", ['goog.crypt.Cbc'], ['goog.array', 'goog.asserts', 'goog.crypt']);
                +goog.addDependency("crypt/cbc_test.js", ['goog.crypt.CbcTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.crypt.Cbc', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/crypt.js", ['goog.crypt'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("crypt/crypt_test.js", ['goog.cryptTest'], ['goog.crypt', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/ctr.js", ['goog.crypt.Ctr'], ['goog.array', 'goog.asserts', 'goog.crypt']);
                +goog.addDependency("crypt/ctr_test.js", ['goog.crypt.CtrTest'], ['goog.crypt', 'goog.crypt.Aes', 'goog.crypt.Ctr', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/hash.js", ['goog.crypt.Hash'], []);
                +goog.addDependency("crypt/hash32.js", ['goog.crypt.hash32'], ['goog.crypt']);
                +goog.addDependency("crypt/hash32_test.js", ['goog.crypt.hash32Test'], ['goog.crypt.hash32', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/hashtester.js", ['goog.crypt.hashTester'], ['goog.array', 'goog.crypt', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTable', 'goog.testing.PseudoRandom', 'goog.testing.asserts']);
                +goog.addDependency("crypt/hmac.js", ['goog.crypt.Hmac'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/hmac_test.js", ['goog.crypt.HmacTest'], ['goog.crypt.Hmac', 'goog.crypt.Sha1', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/md5.js", ['goog.crypt.Md5'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/md5_test.js", ['goog.crypt.Md5Test'], ['goog.crypt', 'goog.crypt.Md5', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/pbkdf2.js", ['goog.crypt.pbkdf2'], ['goog.array', 'goog.asserts', 'goog.crypt', 'goog.crypt.Hmac', 'goog.crypt.Sha1']);
                +goog.addDependency("crypt/pbkdf2_test.js", ['goog.crypt.pbkdf2Test'], ['goog.crypt', 'goog.crypt.pbkdf2', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha1.js", ['goog.crypt.Sha1'], ['goog.crypt.Hash']);
                +goog.addDependency("crypt/sha1_test.js", ['goog.crypt.Sha1Test'], ['goog.crypt', 'goog.crypt.Sha1', 'goog.crypt.hashTester', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha2.js", ['goog.crypt.Sha2'], ['goog.array', 'goog.asserts', 'goog.crypt.Hash']);
                +goog.addDependency("crypt/sha224.js", ['goog.crypt.Sha224'], ['goog.crypt.Sha2']);
                +goog.addDependency("crypt/sha224_test.js", ['goog.crypt.Sha224Test'], ['goog.crypt', 'goog.crypt.Sha224', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/sha256.js", ['goog.crypt.Sha256'], ['goog.crypt.Sha2']);
                +goog.addDependency("crypt/sha256_test.js", ['goog.crypt.Sha256Test'], ['goog.crypt', 'goog.crypt.Sha256', 'goog.crypt.hashTester', 'goog.testing.jsunit']);
                +goog.addDependency("crypt/sha2_64bit.js", ['goog.crypt.Sha2_64bit'], ['goog.array', 'goog.asserts', 'goog.crypt.Hash', 'goog.math.Long']);
                +goog.addDependency("crypt/sha2_64bit_test.js", ['goog.crypt.Sha2_64bit_test'], ['goog.array', 'goog.crypt', 'goog.crypt.Sha384', 'goog.crypt.Sha512', 'goog.crypt.Sha512_256', 'goog.crypt.hashTester', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("crypt/sha384.js", ['goog.crypt.Sha384'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("crypt/sha512.js", ['goog.crypt.Sha512'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("crypt/sha512_256.js", ['goog.crypt.Sha512_256'], ['goog.crypt.Sha2_64bit']);
                +goog.addDependency("cssom/cssom.js", ['goog.cssom', 'goog.cssom.CssRuleType'], ['goog.array', 'goog.dom', 'goog.dom.TagName']);
                +goog.addDependency("cssom/cssom_test.js", ['goog.cssomTest'], ['goog.array', 'goog.cssom', 'goog.cssom.CssRuleType', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("cssom/iframe/style.js", ['goog.cssom.iframe.style'], ['goog.asserts', 'goog.cssom', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("cssom/iframe/style_test.js", ['goog.cssom.iframe.styleTest'], ['goog.cssom', 'goog.cssom.iframe.style', 'goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("datasource/datamanager.js", ['goog.ds.DataManager'], ['goog.ds.BasicNodeList', 'goog.ds.DataNode', 'goog.ds.Expr', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.Map']);
                +goog.addDependency("datasource/datasource.js", ['goog.ds.BaseDataNode', 'goog.ds.BasicNodeList', 'goog.ds.DataNode', 'goog.ds.DataNodeList', 'goog.ds.EmptyNodeList', 'goog.ds.LoadState', 'goog.ds.SortedNodeList', 'goog.ds.Util', 'goog.ds.logger'], ['goog.array', 'goog.log']);
                +goog.addDependency("datasource/datasource_test.js", ['goog.ds.JsDataSourceTest'], ['goog.dom.xml', 'goog.ds.DataManager', 'goog.ds.JsDataSource', 'goog.ds.SortedNodeList', 'goog.ds.XmlDataSource', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/expr.js", ['goog.ds.Expr'], ['goog.ds.BasicNodeList', 'goog.ds.EmptyNodeList', 'goog.string']);
                +goog.addDependency("datasource/expr_test.js", ['goog.ds.ExprTest'], ['goog.ds.DataManager', 'goog.ds.Expr', 'goog.ds.JsDataSource', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/fastdatanode.js", ['goog.ds.AbstractFastDataNode', 'goog.ds.FastDataNode', 'goog.ds.FastListNode', 'goog.ds.PrimitiveFastDataNode'], ['goog.ds.DataManager', 'goog.ds.DataNodeList', 'goog.ds.EmptyNodeList', 'goog.string']);
                +goog.addDependency("datasource/fastdatanode_test.js", ['goog.ds.FastDataNodeTest'], ['goog.array', 'goog.ds.DataManager', 'goog.ds.Expr', 'goog.ds.FastDataNode', 'goog.testing.jsunit']);
                +goog.addDependency("datasource/jsdatasource.js", ['goog.ds.JsDataSource', 'goog.ds.JsPropertyDataSource'], ['goog.ds.BaseDataNode', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.EmptyNodeList', 'goog.ds.LoadState']);
                +goog.addDependency("datasource/jsondatasource.js", ['goog.ds.JsonDataSource'], ['goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.ds.DataManager', 'goog.ds.JsDataSource', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log']);
                +goog.addDependency("datasource/jsxmlhttpdatasource.js", ['goog.ds.JsXmlHttpDataSource'], ['goog.Uri', 'goog.ds.DataManager', 'goog.ds.FastDataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.events', 'goog.json', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("datasource/jsxmlhttpdatasource_test.js", ['goog.ds.JsXmlHttpDataSourceTest'], ['goog.ds.JsXmlHttpDataSource', 'goog.testing.TestQueue', 'goog.testing.jsunit', 'goog.testing.net.XhrIo']);
                +goog.addDependency("datasource/xmldatasource.js", ['goog.ds.XmlDataSource', 'goog.ds.XmlHttpDataSource'], ['goog.Uri', 'goog.dom.NodeType', 'goog.dom.xml', 'goog.ds.BasicNodeList', 'goog.ds.DataManager', 'goog.ds.DataNode', 'goog.ds.LoadState', 'goog.ds.logger', 'goog.log', 'goog.net.XhrIo', 'goog.string']);
                +goog.addDependency("date/date.js", ['goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval', 'goog.date.month', 'goog.date.weekDay'], ['goog.asserts', 'goog.date.DateLike', 'goog.i18n.DateTimeSymbols', 'goog.string']);
                +goog.addDependency("date/date_test.js", ['goog.dateTest'], ['goog.array', 'goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval', 'goog.date.month', 'goog.date.weekDay', 'goog.i18n.DateTimeSymbols', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.platform', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("date/datelike.js", ['goog.date.DateLike'], []);
                +goog.addDependency("date/daterange.js", ['goog.date.DateRange', 'goog.date.DateRange.Iterator', 'goog.date.DateRange.StandardDateRangeKeys'], ['goog.date.Date', 'goog.date.Interval', 'goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("date/daterange_test.js", ['goog.date.DateRangeTest'], ['goog.date.Date', 'goog.date.DateRange', 'goog.date.Interval', 'goog.i18n.DateTimeSymbols', 'goog.testing.jsunit']);
                +goog.addDependency("date/duration.js", ['goog.date.duration'], ['goog.i18n.DateTimeFormat', 'goog.i18n.MessageFormat']);
                +goog.addDependency("date/duration_test.js", ['goog.date.durationTest'], ['goog.date.duration', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.testing.jsunit']);
                +goog.addDependency("date/relative.js", ['goog.date.relative', 'goog.date.relative.TimeDeltaFormatter', 'goog.date.relative.Unit'], ['goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns']);
                +goog.addDependency("date/relative_test.js", ['goog.date.relativeTest'], ['goog.date.DateTime', 'goog.date.relative', 'goog.i18n.DateTimeFormat', 'goog.testing.jsunit']);
                +goog.addDependency("date/relativewithplurals.js", ['goog.date.relativeWithPlurals'], ['goog.date.relative', 'goog.date.relative.Unit', 'goog.i18n.MessageFormat']);
                +goog.addDependency("date/relativewithplurals_test.js", ['goog.date.relativeWithPluralsTest'], ['goog.date.relative', 'goog.date.relativeTest', 'goog.date.relativeWithPlurals', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_bn', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_fa']);
                +goog.addDependency("date/utcdatetime.js", ['goog.date.UtcDateTime'], ['goog.date', 'goog.date.Date', 'goog.date.DateTime', 'goog.date.Interval']);
                +goog.addDependency("date/utcdatetime_test.js", ['goog.date.UtcDateTimeTest'], ['goog.date.Interval', 'goog.date.UtcDateTime', 'goog.date.month', 'goog.date.weekDay', 'goog.testing.jsunit']);
                +goog.addDependency("db/cursor.js", ['goog.db.Cursor'], ['goog.async.Deferred', 'goog.db.Error', 'goog.db.KeyRange', 'goog.debug', 'goog.events.EventTarget']);
                +goog.addDependency("db/db.js", ['goog.db', 'goog.db.BlockedCallback', 'goog.db.UpgradeNeededCallback'], ['goog.asserts', 'goog.async.Deferred', 'goog.db.Error', 'goog.db.IndexedDb', 'goog.db.Transaction']);
                +goog.addDependency("db/db_test.js", ['goog.dbTest'], ['goog.Disposable', 'goog.Promise', 'goog.array', 'goog.db', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.IndexedDb', 'goog.db.KeyRange', 'goog.db.Transaction', 'goog.events', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent.product']);
                +goog.addDependency("db/error.js", ['goog.db.DomErrorLike', 'goog.db.Error', 'goog.db.Error.ErrorCode', 'goog.db.Error.ErrorName', 'goog.db.Error.VersionChangeBlockedError'], ['goog.debug.Error']);
                +goog.addDependency("db/index.js", ['goog.db.Index'], ['goog.async.Deferred', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.KeyRange', 'goog.debug']);
                +goog.addDependency("db/indexeddb.js", ['goog.db.IndexedDb'], ['goog.db.Error', 'goog.db.ObjectStore', 'goog.db.Transaction', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget']);
                +goog.addDependency("db/keyrange.js", ['goog.db.KeyRange'], []);
                +goog.addDependency("db/objectstore.js", ['goog.db.ObjectStore'], ['goog.async.Deferred', 'goog.db.Cursor', 'goog.db.Error', 'goog.db.Index', 'goog.db.KeyRange', 'goog.debug', 'goog.events']);
                +goog.addDependency("db/transaction.js", ['goog.db.Transaction', 'goog.db.Transaction.TransactionMode'], ['goog.async.Deferred', 'goog.db.Error', 'goog.db.ObjectStore', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget']);
                +goog.addDependency("debug/console.js", ['goog.debug.Console'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.debug.TextFormatter']);
                +goog.addDependency("debug/console_test.js", ['goog.debug.ConsoleTest'], ['goog.debug.Console', 'goog.debug.LogRecord', 'goog.debug.Logger', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("debug/debug.js", ['goog.debug'], ['goog.array', 'goog.structs.Set', 'goog.userAgent']);
                +goog.addDependency("debug/debug_test.js", ['goog.debugTest'], ['goog.debug', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("debug/debugwindow.js", ['goog.debug.DebugWindow'], ['goog.debug.HtmlFormatter', 'goog.debug.LogManager', 'goog.debug.Logger', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.string.Const', 'goog.structs.CircularBuffer', 'goog.userAgent']);
                +goog.addDependency("debug/debugwindow_test.js", ['goog.debug.DebugWindowTest'], ['goog.debug.DebugWindow', 'goog.testing.jsunit']);
                +goog.addDependency("debug/devcss/devcss.js", ['goog.debug.DevCss', 'goog.debug.DevCss.UserAgent'], ['goog.asserts', 'goog.cssom', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("debug/devcss/devcss_test.js", ['goog.debug.DevCssTest'], ['goog.debug.DevCss', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("debug/devcss/devcssrunner.js", ['goog.debug.devCssRunner'], ['goog.debug.DevCss']);
                +goog.addDependency("debug/divconsole.js", ['goog.debug.DivConsole'], ['goog.debug.HtmlFormatter', 'goog.debug.LogManager', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.string.Const', 'goog.style']);
                +goog.addDependency("debug/enhanceerror_test.js", ['goog.debugEnhanceErrorTest'], ['goog.debug', 'goog.testing.jsunit']);
                +goog.addDependency("debug/entrypointregistry.js", ['goog.debug.EntryPointMonitor', 'goog.debug.entryPointRegistry'], ['goog.asserts']);
                +goog.addDependency("debug/entrypointregistry_test.js", ['goog.debug.entryPointRegistryTest'], ['goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.testing.jsunit']);
                +goog.addDependency("debug/error.js", ['goog.debug.Error'], []);
                +goog.addDependency("debug/error_test.js", ['goog.debug.ErrorTest'], ['goog.debug.Error', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("debug/errorhandler.js", ['goog.debug.ErrorHandler', 'goog.debug.ErrorHandler.ProtectedFunctionError'], ['goog.Disposable', 'goog.asserts', 'goog.debug', 'goog.debug.EntryPointMonitor', 'goog.debug.Error', 'goog.debug.Trace']);
                +goog.addDependency("debug/errorhandler_async_test.js", ['goog.debug.ErrorHandlerAsyncTest'], ['goog.Promise', 'goog.debug.ErrorHandler', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("debug/errorhandler_test.js", ['goog.debug.ErrorHandlerTest'], ['goog.debug.ErrorHandler', 'goog.testing.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("debug/errorhandlerweakdep.js", ['goog.debug.errorHandlerWeakDep'], []);
                +goog.addDependency("debug/errorreporter.js", ['goog.debug.ErrorReporter', 'goog.debug.ErrorReporter.ExceptionEvent'], ['goog.asserts', 'goog.debug', 'goog.debug.Error', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.log', 'goog.net.XhrIo', 'goog.object', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("debug/errorreporter_test.js", ['goog.debug.ErrorReporterTest'], ['goog.debug.Error', 'goog.debug.ErrorReporter', 'goog.events', 'goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("debug/fancywindow.js", ['goog.debug.FancyWindow'], ['goog.array', 'goog.asserts', 'goog.debug.DebugWindow', 'goog.debug.LogManager', 'goog.debug.Logger', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyleSheet', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("debug/formatter.js", ['goog.debug.Formatter', 'goog.debug.HtmlFormatter', 'goog.debug.TextFormatter'], ['goog.debug', 'goog.debug.Logger', 'goog.debug.RelativeTimeProvider', 'goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.string.Const']);
                +goog.addDependency("debug/formatter_test.js", ['goog.debug.FormatterTest'], ['goog.debug.HtmlFormatter', 'goog.debug.LogRecord', 'goog.debug.Logger', 'goog.html.SafeHtml', 'goog.testing.jsunit']);
                +goog.addDependency("debug/fpsdisplay.js", ['goog.debug.FpsDisplay'], ['goog.asserts', 'goog.async.AnimationDelay', 'goog.dom', 'goog.dom.TagName', 'goog.ui.Component']);
                +goog.addDependency("debug/fpsdisplay_test.js", ['goog.debug.FpsDisplayTest'], ['goog.Timer', 'goog.debug.FpsDisplay', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logbuffer.js", ['goog.debug.LogBuffer'], ['goog.asserts', 'goog.debug.LogRecord']);
                +goog.addDependency("debug/logbuffer_test.js", ['goog.debug.LogBufferTest'], ['goog.debug.LogBuffer', 'goog.debug.Logger', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logger.js", ['goog.debug.LogManager', 'goog.debug.Loggable', 'goog.debug.Logger', 'goog.debug.Logger.Level'], ['goog.array', 'goog.asserts', 'goog.debug', 'goog.debug.LogBuffer', 'goog.debug.LogRecord']);
                +goog.addDependency("debug/logger_test.js", ['goog.debug.LoggerTest'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.testing.jsunit']);
                +goog.addDependency("debug/logrecord.js", ['goog.debug.LogRecord'], []);
                +goog.addDependency("debug/logrecordserializer.js", ['goog.debug.logRecordSerializer'], ['goog.debug.LogRecord', 'goog.debug.Logger', 'goog.json', 'goog.object']);
                +goog.addDependency("debug/logrecordserializer_test.js", ['goog.debug.logRecordSerializerTest'], ['goog.debug.LogRecord', 'goog.debug.Logger', 'goog.debug.logRecordSerializer', 'goog.testing.jsunit']);
                +goog.addDependency("debug/relativetimeprovider.js", ['goog.debug.RelativeTimeProvider'], []);
                +goog.addDependency("debug/tracer.js", ['goog.debug.Trace'], ['goog.array', 'goog.debug.Logger', 'goog.iter', 'goog.log', 'goog.structs.Map', 'goog.structs.SimplePool']);
                +goog.addDependency("debug/tracer_test.js", ['goog.debug.TraceTest'], ['goog.debug.Trace', 'goog.testing.jsunit']);
                +goog.addDependency("defineclass_test.js", ['goog.defineClassTest'], ['goog.testing.jsunit']);
                +goog.addDependency("demos/autocompleteremotedata.js", [], []);
                +goog.addDependency("demos/autocompleterichremotedata.js", [], []);
                +goog.addDependency("demos/editor/deps.js", [], []);
                +goog.addDependency("demos/editor/helloworld.js", ['goog.demos.editor.HelloWorld'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Plugin']);
                +goog.addDependency("demos/editor/helloworld_test.js", ['goog.demos.editor.HelloWorldTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.demos.editor.HelloWorld', 'goog.testing.editor.TestHelper', 'goog.testing.editor.FieldMock']);
                +goog.addDependency("demos/editor/helloworlddialog.js", ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent'], ['goog.dom.TagName', 'goog.events.Event', 'goog.string', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("demos/editor/helloworlddialog_test.js", ['goog.demos.editor.HelloWorldDialogTest'], ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent', 'goog.dom.DomHelper', 'goog.events.EventHandler', 'goog.testing.LooseMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog.EventType']);
                +goog.addDependency("demos/editor/helloworlddialogplugin.js", ['goog.demos.editor.HelloWorldDialogPlugin', 'goog.demos.editor.HelloWorldDialogPlugin.Command'], ['goog.demos.editor.HelloWorldDialog', 'goog.dom.TagName', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.range', 'goog.functions', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("demos/editor/helloworlddialogplugin_test.js", ['goog.demos.editor.HelloWorldDialogPluginTest'], ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent', 'goog.demos.editor.HelloWorldDialogPlugin', 'goog.demos.editor.HelloWorldDialogPlugin.Command', 'goog.dom', 'goog.dom.NodeType', 'goog.testing.ExpectedFailures', 'goog.testing.MockControl', 'goog.testing.MockRange', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.editor.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.userAgent']);
                +goog.addDependency("demos/graphics/tigerdata.js", [], []);
                +goog.addDependency("demos/samplecomponent.js", ['goog.demos.SampleComponent'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.ui.Component']);
                +goog.addDependency("demos/tree/testdata.js", [], []);
                +goog.addDependency("demos/xpc/xpcdemo.js", ['xpcdemo'], ['goog.Uri', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.json', 'goog.log', 'goog.log.Level', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel']);
                +goog.addDependency("deps.js", [], []);
                +goog.addDependency("disposable/disposable.js", ['goog.Disposable', 'goog.dispose', 'goog.disposeAll'], ['goog.disposable.IDisposable']);
                +goog.addDependency("disposable/disposable_test.js", ['goog.DisposableTest'], ['goog.Disposable', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("disposable/idisposable.js", ['goog.disposable.IDisposable'], []);
                +goog.addDependency("dom/abstractmultirange.js", ['goog.dom.AbstractMultiRange'], ['goog.array', 'goog.dom', 'goog.dom.AbstractRange', 'goog.dom.TextRange']);
                +goog.addDependency("dom/abstractrange.js", ['goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.SavedCaretRange', 'goog.dom.TagIterator', 'goog.userAgent']);
                +goog.addDependency("dom/abstractrange_test.js", ['goog.dom.AbstractRangeTest'], ['goog.dom', 'goog.dom.AbstractRange', 'goog.dom.Range', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/animationframe/animationframe.js", ['goog.dom.animationFrame', 'goog.dom.animationFrame.Spec', 'goog.dom.animationFrame.State'], ['goog.dom.animationFrame.polyfill']);
                +goog.addDependency("dom/animationframe/animationframe_test.js", [], ['goog.dom.animationFrame', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("dom/animationframe/polyfill.js", ['goog.dom.animationFrame.polyfill'], []);
                +goog.addDependency("dom/annotate.js", ['goog.dom.annotate', 'goog.dom.annotate.AnnotateFn'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.object']);
                +goog.addDependency("dom/annotate_test.js", ['goog.dom.annotateTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.annotate', 'goog.html.SafeHtml', 'goog.testing.jsunit']);
                +goog.addDependency("dom/attr.js", ['goog.dom.Attr'], []);
                +goog.addDependency("dom/browserfeature.js", ['goog.dom.BrowserFeature'], ['goog.userAgent']);
                +goog.addDependency("dom/browserrange/abstractrange.js", ['goog.dom.browserrange.AbstractRange'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.iter', 'goog.math.Coordinate', 'goog.string', 'goog.string.StringBuffer', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/browserrange.js", ['goog.dom.browserrange', 'goog.dom.browserrange.Error'], ['goog.dom', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.browserrange.GeckoRange', 'goog.dom.browserrange.IeRange', 'goog.dom.browserrange.OperaRange', 'goog.dom.browserrange.W3cRange', 'goog.dom.browserrange.WebKitRange', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/browserrange_test.js", ['goog.dom.browserrangeTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange', 'goog.html.testing', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/geckorange.js", ['goog.dom.browserrange.GeckoRange'], ['goog.dom.browserrange.W3cRange']);
                +goog.addDependency("dom/browserrange/ierange.js", ['goog.dom.browserrange.IeRange'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange.AbstractRange', 'goog.log', 'goog.string']);
                +goog.addDependency("dom/browserrange/operarange.js", ['goog.dom.browserrange.OperaRange'], ['goog.dom.browserrange.W3cRange']);
                +goog.addDependency("dom/browserrange/w3crange.js", ['goog.dom.browserrange.W3cRange'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeEndpoint', 'goog.dom.TagName', 'goog.dom.browserrange.AbstractRange', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/browserrange/webkitrange.js", ['goog.dom.browserrange.WebKitRange'], ['goog.dom.RangeEndpoint', 'goog.dom.browserrange.W3cRange', 'goog.userAgent']);
                +goog.addDependency("dom/bufferedviewportsizemonitor.js", ['goog.dom.BufferedViewportSizeMonitor'], ['goog.asserts', 'goog.async.Delay', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("dom/bufferedviewportsizemonitor_test.js", ['goog.dom.BufferedViewportSizeMonitorTest'], ['goog.dom.BufferedViewportSizeMonitor', 'goog.dom.ViewportSizeMonitor', 'goog.events', 'goog.events.EventType', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit']);
                +goog.addDependency("dom/classes.js", ['goog.dom.classes'], ['goog.array']);
                +goog.addDependency("dom/classes_test.js", ['goog.dom.classes_test'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classes', 'goog.testing.jsunit']);
                +goog.addDependency("dom/classlist.js", ['goog.dom.classlist'], ['goog.array']);
                +goog.addDependency("dom/classlist_test.js", ['goog.dom.classlist_test'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit']);
                +goog.addDependency("dom/controlrange.js", ['goog.dom.ControlRange', 'goog.dom.ControlRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TagWalkType', 'goog.dom.TextRange', 'goog.iter.StopIteration', 'goog.userAgent']);
                +goog.addDependency("dom/controlrange_test.js", ['goog.dom.ControlRangeTest'], ['goog.dom', 'goog.dom.ControlRange', 'goog.dom.RangeType', 'goog.dom.TagName', 'goog.dom.TextRange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/dataset.js", ['goog.dom.dataset'], ['goog.labs.userAgent.browser', 'goog.string', 'goog.userAgent.product']);
                +goog.addDependency("dom/dataset_test.js", ['goog.dom.datasetTest'], ['goog.dom', 'goog.dom.dataset', 'goog.testing.jsunit']);
                +goog.addDependency("dom/dom.js", ['goog.dom', 'goog.dom.Appendable', 'goog.dom.DomHelper'], ['goog.array', 'goog.asserts', 'goog.dom.BrowserFeature', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.uncheckedconversions', 'goog.math.Coordinate', 'goog.math.Size', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']);
                +goog.addDependency("dom/dom_compile_test.js", [], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/dom_test.js", ['goog.dom.dom_test'], ['goog.array', 'goog.dom', 'goog.dom.BrowserFeature', 'goog.dom.DomHelper', 'goog.dom.InputType', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.html.SafeUrl', 'goog.html.testing', 'goog.object', 'goog.string.Const', 'goog.string.Unicode', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("dom/fontsizemonitor.js", ['goog.dom.FontSizeMonitor', 'goog.dom.FontSizeMonitor.EventType'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.userAgent']);
                +goog.addDependency("dom/fontsizemonitor_test.js", ['goog.dom.FontSizeMonitorTest'], ['goog.dom', 'goog.dom.FontSizeMonitor', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/forms.js", ['goog.dom.forms'], ['goog.dom.InputType', 'goog.dom.TagName', 'goog.structs.Map', 'goog.window']);
                +goog.addDependency("dom/forms_test.js", ['goog.dom.formsTest'], ['goog.dom', 'goog.dom.forms', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("dom/fullscreen.js", ['goog.dom.fullscreen', 'goog.dom.fullscreen.EventType'], ['goog.dom', 'goog.userAgent']);
                +goog.addDependency("dom/fullscreen_test.js", ['goog.dom.fullscreen_test'], ['goog.dom.DomHelper', 'goog.dom.fullscreen', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("dom/iframe.js", ['goog.dom.iframe'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.userAgent']);
                +goog.addDependency("dom/iframe_test.js", ['goog.dom.iframeTest'], ['goog.dom', 'goog.dom.iframe', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("dom/inputtype.js", ['goog.dom.InputType'], []);
                +goog.addDependency("dom/inputtype_test.js", ['goog.dom.InputTypeTest'], ['goog.dom.InputType', 'goog.object']);
                +goog.addDependency("dom/iter.js", ['goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator'], ['goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/iter_test.js", ['goog.dom.iterTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.iter.AncestorIterator', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/multirange.js", ['goog.dom.MultiRange', 'goog.dom.MultiRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.AbstractMultiRange', 'goog.dom.AbstractRange', 'goog.dom.RangeIterator', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TextRange', 'goog.iter', 'goog.iter.StopIteration', 'goog.log']);
                +goog.addDependency("dom/multirange_test.js", ['goog.dom.MultiRangeTest'], ['goog.dom', 'goog.dom.MultiRange', 'goog.dom.Range', 'goog.iter', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodeiterator.js", ['goog.dom.NodeIterator'], ['goog.dom.TagIterator']);
                +goog.addDependency("dom/nodeiterator_test.js", ['goog.dom.NodeIteratorTest'], ['goog.dom', 'goog.dom.NodeIterator', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodeoffset.js", ['goog.dom.NodeOffset'], ['goog.Disposable', 'goog.dom.TagName']);
                +goog.addDependency("dom/nodeoffset_test.js", ['goog.dom.NodeOffsetTest'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.testing.jsunit']);
                +goog.addDependency("dom/nodetype.js", ['goog.dom.NodeType'], []);
                +goog.addDependency("dom/pattern/abstractpattern.js", ['goog.dom.pattern.AbstractPattern'], ['goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/allchildren.js", ['goog.dom.pattern.AllChildren'], ['goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/callback/callback.js", ['goog.dom.pattern.callback'], ['goog.dom', 'goog.dom.TagWalkType', 'goog.iter']);
                +goog.addDependency("dom/pattern/callback/counter.js", ['goog.dom.pattern.callback.Counter'], []);
                +goog.addDependency("dom/pattern/callback/test.js", ['goog.dom.pattern.callback.Test'], ['goog.iter.StopIteration']);
                +goog.addDependency("dom/pattern/childmatches.js", ['goog.dom.pattern.ChildMatches'], ['goog.dom.pattern.AllChildren', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/endtag.js", ['goog.dom.pattern.EndTag'], ['goog.dom.TagWalkType', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/fulltag.js", ['goog.dom.pattern.FullTag'], ['goog.dom.pattern.MatchType', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/matcher.js", ['goog.dom.pattern.Matcher'], ['goog.dom.TagIterator', 'goog.dom.pattern.MatchType', 'goog.iter']);
                +goog.addDependency("dom/pattern/matcher_test.js", ['goog.dom.pattern.matcherTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.pattern.EndTag', 'goog.dom.pattern.FullTag', 'goog.dom.pattern.Matcher', 'goog.dom.pattern.Repeat', 'goog.dom.pattern.Sequence', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.callback.Counter', 'goog.dom.pattern.callback.Test', 'goog.iter.StopIteration', 'goog.testing.jsunit']);
                +goog.addDependency("dom/pattern/nodetype.js", ['goog.dom.pattern.NodeType'], ['goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/pattern.js", ['goog.dom.pattern', 'goog.dom.pattern.MatchType'], []);
                +goog.addDependency("dom/pattern/pattern_test.js", ['goog.dom.patternTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagWalkType', 'goog.dom.pattern.AllChildren', 'goog.dom.pattern.ChildMatches', 'goog.dom.pattern.EndTag', 'goog.dom.pattern.FullTag', 'goog.dom.pattern.MatchType', 'goog.dom.pattern.NodeType', 'goog.dom.pattern.Repeat', 'goog.dom.pattern.Sequence', 'goog.dom.pattern.StartTag', 'goog.dom.pattern.Text', 'goog.testing.jsunit']);
                +goog.addDependency("dom/pattern/repeat.js", ['goog.dom.pattern.Repeat'], ['goog.dom.NodeType', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/sequence.js", ['goog.dom.pattern.Sequence'], ['goog.dom.NodeType', 'goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/pattern/starttag.js", ['goog.dom.pattern.StartTag'], ['goog.dom.TagWalkType', 'goog.dom.pattern.Tag']);
                +goog.addDependency("dom/pattern/tag.js", ['goog.dom.pattern.Tag'], ['goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType', 'goog.object']);
                +goog.addDependency("dom/pattern/text.js", ['goog.dom.pattern.Text'], ['goog.dom.NodeType', 'goog.dom.pattern', 'goog.dom.pattern.AbstractPattern', 'goog.dom.pattern.MatchType']);
                +goog.addDependency("dom/range.js", ['goog.dom.Range'], ['goog.dom', 'goog.dom.AbstractRange', 'goog.dom.BrowserFeature', 'goog.dom.ControlRange', 'goog.dom.MultiRange', 'goog.dom.NodeType', 'goog.dom.TextRange']);
                +goog.addDependency("dom/range_test.js", ['goog.dom.RangeTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeType', 'goog.dom.TagName', 'goog.dom.TextRange', 'goog.dom.browserrange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/rangeendpoint.js", ['goog.dom.RangeEndpoint'], []);
                +goog.addDependency("dom/safe.js", ['goog.dom.safe', 'goog.dom.safe.InsertAdjacentHtmlPosition'], ['goog.asserts', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("dom/safe_test.js", ['goog.dom.safeTest'], ['goog.dom.safe', 'goog.dom.safe.InsertAdjacentHtmlPosition', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.testing', 'goog.string', 'goog.string.Const', 'goog.testing', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/savedcaretrange.js", ['goog.dom.SavedCaretRange'], ['goog.array', 'goog.dom', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.string']);
                +goog.addDependency("dom/savedcaretrange_test.js", ['goog.dom.SavedCaretRangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.SavedCaretRange', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/savedrange.js", ['goog.dom.SavedRange'], ['goog.Disposable', 'goog.log']);
                +goog.addDependency("dom/savedrange_test.js", ['goog.dom.SavedRangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/selection.js", ['goog.dom.selection'], ['goog.dom.InputType', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/selection_test.js", ['goog.dom.selectionTest'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.selection', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("dom/tagiterator.js", ['goog.dom.TagIterator', 'goog.dom.TagWalkType'], ['goog.dom', 'goog.dom.NodeType', 'goog.iter.Iterator', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/tagiterator_test.js", ['goog.dom.TagIteratorTest'], ['goog.dom', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.dom.TagWalkType', 'goog.iter', 'goog.iter.StopIteration', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/tagname.js", ['goog.dom.TagName'], []);
                +goog.addDependency("dom/tagname_test.js", ['goog.dom.TagNameTest'], ['goog.dom.TagName', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("dom/tags.js", ['goog.dom.tags'], ['goog.object']);
                +goog.addDependency("dom/tags_test.js", ['goog.dom.tagsTest'], ['goog.dom.tags', 'goog.testing.jsunit']);
                +goog.addDependency("dom/textrange.js", ['goog.dom.TextRange'], ['goog.array', 'goog.dom', 'goog.dom.AbstractRange', 'goog.dom.RangeType', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.dom.browserrange', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/textrange_test.js", ['goog.dom.TextRangeTest'], ['goog.dom', 'goog.dom.ControlRange', 'goog.dom.Range', 'goog.dom.TextRange', 'goog.math.Coordinate', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("dom/textrangeiterator.js", ['goog.dom.TextRangeIterator'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.RangeIterator', 'goog.dom.TagName', 'goog.iter.StopIteration']);
                +goog.addDependency("dom/textrangeiterator_test.js", ['goog.dom.TextRangeIteratorTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.TextRangeIterator', 'goog.iter.StopIteration', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("dom/vendor.js", ['goog.dom.vendor'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("dom/vendor_test.js", ['goog.dom.vendorTest'], ['goog.array', 'goog.dom.vendor', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil']);
                +goog.addDependency("dom/viewportsizemonitor.js", ['goog.dom.ViewportSizeMonitor'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Size']);
                +goog.addDependency("dom/viewportsizemonitor_test.js", ['goog.dom.ViewportSizeMonitorTest'], ['goog.dom.ViewportSizeMonitor', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("dom/xml.js", ['goog.dom.xml'], ['goog.dom', 'goog.dom.NodeType', 'goog.userAgent']);
                +goog.addDependency("dom/xml_test.js", ['goog.dom.xmlTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.xml', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/browserfeature.js", ['goog.editor.BrowserFeature'], ['goog.editor.defines', 'goog.labs.userAgent.browser', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("editor/browserfeature_test.js", ['goog.editor.BrowserFeatureTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit']);
                +goog.addDependency("editor/clicktoeditwrapper.js", ['goog.editor.ClickToEditWrapper'], ['goog.Disposable', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.range', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventType']);
                +goog.addDependency("editor/clicktoeditwrapper_test.js", ['goog.editor.ClickToEditWrapperTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.ClickToEditWrapper', 'goog.editor.SeamlessField', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/command.js", ['goog.editor.Command'], []);
                +goog.addDependency("editor/contenteditablefield.js", ['goog.editor.ContentEditableField'], ['goog.asserts', 'goog.editor.Field', 'goog.log']);
                +goog.addDependency("editor/contenteditablefield_test.js", ['goog.editor.ContentEditableFieldTest'], ['goog.dom', 'goog.editor.ContentEditableField', 'goog.editor.field_test', 'goog.testing.jsunit']);
                +goog.addDependency("editor/defines.js", ['goog.editor.defines'], []);
                +goog.addDependency("editor/field.js", ['goog.editor.Field', 'goog.editor.Field.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.array', 'goog.asserts', 'goog.async.Delay', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Plugin', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.editor.node', 'goog.editor.range', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.html.SafeHtml', 'goog.html.legacyconversions', 'goog.log', 'goog.log.Level', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/field_test.js", ['goog.editor.field_test'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.range', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.LooseMock', 'goog.testing.MockClock', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("editor/focus.js", ['goog.editor.focus'], ['goog.dom.selection']);
                +goog.addDependency("editor/focus_test.js", ['goog.editor.focusTest'], ['goog.dom.selection', 'goog.editor.BrowserFeature', 'goog.editor.focus', 'goog.testing.jsunit']);
                +goog.addDependency("editor/icontent.js", ['goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo'], ['goog.dom', 'goog.editor.BrowserFeature', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/icontent_test.js", ['goog.editor.icontentTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/link.js", ['goog.editor.Link'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.node', 'goog.editor.range', 'goog.string', 'goog.string.Unicode', 'goog.uri.utils', 'goog.uri.utils.ComponentIndex']);
                +goog.addDependency("editor/link_test.js", ['goog.editor.LinkTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Link', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/node.js", ['goog.editor.node'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.iter.ChildIterator', 'goog.dom.iter.SiblingIterator', 'goog.iter', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.userAgent']);
                +goog.addDependency("editor/node_test.js", ['goog.editor.nodeTest'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.node', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugin.js", ['goog.editor.Plugin'], ['goog.events.EventTarget', 'goog.functions', 'goog.log', 'goog.object', 'goog.reflect', 'goog.userAgent']);
                +goog.addDependency("editor/plugin_test.js", ['goog.editor.PluginTest'], ['goog.editor.Field', 'goog.editor.Plugin', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractbubbleplugin.js", ['goog.editor.plugins.AbstractBubblePlugin'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.Plugin', 'goog.editor.style', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.actionEventWrapper', 'goog.functions', 'goog.string.Unicode', 'goog.ui.Component', 'goog.ui.editor.Bubble', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractbubbleplugin_test.js", ['goog.editor.plugins.AbstractBubblePluginTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.functions', 'goog.style', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.editor.Bubble', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstractdialogplugin.js", ['goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.plugins.AbstractDialogPlugin.EventType'], ['goog.dom', 'goog.dom.Range', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.range', 'goog.events', 'goog.ui.editor.AbstractDialog']);
                +goog.addDependency("editor/plugins/abstractdialogplugin_test.js", ['goog.editor.plugins.AbstractDialogPluginTest'], ['goog.dom', 'goog.dom.SavedRange', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.events.Event', 'goog.events.EventHandler', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstracttabhandler.js", ['goog.editor.plugins.AbstractTabHandler'], ['goog.editor.Plugin', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/abstracttabhandler_test.js", ['goog.editor.plugins.AbstractTabHandlerTest'], ['goog.editor.Field', 'goog.editor.plugins.AbstractTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/basictextformatter.js", ['goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.BasicTextFormatter.COMMAND'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.editor.style', 'goog.iter', 'goog.iter.StopIteration', 'goog.log', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/basictextformatter_test.js", ['goog.editor.plugins.BasicTextFormatterTest'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.BasicTextFormatter', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.LooseMock', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/blockquote.js", ['goog.editor.plugins.Blockquote'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Plugin', 'goog.editor.node', 'goog.functions', 'goog.log']);
                +goog.addDependency("editor/plugins/blockquote_test.js", ['goog.editor.plugins.BlockquoteTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.plugins.Blockquote', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/emoticons.js", ['goog.editor.plugins.Emoticons'], ['goog.dom.TagName', 'goog.editor.Plugin', 'goog.editor.range', 'goog.functions', 'goog.ui.emoji.Emoji', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/emoticons_test.js", ['goog.editor.plugins.EmoticonsTest'], ['goog.Uri', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.Emoticons', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/enterhandler.js", ['goog.editor.plugins.EnterHandler'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.plugins.Blockquote', 'goog.editor.range', 'goog.editor.style', 'goog.events.KeyCodes', 'goog.functions', 'goog.object', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/enterhandler_test.js", ['goog.editor.plugins.EnterHandlerTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.Blockquote', 'goog.editor.plugins.EnterHandler', 'goog.editor.range', 'goog.events', 'goog.events.KeyCodes', 'goog.testing.ExpectedFailures', 'goog.testing.MockClock', 'goog.testing.dom', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/firststrong.js", ['goog.editor.plugins.FirstStrong'], ['goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.i18n.bidi', 'goog.i18n.uChar', 'goog.iter', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/firststrong_test.js", ['goog.editor.plugins.FirstStrongTest'], ['goog.dom.Range', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.plugins.FirstStrong', 'goog.editor.range', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/headerformatter.js", ['goog.editor.plugins.HeaderFormatter'], ['goog.editor.Command', 'goog.editor.Plugin', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/headerformatter_test.js", ['goog.editor.plugins.HeaderFormatterTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.HeaderFormatter', 'goog.events.BrowserEvent', 'goog.testing.LooseMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkbubble.js", ['goog.editor.plugins.LinkBubble', 'goog.editor.plugins.LinkBubble.Action'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.functions', 'goog.string', 'goog.style', 'goog.ui.editor.messages', 'goog.uri.utils', 'goog.window']);
                +goog.addDependency("editor/plugins/linkbubble_test.js", ['goog.editor.plugins.LinkBubbleTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.Link', 'goog.editor.plugins.LinkBubble', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.string', 'goog.style', 'goog.testing.FunctionMock', 'goog.testing.PropertyReplacer', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkdialogplugin.js", ['goog.editor.plugins.LinkDialogPlugin'], ['goog.array', 'goog.dom', 'goog.editor.Command', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.events.EventHandler', 'goog.functions', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.uri.utils']);
                +goog.addDependency("editor/plugins/linkdialogplugin_test.js", ['goog.ui.editor.plugins.LinkDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Link', 'goog.editor.plugins.LinkDialogPlugin', 'goog.string', 'goog.string.Unicode', 'goog.testing.MockControl', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.editor.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/linkshortcutplugin.js", ['goog.editor.plugins.LinkShortcutPlugin'], ['goog.editor.Command', 'goog.editor.Plugin']);
                +goog.addDependency("editor/plugins/linkshortcutplugin_test.js", ['goog.editor.plugins.LinkShortcutPluginTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Field', 'goog.editor.plugins.BasicTextFormatter', 'goog.editor.plugins.LinkBubble', 'goog.editor.plugins.LinkShortcutPlugin', 'goog.events.KeyCodes', 'goog.testing.PropertyReplacer', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/listtabhandler.js", ['goog.editor.plugins.ListTabHandler'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.plugins.AbstractTabHandler', 'goog.iter']);
                +goog.addDependency("editor/plugins/listtabhandler_test.js", ['goog.editor.plugins.ListTabHandlerTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.plugins.ListTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/loremipsum.js", ['goog.editor.plugins.LoremIpsum'], ['goog.asserts', 'goog.dom', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.functions', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/loremipsum_test.js", ['goog.editor.plugins.LoremIpsumTest'], ['goog.dom', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.plugins.LoremIpsum', 'goog.string.Unicode', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/removeformatting.js", ['goog.editor.plugins.RemoveFormatting'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.range', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/removeformatting_test.js", ['goog.editor.plugins.RemoveFormattingTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.plugins.RemoveFormatting', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.dom', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("editor/plugins/spacestabhandler.js", ['goog.editor.plugins.SpacesTabHandler'], ['goog.dom.TagName', 'goog.editor.plugins.AbstractTabHandler', 'goog.editor.range']);
                +goog.addDependency("editor/plugins/spacestabhandler_test.js", ['goog.editor.plugins.SpacesTabHandlerTest'], ['goog.dom', 'goog.dom.Range', 'goog.editor.plugins.SpacesTabHandler', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.functions', 'goog.testing.StrictMock', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/tableeditor.js", ['goog.editor.plugins.TableEditor'], ['goog.array', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Plugin', 'goog.editor.Table', 'goog.editor.node', 'goog.editor.range', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tableeditor_test.js", ['goog.editor.plugins.TableEditorTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.plugins.TableEditor', 'goog.object', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.editor.FieldMock', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tagonenterhandler.js", ['goog.editor.plugins.TagOnEnterHandler'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.Command', 'goog.editor.node', 'goog.editor.plugins.EnterHandler', 'goog.editor.range', 'goog.editor.style', 'goog.events.KeyCodes', 'goog.functions', 'goog.string.Unicode', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/tagonenterhandler_test.js", ['goog.editor.plugins.TagOnEnterHandlerTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.plugins.TagOnEnterHandler', 'goog.events.KeyCodes', 'goog.string.Unicode', 'goog.testing.dom', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/plugins/undoredo.js", ['goog.editor.plugins.UndoRedo'], ['goog.dom', 'goog.dom.NodeOffset', 'goog.dom.Range', 'goog.editor.BrowserFeature', 'goog.editor.Command', 'goog.editor.Field', 'goog.editor.Plugin', 'goog.editor.node', 'goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.events.EventHandler', 'goog.log', 'goog.object']);
                +goog.addDependency("editor/plugins/undoredo_test.js", ['goog.editor.plugins.UndoRedoTest'], ['goog.array', 'goog.dom', 'goog.dom.browserrange', 'goog.editor.Field', 'goog.editor.plugins.LoremIpsum', 'goog.editor.plugins.UndoRedo', 'goog.events', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/undoredomanager.js", ['goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoManager.EventType'], ['goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.events.EventTarget']);
                +goog.addDependency("editor/plugins/undoredomanager_test.js", ['goog.editor.plugins.UndoRedoManagerTest'], ['goog.editor.plugins.UndoRedoManager', 'goog.editor.plugins.UndoRedoState', 'goog.events', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("editor/plugins/undoredostate.js", ['goog.editor.plugins.UndoRedoState'], ['goog.events.EventTarget']);
                +goog.addDependency("editor/plugins/undoredostate_test.js", ['goog.editor.plugins.UndoRedoStateTest'], ['goog.editor.plugins.UndoRedoState', 'goog.testing.jsunit']);
                +goog.addDependency("editor/range.js", ['goog.editor.range', 'goog.editor.range.Point'], ['goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.dom.RangeEndpoint', 'goog.dom.SavedCaretRange', 'goog.editor.node', 'goog.editor.style', 'goog.iter', 'goog.userAgent']);
                +goog.addDependency("editor/range_test.js", ['goog.editor.rangeTest'], ['goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.range', 'goog.editor.range.Point', 'goog.string', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("editor/seamlessfield.js", ['goog.editor.SeamlessField'], ['goog.cssom.iframe.style', 'goog.dom', 'goog.dom.Range', 'goog.dom.TagName', 'goog.dom.safe', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.icontent', 'goog.editor.icontent.FieldFormatInfo', 'goog.editor.icontent.FieldStyleInfo', 'goog.editor.node', 'goog.events', 'goog.events.EventType', 'goog.html.uncheckedconversions', 'goog.log', 'goog.string.Const', 'goog.style']);
                +goog.addDependency("editor/seamlessfield_test.js", ['goog.editor.seamlessfield_test'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.Range', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Field', 'goog.editor.SeamlessField', 'goog.events', 'goog.functions', 'goog.style', 'goog.testing.MockClock', 'goog.testing.MockRange', 'goog.testing.jsunit']);
                +goog.addDependency("editor/style.js", ['goog.editor.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.object', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("editor/style_test.js", ['goog.editor.styleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.style', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.style', 'goog.testing.LooseMock', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("editor/table.js", ['goog.editor.Table', 'goog.editor.TableCell', 'goog.editor.TableRow'], ['goog.asserts', 'goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.log', 'goog.string.Unicode', 'goog.style']);
                +goog.addDependency("editor/table_test.js", ['goog.editor.TableTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Table', 'goog.testing.jsunit']);
                +goog.addDependency("events/actioneventwrapper.js", ['goog.events.actionEventWrapper'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.EventWrapper', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/actioneventwrapper_test.js", ['goog.events.actionEventWrapperTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.events', 'goog.events.EventHandler', 'goog.events.KeyCodes', 'goog.events.actionEventWrapper', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("events/actionhandler.js", ['goog.events.ActionEvent', 'goog.events.ActionHandler', 'goog.events.ActionHandler.EventType', 'goog.events.BeforeActionEvent'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/actionhandler_test.js", ['goog.events.ActionHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.ActionHandler', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("events/browserevent.js", ['goog.events.BrowserEvent', 'goog.events.BrowserEvent.MouseButton'], ['goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventType', 'goog.reflect', 'goog.userAgent']);
                +goog.addDependency("events/browserevent_test.js", ['goog.events.BrowserEventTest'], ['goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.math.Coordinate', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/browserfeature.js", ['goog.events.BrowserFeature'], ['goog.userAgent']);
                +goog.addDependency("events/event.js", ['goog.events.Event', 'goog.events.EventLike'], ['goog.Disposable', 'goog.events.EventId']);
                +goog.addDependency("events/event_test.js", ['goog.events.EventTest'], ['goog.events.Event', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventhandler.js", ['goog.events.EventHandler'], ['goog.Disposable', 'goog.events', 'goog.object']);
                +goog.addDependency("events/eventhandler_test.js", ['goog.events.EventHandlerTest'], ['goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventid.js", ['goog.events.EventId'], []);
                +goog.addDependency("events/events.js", ['goog.events', 'goog.events.CaptureSimulationMode', 'goog.events.Key', 'goog.events.ListenableType'], ['goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.Listenable', 'goog.events.ListenerMap']);
                +goog.addDependency("events/events_test.js", ['goog.eventsTest'], ['goog.asserts.AssertionError', 'goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserFeature', 'goog.events.CaptureSimulationMode', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.Listener', 'goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventtarget.js", ['goog.events.EventTarget'], ['goog.Disposable', 'goog.asserts', 'goog.events', 'goog.events.Event', 'goog.events.Listenable', 'goog.events.ListenerMap', 'goog.object']);
                +goog.addDependency("events/eventtarget_test.js", ['goog.events.EventTargetTest'], ['goog.events.EventTarget', 'goog.events.Listenable', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtarget_via_googevents_test.js", ['goog.events.EventTargetGoogEventsTest'], ['goog.events', 'goog.events.EventTarget', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtarget_via_w3cinterface_test.js", ['goog.events.EventTargetW3CTest'], ['goog.events.EventTarget', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.testing.jsunit']);
                +goog.addDependency("events/eventtargettester.js", ['goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType'], ['goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.testing.asserts', 'goog.testing.recordFunction']);
                +goog.addDependency("events/eventtype.js", ['goog.events.EventType'], ['goog.userAgent']);
                +goog.addDependency("events/eventwrapper.js", ['goog.events.EventWrapper'], []);
                +goog.addDependency("events/filedrophandler.js", ['goog.events.FileDropHandler', 'goog.events.FileDropHandler.EventType'], ['goog.array', 'goog.dom', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.log', 'goog.log.Level']);
                +goog.addDependency("events/filedrophandler_test.js", ['goog.events.FileDropHandlerTest'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.FileDropHandler', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/focushandler.js", ['goog.events.FocusHandler', 'goog.events.FocusHandler.EventType'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.userAgent']);
                +goog.addDependency("events/imehandler.js", ['goog.events.ImeHandler', 'goog.events.ImeHandler.Event', 'goog.events.ImeHandler.EventType'], ['goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/imehandler_test.js", ['goog.events.ImeHandlerTest'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.ImeHandler', 'goog.events.KeyCodes', 'goog.object', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/inputhandler.js", ['goog.events.InputHandler', 'goog.events.InputHandler.EventType'], ['goog.Timer', 'goog.dom.TagName', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/inputhandler_test.js", ['goog.events.InputHandlerTest'], ['goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("events/keycodes.js", ['goog.events.KeyCodes'], ['goog.userAgent']);
                +goog.addDependency("events/keycodes_test.js", ['goog.events.KeyCodesTest'], ['goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/keyhandler.js", ['goog.events.KeyEvent', 'goog.events.KeyHandler', 'goog.events.KeyHandler.EventType'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.userAgent']);
                +goog.addDependency("events/keyhandler_test.js", ['goog.events.KeyEventTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/keynames.js", ['goog.events.KeyNames'], []);
                +goog.addDependency("events/keys.js", ['goog.events.Keys'], []);
                +goog.addDependency("events/listenable.js", ['goog.events.Listenable', 'goog.events.ListenableKey'], ['goog.events.EventId']);
                +goog.addDependency("events/listenable_test.js", ['goog.events.ListenableTest'], ['goog.events.Listenable', 'goog.testing.jsunit']);
                +goog.addDependency("events/listener.js", ['goog.events.Listener'], ['goog.events.ListenableKey']);
                +goog.addDependency("events/listenermap.js", ['goog.events.ListenerMap'], ['goog.array', 'goog.events.Listener', 'goog.object']);
                +goog.addDependency("events/listenermap_test.js", ['goog.events.ListenerMapTest'], ['goog.dispose', 'goog.events', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.events.ListenerMap', 'goog.testing.jsunit']);
                +goog.addDependency("events/mousewheelhandler.js", ['goog.events.MouseWheelEvent', 'goog.events.MouseWheelHandler', 'goog.events.MouseWheelHandler.EventType'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.math', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("events/mousewheelhandler_test.js", ['goog.events.MouseWheelHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.MouseWheelEvent', 'goog.events.MouseWheelHandler', 'goog.functions', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/onlinehandler.js", ['goog.events.OnlineHandler', 'goog.events.OnlineHandler.EventType'], ['goog.Timer', 'goog.events.BrowserFeature', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.net.NetworkStatusMonitor']);
                +goog.addDependency("events/onlinelistener_test.js", ['goog.events.OnlineHandlerTest'], ['goog.events', 'goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.OnlineHandler', 'goog.net.NetworkStatusMonitor', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("events/pastehandler.js", ['goog.events.PasteHandler', 'goog.events.PasteHandler.EventType', 'goog.events.PasteHandler.State'], ['goog.Timer', 'goog.async.ConditionalDelay', 'goog.events.BrowserEvent', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.log', 'goog.userAgent']);
                +goog.addDependency("events/pastehandler_test.js", ['goog.events.PasteHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.PasteHandler', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("events/wheelevent.js", ['goog.events.WheelEvent'], ['goog.asserts', 'goog.events.BrowserEvent']);
                +goog.addDependency("events/wheelhandler.js", ['goog.events.WheelHandler'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.WheelEvent', 'goog.style', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("events/wheelhandler_test.js", ['goog.events.WheelHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.WheelEvent', 'goog.events.WheelHandler', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("format/emailaddress.js", ['goog.format.EmailAddress'], ['goog.string']);
                +goog.addDependency("format/emailaddress_test.js", ['goog.format.EmailAddressTest'], ['goog.array', 'goog.format.EmailAddress', 'goog.testing.jsunit']);
                +goog.addDependency("format/format.js", ['goog.format'], ['goog.i18n.GraphemeBreak', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("format/format_test.js", ['goog.formatTest'], ['goog.dom', 'goog.dom.TagName', 'goog.format', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("format/htmlprettyprinter.js", ['goog.format.HtmlPrettyPrinter', 'goog.format.HtmlPrettyPrinter.Buffer'], ['goog.dom.TagName', 'goog.object', 'goog.string.StringBuffer']);
                +goog.addDependency("format/htmlprettyprinter_test.js", ['goog.format.HtmlPrettyPrinterTest'], ['goog.format.HtmlPrettyPrinter', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("format/internationalizedemailaddress.js", ['goog.format.InternationalizedEmailAddress'], ['goog.format.EmailAddress', 'goog.string']);
                +goog.addDependency("format/internationalizedemailaddress_test.js", ['goog.format.InternationalizedEmailAddressTest'], ['goog.array', 'goog.format.InternationalizedEmailAddress', 'goog.testing.jsunit']);
                +goog.addDependency("format/jsonprettyprinter.js", ['goog.format.JsonPrettyPrinter', 'goog.format.JsonPrettyPrinter.SafeHtmlDelimiters', 'goog.format.JsonPrettyPrinter.TextDelimiters'], ['goog.html.SafeHtml', 'goog.json', 'goog.json.Serializer', 'goog.string', 'goog.string.format']);
                +goog.addDependency("format/jsonprettyprinter_test.js", ['goog.format.JsonPrettyPrinterTest'], ['goog.format.JsonPrettyPrinter', 'goog.testing.jsunit']);
                +goog.addDependency("fs/entry.js", ['goog.fs.DirectoryEntry', 'goog.fs.DirectoryEntry.Behavior', 'goog.fs.Entry', 'goog.fs.FileEntry'], []);
                +goog.addDependency("fs/entryimpl.js", ['goog.fs.DirectoryEntryImpl', 'goog.fs.EntryImpl', 'goog.fs.FileEntryImpl'], ['goog.array', 'goog.async.Deferred', 'goog.fs.DirectoryEntry', 'goog.fs.Entry', 'goog.fs.Error', 'goog.fs.FileEntry', 'goog.fs.FileWriter', 'goog.functions', 'goog.string']);
                +goog.addDependency("fs/error.js", ['goog.fs.DOMErrorLike', 'goog.fs.Error', 'goog.fs.Error.ErrorCode'], ['goog.asserts', 'goog.debug.Error', 'goog.object', 'goog.string']);
                +goog.addDependency("fs/filereader.js", ['goog.fs.FileReader', 'goog.fs.FileReader.EventType', 'goog.fs.FileReader.ReadyState'], ['goog.async.Deferred', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.ProgressEvent']);
                +goog.addDependency("fs/filesaver.js", ['goog.fs.FileSaver', 'goog.fs.FileSaver.EventType', 'goog.fs.FileSaver.ReadyState'], ['goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.ProgressEvent']);
                +goog.addDependency("fs/filesystem.js", ['goog.fs.FileSystem'], []);
                +goog.addDependency("fs/filesystemimpl.js", ['goog.fs.FileSystemImpl'], ['goog.fs.DirectoryEntryImpl', 'goog.fs.FileSystem']);
                +goog.addDependency("fs/filewriter.js", ['goog.fs.FileWriter'], ['goog.fs.Error', 'goog.fs.FileSaver']);
                +goog.addDependency("fs/fs.js", ['goog.fs'], ['goog.array', 'goog.async.Deferred', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.fs.FileSystemImpl', 'goog.fs.url', 'goog.userAgent']);
                +goog.addDependency("fs/fs_test.js", ['goog.fsTest'], ['goog.Promise', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.fs.FileSaver', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("fs/progressevent.js", ['goog.fs.ProgressEvent'], ['goog.events.Event']);
                +goog.addDependency("fs/url.js", ['goog.fs.url'], []);
                +goog.addDependency("fs/url_test.js", ['goog.urlTest'], ['goog.fs.url', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("functions/functions.js", ['goog.functions'], []);
                +goog.addDependency("functions/functions_test.js", ['goog.functionsTest'], ['goog.array', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("fx/abstractdragdrop.js", ['goog.fx.AbstractDragDrop', 'goog.fx.AbstractDragDrop.EventType', 'goog.fx.DragDropEvent', 'goog.fx.DragDropItem'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style']);
                +goog.addDependency("fx/abstractdragdrop_test.js", ['goog.fx.AbstractDragDropTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.functions', 'goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit']);
                +goog.addDependency("fx/anim/anim.js", ['goog.fx.anim', 'goog.fx.anim.Animated'], ['goog.async.AnimationDelay', 'goog.async.Delay', 'goog.object']);
                +goog.addDependency("fx/anim/anim_test.js", ['goog.fx.animTest'], ['goog.async.AnimationDelay', 'goog.async.Delay', 'goog.events', 'goog.functions', 'goog.fx.Animation', 'goog.fx.anim', 'goog.object', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("fx/animation.js", ['goog.fx.Animation', 'goog.fx.Animation.EventType', 'goog.fx.Animation.State', 'goog.fx.AnimationEvent'], ['goog.array', 'goog.asserts', 'goog.events.Event', 'goog.fx.Transition', 'goog.fx.TransitionBase', 'goog.fx.anim', 'goog.fx.anim.Animated']);
                +goog.addDependency("fx/animation_test.js", ['goog.fx.AnimationTest'], ['goog.events', 'goog.fx.Animation', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/animationqueue.js", ['goog.fx.AnimationParallelQueue', 'goog.fx.AnimationQueue', 'goog.fx.AnimationSerialQueue'], ['goog.array', 'goog.asserts', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.TransitionBase']);
                +goog.addDependency("fx/animationqueue_test.js", ['goog.fx.AnimationQueueTest'], ['goog.events', 'goog.fx.Animation', 'goog.fx.AnimationParallelQueue', 'goog.fx.AnimationSerialQueue', 'goog.fx.Transition', 'goog.fx.anim', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/css3/fx.js", ['goog.fx.css3'], ['goog.fx.css3.Transition']);
                +goog.addDependency("fx/css3/transition.js", ['goog.fx.css3.Transition'], ['goog.Timer', 'goog.asserts', 'goog.fx.TransitionBase', 'goog.style', 'goog.style.transition']);
                +goog.addDependency("fx/css3/transition_test.js", ['goog.fx.css3.TransitionTest'], ['goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fx.Transition', 'goog.fx.css3.Transition', 'goog.style.transition', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("fx/cssspriteanimation.js", ['goog.fx.CssSpriteAnimation'], ['goog.fx.Animation']);
                +goog.addDependency("fx/cssspriteanimation_test.js", ['goog.fx.CssSpriteAnimationTest'], ['goog.fx.CssSpriteAnimation', 'goog.math.Box', 'goog.math.Size', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dom.js", ['goog.fx.dom', 'goog.fx.dom.BgColorTransform', 'goog.fx.dom.ColorTransform', 'goog.fx.dom.Fade', 'goog.fx.dom.FadeIn', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOut', 'goog.fx.dom.FadeOutAndHide', 'goog.fx.dom.PredefinedEffect', 'goog.fx.dom.Resize', 'goog.fx.dom.ResizeHeight', 'goog.fx.dom.ResizeWidth', 'goog.fx.dom.Scroll', 'goog.fx.dom.Slide', 'goog.fx.dom.SlideFrom', 'goog.fx.dom.Swipe'], ['goog.color', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.style', 'goog.style.bidi']);
                +goog.addDependency("fx/dragdrop.js", ['goog.fx.DragDrop'], ['goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem']);
                +goog.addDependency("fx/dragdropgroup.js", ['goog.fx.DragDropGroup'], ['goog.dom', 'goog.fx.AbstractDragDrop', 'goog.fx.DragDropItem']);
                +goog.addDependency("fx/dragdropgroup_test.js", ['goog.fx.DragDropGroupTest'], ['goog.events', 'goog.fx.DragDropGroup', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dragger.js", ['goog.fx.DragEvent', 'goog.fx.Dragger', 'goog.fx.Dragger.EventType'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.style', 'goog.style.bidi', 'goog.userAgent']);
                +goog.addDependency("fx/dragger_test.js", ['goog.fx.DraggerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Rect', 'goog.style.bidi', 'goog.testing.StrictMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("fx/draglistgroup.js", ['goog.fx.DragListDirection', 'goog.fx.DragListGroup', 'goog.fx.DragListGroup.EventType', 'goog.fx.DragListGroupEvent'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Coordinate', 'goog.string', 'goog.style']);
                +goog.addDependency("fx/draglistgroup_test.js", ['goog.fx.DragListGroupTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.Event', 'goog.events.EventType', 'goog.fx.DragEvent', 'goog.fx.DragListDirection', 'goog.fx.DragListGroup', 'goog.fx.Dragger', 'goog.math.Coordinate', 'goog.object', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("fx/dragscrollsupport.js", ['goog.fx.DragScrollSupport'], ['goog.Disposable', 'goog.Timer', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.style']);
                +goog.addDependency("fx/dragscrollsupport_test.js", ['goog.fx.DragScrollSupportTest'], ['goog.fx.DragScrollSupport', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit']);
                +goog.addDependency("fx/easing.js", ['goog.fx.easing'], []);
                +goog.addDependency("fx/easing_test.js", ['goog.fx.easingTest'], ['goog.fx.easing', 'goog.testing.jsunit']);
                +goog.addDependency("fx/fx.js", ['goog.fx'], ['goog.asserts', 'goog.fx.Animation', 'goog.fx.Animation.EventType', 'goog.fx.Animation.State', 'goog.fx.AnimationEvent', 'goog.fx.Transition.EventType', 'goog.fx.easing']);
                +goog.addDependency("fx/fx_test.js", ['goog.fxTest'], ['goog.fx.Animation', 'goog.object', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("fx/transition.js", ['goog.fx.Transition', 'goog.fx.Transition.EventType'], []);
                +goog.addDependency("fx/transitionbase.js", ['goog.fx.TransitionBase', 'goog.fx.TransitionBase.State'], ['goog.events.EventTarget', 'goog.fx.Transition']);
                +goog.addDependency("graphics/abstractgraphics.js", ['goog.graphics.AbstractGraphics'], ['goog.dom', 'goog.graphics.AffineTransform', 'goog.graphics.Element', 'goog.graphics.EllipseElement', 'goog.graphics.Fill', 'goog.graphics.Font', 'goog.graphics.GroupElement', 'goog.graphics.Path', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.Stroke', 'goog.graphics.StrokeAndFillElement', 'goog.graphics.TextElement', 'goog.math.Coordinate', 'goog.math.Size', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("graphics/affinetransform.js", ['goog.graphics.AffineTransform'], []);
                +goog.addDependency("graphics/affinetransform_test.js", ['goog.graphics.AffineTransformTest'], ['goog.graphics', 'goog.graphics.AffineTransform', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/canvaselement.js", ['goog.graphics.CanvasEllipseElement', 'goog.graphics.CanvasGroupElement', 'goog.graphics.CanvasImageElement', 'goog.graphics.CanvasPathElement', 'goog.graphics.CanvasRectElement', 'goog.graphics.CanvasTextElement'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.graphics.EllipseElement', 'goog.graphics.Font', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.Path', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement', 'goog.html.SafeHtml', 'goog.html.uncheckedconversions', 'goog.math', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("graphics/canvasgraphics.js", ['goog.graphics.CanvasGraphics'], ['goog.dom.TagName', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.CanvasEllipseElement', 'goog.graphics.CanvasGroupElement', 'goog.graphics.CanvasImageElement', 'goog.graphics.CanvasPathElement', 'goog.graphics.CanvasRectElement', 'goog.graphics.CanvasTextElement', 'goog.graphics.Font', 'goog.graphics.SolidFill', 'goog.math.Size', 'goog.style']);
                +goog.addDependency("graphics/canvasgraphics_test.js", ['goog.graphics.CanvasGraphicsTest'], ['goog.dom', 'goog.graphics.CanvasGraphics', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/element.js", ['goog.graphics.Element'], ['goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.events.Listenable', 'goog.graphics.AffineTransform', 'goog.math']);
                +goog.addDependency("graphics/ellipseelement.js", ['goog.graphics.EllipseElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/coordinates.js", ['goog.graphics.ext.coordinates'], ['goog.string']);
                +goog.addDependency("graphics/ext/coordinates_test.js", ['goog.graphics.ext.coordinatesTest'], ['goog.graphics', 'goog.graphics.ext.coordinates', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/element.js", ['goog.graphics.ext.Element'], ['goog.events.EventTarget', 'goog.functions', 'goog.graphics.ext.coordinates']);
                +goog.addDependency("graphics/ext/element_test.js", ['goog.graphics.ext.ElementTest'], ['goog.graphics', 'goog.graphics.ext', 'goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/ellipse.js", ['goog.graphics.ext.Ellipse'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/ext.js", ['goog.graphics.ext'], ['goog.graphics.ext.Ellipse', 'goog.graphics.ext.Graphics', 'goog.graphics.ext.Group', 'goog.graphics.ext.Image', 'goog.graphics.ext.Rectangle', 'goog.graphics.ext.Shape', 'goog.graphics.ext.coordinates']);
                +goog.addDependency("graphics/ext/graphics.js", ['goog.graphics.ext.Graphics'], ['goog.events', 'goog.events.EventType', 'goog.graphics', 'goog.graphics.ext.Group']);
                +goog.addDependency("graphics/ext/group.js", ['goog.graphics.ext.Group'], ['goog.array', 'goog.graphics.ext.Element']);
                +goog.addDependency("graphics/ext/image.js", ['goog.graphics.ext.Image'], ['goog.graphics.ext.Element']);
                +goog.addDependency("graphics/ext/path.js", ['goog.graphics.ext.Path'], ['goog.graphics.AffineTransform', 'goog.graphics.Path', 'goog.math.Rect']);
                +goog.addDependency("graphics/ext/path_test.js", ['goog.graphics.ext.PathTest'], ['goog.graphics', 'goog.graphics.ext.Path', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/ext/rectangle.js", ['goog.graphics.ext.Rectangle'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/shape.js", ['goog.graphics.ext.Shape'], ['goog.graphics.ext.StrokeAndFillElement']);
                +goog.addDependency("graphics/ext/strokeandfillelement.js", ['goog.graphics.ext.StrokeAndFillElement'], ['goog.graphics.ext.Element']);
                +goog.addDependency("graphics/fill.js", ['goog.graphics.Fill'], []);
                +goog.addDependency("graphics/font.js", ['goog.graphics.Font'], []);
                +goog.addDependency("graphics/graphics.js", ['goog.graphics'], ['goog.dom', 'goog.graphics.CanvasGraphics', 'goog.graphics.SvgGraphics', 'goog.graphics.VmlGraphics', 'goog.userAgent']);
                +goog.addDependency("graphics/groupelement.js", ['goog.graphics.GroupElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/imageelement.js", ['goog.graphics.ImageElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/lineargradient.js", ['goog.graphics.LinearGradient'], ['goog.asserts', 'goog.graphics.Fill']);
                +goog.addDependency("graphics/path.js", ['goog.graphics.Path', 'goog.graphics.Path.Segment'], ['goog.array', 'goog.graphics.AffineTransform', 'goog.math']);
                +goog.addDependency("graphics/path_test.js", ['goog.graphics.PathTest'], ['goog.array', 'goog.math', 'goog.graphics.Path', 'goog.graphics.AffineTransform', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/pathelement.js", ['goog.graphics.PathElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/paths.js", ['goog.graphics.paths'], ['goog.graphics.Path', 'goog.math.Coordinate']);
                +goog.addDependency("graphics/paths_test.js", ['goog.graphics.pathsTest'], ['goog.dom', 'goog.graphics', 'goog.graphics.paths', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/rectelement.js", ['goog.graphics.RectElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/solidfill.js", ['goog.graphics.SolidFill'], ['goog.graphics.Fill']);
                +goog.addDependency("graphics/solidfill_test.js", ['goog.graphics.SolidFillTest'], ['goog.graphics.SolidFill', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/stroke.js", ['goog.graphics.Stroke'], []);
                +goog.addDependency("graphics/strokeandfillelement.js", ['goog.graphics.StrokeAndFillElement'], ['goog.graphics.Element']);
                +goog.addDependency("graphics/svgelement.js", ['goog.graphics.SvgEllipseElement', 'goog.graphics.SvgGroupElement', 'goog.graphics.SvgImageElement', 'goog.graphics.SvgPathElement', 'goog.graphics.SvgRectElement', 'goog.graphics.SvgTextElement'], ['goog.dom', 'goog.graphics.EllipseElement', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement']);
                +goog.addDependency("graphics/svggraphics.js", ['goog.graphics.SvgGraphics'], ['goog.Timer', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.Font', 'goog.graphics.LinearGradient', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.graphics.SvgEllipseElement', 'goog.graphics.SvgGroupElement', 'goog.graphics.SvgImageElement', 'goog.graphics.SvgPathElement', 'goog.graphics.SvgRectElement', 'goog.graphics.SvgTextElement', 'goog.math', 'goog.math.Size', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("graphics/svggraphics_test.js", ['goog.graphics.SvgGraphicsTest'], ['goog.dom', 'goog.graphics.SvgGraphics', 'goog.testing.graphics', 'goog.testing.jsunit']);
                +goog.addDependency("graphics/textelement.js", ['goog.graphics.TextElement'], ['goog.graphics.StrokeAndFillElement']);
                +goog.addDependency("graphics/vmlelement.js", ['goog.graphics.VmlEllipseElement', 'goog.graphics.VmlGroupElement', 'goog.graphics.VmlImageElement', 'goog.graphics.VmlPathElement', 'goog.graphics.VmlRectElement', 'goog.graphics.VmlTextElement'], ['goog.dom', 'goog.graphics.EllipseElement', 'goog.graphics.GroupElement', 'goog.graphics.ImageElement', 'goog.graphics.PathElement', 'goog.graphics.RectElement', 'goog.graphics.TextElement']);
                +goog.addDependency("graphics/vmlgraphics.js", ['goog.graphics.VmlGraphics'], ['goog.array', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.graphics.AbstractGraphics', 'goog.graphics.Font', 'goog.graphics.LinearGradient', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.VmlEllipseElement', 'goog.graphics.VmlGroupElement', 'goog.graphics.VmlImageElement', 'goog.graphics.VmlPathElement', 'goog.graphics.VmlRectElement', 'goog.graphics.VmlTextElement', 'goog.html.uncheckedconversions', 'goog.math', 'goog.math.Size', 'goog.reflect', 'goog.string', 'goog.string.Const', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("history/event.js", ['goog.history.Event'], ['goog.events.Event', 'goog.history.EventType']);
                +goog.addDependency("history/eventtype.js", ['goog.history.EventType'], []);
                +goog.addDependency("history/history.js", ['goog.History', 'goog.History.Event', 'goog.History.EventType'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.safe', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.history.Event', 'goog.history.EventType', 'goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.labs.userAgent.device', 'goog.memoize', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("history/history_test.js", ['goog.HistoryTest'], ['goog.History', 'goog.dispose', 'goog.dom', 'goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("history/html5history.js", ['goog.history.Html5History', 'goog.history.Html5History.TokenTransformer'], ['goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.history.Event']);
                +goog.addDependency("history/html5history_test.js", ['goog.history.Html5HistoryTest'], ['goog.Timer', 'goog.events', 'goog.events.EventType', 'goog.history.EventType', 'goog.history.Html5History', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.recordFunction']);
                +goog.addDependency("html/flash.js", ['goog.html.flash'], ['goog.asserts', 'goog.html.SafeHtml']);
                +goog.addDependency("html/flash_test.js", ['goog.html.flashTest'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/legacyconversions.js", ['goog.html.legacyconversions'], ['goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("html/legacyconversions_test.js", ['goog.html.legacyconversionsTest'], ['goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.legacyconversions', 'goog.testing.jsunit']);
                +goog.addDependency("html/safehtml.js", ['goog.html.SafeHtml'], ['goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.tags', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.labs.userAgent.browser', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safehtml_test.js", ['goog.html.safeHtmlTest'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.testing', 'goog.i18n.bidi.Dir', 'goog.labs.userAgent.browser', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safehtmlformatter.js", ['goog.html.SafeHtmlFormatter'], ['goog.asserts', 'goog.dom.tags', 'goog.html.SafeHtml', 'goog.string']);
                +goog.addDependency("html/safehtmlformatter_test.js", ['goog.html.safeHtmlFormatterTest'], ['goog.html.SafeHtml', 'goog.html.SafeHtmlFormatter', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("html/safescript.js", ['goog.html.SafeScript'], ['goog.asserts', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safescript_test.js", ['goog.html.safeScriptTest'], ['goog.html.SafeScript', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safestyle.js", ['goog.html.SafeStyle'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safestyle_test.js", ['goog.html.safeStyleTest'], ['goog.html.SafeStyle', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safestylesheet.js", ['goog.html.SafeStyleSheet'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safestylesheet_test.js", ['goog.html.safeStyleSheetTest'], ['goog.html.SafeStyleSheet', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/safeurl.js", ['goog.html.SafeUrl'], ['goog.asserts', 'goog.fs.url', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.string', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/safeurl_test.js", ['goog.html.safeUrlTest'], ['goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/attributewhitelist.js", ['goog.html.sanitizer.AttributeSanitizedWhitelist', 'goog.html.sanitizer.AttributeWhitelist'], []);
                +goog.addDependency("html/sanitizer/csssanitizer.js", ['goog.html.sanitizer.CssSanitizer'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.SafeStyle', 'goog.html.uncheckedconversions', 'goog.object', 'goog.string']);
                +goog.addDependency("html/sanitizer/csssanitizer_test.js", [], ['goog.array', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.sanitizer.CssSanitizer', 'goog.string', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("html/sanitizer/htmlsanitizer.js", ['goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.html.sanitizer.HtmlSanitizerPolicy', 'goog.html.sanitizer.HtmlSanitizerPolicyContext', 'goog.html.sanitizer.HtmlSanitizerPolicyHints'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.functions', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.sanitizer.AttributeSanitizedWhitelist', 'goog.html.sanitizer.AttributeWhitelist', 'goog.html.sanitizer.CssSanitizer', 'goog.html.sanitizer.TagBlacklist', 'goog.html.sanitizer.TagWhitelist', 'goog.html.uncheckedconversions', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/htmlsanitizer_test.js", [], ['goog.array', 'goog.dom', 'goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.html.sanitizer.TagWhitelist', 'goog.html.sanitizer.unsafe', 'goog.html.testing', 'goog.object', 'goog.string.Const', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/sanitizer/tagblacklist.js", ['goog.html.sanitizer.TagBlacklist'], []);
                +goog.addDependency("html/sanitizer/tagwhitelist.js", ['goog.html.sanitizer.TagWhitelist'], []);
                +goog.addDependency("html/sanitizer/unsafe.js", ['goog.html.sanitizer.unsafe'], ['goog.asserts', 'goog.html.sanitizer.HtmlSanitizer.Builder', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("html/sanitizer/unsafe_test.js", [], ['goog.html.SafeHtml', 'goog.html.sanitizer.HtmlSanitizer', 'goog.html.sanitizer.TagBlacklist', 'goog.html.sanitizer.unsafe', 'goog.string.Const', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("html/silverlight.js", ['goog.html.silverlight'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.string.Const']);
                +goog.addDependency("html/silverlight_test.js", ['goog.html.silverlightTest'], ['goog.html.SafeHtml', 'goog.html.TrustedResourceUrl', 'goog.html.silverlight', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/testing.js", ['goog.html.testing'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("html/trustedresourceurl.js", ['goog.html.TrustedResourceUrl'], ['goog.asserts', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.string.Const', 'goog.string.TypedString']);
                +goog.addDependency("html/trustedresourceurl_test.js", ['goog.html.trustedResourceUrlTest'], ['goog.html.TrustedResourceUrl', 'goog.i18n.bidi.Dir', 'goog.object', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/uncheckedconversions.js", ['goog.html.uncheckedconversions'], ['goog.asserts', 'goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.string', 'goog.string.Const']);
                +goog.addDependency("html/uncheckedconversions_test.js", ['goog.html.uncheckedconversionsTest'], ['goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeStyleSheet', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.uncheckedconversions', 'goog.i18n.bidi.Dir', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("html/utils.js", ['goog.html.utils'], ['goog.string']);
                +goog.addDependency("html/utils_test.js", ['goog.html.UtilsTest'], ['goog.array', 'goog.dom.TagName', 'goog.html.utils', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/bidi.js", ['goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.DirectionalString', 'goog.i18n.bidi.Format'], []);
                +goog.addDependency("i18n/bidi_test.js", ['goog.i18n.bidiTest'], ['goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/bidiformatter.js", ['goog.i18n.BidiFormatter'], ['goog.html.SafeHtml', 'goog.i18n.bidi', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.Format']);
                +goog.addDependency("i18n/bidiformatter_test.js", ['goog.i18n.BidiFormatterTest'], ['goog.html.SafeHtml', 'goog.html.testing', 'goog.i18n.BidiFormatter', 'goog.i18n.bidi.Dir', 'goog.i18n.bidi.Format', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/charlistdecompressor.js", ['goog.i18n.CharListDecompressor'], ['goog.array', 'goog.i18n.uChar']);
                +goog.addDependency("i18n/charlistdecompressor_test.js", ['goog.i18n.CharListDecompressorTest'], ['goog.i18n.CharListDecompressor', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/charpickerdata.js", ['goog.i18n.CharPickerData'], []);
                +goog.addDependency("i18n/collation.js", ['goog.i18n.collation'], []);
                +goog.addDependency("i18n/collation_test.js", ['goog.i18n.collationTest'], ['goog.i18n.collation', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("i18n/compactnumberformatsymbols.js", ['goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.CompactNumberFormatSymbols_af', 'goog.i18n.CompactNumberFormatSymbols_am', 'goog.i18n.CompactNumberFormatSymbols_ar', 'goog.i18n.CompactNumberFormatSymbols_ar_DZ', 'goog.i18n.CompactNumberFormatSymbols_az', 'goog.i18n.CompactNumberFormatSymbols_be', 'goog.i18n.CompactNumberFormatSymbols_bg', 'goog.i18n.CompactNumberFormatSymbols_bn', 'goog.i18n.CompactNumberFormatSymbols_br', 'goog.i18n.CompactNumberFormatSymbols_bs', 'goog.i18n.CompactNumberFormatSymbols_ca', 'goog.i18n.CompactNumberFormatSymbols_chr', 'goog.i18n.CompactNumberFormatSymbols_cs', 'goog.i18n.CompactNumberFormatSymbols_cy', 'goog.i18n.CompactNumberFormatSymbols_da', 'goog.i18n.CompactNumberFormatSymbols_de', 'goog.i18n.CompactNumberFormatSymbols_de_AT', 'goog.i18n.CompactNumberFormatSymbols_de_CH', 'goog.i18n.CompactNumberFormatSymbols_el', 'goog.i18n.CompactNumberFormatSymbols_en', 'goog.i18n.CompactNumberFormatSymbols_en_AU', 'goog.i18n.CompactNumberFormatSymbols_en_CA', 'goog.i18n.CompactNumberFormatSymbols_en_GB', 'goog.i18n.CompactNumberFormatSymbols_en_IE', 'goog.i18n.CompactNumberFormatSymbols_en_IN', 'goog.i18n.CompactNumberFormatSymbols_en_SG', 'goog.i18n.CompactNumberFormatSymbols_en_US', 'goog.i18n.CompactNumberFormatSymbols_en_ZA', 'goog.i18n.CompactNumberFormatSymbols_es', 'goog.i18n.CompactNumberFormatSymbols_es_419', 'goog.i18n.CompactNumberFormatSymbols_es_ES', 'goog.i18n.CompactNumberFormatSymbols_es_MX', 'goog.i18n.CompactNumberFormatSymbols_es_US', 'goog.i18n.CompactNumberFormatSymbols_et', 'goog.i18n.CompactNumberFormatSymbols_eu', 'goog.i18n.CompactNumberFormatSymbols_fa', 'goog.i18n.CompactNumberFormatSymbols_fi', 'goog.i18n.CompactNumberFormatSymbols_fil', 'goog.i18n.CompactNumberFormatSymbols_fr', 'goog.i18n.CompactNumberFormatSymbols_fr_CA', 'goog.i18n.CompactNumberFormatSymbols_ga', 'goog.i18n.CompactNumberFormatSymbols_gl', 'goog.i18n.CompactNumberFormatSymbols_gsw', 'goog.i18n.CompactNumberFormatSymbols_gu', 'goog.i18n.CompactNumberFormatSymbols_haw', 'goog.i18n.CompactNumberFormatSymbols_he', 'goog.i18n.CompactNumberFormatSymbols_hi', 'goog.i18n.CompactNumberFormatSymbols_hr', 'goog.i18n.CompactNumberFormatSymbols_hu', 'goog.i18n.CompactNumberFormatSymbols_hy', 'goog.i18n.CompactNumberFormatSymbols_id', 'goog.i18n.CompactNumberFormatSymbols_in', 'goog.i18n.CompactNumberFormatSymbols_is', 'goog.i18n.CompactNumberFormatSymbols_it', 'goog.i18n.CompactNumberFormatSymbols_iw', 'goog.i18n.CompactNumberFormatSymbols_ja', 'goog.i18n.CompactNumberFormatSymbols_ka', 'goog.i18n.CompactNumberFormatSymbols_kk', 'goog.i18n.CompactNumberFormatSymbols_km', 'goog.i18n.CompactNumberFormatSymbols_kn', 'goog.i18n.CompactNumberFormatSymbols_ko', 'goog.i18n.CompactNumberFormatSymbols_ky', 'goog.i18n.CompactNumberFormatSymbols_ln', 'goog.i18n.CompactNumberFormatSymbols_lo', 'goog.i18n.CompactNumberFormatSymbols_lt', 'goog.i18n.CompactNumberFormatSymbols_lv', 'goog.i18n.CompactNumberFormatSymbols_mk', 'goog.i18n.CompactNumberFormatSymbols_ml', 'goog.i18n.CompactNumberFormatSymbols_mn', 'goog.i18n.CompactNumberFormatSymbols_mo', 'goog.i18n.CompactNumberFormatSymbols_mr', 'goog.i18n.CompactNumberFormatSymbols_ms', 'goog.i18n.CompactNumberFormatSymbols_mt', 'goog.i18n.CompactNumberFormatSymbols_my', 'goog.i18n.CompactNumberFormatSymbols_nb', 'goog.i18n.CompactNumberFormatSymbols_ne', 'goog.i18n.CompactNumberFormatSymbols_nl', 'goog.i18n.CompactNumberFormatSymbols_no', 'goog.i18n.CompactNumberFormatSymbols_no_NO', 'goog.i18n.CompactNumberFormatSymbols_or', 'goog.i18n.CompactNumberFormatSymbols_pa', 'goog.i18n.CompactNumberFormatSymbols_pl', 'goog.i18n.CompactNumberFormatSymbols_pt', 'goog.i18n.CompactNumberFormatSymbols_pt_BR', 'goog.i18n.CompactNumberFormatSymbols_pt_PT', 'goog.i18n.CompactNumberFormatSymbols_ro', 'goog.i18n.CompactNumberFormatSymbols_ru', 'goog.i18n.CompactNumberFormatSymbols_sh', 'goog.i18n.CompactNumberFormatSymbols_si', 'goog.i18n.CompactNumberFormatSymbols_sk', 'goog.i18n.CompactNumberFormatSymbols_sl', 'goog.i18n.CompactNumberFormatSymbols_sq', 'goog.i18n.CompactNumberFormatSymbols_sr', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn', 'goog.i18n.CompactNumberFormatSymbols_sv', 'goog.i18n.CompactNumberFormatSymbols_sw', 'goog.i18n.CompactNumberFormatSymbols_ta', 'goog.i18n.CompactNumberFormatSymbols_te', 'goog.i18n.CompactNumberFormatSymbols_th', 'goog.i18n.CompactNumberFormatSymbols_tl', 'goog.i18n.CompactNumberFormatSymbols_tr', 'goog.i18n.CompactNumberFormatSymbols_uk', 'goog.i18n.CompactNumberFormatSymbols_ur', 'goog.i18n.CompactNumberFormatSymbols_uz', 'goog.i18n.CompactNumberFormatSymbols_vi', 'goog.i18n.CompactNumberFormatSymbols_zh', 'goog.i18n.CompactNumberFormatSymbols_zh_CN', 'goog.i18n.CompactNumberFormatSymbols_zh_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_TW', 'goog.i18n.CompactNumberFormatSymbols_zu'], []);
                +goog.addDependency("i18n/compactnumberformatsymbolsext.js", ['goog.i18n.CompactNumberFormatSymbolsExt', 'goog.i18n.CompactNumberFormatSymbols_af_NA', 'goog.i18n.CompactNumberFormatSymbols_af_ZA', 'goog.i18n.CompactNumberFormatSymbols_agq', 'goog.i18n.CompactNumberFormatSymbols_agq_CM', 'goog.i18n.CompactNumberFormatSymbols_ak', 'goog.i18n.CompactNumberFormatSymbols_ak_GH', 'goog.i18n.CompactNumberFormatSymbols_am_ET', 'goog.i18n.CompactNumberFormatSymbols_ar_001', 'goog.i18n.CompactNumberFormatSymbols_ar_AE', 'goog.i18n.CompactNumberFormatSymbols_ar_BH', 'goog.i18n.CompactNumberFormatSymbols_ar_DJ', 'goog.i18n.CompactNumberFormatSymbols_ar_EG', 'goog.i18n.CompactNumberFormatSymbols_ar_EH', 'goog.i18n.CompactNumberFormatSymbols_ar_ER', 'goog.i18n.CompactNumberFormatSymbols_ar_IL', 'goog.i18n.CompactNumberFormatSymbols_ar_IQ', 'goog.i18n.CompactNumberFormatSymbols_ar_JO', 'goog.i18n.CompactNumberFormatSymbols_ar_KM', 'goog.i18n.CompactNumberFormatSymbols_ar_KW', 'goog.i18n.CompactNumberFormatSymbols_ar_LB', 'goog.i18n.CompactNumberFormatSymbols_ar_LY', 'goog.i18n.CompactNumberFormatSymbols_ar_MA', 'goog.i18n.CompactNumberFormatSymbols_ar_MR', 'goog.i18n.CompactNumberFormatSymbols_ar_OM', 'goog.i18n.CompactNumberFormatSymbols_ar_PS', 'goog.i18n.CompactNumberFormatSymbols_ar_QA', 'goog.i18n.CompactNumberFormatSymbols_ar_SA', 'goog.i18n.CompactNumberFormatSymbols_ar_SD', 'goog.i18n.CompactNumberFormatSymbols_ar_SO', 'goog.i18n.CompactNumberFormatSymbols_ar_SS', 'goog.i18n.CompactNumberFormatSymbols_ar_SY', 'goog.i18n.CompactNumberFormatSymbols_ar_TD', 'goog.i18n.CompactNumberFormatSymbols_ar_TN', 'goog.i18n.CompactNumberFormatSymbols_ar_XB', 'goog.i18n.CompactNumberFormatSymbols_ar_YE', 'goog.i18n.CompactNumberFormatSymbols_as', 'goog.i18n.CompactNumberFormatSymbols_as_IN', 'goog.i18n.CompactNumberFormatSymbols_asa', 'goog.i18n.CompactNumberFormatSymbols_asa_TZ', 'goog.i18n.CompactNumberFormatSymbols_ast', 'goog.i18n.CompactNumberFormatSymbols_ast_ES', 'goog.i18n.CompactNumberFormatSymbols_az_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_az_Cyrl_AZ', 'goog.i18n.CompactNumberFormatSymbols_az_Latn', 'goog.i18n.CompactNumberFormatSymbols_az_Latn_AZ', 'goog.i18n.CompactNumberFormatSymbols_bas', 'goog.i18n.CompactNumberFormatSymbols_bas_CM', 'goog.i18n.CompactNumberFormatSymbols_be_BY', 'goog.i18n.CompactNumberFormatSymbols_bem', 'goog.i18n.CompactNumberFormatSymbols_bem_ZM', 'goog.i18n.CompactNumberFormatSymbols_bez', 'goog.i18n.CompactNumberFormatSymbols_bez_TZ', 'goog.i18n.CompactNumberFormatSymbols_bg_BG', 'goog.i18n.CompactNumberFormatSymbols_bm', 'goog.i18n.CompactNumberFormatSymbols_bm_ML', 'goog.i18n.CompactNumberFormatSymbols_bn_BD', 'goog.i18n.CompactNumberFormatSymbols_bn_IN', 'goog.i18n.CompactNumberFormatSymbols_bo', 'goog.i18n.CompactNumberFormatSymbols_bo_CN', 'goog.i18n.CompactNumberFormatSymbols_bo_IN', 'goog.i18n.CompactNumberFormatSymbols_br_FR', 'goog.i18n.CompactNumberFormatSymbols_brx', 'goog.i18n.CompactNumberFormatSymbols_brx_IN', 'goog.i18n.CompactNumberFormatSymbols_bs_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_bs_Cyrl_BA', 'goog.i18n.CompactNumberFormatSymbols_bs_Latn', 'goog.i18n.CompactNumberFormatSymbols_bs_Latn_BA', 'goog.i18n.CompactNumberFormatSymbols_ca_AD', 'goog.i18n.CompactNumberFormatSymbols_ca_ES', 'goog.i18n.CompactNumberFormatSymbols_ca_FR', 'goog.i18n.CompactNumberFormatSymbols_ca_IT', 'goog.i18n.CompactNumberFormatSymbols_ce', 'goog.i18n.CompactNumberFormatSymbols_ce_RU', 'goog.i18n.CompactNumberFormatSymbols_cgg', 'goog.i18n.CompactNumberFormatSymbols_cgg_UG', 'goog.i18n.CompactNumberFormatSymbols_chr_US', 'goog.i18n.CompactNumberFormatSymbols_ckb', 'goog.i18n.CompactNumberFormatSymbols_ckb_IQ', 'goog.i18n.CompactNumberFormatSymbols_ckb_IR', 'goog.i18n.CompactNumberFormatSymbols_cs_CZ', 'goog.i18n.CompactNumberFormatSymbols_cy_GB', 'goog.i18n.CompactNumberFormatSymbols_da_DK', 'goog.i18n.CompactNumberFormatSymbols_da_GL', 'goog.i18n.CompactNumberFormatSymbols_dav', 'goog.i18n.CompactNumberFormatSymbols_dav_KE', 'goog.i18n.CompactNumberFormatSymbols_de_BE', 'goog.i18n.CompactNumberFormatSymbols_de_DE', 'goog.i18n.CompactNumberFormatSymbols_de_IT', 'goog.i18n.CompactNumberFormatSymbols_de_LI', 'goog.i18n.CompactNumberFormatSymbols_de_LU', 'goog.i18n.CompactNumberFormatSymbols_dje', 'goog.i18n.CompactNumberFormatSymbols_dje_NE', 'goog.i18n.CompactNumberFormatSymbols_dsb', 'goog.i18n.CompactNumberFormatSymbols_dsb_DE', 'goog.i18n.CompactNumberFormatSymbols_dua', 'goog.i18n.CompactNumberFormatSymbols_dua_CM', 'goog.i18n.CompactNumberFormatSymbols_dyo', 'goog.i18n.CompactNumberFormatSymbols_dyo_SN', 'goog.i18n.CompactNumberFormatSymbols_dz', 'goog.i18n.CompactNumberFormatSymbols_dz_BT', 'goog.i18n.CompactNumberFormatSymbols_ebu', 'goog.i18n.CompactNumberFormatSymbols_ebu_KE', 'goog.i18n.CompactNumberFormatSymbols_ee', 'goog.i18n.CompactNumberFormatSymbols_ee_GH', 'goog.i18n.CompactNumberFormatSymbols_ee_TG', 'goog.i18n.CompactNumberFormatSymbols_el_CY', 'goog.i18n.CompactNumberFormatSymbols_el_GR', 'goog.i18n.CompactNumberFormatSymbols_en_001', 'goog.i18n.CompactNumberFormatSymbols_en_150', 'goog.i18n.CompactNumberFormatSymbols_en_AG', 'goog.i18n.CompactNumberFormatSymbols_en_AI', 'goog.i18n.CompactNumberFormatSymbols_en_AS', 'goog.i18n.CompactNumberFormatSymbols_en_AT', 'goog.i18n.CompactNumberFormatSymbols_en_BB', 'goog.i18n.CompactNumberFormatSymbols_en_BE', 'goog.i18n.CompactNumberFormatSymbols_en_BI', 'goog.i18n.CompactNumberFormatSymbols_en_BM', 'goog.i18n.CompactNumberFormatSymbols_en_BS', 'goog.i18n.CompactNumberFormatSymbols_en_BW', 'goog.i18n.CompactNumberFormatSymbols_en_BZ', 'goog.i18n.CompactNumberFormatSymbols_en_CC', 'goog.i18n.CompactNumberFormatSymbols_en_CH', 'goog.i18n.CompactNumberFormatSymbols_en_CK', 'goog.i18n.CompactNumberFormatSymbols_en_CM', 'goog.i18n.CompactNumberFormatSymbols_en_CX', 'goog.i18n.CompactNumberFormatSymbols_en_CY', 'goog.i18n.CompactNumberFormatSymbols_en_DE', 'goog.i18n.CompactNumberFormatSymbols_en_DG', 'goog.i18n.CompactNumberFormatSymbols_en_DK', 'goog.i18n.CompactNumberFormatSymbols_en_DM', 'goog.i18n.CompactNumberFormatSymbols_en_ER', 'goog.i18n.CompactNumberFormatSymbols_en_FI', 'goog.i18n.CompactNumberFormatSymbols_en_FJ', 'goog.i18n.CompactNumberFormatSymbols_en_FK', 'goog.i18n.CompactNumberFormatSymbols_en_FM', 'goog.i18n.CompactNumberFormatSymbols_en_GD', 'goog.i18n.CompactNumberFormatSymbols_en_GG', 'goog.i18n.CompactNumberFormatSymbols_en_GH', 'goog.i18n.CompactNumberFormatSymbols_en_GI', 'goog.i18n.CompactNumberFormatSymbols_en_GM', 'goog.i18n.CompactNumberFormatSymbols_en_GU', 'goog.i18n.CompactNumberFormatSymbols_en_GY', 'goog.i18n.CompactNumberFormatSymbols_en_HK', 'goog.i18n.CompactNumberFormatSymbols_en_IL', 'goog.i18n.CompactNumberFormatSymbols_en_IM', 'goog.i18n.CompactNumberFormatSymbols_en_IO', 'goog.i18n.CompactNumberFormatSymbols_en_JE', 'goog.i18n.CompactNumberFormatSymbols_en_JM', 'goog.i18n.CompactNumberFormatSymbols_en_KE', 'goog.i18n.CompactNumberFormatSymbols_en_KI', 'goog.i18n.CompactNumberFormatSymbols_en_KN', 'goog.i18n.CompactNumberFormatSymbols_en_KY', 'goog.i18n.CompactNumberFormatSymbols_en_LC', 'goog.i18n.CompactNumberFormatSymbols_en_LR', 'goog.i18n.CompactNumberFormatSymbols_en_LS', 'goog.i18n.CompactNumberFormatSymbols_en_MG', 'goog.i18n.CompactNumberFormatSymbols_en_MH', 'goog.i18n.CompactNumberFormatSymbols_en_MO', 'goog.i18n.CompactNumberFormatSymbols_en_MP', 'goog.i18n.CompactNumberFormatSymbols_en_MS', 'goog.i18n.CompactNumberFormatSymbols_en_MT', 'goog.i18n.CompactNumberFormatSymbols_en_MU', 'goog.i18n.CompactNumberFormatSymbols_en_MW', 'goog.i18n.CompactNumberFormatSymbols_en_MY', 'goog.i18n.CompactNumberFormatSymbols_en_NA', 'goog.i18n.CompactNumberFormatSymbols_en_NF', 'goog.i18n.CompactNumberFormatSymbols_en_NG', 'goog.i18n.CompactNumberFormatSymbols_en_NL', 'goog.i18n.CompactNumberFormatSymbols_en_NR', 'goog.i18n.CompactNumberFormatSymbols_en_NU', 'goog.i18n.CompactNumberFormatSymbols_en_NZ', 'goog.i18n.CompactNumberFormatSymbols_en_PG', 'goog.i18n.CompactNumberFormatSymbols_en_PH', 'goog.i18n.CompactNumberFormatSymbols_en_PK', 'goog.i18n.CompactNumberFormatSymbols_en_PN', 'goog.i18n.CompactNumberFormatSymbols_en_PR', 'goog.i18n.CompactNumberFormatSymbols_en_PW', 'goog.i18n.CompactNumberFormatSymbols_en_RW', 'goog.i18n.CompactNumberFormatSymbols_en_SB', 'goog.i18n.CompactNumberFormatSymbols_en_SC', 'goog.i18n.CompactNumberFormatSymbols_en_SD', 'goog.i18n.CompactNumberFormatSymbols_en_SE', 'goog.i18n.CompactNumberFormatSymbols_en_SH', 'goog.i18n.CompactNumberFormatSymbols_en_SI', 'goog.i18n.CompactNumberFormatSymbols_en_SL', 'goog.i18n.CompactNumberFormatSymbols_en_SS', 'goog.i18n.CompactNumberFormatSymbols_en_SX', 'goog.i18n.CompactNumberFormatSymbols_en_SZ', 'goog.i18n.CompactNumberFormatSymbols_en_TC', 'goog.i18n.CompactNumberFormatSymbols_en_TK', 'goog.i18n.CompactNumberFormatSymbols_en_TO', 'goog.i18n.CompactNumberFormatSymbols_en_TT', 'goog.i18n.CompactNumberFormatSymbols_en_TV', 'goog.i18n.CompactNumberFormatSymbols_en_TZ', 'goog.i18n.CompactNumberFormatSymbols_en_UG', 'goog.i18n.CompactNumberFormatSymbols_en_UM', 'goog.i18n.CompactNumberFormatSymbols_en_US_POSIX', 'goog.i18n.CompactNumberFormatSymbols_en_VC', 'goog.i18n.CompactNumberFormatSymbols_en_VG', 'goog.i18n.CompactNumberFormatSymbols_en_VI', 'goog.i18n.CompactNumberFormatSymbols_en_VU', 'goog.i18n.CompactNumberFormatSymbols_en_WS', 'goog.i18n.CompactNumberFormatSymbols_en_XA', 'goog.i18n.CompactNumberFormatSymbols_en_ZM', 'goog.i18n.CompactNumberFormatSymbols_en_ZW', 'goog.i18n.CompactNumberFormatSymbols_eo', 'goog.i18n.CompactNumberFormatSymbols_es_AR', 'goog.i18n.CompactNumberFormatSymbols_es_BO', 'goog.i18n.CompactNumberFormatSymbols_es_BR', 'goog.i18n.CompactNumberFormatSymbols_es_CL', 'goog.i18n.CompactNumberFormatSymbols_es_CO', 'goog.i18n.CompactNumberFormatSymbols_es_CR', 'goog.i18n.CompactNumberFormatSymbols_es_CU', 'goog.i18n.CompactNumberFormatSymbols_es_DO', 'goog.i18n.CompactNumberFormatSymbols_es_EA', 'goog.i18n.CompactNumberFormatSymbols_es_EC', 'goog.i18n.CompactNumberFormatSymbols_es_GQ', 'goog.i18n.CompactNumberFormatSymbols_es_GT', 'goog.i18n.CompactNumberFormatSymbols_es_HN', 'goog.i18n.CompactNumberFormatSymbols_es_IC', 'goog.i18n.CompactNumberFormatSymbols_es_NI', 'goog.i18n.CompactNumberFormatSymbols_es_PA', 'goog.i18n.CompactNumberFormatSymbols_es_PE', 'goog.i18n.CompactNumberFormatSymbols_es_PH', 'goog.i18n.CompactNumberFormatSymbols_es_PR', 'goog.i18n.CompactNumberFormatSymbols_es_PY', 'goog.i18n.CompactNumberFormatSymbols_es_SV', 'goog.i18n.CompactNumberFormatSymbols_es_UY', 'goog.i18n.CompactNumberFormatSymbols_es_VE', 'goog.i18n.CompactNumberFormatSymbols_et_EE', 'goog.i18n.CompactNumberFormatSymbols_eu_ES', 'goog.i18n.CompactNumberFormatSymbols_ewo', 'goog.i18n.CompactNumberFormatSymbols_ewo_CM', 'goog.i18n.CompactNumberFormatSymbols_fa_AF', 'goog.i18n.CompactNumberFormatSymbols_fa_IR', 'goog.i18n.CompactNumberFormatSymbols_ff', 'goog.i18n.CompactNumberFormatSymbols_ff_CM', 'goog.i18n.CompactNumberFormatSymbols_ff_GN', 'goog.i18n.CompactNumberFormatSymbols_ff_MR', 'goog.i18n.CompactNumberFormatSymbols_ff_SN', 'goog.i18n.CompactNumberFormatSymbols_fi_FI', 'goog.i18n.CompactNumberFormatSymbols_fil_PH', 'goog.i18n.CompactNumberFormatSymbols_fo', 'goog.i18n.CompactNumberFormatSymbols_fo_DK', 'goog.i18n.CompactNumberFormatSymbols_fo_FO', 'goog.i18n.CompactNumberFormatSymbols_fr_BE', 'goog.i18n.CompactNumberFormatSymbols_fr_BF', 'goog.i18n.CompactNumberFormatSymbols_fr_BI', 'goog.i18n.CompactNumberFormatSymbols_fr_BJ', 'goog.i18n.CompactNumberFormatSymbols_fr_BL', 'goog.i18n.CompactNumberFormatSymbols_fr_CD', 'goog.i18n.CompactNumberFormatSymbols_fr_CF', 'goog.i18n.CompactNumberFormatSymbols_fr_CG', 'goog.i18n.CompactNumberFormatSymbols_fr_CH', 'goog.i18n.CompactNumberFormatSymbols_fr_CI', 'goog.i18n.CompactNumberFormatSymbols_fr_CM', 'goog.i18n.CompactNumberFormatSymbols_fr_DJ', 'goog.i18n.CompactNumberFormatSymbols_fr_DZ', 'goog.i18n.CompactNumberFormatSymbols_fr_FR', 'goog.i18n.CompactNumberFormatSymbols_fr_GA', 'goog.i18n.CompactNumberFormatSymbols_fr_GF', 'goog.i18n.CompactNumberFormatSymbols_fr_GN', 'goog.i18n.CompactNumberFormatSymbols_fr_GP', 'goog.i18n.CompactNumberFormatSymbols_fr_GQ', 'goog.i18n.CompactNumberFormatSymbols_fr_HT', 'goog.i18n.CompactNumberFormatSymbols_fr_KM', 'goog.i18n.CompactNumberFormatSymbols_fr_LU', 'goog.i18n.CompactNumberFormatSymbols_fr_MA', 'goog.i18n.CompactNumberFormatSymbols_fr_MC', 'goog.i18n.CompactNumberFormatSymbols_fr_MF', 'goog.i18n.CompactNumberFormatSymbols_fr_MG', 'goog.i18n.CompactNumberFormatSymbols_fr_ML', 'goog.i18n.CompactNumberFormatSymbols_fr_MQ', 'goog.i18n.CompactNumberFormatSymbols_fr_MR', 'goog.i18n.CompactNumberFormatSymbols_fr_MU', 'goog.i18n.CompactNumberFormatSymbols_fr_NC', 'goog.i18n.CompactNumberFormatSymbols_fr_NE', 'goog.i18n.CompactNumberFormatSymbols_fr_PF', 'goog.i18n.CompactNumberFormatSymbols_fr_PM', 'goog.i18n.CompactNumberFormatSymbols_fr_RE', 'goog.i18n.CompactNumberFormatSymbols_fr_RW', 'goog.i18n.CompactNumberFormatSymbols_fr_SC', 'goog.i18n.CompactNumberFormatSymbols_fr_SN', 'goog.i18n.CompactNumberFormatSymbols_fr_SY', 'goog.i18n.CompactNumberFormatSymbols_fr_TD', 'goog.i18n.CompactNumberFormatSymbols_fr_TG', 'goog.i18n.CompactNumberFormatSymbols_fr_TN', 'goog.i18n.CompactNumberFormatSymbols_fr_VU', 'goog.i18n.CompactNumberFormatSymbols_fr_WF', 'goog.i18n.CompactNumberFormatSymbols_fr_YT', 'goog.i18n.CompactNumberFormatSymbols_fur', 'goog.i18n.CompactNumberFormatSymbols_fur_IT', 'goog.i18n.CompactNumberFormatSymbols_fy', 'goog.i18n.CompactNumberFormatSymbols_fy_NL', 'goog.i18n.CompactNumberFormatSymbols_ga_IE', 'goog.i18n.CompactNumberFormatSymbols_gd', 'goog.i18n.CompactNumberFormatSymbols_gd_GB', 'goog.i18n.CompactNumberFormatSymbols_gl_ES', 'goog.i18n.CompactNumberFormatSymbols_gsw_CH', 'goog.i18n.CompactNumberFormatSymbols_gsw_FR', 'goog.i18n.CompactNumberFormatSymbols_gsw_LI', 'goog.i18n.CompactNumberFormatSymbols_gu_IN', 'goog.i18n.CompactNumberFormatSymbols_guz', 'goog.i18n.CompactNumberFormatSymbols_guz_KE', 'goog.i18n.CompactNumberFormatSymbols_gv', 'goog.i18n.CompactNumberFormatSymbols_gv_IM', 'goog.i18n.CompactNumberFormatSymbols_ha', 'goog.i18n.CompactNumberFormatSymbols_ha_GH', 'goog.i18n.CompactNumberFormatSymbols_ha_NE', 'goog.i18n.CompactNumberFormatSymbols_ha_NG', 'goog.i18n.CompactNumberFormatSymbols_haw_US', 'goog.i18n.CompactNumberFormatSymbols_he_IL', 'goog.i18n.CompactNumberFormatSymbols_hi_IN', 'goog.i18n.CompactNumberFormatSymbols_hr_BA', 'goog.i18n.CompactNumberFormatSymbols_hr_HR', 'goog.i18n.CompactNumberFormatSymbols_hsb', 'goog.i18n.CompactNumberFormatSymbols_hsb_DE', 'goog.i18n.CompactNumberFormatSymbols_hu_HU', 'goog.i18n.CompactNumberFormatSymbols_hy_AM', 'goog.i18n.CompactNumberFormatSymbols_id_ID', 'goog.i18n.CompactNumberFormatSymbols_ig', 'goog.i18n.CompactNumberFormatSymbols_ig_NG', 'goog.i18n.CompactNumberFormatSymbols_ii', 'goog.i18n.CompactNumberFormatSymbols_ii_CN', 'goog.i18n.CompactNumberFormatSymbols_is_IS', 'goog.i18n.CompactNumberFormatSymbols_it_CH', 'goog.i18n.CompactNumberFormatSymbols_it_IT', 'goog.i18n.CompactNumberFormatSymbols_it_SM', 'goog.i18n.CompactNumberFormatSymbols_ja_JP', 'goog.i18n.CompactNumberFormatSymbols_jgo', 'goog.i18n.CompactNumberFormatSymbols_jgo_CM', 'goog.i18n.CompactNumberFormatSymbols_jmc', 'goog.i18n.CompactNumberFormatSymbols_jmc_TZ', 'goog.i18n.CompactNumberFormatSymbols_ka_GE', 'goog.i18n.CompactNumberFormatSymbols_kab', 'goog.i18n.CompactNumberFormatSymbols_kab_DZ', 'goog.i18n.CompactNumberFormatSymbols_kam', 'goog.i18n.CompactNumberFormatSymbols_kam_KE', 'goog.i18n.CompactNumberFormatSymbols_kde', 'goog.i18n.CompactNumberFormatSymbols_kde_TZ', 'goog.i18n.CompactNumberFormatSymbols_kea', 'goog.i18n.CompactNumberFormatSymbols_kea_CV', 'goog.i18n.CompactNumberFormatSymbols_khq', 'goog.i18n.CompactNumberFormatSymbols_khq_ML', 'goog.i18n.CompactNumberFormatSymbols_ki', 'goog.i18n.CompactNumberFormatSymbols_ki_KE', 'goog.i18n.CompactNumberFormatSymbols_kk_KZ', 'goog.i18n.CompactNumberFormatSymbols_kkj', 'goog.i18n.CompactNumberFormatSymbols_kkj_CM', 'goog.i18n.CompactNumberFormatSymbols_kl', 'goog.i18n.CompactNumberFormatSymbols_kl_GL', 'goog.i18n.CompactNumberFormatSymbols_kln', 'goog.i18n.CompactNumberFormatSymbols_kln_KE', 'goog.i18n.CompactNumberFormatSymbols_km_KH', 'goog.i18n.CompactNumberFormatSymbols_kn_IN', 'goog.i18n.CompactNumberFormatSymbols_ko_KP', 'goog.i18n.CompactNumberFormatSymbols_ko_KR', 'goog.i18n.CompactNumberFormatSymbols_kok', 'goog.i18n.CompactNumberFormatSymbols_kok_IN', 'goog.i18n.CompactNumberFormatSymbols_ks', 'goog.i18n.CompactNumberFormatSymbols_ks_IN', 'goog.i18n.CompactNumberFormatSymbols_ksb', 'goog.i18n.CompactNumberFormatSymbols_ksb_TZ', 'goog.i18n.CompactNumberFormatSymbols_ksf', 'goog.i18n.CompactNumberFormatSymbols_ksf_CM', 'goog.i18n.CompactNumberFormatSymbols_ksh', 'goog.i18n.CompactNumberFormatSymbols_ksh_DE', 'goog.i18n.CompactNumberFormatSymbols_kw', 'goog.i18n.CompactNumberFormatSymbols_kw_GB', 'goog.i18n.CompactNumberFormatSymbols_ky_KG', 'goog.i18n.CompactNumberFormatSymbols_lag', 'goog.i18n.CompactNumberFormatSymbols_lag_TZ', 'goog.i18n.CompactNumberFormatSymbols_lb', 'goog.i18n.CompactNumberFormatSymbols_lb_LU', 'goog.i18n.CompactNumberFormatSymbols_lg', 'goog.i18n.CompactNumberFormatSymbols_lg_UG', 'goog.i18n.CompactNumberFormatSymbols_lkt', 'goog.i18n.CompactNumberFormatSymbols_lkt_US', 'goog.i18n.CompactNumberFormatSymbols_ln_AO', 'goog.i18n.CompactNumberFormatSymbols_ln_CD', 'goog.i18n.CompactNumberFormatSymbols_ln_CF', 'goog.i18n.CompactNumberFormatSymbols_ln_CG', 'goog.i18n.CompactNumberFormatSymbols_lo_LA', 'goog.i18n.CompactNumberFormatSymbols_lrc', 'goog.i18n.CompactNumberFormatSymbols_lrc_IQ', 'goog.i18n.CompactNumberFormatSymbols_lrc_IR', 'goog.i18n.CompactNumberFormatSymbols_lt_LT', 'goog.i18n.CompactNumberFormatSymbols_lu', 'goog.i18n.CompactNumberFormatSymbols_lu_CD', 'goog.i18n.CompactNumberFormatSymbols_luo', 'goog.i18n.CompactNumberFormatSymbols_luo_KE', 'goog.i18n.CompactNumberFormatSymbols_luy', 'goog.i18n.CompactNumberFormatSymbols_luy_KE', 'goog.i18n.CompactNumberFormatSymbols_lv_LV', 'goog.i18n.CompactNumberFormatSymbols_mas', 'goog.i18n.CompactNumberFormatSymbols_mas_KE', 'goog.i18n.CompactNumberFormatSymbols_mas_TZ', 'goog.i18n.CompactNumberFormatSymbols_mer', 'goog.i18n.CompactNumberFormatSymbols_mer_KE', 'goog.i18n.CompactNumberFormatSymbols_mfe', 'goog.i18n.CompactNumberFormatSymbols_mfe_MU', 'goog.i18n.CompactNumberFormatSymbols_mg', 'goog.i18n.CompactNumberFormatSymbols_mg_MG', 'goog.i18n.CompactNumberFormatSymbols_mgh', 'goog.i18n.CompactNumberFormatSymbols_mgh_MZ', 'goog.i18n.CompactNumberFormatSymbols_mgo', 'goog.i18n.CompactNumberFormatSymbols_mgo_CM', 'goog.i18n.CompactNumberFormatSymbols_mk_MK', 'goog.i18n.CompactNumberFormatSymbols_ml_IN', 'goog.i18n.CompactNumberFormatSymbols_mn_MN', 'goog.i18n.CompactNumberFormatSymbols_mr_IN', 'goog.i18n.CompactNumberFormatSymbols_ms_BN', 'goog.i18n.CompactNumberFormatSymbols_ms_MY', 'goog.i18n.CompactNumberFormatSymbols_ms_SG', 'goog.i18n.CompactNumberFormatSymbols_mt_MT', 'goog.i18n.CompactNumberFormatSymbols_mua', 'goog.i18n.CompactNumberFormatSymbols_mua_CM', 'goog.i18n.CompactNumberFormatSymbols_my_MM', 'goog.i18n.CompactNumberFormatSymbols_mzn', 'goog.i18n.CompactNumberFormatSymbols_mzn_IR', 'goog.i18n.CompactNumberFormatSymbols_naq', 'goog.i18n.CompactNumberFormatSymbols_naq_NA', 'goog.i18n.CompactNumberFormatSymbols_nb_NO', 'goog.i18n.CompactNumberFormatSymbols_nb_SJ', 'goog.i18n.CompactNumberFormatSymbols_nd', 'goog.i18n.CompactNumberFormatSymbols_nd_ZW', 'goog.i18n.CompactNumberFormatSymbols_nds', 'goog.i18n.CompactNumberFormatSymbols_nds_DE', 'goog.i18n.CompactNumberFormatSymbols_nds_NL', 'goog.i18n.CompactNumberFormatSymbols_ne_IN', 'goog.i18n.CompactNumberFormatSymbols_ne_NP', 'goog.i18n.CompactNumberFormatSymbols_nl_AW', 'goog.i18n.CompactNumberFormatSymbols_nl_BE', 'goog.i18n.CompactNumberFormatSymbols_nl_BQ', 'goog.i18n.CompactNumberFormatSymbols_nl_CW', 'goog.i18n.CompactNumberFormatSymbols_nl_NL', 'goog.i18n.CompactNumberFormatSymbols_nl_SR', 'goog.i18n.CompactNumberFormatSymbols_nl_SX', 'goog.i18n.CompactNumberFormatSymbols_nmg', 'goog.i18n.CompactNumberFormatSymbols_nmg_CM', 'goog.i18n.CompactNumberFormatSymbols_nn', 'goog.i18n.CompactNumberFormatSymbols_nn_NO', 'goog.i18n.CompactNumberFormatSymbols_nnh', 'goog.i18n.CompactNumberFormatSymbols_nnh_CM', 'goog.i18n.CompactNumberFormatSymbols_nus', 'goog.i18n.CompactNumberFormatSymbols_nus_SS', 'goog.i18n.CompactNumberFormatSymbols_nyn', 'goog.i18n.CompactNumberFormatSymbols_nyn_UG', 'goog.i18n.CompactNumberFormatSymbols_om', 'goog.i18n.CompactNumberFormatSymbols_om_ET', 'goog.i18n.CompactNumberFormatSymbols_om_KE', 'goog.i18n.CompactNumberFormatSymbols_or_IN', 'goog.i18n.CompactNumberFormatSymbols_os', 'goog.i18n.CompactNumberFormatSymbols_os_GE', 'goog.i18n.CompactNumberFormatSymbols_os_RU', 'goog.i18n.CompactNumberFormatSymbols_pa_Arab', 'goog.i18n.CompactNumberFormatSymbols_pa_Arab_PK', 'goog.i18n.CompactNumberFormatSymbols_pa_Guru', 'goog.i18n.CompactNumberFormatSymbols_pa_Guru_IN', 'goog.i18n.CompactNumberFormatSymbols_pl_PL', 'goog.i18n.CompactNumberFormatSymbols_ps', 'goog.i18n.CompactNumberFormatSymbols_ps_AF', 'goog.i18n.CompactNumberFormatSymbols_pt_AO', 'goog.i18n.CompactNumberFormatSymbols_pt_CH', 'goog.i18n.CompactNumberFormatSymbols_pt_CV', 'goog.i18n.CompactNumberFormatSymbols_pt_GQ', 'goog.i18n.CompactNumberFormatSymbols_pt_GW', 'goog.i18n.CompactNumberFormatSymbols_pt_LU', 'goog.i18n.CompactNumberFormatSymbols_pt_MO', 'goog.i18n.CompactNumberFormatSymbols_pt_MZ', 'goog.i18n.CompactNumberFormatSymbols_pt_ST', 'goog.i18n.CompactNumberFormatSymbols_pt_TL', 'goog.i18n.CompactNumberFormatSymbols_qu', 'goog.i18n.CompactNumberFormatSymbols_qu_BO', 'goog.i18n.CompactNumberFormatSymbols_qu_EC', 'goog.i18n.CompactNumberFormatSymbols_qu_PE', 'goog.i18n.CompactNumberFormatSymbols_rm', 'goog.i18n.CompactNumberFormatSymbols_rm_CH', 'goog.i18n.CompactNumberFormatSymbols_rn', 'goog.i18n.CompactNumberFormatSymbols_rn_BI', 'goog.i18n.CompactNumberFormatSymbols_ro_MD', 'goog.i18n.CompactNumberFormatSymbols_ro_RO', 'goog.i18n.CompactNumberFormatSymbols_rof', 'goog.i18n.CompactNumberFormatSymbols_rof_TZ', 'goog.i18n.CompactNumberFormatSymbols_ru_BY', 'goog.i18n.CompactNumberFormatSymbols_ru_KG', 'goog.i18n.CompactNumberFormatSymbols_ru_KZ', 'goog.i18n.CompactNumberFormatSymbols_ru_MD', 'goog.i18n.CompactNumberFormatSymbols_ru_RU', 'goog.i18n.CompactNumberFormatSymbols_ru_UA', 'goog.i18n.CompactNumberFormatSymbols_rw', 'goog.i18n.CompactNumberFormatSymbols_rw_RW', 'goog.i18n.CompactNumberFormatSymbols_rwk', 'goog.i18n.CompactNumberFormatSymbols_rwk_TZ', 'goog.i18n.CompactNumberFormatSymbols_sah', 'goog.i18n.CompactNumberFormatSymbols_sah_RU', 'goog.i18n.CompactNumberFormatSymbols_saq', 'goog.i18n.CompactNumberFormatSymbols_saq_KE', 'goog.i18n.CompactNumberFormatSymbols_sbp', 'goog.i18n.CompactNumberFormatSymbols_sbp_TZ', 'goog.i18n.CompactNumberFormatSymbols_se', 'goog.i18n.CompactNumberFormatSymbols_se_FI', 'goog.i18n.CompactNumberFormatSymbols_se_NO', 'goog.i18n.CompactNumberFormatSymbols_se_SE', 'goog.i18n.CompactNumberFormatSymbols_seh', 'goog.i18n.CompactNumberFormatSymbols_seh_MZ', 'goog.i18n.CompactNumberFormatSymbols_ses', 'goog.i18n.CompactNumberFormatSymbols_ses_ML', 'goog.i18n.CompactNumberFormatSymbols_sg', 'goog.i18n.CompactNumberFormatSymbols_sg_CF', 'goog.i18n.CompactNumberFormatSymbols_shi', 'goog.i18n.CompactNumberFormatSymbols_shi_Latn', 'goog.i18n.CompactNumberFormatSymbols_shi_Latn_MA', 'goog.i18n.CompactNumberFormatSymbols_shi_Tfng', 'goog.i18n.CompactNumberFormatSymbols_shi_Tfng_MA', 'goog.i18n.CompactNumberFormatSymbols_si_LK', 'goog.i18n.CompactNumberFormatSymbols_sk_SK', 'goog.i18n.CompactNumberFormatSymbols_sl_SI', 'goog.i18n.CompactNumberFormatSymbols_smn', 'goog.i18n.CompactNumberFormatSymbols_smn_FI', 'goog.i18n.CompactNumberFormatSymbols_sn', 'goog.i18n.CompactNumberFormatSymbols_sn_ZW', 'goog.i18n.CompactNumberFormatSymbols_so', 'goog.i18n.CompactNumberFormatSymbols_so_DJ', 'goog.i18n.CompactNumberFormatSymbols_so_ET', 'goog.i18n.CompactNumberFormatSymbols_so_KE', 'goog.i18n.CompactNumberFormatSymbols_so_SO', 'goog.i18n.CompactNumberFormatSymbols_sq_AL', 'goog.i18n.CompactNumberFormatSymbols_sq_MK', 'goog.i18n.CompactNumberFormatSymbols_sq_XK', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_BA', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_ME', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_RS', 'goog.i18n.CompactNumberFormatSymbols_sr_Cyrl_XK', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_BA', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_ME', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_RS', 'goog.i18n.CompactNumberFormatSymbols_sr_Latn_XK', 'goog.i18n.CompactNumberFormatSymbols_sv_AX', 'goog.i18n.CompactNumberFormatSymbols_sv_FI', 'goog.i18n.CompactNumberFormatSymbols_sv_SE', 'goog.i18n.CompactNumberFormatSymbols_sw_CD', 'goog.i18n.CompactNumberFormatSymbols_sw_KE', 'goog.i18n.CompactNumberFormatSymbols_sw_TZ', 'goog.i18n.CompactNumberFormatSymbols_sw_UG', 'goog.i18n.CompactNumberFormatSymbols_ta_IN', 'goog.i18n.CompactNumberFormatSymbols_ta_LK', 'goog.i18n.CompactNumberFormatSymbols_ta_MY', 'goog.i18n.CompactNumberFormatSymbols_ta_SG', 'goog.i18n.CompactNumberFormatSymbols_te_IN', 'goog.i18n.CompactNumberFormatSymbols_teo', 'goog.i18n.CompactNumberFormatSymbols_teo_KE', 'goog.i18n.CompactNumberFormatSymbols_teo_UG', 'goog.i18n.CompactNumberFormatSymbols_th_TH', 'goog.i18n.CompactNumberFormatSymbols_ti', 'goog.i18n.CompactNumberFormatSymbols_ti_ER', 'goog.i18n.CompactNumberFormatSymbols_ti_ET', 'goog.i18n.CompactNumberFormatSymbols_to', 'goog.i18n.CompactNumberFormatSymbols_to_TO', 'goog.i18n.CompactNumberFormatSymbols_tr_CY', 'goog.i18n.CompactNumberFormatSymbols_tr_TR', 'goog.i18n.CompactNumberFormatSymbols_twq', 'goog.i18n.CompactNumberFormatSymbols_twq_NE', 'goog.i18n.CompactNumberFormatSymbols_tzm', 'goog.i18n.CompactNumberFormatSymbols_tzm_MA', 'goog.i18n.CompactNumberFormatSymbols_ug', 'goog.i18n.CompactNumberFormatSymbols_ug_CN', 'goog.i18n.CompactNumberFormatSymbols_uk_UA', 'goog.i18n.CompactNumberFormatSymbols_ur_IN', 'goog.i18n.CompactNumberFormatSymbols_ur_PK', 'goog.i18n.CompactNumberFormatSymbols_uz_Arab', 'goog.i18n.CompactNumberFormatSymbols_uz_Arab_AF', 'goog.i18n.CompactNumberFormatSymbols_uz_Cyrl', 'goog.i18n.CompactNumberFormatSymbols_uz_Cyrl_UZ', 'goog.i18n.CompactNumberFormatSymbols_uz_Latn', 'goog.i18n.CompactNumberFormatSymbols_uz_Latn_UZ', 'goog.i18n.CompactNumberFormatSymbols_vai', 'goog.i18n.CompactNumberFormatSymbols_vai_Latn', 'goog.i18n.CompactNumberFormatSymbols_vai_Latn_LR', 'goog.i18n.CompactNumberFormatSymbols_vai_Vaii', 'goog.i18n.CompactNumberFormatSymbols_vai_Vaii_LR', 'goog.i18n.CompactNumberFormatSymbols_vi_VN', 'goog.i18n.CompactNumberFormatSymbols_vun', 'goog.i18n.CompactNumberFormatSymbols_vun_TZ', 'goog.i18n.CompactNumberFormatSymbols_wae', 'goog.i18n.CompactNumberFormatSymbols_wae_CH', 'goog.i18n.CompactNumberFormatSymbols_xog', 'goog.i18n.CompactNumberFormatSymbols_xog_UG', 'goog.i18n.CompactNumberFormatSymbols_yav', 'goog.i18n.CompactNumberFormatSymbols_yav_CM', 'goog.i18n.CompactNumberFormatSymbols_yi', 'goog.i18n.CompactNumberFormatSymbols_yi_001', 'goog.i18n.CompactNumberFormatSymbols_yo', 'goog.i18n.CompactNumberFormatSymbols_yo_BJ', 'goog.i18n.CompactNumberFormatSymbols_yo_NG', 'goog.i18n.CompactNumberFormatSymbols_yue', 'goog.i18n.CompactNumberFormatSymbols_yue_HK', 'goog.i18n.CompactNumberFormatSymbols_zgh', 'goog.i18n.CompactNumberFormatSymbols_zgh_MA', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_CN', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_MO', 'goog.i18n.CompactNumberFormatSymbols_zh_Hans_SG', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_HK', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_MO', 'goog.i18n.CompactNumberFormatSymbols_zh_Hant_TW', 'goog.i18n.CompactNumberFormatSymbols_zu_ZA'], ['goog.i18n.CompactNumberFormatSymbols']);
                +goog.addDependency("i18n/currency.js", ['goog.i18n.currency', 'goog.i18n.currency.CurrencyInfo', 'goog.i18n.currency.CurrencyInfoTier2'], []);
                +goog.addDependency("i18n/currency_test.js", ['goog.i18n.currencyTest'], ['goog.i18n.NumberFormat', 'goog.i18n.currency', 'goog.i18n.currency.CurrencyInfo', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/currencycodemap.js", ['goog.i18n.currencyCodeMap', 'goog.i18n.currencyCodeMapTier2'], []);
                +goog.addDependency("i18n/dateintervalformat.js", [], []);
                +goog.addDependency("i18n/dateintervalformat_test.js", [], []);
                +goog.addDependency("i18n/dateintervalpatterns.js", [], []);
                +goog.addDependency("i18n/dateintervalpatternsext.js", [], []);
                +goog.addDependency("i18n/dateintervalsymbols.js", [], []);
                +goog.addDependency("i18n/dateintervalsymbolsext.js", [], []);
                +goog.addDependency("i18n/datetimeformat.js", ['goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeFormat.Format'], ['goog.asserts', 'goog.date', 'goog.i18n.DateTimeSymbols', 'goog.i18n.TimeZone', 'goog.string']);
                +goog.addDependency("i18n/datetimeformat_test.js", ['goog.i18n.DateTimeFormatTest'], ['goog.date.Date', 'goog.date.DateTime', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns', 'goog.i18n.DateTimePatterns_ar', 'goog.i18n.DateTimePatterns_de', 'goog.i18n.DateTimePatterns_en', 'goog.i18n.DateTimePatterns_fa', 'goog.i18n.DateTimePatterns_fr', 'goog.i18n.DateTimePatterns_ja', 'goog.i18n.DateTimePatterns_sv', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_ar', 'goog.i18n.DateTimeSymbols_ar_AE', 'goog.i18n.DateTimeSymbols_ar_SA', 'goog.i18n.DateTimeSymbols_bn_BD', 'goog.i18n.DateTimeSymbols_de', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_en_GB', 'goog.i18n.DateTimeSymbols_en_IE', 'goog.i18n.DateTimeSymbols_en_IN', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_fr_DJ', 'goog.i18n.DateTimeSymbols_he_IL', 'goog.i18n.DateTimeSymbols_ja', 'goog.i18n.DateTimeSymbols_ro_RO', 'goog.i18n.DateTimeSymbols_sv', 'goog.i18n.TimeZone', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/datetimeparse.js", ['goog.i18n.DateTimeParse'], ['goog.asserts', 'goog.date', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeSymbols']);
                +goog.addDependency("i18n/datetimeparse_test.js", ['goog.i18n.DateTimeParseTest'], ['goog.date.Date', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeParse', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_pl', 'goog.i18n.DateTimeSymbols_zh', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("i18n/datetimepatterns.js", ['goog.i18n.DateTimePatterns', 'goog.i18n.DateTimePatterns_af', 'goog.i18n.DateTimePatterns_am', 'goog.i18n.DateTimePatterns_ar', 'goog.i18n.DateTimePatterns_ar_DZ', 'goog.i18n.DateTimePatterns_az', 'goog.i18n.DateTimePatterns_be', 'goog.i18n.DateTimePatterns_bg', 'goog.i18n.DateTimePatterns_bn', 'goog.i18n.DateTimePatterns_br', 'goog.i18n.DateTimePatterns_bs', 'goog.i18n.DateTimePatterns_ca', 'goog.i18n.DateTimePatterns_chr', 'goog.i18n.DateTimePatterns_cs', 'goog.i18n.DateTimePatterns_cy', 'goog.i18n.DateTimePatterns_da', 'goog.i18n.DateTimePatterns_de', 'goog.i18n.DateTimePatterns_de_AT', 'goog.i18n.DateTimePatterns_de_CH', 'goog.i18n.DateTimePatterns_el', 'goog.i18n.DateTimePatterns_en', 'goog.i18n.DateTimePatterns_en_AU', 'goog.i18n.DateTimePatterns_en_CA', 'goog.i18n.DateTimePatterns_en_GB', 'goog.i18n.DateTimePatterns_en_IE', 'goog.i18n.DateTimePatterns_en_IN', 'goog.i18n.DateTimePatterns_en_SG', 'goog.i18n.DateTimePatterns_en_US', 'goog.i18n.DateTimePatterns_en_ZA', 'goog.i18n.DateTimePatterns_es', 'goog.i18n.DateTimePatterns_es_419', 'goog.i18n.DateTimePatterns_es_ES', 'goog.i18n.DateTimePatterns_es_MX', 'goog.i18n.DateTimePatterns_es_US', 'goog.i18n.DateTimePatterns_et', 'goog.i18n.DateTimePatterns_eu', 'goog.i18n.DateTimePatterns_fa', 'goog.i18n.DateTimePatterns_fi', 'goog.i18n.DateTimePatterns_fil', 'goog.i18n.DateTimePatterns_fr', 'goog.i18n.DateTimePatterns_fr_CA', 'goog.i18n.DateTimePatterns_ga', 'goog.i18n.DateTimePatterns_gl', 'goog.i18n.DateTimePatterns_gsw', 'goog.i18n.DateTimePatterns_gu', 'goog.i18n.DateTimePatterns_haw', 'goog.i18n.DateTimePatterns_he', 'goog.i18n.DateTimePatterns_hi', 'goog.i18n.DateTimePatterns_hr', 'goog.i18n.DateTimePatterns_hu', 'goog.i18n.DateTimePatterns_hy', 'goog.i18n.DateTimePatterns_id', 'goog.i18n.DateTimePatterns_in', 'goog.i18n.DateTimePatterns_is', 'goog.i18n.DateTimePatterns_it', 'goog.i18n.DateTimePatterns_iw', 'goog.i18n.DateTimePatterns_ja', 'goog.i18n.DateTimePatterns_ka', 'goog.i18n.DateTimePatterns_kk', 'goog.i18n.DateTimePatterns_km', 'goog.i18n.DateTimePatterns_kn', 'goog.i18n.DateTimePatterns_ko', 'goog.i18n.DateTimePatterns_ky', 'goog.i18n.DateTimePatterns_ln', 'goog.i18n.DateTimePatterns_lo', 'goog.i18n.DateTimePatterns_lt', 'goog.i18n.DateTimePatterns_lv', 'goog.i18n.DateTimePatterns_mk', 'goog.i18n.DateTimePatterns_ml', 'goog.i18n.DateTimePatterns_mn', 'goog.i18n.DateTimePatterns_mo', 'goog.i18n.DateTimePatterns_mr', 'goog.i18n.DateTimePatterns_ms', 'goog.i18n.DateTimePatterns_mt', 'goog.i18n.DateTimePatterns_my', 'goog.i18n.DateTimePatterns_nb', 'goog.i18n.DateTimePatterns_ne', 'goog.i18n.DateTimePatterns_nl', 'goog.i18n.DateTimePatterns_no', 'goog.i18n.DateTimePatterns_no_NO', 'goog.i18n.DateTimePatterns_or', 'goog.i18n.DateTimePatterns_pa', 'goog.i18n.DateTimePatterns_pl', 'goog.i18n.DateTimePatterns_pt', 'goog.i18n.DateTimePatterns_pt_BR', 'goog.i18n.DateTimePatterns_pt_PT', 'goog.i18n.DateTimePatterns_ro', 'goog.i18n.DateTimePatterns_ru', 'goog.i18n.DateTimePatterns_sh', 'goog.i18n.DateTimePatterns_si', 'goog.i18n.DateTimePatterns_sk', 'goog.i18n.DateTimePatterns_sl', 'goog.i18n.DateTimePatterns_sq', 'goog.i18n.DateTimePatterns_sr', 'goog.i18n.DateTimePatterns_sr_Latn', 'goog.i18n.DateTimePatterns_sv', 'goog.i18n.DateTimePatterns_sw', 'goog.i18n.DateTimePatterns_ta', 'goog.i18n.DateTimePatterns_te', 'goog.i18n.DateTimePatterns_th', 'goog.i18n.DateTimePatterns_tl', 'goog.i18n.DateTimePatterns_tr', 'goog.i18n.DateTimePatterns_uk', 'goog.i18n.DateTimePatterns_ur', 'goog.i18n.DateTimePatterns_uz', 'goog.i18n.DateTimePatterns_vi', 'goog.i18n.DateTimePatterns_zh', 'goog.i18n.DateTimePatterns_zh_CN', 'goog.i18n.DateTimePatterns_zh_HK', 'goog.i18n.DateTimePatterns_zh_TW', 'goog.i18n.DateTimePatterns_zu'], []);
                +goog.addDependency("i18n/datetimepatternsext.js", ['goog.i18n.DateTimePatternsExt', 'goog.i18n.DateTimePatterns_af_NA', 'goog.i18n.DateTimePatterns_af_ZA', 'goog.i18n.DateTimePatterns_agq', 'goog.i18n.DateTimePatterns_agq_CM', 'goog.i18n.DateTimePatterns_ak', 'goog.i18n.DateTimePatterns_ak_GH', 'goog.i18n.DateTimePatterns_am_ET', 'goog.i18n.DateTimePatterns_ar_001', 'goog.i18n.DateTimePatterns_ar_AE', 'goog.i18n.DateTimePatterns_ar_BH', 'goog.i18n.DateTimePatterns_ar_DJ', 'goog.i18n.DateTimePatterns_ar_EG', 'goog.i18n.DateTimePatterns_ar_EH', 'goog.i18n.DateTimePatterns_ar_ER', 'goog.i18n.DateTimePatterns_ar_IL', 'goog.i18n.DateTimePatterns_ar_IQ', 'goog.i18n.DateTimePatterns_ar_JO', 'goog.i18n.DateTimePatterns_ar_KM', 'goog.i18n.DateTimePatterns_ar_KW', 'goog.i18n.DateTimePatterns_ar_LB', 'goog.i18n.DateTimePatterns_ar_LY', 'goog.i18n.DateTimePatterns_ar_MA', 'goog.i18n.DateTimePatterns_ar_MR', 'goog.i18n.DateTimePatterns_ar_OM', 'goog.i18n.DateTimePatterns_ar_PS', 'goog.i18n.DateTimePatterns_ar_QA', 'goog.i18n.DateTimePatterns_ar_SA', 'goog.i18n.DateTimePatterns_ar_SD', 'goog.i18n.DateTimePatterns_ar_SO', 'goog.i18n.DateTimePatterns_ar_SS', 'goog.i18n.DateTimePatterns_ar_SY', 'goog.i18n.DateTimePatterns_ar_TD', 'goog.i18n.DateTimePatterns_ar_TN', 'goog.i18n.DateTimePatterns_ar_XB', 'goog.i18n.DateTimePatterns_ar_YE', 'goog.i18n.DateTimePatterns_as', 'goog.i18n.DateTimePatterns_as_IN', 'goog.i18n.DateTimePatterns_asa', 'goog.i18n.DateTimePatterns_asa_TZ', 'goog.i18n.DateTimePatterns_ast', 'goog.i18n.DateTimePatterns_ast_ES', 'goog.i18n.DateTimePatterns_az_Cyrl', 'goog.i18n.DateTimePatterns_az_Cyrl_AZ', 'goog.i18n.DateTimePatterns_az_Latn', 'goog.i18n.DateTimePatterns_az_Latn_AZ', 'goog.i18n.DateTimePatterns_bas', 'goog.i18n.DateTimePatterns_bas_CM', 'goog.i18n.DateTimePatterns_be_BY', 'goog.i18n.DateTimePatterns_bem', 'goog.i18n.DateTimePatterns_bem_ZM', 'goog.i18n.DateTimePatterns_bez', 'goog.i18n.DateTimePatterns_bez_TZ', 'goog.i18n.DateTimePatterns_bg_BG', 'goog.i18n.DateTimePatterns_bm', 'goog.i18n.DateTimePatterns_bm_ML', 'goog.i18n.DateTimePatterns_bn_BD', 'goog.i18n.DateTimePatterns_bn_IN', 'goog.i18n.DateTimePatterns_bo', 'goog.i18n.DateTimePatterns_bo_CN', 'goog.i18n.DateTimePatterns_bo_IN', 'goog.i18n.DateTimePatterns_br_FR', 'goog.i18n.DateTimePatterns_brx', 'goog.i18n.DateTimePatterns_brx_IN', 'goog.i18n.DateTimePatterns_bs_Cyrl', 'goog.i18n.DateTimePatterns_bs_Cyrl_BA', 'goog.i18n.DateTimePatterns_bs_Latn', 'goog.i18n.DateTimePatterns_bs_Latn_BA', 'goog.i18n.DateTimePatterns_ca_AD', 'goog.i18n.DateTimePatterns_ca_ES', 'goog.i18n.DateTimePatterns_ca_FR', 'goog.i18n.DateTimePatterns_ca_IT', 'goog.i18n.DateTimePatterns_ce', 'goog.i18n.DateTimePatterns_ce_RU', 'goog.i18n.DateTimePatterns_cgg', 'goog.i18n.DateTimePatterns_cgg_UG', 'goog.i18n.DateTimePatterns_chr_US', 'goog.i18n.DateTimePatterns_ckb', 'goog.i18n.DateTimePatterns_ckb_IQ', 'goog.i18n.DateTimePatterns_ckb_IR', 'goog.i18n.DateTimePatterns_cs_CZ', 'goog.i18n.DateTimePatterns_cy_GB', 'goog.i18n.DateTimePatterns_da_DK', 'goog.i18n.DateTimePatterns_da_GL', 'goog.i18n.DateTimePatterns_dav', 'goog.i18n.DateTimePatterns_dav_KE', 'goog.i18n.DateTimePatterns_de_BE', 'goog.i18n.DateTimePatterns_de_DE', 'goog.i18n.DateTimePatterns_de_IT', 'goog.i18n.DateTimePatterns_de_LI', 'goog.i18n.DateTimePatterns_de_LU', 'goog.i18n.DateTimePatterns_dje', 'goog.i18n.DateTimePatterns_dje_NE', 'goog.i18n.DateTimePatterns_dsb', 'goog.i18n.DateTimePatterns_dsb_DE', 'goog.i18n.DateTimePatterns_dua', 'goog.i18n.DateTimePatterns_dua_CM', 'goog.i18n.DateTimePatterns_dyo', 'goog.i18n.DateTimePatterns_dyo_SN', 'goog.i18n.DateTimePatterns_dz', 'goog.i18n.DateTimePatterns_dz_BT', 'goog.i18n.DateTimePatterns_ebu', 'goog.i18n.DateTimePatterns_ebu_KE', 'goog.i18n.DateTimePatterns_ee', 'goog.i18n.DateTimePatterns_ee_GH', 'goog.i18n.DateTimePatterns_ee_TG', 'goog.i18n.DateTimePatterns_el_CY', 'goog.i18n.DateTimePatterns_el_GR', 'goog.i18n.DateTimePatterns_en_001', 'goog.i18n.DateTimePatterns_en_150', 'goog.i18n.DateTimePatterns_en_AG', 'goog.i18n.DateTimePatterns_en_AI', 'goog.i18n.DateTimePatterns_en_AS', 'goog.i18n.DateTimePatterns_en_AT', 'goog.i18n.DateTimePatterns_en_BB', 'goog.i18n.DateTimePatterns_en_BE', 'goog.i18n.DateTimePatterns_en_BI', 'goog.i18n.DateTimePatterns_en_BM', 'goog.i18n.DateTimePatterns_en_BS', 'goog.i18n.DateTimePatterns_en_BW', 'goog.i18n.DateTimePatterns_en_BZ', 'goog.i18n.DateTimePatterns_en_CC', 'goog.i18n.DateTimePatterns_en_CH', 'goog.i18n.DateTimePatterns_en_CK', 'goog.i18n.DateTimePatterns_en_CM', 'goog.i18n.DateTimePatterns_en_CX', 'goog.i18n.DateTimePatterns_en_CY', 'goog.i18n.DateTimePatterns_en_DE', 'goog.i18n.DateTimePatterns_en_DG', 'goog.i18n.DateTimePatterns_en_DK', 'goog.i18n.DateTimePatterns_en_DM', 'goog.i18n.DateTimePatterns_en_ER', 'goog.i18n.DateTimePatterns_en_FI', 'goog.i18n.DateTimePatterns_en_FJ', 'goog.i18n.DateTimePatterns_en_FK', 'goog.i18n.DateTimePatterns_en_FM', 'goog.i18n.DateTimePatterns_en_GD', 'goog.i18n.DateTimePatterns_en_GG', 'goog.i18n.DateTimePatterns_en_GH', 'goog.i18n.DateTimePatterns_en_GI', 'goog.i18n.DateTimePatterns_en_GM', 'goog.i18n.DateTimePatterns_en_GU', 'goog.i18n.DateTimePatterns_en_GY', 'goog.i18n.DateTimePatterns_en_HK', 'goog.i18n.DateTimePatterns_en_IL', 'goog.i18n.DateTimePatterns_en_IM', 'goog.i18n.DateTimePatterns_en_IO', 'goog.i18n.DateTimePatterns_en_JE', 'goog.i18n.DateTimePatterns_en_JM', 'goog.i18n.DateTimePatterns_en_KE', 'goog.i18n.DateTimePatterns_en_KI', 'goog.i18n.DateTimePatterns_en_KN', 'goog.i18n.DateTimePatterns_en_KY', 'goog.i18n.DateTimePatterns_en_LC', 'goog.i18n.DateTimePatterns_en_LR', 'goog.i18n.DateTimePatterns_en_LS', 'goog.i18n.DateTimePatterns_en_MG', 'goog.i18n.DateTimePatterns_en_MH', 'goog.i18n.DateTimePatterns_en_MO', 'goog.i18n.DateTimePatterns_en_MP', 'goog.i18n.DateTimePatterns_en_MS', 'goog.i18n.DateTimePatterns_en_MT', 'goog.i18n.DateTimePatterns_en_MU', 'goog.i18n.DateTimePatterns_en_MW', 'goog.i18n.DateTimePatterns_en_MY', 'goog.i18n.DateTimePatterns_en_NA', 'goog.i18n.DateTimePatterns_en_NF', 'goog.i18n.DateTimePatterns_en_NG', 'goog.i18n.DateTimePatterns_en_NL', 'goog.i18n.DateTimePatterns_en_NR', 'goog.i18n.DateTimePatterns_en_NU', 'goog.i18n.DateTimePatterns_en_NZ', 'goog.i18n.DateTimePatterns_en_PG', 'goog.i18n.DateTimePatterns_en_PH', 'goog.i18n.DateTimePatterns_en_PK', 'goog.i18n.DateTimePatterns_en_PN', 'goog.i18n.DateTimePatterns_en_PR', 'goog.i18n.DateTimePatterns_en_PW', 'goog.i18n.DateTimePatterns_en_RW', 'goog.i18n.DateTimePatterns_en_SB', 'goog.i18n.DateTimePatterns_en_SC', 'goog.i18n.DateTimePatterns_en_SD', 'goog.i18n.DateTimePatterns_en_SE', 'goog.i18n.DateTimePatterns_en_SH', 'goog.i18n.DateTimePatterns_en_SI', 'goog.i18n.DateTimePatterns_en_SL', 'goog.i18n.DateTimePatterns_en_SS', 'goog.i18n.DateTimePatterns_en_SX', 'goog.i18n.DateTimePatterns_en_SZ', 'goog.i18n.DateTimePatterns_en_TC', 'goog.i18n.DateTimePatterns_en_TK', 'goog.i18n.DateTimePatterns_en_TO', 'goog.i18n.DateTimePatterns_en_TT', 'goog.i18n.DateTimePatterns_en_TV', 'goog.i18n.DateTimePatterns_en_TZ', 'goog.i18n.DateTimePatterns_en_UG', 'goog.i18n.DateTimePatterns_en_UM', 'goog.i18n.DateTimePatterns_en_US_POSIX', 'goog.i18n.DateTimePatterns_en_VC', 'goog.i18n.DateTimePatterns_en_VG', 'goog.i18n.DateTimePatterns_en_VI', 'goog.i18n.DateTimePatterns_en_VU', 'goog.i18n.DateTimePatterns_en_WS', 'goog.i18n.DateTimePatterns_en_XA', 'goog.i18n.DateTimePatterns_en_ZM', 'goog.i18n.DateTimePatterns_en_ZW', 'goog.i18n.DateTimePatterns_eo', 'goog.i18n.DateTimePatterns_es_AR', 'goog.i18n.DateTimePatterns_es_BO', 'goog.i18n.DateTimePatterns_es_BR', 'goog.i18n.DateTimePatterns_es_CL', 'goog.i18n.DateTimePatterns_es_CO', 'goog.i18n.DateTimePatterns_es_CR', 'goog.i18n.DateTimePatterns_es_CU', 'goog.i18n.DateTimePatterns_es_DO', 'goog.i18n.DateTimePatterns_es_EA', 'goog.i18n.DateTimePatterns_es_EC', 'goog.i18n.DateTimePatterns_es_GQ', 'goog.i18n.DateTimePatterns_es_GT', 'goog.i18n.DateTimePatterns_es_HN', 'goog.i18n.DateTimePatterns_es_IC', 'goog.i18n.DateTimePatterns_es_NI', 'goog.i18n.DateTimePatterns_es_PA', 'goog.i18n.DateTimePatterns_es_PE', 'goog.i18n.DateTimePatterns_es_PH', 'goog.i18n.DateTimePatterns_es_PR', 'goog.i18n.DateTimePatterns_es_PY', 'goog.i18n.DateTimePatterns_es_SV', 'goog.i18n.DateTimePatterns_es_UY', 'goog.i18n.DateTimePatterns_es_VE', 'goog.i18n.DateTimePatterns_et_EE', 'goog.i18n.DateTimePatterns_eu_ES', 'goog.i18n.DateTimePatterns_ewo', 'goog.i18n.DateTimePatterns_ewo_CM', 'goog.i18n.DateTimePatterns_fa_AF', 'goog.i18n.DateTimePatterns_fa_IR', 'goog.i18n.DateTimePatterns_ff', 'goog.i18n.DateTimePatterns_ff_CM', 'goog.i18n.DateTimePatterns_ff_GN', 'goog.i18n.DateTimePatterns_ff_MR', 'goog.i18n.DateTimePatterns_ff_SN', 'goog.i18n.DateTimePatterns_fi_FI', 'goog.i18n.DateTimePatterns_fil_PH', 'goog.i18n.DateTimePatterns_fo', 'goog.i18n.DateTimePatterns_fo_DK', 'goog.i18n.DateTimePatterns_fo_FO', 'goog.i18n.DateTimePatterns_fr_BE', 'goog.i18n.DateTimePatterns_fr_BF', 'goog.i18n.DateTimePatterns_fr_BI', 'goog.i18n.DateTimePatterns_fr_BJ', 'goog.i18n.DateTimePatterns_fr_BL', 'goog.i18n.DateTimePatterns_fr_CD', 'goog.i18n.DateTimePatterns_fr_CF', 'goog.i18n.DateTimePatterns_fr_CG', 'goog.i18n.DateTimePatterns_fr_CH', 'goog.i18n.DateTimePatterns_fr_CI', 'goog.i18n.DateTimePatterns_fr_CM', 'goog.i18n.DateTimePatterns_fr_DJ', 'goog.i18n.DateTimePatterns_fr_DZ', 'goog.i18n.DateTimePatterns_fr_FR', 'goog.i18n.DateTimePatterns_fr_GA', 'goog.i18n.DateTimePatterns_fr_GF', 'goog.i18n.DateTimePatterns_fr_GN', 'goog.i18n.DateTimePatterns_fr_GP', 'goog.i18n.DateTimePatterns_fr_GQ', 'goog.i18n.DateTimePatterns_fr_HT', 'goog.i18n.DateTimePatterns_fr_KM', 'goog.i18n.DateTimePatterns_fr_LU', 'goog.i18n.DateTimePatterns_fr_MA', 'goog.i18n.DateTimePatterns_fr_MC', 'goog.i18n.DateTimePatterns_fr_MF', 'goog.i18n.DateTimePatterns_fr_MG', 'goog.i18n.DateTimePatterns_fr_ML', 'goog.i18n.DateTimePatterns_fr_MQ', 'goog.i18n.DateTimePatterns_fr_MR', 'goog.i18n.DateTimePatterns_fr_MU', 'goog.i18n.DateTimePatterns_fr_NC', 'goog.i18n.DateTimePatterns_fr_NE', 'goog.i18n.DateTimePatterns_fr_PF', 'goog.i18n.DateTimePatterns_fr_PM', 'goog.i18n.DateTimePatterns_fr_RE', 'goog.i18n.DateTimePatterns_fr_RW', 'goog.i18n.DateTimePatterns_fr_SC', 'goog.i18n.DateTimePatterns_fr_SN', 'goog.i18n.DateTimePatterns_fr_SY', 'goog.i18n.DateTimePatterns_fr_TD', 'goog.i18n.DateTimePatterns_fr_TG', 'goog.i18n.DateTimePatterns_fr_TN', 'goog.i18n.DateTimePatterns_fr_VU', 'goog.i18n.DateTimePatterns_fr_WF', 'goog.i18n.DateTimePatterns_fr_YT', 'goog.i18n.DateTimePatterns_fur', 'goog.i18n.DateTimePatterns_fur_IT', 'goog.i18n.DateTimePatterns_fy', 'goog.i18n.DateTimePatterns_fy_NL', 'goog.i18n.DateTimePatterns_ga_IE', 'goog.i18n.DateTimePatterns_gd', 'goog.i18n.DateTimePatterns_gd_GB', 'goog.i18n.DateTimePatterns_gl_ES', 'goog.i18n.DateTimePatterns_gsw_CH', 'goog.i18n.DateTimePatterns_gsw_FR', 'goog.i18n.DateTimePatterns_gsw_LI', 'goog.i18n.DateTimePatterns_gu_IN', 'goog.i18n.DateTimePatterns_guz', 'goog.i18n.DateTimePatterns_guz_KE', 'goog.i18n.DateTimePatterns_gv', 'goog.i18n.DateTimePatterns_gv_IM', 'goog.i18n.DateTimePatterns_ha', 'goog.i18n.DateTimePatterns_ha_GH', 'goog.i18n.DateTimePatterns_ha_NE', 'goog.i18n.DateTimePatterns_ha_NG', 'goog.i18n.DateTimePatterns_haw_US', 'goog.i18n.DateTimePatterns_he_IL', 'goog.i18n.DateTimePatterns_hi_IN', 'goog.i18n.DateTimePatterns_hr_BA', 'goog.i18n.DateTimePatterns_hr_HR', 'goog.i18n.DateTimePatterns_hsb', 'goog.i18n.DateTimePatterns_hsb_DE', 'goog.i18n.DateTimePatterns_hu_HU', 'goog.i18n.DateTimePatterns_hy_AM', 'goog.i18n.DateTimePatterns_id_ID', 'goog.i18n.DateTimePatterns_ig', 'goog.i18n.DateTimePatterns_ig_NG', 'goog.i18n.DateTimePatterns_ii', 'goog.i18n.DateTimePatterns_ii_CN', 'goog.i18n.DateTimePatterns_is_IS', 'goog.i18n.DateTimePatterns_it_CH', 'goog.i18n.DateTimePatterns_it_IT', 'goog.i18n.DateTimePatterns_it_SM', 'goog.i18n.DateTimePatterns_ja_JP', 'goog.i18n.DateTimePatterns_jgo', 'goog.i18n.DateTimePatterns_jgo_CM', 'goog.i18n.DateTimePatterns_jmc', 'goog.i18n.DateTimePatterns_jmc_TZ', 'goog.i18n.DateTimePatterns_ka_GE', 'goog.i18n.DateTimePatterns_kab', 'goog.i18n.DateTimePatterns_kab_DZ', 'goog.i18n.DateTimePatterns_kam', 'goog.i18n.DateTimePatterns_kam_KE', 'goog.i18n.DateTimePatterns_kde', 'goog.i18n.DateTimePatterns_kde_TZ', 'goog.i18n.DateTimePatterns_kea', 'goog.i18n.DateTimePatterns_kea_CV', 'goog.i18n.DateTimePatterns_khq', 'goog.i18n.DateTimePatterns_khq_ML', 'goog.i18n.DateTimePatterns_ki', 'goog.i18n.DateTimePatterns_ki_KE', 'goog.i18n.DateTimePatterns_kk_KZ', 'goog.i18n.DateTimePatterns_kkj', 'goog.i18n.DateTimePatterns_kkj_CM', 'goog.i18n.DateTimePatterns_kl', 'goog.i18n.DateTimePatterns_kl_GL', 'goog.i18n.DateTimePatterns_kln', 'goog.i18n.DateTimePatterns_kln_KE', 'goog.i18n.DateTimePatterns_km_KH', 'goog.i18n.DateTimePatterns_kn_IN', 'goog.i18n.DateTimePatterns_ko_KP', 'goog.i18n.DateTimePatterns_ko_KR', 'goog.i18n.DateTimePatterns_kok', 'goog.i18n.DateTimePatterns_kok_IN', 'goog.i18n.DateTimePatterns_ks', 'goog.i18n.DateTimePatterns_ks_IN', 'goog.i18n.DateTimePatterns_ksb', 'goog.i18n.DateTimePatterns_ksb_TZ', 'goog.i18n.DateTimePatterns_ksf', 'goog.i18n.DateTimePatterns_ksf_CM', 'goog.i18n.DateTimePatterns_ksh', 'goog.i18n.DateTimePatterns_ksh_DE', 'goog.i18n.DateTimePatterns_kw', 'goog.i18n.DateTimePatterns_kw_GB', 'goog.i18n.DateTimePatterns_ky_KG', 'goog.i18n.DateTimePatterns_lag', 'goog.i18n.DateTimePatterns_lag_TZ', 'goog.i18n.DateTimePatterns_lb', 'goog.i18n.DateTimePatterns_lb_LU', 'goog.i18n.DateTimePatterns_lg', 'goog.i18n.DateTimePatterns_lg_UG', 'goog.i18n.DateTimePatterns_lkt', 'goog.i18n.DateTimePatterns_lkt_US', 'goog.i18n.DateTimePatterns_ln_AO', 'goog.i18n.DateTimePatterns_ln_CD', 'goog.i18n.DateTimePatterns_ln_CF', 'goog.i18n.DateTimePatterns_ln_CG', 'goog.i18n.DateTimePatterns_lo_LA', 'goog.i18n.DateTimePatterns_lrc', 'goog.i18n.DateTimePatterns_lrc_IQ', 'goog.i18n.DateTimePatterns_lrc_IR', 'goog.i18n.DateTimePatterns_lt_LT', 'goog.i18n.DateTimePatterns_lu', 'goog.i18n.DateTimePatterns_lu_CD', 'goog.i18n.DateTimePatterns_luo', 'goog.i18n.DateTimePatterns_luo_KE', 'goog.i18n.DateTimePatterns_luy', 'goog.i18n.DateTimePatterns_luy_KE', 'goog.i18n.DateTimePatterns_lv_LV', 'goog.i18n.DateTimePatterns_mas', 'goog.i18n.DateTimePatterns_mas_KE', 'goog.i18n.DateTimePatterns_mas_TZ', 'goog.i18n.DateTimePatterns_mer', 'goog.i18n.DateTimePatterns_mer_KE', 'goog.i18n.DateTimePatterns_mfe', 'goog.i18n.DateTimePatterns_mfe_MU', 'goog.i18n.DateTimePatterns_mg', 'goog.i18n.DateTimePatterns_mg_MG', 'goog.i18n.DateTimePatterns_mgh', 'goog.i18n.DateTimePatterns_mgh_MZ', 'goog.i18n.DateTimePatterns_mgo', 'goog.i18n.DateTimePatterns_mgo_CM', 'goog.i18n.DateTimePatterns_mk_MK', 'goog.i18n.DateTimePatterns_ml_IN', 'goog.i18n.DateTimePatterns_mn_MN', 'goog.i18n.DateTimePatterns_mr_IN', 'goog.i18n.DateTimePatterns_ms_BN', 'goog.i18n.DateTimePatterns_ms_MY', 'goog.i18n.DateTimePatterns_ms_SG', 'goog.i18n.DateTimePatterns_mt_MT', 'goog.i18n.DateTimePatterns_mua', 'goog.i18n.DateTimePatterns_mua_CM', 'goog.i18n.DateTimePatterns_my_MM', 'goog.i18n.DateTimePatterns_mzn', 'goog.i18n.DateTimePatterns_mzn_IR', 'goog.i18n.DateTimePatterns_naq', 'goog.i18n.DateTimePatterns_naq_NA', 'goog.i18n.DateTimePatterns_nb_NO', 'goog.i18n.DateTimePatterns_nb_SJ', 'goog.i18n.DateTimePatterns_nd', 'goog.i18n.DateTimePatterns_nd_ZW', 'goog.i18n.DateTimePatterns_nds', 'goog.i18n.DateTimePatterns_nds_DE', 'goog.i18n.DateTimePatterns_nds_NL', 'goog.i18n.DateTimePatterns_ne_IN', 'goog.i18n.DateTimePatterns_ne_NP', 'goog.i18n.DateTimePatterns_nl_AW', 'goog.i18n.DateTimePatterns_nl_BE', 'goog.i18n.DateTimePatterns_nl_BQ', 'goog.i18n.DateTimePatterns_nl_CW', 'goog.i18n.DateTimePatterns_nl_NL', 'goog.i18n.DateTimePatterns_nl_SR', 'goog.i18n.DateTimePatterns_nl_SX', 'goog.i18n.DateTimePatterns_nmg', 'goog.i18n.DateTimePatterns_nmg_CM', 'goog.i18n.DateTimePatterns_nn', 'goog.i18n.DateTimePatterns_nn_NO', 'goog.i18n.DateTimePatterns_nnh', 'goog.i18n.DateTimePatterns_nnh_CM', 'goog.i18n.DateTimePatterns_nus', 'goog.i18n.DateTimePatterns_nus_SS', 'goog.i18n.DateTimePatterns_nyn', 'goog.i18n.DateTimePatterns_nyn_UG', 'goog.i18n.DateTimePatterns_om', 'goog.i18n.DateTimePatterns_om_ET', 'goog.i18n.DateTimePatterns_om_KE', 'goog.i18n.DateTimePatterns_or_IN', 'goog.i18n.DateTimePatterns_os', 'goog.i18n.DateTimePatterns_os_GE', 'goog.i18n.DateTimePatterns_os_RU', 'goog.i18n.DateTimePatterns_pa_Arab', 'goog.i18n.DateTimePatterns_pa_Arab_PK', 'goog.i18n.DateTimePatterns_pa_Guru', 'goog.i18n.DateTimePatterns_pa_Guru_IN', 'goog.i18n.DateTimePatterns_pl_PL', 'goog.i18n.DateTimePatterns_ps', 'goog.i18n.DateTimePatterns_ps_AF', 'goog.i18n.DateTimePatterns_pt_AO', 'goog.i18n.DateTimePatterns_pt_CH', 'goog.i18n.DateTimePatterns_pt_CV', 'goog.i18n.DateTimePatterns_pt_GQ', 'goog.i18n.DateTimePatterns_pt_GW', 'goog.i18n.DateTimePatterns_pt_LU', 'goog.i18n.DateTimePatterns_pt_MO', 'goog.i18n.DateTimePatterns_pt_MZ', 'goog.i18n.DateTimePatterns_pt_ST', 'goog.i18n.DateTimePatterns_pt_TL', 'goog.i18n.DateTimePatterns_qu', 'goog.i18n.DateTimePatterns_qu_BO', 'goog.i18n.DateTimePatterns_qu_EC', 'goog.i18n.DateTimePatterns_qu_PE', 'goog.i18n.DateTimePatterns_rm', 'goog.i18n.DateTimePatterns_rm_CH', 'goog.i18n.DateTimePatterns_rn', 'goog.i18n.DateTimePatterns_rn_BI', 'goog.i18n.DateTimePatterns_ro_MD', 'goog.i18n.DateTimePatterns_ro_RO', 'goog.i18n.DateTimePatterns_rof', 'goog.i18n.DateTimePatterns_rof_TZ', 'goog.i18n.DateTimePatterns_ru_BY', 'goog.i18n.DateTimePatterns_ru_KG', 'goog.i18n.DateTimePatterns_ru_KZ', 'goog.i18n.DateTimePatterns_ru_MD', 'goog.i18n.DateTimePatterns_ru_RU', 'goog.i18n.DateTimePatterns_ru_UA', 'goog.i18n.DateTimePatterns_rw', 'goog.i18n.DateTimePatterns_rw_RW', 'goog.i18n.DateTimePatterns_rwk', 'goog.i18n.DateTimePatterns_rwk_TZ', 'goog.i18n.DateTimePatterns_sah', 'goog.i18n.DateTimePatterns_sah_RU', 'goog.i18n.DateTimePatterns_saq', 'goog.i18n.DateTimePatterns_saq_KE', 'goog.i18n.DateTimePatterns_sbp', 'goog.i18n.DateTimePatterns_sbp_TZ', 'goog.i18n.DateTimePatterns_se', 'goog.i18n.DateTimePatterns_se_FI', 'goog.i18n.DateTimePatterns_se_NO', 'goog.i18n.DateTimePatterns_se_SE', 'goog.i18n.DateTimePatterns_seh', 'goog.i18n.DateTimePatterns_seh_MZ', 'goog.i18n.DateTimePatterns_ses', 'goog.i18n.DateTimePatterns_ses_ML', 'goog.i18n.DateTimePatterns_sg', 'goog.i18n.DateTimePatterns_sg_CF', 'goog.i18n.DateTimePatterns_shi', 'goog.i18n.DateTimePatterns_shi_Latn', 'goog.i18n.DateTimePatterns_shi_Latn_MA', 'goog.i18n.DateTimePatterns_shi_Tfng', 'goog.i18n.DateTimePatterns_shi_Tfng_MA', 'goog.i18n.DateTimePatterns_si_LK', 'goog.i18n.DateTimePatterns_sk_SK', 'goog.i18n.DateTimePatterns_sl_SI', 'goog.i18n.DateTimePatterns_smn', 'goog.i18n.DateTimePatterns_smn_FI', 'goog.i18n.DateTimePatterns_sn', 'goog.i18n.DateTimePatterns_sn_ZW', 'goog.i18n.DateTimePatterns_so', 'goog.i18n.DateTimePatterns_so_DJ', 'goog.i18n.DateTimePatterns_so_ET', 'goog.i18n.DateTimePatterns_so_KE', 'goog.i18n.DateTimePatterns_so_SO', 'goog.i18n.DateTimePatterns_sq_AL', 'goog.i18n.DateTimePatterns_sq_MK', 'goog.i18n.DateTimePatterns_sq_XK', 'goog.i18n.DateTimePatterns_sr_Cyrl', 'goog.i18n.DateTimePatterns_sr_Cyrl_BA', 'goog.i18n.DateTimePatterns_sr_Cyrl_ME', 'goog.i18n.DateTimePatterns_sr_Cyrl_RS', 'goog.i18n.DateTimePatterns_sr_Cyrl_XK', 'goog.i18n.DateTimePatterns_sr_Latn_BA', 'goog.i18n.DateTimePatterns_sr_Latn_ME', 'goog.i18n.DateTimePatterns_sr_Latn_RS', 'goog.i18n.DateTimePatterns_sr_Latn_XK', 'goog.i18n.DateTimePatterns_sv_AX', 'goog.i18n.DateTimePatterns_sv_FI', 'goog.i18n.DateTimePatterns_sv_SE', 'goog.i18n.DateTimePatterns_sw_CD', 'goog.i18n.DateTimePatterns_sw_KE', 'goog.i18n.DateTimePatterns_sw_TZ', 'goog.i18n.DateTimePatterns_sw_UG', 'goog.i18n.DateTimePatterns_ta_IN', 'goog.i18n.DateTimePatterns_ta_LK', 'goog.i18n.DateTimePatterns_ta_MY', 'goog.i18n.DateTimePatterns_ta_SG', 'goog.i18n.DateTimePatterns_te_IN', 'goog.i18n.DateTimePatterns_teo', 'goog.i18n.DateTimePatterns_teo_KE', 'goog.i18n.DateTimePatterns_teo_UG', 'goog.i18n.DateTimePatterns_th_TH', 'goog.i18n.DateTimePatterns_ti', 'goog.i18n.DateTimePatterns_ti_ER', 'goog.i18n.DateTimePatterns_ti_ET', 'goog.i18n.DateTimePatterns_to', 'goog.i18n.DateTimePatterns_to_TO', 'goog.i18n.DateTimePatterns_tr_CY', 'goog.i18n.DateTimePatterns_tr_TR', 'goog.i18n.DateTimePatterns_twq', 'goog.i18n.DateTimePatterns_twq_NE', 'goog.i18n.DateTimePatterns_tzm', 'goog.i18n.DateTimePatterns_tzm_MA', 'goog.i18n.DateTimePatterns_ug', 'goog.i18n.DateTimePatterns_ug_CN', 'goog.i18n.DateTimePatterns_uk_UA', 'goog.i18n.DateTimePatterns_ur_IN', 'goog.i18n.DateTimePatterns_ur_PK', 'goog.i18n.DateTimePatterns_uz_Arab', 'goog.i18n.DateTimePatterns_uz_Arab_AF', 'goog.i18n.DateTimePatterns_uz_Cyrl', 'goog.i18n.DateTimePatterns_uz_Cyrl_UZ', 'goog.i18n.DateTimePatterns_uz_Latn', 'goog.i18n.DateTimePatterns_uz_Latn_UZ', 'goog.i18n.DateTimePatterns_vai', 'goog.i18n.DateTimePatterns_vai_Latn', 'goog.i18n.DateTimePatterns_vai_Latn_LR', 'goog.i18n.DateTimePatterns_vai_Vaii', 'goog.i18n.DateTimePatterns_vai_Vaii_LR', 'goog.i18n.DateTimePatterns_vi_VN', 'goog.i18n.DateTimePatterns_vun', 'goog.i18n.DateTimePatterns_vun_TZ', 'goog.i18n.DateTimePatterns_wae', 'goog.i18n.DateTimePatterns_wae_CH', 'goog.i18n.DateTimePatterns_xog', 'goog.i18n.DateTimePatterns_xog_UG', 'goog.i18n.DateTimePatterns_yav', 'goog.i18n.DateTimePatterns_yav_CM', 'goog.i18n.DateTimePatterns_yi', 'goog.i18n.DateTimePatterns_yi_001', 'goog.i18n.DateTimePatterns_yo', 'goog.i18n.DateTimePatterns_yo_BJ', 'goog.i18n.DateTimePatterns_yo_NG', 'goog.i18n.DateTimePatterns_yue', 'goog.i18n.DateTimePatterns_yue_HK', 'goog.i18n.DateTimePatterns_zgh', 'goog.i18n.DateTimePatterns_zgh_MA', 'goog.i18n.DateTimePatterns_zh_Hans', 'goog.i18n.DateTimePatterns_zh_Hans_CN', 'goog.i18n.DateTimePatterns_zh_Hans_HK', 'goog.i18n.DateTimePatterns_zh_Hans_MO', 'goog.i18n.DateTimePatterns_zh_Hans_SG', 'goog.i18n.DateTimePatterns_zh_Hant', 'goog.i18n.DateTimePatterns_zh_Hant_HK', 'goog.i18n.DateTimePatterns_zh_Hant_MO', 'goog.i18n.DateTimePatterns_zh_Hant_TW', 'goog.i18n.DateTimePatterns_zu_ZA'], ['goog.i18n.DateTimePatterns']);
                +goog.addDependency("i18n/datetimesymbols.js", ['goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbolsType', 'goog.i18n.DateTimeSymbols_en_ISO', 'goog.i18n.DateTimeSymbols_af', 'goog.i18n.DateTimeSymbols_am', 'goog.i18n.DateTimeSymbols_ar', 'goog.i18n.DateTimeSymbols_ar_DZ', 'goog.i18n.DateTimeSymbols_az', 'goog.i18n.DateTimeSymbols_be', 'goog.i18n.DateTimeSymbols_bg', 'goog.i18n.DateTimeSymbols_bn', 'goog.i18n.DateTimeSymbols_br', 'goog.i18n.DateTimeSymbols_bs', 'goog.i18n.DateTimeSymbols_ca', 'goog.i18n.DateTimeSymbols_chr', 'goog.i18n.DateTimeSymbols_cs', 'goog.i18n.DateTimeSymbols_cy', 'goog.i18n.DateTimeSymbols_da', 'goog.i18n.DateTimeSymbols_de', 'goog.i18n.DateTimeSymbols_de_AT', 'goog.i18n.DateTimeSymbols_de_CH', 'goog.i18n.DateTimeSymbols_el', 'goog.i18n.DateTimeSymbols_en', 'goog.i18n.DateTimeSymbols_en_AU', 'goog.i18n.DateTimeSymbols_en_CA', 'goog.i18n.DateTimeSymbols_en_GB', 'goog.i18n.DateTimeSymbols_en_IE', 'goog.i18n.DateTimeSymbols_en_IN', 'goog.i18n.DateTimeSymbols_en_SG', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_en_ZA', 'goog.i18n.DateTimeSymbols_es', 'goog.i18n.DateTimeSymbols_es_419', 'goog.i18n.DateTimeSymbols_es_ES', 'goog.i18n.DateTimeSymbols_es_MX', 'goog.i18n.DateTimeSymbols_es_US', 'goog.i18n.DateTimeSymbols_et', 'goog.i18n.DateTimeSymbols_eu', 'goog.i18n.DateTimeSymbols_fa', 'goog.i18n.DateTimeSymbols_fi', 'goog.i18n.DateTimeSymbols_fil', 'goog.i18n.DateTimeSymbols_fr', 'goog.i18n.DateTimeSymbols_fr_CA', 'goog.i18n.DateTimeSymbols_ga', 'goog.i18n.DateTimeSymbols_gl', 'goog.i18n.DateTimeSymbols_gsw', 'goog.i18n.DateTimeSymbols_gu', 'goog.i18n.DateTimeSymbols_haw', 'goog.i18n.DateTimeSymbols_he', 'goog.i18n.DateTimeSymbols_hi', 'goog.i18n.DateTimeSymbols_hr', 'goog.i18n.DateTimeSymbols_hu', 'goog.i18n.DateTimeSymbols_hy', 'goog.i18n.DateTimeSymbols_id', 'goog.i18n.DateTimeSymbols_in', 'goog.i18n.DateTimeSymbols_is', 'goog.i18n.DateTimeSymbols_it', 'goog.i18n.DateTimeSymbols_iw', 'goog.i18n.DateTimeSymbols_ja', 'goog.i18n.DateTimeSymbols_ka', 'goog.i18n.DateTimeSymbols_kk', 'goog.i18n.DateTimeSymbols_km', 'goog.i18n.DateTimeSymbols_kn', 'goog.i18n.DateTimeSymbols_ko', 'goog.i18n.DateTimeSymbols_ky', 'goog.i18n.DateTimeSymbols_ln', 'goog.i18n.DateTimeSymbols_lo', 'goog.i18n.DateTimeSymbols_lt', 'goog.i18n.DateTimeSymbols_lv', 'goog.i18n.DateTimeSymbols_mk', 'goog.i18n.DateTimeSymbols_ml', 'goog.i18n.DateTimeSymbols_mn', 'goog.i18n.DateTimeSymbols_mo', 'goog.i18n.DateTimeSymbols_mr', 'goog.i18n.DateTimeSymbols_ms', 'goog.i18n.DateTimeSymbols_mt', 'goog.i18n.DateTimeSymbols_my', 'goog.i18n.DateTimeSymbols_nb', 'goog.i18n.DateTimeSymbols_ne', 'goog.i18n.DateTimeSymbols_nl', 'goog.i18n.DateTimeSymbols_no', 'goog.i18n.DateTimeSymbols_no_NO', 'goog.i18n.DateTimeSymbols_or', 'goog.i18n.DateTimeSymbols_pa', 'goog.i18n.DateTimeSymbols_pl', 'goog.i18n.DateTimeSymbols_pt', 'goog.i18n.DateTimeSymbols_pt_BR', 'goog.i18n.DateTimeSymbols_pt_PT', 'goog.i18n.DateTimeSymbols_ro', 'goog.i18n.DateTimeSymbols_ru', 'goog.i18n.DateTimeSymbols_sh', 'goog.i18n.DateTimeSymbols_si', 'goog.i18n.DateTimeSymbols_sk', 'goog.i18n.DateTimeSymbols_sl', 'goog.i18n.DateTimeSymbols_sq', 'goog.i18n.DateTimeSymbols_sr', 'goog.i18n.DateTimeSymbols_sr_Latn', 'goog.i18n.DateTimeSymbols_sv', 'goog.i18n.DateTimeSymbols_sw', 'goog.i18n.DateTimeSymbols_ta', 'goog.i18n.DateTimeSymbols_te', 'goog.i18n.DateTimeSymbols_th', 'goog.i18n.DateTimeSymbols_tl', 'goog.i18n.DateTimeSymbols_tr', 'goog.i18n.DateTimeSymbols_uk', 'goog.i18n.DateTimeSymbols_ur', 'goog.i18n.DateTimeSymbols_uz', 'goog.i18n.DateTimeSymbols_vi', 'goog.i18n.DateTimeSymbols_zh', 'goog.i18n.DateTimeSymbols_zh_CN', 'goog.i18n.DateTimeSymbols_zh_HK', 'goog.i18n.DateTimeSymbols_zh_TW', 'goog.i18n.DateTimeSymbols_zu'], []);
                +goog.addDependency("i18n/datetimesymbolsext.js", ['goog.i18n.DateTimeSymbolsExt', 'goog.i18n.DateTimeSymbols_af_NA', 'goog.i18n.DateTimeSymbols_af_ZA', 'goog.i18n.DateTimeSymbols_agq', 'goog.i18n.DateTimeSymbols_agq_CM', 'goog.i18n.DateTimeSymbols_ak', 'goog.i18n.DateTimeSymbols_ak_GH', 'goog.i18n.DateTimeSymbols_am_ET', 'goog.i18n.DateTimeSymbols_ar_001', 'goog.i18n.DateTimeSymbols_ar_AE', 'goog.i18n.DateTimeSymbols_ar_BH', 'goog.i18n.DateTimeSymbols_ar_DJ', 'goog.i18n.DateTimeSymbols_ar_EG', 'goog.i18n.DateTimeSymbols_ar_EH', 'goog.i18n.DateTimeSymbols_ar_ER', 'goog.i18n.DateTimeSymbols_ar_IL', 'goog.i18n.DateTimeSymbols_ar_IQ', 'goog.i18n.DateTimeSymbols_ar_JO', 'goog.i18n.DateTimeSymbols_ar_KM', 'goog.i18n.DateTimeSymbols_ar_KW', 'goog.i18n.DateTimeSymbols_ar_LB', 'goog.i18n.DateTimeSymbols_ar_LY', 'goog.i18n.DateTimeSymbols_ar_MA', 'goog.i18n.DateTimeSymbols_ar_MR', 'goog.i18n.DateTimeSymbols_ar_OM', 'goog.i18n.DateTimeSymbols_ar_PS', 'goog.i18n.DateTimeSymbols_ar_QA', 'goog.i18n.DateTimeSymbols_ar_SA', 'goog.i18n.DateTimeSymbols_ar_SD', 'goog.i18n.DateTimeSymbols_ar_SO', 'goog.i18n.DateTimeSymbols_ar_SS', 'goog.i18n.DateTimeSymbols_ar_SY', 'goog.i18n.DateTimeSymbols_ar_TD', 'goog.i18n.DateTimeSymbols_ar_TN', 'goog.i18n.DateTimeSymbols_ar_XB', 'goog.i18n.DateTimeSymbols_ar_YE', 'goog.i18n.DateTimeSymbols_as', 'goog.i18n.DateTimeSymbols_as_IN', 'goog.i18n.DateTimeSymbols_asa', 'goog.i18n.DateTimeSymbols_asa_TZ', 'goog.i18n.DateTimeSymbols_ast', 'goog.i18n.DateTimeSymbols_ast_ES', 'goog.i18n.DateTimeSymbols_az_Cyrl', 'goog.i18n.DateTimeSymbols_az_Cyrl_AZ', 'goog.i18n.DateTimeSymbols_az_Latn', 'goog.i18n.DateTimeSymbols_az_Latn_AZ', 'goog.i18n.DateTimeSymbols_bas', 'goog.i18n.DateTimeSymbols_bas_CM', 'goog.i18n.DateTimeSymbols_be_BY', 'goog.i18n.DateTimeSymbols_bem', 'goog.i18n.DateTimeSymbols_bem_ZM', 'goog.i18n.DateTimeSymbols_bez', 'goog.i18n.DateTimeSymbols_bez_TZ', 'goog.i18n.DateTimeSymbols_bg_BG', 'goog.i18n.DateTimeSymbols_bm', 'goog.i18n.DateTimeSymbols_bm_ML', 'goog.i18n.DateTimeSymbols_bn_BD', 'goog.i18n.DateTimeSymbols_bn_IN', 'goog.i18n.DateTimeSymbols_bo', 'goog.i18n.DateTimeSymbols_bo_CN', 'goog.i18n.DateTimeSymbols_bo_IN', 'goog.i18n.DateTimeSymbols_br_FR', 'goog.i18n.DateTimeSymbols_brx', 'goog.i18n.DateTimeSymbols_brx_IN', 'goog.i18n.DateTimeSymbols_bs_Cyrl', 'goog.i18n.DateTimeSymbols_bs_Cyrl_BA', 'goog.i18n.DateTimeSymbols_bs_Latn', 'goog.i18n.DateTimeSymbols_bs_Latn_BA', 'goog.i18n.DateTimeSymbols_ca_AD', 'goog.i18n.DateTimeSymbols_ca_ES', 'goog.i18n.DateTimeSymbols_ca_FR', 'goog.i18n.DateTimeSymbols_ca_IT', 'goog.i18n.DateTimeSymbols_ce', 'goog.i18n.DateTimeSymbols_ce_RU', 'goog.i18n.DateTimeSymbols_cgg', 'goog.i18n.DateTimeSymbols_cgg_UG', 'goog.i18n.DateTimeSymbols_chr_US', 'goog.i18n.DateTimeSymbols_ckb', 'goog.i18n.DateTimeSymbols_ckb_IQ', 'goog.i18n.DateTimeSymbols_ckb_IR', 'goog.i18n.DateTimeSymbols_cs_CZ', 'goog.i18n.DateTimeSymbols_cy_GB', 'goog.i18n.DateTimeSymbols_da_DK', 'goog.i18n.DateTimeSymbols_da_GL', 'goog.i18n.DateTimeSymbols_dav', 'goog.i18n.DateTimeSymbols_dav_KE', 'goog.i18n.DateTimeSymbols_de_BE', 'goog.i18n.DateTimeSymbols_de_DE', 'goog.i18n.DateTimeSymbols_de_IT', 'goog.i18n.DateTimeSymbols_de_LI', 'goog.i18n.DateTimeSymbols_de_LU', 'goog.i18n.DateTimeSymbols_dje', 'goog.i18n.DateTimeSymbols_dje_NE', 'goog.i18n.DateTimeSymbols_dsb', 'goog.i18n.DateTimeSymbols_dsb_DE', 'goog.i18n.DateTimeSymbols_dua', 'goog.i18n.DateTimeSymbols_dua_CM', 'goog.i18n.DateTimeSymbols_dyo', 'goog.i18n.DateTimeSymbols_dyo_SN', 'goog.i18n.DateTimeSymbols_dz', 'goog.i18n.DateTimeSymbols_dz_BT', 'goog.i18n.DateTimeSymbols_ebu', 'goog.i18n.DateTimeSymbols_ebu_KE', 'goog.i18n.DateTimeSymbols_ee', 'goog.i18n.DateTimeSymbols_ee_GH', 'goog.i18n.DateTimeSymbols_ee_TG', 'goog.i18n.DateTimeSymbols_el_CY', 'goog.i18n.DateTimeSymbols_el_GR', 'goog.i18n.DateTimeSymbols_en_001', 'goog.i18n.DateTimeSymbols_en_150', 'goog.i18n.DateTimeSymbols_en_AG', 'goog.i18n.DateTimeSymbols_en_AI', 'goog.i18n.DateTimeSymbols_en_AS', 'goog.i18n.DateTimeSymbols_en_AT', 'goog.i18n.DateTimeSymbols_en_BB', 'goog.i18n.DateTimeSymbols_en_BE', 'goog.i18n.DateTimeSymbols_en_BI', 'goog.i18n.DateTimeSymbols_en_BM', 'goog.i18n.DateTimeSymbols_en_BS', 'goog.i18n.DateTimeSymbols_en_BW', 'goog.i18n.DateTimeSymbols_en_BZ', 'goog.i18n.DateTimeSymbols_en_CC', 'goog.i18n.DateTimeSymbols_en_CH', 'goog.i18n.DateTimeSymbols_en_CK', 'goog.i18n.DateTimeSymbols_en_CM', 'goog.i18n.DateTimeSymbols_en_CX', 'goog.i18n.DateTimeSymbols_en_CY', 'goog.i18n.DateTimeSymbols_en_DE', 'goog.i18n.DateTimeSymbols_en_DG', 'goog.i18n.DateTimeSymbols_en_DK', 'goog.i18n.DateTimeSymbols_en_DM', 'goog.i18n.DateTimeSymbols_en_ER', 'goog.i18n.DateTimeSymbols_en_FI', 'goog.i18n.DateTimeSymbols_en_FJ', 'goog.i18n.DateTimeSymbols_en_FK', 'goog.i18n.DateTimeSymbols_en_FM', 'goog.i18n.DateTimeSymbols_en_GD', 'goog.i18n.DateTimeSymbols_en_GG', 'goog.i18n.DateTimeSymbols_en_GH', 'goog.i18n.DateTimeSymbols_en_GI', 'goog.i18n.DateTimeSymbols_en_GM', 'goog.i18n.DateTimeSymbols_en_GU', 'goog.i18n.DateTimeSymbols_en_GY', 'goog.i18n.DateTimeSymbols_en_HK', 'goog.i18n.DateTimeSymbols_en_IL', 'goog.i18n.DateTimeSymbols_en_IM', 'goog.i18n.DateTimeSymbols_en_IO', 'goog.i18n.DateTimeSymbols_en_JE', 'goog.i18n.DateTimeSymbols_en_JM', 'goog.i18n.DateTimeSymbols_en_KE', 'goog.i18n.DateTimeSymbols_en_KI', 'goog.i18n.DateTimeSymbols_en_KN', 'goog.i18n.DateTimeSymbols_en_KY', 'goog.i18n.DateTimeSymbols_en_LC', 'goog.i18n.DateTimeSymbols_en_LR', 'goog.i18n.DateTimeSymbols_en_LS', 'goog.i18n.DateTimeSymbols_en_MG', 'goog.i18n.DateTimeSymbols_en_MH', 'goog.i18n.DateTimeSymbols_en_MO', 'goog.i18n.DateTimeSymbols_en_MP', 'goog.i18n.DateTimeSymbols_en_MS', 'goog.i18n.DateTimeSymbols_en_MT', 'goog.i18n.DateTimeSymbols_en_MU', 'goog.i18n.DateTimeSymbols_en_MW', 'goog.i18n.DateTimeSymbols_en_MY', 'goog.i18n.DateTimeSymbols_en_NA', 'goog.i18n.DateTimeSymbols_en_NF', 'goog.i18n.DateTimeSymbols_en_NG', 'goog.i18n.DateTimeSymbols_en_NL', 'goog.i18n.DateTimeSymbols_en_NR', 'goog.i18n.DateTimeSymbols_en_NU', 'goog.i18n.DateTimeSymbols_en_NZ', 'goog.i18n.DateTimeSymbols_en_PG', 'goog.i18n.DateTimeSymbols_en_PH', 'goog.i18n.DateTimeSymbols_en_PK', 'goog.i18n.DateTimeSymbols_en_PN', 'goog.i18n.DateTimeSymbols_en_PR', 'goog.i18n.DateTimeSymbols_en_PW', 'goog.i18n.DateTimeSymbols_en_RW', 'goog.i18n.DateTimeSymbols_en_SB', 'goog.i18n.DateTimeSymbols_en_SC', 'goog.i18n.DateTimeSymbols_en_SD', 'goog.i18n.DateTimeSymbols_en_SE', 'goog.i18n.DateTimeSymbols_en_SH', 'goog.i18n.DateTimeSymbols_en_SI', 'goog.i18n.DateTimeSymbols_en_SL', 'goog.i18n.DateTimeSymbols_en_SS', 'goog.i18n.DateTimeSymbols_en_SX', 'goog.i18n.DateTimeSymbols_en_SZ', 'goog.i18n.DateTimeSymbols_en_TC', 'goog.i18n.DateTimeSymbols_en_TK', 'goog.i18n.DateTimeSymbols_en_TO', 'goog.i18n.DateTimeSymbols_en_TT', 'goog.i18n.DateTimeSymbols_en_TV', 'goog.i18n.DateTimeSymbols_en_TZ', 'goog.i18n.DateTimeSymbols_en_UG', 'goog.i18n.DateTimeSymbols_en_UM', 'goog.i18n.DateTimeSymbols_en_US_POSIX', 'goog.i18n.DateTimeSymbols_en_VC', 'goog.i18n.DateTimeSymbols_en_VG', 'goog.i18n.DateTimeSymbols_en_VI', 'goog.i18n.DateTimeSymbols_en_VU', 'goog.i18n.DateTimeSymbols_en_WS', 'goog.i18n.DateTimeSymbols_en_XA', 'goog.i18n.DateTimeSymbols_en_ZM', 'goog.i18n.DateTimeSymbols_en_ZW', 'goog.i18n.DateTimeSymbols_eo', 'goog.i18n.DateTimeSymbols_es_AR', 'goog.i18n.DateTimeSymbols_es_BO', 'goog.i18n.DateTimeSymbols_es_BR', 'goog.i18n.DateTimeSymbols_es_CL', 'goog.i18n.DateTimeSymbols_es_CO', 'goog.i18n.DateTimeSymbols_es_CR', 'goog.i18n.DateTimeSymbols_es_CU', 'goog.i18n.DateTimeSymbols_es_DO', 'goog.i18n.DateTimeSymbols_es_EA', 'goog.i18n.DateTimeSymbols_es_EC', 'goog.i18n.DateTimeSymbols_es_GQ', 'goog.i18n.DateTimeSymbols_es_GT', 'goog.i18n.DateTimeSymbols_es_HN', 'goog.i18n.DateTimeSymbols_es_IC', 'goog.i18n.DateTimeSymbols_es_NI', 'goog.i18n.DateTimeSymbols_es_PA', 'goog.i18n.DateTimeSymbols_es_PE', 'goog.i18n.DateTimeSymbols_es_PH', 'goog.i18n.DateTimeSymbols_es_PR', 'goog.i18n.DateTimeSymbols_es_PY', 'goog.i18n.DateTimeSymbols_es_SV', 'goog.i18n.DateTimeSymbols_es_UY', 'goog.i18n.DateTimeSymbols_es_VE', 'goog.i18n.DateTimeSymbols_et_EE', 'goog.i18n.DateTimeSymbols_eu_ES', 'goog.i18n.DateTimeSymbols_ewo', 'goog.i18n.DateTimeSymbols_ewo_CM', 'goog.i18n.DateTimeSymbols_fa_AF', 'goog.i18n.DateTimeSymbols_fa_IR', 'goog.i18n.DateTimeSymbols_ff', 'goog.i18n.DateTimeSymbols_ff_CM', 'goog.i18n.DateTimeSymbols_ff_GN', 'goog.i18n.DateTimeSymbols_ff_MR', 'goog.i18n.DateTimeSymbols_ff_SN', 'goog.i18n.DateTimeSymbols_fi_FI', 'goog.i18n.DateTimeSymbols_fil_PH', 'goog.i18n.DateTimeSymbols_fo', 'goog.i18n.DateTimeSymbols_fo_DK', 'goog.i18n.DateTimeSymbols_fo_FO', 'goog.i18n.DateTimeSymbols_fr_BE', 'goog.i18n.DateTimeSymbols_fr_BF', 'goog.i18n.DateTimeSymbols_fr_BI', 'goog.i18n.DateTimeSymbols_fr_BJ', 'goog.i18n.DateTimeSymbols_fr_BL', 'goog.i18n.DateTimeSymbols_fr_CD', 'goog.i18n.DateTimeSymbols_fr_CF', 'goog.i18n.DateTimeSymbols_fr_CG', 'goog.i18n.DateTimeSymbols_fr_CH', 'goog.i18n.DateTimeSymbols_fr_CI', 'goog.i18n.DateTimeSymbols_fr_CM', 'goog.i18n.DateTimeSymbols_fr_DJ', 'goog.i18n.DateTimeSymbols_fr_DZ', 'goog.i18n.DateTimeSymbols_fr_FR', 'goog.i18n.DateTimeSymbols_fr_GA', 'goog.i18n.DateTimeSymbols_fr_GF', 'goog.i18n.DateTimeSymbols_fr_GN', 'goog.i18n.DateTimeSymbols_fr_GP', 'goog.i18n.DateTimeSymbols_fr_GQ', 'goog.i18n.DateTimeSymbols_fr_HT', 'goog.i18n.DateTimeSymbols_fr_KM', 'goog.i18n.DateTimeSymbols_fr_LU', 'goog.i18n.DateTimeSymbols_fr_MA', 'goog.i18n.DateTimeSymbols_fr_MC', 'goog.i18n.DateTimeSymbols_fr_MF', 'goog.i18n.DateTimeSymbols_fr_MG', 'goog.i18n.DateTimeSymbols_fr_ML', 'goog.i18n.DateTimeSymbols_fr_MQ', 'goog.i18n.DateTimeSymbols_fr_MR', 'goog.i18n.DateTimeSymbols_fr_MU', 'goog.i18n.DateTimeSymbols_fr_NC', 'goog.i18n.DateTimeSymbols_fr_NE', 'goog.i18n.DateTimeSymbols_fr_PF', 'goog.i18n.DateTimeSymbols_fr_PM', 'goog.i18n.DateTimeSymbols_fr_RE', 'goog.i18n.DateTimeSymbols_fr_RW', 'goog.i18n.DateTimeSymbols_fr_SC', 'goog.i18n.DateTimeSymbols_fr_SN', 'goog.i18n.DateTimeSymbols_fr_SY', 'goog.i18n.DateTimeSymbols_fr_TD', 'goog.i18n.DateTimeSymbols_fr_TG', 'goog.i18n.DateTimeSymbols_fr_TN', 'goog.i18n.DateTimeSymbols_fr_VU', 'goog.i18n.DateTimeSymbols_fr_WF', 'goog.i18n.DateTimeSymbols_fr_YT', 'goog.i18n.DateTimeSymbols_fur', 'goog.i18n.DateTimeSymbols_fur_IT', 'goog.i18n.DateTimeSymbols_fy', 'goog.i18n.DateTimeSymbols_fy_NL', 'goog.i18n.DateTimeSymbols_ga_IE', 'goog.i18n.DateTimeSymbols_gd', 'goog.i18n.DateTimeSymbols_gd_GB', 'goog.i18n.DateTimeSymbols_gl_ES', 'goog.i18n.DateTimeSymbols_gsw_CH', 'goog.i18n.DateTimeSymbols_gsw_FR', 'goog.i18n.DateTimeSymbols_gsw_LI', 'goog.i18n.DateTimeSymbols_gu_IN', 'goog.i18n.DateTimeSymbols_guz', 'goog.i18n.DateTimeSymbols_guz_KE', 'goog.i18n.DateTimeSymbols_gv', 'goog.i18n.DateTimeSymbols_gv_IM', 'goog.i18n.DateTimeSymbols_ha', 'goog.i18n.DateTimeSymbols_ha_GH', 'goog.i18n.DateTimeSymbols_ha_NE', 'goog.i18n.DateTimeSymbols_ha_NG', 'goog.i18n.DateTimeSymbols_haw_US', 'goog.i18n.DateTimeSymbols_he_IL', 'goog.i18n.DateTimeSymbols_hi_IN', 'goog.i18n.DateTimeSymbols_hr_BA', 'goog.i18n.DateTimeSymbols_hr_HR', 'goog.i18n.DateTimeSymbols_hsb', 'goog.i18n.DateTimeSymbols_hsb_DE', 'goog.i18n.DateTimeSymbols_hu_HU', 'goog.i18n.DateTimeSymbols_hy_AM', 'goog.i18n.DateTimeSymbols_id_ID', 'goog.i18n.DateTimeSymbols_ig', 'goog.i18n.DateTimeSymbols_ig_NG', 'goog.i18n.DateTimeSymbols_ii', 'goog.i18n.DateTimeSymbols_ii_CN', 'goog.i18n.DateTimeSymbols_is_IS', 'goog.i18n.DateTimeSymbols_it_CH', 'goog.i18n.DateTimeSymbols_it_IT', 'goog.i18n.DateTimeSymbols_it_SM', 'goog.i18n.DateTimeSymbols_ja_JP', 'goog.i18n.DateTimeSymbols_jgo', 'goog.i18n.DateTimeSymbols_jgo_CM', 'goog.i18n.DateTimeSymbols_jmc', 'goog.i18n.DateTimeSymbols_jmc_TZ', 'goog.i18n.DateTimeSymbols_ka_GE', 'goog.i18n.DateTimeSymbols_kab', 'goog.i18n.DateTimeSymbols_kab_DZ', 'goog.i18n.DateTimeSymbols_kam', 'goog.i18n.DateTimeSymbols_kam_KE', 'goog.i18n.DateTimeSymbols_kde', 'goog.i18n.DateTimeSymbols_kde_TZ', 'goog.i18n.DateTimeSymbols_kea', 'goog.i18n.DateTimeSymbols_kea_CV', 'goog.i18n.DateTimeSymbols_khq', 'goog.i18n.DateTimeSymbols_khq_ML', 'goog.i18n.DateTimeSymbols_ki', 'goog.i18n.DateTimeSymbols_ki_KE', 'goog.i18n.DateTimeSymbols_kk_KZ', 'goog.i18n.DateTimeSymbols_kkj', 'goog.i18n.DateTimeSymbols_kkj_CM', 'goog.i18n.DateTimeSymbols_kl', 'goog.i18n.DateTimeSymbols_kl_GL', 'goog.i18n.DateTimeSymbols_kln', 'goog.i18n.DateTimeSymbols_kln_KE', 'goog.i18n.DateTimeSymbols_km_KH', 'goog.i18n.DateTimeSymbols_kn_IN', 'goog.i18n.DateTimeSymbols_ko_KP', 'goog.i18n.DateTimeSymbols_ko_KR', 'goog.i18n.DateTimeSymbols_kok', 'goog.i18n.DateTimeSymbols_kok_IN', 'goog.i18n.DateTimeSymbols_ks', 'goog.i18n.DateTimeSymbols_ks_IN', 'goog.i18n.DateTimeSymbols_ksb', 'goog.i18n.DateTimeSymbols_ksb_TZ', 'goog.i18n.DateTimeSymbols_ksf', 'goog.i18n.DateTimeSymbols_ksf_CM', 'goog.i18n.DateTimeSymbols_ksh', 'goog.i18n.DateTimeSymbols_ksh_DE', 'goog.i18n.DateTimeSymbols_kw', 'goog.i18n.DateTimeSymbols_kw_GB', 'goog.i18n.DateTimeSymbols_ky_KG', 'goog.i18n.DateTimeSymbols_lag', 'goog.i18n.DateTimeSymbols_lag_TZ', 'goog.i18n.DateTimeSymbols_lb', 'goog.i18n.DateTimeSymbols_lb_LU', 'goog.i18n.DateTimeSymbols_lg', 'goog.i18n.DateTimeSymbols_lg_UG', 'goog.i18n.DateTimeSymbols_lkt', 'goog.i18n.DateTimeSymbols_lkt_US', 'goog.i18n.DateTimeSymbols_ln_AO', 'goog.i18n.DateTimeSymbols_ln_CD', 'goog.i18n.DateTimeSymbols_ln_CF', 'goog.i18n.DateTimeSymbols_ln_CG', 'goog.i18n.DateTimeSymbols_lo_LA', 'goog.i18n.DateTimeSymbols_lrc', 'goog.i18n.DateTimeSymbols_lrc_IQ', 'goog.i18n.DateTimeSymbols_lrc_IR', 'goog.i18n.DateTimeSymbols_lt_LT', 'goog.i18n.DateTimeSymbols_lu', 'goog.i18n.DateTimeSymbols_lu_CD', 'goog.i18n.DateTimeSymbols_luo', 'goog.i18n.DateTimeSymbols_luo_KE', 'goog.i18n.DateTimeSymbols_luy', 'goog.i18n.DateTimeSymbols_luy_KE', 'goog.i18n.DateTimeSymbols_lv_LV', 'goog.i18n.DateTimeSymbols_mas', 'goog.i18n.DateTimeSymbols_mas_KE', 'goog.i18n.DateTimeSymbols_mas_TZ', 'goog.i18n.DateTimeSymbols_mer', 'goog.i18n.DateTimeSymbols_mer_KE', 'goog.i18n.DateTimeSymbols_mfe', 'goog.i18n.DateTimeSymbols_mfe_MU', 'goog.i18n.DateTimeSymbols_mg', 'goog.i18n.DateTimeSymbols_mg_MG', 'goog.i18n.DateTimeSymbols_mgh', 'goog.i18n.DateTimeSymbols_mgh_MZ', 'goog.i18n.DateTimeSymbols_mgo', 'goog.i18n.DateTimeSymbols_mgo_CM', 'goog.i18n.DateTimeSymbols_mk_MK', 'goog.i18n.DateTimeSymbols_ml_IN', 'goog.i18n.DateTimeSymbols_mn_MN', 'goog.i18n.DateTimeSymbols_mr_IN', 'goog.i18n.DateTimeSymbols_ms_BN', 'goog.i18n.DateTimeSymbols_ms_MY', 'goog.i18n.DateTimeSymbols_ms_SG', 'goog.i18n.DateTimeSymbols_mt_MT', 'goog.i18n.DateTimeSymbols_mua', 'goog.i18n.DateTimeSymbols_mua_CM', 'goog.i18n.DateTimeSymbols_my_MM', 'goog.i18n.DateTimeSymbols_mzn', 'goog.i18n.DateTimeSymbols_mzn_IR', 'goog.i18n.DateTimeSymbols_naq', 'goog.i18n.DateTimeSymbols_naq_NA', 'goog.i18n.DateTimeSymbols_nb_NO', 'goog.i18n.DateTimeSymbols_nb_SJ', 'goog.i18n.DateTimeSymbols_nd', 'goog.i18n.DateTimeSymbols_nd_ZW', 'goog.i18n.DateTimeSymbols_nds', 'goog.i18n.DateTimeSymbols_nds_DE', 'goog.i18n.DateTimeSymbols_nds_NL', 'goog.i18n.DateTimeSymbols_ne_IN', 'goog.i18n.DateTimeSymbols_ne_NP', 'goog.i18n.DateTimeSymbols_nl_AW', 'goog.i18n.DateTimeSymbols_nl_BE', 'goog.i18n.DateTimeSymbols_nl_BQ', 'goog.i18n.DateTimeSymbols_nl_CW', 'goog.i18n.DateTimeSymbols_nl_NL', 'goog.i18n.DateTimeSymbols_nl_SR', 'goog.i18n.DateTimeSymbols_nl_SX', 'goog.i18n.DateTimeSymbols_nmg', 'goog.i18n.DateTimeSymbols_nmg_CM', 'goog.i18n.DateTimeSymbols_nn', 'goog.i18n.DateTimeSymbols_nn_NO', 'goog.i18n.DateTimeSymbols_nnh', 'goog.i18n.DateTimeSymbols_nnh_CM', 'goog.i18n.DateTimeSymbols_nus', 'goog.i18n.DateTimeSymbols_nus_SS', 'goog.i18n.DateTimeSymbols_nyn', 'goog.i18n.DateTimeSymbols_nyn_UG', 'goog.i18n.DateTimeSymbols_om', 'goog.i18n.DateTimeSymbols_om_ET', 'goog.i18n.DateTimeSymbols_om_KE', 'goog.i18n.DateTimeSymbols_or_IN', 'goog.i18n.DateTimeSymbols_os', 'goog.i18n.DateTimeSymbols_os_GE', 'goog.i18n.DateTimeSymbols_os_RU', 'goog.i18n.DateTimeSymbols_pa_Arab', 'goog.i18n.DateTimeSymbols_pa_Arab_PK', 'goog.i18n.DateTimeSymbols_pa_Guru', 'goog.i18n.DateTimeSymbols_pa_Guru_IN', 'goog.i18n.DateTimeSymbols_pl_PL', 'goog.i18n.DateTimeSymbols_ps', 'goog.i18n.DateTimeSymbols_ps_AF', 'goog.i18n.DateTimeSymbols_pt_AO', 'goog.i18n.DateTimeSymbols_pt_CH', 'goog.i18n.DateTimeSymbols_pt_CV', 'goog.i18n.DateTimeSymbols_pt_GQ', 'goog.i18n.DateTimeSymbols_pt_GW', 'goog.i18n.DateTimeSymbols_pt_LU', 'goog.i18n.DateTimeSymbols_pt_MO', 'goog.i18n.DateTimeSymbols_pt_MZ', 'goog.i18n.DateTimeSymbols_pt_ST', 'goog.i18n.DateTimeSymbols_pt_TL', 'goog.i18n.DateTimeSymbols_qu', 'goog.i18n.DateTimeSymbols_qu_BO', 'goog.i18n.DateTimeSymbols_qu_EC', 'goog.i18n.DateTimeSymbols_qu_PE', 'goog.i18n.DateTimeSymbols_rm', 'goog.i18n.DateTimeSymbols_rm_CH', 'goog.i18n.DateTimeSymbols_rn', 'goog.i18n.DateTimeSymbols_rn_BI', 'goog.i18n.DateTimeSymbols_ro_MD', 'goog.i18n.DateTimeSymbols_ro_RO', 'goog.i18n.DateTimeSymbols_rof', 'goog.i18n.DateTimeSymbols_rof_TZ', 'goog.i18n.DateTimeSymbols_ru_BY', 'goog.i18n.DateTimeSymbols_ru_KG', 'goog.i18n.DateTimeSymbols_ru_KZ', 'goog.i18n.DateTimeSymbols_ru_MD', 'goog.i18n.DateTimeSymbols_ru_RU', 'goog.i18n.DateTimeSymbols_ru_UA', 'goog.i18n.DateTimeSymbols_rw', 'goog.i18n.DateTimeSymbols_rw_RW', 'goog.i18n.DateTimeSymbols_rwk', 'goog.i18n.DateTimeSymbols_rwk_TZ', 'goog.i18n.DateTimeSymbols_sah', 'goog.i18n.DateTimeSymbols_sah_RU', 'goog.i18n.DateTimeSymbols_saq', 'goog.i18n.DateTimeSymbols_saq_KE', 'goog.i18n.DateTimeSymbols_sbp', 'goog.i18n.DateTimeSymbols_sbp_TZ', 'goog.i18n.DateTimeSymbols_se', 'goog.i18n.DateTimeSymbols_se_FI', 'goog.i18n.DateTimeSymbols_se_NO', 'goog.i18n.DateTimeSymbols_se_SE', 'goog.i18n.DateTimeSymbols_seh', 'goog.i18n.DateTimeSymbols_seh_MZ', 'goog.i18n.DateTimeSymbols_ses', 'goog.i18n.DateTimeSymbols_ses_ML', 'goog.i18n.DateTimeSymbols_sg', 'goog.i18n.DateTimeSymbols_sg_CF', 'goog.i18n.DateTimeSymbols_shi', 'goog.i18n.DateTimeSymbols_shi_Latn', 'goog.i18n.DateTimeSymbols_shi_Latn_MA', 'goog.i18n.DateTimeSymbols_shi_Tfng', 'goog.i18n.DateTimeSymbols_shi_Tfng_MA', 'goog.i18n.DateTimeSymbols_si_LK', 'goog.i18n.DateTimeSymbols_sk_SK', 'goog.i18n.DateTimeSymbols_sl_SI', 'goog.i18n.DateTimeSymbols_smn', 'goog.i18n.DateTimeSymbols_smn_FI', 'goog.i18n.DateTimeSymbols_sn', 'goog.i18n.DateTimeSymbols_sn_ZW', 'goog.i18n.DateTimeSymbols_so', 'goog.i18n.DateTimeSymbols_so_DJ', 'goog.i18n.DateTimeSymbols_so_ET', 'goog.i18n.DateTimeSymbols_so_KE', 'goog.i18n.DateTimeSymbols_so_SO', 'goog.i18n.DateTimeSymbols_sq_AL', 'goog.i18n.DateTimeSymbols_sq_MK', 'goog.i18n.DateTimeSymbols_sq_XK', 'goog.i18n.DateTimeSymbols_sr_Cyrl', 'goog.i18n.DateTimeSymbols_sr_Cyrl_BA', 'goog.i18n.DateTimeSymbols_sr_Cyrl_ME', 'goog.i18n.DateTimeSymbols_sr_Cyrl_RS', 'goog.i18n.DateTimeSymbols_sr_Cyrl_XK', 'goog.i18n.DateTimeSymbols_sr_Latn_BA', 'goog.i18n.DateTimeSymbols_sr_Latn_ME', 'goog.i18n.DateTimeSymbols_sr_Latn_RS', 'goog.i18n.DateTimeSymbols_sr_Latn_XK', 'goog.i18n.DateTimeSymbols_sv_AX', 'goog.i18n.DateTimeSymbols_sv_FI', 'goog.i18n.DateTimeSymbols_sv_SE', 'goog.i18n.DateTimeSymbols_sw_CD', 'goog.i18n.DateTimeSymbols_sw_KE', 'goog.i18n.DateTimeSymbols_sw_TZ', 'goog.i18n.DateTimeSymbols_sw_UG', 'goog.i18n.DateTimeSymbols_ta_IN', 'goog.i18n.DateTimeSymbols_ta_LK', 'goog.i18n.DateTimeSymbols_ta_MY', 'goog.i18n.DateTimeSymbols_ta_SG', 'goog.i18n.DateTimeSymbols_te_IN', 'goog.i18n.DateTimeSymbols_teo', 'goog.i18n.DateTimeSymbols_teo_KE', 'goog.i18n.DateTimeSymbols_teo_UG', 'goog.i18n.DateTimeSymbols_th_TH', 'goog.i18n.DateTimeSymbols_ti', 'goog.i18n.DateTimeSymbols_ti_ER', 'goog.i18n.DateTimeSymbols_ti_ET', 'goog.i18n.DateTimeSymbols_to', 'goog.i18n.DateTimeSymbols_to_TO', 'goog.i18n.DateTimeSymbols_tr_CY', 'goog.i18n.DateTimeSymbols_tr_TR', 'goog.i18n.DateTimeSymbols_twq', 'goog.i18n.DateTimeSymbols_twq_NE', 'goog.i18n.DateTimeSymbols_tzm', 'goog.i18n.DateTimeSymbols_tzm_MA', 'goog.i18n.DateTimeSymbols_ug', 'goog.i18n.DateTimeSymbols_ug_CN', 'goog.i18n.DateTimeSymbols_uk_UA', 'goog.i18n.DateTimeSymbols_ur_IN', 'goog.i18n.DateTimeSymbols_ur_PK', 'goog.i18n.DateTimeSymbols_uz_Arab', 'goog.i18n.DateTimeSymbols_uz_Arab_AF', 'goog.i18n.DateTimeSymbols_uz_Cyrl', 'goog.i18n.DateTimeSymbols_uz_Cyrl_UZ', 'goog.i18n.DateTimeSymbols_uz_Latn', 'goog.i18n.DateTimeSymbols_uz_Latn_UZ', 'goog.i18n.DateTimeSymbols_vai', 'goog.i18n.DateTimeSymbols_vai_Latn', 'goog.i18n.DateTimeSymbols_vai_Latn_LR', 'goog.i18n.DateTimeSymbols_vai_Vaii', 'goog.i18n.DateTimeSymbols_vai_Vaii_LR', 'goog.i18n.DateTimeSymbols_vi_VN', 'goog.i18n.DateTimeSymbols_vun', 'goog.i18n.DateTimeSymbols_vun_TZ', 'goog.i18n.DateTimeSymbols_wae', 'goog.i18n.DateTimeSymbols_wae_CH', 'goog.i18n.DateTimeSymbols_xog', 'goog.i18n.DateTimeSymbols_xog_UG', 'goog.i18n.DateTimeSymbols_yav', 'goog.i18n.DateTimeSymbols_yav_CM', 'goog.i18n.DateTimeSymbols_yi', 'goog.i18n.DateTimeSymbols_yi_001', 'goog.i18n.DateTimeSymbols_yo', 'goog.i18n.DateTimeSymbols_yo_BJ', 'goog.i18n.DateTimeSymbols_yo_NG', 'goog.i18n.DateTimeSymbols_yue', 'goog.i18n.DateTimeSymbols_yue_HK', 'goog.i18n.DateTimeSymbols_zgh', 'goog.i18n.DateTimeSymbols_zgh_MA', 'goog.i18n.DateTimeSymbols_zh_Hans', 'goog.i18n.DateTimeSymbols_zh_Hans_CN', 'goog.i18n.DateTimeSymbols_zh_Hans_HK', 'goog.i18n.DateTimeSymbols_zh_Hans_MO', 'goog.i18n.DateTimeSymbols_zh_Hans_SG', 'goog.i18n.DateTimeSymbols_zh_Hant', 'goog.i18n.DateTimeSymbols_zh_Hant_HK', 'goog.i18n.DateTimeSymbols_zh_Hant_MO', 'goog.i18n.DateTimeSymbols_zh_Hant_TW', 'goog.i18n.DateTimeSymbols_zu_ZA'], ['goog.i18n.DateTimeSymbols']);
                +goog.addDependency("i18n/graphemebreak.js", ['goog.i18n.GraphemeBreak'], ['goog.structs.InversionMap']);
                +goog.addDependency("i18n/graphemebreak_test.js", ['goog.i18n.GraphemeBreakTest'], ['goog.i18n.GraphemeBreak', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/messageformat.js", ['goog.i18n.MessageFormat'], ['goog.array', 'goog.asserts', 'goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.NumberFormat', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.ordinalRules', 'goog.i18n.pluralRules']);
                +goog.addDependency("i18n/messageformat_test.js", ['goog.i18n.MessageFormatTest'], ['goog.i18n.MessageFormat', 'goog.i18n.NumberFormatSymbols_hr', 'goog.i18n.pluralRules', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/mime.js", ['goog.i18n.mime', 'goog.i18n.mime.encode'], ['goog.array']);
                +goog.addDependency("i18n/mime_test.js", ['goog.i18n.mime.encodeTest'], ['goog.i18n.mime.encode', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/numberformat.js", ['goog.i18n.NumberFormat', 'goog.i18n.NumberFormat.CurrencyStyle', 'goog.i18n.NumberFormat.Format'], ['goog.asserts', 'goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.currency', 'goog.math']);
                +goog.addDependency("i18n/numberformat_test.js", ['goog.i18n.NumberFormatTest'], ['goog.i18n.CompactNumberFormatSymbols', 'goog.i18n.CompactNumberFormatSymbols_de', 'goog.i18n.CompactNumberFormatSymbols_en', 'goog.i18n.CompactNumberFormatSymbols_fr', 'goog.i18n.NumberFormat', 'goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_de', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_fr', 'goog.i18n.NumberFormatSymbols_pl', 'goog.i18n.NumberFormatSymbols_ro', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("i18n/numberformatsymbols.js", ['goog.i18n.NumberFormatSymbols', 'goog.i18n.NumberFormatSymbols_af', 'goog.i18n.NumberFormatSymbols_am', 'goog.i18n.NumberFormatSymbols_ar', 'goog.i18n.NumberFormatSymbols_ar_DZ', 'goog.i18n.NumberFormatSymbols_az', 'goog.i18n.NumberFormatSymbols_be', 'goog.i18n.NumberFormatSymbols_bg', 'goog.i18n.NumberFormatSymbols_bn', 'goog.i18n.NumberFormatSymbols_br', 'goog.i18n.NumberFormatSymbols_bs', 'goog.i18n.NumberFormatSymbols_ca', 'goog.i18n.NumberFormatSymbols_chr', 'goog.i18n.NumberFormatSymbols_cs', 'goog.i18n.NumberFormatSymbols_cy', 'goog.i18n.NumberFormatSymbols_da', 'goog.i18n.NumberFormatSymbols_de', 'goog.i18n.NumberFormatSymbols_de_AT', 'goog.i18n.NumberFormatSymbols_de_CH', 'goog.i18n.NumberFormatSymbols_el', 'goog.i18n.NumberFormatSymbols_en', 'goog.i18n.NumberFormatSymbols_en_AU', 'goog.i18n.NumberFormatSymbols_en_CA', 'goog.i18n.NumberFormatSymbols_en_GB', 'goog.i18n.NumberFormatSymbols_en_IE', 'goog.i18n.NumberFormatSymbols_en_IN', 'goog.i18n.NumberFormatSymbols_en_SG', 'goog.i18n.NumberFormatSymbols_en_US', 'goog.i18n.NumberFormatSymbols_en_ZA', 'goog.i18n.NumberFormatSymbols_es', 'goog.i18n.NumberFormatSymbols_es_419', 'goog.i18n.NumberFormatSymbols_es_ES', 'goog.i18n.NumberFormatSymbols_es_MX', 'goog.i18n.NumberFormatSymbols_es_US', 'goog.i18n.NumberFormatSymbols_et', 'goog.i18n.NumberFormatSymbols_eu', 'goog.i18n.NumberFormatSymbols_fa', 'goog.i18n.NumberFormatSymbols_fi', 'goog.i18n.NumberFormatSymbols_fil', 'goog.i18n.NumberFormatSymbols_fr', 'goog.i18n.NumberFormatSymbols_fr_CA', 'goog.i18n.NumberFormatSymbols_ga', 'goog.i18n.NumberFormatSymbols_gl', 'goog.i18n.NumberFormatSymbols_gsw', 'goog.i18n.NumberFormatSymbols_gu', 'goog.i18n.NumberFormatSymbols_haw', 'goog.i18n.NumberFormatSymbols_he', 'goog.i18n.NumberFormatSymbols_hi', 'goog.i18n.NumberFormatSymbols_hr', 'goog.i18n.NumberFormatSymbols_hu', 'goog.i18n.NumberFormatSymbols_hy', 'goog.i18n.NumberFormatSymbols_id', 'goog.i18n.NumberFormatSymbols_in', 'goog.i18n.NumberFormatSymbols_is', 'goog.i18n.NumberFormatSymbols_it', 'goog.i18n.NumberFormatSymbols_iw', 'goog.i18n.NumberFormatSymbols_ja', 'goog.i18n.NumberFormatSymbols_ka', 'goog.i18n.NumberFormatSymbols_kk', 'goog.i18n.NumberFormatSymbols_km', 'goog.i18n.NumberFormatSymbols_kn', 'goog.i18n.NumberFormatSymbols_ko', 'goog.i18n.NumberFormatSymbols_ky', 'goog.i18n.NumberFormatSymbols_ln', 'goog.i18n.NumberFormatSymbols_lo', 'goog.i18n.NumberFormatSymbols_lt', 'goog.i18n.NumberFormatSymbols_lv', 'goog.i18n.NumberFormatSymbols_mk', 'goog.i18n.NumberFormatSymbols_ml', 'goog.i18n.NumberFormatSymbols_mn', 'goog.i18n.NumberFormatSymbols_mo', 'goog.i18n.NumberFormatSymbols_mr', 'goog.i18n.NumberFormatSymbols_ms', 'goog.i18n.NumberFormatSymbols_mt', 'goog.i18n.NumberFormatSymbols_my', 'goog.i18n.NumberFormatSymbols_nb', 'goog.i18n.NumberFormatSymbols_ne', 'goog.i18n.NumberFormatSymbols_nl', 'goog.i18n.NumberFormatSymbols_no', 'goog.i18n.NumberFormatSymbols_no_NO', 'goog.i18n.NumberFormatSymbols_or', 'goog.i18n.NumberFormatSymbols_pa', 'goog.i18n.NumberFormatSymbols_pl', 'goog.i18n.NumberFormatSymbols_pt', 'goog.i18n.NumberFormatSymbols_pt_BR', 'goog.i18n.NumberFormatSymbols_pt_PT', 'goog.i18n.NumberFormatSymbols_ro', 'goog.i18n.NumberFormatSymbols_ru', 'goog.i18n.NumberFormatSymbols_sh', 'goog.i18n.NumberFormatSymbols_si', 'goog.i18n.NumberFormatSymbols_sk', 'goog.i18n.NumberFormatSymbols_sl', 'goog.i18n.NumberFormatSymbols_sq', 'goog.i18n.NumberFormatSymbols_sr', 'goog.i18n.NumberFormatSymbols_sr_Latn', 'goog.i18n.NumberFormatSymbols_sv', 'goog.i18n.NumberFormatSymbols_sw', 'goog.i18n.NumberFormatSymbols_ta', 'goog.i18n.NumberFormatSymbols_te', 'goog.i18n.NumberFormatSymbols_th', 'goog.i18n.NumberFormatSymbols_tl', 'goog.i18n.NumberFormatSymbols_tr', 'goog.i18n.NumberFormatSymbols_uk', 'goog.i18n.NumberFormatSymbols_ur', 'goog.i18n.NumberFormatSymbols_uz', 'goog.i18n.NumberFormatSymbols_vi', 'goog.i18n.NumberFormatSymbols_zh', 'goog.i18n.NumberFormatSymbols_zh_CN', 'goog.i18n.NumberFormatSymbols_zh_HK', 'goog.i18n.NumberFormatSymbols_zh_TW', 'goog.i18n.NumberFormatSymbols_zu'], []);
                +goog.addDependency("i18n/numberformatsymbolsext.js", ['goog.i18n.NumberFormatSymbolsExt', 'goog.i18n.NumberFormatSymbols_af_NA', 'goog.i18n.NumberFormatSymbols_af_ZA', 'goog.i18n.NumberFormatSymbols_agq', 'goog.i18n.NumberFormatSymbols_agq_CM', 'goog.i18n.NumberFormatSymbols_ak', 'goog.i18n.NumberFormatSymbols_ak_GH', 'goog.i18n.NumberFormatSymbols_am_ET', 'goog.i18n.NumberFormatSymbols_ar_001', 'goog.i18n.NumberFormatSymbols_ar_AE', 'goog.i18n.NumberFormatSymbols_ar_BH', 'goog.i18n.NumberFormatSymbols_ar_DJ', 'goog.i18n.NumberFormatSymbols_ar_EG', 'goog.i18n.NumberFormatSymbols_ar_EH', 'goog.i18n.NumberFormatSymbols_ar_ER', 'goog.i18n.NumberFormatSymbols_ar_IL', 'goog.i18n.NumberFormatSymbols_ar_IQ', 'goog.i18n.NumberFormatSymbols_ar_JO', 'goog.i18n.NumberFormatSymbols_ar_KM', 'goog.i18n.NumberFormatSymbols_ar_KW', 'goog.i18n.NumberFormatSymbols_ar_LB', 'goog.i18n.NumberFormatSymbols_ar_LY', 'goog.i18n.NumberFormatSymbols_ar_MA', 'goog.i18n.NumberFormatSymbols_ar_MR', 'goog.i18n.NumberFormatSymbols_ar_OM', 'goog.i18n.NumberFormatSymbols_ar_PS', 'goog.i18n.NumberFormatSymbols_ar_QA', 'goog.i18n.NumberFormatSymbols_ar_SA', 'goog.i18n.NumberFormatSymbols_ar_SD', 'goog.i18n.NumberFormatSymbols_ar_SO', 'goog.i18n.NumberFormatSymbols_ar_SS', 'goog.i18n.NumberFormatSymbols_ar_SY', 'goog.i18n.NumberFormatSymbols_ar_TD', 'goog.i18n.NumberFormatSymbols_ar_TN', 'goog.i18n.NumberFormatSymbols_ar_XB', 'goog.i18n.NumberFormatSymbols_ar_YE', 'goog.i18n.NumberFormatSymbols_as', 'goog.i18n.NumberFormatSymbols_as_IN', 'goog.i18n.NumberFormatSymbols_asa', 'goog.i18n.NumberFormatSymbols_asa_TZ', 'goog.i18n.NumberFormatSymbols_ast', 'goog.i18n.NumberFormatSymbols_ast_ES', 'goog.i18n.NumberFormatSymbols_az_Cyrl', 'goog.i18n.NumberFormatSymbols_az_Cyrl_AZ', 'goog.i18n.NumberFormatSymbols_az_Latn', 'goog.i18n.NumberFormatSymbols_az_Latn_AZ', 'goog.i18n.NumberFormatSymbols_bas', 'goog.i18n.NumberFormatSymbols_bas_CM', 'goog.i18n.NumberFormatSymbols_be_BY', 'goog.i18n.NumberFormatSymbols_bem', 'goog.i18n.NumberFormatSymbols_bem_ZM', 'goog.i18n.NumberFormatSymbols_bez', 'goog.i18n.NumberFormatSymbols_bez_TZ', 'goog.i18n.NumberFormatSymbols_bg_BG', 'goog.i18n.NumberFormatSymbols_bm', 'goog.i18n.NumberFormatSymbols_bm_ML', 'goog.i18n.NumberFormatSymbols_bn_BD', 'goog.i18n.NumberFormatSymbols_bn_IN', 'goog.i18n.NumberFormatSymbols_bo', 'goog.i18n.NumberFormatSymbols_bo_CN', 'goog.i18n.NumberFormatSymbols_bo_IN', 'goog.i18n.NumberFormatSymbols_br_FR', 'goog.i18n.NumberFormatSymbols_brx', 'goog.i18n.NumberFormatSymbols_brx_IN', 'goog.i18n.NumberFormatSymbols_bs_Cyrl', 'goog.i18n.NumberFormatSymbols_bs_Cyrl_BA', 'goog.i18n.NumberFormatSymbols_bs_Latn', 'goog.i18n.NumberFormatSymbols_bs_Latn_BA', 'goog.i18n.NumberFormatSymbols_ca_AD', 'goog.i18n.NumberFormatSymbols_ca_ES', 'goog.i18n.NumberFormatSymbols_ca_FR', 'goog.i18n.NumberFormatSymbols_ca_IT', 'goog.i18n.NumberFormatSymbols_ce', 'goog.i18n.NumberFormatSymbols_ce_RU', 'goog.i18n.NumberFormatSymbols_cgg', 'goog.i18n.NumberFormatSymbols_cgg_UG', 'goog.i18n.NumberFormatSymbols_chr_US', 'goog.i18n.NumberFormatSymbols_ckb', 'goog.i18n.NumberFormatSymbols_ckb_IQ', 'goog.i18n.NumberFormatSymbols_ckb_IR', 'goog.i18n.NumberFormatSymbols_cs_CZ', 'goog.i18n.NumberFormatSymbols_cy_GB', 'goog.i18n.NumberFormatSymbols_da_DK', 'goog.i18n.NumberFormatSymbols_da_GL', 'goog.i18n.NumberFormatSymbols_dav', 'goog.i18n.NumberFormatSymbols_dav_KE', 'goog.i18n.NumberFormatSymbols_de_BE', 'goog.i18n.NumberFormatSymbols_de_DE', 'goog.i18n.NumberFormatSymbols_de_IT', 'goog.i18n.NumberFormatSymbols_de_LI', 'goog.i18n.NumberFormatSymbols_de_LU', 'goog.i18n.NumberFormatSymbols_dje', 'goog.i18n.NumberFormatSymbols_dje_NE', 'goog.i18n.NumberFormatSymbols_dsb', 'goog.i18n.NumberFormatSymbols_dsb_DE', 'goog.i18n.NumberFormatSymbols_dua', 'goog.i18n.NumberFormatSymbols_dua_CM', 'goog.i18n.NumberFormatSymbols_dyo', 'goog.i18n.NumberFormatSymbols_dyo_SN', 'goog.i18n.NumberFormatSymbols_dz', 'goog.i18n.NumberFormatSymbols_dz_BT', 'goog.i18n.NumberFormatSymbols_ebu', 'goog.i18n.NumberFormatSymbols_ebu_KE', 'goog.i18n.NumberFormatSymbols_ee', 'goog.i18n.NumberFormatSymbols_ee_GH', 'goog.i18n.NumberFormatSymbols_ee_TG', 'goog.i18n.NumberFormatSymbols_el_CY', 'goog.i18n.NumberFormatSymbols_el_GR', 'goog.i18n.NumberFormatSymbols_en_001', 'goog.i18n.NumberFormatSymbols_en_150', 'goog.i18n.NumberFormatSymbols_en_AG', 'goog.i18n.NumberFormatSymbols_en_AI', 'goog.i18n.NumberFormatSymbols_en_AS', 'goog.i18n.NumberFormatSymbols_en_AT', 'goog.i18n.NumberFormatSymbols_en_BB', 'goog.i18n.NumberFormatSymbols_en_BE', 'goog.i18n.NumberFormatSymbols_en_BI', 'goog.i18n.NumberFormatSymbols_en_BM', 'goog.i18n.NumberFormatSymbols_en_BS', 'goog.i18n.NumberFormatSymbols_en_BW', 'goog.i18n.NumberFormatSymbols_en_BZ', 'goog.i18n.NumberFormatSymbols_en_CC', 'goog.i18n.NumberFormatSymbols_en_CH', 'goog.i18n.NumberFormatSymbols_en_CK', 'goog.i18n.NumberFormatSymbols_en_CM', 'goog.i18n.NumberFormatSymbols_en_CX', 'goog.i18n.NumberFormatSymbols_en_CY', 'goog.i18n.NumberFormatSymbols_en_DE', 'goog.i18n.NumberFormatSymbols_en_DG', 'goog.i18n.NumberFormatSymbols_en_DK', 'goog.i18n.NumberFormatSymbols_en_DM', 'goog.i18n.NumberFormatSymbols_en_ER', 'goog.i18n.NumberFormatSymbols_en_FI', 'goog.i18n.NumberFormatSymbols_en_FJ', 'goog.i18n.NumberFormatSymbols_en_FK', 'goog.i18n.NumberFormatSymbols_en_FM', 'goog.i18n.NumberFormatSymbols_en_GD', 'goog.i18n.NumberFormatSymbols_en_GG', 'goog.i18n.NumberFormatSymbols_en_GH', 'goog.i18n.NumberFormatSymbols_en_GI', 'goog.i18n.NumberFormatSymbols_en_GM', 'goog.i18n.NumberFormatSymbols_en_GU', 'goog.i18n.NumberFormatSymbols_en_GY', 'goog.i18n.NumberFormatSymbols_en_HK', 'goog.i18n.NumberFormatSymbols_en_IL', 'goog.i18n.NumberFormatSymbols_en_IM', 'goog.i18n.NumberFormatSymbols_en_IO', 'goog.i18n.NumberFormatSymbols_en_JE', 'goog.i18n.NumberFormatSymbols_en_JM', 'goog.i18n.NumberFormatSymbols_en_KE', 'goog.i18n.NumberFormatSymbols_en_KI', 'goog.i18n.NumberFormatSymbols_en_KN', 'goog.i18n.NumberFormatSymbols_en_KY', 'goog.i18n.NumberFormatSymbols_en_LC', 'goog.i18n.NumberFormatSymbols_en_LR', 'goog.i18n.NumberFormatSymbols_en_LS', 'goog.i18n.NumberFormatSymbols_en_MG', 'goog.i18n.NumberFormatSymbols_en_MH', 'goog.i18n.NumberFormatSymbols_en_MO', 'goog.i18n.NumberFormatSymbols_en_MP', 'goog.i18n.NumberFormatSymbols_en_MS', 'goog.i18n.NumberFormatSymbols_en_MT', 'goog.i18n.NumberFormatSymbols_en_MU', 'goog.i18n.NumberFormatSymbols_en_MW', 'goog.i18n.NumberFormatSymbols_en_MY', 'goog.i18n.NumberFormatSymbols_en_NA', 'goog.i18n.NumberFormatSymbols_en_NF', 'goog.i18n.NumberFormatSymbols_en_NG', 'goog.i18n.NumberFormatSymbols_en_NL', 'goog.i18n.NumberFormatSymbols_en_NR', 'goog.i18n.NumberFormatSymbols_en_NU', 'goog.i18n.NumberFormatSymbols_en_NZ', 'goog.i18n.NumberFormatSymbols_en_PG', 'goog.i18n.NumberFormatSymbols_en_PH', 'goog.i18n.NumberFormatSymbols_en_PK', 'goog.i18n.NumberFormatSymbols_en_PN', 'goog.i18n.NumberFormatSymbols_en_PR', 'goog.i18n.NumberFormatSymbols_en_PW', 'goog.i18n.NumberFormatSymbols_en_RW', 'goog.i18n.NumberFormatSymbols_en_SB', 'goog.i18n.NumberFormatSymbols_en_SC', 'goog.i18n.NumberFormatSymbols_en_SD', 'goog.i18n.NumberFormatSymbols_en_SE', 'goog.i18n.NumberFormatSymbols_en_SH', 'goog.i18n.NumberFormatSymbols_en_SI', 'goog.i18n.NumberFormatSymbols_en_SL', 'goog.i18n.NumberFormatSymbols_en_SS', 'goog.i18n.NumberFormatSymbols_en_SX', 'goog.i18n.NumberFormatSymbols_en_SZ', 'goog.i18n.NumberFormatSymbols_en_TC', 'goog.i18n.NumberFormatSymbols_en_TK', 'goog.i18n.NumberFormatSymbols_en_TO', 'goog.i18n.NumberFormatSymbols_en_TT', 'goog.i18n.NumberFormatSymbols_en_TV', 'goog.i18n.NumberFormatSymbols_en_TZ', 'goog.i18n.NumberFormatSymbols_en_UG', 'goog.i18n.NumberFormatSymbols_en_UM', 'goog.i18n.NumberFormatSymbols_en_US_POSIX', 'goog.i18n.NumberFormatSymbols_en_VC', 'goog.i18n.NumberFormatSymbols_en_VG', 'goog.i18n.NumberFormatSymbols_en_VI', 'goog.i18n.NumberFormatSymbols_en_VU', 'goog.i18n.NumberFormatSymbols_en_WS', 'goog.i18n.NumberFormatSymbols_en_XA', 'goog.i18n.NumberFormatSymbols_en_ZM', 'goog.i18n.NumberFormatSymbols_en_ZW', 'goog.i18n.NumberFormatSymbols_eo', 'goog.i18n.NumberFormatSymbols_es_AR', 'goog.i18n.NumberFormatSymbols_es_BO', 'goog.i18n.NumberFormatSymbols_es_BR', 'goog.i18n.NumberFormatSymbols_es_CL', 'goog.i18n.NumberFormatSymbols_es_CO', 'goog.i18n.NumberFormatSymbols_es_CR', 'goog.i18n.NumberFormatSymbols_es_CU', 'goog.i18n.NumberFormatSymbols_es_DO', 'goog.i18n.NumberFormatSymbols_es_EA', 'goog.i18n.NumberFormatSymbols_es_EC', 'goog.i18n.NumberFormatSymbols_es_GQ', 'goog.i18n.NumberFormatSymbols_es_GT', 'goog.i18n.NumberFormatSymbols_es_HN', 'goog.i18n.NumberFormatSymbols_es_IC', 'goog.i18n.NumberFormatSymbols_es_NI', 'goog.i18n.NumberFormatSymbols_es_PA', 'goog.i18n.NumberFormatSymbols_es_PE', 'goog.i18n.NumberFormatSymbols_es_PH', 'goog.i18n.NumberFormatSymbols_es_PR', 'goog.i18n.NumberFormatSymbols_es_PY', 'goog.i18n.NumberFormatSymbols_es_SV', 'goog.i18n.NumberFormatSymbols_es_UY', 'goog.i18n.NumberFormatSymbols_es_VE', 'goog.i18n.NumberFormatSymbols_et_EE', 'goog.i18n.NumberFormatSymbols_eu_ES', 'goog.i18n.NumberFormatSymbols_ewo', 'goog.i18n.NumberFormatSymbols_ewo_CM', 'goog.i18n.NumberFormatSymbols_fa_AF', 'goog.i18n.NumberFormatSymbols_fa_IR', 'goog.i18n.NumberFormatSymbols_ff', 'goog.i18n.NumberFormatSymbols_ff_CM', 'goog.i18n.NumberFormatSymbols_ff_GN', 'goog.i18n.NumberFormatSymbols_ff_MR', 'goog.i18n.NumberFormatSymbols_ff_SN', 'goog.i18n.NumberFormatSymbols_fi_FI', 'goog.i18n.NumberFormatSymbols_fil_PH', 'goog.i18n.NumberFormatSymbols_fo', 'goog.i18n.NumberFormatSymbols_fo_DK', 'goog.i18n.NumberFormatSymbols_fo_FO', 'goog.i18n.NumberFormatSymbols_fr_BE', 'goog.i18n.NumberFormatSymbols_fr_BF', 'goog.i18n.NumberFormatSymbols_fr_BI', 'goog.i18n.NumberFormatSymbols_fr_BJ', 'goog.i18n.NumberFormatSymbols_fr_BL', 'goog.i18n.NumberFormatSymbols_fr_CD', 'goog.i18n.NumberFormatSymbols_fr_CF', 'goog.i18n.NumberFormatSymbols_fr_CG', 'goog.i18n.NumberFormatSymbols_fr_CH', 'goog.i18n.NumberFormatSymbols_fr_CI', 'goog.i18n.NumberFormatSymbols_fr_CM', 'goog.i18n.NumberFormatSymbols_fr_DJ', 'goog.i18n.NumberFormatSymbols_fr_DZ', 'goog.i18n.NumberFormatSymbols_fr_FR', 'goog.i18n.NumberFormatSymbols_fr_GA', 'goog.i18n.NumberFormatSymbols_fr_GF', 'goog.i18n.NumberFormatSymbols_fr_GN', 'goog.i18n.NumberFormatSymbols_fr_GP', 'goog.i18n.NumberFormatSymbols_fr_GQ', 'goog.i18n.NumberFormatSymbols_fr_HT', 'goog.i18n.NumberFormatSymbols_fr_KM', 'goog.i18n.NumberFormatSymbols_fr_LU', 'goog.i18n.NumberFormatSymbols_fr_MA', 'goog.i18n.NumberFormatSymbols_fr_MC', 'goog.i18n.NumberFormatSymbols_fr_MF', 'goog.i18n.NumberFormatSymbols_fr_MG', 'goog.i18n.NumberFormatSymbols_fr_ML', 'goog.i18n.NumberFormatSymbols_fr_MQ', 'goog.i18n.NumberFormatSymbols_fr_MR', 'goog.i18n.NumberFormatSymbols_fr_MU', 'goog.i18n.NumberFormatSymbols_fr_NC', 'goog.i18n.NumberFormatSymbols_fr_NE', 'goog.i18n.NumberFormatSymbols_fr_PF', 'goog.i18n.NumberFormatSymbols_fr_PM', 'goog.i18n.NumberFormatSymbols_fr_RE', 'goog.i18n.NumberFormatSymbols_fr_RW', 'goog.i18n.NumberFormatSymbols_fr_SC', 'goog.i18n.NumberFormatSymbols_fr_SN', 'goog.i18n.NumberFormatSymbols_fr_SY', 'goog.i18n.NumberFormatSymbols_fr_TD', 'goog.i18n.NumberFormatSymbols_fr_TG', 'goog.i18n.NumberFormatSymbols_fr_TN', 'goog.i18n.NumberFormatSymbols_fr_VU', 'goog.i18n.NumberFormatSymbols_fr_WF', 'goog.i18n.NumberFormatSymbols_fr_YT', 'goog.i18n.NumberFormatSymbols_fur', 'goog.i18n.NumberFormatSymbols_fur_IT', 'goog.i18n.NumberFormatSymbols_fy', 'goog.i18n.NumberFormatSymbols_fy_NL', 'goog.i18n.NumberFormatSymbols_ga_IE', 'goog.i18n.NumberFormatSymbols_gd', 'goog.i18n.NumberFormatSymbols_gd_GB', 'goog.i18n.NumberFormatSymbols_gl_ES', 'goog.i18n.NumberFormatSymbols_gsw_CH', 'goog.i18n.NumberFormatSymbols_gsw_FR', 'goog.i18n.NumberFormatSymbols_gsw_LI', 'goog.i18n.NumberFormatSymbols_gu_IN', 'goog.i18n.NumberFormatSymbols_guz', 'goog.i18n.NumberFormatSymbols_guz_KE', 'goog.i18n.NumberFormatSymbols_gv', 'goog.i18n.NumberFormatSymbols_gv_IM', 'goog.i18n.NumberFormatSymbols_ha', 'goog.i18n.NumberFormatSymbols_ha_GH', 'goog.i18n.NumberFormatSymbols_ha_NE', 'goog.i18n.NumberFormatSymbols_ha_NG', 'goog.i18n.NumberFormatSymbols_haw_US', 'goog.i18n.NumberFormatSymbols_he_IL', 'goog.i18n.NumberFormatSymbols_hi_IN', 'goog.i18n.NumberFormatSymbols_hr_BA', 'goog.i18n.NumberFormatSymbols_hr_HR', 'goog.i18n.NumberFormatSymbols_hsb', 'goog.i18n.NumberFormatSymbols_hsb_DE', 'goog.i18n.NumberFormatSymbols_hu_HU', 'goog.i18n.NumberFormatSymbols_hy_AM', 'goog.i18n.NumberFormatSymbols_id_ID', 'goog.i18n.NumberFormatSymbols_ig', 'goog.i18n.NumberFormatSymbols_ig_NG', 'goog.i18n.NumberFormatSymbols_ii', 'goog.i18n.NumberFormatSymbols_ii_CN', 'goog.i18n.NumberFormatSymbols_is_IS', 'goog.i18n.NumberFormatSymbols_it_CH', 'goog.i18n.NumberFormatSymbols_it_IT', 'goog.i18n.NumberFormatSymbols_it_SM', 'goog.i18n.NumberFormatSymbols_ja_JP', 'goog.i18n.NumberFormatSymbols_jgo', 'goog.i18n.NumberFormatSymbols_jgo_CM', 'goog.i18n.NumberFormatSymbols_jmc', 'goog.i18n.NumberFormatSymbols_jmc_TZ', 'goog.i18n.NumberFormatSymbols_ka_GE', 'goog.i18n.NumberFormatSymbols_kab', 'goog.i18n.NumberFormatSymbols_kab_DZ', 'goog.i18n.NumberFormatSymbols_kam', 'goog.i18n.NumberFormatSymbols_kam_KE', 'goog.i18n.NumberFormatSymbols_kde', 'goog.i18n.NumberFormatSymbols_kde_TZ', 'goog.i18n.NumberFormatSymbols_kea', 'goog.i18n.NumberFormatSymbols_kea_CV', 'goog.i18n.NumberFormatSymbols_khq', 'goog.i18n.NumberFormatSymbols_khq_ML', 'goog.i18n.NumberFormatSymbols_ki', 'goog.i18n.NumberFormatSymbols_ki_KE', 'goog.i18n.NumberFormatSymbols_kk_KZ', 'goog.i18n.NumberFormatSymbols_kkj', 'goog.i18n.NumberFormatSymbols_kkj_CM', 'goog.i18n.NumberFormatSymbols_kl', 'goog.i18n.NumberFormatSymbols_kl_GL', 'goog.i18n.NumberFormatSymbols_kln', 'goog.i18n.NumberFormatSymbols_kln_KE', 'goog.i18n.NumberFormatSymbols_km_KH', 'goog.i18n.NumberFormatSymbols_kn_IN', 'goog.i18n.NumberFormatSymbols_ko_KP', 'goog.i18n.NumberFormatSymbols_ko_KR', 'goog.i18n.NumberFormatSymbols_kok', 'goog.i18n.NumberFormatSymbols_kok_IN', 'goog.i18n.NumberFormatSymbols_ks', 'goog.i18n.NumberFormatSymbols_ks_IN', 'goog.i18n.NumberFormatSymbols_ksb', 'goog.i18n.NumberFormatSymbols_ksb_TZ', 'goog.i18n.NumberFormatSymbols_ksf', 'goog.i18n.NumberFormatSymbols_ksf_CM', 'goog.i18n.NumberFormatSymbols_ksh', 'goog.i18n.NumberFormatSymbols_ksh_DE', 'goog.i18n.NumberFormatSymbols_kw', 'goog.i18n.NumberFormatSymbols_kw_GB', 'goog.i18n.NumberFormatSymbols_ky_KG', 'goog.i18n.NumberFormatSymbols_lag', 'goog.i18n.NumberFormatSymbols_lag_TZ', 'goog.i18n.NumberFormatSymbols_lb', 'goog.i18n.NumberFormatSymbols_lb_LU', 'goog.i18n.NumberFormatSymbols_lg', 'goog.i18n.NumberFormatSymbols_lg_UG', 'goog.i18n.NumberFormatSymbols_lkt', 'goog.i18n.NumberFormatSymbols_lkt_US', 'goog.i18n.NumberFormatSymbols_ln_AO', 'goog.i18n.NumberFormatSymbols_ln_CD', 'goog.i18n.NumberFormatSymbols_ln_CF', 'goog.i18n.NumberFormatSymbols_ln_CG', 'goog.i18n.NumberFormatSymbols_lo_LA', 'goog.i18n.NumberFormatSymbols_lrc', 'goog.i18n.NumberFormatSymbols_lrc_IQ', 'goog.i18n.NumberFormatSymbols_lrc_IR', 'goog.i18n.NumberFormatSymbols_lt_LT', 'goog.i18n.NumberFormatSymbols_lu', 'goog.i18n.NumberFormatSymbols_lu_CD', 'goog.i18n.NumberFormatSymbols_luo', 'goog.i18n.NumberFormatSymbols_luo_KE', 'goog.i18n.NumberFormatSymbols_luy', 'goog.i18n.NumberFormatSymbols_luy_KE', 'goog.i18n.NumberFormatSymbols_lv_LV', 'goog.i18n.NumberFormatSymbols_mas', 'goog.i18n.NumberFormatSymbols_mas_KE', 'goog.i18n.NumberFormatSymbols_mas_TZ', 'goog.i18n.NumberFormatSymbols_mer', 'goog.i18n.NumberFormatSymbols_mer_KE', 'goog.i18n.NumberFormatSymbols_mfe', 'goog.i18n.NumberFormatSymbols_mfe_MU', 'goog.i18n.NumberFormatSymbols_mg', 'goog.i18n.NumberFormatSymbols_mg_MG', 'goog.i18n.NumberFormatSymbols_mgh', 'goog.i18n.NumberFormatSymbols_mgh_MZ', 'goog.i18n.NumberFormatSymbols_mgo', 'goog.i18n.NumberFormatSymbols_mgo_CM', 'goog.i18n.NumberFormatSymbols_mk_MK', 'goog.i18n.NumberFormatSymbols_ml_IN', 'goog.i18n.NumberFormatSymbols_mn_MN', 'goog.i18n.NumberFormatSymbols_mr_IN', 'goog.i18n.NumberFormatSymbols_ms_BN', 'goog.i18n.NumberFormatSymbols_ms_MY', 'goog.i18n.NumberFormatSymbols_ms_SG', 'goog.i18n.NumberFormatSymbols_mt_MT', 'goog.i18n.NumberFormatSymbols_mua', 'goog.i18n.NumberFormatSymbols_mua_CM', 'goog.i18n.NumberFormatSymbols_my_MM', 'goog.i18n.NumberFormatSymbols_mzn', 'goog.i18n.NumberFormatSymbols_mzn_IR', 'goog.i18n.NumberFormatSymbols_naq', 'goog.i18n.NumberFormatSymbols_naq_NA', 'goog.i18n.NumberFormatSymbols_nb_NO', 'goog.i18n.NumberFormatSymbols_nb_SJ', 'goog.i18n.NumberFormatSymbols_nd', 'goog.i18n.NumberFormatSymbols_nd_ZW', 'goog.i18n.NumberFormatSymbols_nds', 'goog.i18n.NumberFormatSymbols_nds_DE', 'goog.i18n.NumberFormatSymbols_nds_NL', 'goog.i18n.NumberFormatSymbols_ne_IN', 'goog.i18n.NumberFormatSymbols_ne_NP', 'goog.i18n.NumberFormatSymbols_nl_AW', 'goog.i18n.NumberFormatSymbols_nl_BE', 'goog.i18n.NumberFormatSymbols_nl_BQ', 'goog.i18n.NumberFormatSymbols_nl_CW', 'goog.i18n.NumberFormatSymbols_nl_NL', 'goog.i18n.NumberFormatSymbols_nl_SR', 'goog.i18n.NumberFormatSymbols_nl_SX', 'goog.i18n.NumberFormatSymbols_nmg', 'goog.i18n.NumberFormatSymbols_nmg_CM', 'goog.i18n.NumberFormatSymbols_nn', 'goog.i18n.NumberFormatSymbols_nn_NO', 'goog.i18n.NumberFormatSymbols_nnh', 'goog.i18n.NumberFormatSymbols_nnh_CM', 'goog.i18n.NumberFormatSymbols_nus', 'goog.i18n.NumberFormatSymbols_nus_SS', 'goog.i18n.NumberFormatSymbols_nyn', 'goog.i18n.NumberFormatSymbols_nyn_UG', 'goog.i18n.NumberFormatSymbols_om', 'goog.i18n.NumberFormatSymbols_om_ET', 'goog.i18n.NumberFormatSymbols_om_KE', 'goog.i18n.NumberFormatSymbols_or_IN', 'goog.i18n.NumberFormatSymbols_os', 'goog.i18n.NumberFormatSymbols_os_GE', 'goog.i18n.NumberFormatSymbols_os_RU', 'goog.i18n.NumberFormatSymbols_pa_Arab', 'goog.i18n.NumberFormatSymbols_pa_Arab_PK', 'goog.i18n.NumberFormatSymbols_pa_Guru', 'goog.i18n.NumberFormatSymbols_pa_Guru_IN', 'goog.i18n.NumberFormatSymbols_pl_PL', 'goog.i18n.NumberFormatSymbols_ps', 'goog.i18n.NumberFormatSymbols_ps_AF', 'goog.i18n.NumberFormatSymbols_pt_AO', 'goog.i18n.NumberFormatSymbols_pt_CH', 'goog.i18n.NumberFormatSymbols_pt_CV', 'goog.i18n.NumberFormatSymbols_pt_GQ', 'goog.i18n.NumberFormatSymbols_pt_GW', 'goog.i18n.NumberFormatSymbols_pt_LU', 'goog.i18n.NumberFormatSymbols_pt_MO', 'goog.i18n.NumberFormatSymbols_pt_MZ', 'goog.i18n.NumberFormatSymbols_pt_ST', 'goog.i18n.NumberFormatSymbols_pt_TL', 'goog.i18n.NumberFormatSymbols_qu', 'goog.i18n.NumberFormatSymbols_qu_BO', 'goog.i18n.NumberFormatSymbols_qu_EC', 'goog.i18n.NumberFormatSymbols_qu_PE', 'goog.i18n.NumberFormatSymbols_rm', 'goog.i18n.NumberFormatSymbols_rm_CH', 'goog.i18n.NumberFormatSymbols_rn', 'goog.i18n.NumberFormatSymbols_rn_BI', 'goog.i18n.NumberFormatSymbols_ro_MD', 'goog.i18n.NumberFormatSymbols_ro_RO', 'goog.i18n.NumberFormatSymbols_rof', 'goog.i18n.NumberFormatSymbols_rof_TZ', 'goog.i18n.NumberFormatSymbols_ru_BY', 'goog.i18n.NumberFormatSymbols_ru_KG', 'goog.i18n.NumberFormatSymbols_ru_KZ', 'goog.i18n.NumberFormatSymbols_ru_MD', 'goog.i18n.NumberFormatSymbols_ru_RU', 'goog.i18n.NumberFormatSymbols_ru_UA', 'goog.i18n.NumberFormatSymbols_rw', 'goog.i18n.NumberFormatSymbols_rw_RW', 'goog.i18n.NumberFormatSymbols_rwk', 'goog.i18n.NumberFormatSymbols_rwk_TZ', 'goog.i18n.NumberFormatSymbols_sah', 'goog.i18n.NumberFormatSymbols_sah_RU', 'goog.i18n.NumberFormatSymbols_saq', 'goog.i18n.NumberFormatSymbols_saq_KE', 'goog.i18n.NumberFormatSymbols_sbp', 'goog.i18n.NumberFormatSymbols_sbp_TZ', 'goog.i18n.NumberFormatSymbols_se', 'goog.i18n.NumberFormatSymbols_se_FI', 'goog.i18n.NumberFormatSymbols_se_NO', 'goog.i18n.NumberFormatSymbols_se_SE', 'goog.i18n.NumberFormatSymbols_seh', 'goog.i18n.NumberFormatSymbols_seh_MZ', 'goog.i18n.NumberFormatSymbols_ses', 'goog.i18n.NumberFormatSymbols_ses_ML', 'goog.i18n.NumberFormatSymbols_sg', 'goog.i18n.NumberFormatSymbols_sg_CF', 'goog.i18n.NumberFormatSymbols_shi', 'goog.i18n.NumberFormatSymbols_shi_Latn', 'goog.i18n.NumberFormatSymbols_shi_Latn_MA', 'goog.i18n.NumberFormatSymbols_shi_Tfng', 'goog.i18n.NumberFormatSymbols_shi_Tfng_MA', 'goog.i18n.NumberFormatSymbols_si_LK', 'goog.i18n.NumberFormatSymbols_sk_SK', 'goog.i18n.NumberFormatSymbols_sl_SI', 'goog.i18n.NumberFormatSymbols_smn', 'goog.i18n.NumberFormatSymbols_smn_FI', 'goog.i18n.NumberFormatSymbols_sn', 'goog.i18n.NumberFormatSymbols_sn_ZW', 'goog.i18n.NumberFormatSymbols_so', 'goog.i18n.NumberFormatSymbols_so_DJ', 'goog.i18n.NumberFormatSymbols_so_ET', 'goog.i18n.NumberFormatSymbols_so_KE', 'goog.i18n.NumberFormatSymbols_so_SO', 'goog.i18n.NumberFormatSymbols_sq_AL', 'goog.i18n.NumberFormatSymbols_sq_MK', 'goog.i18n.NumberFormatSymbols_sq_XK', 'goog.i18n.NumberFormatSymbols_sr_Cyrl', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_BA', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_ME', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_RS', 'goog.i18n.NumberFormatSymbols_sr_Cyrl_XK', 'goog.i18n.NumberFormatSymbols_sr_Latn_BA', 'goog.i18n.NumberFormatSymbols_sr_Latn_ME', 'goog.i18n.NumberFormatSymbols_sr_Latn_RS', 'goog.i18n.NumberFormatSymbols_sr_Latn_XK', 'goog.i18n.NumberFormatSymbols_sv_AX', 'goog.i18n.NumberFormatSymbols_sv_FI', 'goog.i18n.NumberFormatSymbols_sv_SE', 'goog.i18n.NumberFormatSymbols_sw_CD', 'goog.i18n.NumberFormatSymbols_sw_KE', 'goog.i18n.NumberFormatSymbols_sw_TZ', 'goog.i18n.NumberFormatSymbols_sw_UG', 'goog.i18n.NumberFormatSymbols_ta_IN', 'goog.i18n.NumberFormatSymbols_ta_LK', 'goog.i18n.NumberFormatSymbols_ta_MY', 'goog.i18n.NumberFormatSymbols_ta_SG', 'goog.i18n.NumberFormatSymbols_te_IN', 'goog.i18n.NumberFormatSymbols_teo', 'goog.i18n.NumberFormatSymbols_teo_KE', 'goog.i18n.NumberFormatSymbols_teo_UG', 'goog.i18n.NumberFormatSymbols_th_TH', 'goog.i18n.NumberFormatSymbols_ti', 'goog.i18n.NumberFormatSymbols_ti_ER', 'goog.i18n.NumberFormatSymbols_ti_ET', 'goog.i18n.NumberFormatSymbols_to', 'goog.i18n.NumberFormatSymbols_to_TO', 'goog.i18n.NumberFormatSymbols_tr_CY', 'goog.i18n.NumberFormatSymbols_tr_TR', 'goog.i18n.NumberFormatSymbols_twq', 'goog.i18n.NumberFormatSymbols_twq_NE', 'goog.i18n.NumberFormatSymbols_tzm', 'goog.i18n.NumberFormatSymbols_tzm_MA', 'goog.i18n.NumberFormatSymbols_ug', 'goog.i18n.NumberFormatSymbols_ug_CN', 'goog.i18n.NumberFormatSymbols_uk_UA', 'goog.i18n.NumberFormatSymbols_ur_IN', 'goog.i18n.NumberFormatSymbols_ur_PK', 'goog.i18n.NumberFormatSymbols_uz_Arab', 'goog.i18n.NumberFormatSymbols_uz_Arab_AF', 'goog.i18n.NumberFormatSymbols_uz_Cyrl', 'goog.i18n.NumberFormatSymbols_uz_Cyrl_UZ', 'goog.i18n.NumberFormatSymbols_uz_Latn', 'goog.i18n.NumberFormatSymbols_uz_Latn_UZ', 'goog.i18n.NumberFormatSymbols_vai', 'goog.i18n.NumberFormatSymbols_vai_Latn', 'goog.i18n.NumberFormatSymbols_vai_Latn_LR', 'goog.i18n.NumberFormatSymbols_vai_Vaii', 'goog.i18n.NumberFormatSymbols_vai_Vaii_LR', 'goog.i18n.NumberFormatSymbols_vi_VN', 'goog.i18n.NumberFormatSymbols_vun', 'goog.i18n.NumberFormatSymbols_vun_TZ', 'goog.i18n.NumberFormatSymbols_wae', 'goog.i18n.NumberFormatSymbols_wae_CH', 'goog.i18n.NumberFormatSymbols_xog', 'goog.i18n.NumberFormatSymbols_xog_UG', 'goog.i18n.NumberFormatSymbols_yav', 'goog.i18n.NumberFormatSymbols_yav_CM', 'goog.i18n.NumberFormatSymbols_yi', 'goog.i18n.NumberFormatSymbols_yi_001', 'goog.i18n.NumberFormatSymbols_yo', 'goog.i18n.NumberFormatSymbols_yo_BJ', 'goog.i18n.NumberFormatSymbols_yo_NG', 'goog.i18n.NumberFormatSymbols_yue', 'goog.i18n.NumberFormatSymbols_yue_HK', 'goog.i18n.NumberFormatSymbols_zgh', 'goog.i18n.NumberFormatSymbols_zgh_MA', 'goog.i18n.NumberFormatSymbols_zh_Hans', 'goog.i18n.NumberFormatSymbols_zh_Hans_CN', 'goog.i18n.NumberFormatSymbols_zh_Hans_HK', 'goog.i18n.NumberFormatSymbols_zh_Hans_MO', 'goog.i18n.NumberFormatSymbols_zh_Hans_SG', 'goog.i18n.NumberFormatSymbols_zh_Hant', 'goog.i18n.NumberFormatSymbols_zh_Hant_HK', 'goog.i18n.NumberFormatSymbols_zh_Hant_MO', 'goog.i18n.NumberFormatSymbols_zh_Hant_TW', 'goog.i18n.NumberFormatSymbols_zu_ZA'], ['goog.i18n.NumberFormatSymbols']);
                +goog.addDependency("i18n/ordinalrules.js", ['goog.i18n.ordinalRules'], []);
                +goog.addDependency("i18n/pluralrules.js", ['goog.i18n.pluralRules'], []);
                +goog.addDependency("i18n/pluralrules_test.js", ['goog.i18n.pluralRulesTest'], ['goog.i18n.pluralRules', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/timezone.js", ['goog.i18n.TimeZone'], ['goog.array', 'goog.date.DateLike', 'goog.object', 'goog.string']);
                +goog.addDependency("i18n/timezone_test.js", ['goog.i18n.TimeZoneTest'], ['goog.i18n.TimeZone', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/uchar.js", ['goog.i18n.uChar'], []);
                +goog.addDependency("i18n/uchar/localnamefetcher.js", ['goog.i18n.uChar.LocalNameFetcher'], ['goog.i18n.uChar.NameFetcher', 'goog.i18n.uCharNames', 'goog.log']);
                +goog.addDependency("i18n/uchar/localnamefetcher_test.js", ['goog.i18n.uChar.LocalNameFetcherTest'], ['goog.i18n.uChar.LocalNameFetcher', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("i18n/uchar/namefetcher.js", ['goog.i18n.uChar.NameFetcher'], []);
                +goog.addDependency("i18n/uchar/remotenamefetcher.js", ['goog.i18n.uChar.RemoteNameFetcher'], ['goog.Disposable', 'goog.Uri', 'goog.events', 'goog.i18n.uChar', 'goog.i18n.uChar.NameFetcher', 'goog.log', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.structs.Map']);
                +goog.addDependency("i18n/uchar/remotenamefetcher_test.js", ['goog.i18n.uChar.RemoteNameFetcherTest'], ['goog.i18n.uChar.RemoteNameFetcher', 'goog.net.XhrIo', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("i18n/uchar_test.js", ['goog.i18n.uCharTest'], ['goog.i18n.uChar', 'goog.testing.jsunit']);
                +goog.addDependency("i18n/ucharnames.js", ['goog.i18n.uCharNames'], ['goog.i18n.uChar']);
                +goog.addDependency("i18n/ucharnames_test.js", ['goog.i18n.uCharNamesTest'], ['goog.i18n.uCharNames', 'goog.testing.jsunit']);
                +goog.addDependency("iter/iter.js", ['goog.iter', 'goog.iter.Iterable', 'goog.iter.Iterator', 'goog.iter.StopIteration'], ['goog.array', 'goog.asserts', 'goog.functions', 'goog.math']);
                +goog.addDependency("iter/iter_test.js", ['goog.iterTest'], ['goog.iter', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.testing.jsunit']);
                +goog.addDependency("json/evaljsonprocessor.js", ['goog.json.EvalJsonProcessor'], ['goog.json', 'goog.json.Processor', 'goog.json.Serializer']);
                +goog.addDependency("json/hybrid.js", ['goog.json.hybrid'], ['goog.asserts', 'goog.json']);
                +goog.addDependency("json/hybrid_test.js", ['goog.json.hybridTest'], ['goog.json', 'goog.json.hybrid', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("json/hybridjsonprocessor.js", ['goog.json.HybridJsonProcessor'], ['goog.json.Processor', 'goog.json.hybrid']);
                +goog.addDependency("json/hybridjsonprocessor_test.js", ['goog.json.HybridJsonProcessorTest'], ['goog.json.HybridJsonProcessor', 'goog.json.hybrid', 'goog.testing.jsunit']);
                +goog.addDependency("json/json.js", ['goog.json', 'goog.json.Replacer', 'goog.json.Reviver', 'goog.json.Serializer'], []);
                +goog.addDependency("json/json_perf.js", ['goog.jsonPerf'], ['goog.dom', 'goog.json', 'goog.math', 'goog.string', 'goog.testing.PerformanceTable', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("json/json_test.js", ['goog.jsonTest'], ['goog.functions', 'goog.json', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("json/nativejsonprocessor.js", ['goog.json.NativeJsonProcessor'], ['goog.asserts', 'goog.json.Processor']);
                +goog.addDependency("json/processor.js", ['goog.json.Processor'], ['goog.string.Parser', 'goog.string.Stringifier']);
                +goog.addDependency("json/processor_test.js", ['goog.json.processorTest'], ['goog.json.EvalJsonProcessor', 'goog.json.NativeJsonProcessor', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("labs/dom/pagevisibilitymonitor.js", ['goog.labs.dom.PageVisibilityEvent', 'goog.labs.dom.PageVisibilityMonitor', 'goog.labs.dom.PageVisibilityState'], ['goog.dom', 'goog.dom.vendor', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.memoize']);
                +goog.addDependency("labs/dom/pagevisibilitymonitor_test.js", ['goog.labs.dom.PageVisibilityMonitorTest'], ['goog.events', 'goog.functions', 'goog.labs.dom.PageVisibilityMonitor', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/events/nondisposableeventtarget.js", ['goog.labs.events.NonDisposableEventTarget'], ['goog.array', 'goog.asserts', 'goog.events.Event', 'goog.events.Listenable', 'goog.events.ListenerMap', 'goog.object']);
                +goog.addDependency("labs/events/nondisposableeventtarget_test.js", ['goog.labs.events.NonDisposableEventTargetTest'], ['goog.events.Listenable', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.labs.events.NonDisposableEventTarget', 'goog.testing.jsunit']);
                +goog.addDependency("labs/events/nondisposableeventtarget_via_googevents_test.js", ['goog.labs.events.NonDisposableEventTargetGoogEventsTest'], ['goog.events', 'goog.events.eventTargetTester', 'goog.events.eventTargetTester.KeyType', 'goog.events.eventTargetTester.UnlistenReturnType', 'goog.labs.events.NonDisposableEventTarget', 'goog.testing', 'goog.testing.jsunit']);
                +goog.addDependency("labs/events/touch.js", ['goog.labs.events.touch', 'goog.labs.events.touch.TouchData'], ['goog.array', 'goog.asserts', 'goog.events.EventType', 'goog.string']);
                +goog.addDependency("labs/events/touch_test.js", ['goog.labs.events.touchTest'], ['goog.labs.events.touch', 'goog.testing.jsunit']);
                +goog.addDependency("labs/format/csv.js", ['goog.labs.format.csv', 'goog.labs.format.csv.ParseError', 'goog.labs.format.csv.Token'], ['goog.array', 'goog.asserts', 'goog.debug.Error', 'goog.object', 'goog.string', 'goog.string.newlines']);
                +goog.addDependency("labs/format/csv_test.js", ['goog.labs.format.csvTest'], ['goog.labs.format.csv', 'goog.labs.format.csv.ParseError', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/i18n/listformat.js", ['goog.labs.i18n.GenderInfo', 'goog.labs.i18n.GenderInfo.Gender', 'goog.labs.i18n.ListFormat'], ['goog.asserts', 'goog.labs.i18n.ListFormatSymbols']);
                +goog.addDependency("labs/i18n/listformat_test.js", ['goog.labs.i18n.ListFormatTest'], ['goog.labs.i18n.GenderInfo', 'goog.labs.i18n.ListFormat', 'goog.labs.i18n.ListFormatSymbols', 'goog.labs.i18n.ListFormatSymbols_el', 'goog.labs.i18n.ListFormatSymbols_en', 'goog.labs.i18n.ListFormatSymbols_fr', 'goog.labs.i18n.ListFormatSymbols_ml', 'goog.labs.i18n.ListFormatSymbols_zu', 'goog.testing.jsunit']);
                +goog.addDependency("labs/i18n/listsymbols.js", ['goog.labs.i18n.ListFormatSymbols', 'goog.labs.i18n.ListFormatSymbols_af', 'goog.labs.i18n.ListFormatSymbols_am', 'goog.labs.i18n.ListFormatSymbols_ar', 'goog.labs.i18n.ListFormatSymbols_ar_DZ', 'goog.labs.i18n.ListFormatSymbols_az', 'goog.labs.i18n.ListFormatSymbols_be', 'goog.labs.i18n.ListFormatSymbols_bg', 'goog.labs.i18n.ListFormatSymbols_bn', 'goog.labs.i18n.ListFormatSymbols_br', 'goog.labs.i18n.ListFormatSymbols_bs', 'goog.labs.i18n.ListFormatSymbols_ca', 'goog.labs.i18n.ListFormatSymbols_chr', 'goog.labs.i18n.ListFormatSymbols_cs', 'goog.labs.i18n.ListFormatSymbols_cy', 'goog.labs.i18n.ListFormatSymbols_da', 'goog.labs.i18n.ListFormatSymbols_de', 'goog.labs.i18n.ListFormatSymbols_de_AT', 'goog.labs.i18n.ListFormatSymbols_de_CH', 'goog.labs.i18n.ListFormatSymbols_el', 'goog.labs.i18n.ListFormatSymbols_en', 'goog.labs.i18n.ListFormatSymbols_en_AU', 'goog.labs.i18n.ListFormatSymbols_en_CA', 'goog.labs.i18n.ListFormatSymbols_en_GB', 'goog.labs.i18n.ListFormatSymbols_en_IE', 'goog.labs.i18n.ListFormatSymbols_en_IN', 'goog.labs.i18n.ListFormatSymbols_en_SG', 'goog.labs.i18n.ListFormatSymbols_en_US', 'goog.labs.i18n.ListFormatSymbols_en_ZA', 'goog.labs.i18n.ListFormatSymbols_es', 'goog.labs.i18n.ListFormatSymbols_es_419', 'goog.labs.i18n.ListFormatSymbols_es_ES', 'goog.labs.i18n.ListFormatSymbols_es_MX', 'goog.labs.i18n.ListFormatSymbols_es_US', 'goog.labs.i18n.ListFormatSymbols_et', 'goog.labs.i18n.ListFormatSymbols_eu', 'goog.labs.i18n.ListFormatSymbols_fa', 'goog.labs.i18n.ListFormatSymbols_fi', 'goog.labs.i18n.ListFormatSymbols_fil', 'goog.labs.i18n.ListFormatSymbols_fr', 'goog.labs.i18n.ListFormatSymbols_fr_CA', 'goog.labs.i18n.ListFormatSymbols_ga', 'goog.labs.i18n.ListFormatSymbols_gl', 'goog.labs.i18n.ListFormatSymbols_gsw', 'goog.labs.i18n.ListFormatSymbols_gu', 'goog.labs.i18n.ListFormatSymbols_haw', 'goog.labs.i18n.ListFormatSymbols_he', 'goog.labs.i18n.ListFormatSymbols_hi', 'goog.labs.i18n.ListFormatSymbols_hr', 'goog.labs.i18n.ListFormatSymbols_hu', 'goog.labs.i18n.ListFormatSymbols_hy', 'goog.labs.i18n.ListFormatSymbols_id', 'goog.labs.i18n.ListFormatSymbols_in', 'goog.labs.i18n.ListFormatSymbols_is', 'goog.labs.i18n.ListFormatSymbols_it', 'goog.labs.i18n.ListFormatSymbols_iw', 'goog.labs.i18n.ListFormatSymbols_ja', 'goog.labs.i18n.ListFormatSymbols_ka', 'goog.labs.i18n.ListFormatSymbols_kk', 'goog.labs.i18n.ListFormatSymbols_km', 'goog.labs.i18n.ListFormatSymbols_kn', 'goog.labs.i18n.ListFormatSymbols_ko', 'goog.labs.i18n.ListFormatSymbols_ky', 'goog.labs.i18n.ListFormatSymbols_ln', 'goog.labs.i18n.ListFormatSymbols_lo', 'goog.labs.i18n.ListFormatSymbols_lt', 'goog.labs.i18n.ListFormatSymbols_lv', 'goog.labs.i18n.ListFormatSymbols_mk', 'goog.labs.i18n.ListFormatSymbols_ml', 'goog.labs.i18n.ListFormatSymbols_mn', 'goog.labs.i18n.ListFormatSymbols_mo', 'goog.labs.i18n.ListFormatSymbols_mr', 'goog.labs.i18n.ListFormatSymbols_ms', 'goog.labs.i18n.ListFormatSymbols_mt', 'goog.labs.i18n.ListFormatSymbols_my', 'goog.labs.i18n.ListFormatSymbols_nb', 'goog.labs.i18n.ListFormatSymbols_ne', 'goog.labs.i18n.ListFormatSymbols_nl', 'goog.labs.i18n.ListFormatSymbols_no', 'goog.labs.i18n.ListFormatSymbols_no_NO', 'goog.labs.i18n.ListFormatSymbols_or', 'goog.labs.i18n.ListFormatSymbols_pa', 'goog.labs.i18n.ListFormatSymbols_pl', 'goog.labs.i18n.ListFormatSymbols_pt', 'goog.labs.i18n.ListFormatSymbols_pt_BR', 'goog.labs.i18n.ListFormatSymbols_pt_PT', 'goog.labs.i18n.ListFormatSymbols_ro', 'goog.labs.i18n.ListFormatSymbols_ru', 'goog.labs.i18n.ListFormatSymbols_sh', 'goog.labs.i18n.ListFormatSymbols_si', 'goog.labs.i18n.ListFormatSymbols_sk', 'goog.labs.i18n.ListFormatSymbols_sl', 'goog.labs.i18n.ListFormatSymbols_sq', 'goog.labs.i18n.ListFormatSymbols_sr', 'goog.labs.i18n.ListFormatSymbols_sr_Latn', 'goog.labs.i18n.ListFormatSymbols_sv', 'goog.labs.i18n.ListFormatSymbols_sw', 'goog.labs.i18n.ListFormatSymbols_ta', 'goog.labs.i18n.ListFormatSymbols_te', 'goog.labs.i18n.ListFormatSymbols_th', 'goog.labs.i18n.ListFormatSymbols_tl', 'goog.labs.i18n.ListFormatSymbols_tr', 'goog.labs.i18n.ListFormatSymbols_uk', 'goog.labs.i18n.ListFormatSymbols_ur', 'goog.labs.i18n.ListFormatSymbols_uz', 'goog.labs.i18n.ListFormatSymbols_vi', 'goog.labs.i18n.ListFormatSymbols_zh', 'goog.labs.i18n.ListFormatSymbols_zh_CN', 'goog.labs.i18n.ListFormatSymbols_zh_HK', 'goog.labs.i18n.ListFormatSymbols_zh_TW', 'goog.labs.i18n.ListFormatSymbols_zu'], []);
                +goog.addDependency("labs/i18n/listsymbolsext.js", ['goog.labs.i18n.ListFormatSymbolsExt', 'goog.labs.i18n.ListFormatSymbols_af_NA', 'goog.labs.i18n.ListFormatSymbols_af_ZA', 'goog.labs.i18n.ListFormatSymbols_agq', 'goog.labs.i18n.ListFormatSymbols_agq_CM', 'goog.labs.i18n.ListFormatSymbols_ak', 'goog.labs.i18n.ListFormatSymbols_ak_GH', 'goog.labs.i18n.ListFormatSymbols_am_ET', 'goog.labs.i18n.ListFormatSymbols_ar_001', 'goog.labs.i18n.ListFormatSymbols_ar_AE', 'goog.labs.i18n.ListFormatSymbols_ar_BH', 'goog.labs.i18n.ListFormatSymbols_ar_DJ', 'goog.labs.i18n.ListFormatSymbols_ar_EG', 'goog.labs.i18n.ListFormatSymbols_ar_EH', 'goog.labs.i18n.ListFormatSymbols_ar_ER', 'goog.labs.i18n.ListFormatSymbols_ar_IL', 'goog.labs.i18n.ListFormatSymbols_ar_IQ', 'goog.labs.i18n.ListFormatSymbols_ar_JO', 'goog.labs.i18n.ListFormatSymbols_ar_KM', 'goog.labs.i18n.ListFormatSymbols_ar_KW', 'goog.labs.i18n.ListFormatSymbols_ar_LB', 'goog.labs.i18n.ListFormatSymbols_ar_LY', 'goog.labs.i18n.ListFormatSymbols_ar_MA', 'goog.labs.i18n.ListFormatSymbols_ar_MR', 'goog.labs.i18n.ListFormatSymbols_ar_OM', 'goog.labs.i18n.ListFormatSymbols_ar_PS', 'goog.labs.i18n.ListFormatSymbols_ar_QA', 'goog.labs.i18n.ListFormatSymbols_ar_SA', 'goog.labs.i18n.ListFormatSymbols_ar_SD', 'goog.labs.i18n.ListFormatSymbols_ar_SO', 'goog.labs.i18n.ListFormatSymbols_ar_SS', 'goog.labs.i18n.ListFormatSymbols_ar_SY', 'goog.labs.i18n.ListFormatSymbols_ar_TD', 'goog.labs.i18n.ListFormatSymbols_ar_TN', 'goog.labs.i18n.ListFormatSymbols_ar_XB', 'goog.labs.i18n.ListFormatSymbols_ar_YE', 'goog.labs.i18n.ListFormatSymbols_as', 'goog.labs.i18n.ListFormatSymbols_as_IN', 'goog.labs.i18n.ListFormatSymbols_asa', 'goog.labs.i18n.ListFormatSymbols_asa_TZ', 'goog.labs.i18n.ListFormatSymbols_ast', 'goog.labs.i18n.ListFormatSymbols_ast_ES', 'goog.labs.i18n.ListFormatSymbols_az_Cyrl', 'goog.labs.i18n.ListFormatSymbols_az_Cyrl_AZ', 'goog.labs.i18n.ListFormatSymbols_az_Latn', 'goog.labs.i18n.ListFormatSymbols_az_Latn_AZ', 'goog.labs.i18n.ListFormatSymbols_bas', 'goog.labs.i18n.ListFormatSymbols_bas_CM', 'goog.labs.i18n.ListFormatSymbols_be_BY', 'goog.labs.i18n.ListFormatSymbols_bem', 'goog.labs.i18n.ListFormatSymbols_bem_ZM', 'goog.labs.i18n.ListFormatSymbols_bez', 'goog.labs.i18n.ListFormatSymbols_bez_TZ', 'goog.labs.i18n.ListFormatSymbols_bg_BG', 'goog.labs.i18n.ListFormatSymbols_bm', 'goog.labs.i18n.ListFormatSymbols_bm_ML', 'goog.labs.i18n.ListFormatSymbols_bn_BD', 'goog.labs.i18n.ListFormatSymbols_bn_IN', 'goog.labs.i18n.ListFormatSymbols_bo', 'goog.labs.i18n.ListFormatSymbols_bo_CN', 'goog.labs.i18n.ListFormatSymbols_bo_IN', 'goog.labs.i18n.ListFormatSymbols_br_FR', 'goog.labs.i18n.ListFormatSymbols_brx', 'goog.labs.i18n.ListFormatSymbols_brx_IN', 'goog.labs.i18n.ListFormatSymbols_bs_Cyrl', 'goog.labs.i18n.ListFormatSymbols_bs_Cyrl_BA', 'goog.labs.i18n.ListFormatSymbols_bs_Latn', 'goog.labs.i18n.ListFormatSymbols_bs_Latn_BA', 'goog.labs.i18n.ListFormatSymbols_ca_AD', 'goog.labs.i18n.ListFormatSymbols_ca_ES', 'goog.labs.i18n.ListFormatSymbols_ca_FR', 'goog.labs.i18n.ListFormatSymbols_ca_IT', 'goog.labs.i18n.ListFormatSymbols_ce', 'goog.labs.i18n.ListFormatSymbols_ce_RU', 'goog.labs.i18n.ListFormatSymbols_cgg', 'goog.labs.i18n.ListFormatSymbols_cgg_UG', 'goog.labs.i18n.ListFormatSymbols_chr_US', 'goog.labs.i18n.ListFormatSymbols_ckb', 'goog.labs.i18n.ListFormatSymbols_ckb_IQ', 'goog.labs.i18n.ListFormatSymbols_ckb_IR', 'goog.labs.i18n.ListFormatSymbols_cs_CZ', 'goog.labs.i18n.ListFormatSymbols_cy_GB', 'goog.labs.i18n.ListFormatSymbols_da_DK', 'goog.labs.i18n.ListFormatSymbols_da_GL', 'goog.labs.i18n.ListFormatSymbols_dav', 'goog.labs.i18n.ListFormatSymbols_dav_KE', 'goog.labs.i18n.ListFormatSymbols_de_BE', 'goog.labs.i18n.ListFormatSymbols_de_DE', 'goog.labs.i18n.ListFormatSymbols_de_IT', 'goog.labs.i18n.ListFormatSymbols_de_LI', 'goog.labs.i18n.ListFormatSymbols_de_LU', 'goog.labs.i18n.ListFormatSymbols_dje', 'goog.labs.i18n.ListFormatSymbols_dje_NE', 'goog.labs.i18n.ListFormatSymbols_dsb', 'goog.labs.i18n.ListFormatSymbols_dsb_DE', 'goog.labs.i18n.ListFormatSymbols_dua', 'goog.labs.i18n.ListFormatSymbols_dua_CM', 'goog.labs.i18n.ListFormatSymbols_dyo', 'goog.labs.i18n.ListFormatSymbols_dyo_SN', 'goog.labs.i18n.ListFormatSymbols_dz', 'goog.labs.i18n.ListFormatSymbols_dz_BT', 'goog.labs.i18n.ListFormatSymbols_ebu', 'goog.labs.i18n.ListFormatSymbols_ebu_KE', 'goog.labs.i18n.ListFormatSymbols_ee', 'goog.labs.i18n.ListFormatSymbols_ee_GH', 'goog.labs.i18n.ListFormatSymbols_ee_TG', 'goog.labs.i18n.ListFormatSymbols_el_CY', 'goog.labs.i18n.ListFormatSymbols_el_GR', 'goog.labs.i18n.ListFormatSymbols_en_001', 'goog.labs.i18n.ListFormatSymbols_en_150', 'goog.labs.i18n.ListFormatSymbols_en_AG', 'goog.labs.i18n.ListFormatSymbols_en_AI', 'goog.labs.i18n.ListFormatSymbols_en_AS', 'goog.labs.i18n.ListFormatSymbols_en_AT', 'goog.labs.i18n.ListFormatSymbols_en_BB', 'goog.labs.i18n.ListFormatSymbols_en_BE', 'goog.labs.i18n.ListFormatSymbols_en_BI', 'goog.labs.i18n.ListFormatSymbols_en_BM', 'goog.labs.i18n.ListFormatSymbols_en_BS', 'goog.labs.i18n.ListFormatSymbols_en_BW', 'goog.labs.i18n.ListFormatSymbols_en_BZ', 'goog.labs.i18n.ListFormatSymbols_en_CC', 'goog.labs.i18n.ListFormatSymbols_en_CH', 'goog.labs.i18n.ListFormatSymbols_en_CK', 'goog.labs.i18n.ListFormatSymbols_en_CM', 'goog.labs.i18n.ListFormatSymbols_en_CX', 'goog.labs.i18n.ListFormatSymbols_en_CY', 'goog.labs.i18n.ListFormatSymbols_en_DE', 'goog.labs.i18n.ListFormatSymbols_en_DG', 'goog.labs.i18n.ListFormatSymbols_en_DK', 'goog.labs.i18n.ListFormatSymbols_en_DM', 'goog.labs.i18n.ListFormatSymbols_en_ER', 'goog.labs.i18n.ListFormatSymbols_en_FI', 'goog.labs.i18n.ListFormatSymbols_en_FJ', 'goog.labs.i18n.ListFormatSymbols_en_FK', 'goog.labs.i18n.ListFormatSymbols_en_FM', 'goog.labs.i18n.ListFormatSymbols_en_GD', 'goog.labs.i18n.ListFormatSymbols_en_GG', 'goog.labs.i18n.ListFormatSymbols_en_GH', 'goog.labs.i18n.ListFormatSymbols_en_GI', 'goog.labs.i18n.ListFormatSymbols_en_GM', 'goog.labs.i18n.ListFormatSymbols_en_GU', 'goog.labs.i18n.ListFormatSymbols_en_GY', 'goog.labs.i18n.ListFormatSymbols_en_HK', 'goog.labs.i18n.ListFormatSymbols_en_IL', 'goog.labs.i18n.ListFormatSymbols_en_IM', 'goog.labs.i18n.ListFormatSymbols_en_IO', 'goog.labs.i18n.ListFormatSymbols_en_JE', 'goog.labs.i18n.ListFormatSymbols_en_JM', 'goog.labs.i18n.ListFormatSymbols_en_KE', 'goog.labs.i18n.ListFormatSymbols_en_KI', 'goog.labs.i18n.ListFormatSymbols_en_KN', 'goog.labs.i18n.ListFormatSymbols_en_KY', 'goog.labs.i18n.ListFormatSymbols_en_LC', 'goog.labs.i18n.ListFormatSymbols_en_LR', 'goog.labs.i18n.ListFormatSymbols_en_LS', 'goog.labs.i18n.ListFormatSymbols_en_MG', 'goog.labs.i18n.ListFormatSymbols_en_MH', 'goog.labs.i18n.ListFormatSymbols_en_MO', 'goog.labs.i18n.ListFormatSymbols_en_MP', 'goog.labs.i18n.ListFormatSymbols_en_MS', 'goog.labs.i18n.ListFormatSymbols_en_MT', 'goog.labs.i18n.ListFormatSymbols_en_MU', 'goog.labs.i18n.ListFormatSymbols_en_MW', 'goog.labs.i18n.ListFormatSymbols_en_MY', 'goog.labs.i18n.ListFormatSymbols_en_NA', 'goog.labs.i18n.ListFormatSymbols_en_NF', 'goog.labs.i18n.ListFormatSymbols_en_NG', 'goog.labs.i18n.ListFormatSymbols_en_NL', 'goog.labs.i18n.ListFormatSymbols_en_NR', 'goog.labs.i18n.ListFormatSymbols_en_NU', 'goog.labs.i18n.ListFormatSymbols_en_NZ', 'goog.labs.i18n.ListFormatSymbols_en_PG', 'goog.labs.i18n.ListFormatSymbols_en_PH', 'goog.labs.i18n.ListFormatSymbols_en_PK', 'goog.labs.i18n.ListFormatSymbols_en_PN', 'goog.labs.i18n.ListFormatSymbols_en_PR', 'goog.labs.i18n.ListFormatSymbols_en_PW', 'goog.labs.i18n.ListFormatSymbols_en_RW', 'goog.labs.i18n.ListFormatSymbols_en_SB', 'goog.labs.i18n.ListFormatSymbols_en_SC', 'goog.labs.i18n.ListFormatSymbols_en_SD', 'goog.labs.i18n.ListFormatSymbols_en_SE', 'goog.labs.i18n.ListFormatSymbols_en_SH', 'goog.labs.i18n.ListFormatSymbols_en_SI', 'goog.labs.i18n.ListFormatSymbols_en_SL', 'goog.labs.i18n.ListFormatSymbols_en_SS', 'goog.labs.i18n.ListFormatSymbols_en_SX', 'goog.labs.i18n.ListFormatSymbols_en_SZ', 'goog.labs.i18n.ListFormatSymbols_en_TC', 'goog.labs.i18n.ListFormatSymbols_en_TK', 'goog.labs.i18n.ListFormatSymbols_en_TO', 'goog.labs.i18n.ListFormatSymbols_en_TT', 'goog.labs.i18n.ListFormatSymbols_en_TV', 'goog.labs.i18n.ListFormatSymbols_en_TZ', 'goog.labs.i18n.ListFormatSymbols_en_UG', 'goog.labs.i18n.ListFormatSymbols_en_UM', 'goog.labs.i18n.ListFormatSymbols_en_US_POSIX', 'goog.labs.i18n.ListFormatSymbols_en_VC', 'goog.labs.i18n.ListFormatSymbols_en_VG', 'goog.labs.i18n.ListFormatSymbols_en_VI', 'goog.labs.i18n.ListFormatSymbols_en_VU', 'goog.labs.i18n.ListFormatSymbols_en_WS', 'goog.labs.i18n.ListFormatSymbols_en_XA', 'goog.labs.i18n.ListFormatSymbols_en_ZM', 'goog.labs.i18n.ListFormatSymbols_en_ZW', 'goog.labs.i18n.ListFormatSymbols_eo', 'goog.labs.i18n.ListFormatSymbols_es_AR', 'goog.labs.i18n.ListFormatSymbols_es_BO', 'goog.labs.i18n.ListFormatSymbols_es_BR', 'goog.labs.i18n.ListFormatSymbols_es_CL', 'goog.labs.i18n.ListFormatSymbols_es_CO', 'goog.labs.i18n.ListFormatSymbols_es_CR', 'goog.labs.i18n.ListFormatSymbols_es_CU', 'goog.labs.i18n.ListFormatSymbols_es_DO', 'goog.labs.i18n.ListFormatSymbols_es_EA', 'goog.labs.i18n.ListFormatSymbols_es_EC', 'goog.labs.i18n.ListFormatSymbols_es_GQ', 'goog.labs.i18n.ListFormatSymbols_es_GT', 'goog.labs.i18n.ListFormatSymbols_es_HN', 'goog.labs.i18n.ListFormatSymbols_es_IC', 'goog.labs.i18n.ListFormatSymbols_es_NI', 'goog.labs.i18n.ListFormatSymbols_es_PA', 'goog.labs.i18n.ListFormatSymbols_es_PE', 'goog.labs.i18n.ListFormatSymbols_es_PH', 'goog.labs.i18n.ListFormatSymbols_es_PR', 'goog.labs.i18n.ListFormatSymbols_es_PY', 'goog.labs.i18n.ListFormatSymbols_es_SV', 'goog.labs.i18n.ListFormatSymbols_es_UY', 'goog.labs.i18n.ListFormatSymbols_es_VE', 'goog.labs.i18n.ListFormatSymbols_et_EE', 'goog.labs.i18n.ListFormatSymbols_eu_ES', 'goog.labs.i18n.ListFormatSymbols_ewo', 'goog.labs.i18n.ListFormatSymbols_ewo_CM', 'goog.labs.i18n.ListFormatSymbols_fa_AF', 'goog.labs.i18n.ListFormatSymbols_fa_IR', 'goog.labs.i18n.ListFormatSymbols_ff', 'goog.labs.i18n.ListFormatSymbols_ff_CM', 'goog.labs.i18n.ListFormatSymbols_ff_GN', 'goog.labs.i18n.ListFormatSymbols_ff_MR', 'goog.labs.i18n.ListFormatSymbols_ff_SN', 'goog.labs.i18n.ListFormatSymbols_fi_FI', 'goog.labs.i18n.ListFormatSymbols_fil_PH', 'goog.labs.i18n.ListFormatSymbols_fo', 'goog.labs.i18n.ListFormatSymbols_fo_DK', 'goog.labs.i18n.ListFormatSymbols_fo_FO', 'goog.labs.i18n.ListFormatSymbols_fr_BE', 'goog.labs.i18n.ListFormatSymbols_fr_BF', 'goog.labs.i18n.ListFormatSymbols_fr_BI', 'goog.labs.i18n.ListFormatSymbols_fr_BJ', 'goog.labs.i18n.ListFormatSymbols_fr_BL', 'goog.labs.i18n.ListFormatSymbols_fr_CD', 'goog.labs.i18n.ListFormatSymbols_fr_CF', 'goog.labs.i18n.ListFormatSymbols_fr_CG', 'goog.labs.i18n.ListFormatSymbols_fr_CH', 'goog.labs.i18n.ListFormatSymbols_fr_CI', 'goog.labs.i18n.ListFormatSymbols_fr_CM', 'goog.labs.i18n.ListFormatSymbols_fr_DJ', 'goog.labs.i18n.ListFormatSymbols_fr_DZ', 'goog.labs.i18n.ListFormatSymbols_fr_FR', 'goog.labs.i18n.ListFormatSymbols_fr_GA', 'goog.labs.i18n.ListFormatSymbols_fr_GF', 'goog.labs.i18n.ListFormatSymbols_fr_GN', 'goog.labs.i18n.ListFormatSymbols_fr_GP', 'goog.labs.i18n.ListFormatSymbols_fr_GQ', 'goog.labs.i18n.ListFormatSymbols_fr_HT', 'goog.labs.i18n.ListFormatSymbols_fr_KM', 'goog.labs.i18n.ListFormatSymbols_fr_LU', 'goog.labs.i18n.ListFormatSymbols_fr_MA', 'goog.labs.i18n.ListFormatSymbols_fr_MC', 'goog.labs.i18n.ListFormatSymbols_fr_MF', 'goog.labs.i18n.ListFormatSymbols_fr_MG', 'goog.labs.i18n.ListFormatSymbols_fr_ML', 'goog.labs.i18n.ListFormatSymbols_fr_MQ', 'goog.labs.i18n.ListFormatSymbols_fr_MR', 'goog.labs.i18n.ListFormatSymbols_fr_MU', 'goog.labs.i18n.ListFormatSymbols_fr_NC', 'goog.labs.i18n.ListFormatSymbols_fr_NE', 'goog.labs.i18n.ListFormatSymbols_fr_PF', 'goog.labs.i18n.ListFormatSymbols_fr_PM', 'goog.labs.i18n.ListFormatSymbols_fr_RE', 'goog.labs.i18n.ListFormatSymbols_fr_RW', 'goog.labs.i18n.ListFormatSymbols_fr_SC', 'goog.labs.i18n.ListFormatSymbols_fr_SN', 'goog.labs.i18n.ListFormatSymbols_fr_SY', 'goog.labs.i18n.ListFormatSymbols_fr_TD', 'goog.labs.i18n.ListFormatSymbols_fr_TG', 'goog.labs.i18n.ListFormatSymbols_fr_TN', 'goog.labs.i18n.ListFormatSymbols_fr_VU', 'goog.labs.i18n.ListFormatSymbols_fr_WF', 'goog.labs.i18n.ListFormatSymbols_fr_YT', 'goog.labs.i18n.ListFormatSymbols_fur', 'goog.labs.i18n.ListFormatSymbols_fur_IT', 'goog.labs.i18n.ListFormatSymbols_fy', 'goog.labs.i18n.ListFormatSymbols_fy_NL', 'goog.labs.i18n.ListFormatSymbols_ga_IE', 'goog.labs.i18n.ListFormatSymbols_gd', 'goog.labs.i18n.ListFormatSymbols_gd_GB', 'goog.labs.i18n.ListFormatSymbols_gl_ES', 'goog.labs.i18n.ListFormatSymbols_gsw_CH', 'goog.labs.i18n.ListFormatSymbols_gsw_FR', 'goog.labs.i18n.ListFormatSymbols_gsw_LI', 'goog.labs.i18n.ListFormatSymbols_gu_IN', 'goog.labs.i18n.ListFormatSymbols_guz', 'goog.labs.i18n.ListFormatSymbols_guz_KE', 'goog.labs.i18n.ListFormatSymbols_gv', 'goog.labs.i18n.ListFormatSymbols_gv_IM', 'goog.labs.i18n.ListFormatSymbols_ha', 'goog.labs.i18n.ListFormatSymbols_ha_GH', 'goog.labs.i18n.ListFormatSymbols_ha_NE', 'goog.labs.i18n.ListFormatSymbols_ha_NG', 'goog.labs.i18n.ListFormatSymbols_haw_US', 'goog.labs.i18n.ListFormatSymbols_he_IL', 'goog.labs.i18n.ListFormatSymbols_hi_IN', 'goog.labs.i18n.ListFormatSymbols_hr_BA', 'goog.labs.i18n.ListFormatSymbols_hr_HR', 'goog.labs.i18n.ListFormatSymbols_hsb', 'goog.labs.i18n.ListFormatSymbols_hsb_DE', 'goog.labs.i18n.ListFormatSymbols_hu_HU', 'goog.labs.i18n.ListFormatSymbols_hy_AM', 'goog.labs.i18n.ListFormatSymbols_id_ID', 'goog.labs.i18n.ListFormatSymbols_ig', 'goog.labs.i18n.ListFormatSymbols_ig_NG', 'goog.labs.i18n.ListFormatSymbols_ii', 'goog.labs.i18n.ListFormatSymbols_ii_CN', 'goog.labs.i18n.ListFormatSymbols_is_IS', 'goog.labs.i18n.ListFormatSymbols_it_CH', 'goog.labs.i18n.ListFormatSymbols_it_IT', 'goog.labs.i18n.ListFormatSymbols_it_SM', 'goog.labs.i18n.ListFormatSymbols_ja_JP', 'goog.labs.i18n.ListFormatSymbols_jgo', 'goog.labs.i18n.ListFormatSymbols_jgo_CM', 'goog.labs.i18n.ListFormatSymbols_jmc', 'goog.labs.i18n.ListFormatSymbols_jmc_TZ', 'goog.labs.i18n.ListFormatSymbols_ka_GE', 'goog.labs.i18n.ListFormatSymbols_kab', 'goog.labs.i18n.ListFormatSymbols_kab_DZ', 'goog.labs.i18n.ListFormatSymbols_kam', 'goog.labs.i18n.ListFormatSymbols_kam_KE', 'goog.labs.i18n.ListFormatSymbols_kde', 'goog.labs.i18n.ListFormatSymbols_kde_TZ', 'goog.labs.i18n.ListFormatSymbols_kea', 'goog.labs.i18n.ListFormatSymbols_kea_CV', 'goog.labs.i18n.ListFormatSymbols_khq', 'goog.labs.i18n.ListFormatSymbols_khq_ML', 'goog.labs.i18n.ListFormatSymbols_ki', 'goog.labs.i18n.ListFormatSymbols_ki_KE', 'goog.labs.i18n.ListFormatSymbols_kk_KZ', 'goog.labs.i18n.ListFormatSymbols_kkj', 'goog.labs.i18n.ListFormatSymbols_kkj_CM', 'goog.labs.i18n.ListFormatSymbols_kl', 'goog.labs.i18n.ListFormatSymbols_kl_GL', 'goog.labs.i18n.ListFormatSymbols_kln', 'goog.labs.i18n.ListFormatSymbols_kln_KE', 'goog.labs.i18n.ListFormatSymbols_km_KH', 'goog.labs.i18n.ListFormatSymbols_kn_IN', 'goog.labs.i18n.ListFormatSymbols_ko_KP', 'goog.labs.i18n.ListFormatSymbols_ko_KR', 'goog.labs.i18n.ListFormatSymbols_kok', 'goog.labs.i18n.ListFormatSymbols_kok_IN', 'goog.labs.i18n.ListFormatSymbols_ks', 'goog.labs.i18n.ListFormatSymbols_ks_IN', 'goog.labs.i18n.ListFormatSymbols_ksb', 'goog.labs.i18n.ListFormatSymbols_ksb_TZ', 'goog.labs.i18n.ListFormatSymbols_ksf', 'goog.labs.i18n.ListFormatSymbols_ksf_CM', 'goog.labs.i18n.ListFormatSymbols_ksh', 'goog.labs.i18n.ListFormatSymbols_ksh_DE', 'goog.labs.i18n.ListFormatSymbols_kw', 'goog.labs.i18n.ListFormatSymbols_kw_GB', 'goog.labs.i18n.ListFormatSymbols_ky_KG', 'goog.labs.i18n.ListFormatSymbols_lag', 'goog.labs.i18n.ListFormatSymbols_lag_TZ', 'goog.labs.i18n.ListFormatSymbols_lb', 'goog.labs.i18n.ListFormatSymbols_lb_LU', 'goog.labs.i18n.ListFormatSymbols_lg', 'goog.labs.i18n.ListFormatSymbols_lg_UG', 'goog.labs.i18n.ListFormatSymbols_lkt', 'goog.labs.i18n.ListFormatSymbols_lkt_US', 'goog.labs.i18n.ListFormatSymbols_ln_AO', 'goog.labs.i18n.ListFormatSymbols_ln_CD', 'goog.labs.i18n.ListFormatSymbols_ln_CF', 'goog.labs.i18n.ListFormatSymbols_ln_CG', 'goog.labs.i18n.ListFormatSymbols_lo_LA', 'goog.labs.i18n.ListFormatSymbols_lrc', 'goog.labs.i18n.ListFormatSymbols_lrc_IQ', 'goog.labs.i18n.ListFormatSymbols_lrc_IR', 'goog.labs.i18n.ListFormatSymbols_lt_LT', 'goog.labs.i18n.ListFormatSymbols_lu', 'goog.labs.i18n.ListFormatSymbols_lu_CD', 'goog.labs.i18n.ListFormatSymbols_luo', 'goog.labs.i18n.ListFormatSymbols_luo_KE', 'goog.labs.i18n.ListFormatSymbols_luy', 'goog.labs.i18n.ListFormatSymbols_luy_KE', 'goog.labs.i18n.ListFormatSymbols_lv_LV', 'goog.labs.i18n.ListFormatSymbols_mas', 'goog.labs.i18n.ListFormatSymbols_mas_KE', 'goog.labs.i18n.ListFormatSymbols_mas_TZ', 'goog.labs.i18n.ListFormatSymbols_mer', 'goog.labs.i18n.ListFormatSymbols_mer_KE', 'goog.labs.i18n.ListFormatSymbols_mfe', 'goog.labs.i18n.ListFormatSymbols_mfe_MU', 'goog.labs.i18n.ListFormatSymbols_mg', 'goog.labs.i18n.ListFormatSymbols_mg_MG', 'goog.labs.i18n.ListFormatSymbols_mgh', 'goog.labs.i18n.ListFormatSymbols_mgh_MZ', 'goog.labs.i18n.ListFormatSymbols_mgo', 'goog.labs.i18n.ListFormatSymbols_mgo_CM', 'goog.labs.i18n.ListFormatSymbols_mk_MK', 'goog.labs.i18n.ListFormatSymbols_ml_IN', 'goog.labs.i18n.ListFormatSymbols_mn_MN', 'goog.labs.i18n.ListFormatSymbols_mr_IN', 'goog.labs.i18n.ListFormatSymbols_ms_BN', 'goog.labs.i18n.ListFormatSymbols_ms_MY', 'goog.labs.i18n.ListFormatSymbols_ms_SG', 'goog.labs.i18n.ListFormatSymbols_mt_MT', 'goog.labs.i18n.ListFormatSymbols_mua', 'goog.labs.i18n.ListFormatSymbols_mua_CM', 'goog.labs.i18n.ListFormatSymbols_my_MM', 'goog.labs.i18n.ListFormatSymbols_mzn', 'goog.labs.i18n.ListFormatSymbols_mzn_IR', 'goog.labs.i18n.ListFormatSymbols_naq', 'goog.labs.i18n.ListFormatSymbols_naq_NA', 'goog.labs.i18n.ListFormatSymbols_nb_NO', 'goog.labs.i18n.ListFormatSymbols_nb_SJ', 'goog.labs.i18n.ListFormatSymbols_nd', 'goog.labs.i18n.ListFormatSymbols_nd_ZW', 'goog.labs.i18n.ListFormatSymbols_nds', 'goog.labs.i18n.ListFormatSymbols_nds_DE', 'goog.labs.i18n.ListFormatSymbols_nds_NL', 'goog.labs.i18n.ListFormatSymbols_ne_IN', 'goog.labs.i18n.ListFormatSymbols_ne_NP', 'goog.labs.i18n.ListFormatSymbols_nl_AW', 'goog.labs.i18n.ListFormatSymbols_nl_BE', 'goog.labs.i18n.ListFormatSymbols_nl_BQ', 'goog.labs.i18n.ListFormatSymbols_nl_CW', 'goog.labs.i18n.ListFormatSymbols_nl_NL', 'goog.labs.i18n.ListFormatSymbols_nl_SR', 'goog.labs.i18n.ListFormatSymbols_nl_SX', 'goog.labs.i18n.ListFormatSymbols_nmg', 'goog.labs.i18n.ListFormatSymbols_nmg_CM', 'goog.labs.i18n.ListFormatSymbols_nn', 'goog.labs.i18n.ListFormatSymbols_nn_NO', 'goog.labs.i18n.ListFormatSymbols_nnh', 'goog.labs.i18n.ListFormatSymbols_nnh_CM', 'goog.labs.i18n.ListFormatSymbols_nus', 'goog.labs.i18n.ListFormatSymbols_nus_SS', 'goog.labs.i18n.ListFormatSymbols_nyn', 'goog.labs.i18n.ListFormatSymbols_nyn_UG', 'goog.labs.i18n.ListFormatSymbols_om', 'goog.labs.i18n.ListFormatSymbols_om_ET', 'goog.labs.i18n.ListFormatSymbols_om_KE', 'goog.labs.i18n.ListFormatSymbols_or_IN', 'goog.labs.i18n.ListFormatSymbols_os', 'goog.labs.i18n.ListFormatSymbols_os_GE', 'goog.labs.i18n.ListFormatSymbols_os_RU', 'goog.labs.i18n.ListFormatSymbols_pa_Arab', 'goog.labs.i18n.ListFormatSymbols_pa_Arab_PK', 'goog.labs.i18n.ListFormatSymbols_pa_Guru', 'goog.labs.i18n.ListFormatSymbols_pa_Guru_IN', 'goog.labs.i18n.ListFormatSymbols_pl_PL', 'goog.labs.i18n.ListFormatSymbols_ps', 'goog.labs.i18n.ListFormatSymbols_ps_AF', 'goog.labs.i18n.ListFormatSymbols_pt_AO', 'goog.labs.i18n.ListFormatSymbols_pt_CH', 'goog.labs.i18n.ListFormatSymbols_pt_CV', 'goog.labs.i18n.ListFormatSymbols_pt_GQ', 'goog.labs.i18n.ListFormatSymbols_pt_GW', 'goog.labs.i18n.ListFormatSymbols_pt_LU', 'goog.labs.i18n.ListFormatSymbols_pt_MO', 'goog.labs.i18n.ListFormatSymbols_pt_MZ', 'goog.labs.i18n.ListFormatSymbols_pt_ST', 'goog.labs.i18n.ListFormatSymbols_pt_TL', 'goog.labs.i18n.ListFormatSymbols_qu', 'goog.labs.i18n.ListFormatSymbols_qu_BO', 'goog.labs.i18n.ListFormatSymbols_qu_EC', 'goog.labs.i18n.ListFormatSymbols_qu_PE', 'goog.labs.i18n.ListFormatSymbols_rm', 'goog.labs.i18n.ListFormatSymbols_rm_CH', 'goog.labs.i18n.ListFormatSymbols_rn', 'goog.labs.i18n.ListFormatSymbols_rn_BI', 'goog.labs.i18n.ListFormatSymbols_ro_MD', 'goog.labs.i18n.ListFormatSymbols_ro_RO', 'goog.labs.i18n.ListFormatSymbols_rof', 'goog.labs.i18n.ListFormatSymbols_rof_TZ', 'goog.labs.i18n.ListFormatSymbols_ru_BY', 'goog.labs.i18n.ListFormatSymbols_ru_KG', 'goog.labs.i18n.ListFormatSymbols_ru_KZ', 'goog.labs.i18n.ListFormatSymbols_ru_MD', 'goog.labs.i18n.ListFormatSymbols_ru_RU', 'goog.labs.i18n.ListFormatSymbols_ru_UA', 'goog.labs.i18n.ListFormatSymbols_rw', 'goog.labs.i18n.ListFormatSymbols_rw_RW', 'goog.labs.i18n.ListFormatSymbols_rwk', 'goog.labs.i18n.ListFormatSymbols_rwk_TZ', 'goog.labs.i18n.ListFormatSymbols_sah', 'goog.labs.i18n.ListFormatSymbols_sah_RU', 'goog.labs.i18n.ListFormatSymbols_saq', 'goog.labs.i18n.ListFormatSymbols_saq_KE', 'goog.labs.i18n.ListFormatSymbols_sbp', 'goog.labs.i18n.ListFormatSymbols_sbp_TZ', 'goog.labs.i18n.ListFormatSymbols_se', 'goog.labs.i18n.ListFormatSymbols_se_FI', 'goog.labs.i18n.ListFormatSymbols_se_NO', 'goog.labs.i18n.ListFormatSymbols_se_SE', 'goog.labs.i18n.ListFormatSymbols_seh', 'goog.labs.i18n.ListFormatSymbols_seh_MZ', 'goog.labs.i18n.ListFormatSymbols_ses', 'goog.labs.i18n.ListFormatSymbols_ses_ML', 'goog.labs.i18n.ListFormatSymbols_sg', 'goog.labs.i18n.ListFormatSymbols_sg_CF', 'goog.labs.i18n.ListFormatSymbols_shi', 'goog.labs.i18n.ListFormatSymbols_shi_Latn', 'goog.labs.i18n.ListFormatSymbols_shi_Latn_MA', 'goog.labs.i18n.ListFormatSymbols_shi_Tfng', 'goog.labs.i18n.ListFormatSymbols_shi_Tfng_MA', 'goog.labs.i18n.ListFormatSymbols_si_LK', 'goog.labs.i18n.ListFormatSymbols_sk_SK', 'goog.labs.i18n.ListFormatSymbols_sl_SI', 'goog.labs.i18n.ListFormatSymbols_smn', 'goog.labs.i18n.ListFormatSymbols_smn_FI', 'goog.labs.i18n.ListFormatSymbols_sn', 'goog.labs.i18n.ListFormatSymbols_sn_ZW', 'goog.labs.i18n.ListFormatSymbols_so', 'goog.labs.i18n.ListFormatSymbols_so_DJ', 'goog.labs.i18n.ListFormatSymbols_so_ET', 'goog.labs.i18n.ListFormatSymbols_so_KE', 'goog.labs.i18n.ListFormatSymbols_so_SO', 'goog.labs.i18n.ListFormatSymbols_sq_AL', 'goog.labs.i18n.ListFormatSymbols_sq_MK', 'goog.labs.i18n.ListFormatSymbols_sq_XK', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_BA', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_ME', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_RS', 'goog.labs.i18n.ListFormatSymbols_sr_Cyrl_XK', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_BA', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_ME', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_RS', 'goog.labs.i18n.ListFormatSymbols_sr_Latn_XK', 'goog.labs.i18n.ListFormatSymbols_sv_AX', 'goog.labs.i18n.ListFormatSymbols_sv_FI', 'goog.labs.i18n.ListFormatSymbols_sv_SE', 'goog.labs.i18n.ListFormatSymbols_sw_CD', 'goog.labs.i18n.ListFormatSymbols_sw_KE', 'goog.labs.i18n.ListFormatSymbols_sw_TZ', 'goog.labs.i18n.ListFormatSymbols_sw_UG', 'goog.labs.i18n.ListFormatSymbols_ta_IN', 'goog.labs.i18n.ListFormatSymbols_ta_LK', 'goog.labs.i18n.ListFormatSymbols_ta_MY', 'goog.labs.i18n.ListFormatSymbols_ta_SG', 'goog.labs.i18n.ListFormatSymbols_te_IN', 'goog.labs.i18n.ListFormatSymbols_teo', 'goog.labs.i18n.ListFormatSymbols_teo_KE', 'goog.labs.i18n.ListFormatSymbols_teo_UG', 'goog.labs.i18n.ListFormatSymbols_th_TH', 'goog.labs.i18n.ListFormatSymbols_ti', 'goog.labs.i18n.ListFormatSymbols_ti_ER', 'goog.labs.i18n.ListFormatSymbols_ti_ET', 'goog.labs.i18n.ListFormatSymbols_to', 'goog.labs.i18n.ListFormatSymbols_to_TO', 'goog.labs.i18n.ListFormatSymbols_tr_CY', 'goog.labs.i18n.ListFormatSymbols_tr_TR', 'goog.labs.i18n.ListFormatSymbols_twq', 'goog.labs.i18n.ListFormatSymbols_twq_NE', 'goog.labs.i18n.ListFormatSymbols_tzm', 'goog.labs.i18n.ListFormatSymbols_tzm_MA', 'goog.labs.i18n.ListFormatSymbols_ug', 'goog.labs.i18n.ListFormatSymbols_ug_CN', 'goog.labs.i18n.ListFormatSymbols_uk_UA', 'goog.labs.i18n.ListFormatSymbols_ur_IN', 'goog.labs.i18n.ListFormatSymbols_ur_PK', 'goog.labs.i18n.ListFormatSymbols_uz_Arab', 'goog.labs.i18n.ListFormatSymbols_uz_Arab_AF', 'goog.labs.i18n.ListFormatSymbols_uz_Cyrl', 'goog.labs.i18n.ListFormatSymbols_uz_Cyrl_UZ', 'goog.labs.i18n.ListFormatSymbols_uz_Latn', 'goog.labs.i18n.ListFormatSymbols_uz_Latn_UZ', 'goog.labs.i18n.ListFormatSymbols_vai', 'goog.labs.i18n.ListFormatSymbols_vai_Latn', 'goog.labs.i18n.ListFormatSymbols_vai_Latn_LR', 'goog.labs.i18n.ListFormatSymbols_vai_Vaii', 'goog.labs.i18n.ListFormatSymbols_vai_Vaii_LR', 'goog.labs.i18n.ListFormatSymbols_vi_VN', 'goog.labs.i18n.ListFormatSymbols_vun', 'goog.labs.i18n.ListFormatSymbols_vun_TZ', 'goog.labs.i18n.ListFormatSymbols_wae', 'goog.labs.i18n.ListFormatSymbols_wae_CH', 'goog.labs.i18n.ListFormatSymbols_xog', 'goog.labs.i18n.ListFormatSymbols_xog_UG', 'goog.labs.i18n.ListFormatSymbols_yav', 'goog.labs.i18n.ListFormatSymbols_yav_CM', 'goog.labs.i18n.ListFormatSymbols_yi', 'goog.labs.i18n.ListFormatSymbols_yi_001', 'goog.labs.i18n.ListFormatSymbols_yo', 'goog.labs.i18n.ListFormatSymbols_yo_BJ', 'goog.labs.i18n.ListFormatSymbols_yo_NG', 'goog.labs.i18n.ListFormatSymbols_yue', 'goog.labs.i18n.ListFormatSymbols_yue_HK', 'goog.labs.i18n.ListFormatSymbols_zgh', 'goog.labs.i18n.ListFormatSymbols_zgh_MA', 'goog.labs.i18n.ListFormatSymbols_zh_Hans', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_CN', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_HK', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_MO', 'goog.labs.i18n.ListFormatSymbols_zh_Hans_SG', 'goog.labs.i18n.ListFormatSymbols_zh_Hant', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_HK', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_MO', 'goog.labs.i18n.ListFormatSymbols_zh_Hant_TW', 'goog.labs.i18n.ListFormatSymbols_zu_ZA'], ['goog.labs.i18n.ListFormatSymbols']);
                +goog.addDependency("labs/iterable/iterable.js", [], []);
                +goog.addDependency("labs/iterable/iterable_test.js", [], ['goog.testing.jsunit']);
                +goog.addDependency("labs/mock/mock.js", ['goog.labs.mock', 'goog.labs.mock.VerificationError'], ['goog.array', 'goog.asserts', 'goog.debug', 'goog.debug.Error', 'goog.functions', 'goog.labs.mock.verification', 'goog.labs.mock.verification.VerificationMode', 'goog.object']);
                +goog.addDependency("labs/mock/mock_test.js", ['goog.labs.mockTest'], ['goog.array', 'goog.labs.mock', 'goog.labs.mock.VerificationError', 'goog.labs.testing.AnythingMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.string', 'goog.testing.jsunit']);
                +goog.addDependency("labs/mock/verificationmode.js", ['goog.labs.mock.verification', 'goog.labs.mock.verification.VerificationMode'], []);
                +goog.addDependency("labs/mock/verificationmode_test.js", [], []);
                +goog.addDependency("labs/net/image.js", ['goog.labs.net.image'], ['goog.Promise', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.net.EventType', 'goog.userAgent']);
                +goog.addDependency("labs/net/image_test.js", ['goog.labs.net.imageTest'], ['goog.labs.net.image', 'goog.string', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/net/webchannel.js", ['goog.net.WebChannel'], ['goog.events', 'goog.events.Event']);
                +goog.addDependency("labs/net/webchannel/basetestchannel.js", ['goog.labs.net.webChannel.BaseTestChannel'], ['goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.net.WebChannel']);
                +goog.addDependency("labs/net/webchannel/channel.js", ['goog.labs.net.webChannel.Channel'], []);
                +goog.addDependency("labs/net/webchannel/channelrequest.js", ['goog.labs.net.webChannel.ChannelRequest'], ['goog.Timer', 'goog.async.Throttle', 'goog.events.EventHandler', 'goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("labs/net/webchannel/channelrequest_test.js", ['goog.labs.net.webChannel.channelRequestTest'], ['goog.Uri', 'goog.functions', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/net/webchannel/connectionstate.js", ['goog.labs.net.webChannel.ConnectionState'], []);
                +goog.addDependency("labs/net/webchannel/forwardchannelrequestpool.js", ['goog.labs.net.webChannel.ForwardChannelRequestPool'], ['goog.array', 'goog.string', 'goog.structs.Set']);
                +goog.addDependency("labs/net/webchannel/forwardchannelrequestpool_test.js", ['goog.labs.net.webChannel.forwardChannelRequestPoolTest'], ['goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/netutils.js", ['goog.labs.net.webChannel.netUtils'], ['goog.Uri', 'goog.labs.net.webChannel.WebChannelDebug']);
                +goog.addDependency("labs/net/webchannel/requeststats.js", ['goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Event', 'goog.labs.net.webChannel.requestStats.ServerReachability', 'goog.labs.net.webChannel.requestStats.ServerReachabilityEvent', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.labs.net.webChannel.requestStats.StatEvent', 'goog.labs.net.webChannel.requestStats.TimingEvent'], ['goog.events.Event', 'goog.events.EventTarget']);
                +goog.addDependency("labs/net/webchannel/webchannelbase.js", ['goog.labs.net.webChannel.WebChannelBase'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.TextFormatter', 'goog.json', 'goog.labs.net.webChannel.BaseTestChannel', 'goog.labs.net.webChannel.Channel', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ConnectionState', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.Wire', 'goog.labs.net.webChannel.WireV8', 'goog.labs.net.webChannel.netUtils', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.log', 'goog.net.WebChannel', 'goog.net.XhrIo', 'goog.net.rpc.HttpCors', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.CircularBuffer']);
                +goog.addDependency("labs/net/webchannel/webchannelbase_test.js", ['goog.labs.net.webChannel.webChannelBaseTest'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.functions', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.ForwardChannelRequestPool', 'goog.labs.net.webChannel.WebChannelBase', 'goog.labs.net.webChannel.WebChannelBaseTransport', 'goog.labs.net.webChannel.WebChannelDebug', 'goog.labs.net.webChannel.Wire', 'goog.labs.net.webChannel.netUtils', 'goog.labs.net.webChannel.requestStats', 'goog.labs.net.webChannel.requestStats.Stat', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/webchannelbasetransport.js", ['goog.labs.net.webChannel.WebChannelBaseTransport'], ['goog.asserts', 'goog.events.EventTarget', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelBase', 'goog.log', 'goog.net.WebChannel', 'goog.net.WebChannelTransport', 'goog.object', 'goog.string', 'goog.string.path']);
                +goog.addDependency("labs/net/webchannel/webchannelbasetransport_test.js", ['goog.labs.net.webChannel.webChannelBaseTransportTest'], ['goog.events', 'goog.functions', 'goog.json', 'goog.labs.net.webChannel.ChannelRequest', 'goog.labs.net.webChannel.WebChannelBase', 'goog.labs.net.webChannel.WebChannelBaseTransport', 'goog.net.WebChannel', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchannel/webchanneldebug.js", ['goog.labs.net.webChannel.WebChannelDebug'], ['goog.json', 'goog.log']);
                +goog.addDependency("labs/net/webchannel/wire.js", ['goog.labs.net.webChannel.Wire'], []);
                +goog.addDependency("labs/net/webchannel/wirev8.js", ['goog.labs.net.webChannel.WireV8'], ['goog.asserts', 'goog.json', 'goog.json.NativeJsonProcessor', 'goog.labs.net.webChannel.Wire', 'goog.structs']);
                +goog.addDependency("labs/net/webchannel/wirev8_test.js", ['goog.labs.net.webChannel.WireV8Test'], ['goog.labs.net.webChannel.WireV8', 'goog.testing.jsunit']);
                +goog.addDependency("labs/net/webchanneltransport.js", ['goog.net.WebChannelTransport'], []);
                +goog.addDependency("labs/net/webchanneltransportfactory.js", ['goog.net.createWebChannelTransport'], ['goog.functions', 'goog.labs.net.webChannel.WebChannelBaseTransport']);
                +goog.addDependency("labs/net/xhr.js", ['goog.labs.net.xhr', 'goog.labs.net.xhr.Error', 'goog.labs.net.xhr.HttpError', 'goog.labs.net.xhr.Options', 'goog.labs.net.xhr.PostData', 'goog.labs.net.xhr.ResponseType', 'goog.labs.net.xhr.TimeoutError'], ['goog.Promise', 'goog.asserts', 'goog.debug.Error', 'goog.json', 'goog.net.HttpStatus', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("labs/net/xhr_test.js", ['goog.labs.net.xhrTest'], ['goog.Promise', 'goog.events', 'goog.events.EventType', 'goog.labs.net.xhr', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XmlHttp', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("labs/promise/promise.js", [], []);
                +goog.addDependency("labs/promise/promise_test.js", [], ['goog.testing.jsunit']);
                +goog.addDependency("labs/pubsub/broadcastpubsub.js", ['goog.labs.pubsub.BroadcastPubSub'], ['goog.Disposable', 'goog.Timer', 'goog.array', 'goog.async.run', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.math', 'goog.pubsub.PubSub', 'goog.storage.Storage', 'goog.storage.mechanism.HTML5LocalStorage', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("labs/pubsub/broadcastpubsub_test.js", ['goog.labs.pubsub.BroadcastPubSubTest'], ['goog.array', 'goog.debug.Logger', 'goog.json', 'goog.labs.pubsub.BroadcastPubSub', 'goog.storage.Storage', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("labs/storage/boundedcollectablestorage.js", ['goog.labs.storage.BoundedCollectableStorage'], ['goog.array', 'goog.asserts', 'goog.iter', 'goog.storage.CollectableStorage', 'goog.storage.ErrorCode', 'goog.storage.ExpiringStorage']);
                +goog.addDependency("labs/storage/boundedcollectablestorage_test.js", ['goog.labs.storage.BoundedCollectableStorageTest'], ['goog.labs.storage.BoundedCollectableStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("labs/structs/map.js", ['goog.labs.structs.Map'], ['goog.array', 'goog.asserts', 'goog.object']);
                +goog.addDependency("labs/structs/map_perf.js", ['goog.labs.structs.MapPerf'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.labs.structs.Map', 'goog.structs.Map', 'goog.testing.PerformanceTable', 'goog.testing.jsunit']);
                +goog.addDependency("labs/structs/map_test.js", ['goog.labs.structs.MapTest'], ['goog.labs.structs.Map', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/structs/multimap.js", ['goog.labs.structs.Multimap'], ['goog.array', 'goog.labs.structs.Map', 'goog.object']);
                +goog.addDependency("labs/structs/multimap_test.js", ['goog.labs.structs.MultimapTest'], ['goog.labs.structs.Map', 'goog.labs.structs.Multimap', 'goog.testing.jsunit']);
                +goog.addDependency("labs/style/pixeldensitymonitor.js", ['goog.labs.style.PixelDensityMonitor', 'goog.labs.style.PixelDensityMonitor.Density', 'goog.labs.style.PixelDensityMonitor.EventType'], ['goog.events', 'goog.events.EventTarget']);
                +goog.addDependency("labs/style/pixeldensitymonitor_test.js", ['goog.labs.style.PixelDensityMonitorTest'], ['goog.array', 'goog.dom.DomHelper', 'goog.events', 'goog.labs.style.PixelDensityMonitor', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/testing/assertthat.js", ['goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat'], ['goog.debug.Error']);
                +goog.addDependency("labs/testing/assertthat_test.js", ['goog.labs.testing.assertThatTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("labs/testing/decoratormatcher.js", ['goog.labs.testing.AnythingMatcher'], ['goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/decoratormatcher_test.js", ['goog.labs.testing.decoratorMatcherTest'], ['goog.labs.testing.AnythingMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/dictionarymatcher.js", ['goog.labs.testing.HasEntriesMatcher', 'goog.labs.testing.HasEntryMatcher', 'goog.labs.testing.HasKeyMatcher', 'goog.labs.testing.HasValueMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher', 'goog.object']);
                +goog.addDependency("labs/testing/dictionarymatcher_test.js", ['goog.labs.testing.dictionaryMatcherTest'], ['goog.labs.testing.HasEntryMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/environment.js", ['goog.labs.testing.Environment'], ['goog.Thenable', 'goog.array', 'goog.asserts', 'goog.debug.Console', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/environment_test.js", ['goog.labs.testing.environmentTest'], ['goog.Promise', 'goog.labs.testing.Environment', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.testSuite']);
                +goog.addDependency("labs/testing/environment_usage_test.js", ['goog.labs.testing.environmentUsageTest'], ['goog.labs.testing.Environment']);
                +goog.addDependency("labs/testing/json_fuzzing.js", ['goog.labs.testing.JsonFuzzing'], ['goog.string', 'goog.testing.PseudoRandom']);
                +goog.addDependency("labs/testing/json_fuzzing_test.js", ['goog.labs.testing.JsonFuzzingTest'], ['goog.json', 'goog.labs.testing.JsonFuzzing', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/logicmatcher.js", ['goog.labs.testing.AllOfMatcher', 'goog.labs.testing.AnyOfMatcher', 'goog.labs.testing.IsNotMatcher'], ['goog.array', 'goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/logicmatcher_test.js", ['goog.labs.testing.logicMatcherTest'], ['goog.labs.testing.AllOfMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/matcher.js", ['goog.labs.testing.Matcher'], []);
                +goog.addDependency("labs/testing/numbermatcher.js", ['goog.labs.testing.AnyNumberMatcher', 'goog.labs.testing.CloseToMatcher', 'goog.labs.testing.EqualToMatcher', 'goog.labs.testing.GreaterThanEqualToMatcher', 'goog.labs.testing.GreaterThanMatcher', 'goog.labs.testing.LessThanEqualToMatcher', 'goog.labs.testing.LessThanMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/numbermatcher_test.js", ['goog.labs.testing.numberMatcherTest'], ['goog.labs.testing.LessThanMatcher', 'goog.labs.testing.MatcherError', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/objectmatcher.js", ['goog.labs.testing.AnyObjectMatcher', 'goog.labs.testing.HasPropertyMatcher', 'goog.labs.testing.InstanceOfMatcher', 'goog.labs.testing.IsNullMatcher', 'goog.labs.testing.IsNullOrUndefinedMatcher', 'goog.labs.testing.IsUndefinedMatcher', 'goog.labs.testing.ObjectEqualsMatcher'], ['goog.labs.testing.Matcher']);
                +goog.addDependency("labs/testing/objectmatcher_test.js", ['goog.labs.testing.objectMatcherTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.ObjectEqualsMatcher', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/testing/stringmatcher.js", ['goog.labs.testing.AnyStringMatcher', 'goog.labs.testing.ContainsStringMatcher', 'goog.labs.testing.EndsWithMatcher', 'goog.labs.testing.EqualToIgnoringWhitespaceMatcher', 'goog.labs.testing.EqualsMatcher', 'goog.labs.testing.RegexMatcher', 'goog.labs.testing.StartsWithMatcher', 'goog.labs.testing.StringContainsInOrderMatcher'], ['goog.asserts', 'goog.labs.testing.Matcher', 'goog.string']);
                +goog.addDependency("labs/testing/stringmatcher_test.js", ['goog.labs.testing.stringMatcherTest'], ['goog.labs.testing.MatcherError', 'goog.labs.testing.StringContainsInOrderMatcher', 'goog.labs.testing.assertThat', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/browser.js", ['goog.labs.userAgent.browser'], ['goog.array', 'goog.labs.userAgent.util', 'goog.object', 'goog.string']);
                +goog.addDependency("labs/useragent/browser_test.js", ['goog.labs.userAgent.browserTest'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.object', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/device.js", ['goog.labs.userAgent.device'], ['goog.labs.userAgent.util']);
                +goog.addDependency("labs/useragent/device_test.js", ['goog.labs.userAgent.deviceTest'], ['goog.labs.userAgent.device', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/engine.js", ['goog.labs.userAgent.engine'], ['goog.array', 'goog.labs.userAgent.util', 'goog.string']);
                +goog.addDependency("labs/useragent/engine_test.js", ['goog.labs.userAgent.engineTest'], ['goog.labs.userAgent.engine', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/platform.js", ['goog.labs.userAgent.platform'], ['goog.labs.userAgent.util', 'goog.string']);
                +goog.addDependency("labs/useragent/platform_test.js", ['goog.labs.userAgent.platformTest'], ['goog.labs.userAgent.platform', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/test_agents.js", ['goog.labs.userAgent.testAgents'], []);
                +goog.addDependency("labs/useragent/util.js", ['goog.labs.userAgent.util'], ['goog.string']);
                +goog.addDependency("labs/useragent/util_test.js", ['goog.labs.userAgent.utilTest'], ['goog.functions', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("labs/useragent/verifier.js", ['goog.labs.useragent.verifier'], []);
                +goog.addDependency("labs/useragent/verifier_test.js", [], []);
                +goog.addDependency("locale/countries.js", ['goog.locale.countries'], []);
                +goog.addDependency("locale/countrylanguagenames_test.js", ['goog.locale.countryLanguageNamesTest'], ['goog.locale', 'goog.testing.jsunit']);
                +goog.addDependency("locale/defaultlocalenameconstants.js", ['goog.locale.defaultLocaleNameConstants'], []);
                +goog.addDependency("locale/genericfontnames.js", ['goog.locale.genericFontNames'], []);
                +goog.addDependency("locale/genericfontnames_test.js", ['goog.locale.genericFontNamesTest'], ['goog.locale.genericFontNames', 'goog.testing.jsunit']);
                +goog.addDependency("locale/genericfontnamesdata.js", ['goog.locale.genericFontNamesData'], []);
                +goog.addDependency("locale/locale.js", ['goog.locale'], ['goog.locale.nativeNameConstants']);
                +goog.addDependency("locale/nativenameconstants.js", ['goog.locale.nativeNameConstants'], []);
                +goog.addDependency("locale/scriptToLanguages.js", ['goog.locale.scriptToLanguages'], ['goog.locale']);
                +goog.addDependency("locale/timezonedetection.js", ['goog.locale.timeZoneDetection'], ['goog.locale.TimeZoneFingerprint']);
                +goog.addDependency("locale/timezonedetection_test.js", ['goog.locale.timeZoneDetectionTest'], ['goog.locale.timeZoneDetection', 'goog.testing.jsunit']);
                +goog.addDependency("locale/timezonefingerprint.js", ['goog.locale.TimeZoneFingerprint'], []);
                +goog.addDependency("locale/timezonelist.js", ['goog.locale.TimeZoneList'], ['goog.locale']);
                +goog.addDependency("locale/timezonelist_test.js", ['goog.locale.TimeZoneListTest'], ['goog.locale', 'goog.locale.TimeZoneList', 'goog.testing.jsunit']);
                +goog.addDependency("log/log.js", ['goog.log', 'goog.log.Level', 'goog.log.LogRecord', 'goog.log.Logger'], ['goog.debug', 'goog.debug.LogManager', 'goog.debug.LogRecord', 'goog.debug.Logger']);
                +goog.addDependency("log/log_test.js", ['goog.logTest'], ['goog.debug.LogManager', 'goog.log', 'goog.log.Level', 'goog.testing.jsunit']);
                +goog.addDependency("math/affinetransform.js", ['goog.math.AffineTransform'], []);
                +goog.addDependency("math/affinetransform_test.js", ['goog.math.AffineTransformTest'], ['goog.array', 'goog.math', 'goog.math.AffineTransform', 'goog.testing.jsunit']);
                +goog.addDependency("math/bezier.js", ['goog.math.Bezier'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/bezier_test.js", ['goog.math.BezierTest'], ['goog.math', 'goog.math.Bezier', 'goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/box.js", ['goog.math.Box'], ['goog.asserts', 'goog.math.Coordinate']);
                +goog.addDependency("math/box_test.js", ['goog.math.BoxTest'], ['goog.math.Box', 'goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/coordinate.js", ['goog.math.Coordinate'], ['goog.math']);
                +goog.addDependency("math/coordinate3.js", ['goog.math.Coordinate3'], []);
                +goog.addDependency("math/coordinate3_test.js", ['goog.math.Coordinate3Test'], ['goog.math.Coordinate3', 'goog.testing.jsunit']);
                +goog.addDependency("math/coordinate_test.js", ['goog.math.CoordinateTest'], ['goog.math.Coordinate', 'goog.testing.jsunit']);
                +goog.addDependency("math/exponentialbackoff.js", ['goog.math.ExponentialBackoff'], ['goog.asserts']);
                +goog.addDependency("math/exponentialbackoff_test.js", ['goog.math.ExponentialBackoffTest'], ['goog.math.ExponentialBackoff', 'goog.testing.jsunit']);
                +goog.addDependency("math/integer.js", ['goog.math.Integer'], []);
                +goog.addDependency("math/integer_test.js", ['goog.math.IntegerTest'], ['goog.math.Integer', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/interpolator1.js", ['goog.math.interpolator.Interpolator1'], []);
                +goog.addDependency("math/interpolator/linear1.js", ['goog.math.interpolator.Linear1'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.interpolator.Interpolator1']);
                +goog.addDependency("math/interpolator/linear1_test.js", ['goog.math.interpolator.Linear1Test'], ['goog.math.interpolator.Linear1', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/pchip1.js", ['goog.math.interpolator.Pchip1'], ['goog.math', 'goog.math.interpolator.Spline1']);
                +goog.addDependency("math/interpolator/pchip1_test.js", ['goog.math.interpolator.Pchip1Test'], ['goog.math.interpolator.Pchip1', 'goog.testing.jsunit']);
                +goog.addDependency("math/interpolator/spline1.js", ['goog.math.interpolator.Spline1'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.interpolator.Interpolator1', 'goog.math.tdma']);
                +goog.addDependency("math/interpolator/spline1_test.js", ['goog.math.interpolator.Spline1Test'], ['goog.math.interpolator.Spline1', 'goog.testing.jsunit']);
                +goog.addDependency("math/irect.js", ['goog.math.IRect'], []);
                +goog.addDependency("math/line.js", ['goog.math.Line'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/line_test.js", ['goog.math.LineTest'], ['goog.math.Coordinate', 'goog.math.Line', 'goog.testing.jsunit']);
                +goog.addDependency("math/long.js", ['goog.math.Long'], ['goog.asserts', 'goog.reflect']);
                +goog.addDependency("math/long_test.js", ['goog.math.LongTest'], ['goog.asserts', 'goog.math.Long', 'goog.testing.jsunit']);
                +goog.addDependency("math/math.js", ['goog.math'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("math/math_test.js", ['goog.mathTest'], ['goog.math', 'goog.testing.jsunit']);
                +goog.addDependency("math/matrix.js", ['goog.math.Matrix'], ['goog.array', 'goog.asserts', 'goog.math', 'goog.math.Size', 'goog.string']);
                +goog.addDependency("math/matrix_test.js", ['goog.math.MatrixTest'], ['goog.math.Matrix', 'goog.testing.jsunit']);
                +goog.addDependency("math/path.js", ['goog.math.Path', 'goog.math.Path.Segment'], ['goog.array', 'goog.math', 'goog.math.AffineTransform']);
                +goog.addDependency("math/path_test.js", ['goog.math.PathTest'], ['goog.array', 'goog.math.AffineTransform', 'goog.math.Path', 'goog.testing.jsunit']);
                +goog.addDependency("math/paths.js", ['goog.math.paths'], ['goog.math.Coordinate', 'goog.math.Path']);
                +goog.addDependency("math/paths_test.js", ['goog.math.pathsTest'], ['goog.math.Coordinate', 'goog.math.paths', 'goog.testing.jsunit']);
                +goog.addDependency("math/range.js", ['goog.math.Range'], ['goog.asserts']);
                +goog.addDependency("math/range_test.js", ['goog.math.RangeTest'], ['goog.math.Range', 'goog.testing.jsunit']);
                +goog.addDependency("math/rangeset.js", ['goog.math.RangeSet'], ['goog.array', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.math.Range']);
                +goog.addDependency("math/rangeset_test.js", ['goog.math.RangeSetTest'], ['goog.iter', 'goog.math.Range', 'goog.math.RangeSet', 'goog.testing.jsunit']);
                +goog.addDependency("math/rect.js", ['goog.math.Rect'], ['goog.asserts', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.IRect', 'goog.math.Size']);
                +goog.addDependency("math/rect_test.js", ['goog.math.RectTest'], ['goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.testing.jsunit']);
                +goog.addDependency("math/size.js", ['goog.math.Size'], []);
                +goog.addDependency("math/size_test.js", ['goog.math.SizeTest'], ['goog.math.Size', 'goog.testing.jsunit']);
                +goog.addDependency("math/tdma.js", ['goog.math.tdma'], []);
                +goog.addDependency("math/tdma_test.js", ['goog.math.tdmaTest'], ['goog.math.tdma', 'goog.testing.jsunit']);
                +goog.addDependency("math/vec2.js", ['goog.math.Vec2'], ['goog.math', 'goog.math.Coordinate']);
                +goog.addDependency("math/vec2_test.js", ['goog.math.Vec2Test'], ['goog.math.Vec2', 'goog.testing.jsunit']);
                +goog.addDependency("math/vec3.js", ['goog.math.Vec3'], ['goog.math', 'goog.math.Coordinate3']);
                +goog.addDependency("math/vec3_test.js", ['goog.math.Vec3Test'], ['goog.math.Coordinate3', 'goog.math.Vec3', 'goog.testing.jsunit']);
                +goog.addDependency("memoize/memoize.js", ['goog.memoize'], []);
                +goog.addDependency("memoize/memoize_test.js", ['goog.memoizeTest'], ['goog.memoize', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/abstractchannel.js", ['goog.messaging.AbstractChannel'], ['goog.Disposable', 'goog.json', 'goog.log', 'goog.messaging.MessageChannel']);
                +goog.addDependency("messaging/abstractchannel_test.js", ['goog.messaging.AbstractChannelTest'], ['goog.messaging.AbstractChannel', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/bufferedchannel.js", ['goog.messaging.BufferedChannel'], ['goog.Disposable', 'goog.Timer', 'goog.events', 'goog.log', 'goog.messaging.MessageChannel', 'goog.messaging.MultiChannel']);
                +goog.addDependency("messaging/bufferedchannel_test.js", ['goog.messaging.BufferedChannelTest'], ['goog.debug.Console', 'goog.dom', 'goog.dom.TagName', 'goog.log', 'goog.log.Level', 'goog.messaging.BufferedChannel', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/deferredchannel.js", ['goog.messaging.DeferredChannel'], ['goog.Disposable', 'goog.messaging.MessageChannel']);
                +goog.addDependency("messaging/deferredchannel_test.js", ['goog.messaging.DeferredChannelTest'], ['goog.async.Deferred', 'goog.messaging.DeferredChannel', 'goog.testing.MockControl', 'goog.testing.async.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/loggerclient.js", ['goog.messaging.LoggerClient'], ['goog.Disposable', 'goog.debug', 'goog.debug.LogManager', 'goog.debug.Logger']);
                +goog.addDependency("messaging/loggerclient_test.js", ['goog.messaging.LoggerClientTest'], ['goog.debug', 'goog.debug.Logger', 'goog.messaging.LoggerClient', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/loggerserver.js", ['goog.messaging.LoggerServer'], ['goog.Disposable', 'goog.log', 'goog.log.Level']);
                +goog.addDependency("messaging/loggerserver_test.js", ['goog.messaging.LoggerServerTest'], ['goog.debug.LogManager', 'goog.debug.Logger', 'goog.log', 'goog.log.Level', 'goog.messaging.LoggerServer', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/messagechannel.js", ['goog.messaging.MessageChannel'], []);
                +goog.addDependency("messaging/messaging.js", ['goog.messaging'], []);
                +goog.addDependency("messaging/messaging_test.js", ['goog.testing.messaging.MockMessageChannelTest'], ['goog.messaging', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/multichannel.js", ['goog.messaging.MultiChannel', 'goog.messaging.MultiChannel.VirtualChannel'], ['goog.Disposable', 'goog.log', 'goog.messaging.MessageChannel', 'goog.object']);
                +goog.addDependency("messaging/multichannel_test.js", ['goog.messaging.MultiChannelTest'], ['goog.messaging.MultiChannel', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel', 'goog.testing.mockmatchers.IgnoreArgument']);
                +goog.addDependency("messaging/portcaller.js", ['goog.messaging.PortCaller'], ['goog.Disposable', 'goog.async.Deferred', 'goog.messaging.DeferredChannel', 'goog.messaging.PortChannel', 'goog.messaging.PortNetwork', 'goog.object']);
                +goog.addDependency("messaging/portcaller_test.js", ['goog.messaging.PortCallerTest'], ['goog.events.EventTarget', 'goog.messaging.PortCaller', 'goog.messaging.PortNetwork', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/portchannel.js", ['goog.messaging.PortChannel'], ['goog.Timer', 'goog.array', 'goog.async.Deferred', 'goog.debug', 'goog.events', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.messaging.AbstractChannel', 'goog.messaging.DeferredChannel', 'goog.object', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("messaging/portchannel_test.js", ['goog.messaging.PortChannelTest'], ['goog.Promise', 'goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.json', 'goog.messaging.PortChannel', 'goog.testing.MockControl', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageEvent']);
                +goog.addDependency("messaging/portnetwork.js", ['goog.messaging.PortNetwork'], []);
                +goog.addDependency("messaging/portnetwork_test.js", ['goog.messaging.PortNetworkTest'], ['goog.Promise', 'goog.Timer', 'goog.labs.userAgent.browser', 'goog.messaging.PortChannel', 'goog.messaging.PortOperator', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("messaging/portoperator.js", ['goog.messaging.PortOperator'], ['goog.Disposable', 'goog.asserts', 'goog.log', 'goog.messaging.PortChannel', 'goog.messaging.PortNetwork', 'goog.object']);
                +goog.addDependency("messaging/portoperator_test.js", ['goog.messaging.PortOperatorTest'], ['goog.messaging.PortNetwork', 'goog.messaging.PortOperator', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel', 'goog.testing.messaging.MockMessagePort']);
                +goog.addDependency("messaging/respondingchannel.js", ['goog.messaging.RespondingChannel'], ['goog.Disposable', 'goog.log', 'goog.messaging.MultiChannel']);
                +goog.addDependency("messaging/respondingchannel_test.js", ['goog.messaging.RespondingChannelTest'], ['goog.messaging.RespondingChannel', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("messaging/testdata/portchannel_worker.js", ['goog.messaging.testdata.portchannel_worker'], ['goog.messaging.PortChannel']);
                +goog.addDependency("messaging/testdata/portnetwork_worker1.js", ['goog.messaging.testdata.portnetwork_worker1'], ['goog.messaging.PortCaller', 'goog.messaging.PortChannel']);
                +goog.addDependency("messaging/testdata/portnetwork_worker2.js", ['goog.messaging.testdata.portnetwork_worker2'], ['goog.messaging.PortCaller', 'goog.messaging.PortChannel']);
                +goog.addDependency("module/abstractmoduleloader.js", ['goog.module.AbstractModuleLoader'], ['goog.module', 'goog.module.ModuleInfo']);
                +goog.addDependency("module/basemodule.js", ['goog.module.BaseModule'], ['goog.Disposable', 'goog.module']);
                +goog.addDependency("module/loader.js", ['goog.module.Loader'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.module', 'goog.object']);
                +goog.addDependency("module/module.js", ['goog.module'], []);
                +goog.addDependency("module/moduleinfo.js", ['goog.module.ModuleInfo'], ['goog.Disposable', 'goog.async.throwException', 'goog.functions', 'goog.module', 'goog.module.BaseModule', 'goog.module.ModuleLoadCallback']);
                +goog.addDependency("module/moduleinfo_test.js", ['goog.module.ModuleInfoTest'], ['goog.module.BaseModule', 'goog.module.ModuleInfo', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("module/moduleloadcallback.js", ['goog.module.ModuleLoadCallback'], ['goog.debug.entryPointRegistry', 'goog.module']);
                +goog.addDependency("module/moduleloadcallback_test.js", ['goog.module.ModuleLoadCallbackTest'], ['goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.functions', 'goog.module.ModuleLoadCallback', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("module/moduleloader.js", ['goog.module.ModuleLoader'], ['goog.Timer', 'goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventId', 'goog.events.EventTarget', 'goog.labs.userAgent.browser', 'goog.log', 'goog.module.AbstractModuleLoader', 'goog.net.BulkLoader', 'goog.net.EventType', 'goog.net.jsloader', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("module/moduleloader_test.js", ['goog.module.ModuleLoaderTest'], ['goog.Promise', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.functions', 'goog.module.ModuleLoader', 'goog.module.ModuleManager', 'goog.net.BulkLoader', 'goog.net.XmlHttp', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.events.EventObserver', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("module/modulemanager.js", ['goog.module.ModuleManager', 'goog.module.ModuleManager.CallbackType', 'goog.module.ModuleManager.FailureType'], ['goog.Disposable', 'goog.array', 'goog.asserts', 'goog.async.Deferred', 'goog.debug.Trace', 'goog.dispose', 'goog.log', 'goog.module', 'goog.module.AbstractModuleLoader', 'goog.module.ModuleInfo', 'goog.module.ModuleLoadCallback', 'goog.object']);
                +goog.addDependency("module/modulemanager_test.js", ['goog.module.ModuleManagerTest'], ['goog.array', 'goog.functions', 'goog.module.BaseModule', 'goog.module.ModuleManager', 'goog.testing', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("module/testdata/modA_1.js", ['goog.module.testdata.modA_1'], []);
                +goog.addDependency("module/testdata/modA_2.js", ['goog.module.testdata.modA_2'], ['goog.module.ModuleManager']);
                +goog.addDependency("module/testdata/modB_1.js", ['goog.module.testdata.modB_1'], ['goog.module.ModuleManager']);
                +goog.addDependency("net/browserchannel.js", ['goog.net.BrowserChannel', 'goog.net.BrowserChannel.Error', 'goog.net.BrowserChannel.Event', 'goog.net.BrowserChannel.Handler', 'goog.net.BrowserChannel.LogSaver', 'goog.net.BrowserChannel.QueuedMap', 'goog.net.BrowserChannel.ServerReachability', 'goog.net.BrowserChannel.ServerReachabilityEvent', 'goog.net.BrowserChannel.Stat', 'goog.net.BrowserChannel.StatEvent', 'goog.net.BrowserChannel.State', 'goog.net.BrowserChannel.TimingEvent'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.TextFormatter', 'goog.events.Event', 'goog.events.EventTarget', 'goog.json', 'goog.json.EvalJsonProcessor', 'goog.log', 'goog.net.BrowserTestChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.net.XhrIo', 'goog.net.tmpnetwork', 'goog.object', 'goog.string', 'goog.structs', 'goog.structs.CircularBuffer']);
                +goog.addDependency("net/browserchannel_test.js", ['goog.net.BrowserChannelTest'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.functions', 'goog.json', 'goog.net.BrowserChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.net.tmpnetwork', 'goog.structs.Map', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/browsertestchannel.js", ['goog.net.BrowserTestChannel'], ['goog.json.EvalJsonProcessor', 'goog.net.ChannelRequest', 'goog.net.ChannelRequest.Error', 'goog.net.tmpnetwork', 'goog.string.Parser']);
                +goog.addDependency("net/bulkloader.js", ['goog.net.BulkLoader'], ['goog.events.EventHandler', 'goog.events.EventTarget', 'goog.log', 'goog.net.BulkLoaderHelper', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("net/bulkloader_test.js", ['goog.net.BulkLoaderTest'], ['goog.events.Event', 'goog.events.EventHandler', 'goog.net.BulkLoader', 'goog.net.EventType', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("net/bulkloaderhelper.js", ['goog.net.BulkLoaderHelper'], ['goog.Disposable']);
                +goog.addDependency("net/channeldebug.js", ['goog.net.ChannelDebug'], ['goog.json', 'goog.log']);
                +goog.addDependency("net/channelrequest.js", ['goog.net.ChannelRequest', 'goog.net.ChannelRequest.Error'], ['goog.Timer', 'goog.async.Throttle', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events.EventHandler', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("net/channelrequest_test.js", ['goog.net.ChannelRequestTest'], ['goog.Uri', 'goog.functions', 'goog.net.BrowserChannel', 'goog.net.ChannelDebug', 'goog.net.ChannelRequest', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction']);
                +goog.addDependency("net/cookies.js", ['goog.net.Cookies', 'goog.net.cookies'], ['goog.string']);
                +goog.addDependency("net/cookies_test.js", ['goog.net.cookiesTest'], ['goog.array', 'goog.net.cookies', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("net/corsxmlhttpfactory.js", ['goog.net.CorsXmlHttpFactory', 'goog.net.IeCorsXhrAdapter'], ['goog.net.HttpStatus', 'goog.net.XhrLike', 'goog.net.XmlHttp', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/corsxmlhttpfactory_test.js", ['goog.net.CorsXmlHttpFactoryTest'], ['goog.net.CorsXmlHttpFactory', 'goog.net.IeCorsXhrAdapter', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("net/crossdomainrpc.js", ['goog.net.CrossDomainRpc'], ['goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.json', 'goog.log', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("net/crossdomainrpc_test.js", ['goog.net.CrossDomainRpcTest'], ['goog.Promise', 'goog.log', 'goog.net.CrossDomainRpc', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("net/errorcode.js", ['goog.net.ErrorCode'], []);
                +goog.addDependency("net/eventtype.js", ['goog.net.EventType'], []);
                +goog.addDependency("net/fetchxmlhttpfactory.js", ['goog.net.FetchXmlHttp', 'goog.net.FetchXmlHttpFactory'], ['goog.asserts', 'goog.events.EventTarget', 'goog.functions', 'goog.log', 'goog.net.XhrLike', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/fetchxmlhttpfactory_test.js", ['goog.net.FetchXmlHttpFactoryTest'], ['goog.net.FetchXmlHttp', 'goog.net.FetchXmlHttpFactory', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("net/filedownloader.js", ['goog.net.FileDownloader', 'goog.net.FileDownloader.Error'], ['goog.Disposable', 'goog.asserts', 'goog.async.Deferred', 'goog.crypt.hash32', 'goog.debug.Error', 'goog.events', 'goog.events.EventHandler', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrIoPool', 'goog.object']);
                +goog.addDependency("net/filedownloader_test.js", ['goog.net.FileDownloaderTest'], ['goog.fs.Error', 'goog.net.ErrorCode', 'goog.net.FileDownloader', 'goog.net.XhrIo', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.fs', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit', 'goog.testing.net.XhrIoPool']);
                +goog.addDependency("net/httpstatus.js", ['goog.net.HttpStatus'], []);
                +goog.addDependency("net/httpstatusname.js", ['goog.net.HttpStatusName'], []);
                +goog.addDependency("net/iframeio.js", ['goog.net.IframeIo', 'goog.net.IframeIo.IncrementalDataEvent'], ['goog.Timer', 'goog.Uri', 'goog.array', 'goog.asserts', 'goog.debug.HtmlFormatter', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.html.uncheckedconversions', 'goog.json', 'goog.log', 'goog.log.Level', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.reflect', 'goog.string', 'goog.string.Const', 'goog.structs', 'goog.userAgent']);
                +goog.addDependency("net/iframeio_different_base_test.js", ['goog.net.iframeIoDifferentBaseTest'], ['goog.Promise', 'goog.events', 'goog.net.EventType', 'goog.net.IframeIo', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/iframeio_test.js", ['goog.net.IframeIoTest'], ['goog.debug', 'goog.debug.DivConsole', 'goog.debug.LogManager', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.log', 'goog.log.Level', 'goog.net.IframeIo', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("net/iframeloadmonitor.js", ['goog.net.IframeLoadMonitor'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.userAgent']);
                +goog.addDependency("net/iframeloadmonitor_test.js", [], []);
                +goog.addDependency("net/imageloader.js", ['goog.net.ImageLoader'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.net.EventType', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("net/imageloader_test.js", ['goog.net.ImageLoaderTest'], ['goog.Promise', 'goog.Timer', 'goog.array', 'goog.dispose', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.net.EventType', 'goog.net.ImageLoader', 'goog.object', 'goog.string', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/ipaddress.js", ['goog.net.IpAddress', 'goog.net.Ipv4Address', 'goog.net.Ipv6Address'], ['goog.array', 'goog.math.Integer', 'goog.object', 'goog.string']);
                +goog.addDependency("net/ipaddress_test.js", ['goog.net.IpAddressTest'], ['goog.array', 'goog.math.Integer', 'goog.net.IpAddress', 'goog.net.Ipv4Address', 'goog.net.Ipv6Address', 'goog.testing.jsunit']);
                +goog.addDependency("net/jsloader.js", ['goog.net.jsloader', 'goog.net.jsloader.Error', 'goog.net.jsloader.ErrorCode', 'goog.net.jsloader.Options'], ['goog.array', 'goog.async.Deferred', 'goog.debug.Error', 'goog.dom', 'goog.dom.TagName', 'goog.html.TrustedResourceUrl', 'goog.html.legacyconversions', 'goog.object']);
                +goog.addDependency("net/jsloader_test.js", ['goog.net.jsloaderTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.TrustedResourceUrl', 'goog.net.jsloader', 'goog.net.jsloader.ErrorCode', 'goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("net/jsonp.js", ['goog.net.Jsonp'], ['goog.Uri', 'goog.net.jsloader']);
                +goog.addDependency("net/jsonp_test.js", ['goog.net.JsonpTest'], ['goog.net.Jsonp', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("net/mockiframeio.js", ['goog.net.MockIFrameIo'], ['goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.IframeIo']);
                +goog.addDependency("net/multiiframeloadmonitor.js", ['goog.net.MultiIframeLoadMonitor'], ['goog.events', 'goog.net.IframeLoadMonitor']);
                +goog.addDependency("net/multiiframeloadmonitor_test.js", [], []);
                +goog.addDependency("net/networkstatusmonitor.js", ['goog.net.NetworkStatusMonitor'], ['goog.events.Listenable']);
                +goog.addDependency("net/networktester.js", ['goog.net.NetworkTester'], ['goog.Timer', 'goog.Uri', 'goog.log']);
                +goog.addDependency("net/networktester_test.js", ['goog.net.NetworkTesterTest'], ['goog.Uri', 'goog.net.NetworkTester', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("net/rpc/httpcors.js", [], []);
                +goog.addDependency("net/rpc/httpcors_test.js", [], []);
                +goog.addDependency("net/streams/base64pbstreamparser.js", [], []);
                +goog.addDependency("net/streams/base64pbstreamparser_test.js", [], []);
                +goog.addDependency("net/streams/base64streamdecoder.js", ['goog.net.streams.Base64StreamDecoder'], ['goog.asserts', 'goog.crypt.base64']);
                +goog.addDependency("net/streams/base64streamdecoder_test.js", ['goog.net.streams.Base64StreamDecoderTest'], ['goog.net.streams.Base64StreamDecoder', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/jsonstreamparser.js", ['goog.net.streams.JsonStreamParser', 'goog.net.streams.JsonStreamParser.Options'], ['goog.asserts', 'goog.json', 'goog.net.streams.StreamParser', 'goog.net.streams.utils']);
                +goog.addDependency("net/streams/jsonstreamparser_test.js", ['goog.net.streams.JsonStreamParserTest'], ['goog.array', 'goog.json', 'goog.labs.testing.JsonFuzzing', 'goog.net.streams.JsonStreamParser', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.uri.utils']);
                +goog.addDependency("net/streams/nodereadablestream.js", ['goog.net.streams.NodeReadableStream'], []);
                +goog.addDependency("net/streams/pbjsonstreamparser.js", [], []);
                +goog.addDependency("net/streams/pbjsonstreamparser_test.js", [], []);
                +goog.addDependency("net/streams/pbstreamparser.js", ['goog.net.streams.PbStreamParser'], ['goog.asserts', 'goog.net.streams.StreamParser']);
                +goog.addDependency("net/streams/pbstreamparser_test.js", ['goog.net.streams.PbStreamParserTest'], ['goog.net.streams.PbStreamParser', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/streamfactory.js", ['goog.net.streams.createXhrNodeReadableStream'], ['goog.asserts', 'goog.net.streams.XhrNodeReadableStream', 'goog.net.streams.XhrStreamReader']);
                +goog.addDependency("net/streams/streamparser.js", ['goog.net.streams.StreamParser'], []);
                +goog.addDependency("net/streams/utils.js", [], []);
                +goog.addDependency("net/streams/xhrnodereadablestream.js", ['goog.net.streams.XhrNodeReadableStream'], ['goog.array', 'goog.log', 'goog.net.streams.NodeReadableStream', 'goog.net.streams.XhrStreamReader']);
                +goog.addDependency("net/streams/xhrnodereadablestream_test.js", ['goog.net.streams.XhrNodeReadableStreamTest'], ['goog.net.streams.NodeReadableStream', 'goog.net.streams.XhrNodeReadableStream', 'goog.net.streams.XhrStreamReader', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("net/streams/xhrstreamreader.js", ['goog.net.streams.XhrStreamReader'], ['goog.events.EventHandler', 'goog.log', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.net.streams.Base64PbStreamParser', 'goog.net.streams.JsonStreamParser', 'goog.net.streams.PbJsonStreamParser', 'goog.net.streams.PbStreamParser', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("net/streams/xhrstreamreader_test.js", ['goog.net.streams.XhrStreamReaderTest'], ['goog.net.ErrorCode', 'goog.net.XmlHttp', 'goog.net.streams.Base64PbStreamParser', 'goog.net.streams.JsonStreamParser', 'goog.net.streams.PbJsonStreamParser', 'goog.net.streams.PbStreamParser', 'goog.net.streams.XhrStreamReader', 'goog.object', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.net.XhrIo']);
                +goog.addDependency("net/testdata/jsloader_test1.js", ['goog.net.testdata.jsloader_test1'], []);
                +goog.addDependency("net/testdata/jsloader_test2.js", ['goog.net.testdata.jsloader_test2'], []);
                +goog.addDependency("net/testdata/jsloader_test3.js", ['goog.net.testdata.jsloader_test3'], []);
                +goog.addDependency("net/testdata/jsloader_test4.js", ['goog.net.testdata.jsloader_test4'], []);
                +goog.addDependency("net/tmpnetwork.js", ['goog.net.tmpnetwork'], ['goog.Uri', 'goog.net.ChannelDebug']);
                +goog.addDependency("net/websocket.js", ['goog.net.WebSocket', 'goog.net.WebSocket.ErrorEvent', 'goog.net.WebSocket.EventType', 'goog.net.WebSocket.MessageEvent'], ['goog.Timer', 'goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.log']);
                +goog.addDependency("net/websocket_test.js", ['goog.net.WebSocketTest'], ['goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.functions', 'goog.net.WebSocket', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/wrapperxmlhttpfactory.js", ['goog.net.WrapperXmlHttpFactory'], ['goog.net.XhrLike', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/xhrio.js", ['goog.net.XhrIo', 'goog.net.XhrIo.ResponseType'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.debug.entryPointRegistry', 'goog.events.EventTarget', 'goog.json', 'goog.log', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XmlHttp', 'goog.string', 'goog.structs', 'goog.structs.Map', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("net/xhrio_test.js", ['goog.net.XhrIoTest'], ['goog.Uri', 'goog.debug.EntryPointMonitor', 'goog.debug.ErrorHandler', 'goog.debug.entryPointRegistry', 'goog.events', 'goog.functions', 'goog.net.EventType', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.object', 'goog.string', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.testing.recordFunction', 'goog.userAgent.product']);
                +goog.addDependency("net/xhriopool.js", ['goog.net.XhrIoPool'], ['goog.net.XhrIo', 'goog.structs.PriorityPool']);
                +goog.addDependency("net/xhriopool_test.js", ['goog.net.XhrIoPoolTest'], ['goog.net.XhrIoPool', 'goog.structs.Map', 'goog.testing.jsunit']);
                +goog.addDependency("net/xhrlike.js", ['goog.net.XhrLike'], []);
                +goog.addDependency("net/xhrmanager.js", ['goog.net.XhrManager', 'goog.net.XhrManager.Event', 'goog.net.XhrManager.Request'], ['goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrIoPool', 'goog.structs.Map']);
                +goog.addDependency("net/xhrmanager_test.js", ['goog.net.XhrManagerTest'], ['goog.events', 'goog.net.EventType', 'goog.net.XhrIo', 'goog.net.XhrManager', 'goog.testing.jsunit', 'goog.testing.net.XhrIoPool', 'goog.testing.recordFunction']);
                +goog.addDependency("net/xmlhttp.js", ['goog.net.DefaultXmlHttpFactory', 'goog.net.XmlHttp', 'goog.net.XmlHttp.OptionType', 'goog.net.XmlHttp.ReadyState', 'goog.net.XmlHttpDefines'], ['goog.asserts', 'goog.net.WrapperXmlHttpFactory', 'goog.net.XmlHttpFactory']);
                +goog.addDependency("net/xmlhttpfactory.js", ['goog.net.XmlHttpFactory'], ['goog.net.XhrLike']);
                +goog.addDependency("net/xpc/crosspagechannel.js", ['goog.net.xpc.CrossPageChannel'], ['goog.Uri', 'goog.async.Deferred', 'goog.async.Delay', 'goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.json', 'goog.log', 'goog.messaging.AbstractChannel', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.ChannelStates', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.DirectTransport', 'goog.net.xpc.FrameElementMethodTransport', 'goog.net.xpc.IframePollingTransport', 'goog.net.xpc.IframeRelayTransport', 'goog.net.xpc.NativeMessagingTransport', 'goog.net.xpc.NixTransport', 'goog.net.xpc.TransportTypes', 'goog.net.xpc.UriCfgFields', 'goog.string', 'goog.uri.utils', 'goog.userAgent']);
                +goog.addDependency("net/xpc/crosspagechannel_test.js", ['goog.net.xpc.CrossPageChannelTest'], ['goog.Disposable', 'goog.Promise', 'goog.Timer', 'goog.Uri', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.object', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/crosspagechannelrole.js", ['goog.net.xpc.CrossPageChannelRole'], []);
                +goog.addDependency("net/xpc/directtransport.js", ['goog.net.xpc.DirectTransport'], ['goog.Timer', 'goog.async.Deferred', 'goog.events.EventHandler', 'goog.log', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.object']);
                +goog.addDependency("net/xpc/directtransport_test.js", ['goog.net.xpc.DirectTransportTest'], ['goog.Promise', 'goog.dom', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/frameelementmethodtransport.js", ['goog.net.xpc.FrameElementMethodTransport'], ['goog.log', 'goog.net.xpc', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes']);
                +goog.addDependency("net/xpc/iframepollingtransport.js", ['goog.net.xpc.IframePollingTransport', 'goog.net.xpc.IframePollingTransport.Receiver', 'goog.net.xpc.IframePollingTransport.Sender'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.userAgent']);
                +goog.addDependency("net/xpc/iframepollingtransport_test.js", ['goog.net.xpc.IframePollingTransportTest'], ['goog.Timer', 'goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.TransportTypes', 'goog.object', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("net/xpc/iframerelaytransport.js", ['goog.net.xpc.IframeRelayTransport'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.html.SafeHtml', 'goog.log', 'goog.log.Level', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("net/xpc/nativemessagingtransport.js", ['goog.net.xpc.NativeMessagingTransport'], ['goog.Timer', 'goog.asserts', 'goog.async.Deferred', 'goog.events', 'goog.events.EventHandler', 'goog.log', 'goog.net.xpc', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes']);
                +goog.addDependency("net/xpc/nativemessagingtransport_test.js", ['goog.net.xpc.NativeMessagingTransportTest'], ['goog.dom', 'goog.events', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannel', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.NativeMessagingTransport', 'goog.testing.jsunit']);
                +goog.addDependency("net/xpc/nixtransport.js", ['goog.net.xpc.NixTransport'], ['goog.log', 'goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.CrossPageChannelRole', 'goog.net.xpc.Transport', 'goog.net.xpc.TransportTypes', 'goog.reflect']);
                +goog.addDependency("net/xpc/relay.js", ['goog.net.xpc.relay'], []);
                +goog.addDependency("net/xpc/transport.js", ['goog.net.xpc.Transport'], ['goog.Disposable', 'goog.dom', 'goog.net.xpc.TransportNames']);
                +goog.addDependency("net/xpc/xpc.js", ['goog.net.xpc', 'goog.net.xpc.CfgFields', 'goog.net.xpc.ChannelStates', 'goog.net.xpc.TransportNames', 'goog.net.xpc.TransportTypes', 'goog.net.xpc.UriCfgFields'], ['goog.log']);
                +goog.addDependency("object/object.js", ['goog.object'], []);
                +goog.addDependency("object/object_test.js", ['goog.objectTest'], ['goog.array', 'goog.functions', 'goog.object', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("positioning/absoluteposition.js", ['goog.positioning.AbsolutePosition'], ['goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition']);
                +goog.addDependency("positioning/abstractposition.js", ['goog.positioning.AbstractPosition'], []);
                +goog.addDependency("positioning/anchoredposition.js", ['goog.positioning.AnchoredPosition'], ['goog.positioning', 'goog.positioning.AbstractPosition']);
                +goog.addDependency("positioning/anchoredposition_test.js", ['goog.positioning.AnchoredPositionTest'], ['goog.dom', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/anchoredviewportposition.js", ['goog.positioning.AnchoredViewportPosition'], ['goog.positioning', 'goog.positioning.AnchoredPosition', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus']);
                +goog.addDependency("positioning/anchoredviewportposition_test.js", ['goog.positioning.AnchoredViewportPositionTest'], ['goog.dom', 'goog.math.Box', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.positioning.OverflowStatus', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/clientposition.js", ['goog.positioning.ClientPosition'], ['goog.asserts', 'goog.dom', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition', 'goog.style']);
                +goog.addDependency("positioning/clientposition_test.js", ['goog.positioning.clientPositionTest'], ['goog.dom', 'goog.dom.TagName', 'goog.positioning.ClientPosition', 'goog.positioning.Corner', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/menuanchoredposition.js", ['goog.positioning.MenuAnchoredPosition'], ['goog.positioning.AnchoredViewportPosition', 'goog.positioning.Overflow']);
                +goog.addDependency("positioning/menuanchoredposition_test.js", ['goog.positioning.MenuAnchoredPositionTest'], ['goog.dom', 'goog.dom.TagName', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.testing.jsunit']);
                +goog.addDependency("positioning/positioning.js", ['goog.positioning', 'goog.positioning.Corner', 'goog.positioning.CornerBit', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.style', 'goog.style.bidi']);
                +goog.addDependency("positioning/positioning_test.js", ['goog.positioningTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.labs.userAgent.browser', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Size', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("positioning/viewportclientposition.js", ['goog.positioning.ViewportClientPosition'], ['goog.dom', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.ClientPosition', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.style']);
                +goog.addDependency("positioning/viewportclientposition_test.js", ['goog.positioning.ViewportClientPositionTest'], ['goog.dom', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.ViewportClientPosition', 'goog.style', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("positioning/viewportposition.js", ['goog.positioning.ViewportPosition'], ['goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AbstractPosition', 'goog.positioning.Corner', 'goog.style']);
                +goog.addDependency("promise/promise.js", ['goog.Promise'], ['goog.Thenable', 'goog.asserts', 'goog.async.FreeList', 'goog.async.run', 'goog.async.throwException', 'goog.debug.Error', 'goog.promise.Resolver']);
                +goog.addDependency("promise/promise_test.js", ['goog.PromiseTest'], ['goog.Promise', 'goog.Thenable', 'goog.Timer', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("promise/resolver.js", ['goog.promise.Resolver'], []);
                +goog.addDependency("promise/testsuiteadapter.js", ['goog.promise.testSuiteAdapter'], ['goog.Promise']);
                +goog.addDependency("promise/thenable.js", ['goog.Thenable'], []);
                +goog.addDependency("proto/proto.js", ['goog.proto'], ['goog.proto.Serializer']);
                +goog.addDependency("proto/serializer.js", ['goog.proto.Serializer'], ['goog.json.Serializer', 'goog.string']);
                +goog.addDependency("proto/serializer_test.js", ['goog.protoTest'], ['goog.proto', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/descriptor.js", ['goog.proto2.Descriptor', 'goog.proto2.Metadata'], ['goog.array', 'goog.asserts', 'goog.object', 'goog.string']);
                +goog.addDependency("proto2/descriptor_test.js", ['goog.proto2.DescriptorTest'], ['goog.proto2.Descriptor', 'goog.proto2.Message', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/fielddescriptor.js", ['goog.proto2.FieldDescriptor'], ['goog.asserts', 'goog.string']);
                +goog.addDependency("proto2/fielddescriptor_test.js", ['goog.proto2.FieldDescriptorTest'], ['goog.proto2.FieldDescriptor', 'goog.proto2.Message', 'goog.testing.jsunit']);
                +goog.addDependency("proto2/lazydeserializer.js", ['goog.proto2.LazyDeserializer'], ['goog.asserts', 'goog.proto2.Message', 'goog.proto2.Serializer']);
                +goog.addDependency("proto2/message.js", ['goog.proto2.Message'], ['goog.asserts', 'goog.proto2.Descriptor', 'goog.proto2.FieldDescriptor']);
                +goog.addDependency("proto2/message_test.js", ['goog.proto2.MessageTest'], ['goog.testing.TestCase', 'goog.testing.jsunit', 'proto2.TestAllTypes', 'proto2.TestAllTypes.NestedEnum', 'proto2.TestAllTypes.NestedMessage', 'proto2.TestAllTypes.OptionalGroup', 'proto2.TestAllTypes.RepeatedGroup']);
                +goog.addDependency("proto2/objectserializer.js", ['goog.proto2.ObjectSerializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.Serializer', 'goog.string']);
                +goog.addDependency("proto2/objectserializer_test.js", ['goog.proto2.ObjectSerializerTest'], ['goog.proto2.ObjectSerializer', 'goog.proto2.Serializer', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/package_test.pb.js", ['someprotopackage.TestPackageTypes'], ['goog.proto2.Message', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/pbliteserializer.js", ['goog.proto2.PbLiteSerializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.LazyDeserializer', 'goog.proto2.Serializer']);
                +goog.addDependency("proto2/pbliteserializer_test.js", ['goog.proto2.PbLiteSerializerTest'], ['goog.proto2.PbLiteSerializer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/proto_test.js", ['goog.proto2.messageTest'], ['goog.proto2.FieldDescriptor', 'goog.testing.jsunit', 'proto2.TestAllTypes', 'proto2.TestDefaultParent', 'someprotopackage.TestPackageTypes']);
                +goog.addDependency("proto2/serializer.js", ['goog.proto2.Serializer'], ['goog.asserts', 'goog.proto2.FieldDescriptor', 'goog.proto2.Message']);
                +goog.addDependency("proto2/test.pb.js", ['proto2.TestAllTypes', 'proto2.TestAllTypes.NestedEnum', 'proto2.TestAllTypes.NestedMessage', 'proto2.TestAllTypes.OptionalGroup', 'proto2.TestAllTypes.RepeatedGroup', 'proto2.TestDefaultChild', 'proto2.TestDefaultParent'], ['goog.proto2.Message']);
                +goog.addDependency("proto2/textformatserializer.js", ['goog.proto2.TextFormatSerializer'], ['goog.array', 'goog.asserts', 'goog.json', 'goog.math', 'goog.object', 'goog.proto2.FieldDescriptor', 'goog.proto2.Message', 'goog.proto2.Serializer', 'goog.string']);
                +goog.addDependency("proto2/textformatserializer_test.js", ['goog.proto2.TextFormatSerializerTest'], ['goog.proto2.ObjectSerializer', 'goog.proto2.TextFormatSerializer', 'goog.testing.jsunit', 'proto2.TestAllTypes']);
                +goog.addDependency("proto2/util.js", ['goog.proto2.Util'], ['goog.asserts']);
                +goog.addDependency("pubsub/pubsub.js", ['goog.pubsub.PubSub'], ['goog.Disposable', 'goog.array', 'goog.async.run']);
                +goog.addDependency("pubsub/pubsub_test.js", ['goog.pubsub.PubSubTest'], ['goog.array', 'goog.pubsub.PubSub', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("pubsub/topicid.js", ['goog.pubsub.TopicId'], []);
                +goog.addDependency("pubsub/typedpubsub.js", ['goog.pubsub.TypedPubSub'], ['goog.Disposable', 'goog.pubsub.PubSub']);
                +goog.addDependency("pubsub/typedpubsub_test.js", ['goog.pubsub.TypedPubSubTest'], ['goog.array', 'goog.pubsub.TopicId', 'goog.pubsub.TypedPubSub', 'goog.testing.jsunit']);
                +goog.addDependency("reflect/reflect.js", ['goog.reflect'], []);
                +goog.addDependency("reflect/reflect_test.js", ['goog.reflectTest'], ['goog.object', 'goog.reflect', 'goog.testing.jsunit']);
                +goog.addDependency("result/chain_test.js", ['goog.result.chainTest'], ['goog.Timer', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/combine_test.js", ['goog.result.combineTest'], ['goog.Timer', 'goog.array', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/deferredadaptor.js", ['goog.result.DeferredAdaptor'], ['goog.async.Deferred', 'goog.result', 'goog.result.Result']);
                +goog.addDependency("result/deferredadaptor_test.js", ['goog.result.DeferredAdaptorTest'], ['goog.result', 'goog.result.DeferredAdaptor', 'goog.result.SimpleResult', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/dependentresult.js", ['goog.result.DependentResult'], ['goog.result.Result']);
                +goog.addDependency("result/result_interface.js", ['goog.result.Result'], ['goog.Thenable']);
                +goog.addDependency("result/resultutil.js", ['goog.result'], ['goog.array', 'goog.result.DependentResult', 'goog.result.Result', 'goog.result.SimpleResult']);
                +goog.addDependency("result/resultutil_test.js", ['goog.resultTest'], ['goog.result', 'goog.testing.jsunit']);
                +goog.addDependency("result/simpleresult.js", ['goog.result.SimpleResult', 'goog.result.SimpleResult.StateError'], ['goog.Promise', 'goog.Thenable', 'goog.debug.Error', 'goog.result.Result']);
                +goog.addDependency("result/simpleresult_test.js", ['goog.result.SimpleResultTest'], ['goog.Timer', 'goog.Promise', 'goog.Thenable', 'goog.result', 'goog.testing.MockClock', 'goog.testing.recordFunction', 'goog.testing.jsunit']);
                +goog.addDependency("result/transform_test.js", ['goog.result.transformTest'], ['goog.Timer', 'goog.result.SimpleResult', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("result/wait_test.js", ['goog.result.waitTest'], ['goog.Timer', 'goog.result.SimpleResult', 'goog.result', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("soy/data.js", ['goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.soy.data.SanitizedCss', 'goog.soy.data.SanitizedHtml', 'goog.soy.data.SanitizedHtmlAttribute', 'goog.soy.data.SanitizedJs', 'goog.soy.data.SanitizedTrustedResourceUri', 'goog.soy.data.SanitizedUri', 'goog.soy.data.UnsanitizedText'], ['goog.Uri', 'goog.html.SafeHtml', 'goog.html.SafeScript', 'goog.html.SafeStyle', 'goog.html.SafeUrl', 'goog.html.TrustedResourceUrl', 'goog.html.uncheckedconversions', 'goog.i18n.bidi.Dir', 'goog.string.Const']);
                +goog.addDependency("soy/data_test.js", ['goog.soy.dataTest'], ['goog.html.SafeHtml', 'goog.html.SafeUrl', 'goog.soy.testHelper', 'goog.testing.jsunit']);
                +goog.addDependency("soy/renderer.js", ['goog.soy.InjectedDataSupplier', 'goog.soy.Renderer'], ['goog.asserts', 'goog.dom', 'goog.html.uncheckedconversions', 'goog.soy', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string.Const']);
                +goog.addDependency("soy/renderer_test.js", ['goog.soy.RendererTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.SafeHtml', 'goog.i18n.bidi.Dir', 'goog.soy.Renderer', 'goog.soy.data.SanitizedContentKind', 'goog.soy.testHelper', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("soy/soy.js", ['goog.soy'], ['goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.html.legacyconversions', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string']);
                +goog.addDependency("soy/soy_test.js", ['goog.soyTest'], ['goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.functions', 'goog.soy', 'goog.soy.testHelper', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("soy/soy_testhelper.js", ['goog.soy.testHelper'], ['goog.dom', 'goog.dom.TagName', 'goog.i18n.bidi.Dir', 'goog.soy.data.SanitizedContent', 'goog.soy.data.SanitizedContentKind', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("spell/spellcheck.js", ['goog.spell.SpellCheck', 'goog.spell.SpellCheck.WordChangedEvent'], ['goog.Timer', 'goog.events.Event', 'goog.events.EventTarget', 'goog.structs.Set']);
                +goog.addDependency("spell/spellcheck_test.js", ['goog.spell.SpellCheckTest'], ['goog.spell.SpellCheck', 'goog.testing.jsunit']);
                +goog.addDependency("stats/basicstat.js", ['goog.stats.BasicStat'], ['goog.asserts', 'goog.log', 'goog.string.format', 'goog.structs.CircularBuffer']);
                +goog.addDependency("stats/basicstat_test.js", ['goog.stats.BasicStatTest'], ['goog.array', 'goog.stats.BasicStat', 'goog.string.format', 'goog.testing.PseudoRandom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/collectablestorage.js", ['goog.storage.CollectableStorage'], ['goog.array', 'goog.iter', 'goog.storage.ErrorCode', 'goog.storage.ExpiringStorage', 'goog.storage.RichStorage']);
                +goog.addDependency("storage/collectablestorage_test.js", ['goog.storage.CollectableStorageTest'], ['goog.storage.CollectableStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/collectablestoragetester.js", ['goog.storage.collectableStorageTester'], ['goog.testing.asserts']);
                +goog.addDependency("storage/encryptedstorage.js", ['goog.storage.EncryptedStorage'], ['goog.crypt', 'goog.crypt.Arc4', 'goog.crypt.Sha1', 'goog.crypt.base64', 'goog.json', 'goog.json.Serializer', 'goog.storage.CollectableStorage', 'goog.storage.ErrorCode', 'goog.storage.RichStorage']);
                +goog.addDependency("storage/encryptedstorage_test.js", ['goog.storage.EncryptedStorageTest'], ['goog.json', 'goog.storage.EncryptedStorage', 'goog.storage.ErrorCode', 'goog.storage.RichStorage', 'goog.storage.collectableStorageTester', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.PseudoRandom', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/errorcode.js", ['goog.storage.ErrorCode'], []);
                +goog.addDependency("storage/expiringstorage.js", ['goog.storage.ExpiringStorage'], ['goog.storage.RichStorage']);
                +goog.addDependency("storage/expiringstorage_test.js", ['goog.storage.ExpiringStorageTest'], ['goog.storage.ExpiringStorage', 'goog.storage.storageTester', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/mechanism/errorcode.js", ['goog.storage.mechanism.ErrorCode'], []);
                +goog.addDependency("storage/mechanism/errorhandlingmechanism.js", ['goog.storage.mechanism.ErrorHandlingMechanism'], ['goog.storage.mechanism.Mechanism']);
                +goog.addDependency("storage/mechanism/errorhandlingmechanism_test.js", ['goog.storage.mechanism.ErrorHandlingMechanismTest'], ['goog.storage.mechanism.ErrorHandlingMechanism', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("storage/mechanism/html5localstorage.js", ['goog.storage.mechanism.HTML5LocalStorage'], ['goog.storage.mechanism.HTML5WebStorage']);
                +goog.addDependency("storage/mechanism/html5localstorage_test.js", ['goog.storage.mechanism.HTML5LocalStorageTest'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/html5sessionstorage.js", ['goog.storage.mechanism.HTML5SessionStorage'], ['goog.storage.mechanism.HTML5WebStorage']);
                +goog.addDependency("storage/mechanism/html5sessionstorage_test.js", ['goog.storage.mechanism.HTML5SessionStorageTest'], ['goog.storage.mechanism.HTML5SessionStorage', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/html5webstorage.js", ['goog.storage.mechanism.HTML5WebStorage'], ['goog.asserts', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.IterableMechanism']);
                +goog.addDependency("storage/mechanism/html5webstorage_test.js", ['goog.storage.mechanism.HTML5MockStorage', 'goog.storage.mechanism.HTML5WebStorageTest', 'goog.storage.mechanism.MockThrowableStorage'], ['goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.HTML5WebStorage', 'goog.testing.jsunit']);
                +goog.addDependency("storage/mechanism/ieuserdata.js", ['goog.storage.mechanism.IEUserData'], ['goog.asserts', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.storage.mechanism.ErrorCode', 'goog.storage.mechanism.IterableMechanism', 'goog.structs.Map', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/ieuserdata_test.js", ['goog.storage.mechanism.IEUserDataTest'], ['goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("storage/mechanism/iterablemechanism.js", ['goog.storage.mechanism.IterableMechanism'], ['goog.array', 'goog.asserts', 'goog.iter', 'goog.storage.mechanism.Mechanism']);
                +goog.addDependency("storage/mechanism/iterablemechanismtester.js", ['goog.storage.mechanism.iterableMechanismTester'], ['goog.iter', 'goog.iter.StopIteration', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanism.js", ['goog.storage.mechanism.Mechanism'], []);
                +goog.addDependency("storage/mechanism/mechanismfactory.js", ['goog.storage.mechanism.mechanismfactory'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.HTML5SessionStorage', 'goog.storage.mechanism.IEUserData', 'goog.storage.mechanism.PrefixedMechanism']);
                +goog.addDependency("storage/mechanism/mechanismfactory_test.js", ['goog.storage.mechanism.mechanismfactoryTest'], ['goog.storage.mechanism.mechanismfactory', 'goog.testing.jsunit']);
                +goog.addDependency("storage/mechanism/mechanismseparationtester.js", ['goog.storage.mechanism.mechanismSeparationTester'], ['goog.iter.StopIteration', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanismsharingtester.js", ['goog.storage.mechanism.mechanismSharingTester'], ['goog.iter.StopIteration', 'goog.storage.mechanism.mechanismTestDefinition', 'goog.testing.asserts']);
                +goog.addDependency("storage/mechanism/mechanismtestdefinition.js", ['goog.storage.mechanism.mechanismTestDefinition'], []);
                +goog.addDependency("storage/mechanism/mechanismtester.js", ['goog.storage.mechanism.mechanismTester'], ['goog.storage.mechanism.ErrorCode', 'goog.testing.asserts', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("storage/mechanism/prefixedmechanism.js", ['goog.storage.mechanism.PrefixedMechanism'], ['goog.iter.Iterator', 'goog.storage.mechanism.IterableMechanism']);
                +goog.addDependency("storage/mechanism/prefixedmechanism_test.js", ['goog.storage.mechanism.PrefixedMechanismTest'], ['goog.storage.mechanism.HTML5LocalStorage', 'goog.storage.mechanism.PrefixedMechanism', 'goog.storage.mechanism.mechanismSeparationTester', 'goog.storage.mechanism.mechanismSharingTester', 'goog.testing.jsunit']);
                +goog.addDependency("storage/richstorage.js", ['goog.storage.RichStorage', 'goog.storage.RichStorage.Wrapper'], ['goog.storage.ErrorCode', 'goog.storage.Storage']);
                +goog.addDependency("storage/richstorage_test.js", ['goog.storage.RichStorageTest'], ['goog.storage.ErrorCode', 'goog.storage.RichStorage', 'goog.storage.storageTester', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/storage.js", ['goog.storage.Storage'], ['goog.json', 'goog.storage.ErrorCode']);
                +goog.addDependency("storage/storage_test.js", ['goog.storage.storage_test'], ['goog.functions', 'goog.storage.ErrorCode', 'goog.storage.Storage', 'goog.storage.mechanism.mechanismfactory', 'goog.storage.storageTester', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.storage.FakeMechanism']);
                +goog.addDependency("storage/storagetester.js", ['goog.storage.storageTester'], ['goog.storage.Storage', 'goog.structs.Map', 'goog.testing.asserts']);
                +goog.addDependency("string/const.js", ['goog.string.Const'], ['goog.asserts', 'goog.string.TypedString']);
                +goog.addDependency("string/const_test.js", ['goog.string.constTest'], ['goog.string.Const', 'goog.testing.jsunit']);
                +goog.addDependency("string/linkify.js", ['goog.string.linkify'], ['goog.html.SafeHtml', 'goog.string']);
                +goog.addDependency("string/linkify_test.js", ['goog.string.linkifyTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.string', 'goog.string.linkify', 'goog.testing.dom', 'goog.testing.jsunit']);
                +goog.addDependency("string/newlines.js", ['goog.string.newlines', 'goog.string.newlines.Line'], ['goog.array']);
                +goog.addDependency("string/newlines_test.js", ['goog.string.newlinesTest'], ['goog.string.newlines', 'goog.testing.jsunit']);
                +goog.addDependency("string/parser.js", ['goog.string.Parser'], []);
                +goog.addDependency("string/path.js", ['goog.string.path'], ['goog.array', 'goog.string']);
                +goog.addDependency("string/path_test.js", ['goog.string.pathTest'], ['goog.string.path', 'goog.testing.jsunit']);
                +goog.addDependency("string/string.js", ['goog.string', 'goog.string.Unicode'], []);
                +goog.addDependency("string/string_test.js", ['goog.stringTest'], ['goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.object', 'goog.string', 'goog.string.Unicode', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringbuffer.js", ['goog.string.StringBuffer'], []);
                +goog.addDependency("string/stringbuffer_test.js", ['goog.string.StringBufferTest'], ['goog.string.StringBuffer', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringformat.js", ['goog.string.format'], ['goog.string']);
                +goog.addDependency("string/stringformat_test.js", ['goog.string.formatTest'], ['goog.string.format', 'goog.testing.jsunit']);
                +goog.addDependency("string/stringifier.js", ['goog.string.Stringifier'], []);
                +goog.addDependency("string/typedstring.js", ['goog.string.TypedString'], []);
                +goog.addDependency("structs/avltree.js", ['goog.structs.AvlTree', 'goog.structs.AvlTree.Node'], ['goog.structs.Collection']);
                +goog.addDependency("structs/avltree_test.js", ['goog.structs.AvlTreeTest'], ['goog.array', 'goog.structs.AvlTree', 'goog.testing.jsunit']);
                +goog.addDependency("structs/circularbuffer.js", ['goog.structs.CircularBuffer'], []);
                +goog.addDependency("structs/circularbuffer_test.js", ['goog.structs.CircularBufferTest'], ['goog.structs.CircularBuffer', 'goog.testing.jsunit']);
                +goog.addDependency("structs/collection.js", ['goog.structs.Collection'], []);
                +goog.addDependency("structs/collection_test.js", ['goog.structs.CollectionTest'], ['goog.structs.AvlTree', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/heap.js", ['goog.structs.Heap'], ['goog.array', 'goog.object', 'goog.structs.Node']);
                +goog.addDependency("structs/heap_test.js", ['goog.structs.HeapTest'], ['goog.structs', 'goog.structs.Heap', 'goog.testing.jsunit']);
                +goog.addDependency("structs/inversionmap.js", ['goog.structs.InversionMap'], ['goog.array', 'goog.asserts']);
                +goog.addDependency("structs/inversionmap_test.js", ['goog.structs.InversionMapTest'], ['goog.structs.InversionMap', 'goog.testing.jsunit']);
                +goog.addDependency("structs/linkedmap.js", ['goog.structs.LinkedMap'], ['goog.structs.Map']);
                +goog.addDependency("structs/linkedmap_test.js", ['goog.structs.LinkedMapTest'], ['goog.structs.LinkedMap', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("structs/map.js", ['goog.structs.Map'], ['goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.object']);
                +goog.addDependency("structs/map_test.js", ['goog.structs.MapTest'], ['goog.iter', 'goog.structs', 'goog.structs.Map', 'goog.testing.jsunit']);
                +goog.addDependency("structs/node.js", ['goog.structs.Node'], []);
                +goog.addDependency("structs/pool.js", ['goog.structs.Pool'], ['goog.Disposable', 'goog.structs.Queue', 'goog.structs.Set']);
                +goog.addDependency("structs/pool_test.js", ['goog.structs.PoolTest'], ['goog.structs.Pool', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("structs/prioritypool.js", ['goog.structs.PriorityPool'], ['goog.structs.Pool', 'goog.structs.PriorityQueue']);
                +goog.addDependency("structs/prioritypool_test.js", ['goog.structs.PriorityPoolTest'], ['goog.structs.PriorityPool', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("structs/priorityqueue.js", ['goog.structs.PriorityQueue'], ['goog.structs.Heap']);
                +goog.addDependency("structs/priorityqueue_test.js", ['goog.structs.PriorityQueueTest'], ['goog.structs', 'goog.structs.PriorityQueue', 'goog.testing.jsunit']);
                +goog.addDependency("structs/quadtree.js", ['goog.structs.QuadTree', 'goog.structs.QuadTree.Node', 'goog.structs.QuadTree.Point'], ['goog.math.Coordinate']);
                +goog.addDependency("structs/quadtree_test.js", ['goog.structs.QuadTreeTest'], ['goog.structs', 'goog.structs.QuadTree', 'goog.testing.jsunit']);
                +goog.addDependency("structs/queue.js", ['goog.structs.Queue'], ['goog.array']);
                +goog.addDependency("structs/queue_test.js", ['goog.structs.QueueTest'], ['goog.structs.Queue', 'goog.testing.jsunit']);
                +goog.addDependency("structs/set.js", ['goog.structs.Set'], ['goog.structs', 'goog.structs.Collection', 'goog.structs.Map']);
                +goog.addDependency("structs/set_test.js", ['goog.structs.SetTest'], ['goog.iter', 'goog.structs', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/simplepool.js", ['goog.structs.SimplePool'], ['goog.Disposable']);
                +goog.addDependency("structs/stringset.js", ['goog.structs.StringSet'], ['goog.asserts', 'goog.iter']);
                +goog.addDependency("structs/stringset_test.js", ['goog.structs.StringSetTest'], ['goog.array', 'goog.iter', 'goog.structs.StringSet', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("structs/structs.js", ['goog.structs'], ['goog.array', 'goog.object']);
                +goog.addDependency("structs/structs_test.js", ['goog.structsTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.structs', 'goog.structs.Map', 'goog.structs.Set', 'goog.testing.jsunit']);
                +goog.addDependency("structs/treenode.js", ['goog.structs.TreeNode'], ['goog.array', 'goog.asserts', 'goog.structs.Node']);
                +goog.addDependency("structs/treenode_test.js", ['goog.structs.TreeNodeTest'], ['goog.structs.TreeNode', 'goog.testing.jsunit']);
                +goog.addDependency("structs/trie.js", ['goog.structs.Trie'], ['goog.object', 'goog.structs']);
                +goog.addDependency("structs/trie_test.js", ['goog.structs.TrieTest'], ['goog.object', 'goog.structs', 'goog.structs.Trie', 'goog.testing.jsunit']);
                +goog.addDependency("structs/weak/weak.js", ['goog.structs.weak'], ['goog.userAgent']);
                +goog.addDependency("structs/weak/weak_test.js", ['goog.structs.weakTest'], ['goog.array', 'goog.structs.weak', 'goog.testing.jsunit']);
                +goog.addDependency("style/bidi.js", ['goog.style.bidi'], ['goog.dom', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("style/bidi_test.js", ['goog.style.bidiTest'], ['goog.dom', 'goog.style', 'goog.style.bidi', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/cursor.js", ['goog.style.cursor'], ['goog.userAgent']);
                +goog.addDependency("style/cursor_test.js", ['goog.style.cursorTest'], ['goog.style.cursor', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/style.js", ['goog.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.vendor', 'goog.html.SafeStyleSheet', 'goog.html.legacyconversions', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.object', 'goog.reflect', 'goog.string', 'goog.userAgent']);
                +goog.addDependency("style/style_document_scroll_test.js", ['goog.style.style_document_scroll_test'], ['goog.dom', 'goog.style', 'goog.testing.jsunit']);
                +goog.addDependency("style/style_test.js", ['goog.style_test'], ['goog.array', 'goog.color', 'goog.dom', 'goog.dom.TagName', 'goog.events.BrowserEvent', 'goog.html.testing', 'goog.labs.userAgent.util', 'goog.math.Box', 'goog.math.Coordinate', 'goog.math.Rect', 'goog.math.Size', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.MockUserAgent', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil', 'goog.userAgentTestUtil.UserAgents']);
                +goog.addDependency("style/style_webkit_scrollbars_test.js", ['goog.style.webkitScrollbarsTest'], ['goog.asserts', 'goog.style', 'goog.styleScrollbarTester', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("style/stylescrollbartester.js", ['goog.styleScrollbarTester'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.asserts']);
                +goog.addDependency("style/transform.js", ['goog.style.transform'], ['goog.functions', 'goog.math.Coordinate', 'goog.math.Coordinate3', 'goog.style', 'goog.userAgent', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("style/transform_test.js", ['goog.style.transformTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.style.transform', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("style/transition.js", ['goog.style.transition', 'goog.style.transition.Css3Property'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.dom.vendor', 'goog.functions', 'goog.html.SafeHtml', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("style/transition_test.js", ['goog.style.transitionTest'], ['goog.style', 'goog.style.transition', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("test_module.js", [], []);
                +goog.addDependency("test_module_dep.js", [], []);
                +goog.addDependency("testing/asserts.js", ['goog.testing.asserts'], ['goog.testing.JsUnitException']);
                +goog.addDependency("testing/asserts_test.js", ['goog.testing.assertsTest'], ['goog.array', 'goog.dom', 'goog.iter.Iterator', 'goog.iter.StopIteration', 'goog.labs.userAgent.browser', 'goog.string', 'goog.structs.Map', 'goog.structs.Set', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("testing/async/mockcontrol.js", ['goog.testing.async.MockControl'], ['goog.asserts', 'goog.async.Deferred', 'goog.debug', 'goog.testing.asserts', 'goog.testing.mockmatchers.IgnoreArgument']);
                +goog.addDependency("testing/async/mockcontrol_test.js", ['goog.testing.async.MockControlTest'], ['goog.async.Deferred', 'goog.testing.MockControl', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.async.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase.js", ['goog.testing.AsyncTestCase', 'goog.testing.AsyncTestCase.ControlBreakingException'], ['goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/asynctestcase_async_test.js", ['goog.testing.AsyncTestCaseAsyncTest'], ['goog.testing.AsyncTestCase', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase_noasync_test.js", ['goog.testing.AsyncTestCaseSyncTest'], ['goog.testing.AsyncTestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/asynctestcase_test.js", ['goog.testing.AsyncTestCaseTest'], ['goog.debug.Error', 'goog.testing.AsyncTestCase', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("testing/benchmark.js", ['goog.testing.benchmark'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTable', 'goog.testing.PerformanceTimer', 'goog.testing.TestCase']);
                +goog.addDependency("testing/continuationtestcase.js", ['goog.testing.ContinuationTestCase', 'goog.testing.ContinuationTestCase.ContinuationTest', 'goog.testing.ContinuationTestCase.Step'], ['goog.array', 'goog.events.EventHandler', 'goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/continuationtestcase_test.js", ['goog.testing.ContinuationTestCaseTest'], ['goog.events', 'goog.events.EventTarget', 'goog.testing.ContinuationTestCase', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/deferredtestcase.js", ['goog.testing.DeferredTestCase'], ['goog.testing.AsyncTestCase', 'goog.testing.TestCase']);
                +goog.addDependency("testing/deferredtestcase_test.js", ['goog.testing.DeferredTestCaseTest'], ['goog.async.Deferred', 'goog.testing.DeferredTestCase', 'goog.testing.TestCase', 'goog.testing.TestRunner', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/dom.js", ['goog.testing.dom'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.NodeIterator', 'goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.iter', 'goog.object', 'goog.string', 'goog.style', 'goog.testing.asserts', 'goog.userAgent']);
                +goog.addDependency("testing/dom_test.js", ['goog.testing.domTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.TestCase', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/editor/dom.js", ['goog.testing.editor.dom'], ['goog.dom.NodeType', 'goog.dom.TagIterator', 'goog.dom.TagWalkType', 'goog.iter', 'goog.string', 'goog.testing.asserts']);
                +goog.addDependency("testing/editor/dom_test.js", ['goog.testing.editor.domTest'], ['goog.dom', 'goog.dom.TagName', 'goog.functions', 'goog.testing.TestCase', 'goog.testing.editor.dom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/editor/fieldmock.js", ['goog.testing.editor.FieldMock'], ['goog.dom', 'goog.dom.Range', 'goog.editor.Field', 'goog.testing.LooseMock', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/editor/testhelper.js", ['goog.testing.editor.TestHelper'], ['goog.Disposable', 'goog.dom', 'goog.dom.Range', 'goog.editor.BrowserFeature', 'goog.editor.node', 'goog.editor.plugins.AbstractBubblePlugin', 'goog.testing.dom']);
                +goog.addDependency("testing/editor/testhelper_test.js", ['goog.testing.editor.TestHelperTest'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.node', 'goog.testing.TestCase', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/events/eventobserver.js", ['goog.testing.events.EventObserver'], ['goog.array']);
                +goog.addDependency("testing/events/eventobserver_test.js", ['goog.testing.events.EventObserverTest'], ['goog.array', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.testing.events.EventObserver', 'goog.testing.jsunit']);
                +goog.addDependency("testing/events/events.js", ['goog.testing.events', 'goog.testing.events.Event'], ['goog.Disposable', 'goog.asserts', 'goog.dom.NodeType', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.BrowserFeature', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.object', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("testing/events/events_test.js", ['goog.testing.eventsTest'], ['goog.array', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.userAgent']);
                +goog.addDependency("testing/events/matchers.js", ['goog.testing.events.EventMatcher'], ['goog.events.Event', 'goog.testing.mockmatchers.ArgumentMatcher']);
                +goog.addDependency("testing/events/matchers_test.js", ['goog.testing.events.EventMatcherTest'], ['goog.events.Event', 'goog.testing.events.EventMatcher', 'goog.testing.jsunit']);
                +goog.addDependency("testing/events/onlinehandler.js", ['goog.testing.events.OnlineHandler'], ['goog.events.EventTarget', 'goog.net.NetworkStatusMonitor']);
                +goog.addDependency("testing/events/onlinehandler_test.js", ['goog.testing.events.OnlineHandlerTest'], ['goog.events', 'goog.net.NetworkStatusMonitor', 'goog.testing.events.EventObserver', 'goog.testing.events.OnlineHandler', 'goog.testing.jsunit']);
                +goog.addDependency("testing/expectedfailures.js", ['goog.testing.ExpectedFailures'], ['goog.asserts', 'goog.debug.DivConsole', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.log', 'goog.style', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.asserts']);
                +goog.addDependency("testing/expectedfailures_test.js", ['goog.testing.ExpectedFailuresTest'], ['goog.debug.Logger', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/blob.js", ['goog.testing.fs.Blob'], ['goog.crypt', 'goog.crypt.base64']);
                +goog.addDependency("testing/fs/blob_test.js", ['goog.testing.fs.BlobTest'], ['goog.dom', 'goog.testing.fs.Blob', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/directoryentry_test.js", ['goog.testing.fs.DirectoryEntryTest'], ['goog.array', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/entry.js", ['goog.testing.fs.DirectoryEntry', 'goog.testing.fs.Entry', 'goog.testing.fs.FileEntry'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.async.Deferred', 'goog.fs.DirectoryEntry', 'goog.fs.DirectoryEntryImpl', 'goog.fs.Entry', 'goog.fs.Error', 'goog.fs.FileEntry', 'goog.functions', 'goog.object', 'goog.string', 'goog.testing.fs.File', 'goog.testing.fs.FileWriter']);
                +goog.addDependency("testing/fs/entry_test.js", ['goog.testing.fs.EntryTest'], ['goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.testing.MockClock', 'goog.testing.TestCase', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/file.js", ['goog.testing.fs.File'], ['goog.testing.fs.Blob']);
                +goog.addDependency("testing/fs/fileentry_test.js", ['goog.testing.fs.FileEntryTest'], ['goog.testing.MockClock', 'goog.testing.fs.FileEntry', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/filereader.js", ['goog.testing.fs.FileReader'], ['goog.Timer', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.testing.fs.ProgressEvent']);
                +goog.addDependency("testing/fs/filereader_test.js", ['goog.testing.fs.FileReaderTest'], ['goog.Promise', 'goog.array', 'goog.events', 'goog.fs.Error', 'goog.fs.FileReader', 'goog.object', 'goog.testing.events.EventObserver', 'goog.testing.fs.FileReader', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/filesystem.js", ['goog.testing.fs.FileSystem'], ['goog.fs.FileSystem', 'goog.testing.fs.DirectoryEntry']);
                +goog.addDependency("testing/fs/filewriter.js", ['goog.testing.fs.FileWriter'], ['goog.Timer', 'goog.events.EventTarget', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.string', 'goog.testing.fs.ProgressEvent']);
                +goog.addDependency("testing/fs/filewriter_test.js", ['goog.testing.fs.FileWriterTest'], ['goog.Promise', 'goog.array', 'goog.events', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.object', 'goog.testing.MockClock', 'goog.testing.events.EventObserver', 'goog.testing.fs.Blob', 'goog.testing.fs.FileSystem', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/fs.js", ['goog.testing.fs'], ['goog.Timer', 'goog.array', 'goog.async.Deferred', 'goog.fs', 'goog.testing.fs.Blob', 'goog.testing.fs.FileSystem']);
                +goog.addDependency("testing/fs/fs_test.js", ['goog.testing.fsTest'], ['goog.testing.fs', 'goog.testing.fs.Blob', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/integration_test.js", ['goog.testing.fs.integrationTest'], ['goog.Promise', 'goog.events', 'goog.fs', 'goog.fs.DirectoryEntry', 'goog.fs.Error', 'goog.fs.FileSaver', 'goog.testing.PropertyReplacer', 'goog.testing.fs', 'goog.testing.jsunit']);
                +goog.addDependency("testing/fs/progressevent.js", ['goog.testing.fs.ProgressEvent'], ['goog.events.Event']);
                +goog.addDependency("testing/functionmock.js", ['goog.testing', 'goog.testing.FunctionMock', 'goog.testing.GlobalFunctionMock', 'goog.testing.MethodMock'], ['goog.object', 'goog.testing.LooseMock', 'goog.testing.Mock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock']);
                +goog.addDependency("testing/functionmock_test.js", ['goog.testing.FunctionMockTest'], ['goog.array', 'goog.string', 'goog.testing', 'goog.testing.FunctionMock', 'goog.testing.Mock', 'goog.testing.ObjectPropertyString', 'goog.testing.StrictMock', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/graphics.js", ['goog.testing.graphics'], ['goog.graphics.Path', 'goog.testing.asserts']);
                +goog.addDependency("testing/i18n/asserts.js", ['goog.testing.i18n.asserts'], ['goog.testing.jsunit']);
                +goog.addDependency("testing/i18n/asserts_test.js", ['goog.testing.i18n.assertsTest'], ['goog.testing.ExpectedFailures', 'goog.testing.i18n.asserts']);
                +goog.addDependency("testing/jstdasyncwrapper.js", ['goog.testing.JsTdAsyncWrapper'], ['goog.Promise']);
                +goog.addDependency("testing/jstdtestcaseadapter.js", ['goog.testing.JsTdTestCaseAdapter'], ['goog.async.run', 'goog.functions', 'goog.testing.JsTdAsyncWrapper', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/jsunit.js", ['goog.testing.jsunit'], ['goog.dom.TagName', 'goog.testing.TestCase', 'goog.testing.TestRunner']);
                +goog.addDependency("testing/jsunitexception.js", ['goog.testing.JsUnitException'], ['goog.testing.stacktrace']);
                +goog.addDependency("testing/loosemock.js", ['goog.testing.LooseExpectationCollection', 'goog.testing.LooseMock'], ['goog.array', 'goog.structs.Map', 'goog.testing.Mock']);
                +goog.addDependency("testing/loosemock_test.js", ['goog.testing.LooseMockTest'], ['goog.testing.LooseMock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/messaging/mockmessagechannel.js", ['goog.testing.messaging.MockMessageChannel'], ['goog.messaging.AbstractChannel', 'goog.testing.asserts']);
                +goog.addDependency("testing/messaging/mockmessageevent.js", ['goog.testing.messaging.MockMessageEvent'], ['goog.events.BrowserEvent', 'goog.events.EventType', 'goog.testing.events.Event']);
                +goog.addDependency("testing/messaging/mockmessageport.js", ['goog.testing.messaging.MockMessagePort'], ['goog.events.EventTarget']);
                +goog.addDependency("testing/messaging/mockportnetwork.js", ['goog.testing.messaging.MockPortNetwork'], ['goog.messaging.PortNetwork', 'goog.testing.messaging.MockMessageChannel']);
                +goog.addDependency("testing/mock.js", ['goog.testing.Mock', 'goog.testing.MockExpectation'], ['goog.array', 'goog.object', 'goog.testing.JsUnitException', 'goog.testing.MockInterface', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/mock_test.js", ['goog.testing.MockTest'], ['goog.array', 'goog.testing', 'goog.testing.Mock', 'goog.testing.MockControl', 'goog.testing.MockExpectation', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockclassfactory.js", ['goog.testing.MockClassFactory', 'goog.testing.MockClassRecord'], ['goog.array', 'goog.object', 'goog.testing.LooseMock', 'goog.testing.StrictMock', 'goog.testing.TestCase', 'goog.testing.mockmatchers']);
                +goog.addDependency("testing/mockclassfactory_test.js", ['fake.BaseClass', 'fake.ChildClass', 'goog.testing.MockClassFactoryTest'], ['goog.testing', 'goog.testing.MockClassFactory', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockclock.js", ['goog.testing.MockClock'], ['goog.Disposable', 'goog.Promise', 'goog.Thenable', 'goog.async.run', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.events.Event']);
                +goog.addDependency("testing/mockclock_test.js", ['goog.testing.MockClockTest'], ['goog.Promise', 'goog.Timer', 'goog.events', 'goog.functions', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/mockcontrol.js", ['goog.testing.MockControl'], ['goog.array', 'goog.testing', 'goog.testing.LooseMock', 'goog.testing.StrictMock']);
                +goog.addDependency("testing/mockcontrol_test.js", ['goog.testing.MockControlTest'], ['goog.testing.Mock', 'goog.testing.MockControl', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockinterface.js", ['goog.testing.MockInterface'], []);
                +goog.addDependency("testing/mockmatchers.js", ['goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.testing.mockmatchers.IgnoreArgument', 'goog.testing.mockmatchers.InstanceOf', 'goog.testing.mockmatchers.ObjectEquals', 'goog.testing.mockmatchers.RegexpMatch', 'goog.testing.mockmatchers.SaveArgument', 'goog.testing.mockmatchers.TypeOf'], ['goog.array', 'goog.dom', 'goog.testing.asserts']);
                +goog.addDependency("testing/mockmatchers_test.js", ['goog.testing.mockmatchersTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher']);
                +goog.addDependency("testing/mockrandom.js", ['goog.testing.MockRandom'], ['goog.Disposable']);
                +goog.addDependency("testing/mockrandom_test.js", ['goog.testing.MockRandomTest'], ['goog.testing.MockRandom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockrange.js", ['goog.testing.MockRange'], ['goog.dom.AbstractRange', 'goog.testing.LooseMock']);
                +goog.addDependency("testing/mockrange_test.js", ['goog.testing.MockRangeTest'], ['goog.testing.MockRange', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockstorage.js", ['goog.testing.MockStorage'], ['goog.structs.Map']);
                +goog.addDependency("testing/mockstorage_test.js", ['goog.testing.MockStorageTest'], ['goog.testing.MockStorage', 'goog.testing.jsunit']);
                +goog.addDependency("testing/mockuseragent.js", ['goog.testing.MockUserAgent'], ['goog.Disposable', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.userAgent']);
                +goog.addDependency("testing/mockuseragent_test.js", ['goog.testing.MockUserAgentTest'], ['goog.dispose', 'goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("testing/multitestrunner.js", ['goog.testing.MultiTestRunner', 'goog.testing.MultiTestRunner.TestFrame'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.functions', 'goog.object', 'goog.string', 'goog.ui.Component', 'goog.ui.ServerChart', 'goog.ui.TableSorter']);
                +goog.addDependency("testing/multitestrunner_test.js", [], []);
                +goog.addDependency("testing/net/mockiframeio.js", ['goog.testing.net.MockIFrameIo'], ['goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.IframeIo', 'goog.testing.TestQueue']);
                +goog.addDependency("testing/net/xhrio.js", ['goog.testing.net.XhrIo'], ['goog.array', 'goog.dom.xml', 'goog.events', 'goog.events.EventTarget', 'goog.json', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.HttpStatus', 'goog.net.XhrIo', 'goog.net.XmlHttp', 'goog.object', 'goog.structs', 'goog.structs.Map', 'goog.testing.TestQueue', 'goog.uri.utils']);
                +goog.addDependency("testing/net/xhrio_test.js", ['goog.testing.net.XhrIoTest'], ['goog.dom.xml', 'goog.events', 'goog.events.Event', 'goog.net.ErrorCode', 'goog.net.EventType', 'goog.net.XmlHttp', 'goog.object', 'goog.testing.MockControl', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.mockmatchers.InstanceOf', 'goog.testing.net.XhrIo']);
                +goog.addDependency("testing/net/xhriopool.js", ['goog.testing.net.XhrIoPool'], ['goog.net.XhrIoPool', 'goog.testing.net.XhrIo']);
                +goog.addDependency("testing/objectpropertystring.js", ['goog.testing.ObjectPropertyString'], []);
                +goog.addDependency("testing/parallel_closure_test_suite.js", [], []);
                +goog.addDependency("testing/parallel_closure_test_suite_test.js", [], []);
                +goog.addDependency("testing/performancetable.js", ['goog.testing.PerformanceTable'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.testing.PerformanceTimer']);
                +goog.addDependency("testing/performancetimer.js", ['goog.testing.PerformanceTimer', 'goog.testing.PerformanceTimer.Task'], ['goog.array', 'goog.async.Deferred', 'goog.math']);
                +goog.addDependency("testing/performancetimer_test.js", ['goog.testing.PerformanceTimerTest'], ['goog.async.Deferred', 'goog.dom', 'goog.math', 'goog.testing.MockClock', 'goog.testing.PerformanceTimer', 'goog.testing.jsunit']);
                +goog.addDependency("testing/propertyreplacer.js", ['goog.testing.PropertyReplacer'], ['goog.testing.ObjectPropertyString', 'goog.userAgent']);
                +goog.addDependency("testing/propertyreplacer_test.js", ['goog.testing.PropertyReplacerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("testing/proto2/proto2.js", ['goog.testing.proto2'], ['goog.proto2.Message', 'goog.proto2.ObjectSerializer', 'goog.testing.asserts']);
                +goog.addDependency("testing/proto2/proto2_test.js", ['goog.testing.proto2Test'], ['goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.proto2', 'proto2.TestAllTypes']);
                +goog.addDependency("testing/pseudorandom.js", ['goog.testing.PseudoRandom'], ['goog.Disposable']);
                +goog.addDependency("testing/pseudorandom_test.js", ['goog.testing.PseudoRandomTest'], ['goog.testing.PseudoRandom', 'goog.testing.jsunit']);
                +goog.addDependency("testing/recordfunction.js", ['goog.testing.FunctionCall', 'goog.testing.recordConstructor', 'goog.testing.recordFunction'], ['goog.testing.asserts']);
                +goog.addDependency("testing/recordfunction_test.js", ['goog.testing.recordFunctionTest'], ['goog.functions', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.recordConstructor', 'goog.testing.recordFunction']);
                +goog.addDependency("testing/shardingtestcase.js", ['goog.testing.ShardingTestCase'], ['goog.asserts', 'goog.testing.TestCase']);
                +goog.addDependency("testing/shardingtestcase_test.js", ['goog.testing.ShardingTestCaseTest'], ['goog.testing.ShardingTestCase', 'goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit']);
                +goog.addDependency("testing/singleton.js", ['goog.testing.singleton'], []);
                +goog.addDependency("testing/singleton_test.js", ['goog.testing.singletonTest'], ['goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.singleton']);
                +goog.addDependency("testing/stacktrace.js", ['goog.testing.stacktrace', 'goog.testing.stacktrace.Frame'], []);
                +goog.addDependency("testing/stacktrace_test.js", ['goog.testing.stacktraceTest'], ['goog.functions', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.stacktrace', 'goog.testing.stacktrace.Frame', 'goog.userAgent']);
                +goog.addDependency("testing/storage/fakemechanism.js", ['goog.testing.storage.FakeMechanism'], ['goog.storage.mechanism.IterableMechanism', 'goog.structs.Map']);
                +goog.addDependency("testing/strictmock.js", ['goog.testing.StrictMock'], ['goog.array', 'goog.testing.Mock']);
                +goog.addDependency("testing/strictmock_test.js", ['goog.testing.StrictMockTest'], ['goog.testing.StrictMock', 'goog.testing.jsunit']);
                +goog.addDependency("testing/style/layoutasserts.js", ['goog.testing.style.layoutasserts'], ['goog.style', 'goog.testing.asserts', 'goog.testing.style']);
                +goog.addDependency("testing/style/layoutasserts_test.js", ['goog.testing.style.layoutassertsTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.style.layoutasserts']);
                +goog.addDependency("testing/style/style.js", ['goog.testing.style'], ['goog.dom', 'goog.math.Rect', 'goog.style']);
                +goog.addDependency("testing/style/style_test.js", ['goog.testing.styleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.jsunit', 'goog.testing.style']);
                +goog.addDependency("testing/testcase.js", ['goog.testing.TestCase', 'goog.testing.TestCase.Error', 'goog.testing.TestCase.Order', 'goog.testing.TestCase.Result', 'goog.testing.TestCase.Test'], ['goog.Promise', 'goog.Thenable', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.json', 'goog.object', 'goog.testing.JsUnitException', 'goog.testing.asserts']);
                +goog.addDependency("testing/testcase_test.js", ['goog.testing.TestCaseTest'], ['goog.Promise', 'goog.Timer', 'goog.functions', 'goog.string', 'goog.testing.ExpectedFailures', 'goog.testing.JsUnitException', 'goog.testing.MethodMock', 'goog.testing.MockRandom', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit']);
                +goog.addDependency("testing/testqueue.js", ['goog.testing.TestQueue'], []);
                +goog.addDependency("testing/testrunner.js", ['goog.testing.TestRunner'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.TestCase']);
                +goog.addDependency("testing/testsuite.js", ['goog.testing.testSuite'], ['goog.labs.testing.Environment', 'goog.testing.TestCase']);
                +goog.addDependency("testing/ui/rendererasserts.js", ['goog.testing.ui.rendererasserts'], ['goog.testing.asserts', 'goog.ui.ControlRenderer']);
                +goog.addDependency("testing/ui/rendererasserts_test.js", ['goog.testing.ui.rendererassertsTest'], ['goog.testing.TestCase', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.ControlRenderer']);
                +goog.addDependency("testing/ui/rendererharness.js", ['goog.testing.ui.RendererHarness'], ['goog.Disposable', 'goog.dom.NodeType', 'goog.testing.asserts', 'goog.testing.dom']);
                +goog.addDependency("testing/ui/style.js", ['goog.testing.ui.style'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.testing.asserts']);
                +goog.addDependency("testing/ui/style_test.js", ['goog.testing.ui.styleTest'], ['goog.dom', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.testing.ui.style']);
                +goog.addDependency("timer/timer.js", ['goog.Timer'], ['goog.Promise', 'goog.events.EventTarget']);
                +goog.addDependency("timer/timer_test.js", ['goog.TimerTest'], ['goog.Promise', 'goog.Timer', 'goog.events', 'goog.testing.MockClock', 'goog.testing.jsunit']);
                +goog.addDependency("transpile.js", [], []);
                +goog.addDependency("tweak/entries.js", ['goog.tweak.BaseEntry', 'goog.tweak.BasePrimitiveSetting', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting'], ['goog.array', 'goog.asserts', 'goog.log', 'goog.object']);
                +goog.addDependency("tweak/entries_test.js", ['goog.tweak.BaseEntryTest'], ['goog.testing.MockControl', 'goog.testing.jsunit', 'goog.tweak.testhelpers']);
                +goog.addDependency("tweak/registry.js", ['goog.tweak.Registry'], ['goog.array', 'goog.asserts', 'goog.log', 'goog.string', 'goog.tweak.BasePrimitiveSetting', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting', 'goog.uri.utils']);
                +goog.addDependency("tweak/registry_test.js", ['goog.tweak.RegistryTest'], ['goog.asserts.AssertionError', 'goog.testing.jsunit', 'goog.tweak', 'goog.tweak.testhelpers']);
                +goog.addDependency("tweak/testhelpers.js", ['goog.tweak.testhelpers'], ['goog.tweak', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.Registry', 'goog.tweak.StringSetting']);
                +goog.addDependency("tweak/tweak.js", ['goog.tweak', 'goog.tweak.ConfigParams'], ['goog.asserts', 'goog.tweak.BaseSetting', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.Registry', 'goog.tweak.StringSetting']);
                +goog.addDependency("tweak/tweakui.js", ['goog.tweak.EntriesPanel', 'goog.tweak.TweakUi'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.object', 'goog.string.Const', 'goog.style', 'goog.tweak', 'goog.tweak.BaseEntry', 'goog.tweak.BooleanGroup', 'goog.tweak.BooleanInGroupSetting', 'goog.tweak.BooleanSetting', 'goog.tweak.ButtonAction', 'goog.tweak.NumericSetting', 'goog.tweak.StringSetting', 'goog.ui.Zippy', 'goog.userAgent']);
                +goog.addDependency("tweak/tweakui_test.js", ['goog.tweak.TweakUiTest'], ['goog.dom', 'goog.dom.TagName', 'goog.string', 'goog.testing.jsunit', 'goog.tweak', 'goog.tweak.TweakUi', 'goog.tweak.testhelpers']);
                +goog.addDependency("ui/abstractspellchecker.js", ['goog.ui.AbstractSpellChecker', 'goog.ui.AbstractSpellChecker.AsyncResult'], ['goog.a11y.aria', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.selection', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.spell.SpellCheck', 'goog.structs.Set', 'goog.style', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuSeparator', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/ac/ac.js", ['goog.ui.ac'], ['goog.ui.ac.ArrayMatcher', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/ac_test.js", ['goog.ui.acTest'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.classlist', 'goog.dom.selection', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.ac', 'goog.userAgent']);
                +goog.addDependency("ui/ac/arraymatcher.js", ['goog.ui.ac.ArrayMatcher'], ['goog.string']);
                +goog.addDependency("ui/ac/arraymatcher_test.js", ['goog.ui.ac.ArrayMatcherTest'], ['goog.testing.jsunit', 'goog.ui.ac.ArrayMatcher']);
                +goog.addDependency("ui/ac/autocomplete.js", ['goog.ui.ac.AutoComplete', 'goog.ui.ac.AutoComplete.EventType'], ['goog.array', 'goog.asserts', 'goog.events', 'goog.events.EventTarget', 'goog.object', 'goog.ui.ac.RenderOptions']);
                +goog.addDependency("ui/ac/autocomplete_test.js", ['goog.ui.ac.AutoCompleteTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.string', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.RenderOptions', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/cachingmatcher.js", ['goog.ui.ac.CachingMatcher'], ['goog.array', 'goog.async.Throttle', 'goog.ui.ac.ArrayMatcher', 'goog.ui.ac.RenderOptions']);
                +goog.addDependency("ui/ac/cachingmatcher_test.js", ['goog.ui.ac.CachingMatcherTest'], ['goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.ac.CachingMatcher']);
                +goog.addDependency("ui/ac/inputhandler.js", ['goog.ui.ac.InputHandler'], ['goog.Disposable', 'goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.selection', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/ac/inputhandler_test.js", ['goog.ui.ac.InputHandlerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.selection', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.KeyCodes', 'goog.functions', 'goog.object', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.ac.InputHandler', 'goog.userAgent']);
                +goog.addDependency("ui/ac/remote.js", ['goog.ui.ac.Remote'], ['goog.ui.ac.AutoComplete', 'goog.ui.ac.InputHandler', 'goog.ui.ac.RemoteArrayMatcher', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/remotearraymatcher.js", ['goog.ui.ac.RemoteArrayMatcher'], ['goog.Disposable', 'goog.Uri', 'goog.events', 'goog.json', 'goog.net.EventType', 'goog.net.XhrIo']);
                +goog.addDependency("ui/ac/remotearraymatcher_test.js", ['goog.ui.ac.RemoteArrayMatcherTest'], ['goog.json', 'goog.net.XhrIo', 'goog.testing.MockControl', 'goog.testing.jsunit', 'goog.testing.net.XhrIo', 'goog.ui.ac.RemoteArrayMatcher']);
                +goog.addDependency("ui/ac/renderer.js", ['goog.ui.ac.Renderer', 'goog.ui.ac.Renderer.CustomRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dispose', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOutAndHide', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.string', 'goog.style', 'goog.ui.IdGenerator', 'goog.ui.ac.AutoComplete']);
                +goog.addDependency("ui/ac/renderer_test.js", ['goog.ui.ac.RendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.fx.dom.FadeInAndShow', 'goog.fx.dom.FadeOutAndHide', 'goog.string', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.ac.AutoComplete', 'goog.ui.ac.Renderer']);
                +goog.addDependency("ui/ac/renderoptions.js", ['goog.ui.ac.RenderOptions'], []);
                +goog.addDependency("ui/ac/richinputhandler.js", ['goog.ui.ac.RichInputHandler'], ['goog.ui.ac.InputHandler']);
                +goog.addDependency("ui/ac/richremote.js", ['goog.ui.ac.RichRemote'], ['goog.ui.ac.AutoComplete', 'goog.ui.ac.Remote', 'goog.ui.ac.Renderer', 'goog.ui.ac.RichInputHandler', 'goog.ui.ac.RichRemoteArrayMatcher']);
                +goog.addDependency("ui/ac/richremotearraymatcher.js", ['goog.ui.ac.RichRemoteArrayMatcher'], ['goog.dom', 'goog.ui.ac.RemoteArrayMatcher']);
                +goog.addDependency("ui/activitymonitor.js", ['goog.ui.ActivityMonitor'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("ui/activitymonitor_test.js", ['goog.ui.ActivityMonitorTest'], ['goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/advancedtooltip.js", ['goog.ui.AdvancedTooltip'], ['goog.events', 'goog.events.EventType', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/advancedtooltip_test.js", ['goog.ui.AdvancedTooltipTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventType', 'goog.math.Box', 'goog.math.Coordinate', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.AdvancedTooltip', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/animatedzippy.js", ['goog.ui.AnimatedZippy'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.easing', 'goog.ui.Zippy', 'goog.ui.ZippyEvent']);
                +goog.addDependency("ui/animatedzippy_test.js", ['goog.ui.AnimatedZippyTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events', 'goog.functions', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.testing.PropertyReplacer', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.ui.AnimatedZippy', 'goog.ui.Zippy']);
                +goog.addDependency("ui/attachablemenu.js", ['goog.ui.AttachableMenu'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.string', 'goog.style', 'goog.ui.ItemEvent', 'goog.ui.MenuBase', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/bidiinput.js", ['goog.ui.BidiInput'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.InputHandler', 'goog.i18n.bidi', 'goog.ui.Component']);
                +goog.addDependency("ui/bidiinput_test.js", ['goog.ui.BidiInputTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.BidiInput']);
                +goog.addDependency("ui/bubble.js", ['goog.ui.Bubble'], ['goog.Timer', 'goog.dom.safe', 'goog.events', 'goog.events.EventType', 'goog.html.SafeHtml', 'goog.math.Box', 'goog.positioning', 'goog.positioning.AbsolutePosition', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.CornerBit', 'goog.string.Const', 'goog.style', 'goog.ui.Component', 'goog.ui.Popup']);
                +goog.addDependency("ui/button.js", ['goog.ui.Button', 'goog.ui.Button.Side'], ['goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.NativeButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/button_test.js", ['goog.ui.ButtonTest'], ['goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.NativeButtonRenderer']);
                +goog.addDependency("ui/buttonrenderer.js", ['goog.ui.ButtonRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/buttonrenderer_test.js", ['goog.ui.ButtonRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.ExpectedFailures', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.ButtonSide', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/buttonside.js", ['goog.ui.ButtonSide'], []);
                +goog.addDependency("ui/charcounter.js", ['goog.ui.CharCounter', 'goog.ui.CharCounter.Display'], ['goog.dom', 'goog.events', 'goog.events.EventTarget', 'goog.events.InputHandler']);
                +goog.addDependency("ui/charcounter_test.js", ['goog.ui.CharCounterTest'], ['goog.dom', 'goog.testing.asserts', 'goog.testing.jsunit', 'goog.ui.CharCounter', 'goog.userAgent']);
                +goog.addDependency("ui/charpicker.js", ['goog.ui.CharPicker'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.i18n.CharListDecompressor', 'goog.i18n.CharPickerData', 'goog.i18n.uChar', 'goog.i18n.uChar.NameFetcher', 'goog.structs.Set', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.ContainerScroller', 'goog.ui.FlatButtonRenderer', 'goog.ui.HoverCard', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.Tooltip']);
                +goog.addDependency("ui/charpicker_test.js", ['goog.ui.CharPickerTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dispose', 'goog.dom', 'goog.events.Event', 'goog.events.EventType', 'goog.i18n.CharPickerData', 'goog.i18n.uChar.NameFetcher', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.ui.CharPicker', 'goog.ui.FlatButtonRenderer']);
                +goog.addDependency("ui/checkbox.js", ['goog.ui.Checkbox', 'goog.ui.Checkbox.State'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.string', 'goog.ui.CheckboxRenderer', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.registry']);
                +goog.addDependency("ui/checkbox_test.js", ['goog.ui.CheckboxTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Checkbox', 'goog.ui.CheckboxRenderer', 'goog.ui.Component', 'goog.ui.ControlRenderer', 'goog.ui.decorate']);
                +goog.addDependency("ui/checkboxmenuitem.js", ['goog.ui.CheckBoxMenuItem'], ['goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/checkboxrenderer.js", ['goog.ui.CheckboxRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/colormenubutton.js", ['goog.ui.ColorMenuButton'], ['goog.array', 'goog.object', 'goog.ui.ColorMenuButtonRenderer', 'goog.ui.ColorPalette', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.registry']);
                +goog.addDependency("ui/colormenubuttonrenderer.js", ['goog.ui.ColorMenuButtonRenderer'], ['goog.asserts', 'goog.color', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.MenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/colormenubuttonrenderer_test.js", ['goog.ui.ColorMenuButtonTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.testing.ui.RendererHarness', 'goog.testing.ui.rendererasserts', 'goog.ui.ColorMenuButton', 'goog.ui.ColorMenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/colorpalette.js", ['goog.ui.ColorPalette'], ['goog.array', 'goog.color', 'goog.dom.TagName', 'goog.style', 'goog.ui.Palette', 'goog.ui.PaletteRenderer']);
                +goog.addDependency("ui/colorpalette_test.js", ['goog.ui.ColorPaletteTest'], ['goog.color', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.ColorPalette']);
                +goog.addDependency("ui/colorpicker.js", ['goog.ui.ColorPicker', 'goog.ui.ColorPicker.EventType'], ['goog.ui.ColorPalette', 'goog.ui.Component']);
                +goog.addDependency("ui/combobox.js", ['goog.ui.ComboBox', 'goog.ui.ComboBoxItem'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.log', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.ItemEvent', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.MenuSeparator', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/combobox_test.js", ['goog.ui.ComboBoxTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ComboBox', 'goog.ui.ComboBoxItem', 'goog.ui.Component', 'goog.ui.ControlRenderer', 'goog.ui.LabelInput', 'goog.ui.Menu', 'goog.ui.MenuItem']);
                +goog.addDependency("ui/component.js", ['goog.ui.Component', 'goog.ui.Component.Error', 'goog.ui.Component.EventType', 'goog.ui.Component.State'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.object', 'goog.style', 'goog.ui.IdGenerator']);
                +goog.addDependency("ui/component_test.js", ['goog.ui.ComponentTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.events.EventTarget', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component']);
                +goog.addDependency("ui/container.js", ['goog.ui.Container', 'goog.ui.Container.EventType', 'goog.ui.Container.Orientation'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.object', 'goog.style', 'goog.ui.Component', 'goog.ui.ContainerRenderer', 'goog.ui.Control']);
                +goog.addDependency("ui/container_test.js", ['goog.ui.ContainerTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.events.KeyEvent', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Control']);
                +goog.addDependency("ui/containerrenderer.js", ['goog.ui.ContainerRenderer'], ['goog.a11y.aria', 'goog.array', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.style', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/containerrenderer_test.js", ['goog.ui.ContainerRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Container', 'goog.ui.ContainerRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/containerscroller.js", ['goog.ui.ContainerScroller'], ['goog.Disposable', 'goog.Timer', 'goog.events.EventHandler', 'goog.style', 'goog.ui.Component', 'goog.ui.Container']);
                +goog.addDependency("ui/containerscroller_test.js", ['goog.ui.ContainerScrollerTest'], ['goog.dom', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Container', 'goog.ui.ContainerScroller']);
                +goog.addDependency("ui/control.js", ['goog.ui.Control'], ['goog.Disposable', 'goog.array', 'goog.dom', 'goog.events.BrowserEvent', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.string', 'goog.ui.Component', 'goog.ui.ControlContent', 'goog.ui.ControlRenderer', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/control_test.js", ['goog.ui.ControlTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.html.testing', 'goog.object', 'goog.string', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer', 'goog.ui.registry', 'goog.userAgent']);
                +goog.addDependency("ui/controlcontent.js", ['goog.ui.ControlContent'], []);
                +goog.addDependency("ui/controlrenderer.js", ['goog.ui.ControlRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/controlrenderer_test.js", ['goog.ui.ControlRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.object', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/cookieeditor.js", ['goog.ui.CookieEditor'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventType', 'goog.net.cookies', 'goog.string', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("ui/cookieeditor_test.js", ['goog.ui.CookieEditorTest'], ['goog.dom', 'goog.events.Event', 'goog.events.EventType', 'goog.net.cookies', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.CookieEditor']);
                +goog.addDependency("ui/css3buttonrenderer.js", ['goog.ui.Css3ButtonRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.Component', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/css3menubuttonrenderer.js", ['goog.ui.Css3MenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/cssnames.js", ['goog.ui.INLINE_BLOCK_CLASSNAME'], []);
                +goog.addDependency("ui/custombutton.js", ['goog.ui.CustomButton'], ['goog.ui.Button', 'goog.ui.CustomButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/custombuttonrenderer.js", ['goog.ui.CustomButtonRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.string', 'goog.ui.ButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME']);
                +goog.addDependency("ui/customcolorpalette.js", ['goog.ui.CustomColorPalette'], ['goog.color', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.ColorPalette', 'goog.ui.Component']);
                +goog.addDependency("ui/customcolorpalette_test.js", ['goog.ui.CustomColorPaletteTest'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.ui.CustomColorPalette']);
                +goog.addDependency("ui/datepicker.js", ['goog.ui.DatePicker', 'goog.ui.DatePicker.Events', 'goog.ui.DatePickerEvent'], ['goog.a11y.aria', 'goog.asserts', 'goog.date.Date', 'goog.date.DateRange', 'goog.date.Interval', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyHandler', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimePatterns', 'goog.i18n.DateTimeSymbols', 'goog.style', 'goog.ui.Component', 'goog.ui.DefaultDatePickerRenderer', 'goog.ui.IdGenerator']);
                +goog.addDependency("ui/datepicker_test.js", ['goog.ui.DatePickerTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.date.Date', 'goog.date.DateRange', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.i18n.DateTimeSymbols', 'goog.i18n.DateTimeSymbols_en_US', 'goog.i18n.DateTimeSymbols_zh_HK', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.DatePicker']);
                +goog.addDependency("ui/datepickerrenderer.js", ['goog.ui.DatePickerRenderer'], []);
                +goog.addDependency("ui/decorate.js", ['goog.ui.decorate'], ['goog.ui.registry']);
                +goog.addDependency("ui/decorate_test.js", ['goog.ui.decorateTest'], ['goog.testing.jsunit', 'goog.ui.decorate', 'goog.ui.registry']);
                +goog.addDependency("ui/defaultdatepickerrenderer.js", ['goog.ui.DefaultDatePickerRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.DatePickerRenderer']);
                +goog.addDependency("ui/dialog.js", ['goog.ui.Dialog', 'goog.ui.Dialog.ButtonSet', 'goog.ui.Dialog.ButtonSet.DefaultButtons', 'goog.ui.Dialog.DefaultButtonCaptions', 'goog.ui.Dialog.DefaultButtonKeys', 'goog.ui.Dialog.Event', 'goog.ui.Dialog.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.safe', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Dragger', 'goog.html.SafeHtml', 'goog.math.Rect', 'goog.string', 'goog.structs.Map', 'goog.style', 'goog.ui.ModalPopup']);
                +goog.addDependency("ui/dialog_test.js", ['goog.ui.DialogTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.css3', 'goog.html.SafeHtml', 'goog.html.testing', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Dialog', 'goog.userAgent']);
                +goog.addDependency("ui/dimensionpicker.js", ['goog.ui.DimensionPicker'], ['goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.DimensionPickerRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/dimensionpicker_test.js", ['goog.ui.DimensionPickerTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.DimensionPicker', 'goog.ui.DimensionPickerRenderer']);
                +goog.addDependency("ui/dimensionpickerrenderer.js", ['goog.ui.DimensionPickerRenderer'], ['goog.a11y.aria.Announcer', 'goog.a11y.aria.LivePriority', 'goog.dom', 'goog.dom.TagName', 'goog.i18n.bidi', 'goog.style', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/dimensionpickerrenderer_test.js", ['goog.ui.DimensionPickerRendererTest'], ['goog.a11y.aria.LivePriority', 'goog.array', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.DimensionPicker', 'goog.ui.DimensionPickerRenderer']);
                +goog.addDependency("ui/dragdropdetector.js", ['goog.ui.DragDropDetector', 'goog.ui.DragDropDetector.EventType', 'goog.ui.DragDropDetector.ImageDropEvent', 'goog.ui.DragDropDetector.LinkDropEvent'], ['goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("ui/drilldownrow.js", ['goog.ui.DrilldownRow'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.string.Unicode', 'goog.ui.Component']);
                +goog.addDependency("ui/drilldownrow_test.js", ['goog.ui.DrilldownRowTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.SafeHtml', 'goog.testing.jsunit', 'goog.ui.DrilldownRow']);
                +goog.addDependency("ui/editor/abstractdialog.js", ['goog.ui.editor.AbstractDialog', 'goog.ui.editor.AbstractDialog.Builder', 'goog.ui.editor.AbstractDialog.EventType'], ['goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventTarget', 'goog.string', 'goog.ui.Dialog', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/editor/abstractdialog_test.js", ['goog.ui.editor.AbstractDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.KeyCodes', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.userAgent']);
                +goog.addDependency("ui/editor/bubble.js", ['goog.ui.editor.Bubble'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.ViewportSizeMonitor', 'goog.dom.classlist', 'goog.editor.style', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.functions', 'goog.log', 'goog.math.Box', 'goog.object', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/editor/bubble_test.js", ['goog.ui.editor.BubbleTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.positioning.Corner', 'goog.positioning.OverflowStatus', 'goog.string', 'goog.style', 'goog.testing.editor.TestHelper', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.editor.Bubble', 'goog.userAgent.product']);
                +goog.addDependency("ui/editor/defaulttoolbar.js", ['goog.ui.editor.ButtonDescriptor', 'goog.ui.editor.DefaultToolbar'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.editor.Command', 'goog.style', 'goog.ui.editor.ToolbarFactory', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("ui/editor/linkdialog.js", ['goog.ui.editor.LinkDialog', 'goog.ui.editor.LinkDialog.BeforeTestLinkEvent', 'goog.ui.editor.LinkDialog.EventType', 'goog.ui.editor.LinkDialog.OkEvent'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.editor.BrowserFeature', 'goog.editor.Link', 'goog.editor.focus', 'goog.editor.node', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.InputHandler', 'goog.html.SafeHtml', 'goog.html.SafeHtmlFormatter', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.LinkButtonRenderer', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.TabPane', 'goog.ui.editor.messages', 'goog.userAgent', 'goog.window']);
                +goog.addDependency("ui/editor/linkdialog_test.js", ['goog.ui.editor.LinkDialogTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.editor.BrowserFeature', 'goog.editor.Link', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style', 'goog.testing.MockControl', 'goog.testing.PropertyReplacer', 'goog.testing.dom', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.mockmatchers.ArgumentMatcher', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.LinkDialog', 'goog.ui.editor.messages', 'goog.userAgent']);
                +goog.addDependency("ui/editor/messages.js", ['goog.ui.editor.messages'], ['goog.html.uncheckedconversions', 'goog.string.Const']);
                +goog.addDependency("ui/editor/tabpane.js", ['goog.ui.editor.TabPane'], ['goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.Tab', 'goog.ui.TabBar']);
                +goog.addDependency("ui/editor/toolbarcontroller.js", ['goog.ui.editor.ToolbarController'], ['goog.editor.Field', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.ui.Component']);
                +goog.addDependency("ui/editor/toolbarfactory.js", ['goog.ui.editor.ToolbarFactory'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.string', 'goog.string.Unicode', 'goog.style', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Option', 'goog.ui.Toolbar', 'goog.ui.ToolbarButton', 'goog.ui.ToolbarColorMenuButton', 'goog.ui.ToolbarMenuButton', 'goog.ui.ToolbarRenderer', 'goog.ui.ToolbarSelect', 'goog.userAgent']);
                +goog.addDependency("ui/editor/toolbarfactory_test.js", ['goog.ui.editor.ToolbarFactoryTest'], ['goog.dom', 'goog.testing.ExpectedFailures', 'goog.testing.editor.TestHelper', 'goog.testing.jsunit', 'goog.ui.editor.ToolbarFactory', 'goog.userAgent']);
                +goog.addDependency("ui/emoji/emoji.js", ['goog.ui.emoji.Emoji'], []);
                +goog.addDependency("ui/emoji/emojipalette.js", ['goog.ui.emoji.EmojiPalette'], ['goog.events.EventType', 'goog.net.ImageLoader', 'goog.ui.Palette', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/emojipaletterenderer.js", ['goog.ui.emoji.EmojiPaletteRenderer'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.style', 'goog.ui.PaletteRenderer', 'goog.ui.emoji.Emoji']);
                +goog.addDependency("ui/emoji/emojipicker.js", ['goog.ui.emoji.EmojiPicker'], ['goog.dom.TagName', 'goog.style', 'goog.ui.Component', 'goog.ui.TabPane', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPalette', 'goog.ui.emoji.EmojiPaletteRenderer', 'goog.ui.emoji.ProgressiveEmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/emojipicker_test.js", ['goog.ui.emoji.EmojiPickerTest'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/fast_nonprogressive_emojipicker_test.js", ['goog.ui.emoji.FastNonProgressiveEmojiPickerTest'], ['goog.Promise', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.net.EventType', 'goog.style', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/fast_progressive_emojipicker_test.js", ['goog.ui.emoji.FastProgressiveEmojiPickerTest'], ['goog.Promise', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.net.EventType', 'goog.style', 'goog.testing.jsunit', 'goog.ui.emoji.Emoji', 'goog.ui.emoji.EmojiPicker', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/emoji/popupemojipicker.js", ['goog.ui.emoji.PopupEmojiPicker'], ['goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.ui.Component', 'goog.ui.Popup', 'goog.ui.emoji.EmojiPicker']);
                +goog.addDependency("ui/emoji/popupemojipicker_test.js", ['goog.ui.emoji.PopupEmojiPickerTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.emoji.PopupEmojiPicker']);
                +goog.addDependency("ui/emoji/progressiveemojipaletterenderer.js", ['goog.ui.emoji.ProgressiveEmojiPaletteRenderer'], ['goog.dom.TagName', 'goog.style', 'goog.ui.emoji.EmojiPaletteRenderer']);
                +goog.addDependency("ui/emoji/spriteinfo.js", ['goog.ui.emoji.SpriteInfo'], []);
                +goog.addDependency("ui/emoji/spriteinfo_test.js", ['goog.ui.emoji.SpriteInfoTest'], ['goog.testing.jsunit', 'goog.ui.emoji.SpriteInfo']);
                +goog.addDependency("ui/filteredmenu.js", ['goog.ui.FilteredMenu'], ['goog.a11y.aria', 'goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.object', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.FilterObservingMenuItem', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.userAgent']);
                +goog.addDependency("ui/filteredmenu_test.js", ['goog.ui.FilteredMenuTest'], ['goog.a11y.aria', 'goog.a11y.aria.AutoCompleteValues', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Rect', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.FilteredMenu', 'goog.ui.MenuItem']);
                +goog.addDependency("ui/filterobservingmenuitem.js", ['goog.ui.FilterObservingMenuItem'], ['goog.ui.FilterObservingMenuItemRenderer', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/filterobservingmenuitemrenderer.js", ['goog.ui.FilterObservingMenuItemRenderer'], ['goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/flatbuttonrenderer.js", ['goog.ui.FlatButtonRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.ButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/flatmenubuttonrenderer.js", ['goog.ui.FlatMenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.FlatButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/formpost.js", ['goog.ui.FormPost'], ['goog.array', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeHtml', 'goog.ui.Component']);
                +goog.addDependency("ui/formpost_test.js", ['goog.ui.FormPostTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.object', 'goog.testing.jsunit', 'goog.ui.FormPost', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("ui/gauge.js", ['goog.ui.Gauge', 'goog.ui.GaugeColoredRange'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.TagName', 'goog.events', 'goog.fx.Animation', 'goog.fx.Transition', 'goog.fx.easing', 'goog.graphics', 'goog.graphics.Font', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.math', 'goog.ui.Component', 'goog.ui.GaugeTheme']);
                +goog.addDependency("ui/gaugetheme.js", ['goog.ui.GaugeTheme'], ['goog.graphics.LinearGradient', 'goog.graphics.SolidFill', 'goog.graphics.Stroke']);
                +goog.addDependency("ui/hovercard.js", ['goog.ui.HoverCard', 'goog.ui.HoverCard.EventType', 'goog.ui.HoverCard.TriggerEvent'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.ui.AdvancedTooltip', 'goog.ui.PopupBase', 'goog.ui.Tooltip']);
                +goog.addDependency("ui/hovercard_test.js", ['goog.ui.HoverCardTest'], ['goog.dom', 'goog.events', 'goog.math.Coordinate', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.HoverCard']);
                +goog.addDependency("ui/hsvapalette.js", ['goog.ui.HsvaPalette'], ['goog.array', 'goog.color.alpha', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.HsvPalette']);
                +goog.addDependency("ui/hsvapalette_test.js", ['goog.ui.HsvaPaletteTest'], ['goog.color.alpha', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.Event', 'goog.math.Coordinate', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.HsvaPalette', 'goog.userAgent']);
                +goog.addDependency("ui/hsvpalette.js", ['goog.ui.HsvPalette'], ['goog.color', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.events.InputHandler', 'goog.style', 'goog.style.bidi', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/hsvpalette_test.js", ['goog.ui.HsvPaletteTest'], ['goog.color', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.math.Coordinate', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.HsvPalette', 'goog.userAgent']);
                +goog.addDependency("ui/idgenerator.js", ['goog.ui.IdGenerator'], []);
                +goog.addDependency("ui/idletimer.js", ['goog.ui.IdleTimer'], ['goog.Timer', 'goog.events', 'goog.events.EventTarget', 'goog.structs.Set', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/idletimer_test.js", ['goog.ui.IdleTimerTest'], ['goog.events', 'goog.testing.MockClock', 'goog.testing.jsunit', 'goog.ui.IdleTimer', 'goog.ui.MockActivityMonitor']);
                +goog.addDependency("ui/iframemask.js", ['goog.ui.IframeMask'], ['goog.Disposable', 'goog.Timer', 'goog.dom', 'goog.dom.iframe', 'goog.events.EventHandler', 'goog.structs.Pool', 'goog.style']);
                +goog.addDependency("ui/iframemask_test.js", ['goog.ui.IframeMaskTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.iframe', 'goog.structs.Pool', 'goog.style', 'goog.testing.MockClock', 'goog.testing.StrictMock', 'goog.testing.jsunit', 'goog.ui.IframeMask', 'goog.ui.Popup', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/imagelessbuttonrenderer.js", ['goog.ui.ImagelessButtonRenderer'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/imagelessmenubuttonrenderer.js", ['goog.ui.ImagelessMenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/inputdatepicker.js", ['goog.ui.InputDatePicker'], ['goog.date.DateTime', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.i18n.DateTimeParse', 'goog.string', 'goog.ui.Component', 'goog.ui.DatePicker', 'goog.ui.LabelInput', 'goog.ui.PopupBase', 'goog.ui.PopupDatePicker']);
                +goog.addDependency("ui/inputdatepicker_test.js", ['goog.ui.InputDatePickerTest'], ['goog.dom', 'goog.i18n.DateTimeFormat', 'goog.i18n.DateTimeParse', 'goog.testing.jsunit', 'goog.ui.InputDatePicker']);
                +goog.addDependency("ui/itemevent.js", ['goog.ui.ItemEvent'], ['goog.events.Event']);
                +goog.addDependency("ui/keyboardshortcuthandler.js", ['goog.ui.KeyboardShortcutEvent', 'goog.ui.KeyboardShortcutHandler', 'goog.ui.KeyboardShortcutHandler.EventType', 'goog.ui.KeyboardShortcutHandler.Modifiers'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyNames', 'goog.events.Keys', 'goog.object', 'goog.userAgent']);
                +goog.addDependency("ui/keyboardshortcuthandler_test.js", ['goog.ui.KeyboardShortcutHandlerTest'], ['goog.dom', 'goog.events', 'goog.events.BrowserEvent', 'goog.events.KeyCodes', 'goog.testing.MockClock', 'goog.testing.PropertyReplacer', 'goog.testing.StrictMock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.KeyboardShortcutHandler', 'goog.userAgent']);
                +goog.addDependency("ui/labelinput.js", ['goog.ui.LabelInput'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/labelinput_test.js", ['goog.ui.LabelInputTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventType', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.LabelInput', 'goog.userAgent']);
                +goog.addDependency("ui/linkbuttonrenderer.js", ['goog.ui.LinkButtonRenderer'], ['goog.ui.Button', 'goog.ui.FlatButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/media/flashobject.js", ['goog.ui.media.FlashObject', 'goog.ui.media.FlashObject.ScriptAccessLevel', 'goog.ui.media.FlashObject.Wmodes'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.html.TrustedResourceUrl', 'goog.html.flash', 'goog.log', 'goog.object', 'goog.string', 'goog.structs.Map', 'goog.style', 'goog.ui.Component', 'goog.userAgent', 'goog.userAgent.flash']);
                +goog.addDependency("ui/media/flashobject_test.js", ['goog.ui.media.FlashObjectTest'], ['goog.dom', 'goog.dom.DomHelper', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.html.testing', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.userAgent']);
                +goog.addDependency("ui/media/flickr.js", ['goog.ui.media.FlickrSet', 'goog.ui.media.FlickrSetModel'], ['goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/flickr_test.js", ['goog.ui.media.FlickrSetTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.FlickrSet', 'goog.ui.media.FlickrSetModel', 'goog.ui.media.Media']);
                +goog.addDependency("ui/media/googlevideo.js", ['goog.ui.media.GoogleVideo', 'goog.ui.media.GoogleVideoModel'], ['goog.html.uncheckedconversions', 'goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/googlevideo_test.js", ['goog.ui.media.GoogleVideoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.GoogleVideo', 'goog.ui.media.GoogleVideoModel', 'goog.ui.media.Media']);
                +goog.addDependency("ui/media/media.js", ['goog.ui.media.Media', 'goog.ui.media.MediaRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.style', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/media/media_test.js", ['goog.ui.media.MediaTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.math.Size', 'goog.testing.jsunit', 'goog.ui.ControlRenderer', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/mediamodel.js", ['goog.ui.media.MediaModel', 'goog.ui.media.MediaModel.Category', 'goog.ui.media.MediaModel.Credit', 'goog.ui.media.MediaModel.Credit.Role', 'goog.ui.media.MediaModel.Credit.Scheme', 'goog.ui.media.MediaModel.Medium', 'goog.ui.media.MediaModel.MimeType', 'goog.ui.media.MediaModel.Player', 'goog.ui.media.MediaModel.SubTitle', 'goog.ui.media.MediaModel.Thumbnail'], ['goog.array', 'goog.html.TrustedResourceUrl']);
                +goog.addDependency("ui/media/mediamodel_test.js", ['goog.ui.media.MediaModelTest'], ['goog.testing.jsunit', 'goog.ui.media.MediaModel']);
                +goog.addDependency("ui/media/mp3.js", ['goog.ui.media.Mp3'], ['goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/mp3_test.js", ['goog.ui.media.Mp3Test'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.Mp3']);
                +goog.addDependency("ui/media/photo.js", ['goog.ui.media.Photo'], ['goog.dom.TagName', 'goog.ui.media.Media', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/photo_test.js", ['goog.ui.media.PhotoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.media.MediaModel', 'goog.ui.media.Photo']);
                +goog.addDependency("ui/media/picasa.js", ['goog.ui.media.PicasaAlbum', 'goog.ui.media.PicasaAlbumModel'], ['goog.html.TrustedResourceUrl', 'goog.string.Const', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/picasa_test.js", ['goog.ui.media.PicasaTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.PicasaAlbum', 'goog.ui.media.PicasaAlbumModel']);
                +goog.addDependency("ui/media/vimeo.js", ['goog.ui.media.Vimeo', 'goog.ui.media.VimeoModel'], ['goog.html.uncheckedconversions', 'goog.string', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/vimeo_test.js", ['goog.ui.media.VimeoTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.Vimeo', 'goog.ui.media.VimeoModel']);
                +goog.addDependency("ui/media/youtube.js", ['goog.ui.media.Youtube', 'goog.ui.media.YoutubeModel'], ['goog.dom.TagName', 'goog.html.uncheckedconversions', 'goog.string', 'goog.ui.Component', 'goog.ui.media.FlashObject', 'goog.ui.media.Media', 'goog.ui.media.MediaModel', 'goog.ui.media.MediaRenderer']);
                +goog.addDependency("ui/media/youtube_test.js", ['goog.ui.media.YoutubeTest'], ['goog.dom', 'goog.dom.TagName', 'goog.testing.jsunit', 'goog.ui.media.FlashObject', 'goog.ui.media.Youtube', 'goog.ui.media.YoutubeModel']);
                +goog.addDependency("ui/menu.js", ['goog.ui.Menu', 'goog.ui.Menu.EventType'], ['goog.dom.TagName', 'goog.math.Coordinate', 'goog.string', 'goog.style', 'goog.ui.Component.EventType', 'goog.ui.Component.State', 'goog.ui.Container', 'goog.ui.Container.Orientation', 'goog.ui.MenuHeader', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.MenuSeparator']);
                +goog.addDependency("ui/menu_test.js", ['goog.ui.MenuTest'], ['goog.dom', 'goog.events', 'goog.math.Coordinate', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Menu']);
                +goog.addDependency("ui/menubar.js", ['goog.ui.menuBar'], ['goog.ui.Container', 'goog.ui.MenuBarRenderer']);
                +goog.addDependency("ui/menubardecorator.js", ['goog.ui.menuBarDecorator'], ['goog.ui.MenuBarRenderer', 'goog.ui.menuBar', 'goog.ui.registry']);
                +goog.addDependency("ui/menubarrenderer.js", ['goog.ui.MenuBarRenderer'], ['goog.a11y.aria.Role', 'goog.ui.Container', 'goog.ui.ContainerRenderer']);
                +goog.addDependency("ui/menubase.js", ['goog.ui.MenuBase'], ['goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyHandler', 'goog.ui.Popup']);
                +goog.addDependency("ui/menubutton.js", ['goog.ui.MenuButton'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.math.Box', 'goog.math.Rect', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.IdGenerator', 'goog.ui.Menu', 'goog.ui.MenuButtonRenderer', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.registry', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/menubutton_test.js", ['goog.ui.MenuButtonTest'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.positioning', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.PropertyReplacer', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.SubMenu', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("ui/menubuttonrenderer.js", ['goog.ui.MenuButtonRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.Menu', 'goog.ui.MenuRenderer']);
                +goog.addDependency("ui/menubuttonrenderer_test.js", ['goog.ui.MenuButtonRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.MenuButton', 'goog.ui.MenuButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/menuheader.js", ['goog.ui.MenuHeader'], ['goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuHeaderRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/menuheaderrenderer.js", ['goog.ui.MenuHeaderRenderer'], ['goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuitem.js", ['goog.ui.MenuItem'], ['goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.classlist', 'goog.math.Coordinate', 'goog.string', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuItemRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/menuitem_test.js", ['goog.ui.MenuItemTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.html.testing', 'goog.math.Coordinate', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/menuitemrenderer.js", ['goog.ui.MenuItemRenderer'], ['goog.a11y.aria.Role', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuitemrenderer_test.js", ['goog.ui.MenuItemRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/menurenderer.js", ['goog.ui.MenuRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.ui.ContainerRenderer', 'goog.ui.Separator']);
                +goog.addDependency("ui/menuseparator.js", ['goog.ui.MenuSeparator'], ['goog.ui.MenuSeparatorRenderer', 'goog.ui.Separator', 'goog.ui.registry']);
                +goog.addDependency("ui/menuseparatorrenderer.js", ['goog.ui.MenuSeparatorRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/menuseparatorrenderer_test.js", ['goog.ui.MenuSeparatorRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.MenuSeparator', 'goog.ui.MenuSeparatorRenderer']);
                +goog.addDependency("ui/mockactivitymonitor.js", ['goog.ui.MockActivityMonitor'], ['goog.events.EventType', 'goog.ui.ActivityMonitor']);
                +goog.addDependency("ui/mockactivitymonitor_test.js", ['goog.ui.MockActivityMonitorTest'], ['goog.events', 'goog.functions', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.ActivityMonitor', 'goog.ui.MockActivityMonitor']);
                +goog.addDependency("ui/modalariavisibilityhelper.js", ['goog.ui.ModalAriaVisibilityHelper'], ['goog.a11y.aria', 'goog.a11y.aria.State']);
                +goog.addDependency("ui/modalariavisibilityhelper_test.js", ['goog.ui.ModalAriaVisibilityHelperTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.string', 'goog.testing.jsunit', 'goog.ui.ModalAriaVisibilityHelper']);
                +goog.addDependency("ui/modalpopup.js", ['goog.ui.ModalPopup'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.animationFrame', 'goog.dom.classlist', 'goog.dom.iframe', 'goog.events', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.fx.Transition', 'goog.string', 'goog.style', 'goog.ui.Component', 'goog.ui.ModalAriaVisibilityHelper', 'goog.ui.PopupBase', 'goog.userAgent']);
                +goog.addDependency("ui/modalpopup_test.js", ['goog.ui.ModalPopupTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dispose', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.fx.Transition', 'goog.fx.css3', 'goog.string', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ModalPopup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/nativebuttonrenderer.js", ['goog.ui.NativeButtonRenderer'], ['goog.asserts', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.ui.ButtonRenderer', 'goog.ui.Component']);
                +goog.addDependency("ui/nativebuttonrenderer_test.js", ['goog.ui.NativeButtonRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.testing.ExpectedFailures', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.NativeButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/option.js", ['goog.ui.Option'], ['goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/palette.js", ['goog.ui.Palette'], ['goog.array', 'goog.dom', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Size', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.PaletteRenderer', 'goog.ui.SelectionModel']);
                +goog.addDependency("ui/palette_test.js", ['goog.ui.PaletteTest'], ['goog.a11y.aria', 'goog.dom', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyEvent', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Palette']);
                +goog.addDependency("ui/paletterenderer.js", ['goog.ui.PaletteRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.NodeIterator', 'goog.dom.NodeType', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.iter', 'goog.style', 'goog.ui.ControlRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/paletterenderer_test.js", ['goog.ui.PaletteRendererTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.Palette', 'goog.ui.PaletteRenderer']);
                +goog.addDependency("ui/plaintextspellchecker.js", ['goog.ui.PlainTextSpellChecker'], ['goog.Timer', 'goog.a11y.aria', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.spell.SpellCheck', 'goog.style', 'goog.ui.AbstractSpellChecker', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/plaintextspellchecker_test.js", ['goog.ui.PlainTextSpellCheckerTest'], ['goog.Timer', 'goog.dom', 'goog.events.KeyCodes', 'goog.spell.SpellCheck', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.PlainTextSpellChecker']);
                +goog.addDependency("ui/popup.js", ['goog.ui.Popup'], ['goog.math.Box', 'goog.positioning.AbstractPosition', 'goog.positioning.Corner', 'goog.style', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popup_test.js", ['goog.ui.PopupTest'], ['goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.style', 'goog.testing.jsunit', 'goog.ui.Popup', 'goog.userAgent']);
                +goog.addDependency("ui/popupbase.js", ['goog.ui.PopupBase', 'goog.ui.PopupBase.EventType', 'goog.ui.PopupBase.Type'], ['goog.Timer', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Transition', 'goog.style', 'goog.userAgent']);
                +goog.addDependency("ui/popupbase_test.js", ['goog.ui.PopupBaseTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Transition', 'goog.fx.css3', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupcolorpicker.js", ['goog.ui.PopupColorPicker'], ['goog.asserts', 'goog.dom.classlist', 'goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.ui.ColorPicker', 'goog.ui.Component', 'goog.ui.Popup']);
                +goog.addDependency("ui/popupcolorpicker_test.js", ['goog.ui.PopupColorPickerTest'], ['goog.dom', 'goog.events', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.ColorPicker', 'goog.ui.PopupColorPicker']);
                +goog.addDependency("ui/popupdatepicker.js", ['goog.ui.PopupDatePicker'], ['goog.events.EventType', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.style', 'goog.ui.Component', 'goog.ui.DatePicker', 'goog.ui.Popup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupdatepicker_test.js", ['goog.ui.PopupDatePickerTest'], ['goog.date.Date', 'goog.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.PopupBase', 'goog.ui.PopupDatePicker']);
                +goog.addDependency("ui/popupmenu.js", ['goog.ui.PopupMenu'], ['goog.events', 'goog.events.BrowserEvent', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.positioning.MenuAnchoredPosition', 'goog.positioning.Overflow', 'goog.positioning.ViewportClientPosition', 'goog.structs.Map', 'goog.style', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/popupmenu_test.js", ['goog.ui.PopupMenuTest'], ['goog.dom', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.math.Box', 'goog.math.Coordinate', 'goog.positioning.Corner', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/progressbar.js", ['goog.ui.ProgressBar', 'goog.ui.ProgressBar.Orientation'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.ui.Component', 'goog.ui.RangeModel', 'goog.userAgent']);
                +goog.addDependency("ui/prompt.js", ['goog.ui.Prompt'], ['goog.Timer', 'goog.dom', 'goog.dom.InputType', 'goog.dom.TagName', 'goog.events', 'goog.events.EventType', 'goog.functions', 'goog.html.SafeHtml', 'goog.ui.Component', 'goog.ui.Dialog', 'goog.userAgent']);
                +goog.addDependency("ui/prompt_test.js", ['goog.ui.PromptTest'], ['goog.dom.selection', 'goog.events.InputHandler', 'goog.events.KeyCodes', 'goog.functions', 'goog.string', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.BidiInput', 'goog.ui.Dialog', 'goog.ui.Prompt', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/rangemodel.js", ['goog.ui.RangeModel'], ['goog.events.EventTarget', 'goog.ui.Component']);
                +goog.addDependency("ui/rangemodel_test.js", ['goog.ui.RangeModelTest'], ['goog.testing.jsunit', 'goog.ui.RangeModel']);
                +goog.addDependency("ui/ratings.js", ['goog.ui.Ratings', 'goog.ui.Ratings.EventType'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.ui.Component']);
                +goog.addDependency("ui/registry.js", ['goog.ui.registry'], ['goog.asserts', 'goog.dom.classlist']);
                +goog.addDependency("ui/registry_test.js", ['goog.ui.registryTest'], ['goog.object', 'goog.testing.jsunit', 'goog.ui.registry']);
                +goog.addDependency("ui/richtextspellchecker.js", ['goog.ui.RichTextSpellChecker'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.NodeType', 'goog.dom.Range', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.math.Coordinate', 'goog.spell.SpellCheck', 'goog.string.StringBuffer', 'goog.style', 'goog.ui.AbstractSpellChecker', 'goog.ui.Component', 'goog.ui.PopupMenu']);
                +goog.addDependency("ui/richtextspellchecker_test.js", ['goog.ui.RichTextSpellCheckerTest'], ['goog.dom.Range', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.object', 'goog.spell.SpellCheck', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.RichTextSpellChecker']);
                +goog.addDependency("ui/roundedpanel.js", ['goog.ui.BaseRoundedPanel', 'goog.ui.CssRoundedPanel', 'goog.ui.GraphicsRoundedPanel', 'goog.ui.RoundedPanel', 'goog.ui.RoundedPanel.Corner'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.graphics', 'goog.graphics.Path', 'goog.graphics.SolidFill', 'goog.graphics.Stroke', 'goog.math', 'goog.math.Coordinate', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/roundedpanel_test.js", ['goog.ui.RoundedPanelTest'], ['goog.testing.jsunit', 'goog.ui.CssRoundedPanel', 'goog.ui.GraphicsRoundedPanel', 'goog.ui.RoundedPanel', 'goog.userAgent']);
                +goog.addDependency("ui/roundedtabrenderer.js", ['goog.ui.RoundedTabRenderer'], ['goog.dom', 'goog.dom.TagName', 'goog.ui.Tab', 'goog.ui.TabBar', 'goog.ui.TabRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/scrollfloater.js", ['goog.ui.ScrollFloater', 'goog.ui.ScrollFloater.EventType'], ['goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/scrollfloater_test.js", ['goog.ui.ScrollFloaterTest'], ['goog.dom', 'goog.events', 'goog.style', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.ui.ScrollFloater']);
                +goog.addDependency("ui/select.js", ['goog.ui.Select'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.events.EventType', 'goog.ui.Component', 'goog.ui.IdGenerator', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.MenuRenderer', 'goog.ui.SelectionModel', 'goog.ui.registry']);
                +goog.addDependency("ui/select_test.js", ['goog.ui.SelectTest'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.Select', 'goog.ui.Separator']);
                +goog.addDependency("ui/selectionmenubutton.js", ['goog.ui.SelectionMenuButton', 'goog.ui.SelectionMenuButton.SelectionState'], ['goog.dom.InputType', 'goog.dom.TagName', 'goog.events.EventType', 'goog.style', 'goog.ui.Component', 'goog.ui.MenuButton', 'goog.ui.MenuItem', 'goog.ui.registry']);
                +goog.addDependency("ui/selectionmenubutton_test.js", ['goog.ui.SelectionMenuButtonTest'], ['goog.dom', 'goog.events', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.SelectionMenuButton']);
                +goog.addDependency("ui/selectionmodel.js", ['goog.ui.SelectionModel'], ['goog.array', 'goog.events.EventTarget', 'goog.events.EventType']);
                +goog.addDependency("ui/selectionmodel_test.js", ['goog.ui.SelectionModelTest'], ['goog.array', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.SelectionModel']);
                +goog.addDependency("ui/separator.js", ['goog.ui.Separator'], ['goog.a11y.aria', 'goog.asserts', 'goog.ui.Component', 'goog.ui.Control', 'goog.ui.MenuSeparatorRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/serverchart.js", ['goog.ui.ServerChart', 'goog.ui.ServerChart.AxisDisplayType', 'goog.ui.ServerChart.ChartType', 'goog.ui.ServerChart.EncodingType', 'goog.ui.ServerChart.Event', 'goog.ui.ServerChart.LegendPosition', 'goog.ui.ServerChart.MaximumValue', 'goog.ui.ServerChart.MultiAxisAlignment', 'goog.ui.ServerChart.MultiAxisType', 'goog.ui.ServerChart.UriParam', 'goog.ui.ServerChart.UriTooLongEvent'], ['goog.Uri', 'goog.array', 'goog.asserts', 'goog.dom.TagName', 'goog.events.Event', 'goog.string', 'goog.ui.Component']);
                +goog.addDependency("ui/serverchart_test.js", ['goog.ui.ServerChartTest'], ['goog.Uri', 'goog.events', 'goog.testing.jsunit', 'goog.ui.ServerChart']);
                +goog.addDependency("ui/slider.js", ['goog.ui.Slider', 'goog.ui.Slider.Orientation'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.ui.SliderBase']);
                +goog.addDependency("ui/sliderbase.js", ['goog.ui.SliderBase', 'goog.ui.SliderBase.AnimationFactory', 'goog.ui.SliderBase.Orientation'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.events.MouseWheelHandler', 'goog.functions', 'goog.fx.AnimationParallelQueue', 'goog.fx.Dragger', 'goog.fx.Transition', 'goog.fx.dom.ResizeHeight', 'goog.fx.dom.ResizeWidth', 'goog.fx.dom.Slide', 'goog.math', 'goog.math.Coordinate', 'goog.style', 'goog.style.bidi', 'goog.ui.Component', 'goog.ui.RangeModel']);
                +goog.addDependency("ui/sliderbase_test.js", ['goog.ui.SliderBaseTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.fx.Animation', 'goog.math.Coordinate', 'goog.style', 'goog.style.bidi', 'goog.testing.MockClock', 'goog.testing.MockControl', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.mockmatchers', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.SliderBase', 'goog.userAgent']);
                +goog.addDependency("ui/splitpane.js", ['goog.ui.SplitPane', 'goog.ui.SplitPane.Orientation'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.fx.Dragger', 'goog.math.Rect', 'goog.math.Size', 'goog.style', 'goog.ui.Component', 'goog.userAgent']);
                +goog.addDependency("ui/splitpane_test.js", ['goog.ui.SplitPaneTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.math.Size', 'goog.style', 'goog.testing.events', 'goog.testing.jsunit', 'goog.testing.recordFunction', 'goog.ui.Component', 'goog.ui.SplitPane']);
                +goog.addDependency("ui/style/app/buttonrenderer.js", ['goog.ui.style.app.ButtonRenderer'], ['goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.Button', 'goog.ui.CustomButtonRenderer', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.registry']);
                +goog.addDependency("ui/style/app/buttonrenderer_test.js", ['goog.ui.style.app.ButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.style.app.ButtonRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/style/app/menubuttonrenderer.js", ['goog.ui.style.app.MenuButtonRenderer'], ['goog.a11y.aria.Role', 'goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuRenderer', 'goog.ui.style.app.ButtonRenderer']);
                +goog.addDependency("ui/style/app/menubuttonrenderer_test.js", ['goog.ui.style.app.MenuButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Component', 'goog.ui.MenuButton', 'goog.ui.style.app.MenuButtonRenderer']);
                +goog.addDependency("ui/style/app/primaryactionbuttonrenderer.js", ['goog.ui.style.app.PrimaryActionButtonRenderer'], ['goog.ui.Button', 'goog.ui.registry', 'goog.ui.style.app.ButtonRenderer']);
                +goog.addDependency("ui/style/app/primaryactionbuttonrenderer_test.js", ['goog.ui.style.app.PrimaryActionButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.style', 'goog.ui.Button', 'goog.ui.Component', 'goog.ui.style.app.PrimaryActionButtonRenderer']);
                +goog.addDependency("ui/submenu.js", ['goog.ui.SubMenu'], ['goog.Timer', 'goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.KeyCodes', 'goog.positioning.AnchoredViewportPosition', 'goog.positioning.Corner', 'goog.style', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.SubMenuRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/submenu_test.js", ['goog.ui.SubMenuTest'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.functions', 'goog.positioning', 'goog.positioning.Overflow', 'goog.style', 'goog.testing.MockClock', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Menu', 'goog.ui.MenuItem', 'goog.ui.SubMenu', 'goog.ui.SubMenuRenderer']);
                +goog.addDependency("ui/submenurenderer.js", ['goog.ui.SubMenuRenderer'], ['goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.style', 'goog.ui.Menu', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/tab.js", ['goog.ui.Tab'], ['goog.ui.Component', 'goog.ui.Control', 'goog.ui.TabRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tab_test.js", ['goog.ui.TabTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Tab', 'goog.ui.TabRenderer']);
                +goog.addDependency("ui/tabbar.js", ['goog.ui.TabBar', 'goog.ui.TabBar.Location'], ['goog.ui.Component.EventType', 'goog.ui.Container', 'goog.ui.Container.Orientation', 'goog.ui.Tab', 'goog.ui.TabBarRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tabbar_test.js", ['goog.ui.TabBarTest'], ['goog.dom', 'goog.events', 'goog.events.Event', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.Container', 'goog.ui.Tab', 'goog.ui.TabBar', 'goog.ui.TabBarRenderer']);
                +goog.addDependency("ui/tabbarrenderer.js", ['goog.ui.TabBarRenderer'], ['goog.a11y.aria.Role', 'goog.object', 'goog.ui.ContainerRenderer']);
                +goog.addDependency("ui/tabbarrenderer_test.js", ['goog.ui.TabBarRendererTest'], ['goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Container', 'goog.ui.TabBar', 'goog.ui.TabBarRenderer']);
                +goog.addDependency("ui/tablesorter.js", ['goog.ui.TableSorter', 'goog.ui.TableSorter.EventType'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events.EventType', 'goog.functions', 'goog.ui.Component']);
                +goog.addDependency("ui/tablesorter_test.js", ['goog.ui.TableSorterTest'], ['goog.array', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.TableSorter']);
                +goog.addDependency("ui/tabpane.js", ['goog.ui.TabPane', 'goog.ui.TabPane.Events', 'goog.ui.TabPane.TabLocation', 'goog.ui.TabPane.TabPage', 'goog.ui.TabPaneEvent'], ['goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.Event', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.style']);
                +goog.addDependency("ui/tabpane_test.js", ['goog.ui.TabPaneTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.TabPane']);
                +goog.addDependency("ui/tabrenderer.js", ['goog.ui.TabRenderer'], ['goog.a11y.aria.Role', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/tabrenderer_test.js", ['goog.ui.TabRendererTest'], ['goog.a11y.aria.Role', 'goog.dom', 'goog.dom.classlist', 'goog.testing.dom', 'goog.testing.jsunit', 'goog.testing.ui.rendererasserts', 'goog.ui.Tab', 'goog.ui.TabRenderer']);
                +goog.addDependency("ui/textarea.js", ['goog.ui.Textarea', 'goog.ui.Textarea.EventType'], ['goog.asserts', 'goog.dom', 'goog.dom.classlist', 'goog.events.EventType', 'goog.style', 'goog.ui.Control', 'goog.ui.TextareaRenderer', 'goog.userAgent']);
                +goog.addDependency("ui/textarea_test.js", ['goog.ui.TextareaTest'], ['goog.dom', 'goog.dom.classlist', 'goog.events', 'goog.style', 'goog.testing.ExpectedFailures', 'goog.testing.events.EventObserver', 'goog.testing.jsunit', 'goog.ui.Textarea', 'goog.ui.TextareaRenderer', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("ui/textarearenderer.js", ['goog.ui.TextareaRenderer'], ['goog.dom.TagName', 'goog.ui.Component', 'goog.ui.ControlRenderer']);
                +goog.addDependency("ui/togglebutton.js", ['goog.ui.ToggleButton'], ['goog.ui.Button', 'goog.ui.Component', 'goog.ui.CustomButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbar.js", ['goog.ui.Toolbar'], ['goog.ui.Container', 'goog.ui.ToolbarRenderer']);
                +goog.addDependency("ui/toolbar_test.js", ['goog.ui.ToolbarTest'], ['goog.a11y.aria', 'goog.dom', 'goog.events.EventType', 'goog.testing.events', 'goog.testing.events.Event', 'goog.testing.jsunit', 'goog.ui.Toolbar', 'goog.ui.ToolbarMenuButton']);
                +goog.addDependency("ui/toolbarbutton.js", ['goog.ui.ToolbarButton'], ['goog.ui.Button', 'goog.ui.ToolbarButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarbuttonrenderer.js", ['goog.ui.ToolbarButtonRenderer'], ['goog.ui.CustomButtonRenderer']);
                +goog.addDependency("ui/toolbarcolormenubutton.js", ['goog.ui.ToolbarColorMenuButton'], ['goog.ui.ColorMenuButton', 'goog.ui.ToolbarColorMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarcolormenubuttonrenderer.js", ['goog.ui.ToolbarColorMenuButtonRenderer'], ['goog.asserts', 'goog.dom.classlist', 'goog.ui.ColorMenuButtonRenderer', 'goog.ui.MenuButtonRenderer', 'goog.ui.ToolbarMenuButtonRenderer']);
                +goog.addDependency("ui/toolbarcolormenubuttonrenderer_test.js", ['goog.ui.ToolbarColorMenuButtonRendererTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.testing.ui.RendererHarness', 'goog.testing.ui.rendererasserts', 'goog.ui.ToolbarColorMenuButton', 'goog.ui.ToolbarColorMenuButtonRenderer']);
                +goog.addDependency("ui/toolbarmenubutton.js", ['goog.ui.ToolbarMenuButton'], ['goog.ui.MenuButton', 'goog.ui.ToolbarMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarmenubuttonrenderer.js", ['goog.ui.ToolbarMenuButtonRenderer'], ['goog.ui.MenuButtonRenderer']);
                +goog.addDependency("ui/toolbarrenderer.js", ['goog.ui.ToolbarRenderer'], ['goog.a11y.aria.Role', 'goog.dom.TagName', 'goog.ui.Container', 'goog.ui.ContainerRenderer', 'goog.ui.Separator', 'goog.ui.ToolbarSeparatorRenderer']);
                +goog.addDependency("ui/toolbarselect.js", ['goog.ui.ToolbarSelect'], ['goog.ui.Select', 'goog.ui.ToolbarMenuButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarseparator.js", ['goog.ui.ToolbarSeparator'], ['goog.ui.Separator', 'goog.ui.ToolbarSeparatorRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/toolbarseparatorrenderer.js", ['goog.ui.ToolbarSeparatorRenderer'], ['goog.asserts', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.MenuSeparatorRenderer']);
                +goog.addDependency("ui/toolbarseparatorrenderer_test.js", ['goog.ui.ToolbarSeparatorRendererTest'], ['goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.INLINE_BLOCK_CLASSNAME', 'goog.ui.ToolbarSeparator', 'goog.ui.ToolbarSeparatorRenderer']);
                +goog.addDependency("ui/toolbartogglebutton.js", ['goog.ui.ToolbarToggleButton'], ['goog.ui.ToggleButton', 'goog.ui.ToolbarButtonRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tooltip.js", ['goog.ui.Tooltip', 'goog.ui.Tooltip.CursorTooltipPosition', 'goog.ui.Tooltip.ElementTooltipPosition', 'goog.ui.Tooltip.State'], ['goog.Timer', 'goog.array', 'goog.asserts', 'goog.dom', 'goog.dom.TagName', 'goog.dom.safe', 'goog.events', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.math.Box', 'goog.math.Coordinate', 'goog.positioning', 'goog.positioning.AnchoredPosition', 'goog.positioning.Corner', 'goog.positioning.Overflow', 'goog.positioning.OverflowStatus', 'goog.positioning.ViewportPosition', 'goog.structs.Set', 'goog.style', 'goog.ui.Popup', 'goog.ui.PopupBase']);
                +goog.addDependency("ui/tooltip_test.js", ['goog.ui.TooltipTest'], ['goog.dom', 'goog.dom.TagName', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.html.testing', 'goog.math.Coordinate', 'goog.positioning.AbsolutePosition', 'goog.style', 'goog.testing.MockClock', 'goog.testing.TestQueue', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.PopupBase', 'goog.ui.Tooltip', 'goog.userAgent']);
                +goog.addDependency("ui/tree/basenode.js", ['goog.ui.tree.BaseNode', 'goog.ui.tree.BaseNode.EventType'], ['goog.Timer', 'goog.a11y.aria', 'goog.a11y.aria.State', 'goog.asserts', 'goog.dom.safe', 'goog.events.Event', 'goog.events.KeyCodes', 'goog.html.SafeHtml', 'goog.html.SafeStyle', 'goog.string', 'goog.string.StringBuffer', 'goog.style', 'goog.ui.Component']);
                +goog.addDependency("ui/tree/basenode_test.js", ['goog.ui.tree.BaseNodeTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.html.testing', 'goog.testing.jsunit', 'goog.ui.Component', 'goog.ui.tree.BaseNode', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TreeNode']);
                +goog.addDependency("ui/tree/treecontrol.js", ['goog.ui.tree.TreeControl'], ['goog.a11y.aria', 'goog.asserts', 'goog.dom.classlist', 'goog.events.EventType', 'goog.events.FocusHandler', 'goog.events.KeyHandler', 'goog.html.SafeHtml', 'goog.log', 'goog.ui.tree.BaseNode', 'goog.ui.tree.TreeNode', 'goog.ui.tree.TypeAhead', 'goog.userAgent']);
                +goog.addDependency("ui/tree/treecontrol_test.js", ['goog.ui.tree.TreeControlTest'], ['goog.dom', 'goog.testing.jsunit', 'goog.ui.tree.TreeControl']);
                +goog.addDependency("ui/tree/treenode.js", ['goog.ui.tree.TreeNode'], ['goog.ui.tree.BaseNode']);
                +goog.addDependency("ui/tree/typeahead.js", ['goog.ui.tree.TypeAhead', 'goog.ui.tree.TypeAhead.Offset'], ['goog.array', 'goog.events.KeyCodes', 'goog.string', 'goog.structs.Trie']);
                +goog.addDependency("ui/tree/typeahead_test.js", ['goog.ui.tree.TypeAheadTest'], ['goog.dom', 'goog.events.KeyCodes', 'goog.testing.jsunit', 'goog.ui.tree.TreeControl', 'goog.ui.tree.TypeAhead']);
                +goog.addDependency("ui/tristatemenuitem.js", ['goog.ui.TriStateMenuItem', 'goog.ui.TriStateMenuItem.State'], ['goog.dom.classlist', 'goog.ui.Component', 'goog.ui.MenuItem', 'goog.ui.TriStateMenuItemRenderer', 'goog.ui.registry']);
                +goog.addDependency("ui/tristatemenuitemrenderer.js", ['goog.ui.TriStateMenuItemRenderer'], ['goog.asserts', 'goog.dom.classlist', 'goog.ui.MenuItemRenderer']);
                +goog.addDependency("ui/twothumbslider.js", ['goog.ui.TwoThumbSlider'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.dom', 'goog.dom.TagName', 'goog.ui.SliderBase']);
                +goog.addDependency("ui/twothumbslider_test.js", ['goog.ui.TwoThumbSliderTest'], ['goog.testing.jsunit', 'goog.ui.SliderBase', 'goog.ui.TwoThumbSlider']);
                +goog.addDependency("ui/zippy.js", ['goog.ui.Zippy', 'goog.ui.Zippy.Events', 'goog.ui.ZippyEvent'], ['goog.a11y.aria', 'goog.a11y.aria.Role', 'goog.a11y.aria.State', 'goog.dom', 'goog.dom.classlist', 'goog.events.Event', 'goog.events.EventHandler', 'goog.events.EventTarget', 'goog.events.EventType', 'goog.events.KeyCodes', 'goog.events.KeyHandler', 'goog.style']);
                +goog.addDependency("ui/zippy_test.js", ['goog.ui.ZippyTest'], ['goog.a11y.aria', 'goog.dom', 'goog.dom.TagName', 'goog.dom.classlist', 'goog.events', 'goog.events.KeyCodes', 'goog.object', 'goog.testing.events', 'goog.testing.jsunit', 'goog.ui.Zippy']);
                +goog.addDependency("uri/uri.js", ['goog.Uri', 'goog.Uri.QueryData'], ['goog.array', 'goog.asserts', 'goog.string', 'goog.structs', 'goog.structs.Map', 'goog.uri.utils', 'goog.uri.utils.ComponentIndex', 'goog.uri.utils.StandardQueryParam']);
                +goog.addDependency("uri/uri_test.js", ['goog.UriTest'], ['goog.Uri', 'goog.testing.jsunit']);
                +goog.addDependency("uri/utils.js", ['goog.uri.utils', 'goog.uri.utils.ComponentIndex', 'goog.uri.utils.QueryArray', 'goog.uri.utils.QueryValue', 'goog.uri.utils.StandardQueryParam'], ['goog.asserts', 'goog.string']);
                +goog.addDependency("uri/utils_test.js", ['goog.uri.utilsTest'], ['goog.functions', 'goog.string', 'goog.testing.jsunit', 'goog.uri.utils']);
                +goog.addDependency("useragent/adobereader.js", ['goog.userAgent.adobeReader'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/adobereader_test.js", ['goog.userAgent.adobeReaderTest'], ['goog.testing.jsunit', 'goog.userAgent.adobeReader']);
                +goog.addDependency("useragent/flash.js", ['goog.userAgent.flash'], ['goog.string']);
                +goog.addDependency("useragent/flash_test.js", ['goog.userAgent.flashTest'], ['goog.testing.jsunit', 'goog.userAgent.flash']);
                +goog.addDependency("useragent/iphoto.js", ['goog.userAgent.iphoto'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/jscript.js", ['goog.userAgent.jscript'], ['goog.string']);
                +goog.addDependency("useragent/jscript_test.js", ['goog.userAgent.jscriptTest'], ['goog.testing.jsunit', 'goog.userAgent.jscript']);
                +goog.addDependency("useragent/keyboard.js", ['goog.userAgent.keyboard'], ['goog.labs.userAgent.platform']);
                +goog.addDependency("useragent/keyboard_test.js", ['goog.userAgent.keyboardTest'], ['goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent.keyboard', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/platform.js", ['goog.userAgent.platform'], ['goog.string', 'goog.userAgent']);
                +goog.addDependency("useragent/platform_test.js", ['goog.userAgent.platformTest'], ['goog.testing.MockUserAgent', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.platform', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/product.js", ['goog.userAgent.product'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.platform', 'goog.userAgent']);
                +goog.addDependency("useragent/product_isversion.js", ['goog.userAgent.product.isVersion'], ['goog.labs.userAgent.platform', 'goog.string', 'goog.userAgent', 'goog.userAgent.product']);
                +goog.addDependency("useragent/product_test.js", ['goog.userAgent.productTest'], ['goog.array', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.MockUserAgent', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgent.product', 'goog.userAgent.product.isVersion', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/useragent.js", ['goog.userAgent'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.labs.userAgent.util', 'goog.reflect', 'goog.string']);
                +goog.addDependency("useragent/useragent_quirks_test.js", ['goog.userAgentQuirksTest'], ['goog.testing.jsunit', 'goog.userAgent']);
                +goog.addDependency("useragent/useragent_test.js", ['goog.userAgentTest'], ['goog.array', 'goog.labs.userAgent.platform', 'goog.labs.userAgent.testAgents', 'goog.labs.userAgent.util', 'goog.testing.PropertyReplacer', 'goog.testing.jsunit', 'goog.userAgent', 'goog.userAgentTestUtil']);
                +goog.addDependency("useragent/useragenttestutil.js", ['goog.userAgentTestUtil', 'goog.userAgentTestUtil.UserAgents'], ['goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.object', 'goog.userAgent', 'goog.userAgent.keyboard', 'goog.userAgent.platform', 'goog.userAgent.product', 'goog.userAgent.product.isVersion']);
                +goog.addDependency("vec/float32array.js", ['goog.vec.Float32Array'], []);
                +goog.addDependency("vec/float32array_test.js", ['goog.vec.Float32ArrayTest'], ['goog.vec.Float32Array', 'goog.testing.jsunit']);
                +goog.addDependency("vec/float64array.js", ['goog.vec.Float64Array'], []);
                +goog.addDependency("vec/float64array_test.js", ['goog.vec.Float64ArrayTest'], ['goog.vec.Float64Array', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3.js", ['goog.vec.Mat3'], ['goog.vec']);
                +goog.addDependency("vec/mat3_test.js", ['goog.vec.Mat3Test'], ['goog.vec.Mat3', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3d.js", ['goog.vec.mat3d', 'goog.vec.mat3d.Type'], ['goog.vec', 'goog.vec.vec3d.Type']);
                +goog.addDependency("vec/mat3d_test.js", ['goog.vec.mat3dTest'], ['goog.vec.mat3d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat3f.js", ['goog.vec.mat3f', 'goog.vec.mat3f.Type'], ['goog.vec', 'goog.vec.vec3f.Type']);
                +goog.addDependency("vec/mat3f_test.js", ['goog.vec.mat3fTest'], ['goog.vec.mat3f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4.js", ['goog.vec.Mat4'], ['goog.vec', 'goog.vec.Vec3', 'goog.vec.Vec4']);
                +goog.addDependency("vec/mat4_test.js", ['goog.vec.Mat4Test'], ['goog.vec.Mat4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4d.js", ['goog.vec.mat4d', 'goog.vec.mat4d.Type'], ['goog.vec', 'goog.vec.Quaternion', 'goog.vec.vec3d', 'goog.vec.vec4d']);
                +goog.addDependency("vec/mat4d_test.js", ['goog.vec.mat4dTest'], ['goog.vec.Quaternion', 'goog.vec.mat4d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/mat4f.js", ['goog.vec.mat4f', 'goog.vec.mat4f.Type'], ['goog.vec', 'goog.vec.Quaternion', 'goog.vec.vec3f', 'goog.vec.vec4f']);
                +goog.addDependency("vec/mat4f_test.js", ['goog.vec.mat4fTest'], ['goog.vec.Quaternion', 'goog.vec.mat4f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/quaternion.js", ['goog.vec.Quaternion', 'goog.vec.Quaternion.AnyType'], ['goog.vec', 'goog.vec.Vec3', 'goog.vec.Vec4']);
                +goog.addDependency("vec/quaternion_test.js", ['goog.vec.QuaternionTest'], ['goog.vec.Float32Array', 'goog.vec.Mat3', 'goog.vec.Mat4', 'goog.vec.Quaternion', 'goog.vec.Vec3', 'goog.vec.vec3f', 'goog.vec.Vec4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/ray.js", ['goog.vec.Ray'], ['goog.vec.Vec3']);
                +goog.addDependency("vec/ray_test.js", ['goog.vec.RayTest'], ['goog.vec.Float32Array', 'goog.vec.Ray', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec.js", ['goog.vec', 'goog.vec.AnyType', 'goog.vec.ArrayType', 'goog.vec.Float32', 'goog.vec.Float64', 'goog.vec.Number'], ['goog.vec.Float32Array', 'goog.vec.Float64Array']);
                +goog.addDependency("vec/vec2.js", ['goog.vec.Vec2'], ['goog.vec']);
                +goog.addDependency("vec/vec2_test.js", ['goog.vec.Vec2Test'], ['goog.vec.Float32Array', 'goog.vec.Vec2', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec2d.js", ['goog.vec.vec2d', 'goog.vec.vec2d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec2d_test.js", ['goog.vec.vec2dTest'], ['goog.vec.Float64Array', 'goog.vec.vec2d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec2f.js", ['goog.vec.vec2f', 'goog.vec.vec2f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec2f_test.js", ['goog.vec.vec2fTest'], ['goog.vec.Float32Array', 'goog.vec.vec2f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3.js", ['goog.vec.Vec3'], ['goog.vec']);
                +goog.addDependency("vec/vec3_test.js", ['goog.vec.Vec3Test'], ['goog.vec.Float32Array', 'goog.vec.Vec3', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3d.js", ['goog.vec.vec3d', 'goog.vec.vec3d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec3d_test.js", ['goog.vec.vec3dTest'], ['goog.vec.Float64Array', 'goog.vec.vec3d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec3f.js", ['goog.vec.vec3f', 'goog.vec.vec3f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec3f_test.js", ['goog.vec.vec3fTest'], ['goog.vec.Float32Array', 'goog.vec.vec3f', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4.js", ['goog.vec.Vec4'], ['goog.vec']);
                +goog.addDependency("vec/vec4_test.js", ['goog.vec.Vec4Test'], ['goog.vec.Float32Array', 'goog.vec.Vec4', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4d.js", ['goog.vec.vec4d', 'goog.vec.vec4d.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec4d_test.js", ['goog.vec.vec4dTest'], ['goog.vec.Float64Array', 'goog.vec.vec4d', 'goog.testing.jsunit']);
                +goog.addDependency("vec/vec4f.js", ['goog.vec.vec4f', 'goog.vec.vec4f.Type'], ['goog.vec']);
                +goog.addDependency("vec/vec4f_test.js", ['goog.vec.vec4fTest'], ['goog.vec.Float32Array', 'goog.vec.vec4f', 'goog.testing.jsunit']);
                +goog.addDependency("webgl/webgl.js", ['goog.webgl'], []);
                +goog.addDependency("window/window.js", ['goog.window'], ['goog.dom.TagName', 'goog.dom.safe', 'goog.html.SafeUrl', 'goog.html.uncheckedconversions', 'goog.labs.userAgent.platform', 'goog.string', 'goog.string.Const', 'goog.userAgent']);
                +goog.addDependency("window/window_test.js", ['goog.windowTest'], ['goog.Promise', 'goog.dom', 'goog.dom.TagName', 'goog.events', 'goog.functions', 'goog.html.SafeUrl', 'goog.labs.userAgent.browser', 'goog.labs.userAgent.engine', 'goog.labs.userAgent.platform', 'goog.string', 'goog.testing.PropertyReplacer', 'goog.testing.TestCase', 'goog.testing.jsunit', 'goog.window']);
                +
                +// Load Blockly.
                +goog.require('Blockly');
                +goog.require('Blockly.Block');
                +goog.require('Blockly.BlockDragSurfaceSvg');
                +goog.require('Blockly.BlockDragger');
                +goog.require('Blockly.BlockSvg');
                +goog.require('Blockly.BlockSvg.render');
                +goog.require('Blockly.Blocks');
                +goog.require('Blockly.Bubble');
                +goog.require('Blockly.Comment');
                +goog.require('Blockly.Connection');
                +goog.require('Blockly.ConnectionDB');
                +goog.require('Blockly.ContextMenu');
                +goog.require('Blockly.Css');
                +goog.require('Blockly.DraggedConnectionManager');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.Extensions');
                +goog.require('Blockly.Field');
                +goog.require('Blockly.FieldAngle');
                +goog.require('Blockly.FieldCheckbox');
                +goog.require('Blockly.FieldColour');
                +goog.require('Blockly.FieldDate');
                +goog.require('Blockly.FieldDropdown');
                +goog.require('Blockly.FieldImage');
                +goog.require('Blockly.FieldLabel');
                +goog.require('Blockly.FieldNumber');
                +goog.require('Blockly.FieldTextInput');
                +goog.require('Blockly.FieldVariable');
                +goog.require('Blockly.Flyout');
                +goog.require('Blockly.FlyoutButton');
                +goog.require('Blockly.FlyoutDragger');
                +goog.require('Blockly.Generator');
                +goog.require('Blockly.Gesture');
                +goog.require('Blockly.Grid');
                +goog.require('Blockly.HorizontalFlyout');
                +goog.require('Blockly.Icon');
                +goog.require('Blockly.Input');
                +goog.require('Blockly.Msg');
                +goog.require('Blockly.Mutator');
                +goog.require('Blockly.Names');
                +goog.require('Blockly.Options');
                +goog.require('Blockly.Procedures');
                +goog.require('Blockly.RenderedConnection');
                +goog.require('Blockly.Scrollbar');
                +goog.require('Blockly.ScrollbarPair');
                +goog.require('Blockly.Toolbox');
                +goog.require('Blockly.Tooltip');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.Trashcan');
                +goog.require('Blockly.VariableMap');
                +goog.require('Blockly.VariableModel');
                +goog.require('Blockly.Variables');
                +goog.require('Blockly.VerticalFlyout');
                +goog.require('Blockly.Warning');
                +goog.require('Blockly.WidgetDiv');
                +goog.require('Blockly.Workspace');
                +goog.require('Blockly.WorkspaceAudio');
                +goog.require('Blockly.WorkspaceDragSurfaceSvg');
                +goog.require('Blockly.WorkspaceDragger');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('Blockly.Xml');
                +goog.require('Blockly.ZoomControls');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.inject');
                +goog.require('Blockly.utils');
                +
                +delete this.BLOCKLY_DIR;
                +delete this.BLOCKLY_BOOT;
                +};
                +
                +if (isNodeJS) {
                +  window.BLOCKLY_BOOT();
                +  module.exports = Blockly;
                +} else {
                +  // Delete any existing Closure (e.g. Soy's nogoog_shim).
                +  document.write('<script>var goog = undefined;</script>');
                +  // Load fresh Closure Library.
                +  document.write('<script src="' + window.BLOCKLY_DIR +
                +      '/../closure-library/closure/goog/base.js"></script>');
                +  document.write('<script>window.BLOCKLY_BOOT();</script>');
                +}
                diff --git a/blockly/webif/static/blockly/blocks/colour.js b/blockly/webif/static/blockly/blocks/colour.js
                new file mode 100644
                index 000000000..99e5aacdc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/colour.js
                @@ -0,0 +1,135 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Colour blocks for Blockly.
                + *
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.colour');  // Deprecated
                +goog.provide('Blockly.Constants.Colour');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * This should be the same as Blockly.Msg.COLOUR_HUE.
                + * @readonly
                + */
                +Blockly.Constants.Colour.HUE = 20;
                +/** @deprecated Use Blockly.Constants.Colour.HUE */
                +Blockly.Blocks.colour.HUE = Blockly.Constants.Colour.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for colour picker.
                +  {
                +    "type": "colour_picker",
                +    "message0": "%1",
                +    "args0": [
                +      {
                +        "type": "field_colour",
                +        "name": "COLOUR",
                +        "colour": "#ff0000"
                +      }
                +    ],
                +    "output": "Colour",
                +    "colour": "%{BKY_COLOUR_HUE}",
                +    "helpUrl": "%{BKY_COLOUR_PICKER_HELPURL}",
                +    "tooltip": "%{BKY_COLOUR_PICKER_TOOLTIP}",
                +    "extensions": ["parent_tooltip_when_inline"]
                +  },
                +
                +  // Block for random colour.
                +  {
                +    "type": "colour_random",
                +    "message0": "%{BKY_COLOUR_RANDOM_TITLE}",
                +    "output": "Colour",
                +    "colour": "%{BKY_COLOUR_HUE}",
                +    "helpUrl": "%{BKY_COLOUR_RANDOM_HELPURL}",
                +    "tooltip": "%{BKY_COLOUR_RANDOM_TOOLTIP}"
                +  },
                +
                +  // Block for composing a colour from RGB components.
                +  {
                +    "type": "colour_rgb",
                +    "message0": "%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "RED",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "GREEN",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "BLUE",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      }
                +    ],
                +    "output": "Colour",
                +    "colour": "%{BKY_COLOUR_HUE}",
                +    "helpUrl": "%{BKY_COLOUR_RGB_HELPURL}",
                +    "tooltip": "%{BKY_COLOUR_RGB_TOOLTIP}"
                +  },
                +
                +  // Block for blending two colours together.
                +  {
                +    "type": "colour_blend",
                +    "message0": "%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "COLOUR1",
                +        "check": "Colour",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "COLOUR2",
                +        "check": "Colour",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "RATIO",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      }
                +    ],
                +    "output": "Colour",
                +    "colour": "%{BKY_COLOUR_HUE}",
                +    "helpUrl": "%{BKY_COLOUR_BLEND_HELPURL}",
                +    "tooltip": "%{BKY_COLOUR_BLEND_TOOLTIP}"
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                diff --git a/blockly/webif/static/blockly/blocks/lists.js b/blockly/webif/static/blockly/blocks/lists.js
                new file mode 100644
                index 000000000..3c7ef341d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/lists.js
                @@ -0,0 +1,846 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview List blocks for Blockly.
                + *
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.lists');  // Deprecated
                +goog.provide('Blockly.Constants.Lists');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * This should be the same as Blockly.Msg.LISTS_HUE.
                + * @readonly
                + */
                +Blockly.Constants.Lists.HUE = 260;
                +/** @deprecated Use Blockly.Constants.Lists.HUE */
                +Blockly.Blocks.lists.HUE = Blockly.Constants.Lists.HUE;
                +
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for creating an empty list
                +  // The 'list_create_with' block is preferred as it is more flexible.
                +  // <block type="lists_create_with">
                +  //   <mutation items="0"></mutation>
                +  // </block>
                +  {
                +    "type": "lists_create_empty",
                +    "message0": "%{BKY_LISTS_CREATE_EMPTY_TITLE}",
                +    "output": "Array",
                +    "colour": "%{BKY_LISTS_HUE}",
                +    "tooltip": "%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",
                +    "helpUrl": "%{BKY_LISTS_CREATE_EMPTY_HELPURL}"
                +  },
                +  // Block for creating a list with one element repeated.
                +  {
                +    "type": "lists_repeat",
                +    "message0": "%{BKY_LISTS_REPEAT_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "ITEM"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "NUM",
                +        "check": "Number"
                +      }
                +    ],
                +    "output": "Array",
                +    "colour": "%{BKY_LISTS_HUE}",
                +    "tooltip": "%{BKY_LISTS_REPEAT_TOOLTIP}",
                +    "helpUrl": "%{BKY_LISTS_REPEAT_HELPURL}"
                +  },
                +  // Block for reversing a list.
                +  {
                +    "type": "lists_reverse",
                +    "message0": "%{BKY_LISTS_REVERSE_MESSAGE0}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "LIST",
                +        "check": "Array"
                +      }
                +    ],
                +    "output": "Array",
                +    "inputsInline": true,
                +    "colour": "%{BKY_LISTS_HUE}",
                +    "tooltip": "%{BKY_LISTS_REVERSE_TOOLTIP}",
                +    "helpUrl": "%{BKY_LISTS_REVERSE_HELPURL}"
                +  },
                +  // Block for checking if a list is empty
                +  {
                +    "type": "lists_isEmpty",
                +    "message0": "%{BKY_LISTS_ISEMPTY_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": ["String", "Array"]
                +      }
                +    ],
                +    "output": "Boolean",
                +    "colour": "%{BKY_LISTS_HUE}",
                +    "tooltip": "%{BKY_LISTS_ISEMPTY_TOOLTIP}",
                +    "helpUrl": "%{BKY_LISTS_ISEMPTY_HELPURL}"
                +  },
                +  // Block for getting the list length
                +  {
                +    "type": "lists_length",
                +    "message0": "%{BKY_LISTS_LENGTH_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": ["String", "Array"]
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_LISTS_HUE}",
                +    "tooltip": "%{BKY_LISTS_LENGTH_TOOLTIP}",
                +    "helpUrl": "%{BKY_LISTS_LENGTH_HELPURL}"
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +Blockly.Blocks['lists_create_with'] = {
                +  /**
                +   * Block for creating a list with any number of elements of any type.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.itemCount_ = 3;
                +    this.updateShape_();
                +    this.setOutput(true, 'Array');
                +    this.setMutator(new Blockly.Mutator(['lists_create_with_item']));
                +    this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP);
                +  },
                +  /**
                +   * Create XML to represent list inputs.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('items', this.itemCount_);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the list inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
                +    this.updateShape_();
                +  },
                +  /**
                +   * Populate the mutator's dialog with this block's components.
                +   * @param {!Blockly.Workspace} workspace Mutator's workspace.
                +   * @return {!Blockly.Block} Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  decompose: function(workspace) {
                +    var containerBlock = workspace.newBlock('lists_create_with_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      var itemBlock = workspace.newBlock('lists_create_with_item');
                +      itemBlock.initSvg();
                +      connection.connect(itemBlock.previousConnection);
                +      connection = itemBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  /**
                +   * Reconfigure this block based on the mutator dialog's components.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  compose: function(containerBlock) {
                +    var itemBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    var connections = [];
                +    while (itemBlock) {
                +      connections.push(itemBlock.valueConnection_);
                +      itemBlock = itemBlock.nextConnection &&
                +          itemBlock.nextConnection.targetBlock();
                +    }
                +    // Disconnect any children that don't belong.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      var connection = this.getInput('ADD' + i).connection.targetConnection;
                +      if (connection && connections.indexOf(connection) == -1) {
                +        connection.disconnect();
                +      }
                +    }
                +    this.itemCount_ = connections.length;
                +    this.updateShape_();
                +    // Reconnect any child blocks.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i);
                +    }
                +  },
                +  /**
                +   * Store pointers to any connected child blocks.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  saveConnections: function(containerBlock) {
                +    var itemBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (itemBlock) {
                +      var input = this.getInput('ADD' + i);
                +      itemBlock.valueConnection_ = input && input.connection.targetConnection;
                +      i++;
                +      itemBlock = itemBlock.nextConnection &&
                +          itemBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  /**
                +   * Modify this block to have the correct number of inputs.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateShape_: function() {
                +    if (this.itemCount_ && this.getInput('EMPTY')) {
                +      this.removeInput('EMPTY');
                +    } else if (!this.itemCount_ && !this.getInput('EMPTY')) {
                +      this.appendDummyInput('EMPTY')
                +          .appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);
                +    }
                +    // Add new inputs.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      if (!this.getInput('ADD' + i)) {
                +        var input = this.appendValueInput('ADD' + i);
                +        if (i == 0) {
                +          input.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);
                +        }
                +      }
                +    }
                +    // Remove deleted inputs.
                +    while (this.getInput('ADD' + i)) {
                +      this.removeInput('ADD' + i);
                +      i++;
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['lists_create_with_container'] = {
                +  /**
                +   * Mutator block for list container.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);
                +    this.appendStatementInput('STACK');
                +    this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['lists_create_with_item'] = {
                +  /**
                +   * Mutator block for adding items.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['lists_indexOf'] = {
                +  /**
                +   * Block for finding an item in the list.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var OPERATORS =
                +        [[Blockly.Msg.LISTS_INDEX_OF_FIRST, 'FIRST'],
                +         [Blockly.Msg.LISTS_INDEX_OF_LAST, 'LAST']];
                +    this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.setOutput(true, 'Number');
                +    this.appendValueInput('VALUE')
                +        .setCheck('Array')
                +        .appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);
                +    this.appendValueInput('FIND')
                +        .appendField(new Blockly.FieldDropdown(OPERATORS), 'END');
                +    this.setInputsInline(true);
                +    // Assign 'this' to a variable for use in the tooltip closure below.
                +    var thisBlock = this;
                +    this.setTooltip(function() {
                +      return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace('%1',
                +          thisBlock.workspace.options.oneBasedIndex ? '0' : '-1');
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['lists_getIndex'] = {
                +  /**
                +   * Block for getting element at index.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var MODE =
                +        [[Blockly.Msg.LISTS_GET_INDEX_GET, 'GET'],
                +         [Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE, 'GET_REMOVE'],
                +         [Blockly.Msg.LISTS_GET_INDEX_REMOVE, 'REMOVE']];
                +    this.WHERE_OPTIONS =
                +        [[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
                +         [Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
                +         [Blockly.Msg.LISTS_GET_INDEX_FIRST, 'FIRST'],
                +         [Blockly.Msg.LISTS_GET_INDEX_LAST, 'LAST'],
                +         [Blockly.Msg.LISTS_GET_INDEX_RANDOM, 'RANDOM']];
                +    this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    var modeMenu = new Blockly.FieldDropdown(MODE, function(value) {
                +      var isStatement = (value == 'REMOVE');
                +      this.sourceBlock_.updateStatement_(isStatement);
                +    });
                +    this.appendValueInput('VALUE')
                +        .setCheck('Array')
                +        .appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);
                +    this.appendDummyInput()
                +        .appendField(modeMenu, 'MODE')
                +        .appendField('', 'SPACE');
                +    this.appendDummyInput('AT');
                +    if (Blockly.Msg.LISTS_GET_INDEX_TAIL) {
                +      this.appendDummyInput('TAIL')
                +          .appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);
                +    }
                +    this.setInputsInline(true);
                +    this.setOutput(true);
                +    this.updateAt_(true);
                +    // Assign 'this' to a variable for use in the tooltip closure below.
                +    var thisBlock = this;
                +    this.setTooltip(function() {
                +      var mode = thisBlock.getFieldValue('MODE');
                +      var where = thisBlock.getFieldValue('WHERE');
                +      var tooltip = '';
                +      switch (mode + ' ' + where) {
                +        case 'GET FROM_START':
                +        case 'GET FROM_END':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;
                +          break;
                +        case 'GET FIRST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;
                +          break;
                +        case 'GET LAST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;
                +          break;
                +        case 'GET RANDOM':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;
                +          break;
                +        case 'GET_REMOVE FROM_START':
                +        case 'GET_REMOVE FROM_END':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;
                +          break;
                +        case 'GET_REMOVE FIRST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;
                +          break;
                +        case 'GET_REMOVE LAST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;
                +          break;
                +        case 'GET_REMOVE RANDOM':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;
                +          break;
                +        case 'REMOVE FROM_START':
                +        case 'REMOVE FROM_END':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;
                +          break;
                +        case 'REMOVE FIRST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;
                +          break;
                +        case 'REMOVE LAST':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;
                +          break;
                +        case 'REMOVE RANDOM':
                +          tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM;
                +          break;
                +      }
                +      if (where == 'FROM_START' || where == 'FROM_END') {
                +        var msg = (where == 'FROM_START') ?
                +            Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP :
                +            Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP;
                +        tooltip += '  ' + msg.replace('%1',
                +                thisBlock.workspace.options.oneBasedIndex ? '#1' : '#0');
                +      }
                +      return tooltip;
                +    });
                +  },
                +  /**
                +   * Create XML to represent whether the block is a statement or a value.
                +   * Also represent whether there is an 'AT' input.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var isStatement = !this.outputConnection;
                +    container.setAttribute('statement', isStatement);
                +    var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at', isAt);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'AT' input.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    // Note: Until January 2013 this block did not have mutations,
                +    // so 'statement' defaults to false and 'at' defaults to true.
                +    var isStatement = (xmlElement.getAttribute('statement') == 'true');
                +    this.updateStatement_(isStatement);
                +    var isAt = (xmlElement.getAttribute('at') != 'false');
                +    this.updateAt_(isAt);
                +  },
                +  /**
                +   * Switch between a value block and a statement block.
                +   * @param {boolean} newStatement True if the block should be a statement.
                +   *     False if the block should be a value.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateStatement_: function(newStatement) {
                +    var oldStatement = !this.outputConnection;
                +    if (newStatement != oldStatement) {
                +      this.unplug(true, true);
                +      if (newStatement) {
                +        this.setOutput(false);
                +        this.setPreviousStatement(true);
                +        this.setNextStatement(true);
                +      } else {
                +        this.setPreviousStatement(false);
                +        this.setNextStatement(false);
                +        this.setOutput(true);
                +      }
                +    }
                +  },
                +  /**
                +   * Create or delete an input for the numeric index.
                +   * @param {boolean} isAt True if the input should exist.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateAt_: function(isAt) {
                +    // Destroy old 'AT' and 'ORDINAL' inputs.
                +    this.removeInput('AT');
                +    this.removeInput('ORDINAL', true);
                +    // Create either a value 'AT' input or a dummy input.
                +    if (isAt) {
                +      this.appendValueInput('AT').setCheck('Number');
                +      if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
                +        this.appendDummyInput('ORDINAL')
                +            .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
                +      }
                +    } else {
                +      this.appendDummyInput('AT');
                +    }
                +    var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
                +      var newAt = (value == 'FROM_START') || (value == 'FROM_END');
                +      // The 'isAt' variable is available due to this function being a closure.
                +      if (newAt != isAt) {
                +        var block = this.sourceBlock_;
                +        block.updateAt_(newAt);
                +        // This menu has been destroyed and replaced.  Update the replacement.
                +        block.setFieldValue(value, 'WHERE');
                +        return null;
                +      }
                +      return undefined;
                +    });
                +    this.getInput('AT').appendField(menu, 'WHERE');
                +    if (Blockly.Msg.LISTS_GET_INDEX_TAIL) {
                +      this.moveInputBefore('TAIL', null);
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['lists_setIndex'] = {
                +  /**
                +   * Block for setting the element at index.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var MODE =
                +        [[Blockly.Msg.LISTS_SET_INDEX_SET, 'SET'],
                +         [Blockly.Msg.LISTS_SET_INDEX_INSERT, 'INSERT']];
                +    this.WHERE_OPTIONS =
                +        [[Blockly.Msg.LISTS_GET_INDEX_FROM_START, 'FROM_START'],
                +         [Blockly.Msg.LISTS_GET_INDEX_FROM_END, 'FROM_END'],
                +         [Blockly.Msg.LISTS_GET_INDEX_FIRST, 'FIRST'],
                +         [Blockly.Msg.LISTS_GET_INDEX_LAST, 'LAST'],
                +         [Blockly.Msg.LISTS_GET_INDEX_RANDOM, 'RANDOM']];
                +    this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.appendValueInput('LIST')
                +        .setCheck('Array')
                +        .appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
                +    this.appendDummyInput()
                +        .appendField(new Blockly.FieldDropdown(MODE), 'MODE')
                +        .appendField('', 'SPACE');
                +    this.appendDummyInput('AT');
                +    this.appendValueInput('TO')
                +        .appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);
                +    this.updateAt_(true);
                +    // Assign 'this' to a variable for use in the tooltip closure below.
                +    var thisBlock = this;
                +    this.setTooltip(function() {
                +      var mode = thisBlock.getFieldValue('MODE');
                +      var where = thisBlock.getFieldValue('WHERE');
                +      var tooltip = '';
                +      switch (mode + ' ' + where) {
                +        case 'SET FROM_START':
                +        case 'SET FROM_END':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;
                +          break;
                +        case 'SET FIRST':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;
                +          break;
                +        case 'SET LAST':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;
                +          break;
                +        case 'SET RANDOM':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;
                +          break;
                +        case 'INSERT FROM_START':
                +        case 'INSERT FROM_END':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;
                +          break;
                +        case 'INSERT FIRST':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;
                +          break;
                +        case 'INSERT LAST':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
                +          break;
                +        case 'INSERT RANDOM':
                +          tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM;
                +          break;
                +      }
                +      if (where == 'FROM_START' || where == 'FROM_END') {
                +        tooltip += '  ' + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP
                +            .replace('%1',
                +                thisBlock.workspace.options.oneBasedIndex ? '#1' : '#0');
                +      }
                +      return tooltip;
                +    });
                +  },
                +  /**
                +   * Create XML to represent whether there is an 'AT' input.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at', isAt);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'AT' input.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    // Note: Until January 2013 this block did not have mutations,
                +    // so 'at' defaults to true.
                +    var isAt = (xmlElement.getAttribute('at') != 'false');
                +    this.updateAt_(isAt);
                +  },
                +  /**
                +   * Create or delete an input for the numeric index.
                +   * @param {boolean} isAt True if the input should exist.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateAt_: function(isAt) {
                +    // Destroy old 'AT' and 'ORDINAL' input.
                +    this.removeInput('AT');
                +    this.removeInput('ORDINAL', true);
                +    // Create either a value 'AT' input or a dummy input.
                +    if (isAt) {
                +      this.appendValueInput('AT').setCheck('Number');
                +      if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
                +        this.appendDummyInput('ORDINAL')
                +            .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
                +      }
                +    } else {
                +      this.appendDummyInput('AT');
                +    }
                +    var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
                +      var newAt = (value == 'FROM_START') || (value == 'FROM_END');
                +      // The 'isAt' variable is available due to this function being a closure.
                +      if (newAt != isAt) {
                +        var block = this.sourceBlock_;
                +        block.updateAt_(newAt);
                +        // This menu has been destroyed and replaced.  Update the replacement.
                +        block.setFieldValue(value, 'WHERE');
                +        return null;
                +      }
                +      return undefined;
                +    });
                +    this.moveInputBefore('AT', 'TO');
                +    if (this.getInput('ORDINAL')) {
                +      this.moveInputBefore('ORDINAL', 'TO');
                +    }
                +
                +    this.getInput('AT').appendField(menu, 'WHERE');
                +  }
                +};
                +
                +Blockly.Blocks['lists_getSublist'] = {
                +  /**
                +   * Block for getting sublist.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this['WHERE_OPTIONS_1'] =
                +        [[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START, 'FROM_START'],
                +         [Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END, 'FROM_END'],
                +         [Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST, 'FIRST']];
                +    this['WHERE_OPTIONS_2'] =
                +        [[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START, 'FROM_START'],
                +         [Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END, 'FROM_END'],
                +         [Blockly.Msg.LISTS_GET_SUBLIST_END_LAST, 'LAST']];
                +    this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.appendValueInput('LIST')
                +        .setCheck('Array')
                +        .appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);
                +    this.appendDummyInput('AT1');
                +    this.appendDummyInput('AT2');
                +    if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
                +      this.appendDummyInput('TAIL')
                +          .appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);
                +    }
                +    this.setInputsInline(true);
                +    this.setOutput(true, 'Array');
                +    this.updateAt_(1, true);
                +    this.updateAt_(2, true);
                +    this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP);
                +  },
                +  /**
                +   * Create XML to represent whether there are 'AT' inputs.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at1', isAt1);
                +    var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at2', isAt2);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'AT' inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    var isAt1 = (xmlElement.getAttribute('at1') == 'true');
                +    var isAt2 = (xmlElement.getAttribute('at2') == 'true');
                +    this.updateAt_(1, isAt1);
                +    this.updateAt_(2, isAt2);
                +  },
                +  /**
                +   * Create or delete an input for a numeric index.
                +   * This block has two such inputs, independant of each other.
                +   * @param {number} n Specify first or second input (1 or 2).
                +   * @param {boolean} isAt True if the input should exist.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateAt_: function(n, isAt) {
                +    // Create or delete an input for the numeric index.
                +    // Destroy old 'AT' and 'ORDINAL' inputs.
                +    this.removeInput('AT' + n);
                +    this.removeInput('ORDINAL' + n, true);
                +    // Create either a value 'AT' input or a dummy input.
                +    if (isAt) {
                +      this.appendValueInput('AT' + n).setCheck('Number');
                +      if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
                +        this.appendDummyInput('ORDINAL' + n)
                +            .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
                +      }
                +    } else {
                +      this.appendDummyInput('AT' + n);
                +    }
                +    var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
                +        function(value) {
                +          var newAt = (value == 'FROM_START') || (value == 'FROM_END');
                +          // The 'isAt' variable is available due to this function being a
                +          // closure.
                +          if (newAt != isAt) {
                +            var block = this.sourceBlock_;
                +            block.updateAt_(n, newAt);
                +            // This menu has been destroyed and replaced.
                +            // Update the replacement.
                +            block.setFieldValue(value, 'WHERE' + n);
                +            return null;
                +          }
                +          return undefined;
                +        });
                +    this.getInput('AT' + n)
                +        .appendField(menu, 'WHERE' + n);
                +    if (n == 1) {
                +      this.moveInputBefore('AT1', 'AT2');
                +      if (this.getInput('ORDINAL1')) {
                +        this.moveInputBefore('ORDINAL1', 'AT2');
                +      }
                +    }
                +    if (Blockly.Msg.LISTS_GET_SUBLIST_TAIL) {
                +      this.moveInputBefore('TAIL', null);
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['lists_sort'] = {
                +  /**
                +   * Block for sorting a list.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.jsonInit({
                +      "message0": Blockly.Msg.LISTS_SORT_TITLE,
                +      "args0": [
                +        {
                +          "type": "field_dropdown",
                +          "name": "TYPE",
                +          "options": [
                +            [Blockly.Msg.LISTS_SORT_TYPE_NUMERIC, "NUMERIC"],
                +            [Blockly.Msg.LISTS_SORT_TYPE_TEXT, "TEXT"],
                +            [Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE, "IGNORE_CASE"]
                +          ]
                +        },
                +        {
                +          "type": "field_dropdown",
                +          "name": "DIRECTION",
                +          "options": [
                +            [Blockly.Msg.LISTS_SORT_ORDER_ASCENDING, "1"],
                +            [Blockly.Msg.LISTS_SORT_ORDER_DESCENDING, "-1"]
                +          ]
                +        },
                +        {
                +          "type": "input_value",
                +          "name": "LIST",
                +          "check": "Array"
                +        }
                +      ],
                +      "output": "Array",
                +      "colour": Blockly.Blocks.lists.HUE,
                +      "tooltip": Blockly.Msg.LISTS_SORT_TOOLTIP,
                +      "helpUrl": Blockly.Msg.LISTS_SORT_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['lists_split'] = {
                +  /**
                +   * Block for splitting text into a list, or joining a list into text.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    // Assign 'this' to a variable for use in the closures below.
                +    var thisBlock = this;
                +    var dropdown = new Blockly.FieldDropdown(
                +        [[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT, 'SPLIT'],
                +         [Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST, 'JOIN']],
                +        function(newMode) {
                +          thisBlock.updateType_(newMode);
                +        });
                +    this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);
                +    this.setColour(Blockly.Blocks.lists.HUE);
                +    this.appendValueInput('INPUT')
                +        .setCheck('String')
                +        .appendField(dropdown, 'MODE');
                +    this.appendValueInput('DELIM')
                +        .setCheck('String')
                +        .appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);
                +    this.setInputsInline(true);
                +    this.setOutput(true, 'Array');
                +    this.setTooltip(function() {
                +      var mode = thisBlock.getFieldValue('MODE');
                +      if (mode == 'SPLIT') {
                +        return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;
                +      } else if (mode == 'JOIN') {
                +        return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;
                +      }
                +      throw 'Unknown mode: ' + mode;
                +    });
                +  },
                +  /**
                +   * Modify this block to have the correct input and output types.
                +   * @param {string} newMode Either 'SPLIT' or 'JOIN'.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateType_: function(newMode) {
                +    if (newMode == 'SPLIT') {
                +      this.outputConnection.setCheck('Array');
                +      this.getInput('INPUT').setCheck('String');
                +    } else {
                +      this.outputConnection.setCheck('String');
                +      this.getInput('INPUT').setCheck('Array');
                +    }
                +  },
                +  /**
                +   * Create XML to represent the input and output types.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('mode', this.getFieldValue('MODE'));
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the input and output types.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.updateType_(xmlElement.getAttribute('mode'));
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/blocks/logic.js b/blockly/webif/static/blockly/blocks/logic.js
                new file mode 100644
                index 000000000..f27c4e769
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/logic.js
                @@ -0,0 +1,621 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Logic blocks for Blockly.
                + *
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.logic');  // Deprecated
                +goog.provide('Blockly.Constants.Logic');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * Should be the same as Blockly.Msg.LOGIC_HUE.
                + * @readonly
                + */
                +Blockly.Constants.Logic.HUE = 210;
                +/** @deprecated Use Blockly.Constants.Logic.HUE */
                +Blockly.Blocks.logic.HUE = Blockly.Constants.Logic.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for boolean data type: true and false.
                +  {
                +    "type": "logic_boolean",
                +    "message0": "%1",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "BOOL",
                +        "options": [
                +          ["%{BKY_LOGIC_BOOLEAN_TRUE}", "TRUE"],
                +          ["%{BKY_LOGIC_BOOLEAN_FALSE}", "FALSE"]
                +        ]
                +      }
                +    ],
                +    "output": "Boolean",
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_LOGIC_BOOLEAN_TOOLTIP}",
                +    "helpUrl": "%{BKY_LOGIC_BOOLEAN_HELPURL}"
                +  },
                +  // Block for if/elseif/else condition.
                +  {
                +    "type": "controls_if",
                +    "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "IF0",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
                +    "args1": [
                +      {
                +        "type": "input_statement",
                +        "name": "DO0"
                +      }
                +    ],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
                +    "mutator": "controls_if_mutator",
                +    "extensions": ["controls_if_tooltip"]
                +  },
                +  // If/else block that does not use a mutator.
                +  {
                +    "type": "controls_ifelse",
                +    "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "IF0",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
                +    "args1": [
                +      {
                +        "type": "input_statement",
                +        "name": "DO0"
                +      }
                +    ],
                +    "message2": "%{BKY_CONTROLS_IF_MSG_ELSE} %1",
                +    "args2": [
                +      {
                +        "type": "input_statement",
                +        "name": "ELSE"
                +      }
                +    ],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKYCONTROLS_IF_TOOLTIP_2}",
                +    "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
                +    "extensions": ["controls_if_tooltip"]
                +  },
                +  // Block for comparison operator.
                +  {
                +    "type": "logic_compare",
                +    "message0": "%1 %2 %3",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "A"
                +      },
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["=", "EQ"],
                +          ["\u2260", "NEQ"],
                +          ["<", "LT"],
                +          ["\u2264", "LTE"],
                +          [">", "GT"],
                +          ["\u2265", "GTE"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "B"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Boolean",
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "helpUrl": "%{BKY_LOGIC_COMPARE_HELPURL}",
                +    "extensions": ["logic_compare", "logic_op_tooltip"]
                +  },
                +  // Block for logical operations: 'and', 'or'.
                +  {
                +    "type": "logic_operation",
                +    "message0": "%1 %2 %3",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "A",
                +        "check": "Boolean"
                +      },
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_LOGIC_OPERATION_AND}", "AND"],
                +          ["%{BKY_LOGIC_OPERATION_OR}", "OR"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "B",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Boolean",
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "helpUrl": "%{BKY_LOGIC_OPERATION_HELPURL}",
                +    "extensions": ["logic_op_tooltip"]
                +  },
                +  // Block for negation.
                +  {
                +    "type": "logic_negate",
                +    "message0": "%{BKY_LOGIC_NEGATE_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "BOOL",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "output": "Boolean",
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_LOGIC_NEGATE_TOOLTIP}",
                +    "helpUrl": "%{BKY_LOGIC_NEGATE_HELPURL}"
                +  },
                +  // Block for null data type.
                +  {
                +    "type": "logic_null",
                +    "message0": "%{BKY_LOGIC_NULL}",
                +    "output": null,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_LOGIC_NULL_TOOLTIP}",
                +    "helpUrl": "%{BKY_LOGIC_NULL_HELPURL}"
                +  },
                +  // Block for ternary operator.
                +  {
                +    "type": "logic_ternary",
                +    "message0": "%{BKY_LOGIC_TERNARY_CONDITION} %1",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "IF",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "message1": "%{BKY_LOGIC_TERNARY_IF_TRUE} %1",
                +    "args1": [
                +      {
                +        "type": "input_value",
                +        "name": "THEN"
                +      }
                +    ],
                +    "message2": "%{BKY_LOGIC_TERNARY_IF_FALSE} %1",
                +    "args2": [
                +      {
                +        "type": "input_value",
                +        "name": "ELSE"
                +      }
                +    ],
                +    "output": null,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_LOGIC_TERNARY_TOOLTIP}",
                +    "helpUrl": "%{BKY_LOGIC_TERNARY_HELPURL}",
                +    "extensions": ["logic_ternary"]
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +Blockly.defineBlocksWithJsonArray([ // Mutator blocks. Do not extract.
                +  // Block representing the if statement in the controls_if mutator.
                +  {
                +    "type": "controls_if_if",
                +    "message0": "%{BKY_CONTROLS_IF_IF_TITLE_IF}",
                +    "nextStatement": null,
                +    "enableContextMenu": false,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_CONTROLS_IF_IF_TOOLTIP}"
                +  },
                +  // Block representing the else-if statement in the controls_if mutator.
                +  {
                +    "type": "controls_if_elseif",
                +    "message0": "%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "enableContextMenu": false,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"
                +  },
                +  // Block representing the else statement in the controls_if mutator.
                +  {
                +    "type": "controls_if_else",
                +    "message0": "%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",
                +    "previousStatement": null,
                +    "enableContextMenu": false,
                +    "colour": "%{BKY_LOGIC_HUE}",
                +    "tooltip": "%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"
                +  }
                +]);
                +
                +/**
                + * Tooltip text, keyed by block OP value. Used by logic_compare and
                + * logic_operation blocks.
                + * @see {Blockly.Extensions#buildTooltipForDropdown}
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Logic.TOOLTIPS_BY_OP = {
                +  // logic_compare
                +  'EQ': '%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}',
                +  'NEQ': '%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}',
                +  'LT': '%{BKY_LOGIC_COMPARE_TOOLTIP_LT}',
                +  'LTE': '%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}',
                +  'GT': '%{BKY_LOGIC_COMPARE_TOOLTIP_GT}',
                +  'GTE': '%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}',
                +
                +  // logic_operation
                +  'AND': '%{BKY_LOGIC_OPERATION_TOOLTIP_AND}',
                +  'OR': '%{BKY_LOGIC_OPERATION_TOOLTIP_OR}'
                +};
                +
                +Blockly.Extensions.register('logic_op_tooltip',
                +  Blockly.Extensions.buildTooltipForDropdown(
                +    'OP', Blockly.Constants.Logic.TOOLTIPS_BY_OP));
                +
                +/**
                + * Mutator methods added to controls_if blocks.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
                +  elseifCount_: 0,
                +  elseCount_: 0,
                +
                +  /**
                +   * Create XML to represent the number of else-if and else inputs.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    if (!this.elseifCount_ && !this.elseCount_) {
                +      return null;
                +    }
                +    var container = document.createElement('mutation');
                +    if (this.elseifCount_) {
                +      container.setAttribute('elseif', this.elseifCount_);
                +    }
                +    if (this.elseCount_) {
                +      container.setAttribute('else', 1);
                +    }
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the else-if and else inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.elseifCount_ = parseInt(xmlElement.getAttribute('elseif'), 10) || 0;
                +    this.elseCount_ = parseInt(xmlElement.getAttribute('else'), 10) || 0;
                +    this.updateShape_();
                +  },
                +  /**
                +   * Populate the mutator's dialog with this block's components.
                +   * @param {!Blockly.Workspace} workspace Mutator's workspace.
                +   * @return {!Blockly.Block} Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  decompose: function(workspace) {
                +    var containerBlock = workspace.newBlock('controls_if_if');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.nextConnection;
                +    for (var i = 1; i <= this.elseifCount_; i++) {
                +      var elseifBlock = workspace.newBlock('controls_if_elseif');
                +      elseifBlock.initSvg();
                +      connection.connect(elseifBlock.previousConnection);
                +      connection = elseifBlock.nextConnection;
                +    }
                +    if (this.elseCount_) {
                +      var elseBlock = workspace.newBlock('controls_if_else');
                +      elseBlock.initSvg();
                +      connection.connect(elseBlock.previousConnection);
                +    }
                +    return containerBlock;
                +  },
                +  /**
                +   * Reconfigure this block based on the mutator dialog's components.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  compose: function(containerBlock) {
                +    var clauseBlock = containerBlock.nextConnection.targetBlock();
                +    // Count number of inputs.
                +    this.elseifCount_ = 0;
                +    this.elseCount_ = 0;
                +    var valueConnections = [null];
                +    var statementConnections = [null];
                +    var elseStatementConnection = null;
                +    while (clauseBlock) {
                +      switch (clauseBlock.type) {
                +        case 'controls_if_elseif':
                +          this.elseifCount_++;
                +          valueConnections.push(clauseBlock.valueConnection_);
                +          statementConnections.push(clauseBlock.statementConnection_);
                +          break;
                +        case 'controls_if_else':
                +          this.elseCount_++;
                +          elseStatementConnection = clauseBlock.statementConnection_;
                +          break;
                +        default:
                +          throw 'Unknown block type.';
                +      }
                +      clauseBlock = clauseBlock.nextConnection &&
                +          clauseBlock.nextConnection.targetBlock();
                +    }
                +    this.updateShape_();
                +    // Reconnect any child blocks.
                +    for (var i = 1; i <= this.elseifCount_; i++) {
                +      Blockly.Mutator.reconnect(valueConnections[i], this, 'IF' + i);
                +      Blockly.Mutator.reconnect(statementConnections[i], this, 'DO' + i);
                +    }
                +    Blockly.Mutator.reconnect(elseStatementConnection, this, 'ELSE');
                +  },
                +  /**
                +   * Store pointers to any connected child blocks.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  saveConnections: function(containerBlock) {
                +    var clauseBlock = containerBlock.nextConnection.targetBlock();
                +    var i = 1;
                +    while (clauseBlock) {
                +      switch (clauseBlock.type) {
                +        case 'controls_if_elseif':
                +          var inputIf = this.getInput('IF' + i);
                +          var inputDo = this.getInput('DO' + i);
                +          clauseBlock.valueConnection_ =
                +              inputIf && inputIf.connection.targetConnection;
                +          clauseBlock.statementConnection_ =
                +              inputDo && inputDo.connection.targetConnection;
                +          i++;
                +          break;
                +        case 'controls_if_else':
                +          var inputDo = this.getInput('ELSE');
                +          clauseBlock.statementConnection_ =
                +              inputDo && inputDo.connection.targetConnection;
                +          break;
                +        default:
                +          throw 'Unknown block type.';
                +      }
                +      clauseBlock = clauseBlock.nextConnection &&
                +          clauseBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  /**
                +   * Modify this block to have the correct number of inputs.
                +   * @this Blockly.Block
                +   * @private
                +   */
                +  updateShape_: function() {
                +    // Delete everything.
                +    if (this.getInput('ELSE')) {
                +      this.removeInput('ELSE');
                +    }
                +    var i = 1;
                +    while (this.getInput('IF' + i)) {
                +      this.removeInput('IF' + i);
                +      this.removeInput('DO' + i);
                +      i++;
                +    }
                +    // Rebuild block.
                +    for (var i = 1; i <= this.elseifCount_; i++) {
                +      this.appendValueInput('IF' + i)
                +          .setCheck('Boolean')
                +          .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF);
                +      this.appendStatementInput('DO' + i)
                +          .appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
                +    }
                +    if (this.elseCount_) {
                +      this.appendStatementInput('ELSE')
                +          .appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);
                +    }
                +  }
                +};
                +
                +Blockly.Extensions.registerMutator('controls_if_mutator',
                +    Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN, null,
                +    ['controls_if_elseif', 'controls_if_else']);
                +/**
                + * "controls_if" extension function. Adds mutator, shape updating methods, and
                + * dynamic tooltip to "controls_if" blocks.
                + * @this Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION = function() {
                +
                +  this.setTooltip(function() {
                +    if (!this.elseifCount_ && !this.elseCount_) {
                +      return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;
                +    } else if (!this.elseifCount_ && this.elseCount_) {
                +      return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;
                +    } else if (this.elseifCount_ && !this.elseCount_) {
                +      return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;
                +    } else if (this.elseifCount_ && this.elseCount_) {
                +      return Blockly.Msg.CONTROLS_IF_TOOLTIP_4;
                +    }
                +    return '';
                +  }.bind(this));
                +};
                +
                +Blockly.Extensions.register('controls_if_tooltip',
                +  Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
                +
                +/**
                + * Corrects the logic_compare dropdown label with respect to language direction.
                + * @this Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Logic.fixLogicCompareRtlOpLabels =
                +  function() {
                +    var rtlOpLabels = {
                +      'LT': '\u200F<\u200F',
                +      'LTE': '\u200F\u2264\u200F',
                +      'GT': '\u200F>\u200F',
                +      'GTE': '\u200F\u2265\u200F'
                +    };
                +    var opDropdown = this.getField('OP');
                +    if (opDropdown) {
                +      var options = opDropdown.getOptions();
                +      for (var i = 0; i < options.length; ++i) {
                +        var tuple = options[i];
                +        var op = tuple[1];
                +        var rtlLabel = rtlOpLabels[op];
                +        if (goog.isString(tuple[0]) && rtlLabel) {
                +          // Replace LTR text label
                +          tuple[0] = rtlLabel;
                +        }
                +      }
                +    }
                +  };
                +
                +/**
                + * Adds dynamic type validation for the left and right sides of a logic_compare block.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN = {
                +  prevBlocks_: [null, null],
                +
                +  /**
                +   * Called whenever anything on the workspace changes.
                +   * Prevent mismatched types from being compared.
                +   * @param {!Blockly.Events.Abstract} e Change event.
                +   * @this Blockly.Block
                +   */
                +  onchange: function(e) {
                +    var blockA = this.getInputTargetBlock('A');
                +    var blockB = this.getInputTargetBlock('B');
                +    // Disconnect blocks that existed prior to this change if they don't match.
                +    if (blockA && blockB &&
                +        !blockA.outputConnection.checkType_(blockB.outputConnection)) {
                +      // Mismatch between two inputs.  Disconnect previous and bump it away.
                +      // Ensure that any disconnections are grouped with the causing event.
                +      Blockly.Events.setGroup(e.group);
                +      for (var i = 0; i < this.prevBlocks_.length; i++) {
                +        var block = this.prevBlocks_[i];
                +        if (block === blockA || block === blockB) {
                +          block.unplug();
                +          block.bumpNeighbours_();
                +        }
                +      }
                +      Blockly.Events.setGroup(false);
                +    }
                +    this.prevBlocks_[0] = blockA;
                +    this.prevBlocks_[1] = blockB;
                +  }
                +};
                +
                +/**
                + * "logic_compare" extension function. Corrects direction of operators in the
                + * dropdown labels, and adds type left and right side type checking to
                + * "logic_compare" blocks.
                + * @this Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION = function() {
                +  // Fix operator labels in RTL
                +  if (this.RTL) {
                +    Blockly.Constants.Logic.fixLogicCompareRtlOpLabels.apply(this);
                +  }
                +
                +  // Add onchange handler to ensure types are compatable.
                +  this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN);
                +};
                +
                +Blockly.Extensions.register('logic_compare',
                +  Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
                +
                +/**
                + * Adds type coordination between inputs and output.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN = {
                +  prevParentConnection_: null,
                +
                +  /**
                +   * Called whenever anything on the workspace changes.
                +   * Prevent mismatched types.
                +   * @param {!Blockly.Events.Abstract} e Change event.
                +   * @this Blockly.Block
                +   */
                +  onchange: function(e) {
                +    var blockA = this.getInputTargetBlock('THEN');
                +    var blockB = this.getInputTargetBlock('ELSE');
                +    var parentConnection = this.outputConnection.targetConnection;
                +    // Disconnect blocks that existed prior to this change if they don't match.
                +    if ((blockA || blockB) && parentConnection) {
                +      for (var i = 0; i < 2; i++) {
                +        var block = (i == 1) ? blockA : blockB;
                +        if (block && !block.outputConnection.checkType_(parentConnection)) {
                +          // Ensure that any disconnections are grouped with the causing event.
                +          Blockly.Events.setGroup(e.group);
                +          if (parentConnection === this.prevParentConnection_) {
                +            this.unplug();
                +            parentConnection.getSourceBlock().bumpNeighbours_();
                +          } else {
                +            block.unplug();
                +            block.bumpNeighbours_();
                +          }
                +          Blockly.Events.setGroup(false);
                +        }
                +      }
                +    }
                +    this.prevParentConnection_ = parentConnection;
                +  }
                +};
                +
                +Blockly.Extensions.registerMixin('logic_ternary',
                +  Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);
                diff --git a/blockly/webif/static/blockly/blocks/loops.js b/blockly/webif/static/blockly/blocks/loops.js
                new file mode 100644
                index 000000000..f0d2a98b9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/loops.js
                @@ -0,0 +1,341 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Loop blocks for Blockly.
                + *
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.loops');  // Deprecated
                +goog.provide('Blockly.Constants.Loops');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * Should be the same as Blockly.Msg.LOOPS_HUE
                + * @readonly
                + */
                +Blockly.Constants.Loops.HUE = 120;
                +/** @deprecated Use Blockly.Constants.Loops.HUE */
                +Blockly.Blocks.loops.HUE = Blockly.Constants.Loops.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for repeat n times (external number).
                +  {
                +    "type": "controls_repeat_ext",
                +    "message0": "%{BKY_CONTROLS_REPEAT_TITLE}",
                +    "args0": [{
                +      "type": "input_value",
                +      "name": "TIMES",
                +      "check": "Number"
                +    }],
                +    "message1": "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +    "args1": [{
                +      "type": "input_statement",
                +      "name": "DO"
                +    }],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "tooltip": "%{BKY_CONTROLS_REPEAT_TOOLTIP}",
                +    "helpUrl": "%{BKY_CONTROLS_REPEAT_HELPURL}"
                +  },
                +  // Block for repeat n times (internal number).
                +  // The 'controls_repeat_ext' block is preferred as it is more flexible.
                +  {
                +    "type": "controls_repeat",
                +    "message0": "%{BKY_CONTROLS_REPEAT_TITLE}",
                +    "args0": [{
                +      "type": "field_number",
                +      "name": "TIMES",
                +      "value": 10,
                +      "min": 0,
                +      "precision": 1
                +    }],
                +    "message1": "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +    "args1": [{
                +      "type": "input_statement",
                +      "name": "DO"
                +    }],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "tooltip": "%{BKY_CONTROLS_REPEAT_TOOLTIP}",
                +    "helpUrl": "%{BKY_CONTROLS_REPEAT_HELPURL}"
                +  },
                +  // Block for 'do while/until' loop.
                +  {
                +    "type": "controls_whileUntil",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "MODE",
                +        "options": [
                +          ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}", "WHILE"],
                +          ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}", "UNTIL"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "BOOL",
                +        "check": "Boolean"
                +      }
                +    ],
                +    "message1": "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +    "args1": [{
                +      "type": "input_statement",
                +      "name": "DO"
                +    }],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "helpUrl": "%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",
                +    "extensions": ["controls_whileUntil_tooltip"]
                +  },
                +  // Block for 'for' loop.
                +  {
                +    "type": "controls_for",
                +    "message0": "%{BKY_CONTROLS_FOR_TITLE}",
                +    "args0": [
                +      {
                +        "type": "field_variable",
                +        "name": "VAR",
                +        "variable": null
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "FROM",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "TO",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "BY",
                +        "check": "Number",
                +        "align": "RIGHT"
                +      }
                +    ],
                +    "message1": "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +    "args1": [{
                +      "type": "input_statement",
                +      "name": "DO"
                +    }],
                +    "inputsInline": true,
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "helpUrl": "%{BKY_CONTROLS_FOR_HELPURL}",
                +    "extensions": [
                +      "contextMenu_newGetVariableBlock",
                +      "controls_for_tooltip"
                +    ]
                +  },
                +  // Block for 'for each' loop.
                +  {
                +    "type": "controls_forEach",
                +    "message0": "%{BKY_CONTROLS_FOREACH_TITLE}",
                +    "args0": [
                +      {
                +        "type": "field_variable",
                +        "name": "VAR",
                +        "variable": null
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "LIST",
                +        "check": "Array"
                +      }
                +    ],
                +    "message1": "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +    "args1": [{
                +      "type": "input_statement",
                +      "name": "DO"
                +    }],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "helpUrl": "%{BKY_CONTROLS_FOREACH_HELPURL}",
                +    "extensions": [
                +      "contextMenu_newGetVariableBlock",
                +      "controls_forEach_tooltip"
                +    ]
                +  },
                +  // Block for flow statements: continue, break.
                +  {
                +    "type": "controls_flow_statements",
                +    "message0": "%1",
                +    "args0": [{
                +      "type": "field_dropdown",
                +      "name": "FLOW",
                +      "options": [
                +        ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}", "BREAK"],
                +        ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}", "CONTINUE"]
                +      ]
                +    }],
                +    "previousStatement": null,
                +    "colour": "%{BKY_LOOPS_HUE}",
                +    "helpUrl": "%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",
                +    "extensions": [
                +      "controls_flow_tooltip",
                +      "controls_flow_in_loop_check"
                +    ]
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +/**
                + * Tooltips for the 'controls_whileUntil' block, keyed by MODE value.
                + * @see {Blockly.Extensions#buildTooltipForDropdown}
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS = {
                +  'WHILE': '%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}',
                +  'UNTIL': '%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}'
                +};
                +
                +Blockly.Extensions.register('controls_whileUntil_tooltip',
                +  Blockly.Extensions.buildTooltipForDropdown(
                +    'MODE', Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
                +
                +/**
                + * Tooltips for the 'controls_flow_statements' block, keyed by FLOW value.
                + * @see {Blockly.Extensions#buildTooltipForDropdown}
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS = {
                +  'BREAK': '%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}',
                +  'CONTINUE': '%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}'
                +};
                +
                +Blockly.Extensions.register('controls_flow_tooltip',
                +  Blockly.Extensions.buildTooltipForDropdown(
                +    'FLOW', Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
                +
                +/**
                + * Mixin to add a context menu item to create a 'variables_get' block.
                + * Used by blocks 'controls_for' and 'controls_forEach'.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
                +  /**
                +   * Add context menu option to create getter block for the loop's variable.
                +   * (customContextMenu support limited to web BlockSvg.)
                +   * @param {!Array} options List of menu options to add to.
                +   * @this Blockly.Block
                +   */
                +  customContextMenu: function(options) {
                +    var varName = this.getFieldValue('VAR');
                +    if (!this.isCollapsed() && varName != null) {
                +      var option = {enabled: true};
                +      option.text =
                +        Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', varName);
                +      var xmlField = goog.dom.createDom('field', null, varName);
                +      xmlField.setAttribute('name', 'VAR');
                +      var xmlBlock = goog.dom.createDom('block', null, xmlField);
                +      xmlBlock.setAttribute('type', 'variables_get');
                +      option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
                +      options.push(option);
                +    }
                +  }
                +};
                +
                +Blockly.Extensions.registerMixin('contextMenu_newGetVariableBlock',
                +  Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);
                +
                +Blockly.Extensions.register('controls_for_tooltip',
                +  Blockly.Extensions.buildTooltipWithFieldValue(
                +    Blockly.Msg.CONTROLS_FOR_TOOLTIP, 'VAR'));
                +
                +Blockly.Extensions.register('controls_forEach_tooltip',
                +  Blockly.Extensions.buildTooltipWithFieldValue(
                +    Blockly.Msg.CONTROLS_FOREACH_TOOLTIP, 'VAR'));
                +
                +/**
                + * This mixin adds a check to make sure the 'controls_flow_statements' block
                + * is contained in a loop. Otherwise a warning is added to the block.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Loops.CONTROL_FLOW_CHECK_IN_LOOP_MIXIN = {
                +  /**
                +   * List of block types that are loops and thus do not need warnings.
                +   * To add a new loop type add this to your code:
                +   * Blockly.Blocks['controls_flow_statements'].LOOP_TYPES.push('custom_loop');
                +   */
                +  LOOP_TYPES: ['controls_repeat', 'controls_repeat_ext', 'controls_forEach',
                +    'controls_for', 'controls_whileUntil'],
                +
                +  /**
                +   * Called whenever anything on the workspace changes.
                +   * Add warning if this flow block is not nested inside a loop.
                +   * @param {!Blockly.Events.Abstract} e Change event.
                +   * @this Blockly.Block
                +   */
                +  onchange: function(/* e */) {
                +    if (!this.workspace.isDragging || this.workspace.isDragging()) {
                +      return;  // Don't change state at the start of a drag.
                +    }
                +    var legal = false;
                +    // Is the block nested in a loop?
                +    var block = this;
                +    do {
                +      if (this.LOOP_TYPES.indexOf(block.type) != -1) {
                +        legal = true;
                +        break;
                +      }
                +      block = block.getSurroundParent();
                +    } while (block);
                +    if (legal) {
                +      this.setWarningText(null);
                +      if (!this.isInFlyout) {
                +        this.setDisabled(false);
                +      }
                +    } else {
                +      this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
                +      if (!this.isInFlyout && !this.getInheritedDisabled()) {
                +        this.setDisabled(true);
                +      }
                +    }
                +  }
                +};
                +
                +Blockly.Extensions.registerMixin('controls_flow_in_loop_check',
                +  Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);
                diff --git a/blockly/webif/static/blockly/blocks/math.js b/blockly/webif/static/blockly/blocks/math.js
                new file mode 100644
                index 000000000..0aff2ab3d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/math.js
                @@ -0,0 +1,566 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Math blocks for Blockly.
                + *
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.math');  // Deprecated
                +goog.provide('Blockly.Constants.Math');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * Should be the same as Blockly.Msg.MATH_HUE
                + * @readonly
                + */
                +Blockly.Constants.Math.HUE = 230;
                +/** @deprecated Use Blockly.Constants.Math.HUE */
                +Blockly.Blocks.math.HUE = Blockly.Constants.Math.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for numeric value.
                +  {
                +    "type": "math_number",
                +    "message0": "%1",
                +    "args0": [{
                +      "type": "field_number",
                +      "name": "NUM",
                +      "value": 0
                +    }],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_NUMBER_HELPURL}",
                +    "tooltip": "%{BKY_MATH_NUMBER_TOOLTIP}",
                +    "extensions": ["parent_tooltip_when_inline"]
                +  },
                +
                +  // Block for basic arithmetic operator.
                +  {
                +    "type": "math_arithmetic",
                +    "message0": "%1 %2 %3",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "A",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_MATH_ADDITION_SYMBOL}", "ADD"],
                +          ["%{BKY_MATH_SUBTRACTION_SYMBOL}", "MINUS"],
                +          ["%{BKY_MATH_MULTIPLICATION_SYMBOL}", "MULTIPLY"],
                +          ["%{BKY_MATH_DIVISION_SYMBOL}", "DIVIDE"],
                +          ["%{BKY_MATH_POWER_SYMBOL}", "POWER"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "B",
                +        "check": "Number"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_ARITHMETIC_HELPURL}",
                +    "extensions": ["math_op_tooltip"]
                +  },
                +
                +  // Block for advanced math operators with single operand.
                +  {
                +    "type": "math_single",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_MATH_SINGLE_OP_ROOT}", 'ROOT'],
                +          ["%{BKY_MATH_SINGLE_OP_ABSOLUTE}", 'ABS'],
                +          ['-', 'NEG'],
                +          ['ln', 'LN'],
                +          ['log10', 'LOG10'],
                +          ['e^', 'EXP'],
                +          ['10^', 'POW10']
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "NUM",
                +        "check": "Number"
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_SINGLE_HELPURL}",
                +    "extensions": ["math_op_tooltip"]
                +  },
                +
                +  // Block for trigonometry operators.
                +  {
                +    "type": "math_trig",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_MATH_TRIG_SIN}", "SIN"],
                +          ["%{BKY_MATH_TRIG_COS}", "COS"],
                +          ["%{BKY_MATH_TRIG_TAN}", "TAN"],
                +          ["%{BKY_MATH_TRIG_ASIN}", "ASIN"],
                +          ["%{BKY_MATH_TRIG_ACOS}", "ACOS"],
                +          ["%{BKY_MATH_TRIG_ATAN}", "ATAN"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "NUM",
                +        "check": "Number"
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_TRIG_HELPURL}",
                +    "extensions": ["math_op_tooltip"]
                +  },
                +
                +  // Block for constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  {
                +    "type": "math_constant",
                +    "message0": "%1",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "CONSTANT",
                +        "options": [
                +          ["\u03c0", "PI"],
                +          ["e", "E"],
                +          ["\u03c6", "GOLDEN_RATIO"],
                +          ["sqrt(2)", "SQRT2"],
                +          ["sqrt(\u00bd)", "SQRT1_2"],
                +          ["\u221e", "INFINITY"]
                +        ]
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_CONSTANT_TOOLTIP}",
                +    "helpUrl": "%{BKY_MATH_CONSTANT_HELPURL}"
                +  },
                +
                +  // Block for checking if a number is even, odd, prime, whole, positive,
                +  // negative or if it is divisible by certain number.
                +  {
                +    "type": "math_number_property",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "NUMBER_TO_CHECK",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "field_dropdown",
                +        "name": "PROPERTY",
                +        "options": [
                +          ["%{BKY_MATH_IS_EVEN}", "EVEN"],
                +          ["%{BKY_MATH_IS_ODD}", "ODD"],
                +          ["%{BKY_MATH_IS_PRIME}", "PRIME"],
                +          ["%{BKY_MATH_IS_WHOLE}", "WHOLE"],
                +          ["%{BKY_MATH_IS_POSITIVE}", "POSITIVE"],
                +          ["%{BKY_MATH_IS_NEGATIVE}", "NEGATIVE"],
                +          ["%{BKY_MATH_IS_DIVISIBLE_BY}", "DIVISIBLE_BY"]
                +        ]
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Boolean",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_IS_TOOLTIP}",
                +    "mutator": "math_is_divisibleby_mutator"
                +  },
                +
                +  // Block for adding to a variable in place.
                +  {
                +    "type": "math_change",
                +    "message0": "%{BKY_MATH_CHANGE_TITLE}",
                +    "args0": [
                +      {
                +        "type": "field_variable",
                +        "name": "VAR",
                +        "variable": "%{BKY_MATH_CHANGE_TITLE_ITEM}"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "DELTA",
                +        "check": "Number"
                +      }
                +    ],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_VARIABLES_HUE}",
                +    "helpUrl": "%{BKY_MATH_CHANGE_HELPURL}",
                +    "extensions": ["math_change_tooltip"]
                +  },
                +
                +  // Block for rounding functions.
                +  {
                +    "type": "math_round",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_MATH_ROUND_OPERATOR_ROUND}", "ROUND"],
                +          ["%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}", "ROUNDUP"],
                +          ["%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}", "ROUNDDOWN"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "NUM",
                +        "check": "Number"
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_ROUND_HELPURL}",
                +    "tooltip": "%{BKY_MATH_ROUND_TOOLTIP}"
                +  },
                +
                +  // Block for evaluating a list of numbers to return sum, average, min, max,
                +  // etc.  Some functions also work on text (min, max, mode, median).
                +  {
                +    "type": "math_on_list",
                +    "message0": "%1 %2",
                +    "args0": [
                +      {
                +        "type": "field_dropdown",
                +        "name": "OP",
                +        "options": [
                +          ["%{BKY_MATH_ONLIST_OPERATOR_SUM}", "SUM"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_MIN}", "MIN"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_MAX}", "MAX"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_AVERAGE}", "AVERAGE"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_MEDIAN}", "MEDIAN"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_MODE}", "MODE"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_STD_DEV}", "STD_DEV"],
                +          ["%{BKY_MATH_ONLIST_OPERATOR_RANDOM}", "RANDOM"]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "LIST",
                +        "check": "Array"
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "helpUrl": "%{BKY_MATH_ONLIST_HELPURL}",
                +    "mutator": "math_modes_of_list_mutator",
                +    "extensions": ["math_op_tooltip"]
                +  },
                +
                +  // Block for remainder of a division.
                +  {
                +    "type": "math_modulo",
                +    "message0": "%{BKY_MATH_MODULO_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "DIVIDEND",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "DIVISOR",
                +        "check": "Number"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_MODULO_TOOLTIP}",
                +    "helpUrl": "%{BKY_MATH_MODULO_HELPURL}"
                +  },
                +
                +  // Block for constraining a number between two limits.
                +  {
                +    "type": "math_constrain",
                +    "message0": "%{BKY_MATH_CONSTRAIN_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "LOW",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "HIGH",
                +        "check": "Number"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_CONSTRAIN_TOOLTIP}",
                +    "helpUrl": "%{BKY_MATH_CONSTRAIN_HELPURL}"
                +  },
                +
                +  // Block for random integer between [X] and [Y].
                +  {
                +    "type": "math_random_int",
                +    "message0": "%{BKY_MATH_RANDOM_INT_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "FROM",
                +        "check": "Number"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "TO",
                +        "check": "Number"
                +      }
                +    ],
                +    "inputsInline": true,
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_RANDOM_INT_TOOLTIP}",
                +    "helpUrl": "%{BKY_MATH_RANDOM_INT_HELPURL}"
                +  },
                +
                +  // Block for random integer between [X] and [Y].
                +  {
                +    "type": "math_random_float",
                +    "message0": "%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}",
                +    "output": "Number",
                +    "colour": "%{BKY_MATH_HUE}",
                +    "tooltip": "%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}",
                +    "helpUrl": "%{BKY_MATH_RANDOM_FLOAT_HELPURL}"
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +/**
                + * Mapping of math block OP value to tooltip message for blocks
                + * math_arithmetic, math_simple, math_trig, and math_on_lists.
                + * @see {Blockly.Extensions#buildTooltipForDropdown}
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Math.TOOLTIPS_BY_OP = {
                +  // math_arithmetic
                +  'ADD': '%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}',
                +  'MINUS': '%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}',
                +  'MULTIPLY': '%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}',
                +  'DIVIDE': '%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}',
                +  'POWER': '%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}',
                +
                +  // math_simple
                +  'ROOT': '%{BKY_MATH_SINGLE_TOOLTIP_ROOT}',
                +  'ABS': '%{BKY_MATH_SINGLE_TOOLTIP_ABS}',
                +  'NEG': '%{BKY_MATH_SINGLE_TOOLTIP_NEG}',
                +  'LN': '%{BKY_MATH_SINGLE_TOOLTIP_LN}',
                +  'LOG10': '%{BKY_MATH_SINGLE_TOOLTIP_LOG10}',
                +  'EXP': '%{BKY_MATH_SINGLE_TOOLTIP_EXP}',
                +  'POW10': '%{BKY_MATH_SINGLE_TOOLTIP_POW10}',
                +
                +  // math_trig
                +  'SIN': '%{BKY_MATH_TRIG_TOOLTIP_SIN}',
                +  'COS': '%{BKY_MATH_TRIG_TOOLTIP_COS}',
                +  'TAN': '%{BKY_MATH_TRIG_TOOLTIP_TAN}',
                +  'ASIN': '%{BKY_MATH_TRIG_TOOLTIP_ASIN}',
                +  'ACOS': '%{BKY_MATH_TRIG_TOOLTIP_ACOS}',
                +  'ATAN': '%{BKY_MATH_TRIG_TOOLTIP_ATAN}',
                +
                +  // math_on_lists
                +  'SUM': '%{BKY_MATH_ONLIST_TOOLTIP_SUM}',
                +  'MIN': '%{BKY_MATH_ONLIST_TOOLTIP_MIN}',
                +  'MAX': '%{BKY_MATH_ONLIST_TOOLTIP_MAX}',
                +  'AVERAGE': '%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}',
                +  'MEDIAN': '%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}',
                +  'MODE': '%{BKY_MATH_ONLIST_TOOLTIP_MODE}',
                +  'STD_DEV': '%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}',
                +  'RANDOM': '%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}'
                +};
                +
                +Blockly.Extensions.register('math_op_tooltip',
                +  Blockly.Extensions.buildTooltipForDropdown(
                +    'OP', Blockly.Constants.Math.TOOLTIPS_BY_OP));
                +
                +
                +/**
                + * Mixin for mutator functions in the 'math_is_divisibleby_mutator'
                + * extension.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
                +  /**
                +   * Create XML to represent whether the 'divisorInput' should be present.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var divisorInput = (this.getFieldValue('PROPERTY') == 'DIVISIBLE_BY');
                +    container.setAttribute('divisor_input', divisorInput);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'divisorInput'.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    var divisorInput = (xmlElement.getAttribute('divisor_input') == 'true');
                +    this.updateShape_(divisorInput);
                +  },
                +  /**
                +   * Modify this block to have (or not have) an input for 'is divisible by'.
                +   * @param {boolean} divisorInput True if this block has a divisor input.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateShape_: function(divisorInput) {
                +    // Add or remove a Value Input.
                +    var inputExists = this.getInput('DIVISOR');
                +    if (divisorInput) {
                +      if (!inputExists) {
                +        this.appendValueInput('DIVISOR')
                +            .setCheck('Number');
                +      }
                +    } else if (inputExists) {
                +      this.removeInput('DIVISOR');
                +    }
                +  }
                +};
                +
                +/**
                + * 'math_is_divisibleby_mutator' extension to the 'math_property' block that
                + * can update the block shape (add/remove divisor input) based on whether
                + * property is "divisble by".
                + * @this Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION = function() {
                +  this.getField('PROPERTY').setValidator(function(option) {
                +    var divisorInput = (option == 'DIVISIBLE_BY');
                +    this.sourceBlock_.updateShape_(divisorInput);
                +  });
                +};
                +
                +Blockly.Extensions.registerMutator('math_is_divisibleby_mutator',
                +  Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,
                +  Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);
                +
                +/**
                + * Update the tooltip of 'math_change' block to reference the variable.
                + * @this Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Math.CHANGE_TOOLTIP_EXTENSION = function() {
                +  this.setTooltip(function() {
                +    return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace('%1',
                +        this.getFieldValue('VAR'));
                +  }.bind(this));
                +};
                +
                +Blockly.Extensions.register('math_change_tooltip',
                +  Blockly.Extensions.buildTooltipWithFieldValue(
                +    Blockly.Msg.MATH_CHANGE_TOOLTIP, 'VAR'));
                +
                +/**
                + * Mixin with mutator methods to support alternate output based if the
                + * 'math_on_list' block uses the 'MODE' operation.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN = {
                +  /**
                +   * Modify this block to have the correct output type.
                +   * @param {string} newOp Either 'MODE' or some op than returns a number.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateType_: function(newOp) {
                +    if (newOp == 'MODE') {
                +      this.outputConnection.setCheck('Array');
                +    } else {
                +      this.outputConnection.setCheck('Number');
                +    }
                +  },
                +  /**
                +   * Create XML to represent the output type.
                +   * @return {Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('op', this.getFieldValue('OP'));
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the output type.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.updateType_(xmlElement.getAttribute('op'));
                +  }
                +};
                +
                +/**
                + * Extension to 'math_on_list' blocks that allows support of
                + * modes operation (outputs a list of numbers).
                + * @this Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION = function() {
                +  this.getField('OP').setValidator(function(newOp) {
                +    this.updateType_(newOp);
                +  }.bind(this));
                +};
                +
                +Blockly.Extensions.registerMutator('math_modes_of_list_mutator',
                +  Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,
                +  Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);
                diff --git a/blockly/webif/static/blockly/blocks/procedures.js b/blockly/webif/static/blockly/blocks/procedures.js
                new file mode 100644
                index 000000000..223a655cd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/procedures.js
                @@ -0,0 +1,889 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Procedure blocks for Blockly.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.procedures');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + */
                +Blockly.Blocks.procedures.HUE = 290;
                +
                +Blockly.Blocks['procedures_defnoreturn'] = {
                +  /**
                +   * Block for defining a procedure with no return value.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var nameField = new Blockly.FieldTextInput('',
                +        Blockly.Procedures.rename);
                +    nameField.setSpellcheck(false);
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE)
                +        .appendField(nameField, 'NAME')
                +        .appendField('', 'PARAMS');
                +    this.setMutator(new Blockly.Mutator(['procedures_mutatorarg']));
                +    if ((this.workspace.options.comments ||
                +         (this.workspace.options.parentWorkspace &&
                +          this.workspace.options.parentWorkspace.options.comments)) &&
                +        Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT) {
                +      this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
                +    }
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);
                +    this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);
                +    this.arguments_ = [];
                +    this.setStatements_(true);
                +    this.statementConnection_ = null;
                +  },
                +  /**
                +   * Add or remove the statement block from this function definition.
                +   * @param {boolean} hasStatements True if a statement block is needed.
                +   * @this Blockly.Block
                +   */
                +  setStatements_: function(hasStatements) {
                +    if (this.hasStatements_ === hasStatements) {
                +      return;
                +    }
                +    if (hasStatements) {
                +      this.appendStatementInput('STACK')
                +          .appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO);
                +      if (this.getInput('RETURN')) {
                +        this.moveInputBefore('STACK', 'RETURN');
                +      }
                +    } else {
                +      this.removeInput('STACK', true);
                +    }
                +    this.hasStatements_ = hasStatements;
                +  },
                +  /**
                +   * Update the display of parameters for this procedure definition block.
                +   * Display a warning if there are duplicately named parameters.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateParams_: function() {
                +    // Check for duplicated arguments.
                +    var badArg = false;
                +    var hash = {};
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      if (hash['arg_' + this.arguments_[i].toLowerCase()]) {
                +        badArg = true;
                +        break;
                +      }
                +      hash['arg_' + this.arguments_[i].toLowerCase()] = true;
                +    }
                +    if (badArg) {
                +      this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING);
                +    } else {
                +      this.setWarningText(null);
                +    }
                +    // Merge the arguments into a human-readable list.
                +    var paramString = '';
                +    if (this.arguments_.length) {
                +      paramString = Blockly.Msg.PROCEDURES_BEFORE_PARAMS +
                +          ' ' + this.arguments_.join(', ');
                +    }
                +    // The params field is deterministic based on the mutation,
                +    // no need to fire a change event.
                +    Blockly.Events.disable();
                +    try {
                +      this.setFieldValue(paramString, 'PARAMS');
                +    } finally {
                +      Blockly.Events.enable();
                +    }
                +  },
                +  /**
                +   * Create XML to represent the argument inputs.
                +   * @param {boolean=} opt_paramIds If true include the IDs of the parameter
                +   *     quarks.  Used by Blockly.Procedures.mutateCallers for reconnection.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function(opt_paramIds) {
                +    var container = document.createElement('mutation');
                +    if (opt_paramIds) {
                +      container.setAttribute('name', this.getFieldValue('NAME'));
                +    }
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var parameter = document.createElement('arg');
                +      parameter.setAttribute('name', this.arguments_[i]);
                +      if (opt_paramIds && this.paramIds_) {
                +        parameter.setAttribute('paramId', this.paramIds_[i]);
                +      }
                +      container.appendChild(parameter);
                +    }
                +
                +    // Save whether the statement input is visible.
                +    if (!this.hasStatements_) {
                +      container.setAttribute('statements', 'false');
                +    }
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the argument inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.arguments_ = [];
                +    for (var i = 0, childNode; childNode = xmlElement.childNodes[i]; i++) {
                +      if (childNode.nodeName.toLowerCase() == 'arg') {
                +        this.arguments_.push(childNode.getAttribute('name'));
                +      }
                +    }
                +    this.updateParams_();
                +    Blockly.Procedures.mutateCallers(this);
                +
                +    // Show or hide the statement input.
                +    this.setStatements_(xmlElement.getAttribute('statements') !== 'false');
                +  },
                +  /**
                +   * Populate the mutator's dialog with this block's components.
                +   * @param {!Blockly.Workspace} workspace Mutator's workspace.
                +   * @return {!Blockly.Block} Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  decompose: function(workspace) {
                +    var containerBlock = workspace.newBlock('procedures_mutatorcontainer');
                +    containerBlock.initSvg();
                +
                +    // Check/uncheck the allow statement box.
                +    if (this.getInput('RETURN')) {
                +      containerBlock.setFieldValue(this.hasStatements_ ? 'TRUE' : 'FALSE',
                +                                   'STATEMENTS');
                +    } else {
                +      containerBlock.getInput('STATEMENT_INPUT').setVisible(false);
                +    }
                +
                +    // Parameter list.
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var paramBlock = workspace.newBlock('procedures_mutatorarg');
                +      paramBlock.initSvg();
                +      paramBlock.setFieldValue(this.arguments_[i], 'NAME');
                +      // Store the old location.
                +      paramBlock.oldLocation = i;
                +      connection.connect(paramBlock.previousConnection);
                +      connection = paramBlock.nextConnection;
                +    }
                +    // Initialize procedure's callers with blank IDs.
                +    Blockly.Procedures.mutateCallers(this);
                +    return containerBlock;
                +  },
                +  /**
                +   * Reconfigure this block based on the mutator dialog's components.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  compose: function(containerBlock) {
                +    // Parameter list.
                +    this.arguments_ = [];
                +    this.paramIds_ = [];
                +    var paramBlock = containerBlock.getInputTargetBlock('STACK');
                +    while (paramBlock) {
                +      this.arguments_.push(paramBlock.getFieldValue('NAME'));
                +      this.paramIds_.push(paramBlock.id);
                +      paramBlock = paramBlock.nextConnection &&
                +          paramBlock.nextConnection.targetBlock();
                +    }
                +    this.updateParams_();
                +    Blockly.Procedures.mutateCallers(this);
                +
                +    // Show/hide the statement input.
                +    var hasStatements = containerBlock.getFieldValue('STATEMENTS');
                +    if (hasStatements !== null) {
                +      hasStatements = hasStatements == 'TRUE';
                +      if (this.hasStatements_ != hasStatements) {
                +        if (hasStatements) {
                +          this.setStatements_(true);
                +          // Restore the stack, if one was saved.
                +          Blockly.Mutator.reconnect(this.statementConnection_, this, 'STACK');
                +          this.statementConnection_ = null;
                +        } else {
                +          // Save the stack, then disconnect it.
                +          var stackConnection = this.getInput('STACK').connection;
                +          this.statementConnection_ = stackConnection.targetConnection;
                +          if (this.statementConnection_) {
                +            var stackBlock = stackConnection.targetBlock();
                +            stackBlock.unplug();
                +            stackBlock.bumpNeighbours_();
                +          }
                +          this.setStatements_(false);
                +        }
                +      }
                +    }
                +  },
                +  /**
                +   * Return the signature of this procedure definition.
                +   * @return {!Array} Tuple containing three elements:
                +   *     - the name of the defined procedure,
                +   *     - a list of all its arguments,
                +   *     - that it DOES NOT have a return value.
                +   * @this Blockly.Block
                +   */
                +  getProcedureDef: function() {
                +    return [this.getFieldValue('NAME'), this.arguments_, false];
                +  },
                +  /**
                +   * Return all variables referenced by this block.
                +   * @return {!Array.<string>} List of variable names.
                +   * @this Blockly.Block
                +   */
                +  getVars: function() {
                +    return this.arguments_;
                +  },
                +  /**
                +   * Notification that a variable is renaming.
                +   * If the name matches one of this block's variables, rename it.
                +   * @param {string} oldName Previous name of variable.
                +   * @param {string} newName Renamed variable.
                +   * @this Blockly.Block
                +   */
                +  renameVar: function(oldName, newName) {
                +    var change = false;
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      if (Blockly.Names.equals(oldName, this.arguments_[i])) {
                +        this.arguments_[i] = newName;
                +        change = true;
                +      }
                +    }
                +    if (change) {
                +      this.updateParams_();
                +      // Update the mutator's variables if the mutator is open.
                +      if (this.mutator.isVisible()) {
                +        var blocks = this.mutator.workspace_.getAllBlocks();
                +        for (var i = 0, block; block = blocks[i]; i++) {
                +          if (block.type == 'procedures_mutatorarg' &&
                +              Blockly.Names.equals(oldName, block.getFieldValue('NAME'))) {
                +            block.setFieldValue(newName, 'NAME');
                +          }
                +        }
                +      }
                +    }
                +  },
                +  /**
                +   * Add custom menu options to this block's context menu.
                +   * @param {!Array} options List of menu options to add to.
                +   * @this Blockly.Block
                +   */
                +  customContextMenu: function(options) {
                +    // Add option to create caller.
                +    var option = {enabled: true};
                +    var name = this.getFieldValue('NAME');
                +    option.text = Blockly.Msg.PROCEDURES_CREATE_DO.replace('%1', name);
                +    var xmlMutation = goog.dom.createDom('mutation');
                +    xmlMutation.setAttribute('name', name);
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var xmlArg = goog.dom.createDom('arg');
                +      xmlArg.setAttribute('name', this.arguments_[i]);
                +      xmlMutation.appendChild(xmlArg);
                +    }
                +    var xmlBlock = goog.dom.createDom('block', null, xmlMutation);
                +    xmlBlock.setAttribute('type', this.callType_);
                +    option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
                +    options.push(option);
                +
                +    // Add options to create getters for each parameter.
                +    if (!this.isCollapsed()) {
                +      for (var i = 0; i < this.arguments_.length; i++) {
                +        var option = {enabled: true};
                +        var name = this.arguments_[i];
                +        option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name);
                +        var xmlField = goog.dom.createDom('field', null, name);
                +        xmlField.setAttribute('name', 'VAR');
                +        var xmlBlock = goog.dom.createDom('block', null, xmlField);
                +        xmlBlock.setAttribute('type', 'variables_get');
                +        option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
                +        options.push(option);
                +      }
                +    }
                +  },
                +  callType_: 'procedures_callnoreturn'
                +};
                +
                +Blockly.Blocks['procedures_defreturn'] = {
                +  /**
                +   * Block for defining a procedure with a return value.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var nameField = new Blockly.FieldTextInput('',
                +        Blockly.Procedures.rename);
                +    nameField.setSpellcheck(false);
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE)
                +        .appendField(nameField, 'NAME')
                +        .appendField('', 'PARAMS');
                +    this.appendValueInput('RETURN')
                +        .setAlign(Blockly.ALIGN_RIGHT)
                +        .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
                +    this.setMutator(new Blockly.Mutator(['procedures_mutatorarg']));
                +    if ((this.workspace.options.comments ||
                +         (this.workspace.options.parentWorkspace &&
                +          this.workspace.options.parentWorkspace.options.comments)) &&
                +        Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT) {
                +      this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);
                +    }
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);
                +    this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);
                +    this.arguments_ = [];
                +    this.setStatements_(true);
                +    this.statementConnection_ = null;
                +  },
                +  setStatements_: Blockly.Blocks['procedures_defnoreturn'].setStatements_,
                +  updateParams_: Blockly.Blocks['procedures_defnoreturn'].updateParams_,
                +  mutationToDom: Blockly.Blocks['procedures_defnoreturn'].mutationToDom,
                +  domToMutation: Blockly.Blocks['procedures_defnoreturn'].domToMutation,
                +  decompose: Blockly.Blocks['procedures_defnoreturn'].decompose,
                +  compose: Blockly.Blocks['procedures_defnoreturn'].compose,
                +  /**
                +   * Return the signature of this procedure definition.
                +   * @return {!Array} Tuple containing three elements:
                +   *     - the name of the defined procedure,
                +   *     - a list of all its arguments,
                +   *     - that it DOES have a return value.
                +   * @this Blockly.Block
                +   */
                +  getProcedureDef: function() {
                +    return [this.getFieldValue('NAME'), this.arguments_, true];
                +  },
                +  getVars: Blockly.Blocks['procedures_defnoreturn'].getVars,
                +  renameVar: Blockly.Blocks['procedures_defnoreturn'].renameVar,
                +  customContextMenu: Blockly.Blocks['procedures_defnoreturn'].customContextMenu,
                +  callType_: 'procedures_callreturn'
                +};
                +
                +Blockly.Blocks['procedures_mutatorcontainer'] = {
                +  /**
                +   * Mutator block for procedure container.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);
                +    this.appendStatementInput('STACK');
                +    this.appendDummyInput('STATEMENT_INPUT')
                +        .appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS)
                +        .appendField(new Blockly.FieldCheckbox('TRUE'), 'STATEMENTS');
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['procedures_mutatorarg'] = {
                +  /**
                +   * Mutator block for procedure argument.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var field = new Blockly.FieldTextInput('x', this.validator_);
                +    this.appendDummyInput()
                +        .appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE)
                +        .appendField(field, 'NAME');
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);
                +    this.contextMenu = false;
                +
                +    // Create the default variable when we drag the block in from the flyout.
                +    // Have to do this after installing the field on the block.
                +    field.onFinishEditing_ = this.createNewVar_;
                +    field.onFinishEditing_('x');
                +  },
                +  /**
                +   * Obtain a valid name for the procedure.
                +   * Merge runs of whitespace.  Strip leading and trailing whitespace.
                +   * Beyond this, all names are legal.
                +   * @param {string} newVar User-supplied name.
                +   * @return {?string} Valid name, or null if a name was not specified.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  validator_: function(newVar) {
                +    newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
                +    return newVar || null;
                +  },
                +  /**
                +   * Called when focusing away from the text field.
                +   * Creates a new variable with this name.
                +   * @param {string} newText The new variable name.
                +   * @private
                +   * @this Blockly.FieldTextInput
                +   */
                +  createNewVar_: function(newText) {
                +    var source = this.sourceBlock_;
                +    if (source && source.workspace && source.workspace.options &&
                +        source.workspace.options.parentWorkspace) {
                +      source.workspace.options.parentWorkspace.createVariable(newText);
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['procedures_callnoreturn'] = {
                +  /**
                +   * Block for calling a procedure with no return value.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.appendDummyInput('TOPROW')
                +        .appendField(this.id, 'NAME');
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    // Tooltip is set in renameProcedure.
                +    this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);
                +    this.arguments_ = [];
                +    this.quarkConnections_ = {};
                +    this.quarkIds_ = null;
                +  },
                +  /**
                +   * Returns the name of the procedure this block calls.
                +   * @return {string} Procedure name.
                +   * @this Blockly.Block
                +   */
                +  getProcedureCall: function() {
                +    // The NAME field is guaranteed to exist, null will never be returned.
                +    return /** @type {string} */ (this.getFieldValue('NAME'));
                +  },
                +  /**
                +   * Notification that a procedure is renaming.
                +   * If the name matches this block's procedure, rename it.
                +   * @param {string} oldName Previous name of procedure.
                +   * @param {string} newName Renamed procedure.
                +   * @this Blockly.Block
                +   */
                +  renameProcedure: function(oldName, newName) {
                +    if (Blockly.Names.equals(oldName, this.getProcedureCall())) {
                +      this.setFieldValue(newName, 'NAME');
                +      this.setTooltip(
                +          (this.outputConnection ? Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP :
                +           Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP)
                +          .replace('%1', newName));
                +    }
                +  },
                +  /**
                +   * Notification that the procedure's parameters have changed.
                +   * @param {!Array.<string>} paramNames New param names, e.g. ['x', 'y', 'z'].
                +   * @param {!Array.<string>} paramIds IDs of params (consistent for each
                +   *     parameter through the life of a mutator, regardless of param renaming),
                +   *     e.g. ['piua', 'f8b_', 'oi.o'].
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  setProcedureParameters_: function(paramNames, paramIds) {
                +    // Data structures:
                +    // this.arguments = ['x', 'y']
                +    //     Existing param names.
                +    // this.quarkConnections_ {piua: null, f8b_: Blockly.Connection}
                +    //     Look-up of paramIds to connections plugged into the call block.
                +    // this.quarkIds_ = ['piua', 'f8b_']
                +    //     Existing param IDs.
                +    // Note that quarkConnections_ may include IDs that no longer exist, but
                +    // which might reappear if a param is reattached in the mutator.
                +    var defBlock = Blockly.Procedures.getDefinition(this.getProcedureCall(),
                +        this.workspace);
                +    var mutatorOpen = defBlock && defBlock.mutator &&
                +        defBlock.mutator.isVisible();
                +    if (!mutatorOpen) {
                +      this.quarkConnections_ = {};
                +      this.quarkIds_ = null;
                +    }
                +    if (!paramIds) {
                +      // Reset the quarks (a mutator is about to open).
                +      return;
                +    }
                +    if (goog.array.equals(this.arguments_, paramNames)) {
                +      // No change.
                +      this.quarkIds_ = paramIds;
                +      return;
                +    }
                +    if (paramIds.length != paramNames.length) {
                +      throw 'Error: paramNames and paramIds must be the same length.';
                +    }
                +    this.setCollapsed(false);
                +    if (!this.quarkIds_) {
                +      // Initialize tracking for this block.
                +      this.quarkConnections_ = {};
                +      if (paramNames.join('\n') == this.arguments_.join('\n')) {
                +        // No change to the parameters, allow quarkConnections_ to be
                +        // populated with the existing connections.
                +        this.quarkIds_ = paramIds;
                +      } else {
                +        this.quarkIds_ = [];
                +      }
                +    }
                +    // Switch off rendering while the block is rebuilt.
                +    var savedRendered = this.rendered;
                +    this.rendered = false;
                +    // Update the quarkConnections_ with existing connections.
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var input = this.getInput('ARG' + i);
                +      if (input) {
                +        var connection = input.connection.targetConnection;
                +        this.quarkConnections_[this.quarkIds_[i]] = connection;
                +        if (mutatorOpen && connection &&
                +            paramIds.indexOf(this.quarkIds_[i]) == -1) {
                +          // This connection should no longer be attached to this block.
                +          connection.disconnect();
                +          connection.getSourceBlock().bumpNeighbours_();
                +        }
                +      }
                +    }
                +    // Rebuild the block's arguments.
                +    this.arguments_ = [].concat(paramNames);
                +    this.updateShape_();
                +    this.quarkIds_ = paramIds;
                +    // Reconnect any child blocks.
                +    if (this.quarkIds_) {
                +      for (var i = 0; i < this.arguments_.length; i++) {
                +        var quarkId = this.quarkIds_[i];
                +        if (quarkId in this.quarkConnections_) {
                +          var connection = this.quarkConnections_[quarkId];
                +          if (!Blockly.Mutator.reconnect(connection, this, 'ARG' + i)) {
                +            // Block no longer exists or has been attached elsewhere.
                +            delete this.quarkConnections_[quarkId];
                +          }
                +        }
                +      }
                +    }
                +    // Restore rendering and show the changes.
                +    this.rendered = savedRendered;
                +    if (this.rendered) {
                +      this.render();
                +    }
                +  },
                +  /**
                +   * Modify this block to have the correct number of arguments.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateShape_: function() {
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var field = this.getField('ARGNAME' + i);
                +      if (field) {
                +        // Ensure argument name is up to date.
                +        // The argument name field is deterministic based on the mutation,
                +        // no need to fire a change event.
                +        Blockly.Events.disable();
                +        try {
                +          field.setValue(this.arguments_[i]);
                +        } finally {
                +          Blockly.Events.enable();
                +        }
                +      } else {
                +        // Add new input.
                +        field = new Blockly.FieldLabel(this.arguments_[i]);
                +        var input = this.appendValueInput('ARG' + i)
                +            .setAlign(Blockly.ALIGN_RIGHT)
                +            .appendField(field, 'ARGNAME' + i);
                +        input.init();
                +      }
                +    }
                +    // Remove deleted inputs.
                +    while (this.getInput('ARG' + i)) {
                +      this.removeInput('ARG' + i);
                +      i++;
                +    }
                +    // Add 'with:' if there are parameters, remove otherwise.
                +    var topRow = this.getInput('TOPROW');
                +    if (topRow) {
                +      if (this.arguments_.length) {
                +        if (!this.getField('WITH')) {
                +          topRow.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS, 'WITH');
                +          topRow.init();
                +        }
                +      } else {
                +        if (this.getField('WITH')) {
                +          topRow.removeField('WITH');
                +        }
                +      }
                +    }
                +  },
                +  /**
                +   * Create XML to represent the (non-editable) name and arguments.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('name', this.getProcedureCall());
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      var parameter = document.createElement('arg');
                +      parameter.setAttribute('name', this.arguments_[i]);
                +      container.appendChild(parameter);
                +    }
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the (non-editable) name and parameters.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    var name = xmlElement.getAttribute('name');
                +    this.renameProcedure(this.getProcedureCall(), name);
                +    var args = [];
                +    var paramIds = [];
                +    for (var i = 0, childNode; childNode = xmlElement.childNodes[i]; i++) {
                +      if (childNode.nodeName.toLowerCase() == 'arg') {
                +        args.push(childNode.getAttribute('name'));
                +        paramIds.push(childNode.getAttribute('paramId'));
                +      }
                +    }
                +    this.setProcedureParameters_(args, paramIds);
                +  },
                +  /**
                +   * Notification that a variable is renaming.
                +   * If the name matches one of this block's variables, rename it.
                +   * @param {string} oldName Previous name of variable.
                +   * @param {string} newName Renamed variable.
                +   * @this Blockly.Block
                +   */
                +  renameVar: function(oldName, newName) {
                +    for (var i = 0; i < this.arguments_.length; i++) {
                +      if (Blockly.Names.equals(oldName, this.arguments_[i])) {
                +        this.arguments_[i] = newName;
                +        this.getField('ARGNAME' + i).setValue(newName);
                +      }
                +    }
                +  },
                +  /**
                +   * Procedure calls cannot exist without the corresponding procedure
                +   * definition.  Enforce this link whenever an event is fired.
                +   * @param {!Blockly.Events.Abstract} event Change event.
                +   * @this Blockly.Block
                +   */
                +  onchange: function(event) {
                +    if (!this.workspace || this.workspace.isFlyout) {
                +      // Block is deleted or is in a flyout.
                +      return;
                +    }
                +    if (event.type == Blockly.Events.BLOCK_CREATE &&
                +        event.ids.indexOf(this.id) != -1) {
                +      // Look for the case where a procedure call was created (usually through
                +      // paste) and there is no matching definition.  In this case, create
                +      // an empty definition block with the correct signature.
                +      var name = this.getProcedureCall();
                +      var def = Blockly.Procedures.getDefinition(name, this.workspace);
                +      if (def && (def.type != this.defType_ ||
                +          JSON.stringify(def.arguments_) != JSON.stringify(this.arguments_))) {
                +        // The signatures don't match.
                +        def = null;
                +      }
                +      if (!def) {
                +        Blockly.Events.setGroup(event.group);
                +        /**
                +         * Create matching definition block.
                +         * <xml>
                +         *   <block type="procedures_defreturn" x="10" y="20">
                +         *     <mutation name="test">
                +         *       <arg name="x"></arg>
                +         *     </mutation>
                +         *     <field name="NAME">test</field>
                +         *   </block>
                +         * </xml>
                +         */
                +        var xml = goog.dom.createDom('xml');
                +        var block = goog.dom.createDom('block');
                +        block.setAttribute('type', this.defType_);
                +        var xy = this.getRelativeToSurfaceXY();
                +        var x = xy.x + Blockly.SNAP_RADIUS * (this.RTL ? -1 : 1);
                +        var y = xy.y + Blockly.SNAP_RADIUS * 2;
                +        block.setAttribute('x', x);
                +        block.setAttribute('y', y);
                +        var mutation = this.mutationToDom();
                +        block.appendChild(mutation);
                +        var field = goog.dom.createDom('field');
                +        field.setAttribute('name', 'NAME');
                +        field.appendChild(document.createTextNode(this.getProcedureCall()));
                +        block.appendChild(field);
                +        xml.appendChild(block);
                +        Blockly.Xml.domToWorkspace(xml, this.workspace);
                +        Blockly.Events.setGroup(false);
                +      }
                +    } else if (event.type == Blockly.Events.BLOCK_DELETE) {
                +      // Look for the case where a procedure definition has been deleted,
                +      // leaving this block (a procedure call) orphaned.  In this case, delete
                +      // the orphan.
                +      var name = this.getProcedureCall();
                +      var def = Blockly.Procedures.getDefinition(name, this.workspace);
                +      if (!def) {
                +        Blockly.Events.setGroup(event.group);
                +        this.dispose(true, false);
                +        Blockly.Events.setGroup(false);
                +      }
                +    }
                +  },
                +  /**
                +   * Add menu option to find the definition block for this call.
                +   * @param {!Array} options List of menu options to add to.
                +   * @this Blockly.Block
                +   */
                +  customContextMenu: function(options) {
                +    var option = {enabled: true};
                +    option.text = Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;
                +    var name = this.getProcedureCall();
                +    var workspace = this.workspace;
                +    option.callback = function() {
                +      var def = Blockly.Procedures.getDefinition(name, workspace);
                +      def && def.select();
                +    };
                +    options.push(option);
                +  },
                +  defType_: 'procedures_defnoreturn'
                +};
                +
                +Blockly.Blocks['procedures_callreturn'] = {
                +  /**
                +   * Block for calling a procedure with a return value.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.appendDummyInput('TOPROW')
                +        .appendField('', 'NAME');
                +    this.setOutput(true);
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    // Tooltip is set in domToMutation.
                +    this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);
                +    this.arguments_ = [];
                +    this.quarkConnections_ = {};
                +    this.quarkIds_ = null;
                +  },
                +  getProcedureCall: Blockly.Blocks['procedures_callnoreturn'].getProcedureCall,
                +  renameProcedure: Blockly.Blocks['procedures_callnoreturn'].renameProcedure,
                +  setProcedureParameters_:
                +      Blockly.Blocks['procedures_callnoreturn'].setProcedureParameters_,
                +  updateShape_: Blockly.Blocks['procedures_callnoreturn'].updateShape_,
                +  mutationToDom: Blockly.Blocks['procedures_callnoreturn'].mutationToDom,
                +  domToMutation: Blockly.Blocks['procedures_callnoreturn'].domToMutation,
                +  renameVar: Blockly.Blocks['procedures_callnoreturn'].renameVar,
                +  onchange: Blockly.Blocks['procedures_callnoreturn'].onchange,
                +  customContextMenu:
                +      Blockly.Blocks['procedures_callnoreturn'].customContextMenu,
                +  defType_: 'procedures_defreturn'
                +};
                +
                +Blockly.Blocks['procedures_ifreturn'] = {
                +  /**
                +   * Block for conditionally returning a value from a procedure.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.appendValueInput('CONDITION')
                +        .setCheck('Boolean')
                +        .appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);
                +    this.appendValueInput('VALUE')
                +        .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setColour(Blockly.Blocks.procedures.HUE);
                +    this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);
                +    this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);
                +    this.hasReturnValue_ = true;
                +  },
                +  /**
                +   * Create XML to represent whether this block has a return value.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('value', Number(this.hasReturnValue_));
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore whether this block has a return value.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    var value = xmlElement.getAttribute('value');
                +    this.hasReturnValue_ = (value == 1);
                +    if (!this.hasReturnValue_) {
                +      this.removeInput('VALUE');
                +      this.appendDummyInput('VALUE')
                +        .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
                +    }
                +  },
                +  /**
                +   * Called whenever anything on the workspace changes.
                +   * Add warning if this flow block is not nested inside a loop.
                +   * @param {!Blockly.Events.Abstract} e Change event.
                +   * @this Blockly.Block
                +   */
                +  onchange: function(/* e */) {
                +    if (!this.workspace.isDragging || this.workspace.isDragging()) {
                +      return;  // Don't change state at the start of a drag.
                +    }
                +    var legal = false;
                +    // Is the block nested in a procedure?
                +    var block = this;
                +    do {
                +      if (this.FUNCTION_TYPES.indexOf(block.type) != -1) {
                +        legal = true;
                +        break;
                +      }
                +      block = block.getSurroundParent();
                +    } while (block);
                +    if (legal) {
                +      // If needed, toggle whether this block has a return value.
                +      if (block.type == 'procedures_defnoreturn' && this.hasReturnValue_) {
                +        this.removeInput('VALUE');
                +        this.appendDummyInput('VALUE')
                +            .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
                +        this.hasReturnValue_ = false;
                +      } else if (block.type == 'procedures_defreturn' &&
                +                 !this.hasReturnValue_) {
                +        this.removeInput('VALUE');
                +        this.appendValueInput('VALUE')
                +            .appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
                +        this.hasReturnValue_ = true;
                +      }
                +      this.setWarningText(null);
                +      if (!this.isInFlyout) {
                +        this.setDisabled(false);
                +      }
                +    } else {
                +      this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING);
                +      if (!this.isInFlyout && !this.getInheritedDisabled()) {
                +        this.setDisabled(true);
                +      }
                +    }
                +  },
                +  /**
                +   * List of block types that are functions and thus do not need warnings.
                +   * To add a new function type add this to your code:
                +   * Blockly.Blocks['procedures_ifreturn'].FUNCTION_TYPES.push('custom_func');
                +   */
                +  FUNCTION_TYPES: ['procedures_defnoreturn', 'procedures_defreturn']
                +};
                diff --git a/blockly/webif/static/blockly/blocks/text.js b/blockly/webif/static/blockly/blocks/text.js
                new file mode 100644
                index 000000000..348f99579
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/text.js
                @@ -0,0 +1,892 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Text blocks for Blockly.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.texts');  // Deprecated
                +goog.provide('Blockly.Constants.Text');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * Should be the same as Blockly.Msg.TEXTS_HUE
                + * @readonly
                + */
                +Blockly.Constants.Text.HUE = 160;
                +/** @deprecated Use Blockly.Constants.Text.HUE */
                +Blockly.Blocks.texts.HUE = Blockly.Constants.Text.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for text value
                +  {
                +    "type": "text",
                +    "message0": "%1",
                +    "args0": [{
                +      "type": "field_input",
                +      "name": "TEXT",
                +      "text": ""
                +    }],
                +    "output": "String",
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "helpUrl": "%{BKY_TEXT_TEXT_HELPURL}",
                +    "tooltip": "%{BKY_TEXT_TEXT_TOOLTIP}",
                +    "extensions": [
                +      "text_quotes",
                +      "parent_tooltip_when_inline"
                +    ]
                +  },
                +  {
                +    "type": "text_join",
                +    "message0": "",
                +    "output": "String",
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "helpUrl": "%{BKY_TEXT_JOIN_HELPURL}",
                +    "tooltip": "%{BKY_TEXT_JOIN_TOOLTIP}",
                +    "mutator": "text_join_mutator"
                +
                +  },
                +  {
                +    "type": "text_create_join_container",
                +    "message0": "%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",
                +    "args0": [{
                +      "type": "input_dummy"
                +    },
                +    {
                +      "type": "input_statement",
                +      "name": "STACK"
                +    }],
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "tooltip": "%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",
                +    "enableContextMenu": false
                +  },
                +  {
                +    "type": "text_create_join_item",
                +    "message0": "%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "tooltip": "{%BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",
                +    "enableContextMenu": false
                +  },
                +  {
                +    "type": "text_append",
                +    "message0": "%{BKY_TEXT_APPEND_TITLE}",
                +    "args0": [{
                +      "type": "field_variable",
                +      "name": "VAR",
                +      "variable": "%{BKY_TEXT_APPEND_VARIABLE}"
                +    },
                +    {
                +      "type": "input_value",
                +      "name": "TEXT"
                +    }],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "extensions": [
                +      "text_append_tooltip"
                +    ]
                +  },
                +  {
                +    "type": "text_length",
                +    "message0": "%{BKY_TEXT_LENGTH_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": ['String', 'Array']
                +      }
                +    ],
                +    "output": 'Number',
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "tooltip": "%{BKY_TEXT_LENGTH_TOOLTIP}",
                +    "helpUrl": "%{BKY_TEXT_LENGTH_HELPURL}"
                +  },
                +  {
                +    "type": "text_isEmpty",
                +    "message0": "%{BKY_TEXT_ISEMPTY_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": ['String', 'Array']
                +      }
                +    ],
                +    "output": 'Boolean',
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "tooltip": "%{BKY_TEXT_ISEMPTY_TOOLTIP}",
                +    "helpUrl": "%{BKY_TEXT_ISEMPTY_HELPURL}"
                +  },
                +  {
                +    "type": "text_indexOf",
                +    "message0": "%{BKY_TEXT_INDEXOF_TITLE}",
                +    "args0": [
                +      {
                +        "type": "input_value",
                +        "name": "VALUE",
                +        "check": "String"
                +      },
                +      {
                +        "type": "field_dropdown",
                +        "name": "END",
                +        "options": [
                +          [
                +            "%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}",
                +            "FIRST"
                +          ],
                +          [
                +            "%{BKY_TEXT_INDEXOF_OPERATOR_LAST}",
                +            "LAST"
                +          ]
                +        ]
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "FIND",
                +        "check": "String"
                +      }
                +    ],
                +    "output": "Number",
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "helpUrl": "%{BKY_TEXT_INDEXOF_HELPURL}",
                +    "inputsInline": true,
                +    "extensions": [
                +      "text_indexOf_tooltip"
                +    ]
                +  },
                +  {
                +    "type": "text_charAt",
                +    "message0": "%{BKY_TEXT_CHARAT_TITLE}", // "in text %1 %2"
                +    "args0": [
                +      {
                +        "type":"input_value",
                +        "name": "VALUE",
                +        "check": "String"
                +      },
                +      {
                +        "type": "input_dummy",
                +        "name": "AT"
                +      }
                +    ],
                +    "output": "String",
                +    "colour": "%{BKY_TEXTS_HUE}",
                +    "helpUrl": "%{BKY_TEXT_CHARAT_HELPURL}",
                +    "inputsInline": true,
                +    "mutator": "text_charAt_mutator"
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +Blockly.Blocks['text_getSubstring'] = {
                +  /**
                +   * Block for getting substring.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this['WHERE_OPTIONS_1'] = [
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START, 'FROM_START'],
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END, 'FROM_END'],
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST, 'FIRST']
                +    ];
                +    this['WHERE_OPTIONS_2'] = [
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START, 'FROM_START'],
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END, 'FROM_END'],
                +      [Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST, 'LAST']
                +    ];
                +    this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);
                +    this.setColour(Blockly.Blocks.texts.HUE);
                +    this.appendValueInput('STRING')
                +        .setCheck('String')
                +        .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);
                +    this.appendDummyInput('AT1');
                +    this.appendDummyInput('AT2');
                +    if (Blockly.Msg.TEXT_GET_SUBSTRING_TAIL) {
                +      this.appendDummyInput('TAIL')
                +          .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);
                +    }
                +    this.setInputsInline(true);
                +    this.setOutput(true, 'String');
                +    this.updateAt_(1, true);
                +    this.updateAt_(2, true);
                +    this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP);
                +  },
                +  /**
                +   * Create XML to represent whether there are 'AT' inputs.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at1', isAt1);
                +    var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at2', isAt2);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'AT' inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    var isAt1 = (xmlElement.getAttribute('at1') == 'true');
                +    var isAt2 = (xmlElement.getAttribute('at2') == 'true');
                +    this.updateAt_(1, isAt1);
                +    this.updateAt_(2, isAt2);
                +  },
                +  /**
                +   * Create or delete an input for a numeric index.
                +   * This block has two such inputs, independant of each other.
                +   * @param {number} n Specify first or second input (1 or 2).
                +   * @param {boolean} isAt True if the input should exist.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateAt_: function(n, isAt) {
                +    // Create or delete an input for the numeric index.
                +    // Destroy old 'AT' and 'ORDINAL' inputs.
                +    this.removeInput('AT' + n);
                +    this.removeInput('ORDINAL' + n, true);
                +    // Create either a value 'AT' input or a dummy input.
                +    if (isAt) {
                +      this.appendValueInput('AT' + n).setCheck('Number');
                +      if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
                +        this.appendDummyInput('ORDINAL' + n)
                +            .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
                +      }
                +    } else {
                +      this.appendDummyInput('AT' + n);
                +    }
                +    // Move tail, if present, to end of block.
                +    if (n == 2 && Blockly.Msg.TEXT_GET_SUBSTRING_TAIL) {
                +      this.removeInput('TAIL', true);
                +      this.appendDummyInput('TAIL')
                +          .appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);
                +    }
                +    var menu = new Blockly.FieldDropdown(this['WHERE_OPTIONS_' + n],
                +        function(value) {
                +          var newAt = (value == 'FROM_START') || (value == 'FROM_END');
                +          // The 'isAt' variable is available due to this function being a
                +          // closure.
                +          if (newAt != isAt) {
                +            var block = this.sourceBlock_;
                +            block.updateAt_(n, newAt);
                +            // This menu has been destroyed and replaced.
                +            // Update the replacement.
                +            block.setFieldValue(value, 'WHERE' + n);
                +            return null;
                +          }
                +          return undefined;
                +        });
                +
                +    this.getInput('AT' + n)
                +        .appendField(menu, 'WHERE' + n);
                +    if (n == 1) {
                +      this.moveInputBefore('AT1', 'AT2');
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['text_changeCase'] = {
                +  /**
                +   * Block for changing capitalization.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var OPERATORS = [
                +      [Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE, 'UPPERCASE'],
                +      [Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE, 'LOWERCASE'],
                +      [Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE, 'TITLECASE']
                +    ];
                +    this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);
                +    this.setColour(Blockly.Blocks.texts.HUE);
                +    this.appendValueInput('TEXT')
                +        .setCheck('String')
                +        .appendField(new Blockly.FieldDropdown(OPERATORS), 'CASE');
                +    this.setOutput(true, 'String');
                +    this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP);
                +  }
                +};
                +
                +Blockly.Blocks['text_trim'] = {
                +  /**
                +   * Block for trimming spaces.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var OPERATORS = [
                +      [Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH, 'BOTH'],
                +      [Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT, 'LEFT'],
                +      [Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT, 'RIGHT']
                +    ];
                +    this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);
                +    this.setColour(Blockly.Blocks.texts.HUE);
                +    this.appendValueInput('TEXT')
                +        .setCheck('String')
                +        .appendField(new Blockly.FieldDropdown(OPERATORS), 'MODE');
                +    this.setOutput(true, 'String');
                +    this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP);
                +  }
                +};
                +
                +Blockly.Blocks['text_print'] = {
                +  /**
                +   * Block for print statement.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.jsonInit({
                +      "message0": Blockly.Msg.TEXT_PRINT_TITLE,
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "TEXT"
                +        }
                +      ],
                +      "previousStatement": null,
                +      "nextStatement": null,
                +      "colour": Blockly.Blocks.texts.HUE,
                +      "tooltip": Blockly.Msg.TEXT_PRINT_TOOLTIP,
                +      "helpUrl": Blockly.Msg.TEXT_PRINT_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['text_prompt_ext'] = {
                +  /**
                +   * Block for prompt function (external message).
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    var TYPES = [
                +      [Blockly.Msg.TEXT_PROMPT_TYPE_TEXT, 'TEXT'],
                +      [Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER, 'NUMBER']
                +    ];
                +    this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);
                +    this.setColour(Blockly.Blocks.texts.HUE);
                +    // Assign 'this' to a variable for use in the closures below.
                +    var thisBlock = this;
                +    var dropdown = new Blockly.FieldDropdown(TYPES, function(newOp) {
                +      thisBlock.updateType_(newOp);
                +    });
                +    this.appendValueInput('TEXT')
                +        .appendField(dropdown, 'TYPE');
                +    this.setOutput(true, 'String');
                +    this.setTooltip(function() {
                +      return (thisBlock.getFieldValue('TYPE') == 'TEXT') ?
                +          Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT :
                +          Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER;
                +    });
                +  },
                +  /**
                +   * Modify this block to have the correct output type.
                +   * @param {string} newOp Either 'TEXT' or 'NUMBER'.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateType_: function(newOp) {
                +    this.outputConnection.setCheck(newOp == 'NUMBER' ? 'Number' : 'String');
                +  },
                +  /**
                +   * Create XML to represent the output type.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('type', this.getFieldValue('TYPE'));
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the output type.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.updateType_(xmlElement.getAttribute('type'));
                +  }
                +};
                +
                +Blockly.Blocks['text_prompt'] = {
                +  /**
                +   * Block for prompt function (internal message).
                +   * The 'text_prompt_ext' block is preferred as it is more flexible.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);
                +    var TYPES = [
                +      [Blockly.Msg.TEXT_PROMPT_TYPE_TEXT, 'TEXT'],
                +      [Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER, 'NUMBER']
                +    ];
                +
                +    // Assign 'this' to a variable for use in the closures below.
                +    var thisBlock = this;
                +    this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);
                +    this.setColour(Blockly.Blocks.texts.HUE);
                +    var dropdown = new Blockly.FieldDropdown(TYPES, function(newOp) {
                +      thisBlock.updateType_(newOp);
                +    });
                +    this.appendDummyInput()
                +        .appendField(dropdown, 'TYPE')
                +        .appendField(this.newQuote_(true))
                +        .appendField(new Blockly.FieldTextInput(''), 'TEXT')
                +        .appendField(this.newQuote_(false));
                +    this.setOutput(true, 'String');
                +    this.setTooltip(function() {
                +      return (thisBlock.getFieldValue('TYPE') == 'TEXT') ?
                +          Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT :
                +          Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER;
                +    });
                +  },
                +  updateType_: Blockly.Blocks['text_prompt_ext'].updateType_,
                +  mutationToDom: Blockly.Blocks['text_prompt_ext'].mutationToDom,
                +  domToMutation: Blockly.Blocks['text_prompt_ext'].domToMutation
                +};
                +
                +Blockly.Blocks['text_count'] = {
                +  /**
                +   * Block for counting how many times one string appears within another string.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.jsonInit({
                +      "message0": Blockly.Msg.TEXT_COUNT_MESSAGE0,
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "SUB",
                +          "check": "String"
                +        },
                +        {
                +          "type": "input_value",
                +          "name": "TEXT",
                +          "check": "String"
                +        }
                +      ],
                +      "output": "Number",
                +      "inputsInline": true,
                +      "colour": Blockly.Blocks.texts.HUE,
                +      "tooltip": Blockly.Msg.TEXT_COUNT_TOOLTIP,
                +      "helpUrl": Blockly.Msg.TEXT_COUNT_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['text_replace'] = {
                +  /**
                +   * Block for replacing one string with another in the text.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.jsonInit({
                +      "message0": Blockly.Msg.TEXT_REPLACE_MESSAGE0,
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "FROM",
                +          "check": "String"
                +        },
                +        {
                +          "type": "input_value",
                +          "name": "TO",
                +          "check": "String"
                +        },
                +        {
                +          "type": "input_value",
                +          "name": "TEXT",
                +          "check": "String"
                +        }
                +      ],
                +      "output": "String",
                +      "inputsInline": true,
                +      "colour": Blockly.Blocks.texts.HUE,
                +      "tooltip": Blockly.Msg.TEXT_REPLACE_TOOLTIP,
                +      "helpUrl": Blockly.Msg.TEXT_REPLACE_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['text_reverse'] = {
                +  /**
                +   * Block for reversing a string.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.jsonInit({
                +      "message0": Blockly.Msg.TEXT_REVERSE_MESSAGE0,
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "TEXT",
                +          "check": "String"
                +        }
                +      ],
                +      "output": "String",
                +      "inputsInline": true,
                +      "colour": Blockly.Blocks.texts.HUE,
                +      "tooltip": Blockly.Msg.TEXT_REVERSE_TOOLTIP,
                +      "helpUrl": Blockly.Msg.TEXT_REVERSE_HELPURL
                +    });
                +  }
                +};
                +
                +/**
                + *
                + * @mixin
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Text.QUOTE_IMAGE_MIXIN = {
                +  /**
                +   * Image data URI of an LTR opening double quote (same as RTL closing couble quote).
                +   * @readonly
                +   */
                +  QUOTE_IMAGE_LEFT_DATAURI:
                +    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC',
                +  /**
                +   * Image data URI of an LTR closing double quote (same as RTL opening couble quote).
                +   * @readonly
                +   */
                +  QUOTE_IMAGE_RIGHT_DATAURI:
                +    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==',
                +  /**
                +   * Pixel width of QUOTE_IMAGE_LEFT_DATAURI and QUOTE_IMAGE_RIGHT_DATAURI.
                +   * @readonly
                +   */
                +  QUOTE_IMAGE_WIDTH: 12,
                +  /**
                +   * Pixel height of QUOTE_IMAGE_LEFT_DATAURI and QUOTE_IMAGE_RIGHT_DATAURI.
                +   * @readonly
                +   */
                +  QUOTE_IMAGE_HEIGHT: 12,
                +
                +  /**
                +   * Inserts appropriate quote images before and after the named field.
                +   * @param {string} fieldName The name of the field to wrap with quotes.
                +   */
                +  quoteField_: function(fieldName) {
                +    for (var i = 0, input; input = this.inputList[i]; i++) {
                +      for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +        if (fieldName == field.name) {
                +          input.insertFieldAt(j, this.newQuote_(true));
                +          input.insertFieldAt(j + 2, this.newQuote_(false));
                +          return;
                +        }
                +      }
                +    }
                +    console.warn('field named "' + fieldName + '" not found in ' + this.toDevString());
                +  },
                +
                +  /**
                +   * A helper function that generates a FieldImage of an opening or
                +   * closing double quote. The selected quote will be adapted for RTL blocks.
                +   * @param {boolean} open If the image should be open quote (“ in LTR).
                +   *                       Otherwise, a closing quote is used (” in LTR).
                +   * @returns {!Blockly.FieldImage} The new field.
                +   */
                +  newQuote_: function(open) {
                +    var isLeft = this.RTL? !open : open;
                +    var dataUri = isLeft ?
                +      this.QUOTE_IMAGE_LEFT_DATAURI :
                +      this.QUOTE_IMAGE_RIGHT_DATAURI;
                +    return new Blockly.FieldImage(
                +      dataUri,
                +      this.QUOTE_IMAGE_WIDTH,
                +      this.QUOTE_IMAGE_HEIGHT,
                +      isLeft ? '\u201C' : '\u201D');
                +  }
                +};
                +
                +/** Wraps TEXT field with images of double quote characters. */
                +Blockly.Constants.Text.TEXT_QUOTES_EXTENSION = function() {
                +  this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);
                +  this.quoteField_('TEXT');
                +};
                +
                +/**
                + * Mixin for mutator functions in the 'text_join_mutator' extension.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
                +  /**
                +   * Create XML to represent number of text inputs.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('items', this.itemCount_);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the text inputs.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
                +    this.updateShape_();
                +  },
                +  /**
                +   * Populate the mutator's dialog with this block's components.
                +   * @param {!Blockly.Workspace} workspace Mutator's workspace.
                +   * @return {!Blockly.Block} Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  decompose: function(workspace) {
                +    var containerBlock = workspace.newBlock('text_create_join_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      var itemBlock = workspace.newBlock('text_create_join_item');
                +      itemBlock.initSvg();
                +      connection.connect(itemBlock.previousConnection);
                +      connection = itemBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  /**
                +   * Reconfigure this block based on the mutator dialog's components.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  compose: function(containerBlock) {
                +    var itemBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    var connections = [];
                +    while (itemBlock) {
                +      connections.push(itemBlock.valueConnection_);
                +      itemBlock = itemBlock.nextConnection &&
                +          itemBlock.nextConnection.targetBlock();
                +    }
                +    // Disconnect any children that don't belong.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      var connection = this.getInput('ADD' + i).connection.targetConnection;
                +      if (connection && connections.indexOf(connection) == -1) {
                +        connection.disconnect();
                +      }
                +    }
                +    this.itemCount_ = connections.length;
                +    this.updateShape_();
                +    // Reconnect any child blocks.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i);
                +    }
                +  },
                +  /**
                +   * Store pointers to any connected child blocks.
                +   * @param {!Blockly.Block} containerBlock Root block in mutator.
                +   * @this Blockly.Block
                +   */
                +  saveConnections: function(containerBlock) {
                +    var itemBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (itemBlock) {
                +      var input = this.getInput('ADD' + i);
                +      itemBlock.valueConnection_ = input && input.connection.targetConnection;
                +      i++;
                +      itemBlock = itemBlock.nextConnection &&
                +          itemBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  /**
                +   * Modify this block to have the correct number of inputs.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateShape_: function() {
                +    if (this.itemCount_ && this.getInput('EMPTY')) {
                +      this.removeInput('EMPTY');
                +    } else if (!this.itemCount_ && !this.getInput('EMPTY')) {
                +      this.appendDummyInput('EMPTY')
                +          .appendField(this.newQuote_(true))
                +          .appendField(this.newQuote_(false));
                +    }
                +    // Add new inputs.
                +    for (var i = 0; i < this.itemCount_; i++) {
                +      if (!this.getInput('ADD' + i)) {
                +        var input = this.appendValueInput('ADD' + i);
                +        if (i == 0) {
                +          input.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH);
                +        }
                +      }
                +    }
                +    // Remove deleted inputs.
                +    while (this.getInput('ADD' + i)) {
                +      this.removeInput('ADD' + i);
                +      i++;
                +    }
                +  }
                +};
                +
                +// Performs final setup of a text_join block.
                +Blockly.Constants.Text.TEXT_JOIN_EXTENSION = function() {
                +  // Add the quote mixin for the itemCount_ = 0 case.
                +  this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);
                +  // initialize the mutator values
                +  this.itemCount_ = 2;
                +  this.updateShape_();
                +  // Configure the mutator ui
                +  this.setMutator(new Blockly.Mutator(['text_create_join_item']));
                +};
                +
                +Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION = function() {
                +  // Assign 'this' to a variable for use in the tooltip closure below.
                +  var thisBlock = this;
                +  this.setTooltip(function() {
                +    if (Blockly.Msg.TEXT_APPEND_TOOLTIP) {
                +      return Blockly.Msg.TEXT_APPEND_TOOLTIP.replace('%1',
                +          thisBlock.getFieldValue('VAR'));
                +    }
                +    return '';
                +  });
                +};
                +
                +Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION = function() {
                +  // Assign 'this' to a variable for use in the tooltip closure below.
                +  var thisBlock = this;
                +  this.setTooltip(function() {
                +    return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace('%1',
                +        thisBlock.workspace.options.oneBasedIndex ? '0' : '-1');
                +  });
                +};
                +
                +/**
                + * Mixin for mutator functions in the 'text_charAt_mutator' extension.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + */
                +Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
                +  /**
                +   * Create XML to represent whether there is an 'AT' input.
                +   * @return {!Element} XML storage element.
                +   * @this Blockly.Block
                +   */
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
                +    container.setAttribute('at', isAt);
                +    return container;
                +  },
                +  /**
                +   * Parse XML to restore the 'AT' input.
                +   * @param {!Element} xmlElement XML storage element.
                +   * @this Blockly.Block
                +   */
                +  domToMutation: function(xmlElement) {
                +    // Note: Until January 2013 this block did not have mutations,
                +    // so 'at' defaults to true.
                +    var isAt = (xmlElement.getAttribute('at') != 'false');
                +    this.updateAt_(isAt);
                +  },
                +  /**
                +   * Create or delete an input for the numeric index.
                +   * @param {boolean} isAt True if the input should exist.
                +   * @private
                +   * @this Blockly.Block
                +   */
                +  updateAt_: function(isAt) {
                +    // Destroy old 'AT' and 'ORDINAL' inputs.
                +    this.removeInput('AT');
                +    this.removeInput('ORDINAL', true);
                +    // Create either a value 'AT' input or a dummy input.
                +    if (isAt) {
                +      this.appendValueInput('AT').setCheck('Number');
                +      if (Blockly.Msg.ORDINAL_NUMBER_SUFFIX) {
                +        this.appendDummyInput('ORDINAL')
                +            .appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
                +      }
                +    } else {
                +      this.appendDummyInput('AT');
                +    }
                +    if (Blockly.Msg.TEXT_CHARAT_TAIL) {
                +      this.removeInput('TAIL', true);
                +      this.appendDummyInput('TAIL')
                +          .appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
                +    }
                +    var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
                +      var newAt = (value == 'FROM_START') || (value == 'FROM_END');
                +      // The 'isAt' variable is available due to this function being a closure.
                +      if (newAt != isAt) {
                +        var block = this.sourceBlock_;
                +        block.updateAt_(newAt);
                +        // This menu has been destroyed and replaced.  Update the replacement.
                +        block.setFieldValue(value, 'WHERE');
                +        return null;
                +      }
                +      return undefined;
                +    });
                +    this.getInput('AT').appendField(menu, 'WHERE');
                +  }
                +};
                +
                +// Does the initial mutator update of text_charAt and adds the tooltip
                +Blockly.Constants.Text.TEXT_CHARAT_EXTENSION = function() {
                +    this.WHERE_OPTIONS = [
                +        [Blockly.Msg.TEXT_CHARAT_FROM_START, 'FROM_START'],
                +        [Blockly.Msg.TEXT_CHARAT_FROM_END, 'FROM_END'],
                +        [Blockly.Msg.TEXT_CHARAT_FIRST, 'FIRST'],
                +        [Blockly.Msg.TEXT_CHARAT_LAST, 'LAST'],
                +        [Blockly.Msg.TEXT_CHARAT_RANDOM, 'RANDOM']
                +      ];
                +    this.updateAt_(true);
                +    // Assign 'this' to a variable for use in the tooltip closure below.
                +    var thisBlock = this;
                +    this.setTooltip(function() {
                +      var where = thisBlock.getFieldValue('WHERE');
                +      var tooltip = Blockly.Msg.TEXT_CHARAT_TOOLTIP;
                +      if (where == 'FROM_START' || where == 'FROM_END') {
                +        var msg = (where == 'FROM_START') ?
                +            Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP :
                +            Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP;
                +        if (msg) {
                +          tooltip += '  ' + msg.replace('%1',
                +              thisBlock.workspace.options.oneBasedIndex ? '#1' : '#0');
                +        }
                +      }
                +      return tooltip;
                +    });
                +};
                +
                +Blockly.Extensions.register('text_indexOf_tooltip',
                +  Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);
                +
                +Blockly.Extensions.register('text_quotes',
                +  Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);
                +
                +Blockly.Extensions.register('text_append_tooltip',
                +  Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);
                +
                +Blockly.Extensions.registerMutator('text_join_mutator',
                +  Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,
                +  Blockly.Constants.Text.TEXT_JOIN_EXTENSION);
                +
                +Blockly.Extensions.registerMutator('text_charAt_mutator',
                +  Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,
                +  Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/blocks/variables.js b/blockly/webif/static/blockly/blocks/variables.js
                new file mode 100644
                index 000000000..07ae8e6e5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks/variables.js
                @@ -0,0 +1,127 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Variable blocks for Blockly.
                +
                + * This file is scraped to extract a .json file of block definitions. The array
                + * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes
                + * only, no outside references, no functions, no trailing commas, etc. The one
                + * exception is end-of-line comments, which the scraper will remove.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.variables');  // Deprecated.
                +goog.provide('Blockly.Constants.Variables');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Common HSV hue for all blocks in this category.
                + * Should be the same as Blockly.Msg.VARIABLES_HUE.
                + * @readonly
                + */
                +Blockly.Constants.Variables.HUE = 330;
                +/** @deprecated Use Blockly.Constants.Variables.HUE */
                +Blockly.Blocks.variables.HUE = Blockly.Constants.Variables.HUE;
                +
                +Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
                +  // Block for variable getter.
                +  {
                +    "type": "variables_get",
                +    "message0": "%1",
                +    "args0": [
                +      {
                +        "type": "field_variable",
                +        "name": "VAR",
                +        "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
                +      }
                +    ],
                +    "output": null,
                +    "colour": "%{BKY_VARIABLES_HUE}",
                +    "helpUrl": "%{BKY_VARIABLES_GET_HELPURL}",
                +    "tooltip": "%{BKY_VARIABLES_GET_TOOLTIP}",
                +    "extensions": ["contextMenu_variableSetterGetter"]
                +  },
                +  // Block for variable setter.
                +  {
                +    "type": "variables_set",
                +    "message0": "%{BKY_VARIABLES_SET}",
                +    "args0": [
                +      {
                +        "type": "field_variable",
                +        "name": "VAR",
                +        "variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
                +      },
                +      {
                +        "type": "input_value",
                +        "name": "VALUE"
                +      }
                +    ],
                +    "previousStatement": null,
                +    "nextStatement": null,
                +    "colour": "%{BKY_VARIABLES_HUE}",
                +    "tooltip": "%{BKY_VARIABLES_SET_TOOLTIP}",
                +    "helpUrl": "%{BKY_VARIABLES_SET_HELPURL}",
                +    "extensions": ["contextMenu_variableSetterGetter"]
                +  }
                +]);  // END JSON EXTRACT (Do not delete this comment.)
                +
                +/**
                + * Mixin to add context menu items to create getter/setter blocks for this
                + * setter/getter.
                + * Used by blocks 'variables_set' and 'variables_get'.
                + * @mixin
                + * @augments Blockly.Block
                + * @package
                + * @readonly
                + */
                +Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
                +  /**
                +   * Add menu option to create getter/setter block for this setter/getter.
                +   * @param {!Array} options List of menu options to add to.
                +   * @this Blockly.Block
                +   */
                +  customContextMenu: function(options) {
                +    // Getter blocks have the option to create a setter block, and vice versa.
                +    if (this.type == 'variables_get') {
                +      var opposite_type = 'variables_set';
                +      var contextMenuMsg = Blockly.Msg.VARIABLES_GET_CREATE_SET;
                +    } else {
                +      var opposite_type = 'variables_get';
                +      var contextMenuMsg = Blockly.Msg.VARIABLES_SET_CREATE_GET;
                +    }
                +
                +    var option = {enabled: this.workspace.remainingCapacity() > 0};
                +    var name = this.getFieldValue('VAR');
                +    option.text = contextMenuMsg.replace('%1', name);
                +    var xmlField = goog.dom.createDom('field', null, name);
                +    xmlField.setAttribute('name', 'VAR');
                +    var xmlBlock = goog.dom.createDom('block', null, xmlField);
                +    xmlBlock.setAttribute('type', opposite_type);
                +    option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
                +    options.push(option);
                +  }
                +};
                +
                +Blockly.Extensions.registerMixin('contextMenu_variableSetterGetter',
                +  Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
                diff --git a/blockly/webif/static/blockly/blocks_compressed.js b/blockly/webif/static/blockly/blocks_compressed.js
                new file mode 100644
                index 000000000..d1439adc2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/blocks_compressed.js
                @@ -0,0 +1,174 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Editor
                +
                + Copyright 2012 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Blocks.colour={};Blockly.Constants={};Blockly.Constants.Colour={};Blockly.Constants.Colour.HUE=20;Blockly.Blocks.colour.HUE=Blockly.Constants.Colour.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"colour_picker",message0:"%1",args0:[{type:"field_colour",name:"COLOUR",colour:"#ff0000"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_PICKER_HELPURL}",tooltip:"%{BKY_COLOUR_PICKER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"colour_random",message0:"%{BKY_COLOUR_RANDOM_TITLE}",output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RANDOM_HELPURL}",tooltip:"%{BKY_COLOUR_RANDOM_TOOLTIP}"},{type:"colour_rgb",message0:"%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3",
                +args0:[{type:"input_value",name:"RED",check:"Number",align:"RIGHT"},{type:"input_value",name:"GREEN",check:"Number",align:"RIGHT"},{type:"input_value",name:"BLUE",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RGB_HELPURL}",tooltip:"%{BKY_COLOUR_RGB_TOOLTIP}"},{type:"colour_blend",message0:"%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",args0:[{type:"input_value",name:"COLOUR1",
                +check:"Colour",align:"RIGHT"},{type:"input_value",name:"COLOUR2",check:"Colour",align:"RIGHT"},{type:"input_value",name:"RATIO",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_BLEND_HELPURL}",tooltip:"%{BKY_COLOUR_BLEND_TOOLTIP}"}]);Blockly.Blocks.lists={};Blockly.Constants.Lists={};Blockly.Constants.Lists.HUE=260;Blockly.Blocks.lists.HUE=Blockly.Constants.Lists.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LISTS_CREATE_EMPTY_TITLE}",output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_CREATE_EMPTY_HELPURL}"},{type:"lists_repeat",message0:"%{BKY_LISTS_REPEAT_TITLE}",args0:[{type:"input_value",name:"ITEM"},{type:"input_value",name:"NUM",check:"Number"}],output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_LISTS_REPEAT_HELPURL}"},{type:"lists_reverse",
                +message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",
                +message0:"%{BKY_LISTS_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
                +Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
                +10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
                +c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
                +this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
                +Blockly.Blocks.lists_create_with_container={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
                +Blockly.Blocks.lists_create_with_item={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);this.contextMenu=!1}};
                +Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
                +b.workspace.options.oneBasedIndex?"0":"-1")})}};
                +Blockly.Blocks.lists_getIndex={init:function(){var a=[[Blockly.Msg.LISTS_GET_INDEX_GET,"GET"],[Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE,"GET_REMOVE"],[Blockly.Msg.LISTS_GET_INDEX_REMOVE,"REMOVE"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
                +a=new Blockly.FieldDropdown(a,function(a){this.sourceBlock_.updateStatement_("REMOVE"==a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
                +b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "GET FROM_START":case "GET FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;break;case "GET FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;break;case "GET LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;break;case "GET RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;break;case "GET_REMOVE FROM_START":case "GET_REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;break;case "GET_REMOVE FIRST":e=
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;break;case "GET_REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;break;case "GET_REMOVE RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;break;case "REMOVE FROM_START":case "REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;break;case "REMOVE FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;break;case "REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;break;case "REMOVE RANDOM":e=
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+="  "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b="true"==
                +a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
                +this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
                +Blockly.Blocks.lists_setIndex={init:function(){var a=[[Blockly.Msg.LISTS_SET_INDEX_SET,"SET"],[Blockly.Msg.LISTS_SET_INDEX_INSERT,"INSERT"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
                +this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"MODE").appendField("","SPACE");this.appendDummyInput("AT");this.appendValueInput("TO").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "SET FROM_START":case "SET FROM_END":e=
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;break;case "SET FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;break;case "SET LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;break;case "SET RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;break;case "INSERT FROM_START":case "INSERT FROM_END":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;break;case "INSERT FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;break;case "INSERT LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
                +break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+="  "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
                +this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
                +"TO");this.getInput("AT").appendField(b,"WHERE")}};
                +Blockly.Blocks.lists_getSublist={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
                +this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT1").type==
                +Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
                +this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
                +Blockly.Blocks.lists_sort={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_SORT_TITLE,args0:[{type:"field_dropdown",name:"TYPE",options:[[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC,"NUMERIC"],[Blockly.Msg.LISTS_SORT_TYPE_TEXT,"TEXT"],[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE,"IGNORE_CASE"]]},{type:"field_dropdown",name:"DIRECTION",options:[[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING,"1"],[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING,"-1"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Array",colour:Blockly.Blocks.lists.HUE,
                +tooltip:Blockly.Msg.LISTS_SORT_TOOLTIP,helpUrl:Blockly.Msg.LISTS_SORT_HELPURL})}};
                +Blockly.Blocks.lists_split={init:function(){var a=this,b=new Blockly.FieldDropdown([[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT,"SPLIT"],[Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST,"JOIN"]],function(b){a.updateType_(b)});this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("INPUT").setCheck("String").appendField(b,"MODE");this.appendValueInput("DELIM").setCheck("String").appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);this.setInputsInline(!0);
                +this.setOutput(!0,"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw"Unknown mode: "+b;})},updateType_:function(a){"SPLIT"==a?(this.outputConnection.setCheck("Array"),this.getInput("INPUT").setCheck("String")):(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("mode",
                +this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;Blockly.Blocks.logic.HUE=Blockly.Constants.Logic.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"logic_boolean",message0:"%1",args0:[{type:"field_dropdown",name:"BOOL",options:[["%{BKY_LOGIC_BOOLEAN_TRUE}","TRUE"],["%{BKY_LOGIC_BOOLEAN_FALSE}","FALSE"]]}],output:"Boolean",colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_BOOLEAN_TOOLTIP}",helpUrl:"%{BKY_LOGIC_BOOLEAN_HELPURL}"},{type:"controls_if",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",
                +name:"DO0"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null,nextStatement:null,
                +colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["<","LT"],["\u2264","LTE"],[">","GT"],["\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
                +"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Boolean"},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:"Boolean"}],inputsInline:!0,output:"Boolean",colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL",
                +check:"Boolean"}],output:"Boolean",colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}],
                +message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1",args2:[{type:"input_value",name:"ELSE"}],output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]);
                +Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null,
                +enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
                +Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
                +Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=document.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.updateShape_()},decompose:function(a){var b=a.newBlock("controls_if_if");
                +b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){var b=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;a=[null];for(var c=[null],d=null;b;){switch(b.type){case "controls_if_elseif":this.elseifCount_++;a.push(b.valueConnection_);c.push(b.statementConnection_);
                +break;case "controls_if_else":this.elseCount_++;d=b.statementConnection_;break;default:throw"Unknown block type.";}b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateShape_();for(b=1;b<=this.elseifCount_;b++)Blockly.Mutator.reconnect(a[b],this,"IF"+b),Blockly.Mutator.reconnect(c[b],this,"DO"+b);Blockly.Mutator.reconnect(d,this,"ELSE")},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+
                +b);a.valueConnection_=c&&c.connection.targetConnection;a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw"Unknown block type.";}a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+
                +a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
                +Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
                +Blockly.Constants.Logic.fixLogicCompareRtlOpLabels=function(){var a={LT:"\u200f<\u200f",LTE:"\u200f\u2264\u200f",GT:"\u200f>\u200f",GTE:"\u200f\u2265\u200f"},b=this.getField("OP");if(b)for(var b=b.getOptions(),c=0;c<b.length;++c){var d=b[c],e=a[d[1]];goog.isString(d[0])&&e&&(d[0]=e)}};
                +Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={prevBlocks_:[null,null],onchange:function(a){var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");if(b&&c&&!b.outputConnection.checkType_(c.outputConnection)){Blockly.Events.setGroup(a.group);for(a=0;a<this.prevBlocks_.length;a++){var d=this.prevBlocks_[a];if(d===b||d===c)d.unplug(),d.bumpNeighbours_()}Blockly.Events.setGroup(!1)}this.prevBlocks_[0]=b;this.prevBlocks_[1]=c}};
                +Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.RTL&&Blockly.Constants.Logic.fixLogicCompareRtlOpLabels.apply(this);this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
                +Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN={prevParentConnection_:null,onchange:function(a){var b=this.getInputTargetBlock("THEN"),c=this.getInputTargetBlock("ELSE"),d=this.outputConnection.targetConnection;if((b||c)&&d)for(var e=0;2>e;e++){var f=1==e?b:c;f&&!f.outputConnection.checkType_(d)&&(Blockly.Events.setGroup(a.group),d===this.prevParentConnection_?(this.unplug(),d.getSourceBlock().bumpNeighbours_()):(f.unplug(),f.bumpNeighbours_()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
                +d}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;Blockly.Blocks.loops.HUE=Blockly.Constants.Loops.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"controls_repeat_ext",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"input_value",name:"TIMES",check:"Number"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_repeat",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"field_number",name:"TIMES",
                +value:10,min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_whileUntil",message0:"%1 %2",args0:[{type:"field_dropdown",name:"MODE",options:[["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}","WHILE"],["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}","UNTIL"]]},{type:"input_value",name:"BOOL",
                +check:"Boolean"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",
                +name:"BY",check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],inputsInline:!0,previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOR_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_for_tooltip"]},{type:"controls_forEach",message0:"%{BKY_CONTROLS_FOREACH_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"LIST",check:"Array"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
                +args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,colour:"%{BKY_LOOPS_HUE}",
                +helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
                +Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
                +Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){var b=this.getFieldValue("VAR");if(!this.isCollapsed()&&null!=b){var c={enabled:!0};c.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",b);b=goog.dom.createDom("field",null,b);b.setAttribute("name","VAR");b=goog.dom.createDom("block",null,b);b.setAttribute("type","variables_get");c.callback=Blockly.ContextMenu.callbackFactory(this,b);a.push(c)}}};
                +Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldValue(Blockly.Msg.CONTROLS_FOR_TOOLTIP,"VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldValue(Blockly.Msg.CONTROLS_FOREACH_TOOLTIP,"VAR"));
                +Blockly.Constants.Loops.CONTROL_FLOW_CHECK_IN_LOOP_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.LOOP_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?(this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||
                +this.getInheritedDisabled()||this.setDisabled(!0))}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;Blockly.Blocks.math.HUE=Blockly.Constants.Math.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
                +"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
                +{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",
                +helpUrl:"%{BKY_MATH_TRIG_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_constant",message0:"%1",args0:[{type:"field_dropdown",name:"CONSTANT",options:[["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]}],output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTANT_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTANT_HELPURL}"},{type:"math_number_property",message0:"%1 %2",args0:[{type:"input_value",name:"NUMBER_TO_CHECK",check:"Number"},
                +{type:"field_dropdown",name:"PROPERTY",options:[["%{BKY_MATH_IS_EVEN}","EVEN"],["%{BKY_MATH_IS_ODD}","ODD"],["%{BKY_MATH_IS_PRIME}","PRIME"],["%{BKY_MATH_IS_WHOLE}","WHOLE"],["%{BKY_MATH_IS_POSITIVE}","POSITIVE"],["%{BKY_MATH_IS_NEGATIVE}","NEGATIVE"],["%{BKY_MATH_IS_DIVISIBLE_BY}","DIVISIBLE_BY"]]}],inputsInline:!0,output:"Boolean",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_IS_TOOLTIP}",mutator:"math_is_divisibleby_mutator"},{type:"math_change",message0:"%{BKY_MATH_CHANGE_TITLE}",args0:[{type:"field_variable",
                +name:"VAR",variable:"%{BKY_MATH_CHANGE_TITLE_ITEM}"},{type:"input_value",name:"DELTA",check:"Number"}],previousStatement:null,nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_MATH_CHANGE_HELPURL}",extensions:["math_change_tooltip"]},{type:"math_round",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ROUND_OPERATOR_ROUND}","ROUND"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}","ROUNDUP"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}","ROUNDDOWN"]]},{type:"input_value",
                +name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ROUND_HELPURL}",tooltip:"%{BKY_MATH_ROUND_TOOLTIP}"},{type:"math_on_list",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ONLIST_OPERATOR_SUM}","SUM"],["%{BKY_MATH_ONLIST_OPERATOR_MIN}","MIN"],["%{BKY_MATH_ONLIST_OPERATOR_MAX}","MAX"],["%{BKY_MATH_ONLIST_OPERATOR_AVERAGE}","AVERAGE"],["%{BKY_MATH_ONLIST_OPERATOR_MEDIAN}","MEDIAN"],["%{BKY_MATH_ONLIST_OPERATOR_MODE}","MODE"],["%{BKY_MATH_ONLIST_OPERATOR_STD_DEV}",
                +"STD_DEV"],["%{BKY_MATH_ONLIST_OPERATOR_RANDOM}","RANDOM"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ONLIST_HELPURL}",mutator:"math_modes_of_list_mutator",extensions:["math_op_tooltip"]},{type:"math_modulo",message0:"%{BKY_MATH_MODULO_TITLE}",args0:[{type:"input_value",name:"DIVIDEND",check:"Number"},{type:"input_value",name:"DIVISOR",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_MODULO_TOOLTIP}",
                +helpUrl:"%{BKY_MATH_MODULO_HELPURL}"},{type:"math_constrain",message0:"%{BKY_MATH_CONSTRAIN_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"Number"},{type:"input_value",name:"LOW",check:"Number"},{type:"input_value",name:"HIGH",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTRAIN_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTRAIN_HELPURL}"},{type:"math_random_int",message0:"%{BKY_MATH_RANDOM_INT_TITLE}",args0:[{type:"input_value",name:"FROM",check:"Number"},
                +{type:"input_value",name:"TO",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_INT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_INT_HELPURL}"},{type:"math_random_float",message0:"%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}",output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_FLOAT_HELPURL}"}]);
                +Blockly.Constants.Math.TOOLTIPS_BY_OP={ADD:"%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}",MINUS:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}",MULTIPLY:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}",DIVIDE:"%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}",POWER:"%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}",ROOT:"%{BKY_MATH_SINGLE_TOOLTIP_ROOT}",ABS:"%{BKY_MATH_SINGLE_TOOLTIP_ABS}",NEG:"%{BKY_MATH_SINGLE_TOOLTIP_NEG}",LN:"%{BKY_MATH_SINGLE_TOOLTIP_LN}",LOG10:"%{BKY_MATH_SINGLE_TOOLTIP_LOG10}",EXP:"%{BKY_MATH_SINGLE_TOOLTIP_EXP}",POW10:"%{BKY_MATH_SINGLE_TOOLTIP_POW10}",
                +SIN:"%{BKY_MATH_TRIG_TOOLTIP_SIN}",COS:"%{BKY_MATH_TRIG_TOOLTIP_COS}",TAN:"%{BKY_MATH_TRIG_TOOLTIP_TAN}",ASIN:"%{BKY_MATH_TRIG_TOOLTIP_ASIN}",ACOS:"%{BKY_MATH_TRIG_TOOLTIP_ACOS}",ATAN:"%{BKY_MATH_TRIG_TOOLTIP_ATAN}",SUM:"%{BKY_MATH_ONLIST_TOOLTIP_SUM}",MIN:"%{BKY_MATH_ONLIST_TOOLTIP_MIN}",MAX:"%{BKY_MATH_ONLIST_TOOLTIP_MAX}",AVERAGE:"%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}",MEDIAN:"%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}",MODE:"%{BKY_MATH_ONLIST_TOOLTIP_MODE}",STD_DEV:"%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}",RANDOM:"%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}"};
                +Blockly.Extensions.register("math_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Math.TOOLTIPS_BY_OP));
                +Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
                +Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){this.sourceBlock_.updateShape_("DIVISIBLE_BY"==a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Constants.Math.CHANGE_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace("%1",this.getFieldValue("VAR"))}.bind(this))};
                +Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldValue(Blockly.Msg.MATH_CHANGE_TOOLTIP,"VAR"));Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};
                +Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};Blockly.Blocks.procedures.HUE=290;
                +Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&
                +this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK",
                +"RETURN")):this.removeInput("STACK",!0),this.hasStatements_=a)},updateParams_:function(){for(var a=!1,b={},c=0;c<this.arguments_.length;c++){if(b["arg_"+this.arguments_[c].toLowerCase()]){a=!0;break}b["arg_"+this.arguments_[c].toLowerCase()]=!0}a?this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING):this.setWarningText(null);a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},
                +mutationToDom:function(a){var b=document.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.arguments_.length;c++){var d=document.createElement("arg");d.setAttribute("name",this.arguments_[c]);a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];for(var b=0,c;c=a.childNodes[b];b++)"arg"==c.nodeName.toLowerCase()&&
                +this.arguments_.push(c.getAttribute("name"));this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=a.newBlock("procedures_mutatorcontainer");b.initSvg();this.getInput("RETURN")?b.setFieldValue(this.hasStatements_?"TRUE":"FALSE","STATEMENTS"):b.getInput("STATEMENT_INPUT").setVisible(!1);for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=a.newBlock("procedures_mutatorarg");e.initSvg();
                +e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];for(var b=a.getInputTargetBlock("STACK");b;)this.arguments_.push(b.getFieldValue("NAME")),this.paramIds_.push(b.id),b=b.nextConnection&&b.nextConnection.targetBlock();this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,
                +this.hasStatements_!=a))if(a)this.setStatements_(!0),Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours_();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},renameVar:function(a,b){for(var c=!1,d=0;d<this.arguments_.length;d++)Blockly.Names.equals(a,
                +this.arguments_[d])&&(this.arguments_[d]=b,c=!0);if(c&&(this.updateParams_(),this.mutator.isVisible()))for(var c=this.mutator.workspace_.getAllBlocks(),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){var b={enabled:!0};var c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=goog.dom.createDom("mutation");d.setAttribute("name",c);for(var e=0;e<this.arguments_.length;e++)c=
                +goog.dom.createDom("arg"),c.setAttribute("name",this.arguments_[e]),d.appendChild(c);d=goog.dom.createDom("block",null,d);d.setAttribute("type",this.callType_);b.callback=Blockly.ContextMenu.callbackFactory(this,d);a.push(b);if(!this.isCollapsed())for(e=0;e<this.arguments_.length;e++)b={enabled:!0},c=this.arguments_[e],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c),d=goog.dom.createDom("field",null,c),d.setAttribute("name","VAR"),d=goog.dom.createDom("block",null,d),d.setAttribute("type",
                +"variables_get"),b.callback=Blockly.ContextMenu.callbackFactory(this,d),a.push(b)},callType_:"procedures_callnoreturn"};
                +Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
                +this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
                +mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,renameVar:Blockly.Blocks.procedures_defnoreturn.renameVar,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,
                +callType_:"procedures_callreturn"};Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);this.appendStatementInput("STACK");this.appendDummyInput("STATEMENT_INPUT").appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS).appendField(new Blockly.FieldCheckbox("TRUE"),"STATEMENTS");this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);this.contextMenu=!1}};
                +Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput("x",this.validator_);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=!1;a.onFinishEditing_=this.createNewVar_;a.onFinishEditing_("x")},validator_:function(a){return(a=a.replace(/[\s\xa0]+/g,
                +" ").replace(/^ | $/g,""))||null},createNewVar_:function(a){var b=this.sourceBlock_;b&&b.workspace&&b.workspace.options&&b.workspace.options.parentWorkspace&&b.workspace.options.parentWorkspace.createVariable(a)}};
                +Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,this.getProcedureCall())&&(this.setFieldValue(b,
                +"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c,d=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),e=d&&d.mutator&&d.mutator.isVisible();e||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(goog.array.equals(this.arguments_,a))this.quarkIds_=b;else{if(b.length!=a.length)throw"Error: paramNames and paramIds must be the same length.";
                +this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},a.join("\n")==this.arguments_.join("\n")?this.quarkIds_=b:this.quarkIds_=[]);d=this.rendered;this.rendered=!1;for(var f=0;f<this.arguments_.length;f++)if(c=this.getInput("ARG"+f))c=c.connection.targetConnection,this.quarkConnections_[this.quarkIds_[f]]=c,e&&c&&-1==b.indexOf(this.quarkIds_[f])&&(c.disconnect(),c.getSourceBlock().bumpNeighbours_());this.arguments_=[].concat(a);this.updateShape_();if(this.quarkIds_=b)for(f=0;f<this.arguments_.length;f++)e=
                +this.quarkIds_[f],e in this.quarkConnections_&&(c=this.quarkConnections_[e],Blockly.Mutator.reconnect(c,this,"ARG"+f)||delete this.quarkConnections_[e]);(this.rendered=d)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,
                +"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("name",this.getProcedureCall());for(var b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);
                +a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);for(var b=[],c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},renameVar:function(a,b){for(var c=0;c<this.arguments_.length;c++)Blockly.Names.equals(a,this.arguments_[c])&&(this.arguments_[c]=b,this.getField("ARGNAME"+c).setValue(b))},onchange:function(a){if(this.workspace&&
                +!this.workspace.isFlyout)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.arguments_)==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=goog.dom.createDom("xml");b=goog.dom.createDom("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*
                +(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=goog.dom.createDom("field");c.setAttribute("name","NAME");c.appendChild(document.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE&&(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0,!1),Blockly.Events.setGroup(!1)))},
                +customContextMenu:function(a){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var a=Blockly.Procedures.getDefinition(c,d);a&&a.select()};a.push(b)},defType_:"procedures_defnoreturn"};
                +Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
                +updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,renameVar:Blockly.Blocks.procedures_callnoreturn.renameVar,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
                +Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},
                +mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
                +a?("procedures_defnoreturn"==b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),
                +this.isInFlyout||this.getInheritedDisabled()||this.setDisabled(!0))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;Blockly.Blocks.texts.HUE=Blockly.Constants.Text.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"text",message0:"%1",args0:[{type:"field_input",name:"TEXT",text:""}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["text_quotes","parent_tooltip_when_inline"]},{type:"text_join",message0:"",output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_JOIN_HELPURL}",tooltip:"%{BKY_TEXT_JOIN_TOOLTIP}",mutator:"text_join_mutator"},{type:"text_create_join_container",message0:"%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",
                +args0:[{type:"input_dummy"},{type:"input_statement",name:"STACK"}],colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",enableContextMenu:!1},{type:"text_create_join_item",message0:"%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",tooltip:"{%BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",enableContextMenu:!1},{type:"text_append",message0:"%{BKY_TEXT_APPEND_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_TEXT_APPEND_VARIABLE}"},
                +{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",extensions:["text_append_tooltip"]},{type:"text_length",message0:"%{BKY_TEXT_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_LENGTH_TOOLTIP}",helpUrl:"%{BKY_TEXT_LENGTH_HELPURL}"},{type:"text_isEmpty",message0:"%{BKY_TEXT_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],
                +output:"Boolean",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_TEXT_ISEMPTY_HELPURL}"},{type:"text_indexOf",message0:"%{BKY_TEXT_INDEXOF_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"END",options:[["%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}","FIRST"],["%{BKY_TEXT_INDEXOF_OPERATOR_LAST}","LAST"]]},{type:"input_value",name:"FIND",check:"String"}],output:"Number",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_INDEXOF_HELPURL}",inputsInline:!0,
                +extensions:["text_indexOf_tooltip"]},{type:"text_charAt",message0:"%{BKY_TEXT_CHARAT_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"input_dummy",name:"AT"}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_CHARAT_HELPURL}",inputsInline:!0,mutator:"text_charAt_mutator"}]);
                +Blockly.Blocks.text_getSubstring={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);
                +this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),
                +b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
                +this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&this.moveInputBefore("AT1","AT2")}};
                +Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
                +Blockly.Blocks.text_trim={init:function(){var a=[[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH,"BOTH"],[Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT,"LEFT"],[Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT,"RIGHT"]];this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"MODE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP)}};
                +Blockly.Blocks.text_print={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_PRINT_TITLE,args0:[{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_PRINT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_PRINT_HELPURL})}};
                +Blockly.Blocks.text_prompt_ext={init:function(){var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]];this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);var b=this,a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("TEXT").appendField(a,"TYPE");this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},
                +updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
                +Blockly.Blocks.text_prompt={init:function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]],b=this;this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendDummyInput().appendField(a,"TYPE").appendField(this.newQuote_(!0)).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(this.newQuote_(!1));
                +this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},updateType_:Blockly.Blocks.text_prompt_ext.updateType_,mutationToDom:Blockly.Blocks.text_prompt_ext.mutationToDom,domToMutation:Blockly.Blocks.text_prompt_ext.domToMutation};
                +Blockly.Blocks.text_count={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_COUNT_MESSAGE0,args0:[{type:"input_value",name:"SUB",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"Number",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_COUNT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_COUNT_HELPURL})}};
                +Blockly.Blocks.text_replace={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REPLACE_MESSAGE0,args0:[{type:"input_value",name:"FROM",check:"String"},{type:"input_value",name:"TO",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REPLACE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REPLACE_HELPURL})}};
                +Blockly.Blocks.text_reverse={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REVERSE_MESSAGE0,args0:[{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REVERSE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REVERSE_HELPURL})}};
                +Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC",QUOTE_IMAGE_RIGHT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==",
                +QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
                +Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
                +Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=
                +e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
                +this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
                +a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_APPEND_TOOLTIP?Blockly.Msg.TEXT_APPEND_TOOLTIP.replace("%1",a.getFieldValue("VAR")):""})};
                +Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
                +Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
                +this.appendDummyInput("AT");Blockly.Msg.TEXT_CHARAT_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE")}};
                +Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.WHERE_OPTIONS=[[Blockly.Msg.TEXT_CHARAT_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_CHARAT_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_CHARAT_FIRST,"FIRST"],[Blockly.Msg.TEXT_CHARAT_LAST,"LAST"],[Blockly.Msg.TEXT_CHARAT_RANDOM,"RANDOM"]];this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:
                +Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&(c+="  "+b.replace("%1",a.workspace.options.oneBasedIndex?"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.register("text_append_tooltip",Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);
                +Blockly.Extensions.registerMutator("text_join_mutator",Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_JOIN_EXTENSION);Blockly.Extensions.registerMutator("text_charAt_mutator",Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);Blockly.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;Blockly.Blocks.variables.HUE=Blockly.Constants.Variables.HUE;
                +Blockly.defineBlocksWithJsonArray([{type:"variables_get",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableSetterGetter"]},{type:"variables_set",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",name:"VALUE"}],previousStatement:null,
                +nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableSetterGetter"]}]);
                +Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if("variables_get"==this.type){var b="variables_set";var c=Blockly.Msg.VARIABLES_GET_CREATE_SET}else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getFieldValue("VAR");d.text=c.replace("%1",e);c=goog.dom.createDom("field",null,e);c.setAttribute("name","VAR");c=goog.dom.createDom("block",null,c);c.setAttribute("type",b);d.callback=
                +Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/build.py b/blockly/webif/static/blockly/build.py
                new file mode 100644
                index 000000000..587898690
                --- /dev/null
                +++ b/blockly/webif/static/blockly/build.py
                @@ -0,0 +1,554 @@
                +#!/usr/bin/python2.7
                +# Compresses the core Blockly files into a single JavaScript file.
                +#
                +# Copyright 2012 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +# Usage: build.py <0 or more of accessible, core, generators, langfiles>
                +# build.py with no parameters builds all files.
                +# core builds blockly_compressed, blockly_uncompressed, and blocks_compressed.
                +# accessible builds blockly_accessible_compressed,
                +#  blockly_accessible_uncompressed, and blocks_compressed.
                +# generators builds every <language>_compressed.js.
                +# langfiles builds every msg/js/<LANG>.js file.
                +
                +# This script generates four versions of Blockly's core files. The first pair
                +# are:
                +#   blockly_compressed.js
                +#   blockly_uncompressed.js
                +# The compressed file is a concatenation of all of Blockly's core files which
                +# have been run through Google's Closure Compiler.  This is done using the
                +# online API (which takes a few seconds and requires an Internet connection).
                +# The uncompressed file is a script that loads in each of Blockly's core files
                +# one by one.  This takes much longer for a browser to load, but is useful
                +# when debugging code since line numbers are meaningful and variables haven't
                +# been renamed.  The uncompressed file also allows for a faster developement
                +# cycle since there is no need to rebuild or recompile, just reload.
                +#
                +# The second pair are:
                +#  blockly_accessible_compressed.js
                +#  blockly_accessible_uncompressed.js
                +# These files are analogous to blockly_compressed and blockly_uncompressed,
                +# but also include the visually-impaired module for Blockly.
                +#
                +# This script also generates:
                +#   blocks_compressed.js: The compressed Blockly language blocks.
                +#   javascript_compressed.js: The compressed Javascript generator.
                +#   python_compressed.js: The compressed Python generator.
                +#   dart_compressed.js: The compressed Dart generator.
                +#   lua_compressed.js: The compressed Lua generator.
                +#   msg/js/<LANG>.js for every language <LANG> defined in msg/js/<LANG>.json.
                +
                +import sys
                +if sys.version_info[0] != 2:
                +  raise Exception("Blockly build only compatible with Python 2.x.\n"
                +                  "You are using: " + sys.version)
                +
                +for arg in sys.argv[1:len(sys.argv)]:
                +  if (arg != 'core' and
                +      arg != 'accessible' and
                +      arg != 'generators' and
                +      arg != 'langfiles'):
                +    raise Exception("Invalid argument: \"" + arg + "\". Usage: build.py <0 or more of accessible," +
                +        " core, generators, langfiles>")
                +
                +import errno, glob, httplib, json, os, re, subprocess, threading, urllib
                +
                +
                +def import_path(fullpath):
                +  """Import a file with full path specification.
                +  Allows one to import from any directory, something __import__ does not do.
                +
                +  Args:
                +      fullpath:  Path and filename of import.
                +
                +  Returns:
                +      An imported module.
                +  """
                +  path, filename = os.path.split(fullpath)
                +  filename, ext = os.path.splitext(filename)
                +  sys.path.append(path)
                +  module = __import__(filename)
                +  reload(module)  # Might be out of date.
                +  del sys.path[-1]
                +  return module
                +
                +
                +HEADER = ("// Do not edit this file; automatically generated by build.py.\n"
                +          "'use strict';\n")
                +
                +
                +class Gen_uncompressed(threading.Thread):
                +  """Generate a JavaScript file that loads Blockly's raw files.
                +  Runs in a separate thread.
                +  """
                +  def __init__(self, search_paths, target_filename):
                +    threading.Thread.__init__(self)
                +    self.search_paths = search_paths
                +    self.target_filename = target_filename
                +
                +  def run(self):
                +    f = open(self.target_filename, 'w')
                +    f.write(HEADER)
                +    f.write("""
                +var isNodeJS = !!(typeof module !== 'undefined' && module.exports &&
                +                  typeof window === 'undefined');
                +
                +if (isNodeJS) {
                +  var window = {};
                +  require('closure-library');
                +}
                +
                +window.BLOCKLY_DIR = (function() {
                +  if (!isNodeJS) {
                +    // Find name of current directory.
                +    var scripts = document.getElementsByTagName('script');
                +    var re = new RegExp('(.+)[\/]blockly_(.*)uncompressed\.js$');
                +    for (var i = 0, script; script = scripts[i]; i++) {
                +      var match = re.exec(script.src);
                +      if (match) {
                +        return match[1];
                +      }
                +    }
                +    alert('Could not detect Blockly\\'s directory name.');
                +  }
                +  return '';
                +})();
                +
                +window.BLOCKLY_BOOT = function() {
                +  var dir = '';
                +  if (isNodeJS) {
                +    require('closure-library');
                +    dir = 'blockly';
                +  } else {
                +    // Execute after Closure has loaded.
                +    if (!window.goog) {
                +      alert('Error: Closure not found.  Read this:\\n' +
                +            'developers.google.com/blockly/guides/modify/web/closure');
                +    }
                +    dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0];
                +  }
                +""")
                +    add_dependency = []
                +    base_path = calcdeps.FindClosureBasePath(self.search_paths)
                +    for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths):
                +      add_dependency.append(calcdeps.GetDepsLine(dep, base_path))
                +    add_dependency.sort()  # Deterministic build.
                +    add_dependency = '\n'.join(add_dependency)
                +    # Find the Blockly directory name and replace it with a JS variable.
                +    # This allows blockly_uncompressed.js to be compiled on one computer and be
                +    # used on another, even if the directory name differs.
                +    m = re.search('[\\/]([^\\/]+)[\\/]core[\\/]blockly.js', add_dependency)
                +    add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) +
                +        '([\\/]core[\\/])', '\\1" + dir + "\\2', add_dependency)
                +    f.write(add_dependency + '\n')
                +
                +    provides = []
                +    for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths):
                +      if not dep.filename.startswith(os.pardir + os.sep):  # '../'
                +        provides.extend(dep.provides)
                +    provides.sort()  # Deterministic build.
                +    f.write('\n')
                +    f.write('// Load Blockly.\n')
                +    for provide in provides:
                +      f.write("goog.require('%s');\n" % provide)
                +
                +    f.write("""
                +delete this.BLOCKLY_DIR;
                +delete this.BLOCKLY_BOOT;
                +};
                +
                +if (isNodeJS) {
                +  window.BLOCKLY_BOOT();
                +  module.exports = Blockly;
                +} else {
                +  // Delete any existing Closure (e.g. Soy's nogoog_shim).
                +  document.write('<script>var goog = undefined;</script>');
                +  // Load fresh Closure Library.
                +  document.write('<script src="' + window.BLOCKLY_DIR +
                +      '/../closure-library/closure/goog/base.js"></script>');
                +  document.write('<script>window.BLOCKLY_BOOT();</script>');
                +}
                +""")
                +    f.close()
                +    print("SUCCESS: " + self.target_filename)
                +
                +
                +class Gen_compressed(threading.Thread):
                +  """Generate a JavaScript file that contains all of Blockly's core and all
                +  required parts of Closure, compiled together.
                +  Uses the Closure Compiler's online API.
                +  Runs in a separate thread.
                +  """
                +  def __init__(self, search_paths, bundles):
                +    threading.Thread.__init__(self)
                +    self.search_paths = search_paths
                +    self.bundles = bundles
                +
                +  def run(self):
                +    if ('core' in self.bundles):
                +      self.gen_core()
                +
                +    if ('accessible' in self.bundles):
                +      self.gen_accessible()
                +
                +    if ('core' in self.bundles or 'accessible' in self.bundles):
                +      self.gen_blocks()
                +
                +    if ('generators' in self.bundles):
                +      self.gen_generator("javascript")
                +      self.gen_generator("python")
                +      self.gen_generator("php")
                +      self.gen_generator("dart")
                +      self.gen_generator("lua")
                +
                +  def gen_core(self):
                +    target_filename = "blockly_compressed.js"
                +    # Define the parameters for the POST request.
                +    params = [
                +        ("compilation_level", "SIMPLE_OPTIMIZATIONS"),
                +        ("use_closure_library", "true"),
                +        ("output_format", "json"),
                +        ("output_info", "compiled_code"),
                +        ("output_info", "warnings"),
                +        ("output_info", "errors"),
                +        ("output_info", "statistics"),
                +      ]
                +
                +    # Read in all the source files.
                +    filenames = calcdeps.CalculateDependencies(self.search_paths,
                +        [os.path.join("core", "blockly.js")])
                +    filenames.sort()  # Deterministic build.
                +    for filename in filenames:
                +      # Filter out the Closure files (the compiler will add them).
                +      if filename.startswith(os.pardir + os.sep):  # '../'
                +        continue
                +      f = open(filename)
                +      params.append(("js_code", "".join(f.readlines())))
                +      f.close()
                +
                +    self.do_compile(params, target_filename, filenames, "")
                +
                +  def gen_accessible(self):
                +    target_filename = "blockly_accessible_compressed.js"
                +    # Define the parameters for the POST request.
                +    params = [
                +        ("compilation_level", "SIMPLE_OPTIMIZATIONS"),
                +        ("use_closure_library", "true"),
                +        ("language_out", "ES5"),
                +        ("output_format", "json"),
                +        ("output_info", "compiled_code"),
                +        ("output_info", "warnings"),
                +        ("output_info", "errors"),
                +        ("output_info", "statistics"),
                +      ]
                +
                +    # Read in all the source files.
                +    filenames = calcdeps.CalculateDependencies(self.search_paths,
                +        [os.path.join("accessible", "app.component.js")])
                +    filenames.sort()  # Deterministic build.
                +    for filename in filenames:
                +      # Filter out the Closure files (the compiler will add them).
                +      if filename.startswith(os.pardir + os.sep):  # '../'
                +        continue
                +      f = open(filename)
                +      params.append(("js_code", "".join(f.readlines())))
                +      f.close()
                +
                +    self.do_compile(params, target_filename, filenames, "")
                +
                +  def gen_accessible(self):
                +    target_filename = "blockly_accessible_compressed.js"
                +    # Define the parameters for the POST request.
                +    params = [
                +        ("compilation_level", "SIMPLE_OPTIMIZATIONS"),
                +        ("use_closure_library", "true"),
                +        ("language_out", "ES5"),
                +        ("output_format", "json"),
                +        ("output_info", "compiled_code"),
                +        ("output_info", "warnings"),
                +        ("output_info", "errors"),
                +        ("output_info", "statistics"),
                +      ]
                +
                +    # Read in all the source files.
                +    filenames = calcdeps.CalculateDependencies(self.search_paths,
                +        [os.path.join("accessible", "app.component.js")])
                +    for filename in filenames:
                +      # Filter out the Closure files (the compiler will add them).
                +      if filename.startswith(os.pardir + os.sep):  # '../'
                +        continue
                +      f = open(filename)
                +      params.append(("js_code", "".join(f.readlines())))
                +      f.close()
                +
                +    self.do_compile(params, target_filename, filenames, "")
                +
                +  def gen_blocks(self):
                +    target_filename = "blocks_compressed.js"
                +    # Define the parameters for the POST request.
                +    params = [
                +        ("compilation_level", "SIMPLE_OPTIMIZATIONS"),
                +        ("output_format", "json"),
                +        ("output_info", "compiled_code"),
                +        ("output_info", "warnings"),
                +        ("output_info", "errors"),
                +        ("output_info", "statistics"),
                +      ]
                +
                +    # Read in all the source files.
                +    # Add Blockly.Blocks to be compatible with the compiler.
                +    params.append(("js_code", "goog.provide('Blockly.Blocks');"))
                +    filenames = glob.glob(os.path.join("blocks", "*.js"))
                +    filenames.sort()  # Deterministic build.
                +    for filename in filenames:
                +      f = open(filename)
                +      params.append(("js_code", "".join(f.readlines())))
                +      f.close()
                +
                +    # Remove Blockly.Blocks to be compatible with Blockly.
                +    remove = "var Blockly={Blocks:{}};"
                +    self.do_compile(params, target_filename, filenames, remove)
                +
                +  def gen_generator(self, language):
                +    target_filename = language + "_compressed.js"
                +    # Define the parameters for the POST request.
                +    params = [
                +        ("compilation_level", "SIMPLE_OPTIMIZATIONS"),
                +        ("output_format", "json"),
                +        ("output_info", "compiled_code"),
                +        ("output_info", "warnings"),
                +        ("output_info", "errors"),
                +        ("output_info", "statistics"),
                +      ]
                +
                +    # Read in all the source files.
                +    # Add Blockly.Generator to be compatible with the compiler.
                +    params.append(("js_code", "goog.provide('Blockly.Generator');"))
                +    filenames = glob.glob(
                +        os.path.join("generators", language, "*.js"))
                +    filenames.sort()  # Deterministic build.
                +    filenames.insert(0, os.path.join("generators", language + ".js"))
                +    for filename in filenames:
                +      f = open(filename)
                +      params.append(("js_code", "".join(f.readlines())))
                +      f.close()
                +    filenames.insert(0, "[goog.provide]")
                +
                +    # Remove Blockly.Generator to be compatible with Blockly.
                +    remove = "var Blockly={Generator:{}};"
                +    self.do_compile(params, target_filename, filenames, remove)
                +
                +  def do_compile(self, params, target_filename, filenames, remove):
                +    # Send the request to Google.
                +    headers = {"Content-type": "application/x-www-form-urlencoded"}
                +    conn = httplib.HTTPConnection("closure-compiler.appspot.com")
                +    conn.request("POST", "/compile", urllib.urlencode(params), headers)
                +    response = conn.getresponse()
                +    json_str = response.read()
                +    conn.close()
                +
                +    # Parse the JSON response.
                +    json_data = json.loads(json_str)
                +
                +    def file_lookup(name):
                +      if not name.startswith("Input_"):
                +        return "???"
                +      n = int(name[6:]) - 1
                +      return filenames[n]
                +
                +    if json_data.has_key("serverErrors"):
                +      errors = json_data["serverErrors"]
                +      for error in errors:
                +        print("SERVER ERROR: %s" % target_filename)
                +        print(error["error"])
                +    elif json_data.has_key("errors"):
                +      errors = json_data["errors"]
                +      for error in errors:
                +        print("FATAL ERROR")
                +        print(error["error"])
                +        if error["file"]:
                +          print("%s at line %d:" % (
                +              file_lookup(error["file"]), error["lineno"]))
                +          print(error["line"])
                +          print((" " * error["charno"]) + "^")
                +        sys.exit(1)
                +    else:
                +      if json_data.has_key("warnings"):
                +        warnings = json_data["warnings"]
                +        for warning in warnings:
                +          print("WARNING")
                +          print(warning["warning"])
                +          if warning["file"]:
                +            print("%s at line %d:" % (
                +                file_lookup(warning["file"]), warning["lineno"]))
                +            print(warning["line"])
                +            print((" " * warning["charno"]) + "^")
                +        print()
                +
                +      if not json_data.has_key("compiledCode"):
                +        print("FATAL ERROR: Compiler did not return compiledCode.")
                +        sys.exit(1)
                +
                +      code = HEADER + "\n" + json_data["compiledCode"]
                +      code = code.replace(remove, "")
                +      stats = json_data["statistics"]
                +      original_b = stats["originalSize"]
                +      compressed_b = stats["compressedSize"]
                +      if original_b > 0 and compressed_b > 0:
                +        f = open(target_filename, "w")
                +        f.write(code)
                +        f.close()
                +
                +        original_kb = int(original_b / 1024 + 0.5)
                +        compressed_kb = int(compressed_b / 1024 + 0.5)
                +        ratio = int(float(compressed_b) / float(original_b) * 100 + 0.5)
                +        print("SUCCESS: " + target_filename)
                +        print("Size changed from %d KB to %d KB (%d%%)." % (
                +            original_kb, compressed_kb, ratio))
                +      else:
                +        print("UNKNOWN ERROR")
                +
                +
                +class Gen_langfiles(threading.Thread):
                +  """Generate JavaScript file for each natural language supported.
                +
                +  Runs in a separate thread.
                +  """
                +
                +  def __init__(self, force_gen):
                +    threading.Thread.__init__(self)
                +    self.force_gen = force_gen
                +
                +  def _rebuild(self, srcs, dests):
                +    # Determine whether any of the files in srcs is newer than any in dests.
                +    try:
                +      return (max(os.path.getmtime(src) for src in srcs) >
                +              min(os.path.getmtime(dest) for dest in dests))
                +    except OSError as e:
                +      # Was a file not found?
                +      if e.errno == errno.ENOENT:
                +        # If it was a source file, we can't proceed.
                +        if e.filename in srcs:
                +          print("Source file missing: " + e.filename)
                +          sys.exit(1)
                +        else:
                +          # If a destination file was missing, rebuild.
                +          return True
                +      else:
                +        print("Error checking file creation times: " + e)
                +
                +  def run(self):
                +    # The files msg/json/{en,qqq,synonyms}.json depend on msg/messages.js.
                +    if (self.force_gen or
                +        self._rebuild([os.path.join("msg", "messages.js")],
                +                      [os.path.join("msg", "json", f) for f in
                +                      ["en.json", "qqq.json", "synonyms.json"]])):
                +      try:
                +        subprocess.check_call([
                +            "python",
                +            os.path.join("i18n", "js_to_json.py"),
                +            "--input_file", "msg/messages.js",
                +            "--output_dir", "msg/json/",
                +            "--quiet"])
                +      except (subprocess.CalledProcessError, OSError) as e:
                +        # Documentation for subprocess.check_call says that CalledProcessError
                +        # will be raised on failure, but I found that OSError is also possible.
                +        print("Error running i18n/js_to_json.py: ", e)
                +        sys.exit(1)
                +
                +    # Checking whether it is necessary to rebuild the js files would be a lot of
                +    # work since we would have to compare each <lang>.json file with each
                +    # <lang>.js file.  Rebuilding is easy and cheap, so just go ahead and do it.
                +    try:
                +      # Use create_messages.py to create .js files from .json files.
                +      cmd = [
                +          "python",
                +          os.path.join("i18n", "create_messages.py"),
                +          "--source_lang_file", os.path.join("msg", "json", "en.json"),
                +          "--source_synonym_file", os.path.join("msg", "json", "synonyms.json"),
                +          "--source_constants_file", os.path.join("msg", "json", "constants.json"),
                +          "--key_file", os.path.join("msg", "json", "keys.json"),
                +          "--output_dir", os.path.join("msg", "js"),
                +          "--quiet"]
                +      json_files = glob.glob(os.path.join("msg", "json", "*.json"))
                +      json_files = [file for file in json_files if not
                +                    (file.endswith(("keys.json", "synonyms.json", "qqq.json", "constants.json")))]
                +      cmd.extend(json_files)
                +      subprocess.check_call(cmd)
                +    except (subprocess.CalledProcessError, OSError) as e:
                +      print("Error running i18n/create_messages.py: ", e)
                +      sys.exit(1)
                +
                +    # Output list of .js files created.
                +    for f in json_files:
                +      # This assumes the path to the current directory does not contain "json".
                +      f = f.replace("json", "js")
                +      if os.path.isfile(f):
                +        print("SUCCESS: " + f)
                +      else:
                +        print("FAILED to create " + f)
                +
                +
                +if __name__ == "__main__":
                +  try:
                +    calcdeps = import_path(os.path.join(
                +        os.path.pardir, "closure-library", "closure", "bin", "calcdeps.py"))
                +  except ImportError:
                +    if os.path.isdir(os.path.join(os.path.pardir, "closure-library-read-only")):
                +      # Dir got renamed when Closure moved from Google Code to GitHub in 2014.
                +      print("Error: Closure directory needs to be renamed from"
                +            "'closure-library-read-only' to 'closure-library'.\n"
                +            "Please rename this directory.")
                +    elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")):
                +      # When Closure is installed by npm, it is named "google-closure-library".
                +      #calcdeps = import_path(os.path.join(
                +      # os.path.pardir, "google-closure-library", "closure", "bin", "calcdeps.py"))
                +      print("Error: Closure directory needs to be renamed from"
                +           "'google-closure-library' to 'closure-library'.\n"
                +           "Please rename this directory.")
                +    else:
                +      print("""Error: Closure not found.  Read this:
                +developers.google.com/blockly/guides/modify/web/closure""")
                +    sys.exit(1)
                +
                +  core_search_paths = calcdeps.ExpandDirectories(
                +      ["core", os.path.join(os.path.pardir, "closure-library")])
                +  core_search_paths.sort()  # Deterministic build.
                +  full_search_paths = calcdeps.ExpandDirectories(
                +      ["accessible", "core", os.path.join(os.path.pardir, "closure-library")])
                +  full_search_paths.sort()  # Deterministic build.
                +
                +  if (len(sys.argv) == 1):
                +    args = ['core', 'accessible', 'generators', 'defaultlangfiles']
                +  else:
                +    args = sys.argv
                +
                +  # Uncompressed and compressed are run in parallel threads.
                +  # Uncompressed is limited by processor speed.
                +  if ('core' in args):
                +    Gen_uncompressed(core_search_paths, 'blockly_uncompressed.js').start()
                +
                +  if ('accessible' in args):
                +    Gen_uncompressed(full_search_paths, 'blockly_accessible_uncompressed.js').start()
                +
                +  # Compressed is limited by network and server speed.
                +  Gen_compressed(full_search_paths, args).start()
                +
                +  # This is run locally in a separate thread
                +  # defaultlangfiles checks for changes in the msg files, while manually asking
                +  # to build langfiles will force the messages to be rebuilt.
                +  if ('langfiles' in args or 'defaultlangfiles' in args):
                +    Gen_langfiles('langfiles' in args).start()
                diff --git a/blockly/webif/static/blockly/core/block.js b/blockly/webif/static/blockly/core/block.js
                new file mode 100644
                index 000000000..ead47347d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/block.js
                @@ -0,0 +1,1504 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview The class representing one block.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Block');
                +
                +goog.require('Blockly.Blocks');
                +goog.require('Blockly.Comment');
                +goog.require('Blockly.Connection');
                +goog.require('Blockly.Extensions');
                +goog.require('Blockly.Input');
                +goog.require('Blockly.Mutator');
                +goog.require('Blockly.Warning');
                +goog.require('Blockly.Workspace');
                +goog.require('Blockly.Xml');
                +goog.require('goog.array');
                +goog.require('goog.asserts');
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.string');
                +
                +
                +/**
                + * Class for one block.
                + * Not normally called directly, workspace.newBlock() is preferred.
                + * @param {!Blockly.Workspace} workspace The block's workspace.
                + * @param {?string} prototypeName Name of the language object containing
                + *     type-specific functions for this block.
                + * @param {string=} opt_id Optional ID.  Use this ID if provided, otherwise
                + *     create a new id.
                + * @constructor
                + */
                +Blockly.Block = function(workspace, prototypeName, opt_id) {
                +  /** @type {string} */
                +  this.id = (opt_id && !workspace.getBlockById(opt_id)) ?
                +      opt_id : Blockly.utils.genUid();
                +  workspace.blockDB_[this.id] = this;
                +  /** @type {Blockly.Connection} */
                +  this.outputConnection = null;
                +  /** @type {Blockly.Connection} */
                +  this.nextConnection = null;
                +  /** @type {Blockly.Connection} */
                +  this.previousConnection = null;
                +  /** @type {!Array.<!Blockly.Input>} */
                +  this.inputList = [];
                +  /** @type {boolean|undefined} */
                +  this.inputsInline = undefined;
                +  /** @type {boolean} */
                +  this.disabled = false;
                +  /** @type {string|!Function} */
                +  this.tooltip = '';
                +  /** @type {boolean} */
                +  this.contextMenu = true;
                +
                +  /**
                +   * @type {Blockly.Block}
                +   * @private
                +   */
                +  this.parentBlock_ = null;
                +
                +  /**
                +   * @type {!Array.<!Blockly.Block>}
                +   * @private
                +   */
                +  this.childBlocks_ = [];
                +
                +  /**
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.deletable_ = true;
                +
                +  /**
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.movable_ = true;
                +
                +  /**
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.editable_ = true;
                +
                +  /**
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.isShadow_ = false;
                +
                +  /**
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.collapsed_ = false;
                +
                +  /** @type {string|Blockly.Comment} */
                +  this.comment = null;
                +
                +  /**
                +   * The block's position in workspace units.  (0, 0) is at the workspace's
                +   * origin; scale does not change this value.
                +   * @type {!goog.math.Coordinate}
                +   * @private
                +   */
                +  this.xy_ = new goog.math.Coordinate(0, 0);
                +
                +  /** @type {!Blockly.Workspace} */
                +  this.workspace = workspace;
                +  /** @type {boolean} */
                +  this.isInFlyout = workspace.isFlyout;
                +  /** @type {boolean} */
                +  this.isInMutator = workspace.isMutator;
                +
                +  /** @type {boolean} */
                +  this.RTL = workspace.RTL;
                +
                +  // Copy the type-specific functions and data from the prototype.
                +  if (prototypeName) {
                +    /** @type {string} */
                +    this.type = prototypeName;
                +    var prototype = Blockly.Blocks[prototypeName];
                +    goog.asserts.assertObject(prototype,
                +        'Error: Unknown block type "%s".', prototypeName);
                +    goog.mixin(this, prototype);
                +  }
                +
                +  workspace.addTopBlock(this);
                +
                +  // Call an initialization function, if it exists.
                +  if (goog.isFunction(this.init)) {
                +    this.init();
                +  }
                +  // Record initial inline state.
                +  /** @type {boolean|undefined} */
                +  this.inputsInlineDefault = this.inputsInline;
                +  if (Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockCreate(this));
                +  }
                +  // Bind an onchange function, if it exists.
                +  if (goog.isFunction(this.onchange)) {
                +    this.setOnChange(this.onchange);
                +  }
                +};
                +
                +/**
                + * Obtain a newly created block.
                + * @param {!Blockly.Workspace} workspace The block's workspace.
                + * @param {?string} prototypeName Name of the language object containing
                + *     type-specific functions for this block.
                + * @return {!Blockly.Block} The created block.
                + * @deprecated December 2015
                + */
                +Blockly.Block.obtain = function(workspace, prototypeName) {
                +  console.warn('Deprecated call to Blockly.Block.obtain, ' +
                +               'use workspace.newBlock instead.');
                +  return workspace.newBlock(prototypeName);
                +};
                +
                +/**
                + * Optional text data that round-trips beween blocks and XML.
                + * Has no effect. May be used by 3rd parties for meta information.
                + * @type {?string}
                + */
                +Blockly.Block.prototype.data = null;
                +
                +/**
                + * Colour of the block in '#RRGGBB' format.
                + * @type {string}
                + * @private
                + */
                +Blockly.Block.prototype.colour_ = '#000000';
                +
                +/**
                + * Dispose of this block.
                + * @param {boolean} healStack If true, then try to heal any gap by connecting
                + *     the next statement with the previous statement.  Otherwise, dispose of
                + *     all children of this block.
                + */
                +Blockly.Block.prototype.dispose = function(healStack) {
                +  if (!this.workspace) {
                +    // Already deleted.
                +    return;
                +  }
                +  // Terminate onchange event calls.
                +  if (this.onchangeWrapper_) {
                +    this.workspace.removeChangeListener(this.onchangeWrapper_);
                +  }
                +  this.unplug(healStack);
                +  if (Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockDelete(this));
                +  }
                +  Blockly.Events.disable();
                +
                +  try {
                +    // This block is now at the top of the workspace.
                +    // Remove this block from the workspace's list of top-most blocks.
                +    if (this.workspace) {
                +      this.workspace.removeTopBlock(this);
                +      // Remove from block database.
                +      delete this.workspace.blockDB_[this.id];
                +      this.workspace = null;
                +    }
                +
                +    // Just deleting this block from the DOM would result in a memory leak as
                +    // well as corruption of the connection database.  Therefore we must
                +    // methodically step through the blocks and carefully disassemble them.
                +
                +    // First, dispose of all my children.
                +    for (var i = this.childBlocks_.length - 1; i >= 0; i--) {
                +      this.childBlocks_[i].dispose(false);
                +    }
                +    // Then dispose of myself.
                +    // Dispose of all inputs and their fields.
                +    for (var i = 0, input; input = this.inputList[i]; i++) {
                +      input.dispose();
                +    }
                +    this.inputList.length = 0;
                +    // Dispose of any remaining connections (next/previous/output).
                +    var connections = this.getConnections_(true);
                +    for (var i = 0; i < connections.length; i++) {
                +      var connection = connections[i];
                +      if (connection.isConnected()) {
                +        connection.disconnect();
                +      }
                +      connections[i].dispose();
                +    }
                +  } finally {
                +    Blockly.Events.enable();
                +  }
                +};
                +
                +/**
                + * Unplug this block from its superior block.  If this block is a statement,
                + * optionally reconnect the block underneath with the block on top.
                + * @param {boolean} opt_healStack Disconnect child statement and reconnect
                + *   stack.  Defaults to false.
                + */
                +Blockly.Block.prototype.unplug = function(opt_healStack) {
                +  if (this.outputConnection) {
                +    if (this.outputConnection.isConnected()) {
                +      // Disconnect from any superior block.
                +      this.outputConnection.disconnect();
                +    }
                +  } else if (this.previousConnection) {
                +    var previousTarget = null;
                +    if (this.previousConnection.isConnected()) {
                +      // Remember the connection that any next statements need to connect to.
                +      previousTarget = this.previousConnection.targetConnection;
                +      // Detach this block from the parent's tree.
                +      this.previousConnection.disconnect();
                +    }
                +    var nextBlock = this.getNextBlock();
                +    if (opt_healStack && nextBlock) {
                +      // Disconnect the next statement.
                +      var nextTarget = this.nextConnection.targetConnection;
                +      nextTarget.disconnect();
                +      if (previousTarget && previousTarget.checkType_(nextTarget)) {
                +        // Attach the next statement to the previous statement.
                +        previousTarget.connect(nextTarget);
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Returns all connections originating from this block.
                + * @return {!Array.<!Blockly.Connection>} Array of connections.
                + * @private
                + */
                +Blockly.Block.prototype.getConnections_ = function() {
                +  var myConnections = [];
                +  if (this.outputConnection) {
                +    myConnections.push(this.outputConnection);
                +  }
                +  if (this.previousConnection) {
                +    myConnections.push(this.previousConnection);
                +  }
                +  if (this.nextConnection) {
                +    myConnections.push(this.nextConnection);
                +  }
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (input.connection) {
                +      myConnections.push(input.connection);
                +    }
                +  }
                +  return myConnections;
                +};
                +
                +/**
                + * Walks down a stack of blocks and finds the last next connection on the stack.
                + * @return {Blockly.Connection} The last next connection on the stack, or null.
                + * @package
                + */
                +Blockly.Block.prototype.lastConnectionInStack_ = function() {
                +  var nextConnection = this.nextConnection;
                +  while (nextConnection) {
                +    var nextBlock = nextConnection.targetBlock();
                +    if (!nextBlock) {
                +      // Found a next connection with nothing on the other side.
                +      return nextConnection;
                +    }
                +    nextConnection = nextBlock.nextConnection;
                +  }
                +  // Ran out of next connections.
                +  return null;
                +};
                +
                +/**
                + * Bump unconnected blocks out of alignment.  Two blocks which aren't actually
                + * connected should not coincidentally line up on screen.
                + * @private
                + */
                +Blockly.Block.prototype.bumpNeighbours_ = function() {
                +  console.warn('Not expected to reach this bumpNeighbours_ function. The ' +
                +    'BlockSvg function for bumpNeighbours_ was expected to be called instead.');
                +};
                +
                +/**
                + * Return the parent block or null if this block is at the top level.
                + * @return {Blockly.Block} The block that holds the current block.
                + */
                +Blockly.Block.prototype.getParent = function() {
                +  // Look at the DOM to see if we are nested in another block.
                +  return this.parentBlock_;
                +};
                +
                +/**
                + * Return the input that connects to the specified block.
                + * @param {!Blockly.Block} block A block connected to an input on this block.
                + * @return {Blockly.Input} The input that connects to the specified block.
                + */
                +Blockly.Block.prototype.getInputWithBlock = function(block) {
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (input.connection && input.connection.targetBlock() == block) {
                +      return input;
                +    }
                +  }
                +  return null;
                +};
                +
                +/**
                + * Return the parent block that surrounds the current block, or null if this
                + * block has no surrounding block.  A parent block might just be the previous
                + * statement, whereas the surrounding block is an if statement, while loop, etc.
                + * @return {Blockly.Block} The block that surrounds the current block.
                + */
                +Blockly.Block.prototype.getSurroundParent = function() {
                +  var block = this;
                +  do {
                +    var prevBlock = block;
                +    block = block.getParent();
                +    if (!block) {
                +      // Ran off the top.
                +      return null;
                +    }
                +  } while (block.getNextBlock() == prevBlock);
                +  // This block is an enclosing parent, not just a statement in a stack.
                +  return block;
                +};
                +
                +/**
                + * Return the next statement block directly connected to this block.
                + * @return {Blockly.Block} The next statement block or null.
                + */
                +Blockly.Block.prototype.getNextBlock = function() {
                +  return this.nextConnection && this.nextConnection.targetBlock();
                +};
                +
                +/**
                + * Return the top-most block in this block's tree.
                + * This will return itself if this block is at the top level.
                + * @return {!Blockly.Block} The root block.
                + */
                +Blockly.Block.prototype.getRootBlock = function() {
                +  var rootBlock;
                +  var block = this;
                +  do {
                +    rootBlock = block;
                +    block = rootBlock.parentBlock_;
                +  } while (block);
                +  return rootBlock;
                +};
                +
                +/**
                + * Find all the blocks that are directly nested inside this one.
                + * Includes value and block inputs, as well as any following statement.
                + * Excludes any connection on an output tab or any preceding statement.
                + * @return {!Array.<!Blockly.Block>} Array of blocks.
                + */
                +Blockly.Block.prototype.getChildren = function() {
                +  return this.childBlocks_;
                +};
                +
                +/**
                + * Set parent of this block to be a new block or null.
                + * @param {Blockly.Block} newParent New parent block.
                + */
                +Blockly.Block.prototype.setParent = function(newParent) {
                +  if (newParent == this.parentBlock_) {
                +    return;
                +  }
                +  if (this.parentBlock_) {
                +    // Remove this block from the old parent's child list.
                +    goog.array.remove(this.parentBlock_.childBlocks_, this);
                +
                +    // Disconnect from superior blocks.
                +    if (this.previousConnection && this.previousConnection.isConnected()) {
                +      throw 'Still connected to previous block.';
                +    }
                +    if (this.outputConnection && this.outputConnection.isConnected()) {
                +      throw 'Still connected to parent block.';
                +    }
                +    this.parentBlock_ = null;
                +    // This block hasn't actually moved on-screen, so there's no need to update
                +    // its connection locations.
                +  } else {
                +    // Remove this block from the workspace's list of top-most blocks.
                +    this.workspace.removeTopBlock(this);
                +  }
                +
                +  this.parentBlock_ = newParent;
                +  if (newParent) {
                +    // Add this block to the new parent's child list.
                +    newParent.childBlocks_.push(this);
                +  } else {
                +    this.workspace.addTopBlock(this);
                +  }
                +};
                +
                +/**
                + * Find all the blocks that are directly or indirectly nested inside this one.
                + * Includes this block in the list.
                + * Includes value and block inputs, as well as any following statements.
                + * Excludes any connection on an output tab or any preceding statements.
                + * @return {!Array.<!Blockly.Block>} Flattened array of blocks.
                + */
                +Blockly.Block.prototype.getDescendants = function() {
                +  var blocks = [this];
                +  for (var child, x = 0; child = this.childBlocks_[x]; x++) {
                +    blocks.push.apply(blocks, child.getDescendants());
                +  }
                +  return blocks;
                +};
                +
                +/**
                + * Get whether this block is deletable or not.
                + * @return {boolean} True if deletable.
                + */
                +Blockly.Block.prototype.isDeletable = function() {
                +  return this.deletable_ && !this.isShadow_ &&
                +      !(this.workspace && this.workspace.options.readOnly);
                +};
                +
                +/**
                + * Set whether this block is deletable or not.
                + * @param {boolean} deletable True if deletable.
                + */
                +Blockly.Block.prototype.setDeletable = function(deletable) {
                +  this.deletable_ = deletable;
                +};
                +
                +/**
                + * Get whether this block is movable or not.
                + * @return {boolean} True if movable.
                + */
                +Blockly.Block.prototype.isMovable = function() {
                +  return this.movable_ && !this.isShadow_ &&
                +      !(this.workspace && this.workspace.options.readOnly);
                +};
                +
                +/**
                + * Set whether this block is movable or not.
                + * @param {boolean} movable True if movable.
                + */
                +Blockly.Block.prototype.setMovable = function(movable) {
                +  this.movable_ = movable;
                +};
                +
                +/**
                + * Get whether this block is a shadow block or not.
                + * @return {boolean} True if a shadow.
                + */
                +Blockly.Block.prototype.isShadow = function() {
                +  return this.isShadow_;
                +};
                +
                +/**
                + * Set whether this block is a shadow block or not.
                + * @param {boolean} shadow True if a shadow.
                + */
                +Blockly.Block.prototype.setShadow = function(shadow) {
                +  this.isShadow_ = shadow;
                +};
                +
                +/**
                + * Get whether this block is editable or not.
                + * @return {boolean} True if editable.
                + */
                +Blockly.Block.prototype.isEditable = function() {
                +  return this.editable_ && !(this.workspace && this.workspace.options.readOnly);
                +};
                +
                +/**
                + * Set whether this block is editable or not.
                + * @param {boolean} editable True if editable.
                + */
                +Blockly.Block.prototype.setEditable = function(editable) {
                +  this.editable_ = editable;
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      field.updateEditable();
                +    }
                +  }
                +};
                +
                +/**
                + * Set whether the connections are hidden (not tracked in a database) or not.
                + * Recursively walk down all child blocks (except collapsed blocks).
                + * @param {boolean} hidden True if connections are hidden.
                + */
                +Blockly.Block.prototype.setConnectionsHidden = function(hidden) {
                +  if (!hidden && this.isCollapsed()) {
                +    if (this.outputConnection) {
                +      this.outputConnection.setHidden(hidden);
                +    }
                +    if (this.previousConnection) {
                +      this.previousConnection.setHidden(hidden);
                +    }
                +    if (this.nextConnection) {
                +      this.nextConnection.setHidden(hidden);
                +      var child = this.nextConnection.targetBlock();
                +      if (child) {
                +        child.setConnectionsHidden(hidden);
                +      }
                +    }
                +  } else {
                +    var myConnections = this.getConnections_(true);
                +    for (var i = 0, connection; connection = myConnections[i]; i++) {
                +      connection.setHidden(hidden);
                +      if (connection.isSuperior()) {
                +        var child = connection.targetBlock();
                +        if (child) {
                +          child.setConnectionsHidden(hidden);
                +        }
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Set the URL of this block's help page.
                + * @param {string|Function} url URL string for block help, or function that
                + *     returns a URL.  Null for no help.
                + */
                +Blockly.Block.prototype.setHelpUrl = function(url) {
                +  this.helpUrl = url;
                +};
                +
                +/**
                + * Change the tooltip text for a block.
                + * @param {string|!Function} newTip Text for tooltip or a parent element to
                + *     link to for its tooltip.  May be a function that returns a string.
                + */
                +Blockly.Block.prototype.setTooltip = function(newTip) {
                +  this.tooltip = newTip;
                +};
                +
                +/**
                + * Get the colour of a block.
                + * @return {string} #RRGGBB string.
                + */
                +Blockly.Block.prototype.getColour = function() {
                +  return this.colour_;
                +};
                +
                +/**
                + * Change the colour of a block.
                + * @param {number|string} colour HSV hue value, or #RRGGBB string.
                + */
                +Blockly.Block.prototype.setColour = function(colour) {
                +  var hue = Number(colour);
                +  if (!isNaN(hue)) {
                +    this.colour_ = Blockly.hueToRgb(hue);
                +  } else if (goog.isString(colour) && colour.match(/^#[0-9a-fA-F]{6}$/)) {
                +    this.colour_ = colour;
                +  } else {
                +    throw 'Invalid colour: ' + colour;
                +  }
                +};
                +
                +/**
                + * Sets a callback function to use whenever the block's parent workspace
                + * changes, replacing any prior onchange handler. This is usually only called
                + * from the constructor, the block type initializer function, or an extension
                + * initializer function.
                + * @param {function(Blockly.Events.Abstract)} onchangeFn The callback to call
                + *     when the block's workspace changes.
                + * @throws {Error} if onchangeFn is not falsey or a function.
                + */
                +Blockly.Block.prototype.setOnChange = function(onchangeFn) {
                +  if (onchangeFn && !goog.isFunction(onchangeFn)) {
                +    throw new Error("onchange must be a function.");
                +  }
                +  if (this.onchangeWrapper_) {
                +    this.workspace.removeChangeListener(this.onchangeWrapper_);
                +  }
                +  this.onchange = onchangeFn;
                +  if (this.onchange) {
                +    this.onchangeWrapper_ = onchangeFn.bind(this);
                +    this.workspace.addChangeListener(this.onchangeWrapper_);
                +  }
                +};
                +
                +/**
                + * Returns the named field from a block.
                + * @param {string} name The name of the field.
                + * @return {Blockly.Field} Named field, or null if field does not exist.
                + */
                +Blockly.Block.prototype.getField = function(name) {
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      if (field.name === name) {
                +        return field;
                +      }
                +    }
                +  }
                +  return null;
                +};
                +
                +/**
                + * Return all variables referenced by this block.
                + * @return {!Array.<string>} List of variable names.
                + */
                +Blockly.Block.prototype.getVars = function() {
                +  var vars = [];
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      if (field instanceof Blockly.FieldVariable) {
                +        vars.push(field.getValue());
                +      }
                +    }
                +  }
                +  return vars;
                +};
                +
                +/**
                + * Notification that a variable is renaming.
                + * If the name matches one of this block's variables, rename it.
                + * @param {string} oldName Previous name of variable.
                + * @param {string} newName Renamed variable.
                + */
                +Blockly.Block.prototype.renameVar = function(oldName, newName) {
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      if (field instanceof Blockly.FieldVariable &&
                +          Blockly.Names.equals(oldName, field.getValue())) {
                +        field.setValue(newName);
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Returns the language-neutral value from the field of a block.
                + * @param {string} name The name of the field.
                + * @return {?string} Value from the field or null if field does not exist.
                + */
                +Blockly.Block.prototype.getFieldValue = function(name) {
                +  var field = this.getField(name);
                +  if (field) {
                +    return field.getValue();
                +  }
                +  return null;
                +};
                +
                +/**
                + * Change the field value for a block (e.g. 'CHOOSE' or 'REMOVE').
                + * @param {string} newValue Value to be the new field.
                + * @param {string} name The name of the field.
                + */
                +Blockly.Block.prototype.setFieldValue = function(newValue, name) {
                +  var field = this.getField(name);
                +  goog.asserts.assertObject(field, 'Field "%s" not found.', name);
                +  field.setValue(newValue);
                +};
                +
                +/**
                + * Set whether this block can chain onto the bottom of another block.
                + * @param {boolean} newBoolean True if there can be a previous statement.
                + * @param {string|Array.<string>|null|undefined} opt_check Statement type or
                + *     list of statement types.  Null/undefined if any type could be connected.
                + */
                +Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
                +  if (newBoolean) {
                +    if (opt_check === undefined) {
                +      opt_check = null;
                +    }
                +    if (!this.previousConnection) {
                +      goog.asserts.assert(!this.outputConnection,
                +          'Remove output connection prior to adding previous connection.');
                +      this.previousConnection =
                +          this.makeConnection_(Blockly.PREVIOUS_STATEMENT);
                +    }
                +    this.previousConnection.setCheck(opt_check);
                +  } else {
                +    if (this.previousConnection) {
                +      goog.asserts.assert(!this.previousConnection.isConnected(),
                +          'Must disconnect previous statement before removing connection.');
                +      this.previousConnection.dispose();
                +      this.previousConnection = null;
                +    }
                +  }
                +};
                +
                +/**
                + * Set whether another block can chain onto the bottom of this block.
                + * @param {boolean} newBoolean True if there can be a next statement.
                + * @param {string|Array.<string>|null|undefined} opt_check Statement type or
                + *     list of statement types.  Null/undefined if any type could be connected.
                + */
                +Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
                +  if (newBoolean) {
                +    if (opt_check === undefined) {
                +      opt_check = null;
                +    }
                +    if (!this.nextConnection) {
                +      this.nextConnection = this.makeConnection_(Blockly.NEXT_STATEMENT);
                +    }
                +    this.nextConnection.setCheck(opt_check);
                +  } else {
                +    if (this.nextConnection) {
                +      goog.asserts.assert(!this.nextConnection.isConnected(),
                +          'Must disconnect next statement before removing connection.');
                +      this.nextConnection.dispose();
                +      this.nextConnection = null;
                +    }
                +  }
                +};
                +
                +/**
                + * Set whether this block returns a value.
                + * @param {boolean} newBoolean True if there is an output.
                + * @param {string|Array.<string>|null|undefined} opt_check Returned type or list
                + *     of returned types.  Null or undefined if any type could be returned
                + *     (e.g. variable get).
                + */
                +Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) {
                +  if (newBoolean) {
                +    if (opt_check === undefined) {
                +      opt_check = null;
                +    }
                +    if (!this.outputConnection) {
                +      goog.asserts.assert(!this.previousConnection,
                +          'Remove previous connection prior to adding output connection.');
                +      this.outputConnection = this.makeConnection_(Blockly.OUTPUT_VALUE);
                +    }
                +    this.outputConnection.setCheck(opt_check);
                +  } else {
                +    if (this.outputConnection) {
                +      goog.asserts.assert(!this.outputConnection.isConnected(),
                +          'Must disconnect output value before removing connection.');
                +      this.outputConnection.dispose();
                +      this.outputConnection = null;
                +    }
                +  }
                +};
                +
                +/**
                + * Set whether value inputs are arranged horizontally or vertically.
                + * @param {boolean} newBoolean True if inputs are horizontal.
                + */
                +Blockly.Block.prototype.setInputsInline = function(newBoolean) {
                +  if (this.inputsInline != newBoolean) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this, 'inline', null, this.inputsInline, newBoolean));
                +    this.inputsInline = newBoolean;
                +  }
                +};
                +
                +/**
                + * Get whether value inputs are arranged horizontally or vertically.
                + * @return {boolean} True if inputs are horizontal.
                + */
                +Blockly.Block.prototype.getInputsInline = function() {
                +  if (this.inputsInline != undefined) {
                +    // Set explicitly.
                +    return this.inputsInline;
                +  }
                +  // Not defined explicitly.  Figure out what would look best.
                +  for (var i = 1; i < this.inputList.length; i++) {
                +    if (this.inputList[i - 1].type == Blockly.DUMMY_INPUT &&
                +        this.inputList[i].type == Blockly.DUMMY_INPUT) {
                +      // Two dummy inputs in a row.  Don't inline them.
                +      return false;
                +    }
                +  }
                +  for (var i = 1; i < this.inputList.length; i++) {
                +    if (this.inputList[i - 1].type == Blockly.INPUT_VALUE &&
                +        this.inputList[i].type == Blockly.DUMMY_INPUT) {
                +      // Dummy input after a value input.  Inline them.
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Set whether the block is disabled or not.
                + * @param {boolean} disabled True if disabled.
                + */
                +Blockly.Block.prototype.setDisabled = function(disabled) {
                +  if (this.disabled != disabled) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this, 'disabled', null, this.disabled, disabled));
                +    this.disabled = disabled;
                +  }
                +};
                +
                +/**
                + * Get whether the block is disabled or not due to parents.
                + * The block's own disabled property is not considered.
                + * @return {boolean} True if disabled.
                + */
                +Blockly.Block.prototype.getInheritedDisabled = function() {
                +  var ancestor = this.getSurroundParent();
                +  while (ancestor) {
                +    if (ancestor.disabled) {
                +      return true;
                +    }
                +    ancestor = ancestor.getSurroundParent();
                +  }
                +  // Ran off the top.
                +  return false;
                +};
                +
                +/**
                + * Get whether the block is collapsed or not.
                + * @return {boolean} True if collapsed.
                + */
                +Blockly.Block.prototype.isCollapsed = function() {
                +  return this.collapsed_;
                +};
                +
                +/**
                + * Set whether the block is collapsed or not.
                + * @param {boolean} collapsed True if collapsed.
                + */
                +Blockly.Block.prototype.setCollapsed = function(collapsed) {
                +  if (this.collapsed_ != collapsed) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this, 'collapsed', null, this.collapsed_, collapsed));
                +    this.collapsed_ = collapsed;
                +  }
                +};
                +
                +/**
                + * Create a human-readable text representation of this block and any children.
                + * @param {number=} opt_maxLength Truncate the string to this length.
                + * @param {string=} opt_emptyToken The placeholder string used to denote an
                + *     empty field. If not specified, '?' is used.
                + * @return {string} Text of block.
                + */
                +Blockly.Block.prototype.toString = function(opt_maxLength, opt_emptyToken) {
                +  var text = [];
                +  var emptyFieldPlaceholder = opt_emptyToken || '?';
                +  if (this.collapsed_) {
                +    text.push(this.getInput('_TEMP_COLLAPSED_INPUT').fieldRow[0].text_);
                +  } else {
                +    for (var i = 0, input; input = this.inputList[i]; i++) {
                +      for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +        if (field instanceof Blockly.FieldDropdown && !field.getValue()) {
                +          text.push(emptyFieldPlaceholder);
                +        } else {
                +          text.push(field.getText());
                +        }
                +      }
                +      if (input.connection) {
                +        var child = input.connection.targetBlock();
                +        if (child) {
                +          text.push(child.toString(undefined, opt_emptyToken));
                +        } else {
                +          text.push(emptyFieldPlaceholder);
                +        }
                +      }
                +    }
                +  }
                +  text = goog.string.trim(text.join(' ')) || '???';
                +  if (opt_maxLength) {
                +    // TODO: Improve truncation so that text from this block is given priority.
                +    // E.g. "1+2+3+4+5+6+7+8+9=0" should be "...6+7+8+9=0", not "1+2+3+4+5...".
                +    // E.g. "1+2+3+4+5=6+7+8+9+0" should be "...4+5=6+7...".
                +    text = goog.string.truncate(text, opt_maxLength);
                +  }
                +  return text;
                +};
                +
                +/**
                + * Shortcut for appending a value input row.
                + * @param {string} name Language-neutral identifier which may used to find this
                + *     input again.  Should be unique to this block.
                + * @return {!Blockly.Input} The input object created.
                + */
                +Blockly.Block.prototype.appendValueInput = function(name) {
                +  return this.appendInput_(Blockly.INPUT_VALUE, name);
                +};
                +
                +/**
                + * Shortcut for appending a statement input row.
                + * @param {string} name Language-neutral identifier which may used to find this
                + *     input again.  Should be unique to this block.
                + * @return {!Blockly.Input} The input object created.
                + */
                +Blockly.Block.prototype.appendStatementInput = function(name) {
                +  return this.appendInput_(Blockly.NEXT_STATEMENT, name);
                +};
                +
                +/**
                + * Shortcut for appending a dummy input row.
                + * @param {string=} opt_name Language-neutral identifier which may used to find
                + *     this input again.  Should be unique to this block.
                + * @return {!Blockly.Input} The input object created.
                + */
                +Blockly.Block.prototype.appendDummyInput = function(opt_name) {
                +  return this.appendInput_(Blockly.DUMMY_INPUT, opt_name || '');
                +};
                +
                +/**
                + * Initialize this block using a cross-platform, internationalization-friendly
                + * JSON description.
                + * @param {!Object} json Structured data describing the block.
                + */
                +Blockly.Block.prototype.jsonInit = function(json) {
                +
                +  // Validate inputs.
                +  goog.asserts.assert(json['output'] == undefined ||
                +      json['previousStatement'] == undefined,
                +      'Must not have both an output and a previousStatement.');
                +
                +  // Set basic properties of block.
                +  if (json['colour'] !== undefined) {
                +    var rawValue = json['colour'];
                +    var colour = goog.isString(rawValue) ?
                +        Blockly.utils.replaceMessageReferences(rawValue) : rawValue;
                +    this.setColour(colour);
                +  }
                +
                +  // Interpolate the message blocks.
                +  var i = 0;
                +  while (json['message' + i] !== undefined) {
                +    this.interpolate_(json['message' + i], json['args' + i] || [],
                +        json['lastDummyAlign' + i]);
                +    i++;
                +  }
                +
                +  if (json['inputsInline'] !== undefined) {
                +    this.setInputsInline(json['inputsInline']);
                +  }
                +  // Set output and previous/next connections.
                +  if (json['output'] !== undefined) {
                +    this.setOutput(true, json['output']);
                +  }
                +  if (json['previousStatement'] !== undefined) {
                +    this.setPreviousStatement(true, json['previousStatement']);
                +  }
                +  if (json['nextStatement'] !== undefined) {
                +    this.setNextStatement(true, json['nextStatement']);
                +  }
                +  if (json['tooltip'] !== undefined) {
                +    var rawValue = json['tooltip'];
                +    var localizedText = Blockly.utils.replaceMessageReferences(rawValue);
                +    this.setTooltip(localizedText);
                +  }
                +  if (json['enableContextMenu'] !== undefined) {
                +    var rawValue = json['enableContextMenu'];
                +    this.contextMenu = !!rawValue;
                +  }
                +  if (json['helpUrl'] !== undefined) {
                +    var rawValue = json['helpUrl'];
                +    var localizedValue = Blockly.utils.replaceMessageReferences(rawValue);
                +    this.setHelpUrl(localizedValue);
                +  }
                +  if (goog.isString(json['extensions'])) {
                +    console.warn('JSON attribute \'extensions\' should be an array of ' +
                +      'strings. Found raw string in JSON for \'' + json['type'] + '\' block.');
                +    json['extensions'] = [json['extensions']];  // Correct and continue.
                +  }
                +
                +  // Add the mutator to the block
                +  if (json['mutator'] !== undefined) {
                +    Blockly.Extensions.apply(json['mutator'], this, true);
                +  }
                +
                +  if (Array.isArray(json['extensions'])) {
                +    var extensionNames = json['extensions'];
                +    for (var i = 0; i < extensionNames.length; ++i) {
                +      var extensionName = extensionNames[i];
                +      Blockly.Extensions.apply(extensionName, this, false);
                +    }
                +  }
                +};
                +
                +/**
                + * Add key/values from mixinObj to this block object. By default, this method
                + * will check that the keys in mixinObj will not overwrite existing values in
                + * the block, including prototype values. This provides some insurance against
                + * mixin / extension incompatibilities with future block features. This check
                + * can be disabled by passing true as the second argument.
                + * @param {!Object} mixinObj The key/values pairs to add to this block object.
                + * @param {boolean=} opt_disableCheck Option flag to disable overwrite checks.
                + */
                +Blockly.Block.prototype.mixin = function(mixinObj, opt_disableCheck) {
                +  if (goog.isDef(opt_disableCheck) && !goog.isBoolean(opt_disableCheck)) {
                +    throw new Error("opt_disableCheck must be a boolean if provided");
                +  }
                +  if (!opt_disableCheck) {
                +    var overwrites = [];
                +    for (var key in mixinObj) {
                +      if (this[key] !== undefined) {
                +        overwrites.push(key);
                +      }
                +    }
                +    if (overwrites.length) {
                +      throw new Error('Mixin will overwrite block members: ' +
                +        JSON.stringify(overwrites));
                +    }
                +  }
                +  goog.mixin(this, mixinObj);
                +};
                +
                +/**
                + * Interpolate a message description onto the block.
                + * @param {string} message Text contains interpolation tokens (%1, %2, ...)
                + *     that match with fields or inputs defined in the args array.
                + * @param {!Array} args Array of arguments to be interpolated.
                + * @param {string=} lastDummyAlign If a dummy input is added at the end,
                + *     how should it be aligned?
                + * @private
                + */
                +Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) {
                +  var tokens = Blockly.utils.tokenizeInterpolation(message);
                +  // Interpolate the arguments.  Build a list of elements.
                +  var indexDup = [];
                +  var indexCount = 0;
                +  var elements = [];
                +  for (var i = 0; i < tokens.length; i++) {
                +    var token = tokens[i];
                +    if (typeof token == 'number') {
                +      if (token <= 0 || token > args.length) {
                +        throw new Error('Block \"' + this.type + '\": ' +
                +            'Message index %' + token + ' out of range.');
                +      }
                +      if (indexDup[token]) {
                +        throw new Error('Block \"' + this.type + '\": ' +
                +            'Message index %' + token + ' duplicated.');
                +      }
                +      indexDup[token] = true;
                +      indexCount++;
                +      elements.push(args[token - 1]);
                +    } else {
                +      token = token.trim();
                +      if (token) {
                +        elements.push(token);
                +      }
                +    }
                +  }
                +  if(indexCount != args.length) {
                +    throw new Error('Block \"' + this.type + '\": ' +
                +        'Message does not reference all ' + args.length + ' arg(s).');
                +  }
                +  // Add last dummy input if needed.
                +  if (elements.length && (typeof elements[elements.length - 1] == 'string' ||
                +      goog.string.startsWith(elements[elements.length - 1]['type'],
                +                             'field_'))) {
                +    var dummyInput = {type: 'input_dummy'};
                +    if (lastDummyAlign) {
                +      dummyInput['align'] = lastDummyAlign;
                +    }
                +    elements.push(dummyInput);
                +  }
                +  // Lookup of alignment constants.
                +  var alignmentLookup = {
                +    'LEFT': Blockly.ALIGN_LEFT,
                +    'RIGHT': Blockly.ALIGN_RIGHT,
                +    'CENTRE': Blockly.ALIGN_CENTRE
                +  };
                +  // Populate block with inputs and fields.
                +  var fieldStack = [];
                +  for (var i = 0; i < elements.length; i++) {
                +    var element = elements[i];
                +    if (typeof element == 'string') {
                +      fieldStack.push([element, undefined]);
                +    } else {
                +      var field = null;
                +      var input = null;
                +      do {
                +        var altRepeat = false;
                +        if (typeof element == 'string') {
                +          field = new Blockly.FieldLabel(element);
                +        } else {
                +          switch (element['type']) {
                +            case 'input_value':
                +              input = this.appendValueInput(element['name']);
                +              break;
                +            case 'input_statement':
                +              input = this.appendStatementInput(element['name']);
                +              break;
                +            case 'input_dummy':
                +              input = this.appendDummyInput(element['name']);
                +              break;
                +            case 'field_label':
                +              field = Blockly.Block.newFieldLabelFromJson_(element);
                +              break;
                +            case 'field_input':
                +              field = Blockly.Block.newFieldTextInputFromJson_(element);
                +              break;
                +            case 'field_angle':
                +              field = new Blockly.FieldAngle(element['angle']);
                +              break;
                +            case 'field_checkbox':
                +              field = new Blockly.FieldCheckbox(
                +                  element['checked'] ? 'TRUE' : 'FALSE');
                +              break;
                +            case 'field_colour':
                +              field = new Blockly.FieldColour(element['colour']);
                +              break;
                +            case 'field_variable':
                +              field = Blockly.Block.newFieldVariableFromJson_(element);
                +              break;
                +            case 'field_dropdown':
                +              field = new Blockly.FieldDropdown(element['options']);
                +              break;
                +            case 'field_image':
                +              field = Blockly.Block.newFieldImageFromJson_(element);
                +              break;
                +            case 'field_number':
                +              field = new Blockly.FieldNumber(element['value'],
                +                  element['min'], element['max'], element['precision']);
                +              break;
                +            case 'field_date':
                +              if (Blockly.FieldDate) {
                +                field = new Blockly.FieldDate(element['date']);
                +                break;
                +              }
                +              // Fall through if FieldDate is not compiled in.
                +            default:
                +              // Unknown field.
                +              if (element['alt']) {
                +                element = element['alt'];
                +                altRepeat = true;
                +              }
                +          }
                +        }
                +      } while (altRepeat);
                +      if (field) {
                +        fieldStack.push([field, element['name']]);
                +      } else if (input) {
                +        if (element['check']) {
                +          input.setCheck(element['check']);
                +        }
                +        if (element['align']) {
                +          input.setAlign(alignmentLookup[element['align']]);
                +        }
                +        for (var j = 0; j < fieldStack.length; j++) {
                +          input.appendField(fieldStack[j][0], fieldStack[j][1]);
                +        }
                +        fieldStack.length = 0;
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Helper function to construct a FieldImage from a JSON arg object,
                + * dereferencing any string table references.
                + * @param {!Object} options A JSON object with options (src, width, height, and alt).
                + * @returns {!Blockly.FieldImage} The new image.
                + * @private
                + */
                +Blockly.Block.newFieldImageFromJson_ = function(options) {
                +  var src = Blockly.utils.replaceMessageReferences(options['src']);
                +  var width = Number(Blockly.utils.replaceMessageReferences(options['width']));
                +  var height =
                +    Number(Blockly.utils.replaceMessageReferences(options['height']));
                +  var alt = Blockly.utils.replaceMessageReferences(options['alt']);
                +  return new Blockly.FieldImage(src, width, height, alt);
                +};
                +
                +/**
                + * Helper function to construct a FieldLabel from a JSON arg object,
                + * dereferencing any string table references.
                + * @param {!Object} options A JSON object with options (text, and class).
                + * @returns {!Blockly.FieldLabel} The new label.
                + * @private
                + */
                +Blockly.Block.newFieldLabelFromJson_ = function(options) {
                +  var text = Blockly.utils.replaceMessageReferences(options['text']);
                +  return new Blockly.FieldLabel(text, options['class']);
                +};
                +
                +/**
                + * Helper function to construct a FieldTextInput from a JSON arg object,
                + * dereferencing any string table references.
                + * @param {!Object} options A JSON object with options (text, class, and
                + *                          spellcheck).
                + * @returns {!Blockly.FieldTextInput} The new text input.
                + * @private
                + */
                +Blockly.Block.newFieldTextInputFromJson_ = function(options) {
                +  var text = Blockly.utils.replaceMessageReferences(options['text']);
                +  var field = new Blockly.FieldTextInput(text, options['class']);
                +  if (typeof options['spellcheck'] == 'boolean') {
                +    field.setSpellcheck(options['spellcheck']);
                +  }
                +  return field;
                +};
                +
                +/**
                + * Helper function to construct a FieldVariable from a JSON arg object,
                + * dereferencing any string table references.
                + * @param {!Object} options A JSON object with options (variable).
                + * @returns {!Blockly.FieldVariable} The variable field.
                + * @private
                + */
                +Blockly.Block.newFieldVariableFromJson_ = function(options) {
                +  var varname = Blockly.utils.replaceMessageReferences(options['variable']);
                +  var variableTypes = options['variableTypes'];
                +  return new Blockly.FieldVariable(varname, null, variableTypes);
                +};
                +
                +
                +/**
                + * Add a value input, statement input or local variable to this block.
                + * @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or
                + *     Blockly.DUMMY_INPUT.
                + * @param {string} name Language-neutral identifier which may used to find this
                + *     input again.  Should be unique to this block.
                + * @return {!Blockly.Input} The input object created.
                + * @private
                + */
                +Blockly.Block.prototype.appendInput_ = function(type, name) {
                +  var connection = null;
                +  if (type == Blockly.INPUT_VALUE || type == Blockly.NEXT_STATEMENT) {
                +    connection = this.makeConnection_(type);
                +  }
                +  var input = new Blockly.Input(type, name, this, connection);
                +  // Append input to list.
                +  this.inputList.push(input);
                +  return input;
                +};
                +
                +/**
                + * Move a named input to a different location on this block.
                + * @param {string} name The name of the input to move.
                + * @param {?string} refName Name of input that should be after the moved input,
                + *   or null to be the input at the end.
                + */
                +Blockly.Block.prototype.moveInputBefore = function(name, refName) {
                +  if (name == refName) {
                +    return;
                +  }
                +  // Find both inputs.
                +  var inputIndex = -1;
                +  var refIndex = refName ? -1 : this.inputList.length;
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (input.name == name) {
                +      inputIndex = i;
                +      if (refIndex != -1) {
                +        break;
                +      }
                +    } else if (refName && input.name == refName) {
                +      refIndex = i;
                +      if (inputIndex != -1) {
                +        break;
                +      }
                +    }
                +  }
                +  goog.asserts.assert(inputIndex != -1, 'Named input "%s" not found.', name);
                +  goog.asserts.assert(refIndex != -1, 'Reference input "%s" not found.',
                +                      refName);
                +  this.moveNumberedInputBefore(inputIndex, refIndex);
                +};
                +
                +/**
                + * Move a numbered input to a different location on this block.
                + * @param {number} inputIndex Index of the input to move.
                + * @param {number} refIndex Index of input that should be after the moved input.
                + */
                +Blockly.Block.prototype.moveNumberedInputBefore = function(
                +    inputIndex, refIndex) {
                +  // Validate arguments.
                +  goog.asserts.assert(inputIndex != refIndex, 'Can\'t move input to itself.');
                +  goog.asserts.assert(inputIndex < this.inputList.length,
                +                      'Input index ' + inputIndex + ' out of bounds.');
                +  goog.asserts.assert(refIndex <= this.inputList.length,
                +                      'Reference input ' + refIndex + ' out of bounds.');
                +  // Remove input.
                +  var input = this.inputList[inputIndex];
                +  this.inputList.splice(inputIndex, 1);
                +  if (inputIndex < refIndex) {
                +    refIndex--;
                +  }
                +  // Reinsert input.
                +  this.inputList.splice(refIndex, 0, input);
                +};
                +
                +/**
                + * Remove an input from this block.
                + * @param {string} name The name of the input.
                + * @param {boolean=} opt_quiet True to prevent error if input is not present.
                + * @throws {goog.asserts.AssertionError} if the input is not present and
                + *     opt_quiet is not true.
                + */
                +Blockly.Block.prototype.removeInput = function(name, opt_quiet) {
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (input.name == name) {
                +      if (input.connection && input.connection.isConnected()) {
                +        input.connection.setShadowDom(null);
                +        var block = input.connection.targetBlock();
                +        if (block.isShadow()) {
                +          // Destroy any attached shadow block.
                +          block.dispose();
                +        } else {
                +          // Disconnect any attached normal block.
                +          block.unplug();
                +        }
                +      }
                +      input.dispose();
                +      this.inputList.splice(i, 1);
                +      return;
                +    }
                +  }
                +  if (!opt_quiet) {
                +    goog.asserts.fail('Input "%s" not found.', name);
                +  }
                +};
                +
                +/**
                + * Fetches the named input object.
                + * @param {string} name The name of the input.
                + * @return {Blockly.Input} The input object, or null if input does not exist.
                + */
                +Blockly.Block.prototype.getInput = function(name) {
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (input.name == name) {
                +      return input;
                +    }
                +  }
                +  // This input does not exist.
                +  return null;
                +};
                +
                +/**
                + * Fetches the block attached to the named input.
                + * @param {string} name The name of the input.
                + * @return {Blockly.Block} The attached value block, or null if the input is
                + *     either disconnected or if the input does not exist.
                + */
                +Blockly.Block.prototype.getInputTargetBlock = function(name) {
                +  var input = this.getInput(name);
                +  return input && input.connection && input.connection.targetBlock();
                +};
                +
                +/**
                + * Returns the comment on this block (or '' if none).
                + * @return {string} Block's comment.
                + */
                +Blockly.Block.prototype.getCommentText = function() {
                +  return this.comment || '';
                +};
                +
                +/**
                + * Set this block's comment text.
                + * @param {?string} text The text, or null to delete.
                + */
                +Blockly.Block.prototype.setCommentText = function(text) {
                +  if (this.comment != text) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this, 'comment', null, this.comment, text || ''));
                +    this.comment = text;
                +  }
                +};
                +
                +/**
                + * Set this block's warning text.
                + * @param {?string} text The text, or null to delete.
                + */
                +Blockly.Block.prototype.setWarningText = function(/* text */) {
                +  // NOP.
                +};
                +
                +/**
                + * Give this block a mutator dialog.
                + * @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove.
                + */
                +Blockly.Block.prototype.setMutator = function(/* mutator */) {
                +  // NOP.
                +};
                +
                +/**
                + * Return the coordinates of the top-left corner of this block relative to the
                + * drawing surface's origin (0,0), in workspace units.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties.
                + */
                +Blockly.Block.prototype.getRelativeToSurfaceXY = function() {
                +  return this.xy_;
                +};
                +
                +/**
                + * Move a block by a relative offset.
                + * @param {number} dx Horizontal offset, in workspace units.
                + * @param {number} dy Vertical offset, in workspace units.
                + */
                +Blockly.Block.prototype.moveBy = function(dx, dy) {
                +  goog.asserts.assert(!this.parentBlock_, 'Block has parent.');
                +  var event = new Blockly.Events.BlockMove(this);
                +  this.xy_.translate(dx, dy);
                +  event.recordNew();
                +  Blockly.Events.fire(event);
                +};
                +
                +/**
                + * Create a connection of the specified type.
                + * @param {number} type The type of the connection to create.
                + * @return {!Blockly.Connection} A new connection of the specified type.
                + * @private
                + */
                +Blockly.Block.prototype.makeConnection_ = function(type) {
                +  return new Blockly.Connection(this, type);
                +};
                +
                +/**
                + * Recursively checks whether all statement and value inputs are filled with
                + * blocks. Also checks all following statement blocks in this stack.
                + * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling
                + *     whether shadow blocks are counted as filled. Defaults to true.
                + * @return {boolean} True if all inputs are filled, false otherwise.
                + */
                +Blockly.Block.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) {
                +  // Account for the shadow block filledness toggle.
                +  if (opt_shadowBlocksAreFilled === undefined) {
                +    opt_shadowBlocksAreFilled = true;
                +  }
                +  if (!opt_shadowBlocksAreFilled && this.isShadow()) {
                +    return false;
                +  }
                +
                +  // Recursively check each input block of the current block.
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    if (!input.connection) {
                +      continue;
                +    }
                +    var target = input.connection.targetBlock();
                +    if (!target || !target.allInputsFilled(opt_shadowBlocksAreFilled)) {
                +      return false;
                +    }
                +  }
                +
                +  // Recursively check the next block after the current block.
                +  var next = this.getNextBlock();
                +  if (next) {
                +    return next.allInputsFilled(opt_shadowBlocksAreFilled);
                +  }
                +
                +  return true;
                +};
                +
                +/**
                + * This method returns a string describing this Block in developer terms (type
                + * name and ID; English only).
                + *
                + * Intended to on be used in console logs and errors. If you need a string that
                + * uses the user's native language (including block text, field values, and
                + * child blocks), use [toString()]{@link Blockly.Block#toString}.
                + * @return {string} The description.
                + */
                +Blockly.Block.prototype.toDevString = function() {
                +  var msg = this.type ? '"' + this.type + '" block' : 'Block';
                +  if (this.id) {
                +    msg += ' (id="' + this.id + '")';
                +  }
                +  return msg;
                +};
                diff --git a/blockly/webif/static/blockly/core/block_drag_surface.js b/blockly/webif/static/blockly/core/block_drag_surface.js
                new file mode 100644
                index 000000000..be72fa8e8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/block_drag_surface.js
                @@ -0,0 +1,220 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview A class that manages a surface for dragging blocks.  When a
                + * block drag is started, we move the block (and children) to a separate dom
                + * element that we move around using translate3d. At the end of the drag, the
                + * blocks are put back in into the svg they came from. This helps performance by
                + * avoiding repainting the entire svg on every mouse move while dragging blocks.
                + * @author picklesrus
                + */
                +
                +'use strict';
                +
                +goog.provide('Blockly.BlockDragSurfaceSvg');
                +goog.require('Blockly.utils');
                +goog.require('goog.asserts');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Class for a drag surface for the currently dragged block. This is a separate
                + * SVG that contains only the currently moving block, or nothing.
                + * @param {!Element} container Containing element.
                + * @constructor
                + */
                +Blockly.BlockDragSurfaceSvg = function(container) {
                +  /**
                +   * @type {!Element}
                +   * @private
                +   */
                +  this.container_ = container;
                +  this.createDom();
                +};
                +
                +/**
                + * The SVG drag surface. Set once by Blockly.BlockDragSurfaceSvg.createDom.
                + * @type {Element}
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.SVG_ = null;
                +
                +/**
                + * This is where blocks live while they are being dragged if the drag surface
                + * is enabled.
                + * @type {Element}
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.dragGroup_ = null;
                +
                +/**
                + * Containing HTML element; parent of the workspace and the drag surface.
                + * @type {Element}
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.container_ = null;
                +
                +/**
                + * Cached value for the scale of the drag surface.
                + * Used to set/get the correct translation during and after a drag.
                + * @type {number}
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.scale_ = 1;
                +
                +/**
                + * Cached value for the translation of the drag surface.
                + * This translation is in pixel units, because the scale is applied to the
                + * drag group rather than the top-level SVG.
                + * @type {goog.math.Coordinate}
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_ = null;
                +
                +/**
                + * Create the drag surface and inject it into the container.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.createDom = function() {
                +  if (this.SVG_) {
                +    return;  // Already created.
                +  }
                +  this.SVG_ = Blockly.utils.createSvgElement('svg', {
                +    'xmlns': Blockly.SVG_NS,
                +    'xmlns:html': Blockly.HTML_NS,
                +    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
                +    'version': '1.1',
                +    'class': 'blocklyBlockDragSurface'
                +  }, this.container_);
                +  this.dragGroup_ = Blockly.utils.createSvgElement('g', {}, this.SVG_);
                +};
                +
                +/**
                + * Set the SVG blocks on the drag surface's group and show the surface.
                + * Only one block group should be on the drag surface at a time.
                + * @param {!Element} blocks Block or group of blocks to place on the drag
                + * surface.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow = function(blocks) {
                +  goog.asserts.assert(this.dragGroup_.childNodes.length == 0,
                +    'Already dragging a block.');
                +  // appendChild removes the blocks from the previous parent
                +  this.dragGroup_.appendChild(blocks);
                +  this.SVG_.style.display = 'block';
                +  this.surfaceXY_ = new goog.math.Coordinate(0, 0);
                +};
                +
                +/**
                + * Translate and scale the entire drag surface group to the given position, to
                + * keep in sync with the workspace.
                + * @param {number} x X translation in workspace coordinates.
                + * @param {number} y Y translation in workspace coordinates.
                + * @param {number} scale Scale of the group.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.translateAndScaleGroup = function(x, y, scale) {
                +  this.scale_ = scale;
                +  // This is a work-around to prevent a the blocks from rendering
                +  // fuzzy while they are being dragged on the drag surface.
                +  x = x.toFixed(0);
                +  y = y.toFixed(0);
                +  this.dragGroup_.setAttribute('transform', 'translate('+ x + ','+ y + ')' +
                +      ' scale(' + scale + ')');
                +};
                +
                +/**
                + * Translate the drag surface's SVG based on its internal state.
                + * @private
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_ = function() {
                +  var x = this.surfaceXY_.x;
                +  var y = this.surfaceXY_.y;
                +  // This is a work-around to prevent a the blocks from rendering
                +  // fuzzy while they are being dragged on the drag surface.
                +  x = x.toFixed(0);
                +  y = y.toFixed(0);
                +  this.SVG_.style.display = 'block';
                +
                +  Blockly.utils.setCssTransform(this.SVG_,
                +      'translate3d(' + x + 'px, ' + y + 'px, 0px)');
                +};
                +
                +/**
                + * Translate the entire drag surface during a drag.
                + * We translate the drag surface instead of the blocks inside the surface
                + * so that the browser avoids repainting the SVG.
                + * Because of this, the drag coordinates must be adjusted by scale.
                + * @param {number} x X translation for the entire surface.
                + * @param {number} y Y translation for the entire surface.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.translateSurface = function(x, y) {
                +  this.surfaceXY_ = new goog.math.Coordinate(x * this.scale_, y * this.scale_);
                +  this.translateSurfaceInternal_();
                +};
                +
                +/**
                + * Reports the surface translation in scaled workspace coordinates.
                + * Use this when finishing a drag to return blocks to the correct position.
                + * @return {!goog.math.Coordinate} Current translation of the surface.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation = function() {
                +  var xy = Blockly.utils.getRelativeXY(this.SVG_);
                +  return new goog.math.Coordinate(xy.x / this.scale_, xy.y / this.scale_);
                +};
                +
                +/**
                + * Provide a reference to the drag group (primarily for
                + * BlockSvg.getRelativeToSurfaceXY).
                + * @return {Element} Drag surface group element.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.getGroup = function() {
                +  return this.dragGroup_;
                +};
                +
                +/**
                + * Get the current blocks on the drag surface, if any (primarily
                + * for BlockSvg.getRelativeToSurfaceXY).
                + * @return {!Element|undefined} Drag surface block DOM element, or undefined
                + * if no blocks exist.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock = function() {
                +  return this.dragGroup_.firstChild;
                +};
                +
                +/**
                + * Clear the group and hide the surface; move the blocks off onto the provided
                + * element.
                + * If the block is being deleted it doesn't need to go back to the original
                + * surface, since it would be removed immediately during dispose.
                + * @param {Element} opt_newSurface Surface the dragging blocks should be moved
                + *     to, or null if the blocks should be removed from this surface without
                + *     being moved to a different surface.
                + */
                +Blockly.BlockDragSurfaceSvg.prototype.clearAndHide = function(opt_newSurface) {
                +  if (opt_newSurface) {
                +    // appendChild removes the node from this.dragGroup_
                +    opt_newSurface.appendChild(this.getCurrentBlock());
                +  } else {
                +    this.dragGroup_.removeChild(this.getCurrentBlock());
                +  }
                +  this.SVG_.style.display = 'none';
                +  goog.asserts.assert(this.dragGroup_.childNodes.length == 0,
                +    'Drag group was not cleared.');
                +  this.surfaceXY_ = null;
                +};
                diff --git a/blockly/webif/static/blockly/core/block_dragger.js b/blockly/webif/static/blockly/core/block_dragger.js
                new file mode 100644
                index 000000000..0ba1749f0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/block_dragger.js
                @@ -0,0 +1,324 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Methods for dragging a block visually.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.BlockDragger');
                +
                +goog.require('Blockly.DraggedConnectionManager');
                +
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.asserts');
                +
                +
                +/**
                + * Class for a block dragger.  It moves blocks around the workspace when they
                + * are being dragged by a mouse or touch.
                + * @param {!Blockly.Block} block The block to drag.
                + * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
                + * @constructor
                + */
                +Blockly.BlockDragger = function(block, workspace) {
                +  /**
                +   * The top block in the stack that is being dragged.
                +   * @type {!Blockly.BlockSvg}
                +   * @private
                +   */
                +  this.draggingBlock_ = block;
                +
                +  /**
                +   * The workspace on which the block is being dragged.
                +   * @type {!Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.workspace_ = workspace;
                +
                +  /**
                +   * Object that keeps track of connections on dragged blocks.
                +   * @type {!Blockly.DraggedConnectionManager}
                +   * @private
                +   */
                +  this.draggedConnectionManager_ = new Blockly.DraggedConnectionManager(
                +      this.draggingBlock_);
                +
                +  /**
                +   * Which delete area the mouse pointer is over, if any.
                +   * One of {@link Blockly.DELETE_AREA_TRASH},
                +   * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
                +   * @type {?number}
                +   * @private
                +   */
                +  this.deleteArea_ = null;
                +
                +  /**
                +   * Whether the block would be deleted if dropped immediately.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.wouldDeleteBlock_ = false;
                +
                +  /**
                +   * The location of the top left corner of the dragging block at the beginning
                +   * of the drag in workspace coordinates.
                +   * @type {!goog.math.Coordinate}
                +   * @private
                +   */
                +  this.startXY_ = this.draggingBlock_.getRelativeToSurfaceXY();
                +
                +  /**
                +   * A list of all of the icons (comment, warning, and mutator) that are
                +   * on this block and its descendants.  Moving an icon moves the bubble that
                +   * extends from it if that bubble is open.
                +   * @type {Array.<!Object>}
                +   * @private
                +   */
                +  this.dragIconData_ = Blockly.BlockDragger.initIconData_(block);
                +};
                +
                +/**
                + * Sever all links from this object.
                + * @package
                + */
                +Blockly.BlockDragger.prototype.dispose = function() {
                +  this.draggingBlock_ = null;
                +  this.workspace_ = null;
                +  this.startWorkspace_ = null;
                +  this.dragIconData_.length = 0;
                +
                +  if (this.draggedConnectionManager_) {
                +    this.draggedConnectionManager_.dispose();
                +    this.draggedConnectionManager_ = null;
                +  }
                +};
                +
                +/**
                + * Make a list of all of the icons (comment, warning, and mutator) that are
                + * on this block and its descendants.  Moving an icon moves the bubble that
                + * extends from it if that bubble is open.
                + * @param {!Blockly.BlockSvg} block The root block that is being dragged.
                + * @return {!Array.<!Object>} The list of all icons and their locations.
                + * @private
                + */
                +Blockly.BlockDragger.initIconData_ = function(block) {
                +  // Build a list of icons that need to be moved and where they started.
                +  var dragIconData = [];
                +  var descendants = block.getDescendants();
                +  for (var i = 0, descendant; descendant = descendants[i]; i++) {
                +    var icons = descendant.getIcons();
                +    for (var j = 0; j < icons.length; j++) {
                +      var data = {
                +        // goog.math.Coordinate with x and y properties (workspace coordinates).
                +        location: icons[j].getIconLocation(),
                +        // Blockly.Icon
                +        icon: icons[j]
                +      };
                +      dragIconData.push(data);
                +    }
                +  }
                +  return dragIconData;
                +};
                +
                +/**
                + * Start dragging a block.  This includes moving it to the drag surface.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at mouse down, in pixel units.
                + * @package
                + */
                +Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY) {
                +  if (!Blockly.Events.getGroup()) {
                +    Blockly.Events.setGroup(true);
                +  }
                +
                +  this.workspace_.setResizesEnabled(false);
                +  Blockly.BlockSvg.disconnectUiStop_();
                +
                +  if (this.draggingBlock_.getParent()) {
                +    this.draggingBlock_.unplug();
                +    var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
                +    var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
                +
                +    this.draggingBlock_.translate(newLoc.x, newLoc.y);
                +    this.draggingBlock_.disconnectUiEffect();
                +  }
                +  this.draggingBlock_.setDragging(true);
                +  // For future consideration: we may be able to put moveToDragSurface inside
                +  // the block dragger, which would also let the block not track the block drag
                +  // surface.
                +  this.draggingBlock_.moveToDragSurface_();
                +
                +  if (this.workspace_.toolbox_) {
                +    this.workspace_.toolbox_.addDeleteStyle();
                +  }
                +};
                +
                +/**
                + * Execute a step of block dragging, based on the given event.  Update the
                + * display accordingly.
                + * @param {!Event} e The most recent move event.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at the start of the drag, in pixel units.
                + * @package
                + */
                +Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
                +  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
                +  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
                +
                +  this.draggingBlock_.moveDuringDrag(newLoc);
                +  this.dragIcons_(delta);
                +
                +  this.deleteArea_ = this.workspace_.isDeleteArea(e);
                +  this.draggedConnectionManager_.update(delta, this.deleteArea_);
                +
                +  this.updateCursorDuringBlockDrag_();
                +};
                +
                +/**
                + * Finish a block drag and put the block back on the workspace.
                + * @param {!Event} e The mouseup/touchend event.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at the start of the drag, in pixel units.
                + * @package
                + */
                +Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
                +  // Make sure internal state is fresh.
                +  this.dragBlock(e, currentDragDeltaXY);
                +  this.dragIconData_ = [];
                +
                +  Blockly.BlockSvg.disconnectUiStop_();
                +
                +  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
                +  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
                +  this.draggingBlock_.moveOffDragSurface_(newLoc);
                +
                +  var deleted = this.maybeDeleteBlock_();
                +  if (!deleted) {
                +    // These are expensive and don't need to be done if we're deleting.
                +    this.draggingBlock_.moveConnections_(delta.x, delta.y);
                +    this.draggingBlock_.setDragging(false);
                +    this.draggedConnectionManager_.applyConnections();
                +    this.draggingBlock_.render();
                +    this.fireMoveEvent_();
                +    this.draggingBlock_.scheduleSnapAndBump();
                +  }
                +  this.workspace_.setResizesEnabled(true);
                +
                +  if (this.workspace_.toolbox_) {
                +    this.workspace_.toolbox_.removeDeleteStyle();
                +  }
                +  Blockly.Events.setGroup(false);
                +};
                +
                +/**
                + * Fire a move event at the end of a block drag.
                + * @private
                + */
                +Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
                +  var event = new Blockly.Events.BlockMove(this.draggingBlock_);
                +  event.oldCoordinate = this.startXY_;
                +  event.recordNew();
                +  Blockly.Events.fire(event);
                +};
                +
                +/**
                + * Shut the trash can and, if necessary, delete the dragging block.
                + * Should be called at the end of a block drag.
                + * @return {boolean} whether the block was deleted.
                + * @private
                + */
                +Blockly.BlockDragger.prototype.maybeDeleteBlock_ = function() {
                +  var trashcan = this.workspace_.trashcan;
                +
                +  if (this.wouldDeleteBlock_) {
                +    if (trashcan) {
                +      goog.Timer.callOnce(trashcan.close, 100, trashcan);
                +    }
                +    // Fire a move event, so we know where to go back to for an undo.
                +    this.fireMoveEvent_();
                +    this.draggingBlock_.dispose(false, true);
                +  } else if (trashcan) {
                +    // Make sure the trash can is closed.
                +    trashcan.close();
                +  }
                +  return this.wouldDeleteBlock_;
                +};
                +
                +/**
                + * Update the cursor (and possibly the trash can lid) to reflect whether the
                + * dragging block would be deleted if released immediately.
                + * @private
                + */
                +Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function() {
                +  this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock();
                +  var trashcan = this.workspace_.trashcan;
                +  if (this.wouldDeleteBlock_) {
                +    this.draggingBlock_.setDeleteStyle(true);
                +    if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
                +      trashcan.setOpen_(true);
                +    }
                +  } else {
                +    this.draggingBlock_.setDeleteStyle(false);
                +    if (trashcan) {
                +      trashcan.setOpen_(false);
                +    }
                +  }
                +};
                +
                +/**
                + * Convert a coordinate object from pixels to workspace units, including a
                + * correction for mutator workspaces.
                + * This function does not consider differing origins.  It simply scales the
                + * input's x and y values.
                + * @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
                + *     in css pixel units.
                + * @return {!goog.math.Coordinate} The input coordinate divided by the workspace
                + *     scale.
                + * @private
                + */
                +Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
                +  var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
                +      pixelCoord.y / this.workspace_.scale);
                +  if (this.workspace_.isMutator) {
                +    // If we're in a mutator, its scale is always 1, purely because of some
                +    // oddities in our rendering optimizations.  The actual scale is the same as
                +    // the scale on the parent workspace.
                +    // Fix that for dragging.
                +    var mainScale = this.workspace_.options.parentWorkspace.scale;
                +    result = result.scale(1 / mainScale);
                +  }
                +  return result;
                +};
                +
                +/**
                + * Move all of the icons connected to this drag.
                + * @param {!goog.math.Coordinate} dxy How far to move the icons from their
                + *     original positions, in workspace units.
                + * @private
                + */
                +Blockly.BlockDragger.prototype.dragIcons_ = function(dxy) {
                +  // Moving icons moves their associated bubbles.
                +  for (var i = 0; i < this.dragIconData_.length; i++) {
                +    var data = this.dragIconData_[i];
                +    data.icon.setIconLocation(goog.math.Coordinate.sum(data.location, dxy));
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/block_render_svg.js b/blockly/webif/static/blockly/core/block_render_svg.js
                new file mode 100644
                index 000000000..4c3bfb33b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/block_render_svg.js
                @@ -0,0 +1,1000 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Methods for graphically rendering a block as SVG.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +
                +'use strict';
                +
                +goog.provide('Blockly.BlockSvg.render');
                +
                +goog.require('Blockly.BlockSvg');
                +
                +goog.require('goog.userAgent');
                +
                +
                +// UI constants for rendering blocks.
                +/**
                + * Horizontal space between elements.
                + * @const
                + */
                +Blockly.BlockSvg.SEP_SPACE_X = 10;
                +/**
                + * Vertical space between elements.
                + * @const
                + */
                +Blockly.BlockSvg.SEP_SPACE_Y = 10;
                +/**
                + * Vertical padding around inline elements.
                + * @const
                + */
                +Blockly.BlockSvg.INLINE_PADDING_Y = 5;
                +/**
                + * Minimum height of a block.
                + * @const
                + */
                +Blockly.BlockSvg.MIN_BLOCK_Y = 25;
                +/**
                + * Height of horizontal puzzle tab.
                + * @const
                + */
                +Blockly.BlockSvg.TAB_HEIGHT = 20;
                +/**
                + * Width of horizontal puzzle tab.
                + * @const
                + */
                +Blockly.BlockSvg.TAB_WIDTH = 8;
                +/**
                + * Width of vertical tab (inc left margin).
                + * @const
                + */
                +Blockly.BlockSvg.NOTCH_WIDTH = 30;
                +/**
                + * Rounded corner radius.
                + * @const
                + */
                +Blockly.BlockSvg.CORNER_RADIUS = 8;
                +/**
                + * Do blocks with no previous or output connections have a 'hat' on top?
                + * @const
                + */
                +Blockly.BlockSvg.START_HAT = false;
                +/**
                + * Height of the top hat.
                + * @const
                + */
                +Blockly.BlockSvg.START_HAT_HEIGHT = 15;
                +/**
                + * Path of the top hat's curve.
                + * @const
                + */
                +Blockly.BlockSvg.START_HAT_PATH = 'c 30,-' +
                +    Blockly.BlockSvg.START_HAT_HEIGHT + ' 70,-' +
                +    Blockly.BlockSvg.START_HAT_HEIGHT + ' 100,0';
                +/**
                + * Path of the top hat's curve's highlight in LTR.
                + * @const
                + */
                +Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR =
                +    'c 17.8,-9.2 45.3,-14.9 75,-8.7 M 100.5,0.5';
                +/**
                + * Path of the top hat's curve's highlight in RTL.
                + * @const
                + */
                +Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL =
                +    'm 25,-8.7 c 29.7,-6.2 57.2,-0.5 75,8.7';
                +/**
                + * Distance from shape edge to intersect with a curved corner at 45 degrees.
                + * Applies to highlighting on around the inside of a curve.
                + * @const
                + */
                +Blockly.BlockSvg.DISTANCE_45_INSIDE = (1 - Math.SQRT1_2) *
                +    (Blockly.BlockSvg.CORNER_RADIUS - 0.5) + 0.5;
                +/**
                + * Distance from shape edge to intersect with a curved corner at 45 degrees.
                + * Applies to highlighting on around the outside of a curve.
                + * @const
                + */
                +Blockly.BlockSvg.DISTANCE_45_OUTSIDE = (1 - Math.SQRT1_2) *
                +    (Blockly.BlockSvg.CORNER_RADIUS + 0.5) - 0.5;
                +/**
                + * SVG path for drawing next/previous notch from left to right.
                + * @const
                + */
                +Blockly.BlockSvg.NOTCH_PATH_LEFT = 'l 6,4 3,0 6,-4';
                +/**
                + * SVG path for drawing next/previous notch from left to right with
                + * highlighting.
                + * @const
                + */
                +Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT = 'l 6,4 3,0 6,-4';
                +/**
                + * SVG path for drawing next/previous notch from right to left.
                + * @const
                + */
                +Blockly.BlockSvg.NOTCH_PATH_RIGHT = 'l -6,4 -3,0 -6,-4';
                +/**
                + * SVG path for drawing jagged teeth at the end of collapsed blocks.
                + * @const
                + */
                +Blockly.BlockSvg.JAGGED_TEETH = 'l 8,0 0,4 8,4 -16,8 8,4';
                +/**
                + * Height of SVG path for jagged teeth at the end of collapsed blocks.
                + * @const
                + */
                +Blockly.BlockSvg.JAGGED_TEETH_HEIGHT = 20;
                +/**
                + * Width of SVG path for jagged teeth at the end of collapsed blocks.
                + * @const
                + */
                +Blockly.BlockSvg.JAGGED_TEETH_WIDTH = 15;
                +/**
                + * SVG path for drawing a horizontal puzzle tab from top to bottom.
                + * @const
                + */
                +Blockly.BlockSvg.TAB_PATH_DOWN = 'v 5 c 0,10 -' + Blockly.BlockSvg.TAB_WIDTH +
                +    ',-8 -' + Blockly.BlockSvg.TAB_WIDTH + ',7.5 s ' +
                +    Blockly.BlockSvg.TAB_WIDTH + ',-2.5 ' + Blockly.BlockSvg.TAB_WIDTH + ',7.5';
                +/**
                + * SVG path for drawing a horizontal puzzle tab from top to bottom with
                + * highlighting from the upper-right.
                + * @const
                + */
                +Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL = 'v 6.5 m -' +
                +    (Blockly.BlockSvg.TAB_WIDTH * 0.97) + ',3 q -' +
                +    (Blockly.BlockSvg.TAB_WIDTH * 0.05) + ',10 ' +
                +    (Blockly.BlockSvg.TAB_WIDTH * 0.3) + ',9.5 m ' +
                +    (Blockly.BlockSvg.TAB_WIDTH * 0.67) + ',-1.9 v 1.4';
                +
                +/**
                + * SVG start point for drawing the top-left corner.
                + * @const
                + */
                +Blockly.BlockSvg.TOP_LEFT_CORNER_START =
                +    'm 0,' + Blockly.BlockSvg.CORNER_RADIUS;
                +/**
                + * SVG start point for drawing the top-left corner's highlight in RTL.
                + * @const
                + */
                +Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL =
                +    'm ' + Blockly.BlockSvg.DISTANCE_45_INSIDE + ',' +
                +    Blockly.BlockSvg.DISTANCE_45_INSIDE;
                +/**
                + * SVG start point for drawing the top-left corner's highlight in LTR.
                + * @const
                + */
                +Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR =
                +    'm 0.5,' + (Blockly.BlockSvg.CORNER_RADIUS - 0.5);
                +/**
                + * SVG path for drawing the rounded top-left corner.
                + * @const
                + */
                +Blockly.BlockSvg.TOP_LEFT_CORNER =
                +    'A ' + Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 ' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ',0';
                +/**
                + * SVG path for drawing the highlight on the rounded top-left corner.
                + * @const
                + */
                +Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT =
                +    'A ' + (Blockly.BlockSvg.CORNER_RADIUS - 0.5) + ',' +
                +    (Blockly.BlockSvg.CORNER_RADIUS - 0.5) + ' 0 0,1 ' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ',0.5';
                +/**
                + * SVG path for drawing the top-left corner of a statement input.
                + * Includes the top notch, a horizontal space, and the rounded inside corner.
                + * @const
                + */
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER =
                +    Blockly.BlockSvg.NOTCH_PATH_RIGHT + ' h -' +
                +    (Blockly.BlockSvg.NOTCH_WIDTH - 15 - Blockly.BlockSvg.CORNER_RADIUS) +
                +    ' a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 -' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS;
                +/**
                + * SVG path for drawing the bottom-left corner of a statement input.
                + * Includes the rounded inside corner.
                + * @const
                + */
                +Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER =
                +    'a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS;
                +/**
                + * SVG path for drawing highlight on the top-left corner of a statement
                + * input in RTL.
                + * @const
                + */
                +Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL =
                +    'a ' + Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +    Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,0 ' +
                +    (-Blockly.BlockSvg.DISTANCE_45_OUTSIDE - 0.5) + ',' +
                +    (Blockly.BlockSvg.CORNER_RADIUS -
                +    Blockly.BlockSvg.DISTANCE_45_OUTSIDE);
                +/**
                + * SVG path for drawing highlight on the bottom-left corner of a statement
                + * input in RTL.
                + * @const
                + */
                +Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL =
                +    'a ' + (Blockly.BlockSvg.CORNER_RADIUS + 0.5) + ',' +
                +    (Blockly.BlockSvg.CORNER_RADIUS + 0.5) + ' 0 0,0 ' +
                +    (Blockly.BlockSvg.CORNER_RADIUS + 0.5) + ',' +
                +    (Blockly.BlockSvg.CORNER_RADIUS + 0.5);
                +/**
                + * SVG path for drawing highlight on the bottom-left corner of a statement
                + * input in LTR.
                + * @const
                + */
                +Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR =
                +    'a ' + (Blockly.BlockSvg.CORNER_RADIUS + 0.5) + ',' +
                +    (Blockly.BlockSvg.CORNER_RADIUS + 0.5) + ' 0 0,0 ' +
                +    (Blockly.BlockSvg.CORNER_RADIUS -
                +    Blockly.BlockSvg.DISTANCE_45_OUTSIDE) + ',' +
                +    (Blockly.BlockSvg.DISTANCE_45_OUTSIDE + 0.5);
                +
                +/**
                + * Returns a bounding box describing the dimensions of this block
                + * and any blocks stacked below it.
                + * @return {!{height: number, width: number}} Object with height and width
                + *    properties in workspace units.
                + */
                +Blockly.BlockSvg.prototype.getHeightWidth = function() {
                +  var height = this.height;
                +  var width = this.width;
                +  // Recursively add size of subsequent blocks.
                +  var nextBlock = this.getNextBlock();
                +  if (nextBlock) {
                +    var nextHeightWidth = nextBlock.getHeightWidth();
                +    height += nextHeightWidth.height - 4;  // Height of tab.
                +    width = Math.max(width, nextHeightWidth.width);
                +  } else if (!this.nextConnection && !this.outputConnection) {
                +    // Add a bit of margin under blocks with no bottom tab.
                +    height += 2;
                +  }
                +  return {height: height, width: width};
                +};
                +
                +/**
                + * Render the block.
                + * Lays out and reflows a block based on its contents and settings.
                + * @param {boolean=} opt_bubble If false, just render this block.
                + *   If true, also render block's parent, grandparent, etc.  Defaults to true.
                + */
                +Blockly.BlockSvg.prototype.render = function(opt_bubble) {
                +  Blockly.Field.startCache();
                +  this.rendered = true;
                +
                +  var cursorX = Blockly.BlockSvg.SEP_SPACE_X;
                +  if (this.RTL) {
                +    cursorX = -cursorX;
                +  }
                +  // Move the icons into position.
                +  var icons = this.getIcons();
                +  for (var i = 0; i < icons.length; i++) {
                +    cursorX = icons[i].renderIcon(cursorX);
                +  }
                +  cursorX += this.RTL ?
                +      Blockly.BlockSvg.SEP_SPACE_X : -Blockly.BlockSvg.SEP_SPACE_X;
                +  // If there are no icons, cursorX will be 0, otherwise it will be the
                +  // width that the first label needs to move over by.
                +
                +  var inputRows = this.renderCompute_(cursorX);
                +  this.renderDraw_(cursorX, inputRows);
                +  this.renderMoveConnections_();
                +
                +  if (opt_bubble !== false) {
                +    // Render all blocks above this one (propagate a reflow).
                +    var parentBlock = this.getParent();
                +    if (parentBlock) {
                +      parentBlock.render(true);
                +    } else {
                +      // Top-most block.  Fire an event to allow scrollbars to resize.
                +      this.workspace.resizeContents();
                +    }
                +  }
                +  Blockly.Field.stopCache();
                +};
                +
                +/**
                + * Render a list of fields starting at the specified location.
                + * @param {!Array.<!Blockly.Field>} fieldList List of fields.
                + * @param {number} cursorX X-coordinate to start the fields.
                + * @param {number} cursorY Y-coordinate to start the fields.
                + * @return {number} X-coordinate of the end of the field row (plus a gap).
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderFields_ =
                +    function(fieldList, cursorX, cursorY) {
                +  /* eslint-disable indent */
                +  cursorY += Blockly.BlockSvg.INLINE_PADDING_Y;
                +  if (this.RTL) {
                +    cursorX = -cursorX;
                +  }
                +  for (var t = 0, field; field = fieldList[t]; t++) {
                +    var root = field.getSvgRoot();
                +    if (!root) {
                +      continue;
                +    }
                +
                +    // Force a width re-calculation on IE and Edge to get around the issue
                +    // described in Blockly.Field.getCachedWidth
                +    if (goog.userAgent.IE || goog.userAgent.EDGE) {
                +      field.updateWidth();
                +    }
                +
                +    if (this.RTL) {
                +      cursorX -= field.renderSep + field.renderWidth;
                +      root.setAttribute('transform',
                +          'translate(' + cursorX + ',' + cursorY + ')');
                +      if (field.renderWidth) {
                +        cursorX -= Blockly.BlockSvg.SEP_SPACE_X;
                +      }
                +    } else {
                +      root.setAttribute('transform',
                +          'translate(' + (cursorX + field.renderSep) + ',' + cursorY + ')');
                +      if (field.renderWidth) {
                +        cursorX += field.renderSep + field.renderWidth +
                +            Blockly.BlockSvg.SEP_SPACE_X;
                +      }
                +    }
                +  }
                +  return this.RTL ? -cursorX : cursorX;
                +};  /* eslint-enable indent */
                +
                +/**
                + * Computes the height and widths for each row and field.
                + * @param {number} iconWidth Offset of first row due to icons.
                + * @return {!Array.<!Array.<!Object>>} 2D array of objects, each containing
                + *     position information.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderCompute_ = function(iconWidth) {
                +  var inputList = this.inputList;
                +  var inputRows = [];
                +  inputRows.rightEdge = iconWidth + Blockly.BlockSvg.SEP_SPACE_X * 2;
                +  if (this.previousConnection || this.nextConnection) {
                +    inputRows.rightEdge = Math.max(inputRows.rightEdge,
                +        Blockly.BlockSvg.NOTCH_WIDTH + Blockly.BlockSvg.SEP_SPACE_X);
                +  }
                +  var fieldValueWidth = 0;  // Width of longest external value field.
                +  var fieldStatementWidth = 0;  // Width of longest statement field.
                +  var hasValue = false;
                +  var hasStatement = false;
                +  var hasDummy = false;
                +  var lastType = undefined;
                +  var isInline = this.getInputsInline() && !this.isCollapsed();
                +  for (var i = 0, input; input = inputList[i]; i++) {
                +    if (!input.isVisible()) {
                +      continue;
                +    }
                +    var row;
                +    if (!isInline || !lastType ||
                +        lastType == Blockly.NEXT_STATEMENT ||
                +        input.type == Blockly.NEXT_STATEMENT) {
                +      // Create new row.
                +      lastType = input.type;
                +      row = [];
                +      if (isInline && input.type != Blockly.NEXT_STATEMENT) {
                +        row.type = Blockly.BlockSvg.INLINE;
                +      } else {
                +        row.type = input.type;
                +      }
                +      row.height = 0;
                +      inputRows.push(row);
                +    } else {
                +      row = inputRows[inputRows.length - 1];
                +    }
                +    row.push(input);
                +
                +    // Compute minimum input size.
                +    input.renderHeight = Blockly.BlockSvg.MIN_BLOCK_Y;
                +    // The width is currently only needed for inline value inputs.
                +    if (isInline && input.type == Blockly.INPUT_VALUE) {
                +      input.renderWidth = Blockly.BlockSvg.TAB_WIDTH +
                +          Blockly.BlockSvg.SEP_SPACE_X * 1.25;
                +    } else {
                +      input.renderWidth = 0;
                +    }
                +    // Expand input size if there is a connection.
                +    if (input.connection && input.connection.isConnected()) {
                +      var linkedBlock = input.connection.targetBlock();
                +      var bBox = linkedBlock.getHeightWidth();
                +      input.renderHeight = Math.max(input.renderHeight, bBox.height);
                +      input.renderWidth = Math.max(input.renderWidth, bBox.width);
                +    }
                +    // Blocks have a one pixel shadow that should sometimes overhang.
                +    if (!isInline && i == inputList.length - 1) {
                +      // Last value input should overhang.
                +      input.renderHeight--;
                +    } else if (!isInline && input.type == Blockly.INPUT_VALUE &&
                +        inputList[i + 1] && inputList[i + 1].type == Blockly.NEXT_STATEMENT) {
                +      // Value input above statement input should overhang.
                +      input.renderHeight--;
                +    }
                +
                +    row.height = Math.max(row.height, input.renderHeight);
                +    input.fieldWidth = 0;
                +    if (inputRows.length == 1) {
                +      // The first row gets shifted to accommodate any icons.
                +      input.fieldWidth += this.RTL ? -iconWidth : iconWidth;
                +    }
                +    var previousFieldEditable = false;
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      if (j != 0) {
                +        input.fieldWidth += Blockly.BlockSvg.SEP_SPACE_X;
                +      }
                +      // Get the dimensions of the field.
                +      var fieldSize = field.getSize();
                +      field.renderWidth = fieldSize.width;
                +      field.renderSep = (previousFieldEditable && field.EDITABLE) ?
                +          Blockly.BlockSvg.SEP_SPACE_X : 0;
                +      input.fieldWidth += field.renderWidth + field.renderSep;
                +      row.height = Math.max(row.height, fieldSize.height);
                +      previousFieldEditable = field.EDITABLE;
                +    }
                +
                +    if (row.type != Blockly.BlockSvg.INLINE) {
                +      if (row.type == Blockly.NEXT_STATEMENT) {
                +        hasStatement = true;
                +        fieldStatementWidth = Math.max(fieldStatementWidth, input.fieldWidth);
                +      } else {
                +        if (row.type == Blockly.INPUT_VALUE) {
                +          hasValue = true;
                +        } else if (row.type == Blockly.DUMMY_INPUT) {
                +          hasDummy = true;
                +        }
                +        fieldValueWidth = Math.max(fieldValueWidth, input.fieldWidth);
                +      }
                +    }
                +  }
                +
                +  // Make inline rows a bit thicker in order to enclose the values.
                +  for (var y = 0, row; row = inputRows[y]; y++) {
                +    row.thicker = false;
                +    if (row.type == Blockly.BlockSvg.INLINE) {
                +      for (var z = 0, input; input = row[z]; z++) {
                +        if (input.type == Blockly.INPUT_VALUE) {
                +          row.height += 2 * Blockly.BlockSvg.INLINE_PADDING_Y;
                +          row.thicker = true;
                +          break;
                +        }
                +      }
                +    }
                +  }
                +
                +  // Compute the statement edge.
                +  // This is the width of a block where statements are nested.
                +  inputRows.statementEdge = 2 * Blockly.BlockSvg.SEP_SPACE_X +
                +      fieldStatementWidth;
                +  // Compute the preferred right edge.  Inline blocks may extend beyond.
                +  // This is the width of the block where external inputs connect.
                +  if (hasStatement) {
                +    inputRows.rightEdge = Math.max(inputRows.rightEdge,
                +        inputRows.statementEdge + Blockly.BlockSvg.NOTCH_WIDTH);
                +  }
                +  if (hasValue) {
                +    inputRows.rightEdge = Math.max(inputRows.rightEdge, fieldValueWidth +
                +        Blockly.BlockSvg.SEP_SPACE_X * 2 + Blockly.BlockSvg.TAB_WIDTH);
                +  } else if (hasDummy) {
                +    inputRows.rightEdge = Math.max(inputRows.rightEdge, fieldValueWidth +
                +        Blockly.BlockSvg.SEP_SPACE_X * 2);
                +  }
                +
                +  inputRows.hasValue = hasValue;
                +  inputRows.hasStatement = hasStatement;
                +  inputRows.hasDummy = hasDummy;
                +  return inputRows;
                +};
                +
                +
                +/**
                + * Draw the path of the block.
                + * Move the fields to the correct locations.
                + * @param {number} iconWidth Offset of first row due to icons.
                + * @param {!Array.<!Array.<!Object>>} inputRows 2D array of objects, each
                + *     containing position information.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderDraw_ = function(iconWidth, inputRows) {
                +  this.startHat_ = false;
                +  // Reset the height to zero and let the rendering process add in
                +  // portions of the block height as it goes. (e.g. hats, inputs, etc.)
                +  this.height = 0;
                +  // Should the top and bottom left corners be rounded or square?
                +  if (this.outputConnection) {
                +    this.squareTopLeftCorner_ = true;
                +    this.squareBottomLeftCorner_ = true;
                +  } else {
                +    this.squareTopLeftCorner_ = false;
                +    this.squareBottomLeftCorner_ = false;
                +    // If this block is in the middle of a stack, square the corners.
                +    if (this.previousConnection) {
                +      var prevBlock = this.previousConnection.targetBlock();
                +      if (prevBlock && prevBlock.getNextBlock() == this) {
                +        this.squareTopLeftCorner_ = true;
                +      }
                +    } else if (Blockly.BlockSvg.START_HAT) {
                +      // No output or previous connection.
                +      this.squareTopLeftCorner_ = true;
                +      this.startHat_ = true;
                +      this.height += Blockly.BlockSvg.START_HAT_HEIGHT;
                +      inputRows.rightEdge = Math.max(inputRows.rightEdge, 100);
                +    }
                +    var nextBlock = this.getNextBlock();
                +    if (nextBlock) {
                +      this.squareBottomLeftCorner_ = true;
                +    }
                +  }
                +
                +  // Assemble the block's path.
                +  var steps = [];
                +  var inlineSteps = [];
                +  // The highlighting applies to edges facing the upper-left corner.
                +  // Since highlighting is a two-pixel wide border, it would normally overhang
                +  // the edge of the block by a pixel. So undersize all measurements by a pixel.
                +  var highlightSteps = [];
                +  var highlightInlineSteps = [];
                +
                +  this.renderDrawTop_(steps, highlightSteps, inputRows.rightEdge);
                +  var cursorY = this.renderDrawRight_(steps, highlightSteps, inlineSteps,
                +      highlightInlineSteps, inputRows, iconWidth);
                +  this.renderDrawBottom_(steps, highlightSteps, cursorY);
                +  this.renderDrawLeft_(steps, highlightSteps);
                +
                +  var pathString = steps.join(' ') + '\n' + inlineSteps.join(' ');
                +  this.svgPath_.setAttribute('d', pathString);
                +  this.svgPathDark_.setAttribute('d', pathString);
                +  pathString = highlightSteps.join(' ') + '\n' + highlightInlineSteps.join(' ');
                +  this.svgPathLight_.setAttribute('d', pathString);
                +  if (this.RTL) {
                +    // Mirror the block's path.
                +    this.svgPath_.setAttribute('transform', 'scale(-1 1)');
                +    this.svgPathLight_.setAttribute('transform', 'scale(-1 1)');
                +    this.svgPathDark_.setAttribute('transform', 'translate(1,1) scale(-1 1)');
                +  }
                +};
                +
                +/**
                + * Update all of the connections on this block with the new locations calculated
                + * in renderCompute.  Also move all of the connected blocks based on the new
                + * connection locations.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderMoveConnections_ = function() {
                +  var blockTL = this.getRelativeToSurfaceXY();
                +  // Don't tighten previous or output connections because they are inferior
                +  // connections.
                +  if (this.previousConnection) {
                +    this.previousConnection.moveToOffset(blockTL);
                +  }
                +  if (this.outputConnection) {
                +    this.outputConnection.moveToOffset(blockTL);
                +  }
                +
                +  for (var i = 0; i < this.inputList.length; i++) {
                +    var conn = this.inputList[i].connection;
                +    if (conn) {
                +      conn.moveToOffset(blockTL);
                +      if (conn.isConnected()) {
                +        conn.tighten_();
                +      }
                +    }
                +  }
                +
                +  if (this.nextConnection) {
                +    this.nextConnection.moveToOffset(blockTL);
                +    if (this.nextConnection.isConnected()) {
                +      this.nextConnection.tighten_();
                +    }
                +  }
                +
                +};
                +
                +/**
                + * Render the top edge of the block.
                + * @param {!Array.<string>} steps Path of block outline.
                + * @param {!Array.<string>} highlightSteps Path of block highlights.
                + * @param {number} rightEdge Minimum width of block.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderDrawTop_ =
                +    function(steps, highlightSteps, rightEdge) {
                +  /* eslint-disable indent */
                +  // Position the cursor at the top-left starting point.
                +  if (this.squareTopLeftCorner_) {
                +    steps.push('m 0,0');
                +    highlightSteps.push('m 0.5,0.5');
                +    if (this.startHat_) {
                +      steps.push(Blockly.BlockSvg.START_HAT_PATH);
                +      highlightSteps.push(this.RTL ?
                +          Blockly.BlockSvg.START_HAT_HIGHLIGHT_RTL :
                +          Blockly.BlockSvg.START_HAT_HIGHLIGHT_LTR);
                +    }
                +  } else {
                +    steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER_START);
                +    highlightSteps.push(this.RTL ?
                +        Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_RTL :
                +        Blockly.BlockSvg.TOP_LEFT_CORNER_START_HIGHLIGHT_LTR);
                +    // Top-left rounded corner.
                +    steps.push(Blockly.BlockSvg.TOP_LEFT_CORNER);
                +    highlightSteps.push(Blockly.BlockSvg.TOP_LEFT_CORNER_HIGHLIGHT);
                +  }
                +
                +  // Top edge.
                +  if (this.previousConnection) {
                +    steps.push('H', Blockly.BlockSvg.NOTCH_WIDTH - 15);
                +    highlightSteps.push('H', Blockly.BlockSvg.NOTCH_WIDTH - 15);
                +    steps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT);
                +    highlightSteps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT);
                +
                +    var connectionX = (this.RTL ?
                +        -Blockly.BlockSvg.NOTCH_WIDTH : Blockly.BlockSvg.NOTCH_WIDTH);
                +    this.previousConnection.setOffsetInBlock(connectionX, 0);
                +  }
                +  steps.push('H', rightEdge);
                +  highlightSteps.push('H', rightEdge - 0.5);
                +  this.width = rightEdge;
                +};  /* eslint-enable indent */
                +
                +/**
                + * Render the right edge of the block.
                + * @param {!Array.<string>} steps Path of block outline.
                + * @param {!Array.<string>} highlightSteps Path of block highlights.
                + * @param {!Array.<string>} inlineSteps Inline block outlines.
                + * @param {!Array.<string>} highlightInlineSteps Inline block highlights.
                + * @param {!Array.<!Array.<!Object>>} inputRows 2D array of objects, each
                + *     containing position information.
                + * @param {number} iconWidth Offset of first row due to icons.
                + * @return {number} Height of block.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps,
                +    inlineSteps, highlightInlineSteps, inputRows, iconWidth) {
                +  var cursorX;
                +  var cursorY = 0;
                +  var connectionX, connectionY;
                +  for (var y = 0, row; row = inputRows[y]; y++) {
                +    cursorX = Blockly.BlockSvg.SEP_SPACE_X;
                +    if (y == 0) {
                +      cursorX += this.RTL ? -iconWidth : iconWidth;
                +    }
                +    highlightSteps.push('M', (inputRows.rightEdge - 0.5) + ',' +
                +        (cursorY + 0.5));
                +    if (this.isCollapsed()) {
                +      // Jagged right edge.
                +      var input = row[0];
                +      var fieldX = cursorX;
                +      var fieldY = cursorY;
                +      this.renderFields_(input.fieldRow, fieldX, fieldY);
                +      steps.push(Blockly.BlockSvg.JAGGED_TEETH);
                +      highlightSteps.push('h 8');
                +      var remainder = row.height - Blockly.BlockSvg.JAGGED_TEETH_HEIGHT;
                +      steps.push('v', remainder);
                +      if (this.RTL) {
                +        highlightSteps.push('v 3.9 l 7.2,3.4 m -14.5,8.9 l 7.3,3.5');
                +        highlightSteps.push('v', remainder - 0.7);
                +      }
                +      this.width += Blockly.BlockSvg.JAGGED_TEETH_WIDTH;
                +    } else if (row.type == Blockly.BlockSvg.INLINE) {
                +      // Inline inputs.
                +      for (var x = 0, input; input = row[x]; x++) {
                +        var fieldX = cursorX;
                +        var fieldY = cursorY;
                +        if (row.thicker) {
                +          // Lower the field slightly.
                +          fieldY += Blockly.BlockSvg.INLINE_PADDING_Y;
                +        }
                +        // TODO: Align inline field rows (left/right/centre).
                +        cursorX = this.renderFields_(input.fieldRow, fieldX, fieldY);
                +        if (input.type != Blockly.DUMMY_INPUT) {
                +          cursorX += input.renderWidth + Blockly.BlockSvg.SEP_SPACE_X;
                +        }
                +        if (input.type == Blockly.INPUT_VALUE) {
                +          inlineSteps.push('M', (cursorX - Blockly.BlockSvg.SEP_SPACE_X) +
                +                           ',' + (cursorY + Blockly.BlockSvg.INLINE_PADDING_Y));
                +          inlineSteps.push('h', Blockly.BlockSvg.TAB_WIDTH - 2 -
                +                           input.renderWidth);
                +          inlineSteps.push(Blockly.BlockSvg.TAB_PATH_DOWN);
                +          inlineSteps.push('v', input.renderHeight + 1 -
                +                                Blockly.BlockSvg.TAB_HEIGHT);
                +          inlineSteps.push('h', input.renderWidth + 2 -
                +                           Blockly.BlockSvg.TAB_WIDTH);
                +          inlineSteps.push('z');
                +          if (this.RTL) {
                +            // Highlight right edge, around back of tab, and bottom.
                +            highlightInlineSteps.push('M',
                +                (cursorX - Blockly.BlockSvg.SEP_SPACE_X - 2.5 +
                +                 Blockly.BlockSvg.TAB_WIDTH - input.renderWidth) + ',' +
                +                (cursorY + Blockly.BlockSvg.INLINE_PADDING_Y + 0.5));
                +            highlightInlineSteps.push(
                +                Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL);
                +            highlightInlineSteps.push('v',
                +                input.renderHeight - Blockly.BlockSvg.TAB_HEIGHT + 2.5);
                +            highlightInlineSteps.push('h',
                +                input.renderWidth - Blockly.BlockSvg.TAB_WIDTH + 2);
                +          } else {
                +            // Highlight right edge, bottom.
                +            highlightInlineSteps.push('M',
                +                (cursorX - Blockly.BlockSvg.SEP_SPACE_X + 0.5) + ',' +
                +                (cursorY + Blockly.BlockSvg.INLINE_PADDING_Y + 0.5));
                +            highlightInlineSteps.push('v', input.renderHeight + 1);
                +            highlightInlineSteps.push('h', Blockly.BlockSvg.TAB_WIDTH - 2 -
                +                                           input.renderWidth);
                +            // Short highlight glint at bottom of tab.
                +            highlightInlineSteps.push('M',
                +                (cursorX - input.renderWidth - Blockly.BlockSvg.SEP_SPACE_X +
                +                 0.9) + ',' + (cursorY + Blockly.BlockSvg.INLINE_PADDING_Y +
                +                 Blockly.BlockSvg.TAB_HEIGHT - 0.7));
                +            highlightInlineSteps.push('l',
                +                (Blockly.BlockSvg.TAB_WIDTH * 0.46) + ',-2.1');
                +          }
                +          // Create inline input connection.
                +          if (this.RTL) {
                +            connectionX = -cursorX -
                +                Blockly.BlockSvg.TAB_WIDTH + Blockly.BlockSvg.SEP_SPACE_X +
                +                input.renderWidth + 1;
                +          } else {
                +            connectionX = cursorX +
                +                Blockly.BlockSvg.TAB_WIDTH - Blockly.BlockSvg.SEP_SPACE_X -
                +                input.renderWidth - 1;
                +          }
                +          connectionY = cursorY + Blockly.BlockSvg.INLINE_PADDING_Y + 1;
                +          input.connection.setOffsetInBlock(connectionX, connectionY);
                +        }
                +      }
                +
                +      cursorX = Math.max(cursorX, inputRows.rightEdge);
                +      this.width = Math.max(this.width, cursorX);
                +      steps.push('H', cursorX);
                +      highlightSteps.push('H', cursorX - 0.5);
                +      steps.push('v', row.height);
                +      if (this.RTL) {
                +        highlightSteps.push('v', row.height - 1);
                +      }
                +    } else if (row.type == Blockly.INPUT_VALUE) {
                +      // External input.
                +      var input = row[0];
                +      var fieldX = cursorX;
                +      var fieldY = cursorY;
                +      if (input.align != Blockly.ALIGN_LEFT) {
                +        var fieldRightX = inputRows.rightEdge - input.fieldWidth -
                +            Blockly.BlockSvg.TAB_WIDTH - 2 * Blockly.BlockSvg.SEP_SPACE_X;
                +        if (input.align == Blockly.ALIGN_RIGHT) {
                +          fieldX += fieldRightX;
                +        } else if (input.align == Blockly.ALIGN_CENTRE) {
                +          fieldX += fieldRightX / 2;
                +        }
                +      }
                +      this.renderFields_(input.fieldRow, fieldX, fieldY);
                +      steps.push(Blockly.BlockSvg.TAB_PATH_DOWN);
                +      var v = row.height - Blockly.BlockSvg.TAB_HEIGHT;
                +      steps.push('v', v);
                +      if (this.RTL) {
                +        // Highlight around back of tab.
                +        highlightSteps.push(Blockly.BlockSvg.TAB_PATH_DOWN_HIGHLIGHT_RTL);
                +        highlightSteps.push('v', v + 0.5);
                +      } else {
                +        // Short highlight glint at bottom of tab.
                +        highlightSteps.push('M', (inputRows.rightEdge - 5) + ',' +
                +            (cursorY + Blockly.BlockSvg.TAB_HEIGHT - 0.7));
                +        highlightSteps.push('l', (Blockly.BlockSvg.TAB_WIDTH * 0.46) +
                +            ',-2.1');
                +      }
                +      // Create external input connection.
                +      connectionX = this.RTL ? -inputRows.rightEdge - 1 :
                +          inputRows.rightEdge + 1;
                +      input.connection.setOffsetInBlock(connectionX, cursorY);
                +      if (input.connection.isConnected()) {
                +        this.width = Math.max(this.width, inputRows.rightEdge +
                +            input.connection.targetBlock().getHeightWidth().width -
                +            Blockly.BlockSvg.TAB_WIDTH + 1);
                +      }
                +    } else if (row.type == Blockly.DUMMY_INPUT) {
                +      // External naked field.
                +      var input = row[0];
                +      var fieldX = cursorX;
                +      var fieldY = cursorY;
                +      if (input.align != Blockly.ALIGN_LEFT) {
                +        var fieldRightX = inputRows.rightEdge - input.fieldWidth -
                +            2 * Blockly.BlockSvg.SEP_SPACE_X;
                +        if (inputRows.hasValue) {
                +          fieldRightX -= Blockly.BlockSvg.TAB_WIDTH;
                +        }
                +        if (input.align == Blockly.ALIGN_RIGHT) {
                +          fieldX += fieldRightX;
                +        } else if (input.align == Blockly.ALIGN_CENTRE) {
                +          fieldX += fieldRightX / 2;
                +        }
                +      }
                +      this.renderFields_(input.fieldRow, fieldX, fieldY);
                +      steps.push('v', row.height);
                +      if (this.RTL) {
                +        highlightSteps.push('v', row.height - 1);
                +      }
                +    } else if (row.type == Blockly.NEXT_STATEMENT) {
                +      // Nested statement.
                +      var input = row[0];
                +      if (y == 0) {
                +        // If the first input is a statement stack, add a small row on top.
                +        steps.push('v', Blockly.BlockSvg.SEP_SPACE_Y);
                +        if (this.RTL) {
                +          highlightSteps.push('v', Blockly.BlockSvg.SEP_SPACE_Y - 1);
                +        }
                +        cursorY += Blockly.BlockSvg.SEP_SPACE_Y;
                +      }
                +      var fieldX = cursorX;
                +      var fieldY = cursorY;
                +      if (input.align != Blockly.ALIGN_LEFT) {
                +        var fieldRightX = inputRows.statementEdge - input.fieldWidth -
                +            2 * Blockly.BlockSvg.SEP_SPACE_X;
                +        if (input.align == Blockly.ALIGN_RIGHT) {
                +          fieldX += fieldRightX;
                +        } else if (input.align == Blockly.ALIGN_CENTRE) {
                +          fieldX += fieldRightX / 2;
                +        }
                +      }
                +      this.renderFields_(input.fieldRow, fieldX, fieldY);
                +      cursorX = inputRows.statementEdge + Blockly.BlockSvg.NOTCH_WIDTH;
                +      steps.push('H', cursorX);
                +      steps.push(Blockly.BlockSvg.INNER_TOP_LEFT_CORNER);
                +      steps.push('v', row.height - 2 * Blockly.BlockSvg.CORNER_RADIUS);
                +      steps.push(Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER);
                +      steps.push('H', inputRows.rightEdge);
                +      if (this.RTL) {
                +        highlightSteps.push('M',
                +            (cursorX - Blockly.BlockSvg.NOTCH_WIDTH +
                +             Blockly.BlockSvg.DISTANCE_45_OUTSIDE) +
                +            ',' + (cursorY + Blockly.BlockSvg.DISTANCE_45_OUTSIDE));
                +        highlightSteps.push(
                +            Blockly.BlockSvg.INNER_TOP_LEFT_CORNER_HIGHLIGHT_RTL);
                +        highlightSteps.push('v',
                +            row.height - 2 * Blockly.BlockSvg.CORNER_RADIUS);
                +        highlightSteps.push(
                +            Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_RTL);
                +        highlightSteps.push('H', inputRows.rightEdge - 0.5);
                +      } else {
                +        highlightSteps.push('M',
                +            (cursorX - Blockly.BlockSvg.NOTCH_WIDTH +
                +             Blockly.BlockSvg.DISTANCE_45_OUTSIDE) + ',' +
                +            (cursorY + row.height - Blockly.BlockSvg.DISTANCE_45_OUTSIDE));
                +        highlightSteps.push(
                +            Blockly.BlockSvg.INNER_BOTTOM_LEFT_CORNER_HIGHLIGHT_LTR);
                +        highlightSteps.push('H', inputRows.rightEdge - 0.5);
                +      }
                +      // Create statement connection.
                +      connectionX = this.RTL ? -cursorX : cursorX + 1;
                +      input.connection.setOffsetInBlock(connectionX, cursorY + 1);
                +
                +      if (input.connection.isConnected()) {
                +        this.width = Math.max(this.width, inputRows.statementEdge +
                +            input.connection.targetBlock().getHeightWidth().width);
                +      }
                +      if (y == inputRows.length - 1 ||
                +          inputRows[y + 1].type == Blockly.NEXT_STATEMENT) {
                +        // If the final input is a statement stack, add a small row underneath.
                +        // Consecutive statement stacks are also separated by a small divider.
                +        steps.push('v', Blockly.BlockSvg.SEP_SPACE_Y);
                +        if (this.RTL) {
                +          highlightSteps.push('v', Blockly.BlockSvg.SEP_SPACE_Y - 1);
                +        }
                +        cursorY += Blockly.BlockSvg.SEP_SPACE_Y;
                +      }
                +    }
                +    cursorY += row.height;
                +  }
                +  if (!inputRows.length) {
                +    cursorY = Blockly.BlockSvg.MIN_BLOCK_Y;
                +    steps.push('V', cursorY);
                +    if (this.RTL) {
                +      highlightSteps.push('V', cursorY - 1);
                +    }
                +  }
                +  return cursorY;
                +};
                +
                +/**
                + * Render the bottom edge of the block.
                + * @param {!Array.<string>} steps Path of block outline.
                + * @param {!Array.<string>} highlightSteps Path of block highlights.
                + * @param {number} cursorY Height of block.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderDrawBottom_ =
                +    function(steps, highlightSteps, cursorY) {
                +  /* eslint-disable indent */
                +  this.height += cursorY + 1;  // Add one for the shadow.
                +  if (this.nextConnection) {
                +    steps.push('H', (Blockly.BlockSvg.NOTCH_WIDTH + (this.RTL ? 0.5 : - 0.5)) +
                +        ' ' + Blockly.BlockSvg.NOTCH_PATH_RIGHT);
                +    // Create next block connection.
                +    var connectionX;
                +    if (this.RTL) {
                +      connectionX = -Blockly.BlockSvg.NOTCH_WIDTH;
                +    } else {
                +      connectionX = Blockly.BlockSvg.NOTCH_WIDTH;
                +    }
                +    this.nextConnection.setOffsetInBlock(connectionX, cursorY + 1);
                +    this.height += 4;  // Height of tab.
                +  }
                +
                +  // Should the bottom-left corner be rounded or square?
                +  if (this.squareBottomLeftCorner_) {
                +    steps.push('H 0');
                +    if (!this.RTL) {
                +      highlightSteps.push('M', '0.5,' + (cursorY - 0.5));
                +    }
                +  } else {
                +    steps.push('H', Blockly.BlockSvg.CORNER_RADIUS);
                +    steps.push('a', Blockly.BlockSvg.CORNER_RADIUS + ',' +
                +               Blockly.BlockSvg.CORNER_RADIUS + ' 0 0,1 -' +
                +               Blockly.BlockSvg.CORNER_RADIUS + ',-' +
                +               Blockly.BlockSvg.CORNER_RADIUS);
                +    if (!this.RTL) {
                +      highlightSteps.push('M', Blockly.BlockSvg.DISTANCE_45_INSIDE + ',' +
                +          (cursorY - Blockly.BlockSvg.DISTANCE_45_INSIDE));
                +      highlightSteps.push('A', (Blockly.BlockSvg.CORNER_RADIUS - 0.5) + ',' +
                +          (Blockly.BlockSvg.CORNER_RADIUS - 0.5) + ' 0 0,1 ' +
                +          '0.5,' + (cursorY - Blockly.BlockSvg.CORNER_RADIUS));
                +    }
                +  }
                +};  /* eslint-enable indent */
                +
                +/**
                + * Render the left edge of the block.
                + * @param {!Array.<string>} steps Path of block outline.
                + * @param {!Array.<string>} highlightSteps Path of block highlights.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.renderDrawLeft_ = function(steps, highlightSteps) {
                +  if (this.outputConnection) {
                +    // Create output connection.
                +    this.outputConnection.setOffsetInBlock(0, 0);
                +    steps.push('V', Blockly.BlockSvg.TAB_HEIGHT);
                +    steps.push('c 0,-10 -' + Blockly.BlockSvg.TAB_WIDTH + ',8 -' +
                +        Blockly.BlockSvg.TAB_WIDTH + ',-7.5 s ' + Blockly.BlockSvg.TAB_WIDTH +
                +        ',2.5 ' + Blockly.BlockSvg.TAB_WIDTH + ',-7.5');
                +    if (this.RTL) {
                +      highlightSteps.push('M', (Blockly.BlockSvg.TAB_WIDTH * -0.25) + ',8.4');
                +      highlightSteps.push('l', (Blockly.BlockSvg.TAB_WIDTH * -0.45) + ',-2.1');
                +    } else {
                +      highlightSteps.push('V', Blockly.BlockSvg.TAB_HEIGHT - 1.5);
                +      highlightSteps.push('m', (Blockly.BlockSvg.TAB_WIDTH * -0.92) +
                +                          ',-0.5 q ' + (Blockly.BlockSvg.TAB_WIDTH * -0.19) +
                +                          ',-5.5 0,-11');
                +      highlightSteps.push('m', (Blockly.BlockSvg.TAB_WIDTH * 0.92) +
                +                          ',1 V 0.5 H 1');
                +    }
                +    this.width += Blockly.BlockSvg.TAB_WIDTH;
                +  } else if (!this.RTL) {
                +    if (this.squareTopLeftCorner_) {
                +      // Statement block in a stack.
                +      highlightSteps.push('V', 0.5);
                +    } else {
                +      highlightSteps.push('V', Blockly.BlockSvg.CORNER_RADIUS);
                +    }
                +  }
                +  steps.push('z');
                +};
                diff --git a/blockly/webif/static/blockly/core/block_svg.js b/blockly/webif/static/blockly/core/block_svg.js
                new file mode 100644
                index 000000000..79bfb942a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/block_svg.js
                @@ -0,0 +1,1543 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Methods for graphically rendering a block as SVG.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.BlockSvg');
                +
                +goog.require('Blockly.Block');
                +goog.require('Blockly.ContextMenu');
                +goog.require('Blockly.Grid');
                +goog.require('Blockly.RenderedConnection');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.utils');
                +goog.require('goog.Timer');
                +goog.require('goog.asserts');
                +goog.require('goog.dom');
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a block's SVG representation.
                + * Not normally called directly, workspace.newBlock() is preferred.
                + * @param {!Blockly.Workspace} workspace The block's workspace.
                + * @param {?string} prototypeName Name of the language object containing
                + *     type-specific functions for this block.
                + * @param {string=} opt_id Optional ID.  Use this ID if provided, otherwise
                + *     create a new id.
                + * @extends {Blockly.Block}
                + * @constructor
                + */
                +Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
                +  // Create core elements for the block.
                +  /**
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, null);
                +  this.svgGroup_.translate_ = '';
                +
                +  /**
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.svgPathDark_ = Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyPathDark', 'transform': 'translate(1,1)'},
                +      this.svgGroup_);
                +
                +  /**
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.svgPath_ = Blockly.utils.createSvgElement('path', {'class': 'blocklyPath'},
                +      this.svgGroup_);
                +
                +  /**
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.svgPathLight_ = Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyPathLight'}, this.svgGroup_);
                +  this.svgPath_.tooltip = this;
                +
                +  /** @type {boolean} */
                +  this.rendered = false;
                +
                +  /**
                +   * Whether to move the block to the drag surface when it is dragged.
                +   * True if it should move, false if it should be translated directly.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.useDragSurface_ = Blockly.utils.is3dSupported() && !!workspace.blockDragSurface_;
                +
                +  Blockly.Tooltip.bindMouseEvents(this.svgPath_);
                +  Blockly.BlockSvg.superClass_.constructor.call(this,
                +      workspace, prototypeName, opt_id);
                +};
                +goog.inherits(Blockly.BlockSvg, Blockly.Block);
                +
                +/**
                + * Height of this block, not including any statement blocks above or below.
                + * Height is in workspace units.
                + */
                +Blockly.BlockSvg.prototype.height = 0;
                +/**
                + * Width of this block, including any connected value blocks.
                + * Width is in workspace units.
                + */
                +Blockly.BlockSvg.prototype.width = 0;
                +
                +/**
                + * Original location of block being dragged.
                + * @type {goog.math.Coordinate}
                + * @private
                + */
                +Blockly.BlockSvg.prototype.dragStartXY_ = null;
                +
                +/**
                + * Constant for identifying rows that are to be rendered inline.
                + * Don't collide with Blockly.INPUT_VALUE and friends.
                + * @const
                + */
                +Blockly.BlockSvg.INLINE = -1;
                +
                +/**
                + * Create and initialize the SVG representation of the block.
                + * May be called more than once.
                + */
                +Blockly.BlockSvg.prototype.initSvg = function() {
                +  goog.asserts.assert(this.workspace.rendered, 'Workspace is headless.');
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    input.init();
                +  }
                +  var icons = this.getIcons();
                +  for (var i = 0; i < icons.length; i++) {
                +    icons[i].createIcon();
                +  }
                +  this.updateColour();
                +  this.updateMovable();
                +  if (!this.workspace.options.readOnly && !this.eventsInit_) {
                +    Blockly.bindEventWithChecks_(this.getSvgRoot(), 'mousedown', this,
                +                       this.onMouseDown_);
                +  }
                +  this.eventsInit_ = true;
                +
                +  if (!this.getSvgRoot().parentNode) {
                +    this.workspace.getCanvas().appendChild(this.getSvgRoot());
                +  }
                +};
                +
                +/**
                + * Select this block.  Highlight it visually.
                + */
                +Blockly.BlockSvg.prototype.select = function() {
                +  if (this.isShadow() && this.getParent()) {
                +    // Shadow blocks should not be selected.
                +    this.getParent().select();
                +    return;
                +  }
                +  if (Blockly.selected == this) {
                +    return;
                +  }
                +  var oldId = null;
                +  if (Blockly.selected) {
                +    oldId = Blockly.selected.id;
                +    // Unselect any previously selected block.
                +    Blockly.Events.disable();
                +    try {
                +      Blockly.selected.unselect();
                +    } finally {
                +      Blockly.Events.enable();
                +    }
                +  }
                +  var event = new Blockly.Events.Ui(null, 'selected', oldId, this.id);
                +  event.workspaceId = this.workspace.id;
                +  Blockly.Events.fire(event);
                +  Blockly.selected = this;
                +  this.addSelect();
                +};
                +
                +/**
                + * Unselect this block.  Remove its highlighting.
                + */
                +Blockly.BlockSvg.prototype.unselect = function() {
                +  if (Blockly.selected != this) {
                +    return;
                +  }
                +  var event = new Blockly.Events.Ui(null, 'selected', this.id, null);
                +  event.workspaceId = this.workspace.id;
                +  Blockly.Events.fire(event);
                +  Blockly.selected = null;
                +  this.removeSelect();
                +};
                +
                +/**
                + * Block's mutator icon (if any).
                + * @type {Blockly.Mutator}
                + */
                +Blockly.BlockSvg.prototype.mutator = null;
                +
                +/**
                + * Block's comment icon (if any).
                + * @type {Blockly.Comment}
                + */
                +Blockly.BlockSvg.prototype.comment = null;
                +
                +/**
                + * Block's warning icon (if any).
                + * @type {Blockly.Warning}
                + */
                +Blockly.BlockSvg.prototype.warning = null;
                +
                +/**
                + * Returns a list of mutator, comment, and warning icons.
                + * @return {!Array} List of icons.
                + */
                +Blockly.BlockSvg.prototype.getIcons = function() {
                +  var icons = [];
                +  if (this.mutator) {
                +    icons.push(this.mutator);
                +  }
                +  if (this.comment) {
                +    icons.push(this.comment);
                +  }
                +  if (this.warning) {
                +    icons.push(this.warning);
                +  }
                +  return icons;
                +};
                +
                +/**
                + * Set parent of this block to be a new block or null.
                + * @param {Blockly.BlockSvg} newParent New parent block.
                + */
                +Blockly.BlockSvg.prototype.setParent = function(newParent) {
                +  if (newParent == this.parentBlock_) {
                +    return;
                +  }
                +  var svgRoot = this.getSvgRoot();
                +  if (this.parentBlock_ && svgRoot) {
                +    // Move this block up the DOM.  Keep track of x/y translations.
                +    var xy = this.getRelativeToSurfaceXY();
                +    this.workspace.getCanvas().appendChild(svgRoot);
                +    svgRoot.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')');
                +  }
                +
                +  Blockly.Field.startCache();
                +  Blockly.BlockSvg.superClass_.setParent.call(this, newParent);
                +  Blockly.Field.stopCache();
                +
                +  if (newParent) {
                +    var oldXY = this.getRelativeToSurfaceXY();
                +    newParent.getSvgRoot().appendChild(svgRoot);
                +    var newXY = this.getRelativeToSurfaceXY();
                +    // Move the connections to match the child's new position.
                +    this.moveConnections_(newXY.x - oldXY.x, newXY.y - oldXY.y);
                +  }
                +};
                +
                +/**
                + * Return the coordinates of the top-left corner of this block relative to the
                + * drawing surface's origin (0,0), in workspace units.
                + * If the block is on the workspace, (0, 0) is the origin of the workspace
                + * coordinate system.
                + * This does not change with workspace scale.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties in
                + *     workspace coordinates.
                + */
                +Blockly.BlockSvg.prototype.getRelativeToSurfaceXY = function() {
                +  var x = 0;
                +  var y = 0;
                +
                +  var dragSurfaceGroup = this.useDragSurface_ ?
                +      this.workspace.blockDragSurface_.getGroup() : null;
                +
                +  var element = this.getSvgRoot();
                +  if (element) {
                +    do {
                +      // Loop through this block and every parent.
                +      var xy = Blockly.utils.getRelativeXY(element);
                +      x += xy.x;
                +      y += xy.y;
                +      // If this element is the current element on the drag surface, include
                +      // the translation of the drag surface itself.
                +      if (this.useDragSurface_ &&
                +          this.workspace.blockDragSurface_.getCurrentBlock() == element) {
                +        var surfaceTranslation = this.workspace.blockDragSurface_.getSurfaceTranslation();
                +        x += surfaceTranslation.x;
                +        y += surfaceTranslation.y;
                +      }
                +      element = element.parentNode;
                +    } while (element && element != this.workspace.getCanvas() &&
                +        element != dragSurfaceGroup);
                +  }
                +  return new goog.math.Coordinate(x, y);
                +};
                +
                +/**
                + * Move a block by a relative offset.
                + * @param {number} dx Horizontal offset in workspace units.
                + * @param {number} dy Vertical offset in workspace units.
                + */
                +Blockly.BlockSvg.prototype.moveBy = function(dx, dy) {
                +  goog.asserts.assert(!this.parentBlock_, 'Block has parent.');
                +  var event = new Blockly.Events.BlockMove(this);
                +  var xy = this.getRelativeToSurfaceXY();
                +  this.translate(xy.x + dx, xy.y + dy);
                +  this.moveConnections_(dx, dy);
                +  event.recordNew();
                +  this.workspace.resizeContents();
                +  Blockly.Events.fire(event);
                +};
                +
                +/**
                + * Transforms a block by setting the translation on the transform attribute
                + * of the block's SVG.
                + * @param {number} x The x coordinate of the translation in workspace units.
                + * @param {number} y The y coordinate of the translation in workspace units.
                + */
                +Blockly.BlockSvg.prototype.translate = function(x, y) {
                +  this.getSvgRoot().setAttribute('transform',
                +      'translate(' + x + ',' + y + ')');
                +};
                +
                +/**
                + * Move this block to its workspace's drag surface, accounting for positioning.
                + * Generally should be called at the same time as setDragging_(true).
                + * Does nothing if useDragSurface_ is false.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.moveToDragSurface_ = function() {
                +  if (!this.useDragSurface_) {
                +    return;
                +  }
                +  // The translation for drag surface blocks,
                +  // is equal to the current relative-to-surface position,
                +  // to keep the position in sync as it move on/off the surface.
                +  // This is in workspace coordinates.
                +  var xy = this.getRelativeToSurfaceXY();
                +  this.clearTransformAttributes_();
                +  this.workspace.blockDragSurface_.translateSurface(xy.x, xy.y);
                +  // Execute the move on the top-level SVG component
                +  this.workspace.blockDragSurface_.setBlocksAndShow(this.getSvgRoot());
                +};
                +
                +/**
                + * Move this block back to the workspace block canvas.
                + * Generally should be called at the same time as setDragging_(false).
                + * Does nothing if useDragSurface_ is false.
                + * @param {!goog.math.Coordinate} newXY The position the block should take on
                + *     on the workspace canvas, in workspace coordinates.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.moveOffDragSurface_ = function(newXY) {
                +  if (!this.useDragSurface_) {
                +    return;
                +  }
                +  // Translate to current position, turning off 3d.
                +  this.translate(newXY.x, newXY.y);
                +  this.workspace.blockDragSurface_.clearAndHide(this.workspace.getCanvas());
                +};
                +
                +/**
                + * Move this block during a drag, taking into account whether we are using a
                + * drag surface to translate blocks.
                + * This block must be a top-level block.
                + * @param {!goog.math.Coordinate} newLoc The location to translate to, in
                + *     workspace coordinates.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.moveDuringDrag = function(newLoc) {
                +  if (this.useDragSurface_) {
                +    this.workspace.blockDragSurface_.translateSurface(newLoc.x, newLoc.y);
                +  } else {
                +    this.svgGroup_.translate_ = 'translate(' + newLoc.x + ',' + newLoc.y + ')';
                +    this.svgGroup_.setAttribute('transform',
                +        this.svgGroup_.translate_ + this.svgGroup_.skew_);
                +  }
                +};
                +
                +/**
                + * Clear the block of transform="..." attributes.
                + * Used when the block is switching from 3d to 2d transform or vice versa.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.clearTransformAttributes_ = function() {
                +  Blockly.utils.removeAttribute(this.getSvgRoot(), 'transform');
                +};
                +
                +/**
                + * Snap this block to the nearest grid point.
                + */
                +Blockly.BlockSvg.prototype.snapToGrid = function() {
                +  if (!this.workspace) {
                +    return;  // Deleted block.
                +  }
                +  if (this.workspace.isDragging()) {
                +    return;  // Don't bump blocks during a drag.
                +  }
                +  if (this.getParent()) {
                +    return;  // Only snap top-level blocks.
                +  }
                +  if (this.isInFlyout) {
                +    return;  // Don't move blocks around in a flyout.
                +  }
                +  var grid = this.workspace.getGrid();
                +  if (!grid || !grid.shouldSnap()) {
                +    return;  // Config says no snapping.
                +  }
                +  var spacing = grid.getSpacing();
                +  var half = spacing / 2;
                +  var xy = this.getRelativeToSurfaceXY();
                +  var dx = Math.round((xy.x - half) / spacing) * spacing + half - xy.x;
                +  var dy = Math.round((xy.y - half) / spacing) * spacing + half - xy.y;
                +  dx = Math.round(dx);
                +  dy = Math.round(dy);
                +  if (dx != 0 || dy != 0) {
                +    this.moveBy(dx, dy);
                +  }
                +};
                +
                +/**
                + * Returns the coordinates of a bounding box describing the dimensions of this
                + * block and any blocks stacked below it.
                + * Coordinate system: workspace coordinates.
                + * @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}}
                + *    Object with top left and bottom right coordinates of the bounding box.
                + */
                +Blockly.BlockSvg.prototype.getBoundingRectangle = function() {
                +  var blockXY = this.getRelativeToSurfaceXY(this);
                +  var tab = this.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
                +  var blockBounds = this.getHeightWidth();
                +  var topLeft;
                +  var bottomRight;
                +  if (this.RTL) {
                +    // Width has the tab built into it already so subtract it here.
                +    topLeft = new goog.math.Coordinate(blockXY.x - (blockBounds.width - tab),
                +        blockXY.y);
                +    // Add the width of the tab/puzzle piece knob to the x coordinate
                +    // since X is the corner of the rectangle, not the whole puzzle piece.
                +    bottomRight = new goog.math.Coordinate(blockXY.x + tab,
                +        blockXY.y + blockBounds.height);
                +  } else {
                +    // Subtract the width of the tab/puzzle piece knob to the x coordinate
                +    // since X is the corner of the rectangle, not the whole puzzle piece.
                +    topLeft = new goog.math.Coordinate(blockXY.x - tab, blockXY.y);
                +    // Width has the tab built into it already so subtract it here.
                +    bottomRight = new goog.math.Coordinate(blockXY.x + blockBounds.width - tab,
                +        blockXY.y + blockBounds.height);
                +  }
                +  return {topLeft: topLeft, bottomRight: bottomRight};
                +};
                +
                +/**
                + * Set whether the block is collapsed or not.
                + * @param {boolean} collapsed True if collapsed.
                + */
                +Blockly.BlockSvg.prototype.setCollapsed = function(collapsed) {
                +  if (this.collapsed_ == collapsed) {
                +    return;
                +  }
                +  var renderList = [];
                +  // Show/hide the inputs.
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    renderList.push.apply(renderList, input.setVisible(!collapsed));
                +  }
                +
                +  var COLLAPSED_INPUT_NAME = '_TEMP_COLLAPSED_INPUT';
                +  if (collapsed) {
                +    var icons = this.getIcons();
                +    for (var i = 0; i < icons.length; i++) {
                +      icons[i].setVisible(false);
                +    }
                +    var text = this.toString(Blockly.COLLAPSE_CHARS);
                +    this.appendDummyInput(COLLAPSED_INPUT_NAME).appendField(text).init();
                +  } else {
                +    this.removeInput(COLLAPSED_INPUT_NAME);
                +    // Clear any warnings inherited from enclosed blocks.
                +    this.setWarningText(null);
                +  }
                +  Blockly.BlockSvg.superClass_.setCollapsed.call(this, collapsed);
                +
                +  if (!renderList.length) {
                +    // No child blocks, just render this block.
                +    renderList[0] = this;
                +  }
                +  if (this.rendered) {
                +    for (var i = 0, block; block = renderList[i]; i++) {
                +      block.render();
                +    }
                +    // Don't bump neighbours.
                +    // Although bumping neighbours would make sense, users often collapse
                +    // all their functions and store them next to each other.  Expanding and
                +    // bumping causes all their definitions to go out of alignment.
                +  }
                +};
                +
                +/**
                + * Open the next (or previous) FieldTextInput.
                + * @param {Blockly.Field|Blockly.Block} start Current location.
                + * @param {boolean} forward If true go forward, otherwise backward.
                + */
                +Blockly.BlockSvg.prototype.tab = function(start, forward) {
                +  // This function need not be efficient since it runs once on a keypress.
                +  // Create an ordered list of all text fields and connected inputs.
                +  var list = [];
                +  for (var i = 0, input; input = this.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      if (field instanceof Blockly.FieldTextInput) {
                +        // TODO: Also support dropdown fields.
                +        list.push(field);
                +      }
                +    }
                +    if (input.connection) {
                +      var block = input.connection.targetBlock();
                +      if (block) {
                +        list.push(block);
                +      }
                +    }
                +  }
                +  var i = list.indexOf(start);
                +  if (i == -1) {
                +    // No start location, start at the beginning or end.
                +    i = forward ? -1 : list.length;
                +  }
                +  var target = list[forward ? i + 1 : i - 1];
                +  if (!target) {
                +    // Ran off of list.
                +    var parent = this.getParent();
                +    if (parent) {
                +      parent.tab(this, forward);
                +    }
                +  } else if (target instanceof Blockly.Field) {
                +    target.showEditor_();
                +  } else {
                +    target.tab(null, forward);
                +  }
                +};
                +
                +/**
                + * Handle a mouse-down on an SVG block.
                + * @param {!Event} e Mouse down event or touch start event.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.onMouseDown_ = function(e) {
                +  var gesture = this.workspace.getGesture(e);
                +  if (gesture) {
                +    gesture.handleBlockStart(e, this);
                +  }
                +};
                +
                +/**
                + * Load the block's help page in a new window.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.showHelp_ = function() {
                +  var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl;
                +  if (url) {
                +    window.open(url);
                +  }
                +};
                +
                +/**
                + * Show the context menu for this block.
                + * @param {!Event} e Mouse event.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
                +  if (this.workspace.options.readOnly || !this.contextMenu) {
                +    return;
                +  }
                +  // Save the current block in a variable for use in closures.
                +  var block = this;
                +  var menuOptions = [];
                +
                +  if (this.isDeletable() && this.isMovable() && !block.isInFlyout) {
                +    // Option to duplicate this block.
                +    var duplicateOption = {
                +      text: Blockly.Msg.DUPLICATE_BLOCK,
                +      enabled: true,
                +      callback: function() {
                +        Blockly.duplicate_(block);
                +      }
                +    };
                +    if (this.getDescendants().length > this.workspace.remainingCapacity()) {
                +      duplicateOption.enabled = false;
                +    }
                +    menuOptions.push(duplicateOption);
                +
                +    if (this.isEditable() && !this.collapsed_ &&
                +        this.workspace.options.comments) {
                +      // Option to add/remove a comment.
                +      var commentOption = {enabled: !goog.userAgent.IE};
                +      if (this.comment) {
                +        commentOption.text = Blockly.Msg.REMOVE_COMMENT;
                +        commentOption.callback = function() {
                +          block.setCommentText(null);
                +        };
                +      } else {
                +        commentOption.text = Blockly.Msg.ADD_COMMENT;
                +        commentOption.callback = function() {
                +          block.setCommentText('');
                +        };
                +      }
                +      menuOptions.push(commentOption);
                +    }
                +
                +    // Option to make block inline.
                +    if (!this.collapsed_) {
                +      for (var i = 1; i < this.inputList.length; i++) {
                +        if (this.inputList[i - 1].type != Blockly.NEXT_STATEMENT &&
                +            this.inputList[i].type != Blockly.NEXT_STATEMENT) {
                +          // Only display this option if there are two value or dummy inputs
                +          // next to each other.
                +          var inlineOption = {enabled: true};
                +          var isInline = this.getInputsInline();
                +          inlineOption.text = isInline ?
                +              Blockly.Msg.EXTERNAL_INPUTS : Blockly.Msg.INLINE_INPUTS;
                +          inlineOption.callback = function() {
                +            block.setInputsInline(!isInline);
                +          };
                +          menuOptions.push(inlineOption);
                +          break;
                +        }
                +      }
                +    }
                +
                +    if (this.workspace.options.collapse) {
                +      // Option to collapse/expand block.
                +      if (this.collapsed_) {
                +        var expandOption = {enabled: true};
                +        expandOption.text = Blockly.Msg.EXPAND_BLOCK;
                +        expandOption.callback = function() {
                +          block.setCollapsed(false);
                +        };
                +        menuOptions.push(expandOption);
                +      } else {
                +        var collapseOption = {enabled: true};
                +        collapseOption.text = Blockly.Msg.COLLAPSE_BLOCK;
                +        collapseOption.callback = function() {
                +          block.setCollapsed(true);
                +        };
                +        menuOptions.push(collapseOption);
                +      }
                +    }
                +
                +    if (this.workspace.options.disable) {
                +      // Option to disable/enable block.
                +      var disableOption = {
                +        text: this.disabled ?
                +            Blockly.Msg.ENABLE_BLOCK : Blockly.Msg.DISABLE_BLOCK,
                +        enabled: !this.getInheritedDisabled(),
                +        callback: function() {
                +          block.setDisabled(!block.disabled);
                +        }
                +      };
                +      menuOptions.push(disableOption);
                +    }
                +
                +    // Option to delete this block.
                +    // Count the number of blocks that are nested in this block.
                +    var descendantCount = this.getDescendants().length;
                +    var nextBlock = this.getNextBlock();
                +    if (nextBlock) {
                +      // Blocks in the current stack would survive this block's deletion.
                +      descendantCount -= nextBlock.getDescendants().length;
                +    }
                +    var deleteOption = {
                +      text: descendantCount == 1 ? Blockly.Msg.DELETE_BLOCK :
                +          Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(descendantCount)),
                +      enabled: true,
                +      callback: function() {
                +        Blockly.Events.setGroup(true);
                +        block.dispose(true, true);
                +        Blockly.Events.setGroup(false);
                +      }
                +    };
                +    menuOptions.push(deleteOption);
                +  }
                +
                +  // Option to get help.
                +  var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl;
                +  var helpOption = {enabled: !!url};
                +  helpOption.text = Blockly.Msg.HELP;
                +  helpOption.callback = function() {
                +    block.showHelp_();
                +  };
                +  menuOptions.push(helpOption);
                +
                +  // Allow the block to add or modify menuOptions.
                +  if (this.customContextMenu) {
                +    this.customContextMenu(menuOptions);
                +  }
                +
                +  Blockly.ContextMenu.show(e, menuOptions, this.RTL);
                +  Blockly.ContextMenu.currentBlock = this;
                +};
                +
                +/**
                + * Move the connections for this block and all blocks attached under it.
                + * Also update any attached bubbles.
                + * @param {number} dx Horizontal offset from current location, in workspace
                + *     units.
                + * @param {number} dy Vertical offset from current location, in workspace
                + *     units.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.moveConnections_ = function(dx, dy) {
                +  if (!this.rendered) {
                +    // Rendering is required to lay out the blocks.
                +    // This is probably an invisible block attached to a collapsed block.
                +    return;
                +  }
                +  var myConnections = this.getConnections_(false);
                +  for (var i = 0; i < myConnections.length; i++) {
                +    myConnections[i].moveBy(dx, dy);
                +  }
                +  var icons = this.getIcons();
                +  for (var i = 0; i < icons.length; i++) {
                +    icons[i].computeIconLocation();
                +  }
                +
                +  // Recurse through all blocks attached under this one.
                +  for (var i = 0; i < this.childBlocks_.length; i++) {
                +    this.childBlocks_[i].moveConnections_(dx, dy);
                +  }
                +};
                +
                +/**
                + * Recursively adds or removes the dragging class to this node and its children.
                + * @param {boolean} adding True if adding, false if removing.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.setDragging = function(adding) {
                +  if (adding) {
                +    var group = this.getSvgRoot();
                +    group.translate_ = '';
                +    group.skew_ = '';
                +    Blockly.draggingConnections_ =
                +        Blockly.draggingConnections_.concat(this.getConnections_(true));
                +    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
                +                      'blocklyDragging');
                +  } else {
                +    Blockly.draggingConnections_ = [];
                +    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
                +                         'blocklyDragging');
                +  }
                +  // Recurse through all blocks attached under this one.
                +  for (var i = 0; i < this.childBlocks_.length; i++) {
                +    this.childBlocks_[i].setDragging(adding);
                +  }
                +};
                +
                +/**
                + * Add or remove the UI indicating if this block is movable or not.
                + */
                +Blockly.BlockSvg.prototype.updateMovable = function() {
                +  if (this.isMovable()) {
                +    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
                +                      'blocklyDraggable');
                +  } else {
                +    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
                +                         'blocklyDraggable');
                +  }
                +};
                +
                +/**
                + * Set whether this block is movable or not.
                + * @param {boolean} movable True if movable.
                + */
                +Blockly.BlockSvg.prototype.setMovable = function(movable) {
                +  Blockly.BlockSvg.superClass_.setMovable.call(this, movable);
                +  this.updateMovable();
                +};
                +
                +/**
                + * Set whether this block is editable or not.
                + * @param {boolean} editable True if editable.
                + */
                +Blockly.BlockSvg.prototype.setEditable = function(editable) {
                +  Blockly.BlockSvg.superClass_.setEditable.call(this, editable);
                +  var icons = this.getIcons();
                +  for (var i = 0; i < icons.length; i++) {
                +    icons[i].updateEditable();
                +  }
                +};
                +
                +/**
                + * Set whether this block is a shadow block or not.
                + * @param {boolean} shadow True if a shadow.
                + */
                +Blockly.BlockSvg.prototype.setShadow = function(shadow) {
                +  Blockly.BlockSvg.superClass_.setShadow.call(this, shadow);
                +  this.updateColour();
                +};
                +
                +/**
                + * Return the root node of the SVG or null if none exists.
                + * @return {Element} The root SVG node (probably a group).
                + */
                +Blockly.BlockSvg.prototype.getSvgRoot = function() {
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Dispose of this block.
                + * @param {boolean} healStack If true, then try to heal any gap by connecting
                + *     the next statement with the previous statement.  Otherwise, dispose of
                + *     all children of this block.
                + * @param {boolean} animate If true, show a disposal animation and sound.
                + */
                +Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
                +  if (!this.workspace) {
                +    // The block has already been deleted.
                +    return;
                +  }
                +  Blockly.Tooltip.hide();
                +  Blockly.Field.startCache();
                +  // Save the block's workspace temporarily so we can resize the
                +  // contents once the block is disposed.
                +  var blockWorkspace = this.workspace;
                +  // If this block is being dragged, unlink the mouse events.
                +  if (Blockly.selected == this) {
                +    this.unselect();
                +    this.workspace.cancelCurrentGesture();
                +  }
                +  // If this block has a context menu open, close it.
                +  if (Blockly.ContextMenu.currentBlock == this) {
                +    Blockly.ContextMenu.hide();
                +  }
                +
                +  if (animate && this.rendered) {
                +    this.unplug(healStack);
                +    this.disposeUiEffect();
                +  }
                +  // Stop rerendering.
                +  this.rendered = false;
                +
                +  Blockly.Events.disable();
                +  try {
                +    var icons = this.getIcons();
                +    for (var i = 0; i < icons.length; i++) {
                +      icons[i].dispose();
                +    }
                +  } finally {
                +    Blockly.Events.enable();
                +  }
                +  Blockly.BlockSvg.superClass_.dispose.call(this, healStack);
                +
                +  goog.dom.removeNode(this.svgGroup_);
                +  blockWorkspace.resizeContents();
                +  // Sever JavaScript to DOM connections.
                +  this.svgGroup_ = null;
                +  this.svgPath_ = null;
                +  this.svgPathLight_ = null;
                +  this.svgPathDark_ = null;
                +  Blockly.Field.stopCache();
                +};
                +
                +/**
                + * Play some UI effects (sound, animation) when disposing of a block.
                + */
                +Blockly.BlockSvg.prototype.disposeUiEffect = function() {
                +  this.workspace.getAudioManager().play('delete');
                +
                +  var xy = this.workspace.getSvgXY(/** @type {!Element} */ (this.svgGroup_));
                +  // Deeply clone the current block.
                +  var clone = this.svgGroup_.cloneNode(true);
                +  clone.translateX_ = xy.x;
                +  clone.translateY_ = xy.y;
                +  clone.setAttribute('transform',
                +      'translate(' + clone.translateX_ + ',' + clone.translateY_ + ')');
                +  this.workspace.getParentSvg().appendChild(clone);
                +  clone.bBox_ = clone.getBBox();
                +  // Start the animation.
                +  Blockly.BlockSvg.disposeUiStep_(clone, this.RTL, new Date,
                +      this.workspace.scale);
                +};
                +
                +/**
                + * Animate a cloned block and eventually dispose of it.
                + * This is a class method, not an instance method since the original block has
                + * been destroyed and is no longer accessible.
                + * @param {!Element} clone SVG element to animate and dispose of.
                + * @param {boolean} rtl True if RTL, false if LTR.
                + * @param {!Date} start Date of animation's start.
                + * @param {number} workspaceScale Scale of workspace.
                + * @private
                + */
                +Blockly.BlockSvg.disposeUiStep_ = function(clone, rtl, start, workspaceScale) {
                +  var ms = new Date - start;
                +  var percent = ms / 150;
                +  if (percent > 1) {
                +    goog.dom.removeNode(clone);
                +  } else {
                +    var x = clone.translateX_ +
                +        (rtl ? -1 : 1) * clone.bBox_.width * workspaceScale / 2 * percent;
                +    var y = clone.translateY_ + clone.bBox_.height * workspaceScale * percent;
                +    var scale = (1 - percent) * workspaceScale;
                +    clone.setAttribute('transform', 'translate(' + x + ',' + y + ')' +
                +        ' scale(' + scale + ')');
                +    setTimeout(Blockly.BlockSvg.disposeUiStep_, 10, clone, rtl, start,
                +               workspaceScale);
                +  }
                +};
                +
                +/**
                + * Play some UI effects (sound, ripple) after a connection has been established.
                + */
                +Blockly.BlockSvg.prototype.connectionUiEffect = function() {
                +  this.workspace.getAudioManager().play('click');
                +  if (this.workspace.scale < 1) {
                +    return;  // Too small to care about visual effects.
                +  }
                +  // Determine the absolute coordinates of the inferior block.
                +  var xy = this.workspace.getSvgXY(/** @type {!Element} */ (this.svgGroup_));
                +  // Offset the coordinates based on the two connection types, fix scale.
                +  if (this.outputConnection) {
                +    xy.x += (this.RTL ? 3 : -3) * this.workspace.scale;
                +    xy.y += 13 * this.workspace.scale;
                +  } else if (this.previousConnection) {
                +    xy.x += (this.RTL ? -23 : 23) * this.workspace.scale;
                +    xy.y += 3 * this.workspace.scale;
                +  }
                +  var ripple = Blockly.utils.createSvgElement('circle',
                +      {'cx': xy.x, 'cy': xy.y, 'r': 0, 'fill': 'none',
                +       'stroke': '#888', 'stroke-width': 10},
                +      this.workspace.getParentSvg());
                +  // Start the animation.
                +  Blockly.BlockSvg.connectionUiStep_(ripple, new Date, this.workspace.scale);
                +};
                +
                +/**
                + * Expand a ripple around a connection.
                + * @param {!Element} ripple Element to animate.
                + * @param {!Date} start Date of animation's start.
                + * @param {number} workspaceScale Scale of workspace.
                + * @private
                + */
                +Blockly.BlockSvg.connectionUiStep_ = function(ripple, start, workspaceScale) {
                +  var ms = new Date - start;
                +  var percent = ms / 150;
                +  if (percent > 1) {
                +    goog.dom.removeNode(ripple);
                +  } else {
                +    ripple.setAttribute('r', percent * 25 * workspaceScale);
                +    ripple.style.opacity = 1 - percent;
                +    Blockly.BlockSvg.disconnectUiStop_.pid_ = setTimeout(
                +        Blockly.BlockSvg.connectionUiStep_, 10, ripple, start, workspaceScale);
                +  }
                +};
                +
                +/**
                + * Play some UI effects (sound, animation) when disconnecting a block.
                + */
                +Blockly.BlockSvg.prototype.disconnectUiEffect = function() {
                +  this.workspace.getAudioManager().play('disconnect');
                +  if (this.workspace.scale < 1) {
                +    return;  // Too small to care about visual effects.
                +  }
                +  // Horizontal distance for bottom of block to wiggle.
                +  var DISPLACEMENT = 10;
                +  // Scale magnitude of skew to height of block.
                +  var height = this.getHeightWidth().height;
                +  var magnitude = Math.atan(DISPLACEMENT / height) / Math.PI * 180;
                +  if (!this.RTL) {
                +    magnitude *= -1;
                +  }
                +  // Start the animation.
                +  Blockly.BlockSvg.disconnectUiStep_(this.svgGroup_, magnitude, new Date);
                +};
                +
                +/**
                + * Animate a brief wiggle of a disconnected block.
                + * @param {!Element} group SVG element to animate.
                + * @param {number} magnitude Maximum degrees skew (reversed for RTL).
                + * @param {!Date} start Date of animation's start.
                + * @private
                + */
                +Blockly.BlockSvg.disconnectUiStep_ = function(group, magnitude, start) {
                +  var DURATION = 200;  // Milliseconds.
                +  var WIGGLES = 3;  // Half oscillations.
                +
                +  var ms = new Date - start;
                +  var percent = ms / DURATION;
                +
                +  if (percent > 1) {
                +    group.skew_ = '';
                +  } else {
                +    var skew = Math.round(Math.sin(percent * Math.PI * WIGGLES) *
                +        (1 - percent) * magnitude);
                +    group.skew_ = 'skewX(' + skew + ')';
                +    Blockly.BlockSvg.disconnectUiStop_.group = group;
                +    Blockly.BlockSvg.disconnectUiStop_.pid =
                +        setTimeout(Blockly.BlockSvg.disconnectUiStep_, 10, group, magnitude,
                +                   start);
                +  }
                +  group.setAttribute('transform', group.translate_ + group.skew_);
                +};
                +
                +/**
                + * Stop the disconnect UI animation immediately.
                + * @private
                + */
                +Blockly.BlockSvg.disconnectUiStop_ = function() {
                +  if (Blockly.BlockSvg.disconnectUiStop_.group) {
                +    clearTimeout(Blockly.BlockSvg.disconnectUiStop_.pid);
                +    var group = Blockly.BlockSvg.disconnectUiStop_.group;
                +    group.skew_ = '';
                +    group.setAttribute('transform', group.translate_);
                +    Blockly.BlockSvg.disconnectUiStop_.group = null;
                +  }
                +};
                +
                +/**
                + * PID of disconnect UI animation.  There can only be one at a time.
                + * @type {number}
                + */
                +Blockly.BlockSvg.disconnectUiStop_.pid = 0;
                +
                +/**
                + * SVG group of wobbling block.  There can only be one at a time.
                + * @type {Element}
                + */
                +Blockly.BlockSvg.disconnectUiStop_.group = null;
                +
                +/**
                + * Change the colour of a block.
                + */
                +Blockly.BlockSvg.prototype.updateColour = function() {
                +  if (this.disabled) {
                +    // Disabled blocks don't have colour.
                +    return;
                +  }
                +  var hexColour = this.getColour();
                +  var rgb = goog.color.hexToRgb(hexColour);
                +  if (this.isShadow()) {
                +    rgb = goog.color.lighten(rgb, 0.6);
                +    hexColour = goog.color.rgbArrayToHex(rgb);
                +    this.svgPathLight_.style.display = 'none';
                +    this.svgPathDark_.setAttribute('fill', hexColour);
                +  } else {
                +    this.svgPathLight_.style.display = '';
                +    var hexLight = goog.color.rgbArrayToHex(goog.color.lighten(rgb, 0.3));
                +    var hexDark = goog.color.rgbArrayToHex(goog.color.darken(rgb, 0.2));
                +    this.svgPathLight_.setAttribute('stroke', hexLight);
                +    this.svgPathDark_.setAttribute('fill', hexDark);
                +  }
                +  this.svgPath_.setAttribute('fill', hexColour);
                +
                +  var icons = this.getIcons();
                +  for (var i = 0; i < icons.length; i++) {
                +    icons[i].updateColour();
                +  }
                +
                +  // Bump every dropdown to change its colour.
                +  for (var x = 0, input; input = this.inputList[x]; x++) {
                +    for (var y = 0, field; field = input.fieldRow[y]; y++) {
                +      field.setText(null);
                +    }
                +  }
                +};
                +
                +/**
                + * Enable or disable a block.
                + */
                +Blockly.BlockSvg.prototype.updateDisabled = function() {
                +  if (this.disabled || this.getInheritedDisabled()) {
                +    if (Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
                +                      'blocklyDisabled')) {
                +      this.svgPath_.setAttribute('fill',
                +          'url(#' + this.workspace.options.disabledPatternId + ')');
                +    }
                +  } else {
                +    if (Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
                +                         'blocklyDisabled')) {
                +      this.updateColour();
                +    }
                +  }
                +  var children = this.getChildren();
                +  for (var i = 0, child; child = children[i]; i++) {
                +    child.updateDisabled();
                +  }
                +};
                +
                +/**
                + * Returns the comment on this block (or '' if none).
                + * @return {string} Block's comment.
                + */
                +Blockly.BlockSvg.prototype.getCommentText = function() {
                +  if (this.comment) {
                +    var comment = this.comment.getText();
                +    // Trim off trailing whitespace.
                +    return comment.replace(/\s+$/, '').replace(/ +\n/g, '\n');
                +  }
                +  return '';
                +};
                +
                +/**
                + * Set this block's comment text.
                + * @param {?string} text The text, or null to delete.
                + */
                +Blockly.BlockSvg.prototype.setCommentText = function(text) {
                +  var changedState = false;
                +  if (goog.isString(text)) {
                +    if (!this.comment) {
                +      this.comment = new Blockly.Comment(this);
                +      changedState = true;
                +    }
                +    this.comment.setText(/** @type {string} */ (text));
                +  } else {
                +    if (this.comment) {
                +      this.comment.dispose();
                +      changedState = true;
                +    }
                +  }
                +  if (changedState && this.rendered) {
                +    this.render();
                +    // Adding or removing a comment icon will cause the block to change shape.
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Set this block's warning text.
                + * @param {?string} text The text, or null to delete.
                + * @param {string=} opt_id An optional ID for the warning text to be able to
                + *     maintain multiple warnings.
                + */
                +Blockly.BlockSvg.prototype.setWarningText = function(text, opt_id) {
                +  if (!this.setWarningText.pid_) {
                +    // Create a database of warning PIDs.
                +    // Only runs once per block (and only those with warnings).
                +    this.setWarningText.pid_ = Object.create(null);
                +  }
                +  var id = opt_id || '';
                +  if (!id) {
                +    // Kill all previous pending processes, this edit supersedes them all.
                +    for (var n in this.setWarningText.pid_) {
                +      clearTimeout(this.setWarningText.pid_[n]);
                +      delete this.setWarningText.pid_[n];
                +    }
                +  } else if (this.setWarningText.pid_[id]) {
                +    // Only queue up the latest change.  Kill any earlier pending process.
                +    clearTimeout(this.setWarningText.pid_[id]);
                +    delete this.setWarningText.pid_[id];
                +  }
                +  if (this.workspace.isDragging()) {
                +    // Don't change the warning text during a drag.
                +    // Wait until the drag finishes.
                +    var thisBlock = this;
                +    this.setWarningText.pid_[id] = setTimeout(function() {
                +      if (thisBlock.workspace) {  // Check block wasn't deleted.
                +        delete thisBlock.setWarningText.pid_[id];
                +        thisBlock.setWarningText(text, id);
                +      }
                +    }, 100);
                +    return;
                +  }
                +  if (this.isInFlyout) {
                +    text = null;
                +  }
                +
                +  // Bubble up to add a warning on top-most collapsed block.
                +  var parent = this.getSurroundParent();
                +  var collapsedParent = null;
                +  while (parent) {
                +    if (parent.isCollapsed()) {
                +      collapsedParent = parent;
                +    }
                +    parent = parent.getSurroundParent();
                +  }
                +  if (collapsedParent) {
                +    collapsedParent.setWarningText(text, 'collapsed ' + this.id + ' ' + id);
                +  }
                +
                +  var changedState = false;
                +  if (goog.isString(text)) {
                +    if (!this.warning) {
                +      this.warning = new Blockly.Warning(this);
                +      changedState = true;
                +    }
                +    this.warning.setText(/** @type {string} */ (text), id);
                +  } else {
                +    // Dispose all warnings if no id is given.
                +    if (this.warning && !id) {
                +      this.warning.dispose();
                +      changedState = true;
                +    } else if (this.warning) {
                +      var oldText = this.warning.getText();
                +      this.warning.setText('', id);
                +      var newText = this.warning.getText();
                +      if (!newText) {
                +        this.warning.dispose();
                +      }
                +      changedState = oldText != newText;
                +    }
                +  }
                +  if (changedState && this.rendered) {
                +    this.render();
                +    // Adding or removing a warning icon will cause the block to change shape.
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Give this block a mutator dialog.
                + * @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove.
                + */
                +Blockly.BlockSvg.prototype.setMutator = function(mutator) {
                +  if (this.mutator && this.mutator !== mutator) {
                +    this.mutator.dispose();
                +  }
                +  if (mutator) {
                +    mutator.block_ = this;
                +    this.mutator = mutator;
                +    mutator.createIcon();
                +  }
                +};
                +
                +/**
                + * Set whether the block is disabled or not.
                + * @param {boolean} disabled True if disabled.
                + */
                +Blockly.BlockSvg.prototype.setDisabled = function(disabled) {
                +  if (this.disabled != disabled) {
                +    Blockly.BlockSvg.superClass_.setDisabled.call(this, disabled);
                +    if (this.rendered) {
                +      this.updateDisabled();
                +    }
                +  }
                +};
                +
                +/**
                + * Set whether the block is highlighted or not.  Block highlighting is
                + * often used to visually mark blocks currently being executed.
                + * @param {boolean} highlighted True if highlighted.
                + */
                +Blockly.BlockSvg.prototype.setHighlighted = function(highlighted) {
                +  if (!this.rendered) {
                +    return;
                +  }
                +  if (highlighted) {
                +    this.svgPath_.setAttribute('filter',
                +        'url(#' + this.workspace.options.embossFilterId + ')');
                +    this.svgPathLight_.style.display = 'none';
                +  } else {
                +    Blockly.utils.removeAttribute(this.svgPath_, 'filter');
                +    delete this.svgPathLight_.style.display;
                +  }
                +};
                +
                +/**
                + * Select this block.  Highlight it visually.
                + */
                +Blockly.BlockSvg.prototype.addSelect = function() {
                +  Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
                +                    'blocklySelected');
                +};
                +
                +/**
                + * Unselect this block.  Remove its highlighting.
                + */
                +Blockly.BlockSvg.prototype.removeSelect = function() {
                +  Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
                +                       'blocklySelected');
                +};
                +
                +/**
                + * Update the cursor over this block by adding or removing a class.
                + * @param {boolean} enable True if the delete cursor should be shown, false
                + *     otherwise.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
                +  if (enable) {
                +    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
                +        'blocklyDraggingDelete');
                +  } else {
                +    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
                +        'blocklyDraggingDelete');
                +  }
                +};
                +
                +// Overrides of functions on Blockly.Block that take into account whether the
                +// block has been rendered.
                +
                +/**
                + * Change the colour of a block.
                + * @param {number|string} colour HSV hue value, or #RRGGBB string.
                + */
                +Blockly.BlockSvg.prototype.setColour = function(colour) {
                +  Blockly.BlockSvg.superClass_.setColour.call(this, colour);
                +
                +  if (this.rendered) {
                +    this.updateColour();
                +  }
                +};
                +
                +/**
                + * Move this block to the front of the visible workspace.
                + * <g> tags do not respect z-index so svg renders them in the
                + * order that they are in the dom.  By placing this block first within the
                + * block group's <g>, it will render on top of any other blocks.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.bringToFront = function() {
                +  var block = this;
                +  do {
                +    var root = block.getSvgRoot();
                +    root.parentNode.appendChild(root);
                +    block = block.getParent();
                +  } while (block);
                +};
                +
                +/**
                + * Set whether this block can chain onto the bottom of another block.
                + * @param {boolean} newBoolean True if there can be a previous statement.
                + * @param {string|Array.<string>|null|undefined} opt_check Statement type or
                + *     list of statement types.  Null/undefined if any type could be connected.
                + */
                +Blockly.BlockSvg.prototype.setPreviousStatement =
                +    function(newBoolean, opt_check) {
                +  /* eslint-disable indent */
                +  Blockly.BlockSvg.superClass_.setPreviousStatement.call(this, newBoolean,
                +      opt_check);
                +
                +  if (this.rendered) {
                +    this.render();
                +    this.bumpNeighbours_();
                +  }
                +};  /* eslint-enable indent */
                +
                +/**
                + * Set whether another block can chain onto the bottom of this block.
                + * @param {boolean} newBoolean True if there can be a next statement.
                + * @param {string|Array.<string>|null|undefined} opt_check Statement type or
                + *     list of statement types.  Null/undefined if any type could be connected.
                + */
                +Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) {
                +  Blockly.BlockSvg.superClass_.setNextStatement.call(this, newBoolean,
                +      opt_check);
                +
                +  if (this.rendered) {
                +    this.render();
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Set whether this block returns a value.
                + * @param {boolean} newBoolean True if there is an output.
                + * @param {string|Array.<string>|null|undefined} opt_check Returned type or list
                + *     of returned types.  Null or undefined if any type could be returned
                + *     (e.g. variable get).
                + */
                +Blockly.BlockSvg.prototype.setOutput = function(newBoolean, opt_check) {
                +  Blockly.BlockSvg.superClass_.setOutput.call(this, newBoolean, opt_check);
                +
                +  if (this.rendered) {
                +    this.render();
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Set whether value inputs are arranged horizontally or vertically.
                + * @param {boolean} newBoolean True if inputs are horizontal.
                + */
                +Blockly.BlockSvg.prototype.setInputsInline = function(newBoolean) {
                +  Blockly.BlockSvg.superClass_.setInputsInline.call(this, newBoolean);
                +
                +  if (this.rendered) {
                +    this.render();
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Remove an input from this block.
                + * @param {string} name The name of the input.
                + * @param {boolean=} opt_quiet True to prevent error if input is not present.
                + * @throws {goog.asserts.AssertionError} if the input is not present and
                + *     opt_quiet is not true.
                + */
                +Blockly.BlockSvg.prototype.removeInput = function(name, opt_quiet) {
                +  Blockly.BlockSvg.superClass_.removeInput.call(this, name, opt_quiet);
                +
                +  if (this.rendered) {
                +    this.render();
                +    // Removing an input will cause the block to change shape.
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Move a numbered input to a different location on this block.
                + * @param {number} inputIndex Index of the input to move.
                + * @param {number} refIndex Index of input that should be after the moved input.
                + */
                +Blockly.BlockSvg.prototype.moveNumberedInputBefore = function(
                +    inputIndex, refIndex) {
                +  Blockly.BlockSvg.superClass_.moveNumberedInputBefore.call(this, inputIndex,
                +      refIndex);
                +
                +  if (this.rendered) {
                +    this.render();
                +    // Moving an input will cause the block to change shape.
                +    this.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * Add a value input, statement input or local variable to this block.
                + * @param {number} type Either Blockly.INPUT_VALUE or Blockly.NEXT_STATEMENT or
                + *     Blockly.DUMMY_INPUT.
                + * @param {string} name Language-neutral identifier which may used to find this
                + *     input again.  Should be unique to this block.
                + * @return {!Blockly.Input} The input object created.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.appendInput_ = function(type, name) {
                +  var input = Blockly.BlockSvg.superClass_.appendInput_.call(this, type, name);
                +
                +  if (this.rendered) {
                +    this.render();
                +    // Adding an input will cause the block to change shape.
                +    this.bumpNeighbours_();
                +  }
                +  return input;
                +};
                +
                +/**
                + * Returns connections originating from this block.
                + * @param {boolean} all If true, return all connections even hidden ones.
                + *     Otherwise, for a non-rendered block return an empty list, and for a
                + *     collapsed block don't return inputs connections.
                + * @return {!Array.<!Blockly.Connection>} Array of connections.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.getConnections_ = function(all) {
                +  var myConnections = [];
                +  if (all || this.rendered) {
                +    if (this.outputConnection) {
                +      myConnections.push(this.outputConnection);
                +    }
                +    if (this.previousConnection) {
                +      myConnections.push(this.previousConnection);
                +    }
                +    if (this.nextConnection) {
                +      myConnections.push(this.nextConnection);
                +    }
                +    if (all || !this.collapsed_) {
                +      for (var i = 0, input; input = this.inputList[i]; i++) {
                +        if (input.connection) {
                +          myConnections.push(input.connection);
                +        }
                +      }
                +    }
                +  }
                +  return myConnections;
                +};
                +
                +/**
                + * Create a connection of the specified type.
                + * @param {number} type The type of the connection to create.
                + * @return {!Blockly.RenderedConnection} A new connection of the specified type.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.makeConnection_ = function(type) {
                +  return new Blockly.RenderedConnection(this, type);
                +};
                +
                +/**
                + * Bump unconnected blocks out of alignment.  Two blocks which aren't actually
                + * connected should not coincidentally line up on screen.
                + * @private
                + */
                +Blockly.BlockSvg.prototype.bumpNeighbours_ = function() {
                +  if (!this.workspace) {
                +    return;  // Deleted block.
                +  }
                +  if (Blockly.dragMode_ != Blockly.DRAG_NONE) {
                +    return;  // Don't bump blocks during a drag.
                +  }
                +  var rootBlock = this.getRootBlock();
                +  if (rootBlock.isInFlyout) {
                +    return;  // Don't move blocks around in a flyout.
                +  }
                +  // Loop through every connection on this block.
                +  var myConnections = this.getConnections_(false);
                +  for (var i = 0, connection; connection = myConnections[i]; i++) {
                +
                +    // Spider down from this block bumping all sub-blocks.
                +    if (connection.isConnected() && connection.isSuperior()) {
                +      connection.targetBlock().bumpNeighbours_();
                +    }
                +
                +    var neighbours = connection.neighbours_(Blockly.SNAP_RADIUS);
                +    for (var j = 0, otherConnection; otherConnection = neighbours[j]; j++) {
                +
                +      // If both connections are connected, that's probably fine.  But if
                +      // either one of them is unconnected, then there could be confusion.
                +      if (!connection.isConnected() || !otherConnection.isConnected()) {
                +        // Only bump blocks if they are from different tree structures.
                +        if (otherConnection.getSourceBlock().getRootBlock() != rootBlock) {
                +
                +          // Always bump the inferior block.
                +          if (connection.isSuperior()) {
                +            otherConnection.bumpAwayFrom_(connection);
                +          } else {
                +            connection.bumpAwayFrom_(otherConnection);
                +          }
                +        }
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Schedule snapping to grid and bumping neighbours to occur after a brief
                + * delay.
                + * @package
                + */
                +Blockly.BlockSvg.prototype.scheduleSnapAndBump = function() {
                +  var block = this;
                +  // Ensure that any snap and bump are part of this move's event group.
                +  var group = Blockly.Events.getGroup();
                +
                +  setTimeout(function() {
                +    Blockly.Events.setGroup(group);
                +    block.snapToGrid();
                +    Blockly.Events.setGroup(false);
                +  }, Blockly.BUMP_DELAY / 2);
                +
                +  setTimeout(function() {
                +    Blockly.Events.setGroup(group);
                +    block.bumpNeighbours_();
                +    Blockly.Events.setGroup(false);
                +  }, Blockly.BUMP_DELAY);
                +};
                diff --git a/blockly/webif/static/blockly/core/blockly.js b/blockly/webif/static/blockly/core/blockly.js
                new file mode 100644
                index 000000000..8b7083401
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/blockly.js
                @@ -0,0 +1,541 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Core JavaScript library for Blockly.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * The top level namespace used to access the Blockly library.
                + * @namespace Blockly
                + **/
                +goog.provide('Blockly');
                +
                +goog.require('Blockly.BlockSvg.render');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.FieldAngle');
                +goog.require('Blockly.FieldCheckbox');
                +goog.require('Blockly.FieldColour');
                +// Date picker commented out since it increases footprint by 60%.
                +// Add it only if you need it.
                +//goog.require('Blockly.FieldDate');
                +goog.require('Blockly.FieldDropdown');
                +goog.require('Blockly.FieldImage');
                +goog.require('Blockly.FieldTextInput');
                +goog.require('Blockly.FieldNumber');
                +goog.require('Blockly.FieldVariable');
                +goog.require('Blockly.Generator');
                +goog.require('Blockly.Msg');
                +goog.require('Blockly.Procedures');
                +goog.require('Blockly.Toolbox');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.WidgetDiv');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.inject');
                +goog.require('Blockly.utils');
                +goog.require('goog.color');
                +goog.require('goog.userAgent');
                +
                +
                +// Turn off debugging when compiled.
                +var CLOSURE_DEFINES = {'goog.DEBUG': false};
                +
                +/**
                + * The main workspace most recently used.
                + * Set by Blockly.WorkspaceSvg.prototype.markFocused
                + * @type {Blockly.Workspace}
                + */
                +Blockly.mainWorkspace = null;
                +
                +/**
                + * Currently selected block.
                + * @type {Blockly.Block}
                + */
                +Blockly.selected = null;
                +
                +/**
                + * All of the connections on blocks that are currently being dragged.
                + * @type {!Array.<!Blockly.Connection>}
                + * @private
                + */
                +Blockly.draggingConnections_ = [];
                +
                +/**
                + * Contents of the local clipboard.
                + * @type {Element}
                + * @private
                + */
                +Blockly.clipboardXml_ = null;
                +
                +/**
                + * Source of the local clipboard.
                + * @type {Blockly.WorkspaceSvg}
                + * @private
                + */
                +Blockly.clipboardSource_ = null;
                +
                +/**
                + * Cached value for whether 3D is supported.
                + * @type {!boolean}
                + * @private
                + */
                +Blockly.cache3dSupported_ = null;
                +
                +/**
                + * Convert a hue (HSV model) into an RGB hex triplet.
                + * @param {number} hue Hue on a colour wheel (0-360).
                + * @return {string} RGB code, e.g. '#5ba65b'.
                + */
                +Blockly.hueToRgb = function(hue) {
                +  return goog.color.hsvToHex(hue, Blockly.HSV_SATURATION,
                +      Blockly.HSV_VALUE * 255);
                +};
                +
                +/**
                + * Returns the dimensions of the specified SVG image.
                + * @param {!Element} svg SVG image.
                + * @return {!Object} Contains width and height properties.
                + */
                +Blockly.svgSize = function(svg) {
                +  return {width: svg.cachedWidth_,
                +          height: svg.cachedHeight_};
                +};
                +
                +/**
                + * Size the workspace when the contents change.  This also updates
                + * scrollbars accordingly.
                + * @param {!Blockly.WorkspaceSvg} workspace The workspace to resize.
                + */
                +Blockly.resizeSvgContents = function(workspace) {
                +  workspace.resizeContents();
                +};
                +
                +/**
                + * Size the SVG image to completely fill its container. Call this when the view
                + * actually changes sizes (e.g. on a window resize/device orientation change).
                + * See Blockly.resizeSvgContents to resize the workspace when the contents
                + * change (e.g. when a block is added or removed).
                + * Record the height/width of the SVG image.
                + * @param {!Blockly.WorkspaceSvg} workspace Any workspace in the SVG.
                + */
                +Blockly.svgResize = function(workspace) {
                +  var mainWorkspace = workspace;
                +  while (mainWorkspace.options.parentWorkspace) {
                +    mainWorkspace = mainWorkspace.options.parentWorkspace;
                +  }
                +  var svg = mainWorkspace.getParentSvg();
                +  var div = svg.parentNode;
                +  if (!div) {
                +    // Workspace deleted, or something.
                +    return;
                +  }
                +  var width = div.offsetWidth;
                +  var height = div.offsetHeight;
                +  if (svg.cachedWidth_ != width) {
                +    svg.setAttribute('width', width + 'px');
                +    svg.cachedWidth_ = width;
                +  }
                +  if (svg.cachedHeight_ != height) {
                +    svg.setAttribute('height', height + 'px');
                +    svg.cachedHeight_ = height;
                +  }
                +  mainWorkspace.resize();
                +};
                +
                +/**
                + * Handle a key-down on SVG drawing surface.
                + * @param {!Event} e Key down event.
                + * @private
                + */
                +Blockly.onKeyDown_ = function(e) {
                +  if (Blockly.mainWorkspace.options.readOnly || Blockly.utils.isTargetInput(e)) {
                +    // No key actions on readonly workspaces.
                +    // When focused on an HTML text input widget, don't trap any keys.
                +    return;
                +  }
                +  var deleteBlock = false;
                +  if (e.keyCode == 27) {
                +    // Pressing esc closes the context menu.
                +    Blockly.hideChaff();
                +  } else if (e.keyCode == 8 || e.keyCode == 46) {
                +    // Delete or backspace.
                +    // Stop the browser from going back to the previous page.
                +    // Do this first to prevent an error in the delete code from resulting in
                +    // data loss.
                +    e.preventDefault();
                +    // Don't delete while dragging.  Jeez.
                +    if (Blockly.mainWorkspace.isDragging()) {
                +      return;
                +    }
                +    if (Blockly.selected && Blockly.selected.isDeletable()) {
                +      deleteBlock = true;
                +    }
                +  } else if (e.altKey || e.ctrlKey || e.metaKey) {
                +    // Don't use meta keys during drags.
                +    if (Blockly.mainWorkspace.isDragging()) {
                +      return;
                +    }
                +    if (Blockly.selected &&
                +        Blockly.selected.isDeletable() && Blockly.selected.isMovable()) {
                +      if (e.keyCode == 67) {
                +        // 'c' for copy.
                +        Blockly.hideChaff();
                +        Blockly.copy_(Blockly.selected);
                +      } else if (e.keyCode == 88) {
                +        // 'x' for cut.
                +        Blockly.copy_(Blockly.selected);
                +        deleteBlock = true;
                +      }
                +    }
                +    if (e.keyCode == 86) {
                +      // 'v' for paste.
                +      if (Blockly.clipboardXml_) {
                +        Blockly.Events.setGroup(true);
                +        Blockly.clipboardSource_.paste(Blockly.clipboardXml_);
                +        Blockly.Events.setGroup(false);
                +      }
                +    } else if (e.keyCode == 90) {
                +      // 'z' for undo 'Z' is for redo.
                +      Blockly.hideChaff();
                +      Blockly.mainWorkspace.undo(e.shiftKey);
                +    }
                +  }
                +  if (deleteBlock) {
                +    // Common code for delete and cut.
                +    Blockly.Events.setGroup(true);
                +    Blockly.hideChaff();
                +    Blockly.selected.dispose(/* heal */ true, true);
                +    Blockly.Events.setGroup(false);
                +  }
                +};
                +
                +/**
                + * Copy a block onto the local clipboard.
                + * @param {!Blockly.Block} block Block to be copied.
                + * @private
                + */
                +Blockly.copy_ = function(block) {
                +  var xmlBlock = Blockly.Xml.blockToDom(block);
                +  // Copy only the selected block and internal blocks.
                +  Blockly.Xml.deleteNext(xmlBlock);
                +  // Encode start position in XML.
                +  var xy = block.getRelativeToSurfaceXY();
                +  xmlBlock.setAttribute('x', block.RTL ? -xy.x : xy.x);
                +  xmlBlock.setAttribute('y', xy.y);
                +  Blockly.clipboardXml_ = xmlBlock;
                +  Blockly.clipboardSource_ = block.workspace;
                +};
                +
                +/**
                + * Duplicate this block and its children.
                + * @param {!Blockly.Block} block Block to be copied.
                + * @private
                + */
                +Blockly.duplicate_ = function(block) {
                +  // Save the clipboard.
                +  var clipboardXml = Blockly.clipboardXml_;
                +  var clipboardSource = Blockly.clipboardSource_;
                +
                +  // Create a duplicate via a copy/paste operation.
                +  Blockly.copy_(block);
                +  block.workspace.paste(Blockly.clipboardXml_);
                +
                +  // Restore the clipboard.
                +  Blockly.clipboardXml_ = clipboardXml;
                +  Blockly.clipboardSource_ = clipboardSource;
                +};
                +
                +/**
                + * Cancel the native context menu, unless the focus is on an HTML input widget.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.onContextMenu_ = function(e) {
                +  if (!Blockly.utils.isTargetInput(e)) {
                +    // When focused on an HTML text input widget, don't cancel the context menu.
                +    e.preventDefault();
                +  }
                +};
                +
                +/**
                + * Close tooltips, context menus, dropdown selections, etc.
                + * @param {boolean=} opt_allowToolbox If true, don't close the toolbox.
                + */
                +Blockly.hideChaff = function(opt_allowToolbox) {
                +  Blockly.Tooltip.hide();
                +  Blockly.WidgetDiv.hide();
                +  if (!opt_allowToolbox) {
                +    var workspace = Blockly.getMainWorkspace();
                +    if (workspace.toolbox_ &&
                +        workspace.toolbox_.flyout_ &&
                +        workspace.toolbox_.flyout_.autoClose) {
                +      workspace.toolbox_.clearSelection();
                +    }
                +  }
                +};
                +
                +/**
                + * When something in Blockly's workspace changes, call a function.
                + * @param {!Function} func Function to call.
                + * @return {!Array.<!Array>} Opaque data that can be passed to
                + *     removeChangeListener.
                + * @deprecated April 2015
                + */
                +Blockly.addChangeListener = function(func) {
                +  // Backwards compatibility from before there could be multiple workspaces.
                +  console.warn('Deprecated call to Blockly.addChangeListener, ' +
                +               'use workspace.addChangeListener instead.');
                +  return Blockly.getMainWorkspace().addChangeListener(func);
                +};
                +
                +/**
                + * Returns the main workspace.  Returns the last used main workspace (based on
                + * focus).  Try not to use this function, particularly if there are multiple
                + * Blockly instances on a page.
                + * @return {!Blockly.Workspace} The main workspace.
                + */
                +Blockly.getMainWorkspace = function() {
                +  return Blockly.mainWorkspace;
                +};
                +
                +/**
                + * Wrapper to window.alert() that app developers may override to
                + * provide alternatives to the modal browser window.
                + * @param {string} message The message to display to the user.
                + * @param {function()=} opt_callback The callback when the alert is dismissed.
                + */
                +Blockly.alert = function(message, opt_callback) {
                +  window.alert(message);
                +  if (opt_callback) {
                +    opt_callback();
                +  }
                +};
                +
                +/**
                + * Wrapper to window.confirm() that app developers may override to
                + * provide alternatives to the modal browser window.
                + * @param {string} message The message to display to the user.
                + * @param {!function(boolean)} callback The callback for handling user response.
                + */
                +Blockly.confirm = function(message, callback) {
                +  callback(window.confirm(message));
                +};
                +
                +/**
                + * Wrapper to window.prompt() that app developers may override to provide
                + * alternatives to the modal browser window. Built-in browser prompts are
                + * often used for better text input experience on mobile device. We strongly
                + * recommend testing mobile when overriding this.
                + * @param {string} message The message to display to the user.
                + * @param {string} defaultValue The value to initialize the prompt with.
                + * @param {!function(string)} callback The callback for handling user response.
                + */
                +Blockly.prompt = function(message, defaultValue, callback) {
                +  callback(window.prompt(message, defaultValue));
                +};
                +
                +/**
                + * Helper function for defining a block from JSON.  The resulting function has
                + * the correct value of jsonDef at the point in code where jsonInit is called.
                + * @param {!Object} jsonDef The JSON definition of a block.
                + * @return {function()} A function that calls jsonInit with the correct value
                + *     of jsonDef.
                + * @private
                + */
                +Blockly.jsonInitFactory_ = function(jsonDef) {
                +  return function() {
                +    this.jsonInit(jsonDef);
                +  };
                +};
                +
                +/**
                + * Define blocks from an array of JSON block definitions, as might be generated
                + * by the Blockly Developer Tools.
                + * @param {!Array.<!Object>} jsonArray An array of JSON block definitions.
                + */
                +Blockly.defineBlocksWithJsonArray = function(jsonArray) {
                +  for (var i = 0, elem; elem = jsonArray[i]; i++) {
                +    var typename = elem.type;
                +    if (typename == null || typename === '') {
                +      console.warn('Block definition #' + i +
                +        ' in JSON array is missing a type attribute. Skipping.');
                +    } else {
                +      if (Blockly.Blocks[typename]) {
                +        console.warn('Block definition #' + i +
                +          ' in JSON array overwrites prior definition of "' + typename + '".');
                +      }
                +      Blockly.Blocks[typename] = {
                +        init: Blockly.jsonInitFactory_(elem)
                +      };
                +    }
                +  }
                +};
                +
                +/**
                + * Bind an event to a function call.  When calling the function, verifies that
                + * it belongs to the touch stream that is currently being processed, and splits
                + * multitouch events into multiple events as needed.
                + * @param {!Node} node Node upon which to listen.
                + * @param {string} name Event name to listen to (e.g. 'mousedown').
                + * @param {Object} thisObject The value of 'this' in the function.
                + * @param {!Function} func Function to call when event is triggered.
                + * @param {boolean} opt_noCaptureIdentifier True if triggering on this event
                + *     should not block execution of other event handlers on this touch or other
                + *     simultaneous touches.
                + * @return {!Array.<!Array>} Opaque data that can be passed to unbindEvent_.
                + * @private
                + */
                +Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
                +    opt_noCaptureIdentifier) {
                +  var handled = false;
                +  var wrapFunc = function(e) {
                +    var captureIdentifier = !opt_noCaptureIdentifier;
                +    // Handle each touch point separately.  If the event was a mouse event, this
                +    // will hand back an array with one element, which we're fine handling.
                +    var events = Blockly.Touch.splitEventByTouches(e);
                +    for (var i = 0, event; event = events[i]; i++) {
                +      if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
                +        continue;
                +      }
                +      Blockly.Touch.setClientFromTouch(event);
                +      if (thisObject) {
                +        func.call(thisObject, event);
                +      } else {
                +        func(event);
                +      }
                +      handled = true;
                +    }
                +  };
                +
                +  node.addEventListener(name, wrapFunc, false);
                +  var bindData = [[node, name, wrapFunc]];
                +
                +  // Add equivalent touch event.
                +  if (name in Blockly.Touch.TOUCH_MAP) {
                +    var touchWrapFunc = function(e) {
                +      wrapFunc(e);
                +      // Stop the browser from scrolling/zooming the page.
                +      if (handled) {
                +        e.preventDefault();
                +      }
                +    };
                +    for (var i = 0, eventName;
                +         eventName = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
                +      node.addEventListener(eventName, touchWrapFunc, false);
                +      bindData.push([node, eventName, touchWrapFunc]);
                +    }
                +  }
                +  return bindData;
                +};
                +
                +
                +/**
                + * Bind an event to a function call.  Handles multitouch events by using the
                + * coordinates of the first changed touch, and doesn't do any safety checks for
                + * simultaneous event processing.
                + * @deprecated in favor of bindEventWithChecks_, but preserved for external
                + * users.
                + * @param {!Node} node Node upon which to listen.
                + * @param {string} name Event name to listen to (e.g. 'mousedown').
                + * @param {Object} thisObject The value of 'this' in the function.
                + * @param {!Function} func Function to call when event is triggered.
                + * @return {!Array.<!Array>} Opaque data that can be passed to unbindEvent_.
                + * @private
                + */
                +Blockly.bindEvent_ = function(node, name, thisObject, func) {
                +  var wrapFunc = function(e) {
                +    if (thisObject) {
                +      func.call(thisObject, e);
                +    } else {
                +      func(e);
                +    }
                +  };
                +
                +  node.addEventListener(name, wrapFunc, false);
                +  var bindData = [[node, name, wrapFunc]];
                +
                +  // Add equivalent touch event.
                +  if (name in Blockly.Touch.TOUCH_MAP) {
                +    var touchWrapFunc = function(e) {
                +      // Punt on multitouch events.
                +      if (e.changedTouches.length == 1) {
                +        // Map the touch event's properties to the event.
                +        var touchPoint = e.changedTouches[0];
                +        e.clientX = touchPoint.clientX;
                +        e.clientY = touchPoint.clientY;
                +      }
                +      wrapFunc(e);
                +
                +      // Stop the browser from scrolling/zooming the page.
                +      e.preventDefault();
                +    };
                +    for (var i = 0, eventName;
                +         eventName = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
                +      node.addEventListener(eventName, touchWrapFunc, false);
                +      bindData.push([node, eventName, touchWrapFunc]);
                +    }
                +  }
                +  return bindData;
                +};
                +
                +/**
                + * Unbind one or more events event from a function call.
                + * @param {!Array.<!Array>} bindData Opaque data from bindEvent_.
                + *     This list is emptied during the course of calling this function.
                + * @return {!Function} The function call.
                + * @private
                + */
                +Blockly.unbindEvent_ = function(bindData) {
                +  while (bindData.length) {
                +    var bindDatum = bindData.pop();
                +    var node = bindDatum[0];
                +    var name = bindDatum[1];
                +    var func = bindDatum[2];
                +    node.removeEventListener(name, func, false);
                +  }
                +  return func;
                +};
                +
                +/**
                + * Is the given string a number (includes negative and decimals).
                + * @param {string} str Input string.
                + * @return {boolean} True if number, false otherwise.
                + */
                +Blockly.isNumber = function(str) {
                +  return !!str.match(/^\s*-?\d+(\.\d+)?\s*$/);
                +};
                +
                +// IE9 does not have a console.  Create a stub to stop errors.
                +if (!goog.global['console']) {
                +  goog.global['console'] = {
                +    'log': function() {},
                +    'warn': function() {}
                +  };
                +}
                +
                +// Export symbols that would otherwise be renamed by Closure compiler.
                +if (!goog.global['Blockly']) {
                +  goog.global['Blockly'] = {};
                +}
                +goog.global['Blockly']['getMainWorkspace'] = Blockly.getMainWorkspace;
                +goog.global['Blockly']['addChangeListener'] = Blockly.addChangeListener;
                diff --git a/blockly/webif/static/blockly/core/blocks.js b/blockly/webif/static/blockly/core/blocks.js
                new file mode 100644
                index 000000000..5b78050aa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/blocks.js
                @@ -0,0 +1,37 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview A mapping of block type names to block prototype objects.
                + * @author spertus@google.com (Ellen Spertus)
                + */
                +'use strict';
                +
                +/**
                + * A mapping of block type names to block prototype objects.
                + * @name Blockly.Blocks
                + */
                +goog.provide('Blockly.Blocks');
                +
                +/*
                + * A mapping of block type names to block prototype objects.
                + * @type {!Object<string,Object>}
                + */
                +Blockly.Blocks = new Object(null);
                diff --git a/blockly/webif/static/blockly/core/bubble.js b/blockly/webif/static/blockly/core/bubble.js
                new file mode 100644
                index 000000000..1cd9443fd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/bubble.js
                @@ -0,0 +1,586 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a UI bubble.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Bubble');
                +
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.Workspace');
                +goog.require('goog.dom');
                +goog.require('goog.math');
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for UI bubble.
                + * @param {!Blockly.WorkspaceSvg} workspace The workspace on which to draw the
                + *     bubble.
                + * @param {!Element} content SVG content for the bubble.
                + * @param {Element} shape SVG element to avoid eclipsing.
                + * @param {!goog.math.Coodinate} anchorXY Absolute position of bubble's anchor
                + *     point.
                + * @param {?number} bubbleWidth Width of bubble, or null if not resizable.
                + * @param {?number} bubbleHeight Height of bubble, or null if not resizable.
                + * @constructor
                + */
                +Blockly.Bubble = function(workspace, content, shape, anchorXY,
                +                          bubbleWidth, bubbleHeight) {
                +  this.workspace_ = workspace;
                +  this.content_ = content;
                +  this.shape_ = shape;
                +
                +  var angle = Blockly.Bubble.ARROW_ANGLE;
                +  if (this.workspace_.RTL) {
                +    angle = -angle;
                +  }
                +  this.arrow_radians_ = goog.math.toRadians(angle);
                +
                +  var canvas = workspace.getBubbleCanvas();
                +  canvas.appendChild(this.createDom_(content, !!(bubbleWidth && bubbleHeight)));
                +
                +  this.setAnchorLocation(anchorXY);
                +  if (!bubbleWidth || !bubbleHeight) {
                +    var bBox = /** @type {SVGLocatable} */ (this.content_).getBBox();
                +    bubbleWidth = bBox.width + 2 * Blockly.Bubble.BORDER_WIDTH;
                +    bubbleHeight = bBox.height + 2 * Blockly.Bubble.BORDER_WIDTH;
                +  }
                +  this.setBubbleSize(bubbleWidth, bubbleHeight);
                +
                +  // Render the bubble.
                +  this.positionBubble_();
                +  this.renderArrow_();
                +  this.rendered_ = true;
                +
                +  if (!workspace.options.readOnly) {
                +    Blockly.bindEventWithChecks_(this.bubbleBack_, 'mousedown', this,
                +                       this.bubbleMouseDown_);
                +    if (this.resizeGroup_) {
                +      Blockly.bindEventWithChecks_(this.resizeGroup_, 'mousedown', this,
                +                         this.resizeMouseDown_);
                +    }
                +  }
                +};
                +
                +/**
                + * Width of the border around the bubble.
                + */
                +Blockly.Bubble.BORDER_WIDTH = 6;
                +
                +/**
                + * Determines the thickness of the base of the arrow in relation to the size
                + * of the bubble.  Higher numbers result in thinner arrows.
                + */
                +Blockly.Bubble.ARROW_THICKNESS = 5;
                +
                +/**
                + * The number of degrees that the arrow bends counter-clockwise.
                + */
                +Blockly.Bubble.ARROW_ANGLE = 20;
                +
                +/**
                + * The sharpness of the arrow's bend.  Higher numbers result in smoother arrows.
                + */
                +Blockly.Bubble.ARROW_BEND = 4;
                +
                +/**
                + * Distance between arrow point and anchor point.
                + */
                +Blockly.Bubble.ANCHOR_RADIUS = 8;
                +
                +/**
                + * Wrapper function called when a mouseUp occurs during a drag operation.
                + * @type {Array.<!Array>}
                + * @private
                + */
                +Blockly.Bubble.onMouseUpWrapper_ = null;
                +
                +/**
                + * Wrapper function called when a mouseMove occurs during a drag operation.
                + * @type {Array.<!Array>}
                + * @private
                + */
                +Blockly.Bubble.onMouseMoveWrapper_ = null;
                +
                +/**
                + * Function to call on resize of bubble.
                + * @type {Function}
                + */
                +Blockly.Bubble.prototype.resizeCallback_ = null;
                +
                +/**
                + * Stop binding to the global mouseup and mousemove events.
                + * @private
                + */
                +Blockly.Bubble.unbindDragEvents_ = function() {
                +  if (Blockly.Bubble.onMouseUpWrapper_) {
                +    Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_);
                +    Blockly.Bubble.onMouseUpWrapper_ = null;
                +  }
                +  if (Blockly.Bubble.onMouseMoveWrapper_) {
                +    Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_);
                +    Blockly.Bubble.onMouseMoveWrapper_ = null;
                +  }
                +};
                +
                +/*
                + * Handle a mouse-up event while dragging a bubble's border or resize handle.
                + * @param {!Event} e Mouse up event.
                + * @private
                + */
                +Blockly.Bubble.bubbleMouseUp_ = function(/*e*/) {
                +  Blockly.Touch.clearTouchIdentifier();
                +  Blockly.Bubble.unbindDragEvents_();
                +};
                +
                +/**
                + * Flag to stop incremental rendering during construction.
                + * @private
                + */
                +Blockly.Bubble.prototype.rendered_ = false;
                +
                +/**
                + * Absolute coordinate of anchor point.
                + * @type {goog.math.Coordinate}
                + * @private
                + */
                +Blockly.Bubble.prototype.anchorXY_ = null;
                +
                +/**
                + * Relative X coordinate of bubble with respect to the anchor's centre.
                + * In RTL mode the initial value is negated.
                + * @private
                + */
                +Blockly.Bubble.prototype.relativeLeft_ = 0;
                +
                +/**
                + * Relative Y coordinate of bubble with respect to the anchor's centre.
                + * @private
                + */
                +Blockly.Bubble.prototype.relativeTop_ = 0;
                +
                +/**
                + * Width of bubble.
                + * @private
                + */
                +Blockly.Bubble.prototype.width_ = 0;
                +
                +/**
                + * Height of bubble.
                + * @private
                + */
                +Blockly.Bubble.prototype.height_ = 0;
                +
                +/**
                + * Automatically position and reposition the bubble.
                + * @private
                + */
                +Blockly.Bubble.prototype.autoLayout_ = true;
                +
                +/**
                + * Create the bubble's DOM.
                + * @param {!Element} content SVG content for the bubble.
                + * @param {boolean} hasResize Add diagonal resize gripper if true.
                + * @return {!Element} The bubble's SVG group.
                + * @private
                + */
                +Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
                +  /* Create the bubble.  Here's the markup that will be generated:
                +  <g>
                +    <g filter="url(#blocklyEmbossFilter837493)">
                +      <path d="... Z" />
                +      <rect class="blocklyDraggable" rx="8" ry="8" width="180" height="180"/>
                +    </g>
                +    <g transform="translate(165, 165)" class="blocklyResizeSE">
                +      <polygon points="0,15 15,15 15,0"/>
                +      <line class="blocklyResizeLine" x1="5" y1="14" x2="14" y2="5"/>
                +      <line class="blocklyResizeLine" x1="10" y1="14" x2="14" y2="10"/>
                +    </g>
                +    [...content goes here...]
                +  </g>
                +  */
                +  this.bubbleGroup_ = Blockly.utils.createSvgElement('g', {}, null);
                +  var filter =
                +      {'filter': 'url(#' + this.workspace_.options.embossFilterId + ')'};
                +  if (goog.userAgent.getUserAgentString().indexOf('JavaFX') != -1) {
                +    // Multiple reports that JavaFX can't handle filters.  UserAgent:
                +    // Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44
                +    //     (KHTML, like Gecko) JavaFX/8.0 Safari/537.44
                +    // https://github.com/google/blockly/issues/99
                +    filter = {};
                +  }
                +  var bubbleEmboss = Blockly.utils.createSvgElement('g',
                +      filter, this.bubbleGroup_);
                +  this.bubbleArrow_ = Blockly.utils.createSvgElement('path', {}, bubbleEmboss);
                +  this.bubbleBack_ = Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyDraggable', 'x': 0, 'y': 0,
                +      'rx': Blockly.Bubble.BORDER_WIDTH, 'ry': Blockly.Bubble.BORDER_WIDTH},
                +      bubbleEmboss);
                +  if (hasResize) {
                +    this.resizeGroup_ = Blockly.utils.createSvgElement('g',
                +        {'class': this.workspace_.RTL ?
                +                  'blocklyResizeSW' : 'blocklyResizeSE'},
                +        this.bubbleGroup_);
                +    var resizeSize = 2 * Blockly.Bubble.BORDER_WIDTH;
                +    Blockly.utils.createSvgElement('polygon',
                +        {'points': '0,x x,x x,0'.replace(/x/g, resizeSize.toString())},
                +        this.resizeGroup_);
                +    Blockly.utils.createSvgElement('line',
                +        {'class': 'blocklyResizeLine',
                +        'x1': resizeSize / 3, 'y1': resizeSize - 1,
                +        'x2': resizeSize - 1, 'y2': resizeSize / 3}, this.resizeGroup_);
                +    Blockly.utils.createSvgElement('line',
                +        {'class': 'blocklyResizeLine',
                +        'x1': resizeSize * 2 / 3, 'y1': resizeSize - 1,
                +        'x2': resizeSize - 1, 'y2': resizeSize * 2 / 3}, this.resizeGroup_);
                +  } else {
                +    this.resizeGroup_ = null;
                +  }
                +  this.bubbleGroup_.appendChild(content);
                +  return this.bubbleGroup_;
                +};
                +
                +/**
                + * Handle a mouse-down on bubble's border.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Bubble.prototype.bubbleMouseDown_ = function(e) {
                +  this.promote_();
                +  Blockly.Bubble.unbindDragEvents_();
                +  if (Blockly.utils.isRightButton(e)) {
                +    // No right-click.
                +    e.stopPropagation();
                +    return;
                +  } else if (Blockly.utils.isTargetInput(e)) {
                +    // When focused on an HTML text input widget, don't trap any events.
                +    return;
                +  }
                +  // Left-click (or middle click)
                +  this.workspace_.startDrag(e, new goog.math.Coordinate(
                +      this.workspace_.RTL ? -this.relativeLeft_ : this.relativeLeft_,
                +      this.relativeTop_));
                +
                +  Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mouseup', this, Blockly.Bubble.bubbleMouseUp_);
                +  Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mousemove', this, this.bubbleMouseMove_);
                +  Blockly.hideChaff();
                +  // This event has been handled.  No need to bubble up to the document.
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Drag this bubble to follow the mouse.
                + * @param {!Event} e Mouse move event.
                + * @private
                + */
                +Blockly.Bubble.prototype.bubbleMouseMove_ = function(e) {
                +  this.autoLayout_ = false;
                +  var newXY = this.workspace_.moveDrag(e);
                +  this.relativeLeft_ = this.workspace_.RTL ? -newXY.x : newXY.x;
                +  this.relativeTop_ = newXY.y;
                +  this.positionBubble_();
                +  this.renderArrow_();
                +};
                +
                +/**
                + * Handle a mouse-down on bubble's resize corner.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Bubble.prototype.resizeMouseDown_ = function(e) {
                +  this.promote_();
                +  Blockly.Bubble.unbindDragEvents_();
                +  if (Blockly.utils.isRightButton(e)) {
                +    // No right-click.
                +    e.stopPropagation();
                +    return;
                +  }
                +  // Left-click (or middle click)
                +  this.workspace_.startDrag(e, new goog.math.Coordinate(
                +      this.workspace_.RTL ? -this.width_ : this.width_, this.height_));
                +
                +  Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mouseup', this, Blockly.Bubble.bubbleMouseUp_);
                +  Blockly.Bubble.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mousemove', this, this.resizeMouseMove_);
                +  Blockly.hideChaff();
                +  // This event has been handled.  No need to bubble up to the document.
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Resize this bubble to follow the mouse.
                + * @param {!Event} e Mouse move event.
                + * @private
                + */
                +Blockly.Bubble.prototype.resizeMouseMove_ = function(e) {
                +  this.autoLayout_ = false;
                +  var newXY = this.workspace_.moveDrag(e);
                +  this.setBubbleSize(this.workspace_.RTL ? -newXY.x : newXY.x, newXY.y);
                +  if (this.workspace_.RTL) {
                +    // RTL requires the bubble to move its left edge.
                +    this.positionBubble_();
                +  }
                +};
                +
                +/**
                + * Register a function as a callback event for when the bubble is resized.
                + * @param {!Function} callback The function to call on resize.
                + */
                +Blockly.Bubble.prototype.registerResizeEvent = function(callback) {
                +  this.resizeCallback_ = callback;
                +};
                +
                +/**
                + * Move this bubble to the top of the stack.
                + * @private
                + */
                +Blockly.Bubble.prototype.promote_ = function() {
                +  var svgGroup = this.bubbleGroup_.parentNode;
                +  svgGroup.appendChild(this.bubbleGroup_);
                +};
                +
                +/**
                + * Notification that the anchor has moved.
                + * Update the arrow and bubble accordingly.
                + * @param {!goog.math.Coordinate} xy Absolute location.
                + */
                +Blockly.Bubble.prototype.setAnchorLocation = function(xy) {
                +  this.anchorXY_ = xy;
                +  if (this.rendered_) {
                +    this.positionBubble_();
                +  }
                +};
                +
                +/**
                + * Position the bubble so that it does not fall off-screen.
                + * @private
                + */
                +Blockly.Bubble.prototype.layoutBubble_ = function() {
                +  // Compute the preferred bubble location.
                +  var relativeLeft = -this.width_ / 4;
                +  var relativeTop = -this.height_ - Blockly.BlockSvg.MIN_BLOCK_Y;
                +  // Prevent the bubble from being off-screen.
                +  var metrics = this.workspace_.getMetrics();
                +  metrics.viewWidth /= this.workspace_.scale;
                +  metrics.viewLeft /= this.workspace_.scale;
                +  var anchorX = this.anchorXY_.x;
                +  if (this.workspace_.RTL) {
                +    if (anchorX - metrics.viewLeft - relativeLeft - this.width_ <
                +        Blockly.Scrollbar.scrollbarThickness) {
                +      // Slide the bubble right until it is onscreen.
                +      relativeLeft = anchorX - metrics.viewLeft - this.width_ -
                +        Blockly.Scrollbar.scrollbarThickness;
                +    } else if (anchorX - metrics.viewLeft - relativeLeft >
                +               metrics.viewWidth) {
                +      // Slide the bubble left until it is onscreen.
                +      relativeLeft = anchorX - metrics.viewLeft - metrics.viewWidth;
                +    }
                +  } else {
                +    if (anchorX + relativeLeft < metrics.viewLeft) {
                +      // Slide the bubble right until it is onscreen.
                +      relativeLeft = metrics.viewLeft - anchorX;
                +    } else if (metrics.viewLeft + metrics.viewWidth <
                +        anchorX + relativeLeft + this.width_ +
                +        Blockly.BlockSvg.SEP_SPACE_X +
                +        Blockly.Scrollbar.scrollbarThickness) {
                +      // Slide the bubble left until it is onscreen.
                +      relativeLeft = metrics.viewLeft + metrics.viewWidth - anchorX -
                +          this.width_ - Blockly.Scrollbar.scrollbarThickness;
                +    }
                +  }
                +  if (this.anchorXY_.y + relativeTop < metrics.viewTop) {
                +    // Slide the bubble below the block.
                +    var bBox = /** @type {SVGLocatable} */ (this.shape_).getBBox();
                +    relativeTop = bBox.height;
                +  }
                +  this.relativeLeft_ = relativeLeft;
                +  this.relativeTop_ = relativeTop;
                +};
                +
                +/**
                + * Move the bubble to a location relative to the anchor's centre.
                + * @private
                + */
                +Blockly.Bubble.prototype.positionBubble_ = function() {
                +  var left = this.anchorXY_.x;
                +  if (this.workspace_.RTL) {
                +    left -= this.relativeLeft_ + this.width_;
                +  } else {
                +    left += this.relativeLeft_;
                +  }
                +  var top = this.relativeTop_ + this.anchorXY_.y;
                +  this.bubbleGroup_.setAttribute('transform',
                +      'translate(' + left + ',' + top + ')');
                +};
                +
                +/**
                + * Get the dimensions of this bubble.
                + * @return {!Object} Object with width and height properties.
                + */
                +Blockly.Bubble.prototype.getBubbleSize = function() {
                +  return {width: this.width_, height: this.height_};
                +};
                +
                +/**
                + * Size this bubble.
                + * @param {number} width Width of the bubble.
                + * @param {number} height Height of the bubble.
                + */
                +Blockly.Bubble.prototype.setBubbleSize = function(width, height) {
                +  var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH;
                +  // Minimum size of a bubble.
                +  width = Math.max(width, doubleBorderWidth + 45);
                +  height = Math.max(height, doubleBorderWidth + 20);
                +  this.width_ = width;
                +  this.height_ = height;
                +  this.bubbleBack_.setAttribute('width', width);
                +  this.bubbleBack_.setAttribute('height', height);
                +  if (this.resizeGroup_) {
                +    if (this.workspace_.RTL) {
                +      // Mirror the resize group.
                +      var resizeSize = 2 * Blockly.Bubble.BORDER_WIDTH;
                +      this.resizeGroup_.setAttribute('transform', 'translate(' +
                +          resizeSize + ',' + (height - doubleBorderWidth) + ') scale(-1 1)');
                +    } else {
                +      this.resizeGroup_.setAttribute('transform', 'translate(' +
                +          (width - doubleBorderWidth) + ',' +
                +          (height - doubleBorderWidth) + ')');
                +    }
                +  }
                +  if (this.rendered_) {
                +    if (this.autoLayout_) {
                +      this.layoutBubble_();
                +    }
                +    this.positionBubble_();
                +    this.renderArrow_();
                +  }
                +  // Allow the contents to resize.
                +  if (this.resizeCallback_) {
                +    this.resizeCallback_();
                +  }
                +};
                +
                +/**
                + * Draw the arrow between the bubble and the origin.
                + * @private
                + */
                +Blockly.Bubble.prototype.renderArrow_ = function() {
                +  var steps = [];
                +  // Find the relative coordinates of the center of the bubble.
                +  var relBubbleX = this.width_ / 2;
                +  var relBubbleY = this.height_ / 2;
                +  // Find the relative coordinates of the center of the anchor.
                +  var relAnchorX = -this.relativeLeft_;
                +  var relAnchorY = -this.relativeTop_;
                +  if (relBubbleX == relAnchorX && relBubbleY == relAnchorY) {
                +    // Null case.  Bubble is directly on top of the anchor.
                +    // Short circuit this rather than wade through divide by zeros.
                +    steps.push('M ' + relBubbleX + ',' + relBubbleY);
                +  } else {
                +    // Compute the angle of the arrow's line.
                +    var rise = relAnchorY - relBubbleY;
                +    var run = relAnchorX - relBubbleX;
                +    if (this.workspace_.RTL) {
                +      run *= -1;
                +    }
                +    var hypotenuse = Math.sqrt(rise * rise + run * run);
                +    var angle = Math.acos(run / hypotenuse);
                +    if (rise < 0) {
                +      angle = 2 * Math.PI - angle;
                +    }
                +    // Compute a line perpendicular to the arrow.
                +    var rightAngle = angle + Math.PI / 2;
                +    if (rightAngle > Math.PI * 2) {
                +      rightAngle -= Math.PI * 2;
                +    }
                +    var rightRise = Math.sin(rightAngle);
                +    var rightRun = Math.cos(rightAngle);
                +
                +    // Calculate the thickness of the base of the arrow.
                +    var bubbleSize = this.getBubbleSize();
                +    var thickness = (bubbleSize.width + bubbleSize.height) /
                +                    Blockly.Bubble.ARROW_THICKNESS;
                +    thickness = Math.min(thickness, bubbleSize.width, bubbleSize.height) / 4;
                +
                +    // Back the tip of the arrow off of the anchor.
                +    var backoffRatio = 1 - Blockly.Bubble.ANCHOR_RADIUS / hypotenuse;
                +    relAnchorX = relBubbleX + backoffRatio * run;
                +    relAnchorY = relBubbleY + backoffRatio * rise;
                +
                +    // Coordinates for the base of the arrow.
                +    var baseX1 = relBubbleX + thickness * rightRun;
                +    var baseY1 = relBubbleY + thickness * rightRise;
                +    var baseX2 = relBubbleX - thickness * rightRun;
                +    var baseY2 = relBubbleY - thickness * rightRise;
                +
                +    // Distortion to curve the arrow.
                +    var swirlAngle = angle + this.arrow_radians_;
                +    if (swirlAngle > Math.PI * 2) {
                +      swirlAngle -= Math.PI * 2;
                +    }
                +    var swirlRise = Math.sin(swirlAngle) *
                +        hypotenuse / Blockly.Bubble.ARROW_BEND;
                +    var swirlRun = Math.cos(swirlAngle) *
                +        hypotenuse / Blockly.Bubble.ARROW_BEND;
                +
                +    steps.push('M' + baseX1 + ',' + baseY1);
                +    steps.push('C' + (baseX1 + swirlRun) + ',' + (baseY1 + swirlRise) +
                +               ' ' + relAnchorX + ',' + relAnchorY +
                +               ' ' + relAnchorX + ',' + relAnchorY);
                +    steps.push('C' + relAnchorX + ',' + relAnchorY +
                +               ' ' + (baseX2 + swirlRun) + ',' + (baseY2 + swirlRise) +
                +               ' ' + baseX2 + ',' + baseY2);
                +  }
                +  steps.push('z');
                +  this.bubbleArrow_.setAttribute('d', steps.join(' '));
                +};
                +
                +/**
                + * Change the colour of a bubble.
                + * @param {string} hexColour Hex code of colour.
                + */
                +Blockly.Bubble.prototype.setColour = function(hexColour) {
                +  this.bubbleBack_.setAttribute('fill', hexColour);
                +  this.bubbleArrow_.setAttribute('fill', hexColour);
                +};
                +
                +/**
                + * Dispose of this bubble.
                + */
                +Blockly.Bubble.prototype.dispose = function() {
                +  Blockly.Bubble.unbindDragEvents_();
                +  // Dispose of and unlink the bubble.
                +  goog.dom.removeNode(this.bubbleGroup_);
                +  this.bubbleGroup_ = null;
                +  this.bubbleArrow_ = null;
                +  this.bubbleBack_ = null;
                +  this.resizeGroup_ = null;
                +  this.workspace_ = null;
                +  this.content_ = null;
                +  this.shape_ = null;
                +};
                diff --git a/blockly/webif/static/blockly/core/comment.js b/blockly/webif/static/blockly/core/comment.js
                new file mode 100644
                index 000000000..f0d5f3537
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/comment.js
                @@ -0,0 +1,278 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a code comment.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Comment');
                +
                +goog.require('Blockly.Bubble');
                +goog.require('Blockly.Icon');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a comment.
                + * @param {!Blockly.Block} block The block associated with this comment.
                + * @extends {Blockly.Icon}
                + * @constructor
                + */
                +Blockly.Comment = function(block) {
                +  Blockly.Comment.superClass_.constructor.call(this, block);
                +  this.createIcon();
                +};
                +goog.inherits(Blockly.Comment, Blockly.Icon);
                +
                +/**
                + * Comment text (if bubble is not visible).
                + * @private
                + */
                +Blockly.Comment.prototype.text_ = '';
                +
                +/**
                + * Width of bubble.
                + * @private
                + */
                +Blockly.Comment.prototype.width_ = 160;
                +
                +/**
                + * Height of bubble.
                + * @private
                + */
                +Blockly.Comment.prototype.height_ = 80;
                +
                +/**
                + * Draw the comment icon.
                + * @param {!Element} group The icon group.
                + * @private
                + */
                +Blockly.Comment.prototype.drawIcon_ = function(group) {
                +  // Circle.
                +  Blockly.utils.createSvgElement('circle',
                +      {'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
                +       group);
                +  // Can't use a real '?' text character since different browsers and operating
                +  // systems render it differently.
                +  // Body of question mark.
                +  Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyIconSymbol',
                +       'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405 0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25 -1.201,0.998 -1.201,1.528 -1.204,2.19z'},
                +       group);
                +  // Dot of question mark.
                +  Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyIconSymbol',
                +       'x': '6.8', 'y': '10.78', 'height': '2', 'width': '2'},
                +       group);
                +};
                +
                +/**
                + * Create the editor for the comment's bubble.
                + * @return {!Element} The top-level node of the editor.
                + * @private
                + */
                +Blockly.Comment.prototype.createEditor_ = function() {
                +  /* Create the editor.  Here's the markup that will be generated:
                +    <foreignObject x="8" y="8" width="164" height="164">
                +      <body xmlns="http://www.w3.org/1999/xhtml" class="blocklyMinimalBody">
                +        <textarea xmlns="http://www.w3.org/1999/xhtml"
                +            class="blocklyCommentTextarea"
                +            style="height: 164px; width: 164px;"></textarea>
                +      </body>
                +    </foreignObject>
                +  */
                +  this.foreignObject_ = Blockly.utils.createSvgElement('foreignObject',
                +      {'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH},
                +      null);
                +  var body = document.createElementNS(Blockly.HTML_NS, 'body');
                +  body.setAttribute('xmlns', Blockly.HTML_NS);
                +  body.className = 'blocklyMinimalBody';
                +  var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea');
                +  textarea.className = 'blocklyCommentTextarea';
                +  textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR');
                +  body.appendChild(textarea);
                +  this.textarea_ = textarea;
                +  this.foreignObject_.appendChild(body);
                +  Blockly.bindEventWithChecks_(textarea, 'mouseup', this, this.textareaFocus_);
                +  // Don't zoom with mousewheel.
                +  Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) {
                +    e.stopPropagation();
                +  });
                +  Blockly.bindEventWithChecks_(textarea, 'change', this, function(e) {
                +    if (this.text_ != textarea.value) {
                +      Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this.block_, 'comment', null, this.text_, textarea.value));
                +      this.text_ = textarea.value;
                +    }
                +  });
                +  setTimeout(function() {
                +    textarea.focus();
                +  }, 0);
                +  return this.foreignObject_;
                +};
                +
                +/**
                + * Add or remove editability of the comment.
                + * @override
                + */
                +Blockly.Comment.prototype.updateEditable = function() {
                +  if (this.isVisible()) {
                +    // Toggling visibility will force a rerendering.
                +    this.setVisible(false);
                +    this.setVisible(true);
                +  }
                +  // Allow the icon to update.
                +  Blockly.Icon.prototype.updateEditable.call(this);
                +};
                +
                +/**
                + * Callback function triggered when the bubble has resized.
                + * Resize the text area accordingly.
                + * @private
                + */
                +Blockly.Comment.prototype.resizeBubble_ = function() {
                +  if (this.isVisible()) {
                +    var size = this.bubble_.getBubbleSize();
                +    var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH;
                +    this.foreignObject_.setAttribute('width', size.width - doubleBorderWidth);
                +    this.foreignObject_.setAttribute('height', size.height - doubleBorderWidth);
                +    this.textarea_.style.width = (size.width - doubleBorderWidth - 4) + 'px';
                +    this.textarea_.style.height = (size.height - doubleBorderWidth - 4) + 'px';
                +  }
                +};
                +
                +/**
                + * Show or hide the comment bubble.
                + * @param {boolean} visible True if the bubble should be visible.
                + */
                +Blockly.Comment.prototype.setVisible = function(visible) {
                +  if (visible == this.isVisible()) {
                +    // No change.
                +    return;
                +  }
                +  Blockly.Events.fire(
                +      new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible));
                +  if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) {
                +    // Steal the code from warnings to make an uneditable text bubble.
                +    // MSIE does not support foreignobject; textareas are impossible.
                +    // http://msdn.microsoft.com/en-us/library/hh834675%28v=vs.85%29.aspx
                +    // Always treat comments in IE as uneditable.
                +    Blockly.Warning.prototype.setVisible.call(this, visible);
                +    return;
                +  }
                +  // Save the bubble stats before the visibility switch.
                +  var text = this.getText();
                +  var size = this.getBubbleSize();
                +  if (visible) {
                +    // Create the bubble.
                +    this.bubble_ = new Blockly.Bubble(
                +        /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace),
                +        this.createEditor_(), this.block_.svgPath_,
                +        this.iconXY_, this.width_, this.height_);
                +    this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this));
                +    this.updateColour();
                +  } else {
                +    // Dispose of the bubble.
                +    this.bubble_.dispose();
                +    this.bubble_ = null;
                +    this.textarea_ = null;
                +    this.foreignObject_ = null;
                +  }
                +  // Restore the bubble stats after the visibility switch.
                +  this.setText(text);
                +  this.setBubbleSize(size.width, size.height);
                +};
                +
                +/**
                + * Bring the comment to the top of the stack when clicked on.
                + * @param {!Event} e Mouse up event.
                + * @private
                + */
                +Blockly.Comment.prototype.textareaFocus_ = function(e) {
                +  // Ideally this would be hooked to the focus event for the comment.
                +  // However doing so in Firefox swallows the cursor for unknown reasons.
                +  // So this is hooked to mouseup instead.  No big deal.
                +  this.bubble_.promote_();
                +  // Since the act of moving this node within the DOM causes a loss of focus,
                +  // we need to reapply the focus.
                +  this.textarea_.focus();
                +};
                +
                +/**
                + * Get the dimensions of this comment's bubble.
                + * @return {!Object} Object with width and height properties.
                + */
                +Blockly.Comment.prototype.getBubbleSize = function() {
                +  if (this.isVisible()) {
                +    return this.bubble_.getBubbleSize();
                +  } else {
                +    return {width: this.width_, height: this.height_};
                +  }
                +};
                +
                +/**
                + * Size this comment's bubble.
                + * @param {number} width Width of the bubble.
                + * @param {number} height Height of the bubble.
                + */
                +Blockly.Comment.prototype.setBubbleSize = function(width, height) {
                +  if (this.textarea_) {
                +    this.bubble_.setBubbleSize(width, height);
                +  } else {
                +    this.width_ = width;
                +    this.height_ = height;
                +  }
                +};
                +
                +/**
                + * Returns this comment's text.
                + * @return {string} Comment text.
                + */
                +Blockly.Comment.prototype.getText = function() {
                +  return this.textarea_ ? this.textarea_.value : this.text_;
                +};
                +
                +/**
                + * Set this comment's text.
                + * @param {string} text Comment text.
                + */
                +Blockly.Comment.prototype.setText = function(text) {
                +  if (this.text_ != text) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +      this.block_, 'comment', null, this.text_, text));
                +    this.text_ = text;
                +  }
                +  if (this.textarea_) {
                +    this.textarea_.value = text;
                +  }
                +};
                +
                +/**
                + * Dispose of this comment.
                + */
                +Blockly.Comment.prototype.dispose = function() {
                +  if (Blockly.Events.isEnabled()) {
                +    this.setText('');  // Fire event to delete comment.
                +  }
                +  this.block_.comment = null;
                +  Blockly.Icon.prototype.dispose.call(this);
                +};
                diff --git a/blockly/webif/static/blockly/core/connection.js b/blockly/webif/static/blockly/core/connection.js
                new file mode 100644
                index 000000000..fc13cfaf0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/connection.js
                @@ -0,0 +1,663 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Components for creating connections between blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Connection');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.dom');
                +
                +
                +/**
                + * Class for a connection between blocks.
                + * @param {!Blockly.Block} source The block establishing this connection.
                + * @param {number} type The type of the connection.
                + * @constructor
                + */
                +Blockly.Connection = function(source, type) {
                +  /**
                +   * @type {!Blockly.Block}
                +   * @private
                +   */
                +  this.sourceBlock_ = source;
                +  /** @type {number} */
                +  this.type = type;
                +  // Shortcut for the databases for this connection's workspace.
                +  if (source.workspace.connectionDBList) {
                +    this.db_ = source.workspace.connectionDBList[type];
                +    this.dbOpposite_ =
                +        source.workspace.connectionDBList[Blockly.OPPOSITE_TYPE[type]];
                +    this.hidden_ = !this.db_;
                +  }
                +};
                +
                +/**
                + * Constants for checking whether two connections are compatible.
                + */
                +Blockly.Connection.CAN_CONNECT = 0;
                +Blockly.Connection.REASON_SELF_CONNECTION = 1;
                +Blockly.Connection.REASON_WRONG_TYPE = 2;
                +Blockly.Connection.REASON_TARGET_NULL = 3;
                +Blockly.Connection.REASON_CHECKS_FAILED = 4;
                +Blockly.Connection.REASON_DIFFERENT_WORKSPACES = 5;
                +Blockly.Connection.REASON_SHADOW_PARENT = 6;
                +
                +/**
                + * Connection this connection connects to.  Null if not connected.
                + * @type {Blockly.Connection}
                + */
                +Blockly.Connection.prototype.targetConnection = null;
                +
                +/**
                + * List of compatible value types.  Null if all types are compatible.
                + * @type {Array}
                + * @private
                + */
                +Blockly.Connection.prototype.check_ = null;
                +
                +/**
                + * DOM representation of a shadow block, or null if none.
                + * @type {Element}
                + * @private
                + */
                +Blockly.Connection.prototype.shadowDom_ = null;
                +
                +/**
                + * Horizontal location of this connection.
                + * @type {number}
                + * @private
                + */
                +Blockly.Connection.prototype.x_ = 0;
                +
                +/**
                + * Vertical location of this connection.
                + * @type {number}
                + * @private
                + */
                +Blockly.Connection.prototype.y_ = 0;
                +
                +/**
                + * Has this connection been added to the connection database?
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Connection.prototype.inDB_ = false;
                +
                +/**
                + * Connection database for connections of this type on the current workspace.
                + * @type {Blockly.ConnectionDB}
                + * @private
                + */
                +Blockly.Connection.prototype.db_ = null;
                +
                +/**
                + * Connection database for connections compatible with this type on the
                + * current workspace.
                + * @type {Blockly.ConnectionDB}
                + * @private
                + */
                +Blockly.Connection.prototype.dbOpposite_ = null;
                +
                +/**
                + * Whether this connections is hidden (not tracked in a database) or not.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Connection.prototype.hidden_ = null;
                +
                +/**
                + * Connect two connections together.  This is the connection on the superior
                + * block.
                + * @param {!Blockly.Connection} childConnection Connection on inferior block.
                + * @private
                + */
                +Blockly.Connection.prototype.connect_ = function(childConnection) {
                +  var parentConnection = this;
                +  var parentBlock = parentConnection.getSourceBlock();
                +  var childBlock = childConnection.getSourceBlock();
                +  // Disconnect any existing parent on the child connection.
                +  if (childConnection.isConnected()) {
                +    childConnection.disconnect();
                +  }
                +  if (parentConnection.isConnected()) {
                +    // Other connection is already connected to something.
                +    // Disconnect it and reattach it or bump it as needed.
                +    var orphanBlock = parentConnection.targetBlock();
                +    var shadowDom = parentConnection.getShadowDom();
                +    // Temporarily set the shadow DOM to null so it does not respawn.
                +    parentConnection.setShadowDom(null);
                +    // Displaced shadow blocks dissolve rather than reattaching or bumping.
                +    if (orphanBlock.isShadow()) {
                +      // Save the shadow block so that field values are preserved.
                +      shadowDom = Blockly.Xml.blockToDom(orphanBlock);
                +      orphanBlock.dispose();
                +      orphanBlock = null;
                +    } else if (parentConnection.type == Blockly.INPUT_VALUE) {
                +      // Value connections.
                +      // If female block is already connected, disconnect and bump the male.
                +      if (!orphanBlock.outputConnection) {
                +        throw 'Orphan block does not have an output connection.';
                +      }
                +      // Attempt to reattach the orphan at the end of the newly inserted
                +      // block.  Since this block may be a row, walk down to the end
                +      // or to the first (and only) shadow block.
                +      var connection = Blockly.Connection.lastConnectionInRow_(
                +          childBlock, orphanBlock);
                +      if (connection) {
                +        orphanBlock.outputConnection.connect(connection);
                +        orphanBlock = null;
                +      }
                +    } else if (parentConnection.type == Blockly.NEXT_STATEMENT) {
                +      // Statement connections.
                +      // Statement blocks may be inserted into the middle of a stack.
                +      // Split the stack.
                +      if (!orphanBlock.previousConnection) {
                +        throw 'Orphan block does not have a previous connection.';
                +      }
                +      // Attempt to reattach the orphan at the bottom of the newly inserted
                +      // block.  Since this block may be a stack, walk down to the end.
                +      var newBlock = childBlock;
                +      while (newBlock.nextConnection) {
                +        var nextBlock = newBlock.getNextBlock();
                +        if (nextBlock && !nextBlock.isShadow()) {
                +          newBlock = nextBlock;
                +        } else {
                +          if (orphanBlock.previousConnection.checkType_(
                +              newBlock.nextConnection)) {
                +            newBlock.nextConnection.connect(orphanBlock.previousConnection);
                +            orphanBlock = null;
                +          }
                +          break;
                +        }
                +      }
                +    }
                +    if (orphanBlock) {
                +      // Unable to reattach orphan.
                +      parentConnection.disconnect();
                +      if (Blockly.Events.recordUndo) {
                +        // Bump it off to the side after a moment.
                +        var group = Blockly.Events.getGroup();
                +        setTimeout(function() {
                +          // Verify orphan hasn't been deleted or reconnected (user on meth).
                +          if (orphanBlock.workspace && !orphanBlock.getParent()) {
                +            Blockly.Events.setGroup(group);
                +            if (orphanBlock.outputConnection) {
                +              orphanBlock.outputConnection.bumpAwayFrom_(parentConnection);
                +            } else if (orphanBlock.previousConnection) {
                +              orphanBlock.previousConnection.bumpAwayFrom_(parentConnection);
                +            }
                +            Blockly.Events.setGroup(false);
                +          }
                +        }, Blockly.BUMP_DELAY);
                +      }
                +    }
                +    // Restore the shadow DOM.
                +    parentConnection.setShadowDom(shadowDom);
                +  }
                +
                +  var event;
                +  if (Blockly.Events.isEnabled()) {
                +    event = new Blockly.Events.BlockMove(childBlock);
                +  }
                +  // Establish the connections.
                +  Blockly.Connection.connectReciprocally_(parentConnection, childConnection);
                +  // Demote the inferior block so that one is a child of the superior one.
                +  childBlock.setParent(parentBlock);
                +  if (event) {
                +    event.recordNew();
                +    Blockly.Events.fire(event);
                +  }
                +};
                +
                +/**
                + * Sever all links to this connection (not including from the source object).
                + */
                +Blockly.Connection.prototype.dispose = function() {
                +  if (this.isConnected()) {
                +    throw 'Disconnect connection before disposing of it.';
                +  }
                +  if (this.inDB_) {
                +    this.db_.removeConnection_(this);
                +  }
                +  this.db_ = null;
                +  this.dbOpposite_ = null;
                +};
                +
                +/**
                + * Get the source block for this connection.
                + * @return {Blockly.Block} The source block, or null if there is none.
                + */
                +Blockly.Connection.prototype.getSourceBlock = function() {
                +  return this.sourceBlock_;
                +};
                +
                +/**
                + * Does the connection belong to a superior block (higher in the source stack)?
                + * @return {boolean} True if connection faces down or right.
                + */
                +Blockly.Connection.prototype.isSuperior = function() {
                +  return this.type == Blockly.INPUT_VALUE ||
                +      this.type == Blockly.NEXT_STATEMENT;
                +};
                +
                +/**
                + * Is the connection connected?
                + * @return {boolean} True if connection is connected to another connection.
                + */
                +Blockly.Connection.prototype.isConnected = function() {
                +  return !!this.targetConnection;
                +};
                +
                +/**
                + * Checks whether the current connection can connect with the target
                + * connection.
                + * @param {Blockly.Connection} target Connection to check compatibility with.
                + * @return {number} Blockly.Connection.CAN_CONNECT if the connection is legal,
                + *    an error code otherwise.
                + * @private
                + */
                +Blockly.Connection.prototype.canConnectWithReason_ = function(target) {
                +  if (!target) {
                +    return Blockly.Connection.REASON_TARGET_NULL;
                +  }
                +  if (this.isSuperior()) {
                +    var blockA = this.sourceBlock_;
                +    var blockB = target.getSourceBlock();
                +  } else {
                +    var blockB = this.sourceBlock_;
                +    var blockA = target.getSourceBlock();
                +  }
                +  if (blockA && blockA == blockB) {
                +    return Blockly.Connection.REASON_SELF_CONNECTION;
                +  } else if (target.type != Blockly.OPPOSITE_TYPE[this.type]) {
                +    return Blockly.Connection.REASON_WRONG_TYPE;
                +  } else if (blockA && blockB && blockA.workspace !== blockB.workspace) {
                +    return Blockly.Connection.REASON_DIFFERENT_WORKSPACES;
                +  } else if (!this.checkType_(target)) {
                +    return Blockly.Connection.REASON_CHECKS_FAILED;
                +  } else if (blockA.isShadow() && !blockB.isShadow()) {
                +    return Blockly.Connection.REASON_SHADOW_PARENT;
                +  }
                +  return Blockly.Connection.CAN_CONNECT;
                +};
                +
                +/**
                + * Checks whether the current connection and target connection are compatible
                + * and throws an exception if they are not.
                + * @param {Blockly.Connection} target The connection to check compatibility
                + *    with.
                + * @private
                + */
                +Blockly.Connection.prototype.checkConnection_ = function(target) {
                +  switch (this.canConnectWithReason_(target)) {
                +    case Blockly.Connection.CAN_CONNECT:
                +      break;
                +    case Blockly.Connection.REASON_SELF_CONNECTION:
                +      throw 'Attempted to connect a block to itself.';
                +    case Blockly.Connection.REASON_DIFFERENT_WORKSPACES:
                +      // Usually this means one block has been deleted.
                +      throw 'Blocks not on same workspace.';
                +    case Blockly.Connection.REASON_WRONG_TYPE:
                +      throw 'Attempt to connect incompatible types.';
                +    case Blockly.Connection.REASON_TARGET_NULL:
                +      throw 'Target connection is null.';
                +    case Blockly.Connection.REASON_CHECKS_FAILED:
                +      var msg = 'Connection checks failed. ';
                +      msg += this + ' expected '  + this.check_ + ', found ' + target.check_;
                +      throw msg;
                +    case Blockly.Connection.REASON_SHADOW_PARENT:
                +      throw 'Connecting non-shadow to shadow block.';
                +    default:
                +      throw 'Unknown connection failure: this should never happen!';
                +  }
                +};
                +
                +/**
                + * Check if the two connections can be dragged to connect to each other.
                + * @param {!Blockly.Connection} candidate A nearby connection to check.
                + * @return {boolean} True if the connection is allowed, false otherwise.
                + */
                +Blockly.Connection.prototype.isConnectionAllowed = function(candidate) {
                +  // Type checking.
                +  var canConnect = this.canConnectWithReason_(candidate);
                +  if (canConnect != Blockly.Connection.CAN_CONNECT) {
                +    return false;
                +  }
                +
                +  // Don't offer to connect an already connected left (male) value plug to
                +  // an available right (female) value plug.  Don't offer to connect the
                +  // bottom of a statement block to one that's already connected.
                +  if (candidate.type == Blockly.OUTPUT_VALUE ||
                +      candidate.type == Blockly.PREVIOUS_STATEMENT) {
                +    if (candidate.isConnected() || this.isConnected()) {
                +      return false;
                +    }
                +  }
                +
                +  // Offering to connect the left (male) of a value block to an already
                +  // connected value pair is ok, we'll splice it in.
                +  // However, don't offer to splice into an immovable block.
                +  if (candidate.type == Blockly.INPUT_VALUE && candidate.isConnected() &&
                +      !candidate.targetBlock().isMovable() &&
                +      !candidate.targetBlock().isShadow()) {
                +    return false;
                +  }
                +
                +  // Don't let a block with no next connection bump other blocks out of the
                +  // stack.  But covering up a shadow block or stack of shadow blocks is fine.
                +  // Similarly, replacing a terminal statement with another terminal statement
                +  // is allowed.
                +  if (this.type == Blockly.PREVIOUS_STATEMENT &&
                +      candidate.isConnected() &&
                +      !this.sourceBlock_.nextConnection &&
                +      !candidate.targetBlock().isShadow() &&
                +      candidate.targetBlock().nextConnection) {
                +    return false;
                +  }
                +
                +  // Don't let blocks try to connect to themselves or ones they nest.
                +  if (Blockly.draggingConnections_.indexOf(candidate) != -1) {
                +    return false;
                +  }
                +
                +  return true;
                +};
                +
                +/**
                + * Connect this connection to another connection.
                + * @param {!Blockly.Connection} otherConnection Connection to connect to.
                + */
                +Blockly.Connection.prototype.connect = function(otherConnection) {
                +  if (this.targetConnection == otherConnection) {
                +    // Already connected together.  NOP.
                +    return;
                +  }
                +  this.checkConnection_(otherConnection);
                +  // Determine which block is superior (higher in the source stack).
                +  if (this.isSuperior()) {
                +    // Superior block.
                +    this.connect_(otherConnection);
                +  } else {
                +    // Inferior block.
                +    otherConnection.connect_(this);
                +  }
                +};
                +
                +/**
                + * Update two connections to target each other.
                + * @param {Blockly.Connection} first The first connection to update.
                + * @param {Blockly.Connection} second The second connection to update.
                + * @private
                + */
                +Blockly.Connection.connectReciprocally_ = function(first, second) {
                +  goog.asserts.assert(first && second, 'Cannot connect null connections.');
                +  first.targetConnection = second;
                +  second.targetConnection = first;
                +};
                +
                +/**
                + * Does the given block have one and only one connection point that will accept
                + * an orphaned block?
                + * @param {!Blockly.Block} block The superior block.
                + * @param {!Blockly.Block} orphanBlock The inferior block.
                + * @return {Blockly.Connection} The suitable connection point on 'block',
                + *     or null.
                + * @private
                + */
                +Blockly.Connection.singleConnection_ = function(block, orphanBlock) {
                +  var connection = false;
                +  for (var i = 0; i < block.inputList.length; i++) {
                +    var thisConnection = block.inputList[i].connection;
                +    if (thisConnection && thisConnection.type == Blockly.INPUT_VALUE &&
                +        orphanBlock.outputConnection.checkType_(thisConnection)) {
                +      if (connection) {
                +        return null;  // More than one connection.
                +      }
                +      connection = thisConnection;
                +    }
                +  }
                +  return connection;
                +};
                +
                +/**
                + * Walks down a row a blocks, at each stage checking if there are any
                + * connections that will accept the orphaned block.  If at any point there
                + * are zero or multiple eligible connections, returns null.  Otherwise
                + * returns the only input on the last block in the chain.
                + * Terminates early for shadow blocks.
                + * @param {!Blockly.Block} startBlock The block on which to start the search.
                + * @param {!Blockly.Block} orphanBlock The block that is looking for a home.
                + * @return {Blockly.Connection} The suitable connection point on the chain
                + *    of blocks, or null.
                + * @private
                + */
                +Blockly.Connection.lastConnectionInRow_ = function(startBlock, orphanBlock) {
                +  var newBlock = startBlock;
                +  var connection;
                +  while (connection = Blockly.Connection.singleConnection_(
                +      /** @type {!Blockly.Block} */ (newBlock), orphanBlock)) {
                +    // '=' is intentional in line above.
                +    newBlock = connection.targetBlock();
                +    if (!newBlock || newBlock.isShadow()) {
                +      return connection;
                +    }
                +  }
                +  return null;
                +};
                +
                +/**
                + * Disconnect this connection.
                + */
                +Blockly.Connection.prototype.disconnect = function() {
                +  var otherConnection = this.targetConnection;
                +  goog.asserts.assert(otherConnection, 'Source connection not connected.');
                +  goog.asserts.assert(otherConnection.targetConnection == this,
                +      'Target connection not connected to source connection.');
                +
                +  var parentBlock, childBlock, parentConnection;
                +  if (this.isSuperior()) {
                +    // Superior block.
                +    parentBlock = this.sourceBlock_;
                +    childBlock = otherConnection.getSourceBlock();
                +    parentConnection = this;
                +  } else {
                +    // Inferior block.
                +    parentBlock = otherConnection.getSourceBlock();
                +    childBlock = this.sourceBlock_;
                +    parentConnection = otherConnection;
                +  }
                +  this.disconnectInternal_(parentBlock, childBlock);
                +  parentConnection.respawnShadow_();
                +};
                +
                +/**
                + * Disconnect two blocks that are connected by this connection.
                + * @param {!Blockly.Block} parentBlock The superior block.
                + * @param {!Blockly.Block} childBlock The inferior block.
                + * @private
                + */
                +Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
                +    childBlock) {
                +  var event;
                +  if (Blockly.Events.isEnabled()) {
                +    event = new Blockly.Events.BlockMove(childBlock);
                +  }
                +  var otherConnection = this.targetConnection;
                +  otherConnection.targetConnection = null;
                +  this.targetConnection = null;
                +  childBlock.setParent(null);
                +  if (event) {
                +    event.recordNew();
                +    Blockly.Events.fire(event);
                +  }
                +};
                +
                +/**
                + * Respawn the shadow block if there was one connected to the this connection.
                + * @private
                + */
                +Blockly.Connection.prototype.respawnShadow_ = function() {
                +  var parentBlock = this.getSourceBlock();
                +  var shadow = this.getShadowDom();
                +  if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) {
                +    var blockShadow =
                +        Blockly.Xml.domToBlock(shadow, parentBlock.workspace);
                +    if (blockShadow.outputConnection) {
                +      this.connect(blockShadow.outputConnection);
                +    } else if (blockShadow.previousConnection) {
                +      this.connect(blockShadow.previousConnection);
                +    } else {
                +      throw 'Child block does not have output or previous statement.';
                +    }
                +  }
                +};
                +
                +/**
                + * Returns the block that this connection connects to.
                + * @return {Blockly.Block} The connected block or null if none is connected.
                + */
                +Blockly.Connection.prototype.targetBlock = function() {
                +  if (this.isConnected()) {
                +    return this.targetConnection.getSourceBlock();
                +  }
                +  return null;
                +};
                +
                +/**
                + * Is this connection compatible with another connection with respect to the
                + * value type system.  E.g. square_root("Hello") is not compatible.
                + * @param {!Blockly.Connection} otherConnection Connection to compare against.
                + * @return {boolean} True if the connections share a type.
                + * @private
                + */
                +Blockly.Connection.prototype.checkType_ = function(otherConnection) {
                +  if (!this.check_ || !otherConnection.check_) {
                +    // One or both sides are promiscuous enough that anything will fit.
                +    return true;
                +  }
                +  // Find any intersection in the check lists.
                +  for (var i = 0; i < this.check_.length; i++) {
                +    if (otherConnection.check_.indexOf(this.check_[i]) != -1) {
                +      return true;
                +    }
                +  }
                +  // No intersection.
                +  return false;
                +};
                +
                +/**
                + * Function to be called when this connection's compatible types have changed.
                + * @private
                + */
                +Blockly.Connection.prototype.onCheckChanged_ = function() {
                +  // The new value type may not be compatible with the existing connection.
                +  if (this.isConnected() && !this.checkType_(this.targetConnection)) {
                +    var child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_;
                +    child.unplug();
                +  }
                +};
                +
                +/**
                + * Change a connection's compatibility.
                + * @param {*} check Compatible value type or list of value types.
                + *     Null if all types are compatible.
                + * @return {!Blockly.Connection} The connection being modified
                + *     (to allow chaining).
                + */
                +Blockly.Connection.prototype.setCheck = function(check) {
                +  if (check) {
                +    // Ensure that check is in an array.
                +    if (!goog.isArray(check)) {
                +      check = [check];
                +    }
                +    this.check_ = check;
                +    this.onCheckChanged_();
                +  } else {
                +    this.check_ = null;
                +  }
                +  return this;
                +};
                +
                +/**
                + * Change a connection's shadow block.
                + * @param {Element} shadow DOM representation of a block or null.
                + */
                +Blockly.Connection.prototype.setShadowDom = function(shadow) {
                +  this.shadowDom_ = shadow;
                +};
                +
                +/**
                + * Return a connection's shadow block.
                + * @return {Element} shadow DOM representation of a block or null.
                + */
                +Blockly.Connection.prototype.getShadowDom = function() {
                +  return this.shadowDom_;
                +};
                +
                +/**
                + * Find all nearby compatible connections to this connection.
                + * Type checking does not apply, since this function is used for bumping.
                + *
                + * Headless configurations (the default) do not have neighboring connection,
                + * and always return an empty list (the default).
                + * {@link Blockly.RenderedConnection} overrides this behavior with a list
                + * computed from the rendered positioning.
                + * @param {number} maxLimit The maximum radius to another connection.
                + * @return {!Array.<!Blockly.Connection>} List of connections.
                + * @private
                + */
                +Blockly.Connection.prototype.neighbours_ = function(/* maxLimit */) {
                +  return [];
                +};
                +
                +/**
                + * This method returns a string describing this Connection in developer terms
                + * (English only). Intended to on be used in console logs and errors.
                + * @return {string} The description.
                + */
                +Blockly.Connection.prototype.toString = function() {
                +  var msg;
                +  var block = this.sourceBlock_;
                +  if (!block) {
                +    return 'Orphan Connection';
                +  } else if (block.outputConnection == this) {
                +    msg = 'Output Connection of ';
                +  } else if (block.previousConnection == this) {
                +    msg = 'Previous Connection of ';
                +  } else if (block.nextConnection == this) {
                +    msg = 'Next Connection of ';
                +  } else {
                +    var parentInput = goog.array.find(block.inputList, function(input) {
                +      return input.connection == this;
                +    }, this);
                +    if (parentInput) {
                +      msg = 'Input "' + parentInput.name + '" connection on ';
                +    } else {
                +      console.warn('Connection not actually connected to sourceBlock_');
                +      return 'Orphan Connection';
                +    }
                +  }
                +  return msg + block.toDevString();
                +};
                diff --git a/blockly/webif/static/blockly/core/connection_db.js b/blockly/webif/static/blockly/core/connection_db.js
                new file mode 100644
                index 000000000..8b3c3008e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/connection_db.js
                @@ -0,0 +1,301 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Components for managing connections between blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.ConnectionDB');
                +
                +goog.require('Blockly.Connection');
                +
                +
                +/**
                + * Database of connections.
                + * Connections are stored in order of their vertical component.  This way
                + * connections in an area may be looked up quickly using a binary search.
                + * @constructor
                + */
                +Blockly.ConnectionDB = function() {
                +};
                +
                +Blockly.ConnectionDB.prototype = new Array();
                +/**
                + * Don't inherit the constructor from Array.
                + * @type {!Function}
                + */
                +Blockly.ConnectionDB.constructor = Blockly.ConnectionDB;
                +
                +/**
                + * Add a connection to the database.  Must not already exist in DB.
                + * @param {!Blockly.Connection} connection The connection to be added.
                + */
                +Blockly.ConnectionDB.prototype.addConnection = function(connection) {
                +  if (connection.inDB_) {
                +    throw 'Connection already in database.';
                +  }
                +  if (connection.getSourceBlock().isInFlyout) {
                +    // Don't bother maintaining a database of connections in a flyout.
                +    return;
                +  }
                +  var position = this.findPositionForConnection_(connection);
                +  this.splice(position, 0, connection);
                +  connection.inDB_ = true;
                +};
                +
                +/**
                + * Find the given connection.
                + * Starts by doing a binary search to find the approximate location, then
                + *     linearly searches nearby for the exact connection.
                + * @param {!Blockly.Connection} conn The connection to find.
                + * @return {number} The index of the connection, or -1 if the connection was
                + *     not found.
                + */
                +Blockly.ConnectionDB.prototype.findConnection = function(conn) {
                +  if (!this.length) {
                +    return -1;
                +  }
                +
                +  var bestGuess = this.findPositionForConnection_(conn);
                +  if (bestGuess >= this.length) {
                +    // Not in list
                +    return -1;
                +  }
                +
                +  var yPos = conn.y_;
                +  // Walk forward and back on the y axis looking for the connection.
                +  var pointerMin = bestGuess;
                +  var pointerMax = bestGuess;
                +  while (pointerMin >= 0 && this[pointerMin].y_ == yPos) {
                +    if (this[pointerMin] == conn) {
                +      return pointerMin;
                +    }
                +    pointerMin--;
                +  }
                +
                +  while (pointerMax < this.length && this[pointerMax].y_ == yPos) {
                +    if (this[pointerMax] == conn) {
                +      return pointerMax;
                +    }
                +    pointerMax++;
                +  }
                +  return -1;
                +};
                +
                +/**
                + * Finds a candidate position for inserting this connection into the list.
                + * This will be in the correct y order but makes no guarantees about ordering in
                + *     the x axis.
                + * @param {!Blockly.Connection} connection The connection to insert.
                + * @return {number} The candidate index.
                + * @private
                + */
                +Blockly.ConnectionDB.prototype.findPositionForConnection_ =
                +    function(connection) {
                +  /* eslint-disable indent */
                +  if (!this.length) {
                +    return 0;
                +  }
                +  var pointerMin = 0;
                +  var pointerMax = this.length;
                +  while (pointerMin < pointerMax) {
                +    var pointerMid = Math.floor((pointerMin + pointerMax) / 2);
                +    if (this[pointerMid].y_ < connection.y_) {
                +      pointerMin = pointerMid + 1;
                +    } else if (this[pointerMid].y_ > connection.y_) {
                +      pointerMax = pointerMid;
                +    } else {
                +      pointerMin = pointerMid;
                +      break;
                +    }
                +  }
                +  return pointerMin;
                +};  /* eslint-enable indent */
                +
                +/**
                + * Remove a connection from the database.  Must already exist in DB.
                + * @param {!Blockly.Connection} connection The connection to be removed.
                + * @private
                + */
                +Blockly.ConnectionDB.prototype.removeConnection_ = function(connection) {
                +  if (!connection.inDB_) {
                +    throw 'Connection not in database.';
                +  }
                +  var removalIndex = this.findConnection(connection);
                +  if (removalIndex == -1) {
                +    throw 'Unable to find connection in connectionDB.';
                +  }
                +  connection.inDB_ = false;
                +  this.splice(removalIndex, 1);
                +};
                +
                +/**
                + * Find all nearby connections to the given connection.
                + * Type checking does not apply, since this function is used for bumping.
                + * @param {!Blockly.Connection} connection The connection whose neighbours
                + *     should be returned.
                + * @param {number} maxRadius The maximum radius to another connection.
                + * @return {!Array.<Blockly.Connection>} List of connections.
                + */
                +Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) {
                +  var db = this;
                +  var currentX = connection.x_;
                +  var currentY = connection.y_;
                +
                +  // Binary search to find the closest y location.
                +  var pointerMin = 0;
                +  var pointerMax = db.length - 2;
                +  var pointerMid = pointerMax;
                +  while (pointerMin < pointerMid) {
                +    if (db[pointerMid].y_ < currentY) {
                +      pointerMin = pointerMid;
                +    } else {
                +      pointerMax = pointerMid;
                +    }
                +    pointerMid = Math.floor((pointerMin + pointerMax) / 2);
                +  }
                +
                +  var neighbours = [];
                +  /**
                +   * Computes if the current connection is within the allowed radius of another
                +   * connection.
                +   * This function is a closure and has access to outside variables.
                +   * @param {number} yIndex The other connection's index in the database.
                +   * @return {boolean} True if the current connection's vertical distance from
                +   *     the other connection is less than the allowed radius.
                +   */
                +  function checkConnection_(yIndex) {
                +    var dx = currentX - db[yIndex].x_;
                +    var dy = currentY - db[yIndex].y_;
                +    var r = Math.sqrt(dx * dx + dy * dy);
                +    if (r <= maxRadius) {
                +      neighbours.push(db[yIndex]);
                +    }
                +    return dy < maxRadius;
                +  }
                +
                +  // Walk forward and back on the y axis looking for the closest x,y point.
                +  pointerMin = pointerMid;
                +  pointerMax = pointerMid;
                +  if (db.length) {
                +    while (pointerMin >= 0 && checkConnection_(pointerMin)) {
                +      pointerMin--;
                +    }
                +    do {
                +      pointerMax++;
                +    } while (pointerMax < db.length && checkConnection_(pointerMax));
                +  }
                +
                +  return neighbours;
                +};
                +
                +
                +/**
                + * Is the candidate connection close to the reference connection.
                + * Extremely fast; only looks at Y distance.
                + * @param {number} index Index in database of candidate connection.
                + * @param {number} baseY Reference connection's Y value.
                + * @param {number} maxRadius The maximum radius to another connection.
                + * @return {boolean} True if connection is in range.
                + * @private
                + */
                +Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) {
                +  return (Math.abs(this[index].y_ - baseY) <= maxRadius);
                +};
                +
                +/**
                + * Find the closest compatible connection to this connection.
                + * @param {!Blockly.Connection} conn The connection searching for a compatible
                + *     mate.
                + * @param {number} maxRadius The maximum radius to another connection.
                + * @param {!goog.math.Coordinate} dxy Offset between this connection's location
                + *     in the database and the current location (as a result of dragging).
                + * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two
                + *     properties:' connection' which is either another connection or null,
                + *     and 'radius' which is the distance.
                + */
                +Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
                +    dxy) {
                +  // Don't bother.
                +  if (!this.length) {
                +    return {connection: null, radius: maxRadius};
                +  }
                +
                +  // Stash the values of x and y from before the drag.
                +  var baseY = conn.y_;
                +  var baseX = conn.x_;
                +
                +  conn.x_ = baseX + dxy.x;
                +  conn.y_ = baseY + dxy.y;
                +
                +  // findPositionForConnection finds an index for insertion, which is always
                +  // after any block with the same y index.  We want to search both forward
                +  // and back, so search on both sides of the index.
                +  var closestIndex = this.findPositionForConnection_(conn);
                +
                +  var bestConnection = null;
                +  var bestRadius = maxRadius;
                +  var temp;
                +
                +  // Walk forward and back on the y axis looking for the closest x,y point.
                +  var pointerMin = closestIndex - 1;
                +  while (pointerMin >= 0 && this.isInYRange_(pointerMin, conn.y_, maxRadius)) {
                +    temp = this[pointerMin];
                +    if (conn.isConnectionAllowed(temp, bestRadius)) {
                +      bestConnection = temp;
                +      bestRadius = temp.distanceFrom(conn);
                +    }
                +    pointerMin--;
                +  }
                +
                +  var pointerMax = closestIndex;
                +  while (pointerMax < this.length && this.isInYRange_(pointerMax, conn.y_,
                +      maxRadius)) {
                +    temp = this[pointerMax];
                +    if (conn.isConnectionAllowed(temp, bestRadius)) {
                +      bestConnection = temp;
                +      bestRadius = temp.distanceFrom(conn);
                +    }
                +    pointerMax++;
                +  }
                +
                +  // Reset the values of x and y.
                +  conn.x_ = baseX;
                +  conn.y_ = baseY;
                +
                +  // If there were no valid connections, bestConnection will be null.
                +  return {connection: bestConnection, radius: bestRadius};
                +};
                +
                +/**
                + * Initialize a set of connection DBs for a specified workspace.
                + * @param {!Blockly.Workspace} workspace The workspace this DB is for.
                + */
                +Blockly.ConnectionDB.init = function(workspace) {
                +  // Create four databases, one for each connection type.
                +  var dbList = [];
                +  dbList[Blockly.INPUT_VALUE] = new Blockly.ConnectionDB();
                +  dbList[Blockly.OUTPUT_VALUE] = new Blockly.ConnectionDB();
                +  dbList[Blockly.NEXT_STATEMENT] = new Blockly.ConnectionDB();
                +  dbList[Blockly.PREVIOUS_STATEMENT] = new Blockly.ConnectionDB();
                +  workspace.connectionDBList = dbList;
                +};
                diff --git a/blockly/webif/static/blockly/core/constants.js b/blockly/webif/static/blockly/core/constants.js
                new file mode 100644
                index 000000000..f5428ff74
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/constants.js
                @@ -0,0 +1,267 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Blockly constants.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.constants');
                +
                +
                +/**
                + * Number of pixels the mouse must move before a drag starts.
                + */
                +Blockly.DRAG_RADIUS = 5;
                +
                +/**
                + * Number of pixels the mouse must move before a drag/scroll starts from the
                + * flyout.  Because the drag-intention is determined when this is reached, it is
                + * larger than Blockly.DRAG_RADIUS so that the drag-direction is clearer.
                + */
                +Blockly.FLYOUT_DRAG_RADIUS = 10;
                +
                +/**
                + * Maximum misalignment between connections for them to snap together.
                + */
                +Blockly.SNAP_RADIUS = 20;
                +
                +/**
                + * Delay in ms between trigger and bumping unconnected block out of alignment.
                + */
                +Blockly.BUMP_DELAY = 250;
                +
                +/**
                + * Number of characters to truncate a collapsed block to.
                + */
                +Blockly.COLLAPSE_CHARS = 30;
                +
                +/**
                + * Length in ms for a touch to become a long press.
                + */
                +Blockly.LONGPRESS = 750;
                +
                +/**
                + * Prevent a sound from playing if another sound preceded it within this many
                + * milliseconds.
                + */
                +Blockly.SOUND_LIMIT = 100;
                +
                +/**
                + * When dragging a block out of a stack, split the stack in two (true), or drag
                + * out the block healing the stack (false).
                + */
                +Blockly.DRAG_STACK = true;
                +
                +/**
                + * The richness of block colours, regardless of the hue.
                + * Must be in the range of 0 (inclusive) to 1 (exclusive).
                + */
                +Blockly.HSV_SATURATION = 0.45;
                +
                +/**
                + * The intensity of block colours, regardless of the hue.
                + * Must be in the range of 0 (inclusive) to 1 (exclusive).
                + */
                +Blockly.HSV_VALUE = 0.65;
                +
                +/**
                + * Sprited icons and images.
                + */
                +Blockly.SPRITE = {
                +  width: 96,
                +  height: 124,
                +  url: 'sprites.png'
                +};
                +
                +// Constants below this point are not intended to be changed.
                +
                +/**
                + * Required name space for SVG elements.
                + * @const
                + */
                +Blockly.SVG_NS = 'http://www.w3.org/2000/svg';
                +
                +/**
                + * Required name space for HTML elements.
                + * @const
                + */
                +Blockly.HTML_NS = 'http://www.w3.org/1999/xhtml';
                +
                +/**
                + * ENUM for a right-facing value input.  E.g. 'set item to' or 'return'.
                + * @const
                + */
                +Blockly.INPUT_VALUE = 1;
                +
                +/**
                + * ENUM for a left-facing value output.  E.g. 'random fraction'.
                + * @const
                + */
                +Blockly.OUTPUT_VALUE = 2;
                +
                +/**
                + * ENUM for a down-facing block stack.  E.g. 'if-do' or 'else'.
                + * @const
                + */
                +Blockly.NEXT_STATEMENT = 3;
                +
                +/**
                + * ENUM for an up-facing block stack.  E.g. 'break out of loop'.
                + * @const
                + */
                +Blockly.PREVIOUS_STATEMENT = 4;
                +
                +/**
                + * ENUM for an dummy input.  Used to add field(s) with no input.
                + * @const
                + */
                +Blockly.DUMMY_INPUT = 5;
                +
                +/**
                + * ENUM for left alignment.
                + * @const
                + */
                +Blockly.ALIGN_LEFT = -1;
                +
                +/**
                + * ENUM for centre alignment.
                + * @const
                + */
                +Blockly.ALIGN_CENTRE = 0;
                +
                +/**
                + * ENUM for right alignment.
                + * @const
                + */
                +Blockly.ALIGN_RIGHT = 1;
                +
                +/**
                + * ENUM for no drag operation.
                + * @const
                + */
                +Blockly.DRAG_NONE = 0;
                +
                +/**
                + * ENUM for inside the sticky DRAG_RADIUS.
                + * @const
                + */
                +Blockly.DRAG_STICKY = 1;
                +
                +/**
                + * ENUM for inside the non-sticky DRAG_RADIUS, for differentiating between
                + * clicks and drags.
                + * @const
                + */
                +Blockly.DRAG_BEGIN = 1;
                +
                +/**
                + * ENUM for freely draggable (outside the DRAG_RADIUS, if one applies).
                + * @const
                + */
                +Blockly.DRAG_FREE = 2;
                +
                +/**
                + * Lookup table for determining the opposite type of a connection.
                + * @const
                + */
                +Blockly.OPPOSITE_TYPE = [];
                +Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE] = Blockly.OUTPUT_VALUE;
                +Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE] = Blockly.INPUT_VALUE;
                +Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT] = Blockly.PREVIOUS_STATEMENT;
                +Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT] = Blockly.NEXT_STATEMENT;
                +
                +
                +/**
                + * ENUM for toolbox and flyout at top of screen.
                + * @const
                + */
                +Blockly.TOOLBOX_AT_TOP = 0;
                +
                +/**
                + * ENUM for toolbox and flyout at bottom of screen.
                + * @const
                + */
                +Blockly.TOOLBOX_AT_BOTTOM = 1;
                +
                +/**
                + * ENUM for toolbox and flyout at left of screen.
                + * @const
                + */
                +Blockly.TOOLBOX_AT_LEFT = 2;
                +
                +/**
                + * ENUM for toolbox and flyout at right of screen.
                + * @const
                + */
                +Blockly.TOOLBOX_AT_RIGHT = 3;
                +
                +/**
                + * ENUM representing that an event is not in any delete areas.
                + * Null for backwards compatibility reasons.
                + * @const
                + */
                +Blockly.DELETE_AREA_NONE = null;
                +
                +/**
                + * ENUM representing that an event is in the delete area of the trash can.
                + * @const
                + */
                +Blockly.DELETE_AREA_TRASH = 1;
                +
                +/**
                + * ENUM representing that an event is in the delete area of the toolbox or
                + * flyout.
                + * @const
                + */
                +Blockly.DELETE_AREA_TOOLBOX = 2;
                +
                +/**
                + * String for use in the "custom" attribute of a category in toolbox xml.
                + * This string indicates that the category should be dynamically populated with
                + * variable blocks.
                + * @const {string}
                + */
                +Blockly.VARIABLE_CATEGORY_NAME = 'VARIABLE';
                +
                +/**
                + * String for use in the "custom" attribute of a category in toolbox xml.
                + * This string indicates that the category should be dynamically populated with
                + * procedure blocks.
                + * @const {string}
                + */
                +Blockly.PROCEDURE_CATEGORY_NAME = 'PROCEDURE';
                +
                +/**
                + * String for use in the dropdown created in field_variable.
                + * This string indicates that this option in the dropdown is 'Rename
                + * variable...' and if selected, should trigger the prompt to rename a variable.
                + * @const {string}
                + */
                +Blockly.RENAME_VARIABLE_ID = 'RENAME_VARIABLE_ID';
                +
                +/**
                + * String for use in the dropdown created in field_variable.
                + * This string indicates that this option in the dropdown is 'Delete the "%1"
                + * variable' and if selected, should trigger the prompt to delete a variable.
                + * @const {string}
                + */
                +Blockly.DELETE_VARIABLE_ID = 'DELETE_VARIABLE_ID';
                diff --git a/blockly/webif/static/blockly/core/contextmenu.js b/blockly/webif/static/blockly/core/contextmenu.js
                new file mode 100644
                index 000000000..ebb8caeb6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/contextmenu.js
                @@ -0,0 +1,191 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Functionality for the right-click context menus.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.ContextMenu
                + * @namespace
                + */
                +goog.provide('Blockly.ContextMenu');
                +
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.style');
                +goog.require('goog.ui.Menu');
                +goog.require('goog.ui.MenuItem');
                +
                +
                +/**
                + * Which block is the context menu attached to?
                + * @type {Blockly.Block}
                + */
                +Blockly.ContextMenu.currentBlock = null;
                +
                +/**
                + * @type {Array.<!Array>} Opaque data that can be passed to unbindEvent_.
                + * @private
                + */
                +Blockly.ContextMenu.eventWrapper_ = null;
                +
                +/**
                + * Construct the menu based on the list of options and show the menu.
                + * @param {!Event} e Mouse event.
                + * @param {!Array.<!Object>} options Array of menu options.
                + * @param {boolean} rtl True if RTL, false if LTR.
                + */
                +Blockly.ContextMenu.show = function(e, options, rtl) {
                +  Blockly.WidgetDiv.show(Blockly.ContextMenu, rtl, null);
                +  if (!options.length) {
                +    Blockly.ContextMenu.hide();
                +    return;
                +  }
                +  var menu = Blockly.ContextMenu.populate_(options, rtl);
                +
                +  goog.events.listen(menu, goog.ui.Component.EventType.ACTION,
                +                     Blockly.ContextMenu.hide);
                +
                +  Blockly.ContextMenu.position_(menu, e, rtl);
                +  // 1ms delay is required for focusing on context menus because some other
                +  // mouse event is still waiting in the queue and clears focus.
                +  setTimeout(function() {menu.getElement().focus();}, 1);
                +  Blockly.ContextMenu.currentBlock = null;  // May be set by Blockly.Block.
                +};
                +
                +/**
                + * Create the context menu object and populate it with the given options.
                + * @param {!Array.<!Object>} options Array of menu options.
                + * @param {boolean} rtl True if RTL, false if LTR.
                + * @return {!goog.ui.Menu} The menu that will be shown on right click.
                + * @private
                + */
                +Blockly.ContextMenu.populate_ = function(options, rtl) {
                +  /* Here's what one option object looks like:
                +    {text: 'Make It So',
                +     enabled: true,
                +     callback: Blockly.MakeItSo}
                +  */
                +  var menu = new goog.ui.Menu();
                +  menu.setAllowAutoFocus(true);
                +  menu.setRightToLeft(rtl);
                +  for (var i = 0, option; option = options[i]; i++) {
                +    var menuItem = new goog.ui.MenuItem(option.text);
                +    menuItem.setRightToLeft(rtl);
                +    menu.addChild(menuItem, true);
                +    menuItem.setEnabled(option.enabled);
                +    if (option.enabled) {
                +      goog.events.listen(menuItem, goog.ui.Component.EventType.ACTION,
                +                         option.callback);
                +      menuItem.handleContextMenu = function(/* e */) {
                +        // Right-clicking on menu option should count as a click.
                +        goog.events.dispatchEvent(this, goog.ui.Component.EventType.ACTION);
                +      };
                +    }
                +  }
                +  return menu;
                +};
                +
                +/**
                + * Add the menu to the page and position it correctly.
                + * @param {!goog.ui.Menu} menu The menu to add and position.
                + * @param {!Event} e Mouse event for the right click that is making the context
                + *     menu appear.
                + * @param {boolean} rtl True if RTL, false if LTR.
                + * @private
                + */
                +Blockly.ContextMenu.position_ = function(menu, e, rtl) {
                +    // Record windowSize and scrollOffset before adding menu.
                +  var windowSize = goog.dom.getViewportSize();
                +  var scrollOffset = goog.style.getViewportPageOffset(document);
                +  var div = Blockly.WidgetDiv.DIV;
                +  menu.render(div);
                +  var menuDom = menu.getElement();
                +  Blockly.utils.addClass(menuDom, 'blocklyContextMenu');
                +  // Prevent system context menu when right-clicking a Blockly context menu.
                +  Blockly.bindEventWithChecks_(menuDom, 'contextmenu', null,
                +                               Blockly.utils.noEvent);
                +  // Record menuSize after adding menu.
                +  var menuSize = goog.style.getSize(menuDom);
                +
                +  // Position the menu.
                +  var x = e.clientX + scrollOffset.x;
                +  var y = e.clientY + scrollOffset.y;
                +  // Flip menu vertically if off the bottom.
                +  if (e.clientY + menuSize.height >= windowSize.height) {
                +    y -= menuSize.height;
                +  }
                +  // Flip menu horizontally if off the edge.
                +  if (rtl) {
                +    if (menuSize.width >= e.clientX) {
                +      x += menuSize.width;
                +    }
                +  } else {
                +    if (e.clientX + menuSize.width >= windowSize.width) {
                +      x -= menuSize.width;
                +    }
                +  }
                +  Blockly.WidgetDiv.position(x, y, windowSize, scrollOffset, rtl);
                +};
                +
                +/**
                + * Hide the context menu.
                + */
                +Blockly.ContextMenu.hide = function() {
                +  Blockly.WidgetDiv.hideIfOwner(Blockly.ContextMenu);
                +  Blockly.ContextMenu.currentBlock = null;
                +  if (Blockly.ContextMenu.eventWrapper_) {
                +    Blockly.unbindEvent_(Blockly.ContextMenu.eventWrapper_);
                +  }
                +};
                +
                +/**
                + * Create a callback function that creates and configures a block,
                + *   then places the new block next to the original.
                + * @param {!Blockly.Block} block Original block.
                + * @param {!Element} xml XML representation of new block.
                + * @return {!Function} Function that creates a block.
                + */
                +Blockly.ContextMenu.callbackFactory = function(block, xml) {
                +  return function() {
                +    Blockly.Events.disable();
                +    try {
                +      var newBlock = Blockly.Xml.domToBlock(xml, block.workspace);
                +      // Move the new block next to the old block.
                +      var xy = block.getRelativeToSurfaceXY();
                +      if (block.RTL) {
                +        xy.x -= Blockly.SNAP_RADIUS;
                +      } else {
                +        xy.x += Blockly.SNAP_RADIUS;
                +      }
                +      xy.y += Blockly.SNAP_RADIUS * 2;
                +      newBlock.moveBy(xy.x, xy.y);
                +    } finally {
                +      Blockly.Events.enable();
                +    }
                +    if (Blockly.Events.isEnabled() && !newBlock.isShadow()) {
                +      Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock));
                +    }
                +    newBlock.select();
                +  };
                +};
                diff --git a/blockly/webif/static/blockly/core/css.js b/blockly/webif/static/blockly/core/css.js
                new file mode 100644
                index 000000000..a4d766c36
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/css.js
                @@ -0,0 +1,871 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Inject Blockly's CSS synchronously.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Css
                + * @namespace
                + */
                +goog.provide('Blockly.Css');
                +
                +
                +/**
                + * List of cursors.
                + * @enum {string}
                + */
                +Blockly.Css.Cursor = {
                +  OPEN: 'handopen',
                +  CLOSED: 'handclosed',
                +  DELETE: 'handdelete'
                +};
                +
                +/**
                + * Current cursor (cached value).
                + * @type {string}
                + * @private
                + */
                +Blockly.Css.currentCursor_ = '';
                +
                +/**
                + * Large stylesheet added by Blockly.Css.inject.
                + * @type {Element}
                + * @private
                + */
                +Blockly.Css.styleSheet_ = null;
                +
                +/**
                + * Path to media directory, with any trailing slash removed.
                + * @type {string}
                + * @private
                + */
                +Blockly.Css.mediaPath_ = '';
                +
                +/**
                + * Inject the CSS into the DOM.  This is preferable over using a regular CSS
                + * file since:
                + * a) It loads synchronously and doesn't force a redraw later.
                + * b) It speeds up loading by not blocking on a separate HTTP transfer.
                + * c) The CSS content may be made dynamic depending on init options.
                + * @param {boolean} hasCss If false, don't inject CSS
                + *     (providing CSS becomes the document's responsibility).
                + * @param {string} pathToMedia Path from page to the Blockly media directory.
                + */
                +Blockly.Css.inject = function(hasCss, pathToMedia) {
                +  // Only inject the CSS once.
                +  if (Blockly.Css.styleSheet_) {
                +    return;
                +  }
                +  // Placeholder for cursor rule.  Must be first rule (index 0).
                +  var text = '.blocklyDraggable {}\n';
                +  if (hasCss) {
                +    text += Blockly.Css.CONTENT.join('\n');
                +    if (Blockly.FieldDate) {
                +      text += Blockly.FieldDate.CSS.join('\n');
                +    }
                +  }
                +  // Strip off any trailing slash (either Unix or Windows).
                +  Blockly.Css.mediaPath_ = pathToMedia.replace(/[\\\/]$/, '');
                +  text = text.replace(/<<<PATH>>>/g, Blockly.Css.mediaPath_);
                +  // Inject CSS tag at start of head.
                +  var cssNode = document.createElement('style');
                +  document.head.insertBefore(cssNode, document.head.firstChild);
                +
                +  var cssTextNode = document.createTextNode(text);
                +  cssNode.appendChild(cssTextNode);
                +  Blockly.Css.styleSheet_ = cssNode.sheet;
                +};
                +
                +/**
                + * Set the cursor to be displayed when over something draggable.
                + * See See https://github.com/google/blockly/issues/981 for context.
                + * @param {Blockly.Css.Cursor} cursor Enum.
                + * @deprecated April 2017.
                + */
                +Blockly.Css.setCursor = function(cursor) {
                +  console.warn('Deprecated call to Blockly.Css.setCursor.' +
                +    'See https://github.com/google/blockly/issues/981 for context');
                +};
                +
                +/**
                + * Array making up the CSS content for Blockly.
                + */
                +Blockly.Css.CONTENT = [
                +  '.blocklySvg {',
                +    'background-color: #fff;',
                +    'outline: none;',
                +    'overflow: hidden;',  /* IE overflows by default. */
                +    'position: absolute;',
                +    'display: block;',
                +  '}',
                +
                +  '.blocklyWidgetDiv {',
                +    'display: none;',
                +    'position: absolute;',
                +    'z-index: 99999;', /* big value for bootstrap3 compatibility */
                +  '}',
                +
                +  '.injectionDiv {',
                +    'height: 100%;',
                +    'position: relative;',
                +    'overflow: hidden;', /* So blocks in drag surface disappear at edges */
                +    'touch-action: none',
                +  '}',
                +
                +  '.blocklyNonSelectable {',
                +    'user-select: none;',
                +    '-moz-user-select: none;',
                +    '-webkit-user-select: none;',
                +    '-ms-user-select: none;',
                +  '}',
                +
                +  '.blocklyWsDragSurface {',
                +    'display: none;',
                +    'position: absolute;',
                +    'overflow: visible;',
                +    'top: 0;',
                +    'left: 0;',
                +  '}',
                +
                +  '.blocklyBlockDragSurface {',
                +    'display: none;',
                +    'position: absolute;',
                +    'top: 0;',
                +    'left: 0;',
                +    'right: 0;',
                +    'bottom: 0;',
                +    'overflow: visible !important;',
                +    'z-index: 50;', /* Display below toolbox, but above everything else. */
                +  '}',
                +
                +  '.blocklyTooltipDiv {',
                +    'background-color: #ffffc7;',
                +    'border: 1px solid #ddc;',
                +    'box-shadow: 4px 4px 20px 1px rgba(0,0,0,.15);',
                +    'color: #000;',
                +    'display: none;',
                +    'font-family: sans-serif;',
                +    'font-size: 9pt;',
                +    'opacity: 0.9;',
                +    'padding: 2px;',
                +    'position: absolute;',
                +    'z-index: 100000;', /* big value for bootstrap3 compatibility */
                +  '}',
                +
                +  '.blocklyResizeSE {',
                +    'cursor: se-resize;',
                +    'fill: #aaa;',
                +  '}',
                +
                +  '.blocklyResizeSW {',
                +    'cursor: sw-resize;',
                +    'fill: #aaa;',
                +  '}',
                +
                +  '.blocklyResizeLine {',
                +    'stroke: #888;',
                +    'stroke-width: 1;',
                +  '}',
                +
                +  '.blocklyHighlightedConnectionPath {',
                +    'fill: none;',
                +    'stroke: #fc3;',
                +    'stroke-width: 4px;',
                +  '}',
                +
                +  '.blocklyPathLight {',
                +    'fill: none;',
                +    'stroke-linecap: round;',
                +    'stroke-width: 1;',
                +  '}',
                +
                +  '.blocklySelected>.blocklyPath {',
                +    'stroke: #fc3;',
                +    'stroke-width: 3px;',
                +  '}',
                +
                +  '.blocklySelected>.blocklyPathLight {',
                +    'display: none;',
                +  '}',
                +
                +  '.blocklyDraggable {',
                +    /* backup for browsers (e.g. IE11) that don't support grab */
                +    'cursor: url("<<<PATH>>>/handopen.cur"), auto;',
                +    'cursor: grab;',
                +    'cursor: -webkit-grab;',
                +    'cursor: -moz-grab;',
                +  '}',
                +
                +   '.blocklyDragging {',
                +    /* backup for browsers (e.g. IE11) that don't support grabbing */
                +    'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
                +    'cursor: grabbing;',
                +    'cursor: -webkit-grabbing;',
                +    'cursor: -moz-grabbing;',
                +  '}',
                +  /* Changes cursor on mouse down. Not effective in Firefox because of
                +    https://bugzilla.mozilla.org/show_bug.cgi?id=771241 */
                +  '.blocklyDraggable:active {',
                +    /* backup for browsers (e.g. IE11) that don't support grabbing */
                +    'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
                +    'cursor: grabbing;',
                +    'cursor: -webkit-grabbing;',
                +    'cursor: -moz-grabbing;',
                +  '}',
                +  /* Change the cursor on the whole drag surface in case the mouse gets
                +     ahead of block during a drag. This way the cursor is still a closed hand.
                +   */
                +  '.blocklyBlockDragSurface .blocklyDraggable {',
                +    /* backup for browsers (e.g. IE11) that don't support grabbing */
                +    'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
                +    'cursor: grabbing;',
                +    'cursor: -webkit-grabbing;',
                +    'cursor: -moz-grabbing;',
                +  '}',
                +
                +  '.blocklyDragging.blocklyDraggingDelete {',
                +    'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',
                +  '}',
                +
                +  '.blocklyToolboxDelete {',
                +    'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',
                +  '}',
                +
                +  '.blocklyDragging>.blocklyPath,',
                +  '.blocklyDragging>.blocklyPathLight {',
                +    'fill-opacity: .8;',
                +    'stroke-opacity: .8;',
                +  '}',
                +
                +  '.blocklyDragging>.blocklyPathDark {',
                +    'display: none;',
                +  '}',
                +
                +  '.blocklyDisabled>.blocklyPath {',
                +    'fill-opacity: .5;',
                +    'stroke-opacity: .5;',
                +  '}',
                +
                +  '.blocklyDisabled>.blocklyPathLight,',
                +  '.blocklyDisabled>.blocklyPathDark {',
                +    'display: none;',
                +  '}',
                +
                +  '.blocklyText {',
                +    'cursor: default;',
                +    'fill: #fff;',
                +    'font-family: sans-serif;',
                +    'font-size: 11pt;',
                +  '}',
                +
                +  '.blocklyNonEditableText>text {',
                +    'pointer-events: none;',
                +  '}',
                +
                +  '.blocklyNonEditableText>rect,',
                +  '.blocklyEditableText>rect {',
                +    'fill: #fff;',
                +    'fill-opacity: .6;',
                +  '}',
                +
                +  '.blocklyNonEditableText>text,',
                +  '.blocklyEditableText>text {',
                +    'fill: #000;',
                +  '}',
                +
                +  '.blocklyEditableText:hover>rect {',
                +    'stroke: #fff;',
                +    'stroke-width: 2;',
                +  '}',
                +
                +  '.blocklyBubbleText {',
                +    'fill: #000;',
                +  '}',
                +
                +  '.blocklyFlyout {',
                +    'position: absolute;',
                +    'z-index: 20;',
                +  '}',
                +  '.blocklyFlyoutButton {',
                +    'fill: #888;',
                +    'cursor: default;',
                +  '}',
                +
                +  '.blocklyFlyoutButtonShadow {',
                +    'fill: #666;',
                +  '}',
                +
                +  '.blocklyFlyoutButton:hover {',
                +    'fill: #aaa;',
                +  '}',
                +
                +  '.blocklyFlyoutLabel {',
                +    'cursor: default;',
                +  '}',
                +
                +  '.blocklyFlyoutLabelBackground {',
                +    'opacity: 0;',
                +  '}',
                +
                +  '.blocklyFlyoutLabelText {',
                +    'fill: #000;',
                +  '}',
                +
                +  /*
                +    Don't allow users to select text.  It gets annoying when trying to
                +    drag a block and selected text moves instead.
                +  */
                +  '.blocklySvg text, .blocklyBlockDragSurface text {',
                +    'user-select: none;',
                +    '-moz-user-select: none;',
                +    '-webkit-user-select: none;',
                +    'cursor: inherit;',
                +  '}',
                +
                +  '.blocklyHidden {',
                +    'display: none;',
                +  '}',
                +
                +  '.blocklyFieldDropdown:not(.blocklyHidden) {',
                +    'display: block;',
                +  '}',
                +
                +  '.blocklyIconGroup {',
                +    'cursor: default;',
                +  '}',
                +
                +  '.blocklyIconGroup:not(:hover),',
                +  '.blocklyIconGroupReadonly {',
                +    'opacity: .6;',
                +  '}',
                +
                +  '.blocklyIconShape {',
                +    'fill: #00f;',
                +    'stroke: #fff;',
                +    'stroke-width: 1px;',
                +  '}',
                +
                +  '.blocklyIconSymbol {',
                +    'fill: #fff;',
                +  '}',
                +
                +  '.blocklyMinimalBody {',
                +    'margin: 0;',
                +    'padding: 0;',
                +  '}',
                +
                +  '.blocklyCommentTextarea {',
                +    'background-color: #ffc;',
                +    'border: 0;',
                +    'margin: 0;',
                +    'padding: 2px;',
                +    'resize: none;',
                +  '}',
                +
                +  '.blocklyHtmlInput {',
                +    'border: none;',
                +    'border-radius: 4px;',
                +    'font-family: sans-serif;',
                +    'height: 100%;',
                +    'margin: 0;',
                +    'outline: none;',
                +    'padding: 0 1px;',
                +    'width: 100%',
                +  '}',
                +
                +  '.blocklyMainBackground {',
                +    'stroke-width: 1;',
                +    'stroke: #c6c6c6;',  /* Equates to #ddd due to border being off-pixel. */
                +  '}',
                +
                +  '.blocklyMutatorBackground {',
                +    'fill: #fff;',
                +    'stroke: #ddd;',
                +    'stroke-width: 1;',
                +  '}',
                +
                +  '.blocklyFlyoutBackground {',
                +    'fill: #ddd;',
                +    'fill-opacity: .8;',
                +  '}',
                +
                +  '.blocklyTransparentBackground {',
                +    'opacity: 0;',
                +  '}',
                +
                +  '.blocklyMainWorkspaceScrollbar {',
                +    'z-index: 20;',
                +  '}',
                +
                +  '.blocklyFlyoutScrollbar {',
                +    'z-index: 30;',
                +  '}',
                +
                +  '.blocklyScrollbarHorizontal, .blocklyScrollbarVertical {',
                +    'position: absolute;',
                +    'outline: none;',
                +  '}',
                +
                +  '.blocklyScrollbarBackground {',
                +    'opacity: 0;',
                +  '}',
                +
                +  '.blocklyScrollbarHandle {',
                +    'fill: #ccc;',
                +  '}',
                +
                +  '.blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,',
                +  '.blocklyScrollbarHandle:hover {',
                +    'fill: #bbb;',
                +  '}',
                +
                +  '.blocklyZoom>image {',
                +    'opacity: .4;',
                +  '}',
                +
                +  '.blocklyZoom>image:hover {',
                +    'opacity: .6;',
                +  '}',
                +
                +  '.blocklyZoom>image:active {',
                +    'opacity: .8;',
                +  '}',
                +
                +  /* Darken flyout scrollbars due to being on a grey background. */
                +  /* By contrast, workspace scrollbars are on a white background. */
                +  '.blocklyFlyout .blocklyScrollbarHandle {',
                +    'fill: #bbb;',
                +  '}',
                +
                +  '.blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,',
                +  '.blocklyFlyout .blocklyScrollbarHandle:hover {',
                +    'fill: #aaa;',
                +  '}',
                +
                +  '.blocklyInvalidInput {',
                +    'background: #faa;',
                +  '}',
                +
                +  '.blocklyAngleCircle {',
                +    'stroke: #444;',
                +    'stroke-width: 1;',
                +    'fill: #ddd;',
                +    'fill-opacity: .8;',
                +  '}',
                +
                +  '.blocklyAngleMarks {',
                +    'stroke: #444;',
                +    'stroke-width: 1;',
                +  '}',
                +
                +  '.blocklyAngleGauge {',
                +    'fill: #f88;',
                +    'fill-opacity: .8;',
                +  '}',
                +
                +  '.blocklyAngleLine {',
                +    'stroke: #f00;',
                +    'stroke-width: 2;',
                +    'stroke-linecap: round;',
                +    'pointer-events: none;',
                +  '}',
                +
                +  '.blocklyContextMenu {',
                +    'border-radius: 4px;',
                +  '}',
                +
                +  '.blocklyDropdownMenu {',
                +    'padding: 0 !important;',
                +  '}',
                +
                +  /* Override the default Closure URL. */
                +  '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,',
                +  '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {',
                +    'background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;',
                +  '}',
                +
                +  /* Category tree in Toolbox. */
                +  '.blocklyToolboxDiv {',
                +    'background-color: #ddd;',
                +    'overflow-x: visible;',
                +    'overflow-y: auto;',
                +    'position: absolute;',
                +    'z-index: 70;', /* so blocks go under toolbox when dragging */
                +  '}',
                +
                +  '.blocklyTreeRoot {',
                +    'padding: 4px 0;',
                +  '}',
                +
                +  '.blocklyTreeRoot:focus {',
                +    'outline: none;',
                +  '}',
                +
                +  '.blocklyTreeRow {',
                +    'height: 22px;',
                +    'line-height: 22px;',
                +    'margin-bottom: 3px;',
                +    'padding-right: 8px;',
                +    'white-space: nowrap;',
                +  '}',
                +
                +  '.blocklyHorizontalTree {',
                +    'float: left;',
                +    'margin: 1px 5px 8px 0;',
                +  '}',
                +
                +  '.blocklyHorizontalTreeRtl {',
                +    'float: right;',
                +    'margin: 1px 0 8px 5px;',
                +  '}',
                +
                +  '.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',
                +    'margin-left: 8px;',
                +  '}',
                +
                +  '.blocklyTreeRow:not(.blocklyTreeSelected):hover {',
                +    'background-color: #e4e4e4;',
                +  '}',
                +
                +  '.blocklyTreeSeparator {',
                +    'border-bottom: solid #e5e5e5 1px;',
                +    'height: 0;',
                +    'margin: 5px 0;',
                +  '}',
                +
                +  '.blocklyTreeSeparatorHorizontal {',
                +    'border-right: solid #e5e5e5 1px;',
                +    'width: 0;',
                +    'padding: 5px 0;',
                +    'margin: 0 5px;',
                +  '}',
                +
                +
                +  '.blocklyTreeIcon {',
                +    'background-image: url(<<<PATH>>>/sprites.png);',
                +    'height: 16px;',
                +    'vertical-align: middle;',
                +    'width: 16px;',
                +  '}',
                +
                +  '.blocklyTreeIconClosedLtr {',
                +    'background-position: -32px -1px;',
                +  '}',
                +
                +  '.blocklyTreeIconClosedRtl {',
                +    'background-position: 0px -1px;',
                +  '}',
                +
                +  '.blocklyTreeIconOpen {',
                +    'background-position: -16px -1px;',
                +  '}',
                +
                +  '.blocklyTreeSelected>.blocklyTreeIconClosedLtr {',
                +    'background-position: -32px -17px;',
                +  '}',
                +
                +  '.blocklyTreeSelected>.blocklyTreeIconClosedRtl {',
                +    'background-position: 0px -17px;',
                +  '}',
                +
                +  '.blocklyTreeSelected>.blocklyTreeIconOpen {',
                +    'background-position: -16px -17px;',
                +  '}',
                +
                +  '.blocklyTreeIconNone,',
                +  '.blocklyTreeSelected>.blocklyTreeIconNone {',
                +    'background-position: -48px -1px;',
                +  '}',
                +
                +  '.blocklyTreeLabel {',
                +    'cursor: default;',
                +    'font-family: sans-serif;',
                +    'font-size: 16px;',
                +    'padding: 0 3px;',
                +    'vertical-align: middle;',
                +  '}',
                +
                +  '.blocklyToolboxDelete .blocklyTreeLabel {',
                +    'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',
                +  '}',
                +
                +  '.blocklyTreeSelected .blocklyTreeLabel {',
                +    'color: #fff;',
                +  '}',
                +
                +  /* Copied from: goog/css/colorpicker-simplegrid.css */
                +  /*
                +   * Copyright 2007 The Closure Library Authors. All Rights Reserved.
                +   *
                +   * Use of this source code is governed by the Apache License, Version 2.0.
                +   * See the COPYING file for details.
                +   */
                +
                +  /* Author: pupius@google.com (Daniel Pupius) */
                +
                +  /*
                +    Styles to make the colorpicker look like the old gmail color picker
                +    NOTE: without CSS scoping this will override styles defined in palette.css
                +  */
                +  '.blocklyWidgetDiv .goog-palette {',
                +    'outline: none;',
                +    'cursor: default;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-palette-table {',
                +    'border: 1px solid #666;',
                +    'border-collapse: collapse;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-palette-cell {',
                +    'height: 13px;',
                +    'width: 15px;',
                +    'margin: 0;',
                +    'border: 0;',
                +    'text-align: center;',
                +    'vertical-align: middle;',
                +    'border-right: 1px solid #666;',
                +    'font-size: 1px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-palette-colorswatch {',
                +    'position: relative;',
                +    'height: 13px;',
                +    'width: 15px;',
                +    'border: 1px solid #666;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-palette-cell-hover .goog-palette-colorswatch {',
                +    'border: 1px solid #FFF;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-palette-cell-selected .goog-palette-colorswatch {',
                +    'border: 1px solid #000;',
                +    'color: #fff;',
                +  '}',
                +
                +  /* Copied from: goog/css/menu.css */
                +  /*
                +   * Copyright 2009 The Closure Library Authors. All Rights Reserved.
                +   *
                +   * Use of this source code is governed by the Apache License, Version 2.0.
                +   * See the COPYING file for details.
                +   */
                +
                +  /**
                +   * Standard styling for menus created by goog.ui.MenuRenderer.
                +   *
                +   * @author attila@google.com (Attila Bodis)
                +   */
                +
                +  '.blocklyWidgetDiv .goog-menu {',
                +    'background: #fff;',
                +    'border-color: #ccc #666 #666 #ccc;',
                +    'border-style: solid;',
                +    'border-width: 1px;',
                +    'cursor: default;',
                +    'font: normal 13px Arial, sans-serif;',
                +    'margin: 0;',
                +    'outline: none;',
                +    'padding: 4px 0;',
                +    'position: absolute;',
                +    'overflow-y: auto;',
                +    'overflow-x: hidden;',
                +    'max-height: 100%;',
                +    'z-index: 20000;',  /* Arbitrary, but some apps depend on it... */
                +  '}',
                +
                +  /* Copied from: goog/css/menuitem.css */
                +  /*
                +   * Copyright 2009 The Closure Library Authors. All Rights Reserved.
                +   *
                +   * Use of this source code is governed by the Apache License, Version 2.0.
                +   * See the COPYING file for details.
                +   */
                +
                +  /**
                +   * Standard styling for menus created by goog.ui.MenuItemRenderer.
                +   *
                +   * @author attila@google.com (Attila Bodis)
                +   */
                +
                +  /**
                +   * State: resting.
                +   *
                +   * NOTE(mleibman,chrishenry):
                +   * The RTL support in Closure is provided via two mechanisms -- "rtl" CSS
                +   * classes and BiDi flipping done by the CSS compiler.  Closure supports RTL
                +   * with or without the use of the CSS compiler.  In order for them not
                +   * to conflict with each other, the "rtl" CSS classes need to have the #noflip
                +   * annotation.  The non-rtl counterparts should ideally have them as well, but,
                +   * since .goog-menuitem existed without .goog-menuitem-rtl for so long before
                +   * being added, there is a risk of people having templates where they are not
                +   * rendering the .goog-menuitem-rtl class when in RTL and instead rely solely
                +   * on the BiDi flipping by the CSS compiler.  That's why we're not adding the
                +   * #noflip to .goog-menuitem.
                +   */
                +  '.blocklyWidgetDiv .goog-menuitem {',
                +    'color: #000;',
                +    'font: normal 13px Arial, sans-serif;',
                +    'list-style: none;',
                +    'margin: 0;',
                +     /* 28px on the left for icon or checkbox; 7em on the right for shortcut. */
                +    'padding: 4px 7em 4px 28px;',
                +    'white-space: nowrap;',
                +  '}',
                +
                +  /* BiDi override for the resting state. */
                +  /* #noflip */
                +  '.blocklyWidgetDiv .goog-menuitem.goog-menuitem-rtl {',
                +     /* Flip left/right padding for BiDi. */
                +    'padding-left: 7em;',
                +    'padding-right: 28px;',
                +  '}',
                +
                +  /* If a menu doesn't have checkable items or items with icons, remove padding. */
                +  '.blocklyWidgetDiv .goog-menu-nocheckbox .goog-menuitem,',
                +  '.blocklyWidgetDiv .goog-menu-noicon .goog-menuitem {',
                +    'padding-left: 12px;',
                +  '}',
                +
                +  /*
                +   * If a menu doesn't have items with shortcuts, leave just enough room for
                +   * submenu arrows, if they are rendered.
                +   */
                +  '.blocklyWidgetDiv .goog-menu-noaccel .goog-menuitem {',
                +    'padding-right: 20px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-menuitem-content {',
                +    'color: #000;',
                +    'font: normal 13px Arial, sans-serif;',
                +  '}',
                +
                +  /* State: disabled. */
                +  '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-accel,',
                +  '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-content {',
                +    'color: #ccc !important;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-menuitem-disabled .goog-menuitem-icon {',
                +    'opacity: 0.3;',
                +    '-moz-opacity: 0.3;',
                +    'filter: alpha(opacity=30);',
                +  '}',
                +
                +  /* State: hover. */
                +  '.blocklyWidgetDiv .goog-menuitem-highlight,',
                +  '.blocklyWidgetDiv .goog-menuitem-hover {',
                +    'background-color: #d6e9f8;',
                +     /* Use an explicit top and bottom border so that the selection is visible',
                +      * in high contrast mode. */
                +    'border-color: #d6e9f8;',
                +    'border-style: dotted;',
                +    'border-width: 1px 0;',
                +    'padding-bottom: 3px;',
                +    'padding-top: 3px;',
                +  '}',
                +
                +  /* State: selected/checked. */
                +  '.blocklyWidgetDiv .goog-menuitem-checkbox,',
                +  '.blocklyWidgetDiv .goog-menuitem-icon {',
                +    'background-repeat: no-repeat;',
                +    'height: 16px;',
                +    'left: 6px;',
                +    'position: absolute;',
                +    'right: auto;',
                +    'vertical-align: middle;',
                +    'width: 16px;',
                +  '}',
                +
                +  /* BiDi override for the selected/checked state. */
                +  /* #noflip */
                +  '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-checkbox,',
                +  '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-icon {',
                +     /* Flip left/right positioning. */
                +    'left: auto;',
                +    'right: 6px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,',
                +  '.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {',
                +     /* Client apps may override the URL at which they serve the sprite. */
                +    'background: url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0;',
                +  '}',
                +
                +  /* Keyboard shortcut ("accelerator") style. */
                +  '.blocklyWidgetDiv .goog-menuitem-accel {',
                +    'color: #999;',
                +     /* Keyboard shortcuts are untranslated; always left-to-right. */
                +     /* #noflip */
                +    'direction: ltr;',
                +    'left: auto;',
                +    'padding: 0 6px;',
                +    'position: absolute;',
                +    'right: 0;',
                +    'text-align: right;',
                +  '}',
                +
                +  /* BiDi override for shortcut style. */
                +  /* #noflip */
                +  '.blocklyWidgetDiv .goog-menuitem-rtl .goog-menuitem-accel {',
                +     /* Flip left/right positioning and text alignment. */
                +    'left: 0;',
                +    'right: auto;',
                +    'text-align: left;',
                +  '}',
                +
                +  /* Mnemonic styles. */
                +  '.blocklyWidgetDiv .goog-menuitem-mnemonic-hint {',
                +    'text-decoration: underline;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-menuitem-mnemonic-separator {',
                +    'color: #999;',
                +    'font-size: 12px;',
                +    'padding-left: 4px;',
                +  '}',
                +
                +  /* Copied from: goog/css/menuseparator.css */
                +  /*
                +   * Copyright 2009 The Closure Library Authors. All Rights Reserved.
                +   *
                +   * Use of this source code is governed by the Apache License, Version 2.0.
                +   * See the COPYING file for details.
                +   */
                +
                +  /**
                +   * Standard styling for menus created by goog.ui.MenuSeparatorRenderer.
                +   *
                +   * @author attila@google.com (Attila Bodis)
                +   */
                +
                +  '.blocklyWidgetDiv .goog-menuseparator {',
                +    'border-top: 1px solid #ccc;',
                +    'margin: 4px 0;',
                +    'padding: 0;',
                +  '}',
                +
                +  ''
                +];
                diff --git a/blockly/webif/static/blockly/core/dragged_connection_manager.js b/blockly/webif/static/blockly/core/dragged_connection_manager.js
                new file mode 100644
                index 000000000..1ebe2ef66
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/dragged_connection_manager.js
                @@ -0,0 +1,237 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Class that controls updates to connections during drags.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.DraggedConnectionManager');
                +
                +goog.require('Blockly.RenderedConnection');
                +
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Class that controls updates to connections during drags.  It is primarily
                + * responsible for finding the closest eligible connection and highlighting or
                + * unhiglighting it as needed during a drag.
                + * @param {!Blockly.BlockSvg} block The top block in the stack being dragged.
                + * @constructor
                + */
                +Blockly.DraggedConnectionManager = function(block) {
                +  Blockly.selected = block;
                +
                +  /**
                +   * The top block in the stack being dragged.
                +   * Does not change during a drag.
                +   * @type {!Blockly.Block}
                +   * @private
                +   */
                +  this.topBlock_ = block;
                +
                +  /**
                +   * The workspace on which these connections are being dragged.
                +   * Does not change during a drag.
                +   * @type {!Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.workspace_ = block.workspace;
                +
                +  /**
                +   * The connections on the dragging blocks that are available to connect to
                +   * other blocks.  This includes all open connections on the top block, as well
                +   * as the last connection on the block stack.
                +   * Does not change during a drag.
                +   * @type {!Array.<!Blockly.RenderedConnection>}
                +   * @private
                +   */
                +  this.availableConnections_ = this.initAvailableConnections_();
                +
                +  /**
                +   * The connection that this block would connect to if released immediately.
                +   * Updated on every mouse move.
                +   * @type {Blockly.RenderedConnection}
                +   * @private
                +   */
                +  this.closestConnection_ = null;
                +
                +  /**
                +   * The connection that would connect to this.closestConnection_ if this block
                +   * were released immediately.
                +   * Updated on every mouse move.
                +   * @type {Blockly.RenderedConnection}
                +   * @private
                +   */
                +  this.localConnection_ = null;
                +
                +  /**
                +   * The distance between this.closestConnection_ and this.localConnection_,
                +   * in workspace units.
                +   * Updated on every mouse move.
                +   * @type {number}
                +   * @private
                +   */
                +  this.radiusConnection_ = 0;
                +
                +  /**
                +   * Whether the block would be deleted if it were dropped immediately.
                +   * Updated on every mouse move.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.wouldDeleteBlock_ = false;
                +};
                +
                +/**
                + * Sever all links from this object.
                + * @package
                + */
                +Blockly.DraggedConnectionManager.prototype.dispose = function() {
                +  this.topBlock_ = null;
                +  this.workspace_ = null;
                +  this.availableConnections_.length = 0;
                +  this.closestConnection_ = null;
                +  this.localConnection_ = null;
                +};
                +
                +/**
                + * Return whether the block would be deleted if dropped immediately, based on
                + * information from the most recent move event.
                + * @return {boolean} true if the block would be deleted if dropped immediately.
                + * @package
                + */
                +Blockly.DraggedConnectionManager.prototype.wouldDeleteBlock = function() {
                +  return this.wouldDeleteBlock_;
                +};
                +
                +/**
                + * Connect to the closest connection and render the results.
                + * This should be called at the end of a drag.
                + * @package
                + */
                +Blockly.DraggedConnectionManager.prototype.applyConnections = function() {
                +  if (this.closestConnection_) {
                +    // Connect two blocks together.
                +    this.localConnection_.connect(this.closestConnection_);
                +    if (this.topBlock_.rendered) {
                +      // Trigger a connection animation.
                +      // Determine which connection is inferior (lower in the source stack).
                +      var inferiorConnection = this.localConnection_.isSuperior() ?
                +          this.closestConnection_ : this.localConnection_;
                +      inferiorConnection.getSourceBlock().connectionUiEffect();
                +    }
                +    this.removeHighlighting_();
                +  }
                +};
                +
                +/**
                + * Update highlighted connections based on the most recent move location.
                + * @param {!goog.math.Coordinate} dxy Position relative to drag start,
                + *     in workspace units.
                + * @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH},
                + *     {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
                + * @package
                + */
                +Blockly.DraggedConnectionManager.prototype.update = function(dxy, deleteArea) {
                +  var oldClosestConnection = this.closestConnection_;
                +  var closestConnectionChanged = this.updateClosest_(dxy);
                +
                +  if (closestConnectionChanged && oldClosestConnection) {
                +    oldClosestConnection.unhighlight();
                +  }
                +
                + // Prefer connecting over dropping into the trash can, but prefer dragging to
                + // the toolbox over connecting to other blocks.
                +  var wouldConnect = !!this.closestConnection_ &&
                +      deleteArea != Blockly.DELETE_AREA_TOOLBOX;
                +  var wouldDelete = !!deleteArea && !this.topBlock_.getParent() &&
                +      this.topBlock_.isDeletable();
                +  this.wouldDeleteBlock_ = wouldDelete && !wouldConnect;
                +
                +  if (!this.wouldDeleteBlock_ && closestConnectionChanged &&
                +      this.closestConnection_) {
                +    this.addHighlighting_();
                +  }
                +};
                +
                +/**
                + * Remove highlighting from the currently highlighted connection, if it exists.
                + * @private
                + */
                +Blockly.DraggedConnectionManager.prototype.removeHighlighting_ = function() {
                +  if (this.closestConnection_) {
                +    this.closestConnection_.unhighlight();
                +  }
                +};
                +
                +/**
                + * Add highlighting to the closest connection, if it exists.
                + * @private
                + */
                +Blockly.DraggedConnectionManager.prototype.addHighlighting_ = function() {
                +  if (this.closestConnection_) {
                +    this.closestConnection_.highlight();
                +  }
                +};
                +
                +/**
                + * Populate the list of available connections on this block stack.  This should
                + * only be called once, at the beginning of a drag.
                + * @return {!Array.<!Blockly.RenderedConnection>} a list of available
                + *     connections.
                + * @private
                + */
                +Blockly.DraggedConnectionManager.prototype.initAvailableConnections_ = function() {
                +  var available = this.topBlock_.getConnections_(false);
                +  // Also check the last connection on this stack
                +  var lastOnStack = this.topBlock_.lastConnectionInStack_();
                +  if (lastOnStack && lastOnStack != this.topBlock_.nextConnection) {
                +    available.push(lastOnStack);
                +  }
                +  return available;
                +};
                +
                +/**
                + * Find the new closest connection, and update internal state in response.
                + * @param {!goog.math.Coordinate} dxy Position relative to the drag start,
                + *     in workspace units.
                + * @return {boolean} Whether the closest connection has changed.
                + * @private
                + */
                +Blockly.DraggedConnectionManager.prototype.updateClosest_ = function(dxy) {
                +  var oldClosestConnection = this.closestConnection_;
                +
                +  this.closestConnection_ = null;
                +  this.localConnection_ = null;
                +  this.radiusConnection_ = Blockly.SNAP_RADIUS;
                +  for (var i = 0; i < this.availableConnections_.length; i++) {
                +    var myConnection = this.availableConnections_[i];
                +    var neighbour = myConnection.closest(this.radiusConnection_, dxy);
                +    if (neighbour.connection) {
                +      this.closestConnection_ = neighbour.connection;
                +      this.localConnection_ = myConnection;
                +      this.radiusConnection_ = neighbour.radius;
                +    }
                +  }
                +  return oldClosestConnection != this.closestConnection_;
                +};
                diff --git a/blockly/webif/static/blockly/core/events.js b/blockly/webif/static/blockly/core/events.js
                new file mode 100644
                index 000000000..3e196dc56
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/events.js
                @@ -0,0 +1,1116 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Events fired as a result of actions in Blockly's editor.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * Events fired as a result of actions in Blockly's editor.
                + * @namespace Blockly.Events
                + */
                +goog.provide('Blockly.Events');
                +
                +goog.require('goog.array');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Group ID for new events.  Grouped events are indivisible.
                + * @type {string}
                + * @private
                + */
                +Blockly.Events.group_ = '';
                +
                +/**
                + * Sets whether events should be added to the undo stack.
                + * @type {boolean}
                + */
                +Blockly.Events.recordUndo = true;
                +
                +/**
                + * Allow change events to be created and fired.
                + * @type {number}
                + * @private
                + */
                +Blockly.Events.disabled_ = 0;
                +
                +/**
                + * Name of event that creates a block. Will be deprecated for BLOCK_CREATE.
                + * @const
                + */
                +Blockly.Events.CREATE = 'create';
                +
                +/**
                + * Name of event that creates a block.
                + * @const
                + */
                +Blockly.Events.BLOCK_CREATE = Blockly.Events.CREATE;
                +
                +/**
                + * Name of event that deletes a block. Will be deprecated for BLOCK_DELETE.
                + * @const
                + */
                +Blockly.Events.DELETE = 'delete';
                +
                +/**
                + * Name of event that deletes a block.
                + * @const
                + */
                +Blockly.Events.BLOCK_DELETE = Blockly.Events.DELETE;
                +
                +/**
                + * Name of event that changes a block. Will be deprecated for BLOCK_CHANGE.
                + * @const
                + */
                +Blockly.Events.CHANGE = 'change';
                +
                +/**
                + * Name of event that changes a block.
                + * @const
                + */
                +Blockly.Events.BLOCK_CHANGE = Blockly.Events.CHANGE;
                +
                +/**
                + * Name of event that moves a block. Will be deprecated for BLOCK_MOVE.
                + * @const
                + */
                +Blockly.Events.MOVE = 'move';
                +
                +/**
                + * Name of event that moves a block.
                + * @const
                + */
                +Blockly.Events.BLOCK_MOVE = Blockly.Events.MOVE;
                +
                +/**
                + * Name of event that creates a variable.
                + * @const
                + */
                +Blockly.Events.VAR_CREATE = 'var_create';
                +
                +/**
                + * Name of event that deletes a variable.
                + * @const
                + */
                +Blockly.Events.VAR_DELETE = 'var_delete';
                +
                +/**
                + * Name of event that renames a variable.
                + * @const
                + */
                +Blockly.Events.VAR_RENAME = 'var_rename';
                +
                +/**
                + * Name of event that records a UI change.
                + * @const
                + */
                +Blockly.Events.UI = 'ui';
                +
                +/**
                + * List of events queued for firing.
                + * @private
                + */
                +Blockly.Events.FIRE_QUEUE_ = [];
                +
                +/**
                + * Create a custom event and fire it.
                + * @param {!Blockly.Events.Abstract} event Custom data for event.
                + */
                +Blockly.Events.fire = function(event) {
                +  if (!Blockly.Events.isEnabled()) {
                +    return;
                +  }
                +  if (!Blockly.Events.FIRE_QUEUE_.length) {
                +    // First event added; schedule a firing of the event queue.
                +    setTimeout(Blockly.Events.fireNow_, 0);
                +  }
                +  Blockly.Events.FIRE_QUEUE_.push(event);
                +};
                +
                +/**
                + * Fire all queued events.
                + * @private
                + */
                +Blockly.Events.fireNow_ = function() {
                +  var queue = Blockly.Events.filter(Blockly.Events.FIRE_QUEUE_, true);
                +  Blockly.Events.FIRE_QUEUE_.length = 0;
                +  for (var i = 0, event; event = queue[i]; i++) {
                +    var workspace = Blockly.Workspace.getById(event.workspaceId);
                +    if (workspace) {
                +      workspace.fireChangeListener(event);
                +    }
                +  }
                +};
                +
                +/**
                + * Filter the queued events and merge duplicates.
                + * @param {!Array.<!Blockly.Events.Abstract>} queueIn Array of events.
                + * @param {boolean} forward True if forward (redo), false if backward (undo).
                + * @return {!Array.<!Blockly.Events.Abstract>} Array of filtered events.
                + */
                +Blockly.Events.filter = function(queueIn, forward) {
                +  var queue = goog.array.clone(queueIn);
                +  if (!forward) {
                +    // Undo is merged in reverse order.
                +    queue.reverse();
                +  }
                +  // Merge duplicates.  O(n^2), but n should be very small.
                +  for (var i = 0, event1; event1 = queue[i]; i++) {
                +    for (var j = i + 1, event2; event2 = queue[j]; j++) {
                +      if (event1.type == event2.type &&
                +          event1.blockId == event2.blockId &&
                +          event1.workspaceId == event2.workspaceId) {
                +        if (event1.type == Blockly.Events.MOVE) {
                +          // Merge move events.
                +          event1.newParentId = event2.newParentId;
                +          event1.newInputName = event2.newInputName;
                +          event1.newCoordinate = event2.newCoordinate;
                +          queue.splice(j, 1);
                +          j--;
                +        } else if (event1.type == Blockly.Events.CHANGE &&
                +            event1.element == event2.element &&
                +            event1.name == event2.name) {
                +          // Merge change events.
                +          event1.newValue = event2.newValue;
                +          queue.splice(j, 1);
                +          j--;
                +        } else if (event1.type == Blockly.Events.UI &&
                +            event2.element == 'click' &&
                +            (event1.element == 'commentOpen' ||
                +             event1.element == 'mutatorOpen' ||
                +             event1.element == 'warningOpen')) {
                +          // Merge change events.
                +          event1.newValue = event2.newValue;
                +          queue.splice(j, 1);
                +          j--;
                +        }
                +      }
                +    }
                +  }
                +  // Remove null events.
                +  for (var i = queue.length - 1; i >= 0; i--) {
                +    if (queue[i].isNull()) {
                +      queue.splice(i, 1);
                +    }
                +  }
                +  if (!forward) {
                +    // Restore undo order.
                +    queue.reverse();
                +  }
                +  // Move mutation events to the top of the queue.
                +  // Intentionally skip first event.
                +  for (var i = 1, event; event = queue[i]; i++) {
                +    if (event.type == Blockly.Events.CHANGE &&
                +        event.element == 'mutation') {
                +      queue.unshift(queue.splice(i, 1)[0]);
                +    }
                +  }
                +  return queue;
                +};
                +
                +/**
                + * Modify pending undo events so that when they are fired they don't land
                + * in the undo stack.  Called by Blockly.Workspace.clearUndo.
                + */
                +Blockly.Events.clearPendingUndo = function() {
                +  for (var i = 0, event; event = Blockly.Events.FIRE_QUEUE_[i]; i++) {
                +    event.recordUndo = false;
                +  }
                +};
                +
                +/**
                + * Stop sending events.  Every call to this function MUST also call enable.
                + */
                +Blockly.Events.disable = function() {
                +  Blockly.Events.disabled_++;
                +};
                +
                +/**
                + * Start sending events.  Unless events were already disabled when the
                + * corresponding call to disable was made.
                + */
                +Blockly.Events.enable = function() {
                +  Blockly.Events.disabled_--;
                +};
                +
                +/**
                + * Returns whether events may be fired or not.
                + * @return {boolean} True if enabled.
                + */
                +Blockly.Events.isEnabled = function() {
                +  return Blockly.Events.disabled_ == 0;
                +};
                +
                +/**
                + * Current group.
                + * @return {string} ID string.
                + */
                +Blockly.Events.getGroup = function() {
                +  return Blockly.Events.group_;
                +};
                +
                +/**
                + * Start or stop a group.
                + * @param {boolean|string} state True to start new group, false to end group.
                + *   String to set group explicitly.
                + */
                +Blockly.Events.setGroup = function(state) {
                +  if (typeof state == 'boolean') {
                +    Blockly.Events.group_ = state ? Blockly.utils.genUid() : '';
                +  } else {
                +    Blockly.Events.group_ = state;
                +  }
                +};
                +
                +/**
                + * Compute a list of the IDs of the specified block and all its descendants.
                + * @param {!Blockly.Block} block The root block.
                + * @return {!Array.<string>} List of block IDs.
                + * @private
                + */
                +Blockly.Events.getDescendantIds_ = function(block) {
                +  var ids = [];
                +  var descendants = block.getDescendants();
                +  for (var i = 0, descendant; descendant = descendants[i]; i++) {
                +    ids[i] = descendant.id;
                +  }
                +  return ids;
                +};
                +
                +/**
                + * Decode the JSON into an event.
                + * @param {!Object} json JSON representation.
                + * @param {!Blockly.Workspace} workspace Target workspace for event.
                + * @return {!Blockly.Events.Abstract} The event represented by the JSON.
                + */
                +Blockly.Events.fromJson = function(json, workspace) {
                +  var event;
                +  switch (json.type) {
                +    case Blockly.Events.CREATE:
                +      event = new Blockly.Events.Create(null);
                +      break;
                +    case Blockly.Events.DELETE:
                +      event = new Blockly.Events.Delete(null);
                +      break;
                +    case Blockly.Events.CHANGE:
                +      event = new Blockly.Events.Change(null);
                +      break;
                +    case Blockly.Events.MOVE:
                +      event = new Blockly.Events.Move(null);
                +      break;
                +    case Blockly.Events.VAR_CREATE:
                +      event = new Blockly.Events.VarCreate(null);
                +      break;
                +    case Blockly.Events.VAR_DELETE:
                +      event = new Blockly.Events.VarDelete(null);
                +      break;
                +    case Blockly.Events.VAR_RENAME:
                +      event = new Blockly.Events.VarRename(null);
                +      break;
                +    case Blockly.Events.UI:
                +      event = new Blockly.Events.Ui(null);
                +      break;
                +    default:
                +      throw 'Unknown event type.';
                +  }
                +  event.fromJson(json);
                +  event.workspaceId = workspace.id;
                +  return event;
                +};
                +
                +/**
                + * Abstract class for an event.
                + * @param {Blockly.Block|Blockly.VariableModel} elem The block or variable.
                + * @constructor
                + */
                +Blockly.Events.Abstract = function(elem) {
                +  if (elem instanceof Blockly.Block) {
                +    this.blockId = elem.id;
                +    this.workspaceId = elem.workspace.id;
                +  }
                +  else if (elem instanceof Blockly.VariableModel){
                +    this.workspaceId = elem.workspace.id;
                +    this.varId = elem.getId();
                +  }
                +  this.group = Blockly.Events.group_;
                +  this.recordUndo = Blockly.Events.recordUndo;
                +};
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Abstract.prototype.toJson = function() {
                +  var json = {
                +    'type': this.type
                +  };
                +  if (this.blockId) {
                +    json['blockId'] = this.blockId;
                +  }
                +  if (this.varId) {
                +    json['varId'] = this.varId;
                +  }
                +  if (this.group) {
                +    json['group'] = this.group;
                +  }
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Abstract.prototype.fromJson = function(json) {
                +  this.blockId = json['blockId'];
                +  this.varId = json['varId'];
                +  this.group = json['group'];
                +};
                +
                +/**
                + * Does this event record any change of state?
                + * @return {boolean} True if null, false if something changed.
                + */
                +Blockly.Events.Abstract.prototype.isNull = function() {
                +  return false;
                +};
                +
                +/**
                + * Run an event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.Abstract.prototype.run = function(forward) {
                +  // Defined by subclasses.
                +};
                +
                +/**
                + * Get workspace the event belongs to.
                + * @return {Blockly.Workspace} The workspace the event belongs to.
                + * @throws {Error} if workspace is null.
                + * @private
                + */
                +Blockly.Events.Abstract.prototype.getEventWorkspace_ = function() {
                +  var workspace = Blockly.Workspace.getById(this.workspaceId);
                +  if (!workspace) {
                +    throw Error('Workspace is null. Event must have been generated from real' +
                +      ' Blockly events.');
                +  }
                +  return workspace;
                +};
                +
                +/**
                + * Class for a block creation event.
                + * @param {Blockly.Block} block The created block.  Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.Create = function(block) {
                +  if (!block) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.Create.superClass_.constructor.call(this, block);
                +
                +  if (block.workspace.rendered) {
                +    this.xml = Blockly.Xml.blockToDomWithXY(block);
                +  } else {
                +    this.xml = Blockly.Xml.blockToDom(block);
                +  }
                +  this.ids = Blockly.Events.getDescendantIds_(block);
                +};
                +goog.inherits(Blockly.Events.Create, Blockly.Events.Abstract);
                +
                +/**
                + * Class for a block creation event.
                + * @param {Blockly.Block} block The created block. Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.BlockCreate = Blockly.Events.Create;
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.Create.prototype.type = Blockly.Events.CREATE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Create.prototype.toJson = function() {
                +  var json = Blockly.Events.Create.superClass_.toJson.call(this);
                +  json['xml'] = Blockly.Xml.domToText(this.xml);
                +  json['ids'] = this.ids;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Create.prototype.fromJson = function(json) {
                +  Blockly.Events.Create.superClass_.fromJson.call(this, json);
                +  this.xml = Blockly.Xml.textToDom('<xml>' + json['xml'] + '</xml>').firstChild;
                +  this.ids = json['ids'];
                +};
                +
                +/**
                + * Run a creation event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.Create.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  if (forward) {
                +    var xml = goog.dom.createDom('xml');
                +    xml.appendChild(this.xml);
                +    Blockly.Xml.domToWorkspace(xml, workspace);
                +  } else {
                +    for (var i = 0, id; id = this.ids[i]; i++) {
                +      var block = workspace.getBlockById(id);
                +      if (block) {
                +        block.dispose(false, false);
                +      } else if (id == this.blockId) {
                +        // Only complain about root-level block.
                +        console.warn("Can't uncreate non-existant block: " + id);
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Class for a block deletion event.
                + * @param {Blockly.Block} block The deleted block.  Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.Delete = function(block) {
                +  if (!block) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  if (block.getParent()) {
                +    throw 'Connected blocks cannot be deleted.';
                +  }
                +  Blockly.Events.Delete.superClass_.constructor.call(this, block);
                +
                +  if (block.workspace.rendered) {
                +    this.oldXml = Blockly.Xml.blockToDomWithXY(block);
                +  } else {
                +    this.oldXml = Blockly.Xml.blockToDom(block);
                +  }
                +  this.ids = Blockly.Events.getDescendantIds_(block);
                +};
                +goog.inherits(Blockly.Events.Delete, Blockly.Events.Abstract);
                +
                +/**
                + * Class for a block deletion event.
                + * @param {Blockly.Block} block The deleted block.  Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.BlockDelete = Blockly.Events.Delete;
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.Delete.prototype.type = Blockly.Events.DELETE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Delete.prototype.toJson = function() {
                +  var json = Blockly.Events.Delete.superClass_.toJson.call(this);
                +  json['ids'] = this.ids;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Delete.prototype.fromJson = function(json) {
                +  Blockly.Events.Delete.superClass_.fromJson.call(this, json);
                +  this.ids = json['ids'];
                +};
                +
                +/**
                + * Run a deletion event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.Delete.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  if (forward) {
                +    for (var i = 0, id; id = this.ids[i]; i++) {
                +      var block = workspace.getBlockById(id);
                +      if (block) {
                +        block.dispose(false, false);
                +      } else if (id == this.blockId) {
                +        // Only complain about root-level block.
                +        console.warn("Can't delete non-existant block: " + id);
                +      }
                +    }
                +  } else {
                +    var xml = goog.dom.createDom('xml');
                +    xml.appendChild(this.oldXml);
                +    Blockly.Xml.domToWorkspace(xml, workspace);
                +  }
                +};
                +
                +/**
                + * Class for a block change event.
                + * @param {Blockly.Block} block The changed block.  Null for a blank event.
                + * @param {string} element One of 'field', 'comment', 'disabled', etc.
                + * @param {?string} name Name of input or field affected, or null.
                + * @param {string} oldValue Previous value of element.
                + * @param {string} newValue New value of element.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.Change = function(block, element, name, oldValue, newValue) {
                +  if (!block) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.Change.superClass_.constructor.call(this, block);
                +  this.element = element;
                +  this.name = name;
                +  this.oldValue = oldValue;
                +  this.newValue = newValue;
                +};
                +goog.inherits(Blockly.Events.Change, Blockly.Events.Abstract);
                +
                +/**
                + * Class for a block change event.
                + * @param {Blockly.Block} block The changed block.  Null for a blank event.
                + * @param {string} element One of 'field', 'comment', 'disabled', etc.
                + * @param {?string} name Name of input or field affected, or null.
                + * @param {string} oldValue Previous value of element.
                + * @param {string} newValue New value of element.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.BlockChange = Blockly.Events.Change;
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.Change.prototype.type = Blockly.Events.CHANGE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Change.prototype.toJson = function() {
                +  var json = Blockly.Events.Change.superClass_.toJson.call(this);
                +  json['element'] = this.element;
                +  if (this.name) {
                +    json['name'] = this.name;
                +  }
                +  json['newValue'] = this.newValue;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Change.prototype.fromJson = function(json) {
                +  Blockly.Events.Change.superClass_.fromJson.call(this, json);
                +  this.element = json['element'];
                +  this.name = json['name'];
                +  this.newValue = json['newValue'];
                +};
                +
                +/**
                + * Does this event record any change of state?
                + * @return {boolean} True if something changed.
                + */
                +Blockly.Events.Change.prototype.isNull = function() {
                +  return this.oldValue == this.newValue;
                +};
                +
                +/**
                + * Run a change event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.Change.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  var block = workspace.getBlockById(this.blockId);
                +  if (!block) {
                +    console.warn("Can't change non-existant block: " + this.blockId);
                +    return;
                +  }
                +  if (block.mutator) {
                +    // Close the mutator (if open) since we don't want to update it.
                +    block.mutator.setVisible(false);
                +  }
                +  var value = forward ? this.newValue : this.oldValue;
                +  switch (this.element) {
                +    case 'field':
                +      var field = block.getField(this.name);
                +      if (field) {
                +        // Run the validator for any side-effects it may have.
                +        // The validator's opinion on validity is ignored.
                +        field.callValidator(value);
                +        field.setValue(value);
                +      } else {
                +        console.warn("Can't set non-existant field: " + this.name);
                +      }
                +      break;
                +    case 'comment':
                +      block.setCommentText(value || null);
                +      break;
                +    case 'collapsed':
                +      block.setCollapsed(value);
                +      break;
                +    case 'disabled':
                +      block.setDisabled(value);
                +      break;
                +    case 'inline':
                +      block.setInputsInline(value);
                +      break;
                +    case 'mutation':
                +      var oldMutation = '';
                +      if (block.mutationToDom) {
                +        var oldMutationDom = block.mutationToDom();
                +        oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
                +      }
                +      if (block.domToMutation) {
                +        value = value || '<mutation></mutation>';
                +        var dom = Blockly.Xml.textToDom('<xml>' + value + '</xml>');
                +        block.domToMutation(dom.firstChild);
                +      }
                +      Blockly.Events.fire(new Blockly.Events.Change(
                +          block, 'mutation', null, oldMutation, value));
                +      break;
                +    default:
                +      console.warn('Unknown change type: ' + this.element);
                +  }
                +};
                +
                +/**
                + * Class for a block move event.  Created before the move.
                + * @param {Blockly.Block} block The moved block.  Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.Move = function(block) {
                +  if (!block) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.Move.superClass_.constructor.call(this, block);
                +  var location = this.currentLocation_();
                +  this.oldParentId = location.parentId;
                +  this.oldInputName = location.inputName;
                +  this.oldCoordinate = location.coordinate;
                +};
                +goog.inherits(Blockly.Events.Move, Blockly.Events.Abstract);
                +
                +
                +/**
                + * Class for a block move event.  Created before the move.
                + * @param {Blockly.Block} block The moved block.  Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.BlockMove = Blockly.Events.Move;
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.Move.prototype.type = Blockly.Events.MOVE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Move.prototype.toJson = function() {
                +  var json = Blockly.Events.Move.superClass_.toJson.call(this);
                +  if (this.newParentId) {
                +    json['newParentId'] = this.newParentId;
                +  }
                +  if (this.newInputName) {
                +    json['newInputName'] = this.newInputName;
                +  }
                +  if (this.newCoordinate) {
                +    json['newCoordinate'] = Math.round(this.newCoordinate.x) + ',' +
                +        Math.round(this.newCoordinate.y);
                +  }
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Move.prototype.fromJson = function(json) {
                +  Blockly.Events.Move.superClass_.fromJson.call(this, json);
                +  this.newParentId = json['newParentId'];
                +  this.newInputName = json['newInputName'];
                +  if (json['newCoordinate']) {
                +    var xy = json['newCoordinate'].split(',');
                +    this.newCoordinate =
                +        new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1]));
                +  }
                +};
                +
                +/**
                + * Record the block's new location.  Called after the move.
                + */
                +Blockly.Events.Move.prototype.recordNew = function() {
                +  var location = this.currentLocation_();
                +  this.newParentId = location.parentId;
                +  this.newInputName = location.inputName;
                +  this.newCoordinate = location.coordinate;
                +};
                +
                +/**
                + * Returns the parentId and input if the block is connected,
                + *   or the XY location if disconnected.
                + * @return {!Object} Collection of location info.
                + * @private
                + */
                +Blockly.Events.Move.prototype.currentLocation_ = function() {
                +  var workspace = Blockly.Workspace.getById(this.workspaceId);
                +  var block = workspace.getBlockById(this.blockId);
                +  var location = {};
                +  var parent = block.getParent();
                +  if (parent) {
                +    location.parentId = parent.id;
                +    var input = parent.getInputWithBlock(block);
                +    if (input) {
                +      location.inputName = input.name;
                +    }
                +  } else {
                +    location.coordinate = block.getRelativeToSurfaceXY();
                +  }
                +  return location;
                +};
                +
                +/**
                + * Does this event record any change of state?
                + * @return {boolean} True if something changed.
                + */
                +Blockly.Events.Move.prototype.isNull = function() {
                +  return this.oldParentId == this.newParentId &&
                +      this.oldInputName == this.newInputName &&
                +      goog.math.Coordinate.equals(this.oldCoordinate, this.newCoordinate);
                +};
                +
                +/**
                + * Run a move event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.Move.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  var block = workspace.getBlockById(this.blockId);
                +  if (!block) {
                +    console.warn("Can't move non-existant block: " + this.blockId);
                +    return;
                +  }
                +  var parentId = forward ? this.newParentId : this.oldParentId;
                +  var inputName = forward ? this.newInputName : this.oldInputName;
                +  var coordinate = forward ? this.newCoordinate : this.oldCoordinate;
                +  var parentBlock = null;
                +  if (parentId) {
                +    parentBlock = workspace.getBlockById(parentId);
                +    if (!parentBlock) {
                +      console.warn("Can't connect to non-existant block: " + parentId);
                +      return;
                +    }
                +  }
                +  if (block.getParent()) {
                +    block.unplug();
                +  }
                +  if (coordinate) {
                +    var xy = block.getRelativeToSurfaceXY();
                +    block.moveBy(coordinate.x - xy.x, coordinate.y - xy.y);
                +  } else {
                +    var blockConnection = block.outputConnection || block.previousConnection;
                +    var parentConnection;
                +    if (inputName) {
                +      var input = parentBlock.getInput(inputName);
                +      if (input) {
                +        parentConnection = input.connection;
                +      }
                +    } else if (blockConnection.type == Blockly.PREVIOUS_STATEMENT) {
                +      parentConnection = parentBlock.nextConnection;
                +    }
                +    if (parentConnection) {
                +      blockConnection.connect(parentConnection);
                +    } else {
                +      console.warn("Can't connect to non-existant input: " + inputName);
                +    }
                +  }
                +};
                +
                +/**
                + * Class for a UI event.
                + * @param {Blockly.Block} block The affected block.
                + * @param {string} element One of 'selected', 'comment', 'mutator', etc.
                + * @param {string} oldValue Previous value of element.
                + * @param {string} newValue New value of element.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.Ui = function(block, element, oldValue, newValue) {
                +  Blockly.Events.Ui.superClass_.constructor.call(this, block);
                +  this.element = element;
                +  this.oldValue = oldValue;
                +  this.newValue = newValue;
                +  this.recordUndo = false;
                +};
                +goog.inherits(Blockly.Events.Ui, Blockly.Events.Abstract);
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.Ui.prototype.type = Blockly.Events.UI;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.Ui.prototype.toJson = function() {
                +  var json = Blockly.Events.Ui.superClass_.toJson.call(this);
                +  json['element'] = this.element;
                +  if (this.newValue !== undefined) {
                +    json['newValue'] = this.newValue;
                +  }
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.Ui.prototype.fromJson = function(json) {
                +  Blockly.Events.Ui.superClass_.fromJson.call(this, json);
                +  this.element = json['element'];
                +  this.newValue = json['newValue'];
                +};
                +
                +/**
                + * Class for a variable creation event.
                + * @param {Blockly.VariableModel} variable The created variable.
                + *     Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.VarCreate = function(variable) {
                +  if (!variable) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.VarCreate.superClass_.constructor.call(this, variable);
                +  this.varType = variable.type;
                +  this.varName = variable.name;
                +};
                +goog.inherits(Blockly.Events.VarCreate, Blockly.Events.Abstract);
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.VarCreate.prototype.type = Blockly.Events.VAR_CREATE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.VarCreate.prototype.toJson = function() {
                +  var json = Blockly.Events.VarCreate.superClass_.toJson.call(this);
                +  json['varType'] = this.varType;
                +  json['varName'] = this.varName;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.VarCreate.prototype.fromJson = function(json) {
                +  Blockly.Events.VarCreate.superClass_.fromJson.call(this, json);
                +  this.varType = json['varType'];
                +  this.varName = json['varName'];
                +};
                +
                +/**
                + * Run a variable creation event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.VarCreate.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  if (forward) {
                +    workspace.createVariable(this.varName, this.varType, this.varId);
                +  } else {
                +    workspace.deleteVariableById(this.varId);
                +  }
                +};
                +
                +/**
                + * Class for a variable deletion event.
                + * @param {Blockly.VariableModel} variable The deleted variable.
                + *     Null for a blank event.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.VarDelete = function(variable) {
                +  if (!variable) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.VarDelete.superClass_.constructor.call(this, variable);
                +  this.varType = variable.type;
                +  this.varName = variable.name;
                +};
                +goog.inherits(Blockly.Events.VarDelete, Blockly.Events.Abstract);
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.VarDelete.prototype.type = Blockly.Events.VAR_DELETE;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.VarDelete.prototype.toJson = function() {
                +  var json = Blockly.Events.VarDelete.superClass_.toJson.call(this);
                +  json['varType'] = this.varType;
                +  json['varName'] = this.varName;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.VarDelete.prototype.fromJson = function(json) {
                +  Blockly.Events.VarDelete.superClass_.fromJson.call(this, json);
                +  this.varType = json['varType'];
                +  this.varName = json['varName'];
                +};
                +
                +/**
                + * Run a variable deletion event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.VarDelete.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  if (forward) {
                +    workspace.deleteVariableById(this.varId);
                +  } else {
                +    workspace.createVariable(this.varName, this.varType, this.varId);
                +  }
                +};
                +
                +/**
                + * Class for a variable rename event.
                + * @param {Blockly.VariableModel} variable The renamed variable.
                + *     Null for a blank event.
                + * @param {string} newName The new name the variable will be changed to.
                + * @extends {Blockly.Events.Abstract}
                + * @constructor
                + */
                +Blockly.Events.VarRename = function(variable, newName) {
                +  if (!variable) {
                +    return;  // Blank event to be populated by fromJson.
                +  }
                +  Blockly.Events.VarRename.superClass_.constructor.call(this, variable);
                +  this.oldName = variable.name;
                +  this.newName = newName;
                +};
                +goog.inherits(Blockly.Events.VarRename, Blockly.Events.Abstract);
                +
                +/**
                + * Type of this event.
                + * @type {string}
                + */
                +Blockly.Events.VarRename.prototype.type = Blockly.Events.VAR_RENAME;
                +
                +/**
                + * Encode the event as JSON.
                + * @return {!Object} JSON representation.
                + */
                +Blockly.Events.VarRename.prototype.toJson = function() {
                +  var json = Blockly.Events.VarRename.superClass_.toJson.call(this);
                +  json['oldName'] = this.oldName;
                +  json['newName'] = this.newName;
                +  return json;
                +};
                +
                +/**
                + * Decode the JSON event.
                + * @param {!Object} json JSON representation.
                + */
                +Blockly.Events.VarRename.prototype.fromJson = function(json) {
                +  Blockly.Events.VarRename.superClass_.fromJson.call(this, json);
                +  this.oldName = json['oldName'];
                +  this.newName = json['newName'];
                +};
                +
                +/**
                + * Run a variable rename event.
                + * @param {boolean} forward True if run forward, false if run backward (undo).
                + */
                +Blockly.Events.VarRename.prototype.run = function(forward) {
                +  var workspace = this.getEventWorkspace_();
                +  if (forward) {
                +    workspace.renameVariableById(this.varId, this.newName);
                +  } else {
                +    workspace.renameVariableById(this.varId, this.oldName);
                +  }
                +};
                +
                +/**
                + * Enable/disable a block depending on whether it is properly connected.
                + * Use this on applications where all blocks should be connected to a top block.
                + * Recommend setting the 'disable' option to 'false' in the config so that
                + * users don't try to reenable disabled orphan blocks.
                + * @param {!Blockly.Events.Abstract} event Custom data for event.
                + */
                +Blockly.Events.disableOrphans = function(event) {
                +  if (event.type == Blockly.Events.MOVE ||
                +      event.type == Blockly.Events.CREATE) {
                +    Blockly.Events.disable();
                +    var workspace = Blockly.Workspace.getById(event.workspaceId);
                +    var block = workspace.getBlockById(event.blockId);
                +    if (block) {
                +      if (block.getParent() && !block.getParent().disabled) {
                +        var children = block.getDescendants();
                +        for (var i = 0, child; child = children[i]; i++) {
                +          child.setDisabled(false);
                +        }
                +      } else if ((block.outputConnection || block.previousConnection) &&
                +                 !workspace.isDragging()) {
                +        do {
                +          block.setDisabled(true);
                +          block = block.getNextBlock();
                +        } while (block);
                +      }
                +    }
                +    Blockly.Events.enable();
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/extensions.js b/blockly/webif/static/blockly/core/extensions.js
                new file mode 100644
                index 000000000..101fe9267
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/extensions.js
                @@ -0,0 +1,445 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Extensions are functions that help initialize blocks, usually
                + *      adding dynamic behavior such as onchange handlers and mutators. These
                + *      are applied using Block.applyExtension(), or the JSON "extensions"
                + *      array attribute.
                + * @author Anm@anm.me (Andrew n marshall)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Extensions
                + * @namespace
                + **/
                +goog.provide('Blockly.Extensions');
                +
                +
                +/**
                + * The set of all registered extensions, keyed by extension name/id.
                + * @private
                + */
                +Blockly.Extensions.ALL_ = {};
                +
                +/**
                + * The set of properties on a block that may only be set by a mutator.
                + * @type {!Array.<string>}
                + * @private
                + * @constant
                + */
                +Blockly.Extensions.MUTATOR_PROPERTIES_ =
                +    ['domToMutation', 'mutationToDom', 'compose', 'decompose'];
                +
                +/**
                + * Registers a new extension function. Extensions are functions that help
                + * initialize blocks, usually adding dynamic behavior such as onchange
                + * handlers and mutators. These are applied using Block.applyExtension(), or
                + * the JSON "extensions" array attribute.
                + * @param {string} name The name of this extension.
                + * @param {Function} initFn The function to initialize an extended block.
                + * @throws {Error} if the extension name is empty, the extension is already
                + *     registered, or extensionFn is not a function.
                + */
                +Blockly.Extensions.register = function(name, initFn) {
                +  if (!goog.isString(name) || goog.string.isEmptyOrWhitespace(name)) {
                +    throw new Error('Error: Invalid extension name "' + name + '"');
                +  }
                +  if (Blockly.Extensions.ALL_[name]) {
                +    throw new Error('Error: Extension "' + name + '" is already registered.');
                +  }
                +  if (!goog.isFunction(initFn)) {
                +    throw new Error('Error: Extension "' + name + '" must be a function');
                +  }
                +  Blockly.Extensions.ALL_[name] = initFn;
                +};
                +
                +/**
                + * Registers a new extension function that adds all key/value of mixinObj.
                + * @param {string} name The name of this extension.
                + * @param {!Object} mixinObj The values to mix in.
                + * @throws {Error} if the extension name is empty or the extension is already
                + *     registered.
                + */
                +Blockly.Extensions.registerMixin = function(name, mixinObj) {
                +  Blockly.Extensions.register(name, function() {
                +    this.mixin(mixinObj);
                +  });
                +};
                +
                +/**
                + * Registers a new extension function that adds a mutator to the block.
                + * At register time this performs some basic sanity checks on the mutator.
                + * The wrapper may also add a mutator dialog to the block, if both compose and
                + * decompose are defined on the mixin.
                + * @param {string} name The name of this mutator extension.
                + * @param {!Object} mixinObj The values to mix in.
                + * @param {(function())=} opt_helperFn An optional function to apply after mixing
                + *     in the object.
                + * @param {Array.<string>=} opt_blockList A list of blocks to appear in the
                + *     flyout of the mutator dialog.
                + * @throws {Error} if the mutation is invalid or can't be applied to the block.
                + */
                +Blockly.Extensions.registerMutator = function(name, mixinObj, opt_helperFn,
                +    opt_blockList) {
                +  var errorPrefix = 'Error when registering mutator "' + name + '": ';
                +
                +  // Sanity check the mixin object before registering it.
                +  Blockly.Extensions.checkHasFunction_(errorPrefix, mixinObj.domToMutation,
                +                                       'domToMutation');
                +  Blockly.Extensions.checkHasFunction_(errorPrefix, mixinObj.mutationToDom,
                +                                       'mutationToDom');
                +
                +  var hasMutatorDialog = Blockly.Extensions.checkMutatorDialog_(mixinObj,
                +    errorPrefix);
                +
                +  if (opt_helperFn && !goog.isFunction(opt_helperFn)) {
                +    throw new Error('Extension "' + name + '" is not a function');
                +  }
                +
                +  // Sanity checks passed.
                +  Blockly.Extensions.register(name, function() {
                +    if (hasMutatorDialog) {
                +      this.setMutator(new Blockly.Mutator(opt_blockList));
                +    }
                +    // Mixin the object.
                +    this.mixin(mixinObj);
                +
                +    if (opt_helperFn) {
                +      opt_helperFn.apply(this);
                +    }
                +  });
                +};
                +
                +/**
                + * Applies an extension method to a block. This should only be called during
                + * block construction.
                + * @param {string} name The name of the extension.
                + * @param {!Blockly.Block} block The block to apply the named extension to.
                + * @param {boolean} isMutator True if this extension defines a mutator.
                + * @throws {Error} if the extension is not found.
                + */
                +Blockly.Extensions.apply = function(name, block, isMutator) {
                +  var extensionFn = Blockly.Extensions.ALL_[name];
                +  if (!goog.isFunction(extensionFn)) {
                +    throw new Error('Error: Extension "' + name + '" not found.');
                +  }
                +  if (isMutator) {
                +    // Fail early if the block already has mutation properties.
                +    Blockly.Extensions.checkNoMutatorProperties_(name, block);
                +  } else {
                +    // Record the old properties so we can make sure they don't change after
                +    // applying the extension.
                +    var mutatorProperties = Blockly.Extensions.getMutatorProperties_(block);
                +  }
                +  extensionFn.apply(block);
                +
                +  if (isMutator) {
                +    var errorPrefix = 'Error after applying mutator "' + name + '": ';
                +    Blockly.Extensions.checkBlockHasMutatorProperties_(name, block, errorPrefix);
                +  } else {
                +    if (!Blockly.Extensions.mutatorPropertiesMatch_(mutatorProperties, block)) {
                +      throw new Error('Error when applying extension "' + name +
                +          '": mutation properties changed when applying a non-mutator extension.');
                +    }
                +  }
                +};
                +
                +/**
                + * Check that the given value is a function.
                + * @param {string} errorPrefix The string to prepend to any error message.
                + * @param {*} func Function to check.
                + * @param {string} propertyName Which property to check.
                + * @throws {Error} if the property does not exist or is not a function.
                + * @private
                + */
                +Blockly.Extensions.checkHasFunction_ = function(errorPrefix, func,
                +    propertyName) {
                +  if (!func) {
                +    throw new Error(errorPrefix +
                +        'missing required property "' + propertyName + '"');
                +  } else if (typeof func != 'function') {
                +    throw new Error(errorPrefix +
                +      '" required property "' + propertyName + '" must be a function');
                +  }
                +};
                +
                +/**
                + * Check that the given block does not have any of the four mutator properties
                + * defined on it.  This function should be called before applying a mutator
                + * extension to a block, to make sure we are not overwriting properties.
                + * @param {string} mutationName The name of the mutation to reference in error
                + *     messages.
                + * @param {!Blockly.Block} block The block to check.
                + * @throws {Error} if any of the properties already exist on the block.
                + * @private
                + */
                +Blockly.Extensions.checkNoMutatorProperties_ = function(mutationName, block) {
                +  for (var i = 0; i < Blockly.Extensions.MUTATOR_PROPERTIES_.length; i++) {
                +    var propertyName = Blockly.Extensions.MUTATOR_PROPERTIES_[i];
                +    if (block.hasOwnProperty(propertyName)) {
                +      throw new Error('Error: tried to apply mutation "' + mutationName +
                +          '" to a block that already has a "' + propertyName +
                +          '" function.  Block id: ' + block.id);
                +    }
                +  }
                +};
                +
                +/**
                + * Check that the given object has both or neither of the functions required
                + * to have a mutator dialog.
                + * These functions are 'compose' and 'decompose'.  If a block has one, it must
                + * have both.
                + * @param {!Object} object The object to check.
                + * @param {string} errorPrefix The string to prepend to any error message.
                + * @return {boolean} True if the object has both functions.  False if it has
                + *     neither function.
                + * @throws {Error} if the object has only one of the functions.
                + * @private
                + */
                +Blockly.Extensions.checkMutatorDialog_ = function(object, errorPrefix) {
                +  var hasCompose = object.hasOwnProperty('compose');
                +  var hasDecompose = object.hasOwnProperty('decompose');
                +
                +  if (hasCompose && hasDecompose) {
                +    if (typeof object['compose'] !== "function") {
                +      throw new Error(errorPrefix + 'compose must be a function.');
                +    } else if (typeof object['decompose'] !== "function") {
                +      throw new Error(errorPrefix + 'decompose must be a function.');
                +    }
                +    return true;
                +  } else if (!hasCompose && !hasDecompose) {
                +    return false;
                +  } else {
                +    throw new Error(errorPrefix +
                +        'Must have both or neither of "compose" and "decompose"');
                +  }
                +};
                +
                +/**
                + * Check that a block has required mutator properties.  This should be called
                + * after applying a mutation extension.
                + * @param {string} errorPrefix The string to prepend to any error message.
                + * @param {!Blockly.Block} block The block to inspect.
                + * @private
                + */
                +Blockly.Extensions.checkBlockHasMutatorProperties_ = function(errorPrefix,
                +    block) {
                +  if (!block.hasOwnProperty('domToMutation')) {
                +    throw new Error(errorPrefix + 'Applying a mutator didn\'t add "domToMutation"');
                +  }
                +  if (!block.hasOwnProperty('mutationToDom')) {
                +    throw new Error(errorPrefix + 'Applying a mutator didn\'t add "mutationToDom"');
                +  }
                +
                +  // A block with a mutator isn't required to have a mutation dialog, but
                +  // it should still have both or neither of compose and decompose.
                +  Blockly.Extensions.checkMutatorDialog_(block, errorPrefix);
                +};
                +
                +/**
                + * Get a list of values of mutator properties on the given block.
                + * @param {!Blockly.Block} block The block to inspect.
                + * @return {!Array.<Object>} a list with all of the properties, which should be
                + *     functions or undefined, but are not guaranteed to be.
                + * @private
                + */
                +Blockly.Extensions.getMutatorProperties_ = function(block) {
                +  var result = [];
                +  for (var i = 0; i < Blockly.Extensions.MUTATOR_PROPERTIES_.length; i++) {
                +    result.push(block[Blockly.Extensions.MUTATOR_PROPERTIES_[i]]);
                +  }
                +  return result;
                +};
                +
                +/**
                + * Check that the current mutator properties match a list of old mutator
                + * properties.  This should be called after applying a non-mutator extension,
                + * to verify that the extension didn't change properties it shouldn't.
                + * @param {!Array.<Object>} oldProperties The old values to compare to.
                + * @param {!Blockly.Block} block The block to inspect for new values.
                + * @return {boolean} True if the property lists match.
                + * @private
                + */
                +Blockly.Extensions.mutatorPropertiesMatch_ = function(oldProperties, block) {
                +  var match = true;
                +  var newProperties = Blockly.Extensions.getMutatorProperties_(block);
                +  if (newProperties.length != oldProperties.length) {
                +    match = false;
                +  } else {
                +    for (var i = 0; i < newProperties.length; i++) {
                +      if (oldProperties[i] != newProperties[i]) {
                +        match = false;
                +      }
                +    }
                +  }
                +
                +  return match;
                +};
                +
                +/**
                + * Builds an extension function that will map a dropdown value to a tooltip
                + * string.
                + *
                + * This method includes multiple checks to ensure tooltips, dropdown options,
                + * and message references are aligned. This aims to catch errors as early as
                + * possible, without requiring developers to manually test tooltips under each
                + * option. After the page is loaded, each tooltip text string will be checked
                + * for matching message keys in the internationalized string table. Deferring
                + * this until the page is loaded decouples loading dependencies. Later, upon
                + * loading the first block of any given type, the extension will validate every
                + * dropdown option has a matching tooltip in the lookupTable.  Errors are
                + * reported as warnings in the console, and are never fatal.
                + * @param {string} dropdownName The name of the field whose value is the key
                + *     to the lookup table.
                + * @param {!Object<string, string>} lookupTable The table of field values to
                + *     tooltip text.
                + * @return {Function} The extension function.
                + */
                +Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable) {
                +  // List of block types already validated, to minimize duplicate warnings.
                +  var blockTypesChecked = [];
                +
                +  // Check the tooltip string messages for invalid references.
                +  // Wait for load, in case Blockly.Msg is not yet populated.
                +  // runAfterPageLoad() does not run in a Node.js environment due to lack of
                +  // document object, in which case skip the validation.
                +  if (document) { // Relies on document.readyState
                +    Blockly.utils.runAfterPageLoad(function() {
                +      for (var key in lookupTable) {
                +        // Will print warnings is reference is missing.
                +        Blockly.utils.checkMessageReferences(lookupTable[key]);
                +      }
                +    });
                +  }
                +
                +  /**
                +   * The actual extension.
                +   * @this {Blockly.Block}
                +   */
                +  var extensionFn = function() {
                +    if (this.type && blockTypesChecked.indexOf(this.type) === -1) {
                +      Blockly.Extensions.checkDropdownOptionsInTable_(
                +        this, dropdownName, lookupTable);
                +      blockTypesChecked.push(this.type);
                +    }
                +
                +    this.setTooltip(function() {
                +      var value = this.getFieldValue(dropdownName);
                +      var tooltip = lookupTable[value];
                +      if (tooltip == null) {
                +        if (blockTypesChecked.indexOf(this.type) === -1) {
                +          // Warn for missing values on generated tooltips
                +          var warning = 'No tooltip mapping for value ' + value +
                +              ' of field ' + dropdownName;
                +          if (this.type != null) {
                +            warning += (' of block type ' + this.type);
                +          }
                +          console.warn(warning + '.');
                +        }
                +      } else {
                +        tooltip = Blockly.utils.replaceMessageReferences(tooltip);
                +      }
                +      return tooltip;
                +    }.bind(this));
                +  };
                +  return extensionFn;
                +};
                +
                +/**
                + * Checks all options keys are present in the provided string lookup table.
                + * Emits console warnings when they are not.
                + * @param {!Blockly.Block} block The block containing the dropdown
                + * @param {string} dropdownName The name of the dropdown
                + * @param {!Object<string, string>} lookupTable The string lookup table
                + * @private
                + */
                +Blockly.Extensions.checkDropdownOptionsInTable_ =
                +  function(block, dropdownName, lookupTable) {
                +    // Validate all dropdown options have values.
                +    var dropdown = block.getField(dropdownName);
                +    if (!dropdown.isOptionListDynamic()) {
                +      var options = dropdown.getOptions();
                +      for (var i = 0; i < options.length; ++i) {
                +        var optionKey = options[i][1]; // label, then value
                +        if (lookupTable[optionKey] == null) {
                +          console.warn('No tooltip mapping for value ' + optionKey +
                +            ' of field ' + dropdownName + ' of block type ' + block.type);
                +        }
                +      }
                +    }
                +  };
                +
                +/**
                + * Builds an extension function that will install a dynamic tooltip. The
                + * tooltip message should include the string '%1' and that string will be
                + * replaced with the value of the named field.
                + * @param {string} msgTemplate The template form to of the message text, with
                + *     %1 placeholder.
                + * @param {string} fieldName The field with the replacement value.
                + * @returns {Function} The extension function.
                + */
                +Blockly.Extensions.buildTooltipWithFieldValue =
                +  function(msgTemplate, fieldName) {
                +    // Check the tooltip string messages for invalid references.
                +    // Wait for load, in case Blockly.Msg is not yet populated.
                +    // runAfterPageLoad() does not run in a Node.js environment due to lack of
                +    // document object, in which case skip the validation.
                +    if (document) { // Relies on document.readyState
                +      Blockly.utils.runAfterPageLoad(function() {
                +        // Will print warnings is reference is missing.
                +        Blockly.utils.checkMessageReferences(msgTemplate);
                +      });
                +    }
                +
                +    /**
                +     * The actual extension.
                +     * @this {Blockly.Block}
                +     */
                +    var extensionFn = function() {
                +      this.setTooltip(function() {
                +        return Blockly.utils.replaceMessageReferences(msgTemplate)
                +            .replace('%1', this.getFieldValue(fieldName));
                +      }.bind(this));
                +    };
                +    return extensionFn;
                +  };
                +
                +/**
                + * Configures the tooltip to mimic the parent block when connected. Otherwise,
                + * uses the tooltip text at the time this extension is initialized. This takes
                + * advantage of the fact that all other values from JSON are initialized before
                + * extensions.
                + * @this {Blockly.Block}
                + * @private
                + */
                +Blockly.Extensions.extensionParentTooltip_ = function() {
                +  this.tooltipWhenNotConnected_ = this.tooltip;
                +  this.setTooltip(function() {
                +    var parent = this.getParent();
                +    return (parent &&
                +      parent.getInputsInline() &&
                +      parent.tooltip) ||
                +      this.tooltipWhenNotConnected_;
                +  }.bind(this));
                +};
                +Blockly.Extensions.register('parent_tooltip_when_inline',
                +    Blockly.Extensions.extensionParentTooltip_);
                diff --git a/blockly/webif/static/blockly/core/field.js b/blockly/webif/static/blockly/core/field.js
                new file mode 100644
                index 000000000..4060ac62b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field.js
                @@ -0,0 +1,537 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Field.  Used for editable titles, variables, etc.
                + * This is an abstract class that defines the UI on the block.  Actual
                + * instances would be Blockly.FieldTextInput, Blockly.FieldDropdown, etc.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Field');
                +
                +goog.require('Blockly.Gesture');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.dom');
                +goog.require('goog.math.Size');
                +goog.require('goog.style');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Abstract class for an editable field.
                + * @param {string} text The initial content of the field.
                + * @param {Function=} opt_validator An optional function that is called
                + *     to validate any constraints on what the user entered.  Takes the new
                + *     text as an argument and returns either the accepted text, a replacement
                + *     text, or null to abort the change.
                + * @constructor
                + */
                +Blockly.Field = function(text, opt_validator) {
                +  this.size_ = new goog.math.Size(0, Blockly.BlockSvg.MIN_BLOCK_Y);
                +  this.setValue(text);
                +  this.setValidator(opt_validator);
                +};
                +
                +/**
                + * Temporary cache of text widths.
                + * @type {Object}
                + * @private
                + */
                +Blockly.Field.cacheWidths_ = null;
                +
                +/**
                + * Number of current references to cache.
                + * @type {number}
                + * @private
                + */
                +Blockly.Field.cacheReference_ = 0;
                +
                +
                +/**
                + * Name of field.  Unique within each block.
                + * Static labels are usually unnamed.
                + * @type {string|undefined}
                + */
                +Blockly.Field.prototype.name = undefined;
                +
                +/**
                + * Maximum characters of text to display before adding an ellipsis.
                + * @type {number}
                + */
                +Blockly.Field.prototype.maxDisplayLength = 50;
                +
                +/**
                + * Visible text to display.
                + * @type {string}
                + * @private
                + */
                +Blockly.Field.prototype.text_ = '';
                +
                +/**
                + * Block this field is attached to.  Starts as null, then in set in init.
                + * @type {Blockly.Block}
                + * @private
                + */
                +Blockly.Field.prototype.sourceBlock_ = null;
                +
                +/**
                + * Is the field visible, or hidden due to the block being collapsed?
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Field.prototype.visible_ = true;
                +
                +/**
                + * Validation function called when user edits an editable field.
                + * @type {Function}
                + * @private
                + */
                +Blockly.Field.prototype.validator_ = null;
                +
                +/**
                + * Non-breaking space.
                + * @const
                + */
                +Blockly.Field.NBSP = '\u00A0';
                +
                +/**
                + * Editable fields are saved by the XML renderer, non-editable fields are not.
                + */
                +Blockly.Field.prototype.EDITABLE = true;
                +
                +/**
                + * Attach this field to a block.
                + * @param {!Blockly.Block} block The block containing this field.
                + */
                +Blockly.Field.prototype.setSourceBlock = function(block) {
                +  goog.asserts.assert(!this.sourceBlock_, 'Field already bound to a block.');
                +  this.sourceBlock_ = block;
                +};
                +
                +/**
                + * Install this field on a block.
                + */
                +Blockly.Field.prototype.init = function() {
                +  if (this.fieldGroup_) {
                +    // Field has already been initialized once.
                +    return;
                +  }
                +  // Build the DOM.
                +  this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null);
                +  if (!this.visible_) {
                +    this.fieldGroup_.style.display = 'none';
                +  }
                +  this.borderRect_ = Blockly.utils.createSvgElement('rect',
                +      {'rx': 4,
                +       'ry': 4,
                +       'x': -Blockly.BlockSvg.SEP_SPACE_X / 2,
                +       'y': 0,
                +       'height': 16}, this.fieldGroup_, this.sourceBlock_.workspace);
                +  /** @type {!Element} */
                +  this.textElement_ = Blockly.utils.createSvgElement('text',
                +      {'class': 'blocklyText', 'y': this.size_.height - 12.5},
                +      this.fieldGroup_);
                +
                +  this.updateEditable();
                +  this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
                +  this.mouseDownWrapper_ =
                +      Blockly.bindEventWithChecks_(this.fieldGroup_, 'mousedown', this,
                +      this.onMouseDown_);
                +  // Force a render.
                +  this.render_();
                +};
                +
                +/**
                + * Initializes the model of the field after it has been installed on a block.
                + * No-op by default.
                + */
                +Blockly.Field.prototype.initModel = function() {
                +};
                +
                +/**
                + * Dispose of all DOM objects belonging to this editable field.
                + */
                +Blockly.Field.prototype.dispose = function() {
                +  if (this.mouseDownWrapper_) {
                +    Blockly.unbindEvent_(this.mouseDownWrapper_);
                +    this.mouseDownWrapper_ = null;
                +  }
                +  this.sourceBlock_ = null;
                +  goog.dom.removeNode(this.fieldGroup_);
                +  this.fieldGroup_ = null;
                +  this.textElement_ = null;
                +  this.borderRect_ = null;
                +  this.validator_ = null;
                +};
                +
                +/**
                + * Add or remove the UI indicating if this field is editable or not.
                + */
                +Blockly.Field.prototype.updateEditable = function() {
                +  var group = this.fieldGroup_;
                +  if (!this.EDITABLE || !group) {
                +    return;
                +  }
                +  if (this.sourceBlock_.isEditable()) {
                +    Blockly.utils.addClass(group, 'blocklyEditableText');
                +    Blockly.utils.removeClass(group, 'blocklyNonEditableText');
                +    this.fieldGroup_.style.cursor = this.CURSOR;
                +  } else {
                +    Blockly.utils.addClass(group, 'blocklyNonEditableText');
                +    Blockly.utils.removeClass(group, 'blocklyEditableText');
                +    this.fieldGroup_.style.cursor = '';
                +  }
                +};
                +
                +/**
                + * Check whether this field is currently editable.  Some fields are never
                + * editable (e.g. text labels).  Those fields are not serialized to XML.  Other
                + * fields may be editable, and therefore serialized, but may exist on
                + * non-editable blocks.
                + * @return {boolean} whether this field is editable and on an editable block
                + */
                +Blockly.Field.prototype.isCurrentlyEditable = function() {
                +  return this.EDITABLE && !!this.sourceBlock_ && this.sourceBlock_.isEditable();
                +};
                +
                +/**
                + * Gets whether this editable field is visible or not.
                + * @return {boolean} True if visible.
                + */
                +Blockly.Field.prototype.isVisible = function() {
                +  return this.visible_;
                +};
                +
                +/**
                + * Sets whether this editable field is visible or not.
                + * @param {boolean} visible True if visible.
                + */
                +Blockly.Field.prototype.setVisible = function(visible) {
                +  if (this.visible_ == visible) {
                +    return;
                +  }
                +  this.visible_ = visible;
                +  var root = this.getSvgRoot();
                +  if (root) {
                +    root.style.display = visible ? 'block' : 'none';
                +    this.render_();
                +  }
                +};
                +
                +/**
                + * Sets a new validation function for editable fields.
                + * @param {Function} handler New validation function, or null.
                + */
                +Blockly.Field.prototype.setValidator = function(handler) {
                +  this.validator_ = handler;
                +};
                +
                +/**
                + * Gets the validation function for editable fields.
                + * @return {Function} Validation function, or null.
                + */
                +Blockly.Field.prototype.getValidator = function() {
                +  return this.validator_;
                +};
                +
                +/**
                + * Validates a change.  Does nothing.  Subclasses may override this.
                + * @param {string} text The user's text.
                + * @return {string} No change needed.
                + */
                +Blockly.Field.prototype.classValidator = function(text) {
                +  return text;
                +};
                +
                +/**
                + * Calls the validation function for this field, as well as all the validation
                + * function for the field's class and its parents.
                + * @param {string} text Proposed text.
                + * @return {?string} Revised text, or null if invalid.
                + */
                +Blockly.Field.prototype.callValidator = function(text) {
                +  var classResult = this.classValidator(text);
                +  if (classResult === null) {
                +    // Class validator rejects value.  Game over.
                +    return null;
                +  } else if (classResult !== undefined) {
                +    text = classResult;
                +  }
                +  var userValidator = this.getValidator();
                +  if (userValidator) {
                +    var userResult = userValidator.call(this, text);
                +    if (userResult === null) {
                +      // User validator rejects value.  Game over.
                +      return null;
                +    } else if (userResult !== undefined) {
                +      text = userResult;
                +    }
                +  }
                +  return text;
                +};
                +
                +/**
                + * Gets the group element for this editable field.
                + * Used for measuring the size and for positioning.
                + * @return {!Element} The group element.
                + */
                +Blockly.Field.prototype.getSvgRoot = function() {
                +  return /** @type {!Element} */ (this.fieldGroup_);
                +};
                +
                +/**
                + * Draws the border with the correct width.
                + * Saves the computed width in a property.
                + * @private
                + */
                +Blockly.Field.prototype.render_ = function() {
                +  if (!this.visible_) {
                +    this.size_.width = 0;
                +    return;
                +  }
                +
                +  // Replace the text.
                +  goog.dom.removeChildren(/** @type {!Element} */ (this.textElement_));
                +  var textNode = document.createTextNode(this.getDisplayText_());
                +  this.textElement_.appendChild(textNode);
                +
                +  this.updateWidth();
                +};
                +
                +/**
                + * Updates thw width of the field. This calls getCachedWidth which won't cache
                + * the approximated width on IE/Edge when `getComputedTextLength` fails. Once
                + * it eventually does succeed, the result will be cached.
                + **/
                +Blockly.Field.prototype.updateWidth = function() {
                +  var width = Blockly.Field.getCachedWidth(this.textElement_);
                +  if (this.borderRect_) {
                +    this.borderRect_.setAttribute('width',
                +        width + Blockly.BlockSvg.SEP_SPACE_X);
                +  }
                +  this.size_.width = width;
                +};
                +
                +/**
                + * Gets the width of a text element, caching it in the process.
                + * @param {!Element} textElement An SVG 'text' element.
                + * @return {number} Width of element.
                + */
                +Blockly.Field.getCachedWidth = function(textElement) {
                +  var key = textElement.textContent + '\n' + textElement.className.baseVal;
                +  var width;
                +
                +  // Return the cached width if it exists.
                +  if (Blockly.Field.cacheWidths_) {
                +    width = Blockly.Field.cacheWidths_[key];
                +    if (width) {
                +      return width;
                +    }
                +  }
                +
                +  // Attempt to compute fetch the width of the SVG text element.
                +  try {
                +    width = textElement.getComputedTextLength();
                +  } catch (e) {
                +    // MSIE 11 and Edge are known to throw "Unexpected call to method or
                +    // property access." if the block is hidden. Instead, use an
                +    // approximation and do not cache the result. At some later point in time
                +    // when the block is inserted into the visible DOM, this method will be
                +    // called again and, at that point in time, will not throw an exception.
                +    return textElement.textContent.length * 8;
                +  }
                +
                +  // Cache the computed width and return.
                +  if (Blockly.Field.cacheWidths_) {
                +    Blockly.Field.cacheWidths_[key] = width;
                +  }
                +  return width;
                +};
                +
                +/**
                + * Start caching field widths.  Every call to this function MUST also call
                + * stopCache.  Caches must not survive between execution threads.
                + */
                +Blockly.Field.startCache = function() {
                +  Blockly.Field.cacheReference_++;
                +  if (!Blockly.Field.cacheWidths_) {
                +    Blockly.Field.cacheWidths_ = {};
                +  }
                +};
                +
                +/**
                + * Stop caching field widths.  Unless caching was already on when the
                + * corresponding call to startCache was made.
                + */
                +Blockly.Field.stopCache = function() {
                +  Blockly.Field.cacheReference_--;
                +  if (!Blockly.Field.cacheReference_) {
                +    Blockly.Field.cacheWidths_ = null;
                +  }
                +};
                +
                +/**
                + * Returns the height and width of the field.
                + * @return {!goog.math.Size} Height and width.
                + */
                +Blockly.Field.prototype.getSize = function() {
                +  if (!this.size_.width) {
                +    this.render_();
                +  }
                +  return this.size_;
                +};
                +
                +/**
                + * Returns the height and width of the field,
                + * accounting for the workspace scaling.
                + * @return {!goog.math.Size} Height and width.
                + * @private
                + */
                +Blockly.Field.prototype.getScaledBBox_ = function() {
                +  var bBox = this.borderRect_.getBBox();
                +  // Create new object, as getBBox can return an uneditable SVGRect in IE.
                +  return new goog.math.Size(bBox.width * this.sourceBlock_.workspace.scale,
                +                            bBox.height * this.sourceBlock_.workspace.scale);
                +};
                +
                +/**
                + * Get the text from this field as displayed on screen.  May differ from getText
                + * due to ellipsis, and other formatting.
                + * @return {string} Currently displayed text.
                + * @private
                + */
                +Blockly.Field.prototype.getDisplayText_ = function() {
                +  var text = this.text_;
                +  if (!text) {
                +    // Prevent the field from disappearing if empty.
                +    return Blockly.Field.NBSP;
                +  }
                +  if (text.length > this.maxDisplayLength) {
                +    // Truncate displayed string and add an ellipsis ('...').
                +    text = text.substring(0, this.maxDisplayLength - 2) + '\u2026';
                +  }
                +  // Replace whitespace with non-breaking spaces so the text doesn't collapse.
                +  text = text.replace(/\s/g, Blockly.Field.NBSP);
                +  if (this.sourceBlock_.RTL) {
                +    // The SVG is LTR, force text to be RTL.
                +    text += '\u200F';
                +  }
                +  return text;
                +};
                +
                +/**
                + * Get the text from this field.
                + * @return {string} Current text.
                + */
                +Blockly.Field.prototype.getText = function() {
                +  return this.text_;
                +};
                +
                +/**
                + * Set the text in this field.  Trigger a rerender of the source block.
                + * @param {*} newText New text.
                + */
                +Blockly.Field.prototype.setText = function(newText) {
                +  if (newText === null) {
                +    // No change if null.
                +    return;
                +  }
                +  newText = String(newText);
                +  if (newText === this.text_) {
                +    // No change.
                +    return;
                +  }
                +  this.text_ = newText;
                +  // Set width to 0 to force a rerender of this field.
                +  this.size_.width = 0;
                +
                +  if (this.sourceBlock_ && this.sourceBlock_.rendered) {
                +    this.sourceBlock_.render();
                +    this.sourceBlock_.bumpNeighbours_();
                +  }
                +};
                +
                +/**
                + * By default there is no difference between the human-readable text and
                + * the language-neutral values.  Subclasses (such as dropdown) may define this.
                + * @return {string} Current value.
                + */
                +Blockly.Field.prototype.getValue = function() {
                +  return this.getText();
                +};
                +
                +/**
                + * By default there is no difference between the human-readable text and
                + * the language-neutral values.  Subclasses (such as dropdown) may define this.
                + * @param {string} newValue New value.
                + */
                +Blockly.Field.prototype.setValue = function(newValue) {
                +  if (newValue === null) {
                +    // No change if null.
                +    return;
                +  }
                +  var oldValue = this.getValue();
                +  if (oldValue == newValue) {
                +    return;
                +  }
                +  if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this.sourceBlock_, 'field', this.name, oldValue, newValue));
                +  }
                +  this.setText(newValue);
                +};
                +
                +/**
                + * Handle a mouse down event on a field.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Field.prototype.onMouseDown_ = function(e) {
                +  if (!this.sourceBlock_ || !this.sourceBlock_.workspace) {
                +    return;
                +  }
                +  var gesture = this.sourceBlock_.workspace.getGesture(e);
                +  if (gesture) {
                +    gesture.setStartField(this);
                +  }
                +};
                +
                +
                +/**
                + * Change the tooltip text for this field.
                + * @param {string|!Element} newTip Text for tooltip or a parent element to
                + *     link to for its tooltip.
                + */
                +Blockly.Field.prototype.setTooltip = function(newTip) {
                +  // Non-abstract sub-classes may wish to implement this.  See FieldLabel.
                +};
                +
                +/**
                + * Return the absolute coordinates of the top-left corner of this field.
                + * The origin (0,0) is the top-left corner of the page body.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties.
                + * @private
                + */
                +Blockly.Field.prototype.getAbsoluteXY_ = function() {
                +  return goog.style.getPageOffset(this.borderRect_);
                +};
                diff --git a/blockly/webif/static/blockly/core/field_angle.js b/blockly/webif/static/blockly/core/field_angle.js
                new file mode 100644
                index 000000000..55b15d263
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_angle.js
                @@ -0,0 +1,320 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Angle input field.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldAngle');
                +
                +goog.require('Blockly.FieldTextInput');
                +goog.require('goog.math');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for an editable angle field.
                + * @param {(string|number)=} opt_value The initial content of the field. The
                + *     value should cast to a number, and if it does not, '0' will be used.
                + * @param {Function=} opt_validator An optional function that is called
                + *     to validate any constraints on what the user entered.  Takes the new
                + *     text as an argument and returns the accepted text or null to abort
                + *     the change.
                + * @extends {Blockly.FieldTextInput}
                + * @constructor
                + */
                +Blockly.FieldAngle = function(opt_value, opt_validator) {
                +  // Add degree symbol: '360°' (LTR) or '°360' (RTL)
                +  this.symbol_ = Blockly.utils.createSvgElement('tspan', {}, null);
                +  this.symbol_.appendChild(document.createTextNode('\u00B0'));
                +
                +  opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0';
                +  Blockly.FieldAngle.superClass_.constructor.call(
                +      this, opt_value, opt_validator);
                +};
                +goog.inherits(Blockly.FieldAngle, Blockly.FieldTextInput);
                +
                +/**
                + * Round angles to the nearest 15 degrees when using mouse.
                + * Set to 0 to disable rounding.
                + */
                +Blockly.FieldAngle.ROUND = 15;
                +
                +/**
                + * Half the width of protractor image.
                + */
                +Blockly.FieldAngle.HALF = 100 / 2;
                +
                +/* The following two settings work together to set the behaviour of the angle
                + * picker.  While many combinations are possible, two modes are typical:
                + * Math mode.
                + *   0 deg is right, 90 is up.  This is the style used by protractors.
                + *   Blockly.FieldAngle.CLOCKWISE = false;
                + *   Blockly.FieldAngle.OFFSET = 0;
                + * Compass mode.
                + *   0 deg is up, 90 is right.  This is the style used by maps.
                + *   Blockly.FieldAngle.CLOCKWISE = true;
                + *   Blockly.FieldAngle.OFFSET = 90;
                + */
                +
                +/**
                + * Angle increases clockwise (true) or counterclockwise (false).
                + */
                +Blockly.FieldAngle.CLOCKWISE = false;
                +
                +/**
                + * Offset the location of 0 degrees (and all angles) by a constant.
                + * Usually either 0 (0 = right) or 90 (0 = up).
                + */
                +Blockly.FieldAngle.OFFSET = 0;
                +
                +/**
                + * Maximum allowed angle before wrapping.
                + * Usually either 360 (for 0 to 359.9) or 180 (for -179.9 to 180).
                + */
                +Blockly.FieldAngle.WRAP = 360;
                +
                +/**
                + * Radius of protractor circle.  Slightly smaller than protractor size since
                + * otherwise SVG crops off half the border at the edges.
                + */
                +Blockly.FieldAngle.RADIUS = Blockly.FieldAngle.HALF - 1;
                +
                +/**
                + * Adds degree symbol and recalculates width.
                + * Saves the computed width in a property.
                + * @private
                + */
                +Blockly.FieldAngle.prototype.render_ = function() {
                +  if (!this.visible_) {
                +    this.size_.width = 0;
                +    return;
                +  }
                +
                +  // Update textElement.
                +  this.textElement_.textContent = this.getDisplayText_();
                +  
                +  // Insert degree symbol.
                +  if (this.sourceBlock_.RTL) {
                +     this.textElement_.insertBefore(this.symbol_, this.textElement_.firstChild);
                +   } else {
                +     this.textElement_.appendChild(this.symbol_);
                +   }
                +  this.updateWidth();
                +};
                +
                +/**
                + * Clean up this FieldAngle, as well as the inherited FieldTextInput.
                + * @return {!Function} Closure to call on destruction of the WidgetDiv.
                + * @private
                + */
                +Blockly.FieldAngle.prototype.dispose_ = function() {
                +  var thisField = this;
                +  return function() {
                +    Blockly.FieldAngle.superClass_.dispose_.call(thisField)();
                +    thisField.gauge_ = null;
                +    if (thisField.clickWrapper_) {
                +      Blockly.unbindEvent_(thisField.clickWrapper_);
                +    }
                +    if (thisField.moveWrapper1_) {
                +      Blockly.unbindEvent_(thisField.moveWrapper1_);
                +    }
                +    if (thisField.moveWrapper2_) {
                +      Blockly.unbindEvent_(thisField.moveWrapper2_);
                +    }
                +  };
                +};
                +
                +/**
                + * Show the inline free-text editor on top of the text.
                + * @private
                + */
                +Blockly.FieldAngle.prototype.showEditor_ = function() {
                +  var noFocus =
                +      goog.userAgent.MOBILE || goog.userAgent.ANDROID || goog.userAgent.IPAD;
                +  // Mobile browsers have issues with in-line textareas (focus & keyboards).
                +  Blockly.FieldAngle.superClass_.showEditor_.call(this, noFocus);
                +  var div = Blockly.WidgetDiv.DIV;
                +  if (!div.firstChild) {
                +    // Mobile interface uses Blockly.prompt.
                +    return;
                +  }
                +  // Build the SVG DOM.
                +  var svg = Blockly.utils.createSvgElement('svg', {
                +    'xmlns': 'http://www.w3.org/2000/svg',
                +    'xmlns:html': 'http://www.w3.org/1999/xhtml',
                +    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
                +    'version': '1.1',
                +    'height': (Blockly.FieldAngle.HALF * 2) + 'px',
                +    'width': (Blockly.FieldAngle.HALF * 2) + 'px'
                +  }, div);
                +  var circle = Blockly.utils.createSvgElement('circle', {
                +    'cx': Blockly.FieldAngle.HALF, 'cy': Blockly.FieldAngle.HALF,
                +    'r': Blockly.FieldAngle.RADIUS,
                +    'class': 'blocklyAngleCircle'
                +  }, svg);
                +  this.gauge_ = Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyAngleGauge'}, svg);
                +  this.line_ = Blockly.utils.createSvgElement('line',{
                +      'x1': Blockly.FieldAngle.HALF,
                +      'y1': Blockly.FieldAngle.HALF,
                +      'class': 'blocklyAngleLine',
                +     }, svg);
                +  // Draw markers around the edge.
                +  for (var angle = 0; angle < 360; angle += 15) {
                +    Blockly.utils.createSvgElement('line', {
                +      'x1': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS,
                +      'y1': Blockly.FieldAngle.HALF,
                +      'x2': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS -
                +          (angle % 45 == 0 ? 10 : 5),
                +      'y2': Blockly.FieldAngle.HALF,
                +      'class': 'blocklyAngleMarks',
                +      'transform': 'rotate(' + angle + ',' +
                +          Blockly.FieldAngle.HALF + ',' + Blockly.FieldAngle.HALF + ')'
                +    }, svg);
                +  }
                +  svg.style.marginLeft = (15 - Blockly.FieldAngle.RADIUS) + 'px';
                +
                +  // The angle picker is different from other fields in that it updates on
                +  // mousemove even if it's not in the middle of a drag.  In future we may
                +  // change this behavior.  For now, using bindEvent_ instead of
                +  // bindEventWithChecks_ allows it to work without a mousedown/touchstart.
                +  this.clickWrapper_ =
                +      Blockly.bindEvent_(svg, 'click', this, Blockly.WidgetDiv.hide);
                +  this.moveWrapper1_ =
                +      Blockly.bindEvent_(circle, 'mousemove', this, this.onMouseMove);
                +  this.moveWrapper2_ =
                +      Blockly.bindEvent_(this.gauge_, 'mousemove', this,
                +      this.onMouseMove);
                +  this.updateGraph_();
                +};
                +
                +/**
                + * Set the angle to match the mouse's position.
                + * @param {!Event} e Mouse move event.
                + */
                +Blockly.FieldAngle.prototype.onMouseMove = function(e) {
                +  var bBox = this.gauge_.ownerSVGElement.getBoundingClientRect();
                +  var dx = e.clientX - bBox.left - Blockly.FieldAngle.HALF;
                +  var dy = e.clientY - bBox.top - Blockly.FieldAngle.HALF;
                +  var angle = Math.atan(-dy / dx);
                +  if (isNaN(angle)) {
                +    // This shouldn't happen, but let's not let this error propagate further.
                +    return;
                +  }
                +  angle = goog.math.toDegrees(angle);
                +  // 0: East, 90: North, 180: West, 270: South.
                +  if (dx < 0) {
                +    angle += 180;
                +  } else if (dy > 0) {
                +    angle += 360;
                +  }
                +  if (Blockly.FieldAngle.CLOCKWISE) {
                +    angle = Blockly.FieldAngle.OFFSET + 360 - angle;
                +  } else {
                +    angle -= Blockly.FieldAngle.OFFSET;
                +  }
                +  if (Blockly.FieldAngle.ROUND) {
                +    angle = Math.round(angle / Blockly.FieldAngle.ROUND) *
                +        Blockly.FieldAngle.ROUND;
                +  }
                +  angle = this.callValidator(angle);
                +  Blockly.FieldTextInput.htmlInput_.value = angle;
                +  this.setValue(angle);
                +  this.validate_();
                +  this.resizeEditor_();
                +};
                +
                +/**
                + * Insert a degree symbol.
                + * @param {?string} text New text.
                + */
                +Blockly.FieldAngle.prototype.setText = function(text) {
                +  Blockly.FieldAngle.superClass_.setText.call(this, text);
                +  if (!this.textElement_) {
                +    // Not rendered yet.
                +    return;
                +  }
                +  this.updateGraph_();
                +  // Cached width is obsolete.  Clear it.
                +  this.size_.width = 0;
                +};
                +
                +/**
                + * Redraw the graph with the current angle.
                + * @private
                + */
                +Blockly.FieldAngle.prototype.updateGraph_ = function() {
                +  if (!this.gauge_) {
                +    return;
                +  }
                +  var angleDegrees = Number(this.getText()) + Blockly.FieldAngle.OFFSET;
                +  var angleRadians = goog.math.toRadians(angleDegrees);
                +  var path = ['M ', Blockly.FieldAngle.HALF, ',', Blockly.FieldAngle.HALF];
                +  var x2 = Blockly.FieldAngle.HALF;
                +  var y2 = Blockly.FieldAngle.HALF;
                +  if (!isNaN(angleRadians)) {
                +    var angle1 = goog.math.toRadians(Blockly.FieldAngle.OFFSET);
                +    var x1 = Math.cos(angle1) * Blockly.FieldAngle.RADIUS;
                +    var y1 = Math.sin(angle1) * -Blockly.FieldAngle.RADIUS;
                +    if (Blockly.FieldAngle.CLOCKWISE) {
                +      angleRadians = 2 * angle1 - angleRadians;
                +    }
                +    x2 += Math.cos(angleRadians) * Blockly.FieldAngle.RADIUS;
                +    y2 -= Math.sin(angleRadians) * Blockly.FieldAngle.RADIUS;
                +    // Don't ask how the flag calculations work.  They just do.
                +    var largeFlag = Math.abs(Math.floor((angleRadians - angle1) / Math.PI) % 2);
                +    if (Blockly.FieldAngle.CLOCKWISE) {
                +      largeFlag = 1 - largeFlag;
                +    }
                +    var sweepFlag = Number(Blockly.FieldAngle.CLOCKWISE);
                +    path.push(' l ', x1, ',', y1,
                +        ' A ', Blockly.FieldAngle.RADIUS, ',', Blockly.FieldAngle.RADIUS,
                +        ' 0 ', largeFlag, ' ', sweepFlag, ' ', x2, ',', y2, ' z');
                +  }
                +  this.gauge_.setAttribute('d', path.join(''));
                +  this.line_.setAttribute('x2', x2);
                +  this.line_.setAttribute('y2', y2);
                +};
                +
                +/**
                + * Ensure that only an angle may be entered.
                + * @param {string} text The user's text.
                + * @return {?string} A string representing a valid angle, or null if invalid.
                + */
                +Blockly.FieldAngle.prototype.classValidator = function(text) {
                +  if (text === null) {
                +    return null;
                +  }
                +  var n = parseFloat(text || 0);
                +  if (isNaN(n)) {
                +    return null;
                +  }
                +  n = n % 360;
                +  if (n < 0) {
                +    n += 360;
                +  }
                +  if (n > Blockly.FieldAngle.WRAP) {
                +    n -= 360;
                +  }
                +  return String(n);
                +};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/core/field_checkbox.js b/blockly/webif/static/blockly/core/field_checkbox.js
                new file mode 100644
                index 000000000..0f2c78c6a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_checkbox.js
                @@ -0,0 +1,119 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Checkbox field.  Checked or not checked.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldCheckbox');
                +
                +goog.require('Blockly.Field');
                +
                +
                +/**
                + * Class for a checkbox field.
                + * @param {string} state The initial state of the field ('TRUE' or 'FALSE').
                + * @param {Function=} opt_validator A function that is executed when a new
                + *     option is selected.  Its sole argument is the new checkbox state.  If
                + *     it returns a value, this becomes the new checkbox state, unless the
                + *     value is null, in which case the change is aborted.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldCheckbox = function(state, opt_validator) {
                +  Blockly.FieldCheckbox.superClass_.constructor.call(this, '', opt_validator);
                +  // Set the initial state.
                +  this.setValue(state);
                +};
                +goog.inherits(Blockly.FieldCheckbox, Blockly.Field);
                +
                +/**
                + * Character for the checkmark.
                + */
                +Blockly.FieldCheckbox.CHECK_CHAR = '\u2713';
                +
                +/**
                + * Mouse cursor style when over the hotspot that initiates editability.
                + */
                +Blockly.FieldCheckbox.prototype.CURSOR = 'default';
                +
                +/**
                + * Install this checkbox on a block.
                + */
                +Blockly.FieldCheckbox.prototype.init = function() {
                +  if (this.fieldGroup_) {
                +    // Checkbox has already been initialized once.
                +    return;
                +  }
                +  Blockly.FieldCheckbox.superClass_.init.call(this);
                +  // The checkbox doesn't use the inherited text element.
                +  // Instead it uses a custom checkmark element that is either visible or not.
                +  this.checkElement_ = Blockly.utils.createSvgElement('text',
                +      {'class': 'blocklyText blocklyCheckbox', 'x': -3, 'y': 14},
                +      this.fieldGroup_);
                +  var textNode = document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR);
                +  this.checkElement_.appendChild(textNode);
                +  this.checkElement_.style.display = this.state_ ? 'block' : 'none';
                +};
                +
                +/**
                + * Return 'TRUE' if the checkbox is checked, 'FALSE' otherwise.
                + * @return {string} Current state.
                + */
                +Blockly.FieldCheckbox.prototype.getValue = function() {
                +  return String(this.state_).toUpperCase();
                +};
                +
                +/**
                + * Set the checkbox to be checked if newBool is 'TRUE' or true,
                + * unchecks otherwise.
                + * @param {string|boolean} newBool New state.
                + */
                +Blockly.FieldCheckbox.prototype.setValue = function(newBool) {
                +  var newState = (typeof newBool == 'string') ?
                +      (newBool.toUpperCase() == 'TRUE') : !!newBool;
                +  if (this.state_ !== newState) {
                +    if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                +      Blockly.Events.fire(new Blockly.Events.BlockChange(
                +          this.sourceBlock_, 'field', this.name, this.state_, newState));
                +    }
                +    this.state_ = newState;
                +    if (this.checkElement_) {
                +      this.checkElement_.style.display = newState ? 'block' : 'none';
                +    }
                +  }
                +};
                +
                +/**
                + * Toggle the state of the checkbox.
                + * @private
                + */
                +Blockly.FieldCheckbox.prototype.showEditor_ = function() {
                +  var newState = !this.state_;
                +  if (this.sourceBlock_) {
                +    // Call any validation function, and allow it to override.
                +    newState = this.callValidator(newState);
                +  }
                +  if (newState !== null) {
                +    this.setValue(String(newState).toUpperCase());
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/field_colour.js b/blockly/webif/static/blockly/core/field_colour.js
                new file mode 100644
                index 000000000..425e4a35c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_colour.js
                @@ -0,0 +1,235 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Colour input field.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldColour');
                +
                +goog.require('Blockly.Field');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.style');
                +goog.require('goog.ui.ColorPicker');
                +
                +
                +/**
                + * Class for a colour input field.
                + * @param {string} colour The initial colour in '#rrggbb' format.
                + * @param {Function=} opt_validator A function that is executed when a new
                + *     colour is selected.  Its sole argument is the new colour value.  Its
                + *     return value becomes the selected colour, unless it is undefined, in
                + *     which case the new colour stands, or it is null, in which case the change
                + *     is aborted.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldColour = function(colour, opt_validator) {
                +  Blockly.FieldColour.superClass_.constructor.call(this, colour, opt_validator);
                +  this.setText(Blockly.Field.NBSP + Blockly.Field.NBSP + Blockly.Field.NBSP);
                +};
                +goog.inherits(Blockly.FieldColour, Blockly.Field);
                +
                +/**
                + * By default use the global constants for colours.
                + * @type {Array.<string>}
                + * @private
                + */
                +Blockly.FieldColour.prototype.colours_ = null;
                +
                +/**
                + * By default use the global constants for columns.
                + * @type {number}
                + * @private
                + */
                +Blockly.FieldColour.prototype.columns_ = 0;
                +
                +/**
                + * Install this field on a block.
                + */
                +Blockly.FieldColour.prototype.init = function() {
                +  Blockly.FieldColour.superClass_.init.call(this);
                +  this.borderRect_.style['fillOpacity'] = 1;
                +  this.setValue(this.getValue());
                +};
                +
                +/**
                + * Mouse cursor style when over the hotspot that initiates the editor.
                + */
                +Blockly.FieldColour.prototype.CURSOR = 'default';
                +
                +/**
                + * Close the colour picker if this input is being deleted.
                + */
                +Blockly.FieldColour.prototype.dispose = function() {
                +  Blockly.WidgetDiv.hideIfOwner(this);
                +  Blockly.FieldColour.superClass_.dispose.call(this);
                +};
                +
                +/**
                + * Return the current colour.
                + * @return {string} Current colour in '#rrggbb' format.
                + */
                +Blockly.FieldColour.prototype.getValue = function() {
                +  return this.colour_;
                +};
                +
                +/**
                + * Set the colour.
                + * @param {string} colour The new colour in '#rrggbb' format.
                + */
                +Blockly.FieldColour.prototype.setValue = function(colour) {
                +  if (this.sourceBlock_ && Blockly.Events.isEnabled() &&
                +      this.colour_ != colour) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this.sourceBlock_, 'field', this.name, this.colour_, colour));
                +  }
                +  this.colour_ = colour;
                +  if (this.borderRect_) {
                +    this.borderRect_.style.fill = colour;
                +  }
                +};
                +
                +/**
                + * Get the text from this field.  Used when the block is collapsed.
                + * @return {string} Current text.
                + */
                +Blockly.FieldColour.prototype.getText = function() {
                +  var colour = this.colour_;
                +  // Try to use #rgb format if possible, rather than #rrggbb.
                +  var m = colour.match(/^#(.)\1(.)\2(.)\3$/);
                +  if (m) {
                +    colour = '#' + m[1] + m[2] + m[3];
                +  }
                +  return colour;
                +};
                +
                +/**
                + * An array of colour strings for the palette.
                + * See bottom of this page for the default:
                + * http://docs.closure-library.googlecode.com/git/closure_goog_ui_colorpicker.js.source.html
                + * @type {!Array.<string>}
                + */
                +Blockly.FieldColour.COLOURS = goog.ui.ColorPicker.SIMPLE_GRID_COLORS;
                +
                +/**
                + * Number of columns in the palette.
                + */
                +Blockly.FieldColour.COLUMNS = 7;
                +
                +/**
                + * Set a custom colour grid for this field.
                + * @param {Array.<string>} colours Array of colours for this block,
                + *     or null to use default (Blockly.FieldColour.COLOURS).
                + * @return {!Blockly.FieldColour} Returns itself (for method chaining).
                + */
                +Blockly.FieldColour.prototype.setColours = function(colours) {
                +  this.colours_ = colours;
                +  return this;
                +};
                +
                +/**
                + * Set a custom grid size for this field.
                + * @param {number} columns Number of columns for this block,
                + *     or 0 to use default (Blockly.FieldColour.COLUMNS).
                + * @return {!Blockly.FieldColour} Returns itself (for method chaining).
                + */
                +Blockly.FieldColour.prototype.setColumns = function(columns) {
                +  this.columns_ = columns;
                +  return this;
                +};
                +
                +/**
                + * Create a palette under the colour field.
                + * @private
                + */
                +Blockly.FieldColour.prototype.showEditor_ = function() {
                +  Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL,
                +      Blockly.FieldColour.widgetDispose_);
                +  // Create the palette using Closure.
                +  var picker = new goog.ui.ColorPicker();
                +  picker.setSize(this.columns_ || Blockly.FieldColour.COLUMNS);
                +  picker.setColors(this.colours_ || Blockly.FieldColour.COLOURS);
                +
                +  // Position the palette to line up with the field.
                +  // Record windowSize and scrollOffset before adding the palette.
                +  var windowSize = goog.dom.getViewportSize();
                +  var scrollOffset = goog.style.getViewportPageOffset(document);
                +  var xy = this.getAbsoluteXY_();
                +  var borderBBox = this.getScaledBBox_();
                +  var div = Blockly.WidgetDiv.DIV;
                +  picker.render(div);
                +  picker.setSelectedColor(this.getValue());
                +  // Record paletteSize after adding the palette.
                +  var paletteSize = goog.style.getSize(picker.getElement());
                +
                +  // Flip the palette vertically if off the bottom.
                +  if (xy.y + paletteSize.height + borderBBox.height >=
                +      windowSize.height + scrollOffset.y) {
                +    xy.y -= paletteSize.height - 1;
                +  } else {
                +    xy.y += borderBBox.height - 1;
                +  }
                +  if (this.sourceBlock_.RTL) {
                +    xy.x += borderBBox.width;
                +    xy.x -= paletteSize.width;
                +    // Don't go offscreen left.
                +    if (xy.x < scrollOffset.x) {
                +      xy.x = scrollOffset.x;
                +    }
                +  } else {
                +    // Don't go offscreen right.
                +    if (xy.x > windowSize.width + scrollOffset.x - paletteSize.width) {
                +      xy.x = windowSize.width + scrollOffset.x - paletteSize.width;
                +    }
                +  }
                +  Blockly.WidgetDiv.position(xy.x, xy.y, windowSize, scrollOffset,
                +                             this.sourceBlock_.RTL);
                +
                +  // Configure event handler.
                +  var thisField = this;
                +  Blockly.FieldColour.changeEventKey_ = goog.events.listen(picker,
                +      goog.ui.ColorPicker.EventType.CHANGE,
                +      function(event) {
                +        var colour = event.target.getSelectedColor() || '#000000';
                +        Blockly.WidgetDiv.hide();
                +        if (thisField.sourceBlock_) {
                +          // Call any validation function, and allow it to override.
                +          colour = thisField.callValidator(colour);
                +        }
                +        if (colour !== null) {
                +          thisField.setValue(colour);
                +        }
                +      });
                +};
                +
                +/**
                + * Hide the colour palette.
                + * @private
                + */
                +Blockly.FieldColour.widgetDispose_ = function() {
                +  if (Blockly.FieldColour.changeEventKey_) {
                +    goog.events.unlistenByKey(Blockly.FieldColour.changeEventKey_);
                +  }
                +  Blockly.Events.setGroup(false);
                +};
                diff --git a/blockly/webif/static/blockly/core/field_date.js b/blockly/webif/static/blockly/core/field_date.js
                new file mode 100644
                index 000000000..9e19c63ac
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_date.js
                @@ -0,0 +1,347 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Date input field.
                + * @author pkendall64@gmail.com (Paul Kendall)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldDate');
                +
                +goog.require('Blockly.Field');
                +goog.require('goog.date');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.i18n.DateTimeSymbols');
                +goog.require('goog.i18n.DateTimeSymbols_he');
                +goog.require('goog.style');
                +goog.require('goog.ui.DatePicker');
                +
                +
                +/**
                + * Class for a date input field.
                + * @param {string} date The initial date.
                + * @param {Function=} opt_validator A function that is executed when a new
                + *     date is selected.  Its sole argument is the new date value.  Its
                + *     return value becomes the selected date, unless it is undefined, in
                + *     which case the new date stands, or it is null, in which case the change
                + *     is aborted.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldDate = function(date, opt_validator) {
                +  if (!date) {
                +    date = new goog.date.Date().toIsoString(true);
                +  }
                +  Blockly.FieldDate.superClass_.constructor.call(this, date, opt_validator);
                +  this.setValue(date);
                +};
                +goog.inherits(Blockly.FieldDate, Blockly.Field);
                +
                +/**
                + * Mouse cursor style when over the hotspot that initiates the editor.
                + */
                +Blockly.FieldDate.prototype.CURSOR = 'text';
                +
                +/**
                + * Close the colour picker if this input is being deleted.
                + */
                +Blockly.FieldDate.prototype.dispose = function() {
                +  Blockly.WidgetDiv.hideIfOwner(this);
                +  Blockly.FieldDate.superClass_.dispose.call(this);
                +};
                +
                +/**
                + * Return the current date.
                + * @return {string} Current date.
                + */
                +Blockly.FieldDate.prototype.getValue = function() {
                +  return this.date_;
                +};
                +
                +/**
                + * Set the date.
                + * @param {string} date The new date.
                + */
                +Blockly.FieldDate.prototype.setValue = function(date) {
                +  if (this.sourceBlock_) {
                +    var validated = this.callValidator(date);
                +    // If the new date is invalid, validation returns null.
                +    // In this case we still want to display the illegal result.
                +    if (validated !== null) {
                +      date = validated;
                +    }
                +  }
                +  this.date_ = date;
                +  Blockly.Field.prototype.setText.call(this, date);
                +};
                +
                +/**
                + * Create a date picker under the date field.
                + * @private
                + */
                +Blockly.FieldDate.prototype.showEditor_ = function() {
                +  Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL,
                +      Blockly.FieldDate.widgetDispose_);
                +  // Create the date picker using Closure.
                +  Blockly.FieldDate.loadLanguage_();
                +  var picker = new goog.ui.DatePicker();
                +  picker.setAllowNone(false);
                +  picker.setShowWeekNum(false);
                +
                +  // Position the picker to line up with the field.
                +  // Record windowSize and scrollOffset before adding the picker.
                +  var windowSize = goog.dom.getViewportSize();
                +  var scrollOffset = goog.style.getViewportPageOffset(document);
                +  var xy = this.getAbsoluteXY_();
                +  var borderBBox = this.getScaledBBox_();
                +  var div = Blockly.WidgetDiv.DIV;
                +  picker.render(div);
                +  picker.setDate(goog.date.fromIsoString(this.getValue()));
                +  // Record pickerSize after adding the date picker.
                +  var pickerSize = goog.style.getSize(picker.getElement());
                +
                +  // Flip the picker vertically if off the bottom.
                +  if (xy.y + pickerSize.height + borderBBox.height >=
                +      windowSize.height + scrollOffset.y) {
                +    xy.y -= pickerSize.height - 1;
                +  } else {
                +    xy.y += borderBBox.height - 1;
                +  }
                +  if (this.sourceBlock_.RTL) {
                +    xy.x += borderBBox.width;
                +    xy.x -= pickerSize.width;
                +    // Don't go offscreen left.
                +    if (xy.x < scrollOffset.x) {
                +      xy.x = scrollOffset.x;
                +    }
                +  } else {
                +    // Don't go offscreen right.
                +    if (xy.x > windowSize.width + scrollOffset.x - pickerSize.width) {
                +      xy.x = windowSize.width + scrollOffset.x - pickerSize.width;
                +    }
                +  }
                +  Blockly.WidgetDiv.position(xy.x, xy.y, windowSize, scrollOffset,
                +                             this.sourceBlock_.RTL);
                +
                +  // Configure event handler.
                +  var thisField = this;
                +  Blockly.FieldDate.changeEventKey_ = goog.events.listen(picker,
                +      goog.ui.DatePicker.Events.CHANGE,
                +      function(event) {
                +        var date = event.date ? event.date.toIsoString(true) : '';
                +        Blockly.WidgetDiv.hide();
                +        if (thisField.sourceBlock_) {
                +          // Call any validation function, and allow it to override.
                +          date = thisField.callValidator(date);
                +        }
                +        thisField.setValue(date);
                +      });
                +};
                +
                +/**
                + * Hide the date picker.
                + * @private
                + */
                +Blockly.FieldDate.widgetDispose_ = function() {
                +  if (Blockly.FieldDate.changeEventKey_) {
                +    goog.events.unlistenByKey(Blockly.FieldDate.changeEventKey_);
                +  }
                +  Blockly.Events.setGroup(false);
                +};
                +
                +/**
                + * Load the best language pack by scanning the Blockly.Msg object for a
                + * language that matches the available languages in Closure.
                + * @private
                + */
                +Blockly.FieldDate.loadLanguage_ = function() {
                +  var reg = /^DateTimeSymbols_(.+)$/;
                +  for (var prop in goog.i18n) {
                +    var m = prop.match(reg);
                +    if (m) {
                +      var lang = m[1].toLowerCase().replace('_', '.');  // E.g. 'pt.br'
                +      if (goog.getObjectByName(lang, Blockly.Msg)) {
                +        goog.i18n.DateTimeSymbols = goog.i18n[prop];
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * CSS for date picker.  See css.js for use.
                + */
                +Blockly.FieldDate.CSS = [
                +  /* Copied from: goog/css/datepicker.css */
                +  /**
                +   * Copyright 2009 The Closure Library Authors. All Rights Reserved.
                +   *
                +   * Use of this source code is governed by the Apache License, Version 2.0.
                +   * See the COPYING file for details.
                +   */
                +
                +  /**
                +   * Standard styling for a goog.ui.DatePicker.
                +   *
                +   * @author arv@google.com (Erik Arvidsson)
                +   */
                +
                +  '.blocklyWidgetDiv .goog-date-picker,',
                +  '.blocklyWidgetDiv .goog-date-picker th,',
                +  '.blocklyWidgetDiv .goog-date-picker td {',
                +  '  font: 13px Arial, sans-serif;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker {',
                +  '  -moz-user-focus: normal;',
                +  '  -moz-user-select: none;',
                +  '  position: relative;',
                +  '  border: 1px solid #000;',
                +  '  float: left;',
                +  '  padding: 2px;',
                +  '  color: #000;',
                +  '  background: #c3d9ff;',
                +  '  cursor: default;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker th {',
                +  '  text-align: center;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker td {',
                +  '  text-align: center;',
                +  '  vertical-align: middle;',
                +  '  padding: 1px 3px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-menu {',
                +  '  position: absolute;',
                +  '  background: threedface;',
                +  '  border: 1px solid gray;',
                +  '  -moz-user-focus: normal;',
                +  '  z-index: 1;',
                +  '  outline: none;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-menu ul {',
                +  '  list-style: none;',
                +  '  margin: 0px;',
                +  '  padding: 0px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-menu ul li {',
                +  '  cursor: default;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-menu-selected {',
                +  '  background: #ccf;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker th {',
                +  '  font-size: .9em;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker td div {',
                +  '  float: left;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker button {',
                +  '  padding: 0px;',
                +  '  margin: 1px 0;',
                +  '  border: 0;',
                +  '  color: #20c;',
                +  '  font-weight: bold;',
                +  '  background: transparent;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-date {',
                +  '  background: #fff;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-week,',
                +  '.blocklyWidgetDiv .goog-date-picker-wday {',
                +  '  padding: 1px 3px;',
                +  '  border: 0;',
                +  '  border-color: #a2bbdd;',
                +  '  border-style: solid;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-week {',
                +  '  border-right-width: 1px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-wday {',
                +  '  border-bottom-width: 1px;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-head td {',
                +  '  text-align: center;',
                +  '}',
                +
                +  /** Use td.className instead of !important */
                +  '.blocklyWidgetDiv td.goog-date-picker-today-cont {',
                +  '  text-align: center;',
                +  '}',
                +
                +  /** Use td.className instead of !important */
                +  '.blocklyWidgetDiv td.goog-date-picker-none-cont {',
                +  '  text-align: center;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-month {',
                +  '  min-width: 11ex;',
                +  '  white-space: nowrap;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-year {',
                +  '  min-width: 6ex;',
                +  '  white-space: nowrap;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-monthyear {',
                +  '  white-space: nowrap;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker table {',
                +  '  border-collapse: collapse;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-other-month {',
                +  '  color: #888;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-wkend-start,',
                +  '.blocklyWidgetDiv .goog-date-picker-wkend-end {',
                +  '  background: #eee;',
                +  '}',
                +
                +  /** Use td.className instead of !important */
                +  '.blocklyWidgetDiv td.goog-date-picker-selected {',
                +  '  background: #c3d9ff;',
                +  '}',
                +
                +  '.blocklyWidgetDiv .goog-date-picker-today {',
                +  '  background: #9ab;',
                +  '  font-weight: bold !important;',
                +  '  border-color: #246 #9bd #9bd #246;',
                +  '  color: #fff;',
                +  '}'
                +];
                diff --git a/blockly/webif/static/blockly/core/field_dropdown.js b/blockly/webif/static/blockly/core/field_dropdown.js
                new file mode 100644
                index 000000000..7ece4e8dc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_dropdown.js
                @@ -0,0 +1,422 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Dropdown input field.  Used for editable titles and variables.
                + * In the interests of a consistent UI, the toolbox shares some functions and
                + * properties with the context menu.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldDropdown');
                +
                +goog.require('Blockly.Field');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.style');
                +goog.require('goog.ui.Menu');
                +goog.require('goog.ui.MenuItem');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for an editable dropdown field.
                + * @param {(!Array.<!Array>|!Function)} menuGenerator An array of options
                + *     for a dropdown list, or a function which generates these options.
                + * @param {Function=} opt_validator A function that is executed when a new
                + *     option is selected, with the newly selected value as its sole argument.
                + *     If it returns a value, that value (which must be one of the options) will
                + *     become selected in place of the newly selected option, unless the return
                + *     value is null, in which case the change is aborted.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldDropdown = function(menuGenerator, opt_validator) {
                +  this.menuGenerator_ = menuGenerator;
                +  this.trimOptions_();
                +  var firstTuple = this.getOptions()[0];
                +
                +  // Call parent's constructor.
                +  Blockly.FieldDropdown.superClass_.constructor.call(this, firstTuple[1],
                +      opt_validator);
                +};
                +goog.inherits(Blockly.FieldDropdown, Blockly.Field);
                +
                +/**
                + * Horizontal distance that a checkmark overhangs the dropdown.
                + */
                +Blockly.FieldDropdown.CHECKMARK_OVERHANG = 25;
                +
                +/**
                + * Android can't (in 2014) display "▾", so use "▼" instead.
                + */
                +Blockly.FieldDropdown.ARROW_CHAR = goog.userAgent.ANDROID ? '\u25BC' : '\u25BE';
                +
                +/**
                + * Mouse cursor style when over the hotspot that initiates the editor.
                + */
                +Blockly.FieldDropdown.prototype.CURSOR = 'default';
                +
                +/**
                + * Language-neutral currently selected string or image object.
                + * @type {string|!Object}
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.value_ = '';
                +
                +/**
                + * SVG image element if currently selected option is an image, or null.
                + * @type {SVGElement}
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.imageElement_ = null;
                +
                +/**
                + * Object with src, height, width, and alt attributes if currently selected
                + * option is an image, or null.
                + * @type {Object}
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.imageJson_ = null;
                +
                +/**
                + * Install this dropdown on a block.
                + */
                +Blockly.FieldDropdown.prototype.init = function() {
                +  if (this.fieldGroup_) {
                +    // Dropdown has already been initialized once.
                +    return;
                +  }
                +  // Add dropdown arrow: "option ▾" (LTR) or "▾ אופציה" (RTL)
                +  this.arrow_ = Blockly.utils.createSvgElement('tspan', {}, null);
                +  this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL ?
                +      Blockly.FieldDropdown.ARROW_CHAR + ' ' :
                +      ' ' + Blockly.FieldDropdown.ARROW_CHAR));
                +
                +  Blockly.FieldDropdown.superClass_.init.call(this);
                +  // Force a reset of the text to add the arrow.
                +  var text = this.text_;
                +  this.text_ = null;
                +  this.setText(text);
                +};
                +
                +/**
                + * Create a dropdown menu under the text.
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.showEditor_ = function() {
                +  Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, null);
                +  var thisField = this;
                +
                +  function callback(e) {
                +    var menu = this;
                +    var menuItem = e.target;
                +    if (menuItem) {
                +      thisField.onItemSelected(menu, menuItem);
                +    }
                +    Blockly.WidgetDiv.hideIfOwner(thisField);
                +    Blockly.Events.setGroup(false);
                +  }
                +
                +  var menu = new goog.ui.Menu();
                +  menu.setRightToLeft(this.sourceBlock_.RTL);
                +  var options = this.getOptions();
                +  for (var i = 0; i < options.length; i++) {
                +    var content = options[i][0]; // Human-readable text or image.
                +    var value = options[i][1];   // Language-neutral value.
                +    if (typeof content == 'object') {
                +      // An image, not text.
                +      var image = new Image(content['width'], content['height']);
                +      image.src = content['src'];
                +      image.alt = content['alt'] || '';
                +      content = image;
                +    }
                +    var menuItem = new goog.ui.MenuItem(content);
                +    menuItem.setRightToLeft(this.sourceBlock_.RTL);
                +    menuItem.setValue(value);
                +    menuItem.setCheckable(true);
                +    menu.addChild(menuItem, true);
                +    menuItem.setChecked(value == this.value_);
                +  }
                +  // Listen for mouse/keyboard events.
                +  goog.events.listen(menu, goog.ui.Component.EventType.ACTION, callback);
                +  // Listen for touch events (why doesn't Closure handle this already?).
                +  function callbackTouchStart(e) {
                +    var control = this.getOwnerControl(/** @type {Node} */ (e.target));
                +    // Highlight the menu item.
                +    control.handleMouseDown(e);
                +  }
                +  function callbackTouchEnd(e) {
                +    var control = this.getOwnerControl(/** @type {Node} */ (e.target));
                +    // Activate the menu item.
                +    control.performActionInternal(e);
                +  }
                +  menu.getHandler().listen(menu.getElement(), goog.events.EventType.TOUCHSTART,
                +                           callbackTouchStart);
                +  menu.getHandler().listen(menu.getElement(), goog.events.EventType.TOUCHEND,
                +                           callbackTouchEnd);
                +
                +  // Record windowSize and scrollOffset before adding menu.
                +  var windowSize = goog.dom.getViewportSize();
                +  var scrollOffset = goog.style.getViewportPageOffset(document);
                +  var xy = this.getAbsoluteXY_();
                +  var borderBBox = this.getScaledBBox_();
                +  var div = Blockly.WidgetDiv.DIV;
                +  menu.render(div);
                +  var menuDom = menu.getElement();
                +  Blockly.utils.addClass(menuDom, 'blocklyDropdownMenu');
                +  // Record menuSize after adding menu.
                +  var menuSize = goog.style.getSize(menuDom);
                +  // Recalculate height for the total content, not only box height.
                +  menuSize.height = menuDom.scrollHeight;
                +
                +  // Position the menu.
                +  // Flip menu vertically if off the bottom.
                +  if (xy.y + menuSize.height + borderBBox.height >=
                +      windowSize.height + scrollOffset.y) {
                +    xy.y -= menuSize.height + 2;
                +  } else {
                +    xy.y += borderBBox.height;
                +  }
                +  if (this.sourceBlock_.RTL) {
                +    xy.x += borderBBox.width;
                +    xy.x += Blockly.FieldDropdown.CHECKMARK_OVERHANG;
                +    // Don't go offscreen left.
                +    if (xy.x < scrollOffset.x + menuSize.width) {
                +      xy.x = scrollOffset.x + menuSize.width;
                +    }
                +  } else {
                +    xy.x -= Blockly.FieldDropdown.CHECKMARK_OVERHANG;
                +    // Don't go offscreen right.
                +    if (xy.x > windowSize.width + scrollOffset.x - menuSize.width) {
                +      xy.x = windowSize.width + scrollOffset.x - menuSize.width;
                +    }
                +  }
                +  Blockly.WidgetDiv.position(xy.x, xy.y, windowSize, scrollOffset,
                +                             this.sourceBlock_.RTL);
                +  menu.setAllowAutoFocus(true);
                +  menuDom.focus();
                +};
                +
                +/**
                + * Handle the selection of an item in the dropdown menu.
                + * @param {!goog.ui.Menu} menu The Menu component clicked.
                + * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu.
                + */
                +Blockly.FieldDropdown.prototype.onItemSelected = function(menu, menuItem) {
                +  var value = menuItem.getValue();
                +  if (this.sourceBlock_) {
                +    // Call any validation function, and allow it to override.
                +    value = this.callValidator(value);
                +  }
                +  if (value !== null) {
                +    this.setValue(value);
                +  }
                +};
                +
                +/**
                + * Factor out common words in statically defined options.
                + * Create prefix and/or suffix labels.
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.trimOptions_ = function() {
                +  this.prefixField = null;
                +  this.suffixField = null;
                +  var options = this.menuGenerator_;
                +  if (!goog.isArray(options)) {
                +    return;
                +  }
                +  var hasImages = false;
                +
                +  // Localize label text and image alt text.
                +  for (var i = 0; i < options.length; i++) {
                +    var label = options[i][0];
                +    if (typeof label == 'string') {
                +      options[i][0] = Blockly.utils.replaceMessageReferences(label);
                +    } else {
                +      if (label.alt != null) {
                +        options[i][0].alt = Blockly.utils.replaceMessageReferences(label.alt);
                +      }
                +      hasImages = true;
                +    }
                +  }
                +  if (hasImages || options.length < 2) {
                +    return;  // Do nothing if too few items or at least one label is an image.
                +  }
                +  var strings = [];
                +  for (var i = 0; i < options.length; i++) {
                +    strings.push(options[i][0]);
                +  }
                +  var shortest = Blockly.utils.shortestStringLength(strings);
                +  var prefixLength = Blockly.utils.commonWordPrefix(strings, shortest);
                +  var suffixLength = Blockly.utils.commonWordSuffix(strings, shortest);
                +  if (!prefixLength && !suffixLength) {
                +    return;
                +  }
                +  if (shortest <= prefixLength + suffixLength) {
                +    // One or more strings will entirely vanish if we proceed.  Abort.
                +    return;
                +  }
                +  if (prefixLength) {
                +    this.prefixField = strings[0].substring(0, prefixLength - 1);
                +  }
                +  if (suffixLength) {
                +    this.suffixField = strings[0].substr(1 - suffixLength);
                +  }
                +  // Remove the prefix and suffix from the options.
                +  var newOptions = [];
                +  for (var i = 0; i < options.length; i++) {
                +    var text = options[i][0];
                +    var value = options[i][1];
                +    text = text.substring(prefixLength, text.length - suffixLength);
                +    newOptions[i] = [text, value];
                +  }
                +  this.menuGenerator_ = newOptions;
                +};
                +
                +/**
                + * @return {boolean} True if the option list is generated by a function. Otherwise false.
                + */
                +Blockly.FieldDropdown.prototype.isOptionListDynamic = function() {
                +  return goog.isFunction(this.menuGenerator_);
                +};
                +
                +/**
                + * Return a list of the options for this dropdown.
                + * @return {!Array.<!Array>} Array of option tuples:
                + *     (human-readable text or image, language-neutral name).
                + */
                +Blockly.FieldDropdown.prototype.getOptions = function() {
                +  if (goog.isFunction(this.menuGenerator_)) {
                +    return this.menuGenerator_.call(this);
                +  }
                +  return /** @type {!Array.<!Array.<string>>} */ (this.menuGenerator_);
                +};
                +
                +/**
                + * Get the language-neutral value from this dropdown menu.
                + * @return {string} Current text.
                + */
                +Blockly.FieldDropdown.prototype.getValue = function() {
                +  return this.value_;
                +};
                +
                +/**
                + * Set the language-neutral value for this dropdown menu.
                + * @param {string} newValue New value to set.
                + */
                +Blockly.FieldDropdown.prototype.setValue = function(newValue) {
                +  if (newValue === null || newValue === this.value_) {
                +    return;  // No change if null.
                +  }
                +  if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this.sourceBlock_, 'field', this.name, this.value_, newValue));
                +  }
                +  this.value_ = newValue;
                +  // Look up and display the human-readable text.
                +  var options = this.getOptions();
                +  for (var i = 0; i < options.length; i++) {
                +    // Options are tuples of human-readable text and language-neutral values.
                +    if (options[i][1] == newValue) {
                +      var content = options[i][0];
                +      if (typeof content == 'object') {
                +        this.imageJson_ = content;
                +        this.setText(content.alt);
                +      } else {
                +        this.imageJson_ = null;
                +        this.setText(content);
                +      }
                +      return;
                +    }
                +  }
                +  // Value not found.  Add it, maybe it will become valid once set
                +  // (like variable names).
                +  this.setText(newValue);
                +};
                +
                +/**
                + * Draws the border with the correct width.
                + * @private
                + */
                +Blockly.FieldDropdown.prototype.render_ = function() {
                +  if (!this.visible_) {
                +    this.size_.width = 0;
                +    return;
                +  }
                +  if (this.sourceBlock_ && this.arrow_) {
                +    // Update arrow's colour.
                +    this.arrow_.style.fill = this.sourceBlock_.getColour();
                +  }
                +  goog.dom.removeChildren(/** @type {!Element} */ (this.textElement_));
                +  goog.dom.removeNode(this.imageElement_);
                +  this.imageElement_ = null;
                +
                +  if (this.imageJson_) {
                +    // Image option is selected.
                +    this.imageElement_ = Blockly.utils.createSvgElement('image',
                +        {'y': 5,
                +         'height': this.imageJson_.height + 'px',
                +         'width': this.imageJson_.width + 'px'}, this.fieldGroup_);
                +    this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink',
                +                                      'xlink:href', this.imageJson_.src);
                +    // Insert dropdown arrow.
                +    this.textElement_.appendChild(this.arrow_);
                +    var arrowWidth = Blockly.Field.getCachedWidth(this.arrow_);
                +    this.size_.height = Number(this.imageJson_.height) + 19;
                +    this.size_.width = Number(this.imageJson_.width) + arrowWidth;
                +    if (this.sourceBlock_.RTL) {
                +      this.imageElement_.setAttribute('x', arrowWidth);
                +      this.textElement_.setAttribute('x', -1);
                +    } else {
                +      this.textElement_.setAttribute('text-anchor', 'end');
                +      this.textElement_.setAttribute('x', this.size_.width + 1);
                +    }
                +
                +  } else {
                +    // Text option is selected.
                +    // Replace the text.
                +    var textNode = document.createTextNode(this.getDisplayText_());
                +    this.textElement_.appendChild(textNode);
                +    // Insert dropdown arrow.
                +    if (this.sourceBlock_.RTL) {
                +      this.textElement_.insertBefore(this.arrow_, this.textElement_.firstChild);
                +    } else {
                +      this.textElement_.appendChild(this.arrow_);
                +    }
                +    this.textElement_.setAttribute('text-anchor', 'start');
                +    this.textElement_.setAttribute('x', 0);
                +
                +    this.size_.height = Blockly.BlockSvg.MIN_BLOCK_Y;
                +    this.size_.width = Blockly.Field.getCachedWidth(this.textElement_);
                +  }
                +  this.borderRect_.setAttribute('height', this.size_.height - 9);
                +  this.borderRect_.setAttribute('width',
                +      this.size_.width + Blockly.BlockSvg.SEP_SPACE_X);
                +};
                +
                +/**
                + * Close the dropdown menu if this input is being deleted.
                + */
                +Blockly.FieldDropdown.prototype.dispose = function() {
                +  Blockly.WidgetDiv.hideIfOwner(this);
                +  Blockly.FieldDropdown.superClass_.dispose.call(this);
                +};
                diff --git a/blockly/webif/static/blockly/core/field_image.js b/blockly/webif/static/blockly/core/field_image.js
                new file mode 100644
                index 000000000..4b4859da7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_image.js
                @@ -0,0 +1,178 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Image field.  Used for pictures, icons, etc.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldImage');
                +
                +goog.require('Blockly.Field');
                +goog.require('goog.dom');
                +goog.require('goog.math.Size');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for an image on a block.
                + * @param {string} src The URL of the image.
                + * @param {number} width Width of the image.
                + * @param {number} height Height of the image.
                + * @param {string=} opt_alt Optional alt text for when block is collapsed.
                + * @param {Function=} opt_onClick Optional function to be called when image is clicked
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldImage = function(src, width, height, opt_alt, opt_onClick) {
                +  this.sourceBlock_ = null;
                +
                +  // Ensure height and width are numbers.  Strings are bad at math.
                +  this.height_ = Number(height);
                +  this.width_ = Number(width);
                +  this.size_ = new goog.math.Size(this.width_,
                +      this.height_ + 2 * Blockly.BlockSvg.INLINE_PADDING_Y);
                +  this.text_ = opt_alt || '';
                +  this.setValue(src);
                +
                +  if (typeof opt_onClick === "function") {
                +    this.clickHandler_ = opt_onClick;
                +  }
                +};
                +goog.inherits(Blockly.FieldImage, Blockly.Field);
                +
                +/**
                + * Editable fields are saved by the XML renderer, non-editable fields are not.
                + */
                +Blockly.FieldImage.prototype.EDITABLE = false;
                +
                +/**
                + * Install this image on a block.
                + */
                +Blockly.FieldImage.prototype.init = function() {
                +  if (this.fieldGroup_) {
                +    // Image has already been initialized once.
                +    return;
                +  }
                +  // Build the DOM.
                +  /** @type {SVGElement} */
                +  this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null);
                +  if (!this.visible_) {
                +    this.fieldGroup_.style.display = 'none';
                +  }
                +  /** @type {SVGElement} */
                +  this.imageElement_ = Blockly.utils.createSvgElement(
                +    'image',
                +    {
                +      'height': this.height_ + 'px',
                +      'width': this.width_ + 'px'
                +    },
                +    this.fieldGroup_);
                +  this.setValue(this.src_);
                +  this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
                +
                +  // Configure the field to be transparent with respect to tooltips.
                +  this.setTooltip(this.sourceBlock_);
                +  Blockly.Tooltip.bindMouseEvents(this.imageElement_);
                +};
                +
                +/**
                + * Dispose of all DOM objects belonging to this text.
                + */
                +Blockly.FieldImage.prototype.dispose = function() {
                +  goog.dom.removeNode(this.fieldGroup_);
                +  this.fieldGroup_ = null;
                +  this.imageElement_ = null;
                +};
                +
                +/**
                + * Change the tooltip text for this field.
                + * @param {string|!Element} newTip Text for tooltip or a parent element to
                + *     link to for its tooltip.
                + */
                +Blockly.FieldImage.prototype.setTooltip = function(newTip) {
                +  this.imageElement_.tooltip = newTip;
                +};
                +
                +/**
                + * Get the source URL of this image.
                + * @return {string} Current text.
                + * @override
                + */
                +Blockly.FieldImage.prototype.getValue = function() {
                +  return this.src_;
                +};
                +
                +/**
                + * Set the source URL of this image.
                + * @param {?string} src New source.
                + * @override
                + */
                +Blockly.FieldImage.prototype.setValue = function(src) {
                +  if (src === null) {
                +    // No change if null.
                +    return;
                +  }
                +  this.src_ = src;
                +  if (this.imageElement_) {
                +    this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink',
                +        'xlink:href', src || '');
                +  }
                +};
                +
                +/**
                + * Set the alt text of this image.
                + * @param {?string} alt New alt text.
                + * @override
                + */
                +Blockly.FieldImage.prototype.setText = function(alt) {
                +  if (alt === null) {
                +    // No change if null.
                +    return;
                +  }
                +  this.text_ = alt;
                +};
                +
                +/**
                + * Images are fixed width, no need to render.
                + * @private
                + */
                +Blockly.FieldImage.prototype.render_ = function() {
                +  // NOP
                +};
                +
                +/**
                + * Images are fixed width, no need to update.
                + * @private
                + */
                +Blockly.FieldImage.prototype.updateWidth = function() {
                + // NOP
                +};
                +
                +/**
                + * If field click is called, and click handler defined,
                + * call the handler.
                + */
                + Blockly.FieldImage.prototype.showEditor = function() {
                +   if (this.clickHandler_){
                +     this.clickHandler_(this);
                +   }
                + };
                diff --git a/blockly/webif/static/blockly/core/field_label.js b/blockly/webif/static/blockly/core/field_label.js
                new file mode 100644
                index 000000000..f4bca6a24
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_label.js
                @@ -0,0 +1,104 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Non-editable text field.  Used for titles, labels, etc.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldLabel');
                +
                +goog.require('Blockly.Field');
                +goog.require('Blockly.Tooltip');
                +goog.require('goog.dom');
                +goog.require('goog.math.Size');
                +
                +
                +/**
                + * Class for a non-editable field.
                + * @param {string} text The initial content of the field.
                + * @param {string=} opt_class Optional CSS class for the field's text.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldLabel = function(text, opt_class) {
                +  this.size_ = new goog.math.Size(0, 17.5);
                +  this.class_ = opt_class;
                +  this.setValue(text);
                +};
                +goog.inherits(Blockly.FieldLabel, Blockly.Field);
                +
                +/**
                + * Editable fields are saved by the XML renderer, non-editable fields are not.
                + */
                +Blockly.FieldLabel.prototype.EDITABLE = false;
                +
                +/**
                + * Install this text on a block.
                + */
                +Blockly.FieldLabel.prototype.init = function() {
                +  if (this.textElement_) {
                +    // Text has already been initialized once.
                +    return;
                +  }
                +  // Build the DOM.
                +  this.textElement_ = Blockly.utils.createSvgElement('text',
                +      {'class': 'blocklyText', 'y': this.size_.height - 5}, null);
                +  if (this.class_) {
                +    Blockly.utils.addClass(this.textElement_, this.class_);
                +  }
                +  if (!this.visible_) {
                +    this.textElement_.style.display = 'none';
                +  }
                +  this.sourceBlock_.getSvgRoot().appendChild(this.textElement_);
                +
                +  // Configure the field to be transparent with respect to tooltips.
                +  this.textElement_.tooltip = this.sourceBlock_;
                +  Blockly.Tooltip.bindMouseEvents(this.textElement_);
                +  // Force a render.
                +  this.render_();
                +};
                +
                +/**
                + * Dispose of all DOM objects belonging to this text.
                + */
                +Blockly.FieldLabel.prototype.dispose = function() {
                +  goog.dom.removeNode(this.textElement_);
                +  this.textElement_ = null;
                +};
                +
                +/**
                + * Gets the group element for this field.
                + * Used for measuring the size and for positioning.
                + * @return {!Element} The group element.
                + */
                +Blockly.FieldLabel.prototype.getSvgRoot = function() {
                +  return /** @type {!Element} */ (this.textElement_);
                +};
                +
                +/**
                + * Change the tooltip text for this field.
                + * @param {string|!Element} newTip Text for tooltip or a parent element to
                + *     link to for its tooltip.
                + */
                +Blockly.FieldLabel.prototype.setTooltip = function(newTip) {
                +  this.textElement_.tooltip = newTip;
                +};
                diff --git a/blockly/webif/static/blockly/core/field_number.js b/blockly/webif/static/blockly/core/field_number.js
                new file mode 100644
                index 000000000..722b0eefa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_number.js
                @@ -0,0 +1,103 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Number input field
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldNumber');
                +
                +goog.require('Blockly.FieldTextInput');
                +goog.require('goog.math');
                +
                +/**
                + * Class for an editable number field.
                + * @param {(string|number)=} opt_value The initial content of the field. The value
                + *     should cast to a number, and if it does not, '0' will be used.
                + * @param {(string|number)=} opt_min Minimum value.
                + * @param {(string|number)=} opt_max Maximum value.
                + * @param {(string|number)=} opt_precision Precision for value.
                + * @param {Function=} opt_validator An optional function that is called
                + *     to validate any constraints on what the user entered.  Takes the new
                + *     text as an argument and returns either the accepted text, a replacement
                + *     text, or null to abort the change.
                + * @extends {Blockly.FieldTextInput}
                + * @constructor
                + */
                +Blockly.FieldNumber = function(opt_value, opt_min, opt_max, opt_precision,
                +    opt_validator) {
                +  opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0';
                +  Blockly.FieldNumber.superClass_.constructor.call(
                +      this, opt_value, opt_validator);
                +  this.setConstraints(opt_min, opt_max, opt_precision);
                +};
                +goog.inherits(Blockly.FieldNumber, Blockly.FieldTextInput);
                +
                +/**
                + * Set the maximum, minimum and precision constraints on this field.
                + * Any of these properties may be undefiend or NaN to be disabled.
                + * Setting precision (usually a power of 10) enforces a minimum step between
                + * values. That is, the user's value will rounded to the closest multiple of
                + * precision. The least significant digit place is inferred from the precision.
                + * Integers values can be enforces by choosing an integer precision.
                + * @param {number|string|undefined} min Minimum value.
                + * @param {number|string|undefined} max Maximum value.
                + * @param {number|string|undefined} precision Precision for value.
                + */
                +Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) {
                +  precision = parseFloat(precision);
                +  this.precision_ = isNaN(precision) ? 0 : precision;
                +  min = parseFloat(min);
                +  this.min_ = isNaN(min) ? -Infinity : min;
                +  max = parseFloat(max);
                +  this.max_ = isNaN(max) ? Infinity : max;
                +  this.setValue(this.callValidator(this.getValue()));
                +};
                +
                +/**
                + * Ensure that only a number in the correct range may be entered.
                + * @param {string} text The user's text.
                + * @return {?string} A string representing a valid number, or null if invalid.
                + */
                +Blockly.FieldNumber.prototype.classValidator = function(text) {
                +  if (text === null) {
                +    return null;
                +  }
                +  text = String(text);
                +  // TODO: Handle cases like 'ten', '1.203,14', etc.
                +  // 'O' is sometimes mistaken for '0' by inexperienced users.
                +  text = text.replace(/O/ig, '0');
                +  // Strip out thousands separators.
                +  text = text.replace(/,/g, '');
                +  var n = parseFloat(text || 0);
                +  if (isNaN(n)) {
                +    // Invalid number.
                +    return null;
                +  }
                +  // Round to nearest multiple of precision.
                +  if (this.precision_ && isFinite(n)) {
                +    n = Math.round(n / this.precision_) * this.precision_;
                +  }
                +  // Get the value in range.
                +  n = goog.math.clamp(n, this.min_, this.max_);
                +  return String(n);
                +};
                diff --git a/blockly/webif/static/blockly/core/field_textinput.js b/blockly/webif/static/blockly/core/field_textinput.js
                new file mode 100644
                index 000000000..a8014a187
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_textinput.js
                @@ -0,0 +1,355 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Text input field.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldTextInput');
                +
                +goog.require('Blockly.Field');
                +goog.require('Blockly.Msg');
                +goog.require('goog.asserts');
                +goog.require('goog.dom');
                +goog.require('goog.dom.TagName');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for an editable text field.
                + * @param {string} text The initial content of the field.
                + * @param {Function=} opt_validator An optional function that is called
                + *     to validate any constraints on what the user entered.  Takes the new
                + *     text as an argument and returns either the accepted text, a replacement
                + *     text, or null to abort the change.
                + * @extends {Blockly.Field}
                + * @constructor
                + */
                +Blockly.FieldTextInput = function(text, opt_validator) {
                +  Blockly.FieldTextInput.superClass_.constructor.call(this, text,
                +      opt_validator);
                +};
                +goog.inherits(Blockly.FieldTextInput, Blockly.Field);
                +
                +/**
                + * Point size of text.  Should match blocklyText's font-size in CSS.
                + */
                +Blockly.FieldTextInput.FONTSIZE = 11;
                +
                +/**
                + * Mouse cursor style when over the hotspot that initiates the editor.
                + */
                +Blockly.FieldTextInput.prototype.CURSOR = 'text';
                +
                +/**
                + * Allow browser to spellcheck this field.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.spellcheck_ = true;
                +
                +/**
                + * Close the input widget if this input is being deleted.
                + */
                +Blockly.FieldTextInput.prototype.dispose = function() {
                +  Blockly.WidgetDiv.hideIfOwner(this);
                +  Blockly.FieldTextInput.superClass_.dispose.call(this);
                +};
                +
                +/**
                + * Set the value of this field.
                + * @param {?string} newValue New value.
                + * @override
                + */
                +Blockly.FieldTextInput.prototype.setValue = function(newValue) {
                +  if (newValue === null) {
                +    return;  // No change if null.
                +  }
                +  if (this.sourceBlock_) {
                +    var validated = this.callValidator(newValue);
                +    // If the new value is invalid, validation returns null.
                +    // In this case we still want to display the illegal result.
                +    if (validated !== null) {
                +      newValue = validated;
                +    }
                +  }
                +  Blockly.Field.prototype.setValue.call(this, newValue);
                +};
                +
                +/**
                + * Set the text in this field and fire a change event.
                + * @param {*} newText New text.
                + */
                +Blockly.FieldTextInput.prototype.setText = function(newText) {
                +  if (newText === null) {
                +    // No change if null.
                +    return;
                +  }
                +  newText = String(newText);
                +  if (newText === this.text_) {
                +    // No change.
                +    return;
                +  }
                +  if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockChange(
                +        this.sourceBlock_, 'field', this.name, this.text_, newText));
                +  }
                +  Blockly.Field.prototype.setText.call(this, newText);
                +};
                +
                +/**
                + * Set whether this field is spellchecked by the browser.
                + * @param {boolean} check True if checked.
                + */
                +Blockly.FieldTextInput.prototype.setSpellcheck = function(check) {
                +  this.spellcheck_ = check;
                +};
                +
                +/**
                + * Show the inline free-text editor on top of the text.
                + * @param {boolean=} opt_quietInput True if editor should be created without
                + *     focus.  Defaults to false.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) {
                +  this.workspace_ = this.sourceBlock_.workspace;
                +  var quietInput = opt_quietInput || false;
                +  if (!quietInput && (goog.userAgent.MOBILE || goog.userAgent.ANDROID ||
                +                      goog.userAgent.IPAD)) {
                +    // Mobile browsers have issues with in-line textareas (focus & keyboards).
                +    var fieldText = this;
                +    Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE, this.text_,
                +      function(newValue) {
                +        if (fieldText.sourceBlock_) {
                +          newValue = fieldText.callValidator(newValue);
                +        }
                +        fieldText.setValue(newValue);
                +      });
                +    return;
                +  }
                +
                +  Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_());
                +  var div = Blockly.WidgetDiv.DIV;
                +  // Create the input.
                +  var htmlInput =
                +      goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput');
                +  htmlInput.setAttribute('spellcheck', this.spellcheck_);
                +  var fontSize =
                +      (Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt';
                +  div.style.fontSize = fontSize;
                +  htmlInput.style.fontSize = fontSize;
                +  /** @type {!HTMLInputElement} */
                +  Blockly.FieldTextInput.htmlInput_ = htmlInput;
                +  div.appendChild(htmlInput);
                +
                +  htmlInput.value = htmlInput.defaultValue = this.text_;
                +  htmlInput.oldValue_ = null;
                +  this.validate_();
                +  this.resizeEditor_();
                +  if (!quietInput) {
                +    htmlInput.focus();
                +    htmlInput.select();
                +  }
                +
                +  // Bind to keydown -- trap Enter without IME and Esc to hide.
                +  htmlInput.onKeyDownWrapper_ =
                +      Blockly.bindEventWithChecks_(htmlInput, 'keydown', this,
                +      this.onHtmlInputKeyDown_);
                +  // Bind to keyup -- trap Enter; resize after every keystroke.
                +  htmlInput.onKeyUpWrapper_ =
                +      Blockly.bindEventWithChecks_(htmlInput, 'keyup', this,
                +      this.onHtmlInputChange_);
                +  // Bind to keyPress -- repeatedly resize when holding down a key.
                +  htmlInput.onKeyPressWrapper_ =
                +      Blockly.bindEventWithChecks_(htmlInput, 'keypress', this,
                +      this.onHtmlInputChange_);
                +  htmlInput.onWorkspaceChangeWrapper_ = this.resizeEditor_.bind(this);
                +  this.workspace_.addChangeListener(htmlInput.onWorkspaceChangeWrapper_);
                +};
                +
                +/**
                + * Handle key down to the editor.
                + * @param {!Event} e Keyboard event.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function(e) {
                +  var htmlInput = Blockly.FieldTextInput.htmlInput_;
                +  var tabKey = 9, enterKey = 13, escKey = 27;
                +  if (e.keyCode == enterKey) {
                +    Blockly.WidgetDiv.hide();
                +  } else if (e.keyCode == escKey) {
                +    htmlInput.value = htmlInput.defaultValue;
                +    Blockly.WidgetDiv.hide();
                +  } else if (e.keyCode == tabKey) {
                +    Blockly.WidgetDiv.hide();
                +    this.sourceBlock_.tab(this, !e.shiftKey);
                +    e.preventDefault();
                +  }
                +};
                +
                +/**
                + * Handle a change to the editor.
                + * @param {!Event} e Keyboard event.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(e) {
                +  var htmlInput = Blockly.FieldTextInput.htmlInput_;
                +  // Update source block.
                +  var text = htmlInput.value;
                +  if (text !== htmlInput.oldValue_) {
                +    htmlInput.oldValue_ = text;
                +    this.setValue(text);
                +    this.validate_();
                +  } else if (goog.userAgent.WEBKIT) {
                +    // Cursor key.  Render the source block to show the caret moving.
                +    // Chrome only (version 26, OS X).
                +    this.sourceBlock_.render();
                +  }
                +  this.resizeEditor_();
                +  Blockly.svgResize(this.sourceBlock_.workspace);
                +};
                +
                +/**
                + * Check to see if the contents of the editor validates.
                + * Style the editor accordingly.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.validate_ = function() {
                +  var valid = true;
                +  goog.asserts.assertObject(Blockly.FieldTextInput.htmlInput_);
                +  var htmlInput = Blockly.FieldTextInput.htmlInput_;
                +  if (this.sourceBlock_) {
                +    valid = this.callValidator(htmlInput.value);
                +  }
                +  if (valid === null) {
                +    Blockly.utils.addClass(htmlInput, 'blocklyInvalidInput');
                +  } else {
                +    Blockly.utils.removeClass(htmlInput, 'blocklyInvalidInput');
                +  }
                +};
                +
                +/**
                + * Resize the editor and the underlying block to fit the text.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
                +  var div = Blockly.WidgetDiv.DIV;
                +  var bBox = this.fieldGroup_.getBBox();
                +  div.style.width = bBox.width * this.workspace_.scale + 'px';
                +  div.style.height = bBox.height * this.workspace_.scale + 'px';
                +  var xy = this.getAbsoluteXY_();
                +  // In RTL mode block fields and LTR input fields the left edge moves,
                +  // whereas the right edge is fixed.  Reposition the editor.
                +  if (this.sourceBlock_.RTL) {
                +    var borderBBox = this.getScaledBBox_();
                +    xy.x += borderBBox.width;
                +    xy.x -= div.offsetWidth;
                +  }
                +  // Shift by a few pixels to line up exactly.
                +  xy.y += 1;
                +  if (goog.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) {
                +    // Firefox mis-reports the location of the border by a pixel
                +    // once the WidgetDiv is moved into position.
                +    xy.x -= 1;
                +    xy.y -= 1;
                +  }
                +  if (goog.userAgent.WEBKIT) {
                +    xy.y -= 3;
                +  }
                +  div.style.left = xy.x + 'px';
                +  div.style.top = xy.y + 'px';
                +};
                +
                +/**
                + * Close the editor, save the results, and dispose of the editable
                + * text field's elements.
                + * @return {!Function} Closure to call on destruction of the WidgetDiv.
                + * @private
                + */
                +Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
                +  var thisField = this;
                +  return function() {
                +    var htmlInput = Blockly.FieldTextInput.htmlInput_;
                +    // Save the edit (if it validates).
                +    var text = htmlInput.value;
                +    if (thisField.sourceBlock_) {
                +      var text1 = thisField.callValidator(text);
                +      if (text1 === null) {
                +        // Invalid edit.
                +        text = htmlInput.defaultValue;
                +      } else {
                +        // Validation function has changed the text.
                +        text = text1;
                +        if (thisField.onFinishEditing_) {
                +          thisField.onFinishEditing_(text);
                +        }
                +      }
                +    }
                +    thisField.setText(text);
                +    thisField.sourceBlock_.rendered && thisField.sourceBlock_.render();
                +    Blockly.unbindEvent_(htmlInput.onKeyDownWrapper_);
                +    Blockly.unbindEvent_(htmlInput.onKeyUpWrapper_);
                +    Blockly.unbindEvent_(htmlInput.onKeyPressWrapper_);
                +    thisField.workspace_.removeChangeListener(
                +        htmlInput.onWorkspaceChangeWrapper_);
                +    Blockly.FieldTextInput.htmlInput_ = null;
                +    Blockly.Events.setGroup(false);
                +    // Delete style properties.
                +    var style = Blockly.WidgetDiv.DIV.style;
                +    style.width = 'auto';
                +    style.height = 'auto';
                +    style.fontSize = '';
                +  };
                +};
                +
                +/**
                + * Ensure that only a number may be entered.
                + * @param {string} text The user's text.
                + * @return {?string} A string representing a valid number, or null if invalid.
                + */
                +Blockly.FieldTextInput.numberValidator = function(text) {
                +  console.warn('Blockly.FieldTextInput.numberValidator is deprecated. ' +
                +               'Use Blockly.FieldNumber instead.');
                +  if (text === null) {
                +    return null;
                +  }
                +  text = String(text);
                +  // TODO: Handle cases like 'ten', '1.203,14', etc.
                +  // 'O' is sometimes mistaken for '0' by inexperienced users.
                +  text = text.replace(/O/ig, '0');
                +  // Strip out thousands separators.
                +  text = text.replace(/,/g, '');
                +  var n = parseFloat(text || 0);
                +  return isNaN(n) ? null : String(n);
                +};
                +
                +/**
                + * Ensure that only a nonnegative integer may be entered.
                + * @param {string} text The user's text.
                + * @return {?string} A string representing a valid int, or null if invalid.
                + */
                +Blockly.FieldTextInput.nonnegativeIntegerValidator = function(text) {
                +  var n = Blockly.FieldTextInput.numberValidator(text);
                +  if (n) {
                +    n = String(Math.max(0, Math.floor(n)));
                +  }
                +  return n;
                +};
                diff --git a/blockly/webif/static/blockly/core/field_variable.js b/blockly/webif/static/blockly/core/field_variable.js
                new file mode 100644
                index 000000000..3e06c96ff
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/field_variable.js
                @@ -0,0 +1,248 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Variable input field.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FieldVariable');
                +
                +goog.require('Blockly.FieldDropdown');
                +goog.require('Blockly.Msg');
                +goog.require('Blockly.VariableModel');
                +goog.require('Blockly.Variables');
                +goog.require('Blockly.VariableModel');
                +goog.require('goog.asserts');
                +goog.require('goog.string');
                +
                +
                +/**
                + * Class for a variable's dropdown field.
                + * @param {?string} varname The default name for the variable.  If null,
                + *     a unique variable name will be generated.
                + * @param {Function=} opt_validator A function that is executed when a new
                + *     option is selected.  Its sole argument is the new option value.
                + * @param {Array.<string>} opt_variableTypes A list of the types of variables to
                + *     include in the dropdown.
                + * @extends {Blockly.FieldDropdown}
                + * @constructor
                + */
                +Blockly.FieldVariable = function(varname, opt_validator, opt_variableTypes) {
                +  Blockly.FieldVariable.superClass_.constructor.call(this,
                +      Blockly.FieldVariable.dropdownCreate, opt_validator);
                +  this.setValue(varname || '');
                +  this.variableTypes = opt_variableTypes;
                +};
                +goog.inherits(Blockly.FieldVariable, Blockly.FieldDropdown);
                +
                +/**
                + * Install this dropdown on a block.
                + */
                +Blockly.FieldVariable.prototype.init = function() {
                +  if (this.fieldGroup_) {
                +    // Dropdown has already been initialized once.
                +    return;
                +  }
                +  Blockly.FieldVariable.superClass_.init.call(this);
                +
                +  // TODO (1010): Change from init/initModel to initView/initModel
                +  this.initModel();
                +};
                +
                +Blockly.FieldVariable.prototype.initModel = function() {
                +  if (!this.getValue()) {
                +    // Variables without names get uniquely named for this workspace.
                +    var workspace =
                +        this.sourceBlock_.isInFlyout ?
                +            this.sourceBlock_.workspace.targetWorkspace :
                +            this.sourceBlock_.workspace;
                +    this.setValue(Blockly.Variables.generateUniqueName(workspace));
                +  }
                +  // If the selected variable doesn't exist yet, create it.
                +  // For instance, some blocks in the toolbox have variable dropdowns filled
                +  // in by default.
                +  if (!this.sourceBlock_.isInFlyout) {
                +    this.sourceBlock_.workspace.createVariable(this.getValue());
                +  }
                +};
                +
                +/**
                + * Attach this field to a block.
                + * @param {!Blockly.Block} block The block containing this field.
                + */
                +Blockly.FieldVariable.prototype.setSourceBlock = function(block) {
                +  goog.asserts.assert(!block.isShadow(),
                +      'Variable fields are not allowed to exist on shadow blocks.');
                +  Blockly.FieldVariable.superClass_.setSourceBlock.call(this, block);
                +};
                +
                +/**
                + * Get the variable's name (use a variableDB to convert into a real name).
                + * Unline a regular dropdown, variables are literal and have no neutral value.
                + * @return {string} Current text.
                + */
                +Blockly.FieldVariable.prototype.getValue = function() {
                +  return this.getText();
                +};
                +
                +/**
                + * Set the variable name.
                + * @param {string} value New text.
                + */
                +Blockly.FieldVariable.prototype.setValue = function(value) {
                +  var newValue = value;
                +  var newText = value;
                +
                +  if (this.sourceBlock_) {
                +    var variable = this.sourceBlock_.workspace.getVariableById(value);
                +    if (variable) {
                +      newText = variable.name;
                +    }
                +    // TODO(marisaleung): Remove name lookup after converting all Field Variable
                +    //     instances to use id instead of name.
                +    else if (variable = this.sourceBlock_.workspace.getVariable(value)) {
                +      newValue = variable.getId();
                +    }
                +    if (Blockly.Events.isEnabled()) {
                +      Blockly.Events.fire(new Blockly.Events.BlockChange(
                +          this.sourceBlock_, 'field', this.name, this.value_, newValue));
                +    }
                +  }
                +  this.value_ = newValue;
                +  this.setText(newText);
                +};
                +
                +/**
                + * Return a list of variable types to include in the dropdown.
                + * @return {!Array.<string>} Array of variable types.
                + * @throws {Error} if variableTypes is an empty array.
                + * @private
                + */
                +Blockly.FieldVariable.prototype.getVariableTypes_ = function() {
                +  var variableTypes = this.variableTypes;
                +  if (variableTypes === null) {
                +    // If variableTypes is null, return all variable types.
                +    if (this.sourceBlock_) {
                +      var workspace = this.sourceBlock_.workspace;
                +      return workspace.getVariableTypes();
                +    }
                +  }
                +  variableTypes = variableTypes || [''];
                +  if (variableTypes.length == 0) {
                +    // Throw an error if variableTypes is an empty list.
                +    var name = this.getText();
                +    throw new Error('\'variableTypes\' of field variable ' +
                +      name + ' was an empty list');
                +  }
                +  return variableTypes;
                +};
                +
                +/**
                + * Return a sorted list of variable names for variable dropdown menus.
                + * Include a special option at the end for creating a new variable name.
                + * @return {!Array.<string>} Array of variable names.
                + * @this {Blockly.FieldVariable}
                + */
                +Blockly.FieldVariable.dropdownCreate = function() {
                +  var variableModelList = [];
                +  var name = this.getText();
                +  // Don't create a new variable if there is nothing selected.
                +  var createSelectedVariable = name ? true : false;
                +  var workspace = null;
                +  if (this.sourceBlock_) {
                +    workspace = this.sourceBlock_.workspace;
                +  }
                +  if (workspace) {
                +    var variableTypes = this.getVariableTypes_();
                +    var variableModelList = [];
                +    // Get a copy of the list, so that adding rename and new variable options
                +    // doesn't modify the workspace's list.
                +    for (var i = 0; i < variableTypes.length; i++) {
                +      var variableType = variableTypes[i];
                +      var variables = workspace.getVariablesOfType(variableType);
                +      variableModelList = variableModelList.concat(variables);
                +    }
                +    for (var i = 0; i < variableModelList.length; i++){
                +      if (createSelectedVariable &&
                +          goog.string.caseInsensitiveEquals(variableModelList[i].name, name)) {
                +        createSelectedVariable = false;
                +        break;
                +      }
                +    }
                +  }
                +  // Ensure that the currently selected variable is an option.
                +  if (createSelectedVariable && workspace) {
                +    var newVar = workspace.createVariable(name);
                +    variableModelList.push(newVar);
                +  }
                +  variableModelList.sort(Blockly.VariableModel.compareByName);
                +  var options = [];
                +  for (var i = 0; i < variableModelList.length; i++) {
                +    // Set the uuid as the internal representation of the variable.
                +    options[i] = [variableModelList[i].name, variableModelList[i].getId()];
                +  }
                +  options.push([Blockly.Msg.RENAME_VARIABLE, Blockly.RENAME_VARIABLE_ID]);
                +  if (Blockly.Msg.DELETE_VARIABLE) {
                +    options.push([Blockly.Msg.DELETE_VARIABLE.replace('%1', name),
                +      Blockly.DELETE_VARIABLE_ID]);
                +  }
                +  return options;
                +};
                +
                +/**
                + * Handle the selection of an item in the variable dropdown menu.
                + * Special case the 'Rename variable...' and 'Delete variable...' options.
                + * In the rename case, prompt the user for a new name.
                + * @param {!goog.ui.Menu} menu The Menu component clicked.
                + * @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu.
                + */
                +Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
                +  var id = menuItem.getValue();
                +  // TODO(marisaleung): change setValue() to take in an id as the parameter.
                +  // Then remove itemText.
                +  var itemText;
                +  if (this.sourceBlock_ && this.sourceBlock_.workspace) {
                +    var workspace = this.sourceBlock_.workspace;
                +    var variable = workspace.getVariableById(id);
                +    // If the item selected is a variable, set itemText to the variable name.
                +    if (variable) {
                +      itemText = variable.name;
                +    }
                +    else if (id == Blockly.RENAME_VARIABLE_ID) {
                +      // Rename variable.
                +      var currentName = this.getText();
                +      variable = workspace.getVariable(currentName);
                +      Blockly.Variables.renameVariable(workspace, variable);
                +      return;
                +    } else if (id == Blockly.DELETE_VARIABLE_ID) {
                +      // Delete variable.
                +      workspace.deleteVariable(this.getText());
                +      return;
                +    }
                +
                +    // Call any validation function, and allow it to override.
                +    itemText = this.callValidator(itemText);
                +  }
                +  if (itemText !== null) {
                +    this.setValue(itemText);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/flyout_base.js b/blockly/webif/static/blockly/core/flyout_base.js
                new file mode 100644
                index 000000000..fd8272214
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/flyout_base.js
                @@ -0,0 +1,813 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Flyout tray containing blocks which may be created.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Flyout');
                +
                +goog.require('Blockly.Block');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.FlyoutButton');
                +goog.require('Blockly.Gesture');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.math.Rect');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a flyout.
                + * @param {!Object} workspaceOptions Dictionary of options for the workspace.
                + * @constructor
                + */
                +Blockly.Flyout = function(workspaceOptions) {
                +  workspaceOptions.getMetrics = this.getMetrics_.bind(this);
                +  workspaceOptions.setMetrics = this.setMetrics_.bind(this);
                +
                +  /**
                +   * @type {!Blockly.Workspace}
                +   * @private
                +   */
                +  this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
                +  this.workspace_.isFlyout = true;
                +
                +  /**
                +   * Is RTL vs LTR.
                +   * @type {boolean}
                +   */
                +  this.RTL = !!workspaceOptions.RTL;
                +
                +  /**
                +   * Position of the toolbox and flyout relative to the workspace.
                +   * @type {number}
                +   * @private
                +   */
                +  this.toolboxPosition_ = workspaceOptions.toolboxPosition;
                +
                +  /**
                +   * Opaque data that can be passed to Blockly.unbindEvent_.
                +   * @type {!Array.<!Array>}
                +   * @private
                +   */
                +  this.eventWrappers_ = [];
                +
                +  /**
                +   * List of background buttons that lurk behind each block to catch clicks
                +   * landing in the blocks' lakes and bays.
                +   * @type {!Array.<!Element>}
                +   * @private
                +   */
                +  this.backgroundButtons_ = [];
                +
                +  /**
                +   * List of visible buttons.
                +   * @type {!Array.<!Blockly.FlyoutButton>}
                +   * @private
                +   */
                +  this.buttons_ = [];
                +
                +  /**
                +   * List of event listeners.
                +   * @type {!Array.<!Array>}
                +   * @private
                +   */
                +  this.listeners_ = [];
                +
                +  /**
                +   * List of blocks that should always be disabled.
                +   * @type {!Array.<!Blockly.Block>}
                +   * @private
                +   */
                +  this.permanentlyDisabled_ = [];
                +};
                +
                +/**
                + * Does the flyout automatically close when a block is created?
                + * @type {boolean}
                + */
                +Blockly.Flyout.prototype.autoClose = true;
                +
                +/**
                + * Whether the flyout is visible.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Flyout.prototype.isVisible_ = false;
                +
                +/**
                + * Whether the workspace containing this flyout is visible.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Flyout.prototype.containerVisible_ = true;
                +
                +/**
                + * Corner radius of the flyout background.
                + * @type {number}
                + * @const
                + */
                +Blockly.Flyout.prototype.CORNER_RADIUS = 8;
                +
                +/**
                + * Margin around the edges of the blocks in the flyout.
                + * @type {number}
                + * @const
                + */
                +Blockly.Flyout.prototype.MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS;
                +
                +/**
                + * TODO: Move GAP_X and GAP_Y to their appropriate files.
                + * Gap between items in horizontal flyouts. Can be overridden with the "sep"
                + * element.
                + * @const {number}
                + */
                +Blockly.Flyout.prototype.GAP_X = Blockly.Flyout.prototype.MARGIN * 3;
                +
                +/**
                + * Gap between items in vertical flyouts. Can be overridden with the "sep"
                + * element.
                + * @const {number}
                + */
                +Blockly.Flyout.prototype.GAP_Y = Blockly.Flyout.prototype.MARGIN * 3;
                +
                +/**
                + * Top/bottom padding between scrollbar and edge of flyout background.
                + * @type {number}
                + * @const
                + */
                +Blockly.Flyout.prototype.SCROLLBAR_PADDING = 2;
                +
                +/**
                + * Width of flyout.
                + * @type {number}
                + * @private
                + */
                +Blockly.Flyout.prototype.width_ = 0;
                +
                +/**
                + * Height of flyout.
                + * @type {number}
                + * @private
                + */
                +Blockly.Flyout.prototype.height_ = 0;
                +
                +/**
                + * Range of a drag angle from a flyout considered "dragging toward workspace".
                + * Drags that are within the bounds of this many degrees from the orthogonal
                + * line to the flyout edge are considered to be "drags toward the workspace".
                + * Example:
                + * Flyout                                                  Edge   Workspace
                + * [block] /  <-within this angle, drags "toward workspace" |
                + * [block] ---- orthogonal to flyout boundary ----          |
                + * [block] \                                                |
                + * The angle is given in degrees from the orthogonal.
                + *
                + * This is used to know when to create a new block and when to scroll the
                + * flyout. Setting it to 360 means that all drags create a new block.
                + * @type {number}
                + * @private
                +*/
                +Blockly.Flyout.prototype.dragAngleRange_ = 70;
                +
                +/**
                + * Creates the flyout's DOM.  Only needs to be called once.  The flyout can
                + * either exist as its own svg element or be a g element nested inside a
                + * separate svg element.
                + * @param {string} tagName The type of tag to put the flyout in. This
                + *     should be <svg> or <g>.
                + * @return {!Element} The flyout's SVG group.
                + */
                +Blockly.Flyout.prototype.createDom = function(tagName) {
                +  /*
                +  <svg | g>
                +    <path class="blocklyFlyoutBackground"/>
                +    <g class="blocklyFlyout"></g>
                +  </ svg | g>
                +  */
                +  // Setting style to display:none to start. The toolbox and flyout
                +  // hide/show code will set up proper visibility and size later.
                +  this.svgGroup_ = Blockly.utils.createSvgElement(tagName,
                +      {'class': 'blocklyFlyout', 'style': 'display: none'}, null);
                +  this.svgBackground_ = Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyFlyoutBackground'}, this.svgGroup_);
                +  this.svgGroup_.appendChild(this.workspace_.createDom());
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Initializes the flyout.
                + * @param {!Blockly.Workspace} targetWorkspace The workspace in which to create
                + *     new blocks.
                + */
                +Blockly.Flyout.prototype.init = function(targetWorkspace) {
                +  this.targetWorkspace_ = targetWorkspace;
                +  this.workspace_.targetWorkspace = targetWorkspace;
                +  // Add scrollbar.
                +  this.scrollbar_ = new Blockly.Scrollbar(this.workspace_,
                +      this.horizontalLayout_, false, 'blocklyFlyoutScrollbar');
                +
                +  this.hide();
                +
                +  Array.prototype.push.apply(this.eventWrappers_,
                +      Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, this.wheel_));
                +  if (!this.autoClose) {
                +    this.filterWrapper_ = this.filterForCapacity_.bind(this);
                +    this.targetWorkspace_.addChangeListener(this.filterWrapper_);
                +  }
                +
                +  // Dragging the flyout up and down.
                +  Array.prototype.push.apply(this.eventWrappers_,
                +      Blockly.bindEventWithChecks_(this.svgBackground_, 'mousedown', this,
                +      this.onMouseDown_));
                +
                +  // A flyout connected to a workspace doesn't have its own current gesture.
                +  this.workspace_.getGesture =
                +      this.targetWorkspace_.getGesture.bind(this.targetWorkspace_);
                +
                +  // Get variables from the main workspace rather than the target workspace.
                +  this.workspace_.getVariable =
                +      this.targetWorkspace_.getVariable.bind(this.targetWorkspace_);
                +
                +  this.workspace_.getVariableById =
                +      this.targetWorkspace_.getVariableById.bind(this.targetWorkspace_);
                +
                +  this.workspace_.getVariablesOfType =
                +      this.targetWorkspace_.getVariablesOfType.bind(this.targetWorkspace_);
                +
                +  this.workspace_.deleteVariable =
                +      this.targetWorkspace_.deleteVariable.bind(this.targetWorkspace_);
                +
                +  this.workspace_.deleteVariableById =
                +      this.targetWorkspace_.deleteVariableById.bind(this.targetWorkspace_);
                +
                +  this.workspace_.renameVariable =
                +      this.targetWorkspace_.renameVariable.bind(this.targetWorkspace_);
                +
                +  this.workspace_.renameVariableById =
                +      this.targetWorkspace_.renameVariableById.bind(this.targetWorkspace_);
                +};
                +
                +/**
                + * Dispose of this flyout.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.Flyout.prototype.dispose = function() {
                +  this.hide();
                +  Blockly.unbindEvent_(this.eventWrappers_);
                +  if (this.filterWrapper_) {
                +    this.targetWorkspace_.removeChangeListener(this.filterWrapper_);
                +    this.filterWrapper_ = null;
                +  }
                +  if (this.scrollbar_) {
                +    this.scrollbar_.dispose();
                +    this.scrollbar_ = null;
                +  }
                +  if (this.workspace_) {
                +    this.workspace_.targetWorkspace = null;
                +    this.workspace_.dispose();
                +    this.workspace_ = null;
                +  }
                +  if (this.svgGroup_) {
                +    goog.dom.removeNode(this.svgGroup_);
                +    this.svgGroup_ = null;
                +  }
                +  this.svgBackground_ = null;
                +  this.targetWorkspace_ = null;
                +};
                +
                +/**
                + * Get the width of the flyout.
                + * @return {number} The width of the flyout.
                + */
                +Blockly.Flyout.prototype.getWidth = function() {
                +  return this.width_;
                +};
                +
                +/**
                + * Get the height of the flyout.
                + * @return {number} The width of the flyout.
                + */
                +Blockly.Flyout.prototype.getHeight = function() {
                +  return this.height_;
                +};
                +
                +/**
                + * Get the workspace inside the flyout.
                + * @return {!Blockly.WorkspaceSvg} The workspace inside the flyout.
                + * @package
                + */
                +Blockly.Flyout.prototype.getWorkspace = function() {
                +  return this.workspace_;
                +};
                +
                +/**
                + * Is the flyout visible?
                + * @return {boolean} True if visible.
                + */
                +Blockly.Flyout.prototype.isVisible = function() {
                +  return this.isVisible_;
                +};
                +
                + /**
                + * Set whether the flyout is visible. A value of true does not necessarily mean
                + * that the flyout is shown. It could be hidden because its container is hidden.
                + * @param {boolean} visible True if visible.
                + */
                +Blockly.Flyout.prototype.setVisible = function(visible) {
                +  var visibilityChanged = (visible != this.isVisible());
                +
                +  this.isVisible_ = visible;
                +  if (visibilityChanged) {
                +    this.updateDisplay_();
                +  }
                +};
                +
                +/**
                + * Set whether this flyout's container is visible.
                + * @param {boolean} visible Whether the container is visible.
                + */
                +Blockly.Flyout.prototype.setContainerVisible = function(visible) {
                +  var visibilityChanged = (visible != this.containerVisible_);
                +  this.containerVisible_ = visible;
                +  if (visibilityChanged) {
                +    this.updateDisplay_();
                +  }
                +};
                +
                +/**
                + * Update the display property of the flyout based whether it thinks it should
                + * be visible and whether its containing workspace is visible.
                + * @private
                + */
                +Blockly.Flyout.prototype.updateDisplay_ = function() {
                +  var show = true;
                +  if (!this.containerVisible_) {
                +    show = false;
                +  } else {
                +    show = this.isVisible();
                +  }
                +  this.svgGroup_.style.display = show ? 'block' : 'none';
                +  // Update the scrollbar's visiblity too since it should mimic the
                +  // flyout's visibility.
                +  this.scrollbar_.setContainerVisible(show);
                +};
                +
                +/**
                + * Update the view based on coordinates calculated in position().
                + * @param {number} width The computed width of the flyout's SVG group
                + * @param {number} height The computed height of the flyout's SVG group.
                + * @param {number} x The computed x origin of the flyout's SVG group.
                + * @param {number} y The computed y origin of the flyout's SVG group.
                + * @private
                + */
                +Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) {
                +  this.svgGroup_.setAttribute("width", width);
                +  this.svgGroup_.setAttribute("height", height);
                +  var transform = 'translate(' + x + 'px,' + y + 'px)';
                +  Blockly.utils.setCssTransform(this.svgGroup_, transform);
                +
                +  // Update the scrollbar (if one exists).
                +  if (this.scrollbar_) {
                +    // Set the scrollbars origin to be the top left of the flyout.
                +    this.scrollbar_.setOrigin(x, y);
                +    this.scrollbar_.resize();
                +  }
                +};
                +
                +/**
                + * Hide and empty the flyout.
                + */
                +Blockly.Flyout.prototype.hide = function() {
                +  if (!this.isVisible()) {
                +    return;
                +  }
                +  this.setVisible(false);
                +  // Delete all the event listeners.
                +  for (var x = 0, listen; listen = this.listeners_[x]; x++) {
                +    Blockly.unbindEvent_(listen);
                +  }
                +  this.listeners_.length = 0;
                +  if (this.reflowWrapper_) {
                +    this.workspace_.removeChangeListener(this.reflowWrapper_);
                +    this.reflowWrapper_ = null;
                +  }
                +  // Do NOT delete the blocks here.  Wait until Flyout.show.
                +  // https://neil.fraser.name/news/2014/08/09/
                +};
                +
                +/**
                + * Show and populate the flyout.
                + * @param {!Array|string} xmlList List of blocks to show.
                + *     Variables and procedures have a custom set of blocks.
                + */
                +Blockly.Flyout.prototype.show = function(xmlList) {
                +  this.workspace_.setResizesEnabled(false);
                +  this.hide();
                +  this.clearOldBlocks_();
                +
                +  // Handle dynamic categories, represented by a name instead of a list of XML.
                +  // Look up the correct category generation function and call that to get a
                +  // valid XML list.
                +  if (typeof xmlList == 'string') {
                +    var fnToApply = this.workspace_.targetWorkspace.getToolboxCategoryCallback(
                +        xmlList);
                +    goog.asserts.assert(goog.isFunction(fnToApply),
                +        'Couldn\'t find a callback function when opening a toolbox category.');
                +    xmlList = fnToApply(this.workspace_.targetWorkspace);
                +    goog.asserts.assert(goog.isArray(xmlList),
                +        'The result of a toolbox category callback must be an array.');
                +  }
                +
                +  this.setVisible(true);
                +  // Create the blocks to be shown in this flyout.
                +  var contents = [];
                +  var gaps = [];
                +  this.permanentlyDisabled_.length = 0;
                +  for (var i = 0, xml; xml = xmlList[i]; i++) {
                +    if (xml.tagName) {
                +      var tagName = xml.tagName.toUpperCase();
                +      var default_gap = this.horizontalLayout_ ? this.GAP_X : this.GAP_Y;
                +      if (tagName == 'BLOCK') {
                +        var curBlock = Blockly.Xml.domToBlock(xml, this.workspace_);
                +        if (curBlock.disabled) {
                +          // Record blocks that were initially disabled.
                +          // Do not enable these blocks as a result of capacity filtering.
                +          this.permanentlyDisabled_.push(curBlock);
                +        }
                +        contents.push({type: 'block', block: curBlock});
                +        var gap = parseInt(xml.getAttribute('gap'), 10);
                +        gaps.push(isNaN(gap) ? default_gap : gap);
                +      } else if (xml.tagName.toUpperCase() == 'SEP') {
                +        // Change the gap between two blocks.
                +        // <sep gap="36"></sep>
                +        // The default gap is 24, can be set larger or smaller.
                +        // This overwrites the gap attribute on the previous block.
                +        // Note that a deprecated method is to add a gap to a block.
                +        // <block type="math_arithmetic" gap="8"></block>
                +        var newGap = parseInt(xml.getAttribute('gap'), 10);
                +        // Ignore gaps before the first block.
                +        if (!isNaN(newGap) && gaps.length > 0) {
                +          gaps[gaps.length - 1] = newGap;
                +        } else {
                +          gaps.push(default_gap);
                +        }
                +      } else if (tagName == 'BUTTON' || tagName == 'LABEL') {
                +        // Labels behave the same as buttons, but are styled differently.
                +        var isLabel = tagName == 'LABEL';
                +        var curButton = new Blockly.FlyoutButton(this.workspace_,
                +            this.targetWorkspace_, xml, isLabel);
                +        contents.push({type: 'button', button: curButton});
                +        gaps.push(default_gap);
                +      }
                +    }
                +  }
                +
                +  this.layout_(contents, gaps);
                +
                +  // IE 11 is an incompetent browser that fails to fire mouseout events.
                +  // When the mouse is over the background, deselect all blocks.
                +  var deselectAll = function() {
                +    var topBlocks = this.workspace_.getTopBlocks(false);
                +    for (var i = 0, block; block = topBlocks[i]; i++) {
                +      block.removeSelect();
                +    }
                +  };
                +
                +  this.listeners_.push(Blockly.bindEventWithChecks_(this.svgBackground_,
                +      'mouseover', this, deselectAll));
                +
                +  if (this.horizontalLayout_) {
                +    this.height_ = 0;
                +  } else {
                +    this.width_ = 0;
                +  }
                +  this.workspace_.setResizesEnabled(true);
                +  this.reflow();
                +
                +  this.filterForCapacity_();
                +
                +  // Correctly position the flyout's scrollbar when it opens.
                +  this.position();
                +
                +  this.reflowWrapper_ = this.reflow.bind(this);
                +  this.workspace_.addChangeListener(this.reflowWrapper_);
                +};
                +
                +/**
                + * Delete blocks and background buttons from a previous showing of the flyout.
                + * @private
                + */
                +Blockly.Flyout.prototype.clearOldBlocks_ = function() {
                +  // Delete any blocks from a previous showing.
                +  var oldBlocks = this.workspace_.getTopBlocks(false);
                +  for (var i = 0, block; block = oldBlocks[i]; i++) {
                +    if (block.workspace == this.workspace_) {
                +      block.dispose(false, false);
                +    }
                +  }
                +  // Delete any background buttons from a previous showing.
                +  for (var j = 0, rect; rect = this.backgroundButtons_[j]; j++) {
                +    goog.dom.removeNode(rect);
                +  }
                +  this.backgroundButtons_.length = 0;
                +
                +  for (var i = 0, button; button = this.buttons_[i]; i++) {
                +    button.dispose();
                +  }
                +  this.buttons_.length = 0;
                +};
                +
                +/**
                + * Add listeners to a block that has been added to the flyout.
                + * @param {!Element} root The root node of the SVG group the block is in.
                + * @param {!Blockly.Block} block The block to add listeners for.
                + * @param {!Element} rect The invisible rectangle under the block that acts as
                + *     a button for that block.
                + * @private
                + */
                +Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) {
                +  this.listeners_.push(Blockly.bindEventWithChecks_(root, 'mousedown', null,
                +      this.blockMouseDown_(block)));
                +  this.listeners_.push(Blockly.bindEventWithChecks_(rect, 'mousedown', null,
                +      this.blockMouseDown_(block)));
                +  this.listeners_.push(Blockly.bindEvent_(root, 'mouseover', block,
                +      block.addSelect));
                +  this.listeners_.push(Blockly.bindEvent_(root, 'mouseout', block,
                +      block.removeSelect));
                +  this.listeners_.push(Blockly.bindEvent_(rect, 'mouseover', block,
                +      block.addSelect));
                +  this.listeners_.push(Blockly.bindEvent_(rect, 'mouseout', block,
                +      block.removeSelect));
                +};
                +
                +/**
                + * Handle a mouse-down on an SVG block in a non-closing flyout.
                + * @param {!Blockly.Block} block The flyout block to copy.
                + * @return {!Function} Function to call when block is clicked.
                + * @private
                + */
                +Blockly.Flyout.prototype.blockMouseDown_ = function(block) {
                +  var flyout = this;
                +  return function(e) {
                +    var gesture = flyout.targetWorkspace_.getGesture(e);
                +    if (gesture) {
                +      gesture.setStartBlock(block);
                +      gesture.handleFlyoutStart(e, flyout);
                +    }
                +  };
                +};
                +
                +/**
                + * Mouse down on the flyout background.  Start a vertical scroll drag.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Flyout.prototype.onMouseDown_ = function(e) {
                +  var gesture = this.targetWorkspace_.getGesture(e);
                +  if (gesture) {
                +    gesture.handleFlyoutStart(e, this);
                +  }
                +};
                +
                +/**
                + * Create a copy of this block on the workspace.
                + * @param {!Blockly.BlockSvg} originalBlock The block to copy from the flyout.
                + * @return {Blockly.BlockSvg} The newly created block, or null if something
                + *     went wrong with deserialization.
                + * @package
                + */
                +Blockly.Flyout.prototype.createBlock = function(originalBlock) {
                +  var newBlock = null;
                +  Blockly.Events.disable();
                +  this.targetWorkspace_.setResizesEnabled(false);
                +  try {
                +    newBlock = this.placeNewBlock_(originalBlock);
                +    //Force a render on IE and Edge to get around the issue described in
                +    //Blockly.Field.getCachedWidth
                +    if (goog.userAgent.IE || goog.userAgent.EDGE) {
                +      var blocks = newBlock.getDescendants();
                +      for (var i = blocks.length - 1; i >= 0; i--) {
                +        blocks[i].render(false);
                +      }
                +    }
                +    // Close the flyout.
                +    Blockly.hideChaff();
                +  } finally {
                +    Blockly.Events.enable();
                +  }
                +
                +  if (Blockly.Events.isEnabled()) {
                +    Blockly.Events.setGroup(true);
                +    Blockly.Events.fire(new Blockly.Events.Create(newBlock));
                +  }
                +  if (this.autoClose) {
                +    this.hide();
                +  } else {
                +    this.filterForCapacity_();
                +  }
                +  return newBlock;
                +};
                +
                +/**
                + * Initialize the given button: move it to the correct location,
                + * add listeners, etc.
                + * @param {!Blockly.FlyoutButton} button The button to initialize and place.
                + * @param {number} x The x position of the cursor during this layout pass.
                + * @param {number} y The y position of the cursor during this layout pass.
                + * @private
                + */
                +Blockly.Flyout.prototype.initFlyoutButton_ = function(button, x, y) {
                +  var buttonSvg = button.createDom();
                +  button.moveTo(x, y);
                +  button.show();
                +  // Clicking on a flyout button or label is a lot like clicking on the
                +  // flyout background.
                +  this.listeners_.push(Blockly.bindEventWithChecks_(buttonSvg, 'mousedown',
                +       this, this.onMouseDown_));
                +
                +  this.buttons_.push(button);
                +};
                +
                +/**
                + * Create and place a rectangle corresponding to the given block.
                + * @param {!Blockly.Block} block The block to associate the rect to.
                + * @param {number} x The x position of the cursor during this layout pass.
                + * @param {number} y The y position of the cursor during this layout pass.
                + * @param {!{height: number, width: number}} blockHW The height and width of the
                + *     block.
                + * @param {number} index The index into the background buttons list where this
                + *     rect should be placed.
                + * @return {!SVGElement} Newly created SVG element for the rectangle behind the
                + *     block.
                + * @private
                + */
                +Blockly.Flyout.prototype.createRect_ = function(block, x, y, blockHW, index) {
                +  // Create an invisible rectangle under the block to act as a button.  Just
                +  // using the block as a button is poor, since blocks have holes in them.
                +  var rect = Blockly.utils.createSvgElement('rect',
                +    {
                +      'fill-opacity': 0,
                +      'x': x,
                +      'y': y,
                +      'height': blockHW.height,
                +      'width': blockHW.width
                +    }, null);
                +  rect.tooltip = block;
                +  Blockly.Tooltip.bindMouseEvents(rect);
                +  // Add the rectangles under the blocks, so that the blocks' tooltips work.
                +  this.workspace_.getCanvas().insertBefore(rect, block.getSvgRoot());
                +
                +  block.flyoutRect_ = rect;
                +  this.backgroundButtons_[index] = rect;
                +  return rect;
                +};
                +
                +/**
                + * Move a rectangle to sit exactly behind a block, taking into account tabs,
                + * hats, and any other protrusions we invent.
                + * @param {!SVGElement} rect The rectangle to move directly behind the block.
                + * @param {!Blockly.BlockSvg} block The block the rectangle should be behind.
                + * @private
                + */
                +Blockly.Flyout.prototype.moveRectToBlock_ = function(rect, block) {
                +  var blockHW = block.getHeightWidth();
                +  rect.setAttribute('width', blockHW.width);
                +  rect.setAttribute('height', blockHW.height);
                +
                +  // For hat blocks we want to shift them down by the hat height
                +  // since the y coordinate is the corner, not the top of the hat.
                +  var hatOffset =
                +      block.startHat_ ? Blockly.BlockSvg.START_HAT_HEIGHT : 0;
                +  if (hatOffset) {
                +    block.moveBy(0, hatOffset);
                +  }
                +
                +  // Blocks with output tabs are shifted a bit.
                +  var tab = block.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
                +  var blockXY = block.getRelativeToSurfaceXY();
                +  rect.setAttribute('y', blockXY.y);
                +  rect.setAttribute('x',
                +      this.RTL ? blockXY.x - blockHW.width + tab : blockXY.x - tab);
                +};
                +
                +/**
                + * Filter the blocks on the flyout to disable the ones that are above the
                + * capacity limit.  For instance, if the user may only place two more blocks on
                + * the workspace, an "a + b" block that has two shadow blocks would be disabled.
                + * @private
                + */
                +Blockly.Flyout.prototype.filterForCapacity_ = function() {
                +  var remainingCapacity = this.targetWorkspace_.remainingCapacity();
                +  var blocks = this.workspace_.getTopBlocks(false);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (this.permanentlyDisabled_.indexOf(block) == -1) {
                +      var allBlocks = block.getDescendants();
                +      block.setDisabled(allBlocks.length > remainingCapacity);
                +    }
                +  }
                +};
                +
                +/**
                + * Reflow blocks and their buttons.
                + */
                +Blockly.Flyout.prototype.reflow = function() {
                +  if (this.reflowWrapper_) {
                +    this.workspace_.removeChangeListener(this.reflowWrapper_);
                +  }
                +  var blocks = this.workspace_.getTopBlocks(false);
                +  this.reflowInternal_(blocks);
                +  if (this.reflowWrapper_) {
                +    this.workspace_.addChangeListener(this.reflowWrapper_);
                +  }
                +};
                +
                +/**
                + * @return {boolean} True if this flyout may be scrolled with a scrollbar or by
                + *     dragging.
                + * @package
                + */
                +Blockly.Flyout.prototype.isScrollable = function() {
                +  return this.scrollbar_ ? this.scrollbar_.isVisible() : false;
                +};
                +
                +/**
                + * Copy a block from the flyout to the workspace and position it correctly.
                + * @param {!Blockly.Block} oldBlock The flyout block to copy.
                + * @return {!Blockly.Block} The new block in the main workspace.
                + * @private
                + */
                +Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
                +  var targetWorkspace = this.targetWorkspace_;
                +  var svgRootOld = oldBlock.getSvgRoot();
                +  if (!svgRootOld) {
                +    throw 'oldBlock is not rendered.';
                +  }
                +
                +  // Create the new block by cloning the block in the flyout (via XML).
                +  var xml = Blockly.Xml.blockToDom(oldBlock);
                +  // The target workspace would normally resize during domToBlock, which will
                +  // lead to weird jumps.  Save it for terminateDrag.
                +  targetWorkspace.setResizesEnabled(false);
                +
                +  // Using domToBlock instead of domToWorkspace means that the new block will be
                +  // placed at position (0, 0) in main workspace units.
                +  var block = Blockly.Xml.domToBlock(xml, targetWorkspace);
                +  var svgRootNew = block.getSvgRoot();
                +  if (!svgRootNew) {
                +    throw 'block is not rendered.';
                +  }
                +
                +  // The offset in pixels between the main workspace's origin and the upper left
                +  // corner of the injection div.
                +  var mainOffsetPixels = targetWorkspace.getOriginOffsetInPixels();
                +
                +  // The offset in pixels between the flyout workspace's origin and the upper
                +  // left corner of the injection div.
                +  var flyoutOffsetPixels = this.workspace_.getOriginOffsetInPixels();
                +
                +  // The position of the old block in flyout workspace coordinates.
                +  var oldBlockPosWs = oldBlock.getRelativeToSurfaceXY();
                +
                +  // The position of the old block in pixels relative to the flyout
                +  // workspace's origin.
                +  var oldBlockPosPixels = oldBlockPosWs.scale(this.workspace_.scale);
                +
                +  // The position of the old block in pixels relative to the upper left corner
                +  // of the injection div.
                +  var oldBlockOffsetPixels = goog.math.Coordinate.sum(flyoutOffsetPixels,
                +      oldBlockPosPixels);
                +
                +  // The position of the old block in pixels relative to the origin of the
                +  // main workspace.
                +  var finalOffsetPixels = goog.math.Coordinate.difference(oldBlockOffsetPixels,
                +      mainOffsetPixels);
                +
                +  // The position of the old block in main workspace coordinates.
                +  var finalOffsetMainWs = finalOffsetPixels.scale(1 / targetWorkspace.scale);
                +
                +  block.moveBy(finalOffsetMainWs.x, finalOffsetMainWs.y);
                +  return block;
                +};
                diff --git a/blockly/webif/static/blockly/core/flyout_button.js b/blockly/webif/static/blockly/core/flyout_button.js
                new file mode 100644
                index 000000000..965ce8ef3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/flyout_button.js
                @@ -0,0 +1,246 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Class for a button in the flyout.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FlyoutButton');
                +
                +goog.require('goog.dom');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Class for a button in the flyout.
                + * @param {!Blockly.WorkspaceSvg} workspace The workspace in which to place this
                + *     button.
                + * @param {!Blockly.WorkspaceSvg} targetWorkspace The flyout's target workspace.
                + * @param {!Element} xml The XML specifying the label/button.
                + * @param {boolean} isLabel Whether this button should be styled as a label.
                + * @constructor
                + */
                +Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) {
                +  // Labels behave the same as buttons, but are styled differently.
                +
                +  /**
                +   * @type {!Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.workspace_ = workspace;
                +
                +  /**
                +   * @type {!Blockly.Workspace}
                +   * @private
                +   */
                +  this.targetWorkspace_ = targetWorkspace;
                +
                +  /**
                +   * @type {string}
                +   * @private
                +   */
                +  this.text_ = xml.getAttribute('text');
                +
                +  /**
                +   * @type {!goog.math.Coordinate}
                +   * @private
                +   */
                +  this.position_ = new goog.math.Coordinate(0, 0);
                +
                +  /**
                +   * Whether this button should be styled as a label.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.isLabel_ = isLabel;
                +
                +  /**
                +   * Function to call when this button is clicked.
                +   * @type {function(!Blockly.FlyoutButton)}
                +   * @private
                +   */
                +  this.callback_ = null;
                +
                +  var callbackKey = xml.getAttribute('callbackKey');
                +  if (this.isLabel_ && callbackKey) {
                +    console.warn('Labels should not have callbacks. Label text: ' + this.text_);
                +  } else if (!this.isLabel_ &&
                +      !(callbackKey && targetWorkspace.getButtonCallback(callbackKey))) {
                +    console.warn('Buttons should have callbacks. Button text: ' + this.text_);
                +  } else {
                +    this.callback_ = targetWorkspace.getButtonCallback(callbackKey);
                +  }
                +
                +  /**
                +   * If specified, a CSS class to add to this button.
                +   * @type {?string}
                +   * @private
                +   */
                +  this.cssClass_ = xml.getAttribute('web-class') || null;
                +};
                +
                +/**
                + * The margin around the text in the button.
                + */
                +Blockly.FlyoutButton.MARGIN = 5;
                +
                +/**
                + * The width of the button's rect.
                + * @type {number}
                + */
                +Blockly.FlyoutButton.prototype.width = 0;
                +
                +/**
                + * The height of the button's rect.
                + * @type {number}
                + */
                +Blockly.FlyoutButton.prototype.height = 0;
                +
                +/**
                + * Opaque data that can be passed to Blockly.unbindEvent_.
                + * @type {Array.<!Array>}
                + * @private
                + */
                +Blockly.FlyoutButton.prototype.onMouseUpWrapper_ = null;
                +
                +/**
                + * Create the button elements.
                + * @return {!Element} The button's SVG group.
                + */
                +Blockly.FlyoutButton.prototype.createDom = function() {
                +  var cssClass = this.isLabel_ ? 'blocklyFlyoutLabel' : 'blocklyFlyoutButton';
                +  if (this.cssClass_) {
                +    cssClass += ' ' + this.cssClass_;
                +  }
                +
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g', {'class': cssClass},
                +      this.workspace_.getCanvas());
                +
                +  if (!this.isLabel_) {
                +    // Shadow rectangle (light source does not mirror in RTL).
                +    var shadow = Blockly.utils.createSvgElement('rect',
                +        {'class': 'blocklyFlyoutButtonShadow',
                +         'rx': 4, 'ry': 4, 'x': 1, 'y': 1},
                +         this.svgGroup_);
                +  }
                +  // Background rectangle.
                +  var rect = Blockly.utils.createSvgElement('rect',
                +      {'class': this.isLabel_ ?
                +        'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground',
                +        'rx': 4, 'ry': 4},
                +      this.svgGroup_);
                +
                +  var svgText = Blockly.utils.createSvgElement('text',
                +      {'class': this.isLabel_ ? 'blocklyFlyoutLabelText' : 'blocklyText',
                +          'x': 0, 'y': 0, 'text-anchor': 'middle'},
                +      this.svgGroup_);
                +  svgText.textContent = this.text_;
                +
                +  this.width = svgText.getComputedTextLength() +
                +      2 * Blockly.FlyoutButton.MARGIN;
                +  this.height = 20;  // Can't compute it :(
                +
                +  if (!this.isLabel_) {
                +    shadow.setAttribute('width', this.width);
                +    shadow.setAttribute('height', this.height);
                +  }
                +  rect.setAttribute('width', this.width);
                +  rect.setAttribute('height', this.height);
                +
                +  svgText.setAttribute('x', this.width / 2);
                +  svgText.setAttribute('y', this.height - Blockly.FlyoutButton.MARGIN);
                +
                +  this.updateTransform_();
                +
                +  this.mouseUpWrapper_ = Blockly.bindEventWithChecks_(this.svgGroup_, 'mouseup',
                +      this, this.onMouseUp_);
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Correctly position the flyout button and make it visible.
                + */
                +Blockly.FlyoutButton.prototype.show = function() {
                +  this.updateTransform_();
                +  this.svgGroup_.setAttribute('display', 'block');
                +};
                +
                +/**
                + * Update svg attributes to match internal state.
                + * @private
                + */
                +Blockly.FlyoutButton.prototype.updateTransform_ = function() {
                +  this.svgGroup_.setAttribute('transform',
                +      'translate(' + this.position_.x + ',' + this.position_.y + ')');
                +};
                +
                +/**
                + * Move the button to the given x, y coordinates.
                + * @param {number} x The new x coordinate.
                + * @param {number} y The new y coordinate.
                + */
                +Blockly.FlyoutButton.prototype.moveTo = function(x, y) {
                +  this.position_.x = x;
                +  this.position_.y = y;
                +  this.updateTransform_();
                +};
                +
                +/**
                + * Get the button's target workspace.
                + * @return {!Blockly.WorkspaceSvg} The target workspace of the flyout where this
                + *     button resides.
                + */
                +Blockly.FlyoutButton.prototype.getTargetWorkspace = function() {
                +  return this.targetWorkspace_;
                +};
                +
                +/**
                + * Dispose of this button.
                + */
                +Blockly.FlyoutButton.prototype.dispose = function() {
                +  if (this.onMouseUpWrapper_) {
                +    Blockly.unbindEvent_(this.onMouseUpWrapper_);
                +  }
                +  if (this.svgGroup_) {
                +    goog.dom.removeNode(this.svgGroup_);
                +    this.svgGroup_ = null;
                +  }
                +  this.workspace_ = null;
                +  this.targetWorkspace_ = null;
                +};
                +
                +/**
                + * Do something when the button is clicked.
                + * @param {!Event} e Mouse up event.
                + * @private
                + */
                +Blockly.FlyoutButton.prototype.onMouseUp_ = function(e) {
                +  var gesture = this.targetWorkspace_.getGesture(e);
                +  if (gesture) {
                +    gesture.cancel();
                +  }
                +
                +  // Call the callback registered to this button.
                +  if (this.callback_) {
                +    this.callback_(this);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/flyout_dragger.js b/blockly/webif/static/blockly/core/flyout_dragger.js
                new file mode 100644
                index 000000000..c3909eaf2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/flyout_dragger.js
                @@ -0,0 +1,83 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Methods for dragging a flyout visually.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.FlyoutDragger');
                +
                +goog.require('Blockly.WorkspaceDragger');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Class for a flyout dragger.  It moves a flyout workspace around when it is
                + * being dragged by a mouse or touch.
                + * Note that the workspace itself manages whether or not it has a drag surface
                + * and how to do translations based on that.  This simply passes the right
                + * commands based on events.
                + * @param {!Blockly.Flyout} flyout The flyout to drag.
                + * @constructor
                + */
                +Blockly.FlyoutDragger = function(flyout) {
                +  Blockly.FlyoutDragger.superClass_.constructor.call(this,
                +      flyout.getWorkspace());
                +
                +  /**
                +   * The scrollbar to update to move the flyout.
                +   * Unlike the main workspace, the flyout has only one scrollbar, in either the
                +   * horizontal or the vertical direction.
                +   * @type {!Blockly.Scrollbar}
                +   * @private
                +   */
                +  this.scrollbar_ = flyout.scrollbar_;
                +
                +  /**
                +   * Whether the flyout scrolls horizontally.  If false, the flyout scrolls
                +   * vertically.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.horizontalLayout_ = flyout.horizontalLayout_;
                +};
                +goog.inherits(Blockly.FlyoutDragger, Blockly.WorkspaceDragger);
                +
                +/**
                + * Move the appropriate scrollbar to drag the flyout.
                + * Since flyouts only scroll in one direction at a time, this will discard one
                + * of the calculated values.
                + * x and y are in pixels.
                + * @param {number} x The new x position to move the scrollbar to.
                + * @param {number} y The new y position to move the scrollbar to.
                + * @private
                + */
                +Blockly.FlyoutDragger.prototype.updateScroll_ = function(x, y) {
                +  // Move the scrollbar and the flyout will scroll automatically.
                +  if (this.horizontalLayout_) {
                +    this.scrollbar_.set(x);
                +  } else {
                +    this.scrollbar_.set(y);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/flyout_horizontal.js b/blockly/webif/static/blockly/core/flyout_horizontal.js
                new file mode 100644
                index 000000000..e09d95512
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/flyout_horizontal.js
                @@ -0,0 +1,380 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Horizontal flyout tray containing blocks which may be created.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.HorizontalFlyout');
                +
                +goog.require('Blockly.Block');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.FlyoutButton');
                +goog.require('Blockly.Flyout');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.math.Rect');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a flyout.
                + * @param {!Object} workspaceOptions Dictionary of options for the workspace.
                + * @extends {Blockly.Flyout}
                + * @constructor
                + */
                +Blockly.HorizontalFlyout = function(workspaceOptions) {
                +  workspaceOptions.getMetrics = this.getMetrics_.bind(this);
                +  workspaceOptions.setMetrics = this.setMetrics_.bind(this);
                +
                +  Blockly.HorizontalFlyout.superClass_.constructor.call(this, workspaceOptions);
                +  /**
                +   * Flyout should be laid out horizontally.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.horizontalLayout_ = true;
                +};
                +goog.inherits(Blockly.HorizontalFlyout, Blockly.Flyout);
                +
                +/**
                + * Return an object with all the metrics required to size scrollbars for the
                + * flyout.  The following properties are computed:
                + * .viewHeight: Height of the visible rectangle,
                + * .viewWidth: Width of the visible rectangle,
                + * .contentHeight: Height of the contents,
                + * .contentWidth: Width of the contents,
                + * .viewTop: Offset of top edge of visible rectangle from parent,
                + * .contentTop: Offset of the top-most content from the y=0 coordinate,
                + * .absoluteTop: Top-edge of view.
                + * .viewLeft: Offset of the left edge of visible rectangle from parent,
                + * .contentLeft: Offset of the left-most content from the x=0 coordinate,
                + * .absoluteLeft: Left-edge of view.
                + * @return {Object} Contains size and position metrics of the flyout.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
                +  if (!this.isVisible()) {
                +    // Flyout is hidden.
                +    return null;
                +  }
                +
                +  try {
                +    var optionBox = this.workspace_.getCanvas().getBBox();
                +  } catch (e) {
                +    // Firefox has trouble with hidden elements (Bug 528969).
                +    var optionBox = {height: 0, y: 0, width: 0, x: 0};
                +  }
                +
                +  var absoluteTop = this.SCROLLBAR_PADDING;
                +  var absoluteLeft = this.SCROLLBAR_PADDING;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) {
                +    absoluteTop = 0;
                +  }
                +  var viewHeight = this.height_;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
                +    viewHeight -= this.SCROLLBAR_PADDING;
                +  }
                +  var viewWidth = this.width_ - 2 * this.SCROLLBAR_PADDING;
                +
                +  var metrics = {
                +    viewHeight: viewHeight,
                +    viewWidth: viewWidth,
                +    contentHeight: (optionBox.height + 2 * this.MARGIN) * this.workspace_.scale,
                +    contentWidth: (optionBox.width + 2 * this.MARGIN) * this.workspace_.scale,
                +    viewTop: -this.workspace_.scrollY,
                +    viewLeft: -this.workspace_.scrollX,
                +    contentTop: optionBox.y,
                +    contentLeft: optionBox.x,
                +    absoluteTop: absoluteTop,
                +    absoluteLeft: absoluteLeft
                +  };
                +  return metrics;
                +};
                +
                +/**
                + * Sets the translation of the flyout to match the scrollbars.
                + * @param {!Object} xyRatio Contains a y property which is a float
                + *     between 0 and 1 specifying the degree of scrolling and a
                + *     similar x property.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
                +  var metrics = this.getMetrics_();
                +  // This is a fix to an apparent race condition.
                +  if (!metrics) {
                +    return;
                +  }
                +
                +  if (goog.isNumber(xyRatio.x)) {
                +    this.workspace_.scrollX = -metrics.contentWidth * xyRatio.x;
                +  }
                +
                +  this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft,
                +      this.workspace_.scrollY + metrics.absoluteTop);
                +};
                +
                +/**
                + * Move the flyout to the edge of the workspace.
                + */
                +Blockly.HorizontalFlyout.prototype.position = function() {
                +  if (!this.isVisible()) {
                +    return;
                +  }
                +  var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics();
                +  if (!targetWorkspaceMetrics) {
                +    // Hidden components will return null.
                +    return;
                +  }
                +  // Record the width for Blockly.Flyout.getMetrics_.
                +  this.width_ = targetWorkspaceMetrics.viewWidth;
                +
                +  var edgeWidth = targetWorkspaceMetrics.viewWidth - 2 * this.CORNER_RADIUS;
                +  var edgeHeight = this.height_ - this.CORNER_RADIUS;
                +  this.setBackgroundPath_(edgeWidth, edgeHeight);
                +
                +  var x = targetWorkspaceMetrics.absoluteLeft;
                +  var y = targetWorkspaceMetrics.absoluteTop;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) {
                +    y += (targetWorkspaceMetrics.viewHeight - this.height_);
                +  }
                +  this.positionAt_(this.width_, this.height_, x, y);
                +};
                +
                +/**
                + * Create and set the path for the visible boundaries of the flyout.
                + * @param {number} width The width of the flyout, not including the
                + *     rounded corners.
                + * @param {number} height The height of the flyout, not including
                + *     rounded corners.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(width,
                +    height) {
                +  var atTop = this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP;
                +  // Start at top left.
                +  var path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)];
                +
                +  if (atTop) {
                +    // Top.
                +    path.push('h', width + 2 * this.CORNER_RADIUS);
                +    // Right.
                +    path.push('v', height);
                +    // Bottom.
                +    path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
                +        -this.CORNER_RADIUS, this.CORNER_RADIUS);
                +    path.push('h', -1 * width);
                +    // Left.
                +    path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
                +        -this.CORNER_RADIUS, -this.CORNER_RADIUS);
                +    path.push('z');
                +  } else {
                +    // Top.
                +    path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
                +        this.CORNER_RADIUS, -this.CORNER_RADIUS);
                +    path.push('h', width);
                +     // Right.
                +    path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1,
                +        this.CORNER_RADIUS, this.CORNER_RADIUS);
                +    path.push('v', height);
                +    // Bottom.
                +    path.push('h', -width - 2 * this.CORNER_RADIUS);
                +    // Left.
                +    path.push('z');
                +  }
                +  this.svgBackground_.setAttribute('d', path.join(' '));
                +};
                +
                +/**
                + * Scroll the flyout to the top.
                + */
                +Blockly.HorizontalFlyout.prototype.scrollToStart = function() {
                +  this.scrollbar_.set(this.RTL ? Infinity : 0);
                +};
                +
                +/**
                + * Scroll the flyout.
                + * @param {!Event} e Mouse wheel scroll event.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.wheel_ = function(e) {
                +  var delta = e.deltaX;
                +
                +  if (delta) {
                +    if (goog.userAgent.GECKO) {
                +      // Firefox's deltas are a tenth that of Chrome/Safari.
                +      delta *= 10;
                +    }
                +    // TODO: #1093
                +    var metrics = this.getMetrics_();
                +    var pos = metrics.viewLeft + delta;
                +    var limit = metrics.contentWidth - metrics.viewWidth;
                +    pos = Math.min(pos, limit);
                +    pos = Math.max(pos, 0);
                +    this.scrollbar_.set(pos);
                +    // When the flyout moves from a wheel event, hide WidgetDiv.
                +    Blockly.WidgetDiv.hide();
                +  }
                +
                +  // Don't scroll the page.
                +  e.preventDefault();
                +  // Don't propagate mousewheel event (zooming).
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Lay out the blocks in the flyout.
                + * @param {!Array.<!Object>} contents The blocks and buttons to lay out.
                + * @param {!Array.<number>} gaps The visible gaps between blocks.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.layout_ = function(contents, gaps) {
                +  this.workspace_.scale = this.targetWorkspace_.scale;
                +  var margin = this.MARGIN;
                +  var cursorX = this.RTL ? margin : margin + Blockly.BlockSvg.TAB_WIDTH;
                +  var cursorY = margin;
                +  if (this.RTL) {
                +    contents = contents.reverse();
                +  }
                +
                +  for (var i = 0, item; item = contents[i]; i++) {
                +    if (item.type == 'block') {
                +      var block = item.block;
                +      var allBlocks = block.getDescendants();
                +      for (var j = 0, child; child = allBlocks[j]; j++) {
                +        // Mark blocks as being inside a flyout.  This is used to detect and
                +        // prevent the closure of the flyout if the user right-clicks on such a
                +        // block.
                +        child.isInFlyout = true;
                +      }
                +      block.render();
                +      var root = block.getSvgRoot();
                +      var blockHW = block.getHeightWidth();
                +
                +      // Figure out where to place the block.
                +      var tab = block.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
                +      if (this.RTL) {
                +        var moveX = cursorX + blockHW.width;
                +      } else {
                +        var moveX = cursorX + tab;
                +      }
                +      block.moveBy(moveX, cursorY);
                +
                +      var rect = this.createRect_(block, moveX, cursorY, blockHW, i);
                +      cursorX += (blockHW.width + gaps[i]);
                +
                +      this.addBlockListeners_(root, block, rect);
                +    } else if (item.type == 'button') {
                +      this.initFlyoutButton_(item.button, cursorX, cursorY);
                +      cursorX += (item.button.width + gaps[i]);
                +    }
                +  }
                +};
                +
                +/**
                + * Determine if a drag delta is toward the workspace, based on the position
                + * and orientation of the flyout. This is used in determineDragIntention_ to
                + * determine if a new block should be created or if the flyout should scroll.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at mouse down, in pixel units.
                + * @return {boolean} true if the drag is toward the workspace.
                + * @package
                + */
                +Blockly.HorizontalFlyout.prototype.isDragTowardWorkspace = function(
                +    currentDragDeltaXY) {
                +  var dx = currentDragDeltaXY.x;
                +  var dy = currentDragDeltaXY.y;
                +  // Direction goes from -180 to 180, with 0 toward the right and 90 on top.
                +  var dragDirection = Math.atan2(dy, dx) / Math.PI * 180;
                +
                +  var range = this.dragAngleRange_;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
                +    // Horizontal at top.
                +    if (dragDirection < 90 + range && dragDirection > 90 - range) {
                +      return true;
                +    }
                +  } else {
                +    // Horizontal at bottom.
                +    if (dragDirection > -90 - range && dragDirection < -90 + range) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Return the deletion rectangle for this flyout in viewport coordinates.
                + * @return {goog.math.Rect} Rectangle in which to delete.
                + */
                +Blockly.HorizontalFlyout.prototype.getClientRect = function() {
                +  if (!this.svgGroup_) {
                +    return null;
                +  }
                +
                +  var flyoutRect = this.svgGroup_.getBoundingClientRect();
                +  // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout
                +  // area are still deleted.  Must be larger than the largest screen size,
                +  // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE).
                +  var BIG_NUM = 1000000000;
                +  var y = flyoutRect.top;
                +  var height = flyoutRect.height;
                +
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
                +    return new goog.math.Rect(-BIG_NUM, y - BIG_NUM, BIG_NUM * 2,
                +        BIG_NUM + height);
                +  } else if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) {
                +    return new goog.math.Rect(-BIG_NUM, y, BIG_NUM * 2,
                +        BIG_NUM + height);
                +  }
                +  // TODO: Else throw error (should never happen).
                +};
                +
                +/**
                + * Compute height of flyout.  Position button under each block.
                + * For RTL: Lay out the blocks right-aligned.
                + * @param {!Array<!Blockly.Block>} blocks The blocks to reflow.
                + * @private
                + */
                +Blockly.HorizontalFlyout.prototype.reflowInternal_ = function(blocks) {
                +  this.workspace_.scale = this.targetWorkspace_.scale;
                +  var flyoutHeight = 0;
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    flyoutHeight = Math.max(flyoutHeight, block.getHeightWidth().height);
                +  }
                +  flyoutHeight += this.MARGIN * 1.5;
                +  flyoutHeight *= this.workspace_.scale;
                +  flyoutHeight += Blockly.Scrollbar.scrollbarThickness;
                +
                +  if (this.height_ != flyoutHeight) {
                +    for (var i = 0, block; block = blocks[i]; i++) {
                +      if (block.flyoutRect_) {
                +        this.moveRectToBlock_(block.flyoutRect_, block);
                +      }
                +    }
                +    // Record the height for .getMetrics_ and .position.
                +    this.height_ = flyoutHeight;
                +    // Call this since it is possible the trash and zoom buttons need
                +    // to move. e.g. on a bottom positioned flyout when zoom is clicked.
                +    this.targetWorkspace_.resize();
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/flyout_vertical.js b/blockly/webif/static/blockly/core/flyout_vertical.js
                new file mode 100644
                index 000000000..19d7a4330
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/flyout_vertical.js
                @@ -0,0 +1,370 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Layout code for a vertical variant of the flyout.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.VerticalFlyout');
                +
                +goog.require('Blockly.Block');
                +goog.require('Blockly.Events');
                +goog.require('Blockly.Flyout');
                +goog.require('Blockly.FlyoutButton');
                +goog.require('Blockly.utils');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +goog.require('goog.math.Rect');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a flyout.
                + * @param {!Object} workspaceOptions Dictionary of options for the workspace.
                + * @extends {Blockly.Flyout}
                + * @constructor
                + */
                +Blockly.VerticalFlyout = function(workspaceOptions) {
                +  workspaceOptions.getMetrics = this.getMetrics_.bind(this);
                +  workspaceOptions.setMetrics = this.setMetrics_.bind(this);
                +
                +  Blockly.VerticalFlyout.superClass_.constructor.call(this, workspaceOptions);
                +  /**
                +   * Flyout should be laid out vertically.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.horizontalLayout_ = false;
                +};
                +goog.inherits(Blockly.VerticalFlyout, Blockly.Flyout);
                +
                +/**
                + * Return an object with all the metrics required to size scrollbars for the
                + * flyout.  The following properties are computed:
                + * .viewHeight: Height of the visible rectangle,
                + * .viewWidth: Width of the visible rectangle,
                + * .contentHeight: Height of the contents,
                + * .contentWidth: Width of the contents,
                + * .viewTop: Offset of top edge of visible rectangle from parent,
                + * .contentTop: Offset of the top-most content from the y=0 coordinate,
                + * .absoluteTop: Top-edge of view.
                + * .viewLeft: Offset of the left edge of visible rectangle from parent,
                + * .contentLeft: Offset of the left-most content from the x=0 coordinate,
                + * .absoluteLeft: Left-edge of view.
                + * @return {Object} Contains size and position metrics of the flyout.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
                +  if (!this.isVisible()) {
                +    // Flyout is hidden.
                +    return null;
                +  }
                +
                +  try {
                +    var optionBox = this.workspace_.getCanvas().getBBox();
                +  } catch (e) {
                +    // Firefox has trouble with hidden elements (Bug 528969).
                +    var optionBox = {height: 0, y: 0, width: 0, x: 0};
                +  }
                +
                +  // Padding for the end of the scrollbar.
                +  var absoluteTop = this.SCROLLBAR_PADDING;
                +  var absoluteLeft = 0;
                +
                +  var viewHeight = this.height_ - 2 * this.SCROLLBAR_PADDING;
                +  var viewWidth = this.width_;
                +  if (!this.RTL) {
                +    viewWidth -= this.SCROLLBAR_PADDING;
                +  }
                +
                +  var metrics = {
                +    viewHeight: viewHeight,
                +    viewWidth: viewWidth,
                +    contentHeight: optionBox.height * this.workspace_.scale + 2 * this.MARGIN,
                +    contentWidth: optionBox.width * this.workspace_.scale + 2 * this.MARGIN,
                +    viewTop: -this.workspace_.scrollY + optionBox.y,
                +    viewLeft: -this.workspace_.scrollX,
                +    contentTop: optionBox.y,
                +    contentLeft: optionBox.x,
                +    absoluteTop: absoluteTop,
                +    absoluteLeft: absoluteLeft
                +  };
                +  return metrics;
                +};
                +
                +/**
                + * Sets the translation of the flyout to match the scrollbars.
                + * @param {!Object} xyRatio Contains a y property which is a float
                + *     between 0 and 1 specifying the degree of scrolling and a
                + *     similar x property.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
                +  var metrics = this.getMetrics_();
                +  // This is a fix to an apparent race condition.
                +  if (!metrics) {
                +    return;
                +  }
                +  if (goog.isNumber(xyRatio.y)) {
                +    this.workspace_.scrollY = -metrics.contentHeight * xyRatio.y;
                +  }
                +  this.workspace_.translate(this.workspace_.scrollX + metrics.absoluteLeft,
                +      this.workspace_.scrollY + metrics.absoluteTop);
                +};
                +
                +/**
                + * Move the flyout to the edge of the workspace.
                + */
                +Blockly.VerticalFlyout.prototype.position = function() {
                +  if (!this.isVisible()) {
                +    return;
                +  }
                +  var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics();
                +  if (!targetWorkspaceMetrics) {
                +    // Hidden components will return null.
                +    return;
                +  }
                +  // Record the height for Blockly.Flyout.getMetrics_
                +  this.height_ = targetWorkspaceMetrics.viewHeight;
                +
                +  var edgeWidth = this.width_ - this.CORNER_RADIUS;
                +  var edgeHeight = targetWorkspaceMetrics.viewHeight - 2 * this.CORNER_RADIUS;
                +  this.setBackgroundPath_(edgeWidth, edgeHeight);
                +
                +  var y = targetWorkspaceMetrics.absoluteTop;
                +  var x = targetWorkspaceMetrics.absoluteLeft;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT) {
                +    x += (targetWorkspaceMetrics.viewWidth - this.width_);
                +  }
                +  this.positionAt_(this.width_, this.height_, x, y);
                +};
                +
                +/**
                + * Create and set the path for the visible boundaries of the flyout.
                + * @param {number} width The width of the flyout, not including the
                + *     rounded corners.
                + * @param {number} height The height of the flyout, not including
                + *     rounded corners.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
                +  var atRight = this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT;
                +  var totalWidth = width + this.CORNER_RADIUS;
                +
                +  // Decide whether to start on the left or right.
                +  var path = ['M ' + (atRight ? totalWidth : 0) + ',0'];
                +  // Top.
                +  path.push('h', atRight ? -width : width);
                +  // Rounded corner.
                +  path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
                +      atRight ? 0 : 1,
                +      atRight ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
                +      this.CORNER_RADIUS);
                +  // Side closest to workspace.
                +  path.push('v', Math.max(0, height));
                +  // Rounded corner.
                +  path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
                +      atRight ? 0 : 1,
                +      atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
                +      this.CORNER_RADIUS);
                +  // Bottom.
                +  path.push('h',  atRight ? width : -width);
                +  path.push('z');
                +  this.svgBackground_.setAttribute('d', path.join(' '));
                +};
                +
                +/**
                + * Scroll the flyout to the top.
                + */
                +Blockly.VerticalFlyout.prototype.scrollToStart = function() {
                +  this.scrollbar_.set(0);
                +};
                +
                +/**
                + * Scroll the flyout.
                + * @param {!Event} e Mouse wheel scroll event.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.wheel_ = function(e) {
                +  var delta = e.deltaY;
                +
                +  if (delta) {
                +    if (goog.userAgent.GECKO) {
                +      // Firefox's deltas are a tenth that of Chrome/Safari.
                +      delta *= 10;
                +    }
                +    var metrics = this.getMetrics_();
                +    var pos = metrics.viewTop + delta;
                +    var limit = metrics.contentHeight - metrics.viewHeight;
                +    pos = Math.min(pos, limit);
                +    pos = Math.max(pos, 0);
                +    this.scrollbar_.set(pos);
                +    // When the flyout moves from a wheel event, hide WidgetDiv.
                +    Blockly.WidgetDiv.hide();
                +  }
                +
                +  // Don't scroll the page.
                +  e.preventDefault();
                +  // Don't propagate mousewheel event (zooming).
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Lay out the blocks in the flyout.
                + * @param {!Array.<!Object>} contents The blocks and buttons to lay out.
                + * @param {!Array.<number>} gaps The visible gaps between blocks.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) {
                +  this.workspace_.scale = this.targetWorkspace_.scale;
                +  var margin = this.MARGIN;
                +  var cursorX = this.RTL ? margin : margin + Blockly.BlockSvg.TAB_WIDTH;
                +  var cursorY = margin;
                +
                +  for (var i = 0, item; item = contents[i]; i++) {
                +    if (item.type == 'block') {
                +      var block = item.block;
                +      var allBlocks = block.getDescendants();
                +      for (var j = 0, child; child = allBlocks[j]; j++) {
                +        // Mark blocks as being inside a flyout.  This is used to detect and
                +        // prevent the closure of the flyout if the user right-clicks on such a
                +        // block.
                +        child.isInFlyout = true;
                +      }
                +      block.render();
                +      var root = block.getSvgRoot();
                +      var blockHW = block.getHeightWidth();
                +      block.moveBy(cursorX, cursorY);
                +
                +      var rect = this.createRect_(block,
                +          this.RTL ? cursorX - blockHW.width : cursorX, cursorY, blockHW, i);
                +
                +      this.addBlockListeners_(root, block, rect);
                +
                +      cursorY += blockHW.height + gaps[i];
                +    } else if (item.type == 'button') {
                +      this.initFlyoutButton_(item.button, cursorX, cursorY);
                +      cursorY += item.button.height + gaps[i];
                +    }
                +  }
                +};
                +
                +/**
                + * Determine if a drag delta is toward the workspace, based on the position
                + * and orientation of the flyout. This is used in determineDragIntention_ to
                + * determine if a new block should be created or if the flyout should scroll.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at mouse down, in pixel units.
                + * @return {boolean} true if the drag is toward the workspace.
                + * @package
                + */
                +Blockly.VerticalFlyout.prototype.isDragTowardWorkspace = function(
                +    currentDragDeltaXY) {
                +  var dx = currentDragDeltaXY.x;
                +  var dy = currentDragDeltaXY.y;
                +  // Direction goes from -180 to 180, with 0 toward the right and 90 on top.
                +  var dragDirection = Math.atan2(dy, dx) / Math.PI * 180;
                +
                +  var range = this.dragAngleRange_;
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
                +    // Vertical at left.
                +    if (dragDirection < range && dragDirection > -range) {
                +      return true;
                +    }
                +  } else {
                +    // Vertical at right.
                +    if (dragDirection < -180 + range || dragDirection > 180 - range) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Return the deletion rectangle for this flyout in viewport coordinates.
                + * @return {goog.math.Rect} Rectangle in which to delete.
                + */
                +Blockly.VerticalFlyout.prototype.getClientRect = function() {
                +  if (!this.svgGroup_) {
                +    return null;
                +  }
                +
                +  var flyoutRect = this.svgGroup_.getBoundingClientRect();
                +  // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout
                +  // area are still deleted.  Must be larger than the largest screen size,
                +  // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE).
                +  var BIG_NUM = 1000000000;
                +  var x = flyoutRect.left;
                +  var width = flyoutRect.width;
                +
                +  if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
                +    return new goog.math.Rect(x - BIG_NUM, -BIG_NUM, BIG_NUM + width,
                +        BIG_NUM * 2);
                +  } else {  // Right
                +    return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + width, BIG_NUM * 2);
                +  }
                +};
                +
                +/**
                + * Compute width of flyout.  Position button under each block.
                + * For RTL: Lay out the blocks right-aligned.
                + * @param {!Array<!Blockly.Block>} blocks The blocks to reflow.
                + * @private
                + */
                +Blockly.VerticalFlyout.prototype.reflowInternal_ = function(blocks) {
                +  this.workspace_.scale = this.targetWorkspace_.scale;
                +  var flyoutWidth = 0;
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var width = block.getHeightWidth().width;
                +    if (block.outputConnection) {
                +      width -= Blockly.BlockSvg.TAB_WIDTH;
                +    }
                +    flyoutWidth = Math.max(flyoutWidth, width);
                +  }
                +  for (var i = 0, button; button = this.buttons_[i]; i++) {
                +    flyoutWidth = Math.max(flyoutWidth, button.width);
                +  }
                +  flyoutWidth += this.MARGIN * 1.5 + Blockly.BlockSvg.TAB_WIDTH;
                +  flyoutWidth *= this.workspace_.scale;
                +  flyoutWidth += Blockly.Scrollbar.scrollbarThickness;
                +
                +  if (this.width_ != flyoutWidth) {
                +    for (var i = 0, block; block = blocks[i]; i++) {
                +      if (this.RTL) {
                +        // With the flyoutWidth known, right-align the blocks.
                +        var oldX = block.getRelativeToSurfaceXY().x;
                +        var newX = flyoutWidth / this.workspace_.scale - this.MARGIN;
                +        newX -= Blockly.BlockSvg.TAB_WIDTH;
                +        block.moveBy(newX - oldX, 0);
                +      }
                +      if (block.flyoutRect_) {
                +        this.moveRectToBlock_(block.flyoutRect_, block);
                +      }
                +    }
                +    // Record the width for .getMetrics_ and .position.
                +    this.width_ = flyoutWidth;
                +    // Call this since it is possible the trash and zoom buttons need
                +    // to move. e.g. on a bottom positioned flyout when zoom is clicked.
                +    this.targetWorkspace_.resize();
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/generator.js b/blockly/webif/static/blockly/core/generator.js
                new file mode 100644
                index 000000000..cba266f27
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/generator.js
                @@ -0,0 +1,415 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Utility functions for generating executable code from
                + * Blockly code.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Generator');
                +
                +goog.require('Blockly.Block');
                +goog.require('goog.asserts');
                +
                +
                +/**
                + * Class for a code generator that translates the blocks into a language.
                + * @param {string} name Language name of this generator.
                + * @constructor
                + */
                +Blockly.Generator = function(name) {
                +  this.name_ = name;
                +  this.FUNCTION_NAME_PLACEHOLDER_REGEXP_ =
                +      new RegExp(this.FUNCTION_NAME_PLACEHOLDER_, 'g');
                +};
                +
                +/**
                + * Category to separate generated function names from variables and procedures.
                + */
                +Blockly.Generator.NAME_TYPE = 'generated_function';
                +
                +/**
                + * Arbitrary code to inject into locations that risk causing infinite loops.
                + * Any instances of '%1' will be replaced by the block ID that failed.
                + * E.g. '  checkTimeout(%1);\n'
                + * @type {?string}
                + */
                +Blockly.Generator.prototype.INFINITE_LOOP_TRAP = null;
                +
                +/**
                + * Arbitrary code to inject before every statement.
                + * Any instances of '%1' will be replaced by the block ID of the statement.
                + * E.g. 'highlight(%1);\n'
                + * @type {?string}
                + */
                +Blockly.Generator.prototype.STATEMENT_PREFIX = null;
                +
                +/**
                + * The method of indenting.  Defaults to two spaces, but language generators
                + * may override this to increase indent or change to tabs.
                + * @type {string}
                + */
                +Blockly.Generator.prototype.INDENT = '  ';
                +
                +/**
                + * Maximum length for a comment before wrapping.  Does not account for
                + * indenting level.
                + * @type {number}
                + */
                +Blockly.Generator.prototype.COMMENT_WRAP = 60;
                +
                +/**
                + * List of outer-inner pairings that do NOT require parentheses.
                + * @type {!Array.<!Array.<number>>}
                + */
                +Blockly.Generator.prototype.ORDER_OVERRIDES = [];
                +
                +/**
                + * Generate code for all blocks in the workspace to the specified language.
                + * @param {Blockly.Workspace} workspace Workspace to generate code from.
                + * @return {string} Generated code.
                + */
                +Blockly.Generator.prototype.workspaceToCode = function(workspace) {
                +  if (!workspace) {
                +    // Backwards compatibility from before there could be multiple workspaces.
                +    console.warn('No workspace specified in workspaceToCode call.  Guessing.');
                +    workspace = Blockly.getMainWorkspace();
                +  }
                +  var code = [];
                +  this.init(workspace);
                +  var blocks = workspace.getTopBlocks(true);
                +  for (var x = 0, block; block = blocks[x]; x++) {
                +    var line = this.blockToCode(block);
                +    if (goog.isArray(line)) {
                +      // Value blocks return tuples of code and operator order.
                +      // Top-level blocks don't care about operator order.
                +      line = line[0];
                +    }
                +    if (line) {
                +      if (block.outputConnection && this.scrubNakedValue) {
                +        // This block is a naked value.  Ask the language's code generator if
                +        // it wants to append a semicolon, or something.
                +        line = this.scrubNakedValue(line);
                +      }
                +      code.push(line);
                +    }
                +  }
                +  code = code.join('\n');  // Blank line between each section.
                +  code = this.finish(code);
                +  // Final scrubbing of whitespace.
                +  code = code.replace(/^\s+\n/, '');
                +  code = code.replace(/\n\s+$/, '\n');
                +  code = code.replace(/[ \t]+\n/g, '\n');
                +  return code;
                +};
                +
                +// The following are some helpful functions which can be used by multiple
                +// languages.
                +
                +/**
                + * Prepend a common prefix onto each line of code.
                + * @param {string} text The lines of code.
                + * @param {string} prefix The common prefix.
                + * @return {string} The prefixed lines of code.
                + */
                +Blockly.Generator.prototype.prefixLines = function(text, prefix) {
                +  return prefix + text.replace(/(?!\n$)\n/g, '\n' + prefix);
                +};
                +
                +/**
                + * Recursively spider a tree of blocks, returning all their comments.
                + * @param {!Blockly.Block} block The block from which to start spidering.
                + * @return {string} Concatenated list of comments.
                + */
                +Blockly.Generator.prototype.allNestedComments = function(block) {
                +  var comments = [];
                +  var blocks = block.getDescendants();
                +  for (var i = 0; i < blocks.length; i++) {
                +    var comment = blocks[i].getCommentText();
                +    if (comment) {
                +      comments.push(comment);
                +    }
                +  }
                +  // Append an empty string to create a trailing line break when joined.
                +  if (comments.length) {
                +    comments.push('');
                +  }
                +  return comments.join('\n');
                +};
                +
                +/**
                + * Generate code for the specified block (and attached blocks).
                + * @param {Blockly.Block} block The block to generate code for.
                + * @return {string|!Array} For statement blocks, the generated code.
                + *     For value blocks, an array containing the generated code and an
                + *     operator order value.  Returns '' if block is null.
                + */
                +Blockly.Generator.prototype.blockToCode = function(block) {
                +  if (!block) {
                +    return '';
                +  }
                +  if (block.disabled) {
                +    // Skip past this block if it is disabled.
                +    return this.blockToCode(block.getNextBlock());
                +  }
                +
                +  var func = this[block.type];
                +  goog.asserts.assertFunction(func,
                +      'Language "%s" does not know how to generate code for block type "%s".',
                +      this.name_, block.type);
                +  // First argument to func.call is the value of 'this' in the generator.
                +  // Prior to 24 September 2013 'this' was the only way to access the block.
                +  // The current prefered method of accessing the block is through the second
                +  // argument to func.call, which becomes the first parameter to the generator.
                +  var code = func.call(block, block);
                +  if (goog.isArray(code)) {
                +    // Value blocks return tuples of code and operator order.
                +    goog.asserts.assert(block.outputConnection,
                +        'Expecting string from statement block "%s".', block.type);
                +    return [this.scrub_(block, code[0]), code[1]];
                +  } else if (goog.isString(code)) {
                +    var id = block.id.replace(/\$/g, '$$$$');  // Issue 251.
                +    if (this.STATEMENT_PREFIX) {
                +      code = this.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\'') +
                +          code;
                +    }
                +    return this.scrub_(block, code);
                +  } else if (code === null) {
                +    // Block has handled code generation itself.
                +    return '';
                +  } else {
                +    goog.asserts.fail('Invalid code generated: %s', code);
                +  }
                +};
                +
                +/**
                + * Generate code representing the specified value input.
                + * @param {!Blockly.Block} block The block containing the input.
                + * @param {string} name The name of the input.
                + * @param {number} outerOrder The maximum binding strength (minimum order value)
                + *     of any operators adjacent to "block".
                + * @return {string} Generated code or '' if no blocks are connected or the
                + *     specified input does not exist.
                + */
                +Blockly.Generator.prototype.valueToCode = function(block, name, outerOrder) {
                +  if (isNaN(outerOrder)) {
                +    goog.asserts.fail('Expecting valid order from block "%s".', block.type);
                +  }
                +  var targetBlock = block.getInputTargetBlock(name);
                +  if (!targetBlock) {
                +    return '';
                +  }
                +  var tuple = this.blockToCode(targetBlock);
                +  if (tuple === '') {
                +    // Disabled block.
                +    return '';
                +  }
                +  // Value blocks must return code and order of operations info.
                +  // Statement blocks must only return code.
                +  goog.asserts.assertArray(tuple, 'Expecting tuple from value block "%s".',
                +      targetBlock.type);
                +  var code = tuple[0];
                +  var innerOrder = tuple[1];
                +  if (isNaN(innerOrder)) {
                +    goog.asserts.fail('Expecting valid order from value block "%s".',
                +        targetBlock.type);
                +  }
                +  if (!code) {
                +    return '';
                +  }
                +
                +  // Add parentheses if needed.
                +  var parensNeeded = false;
                +  var outerOrderClass = Math.floor(outerOrder);
                +  var innerOrderClass = Math.floor(innerOrder);
                +  if (outerOrderClass <= innerOrderClass) {
                +    if (outerOrderClass == innerOrderClass &&
                +        (outerOrderClass == 0 || outerOrderClass == 99)) {
                +      // Don't generate parens around NONE-NONE and ATOMIC-ATOMIC pairs.
                +      // 0 is the atomic order, 99 is the none order.  No parentheses needed.
                +      // In all known languages multiple such code blocks are not order
                +      // sensitive.  In fact in Python ('a' 'b') 'c' would fail.
                +    } else {
                +      // The operators outside this code are stronger than the operators
                +      // inside this code.  To prevent the code from being pulled apart,
                +      // wrap the code in parentheses.
                +      parensNeeded = true;
                +      // Check for special exceptions.
                +      for (var i = 0; i < this.ORDER_OVERRIDES.length; i++) {
                +        if (this.ORDER_OVERRIDES[i][0] == outerOrder &&
                +            this.ORDER_OVERRIDES[i][1] == innerOrder) {
                +          parensNeeded = false;
                +          break;
                +        }
                +      }
                +    }
                +  }
                +  if (parensNeeded) {
                +    // Technically, this should be handled on a language-by-language basis.
                +    // However all known (sane) languages use parentheses for grouping.
                +    code = '(' + code + ')';
                +  }
                +  return code;
                +};
                +
                +/**
                + * Generate code representing the statement.  Indent the code.
                + * @param {!Blockly.Block} block The block containing the input.
                + * @param {string} name The name of the input.
                + * @return {string} Generated code or '' if no blocks are connected.
                + */
                +Blockly.Generator.prototype.statementToCode = function(block, name) {
                +  var targetBlock = block.getInputTargetBlock(name);
                +  var code = this.blockToCode(targetBlock);
                +  // Value blocks must return code and order of operations info.
                +  // Statement blocks must only return code.
                +  goog.asserts.assertString(code, 'Expecting code from statement block "%s".',
                +      targetBlock && targetBlock.type);
                +  if (code) {
                +    code = this.prefixLines(/** @type {string} */ (code), this.INDENT);
                +  }
                +  return code;
                +};
                +
                +/**
                + * Add an infinite loop trap to the contents of a loop.
                + * If loop is empty, add a statment prefix for the loop block.
                + * @param {string} branch Code for loop contents.
                + * @param {string} id ID of enclosing block.
                + * @return {string} Loop contents, with infinite loop trap added.
                + */
                +Blockly.Generator.prototype.addLoopTrap = function(branch, id) {
                +  id = id.replace(/\$/g, '$$$$');  // Issue 251.
                +  if (this.INFINITE_LOOP_TRAP) {
                +    branch = this.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\'') + branch;
                +  }
                +  if (this.STATEMENT_PREFIX) {
                +    branch += this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + id + '\''), this.INDENT);
                +  }
                +  return branch;
                +};
                +
                +/**
                + * Comma-separated list of reserved words.
                + * @type {string}
                + * @private
                + */
                +Blockly.Generator.prototype.RESERVED_WORDS_ = '';
                +
                +/**
                + * Add one or more words to the list of reserved words for this language.
                + * @param {string} words Comma-separated list of words to add to the list.
                + *     No spaces.  Duplicates are ok.
                + */
                +Blockly.Generator.prototype.addReservedWords = function(words) {
                +  this.RESERVED_WORDS_ += words + ',';
                +};
                +
                +/**
                + * This is used as a placeholder in functions defined using
                + * Blockly.Generator.provideFunction_.  It must not be legal code that could
                + * legitimately appear in a function definition (or comment), and it must
                + * not confuse the regular expression parser.
                + * @type {string}
                + * @private
                + */
                +Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_ = '{leCUI8hutHZI4480Dc}';
                +
                +/**
                + * Define a function to be included in the generated code.
                + * The first time this is called with a given desiredName, the code is
                + * saved and an actual name is generated.  Subsequent calls with the
                + * same desiredName have no effect but have the same return value.
                + *
                + * It is up to the caller to make sure the same desiredName is not
                + * used for different code values.
                + *
                + * The code gets output when Blockly.Generator.finish() is called.
                + *
                + * @param {string} desiredName The desired name of the function (e.g., isPrime).
                + * @param {!Array.<string>} code A list of statements.  Use '  ' for indents.
                + * @return {string} The actual name of the new function.  This may differ
                + *     from desiredName if the former has already been taken by the user.
                + * @private
                + */
                +Blockly.Generator.prototype.provideFunction_ = function(desiredName, code) {
                +  if (!this.definitions_[desiredName]) {
                +    var functionName = this.variableDB_.getDistinctName(desiredName,
                +        Blockly.Procedures.NAME_TYPE);
                +    this.functionNames_[desiredName] = functionName;
                +    var codeText = code.join('\n').replace(
                +        this.FUNCTION_NAME_PLACEHOLDER_REGEXP_, functionName);
                +    // Change all '  ' indents into the desired indent.
                +    // To avoid an infinite loop of replacements, change all indents to '\0'
                +    // character first, then replace them all with the indent.
                +    // We are assuming that no provided functions contain a literal null char.
                +    var oldCodeText;
                +    while (oldCodeText != codeText) {
                +      oldCodeText = codeText;
                +      codeText = codeText.replace(/^((  )*)  /gm, '$1\0');
                +    }
                +    codeText = codeText.replace(/\0/g, this.INDENT);
                +    this.definitions_[desiredName] = codeText;
                +  }
                +  return this.functionNames_[desiredName];
                +};
                +
                +/**
                + * Hook for code to run before code generation starts.
                + * Subclasses may override this, e.g. to initialise the database of variable
                + * names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.Generator.prototype.init = undefined;
                +
                +/**
                + * Common tasks for generating code from blocks.  This is called from
                + * blockToCode and is called on every block, not just top level blocks.
                + * Subclasses may override this, e.g. to generate code for statements following
                + * the block, or to handle comments for the specified block and any connected
                + * value blocks.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The JavaScript code created for this block.
                + * @return {string} JavaScript code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.Generator.prototype.scrub_ = undefined;
                +
                +/**
                + * Hook for code to run at end of code generation.
                + * Subclasses may override this, e.g. to prepend the generated code with the
                + * variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.Generator.prototype.finish = undefined;
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything.
                + * Subclasses may override this, e.g. if their language does not allow
                + * naked values.
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.Generator.prototype.scrubNakedValue = undefined;
                diff --git a/blockly/webif/static/blockly/core/gesture.js b/blockly/webif/static/blockly/core/gesture.js
                new file mode 100644
                index 000000000..ba09192cf
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/gesture.js
                @@ -0,0 +1,783 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview The class representing an in-progress gesture, usually a drag
                + * or a tap.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Gesture');
                +
                +goog.require('Blockly.BlockDragger');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.FlyoutDragger');
                +goog.require('Blockly.Tooltip');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.WorkspaceDragger');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * NB: In this file "start" refers to touchstart, mousedown, and pointerstart
                + * events.  "End" refers to touchend, mouseup, and pointerend events.
                + * TODO: Consider touchcancel/pointercancel.
                + */
                +
                +/**
                + * Class for one gesture.
                + * @param {!Event} e The event that kicked off this gesture.
                + * @param {!Blockly.WorkspaceSvg} creatorWorkspace The workspace that created
                + *     this gesture and has a reference to it.
                + * @constructor
                + */
                +Blockly.Gesture = function(e, creatorWorkspace) {
                +
                +  /**
                +   * The position of the mouse when the gesture started.  Units are css pixels,
                +   * with (0, 0) at the top left of the browser window (mouseEvent clientX/Y).
                +   * @type {goog.math.Coordinate}
                +   */
                +  this.mouseDownXY_ = null;
                +
                +  /**
                +   * How far the mouse has moved during this drag, in pixel units.
                +   * (0, 0) is at this.mouseDownXY_.
                +   * @type {goog.math.Coordinate}
                +   * private
                +   */
                +  this.currentDragDeltaXY_ = 0;
                +
                +  /**
                +   * The field that the gesture started on, or null if it did not start on a
                +   * field.
                +   * @type {Blockly.Field}
                +   * @private
                +   */
                +  this.startField_ = null;
                +
                +  /**
                +   * The block that the gesture started on, or null if it did not start on a
                +   * block.
                +   * @type {Blockly.BlockSvg}
                +   * @private
                +   */
                +  this.startBlock_ = null;
                +
                +  /**
                +   * The block that this gesture targets.  If the gesture started on a
                +   * shadow block, this is the first non-shadow parent of the block.  If the
                +   * gesture started in the flyout, this is the root block of the block group
                +   * that was clicked or dragged.
                +   * @type {Blockly.BlockSvg}
                +   * @private
                +   */
                +  this.targetBlock_ = null;
                +
                +  /**
                +   * The workspace that the gesture started on.  There may be multiple
                +   * workspaces on a page; this is more accurate than using
                +   * Blockly.getMainWorkspace().
                +   * @type {Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.startWorkspace_ = null;
                +
                +  /**
                +   * The workspace that created this gesture.  This workspace keeps a reference
                +   * to the gesture, which will need to be cleared at deletion.
                +   * This may be different from the start workspace.  For instance, a flyout is
                +   * a workspace, but its parent workspace manages gestures for it.
                +   * @type {Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.creatorWorkspace_ = creatorWorkspace;
                +
                +  /**
                +   * Whether the pointer has at any point moved out of the drag radius.
                +   * A gesture that exceeds the drag radius is a drag even if it ends exactly at
                +   * its start point.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.hasExceededDragRadius_ = false;
                +
                +  /**
                +   * Whether the workspace is currently being dragged.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.isDraggingWorkspace_ = false;
                +
                +  /**
                +   * Whether the block is currently being dragged.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.isDraggingBlock_ = false;
                +
                +  /**
                +   * The event that most recently updated this gesture.
                +   * @type {!Event}
                +   * @private
                +   */
                +  this.mostRecentEvent_ = e;
                +
                +  /**
                +   * A handle to use to unbind a mouse move listener at the end of a drag.
                +   * Opaque data returned from Blockly.bindEventWithChecks_.
                +   * @type {Array.<!Array>}
                +   * @private
                +   */
                +  this.onMoveWrapper_ = null;
                +
                +  /**
                +   * A handle to use to unbind a mouse up listener at the end of a drag.
                +   * Opaque data returned from Blockly.bindEventWithChecks_.
                +   * @type {Array.<!Array>}
                +   * @private
                +   */
                +  this.onUpWrapper_ = null;
                +
                +  /**
                +   * The object tracking a block drag, or null if none is in progress.
                +   * @type {Blockly.BlockDragger}
                +   * @private
                +   */
                +  this.blockDragger_ = null;
                +
                +  /**
                +   * The object tracking a workspace or flyout workspace drag, or null if none
                +   * is in progress.
                +   * @type {Blockly.WorkspaceDragger}
                +   * @private
                +   */
                +  this.workspaceDragger_ = null;
                +
                +  /**
                +   * The flyout a gesture started in, if any.
                +   * @type {Blockly.Flyout}
                +   * @private
                +   */
                +  this.flyout_ = null;
                +
                +  /**
                +   * Boolean for sanity-checking that some code is only called once.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.calledUpdateIsDragging_ = false;
                +
                +  /**
                +   * Boolean for sanity-checking that some code is only called once.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.hasStarted_ = false;
                +
                +  /**
                +   * Boolean used internally to break a cycle in disposal.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.isEnding_ = false;
                +};
                +
                +/**
                + * Sever all links from this object.
                + * @package
                + */
                +Blockly.Gesture.prototype.dispose = function() {
                +  Blockly.Touch.clearTouchIdentifier();
                +  Blockly.Tooltip.unblock();
                +  // Clear the owner's reference to this gesture.
                +  this.creatorWorkspace_.clearGesture();
                +
                +  if (this.onMoveWrapper_) {
                +    Blockly.unbindEvent_(this.onMoveWrapper_);
                +  }
                +  if (this.onUpWrapper_) {
                +    Blockly.unbindEvent_(this.onUpWrapper_);
                +  }
                +
                +
                +  this.startField_ = null;
                +  this.startBlock_ = null;
                +  this.targetBlock_ = null;
                +  this.startWorkspace_ = null;
                +  this.flyout_ = null;
                +
                +  if (this.blockDragger_) {
                +    this.blockDragger_.dispose();
                +    this.blockDragger_ = null;
                +  }
                +  if (this.workspaceDragger_) {
                +    this.workspaceDragger_.dispose();
                +    this.workspaceDragger_ = null;
                +  }
                +};
                +
                +/**
                + * Update internal state based on an event.
                + * @param {!Event} e The most recent mouse or touch event.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateFromEvent_ = function(e) {
                +  var currentXY = new goog.math.Coordinate(e.clientX, e.clientY);
                +  var changed = this.updateDragDelta_(currentXY);
                +  // Exceeded the drag radius for the first time.
                +  if (changed){
                +    this.updateIsDragging_();
                +    Blockly.longStop_();
                +  }
                +  this.mostRecentEvent_ = e;
                +};
                +
                +/**
                + * DO MATH to set currentDragDeltaXY_ based on the most recent mouse position.
                + * @param {!goog.math.Coordinate} currentXY The most recent mouse/pointer
                + *     position, in pixel units, with (0, 0) at the window's top left corner.
                + * @return {boolean} True if the drag just exceeded the drag radius for the
                + *     first time.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateDragDelta_ = function(currentXY) {
                +  this.currentDragDeltaXY_ = goog.math.Coordinate.difference(currentXY,
                +      this.mouseDownXY_);
                +
                +  if (!this.hasExceededDragRadius_) {
                +    var currentDragDelta = goog.math.Coordinate.magnitude(
                +        this.currentDragDeltaXY_);
                +
                +    // The flyout has a different drag radius from the rest of Blockly.
                +    var limitRadius = this.flyout_ ? Blockly.FLYOUT_DRAG_RADIUS :
                +        Blockly.DRAG_RADIUS;
                +
                +    this.hasExceededDragRadius_ = currentDragDelta > limitRadius;
                +    return this.hasExceededDragRadius_;
                +  }
                +  return false;
                +};
                +
                +/**
                + * Update this gesture to record whether a block is being dragged from the
                + * flyout.
                + * This function should be called on a mouse/touch move event the first time the
                + * drag radius is exceeded.  It should be called no more than once per gesture.
                + * If a block should be dragged from the flyout this function creates the new
                + * block on the main workspace and updates targetBlock_ and startWorkspace_.
                + * @return {boolean} True if a block is being dragged from the flyout.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateIsDraggingFromFlyout_ = function() {
                +  // Disabled blocks may not be dragged from the flyout.
                +  if (this.targetBlock_.disabled) {
                +    return false;
                +  }
                +  if (!this.flyout_.isScrollable() ||
                +      this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)) {
                +    this.startWorkspace_ = this.flyout_.targetWorkspace_;
                +    this.startWorkspace_.updateScreenCalculationsIfScrolled();
                +    // Start the event group now, so that the same event group is used for block
                +    // creation and block dragging.
                +    if (!Blockly.Events.getGroup()) {
                +      Blockly.Events.setGroup(true);
                +    }
                +    // The start block is no longer relevant, because this is a drag.
                +    this.startBlock_ = null;
                +    this.targetBlock_ = this.flyout_.createBlock(this.targetBlock_);
                +    this.targetBlock_.select();
                +    return true;
                +  }
                +  return false;
                +};
                +
                +/**
                + * Update this gesture to record whether a block is being dragged.
                + * This function should be called on a mouse/touch move event the first time the
                + * drag radius is exceeded.  It should be called no more than once per gesture.
                + * If a block should be dragged, either from the flyout or in the workspace,
                + * this function creates the necessary BlockDragger and starts the drag.
                + * @return {boolean} true if a block is being dragged.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateIsDraggingBlock_ = function() {
                +  if (!this.targetBlock_) {
                +    return false;
                +  }
                +
                +  if (this.flyout_) {
                +    this.isDraggingBlock_ = this.updateIsDraggingFromFlyout_();
                +  } else if (this.targetBlock_.isMovable()){
                +    this.isDraggingBlock_ = true;
                +  }
                +
                +  if (this.isDraggingBlock_) {
                +    this.startDraggingBlock_();
                +    return true;
                +  }
                +  return false;
                +};
                +
                +/**
                + * Update this gesture to record whether a workspace is being dragged.
                + * This function should be called on a mouse/touch move event the first time the
                + * drag radius is exceeded.  It should be called no more than once per gesture.
                + * If a workspace is being dragged this function creates the necessary
                + * WorkspaceDragger or FlyoutDragger and starts the drag.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateIsDraggingWorkspace_ = function() {
                +  var wsMovable = this.flyout_ ? this.flyout_.isScrollable() :
                +      this.startWorkspace_ && this.startWorkspace_.isDraggable();
                +
                +  if (!wsMovable) {
                +    return;
                +  }
                +
                +  if (this.flyout_) {
                +    this.workspaceDragger_ = new Blockly.FlyoutDragger(this.flyout_);
                +  } else {
                +    this.workspaceDragger_ = new Blockly.WorkspaceDragger(this.startWorkspace_);
                +  }
                +
                +  this.isDraggingWorkspace_ = true;
                +  this.workspaceDragger_.startDrag();
                +};
                +
                +/**
                + * Update this gesture to record whether anything is being dragged.
                + * This function should be called on a mouse/touch move event the first time the
                + * drag radius is exceeded.  It should be called no more than once per gesture.
                + * @private
                + */
                +Blockly.Gesture.prototype.updateIsDragging_ = function() {
                +  // Sanity check.
                +  goog.asserts.assert(!this.calledUpdateIsDragging_,
                +      'updateIsDragging_ should only be called once per gesture.');
                +  this.calledUpdateIsDragging_ = true;
                +
                +  // First check if it was a block drag.
                +  if (this.updateIsDraggingBlock_()) {
                +    return;
                +  }
                +  // Then check if it's a workspace drag.
                +  this.updateIsDraggingWorkspace_();
                +};
                +
                +/**
                + * Create a block dragger and start dragging the selected block.
                + * @private
                + */
                +Blockly.Gesture.prototype.startDraggingBlock_ = function() {
                +  this.blockDragger_ = new Blockly.BlockDragger(this.targetBlock_,
                +      this.startWorkspace_);
                +  this.blockDragger_.startBlockDrag(this.currentDragDeltaXY_);
                +  this.blockDragger_.dragBlock(this.mostRecentEvent_,
                +      this.currentDragDeltaXY_);
                +};
                +
                +/**
                + * Start a gesture: update the workspace to indicate that a gesture is in
                + * progress and bind mousemove and mouseup handlers.
                + * @param {!Event} e A mouse down or touch start event.
                + * @package
                + */
                +Blockly.Gesture.prototype.doStart = function(e) {
                +  if (Blockly.utils.isTargetInput(e)) {
                +    this.cancel();
                +    return;
                +  }
                +  this.hasStarted_ = true;
                +
                +  Blockly.BlockSvg.disconnectUiStop_();
                +  this.startWorkspace_.updateScreenCalculationsIfScrolled();
                +  if (this.startWorkspace_.isMutator) {
                +    // Mutator's coordinate system could be out of date because the bubble was
                +    // dragged, the block was moved, the parent workspace zoomed, etc.
                +    this.startWorkspace_.resize();
                +  }
                +  this.startWorkspace_.markFocused();
                +  this.mostRecentEvent_ = e;
                +
                +  // Hide chaff also hides the flyout, so don't do it if the click is in a flyout.
                +  Blockly.hideChaff(!!this.flyout_);
                +  Blockly.Tooltip.block();
                +
                +  if (this.targetBlock_) {
                +    this.targetBlock_.select();
                +  }
                +
                +  if (Blockly.utils.isRightButton(e)) {
                +    this.handleRightClick(e);
                +    return;
                +  }
                +
                +  if (goog.string.caseInsensitiveEquals(e.type, 'touchstart')) {
                +    Blockly.longStart_(e, this);
                +  }
                +
                +  this.mouseDownXY_ = new goog.math.Coordinate(e.clientX, e.clientY);
                +
                +  this.onMoveWrapper_ = Blockly.bindEventWithChecks_(
                +      document, 'mousemove', null, this.handleMove.bind(this));
                +  this.onUpWrapper_ = Blockly.bindEventWithChecks_(
                +      document, 'mouseup', null, this.handleUp.bind(this));
                +
                +  e.preventDefault();
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Handle a mouse move or touch move event.
                + * @param {!Event} e A mouse move or touch move event.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleMove = function(e) {
                +  this.updateFromEvent_(e);
                +  if (this.isDraggingWorkspace_) {
                +    this.workspaceDragger_.drag(this.currentDragDeltaXY_);
                +  } else if (this.isDraggingBlock_) {
                +    this.blockDragger_.dragBlock(this.mostRecentEvent_,
                +        this.currentDragDeltaXY_);
                +  }
                +  e.preventDefault();
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Handle a mouse up or touch end event.
                + * @param {!Event} e A mouse up or touch end event.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleUp = function(e) {
                +  this.updateFromEvent_(e);
                +  Blockly.longStop_();
                +
                +  if (this.isEnding_) {
                +    console.log('Trying to end a gesture recursively.');
                +    return;
                +  }
                +  this.isEnding_ = true;
                +  // The ordering of these checks is important: drags have higher priority than
                +  // clicks.  Fields have higher priority than blocks; blocks have higher
                +  // priority than workspaces.
                +  if (this.isDraggingBlock_) {
                +    this.blockDragger_.endBlockDrag(e, this.currentDragDeltaXY_);
                +  } else if (this.isDraggingWorkspace_) {
                +    this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
                +  } else if (this.isFieldClick_()) {
                +    this.doFieldClick_();
                +  } else if (this.isBlockClick_()) {
                +    this.doBlockClick_();
                +  } else if (this.isWorkspaceClick_()) {
                +    this.doWorkspaceClick_();
                +  }
                +
                +  e.preventDefault();
                +  e.stopPropagation();
                +
                +  this.dispose();
                +};
                +
                +/**
                + * Cancel an in-progress gesture.  If a workspace or block drag is in progress,
                + * end the drag at the most recent location.
                + * @package
                + */
                +Blockly.Gesture.prototype.cancel = function() {
                +  // Disposing of a block cancels in-progress drags, but dragging to a delete
                +  // area disposes of a block and leads to recursive disposal. Break that cycle.
                +  if (this.isEnding_) {
                +    return;
                +  }
                +  Blockly.longStop_();
                +  if (this.isDraggingBlock_) {
                +    this.blockDragger_.endBlockDrag(this.mostRecentEvent_,
                +        this.currentDragDeltaXY_);
                +  } else if (this.isDraggingWorkspace_) {
                +    this.workspaceDragger_.endDrag(this.currentDragDeltaXY_);
                +  }
                +  this.dispose();
                +};
                +
                +/**
                + * Handle a real or faked right-click event by showing a context menu.
                + * @param {!Event} e A mouse move or touch move event.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleRightClick = function(e) {
                +  if (this.targetBlock_) {
                +    this.bringBlockToFront_();
                +    Blockly.hideChaff(this.flyout_);
                +    this.targetBlock_.showContextMenu_(e);
                +  } else if (this.startWorkspace_ && !this.flyout_) {
                +    Blockly.hideChaff();
                +    this.startWorkspace_.showContextMenu_(e);
                +  }
                +
                +  e.preventDefault();
                +  e.stopPropagation();
                +
                +  this.dispose();
                +};
                +
                +/**
                + * Handle a mousedown/touchstart event on a workspace.
                + * @param {!Event} e A mouse down or touch start event.
                + * @param {!Blockly.Workspace} ws The workspace the event hit.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleWsStart = function(e, ws) {
                +  goog.asserts.assert(!this.hasStarted_,
                +     'Tried to call gesture.handleWsStart, but the gesture had already been ' +
                +     'started.');
                +  this.setStartWorkspace_(ws);
                +  this.mostRecentEvent_ = e;
                +  this.doStart(e);
                +};
                +
                +/**
                + * Handle a mousedown/touchstart event on a flyout.
                + * @param {!Event} e A mouse down or touch start event.
                + * @param {!Blockly.Flyout} flyout The flyout the event hit.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleFlyoutStart = function(e, flyout) {
                +  goog.asserts.assert(!this.hasStarted_,
                +     'Tried to call gesture.handleFlyoutStart, but the gesture had already been ' +
                +     'started.');
                +  this.setStartFlyout_(flyout);
                +  this.handleWsStart(e, flyout.getWorkspace());
                +};
                +
                +/**
                + * Handle a mousedown/touchstart event on a block.
                + * @param {!Event} e A mouse down or touch start event.
                + * @param {!Blockly.BlockSvg} block The block the event hit.
                + * @package
                + */
                +Blockly.Gesture.prototype.handleBlockStart = function(e, block) {
                +  goog.asserts.assert(!this.hasStarted_,
                +     'Tried to call gesture.handleBlockStart, but the gesture had already been ' +
                +     'started.');
                +  this.setStartBlock(block);
                +  this.mostRecentEvent_ = e;
                +};
                +
                +/* Begin functions defining what actions to take to execute clicks on each type
                + * of target.  Any developer wanting to add behaviour on clicks should modify
                + * only this code. */
                +
                +/**
                + * Execute a field click.
                + * @private
                + */
                +Blockly.Gesture.prototype.doFieldClick_ = function() {
                +  this.startField_.showEditor_();
                +  this.bringBlockToFront_();
                +};
                +
                +/**
                + * Execute a block click.
                + * @private
                + */
                +Blockly.Gesture.prototype.doBlockClick_ = function() {
                +  // Block click in an autoclosing flyout.
                +  if (this.flyout_ && this.flyout_.autoClose) {
                +    if (!this.targetBlock_.disabled) {
                +      if (!Blockly.Events.getGroup()) {
                +        Blockly.Events.setGroup(true);
                +      }
                +      var newBlock = this.flyout_.createBlock(this.targetBlock_);
                +      newBlock.scheduleSnapAndBump();
                +    }
                +  } else {
                +    // Clicks events are on the start block, even if it was a shadow.
                +    Blockly.Events.fire(
                +        new Blockly.Events.Ui(this.startBlock_, 'click', undefined, undefined));
                +  }
                +  this.bringBlockToFront_();
                +  Blockly.Events.setGroup(false);
                +};
                +
                +/**
                + * Execute a workspace click.
                + * @private
                + */
                +Blockly.Gesture.prototype.doWorkspaceClick_ = function() {
                +  if (Blockly.selected) {
                +    Blockly.selected.unselect();
                +  }
                +};
                +
                +/* End functions defining what actions to take to execute clicks on each type
                + * of target. */
                +
                +/**
                + * Move the dragged/clicked block to the front of the workspace so that it is
                + * not occluded by other blocks.
                + * @private
                + */
                +Blockly.Gesture.prototype.bringBlockToFront_ = function() {
                +  // Blocks in the flyout don't overlap, so skip the work.
                +  if (this.targetBlock_ && !this.flyout_) {
                +    this.targetBlock_.bringToFront();
                +  }
                +};
                +
                +/* Begin functions for populating a gesture at mouse down. */
                +
                +/**
                + * Record the field that a gesture started on.
                + * @param {Blockly.Field} field The field the gesture started on.
                + * @package
                + */
                +Blockly.Gesture.prototype.setStartField = function(field) {
                +  goog.asserts.assert(!this.hasStarted_,
                +     'Tried to call gesture.setStartField, but the gesture had already been ' +
                +     'started.');
                +  if (!this.startField_) {
                +    this.startField_ = field;
                +  }
                +};
                +
                +/**
                + * Record the block that a gesture started on, and set the target block
                + * appropriately.
                + * @param {Blockly.BlockSvg} block The block the gesture started on.
                + * @package
                + */
                +Blockly.Gesture.prototype.setStartBlock = function(block) {
                +  if (!this.startBlock_) {
                +    this.startBlock_ = block;
                +    if (block.isInFlyout && block != block.getRootBlock()) {
                +      this.setTargetBlock_(block.getRootBlock());
                +    } else {
                +      this.setTargetBlock_(block);
                +    }
                +  }
                +};
                +
                +/**
                + * Record the block that a gesture targets, meaning the block that will be
                + * dragged if this turns into a drag.  If this block is a shadow, that will be
                + * its first non-shadow parent.
                + * @param {Blockly.BlockSvg} block The block the gesture targets.
                + * @private
                + */
                +Blockly.Gesture.prototype.setTargetBlock_ = function(block) {
                +  if (block.isShadow()) {
                +    this.setTargetBlock_(block.getParent());
                +  } else {
                +    this.targetBlock_ = block;
                +  }
                +};
                +
                +/**
                + * Record the workspace that a gesture started on.
                + * @param {Blockly.WorkspaceSvg} ws The workspace the gesture started on.
                + * @private
                + */
                +Blockly.Gesture.prototype.setStartWorkspace_ = function(ws) {
                +  if (!this.startWorkspace_) {
                +    this.startWorkspace_ = ws;
                +  }
                +};
                +
                +/**
                + * Record the flyout that a gesture started on.
                + * @param {Blockly.Flyout} flyout The flyout the gesture started on.
                + * @private
                + */
                +Blockly.Gesture.prototype.setStartFlyout_ = function(flyout) {
                +  if (!this.flyout_) {
                +    this.flyout_ = flyout;
                +  }
                +};
                +
                +/* End functions for populating a gesture at mouse down. */
                +
                +/* Begin helper functions defining types of clicks.  Any developer wanting
                + * to change the definition of a click should modify only this code. */
                +
                +/**
                + * Whether this gesture is a click on a block.  This should only be called when
                + * ending a gesture (mouse up, touch end).
                + * @return {boolean} whether this gesture was a click on a block.
                + * @private
                + */
                +Blockly.Gesture.prototype.isBlockClick_ = function() {
                +  // A block click starts on a block, never escapes the drag radius, and is not
                +  // a field click.
                +  var hasStartBlock = !!this.startBlock_;
                +  return hasStartBlock && !this.hasExceededDragRadius_ && !this.isFieldClick_();
                +};
                +
                +/**
                + * Whether this gesture is a click on a field.  This should only be called when
                + * ending a gesture (mouse up, touch end).
                + * @return {boolean} whether this gesture was a click on a field.
                + * @private
                + */
                +Blockly.Gesture.prototype.isFieldClick_ = function() {
                +  var fieldEditable = this.startField_ ?
                +      this.startField_.isCurrentlyEditable() : false;
                +  return fieldEditable && !this.hasExceededDragRadius_ && (!this.flyout_ ||
                +    !this.flyout_.autoClose);
                +};
                +
                +/**
                + * Whether this gesture is a click on a workspace.  This should only be called
                + * when ending a gesture (mouse up, touch end).
                + * @return {boolean} whether this gesture was a click on a workspace.
                + * @private
                + */
                +Blockly.Gesture.prototype.isWorkspaceClick_ = function() {
                +  var onlyTouchedWorkspace = !this.startBlock_ && !this.startField_;
                +  return onlyTouchedWorkspace && !this.hasExceededDragRadius_;
                +};
                +
                +/* End helper functions defining types of clicks. */
                +
                +/**
                + * Whether this gesture is a drag of either a workspace or block.
                + * This function is called externally to block actions that cannot be taken
                + * mid-drag (e.g. using the keyboard to delete the selected blocks).
                + * @return {boolean} true if this gesture is a drag of a workspace or block.
                + * @package
                + */
                +Blockly.Gesture.prototype.isDragging = function() {
                +  return this.isDraggingWorkspace_ || this.isDraggingBlock_;
                +};
                +
                +/**
                + * Whether this gesture has already been started.  In theory every mouse down
                + * has a corresponding mouse up, but in reality it is possible to lose a
                + * mouse up, leaving an in-process gesture hanging.
                + * @return {boolean} whether this gesture was a click on a workspace.
                + * @package
                + */
                +Blockly.Gesture.prototype.hasStarted = function() {
                +  return this.hasStarted_;
                +};
                diff --git a/blockly/webif/static/blockly/core/grid.js b/blockly/webif/static/blockly/core/grid.js
                new file mode 100644
                index 000000000..e87df6021
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/grid.js
                @@ -0,0 +1,222 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object for configuring and updating a workspace grid in
                + * Blockly.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Grid');
                +
                +goog.require('Blockly.utils');
                +
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a workspace's grid.
                + * @param {!SVGElement} pattern The grid's SVG pattern, created during injection.
                + * @param {!Object} options A dictionary of normalized options for the grid.
                + *     See grid documentation:
                + *     https://developers.google.com/blockly/guides/configure/web/grid
                + * @constructor
                + */
                +Blockly.Grid = function(pattern, options) {
                +  /**
                +   * The grid's SVG pattern, created during injection.
                +   * @type {!SVGElement}
                +   * @private
                +   */
                +  this.gridPattern_ = pattern;
                +
                +  /**
                +   * The spacing of the grid lines (in px).
                +   * @type {number}
                +   * @private
                +   */
                +  this.spacing_ = options['spacing'];
                +
                +  /**
                +   * How long the grid lines should be (in px).
                +   * @type {number}
                +   * @private
                +   */
                +  this.length_ = options['length'];
                +
                +  /**
                +   * The horizontal grid line, if it exists.
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.line1_ = pattern.firstChild;
                +
                +  /**
                +   * The vertical grid line, if it exists.
                +   * @type {SVGElement}
                +   * @private
                +   */
                +  this.line2_ = this.line1_ && this.line1_.nextSibling;
                +
                +  /**
                +   * Whether blocks should snap to the grid.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.snapToGrid_ = options['snap'];
                +};
                +
                +/**
                + * The scale of the grid, used to set stroke width on grid lines.
                + * This should always be the same as the workspace scale.
                + * @type {number}
                + * @private
                + */
                +Blockly.Grid.prototype.scale_ = 1;
                +
                +/**
                + * Dispose of this grid and unlink from the DOM.
                + * @package
                + */
                +Blockly.Grid.prototype.dispose = function() {
                +  this.gridPattern_ = null;
                +};
                +
                +/**
                + * Whether blocks should snap to the grid, based on the initial configuration.
                + * @return {boolean} True if blocks should snap, false otherwise.
                + * @package
                + */
                +Blockly.Grid.prototype.shouldSnap = function() {
                +  return this.snapToGrid_;
                +};
                +
                +/**
                + * Get the spacing of the grid points (in px).
                + * @return {number} The spacing of the grid points.
                + * @package
                + */
                +Blockly.Grid.prototype.getSpacing = function() {
                +  return this.spacing_;
                +};
                +
                +/**
                + * Get the id of the pattern element, which should be randomized to avoid
                + * conflicts with other Blockly instances on the page.
                + * @return {string} The pattern id.
                + * @package
                + */
                +Blockly.Grid.prototype.getPatternId = function() {
                +  return this.gridPattern_.id;
                +};
                +
                +/**
                + * Update the grid with a new scale.
                + * @param {number} scale The new workspace scale.
                + * @package
                + */
                +Blockly.Grid.prototype.update = function(scale) {
                +  this.scale_ = scale;
                +  // MSIE freaks if it sees a 0x0 pattern, so set empty patterns to 100x100.
                +  var safeSpacing = (this.spacing_ * scale) || 100;
                +
                +  this.gridPattern_.setAttribute('width', safeSpacing);
                +  this.gridPattern_.setAttribute('height', safeSpacing);
                +
                +  var half = Math.floor(this.spacing_ / 2) + 0.5;
                +  var start = half - this.length_ / 2;
                +  var end = half + this.length_ / 2;
                +
                +  half *= scale;
                +  start *= scale;
                +  end *= scale;
                +
                +  this.setLineAttributes_(this.line1_, scale, start, end, half, half);
                +  this.setLineAttributes_(this.line2_, scale, half, half, start, end);
                +};
                +
                +/**
                + * Set the attributes on one of the lines in the grid.  Use this to update the
                + * length and stroke width of the grid lines.
                + * @param {!SVGElement} line Which line to update.
                + * @param {number} width The new stroke size (in px).
                + * @param {number} x1 The new x start position of the line (in px).
                + * @param {number} x2 The new x end position of the line (in px).
                + * @param {number} y1 The new y start position of the line (in px).
                + * @param {number} y2 The new y end position of the line (in px).
                + * @private
                + */
                +Blockly.Grid.prototype.setLineAttributes_ = function(line, width, x1, x2, y1, y2) {
                +  if (line) {
                +    line.setAttribute('stroke-width', width);
                +    line.setAttribute('x1', x1);
                +    line.setAttribute('y1', y1);
                +    line.setAttribute('x2', x2);
                +    line.setAttribute('y2', y2);
                +  }
                +};
                +
                +/**
                + * Move the grid to a new x and y position, and make sure that change is visible.
                + * @param {number} x The new x position of the grid (in px).
                + * @param {number} y The new y position ofthe grid (in px).
                + * @package
                + */
                +Blockly.Grid.prototype.moveTo = function(x, y) {
                +  this.gridPattern_.setAttribute('x', x);
                +  this.gridPattern_.setAttribute('y', y);
                +
                +  if (goog.userAgent.IE || goog.userAgent.EDGE) {
                +    // IE/Edge doesn't notice that the x/y offsets have changed.
                +    // Force an update.
                +    this.update(this.scale_);
                +  }
                +};
                +
                +/**
                + * Create the DOM for the grid described by options.
                + * @param {string} rnd A random ID to append to the pattern's ID.
                + * @param {!Object} gridOptions The object containing grid configuration.
                + * @param {!SVGElement} defs The root SVG element for this workspace's defs.
                + * @return {!SVGElement} The SVG element for the grid pattern.
                + * @package
                + */
                +Blockly.Grid.createDom = function(rnd, gridOptions, defs) {
                +  /*
                +    <pattern id="blocklyGridPattern837493" patternUnits="userSpaceOnUse">
                +      <rect stroke="#888" />
                +      <rect stroke="#888" />
                +    </pattern>
                +  */
                +  var gridPattern = Blockly.utils.createSvgElement('pattern',
                +      {'id': 'blocklyGridPattern' + rnd,
                +       'patternUnits': 'userSpaceOnUse'}, defs);
                +  if (gridOptions['length'] > 0 && gridOptions['spacing'] > 0) {
                +    Blockly.utils.createSvgElement('line',
                +        {'stroke': gridOptions['colour']}, gridPattern);
                +    if (gridOptions['length'] > 1) {
                +      Blockly.utils.createSvgElement('line',
                +          {'stroke': gridOptions['colour']}, gridPattern);
                +    }
                +    // x1, y1, x1, x2 properties will be set later in update.
                +  }
                +  return gridPattern;
                +};
                diff --git a/blockly/webif/static/blockly/core/icon.js b/blockly/webif/static/blockly/core/icon.js
                new file mode 100644
                index 000000000..37dd6768d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/icon.js
                @@ -0,0 +1,205 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing an icon on a block.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Icon');
                +
                +goog.require('goog.dom');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Class for an icon.
                + * @param {Blockly.Block} block The block associated with this icon.
                + * @constructor
                + */
                +Blockly.Icon = function(block) {
                +  this.block_ = block;
                +};
                +
                +/**
                + * Does this icon get hidden when the block is collapsed.
                + */
                +Blockly.Icon.prototype.collapseHidden = true;
                +
                +/**
                + * Height and width of icons.
                + */
                +Blockly.Icon.prototype.SIZE = 17;
                +
                +/**
                + * Bubble UI (if visible).
                + * @type {Blockly.Bubble}
                + * @private
                + */
                +Blockly.Icon.prototype.bubble_ = null;
                +
                +/**
                + * Absolute coordinate of icon's center.
                + * @type {goog.math.Coordinate}
                + * @private
                + */
                +Blockly.Icon.prototype.iconXY_ = null;
                +
                +/**
                + * Create the icon on the block.
                + */
                +Blockly.Icon.prototype.createIcon = function() {
                +  if (this.iconGroup_) {
                +    // Icon already exists.
                +    return;
                +  }
                +  /* Here's the markup that will be generated:
                +  <g class="blocklyIconGroup">
                +    ...
                +  </g>
                +  */
                +  this.iconGroup_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyIconGroup'}, null);
                +  if (this.block_.isInFlyout) {
                +    Blockly.utils.addClass(/** @type {!Element} */ (this.iconGroup_),
                +                      'blocklyIconGroupReadonly');
                +  }
                +  this.drawIcon_(this.iconGroup_);
                +
                +  this.block_.getSvgRoot().appendChild(this.iconGroup_);
                +  Blockly.bindEventWithChecks_(this.iconGroup_, 'mouseup', this,
                +      this.iconClick_);
                +  this.updateEditable();
                +};
                +
                +/**
                + * Dispose of this icon.
                + */
                +Blockly.Icon.prototype.dispose = function() {
                +  // Dispose of and unlink the icon.
                +  goog.dom.removeNode(this.iconGroup_);
                +  this.iconGroup_ = null;
                +  // Dispose of and unlink the bubble.
                +  this.setVisible(false);
                +  this.block_ = null;
                +};
                +
                +/**
                + * Add or remove the UI indicating if this icon may be clicked or not.
                + */
                +Blockly.Icon.prototype.updateEditable = function() {
                +};
                +
                +/**
                + * Is the associated bubble visible?
                + * @return {boolean} True if the bubble is visible.
                + */
                +Blockly.Icon.prototype.isVisible = function() {
                +  return !!this.bubble_;
                +};
                +
                +/**
                + * Clicking on the icon toggles if the bubble is visible.
                + * @param {!Event} e Mouse click event.
                + * @private
                + */
                +Blockly.Icon.prototype.iconClick_ = function(e) {
                +  if (this.block_.workspace.isDragging()) {
                +    // Drag operation is concluding.  Don't open the editor.
                +    return;
                +  }
                +  if (!this.block_.isInFlyout && !Blockly.utils.isRightButton(e)) {
                +    this.setVisible(!this.isVisible());
                +  }
                +};
                +
                +/**
                + * Change the colour of the associated bubble to match its block.
                + */
                +Blockly.Icon.prototype.updateColour = function() {
                +  if (this.isVisible()) {
                +    this.bubble_.setColour(this.block_.getColour());
                +  }
                +};
                +
                +/**
                + * Render the icon.
                + * @param {number} cursorX Horizontal offset at which to position the icon.
                + * @return {number} Horizontal offset for next item to draw.
                + */
                +Blockly.Icon.prototype.renderIcon = function(cursorX) {
                +  if (this.collapseHidden && this.block_.isCollapsed()) {
                +    this.iconGroup_.setAttribute('display', 'none');
                +    return cursorX;
                +  }
                +  this.iconGroup_.setAttribute('display', 'block');
                +
                +  var TOP_MARGIN = 5;
                +  var width = this.SIZE;
                +  if (this.block_.RTL) {
                +    cursorX -= width;
                +  }
                +  this.iconGroup_.setAttribute('transform',
                +      'translate(' + cursorX + ',' + TOP_MARGIN + ')');
                +  this.computeIconLocation();
                +  if (this.block_.RTL) {
                +    cursorX -= Blockly.BlockSvg.SEP_SPACE_X;
                +  } else {
                +    cursorX += width + Blockly.BlockSvg.SEP_SPACE_X;
                +  }
                +  return cursorX;
                +};
                +
                +/**
                + * Notification that the icon has moved.  Update the arrow accordingly.
                + * @param {!goog.math.Coordinate} xy Absolute location in workspace coordinates.
                + */
                +Blockly.Icon.prototype.setIconLocation = function(xy) {
                +  this.iconXY_ = xy;
                +  if (this.isVisible()) {
                +    this.bubble_.setAnchorLocation(xy);
                +  }
                +};
                +
                +/**
                + * Notification that the icon has moved, but we don't really know where.
                + * Recompute the icon's location from scratch.
                + */
                +Blockly.Icon.prototype.computeIconLocation = function() {
                +  // Find coordinates for the centre of the icon and update the arrow.
                +  var blockXY = this.block_.getRelativeToSurfaceXY();
                +  var iconXY = Blockly.utils.getRelativeXY(this.iconGroup_);
                +  var newXY = new goog.math.Coordinate(
                +      blockXY.x + iconXY.x + this.SIZE / 2,
                +      blockXY.y + iconXY.y + this.SIZE / 2);
                +  if (!goog.math.Coordinate.equals(this.getIconLocation(), newXY)) {
                +    this.setIconLocation(newXY);
                +  }
                +};
                +
                +/**
                + * Returns the center of the block's icon relative to the surface.
                + * @return {!goog.math.Coordinate} Object with x and y properties in workspace
                + *     coordinates.
                + */
                +Blockly.Icon.prototype.getIconLocation = function() {
                +  return this.iconXY_;
                +};
                diff --git a/blockly/webif/static/blockly/core/inject.js b/blockly/webif/static/blockly/core/inject.js
                new file mode 100644
                index 000000000..ff196202e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/inject.js
                @@ -0,0 +1,393 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Functions for injecting Blockly into a web page.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.inject');
                +
                +goog.require('Blockly.BlockDragSurfaceSvg');
                +goog.require('Blockly.Css');
                +goog.require('Blockly.Grid');
                +goog.require('Blockly.Options');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('Blockly.WorkspaceDragSurfaceSvg');
                +goog.require('goog.dom');
                +goog.require('goog.ui.Component');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Inject a Blockly editor into the specified container element (usually a div).
                + * @param {!Element|string} container Containing element, or its ID,
                + *     or a CSS selector.
                + * @param {Object=} opt_options Optional dictionary of options.
                + * @return {!Blockly.Workspace} Newly created main workspace.
                + */
                +Blockly.inject = function(container, opt_options) {
                +  if (goog.isString(container)) {
                +    container = document.getElementById(container) ||
                +        document.querySelector(container);
                +  }
                +  // Verify that the container is in document.
                +  if (!goog.dom.contains(document, container)) {
                +    throw 'Error: container is not in current document.';
                +  }
                +  var options = new Blockly.Options(opt_options || {});
                +  var subContainer = goog.dom.createDom('div', 'injectionDiv');
                +  container.appendChild(subContainer);
                +  var svg = Blockly.createDom_(subContainer, options);
                +
                +  // Create surfaces for dragging things. These are optimizations
                +  // so that the broowser does not repaint during the drag.
                +  var blockDragSurface = new Blockly.BlockDragSurfaceSvg(subContainer);
                +  var workspaceDragSurface = new Blockly.WorkspaceDragSurfaceSvg(subContainer);
                +
                +  var workspace = Blockly.createMainWorkspace_(svg, options, blockDragSurface,
                +      workspaceDragSurface);
                +  Blockly.init_(workspace);
                +  Blockly.mainWorkspace = workspace;
                +
                +  Blockly.svgResize(workspace);
                +  return workspace;
                +};
                +
                +/**
                + * Create the SVG image.
                + * @param {!Element} container Containing element.
                + * @param {!Blockly.Options} options Dictionary of options.
                + * @return {!Element} Newly created SVG image.
                + * @private
                + */
                +Blockly.createDom_ = function(container, options) {
                +  // Sadly browsers (Chrome vs Firefox) are currently inconsistent in laying
                +  // out content in RTL mode.  Therefore Blockly forces the use of LTR,
                +  // then manually positions content in RTL as needed.
                +  container.setAttribute('dir', 'LTR');
                +  // Closure can be trusted to create HTML widgets with the proper direction.
                +  goog.ui.Component.setDefaultRightToLeft(options.RTL);
                +
                +  // Load CSS.
                +  Blockly.Css.inject(options.hasCss, options.pathToMedia);
                +
                +  // Build the SVG DOM.
                +  /*
                +  <svg
                +    xmlns="http://www.w3.org/2000/svg"
                +    xmlns:html="http://www.w3.org/1999/xhtml"
                +    xmlns:xlink="http://www.w3.org/1999/xlink"
                +    version="1.1"
                +    class="blocklySvg">
                +    ...
                +  </svg>
                +  */
                +  var svg = Blockly.utils.createSvgElement('svg', {
                +    'xmlns': 'http://www.w3.org/2000/svg',
                +    'xmlns:html': 'http://www.w3.org/1999/xhtml',
                +    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
                +    'version': '1.1',
                +    'class': 'blocklySvg'
                +  }, container);
                +  /*
                +  <defs>
                +    ... filters go here ...
                +  </defs>
                +  */
                +  var defs = Blockly.utils.createSvgElement('defs', {}, svg);
                +  // Each filter/pattern needs a unique ID for the case of multiple Blockly
                +  // instances on a page.  Browser behaviour becomes undefined otherwise.
                +  // https://neil.fraser.name/news/2015/11/01/
                +  var rnd = String(Math.random()).substring(2);
                +  /*
                +    <filter id="blocklyEmbossFilter837493">
                +      <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
                +      <feSpecularLighting in="blur" surfaceScale="1" specularConstant="0.5"
                +                          specularExponent="10" lighting-color="white"
                +                          result="specOut">
                +        <fePointLight x="-5000" y="-10000" z="20000" />
                +      </feSpecularLighting>
                +      <feComposite in="specOut" in2="SourceAlpha" operator="in"
                +                   result="specOut" />
                +      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
                +                   k1="0" k2="1" k3="1" k4="0" />
                +    </filter>
                +  */
                +  var embossFilter = Blockly.utils.createSvgElement('filter',
                +      {'id': 'blocklyEmbossFilter' + rnd}, defs);
                +  Blockly.utils.createSvgElement('feGaussianBlur',
                +      {'in': 'SourceAlpha', 'stdDeviation': 1, 'result': 'blur'}, embossFilter);
                +  var feSpecularLighting = Blockly.utils.createSvgElement('feSpecularLighting',
                +      {'in': 'blur', 'surfaceScale': 1, 'specularConstant': 0.5,
                +       'specularExponent': 10, 'lighting-color': 'white', 'result': 'specOut'},
                +      embossFilter);
                +  Blockly.utils.createSvgElement('fePointLight',
                +      {'x': -5000, 'y': -10000, 'z': 20000}, feSpecularLighting);
                +  Blockly.utils.createSvgElement('feComposite',
                +      {'in': 'specOut', 'in2': 'SourceAlpha', 'operator': 'in',
                +       'result': 'specOut'}, embossFilter);
                +  Blockly.utils.createSvgElement('feComposite',
                +      {'in': 'SourceGraphic', 'in2': 'specOut', 'operator': 'arithmetic',
                +       'k1': 0, 'k2': 1, 'k3': 1, 'k4': 0}, embossFilter);
                +  options.embossFilterId = embossFilter.id;
                +  /*
                +    <pattern id="blocklyDisabledPattern837493" patternUnits="userSpaceOnUse"
                +             width="10" height="10">
                +      <rect width="10" height="10" fill="#aaa" />
                +      <path d="M 0 0 L 10 10 M 10 0 L 0 10" stroke="#cc0" />
                +    </pattern>
                +  */
                +  var disabledPattern = Blockly.utils.createSvgElement('pattern',
                +      {'id': 'blocklyDisabledPattern' + rnd,
                +       'patternUnits': 'userSpaceOnUse',
                +       'width': 10, 'height': 10}, defs);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': 10, 'height': 10, 'fill': '#aaa'}, disabledPattern);
                +  Blockly.utils.createSvgElement('path',
                +      {'d': 'M 0 0 L 10 10 M 10 0 L 0 10', 'stroke': '#cc0'}, disabledPattern);
                +  options.disabledPatternId = disabledPattern.id;
                +
                +  options.gridPattern = Blockly.Grid.createDom(rnd, options.gridOptions, defs);
                +  return svg;
                +};
                +
                +/**
                + * Create a main workspace and add it to the SVG.
                + * @param {!Element} svg SVG element with pattern defined.
                + * @param {!Blockly.Options} options Dictionary of options.
                + * @param {!Blockly.BlockDragSurfaceSvg} blockDragSurface Drag surface SVG
                + *     for the blocks.
                + * @param {!Blockly.WorkspaceDragSurfaceSvg} workspaceDragSurface Drag surface
                + *     SVG for the workspace.
                + * @return {!Blockly.Workspace} Newly created main workspace.
                + * @private
                + */
                +Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface, workspaceDragSurface) {
                +  options.parentWorkspace = null;
                +  var mainWorkspace = new Blockly.WorkspaceSvg(options, blockDragSurface, workspaceDragSurface);
                +  mainWorkspace.scale = options.zoomOptions.startScale;
                +  svg.appendChild(mainWorkspace.createDom('blocklyMainBackground'));
                +
                +  if (!options.hasCategories && options.languageTree) {
                +    // Add flyout as an <svg> that is a sibling of the workspace svg.
                +    var flyout = mainWorkspace.addFlyout_('svg');
                +    Blockly.utils.insertAfter_(flyout, svg);
                +  }
                +
                +  // A null translation will also apply the correct initial scale.
                +  mainWorkspace.translate(0, 0);
                +  Blockly.mainWorkspace = mainWorkspace;
                +
                +  if (!options.readOnly && !options.hasScrollbars) {
                +    var workspaceChanged = function() {
                +      if (!mainWorkspace.isDragging()) {
                +        var metrics = mainWorkspace.getMetrics();
                +        var edgeLeft = metrics.viewLeft + metrics.absoluteLeft;
                +        var edgeTop = metrics.viewTop + metrics.absoluteTop;
                +        if (metrics.contentTop < edgeTop ||
                +            metrics.contentTop + metrics.contentHeight >
                +            metrics.viewHeight + edgeTop ||
                +            metrics.contentLeft <
                +                (options.RTL ? metrics.viewLeft : edgeLeft) ||
                +            metrics.contentLeft + metrics.contentWidth > (options.RTL ?
                +                metrics.viewWidth : metrics.viewWidth + edgeLeft)) {
                +          // One or more blocks may be out of bounds.  Bump them back in.
                +          var MARGIN = 25;
                +          var blocks = mainWorkspace.getTopBlocks(false);
                +          for (var b = 0, block; block = blocks[b]; b++) {
                +            var blockXY = block.getRelativeToSurfaceXY();
                +            var blockHW = block.getHeightWidth();
                +            // Bump any block that's above the top back inside.
                +            var overflowTop = edgeTop + MARGIN - blockHW.height - blockXY.y;
                +            if (overflowTop > 0) {
                +              block.moveBy(0, overflowTop);
                +            }
                +            // Bump any block that's below the bottom back inside.
                +            var overflowBottom =
                +                edgeTop + metrics.viewHeight - MARGIN - blockXY.y;
                +            if (overflowBottom < 0) {
                +              block.moveBy(0, overflowBottom);
                +            }
                +            // Bump any block that's off the left back inside.
                +            var overflowLeft = MARGIN + edgeLeft -
                +                blockXY.x - (options.RTL ? 0 : blockHW.width);
                +            if (overflowLeft > 0) {
                +              block.moveBy(overflowLeft, 0);
                +            }
                +            // Bump any block that's off the right back inside.
                +            var overflowRight = edgeLeft + metrics.viewWidth - MARGIN -
                +                blockXY.x + (options.RTL ? blockHW.width : 0);
                +            if (overflowRight < 0) {
                +              block.moveBy(overflowRight, 0);
                +            }
                +          }
                +        }
                +      }
                +    };
                +    mainWorkspace.addChangeListener(workspaceChanged);
                +  }
                +  // The SVG is now fully assembled.
                +  Blockly.svgResize(mainWorkspace);
                +  Blockly.WidgetDiv.createDom();
                +  Blockly.Tooltip.createDom();
                +  return mainWorkspace;
                +};
                +
                +/**
                + * Initialize Blockly with various handlers.
                + * @param {!Blockly.Workspace} mainWorkspace Newly created main workspace.
                + * @private
                + */
                +Blockly.init_ = function(mainWorkspace) {
                +  var options = mainWorkspace.options;
                +  var svg = mainWorkspace.getParentSvg();
                +
                +  // Suppress the browser's context menu.
                +  Blockly.bindEventWithChecks_(svg.parentNode, 'contextmenu', null,
                +      function(e) {
                +        if (!Blockly.utils.isTargetInput(e)) {
                +          e.preventDefault();
                +        }
                +      });
                +
                +  var workspaceResizeHandler = Blockly.bindEventWithChecks_(window, 'resize',
                +      null,
                +      function() {
                +        Blockly.hideChaff(true);
                +        Blockly.svgResize(mainWorkspace);
                +      });
                +  mainWorkspace.setResizeHandlerWrapper(workspaceResizeHandler);
                +
                +  Blockly.inject.bindDocumentEvents_();
                +
                +  if (options.languageTree) {
                +    if (mainWorkspace.toolbox_) {
                +      mainWorkspace.toolbox_.init(mainWorkspace);
                +    } else if (mainWorkspace.flyout_) {
                +      // Build a fixed flyout with the root blocks.
                +      mainWorkspace.flyout_.init(mainWorkspace);
                +      mainWorkspace.flyout_.show(options.languageTree.childNodes);
                +      mainWorkspace.flyout_.scrollToStart();
                +      // Translate the workspace sideways to avoid the fixed flyout.
                +      mainWorkspace.scrollX = mainWorkspace.flyout_.width_;
                +      if (options.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
                +        mainWorkspace.scrollX *= -1;
                +      }
                +      mainWorkspace.translate(mainWorkspace.scrollX, 0);
                +    }
                +  }
                +
                +  if (options.hasScrollbars) {
                +    mainWorkspace.scrollbar = new Blockly.ScrollbarPair(mainWorkspace);
                +    mainWorkspace.scrollbar.resize();
                +  }
                +
                +  // Load the sounds.
                +  if (options.hasSounds) {
                +    Blockly.inject.loadSounds_(options.pathToMedia, mainWorkspace);
                +  }
                +};
                +
                +/**
                + * Bind document events, but only once.  Destroying and reinjecting Blockly
                + * should not bind again.
                + * Bind events for scrolling the workspace.
                + * Most of these events should be bound to the SVG's surface.
                + * However, 'mouseup' has to be on the whole document so that a block dragged
                + * out of bounds and released will know that it has been released.
                + * Also, 'keydown' has to be on the whole document since the browser doesn't
                + * understand a concept of focus on the SVG image.
                + * @private
                + */
                +Blockly.inject.bindDocumentEvents_ = function() {
                +  if (!Blockly.documentEventsBound_) {
                +    Blockly.bindEventWithChecks_(document, 'keydown', null, Blockly.onKeyDown_);
                +    // longStop needs to run to stop the context menu from showing up.  It
                +    // should run regardless of what other touch event handlers have run.
                +    Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_);
                +    Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_);
                +    // Some iPad versions don't fire resize after portrait to landscape change.
                +    if (goog.userAgent.IPAD) {
                +      Blockly.bindEventWithChecks_(window, 'orientationchange', document,
                +          function() {
                +            // TODO(#397): Fix for multiple blockly workspaces.
                +            Blockly.svgResize(Blockly.getMainWorkspace());
                +          });
                +    }
                +  }
                +  Blockly.documentEventsBound_ = true;
                +};
                +
                +/**
                + * Load sounds for the given workspace.
                + * @param {string} pathToMedia The path to the media directory.
                + * @param {!Blockly.Workspace} workspace The workspace to load sounds for.
                + * @private
                + */
                +Blockly.inject.loadSounds_ = function(pathToMedia, workspace) {
                +  var audioMgr = workspace.getAudioManager();
                +  audioMgr.load(
                +      [pathToMedia + 'click.mp3',
                +       pathToMedia + 'click.wav',
                +       pathToMedia + 'click.ogg'], 'click');
                +  audioMgr.load(
                +      [pathToMedia + 'disconnect.wav',
                +       pathToMedia + 'disconnect.mp3',
                +       pathToMedia + 'disconnect.ogg'], 'disconnect');
                +  audioMgr.load(
                +      [pathToMedia + 'delete.mp3',
                +       pathToMedia + 'delete.ogg',
                +       pathToMedia + 'delete.wav'], 'delete');
                +
                +  // Bind temporary hooks that preload the sounds.
                +  var soundBinds = [];
                +  var unbindSounds = function() {
                +    while (soundBinds.length) {
                +      Blockly.unbindEvent_(soundBinds.pop());
                +    }
                +    audioMgr.preload();
                +  };
                +
                +  // These are bound on mouse/touch events with Blockly.bindEventWithChecks_, so
                +  // they restrict the touch identifier that will be recognized.  But this is
                +  // really something that happens on a click, not a drag, so that's not
                +  // necessary.
                +
                +  // Android ignores any sound not loaded as a result of a user action.
                +  soundBinds.push(
                +      Blockly.bindEventWithChecks_(document, 'mousemove', null, unbindSounds,
                +          true));
                +  soundBinds.push(
                +      Blockly.bindEventWithChecks_(document, 'touchstart', null, unbindSounds,
                +          true));
                +};
                +
                +/**
                + * Modify the block tree on the existing toolbox.
                + * @param {Node|string} tree DOM tree of blocks, or text representation of same.
                + * @deprecated April 2015
                + */
                +Blockly.updateToolbox = function(tree) {
                +  console.warn('Deprecated call to Blockly.updateToolbox, ' +
                +               'use workspace.updateToolbox instead.');
                +  Blockly.getMainWorkspace().updateToolbox(tree);
                +};
                diff --git a/blockly/webif/static/blockly/core/input.js b/blockly/webif/static/blockly/core/input.js
                new file mode 100644
                index 000000000..c2c006e52
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/input.js
                @@ -0,0 +1,251 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing an input (value, statement, or dummy).
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Input');
                +
                +goog.require('Blockly.Connection');
                +goog.require('Blockly.FieldLabel');
                +goog.require('goog.asserts');
                +
                +
                +/**
                + * Class for an input with an optional field.
                + * @param {number} type The type of the input.
                + * @param {string} name Language-neutral identifier which may used to find this
                + *     input again.
                + * @param {!Blockly.Block} block The block containing this input.
                + * @param {Blockly.Connection} connection Optional connection for this input.
                + * @constructor
                + */
                +Blockly.Input = function(type, name, block, connection) {
                +  if (type != Blockly.DUMMY_INPUT && !name) {
                +    throw 'Value inputs and statement inputs must have non-empty name.';
                +  }
                +  /** @type {number} */
                +  this.type = type;
                +  /** @type {string} */
                +  this.name = name;
                +  /**
                +   * @type {!Blockly.Block}
                +   * @private
                +   */
                +  this.sourceBlock_ = block;
                +  /** @type {Blockly.Connection} */
                +  this.connection = connection;
                +  /** @type {!Array.<!Blockly.Field>} */
                +  this.fieldRow = [];
                +};
                +
                +/**
                + * Alignment of input's fields (left, right or centre).
                + * @type {number}
                + */
                +Blockly.Input.prototype.align = Blockly.ALIGN_LEFT;
                +
                +/**
                + * Is the input visible?
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Input.prototype.visible_ = true;
                +
                +/**
                + * Add a field (or label from string), and all prefix and suffix fields, to the
                + * end of the input's field row.
                + * @param {string|!Blockly.Field} field Something to add as a field.
                + * @param {string=} opt_name Language-neutral identifier which may used to find
                + *     this field again.  Should be unique to the host block.
                + * @return {!Blockly.Input} The input being append to (to allow chaining).
                + */
                +Blockly.Input.prototype.appendField = function(field, opt_name) {
                +  this.insertFieldAt(this.fieldRow.length, field, opt_name);
                +  return this;
                +};
                +
                +/**
                + * Inserts a field (or label from string), and all prefix and suffix fields, at
                + * the location of the input's field row.
                + * @param {number} index The index at which to insert field.
                + * @param {string|!Blockly.Field} field Something to add as a field.
                + * @param {string=} opt_name Language-neutral identifier which may used to find
                + *     this field again.  Should be unique to the host block.
                + * @return {number} The index following the last inserted field.
                + */
                +Blockly.Input.prototype.insertFieldAt = function(index, field, opt_name) {
                +  if (index < 0 || index > this.fieldRow.length) {
                +    throw new Error('index ' + index + ' out of bounds.');
                +  }
                +
                +  // Empty string, Null or undefined generates no field, unless field is named.
                +  if (!field && !opt_name) {
                +    return this;
                +  }
                +  // Generate a FieldLabel when given a plain text field.
                +  if (goog.isString(field)) {
                +    field = new Blockly.FieldLabel(/** @type {string} */ (field));
                +  }
                +  field.setSourceBlock(this.sourceBlock_);
                +  if (this.sourceBlock_.rendered) {
                +    field.init();
                +  }
                +  field.name = opt_name;
                +
                +  if (field.prefixField) {
                +    // Add any prefix.
                +    index = this.insertFieldAt(index, field.prefixField);
                +  }
                +  // Add the field to the field row.
                +  this.fieldRow.splice(index, 0, field);
                +  ++index;
                +  if (field.suffixField) {
                +    // Add any suffix.
                +    index = this.insertFieldAt(index, field.suffixField);
                +  }
                +
                +  if (this.sourceBlock_.rendered) {
                +    this.sourceBlock_.render();
                +    // Adding a field will cause the block to change shape.
                +    this.sourceBlock_.bumpNeighbours_();
                +  }
                +  return index;
                +};
                +
                +/**
                + * Remove a field from this input.
                + * @param {string} name The name of the field.
                + * @throws {goog.asserts.AssertionError} if the field is not present.
                + */
                +Blockly.Input.prototype.removeField = function(name) {
                +  for (var i = 0, field; field = this.fieldRow[i]; i++) {
                +    if (field.name === name) {
                +      field.dispose();
                +      this.fieldRow.splice(i, 1);
                +      if (this.sourceBlock_.rendered) {
                +        this.sourceBlock_.render();
                +        // Removing a field will cause the block to change shape.
                +        this.sourceBlock_.bumpNeighbours_();
                +      }
                +      return;
                +    }
                +  }
                +  goog.asserts.fail('Field "%s" not found.', name);
                +};
                +
                +/**
                + * Gets whether this input is visible or not.
                + * @return {boolean} True if visible.
                + */
                +Blockly.Input.prototype.isVisible = function() {
                +  return this.visible_;
                +};
                +
                +/**
                + * Sets whether this input is visible or not.
                + * Used to collapse/uncollapse a block.
                + * @param {boolean} visible True if visible.
                + * @return {!Array.<!Blockly.Block>} List of blocks to render.
                + */
                +Blockly.Input.prototype.setVisible = function(visible) {
                +  var renderList = [];
                +  if (this.visible_ == visible) {
                +    return renderList;
                +  }
                +  this.visible_ = visible;
                +
                +  var display = visible ? 'block' : 'none';
                +  for (var y = 0, field; field = this.fieldRow[y]; y++) {
                +    field.setVisible(visible);
                +  }
                +  if (this.connection) {
                +    // Has a connection.
                +    if (visible) {
                +      renderList = this.connection.unhideAll();
                +    } else {
                +      this.connection.hideAll();
                +    }
                +    var child = this.connection.targetBlock();
                +    if (child) {
                +      child.getSvgRoot().style.display = display;
                +      if (!visible) {
                +        child.rendered = false;
                +      }
                +    }
                +  }
                +  return renderList;
                +};
                +
                +/**
                + * Change a connection's compatibility.
                + * @param {string|Array.<string>|null} check Compatible value type or
                + *     list of value types.  Null if all types are compatible.
                + * @return {!Blockly.Input} The input being modified (to allow chaining).
                + */
                +Blockly.Input.prototype.setCheck = function(check) {
                +  if (!this.connection) {
                +    throw 'This input does not have a connection.';
                +  }
                +  this.connection.setCheck(check);
                +  return this;
                +};
                +
                +/**
                + * Change the alignment of the connection's field(s).
                + * @param {number} align One of Blockly.ALIGN_LEFT, ALIGN_CENTRE, ALIGN_RIGHT.
                + *   In RTL mode directions are reversed, and ALIGN_RIGHT aligns to the left.
                + * @return {!Blockly.Input} The input being modified (to allow chaining).
                + */
                +Blockly.Input.prototype.setAlign = function(align) {
                +  this.align = align;
                +  if (this.sourceBlock_.rendered) {
                +    this.sourceBlock_.render();
                +  }
                +  return this;
                +};
                +
                +/**
                + * Initialize the fields on this input.
                + */
                +Blockly.Input.prototype.init = function() {
                +  if (!this.sourceBlock_.workspace.rendered) {
                +    return;  // Headless blocks don't need fields initialized.
                +  }
                +  for (var i = 0; i < this.fieldRow.length; i++) {
                +    this.fieldRow[i].init();
                +  }
                +};
                +
                +/**
                + * Sever all links to this input.
                + */
                +Blockly.Input.prototype.dispose = function() {
                +  for (var i = 0, field; field = this.fieldRow[i]; i++) {
                +    field.dispose();
                +  }
                +  if (this.connection) {
                +    this.connection.dispose();
                +  }
                +  this.sourceBlock_ = null;
                +};
                diff --git a/blockly/webif/static/blockly/core/msg.js b/blockly/webif/static/blockly/core/msg.js
                new file mode 100644
                index 000000000..4ebcad1ab
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/msg.js
                @@ -0,0 +1,62 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Empty name space for the Message singleton.
                + * @author scr@google.com (Sheridan Rawlins)
                + */
                +'use strict';
                +
                +/**
                + * Name space for the Msg singleton.
                + * Msg gets populated in the message files.
                + */
                +goog.provide('Blockly.Msg');
                +
                +
                +/**
                + * Back up original getMsg function.
                + * @type {!Function}
                + */
                +goog.getMsgOrig = goog.getMsg;
                +
                +/**
                + * Gets a localized message.
                + * Overrides the default Closure function to check for a Blockly.Msg first.
                + * Used infrequently, only known case is TODAY button in date picker.
                + * @param {string} str Translatable string, places holders in the form {$foo}.
                + * @param {Object<string, string>=} opt_values Maps place holder name to value.
                + * @return {string} message with placeholders filled.
                + * @suppress {duplicate}
                + */
                +goog.getMsg = function(str, opt_values) {
                +  var key = goog.getMsg.blocklyMsgMap[str];
                +  if (key) {
                +    str = Blockly.Msg[key];
                +  }
                +  return goog.getMsgOrig(str, opt_values);
                +};
                +
                +/**
                + * Mapping of Closure messages to Blockly.Msg names.
                + */
                +goog.getMsg.blocklyMsgMap = {
                +  'Today': 'TODAY'
                +};
                diff --git a/blockly/webif/static/blockly/core/mutator.js b/blockly/webif/static/blockly/core/mutator.js
                new file mode 100644
                index 000000000..613771bcc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/mutator.js
                @@ -0,0 +1,405 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a mutator dialog.  A mutator allows the
                + * user to change the shape of a block using a nested blocks editor.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Mutator');
                +
                +goog.require('Blockly.Bubble');
                +goog.require('Blockly.Icon');
                +goog.require('Blockly.WorkspaceSvg');
                +goog.require('goog.Timer');
                +goog.require('goog.dom');
                +
                +
                +/**
                + * Class for a mutator dialog.
                + * @param {!Array.<string>} quarkNames List of names of sub-blocks for flyout.
                + * @extends {Blockly.Icon}
                + * @constructor
                + */
                +Blockly.Mutator = function(quarkNames) {
                +  Blockly.Mutator.superClass_.constructor.call(this, null);
                +  this.quarkNames_ = quarkNames;
                +};
                +goog.inherits(Blockly.Mutator, Blockly.Icon);
                +
                +/**
                + * Width of workspace.
                + * @private
                + */
                +Blockly.Mutator.prototype.workspaceWidth_ = 0;
                +
                +/**
                + * Height of workspace.
                + * @private
                + */
                +Blockly.Mutator.prototype.workspaceHeight_ = 0;
                +
                +/**
                + * Draw the mutator icon.
                + * @param {!Element} group The icon group.
                + * @private
                + */
                +Blockly.Mutator.prototype.drawIcon_ = function(group) {
                +  // Square with rounded corners.
                +  Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyIconShape',
                +       'rx': '4', 'ry': '4',
                +       'height': '16', 'width': '16'},
                +       group);
                +  // Gear teeth.
                +  Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyIconSymbol',
                +       'd': 'm4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 -0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z'},
                +       group);
                +  // Axle hole.
                +  Blockly.utils.createSvgElement('circle',
                +      {'class': 'blocklyIconShape', 'r': '2.7', 'cx': '8', 'cy': '8'},
                +       group);
                +};
                +
                +/**
                + * Clicking on the icon toggles if the mutator bubble is visible.
                + * Disable if block is uneditable.
                + * @param {!Event} e Mouse click event.
                + * @private
                + * @override
                + */
                +Blockly.Mutator.prototype.iconClick_ = function(e) {
                +  if (this.block_.isEditable()) {
                +    Blockly.Icon.prototype.iconClick_.call(this, e);
                +  }
                +};
                +
                +/**
                + * Create the editor for the mutator's bubble.
                + * @return {!Element} The top-level node of the editor.
                + * @private
                + */
                +Blockly.Mutator.prototype.createEditor_ = function() {
                +  /* Create the editor.  Here's the markup that will be generated:
                +  <svg>
                +    [Workspace]
                +  </svg>
                +  */
                +  this.svgDialog_ = Blockly.utils.createSvgElement('svg',
                +      {'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH},
                +      null);
                +  // Convert the list of names into a list of XML objects for the flyout.
                +  if (this.quarkNames_.length) {
                +    var quarkXml = goog.dom.createDom('xml');
                +    for (var i = 0, quarkName; quarkName = this.quarkNames_[i]; i++) {
                +      quarkXml.appendChild(goog.dom.createDom('block', {'type': quarkName}));
                +    }
                +  } else {
                +    var quarkXml = null;
                +  }
                +  var workspaceOptions = {
                +    languageTree: quarkXml,
                +    parentWorkspace: this.block_.workspace,
                +    pathToMedia: this.block_.workspace.options.pathToMedia,
                +    RTL: this.block_.RTL,
                +    toolboxPosition: this.block_.RTL ? Blockly.TOOLBOX_AT_RIGHT :
                +        Blockly.TOOLBOX_AT_LEFT,
                +    horizontalLayout: false,
                +    getMetrics: this.getFlyoutMetrics_.bind(this),
                +    setMetrics: null
                +  };
                +  this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
                +  this.workspace_.isMutator = true;
                +
                +  // Mutator flyouts go inside the mutator workspace's <g> rather than in
                +  // a top level svg. Instead of handling scale themselves, mutators
                +  // inherit scale from the parent workspace.
                +  // To fix this, scale needs to be applied at a different level in the dom.
                +  var flyoutSvg =  this.workspace_.addFlyout_('g');
                +  var background = this.workspace_.createDom('blocklyMutatorBackground');
                +
                +  // Insert the flyout after the <rect> but before the block canvas so that
                +  // the flyout is underneath in z-order.  This makes blocks layering during
                +  // dragging work properly.
                +  background.insertBefore(flyoutSvg, this.workspace_.svgBlockCanvas_);
                +  this.svgDialog_.appendChild(background);
                +
                +  return this.svgDialog_;
                +};
                +
                +/**
                + * Add or remove the UI indicating if this icon may be clicked or not.
                + */
                +Blockly.Mutator.prototype.updateEditable = function() {
                +  if (!this.block_.isInFlyout) {
                +    if (this.block_.isEditable()) {
                +      if (this.iconGroup_) {
                +        Blockly.utils.removeClass(/** @type {!Element} */ (this.iconGroup_),
                +                             'blocklyIconGroupReadonly');
                +      }
                +    } else {
                +      // Close any mutator bubble.  Icon is not clickable.
                +      this.setVisible(false);
                +      if (this.iconGroup_) {
                +        Blockly.utils.addClass(/** @type {!Element} */ (this.iconGroup_),
                +                          'blocklyIconGroupReadonly');
                +      }
                +    }
                +  }
                +  // Default behaviour for an icon.
                +  Blockly.Icon.prototype.updateEditable.call(this);
                +};
                +
                +/**
                + * Callback function triggered when the bubble has resized.
                + * Resize the workspace accordingly.
                + * @private
                + */
                +Blockly.Mutator.prototype.resizeBubble_ = function() {
                +  var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH;
                +  var workspaceSize = this.workspace_.getCanvas().getBBox();
                +  var width;
                +  if (this.block_.RTL) {
                +    width = -workspaceSize.x;
                +  } else {
                +    width = workspaceSize.width + workspaceSize.x;
                +  }
                +  var height = workspaceSize.height + doubleBorderWidth * 3;
                +  if (this.workspace_.flyout_) {
                +    var flyoutMetrics = this.workspace_.flyout_.getMetrics_();
                +    height = Math.max(height, flyoutMetrics.contentHeight + 20);
                +  }
                +  width += doubleBorderWidth * 3;
                +  // Only resize if the size difference is significant.  Eliminates shuddering.
                +  if (Math.abs(this.workspaceWidth_ - width) > doubleBorderWidth ||
                +      Math.abs(this.workspaceHeight_ - height) > doubleBorderWidth) {
                +    // Record some layout information for getFlyoutMetrics_.
                +    this.workspaceWidth_ = width;
                +    this.workspaceHeight_ = height;
                +    // Resize the bubble.
                +    this.bubble_.setBubbleSize(width + doubleBorderWidth,
                +                               height + doubleBorderWidth);
                +    this.svgDialog_.setAttribute('width', this.workspaceWidth_);
                +    this.svgDialog_.setAttribute('height', this.workspaceHeight_);
                +  }
                +
                +  if (this.block_.RTL) {
                +    // Scroll the workspace to always left-align.
                +    var translation = 'translate(' + this.workspaceWidth_ + ',0)';
                +    this.workspace_.getCanvas().setAttribute('transform', translation);
                +  }
                +  this.workspace_.resize();
                +};
                +
                +/**
                + * Show or hide the mutator bubble.
                + * @param {boolean} visible True if the bubble should be visible.
                + */
                +Blockly.Mutator.prototype.setVisible = function(visible) {
                +  if (visible == this.isVisible()) {
                +    // No change.
                +    return;
                +  }
                +  Blockly.Events.fire(
                +      new Blockly.Events.Ui(this.block_, 'mutatorOpen', !visible, visible));
                +  if (visible) {
                +    // Create the bubble.
                +    this.bubble_ = new Blockly.Bubble(
                +        /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace),
                +        this.createEditor_(), this.block_.svgPath_, this.iconXY_, null, null);
                +    var tree = this.workspace_.options.languageTree;
                +    if (tree) {
                +      this.workspace_.flyout_.init(this.workspace_);
                +      this.workspace_.flyout_.show(tree.childNodes);
                +    }
                +
                +    this.rootBlock_ = this.block_.decompose(this.workspace_);
                +    var blocks = this.rootBlock_.getDescendants();
                +    for (var i = 0, child; child = blocks[i]; i++) {
                +      child.render();
                +    }
                +    // The root block should not be dragable or deletable.
                +    this.rootBlock_.setMovable(false);
                +    this.rootBlock_.setDeletable(false);
                +    if (this.workspace_.flyout_) {
                +      var margin = this.workspace_.flyout_.CORNER_RADIUS * 2;
                +      var x = this.workspace_.flyout_.width_ + margin;
                +    } else {
                +      var margin = 16;
                +      var x = margin;
                +    }
                +    if (this.block_.RTL) {
                +      x = -x;
                +    }
                +    this.rootBlock_.moveBy(x, margin);
                +    // Save the initial connections, then listen for further changes.
                +    if (this.block_.saveConnections) {
                +      var thisMutator = this;
                +      this.block_.saveConnections(this.rootBlock_);
                +      this.sourceListener_ = function() {
                +        thisMutator.block_.saveConnections(thisMutator.rootBlock_);
                +      };
                +      this.block_.workspace.addChangeListener(this.sourceListener_);
                +    }
                +    this.resizeBubble_();
                +    // When the mutator's workspace changes, update the source block.
                +    this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));
                +    this.updateColour();
                +  } else {
                +    // Dispose of the bubble.
                +    this.svgDialog_ = null;
                +    this.workspace_.dispose();
                +    this.workspace_ = null;
                +    this.rootBlock_ = null;
                +    this.bubble_.dispose();
                +    this.bubble_ = null;
                +    this.workspaceWidth_ = 0;
                +    this.workspaceHeight_ = 0;
                +    if (this.sourceListener_) {
                +      this.block_.workspace.removeChangeListener(this.sourceListener_);
                +      this.sourceListener_ = null;
                +    }
                +  }
                +};
                +
                +/**
                + * Update the source block when the mutator's blocks are changed.
                + * Bump down any block that's too high.
                + * Fired whenever a change is made to the mutator's workspace.
                + * @private
                + */
                +Blockly.Mutator.prototype.workspaceChanged_ = function() {
                +  if (!this.workspace_.isDragging()) {
                +    var blocks = this.workspace_.getTopBlocks(false);
                +    var MARGIN = 20;
                +    for (var b = 0, block; block = blocks[b]; b++) {
                +      var blockXY = block.getRelativeToSurfaceXY();
                +      var blockHW = block.getHeightWidth();
                +      if (blockXY.y + blockHW.height < MARGIN) {
                +        // Bump any block that's above the top back inside.
                +        block.moveBy(0, MARGIN - blockHW.height - blockXY.y);
                +      }
                +    }
                +  }
                +
                +  // When the mutator's workspace changes, update the source block.
                +  if (this.rootBlock_.workspace == this.workspace_) {
                +    Blockly.Events.setGroup(true);
                +    var block = this.block_;
                +    var oldMutationDom = block.mutationToDom();
                +    var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
                +    // Switch off rendering while the source block is rebuilt.
                +    var savedRendered = block.rendered;
                +    block.rendered = false;
                +    // Allow the source block to rebuild itself.
                +    block.compose(this.rootBlock_);
                +    // Restore rendering and show the changes.
                +    block.rendered = savedRendered;
                +    // Mutation may have added some elements that need initializing.
                +    block.initSvg();
                +    var newMutationDom = block.mutationToDom();
                +    var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
                +    if (oldMutation != newMutation) {
                +      Blockly.Events.fire(new Blockly.Events.BlockChange(
                +          block, 'mutation', null, oldMutation, newMutation));
                +      // Ensure that any bump is part of this mutation's event group.
                +      var group = Blockly.Events.getGroup();
                +      setTimeout(function() {
                +        Blockly.Events.setGroup(group);
                +        block.bumpNeighbours_();
                +        Blockly.Events.setGroup(false);
                +      }, Blockly.BUMP_DELAY);
                +    }
                +    if (block.rendered) {
                +      block.render();
                +    }
                +    // Don't update the bubble until the drag has ended, to avoid moving blocks
                +    // under the cursor.
                +    if (!this.workspace_.isDragging()) {
                +      this.resizeBubble_();
                +    }
                +    Blockly.Events.setGroup(false);
                +  }
                +};
                +
                +/**
                + * Return an object with all the metrics required to size scrollbars for the
                + * mutator flyout.  The following properties are computed:
                + * .viewHeight: Height of the visible rectangle,
                + * .viewWidth: Width of the visible rectangle,
                + * .absoluteTop: Top-edge of view.
                + * .absoluteLeft: Left-edge of view.
                + * @return {!Object} Contains size and position metrics of mutator dialog's
                + *     workspace.
                + * @private
                + */
                +Blockly.Mutator.prototype.getFlyoutMetrics_ = function() {
                +  return {
                +    viewHeight: this.workspaceHeight_,
                +    viewWidth: this.workspaceWidth_,
                +    absoluteTop: 0,
                +    absoluteLeft: 0
                +  };
                +};
                +
                +/**
                + * Dispose of this mutator.
                + */
                +Blockly.Mutator.prototype.dispose = function() {
                +  this.block_.mutator = null;
                +  Blockly.Icon.prototype.dispose.call(this);
                +};
                +
                +/**
                + * Reconnect an block to a mutated input.
                + * @param {Blockly.Connection} connectionChild Connection on child block.
                + * @param {!Blockly.Block} block Parent block.
                + * @param {string} inputName Name of input on parent block.
                + * @return {boolean} True iff a reconnection was made, false otherwise.
                + */
                +Blockly.Mutator.reconnect = function(connectionChild, block, inputName) {
                +  if (!connectionChild || !connectionChild.getSourceBlock().workspace) {
                +    return false;  // No connection or block has been deleted.
                +  }
                +  var connectionParent = block.getInput(inputName).connection;
                +  var currentParent = connectionChild.targetBlock();
                +  if ((!currentParent || currentParent == block) &&
                +      connectionParent.targetConnection != connectionChild) {
                +    if (connectionParent.isConnected()) {
                +      // There's already something connected here.  Get rid of it.
                +      connectionParent.disconnect();
                +    }
                +    connectionParent.connect(connectionChild);
                +    return true;
                +  }
                +  return false;
                +};
                +
                +// Export symbols that would otherwise be renamed by Closure compiler.
                +if (!goog.global['Blockly']) {
                +  goog.global['Blockly'] = {};
                +}
                +if (!goog.global['Blockly']['Mutator']) {
                +  goog.global['Blockly']['Mutator'] = {};
                +}
                +goog.global['Blockly']['Mutator']['reconnect'] = Blockly.Mutator.reconnect;
                diff --git a/blockly/webif/static/blockly/core/names.js b/blockly/webif/static/blockly/core/names.js
                new file mode 100644
                index 000000000..bfe942ab9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/names.js
                @@ -0,0 +1,143 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Utility functions for handling variables and procedure names.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Names');
                +
                +
                +/**
                + * Class for a database of entity names (variables, functions, etc).
                + * @param {string} reservedWords A comma-separated string of words that are
                + *     illegal for use as names in a language (e.g. 'new,if,this,...').
                + * @param {string=} opt_variablePrefix Some languages need a '$' or a namespace
                + *     before all variable names.
                + * @constructor
                + */
                +Blockly.Names = function(reservedWords, opt_variablePrefix) {
                +  this.variablePrefix_ = opt_variablePrefix || '';
                +  this.reservedDict_ = Object.create(null);
                +  if (reservedWords) {
                +    var splitWords = reservedWords.split(',');
                +    for (var i = 0; i < splitWords.length; i++) {
                +      this.reservedDict_[splitWords[i]] = true;
                +    }
                +  }
                +  this.reset();
                +};
                +
                +/**
                + * When JavaScript (or most other languages) is generated, variable 'foo' and
                + * procedure 'foo' would collide.  However, Blockly has no such problems since
                + * variable get 'foo' and procedure call 'foo' are unambiguous.
                + * Therefore, Blockly keeps a separate type name to disambiguate.
                + * getName('foo', 'variable') -> 'foo'
                + * getName('foo', 'procedure') -> 'foo2'
                + */
                +
                +/**
                + * Empty the database and start from scratch.  The reserved words are kept.
                + */
                +Blockly.Names.prototype.reset = function() {
                +  this.db_ = Object.create(null);
                +  this.dbReverse_ = Object.create(null);
                +};
                +
                +/**
                + * Convert a Blockly entity name to a legal exportable entity name.
                + * @param {string} name The Blockly entity name (no constraints).
                + * @param {string} type The type of entity in Blockly
                + *     ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
                + * @return {string} An entity name legal for the exported language.
                + */
                +Blockly.Names.prototype.getName = function(name, type) {
                +  var normalized = name.toLowerCase() + '_' + type;
                +  var prefix = (type == Blockly.Variables.NAME_TYPE) ?
                +      this.variablePrefix_ : '';
                +  if (normalized in this.db_) {
                +    return prefix + this.db_[normalized];
                +  }
                +  var safeName = this.getDistinctName(name, type);
                +  this.db_[normalized] = safeName.substr(prefix.length);
                +  return safeName;
                +};
                +
                +/**
                + * Convert a Blockly entity name to a legal exportable entity name.
                + * Ensure that this is a new name not overlapping any previously defined name.
                + * Also check against list of reserved words for the current language and
                + * ensure name doesn't collide.
                + * @param {string} name The Blockly entity name (no constraints).
                + * @param {string} type The type of entity in Blockly
                + *     ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
                + * @return {string} An entity name legal for the exported language.
                + */
                +Blockly.Names.prototype.getDistinctName = function(name, type) {
                +  var safeName = this.safeName_(name);
                +  var i = '';
                +  while (this.dbReverse_[safeName + i] ||
                +         (safeName + i) in this.reservedDict_) {
                +    // Collision with existing name.  Create a unique name.
                +    i = i ? i + 1 : 2;
                +  }
                +  safeName += i;
                +  this.dbReverse_[safeName] = true;
                +  var prefix = (type == Blockly.Variables.NAME_TYPE) ?
                +      this.variablePrefix_ : '';
                +  return prefix + safeName;
                +};
                +
                +/**
                + * Given a proposed entity name, generate a name that conforms to the
                + * [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for
                + * variables.
                + * @param {string} name Potentially illegal entity name.
                + * @return {string} Safe entity name.
                + * @private
                + */
                +Blockly.Names.prototype.safeName_ = function(name) {
                +  if (!name) {
                +    name = 'unnamed';
                +  } else {
                +    // Unfortunately names in non-latin characters will look like
                +    // _E9_9F_B3_E4_B9_90 which is pretty meaningless.
                +    name = encodeURI(name.replace(/ /g, '_')).replace(/[^\w]/g, '_');
                +    // Most languages don't allow names with leading numbers.
                +    if ('0123456789'.indexOf(name[0]) != -1) {
                +      name = 'my_' + name;
                +    }
                +  }
                +  return name;
                +};
                +
                +/**
                + * Do the given two entity names refer to the same entity?
                + * Blockly names are case-insensitive.
                + * @param {string} name1 First name.
                + * @param {string} name2 Second name.
                + * @return {boolean} True if names are the same.
                + */
                +Blockly.Names.equals = function(name1, name2) {
                +  return name1.toLowerCase() == name2.toLowerCase();
                +};
                diff --git a/blockly/webif/static/blockly/core/options.js b/blockly/webif/static/blockly/core/options.js
                new file mode 100644
                index 000000000..f9ab04005
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/options.js
                @@ -0,0 +1,237 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object that controls settings for the workspace.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Options');
                +
                +
                +/**
                + * Parse the user-specified options, using reasonable defaults where behaviour
                + * is unspecified.
                + * @param {!Object} options Dictionary of options.  Specification:
                + *   https://developers.google.com/blockly/guides/get-started/web#configuration
                + * @constructor
                + */
                +Blockly.Options = function(options) {
                +  var readOnly = !!options['readOnly'];
                +  if (readOnly) {
                +    var languageTree = null;
                +    var hasCategories = false;
                +    var hasTrashcan = false;
                +    var hasCollapse = false;
                +    var hasComments = false;
                +    var hasDisable = false;
                +    var hasSounds = false;
                +  } else {
                +    var languageTree = Blockly.Options.parseToolboxTree(options['toolbox']);
                +    var hasCategories = Boolean(languageTree &&
                +        languageTree.getElementsByTagName('category').length);
                +    var hasTrashcan = options['trashcan'];
                +    if (hasTrashcan === undefined) {
                +      hasTrashcan = hasCategories;
                +    }
                +    var hasCollapse = options['collapse'];
                +    if (hasCollapse === undefined) {
                +      hasCollapse = hasCategories;
                +    }
                +    var hasComments = options['comments'];
                +    if (hasComments === undefined) {
                +      hasComments = hasCategories;
                +    }
                +    var hasDisable = options['disable'];
                +    if (hasDisable === undefined) {
                +      hasDisable = hasCategories;
                +    }
                +    var hasSounds = options['sounds'];
                +    if (hasSounds === undefined) {
                +      hasSounds = true;
                +    }
                +  }
                +  var rtl = !!options['rtl'];
                +  var horizontalLayout = options['horizontalLayout'];
                +  if (horizontalLayout === undefined) {
                +    horizontalLayout = false;
                +  }
                +  var toolboxAtStart = options['toolboxPosition'];
                +  if (toolboxAtStart === 'end') {
                +    toolboxAtStart = false;
                +  } else {
                +    toolboxAtStart = true;
                +  }
                +
                +  if (horizontalLayout) {
                +    var toolboxPosition = toolboxAtStart ?
                +        Blockly.TOOLBOX_AT_TOP : Blockly.TOOLBOX_AT_BOTTOM;
                +  } else {
                +    var toolboxPosition = (toolboxAtStart == rtl) ?
                +        Blockly.TOOLBOX_AT_RIGHT : Blockly.TOOLBOX_AT_LEFT;
                +  }
                +
                +  var hasScrollbars = options['scrollbars'];
                +  if (hasScrollbars === undefined) {
                +    hasScrollbars = hasCategories;
                +  }
                +  var hasCss = options['css'];
                +  if (hasCss === undefined) {
                +    hasCss = true;
                +  }
                +  var pathToMedia = 'https://blockly-demo.appspot.com/static/media/';
                +  if (options['media']) {
                +    pathToMedia = options['media'];
                +  } else if (options['path']) {
                +    // 'path' is a deprecated option which has been replaced by 'media'.
                +    pathToMedia = options['path'] + 'media/';
                +  }
                +  if (options['oneBasedIndex'] === undefined) {
                +    var oneBasedIndex = true;
                +  } else {
                +    var oneBasedIndex = !!options['oneBasedIndex'];
                +  }
                +
                +  this.RTL = rtl;
                +  this.oneBasedIndex = oneBasedIndex;
                +  this.collapse = hasCollapse;
                +  this.comments = hasComments;
                +  this.disable = hasDisable;
                +  this.readOnly = readOnly;
                +  this.maxBlocks = options['maxBlocks'] || Infinity;
                +  this.pathToMedia = pathToMedia;
                +  this.hasCategories = hasCategories;
                +  this.hasScrollbars = hasScrollbars;
                +  this.hasTrashcan = hasTrashcan;
                +  this.hasSounds = hasSounds;
                +  this.hasCss = hasCss;
                +  this.horizontalLayout = horizontalLayout;
                +  this.languageTree = languageTree;
                +  this.gridOptions = Blockly.Options.parseGridOptions_(options);
                +  this.zoomOptions = Blockly.Options.parseZoomOptions_(options);
                +  this.toolboxPosition = toolboxPosition;
                +};
                +
                +/**
                + * The parent of the current workspace, or null if there is no parent workspace.
                + * @type {Blockly.Workspace}
                + **/
                +Blockly.Options.prototype.parentWorkspace = null;
                +
                +/**
                + * If set, sets the translation of the workspace to match the scrollbars.
                + */
                +Blockly.Options.prototype.setMetrics = null;
                +
                +/**
                + * Return an object with the metrics required to size the workspace.
                + * @return {Object} Contains size and position metrics, or null.
                + */
                +Blockly.Options.prototype.getMetrics = null;
                +
                +/**
                + * Parse the user-specified zoom options, using reasonable defaults where
                + * behaviour is unspecified.  See zoom documentation:
                + *   https://developers.google.com/blockly/guides/configure/web/zoom
                + * @param {!Object} options Dictionary of options.
                + * @return {!Object} A dictionary of normalized options.
                + * @private
                + */
                +Blockly.Options.parseZoomOptions_ = function(options) {
                +  var zoom = options['zoom'] || {};
                +  var zoomOptions = {};
                +  if (zoom['controls'] === undefined) {
                +    zoomOptions.controls = false;
                +  } else {
                +    zoomOptions.controls = !!zoom['controls'];
                +  }
                +  if (zoom['wheel'] === undefined) {
                +    zoomOptions.wheel = false;
                +  } else {
                +    zoomOptions.wheel = !!zoom['wheel'];
                +  }
                +  if (zoom['startScale'] === undefined) {
                +    zoomOptions.startScale = 1;
                +  } else {
                +    zoomOptions.startScale = parseFloat(zoom['startScale']);
                +  }
                +  if (zoom['maxScale'] === undefined) {
                +    zoomOptions.maxScale = 3;
                +  } else {
                +    zoomOptions.maxScale = parseFloat(zoom['maxScale']);
                +  }
                +  if (zoom['minScale'] === undefined) {
                +    zoomOptions.minScale = 0.3;
                +  } else {
                +    zoomOptions.minScale = parseFloat(zoom['minScale']);
                +  }
                +  if (zoom['scaleSpeed'] === undefined) {
                +    zoomOptions.scaleSpeed = 1.2;
                +  } else {
                +    zoomOptions.scaleSpeed = parseFloat(zoom['scaleSpeed']);
                +  }
                +  return zoomOptions;
                +};
                +
                +/**
                + * Parse the user-specified grid options, using reasonable defaults where
                + * behaviour is unspecified. See grid documentation:
                + *   https://developers.google.com/blockly/guides/configure/web/grid
                + * @param {!Object} options Dictionary of options.
                + * @return {!Object} A dictionary of normalized options.
                + * @private
                + */
                +Blockly.Options.parseGridOptions_ = function(options) {
                +  var grid = options['grid'] || {};
                +  var gridOptions = {};
                +  gridOptions.spacing = parseFloat(grid['spacing']) || 0;
                +  gridOptions.colour = grid['colour'] || '#888';
                +  gridOptions.length = parseFloat(grid['length']) || 1;
                +  gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap'];
                +  return gridOptions;
                +};
                +
                +/**
                + * Parse the provided toolbox tree into a consistent DOM format.
                + * @param {Node|string} tree DOM tree of blocks, or text representation of same.
                + * @return {Node} DOM tree of blocks, or null.
                + */
                +Blockly.Options.parseToolboxTree = function(tree) {
                +  if (tree) {
                +    if (typeof tree != 'string') {
                +      if (typeof XSLTProcessor == 'undefined' && tree.outerHTML) {
                +        // In this case the tree will not have been properly built by the
                +        // browser. The HTML will be contained in the element, but it will
                +        // not have the proper DOM structure since the browser doesn't support
                +        // XSLTProcessor (XML -> HTML). This is the case in IE 9+.
                +        tree = tree.outerHTML;
                +      } else if (!(tree instanceof Element)) {
                +        tree = null;
                +      }
                +    }
                +    if (typeof tree == 'string') {
                +      tree = Blockly.Xml.textToDom(tree);
                +    }
                +  } else {
                +    tree = null;
                +  }
                +  return tree;
                +};
                diff --git a/blockly/webif/static/blockly/core/procedures.js b/blockly/webif/static/blockly/core/procedures.js
                new file mode 100644
                index 000000000..98ebf41b6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/procedures.js
                @@ -0,0 +1,318 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Utility functions for handling procedures.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Procedures
                + * @namespace
                + **/
                +goog.provide('Blockly.Procedures');
                +
                +goog.require('Blockly.Blocks');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.Field');
                +goog.require('Blockly.Names');
                +goog.require('Blockly.Workspace');
                +
                +
                +/**
                + * Constant to separate procedure names from variables and generated functions
                + * when running generators.
                + * @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME
                + */
                +Blockly.Procedures.NAME_TYPE = Blockly.PROCEDURE_CATEGORY_NAME;
                +
                +/**
                + * Find all user-created procedure definitions in a workspace.
                + * @param {!Blockly.Workspace} root Root workspace.
                + * @return {!Array.<!Array.<!Array>>} Pair of arrays, the
                + *     first contains procedures without return variables, the second with.
                + *     Each procedure is defined by a three-element list of name, parameter
                + *     list, and return value boolean.
                + */
                +Blockly.Procedures.allProcedures = function(root) {
                +  var blocks = root.getAllBlocks();
                +  var proceduresReturn = [];
                +  var proceduresNoReturn = [];
                +  for (var i = 0; i < blocks.length; i++) {
                +    if (blocks[i].getProcedureDef) {
                +      var tuple = blocks[i].getProcedureDef();
                +      if (tuple) {
                +        if (tuple[2]) {
                +          proceduresReturn.push(tuple);
                +        } else {
                +          proceduresNoReturn.push(tuple);
                +        }
                +      }
                +    }
                +  }
                +  proceduresNoReturn.sort(Blockly.Procedures.procTupleComparator_);
                +  proceduresReturn.sort(Blockly.Procedures.procTupleComparator_);
                +  return [proceduresNoReturn, proceduresReturn];
                +};
                +
                +/**
                + * Comparison function for case-insensitive sorting of the first element of
                + * a tuple.
                + * @param {!Array} ta First tuple.
                + * @param {!Array} tb Second tuple.
                + * @return {number} -1, 0, or 1 to signify greater than, equality, or less than.
                + * @private
                + */
                +Blockly.Procedures.procTupleComparator_ = function(ta, tb) {
                +  return ta[0].toLowerCase().localeCompare(tb[0].toLowerCase());
                +};
                +
                +/**
                + * Ensure two identically-named procedures don't exist.
                + * @param {string} name Proposed procedure name.
                + * @param {!Blockly.Block} block Block to disambiguate.
                + * @return {string} Non-colliding name.
                + */
                +Blockly.Procedures.findLegalName = function(name, block) {
                +  if (block.isInFlyout) {
                +    // Flyouts can have multiple procedures called 'do something'.
                +    return name;
                +  }
                +  while (!Blockly.Procedures.isLegalName_(name, block.workspace, block)) {
                +    // Collision with another procedure.
                +    var r = name.match(/^(.*?)(\d+)$/);
                +    if (!r) {
                +      name += '2';
                +    } else {
                +      name = r[1] + (parseInt(r[2], 10) + 1);
                +    }
                +  }
                +  return name;
                +};
                +
                +/**
                + * Does this procedure have a legal name?  Illegal names include names of
                + * procedures already defined.
                + * @param {string} name The questionable name.
                + * @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
                + * @param {Blockly.Block=} opt_exclude Optional block to exclude from
                + *     comparisons (one doesn't want to collide with oneself).
                + * @return {boolean} True if the name is legal.
                + * @private
                + */
                +Blockly.Procedures.isLegalName_ = function(name, workspace, opt_exclude) {
                +  return !Blockly.Procedures.isNameUsed(name, workspace, opt_exclude);
                +};
                +
                +/**
                + * Return if the given name is already a procedure name.
                + * @param {string} name The questionable name.
                + * @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
                + * @param {Blockly.Block=} opt_exclude Optional block to exclude from
                + *     comparisons (one doesn't want to collide with oneself).
                + * @return {boolean} True if the name is used, otherwise return false.
                + */
                +Blockly.Procedures.isNameUsed = function(name, workspace, opt_exclude) {
                +  var blocks = workspace.getAllBlocks();
                +  // Iterate through every block and check the name.
                +  for (var i = 0; i < blocks.length; i++) {
                +    if (blocks[i] == opt_exclude) {
                +      continue;
                +    }
                +    if (blocks[i].getProcedureDef) {
                +      var procName = blocks[i].getProcedureDef();
                +      if (Blockly.Names.equals(procName[0], name)) {
                +        return true;
                +      }
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Rename a procedure.  Called by the editable field.
                + * @param {string} name The proposed new name.
                + * @return {string} The accepted name.
                + * @this {Blockly.Field}
                + */
                +Blockly.Procedures.rename = function(name) {
                +  // Strip leading and trailing whitespace.  Beyond this, all names are legal.
                +  name = name.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
                +
                +  // Ensure two identically-named procedures don't exist.
                +  var legalName = Blockly.Procedures.findLegalName(name, this.sourceBlock_);
                +  var oldName = this.text_;
                +  if (oldName != name && oldName != legalName) {
                +    // Rename any callers.
                +    var blocks = this.sourceBlock_.workspace.getAllBlocks();
                +    for (var i = 0; i < blocks.length; i++) {
                +      if (blocks[i].renameProcedure) {
                +        blocks[i].renameProcedure(oldName, legalName);
                +      }
                +    }
                +  }
                +  return legalName;
                +};
                +
                +/**
                + * Construct the blocks required by the flyout for the procedure category.
                + * @param {!Blockly.Workspace} workspace The workspace contianing procedures.
                + * @return {!Array.<!Element>} Array of XML block elements.
                + */
                +Blockly.Procedures.flyoutCategory = function(workspace) {
                +  var xmlList = [];
                +  if (Blockly.Blocks['procedures_defnoreturn']) {
                +    // <block type="procedures_defnoreturn" gap="16">
                +    //     <field name="NAME">do something</field>
                +    // </block>
                +    var block = goog.dom.createDom('block');
                +    block.setAttribute('type', 'procedures_defnoreturn');
                +    block.setAttribute('gap', 16);
                +    var nameField = goog.dom.createDom('field', null,
                +        Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE);
                +    nameField.setAttribute('name', 'NAME');
                +    block.appendChild(nameField);
                +    xmlList.push(block);
                +  }
                +  if (Blockly.Blocks['procedures_defreturn']) {
                +    // <block type="procedures_defreturn" gap="16">
                +    //     <field name="NAME">do something</field>
                +    // </block>
                +    var block = goog.dom.createDom('block');
                +    block.setAttribute('type', 'procedures_defreturn');
                +    block.setAttribute('gap', 16);
                +    var nameField = goog.dom.createDom('field', null,
                +        Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE);
                +    nameField.setAttribute('name', 'NAME');
                +    block.appendChild(nameField);
                +    xmlList.push(block);
                +  }
                +  if (Blockly.Blocks['procedures_ifreturn']) {
                +    // <block type="procedures_ifreturn" gap="16"></block>
                +    var block = goog.dom.createDom('block');
                +    block.setAttribute('type', 'procedures_ifreturn');
                +    block.setAttribute('gap', 16);
                +    xmlList.push(block);
                +  }
                +  if (xmlList.length) {
                +    // Add slightly larger gap between system blocks and user calls.
                +    xmlList[xmlList.length - 1].setAttribute('gap', 24);
                +  }
                +
                +  function populateProcedures(procedureList, templateName) {
                +    for (var i = 0; i < procedureList.length; i++) {
                +      var name = procedureList[i][0];
                +      var args = procedureList[i][1];
                +      // <block type="procedures_callnoreturn" gap="16">
                +      //   <mutation name="do something">
                +      //     <arg name="x"></arg>
                +      //   </mutation>
                +      // </block>
                +      var block = goog.dom.createDom('block');
                +      block.setAttribute('type', templateName);
                +      block.setAttribute('gap', 16);
                +      var mutation = goog.dom.createDom('mutation');
                +      mutation.setAttribute('name', name);
                +      block.appendChild(mutation);
                +      for (var j = 0; j < args.length; j++) {
                +        var arg = goog.dom.createDom('arg');
                +        arg.setAttribute('name', args[j]);
                +        mutation.appendChild(arg);
                +      }
                +      xmlList.push(block);
                +    }
                +  }
                +
                +  var tuple = Blockly.Procedures.allProcedures(workspace);
                +  populateProcedures(tuple[0], 'procedures_callnoreturn');
                +  populateProcedures(tuple[1], 'procedures_callreturn');
                +  return xmlList;
                +};
                +
                +/**
                + * Find all the callers of a named procedure.
                + * @param {string} name Name of procedure.
                + * @param {!Blockly.Workspace} workspace The workspace to find callers in.
                + * @return {!Array.<!Blockly.Block>} Array of caller blocks.
                + */
                +Blockly.Procedures.getCallers = function(name, workspace) {
                +  var callers = [];
                +  var blocks = workspace.getAllBlocks();
                +  // Iterate through every block and check the name.
                +  for (var i = 0; i < blocks.length; i++) {
                +    if (blocks[i].getProcedureCall) {
                +      var procName = blocks[i].getProcedureCall();
                +      // Procedure name may be null if the block is only half-built.
                +      if (procName && Blockly.Names.equals(procName, name)) {
                +        callers.push(blocks[i]);
                +      }
                +    }
                +  }
                +  return callers;
                +};
                +
                +/**
                + * When a procedure definition changes its parameters, find and edit all its
                + * callers.
                + * @param {!Blockly.Block} defBlock Procedure definition block.
                + */
                +Blockly.Procedures.mutateCallers = function(defBlock) {
                +  var oldRecordUndo = Blockly.Events.recordUndo;
                +  var name = defBlock.getProcedureDef()[0];
                +  var xmlElement = defBlock.mutationToDom(true);
                +  var callers = Blockly.Procedures.getCallers(name, defBlock.workspace);
                +  for (var i = 0, caller; caller = callers[i]; i++) {
                +    var oldMutationDom = caller.mutationToDom();
                +    var oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
                +    caller.domToMutation(xmlElement);
                +    var newMutationDom = caller.mutationToDom();
                +    var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
                +    if (oldMutation != newMutation) {
                +      // Fire a mutation on every caller block.  But don't record this as an
                +      // undo action since it is deterministically tied to the procedure's
                +      // definition mutation.
                +      Blockly.Events.recordUndo = false;
                +      Blockly.Events.fire(new Blockly.Events.BlockChange(
                +          caller, 'mutation', null, oldMutation, newMutation));
                +      Blockly.Events.recordUndo = oldRecordUndo;
                +    }
                +  }
                +};
                +
                +/**
                + * Find the definition block for the named procedure.
                + * @param {string} name Name of procedure.
                + * @param {!Blockly.Workspace} workspace The workspace to search.
                + * @return {Blockly.Block} The procedure definition block, or null not found.
                + */
                +Blockly.Procedures.getDefinition = function(name, workspace) {
                +  // Assume that a procedure definition is a top block.
                +  var blocks = workspace.getTopBlocks(false);
                +  for (var i = 0; i < blocks.length; i++) {
                +    if (blocks[i].getProcedureDef) {
                +      var tuple = blocks[i].getProcedureDef();
                +      if (tuple && Blockly.Names.equals(tuple[0], name)) {
                +        return blocks[i];
                +      }
                +    }
                +  }
                +  return null;
                +};
                diff --git a/blockly/webif/static/blockly/core/rendered_connection.js b/blockly/webif/static/blockly/core/rendered_connection.js
                new file mode 100644
                index 000000000..ea3fcc1d5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/rendered_connection.js
                @@ -0,0 +1,420 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Components for creating connections between blocks.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.RenderedConnection');
                +
                +goog.require('Blockly.Connection');
                +
                +
                +/**
                + * Class for a connection between blocks that may be rendered on screen.
                + * @param {!Blockly.Block} source The block establishing this connection.
                + * @param {number} type The type of the connection.
                + * @extends {Blockly.Connection}
                + * @constructor
                + */
                +Blockly.RenderedConnection = function(source, type) {
                +  Blockly.RenderedConnection.superClass_.constructor.call(this, source, type);
                +
                +  /**
                +   * Workspace units, (0, 0) is top left of block.
                +   * @type {!goog.math.Coordinate}
                +   * @private
                +   */
                +  this.offsetInBlock_ = new goog.math.Coordinate(0, 0);
                +};
                +goog.inherits(Blockly.RenderedConnection, Blockly.Connection);
                +
                +/**
                + * Returns the distance between this connection and another connection in
                + * workspace units.
                + * @param {!Blockly.Connection} otherConnection The other connection to measure
                + *     the distance to.
                + * @return {number} The distance between connections, in workspace units.
                + */
                +Blockly.RenderedConnection.prototype.distanceFrom = function(otherConnection) {
                +  var xDiff = this.x_ - otherConnection.x_;
                +  var yDiff = this.y_ - otherConnection.y_;
                +  return Math.sqrt(xDiff * xDiff + yDiff * yDiff);
                +};
                +
                +/**
                + * Move the block(s) belonging to the connection to a point where they don't
                + * visually interfere with the specified connection.
                + * @param {!Blockly.Connection} staticConnection The connection to move away
                + *     from.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.bumpAwayFrom_ = function(staticConnection) {
                +  if (this.sourceBlock_.workspace.isDragging()) {
                +    // Don't move blocks around while the user is doing the same.
                +    return;
                +  }
                +  // Move the root block.
                +  var rootBlock = this.sourceBlock_.getRootBlock();
                +  if (rootBlock.isInFlyout) {
                +    // Don't move blocks around in a flyout.
                +    return;
                +  }
                +  var reverse = false;
                +  if (!rootBlock.isMovable()) {
                +    // Can't bump an uneditable block away.
                +    // Check to see if the other block is movable.
                +    rootBlock = staticConnection.getSourceBlock().getRootBlock();
                +    if (!rootBlock.isMovable()) {
                +      return;
                +    }
                +    // Swap the connections and move the 'static' connection instead.
                +    staticConnection = this;
                +    reverse = true;
                +  }
                +  // Raise it to the top for extra visibility.
                +  var selected = Blockly.selected == rootBlock;
                +  selected || rootBlock.addSelect();
                +  var dx = (staticConnection.x_ + Blockly.SNAP_RADIUS) - this.x_;
                +  var dy = (staticConnection.y_ + Blockly.SNAP_RADIUS) - this.y_;
                +  if (reverse) {
                +    // When reversing a bump due to an uneditable block, bump up.
                +    dy = -dy;
                +  }
                +  if (rootBlock.RTL) {
                +    dx = -dx;
                +  }
                +  rootBlock.moveBy(dx, dy);
                +  selected || rootBlock.removeSelect();
                +};
                +
                +/**
                + * Change the connection's coordinates.
                + * @param {number} x New absolute x coordinate, in workspace coordinates.
                + * @param {number} y New absolute y coordinate, in workspace coordinates.
                + */
                +Blockly.RenderedConnection.prototype.moveTo = function(x, y) {
                +  // Remove it from its old location in the database (if already present)
                +  if (this.inDB_) {
                +    this.db_.removeConnection_(this);
                +  }
                +  this.x_ = x;
                +  this.y_ = y;
                +  // Insert it into its new location in the database.
                +  if (!this.hidden_) {
                +    this.db_.addConnection(this);
                +  }
                +};
                +
                +/**
                + * Change the connection's coordinates.
                + * @param {number} dx Change to x coordinate, in workspace units.
                + * @param {number} dy Change to y coordinate, in workspace units.
                + */
                +Blockly.RenderedConnection.prototype.moveBy = function(dx, dy) {
                +  this.moveTo(this.x_ + dx, this.y_ + dy);
                +};
                +
                +/**
                + * Move this connection to the location given by its offset within the block and
                + * the location of the block's top left corner.
                + * @param {!goog.math.Coordinate} blockTL The location of the top left corner
                + *     of the block, in workspace coordinates.
                + */
                +Blockly.RenderedConnection.prototype.moveToOffset = function(blockTL) {
                +  this.moveTo(blockTL.x + this.offsetInBlock_.x,
                +      blockTL.y + this.offsetInBlock_.y);
                +};
                +
                +/**
                + * Set the offset of this connection relative to the top left of its block.
                + * @param {number} x The new relative x, in workspace units.
                + * @param {number} y The new relative y, in workspace units.
                + */
                +Blockly.RenderedConnection.prototype.setOffsetInBlock = function(x, y) {
                +  this.offsetInBlock_.x = x;
                +  this.offsetInBlock_.y = y;
                +};
                +
                +/**
                + * Move the blocks on either side of this connection right next to each other.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.tighten_ = function() {
                +  var dx = this.targetConnection.x_ - this.x_;
                +  var dy = this.targetConnection.y_ - this.y_;
                +  if (dx != 0 || dy != 0) {
                +    var block = this.targetBlock();
                +    var svgRoot = block.getSvgRoot();
                +    if (!svgRoot) {
                +      throw 'block is not rendered.';
                +    }
                +    // Workspace coordinates.
                +    var xy = Blockly.utils.getRelativeXY(svgRoot);
                +    block.getSvgRoot().setAttribute('transform',
                +        'translate(' + (xy.x - dx) + ',' + (xy.y - dy) + ')');
                +    block.moveConnections_(-dx, -dy);
                +  }
                +};
                +
                +/**
                + * Find the closest compatible connection to this connection.
                + * All parameters are in workspace units.
                + * @param {number} maxLimit The maximum radius to another connection.
                + * @param {number} dx Horizontal offset between this connection's location
                + *     in the database and the current location (as a result of dragging).
                + * @param {number} dy Vertical offset between this connection's location
                + *     in the database and the current location (as a result of dragging).
                + * @return {!{connection: ?Blockly.Connection, radius: number}} Contains two
                + *     properties: 'connection' which is either another connection or null,
                + *     and 'radius' which is the distance.
                + */
                +Blockly.RenderedConnection.prototype.closest = function(maxLimit, dx, dy) {
                +  return this.dbOpposite_.searchForClosest(this, maxLimit, dx, dy);
                +};
                +
                +/**
                + * Add highlighting around this connection.
                + */
                +Blockly.RenderedConnection.prototype.highlight = function() {
                +  var steps;
                +  if (this.type == Blockly.INPUT_VALUE || this.type == Blockly.OUTPUT_VALUE) {
                +    steps = 'm 0,0 ' + Blockly.BlockSvg.TAB_PATH_DOWN + ' v 5';
                +  } else {
                +    steps = 'm -20,0 h 5 ' + Blockly.BlockSvg.NOTCH_PATH_LEFT + ' h 5';
                +  }
                +  var xy = this.sourceBlock_.getRelativeToSurfaceXY();
                +  var x = this.x_ - xy.x;
                +  var y = this.y_ - xy.y;
                +  Blockly.Connection.highlightedPath_ = Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyHighlightedConnectionPath',
                +       'd': steps,
                +       transform: 'translate(' + x + ',' + y + ')' +
                +           (this.sourceBlock_.RTL ? ' scale(-1 1)' : '')},
                +      this.sourceBlock_.getSvgRoot());
                +};
                +
                +/**
                + * Unhide this connection, as well as all down-stream connections on any block
                + * attached to this connection.  This happens when a block is expanded.
                + * Also unhides down-stream comments.
                + * @return {!Array.<!Blockly.Block>} List of blocks to render.
                + */
                +Blockly.RenderedConnection.prototype.unhideAll = function() {
                +  this.setHidden(false);
                +  // All blocks that need unhiding must be unhidden before any rendering takes
                +  // place, since rendering requires knowing the dimensions of lower blocks.
                +  // Also, since rendering a block renders all its parents, we only need to
                +  // render the leaf nodes.
                +  var renderList = [];
                +  if (this.type != Blockly.INPUT_VALUE && this.type != Blockly.NEXT_STATEMENT) {
                +    // Only spider down.
                +    return renderList;
                +  }
                +  var block = this.targetBlock();
                +  if (block) {
                +    var connections;
                +    if (block.isCollapsed()) {
                +      // This block should only be partially revealed since it is collapsed.
                +      connections = [];
                +      block.outputConnection && connections.push(block.outputConnection);
                +      block.nextConnection && connections.push(block.nextConnection);
                +      block.previousConnection && connections.push(block.previousConnection);
                +    } else {
                +      // Show all connections of this block.
                +      connections = block.getConnections_(true);
                +    }
                +    for (var i = 0; i < connections.length; i++) {
                +      renderList.push.apply(renderList, connections[i].unhideAll());
                +    }
                +    if (!renderList.length) {
                +      // Leaf block.
                +      renderList[0] = block;
                +    }
                +  }
                +  return renderList;
                +};
                +
                +/**
                + * Remove the highlighting around this connection.
                + */
                +Blockly.RenderedConnection.prototype.unhighlight = function() {
                +  goog.dom.removeNode(Blockly.Connection.highlightedPath_);
                +  delete Blockly.Connection.highlightedPath_;
                +};
                +
                +/**
                + * Set whether this connections is hidden (not tracked in a database) or not.
                + * @param {boolean} hidden True if connection is hidden.
                + */
                +Blockly.RenderedConnection.prototype.setHidden = function(hidden) {
                +  this.hidden_ = hidden;
                +  if (hidden && this.inDB_) {
                +    this.db_.removeConnection_(this);
                +  } else if (!hidden && !this.inDB_) {
                +    this.db_.addConnection(this);
                +  }
                +};
                +
                +/**
                + * Hide this connection, as well as all down-stream connections on any block
                + * attached to this connection.  This happens when a block is collapsed.
                + * Also hides down-stream comments.
                + */
                +Blockly.RenderedConnection.prototype.hideAll = function() {
                +  this.setHidden(true);
                +  if (this.targetConnection) {
                +    var blocks = this.targetBlock().getDescendants();
                +    for (var i = 0; i < blocks.length; i++) {
                +      var block = blocks[i];
                +      // Hide all connections of all children.
                +      var connections = block.getConnections_(true);
                +      for (var j = 0; j < connections.length; j++) {
                +        connections[j].setHidden(true);
                +      }
                +      // Close all bubbles of all children.
                +      var icons = block.getIcons();
                +      for (var j = 0; j < icons.length; j++) {
                +        icons[j].setVisible(false);
                +      }
                +    }
                +  }
                +};
                +
                +/**
                + * Check if the two connections can be dragged to connect to each other.
                + * @param {!Blockly.Connection} candidate A nearby connection to check.
                + * @param {number} maxRadius The maximum radius allowed for connections, in
                + *     workspace units.
                + * @return {boolean} True if the connection is allowed, false otherwise.
                + */
                +Blockly.RenderedConnection.prototype.isConnectionAllowed = function(candidate,
                +    maxRadius) {
                +  if (this.distanceFrom(candidate) > maxRadius) {
                +    return false;
                +  }
                +
                +  return Blockly.RenderedConnection.superClass_.isConnectionAllowed.call(this,
                +      candidate);
                +};
                +
                +/**
                + * Disconnect two blocks that are connected by this connection.
                + * @param {!Blockly.Block} parentBlock The superior block.
                + * @param {!Blockly.Block} childBlock The inferior block.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.disconnectInternal_ = function(parentBlock,
                +    childBlock) {
                +  Blockly.RenderedConnection.superClass_.disconnectInternal_.call(this,
                +      parentBlock, childBlock);
                +  // Rerender the parent so that it may reflow.
                +  if (parentBlock.rendered) {
                +    parentBlock.render();
                +  }
                +  if (childBlock.rendered) {
                +    childBlock.updateDisabled();
                +    childBlock.render();
                +  }
                +};
                +
                +/**
                + * Respawn the shadow block if there was one connected to the this connection.
                + * Render/rerender blocks as needed.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.respawnShadow_ = function() {
                +  var parentBlock = this.getSourceBlock();
                +  // Respawn the shadow block if there is one.
                +  var shadow = this.getShadowDom();
                +  if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) {
                +    Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);
                +    var blockShadow = this.targetBlock();
                +    if (!blockShadow) {
                +      throw 'Couldn\'t respawn the shadow block that should exist here.';
                +    }
                +    blockShadow.initSvg();
                +    blockShadow.render(false);
                +    if (parentBlock.rendered) {
                +      parentBlock.render();
                +    }
                +  }
                +};
                +
                +/**
                + * Find all nearby compatible connections to this connection.
                + * Type checking does not apply, since this function is used for bumping.
                + * @param {number} maxLimit The maximum radius to another connection, in
                + *     workspace units.
                + * @return {!Array.<!Blockly.Connection>} List of connections.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.neighbours_ = function(maxLimit) {
                +  return this.dbOpposite_.getNeighbours(this, maxLimit);
                +};
                +
                +/**
                + * Connect two connections together.  This is the connection on the superior
                + * block.  Rerender blocks as needed.
                + * @param {!Blockly.Connection} childConnection Connection on inferior block.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.connect_ = function(childConnection) {
                +  Blockly.RenderedConnection.superClass_.connect_.call(this, childConnection);
                +
                +  var parentConnection = this;
                +  var parentBlock = parentConnection.getSourceBlock();
                +  var childBlock = childConnection.getSourceBlock();
                +
                +  if (parentBlock.rendered) {
                +    parentBlock.updateDisabled();
                +  }
                +  if (childBlock.rendered) {
                +    childBlock.updateDisabled();
                +  }
                +  if (parentBlock.rendered && childBlock.rendered) {
                +    if (parentConnection.type == Blockly.NEXT_STATEMENT ||
                +        parentConnection.type == Blockly.PREVIOUS_STATEMENT) {
                +      // Child block may need to square off its corners if it is in a stack.
                +      // Rendering a child will render its parent.
                +      childBlock.render();
                +    } else {
                +      // Child block does not change shape.  Rendering the parent node will
                +      // move its connected children into position.
                +      parentBlock.render();
                +    }
                +  }
                +};
                +
                +/**
                + * Function to be called when this connection's compatible types have changed.
                + * @private
                + */
                +Blockly.RenderedConnection.prototype.onCheckChanged_ = function() {
                +  // The new value type may not be compatible with the existing connection.
                +  if (this.isConnected() && !this.checkType_(this.targetConnection)) {
                +    var child = this.isSuperior() ? this.targetBlock() : this.sourceBlock_;
                +    child.unplug();
                +    // Bump away.
                +    this.sourceBlock_.bumpNeighbours_();
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/scrollbar.js b/blockly/webif/static/blockly/core/scrollbar.js
                new file mode 100644
                index 000000000..c4e63bfbb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/scrollbar.js
                @@ -0,0 +1,833 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Library for creating scrollbars.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Scrollbar');
                +goog.provide('Blockly.ScrollbarPair');
                +
                +goog.require('goog.dom');
                +goog.require('goog.events');
                +
                +
                +/**
                + * Class for a pair of scrollbars.  Horizontal and vertical.
                + * @param {!Blockly.Workspace} workspace Workspace to bind the scrollbars to.
                + * @constructor
                + */
                +Blockly.ScrollbarPair = function(workspace) {
                +  this.workspace_ = workspace;
                +  this.hScroll = new Blockly.Scrollbar(workspace, true, true,
                +    'blocklyMainWorkspaceScrollbar');
                +  this.vScroll = new Blockly.Scrollbar(workspace, false, true,
                +    'blocklyMainWorkspaceScrollbar');
                +  this.corner_ = Blockly.utils.createSvgElement('rect',
                +      {'height': Blockly.Scrollbar.scrollbarThickness,
                +      'width': Blockly.Scrollbar.scrollbarThickness,
                +      'class': 'blocklyScrollbarBackground'}, null);
                +  Blockly.utils.insertAfter_(this.corner_, workspace.getBubbleCanvas());
                +};
                +
                +/**
                + * Previously recorded metrics from the workspace.
                + * @type {Object}
                + * @private
                + */
                +Blockly.ScrollbarPair.prototype.oldHostMetrics_ = null;
                +
                +/**
                + * Dispose of this pair of scrollbars.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.ScrollbarPair.prototype.dispose = function() {
                +  goog.dom.removeNode(this.corner_);
                +  this.corner_ = null;
                +  this.workspace_ = null;
                +  this.oldHostMetrics_ = null;
                +  this.hScroll.dispose();
                +  this.hScroll = null;
                +  this.vScroll.dispose();
                +  this.vScroll = null;
                +};
                +
                +/**
                + * Recalculate both of the scrollbars' locations and lengths.
                + * Also reposition the corner rectangle.
                + */
                +Blockly.ScrollbarPair.prototype.resize = function() {
                +  // Look up the host metrics once, and use for both scrollbars.
                +  var hostMetrics = this.workspace_.getMetrics();
                +  if (!hostMetrics) {
                +    // Host element is likely not visible.
                +    return;
                +  }
                +
                +  // Only change the scrollbars if there has been a change in metrics.
                +  var resizeH = false;
                +  var resizeV = false;
                +  if (!this.oldHostMetrics_ ||
                +      this.oldHostMetrics_.viewWidth != hostMetrics.viewWidth ||
                +      this.oldHostMetrics_.viewHeight != hostMetrics.viewHeight ||
                +      this.oldHostMetrics_.absoluteTop != hostMetrics.absoluteTop ||
                +      this.oldHostMetrics_.absoluteLeft != hostMetrics.absoluteLeft) {
                +    // The window has been resized or repositioned.
                +    resizeH = true;
                +    resizeV = true;
                +  } else {
                +    // Has the content been resized or moved?
                +    if (!this.oldHostMetrics_ ||
                +        this.oldHostMetrics_.contentWidth != hostMetrics.contentWidth ||
                +        this.oldHostMetrics_.viewLeft != hostMetrics.viewLeft ||
                +        this.oldHostMetrics_.contentLeft != hostMetrics.contentLeft) {
                +      resizeH = true;
                +    }
                +    if (!this.oldHostMetrics_ ||
                +        this.oldHostMetrics_.contentHeight != hostMetrics.contentHeight ||
                +        this.oldHostMetrics_.viewTop != hostMetrics.viewTop ||
                +        this.oldHostMetrics_.contentTop != hostMetrics.contentTop) {
                +      resizeV = true;
                +    }
                +  }
                +  if (resizeH) {
                +    this.hScroll.resize(hostMetrics);
                +  }
                +  if (resizeV) {
                +    this.vScroll.resize(hostMetrics);
                +  }
                +
                +  // Reposition the corner square.
                +  if (!this.oldHostMetrics_ ||
                +      this.oldHostMetrics_.viewWidth != hostMetrics.viewWidth ||
                +      this.oldHostMetrics_.absoluteLeft != hostMetrics.absoluteLeft) {
                +    this.corner_.setAttribute('x', this.vScroll.position_.x);
                +  }
                +  if (!this.oldHostMetrics_ ||
                +      this.oldHostMetrics_.viewHeight != hostMetrics.viewHeight ||
                +      this.oldHostMetrics_.absoluteTop != hostMetrics.absoluteTop) {
                +    this.corner_.setAttribute('y', this.hScroll.position_.y);
                +  }
                +
                +  // Cache the current metrics to potentially short-cut the next resize event.
                +  this.oldHostMetrics_ = hostMetrics;
                +};
                +
                +/**
                + * Set the sliders of both scrollbars to be at a certain position.
                + * @param {number} x Horizontal scroll value.
                + * @param {number} y Vertical scroll value.
                + */
                +Blockly.ScrollbarPair.prototype.set = function(x, y) {
                +  // This function is equivalent to:
                +  //   this.hScroll.set(x);
                +  //   this.vScroll.set(y);
                +  // However, that calls setMetrics twice which causes a chain of
                +  // getAttribute->setAttribute->getAttribute resulting in an extra layout pass.
                +  // Combining them speeds up rendering.
                +  var xyRatio = {};
                +
                +  var hHandlePosition = x * this.hScroll.ratio_;
                +  var vHandlePosition = y * this.vScroll.ratio_;
                +
                +  var hBarLength = this.hScroll.scrollViewSize_;
                +  var vBarLength = this.vScroll.scrollViewSize_;
                +
                +  xyRatio.x = this.getRatio_(hHandlePosition, hBarLength);
                +  xyRatio.y = this.getRatio_(vHandlePosition, vBarLength);
                +  this.workspace_.setMetrics(xyRatio);
                +
                +  this.hScroll.setHandlePosition(hHandlePosition);
                +  this.vScroll.setHandlePosition(vHandlePosition);
                +};
                +
                +/**
                + * Helper to calculate the ratio of handle position to scrollbar view size.
                + * @param {number} handlePosition The value of the handle.
                + * @param {number} viewSize The total size of the scrollbar's view.
                + * @return {number} Ratio.
                + * @private
                + */
                +Blockly.ScrollbarPair.prototype.getRatio_ = function(handlePosition, viewSize) {
                +  var ratio = handlePosition / viewSize;
                +  if (isNaN(ratio)) {
                +    return 0;
                +  }
                +  return ratio;
                +};
                +
                +// --------------------------------------------------------------------
                +
                +/**
                + * Class for a pure SVG scrollbar.
                + * This technique offers a scrollbar that is guaranteed to work, but may not
                + * look or behave like the system's scrollbars.
                + * @param {!Blockly.Workspace} workspace Workspace to bind the scrollbar to.
                + * @param {boolean} horizontal True if horizontal, false if vertical.
                + * @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair.
                + * @param {string} opt_class A class to be applied to this scrollbar.
                + * @constructor
                + */
                +Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
                +  this.workspace_ = workspace;
                +  this.pair_ = opt_pair || false;
                +  this.horizontal_ = horizontal;
                +  this.oldHostMetrics_ = null;
                +
                +  this.createDom_(opt_class);
                +
                +  /**
                +   * The upper left corner of the scrollbar's svg group.
                +   * @type {goog.math.Coordinate}
                +   * @private
                +   */
                +  this.position_ = new goog.math.Coordinate(0, 0);
                +
                +  if (horizontal) {
                +    this.svgBackground_.setAttribute('height',
                +        Blockly.Scrollbar.scrollbarThickness);
                +    this.outerSvg_.setAttribute('height',
                +          Blockly.Scrollbar.scrollbarThickness);
                +    this.svgHandle_.setAttribute('height',
                +        Blockly.Scrollbar.scrollbarThickness - 5);
                +    this.svgHandle_.setAttribute('y', 2.5);
                +
                +    this.lengthAttribute_ = 'width';
                +    this.positionAttribute_ = 'x';
                +  } else {
                +    this.svgBackground_.setAttribute('width',
                +        Blockly.Scrollbar.scrollbarThickness);
                +    this.outerSvg_.setAttribute('width',
                +       Blockly.Scrollbar.scrollbarThickness);
                +    this.svgHandle_.setAttribute('width',
                +        Blockly.Scrollbar.scrollbarThickness - 5);
                +    this.svgHandle_.setAttribute('x', 2.5);
                +
                +    this.lengthAttribute_ = 'height';
                +    this.positionAttribute_ = 'y';
                +  }
                +  var scrollbar = this;
                +  this.onMouseDownBarWrapper_ = Blockly.bindEventWithChecks_(
                +      this.svgBackground_, 'mousedown', scrollbar, scrollbar.onMouseDownBar_);
                +  this.onMouseDownHandleWrapper_ = Blockly.bindEventWithChecks_(this.svgHandle_,
                +      'mousedown', scrollbar, scrollbar.onMouseDownHandle_);
                +};
                +/**
                +   * The coordinate of the upper left corner of the scrollbar SVG.
                +   * @type {goog.math.Coordinate}
                +   * @private
                +   */
                +Blockly.Scrollbar.prototype.origin_ = new goog.math.Coordinate(0, 0);
                +
                +/**
                + * The size of the area within which the scrollbar handle can move.
                + * Coordinate system: pixel coordinates.
                + * @type {number}
                + * @private
                + */
                +Blockly.Scrollbar.prototype.scrollViewSize_ = 0;
                +
                +/**
                + * The length of the scrollbar handle.
                + * Coordinate system: pixel coordinates.
                + * @type {number}
                + * @private
                + */
                +Blockly.Scrollbar.prototype.handleLength_ = 0;
                +
                +/**
                + * The offset of the start of the handle from the start of the scrollbar range.
                + * Coordinate system: pixel coordinates.
                + * @type {number}
                + * @private
                + */
                +Blockly.Scrollbar.prototype.handlePosition_ = 0;
                +
                +/**
                + * Whether the scrollbar handle is visible.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Scrollbar.prototype.isVisible_ = true;
                +
                +/**
                + * Whether the workspace containing this scrollbar is visible.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Scrollbar.prototype.containerVisible_ = true;
                +
                +/**
                + * Width of vertical scrollbar or height of horizontal scrollbar.
                + * Increase the size of scrollbars on touch devices.
                + */
                +Blockly.Scrollbar.scrollbarThickness = 15;
                +if (goog.events.BrowserFeature.TOUCH_ENABLED) {
                +  Blockly.Scrollbar.scrollbarThickness = 25;
                +}
                +
                +/**
                + * @param {!Object} first An object containing computed measurements of a
                + *    workspace.
                + * @param {!Object} second Another object containing computed measurements of a
                + *    workspace.
                + * @return {boolean} Whether the two sets of metrics are equivalent.
                + * @private
                + */
                +Blockly.Scrollbar.metricsAreEquivalent_ = function(first, second) {
                +  if (!(first && second)) {
                +    return false;
                +  }
                +
                +  if (first.viewWidth != second.viewWidth ||
                +      first.viewHeight != second.viewHeight ||
                +      first.viewLeft != second.viewLeft ||
                +      first.viewTop != second.viewTop ||
                +      first.absoluteTop != second.absoluteTop ||
                +      first.absoluteLeft != second.absoluteLeft ||
                +      first.contentWidth != second.contentWidth ||
                +      first.contentHeight != second.contentHeight ||
                +      first.contentLeft != second.contentLeft ||
                +      first.contentTop != second.contentTop) {
                +    return false;
                +  }
                +
                +  return true;
                +};
                +
                +/**
                + * Dispose of this scrollbar.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.Scrollbar.prototype.dispose = function() {
                +  this.cleanUp_();
                +  Blockly.unbindEvent_(this.onMouseDownBarWrapper_);
                +  this.onMouseDownBarWrapper_ = null;
                +  Blockly.unbindEvent_(this.onMouseDownHandleWrapper_);
                +  this.onMouseDownHandleWrapper_ = null;
                +
                +  goog.dom.removeNode(this.outerSvg_);
                +  this.outerSvg_ = null;
                +  this.svgGroup_ = null;
                +  this.svgBackground_ = null;
                +  this.svgHandle_ = null;
                +  this.workspace_ = null;
                +};
                +
                +/**
                + * Set the length of the scrollbar's handle and change the SVG attribute
                + * accordingly.
                + * @param {number} newLength The new scrollbar handle length.
                + */
                +Blockly.Scrollbar.prototype.setHandleLength_ = function(newLength) {
                +  this.handleLength_ = newLength;
                +  this.svgHandle_.setAttribute(this.lengthAttribute_, this.handleLength_);
                +};
                +
                +/**
                + * Set the offset of the scrollbar's handle and change the SVG attribute
                + * accordingly.
                + * @param {number} newPosition The new scrollbar handle offset.
                + */
                +Blockly.Scrollbar.prototype.setHandlePosition = function(newPosition) {
                +  this.handlePosition_ = newPosition;
                +  this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
                +};
                +
                +/**
                + * Set the size of the scrollbar's background and change the SVG attribute
                + * accordingly.
                + * @param {number} newSize The new scrollbar background length.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.setScrollViewSize_ = function(newSize) {
                +  this.scrollViewSize_ = newSize;
                +  this.outerSvg_.setAttribute(this.lengthAttribute_, this.scrollViewSize_);
                +  this.svgBackground_.setAttribute(this.lengthAttribute_, this.scrollViewSize_);
                +};
                +
                +/**
                + * Set whether this scrollbar's container is visible.
                + * @param {boolean} visible Whether the container is visible.
                + */
                +Blockly.ScrollbarPair.prototype.setContainerVisible = function(visible) {
                +  this.hScroll.setContainerVisible(visible);
                +  this.vScroll.setContainerVisible(visible);
                +};
                +
                +/**
                + * Set the position of the scrollbar's svg group.
                + * @param {number} x The new x coordinate.
                + * @param {number} y The new y coordinate.
                + */
                +Blockly.Scrollbar.prototype.setPosition = function(x, y) {
                +  this.position_.x = x;
                +  this.position_.y = y;
                +
                +  var tempX = this.position_.x + this.origin_.x;
                +  var tempY = this.position_.y + this.origin_.y;
                +  var transform = 'translate(' + tempX + 'px,' + tempY + 'px)';
                +  Blockly.utils.setCssTransform(this.outerSvg_, transform);
                +};
                +
                +/**
                + * Recalculate the scrollbar's location and its length.
                + * @param {Object=} opt_metrics A data structure of from the describing all the
                + * required dimensions.  If not provided, it will be fetched from the host
                + * object.
                + */
                +Blockly.Scrollbar.prototype.resize = function(opt_metrics) {
                +  // Determine the location, height and width of the host element.
                +  var hostMetrics = opt_metrics;
                +  if (!hostMetrics) {
                +    hostMetrics = this.workspace_.getMetrics();
                +    if (!hostMetrics) {
                +      // Host element is likely not visible.
                +      return;
                +    }
                +  }
                +
                +  if (Blockly.Scrollbar.metricsAreEquivalent_(hostMetrics,
                +      this.oldHostMetrics_)) {
                +    return;
                +  }
                +  this.oldHostMetrics_ = hostMetrics;
                +
                +  /* hostMetrics is an object with the following properties.
                +   * .viewHeight: Height of the visible rectangle,
                +   * .viewWidth: Width of the visible rectangle,
                +   * .contentHeight: Height of the contents,
                +   * .contentWidth: Width of the content,
                +   * .viewTop: Offset of top edge of visible rectangle from parent,
                +   * .viewLeft: Offset of left edge of visible rectangle from parent,
                +   * .contentTop: Offset of the top-most content from the y=0 coordinate,
                +   * .contentLeft: Offset of the left-most content from the x=0 coordinate,
                +   * .absoluteTop: Top-edge of view.
                +   * .absoluteLeft: Left-edge of view.
                +   */
                +  if (this.horizontal_) {
                +    this.resizeHorizontal_(hostMetrics);
                +  } else {
                +    this.resizeVertical_(hostMetrics);
                +  }
                +  // Resizing may have caused some scrolling.
                +  this.onScroll_();
                +};
                +
                +/**
                + * Recalculate a horizontal scrollbar's location and length.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.resizeHorizontal_ = function(hostMetrics) {
                +  // TODO: Inspect metrics to determine if we can get away with just a content
                +  // resize.
                +  this.resizeViewHorizontal(hostMetrics);
                +};
                +
                +/**
                + * Recalculate a horizontal scrollbar's location on the screen and path length.
                + * This should be called when the layout or size of the window has changed.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + */
                +Blockly.Scrollbar.prototype.resizeViewHorizontal = function(hostMetrics) {
                +  var viewSize = hostMetrics.viewWidth - 1;
                +  if (this.pair_) {
                +    // Shorten the scrollbar to make room for the corner square.
                +    viewSize -= Blockly.Scrollbar.scrollbarThickness;
                +  }
                +  this.setScrollViewSize_(Math.max(0, viewSize));
                +
                +  var xCoordinate = hostMetrics.absoluteLeft + 0.5;
                +  if (this.pair_ && this.workspace_.RTL) {
                +    xCoordinate += Blockly.Scrollbar.scrollbarThickness;
                +  }
                +
                +  // Horizontal toolbar should always be just above the bottom of the workspace.
                +  var yCoordinate = hostMetrics.absoluteTop + hostMetrics.viewHeight -
                +      Blockly.Scrollbar.scrollbarThickness - 0.5;
                +  this.setPosition(xCoordinate, yCoordinate);
                +
                +  // If the view has been resized, a content resize will also be necessary.  The
                +  // reverse is not true.
                +  this.resizeContentHorizontal(hostMetrics);
                +};
                +
                +/**
                + * Recalculate a horizontal scrollbar's location within its path and length.
                + * This should be called when the contents of the workspace have changed.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + */
                +Blockly.Scrollbar.prototype.resizeContentHorizontal = function(hostMetrics) {
                +  if (!this.pair_) {
                +    // Only show the scrollbar if needed.
                +    // Ideally this would also apply to scrollbar pairs, but that's a bigger
                +    // headache (due to interactions with the corner square).
                +    this.setVisible(this.scrollViewSize_ < hostMetrics.contentWidth);
                +  }
                +
                +  this.ratio_ = this.scrollViewSize_ / hostMetrics.contentWidth;
                +  if (this.ratio_ == -Infinity || this.ratio_ == Infinity ||
                +      isNaN(this.ratio_)) {
                +    this.ratio_ = 0;
                +  }
                +
                +  var handleLength = hostMetrics.viewWidth * this.ratio_;
                +  this.setHandleLength_(Math.max(0, handleLength));
                +
                +  var handlePosition = (hostMetrics.viewLeft - hostMetrics.contentLeft) *
                +      this.ratio_;
                +  this.setHandlePosition(this.constrainHandle_(handlePosition));
                +};
                +
                +/**
                + * Recalculate a vertical scrollbar's location and length.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.resizeVertical_ = function(hostMetrics) {
                +  // TODO: Inspect metrics to determine if we can get away with just a content
                +  // resize.
                +  this.resizeViewVertical(hostMetrics);
                +};
                +
                +/**
                + * Recalculate a vertical scrollbar's location on the screen and path length.
                + * This should be called when the layout or size of the window has changed.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + */
                +Blockly.Scrollbar.prototype.resizeViewVertical = function(hostMetrics) {
                +  var viewSize = hostMetrics.viewHeight - 1;
                +  if (this.pair_) {
                +    // Shorten the scrollbar to make room for the corner square.
                +    viewSize -= Blockly.Scrollbar.scrollbarThickness;
                +  }
                +  this.setScrollViewSize_(Math.max(0, viewSize));
                +
                +  var xCoordinate = hostMetrics.absoluteLeft + 0.5;
                +  if (!this.workspace_.RTL) {
                +    xCoordinate += hostMetrics.viewWidth -
                +        Blockly.Scrollbar.scrollbarThickness - 1;
                +  }
                +  var yCoordinate = hostMetrics.absoluteTop + 0.5;
                +  this.setPosition(xCoordinate, yCoordinate);
                +
                +  // If the view has been resized, a content resize will also be necessary.  The
                +  // reverse is not true.
                +  this.resizeContentVertical(hostMetrics);
                +};
                +
                +/**
                + * Recalculate a vertical scrollbar's location within its path and length.
                + * This should be called when the contents of the workspace have changed.
                + * @param {!Object} hostMetrics A data structure describing all the
                + *     required dimensions, possibly fetched from the host object.
                + */
                +Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) {
                +  if (!this.pair_) {
                +    // Only show the scrollbar if needed.
                +    this.setVisible(this.scrollViewSize_ < hostMetrics.contentHeight);
                +  }
                +
                +  this.ratio_ = this.scrollViewSize_ / hostMetrics.contentHeight;
                +  if (this.ratio_ == -Infinity || this.ratio_ == Infinity ||
                +      isNaN(this.ratio_)) {
                +    this.ratio_ = 0;
                +  }
                +
                +  var handleLength = hostMetrics.viewHeight * this.ratio_;
                +  this.setHandleLength_(Math.max(0, handleLength));
                +
                +  var handlePosition = (hostMetrics.viewTop - hostMetrics.contentTop) *
                +      this.ratio_;
                +  this.setHandlePosition(this.constrainHandle_(handlePosition));
                +};
                +
                +/**
                + * Create all the DOM elements required for a scrollbar.
                + * The resulting widget is not sized.
                + * @param {string} opt_class A class to be applied to this scrollbar.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.createDom_ = function(opt_class) {
                +  /* Create the following DOM:
                +  <svg class="blocklyScrollbarHorizontal  optionalClass">
                +    <g>
                +      <rect class="blocklyScrollbarBackground" />
                +      <rect class="blocklyScrollbarHandle" rx="8" ry="8" />
                +    </g>
                +  </svg>
                +  */
                +  var className = 'blocklyScrollbar' +
                +      (this.horizontal_ ? 'Horizontal' : 'Vertical');
                +  if (opt_class) {
                +    className += ' ' + opt_class;
                +  }
                +  this.outerSvg_ = Blockly.utils.createSvgElement('svg', {'class': className},
                +                                                  null);
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, this.outerSvg_);
                +  this.svgBackground_ = Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyScrollbarBackground'}, this.svgGroup_);
                +  var radius = Math.floor((Blockly.Scrollbar.scrollbarThickness - 5) / 2);
                +  this.svgHandle_ = Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyScrollbarHandle', 'rx': radius, 'ry': radius},
                +      this.svgGroup_);
                +  Blockly.utils.insertAfter_(this.outerSvg_,
                +                                 this.workspace_.getParentSvg());
                +};
                +
                +/**
                + * Is the scrollbar visible.  Non-paired scrollbars disappear when they aren't
                + * needed.
                + * @return {boolean} True if visible.
                + */
                +Blockly.Scrollbar.prototype.isVisible = function() {
                +  return this.isVisible_;
                +};
                +
                +/**
                + * Set whether the scrollbar's container is visible and update
                + * display accordingly if visibility has changed.
                + * @param {boolean} visible Whether the container is visible
                + */
                +Blockly.Scrollbar.prototype.setContainerVisible = function(visible) {
                +  var visibilityChanged = (visible != this.containerVisible_);
                +
                +  this.containerVisible_ = visible;
                +  if (visibilityChanged) {
                +    this.updateDisplay_();
                +  }
                +};
                +
                +/**
                + * Set whether the scrollbar is visible.
                + * Only applies to non-paired scrollbars.
                + * @param {boolean} visible True if visible.
                + */
                +Blockly.Scrollbar.prototype.setVisible = function(visible) {
                +  var visibilityChanged = (visible != this.isVisible());
                +
                +  // Ideally this would also apply to scrollbar pairs, but that's a bigger
                +  // headache (due to interactions with the corner square).
                +  if (this.pair_) {
                +    throw 'Unable to toggle visibility of paired scrollbars.';
                +  }
                +  this.isVisible_ = visible;
                +  if (visibilityChanged) {
                +    this.updateDisplay_();
                +  }
                +};
                +
                +/**
                + * Update visibility of scrollbar based on whether it thinks it should
                + * be visible and whether its containing workspace is visible.
                + * We cannot rely on the containing workspace being hidden to hide us
                + * because it is not necessarily our parent in the dom.
                + */
                +Blockly.Scrollbar.prototype.updateDisplay_ = function() {
                +  var show = true;
                +  // Check whether our parent/container is visible.
                +  if (!this.containerVisible_) {
                +    show = false;
                +  } else {
                +    show = this.isVisible();
                +  }
                +  if (show) {
                +    this.outerSvg_.setAttribute('display', 'block');
                +  } else {
                +    this.outerSvg_.setAttribute('display', 'none');
                +  }
                +};
                +
                +/**
                + * Scroll by one pageful.
                + * Called when scrollbar background is clicked.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.onMouseDownBar_ = function(e) {
                +  this.workspace_.markFocused();
                +  Blockly.Touch.clearTouchIdentifier();  // This is really a click.
                +  this.cleanUp_();
                +  if (Blockly.utils.isRightButton(e)) {
                +    // Right-click.
                +    // Scrollbars have no context menu.
                +    e.stopPropagation();
                +    return;
                +  }
                +  var mouseXY = Blockly.utils.mouseToSvg(e, this.workspace_.getParentSvg(),
                +      this.workspace_.getInverseScreenCTM());
                +  var mouseLocation = this.horizontal_ ? mouseXY.x : mouseXY.y;
                +
                +  var handleXY = Blockly.utils.getInjectionDivXY_(this.svgHandle_);
                +  var handleStart = this.horizontal_ ? handleXY.x : handleXY.y;
                +  var handlePosition = this.handlePosition_;
                +
                +  var pageLength = this.handleLength_ * 0.95;
                +  if (mouseLocation <= handleStart) {
                +    // Decrease the scrollbar's value by a page.
                +    handlePosition -= pageLength;
                +  } else if (mouseLocation >= handleStart + this.handleLength_) {
                +    // Increase the scrollbar's value by a page.
                +    handlePosition += pageLength;
                +  }
                +
                +  this.setHandlePosition(this.constrainHandle_(handlePosition));
                +
                +  this.onScroll_();
                +  e.stopPropagation();
                +  e.preventDefault();
                +};
                +
                +/**
                + * Start a dragging operation.
                + * Called when scrollbar handle is clicked.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.onMouseDownHandle_ = function(e) {
                +  this.workspace_.markFocused();
                +  this.cleanUp_();
                +  if (Blockly.utils.isRightButton(e)) {
                +    // Right-click.
                +    // Scrollbars have no context menu.
                +    e.stopPropagation();
                +    return;
                +  }
                +  // Look up the current translation and record it.
                +  this.startDragHandle = this.handlePosition_;
                +
                +  // Tell the workspace to setup its drag surface since it is about to move.
                +  // onMouseMoveHandle will call onScroll which actually tells the workspace
                +  // to move.
                +  this.workspace_.setupDragSurface();
                +
                +  // Record the current mouse position.
                +  this.startDragMouse = this.horizontal_ ? e.clientX : e.clientY;
                +  Blockly.Scrollbar.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mouseup', this, this.onMouseUpHandle_);
                +  Blockly.Scrollbar.onMouseMoveWrapper_ = Blockly.bindEventWithChecks_(document,
                +      'mousemove', this, this.onMouseMoveHandle_);
                +  e.stopPropagation();
                +  e.preventDefault();
                +};
                +
                +/**
                + * Drag the scrollbar's handle.
                + * @param {!Event} e Mouse up event.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.onMouseMoveHandle_ = function(e) {
                +  var currentMouse = this.horizontal_ ? e.clientX : e.clientY;
                +  var mouseDelta = currentMouse - this.startDragMouse;
                +  var handlePosition = this.startDragHandle + mouseDelta;
                +  // Position the bar.
                +  this.setHandlePosition(this.constrainHandle_(handlePosition));
                +  this.onScroll_();
                +};
                +
                +/**
                + * Release the scrollbar handle and reset state accordingly.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.onMouseUpHandle_ = function() {
                +  // Tell the workspace to clean up now that the workspace is done moving.
                +  this.workspace_.resetDragSurface();
                +  Blockly.Touch.clearTouchIdentifier();
                +  this.cleanUp_();
                +};
                +
                +/**
                + * Hide chaff and stop binding to mouseup and mousemove events.  Call this to
                + * wrap up lose ends associated with the scrollbar.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.cleanUp_ = function() {
                +  Blockly.hideChaff(true);
                +  if (Blockly.Scrollbar.onMouseUpWrapper_) {
                +    Blockly.unbindEvent_(Blockly.Scrollbar.onMouseUpWrapper_);
                +    Blockly.Scrollbar.onMouseUpWrapper_ = null;
                +  }
                +  if (Blockly.Scrollbar.onMouseMoveWrapper_) {
                +    Blockly.unbindEvent_(Blockly.Scrollbar.onMouseMoveWrapper_);
                +    Blockly.Scrollbar.onMouseMoveWrapper_ = null;
                +  }
                +};
                +
                +/**
                + * Constrain the handle's position within the minimum (0) and maximum
                + * (length of scrollbar) values allowed for the scrollbar.
                + * @param {number} value Value that is potentially out of bounds.
                + * @return {number} Constrained value.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.constrainHandle_ = function(value) {
                +  if (value <= 0 || isNaN(value) || this.scrollViewSize_ < this.handleLength_) {
                +    value = 0;
                +  } else {
                +    value = Math.min(value, this.scrollViewSize_ - this.handleLength_);
                +  }
                +  return value;
                +};
                +
                +/**
                + * Called when scrollbar is moved.
                + * @private
                + */
                +Blockly.Scrollbar.prototype.onScroll_ = function() {
                +  var ratio = this.handlePosition_ / this.scrollViewSize_;
                +  if (isNaN(ratio)) {
                +    ratio = 0;
                +  }
                +  var xyRatio = {};
                +  if (this.horizontal_) {
                +    xyRatio.x = ratio;
                +  } else {
                +    xyRatio.y = ratio;
                +  }
                +  this.workspace_.setMetrics(xyRatio);
                +};
                +
                +/**
                + * Set the scrollbar slider's position.
                + * @param {number} value The distance from the top/left end of the bar.
                + */
                +Blockly.Scrollbar.prototype.set = function(value) {
                +  this.setHandlePosition(this.constrainHandle_(value * this.ratio_));
                +  this.onScroll_();
                +};
                +
                +/**
                + * Set the origin of the upper left of the scrollbar. This if for times
                + * when the scrollbar is used in an object whose origin isn't the same
                + * as the main workspace (e.g. in a flyout.)
                + * @param {number} x The x coordinate of the scrollbar's origin.
                + * @param {number} y The y coordinate of the scrollbar's origin.
                + */
                +Blockly.Scrollbar.prototype.setOrigin = function(x, y) {
                +  this.origin_ = new goog.math.Coordinate(x, y);
                +};
                diff --git a/blockly/webif/static/blockly/core/toolbox.js b/blockly/webif/static/blockly/core/toolbox.js
                new file mode 100644
                index 000000000..6d72c154f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/toolbox.js
                @@ -0,0 +1,691 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Toolbox from whence to create blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Toolbox');
                +
                +goog.require('Blockly.Flyout');
                +goog.require('Blockly.HorizontalFlyout');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.VerticalFlyout');
                +goog.require('goog.dom');
                +goog.require('goog.dom.TagName');
                +goog.require('goog.events');
                +goog.require('goog.events.BrowserFeature');
                +goog.require('goog.html.SafeHtml');
                +goog.require('goog.html.SafeStyle');
                +goog.require('goog.math.Rect');
                +goog.require('goog.style');
                +goog.require('goog.ui.tree.TreeControl');
                +goog.require('goog.ui.tree.TreeNode');
                +
                +
                +/**
                + * Class for a Toolbox.
                + * Creates the toolbox's DOM.
                + * @param {!Blockly.Workspace} workspace The workspace in which to create new
                + *     blocks.
                + * @constructor
                + */
                +Blockly.Toolbox = function(workspace) {
                +  /**
                +   * @type {!Blockly.Workspace}
                +   * @private
                +   */
                +  this.workspace_ = workspace;
                +
                +  /**
                +   * Is RTL vs LTR.
                +   * @type {boolean}
                +   */
                +  this.RTL = workspace.options.RTL;
                +
                +  /**
                +   * Whether the toolbox should be laid out horizontally.
                +   * @type {boolean}
                +   * @private
                +   */
                +  this.horizontalLayout_ = workspace.options.horizontalLayout;
                +
                +  /**
                +   * Position of the toolbox and flyout relative to the workspace.
                +   * @type {number}
                +   */
                +  this.toolboxPosition = workspace.options.toolboxPosition;
                +
                +  /**
                +   * Configuration constants for Closure's tree UI.
                +   * @type {Object.<string,*>}
                +   * @private
                +   */
                +  this.config_ = {
                +    indentWidth: 19,
                +    cssRoot: 'blocklyTreeRoot',
                +    cssHideRoot: 'blocklyHidden',
                +    cssItem: '',
                +    cssTreeRow: 'blocklyTreeRow',
                +    cssItemLabel: 'blocklyTreeLabel',
                +    cssTreeIcon: 'blocklyTreeIcon',
                +    cssExpandedFolderIcon: 'blocklyTreeIconOpen',
                +    cssFileIcon: 'blocklyTreeIconNone',
                +    cssSelectedRow: 'blocklyTreeSelected'
                +  };
                +
                +
                +  /**
                +   * Configuration constants for tree separator.
                +   * @type {Object.<string,*>}
                +   * @private
                +   */
                +  this.treeSeparatorConfig_ = {
                +    cssTreeRow: 'blocklyTreeSeparator'
                +  };
                +
                +  if (this.horizontalLayout_) {
                +    this.config_['cssTreeRow'] =
                +        this.config_['cssTreeRow'] +
                +        (workspace.RTL ?
                +        ' blocklyHorizontalTreeRtl' : ' blocklyHorizontalTree');
                +
                +    this.treeSeparatorConfig_['cssTreeRow'] =
                +        'blocklyTreeSeparatorHorizontal ' +
                +        (workspace.RTL ?
                +        'blocklyHorizontalTreeRtl' : 'blocklyHorizontalTree');
                +    this.config_['cssTreeIcon'] = '';
                +  }
                +};
                +
                +/**
                + * Width of the toolbox, which changes only in vertical layout.
                + * @type {number}
                + */
                +Blockly.Toolbox.prototype.width = 0;
                +
                +/**
                + * Height of the toolbox, which changes only in horizontal layout.
                + * @type {number}
                + */
                +Blockly.Toolbox.prototype.height = 0;
                +
                +/**
                + * The SVG group currently selected.
                + * @type {SVGGElement}
                + * @private
                + */
                +Blockly.Toolbox.prototype.selectedOption_ = null;
                +
                +/**
                + * The tree node most recently selected.
                + * @type {goog.ui.tree.BaseNode}
                + * @private
                + */
                +Blockly.Toolbox.prototype.lastCategory_ = null;
                +
                +/**
                + * Initializes the toolbox.
                + */
                +Blockly.Toolbox.prototype.init = function() {
                +  var workspace = this.workspace_;
                +  var svg = this.workspace_.getParentSvg();
                +
                +  /**
                +   * HTML container for the Toolbox menu.
                +   * @type {Element}
                +   */
                +  this.HtmlDiv =
                +      goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyToolboxDiv');
                +  this.HtmlDiv.setAttribute('dir', workspace.RTL ? 'RTL' : 'LTR');
                +  svg.parentNode.insertBefore(this.HtmlDiv, svg);
                +
                +  // Clicking on toolbox closes popups.
                +  Blockly.bindEventWithChecks_(this.HtmlDiv, 'mousedown', this,
                +      function(e) {
                +        if (Blockly.utils.isRightButton(e) || e.target == this.HtmlDiv) {
                +          // Close flyout.
                +          Blockly.hideChaff(false);
                +        } else {
                +          // Just close popups.
                +          Blockly.hideChaff(true);
                +        }
                +        Blockly.Touch.clearTouchIdentifier();  // Don't block future drags.
                +      });
                +  var workspaceOptions = {
                +    disabledPatternId: workspace.options.disabledPatternId,
                +    parentWorkspace: workspace,
                +    RTL: workspace.RTL,
                +    oneBasedIndex: workspace.options.oneBasedIndex,
                +    horizontalLayout: workspace.horizontalLayout,
                +    toolboxPosition: workspace.options.toolboxPosition
                +  };
                +  /**
                +   * @type {!Blockly.Flyout}
                +   * @private
                +   */
                +  this.flyout_ = null;
                +  if (workspace.horizontalLayout) {
                +    this.flyout_ = new Blockly.HorizontalFlyout(workspaceOptions);
                +  } else {
                +    this.flyout_ = new Blockly.VerticalFlyout(workspaceOptions);
                +  }
                +  goog.dom.insertSiblingAfter(this.flyout_.createDom('svg'),
                +                              this.workspace_.getParentSvg());
                +  this.flyout_.init(workspace);
                +
                +  this.config_['cleardotPath'] = workspace.options.pathToMedia + '1x1.gif';
                +  this.config_['cssCollapsedFolderIcon'] =
                +      'blocklyTreeIconClosed' + (workspace.RTL ? 'Rtl' : 'Ltr');
                +  var tree = new Blockly.Toolbox.TreeControl(this, this.config_);
                +  this.tree_ = tree;
                +  tree.setShowRootNode(false);
                +  tree.setShowLines(false);
                +  tree.setShowExpandIcons(false);
                +  tree.setSelectedItem(null);
                +  var openNode = this.populate_(workspace.options.languageTree);
                +  tree.render(this.HtmlDiv);
                +  if (openNode) {
                +    tree.setSelectedItem(openNode);
                +  }
                +  this.addColour_();
                +  this.position();
                +};
                +
                +/**
                + * Dispose of this toolbox.
                + */
                +Blockly.Toolbox.prototype.dispose = function() {
                +  this.flyout_.dispose();
                +  this.tree_.dispose();
                +  goog.dom.removeNode(this.HtmlDiv);
                +  this.workspace_ = null;
                +  this.lastCategory_ = null;
                +};
                +
                +/**
                + * Get the width of the toolbox.
                + * @return {number} The width of the toolbox.
                + */
                +Blockly.Toolbox.prototype.getWidth = function() {
                +  return this.width;
                +};
                +
                +/**
                + * Get the height of the toolbox.
                + * @return {number} The width of the toolbox.
                + */
                +Blockly.Toolbox.prototype.getHeight = function() {
                +  return this.height;
                +};
                +
                +/**
                + * Move the toolbox to the edge.
                + */
                +Blockly.Toolbox.prototype.position = function() {
                +  var treeDiv = this.HtmlDiv;
                +  if (!treeDiv) {
                +    // Not initialized yet.
                +    return;
                +  }
                +  var svg = this.workspace_.getParentSvg();
                +  var svgSize = Blockly.svgSize(svg);
                +  if (this.horizontalLayout_) {
                +    treeDiv.style.left = '0';
                +    treeDiv.style.height = 'auto';
                +    treeDiv.style.width = svgSize.width + 'px';
                +    this.height = treeDiv.offsetHeight;
                +    if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {  // Top
                +      treeDiv.style.top = '0';
                +    } else {  // Bottom
                +      treeDiv.style.bottom = '0';
                +    }
                +  } else {
                +    if (this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {  // Right
                +      treeDiv.style.right = '0';
                +    } else {  // Left
                +      treeDiv.style.left = '0';
                +    }
                +    treeDiv.style.height = svgSize.height + 'px';
                +    this.width = treeDiv.offsetWidth;
                +  }
                +  this.flyout_.position();
                +};
                +
                +/**
                + * Fill the toolbox with categories and blocks.
                + * @param {!Node} newTree DOM tree of blocks.
                + * @return {Node} Tree node to open at startup (or null).
                + * @private
                + */
                +Blockly.Toolbox.prototype.populate_ = function(newTree) {
                +  this.tree_.removeChildren();  // Delete any existing content.
                +  this.tree_.blocks = [];
                +  this.hasColours_ = false;
                +  var openNode =
                +    this.syncTrees_(newTree, this.tree_, this.workspace_.options.pathToMedia);
                +
                +  if (this.tree_.blocks.length) {
                +    throw 'Toolbox cannot have both blocks and categories in the root level.';
                +  }
                +
                +  // Fire a resize event since the toolbox may have changed width and height.
                +  this.workspace_.resizeContents();
                +  return openNode;
                +};
                +
                +/**
                + * Sync trees of the toolbox.
                + * @param {!Node} treeIn DOM tree of blocks.
                + * @param {!Blockly.Toolbox.TreeControl} treeOut
                + * @param {string} pathToMedia
                + * @return {Node} Tree node to open at startup (or null).
                + * @private
                + */
                +Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
                +  var openNode = null;
                +  var lastElement = null;
                +  for (var i = 0, childIn; childIn = treeIn.childNodes[i]; i++) {
                +    if (!childIn.tagName) {
                +      // Skip over text.
                +      continue;
                +    }
                +    switch (childIn.tagName.toUpperCase()) {
                +      case 'CATEGORY':
                +        // Decode the category name for any potential message references
                +        // (eg. `%{BKY_CATEGORY_NAME_LOGIC}`).
                +        var categoryName = Blockly.utils.replaceMessageReferences(
                +          childIn.getAttribute('name'));
                +        var childOut = this.tree_.createNode(categoryName);
                +        childOut.blocks = [];
                +        treeOut.add(childOut);
                +        var custom = childIn.getAttribute('custom');
                +        if (custom) {
                +          // Variables and procedures are special dynamic categories.
                +          childOut.blocks = custom;
                +        } else {
                +          var newOpenNode = this.syncTrees_(childIn, childOut, pathToMedia);
                +          if (newOpenNode) {
                +            openNode = newOpenNode;
                +          }
                +        }
                +        // Decode the colour for any potential message references
                +        // (eg. `%{BKY_MATH_HUE}`).
                +        var colour = Blockly.utils.replaceMessageReferences(
                +          childIn.getAttribute('colour'));
                +        if (goog.isString(colour)) {
                +          if (colour.match(/^#[0-9a-fA-F]{6}$/)) {
                +            childOut.hexColour = colour;
                +          } else {
                +            childOut.hexColour = Blockly.hueToRgb(colour);
                +          }
                +          this.hasColours_ = true;
                +        } else {
                +          childOut.hexColour = '';
                +        }
                +        if (childIn.getAttribute('expanded') == 'true') {
                +          if (childOut.blocks.length) {
                +            // This is a category that directly contains blocks.
                +            // After the tree is rendered, open this category and show flyout.
                +            openNode = childOut;
                +          }
                +          childOut.setExpanded(true);
                +        } else {
                +          childOut.setExpanded(false);
                +        }
                +        lastElement = childIn;
                +        break;
                +      case 'SEP':
                +        if (lastElement) {
                +          if (lastElement.tagName.toUpperCase() == 'CATEGORY') {
                +            // Separator between two categories.
                +            // <sep></sep>
                +            treeOut.add(new Blockly.Toolbox.TreeSeparator(
                +                this.treeSeparatorConfig_));
                +          } else {
                +            // Change the gap between two blocks.
                +            // <sep gap="36"></sep>
                +            // The default gap is 24, can be set larger or smaller.
                +            // Note that a deprecated method is to add a gap to a block.
                +            // <block type="math_arithmetic" gap="8"></block>
                +            var newGap = parseFloat(childIn.getAttribute('gap'));
                +            if (!isNaN(newGap) && lastElement) {
                +              lastElement.setAttribute('gap', newGap);
                +            }
                +          }
                +        }
                +        break;
                +      case 'BLOCK':
                +      case 'SHADOW':
                +      case 'LABEL':
                +      case 'BUTTON':
                +        treeOut.blocks.push(childIn);
                +        lastElement = childIn;
                +        break;
                +    }
                +  }
                +  return openNode;
                +};
                +
                +/**
                + * Recursively add colours to this toolbox.
                + * @param {Blockly.Toolbox.TreeNode} opt_tree Starting point of tree.
                + *     Defaults to the root node.
                + * @private
                + */
                +Blockly.Toolbox.prototype.addColour_ = function(opt_tree) {
                +  var tree = opt_tree || this.tree_;
                +  var children = tree.getChildren();
                +  for (var i = 0, child; child = children[i]; i++) {
                +    var element = child.getRowElement();
                +    if (element) {
                +      if (this.hasColours_) {
                +        var border = '8px solid ' + (child.hexColour || '#ddd');
                +      } else {
                +        var border = 'none';
                +      }
                +      if (this.workspace_.RTL) {
                +        element.style.borderRight = border;
                +      } else {
                +        element.style.borderLeft = border;
                +      }
                +    }
                +    this.addColour_(child);
                +  }
                +};
                +
                +/**
                + * Unhighlight any previously specified option.
                + */
                +Blockly.Toolbox.prototype.clearSelection = function() {
                +  this.tree_.setSelectedItem(null);
                +};
                +
                +/**
                + * Adds styles on the toolbox indicating blocks will be deleted.
                + * @package
                + */
                +Blockly.Toolbox.prototype.addDeleteStyle = function() {
                +  Blockly.utils.addClass(/** @type {!Element} */ (this.HtmlDiv),
                +                         'blocklyToolboxDelete');
                +};
                +
                +/**
                + * Remove styles from the toolbox that indicate blocks will be deleted.
                + * @package
                + */
                +Blockly.Toolbox.prototype.removeDeleteStyle = function() {
                +  Blockly.utils.removeClass(/** @type {!Element} */ (this.HtmlDiv),
                +                            'blocklyToolboxDelete');
                +};
                +
                +/**
                + * Return the deletion rectangle for this toolbox.
                + * @return {goog.math.Rect} Rectangle in which to delete.
                + */
                +Blockly.Toolbox.prototype.getClientRect = function() {
                +  if (!this.HtmlDiv) {
                +    return null;
                +  }
                +
                +  // BIG_NUM is offscreen padding so that blocks dragged beyond the toolbox
                +  // area are still deleted.  Must be smaller than Infinity, but larger than
                +  // the largest screen size.
                +  var BIG_NUM = 10000000;
                +  var toolboxRect = this.HtmlDiv.getBoundingClientRect();
                +
                +  var x = toolboxRect.left;
                +  var y = toolboxRect.top;
                +  var width = toolboxRect.width;
                +  var height = toolboxRect.height;
                +
                +  // Assumes that the toolbox is on the SVG edge.  If this changes
                +  // (e.g. toolboxes in mutators) then this code will need to be more complex.
                +  if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
                +    return new goog.math.Rect(-BIG_NUM, -BIG_NUM, BIG_NUM + x + width,
                +        2 * BIG_NUM);
                +  } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
                +    return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + width, 2 * BIG_NUM);
                +  } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {
                +    return new goog.math.Rect(-BIG_NUM, -BIG_NUM, 2 * BIG_NUM,
                +        BIG_NUM + y + height);
                +  } else {  // Bottom
                +    return new goog.math.Rect(0, y, 2 * BIG_NUM, BIG_NUM + width);
                +  }
                +};
                +
                +/**
                + * Update the flyout's contents without closing it.  Should be used in response
                + * to a change in one of the dynamic categories, such as variables or
                + * procedures.
                + */
                +Blockly.Toolbox.prototype.refreshSelection = function() {
                +  var selectedItem = this.tree_.getSelectedItem();
                +  if (selectedItem && selectedItem.blocks) {
                +    this.flyout_.show(selectedItem.blocks);
                +  }
                +};
                +
                +// Extending Closure's Tree UI.
                +
                +/**
                + * Extension of a TreeControl object that uses a custom tree node.
                + * @param {Blockly.Toolbox} toolbox The parent toolbox for this tree.
                + * @param {Object} config The configuration for the tree. See
                + *    goog.ui.tree.TreeControl.DefaultConfig.
                + * @constructor
                + * @extends {goog.ui.tree.TreeControl}
                + */
                +Blockly.Toolbox.TreeControl = function(toolbox, config) {
                +  this.toolbox_ = toolbox;
                +  goog.ui.tree.TreeControl.call(this, goog.html.SafeHtml.EMPTY, config);
                +};
                +goog.inherits(Blockly.Toolbox.TreeControl, goog.ui.tree.TreeControl);
                +
                +/**
                + * Adds touch handling to TreeControl.
                + * @override
                + */
                +Blockly.Toolbox.TreeControl.prototype.enterDocument = function() {
                +  Blockly.Toolbox.TreeControl.superClass_.enterDocument.call(this);
                +
                +  // Add touch handler.
                +  if (goog.events.BrowserFeature.TOUCH_ENABLED) {
                +    var el = this.getElement();
                +    Blockly.bindEventWithChecks_(el, goog.events.EventType.TOUCHSTART, this,
                +        this.handleTouchEvent_);
                +  }
                +};
                +
                +/**
                + * Handles touch events.
                + * @param {!goog.events.BrowserEvent} e The browser event.
                + * @private
                + */
                +Blockly.Toolbox.TreeControl.prototype.handleTouchEvent_ = function(e) {
                +  e.preventDefault();
                +  var node = this.getNodeFromEvent_(e);
                +  if (node && e.type === goog.events.EventType.TOUCHSTART) {
                +    // Fire asynchronously since onMouseDown takes long enough that the browser
                +    // would fire the default mouse event before this method returns.
                +    setTimeout(function() {
                +      node.onMouseDown(e);  // Same behaviour for click and touch.
                +    }, 1);
                +  }
                +};
                +
                +/**
                + * Creates a new tree node using a custom tree node.
                + * @param {string=} opt_html The HTML content of the node label.
                + * @return {!goog.ui.tree.TreeNode} The new item.
                + * @override
                + */
                +Blockly.Toolbox.TreeControl.prototype.createNode = function(opt_html) {
                +  return new Blockly.Toolbox.TreeNode(this.toolbox_, opt_html ?
                +      goog.html.SafeHtml.htmlEscape(opt_html) : goog.html.SafeHtml.EMPTY,
                +      this.getConfig(), this.getDomHelper());
                +};
                +
                +/**
                + * Display/hide the flyout when an item is selected.
                + * @param {goog.ui.tree.BaseNode} node The item to select.
                + * @override
                + */
                +Blockly.Toolbox.TreeControl.prototype.setSelectedItem = function(node) {
                +  var toolbox = this.toolbox_;
                +  if (node == this.selectedItem_ || node == toolbox.tree_) {
                +    return;
                +  }
                +  if (toolbox.lastCategory_) {
                +    toolbox.lastCategory_.getRowElement().style.backgroundColor = '';
                +  }
                +  if (node) {
                +    var hexColour = node.hexColour || '#57e';
                +    node.getRowElement().style.backgroundColor = hexColour;
                +    // Add colours to child nodes which may have been collapsed and thus
                +    // not rendered.
                +    toolbox.addColour_(node);
                +  }
                +  var oldNode = this.getSelectedItem();
                +  goog.ui.tree.TreeControl.prototype.setSelectedItem.call(this, node);
                +  if (node && node.blocks && node.blocks.length) {
                +    toolbox.flyout_.show(node.blocks);
                +    // Scroll the flyout to the top if the category has changed.
                +    if (toolbox.lastCategory_ != node) {
                +      toolbox.flyout_.scrollToStart();
                +    }
                +  } else {
                +    // Hide the flyout.
                +    toolbox.flyout_.hide();
                +  }
                +  if (oldNode != node && oldNode != this) {
                +    var event = new Blockly.Events.Ui(null, 'category',
                +        oldNode && oldNode.getHtml(), node && node.getHtml());
                +    event.workspaceId = toolbox.workspace_.id;
                +    Blockly.Events.fire(event);
                +  }
                +  if (node) {
                +    toolbox.lastCategory_ = node;
                +  }
                +};
                +
                +/**
                + * A single node in the tree, customized for Blockly's UI.
                + * @param {Blockly.Toolbox} toolbox The parent toolbox for this tree.
                + * @param {!goog.html.SafeHtml} html The HTML content of the node label.
                + * @param {Object=} opt_config The configuration for the tree. See
                + *    goog.ui.tree.TreeControl.DefaultConfig. If not specified, a default config
                + *    will be used.
                + * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
                + * @constructor
                + * @extends {goog.ui.tree.TreeNode}
                + */
                +Blockly.Toolbox.TreeNode = function(toolbox, html, opt_config, opt_domHelper) {
                +  goog.ui.tree.TreeNode.call(this, html, opt_config, opt_domHelper);
                +  if (toolbox) {
                +    var resize = function() {
                +      // Even though the div hasn't changed size, the visible workspace
                +      // surface of the workspace has, so we may need to reposition everything.
                +      Blockly.svgResize(toolbox.workspace_);
                +    };
                +    // Fire a resize event since the toolbox may have changed width.
                +    goog.events.listen(toolbox.tree_,
                +        goog.ui.tree.BaseNode.EventType.EXPAND, resize);
                +    goog.events.listen(toolbox.tree_,
                +        goog.ui.tree.BaseNode.EventType.COLLAPSE, resize);
                +  }
                +};
                +goog.inherits(Blockly.Toolbox.TreeNode, goog.ui.tree.TreeNode);
                +
                +/**
                + * Suppress population of the +/- icon.
                + * @return {!goog.html.SafeHtml} The source for the icon.
                + * @override
                + */
                +Blockly.Toolbox.TreeNode.prototype.getExpandIconSafeHtml = function() {
                +  return goog.html.SafeHtml.create('span');
                +};
                +
                +/**
                + * Expand or collapse the node on mouse click.
                + * @param {!goog.events.BrowserEvent} e The browser event.
                + * @override
                + */
                +Blockly.Toolbox.TreeNode.prototype.onMouseDown = function(e) {
                +  // Expand icon.
                +  if (this.hasChildren() && this.isUserCollapsible_) {
                +    this.toggle();
                +    this.select();
                +  } else if (this.isSelected()) {
                +    this.getTree().setSelectedItem(null);
                +  } else {
                +    this.select();
                +  }
                +  this.updateRow();
                +};
                +
                +/**
                + * Suppress the inherited double-click behaviour.
                + * @param {!goog.events.BrowserEvent} e The browser event.
                + * @override
                + * @private
                + */
                +Blockly.Toolbox.TreeNode.prototype.onDoubleClick_ = function(e) {
                +  // NOP.
                +};
                +
                +/**
                + * Remap event.keyCode in horizontalLayout so that arrow
                + * keys work properly and call original onKeyDown handler.
                + * @param {!goog.events.BrowserEvent} e The browser event.
                + * @return {boolean} The handled value.
                + * @override
                + * @private
                + */
                +Blockly.Toolbox.TreeNode.prototype.onKeyDown = function(e) {
                +  if (this.tree.toolbox_.horizontalLayout_) {
                +    var map = {};
                +    var next = goog.events.KeyCodes.DOWN;
                +    var prev = goog.events.KeyCodes.UP;
                +    map[goog.events.KeyCodes.RIGHT] = this.rightToLeft_ ? prev : next;
                +    map[goog.events.KeyCodes.LEFT] = this.rightToLeft_ ? next : prev;
                +    map[goog.events.KeyCodes.UP] = goog.events.KeyCodes.LEFT;
                +    map[goog.events.KeyCodes.DOWN] = goog.events.KeyCodes.RIGHT;
                +
                +    var newKeyCode = map[e.keyCode];
                +    e.keyCode = newKeyCode || e.keyCode;
                +  }
                +  return Blockly.Toolbox.TreeNode.superClass_.onKeyDown.call(this, e);
                +};
                +
                +/**
                + * A blank separator node in the tree.
                + * @param {Object=} config The configuration for the tree. See
                + *    goog.ui.tree.TreeControl.DefaultConfig. If not specified, a default config
                + *    will be used.
                + * @constructor
                + * @extends {Blockly.Toolbox.TreeNode}
                + */
                +Blockly.Toolbox.TreeSeparator = function(config) {
                +  Blockly.Toolbox.TreeNode.call(this, null, '', config);
                +};
                +goog.inherits(Blockly.Toolbox.TreeSeparator, Blockly.Toolbox.TreeNode);
                diff --git a/blockly/webif/static/blockly/core/tooltip.js b/blockly/webif/static/blockly/core/tooltip.js
                new file mode 100644
                index 000000000..17fa45d49
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/tooltip.js
                @@ -0,0 +1,335 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Library to create tooltips for Blockly.
                + * First, call Blockly.Tooltip.init() after onload.
                + * Second, set the 'tooltip' property on any SVG element that needs a tooltip.
                + * If the tooltip is a string, then that message will be displayed.
                + * If the tooltip is an SVG element, then that object's tooltip will be used.
                + * Third, call Blockly.Tooltip.bindMouseEvents(e) passing the SVG element.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Tooltip
                + * @namespace
                + **/
                +goog.provide('Blockly.Tooltip');
                +
                +goog.require('goog.dom');
                +goog.require('goog.dom.TagName');
                +
                +
                +/**
                + * Is a tooltip currently showing?
                + */
                +Blockly.Tooltip.visible = false;
                +
                +/**
                + * Is someone else blocking the tooltip from being shown?
                + * @type {boolean}
                + * @private
                + */
                +Blockly.Tooltip.blocked_ = false;
                +
                +/**
                + * Maximum width (in characters) of a tooltip.
                + */
                +Blockly.Tooltip.LIMIT = 50;
                +
                +/**
                + * PID of suspended thread to clear tooltip on mouse out.
                + * @private
                + */
                +Blockly.Tooltip.mouseOutPid_ = 0;
                +
                +/**
                + * PID of suspended thread to show the tooltip.
                + * @private
                + */
                +Blockly.Tooltip.showPid_ = 0;
                +
                +/**
                + * Last observed X location of the mouse pointer (freezes when tooltip appears).
                + * @private
                + */
                +Blockly.Tooltip.lastX_ = 0;
                +
                +/**
                + * Last observed Y location of the mouse pointer (freezes when tooltip appears).
                + * @private
                + */
                +Blockly.Tooltip.lastY_ = 0;
                +
                +/**
                + * Current element being pointed at.
                + * @private
                + */
                +Blockly.Tooltip.element_ = null;
                +
                +/**
                + * Once a tooltip has opened for an element, that element is 'poisoned' and
                + * cannot respawn a tooltip until the pointer moves over a different element.
                + * @private
                + */
                +Blockly.Tooltip.poisonedElement_ = null;
                +
                +/**
                + * Horizontal offset between mouse cursor and tooltip.
                + */
                +Blockly.Tooltip.OFFSET_X = 0;
                +
                +/**
                + * Vertical offset between mouse cursor and tooltip.
                + */
                +Blockly.Tooltip.OFFSET_Y = 10;
                +
                +/**
                + * Radius mouse can move before killing tooltip.
                + */
                +Blockly.Tooltip.RADIUS_OK = 10;
                +
                +/**
                + * Delay before tooltip appears.
                + */
                +Blockly.Tooltip.HOVER_MS = 750;
                +
                +/**
                + * Horizontal padding between tooltip and screen edge.
                + */
                +Blockly.Tooltip.MARGINS = 5;
                +
                +/**
                + * The HTML container.  Set once by Blockly.Tooltip.createDom.
                + * @type {Element}
                + */
                +Blockly.Tooltip.DIV = null;
                +
                +/**
                + * Create the tooltip div and inject it onto the page.
                + */
                +Blockly.Tooltip.createDom = function() {
                +  if (Blockly.Tooltip.DIV) {
                +    return;  // Already created.
                +  }
                +  // Create an HTML container for popup overlays (e.g. editor widgets).
                +  Blockly.Tooltip.DIV =
                +      goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyTooltipDiv');
                +  document.body.appendChild(Blockly.Tooltip.DIV);
                +};
                +
                +/**
                + * Binds the required mouse events onto an SVG element.
                + * @param {!Element} element SVG element onto which tooltip is to be bound.
                + */
                +Blockly.Tooltip.bindMouseEvents = function(element) {
                +  Blockly.bindEvent_(element, 'mouseover', null,
                +      Blockly.Tooltip.onMouseOver_);
                +  Blockly.bindEvent_(element, 'mouseout', null,
                +      Blockly.Tooltip.onMouseOut_);
                +
                +  // Don't use bindEvent_ for mousemove since that would create a
                +  // corresponding touch handler, even though this only makes sense in the
                +  // context of a mouseover/mouseout.
                +  element.addEventListener('mousemove', Blockly.Tooltip.onMouseMove_, false);
                +};
                +
                +/**
                + * Hide the tooltip if the mouse is over a different object.
                + * Initialize the tooltip to potentially appear for this object.
                + * @param {!Event} e Mouse event.
                + * @private
                + */
                +Blockly.Tooltip.onMouseOver_ = function(e) {
                +  if (Blockly.Tooltip.blocked_) {
                +    // Someone doesn't want us to show tooltips.
                +    return;
                +  }
                +  // If the tooltip is an object, treat it as a pointer to the next object in
                +  // the chain to look at.  Terminate when a string or function is found.
                +  var element = e.target;
                +  while (!goog.isString(element.tooltip) && !goog.isFunction(element.tooltip)) {
                +    element = element.tooltip;
                +  }
                +  if (Blockly.Tooltip.element_ != element) {
                +    Blockly.Tooltip.hide();
                +    Blockly.Tooltip.poisonedElement_ = null;
                +    Blockly.Tooltip.element_ = element;
                +  }
                +  // Forget about any immediately preceding mouseOut event.
                +  clearTimeout(Blockly.Tooltip.mouseOutPid_);
                +};
                +
                +/**
                + * Hide the tooltip if the mouse leaves the object and enters the workspace.
                + * @param {!Event} e Mouse event.
                + * @private
                + */
                +Blockly.Tooltip.onMouseOut_ = function(e) {
                +  if (Blockly.Tooltip.blocked_) {
                +    // Someone doesn't want us to show tooltips.
                +    return;
                +  }
                +  // Moving from one element to another (overlapping or with no gap) generates
                +  // a mouseOut followed instantly by a mouseOver.  Fork off the mouseOut
                +  // event and kill it if a mouseOver is received immediately.
                +  // This way the task only fully executes if mousing into the void.
                +  Blockly.Tooltip.mouseOutPid_ = setTimeout(function() {
                +    Blockly.Tooltip.element_ = null;
                +    Blockly.Tooltip.poisonedElement_ = null;
                +    Blockly.Tooltip.hide();
                +  }, 1);
                +  clearTimeout(Blockly.Tooltip.showPid_);
                +};
                +
                +/**
                + * When hovering over an element, schedule a tooltip to be shown.  If a tooltip
                + * is already visible, hide it if the mouse strays out of a certain radius.
                + * @param {!Event} e Mouse event.
                + * @private
                + */
                +Blockly.Tooltip.onMouseMove_ = function(e) {
                +  if (!Blockly.Tooltip.element_ || !Blockly.Tooltip.element_.tooltip) {
                +    // No tooltip here to show.
                +    return;
                +  } else if (Blockly.WidgetDiv.isVisible()) {
                +    // Don't display a tooltip if a widget is open (tooltip would be under it).
                +    return;
                +  } else if (Blockly.Tooltip.blocked_) {
                +    // Someone doesn't want us to show tooltips.  We are probably handling a
                +    // user gesture, such as a click or drag.
                +    return;
                +  }
                +  if (Blockly.Tooltip.visible) {
                +    // Compute the distance between the mouse position when the tooltip was
                +    // shown and the current mouse position.  Pythagorean theorem.
                +    var dx = Blockly.Tooltip.lastX_ - e.pageX;
                +    var dy = Blockly.Tooltip.lastY_ - e.pageY;
                +    if (Math.sqrt(dx * dx + dy * dy) > Blockly.Tooltip.RADIUS_OK) {
                +      Blockly.Tooltip.hide();
                +    }
                +  } else if (Blockly.Tooltip.poisonedElement_ != Blockly.Tooltip.element_) {
                +    // The mouse moved, clear any previously scheduled tooltip.
                +    clearTimeout(Blockly.Tooltip.showPid_);
                +    // Maybe this time the mouse will stay put.  Schedule showing of tooltip.
                +    Blockly.Tooltip.lastX_ = e.pageX;
                +    Blockly.Tooltip.lastY_ = e.pageY;
                +    Blockly.Tooltip.showPid_ =
                +        setTimeout(Blockly.Tooltip.show_, Blockly.Tooltip.HOVER_MS);
                +  }
                +};
                +
                +/**
                + * Hide the tooltip.
                + */
                +Blockly.Tooltip.hide = function() {
                +  if (Blockly.Tooltip.visible) {
                +    Blockly.Tooltip.visible = false;
                +    if (Blockly.Tooltip.DIV) {
                +      Blockly.Tooltip.DIV.style.display = 'none';
                +    }
                +  }
                +  clearTimeout(Blockly.Tooltip.showPid_);
                +};
                +
                +/**
                + * Hide any in-progress tooltips and block showing new tooltips until the next
                + * call to unblock().
                + * @package
                + */
                +Blockly.Tooltip.block = function() {
                +  Blockly.Tooltip.hide();
                +  Blockly.Tooltip.blocked_ = true;
                +};
                +
                +/**
                + * Unblock tooltips: allow them to be scheduled and shown according to their own
                + * logic.
                + * @package
                + */
                +Blockly.Tooltip.unblock = function() {
                +  Blockly.Tooltip.blocked_ = false;
                +};
                +
                +/**
                + * Create the tooltip and show it.
                + * @private
                + */
                +Blockly.Tooltip.show_ = function() {
                +  if (Blockly.Tooltip.blocked_) {
                +    // Someone doesn't want us to show tooltips.
                +    return;
                +  }
                +  Blockly.Tooltip.poisonedElement_ = Blockly.Tooltip.element_;
                +  if (!Blockly.Tooltip.DIV) {
                +    return;
                +  }
                +  // Erase all existing text.
                +  goog.dom.removeChildren(/** @type {!Element} */ (Blockly.Tooltip.DIV));
                +  // Get the new text.
                +  var tip = Blockly.Tooltip.element_.tooltip;
                +  while (goog.isFunction(tip)) {
                +    tip = tip();
                +  }
                +  tip = Blockly.utils.wrap(tip, Blockly.Tooltip.LIMIT);
                +  // Create new text, line by line.
                +  var lines = tip.split('\n');
                +  for (var i = 0; i < lines.length; i++) {
                +    var div = document.createElement('div');
                +    div.appendChild(document.createTextNode(lines[i]));
                +    Blockly.Tooltip.DIV.appendChild(div);
                +  }
                +  var rtl = Blockly.Tooltip.element_.RTL;
                +  var windowSize = goog.dom.getViewportSize();
                +  // Display the tooltip.
                +  Blockly.Tooltip.DIV.style.direction = rtl ? 'rtl' : 'ltr';
                +  Blockly.Tooltip.DIV.style.display = 'block';
                +  Blockly.Tooltip.visible = true;
                +  // Move the tooltip to just below the cursor.
                +  var anchorX = Blockly.Tooltip.lastX_;
                +  if (rtl) {
                +    anchorX -= Blockly.Tooltip.OFFSET_X + Blockly.Tooltip.DIV.offsetWidth;
                +  } else {
                +    anchorX += Blockly.Tooltip.OFFSET_X;
                +  }
                +  var anchorY = Blockly.Tooltip.lastY_ + Blockly.Tooltip.OFFSET_Y;
                +
                +  if (anchorY + Blockly.Tooltip.DIV.offsetHeight >
                +      windowSize.height + window.scrollY) {
                +    // Falling off the bottom of the screen; shift the tooltip up.
                +    anchorY -= Blockly.Tooltip.DIV.offsetHeight + 2 * Blockly.Tooltip.OFFSET_Y;
                +  }
                +  if (rtl) {
                +    // Prevent falling off left edge in RTL mode.
                +    anchorX = Math.max(Blockly.Tooltip.MARGINS - window.scrollX, anchorX);
                +  } else {
                +    if (anchorX + Blockly.Tooltip.DIV.offsetWidth >
                +        windowSize.width + window.scrollX - 2 * Blockly.Tooltip.MARGINS) {
                +      // Falling off the right edge of the screen;
                +      // clamp the tooltip on the edge.
                +      anchorX = windowSize.width - Blockly.Tooltip.DIV.offsetWidth -
                +          2 * Blockly.Tooltip.MARGINS;
                +    }
                +  }
                +  Blockly.Tooltip.DIV.style.top = anchorY + 'px';
                +  Blockly.Tooltip.DIV.style.left = anchorX + 'px';
                +};
                diff --git a/blockly/webif/static/blockly/core/touch.js b/blockly/webif/static/blockly/core/touch.js
                new file mode 100644
                index 000000000..37fde517b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/touch.js
                @@ -0,0 +1,226 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Touch handling for Blockly.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Touch
                + * @namespace
                + **/
                +goog.provide('Blockly.Touch');
                +
                +goog.require('goog.events');
                +goog.require('goog.events.BrowserFeature');
                +goog.require('goog.string');
                +
                +/**
                + * Which touch events are we currently paying attention to?
                + * @type {DOMString}
                + * @private
                + */
                +Blockly.Touch.touchIdentifier_ = null;
                +
                +/**
                + * The TOUCH_MAP lookup dictionary specifies additional touch events to fire,
                + * in conjunction with mouse events.
                + * @type {Object}
                + */
                +Blockly.Touch.TOUCH_MAP = {};
                +if (goog.events.BrowserFeature.TOUCH_ENABLED) {
                +  Blockly.Touch.TOUCH_MAP = {
                +    'mousedown': ['touchstart'],
                +    'mousemove': ['touchmove'],
                +    'mouseup': ['touchend', 'touchcancel']
                +  };
                +}
                +
                +/**
                + * PID of queued long-press task.
                + * @private
                + */
                +Blockly.longPid_ = 0;
                +
                +/**
                + * Context menus on touch devices are activated using a long-press.
                + * Unfortunately the contextmenu touch event is currently (2015) only suported
                + * by Chrome.  This function is fired on any touchstart event, queues a task,
                + * which after about a second opens the context menu.  The tasks is killed
                + * if the touch event terminates early.
                + * @param {!Event} e Touch start event.
                + * @param {Blockly.Gesture} gesture The gesture that triggered this longStart.
                + * @private
                + */
                +Blockly.longStart_ = function(e, gesture) {
                +  Blockly.longStop_();
                +  // Punt on multitouch events.
                +  if (e.changedTouches.length != 1) {
                +    return;
                +  }
                +  Blockly.longPid_ = setTimeout(function() {
                +    e.button = 2;  // Simulate a right button click.
                +    // e was a touch event.  It needs to pretend to be a mouse event.
                +    e.clientX = e.changedTouches[0].clientX;
                +    e.clientY = e.changedTouches[0].clientY;
                +
                +    // Let the gesture route the right-click correctly.
                +    if (gesture) {
                +      gesture.handleRightClick(e);
                +    }
                +
                +  }, Blockly.LONGPRESS);
                +};
                +
                +/**
                + * Nope, that's not a long-press.  Either touchend or touchcancel was fired,
                + * or a drag hath begun.  Kill the queued long-press task.
                + * @private
                + */
                +Blockly.longStop_ = function() {
                +  if (Blockly.longPid_) {
                +    clearTimeout(Blockly.longPid_);
                +    Blockly.longPid_ = 0;
                +  }
                +};
                +
                +/**
                + * Clear the touch identifier that tracks which touch stream to pay attention
                + * to.  This ends the current drag/gesture and allows other pointers to be
                + * captured.
                + */
                +Blockly.Touch.clearTouchIdentifier = function() {
                +  Blockly.Touch.touchIdentifier_ = null;
                +};
                +
                +/**
                + * Decide whether Blockly should handle or ignore this event.
                + * Mouse and touch events require special checks because we only want to deal
                + * with one touch stream at a time.  All other events should always be handled.
                + * @param {!Event} e The event to check.
                + * @return {boolean} True if this event should be passed through to the
                + *     registered handler; false if it should be blocked.
                + */
                +Blockly.Touch.shouldHandleEvent = function(e) {
                +  return !Blockly.Touch.isMouseOrTouchEvent(e) ||
                +      Blockly.Touch.checkTouchIdentifier(e);
                +};
                +
                +/**
                + * Get the touch identifier from the given event.  If it was a mouse event, the
                + * identifier is the string 'mouse'.
                + * @param {!Event} e Mouse event or touch event.
                + * @return {string} The touch identifier from the first changed touch, if
                + *     defined.  Otherwise 'mouse'.
                + */
                +Blockly.Touch.getTouchIdentifierFromEvent = function(e) {
                +  return (e.changedTouches && e.changedTouches[0] &&
                +      e.changedTouches[0].identifier != undefined &&
                +      e.changedTouches[0].identifier != null) ?
                +      e.changedTouches[0].identifier : 'mouse';
                +};
                +
                +/**
                + * Check whether the touch identifier on the event matches the current saved
                + * identifier.  If there is no identifier, that means it's a mouse event and
                + * we'll use the identifier "mouse".  This means we won't deal well with
                + * multiple mice being used at the same time.  That seems okay.
                + * If the current identifier was unset, save the identifier from the
                + * event.  This starts a drag/gesture, during which touch events with other
                + * identifiers will be silently ignored.
                + * @param {!Event} e Mouse event or touch event.
                + * @return {boolean} Whether the identifier on the event matches the current
                + *     saved identifier.
                + */
                +Blockly.Touch.checkTouchIdentifier = function(e) {
                +  var identifier = Blockly.Touch.getTouchIdentifierFromEvent(e);
                +
                +  // if (Blockly.touchIdentifier_ )is insufficient because android touch
                +  // identifiers may be zero.
                +  if (Blockly.Touch.touchIdentifier_ != undefined &&
                +      Blockly.Touch.touchIdentifier_ != null) {
                +    // We're already tracking some touch/mouse event.  Is this from the same
                +    // source?
                +    return Blockly.Touch.touchIdentifier_ == identifier;
                +  }
                +  if (e.type == 'mousedown' || e.type == 'touchstart') {
                +    // No identifier set yet, and this is the start of a drag.  Set it and
                +    // return.
                +    Blockly.Touch.touchIdentifier_ = identifier;
                +    return true;
                +  }
                +  // There was no identifier yet, but this wasn't a start event so we're going
                +  // to ignore it.  This probably means that another drag finished while this
                +  // pointer was down.
                +  return false;
                +};
                +
                +/**
                + * Set an event's clientX and clientY from its first changed touch.  Use this to
                + * make a touch event work in a mouse event handler.
                + * @param {!Event} e A touch event.
                + */
                +Blockly.Touch.setClientFromTouch = function(e) {
                +  if (goog.string.startsWith(e.type, 'touch')) {
                +    // Map the touch event's properties to the event.
                +    var touchPoint = e.changedTouches[0];
                +    e.clientX = touchPoint.clientX;
                +    e.clientY = touchPoint.clientY;
                +  }
                +};
                +
                +/**
                + * Check whether a given event is a mouse or touch event.
                + * @param {!Event} e An event.
                + * @return {boolean} true if it is a mouse or touch event; false otherwise.
                + */
                +Blockly.Touch.isMouseOrTouchEvent = function(e) {
                +  return goog.string.startsWith(e.type, 'touch') ||
                +      goog.string.startsWith(e.type, 'mouse');
                +};
                +
                +/**
                + * Split an event into an array of events, one per changed touch or mouse
                + * point.
                + * @param {!Event} e A mouse event or a touch event with one or more changed
                + * touches.
                + * @return {!Array.<!Event>} An array of mouse or touch events.  Each touch
                + *     event will have exactly one changed touch.
                + */
                +Blockly.Touch.splitEventByTouches = function(e) {
                +  var events = [];
                +  if (e.changedTouches) {
                +    for (var i = 0; i < e.changedTouches.length; i++) {
                +      var newEvent = {
                +        type: e.type,
                +        changedTouches: [e.changedTouches[i]],
                +        target: e.target,
                +        stopPropagation: function(){ e.stopPropagation(); },
                +        preventDefault: function(){ e.preventDefault(); }
                +      };
                +      events[i] = newEvent;
                +    }
                +  } else {
                +    events.push(e);
                +  }
                +  return events;
                +};
                diff --git a/blockly/webif/static/blockly/core/trashcan.js b/blockly/webif/static/blockly/core/trashcan.js
                new file mode 100644
                index 000000000..7dfb600a1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/trashcan.js
                @@ -0,0 +1,333 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a trash can icon.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Trashcan');
                +
                +goog.require('goog.Timer');
                +goog.require('goog.dom');
                +goog.require('goog.math');
                +goog.require('goog.math.Rect');
                +
                +
                +/**
                + * Class for a trash can.
                + * @param {!Blockly.Workspace} workspace The workspace to sit in.
                + * @constructor
                + */
                +Blockly.Trashcan = function(workspace) {
                +  this.workspace_ = workspace;
                +};
                +
                +/**
                + * Width of both the trash can and lid images.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.WIDTH_ = 47;
                +
                +/**
                + * Height of the trashcan image (minus lid).
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.BODY_HEIGHT_ = 44;
                +
                +/**
                + * Height of the lid image.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.LID_HEIGHT_ = 16;
                +
                +/**
                + * Distance between trashcan and bottom edge of workspace.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.MARGIN_BOTTOM_ = 20;
                +
                +/**
                + * Distance between trashcan and right edge of workspace.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.MARGIN_SIDE_ = 20;
                +
                +/**
                + * Extent of hotspot on all sides beyond the size of the image.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.MARGIN_HOTSPOT_ = 10;
                +
                +/**
                + * Location of trashcan in sprite image.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.SPRITE_LEFT_ = 0;
                +
                +/**
                + * Location of trashcan in sprite image.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.SPRITE_TOP_ = 32;
                +
                +/**
                + * Current open/close state of the lid.
                + * @type {boolean}
                + */
                +Blockly.Trashcan.prototype.isOpen = false;
                +
                +/**
                + * The SVG group containing the trash can.
                + * @type {Element}
                + * @private
                + */
                +Blockly.Trashcan.prototype.svgGroup_ = null;
                +
                +/**
                + * The SVG image element of the trash can lid.
                + * @type {Element}
                + * @private
                + */
                +Blockly.Trashcan.prototype.svgLid_ = null;
                +
                +/**
                + * Task ID of opening/closing animation.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.lidTask_ = 0;
                +
                +/**
                + * Current state of lid opening (0.0 = closed, 1.0 = open).
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.lidOpen_ = 0;
                +
                +/**
                + * Left coordinate of the trash can.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.left_ = 0;
                +
                +/**
                + * Top coordinate of the trash can.
                + * @type {number}
                + * @private
                + */
                +Blockly.Trashcan.prototype.top_ = 0;
                +
                +/**
                + * Create the trash can elements.
                + * @return {!Element} The trash can's SVG group.
                + */
                +Blockly.Trashcan.prototype.createDom = function() {
                +  /* Here's the markup that will be generated:
                +  <g class="blocklyTrash">
                +    <clippath id="blocklyTrashBodyClipPath837493">
                +      <rect width="47" height="45" y="15"></rect>
                +    </clippath>
                +    <image width="64" height="92" y="-32" xlink:href="media/sprites.png"
                +        clip-path="url(#blocklyTrashBodyClipPath837493)"></image>
                +    <clippath id="blocklyTrashLidClipPath837493">
                +      <rect width="47" height="15"></rect>
                +    </clippath>
                +    <image width="84" height="92" y="-32" xlink:href="media/sprites.png"
                +        clip-path="url(#blocklyTrashLidClipPath837493)"></image>
                +  </g>
                +  */
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyTrash'}, null);
                +  var clip;
                +  var rnd = String(Math.random()).substring(2);
                +  clip = Blockly.utils.createSvgElement('clipPath',
                +      {'id': 'blocklyTrashBodyClipPath' + rnd},
                +      this.svgGroup_);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': this.WIDTH_, 'height': this.BODY_HEIGHT_,
                +       'y': this.LID_HEIGHT_},
                +      clip);
                +  var body = Blockly.utils.createSvgElement('image',
                +      {'width': Blockly.SPRITE.width, 'x': -this.SPRITE_LEFT_,
                +       'height': Blockly.SPRITE.height, 'y': -this.SPRITE_TOP_,
                +       'clip-path': 'url(#blocklyTrashBodyClipPath' + rnd + ')'},
                +      this.svgGroup_);
                +  body.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
                +      this.workspace_.options.pathToMedia + Blockly.SPRITE.url);
                +
                +  clip = Blockly.utils.createSvgElement('clipPath',
                +      {'id': 'blocklyTrashLidClipPath' + rnd},
                +      this.svgGroup_);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': this.WIDTH_, 'height': this.LID_HEIGHT_}, clip);
                +  this.svgLid_ = Blockly.utils.createSvgElement('image',
                +      {'width': Blockly.SPRITE.width, 'x': -this.SPRITE_LEFT_,
                +       'height': Blockly.SPRITE.height, 'y': -this.SPRITE_TOP_,
                +       'clip-path': 'url(#blocklyTrashLidClipPath' + rnd + ')'},
                +      this.svgGroup_);
                +  this.svgLid_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
                +      this.workspace_.options.pathToMedia + Blockly.SPRITE.url);
                +
                +  Blockly.bindEventWithChecks_(this.svgGroup_, 'mouseup', this, this.click);
                +  this.animateLid_();
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Initialize the trash can.
                + * @param {number} bottom Distance from workspace bottom to bottom of trashcan.
                + * @return {number} Distance from workspace bottom to the top of trashcan.
                + */
                +Blockly.Trashcan.prototype.init = function(bottom) {
                +  this.bottom_ = this.MARGIN_BOTTOM_ + bottom;
                +  this.setOpen_(false);
                +  return this.bottom_ + this.BODY_HEIGHT_ + this.LID_HEIGHT_;
                +};
                +
                +/**
                + * Dispose of this trash can.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.Trashcan.prototype.dispose = function() {
                +  if (this.svgGroup_) {
                +    goog.dom.removeNode(this.svgGroup_);
                +    this.svgGroup_ = null;
                +  }
                +  this.svgLid_ = null;
                +  this.workspace_ = null;
                +  goog.Timer.clear(this.lidTask_);
                +};
                +
                +/**
                + * Move the trash can to the bottom-right corner.
                + */
                +Blockly.Trashcan.prototype.position = function() {
                +  var metrics = this.workspace_.getMetrics();
                +  if (!metrics) {
                +    // There are no metrics available (workspace is probably not visible).
                +    return;
                +  }
                +  if (this.workspace_.RTL) {
                +    this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness;
                +    if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
                +      this.left_ += metrics.flyoutWidth;
                +      if (this.workspace_.toolbox_) {
                +        this.left_ += metrics.absoluteLeft;
                +      }
                +    }
                +  } else {
                +    this.left_ = metrics.viewWidth + metrics.absoluteLeft -
                +        this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness;
                +
                +    if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
                +      this.left_ -= metrics.flyoutWidth;
                +    }
                +  }
                +  this.top_ = metrics.viewHeight + metrics.absoluteTop -
                +      (this.BODY_HEIGHT_ + this.LID_HEIGHT_) - this.bottom_;
                +
                +  if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
                +    this.top_ -= metrics.flyoutHeight;
                +  }
                +  this.svgGroup_.setAttribute('transform',
                +      'translate(' + this.left_ + ',' + this.top_ + ')');
                +};
                +
                +/**
                + * Return the deletion rectangle for this trash can.
                + * @return {goog.math.Rect} Rectangle in which to delete.
                + */
                +Blockly.Trashcan.prototype.getClientRect = function() {
                +  if (!this.svgGroup_) {
                +    return null;
                +  }
                +
                +  var trashRect = this.svgGroup_.getBoundingClientRect();
                +  var left = trashRect.left + this.SPRITE_LEFT_ - this.MARGIN_HOTSPOT_;
                +  var top = trashRect.top + this.SPRITE_TOP_ - this.MARGIN_HOTSPOT_;
                +  var width = this.WIDTH_ + 2 * this.MARGIN_HOTSPOT_;
                +  var height = this.LID_HEIGHT_ + this.BODY_HEIGHT_ + 2 * this.MARGIN_HOTSPOT_;
                +  return new goog.math.Rect(left, top, width, height);
                +
                +};
                +
                +/**
                + * Flip the lid open or shut.
                + * @param {boolean} state True if open.
                + * @private
                + */
                +Blockly.Trashcan.prototype.setOpen_ = function(state) {
                +  if (this.isOpen == state) {
                +    return;
                +  }
                +  goog.Timer.clear(this.lidTask_);
                +  this.isOpen = state;
                +  this.animateLid_();
                +};
                +
                +/**
                + * Rotate the lid open or closed by one step.  Then wait and recurse.
                + * @private
                + */
                +Blockly.Trashcan.prototype.animateLid_ = function() {
                +  this.lidOpen_ += this.isOpen ? 0.2 : -0.2;
                +  this.lidOpen_ = goog.math.clamp(this.lidOpen_, 0, 1);
                +  var lidAngle = this.lidOpen_ * 45;
                +  this.svgLid_.setAttribute('transform', 'rotate(' +
                +      (this.workspace_.RTL ? -lidAngle : lidAngle) + ',' +
                +      (this.workspace_.RTL ? 4 : this.WIDTH_ - 4) + ',' +
                +      (this.LID_HEIGHT_ - 2) + ')');
                +  var opacity = goog.math.lerp(0.4, 0.8, this.lidOpen_);
                +  this.svgGroup_.style.opacity = opacity;
                +  if (this.lidOpen_ > 0 && this.lidOpen_ < 1) {
                +    this.lidTask_ = goog.Timer.callOnce(this.animateLid_, 20, this);
                +  }
                +};
                +
                +/**
                + * Flip the lid shut.
                + * Called externally after a drag.
                + */
                +Blockly.Trashcan.prototype.close = function() {
                +  this.setOpen_(false);
                +};
                +
                +/**
                + * Inspect the contents of the trash.
                + */
                +Blockly.Trashcan.prototype.click = function() {
                +  var dx = this.workspace_.startScrollX - this.workspace_.scrollX;
                +  var dy = this.workspace_.startScrollY - this.workspace_.scrollY;
                +  if (Math.sqrt(dx * dx + dy * dy) > Blockly.DRAG_RADIUS) {
                +    return;
                +  }
                +  console.log('TODO: Inspect trash.');
                +};
                diff --git a/blockly/webif/static/blockly/core/utils.js b/blockly/webif/static/blockly/core/utils.js
                new file mode 100644
                index 000000000..b578e6b71
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/utils.js
                @@ -0,0 +1,905 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Utility methods.
                + * These methods are not specific to Blockly, and could be factored out into
                + * a JavaScript framework such as Closure.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.utils
                + * @namespace
                + **/
                +goog.provide('Blockly.utils');
                +
                +goog.require('Blockly.Touch');
                +goog.require('goog.dom');
                +goog.require('goog.events.BrowserFeature');
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.userAgent');
                +
                +/**
                + * Remove an attribute from a element even if it's in IE 10.
                + * Similar to Element.removeAttribute() but it works on SVG elements in IE 10.
                + * Sets the attribute to null in IE 10, which treats removeAttribute as a no-op
                + * if it's called on an SVG element.
                + * @param {!Element} element DOM element to remove attribute from.
                + * @param {string} attributeName Name of attribute to remove.
                + */
                +Blockly.utils.removeAttribute = function(element, attributeName) {
                +  // goog.userAgent.isVersion is deprecated, but the replacement is
                +  // goog.userAgent.isVersionOrHigher.
                +  if (goog.userAgent.IE && goog.userAgent.isVersion('10.0')) {
                +    element.setAttribute(attributeName, null);
                +  } else {
                +    element.removeAttribute(attributeName);
                +  }
                +};
                +
                +/**
                + * Add a CSS class to a element.
                + * Similar to Closure's goog.dom.classes.add, except it handles SVG elements.
                + * @param {!Element} element DOM element to add class to.
                + * @param {string} className Name of class to add.
                + * @return {boolean} True if class was added, false if already present.
                + */
                +Blockly.utils.addClass = function(element, className) {
                +  var classes = element.getAttribute('class') || '';
                +  if ((' ' + classes + ' ').indexOf(' ' + className + ' ') != -1) {
                +    return false;
                +  }
                +  if (classes) {
                +    classes += ' ';
                +  }
                +  element.setAttribute('class', classes + className);
                +  return true;
                +};
                +
                +/**
                + * Remove a CSS class from a element.
                + * Similar to Closure's goog.dom.classes.remove, except it handles SVG elements.
                + * @param {!Element} element DOM element to remove class from.
                + * @param {string} className Name of class to remove.
                + * @return {boolean} True if class was removed, false if never present.
                + */
                +Blockly.utils.removeClass = function(element, className) {
                +  var classes = element.getAttribute('class');
                +  if ((' ' + classes + ' ').indexOf(' ' + className + ' ') == -1) {
                +    return false;
                +  }
                +  var classList = classes.split(/\s+/);
                +  for (var i = 0; i < classList.length; i++) {
                +    if (!classList[i] || classList[i] == className) {
                +      classList.splice(i, 1);
                +      i--;
                +    }
                +  }
                +  if (classList.length) {
                +    element.setAttribute('class', classList.join(' '));
                +  } else {
                +    Blockly.utils.removeAttribute(element, 'class');
                +  }
                +  return true;
                +};
                +
                +/**
                + * Checks if an element has the specified CSS class.
                + * Similar to Closure's goog.dom.classes.has, except it handles SVG elements.
                + * @param {!Element} element DOM element to check.
                + * @param {string} className Name of class to check.
                + * @return {boolean} True if class exists, false otherwise.
                + * @private
                + */
                +Blockly.utils.hasClass = function(element, className) {
                +  var classes = element.getAttribute('class');
                +  return (' ' + classes + ' ').indexOf(' ' + className + ' ') != -1;
                +};
                +
                +/**
                + * Don't do anything for this event, just halt propagation.
                + * @param {!Event} e An event.
                + */
                +Blockly.utils.noEvent = function(e) {
                +  // This event has been handled.  No need to bubble up to the document.
                +  e.preventDefault();
                +  e.stopPropagation();
                +};
                +
                +/**
                + * Is this event targeting a text input widget?
                + * @param {!Event} e An event.
                + * @return {boolean} True if text input.
                + */
                +Blockly.utils.isTargetInput = function(e) {
                +  return e.target.type == 'textarea' || e.target.type == 'text' ||
                +         e.target.type == 'number' || e.target.type == 'email' ||
                +         e.target.type == 'password' || e.target.type == 'search' ||
                +         e.target.type == 'tel' || e.target.type == 'url' ||
                +         e.target.isContentEditable;
                +};
                +
                +/**
                + * Return the coordinates of the top-left corner of this element relative to
                + * its parent.  Only for SVG elements and children (e.g. rect, g, path).
                + * @param {!Element} element SVG element to find the coordinates of.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties.
                + */
                +Blockly.utils.getRelativeXY = function(element) {
                +  var xy = new goog.math.Coordinate(0, 0);
                +  // First, check for x and y attributes.
                +  var x = element.getAttribute('x');
                +  if (x) {
                +    xy.x = parseInt(x, 10);
                +  }
                +  var y = element.getAttribute('y');
                +  if (y) {
                +    xy.y = parseInt(y, 10);
                +  }
                +  // Second, check for transform="translate(...)" attribute.
                +  var transform = element.getAttribute('transform');
                +  var r = transform && transform.match(Blockly.utils.getRelativeXY.XY_REGEX_);
                +  if (r) {
                +    xy.x += parseFloat(r[1]);
                +    if (r[3]) {
                +      xy.y += parseFloat(r[3]);
                +    }
                +  }
                +
                +  // Then check for style = transform: translate(...) or translate3d(...)
                +  var style = element.getAttribute('style');
                +  if (style && style.indexOf('translate') > -1) {
                +    var styleComponents = style.match(Blockly.utils.getRelativeXY.XY_2D_REGEX_);
                +    // Try transform3d if 2d transform wasn't there.
                +    if (!styleComponents) {
                +      styleComponents = style.match(Blockly.utils.getRelativeXY.XY_3D_REGEX_);
                +    }
                +    if (styleComponents) {
                +      xy.x += parseFloat(styleComponents[1]);
                +      if (styleComponents[3]) {
                +        xy.y += parseFloat(styleComponents[3]);
                +      }
                +    }
                +  }
                +  return xy;
                +};
                +
                +/**
                + * Return the coordinates of the top-left corner of this element relative to
                + * the div blockly was injected into.
                + * @param {!Element} element SVG element to find the coordinates of. If this is
                + *     not a child of the div blockly was injected into, the behaviour is
                + *     undefined.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties.
                + */
                +Blockly.utils.getInjectionDivXY_ = function(element) {
                +  var x = 0;
                +  var y = 0;
                +  var scale = 1;
                +  while (element) {
                +    var xy = Blockly.utils.getRelativeXY(element);
                +    scale = Blockly.utils.getScale_(element);
                +    x = (x * scale) + xy.x;
                +    y = (y * scale) + xy.y;
                +    var classes = element.getAttribute('class') || '';
                +    if ((' ' + classes + ' ').indexOf(' injectionDiv ') != -1) {
                +      break;
                +    }
                +    element = element.parentNode;
                +  }
                +  return new goog.math.Coordinate(x, y);
                +};
                +
                +/**
                + * Return the scale of this element.
                + * @param {!Element} element  The element to find the coordinates of.
                + * @return {!number} number represending the scale applied to the element.
                + * @private
                + */
                +Blockly.utils.getScale_ = function(element) {
                +  var scale = 1;
                +  var transform = element.getAttribute('transform');
                +  if (transform) {
                +    var transformComponents =
                +        transform.match(Blockly.utils.getScale_.REGEXP_);
                +    if (transformComponents && transformComponents[0]) {
                +      scale = parseFloat(transformComponents[0]);
                +    }
                +  }
                +  return scale;
                +};
                +
                +/**
                + * Static regex to pull the x,y values out of an SVG translate() directive.
                + * Note that Firefox and IE (9,10) return 'translate(12)' instead of
                + * 'translate(12, 0)'.
                + * Note that IE (9,10) returns 'translate(16 8)' instead of 'translate(16, 8)'.
                + * Note that IE has been reported to return scientific notation (0.123456e-42).
                + * @type {!RegExp}
                + * @private
                + */
                +Blockly.utils.getRelativeXY.XY_REGEX_ =
                +    /translate\(\s*([-+\d.e]+)([ ,]\s*([-+\d.e]+)\s*\))?/;
                +
                +
                +/**
                + * Static regex to pull the scale values out of a transform style property.
                + * Accounts for same exceptions as XY_REGEXP_.
                + * @type {!RegExp}
                + * @private
                + */
                +Blockly.utils.getScale_REGEXP_ = /scale\(\s*([-+\d.e]+)\s*\)/;
                +
                +/**
                + * Static regex to pull the x,y,z values out of a translate3d() style property.
                + * Accounts for same exceptions as XY_REGEXP_.
                + * @type {!RegExp}
                + * @private
                + */
                +Blockly.utils.getRelativeXY.XY_3D_REGEX_ =
                +  /transform:\s*translate3d\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;
                +
                +/**
                + * Static regex to pull the x,y,z values out of a translate3d() style property.
                + * Accounts for same exceptions as XY_REGEXP_.
                + * @type {!RegExp}
                + * @private
                + */
                +Blockly.utils.getRelativeXY.XY_2D_REGEX_ =
                +  /transform:\s*translate\(\s*([-+\d.e]+)px([ ,]\s*([-+\d.e]+)\s*)px\)?/;
                +
                +/**
                + * Helper method for creating SVG elements.
                + * @param {string} name Element's tag name.
                + * @param {!Object} attrs Dictionary of attribute names and values.
                + * @param {Element} parent Optional parent on which to append the element.
                + * @param {Blockly.Workspace=} opt_workspace Optional workspace for access to
                + *     context (scale...).
                + * @return {!SVGElement} Newly created SVG element.
                + */
                +Blockly.utils.createSvgElement = function(name, attrs, parent /*, opt_workspace */) {
                +  var e = /** @type {!SVGElement} */ (
                +      document.createElementNS(Blockly.SVG_NS, name));
                +  for (var key in attrs) {
                +    e.setAttribute(key, attrs[key]);
                +  }
                +  // IE defines a unique attribute "runtimeStyle", it is NOT applied to
                +  // elements created with createElementNS. However, Closure checks for IE
                +  // and assumes the presence of the attribute and crashes.
                +  if (document.body.runtimeStyle) {  // Indicates presence of IE-only attr.
                +    e.runtimeStyle = e.currentStyle = e.style;
                +  }
                +  if (parent) {
                +    parent.appendChild(e);
                +  }
                +  return e;
                +};
                +
                +/**
                + * Is this event a right-click?
                + * @param {!Event} e Mouse event.
                + * @return {boolean} True if right-click.
                + */
                +Blockly.utils.isRightButton = function(e) {
                +  if (e.ctrlKey && goog.userAgent.MAC) {
                +    // Control-clicking on Mac OS X is treated as a right-click.
                +    // WebKit on Mac OS X fails to change button to 2 (but Gecko does).
                +    return true;
                +  }
                +  return e.button == 2;
                +};
                +
                +/**
                + * Return the converted coordinates of the given mouse event.
                + * The origin (0,0) is the top-left corner of the Blockly SVG.
                + * @param {!Event} e Mouse event.
                + * @param {!Element} svg SVG element.
                + * @param {SVGMatrix} matrix Inverted screen CTM to use.
                + * @return {!Object} Object with .x and .y properties.
                + */
                +Blockly.utils.mouseToSvg = function(e, svg, matrix) {
                +  var svgPoint = svg.createSVGPoint();
                +  svgPoint.x = e.clientX;
                +  svgPoint.y = e.clientY;
                +
                +  if (!matrix) {
                +    matrix = svg.getScreenCTM().inverse();
                +  }
                +  return svgPoint.matrixTransform(matrix);
                +};
                +
                +/**
                + * Given an array of strings, return the length of the shortest one.
                + * @param {!Array.<string>} array Array of strings.
                + * @return {number} Length of shortest string.
                + */
                +Blockly.utils.shortestStringLength = function(array) {
                +  if (!array.length) {
                +    return 0;
                +  }
                +  return array.reduce(function(a, b) {
                +    return a.length < b.length ? a : b;
                +  }).length;
                +};
                +
                +/**
                + * Given an array of strings, return the length of the common prefix.
                + * Words may not be split.  Any space after a word is included in the length.
                + * @param {!Array.<string>} array Array of strings.
                + * @param {number=} opt_shortest Length of shortest string.
                + * @return {number} Length of common prefix.
                + */
                +Blockly.utils.commonWordPrefix = function(array, opt_shortest) {
                +  if (!array.length) {
                +    return 0;
                +  } else if (array.length == 1) {
                +    return array[0].length;
                +  }
                +  var wordPrefix = 0;
                +  var max = opt_shortest || Blockly.utils.shortestStringLength(array);
                +  for (var len = 0; len < max; len++) {
                +    var letter = array[0][len];
                +    for (var i = 1; i < array.length; i++) {
                +      if (letter != array[i][len]) {
                +        return wordPrefix;
                +      }
                +    }
                +    if (letter == ' ') {
                +      wordPrefix = len + 1;
                +    }
                +  }
                +  for (var i = 1; i < array.length; i++) {
                +    var letter = array[i][len];
                +    if (letter && letter != ' ') {
                +      return wordPrefix;
                +    }
                +  }
                +  return max;
                +};
                +
                +/**
                + * Given an array of strings, return the length of the common suffix.
                + * Words may not be split.  Any space after a word is included in the length.
                + * @param {!Array.<string>} array Array of strings.
                + * @param {number=} opt_shortest Length of shortest string.
                + * @return {number} Length of common suffix.
                + */
                +Blockly.utils.commonWordSuffix = function(array, opt_shortest) {
                +  if (!array.length) {
                +    return 0;
                +  } else if (array.length == 1) {
                +    return array[0].length;
                +  }
                +  var wordPrefix = 0;
                +  var max = opt_shortest || Blockly.utils.shortestStringLength(array);
                +  for (var len = 0; len < max; len++) {
                +    var letter = array[0].substr(-len - 1, 1);
                +    for (var i = 1; i < array.length; i++) {
                +      if (letter != array[i].substr(-len - 1, 1)) {
                +        return wordPrefix;
                +      }
                +    }
                +    if (letter == ' ') {
                +      wordPrefix = len + 1;
                +    }
                +  }
                +  for (var i = 1; i < array.length; i++) {
                +    var letter = array[i].charAt(array[i].length - len - 1);
                +    if (letter && letter != ' ') {
                +      return wordPrefix;
                +    }
                +  }
                +  return max;
                +};
                +
                +/**
                + * Parse a string with any number of interpolation tokens (%1, %2, ...).
                + * It will also replace string table references (e.g., %{bky_my_msg} and
                + * %{BKY_MY_MSG} will both be replaced with the value in
                + * Blockly.Msg['MY_MSG']). Percentage sign characters '%' may be self-escaped
                + * (e.g., '%%').
                + * @param {string} message Text which might contain string table references and
                + *     interpolation tokens.
                + * @return {!Array.<string|number>} Array of strings and numbers.
                + */
                +Blockly.utils.tokenizeInterpolation = function(message) {
                +  return Blockly.utils.tokenizeInterpolation_(message, true);
                +};
                +
                +/**
                + * Replaces string table references in a message, if the message is a string.
                + * For example, "%{bky_my_msg}" and "%{BKY_MY_MSG}" will both be replaced with
                + * the value in Blockly.Msg['MY_MSG'].
                + * @param {string|?} message Message, which may be a string that contains
                + *                           string table references.
                + * @return {!string} String with message references replaced.
                + */
                +Blockly.utils.replaceMessageReferences = function(message) {
                +  if (!goog.isString(message)) {
                +    return message;
                +  }
                +  var interpolatedResult = Blockly.utils.tokenizeInterpolation_(message, false);
                +  // When parseInterpolationTokens == false, interpolatedResult should be at
                +  // most length 1.
                +  return interpolatedResult.length ? interpolatedResult[0] : "";
                +};
                +
                +/**
                + * Validates that any %{BKY_...} references in the message refer to keys of
                + * the Blockly.Msg string table.
                + * @param {string} message Text which might contain string table references.
                + * @return {boolean} True if all message references have matching values.
                + *     Otherwise, false.
                + */
                +Blockly.utils.checkMessageReferences = function(message) {
                +  var isValid = true; // True until a bad reference is found
                +
                +  var regex = /%{BKY_([a-zA-Z][a-zA-Z0-9_]*)}/g;
                +  var match = regex.exec(message);
                +  while (match != null) {
                +    var msgKey = match[1];
                +    if (Blockly.Msg[msgKey] == null) {
                +      console.log('WARNING: No message string for %{BKY_' + msgKey + '}.');
                +      isValid = false;
                +    }
                +
                +    // Re-run on remainder of sting.
                +    message = message.substring(match.index + msgKey.length + 1);
                +    match = regex.exec(message);
                +  }
                +
                +  return isValid;
                +};
                +
                +/**
                + * Internal implemention of the message reference and interpolation token
                + * parsing used by tokenizeInterpolation() and replaceMessageReferences().
                + * @param {string} message Text which might contain string table references and
                + *     interpolation tokens.
                + * @param {boolean} parseInterpolationTokens Option to parse numeric
                + *     interpolation tokens (%1, %2, ...) when true.
                + * @return {!Array.<string|number>} Array of strings and numbers.
                + * @private
                + */
                +Blockly.utils.tokenizeInterpolation_ = function(message, parseInterpolationTokens) {
                +  var tokens = [];
                +  var chars = message.split('');
                +  chars.push('');  // End marker.
                +  // Parse the message with a finite state machine.
                +  // 0 - Base case.
                +  // 1 - % found.
                +  // 2 - Digit found.
                +  // 3 - Message ref found
                +  var state = 0;
                +  var buffer = [];
                +  var number = null;
                +  for (var i = 0; i < chars.length; i++) {
                +    var c = chars[i];
                +    if (state == 0) {
                +      if (c == '%') {
                +        var text = buffer.join('');
                +        if (text) {
                +          tokens.push(text);
                +        }
                +        buffer.length = 0;
                +        state = 1;  // Start escape.
                +      } else {
                +        buffer.push(c);  // Regular char.
                +      }
                +    } else if (state == 1) {
                +      if (c == '%') {
                +        buffer.push(c);  // Escaped %: %%
                +        state = 0;
                +      } else if (parseInterpolationTokens && '0' <= c && c <= '9') {
                +        state = 2;
                +        number = c;
                +        var text = buffer.join('');
                +        if (text) {
                +          tokens.push(text);
                +        }
                +        buffer.length = 0;
                +      } else if (c == '{') {
                +        state = 3;
                +      } else {
                +        buffer.push('%', c);  // Not recognized. Return as literal.
                +        state = 0;
                +      }
                +    } else if (state == 2) {
                +      if ('0' <= c && c <= '9') {
                +        number += c;  // Multi-digit number.
                +      } else {
                +        tokens.push(parseInt(number, 10));
                +        i--;  // Parse this char again.
                +        state = 0;
                +      }
                +    } else if (state == 3) {  // String table reference
                +      if (c == '') {
                +        // Premature end before closing '}'
                +        buffer.splice(0, 0, '%{'); // Re-insert leading delimiter
                +        i--;  // Parse this char again.
                +        state = 0; // and parse as string literal.
                +      } else if (c != '}') {
                +        buffer.push(c);
                +      } else  {
                +        var rawKey = buffer.join('');
                +        if (/[a-zA-Z][a-zA-Z0-9_]*/.test(rawKey)) {  // Strict matching
                +          // Found a valid string key. Attempt case insensitive match.
                +          var keyUpper = rawKey.toUpperCase();
                +
                +          // BKY_ is the prefix used to namespace the strings used in Blockly
                +          // core files and the predefined blocks in ../blocks/. These strings
                +          // are defined in ../msgs/ files.
                +          var bklyKey = goog.string.startsWith(keyUpper, 'BKY_') ?
                +              keyUpper.substring(4) : null;
                +          if (bklyKey && bklyKey in Blockly.Msg) {
                +            var rawValue = Blockly.Msg[bklyKey];
                +            if (goog.isString(rawValue)) {
                +              // Attempt to dereference substrings, too, appending to the end.
                +              Array.prototype.push.apply(tokens,
                +                Blockly.utils.tokenizeInterpolation(rawValue));
                +            } else if (parseInterpolationTokens) {
                +              // When parsing interpolation tokens, numbers are special
                +              // placeholders (%1, %2, etc). Make sure all other values are
                +              // strings.
                +              tokens.push(String(rawValue));
                +            } else {
                +              tokens.push(rawValue);
                +            }
                +          } else {
                +            // No entry found in the string table. Pass reference as string.
                +            tokens.push('%{' + rawKey + '}');
                +          }
                +          buffer.length = 0;  // Clear the array
                +          state = 0;
                +        } else {
                +          tokens.push('%{' + rawKey + '}');
                +          buffer.length = 0;
                +          state = 0; // and parse as string literal.
                +        }
                +      }
                +    }
                +  }
                +  var text = buffer.join('');
                +  if (text) {
                +    tokens.push(text);
                +  }
                +
                +  // Merge adjacent text tokens into a single string.
                +  var mergedTokens = [];
                +  buffer.length = 0;
                +  for (var i = 0; i < tokens.length; ++i) {
                +    if (typeof tokens[i] == 'string') {
                +      buffer.push(tokens[i]);
                +    } else {
                +      text = buffer.join('');
                +      if (text) {
                +        mergedTokens.push(text);
                +      }
                +      buffer.length = 0;
                +      mergedTokens.push(tokens[i]);
                +    }
                +  }
                +  text = buffer.join('');
                +  if (text) {
                +    mergedTokens.push(text);
                +  }
                +  buffer.length = 0;
                +
                +  return mergedTokens;
                +};
                +
                +/**
                + * Generate a unique ID.  This should be globally unique.
                + * 87 characters ^ 20 length > 128 bits (better than a UUID).
                + * @return {string} A globally unique ID string.
                + */
                +Blockly.utils.genUid = function() {
                +  var length = 20;
                +  var soupLength = Blockly.utils.genUid.soup_.length;
                +  var id = [];
                +  for (var i = 0; i < length; i++) {
                +    id[i] = Blockly.utils.genUid.soup_.charAt(Math.random() * soupLength);
                +  }
                +  return id.join('');
                +};
                +
                +/**
                + * Legal characters for the unique ID.  Should be all on a US keyboard.
                + * No characters that conflict with XML or JSON.  Requests to remove additional
                + * 'problematic' characters from this soup will be denied.  That's your failure
                + * to properly escape in your own environment.  Issues #251, #625, #682.
                + * @private
                + */
                +Blockly.utils.genUid.soup_ = '!#$%()*+,-./:;=?@[]^_`{|}~' +
                +    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                +
                +/**
                + * Wrap text to the specified width.
                + * @param {string} text Text to wrap.
                + * @param {number} limit Width to wrap each line.
                + * @return {string} Wrapped text.
                + */
                +Blockly.utils.wrap = function(text, limit) {
                +  var lines = text.split('\n');
                +  for (var i = 0; i < lines.length; i++) {
                +    lines[i] = Blockly.utils.wrapLine_(lines[i], limit);
                +  }
                +  return lines.join('\n');
                +};
                +
                +/**
                + * Wrap single line of text to the specified width.
                + * @param {string} text Text to wrap.
                + * @param {number} limit Width to wrap each line.
                + * @return {string} Wrapped text.
                + * @private
                + */
                +Blockly.utils.wrapLine_ = function(text, limit) {
                +  if (text.length <= limit) {
                +    // Short text, no need to wrap.
                +    return text;
                +  }
                +  // Split the text into words.
                +  var words = text.trim().split(/\s+/);
                +  // Set limit to be the length of the largest word.
                +  for (var i = 0; i < words.length; i++) {
                +    if (words[i].length > limit) {
                +      limit = words[i].length;
                +    }
                +  }
                +
                +  var lastScore;
                +  var score = -Infinity;
                +  var lastText;
                +  var lineCount = 1;
                +  do {
                +    lastScore = score;
                +    lastText = text;
                +    // Create a list of booleans representing if a space (false) or
                +    // a break (true) appears after each word.
                +    var wordBreaks = [];
                +    // Seed the list with evenly spaced linebreaks.
                +    var steps = words.length / lineCount;
                +    var insertedBreaks = 1;
                +    for (var i = 0; i < words.length - 1; i++) {
                +      if (insertedBreaks < (i + 1.5) / steps) {
                +        insertedBreaks++;
                +        wordBreaks[i] = true;
                +      } else {
                +        wordBreaks[i] = false;
                +      }
                +    }
                +    wordBreaks = Blockly.utils.wrapMutate_(words, wordBreaks, limit);
                +    score = Blockly.utils.wrapScore_(words, wordBreaks, limit);
                +    text = Blockly.utils.wrapToText_(words, wordBreaks);
                +    lineCount++;
                +  } while (score > lastScore);
                +  return lastText;
                +};
                +
                +/**
                + * Compute a score for how good the wrapping is.
                + * @param {!Array.<string>} words Array of each word.
                + * @param {!Array.<boolean>} wordBreaks Array of line breaks.
                + * @param {number} limit Width to wrap each line.
                + * @return {number} Larger the better.
                + * @private
                + */
                +Blockly.utils.wrapScore_ = function(words, wordBreaks, limit) {
                +  // If this function becomes a performance liability, add caching.
                +  // Compute the length of each line.
                +  var lineLengths = [0];
                +  var linePunctuation = [];
                +  for (var i = 0; i < words.length; i++) {
                +    lineLengths[lineLengths.length - 1] += words[i].length;
                +    if (wordBreaks[i] === true) {
                +      lineLengths.push(0);
                +      linePunctuation.push(words[i].charAt(words[i].length - 1));
                +    } else if (wordBreaks[i] === false) {
                +      lineLengths[lineLengths.length - 1]++;
                +    }
                +  }
                +  var maxLength = Math.max.apply(Math, lineLengths);
                +
                +  var score = 0;
                +  for (var i = 0; i < lineLengths.length; i++) {
                +    // Optimize for width.
                +    // -2 points per char over limit (scaled to the power of 1.5).
                +    score -= Math.pow(Math.abs(limit - lineLengths[i]), 1.5) * 2;
                +    // Optimize for even lines.
                +    // -1 point per char smaller than max (scaled to the power of 1.5).
                +    score -= Math.pow(maxLength - lineLengths[i], 1.5);
                +    // Optimize for structure.
                +    // Add score to line endings after punctuation.
                +    if ('.?!'.indexOf(linePunctuation[i]) != -1) {
                +      score += limit / 3;
                +    } else if (',;)]}'.indexOf(linePunctuation[i]) != -1) {
                +      score += limit / 4;
                +    }
                +  }
                +  // All else being equal, the last line should not be longer than the
                +  // previous line.  For example, this looks wrong:
                +  // aaa bbb
                +  // ccc ddd eee
                +  if (lineLengths.length > 1 && lineLengths[lineLengths.length - 1] <=
                +      lineLengths[lineLengths.length - 2]) {
                +    score += 0.5;
                +  }
                +  return score;
                +};
                +
                +/**
                + * Mutate the array of line break locations until an optimal solution is found.
                + * No line breaks are added or deleted, they are simply moved around.
                + * @param {!Array.<string>} words Array of each word.
                + * @param {!Array.<boolean>} wordBreaks Array of line breaks.
                + * @param {number} limit Width to wrap each line.
                + * @return {!Array.<boolean>} New array of optimal line breaks.
                + * @private
                + */
                +Blockly.utils.wrapMutate_ = function(words, wordBreaks, limit) {
                +  var bestScore = Blockly.utils.wrapScore_(words, wordBreaks, limit);
                +  var bestBreaks;
                +  // Try shifting every line break forward or backward.
                +  for (var i = 0; i < wordBreaks.length - 1; i++) {
                +    if (wordBreaks[i] == wordBreaks[i + 1]) {
                +      continue;
                +    }
                +    var mutatedWordBreaks = [].concat(wordBreaks);
                +    mutatedWordBreaks[i] = !mutatedWordBreaks[i];
                +    mutatedWordBreaks[i + 1] = !mutatedWordBreaks[i + 1];
                +    var mutatedScore =
                +        Blockly.utils.wrapScore_(words, mutatedWordBreaks, limit);
                +    if (mutatedScore > bestScore) {
                +      bestScore = mutatedScore;
                +      bestBreaks = mutatedWordBreaks;
                +    }
                +  }
                +  if (bestBreaks) {
                +    // Found an improvement.  See if it may be improved further.
                +    return Blockly.utils.wrapMutate_(words, bestBreaks, limit);
                +  }
                +  // No improvements found.  Done.
                +  return wordBreaks;
                +};
                +
                +/**
                + * Reassemble the array of words into text, with the specified line breaks.
                + * @param {!Array.<string>} words Array of each word.
                + * @param {!Array.<boolean>} wordBreaks Array of line breaks.
                + * @return {string} Plain text.
                + * @private
                + */
                +Blockly.utils.wrapToText_ = function(words, wordBreaks) {
                +  var text = [];
                +  for (var i = 0; i < words.length; i++) {
                +    text.push(words[i]);
                +    if (wordBreaks[i] !== undefined) {
                +      text.push(wordBreaks[i] ? '\n' : ' ');
                +    }
                +  }
                +  return text.join('');
                +};
                +
                +/**
                + * Check if 3D transforms are supported by adding an element
                + * and attempting to set the property.
                + * @return {boolean} true if 3D transforms are supported.
                + */
                +Blockly.utils.is3dSupported = function() {
                +  if (Blockly.utils.is3dSupported.cached_ !== undefined) {
                +    return Blockly.utils.is3dSupported.cached_;
                +  }
                +  // CC-BY-SA Lorenzo Polidori
                +  // stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
                +  if (!goog.global.getComputedStyle) {
                +    return false;
                +  }
                +
                +  var el = document.createElement('p');
                +  var has3d = 'none';
                +  var transforms = {
                +    'webkitTransform': '-webkit-transform',
                +    'OTransform': '-o-transform',
                +    'msTransform': '-ms-transform',
                +    'MozTransform': '-moz-transform',
                +    'transform': 'transform'
                +  };
                +
                +  // Add it to the body to get the computed style.
                +  document.body.insertBefore(el, null);
                +
                +  for (var t in transforms) {
                +    if (el.style[t] !== undefined) {
                +      el.style[t] = 'translate3d(1px,1px,1px)';
                +      var computedStyle = goog.global.getComputedStyle(el);
                +      if (!computedStyle) {
                +        // getComputedStyle in Firefox returns null when blockly is loaded
                +        // inside an iframe with display: none.  Returning false and not
                +        // caching is3dSupported means we try again later.  This is most likely
                +        // when users are interacting with blocks which should mean blockly is
                +        // visible again.
                +        // See https://bugzilla.mozilla.org/show_bug.cgi?id=548397
                +        document.body.removeChild(el);
                +        return false;
                +      }
                +      has3d = computedStyle.getPropertyValue(transforms[t]);
                +    }
                +  }
                +  document.body.removeChild(el);
                +  Blockly.utils.is3dSupported.cached_ = has3d !== 'none';
                +  return Blockly.utils.is3dSupported.cached_;
                +};
                +
                +/**
                + * Insert a node after a reference node.
                + * Contrast with node.insertBefore function.
                + * @param {!Element} newNode New element to insert.
                + * @param {!Element} refNode Existing element to precede new node.
                + * @private
                + */
                +Blockly.utils.insertAfter_ = function(newNode, refNode) {
                +  var siblingNode = refNode.nextSibling;
                +  var parentNode = refNode.parentNode;
                +  if (!parentNode) {
                +    throw 'Reference node has no parent.';
                +  }
                +  if (siblingNode) {
                +    parentNode.insertBefore(newNode, siblingNode);
                +  } else {
                +    parentNode.appendChild(newNode);
                +  }
                +};
                +
                +/**
                + * Calls a function after the page has loaded, possibly immediately.
                + * @param {function()} fn Function to run.
                + * @throws Error Will throw if no global document can be found (e.g., Node.js).
                + */
                +Blockly.utils.runAfterPageLoad = function(fn) {
                +  if (!document) {
                +    throw new Error('Blockly.utils.runAfterPageLoad() requires browser document.');
                +  }
                +  if (document.readyState === 'complete') {
                +    fn();  // Page has already loaded. Call immediately.
                +  } else {
                +    // Poll readyState.
                +    var readyStateCheckInterval = setInterval(function() {
                +      if (document.readyState === 'complete') {
                +        clearInterval(readyStateCheckInterval);
                +        fn();
                +      }
                +    }, 10);
                +  }
                +};
                +
                +/**
                + * Sets the CSS transform property on an element. This function sets the
                + * non-vendor-prefixed and vendor-prefixed versions for backwards compatibility
                + * with older browsers. See http://caniuse.com/#feat=transforms2d
                + * @param {!Element} node The node which the CSS transform should be applied.
                + * @param {string} transform The value of the CSS `transform` property.
                + */
                +Blockly.utils.setCssTransform = function(node, transform) {
                +  node.style['transform'] = transform;
                +  node.style['-webkit-transform'] = transform;
                +};
                diff --git a/blockly/webif/static/blockly/core/variable_map.js b/blockly/webif/static/blockly/core/variable_map.js
                new file mode 100644
                index 000000000..0eb2a9154
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/variable_map.js
                @@ -0,0 +1,238 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Object representing a map of variables and their types.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.VariableMap');
                +
                +/**
                + * Class for a variable map.  This contains a dictionary data structure with
                + * variable types as keys and lists of variables as values.  The list of
                + * variables are the type indicated by the key.
                + * @param {!Blockly.Workspace} workspace The workspace this map belongs to.
                + * @constructor
                + */
                + Blockly.VariableMap = function(workspace) {
                + /**
                +   * @type {!Object<string, !Array.<Blockly.VariableModel>>}
                +   * A map from variable type to list of variable names.  The lists contain all
                +   * of the named variables in the workspace, including variables
                +   * that are not currently in use.
                +   * @private
                +   */
                +  this.variableMap_ = {};
                +
                +  /**
                +   * The workspace this map belongs to.
                +   * @type {!Blockly.Workspace}
                +   */
                +  this.workspace = workspace;
                +};
                +
                +/**
                + * Clear the variable map.
                + */
                +Blockly.VariableMap.prototype.clear = function() {
                +  this.variableMap_ = new Object(null);
                +};
                +
                +/**
                + * Rename the given variable by updating its name in the variable map.
                + * @param {?Blockly.VariableModel} variable Variable to rename.
                + * @param {string} newName New variable name.
                + */
                +Blockly.VariableMap.prototype.renameVariable = function(variable, newName) {
                +  var newVariable = this.getVariable(newName);
                +  var variableIndex = -1;
                +  var newVariableIndex = -1;
                +  var type = '';
                +  if (variable || newVariable) {
                +    type = (variable || newVariable).type;
                +  }
                +
                +  var variableList = this.getVariablesOfType(type);
                +  if (variable) {
                +    variableIndex = variableList.indexOf(variable);
                +  }
                +  if (newVariable){ // see if I can get rid of newVariable dependency
                +    newVariableIndex = variableList.indexOf(newVariable);
                +  }
                +
                +  if (variableIndex == -1 && newVariableIndex == -1) {
                +    this.createVariable(newName, '');
                +    console.log('Tried to rename an non-existent variable.');
                +  } else if (variableIndex == newVariableIndex ||
                +      variableIndex != -1 && newVariableIndex == -1) {
                +    // Only changing case, or renaming to a completely novel name.
                +    var variableToRename = this.variableMap_[type][variableIndex];
                +    Blockly.Events.fire(new Blockly.Events.VarRename(variableToRename,
                +      newName));
                +    variableToRename.name = newName;
                +  } else if (variableIndex != -1 && newVariableIndex != -1) {
                +    // Renaming one existing variable to another existing variable.
                +    // The case might have changed, so we update the destination ID.
                +    var variableToRename = this.variableMap_[type][newVariableIndex];
                +    Blockly.Events.fire(new Blockly.Events.VarRename(variableToRename,
                +      newName));
                +    var variableToDelete = this.variableMap_[type][variableIndex];
                +    Blockly.Events.fire(new Blockly.Events.VarDelete(variableToDelete));
                +    variableToRename.name = newName;
                +    this.variableMap_[type].splice(variableIndex, 1);
                +  }
                +};
                +
                +/**
                + * Create a variable with a given name, optional type, and optional id.
                + * @param {!string} name The name of the variable. This must be unique across
                + *     variables and procedures.
                + * @param {?string} opt_type The type of the variable like 'int' or 'string'.
                + *     Does not need to be unique. Field_variable can filter variables based on
                + *     their type. This will default to '' which is a specific type.
                + * @param {?string} opt_id The unique id of the variable. This will default to
                + *     a UUID.
                + * @return {?Blockly.VariableModel} The newly created variable.
                + */
                +Blockly.VariableMap.prototype.createVariable = function(name, opt_type, opt_id) {
                +  var variable = this.getVariable(name);
                +  if (variable) {
                +    if (opt_type && variable.type != opt_type) {
                +      throw Error('Variable "' + name + '" is already in use and its type is "'
                +                  + variable.type + '" which conflicts with the passed in ' +
                +                  'type, "' + opt_type + '".');
                +    }
                +    if (opt_id && variable.getId() != opt_id) {
                +      throw Error('Variable "' + name + '" is already in use and its id is "'
                +                  + variable.getId() + '" which conflicts with the passed in ' +
                +                  'id, "' + opt_id + '".');
                +    }
                +    // The variable already exists and has the same id and type.
                +    return variable;
                +  }
                +  if (opt_id && this.getVariableById(opt_id)) {
                +    throw Error('Variable id, "' + opt_id + '", is already in use.');
                +  }
                +  opt_id = opt_id || Blockly.utils.genUid();
                +  opt_type = opt_type || '';
                +
                +  variable = new Blockly.VariableModel(this.workspace, name, opt_type, opt_id);
                +  // If opt_type is not a key, create a new list.
                +  if (!this.variableMap_[opt_type]) {
                +    this.variableMap_[opt_type] = [variable];
                +  } else {
                +  // Else append the variable to the preexisting list.
                +    this.variableMap_[opt_type].push(variable);
                +  }
                +  return variable;
                +};
                +
                +/**
                + * Delete a variable.
                + * @param {Blockly.VariableModel} variable Variable to delete.
                + */
                +Blockly.VariableMap.prototype.deleteVariable = function(variable) {
                +  var variableList = this.variableMap_[variable.type];
                +  for (var i = 0, tempVar; tempVar = variableList[i]; i++) {
                +    if (tempVar.getId() == variable.getId()) {
                +      variableList.splice(i, 1);
                +      Blockly.Events.fire(new Blockly.Events.VarDelete(variable));
                +      return;
                +    }
                +  }
                +};
                +
                +/**
                + * Find the variable by the given name and return it. Return null if it is not
                + *     found.
                + * @param {!string} name The name to check for.
                + * @return {?Blockly.VariableModel} The variable with the given name, or null if
                + *     it was not found.
                + */
                +Blockly.VariableMap.prototype.getVariable = function(name) {
                +  var keys = Object.keys(this.variableMap_);
                +  for (var i = 0; i < keys.length; i++ ) {
                +    var key = keys[i];
                +    for (var j = 0, variable; variable = this.variableMap_[key][j]; j++) {
                +      if (Blockly.Names.equals(variable.name, name)) {
                +        return variable;
                +      }
                +    }
                +  }
                +  return null;
                +};
                +
                +/**
                + * Find the variable by the given id and return it. Return null if it is not
                + *     found.
                + * @param {!string} id The id to check for.
                + * @return {?Blockly.VariableModel} The variable with the given id.
                + */
                +Blockly.VariableMap.prototype.getVariableById = function(id) {
                +  var keys = Object.keys(this.variableMap_);
                +  for (var i = 0; i < keys.length; i++ ) {
                +    var key = keys[i];
                +    for (var j = 0, variable; variable = this.variableMap_[key][j]; j++) {
                +      if (variable.getId() == id) {
                +        return variable;
                +      }
                +    }
                +  }
                +  return null;
                +};
                +
                +/**
                + * Get a list containing all of the variables of a specified type. If type is
                + *     null, return list of variables with empty string type.
                + * @param {?string} type Type of the variables to find.
                + * @return {Array.<Blockly.VariableModel>} The sought after variables of the
                + *     passed in type. An empty array if none are found.
                + */
                +Blockly.VariableMap.prototype.getVariablesOfType = function(type) {
                +  type = type || '';
                +  var variable_list = this.variableMap_[type];
                +  if (variable_list) {
                +    return variable_list.slice();
                +  }
                +  return [];
                +};
                +
                +/**
                + * Return all variable types.
                + * @return {!Array.<string>} List of variable types.
                + */
                +Blockly.VariableMap.prototype.getVariableTypes = function() {
                +  return Object.keys(this.variableMap_);
                +};
                +
                +/**
                + * Return all variables of all types.
                + * @return {!Array.<Blockly.VariableModel>} List of variable models.
                + */
                +Blockly.VariableMap.prototype.getAllVariables = function() {
                +  var all_variables = [];
                +  var keys = Object.keys(this.variableMap_);
                +  for (var i = 0; i < keys.length; i++ ) {
                +    all_variables = all_variables.concat(this.variableMap_[keys[i]]);
                +  }
                +  return all_variables;
                +};
                diff --git a/blockly/webif/static/blockly/core/variable_model.js b/blockly/webif/static/blockly/core/variable_model.js
                new file mode 100644
                index 000000000..990702a9b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/variable_model.js
                @@ -0,0 +1,99 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Components for the variable model.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.VariableModel');
                +
                +goog.require('goog.string');
                +
                +
                +/**
                + * Class for a variable model.
                + * Holds information for the variable including name, id, and type.
                + * @param {!Blockly.Workspace} workspace The variable's workspace.
                + * @param {!string} name The name of the variable. This must be unique across
                + *     variables and procedures.
                + * @param {?string} opt_type The type of the variable like 'int' or 'string'.
                + *     Does not need to be unique. Field_variable can filter variables based on
                + *     their type. This will default to '' which is a specific type.
                + * @param {?string} opt_id The unique id of the variable. This will default to
                + *     a UUID.
                + * @see {Blockly.FieldVariable}
                + * @constructor
                + */
                +Blockly.VariableModel = function(workspace, name, opt_type, opt_id) {
                +  /**
                +   * The workspace the variable is in.
                +   * @type {!Blockly.Workspace}
                +   */
                +  this.workspace = workspace;
                +
                +  /**
                +   * The name of the variable, typically defined by the user. It must be
                +   * unique across all names used for procedures and variables. It may be
                +   * changed by the user.
                +   * @type {string}
                +   */
                +  this.name = name;
                +
                +  /**
                +   * The type of the variable, such as 'int' or 'sound_effect'. This may be
                +   * used to build a list of variables of a specific type. By default this is
                +   * the empty string '', which is a specific type.
                +   * @see {Blockly.FieldVariable}
                +   * @type {string}
                +   */
                +  this.type = opt_type || '';
                +
                +  /**
                +   * A unique id for the variable. This should be defined at creation and
                +   * not change, even if the name changes. In most cases this should be a
                +   * UUID.
                +   * @type {string}
                +   * @private
                +   */
                +  this.id_ = opt_id || Blockly.utils.genUid();
                +
                +  Blockly.Events.fire(new Blockly.Events.VarCreate(this));
                +};
                +
                +/**
                + * @return {!string} The id for the variable.
                + */
                +Blockly.VariableModel.prototype.getId = function() {
                +  return this.id_;
                +};
                +
                +/**
                + * A custom compare function for the VariableModel objects.
                + * @param {Blockly.VariableModel} var1 First variable to compare.
                + * @param {Blockly.VariableModel} var2 Second variable to compare.
                + * @return {number} -1 if name of var1 is less than name of var2, 0 if equal,
                + *     and 1 if greater.
                + * @package
                + */
                +Blockly.VariableModel.compareByName = function(var1, var2) {
                +  return goog.string.caseInsensitiveCompare(var1.name, var2.name);
                +};
                diff --git a/blockly/webif/static/blockly/core/variables.js b/blockly/webif/static/blockly/core/variables.js
                new file mode 100644
                index 000000000..ac952844e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/variables.js
                @@ -0,0 +1,360 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Utility functions for handling variables.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Variables
                + * @namespace
                + **/
                +goog.provide('Blockly.Variables');
                +
                +goog.require('Blockly.Blocks');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.VariableModel');
                +goog.require('Blockly.Workspace');
                +goog.require('goog.string');
                +
                +
                +/**
                + * Constant to separate variable names from procedures and generated functions
                + * when running generators.
                + * @deprecated Use Blockly.VARIABLE_CATEGORY_NAME
                + */
                +Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME;
                +
                +/**
                + * Find all user-created variables that are in use in the workspace.
                + * For use by generators.
                + * @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
                + * @return {!Array.<string>} Array of variable names.
                + */
                +Blockly.Variables.allUsedVariables = function(root) {
                +  var blocks;
                +  if (root instanceof Blockly.Block) {
                +    // Root is Block.
                +    blocks = root.getDescendants();
                +  } else if (root.getAllBlocks) {
                +    // Root is Workspace.
                +    blocks = root.getAllBlocks();
                +  } else {
                +    throw 'Not Block or Workspace: ' + root;
                +  }
                +  var variableHash = Object.create(null);
                +  // Iterate through every block and add each variable to the hash.
                +  for (var x = 0; x < blocks.length; x++) {
                +    var blockVariables = blocks[x].getVars();
                +    if (blockVariables) {
                +      for (var y = 0; y < blockVariables.length; y++) {
                +        var varName = blockVariables[y];
                +        // Variable name may be null if the block is only half-built.
                +        if (varName) {
                +          variableHash[varName.toLowerCase()] = varName;
                +        }
                +      }
                +    }
                +  }
                +  // Flatten the hash into a list.
                +  var variableList = [];
                +  for (var name in variableHash) {
                +    variableList.push(variableHash[name]);
                +  }
                +  return variableList;
                +};
                +
                +/**
                + * Find all variables that the user has created through the workspace or
                + * toolbox.  For use by generators.
                + * @param {!Blockly.Workspace} root The workspace to inspect.
                + * @return {!Array.<Blockly.VariableModel>} Array of variable models.
                + */
                +Blockly.Variables.allVariables = function(root) {
                +  if (root instanceof Blockly.Block) {
                +    // Root is Block.
                +    console.warn('Deprecated call to Blockly.Variables.allVariables ' +
                +                 'with a block instead of a workspace.  You may want ' +
                +                 'Blockly.Variables.allUsedVariables');
                +    return {};
                +  }
                +  return root.getAllVariables();
                +};
                +
                +/**
                + * Construct the elements (blocks and button) required by the flyout for the
                + * variable category.
                + * @param {!Blockly.Workspace} workspace The workspace contianing variables.
                + * @return {!Array.<!Element>} Array of XML elements.
                + */
                +Blockly.Variables.flyoutCategory = function(workspace) {
                +  var xmlList = [];
                +  var button = goog.dom.createDom('button');
                +  button.setAttribute('text', Blockly.Msg.NEW_VARIABLE);
                +  button.setAttribute('callbackKey', 'CREATE_VARIABLE');
                +
                +  workspace.registerButtonCallback('CREATE_VARIABLE', function(button) {
                +    Blockly.Variables.createVariable(button.getTargetWorkspace());
                +  });
                +
                +  xmlList.push(button);
                +
                +  var blockList = Blockly.Variables.flyoutCategoryBlocks(workspace);
                +  xmlList = xmlList.concat(blockList);
                +  return xmlList;
                +};
                +
                +/**
                + * Construct the blocks required by the flyout for the variable category.
                + * @param {!Blockly.Workspace} workspace The workspace contianing variables.
                + * @return {!Array.<!Element>} Array of XML block elements.
                + */
                +Blockly.Variables.flyoutCategoryBlocks = function(workspace) {
                +  var variableModelList = workspace.getVariablesOfType('');
                +  variableModelList.sort(Blockly.VariableModel.compareByName);
                +
                +  var xmlList = [];
                +  if (variableModelList.length > 0) {
                +    var firstVariable = variableModelList[0];
                +    if (Blockly.Blocks['variables_set']) {
                +      var gap = Blockly.Blocks['math_change'] ? 8 : 24;
                +      var blockText = '<xml>' +
                +            '<block type="variables_set" gap="' + gap + '">' +
                +            Blockly.Variables.generateVariableFieldXml_(firstVariable) +
                +            '</block>' +
                +            '</xml>';
                +      var block = Blockly.Xml.textToDom(blockText).firstChild;
                +      xmlList.push(block);
                +    }
                +    if (Blockly.Blocks['math_change']) {
                +      var gap = Blockly.Blocks['variables_get'] ? 20 : 8;
                +      var blockText = '<xml>' +
                +          '<block type="math_change" gap="' + gap + '">' +
                +          Blockly.Variables.generateVariableFieldXml_(firstVariable) +
                +          '<value name="DELTA">' +
                +          '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +          '</shadow>' +
                +          '</value>' +
                +          '</block>' +
                +          '</xml>';
                +      var block = Blockly.Xml.textToDom(blockText).firstChild;
                +      xmlList.push(block);
                +    }
                +
                +    for (var i = 0, variable; variable = variableModelList[i]; i++) {
                +      if (Blockly.Blocks['variables_get']) {
                +        var blockText = '<xml>' +
                +            '<block type="variables_get" gap="8">' +
                +            Blockly.Variables.generateVariableFieldXml_(variable) +
                +            '</block>' +
                +            '</xml>';
                +        var block = Blockly.Xml.textToDom(blockText).firstChild;
                +        xmlList.push(block);
                +      }
                +    }
                +  }
                +  return xmlList;
                +};
                +
                +/**
                +* Return a new variable name that is not yet being used. This will try to
                +* generate single letter variable names in the range 'i' to 'z' to start with.
                +* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
                +* then 'i2' to 'z2' etc.  Skip 'l'.
                + * @param {!Blockly.Workspace} workspace The workspace to be unique in.
                +* @return {string} New variable name.
                +*/
                +Blockly.Variables.generateUniqueName = function(workspace) {
                +  var variableList = workspace.getAllVariables();
                +  var newName = '';
                +  if (variableList.length) {
                +    var nameSuffix = 1;
                +    var letters = 'ijkmnopqrstuvwxyzabcdefgh';  // No 'l'.
                +    var letterIndex = 0;
                +    var potName = letters.charAt(letterIndex);
                +    while (!newName) {
                +      var inUse = false;
                +      for (var i = 0; i < variableList.length; i++) {
                +        if (variableList[i].name.toLowerCase() == potName) {
                +          // This potential name is already used.
                +          inUse = true;
                +          break;
                +        }
                +      }
                +      if (inUse) {
                +        // Try the next potential name.
                +        letterIndex++;
                +        if (letterIndex == letters.length) {
                +          // Reached the end of the character sequence so back to 'i'.
                +          // a new suffix.
                +          letterIndex = 0;
                +          nameSuffix++;
                +        }
                +        potName = letters.charAt(letterIndex);
                +        if (nameSuffix > 1) {
                +          potName += nameSuffix;
                +        }
                +      } else {
                +        // We can use the current potential name.
                +        newName = potName;
                +      }
                +    }
                +  } else {
                +    newName = 'i';
                +  }
                +  return newName;
                +};
                +
                +/**
                + * Create a new variable on the given workspace.
                + * @param {!Blockly.Workspace} workspace The workspace on which to create the
                + *     variable.
                + * @param {function(?string=)=} opt_callback A callback. It will
                + *     be passed an acceptable new variable name, or null if change is to be
                + *     aborted (cancel button), or undefined if an existing variable was chosen.
                + * @param {?string} opt_type The type of the variable like 'int', 'string', or
                + *     ''. This will default to '', which is a specific type.
                + */
                +Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
                +  // This function needs to be named so it can be called recursively.
                +  var promptAndCheckWithAlert = function(defaultName) {
                +    Blockly.Variables.promptName(Blockly.Msg.NEW_VARIABLE_TITLE, defaultName,
                +      function(text) {
                +        if (text) {
                +          if (workspace.getVariable(text)) {
                +            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS.replace('%1',
                +                text.toLowerCase()),
                +                function() {
                +                  promptAndCheckWithAlert(text);  // Recurse
                +                });
                +          }
                +          else if (Blockly.Procedures.isNameUsed(text, workspace)) {
                +            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                +                text.toLowerCase()),
                +                function() {
                +                  promptAndCheckWithAlert(text);  // Recurse
                +                });
                +          }
                +          else {
                +            workspace.createVariable(text, opt_type);
                +            if (opt_callback) {
                +              opt_callback(text);
                +            }
                +          }
                +        } else {
                +          // User canceled prompt without a value.
                +          if (opt_callback) {
                +            opt_callback(null);
                +          }
                +        }
                +      });
                +  };
                +  promptAndCheckWithAlert('');
                +};
                +
                +/**
                + * Rename a variable with the given workspace, variableType, and oldName.
                + * @param {!Blockly.Workspace} workspace The workspace on which to rename the
                + *     variable.
                + * @param {?Blockly.VariableModel} variable Variable to rename.
                + * @param {function(?string=)=} opt_callback A callback. It will
                + *     be passed an acceptable new variable name, or null if change is to be
                + *     aborted (cancel button), or undefined if an existing variable was chosen.
                + */
                +Blockly.Variables.renameVariable = function(workspace, variable,
                +  opt_callback) {
                +  // This function needs to be named so it can be called recursively.
                +  var promptAndCheckWithAlert = function(defaultName) {
                +    Blockly.Variables.promptName(
                +      Blockly.Msg.RENAME_VARIABLE_TITLE.replace('%1', variable.name), defaultName,
                +      function(newName) {
                +        if (newName) {
                +          var newVariable = workspace.getVariable(newName);
                +          if (newVariable && newVariable.type != variable.type) {
                +            Blockly.alert(Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE.replace('%1',
                +                newName.toLowerCase()).replace('%2', newVariable.type),
                +                function() {
                +                  promptAndCheckWithAlert(newName);  // Recurse
                +                });
                +          }
                +          else if (Blockly.Procedures.isNameUsed(newName, workspace)) {
                +            Blockly.alert(Blockly.Msg.PROCEDURE_ALREADY_EXISTS.replace('%1',
                +                newName.toLowerCase()),
                +                function() {
                +                  promptAndCheckWithAlert(newName);  // Recurse
                +                });
                +          }
                +          else {
                +            workspace.renameVariable(variable.name, newName);
                +            if (opt_callback) {
                +              opt_callback(newName);
                +            }
                +          }
                +        } else {
                +          // User canceled prompt without a value.
                +          if (opt_callback) {
                +            opt_callback(null);
                +          }
                +        }
                +      });
                +  };
                +  promptAndCheckWithAlert('');
                +};
                +
                +/**
                + * Prompt the user for a new variable name.
                + * @param {string} promptText The string of the prompt.
                + * @param {string} defaultText The default value to show in the prompt's field.
                + * @param {function(?string)} callback A callback. It will return the new
                + *     variable name, or null if the user picked something illegal.
                + */
                +Blockly.Variables.promptName = function(promptText, defaultText, callback) {
                +  Blockly.prompt(promptText, defaultText, function(newVar) {
                +    // Merge runs of whitespace.  Strip leading and trailing whitespace.
                +    // Beyond this, all names are legal.
                +    if (newVar) {
                +      newVar = newVar.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
                +      if (newVar == Blockly.Msg.RENAME_VARIABLE ||
                +          newVar == Blockly.Msg.NEW_VARIABLE) {
                +        // Ok, not ALL names are legal...
                +        newVar = null;
                +      }
                +    }
                +    callback(newVar);
                +  });
                +};
                +
                +/**
                + * Generate XML string for variable field.
                + * @param {!Blockly.VariableModel} variableModel The variable model to generate
                + *     an XML string from.
                + * @return {string} The generated XML.
                + * @private
                + */
                +Blockly.Variables.generateVariableFieldXml_ = function(variableModel) {
                +  var xmlString = '<field name="VAR" ' + 'variableType="' +
                +      variableModel.type + '" id="' + variableModel.getId() + '">'+
                +      variableModel.name +
                +      '</field>';
                +  return xmlString;
                +};
                diff --git a/blockly/webif/static/blockly/core/warning.js b/blockly/webif/static/blockly/core/warning.js
                new file mode 100644
                index 000000000..86413fa65
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/warning.js
                @@ -0,0 +1,185 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a warning.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Warning');
                +
                +goog.require('Blockly.Bubble');
                +goog.require('Blockly.Icon');
                +
                +
                +/**
                + * Class for a warning.
                + * @param {!Blockly.Block} block The block associated with this warning.
                + * @extends {Blockly.Icon}
                + * @constructor
                + */
                +Blockly.Warning = function(block) {
                +  Blockly.Warning.superClass_.constructor.call(this, block);
                +  this.createIcon();
                +  // The text_ object can contain multiple warnings.
                +  this.text_ = {};
                +};
                +goog.inherits(Blockly.Warning, Blockly.Icon);
                +
                +/**
                + * Does this icon get hidden when the block is collapsed.
                + */
                +Blockly.Warning.prototype.collapseHidden = false;
                +
                +/**
                + * Draw the warning icon.
                + * @param {!Element} group The icon group.
                + * @private
                + */
                +Blockly.Warning.prototype.drawIcon_ = function(group) {
                +  // Triangle with rounded corners.
                +  Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyIconShape',
                +       'd': 'M2,15Q-1,15 0.5,12L6.5,1.7Q8,-1 9.5,1.7L15.5,12Q17,15 14,15z'},
                +       group);
                +  // Can't use a real '!' text character since different browsers and operating
                +  // systems render it differently.
                +  // Body of exclamation point.
                +  Blockly.utils.createSvgElement('path',
                +      {'class': 'blocklyIconSymbol',
                +       'd': 'm7,4.8v3.16l0.27,2.27h1.46l0.27,-2.27v-3.16z'},
                +       group);
                +  // Dot of exclamation point.
                +  Blockly.utils.createSvgElement('rect',
                +      {'class': 'blocklyIconSymbol',
                +       'x': '7', 'y': '11', 'height': '2', 'width': '2'},
                +       group);
                +};
                +
                +/**
                + * Create the text for the warning's bubble.
                + * @param {string} text The text to display.
                + * @return {!SVGTextElement} The top-level node of the text.
                + * @private
                + */
                +Blockly.Warning.textToDom_ = function(text) {
                +  var paragraph = /** @type {!SVGTextElement} */ (
                +      Blockly.utils.createSvgElement('text',
                +          {'class': 'blocklyText blocklyBubbleText',
                +           'y': Blockly.Bubble.BORDER_WIDTH},
                +          null));
                +  var lines = text.split('\n');
                +  for (var i = 0; i < lines.length; i++) {
                +    var tspanElement = Blockly.utils.createSvgElement('tspan',
                +        {'dy': '1em', 'x': Blockly.Bubble.BORDER_WIDTH}, paragraph);
                +    var textNode = document.createTextNode(lines[i]);
                +    tspanElement.appendChild(textNode);
                +  }
                +  return paragraph;
                +};
                +
                +/**
                + * Show or hide the warning bubble.
                + * @param {boolean} visible True if the bubble should be visible.
                + */
                +Blockly.Warning.prototype.setVisible = function(visible) {
                +  if (visible == this.isVisible()) {
                +    // No change.
                +    return;
                +  }
                +  Blockly.Events.fire(
                +      new Blockly.Events.Ui(this.block_, 'warningOpen', !visible, visible));
                +  if (visible) {
                +    // Create the bubble to display all warnings.
                +    var paragraph = Blockly.Warning.textToDom_(this.getText());
                +    this.bubble_ = new Blockly.Bubble(
                +        /** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace),
                +        paragraph, this.block_.svgPath_, this.iconXY_, null, null);
                +    if (this.block_.RTL) {
                +      // Right-align the paragraph.
                +      // This cannot be done until the bubble is rendered on screen.
                +      var maxWidth = paragraph.getBBox().width;
                +      for (var i = 0, textElement; textElement = paragraph.childNodes[i]; i++) {
                +        textElement.setAttribute('text-anchor', 'end');
                +        textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH);
                +      }
                +    }
                +    this.updateColour();
                +    // Bump the warning into the right location.
                +    var size = this.bubble_.getBubbleSize();
                +    this.bubble_.setBubbleSize(size.width, size.height);
                +  } else {
                +    // Dispose of the bubble.
                +    this.bubble_.dispose();
                +    this.bubble_ = null;
                +    this.body_ = null;
                +  }
                +};
                +
                +/**
                + * Bring the warning to the top of the stack when clicked on.
                + * @param {!Event} e Mouse up event.
                + * @private
                + */
                +Blockly.Warning.prototype.bodyFocus_ = function(e) {
                +  this.bubble_.promote_();
                +};
                +
                +/**
                + * Set this warning's text.
                + * @param {string} text Warning text (or '' to delete).
                + * @param {string} id An ID for this text entry to be able to maintain
                + *     multiple warnings.
                + */
                +Blockly.Warning.prototype.setText = function(text, id) {
                +  if (this.text_[id] == text) {
                +    return;
                +  }
                +  if (text) {
                +    this.text_[id] = text;
                +  } else {
                +    delete this.text_[id];
                +  }
                +  if (this.isVisible()) {
                +    this.setVisible(false);
                +    this.setVisible(true);
                +  }
                +};
                +
                +/**
                + * Get this warning's texts.
                + * @return {string} All texts concatenated into one string.
                + */
                +Blockly.Warning.prototype.getText = function() {
                +  var allWarnings = [];
                +  for (var id in this.text_) {
                +    allWarnings.push(this.text_[id]);
                +  }
                +  return allWarnings.join('\n');
                +};
                +
                +/**
                + * Dispose of this warning.
                + */
                +Blockly.Warning.prototype.dispose = function() {
                +  this.block_.warning = null;
                +  Blockly.Icon.prototype.dispose.call(this);
                +};
                diff --git a/blockly/webif/static/blockly/core/widgetdiv.js b/blockly/webif/static/blockly/core/widgetdiv.js
                new file mode 100644
                index 000000000..c2a9a6537
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/widgetdiv.js
                @@ -0,0 +1,156 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview A div that floats on top of Blockly.  This singleton contains
                + *     temporary HTML UI widgets that the user is currently interacting with.
                + *     E.g. text input areas, colour pickers, context menus.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.WidgetDiv
                + * @namespace
                + **/
                +goog.provide('Blockly.WidgetDiv');
                +
                +goog.require('Blockly.Css');
                +goog.require('goog.dom');
                +goog.require('goog.dom.TagName');
                +goog.require('goog.style');
                +
                +
                +/**
                + * The HTML container.  Set once by Blockly.WidgetDiv.createDom.
                + * @type {Element}
                + */
                +Blockly.WidgetDiv.DIV = null;
                +
                +/**
                + * The object currently using this container.
                + * @type {Object}
                + * @private
                + */
                +Blockly.WidgetDiv.owner_ = null;
                +
                +/**
                + * Optional cleanup function set by whichever object uses the widget.
                + * @type {Function}
                + * @private
                + */
                +Blockly.WidgetDiv.dispose_ = null;
                +
                +/**
                + * Create the widget div and inject it onto the page.
                + */
                +Blockly.WidgetDiv.createDom = function() {
                +  if (Blockly.WidgetDiv.DIV) {
                +    return;  // Already created.
                +  }
                +  // Create an HTML container for popup overlays (e.g. editor widgets).
                +  Blockly.WidgetDiv.DIV =
                +      goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyWidgetDiv');
                +  document.body.appendChild(Blockly.WidgetDiv.DIV);
                +};
                +
                +/**
                + * Initialize and display the widget div.  Close the old one if needed.
                + * @param {!Object} newOwner The object that will be using this container.
                + * @param {boolean} rtl Right-to-left (true) or left-to-right (false).
                + * @param {Function} dispose Optional cleanup function to be run when the widget
                + *   is closed.
                + */
                +Blockly.WidgetDiv.show = function(newOwner, rtl, dispose) {
                +  Blockly.WidgetDiv.hide();
                +  Blockly.WidgetDiv.owner_ = newOwner;
                +  Blockly.WidgetDiv.dispose_ = dispose;
                +  // Temporarily move the widget to the top of the screen so that it does not
                +  // cause a scrollbar jump in Firefox when displayed.
                +  var xy = goog.style.getViewportPageOffset(document);
                +  Blockly.WidgetDiv.DIV.style.top = xy.y + 'px';
                +  Blockly.WidgetDiv.DIV.style.direction = rtl ? 'rtl' : 'ltr';
                +  Blockly.WidgetDiv.DIV.style.display = 'block';
                +};
                +
                +/**
                + * Destroy the widget and hide the div.
                + */
                +Blockly.WidgetDiv.hide = function() {
                +  if (Blockly.WidgetDiv.owner_) {
                +    Blockly.WidgetDiv.owner_ = null;
                +    Blockly.WidgetDiv.DIV.style.display = 'none';
                +    Blockly.WidgetDiv.DIV.style.left = '';
                +    Blockly.WidgetDiv.DIV.style.top = '';
                +    Blockly.WidgetDiv.dispose_ && Blockly.WidgetDiv.dispose_();
                +    Blockly.WidgetDiv.dispose_ = null;
                +    goog.dom.removeChildren(Blockly.WidgetDiv.DIV);
                +  }
                +};
                +
                +/**
                + * Is the container visible?
                + * @return {boolean} True if visible.
                + */
                +Blockly.WidgetDiv.isVisible = function() {
                +  return !!Blockly.WidgetDiv.owner_;
                +};
                +
                +/**
                + * Destroy the widget and hide the div if it is being used by the specified
                + *   object.
                + * @param {!Object} oldOwner The object that was using this container.
                + */
                +Blockly.WidgetDiv.hideIfOwner = function(oldOwner) {
                +  if (Blockly.WidgetDiv.owner_ == oldOwner) {
                +    Blockly.WidgetDiv.hide();
                +  }
                +};
                +
                +/**
                + * Position the widget at a given location.  Prevent the widget from going
                + * offscreen top or left (right in RTL).
                + * @param {number} anchorX Horizontal location (window coorditates, not body).
                + * @param {number} anchorY Vertical location (window coorditates, not body).
                + * @param {!goog.math.Size} windowSize Height/width of window.
                + * @param {!goog.math.Coordinate} scrollOffset X/y of window scrollbars.
                + * @param {boolean} rtl True if RTL, false if LTR.
                + */
                +Blockly.WidgetDiv.position = function(anchorX, anchorY, windowSize,
                +                                      scrollOffset, rtl) {
                +  // Don't let the widget go above the top edge of the window.
                +  if (anchorY < scrollOffset.y) {
                +    anchorY = scrollOffset.y;
                +  }
                +  if (rtl) {
                +    // Don't let the widget go right of the right edge of the window.
                +    if (anchorX > windowSize.width + scrollOffset.x) {
                +      anchorX = windowSize.width + scrollOffset.x;
                +    }
                +  } else {
                +    // Don't let the widget go left of the left edge of the window.
                +    if (anchorX < scrollOffset.x) {
                +      anchorX = scrollOffset.x;
                +    }
                +  }
                +  Blockly.WidgetDiv.DIV.style.left = anchorX + 'px';
                +  Blockly.WidgetDiv.DIV.style.top = anchorY + 'px';
                +  Blockly.WidgetDiv.DIV.style.height = windowSize.height + 'px';
                +};
                diff --git a/blockly/webif/static/blockly/core/workspace.js b/blockly/webif/static/blockly/core/workspace.js
                new file mode 100644
                index 000000000..614f2fe6a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/workspace.js
                @@ -0,0 +1,626 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a workspace.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Workspace');
                +
                +goog.require('Blockly.VariableMap');
                +goog.require('goog.array');
                +goog.require('goog.math');
                +
                +
                +/**
                + * Class for a workspace.  This is a data structure that contains blocks.
                + * There is no UI, and can be created headlessly.
                + * @param {Blockly.Options} opt_options Dictionary of options.
                + * @constructor
                + */
                +Blockly.Workspace = function(opt_options) {
                +  /** @type {string} */
                +  this.id = Blockly.utils.genUid();
                +  Blockly.Workspace.WorkspaceDB_[this.id] = this;
                +  /** @type {!Blockly.Options} */
                +  this.options = opt_options || {};
                +  /** @type {boolean} */
                +  this.RTL = !!this.options.RTL;
                +  /** @type {boolean} */
                +  this.horizontalLayout = !!this.options.horizontalLayout;
                +  /** @type {number} */
                +  this.toolboxPosition = this.options.toolboxPosition;
                +
                +  /**
                +   * @type {!Array.<!Blockly.Block>}
                +   * @private
                +   */
                +  this.topBlocks_ = [];
                +  /**
                +   * @type {!Array.<!Function>}
                +   * @private
                +   */
                +  this.listeners_ = [];
                +  /**
                +   * @type {!Array.<!Blockly.Events.Abstract>}
                +   * @private
                +   */
                +  this.undoStack_ = [];
                +  /**
                +   * @type {!Array.<!Blockly.Events.Abstract>}
                +   * @private
                +   */
                +  this.redoStack_ = [];
                +  /**
                +   * @type {!Object}
                +   * @private
                +   */
                +  this.blockDB_ = Object.create(null);
                +
                +  /**
                +   * @type {!Blockly.VariableMap}
                +   * A map from variable type to list of variable names.  The lists contain all
                +   * of the named variables in the workspace, including variables
                +   * that are not currently in use.
                +   * @private
                +   */
                +  this.variableMap_ = new Blockly.VariableMap(this);
                +};
                +
                +/**
                + * Returns `true` if the workspace is visible and `false` if it's headless.
                + * @type {boolean}
                + */
                +Blockly.Workspace.prototype.rendered = false;
                +
                +/**
                + * Maximum number of undo events in stack. `0` turns off undo, `Infinity` sets it to unlimited.
                + * @type {number}
                + */
                +Blockly.Workspace.prototype.MAX_UNDO = 1024;
                +
                +/**
                + * Dispose of this workspace.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.Workspace.prototype.dispose = function() {
                +  this.listeners_.length = 0;
                +  this.clear();
                +  // Remove from workspace database.
                +  delete Blockly.Workspace.WorkspaceDB_[this.id];
                +};
                +
                +/**
                + * Angle away from the horizontal to sweep for blocks.  Order of execution is
                + * generally top to bottom, but a small angle changes the scan to give a bit of
                + * a left to right bias (reversed in RTL).  Units are in degrees.
                + * See: http://tvtropes.org/pmwiki/pmwiki.php/Main/DiagonalBilling.
                + */
                +Blockly.Workspace.SCAN_ANGLE = 3;
                +
                +/**
                + * Add a block to the list of top blocks.
                + * @param {!Blockly.Block} block Block to add.
                + */
                +Blockly.Workspace.prototype.addTopBlock = function(block) {
                +  this.topBlocks_.push(block);
                +  if (!this.isFlyout) {
                +    return;
                +  }
                +  // This is for the (unlikely) case where you have a variable in a block in
                +  // an always-open flyout.  It needs to be possible to edit the block in the
                +  // flyout, so the contents of the dropdown need to be correct.
                +  var variableNames = Blockly.Variables.allUsedVariables(block);
                +  for (var i = 0, name; name = variableNames[i]; i++) {
                +    if (!this.getVariable(name)) {
                +      this.createVariable(name);
                +    }
                +  }
                +};
                +
                +/**
                + * Remove a block from the list of top blocks.
                + * @param {!Blockly.Block} block Block to remove.
                + */
                +Blockly.Workspace.prototype.removeTopBlock = function(block) {
                +  if (!goog.array.remove(this.topBlocks_, block)) {
                +    throw 'Block not present in workspace\'s list of top-most blocks.';
                +  }
                +};
                +
                +/**
                + * Finds the top-level blocks and returns them.  Blocks are optionally sorted
                + * by position; top to bottom (with slight LTR or RTL bias).
                + * @param {boolean} ordered Sort the list if true.
                + * @return {!Array.<!Blockly.Block>} The top-level block objects.
                + */
                +Blockly.Workspace.prototype.getTopBlocks = function(ordered) {
                +  // Copy the topBlocks_ list.
                +  var blocks = [].concat(this.topBlocks_);
                +  if (ordered && blocks.length > 1) {
                +    var offset = Math.sin(goog.math.toRadians(Blockly.Workspace.SCAN_ANGLE));
                +    if (this.RTL) {
                +      offset *= -1;
                +    }
                +    blocks.sort(function(a, b) {
                +      var aXY = a.getRelativeToSurfaceXY();
                +      var bXY = b.getRelativeToSurfaceXY();
                +      return (aXY.y + offset * aXY.x) - (bXY.y + offset * bXY.x);
                +    });
                +  }
                +  return blocks;
                +};
                +
                +/**
                + * Find all blocks in workspace.  No particular order.
                + * @return {!Array.<!Blockly.Block>} Array of blocks.
                + */
                +Blockly.Workspace.prototype.getAllBlocks = function() {
                +  var blocks = this.getTopBlocks(false);
                +  for (var i = 0; i < blocks.length; i++) {
                +    blocks.push.apply(blocks, blocks[i].getChildren());
                +  }
                +  return blocks;
                +};
                +
                +/**
                + * Dispose of all blocks in workspace.
                + */
                +Blockly.Workspace.prototype.clear = function() {
                +  var existingGroup = Blockly.Events.getGroup();
                +  if (!existingGroup) {
                +    Blockly.Events.setGroup(true);
                +  }
                +  while (this.topBlocks_.length) {
                +    this.topBlocks_[0].dispose();
                +  }
                +  if (!existingGroup) {
                +    Blockly.Events.setGroup(false);
                +  }
                +  this.variableMap_.clear();
                +};
                +
                +/**
                + * Walk the workspace and update the map of variables to only contain ones in
                + * use on the workspace.  Use when loading new workspaces from disk.
                + * @param {boolean} clear True if the old variable map should be cleared.
                + */
                +Blockly.Workspace.prototype.updateVariableStore = function(clear) {
                +  // TODO: Sort
                +  if (this.isFlyout) {
                +    return;
                +  }
                +  var variableNames = Blockly.Variables.allUsedVariables(this);
                +  var varList = [];
                +  for (var i = 0, name; name = variableNames[i]; i++) {
                +    // Get variable model with the used variable name.
                +    var tempVar = this.getVariable(name);
                +    if (tempVar) {
                +      varList.push({'name': tempVar.name, 'type': tempVar.type,
                +          'id': tempVar.getId()});
                +    }
                +    else {
                +      varList.push({'name': name, 'type': null, 'id': null});
                +      // TODO(marisaleung): Use variable.type and variable.getId() once variable
                +      // instances are storing more than just name.
                +    }
                +  }
                +  if (clear) {
                +    this.variableMap_.clear();
                +  }
                +  // Update the list in place so that the flyout's references stay correct.
                +  for (var i = 0, varDict; varDict = varList[i]; i++) {
                +    if (!this.getVariable(varDict.name)) {
                +      this.createVariable(varDict.name, varDict.type, varDict.id);
                +    }
                +  }
                +};
                +
                +/**
                + * Rename a variable by updating its name in the variable map. Identify the
                + * variable to rename with the given variable.
                + * @param {?Blockly.VariableModel} variable Variable to rename.
                + * @param {string} newName New variable name.
                + */
                +Blockly.Workspace.prototype.renameVariableInternal_ = function(variable, newName) {
                +  var newVariable = this.getVariable(newName);
                +  var oldCase;
                +
                +  // If they are different types, throw an error.
                +  if (variable && newVariable && variable.type != newVariable.type) {
                +    throw Error('Variable "' + variable.name + '" is type "' + variable.type +
                +         '" and variable "' + newName + '" is type "' + newVariable.type +
                +         '". Both must be the same type.');
                +  }
                +
                +  // Find if newVariable case is different.
                +  if (newVariable && newVariable.name != newName) {
                +    oldCase = newVariable.name;
                +  }
                +
                +  Blockly.Events.setGroup(true);
                +  var blocks = this.getAllBlocks();
                +  // Iterate through every block and update name.
                +  for (var i = 0; i < blocks.length; i++) {
                +    blocks[i].renameVar(variable.name, newName);
                +    if (oldCase) {
                +      blocks[i].renameVar(oldCase, newName);
                +    }
                +  }
                +  this.variableMap_.renameVariable(variable, newName);
                +  Blockly.Events.setGroup(false);
                +};
                +
                +
                +/**
                + * Rename a variable by updating its name in the variable map. Identify the
                + * variable to rename with the given name.
                + * @param {string} oldName Variable to rename.
                + * @param {string} newName New variable name.
                + */
                +Blockly.Workspace.prototype.renameVariable = function(oldName, newName) {
                +  // Warning: Prefer to use renameVariableById.
                +  var variable = this.getVariable(oldName);
                +  this.renameVariableInternal_(variable, newName);
                +};
                +
                +/**
                + * Rename a variable by updating its name in the variable map. Identify the
                + * variable to rename with the given id.
                + * @param {string} id Id of the variable to rename.
                + * @param {string} newName New variable name.
                + */
                +Blockly.Workspace.prototype.renameVariableById = function(id, newName) {
                +  var variable = this.getVariableById(id);
                +  this.renameVariableInternal_(variable, newName);
                +};
                +
                +/**
                + * Create a variable with a given name, optional type, and optional id.
                + * @param {!string} name The name of the variable. This must be unique across
                + *     variables and procedures.
                + * @param {?string} opt_type The type of the variable like 'int' or 'string'.
                + *     Does not need to be unique. Field_variable can filter variables based on
                + *     their type. This will default to '' which is a specific type.
                + * @param {?string} opt_id The unique id of the variable. This will default to
                + *     a UUID.
                + * @return {?Blockly.VariableModel} The newly created variable.
                + */
                +Blockly.Workspace.prototype.createVariable = function(name, opt_type, opt_id) {
                +  return this.variableMap_.createVariable(name, opt_type, opt_id);
                +};
                +
                +/**
                + * Find all the uses of a named variable.
                + * @param {string} name Name of variable.
                + * @return {!Array.<!Blockly.Block>} Array of block usages.
                + */
                +Blockly.Workspace.prototype.getVariableUses = function(name) {
                +  var uses = [];
                +  var blocks = this.getAllBlocks();
                +  // Iterate through every block and check the name.
                +  for (var i = 0; i < blocks.length; i++) {
                +    var blockVariables = blocks[i].getVars();
                +    if (blockVariables) {
                +      for (var j = 0; j < blockVariables.length; j++) {
                +        var varName = blockVariables[j];
                +        // Variable name may be null if the block is only half-built.
                +        if (varName && name && Blockly.Names.equals(varName, name)) {
                +          uses.push(blocks[i]);
                +        }
                +      }
                +    }
                +  }
                +  return uses;
                +};
                +
                +/**
                + * Delete a variable by the passed in name and all of its uses from this
                + * workspace. May prompt the user for confirmation.
                + * @param {string} name Name of variable to delete.
                + */
                +Blockly.Workspace.prototype.deleteVariable = function(name) {
                +  // Check whether this variable is a function parameter before deleting.
                +  var uses = this.getVariableUses(name);
                +  for (var i = 0, block; block = uses[i]; i++) {
                +    if (block.type == 'procedures_defnoreturn' ||
                +      block.type == 'procedures_defreturn') {
                +      var procedureName = block.getFieldValue('NAME');
                +      Blockly.alert(
                +          Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE.
                +          replace('%1', name).
                +          replace('%2', procedureName));
                +      return;
                +    }
                +  }
                +
                +  var workspace = this;
                +  var variable = workspace.getVariable(name);
                +  if (uses.length > 1) {
                +    // Confirm before deleting multiple blocks.
                +    Blockly.confirm(
                +        Blockly.Msg.DELETE_VARIABLE_CONFIRMATION.replace('%1', uses.length).
                +        replace('%2', name),
                +        function(ok) {
                +          if (ok) {
                +            workspace.deleteVariableInternal_(variable);
                +          }
                +        });
                +  } else {
                +    // No confirmation necessary for a single block.
                +    this.deleteVariableInternal_(variable);
                +  }
                +};
                +
                +/**
                + * Delete a variables by the passed in id and all of its uses from this
                + * workspace. May prompt the user for confirmation.
                + * @param {string} id Id of variable to delete.
                + */
                +Blockly.Workspace.prototype.deleteVariableById = function(id) {
                +  var variable = this.getVariableById(id);
                +  if (variable) {
                +    this.deleteVariableInternal_(variable);
                +  } else {
                +    console.warn("Can't delete non-existant variable: " + id);
                +  }
                +};
                +
                +/**
                + * Deletes a variable and all of its uses from this workspace without asking the
                + * user for confirmation.
                + * @param {Blockly.VariableModel} variable Variable to delete.
                + * @private
                + */
                +Blockly.Workspace.prototype.deleteVariableInternal_ = function(variable) {
                +  var uses = this.getVariableUses(variable.name);
                +  Blockly.Events.setGroup(true);
                +  for (var i = 0; i < uses.length; i++) {
                +    uses[i].dispose(true, false);
                +  }
                +  this.variableMap_.deleteVariable(variable);
                +  Blockly.Events.setGroup(false);
                +};
                +
                +/**
                + * Check whether a variable exists with the given name.  The check is
                + * case-insensitive.
                + * @param {string} name The name to check for.
                + * @return {number} The index of the name in the variable list, or -1 if it is
                + *     not present.
                + * @deprecated April 2017
                + */
                +Blockly.Workspace.prototype.variableIndexOf = function(name) {
                +  console.warn(
                +      'Deprecated call to Blockly.Workspace.prototype.variableIndexOf');
                +  return -1;
                +};
                +
                +/**
                + * Find the variable by the given name and return it. Return null if it is not
                + *     found.
                + * @param {!string} name The name to check for.
                + * @return {?Blockly.VariableModel} the variable with the given name.
                + */
                +Blockly.Workspace.prototype.getVariable = function(name) {
                +  return this.variableMap_.getVariable(name);
                +};
                +
                +/**
                + * Find the variable by the given id and return it. Return null if it is not
                + *     found.
                + * @param {!string} id The id to check for.
                + * @return {?Blockly.VariableModel} The variable with the given id.
                + */
                +Blockly.Workspace.prototype.getVariableById = function(id) {
                +  return this.variableMap_.getVariableById(id);
                +};
                +
                +/**
                + * Returns the horizontal offset of the workspace.
                + * Intended for LTR/RTL compatibility in XML.
                + * Not relevant for a headless workspace.
                + * @return {number} Width.
                + */
                +Blockly.Workspace.prototype.getWidth = function() {
                +  return 0;
                +};
                +
                +/**
                + * Obtain a newly created block.
                + * @param {?string} prototypeName Name of the language object containing
                + *     type-specific functions for this block.
                + * @param {string=} opt_id Optional ID.  Use this ID if provided, otherwise
                + *     create a new id.
                + * @return {!Blockly.Block} The created block.
                + */
                +Blockly.Workspace.prototype.newBlock = function(prototypeName, opt_id) {
                +  return new Blockly.Block(this, prototypeName, opt_id);
                +};
                +
                +/**
                + * The number of blocks that may be added to the workspace before reaching
                + *     the maxBlocks.
                + * @return {number} Number of blocks left.
                + */
                +Blockly.Workspace.prototype.remainingCapacity = function() {
                +  if (isNaN(this.options.maxBlocks)) {
                +    return Infinity;
                +  }
                +  return this.options.maxBlocks - this.getAllBlocks().length;
                +};
                +
                +/**
                + * Undo or redo the previous action.
                + * @param {boolean} redo False if undo, true if redo.
                + */
                +Blockly.Workspace.prototype.undo = function(redo) {
                +  var inputStack = redo ? this.redoStack_ : this.undoStack_;
                +  var outputStack = redo ? this.undoStack_ : this.redoStack_;
                +  var inputEvent = inputStack.pop();
                +  if (!inputEvent) {
                +    return;
                +  }
                +  var events = [inputEvent];
                +  // Do another undo/redo if the next one is of the same group.
                +  while (inputStack.length && inputEvent.group &&
                +      inputEvent.group == inputStack[inputStack.length - 1].group) {
                +    events.push(inputStack.pop());
                +  }
                +  // Push these popped events on the opposite stack.
                +  for (var i = 0, event; event = events[i]; i++) {
                +    outputStack.push(event);
                +  }
                +  events = Blockly.Events.filter(events, redo);
                +  Blockly.Events.recordUndo = false;
                +  try {
                +    for (var i = 0, event; event = events[i]; i++) {
                +      event.run(redo);
                +    }
                +  }
                +  finally {
                +    Blockly.Events.recordUndo = true;
                +  }
                +};
                +
                +/**
                + * Clear the undo/redo stacks.
                + */
                +Blockly.Workspace.prototype.clearUndo = function() {
                +  this.undoStack_.length = 0;
                +  this.redoStack_.length = 0;
                +  // Stop any events already in the firing queue from being undoable.
                +  Blockly.Events.clearPendingUndo();
                +};
                +
                +/**
                + * When something in this workspace changes, call a function.
                + * @param {!Function} func Function to call.
                + * @return {!Function} Function that can be passed to
                + *     removeChangeListener.
                + */
                +Blockly.Workspace.prototype.addChangeListener = function(func) {
                +  this.listeners_.push(func);
                +  return func;
                +};
                +
                +/**
                + * Stop listening for this workspace's changes.
                + * @param {Function} func Function to stop calling.
                + */
                +Blockly.Workspace.prototype.removeChangeListener = function(func) {
                +  goog.array.remove(this.listeners_, func);
                +};
                +
                +/**
                + * Fire a change event.
                + * @param {!Blockly.Events.Abstract} event Event to fire.
                + */
                +Blockly.Workspace.prototype.fireChangeListener = function(event) {
                +  if (event.recordUndo) {
                +    this.undoStack_.push(event);
                +    this.redoStack_.length = 0;
                +    if (this.undoStack_.length > this.MAX_UNDO) {
                +      this.undoStack_.unshift();
                +    }
                +  }
                +  for (var i = 0, func; func = this.listeners_[i]; i++) {
                +    func(event);
                +  }
                +};
                +
                +/**
                + * Find the block on this workspace with the specified ID.
                + * @param {string} id ID of block to find.
                + * @return {Blockly.Block} The sought after block or null if not found.
                + */
                +Blockly.Workspace.prototype.getBlockById = function(id) {
                +  return this.blockDB_[id] || null;
                +};
                +
                +/**
                + * Checks whether all value and statement inputs in the workspace are filled
                + * with blocks.
                + * @param {boolean=} opt_shadowBlocksAreFilled An optional argument controlling
                + *     whether shadow blocks are counted as filled. Defaults to true.
                + * @return {boolean} True if all inputs are filled, false otherwise.
                + */
                +Blockly.Workspace.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) {
                +  var blocks = this.getTopBlocks(false);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (!block.allInputsFilled(opt_shadowBlocksAreFilled)) {
                +      return false;
                +    }
                +  }
                +  return true;
                +};
                +
                +/**
                + * Find the variable with the specified type. If type is null, return list of
                + *     variables with empty string type.
                + * @param {?string} type Type of the variables to find.
                + * @return {Array.<Blockly.VariableModel>} The sought after variables of the
                + *     passed in type. An empty array if none are found.
                + */
                +Blockly.Workspace.prototype.getVariablesOfType = function(type) {
                +  return this.variableMap_.getVariablesOfType(type);
                +};
                +
                +/**
                + * Return all variable types.
                + * @return {!Array.<string>} List of variable types.
                + */
                +Blockly.Workspace.prototype.getVariableTypes = function() {
                +  return this.variableMap_.getVariableTypes();
                +};
                +
                +/**
                + * Return all variables of all types.
                + * @return {!Array.<Blockly.VariableModel>} List of variable models.
                + */
                +Blockly.Workspace.prototype.getAllVariables = function() {
                +  return this.variableMap_.getAllVariables();
                +};
                +
                +/**
                + * Database of all workspaces.
                + * @private
                + */
                +Blockly.Workspace.WorkspaceDB_ = Object.create(null);
                +
                +/**
                + * Find the workspace with the specified ID.
                + * @param {string} id ID of workspace to find.
                + * @return {Blockly.Workspace} The sought after workspace or null if not found.
                + */
                +Blockly.Workspace.getById = function(id) {
                +  return Blockly.Workspace.WorkspaceDB_[id] || null;
                +};
                +
                +// Export symbols that would otherwise be renamed by Closure compiler.
                +Blockly.Workspace.prototype['clear'] = Blockly.Workspace.prototype.clear;
                +Blockly.Workspace.prototype['clearUndo'] =
                +    Blockly.Workspace.prototype.clearUndo;
                +Blockly.Workspace.prototype['addChangeListener'] =
                +    Blockly.Workspace.prototype.addChangeListener;
                +Blockly.Workspace.prototype['removeChangeListener'] =
                +    Blockly.Workspace.prototype.removeChangeListener;
                diff --git a/blockly/webif/static/blockly/core/workspace_audio.js b/blockly/webif/static/blockly/core/workspace_audio.js
                new file mode 100644
                index 000000000..8b746a360
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/workspace_audio.js
                @@ -0,0 +1,154 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object in charge of loading, storing, and playing audio for a
                + *     workspace.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.WorkspaceAudio');
                +
                +/**
                + * Class for loading, storing, and playing audio for a workspace.
                + * @param {Blockly.WorkspaceSvg} parentWorkspace The parent of the workspace
                + *     this audio object belongs to, or null.
                + */
                +Blockly.WorkspaceAudio = function(parentWorkspace) {
                +
                +  /**
                +   * The parent of the workspace this object belongs to, or null.  May be
                +   * checked for sounds that this object can't find.
                +   * @type {Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.parentWorkspace_ = parentWorkspace;
                +
                +  /**
                +   * Database of pre-loaded sounds.
                +   * @private
                +   * @const
                +   */
                +  this.SOUNDS_ = Object.create(null);
                +};
                +
                +/**
                + * Time that the last sound was played.
                + * @type {Date}
                + * @private
                + */
                +Blockly.WorkspaceAudio.prototype.lastSound_ = null;
                +
                +/**
                + * Dispose of this audio manager.
                + * @package
                + */
                +Blockly.WorkspaceAudio.prototype.dispose = function() {
                +  this.parentWorkspace_ = null;
                +  this.SOUNDS_ = null;
                +};
                +
                +/**
                + * Load an audio file.  Cache it, ready for instantaneous playing.
                + * @param {!Array.<string>} filenames List of file types in decreasing order of
                + *   preference (i.e. increasing size).  E.g. ['media/go.mp3', 'media/go.wav']
                + *   Filenames include path from Blockly's root.  File extensions matter.
                + * @param {string} name Name of sound.
                + * @package
                + */
                +Blockly.WorkspaceAudio.prototype.load = function(filenames, name) {
                +  if (!filenames.length) {
                +    return;
                +  }
                +  try {
                +    var audioTest = new window['Audio']();
                +  } catch (e) {
                +    // No browser support for Audio.
                +    // IE can throw an error even if the Audio object exists.
                +    return;
                +  }
                +  var sound;
                +  for (var i = 0; i < filenames.length; i++) {
                +    var filename = filenames[i];
                +    var ext = filename.match(/\.(\w+)$/);
                +    if (ext && audioTest.canPlayType('audio/' + ext[1])) {
                +      // Found an audio format we can play.
                +      sound = new window['Audio'](filename);
                +      break;
                +    }
                +  }
                +  if (sound && sound.play) {
                +    this.SOUNDS_[name] = sound;
                +  }
                +};
                +
                +/**
                + * Preload all the audio files so that they play quickly when asked for.
                + * @package
                + */
                +Blockly.WorkspaceAudio.prototype.preload = function() {
                +  for (var name in this.SOUNDS_) {
                +    var sound = this.SOUNDS_[name];
                +    sound.volume = .01;
                +    sound.play();
                +    sound.pause();
                +    // iOS can only process one sound at a time.  Trying to load more than one
                +    // corrupts the earlier ones.  Just load one and leave the others uncached.
                +    if (goog.userAgent.IPAD || goog.userAgent.IPHONE) {
                +      break;
                +    }
                +  }
                +};
                +
                +/**
                + * Play a named sound at specified volume.  If volume is not specified,
                + * use full volume (1).
                + * @param {string} name Name of sound.
                + * @param {number=} opt_volume Volume of sound (0-1).
                + */
                +Blockly.WorkspaceAudio.prototype.play = function(name, opt_volume) {
                +  var sound = this.SOUNDS_[name];
                +  if (sound) {
                +    // Don't play one sound on top of another.
                +    var now = new Date;
                +    if (this.lastSound_ != null &&
                +        now - this.lastSound_ < Blockly.SOUND_LIMIT) {
                +      return;
                +    }
                +    this.lastSound_ = now;
                +    var mySound;
                +    var ie9 = goog.userAgent.DOCUMENT_MODE &&
                +              goog.userAgent.DOCUMENT_MODE === 9;
                +    if (ie9 || goog.userAgent.IPAD || goog.userAgent.ANDROID) {
                +      // Creating a new audio node causes lag in IE9, Android and iPad. Android
                +      // and IE9 refetch the file from the server, iPad uses a singleton audio
                +      // node which must be deleted and recreated for each new audio tag.
                +      mySound = sound;
                +    } else {
                +      mySound = sound.cloneNode();
                +    }
                +    mySound.volume = (opt_volume === undefined ? 1 : opt_volume);
                +    mySound.play();
                +  } else if (this.parentWorkspace_) {
                +    // Maybe a workspace on a lower level knows about this sound.
                +    this.parentWorkspace_.getAudioManager().play(name, opt_volume);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/core/workspace_drag_surface_svg.js b/blockly/webif/static/blockly/core/workspace_drag_surface_svg.js
                new file mode 100644
                index 000000000..d642a1686
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/workspace_drag_surface_svg.js
                @@ -0,0 +1,191 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview An SVG that floats on top of the workspace.
                + * Blocks are moved into this SVG during a drag, improving performance.
                + * The entire SVG is translated using css translation instead of SVG so the
                + * blocks are never repainted during drag improving performance.
                + * @author katelyn@google.com (Katelyn Mann)
                + */
                +
                +'use strict';
                +
                +goog.provide('Blockly.WorkspaceDragSurfaceSvg');
                +
                +goog.require('Blockly.utils');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.math.Coordinate');
                +
                +
                +/**
                + * Blocks are moved into this SVG during a drag, improving performance.
                + * The entire SVG is translated using css transforms instead of SVG so the
                + * blocks are never repainted during drag improving performance.
                + * @param {!Element} container Containing element.
                + * @constructor
                + */
                +Blockly.WorkspaceDragSurfaceSvg = function(container) {
                +  this.container_ = container;
                +  this.createDom();
                +};
                +
                +/**
                + * The SVG drag surface. Set once by Blockly.WorkspaceDragSurfaceSvg.createDom.
                + * @type {Element}
                + * @private
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.SVG_ = null;
                +
                +/**
                + * SVG group inside the drag surface that holds blocks while a drag is in
                + * progress. Blocks are moved here by the workspace at start of a drag and moved
                + * back into the main SVG at the end of a drag.
                + *
                + * @type {Element}
                + * @private
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.dragGroup_ = null;
                +
                +/**
                + * Containing HTML element; parent of the workspace and the drag surface.
                + * @type {Element}
                + * @private
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.container_ = null;
                +
                +/**
                + * Create the drag surface and inject it into the container.
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.createDom = function() {
                +  if (this.SVG_) {
                +    return;  // Already created.
                +  }
                +
                +  /**
                +  * Dom structure when the workspace is being dragged. If there is no drag in
                +  * progress, the SVG is empty and display: none.
                +  * <svg class="blocklyWsDragSurface" style=transform:translate3d(...)>
                +  *   <g class="blocklyBlockCanvas"></g>
                +  *   <g class="blocklyBubbleCanvas">/g>
                +  * </svg>
                +  */
                +  this.SVG_ = Blockly.utils.createSvgElement('svg', {
                +    'xmlns': Blockly.SVG_NS,
                +    'xmlns:html': Blockly.HTML_NS,
                +    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
                +    'version': '1.1',
                +    'class': 'blocklyWsDragSurface'
                +  }, null);
                +  this.container_.appendChild(this.SVG_);
                +};
                +
                +/**
                + * Translate the entire drag surface during a drag.
                + * We translate the drag surface instead of the blocks inside the surface
                + * so that the browser avoids repainting the SVG.
                + * Because of this, the drag coordinates must be adjusted by scale.
                + * @param {number} x X translation for the entire surface
                + * @param {number} y Y translation for the entire surface
                + * @package
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.translateSurface = function(x, y) {
                +  // This is a work-around to prevent a the blocks from rendering
                +  // fuzzy while they are being moved on the drag surface.
                +  x = x.toFixed(0);
                +  y = y.toFixed(0);
                +
                +  this.SVG_.style.display = 'block';
                +  Blockly.utils.setCssTransform(this.SVG_,
                +    'translate3d(' + x + 'px, ' + y + 'px, 0px)');
                +};
                +
                +/**
                + * Reports the surface translation in scaled workspace coordinates.
                + * Use this when finishing a drag to return blocks to the correct position.
                + * @return {!goog.math.Coordinate} Current translation of the surface
                + * @package
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.getSurfaceTranslation = function() {
                +  return Blockly.utils.getRelativeXY(this.SVG_);
                +};
                +
                +/**
                + * Move the blockCanvas and bubbleCanvas out of the surface SVG and on to
                + * newSurface.
                + * @param {!SVGElement} newSurface The element to put the drag surface contents
                + *     into.
                + * @package
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide = function(newSurface) {
                +  var blockCanvas = this.SVG_.childNodes[0];
                +  var bubbleCanvas = this.SVG_.childNodes[1];
                +  if (!blockCanvas || !bubbleCanvas ||
                +      !Blockly.utils.hasClass(blockCanvas, 'blocklyBlockCanvas') ||
                +      !Blockly.utils.hasClass(bubbleCanvas, 'blocklyBubbleCanvas')) {
                +    throw 'Couldn\'t clear and hide the drag surface.  A node was missing.';
                +  }
                +
                +  // If there is a previous sibling, put the blockCanvas back right afterwards,
                +  // otherwise insert it as the first child node in newSurface.
                +  if (this.previousSibling_ != null) {
                +    Blockly.utils.insertAfter_(blockCanvas, this.previousSibling_);
                +  } else {
                +    newSurface.insertBefore(blockCanvas, newSurface.firstChild);
                +  }
                +
                +  // Reattach the bubble canvas after the blockCanvas.
                +  Blockly.utils.insertAfter_(bubbleCanvas, blockCanvas);
                +  // Hide the drag surface.
                +  this.SVG_.style.display = 'none';
                +  goog.asserts.assert(this.SVG_.childNodes.length == 0,
                +    'Drag surface was not cleared.');
                +  Blockly.utils.setCssTransform(this.SVG_, '');
                +  this.previousSibling_ = null;
                +};
                +
                +/**
                + * Set the SVG to have the block canvas and bubble canvas in it and then
                + * show the surface.
                + * @param {!Element} blockCanvas The block canvas <g> element from the workspace.
                + * @param {!Element} bubbleCanvas The <g> element that contains the bubbles.
                + * @param {?Element} previousSibling The element to insert the block canvas &
                +       bubble canvas after when it goes back in the dom at the end of a drag.
                + * @param {number} width The width of the workspace svg element.
                + * @param {number} height The height of the workspace svg element.
                + * @param {number} scale The scale of the workspace being dragged.
                + * @package
                + */
                +Blockly.WorkspaceDragSurfaceSvg.prototype.setContentsAndShow = function(
                +    blockCanvas, bubbleCanvas, previousSibling, width, height, scale) {
                +  goog.asserts.assert(this.SVG_.childNodes.length == 0,
                +    'Already dragging a block.');
                +  this.previousSibling_ = previousSibling;
                +  // Make sure the blocks and bubble canvas are scaled appropriately.
                +  blockCanvas.setAttribute('transform', 'translate(0, 0) scale(' + scale + ')');
                +  bubbleCanvas.setAttribute('transform',
                +    'translate(0, 0) scale(' + scale + ')');
                +  this.SVG_.setAttribute('width', width);
                +  this.SVG_.setAttribute('height', height);
                +  this.SVG_.appendChild(blockCanvas);
                +  this.SVG_.appendChild(bubbleCanvas);
                +  this.SVG_.style.display = 'block';
                +};
                diff --git a/blockly/webif/static/blockly/core/workspace_dragger.js b/blockly/webif/static/blockly/core/workspace_dragger.js
                new file mode 100644
                index 000000000..5c45aab3f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/workspace_dragger.js
                @@ -0,0 +1,132 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Methods for dragging a workspace visually.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.WorkspaceDragger');
                +
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.asserts');
                +
                +
                +/**
                + * Class for a workspace dragger.  It moves the workspace around when it is
                + * being dragged by a mouse or touch.
                + * Note that the workspace itself manages whether or not it has a drag surface
                + * and how to do translations based on that.  This simply passes the right
                + * commands based on events.
                + * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag.
                + * @constructor
                + */
                +Blockly.WorkspaceDragger = function(workspace) {
                +  /**
                +   * @type {!Blockly.WorkspaceSvg}
                +   * @private
                +   */
                +  this.workspace_ = workspace;
                +
                +  /**
                +   * The workspace's metrics object at the beginning of the drag.  Contains size
                +   * and position metrics of a workspace.
                +   * Coordinate system: pixel coordinates.
                +   * @type {!Object}
                +   * @private
                +   */
                +  this.startDragMetrics_ = workspace.getMetrics();
                +
                +  /**
                +   * The scroll position of the workspace at the beginning of the drag.
                +   * Coordinate system: pixel coordinates.
                +   * @type {!goog.math.Coordinate}
                +   * @private
                +   */
                +  this.startScrollXY_ = new goog.math.Coordinate(workspace.scrollX,
                +        workspace.scrollY);
                +};
                +
                +/**
                + * Sever all links from this object.
                + * @package
                + */
                +Blockly.WorkspaceDragger.prototype.dispose = function() {
                +  this.workspace_ = null;
                +};
                +
                +/**
                + * Start dragging the workspace.
                + * @package
                + */
                +Blockly.WorkspaceDragger.prototype.startDrag = function() {
                +  if (Blockly.selected) {
                +    Blockly.selected.unselect();
                +  }
                +  this.workspace_.setupDragSurface();
                +};
                +
                +/**
                + * Finish dragging the workspace and put everything back where it belongs.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at the start of the drag, in pixel coordinates.
                + * @package
                + */
                +Blockly.WorkspaceDragger.prototype.endDrag = function(currentDragDeltaXY) {
                +  // Make sure everything is up to date.
                +  this.drag(currentDragDeltaXY);
                +  this.workspace_.resetDragSurface();
                +};
                +
                +/**
                + * Move the workspace based on the most recent mouse movements.
                + * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
                + *     moved from the position at the start of the drag, in pixel coordinates.
                + * @package
                + */
                +Blockly.WorkspaceDragger.prototype.drag = function(currentDragDeltaXY) {
                +  var metrics = this.startDragMetrics_;
                +  var newXY = goog.math.Coordinate.sum(this.startScrollXY_, currentDragDeltaXY);
                +
                +  // Bound the new XY based on workspace bounds.
                +  var x = Math.min(newXY.x, -metrics.contentLeft);
                +  var y = Math.min(newXY.y, -metrics.contentTop);
                +  x = Math.max(x, metrics.viewWidth - metrics.contentLeft -
                +               metrics.contentWidth);
                +  y = Math.max(y, metrics.viewHeight - metrics.contentTop -
                +               metrics.contentHeight);
                +
                +  x = -x - metrics.contentLeft;
                +  y = -y - metrics.contentTop;
                +
                +  this.updateScroll_(x, y);
                +};
                +
                +/**
                + * Move the scrollbars to drag the workspace.
                + * x and y are in pixels.
                + * @param {number} x The new x position to move the scrollbar to.
                + * @param {number} y The new y position to move the scrollbar to.
                + * @private
                + */
                +Blockly.WorkspaceDragger.prototype.updateScroll_ = function(x, y) {
                +  this.workspace_.scrollbar.set(x, y);
                +};
                diff --git a/blockly/webif/static/blockly/core/workspace_svg.js b/blockly/webif/static/blockly/core/workspace_svg.js
                new file mode 100644
                index 000000000..c4c783600
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/workspace_svg.js
                @@ -0,0 +1,1796 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a workspace rendered as SVG.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.WorkspaceSvg');
                +
                +// TODO(scr): Fix circular dependencies
                +//goog.require('Blockly.BlockSvg');
                +goog.require('Blockly.ConnectionDB');
                +goog.require('Blockly.constants');
                +goog.require('Blockly.Gesture');
                +goog.require('Blockly.Grid');
                +goog.require('Blockly.Options');
                +goog.require('Blockly.ScrollbarPair');
                +goog.require('Blockly.Touch');
                +goog.require('Blockly.Trashcan');
                +goog.require('Blockly.Workspace');
                +goog.require('Blockly.WorkspaceAudio');
                +goog.require('Blockly.WorkspaceDragSurfaceSvg');
                +goog.require('Blockly.Xml');
                +goog.require('Blockly.ZoomControls');
                +
                +goog.require('goog.array');
                +goog.require('goog.dom');
                +goog.require('goog.math.Coordinate');
                +goog.require('goog.userAgent');
                +
                +
                +/**
                + * Class for a workspace.  This is an onscreen area with optional trashcan,
                + * scrollbars, bubbles, and dragging.
                + * @param {!Blockly.Options} options Dictionary of options.
                + * @param {Blockly.BlockDragSurfaceSvg=} opt_blockDragSurface Drag surface for
                + *     blocks.
                + * @param {Blockly.WorkspaceDragSurfaceSvg=} opt_wsDragSurface Drag surface for
                + *     the workspace.
                + * @extends {Blockly.Workspace}
                + * @constructor
                + */
                +Blockly.WorkspaceSvg = function(options, opt_blockDragSurface, opt_wsDragSurface) {
                +  Blockly.WorkspaceSvg.superClass_.constructor.call(this, options);
                +  this.getMetrics =
                +      options.getMetrics || Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_;
                +  this.setMetrics =
                +      options.setMetrics || Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_;
                +
                +  Blockly.ConnectionDB.init(this);
                +
                +  if (opt_blockDragSurface) {
                +    this.blockDragSurface_ = opt_blockDragSurface;
                +  }
                +
                +  if (opt_wsDragSurface) {
                +    this.workspaceDragSurface_ = opt_wsDragSurface;
                +  }
                +
                +  this.useWorkspaceDragSurface_ =
                +      this.workspaceDragSurface_ && Blockly.utils.is3dSupported();
                +
                +  /**
                +   * List of currently highlighted blocks.  Block highlighting is often used to
                +   * visually mark blocks currently being executed.
                +   * @type !Array.<!Blockly.BlockSvg>
                +   * @private
                +   */
                +  this.highlightedBlocks_ = [];
                +
                +  /**
                +   * Object in charge of loading, storing, and playing audio for a workspace.
                +   * @type {Blockly.WorkspaceAudio}
                +   * @private
                +   */
                +  this.audioManager_ = new Blockly.WorkspaceAudio(options.parentWorkspace);
                +
                +  /**
                +   * This workspace's grid object or null.
                +   * @type {Blockly.Grid}
                +   * @private
                +   */
                +  this.grid_ = this.options.gridPattern ?
                +      new Blockly.Grid(options.gridPattern, options.gridOptions) : null;
                +
                +  this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,
                +      Blockly.Variables.flyoutCategory);
                +  this.registerToolboxCategoryCallback(Blockly.PROCEDURE_CATEGORY_NAME,
                +      Blockly.Procedures.flyoutCategory);
                +};
                +goog.inherits(Blockly.WorkspaceSvg, Blockly.Workspace);
                +
                +/**
                + * A wrapper function called when a resize event occurs.
                + * You can pass the result to `unbindEvent_`.
                + * @type {Array.<!Array>}
                + */
                +Blockly.WorkspaceSvg.prototype.resizeHandlerWrapper_ = null;
                +
                +/**
                + * The render status of an SVG workspace.
                + * Returns `true` for visible workspaces and `false` for non-visible,
                + * or headless, workspaces.
                + * @type {boolean}
                + */
                +Blockly.WorkspaceSvg.prototype.rendered = true;
                +
                +/**
                + * Is this workspace the surface for a flyout?
                + * @type {boolean}
                + */
                +Blockly.WorkspaceSvg.prototype.isFlyout = false;
                +
                +/**
                + * Is this workspace the surface for a mutator?
                + * @type {boolean}
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.isMutator = false;
                +
                +/**
                + * Whether this workspace has resizes enabled.
                + * Disable during batch operations for a performance improvement.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.resizesEnabled_ = true;
                +
                +/**
                + * Current horizontal scrolling offset in pixel units.
                + * @type {number}
                + */
                +Blockly.WorkspaceSvg.prototype.scrollX = 0;
                +
                +/**
                + * Current vertical scrolling offset in pixel units.
                + * @type {number}
                + */
                +Blockly.WorkspaceSvg.prototype.scrollY = 0;
                +
                +/**
                + * Horizontal scroll value when scrolling started in pixel units.
                + * @type {number}
                + */
                +Blockly.WorkspaceSvg.prototype.startScrollX = 0;
                +
                +/**
                + * Vertical scroll value when scrolling started in pixel units.
                + * @type {number}
                + */
                +Blockly.WorkspaceSvg.prototype.startScrollY = 0;
                +
                +/**
                + * Distance from mouse to object being dragged.
                + * @type {goog.math.Coordinate}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.dragDeltaXY_ = null;
                +
                +/**
                + * Current scale.
                + * @type {number}
                + */
                +Blockly.WorkspaceSvg.prototype.scale = 1;
                +
                +/**
                + * The workspace's trashcan (if any).
                + * @type {Blockly.Trashcan}
                + */
                +Blockly.WorkspaceSvg.prototype.trashcan = null;
                +
                +/**
                + * This workspace's scrollbars, if they exist.
                + * @type {Blockly.ScrollbarPair}
                + */
                +Blockly.WorkspaceSvg.prototype.scrollbar = null;
                +
                +/**
                + * The current gesture in progress on this workspace, if any.
                + * @type {Blockly.Gesture}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.currentGesture_ = null;
                +
                +/**
                + * This workspace's surface for dragging blocks, if it exists.
                + * @type {Blockly.BlockDragSurfaceSvg}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.blockDragSurface_ = null;
                +
                +/**
                + * This workspace's drag surface, if it exists.
                + * @type {Blockly.WorkspaceDragSurfaceSvg}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.workspaceDragSurface_ = null;
                +
                +/**
                +  * Whether to move workspace to the drag surface when it is dragged.
                +  * True if it should move, false if it should be translated directly.
                +  * @type {boolean}
                +  * @private
                +  */
                +Blockly.WorkspaceSvg.prototype.useWorkspaceDragSurface_ = false;
                +
                +/**
                + * Whether the drag surface is actively in use. When true, calls to
                + * translate will translate the drag surface instead of the translating the
                + * workspace directly.
                + * This is set to true in setupDragSurface and to false in resetDragSurface.
                + * @type {boolean}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.isDragSurfaceActive_ = false;
                +
                +/**
                + * Last known position of the page scroll.
                + * This is used to determine whether we have recalculated screen coordinate
                + * stuff since the page scrolled.
                + * @type {!goog.math.Coordinate}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_ = null;
                +
                +/**
                + * Map from function names to callbacks, for deciding what to do when a button
                + * is clicked.
                + * @type {!Object<string, function(!Blockly.FlyoutButton)>}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_ = {};
                +
                +/**
                + * Map from function names to callbacks, for deciding what to do when a custom
                + * toolbox category is opened.
                + * @type {!Object<string, function(!Blockly.Workspace):!Array<!Element>>}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.toolboxCategoryCallbacks_ = {};
                +
                +/**
                + * Inverted screen CTM, for use in mouseToSvg.
                + * @type {SVGMatrix}
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.inverseScreenCTM_ = null;
                +
                +/**
                + * Getter for the inverted screen CTM.
                + * @return {SVGMatrix} The matrix to use in mouseToSvg
                + */
                +Blockly.WorkspaceSvg.prototype.getInverseScreenCTM = function() {
                +  return this.inverseScreenCTM_;
                +};
                +
                +/**
                + * Update the inverted screen CTM.
                + */
                +Blockly.WorkspaceSvg.prototype.updateInverseScreenCTM = function() {
                +  var ctm = this.getParentSvg().getScreenCTM();
                +  if (ctm) {
                +    this.inverseScreenCTM_ = ctm.inverse();
                +  }
                +};
                +
                +/**
                + * Return the absolute coordinates of the top-left corner of this element,
                + * scales that after canvas SVG element, if it's a descendant.
                + * The origin (0,0) is the top-left corner of the Blockly SVG.
                + * @param {!Element} element Element to find the coordinates of.
                + * @return {!goog.math.Coordinate} Object with .x and .y properties.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.getSvgXY = function(element) {
                +  var x = 0;
                +  var y = 0;
                +  var scale = 1;
                +  if (goog.dom.contains(this.getCanvas(), element) ||
                +      goog.dom.contains(this.getBubbleCanvas(), element)) {
                +    // Before the SVG canvas, scale the coordinates.
                +    scale = this.scale;
                +  }
                +  do {
                +    // Loop through this block and every parent.
                +    var xy = Blockly.utils.getRelativeXY(element);
                +    if (element == this.getCanvas() ||
                +        element == this.getBubbleCanvas()) {
                +      // After the SVG canvas, don't scale the coordinates.
                +      scale = 1;
                +    }
                +    x += xy.x * scale;
                +    y += xy.y * scale;
                +    element = element.parentNode;
                +  } while (element && element != this.getParentSvg());
                +  return new goog.math.Coordinate(x, y);
                +};
                +
                +/**
                + * Return the position of the workspace origin relative to the injection div
                + * origin in pixels.
                + * The workspace origin is where a block would render at position (0, 0).
                + * It is not the upper left corner of the workspace SVG.
                + * @return {!goog.math.Coordinate} Offset in pixels.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.getOriginOffsetInPixels = function() {
                +  return Blockly.utils.getInjectionDivXY_(this.svgBlockCanvas_);
                +};
                +
                +/**
                + * Save resize handler data so we can delete it later in dispose.
                + * @param {!Array.<!Array>} handler Data that can be passed to unbindEvent_.
                + */
                +Blockly.WorkspaceSvg.prototype.setResizeHandlerWrapper = function(handler) {
                +  this.resizeHandlerWrapper_ = handler;
                +};
                +
                +/**
                + * Create the workspace DOM elements.
                + * @param {string=} opt_backgroundClass Either 'blocklyMainBackground' or
                + *     'blocklyMutatorBackground'.
                + * @return {!Element} The workspace's SVG group.
                + */
                +Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
                +  /**
                +   * <g class="blocklyWorkspace">
                +   *   <rect class="blocklyMainBackground" height="100%" width="100%"></rect>
                +   *   [Trashcan and/or flyout may go here]
                +   *   <g class="blocklyBlockCanvas"></g>
                +   *   <g class="blocklyBubbleCanvas"></g>
                +   * </g>
                +   * @type {SVGElement}
                +   */
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyWorkspace'}, null);
                +
                +  // Note that a <g> alone does not receive mouse events--it must have a
                +  // valid target inside it.  If no background class is specified, as in the
                +  // flyout, the workspace will not receive mouse events.
                +  if (opt_backgroundClass) {
                +    /** @type {SVGElement} */
                +    this.svgBackground_ = Blockly.utils.createSvgElement('rect',
                +        {'height': '100%', 'width': '100%', 'class': opt_backgroundClass},
                +        this.svgGroup_);
                +
                +    if (opt_backgroundClass == 'blocklyMainBackground' && this.grid_) {
                +      this.svgBackground_.style.fill =
                +          'url(#' + this.grid_.getPatternId() + ')';
                +    }
                +  }
                +  /** @type {SVGElement} */
                +  this.svgBlockCanvas_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyBlockCanvas'}, this.svgGroup_, this);
                +  /** @type {SVGElement} */
                +  this.svgBubbleCanvas_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyBubbleCanvas'}, this.svgGroup_, this);
                +  var bottom = Blockly.Scrollbar.scrollbarThickness;
                +  if (this.options.hasTrashcan) {
                +    bottom = this.addTrashcan_(bottom);
                +  }
                +  if (this.options.zoomOptions && this.options.zoomOptions.controls) {
                +    bottom = this.addZoomControls_(bottom);
                +  }
                +
                +  if (!this.isFlyout) {
                +    Blockly.bindEventWithChecks_(this.svgGroup_, 'mousedown', this,
                +        this.onMouseDown_);
                +    if (this.options.zoomOptions && this.options.zoomOptions.wheel) {
                +      // Mouse-wheel.
                +      Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this,
                +          this.onMouseWheel_);
                +    }
                +  }
                +
                +  // Determine if there needs to be a category tree, or a simple list of
                +  // blocks.  This cannot be changed later, since the UI is very different.
                +  if (this.options.hasCategories) {
                +    /**
                +     * @type {Blockly.Toolbox}
                +     * @private
                +     */
                +    this.toolbox_ = new Blockly.Toolbox(this);
                +  }
                +  if (this.grid_) {
                +    this.grid_.update(this.scale);
                +  }
                +  this.recordDeleteAreas();
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Dispose of this workspace.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.WorkspaceSvg.prototype.dispose = function() {
                +  // Stop rerendering.
                +  this.rendered = false;
                +  if (this.currentGesture_) {
                +    this.currentGesture_.cancel();
                +  }
                +  Blockly.WorkspaceSvg.superClass_.dispose.call(this);
                +  if (this.svgGroup_) {
                +    goog.dom.removeNode(this.svgGroup_);
                +    this.svgGroup_ = null;
                +  }
                +  this.svgBlockCanvas_ = null;
                +  this.svgBubbleCanvas_ = null;
                +  if (this.toolbox_) {
                +    this.toolbox_.dispose();
                +    this.toolbox_ = null;
                +  }
                +  if (this.flyout_) {
                +    this.flyout_.dispose();
                +    this.flyout_ = null;
                +  }
                +  if (this.trashcan) {
                +    this.trashcan.dispose();
                +    this.trashcan = null;
                +  }
                +  if (this.scrollbar) {
                +    this.scrollbar.dispose();
                +    this.scrollbar = null;
                +  }
                +  if (this.zoomControls_) {
                +    this.zoomControls_.dispose();
                +    this.zoomControls_ = null;
                +  }
                +
                +  if (this.audioManager_) {
                +    this.audioManager_.dispose();
                +    this.audioManager_ = null;
                +  }
                +
                +  if (this.grid_) {
                +    this.grid_.dispose();
                +    this.grid_ = null;
                +  }
                +
                +  if (this.toolboxCategoryCallbacks_) {
                +    this.toolboxCategoryCallbacks_ = null;
                +  }
                +  if (this.flyoutButtonCallbacks_) {
                +    this.flyoutButtonCallbacks_ = null;
                +  }
                +  if (!this.options.parentWorkspace) {
                +    // Top-most workspace.  Dispose of the div that the
                +    // svg is injected into (i.e. injectionDiv).
                +    goog.dom.removeNode(this.getParentSvg().parentNode);
                +  }
                +  if (this.resizeHandlerWrapper_) {
                +    Blockly.unbindEvent_(this.resizeHandlerWrapper_);
                +    this.resizeHandlerWrapper_ = null;
                +  }
                +};
                +
                +/**
                + * Obtain a newly created block.
                + * @param {?string} prototypeName Name of the language object containing
                + *     type-specific functions for this block.
                + * @param {string=} opt_id Optional ID.  Use this ID if provided, otherwise
                + *     create a new ID.
                + * @return {!Blockly.BlockSvg} The created block.
                + */
                +Blockly.WorkspaceSvg.prototype.newBlock = function(prototypeName, opt_id) {
                +  return new Blockly.BlockSvg(this, prototypeName, opt_id);
                +};
                +
                +/**
                + * Add a trashcan.
                + * @param {number} bottom Distance from workspace bottom to bottom of trashcan.
                + * @return {number} Distance from workspace bottom to the top of trashcan.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.addTrashcan_ = function(bottom) {
                +  /** @type {Blockly.Trashcan} */
                +  this.trashcan = new Blockly.Trashcan(this);
                +  var svgTrashcan = this.trashcan.createDom();
                +  this.svgGroup_.insertBefore(svgTrashcan, this.svgBlockCanvas_);
                +  return this.trashcan.init(bottom);
                +};
                +
                +/**
                + * Add zoom controls.
                + * @param {number} bottom Distance from workspace bottom to bottom of controls.
                + * @return {number} Distance from workspace bottom to the top of controls.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.addZoomControls_ = function(bottom) {
                +  /** @type {Blockly.ZoomControls} */
                +  this.zoomControls_ = new Blockly.ZoomControls(this);
                +  var svgZoomControls = this.zoomControls_.createDom();
                +  this.svgGroup_.appendChild(svgZoomControls);
                +  return this.zoomControls_.init(bottom);
                +};
                +
                +/**
                + * Add a flyout element in an element with the given tag name.
                + * @param {string} tagName What type of tag the flyout belongs in.
                + * @return {!Element} The element containing the flyout dom.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.addFlyout_ = function(tagName) {
                +  var workspaceOptions = {
                +    disabledPatternId: this.options.disabledPatternId,
                +    parentWorkspace: this,
                +    RTL: this.RTL,
                +    oneBasedIndex: this.options.oneBasedIndex,
                +    horizontalLayout: this.horizontalLayout,
                +    toolboxPosition: this.options.toolboxPosition
                +  };
                +  /**
                +   * @type {!Blockly.Flyout}
                +   * @private
                +   */
                +  this.flyout_ = null;
                +  if (this.horizontalLayout) {
                +    this.flyout_ = new Blockly.HorizontalFlyout(workspaceOptions);
                +  } else {
                +    this.flyout_ = new Blockly.VerticalFlyout(workspaceOptions);
                +  }
                +  this.flyout_.autoClose = false;
                +
                +  // Return the element  so that callers can place it in their desired
                +  // spot in the dom.  For exmaple, mutator flyouts do not go in the same place
                +  // as main workspace flyouts.
                +  return this.flyout_.createDom(tagName);
                +};
                +
                +/**
                + * Getter for the flyout associated with this workspace.  This flyout may be
                + * owned by either the toolbox or the workspace, depending on toolbox
                + * configuration.  It will be null if there is no flyout.
                + * @return {Blockly.Flyout} The flyout on this workspace.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.getFlyout_ = function() {
                +  if (this.flyout_) {
                +    return this.flyout_;
                +  }
                +  if (this.toolbox_) {
                +    return this.toolbox_.flyout_;
                +  }
                +  return null;
                +};
                +
                +/**
                + * Update items that use screen coordinate calculations
                + * because something has changed (e.g. scroll position, window size).
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.updateScreenCalculations_ = function() {
                +  this.updateInverseScreenCTM();
                +  this.recordDeleteAreas();
                +};
                +
                +/**
                + * If enabled, resize the parts of the workspace that change when the workspace
                + * contents (e.g. block positions) change.  This will also scroll the
                + * workspace contents if needed.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.resizeContents = function() {
                +  if (!this.resizesEnabled_ || !this.rendered) {
                +    return;
                +  }
                +  if (this.scrollbar) {
                +    // TODO(picklesrus): Once rachel-fenichel's scrollbar refactoring
                +    // is complete, call the method that only resizes scrollbar
                +    // based on contents.
                +    this.scrollbar.resize();
                +  }
                +  this.updateInverseScreenCTM();
                +};
                +
                +/**
                + * Resize and reposition all of the workspace chrome (toolbox,
                + * trash, scrollbars etc.)
                + * This should be called when something changes that
                + * requires recalculating dimensions and positions of the
                + * trash, zoom, toolbox, etc. (e.g. window resize).
                + */
                +Blockly.WorkspaceSvg.prototype.resize = function() {
                +  if (this.toolbox_) {
                +    this.toolbox_.position();
                +  }
                +  if (this.flyout_) {
                +    this.flyout_.position();
                +  }
                +  if (this.trashcan) {
                +    this.trashcan.position();
                +  }
                +  if (this.zoomControls_) {
                +    this.zoomControls_.position();
                +  }
                +  if (this.scrollbar) {
                +    this.scrollbar.resize();
                +  }
                +  this.updateScreenCalculations_();
                +};
                +
                +/**
                + * Resizes and repositions workspace chrome if the page has a new
                + * scroll position.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled
                +    = function() {
                +  /* eslint-disable indent */
                +  var currScroll = goog.dom.getDocumentScroll();
                +  if (!goog.math.Coordinate.equals(this.lastRecordedPageScroll_,
                +     currScroll)) {
                +    this.lastRecordedPageScroll_ = currScroll;
                +    this.updateScreenCalculations_();
                +  }
                +}; /* eslint-enable indent */
                +
                +/**
                + * Get the SVG element that forms the drawing surface.
                + * @return {!Element} SVG element.
                + */
                +Blockly.WorkspaceSvg.prototype.getCanvas = function() {
                +  return this.svgBlockCanvas_;
                +};
                +
                +/**
                + * Get the SVG element that forms the bubble surface.
                + * @return {!SVGGElement} SVG element.
                + */
                +Blockly.WorkspaceSvg.prototype.getBubbleCanvas = function() {
                +  return this.svgBubbleCanvas_;
                +};
                +
                +/**
                + * Get the SVG element that contains this workspace.
                + * @return {!Element} SVG element.
                + */
                +Blockly.WorkspaceSvg.prototype.getParentSvg = function() {
                +  if (this.cachedParentSvg_) {
                +    return this.cachedParentSvg_;
                +  }
                +  var element = this.svgGroup_;
                +  while (element) {
                +    if (element.tagName == 'svg') {
                +      this.cachedParentSvg_ = element;
                +      return element;
                +    }
                +    element = element.parentNode;
                +  }
                +  return null;
                +};
                +
                +/**
                + * Translate this workspace to new coordinates.
                + * @param {number} x Horizontal translation.
                + * @param {number} y Vertical translation.
                + */
                +Blockly.WorkspaceSvg.prototype.translate = function(x, y) {
                +  if (this.useWorkspaceDragSurface_ && this.isDragSurfaceActive_) {
                +    this.workspaceDragSurface_.translateSurface(x,y);
                +  } else {
                +    var translation = 'translate(' + x + ',' + y + ') ' +
                +        'scale(' + this.scale + ')';
                +    this.svgBlockCanvas_.setAttribute('transform', translation);
                +    this.svgBubbleCanvas_.setAttribute('transform', translation);
                +  }
                +  // Now update the block drag surface if we're using one.
                +  if (this.blockDragSurface_) {
                +    this.blockDragSurface_.translateAndScaleGroup(x, y, this.scale);
                +  }
                +};
                +
                +/**
                + * Called at the end of a workspace drag to take the contents
                + * out of the drag surface and put them back into the workspace svg.
                + * Does nothing if the workspace drag surface is not enabled.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.resetDragSurface = function() {
                +  // Don't do anything if we aren't using a drag surface.
                +  if (!this.useWorkspaceDragSurface_) {
                +    return;
                +  }
                +
                +  this.isDragSurfaceActive_ = false;
                +
                +  var trans = this.workspaceDragSurface_.getSurfaceTranslation();
                +  this.workspaceDragSurface_.clearAndHide(this.svgGroup_);
                +  var translation = 'translate(' + trans.x + ',' + trans.y + ') ' +
                +        'scale(' + this.scale + ')';
                +  this.svgBlockCanvas_.setAttribute('transform', translation);
                +  this.svgBubbleCanvas_.setAttribute('transform', translation);
                +};
                +
                +/**
                + * Called at the beginning of a workspace drag to move contents of
                + * the workspace to the drag surface.
                + * Does nothing if the drag surface is not enabled.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.setupDragSurface = function() {
                +  // Don't do anything if we aren't using a drag surface.
                +  if (!this.useWorkspaceDragSurface_) {
                +    return;
                +  }
                +
                +  // This can happen if the user starts a drag, mouses up outside of the
                +  // document where the mouseup listener is registered (e.g. outside of an
                +  // iframe) and then moves the mouse back in the workspace.  On mobile and ff,
                +  // we get the mouseup outside the frame. On chrome and safari desktop we do
                +  // not.
                +  if (this.isDragSurfaceActive_) {
                +    return;
                +  }
                +
                +  this.isDragSurfaceActive_ = true;
                +
                +  // Figure out where we want to put the canvas back.  The order
                +  // in the is important because things are layered.
                +  var previousElement = this.svgBlockCanvas_.previousSibling;
                +  var width = this.getParentSvg().getAttribute("width");
                +  var height = this.getParentSvg().getAttribute("height");
                +  var coord = Blockly.utils.getRelativeXY(this.svgBlockCanvas_);
                +  this.workspaceDragSurface_.setContentsAndShow(this.svgBlockCanvas_,
                +      this.svgBubbleCanvas_, previousElement, width, height, this.scale);
                +  this.workspaceDragSurface_.translateSurface(coord.x, coord.y);
                +};
                +
                +/**
                + * Returns the horizontal offset of the workspace.
                + * Intended for LTR/RTL compatibility in XML.
                + * @return {number} Width.
                + */
                +Blockly.WorkspaceSvg.prototype.getWidth = function() {
                +  var metrics = this.getMetrics();
                +  return metrics ? metrics.viewWidth / this.scale : 0;
                +};
                +
                +/**
                + * Toggles the visibility of the workspace.
                + * Currently only intended for main workspace.
                + * @param {boolean} isVisible True if workspace should be visible.
                + */
                +Blockly.WorkspaceSvg.prototype.setVisible = function(isVisible) {
                +
                +  // Tell the scrollbar whether its container is visible so it can
                +  // tell when to hide itself.
                +  if (this.scrollbar) {
                +    this.scrollbar.setContainerVisible(isVisible);
                +  }
                +
                +  // Tell the flyout whether its container is visible so it can
                +  // tell when to hide itself.
                +  if (this.getFlyout_()) {
                +    this.getFlyout_().setContainerVisible(isVisible);
                +  }
                +
                +  this.getParentSvg().style.display = isVisible ? 'block' : 'none';
                +  if (this.toolbox_) {
                +    // Currently does not support toolboxes in mutators.
                +    this.toolbox_.HtmlDiv.style.display = isVisible ? 'block' : 'none';
                +  }
                +  if (isVisible) {
                +    this.render();
                +    if (this.toolbox_) {
                +      this.toolbox_.position();
                +    }
                +  } else {
                +    Blockly.hideChaff(true);
                +  }
                +};
                +
                +/**
                + * Render all blocks in workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.render = function() {
                +  // Generate list of all blocks.
                +  var blocks = this.getAllBlocks();
                +  // Render each block.
                +  for (var i = blocks.length - 1; i >= 0; i--) {
                +    blocks[i].render(false);
                +  }
                +};
                +
                +/**
                + * Was used back when block highlighting (for execution) and block selection
                + * (for editing) were the same thing.
                + * Any calls of this function can be deleted.
                + * @deprecated October 2016
                + */
                +Blockly.WorkspaceSvg.prototype.traceOn = function() {
                +  console.warn('Deprecated call to traceOn, delete this.');
                +};
                +
                +/**
                + * Highlight or unhighlight a block in the workspace.  Block highlighting is
                + * often used to visually mark blocks currently being executed.
                + * @param {?string} id ID of block to highlight/unhighlight,
                + *   or null for no block (used to unhighlight all blocks).
                + * @param {boolean=} opt_state If undefined, highlight specified block and
                + * automatically unhighlight all others.  If true or false, manually
                + * highlight/unhighlight the specified block.
                + */
                +Blockly.WorkspaceSvg.prototype.highlightBlock = function(id, opt_state) {
                +  if (opt_state === undefined) {
                +    // Unhighlight all blocks.
                +    for (var i = 0, block; block = this.highlightedBlocks_[i]; i++) {
                +      block.setHighlighted(false);
                +    }
                +    this.highlightedBlocks_.length = 0;
                +  }
                +  // Highlight/unhighlight the specified block.
                +  var block = id ? this.getBlockById(id) : null;
                +  if (block) {
                +    var state = (opt_state === undefined) || opt_state;
                +    // Using Set here would be great, but at the cost of IE10 support.
                +    if (!state) {
                +      goog.array.remove(this.highlightedBlocks_, block);
                +    } else if (this.highlightedBlocks_.indexOf(block) == -1) {
                +      this.highlightedBlocks_.push(block);
                +    }
                +    block.setHighlighted(state);
                +  }
                +};
                +
                +/**
                + * Paste the provided block onto the workspace.
                + * @param {!Element} xmlBlock XML block element.
                + */
                +Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) {
                +  if (!this.rendered || xmlBlock.getElementsByTagName('block').length >=
                +      this.remainingCapacity()) {
                +    return;
                +  }
                +  if (this.currentGesture_) {
                +    this.currentGesture_.cancel();  // Dragging while pasting?  No.
                +  }
                +  Blockly.Events.disable();
                +  try {
                +    var block = Blockly.Xml.domToBlock(xmlBlock, this);
                +    // Rerender to get around problem with IE and Edge not measuring text
                +    // correctly when it is hidden.
                +    if (goog.userAgent.IE || goog.userAgent.EDGE) {
                +      var blocks = block.getDescendants();
                +      for (var i = blocks.length - 1; i >= 0; i--) {
                +        blocks[i].render(false);
                +      }
                +    }
                +    // Move the duplicate to original position.
                +    var blockX = parseInt(xmlBlock.getAttribute('x'), 10);
                +    var blockY = parseInt(xmlBlock.getAttribute('y'), 10);
                +    if (!isNaN(blockX) && !isNaN(blockY)) {
                +      if (this.RTL) {
                +        blockX = -blockX;
                +      }
                +      // Offset block until not clobbering another block and not in connection
                +      // distance with neighbouring blocks.
                +      do {
                +        var collide = false;
                +        var allBlocks = this.getAllBlocks();
                +        for (var i = 0, otherBlock; otherBlock = allBlocks[i]; i++) {
                +          var otherXY = otherBlock.getRelativeToSurfaceXY();
                +          if (Math.abs(blockX - otherXY.x) <= 1 &&
                +              Math.abs(blockY - otherXY.y) <= 1) {
                +            collide = true;
                +            break;
                +          }
                +        }
                +        if (!collide) {
                +          // Check for blocks in snap range to any of its connections.
                +          var connections = block.getConnections_(false);
                +          for (var i = 0, connection; connection = connections[i]; i++) {
                +            var neighbour = connection.closest(Blockly.SNAP_RADIUS,
                +                new goog.math.Coordinate(blockX, blockY));
                +            if (neighbour.connection) {
                +              collide = true;
                +              break;
                +            }
                +          }
                +        }
                +        if (collide) {
                +          if (this.RTL) {
                +            blockX -= Blockly.SNAP_RADIUS;
                +          } else {
                +            blockX += Blockly.SNAP_RADIUS;
                +          }
                +          blockY += Blockly.SNAP_RADIUS * 2;
                +        }
                +      } while (collide);
                +      block.moveBy(blockX, blockY);
                +    }
                +  } finally {
                +    Blockly.Events.enable();
                +  }
                +  if (Blockly.Events.isEnabled() && !block.isShadow()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockCreate(block));
                +  }
                +  block.select();
                +};
                +
                +/**
                + * Refresh the toolbox unless there's a drag in progress.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.refreshToolboxSelection_ = function() {
                +  if (this.toolbox_ && this.toolbox_.flyout_ && !this.currentGesture_) {
                +    this.toolbox_.refreshSelection();
                +  }
                +};
                +
                +/**
                + * Rename a variable by updating its name in the variable list.
                + * TODO: google/blockly:#468
                + * @param {string} oldName Variable to rename.
                + * @param {string} newName New variable name.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.renameVariable = function(oldName, newName) {
                +  Blockly.WorkspaceSvg.superClass_.renameVariable.call(this, oldName, newName);
                +  this.refreshToolboxSelection_();
                +};
                +
                +/**
                + * Rename a variable by updating its name in the variable map.  Update the
                + *     flyout to show the renamed variable immediately.
                + * @param {string} id Id of the variable to rename.
                + * @param {string} newName New variable name.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.renameVariableById = function(id, newName) {
                +  Blockly.WorkspaceSvg.superClass_.renameVariableById.call(this, id, newName);
                +  this.refreshToolboxSelection_();
                +};
                +
                +/**
                + * Delete a variable by the passed in name.   Update the flyout to show
                + *     immediately that the variable is deleted.
                + * @param {string} name Name of variable to delete.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.deleteVariable = function(name) {
                +  Blockly.WorkspaceSvg.superClass_.deleteVariable.call(this, name);
                +  this.refreshToolboxSelection_();
                +};
                +
                +/**
                + * Delete a variable by the passed in id.   Update the flyout to show
                + *     immediately that the variable is deleted.
                + * @param {string} id Id of variable to delete.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) {
                +  Blockly.WorkspaceSvg.superClass_.deleteVariableById.call(this, id);
                +  this.refreshToolboxSelection_();
                +};
                +
                +/**
                + * Create a new variable with the given name.  Update the flyout to show the new
                + *     variable immediately.
                + * @param {string} name The new variable's name.
                + * @param {string=} opt_type The type of the variable like 'int' or 'string'.
                + *     Does not need to be unique. Field_variable can filter variables based on
                + *     their type. This will default to '' which is a specific type.
                + * @param {string=} opt_id The unique id of the variable. This will default to
                + *     a UUID.
                + * @return {?Blockly.VariableModel} The newly created variable.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.createVariable = function(name, opt_type, opt_id) {
                +  var newVar = Blockly.WorkspaceSvg.superClass_.createVariable.call(this, name,
                +    opt_type, opt_id);
                +  this.refreshToolboxSelection_();
                +  return newVar;
                +};
                +
                +/**
                + * Make a list of all the delete areas for this workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.recordDeleteAreas = function() {
                +  if (this.trashcan) {
                +    this.deleteAreaTrash_ = this.trashcan.getClientRect();
                +  } else {
                +    this.deleteAreaTrash_ = null;
                +  }
                +  if (this.flyout_) {
                +    this.deleteAreaToolbox_ = this.flyout_.getClientRect();
                +  } else if (this.toolbox_) {
                +    this.deleteAreaToolbox_ = this.toolbox_.getClientRect();
                +  } else {
                +    this.deleteAreaToolbox_ = null;
                +  }
                +};
                +
                +/**
                + * Is the mouse event over a delete area (toolbox or non-closing flyout)?
                + * @param {!Event} e Mouse move event.
                + * @return {?number} Null if not over a delete area, or an enum representing
                + *     which delete area the event is over.
                + */
                +Blockly.WorkspaceSvg.prototype.isDeleteArea = function(e) {
                +  var xy = new goog.math.Coordinate(e.clientX, e.clientY);
                +  if (this.deleteAreaTrash_ && this.deleteAreaTrash_.contains(xy)) {
                +    return Blockly.DELETE_AREA_TRASH;
                +  }
                +  if (this.deleteAreaToolbox_ && this.deleteAreaToolbox_.contains(xy)) {
                +    return Blockly.DELETE_AREA_TOOLBOX;
                +  }
                +  return Blockly.DELETE_AREA_NONE;
                +};
                +
                +/**
                + * Handle a mouse-down on SVG drawing surface.
                + * @param {!Event} e Mouse down event.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.onMouseDown_ = function(e) {
                +  var gesture = this.getGesture(e);
                +  if (gesture) {
                +    gesture.handleWsStart(e, this);
                +  }
                +};
                +
                +/**
                + * Start tracking a drag of an object on this workspace.
                + * @param {!Event} e Mouse down event.
                + * @param {!goog.math.Coordinate} xy Starting location of object.
                + */
                +Blockly.WorkspaceSvg.prototype.startDrag = function(e, xy) {
                +  // Record the starting offset between the bubble's location and the mouse.
                +  var point = Blockly.utils.mouseToSvg(e, this.getParentSvg(),
                +      this.getInverseScreenCTM());
                +  // Fix scale of mouse event.
                +  point.x /= this.scale;
                +  point.y /= this.scale;
                +  this.dragDeltaXY_ = goog.math.Coordinate.difference(xy, point);
                +};
                +
                +/**
                + * Track a drag of an object on this workspace.
                + * @param {!Event} e Mouse move event.
                + * @return {!goog.math.Coordinate} New location of object.
                + */
                +Blockly.WorkspaceSvg.prototype.moveDrag = function(e) {
                +  var point = Blockly.utils.mouseToSvg(e, this.getParentSvg(),
                +      this.getInverseScreenCTM());
                +  // Fix scale of mouse event.
                +  point.x /= this.scale;
                +  point.y /= this.scale;
                +  return goog.math.Coordinate.sum(this.dragDeltaXY_, point);
                +};
                +
                +/**
                + * Is the user currently dragging a block or scrolling the flyout/workspace?
                + * @return {boolean} True if currently dragging or scrolling.
                + */
                +Blockly.WorkspaceSvg.prototype.isDragging = function() {
                +  return this.currentGesture_ && this.currentGesture_.isDragging();
                +};
                +
                +/**
                + * Is this workspace draggable and scrollable?
                + * @return {boolean} True if this workspace may be dragged.
                + */
                +Blockly.WorkspaceSvg.prototype.isDraggable = function() {
                +  return !!this.scrollbar;
                +};
                +
                +/**
                + * Handle a mouse-wheel on SVG drawing surface.
                + * @param {!Event} e Mouse wheel event.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) {
                +  // TODO: Remove gesture cancellation and compensate for coordinate skew during
                +  // zoom.
                +  if (this.currentGesture_) {
                +    this.currentGesture_.cancel();
                +  }
                +  // The vertical scroll distance that corresponds to a click of a zoom button.
                +  var PIXELS_PER_ZOOM_STEP = 50;
                +  var delta = -e.deltaY / PIXELS_PER_ZOOM_STEP;
                +  var position = Blockly.utils.mouseToSvg(e, this.getParentSvg(),
                +      this.getInverseScreenCTM());
                +  this.zoom(position.x, position.y, delta);
                +  e.preventDefault();
                +};
                +
                +/**
                + * Calculate the bounding box for the blocks on the workspace.
                + * Coordinate system: workspace coordinates.
                + *
                + * @return {Object} Contains the position and size of the bounding box
                + *   containing the blocks on the workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.getBlocksBoundingBox = function() {
                +  var topBlocks = this.getTopBlocks(false);
                +  // There are no blocks, return empty rectangle.
                +  if (!topBlocks.length) {
                +    return {x: 0, y: 0, width: 0, height: 0};
                +  }
                +
                +  // Initialize boundary using the first block.
                +  var boundary = topBlocks[0].getBoundingRectangle();
                +
                +  // Start at 1 since the 0th block was used for initialization
                +  for (var i = 1; i < topBlocks.length; i++) {
                +    var blockBoundary = topBlocks[i].getBoundingRectangle();
                +    if (blockBoundary.topLeft.x < boundary.topLeft.x) {
                +      boundary.topLeft.x = blockBoundary.topLeft.x;
                +    }
                +    if (blockBoundary.bottomRight.x > boundary.bottomRight.x) {
                +      boundary.bottomRight.x = blockBoundary.bottomRight.x;
                +    }
                +    if (blockBoundary.topLeft.y < boundary.topLeft.y) {
                +      boundary.topLeft.y = blockBoundary.topLeft.y;
                +    }
                +    if (blockBoundary.bottomRight.y > boundary.bottomRight.y) {
                +      boundary.bottomRight.y = blockBoundary.bottomRight.y;
                +    }
                +  }
                +  return {
                +    x: boundary.topLeft.x,
                +    y: boundary.topLeft.y,
                +    width: boundary.bottomRight.x - boundary.topLeft.x,
                +    height: boundary.bottomRight.y - boundary.topLeft.y
                +  };
                +};
                +
                +/**
                + * Clean up the workspace by ordering all the blocks in a column.
                + */
                +Blockly.WorkspaceSvg.prototype.cleanUp = function() {
                +  Blockly.Events.setGroup(true);
                +  var topBlocks = this.getTopBlocks(true);
                +  var cursorY = 0;
                +  for (var i = 0, block; block = topBlocks[i]; i++) {
                +    var xy = block.getRelativeToSurfaceXY();
                +    block.moveBy(-xy.x, cursorY - xy.y);
                +    block.snapToGrid();
                +    cursorY = block.getRelativeToSurfaceXY().y +
                +        block.getHeightWidth().height + Blockly.BlockSvg.MIN_BLOCK_Y;
                +  }
                +  Blockly.Events.setGroup(false);
                +  // Fire an event to allow scrollbars to resize.
                +  this.resizeContents();
                +};
                +
                +/**
                + * Show the context menu for the workspace.
                + * @param {!Event} e Mouse event.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.showContextMenu_ = function(e) {
                +  if (this.options.readOnly || this.isFlyout) {
                +    return;
                +  }
                +  var menuOptions = [];
                +  var topBlocks = this.getTopBlocks(true);
                +  var eventGroup = Blockly.utils.genUid();
                +  var ws = this;
                +
                +  // Options to undo/redo previous action.
                +  var undoOption = {};
                +  undoOption.text = Blockly.Msg.UNDO;
                +  undoOption.enabled = this.undoStack_.length > 0;
                +  undoOption.callback = this.undo.bind(this, false);
                +  menuOptions.push(undoOption);
                +  var redoOption = {};
                +  redoOption.text = Blockly.Msg.REDO;
                +  redoOption.enabled = this.redoStack_.length > 0;
                +  redoOption.callback = this.undo.bind(this, true);
                +  menuOptions.push(redoOption);
                +
                +  // Option to clean up blocks.
                +  if (this.scrollbar) {
                +    var cleanOption = {};
                +    cleanOption.text = Blockly.Msg.CLEAN_UP;
                +    cleanOption.enabled = topBlocks.length > 1;
                +    cleanOption.callback = this.cleanUp.bind(this);
                +    menuOptions.push(cleanOption);
                +  }
                +
                +  // Add a little animation to collapsing and expanding.
                +  var DELAY = 10;
                +  if (this.options.collapse) {
                +    var hasCollapsedBlocks = false;
                +    var hasExpandedBlocks = false;
                +    for (var i = 0; i < topBlocks.length; i++) {
                +      var block = topBlocks[i];
                +      while (block) {
                +        if (block.isCollapsed()) {
                +          hasCollapsedBlocks = true;
                +        } else {
                +          hasExpandedBlocks = true;
                +        }
                +        block = block.getNextBlock();
                +      }
                +    }
                +
                +    /**
                +     * Option to collapse or expand top blocks.
                +     * @param {boolean} shouldCollapse Whether a block should collapse.
                +     * @private
                +     */
                +    var toggleOption = function(shouldCollapse) {
                +      var ms = 0;
                +      for (var i = 0; i < topBlocks.length; i++) {
                +        var block = topBlocks[i];
                +        while (block) {
                +          setTimeout(block.setCollapsed.bind(block, shouldCollapse), ms);
                +          block = block.getNextBlock();
                +          ms += DELAY;
                +        }
                +      }
                +    };
                +
                +    // Option to collapse top blocks.
                +    var collapseOption = {enabled: hasExpandedBlocks};
                +    collapseOption.text = Blockly.Msg.COLLAPSE_ALL;
                +    collapseOption.callback = function() {
                +      toggleOption(true);
                +    };
                +    menuOptions.push(collapseOption);
                +
                +    // Option to expand top blocks.
                +    var expandOption = {enabled: hasCollapsedBlocks};
                +    expandOption.text = Blockly.Msg.EXPAND_ALL;
                +    expandOption.callback = function() {
                +      toggleOption(false);
                +    };
                +    menuOptions.push(expandOption);
                +  }
                +
                +  // Option to delete all blocks.
                +  // Count the number of blocks that are deletable.
                +  var deleteList = [];
                +  function addDeletableBlocks(block) {
                +    if (block.isDeletable()) {
                +      deleteList = deleteList.concat(block.getDescendants());
                +    } else {
                +      var children = block.getChildren();
                +      for (var i = 0; i < children.length; i++) {
                +        addDeletableBlocks(children[i]);
                +      }
                +    }
                +  }
                +  for (var i = 0; i < topBlocks.length; i++) {
                +    addDeletableBlocks(topBlocks[i]);
                +  }
                +
                +  function deleteNext() {
                +    Blockly.Events.setGroup(eventGroup);
                +    var block = deleteList.shift();
                +    if (block) {
                +      if (block.workspace) {
                +        block.dispose(false, true);
                +        setTimeout(deleteNext, DELAY);
                +      } else {
                +        deleteNext();
                +      }
                +    }
                +    Blockly.Events.setGroup(false);
                +  }
                +
                +  var deleteOption = {
                +    text: deleteList.length == 1 ? Blockly.Msg.DELETE_BLOCK :
                +        Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(deleteList.length)),
                +    enabled: deleteList.length > 0,
                +    callback: function() {
                +      if (ws.currentGesture_) {
                +        ws.currentGesture_.cancel();
                +      }
                +      if (deleteList.length < 2 ) {
                +        deleteNext();
                +      } else {
                +        Blockly.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.
                +            replace('%1', deleteList.length),
                +            function(ok) {
                +              if (ok) {
                +                deleteNext();
                +              }
                +            });
                +      }
                +    }
                +  };
                +  menuOptions.push(deleteOption);
                +
                +  Blockly.ContextMenu.show(e, menuOptions, this.RTL);
                +};
                +
                +/**
                + * Modify the block tree on the existing toolbox.
                + * @param {Node|string} tree DOM tree of blocks, or text representation of same.
                + */
                +Blockly.WorkspaceSvg.prototype.updateToolbox = function(tree) {
                +  tree = Blockly.Options.parseToolboxTree(tree);
                +  if (!tree) {
                +    if (this.options.languageTree) {
                +      throw 'Can\'t nullify an existing toolbox.';
                +    }
                +    return;  // No change (null to null).
                +  }
                +  if (!this.options.languageTree) {
                +    throw 'Existing toolbox is null.  Can\'t create new toolbox.';
                +  }
                +  if (tree.getElementsByTagName('category').length) {
                +    if (!this.toolbox_) {
                +      throw 'Existing toolbox has no categories.  Can\'t change mode.';
                +    }
                +    this.options.languageTree = tree;
                +    this.toolbox_.populate_(tree);
                +    this.toolbox_.addColour_();
                +  } else {
                +    if (!this.flyout_) {
                +      throw 'Existing toolbox has categories.  Can\'t change mode.';
                +    }
                +    this.options.languageTree = tree;
                +    this.flyout_.show(tree.childNodes);
                +  }
                +};
                +
                +/**
                + * Mark this workspace as the currently focused main workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.markFocused = function() {
                +  if (this.options.parentWorkspace) {
                +    this.options.parentWorkspace.markFocused();
                +  } else {
                +    Blockly.mainWorkspace = this;
                +    // We call e.preventDefault in many event handlers which means we
                +    // need to explicitly grab focus (e.g from a textarea) because
                +    // the browser will not do it for us.  How to do this is browser dependant.
                +    this.setBrowserFocus();
                +  }
                +};
                +
                +/**
                + * Set the workspace to have focus in the browser.
                + * @private
                + */
                +Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
                +  // Blur whatever was focused since explcitly grabbing focus below does not
                +  // work in Edge.
                +  if (document.activeElement) {
                +    document.activeElement.blur();
                +  }
                +  try {
                +    // Focus the workspace SVG - this is for Chrome and Firefox.
                +    this.getParentSvg().focus();
                +  }  catch (e) {
                +    // IE and Edge do not support focus on SVG elements. When that fails
                +    // above, get the injectionDiv (the workspace's parent) and focus that
                +    // instead.  This doesn't work in Chrome.
                +    try {
                +      // In IE11, use setActive (which is IE only) so the page doesn't scroll
                +      // to the workspace gaining focus.
                +      this.getParentSvg().parentNode.setActive();
                +    } catch (e) {
                +      // setActive support was discontinued in Edge so when that fails, call
                +      // focus instead.
                +      this.getParentSvg().parentNode.focus();
                +    }
                +  }
                +};
                +
                +/**
                + * Zooming the blocks centered in (x, y) coordinate with zooming in or out.
                + * @param {number} x X coordinate of center.
                + * @param {number} y Y coordinate of center.
                + * @param {number} amount Amount of zooming
                + *                        (negative zooms out and positive zooms in).
                + */
                +Blockly.WorkspaceSvg.prototype.zoom = function(x, y, amount) {
                +  var speed = this.options.zoomOptions.scaleSpeed;
                +  var metrics = this.getMetrics();
                +  var center = this.getParentSvg().createSVGPoint();
                +  center.x = x;
                +  center.y = y;
                +  center = center.matrixTransform(this.getCanvas().getCTM().inverse());
                +  x = center.x;
                +  y = center.y;
                +  var canvas = this.getCanvas();
                +  // Scale factor.
                +  var scaleChange = Math.pow(speed, amount);
                +  // Clamp scale within valid range.
                +  var newScale = this.scale * scaleChange;
                +  if (newScale > this.options.zoomOptions.maxScale) {
                +    scaleChange = this.options.zoomOptions.maxScale / this.scale;
                +  } else if (newScale < this.options.zoomOptions.minScale) {
                +    scaleChange = this.options.zoomOptions.minScale / this.scale;
                +  }
                +  if (this.scale == newScale) {
                +    return;  // No change in zoom.
                +  }
                +  if (this.scrollbar) {
                +    var matrix = canvas.getCTM()
                +        .translate(x * (1 - scaleChange), y * (1 - scaleChange))
                +        .scale(scaleChange);
                +    // newScale and matrix.a should be identical (within a rounding error).
                +    this.scrollX = matrix.e - metrics.absoluteLeft;
                +    this.scrollY = matrix.f - metrics.absoluteTop;
                +  }
                +  this.setScale(newScale);
                +};
                +
                +/**
                + * Zooming the blocks centered in the center of view with zooming in or out.
                + * @param {number} type Type of zooming (-1 zooming out and 1 zooming in).
                + */
                +Blockly.WorkspaceSvg.prototype.zoomCenter = function(type) {
                +  var metrics = this.getMetrics();
                +  var x = metrics.viewWidth / 2;
                +  var y = metrics.viewHeight / 2;
                +  this.zoom(x, y, type);
                +};
                +
                +/**
                + * Zoom the blocks to fit in the workspace if possible.
                + */
                +Blockly.WorkspaceSvg.prototype.zoomToFit = function() {
                +  var metrics = this.getMetrics();
                +  var blocksBox = this.getBlocksBoundingBox();
                +  var blocksWidth = blocksBox.width;
                +  var blocksHeight = blocksBox.height;
                +  if (!blocksWidth) {
                +    return;  // Prevents zooming to infinity.
                +  }
                +  var workspaceWidth = metrics.viewWidth;
                +  var workspaceHeight = metrics.viewHeight;
                +  if (this.flyout_) {
                +    workspaceWidth -= this.flyout_.width_;
                +  }
                +  if (!this.scrollbar) {
                +    // Origin point of 0,0 is fixed, blocks will not scroll to center.
                +    blocksWidth += metrics.contentLeft;
                +    blocksHeight += metrics.contentTop;
                +  }
                +  var ratioX = workspaceWidth / blocksWidth;
                +  var ratioY = workspaceHeight / blocksHeight;
                +  this.setScale(Math.min(ratioX, ratioY));
                +  this.scrollCenter();
                +};
                +
                +/**
                + * Center the workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.scrollCenter = function() {
                +  if (!this.scrollbar) {
                +    // Can't center a non-scrolling workspace.
                +    return;
                +  }
                +  var metrics = this.getMetrics();
                +  var x = (metrics.contentWidth - metrics.viewWidth) / 2;
                +  if (this.flyout_) {
                +    x -= this.flyout_.width_ / 2;
                +  }
                +  var y = (metrics.contentHeight - metrics.viewHeight) / 2;
                +  this.scrollbar.set(x, y);
                +};
                +
                +/**
                + * Set the workspace's zoom factor.
                + * @param {number} newScale Zoom factor.
                + */
                +Blockly.WorkspaceSvg.prototype.setScale = function(newScale) {
                +  if (this.options.zoomOptions.maxScale &&
                +      newScale > this.options.zoomOptions.maxScale) {
                +    newScale = this.options.zoomOptions.maxScale;
                +  } else if (this.options.zoomOptions.minScale &&
                +      newScale < this.options.zoomOptions.minScale) {
                +    newScale = this.options.zoomOptions.minScale;
                +  }
                +  this.scale = newScale;
                +  if (this.grid_) {
                +    this.grid_.update(this.scale);
                +  }
                +  if (this.scrollbar) {
                +    this.scrollbar.resize();
                +  } else {
                +    this.translate(this.scrollX, this.scrollY);
                +  }
                +  Blockly.hideChaff(false);
                +  if (this.flyout_) {
                +    // No toolbox, resize flyout.
                +    this.flyout_.reflow();
                +  }
                +};
                +
                +/**
                + * Return an object with all the metrics required to size scrollbars for a
                + * top level workspace.  The following properties are computed:
                + * Coordinate system: pixel coordinates.
                + * .viewHeight: Height of the visible rectangle,
                + * .viewWidth: Width of the visible rectangle,
                + * .contentHeight: Height of the contents,
                + * .contentWidth: Width of the content,
                + * .viewTop: Offset of top edge of visible rectangle from parent,
                + * .viewLeft: Offset of left edge of visible rectangle from parent,
                + * .contentTop: Offset of the top-most content from the y=0 coordinate,
                + * .contentLeft: Offset of the left-most content from the x=0 coordinate.
                + * .absoluteTop: Top-edge of view.
                + * .absoluteLeft: Left-edge of view.
                + * .toolboxWidth: Width of toolbox, if it exists.  Otherwise zero.
                + * .toolboxHeight: Height of toolbox, if it exists.  Otherwise zero.
                + * .flyoutWidth: Width of the flyout if it is always open.  Otherwise zero.
                + * .flyoutHeight: Height of flyout if it is always open.  Otherwise zero.
                + * .toolboxPosition: Top, bottom, left or right.
                + * @return {!Object} Contains size and position metrics of a top level
                + *   workspace.
                + * @private
                + * @this Blockly.WorkspaceSvg
                + */
                +Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_ = function() {
                +  var svgSize = Blockly.svgSize(this.getParentSvg());
                +  if (this.toolbox_) {
                +    if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP ||
                +        this.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
                +      svgSize.height -= this.toolbox_.getHeight();
                +    } else if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT ||
                +        this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
                +      svgSize.width -= this.toolbox_.getWidth();
                +    }
                +  }
                +  // Set the margin to match the flyout's margin so that the workspace does
                +  // not jump as blocks are added.
                +  var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1;
                +  var viewWidth = svgSize.width - MARGIN;
                +  var viewHeight = svgSize.height - MARGIN;
                +
                +  var blockBox = this.getBlocksBoundingBox();
                +
                +  // Fix scale.
                +  var contentWidth = blockBox.width * this.scale;
                +  var contentHeight = blockBox.height * this.scale;
                +  var contentX = blockBox.x * this.scale;
                +  var contentY = blockBox.y * this.scale;
                +  if (this.scrollbar) {
                +    // Add a border around the content that is at least half a screenful wide.
                +    // Ensure border is wide enough that blocks can scroll over entire screen.
                +    var leftEdge = Math.min(contentX - viewWidth / 2,
                +                            contentX + contentWidth - viewWidth);
                +    var rightEdge = Math.max(contentX + contentWidth + viewWidth / 2,
                +                             contentX + viewWidth);
                +    var topEdge = Math.min(contentY - viewHeight / 2,
                +                           contentY + contentHeight - viewHeight);
                +    var bottomEdge = Math.max(contentY + contentHeight + viewHeight / 2,
                +                              contentY + viewHeight);
                +  } else {
                +    var leftEdge = blockBox.x;
                +    var rightEdge = leftEdge + blockBox.width;
                +    var topEdge = blockBox.y;
                +    var bottomEdge = topEdge + blockBox.height;
                +  }
                +  var absoluteLeft = 0;
                +  if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
                +    absoluteLeft = this.toolbox_.getWidth();
                +  }
                +  var absoluteTop = 0;
                +  if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {
                +    absoluteTop = this.toolbox_.getHeight();
                +  }
                +
                +  var metrics = {
                +    viewHeight: svgSize.height,
                +    viewWidth: svgSize.width,
                +    contentHeight: bottomEdge - topEdge,
                +    contentWidth: rightEdge - leftEdge,
                +    viewTop: -this.scrollY,
                +    viewLeft: -this.scrollX,
                +    contentTop: topEdge,
                +    contentLeft: leftEdge,
                +    absoluteTop: absoluteTop,
                +    absoluteLeft: absoluteLeft,
                +    toolboxWidth: this.toolbox_ ? this.toolbox_.getWidth() : 0,
                +    toolboxHeight: this.toolbox_ ? this.toolbox_.getHeight() : 0,
                +    flyoutWidth: this.flyout_ ? this.flyout_.getWidth() : 0,
                +    flyoutHeight: this.flyout_ ? this.flyout_.getHeight() : 0,
                +    toolboxPosition: this.toolboxPosition
                +  };
                +  return metrics;
                +};
                +
                +/**
                + * Sets the X/Y translations of a top level workspace to match the scrollbars.
                + * @param {!Object} xyRatio Contains an x and/or y property which is a float
                + *     between 0 and 1 specifying the degree of scrolling.
                + * @private
                + * @this Blockly.WorkspaceSvg
                + */
                +Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_ = function(xyRatio) {
                +  if (!this.scrollbar) {
                +    throw 'Attempt to set top level workspace scroll without scrollbars.';
                +  }
                +  var metrics = this.getMetrics();
                +  if (goog.isNumber(xyRatio.x)) {
                +    this.scrollX = -metrics.contentWidth * xyRatio.x - metrics.contentLeft;
                +  }
                +  if (goog.isNumber(xyRatio.y)) {
                +    this.scrollY = -metrics.contentHeight * xyRatio.y - metrics.contentTop;
                +  }
                +  var x = this.scrollX + metrics.absoluteLeft;
                +  var y = this.scrollY + metrics.absoluteTop;
                +  this.translate(x, y);
                +  if (this.grid_) {
                +    this.grid_.moveTo(x, y);
                +  }
                +};
                +
                +/**
                + * Update whether this workspace has resizes enabled.
                + * If enabled, workspace will resize when appropriate.
                + * If disabled, workspace will not resize until re-enabled.
                + * Use to avoid resizing during a batch operation, for performance.
                + * @param {boolean} enabled Whether resizes should be enabled.
                + */
                +Blockly.WorkspaceSvg.prototype.setResizesEnabled = function(enabled) {
                +  var reenabled = (!this.resizesEnabled_ && enabled);
                +  this.resizesEnabled_ = enabled;
                +  if (reenabled) {
                +    // Newly enabled.  Trigger a resize.
                +    this.resizeContents();
                +  }
                +};
                +
                +/**
                + * Dispose of all blocks in workspace, with an optimization to prevent resizes.
                + */
                +Blockly.WorkspaceSvg.prototype.clear = function() {
                +  this.setResizesEnabled(false);
                +  Blockly.WorkspaceSvg.superClass_.clear.call(this);
                +  this.setResizesEnabled(true);
                +};
                +
                +/**
                + * Register a callback function associated with a given key, for clicks on
                + * buttons and labels in the flyout.
                + * For instance, a button specified by the XML
                + * <button text="create variable" callbackKey="CREATE_VARIABLE"></button>
                + * should be matched by a call to
                + * registerButtonCallback("CREATE_VARIABLE", yourCallbackFunction).
                + * @param {string} key The name to use to look up this function.
                + * @param {function(!Blockly.FlyoutButton)} func The function to call when the
                + *     given button is clicked.
                + */
                +Blockly.WorkspaceSvg.prototype.registerButtonCallback = function(key, func) {
                +  goog.asserts.assert(goog.isFunction(func),
                +      'Button callbacks must be functions.');
                +  this.flyoutButtonCallbacks_[key] = func;
                +};
                +
                +/**
                + * Get the callback function associated with a given key, for clicks on buttons
                + * and labels in the flyout.
                + * @param {string} key The name to use to look up the function.
                + * @return {?function(!Blockly.FlyoutButton)} The function corresponding to the
                + *     given key for this workspace; null if no callback is registered.
                + */
                +Blockly.WorkspaceSvg.prototype.getButtonCallback = function(key) {
                +  var result = this.flyoutButtonCallbacks_[key];
                +  return result ? result : null;
                +};
                +
                +/**
                + * Remove a callback for a click on a button in the flyout.
                + * @param {string} key The name associated with the callback function.
                + */
                +Blockly.WorkspaceSvg.prototype.removeButtonCallback = function(key) {
                +  this.flyoutButtonCallbacks_[key] = null;
                +};
                +
                +/**
                + * Register a callback function associated with a given key, for populating
                + * custom toolbox categories in this workspace.  See the variable and procedure
                + * categories as an example.
                + * @param {string} key The name to use to look up this function.
                + * @param {function(!Blockly.Workspace):!Array<!Element>} func The function to
                + *     call when the given toolbox category is opened.
                + */
                +Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback = function(key,
                +    func) {
                +  goog.asserts.assert(goog.isFunction(func),
                +      'Toolbox category callbacks must be functions.');
                +  this.toolboxCategoryCallbacks_[key] = func;
                +};
                +
                +/**
                + * Get the callback function associated with a given key, for populating
                + * custom toolbox categories in this workspace.
                + * @param {string} key The name to use to look up the function.
                + * @return {?function(!Blockly.Workspace):!Array<!Element>} The function
                + *     corresponding to the given key for this workspace, or null if no function
                + *     is registered.
                + */
                +Blockly.WorkspaceSvg.prototype.getToolboxCategoryCallback = function(key) {
                +  var result = this.toolboxCategoryCallbacks_[key];
                +  return result ? result : null;
                +};
                +
                +/**
                + * Remove a callback for a click on a custom category's name in the toolbox.
                + * @param {string} key The name associated with the callback function.
                + */
                +Blockly.WorkspaceSvg.prototype.removeToolboxCategoryCallback = function(key) {
                +  this.toolboxCategoryCallbacks_[key] = null;
                +};
                +
                +/**
                + * Look up the gesture that is tracking this touch stream on this workspace.
                + * May create a new gesture.
                + * @param {!Event} e Mouse event or touch event
                + * @return {Blockly.Gesture} The gesture that is tracking this touch stream,
                + *     or null if no valid gesture exists.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.getGesture = function(e) {
                +  var isStart = (e.type == 'mousedown' || e.type == 'touchstart');
                +
                +  var gesture = this.currentGesture_;
                +  if (gesture) {
                +    if (isStart && gesture.hasStarted()) {
                +      console.warn('tried to start the same gesture twice');
                +      // That's funny.  We must have missed a mouse up.
                +      // Cancel it, rather than try to retrieve all of the state we need.
                +      gesture.cancel();
                +      return null;
                +    }
                +    return gesture;
                +  }
                +
                +  // No gesture existed on this workspace, but this looks like the start of a
                +  // new gesture.
                +  if (isStart) {
                +    this.currentGesture_ = new Blockly.Gesture(e, this);
                +    return this.currentGesture_;
                +  }
                +  // No gesture existed and this event couldn't be the start of a new gesture.
                +  return null;
                +};
                +
                +/**
                + * Clear the reference to the current gesture.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.clearGesture = function() {
                +  this.currentGesture_ = null;
                +};
                +
                +/**
                + * Cancel the current gesture, if one exists.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.cancelCurrentGesture = function() {
                +  if (this.currentGesture_) {
                +    this.currentGesture_.cancel();
                +  }
                +};
                +
                +/**
                + * Get the audio manager for this workspace.
                + * @return {Blockly.WorkspaceAudio} The audio manager for this workspace.
                + */
                +Blockly.WorkspaceSvg.prototype.getAudioManager = function() {
                +  return this.audioManager_;
                +};
                +
                +/**
                + * Get the grid object for this workspace, or null if there is none.
                + * @return {Blockly.Grid} The grid object for this workspace.
                + * @package
                + */
                +Blockly.WorkspaceSvg.prototype.getGrid = function() {
                +  return this.grid_;
                +};
                +
                +// Export symbols that would otherwise be renamed by Closure compiler.
                +Blockly.WorkspaceSvg.prototype['setVisible'] =
                +    Blockly.WorkspaceSvg.prototype.setVisible;
                diff --git a/blockly/webif/static/blockly/core/xml.js b/blockly/webif/static/blockly/core/xml.js
                new file mode 100644
                index 000000000..64f001560
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/xml.js
                @@ -0,0 +1,725 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview XML reader and writer.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * @name Blockly.Xml
                + * @namespace
                + **/
                +goog.provide('Blockly.Xml');
                +
                +goog.require('goog.asserts');
                +goog.require('goog.dom');
                +
                +
                +/**
                + * Encode a block tree as XML.
                + * @param {!Blockly.Workspace} workspace The workspace containing blocks.
                + * @param {boolean} opt_noId True if the encoder should skip the block ids.
                + * @return {!Element} XML document.
                + */
                +Blockly.Xml.workspaceToDom = function(workspace, opt_noId) {
                +  var xml = goog.dom.createDom('xml');
                +  xml.appendChild(Blockly.Xml.variablesToDom(workspace.getAllVariables()));
                +  var blocks = workspace.getTopBlocks(true);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    xml.appendChild(Blockly.Xml.blockToDomWithXY(block, opt_noId));
                +  }
                +  return xml;
                +};
                +
                +/**
                + * Encode a list of variables as XML.
                + * @param {!Array.<!Blockly.VariableModel>} variableList List of all variable
                + *     models.
                + * @return {!Element} List of XML elements.
                + */
                +Blockly.Xml.variablesToDom = function(variableList) {
                +  var variables = goog.dom.createDom('variables');
                +  for (var i = 0, variable; variable = variableList[i]; i++) {
                +    var element = goog.dom.createDom('variable', null, variable.name);
                +    element.setAttribute('type', variable.type);
                +    element.setAttribute('id', variable.getId());
                +    variables.appendChild(element);
                +  }
                +  return variables;
                +};
                +
                +/**
                + * Encode a block subtree as XML with XY coordinates.
                + * @param {!Blockly.Block} block The root block to encode.
                + * @param {boolean} opt_noId True if the encoder should skip the block id.
                + * @return {!Element} Tree of XML elements.
                + */
                +Blockly.Xml.blockToDomWithXY = function(block, opt_noId) {
                +  var width;  // Not used in LTR.
                +  if (block.workspace.RTL) {
                +    width = block.workspace.getWidth();
                +  }
                +  var element = Blockly.Xml.blockToDom(block, opt_noId);
                +  var xy = block.getRelativeToSurfaceXY();
                +  element.setAttribute('x',
                +      Math.round(block.workspace.RTL ? width - xy.x : xy.x));
                +  element.setAttribute('y', Math.round(xy.y));
                +  return element;
                +};
                +
                +/**
                + * Encode a block subtree as XML.
                + * @param {!Blockly.Block} block The root block to encode.
                + * @param {boolean} opt_noId True if the encoder should skip the block id.
                + * @return {!Element} Tree of XML elements.
                + */
                +Blockly.Xml.blockToDom = function(block, opt_noId) {
                +  var element = goog.dom.createDom(block.isShadow() ? 'shadow' : 'block');
                +  element.setAttribute('type', block.type);
                +  if (!opt_noId) {
                +    element.setAttribute('id', block.id);
                +  }
                +  if (block.mutationToDom) {
                +    // Custom data for an advanced block.
                +    var mutation = block.mutationToDom();
                +    if (mutation && (mutation.hasChildNodes() || mutation.hasAttributes())) {
                +      element.appendChild(mutation);
                +    }
                +  }
                +  function fieldToDom(field) {
                +    if (field.name && field.EDITABLE) {
                +      var container = goog.dom.createDom('field', null, field.getValue());
                +      container.setAttribute('name', field.name);
                +      if (field instanceof Blockly.FieldVariable) {
                +        var variable = block.workspace.getVariable(field.getValue());
                +        if (variable) {
                +          container.setAttribute('id', variable.getId());
                +          container.setAttribute('variableType', variable.type);
                +        }
                +      }
                +      element.appendChild(container);
                +    }
                +  }
                +  for (var i = 0, input; input = block.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      fieldToDom(field);
                +    }
                +  }
                +
                +  var commentText = block.getCommentText();
                +  if (commentText) {
                +    var commentElement = goog.dom.createDom('comment', null, commentText);
                +    if (typeof block.comment == 'object') {
                +      commentElement.setAttribute('pinned', block.comment.isVisible());
                +      var hw = block.comment.getBubbleSize();
                +      commentElement.setAttribute('h', hw.height);
                +      commentElement.setAttribute('w', hw.width);
                +    }
                +    element.appendChild(commentElement);
                +  }
                +
                +  if (block.data) {
                +    var dataElement = goog.dom.createDom('data', null, block.data);
                +    element.appendChild(dataElement);
                +  }
                +
                +  for (var i = 0, input; input = block.inputList[i]; i++) {
                +    var container;
                +    var empty = true;
                +    if (input.type == Blockly.DUMMY_INPUT) {
                +      continue;
                +    } else {
                +      var childBlock = input.connection.targetBlock();
                +      if (input.type == Blockly.INPUT_VALUE) {
                +        container = goog.dom.createDom('value');
                +      } else if (input.type == Blockly.NEXT_STATEMENT) {
                +        container = goog.dom.createDom('statement');
                +      }
                +      var shadow = input.connection.getShadowDom();
                +      if (shadow && (!childBlock || !childBlock.isShadow())) {
                +        container.appendChild(Blockly.Xml.cloneShadow_(shadow));
                +      }
                +      if (childBlock) {
                +        container.appendChild(Blockly.Xml.blockToDom(childBlock, opt_noId));
                +        empty = false;
                +      }
                +    }
                +    container.setAttribute('name', input.name);
                +    if (!empty) {
                +      element.appendChild(container);
                +    }
                +  }
                +  if (block.inputsInlineDefault != block.inputsInline) {
                +    element.setAttribute('inline', block.inputsInline);
                +  }
                +  if (block.isCollapsed()) {
                +    element.setAttribute('collapsed', true);
                +  }
                +  if (block.disabled) {
                +    element.setAttribute('disabled', true);
                +  }
                +  if (!block.isDeletable() && !block.isShadow()) {
                +    element.setAttribute('deletable', false);
                +  }
                +  if (!block.isMovable() && !block.isShadow()) {
                +    element.setAttribute('movable', false);
                +  }
                +  if (!block.isEditable()) {
                +    element.setAttribute('editable', false);
                +  }
                +
                +  var nextBlock = block.getNextBlock();
                +  if (nextBlock) {
                +    var container = goog.dom.createDom('next', null,
                +        Blockly.Xml.blockToDom(nextBlock, opt_noId));
                +    element.appendChild(container);
                +  }
                +  var shadow = block.nextConnection && block.nextConnection.getShadowDom();
                +  if (shadow && (!nextBlock || !nextBlock.isShadow())) {
                +    container.appendChild(Blockly.Xml.cloneShadow_(shadow));
                +  }
                +
                +  return element;
                +};
                +
                +/**
                + * Deeply clone the shadow's DOM so that changes don't back-wash to the block.
                + * @param {!Element} shadow A tree of XML elements.
                + * @return {!Element} A tree of XML elements.
                + * @private
                + */
                +Blockly.Xml.cloneShadow_ = function(shadow) {
                +  shadow = shadow.cloneNode(true);
                +  // Walk the tree looking for whitespace.  Don't prune whitespace in a tag.
                +  var node = shadow;
                +  var textNode;
                +  while (node) {
                +    if (node.firstChild) {
                +      node = node.firstChild;
                +    } else {
                +      while (node && !node.nextSibling) {
                +        textNode = node;
                +        node = node.parentNode;
                +        if (textNode.nodeType == 3 && textNode.data.trim() == '' &&
                +            node.firstChild != textNode) {
                +          // Prune whitespace after a tag.
                +          goog.dom.removeNode(textNode);
                +        }
                +      }
                +      if (node) {
                +        textNode = node;
                +        node = node.nextSibling;
                +        if (textNode.nodeType == 3 && textNode.data.trim() == '') {
                +          // Prune whitespace before a tag.
                +          goog.dom.removeNode(textNode);
                +        }
                +      }
                +    }
                +  }
                +  return shadow;
                +};
                +
                +/**
                + * Converts a DOM structure into plain text.
                + * Currently the text format is fairly ugly: all one line with no whitespace.
                + * @param {!Element} dom A tree of XML elements.
                + * @return {string} Text representation.
                + */
                +Blockly.Xml.domToText = function(dom) {
                +  var oSerializer = new XMLSerializer();
                +  return oSerializer.serializeToString(dom);
                +};
                +
                +/**
                + * Converts a DOM structure into properly indented text.
                + * @param {!Element} dom A tree of XML elements.
                + * @return {string} Text representation.
                + */
                +Blockly.Xml.domToPrettyText = function(dom) {
                +  // This function is not guaranteed to be correct for all XML.
                +  // But it handles the XML that Blockly generates.
                +  var blob = Blockly.Xml.domToText(dom);
                +  // Place every open and close tag on its own line.
                +  var lines = blob.split('<');
                +  // Indent every line.
                +  var indent = '';
                +  for (var i = 1; i < lines.length; i++) {
                +    var line = lines[i];
                +    if (line[0] == '/') {
                +      indent = indent.substring(2);
                +    }
                +    lines[i] = indent + '<' + line;
                +    if (line[0] != '/' && line.slice(-2) != '/>') {
                +      indent += '  ';
                +    }
                +  }
                +  // Pull simple tags back together.
                +  // E.g. <foo></foo>
                +  var text = lines.join('\n');
                +  text = text.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g, '$1</$2>');
                +  // Trim leading blank line.
                +  return text.replace(/^\n/, '');
                +};
                +
                +/**
                + * Converts plain text into a DOM structure.
                + * Throws an error if XML doesn't parse.
                + * @param {string} text Text representation.
                + * @return {!Element} A tree of XML elements.
                + */
                +Blockly.Xml.textToDom = function(text) {
                +  var oParser = new DOMParser();
                +  var dom = oParser.parseFromString(text, 'text/xml');
                +  // The DOM should have one and only one top-level node, an XML tag.
                +  if (!dom || !dom.firstChild ||
                +      dom.firstChild.nodeName.toLowerCase() != 'xml' ||
                +      dom.firstChild !== dom.lastChild) {
                +    // Whatever we got back from the parser is not XML.
                +    goog.asserts.fail('Blockly.Xml.textToDom did not obtain a valid XML tree.');
                +  }
                +  return dom.firstChild;
                +};
                +
                +/**
                + * Decode an XML DOM and create blocks on the workspace.
                + * @param {!Element} xml XML DOM.
                + * @param {!Blockly.Workspace} workspace The workspace.
                + * @return {Array.<string>} An array containing new block ids.
                + */
                +Blockly.Xml.domToWorkspace = function(xml, workspace) {
                +  if (xml instanceof Blockly.Workspace) {
                +    var swap = xml;
                +    xml = workspace;
                +    workspace = swap;
                +    console.warn('Deprecated call to Blockly.Xml.domToWorkspace, ' +
                +                 'swap the arguments.');
                +  }
                +  var width;  // Not used in LTR.
                +  if (workspace.RTL) {
                +    width = workspace.getWidth();
                +  }
                +  var newBlockIds = []; // A list of block ids added by this call.
                +  Blockly.Field.startCache();
                +  // Safari 7.1.3 is known to provide node lists with extra references to
                +  // children beyond the lists' length.  Trust the length, do not use the
                +  // looping pattern of checking the index for an object.
                +  var childCount = xml.childNodes.length;
                +  var existingGroup = Blockly.Events.getGroup();
                +  if (!existingGroup) {
                +    Blockly.Events.setGroup(true);
                +  }
                +
                +  // Disable workspace resizes as an optimization.
                +  if (workspace.setResizesEnabled) {
                +    workspace.setResizesEnabled(false);
                +  }
                +  var variablesFirst = true;
                +  try {
                +    for (var i = 0; i < childCount; i++) {
                +      var xmlChild = xml.childNodes[i];
                +      var name = xmlChild.nodeName.toLowerCase();
                +      if (name == 'block' ||
                +          (name == 'shadow' && !Blockly.Events.recordUndo)) {
                +        // Allow top-level shadow blocks if recordUndo is disabled since
                +        // that means an undo is in progress.  Such a block is expected
                +        // to be moved to a nested destination in the next operation.
                +        var block = Blockly.Xml.domToBlock(xmlChild, workspace);
                +        newBlockIds.push(block.id);
                +        var blockX = parseInt(xmlChild.getAttribute('x'), 10);
                +        var blockY = parseInt(xmlChild.getAttribute('y'), 10);
                +        if (!isNaN(blockX) && !isNaN(blockY)) {
                +          block.moveBy(workspace.RTL ? width - blockX : blockX, blockY);
                +        }
                +        variablesFirst = false;
                +      } else if (name == 'shadow') {
                +        goog.asserts.fail('Shadow block cannot be a top-level block.');
                +        variablesFirst = false;
                +      }  else if (name == 'variables') {
                +        if (variablesFirst) {
                +          Blockly.Xml.domToVariables(xmlChild, workspace);
                +        }
                +        else {
                +          throw Error('\'variables\' tag must exist once before block and ' +
                +            'shadow tag elements in the workspace XML, but it was found in ' +
                +            'another location.');
                +        }
                +        variablesFirst = false;
                +      }
                +    }
                +  }
                +  finally {
                +    if (!existingGroup) {
                +      Blockly.Events.setGroup(false);
                +    }
                +    Blockly.Field.stopCache();
                +  }
                +  workspace.updateVariableStore(false);
                +  // Re-enable workspace resizing.
                +  if (workspace.setResizesEnabled) {
                +    workspace.setResizesEnabled(true);
                +  }
                +  return newBlockIds;
                +};
                +
                +/**
                + * Decode an XML DOM and create blocks on the workspace. Position the new
                + * blocks immediately below prior blocks, aligned by their starting edge.
                + * @param {!Element} xml The XML DOM.
                + * @param {!Blockly.Workspace} workspace The workspace to add to.
                + * @return {Array.<string>} An array containing new block ids.
                + */
                +Blockly.Xml.appendDomToWorkspace = function(xml, workspace) {
                +  var bbox; //bounding box of the current blocks
                +  // first check if we have a workspaceSvg otherwise the block have no shape
                +  // and the position does not matter
                +  if (workspace.hasOwnProperty('scale')) {
                +    var savetab = Blockly.BlockSvg.TAB_WIDTH;
                +    try {
                +      Blockly.BlockSvg.TAB_WIDTH = 0;
                +      bbox = workspace.getBlocksBoundingBox();
                +    } finally {
                +      Blockly.BlockSvg.TAB_WIDTH = savetab;
                +    }
                +  }
                +  // load the new blocks into the workspace and get the ids of the new blocks
                +  var newBlockIds = Blockly.Xml.domToWorkspace(xml,workspace);
                +  if (bbox && bbox.height) { // check if any previous block
                +    var offsetY = 0; // offset to add to y of the new block
                +    var offsetX = 0;
                +    var farY = bbox.y + bbox.height; //bottom position
                +    var topX = bbox.x; // x of bounding box
                +    // check position of the new blocks
                +    var newX = Infinity; // x of top corner
                +    var newY = Infinity; // y of top corner
                +    for (var i = 0; i < newBlockIds.length; i++) {
                +      var blockXY = workspace.getBlockById(newBlockIds[i]).getRelativeToSurfaceXY();
                +      if (blockXY.y < newY) {
                +        newY = blockXY.y;
                +      }
                +      if (blockXY.x  < newX) { //if we align also on x
                +        newX = blockXY.x;
                +      }
                +    }
                +    offsetY = farY - newY + Blockly.BlockSvg.SEP_SPACE_Y;
                +    offsetX = topX - newX;
                +    // move the new blocks to append them at the bottom
                +    var width;  // Not used in LTR.
                +    if (workspace.RTL) {
                +      width = workspace.getWidth();
                +    }
                +    for (var i = 0; i < newBlockIds.length; i++) {
                +      var block = workspace.getBlockById(newBlockIds[i]);
                +      block.moveBy(workspace.RTL ? width - offsetX : offsetX, offsetY);
                +    }
                +  }
                +  return newBlockIds;
                +};
                +
                +/**
                + * Decode an XML block tag and create a block (and possibly sub blocks) on the
                + * workspace.
                + * @param {!Element} xmlBlock XML block element.
                + * @param {!Blockly.Workspace} workspace The workspace.
                + * @return {!Blockly.Block} The root block created.
                + */
                +Blockly.Xml.domToBlock = function(xmlBlock, workspace) {
                +  if (xmlBlock instanceof Blockly.Workspace) {
                +    var swap = xmlBlock;
                +    xmlBlock = workspace;
                +    workspace = swap;
                +    console.warn('Deprecated call to Blockly.Xml.domToBlock, ' +
                +                 'swap the arguments.');
                +  }
                +  // Create top-level block.
                +  Blockly.Events.disable();
                +  try {
                +    var topBlock = Blockly.Xml.domToBlockHeadless_(xmlBlock, workspace);
                +    if (workspace.rendered) {
                +      // Hide connections to speed up assembly.
                +      topBlock.setConnectionsHidden(true);
                +      // Generate list of all blocks.
                +      var blocks = topBlock.getDescendants();
                +      // Render each block.
                +      for (var i = blocks.length - 1; i >= 0; i--) {
                +        blocks[i].initSvg();
                +      }
                +      for (var i = blocks.length - 1; i >= 0; i--) {
                +        blocks[i].render(false);
                +      }
                +      // Populating the connection database may be deferred until after the
                +      // blocks have rendered.
                +      setTimeout(function() {
                +        if (topBlock.workspace) {  // Check that the block hasn't been deleted.
                +          topBlock.setConnectionsHidden(false);
                +        }
                +      }, 1);
                +      topBlock.updateDisabled();
                +      // Allow the scrollbars to resize and move based on the new contents.
                +      // TODO(@picklesrus): #387. Remove when domToBlock avoids resizing.
                +      workspace.resizeContents();
                +    }
                +  } finally {
                +    Blockly.Events.enable();
                +  }
                +  if (Blockly.Events.isEnabled()) {
                +    Blockly.Events.fire(new Blockly.Events.BlockCreate(topBlock));
                +  }
                +  return topBlock;
                +};
                +
                +/**
                + * Decode an XML list of variables and add the variables to the workspace.
                + * @param {!Element} xmlVariables List of XML variable elements.
                + * @param {!Blockly.Workspace} workspace The workspace to which the variable
                + *     should be added.
                + */
                +Blockly.Xml.domToVariables = function(xmlVariables, workspace) {
                +  for (var i = 0, xmlChild; xmlChild = xmlVariables.children[i]; i++) {
                +    var type = xmlChild.getAttribute('type');
                +    var id = xmlChild.getAttribute('id');
                +    var name = xmlChild.textContent;
                +
                +    if (typeof(type) === undefined || type === null) {
                +      throw Error('Variable with id, ' + id + ' is without a type');
                +    }
                +    workspace.createVariable(name, type, id);
                +  }
                +};
                +
                +/**
                + * Decode an XML block tag and create a block (and possibly sub blocks) on the
                + * workspace.
                + * @param {!Element} xmlBlock XML block element.
                + * @param {!Blockly.Workspace} workspace The workspace.
                + * @return {!Blockly.Block} The root block created.
                + * @private
                + */
                +Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
                +  var block = null;
                +  var prototypeName = xmlBlock.getAttribute('type');
                +  goog.asserts.assert(prototypeName, 'Block type unspecified: %s',
                +                      xmlBlock.outerHTML);
                +  var id = xmlBlock.getAttribute('id');
                +  block = workspace.newBlock(prototypeName, id);
                +
                +  var blockChild = null;
                +  for (var i = 0, xmlChild; xmlChild = xmlBlock.childNodes[i]; i++) {
                +    if (xmlChild.nodeType == 3) {
                +      // Ignore any text at the <block> level.  It's all whitespace anyway.
                +      continue;
                +    }
                +    var input;
                +
                +    // Find any enclosed blocks or shadows in this tag.
                +    var childBlockNode = null;
                +    var childShadowNode = null;
                +    for (var j = 0, grandchildNode; grandchildNode = xmlChild.childNodes[j];
                +         j++) {
                +      if (grandchildNode.nodeType == 1) {
                +        if (grandchildNode.nodeName.toLowerCase() == 'block') {
                +          childBlockNode = grandchildNode;
                +        } else if (grandchildNode.nodeName.toLowerCase() == 'shadow') {
                +          childShadowNode = grandchildNode;
                +        }
                +      }
                +    }
                +    // Use the shadow block if there is no child block.
                +    if (!childBlockNode && childShadowNode) {
                +      childBlockNode = childShadowNode;
                +    }
                +
                +    var name = xmlChild.getAttribute('name');
                +    switch (xmlChild.nodeName.toLowerCase()) {
                +      case 'mutation':
                +        // Custom data for an advanced block.
                +        if (block.domToMutation) {
                +          block.domToMutation(xmlChild);
                +          if (block.initSvg) {
                +            // Mutation may have added some elements that need initializing.
                +            block.initSvg();
                +          }
                +        }
                +        break;
                +      case 'comment':
                +        block.setCommentText(xmlChild.textContent);
                +        var visible = xmlChild.getAttribute('pinned');
                +        if (visible && !block.isInFlyout) {
                +          // Give the renderer a millisecond to render and position the block
                +          // before positioning the comment bubble.
                +          setTimeout(function() {
                +            if (block.comment && block.comment.setVisible) {
                +              block.comment.setVisible(visible == 'true');
                +            }
                +          }, 1);
                +        }
                +        var bubbleW = parseInt(xmlChild.getAttribute('w'), 10);
                +        var bubbleH = parseInt(xmlChild.getAttribute('h'), 10);
                +        if (!isNaN(bubbleW) && !isNaN(bubbleH) &&
                +            block.comment && block.comment.setVisible) {
                +          block.comment.setBubbleSize(bubbleW, bubbleH);
                +        }
                +        break;
                +      case 'data':
                +        block.data = xmlChild.textContent;
                +        break;
                +      case 'title':
                +        // Titles were renamed to field in December 2013.
                +        // Fall through.
                +      case 'field':
                +        var field = block.getField(name);
                +        var text = xmlChild.textContent;
                +        if (field instanceof Blockly.FieldVariable) {
                +          // TODO (marisaleung): When we change setValue and getValue to
                +          // interact with id's instead of names, update this so that we get
                +          // the variable based on id instead of textContent.
                +          var type = xmlChild.getAttribute('variableType') || '';
                +          var variable = workspace.getVariable(text);
                +          if (!variable) {
                +            variable = workspace.createVariable(text, type,
                +              xmlChild.getAttribute(id));
                +          }
                +          if (typeof(type) !== undefined && type !== null) {
                +            if (type !== variable.type) {
                +              throw Error('Serialized variable type with id \'' +
                +                variable.getId() + '\' had type ' + variable.type + ', and ' +
                +                'does not match variable field that references it: ' +
                +                Blockly.Xml.domToText(xmlChild) + '.');
                +            }
                +          }
                +        }
                +        if (!field) {
                +          console.warn('Ignoring non-existent field ' + name + ' in block ' +
                +                       prototypeName);
                +          break;
                +        }
                +        field.setValue(text);
                +        break;
                +      case 'value':
                +      case 'statement':
                +        input = block.getInput(name);
                +        if (!input) {
                +          console.warn('Ignoring non-existent input ' + name + ' in block ' +
                +                       prototypeName);
                +          break;
                +        }
                +        if (childShadowNode) {
                +          input.connection.setShadowDom(childShadowNode);
                +        }
                +        if (childBlockNode) {
                +          blockChild = Blockly.Xml.domToBlockHeadless_(childBlockNode,
                +              workspace);
                +          if (blockChild.outputConnection) {
                +            input.connection.connect(blockChild.outputConnection);
                +          } else if (blockChild.previousConnection) {
                +            input.connection.connect(blockChild.previousConnection);
                +          } else {
                +            goog.asserts.fail(
                +                'Child block does not have output or previous statement.');
                +          }
                +        }
                +        break;
                +      case 'next':
                +        if (childShadowNode && block.nextConnection) {
                +          block.nextConnection.setShadowDom(childShadowNode);
                +        }
                +        if (childBlockNode) {
                +          goog.asserts.assert(block.nextConnection,
                +              'Next statement does not exist.');
                +          // If there is more than one XML 'next' tag.
                +          goog.asserts.assert(!block.nextConnection.isConnected(),
                +              'Next statement is already connected.');
                +          blockChild = Blockly.Xml.domToBlockHeadless_(childBlockNode,
                +              workspace);
                +          goog.asserts.assert(blockChild.previousConnection,
                +              'Next block does not have previous statement.');
                +          block.nextConnection.connect(blockChild.previousConnection);
                +        }
                +        break;
                +      default:
                +        // Unknown tag; ignore.  Same principle as HTML parsers.
                +        console.warn('Ignoring unknown tag: ' + xmlChild.nodeName);
                +    }
                +  }
                +
                +  var inline = xmlBlock.getAttribute('inline');
                +  if (inline) {
                +    block.setInputsInline(inline == 'true');
                +  }
                +  var disabled = xmlBlock.getAttribute('disabled');
                +  if (disabled) {
                +    block.setDisabled(disabled == 'true');
                +  }
                +  var deletable = xmlBlock.getAttribute('deletable');
                +  if (deletable) {
                +    block.setDeletable(deletable == 'true');
                +  }
                +  var movable = xmlBlock.getAttribute('movable');
                +  if (movable) {
                +    block.setMovable(movable == 'true');
                +  }
                +  var editable = xmlBlock.getAttribute('editable');
                +  if (editable) {
                +    block.setEditable(editable == 'true');
                +  }
                +  var collapsed = xmlBlock.getAttribute('collapsed');
                +  if (collapsed) {
                +    block.setCollapsed(collapsed == 'true');
                +  }
                +  if (xmlBlock.nodeName.toLowerCase() == 'shadow') {
                +    // Ensure all children are also shadows.
                +    var children = block.getChildren();
                +    for (var i = 0, child; child = children[i]; i++) {
                +      goog.asserts.assert(child.isShadow(),
                +                          'Shadow block not allowed non-shadow child.');
                +    }
                +    // Ensure this block doesn't have any variable inputs.
                +    goog.asserts.assert(block.getVars().length == 0,
                +        'Shadow blocks cannot have variable fields.');
                +    block.setShadow(true);
                +  }
                +  return block;
                +};
                +
                +/**
                + * Remove any 'next' block (statements in a stack).
                + * @param {!Element} xmlBlock XML block element.
                + */
                +Blockly.Xml.deleteNext = function(xmlBlock) {
                +  for (var i = 0, child; child = xmlBlock.childNodes[i]; i++) {
                +    if (child.nodeName.toLowerCase() == 'next') {
                +      xmlBlock.removeChild(child);
                +      break;
                +    }
                +  }
                +};
                +
                +// Export symbols that would otherwise be renamed by Closure compiler.
                +if (!goog.global['Blockly']) {
                +  goog.global['Blockly'] = {};
                +}
                +if (!goog.global['Blockly']['Xml']) {
                +  goog.global['Blockly']['Xml'] = {};
                +}
                +goog.global['Blockly']['Xml']['domToText'] = Blockly.Xml.domToText;
                +goog.global['Blockly']['Xml']['domToWorkspace'] = Blockly.Xml.domToWorkspace;
                +goog.global['Blockly']['Xml']['textToDom'] = Blockly.Xml.textToDom;
                +goog.global['Blockly']['Xml']['workspaceToDom'] = Blockly.Xml.workspaceToDom;
                diff --git a/blockly/webif/static/blockly/core/zoom_controls.js b/blockly/webif/static/blockly/core/zoom_controls.js
                new file mode 100644
                index 000000000..143680658
                --- /dev/null
                +++ b/blockly/webif/static/blockly/core/zoom_controls.js
                @@ -0,0 +1,247 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Object representing a zoom icons.
                + * @author carloslfu@gmail.com (Carlos Galarza)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.ZoomControls');
                +
                +goog.require('Blockly.Touch');
                +goog.require('goog.dom');
                +
                +
                +/**
                + * Class for a zoom controls.
                + * @param {!Blockly.Workspace} workspace The workspace to sit in.
                + * @constructor
                + */
                +Blockly.ZoomControls = function(workspace) {
                +  this.workspace_ = workspace;
                +};
                +
                +/**
                + * Width of the zoom controls.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.WIDTH_ = 32;
                +
                +/**
                + * Height of the zoom controls.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.HEIGHT_ = 110;
                +
                +/**
                + * Distance between zoom controls and bottom edge of workspace.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.MARGIN_BOTTOM_ = 20;
                +
                +/**
                + * Distance between zoom controls and right edge of workspace.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.MARGIN_SIDE_ = 20;
                +
                +/**
                + * The SVG group containing the zoom controls.
                + * @type {Element}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.svgGroup_ = null;
                +
                +/**
                + * Left coordinate of the zoom controls.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.left_ = 0;
                +
                +/**
                + * Top coordinate of the zoom controls.
                + * @type {number}
                + * @private
                + */
                +Blockly.ZoomControls.prototype.top_ = 0;
                +
                +/**
                + * Create the zoom controls.
                + * @return {!Element} The zoom controls SVG group.
                + */
                +Blockly.ZoomControls.prototype.createDom = function() {
                +  var workspace = this.workspace_;
                +  /* Here's the markup that will be generated:
                +  <g class="blocklyZoom">
                +    <clippath id="blocklyZoomoutClipPath837493">
                +      <rect width="32" height="32" y="77"></rect>
                +    </clippath>
                +    <image width="96" height="124" x="-64" y="-15" xlink:href="media/sprites.png"
                +        clip-path="url(#blocklyZoomoutClipPath837493)"></image>
                +    <clippath id="blocklyZoominClipPath837493">
                +      <rect width="32" height="32" y="43"></rect>
                +    </clippath>
                +    <image width="96" height="124" x="-32" y="-49" xlink:href="media/sprites.png"
                +        clip-path="url(#blocklyZoominClipPath837493)"></image>
                +    <clippath id="blocklyZoomresetClipPath837493">
                +      <rect width="32" height="32"></rect>
                +    </clippath>
                +    <image width="96" height="124" y="-92" xlink:href="media/sprites.png"
                +        clip-path="url(#blocklyZoomresetClipPath837493)"></image>
                +  </g>
                +  */
                +  this.svgGroup_ = Blockly.utils.createSvgElement('g',
                +      {'class': 'blocklyZoom'}, null);
                +  var clip;
                +  var rnd = String(Math.random()).substring(2);
                +
                +  clip = Blockly.utils.createSvgElement('clipPath',
                +      {'id': 'blocklyZoomoutClipPath' + rnd},
                +      this.svgGroup_);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': 32, 'height': 32, 'y': 77},
                +      clip);
                +  var zoomoutSvg = Blockly.utils.createSvgElement('image',
                +      {'width': Blockly.SPRITE.width,
                +       'height': Blockly.SPRITE.height, 'x': -64,
                +       'y': -15,
                +       'clip-path': 'url(#blocklyZoomoutClipPath' + rnd + ')'},
                +      this.svgGroup_);
                +  zoomoutSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
                +      workspace.options.pathToMedia + Blockly.SPRITE.url);
                +
                +  clip = Blockly.utils.createSvgElement('clipPath',
                +      {'id': 'blocklyZoominClipPath' + rnd},
                +      this.svgGroup_);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': 32, 'height': 32, 'y': 43},
                +      clip);
                +  var zoominSvg = Blockly.utils.createSvgElement('image',
                +      {'width': Blockly.SPRITE.width,
                +       'height': Blockly.SPRITE.height,
                +       'x': -32,
                +       'y': -49,
                +       'clip-path': 'url(#blocklyZoominClipPath' + rnd + ')'},
                +      this.svgGroup_);
                +  zoominSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
                +      workspace.options.pathToMedia + Blockly.SPRITE.url);
                +
                +  clip = Blockly.utils.createSvgElement('clipPath',
                +      {'id': 'blocklyZoomresetClipPath' + rnd},
                +      this.svgGroup_);
                +  Blockly.utils.createSvgElement('rect',
                +      {'width': 32, 'height': 32},
                +      clip);
                +  var zoomresetSvg = Blockly.utils.createSvgElement('image',
                +      {'width': Blockly.SPRITE.width,
                +       'height': Blockly.SPRITE.height, 'y': -92,
                +       'clip-path': 'url(#blocklyZoomresetClipPath' + rnd + ')'},
                +      this.svgGroup_);
                +  zoomresetSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href',
                +      workspace.options.pathToMedia + Blockly.SPRITE.url);
                +
                +  // Attach event listeners.
                +  Blockly.bindEventWithChecks_(zoomresetSvg, 'mousedown', null, function(e) {
                +    workspace.markFocused();
                +    workspace.setScale(workspace.options.zoomOptions.startScale);
                +    workspace.scrollCenter();
                +    Blockly.Touch.clearTouchIdentifier();  // Don't block future drags.
                +    e.stopPropagation();  // Don't start a workspace scroll.
                +    e.preventDefault();  // Stop double-clicking from selecting text.
                +  });
                +  Blockly.bindEventWithChecks_(zoominSvg, 'mousedown', null, function(e) {
                +    workspace.markFocused();
                +    workspace.zoomCenter(1);
                +    Blockly.Touch.clearTouchIdentifier();  // Don't block future drags.
                +    e.stopPropagation();  // Don't start a workspace scroll.
                +    e.preventDefault();  // Stop double-clicking from selecting text.
                +  });
                +  Blockly.bindEventWithChecks_(zoomoutSvg, 'mousedown', null, function(e) {
                +    workspace.markFocused();
                +    workspace.zoomCenter(-1);
                +    Blockly.Touch.clearTouchIdentifier();  // Don't block future drags.
                +    e.stopPropagation();  // Don't start a workspace scroll.
                +    e.preventDefault();  // Stop double-clicking from selecting text.
                +  });
                +
                +  return this.svgGroup_;
                +};
                +
                +/**
                + * Initialize the zoom controls.
                + * @param {number} bottom Distance from workspace bottom to bottom of controls.
                + * @return {number} Distance from workspace bottom to the top of controls.
                + */
                +Blockly.ZoomControls.prototype.init = function(bottom) {
                +  this.bottom_ = this.MARGIN_BOTTOM_ + bottom;
                +  return this.bottom_ + this.HEIGHT_;
                +};
                +
                +/**
                + * Dispose of this zoom controls.
                + * Unlink from all DOM elements to prevent memory leaks.
                + */
                +Blockly.ZoomControls.prototype.dispose = function() {
                +  if (this.svgGroup_) {
                +    goog.dom.removeNode(this.svgGroup_);
                +    this.svgGroup_ = null;
                +  }
                +  this.workspace_ = null;
                +};
                +
                +/**
                + * Move the zoom controls to the bottom-right corner.
                + */
                +Blockly.ZoomControls.prototype.position = function() {
                +  var metrics = this.workspace_.getMetrics();
                +  if (!metrics) {
                +    // There are no metrics available (workspace is probably not visible).
                +    return;
                +  }
                +  if (this.workspace_.RTL) {
                +    this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness;
                +    if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
                +      this.left_ += metrics.flyoutWidth;
                +      if (this.workspace_.toolbox_) {
                +        this.left_ += metrics.absoluteLeft;
                +      }
                +    }
                +  } else {
                +    this.left_ = metrics.viewWidth + metrics.absoluteLeft -
                +        this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness;
                +
                +    if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
                +      this.left_ -= metrics.flyoutWidth;
                +    }
                +  }
                +  this.top_ = metrics.viewHeight + metrics.absoluteTop -
                +      this.HEIGHT_ - this.bottom_;
                +  if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
                +    this.top_ -= metrics.flyoutHeight;
                +  }
                +  this.svgGroup_.setAttribute('transform',
                +      'translate(' + this.left_ + ',' + this.top_ + ')');
                +};
                diff --git a/blockly/webif/static/blockly/dart_compressed.js b/blockly/webif/static/blockly/dart_compressed.js
                new file mode 100644
                index 000000000..01b8fb866
                --- /dev/null
                +++ b/blockly/webif/static/blockly/dart_compressed.js
                @@ -0,0 +1,113 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Language
                +
                + Copyright 2014 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Dart=new Blockly.Generator("Dart");Blockly.Dart.addReservedWords("assert,break,case,catch,class,const,continue,default,do,else,enum,extends,false,final,finally,for,if,in,is,new,null,rethrow,return,super,switch,this,throw,true,try,var,void,while,with,print,identityHashCode,identical,BidirectionalIterator,Comparable,double,Function,int,Invocation,Iterable,Iterator,List,Map,Match,num,Pattern,RegExp,Set,StackTrace,String,StringSink,Type,bool,DateTime,Deprecated,Duration,Expando,Null,Object,RuneIterator,Runes,Stopwatch,StringBuffer,Symbol,Uri,Comparator,AbstractClassInstantiationError,ArgumentError,AssertionError,CastError,ConcurrentModificationError,CyclicInitializationError,Error,Exception,FallThroughError,FormatException,IntegerDivisionByZeroException,NoSuchMethodError,NullThrownError,OutOfMemoryError,RangeError,StackOverflowError,StateError,TypeError,UnimplementedError,UnsupportedError");
                +Blockly.Dart.ORDER_ATOMIC=0;Blockly.Dart.ORDER_UNARY_POSTFIX=1;Blockly.Dart.ORDER_UNARY_PREFIX=2;Blockly.Dart.ORDER_MULTIPLICATIVE=3;Blockly.Dart.ORDER_ADDITIVE=4;Blockly.Dart.ORDER_SHIFT=5;Blockly.Dart.ORDER_BITWISE_AND=6;Blockly.Dart.ORDER_BITWISE_XOR=7;Blockly.Dart.ORDER_BITWISE_OR=8;Blockly.Dart.ORDER_RELATIONAL=9;Blockly.Dart.ORDER_EQUALITY=10;Blockly.Dart.ORDER_LOGICAL_AND=11;Blockly.Dart.ORDER_LOGICAL_OR=12;Blockly.Dart.ORDER_IF_NULL=13;Blockly.Dart.ORDER_CONDITIONAL=14;
                +Blockly.Dart.ORDER_CASCADE=15;Blockly.Dart.ORDER_ASSIGNMENT=16;Blockly.Dart.ORDER_NONE=99;
                +Blockly.Dart.init=function(a){Blockly.Dart.definitions_=Object.create(null);Blockly.Dart.functionNames_=Object.create(null);Blockly.Dart.variableDB_?Blockly.Dart.variableDB_.reset():Blockly.Dart.variableDB_=new Blockly.Names(Blockly.Dart.RESERVED_WORDS_);var b=[];a=a.getAllVariables();if(a.length){for(var c=0;c<a.length;c++)b[c]=Blockly.Dart.variableDB_.getName(a[c].name,Blockly.Variables.NAME_TYPE);Blockly.Dart.definitions_.variables="var "+b.join(", ")+";"}};
                +Blockly.Dart.finish=function(a){a&&(a=Blockly.Dart.prefixLines(a,Blockly.Dart.INDENT));a="main() {\n"+a+"}";var b=[],c=[],d;for(d in Blockly.Dart.definitions_){var e=Blockly.Dart.definitions_[d];e.match(/^import\s/)?b.push(e):c.push(e)}delete Blockly.Dart.definitions_;delete Blockly.Dart.functionNames_;Blockly.Dart.variableDB_.reset();return(b.join("\n")+"\n\n"+c.join("\n\n")).replace(/\n\n+/g,"\n\n").replace(/\n*$/,"\n\n\n")+a};Blockly.Dart.scrubNakedValue=function(a){return a+";\n"};
                +Blockly.Dart.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/\$/g,"\\$").replace(/'/g,"\\'");return"'"+a+"'"};
                +Blockly.Dart.scrub_=function(a,b){var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();(d=Blockly.utils.wrap(d,Blockly.Dart.COMMENT_WRAP-3))&&(c=a.getProcedureDef?c+Blockly.Dart.prefixLines(d+"\n","/// "):c+Blockly.Dart.prefixLines(d+"\n","// "));for(var e=0;e<a.inputList.length;e++)a.inputList[e].type==Blockly.INPUT_VALUE&&(d=a.inputList[e].connection.targetBlock())&&(d=Blockly.Dart.allNestedComments(d))&&(c+=Blockly.Dart.prefixLines(d,"// "))}e=a.nextConnection&&
                +a.nextConnection.targetBlock();e=Blockly.Dart.blockToCode(e);return c+b+e};
                +Blockly.Dart.getAdjusted=function(a,b,c,d,e){c=c||0;e=e||Blockly.Dart.ORDER_NONE;a.workspace.options.oneBasedIndex&&c--;var f=a.workspace.options.oneBasedIndex?"1":"0";a=c?Blockly.Dart.valueToCode(a,b,Blockly.Dart.ORDER_ADDITIVE)||f:d?Blockly.Dart.valueToCode(a,b,Blockly.Dart.ORDER_UNARY_PREFIX)||f:Blockly.Dart.valueToCode(a,b,e)||f;if(Blockly.isNumber(a))a=parseInt(a,10)+c,d&&(a=-a);else{if(0<c){a=a+" + "+c;var g=Blockly.Dart.ORDER_ADDITIVE}else 0>c&&(a=a+" - "+-c,g=Blockly.Dart.ORDER_ADDITIVE);
                +d&&(a=c?"-("+a+")":"-"+a,g=Blockly.Dart.ORDER_UNARY_PREFIX);g=Math.floor(g);e=Math.floor(e);g&&e>=g&&(a="("+a+")")}return a};Blockly.Dart.colour={};Blockly.Dart.addReservedWords("Math");Blockly.Dart.colour_picker=function(a){return["'"+a.getFieldValue("COLOUR")+"'",Blockly.Dart.ORDER_ATOMIC]};
                +Blockly.Dart.colour_random=function(a){Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";return[Blockly.Dart.provideFunction_("colour_random",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"() {","  String hex = '0123456789abcdef';","  var rnd = new Math.Random();","  return '#${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}'","      '${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}'","      '${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}';","}"])+"()",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.colour_rgb=function(a){var b=Blockly.Dart.valueToCode(a,"RED",Blockly.Dart.ORDER_NONE)||0,c=Blockly.Dart.valueToCode(a,"GREEN",Blockly.Dart.ORDER_NONE)||0;a=Blockly.Dart.valueToCode(a,"BLUE",Blockly.Dart.ORDER_NONE)||0;Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";return[Blockly.Dart.provideFunction_("colour_rgb",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(num r, num g, num b) {","  num rn = (Math.max(Math.min(r, 100), 0) * 2.55).round();","  String rs = rn.toInt().toRadixString(16);",
                +"  rs = '0$rs';","  rs = rs.substring(rs.length - 2);","  num gn = (Math.max(Math.min(g, 100), 0) * 2.55).round();","  String gs = gn.toInt().toRadixString(16);","  gs = '0$gs';","  gs = gs.substring(gs.length - 2);","  num bn = (Math.max(Math.min(b, 100), 0) * 2.55).round();","  String bs = bn.toInt().toRadixString(16);","  bs = '0$bs';","  bs = bs.substring(bs.length - 2);","  return '#$rs$gs$bs';","}"])+"("+b+", "+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.colour_blend=function(a){var b=Blockly.Dart.valueToCode(a,"COLOUR1",Blockly.Dart.ORDER_NONE)||"'#000000'",c=Blockly.Dart.valueToCode(a,"COLOUR2",Blockly.Dart.ORDER_NONE)||"'#000000'";a=Blockly.Dart.valueToCode(a,"RATIO",Blockly.Dart.ORDER_NONE)||.5;Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";return[Blockly.Dart.provideFunction_("colour_blend",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String c1, String c2, num ratio) {","  ratio = Math.max(Math.min(ratio, 1), 0);",
                +"  int r1 = int.parse('0x${c1.substring(1, 3)}');","  int g1 = int.parse('0x${c1.substring(3, 5)}');","  int b1 = int.parse('0x${c1.substring(5, 7)}');","  int r2 = int.parse('0x${c2.substring(1, 3)}');","  int g2 = int.parse('0x${c2.substring(3, 5)}');","  int b2 = int.parse('0x${c2.substring(5, 7)}');","  num rn = (r1 * (1 - ratio) + r2 * ratio).round();","  String rs = rn.toInt().toRadixString(16);","  num gn = (g1 * (1 - ratio) + g2 * ratio).round();","  String gs = gn.toInt().toRadixString(16);",
                +"  num bn = (b1 * (1 - ratio) + b2 * ratio).round();","  String bs = bn.toInt().toRadixString(16);","  rs = '0$rs';","  rs = rs.substring(rs.length - 2);","  gs = '0$gs';","  gs = gs.substring(gs.length - 2);","  bs = '0$bs';","  bs = bs.substring(bs.length - 2);","  return '#$rs$gs$bs';","}"])+"("+b+", "+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.lists={};Blockly.Dart.addReservedWords("Math");Blockly.Dart.lists_create_empty=function(a){return["[]",Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Dart.valueToCode(a,"ADD"+c,Blockly.Dart.ORDER_NONE)||"null";return["["+b.join(", ")+"]",Blockly.Dart.ORDER_ATOMIC]};
                +Blockly.Dart.lists_repeat=function(a){var b=Blockly.Dart.valueToCode(a,"ITEM",Blockly.Dart.ORDER_NONE)||"null";return["new List.filled("+(Blockly.Dart.valueToCode(a,"NUM",Blockly.Dart.ORDER_NONE)||"0")+", "+b+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.lists_length=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]")+".length",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_isEmpty=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]")+".isEmpty",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"indexOf":"lastIndexOf",c=Blockly.Dart.valueToCode(a,"FIND",Blockly.Dart.ORDER_NONE)||"''",b=(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.Dart.ORDER_ADDITIVE]:[b,Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_getIndex=function(a){function b(){var a=Blockly.Dart.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),b="List "+a+" = "+e+";\n";e=a;return b}var c=a.getFieldValue("MODE")||"GET";var d=a.getFieldValue("WHERE")||"FROM_START";var e=Blockly.Dart.valueToCode(a,"VALUE","RANDOM"==d||"FROM_END"==d?Blockly.Dart.ORDER_NONE:Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]";if(("RANDOM"!=d||"REMOVE"!=c)&&"FROM_END"!=d||e.match(/^\w+$/))switch(d){case "FIRST":if("GET"==c)return[e+".first",
                +Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c)return[e+".removeAt(0)",Blockly.Dart.ORDER_UNARY_POSTFIX];if("REMOVE"==c)return e+".removeAt(0);\n";break;case "LAST":if("GET"==c)return[e+".last",Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c)return[e+".removeLast()",Blockly.Dart.ORDER_UNARY_POSTFIX];if("REMOVE"==c)return e+".removeLast();\n";break;case "FROM_START":d=Blockly.Dart.getAdjusted(a,"AT");if("GET"==c)return[e+"["+d+"]",Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c)return[e+
                +".removeAt("+d+")",Blockly.Dart.ORDER_UNARY_POSTFIX];if("REMOVE"==c)return e+".removeAt("+d+");\n";break;case "FROM_END":d=Blockly.Dart.getAdjusted(a,"AT",1,!1,Blockly.Dart.ORDER_ADDITIVE);if("GET"==c)return[e+"["+e+".length - "+d+"]",Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c||"REMOVE"==c){a=e+".removeAt("+e+".length - "+d+")";if("GET_REMOVE"==c)return[a,Blockly.Dart.ORDER_UNARY_POSTFIX];if("REMOVE"==c)return a+";\n"}break;case "RANDOM":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";
                +if("REMOVE"==c)return c=Blockly.Dart.variableDB_.getDistinctName("tmp_x",Blockly.Variables.NAME_TYPE),"int "+c+" = new Math.Random().nextInt("+e+".length);\n"+(e+".removeAt("+c+");\n");if("GET"==c)return c=Blockly.Dart.provideFunction_("lists_get_random_item",["dynamic "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List my_list) {","  int x = new Math.Random().nextInt(my_list.length);","  return my_list[x];","}"]),[c+"("+e+")",Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c)return c=Blockly.Dart.provideFunction_("lists_remove_random_item",
                +["dynamic "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List my_list) {","  int x = new Math.Random().nextInt(my_list.length);","  return my_list.removeAt(x);","}"]),[c+"("+e+")",Blockly.Dart.ORDER_UNARY_POSTFIX]}else{if("RANDOM"==d)return Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",a=b(),c=Blockly.Dart.variableDB_.getDistinctName("tmp_x",Blockly.Variables.NAME_TYPE),a+("int "+c+" = new Math.Random().nextInt("+e+".length);\n")+(e+".removeAt("+c+");\n");if("REMOVE"==c)return d=
                +Blockly.Dart.getAdjusted(a,"AT",1,!1,Blockly.Dart.ORDER_ADDITIVE),a=b(),a+=e+".removeAt("+e+".length - "+d+");\n";if("GET"==c)return d=Blockly.Dart.getAdjusted(a,"AT",1),c=Blockly.Dart.provideFunction_("lists_get_from_end",["dynamic "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List my_list, num x) {","  x = my_list.length - x;","  return my_list[x];","}"]),[c+"("+e+", "+d+")",Blockly.Dart.ORDER_UNARY_POSTFIX];if("GET_REMOVE"==c)return d=Blockly.Dart.getAdjusted(a,"AT",1),c=Blockly.Dart.provideFunction_("lists_remove_from_end",
                +["dynamic "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List my_list, num x) {","  x = my_list.length - x;","  return my_list.removeAt(x);","}"]),[c+"("+e+", "+d+")",Blockly.Dart.ORDER_UNARY_POSTFIX]}throw"Unhandled combination (lists_getIndex).";};
                +Blockly.Dart.lists_setIndex=function(a){function b(){if(e.match(/^\w+$/))return"";var a=Blockly.Dart.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),b="List "+a+" = "+e+";\n";e=a;return b}var c=a.getFieldValue("MODE")||"GET",d=a.getFieldValue("WHERE")||"FROM_START",e=Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]",f=Blockly.Dart.valueToCode(a,"TO",Blockly.Dart.ORDER_ASSIGNMENT)||"null";switch(d){case "FIRST":if("SET"==c)return e+"[0] = "+f+";\n";if("INSERT"==
                +c)return e+".insert(0, "+f+");\n";break;case "LAST":if("SET"==c)return a=b(),a+(e+"["+e+".length - 1] = "+f+";\n");if("INSERT"==c)return e+".add("+f+");\n";break;case "FROM_START":d=Blockly.Dart.getAdjusted(a,"AT");if("SET"==c)return e+"["+d+"] = "+f+";\n";if("INSERT"==c)return e+".insert("+d+", "+f+");\n";break;case "FROM_END":d=Blockly.Dart.getAdjusted(a,"AT",1,!1,Blockly.Dart.ORDER_ADDITIVE);a=b();if("SET"==c)return a+(e+"["+e+".length - "+d+"] = "+f+";\n");if("INSERT"==c)return a+(e+".insert("+
                +e+".length - "+d+", "+f+");\n");break;case "RANDOM":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";a=b();d=Blockly.Dart.variableDB_.getDistinctName("tmp_x",Blockly.Variables.NAME_TYPE);a+="int "+d+" = new Math.Random().nextInt("+e+".length);\n";if("SET"==c)return a+(e+"["+d+"] = "+f+";\n");if("INSERT"==c)return a+(e+".insert("+d+", "+f+");\n")}throw"Unhandled combination (lists_setIndex).";};
                +Blockly.Dart.lists_getSublist=function(a){var b=Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_UNARY_POSTFIX)||"[]",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if(b.match(/^\w+$/)||"FROM_END"!=c&&"FROM_START"==d){switch(c){case "FROM_START":var e=Blockly.Dart.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.Dart.getAdjusted(a,"AT1",1,!1,Blockly.Dart.ORDER_ADDITIVE);e=b+".length - "+e;break;case "FIRST":e="0";break;default:throw"Unhandled option (lists_getSublist).";}switch(d){case "FROM_START":var f=
                +Blockly.Dart.getAdjusted(a,"AT2",1);break;case "FROM_END":f=Blockly.Dart.getAdjusted(a,"AT2",0,!1,Blockly.Dart.ORDER_ADDITIVE);f=b+".length - "+f;break;case "LAST":break;default:throw"Unhandled option (lists_getSublist).";}a="LAST"==d?b+".sublist("+e+")":b+".sublist("+e+", "+f+")"}else e=Blockly.Dart.getAdjusted(a,"AT1"),f=Blockly.Dart.getAdjusted(a,"AT2"),a=Blockly.Dart.provideFunction_("lists_get_sublist",["List "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(list, where1, at1, where2, at2) {","  int getAt(where, at) {",
                +"    if (where == 'FROM_END') {","      at = list.length - 1 - at;","    } else if (where == 'FIRST') {","      at = 0;","    } else if (where == 'LAST') {","      at = list.length - 1;","    } else if (where != 'FROM_START') {","      throw 'Unhandled option (lists_getSublist).';","    }","    return at;","  }","  at1 = getAt(where1, at1);","  at2 = getAt(where2, at2) + 1;","  return list.sublist(at1, at2);","}"])+"("+b+", '"+c+"', "+e+", '"+d+"', "+f+")";return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_sort=function(a){var b=Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_NONE)||"[]",c="1"===a.getFieldValue("DIRECTION")?1:-1;a=a.getFieldValue("TYPE");return[Blockly.Dart.provideFunction_("lists_sort",["List "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(list, type, direction) {","  var compareFuncs = {",'    "NUMERIC": (a, b) => direction * a.compareTo(b),','    "TEXT": (a, b) => direction * a.toString().compareTo(b.toString()),','    "IGNORE_CASE": ',"       (a, b) => direction * ",
                +"      a.toString().toLowerCase().compareTo(b.toString().toLowerCase())","  };","  list = new List.from(list);","  var compare = compareFuncs[type];","  list.sort(compare);","  return list;","}"])+"("+b+', "'+a+'", '+c+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_split=function(a){var b=Blockly.Dart.valueToCode(a,"INPUT",Blockly.Dart.ORDER_UNARY_POSTFIX),c=Blockly.Dart.valueToCode(a,"DELIM",Blockly.Dart.ORDER_NONE)||"''";a=a.getFieldValue("MODE");if("SPLIT"==a)b||(b="''"),a="split";else if("JOIN"==a)b||(b="[]"),a="join";else throw"Unknown mode: "+a;return[b+"."+a+"("+c+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.lists_reverse=function(a){return["new List.from("+(Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_NONE)||"[]")+".reversed)",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.logic={};Blockly.Dart.controls_if=function(a){var b=0,c="";do{var d=Blockly.Dart.valueToCode(a,"IF"+b,Blockly.Dart.ORDER_NONE)||"false";var e=Blockly.Dart.statementToCode(a,"DO"+b);c+=(0<b?"else ":"")+"if ("+d+") {\n"+e+"}";++b}while(a.getInput("IF"+b));a.getInput("ELSE")&&(e=Blockly.Dart.statementToCode(a,"ELSE"),c+=" else {\n"+e+"}");return c+"\n"};Blockly.Dart.controls_ifelse=Blockly.Dart.controls_if;
                +Blockly.Dart.logic_compare=function(a){var b={EQ:"==",NEQ:"!=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c="=="==b||"!="==b?Blockly.Dart.ORDER_EQUALITY:Blockly.Dart.ORDER_RELATIONAL,d=Blockly.Dart.valueToCode(a,"A",c)||"0";a=Blockly.Dart.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
                +Blockly.Dart.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"&&":"||",c="&&"==b?Blockly.Dart.ORDER_LOGICAL_AND:Blockly.Dart.ORDER_LOGICAL_OR,d=Blockly.Dart.valueToCode(a,"A",c);a=Blockly.Dart.valueToCode(a,"B",c);if(d||a){var e="&&"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]};Blockly.Dart.logic_negate=function(a){var b=Blockly.Dart.ORDER_UNARY_PREFIX;return["!"+(Blockly.Dart.valueToCode(a,"BOOL",b)||"true"),b]};
                +Blockly.Dart.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.logic_null=function(a){return["null",Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.logic_ternary=function(a){var b=Blockly.Dart.valueToCode(a,"IF",Blockly.Dart.ORDER_CONDITIONAL)||"false",c=Blockly.Dart.valueToCode(a,"THEN",Blockly.Dart.ORDER_CONDITIONAL)||"null";a=Blockly.Dart.valueToCode(a,"ELSE",Blockly.Dart.ORDER_CONDITIONAL)||"null";return[b+" ? "+c+" : "+a,Blockly.Dart.ORDER_CONDITIONAL]};Blockly.Dart.loops={};
                +Blockly.Dart.controls_repeat_ext=function(a){var b=a.getField("TIMES")?String(Number(a.getFieldValue("TIMES"))):Blockly.Dart.valueToCode(a,"TIMES",Blockly.Dart.ORDER_ASSIGNMENT)||"0";var c=Blockly.Dart.statementToCode(a,"DO"),c=Blockly.Dart.addLoopTrap(c,a.id),d="",e=Blockly.Dart.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE);a=b;b.match(/^\w+$/)||Blockly.isNumber(b)||(a=Blockly.Dart.variableDB_.getDistinctName("repeat_end",Blockly.Variables.NAME_TYPE),d+="var "+a+" = "+b+";\n");
                +return d+("for (int "+e+" = 0; "+e+" < "+a+"; "+e+"++) {\n"+c+"}\n")};Blockly.Dart.controls_repeat=Blockly.Dart.controls_repeat_ext;Blockly.Dart.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.Dart.valueToCode(a,"BOOL",b?Blockly.Dart.ORDER_UNARY_PREFIX:Blockly.Dart.ORDER_NONE)||"false",d=Blockly.Dart.statementToCode(a,"DO"),d=Blockly.Dart.addLoopTrap(d,a.id);b&&(c="!"+c);return"while ("+c+") {\n"+d+"}\n"};
                +Blockly.Dart.controls_for=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);var c=Blockly.Dart.valueToCode(a,"FROM",Blockly.Dart.ORDER_ASSIGNMENT)||"0";var d=Blockly.Dart.valueToCode(a,"TO",Blockly.Dart.ORDER_ASSIGNMENT)||"0",e=Blockly.Dart.valueToCode(a,"BY",Blockly.Dart.ORDER_ASSIGNMENT)||"1",f=Blockly.Dart.statementToCode(a,"DO"),f=Blockly.Dart.addLoopTrap(f,a.id);if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&Blockly.isNumber(e)){var g=parseFloat(c)<=
                +parseFloat(d);a="for ("+b+" = "+c+"; "+b+(g?" <= ":" >= ")+d+"; "+b;b=Math.abs(parseFloat(e));a=(1==b?a+(g?"++":"--"):a+((g?" += ":" -= ")+b))+(") {\n"+f+"}\n")}else a="",g=c,c.match(/^\w+$/)||Blockly.isNumber(c)||(g=Blockly.Dart.variableDB_.getDistinctName(b+"_start",Blockly.Variables.NAME_TYPE),a+="var "+g+" = "+c+";\n"),c=d,d.match(/^\w+$/)||Blockly.isNumber(d)||(c=Blockly.Dart.variableDB_.getDistinctName(b+"_end",Blockly.Variables.NAME_TYPE),a+="var "+c+" = "+d+";\n"),d=Blockly.Dart.variableDB_.getDistinctName(b+
                +"_inc",Blockly.Variables.NAME_TYPE),a+="num "+d+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+";\n"):a+("("+e+").abs();\n"),a=a+("if ("+g+" > "+c+") {\n")+(Blockly.Dart.INDENT+d+" = -"+d+";\n"),a+="}\n",a+="for ("+b+" = "+g+"; "+d+" >= 0 ? "+b+" <= "+c+" : "+b+" >= "+c+"; "+b+" += "+d+") {\n"+f+"}\n";return a};
                +Blockly.Dart.controls_forEach=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_ASSIGNMENT)||"[]",d=Blockly.Dart.statementToCode(a,"DO"),d=Blockly.Dart.addLoopTrap(d,a.id);return"for (var "+b+" in "+c+") {\n"+d+"}\n"};
                +Blockly.Dart.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break;\n";case "CONTINUE":return"continue;\n"}throw"Unknown flow statement.";};Blockly.Dart.math={};Blockly.Dart.addReservedWords("Math");Blockly.Dart.math_number=function(a){a=parseFloat(a.getFieldValue("NUM"));if(Infinity==a){a="double.INFINITY";var b=Blockly.Dart.ORDER_UNARY_POSTFIX}else-Infinity==a?(a="-double.INFINITY",b=Blockly.Dart.ORDER_UNARY_PREFIX):b=0>a?Blockly.Dart.ORDER_UNARY_PREFIX:Blockly.Dart.ORDER_ATOMIC;return[a,b]};
                +Blockly.Dart.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.Dart.ORDER_ADDITIVE],MINUS:[" - ",Blockly.Dart.ORDER_ADDITIVE],MULTIPLY:[" * ",Blockly.Dart.ORDER_MULTIPLICATIVE],DIVIDE:[" / ",Blockly.Dart.ORDER_MULTIPLICATIVE],POWER:[null,Blockly.Dart.ORDER_NONE]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.Dart.valueToCode(a,"A",b)||"0";a=Blockly.Dart.valueToCode(a,"B",b)||"0";return c?[d+c+a,b]:(Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",["Math.pow("+d+", "+a+
                +")",Blockly.Dart.ORDER_UNARY_POSTFIX])};
                +Blockly.Dart.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b)return a=Blockly.Dart.valueToCode(a,"NUM",Blockly.Dart.ORDER_UNARY_PREFIX)||"0","-"==a[0]&&(a=" "+a),["-"+a,Blockly.Dart.ORDER_UNARY_PREFIX];Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";a="ABS"==b||"ROUND"==b.substring(0,5)?Blockly.Dart.valueToCode(a,"NUM",Blockly.Dart.ORDER_UNARY_POSTFIX)||"0":"SIN"==b||"COS"==b||"TAN"==b?Blockly.Dart.valueToCode(a,"NUM",Blockly.Dart.ORDER_MULTIPLICATIVE)||"0":
                +Blockly.Dart.valueToCode(a,"NUM",Blockly.Dart.ORDER_NONE)||"0";switch(b){case "ABS":var c=a+".abs()";break;case "ROOT":c="Math.sqrt("+a+")";break;case "LN":c="Math.log("+a+")";break;case "EXP":c="Math.exp("+a+")";break;case "POW10":c="Math.pow(10,"+a+")";break;case "ROUND":c=a+".round()";break;case "ROUNDUP":c=a+".ceil()";break;case "ROUNDDOWN":c=a+".floor()";break;case "SIN":c="Math.sin("+a+" / 180 * Math.PI)";break;case "COS":c="Math.cos("+a+" / 180 * Math.PI)";break;case "TAN":c="Math.tan("+a+
                +" / 180 * Math.PI)"}if(c)return[c,Blockly.Dart.ORDER_UNARY_POSTFIX];switch(b){case "LOG10":c="Math.log("+a+") / Math.log(10)";break;case "ASIN":c="Math.asin("+a+") / Math.PI * 180";break;case "ACOS":c="Math.acos("+a+") / Math.PI * 180";break;case "ATAN":c="Math.atan("+a+") / Math.PI * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.Dart.ORDER_MULTIPLICATIVE]};
                +Blockly.Dart.math_constant=function(a){var b={PI:["Math.PI",Blockly.Dart.ORDER_UNARY_POSTFIX],E:["Math.E",Blockly.Dart.ORDER_UNARY_POSTFIX],GOLDEN_RATIO:["(1 + Math.sqrt(5)) / 2",Blockly.Dart.ORDER_MULTIPLICATIVE],SQRT2:["Math.SQRT2",Blockly.Dart.ORDER_UNARY_POSTFIX],SQRT1_2:["Math.SQRT1_2",Blockly.Dart.ORDER_UNARY_POSTFIX],INFINITY:["double.INFINITY",Blockly.Dart.ORDER_ATOMIC]};a=a.getFieldValue("CONSTANT");"INFINITY"!=a&&(Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;");
                +return b[a]};
                +Blockly.Dart.math_number_property=function(a){var b=Blockly.Dart.valueToCode(a,"NUMBER_TO_CHECK",Blockly.Dart.ORDER_MULTIPLICATIVE);if(!b)return["false",Blockly.Python.ORDER_ATOMIC];var c=a.getFieldValue("PROPERTY");if("PRIME"==c)return Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",[Blockly.Dart.provideFunction_("math_isPrime",["bool "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(n) {","  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods","  if (n == 2 || n == 3) {","    return true;",
                +"  }","  // False if n is null, negative, is 1, or not whole.","  // And false if n is divisible by 2 or 3.","  if (n == null || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) {","    return false;","  }","  // Check all the numbers of form 6k +/- 1, up to sqrt(n).","  for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {","    if (n % (x - 1) == 0 || n % (x + 1) == 0) {","      return false;","    }","  }","  return true;","}"])+"("+b+")",Blockly.Dart.ORDER_UNARY_POSTFIX];switch(c){case "EVEN":var d=
                +b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.Dart.valueToCode(a,"DIVISOR",Blockly.Dart.ORDER_MULTIPLICATIVE);if(!a)return["false",Blockly.Python.ORDER_ATOMIC];d=b+" % "+a+" == 0"}return[d,Blockly.Dart.ORDER_EQUALITY]};
                +Blockly.Dart.math_change=function(a){var b=Blockly.Dart.valueToCode(a,"DELTA",Blockly.Dart.ORDER_ADDITIVE)||"0";a=Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);return a+" = ("+a+" is num ? "+a+" : 0) + "+b+";\n"};Blockly.Dart.math_round=Blockly.Dart.math_single;Blockly.Dart.math_trig=Blockly.Dart.math_single;
                +Blockly.Dart.math_on_list=function(a){var b=a.getFieldValue("OP");a=Blockly.Dart.valueToCode(a,"LIST",Blockly.Dart.ORDER_NONE)||"[]";switch(b){case "SUM":b=Blockly.Dart.provideFunction_("math_sum",["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  num sumVal = 0;","  myList.forEach((num entry) {sumVal += entry;});","  return sumVal;","}"]);b=b+"("+a+")";break;case "MIN":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";b=Blockly.Dart.provideFunction_("math_min",
                +["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  if (myList.isEmpty) return null;","  num minVal = myList[0];","  myList.forEach((num entry) {minVal = Math.min(minVal, entry);});","  return minVal;","}"]);b=b+"("+a+")";break;case "MAX":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";b=Blockly.Dart.provideFunction_("math_max",["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  if (myList.isEmpty) return null;","  num maxVal = myList[0];",
                +"  myList.forEach((num entry) {maxVal = Math.max(maxVal, entry);});","  return maxVal;","}"]);b=b+"("+a+")";break;case "AVERAGE":b=Blockly.Dart.provideFunction_("math_mean",["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  // First filter list for numbers only.","  List localList = new List.from(myList);","  localList.removeWhere((a) => a is! num);","  if (localList.isEmpty) return null;","  num sumVal = 0;","  localList.forEach((num entry) {sumVal += entry;});","  return sumVal / localList.length;",
                +"}"]);b=b+"("+a+")";break;case "MEDIAN":b=Blockly.Dart.provideFunction_("math_median",["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  // First filter list for numbers only, then sort, then return middle value","  // or the average of two middle values if list has an even number of elements.","  List localList = new List.from(myList);","  localList.removeWhere((a) => a is! num);","  if (localList.isEmpty) return null;","  localList.sort((a, b) => (a - b));","  int index = localList.length ~/ 2;",
                +"  if (localList.length % 2 == 1) {","    return localList[index];","  } else {","    return (localList[index - 1] + localList[index]) / 2;","  }","}"]);b=b+"("+a+")";break;case "MODE":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";b=Blockly.Dart.provideFunction_("math_modes",["List "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List values) {","  List modes = [];","  List counts = [];","  int maxCount = 0;","  for (int i = 0; i < values.length; i++) {","    var value = values[i];",
                +"    bool found = false;","    int thisCount;","    for (int j = 0; j < counts.length; j++) {","      if (counts[j][0] == value) {","        thisCount = ++counts[j][1];","        found = true;","        break;","      }","    }","    if (!found) {","      counts.add([value, 1]);","      thisCount = 1;","    }","    maxCount = Math.max(thisCount, maxCount);","  }","  for (int j = 0; j < counts.length; j++) {","    if (counts[j][1] == maxCount) {","        modes.add(counts[j][0]);","    }","  }","  return modes;",
                +"}"]);b=b+"("+a+")";break;case "STD_DEV":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";b=Blockly.Dart.provideFunction_("math_standard_deviation",["num "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  // First filter list for numbers only.","  List numbers = new List.from(myList);","  numbers.removeWhere((a) => a is! num);","  if (numbers.isEmpty) return null;","  num n = numbers.length;","  num sum = 0;","  numbers.forEach((x) => sum += x);","  num mean = sum / n;",
                +"  num sumSquare = 0;","  numbers.forEach((x) => sumSquare += Math.pow(x - mean, 2));","  return Math.sqrt(sumSquare / n);","}"]);b=b+"("+a+")";break;case "RANDOM":Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";b=Blockly.Dart.provideFunction_("math_random_item",["dynamic "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(List myList) {","  int x = new Math.Random().nextInt(myList.length);","  return myList[x];","}"]);b=b+"("+a+")";break;default:throw"Unknown operator: "+b;}return[b,
                +Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.math_modulo=function(a){var b=Blockly.Dart.valueToCode(a,"DIVIDEND",Blockly.Dart.ORDER_MULTIPLICATIVE)||"0";a=Blockly.Dart.valueToCode(a,"DIVISOR",Blockly.Dart.ORDER_MULTIPLICATIVE)||"0";return[b+" % "+a,Blockly.Dart.ORDER_MULTIPLICATIVE]};
                +Blockly.Dart.math_constrain=function(a){Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";var b=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_NONE)||"0",c=Blockly.Dart.valueToCode(a,"LOW",Blockly.Dart.ORDER_NONE)||"0";a=Blockly.Dart.valueToCode(a,"HIGH",Blockly.Dart.ORDER_NONE)||"double.INFINITY";return["Math.min(Math.max("+b+", "+c+"), "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.math_random_int=function(a){Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";var b=Blockly.Dart.valueToCode(a,"FROM",Blockly.Dart.ORDER_NONE)||"0";a=Blockly.Dart.valueToCode(a,"TO",Blockly.Dart.ORDER_NONE)||"0";return[Blockly.Dart.provideFunction_("math_random_int",["int "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(num a, num b) {","  if (a > b) {","    // Swap a and b to ensure a is smaller.","    num c = a;","    a = b;","    b = c;","  }","  return new Math.Random().nextInt(b - a + 1) + a;",
                +"}"])+"("+b+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.math_random_float=function(a){Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;";return["new Math.Random().nextDouble()",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.procedures={};
                +Blockly.Dart.procedures_defreturn=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=Blockly.Dart.statementToCode(a,"STACK");Blockly.Dart.STATEMENT_PREFIX&&(c=Blockly.Dart.prefixLines(Blockly.Dart.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+"'"),Blockly.Dart.INDENT)+c);Blockly.Dart.INFINITE_LOOP_TRAP&&(c=Blockly.Dart.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var d=Blockly.Dart.valueToCode(a,"RETURN",Blockly.Dart.ORDER_NONE)||"";d&&(d="  return "+
                +d+";\n");for(var e=d?"dynamic":"void",f=[],g=0;g<a.arguments_.length;g++)f[g]=Blockly.Dart.variableDB_.getName(a.arguments_[g],Blockly.Variables.NAME_TYPE);c=e+" "+b+"("+f.join(", ")+") {\n"+c+d+"}";c=Blockly.Dart.scrub_(a,c);Blockly.Dart.definitions_["%"+b]=c;return null};Blockly.Dart.procedures_defnoreturn=Blockly.Dart.procedures_defreturn;
                +Blockly.Dart.procedures_callreturn=function(a){for(var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Dart.valueToCode(a,"ARG"+d,Blockly.Dart.ORDER_NONE)||"null";return[b+"("+c.join(", ")+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.procedures_callnoreturn=function(a){for(var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Dart.valueToCode(a,"ARG"+d,Blockly.Dart.ORDER_NONE)||"null";return b+"("+c.join(", ")+");\n"};
                +Blockly.Dart.procedures_ifreturn=function(a){var b="if ("+(Blockly.Dart.valueToCode(a,"CONDITION",Blockly.Dart.ORDER_NONE)||"false")+") {\n";a.hasReturnValue_?(a=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_NONE)||"null",b+="  return "+a+";\n"):b+="  return;\n";return b+"}\n"};Blockly.Dart.texts={};Blockly.Dart.addReservedWords("Html,Math");Blockly.Dart.text=function(a){return[Blockly.Dart.quote_(a.getFieldValue("TEXT")),Blockly.Dart.ORDER_ATOMIC]};
                +Blockly.Dart.text_join=function(a){switch(a.itemCount_){case 0:return["''",Blockly.Dart.ORDER_ATOMIC];case 1:return[(Blockly.Dart.valueToCode(a,"ADD0",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".toString()",Blockly.Dart.ORDER_UNARY_POSTFIX];default:for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Dart.valueToCode(a,"ADD"+c,Blockly.Dart.ORDER_NONE)||"''";a="["+b.join(",")+"].join()";return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]}};
                +Blockly.Dart.text_append=function(a){var b=Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);a=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''";return b+" = ["+b+", "+a+"].join();\n"};Blockly.Dart.text_length=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".length",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_isEmpty=function(a){return[(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".isEmpty",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"indexOf":"lastIndexOf",c=Blockly.Dart.valueToCode(a,"FIND",Blockly.Dart.ORDER_NONE)||"''",b=(Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.Dart.ORDER_ADDITIVE]:[b,Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''";switch(b){case "FIRST":return[c+"[0]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "FROM_START":return a=Blockly.Dart.getAdjusted(a,"AT"),[c+"["+a+"]",Blockly.Dart.ORDER_UNARY_POSTFIX];case "LAST":case "FROM_END":return a=Blockly.Dart.getAdjusted(a,"AT",1),b=Blockly.Dart.provideFunction_("text_get_from_end",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+
                +"(String text, num x) {","  return text[text.length - x];","}"]),[b+"("+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX];case "RANDOM":return Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",b=Blockly.Dart.provideFunction_("text_random_letter",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String text) {","  int x = new Math.Random().nextInt(text.length);","  return text[x];","}"]),[b+"("+c+")",Blockly.Dart.ORDER_UNARY_POSTFIX]}throw"Unhandled option (text_charAt).";};
                +Blockly.Dart.text_getSubstring=function(a){var b=Blockly.Dart.valueToCode(a,"STRING",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if("FIRST"==c&&"LAST"==d)a=b;else if(b.match(/^'?\w+'?$/)||"FROM_END"!=c&&"FROM_START"==d){switch(c){case "FROM_START":var e=Blockly.Dart.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.Dart.getAdjusted(a,"AT1",1,!1,Blockly.Dart.ORDER_ADDITIVE);e=b+".length - "+e;break;case "FIRST":e="0";break;default:throw"Unhandled option (text_getSubstring).";
                +}switch(d){case "FROM_START":var f=Blockly.Dart.getAdjusted(a,"AT2",1);break;case "FROM_END":f=Blockly.Dart.getAdjusted(a,"AT2",0,!1,Blockly.Dart.ORDER_ADDITIVE);f=b+".length - "+f;break;case "LAST":break;default:throw"Unhandled option (text_getSubstring).";}a="LAST"==d?b+".substring("+e+")":b+".substring("+e+", "+f+")"}else e=Blockly.Dart.getAdjusted(a,"AT1"),f=Blockly.Dart.getAdjusted(a,"AT2"),a=Blockly.Dart.provideFunction_("text_get_substring",["List "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+
                +"(text, where1, at1, where2, at2) {","  int getAt(where, at) {","    if (where == 'FROM_END') {","      at = text.length - 1 - at;","    } else if (where == 'FIRST') {","      at = 0;","    } else if (where == 'LAST') {","      at = text.length - 1;","    } else if (where != 'FROM_START') {","      throw 'Unhandled option (text_getSubstring).';","    }","    return at;","  }","  at1 = getAt(where1, at1);","  at2 = getAt(where2, at2) + 1;","  return text.substring(at1, at2);","}"])+"("+b+", '"+c+"', "+
                +e+", '"+d+"', "+f+")";return[a,Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_changeCase=function(a){var b={UPPERCASE:".toUpperCase()",LOWERCASE:".toLowerCase()",TITLECASE:null}[a.getFieldValue("CASE")];a=Blockly.Dart.valueToCode(a,"TEXT",b?Blockly.Dart.ORDER_UNARY_POSTFIX:Blockly.Dart.ORDER_NONE)||"''";return[b?a+b:Blockly.Dart.provideFunction_("text_toTitleCase",["String "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String str) {","  RegExp exp = new RegExp(r'\\b');","  List<String> list = str.split(exp);","  final title = new StringBuffer();","  for (String part in list) {",
                +"    if (part.length > 0) {","      title.write(part[0].toUpperCase());","      if (part.length > 0) {","        title.write(part.substring(1).toLowerCase());","      }","    }","  }","  return title.toString();","}"])+"("+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_trim=function(a){var b={LEFT:".replaceFirst(new RegExp(r'^\\s+'), '')",RIGHT:".replaceFirst(new RegExp(r'\\s+$'), '')",BOTH:".trim()"}[a.getFieldValue("MODE")];return[(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+b,Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_print=function(a){return"print("+(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''")+");\n"};
                +Blockly.Dart.text_prompt_ext=function(a){Blockly.Dart.definitions_.import_dart_html="import 'dart:html' as Html;";var b="Html.window.prompt("+(a.getField("TEXT")?Blockly.Dart.quote_(a.getFieldValue("TEXT")):Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_NONE)||"''")+", '')";"NUMBER"==a.getFieldValue("TYPE")&&(Blockly.Dart.definitions_.import_dart_math="import 'dart:math' as Math;",b="Math.parseDouble("+b+")");return[b,Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_prompt=Blockly.Dart.text_prompt_ext;
                +Blockly.Dart.text_count=function(a){var b=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''";a=Blockly.Dart.valueToCode(a,"SUB",Blockly.Dart.ORDER_NONE)||"''";return[Blockly.Dart.provideFunction_("text_count",["int "+Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_+"(String haystack, String needle) {","  if (needle.length == 0) {","    return haystack.length + 1;","  }","  int index = 0;","  int count = 0;","  while (index != -1) {","    index = haystack.indexOf(needle, index);","    if (index != -1) {",
                +"      count++;","     index += needle.length;","    }","  }","  return count;","}"])+"("+b+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.text_replace=function(a){var b=Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''",c=Blockly.Dart.valueToCode(a,"FROM",Blockly.Dart.ORDER_NONE)||"''";a=Blockly.Dart.valueToCode(a,"TO",Blockly.Dart.ORDER_NONE)||"''";return[b+".replaceAll("+c+", "+a+")",Blockly.Dart.ORDER_UNARY_POSTFIX]};
                +Blockly.Dart.text_reverse=function(a){return["new String.fromCharCodes("+(Blockly.Dart.valueToCode(a,"TEXT",Blockly.Dart.ORDER_UNARY_POSTFIX)||"''")+".runes.toList().reversed)",Blockly.Dart.ORDER_UNARY_POSTFIX]};Blockly.Dart.variables={};Blockly.Dart.variables_get=function(a){return[Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),Blockly.Dart.ORDER_ATOMIC]};Blockly.Dart.variables_set=function(a){var b=Blockly.Dart.valueToCode(a,"VALUE",Blockly.Dart.ORDER_ASSIGNMENT)||"0";return Blockly.Dart.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" = "+b+";\n"};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/demos/accessible/icon.png b/blockly/webif/static/blockly/demos/accessible/icon.png
                new file mode 100644
                index 000000000..3ea238c44
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/accessible/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/accessible/index.html b/blockly/webif/static/blockly/demos/accessible/index.html
                new file mode 100644
                index 000000000..5b56668ab
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/accessible/index.html
                @@ -0,0 +1,329 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Accessible Blockly Demo</title>
                +
                +  <script src="../../accessible/libs/es6-shim.min.js"></script>
                +  <script src="../../accessible/libs/angular2-polyfills.min.js"></script>
                +  <script src="../../accessible/libs/Rx.umd.min.js"></script>
                +  <script src="../../accessible/libs/angular2-all.umd.min.js"></script>
                +
                +  <!-- Load accessibleBlockly -->
                +  <script src="../../blockly_accessible_compressed.js"></script>
                +
                +  <!-- Load Blockly -->
                +  <script src="../../msg/js/en.js"></script>
                +  <script src="../../accessible/messages.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +
                +  <link rel="stylesheet" href="../../accessible/media/accessible.css">
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +      margin-left: 30px;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +
                +    *:focus {
                +      background: yellow;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1>
                +    <a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Accessible Blockly
                +  </h1>
                +
                +  <p>
                +    This is a demo of a version of Blockly designed for screen readers,
                +    optimized for NVDA on Firefox. It allows users to create programs in a
                +    workspace by manipulating groups of blocks.
                +    <ul>
                +      <li>To explore a group of blocks, use the arrow keys.</li>
                +      <li>To navigate between groups, use Tab or Shift-Tab.</li>
                +      <li>To add new blocks, use the buttons in the menu on the right.</li>
                +      <li>To delete or add links to existing blocks, press Enter while you're on that block.</li>
                +    </ul>
                +  </p>
                +
                +  <!--
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/">accessible Blockly</a>&hellip;</p>
                +  -->
                +
                +  <blockly-app></blockly-app>
                +
                +  <script>
                +    var ACCESSIBLE_GLOBALS = {
                +      // Prefix of path to sound files.
                +      mediaPathPrefix: '../../accessible/media/',
                +      // Additional buttons for the sidebar.
                +      customSidebarButtons: []
                +    };
                +    document.addEventListener('DOMContentLoaded', function() {
                +      ng.platform.browser.bootstrap(blocklyApp.AppComponent);
                +    });
                +  </script>
                +
                +  <xml id="blockly-toolbox-xml" style="display: none">
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +        <value name="BY">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number" gap="32"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="B">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">9</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">45</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">3.1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <block type="math_number">
                +            <field name="NUM">64</field>
                +          </block>
                +        </value>
                +        <value name="DIVISOR">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">50</field>
                +          </block>
                +        </value>
                +        <value name="LOW">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="HIGH">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">abc</field>
                +          </block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">5</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <block type="text">
                +            <field name="TEXT">,</field>
                +          </block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +  </xml>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/analytics.js b/blockly/webif/static/blockly/demos/blockfactory/analytics.js
                new file mode 100644
                index 000000000..6473f8858
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/analytics.js
                @@ -0,0 +1,210 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Stubbed interface functions for analytics integration.
                + */
                +
                +goog.provide('BlocklyDevTools.Analytics');
                +
                +/**
                + * Whether these stub methods should log analytics calls to the console.
                + * @private
                + * @const
                + */
                +BlocklyDevTools.Analytics.LOG_TO_CONSOLE_ = false;
                +
                +/**
                + * An import/export type id for a library of BlockFactory's original block
                + * save files (each a serialized workspace of block definition blocks).
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.BLOCK_FACTORY_LIBRARY = "Block Factory library";
                +/**
                + * An import/export type id for a standard Blockly library of block
                + * definitions.
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.BLOCK_DEFINITIONS = "Block definitions";
                +/**
                + * An import/export type id for a code generation function, or a
                + * boilerplate stub of the same.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.GENERATOR = "Generator";
                +/**
                + * An import/export type id for a Blockly Toolbox.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.TOOLBOX = "Toolbox";
                +/**
                + * An import/export type id for the serialized contents of a workspace.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.WORKSPACE_CONTENTS = "Workspace contents";
                +
                +/**
                + * Format id for imported/exported JavaScript resources.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.FORMAT_JS = "JavaScript";
                +/**
                + * Format id for imported/exported JSON resources.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.FORMAT_JSON = "JSON";
                +/**
                + * Format id for imported/exported XML resources.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.FORMAT_XML = "XML";
                +
                +/**
                + * Platform id for resources exported for use in Android projects.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.PLATFORM_ANDROID = "Android";
                +/**
                + * Platform id for resources exported for use in iOS projects.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.PLATFORM_IOS = "iOS";
                +/**
                + * Platform id for resources exported for use in web projects.
                + *
                + * @package
                + * @const
                + */
                +BlocklyDevTools.Analytics.PLATFORM_WEB = "web";
                +
                +/**
                + * Initializes the analytics framework, including noting that the page/app was
                + * opened.
                + * @package
                + */
                +BlocklyDevTools.Analytics.init = function() {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.init');
                +};
                +
                +/**
                + * Event noting the user navigated to a specific view.
                + *
                + * @package
                + * @param viewId {string} An identifier for the view state.
                + */
                +BlocklyDevTools.Analytics.onNavigateTo = function(viewId) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ &&
                +      console.log('Analytics.onNavigateTo(' + viewId + ')');
                +};
                +
                +/**
                + * Event noting a project resource was saved. In the web Block Factory, this
                + * means saved to localStorage.
                + *
                + * @package
                + * @param typeId {string} An identifying string for the saved type.
                + */
                +BlocklyDevTools.Analytics.onSave = function(typeId) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.onSave(' + typeId + ')');
                +};
                +
                +/**
                + * Event noting the user attempted to import a resource file.
                + *
                + * @package
                + * @param typeId {string} An identifying string for the imported type.
                + * @param optMetadata {Object} Metadata about the import, such as format and
                + *                             platform.
                + */
                +BlocklyDevTools.Analytics.onImport = function(typeId, optMetadata) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.onImport(' + typeId +
                +      (optMetadata ? '): ' + JSON.stringify(optMetadata) : ')'));
                +};
                +
                +/**
                + * Event noting a project resource was saved. In the web Block Factory, this
                + * means downloaded to the user's system.
                + *
                + * @package
                + * @param typeId {string} An identifying string for the exported object type.
                + * @param optMetadata {Object} Metadata about the import, such as format and
                + *                             platform.
                + */
                +BlocklyDevTools.Analytics.onExport = function(typeId, optMetadata) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.onExport(' + typeId +
                +      (optMetadata ? '): ' + JSON.stringify(optMetadata) : ')'));
                +};
                +
                +/**
                + * Event noting the system encountered an error. It should attempt to send
                + * immediately.
                + *
                + * @package
                + * @param e {!Object} A value representing or describing the error.
                + */
                +BlocklyDevTools.Analytics.onError = function(e) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ &&
                +      console.log('Analytics.onError("' + e.toString() + '")');
                +};
                +
                +/**
                + * Event noting the user was notified with a warning.
                + *
                + * @package
                + * @param msg {string} The warning message, or a description thereof.
                + */
                +BlocklyDevTools.Analytics.onWarning = function(msg) {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.onWarning("' + msg + '")');
                +};
                +
                +/**
                + * Request the analytics framework to send any queued events to the server.
                + * @package
                + */
                +BlocklyDevTools.Analytics.sendQueued = function() {
                +  // stub
                +  this.LOG_TO_CONSOLE_ && console.log('Analytics.sendQueued');
                +};
                +
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/app_controller.js b/blockly/webif/static/blockly/demos/blockfactory/app_controller.js
                new file mode 100644
                index 000000000..e3fc1bd23
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/app_controller.js
                @@ -0,0 +1,758 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview The AppController Class brings together the Block
                + * Factory, Block Library, and Block Exporter functionality into a single web
                + * app.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +goog.provide('AppController');
                +
                +goog.require('BlockFactory');
                +goog.require('BlocklyDevTools.Analytics');
                +goog.require('FactoryUtils');
                +goog.require('BlockLibraryController');
                +goog.require('BlockExporterController');
                +goog.require('goog.dom.classlist');
                +goog.require('goog.ui.PopupColorPicker');
                +goog.require('goog.ui.ColorPicker');
                +
                +
                +/**
                + * Controller for the Blockly Factory
                + * @constructor
                + */
                +AppController = function() {
                +  // Initialize Block Library
                +  this.blockLibraryName = 'blockLibrary';
                +  this.blockLibraryController =
                +      new BlockLibraryController(this.blockLibraryName);
                +  this.blockLibraryController.populateBlockLibrary();
                +
                +  // Construct Workspace Factory Controller.
                +  this.workspaceFactoryController = new WorkspaceFactoryController
                +      ('workspacefactory_toolbox', 'toolbox_blocks', 'preview_blocks');
                +
                +  // Initialize Block Exporter
                +  this.exporter =
                +      new BlockExporterController(this.blockLibraryController.storage);
                +
                +  // Map of tab type to the div element for the tab.
                +  this.tabMap = Object.create(null);
                +  this.tabMap[AppController.BLOCK_FACTORY] =
                +      document.getElementById('blockFactory_tab');
                +  this.tabMap[AppController.WORKSPACE_FACTORY] =
                +      document.getElementById('workspaceFactory_tab');
                +  this.tabMap[AppController.EXPORTER] =
                +      document.getElementById('blocklibraryExporter_tab');
                +
                +  // Last selected tab.
                +  this.lastSelectedTab = null;
                +  // Selected tab.
                +  this.selectedTab = AppController.BLOCK_FACTORY;
                +};
                +
                +// Constant values representing the three tabs in the controller.
                +AppController.BLOCK_FACTORY = 'BLOCK_FACTORY';
                +AppController.WORKSPACE_FACTORY = 'WORKSPACE_FACTORY';
                +AppController.EXPORTER = 'EXPORTER';
                +
                +/**
                + * Tied to the 'Import Block Library' button. Imports block library from file to
                + * Block Factory. Expects user to upload a single file of JSON mapping each
                + * block type to its XML text representation.
                + */
                +AppController.prototype.importBlockLibraryFromFile = function() {
                +  var self = this;
                +  var files = document.getElementById('files');
                +  // If the file list is empty, the user likely canceled in the dialog.
                +  if (files.files.length > 0) {
                +    BlocklyDevTools.Analytics.onImport(
                +        BlocklyDevTools.Analytics.BLOCK_FACTORY_LIBRARY,
                +        { format: BlocklyDevTools.Analytics.FORMAT_XML });
                +
                +    // The input tag doesn't have the "multiple" attribute
                +    // so the user can only choose 1 file.
                +    var file = files.files[0];
                +    var fileReader = new FileReader();
                +
                +    // Create a map of block type to XML text from the file when it has been
                +    // read.
                +    fileReader.addEventListener('load', function(event) {
                +      var fileContents = event.target.result;
                +      // Create empty object to hold the read block library information.
                +      var blockXmlTextMap = Object.create(null);
                +      try {
                +        // Parse the file to get map of block type to XML text.
                +        blockXmlTextMap = self.formatBlockLibraryForImport_(fileContents);
                +      } catch (e) {
                +        var message = 'Could not load your block library file.\n'
                +        window.alert(message + '\nFile Name: ' + file.name);
                +        return;
                +      }
                +
                +      // Create a new block library storage object with inputted block library.
                +      var blockLibStorage = new BlockLibraryStorage(
                +          self.blockLibraryName, blockXmlTextMap);
                +
                +      // Update block library controller with the new block library
                +      // storage.
                +      self.blockLibraryController.setBlockLibraryStorage(blockLibStorage);
                +      // Update the block library dropdown.
                +      self.blockLibraryController.populateBlockLibrary();
                +      // Update the exporter's block library storage.
                +      self.exporter.setBlockLibraryStorage(blockLibStorage);
                +    });
                +    // Read the file.
                +    fileReader.readAsText(file);
                +  }
                +};
                +
                +/**
                + * Tied to the 'Export Block Library' button. Exports block library to file that
                + * contains JSON mapping each block type to its XML text representation.
                + */
                +AppController.prototype.exportBlockLibraryToFile = function() {
                +  // Get map of block type to XML.
                +  var blockLib = this.blockLibraryController.getBlockLibrary();
                +  // Concatenate the XMLs, each separated by a blank line.
                +  var blockLibText = this.formatBlockLibraryForExport_(blockLib);
                +  // Get file name.
                +  var filename = prompt('Enter the file name under which to save your block ' +
                +      'library.', 'library.xml');
                +  // Download file if all necessary parameters are provided.
                +  if (filename) {
                +    FactoryUtils.createAndDownloadFile(blockLibText, filename, 'xml');
                +    BlocklyDevTools.Analytics.onExport(
                +        BlocklyDevTools.Analytics.BLOCK_FACTORY_LIBRARY,
                +        { format: BlocklyDevTools.Analytics.FORMAT_XML });
                +  } else {
                +    var msg = 'Could not export Block Library without file name under which ' +
                +      'to save library.';
                +    BlocklyDevTools.Analytics.onWarning(msg);
                +    alert(msg);
                +  }
                +};
                +
                +/**
                + * Converts an object mapping block type to XML to text file for output.
                + * @param {!Object} blockXmlMap Object mapping block type to XML.
                + * @return {string} XML text containing the block XMLs.
                + * @private
                + */
                +AppController.prototype.formatBlockLibraryForExport_ = function(blockXmlMap) {
                +  // Create DOM for XML.
                +  var xmlDom = goog.dom.createDom('xml', {
                +    'xmlns':"http://www.w3.org/1999/xhtml"
                +  });
                +
                +  // Append each block node to XML DOM.
                +  for (var blockType in blockXmlMap) {
                +    var blockXmlDom = Blockly.Xml.textToDom(blockXmlMap[blockType]);
                +    var blockNode = blockXmlDom.firstElementChild;
                +    xmlDom.appendChild(blockNode);
                +  }
                +
                +  // Return the XML text.
                +  return Blockly.Xml.domToText(xmlDom);
                +};
                +
                +/**
                + * Converts imported block library to an object mapping block type to block XML.
                + * @param {string} xmlText String representation of an XML with each block as
                + *    a child node.
                + * @return {!Object} Object mapping block type to XML text.
                + * @private
                + */
                +AppController.prototype.formatBlockLibraryForImport_ = function(xmlText) {
                +  var xmlDom = Blockly.Xml.textToDom(xmlText);
                +
                +  // Get array of XMLs. Use an asterisk (*) instead of a tag name for the XPath
                +  // selector, to match all elements at that level and get all factory_base
                +  // blocks.
                +  var blockNodes = goog.dom.xml.selectNodes(xmlDom, '*');
                +
                +  // Create empty map. The line below creates a  truly empy object. It doesn't
                +  // have built-in attributes/functions such as length or toString.
                +  var blockXmlTextMap = Object.create(null);
                +
                +  // Populate map.
                +  for (var i = 0, blockNode; blockNode = blockNodes[i]; i++) {
                +
                +    // Add outer XML tag to the block for proper injection in to the
                +    // main workspace.
                +    // Create DOM for XML.
                +    var xmlDom = goog.dom.createDom('xml', {
                +      'xmlns':"http://www.w3.org/1999/xhtml"
                +    });
                +    xmlDom.appendChild(blockNode);
                +
                +    xmlText = Blockly.Xml.domToText(xmlDom);
                +    // All block types should be lowercase.
                +    var blockType = this.getBlockTypeFromXml_(xmlText).toLowerCase();
                +    // Some names are invalid so fix them up.
                +    blockType = FactoryUtils.cleanBlockType(blockType);
                +
                +    blockXmlTextMap[blockType] = xmlText;
                +  }
                +
                +  return blockXmlTextMap;
                +};
                +
                +/**
                + * Extracts out block type from XML text, the kind that is saved in block
                + * library storage.
                + * @param {string} xmlText A block's XML text.
                + * @return {string} The block type that corresponds to the provided XML text.
                + * @private
                + */
                +AppController.prototype.getBlockTypeFromXml_ = function(xmlText) {
                +  var xmlDom = Blockly.Xml.textToDom(xmlText);
                +  // Find factory base block.
                +  var factoryBaseBlockXml = xmlDom.getElementsByTagName('block')[0];
                +  // Get field elements from factory base.
                +  var fields = factoryBaseBlockXml.getElementsByTagName('field');
                +  for (var i = 0; i < fields.length; i++) {
                +    // The field whose name is 'NAME' holds the block type as its value.
                +    if (fields[i].getAttribute('name') == 'NAME') {
                +      return fields[i].childNodes[0].nodeValue;
                +    }
                +  }
                +};
                +
                +/**
                + * Add click handlers to each tab to allow switching between the Block Factory,
                + * Workspace Factory, and Block Exporter tab.
                + * @param {!Object} tabMap Map of tab name to div element that is the tab.
                + */
                +AppController.prototype.addTabHandlers = function(tabMap) {
                +  var self = this;
                +  for (var tabName in tabMap) {
                +    var tab = tabMap[tabName];
                +    // Use an additional closure to correctly assign the tab callback.
                +    tab.addEventListener('click', self.makeTabClickHandler_(tabName));
                +  }
                +};
                +
                +/**
                + * Set the selected tab.
                + * @param {string} tabName AppController.BLOCK_FACTORY,
                + *    AppController.WORKSPACE_FACTORY, or AppController.EXPORTER
                + * @private
                + */
                +AppController.prototype.setSelected_ = function(tabName) {
                +  this.lastSelectedTab = this.selectedTab;
                +  this.selectedTab = tabName;
                +};
                +
                +/**
                + * Creates the tab click handler specific to the tab specified.
                + * @param {string} tabName AppController.BLOCK_FACTORY,
                + *    AppController.WORKSPACE_FACTORY, or AppController.EXPORTER
                + * @return {!Function} The tab click handler.
                + * @private
                + */
                +AppController.prototype.makeTabClickHandler_ = function(tabName) {
                +  var self = this;
                +  return function() {
                +    self.setSelected_(tabName);
                +    self.onTab();
                +  };
                +};
                +
                +/**
                + * Called on each tab click. Hides and shows specific content based on which tab
                + * (Block Factory, Workspace Factory, or Exporter) is selected.
                + */
                +AppController.prototype.onTab = function() {
                +  // Get tab div elements.
                +  var blockFactoryTab = this.tabMap[AppController.BLOCK_FACTORY];
                +  var exporterTab = this.tabMap[AppController.EXPORTER];
                +  var workspaceFactoryTab = this.tabMap[AppController.WORKSPACE_FACTORY];
                +
                +  // Warn user if they have unsaved changes when leaving Block Factory.
                +  if (this.lastSelectedTab == AppController.BLOCK_FACTORY &&
                +      this.selectedTab != AppController.BLOCK_FACTORY) {
                +
                +    var hasUnsavedChanges =
                +        !FactoryUtils.savedBlockChanges(this.blockLibraryController);
                +    if (hasUnsavedChanges) {
                +      var msg = 'You have unsaved changes in Block Factory.';
                +      var continueAnyway = confirm(msg);
                +      BlocklyDevTools.Analytics.onWarning(msg);
                +      if (!continueAnyway) {
                +        // If the user doesn't want to switch tabs with unsaved changes,
                +        // stay on Block Factory Tab.
                +        this.setSelected_(AppController.BLOCK_FACTORY);
                +        this.lastSelectedTab = AppController.BLOCK_FACTORY;
                +        return;
                +      }
                +    }
                +  }
                +
                +  // Only enable key events in workspace factory if workspace factory tab is
                +  // selected.
                +  this.workspaceFactoryController.keyEventsEnabled =
                +      this.selectedTab == AppController.WORKSPACE_FACTORY;
                +
                +  // Turn selected tab on and other tabs off.
                +  this.styleTabs_();
                +
                +  if (this.selectedTab == AppController.EXPORTER) {
                +    BlocklyDevTools.Analytics.onNavigateTo('Exporter');
                +
                +    // Hide other tabs.
                +    FactoryUtils.hide('workspaceFactoryContent');
                +    FactoryUtils.hide('blockFactoryContent');
                +    // Show exporter tab.
                +    FactoryUtils.show('blockLibraryExporter');
                +
                +    // Need accurate state in order to know which blocks are used in workspace
                +    // factory.
                +    this.workspaceFactoryController.saveStateFromWorkspace();
                +
                +    // Update exporter's list of the types of blocks used in workspace factory.
                +    var usedBlockTypes = this.workspaceFactoryController.getAllUsedBlockTypes();
                +    this.exporter.setUsedBlockTypes(usedBlockTypes);
                +
                +    // Update exporter's block selector to reflect current block library.
                +    this.exporter.updateSelector();
                +
                +    // Update the exporter's preview to reflect any changes made to the blocks.
                +    this.exporter.updatePreview();
                +
                +  } else if (this.selectedTab ==  AppController.BLOCK_FACTORY) {
                +    BlocklyDevTools.Analytics.onNavigateTo('BlockFactory');
                +
                +    // Hide other tabs.
                +    FactoryUtils.hide('blockLibraryExporter');
                +    FactoryUtils.hide('workspaceFactoryContent');
                +    // Show Block Factory.
                +    FactoryUtils.show('blockFactoryContent');
                +
                +  } else if (this.selectedTab == AppController.WORKSPACE_FACTORY) {
                +    // TODO: differentiate Workspace and Toolbox editor, based on the other tab state.
                +    BlocklyDevTools.Analytics.onNavigateTo('WorkspaceFactory');
                +
                +    // Hide other tabs.
                +    FactoryUtils.hide('blockLibraryExporter');
                +    FactoryUtils.hide('blockFactoryContent');
                +    // Show workspace factory container.
                +    FactoryUtils.show('workspaceFactoryContent');
                +    // Update block library category.
                +    var categoryXml = this.exporter.getBlockLibraryCategory();
                +    var blockTypes = this.blockLibraryController.getStoredBlockTypes();
                +    this.workspaceFactoryController.setBlockLibCategory(categoryXml,
                +        blockTypes);
                +  }
                +
                +  // Resize to render workspaces' toolboxes correctly for all tabs.
                +  window.dispatchEvent(new Event('resize'));
                +};
                +
                +/**
                + * Called on each tab click. Styles the tabs to reflect which tab is selected.
                + * @private
                + */
                +AppController.prototype.styleTabs_ = function() {
                +  for (var tabName in this.tabMap) {
                +    if (this.selectedTab == tabName) {
                +      goog.dom.classlist.addRemove(this.tabMap[tabName], 'taboff', 'tabon');
                +    } else {
                +      goog.dom.classlist.addRemove(this.tabMap[tabName], 'tabon', 'taboff');
                +    }
                +  }
                +};
                +
                +/**
                + * Assign button click handlers for the exporter.
                + */
                +AppController.prototype.assignExporterClickHandlers = function() {
                +  var self = this;
                +  document.getElementById('button_setBlocks').addEventListener('click',
                +      function() {
                +        self.openModal('dropdownDiv_setBlocks');
                +      });
                +
                +  document.getElementById('dropdown_addAllUsed').addEventListener('click',
                +      function() {
                +        self.exporter.selectUsedBlocks();
                +        self.exporter.updatePreview();
                +        self.closeModal();
                +      });
                +
                +  document.getElementById('dropdown_addAllFromLib').addEventListener('click',
                +      function() {
                +        self.exporter.selectAllBlocks();
                +        self.exporter.updatePreview();
                +        self.closeModal();
                +      });
                +
                +  document.getElementById('clearSelectedButton').addEventListener('click',
                +      function() {
                +        self.exporter.clearSelectedBlocks();
                +        self.exporter.updatePreview();
                +      });
                +
                +  // Export blocks when the user submits the export settings.
                +  document.getElementById('exporterSubmitButton').addEventListener('click',
                +      function() {
                +        self.exporter.export();
                +      });
                +};
                +
                +/**
                + * Assign change listeners for the exporter. These allow for the dynamic update
                + * of the exporter preview.
                + */
                +AppController.prototype.assignExporterChangeListeners = function() {
                +  var self = this;
                +
                +  var blockDefCheck = document.getElementById('blockDefCheck');
                +  var genStubCheck = document.getElementById('genStubCheck');
                +
                +  // Select the block definitions and generator stubs on default.
                +  blockDefCheck.checked = true;
                +  genStubCheck.checked = true;
                +
                +  // Checking the block definitions checkbox displays preview of code to export.
                +  document.getElementById('blockDefCheck').addEventListener('change',
                +      function(e) {
                +        self.ifCheckedEnable(blockDefCheck.checked,
                +            ['blockDefs', 'blockDefSettings']);
                +      });
                +
                +  // Preview updates when user selects different block definition format.
                +  document.getElementById('exportFormat').addEventListener('change',
                +      function(e) {
                +        self.exporter.updatePreview();
                +      });
                +
                +  // Checking the generator stub checkbox displays preview of code to export.
                +  document.getElementById('genStubCheck').addEventListener('change',
                +      function(e) {
                +        self.ifCheckedEnable(genStubCheck.checked,
                +            ['genStubs', 'genStubSettings']);
                +      });
                +
                +  // Preview updates when user selects different generator stub language.
                +  document.getElementById('exportLanguage').addEventListener('change',
                +      function(e) {
                +        self.exporter.updatePreview();
                +      });
                +};
                +
                +/**
                + * If given checkbox is checked, enable the given elements.  Otherwise, disable.
                + * @param {boolean} enabled True if enabled, false otherwise.
                + * @param {!Array.<string>} idArray Array of element IDs to enable when
                + *    checkbox is checked.
                + */
                +AppController.prototype.ifCheckedEnable = function(enabled, idArray) {
                +  for (var i = 0, id; id = idArray[i]; i++) {
                +    var element = document.getElementById(id);
                +    if (enabled) {
                +      element.classList.remove('disabled');
                +    } else {
                +      element.classList.add('disabled');
                +    }
                +    var fields = element.querySelectorAll('input, textarea, select');
                +    for (var j = 0, field; field = fields[j]; j++) {
                +      field.disabled = !enabled;
                +    }
                +  }
                +};
                +
                +/**
                + * Assign button click handlers for the block library.
                + */
                +AppController.prototype.assignLibraryClickHandlers = function() {
                +  var self = this;
                +
                +  // Button for saving block to library.
                +  document.getElementById('saveToBlockLibraryButton').addEventListener('click',
                +      function() {
                +        self.blockLibraryController.saveToBlockLibrary();
                +      });
                +
                +  // Button for removing selected block from library.
                +  document.getElementById('removeBlockFromLibraryButton').addEventListener(
                +    'click',
                +      function() {
                +        self.blockLibraryController.removeFromBlockLibrary();
                +      });
                +
                +  // Button for clearing the block library.
                +  document.getElementById('clearBlockLibraryButton').addEventListener('click',
                +      function() {
                +        self.blockLibraryController.clearBlockLibrary();
                +      });
                +
                +  // Hide and show the block library dropdown.
                +  document.getElementById('button_blockLib').addEventListener('click',
                +      function() {
                +        self.openModal('dropdownDiv_blockLib');
                +      });
                +};
                +
                +/**
                + * Assign button click handlers for the block factory.
                + */
                +AppController.prototype.assignBlockFactoryClickHandlers = function() {
                +  var self = this;
                +  // Assign button event handlers for Block Factory.
                +  document.getElementById('localSaveButton')
                +      .addEventListener('click', function() {
                +        self.exportBlockLibraryToFile();
                +      });
                +
                +  document.getElementById('helpButton').addEventListener('click',
                +      function() {
                +        open('https://developers.google.com/blockly/custom-blocks/block-factory',
                +             'BlockFactoryHelp');
                +      });
                +
                +  document.getElementById('files').addEventListener('change',
                +      function() {
                +        // Warn user.
                +        var replace = confirm('This imported block library will ' +
                +            'replace your current block library.');
                +        if (replace) {
                +          self.importBlockLibraryFromFile();
                +          // Clear this so that the change event still fires even if the
                +          // same file is chosen again. If the user re-imports a file, we
                +          // want to reload the workspace with its contents.
                +          this.value = null;
                +        }
                +      });
                +
                +  document.getElementById('createNewBlockButton')
                +    .addEventListener('click', function() {
                +      // If there are unsaved changes warn user, check if they'd like to
                +      // proceed with unsaved changes, and act accordingly.
                +      var proceedWithUnsavedChanges =
                +          self.blockLibraryController.warnIfUnsavedChanges();
                +      if (!proceedWithUnsavedChanges) {
                +        return;
                +      }
                +
                +      BlockFactory.showStarterBlock();
                +      self.blockLibraryController.setNoneSelected();
                +
                +      // Close the Block Library Dropdown.
                +      self.closeModal();
                +    });
                +};
                +
                +/**
                + * Add event listeners for the block factory.
                + */
                +AppController.prototype.addBlockFactoryEventListeners = function() {
                +  // Update code on changes to block being edited.
                +  BlockFactory.mainWorkspace.addChangeListener(BlockFactory.updateLanguage);
                +
                +  // Disable blocks not attached to the factory_base block.
                +  BlockFactory.mainWorkspace.addChangeListener(Blockly.Events.disableOrphans);
                +
                +  // Update the buttons on the screen based on whether
                +  // changes have been saved.
                +  var self = this;
                +  BlockFactory.mainWorkspace.addChangeListener(function() {
                +    self.blockLibraryController.updateButtons(FactoryUtils.savedBlockChanges(
                +        self.blockLibraryController));
                +    });
                +
                +  document.getElementById('direction')
                +      .addEventListener('change', BlockFactory.updatePreview);
                +  document.getElementById('languageTA')
                +      .addEventListener('change', BlockFactory.updatePreview);
                +  document.getElementById('languageTA')
                +      .addEventListener('keyup', BlockFactory.updatePreview);
                +  document.getElementById('format')
                +      .addEventListener('change', BlockFactory.formatChange);
                +  document.getElementById('language')
                +      .addEventListener('change', BlockFactory.updatePreview);
                +};
                +
                +/**
                + * Handle Blockly Storage with App Engine.
                + */
                +AppController.prototype.initializeBlocklyStorage = function() {
                +  BlocklyStorage.HTTPREQUEST_ERROR =
                +      'There was a problem with the request.\n';
                +  BlocklyStorage.LINK_ALERT =
                +      'Share your blocks with this link:\n\n%1';
                +  BlocklyStorage.HASH_ERROR =
                +      'Sorry, "%1" doesn\'t correspond with any saved Blockly file.';
                +  BlocklyStorage.XML_ERROR = 'Could not load your saved file.\n' +
                +      'Perhaps it was created with a different version of Blockly?';
                +  var linkButton = document.getElementById('linkButton');
                +  linkButton.style.display = 'inline-block';
                +  linkButton.addEventListener('click',
                +      function() {
                +          BlocklyStorage.link(BlockFactory.mainWorkspace);});
                +  BlockFactory.disableEnableLink();
                +};
                +
                +/**
                + * Handle resizing of elements.
                + */
                +AppController.prototype.onresize = function(event) {
                +  if (this.selectedTab == AppController.BLOCK_FACTORY) {
                +    // Handle resizing of Block Factory elements.
                +    var expandList = [
                +      document.getElementById('blocklyPreviewContainer'),
                +      document.getElementById('blockly'),
                +      document.getElementById('blocklyMask'),
                +      document.getElementById('preview'),
                +      document.getElementById('languagePre'),
                +      document.getElementById('languageTA'),
                +      document.getElementById('generatorPre'),
                +    ];
                +    for (var i = 0, expand; expand = expandList[i]; i++) {
                +      expand.style.width = (expand.parentNode.offsetWidth - 2) + 'px';
                +      expand.style.height = (expand.parentNode.offsetHeight - 2) + 'px';
                +    }
                +  } else if (this.selectedTab == AppController.EXPORTER) {
                +    // Handle resize of Exporter block options.
                +    this.exporter.view.centerPreviewBlocks();
                +  }
                +};
                +
                +/**
                + * Handler for the window's 'beforeunload' event. When a user has unsaved
                + * changes and refreshes or leaves the page, confirm that they want to do so
                + * before actually refreshing.
                + * @param {!Event} e beforeunload event.
                + */
                +AppController.prototype.confirmLeavePage = function(e) {
                +  BlocklyDevTools.Analytics.sendQueued();
                +  if ((!BlockFactory.isStarterBlock() &&
                +      !FactoryUtils.savedBlockChanges(blocklyFactory.blockLibraryController)) ||
                +      blocklyFactory.workspaceFactoryController.hasUnsavedChanges()) {
                +
                +    var confirmationMessage = 'You will lose any unsaved changes. ' +
                +        'Are you sure you want to exit this page?';
                +    BlocklyDevTools.Analytics.onWarning(confirmationMessage);
                +    e.returnValue = confirmationMessage;
                +    return confirmationMessage;
                +  }
                +};
                +
                +/**
                + * Show a modal element, usually a dropdown list.
                + * @param {string} id ID of element to show.
                + */
                +AppController.prototype.openModal = function(id) {
                +  Blockly.hideChaff();
                +  this.modalName_ = id;
                +  document.getElementById(id).style.display = 'block';
                +  document.getElementById('modalShadow').style.display = 'block';
                +};
                +
                +/**
                + * Hide a previously shown modal element.
                + */
                +AppController.prototype.closeModal = function() {
                +  var id = this.modalName_;
                +  if (!id) {
                +    return;
                +  }
                +  document.getElementById(id).style.display = 'none';
                +  document.getElementById('modalShadow').style.display = 'none';
                +  this.modalName_ = null;
                +};
                +
                +/**
                + * Name of currently open modal.
                + * @type {string?}
                + * @private
                + */
                +AppController.prototype.modalName_ = null;
                +
                +/**
                + * Initialize Blockly and layout.  Called on page load.
                + */
                +AppController.prototype.init = function() {
                +  // Block Factory has a dependency on bits of Closure that core Blockly
                +  // doesn't have. When you run this from file:// without a copy of Closure,
                +  // it breaks it non-obvious ways.  Warning about this for now until the
                +  // dependency is broken.
                +  // TODO: #668.
                +  if (!window.goog.dom.xml) {
                +    alert('Sorry: Closure dependency not found. We are working on removing ' +
                +      'this dependency.  In the meantime, you can use our hosted demo\n ' +
                +      'https://blockly-demo.appspot.com/static/demos/blockfactory/index.html' +
                +      '\nor use these instructions to continue running locally:\n' +
                +      'https://developers.google.com/blockly/guides/modify/web/closure');
                +    return;
                +  }
                +
                +  var self = this;
                +  // Handle Blockly Storage with App Engine.
                +  if ('BlocklyStorage' in window) {
                +    this.initializeBlocklyStorage();
                +  }
                +
                +  // Assign click handlers.
                +  this.assignExporterClickHandlers();
                +  this.assignLibraryClickHandlers();
                +  this.assignBlockFactoryClickHandlers();
                +  // Hide and show the block library dropdown.
                +  document.getElementById('modalShadow').addEventListener('click',
                +      function() {
                +        self.closeModal();
                +      });
                +
                +  this.onresize();
                +  window.addEventListener('resize', function() {
                +    self.onresize();
                +  });
                +
                +  // Inject Block Factory Main Workspace.
                +  var toolbox = document.getElementById('blockfactory_toolbox');
                +  BlockFactory.mainWorkspace = Blockly.inject('blockly',
                +      {collapse: false,
                +       toolbox: toolbox,
                +       media: '../../media/'});
                +
                +  // Add tab handlers for switching between Block Factory and Block Exporter.
                +  this.addTabHandlers(this.tabMap);
                +
                +  // Assign exporter change listeners.
                +  this.assignExporterChangeListeners();
                +
                +  // Create the root block on Block Factory main workspace.
                +  if ('BlocklyStorage' in window && window.location.hash.length > 1) {
                +    BlocklyStorage.retrieveXml(window.location.hash.substring(1),
                +                               BlockFactory.mainWorkspace);
                +  } else {
                +    BlockFactory.showStarterBlock();
                +  }
                +  BlockFactory.mainWorkspace.clearUndo();
                +
                +  // Add Block Factory event listeners.
                +  this.addBlockFactoryEventListeners();
                +
                +  // Workspace Factory init.
                +  WorkspaceFactoryInit.initWorkspaceFactory(this.workspaceFactoryController);
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_exporter_controller.js b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_controller.js
                new file mode 100644
                index 000000000..705de2667
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_controller.js
                @@ -0,0 +1,339 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for the Block Exporter Controller class. Allows
                + * users to export block definitions and generator stubs of their saved blocks
                + * easily using a visual interface. Depends on Block Exporter View and Block
                + * Exporter Tools classes. Interacts with Export Settings in the index.html.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +
                +'use strict';
                +
                +goog.provide('BlockExporterController');
                +
                +goog.require('BlocklyDevTools.Analytics');
                +goog.require('FactoryUtils');
                +goog.require('StandardCategories');
                +goog.require('BlockExporterView');
                +goog.require('BlockExporterTools');
                +goog.require('goog.dom.xml');
                +
                +
                +/**
                + * BlockExporter Controller Class
                + * @param {!BlockLibrary.Storage} blockLibStorage Block Library Storage.
                + * @constructor
                + */
                +BlockExporterController = function(blockLibStorage) {
                +  // BlockLibrary.Storage object containing user's saved blocks.
                +  this.blockLibStorage = blockLibStorage;
                +  // Utils for generating code to export.
                +  this.tools = new BlockExporterTools();
                +  // The ID of the block selector, a div element that will be populated with the
                +  // block options.
                +  this.selectorID = 'blockSelector';
                +  // Map of block types stored in block library to their corresponding Block
                +  // Option objects.
                +  this.blockOptions = this.tools.createBlockSelectorFromLib(
                +      this.blockLibStorage, this.selectorID);
                +  // View provides the block selector and export settings UI.
                +  this.view = new BlockExporterView(this.blockOptions);
                +};
                +
                +/**
                + * Set the block library storage object from which exporter exports.
                + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object
                + *    that stores the blocks.
                + */
                +BlockExporterController.prototype.setBlockLibraryStorage =
                +    function(blockLibStorage) {
                +  this.blockLibStorage = blockLibStorage;
                +};
                +
                +/**
                + * Get the block library storage object from which exporter exports.
                + * @return {!BlockLibraryStorage} blockLibStorage Block Library Storage object
                + *    that stores the blocks.
                + */
                +BlockExporterController.prototype.getBlockLibraryStorage =
                +    function(blockLibStorage) {
                +  return this.blockLibStorage;
                +};
                +
                +/**
                + * Get selected blocks from block selector, pulls info from the Export
                + * Settings form in Block Exporter, and downloads code accordingly.
                + */
                +BlockExporterController.prototype.export = function() {
                +  // Get selected blocks' information.
                +  var blockTypes = this.view.getSelectedBlockTypes();
                +  var blockXmlMap = this.blockLibStorage.getBlockXmlMap(blockTypes);
                +
                +  // Pull block definition(s) settings from the Export Settings form.
                +  var wantBlockDef = document.getElementById('blockDefCheck').checked;
                +  var definitionFormat = document.getElementById('exportFormat').value;
                +  var blockDef_filename = document.getElementById('blockDef_filename').value;
                +
                +  // Pull block generator stub(s) settings from the Export Settings form.
                +  var wantGenStub = document.getElementById('genStubCheck').checked;
                +  var language = document.getElementById('exportLanguage').value;
                +  var generatorStub_filename = document.getElementById(
                +      'generatorStub_filename').value;
                +
                +  if (wantBlockDef) {
                +    // User wants to export selected blocks' definitions.
                +    if (!blockDef_filename) {
                +      // User needs to enter filename.
                +      var msg = 'Please enter a filename for your block definition(s) download.';
                +      BlocklyDevTools.Analytics.onWarning(msg);
                +      alert(msg);
                +    } else {
                +      // Get block definition code in the selected format for the blocks.
                +      var blockDefs = this.tools.getBlockDefinitions(blockXmlMap,
                +          definitionFormat);
                +      // Download the file, using .js file ending for JSON or Javascript.
                +      FactoryUtils.createAndDownloadFile(
                +          blockDefs, blockDef_filename, 'javascript');
                +      BlocklyDevTools.Analytics.onExport(
                +          BlocklyDevTools.Analytics.BLOCK_DEFINITIONS,
                +          {
                +            format: (definitionFormat == 'JSON' ?
                +                BlocklyDevTools.Analytics.FORMAT_JSON :
                +                BlocklyDevTools.Analytics.FORMAT_JS)
                +          });
                +    }
                +  }
                +
                +  if (wantGenStub) {
                +    // User wants to export selected blocks' generator stubs.
                +    if (!generatorStub_filename) {
                +      // User needs to enter filename.
                +      var msg = 'Please enter a filename for your generator stub(s) download.';
                +      BlocklyDevTools.Analytics.onWarning(msg);
                +      alert(msg);
                +    } else {
                +      // Get generator stub code in the selected language for the blocks.
                +      var genStubs = this.tools.getGeneratorCode(blockXmlMap,
                +          language);
                +      // Get the correct file extension.
                +      var fileType = (language == 'JavaScript') ? 'javascript' : 'plain';
                +      // Download the file.
                +      FactoryUtils.createAndDownloadFile(
                +          genStubs, generatorStub_filename, fileType);
                +      BlocklyDevTools.Analytics.onExport(
                +          BlocklyDevTools.Analytics.GENERATOR,
                +          (fileType == 'javascript' ?
                +              { format: BlocklyDevTools.Analytics.FORMAT_JS } : undefined));
                +    }
                +  }
                +
                +};
                +
                +/**
                + * Update the Exporter's block selector with block options generated from blocks
                + * stored in block library.
                + */
                +BlockExporterController.prototype.updateSelector = function() {
                +  // Get previously selected block types.
                +  var oldSelectedTypes = this.view.getSelectedBlockTypes();
                +
                +  // Generate options from block library and assign to view.
                +  this.blockOptions = this.tools.createBlockSelectorFromLib(
                +      this.blockLibStorage, this.selectorID);
                +  this.addBlockOptionSelectHandlers();
                +  this.view.setBlockOptions(this.blockOptions);
                +
                +  // Select all previously selected blocks.
                +  for (var i = 0, blockType; blockType = oldSelectedTypes[i]; i++) {
                +    if (this.blockOptions[blockType]) {
                +      this.view.select(blockType);
                +    }
                +  }
                +
                +  this.view.listSelectedBlocks();
                +};
                +
                +/**
                + * Tied to the 'Clear Selected Blocks' button in the Block Exporter.
                + * Deselects all blocks in the selector and updates text accordingly.
                + */
                +BlockExporterController.prototype.clearSelectedBlocks = function() {
                +  this.view.deselectAllBlocks();
                +  this.view.listSelectedBlocks();
                +};
                +
                +/**
                + * Tied to the 'All Stored' button in the Block Exporter 'Select' dropdown.
                + * Selects all blocks stored in block library for export.
                + */
                +BlockExporterController.prototype.selectAllBlocks = function() {
                +  var allBlockTypes = this.blockLibStorage.getBlockTypes();
                +  for (var i = 0, blockType; blockType = allBlockTypes[i]; i++) {
                +    this.view.select(blockType);
                +  }
                +  this.view.listSelectedBlocks();
                +};
                +
                +/**
                + * Returns the category XML containing all blocks in the block library.
                + * @return {Element} XML for a category to be used in toolbox.
                + */
                +BlockExporterController.prototype.getBlockLibraryCategory = function() {
                +  return this.tools.generateCategoryFromBlockLib(this.blockLibStorage);
                +};
                +
                +/**
                + * Add select handlers to each block option to update the view and the selected
                + * blocks accordingly.
                + */
                +BlockExporterController.prototype.addBlockOptionSelectHandlers = function() {
                +  var self = this;
                +
                +  // Click handler for a block option. Toggles whether or not it's selected and
                +  // updates helper text accordingly.
                +  var updateSelectedBlockTypes_ = function(blockOption) {
                +    // Toggle selected.
                +    blockOption.setSelected(!blockOption.isSelected());
                +
                +    // Show currently selected blocks in helper text.
                +    self.view.listSelectedBlocks();
                +  };
                +
                +  // Returns a block option select handler.
                +  var makeBlockOptionSelectHandler_ = function(blockOption) {
                +    return function() {
                +      updateSelectedBlockTypes_(blockOption);
                +      self.updatePreview();
                +    };
                +  };
                +
                +  // Assign a click handler to each block option.
                +  for (var blockType in this.blockOptions) {
                +    var blockOption = this.blockOptions[blockType];
                +    // Use an additional closure to correctly assign the tab callback.
                +    blockOption.dom.addEventListener(
                +        'click', makeBlockOptionSelectHandler_(blockOption));
                +  }
                +};
                +
                +/**
                + * Tied to the 'All Used' button in the Block Exporter's 'Select' button.
                + * Selects all blocks stored in block library and used in workspace factory.
                + */
                +BlockExporterController.prototype.selectUsedBlocks = function() {
                +  // Deselect all blocks.
                +  this.view.deselectAllBlocks();
                +
                +  // Get list of block types that are in block library and used in workspace
                +  // factory.
                +  var storedBlockTypes = this.blockLibStorage.getBlockTypes();
                +  var sharedBlockTypes = [];
                +  // Keep list of custom block types used but not in library.
                +  var unstoredCustomBlockTypes = [];
                +
                +  for (var i = 0, blockType; blockType = this.usedBlockTypes[i]; i++) {
                +    if (storedBlockTypes.indexOf(blockType) != -1) {
                +      sharedBlockTypes.push(blockType);
                +    } else if (StandardCategories.coreBlockTypes.indexOf(blockType) == -1) {
                +      unstoredCustomBlockTypes.push(blockType);
                +    }
                +  }
                +
                +  // Select each shared block type.
                +  for (var i = 0, blockType; blockType = sharedBlockTypes[i]; i++) {
                +    this.view.select(blockType);
                +  }
                +  this.view.listSelectedBlocks();
                +
                +  if (unstoredCustomBlockTypes.length > 0){
                +    // Warn user to import block defifnitions and generator code for blocks
                +    // not in their Block Library nor Blockly's standard library.
                +    var blockTypesText = unstoredCustomBlockTypes.join(', ');
                +    var customWarning = 'Custom blocks used in workspace factory but not ' +
                +        'stored in block library:\n ' + blockTypesText +
                +        '\n\nDon\'t forget to include block definitions and generator code ' +
                +        'for these blocks.';
                +    alert(customWarning);
                +  }
                +};
                +
                +/**
                + * Set the array that holds the block types used in workspace factory.
                + * @param {!Array.<string>} usedBlockTypes Block types used in
                + */
                +BlockExporterController.prototype.setUsedBlockTypes =
                +    function(usedBlockTypes) {
                +  this.usedBlockTypes = usedBlockTypes;
                +};
                +
                +/**
                + * Updates preview code (block definitions and generator stubs) in the exporter
                + * preview to reflect selected blocks.
                + */
                +BlockExporterController.prototype.updatePreview = function() {
                +  // Generate preview code for selected blocks.
                +  var blockDefs = this.getBlockDefinitionsOfSelected();
                +  var genStubs = this.getGeneratorStubsOfSelected();
                +
                +  // Update the text areas containing the code.
                +  FactoryUtils.injectCode(blockDefs, 'blockDefs_textArea');
                +  FactoryUtils.injectCode(genStubs, 'genStubs_textArea');
                +};
                +
                +/**
                + * Returns a map of each selected block's type to its corresponding XML.
                + * @return {!Object} A map of each selected block's type (a string) to its
                + * corresponding XML element.
                + */
                +BlockExporterController.prototype.getSelectedBlockXmlMap = function() {
                +  var blockTypes = this.view.getSelectedBlockTypes();
                +  return this.blockLibStorage.getBlockXmlMap(blockTypes);
                +};
                +
                +/**
                + * Get block definition code in the selected format for selected blocks.
                + * @return {string} The concatenation of each selected block's language code
                + * in the format specified in export settings.
                + */
                +BlockExporterController.prototype.getBlockDefinitionsOfSelected = function() {
                +  // Get selected blocks' information.
                +  var blockXmlMap = this.getSelectedBlockXmlMap();
                +
                +  // Get block definition code in the selected format for the blocks.
                +  var definitionFormat = document.getElementById('exportFormat').value;
                +  return this.tools.getBlockDefinitions(blockXmlMap, definitionFormat);
                +};
                +
                +/**
                + * Get generator stubs in the selected language for selected blocks.
                + * @return {string} The concatenation of each selected block's generator stub
                + * in the language specified in export settings.
                + */
                +BlockExporterController.prototype.getGeneratorStubsOfSelected = function() {
                +  // Get selected blocks' information.
                +  var blockXmlMap = this.getSelectedBlockXmlMap();
                +
                +  // Get generator stub code in the selected language for the blocks.
                +  var language = document.getElementById('exportLanguage').value;
                +  return this.tools.getGeneratorCode(blockXmlMap, language);
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_exporter_tools.js b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_tools.js
                new file mode 100644
                index 000000000..4d6d9bec6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_tools.js
                @@ -0,0 +1,277 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for the BlockExporter Tools class, which generates
                + * block definitions and generator stubs for given block types.  Also generates
                + * toolbox XML for the exporter's workspace.  Depends on the FactoryUtils for
                + * its code generation functions.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +'use strict';
                +
                +goog.provide('BlockExporterTools');
                +
                +goog.require('FactoryUtils');
                +goog.require('BlockOption');
                +goog.require('goog.dom');
                +goog.require('goog.dom.xml');
                +
                +
                +/**
                +* Block Exporter Tools Class
                +* @constructor
                +*/
                +BlockExporterTools = function() {
                +  // Create container for hidden workspace.
                +  this.container = goog.dom.createDom('div', {
                +    'id': 'blockExporterTools_hiddenWorkspace'
                +  }, ''); // Empty quotes for empty div.
                +  // Hide hidden workspace.
                +  this.container.style.display = 'none';
                +  document.body.appendChild(this.container);
                +  /**
                +   * Hidden workspace for the Block Exporter that holds pieces that make
                +   * up the block
                +   * @type {Blockly.Workspace}
                +   */
                +  this.hiddenWorkspace = Blockly.inject(this.container.id,
                +      {collapse: false,
                +       media: '../../media/'});
                +};
                +
                +/**
                + * Get Blockly Block object from XML that encodes the blocks used to design
                + * the block.
                + * @param {!Element} xml XML element that encodes the blocks used to design
                + *    the block. For example, the block XMLs saved in block library.
                + * @return {!Blockly.Block} Root block (factory_base block) which contains
                + *    all information needed to generate block definition or null.
                + * @private
                + */
                +BlockExporterTools.prototype.getRootBlockFromXml_ = function(xml) {
                +  // Render XML in hidden workspace.
                +  this.hiddenWorkspace.clear();
                +  Blockly.Xml.domToWorkspace(xml, this.hiddenWorkspace);
                +  // Get root block.
                +  var rootBlock = this.hiddenWorkspace.getTopBlocks()[0] || null;
                +  return rootBlock;
                +};
                +
                +/**
                + * Return the given language code of each block type in an array.
                + * @param {!Object} blockXmlMap Map of block type to XML.
                + * @param {string} definitionFormat 'JSON' or 'JavaScript'
                + * @return {string} The concatenation of each block's language code in the
                + *    desired format.
                + */
                +BlockExporterTools.prototype.getBlockDefinitions =
                +    function(blockXmlMap, definitionFormat) {
                +  var blockCode = [];
                +  for (var blockType in blockXmlMap) {
                +    var xml = blockXmlMap[blockType];
                +    if (xml) {
                +      // Render and get block from hidden workspace.
                +      var rootBlock = this.getRootBlockFromXml_(xml);
                +      if (rootBlock) {
                +        // Generate the block's definition.
                +        var code = FactoryUtils.getBlockDefinition(blockType, rootBlock,
                +            definitionFormat, this.hiddenWorkspace);
                +        // Add block's definition to the definitions to return.
                +      } else {
                +        // Append warning comment and write to console.
                +        var code = '// No block definition generated for ' + blockType +
                +          '. Could not find root block in XML stored for this block.';
                +        console.log('No block definition generated for ' + blockType +
                +          '. Could not find root block in XML stored for this block.');
                +      }
                +    } else {
                +      // Append warning comment and write to console.
                +      var code = '// No block definition generated for ' + blockType +
                +        '. Block was not found in Block Library Storage.';
                +      console.log('No block definition generated for ' + blockType +
                +        '. Block was not found in Block Library Storage.');
                +    }
                +    blockCode.push(code);
                +  }
                +
                +  // Surround json with [] and comma separate items.
                +  if (definitionFormat == "JSON") {
                +    return "[" + blockCode.join(",\n") + "]";
                +  }
                +  return blockCode.join("\n\n");
                +};
                +
                +/**
                + * Return the generator code of each block type in an array in a given language.
                + * @param {!Object} blockXmlMap Map of block type to XML.
                + * @param {string} generatorLanguage E.g. 'JavaScript', 'Python', 'PHP', 'Lua',
                + *     'Dart'
                + * @return {string} The concatenation of each block's generator code in the
                + * desired format.
                + */
                +BlockExporterTools.prototype.getGeneratorCode =
                +    function(blockXmlMap, generatorLanguage) {
                +  var multiblockCode = [];
                +  // Define the custom blocks in order to be able to create instances of
                +  // them in the exporter workspace.
                +  this.addBlockDefinitions(blockXmlMap);
                +
                +  for (var blockType in blockXmlMap) {
                +    var xml = blockXmlMap[blockType];
                +    if (xml) {
                +      // Render the preview block in the hidden workspace.
                +      var tempBlock =
                +          FactoryUtils.getDefinedBlock(blockType, this.hiddenWorkspace);
                +      // Get generator stub for the given block and add to  generator code.
                +      var blockGenCode =
                +          FactoryUtils.getGeneratorStub(tempBlock, generatorLanguage);
                +    } else {
                +      // Append warning comment and write to console.
                +      var blockGenCode = '// No generator stub generated for ' + blockType +
                +        '. Block was not found in Block Library Storage.';
                +      console.log('No block generator stub generated for ' + blockType +
                +        '. Block was not found in Block Library Storage.');
                +    }
                +    multiblockCode.push(blockGenCode);
                +  }
                +  return multiblockCode.join("\n\n");
                +};
                +
                +/**
                + * Evaluates block definition code of each block in given object mapping
                + * block type to XML. Called in order to be able to create instances of the
                + * blocks in the exporter workspace.
                + * @param {!Object} blockXmlMap Map of block type to XML.
                + */
                +BlockExporterTools.prototype.addBlockDefinitions = function(blockXmlMap) {
                +  var blockDefs = this.getBlockDefinitions(blockXmlMap, 'JavaScript');
                +  eval(blockDefs);
                +};
                +
                +/**
                + * Pulls information about all blocks in the block library to generate XML
                + * for the selector workpace's toolbox.
                + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object.
                + * @return {!Element} XML representation of the toolbox.
                + */
                +BlockExporterTools.prototype.generateToolboxFromLibrary
                +    = function(blockLibStorage) {
                +  // Create DOM for XML.
                +  var xmlDom = goog.dom.createDom('xml', {
                +    'id' : 'blockExporterTools_toolbox',
                +    'style' : 'display:none'
                +  });
                +
                +  var allBlockTypes = blockLibStorage.getBlockTypes();
                +  // Object mapping block type to XML.
                +  var blockXmlMap = blockLibStorage.getBlockXmlMap(allBlockTypes);
                +
                +  // Define the custom blocks in order to be able to create instances of
                +  // them in the exporter workspace.
                +  this.addBlockDefinitions(blockXmlMap);
                +
                +  for (var blockType in blockXmlMap) {
                +    // Get block.
                +    var block = FactoryUtils.getDefinedBlock(blockType, this.hiddenWorkspace);
                +    var category = FactoryUtils.generateCategoryXml([block], blockType);
                +    xmlDom.appendChild(category);
                +  }
                +
                +  // If there are no blocks in library and the map is empty, append dummy
                +  // category.
                +  if (Object.keys(blockXmlMap).length == 0) {
                +    var category = goog.dom.createDom('category');
                +    category.setAttribute('name','Next Saved Block');
                +    xmlDom.appendChild(category);
                +  }
                +  return xmlDom;
                +};
                +
                +/**
                + * Generate XML for the workspace factory's category from imported block
                + * definitions.
                + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object.
                + * @return {!Element} XML representation of a category.
                + */
                +BlockExporterTools.prototype.generateCategoryFromBlockLib =
                +    function(blockLibStorage) {
                +  var allBlockTypes = blockLibStorage.getBlockTypes();
                +  // Object mapping block type to XML.
                +  var blockXmlMap = blockLibStorage.getBlockXmlMap(allBlockTypes);
                +
                +  // Define the custom blocks in order to be able to create instances of
                +  // them in the exporter workspace.
                +  this.addBlockDefinitions(blockXmlMap);
                +
                +  // Get array of defined blocks.
                +  var blocks = [];
                +  for (var blockType in blockXmlMap) {
                +    var block = FactoryUtils.getDefinedBlock(blockType, this.hiddenWorkspace);
                +    blocks.push(block);
                +  }
                +
                +  return FactoryUtils.generateCategoryXml(blocks,'Block Library');
                +};
                +
                +/**
                + * Generate selector dom from block library storage. For each block in the
                + * library, it has a block option, which consists of a checkbox, a label,
                + * and a fixed size preview workspace.
                + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object.
                + * @param {string} blockSelectorId ID of the div element that will contain
                + *    the block options.
                + * @return {!Object} Map of block type to Block Option object.
                + */
                +BlockExporterTools.prototype.createBlockSelectorFromLib =
                +    function(blockLibStorage, blockSelectorId) {
                +  // Object mapping each stored block type to XML.
                +  var allBlockTypes = blockLibStorage.getBlockTypes();
                +  var blockXmlMap = blockLibStorage.getBlockXmlMap(allBlockTypes);
                +
                +  // Define the custom blocks in order to be able to create instances of
                +  // them in the exporter workspace.
                +  this.addBlockDefinitions(blockXmlMap);
                +
                +  var blockSelector = document.getElementById(blockSelectorId);
                +  // Clear the block selector.
                +  var child;
                +  while ((child = blockSelector.firstChild)) {
                +    blockSelector.removeChild(child);
                +  }
                +
                +  // Append each block option's dom to the selector.
                +  var blockOptions = Object.create(null);
                +  for (var blockType in blockXmlMap) {
                +    // Get preview block's XML.
                +    var block = FactoryUtils.getDefinedBlock(blockType, this.hiddenWorkspace);
                +    var previewBlockXml = Blockly.Xml.workspaceToDom(this.hiddenWorkspace);
                +
                +    // Create block option, inject block into preview workspace, and append
                +    // option to block selector.
                +    var blockOpt = new BlockOption(blockSelector, blockType, previewBlockXml);
                +    blockOpt.createDom();
                +    blockSelector.appendChild(blockOpt.dom);
                +    blockOpt.showPreviewBlock();
                +    blockOptions[blockType] = blockOpt;
                +  }
                +  return blockOptions;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_exporter_view.js b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_view.js
                new file mode 100644
                index 000000000..198598c14
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_exporter_view.js
                @@ -0,0 +1,124 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for the Block Exporter View class. Reads from and
                + * manages a block selector through which users select blocks to export.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +
                +'use strict';
                +
                +goog.provide('BlockExporterView');
                +
                +goog.require('BlockExporterTools');
                +goog.require('BlockOption');
                +goog.require('goog.dom');
                +
                +
                +/**
                + * BlockExporter View Class
                + * @param {!Object} blockOptions Map of block types to BlockOption objects.
                + * @constructor
                + */
                +BlockExporterView = function(blockOptions) {
                +  //  Map of block types to BlockOption objects to select from.
                +  this.blockOptions = blockOptions;
                +};
                +
                +/**
                + * Set the block options in the selector of this instance of
                + * BlockExporterView.
                + * @param {!Object} blockOptions Map of block types to BlockOption objects.
                + */
                +BlockExporterView.prototype.setBlockOptions = function(blockOptions) {
                +  this.blockOptions = blockOptions;
                +};
                +
                +/**
                + * Updates the helper text to show list of currently selected blocks.
                + */
                +BlockExporterView.prototype.listSelectedBlocks = function() {
                +
                +  var selectedBlocksText = this.getSelectedBlockTypes().join(",\n ");
                +  document.getElementById('selectedBlocksText').textContent = selectedBlocksText;
                +};
                +
                +/**
                + * Selects a given block type in the selector.
                + * @param {string} blockType Type of block to selector.
                + */
                +BlockExporterView.prototype.select = function(blockType) {
                +  this.blockOptions[blockType].setSelected(true);
                +};
                +
                +/**
                + * Deselects a block in the selector.
                + * @param {!Blockly.Block} block Type of block to add to selector workspce.
                + */
                +BlockExporterView.prototype.deselect = function(blockType) {
                +  this.blockOptions[blockType].setSelected(false);
                +};
                +
                +
                +/**
                + * Deselects all blocks.
                + */
                +BlockExporterView.prototype.deselectAllBlocks = function() {
                +  for (var blockType in this.blockOptions) {
                +    this.deselect(blockType);
                +  }
                +};
                +
                +/**
                + * Given an array of selected blocks, selects these blocks in the view, marking
                + * the checkboxes accordingly.
                + * @param {Array.<Blockly.Block>} blockTypes Array of block types to select.
                + */
                +BlockExporterView.prototype.setSelectedBlockTypes = function(blockTypes) {
                +  for (var i = 0, blockType; blockType = blockTypes[i]; i++) {
                +    this.select(blockType);
                +  }
                +};
                +
                +/**
                + * Returns array of selected blocks.
                + * @return {!Array.<string>} Array of all selected block types.
                + */
                +BlockExporterView.prototype.getSelectedBlockTypes = function() {
                +  var selectedTypes = [];
                +  for (var blockType in this.blockOptions) {
                +    var blockOption = this.blockOptions[blockType];
                +    if (blockOption.isSelected()) {
                +      selectedTypes.push(blockType);
                +    }
                +  }
                +  return selectedTypes;
                +};
                +
                +/**
                + * Centers the preview block of each block option in the exporter selector.
                + */
                +BlockExporterView.prototype.centerPreviewBlocks = function() {
                +  for (var blockType in this.blockOptions) {
                +    this.blockOptions[blockType].centerBlock();
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_library_controller.js b/blockly/webif/static/blockly/demos/blockfactory/block_library_controller.js
                new file mode 100644
                index 000000000..b0e540489
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_library_controller.js
                @@ -0,0 +1,326 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Contains the code for Block Library Controller, which
                + * depends on Block Library Storage and Block Library UI. Provides the
                + * interfaces for the user to
                + *  - save their blocks to the browser
                + *  - re-open and edit saved blocks
                + *  - delete blocks
                + *  - clear their block library
                + * Depends on BlockFactory functions defined in factory.js.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +'use strict';
                +
                +goog.provide('BlockLibraryController');
                +
                +goog.require('BlocklyDevTools.Analytics');
                +goog.require('BlockLibraryStorage');
                +goog.require('BlockLibraryView');
                +goog.require('BlockFactory');
                +
                +
                +/**
                + * Block Library Controller Class
                + * @param {string} blockLibraryName Desired name of Block Library, also used
                + *    to create the key for where it's stored in local storage.
                + * @param {!BlockLibraryStorage} opt_blockLibraryStorage Optional storage
                + *    object that allows user to import a block library.
                + * @constructor
                + */
                +BlockLibraryController = function(blockLibraryName, opt_blockLibraryStorage) {
                +  this.name = blockLibraryName;
                +  // Create a new, empty Block Library Storage object, or load existing one.
                +  this.storage = opt_blockLibraryStorage || new BlockLibraryStorage(this.name);
                +  // The BlockLibraryView object handles the proper updating and formatting of
                +  // the block library dropdown.
                +  this.view = new BlockLibraryView();
                +};
                +
                +/**
                + * Returns the block type of the block the user is building.
                + * @return {string} The current block's type.
                + * @private
                + */
                +BlockLibraryController.prototype.getCurrentBlockType = function() {
                +  var rootBlock = FactoryUtils.getRootBlock(BlockFactory.mainWorkspace);
                +  var blockType = rootBlock.getFieldValue('NAME').trim().toLowerCase();
                +  // Replace invalid characters.
                +  return FactoryUtils.cleanBlockType(blockType);
                +};
                +
                +/**
                + * Removes current block from Block Library and updates the save and delete
                + * buttons so that user may save block to library and but not delete.
                + * @param {string} blockType Type of block.
                + */
                +BlockLibraryController.prototype.removeFromBlockLibrary = function() {
                +  var blockType = this.getCurrentBlockType();
                +  this.storage.removeBlock(blockType);
                +  this.storage.saveToLocalStorage();
                +  this.populateBlockLibrary();
                +  this.view.updateButtons(blockType, false, false);
                +};
                +
                +/**
                + * Updates the workspace to show the block user selected from library
                + * @param {string} blockType Block to edit on block factory.
                + */
                +BlockLibraryController.prototype.openBlock = function(blockType) {
                +  if (blockType) {
                +    var xml = this.storage.getBlockXml(blockType);
                +    BlockFactory.mainWorkspace.clear();
                +    Blockly.Xml.domToWorkspace(xml, BlockFactory.mainWorkspace);
                +    BlockFactory.mainWorkspace.clearUndo();
                +  } else {
                +    BlockFactory.showStarterBlock();
                +    this.view.setSelectedBlockType(null);
                +  }
                +};
                +
                +/**
                + * Returns type of block selected from library.
                + * @return {string} Type of block selected.
                + */
                +BlockLibraryController.prototype.getSelectedBlockType = function() {
                +  return this.view.getSelectedBlockType();
                +};
                +
                +/**
                + * Confirms with user before clearing the block library in local storage and
                + * updating the dropdown and displaying the starter block (factory_base).
                + */
                +BlockLibraryController.prototype.clearBlockLibrary = function() {
                +  var msg = 'Delete all blocks from library?';
                +  BlocklyDevTools.Analytics.onWarning(msg);
                +  if (confirm(msg)) {
                +    // Clear Block Library Storage.
                +    this.storage.clear();
                +    this.storage.saveToLocalStorage();
                +    // Update dropdown.
                +    this.view.clearOptions();
                +    // Show default block.
                +    BlockFactory.showStarterBlock();
                +    // User may not save the starter block, but will get explicit instructions
                +    // upon clicking the red save button.
                +    this.view.updateButtons(null);
                +  }
                +};
                +
                +/**
                + * Saves current block to local storage and updates dropdown.
                + */
                +BlockLibraryController.prototype.saveToBlockLibrary = function() {
                +  var blockType = this.getCurrentBlockType();
                +  // If user has not changed the name of the starter block.
                +  if (blockType == 'block_type') {
                +    // Do not save block if it has the default type, 'block_type'.
                +    var msg = 'You cannot save a block under the name "block_type". Try ' +
                +        'changing the name before saving. Then, click on the "Block Library"' +
                +        ' button to view your saved blocks.';
                +    alert(msg);
                +    BlocklyDevTools.Analytics.onWarning(msg);
                +    return;
                +  }
                +
                +  // Create block XML.
                +  var xmlElement = goog.dom.createDom('xml');
                +  var block = FactoryUtils.getRootBlock(BlockFactory.mainWorkspace);
                +  xmlElement.appendChild(Blockly.Xml.blockToDomWithXY(block));
                +
                +  // Do not add option again if block type is already in library.
                +  if (!this.has(blockType)) {
                +    this.view.addOption(blockType, true, true);
                +  }
                +
                +  // Save block.
                +  this.storage.addBlock(blockType, xmlElement);
                +  this.storage.saveToLocalStorage();
                +
                +  // Show saved block without other stray blocks sitting in Block Factory's
                +  // main workspace.
                +  this.openBlock(blockType);
                +
                +  // Add select handler to the new option.
                +  this.addOptionSelectHandler(blockType);
                +  BlocklyDevTools.Analytics.onSave('Block');
                +};
                +
                +/**
                + * Checks to see if the given blockType is already in Block Library
                + * @param {string} blockType Type of block.
                + * @return {boolean} Boolean indicating whether or not block is in the library.
                + */
                +BlockLibraryController.prototype.has = function(blockType) {
                +  var blockLibrary = this.storage.blocks;
                +  return (blockType in blockLibrary && blockLibrary[blockType] != null);
                +};
                +
                +/**
                + * Populates the dropdown menu.
                + */
                +BlockLibraryController.prototype.populateBlockLibrary = function() {
                +  this.view.clearOptions();
                +  // Add an unselected option for each saved block.
                +  var blockLibrary = this.storage.blocks;
                +  for (var blockType in blockLibrary) {
                +    this.view.addOption(blockType, false);
                +  }
                +  this.addOptionSelectHandlers();
                +};
                +
                +/**
                + * Return block library mapping block type to XML.
                + * @return {Object} Object mapping block type to XML text.
                + */
                +BlockLibraryController.prototype.getBlockLibrary = function() {
                +  return this.storage.getBlockXmlTextMap();
                +};
                +
                +/**
                + * Return stored XML of a given block type.
                + * @param {string} blockType The type of block.
                + * @return {!Element} XML element of a given block type or null.
                + */
                +BlockLibraryController.prototype.getBlockXml = function(blockType) {
                +  return this.storage.getBlockXml(blockType);
                +};
                +
                +/**
                + * Set the block library storage object from which exporter exports.
                + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object.
                + */
                +BlockLibraryController.prototype.setBlockLibraryStorage
                +    = function(blockLibStorage) {
                +  this.storage = blockLibStorage;
                +};
                +
                +/**
                + * Get the block library storage object from which exporter exports.
                + * @return {!BlockLibraryStorage} blockLibStorage Block Library Storage object
                + *    that stores the blocks.
                + */
                +BlockLibraryController.prototype.getBlockLibraryStorage = function() {
                +  return this.blockLibStorage;
                +};
                +
                +/**
                + * Get the block library storage object from which exporter exports.
                + * @return {boolean} True if the Block Library is empty, false otherwise.
                + */
                +BlockLibraryController.prototype.hasEmptyBlockLibrary = function() {
                +  return this.storage.isEmpty();
                +};
                +
                +/**
                + * Get all block types stored in block library.
                + * @return {!Array.<string>} Array of block types.
                + */
                +BlockLibraryController.prototype.getStoredBlockTypes = function() {
                +  return this.storage.getBlockTypes();
                +};
                +
                +/**
                + * Sets the currently selected block option to none.
                + */
                +BlockLibraryController.prototype.setNoneSelected = function() {
                +  this.view.setSelectedBlockType(null);
                +};
                +
                +/**
                + * If there are unsaved changes to the block in open in Block Factory
                + * and the block is not the starter block, check if user wants to proceed,
                + * knowing that it will cause them to lose their changes.
                + * @return {boolean} Whether or not to proceed.
                + */
                +BlockLibraryController.prototype.warnIfUnsavedChanges = function() {
                +  if (!FactoryUtils.savedBlockChanges(this)) {
                +    return confirm('You have unsaved changes. By proceeding without saving ' +
                +        ' your block first, you will lose these changes.');
                +  }
                +  return true;
                +};
                +
                +/**
                + * Add select handler for an option of a given block type. The handler will to
                + * update the view and the selected block accordingly.
                + * @param {string} blockType The type of block represented by the option is for.
                + */
                +BlockLibraryController.prototype.addOptionSelectHandler = function(blockType) {
                +  var self = this;
                +
                +  // Click handler for a block option. Sets the block option as the selected
                +  // option and opens the block for edit in Block Factory.
                +  var setSelectedAndOpen_ = function(blockOption) {
                +    var blockType = blockOption.textContent;
                +    self.view.setSelectedBlockType(blockType);
                +    self.openBlock(blockType);
                +    // The block is saved in the block library and all changes have been saved
                +    // when the user opens a block from the block library dropdown.
                +    // Thus, the buttons show up as a disabled update button and an enabled
                +    // delete.
                +    self.view.updateButtons(blockType, true, true);
                +    blocklyFactory.closeModal();
                +  };
                +
                +  // Returns a block option select handler.
                +  var makeOptionSelectHandler_ = function(blockOption) {
                +    return function() {
                +      // If there are unsaved changes warn user, check if they'd like to
                +      // proceed with unsaved changes, and act accordingly.
                +      var proceedWithUnsavedChanges = self.warnIfUnsavedChanges();
                +      if (!proceedWithUnsavedChanges) {
                +        return;
                +      }
                +      setSelectedAndOpen_(blockOption);
                +    };
                +  };
                +
                +  // Assign a click handler to the block option.
                +  var blockOption = this.view.optionMap[blockType];
                +  // Use an additional closure to correctly assign the tab callback.
                +  blockOption.addEventListener(
                +      'click', makeOptionSelectHandler_(blockOption));
                +};
                +
                +/**
                + * Add select handlers to each option to update the view and the selected
                + * blocks accordingly.
                + */
                +BlockLibraryController.prototype.addOptionSelectHandlers = function() {
                +  // Assign a click handler to each block option.
                +  for (var blockType in this.view.optionMap) {
                +    this.addOptionSelectHandler(blockType);
                +  }
                +};
                +
                +/**
                + * Update the save and delete buttons based on the current block type of the
                + * block the user is currently editing.
                + * @param {boolean} Whether changes to the block have been saved.
                + */
                +BlockLibraryController.prototype.updateButtons = function(savedChanges) {
                +  var blockType = this.getCurrentBlockType();
                +  var isInLibrary = this.has(blockType);
                +  this.view.updateButtons(blockType, isInLibrary, savedChanges);
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_library_storage.js b/blockly/webif/static/blockly/demos/blockfactory/block_library_storage.js
                new file mode 100644
                index 000000000..750717752
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_library_storage.js
                @@ -0,0 +1,170 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for Block Library's Storage Class.
                + * Depends on Block Library for its namespace.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +
                +'use strict';
                +
                +goog.provide('BlockLibraryStorage');
                +
                +
                +/**
                + * Represents a block library's storage.
                + * @param {string} blockLibraryName Desired name of Block Library, also used
                + *    to create the key for where it's stored in local storage.
                + * @param {Object} opt_blocks Object mapping block type to XML.
                + * @constructor
                + */
                +BlockLibraryStorage = function(blockLibraryName, opt_blocks) {
                +  // Add prefix to this.name to avoid collisions in local storage.
                +  this.name = 'BlockLibraryStorage.' + blockLibraryName;
                +  if (!opt_blocks) {
                +    // Initialize this.blocks by loading from local storage.
                +    this.loadFromLocalStorage();
                +    if (this.blocks == null) {
                +      this.blocks = Object.create(null);
                +      // The line above is equivalent of {} except that this object is TRULY
                +      // empty. It doesn't have built-in attributes/functions such as length or
                +      // toString.
                +      this.saveToLocalStorage();
                +    }
                +  } else {
                +    this.blocks = opt_blocks;
                +    this.saveToLocalStorage();
                +  }
                +};
                +
                +/**
                + * Reads the named block library from local storage and saves it in this.blocks.
                + */
                +BlockLibraryStorage.prototype.loadFromLocalStorage = function() {
                +  // goog.global is synonymous to window, and allows for flexibility
                +  // between browsers.
                +  var object = goog.global.localStorage[this.name];
                +  this.blocks = object ? JSON.parse(object) : null;
                +};
                +
                +/**
                + * Writes the current block library (this.blocks) to local storage.
                + */
                +BlockLibraryStorage.prototype.saveToLocalStorage = function() {
                +  goog.global.localStorage[this.name] = JSON.stringify(this.blocks);
                +};
                +
                +/**
                + * Clears the current block library.
                + */
                +BlockLibraryStorage.prototype.clear = function() {
                +  this.blocks = Object.create(null);
                +  // The line above is equivalent of {} except that this object is TRULY
                +  // empty. It doesn't have built-in attributes/functions such as length or
                +  // toString.
                +};
                +
                +/**
                + * Saves block to block library.
                + * @param {string} blockType Type of block.
                + * @param {Element} blockXML The block's XML pulled from workspace.
                + */
                +BlockLibraryStorage.prototype.addBlock = function(blockType, blockXML) {
                +  var prettyXml = Blockly.Xml.domToPrettyText(blockXML);
                +  this.blocks[blockType] = prettyXml;
                +};
                +
                +/**
                + * Removes block from current block library (this.blocks).
                + * @param {string} blockType Type of block.
                + */
                +BlockLibraryStorage.prototype.removeBlock = function(blockType) {
                +  delete this.blocks[blockType];
                +};
                +
                +/**
                + * Returns the XML of given block type stored in current block library
                + * (this.blocks).
                + * @param {string} blockType Type of block.
                + * @return {Element} The XML that represents the block type or null.
                + */
                +BlockLibraryStorage.prototype.getBlockXml = function(blockType) {
                +  var xml = this.blocks[blockType] || null;
                +  if (xml) {
                +    var xml = Blockly.Xml.textToDom(xml);
                +  }
                +  return xml;
                +};
                +
                +
                +/**
                + * Returns map of each block type to its corresponding XML stored in current
                + * block library (this.blocks).
                + * @param {!Array.<string>} blockTypes Types of blocks.
                + * @return {!Object} Map of block type to corresponding XML.
                + */
                +BlockLibraryStorage.prototype.getBlockXmlMap = function(blockTypes) {
                +  var blockXmlMap = {};
                +  for (var i = 0; i < blockTypes.length; i++) {
                +    var blockType = blockTypes[i];
                +    var xml = this.getBlockXml(blockType);
                +    blockXmlMap[blockType] = xml;
                +  }
                +  return blockXmlMap;
                +};
                +
                +/**
                + * Returns array of all block types stored in current block library.
                + * @return {!Array.<string>} Array of block types stored in library.
                + */
                +BlockLibraryStorage.prototype.getBlockTypes = function() {
                +  return Object.keys(this.blocks);
                +};
                +
                +/**
                + * Checks to see if block library is empty.
                + * @return {boolean} True if empty, false otherwise.
                + */
                +BlockLibraryStorage.prototype.isEmpty = function() {
                +  for (var blockType in this.blocks) {
                +    return false;
                +  }
                +  return true;
                +};
                +
                +/**
                + * Returns array of all block types stored in current block library.
                + * @return {!Array.<string>} Map of block type to corresponding XML text.
                + */
                +BlockLibraryStorage.prototype.getBlockXmlTextMap = function() {
                +  return this.blocks;
                +};
                +
                +/**
                + * Returns boolean of whether or not a given blockType is stored in block
                + * library.
                + * @param {string} blockType Type of block.
                + * @return {boolean} Whether or not blockType is stored in block library.
                + */
                +BlockLibraryStorage.prototype.has = function(blockType) {
                +  return !!this.blocks[blockType];
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_library_view.js b/blockly/webif/static/blockly/demos/blockfactory/block_library_view.js
                new file mode 100644
                index 000000000..16181f290
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_library_view.js
                @@ -0,0 +1,201 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for BlockLibraryView class. It manages the display
                + * of the Block Library dropdown, save, and delete buttons.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +
                +'use strict';
                +
                +goog.provide('BlockLibraryView');
                +
                +goog.require('goog.dom');
                +goog.require('goog.dom.classlist');
                +
                +
                +/**
                + * BlockLibraryView Class
                + * @constructor
                + */
                +var BlockLibraryView = function() {
                +  // Div element to contain the block types to choose from.
                +  this.dropdown = document.getElementById('dropdownDiv_blockLib');
                +  // Map of block type to corresponding 'a' element that is the option in the
                +  // dropdown. Used to quickly and easily get a specific option.
                +  this.optionMap = Object.create(null);
                +  // Save and delete buttons.
                +  this.saveButton = document.getElementById('saveToBlockLibraryButton');
                +  this.deleteButton = document.getElementById('removeBlockFromLibraryButton');
                +  // Initially, user should not be able to delete a block. They must save a
                +  // block or select a stored block first.
                +  this.deleteButton.disabled = true;
                +};
                +
                +/**
                + * Creates a node of a given element type and appends to the node with given ID.
                + * @param {string} blockType Type of block.
                + * @param {boolean} selected Whether or not the option should be selected on
                + *    the dropdown.
                + */
                +BlockLibraryView.prototype.addOption = function(blockType, selected) {
                +  // Create option.
                +  var option = goog.dom.createDom('a', {
                +    'id': 'dropdown_' + blockType,
                +    'class': 'blockLibOpt'
                +  }, blockType);
                +
                +  // Add option to dropdown.
                +  this.dropdown.appendChild(option);
                +  this.optionMap[blockType] = option;
                +
                +  // Select the block.
                +  if (selected) {
                +    this.setSelectedBlockType(blockType);
                +  }
                +};
                +
                +/**
                + * Sets a given block type to selected and all other blocks to deselected.
                + * If null, deselects all blocks.
                + * @param {string} blockTypeToSelect Type of block to select or null.
                + */
                +BlockLibraryView.prototype.setSelectedBlockType = function(blockTypeToSelect) {
                +  // Select given block type and deselect all others. Will deselect all blocks
                +  // if null or invalid block type selected.
                +  for (var blockType in this.optionMap) {
                +    var option = this.optionMap[blockType];
                +    if (blockType == blockTypeToSelect) {
                +      this.selectOption_(option);
                +    } else {
                +      this.deselectOption_(option);
                +    }
                +  }
                +};
                +
                +/**
                + * Selects a given option.
                + * @param {!Element} option HTML 'a' element in the dropdown that represents
                + *    a particular block type.
                + * @private
                + */
                +BlockLibraryView.prototype.selectOption_ = function(option) {
                +  goog.dom.classlist.add(option, 'dropdown-content-selected');
                +};
                +
                +/**
                + * Deselects a given option.
                + * @param {!Element} option HTML 'a' element in the dropdown that represents
                + *    a particular block type.
                + * @private
                + */
                +BlockLibraryView.prototype.deselectOption_ = function(option) {
                +  goog.dom.classlist.remove(option, 'dropdown-content-selected');
                +};
                +
                +/**
                + * Updates the save and delete buttons to represent how the current block will
                + * be saved by including the block type in the button text as well as indicating
                + * whether the block is being saved or updated.
                + * @param {string} blockType The type of block being edited.
                + * @param {boolean} isInLibrary Whether the block type is in the library.
                + * @param {boolean} savedChanges Whether changes to block have been saved.
                + */
                +BlockLibraryView.prototype.updateButtons =
                +    function(blockType, isInLibrary, savedChanges) {
                +  if (blockType) {
                +    // User is editing a block.
                +
                +    if (!isInLibrary) {
                +      // Block type has not been saved to library yet. Disable the delete button
                +      // and allow user to save.
                +      this.saveButton.textContent = 'Save "' + blockType + '"';
                +      this.saveButton.disabled = false;
                +      this.deleteButton.disabled = true;
                +    } else {
                +      // Block type has already been saved. Disable the save button unless the
                +      // there are unsaved changes (checked below).
                +      this.saveButton.textContent = 'Update "' + blockType + '"';
                +      this.saveButton.disabled = true;
                +      this.deleteButton.disabled = false;
                +    }
                +    this.deleteButton.textContent = 'Delete "' + blockType + '"';
                +
                +    // If changes to block have been made and are not saved, make button
                +    // green to encourage user to save the block.
                +    if (!savedChanges) {
                +      var buttonFormatClass = 'button_warn';
                +
                +      // If block type is the default, 'block_type', make button red to alert
                +      // user.
                +      if (blockType == 'block_type') {
                +        buttonFormatClass = 'button_alert';
                +      }
                +      goog.dom.classlist.add(this.saveButton, buttonFormatClass);
                +      this.saveButton.disabled = false;
                +
                +    } else {
                +      // No changes to save.
                +      var classesToRemove = ['button_alert', 'button_warn'];
                +      goog.dom.classlist.removeAll(this.saveButton, classesToRemove);
                +      this.saveButton.disabled = true;
                +    }
                +
                +  }
                +};
                +
                +/**
                + * Removes option currently selected in dropdown from dropdown menu.
                + */
                +BlockLibraryView.prototype.removeSelectedOption = function() {
                +  var selectedOption = this.getSelectedOption();
                +  this.dropdown.removeNode(selectedOption);
                +};
                +
                +/**
                + * Returns block type of selected block.
                + * @return {string} Type of block selected.
                + */
                +BlockLibraryView.prototype.getSelectedBlockType = function() {
                +  var selectedOption = this.getSelectedOption();
                +  var blockType = selectedOption.textContent;
                +  return blockType;
                +};
                +
                +/**
                + * Returns selected option.
                + * @return {!Element} HTML 'a' element that is the option for a block type.
                + */
                +BlockLibraryView.prototype.getSelectedOption = function() {
                +  return this.dropdown.getElementsByClassName('dropdown-content-selected')[0];
                +};
                +
                +/**
                + * Removes all options from dropdown.
                + */
                +BlockLibraryView.prototype.clearOptions = function() {
                +  var blockOpts = this.dropdown.getElementsByClassName('blockLibOpt');
                +  var option;
                +  while ((option = blockOpts[0])) {
                +    option.parentNode.removeChild(option);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/block_option.js b/blockly/webif/static/blockly/demos/blockfactory/block_option.js
                new file mode 100644
                index 000000000..8bc1a2fd4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/block_option.js
                @@ -0,0 +1,176 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Javascript for the BlockOption class, used to represent each of
                + * the various blocks that you may select. Each block option has a checkbox,
                + * a label, and a preview workspace through which to view the block.
                + *
                + * @author quachtina96 (Tina Quach)
                + */
                +'use strict';
                +
                +goog.provide('BlockOption');
                +goog.require('goog.dom');
                +
                +
                + /**
                + * BlockOption Class
                + * A block option includes checkbox, label, and div element that shows a preview
                + * of the block.
                + * @param {!Element} blockSelector Scrollable div that will contain the
                + *    block options for the selector.
                + * @param {string} blockType Type of block for which to create an option.
                + * @param {!Element} previewBlockXml XML element containing the preview block.
                + * @constructor
                + */
                +var BlockOption = function(blockSelector, blockType, previewBlockXml) {
                +  // The div to contain the block option.
                +  this.blockSelector = blockSelector;
                +  // The type of block represented by the option.
                +  this.blockType = blockType;
                +  // The checkbox for the option. Set in createDom.
                +  this.checkbox = null;
                +  // The dom for the option. Set in createDom.
                +  this.dom = null;
                +  // Xml element containing the preview block.
                +  this.previewBlockXml = previewBlockXml;
                +  // Workspace containing preview of block. Set upon injection of workspace in
                +  // showPreviewBlock.
                +  this.previewWorkspace = null;
                +  // Whether or not block the option is selected.
                +  this.selected = false;
                +  // Using this.selected rather than this.checkbox.checked allows for proper
                +  // handling of click events on the block option; Without this, clicking
                +  // directly on the checkbox does not toggle selection.
                +};
                +
                +/**
                + * Creates the dom for a single block option. Includes checkbox, label, and div
                + * in which to inject the preview block.
                + * @return {!Element} Root node of the selector dom which consists of a
                + * checkbox, a label, and a fixed size preview workspace per block.
                + */
                +BlockOption.prototype.createDom = function() {
                +  // Create the div for the block option.
                +  var blockOptContainer = goog.dom.createDom('div', {
                +    'id': this.blockType,
                +    'class': 'blockOption'
                +  }, ''); // Empty quotes for empty div.
                +
                +  // Create and append div in which to inject the workspace for viewing the
                +  // block option.
                +  var blockOptionPreview = goog.dom.createDom('div', {
                +    'id' : this.blockType + '_workspace',
                +    'class': 'blockOption_preview'
                +  }, '');
                +  blockOptContainer.appendChild(blockOptionPreview);
                +
                +  // Create and append container to hold checkbox and label.
                +  var checkLabelContainer = goog.dom.createDom('div', {
                +    'class': 'blockOption_checkLabel'
                +  }, '');
                +  blockOptContainer.appendChild(checkLabelContainer);
                +
                +  // Create and append container for checkbox.
                +  var checkContainer = goog.dom.createDom('div', {
                +    'class': 'blockOption_check'
                +  }, '');
                +  checkLabelContainer.appendChild(checkContainer);
                +
                +  // Create and append checkbox.
                +  this.checkbox = goog.dom.createDom('input', {
                +    'type': 'checkbox',
                +    'id': this.blockType + '_check'
                +  }, '');
                +  checkContainer.appendChild(this.checkbox);
                +
                +  // Create and append container for block label.
                +  var labelContainer = goog.dom.createDom('div', {
                +    'class': 'blockOption_label'
                +  }, '');
                +  checkLabelContainer.appendChild(labelContainer);
                +
                +  // Create and append text node for the label.
                +  var labelText = goog.dom.createDom('p', {
                +    'id': this.blockType + '_text'
                +  }, this.blockType);
                +  labelContainer.appendChild(labelText);
                +
                +  this.dom = blockOptContainer;
                +  return this.dom;
                +};
                +
                +/**
                + * Injects a workspace containing the block into the block option's preview div.
                + */
                +BlockOption.prototype.showPreviewBlock = function() {
                +  // Get ID of preview workspace.
                +  var blockOptPreviewID = this.dom.id + '_workspace';
                +
                +  // Inject preview block.
                +  var workspace = Blockly.inject(blockOptPreviewID, {readOnly:true});
                +  Blockly.Xml.domToWorkspace(this.previewBlockXml, workspace);
                +  this.previewWorkspace = workspace;
                +
                +  // Center the preview block in the workspace.
                +  this.centerBlock();
                +};
                +
                +/**
                + * Centers the preview block in the workspace.
                + */
                +BlockOption.prototype.centerBlock = function() {
                +  // Get metrics.
                +  var block = this.previewWorkspace.getTopBlocks()[0];
                +  var blockMetrics = block.getHeightWidth();
                +  var blockCoordinates = block.getRelativeToSurfaceXY();
                +  var workspaceMetrics = this.previewWorkspace.getMetrics();
                +
                +  // Calculate new coordinates.
                +  var x = workspaceMetrics.viewWidth/2 - blockMetrics['width']/2 -
                +      blockCoordinates.x;
                +  var y = workspaceMetrics.viewHeight/2 - blockMetrics['height']/2 -
                +      blockCoordinates.y;
                +
                +  // Move block.
                +  block.moveBy(x, y);
                +};
                +
                +/**
                + * Selects or deselects the block option.
                + * @param {!boolean} selected True if selecting option, false if deselecting
                + *    option.
                + */
                +BlockOption.prototype.setSelected = function(selected) {
                +  this.selected = selected;
                +  if (this.checkbox) {
                +    this.checkbox.checked = selected;
                +  }
                +};
                +
                +/**
                + * Returns boolean telling whether or not block is selected.
                + * @return {!boolean} True if selecting option, false if deselecting
                + *    option.
                + */
                +BlockOption.prototype.isSelected = function() {
                +  return this.selected;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/blocks.js b/blockly/webif/static/blockly/demos/blockfactory/blocks.js
                new file mode 100644
                index 000000000..6dcd00617
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/blocks.js
                @@ -0,0 +1,905 @@
                +/**
                + * Blockly Demos: Block Factory Blocks
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Blocks for Blockly's Block Factory application.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Blocks['factory_base'] = {
                +  // Base of new block.
                +  init: function() {
                +    this.setColour(120);
                +    this.appendDummyInput()
                +        .appendField('name')
                +        .appendField(new Blockly.FieldTextInput('block_type'), 'NAME');
                +    this.appendStatementInput('INPUTS')
                +        .setCheck('Input')
                +        .appendField('inputs');
                +    var dropdown = new Blockly.FieldDropdown([
                +        ['automatic inputs', 'AUTO'],
                +        ['external inputs', 'EXT'],
                +        ['inline inputs', 'INT']]);
                +    this.appendDummyInput()
                +        .appendField(dropdown, 'INLINE');
                +    dropdown = new Blockly.FieldDropdown([
                +        ['no connections', 'NONE'],
                +        ['← left output', 'LEFT'],
                +        ['↕ top+bottom connections', 'BOTH'],
                +        ['↑ top connection', 'TOP'],
                +        ['↓ bottom connection', 'BOTTOM']],
                +        function(option) {
                +          this.sourceBlock_.updateShape_(option);
                +          // Connect a shadow block to this new input.
                +          this.sourceBlock_.spawnOutputShadow_(option);
                +        });
                +    this.appendDummyInput()
                +        .appendField(dropdown, 'CONNECTIONS');
                +    this.appendValueInput('TOOLTIP')
                +        .setCheck('String')
                +        .appendField('tooltip');
                +    this.appendValueInput('HELPURL')
                +        .setCheck('String')
                +        .appendField('help url');
                +    this.appendValueInput('COLOUR')
                +        .setCheck('Colour')
                +        .appendField('colour');
                +    this.setTooltip('Build a custom block by plugging\n' +
                +        'fields, inputs and other blocks here.');
                +    this.setHelpUrl(
                +        'https://developers.google.com/blockly/guides/create-custom-blocks/block-factory');
                +  },
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('connections', this.getFieldValue('CONNECTIONS'));
                +    return container;
                +  },
                +  domToMutation: function(xmlElement) {
                +    var connections = xmlElement.getAttribute('connections');
                +    this.updateShape_(connections);
                +  },
                +  spawnOutputShadow_: function(option) {
                +    // Helper method for deciding which type of outputs this block needs
                +    // to attach shaddow blocks to.
                +    switch (option) {
                +      case 'LEFT':
                +        this.connectOutputShadow_('OUTPUTTYPE');
                +        break;
                +      case 'TOP':
                +        this.connectOutputShadow_('TOPTYPE');
                +        break;
                +      case 'BOTTOM':
                +        this.connectOutputShadow_('BOTTOMTYPE');
                +        break;
                +      case 'BOTH':
                +        this.connectOutputShadow_('TOPTYPE');
                +        this.connectOutputShadow_('BOTTOMTYPE');
                +        break;
                +    }
                +  },
                +  connectOutputShadow_: function(outputType) {
                +    // Helper method to create & connect shadow block.
                +    var type = this.workspace.newBlock('type_null');
                +    type.setShadow(true);
                +    type.outputConnection.connect(this.getInput(outputType).connection);
                +    type.initSvg();
                +    type.render();
                +  },
                +  updateShape_: function(option) {
                +    var outputExists = this.getInput('OUTPUTTYPE');
                +    var topExists = this.getInput('TOPTYPE');
                +    var bottomExists = this.getInput('BOTTOMTYPE');
                +    if (option == 'LEFT') {
                +      if (!outputExists) {
                +        this.addTypeInput_('OUTPUTTYPE', 'output type');
                +      }
                +    } else if (outputExists) {
                +      this.removeInput('OUTPUTTYPE');
                +    }
                +    if (option == 'TOP' || option == 'BOTH') {
                +      if (!topExists) {
                +        this.addTypeInput_('TOPTYPE', 'top type');
                +      }
                +    } else if (topExists) {
                +      this.removeInput('TOPTYPE');
                +    }
                +    if (option == 'BOTTOM' || option == 'BOTH') {
                +      if (!bottomExists) {
                +        this.addTypeInput_('BOTTOMTYPE', 'bottom type');
                +      }
                +    } else if (bottomExists) {
                +      this.removeInput('BOTTOMTYPE');
                +    }
                +  },
                +  addTypeInput_: function(name, label) {
                +    this.appendValueInput(name)
                +        .setCheck('Type')
                +        .appendField(label);
                +    this.moveInputBefore(name, 'COLOUR');
                +  }
                +};
                +
                +var FIELD_MESSAGE = 'fields %1 %2';
                +var FIELD_ARGS = [
                +  {
                +    "type": "field_dropdown",
                +    "name": "ALIGN",
                +    "options": [['left', 'LEFT'], ['right', 'RIGHT'], ['centre', 'CENTRE']],
                +  },
                +  {
                +    "type": "input_statement",
                +    "name": "FIELDS",
                +    "check": "Field"
                +  }
                +];
                +
                +var TYPE_MESSAGE = 'type %1';
                +var TYPE_ARGS = [
                +  {
                +    "type": "input_value",
                +    "name": "TYPE",
                +    "check": "Type",
                +    "align": "RIGHT"
                +  }
                +];
                +
                +Blockly.Blocks['input_value'] = {
                +  // Value input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "value input %1 %2",
                +      "args0": [
                +        {
                +          "type": "field_input",
                +          "name": "INPUTNAME",
                +          "text": "NAME"
                +        },
                +        {
                +          "type": "input_dummy"
                +        }
                +      ],
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "message2": TYPE_MESSAGE,
                +      "args2": TYPE_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "A value socket for horizontal connections.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=71"
                +    });
                +  },
                +  onchange: function() {
                +    inputNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['input_statement'] = {
                +  // Statement input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "statement input %1 %2",
                +      "args0": [
                +        {
                +          "type": "field_input",
                +          "name": "INPUTNAME",
                +          "text": "NAME"
                +        },
                +        {
                +          "type": "input_dummy"
                +        },
                +      ],
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "message2": TYPE_MESSAGE,
                +      "args2": TYPE_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "A statement socket for enclosed vertical stacks.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=246"
                +    });
                +  },
                +  onchange: function() {
                +    inputNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['input_dummy'] = {
                +  // Dummy input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "dummy input",
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "For adding fields on a separate row with no " +
                +                 "connections. Alignment options (left, right, centre) " +
                +                 "apply only to multi-line fields.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=293"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['field_static'] = {
                +  // Text value.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('text')
                +        .appendField(new Blockly.FieldTextInput(''), 'TEXT');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Static text that serves as a label.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=88');
                +  }
                +};
                +
                +Blockly.Blocks['field_input'] = {
                +  // Text input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('text input')
                +        .appendField(new Blockly.FieldTextInput('default'), 'TEXT')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter text.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=319');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_number'] = {
                +  // Numeric input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('numeric input')
                +        .appendField(new Blockly.FieldNumber(0), 'VALUE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.appendDummyInput()
                +        .appendField('min')
                +        .appendField(new Blockly.FieldNumber(-Infinity), 'MIN')
                +        .appendField('max')
                +        .appendField(new Blockly.FieldNumber(Infinity), 'MAX')
                +        .appendField('precision')
                +        .appendField(new Blockly.FieldNumber(0, 0), 'PRECISION');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter a number.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=319');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_angle'] = {
                +  // Angle input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('angle input')
                +        .appendField(new Blockly.FieldAngle('90'), 'ANGLE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter an angle.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=372');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown'] = {
                +  // Dropdown menu.
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField('dropdown')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.optionList_ = ['text', 'text', 'text'];
                +    this.updateShape_();
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setMutator(new Blockly.Mutator(['field_dropdown_option_text',
                +                                         'field_dropdown_option_image']));
                +    this.setColour(160);
                +    this.setTooltip('Dropdown menu with a list of options.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +  },
                +  mutationToDom: function(workspace) {
                +    // Create XML to represent menu options.
                +    var container = document.createElement('mutation');
                +    container.setAttribute('options', JSON.stringify(this.optionList_));
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    // Parse XML to restore the menu options.
                +    var value = JSON.parse(container.getAttribute('options'));
                +    if (typeof value == 'number') {
                +      // Old format from before images were added.  November 2016.
                +      this.optionList_ = [];
                +      for (var i = 0; i < value; i++) {
                +        this.optionList_.push('text');
                +      }
                +    } else {
                +      this.optionList_ = value;
                +    }
                +    this.updateShape_();
                +  },
                +  decompose: function(workspace) {
                +    // Populate the mutator's dialog with this block's components.
                +    var containerBlock = workspace.newBlock('field_dropdown_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.optionList_.length; i++) {
                +      var optionBlock = workspace.newBlock(
                +          'field_dropdown_option_' + this.optionList_[i]);
                +      optionBlock.initSvg();
                +      connection.connect(optionBlock.previousConnection);
                +      connection = optionBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  compose: function(containerBlock) {
                +    // Reconfigure this block based on the mutator dialog's components.
                +    var optionBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    this.optionList_.length = 0;
                +    var data = [];
                +    while (optionBlock) {
                +      if (optionBlock.type == 'field_dropdown_option_text') {
                +        this.optionList_.push('text');
                +      } else if (optionBlock.type == 'field_dropdown_option_image') {
                +        this.optionList_.push('image');
                +      }
                +      data.push([optionBlock.userData_, optionBlock.cpuData_]);
                +      optionBlock = optionBlock.nextConnection &&
                +          optionBlock.nextConnection.targetBlock();
                +    }
                +    this.updateShape_();
                +    // Restore any data.
                +    for (var i = 0; i < this.optionList_.length; i++) {
                +      var userData = data[i][0];
                +      if (userData !== undefined) {
                +        if (typeof userData == 'string') {
                +          this.setFieldValue(userData || 'option', 'USER' + i);
                +        } else {
                +          this.setFieldValue(userData.src, 'SRC' + i);
                +          this.setFieldValue(userData.width, 'WIDTH' + i);
                +          this.setFieldValue(userData.height, 'HEIGHT' + i);
                +          this.setFieldValue(userData.alt, 'ALT' + i);
                +        }
                +        this.setFieldValue(data[i][1] || 'OPTIONNAME', 'CPU' + i);
                +      }
                +    }
                +  },
                +  saveConnections: function(containerBlock) {
                +    // Store all data for each option.
                +    var optionBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (optionBlock) {
                +      optionBlock.userData_ = this.getUserData(i);
                +      optionBlock.cpuData_ = this.getFieldValue('CPU' + i);
                +      i++;
                +      optionBlock = optionBlock.nextConnection &&
                +          optionBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  updateShape_: function() {
                +    // Delete everything.
                +    var i = 0;
                +    while (this.getInput('OPTION' + i)) {
                +      this.removeInput('OPTION' + i);
                +      this.removeInput('OPTION_IMAGE' + i, true);
                +      i++;
                +    }
                +    // Rebuild block.
                +    var src = 'https://www.gstatic.com/codesite/ph/images/star_on.gif';
                +    for (var i = 0; i <= this.optionList_.length; i++) {
                +      var type = this.optionList_[i];
                +      if (type == 'text') {
                +        this.appendDummyInput('OPTION' + i)
                +            .appendField('•')
                +            .appendField(new Blockly.FieldTextInput('option'), 'USER' + i)
                +            .appendField(',')
                +            .appendField(new Blockly.FieldTextInput('OPTIONNAME'), 'CPU' + i);
                +      } else if (type == 'image') {
                +        this.appendDummyInput('OPTION' + i)
                +            .appendField('•')
                +            .appendField('image')
                +            .appendField(new Blockly.FieldTextInput(src), 'SRC' + i);
                +        this.appendDummyInput('OPTION_IMAGE' + i)
                +            .appendField(' ')
                +            .appendField('width')
                +            .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'WIDTH' + i)
                +            .appendField('height')
                +            .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'HEIGHT' + i)
                +            .appendField('alt text')
                +            .appendField(new Blockly.FieldTextInput('*'), 'ALT' + i)
                +            .appendField(',')
                +            .appendField(new Blockly.FieldTextInput('OPTIONNAME'), 'CPU' + i);
                +      }
                +    }
                +  },
                +  onchange: function() {
                +    if (this.workspace && this.optionList_.length < 1) {
                +      this.setWarningText('Drop down menu must\nhave at least one option.');
                +    } else {
                +      fieldNameCheck(this);
                +    }
                +  },
                +  getUserData: function(n) {
                +    if (this.optionList_[n] == 'text') {
                +      return this.getFieldValue('USER' + n);
                +    }
                +    if (this.optionList_[n] == 'image') {
                +      return {
                +        src: this.getFieldValue('SRC' + n),
                +        width: Number(this.getFieldValue('WIDTH' + n)),
                +        height: Number(this.getFieldValue('HEIGHT' + n)),
                +        alt: this.getFieldValue('ALT' + n)
                +      };
                +    }
                +    throw 'Unknown dropdown type';
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown_container'] = {
                +  // Container.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('add options');
                +    this.appendStatementInput('STACK');
                +    this.setTooltip('Add, remove, or reorder options\n' +
                +                    'to reconfigure this dropdown menu.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown_option_text'] = {
                +  // Add text option.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('text option');
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Add a new text option to the dropdown menu.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown_option_image'] = {
                +  // Add image option.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('image option');
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Add a new image option to the dropdown menu.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['field_checkbox'] = {
                +  // Checkbox.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('checkbox')
                +        .appendField(new Blockly.FieldCheckbox('TRUE'), 'CHECKED')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Checkbox field.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=485');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_colour'] = {
                +  // Colour input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('colour')
                +        .appendField(new Blockly.FieldColour('#ff0000'), 'COLOUR')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Colour input field.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=495');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_date'] = {
                +  // Date input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('date')
                +        .appendField(new Blockly.FieldDate(), 'DATE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Date input field.');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_variable'] = {
                +  // Dropdown for variables.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('variable')
                +        .appendField(new Blockly.FieldTextInput('item'), 'TEXT')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Dropdown menu for variable names.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=510');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_image'] = {
                +  // Image.
                +  init: function() {
                +    this.setColour(160);
                +    var src = 'https://www.gstatic.com/codesite/ph/images/star_on.gif';
                +    this.appendDummyInput()
                +        .appendField('image')
                +        .appendField(new Blockly.FieldTextInput(src), 'SRC');
                +    this.appendDummyInput()
                +        .appendField('width')
                +        .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'WIDTH')
                +        .appendField('height')
                +        .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'HEIGHT')
                +        .appendField('alt text')
                +        .appendField(new Blockly.FieldTextInput('*'), 'ALT');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Static image (JPEG, PNG, GIF, SVG, BMP).\n' +
                +                    'Retains aspect ratio regardless of height and width.\n' +
                +                    'Alt text is for when collapsed.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=567');
                +  }
                +};
                +
                +Blockly.Blocks['type_group'] = {
                +  // Group of types.
                +  init: function() {
                +    this.typeCount_ = 2;
                +    this.updateShape_();
                +    this.setOutput(true, 'Type');
                +    this.setMutator(new Blockly.Mutator(['type_group_item']));
                +    this.setColour(230);
                +    this.setTooltip('Allows more than one type to be accepted.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677');
                +  },
                +  mutationToDom: function(workspace) {
                +    // Create XML to represent a group of types.
                +    var container = document.createElement('mutation');
                +    container.setAttribute('types', this.typeCount_);
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    // Parse XML to restore the group of types.
                +    this.typeCount_ = parseInt(container.getAttribute('types'), 10);
                +    this.updateShape_();
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      this.removeInput('TYPE' + i);
                +    }
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var input = this.appendValueInput('TYPE' + i)
                +                      .setCheck('Type');
                +      if (i == 0) {
                +        input.appendField('any of');
                +      }
                +    }
                +  },
                +  decompose: function(workspace) {
                +    // Populate the mutator's dialog with this block's components.
                +    var containerBlock = workspace.newBlock('type_group_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var typeBlock = workspace.newBlock('type_group_item');
                +      typeBlock.initSvg();
                +      connection.connect(typeBlock.previousConnection);
                +      connection = typeBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  compose: function(containerBlock) {
                +    // Reconfigure this block based on the mutator dialog's components.
                +    var typeBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    var connections = [];
                +    while (typeBlock) {
                +      connections.push(typeBlock.valueConnection_);
                +      typeBlock = typeBlock.nextConnection &&
                +          typeBlock.nextConnection.targetBlock();
                +    }
                +    // Disconnect any children that don't belong.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var connection = this.getInput('TYPE' + i).connection.targetConnection;
                +      if (connection && connections.indexOf(connection) == -1) {
                +        connection.disconnect();
                +      }
                +    }
                +    this.typeCount_ = connections.length;
                +    this.updateShape_();
                +    // Reconnect any child blocks.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      Blockly.Mutator.reconnect(connections[i], this, 'TYPE' + i);
                +    }
                +  },
                +  saveConnections: function(containerBlock) {
                +    // Store a pointer to any connected child blocks.
                +    var typeBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (typeBlock) {
                +      var input = this.getInput('TYPE' + i);
                +      typeBlock.valueConnection_ = input && input.connection.targetConnection;
                +      i++;
                +      typeBlock = typeBlock.nextConnection &&
                +          typeBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  updateShape_: function() {
                +    // Modify this block to have the correct number of inputs.
                +    // Add new inputs.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      if (!this.getInput('TYPE' + i)) {
                +        var input = this.appendValueInput('TYPE' + i);
                +        if (i == 0) {
                +          input.appendField('any of');
                +        }
                +      }
                +    }
                +    // Remove deleted inputs.
                +    while (this.getInput('TYPE' + i)) {
                +      this.removeInput('TYPE' + i);
                +      i++;
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['type_group_container'] = {
                +  // Container.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "add types %1 %2",
                +      "args0": [
                +        {"type": "input_dummy"},
                +        {"type": "input_statement", "name": "STACK"}
                +      ],
                +      "colour": 230,
                +      "tooltip": "Add, or remove allowed type.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_group_item'] = {
                +  // Add type.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "type",
                +      "previousStatement": null,
                +      "nextStatement": null,
                +      "colour": 230,
                +      "tooltip": "Add a new allowed type.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_null'] = {
                +  // Null type.
                +  valueType: null,
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "any",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Any type is allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_boolean'] = {
                +  // Boolean type.
                +  valueType: 'Boolean',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Boolean",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Booleans (true/false) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_number'] = {
                +  // Number type.
                +  valueType: 'Number',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Number",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Numbers (int/float) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_string'] = {
                +  // String type.
                +  valueType: 'String',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "String",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Strings (text) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_list'] = {
                +  // List type.
                +  valueType: 'Array',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Array",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Arrays (lists) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_other'] = {
                +  // Other type.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "other %1",
                +      "args0": [{"type": "field_input", "name": "TYPE", "text": ""}],
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Custom type to allow.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=702"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['colour_hue'] = {
                +  // Set the colour of the block.
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField('hue:')
                +        .appendField(new Blockly.FieldAngle('0', this.validator), 'HUE');
                +    this.setOutput(true, 'Colour');
                +    this.setTooltip('Paint the block with this colour.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=55');
                +  },
                +  validator: function(text) {
                +    // Update the current block's colour to match.
                +    var hue = parseInt(text, 10);
                +    if (!isNaN(hue)) {
                +      this.sourceBlock_.setColour(hue);
                +    }
                +  },
                +  mutationToDom: function(workspace) {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('colour', this.getColour());
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    this.setColour(container.getAttribute('colour'));
                +  }
                +};
                +
                +/**
                + * Check to see if more than one field has this name.
                + * Highly inefficient (On^2), but n is small.
                + * @param {!Blockly.Block} referenceBlock Block to check.
                + */
                +function fieldNameCheck(referenceBlock) {
                +  if (!referenceBlock.workspace) {
                +    // Block has been deleted.
                +    return;
                +  }
                +  var name = referenceBlock.getFieldValue('FIELDNAME').toLowerCase();
                +  var count = 0;
                +  var blocks = referenceBlock.workspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var otherName = block.getFieldValue('FIELDNAME');
                +    if (!block.disabled && !block.getInheritedDisabled() &&
                +        otherName && otherName.toLowerCase() == name) {
                +      count++;
                +    }
                +  }
                +  var msg = (count > 1) ?
                +      'There are ' + count + ' field blocks\n with this name.' : null;
                +  referenceBlock.setWarningText(msg);
                +}
                +
                +/**
                + * Check to see if more than one input has this name.
                + * Highly inefficient (On^2), but n is small.
                + * @param {!Blockly.Block} referenceBlock Block to check.
                + */
                +function inputNameCheck(referenceBlock) {
                +  if (!referenceBlock.workspace) {
                +    // Block has been deleted.
                +    return;
                +  }
                +  var name = referenceBlock.getFieldValue('INPUTNAME').toLowerCase();
                +  var count = 0;
                +  var blocks = referenceBlock.workspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var otherName = block.getFieldValue('INPUTNAME');
                +    if (!block.disabled && !block.getInheritedDisabled() &&
                +        otherName && otherName.toLowerCase() == name) {
                +      count++;
                +    }
                +  }
                +  var msg = (count > 1) ?
                +      'There are ' + count + ' input blocks\n with this name.' : null;
                +  referenceBlock.setWarningText(msg);
                +}
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/factory.css b/blockly/webif/static/blockly/demos/blockfactory/factory.css
                new file mode 100644
                index 000000000..6661c139c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/factory.css
                @@ -0,0 +1,609 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +html, body {
                +  height: 100%;
                +  min-height: 375px;
                +}
                +
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  margin: 0 5px;
                +  overflow: hidden;
                +}
                +
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +
                +h3 {
                +  margin-top: 5px;
                +  margin-bottom: 0;
                +}
                +
                +table {
                +  border: none;
                +  border-collapse: collapse;
                +  height: 100%;
                +  margin: 0;
                +  padding: 0;
                +  width: 100%;
                +}
                +
                +td {
                +  vertical-align: top;
                +  padding: 0;
                +}
                +
                +p {
                +  display: block;
                +  -webkit-margin-before: 0em;
                +  -webkit-margin-after: 0em;
                +  -webkit-margin-start: 0px;
                +  -webkit-margin-end: 0px;
                +  padding: 5px 0px;
                +}
                +
                +#factoryHeader {
                +  display: table;
                +  height: 10%;
                +}
                +
                +#blockly {
                +  position: absolute;
                +}
                +
                +#blocklyMask {
                +  background-color: #000;
                +  cursor: not-allowed;
                +  display: none;
                +  position: fixed;
                +  opacity: 0.2;
                +  z-index: 9;
                +}
                +
                +#preview {
                +  position: absolute;
                +}
                +
                +pre,
                +#languageTA {
                +  border: #ddd 1px solid;
                +  margin-top: 0;
                +  position: absolute;
                +  overflow: scroll;
                +}
                +
                +#languageTA {
                +  display: none;
                +  font: 10pt monospace;
                +}
                +
                +.downloadButton {
                +  padding: 5px;
                +}
                +
                +.disabled {
                +  color: #888;
                +}
                +
                +button:disabled, .buttonStyle:disabled {
                +  opacity: 0.6;
                +}
                +
                +button>*, .buttonStyle>* {
                +  opacity: 1;
                +  vertical-align: text-bottom;
                +}
                +
                +button, .buttonStyle {
                +  border-radius: 4px;
                +  border: 1px solid #ddd;
                +  background-color: #eee;
                +  color: #000;
                +  padding: 10px;
                +  margin: 10px 5px;
                +  font-size: small;
                +}
                +
                +.buttonStyle:hover:not(:disabled), button:hover:not(:disabled) {
                +  box-shadow: 2px 2px 5px #888;
                +}
                +
                +.buttonStyle:hover:not(:disabled)>*, button:hover:not(:disabled)>* {
                +  opacity: 1;
                +}
                +
                +#linkButton {
                +  display: none;
                +}
                +
                +#helpButton {
                +  float: right;
                +}
                +
                +#blockFactoryContent {
                +  height: 85%;
                +  width: 100%;
                +  overflow: hidden;
                +}
                +
                +#blockFactoryPreview {
                +  height: 100%;
                +  width: 100%;
                +}
                +
                +#blockLibraryContainer {
                +  vertical-align: bottom;
                +}
                +
                +#blockLibraryControls {
                +  text-align: right;
                +  vertical-align: middle;
                +}
                +
                +#previewContainer {
                +  vertical-align: bottom;
                +}
                +
                +#buttonContainer {
                +  text-align: right;
                +  vertical-align: middle;
                +}
                +
                +#files {
                +  position: absolute;
                +  visibility: hidden;
                +}
                +
                +.toolbox {
                +  display: none;
                +}
                +
                +#blocklyWorkspaceContainer {
                +  width: 50%;
                +}
                +
                +#workspaceFactoryContent {
                +  clear: both;
                +  display: none;
                +  height: 90%;
                +  overflow-x: hidden;
                +  overflow-y: scroll;
                +}
                +
                +/* Exporter */
                +
                +#blockLibraryExporter {
                +  clear: both;
                +  display: none;
                +  height: 90%;
                +  overflow-x: hidden;
                +  overflow-y: scroll;
                +}
                +
                +#exportSelector {
                +  display: inline-block;
                +  float: left;
                +  height: 70%;
                +  width: 30%;
                +}
                +
                +#exportSettings {
                +  float: left;
                +  overflow: hidden;
                +  padding-left: 16px;
                +  width: 20%;
                +}
                +
                +#selectedBlocksTextContainer {
                +  max-height: 200px;
                +  overflow-y: scroll;
                +  padding-bottom: 2em;
                +}
                +
                +::-webkit-scrollbar {
                +  -webkit-appearance: none;
                +  width: 7px;
                +}
                +
                +::-webkit-scrollbar-thumb {
                +  border-radius: 4px;
                +  background-color: #ccc;
                +  -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
                +}
                +
                +.subsettings {
                +  margin: 0px 25px;
                +}
                +
                +#exporterHiddenWorkspace {
                + display: none;
                +}
                +
                +#exportPreview {
                +  float: right;
                +  height: 90%;
                +  overflow: hidden;
                +  width: 45%;
                +}
                +
                +.exportPreviewTextArea {
                +  display: block;
                +  float: right;
                +  height: 40%;
                +  width: 100%;
                +}
                +
                +#genStubs_textArea, #blockDefs_textArea {
                +  display: block;
                +  height: 80%;
                +  margin-right: 20px;
                +  max-height: 300px;
                +  overflow: scroll;
                +  position: static;
                +}
                +
                +#blockDefs_label, #genStubs_label {
                +  display: block;
                +}
                +
                +#blockSelector {
                +  background-color: #eee;
                +  border: 1px solid lightgrey;
                +  width: 80%;
                +  height: 90%;
                +  overflow-y: scroll;
                +  position: relative;
                +}
                +
                +/* Exporter Block Option */
                +
                +.blockOption {
                +  background-color: #eee;
                +  padding: 0px 20px;
                +  width: 95%;
                +}
                +
                +.blockOption_check_label {
                +  position: relative;
                +}
                +
                +.blockOption_check {
                +  float: left;
                +  display:inline;
                +  padding: 4px;
                +}
                +
                +.blockOption_label {
                +  display:inline;
                +  max-width: inherit;
                +  word-wrap: break-word;
                +}
                +
                +.blockOption_preview {
                +  height: 100px;
                +  padding-top: 10px;
                +  width: 90%;
                +}
                +
                +/* Block Library */
                +
                +#dropdownDiv_blockLib {
                +  max-height: 65%;
                +  overflow-y: scroll;
                +}
                +
                +#button_blockLib {
                +  border-color: darkgrey;
                +  font-size: large;
                +}
                +
                +.button_alert {
                +  background-color: #fcc;
                +  border-color: #f99;
                +}
                +
                +.button_warn {
                +  background-color: #aea;
                +  border-color: #5d5;
                +}
                +
                +/* Tabs */
                +
                +.tab {
                +  float: left;
                +  padding: 5px 19px;
                +}
                +
                +.tab:hover:not(.tabon){
                +  background-color: #e8e8e8;
                +}
                +
                +.tab.tabon {
                +  background-color: #ccc;
                +}
                +
                +.tab.taboff {
                +  cursor: pointer;
                +}
                +
                +#tabContainer {
                +  background-color: #f8f8f8;
                +  border-top: 1px solid #ddd;
                +  border-bottom: 1px solid #ddd;
                +  display: table;
                +  width: 100%;
                +}
                +
                +/* Workspace Factory */
                +
                +section {
                +  float: left;
                +}
                +
                +aside {
                +  float: right;
                +}
                +
                +#categoryTable>table {
                +  border: 1px solid #ccc;
                +  border-bottom: none;
                +  width: auto;
                +}
                +
                +td.tabon {
                +  background-color: #ccc;
                +  border-bottom-color: #ccc;
                +  padding: 5px 19px;
                +}
                +
                +td.taboff {
                +  cursor: pointer;
                +  padding: 5px 19px;
                +}
                +
                +td.taboff:hover {
                +  background-color: #eee;
                +}
                +
                +.large {
                +  font-size: large;
                +}
                +
                +.inputfile {
                +  height: 0;
                +  opacity: 0;
                +  overflow: hidden;
                +  position: absolute;
                +  width: 0;
                +  z-index: -1;
                +}
                +#wfactoryHeader {
                +  height: 29%;
                +  padding: 0.5%;
                +}
                +
                +#workspaceTabs {
                +  background-color: #f8f8f8;
                +  border: 1px solid #ccc;
                +  display: table;
                +  width: auto;
                +}
                +
                +#toolbox_section {
                +  height: 85%;
                +  width: 60%;
                +}
                +
                +#previewHelp {
                +  padding: 10px;
                +  width: 98%;
                +}
                +
                +#toolbox_blocks {
                +  height: 100%;
                +  width: 100%;
                +}
                +
                +#preview_blocks {
                +  height: 80%;
                +  padding: 10px;
                +  width: 100%;
                +}
                +
                +#createDiv {
                +  height: 79%;
                +  padding: 0.5%;
                +  width: 60%;
                +}
                +
                +#previewDiv {
                +  border: 10px solid #eee;
                +  height: 77%;
                +  margin-right: 0.5%;
                +  padding-bottom: 10px;
                +  width: 35%;
                +}
                +
                +#previewBorder {
                +  border: 5px solid #ddd;
                +  height: 100%;
                +  padding-right: 20px;
                +}
                +
                +.disabled {
                +  background-color: white;
                +  opacity: 0.5;
                +}
                +
                +#toolbox_div {
                +  display: table;
                +  height: auto;
                +  margin-right: 5%;
                +  overflow: hidden;
                +  width: 35%;
                +}
                +
                +#preload_div {
                +  display: table;
                +  height: 75%;
                +  margin-left: 2%;
                +  margin-right: 2%;
                +  max-height: 500px;
                +  overflow: hidden;
                +  overflow-y: scroll;
                +  width: 30%;
                +}
                +
                +#shadowBlockDropdown {
                +  height: 15%;
                +}
                +
                +#preloadHelp {
                +  display: table-row;
                +  height: 30%;
                +}
                +
                +#workspace_options {
                +  display: table-row;
                +  margin-top: 2%;
                +}
                +
                +#disable_div {
                +  background-color: white;
                +  height: 100%;
                +  left: 0;
                +  opacity: .5;
                +  position: absolute;
                +  top: 0;
                +  width: 100%;
                +  z-index: -1;  /* Start behind workspace */
                +}
                +
                +#grid_options, #zoom_options, #maxBlockNumber_option {
                +  padding-left: 15px;
                +}
                +
                +#modalShadow {
                +  display: none;
                +  position: fixed;
                +  top: 0;
                +  right: 0;
                +  bottom: 0;
                +  left: 0;
                +  background: rgba(0, 0, 0, 0.05);
                +  z-index: 100;
                +}
                +
                +/* Rules for Closure popup color picker */
                +.goog-palette {
                +  outline: none;
                +  cursor: default;
                +}
                +
                +.goog-palette-cell {
                +  height: 13px;
                +  width: 15px;
                +  margin: 0;
                +  border: 0;
                +  text-align: center;
                +  vertical-align: middle;
                +  border-right: 1px solid #000;
                +  font-size: 1px;
                +}
                +
                +.goog-palette-colorswatch {
                +  border: 1px solid #000;
                +  height: 13px;
                +  position: relative;
                +  width: 15px;
                +}
                +
                +.goog-palette-cell-hover .goog-palette-colorswatch {
                +  border: 1px solid #fff;
                +}
                +
                +.goog-palette-cell-selected .goog-palette-colorswatch {
                +  border: 1px solid #000;
                +  color: #fff;
                +}
                +
                +.goog-palette-table {
                +  border: 1px solid #000;
                +  border-collapse: collapse;
                +}
                +
                +.goog-popupcolorpicker {
                +  position: absolute;
                +  z-index: 101;  /* On top of the modal Shadow. */
                +}
                +
                +/* The container <div> - needed to position the dropdown content */
                +.dropdown {
                +  display: inline-block;
                +}
                +
                +/* Dropdown Content (Hidden by Default) */
                +.dropdown-content {
                +  background-color: #fff;
                +  box-shadow: 0px 8px 16px 0px rgba(0,0,0,.2);
                +  display: none;
                +  min-width: 170px;
                +  opacity: 1;
                +  position: absolute;
                +  z-index: 101;  /* On top of the modal Shadow. */
                +}
                +
                +/* Links inside the dropdown */
                +.dropdown-content a, .dropdown-content label {
                +  color: black;
                +  display: block;
                +  font-size: small;
                +  padding: 12px 16px;
                +  text-decoration: none;
                +}
                +
                +/* Change color  of dropdown links on hover. */
                +.dropdown-content a:hover, .dropdown-content label:hover {
                +  background-color: #EEE;
                +}
                +
                +/* Change color of dropdown links on selected. */
                +.dropdown-content-selected {
                +  background-color: #DDD;
                +}
                +
                +/* Show the dropdown menu */
                +.show {
                +  display: block;
                +}
                +
                +.shadowBlock>.blocklyPath {
                +  fill-opacity: .5;
                +  stroke-opacity: .5;
                +}
                +
                +.shadowBlock>.blocklyPathLight,
                +.shadowBlock>.blocklyPathDark {
                +  display: none;
                +}
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/factory.js b/blockly/webif/static/blockly/demos/blockfactory/factory.js
                new file mode 100644
                index 000000000..974cd8a7e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/factory.js
                @@ -0,0 +1,276 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview JavaScript for Blockly's Block Factory application through
                + * which users can build blocks using a visual interface and dynamically
                + * generate a preview block and starter code for the block (block definition and
                + * generator stub. Uses the Block Factory namespace. Depends on the FactoryUtils
                + * for its code generation functions.
                + *
                + * @author fraser@google.com (Neil Fraser), quachtina96 (Tina Quach)
                + */
                +'use strict';
                +
                +/**
                + * Namespace for Block Factory.
                + */
                +goog.provide('BlockFactory');
                +
                +goog.require('FactoryUtils');
                +goog.require('StandardCategories');
                +
                +
                +/**
                + * Workspace for user to build block.
                + * @type {Blockly.Workspace}
                + */
                +BlockFactory.mainWorkspace = null;
                +
                +/**
                + * Workspace for preview of block.
                + * @type {Blockly.Workspace}
                + */
                +BlockFactory.previewWorkspace = null;
                +
                +/**
                + * Name of block if not named.
                + */
                +BlockFactory.UNNAMED = 'unnamed';
                +
                +/**
                + * Existing direction ('ltr' vs 'rtl') of preview.
                + */
                +BlockFactory.oldDir = null;
                +
                +/*
                + * The starting XML for the Block Factory main workspace. Contains the
                + * unmovable, undeletable factory_base block.
                + */
                +BlockFactory.STARTER_BLOCK_XML_TEXT = '<xml><block type="factory_base" ' +
                +    'deletable="false" movable="false">' +
                +    '<value name="TOOLTIP">' +
                +    '<block type="text" deletable="false" movable="false">' +
                +    '<field name="TEXT"></field></block></value>' +
                +    '<value name="HELPURL">' +
                +    '<block type="text" deletable="false" movable="false">' +
                +    '<field name="TEXT"></field></block></value>' +
                +    '<value name="COLOUR">' +
                +    '<block type="colour_hue">' +
                +    '<mutation colour="#5b67a5"></mutation>' +
                +    '<field name="HUE">230</field>' +
                +    '</block></value></block></xml>';
                +
                +/**
                + * Change the language code format.
                + */
                +BlockFactory.formatChange = function() {
                +  var mask = document.getElementById('blocklyMask');
                +  var languagePre = document.getElementById('languagePre');
                +  var languageTA = document.getElementById('languageTA');
                +  if (document.getElementById('format').value == 'Manual') {
                +    Blockly.hideChaff();
                +    mask.style.display = 'block';
                +    languagePre.style.display = 'none';
                +    languageTA.style.display = 'block';
                +    var code = languagePre.textContent.trim();
                +    languageTA.value = code;
                +    languageTA.focus();
                +    BlockFactory.updatePreview();
                +  } else {
                +    mask.style.display = 'none';
                +    languageTA.style.display = 'none';
                +    languagePre.style.display = 'block';
                +    BlockFactory.updateLanguage();
                +  }
                +  BlockFactory.disableEnableLink();
                +};
                +
                +/**
                + * Update the language code based on constructs made in Blockly.
                + */
                +BlockFactory.updateLanguage = function() {
                +  var rootBlock = FactoryUtils.getRootBlock(BlockFactory.mainWorkspace);
                +  if (!rootBlock) {
                +    return;
                +  }
                +  var blockType = rootBlock.getFieldValue('NAME').trim().toLowerCase();
                +  if (!blockType) {
                +    blockType = BlockFactory.UNNAMED;
                +  }
                +  var format = document.getElementById('format').value;
                +  var code = FactoryUtils.getBlockDefinition(blockType, rootBlock, format,
                +      BlockFactory.mainWorkspace);
                +  FactoryUtils.injectCode(code, 'languagePre');
                +  BlockFactory.updatePreview();
                +};
                +
                +/**
                + * Update the generator code.
                + * @param {!Blockly.Block} block Rendered block in preview workspace.
                + */
                +BlockFactory.updateGenerator = function(block) {
                +  var language = document.getElementById('language').value;
                +  var generatorStub = FactoryUtils.getGeneratorStub(block, language);
                +  FactoryUtils.injectCode(generatorStub, 'generatorPre');
                +};
                +
                +/**
                + * Update the preview display.
                + */
                +BlockFactory.updatePreview = function() {
                +  // Toggle between LTR/RTL if needed (also used in first display).
                +  var newDir = document.getElementById('direction').value;
                +  if (BlockFactory.oldDir != newDir) {
                +    if (BlockFactory.previewWorkspace) {
                +      BlockFactory.previewWorkspace.dispose();
                +    }
                +    var rtl = newDir == 'rtl';
                +    BlockFactory.previewWorkspace = Blockly.inject('preview',
                +        {rtl: rtl,
                +         media: '../../media/',
                +         scrollbars: true});
                +    BlockFactory.oldDir = newDir;
                +  }
                +  BlockFactory.previewWorkspace.clear();
                +
                +  // Fetch the code and determine its format (JSON or JavaScript).
                +  var format = document.getElementById('format').value;
                +  if (format == 'Manual') {
                +    var code = document.getElementById('languageTA').value;
                +    // If the code is JSON, it will parse, otherwise treat as JS.
                +    try {
                +      JSON.parse(code);
                +      format = 'JSON';
                +    } catch (e) {
                +      format = 'JavaScript';
                +    }
                +  } else {
                +    var code = document.getElementById('languagePre').textContent;
                +  }
                +  if (!code.trim()) {
                +    // Nothing to render.  Happens while cloud storage is loading.
                +    return;
                +  }
                +
                +  // Backup Blockly.Blocks object so that main workspace and preview don't
                +  // collide if user creates a 'factory_base' block, for instance.
                +  var backupBlocks = Blockly.Blocks;
                +  try {
                +    // Make a shallow copy.
                +    Blockly.Blocks = Object.create(null);
                +    for (var prop in backupBlocks) {
                +      Blockly.Blocks[prop] = backupBlocks[prop];
                +    }
                +
                +    if (format == 'JSON') {
                +      var json = JSON.parse(code);
                +      Blockly.Blocks[json.type || BlockFactory.UNNAMED] = {
                +        init: function() {
                +          this.jsonInit(json);
                +        }
                +      };
                +    } else if (format == 'JavaScript') {
                +      eval(code);
                +    } else {
                +      throw 'Unknown format: ' + format;
                +    }
                +
                +    // Look for a block on Blockly.Blocks that does not match the backup.
                +    var blockType = null;
                +    for (var type in Blockly.Blocks) {
                +      if (typeof Blockly.Blocks[type].init == 'function' &&
                +          Blockly.Blocks[type] != backupBlocks[type]) {
                +        blockType = type;
                +        break;
                +      }
                +    }
                +    if (!blockType) {
                +      return;
                +    }
                +
                +    // Create the preview block.
                +    var previewBlock = BlockFactory.previewWorkspace.newBlock(blockType);
                +    previewBlock.initSvg();
                +    previewBlock.render();
                +    previewBlock.setMovable(false);
                +    previewBlock.setDeletable(false);
                +    previewBlock.moveBy(15, 10);
                +    BlockFactory.previewWorkspace.clearUndo();
                +    BlockFactory.updateGenerator(previewBlock);
                +
                +    // Warn user only if their block type is already exists in Blockly's
                +    // standard library.
                +    var rootBlock = FactoryUtils.getRootBlock(BlockFactory.mainWorkspace);
                +    if (StandardCategories.coreBlockTypes.indexOf(blockType) != -1) {
                +      rootBlock.setWarningText('A core Blockly block already exists ' +
                +          'under this name.');
                +
                +    } else if (blockType == 'block_type') {
                +      // Warn user to let them know they can't save a block under the default
                +      // name 'block_type'
                +      rootBlock.setWarningText('You cannot save a block with the default ' +
                +          'name, "block_type"');
                +
                +    } else {
                +      rootBlock.setWarningText(null);
                +    }
                +
                +  } finally {
                +    Blockly.Blocks = backupBlocks;
                +  }
                +};
                +
                +/**
                + * Disable link and save buttons if the format is 'Manual', enable otherwise.
                + */
                +BlockFactory.disableEnableLink = function() {
                +  var linkButton = document.getElementById('linkButton');
                +  var saveBlockButton = document.getElementById('localSaveButton');
                +  var saveToLibButton = document.getElementById('saveToBlockLibraryButton');
                +  var disabled = document.getElementById('format').value == 'Manual';
                +  linkButton.disabled = disabled;
                +  saveBlockButton.disabled = disabled;
                +  saveToLibButton.disabled = disabled;
                +};
                +
                +/**
                + * Render starter block (factory_base).
                + */
                +BlockFactory.showStarterBlock = function() {
                +  BlockFactory.mainWorkspace.clear();
                +  var xml = Blockly.Xml.textToDom(BlockFactory.STARTER_BLOCK_XML_TEXT);
                +  Blockly.Xml.domToWorkspace(xml, BlockFactory.mainWorkspace);
                +};
                +
                +/**
                + * Returns whether or not the current block open is the starter block.
                + */
                +BlockFactory.isStarterBlock = function() {
                +  var rootBlock = FactoryUtils.getRootBlock(BlockFactory.mainWorkspace);
                +  // The starter block does not have blocks nested into the factory_base block.
                +  return !(rootBlock.getChildren().length > 0 ||
                +      // The starter block's name is the default, 'block_type'.
                +      rootBlock.getFieldValue('NAME').trim().toLowerCase() != 'block_type' ||
                +      // The starter block has no connections.
                +      rootBlock.getFieldValue('CONNECTIONS') != 'NONE' ||
                +      // The starter block has automatic inputs.
                +      rootBlock.getFieldValue('INLINE') != 'AUTO');
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/factory_utils.js b/blockly/webif/static/blockly/demos/blockfactory/factory_utils.js
                new file mode 100644
                index 000000000..d66225c3a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/factory_utils.js
                @@ -0,0 +1,999 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview FactoryUtils is a namespace that holds block starter code
                + * generation functions shared by the Block Factory, Workspace Factory, and
                + * Exporter applications within Blockly Factory. Holds functions to generate
                + * block definitions and generator stubs and to create and download files.
                + *
                + * @author fraser@google.com (Neil Fraser), quachtina96 (Tina Quach)
                + */
                + 'use strict';
                +
                +/**
                + * Namespace for FactoryUtils.
                + */
                +goog.provide('FactoryUtils');
                +
                +
                +/**
                + * Get block definition code for the current block.
                + * @param {string} blockType Type of block.
                + * @param {!Blockly.Block} rootBlock RootBlock from main workspace in which
                + *    user uses Block Factory Blocks to create a custom block.
                + * @param {string} format 'JSON' or 'JavaScript'.
                + * @param {!Blockly.Workspace} workspace Where the root block lives.
                + * @return {string} Block definition.
                + */
                +FactoryUtils.getBlockDefinition = function(blockType, rootBlock, format, workspace) {
                +  blockType = FactoryUtils.cleanBlockType(blockType);
                +  switch (format) {
                +    case 'JSON':
                +      var code = FactoryUtils.formatJson_(blockType, rootBlock);
                +      break;
                +    case 'JavaScript':
                +      var code = FactoryUtils.formatJavaScript_(blockType, rootBlock, workspace);
                +      break;
                +  }
                +  return code;
                +};
                +
                +/**
                + * Convert invalid block name to a valid one. Replaces whitespace
                + * and prepend names that start with a digit with an '_'.
                + * @param {string} blockType Type of block.
                + * @return {string} Cleaned up block type.
                + */
                +FactoryUtils.cleanBlockType = function(blockType) {
                +  if (!blockType) {
                +    return '';
                +  }
                +  return blockType.replace(/\W/g, '_').replace(/^(\d)/, '_$1');
                +};
                +
                +/**
                + * Get the generator code for a given block.
                + * @param {!Blockly.Block} block Rendered block in preview workspace.
                + * @param {string} generatorLanguage 'JavaScript', 'Python', 'PHP', 'Lua',
                + *   'Dart'.
                + * @return {string} Generator code for multiple blocks.
                + */
                +FactoryUtils.getGeneratorStub = function(block, generatorLanguage) {
                +  function makeVar(root, name) {
                +    name = name.toLowerCase().replace(/\W/g, '_');
                +    return '  var ' + root + '_' + name;
                +  }
                +  // The makevar function lives in the original update generator.
                +  var language = generatorLanguage;
                +  var code = [];
                +  code.push("Blockly." + language + "['" + block.type +
                +            "'] = function(block) {");
                +
                +  // Generate getters for any fields or inputs.
                +  for (var i = 0, input; input = block.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      var name = field.name;
                +      if (!name) {
                +        continue;
                +      }
                +      if (field instanceof Blockly.FieldVariable) {
                +        // Subclass of Blockly.FieldDropdown, must test first.
                +        code.push(makeVar('variable', name) +
                +                  " = Blockly." + language +
                +                  ".variableDB_.getName(block.getFieldValue('" + name +
                +                  "'), Blockly.Variables.NAME_TYPE);");
                +      } else if (field instanceof Blockly.FieldAngle) {
                +        // Subclass of Blockly.FieldTextInput, must test first.
                +        code.push(makeVar('angle', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (Blockly.FieldDate && field instanceof Blockly.FieldDate) {
                +        // Blockly.FieldDate may not be compiled into Blockly.
                +        code.push(makeVar('date', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldColour) {
                +        code.push(makeVar('colour', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldCheckbox) {
                +        code.push(makeVar('checkbox', name) +
                +                  " = block.getFieldValue('" + name + "') == 'TRUE';");
                +      } else if (field instanceof Blockly.FieldDropdown) {
                +        code.push(makeVar('dropdown', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldNumber) {
                +        code.push(makeVar('number', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldTextInput) {
                +        code.push(makeVar('text', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      }
                +    }
                +    var name = input.name;
                +    if (name) {
                +      if (input.type == Blockly.INPUT_VALUE) {
                +        code.push(makeVar('value', name) +
                +                  " = Blockly." + language + ".valueToCode(block, '" + name +
                +                  "', Blockly." + language + ".ORDER_ATOMIC);");
                +      } else if (input.type == Blockly.NEXT_STATEMENT) {
                +        code.push(makeVar('statements', name) +
                +                  " = Blockly." + language + ".statementToCode(block, '" +
                +                  name + "');");
                +      }
                +    }
                +  }
                +  // Most languages end lines with a semicolon.  Python does not.
                +  var lineEnd = {
                +    'JavaScript': ';',
                +    'Python': '',
                +    'PHP': ';',
                +    'Dart': ';'
                +  };
                +  code.push("  // TODO: Assemble " + language + " into code variable.");
                +  if (block.outputConnection) {
                +    code.push("  var code = '...';");
                +    code.push("  // TODO: Change ORDER_NONE to the correct strength.");
                +    code.push("  return [code, Blockly." + language + ".ORDER_NONE];");
                +  } else {
                +    code.push("  var code = '..." + (lineEnd[language] || '') + "\\n';");
                +    code.push("  return code;");
                +  }
                +  code.push("};");
                +
                +  return code.join('\n');
                +};
                +
                +/**
                + * Update the language code as JSON.
                + * @param {string} blockType Name of block.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @return {string} Generanted language code.
                + * @private
                + */
                +FactoryUtils.formatJson_ = function(blockType, rootBlock) {
                +  var JS = {};
                +  // Type is not used by Blockly, but may be used by a loader.
                +  JS.type = blockType;
                +  // Generate inputs.
                +  var message = [];
                +  var args = [];
                +  var contentsBlock = rootBlock.getInputTargetBlock('INPUTS');
                +  var lastInput = null;
                +  while (contentsBlock) {
                +    if (!contentsBlock.disabled && !contentsBlock.getInheritedDisabled()) {
                +      var fields = FactoryUtils.getFieldsJson_(
                +          contentsBlock.getInputTargetBlock('FIELDS'));
                +      for (var i = 0; i < fields.length; i++) {
                +        if (typeof fields[i] == 'string') {
                +          message.push(fields[i].replace(/%/g, '%%'));
                +        } else {
                +          args.push(fields[i]);
                +          message.push('%' + args.length);
                +        }
                +      }
                +
                +      var input = {type: contentsBlock.type};
                +      // Dummy inputs don't have names.  Other inputs do.
                +      if (contentsBlock.type != 'input_dummy') {
                +        input.name = contentsBlock.getFieldValue('INPUTNAME');
                +      }
                +      var check = JSON.parse(
                +          FactoryUtils.getOptTypesFrom(contentsBlock, 'TYPE') || 'null');
                +      if (check) {
                +        input.check = check;
                +      }
                +      var align = contentsBlock.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        input.align = align;
                +      }
                +      args.push(input);
                +      message.push('%' + args.length);
                +      lastInput = contentsBlock;
                +    }
                +    contentsBlock = contentsBlock.nextConnection &&
                +        contentsBlock.nextConnection.targetBlock();
                +  }
                +  // Remove last input if dummy and not empty.
                +  if (lastInput && lastInput.type == 'input_dummy') {
                +    var fields = lastInput.getInputTargetBlock('FIELDS');
                +    if (fields && FactoryUtils.getFieldsJson_(fields).join('').trim() != '') {
                +      var align = lastInput.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        JS.lastDummyAlign0 = align;
                +      }
                +      args.pop();
                +      message.pop();
                +    }
                +  }
                +  JS.message0 = message.join(' ');
                +  if (args.length) {
                +    JS.args0 = args;
                +  }
                +  // Generate inline/external switch.
                +  if (rootBlock.getFieldValue('INLINE') == 'EXT') {
                +    JS.inputsInline = false;
                +  } else if (rootBlock.getFieldValue('INLINE') == 'INT') {
                +    JS.inputsInline = true;
                +  }
                +  // Generate output, or next/previous connections.
                +  switch (rootBlock.getFieldValue('CONNECTIONS')) {
                +    case 'LEFT':
                +      JS.output =
                +          JSON.parse(
                +              FactoryUtils.getOptTypesFrom(rootBlock, 'OUTPUTTYPE') || 'null');
                +      break;
                +    case 'BOTH':
                +      JS.previousStatement =
                +          JSON.parse(
                +              FactoryUtils.getOptTypesFrom(rootBlock, 'TOPTYPE') || 'null');
                +      JS.nextStatement =
                +          JSON.parse(
                +              FactoryUtils.getOptTypesFrom(rootBlock, 'BOTTOMTYPE') || 'null');
                +      break;
                +    case 'TOP':
                +      JS.previousStatement =
                +          JSON.parse(
                +              FactoryUtils.getOptTypesFrom(rootBlock, 'TOPTYPE') || 'null');
                +      break;
                +    case 'BOTTOM':
                +      JS.nextStatement =
                +          JSON.parse(
                +              FactoryUtils.getOptTypesFrom(rootBlock, 'BOTTOMTYPE') || 'null');
                +      break;
                +  }
                +  // Generate colour.
                +  var colourBlock = rootBlock.getInputTargetBlock('COLOUR');
                +  if (colourBlock && !colourBlock.disabled) {
                +    var hue = parseInt(colourBlock.getFieldValue('HUE'), 10);
                +    JS.colour = hue;
                +  }
                +
                +  JS.tooltip = FactoryUtils.getTooltipFromRootBlock_(rootBlock);
                +  JS.helpUrl = FactoryUtils.getHelpUrlFromRootBlock_(rootBlock);
                +
                +  return JSON.stringify(JS, null, '  ');
                +};
                +
                +/**
                + * Update the language code as JavaScript.
                + * @param {string} blockType Name of block.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @param {!Blockly.Workspace} workspace Where the root block lives.
                + * @return {string} Generated language code.
                + * @private
                + */
                +FactoryUtils.formatJavaScript_ = function(blockType, rootBlock, workspace) {
                +  var code = [];
                +  code.push("Blockly.Blocks['" + blockType + "'] = {");
                +  code.push("  init: function() {");
                +  // Generate inputs.
                +  var TYPES = {'input_value': 'appendValueInput',
                +               'input_statement': 'appendStatementInput',
                +               'input_dummy': 'appendDummyInput'};
                +  var contentsBlock = rootBlock.getInputTargetBlock('INPUTS');
                +  while (contentsBlock) {
                +    if (!contentsBlock.disabled && !contentsBlock.getInheritedDisabled()) {
                +      var name = '';
                +      // Dummy inputs don't have names.  Other inputs do.
                +      if (contentsBlock.type != 'input_dummy') {
                +        name =
                +            JSON.stringify(contentsBlock.getFieldValue('INPUTNAME'));
                +      }
                +      code.push('    this.' + TYPES[contentsBlock.type] + '(' + name + ')');
                +      var check = FactoryUtils.getOptTypesFrom(contentsBlock, 'TYPE');
                +      if (check) {
                +        code.push('        .setCheck(' + check + ')');
                +      }
                +      var align = contentsBlock.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        code.push('        .setAlign(Blockly.ALIGN_' + align + ')');
                +      }
                +      var fields = FactoryUtils.getFieldsJs_(
                +          contentsBlock.getInputTargetBlock('FIELDS'));
                +      for (var i = 0; i < fields.length; i++) {
                +        code.push('        .appendField(' + fields[i] + ')');
                +      }
                +      // Add semicolon to last line to finish the statement.
                +      code[code.length - 1] += ';';
                +    }
                +    contentsBlock = contentsBlock.nextConnection &&
                +        contentsBlock.nextConnection.targetBlock();
                +  }
                +  // Generate inline/external switch.
                +  if (rootBlock.getFieldValue('INLINE') == 'EXT') {
                +    code.push('    this.setInputsInline(false);');
                +  } else if (rootBlock.getFieldValue('INLINE') == 'INT') {
                +    code.push('    this.setInputsInline(true);');
                +  }
                +  // Generate output, or next/previous connections.
                +  switch (rootBlock.getFieldValue('CONNECTIONS')) {
                +    case 'LEFT':
                +      code.push(FactoryUtils.connectionLineJs_('setOutput', 'OUTPUTTYPE', workspace));
                +      break;
                +    case 'BOTH':
                +      code.push(
                +          FactoryUtils.connectionLineJs_('setPreviousStatement', 'TOPTYPE', workspace));
                +      code.push(
                +          FactoryUtils.connectionLineJs_('setNextStatement', 'BOTTOMTYPE', workspace));
                +      break;
                +    case 'TOP':
                +      code.push(
                +          FactoryUtils.connectionLineJs_('setPreviousStatement', 'TOPTYPE', workspace));
                +      break;
                +    case 'BOTTOM':
                +      code.push(
                +          FactoryUtils.connectionLineJs_('setNextStatement', 'BOTTOMTYPE', workspace));
                +      break;
                +  }
                +  // Generate colour.
                +  var colourBlock = rootBlock.getInputTargetBlock('COLOUR');
                +  if (colourBlock && !colourBlock.disabled) {
                +    var hue = parseInt(colourBlock.getFieldValue('HUE'), 10);
                +    if (!isNaN(hue)) {
                +      code.push('    this.setColour(' + hue + ');');
                +    }
                +  }
                +
                +  var tooltip = FactoryUtils.getTooltipFromRootBlock_(rootBlock);
                +  var helpUrl = FactoryUtils.getHelpUrlFromRootBlock_(rootBlock);
                +  code.push(' this.setTooltip(' + JSON.stringify(tooltip) + ');');
                +  code.push(' this.setHelpUrl(' + JSON.stringify(helpUrl) + ');');
                +  code.push('  }');
                +  code.push('};');
                +  return code.join('\n');
                +};
                +
                +/**
                + * Create JS code required to create a top, bottom, or value connection.
                + * @param {string} functionName JavaScript function name.
                + * @param {string} typeName Name of type input.
                + * @param {!Blockly.Workspace} workspace Where the root block lives.
                + * @return {string} Line of JavaScript code to create connection.
                + * @private
                + */
                +FactoryUtils.connectionLineJs_ = function(functionName, typeName, workspace) {
                +  var type = FactoryUtils.getOptTypesFrom(
                +      FactoryUtils.getRootBlock(workspace), typeName);
                +  if (type) {
                +    type = ', ' + type;
                +  } else {
                +    type = '';
                +  }
                +  return '    this.' + functionName + '(true' + type + ');';
                +};
                +
                +/**
                + * Returns field strings and any config.
                + * @param {!Blockly.Block} block Input block.
                + * @return {!Array.<string>} Field strings.
                + * @private
                + */
                +FactoryUtils.getFieldsJs_ = function(block) {
                +  var fields = [];
                +  while (block) {
                +    if (!block.disabled && !block.getInheritedDisabled()) {
                +      switch (block.type) {
                +        case 'field_static':
                +          // Result: 'hello'
                +          fields.push(JSON.stringify(block.getFieldValue('TEXT')));
                +          break;
                +        case 'field_input':
                +          // Result: new Blockly.FieldTextInput('Hello'), 'GREET'
                +          fields.push('new Blockly.FieldTextInput(' +
                +              JSON.stringify(block.getFieldValue('TEXT')) + '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_number':
                +          // Result: new Blockly.FieldNumber(10, 0, 100, 1), 'NUMBER'
                +          var args = [
                +            Number(block.getFieldValue('VALUE')),
                +            Number(block.getFieldValue('MIN')),
                +            Number(block.getFieldValue('MAX')),
                +            Number(block.getFieldValue('PRECISION'))
                +          ];
                +          // Remove any trailing arguments that aren't needed.
                +          if (args[3] == 0) {
                +            args.pop();
                +            if (args[2] == Infinity) {
                +              args.pop();
                +              if (args[1] == -Infinity) {
                +                args.pop();
                +              }
                +            }
                +          }
                +          fields.push('new Blockly.FieldNumber(' + args.join(', ') + '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_angle':
                +          // Result: new Blockly.FieldAngle(90), 'ANGLE'
                +          fields.push('new Blockly.FieldAngle(' +
                +              parseFloat(block.getFieldValue('ANGLE')) + '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_checkbox':
                +          // Result: new Blockly.FieldCheckbox('TRUE'), 'CHECK'
                +          fields.push('new Blockly.FieldCheckbox(' +
                +              JSON.stringify(block.getFieldValue('CHECKED')) +
                +               '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_colour':
                +          // Result: new Blockly.FieldColour('#ff0000'), 'COLOUR'
                +          fields.push('new Blockly.FieldColour(' +
                +              JSON.stringify(block.getFieldValue('COLOUR')) +
                +              '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_date':
                +          // Result: new Blockly.FieldDate('2015-02-04'), 'DATE'
                +          fields.push('new Blockly.FieldDate(' +
                +              JSON.stringify(block.getFieldValue('DATE')) + '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_variable':
                +          // Result: new Blockly.FieldVariable('item'), 'VAR'
                +          var varname
                +              = JSON.stringify(block.getFieldValue('TEXT') || null);
                +          fields.push('new Blockly.FieldVariable(' + varname + '), ' +
                +              JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_dropdown':
                +          // Result:
                +          // new Blockly.FieldDropdown([['yes', '1'], ['no', '0']]), 'TOGGLE'
                +          var options = [];
                +          for (var i = 0; i < block.optionList_.length; i++) {
                +            options[i] = JSON.stringify([block.getUserData(i),
                +                                         block.getFieldValue('CPU' + i)]);
                +          }
                +          if (options.length) {
                +            fields.push('new Blockly.FieldDropdown([' +
                +                options.join(', ') + ']), ' +
                +                JSON.stringify(block.getFieldValue('FIELDNAME')));
                +          }
                +          break;
                +        case 'field_image':
                +          // Result: new Blockly.FieldImage('http://...', 80, 60, '*')
                +          var src = JSON.stringify(block.getFieldValue('SRC'));
                +          var width = Number(block.getFieldValue('WIDTH'));
                +          var height = Number(block.getFieldValue('HEIGHT'));
                +          var alt = JSON.stringify(block.getFieldValue('ALT'));
                +          fields.push('new Blockly.FieldImage(' +
                +              src + ', ' + width + ', ' + height + ', ' + alt + ')');
                +          break;
                +      }
                +    }
                +    block = block.nextConnection && block.nextConnection.targetBlock();
                +  }
                +  return fields;
                +};
                +
                +/**
                + * Returns field strings and any config.
                + * @param {!Blockly.Block} block Input block.
                + * @return {!Array.<string|!Object>} Array of static text and field configs.
                + * @private
                + */
                +FactoryUtils.getFieldsJson_ = function(block) {
                +  var fields = [];
                +  while (block) {
                +    if (!block.disabled && !block.getInheritedDisabled()) {
                +      switch (block.type) {
                +        case 'field_static':
                +          // Result: 'hello'
                +          fields.push(block.getFieldValue('TEXT'));
                +          break;
                +        case 'field_input':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            text: block.getFieldValue('TEXT')
                +          });
                +          break;
                +        case 'field_number':
                +          var obj = {
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            value: parseFloat(block.getFieldValue('VALUE'))
                +          };
                +          var min = parseFloat(block.getFieldValue('MIN'));
                +          if (min > -Infinity) {
                +            obj.min = min;
                +          }
                +          var max = parseFloat(block.getFieldValue('MAX'));
                +          if (max < Infinity) {
                +            obj.max = max;
                +          }
                +          var precision = parseFloat(block.getFieldValue('PRECISION'));
                +          if (precision) {
                +            obj.precision = precision;
                +          }
                +          fields.push(obj);
                +          break;
                +        case 'field_angle':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            angle: Number(block.getFieldValue('ANGLE'))
                +          });
                +          break;
                +        case 'field_checkbox':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            checked: block.getFieldValue('CHECKED') == 'TRUE'
                +          });
                +          break;
                +        case 'field_colour':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            colour: block.getFieldValue('COLOUR')
                +          });
                +          break;
                +        case 'field_date':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            date: block.getFieldValue('DATE')
                +          });
                +          break;
                +        case 'field_variable':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            variable: block.getFieldValue('TEXT') || null
                +          });
                +          break;
                +        case 'field_dropdown':
                +          var options = [];
                +          for (var i = 0; i < block.optionList_.length; i++) {
                +            options[i] = [block.getUserData(i),
                +                block.getFieldValue('CPU' + i)];
                +          }
                +          if (options.length) {
                +            fields.push({
                +              type: block.type,
                +              name: block.getFieldValue('FIELDNAME'),
                +              options: options
                +            });
                +          }
                +          break;
                +        case 'field_image':
                +          fields.push({
                +            type: block.type,
                +            src: block.getFieldValue('SRC'),
                +            width: Number(block.getFieldValue('WIDTH')),
                +            height: Number(block.getFieldValue('HEIGHT')),
                +            alt: block.getFieldValue('ALT')
                +          });
                +          break;
                +      }
                +    }
                +    block = block.nextConnection && block.nextConnection.targetBlock();
                +  }
                +  return fields;
                +};
                +
                +/**
                + * Fetch the type(s) defined in the given input.
                + * Format as a string for appending to the generated code.
                + * @param {!Blockly.Block} block Block with input.
                + * @param {string} name Name of the input.
                + * @return {?string} String defining the types.
                + */
                +FactoryUtils.getOptTypesFrom = function(block, name) {
                +  var types = FactoryUtils.getTypesFrom_(block, name);
                +  if (types.length == 0) {
                +    return undefined;
                +  } else if (types.indexOf('null') != -1) {
                +    return 'null';
                +  } else if (types.length == 1) {
                +    return types[0];
                +  } else {
                +    return '[' + types.join(', ') + ']';
                +  }
                +};
                +
                +
                +/**
                + * Fetch the type(s) defined in the given input.
                + * @param {!Blockly.Block} block Block with input.
                + * @param {string} name Name of the input.
                + * @return {!Array.<string>} List of types.
                + * @private
                + */
                +FactoryUtils.getTypesFrom_ = function(block, name) {
                +  var typeBlock = block.getInputTargetBlock(name);
                +  var types;
                +  if (!typeBlock || typeBlock.disabled) {
                +    types = [];
                +  } else if (typeBlock.type == 'type_other') {
                +    types = [JSON.stringify(typeBlock.getFieldValue('TYPE'))];
                +  } else if (typeBlock.type == 'type_group') {
                +    types = [];
                +    for (var n = 0; n < typeBlock.typeCount_; n++) {
                +      types = types.concat(FactoryUtils.getTypesFrom_(typeBlock, 'TYPE' + n));
                +    }
                +    // Remove duplicates.
                +    var hash = Object.create(null);
                +    for (var n = types.length - 1; n >= 0; n--) {
                +      if (hash[types[n]]) {
                +        types.splice(n, 1);
                +      }
                +      hash[types[n]] = true;
                +    }
                +  } else {
                +    types = [JSON.stringify(typeBlock.valueType)];
                +  }
                +  return types;
                +};
                +
                +/**
                + * Return the uneditable container block that everything else attaches to in
                + * given workspace.
                + * @param {!Blockly.Workspace} workspace Where the root block lives.
                + * @return {Blockly.Block} Root block.
                + */
                +FactoryUtils.getRootBlock = function(workspace) {
                +  var blocks = workspace.getTopBlocks(false);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (block.type == 'factory_base') {
                +      return block;
                +    }
                +  }
                +  return null;
                +};
                +
                +// TODO(quachtina96): Move hide, show, makeInvisible, and makeVisible to a new
                +// AppView namespace.
                +
                +/**
                + * Hides element so that it's invisible and doesn't take up space.
                + * @param {string} elementID ID of element to hide.
                + */
                +FactoryUtils.hide = function(elementID) {
                +  document.getElementById(elementID).style.display = 'none';
                +};
                +
                +/**
                + * Un-hides an element.
                + * @param {string} elementID ID of element to hide.
                + */
                +FactoryUtils.show = function(elementID) {
                +  document.getElementById(elementID).style.display = 'block';
                +};
                +
                +/**
                + * Hides element so that it's invisible but still takes up space.
                + * @param {string} elementID ID of element to hide.
                + */
                +FactoryUtils.makeInvisible = function(elementID) {
                +  document.getElementById(elementID).visibility = 'hidden';
                +};
                +
                +/**
                + * Makes element visible.
                + * @param {string} elementID ID of element to hide.
                + */
                +FactoryUtils.makeVisible = function(elementID) {
                +  document.getElementById(elementID).visibility = 'visible';
                +};
                +
                +/**
                + * Create a file with the given attributes and download it.
                + * @param {string} contents The contents of the file.
                + * @param {string} filename The name of the file to save to.
                + * @param {string} fileType The type of the file to save.
                + */
                +FactoryUtils.createAndDownloadFile = function(contents, filename, fileType) {
                +  var data = new Blob([contents], {type: 'text/' + fileType});
                +  var clickEvent = new MouseEvent("click", {
                +    "view": window,
                +    "bubbles": true,
                +    "cancelable": false
                +  });
                +
                +  var a = document.createElement('a');
                +  a.href = window.URL.createObjectURL(data);
                +  a.download = filename;
                +  a.textContent = 'Download file!';
                +  a.dispatchEvent(clickEvent);
                +};
                +
                +/**
                + * Get Blockly Block by rendering pre-defined block in workspace.
                + * @param {!Element} blockType Type of block that has already been defined.
                + * @param {!Blockly.Workspace} workspace Workspace on which to render
                + *    the block.
                + * @return {!Blockly.Block} The Blockly.Block of desired type.
                + */
                +FactoryUtils.getDefinedBlock = function(blockType, workspace) {
                +  workspace.clear();
                +  return workspace.newBlock(blockType);
                +};
                +
                +/**
                + * Parses a block definition get the type of the block it defines.
                + * @param {string} blockDef A single block definition.
                + * @return {string} Type of block defined by the given definition.
                + */
                +FactoryUtils.getBlockTypeFromJsDefinition = function(blockDef) {
                +  var indexOfStartBracket = blockDef.indexOf('[\'');
                +  var indexOfEndBracket = blockDef.indexOf('\']');
                +  if (indexOfStartBracket != -1 && indexOfEndBracket != -1) {
                +    return blockDef.substring(indexOfStartBracket + 2, indexOfEndBracket);
                +  } else {
                +    throw new Error ('Could not parse block type out of JavaScript block ' +
                +        'definition. Brackets normally enclosing block type not found.');
                +  }
                +};
                +
                +/**
                + * Generates a category containing blocks of the specified block types.
                + * @param {!Array.<!Blockly.Block>} blocks Blocks to include in the category.
                + * @param {string} categoryName Name to use for the generated category.
                + * @return {!Element} Category XML containing the given block types.
                + */
                +FactoryUtils.generateCategoryXml = function(blocks, categoryName) {
                +  // Create category DOM element.
                +  var categoryElement = goog.dom.createDom('category');
                +  categoryElement.setAttribute('name', categoryName);
                +
                +  // For each block, add block element to category.
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +
                +    // Get preview block XML.
                +    var blockXml = Blockly.Xml.blockToDom(block);
                +    blockXml.removeAttribute('id');
                +
                +    // Add block to category and category to XML.
                +    categoryElement.appendChild(blockXml);
                +  }
                +  return categoryElement;
                +};
                +
                +/**
                + * Parses a string containing JavaScript block definition(s) to create an array
                + * in which each element is a single block definition.
                + * @param {string} blockDefsString JavaScript block definition(s).
                + * @return {!Array.<string>} Array of block definitions.
                + */
                +FactoryUtils.parseJsBlockDefinitions = function(blockDefsString) {
                +  var blockDefArray = [];
                +  var defStart = blockDefsString.indexOf('Blockly.Blocks');
                +
                +  while (blockDefsString.indexOf('Blockly.Blocks', defStart) != -1) {
                +    var nextStart = blockDefsString.indexOf('Blockly.Blocks', defStart + 1);
                +    if (nextStart == -1) {
                +      // This is the last block definition.
                +      nextStart = blockDefsString.length;
                +    }
                +    var blockDef = blockDefsString.substring(defStart, nextStart);
                +    blockDefArray.push(blockDef);
                +    defStart = nextStart;
                +  }
                +  return blockDefArray;
                +};
                +
                +/**
                + * Parses a string containing JSON block definition(s) to create an array
                + * in which each element is a single block definition. Expected input is
                + * one or more block definitions in the form of concatenated, stringified
                + * JSON objects.
                + * @param {string} blockDefsString String containing JSON block
                + *    definition(s).
                + * @return {!Array.<string>} Array of block definitions.
                + */
                +FactoryUtils.parseJsonBlockDefinitions = function(blockDefsString) {
                +  var blockDefArray = [];
                +  var unbalancedBracketCount = 0;
                +  var defStart = 0;
                +  // Iterate through the blockDefs string. Keep track of whether brackets
                +  // are balanced.
                +  for (var i = 0; i < blockDefsString.length; i++) {
                +    var currentChar = blockDefsString[i];
                +    if (currentChar == '{') {
                +      unbalancedBracketCount++;
                +    }
                +    else if (currentChar == '}') {
                +      unbalancedBracketCount--;
                +      if (unbalancedBracketCount == 0 && i > 0) {
                +        // The brackets are balanced. We've got a complete block defintion.
                +        var blockDef = blockDefsString.substring(defStart, i + 1);
                +        blockDefArray.push(blockDef);
                +        defStart = i + 1;
                +      }
                +    }
                +  }
                +  return blockDefArray;
                +};
                +
                +/**
                + * Define blocks from imported block definitions.
                + * @param {string} blockDefsString Block definition(s).
                + * @param {string} format Block definition format ('JSON' or 'JavaScript').
                + * @return {!Array.<!Element>} Array of block types defined.
                + */
                +FactoryUtils.defineAndGetBlockTypes = function(blockDefsString, format) {
                +  var blockTypes = [];
                +
                +  // Define blocks and get block types.
                +  if (format == 'JSON') {
                +    var blockDefArray = FactoryUtils.parseJsonBlockDefinitions(blockDefsString);
                +
                +    // Populate array of blocktypes and define each block.
                +    for (var i = 0, blockDef; blockDef = blockDefArray[i]; i++) {
                +      var json = JSON.parse(blockDef);
                +      blockTypes.push(json.type);
                +
                +      // Define the block.
                +      Blockly.Blocks[json.type] = {
                +        init: function() {
                +          this.jsonInit(json);
                +        }
                +      };
                +    }
                +  } else if (format == 'JavaScript') {
                +    var blockDefArray = FactoryUtils.parseJsBlockDefinitions(blockDefsString);
                +
                +    // Populate array of block types.
                +    for (var i = 0, blockDef; blockDef = blockDefArray[i]; i++) {
                +      var blockType = FactoryUtils.getBlockTypeFromJsDefinition(blockDef);
                +      blockTypes.push(blockType);
                +    }
                +
                +    // Define all blocks.
                +    eval(blockDefsString);
                +  }
                +
                +  return blockTypes;
                +};
                +
                +/**
                + * Inject code into a pre tag, with syntax highlighting.
                + * Safe from HTML/script injection.
                + * @param {string} code Lines of code.
                + * @param {string} id ID of <pre> element to inject into.
                + */
                +FactoryUtils.injectCode = function(code, id) {
                +  var pre = document.getElementById(id);
                +  pre.textContent = code;
                +  code = pre.textContent;
                +  code = PR.prettyPrintOne(code, 'js');
                +  pre.innerHTML = code;
                +};
                +
                +/**
                + * Returns whether or not two blocks are the same based on their XML. Expects
                + * XML with a single child node that is a factory_base block, the XML found on
                + * Block Factory's main workspace.
                + * @param {!Element} blockXml1 An XML element with a single child node that
                + *    is a factory_base block.
                + * @param {!Element} blockXml2 An XML element with a single child node that
                + *    is a factory_base block.
                + * @return {boolean} Whether or not two blocks are the same based on their XML.
                + */
                +FactoryUtils.sameBlockXml = function(blockXml1, blockXml2) {
                +  // Each XML element should contain a single child element with a 'block' tag
                +  if (blockXml1.tagName.toLowerCase() != 'xml' ||
                +      blockXml2.tagName.toLowerCase() != 'xml') {
                +    throw new Error('Expected two XML elements, recieved elements with tag ' +
                +        'names: ' + blockXml1.tagName + ' and ' + blockXml2.tagName + '.');
                +  }
                +
                +  // Compare the block elements directly. The XML tags may include other meta
                +  // information we want to igrore.
                +  var blockElement1 = blockXml1.getElementsByTagName('block')[0];
                +  var blockElement2 = blockXml2.getElementsByTagName('block')[0];
                +
                +  if (!(blockElement1 && blockElement2)) {
                +    throw new Error('Could not get find block element in XML.');
                +  }
                +
                +  var blockXmlText1 = Blockly.Xml.domToText(blockElement1);
                +  var blockXmlText2 = Blockly.Xml.domToText(blockElement2);
                +
                +  // Strip white space.
                +  blockXmlText1 = blockXmlText1.replace(/\s+/g, '');
                +  blockXmlText2 = blockXmlText2.replace(/\s+/g, '');
                +
                +  // Return whether or not changes have been saved.
                +  return blockXmlText1 == blockXmlText2;
                +};
                +
                +/*
                + * Checks if a block has a variable field. Blocks with variable fields cannot
                + * be shadow blocks.
                + * @param {Blockly.Block} block The block to check if a variable field exists.
                + * @return {boolean} True if the block has a variable field, false otherwise.
                + */
                +FactoryUtils.hasVariableField = function(block) {
                +  if (!block) {
                +    return false;
                +  }
                +  return block.getVars().length > 0;
                +};
                +
                +/**
                + * Checks if a block is a procedures block. If procedures block names are
                + * ever updated or expanded, this function should be updated as well (no
                + * other known markers for procedure blocks beyond name).
                + * @param {Blockly.Block} block The block to check.
                + * @return {boolean} True if the block is a procedure block, false otherwise.
                + */
                +FactoryUtils.isProcedureBlock = function(block) {
                +  return block &&
                +      (block.type == 'procedures_defnoreturn' ||
                +      block.type == 'procedures_defreturn' ||
                +      block.type == 'procedures_callnoreturn' ||
                +      block.type == 'procedures_callreturn' ||
                +      block.type == 'procedures_ifreturn');
                +};
                +
                +/**
                + * Returns whether or not a modified block's changes has been saved to the
                + * Block Library.
                + * TODO(quachtina96): move into the Block Factory Controller once made.
                + * @param {!BlockLibraryController} blockLibraryController Block Library
                + *    Controller storing custom blocks.
                + * @return {boolean} True if all changes made to the block have been saved to
                + *    the given Block Library.
                + */
                +FactoryUtils.savedBlockChanges = function(blockLibraryController) {
                +  if (BlockFactory.isStarterBlock()) {
                +    return true;
                +  }
                +  var blockType = blockLibraryController.getCurrentBlockType();
                +  var currentXml = Blockly.Xml.workspaceToDom(BlockFactory.mainWorkspace);
                +
                +  if (blockLibraryController.has(blockType)) {
                +    // Block is saved in block library.
                +    var savedXml = blockLibraryController.getBlockXml(blockType);
                +    return FactoryUtils.sameBlockXml(savedXml, currentXml);
                +  }
                +  return false;
                +};
                +
                +/**
                + * Given the root block of the factory, return the tooltip specified by the user
                + * or the empty string if no tooltip is found.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @return {string} The tooltip for the generated block, or the empty string.
                + */
                +FactoryUtils.getTooltipFromRootBlock_ = function(rootBlock) {
                +  var tooltipBlock = rootBlock.getInputTargetBlock('TOOLTIP');
                +  if (tooltipBlock && !tooltipBlock.disabled) {
                +    return tooltipBlock.getFieldValue('TEXT');
                +  }
                +  return '';
                +};
                +
                +/**
                + * Given the root block of the factory, return the help url specified by the
                + * user or the empty string if no tooltip is found.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @return {string} The help url for the generated block, or the empty string.
                + */
                +FactoryUtils.getHelpUrlFromRootBlock_ = function(rootBlock) {
                +  var helpUrlBlock = rootBlock.getInputTargetBlock('HELPURL');
                +  if (helpUrlBlock && !helpUrlBlock.disabled) {
                +    return helpUrlBlock.getFieldValue('TEXT');
                +  }
                +  return '';
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/icon.png b/blockly/webif/static/blockly/demos/blockfactory/icon.png
                new file mode 100644
                index 000000000..2fcb25ed7
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/blockfactory/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/index.html b/blockly/webif/static/blockly/demos/blockfactory/index.html
                new file mode 100644
                index 000000000..9190bd132
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/index.html
                @@ -0,0 +1,748 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <meta name="viewport" content="target-densitydpi=device-dpi, height=660, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
                +  <title>Blockly Demo: Blockly Developer Tools</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../../closure-library/closure/goog/base.js"></script>
                +  <script src="analytics.js"></script>
                +  <script src="factory_utils.js"></script>
                +  <script src="workspacefactory/wfactory_model.js"></script>
                +  <script src="standard_categories.js"></script>
                +  <script src="workspacefactory/wfactory_controller.js"></script>
                +  <script src="workspacefactory/wfactory_view.js"></script>
                +  <script src="workspacefactory/wfactory_generator.js"></script>
                +  <script src="workspacefactory/wfactory_init.js"></script>
                +  <script src="block_option.js"></script>
                +  <script src="factory.js"></script>
                +  <script src="block_library_view.js"></script>
                +  <script src="block_library_storage.js"></script>
                +  <script src="block_library_controller.js"></script>
                +  <script src="block_exporter_tools.js"></script>
                +  <script src="block_exporter_view.js"></script>
                +  <script src="block_exporter_controller.js"></script>
                +  <script src="blocks.js"></script>
                +  <script src="app_controller.js"></script>
                +  <script src="/storage.js"></script>
                +  <link rel="stylesheet" href="factory.css">
                +  <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
                +  <script>
                +    var blocklyFactory;
                +    var init = function() {
                +      BlocklyDevTools.Analytics.init();
                +
                +      blocklyFactory = new AppController();
                +      blocklyFactory.init();
                +      window.addEventListener('beforeunload', blocklyFactory.confirmLeavePage);
                +    };
                +    window.addEventListener('load', init);
                +  </script>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Blockly Developer Tools
                +    <button id="helpButton" title="View documentation in new window.">
                +      <span>Help</span>
                +    </button>
                +  </h1>
                +  <div id="tabContainer">
                +    <div id="blockFactory_tab" class="tab tabon">Block Factory</div>
                +    <div id="blocklibraryExporter_tab" class="tab taboff">Block Exporter</div>
                +    <div id="workspaceFactory_tab" class="tab taboff">Workspace Factory</div>
                +  </div>
                +
                +  <!-- Exporter tab -->
                +  <div id="blockLibraryExporter">
                +    <br>
                +    <p>
                +      First, select blocks from your block library by clicking on them. Then, use the Export Settings form to download starter code for selected blocks.
                +    </p>
                +    <div id="exportSelector">
                +      <br>
                +      <h3>Block Selector</h3>
                +      <div class="dropdown">
                +        <button id="button_setBlocks">Select</button>
                +        <div id="dropdownDiv_setBlocks" class="dropdown-content">
                +          <a id="dropdown_addAllFromLib" title="Select all block library blocks.">All Stored in Block Library</a>
                +          <a id="dropdown_addAllUsed" title="Select all block library blocks used in workspace factory.">All Used in Workspace Factory</a>
                +        </div>
                +        <button id="clearSelectedButton" title="Clear selected blocks.">Clear Selected</a>
                +      </div>
                +
                +      <div id="blockSelector"></div>
                +    </div>
                +
                +    <!-- Users may customize export settings through this form -->
                +    <div id="exportSettings">
                +      <br>
                +      <h3> Export Settings </h3>
                +      <form id="exportSettingsForm">
                +
                +        <div id="selectedBlocksTextContainer">
                +          <p>Currently Selected:</p>
                +          <p id="selectedBlocksText"></p>
                +        </div>
                +        <label><input type="checkbox" id="blockDefCheck">Block Definition(s)</label><br>
                +        <div id="blockDefSettings" class="subsettings">
                +          <label>Format:
                +          <select id="exportFormat">
                +            <option value="JSON">JSON</option>
                +            <option value="JavaScript">JavaScript</option>
                +          </select></label>
                +          <br>
                +          <label>File Name:<br>
                +          <input type="text" id="blockDef_filename"></label>
                +        </div>
                +        <br>
                +
                +        <label><input type="checkbox" id="genStubCheck">Generator Stub(s)</label><br>
                +        <div id="genStubSettings" class="subsettings">
                +          <label>Language:
                +          <select id="exportLanguage">
                +            <option value="JavaScript">JavaScript</option>
                +            <option value="Python">Python</option>
                +            <option value="PHP">PHP</option>
                +            <option value="Lua">Lua</option>
                +            <option value="Dart">Dart</option>
                +          </select></label>
                +          <br>
                +          <label>File Name:<br>
                +          <input type="text" id="generatorStub_filename"></label><br>
                +        </div>
                +        <br>
                +      </form>
                +      <button id="exporterSubmitButton" title="Download block starter code as specified in export settings.">Export</button>
                +    </div>
                +    <div id="exportPreview">
                +      <br>
                +      <h3>Export Preview</h3>
                +      <div id="blockDefs" class="exportPreviewTextArea">
                +        <p id="blockDefs_label">Block Definitions:</p>
                +        <pre id="blockDefs_textArea"></pre>
                +      </div>
                +      <div id="genStubs" class="exportPreviewTextArea">
                +        <p id="genStubs_label">Generator Stubs:</p>
                +        <pre id="genStubs_textArea"></pre>
                +      </div>
                +    </div>
                +  </div>
                +
                +  <!-- Workspace Factory tab -->
                +
                +  <div id="workspaceFactoryContent">
                +    <div id="factoryHeader">
                +      <p>
                +        <div class="dropdown">
                +        <button id="button_importBlocks">Import Custom Blocks</button>
                +          <div id="dropdownDiv_importBlocks" class="dropdown-content">
                +            <input type="file" id="input_importBlocksJson" accept=".js, .json, .txt" class="inputfile"</input>
                +            <label for="input_importBlocksJson">From JSON</label>
                +            <input type="file" id="input_importBlocksJs" accept=".js, .txt" class="inputfile"</input>
                +            <label for="input_importBlocksJs">From Javascript</label>
                +          </div>
                +        </div>
                +
                +        <div class="dropdown">
                +        <button id="button_load">Load to Edit</button>
                +          <div id="dropdownDiv_load" class="dropdown-content">
                +            <input type="file" id="input_loadToolbox" accept=".xml" class="inputfile"></input>
                +            <label for="input_loadToolbox">Toolbox</label>
                +            <input type="file" id="input_loadPreload" accept=".xml" class="inputfile"</input>
                +            <label for="input_loadPreload">Workspace Blocks</label>
                +          </div>
                +        </div>
                +
                +        <div class="dropdown">
                +        <button id="button_export">Export</button>
                +          <div id="dropdownDiv_export" class="dropdown-content">
                +            <a id="dropdown_exportOptions">Starter Code</a>
                +            <a id="dropdown_exportToolbox">Toolbox</a>
                +            <a id="dropdown_exportPreload">Workspace Blocks</a>
                +            <a id="dropdown_exportAll">All</a>
                +          </div>
                +        </div>
                +
                +        <button id="button_clear">Clear</button>
                +      </p>
                +    </div>
                +
                +    <section id="createDiv">
                +      <div id="createHeader">
                +        <h3>Edit</h3>
                +        <p id="editHelpText">Drag blocks into the workspace to configure the toolbox in your custom workspace.</p>
                +      </div>
                +      <table id="workspaceTabs" style="width:auto; height:auto">
                +        <tr>
                +          <td id="tab_toolbox" class="tabon">Toolbox</td>
                +          <td id="tab_preload" class="taboff">Workspace</td>
                +        </tr>
                +      </table>
                +      <section id="toolbox_section">
                +        <div id="toolbox_blocks"></div>
                +      </section>
                +      <aside id="toolbox_div">
                +        <p id="categoryHeader">You currently have no categories.</p>
                +        <table id="categoryTable" style="width:auto; height:auto">
                +        </table>
                +        <p>&nbsp;</p>
                +
                +        <div class="dropdown">
                +          <button id="button_add" class="large">+</button>
                +          <div id="dropdownDiv_add" class="dropdown-content">
                +            <a id="dropdown_newCategory">New Category</a>
                +            <a id="dropdown_loadCategory">Standard Category</a>
                +            <a id="dropdown_separator">Separator</a>
                +            <a id="dropdown_loadStandardToolbox">Standard Toolbox</a>
                +          </div>
                +        </div>
                +
                +        <button id="button_remove" class="large">-</button>
                +
                +        <button id="button_up" class="large">&#8593;</button>
                +        <button id="button_down" class="large">&#8595;</button>
                +
                +        <br>
                +        <div class="dropdown">
                +          <button id="button_editCategory">Edit Category</button>
                +          <div id="dropdownDiv_editCategory" class="dropdown-content">
                +            <a id='dropdown_name'>Name</a>
                +            <a id='dropdown_color'>Colour</a>
                +          </div>
                +        </div>
                +
                +      </aside>
                +
                +      <button id="button_addShadow" style="display: none">Make Shadow</button>
                +      <button id="button_removeShadow" style="display: none">Remove Shadow</button>
                +
                +      <aside id="preload_div" style="display:none">
                +        <div id="preloadHelp">
                +          <p>Configure the options for your Blockly inject call.</p>
                +          <button id="button_optionsHelp">Help</button>
                +          <button class="small" id="button_standardOptions">Reset to Default</button>
                +        </div>
                +        <div id="workspace_options">
                +          <label><input type="checkbox" id="option_readOnly_checkbox">Read Only</label><br>
                +          <label><input type="checkbox" id="option_grid_checkbox">Use Grid</label><br>
                +          <div id="grid_options" style="display: none">
                +            <label>Spacing <input type="number" id="gridOption_spacing_number" style="width: 3em"></label><br>
                +            <label>Length <input type="number" id="gridOption_length_number" style="width: 3em"></label><br>
                +            <label>Colour <input type="text" id="gridOption_colour_text" style="width: 8em"></label><br>
                +            <div id="readonly1">
                +              <label><input type="checkbox" id="gridOption_snap_checkbox">Snap</label><br>
                +            </div>
                +          </div>
                +          <label>Path to Blockly Media <input type="text" id="option_media_text" style="width: 90%"></label><br>
                +          <label><input type="checkbox" id="option_rtl_checkbox">Layout with RTL</label><br>
                +          <label><input type="checkbox" id="option_scrollbars_checkbox">Scrollbars</label><br>
                +          <label><input type="checkbox" id="option_zoom_checkbox">Zoom</label><br>
                +          <div id="zoom_options" style="display: none">
                +            <label><input type="checkbox" id="zoomOption_controls_checkbox">Zoom Controls</label><br>
                +            <label><input type="checkbox" id="zoomOption_wheel_checkbox">Zoom Wheel</label><br>
                +            <label>Start Scale <input type="number" id="zoomOption_startScale_number" style="width: 4em"></label><br>
                +            <label>Max Scale <input type="number" id="zoomOption_maxScale_number" style="width: 4em"></label><br>
                +            <label>Min Scale <input type="number" id="zoomOption_minScale_number" style="width: 4em"></label><br>
                +            <label>Scale Speed <input type="number" id="zoomOption_scaleSpeed_number" style="width: 4em"></label><br>
                +          </div>
                +          <label><input type="checkbox" id="option_css_checkbox">Use Blockly CSS</label><br>
                +          <div id="readonly2">
                +            <label><input type="checkbox" id="option_collapse_checkbox">Collapsible Blocks</label><br>
                +            <label><input type="checkbox" id="option_comments_checkbox">Comments for Blocks</label><br>
                +            <label><input type="checkbox" id="option_disable_checkbox">Disabled Blocks</label><br>
                +            <label><input type="checkbox" id="option_infiniteBlocks_checkbox">Infinite Blocks</label><br>
                +            <div id="maxBlockNumber_option" style="display: none">
                +              <label>Max Blocks <input type="number" id="option_maxBlocks_number" style="width: 5em"></label><br>
                +            </div>
                +            <label><input type="checkbox" id="option_horizontalLayout_checkbox">Horizontal Toolbox</label><br>
                +            <label><input type="checkbox" id="option_toolboxPosition_checkbox">Toolbox End</label><br>
                +            <label><input type="checkbox" id="option_oneBasedIndex_checkbox">One-based index</label><br>
                +            <label><input type="checkbox" id="option_sounds_checkbox">Sounds<br>
                +            <label><input type="checkbox" id="option_trashcan_checkbox">Trashcan</label><br>
                +          </div>
                +        </div>
                +      </aside>
                +
                +    </section>
                +
                +    <aside id="previewDiv">
                +      <div id="previewBorder">
                +        <div id="previewHelp">
                +          <h3>Preview</h3>
                +          <p>This is what your custom workspace will look like.</p>
                +        </div>
                +        <div id="preview_blocks" class="content"></div>
                +      </div>
                +    </aside>
                +  </div>
                +
                +  <!-- Blockly Factory Tab -->
                +  <table id="blockFactoryContent">
                +    <tr width="100%" height="10%">
                +      <td width="50%" height="5%">
                +        <table>
                +          <tr id="blockLibrary">
                +            <td id="blockLibraryContainer">
                +            <span>
                +              <div class="dropdown">
                +                <button id="button_blockLib">Block Library</button>
                +                <div id="dropdownDiv_blockLib" class="dropdown-content">
                +                  <a id="createNewBlockButton">Create New Block</a>
                +                </div>
                +              </div>
                +              <select id="blockLibraryDropdown" style="display:none">
                +              </select>
                +            </span>
                +            </td>
                +            <td id="blockLibraryControls">
                +            <button id="saveToBlockLibraryButton" title="Save block to Block Library.">
                +              Save "block_type"
                +            </button>
                +            <button id="removeBlockFromLibraryButton" title="Remove block from Block Library.">
                +              Delete "block_type"
                +            </button>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +      <td height="5%">
                +        <table id="blockFactoryPreview">
                +          <tr>
                +            <td id="previewContainer">
                +              <h3>Preview:
                +                <select id="direction">
                +                  <option value="ltr">LTR</option>
                +                  <option value="rtl">RTL</option>
                +                </select>
                +              </h3>
                +            </td>
                +            <td id="buttonContainer">
                +              <button id="linkButton" title="Save and link to blocks.">
                +                <img src="link.png" height="21" width="21">
                +              </button>
                +              <button id="clearBlockLibraryButton" title="Clear Block Library.">
                +                <span>Clear Library</span>
                +              </button>
                +              <label for="files" class="buttonStyle">
                +                <span class=>Import Block Library</span>
                +              </label>
                +              <input id="files" type="file" name="files"
                +                  accept="application/xml">
                +              <button id="localSaveButton" title="Save block library XML to a local file.">
                +                <span>Download Block Library</span>
                +              </button>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +    </tr>
                +    <tr height="80%">
                +      <td id="blocklyWorkspaceContainer">
                +        <div id="blockly"></div>
                +        <div id="blocklyMask"></div>
                +      </td>
                +      <td width="50%">
                +        <table id="blocklyPreviewContainer">
                +          <tr>
                +            <td height="30%">
                +              <div id="preview"></div>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="5%">
                +              <h3>Block Definition:
                +                <select id="format">
                +                  <option value="JSON">JSON</option>
                +                  <option value="JavaScript">JavaScript</option>
                +                  <option value="Manual">Manual edit&hellip;</option>
                +                </select>
                +              </h3>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="30%">
                +              <pre id="languagePre"></pre>
                +              <textarea id="languageTA"></textarea>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="5%">
                +              <h3>Generator stub:
                +                <select id="language">
                +                  <option value="JavaScript">JavaScript</option>
                +                  <option value="Python">Python</option>
                +                  <option value="PHP">PHP</option>
                +                  <option value="Lua">Lua</option>
                +                  <option value="Dart">Dart</option>
                +                </select>
                +              </h3>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="30%">
                +              <pre id="generatorPre"></pre>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +      </tr>
                +  </table>
                +
                +  <div id="modalShadow"></div>
                +
                +  <xml id="blockfactory_toolbox" class="toolbox">
                +    <category name="Input">
                +      <block type="input_value">
                +        <value name="TYPE">
                +          <shadow type="type_null"></shadow>
                +        </value>
                +      </block>
                +      <block type="input_statement">
                +        <value name="TYPE">
                +          <shadow type="type_null"></shadow>
                +        </value>
                +      </block>
                +      <block type="input_dummy"></block>
                +    </category>
                +    <category name="Field">
                +      <block type="field_static"></block>
                +      <block type="field_input"></block>
                +      <block type="field_number"></block>
                +      <block type="field_angle"></block>
                +      <block type="field_dropdown"></block>
                +      <block type="field_checkbox"></block>
                +      <block type="field_colour"></block>
                +      <!--
                +      Date picker commented out since it increases footprint by 60%.
                +      Add it only if you need it.  See also goog.require in blockly.js.
                +      <block type="field_date"></block>
                +      -->
                +      <block type="field_variable"></block>
                +      <block type="field_image"></block>
                +    </category>
                +    <category name="Type">
                +      <block type="type_group"></block>
                +      <block type="type_null"></block>
                +      <block type="type_boolean"></block>
                +      <block type="type_number"></block>
                +      <block type="type_string"></block>
                +      <block type="type_list"></block>
                +      <block type="type_other"></block>
                +    </category>
                +    <category name="Colour" id="colourCategory">
                +      <block type="colour_hue"><mutation colour="20"></mutation><field name="HUE">20</field></block>
                +      <block type="colour_hue"><mutation colour="65"></mutation><field name="HUE">65</field></block>
                +      <block type="colour_hue"><mutation colour="120"></mutation><field name="HUE">120</field></block>
                +      <block type="colour_hue"><mutation colour="160"></mutation><field name="HUE">160</field></block>
                +      <block type="colour_hue"><mutation colour="210"></mutation><field name="HUE">210</field></block>
                +      <block type="colour_hue"><mutation colour="230"></mutation><field name="HUE">230</field></block>
                +      <block type="colour_hue"><mutation colour="260"></mutation><field name="HUE">260</field></block>
                +      <block type="colour_hue"><mutation colour="290"></mutation><field name="HUE">290</field></block>
                +      <block type="colour_hue"><mutation colour="330"></mutation><field name="HUE">330</field></block>
                +    </category>
                +  </xml>
                +
                +  <xml id="workspacefactory_toolbox" class="toolbox">
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +        <value name="BY">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT"></field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <shadow type="text">
                +            <field name="TEXT">,</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_sort"></block>
                +    </category>
                +    <category name="Colour" colour="20">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +        <value name="GREEN">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="BLUE">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </shadow>
                +        </value>
                +        <value name="COLOUR2">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </shadow>
                +        </value>
                +        <value name="RATIO">
                +          <shadow type="math_number">
                +            <field name="NUM">0.5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +    <sep></sep>
                +    <category name="Block Library" colour="260" id="blockLibCategory"></category>
                +  </xml>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/link.png b/blockly/webif/static/blockly/demos/blockfactory/link.png
                new file mode 100644
                index 000000000..11dfd8284
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/blockfactory/link.png differ
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/standard_categories.js b/blockly/webif/static/blockly/demos/blockfactory/standard_categories.js
                new file mode 100644
                index 000000000..6b4072680
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/standard_categories.js
                @@ -0,0 +1,395 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Contains a map of standard Blockly categories used to load
                + * standard Blockly categories into the user's toolbox. The map is keyed by
                + * the lower case name of the category, and contains the Category object for
                + * that particular category. Also has a list of core block types provided
                + * by Blockly.
                + *
                + * @author Emma Dauterman (evd2014)
                + */
                + 'use strict';
                +
                +/**
                + * Namespace for StandardCategories
                + */
                +goog.provide('StandardCategories');
                +
                +
                +// Map of standard category information necessary to add a standard category
                +// to the toolbox.
                +StandardCategories.categoryMap = Object.create(null);
                +
                +StandardCategories.categoryMap['logic'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Logic');
                +StandardCategories.categoryMap['logic'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="controls_if"></block>' +
                +    '<block type="logic_compare"></block>' +
                +    '<block type="logic_operation"></block>' +
                +    '<block type="logic_negate"></block>' +
                +    '<block type="logic_boolean"></block>' +
                +    '<block type="logic_null"></block>' +
                +    '<block type="logic_ternary"></block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['logic'].color ='#5C81A6';
                +
                +StandardCategories.categoryMap['loops'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Loops');
                +StandardCategories.categoryMap['loops'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="controls_repeat_ext">' +
                +      '<value name="TIMES">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">10</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="controls_whileUntil"></block>' +
                +    '<block type="controls_for">' +
                +      '<value name="FROM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="TO">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">10</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="BY">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="controls_forEach"></block>' +
                +    '<block type="controls_flow_statements"></block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['loops'].color = '#5CA65C';
                +
                +StandardCategories.categoryMap['math'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Math');
                +StandardCategories.categoryMap['math'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="math_number"></block>' +
                +    '<block type="math_arithmetic">' +
                +      '<value name="A">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="B">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_single">' +
                +      '<value name="NUM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">9</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_trig">' +
                +      '<value name="NUM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">45</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_constant"></block>' +
                +    '<block type="math_number_property">' +
                +      '<value name="NUMBER_TO_CHECK">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">0</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_round">' +
                +      '<value name="NUM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">3.1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_on_list"></block>' +
                +    '<block type="math_modulo">' +
                +      '<value name="DIVIDEND">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">64</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="DIVISOR">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">10</field>'+
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_constrain">' +
                +      '<value name="VALUE">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">50</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="LOW">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="HIGH">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">100</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_random_int">' +
                +      '<value name="FROM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">1</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="TO">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">100</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="math_random_float"></block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['math'].color = '#5C68A6';
                +
                +StandardCategories.categoryMap['text'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Text');
                +StandardCategories.categoryMap['text'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="text"></block>' +
                +    '<block type="text_join"></block>' +
                +    '<block type="text_append">' +
                +      '<value name="TEXT">' +
                +        '<shadow type="text"></shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_length">' +
                +      '<value name="VALUE">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_isEmpty">' +
                +      '<value name="VALUE">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT"></field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_indexOf">' +
                +      '<value name="VALUE">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">text</field>' +
                +        '</block>' +
                +      '</value>' +
                +      '<value name="FIND">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_charAt">' +
                +      '<value name="VALUE">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">text</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_getSubstring">' +
                +      '<value name="STRING">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">text</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_changeCase">' +
                +      '<value name="TEXT">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_trim">' +
                +      '<value name="TEXT">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_print">' +
                +      '<value name="TEXT">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="text_prompt_ext">' +
                +      '<value name="TEXT">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">abc</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['text'].color = '#5CA68D';
                +
                +StandardCategories.categoryMap['lists'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Lists');
                +StandardCategories.categoryMap['lists'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="lists_create_with">' +
                +      '<mutation items="0"></mutation>' +
                +    '</block>' +
                +    '<block type="lists_create_with"></block>' +
                +    '<block type="lists_repeat">' +
                +      '<value name="NUM">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">5</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_length"></block>' +
                +    '<block type="lists_isEmpty"></block>' +
                +    '<block type="lists_indexOf">' +
                +      '<value name="VALUE">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">list</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_getIndex">' +
                +      '<value name="VALUE">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">list</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_setIndex">' +
                +      '<value name="LIST">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">list</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_getSublist">' +
                +      '<value name="LIST">' +
                +        '<block type="variables_get">' +
                +          '<field name="VAR">list</field>' +
                +        '</block>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_split">' +
                +      '<value name="DELIM">' +
                +        '<shadow type="text">' +
                +          '<field name="TEXT">,</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="lists_sort"></block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['lists'].color = '#745CA6';
                +
                +StandardCategories.categoryMap['colour'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Colour');
                +StandardCategories.categoryMap['colour'].xml =
                +    Blockly.Xml.textToDom(
                +    '<xml>' +
                +    '<block type="colour_picker"></block>' +
                +    '<block type="colour_random"></block>' +
                +    '<block type="colour_rgb">' +
                +      '<value name="RED">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">100</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="GREEN">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">50</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="BLUE">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">0</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '<block type="colour_blend">' +
                +      '<value name="COLOUR1">' +
                +        '<shadow type="colour_picker">' +
                +          '<field name="COLOUR">#ff0000</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="COLOUR2">' +
                +        '<shadow type="colour_picker">' +
                +          '<field name="COLOUR">#3333ff</field>' +
                +        '</shadow>' +
                +      '</value>' +
                +      '<value name="RATIO">' +
                +        '<shadow type="math_number">' +
                +          '<field name="NUM">0.5</field>' +
                +       '</shadow>' +
                +      '</value>' +
                +    '</block>' +
                +    '</xml>');
                +StandardCategories.categoryMap['colour'].color = '#A6745C';
                +
                +StandardCategories.categoryMap['functions'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Functions');
                +StandardCategories.categoryMap['functions'].color = '#9A5CA6'
                +StandardCategories.categoryMap['functions'].custom = 'PROCEDURE';
                +
                +StandardCategories.categoryMap['variables'] =
                +    new ListElement(ListElement.TYPE_CATEGORY, 'Variables');
                +StandardCategories.categoryMap['variables'].color = '#A65C81';
                +StandardCategories.categoryMap['variables'].custom = 'VARIABLE';
                +
                +// All standard block types in provided in Blockly core.
                +StandardCategories.coreBlockTypes =  ["controls_if", "logic_compare",
                +    "logic_operation", "logic_negate", "logic_boolean", "logic_null",
                +    "logic_ternary", "controls_repeat_ext", "controls_whileUntil",
                +    "controls_for", "controls_forEach", "controls_flow_statements",
                +    "math_number", "math_arithmetic", "math_single", "math_trig",
                +    "math_constant", "math_number_property", "math_change", "math_round",
                +    "math_on_list", "math_modulo", "math_constrain", "math_random_int",
                +    "math_random_float", "text", "text_join", "text_append", "text_length",
                +    "text_isEmpty", "text_indexOf", "variables_get", "text_charAt",
                +    "text_getSubstring", "text_changeCase", "text_trim", "text_print",
                +    "text_prompt_ext", "colour_picker", "colour_random", "colour_rgb",
                +    "colour_blend", "lists_create_with", "lists_repeat", "lists_length",
                +    "lists_isEmpty", "lists_indexOf", "lists_getIndex", "lists_setIndex",
                +    "lists_getSublist", "lists_split", "lists_sort", "variables_set",
                +    "procedures_defreturn", "procedures_ifreturn", "procedures_defnoreturn",
                +    "procedures_callreturn"];
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_controller.js b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_controller.js
                new file mode 100644
                index 000000000..7516b0171
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_controller.js
                @@ -0,0 +1,1373 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Contains the controller code for workspace factory. Depends
                + * on the model and view objects (created as internal variables) and interacts
                + * with previewWorkspace and toolboxWorkspace (internal references stored to
                + * both). Also depends on standard_categories.js for standard Blockly
                + * categories. Provides the functionality for the actions the user can initiate:
                + * - adding and removing categories
                + * - switching between categories
                + * - printing and downloading configuration xml
                + * - updating the preview workspace
                + * - changing a category name
                + * - moving the position of a category.
                + *
                + * @author Emma Dauterman (evd2014)
                + */
                +
                +goog.require('BlocklyDevTools.Analytics');
                +goog.require('FactoryUtils');
                +goog.require('StandardCategories');
                +
                +
                +/**
                + * Class for a WorkspaceFactoryController
                + * @param {string} toolboxName Name of workspace toolbox XML.
                + * @param {string} toolboxDiv Name of div to inject toolbox workspace in.
                + * @param {string} previewDiv Name of div to inject preview workspace in.
                + * @constructor
                + */
                +WorkspaceFactoryController = function(toolboxName, toolboxDiv, previewDiv) {
                +  // Toolbox XML element for the editing workspace.
                +  this.toolbox = document.getElementById(toolboxName);
                +
                +  // Workspace for user to drag blocks in for a certain category.
                +  this.toolboxWorkspace = Blockly.inject(toolboxDiv,
                +    {grid:
                +      {spacing: 25,
                +       length: 3,
                +       colour: '#ccc',
                +       snap: true},
                +       media: '../../media/',
                +       toolbox: this.toolbox
                +     });
                +
                +  // Workspace for user to preview their changes.
                +  this.previewWorkspace = Blockly.inject(previewDiv,
                +    {grid:
                +      {spacing: 25,
                +       length: 3,
                +       colour: '#ccc',
                +       snap: true},
                +     media: '../../media/',
                +     toolbox: '<xml></xml>',
                +     zoom:
                +       {controls: true,
                +        wheel: true}
                +    });
                +
                +  // Model to keep track of categories and blocks.
                +  this.model = new WorkspaceFactoryModel();
                +  // Updates the category tabs.
                +  this.view = new WorkspaceFactoryView();
                +  // Generates XML for categories.
                +  this.generator = new WorkspaceFactoryGenerator(this.model);
                +  // Tracks which editing mode the user is in. Toolbox mode on start.
                +  this.selectedMode = WorkspaceFactoryController.MODE_TOOLBOX;
                +  // True if key events are enabled, false otherwise.
                +  this.keyEventsEnabled = true;
                +  // True if there are unsaved changes in the toolbox, false otherwise.
                +  this.hasUnsavedToolboxChanges = false;
                +  // True if there are unsaved changes in the preloaded blocks, false otherwise.
                +  this.hasUnsavedPreloadChanges = false;
                +};
                +
                +// Toolbox editing mode. Changes the user makes to the workspace updates the
                +// toolbox.
                +WorkspaceFactoryController.MODE_TOOLBOX = 'toolbox';
                +// Pre-loaded workspace editing mode. Changes the user makes to the workspace
                +// udpates the pre-loaded blocks.
                +WorkspaceFactoryController.MODE_PRELOAD = 'preload';
                +
                +/**
                + * Currently prompts the user for a name, checking that it's valid (not used
                + * before), and then creates a tab and switches to it.
                + */
                +WorkspaceFactoryController.prototype.addCategory = function() {
                +  // Transfers the user's blocks to a flyout if it's the first category created.
                +  this.transferFlyoutBlocksToCategory();
                +
                +  // After possibly creating a category, check again if it's the first category.
                +  var isFirstCategory = !this.model.hasElements();
                +  // Get name from user.
                +  var name = this.promptForNewCategoryName('Enter the name of your new category:');
                +  if (!name) {  // Exit if cancelled.
                +    return;
                +  }
                +  // Create category.
                +  this.createCategory(name);
                +  // Switch to category.
                +  this.switchElement(this.model.getCategoryIdByName(name));
                +
                +  // Sets the default options for injecting the workspace
                +  // when there are categories if adding the first category.
                +  if (isFirstCategory) {
                +    this.view.setCategoryOptions(this.model.hasElements());
                +    this.generateNewOptions();
                +  }
                +  // Update preview.
                +  this.updatePreview();
                +};
                +
                +/**
                + * Helper method for addCategory. Adds a category to the view given a name, ID,
                + * and a boolean for if it's the first category created. Assumes the category
                + * has already been created in the model. Does not switch to category.
                + * @param {string} name Name of category being added.
                + * @param {string} id The ID of the category being added.
                + */
                +WorkspaceFactoryController.prototype.createCategory = function(name) {
                +  // Create empty category
                +  var category = new ListElement(ListElement.TYPE_CATEGORY, name);
                +  this.model.addElementToList(category);
                +  // Create new category.
                +  var tab = this.view.addCategoryRow(name, category.id);
                +  this.addClickToSwitch(tab, category.id);
                +};
                +
                +/**
                + * Given a tab and a ID to be associated to that tab, adds a listener to
                + * that tab so that when the user clicks on the tab, it switches to the
                + * element associated with that ID.
                + * @param {!Element} tab The DOM element to add the listener to.
                + * @param {string} id The ID of the element to switch to when tab is clicked.
                + */
                +WorkspaceFactoryController.prototype.addClickToSwitch = function(tab, id) {
                +  var self = this;
                +  var clickFunction = function(id) {  // Keep this in scope for switchElement.
                +    return function() {
                +      self.switchElement(id);
                +    };
                +  };
                +  this.view.bindClick(tab, clickFunction(id));
                +};
                +
                +/**
                + * Transfers the blocks in the user's flyout to a new category if
                + * the user is creating their first category and their workspace is not
                + * empty. Should be called whenever it is possible to switch from single flyout
                + * to categories (not including importing).
                + */
                +WorkspaceFactoryController.prototype.transferFlyoutBlocksToCategory =
                +    function() {
                +  // Saves the user's blocks from the flyout in a category if there is no
                +  // toolbox and the user has dragged in blocks.
                +  if (!this.model.hasElements() &&
                +        this.toolboxWorkspace.getAllBlocks().length > 0) {
                +    // Create the new category.
                +    this.createCategory('Category 1', true);
                +    // Set the new category as selected.
                +    var id = this.model.getCategoryIdByName('Category 1');
                +    this.model.setSelectedById(id);
                +    this.view.setCategoryTabSelection(id, true);
                +    // Allow user to use the default options for injecting with categories.
                +    this.view.setCategoryOptions(this.model.hasElements());
                +    this.generateNewOptions();
                +    // Update preview here in case exit early.
                +    this.updatePreview();
                +  }
                +};
                +
                +/**
                + * Attached to "-" button. Checks if the user wants to delete
                + * the current element.  Removes the element and switches to another element.
                + * When the last element is removed, it switches to a single flyout mode.
                + */
                +WorkspaceFactoryController.prototype.removeElement = function() {
                +  // Check that there is a currently selected category to remove.
                +  if (!this.model.getSelected()) {
                +    return;
                +  }
                +
                +  // Check if user wants to remove current category.
                +  var check = confirm('Are you sure you want to delete the currently selected '
                +        + this.model.getSelected().type + '?');
                +  if (!check) { // If cancelled, exit.
                +    return;
                +  }
                +
                +  var selectedId = this.model.getSelectedId();
                +  var selectedIndex = this.model.getIndexByElementId(selectedId);
                +  // Delete element visually.
                +  this.view.deleteElementRow(selectedId, selectedIndex);
                +  // Delete element in model.
                +  this.model.deleteElementFromList(selectedIndex);
                +
                +  // Find next logical element to switch to.
                +  var next = this.model.getElementByIndex(selectedIndex);
                +  if (!next && this.model.hasElements()) {
                +    next = this.model.getElementByIndex(selectedIndex - 1);
                +  }
                +  var nextId = next ? next.id : null;
                +
                +  // Open next element.
                +  this.clearAndLoadElement(nextId);
                +
                +  // If no element to switch to, display message, clear the workspace, and
                +  // set a default selected element not in toolbox list in the model.
                +  if (!nextId) {
                +    alert('You currently have no categories or separators. All your blocks' +
                +        ' will be displayed in a single flyout.');
                +    this.toolboxWorkspace.clear();
                +    this.toolboxWorkspace.clearUndo();
                +    this.model.createDefaultSelectedIfEmpty();
                +  }
                +  // Update preview.
                +  this.updatePreview();
                +};
                +
                +/**
                + * Gets a valid name for a new category from the user.
                + * @param {string} promptString Prompt for the user to enter a name.
                + * @param {string=} opt_oldName The current name.
                + * @return {string?} Valid name for a new category, or null if cancelled.
                + */
                +WorkspaceFactoryController.prototype.promptForNewCategoryName =
                +    function(promptString, opt_oldName) {
                +  var defaultName = opt_oldName;
                +  do {
                +    var name = prompt(promptString, defaultName);
                +    if (!name) {  // If cancelled.
                +      return null;
                +    }
                +    defaultName = name;
                +  } while (this.model.hasCategoryByName(name));
                +  return name;
                +};
                +
                +/**
                + * Switches to a new tab for the element given by ID. Stores XML and blocks
                + * to reload later, updates selected accordingly, and clears the workspace
                + * and clears undo, then loads the new element.
                + * @param {string} id ID of tab to be opened, must be valid element ID.
                + */
                +WorkspaceFactoryController.prototype.switchElement = function(id) {
                +  // Disables events while switching so that Blockly delete and create events
                +  // don't update the preview repeatedly.
                +  Blockly.Events.disable();
                +  // Caches information to reload or generate XML if switching to/from element.
                +  // Only saves if a category is selected.
                +  if (this.model.getSelectedId() != null && id != null) {
                +    this.model.getSelected().saveFromWorkspace(this.toolboxWorkspace);
                +  }
                +  // Load element.
                +  this.clearAndLoadElement(id);
                +  // Enable Blockly events again.
                +  Blockly.Events.enable();
                +};
                +
                +/**
                + * Switches to a new tab for the element by ID. Helper for switchElement.
                + * Updates selected, clears the workspace and clears undo, loads a new element.
                + * @param {string} id ID of category to load.
                + */
                +WorkspaceFactoryController.prototype.clearAndLoadElement = function(id) {
                +  // Unselect current tab if switching to and from an element.
                +  if (this.model.getSelectedId() != null && id != null) {
                +    this.view.setCategoryTabSelection(this.model.getSelectedId(), false);
                +  }
                +
                +  // If switching to another category, set category selection in the model and
                +  // view.
                +  if (id != null) {
                +    // Set next category.
                +    this.model.setSelectedById(id);
                +
                +    // Clears workspace and loads next category.
                +    this.clearAndLoadXml_(this.model.getSelectedXml());
                +
                +    // Selects the next tab.
                +    this.view.setCategoryTabSelection(id, true);
                +
                +    // Order blocks as shown in flyout.
                +    this.toolboxWorkspace.cleanUp();
                +
                +    // Update category editing buttons.
                +    this.view.updateState(this.model.getIndexByElementId
                +        (this.model.getSelectedId()), this.model.getSelected());
                +  } else {
                +    // Update category editing buttons for no categories.
                +    this.view.updateState(-1, null);
                +  }
                +};
                +
                +/**
                + * Tied to "Export" button. Gets a file name from the user and downloads
                + * the corresponding configuration XML to that file.
                + * @param {string} exportMode The type of file to export
                + *    (WorkspaceFactoryController.MODE_TOOLBOX for the toolbox configuration,
                + *    and WorkspaceFactoryController.MODE_PRELOAD for the pre-loaded workspace
                + *    configuration)
                + */
                +WorkspaceFactoryController.prototype.exportXmlFile = function(exportMode) {
                +  // Get file name.
                +  if (exportMode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    var fileName = prompt('File Name for toolbox XML:', 'toolbox.xml');
                +  } else {
                +    var fileName = prompt('File Name for pre-loaded workspace XML:',
                +                          'workspace.xml');
                +  }
                +  if (!fileName) {  // If cancelled.
                +    return;
                +  }
                +
                +  // Generate XML.
                +  if (exportMode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    // Export the toolbox XML.
                +    var configXml = Blockly.Xml.domToPrettyText
                +        (this.generator.generateToolboxXml());
                +    this.hasUnsavedToolboxChanges = false;
                +  } else if (exportMode == WorkspaceFactoryController.MODE_PRELOAD) {
                +    // Export the pre-loaded block XML.
                +    var configXml = Blockly.Xml.domToPrettyText
                +        (this.generator.generateWorkspaceXml());
                +    this.hasUnsavedPreloadChanges = false;
                +  } else {
                +    // Unknown mode. Throw error.
                +    var msg = "Unknown export mode: " + exportMode;
                +    BlocklyDevTools.Analytics.onError(msg);
                +    throw new Error(msg);
                +  }
                +
                +  // Download file.
                +  var data = new Blob([configXml], {type: 'text/xml'});
                +  this.view.createAndDownloadFile(fileName, data);
                +
                +  if (exportMode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    BlocklyDevTools.Analytics.onExport(
                +        BlocklyDevTools.Analytics.TOOLBOX,
                +        { format: BlocklyDevTools.Analytics.FORMAT_XML });
                +  } else if (exportMode == WorkspaceFactoryController.MODE_PRELOAD) {
                +    BlocklyDevTools.Analytics.onExport(
                +        BlocklyDevTools.Analytics.WORKSPACE_CONTENTS,
                +        { format: BlocklyDevTools.Analytics.FORMAT_XML });
                +  }
                +};
                +
                +/**
                + * Export the options object to be used for the Blockly inject call. Gets a
                + * file name from the user and downloads the options object to that file.
                + */
                +WorkspaceFactoryController.prototype.exportInjectFile = function() {
                +  var fileName = prompt('File Name for starter Blockly workspace code:',
                +                        'workspace.js');
                +  if (!fileName) {  // If cancelled.
                +    return;
                +  }
                +  // Generate new options to remove toolbox XML from options object (if
                +  // necessary).
                +  this.generateNewOptions();
                +  var printableOptions = this.generator.generateInjectString()
                +  var data = new Blob([printableOptions], {type: 'text/javascript'});
                +  this.view.createAndDownloadFile(fileName, data);
                +
                +  BlocklyDevTools.Analytics.onExport(
                +      BlocklyDevTools.Analytics.STARTER_CODE,
                +      {
                +        format: BlocklyDevTools.Analytics.FORMAT_JS,
                +        platform: BlocklyDevTools.Analytics.PLATFORM_WEB
                +      });
                +};
                +
                +/**
                + * Tied to "Print" button. Mainly used for debugging purposes. Prints
                + * the configuration XML to the console.
                + */
                +WorkspaceFactoryController.prototype.printConfig = function() {
                +  // Capture any changes made by user before generating XML.
                +  this.saveStateFromWorkspace();
                +  // Print XML.
                +  window.console.log(Blockly.Xml.domToPrettyText
                +      (this.generator.generateToolboxXml()));
                +};
                +
                +/**
                + * Updates the preview workspace based on the toolbox workspace. If switching
                + * from no categories to categories or categories to no categories, reinjects
                + * Blockly with reinjectPreview, otherwise just updates without reinjecting.
                + * Called whenever a list element is created, removed, or modified and when
                + * Blockly move and delete events are fired. Do not call on create events
                + * or disabling will cause the user to "drop" their current blocks. Make sure
                + * that no changes have been made to the workspace since updating the model
                + * (if this might be the case, call saveStateFromWorkspace).
                + */
                +WorkspaceFactoryController.prototype.updatePreview = function() {
                +  // Disable events to stop updatePreview from recursively calling itself
                +  // through event handlers.
                +  Blockly.Events.disable();
                +
                +  // Only update the toolbox if not in read only mode.
                +  if (!this.model.options['readOnly']) {
                +    // Get toolbox XML.
                +    var tree = Blockly.Options.parseToolboxTree(
                +        this.generator.generateToolboxXml());
                +
                +    // No categories, creates a simple flyout.
                +    if (tree.getElementsByTagName('category').length == 0) {
                +      // No categories, creates a simple flyout.
                +      if (this.previewWorkspace.toolbox_) {
                +        this.reinjectPreview(tree); // Switch to simple flyout, expensive.
                +      } else {
                +        this.previewWorkspace.updateToolbox(tree);
                +      }
                +    } else {
                +      // Uses categories, creates a toolbox.
                +      if (!this.previewWorkspace.toolbox_) {
                +        this.reinjectPreview(tree); // Create a toolbox, expensive.
                +      } else {
                +        // Close the toolbox before updating it so that the user has to reopen
                +        // the flyout and see their updated toolbox (open flyout doesn't update)
                +        this.previewWorkspace.toolbox_.clearSelection();
                +        this.previewWorkspace.updateToolbox(tree);
                +      }
                +    }
                +  }
                +
                +  // Update pre-loaded blocks in the preview workspace.
                +  this.previewWorkspace.clear();
                +  Blockly.Xml.domToWorkspace(this.generator.generateWorkspaceXml(),
                +      this.previewWorkspace);
                +
                +  // Reenable events.
                +  Blockly.Events.enable();
                +};
                +
                +/**
                + * Saves the state from the workspace depending on the current mode. Should
                + * be called after making changes to the workspace.
                + */
                +WorkspaceFactoryController.prototype.saveStateFromWorkspace = function() {
                +  if (this.selectedMode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    // If currently editing the toolbox.
                +    // Update flags if toolbox has been changed.
                +    if (this.model.getSelectedXml() !=
                +        Blockly.Xml.workspaceToDom(this.toolboxWorkspace)) {
                +      this.hasUnsavedToolboxChanges = true;
                +    }
                +
                +    this.model.getSelected().saveFromWorkspace(this.toolboxWorkspace);
                +
                +  } else if (this.selectedMode == WorkspaceFactoryController.MODE_PRELOAD) {
                +    // If currently editing the pre-loaded workspace.
                +    // Update flags if preloaded blocks have been changed.
                +    if (this.model.getPreloadXml() !=
                +        Blockly.Xml.workspaceToDom(this.toolboxWorkspace)) {
                +      this.hasUnsavedPreloadChanges = true;
                +    }
                +
                +    this.model.savePreloadXml(
                +        Blockly.Xml.workspaceToDom(this.toolboxWorkspace));
                +  }
                +};
                +
                +/**
                + * Used to completely reinject the preview workspace. This should be used only
                + * when switching from simple flyout to categories, or categories to simple
                + * flyout. More expensive than simply updating the flyout or toolbox.
                + * @param {!Element} Tree of XML elements
                + * @package
                + */
                +WorkspaceFactoryController.prototype.reinjectPreview = function(tree) {
                +  this.previewWorkspace.dispose();
                +  var injectOptions = this.readOptions_();
                +  injectOptions['toolbox'] = Blockly.Xml.domToPrettyText(tree);
                +  this.previewWorkspace = Blockly.inject('preview_blocks', injectOptions);
                +  Blockly.Xml.domToWorkspace(this.generator.generateWorkspaceXml(),
                +      this.previewWorkspace);
                +};
                +
                +/**
                + * Tied to "change name" button. Changes the name of the selected category.
                + * Continues prompting the user until they input a category name that is not
                + * currently in use, exits if user presses cancel.
                + */
                +WorkspaceFactoryController.prototype.changeCategoryName = function() {
                +  var selected = this.model.getSelected();
                +  // Return if a category is not selected.
                +  if (selected.type != ListElement.TYPE_CATEGORY) {
                +    return;
                +  }
                +  // Get new name from user.
                +  window.foo = selected;
                +  var newName = this.promptForNewCategoryName('What do you want to change this'
                +    + ' category\'s name to?', selected.name);
                +  if (!newName) {  // If cancelled.
                +    return;
                +  }
                +  // Change category name.
                +  selected.changeName(newName);
                +  this.view.updateCategoryName(newName, this.model.getSelectedId());
                +  // Update preview.
                +  this.updatePreview();
                +};
                +
                +/**
                + * Tied to arrow up and arrow down buttons. Swaps with the element above or
                + * below the currently selected element (offset categories away from the
                + * current element). Updates state to enable the correct element editing
                + * buttons.
                + * @param {number} offset The index offset from the currently selected element
                + * to swap with. Positive if the element to be swapped with is below, negative
                + * if the element to be swapped with is above.
                + */
                +WorkspaceFactoryController.prototype.moveElement = function(offset) {
                +  var curr = this.model.getSelected();
                +  if (!curr) {  // Return if no selected element.
                +    return;
                +  }
                +  var currIndex = this.model.getIndexByElementId(curr.id);
                +  var swapIndex = this.model.getIndexByElementId(curr.id) + offset;
                +  var swap = this.model.getElementByIndex(swapIndex);
                +  if (!swap) {  // Return if cannot swap in that direction.
                +    return;
                +  }
                +  // Move currently selected element to index of other element.
                +  // Indexes must be valid because confirmed that curr and swap exist.
                +  this.moveElementToIndex(curr, swapIndex, currIndex);
                +  // Update element editing buttons.
                +  this.view.updateState(swapIndex, this.model.getSelected());
                +  // Update preview.
                +  this.updatePreview();
                +};
                +
                +/**
                + * Moves a element to a specified index and updates the model and view
                + * accordingly. Helper functions throw an error if indexes are out of bounds.
                + * @param {!Element} element The element to move.
                + * @param {number} newIndex The index to insert the element at.
                + * @param {number} oldIndex The index the element is currently at.
                + */
                +WorkspaceFactoryController.prototype.moveElementToIndex = function(element,
                +    newIndex, oldIndex) {
                +  this.model.moveElementToIndex(element, newIndex, oldIndex);
                +  this.view.moveTabToIndex(element.id, newIndex, oldIndex);
                +};
                +
                +/**
                + * Changes the color of the selected category. Return if selected element is
                + * a separator.
                + * @param {string} color The color to change the selected category. Must be
                + * a valid CSS string.
                + */
                +WorkspaceFactoryController.prototype.changeSelectedCategoryColor =
                +    function(color) {
                +  // Return if category is not selected.
                +  if (this.model.getSelected().type != ListElement.TYPE_CATEGORY) {
                +    return;
                +  }
                +  // Change color of selected category.
                +  this.model.getSelected().changeColor(color);
                +  this.view.setBorderColor(this.model.getSelectedId(), color);
                +  this.updatePreview();
                +};
                +
                +/**
                + * Tied to the "Standard Category" dropdown option, this function prompts
                + * the user for a name of a standard Blockly category (case insensitive) and
                + * loads it as a new category and switches to it. Leverages StandardCategories.
                + */
                +WorkspaceFactoryController.prototype.loadCategory = function() {
                +  // Prompt user for the name of the standard category to load.
                +  do {
                +    var name = prompt('Enter the name of the category you would like to import '
                +        + '(Logic, Loops, Math, Text, Lists, Colour, Variables, or Functions)');
                +    if (!name) {
                +      return;  // Exit if cancelled.
                +    }
                +  } while (!this.isStandardCategoryName(name));
                +
                +  // Load category.
                +  this.loadCategoryByName(name);
                +};
                +
                +/**
                + * Loads a Standard Category by name and switches to it. Leverages
                + * StandardCategories. Returns if cannot load standard category.
                + * @param {string} name Name of the standard category to load.
                + */
                +WorkspaceFactoryController.prototype.loadCategoryByName = function(name) {
                +  // Check if the user can load that standard category.
                +  if (!this.isStandardCategoryName(name)) {
                +    return;
                +  }
                +  if (this.model.hasVariables() && name.toLowerCase() == 'variables') {
                +    alert('A Variables category already exists. You cannot create multiple' +
                +        ' variables categories.');
                +    return;
                +  }
                +  if (this.model.hasProcedures() && name.toLowerCase() == 'functions') {
                +    alert('A Functions category already exists. You cannot create multiple' +
                +        ' functions categories.');
                +    return;
                +  }
                +  // Check if the user can create a category with that name.
                +  var standardCategory = StandardCategories.categoryMap[name.toLowerCase()]
                +  if (this.model.hasCategoryByName(standardCategory.name)) {
                +    alert('You already have a category with the name ' + standardCategory.name
                +        + '. Rename your category and try again.');
                +    return;
                +  }
                +  // Transfers current flyout blocks to a category if it's the first category
                +  // created.
                +  this.transferFlyoutBlocksToCategory();
                +
                +  var isFirstCategory = !this.model.hasElements();
                +  // Copy the standard category in the model.
                +  var copy = standardCategory.copy();
                +
                +  // Add it to the model.
                +  this.model.addElementToList(copy);
                +
                +  // Update the copy in the view.
                +  var tab = this.view.addCategoryRow(copy.name, copy.id);
                +  this.addClickToSwitch(tab, copy.id);
                +  // Color the category tab in the view.
                +  if (copy.color) {
                +    this.view.setBorderColor(copy.id, copy.color);
                +  }
                +  // Switch to loaded category.
                +  this.switchElement(copy.id);
                +  // Convert actual shadow blocks to user-generated shadow blocks.
                +  this.convertShadowBlocks();
                +  // Save state from workspace before updating preview.
                +  this.saveStateFromWorkspace();
                +  if (isFirstCategory) {
                +    // Allow the user to use the default options for injecting the workspace
                +    // when there are categories.
                +    this.view.setCategoryOptions(this.model.hasElements());
                +    this.generateNewOptions();
                +  }
                +  // Update preview.
                +  this.updatePreview();
                +};
                +
                +/**
                + * Loads the standard Blockly toolbox into the editing space. Should only
                + * be called when the mode is set to toolbox.
                + */
                +WorkspaceFactoryController.prototype.loadStandardToolbox = function() {
                +  this.loadCategoryByName('Logic');
                +  this.loadCategoryByName('Loops');
                +  this.loadCategoryByName('Math');
                +  this.loadCategoryByName('Text');
                +  this.loadCategoryByName('Lists');
                +  this.loadCategoryByName('Colour');
                +  this.addSeparator();
                +  this.loadCategoryByName('Variables');
                +  this.loadCategoryByName('Functions');
                +};
                +
                +/**
                + * Given the name of a category, determines if it's the name of a standard
                + * category (case insensitive).
                + * @param {string} name The name of the category that should be checked if it's
                + * in StandardCategories categoryMap
                + * @return {boolean} True if name is a standard category name, false otherwise.
                + */
                +WorkspaceFactoryController.prototype.isStandardCategoryName = function(name) {
                +  for (var category in StandardCategories.categoryMap) {
                +    if (name.toLowerCase() == category) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Connected to the "add separator" dropdown option. If categories already
                + * exist, adds a separator to the model and view. Does not switch to select
                + * the separator, and updates the preview.
                + */
                +WorkspaceFactoryController.prototype.addSeparator = function() {
                +  // If adding the first element in the toolbox, transfers the user's blocks
                +  // in a flyout to a category.
                +  this.transferFlyoutBlocksToCategory();
                +  // Create the separator in the model.
                +  var separator = new ListElement(ListElement.TYPE_SEPARATOR);
                +  this.model.addElementToList(separator);
                +  // Create the separator in the view.
                +  var tab = this.view.addSeparatorTab(separator.id);
                +  this.addClickToSwitch(tab, separator.id);
                +  // Switch to the separator and update the preview.
                +  this.switchElement(separator.id);
                +  this.updatePreview();
                +};
                +
                +/**
                + * Connected to the import button. Given the file path inputted by the user
                + * from file input, if the import mode is for the toolbox, this function loads
                + * that toolbox XML to the workspace, creating category and separator tabs as
                + * necessary. If the import mode is for pre-loaded blocks in the workspace,
                + * this function loads that XML to the workspace to be edited further. This
                + * function switches mode to whatever the import mode is. Catches errors from
                + * file reading and prints an error message alerting the user.
                + * @param {string} file The path for the file to be imported into the workspace.
                + *   Should contain valid toolbox XML.
                + * @param {string} importMode The mode corresponding to the type of file the
                + *   user is importing (WorkspaceFactoryController.MODE_TOOLBOX or
                + *   WorkspaceFactoryController.MODE_PRELOAD).
                + */
                +WorkspaceFactoryController.prototype.importFile = function(file, importMode) {
                +  // Exit if cancelled.
                +  if (!file) {
                +    return;
                +  }
                +
                +  Blockly.Events.disable();
                +  var controller = this;
                +  var reader = new FileReader();
                +
                +  // To be executed when the reader has read the file.
                +  reader.onload = function() {
                +    // Try to parse XML from file and load it into toolbox editing area.
                +    // Print error message if fail.
                +    try {
                +      var tree = Blockly.Xml.textToDom(reader.result);
                +      if (importMode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +        // Switch mode.
                +        controller.setMode(WorkspaceFactoryController.MODE_TOOLBOX);
                +
                +        // Confirm that the user wants to override their current toolbox.
                +        var hasToolboxElements = controller.model.hasElements() ||
                +            controller.toolboxWorkspace.getAllBlocks().length > 0;
                +        if (hasToolboxElements) {
                +            var msg = 'Are you sure you want to import? You will lose your ' +
                +                'current toolbox.';
                +            BlocklyDevTools.Analytics.onWarning(msg);
                +            var continueAnyway = confirm();
                +            if (!continueAnyway) {
                +              return;
                +            }
                +        }
                +        // Import toolbox XML.
                +        controller.importToolboxFromTree_(tree);
                +        BlocklyDevTools.Analytics.onImport('Toolbox.xml');
                +
                +      } else if (importMode == WorkspaceFactoryController.MODE_PRELOAD) {
                +        // Switch mode.
                +        controller.setMode(WorkspaceFactoryController.MODE_PRELOAD);
                +
                +        // Confirm that the user wants to override their current blocks.
                +        if (controller.toolboxWorkspace.getAllBlocks().length > 0) {
                +          var msg = 'Are you sure you want to import? You will lose your ' +
                +            'current workspace blocks.';
                +          var continueAnyway = confirm(msg);
                +          BlocklyDevTools.Analytics.onWarning(msg);
                +          if (!continueAnyway) {
                +            return;
                +          }
                +        }
                +
                +        // Import pre-loaded workspace XML.
                +        controller.importPreloadFromTree_(tree);
                +        BlocklyDevTools.Analytics.onImport('WorkspaceContents.xml');
                +      } else {
                +        // Throw error if invalid mode.
                +        throw new Error("Unknown import mode: " + importMode);
                +      }
                +    } catch(e) {
                +      var msg = 'Cannot load XML from file.';
                +      alert(msg);
                +      BlocklyDevTools.Analytics.onError(msg);
                +      console.log(e);
                +    } finally {
                +      Blockly.Events.enable();
                +    }
                +  }
                +
                +  // Read the file asynchronously.
                +  reader.readAsText(file);
                +};
                +
                +/**
                + * Given a XML DOM tree, loads it into the toolbox editing area so that the
                + * user can continue editing their work. Assumes that tree is in valid toolbox
                + * XML format. Assumes that the mode is MODE_TOOLBOX.
                + * @param {!Element} tree XML tree to be loaded to toolbox editing area.
                + * @private
                + */
                +WorkspaceFactoryController.prototype.importToolboxFromTree_ = function(tree) {
                +  // Clear current editing area.
                +  this.model.clearToolboxList();
                +  this.view.clearToolboxTabs();
                +
                +  if (tree.getElementsByTagName('category').length == 0) {
                +    // No categories present.
                +    // Load all the blocks into a single category evenly spaced.
                +    Blockly.Xml.domToWorkspace(tree, this.toolboxWorkspace);
                +    this.toolboxWorkspace.cleanUp();
                +
                +    // Convert actual shadow blocks to user-generated shadow blocks.
                +    this.convertShadowBlocks();
                +
                +    // Add message to denote empty category.
                +    this.view.addEmptyCategoryMessage();
                +
                +  } else {
                +    // Categories/separators present.
                +    for (var i = 0, item; item = tree.children[i]; i++) {
                +
                +      if (item.tagName == 'category') {
                +        // If the element is a category, create a new category and switch to it.
                +        this.createCategory(item.getAttribute('name'), false);
                +        var category = this.model.getElementByIndex(i);
                +        this.switchElement(category.id);
                +
                +        // Load all blocks in that category to the workspace to be evenly
                +        // spaced and saved to that category.
                +        for (var j = 0, blockXml; blockXml = item.children[j]; j++) {
                +          Blockly.Xml.domToBlock(blockXml, this.toolboxWorkspace);
                +        }
                +
                +        // Evenly space the blocks.
                +        this.toolboxWorkspace.cleanUp();
                +
                +        // Convert actual shadow blocks to user-generated shadow blocks.
                +        this.convertShadowBlocks();
                +
                +        // Set category color.
                +        if (item.getAttribute('colour')) {
                +          category.changeColor(item.getAttribute('colour'));
                +          this.view.setBorderColor(category.id, category.color);
                +        }
                +        // Set any custom tags.
                +        if (item.getAttribute('custom')) {
                +          this.model.addCustomTag(category, item.getAttribute('custom'));
                +        }
                +      } else {
                +        // If the element is a separator, add the separator and switch to it.
                +        this.addSeparator();
                +        this.switchElement(this.model.getElementByIndex(i).id);
                +      }
                +    }
                +  }
                +  this.view.updateState(this.model.getIndexByElementId
                +      (this.model.getSelectedId()), this.model.getSelected());
                +
                +  this.saveStateFromWorkspace();
                +
                +  // Set default configuration options for a single flyout or multiple
                +  // categories.
                +  this.view.setCategoryOptions(this.model.hasElements());
                +  this.generateNewOptions();
                +
                +  this.updatePreview();
                +};
                +
                +/**
                + * Given a XML DOM tree, loads it into the pre-loaded workspace editing area.
                + * Assumes that tree is in valid XML format and that the selected mode is
                + * MODE_PRELOAD.
                + * @param {!Element} tree XML tree to be loaded to pre-loaded block editing
                + *   area.
                + */
                +WorkspaceFactoryController.prototype.importPreloadFromTree_ = function(tree) {
                +  this.clearAndLoadXml_(tree);
                +  this.model.savePreloadXml(tree);
                +  this.updatePreview();
                +};
                +
                +/**
                + * Given a XML DOM tree, loads it into the pre-loaded workspace editing area.
                + * Assumes that tree is in valid XML format and that the selected mode is
                + * MODE_PRELOAD.
                + * @param {!Element} tree XML tree to be loaded to pre-loaded block editing
                + *   area.
                + */
                +WorkspaceFactoryController.prototype.importPreloadFromTree_ = function(tree) {
                +  this.clearAndLoadXml_(tree);
                +  this.model.savePreloadXml(tree);
                +  this.saveStateFromWorkspace();
                +  this.updatePreview();
                +};
                +
                +/**
                + * Given a XML DOM tree, loads it into the pre-loaded workspace editing area.
                + * Assumes that tree is in valid XML format and that the selected mode is
                + * MODE_PRELOAD.
                + * @param {!Element} tree XML tree to be loaded to pre-loaded block editing
                + *   area.
                + */
                +WorkspaceFactoryController.prototype.importPreloadFromTree_ = function(tree) {
                +  this.clearAndLoadXml_(tree);
                +  this.model.savePreloadXml(tree);
                +  this.saveStateFromWorkspace();
                +  this.updatePreview();
                +};
                +
                +/**
                + * Clears the editing area completely, deleting all categories and all
                + * blocks in the model and view and all pre-loaded blocks. Tied to the
                + * "Clear" button.
                + */
                +WorkspaceFactoryController.prototype.clearAll = function() {
                +  var msg = 'Are you sure you want to clear all of your work in Workspace' +
                +      ' Factory?';
                +  BlocklyDevTools.Analytics.onWarning(msg);
                +  if (!confirm(msg)) {
                +    return;
                +  }
                +  var hasCategories = this.model.hasElements();
                +  this.model.clearToolboxList();
                +  this.view.clearToolboxTabs();
                +  this.model.savePreloadXml(Blockly.Xml.textToDom('<xml></xml>'));
                +  this.view.addEmptyCategoryMessage();
                +  this.view.updateState(-1, null);
                +  this.toolboxWorkspace.clear();
                +  this.toolboxWorkspace.clearUndo();
                +  this.saveStateFromWorkspace();
                +  this.hasUnsavedToolboxChanges = false;
                +  this.hasUnsavedPreloadChanges = false;
                +  this.view.setCategoryOptions(this.model.hasElements());
                +  this.generateNewOptions();
                +  this.updatePreview();
                +};
                +
                +/*
                + * Makes the currently selected block a user-generated shadow block. These
                + * blocks are not made into real shadow blocks, but recorded in the model
                + * and visually marked as shadow blocks, allowing the user to move and edit
                + * them (which would be impossible with actual shadow blocks). Updates the
                + * preview when done.
                + */
                +WorkspaceFactoryController.prototype.addShadow = function() {
                +  // No block selected to make a shadow block.
                +  if (!Blockly.selected) {
                +    return;
                +  }
                +  // Clear any previous warnings on the block (would only have warnings on
                +  // a non-shadow block if it was nested inside another shadow block).
                +  Blockly.selected.setWarningText(null);
                +  // Set selected block and all children as shadow blocks.
                +  this.addShadowForBlockAndChildren_(Blockly.selected);
                +
                +  // Save and update the preview.
                +  this.saveStateFromWorkspace();
                +  this.updatePreview();
                +};
                +
                +/**
                + * Sets a block and all of its children to be user-generated shadow blocks,
                + * both in the model and view.
                + * @param {!Blockly.Block} block The block to be converted to a user-generated
                + *    shadow block.
                + * @private
                + */
                +WorkspaceFactoryController.prototype.addShadowForBlockAndChildren_ =
                +    function(block) {
                +  // Convert to shadow block.
                +  this.view.markShadowBlock(block);
                +  this.model.addShadowBlock(block.id);
                +
                +  if (FactoryUtils.hasVariableField(block)) {
                +    block.setWarningText('Cannot make variable blocks shadow blocks.');
                +  }
                +
                +  // Convert all children to shadow blocks recursively.
                +  var children = block.getChildren();
                +  for (var i = 0; i < children.length; i++) {
                +    this.addShadowForBlockAndChildren_(children[i]);
                +  }
                +};
                +
                +/**
                + * If the currently selected block is a user-generated shadow block, this
                + * function makes it a normal block again, removing it from the list of
                + * shadow blocks and loading the workspace again. Updates the preview again.
                + */
                +WorkspaceFactoryController.prototype.removeShadow = function() {
                +  // No block selected to modify.
                +  if (!Blockly.selected) {
                +    return;
                +  }
                +  this.model.removeShadowBlock(Blockly.selected.id);
                +  this.view.unmarkShadowBlock(Blockly.selected);
                +
                +  // If turning invalid shadow block back to normal block, remove warning.
                +  Blockly.selected.setWarningText(null);
                +
                +  this.saveStateFromWorkspace();
                +  this.updatePreview();
                +};
                +
                +/**
                + * Given a unique block ID, uses the model to determine if a block is a
                + * user-generated shadow block.
                + * @param {string} blockId The unique ID of the block to examine.
                + * @return {boolean} True if the block is a user-generated shadow block, false
                + *    otherwise.
                + */
                +WorkspaceFactoryController.prototype.isUserGenShadowBlock = function(blockId) {
                +  return this.model.isShadowBlock(blockId);
                +};
                +
                +/**
                + * Call when importing XML containing real shadow blocks. This function turns
                + * all real shadow blocks loaded in the workspace into user-generated shadow
                + * blocks, meaning they are marked as shadow blocks by the model and appear as
                + * shadow blocks in the view but are still editable and movable.
                + */
                +WorkspaceFactoryController.prototype.convertShadowBlocks = function() {
                +  var blocks = this.toolboxWorkspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (block.isShadow()) {
                +      block.setShadow(false);
                +      // Delete the shadow DOM attached to the block so that the shadow block
                +      // does not respawn. Dependent on implementation details.
                +      var parentConnection = block.outputConnection ?
                +          block.outputConnection.targetConnection :
                +          block.previousConnection.targetConnection;
                +      if (parentConnection) {
                +        parentConnection.setShadowDom(null);
                +      }
                +      this.model.addShadowBlock(block.id);
                +      this.view.markShadowBlock(block);
                +    }
                +  }
                +};
                +
                +/**
                + * Sets the currently selected mode that determines what the toolbox workspace
                + * is being used to edit. Updates the view and then saves and loads XML
                + * to and from the toolbox and updates the help text.
                + * @param {string} tab The type of tab being switched to
                + *    (WorkspaceFactoryController.MODE_TOOLBOX or
                + *    WorkspaceFactoryController.MODE_PRELOAD).
                + */
                +WorkspaceFactoryController.prototype.setMode = function(mode) {
                +  // No work to change mode that's currently set.
                +  if (this.selectedMode == mode) {
                +    return;
                +  }
                +
                +  // No work to change mode that's currently set.
                +  if (this.selectedMode == mode) {
                +    return;
                +  }
                +
                +  // Set tab selection and display appropriate tab.
                +  this.view.setModeSelection(mode);
                +
                +  // Update selected tab.
                +  this.selectedMode = mode;
                +
                +  // Update help text above workspace.
                +  this.view.updateHelpText(mode);
                +
                +  if (mode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    // Open the toolbox editing space.
                +    this.model.savePreloadXml
                +        (Blockly.Xml.workspaceToDom(this.toolboxWorkspace));
                +    this.clearAndLoadXml_(this.model.getSelectedXml());
                +    this.view.disableWorkspace(this.view.shouldDisableWorkspace
                +        (this.model.getSelected()));
                +  } else {
                +    // Open the pre-loaded workspace editing space.
                +    if (this.model.getSelected()) {
                +      this.model.getSelected().saveFromWorkspace(this.toolboxWorkspace);
                +    }
                +    this.clearAndLoadXml_(this.model.getPreloadXml());
                +    this.view.disableWorkspace(false);
                +  }
                +};
                +
                +/**
                + * Clears the toolbox workspace and loads XML to it, marking shadow blocks
                + * as necessary.
                + * @private
                + * @param {!Element} xml The XML to be loaded to the workspace.
                + */
                +WorkspaceFactoryController.prototype.clearAndLoadXml_ = function(xml) {
                +  this.toolboxWorkspace.clear();
                +  this.toolboxWorkspace.clearUndo();
                +  Blockly.Xml.domToWorkspace(xml, this.toolboxWorkspace);
                +  this.view.markShadowBlocks(this.model.getShadowBlocksInWorkspace
                +      (this.toolboxWorkspace.getAllBlocks()));
                +  this.warnForUndefinedBlocks_();
                +};
                +
                +/**
                + * Sets the standard default options for the options object and updates
                + * the preview workspace. The default values depends on if categories are
                + * present.
                + */
                +WorkspaceFactoryController.prototype.setStandardOptionsAndUpdate = function() {
                +  this.view.setBaseOptions();
                +  this.view.setCategoryOptions(this.model.hasElements());
                +  this.generateNewOptions();
                +};
                +
                +/**
                + * Generates a new options object for injecting a Blockly workspace based
                + * on user input. Should be called every time a change has been made to
                + * an input field. Updates the model and reinjects the preview workspace.
                + */
                +WorkspaceFactoryController.prototype.generateNewOptions = function() {
                +  this.model.setOptions(this.readOptions_());
                +
                +  this.reinjectPreview(Blockly.Options.parseToolboxTree
                +      (this.generator.generateToolboxXml()));
                +};
                +
                +/**
                + * Generates a new options object for injecting a Blockly workspace based on
                + * user input.
                + * @return {!Object} Blockly injection options object.
                + * @private
                + */
                +WorkspaceFactoryController.prototype.readOptions_ = function() {
                +  var optionsObj = Object.create(null);
                +
                +  // Add all standard options to the options object.
                +  // Use parse int to get numbers from value inputs.
                +  var readonly = document.getElementById('option_readOnly_checkbox').checked;
                +  if (readonly) {
                +    optionsObj['readOnly'] = true;
                +  } else {
                +    optionsObj['collapse'] =
                +        document.getElementById('option_collapse_checkbox').checked;
                +    optionsObj['comments'] =
                +        document.getElementById('option_comments_checkbox').checked;
                +    optionsObj['disable'] =
                +        document.getElementById('option_disable_checkbox').checked;
                +    if (document.getElementById('option_infiniteBlocks_checkbox').checked) {
                +      optionsObj['maxBlocks'] = Infinity;
                +    } else {
                +      var maxBlocksValue =
                +          document.getElementById('option_maxBlocks_number').value;
                +      optionsObj['maxBlocks'] = typeof maxBlocksValue == 'string' ?
                +          parseInt(maxBlocksValue) : maxBlocksValue;
                +    }
                +    optionsObj['trashcan'] =
                +        document.getElementById('option_trashcan_checkbox').checked;
                +    optionsObj['horizontalLayout'] =
                +        document.getElementById('option_horizontalLayout_checkbox').checked;
                +    optionsObj['toolboxPosition'] =
                +        document.getElementById('option_toolboxPosition_checkbox').checked ?
                +        'end' : 'start';
                +  }
                +
                +  optionsObj['css'] = document.getElementById('option_css_checkbox').checked;
                +  optionsObj['media'] = document.getElementById('option_media_text').value;
                +  optionsObj['rtl'] = document.getElementById('option_rtl_checkbox').checked;
                +  optionsObj['scrollbars'] =
                +      document.getElementById('option_scrollbars_checkbox').checked;
                +  optionsObj['sounds'] =
                +      document.getElementById('option_sounds_checkbox').checked;
                +  optionsObj['oneBasedIndex'] =
                +      document.getElementById('option_oneBasedIndex_checkbox').checked;
                +
                +  // If using a grid, add all grid options.
                +  if (document.getElementById('option_grid_checkbox').checked) {
                +    var grid = Object.create(null);
                +    var spacingValue =
                +        document.getElementById('gridOption_spacing_number').value;
                +    grid['spacing'] = typeof spacingValue == 'string' ?
                +        parseInt(spacingValue) : spacingValue;
                +    var lengthValue = document.getElementById('gridOption_length_number').value;
                +    grid['length'] = typeof lengthValue == 'string' ?
                +        parseInt(lengthValue) : lengthValue;
                +    grid['colour'] = document.getElementById('gridOption_colour_text').value;
                +    if (!readonly) {
                +      grid['snap'] =
                +        document.getElementById('gridOption_snap_checkbox').checked;
                +    }
                +    optionsObj['grid'] = grid;
                +  }
                +
                +  // If using zoom, add all zoom options.
                +  if (document.getElementById('option_zoom_checkbox').checked) {
                +    var zoom = Object.create(null);
                +    zoom['controls'] =
                +        document.getElementById('zoomOption_controls_checkbox').checked;
                +    zoom['wheel'] =
                +        document.getElementById('zoomOption_wheel_checkbox').checked;
                +    var startScaleValue =
                +        document.getElementById('zoomOption_startScale_number').value;
                +    zoom['startScale'] = typeof startScaleValue == 'string' ?
                +        parseFloat(startScaleValue) : startScaleValue;
                +    var maxScaleValue =
                +        document.getElementById('zoomOption_maxScale_number').value;
                +    zoom['maxScale'] = typeof maxScaleValue == 'string' ?
                +        parseFloat(maxScaleValue) : maxScaleValue;
                +    var minScaleValue =
                +        document.getElementById('zoomOption_minScale_number').value;
                +    zoom['minScale'] = typeof minScaleValue == 'string' ?
                +        parseFloat(minScaleValue) : minScaleValue;
                +    var scaleSpeedValue =
                +        document.getElementById('zoomOption_scaleSpeed_number').value;
                +    zoom['scaleSpeed'] = typeof scaleSpeedValue == 'string' ?
                +        parseFloat(scaleSpeedValue) : scaleSpeedValue;
                +    optionsObj['zoom'] = zoom;
                +  }
                +
                +  return optionsObj;
                +};
                +
                +/**
                + * Imports blocks from a file, generating a category in the toolbox workspace
                + * to allow the user to use imported blocks in the toolbox and in pre-loaded
                + * blocks.
                + * @param {!File} file File object for the blocks to import.
                + * @param {string} format The format of the file to import, either 'JSON' or
                + *    'JavaScript'.
                + */
                +WorkspaceFactoryController.prototype.importBlocks = function(file, format) {
                +  // Generate category name from file name.
                +  var categoryName = file.name;
                +
                +  var controller = this;
                +  var reader = new FileReader();
                +
                +  // To be executed when the reader has read the file.
                +  reader.onload = function() {
                +    try {
                +      // Define blocks using block types from file.
                +      var blockTypes = FactoryUtils.defineAndGetBlockTypes(reader.result,
                +          format);
                +
                +      // If an imported block type is already defined, check if the user wants
                +      // to override the current block definition.
                +      if (controller.model.hasDefinedBlockTypes(blockTypes)) {
                +        var msg = 'An imported block uses the same name as a block '
                +          + 'already in your toolbox. Are you sure you want to override the '
                +          + 'currently defined block?';
                +        var continueAnyway = confirm(msg);
                +        BlocklyDevTools.Analytics.onWarning(msg);
                +        if (!continueAnyway) {
                +          return;
                +        }
                +      }
                +
                +      var blocks = controller.generator.getDefinedBlocks(blockTypes);
                +      // Generate category XML and append to toolbox.
                +      var categoryXml = FactoryUtils.generateCategoryXml(blocks, categoryName);
                +      // Get random color for category between 0 and 360. Gives each imported
                +      // category a different color.
                +      var randomColor = Math.floor(Math.random() * 360);
                +      categoryXml.setAttribute('colour', randomColor);
                +      controller.toolbox.appendChild(categoryXml);
                +      controller.toolboxWorkspace.updateToolbox(controller.toolbox);
                +      // Update imported block types.
                +      controller.model.addImportedBlockTypes(blockTypes);
                +      // Reload current category to possibly reflect any newly defined blocks.
                +      controller.clearAndLoadXml_
                +          (Blockly.Xml.workspaceToDom(controller.toolboxWorkspace));
                +
                +      BlocklyDevTools.Analytics.onImport('BlockDefinitions' +
                +          (format == 'JSON' ? '.json' : '.js'));
                +    } catch (e) {
                +      msg = 'Cannot read blocks from file.';
                +      alert(msg);
                +      BlocklyDevTools.Analytics.onError(msg);
                +      window.console.log(e);
                +    }
                +  }
                +
                +  // Read the file asynchronously.
                +  reader.readAsText(file);
                +};
                +
                +/*
                + * Updates the block library category in the toolbox workspace toolbox.
                + * @param {!Element} categoryXml XML for the block library category.
                + * @param {!Array.<string>} libBlockTypes Array of block types from the block
                + *    library.
                + */
                +WorkspaceFactoryController.prototype.setBlockLibCategory =
                +    function(categoryXml, libBlockTypes) {
                +  var blockLibCategory = document.getElementById('blockLibCategory');
                +
                +  // Set category ID so that it can be easily replaced, and set a standard,
                +  // arbitrary block library color.
                +  categoryXml.setAttribute('id', 'blockLibCategory');
                +  categoryXml.setAttribute('colour', 260);
                +
                +  // Update the toolbox and toolboxWorkspace.
                +  this.toolbox.replaceChild(categoryXml, blockLibCategory);
                +  this.toolboxWorkspace.toolbox_.clearSelection();
                +  this.toolboxWorkspace.updateToolbox(this.toolbox);
                +
                +  // Update the block library types.
                +  this.model.updateLibBlockTypes(libBlockTypes);
                +
                +  // Reload XML on page to account for blocks now defined or undefined in block
                +  // library.
                +  this.clearAndLoadXml_(Blockly.Xml.workspaceToDom(this.toolboxWorkspace));
                +};
                +
                +/**
                + * Return the block types used in the custom toolbox and pre-loaded workspace.
                + * @return {!Array.<string>} Block types used in the custom toolbox and
                + *    pre-loaded workspace.
                + */
                +WorkspaceFactoryController.prototype.getAllUsedBlockTypes = function() {
                +  return this.model.getAllUsedBlockTypes();
                +};
                +
                +/**
                + * Determines if a block loaded in the workspace has a definition (if it
                + * is a standard block, is defined in the block library, or has a definition
                + * imported).
                + * @param {!Blockly.Block} block The block to examine.
                + */
                +WorkspaceFactoryController.prototype.isDefinedBlock = function(block) {
                +  return this.model.isDefinedBlockType(block.type);
                +};
                +
                +/**
                + * Sets a warning on blocks loaded to the workspace that are not defined.
                + * @private
                + */
                +WorkspaceFactoryController.prototype.warnForUndefinedBlocks_ = function() {
                +  var blocks = this.toolboxWorkspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (!this.isDefinedBlock(block)) {
                +      block.setWarningText(block.type + ' is not defined (it is not a standard '
                +          + 'block, \nin your block library, or an imported block)');
                +    }
                +  }
                +};
                +
                +/*
                + * Determines if a standard variable category is in the custom toolbox.
                + * @return {boolean} True if a variables category is in use, false otherwise.
                + */
                +WorkspaceFactoryController.prototype.hasVariablesCategory = function() {
                +  return this.model.hasVariables();
                +};
                +
                +/**
                + * Determines if a standard procedures category is in the custom toolbox.
                + * @return {boolean} True if a procedures category is in use, false otherwise.
                + */
                +WorkspaceFactoryController.prototype.hasProceduresCategory = function() {
                +  return this.model.hasProcedures();
                +};
                +
                +/**
                + * Determines if there are any unsaved changes in workspace factory.
                + * @return {boolean} True if there are unsaved changes, false otherwise.
                + */
                +WorkspaceFactoryController.prototype.hasUnsavedChanges = function() {
                +  return this.hasUnsavedToolboxChanges || this.hasUnsavedPreloadChanges;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_generator.js b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_generator.js
                new file mode 100644
                index 000000000..3b06ac282
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_generator.js
                @@ -0,0 +1,243 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generates the configuration XML used to update the preview
                + * workspace or print to the console or download to a file. Leverages
                + * Blockly.Xml and depends on information in the model (holds a reference).
                + * Depends on a hidden workspace created in the generator to load saved XML in
                + * order to generate toolbox XML.
                + *
                + * @author Emma Dauterman (evd2014)
                + */
                +
                +goog.require('FactoryUtils');
                +
                +
                +/**
                + * Class for a WorkspaceFactoryGenerator
                + * @constructor
                + */
                +WorkspaceFactoryGenerator = function(model) {
                +  // Model to share information about categories and shadow blocks.
                +  this.model = model;
                +  // Create hidden workspace to load saved XML to generate toolbox XML.
                +  var hiddenBlocks = document.createElement('div');
                +  // Generate a globally unique ID for the hidden div element to avoid
                +  // collisions.
                +  var hiddenBlocksId = Blockly.utils.genUid();
                +  hiddenBlocks.id = hiddenBlocksId;
                +  hiddenBlocks.style.display = 'none';
                +  document.body.appendChild(hiddenBlocks);
                +  this.hiddenWorkspace = Blockly.inject(hiddenBlocksId);
                +};
                +
                +/**
                + * Generates the XML for the toolbox or flyout with information from
                + * toolboxWorkspace and the model. Uses the hiddenWorkspace to generate XML.
                + * Save state of workspace in model (saveFromWorkspace) before calling if
                + * changes might have been made to the selected category.
                + * @param {!Blockly.workspace} toolboxWorkspace Toolbox editing workspace where
                + * blocks are added by user to be part of the toolbox.
                + * @return {!Element} XML element representing toolbox or flyout corresponding
                + * to toolbox workspace.
                + */
                +WorkspaceFactoryGenerator.prototype.generateToolboxXml = function() {
                +  // Create DOM for XML.
                +  var xmlDom = goog.dom.createDom('xml',
                +      {
                +        'id' : 'toolbox',
                +        'style' : 'display:none'
                +      });
                +  if (!this.model.hasElements()) {
                +    // Toolbox has no categories. Use XML directly from workspace.
                +    this.loadToHiddenWorkspace_(this.model.getSelectedXml());
                +    this.appendHiddenWorkspaceToDom_(xmlDom);
                +  } else {
                +    // Toolbox has categories.
                +    // Assert that selected != null
                +    if (!this.model.getSelected()) {
                +      throw new Error('Selected is null when the toolbox is empty.');
                +    }
                +
                +    var xml = this.model.getSelectedXml();
                +    var toolboxList = this.model.getToolboxList();
                +
                +    // Iterate through each category to generate XML for each using the
                +    // hidden workspace. Load each category to the hidden workspace to make sure
                +    // that all the blocks that are not top blocks are also captured as block
                +    // groups in the flyout.
                +    for (var i = 0; i < toolboxList.length; i++) {
                +      var element = toolboxList[i];
                +      if (element.type == ListElement.TYPE_SEPARATOR) {
                +        // If the next element is a separator.
                +        var nextElement = goog.dom.createDom('sep');
                +      } else if (element.type == ListElement.TYPE_CATEGORY) {
                +        // If the next element is a category.
                +        var nextElement = goog.dom.createDom('category');
                +        nextElement.setAttribute('name', element.name);
                +        // Add a colour attribute if one exists.
                +        if (element.color != null) {
                +          nextElement.setAttribute('colour', element.color);
                +        }
                +        // Add a custom attribute if one exists.
                +        if (element.custom != null) {
                +          nextElement.setAttribute('custom', element.custom);
                +        }
                +        // Load that category to hidden workspace, setting user-generated shadow
                +        // blocks as real shadow blocks.
                +        this.loadToHiddenWorkspace_(element.xml);
                +        this.appendHiddenWorkspaceToDom_(nextElement);
                +      }
                +      xmlDom.appendChild(nextElement);
                +    }
                +  }
                +  return xmlDom;
                + };
                +
                +
                + /**
                +  * Generates XML for the workspace (different from generateConfigXml in that
                +  * it includes XY and ID attributes). Uses a workspace and converts user
                +  * generated shadow blocks to actual shadow blocks.
                +  * @return {!Element} XML element representing toolbox or flyout corresponding
                +  * to toolbox workspace.
                +  */
                +WorkspaceFactoryGenerator.prototype.generateWorkspaceXml = function() {
                +  // Load workspace XML to hidden workspace with user-generated shadow blocks
                +  // as actual shadow blocks.
                +  this.hiddenWorkspace.clear();
                +  Blockly.Xml.domToWorkspace(this.model.getPreloadXml(), this.hiddenWorkspace);
                +  this.setShadowBlocksInHiddenWorkspace_();
                +
                +  // Generate XML and set attributes.
                +  var generatedXml = Blockly.Xml.workspaceToDom(this.hiddenWorkspace);
                +  generatedXml.setAttribute('id', 'workspaceBlocks');
                +  generatedXml.setAttribute('style', 'display:none');
                +  return generatedXml;
                +};
                +
                +/**
                + * Generates a string representation of the options object for injecting the
                + * workspace and starter code.
                + * @return {string} String representation of starter code for injecting.
                + */
                +WorkspaceFactoryGenerator.prototype.generateInjectString = function() {
                +  var addAttributes = function(obj, tabChar) {
                +    if (!obj) {
                +      return '{}\n';
                +    }
                +    var str = '';
                +    for (var key in obj) {
                +      if (key == 'grid' || key == 'zoom') {
                +        var temp = tabChar + key + ' : {\n' + addAttributes(obj[key],
                +            tabChar + '\t') + tabChar + '}, \n';
                +      } else if (typeof obj[key] == 'string') {
                +        var temp = tabChar + key + ' : \'' + obj[key] + '\', \n';
                +      } else {
                +        var temp = tabChar + key + ' : ' + obj[key] + ', \n';
                +      }
                +      str += temp;
                +    }
                +    var lastCommaIndex = str.lastIndexOf(',');
                +    str = str.slice(0, lastCommaIndex) + '\n';
                +    return str;
                +  };
                +
                +  var attributes = addAttributes(this.model.options, '\t');
                +  if (!this.model.options['readOnly']) {
                +    attributes = '\ttoolbox : toolbox, \n' +
                +      attributes;
                +  }
                +  var finalStr = '/* TODO: Change toolbox XML ID if necessary. Can export ' +
                +      'toolbox XML from Workspace Factory. */\n' +
                +      'var toolbox = document.getElementById("toolbox");\n\n';
                +  finalStr += 'var options = { \n' + attributes + '};';
                +  finalStr += '\n\n/* Inject your workspace */ \nvar workspace = Blockly.' +
                +      'inject(/* TODO: Add ID of div to inject Blockly into */, options);';
                +  finalStr += '\n\n/* Load Workspace Blocks from XML to workspace. ' +
                +      'Remove all code below if no blocks to load */\n\n' +
                +      '/* TODO: Change workspace blocks XML ID if necessary. Can export' +
                +      ' workspace blocks XML from Workspace Factory. */\n' +
                +      'var workspaceBlocks = document.getElementById("workspaceBlocks"); \n\n' +
                +      '/* Load blocks to workspace. */\n' +
                +      'Blockly.Xml.domToWorkspace(workspace, workspaceBlocks);';
                +  return finalStr;
                +};
                +
                +/**
                + * Loads the given XML to the hidden workspace and sets any user-generated
                + * shadow blocks to be actual shadow blocks.
                + * @param {!Element} xml The XML to be loaded to the hidden workspace.
                + * @private
                + */
                +WorkspaceFactoryGenerator.prototype.loadToHiddenWorkspace_ = function(xml) {
                +  this.hiddenWorkspace.clear();
                +  Blockly.Xml.domToWorkspace(xml, this.hiddenWorkspace);
                +  this.setShadowBlocksInHiddenWorkspace_();
                +};
                +
                +/**
                + * Encodes blocks in the hidden workspace in a XML DOM element. Very
                + * similar to workspaceToDom, but doesn't capture IDs. Uses the top-level
                + * blocks loaded in hiddenWorkspace.
                + * @private
                + * @param {!Element} xmlDom Tree of XML elements to be appended to.
                + */
                +WorkspaceFactoryGenerator.prototype.appendHiddenWorkspaceToDom_ =
                +    function(xmlDom) {
                +  var blocks = this.hiddenWorkspace.getTopBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var blockChild = Blockly.Xml.blockToDom(block, /* opt_noId */ true);
                +    xmlDom.appendChild(blockChild);
                +  }
                +};
                +
                +/**
                + * Sets the user-generated shadow blocks loaded into hiddenWorkspace to be
                + * actual shadow blocks. This is done so that blockToDom records them as
                + * shadow blocks instead of regular blocks.
                + * @private
                + */
                +WorkspaceFactoryGenerator.prototype.setShadowBlocksInHiddenWorkspace_ =
                +    function() {
                +  var blocks = this.hiddenWorkspace.getAllBlocks();
                +  for (var i = 0; i < blocks.length; i++) {
                +    if (this.model.isShadowBlock(blocks[i].id)) {
                +      blocks[i].setShadow(true);
                +    }
                +  }
                +};
                +
                +/**
                + * Given a set of block types, gets the Blockly.Block objects for each block
                + * type.
                + * @param {!Array.<!Element>} blockTypes Array of blocks that have been defined.
                + * @return {!Array.<!Blockly.Block>} Array of Blockly.Block objects corresponding
                + *    to the array of blockTypes.
                + */
                +WorkspaceFactoryGenerator.prototype.getDefinedBlocks = function(blockTypes) {
                +  var blocks = [];
                +  for (var i = 0; i < blockTypes.length ; i++) {
                +    blocks.push(FactoryUtils.getDefinedBlock(blockTypes[i],
                +        this.hiddenWorkspace));
                +  }
                +  return blocks;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_init.js b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_init.js
                new file mode 100644
                index 000000000..6b619a76f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_init.js
                @@ -0,0 +1,605 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Contains the init functions for the workspace factory tab.
                + * Adds click handlers to buttons and dropdowns, adds event listeners for
                + * keydown events and Blockly events, and configures the initial setup of
                + * the page.
                + *
                + * @author Emma Dauterman (evd2014)
                + */
                +
                + goog.require('FactoryUtils');
                +
                +/**
                + * Namespace for workspace factory initialization methods.
                + * @namespace
                + */
                +WorkspaceFactoryInit = {};
                +
                +/**
                + * Initialization for workspace factory tab.
                + * @param {!FactoryController} controller The controller for the workspace
                + *    factory tab.
                + */
                +WorkspaceFactoryInit.initWorkspaceFactory = function(controller) {
                +  // Disable category editing buttons until categories are created.
                +  document.getElementById('button_remove').disabled = true;
                +  document.getElementById('button_up').disabled = true;
                +  document.getElementById('button_down').disabled = true;
                +  document.getElementById('button_editCategory').disabled = true;
                +
                +  this.initColorPicker_(controller);
                +  this.addWorkspaceFactoryEventListeners_(controller);
                +  this.assignWorkspaceFactoryClickHandlers_(controller);
                +  this.addWorkspaceFactoryOptionsListeners_(controller);
                +
                +  // Check standard options and apply the changes to update the view.
                +  controller.setStandardOptionsAndUpdate();
                +};
                +
                +/**
                + * Initialize the color picker in workspace factory.
                + * @param {!FactoryController} controller The controller for the workspace
                + *    factory tab.
                + * @private
                + */
                +WorkspaceFactoryInit.initColorPicker_ = function(controller) {
                +  // Array of Blockly category colours, consitent with the 15 degree default
                +  // of the block factory's colour wheel.
                +  var colours = [];
                +  for (var hue = 0; hue < 360; hue += 15) {
                +    colours.push(WorkspaceFactoryInit.hsvToHex_(hue,
                +        Blockly.HSV_SATURATION, Blockly.HSV_VALUE));
                +  }
                +
                +  // Create color picker with specific set of Blockly colours.
                +  var colourPicker = new goog.ui.ColorPicker();
                +  colourPicker.setSize(6);
                +  colourPicker.setColors(colours);
                +
                +  // Create and render the popup colour picker and attach to button.
                +  var popupPicker = new goog.ui.PopupColorPicker(null, colourPicker);
                +  popupPicker.render();
                +  popupPicker.attach(document.getElementById('dropdown_color'));
                +  popupPicker.setFocusable(true);
                +  goog.events.listen(popupPicker, 'change', function(e) {
                +    controller.changeSelectedCategoryColor(popupPicker.getSelectedColor());
                +    blocklyFactory.closeModal();
                +  });
                +};
                +
                +/**
                + * Converts from h,s,v values to a hex string
                + * @param {number} h Hue, in [0, 360].
                + * @param {number} s Saturation, in [0, 1].
                + * @param {number} v Value, in [0, 1].
                + * @return {string} hex representation of the color.
                + * @private
                + */
                +WorkspaceFactoryInit.hsvToHex_ = function(h, s, v) {
                +  var brightness = v * 255;
                +  var red = 0;
                +  var green = 0;
                +  var blue = 0;
                +  if (s == 0) {
                +    red = brightness;
                +    green = brightness;
                +    blue = brightness;
                +  } else {
                +    var sextant = Math.floor(h / 60);
                +    var remainder = (h / 60) - sextant;
                +    var val1 = brightness * (1 - s);
                +    var val2 = brightness * (1 - (s * remainder));
                +    var val3 = brightness * (1 - (s * (1 - remainder)));
                +    switch (sextant) {
                +      case 1:
                +        red = val2;
                +        green = brightness;
                +        blue = val1;
                +        break;
                +      case 2:
                +        red = val1;
                +        green = brightness;
                +        blue = val3;
                +        break;
                +      case 3:
                +        red = val1;
                +        green = val2;
                +        blue = brightness;
                +        break;
                +      case 4:
                +        red = val3;
                +        green = val1;
                +        blue = brightness;
                +        break;
                +      case 5:
                +        red = brightness;
                +        green = val1;
                +        blue = val2;
                +        break;
                +      case 6:
                +      case 0:
                +        red = brightness;
                +        green = val3;
                +        blue = val1;
                +        break;
                +    }
                +  }
                +
                +  var hexR = ('0' + Math.floor(red).toString(16)).slice(-2);
                +  var hexG = ('0' + Math.floor(green).toString(16)).slice(-2);
                +  var hexB = ('0' + Math.floor(blue).toString(16)).slice(-2);
                +  return '#' + hexR + hexG + hexB;
                +};
                +
                +/**
                + * Assign click handlers for workspace factory.
                + * @param {!FactoryController} controller The controller for the workspace
                + *    factory tab.
                + * @private
                + */
                +WorkspaceFactoryInit.assignWorkspaceFactoryClickHandlers_ =
                +    function(controller) {
                +
                +  // Import Custom Blocks button.
                +  document.getElementById('button_importBlocks').addEventListener
                +      ('click',
                +      function() {
                +        blocklyFactory.openModal('dropdownDiv_importBlocks');
                +      });
                +  document.getElementById('input_importBlocksJson').addEventListener
                +      ('change',
                +      function() {
                +        controller.importBlocks(event.target.files[0], 'JSON');
                +      });
                +  document.getElementById('input_importBlocksJson').addEventListener
                +      ('click', function() {blocklyFactory.closeModal()});
                +  document.getElementById('input_importBlocksJs').addEventListener
                +      ('change',
                +      function() {
                +        controller.importBlocks(event.target.files[0], 'JavaScript');
                +      });
                +  document.getElementById('input_importBlocksJs').addEventListener
                +      ('click', function() {blocklyFactory.closeModal()});
                +
                +  // Load to Edit button.
                +  document.getElementById('button_load').addEventListener
                +      ('click',
                +      function() {
                +        blocklyFactory.openModal('dropdownDiv_load');
                +      });
                +  document.getElementById('input_loadToolbox').addEventListener
                +      ('change',
                +      function() {
                +        controller.importFile(event.target.files[0],
                +            WorkspaceFactoryController.MODE_TOOLBOX);
                +      });
                +  document.getElementById('input_loadToolbox').addEventListener
                +      ('click', function() {blocklyFactory.closeModal()});
                +  document.getElementById('input_loadPreload').addEventListener
                +      ('change',
                +      function() {
                +        controller.importFile(event.target.files[0],
                +            WorkspaceFactoryController.MODE_PRELOAD);
                +      });
                +  document.getElementById('input_loadPreload').addEventListener
                +      ('click', function() {blocklyFactory.closeModal()});
                +
                +  // Export button.
                +  document.getElementById('dropdown_exportOptions').addEventListener
                +      ('click',
                +      function() {
                +        controller.exportInjectFile();
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_exportToolbox').addEventListener
                +      ('click',
                +      function() {
                +        controller.exportXmlFile(WorkspaceFactoryController.MODE_TOOLBOX);
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_exportPreload').addEventListener
                +      ('click',
                +      function() {
                +        controller.exportXmlFile(WorkspaceFactoryController.MODE_PRELOAD);
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_exportAll').addEventListener
                +      ('click',
                +      function() {
                +        controller.exportInjectFile();
                +        controller.exportXmlFile(WorkspaceFactoryController.MODE_TOOLBOX);
                +        controller.exportXmlFile(WorkspaceFactoryController.MODE_PRELOAD);
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('button_export').addEventListener
                +      ('click',
                +      function() {
                +        blocklyFactory.openModal('dropdownDiv_export');
                +      });
                +
                +  // Clear button.
                +  document.getElementById('button_clear').addEventListener
                +      ('click',
                +      function() {
                +        controller.clearAll();
                +      });
                +
                +  // Toolbox and Workspace tabs.
                +  document.getElementById('tab_toolbox').addEventListener
                +      ('click',
                +      function() {
                +        controller.setMode(WorkspaceFactoryController.MODE_TOOLBOX);
                +      });
                +  document.getElementById('tab_preload').addEventListener
                +      ('click',
                +      function() {
                +        controller.setMode(WorkspaceFactoryController.MODE_PRELOAD);
                +      });
                +
                +  // '+' button.
                +  document.getElementById('button_add').addEventListener
                +      ('click',
                +      function() {
                +        blocklyFactory.openModal('dropdownDiv_add');
                +      });
                +  document.getElementById('dropdown_newCategory').addEventListener
                +      ('click',
                +      function() {
                +        controller.addCategory();
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_loadCategory').addEventListener
                +      ('click',
                +      function() {
                +        controller.loadCategory();
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_separator').addEventListener
                +      ('click',
                +      function() {
                +        controller.addSeparator();
                +        blocklyFactory.closeModal();
                +      });
                +  document.getElementById('dropdown_loadStandardToolbox').addEventListener
                +      ('click',
                +      function() {
                +        controller.loadStandardToolbox();
                +        blocklyFactory.closeModal();
                +      });
                +
                +  // '-' button.
                +  document.getElementById('button_remove').addEventListener
                +      ('click',
                +      function() {
                +        controller.removeElement();
                +      });
                +
                +  // Up/Down buttons.
                +  document.getElementById('button_up').addEventListener
                +      ('click',
                +      function() {
                +        controller.moveElement(-1);
                +      });
                +  document.getElementById('button_down').addEventListener
                +      ('click',
                +      function() {
                +        controller.moveElement(1);
                +      });
                +
                +  // Edit Category button.
                +  document.getElementById('button_editCategory').addEventListener
                +      ('click',
                +      function() {
                +        blocklyFactory.openModal('dropdownDiv_editCategory');
                +      });
                +  document.getElementById('dropdown_name').addEventListener
                +      ('click',
                +      function() {
                +        controller.changeCategoryName();
                +        blocklyFactory.closeModal();
                +      });
                +
                +  // Make/Remove Shadow buttons.
                +  document.getElementById('button_addShadow').addEventListener
                +      ('click',
                +      function() {
                +        controller.addShadow();
                +        WorkspaceFactoryInit.displayAddShadow_(false);
                +        WorkspaceFactoryInit.displayRemoveShadow_(true);
                +      });
                +  document.getElementById('button_removeShadow').addEventListener
                +      ('click',
                +      function() {
                +        controller.removeShadow();
                +        WorkspaceFactoryInit.displayAddShadow_(true);
                +        WorkspaceFactoryInit.displayRemoveShadow_(false);
                +
                +        // Disable shadow editing button if turning invalid shadow block back
                +        // to normal block.
                +        if (!Blockly.selected.getSurroundParent()) {
                +          document.getElementById('button_addShadow').disabled = true;
                +        }
                +      });
                +
                +  // Help button on workspace tab.
                +  document.getElementById('button_optionsHelp').addEventListener
                +      ('click', function() {
                +        open('https://developers.google.com/blockly/guides/get-started/web#configuration');
                +      });
                +
                +  // Reset to Default button on workspace tab.
                +  document.getElementById('button_standardOptions').addEventListener
                +      ('click', function() {
                +        controller.setStandardOptionsAndUpdate();
                +      });
                +};
                +
                +/**
                + * Add event listeners for workspace factory.
                + * @param {!FactoryController} controller The controller for the workspace
                + *    factory tab.
                + * @private
                + */
                +WorkspaceFactoryInit.addWorkspaceFactoryEventListeners_ = function(controller) {
                +  // Use up and down arrow keys to move categories.
                +  window.addEventListener('keydown', function(e) {
                +    // Don't let arrow keys have any effect if not in Workspace Factory
                +    // editing the toolbox.
                +    if (!(controller.keyEventsEnabled && controller.selectedMode
                +        == WorkspaceFactoryController.MODE_TOOLBOX)) {
                +      return;
                +    }
                +
                +    if (e.keyCode == 38) {
                +      // Arrow up.
                +      controller.moveElement(-1);
                +    } else if (e.keyCode == 40) {
                +      // Arrow down.
                +      controller.moveElement(1);
                +    }
                +  });
                +
                +  // Determines if a block breaks shadow block placement rules.
                +  // Breaks rules if (1) a shadow block no longer has a valid
                +  // parent, or (2) a normal block is inside of a shadow block.
                +  var isInvalidBlockPlacement = function(block) {
                +    return ((controller.isUserGenShadowBlock(block.id) &&
                +        !block.getSurroundParent()) ||
                +        (!controller.isUserGenShadowBlock(block.id) &&
                +         block.getSurroundParent() &&
                +         controller.isUserGenShadowBlock(block.getSurroundParent().id)));
                +  };
                +
                +  // Add change listeners for toolbox workspace in workspace factory.
                +  controller.toolboxWorkspace.addChangeListener(function(e) {
                +    // Listen for Blockly move and delete events to update preview.
                +    // Not listening for Blockly create events because causes the user to drop
                +    // blocks when dragging them into workspace. Could cause problems if ever
                +    // load blocks into workspace directly without calling updatePreview.
                +    if (e.type == Blockly.Events.BLOCK_MOVE ||
                +          e.type == Blockly.Events.BLOCK_DELETE ||
                +          e.type == Blockly.Events.BLOCK_CHANGE) {
                +      controller.saveStateFromWorkspace();
                +      controller.updatePreview();
                +    }
                +
                +    // Listen for Blockly UI events to correctly enable the "Edit Block" button.
                +    // Only enable "Edit Block" when a block is selected and it has a
                +    // surrounding parent, meaning it is nested in another block (blocks that
                +    // are not nested in parents cannot be shadow blocks).
                +    if (e.type == Blockly.Events.BLOCK_MOVE || (e.type == Blockly.Events.UI &&
                +        e.element == 'selected')) {
                +      var selected = Blockly.selected;
                +
                +      // Show shadow button if a block is selected. Show "Add Shadow" if
                +      // a block is not a shadow block, show "Remove Shadow" if it is a
                +      // shadow block.
                +      if (selected) {
                +        var isShadow = controller.isUserGenShadowBlock(selected.id);
                +        WorkspaceFactoryInit.displayAddShadow_(!isShadow);
                +        WorkspaceFactoryInit.displayRemoveShadow_(isShadow);
                +      } else {
                +        WorkspaceFactoryInit.displayAddShadow_(false);
                +        WorkspaceFactoryInit.displayRemoveShadow_(false);
                +      }
                +
                +      if (selected != null && selected.getSurroundParent() != null &&
                +          !controller.isUserGenShadowBlock(selected.getSurroundParent().id)) {
                +        // Selected block is a valid shadow block or could be a valid shadow
                +        // block.
                +
                +        // Enable block editing and remove warnings if the block is not a
                +        // variable user-generated shadow block.
                +        document.getElementById('button_addShadow').disabled = false;
                +        document.getElementById('button_removeShadow').disabled = false;
                +
                +        if (!FactoryUtils.hasVariableField(selected) &&
                +            controller.isDefinedBlock(selected)) {
                +          selected.setWarningText(null);
                +        }
                +      } else {
                +        // Selected block cannot be a valid shadow block.
                +
                +        if (selected != null && isInvalidBlockPlacement(selected)) {
                +          // Selected block breaks shadow block rules.
                +          // Invalid shadow block if (1) a shadow block no longer has a valid
                +          // parent, or (2) a normal block is inside of a shadow block.
                +
                +          if (!controller.isUserGenShadowBlock(selected.id)) {
                +            // Warn if a non-shadow block is nested inside a shadow block.
                +            selected.setWarningText('Only shadow blocks can be nested inside\n'
                +                + 'other shadow blocks.');
                +          } else if (!FactoryUtils.hasVariableField(selected)) {
                +            // Warn if a shadow block is invalid only if not replacing
                +            // warning for variables.
                +            selected.setWarningText('Shadow blocks must be nested inside other'
                +                + ' blocks.')
                +          }
                +
                +          // Give editing options so that the user can make an invalid shadow
                +          // block a normal block.
                +          document.getElementById('button_removeShadow').disabled = false;
                +          document.getElementById('button_addShadow').disabled = true;
                +        } else {
                +          // Selected block does not break any shadow block rules, but cannot
                +          // be a shadow block.
                +
                +          // Remove possible 'invalid shadow block placement' warning.
                +          if (selected != null && controller.isDefinedBlock(selected) &&
                +              (!FactoryUtils.hasVariableField(selected) ||
                +              !controller.isUserGenShadowBlock(selected.id))) {
                +            selected.setWarningText(null);
                +          }
                +
                +          // No block selected that is a shadow block or could be a valid shadow
                +          // block. Disable block editing.
                +          document.getElementById('button_addShadow').disabled = true;
                +          document.getElementById('button_removeShadow').disabled = true;
                +        }
                +      }
                +    }
                +
                +    // Convert actual shadow blocks added from the toolbox to user-generated
                +    // shadow blocks.
                +    if (e.type == Blockly.Events.BLOCK_CREATE) {
                +      controller.convertShadowBlocks();
                +
                +      // Let the user create a Variables or Functions category if they use
                +      // blocks from either category.
                +
                +      // Get all children of a block and add them to childList.
                +      var getAllChildren = function(block, childList) {
                +        childList.push(block);
                +        var children = block.getChildren();
                +        for (var i = 0, child; child = children[i]; i++) {
                +          getAllChildren(child, childList);
                +        }
                +      };
                +
                +      var newBaseBlock = controller.toolboxWorkspace.getBlockById(e.blockId);
                +      var allNewBlocks = [];
                +      getAllChildren(newBaseBlock, allNewBlocks);
                +      var variableCreated = false;
                +      var procedureCreated = false;
                +
                +      // Check if the newly created block or any of its children are variable
                +      // or procedure blocks.
                +      for (var i = 0, block; block = allNewBlocks[i]; i++) {
                +        if (FactoryUtils.hasVariableField(block)) {
                +          variableCreated = true;
                +        } else if (FactoryUtils.isProcedureBlock(block)) {
                +          procedureCreated = true;
                +        }
                +      }
                +
                +      // If any of the newly created blocks are variable or procedure blocks,
                +      // prompt the user to create the corresponding standard category.
                +      if (variableCreated && !controller.hasVariablesCategory()) {
                +        if (confirm('Your new block has a variables field. To use this block '
                +            + 'fully, you will need a Variables category. Do you want to add '
                +            + 'a Variables category to your custom toolbox?')) {
                +          controller.setMode(WorkspaceFactoryController.MODE_TOOLBOX);
                +          controller.loadCategoryByName('variables');
                +        }
                +      }
                +
                +      if (procedureCreated && !controller.hasProceduresCategory()) {
                +        if (confirm('Your new block is a function block. To use this block '
                +            + 'fully, you will need a Functions category. Do you want to add '
                +            + 'a Functions category to your custom toolbox?')) {
                +          controller.setMode(WorkspaceFactoryController.MODE_TOOLBOX);
                +          controller.loadCategoryByName('functions');
                +        }
                +      }
                +    }
                +  });
                +};
                +
                +/**
                + * Display or hide the add shadow button.
                + * @param {boolean} show True if the add shadow button should be shown, false
                + *    otherwise.
                + */
                +WorkspaceFactoryInit.displayAddShadow_ = function(show) {
                +  document.getElementById('button_addShadow').style.display =
                +      show ? 'inline-block' : 'none';
                +};
                +
                +/**
                + * Display or hide the remove shadow button.
                + * @param {boolean} show True if the remove shadow button should be shown, false
                + *    otherwise.
                + */
                +WorkspaceFactoryInit.displayRemoveShadow_ = function(show) {
                +  document.getElementById('button_removeShadow').style.display =
                +      show ? 'inline-block' : 'none';
                +};
                +
                +/**
                + * Add listeners for workspace factory options input elements.
                + * @param {!FactoryController} controller The controller for the workspace
                + *    factory tab.
                + * @private
                + */
                +WorkspaceFactoryInit.addWorkspaceFactoryOptionsListeners_ =
                +    function(controller) {
                +  // Checking the grid checkbox displays grid options.
                +  document.getElementById('option_grid_checkbox').addEventListener('change',
                +      function(e) {
                +        document.getElementById('grid_options').style.display =
                +            document.getElementById('option_grid_checkbox').checked ?
                +            'block' : 'none';
                +      });
                +
                +  // Checking the zoom checkbox displays zoom options.
                +  document.getElementById('option_zoom_checkbox').addEventListener('change',
                +      function(e) {
                +        document.getElementById('zoom_options').style.display =
                +            document.getElementById('option_zoom_checkbox').checked ?
                +            'block' : 'none';
                +      });
                +
                +  // Checking the readonly checkbox enables/disables other options.
                +  document.getElementById('option_readOnly_checkbox').addEventListener('change',
                +    function(e) {
                +      var checkbox = document.getElementById('option_readOnly_checkbox');
                +      blocklyFactory.ifCheckedEnable(!checkbox.checked,
                +          ['readonly1', 'readonly2']);
                +    });
                +
                +    document.getElementById('option_infiniteBlocks_checkbox').addEventListener('change',
                +    function(e) {
                +      document.getElementById('maxBlockNumber_option').style.display =
                +          document.getElementById('option_infiniteBlocks_checkbox').checked ?
                +            'none' : 'block';
                +    });
                +
                +  // Generate new options every time an options input is updated.
                +  var div = document.getElementById('workspace_options');
                +  var options = div.getElementsByTagName('input');
                +  for (var i = 0, option; option = options[i]; i++) {
                +    option.addEventListener('change', function() {
                +      controller.generateNewOptions();
                +    });
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_model.js b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_model.js
                new file mode 100644
                index 000000000..7b60810d3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_model.js
                @@ -0,0 +1,563 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Stores and updates information about state and categories
                + * in workspace factory. Each list element is either a separator or a category,
                + * and each category stores its name, XML to load that category, color,
                + * custom tags, and a unique ID making it possible to change category names and
                + * move categories easily. Keeps track of the currently selected list
                + * element. Also keeps track of all the user-created shadow blocks and
                + * manipulates them as necessary.
                + *
                + * @author Emma Dauterman (evd2014)
                + */
                +
                +/**
                + * Class for a WorkspaceFactoryModel
                + * @constructor
                + */
                +WorkspaceFactoryModel = function() {
                +  // Ordered list of ListElement objects. Empty if there is a single flyout.
                +  this.toolboxList = [];
                +  // ListElement for blocks in a single flyout. Null if a toolbox exists.
                +  this.flyout = new ListElement(ListElement.TYPE_FLYOUT);
                +  // Array of block IDs for all user created shadow blocks.
                +  this.shadowBlocks = [];
                +  // Reference to currently selected ListElement. Stored in this.toolboxList if
                +  // there are categories, or in this.flyout if blocks are displayed in a single
                +  // flyout.
                +  this.selected = this.flyout;
                +  // Boolean for if a Variable category has been added.
                +  this.hasVariableCategory = false;
                +  // Boolean for if a Procedure category has been added.
                +  this.hasProcedureCategory = false;
                +  // XML to be pre-loaded to workspace. Empty on default;
                +  this.preloadXml = Blockly.Xml.textToDom('<xml></xml>');
                +  // Options object to be configured for Blockly inject call.
                +  this.options = new Object(null);
                +  // Block Library block types.
                +  this.libBlockTypes = [];
                +  // Imported block types.
                +  this.importedBlockTypes = [];
                +  //
                +};
                +
                +/**
                + * Given a name, determines if it is the name of a category already present.
                + * Used when getting a valid category name from the user.
                + * @param {string} name String name to be compared against.
                + * @return {boolean} True if string is a used category name, false otherwise.
                + */
                +WorkspaceFactoryModel.prototype.hasCategoryByName = function(name) {
                +  for (var i = 0; i < this.toolboxList.length; i++) {
                +    if (this.toolboxList[i].type == ListElement.TYPE_CATEGORY &&
                +        this.toolboxList[i].name == name) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Determines if a category with the 'VARIABLE' tag exists.
                + * @return {boolean} True if there exists a category with the Variables tag,
                + * false otherwise.
                + */
                +WorkspaceFactoryModel.prototype.hasVariables = function() {
                +  return this.hasVariableCategory;
                +};
                +
                +/**
                + * Determines if a category with the 'PROCEDURE' tag exists.
                + * @return {boolean} True if there exists a category with the Procedures tag,
                + * false otherwise.
                + */
                +WorkspaceFactoryModel.prototype.hasProcedures = function() {
                +  return this.hasProcedureCategory;
                +};
                +
                +/**
                + * Determines if the user has any elements in the toolbox. Uses the length of
                + * toolboxList.
                + * @return {boolean} True if elements exist, false otherwise.
                + */
                +WorkspaceFactoryModel.prototype.hasElements = function() {
                +  return this.toolboxList.length > 0;
                +};
                +
                +/**
                + * Given a ListElement, adds it to the toolbox list.
                + * @param {!ListElement} element The element to be added to the list.
                + */
                +WorkspaceFactoryModel.prototype.addElementToList = function(element) {
                +  // Update state if the copied category has a custom tag.
                +  this.hasVariableCategory = element.custom == 'VARIABLE' ? true :
                +      this.hasVariableCategory;
                +  this.hasProcedureCategory = element.custom == 'PROCEDURE' ? true :
                +      this.hasProcedureCategory;
                +  // Add element to toolboxList.
                +  this.toolboxList.push(element);
                +  // Empty single flyout.
                +  this.flyout = null;
                +};
                +
                +/**
                + * Given an index, deletes a list element and all associated data.
                + * @param {number} index The index of the list element to delete.
                + */
                +WorkspaceFactoryModel.prototype.deleteElementFromList = function(index) {
                +  // Check if index is out of bounds.
                +  if (index < 0 || index >= this.toolboxList.length) {
                +    return; // No entry to delete.
                +  }
                +  // Check if need to update flags.
                +  this.hasVariableCategory = this.toolboxList[index].custom == 'VARIABLE' ?
                +      false : this.hasVariableCategory;
                +  this.hasProcedureCategory = this.toolboxList[index].custom == 'PROCEDURE' ?
                +      false : this.hasProcedureCategory;
                +  // Remove element.
                +  this.toolboxList.splice(index, 1);
                +};
                +
                +/**
                + * Sets selected to be an empty category not in toolbox list if toolbox list
                + * is empty. Should be called when removing the last element from toolbox list.
                + * If the toolbox list is empty, selected stores the XML for the single flyout
                + * of blocks displayed.
                + */
                +WorkspaceFactoryModel.prototype.createDefaultSelectedIfEmpty = function() {
                +  if (this.toolboxList.length == 0) {
                +    this.flyout = new ListElement(ListElement.TYPE_FLYOUT);
                +    this.selected = this.flyout;
                +  }
                +};
                +
                +/**
                + * Moves a list element to a certain position in toolboxList by removing it
                + * and then inserting it at the correct index. Checks that indices are in
                + * bounds (throws error if not), but assumes that oldIndex is the correct index
                + * for list element.
                + * @param {!ListElement} element The element to move in toolboxList.
                + * @param {number} newIndex The index to insert the element at.
                + * @param {number} oldIndex The index the element is currently at.
                + */
                +WorkspaceFactoryModel.prototype.moveElementToIndex = function(element, newIndex,
                +    oldIndex) {
                +  // Check that indexes are in bounds.
                +  if (newIndex < 0 || newIndex >= this.toolboxList.length || oldIndex < 0 ||
                +      oldIndex >= this.toolboxList.length) {
                +    throw new Error('Index out of bounds when moving element in the model.');
                +  }
                +  this.deleteElementFromList(oldIndex);
                +  this.toolboxList.splice(newIndex, 0, element);
                +};
                +
                +/**
                + * Returns the ID of the currently selected element. Returns null if there are
                + * no categories (if selected == null).
                + * @return {string} The ID of the element currently selected.
                + */
                +WorkspaceFactoryModel.prototype.getSelectedId = function() {
                +  return this.selected ? this.selected.id : null;
                +};
                +
                +/**
                + * Returns the name of the currently selected category. Returns null if there
                + * are no categories (if selected == null) or the selected element is not
                + * a category (in which case its name is null).
                + * @return {string} The name of the category currently selected.
                + */
                +WorkspaceFactoryModel.prototype.getSelectedName = function() {
                +  return this.selected ? this.selected.name : null;
                +};
                +
                +/**
                + * Returns the currently selected list element object.
                + * @return {ListElement} The currently selected ListElement
                + */
                +WorkspaceFactoryModel.prototype.getSelected = function() {
                +  return this.selected;
                +};
                +
                +/**
                + * Sets list element currently selected by id.
                + * @param {string} id ID of list element that should now be selected.
                + */
                +WorkspaceFactoryModel.prototype.setSelectedById = function(id) {
                +  this.selected = this.getElementById(id);
                +};
                +
                +/**
                + * Given an ID of a list element, returns the index of that list element in
                + * toolboxList. Returns -1 if ID is not present.
                + * @param {string} id The ID of list element to search for.
                + * @return {number} The index of the list element in toolboxList, or -1 if it
                + * doesn't exist.
                + */
                +WorkspaceFactoryModel.prototype.getIndexByElementId = function(id) {
                +  for (var i = 0; i < this.toolboxList.length; i++) {
                +    if (this.toolboxList[i].id == id) {
                +      return i;
                +    }
                +  }
                +  return -1;  // ID not present in toolboxList.
                +};
                +
                +/**
                + * Given the ID of a list element, returns that ListElement object.
                + * @param {string} id The ID of element to search for.
                + * @return {ListElement} Corresponding ListElement object in toolboxList, or
                + *     null if that element does not exist.
                + */
                +WorkspaceFactoryModel.prototype.getElementById = function(id) {
                +  for (var i = 0; i < this.toolboxList.length; i++) {
                +    if (this.toolboxList[i].id == id) {
                +      return this.toolboxList[i];
                +    }
                +  }
                +  return null;  // ID not present in toolboxList.
                +};
                +
                +/**
                + * Given the index of a list element in toolboxList, returns that ListElement
                + * object.
                + * @param {number} index The index of the element to return.
                + * @return {ListElement} The corresponding ListElement object in toolboxList.
                + */
                +WorkspaceFactoryModel.prototype.getElementByIndex = function(index) {
                +  if (index < 0 || index >= this.toolboxList.length) {
                +    return null;
                +  }
                +  return this.toolboxList[index];
                +};
                +
                +/**
                + * Returns the XML to load the selected element.
                + * @return {!Element} The XML of the selected element, or null if there is
                + * no selected element.
                + */
                +WorkspaceFactoryModel.prototype.getSelectedXml = function() {
                +  return this.selected ? this.selected.xml : null;
                +};
                +
                +/**
                + * Return ordered list of ListElement objects.
                + * @return {!Array.<!ListElement>} ordered list of ListElement objects
                + */
                +WorkspaceFactoryModel.prototype.getToolboxList = function() {
                +  return this.toolboxList;
                +};
                +
                +/**
                + * Gets the ID of a category given its name.
                + * @param {string} name Name of category.
                + * @return {number} ID of category
                + */
                +WorkspaceFactoryModel.prototype.getCategoryIdByName = function(name) {
                +  for (var i = 0; i < this.toolboxList.length; i++) {
                +    if (this.toolboxList[i].name == name) {
                +      return this.toolboxList[i].id;
                +    }
                +  }
                +  return null;  // Name not present in toolboxList.
                +};
                +
                +/**
                + * Clears the toolbox list, deleting all ListElements.
                + */
                +WorkspaceFactoryModel.prototype.clearToolboxList = function() {
                +  this.toolboxList = [];
                +  this.hasVariableCategory = false;
                +  this.hasProcedureCategory = false;
                +  this.shadowBlocks = [];
                +  this.selected.xml = Blockly.Xml.textToDom('<xml></xml>');
                +};
                +
                +/**
                + * Class for a ListElement
                + * Adds a shadow block to the list of shadow blocks.
                + * @param {string} blockId The unique ID of block to be added.
                + */
                +WorkspaceFactoryModel.prototype.addShadowBlock = function(blockId) {
                +  this.shadowBlocks.push(blockId);
                +};
                +
                +/**
                + * Removes a shadow block ID from the list of shadow block IDs if that ID is
                + * in the list.
                + * @param {string} blockId The unique ID of block to be removed.
                + */
                +WorkspaceFactoryModel.prototype.removeShadowBlock = function(blockId) {
                +  for (var i = 0; i < this.shadowBlocks.length; i++) {
                +    if (this.shadowBlocks[i] == blockId) {
                +      this.shadowBlocks.splice(i, 1);
                +      return;
                +    }
                +  }
                +};
                +
                +/**
                + * Determines if a block is a shadow block given a unique block ID.
                + * @param {string} blockId The unique ID of the block to examine.
                + * @return {boolean} True if the block is a user-generated shadow block, false
                + *    otherwise.
                + */
                +WorkspaceFactoryModel.prototype.isShadowBlock = function(blockId) {
                +  for (var i = 0; i < this.shadowBlocks.length; i++) {
                +    if (this.shadowBlocks[i] == blockId) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Given a set of blocks currently loaded, returns all blocks in the workspace
                + * that are user generated shadow blocks.
                + * @param {!<Blockly.Block>} blocks Array of blocks currently loaded.
                + * @return {!<Blockly.Block>} Array of user-generated shadow blocks currently
                + *   loaded.
                + */
                +WorkspaceFactoryModel.prototype.getShadowBlocksInWorkspace =
                +    function(workspaceBlocks) {
                +  var shadowsInWorkspace = [];
                +  for (var i = 0; i < workspaceBlocks.length; i++) {
                +    if (this.isShadowBlock(workspaceBlocks[i].id)) {
                +      shadowsInWorkspace.push(workspaceBlocks[i]);
                +    }
                +  }
                +  return shadowsInWorkspace;
                +};
                +
                +/**
                + * Adds a custom tag to a category, updating state variables accordingly.
                + * Only accepts 'VARIABLE' and 'PROCEDURE' tags.
                + * @param {!ListElement} category The category to add the tag to.
                + * @param {string} tag The custom tag to add to the category.
                + */
                +WorkspaceFactoryModel.prototype.addCustomTag = function(category, tag) {
                +  // Only update list elements that are categories.
                +  if (category.type != ListElement.TYPE_CATEGORY) {
                +    return;
                +  }
                +  // Only update the tag to be 'VARIABLE' or 'PROCEDURE'.
                +  if (tag == 'VARIABLE') {
                +    this.hasVariableCategory = true;
                +    category.custom = 'VARIABLE';
                +  } else if (tag == 'PROCEDURE') {
                +    this.hasProcedureCategory = true;
                +    category.custom = 'PROCEDURE';
                +  }
                +};
                +
                +/**
                + * Have basic pre-loaded workspace working
                + * Saves XML as XML to be pre-loaded into the workspace.
                + * @param {!Element} xml The XML to be saved.
                + */
                +WorkspaceFactoryModel.prototype.savePreloadXml = function(xml) {
                +  this.preloadXml = xml
                +};
                +
                +/**
                + * Gets the XML to be pre-loaded into the workspace.
                + * @return {!Element} The XML for the workspace.
                + */
                +WorkspaceFactoryModel.prototype.getPreloadXml = function() {
                +  return this.preloadXml;
                +};
                +
                +/**
                + * Sets a new options object for injecting a Blockly workspace.
                + * @param {Object} options Options object for injecting a Blockly workspace.
                + */
                +WorkspaceFactoryModel.prototype.setOptions = function(options) {
                +  this.options = options;
                +};
                +
                +/*
                + * Returns an array of all the block types currently being used in the toolbox
                + * and the pre-loaded blocks. No duplicates.
                + * TODO(evd2014): Move pushBlockTypesToList to FactoryUtils.
                + * @return {!Array.<string>} Array of block types currently being used.
                + */
                +WorkspaceFactoryModel.prototype.getAllUsedBlockTypes = function() {
                +  var blockTypeList = [];
                +
                +  // Given XML for the workspace, adds all block types included in the XML
                +  // to the list, not including duplicates.
                +  var pushBlockTypesToList = function(xml, list) {
                +    // Get all block XML nodes.
                +    var blocks = xml.getElementsByTagName('block');
                +
                +    // Add block types if not already in list.
                +    for (var i = 0; i < blocks.length; i++) {
                +      var type = blocks[i].getAttribute('type');
                +      if (list.indexOf(type) == -1) {
                +        list.push(type);
                +      }
                +    }
                +  };
                +
                +  if (this.flyout) {
                +    // If has a single flyout, add block types for the single flyout.
                +    pushBlockTypesToList(this.getSelectedXml(), blockTypeList);
                +  } else {
                +    // If has categories, add block types for each category.
                +
                +    for (var i = 0, category; category = this.toolboxList[i]; i++) {
                +      if (category.type == ListElement.TYPE_CATEGORY) {
                +        pushBlockTypesToList(category.xml, blockTypeList);
                +      }
                +    }
                +  }
                +
                +  // Add the block types from any pre-loaded blocks.
                +  pushBlockTypesToList(this.getPreloadXml(), blockTypeList);
                +
                +  return blockTypeList;
                +};
                +
                +/**
                + * Adds new imported block types to the list of current imported block types.
                + * @param {!Array.<string>} blockTypes Array of block types imported.
                + */
                +WorkspaceFactoryModel.prototype.addImportedBlockTypes = function(blockTypes) {
                +  this.importedBlockTypes = this.importedBlockTypes.concat(blockTypes);
                +};
                +
                +/**
                + * Updates block types in block library.
                + * @param {!Array.<string>} blockTypes Array of block types in block library.
                + */
                +WorkspaceFactoryModel.prototype.updateLibBlockTypes = function(blockTypes) {
                +  this.libBlockTypes = blockTypes;
                +};
                +
                +/**
                + * Determines if a block type is defined as a standard block, in the block
                + * library, or as an imported block.
                + * @param {string} blockType Block type to check.
                + * @return {boolean} True if blockType is defined, false otherwise.
                + */
                +WorkspaceFactoryModel.prototype.isDefinedBlockType = function(blockType) {
                +  var isStandardBlock = StandardCategories.coreBlockTypes.indexOf(blockType)
                +      != -1;
                +  var isLibBlock = this.libBlockTypes.indexOf(blockType) != -1;
                +  var isImportedBlock = this.importedBlockTypes.indexOf(blockType) != -1;
                +  return (isStandardBlock || isLibBlock || isImportedBlock);
                +};
                +
                +/**
                + * Checks if any of the block types are already defined.
                + * @param {!Array.<string>} blockTypes Array of block types.
                + * @return {boolean} True if a block type in the array is already defined,
                + *    false if none of the blocks are already defined.
                + */
                +WorkspaceFactoryModel.prototype.hasDefinedBlockTypes = function(blockTypes) {
                +  for (var i = 0, blockType; blockType = blockTypes[i]; i++) {
                +    if (this.isDefinedBlockType(blockType)) {
                +      return true;
                +    }
                +  }
                +  return false;
                +};
                +
                +/**
                + * Class for a ListElement.
                + * @constructor
                + */
                +ListElement = function(type, opt_name) {
                +  this.type = type;
                +  // XML DOM element to load the element.
                +  this.xml = Blockly.Xml.textToDom('<xml></xml>');
                +  // Name of category. Can be changed by user. Null if separator.
                +  this.name = opt_name ? opt_name : null;
                +  // Unique ID of element. Does not change.
                +  this.id = Blockly.utils.genUid();
                +  // Color of category. Default is no color. Null if separator.
                +  this.color = null;
                +  // Stores a custom tag, if necessary. Null if no custom tag or separator.
                +  this.custom = null;
                +};
                +
                +// List element types.
                +ListElement.TYPE_CATEGORY = 'category';
                +ListElement.TYPE_SEPARATOR = 'separator';
                +ListElement.TYPE_FLYOUT = 'flyout';
                +
                +/**
                + * Saves a category by updating its XML (does not save XML for
                + * elements that are not categories).
                + * @param {!Blockly.workspace} workspace The workspace to save category entry
                + * from.
                + */
                +ListElement.prototype.saveFromWorkspace = function(workspace) {
                +  // Only save XML for categories and flyouts.
                +  if (this.type == ListElement.TYPE_FLYOUT ||
                +      this.type == ListElement.TYPE_CATEGORY) {
                +    this.xml = Blockly.Xml.workspaceToDom(workspace);
                +  }
                +};
                +
                +
                +/**
                + * Changes the name of a category object given a new name. Returns if
                + * not a category.
                + * @param {string} name New name of category.
                + */
                +ListElement.prototype.changeName = function (name) {
                +  // Only update list elements that are categories.
                +  if (this.type != ListElement.TYPE_CATEGORY) {
                +    return;
                +  }
                +  this.name = name;
                +};
                +
                +/**
                + * Sets the color of a category. If tries to set the color of something other
                + * than a category, returns.
                + * @param {string} color The color that should be used for that category.
                + */
                +ListElement.prototype.changeColor = function (color) {
                +  if (this.type != ListElement.TYPE_CATEGORY) {
                +    return;
                +  }
                +  this.color = color;
                +};
                +
                +/**
                + * Makes a copy of the original element and returns it. Everything about the
                + * copy is identical except for its ID.
                + * @return {!ListElement} The copy of the ListElement.
                + */
                +ListElement.prototype.copy = function() {
                +  copy = new ListElement(this.type);
                +  // Generate a unique ID for the element.
                +  copy.id = Blockly.utils.genUid();
                +  // Copy all attributes except ID.
                +  copy.name = this.name;
                +  copy.xml = this.xml;
                +  copy.color = this.color;
                +  copy.custom = this.custom;
                +  // Return copy.
                +  return copy;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_view.js b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_view.js
                new file mode 100644
                index 000000000..bf7463eb9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory/workspacefactory/wfactory_view.js
                @@ -0,0 +1,436 @@
                +/**
                + * @license
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * Controls the UI elements for workspace factory, mainly the category tabs.
                + * Also includes downloading files because that interacts directly with the DOM.
                + * Depends on WorkspaceFactoryController (for adding mouse listeners). Tabs for
                + * each category are stored in tab map, which associates a unique ID for a
                + * category with a particular tab.
                + *
                + * @author Emma Dauterman (edauterman)
                + */
                +
                +goog.require('FactoryUtils');
                +
                +/**
                + * Class for a WorkspaceFactoryView
                + * @constructor
                + */
                +WorkspaceFactoryView = function() {
                +  // For each tab, maps ID of a ListElement to the td DOM element.
                +  this.tabMap = Object.create(null);
                +};
                +
                +/**
                + * Adds a category tab to the UI, and updates tabMap accordingly.
                + * @param {string} name The name of the category being created
                + * @param {string} id ID of category being created
                + * @return {!Element} DOM element created for tab
                + */
                +WorkspaceFactoryView.prototype.addCategoryRow = function(name, id) {
                +  var table = document.getElementById('categoryTable');
                +  var count = table.rows.length;
                +
                +  // Delete help label and enable category buttons if it's the first category.
                +  if (count == 0) {
                +    document.getElementById('categoryHeader').textContent = 'Your categories:';
                +  }
                +
                +  // Create tab.
                +  var row = table.insertRow(count);
                +  var nextEntry = row.insertCell(0);
                +  // Configure tab.
                +  nextEntry.id = this.createCategoryIdName(name);
                +  nextEntry.textContent = name;
                +  // Store tab.
                +  this.tabMap[id] = table.rows[count].cells[0];
                +  // Return tab.
                +  return nextEntry;
                +};
                +
                +/**
                + * Deletes a category tab from the UI and updates tabMap accordingly.
                + * @param {string} id ID of category to be deleted.
                + * @param {string} name The name of the category to be deleted.
                + */
                +WorkspaceFactoryView.prototype.deleteElementRow = function(id, index) {
                +  // Delete tab entry.
                +  delete this.tabMap[id];
                +  // Delete tab row.
                +  var table = document.getElementById('categoryTable');
                +  var count = table.rows.length;
                +  table.deleteRow(index);
                +
                +  // If last category removed, add category help text and disable category
                +  // buttons.
                +  this.addEmptyCategoryMessage();
                +};
                +
                +/**
                + * If there are no toolbox elements created, adds a help message to show
                + * where categories will appear. Should be called when deleting list elements
                + * in case the last element is deleted.
                + */
                +WorkspaceFactoryView.prototype.addEmptyCategoryMessage = function() {
                +  var table = document.getElementById('categoryTable');
                +  if (!table.rows.length) {
                +    document.getElementById('categoryHeader').textContent =
                +        'You currently have no categories.';
                +  }
                +};
                +
                +/**
                + * Given the index of the currently selected element, updates the state of
                + * the buttons that allow the user to edit the list elements. Updates the edit
                + * and arrow buttons. Should be called when adding or removing elements
                + * or when changing to a new element or when swapping to a different element.
                + * TODO(evd2014): Switch to using CSS to add/remove styles.
                + * @param {number} selectedIndex The index of the currently selected category,
                + *   -1 if no categories created.
                + * @param {ListElement} selected The selected ListElement.
                + */
                +WorkspaceFactoryView.prototype.updateState = function(selectedIndex, selected) {
                +  // Disable/enable editing buttons as necessary.
                +  document.getElementById('button_editCategory').disabled = selectedIndex < 0 ||
                +      selected.type != ListElement.TYPE_CATEGORY;
                +  document.getElementById('button_remove').disabled = selectedIndex < 0;
                +  document.getElementById('button_up').disabled = selectedIndex <= 0;
                +  var table = document.getElementById('categoryTable');
                +  document.getElementById('button_down').disabled = selectedIndex >=
                +      table.rows.length - 1 || selectedIndex < 0;
                +  // Disable/enable the workspace as necessary.
                +  this.disableWorkspace(this.shouldDisableWorkspace(selected));
                +};
                +
                +/**
                + * Determines the DOM ID for a category given its name.
                + * @param {string} name Name of category
                + * @return {string} ID of category tab
                + */
                +WorkspaceFactoryView.prototype.createCategoryIdName = function(name) {
                +  return 'tab_' + name;
                +};
                +
                +/**
                + * Switches a tab on or off.
                + * @param {string} id ID of the tab to switch on or off.
                + * @param {boolean} selected True if tab should be on, false if tab should be
                + * off.
                + */
                +WorkspaceFactoryView.prototype.setCategoryTabSelection =
                +    function(id, selected) {
                +  if (!this.tabMap[id]) {
                +    return;   // Exit if tab does not exist.
                +  }
                +  this.tabMap[id].className = selected ? 'tabon' : 'taboff';
                +};
                +
                +/**
                + * Used to bind a click to a certain DOM element (used for category tabs).
                + * Taken directly from code.js
                + * @param {string|!Element} e1 Tab element or corresponding ID string.
                + * @param {!Function} func Function to be executed on click.
                + */
                +WorkspaceFactoryView.prototype.bindClick = function(el, func) {
                +  if (typeof el == 'string') {
                +    el = document.getElementById(el);
                +  }
                +  el.addEventListener('click', func, true);
                +  el.addEventListener('touchend', func, true);
                +};
                +
                +/**
                + * Creates a file and downloads it. In some browsers downloads, and in other
                + * browsers, opens new tab with contents.
                + * @param {string} filename Name of file
                + * @param {!Blob} data Blob containing contents to download
                + */
                +WorkspaceFactoryView.prototype.createAndDownloadFile =
                +    function(filename, data) {
                +  var clickEvent = new MouseEvent('click', {
                +    'view': window,
                +    'bubbles': true,
                +    'cancelable': false
                +  });
                +  var a = document.createElement('a');
                +  a.href = window.URL.createObjectURL(data);
                +  a.download = filename;
                +  a.textContent = 'Download file!';
                +  a.dispatchEvent(clickEvent);
                +};
                +
                +/**
                + * Given the ID of a certain category, updates the corresponding tab in
                + * the DOM to show a new name.
                + * @param {string} newName Name of string to be displayed on tab
                + * @param {string} id ID of category to be updated
                + */
                +WorkspaceFactoryView.prototype.updateCategoryName = function(newName, id) {
                +  this.tabMap[id].textContent = newName;
                +  this.tabMap[id].id = this.createCategoryIdName(newName);
                +};
                +
                +/**
                + * Moves a tab from one index to another. Adjusts index inserting before
                + * based on if inserting before or after. Checks that the indexes are in
                + * bounds, throws error if not.
                + * @param {string} id The ID of the category to move.
                + * @param {number} newIndex The index to move the category to.
                + * @param {number} oldIndex The index the category is currently at.
                + */
                +WorkspaceFactoryView.prototype.moveTabToIndex =
                +    function(id, newIndex, oldIndex) {
                +  var table = document.getElementById('categoryTable');
                +  // Check that indexes are in bounds.
                +  if (newIndex < 0 || newIndex >= table.rows.length || oldIndex < 0 ||
                +      oldIndex >= table.rows.length) {
                +    throw new Error('Index out of bounds when moving tab in the view.');
                +  }
                +
                +  if (newIndex < oldIndex) {
                +    // Inserting before.
                +    var row = table.insertRow(newIndex);
                +    row.appendChild(this.tabMap[id]);
                +    table.deleteRow(oldIndex + 1);
                +  } else {
                +    // Inserting after.
                +    var row = table.insertRow(newIndex + 1);
                +    row.appendChild(this.tabMap[id]);
                +    table.deleteRow(oldIndex);
                +  }
                +};
                +
                +/**
                + * Given a category ID and color, use that color to color the left border of the
                + * tab for that category.
                + * @param {string} id The ID of the category to color.
                + * @param {string} color The color for to be used for the border of the tab.
                + * Must be a valid CSS string.
                + */
                +WorkspaceFactoryView.prototype.setBorderColor = function(id, color) {
                +  var tab = this.tabMap[id];
                +  tab.style.borderLeftWidth = '8px';
                +  tab.style.borderLeftStyle = 'solid';
                +  tab.style.borderColor = color;
                +};
                +
                +/**
                + * Given a separator ID, creates a corresponding tab in the view, updates
                + * tab map, and returns the tab.
                + * @param {string} id The ID of the separator.
                + * @param {!Element} The td DOM element representing the separator.
                + */
                +WorkspaceFactoryView.prototype.addSeparatorTab = function(id) {
                +  var table = document.getElementById('categoryTable');
                +  var count = table.rows.length;
                +
                +  if (count == 0) {
                +    document.getElementById('categoryHeader').textContent = 'Your categories:';
                +  }
                +  // Create separator.
                +  var row = table.insertRow(count);
                +  var nextEntry = row.insertCell(0);
                +  // Configure separator.
                +  nextEntry.style.height = '10px';
                +  // Store and return separator.
                +  this.tabMap[id] = table.rows[count].cells[0];
                +  return nextEntry;
                +};
                +
                +/**
                + * Disables or enables the workspace by putting a div over or under the
                + * toolbox workspace, depending on the value of disable. Used when switching
                + * to/from separators where the user shouldn't be able to drag blocks into
                + * the workspace.
                + * @param {boolean} disable True if the workspace should be disabled, false
                + * if it should be enabled.
                + */
                +WorkspaceFactoryView.prototype.disableWorkspace = function(disable) {
                +  if (disable) {
                +    document.getElementById('toolbox_section').className = 'disabled';
                +    document.getElementById('toolbox_blocks').style.pointerEvents = 'none';
                +  } else {
                +    document.getElementById('toolbox_section').className = '';
                +    document.getElementById('toolbox_blocks').style.pointerEvents = 'auto';
                +  }
                +
                +};
                +
                +/**
                + * Determines if the workspace should be disabled. The workspace should be
                + * disabled if category is a separator or has VARIABLE or PROCEDURE tags.
                + * @return {boolean} True if the workspace should be disabled, false otherwise.
                + */
                +WorkspaceFactoryView.prototype.shouldDisableWorkspace = function(category) {
                +  return category != null && category.type != ListElement.TYPE_FLYOUT &&
                +      (category.type == ListElement.TYPE_SEPARATOR ||
                +      category.custom == 'VARIABLE' || category.custom == 'PROCEDURE');
                +};
                +
                +/**
                + * Removes all categories and separators in the view. Clears the tabMap to
                + * reflect this.
                + */
                +WorkspaceFactoryView.prototype.clearToolboxTabs = function() {
                +  this.tabMap = [];
                +  var oldCategoryTable = document.getElementById('categoryTable');
                +  var newCategoryTable = document.createElement('table');
                +  newCategoryTable.id = 'categoryTable';
                +  newCategoryTable.style.width = 'auto';
                +  oldCategoryTable.parentElement.replaceChild(newCategoryTable,
                +      oldCategoryTable);
                +};
                +
                +/**
                + * Given a set of blocks currently loaded user-generated shadow blocks, visually
                + * marks them without making them actual shadow blocks (allowing them to still
                + * be editable and movable).
                + * @param {!Array.<!Blockly.Block>} blocks Array of user-generated shadow blocks
                + * currently loaded.
                + */
                +WorkspaceFactoryView.prototype.markShadowBlocks = function(blocks) {
                +  for (var i = 0; i < blocks.length; i++) {
                +    this.markShadowBlock(blocks[i]);
                +  }
                +};
                +
                +/**
                + * Visually marks a user-generated shadow block as a shadow block in the
                + * workspace without making the block an actual shadow block (allowing it
                + * to be moved and edited).
                + * @param {!Blockly.Block} block The block that should be marked as a shadow
                + *   block (must be rendered).
                + */
                +WorkspaceFactoryView.prototype.markShadowBlock = function(block) {
                +  // Add Blockly CSS for user-generated shadow blocks.
                +  Blockly.utils.addClass(block.svgGroup_, 'shadowBlock');
                +  // If not a valid shadow block, add a warning message.
                +  if (!block.getSurroundParent()) {
                +      block.setWarningText('Shadow blocks must be nested inside' +
                +          ' other blocks to be displayed.');
                +  }
                +  if (FactoryUtils.hasVariableField(block)) {
                +    block.setWarningText('Cannot make variable blocks shadow blocks.');
                +  }
                +};
                +
                +/**
                + * Removes visual marking for a shadow block given a rendered block.
                + * @param {!Blockly.Block} block The block that should be unmarked as a shadow
                + *   block (must be rendered).
                + */
                +WorkspaceFactoryView.prototype.unmarkShadowBlock = function(block) {
                +  // Remove Blockly CSS for user-generated shadow blocks.
                +  Blockly.utils.removeClass(block.svgGroup_, 'shadowBlock');
                +};
                +
                +/**
                + * Sets the tabs for modes according to which mode the user is currenly
                + * editing in.
                + * @param {string} mode The mode being switched to
                + *   (WorkspaceFactoryController.MODE_TOOLBOX or WorkspaceFactoryController.MODE_PRELOAD).
                + */
                +WorkspaceFactoryView.prototype.setModeSelection = function(mode) {
                +  document.getElementById('tab_preload').className = mode ==
                +      WorkspaceFactoryController.MODE_PRELOAD ? 'tabon' : 'taboff';
                +  document.getElementById('preload_div').style.display = mode ==
                +      WorkspaceFactoryController.MODE_PRELOAD ? 'block' : 'none';
                +  document.getElementById('tab_toolbox').className = mode ==
                +      WorkspaceFactoryController.MODE_TOOLBOX ? 'tabon' : 'taboff';
                +  document.getElementById('toolbox_div').style.display = mode ==
                +      WorkspaceFactoryController.MODE_TOOLBOX ? 'block' : 'none';
                +};
                +
                +/**
                + * Updates the help text above the workspace depending on the selected mode.
                + * @param {string} mode The selected mode (WorkspaceFactoryController.MODE_TOOLBOX or
                + *   WorkspaceFactoryController.MODE_PRELOAD).
                + */
                +WorkspaceFactoryView.prototype.updateHelpText = function(mode) {
                +  if (mode == WorkspaceFactoryController.MODE_TOOLBOX) {
                +    var helpText = 'Drag blocks into the workspace to configure the toolbox ' +
                +        'in your custom workspace.';
                +  } else {
                +    var helpText = 'Drag blocks into the workspace to pre-load them in your ' +
                +        'custom workspace.'
                +  }
                +  document.getElementById('editHelpText').textContent = helpText;
                +};
                +
                +/**
                + * Sets the basic options that are not dependent on if there are categories
                + * or a single flyout of blocks. Updates checkboxes and text fields.
                + */
                +WorkspaceFactoryView.prototype.setBaseOptions = function() {
                +  // Readonly mode.
                +  document.getElementById('option_readOnly_checkbox').checked = false;
                +  blocklyFactory.ifCheckedEnable(true, ['readonly1', 'readonly2']);
                +
                +  // Set basic options.
                +  document.getElementById('option_css_checkbox').checked = true;
                +  document.getElementById('option_maxBlocks_number').value = 100;
                +  document.getElementById('option_media_text').value =
                +      'https://blockly-demo.appspot.com/static/media/';
                +  document.getElementById('option_rtl_checkbox').checked = false;
                +  document.getElementById('option_sounds_checkbox').checked = true;
                +  document.getElementById('option_oneBasedIndex_checkbox').checked = true;
                +  document.getElementById('option_horizontalLayout_checkbox').checked = false;
                +  document.getElementById('option_toolboxPosition_checkbox').checked = false;
                +
                +  // Check infinite blocks and hide suboption.
                +  document.getElementById('option_infiniteBlocks_checkbox').checked = true;
                +  document.getElementById('maxBlockNumber_option').style.display =
                +      'none';
                +
                +  // Uncheck grid and zoom options and hide suboptions.
                +  document.getElementById('option_grid_checkbox').checked = false;
                +  document.getElementById('grid_options').style.display = 'none';
                +  document.getElementById('option_zoom_checkbox').checked = false;
                +  document.getElementById('zoom_options').style.display = 'none';
                +
                +  // Set grid options.
                +  document.getElementById('gridOption_spacing_number').value = 20;
                +  document.getElementById('gridOption_length_number').value = 1;
                +  document.getElementById('gridOption_colour_text').value = '#888';
                +  document.getElementById('gridOption_snap_checkbox').checked = false;
                +
                +  // Set zoom options.
                +  document.getElementById('zoomOption_controls_checkbox').checked = true;
                +  document.getElementById('zoomOption_wheel_checkbox').checked = true;
                +  document.getElementById('zoomOption_startScale_number').value = 1.0;
                +  document.getElementById('zoomOption_maxScale_number').value = 3;
                +  document.getElementById('zoomOption_minScale_number').value = 0.3;
                +  document.getElementById('zoomOption_scaleSpeed_number').value = 1.2;
                +};
                +
                +/**
                + * Updates category specific options depending on if there are categories
                + * currently present. Updates checkboxes and text fields in the view.
                + * @param {boolean} hasCategories True if categories are present, false if all
                + *    blocks are displayed in a single flyout.
                + */
                +WorkspaceFactoryView.prototype.setCategoryOptions = function(hasCategories) {
                +  document.getElementById('option_collapse_checkbox').checked = hasCategories;
                +  document.getElementById('option_comments_checkbox').checked = hasCategories;
                +  document.getElementById('option_disable_checkbox').checked = hasCategories;
                +  document.getElementById('option_scrollbars_checkbox').checked = hasCategories;
                +  document.getElementById('option_trashcan_checkbox').checked = hasCategories;
                +};
                diff --git a/blockly/webif/static/blockly/demos/blockfactory_old/blocks.js b/blockly/webif/static/blockly/demos/blockfactory_old/blocks.js
                new file mode 100644
                index 000000000..856780a52
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory_old/blocks.js
                @@ -0,0 +1,826 @@
                +/**
                + * Blockly Demos: Block Factory Blocks
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Blocks for Blockly's Block Factory application.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Blocks['factory_base'] = {
                +  // Base of new block.
                +  init: function() {
                +    this.setColour(120);
                +    this.appendDummyInput()
                +        .appendField('name')
                +        .appendField(new Blockly.FieldTextInput('block_type'), 'NAME');
                +    this.appendStatementInput('INPUTS')
                +        .setCheck('Input')
                +        .appendField('inputs');
                +    var dropdown = new Blockly.FieldDropdown([
                +        ['automatic inputs', 'AUTO'],
                +        ['external inputs', 'EXT'],
                +        ['inline inputs', 'INT']]);
                +    this.appendDummyInput()
                +        .appendField(dropdown, 'INLINE');
                +    dropdown = new Blockly.FieldDropdown([
                +        ['no connections', 'NONE'],
                +        ['← left output', 'LEFT'],
                +        ['↕ top+bottom connections', 'BOTH'],
                +        ['↑ top connection', 'TOP'],
                +        ['↓ bottom connection', 'BOTTOM']],
                +        function(option) {
                +          this.sourceBlock_.updateShape_(option);
                +          // Connect a shadow block to this new input. 
                +          this.sourceBlock_.spawnOutputShadow_(option);
                +        });
                +    this.appendDummyInput()
                +        .appendField(dropdown, 'CONNECTIONS');
                +    this.appendValueInput('COLOUR')
                +        .setCheck('Colour')
                +        .appendField('colour');
                +    this.setTooltip('Build a custom block by plugging\n' +
                +        'fields, inputs and other blocks here.');
                +    this.setHelpUrl(
                +        'https://developers.google.com/blockly/guides/create-custom-blocks/block-factory');
                +  },
                +  mutationToDom: function() {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('connections', this.getFieldValue('CONNECTIONS'));
                +    return container;
                +  },
                +  domToMutation: function(xmlElement) {
                +    var connections = xmlElement.getAttribute('connections');
                +    this.updateShape_(connections);
                +  },
                +  spawnOutputShadow_: function(option) {
                +    // Helper method for deciding which type of outputs this block needs
                +    // to attach shaddow blocks to.
                +    switch (option) {
                +      case 'LEFT':
                +        this.connectOutputShadow_('OUTPUTTYPE');
                +        break;
                +      case 'TOP':
                +        this.connectOutputShadow_('TOPTYPE');
                +        break;
                +      case 'BOTTOM':
                +        this.connectOutputShadow_('BOTTOMTYPE');
                +        break;
                +      case 'BOTH':
                +        this.connectOutputShadow_('TOPTYPE');
                +        this.connectOutputShadow_('BOTTOMTYPE');
                +        break;
                +    }
                +  },
                +  connectOutputShadow_: function(outputType) {
                +    // Helper method to create & connect shadow block.
                +    var type = this.workspace.newBlock('type_null');
                +    type.setShadow(true);
                +    type.outputConnection.connect(this.getInput(outputType).connection);
                +    type.initSvg();
                +    type.render();
                +  },
                +  updateShape_: function(option) {
                +    var outputExists = this.getInput('OUTPUTTYPE');
                +    var topExists = this.getInput('TOPTYPE');
                +    var bottomExists = this.getInput('BOTTOMTYPE');
                +    if (option == 'LEFT') {
                +      if (!outputExists) {
                +        this.addTypeInput_('OUTPUTTYPE', 'output type');
                +      }
                +    } else if (outputExists) {
                +      this.removeInput('OUTPUTTYPE');
                +    }
                +    if (option == 'TOP' || option == 'BOTH') {
                +      if (!topExists) {
                +        this.addTypeInput_('TOPTYPE', 'top type');
                +      }
                +    } else if (topExists) {
                +      this.removeInput('TOPTYPE');
                +    }
                +    if (option == 'BOTTOM' || option == 'BOTH') {
                +      if (!bottomExists) {
                +        this.addTypeInput_('BOTTOMTYPE', 'bottom type');
                +      }
                +    } else if (bottomExists) {
                +      this.removeInput('BOTTOMTYPE');
                +    }
                +  },
                +  addTypeInput_: function(name, label) {
                +    this.appendValueInput(name)
                +        .setCheck('Type')
                +        .appendField(label);
                +    this.moveInputBefore(name, 'COLOUR');
                +  }
                +};
                +
                +var FIELD_MESSAGE = 'fields %1 %2';
                +var FIELD_ARGS = [
                +  {
                +    "type": "field_dropdown",
                +    "name": "ALIGN",
                +    "options": [['left', 'LEFT'], ['right', 'RIGHT'], ['centre', 'CENTRE']],
                +  },
                +  {
                +    "type": "input_statement",
                +    "name": "FIELDS",
                +    "check": "Field"
                +  }
                +];
                +
                +var TYPE_MESSAGE = 'type %1';
                +var TYPE_ARGS = [
                +  {
                +    "type": "input_value",
                +    "name": "TYPE",
                +    "check": "Type",
                +    "align": "RIGHT"
                +  }
                +];
                +
                +Blockly.Blocks['input_value'] = {
                +  // Value input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "value input %1 %2",
                +      "args0": [
                +        {
                +          "type": "field_input",
                +          "name": "INPUTNAME",
                +          "text": "NAME"
                +        },
                +        {
                +          "type": "input_dummy"
                +        }
                +      ],
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "message2": TYPE_MESSAGE,
                +      "args2": TYPE_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "A value socket for horizontal connections.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=71"
                +    });
                +  },
                +  onchange: function() {
                +    inputNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['input_statement'] = {
                +  // Statement input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "statement input %1 %2",
                +      "args0": [
                +        {
                +          "type": "field_input",
                +          "name": "INPUTNAME",
                +          "text": "NAME"
                +        },
                +        {
                +          "type": "input_dummy"
                +        },
                +      ],
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "message2": TYPE_MESSAGE,
                +      "args2": TYPE_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "A statement socket for enclosed vertical stacks.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=246"
                +    });
                +  },
                +  onchange: function() {
                +    inputNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['input_dummy'] = {
                +  // Dummy input.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "dummy input",
                +      "message1": FIELD_MESSAGE,
                +      "args1": FIELD_ARGS,
                +      "previousStatement": "Input",
                +      "nextStatement": "Input",
                +      "colour": 210,
                +      "tooltip": "For adding fields on a separate row with no " +
                +                 "connections. Alignment options (left, right, centre) " +
                +                 "apply only to multi-line fields.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=293"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['field_static'] = {
                +  // Text value.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('text')
                +        .appendField(new Blockly.FieldTextInput(''), 'TEXT');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Static text that serves as a label.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=88');
                +  }
                +};
                +
                +Blockly.Blocks['field_input'] = {
                +  // Text input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('text input')
                +        .appendField(new Blockly.FieldTextInput('default'), 'TEXT')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter text.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=319');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_number'] = {
                +  // Numeric input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('numeric input')
                +        .appendField(new Blockly.FieldNumber(0), 'VALUE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.appendDummyInput()
                +        .appendField('min')
                +        .appendField(new Blockly.FieldNumber(-Infinity), 'MIN')
                +        .appendField('max')
                +        .appendField(new Blockly.FieldNumber(Infinity), 'MAX')
                +        .appendField('precision')
                +        .appendField(new Blockly.FieldNumber(0, 0), 'PRECISION');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter a number.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=319');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_angle'] = {
                +  // Angle input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('angle input')
                +        .appendField(new Blockly.FieldAngle('90'), 'ANGLE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('An input field for the user to enter an angle.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=372');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown'] = {
                +  // Dropdown menu.
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField('dropdown')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.optionCount_ = 3;
                +    this.updateShape_();
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setMutator(new Blockly.Mutator(['field_dropdown_option']));
                +    this.setColour(160);
                +    this.setTooltip('Dropdown menu with a list of options.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +  },
                +  mutationToDom: function(workspace) {
                +    // Create XML to represent menu options.
                +    var container = document.createElement('mutation');
                +    container.setAttribute('options', this.optionCount_);
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    // Parse XML to restore the menu options.
                +    this.optionCount_ = parseInt(container.getAttribute('options'), 10);
                +    this.updateShape_();
                +  },
                +  decompose: function(workspace) {
                +    // Populate the mutator's dialog with this block's components.
                +    var containerBlock = workspace.newBlock('field_dropdown_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.optionCount_; i++) {
                +      var optionBlock = workspace.newBlock('field_dropdown_option');
                +      optionBlock.initSvg();
                +      connection.connect(optionBlock.previousConnection);
                +      connection = optionBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  compose: function(containerBlock) {
                +    // Reconfigure this block based on the mutator dialog's components.
                +    var optionBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    var data = [];
                +    while (optionBlock) {
                +      data.push([optionBlock.userData_, optionBlock.cpuData_]);
                +      optionBlock = optionBlock.nextConnection &&
                +          optionBlock.nextConnection.targetBlock();
                +    }
                +    this.optionCount_ = data.length;
                +    this.updateShape_();
                +    // Restore any data.
                +    for (var i = 0; i < this.optionCount_; i++) {
                +      this.setFieldValue(data[i][0] || 'option', 'USER' + i);
                +      this.setFieldValue(data[i][1] || 'OPTIONNAME', 'CPU' + i);
                +    }
                +  },
                +  saveConnections: function(containerBlock) {
                +    // Store names and values for each option.
                +    var optionBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (optionBlock) {
                +      optionBlock.userData_ = this.getFieldValue('USER' + i);
                +      optionBlock.cpuData_ = this.getFieldValue('CPU' + i);
                +      i++;
                +      optionBlock = optionBlock.nextConnection &&
                +          optionBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  updateShape_: function() {
                +    // Modify this block to have the correct number of options.
                +    // Add new options.
                +    for (var i = 0; i < this.optionCount_; i++) {
                +      if (!this.getInput('OPTION' + i)) {
                +        this.appendDummyInput('OPTION' + i)
                +            .appendField(new Blockly.FieldTextInput('option'), 'USER' + i)
                +            .appendField(',')
                +            .appendField(new Blockly.FieldTextInput('OPTIONNAME'), 'CPU' + i);
                +      }
                +    }
                +    // Remove deleted options.
                +    while (this.getInput('OPTION' + i)) {
                +      this.removeInput('OPTION' + i);
                +      i++;
                +    }
                +  },
                +  onchange: function() {
                +    if (this.workspace && this.optionCount_ < 1) {
                +      this.setWarningText('Drop down menu must\nhave at least one option.');
                +    } else {
                +      fieldNameCheck(this);
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown_container'] = {
                +  // Container.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('add options');
                +    this.appendStatementInput('STACK');
                +    this.setTooltip('Add, remove, or reorder options\n' +
                +                    'to reconfigure this dropdown menu.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['field_dropdown_option'] = {
                +  // Add option.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('option');
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Add a new option to the dropdown menu.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=386');
                +    this.contextMenu = false;
                +  }
                +};
                +
                +Blockly.Blocks['field_checkbox'] = {
                +  // Checkbox.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('checkbox')
                +        .appendField(new Blockly.FieldCheckbox('TRUE'), 'CHECKED')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Checkbox field.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=485');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_colour'] = {
                +  // Colour input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('colour')
                +        .appendField(new Blockly.FieldColour('#ff0000'), 'COLOUR')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Colour input field.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=495');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_date'] = {
                +  // Date input.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('date')
                +        .appendField(new Blockly.FieldDate(), 'DATE')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Date input field.');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_variable'] = {
                +  // Dropdown for variables.
                +  init: function() {
                +    this.setColour(160);
                +    this.appendDummyInput()
                +        .appendField('variable')
                +        .appendField(new Blockly.FieldTextInput('item'), 'TEXT')
                +        .appendField(',')
                +        .appendField(new Blockly.FieldTextInput('NAME'), 'FIELDNAME');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Dropdown menu for variable names.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=510');
                +  },
                +  onchange: function() {
                +    fieldNameCheck(this);
                +  }
                +};
                +
                +Blockly.Blocks['field_image'] = {
                +  // Image.
                +  init: function() {
                +    this.setColour(160);
                +    var src = 'https://www.gstatic.com/codesite/ph/images/star_on.gif';
                +    this.appendDummyInput()
                +        .appendField('image')
                +        .appendField(new Blockly.FieldTextInput(src), 'SRC');
                +    this.appendDummyInput()
                +        .appendField('width')
                +        .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'WIDTH')
                +        .appendField('height')
                +        .appendField(new Blockly.FieldNumber('15', 0, NaN, 1), 'HEIGHT')
                +        .appendField('alt text')
                +        .appendField(new Blockly.FieldTextInput('*'), 'ALT');
                +    this.setPreviousStatement(true, 'Field');
                +    this.setNextStatement(true, 'Field');
                +    this.setTooltip('Static image (JPEG, PNG, GIF, SVG, BMP).\n' +
                +                    'Retains aspect ratio regardless of height and width.\n' +
                +                    'Alt text is for when collapsed.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=567');
                +  }
                +};
                +
                +Blockly.Blocks['type_group'] = {
                +  // Group of types.
                +  init: function() {
                +    this.typeCount_ = 2;
                +    this.updateShape_();
                +    this.setOutput(true, 'Type');
                +    this.setMutator(new Blockly.Mutator(['type_group_item']));
                +    this.setColour(230);
                +    this.setTooltip('Allows more than one type to be accepted.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677');
                +  },
                +  mutationToDom: function(workspace) {
                +    // Create XML to represent a group of types.
                +    var container = document.createElement('mutation');
                +    container.setAttribute('types', this.typeCount_);
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    // Parse XML to restore the group of types.
                +    this.typeCount_ = parseInt(container.getAttribute('types'), 10);
                +    this.updateShape_();
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      this.removeInput('TYPE' + i);
                +    }
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var input = this.appendValueInput('TYPE' + i)
                +                      .setCheck('Type');
                +      if (i == 0) {
                +        input.appendField('any of');
                +      }
                +    }
                +  },
                +  decompose: function(workspace) {
                +    // Populate the mutator's dialog with this block's components.
                +    var containerBlock = workspace.newBlock('type_group_container');
                +    containerBlock.initSvg();
                +    var connection = containerBlock.getInput('STACK').connection;
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var typeBlock = workspace.newBlock('type_group_item');
                +      typeBlock.initSvg();
                +      connection.connect(typeBlock.previousConnection);
                +      connection = typeBlock.nextConnection;
                +    }
                +    return containerBlock;
                +  },
                +  compose: function(containerBlock) {
                +    // Reconfigure this block based on the mutator dialog's components.
                +    var typeBlock = containerBlock.getInputTargetBlock('STACK');
                +    // Count number of inputs.
                +    var connections = [];
                +    while (typeBlock) {
                +      connections.push(typeBlock.valueConnection_);
                +      typeBlock = typeBlock.nextConnection &&
                +          typeBlock.nextConnection.targetBlock();
                +    }
                +    // Disconnect any children that don't belong.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      var connection = this.getInput('TYPE' + i).connection.targetConnection;
                +      if (connection && connections.indexOf(connection) == -1) {
                +        connection.disconnect();
                +      }
                +    }
                +    this.typeCount_ = connections.length;
                +    this.updateShape_();
                +    // Reconnect any child blocks.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      Blockly.Mutator.reconnect(connections[i], this, 'TYPE' + i);
                +    }
                +  },
                +  saveConnections: function(containerBlock) {
                +    // Store a pointer to any connected child blocks.
                +    var typeBlock = containerBlock.getInputTargetBlock('STACK');
                +    var i = 0;
                +    while (typeBlock) {
                +      var input = this.getInput('TYPE' + i);
                +      typeBlock.valueConnection_ = input && input.connection.targetConnection;
                +      i++;
                +      typeBlock = typeBlock.nextConnection &&
                +          typeBlock.nextConnection.targetBlock();
                +    }
                +  },
                +  updateShape_: function() {
                +    // Modify this block to have the correct number of inputs.
                +    // Add new inputs.
                +    for (var i = 0; i < this.typeCount_; i++) {
                +      if (!this.getInput('TYPE' + i)) {
                +        var input = this.appendValueInput('TYPE' + i);
                +        if (i == 0) {
                +          input.appendField('any of');
                +        }
                +      }
                +    }
                +    // Remove deleted inputs.
                +    while (this.getInput('TYPE' + i)) {
                +      this.removeInput('TYPE' + i);
                +      i++;
                +    }
                +  }
                +};
                +
                +Blockly.Blocks['type_group_container'] = {
                +  // Container.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "add types %1 %2",
                +      "args0": [
                +        {"type": "input_dummy"},
                +        {"type": "input_statement", "name": "STACK"}
                +      ],
                +      "colour": 230,
                +      "tooltip": "Add, or remove allowed type.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_group_item'] = {
                +  // Add type.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "type",
                +      "previousStatement": null,
                +      "nextStatement": null,
                +      "colour": 230,
                +      "tooltip": "Add a new allowed type.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=677"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_null'] = {
                +  // Null type.
                +  valueType: null,
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "any",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Any type is allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_boolean'] = {
                +  // Boolean type.
                +  valueType: 'Boolean',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Boolean",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Booleans (true/false) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_number'] = {
                +  // Number type.
                +  valueType: 'Number',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Number",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Numbers (int/float) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_string'] = {
                +  // String type.
                +  valueType: 'String',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "String",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Strings (text) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_list'] = {
                +  // List type.
                +  valueType: 'Array',
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "Array",
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Arrays (lists) are allowed.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=602"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['type_other'] = {
                +  // Other type.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "other %1",
                +      "args0": [{"type": "field_input", "name": "TYPE", "text": ""}],
                +      "output": "Type",
                +      "colour": 230,
                +      "tooltip": "Custom type to allow.",
                +      "helpUrl": "https://www.youtube.com/watch?v=s2_xaEvcVI0#t=702"
                +    });
                +  }
                +};
                +
                +Blockly.Blocks['colour_hue'] = {
                +  // Set the colour of the block.
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField('hue:')
                +        .appendField(new Blockly.FieldAngle('0', this.validator), 'HUE');
                +    this.setOutput(true, 'Colour');
                +    this.setTooltip('Paint the block with this colour.');
                +    this.setHelpUrl('https://www.youtube.com/watch?v=s2_xaEvcVI0#t=55');
                +  },
                +  validator: function(text) {
                +    // Update the current block's colour to match.
                +    var hue = parseInt(text, 10);
                +    if (!isNaN(hue)) {
                +      this.sourceBlock_.setColour(hue);
                +    }
                +  },
                +  mutationToDom: function(workspace) {
                +    var container = document.createElement('mutation');
                +    container.setAttribute('colour', this.getColour());
                +    return container;
                +  },
                +  domToMutation: function(container) {
                +    this.setColour(container.getAttribute('colour'));
                +  }
                +};
                +
                +/**
                + * Check to see if more than one field has this name.
                + * Highly inefficient (On^2), but n is small.
                + * @param {!Blockly.Block} referenceBlock Block to check.
                + */
                +function fieldNameCheck(referenceBlock) {
                +  if (!referenceBlock.workspace) {
                +    // Block has been deleted.
                +    return;
                +  }
                +  var name = referenceBlock.getFieldValue('FIELDNAME').toLowerCase();
                +  var count = 0;
                +  var blocks = referenceBlock.workspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var otherName = block.getFieldValue('FIELDNAME');
                +    if (!block.disabled && !block.getInheritedDisabled() &&
                +        otherName && otherName.toLowerCase() == name) {
                +      count++;
                +    }
                +  }
                +  var msg = (count > 1) ?
                +      'There are ' + count + ' field blocks\n with this name.' : null;
                +  referenceBlock.setWarningText(msg);
                +}
                +
                +/**
                + * Check to see if more than one input has this name.
                + * Highly inefficient (On^2), but n is small.
                + * @param {!Blockly.Block} referenceBlock Block to check.
                + */
                +function inputNameCheck(referenceBlock) {
                +  if (!referenceBlock.workspace) {
                +    // Block has been deleted.
                +    return;
                +  }
                +  var name = referenceBlock.getFieldValue('INPUTNAME').toLowerCase();
                +  var count = 0;
                +  var blocks = referenceBlock.workspace.getAllBlocks();
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    var otherName = block.getFieldValue('INPUTNAME');
                +    if (!block.disabled && !block.getInheritedDisabled() &&
                +        otherName && otherName.toLowerCase() == name) {
                +      count++;
                +    }
                +  }
                +  var msg = (count > 1) ?
                +      'There are ' + count + ' input blocks\n with this name.' : null;
                +  referenceBlock.setWarningText(msg);
                +}
                diff --git a/blockly/webif/static/blockly/demos/blockfactory_old/factory.js b/blockly/webif/static/blockly/demos/blockfactory_old/factory.js
                new file mode 100644
                index 000000000..9db58bd6d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory_old/factory.js
                @@ -0,0 +1,850 @@
                +/**
                + * Blockly Demos: Block Factory
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview JavaScript for Blockly's Block Factory application.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * Workspace for user to build block.
                + * @type {Blockly.Workspace}
                + */
                +var mainWorkspace = null;
                +
                +/**
                + * Workspace for preview of block.
                + * @type {Blockly.Workspace}
                + */
                +var previewWorkspace = null;
                +
                +/**
                + * Name of block if not named.
                + */
                +var UNNAMED = 'unnamed';
                +
                +/**
                + * Change the language code format.
                + */
                +function formatChange() {
                +  var mask = document.getElementById('blocklyMask');
                +  var languagePre = document.getElementById('languagePre');
                +  var languageTA = document.getElementById('languageTA');
                +  if (document.getElementById('format').value == 'Manual') {
                +    Blockly.hideChaff();
                +    mask.style.display = 'block';
                +    languagePre.style.display = 'none';
                +    languageTA.style.display = 'block';
                +    var code = languagePre.textContent.trim();
                +    languageTA.value = code;
                +    languageTA.focus();
                +    updatePreview();
                +  } else {
                +    mask.style.display = 'none';
                +    languageTA.style.display = 'none';
                +    languagePre.style.display = 'block';
                +    updateLanguage();
                +  }
                +  disableEnableLink();
                +}
                +
                +/**
                + * Update the language code based on constructs made in Blockly.
                + */
                +function updateLanguage() {
                +  var rootBlock = getRootBlock();
                +  if (!rootBlock) {
                +    return;
                +  }
                +  var blockType = rootBlock.getFieldValue('NAME').trim().toLowerCase();
                +  if (!blockType) {
                +    blockType = UNNAMED;
                +  }
                +  blockType = blockType.replace(/\W/g, '_').replace(/^(\d)/, '_\\1');
                +  switch (document.getElementById('format').value) {
                +    case 'JSON':
                +      var code = formatJson_(blockType, rootBlock);
                +      break;
                +    case 'JavaScript':
                +      var code = formatJavaScript_(blockType, rootBlock);
                +      break;
                +  }
                +  injectCode(code, 'languagePre');
                +  updatePreview();
                +}
                +
                +/**
                + * Update the language code as JSON.
                + * @param {string} blockType Name of block.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @return {string} Generanted language code.
                + * @private
                + */
                +function formatJson_(blockType, rootBlock) {
                +  var JS = {};
                +  // Type is not used by Blockly, but may be used by a loader.
                +  JS.type = blockType;
                +  // Generate inputs.
                +  var message = [];
                +  var args = [];
                +  var contentsBlock = rootBlock.getInputTargetBlock('INPUTS');
                +  var lastInput = null;
                +  while (contentsBlock) {
                +    if (!contentsBlock.disabled && !contentsBlock.getInheritedDisabled()) {
                +      var fields = getFieldsJson_(contentsBlock.getInputTargetBlock('FIELDS'));
                +      for (var i = 0; i < fields.length; i++) {
                +        if (typeof fields[i] == 'string') {
                +          message.push(fields[i].replace(/%/g, '%%'));
                +        } else {
                +          args.push(fields[i]);
                +          message.push('%' + args.length);
                +        }
                +      }
                +
                +      var input = {type: contentsBlock.type};
                +      // Dummy inputs don't have names.  Other inputs do.
                +      if (contentsBlock.type != 'input_dummy') {
                +        input.name = contentsBlock.getFieldValue('INPUTNAME');
                +      }
                +      var check = JSON.parse(getOptTypesFrom(contentsBlock, 'TYPE') || 'null');
                +      if (check) {
                +        input.check = check;
                +      }
                +      var align = contentsBlock.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        input.align = align;
                +      }
                +      args.push(input);
                +      message.push('%' + args.length);
                +      lastInput = contentsBlock;
                +    }
                +    contentsBlock = contentsBlock.nextConnection &&
                +        contentsBlock.nextConnection.targetBlock();
                +  }
                +  // Remove last input if dummy and not empty.
                +  if (lastInput && lastInput.type == 'input_dummy') {
                +    var fields = lastInput.getInputTargetBlock('FIELDS');
                +    if (fields && getFieldsJson_(fields).join('').trim() != '') {
                +      var align = lastInput.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        JS.lastDummyAlign0 = align;
                +      }
                +      args.pop();
                +      message.pop();
                +    }
                +  }
                +  JS.message0 = message.join(' ');
                +  if (args.length) {
                +    JS.args0 = args;
                +  }
                +  // Generate inline/external switch.
                +  if (rootBlock.getFieldValue('INLINE') == 'EXT') {
                +    JS.inputsInline = false;
                +  } else if (rootBlock.getFieldValue('INLINE') == 'INT') {
                +    JS.inputsInline = true;
                +  }
                +  // Generate output, or next/previous connections.
                +  switch (rootBlock.getFieldValue('CONNECTIONS')) {
                +    case 'LEFT':
                +      JS.output =
                +          JSON.parse(getOptTypesFrom(rootBlock, 'OUTPUTTYPE') || 'null');
                +      break;
                +    case 'BOTH':
                +      JS.previousStatement =
                +          JSON.parse(getOptTypesFrom(rootBlock, 'TOPTYPE') || 'null');
                +      JS.nextStatement =
                +          JSON.parse(getOptTypesFrom(rootBlock, 'BOTTOMTYPE') || 'null');
                +      break;
                +    case 'TOP':
                +      JS.previousStatement =
                +          JSON.parse(getOptTypesFrom(rootBlock, 'TOPTYPE') || 'null');
                +      break;
                +    case 'BOTTOM':
                +      JS.nextStatement =
                +          JSON.parse(getOptTypesFrom(rootBlock, 'BOTTOMTYPE') || 'null');
                +      break;
                +  }
                +  // Generate colour.
                +  var colourBlock = rootBlock.getInputTargetBlock('COLOUR');
                +  if (colourBlock && !colourBlock.disabled) {
                +    var hue = parseInt(colourBlock.getFieldValue('HUE'), 10);
                +    JS.colour = hue;
                +  }
                +  JS.tooltip = '';
                +  JS.helpUrl = 'http://www.example.com/';
                +  return JSON.stringify(JS, null, '  ');
                +}
                +
                +/**
                + * Update the language code as JavaScript.
                + * @param {string} blockType Name of block.
                + * @param {!Blockly.Block} rootBlock Factory_base block.
                + * @return {string} Generanted language code.
                + * @private
                + */
                +function formatJavaScript_(blockType, rootBlock) {
                +  var code = [];
                +  code.push("Blockly.Blocks['" + blockType + "'] = {");
                +  code.push("  init: function() {");
                +  // Generate inputs.
                +  var TYPES = {'input_value': 'appendValueInput',
                +               'input_statement': 'appendStatementInput',
                +               'input_dummy': 'appendDummyInput'};
                +  var contentsBlock = rootBlock.getInputTargetBlock('INPUTS');
                +  while (contentsBlock) {
                +    if (!contentsBlock.disabled && !contentsBlock.getInheritedDisabled()) {
                +      var name = '';
                +      // Dummy inputs don't have names.  Other inputs do.
                +      if (contentsBlock.type != 'input_dummy') {
                +        name = escapeString(contentsBlock.getFieldValue('INPUTNAME'));
                +      }
                +      code.push('    this.' + TYPES[contentsBlock.type] + '(' + name + ')');
                +      var check = getOptTypesFrom(contentsBlock, 'TYPE');
                +      if (check) {
                +        code.push('        .setCheck(' + check + ')');
                +      }
                +      var align = contentsBlock.getFieldValue('ALIGN');
                +      if (align != 'LEFT') {
                +        code.push('        .setAlign(Blockly.ALIGN_' + align + ')');
                +      }
                +      var fields = getFieldsJs_(contentsBlock.getInputTargetBlock('FIELDS'));
                +      for (var i = 0; i < fields.length; i++) {
                +        code.push('        .appendField(' + fields[i] + ')');
                +      }
                +      // Add semicolon to last line to finish the statement.
                +      code[code.length - 1] += ';';
                +    }
                +    contentsBlock = contentsBlock.nextConnection &&
                +        contentsBlock.nextConnection.targetBlock();
                +  }
                +  // Generate inline/external switch.
                +  if (rootBlock.getFieldValue('INLINE') == 'EXT') {
                +    code.push('    this.setInputsInline(false);');
                +  } else if (rootBlock.getFieldValue('INLINE') == 'INT') {
                +    code.push('    this.setInputsInline(true);');
                +  }
                +  // Generate output, or next/previous connections.
                +  switch (rootBlock.getFieldValue('CONNECTIONS')) {
                +    case 'LEFT':
                +      code.push(connectionLineJs_('setOutput', 'OUTPUTTYPE'));
                +      break;
                +    case 'BOTH':
                +      code.push(connectionLineJs_('setPreviousStatement', 'TOPTYPE'));
                +      code.push(connectionLineJs_('setNextStatement', 'BOTTOMTYPE'));
                +      break;
                +    case 'TOP':
                +      code.push(connectionLineJs_('setPreviousStatement', 'TOPTYPE'));
                +      break;
                +    case 'BOTTOM':
                +      code.push(connectionLineJs_('setNextStatement', 'BOTTOMTYPE'));
                +      break;
                +  }
                +  // Generate colour.
                +  var colourBlock = rootBlock.getInputTargetBlock('COLOUR');
                +  if (colourBlock && !colourBlock.disabled) {
                +    var hue = parseInt(colourBlock.getFieldValue('HUE'), 10);
                +    if (!isNaN(hue)) {
                +      code.push('    this.setColour(' + hue + ');');
                +    }
                +  }
                +  code.push("    this.setTooltip('');");
                +  code.push("    this.setHelpUrl('http://www.example.com/');");
                +  code.push('  }');
                +  code.push('};');
                +  return code.join('\n');
                +}
                +
                +/**
                + * Create JS code required to create a top, bottom, or value connection.
                + * @param {string} functionName JavaScript function name.
                + * @param {string} typeName Name of type input.
                + * @return {string} Line of JavaScript code to create connection.
                + * @private
                + */
                +function connectionLineJs_(functionName, typeName) {
                +  var type = getOptTypesFrom(getRootBlock(), typeName);
                +  if (type) {
                +    type = ', ' + type;
                +  } else {
                +    type = '';
                +  }
                +  return '    this.' + functionName + '(true' + type + ');';
                +}
                +
                +/**
                + * Returns field strings and any config.
                + * @param {!Blockly.Block} block Input block.
                + * @return {!Array.<string>} Field strings.
                + * @private
                + */
                +function getFieldsJs_(block) {
                +  var fields = [];
                +  while (block) {
                +    if (!block.disabled && !block.getInheritedDisabled()) {
                +      switch (block.type) {
                +        case 'field_static':
                +          // Result: 'hello'
                +          fields.push(escapeString(block.getFieldValue('TEXT')));
                +          break;
                +        case 'field_input':
                +          // Result: new Blockly.FieldTextInput('Hello'), 'GREET'
                +          fields.push('new Blockly.FieldTextInput(' +
                +              escapeString(block.getFieldValue('TEXT')) + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_number':
                +          // Result: new Blockly.FieldNumber(10, 0, 100, 1), 'NUMBER'
                +          var args = [
                +            Number(block.getFieldValue('VALUE')),
                +            Number(block.getFieldValue('MIN')),
                +            Number(block.getFieldValue('MAX')),
                +            Number(block.getFieldValue('PRECISION'))
                +          ];
                +          // Remove any trailing arguments that aren't needed.
                +          if (args[3] == 0) {
                +            args.pop();
                +            if (args[2] == Infinity) {
                +              args.pop();
                +              if (args[1] == -Infinity) {
                +                args.pop();
                +              }
                +            }
                +          }
                +          fields.push('new Blockly.FieldNumber(' + args.join(', ') + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_angle':
                +          // Result: new Blockly.FieldAngle(90), 'ANGLE'
                +          fields.push('new Blockly.FieldAngle(' +
                +              Number(block.getFieldValue('ANGLE')) + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_checkbox':
                +          // Result: new Blockly.FieldCheckbox('TRUE'), 'CHECK'
                +          fields.push('new Blockly.FieldCheckbox(' +
                +              escapeString(block.getFieldValue('CHECKED')) + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_colour':
                +          // Result: new Blockly.FieldColour('#ff0000'), 'COLOUR'
                +          fields.push('new Blockly.FieldColour(' +
                +              escapeString(block.getFieldValue('COLOUR')) + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_date':
                +          // Result: new Blockly.FieldDate('2015-02-04'), 'DATE'
                +          fields.push('new Blockly.FieldDate(' +
                +              escapeString(block.getFieldValue('DATE')) + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_variable':
                +          // Result: new Blockly.FieldVariable('item'), 'VAR'
                +          var varname = escapeString(block.getFieldValue('TEXT') || null);
                +          fields.push('new Blockly.FieldVariable(' + varname + '), ' +
                +              escapeString(block.getFieldValue('FIELDNAME')));
                +          break;
                +        case 'field_dropdown':
                +          // Result:
                +          // new Blockly.FieldDropdown([['yes', '1'], ['no', '0']]), 'TOGGLE'
                +          var options = [];
                +          for (var i = 0; i < block.optionCount_; i++) {
                +            options[i] = '[' + escapeString(block.getFieldValue('USER' + i)) +
                +                ', ' + escapeString(block.getFieldValue('CPU' + i)) + ']';
                +          }
                +          if (options.length) {
                +            fields.push('new Blockly.FieldDropdown([' +
                +                options.join(', ') + ']), ' +
                +                escapeString(block.getFieldValue('FIELDNAME')));
                +          }
                +          break;
                +        case 'field_image':
                +          // Result: new Blockly.FieldImage('http://...', 80, 60, '*')
                +          var src = escapeString(block.getFieldValue('SRC'));
                +          var width = Number(block.getFieldValue('WIDTH'));
                +          var height = Number(block.getFieldValue('HEIGHT'));
                +          var alt = escapeString(block.getFieldValue('ALT'));
                +          fields.push('new Blockly.FieldImage(' +
                +              src + ', ' + width + ', ' + height + ', ' + alt + ')');
                +          break;
                +      }
                +    }
                +    block = block.nextConnection && block.nextConnection.targetBlock();
                +  }
                +  return fields;
                +}
                +
                +/**
                + * Returns field strings and any config.
                + * @param {!Blockly.Block} block Input block.
                + * @return {!Array.<string|!Object>} Array of static text and field configs.
                + * @private
                + */
                +function getFieldsJson_(block) {
                +  var fields = [];
                +  while (block) {
                +    if (!block.disabled && !block.getInheritedDisabled()) {
                +      switch (block.type) {
                +        case 'field_static':
                +          // Result: 'hello'
                +          fields.push(block.getFieldValue('TEXT'));
                +          break;
                +        case 'field_input':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            text: block.getFieldValue('TEXT')
                +          });
                +          break;
                +        case 'field_number':
                +          var obj = {
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            value: parseFloat(block.getFieldValue('VALUE'))
                +          };
                +          var min = parseFloat(block.getFieldValue('MIN'));
                +          if (min > -Infinity) {
                +            obj.min = min;
                +          }
                +          var max = parseFloat(block.getFieldValue('MAX'));
                +          if (max < Infinity) {
                +            obj.max = max;
                +          }
                +          var precision = parseFloat(block.getFieldValue('PRECISION'));
                +          if (precision) {
                +            obj.precision = precision;
                +          }
                +          fields.push(obj);
                +          break;
                +        case 'field_angle':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            angle: Number(block.getFieldValue('ANGLE'))
                +          });
                +          break;
                +        case 'field_checkbox':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            checked: block.getFieldValue('CHECKED') == 'TRUE'
                +          });
                +          break;
                +        case 'field_colour':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            colour: block.getFieldValue('COLOUR')
                +          });
                +          break;
                +        case 'field_date':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            date: block.getFieldValue('DATE')
                +          });
                +          break;
                +        case 'field_variable':
                +          fields.push({
                +            type: block.type,
                +            name: block.getFieldValue('FIELDNAME'),
                +            variable: block.getFieldValue('TEXT') || null
                +          });
                +          break;
                +        case 'field_dropdown':
                +          var options = [];
                +          for (var i = 0; i < block.optionCount_; i++) {
                +            options[i] = [block.getFieldValue('USER' + i),
                +                block.getFieldValue('CPU' + i)];
                +          }
                +          if (options.length) {
                +            fields.push({
                +              type: block.type,
                +              name: block.getFieldValue('FIELDNAME'),
                +              options: options
                +            });
                +          }
                +          break;
                +        case 'field_image':
                +          fields.push({
                +            type: block.type,
                +            src: block.getFieldValue('SRC'),
                +            width: Number(block.getFieldValue('WIDTH')),
                +            height: Number(block.getFieldValue('HEIGHT')),
                +            alt: block.getFieldValue('ALT')
                +          });
                +          break;
                +      }
                +    }
                +    block = block.nextConnection && block.nextConnection.targetBlock();
                +  }
                +  return fields;
                +}
                +
                +/**
                + * Escape a string.
                + * @param {string} string String to escape.
                + * @return {string} Escaped string surrouned by quotes.
                + */
                +function escapeString(string) {
                +  return JSON.stringify(string);
                +}
                +
                +/**
                + * Fetch the type(s) defined in the given input.
                + * Format as a string for appending to the generated code.
                + * @param {!Blockly.Block} block Block with input.
                + * @param {string} name Name of the input.
                + * @return {?string} String defining the types.
                + */
                +function getOptTypesFrom(block, name) {
                +  var types = getTypesFrom_(block, name);
                +  if (types.length == 0) {
                +    return undefined;
                +  } else if (types.indexOf('null') != -1) {
                +    return 'null';
                +  } else if (types.length == 1) {
                +    return types[0];
                +  } else {
                +    return '[' + types.join(', ') + ']';
                +  }
                +}
                +
                +/**
                + * Fetch the type(s) defined in the given input.
                + * @param {!Blockly.Block} block Block with input.
                + * @param {string} name Name of the input.
                + * @return {!Array.<string>} List of types.
                + * @private
                + */
                +function getTypesFrom_(block, name) {
                +  var typeBlock = block.getInputTargetBlock(name);
                +  var types;
                +  if (!typeBlock || typeBlock.disabled) {
                +    types = [];
                +  } else if (typeBlock.type == 'type_other') {
                +    types = [escapeString(typeBlock.getFieldValue('TYPE'))];
                +  } else if (typeBlock.type == 'type_group') {
                +    types = [];
                +    for (var i = 0; i < typeBlock.typeCount_; i++) {
                +      types = types.concat(getTypesFrom_(typeBlock, 'TYPE' + i));
                +    }
                +    // Remove duplicates.
                +    var hash = Object.create(null);
                +    for (var n = types.length - 1; n >= 0; n--) {
                +      if (hash[types[n]]) {
                +        types.splice(n, 1);
                +      }
                +      hash[types[n]] = true;
                +    }
                +  } else {
                +    types = [escapeString(typeBlock.valueType)];
                +  }
                +  return types;
                +}
                +
                +/**
                + * Update the generator code.
                + * @param {!Blockly.Block} block Rendered block in preview workspace.
                + */
                +function updateGenerator(block) {
                +  function makeVar(root, name) {
                +    name = name.toLowerCase().replace(/\W/g, '_');
                +    return '  var ' + root + '_' + name;
                +  }
                +  var language = document.getElementById('language').value;
                +  var code = [];
                +  code.push("Blockly." + language + "['" + block.type +
                +            "'] = function(block) {");
                +
                +  // Generate getters for any fields or inputs.
                +  for (var i = 0, input; input = block.inputList[i]; i++) {
                +    for (var j = 0, field; field = input.fieldRow[j]; j++) {
                +      var name = field.name;
                +      if (!name) {
                +        continue;
                +      }
                +      if (field instanceof Blockly.FieldVariable) {
                +        // Subclass of Blockly.FieldDropdown, must test first.
                +        code.push(makeVar('variable', name) +
                +                  " = Blockly." + language +
                +                  ".variableDB_.getName(block.getFieldValue('" + name +
                +                  "'), Blockly.Variables.NAME_TYPE);");
                +      } else if (field instanceof Blockly.FieldAngle) {
                +        // Subclass of Blockly.FieldTextInput, must test first.
                +        code.push(makeVar('angle', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (Blockly.FieldDate && field instanceof Blockly.FieldDate) {
                +        // Blockly.FieldDate may not be compiled into Blockly.
                +        code.push(makeVar('date', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldColour) {
                +        code.push(makeVar('colour', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldCheckbox) {
                +        code.push(makeVar('checkbox', name) +
                +                  " = block.getFieldValue('" + name + "') == 'TRUE';");
                +      } else if (field instanceof Blockly.FieldDropdown) {
                +        code.push(makeVar('dropdown', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldNumber) {
                +        code.push(makeVar('number', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      } else if (field instanceof Blockly.FieldTextInput) {
                +        code.push(makeVar('text', name) +
                +                  " = block.getFieldValue('" + name + "');");
                +      }
                +    }
                +    var name = input.name;
                +    if (name) {
                +      if (input.type == Blockly.INPUT_VALUE) {
                +        code.push(makeVar('value', name) +
                +                  " = Blockly." + language + ".valueToCode(block, '" + name +
                +                  "', Blockly." + language + ".ORDER_ATOMIC);");
                +      } else if (input.type == Blockly.NEXT_STATEMENT) {
                +        code.push(makeVar('statements', name) +
                +                  " = Blockly." + language + ".statementToCode(block, '" +
                +                  name + "');");
                +      }
                +    }
                +  }
                +  // Most languages end lines with a semicolon.  Python does not.
                +  var lineEnd = {
                +    'JavaScript': ';',
                +    'Python': '',
                +    'PHP': ';',
                +    'Dart': ';'
                +  };
                +  code.push("  // TODO: Assemble " + language + " into code variable.");
                +  if (block.outputConnection) {
                +    code.push("  var code = '...';");
                +    code.push("  // TODO: Change ORDER_NONE to the correct strength.");
                +    code.push("  return [code, Blockly." + language + ".ORDER_NONE];");
                +  } else {
                +    code.push("  var code = '..." + (lineEnd[language] || '') + "\\n';");
                +    code.push("  return code;");
                +  }
                +  code.push("};");
                +
                +  injectCode(code.join('\n'), 'generatorPre');
                +}
                +
                +/**
                + * Existing direction ('ltr' vs 'rtl') of preview.
                + */
                +var oldDir = null;
                +
                +/**
                + * Update the preview display.
                + */
                +function updatePreview() {
                +  // Toggle between LTR/RTL if needed (also used in first display).
                +  var newDir = document.getElementById('direction').value;
                +  if (oldDir != newDir) {
                +    if (previewWorkspace) {
                +      previewWorkspace.dispose();
                +    }
                +    var rtl = newDir == 'rtl';
                +    previewWorkspace = Blockly.inject('preview',
                +        {rtl: rtl,
                +         media: '../../media/',
                +         scrollbars: true});
                +    oldDir = newDir;
                +  }
                +  previewWorkspace.clear();
                +
                +  // Fetch the code and determine its format (JSON or JavaScript).
                +  var format = document.getElementById('format').value;
                +  if (format == 'Manual') {
                +    var code = document.getElementById('languageTA').value;
                +    // If the code is JSON, it will parse, otherwise treat as JS.
                +    try {
                +      JSON.parse(code);
                +      format = 'JSON';
                +    } catch (e) {
                +      format = 'JavaScript';
                +    }
                +  } else {
                +    var code = document.getElementById('languagePre').textContent;
                +  }
                +  if (!code.trim()) {
                +    // Nothing to render.  Happens while cloud storage is loading.
                +    return;
                +  }
                +
                +  // Backup Blockly.Blocks object so that main workspace and preview don't
                +  // collide if user creates a 'factory_base' block, for instance.
                +  var backupBlocks = Blockly.Blocks;
                +  try {
                +    // Make a shallow copy.
                +    Blockly.Blocks = {};
                +    for (var prop in backupBlocks) {
                +      Blockly.Blocks[prop] = backupBlocks[prop];
                +    }
                +
                +    if (format == 'JSON') {
                +      var json = JSON.parse(code);
                +      Blockly.Blocks[json.type || UNNAMED] = {
                +        init: function() {
                +          this.jsonInit(json);
                +        }
                +      };
                +    } else if (format == 'JavaScript') {
                +      eval(code);
                +    } else {
                +      throw 'Unknown format: ' + format;
                +    }
                +
                +    // Look for a block on Blockly.Blocks that does not match the backup.
                +    var blockType = null;
                +    for (var type in Blockly.Blocks) {
                +      if (typeof Blockly.Blocks[type].init == 'function' &&
                +          Blockly.Blocks[type] != backupBlocks[type]) {
                +        blockType = type;
                +        break;
                +      }
                +    }
                +    if (!blockType) {
                +      return;
                +    }
                +
                +    // Create the preview block.
                +    var previewBlock = previewWorkspace.newBlock(blockType);
                +    previewBlock.initSvg();
                +    previewBlock.render();
                +    previewBlock.setMovable(false);
                +    previewBlock.setDeletable(false);
                +    previewBlock.moveBy(15, 10);
                +    previewWorkspace.clearUndo();
                +
                +    updateGenerator(previewBlock);
                +  } finally {
                +    Blockly.Blocks = backupBlocks;
                +  }
                +}
                +
                +/**
                + * Inject code into a pre tag, with syntax highlighting.
                + * Safe from HTML/script injection.
                + * @param {string} code Lines of code.
                + * @param {string} id ID of <pre> element to inject into.
                + */
                +function injectCode(code, id) {
                +  var pre = document.getElementById(id);
                +  pre.textContent = code;
                +  code = pre.textContent;
                +  code = PR.prettyPrintOne(code, 'js');
                +  pre.innerHTML = code;
                +}
                +
                +/**
                + * Return the uneditable container block that everything else attaches to.
                + * @return {Blockly.Block}
                + */
                +function getRootBlock() {
                +  var blocks = mainWorkspace.getTopBlocks(false);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (block.type == 'factory_base') {
                +      return block;
                +    }
                +  }
                +  return null;
                +}
                +
                +/**
                + * Disable the link button if the format is 'Manual', enable otherwise.
                + */
                +function disableEnableLink() {
                +  var linkButton = document.getElementById('linkButton');
                +  linkButton.disabled = document.getElementById('format').value == 'Manual';
                +}
                +
                +/**
                + * Initialize Blockly and layout.  Called on page load.
                + */
                +function init() {
                +  if ('BlocklyStorage' in window) {
                +    BlocklyStorage.HTTPREQUEST_ERROR =
                +        'There was a problem with the request.\n';
                +    BlocklyStorage.LINK_ALERT =
                +        'Share your blocks with this link:\n\n%1';
                +    BlocklyStorage.HASH_ERROR =
                +        'Sorry, "%1" doesn\'t correspond with any saved Blockly file.';
                +    BlocklyStorage.XML_ERROR = 'Could not load your saved file.\n'+
                +        'Perhaps it was created with a different version of Blockly?';
                +    var linkButton = document.getElementById('linkButton');
                +    linkButton.style.display = 'inline-block';
                +    linkButton.addEventListener('click',
                +        function() {BlocklyStorage.link(mainWorkspace);});
                +    disableEnableLink();
                +  }
                +
                +  document.getElementById('helpButton').addEventListener('click',
                +    function() {
                +      open('https://developers.google.com/blockly/guides/create-custom-blocks/block-factory',
                +           'BlockFactoryHelp');
                +    });
                +
                +  var expandList = [
                +    document.getElementById('blockly'),
                +    document.getElementById('blocklyMask'),
                +    document.getElementById('preview'),
                +    document.getElementById('languagePre'),
                +    document.getElementById('languageTA'),
                +    document.getElementById('generatorPre')
                +  ];
                +  var onresize = function(e) {
                +    for (var i = 0, expand; expand = expandList[i]; i++) {
                +      expand.style.width = (expand.parentNode.offsetWidth - 2) + 'px';
                +      expand.style.height = (expand.parentNode.offsetHeight - 2) + 'px';
                +    }
                +  };
                +  onresize();
                +  window.addEventListener('resize', onresize);
                +
                +  var toolbox = document.getElementById('toolbox');
                +  mainWorkspace = Blockly.inject('blockly',
                +      {collapse: false,
                +       toolbox: toolbox,
                +       media: '../../media/'});
                +
                +  // Create the root block.
                +  if ('BlocklyStorage' in window && window.location.hash.length > 1) {
                +    BlocklyStorage.retrieveXml(window.location.hash.substring(1),
                +                               mainWorkspace);
                +  } else {
                +    var xml = '<xml><block type="factory_base" deletable="false" movable="false"></block></xml>';
                +    Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), mainWorkspace);
                +  }
                +  mainWorkspace.clearUndo();
                +
                +  mainWorkspace.addChangeListener(Blockly.Events.disableOrphans);
                +  mainWorkspace.addChangeListener(updateLanguage);
                +  document.getElementById('direction')
                +      .addEventListener('change', updatePreview);
                +  document.getElementById('languageTA')
                +      .addEventListener('change', updatePreview);
                +  document.getElementById('languageTA')
                +      .addEventListener('keyup', updatePreview);
                +  document.getElementById('format')
                +      .addEventListener('change', formatChange);
                +  document.getElementById('language')
                +      .addEventListener('change', updatePreview);
                +}
                +window.addEventListener('load', init);
                diff --git a/blockly/webif/static/blockly/demos/blockfactory_old/icon.png b/blockly/webif/static/blockly/demos/blockfactory_old/icon.png
                new file mode 100644
                index 000000000..d4d19b457
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/blockfactory_old/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/blockfactory_old/index.html b/blockly/webif/static/blockly/demos/blockfactory_old/index.html
                new file mode 100644
                index 000000000..f4fd4f6c7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/blockfactory_old/index.html
                @@ -0,0 +1,229 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <meta name="viewport" content="target-densitydpi=device-dpi, height=660, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
                +  <title>Blockly Demo: Block Factory</title>
                +  <script src="/storage.js"></script>
                +  <script src="factory.js"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../msg/messages.js"></script>
                +  <script src="blocks.js"></script>
                +  <style>
                +    html, body {
                +      height: 100%;
                +    }
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +      margin: 0 5px;
                +      overflow: hidden
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    h3 {
                +      margin-top: 5px;
                +      margin-bottom: 0;
                +    }
                +    table {
                +      height: 100%;
                +      width: 100%;
                +    }
                +    td {
                +      vertical-align: top;
                +      padding: 0;
                +    }
                +    #blockly {
                +      position: fixed;
                +    }
                +    #blocklyMask {
                +      background-color: #000;
                +      cursor: not-allowed;
                +      display: none;
                +      position: fixed;
                +      opacity: 0.2;
                +      z-index: 9;
                +    }
                +    #preview {
                +      position: absolute;
                +    }
                +    pre,
                +    #languageTA {
                +      border: #ddd 1px solid;
                +      margin-top: 0;
                +      position: absolute;
                +      overflow: scroll;
                +    }
                +    #languageTA {
                +      display: none;
                +      font-family: monospace;
                +      font-size: 10pt;
                +    }
                +
                +    button {
                +      border-radius: 4px;
                +      border: 1px solid #ddd;
                +      background-color: #eee;
                +      color: #000;
                +      padding: 10px;
                +      margin: 0 5px;
                +      font-size: large;
                +    }
                +    button:hover:not(:disabled) {
                +      box-shadow: 2px 2px 5px #888;
                +    }
                +    button:disabled {
                +      opacity: 0.6;
                +    }
                +    button>* {
                +      opacity: 0.6;
                +      vertical-align: text-bottom;
                +    }
                +    button:hover:not(:disabled)>* {
                +      opacity: 1;
                +    }
                +    #linkButton {
                +      display: none;
                +    }
                +  </style>
                +  <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
                +</head>
                +<body>
                +  <table>
                +    <tr>
                +      <td width="50%" height="5%">
                +        <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +          <a href="../index.html">Demos</a> &gt; Block Factory</h1>
                +      </td>
                +      <td width="50%" height="5%">
                +        <table>
                +          <tr>
                +            <td style="vertical-align: bottom;">
                +              <h3>Preview:
                +                <select id="direction">
                +                  <option value="ltr">LTR</option>
                +                  <option value="rtl">RTL</option>
                +                </select>
                +              </h3>
                +            </td>
                +            <td style="vertical-align: middle; text-align: right;">
                +              <button id="linkButton" title="Save and link to blocks.">
                +                <img src="link.png" height="21" width="21">
                +              </button>
                +              <button id="linkButton" title="Save and link to blocks.">
                +                <img src="link.png" height="21" width="21">
                +              </button>
                +              <button id="helpButton" title="View documentation in new window.">
                +                <span>Help</span>
                +              </button>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +    </tr>
                +    <tr>
                +      <td width="50%" height="95%" style="padding: 2px;">
                +        <div id="blockly"></div>
                +        <div id="blocklyMask"></div>
                +      </td>
                +      <td width="50%" height="95%">
                +        <table>
                +          <tr>
                +            <td height="30%">
                +              <div id="preview"></div>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="5%">
                +              <h3>Language code:
                +                <select id="format">
                +                  <option value="JSON">JSON</option>
                +                  <option value="JavaScript">JavaScript</option>
                +                  <option value="Manual">Manual edit&hellip;</option>
                +                </select>
                +              </h3>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="30%">
                +              <pre id="languagePre"></pre>
                +              <textarea id="languageTA"></textarea>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="5%">
                +              <h3>Generator stub:
                +                <select id="language">
                +                  <option value="JavaScript">JavaScript</option>
                +                  <option value="Python">Python</option>
                +                  <option value="PHP">PHP</option>
                +                  <option value="Lua">Lua</option>
                +                  <option value="Dart">Dart</option>
                +                </select>
                +              </h3>
                +            </td>
                +          </tr>
                +          <tr>
                +            <td height="30%">
                +              <pre id="generatorPre"></pre>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +    </tr>
                +  </table>
                +  <xml id="toolbox" style="display: none">
                +    <category name="Input">
                +      <block type="input_value">
                +        <value name="TYPE">
                +          <shadow type="type_null"></shadow>
                +        </value>
                +      </block>
                +      <block type="input_statement">
                +        <value name="TYPE">
                +          <shadow type="type_null"></shadow>
                +        </value>
                +      </block>
                +      <block type="input_dummy"></block>
                +    </category>
                +    <category name="Field">
                +      <block type="field_static"></block>
                +      <block type="field_input"></block>
                +      <block type="field_number"></block>
                +      <block type="field_angle"></block>
                +      <block type="field_dropdown"></block>
                +      <block type="field_checkbox"></block>
                +      <block type="field_colour"></block>
                +      <!--
                +      Date picker commented out since it increases footprint by 60%.
                +      Add it only if you need it.  See also goog.require in blockly.js.
                +      <block type="field_date"></block>
                +      -->
                +      <block type="field_variable"></block>
                +      <block type="field_image"></block>
                +    </category>
                +    <category name="Type">
                +      <block type="type_group"></block>
                +      <block type="type_null"></block>
                +      <block type="type_boolean"></block>
                +      <block type="type_number"></block>
                +      <block type="type_string"></block>
                +      <block type="type_list"></block>
                +      <block type="type_other"></block>
                +    </category>
                +    <category name="Colour" id="colourCategory">
                +      <block type="colour_hue"><mutation colour="20"></mutation><field name="HUE">20</field></block>
                +      <block type="colour_hue"><mutation colour="65"></mutation><field name="HUE">65</field></block>
                +      <block type="colour_hue"><mutation colour="120"></mutation><field name="HUE">120</field></block>
                +      <block type="colour_hue"><mutation colour="160"></mutation><field name="HUE">160</field></block>
                +      <block type="colour_hue"><mutation colour="210"></mutation><field name="HUE">210</field></block>
                +      <block type="colour_hue"><mutation colour="230"></mutation><field name="HUE">230</field></block>
                +      <block type="colour_hue"><mutation colour="260"></mutation><field name="HUE">260</field></block>
                +      <block type="colour_hue"><mutation colour="290"></mutation><field name="HUE">290</field></block>
                +      <block type="colour_hue"><mutation colour="330"></mutation><field name="HUE">330</field></block>
                +    </category>
                +  </xml>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/blockfactory_old/link.png b/blockly/webif/static/blockly/demos/blockfactory_old/link.png
                new file mode 100644
                index 000000000..11dfd8284
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/blockfactory_old/link.png differ
                diff --git a/blockly/webif/static/blockly/demos/code/code.js b/blockly/webif/static/blockly/demos/code/code.js
                new file mode 100644
                index 000000000..8ad4d1667
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/code.js
                @@ -0,0 +1,538 @@
                +/**
                + * Blockly Demos: Code
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview JavaScript for Blockly's Code demo.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * Create a namespace for the application.
                + */
                +var Code = {};
                +
                +/**
                + * Lookup for names of supported languages.  Keys should be in ISO 639 format.
                + */
                +Code.LANGUAGE_NAME = {
                +  'ar': 'العربية',
                +  'be-tarask': 'Taraškievica',
                +  'br': 'Brezhoneg',
                +  'ca': 'Català',
                +  'cs': 'Česky',
                +  'da': 'Dansk',
                +  'de': 'Deutsch',
                +  'el': 'Ελληνικά',
                +  'en': 'English',
                +  'es': 'Español',
                +  'et': 'Eesti',
                +  'fa': 'فارسی',
                +  'fr': 'Français',
                +  'he': 'עברית',
                +  'hrx': 'Hunsrik',
                +  'hu': 'Magyar',
                +  'ia': 'Interlingua',
                +  'is': 'Íslenska',
                +  'it': 'Italiano',
                +  'ja': '日本語',
                +  'ko': '한국어',
                +  'mk': 'Македонски',
                +  'ms': 'Bahasa Melayu',
                +  'nb': 'Norsk Bokmål',
                +  'nl': 'Nederlands, Vlaams',
                +  'oc': 'Lenga d\'òc',
                +  'pl': 'Polski',
                +  'pms': 'Piemontèis',
                +  'pt-br': 'Português Brasileiro',
                +  'ro': 'Română',
                +  'ru': 'Русский',
                +  'sc': 'Sardu',
                +  'sk': 'Slovenčina',
                +  'sr': 'Српски',
                +  'sv': 'Svenska',
                +  'ta': 'தமிழ்',
                +  'th': 'ภาษาไทย',
                +  'tlh': 'tlhIngan Hol',
                +  'tr': 'Türkçe',
                +  'uk': 'Українська',
                +  'vi': 'Tiếng Việt',
                +  'zh-hans': '简体中文',
                +  'zh-hant': '正體中文'
                +};
                +
                +/**
                + * List of RTL languages.
                + */
                +Code.LANGUAGE_RTL = ['ar', 'fa', 'he', 'lki'];
                +
                +/**
                + * Blockly's main workspace.
                + * @type {Blockly.WorkspaceSvg}
                + */
                +Code.workspace = null;
                +
                +/**
                + * Extracts a parameter from the URL.
                + * If the parameter is absent default_value is returned.
                + * @param {string} name The name of the parameter.
                + * @param {string} defaultValue Value to return if paramater not found.
                + * @return {string} The parameter value or the default value if not found.
                + */
                +Code.getStringParamFromUrl = function(name, defaultValue) {
                +  var val = location.search.match(new RegExp('[?&]' + name + '=([^&]+)'));
                +  return val ? decodeURIComponent(val[1].replace(/\+/g, '%20')) : defaultValue;
                +};
                +
                +/**
                + * Get the language of this user from the URL.
                + * @return {string} User's language.
                + */
                +Code.getLang = function() {
                +  var lang = Code.getStringParamFromUrl('lang', '');
                +  if (Code.LANGUAGE_NAME[lang] === undefined) {
                +    // Default to English.
                +    lang = 'en';
                +  }
                +  return lang;
                +};
                +
                +/**
                + * Is the current language (Code.LANG) an RTL language?
                + * @return {boolean} True if RTL, false if LTR.
                + */
                +Code.isRtl = function() {
                +  return Code.LANGUAGE_RTL.indexOf(Code.LANG) != -1;
                +};
                +
                +/**
                + * Load blocks saved on App Engine Storage or in session/local storage.
                + * @param {string} defaultXml Text representation of default blocks.
                + */
                +Code.loadBlocks = function(defaultXml) {
                +  try {
                +    var loadOnce = window.sessionStorage.loadOnceBlocks;
                +  } catch(e) {
                +    // Firefox sometimes throws a SecurityError when accessing sessionStorage.
                +    // Restarting Firefox fixes this, so it looks like a bug.
                +    var loadOnce = null;
                +  }
                +  if ('BlocklyStorage' in window && window.location.hash.length > 1) {
                +    // An href with #key trigers an AJAX call to retrieve saved blocks.
                +    BlocklyStorage.retrieveXml(window.location.hash.substring(1));
                +  } else if (loadOnce) {
                +    // Language switching stores the blocks during the reload.
                +    delete window.sessionStorage.loadOnceBlocks;
                +    var xml = Blockly.Xml.textToDom(loadOnce);
                +    Blockly.Xml.domToWorkspace(xml, Code.workspace);
                +  } else if (defaultXml) {
                +    // Load the editor with default starting blocks.
                +    var xml = Blockly.Xml.textToDom(defaultXml);
                +    Blockly.Xml.domToWorkspace(xml, Code.workspace);
                +  } else if ('BlocklyStorage' in window) {
                +    // Restore saved blocks in a separate thread so that subsequent
                +    // initialization is not affected from a failed load.
                +    window.setTimeout(BlocklyStorage.restoreBlocks, 0);
                +  }
                +};
                +
                +/**
                + * Save the blocks and reload with a different language.
                + */
                +Code.changeLanguage = function() {
                +  // Store the blocks for the duration of the reload.
                +  // This should be skipped for the index page, which has no blocks and does
                +  // not load Blockly.
                +  // MSIE 11 does not support sessionStorage on file:// URLs.
                +  if (typeof Blockly != 'undefined' && window.sessionStorage) {
                +    var xml = Blockly.Xml.workspaceToDom(Code.workspace);
                +    var text = Blockly.Xml.domToText(xml);
                +    window.sessionStorage.loadOnceBlocks = text;
                +  }
                +
                +  var languageMenu = document.getElementById('languageMenu');
                +  var newLang = encodeURIComponent(
                +      languageMenu.options[languageMenu.selectedIndex].value);
                +  var search = window.location.search;
                +  if (search.length <= 1) {
                +    search = '?lang=' + newLang;
                +  } else if (search.match(/[?&]lang=[^&]*/)) {
                +    search = search.replace(/([?&]lang=)[^&]*/, '$1' + newLang);
                +  } else {
                +    search = search.replace(/\?/, '?lang=' + newLang + '&');
                +  }
                +
                +  window.location = window.location.protocol + '//' +
                +      window.location.host + window.location.pathname + search;
                +};
                +
                +/**
                + * Bind a function to a button's click event.
                + * On touch enabled browsers, ontouchend is treated as equivalent to onclick.
                + * @param {!Element|string} el Button element or ID thereof.
                + * @param {!Function} func Event handler to bind.
                + */
                +Code.bindClick = function(el, func) {
                +  if (typeof el == 'string') {
                +    el = document.getElementById(el);
                +  }
                +  el.addEventListener('click', func, true);
                +  el.addEventListener('touchend', func, true);
                +};
                +
                +/**
                + * Load the Prettify CSS and JavaScript.
                + */
                +Code.importPrettify = function() {
                +  var script = document.createElement('script');
                +  script.setAttribute('src', 'https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js');
                +  document.head.appendChild(script);
                +};
                +
                +/**
                + * Compute the absolute coordinates and dimensions of an HTML element.
                + * @param {!Element} element Element to match.
                + * @return {!Object} Contains height, width, x, and y properties.
                + * @private
                + */
                +Code.getBBox_ = function(element) {
                +  var height = element.offsetHeight;
                +  var width = element.offsetWidth;
                +  var x = 0;
                +  var y = 0;
                +  do {
                +    x += element.offsetLeft;
                +    y += element.offsetTop;
                +    element = element.offsetParent;
                +  } while (element);
                +  return {
                +    height: height,
                +    width: width,
                +    x: x,
                +    y: y
                +  };
                +};
                +
                +/**
                + * User's language (e.g. "en").
                + * @type {string}
                + */
                +Code.LANG = Code.getLang();
                +
                +/**
                + * List of tab names.
                + * @private
                + */
                +Code.TABS_ = ['blocks', 'javascript', 'php', 'python', 'dart', 'lua', 'xml'];
                +
                +Code.selected = 'blocks';
                +
                +/**
                + * Switch the visible pane when a tab is clicked.
                + * @param {string} clickedName Name of tab clicked.
                + */
                +Code.tabClick = function(clickedName) {
                +  // If the XML tab was open, save and render the content.
                +  if (document.getElementById('tab_xml').className == 'tabon') {
                +    var xmlTextarea = document.getElementById('content_xml');
                +    var xmlText = xmlTextarea.value;
                +    var xmlDom = null;
                +    try {
                +      xmlDom = Blockly.Xml.textToDom(xmlText);
                +    } catch (e) {
                +      var q =
                +          window.confirm(MSG['badXml'].replace('%1', e));
                +      if (!q) {
                +        // Leave the user on the XML tab.
                +        return;
                +      }
                +    }
                +    if (xmlDom) {
                +      Code.workspace.clear();
                +      Blockly.Xml.domToWorkspace(xmlDom, Code.workspace);
                +    }
                +  }
                +
                +  if (document.getElementById('tab_blocks').className == 'tabon') {
                +    Code.workspace.setVisible(false);
                +  }
                +  // Deselect all tabs and hide all panes.
                +  for (var i = 0; i < Code.TABS_.length; i++) {
                +    var name = Code.TABS_[i];
                +    document.getElementById('tab_' + name).className = 'taboff';
                +    document.getElementById('content_' + name).style.visibility = 'hidden';
                +  }
                +
                +  // Select the active tab.
                +  Code.selected = clickedName;
                +  document.getElementById('tab_' + clickedName).className = 'tabon';
                +  // Show the selected pane.
                +  document.getElementById('content_' + clickedName).style.visibility =
                +      'visible';
                +  Code.renderContent();
                +  if (clickedName == 'blocks') {
                +    Code.workspace.setVisible(true);
                +  }
                +  Blockly.svgResize(Code.workspace);
                +};
                +
                +/**
                + * Populate the currently selected pane with content generated from the blocks.
                + */
                +Code.renderContent = function() {
                +  var content = document.getElementById('content_' + Code.selected);
                +  // Initialize the pane.
                +  if (content.id == 'content_xml') {
                +    var xmlTextarea = document.getElementById('content_xml');
                +    var xmlDom = Blockly.Xml.workspaceToDom(Code.workspace);
                +    var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
                +    xmlTextarea.value = xmlText;
                +    xmlTextarea.focus();
                +  } else if (content.id == 'content_javascript') {
                +    var code = Blockly.JavaScript.workspaceToCode(Code.workspace);
                +    content.textContent = code;
                +    if (typeof PR.prettyPrintOne == 'function') {
                +      code = content.textContent;
                +      code = PR.prettyPrintOne(code, 'js');
                +      content.innerHTML = code;
                +    }
                +  } else if (content.id == 'content_python') {
                +    code = Blockly.Python.workspaceToCode(Code.workspace);
                +    content.textContent = code;
                +    if (typeof PR.prettyPrintOne == 'function') {
                +      code = content.textContent;
                +      code = PR.prettyPrintOne(code, 'py');
                +      content.innerHTML = code;
                +    }
                +  } else if (content.id == 'content_php') {
                +    code = Blockly.PHP.workspaceToCode(Code.workspace);
                +    content.textContent = code;
                +    if (typeof PR.prettyPrintOne == 'function') {
                +      code = content.textContent;
                +      code = PR.prettyPrintOne(code, 'php');
                +      content.innerHTML = code;
                +    }
                +  } else if (content.id == 'content_dart') {
                +    code = Blockly.Dart.workspaceToCode(Code.workspace);
                +    content.textContent = code;
                +    if (typeof PR.prettyPrintOne == 'function') {
                +      code = content.textContent;
                +      code = PR.prettyPrintOne(code, 'dart');
                +      content.innerHTML = code;
                +    }
                +  } else if (content.id == 'content_lua') {
                +    code = Blockly.Lua.workspaceToCode(Code.workspace);
                +    content.textContent = code;
                +    if (typeof PR.prettyPrintOne == 'function') {
                +      code = content.textContent;
                +      code = PR.prettyPrintOne(code, 'lua');
                +      content.innerHTML = code;
                +    }
                +  }
                +};
                +
                +/**
                + * Initialize Blockly.  Called on page load.
                + */
                +Code.init = function() {
                +  Code.initLanguage();
                +
                +  var rtl = Code.isRtl();
                +  var container = document.getElementById('content_area');
                +  var onresize = function(e) {
                +    var bBox = Code.getBBox_(container);
                +    for (var i = 0; i < Code.TABS_.length; i++) {
                +      var el = document.getElementById('content_' + Code.TABS_[i]);
                +      el.style.top = bBox.y + 'px';
                +      el.style.left = bBox.x + 'px';
                +      // Height and width need to be set, read back, then set again to
                +      // compensate for scrollbars.
                +      el.style.height = bBox.height + 'px';
                +      el.style.height = (2 * bBox.height - el.offsetHeight) + 'px';
                +      el.style.width = bBox.width + 'px';
                +      el.style.width = (2 * bBox.width - el.offsetWidth) + 'px';
                +    }
                +    // Make the 'Blocks' tab line up with the toolbox.
                +    if (Code.workspace && Code.workspace.toolbox_.width) {
                +      document.getElementById('tab_blocks').style.minWidth =
                +          (Code.workspace.toolbox_.width - 38) + 'px';
                +          // Account for the 19 pixel margin and on each side.
                +    }
                +  };
                +  window.addEventListener('resize', onresize, false);
                +
                +  // The toolbox XML specifies each category name using Blockly's messaging
                +  // format (eg. `<category name="%{BKY_CATLOGIC}">`).
                +  // These message keys need to be defined in `Blockly.Msg` in order to
                +  // be decoded by the library. Therefore, we'll use the `MSG` dictionary that's
                +  // been defined for each language to import each category name message
                +  // into `Blockly.Msg`.
                +  // TODO: Clean up the message files so this is done explicitly instead of
                +  // through this for-loop.
                +  for (var messageKey in MSG) {
                +    if (goog.string.startsWith(messageKey, 'cat')) {
                +      Blockly.Msg[messageKey.toUpperCase()] = MSG[messageKey];
                +    }
                +  }
                +
                +  // Construct the toolbox XML.
                +  var toolboxText = document.getElementById('toolbox').outerHTML;
                +  var toolboxXml = Blockly.Xml.textToDom(toolboxText);
                +
                +  Code.workspace = Blockly.inject('content_blocks',
                +      {grid:
                +          {spacing: 25,
                +           length: 3,
                +           colour: '#ccc',
                +           snap: true},
                +       media: '../../media/',
                +       rtl: rtl,
                +       toolbox: toolboxXml,
                +       zoom:
                +           {controls: true,
                +            wheel: true}
                +      });
                +
                +  // Add to reserved word list: Local variables in execution environment (runJS)
                +  // and the infinite loop detection function.
                +  Blockly.JavaScript.addReservedWords('code,timeouts,checkTimeout');
                +
                +  Code.loadBlocks('');
                +
                +  if ('BlocklyStorage' in window) {
                +    // Hook a save function onto unload.
                +    BlocklyStorage.backupOnUnload(Code.workspace);
                +  }
                +
                +  Code.tabClick(Code.selected);
                +
                +  Code.bindClick('trashButton',
                +      function() {Code.discard(); Code.renderContent();});
                +  Code.bindClick('runButton', Code.runJS);
                +  // Disable the link button if page isn't backed by App Engine storage.
                +  var linkButton = document.getElementById('linkButton');
                +  if ('BlocklyStorage' in window) {
                +    BlocklyStorage['HTTPREQUEST_ERROR'] = MSG['httpRequestError'];
                +    BlocklyStorage['LINK_ALERT'] = MSG['linkAlert'];
                +    BlocklyStorage['HASH_ERROR'] = MSG['hashError'];
                +    BlocklyStorage['XML_ERROR'] = MSG['xmlError'];
                +    Code.bindClick(linkButton,
                +        function() {BlocklyStorage.link(Code.workspace);});
                +  } else if (linkButton) {
                +    linkButton.className = 'disabled';
                +  }
                +
                +  for (var i = 0; i < Code.TABS_.length; i++) {
                +    var name = Code.TABS_[i];
                +    Code.bindClick('tab_' + name,
                +        function(name_) {return function() {Code.tabClick(name_);};}(name));
                +  }
                +  onresize();
                +  Blockly.svgResize(Code.workspace);
                +
                +  // Lazy-load the syntax-highlighting.
                +  window.setTimeout(Code.importPrettify, 1);
                +};
                +
                +/**
                + * Initialize the page language.
                + */
                +Code.initLanguage = function() {
                +  // Set the HTML's language and direction.
                +  var rtl = Code.isRtl();
                +  document.dir = rtl ? 'rtl' : 'ltr';
                +  document.head.parentElement.setAttribute('lang', Code.LANG);
                +
                +  // Sort languages alphabetically.
                +  var languages = [];
                +  for (var lang in Code.LANGUAGE_NAME) {
                +    languages.push([Code.LANGUAGE_NAME[lang], lang]);
                +  }
                +  var comp = function(a, b) {
                +    // Sort based on first argument ('English', 'Русский', '简体字', etc).
                +    if (a[0] > b[0]) return 1;
                +    if (a[0] < b[0]) return -1;
                +    return 0;
                +  };
                +  languages.sort(comp);
                +  // Populate the language selection menu.
                +  var languageMenu = document.getElementById('languageMenu');
                +  languageMenu.options.length = 0;
                +  for (var i = 0; i < languages.length; i++) {
                +    var tuple = languages[i];
                +    var lang = tuple[tuple.length - 1];
                +    var option = new Option(tuple[0], lang);
                +    if (lang == Code.LANG) {
                +      option.selected = true;
                +    }
                +    languageMenu.options.add(option);
                +  }
                +  languageMenu.addEventListener('change', Code.changeLanguage, true);
                +
                +  // Inject language strings.
                +  document.title += ' ' + MSG['title'];
                +  document.getElementById('title').textContent = MSG['title'];
                +  document.getElementById('tab_blocks').textContent = MSG['blocks'];
                +
                +  document.getElementById('linkButton').title = MSG['linkTooltip'];
                +  document.getElementById('runButton').title = MSG['runTooltip'];
                +  document.getElementById('trashButton').title = MSG['trashTooltip'];
                +};
                +
                +/**
                + * Execute the user's code.
                + * Just a quick and dirty eval.  Catch infinite loops.
                + */
                +Code.runJS = function() {
                +  Blockly.JavaScript.INFINITE_LOOP_TRAP = '  checkTimeout();\n';
                +  var timeouts = 0;
                +  var checkTimeout = function() {
                +    if (timeouts++ > 1000000) {
                +      throw MSG['timeout'];
                +    }
                +  };
                +  var code = Blockly.JavaScript.workspaceToCode(Code.workspace);
                +  Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
                +  try {
                +    eval(code);
                +  } catch (e) {
                +    alert(MSG['badCode'].replace('%1', e));
                +  }
                +};
                +
                +/**
                + * Discard all blocks from the workspace.
                + */
                +Code.discard = function() {
                +  var count = Code.workspace.getAllBlocks().length;
                +  if (count < 2 ||
                +      window.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace('%1', count))) {
                +    Code.workspace.clear();
                +    if (window.location.hash) {
                +      window.location.hash = '';
                +    }
                +  }
                +};
                +
                +// Load the Code demo's language strings.
                +document.write('<script src="msg/' + Code.LANG + '.js"></script>\n');
                +// Load Blockly's language strings.
                +document.write('<script src="../../msg/js/' + Code.LANG + '.js"></script>\n');
                +
                +window.addEventListener('load', Code.init);
                diff --git a/blockly/webif/static/blockly/demos/code/icon.png b/blockly/webif/static/blockly/demos/code/icon.png
                new file mode 100644
                index 000000000..e2f23bd83
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/code/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/code/icons.png b/blockly/webif/static/blockly/demos/code/icons.png
                new file mode 100644
                index 000000000..7cced7a7e
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/code/icons.png differ
                diff --git a/blockly/webif/static/blockly/demos/code/index.html b/blockly/webif/static/blockly/demos/code/index.html
                new file mode 100644
                index 000000000..84a35ab50
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/index.html
                @@ -0,0 +1,374 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <meta name="google" value="notranslate">
                +  <title>Blockly Demo:</title>
                +  <link rel="stylesheet" href="style.css">
                +  <script src="/storage.js"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../python_compressed.js"></script>
                +  <script src="../../php_compressed.js"></script>
                +  <script src="../../lua_compressed.js"></script>
                +  <script src="../../dart_compressed.js"></script>
                +  <script src="code.js"></script>
                +</head>
                +<body>
                +  <table width="100%" height="100%">
                +    <tr>
                +      <td>
                +        <h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt;
                +          <a href="../index.html">Demos</a>&rlm; &gt;
                +          <span id="title">...</span>
                +        </h1>
                +      </td>
                +      <td class="farSide">
                +        <select id="languageMenu"></select>
                +      </td>
                +    </tr>
                +    <tr>
                +      <td colspan=2>
                +        <table width="100%">
                +          <tr id="tabRow" height="1em">
                +            <td id="tab_blocks" class="tabon">...</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_javascript" class="taboff">JavaScript</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_python" class="taboff">Python</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_php" class="taboff">PHP</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_lua" class="taboff">Lua</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_dart" class="taboff">Dart</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_xml" class="taboff">XML</td>
                +            <td class="tabmax">
                +              <button id="trashButton" class="notext" title="...">
                +                <img src='../../media/1x1.gif' class="trash icon21">
                +              </button>
                +              <button id="linkButton" class="notext" title="...">
                +                <img src='../../media/1x1.gif' class="link icon21">
                +              </button>
                +              <button id="runButton" class="notext primary" title="...">
                +                <img src='../../media/1x1.gif' class="run icon21">
                +              </button>
                +            </td>
                +          </tr>
                +        </table>
                +      </td>
                +    </tr>
                +    <tr>
                +      <td height="99%" colspan=2 id="content_area">
                +      </td>
                +    </tr>
                +  </table>
                +  <div id="content_blocks" class="content"></div>
                +  <pre id="content_javascript" class="content"></pre>
                +  <pre id="content_python" class="content"></pre>
                +  <pre id="content_php" class="content"></pre>
                +  <pre id="content_lua" class="content"></pre>
                +  <pre id="content_dart" class="content"></pre>
                +  <textarea id="content_xml" class="content" wrap="off"></textarea>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="%{BKY_CATLOGIC}" colour="%{BKY_LOGIC_HUE}">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="%{BKY_CATLOOPS}" colour="%{BKY_LOOPS_HUE}">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +        <value name="BY">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="%{BKY_CATMATH}" colour="%{BKY_MATH_HUE}">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="%{BKY_CATTEXT}" colour="%{BKY_TEXTS_HUE}">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT"></field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">{textVariable}</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">{textVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">{textVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="%{BKY_CATLISTS}" colour="%{BKY_LISTS_HUE}">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">{listVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">{listVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">{listVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">{listVariable}</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <shadow type="text">
                +            <field name="TEXT">,</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_sort"></block>
                +    </category>
                +    <category name="%{BKY_CATCOLOUR}" colour="%{BKY_COLOUR_HUE}">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +        <value name="GREEN">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="BLUE">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </shadow>
                +        </value>
                +        <value name="COLOUR2">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </shadow>
                +        </value>
                +        <value name="RATIO">
                +          <shadow type="math_number">
                +            <field name="NUM">0.5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="%{BKY_CATVARIABLES}" colour="%{BKY_VARIABLES_HUE}" custom="VARIABLE"></category>
                +    <category name="%{BKY_CATFUNCTIONS}" colour="%{BKY_PROCEDURES_HUE}" custom="PROCEDURE"></category>
                +  </xml>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ar.js b/blockly/webif/static/blockly/demos/code/msg/ar.js
                new file mode 100644
                index 000000000..952198b21
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ar.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "كود",
                +  blocks: "البلوكات",
                +  linkTooltip: "احفظ ووصلة إلى البلوكات.",
                +  runTooltip: "شغل البرنامج المعرف بواسطة البلوكات في مساحة العمل.",
                +  badCode: "خطأ في البرنامج:\n %1",
                +  timeout: "تم تجاوز الحد الأقصى لتكرارات التنفيذ .",
                +  trashTooltip: "تجاهل كل البلوكات.",
                +  catLogic: "منطق",
                +  catLoops: "الحلقات",
                +  catMath: "رياضيات",
                +  catText: "نص",
                +  catLists: "قوائم",
                +  catColour: "لون",
                +  catVariables: "متغيرات",
                +  catFunctions: "إجراءات",
                +  listVariable: "قائمة",
                +  textVariable: "نص",
                +  httpRequestError: "كانت هناك مشكلة مع هذا الطلب.",
                +  linkAlert: "مشاركة كود بلوكلي الخاص بك مع هذا الرابط:\n %1",
                +  hashError: "عذراً،ال '%1' لا تتوافق مع أي برنامج تم حفظه.",
                +  xmlError: "تعذر تحميل الملف المحفوظة الخاصة بك.  ربما تم إنشاؤه باستخدام إصدار مختلف من بلوكلي؟",
                +  badXml: "خطأ في توزيع ال \"XML\":\n %1\n\nحدد 'موافق' للتخلي عن التغييرات أو 'إلغاء الأمر' لمواصلة تحرير ال\"XML\"."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/be-tarask.js b/blockly/webif/static/blockly/demos/code/msg/be-tarask.js
                new file mode 100644
                index 000000000..5c8d72264
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/be-tarask.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Код",
                +  blocks: "Блёкі",
                +  linkTooltip: "Захаваць і зьвязаць з блёкамі.",
                +  runTooltip: "Запусьціце праграму, вызначаную блёкамі ў працоўнай вобласьці.",
                +  badCode: "Памылка праграмы:\n%1",
                +  timeout: "Перавышана максымальная колькасьць ітэрацыяў.",
                +  trashTooltip: "Выдаліць усе блёкі.",
                +  catLogic: "Лёгіка",
                +  catLoops: "Петлі",
                +  catMath: "Матэматычныя формулы",
                +  catText: "Тэкст",
                +  catLists: "Сьпісы",
                +  catColour: "Колер",
                +  catVariables: "Зьменныя",
                +  catFunctions: "Функцыі",
                +  listVariable: "сьпіс",
                +  textVariable: "тэкст",
                +  httpRequestError: "Узьнікла праблема з запытам.",
                +  linkAlert: "Падзяліцца Вашым блёкам праз гэтую спасылку:\n\n%1",
                +  hashError: "Прабачце, '%1' не адпавядае ніводнай захаванай праграме.",
                +  xmlError: "Не атрымалася загрузіць захаваны файл. Магчыма, ён быў створаны з іншай вэрсіяй Блёклі?",
                +  badXml: "Памылка сынтаксічнага аналізу XML:\n%1\n\nАбярыце \"ОК\", каб адмовіцца ад зьменаў ці \"Скасаваць\" для далейшага рэдагаваньня XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/br.js b/blockly/webif/static/blockly/demos/code/msg/br.js
                new file mode 100644
                index 000000000..321e28e58
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/br.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kod",
                +  blocks: "Bloc'hoù",
                +  linkTooltip: "Enrollañ ha liammañ d'ar bloc'hadoù.",
                +  runTooltip: "Lañsañ ar programm termenet gant ar bloc'hadoù en takad labour.",
                +  badCode: "Fazi programm :\n%1",
                +  timeout: "Tizhet eo bet an niver brasañ a iteradurioù seveniñ aotreet.",
                +  trashTooltip: "Disteurel an holl vloc'hoù.",
                +  catLogic: "Poell",
                +  catLoops: "Boukloù",
                +  catMath: "Matematik",
                +  catText: "Testenn",
                +  catLists: "Rolloù",
                +  catColour: "Liv",
                +  catVariables: "Argemmennoù",
                +  catFunctions: "Arc'hwelioù",
                +  listVariable: "roll",
                +  textVariable: "testenn",
                +  httpRequestError: "Ur gudenn zo gant ar reked.",
                +  linkAlert: "Rannañ ho ploc'hoù gant al liamm-mañ :\n\n%1",
                +  hashError: "Digarezit. \"%1\" ne glot gant programm enrollet ebet.",
                +  xmlError: "Ne c'haller ket kargañ ho restr enrollet. Marteze e oa bet krouet gant ur stumm disheñvel eus Blockly ?",
                +  badXml: "Fazi dielfennañ XML :\n%1\n\nDibabit \"Mat eo\" evit dilezel ar c'hemmoù-se pe \"Nullañ\" evit kemmañ an XML c'hoazh."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ca.js b/blockly/webif/static/blockly/demos/code/msg/ca.js
                new file mode 100644
                index 000000000..2b6d9738e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ca.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Codi",
                +  blocks: "Blocs",
                +  linkTooltip: "Desa i enllaça als blocs.",
                +  runTooltip: "Executa el programa definit pels blocs de l'àrea de treball.",
                +  badCode: "Error de programa:\n %1",
                +  timeout: "S'ha superat el nombre màxim d'iteracions d'execució.",
                +  trashTooltip: "Descarta tots els blocs.",
                +  catLogic: "Lògica",
                +  catLoops: "Bucles",
                +  catMath: "Matemàtiques",
                +  catText: "Text",
                +  catLists: "Llistes",
                +  catColour: "Color",
                +  catVariables: "Variables",
                +  catFunctions: "Procediments",
                +  listVariable: "llista",
                +  textVariable: "text",
                +  httpRequestError: "Hi ha hagut un problema amb la sol·licitud.",
                +  linkAlert: "Comparteix els teus blocs amb aquest enllaç: %1",
                +  hashError: "Ho sentim, '%1' no es correspon amb cap fitxer desat de Blockly.",
                +  xmlError: "No s'ha pogut carregar el teu fitxer desat.  Potser va ser creat amb una versió diferent de Blockly?",
                +  badXml: "Error d'anàlisi XML:\n%1\n\nSeleccioneu 'Acceptar' per abandonar els vostres canvis, o 'Cancel·lar' per continuar editant l'XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/cs.js b/blockly/webif/static/blockly/demos/code/msg/cs.js
                new file mode 100644
                index 000000000..1026511e3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/cs.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kód",
                +  blocks: "Bloky",
                +  linkTooltip: "Ulož a spoj bloky..",
                +  runTooltip: "",
                +  badCode: "Chyba programu:\n%1",
                +  timeout: "Maximum execution iterations exceeded.",
                +  trashTooltip: "Zahodit všechny bloky.",
                +  catLogic: "Logika",
                +  catLoops: "Smyčky",
                +  catMath: "Matematika",
                +  catText: "Text",
                +  catLists: "Seznamy",
                +  catColour: "Barva",
                +  catVariables: "Proměnné",
                +  catFunctions: "Procedury",
                +  listVariable: "seznam",
                +  textVariable: "text",
                +  httpRequestError: "Došlo k potížím s požadavkem.",
                +  linkAlert: "Sdílej bloky tímto odkazem: \n\n%1",
                +  hashError: "Omlouváme se, '%1' nesouhlasí s žádným z uložených souborů.",
                +  xmlError: "Nepodařilo se uložit vás soubor.  Pravděpodobně byl vytvořen jinou verzí Blockly?",
                +  badXml: "Chyba parsování XML:\n%1\n\nVybrat \"OK\" pro zahození vašich změn nebo 'Cancel' k dalšímu upravování XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/da.js b/blockly/webif/static/blockly/demos/code/msg/da.js
                new file mode 100644
                index 000000000..089450b2d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/da.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kode",
                +  blocks: "Blokke",
                +  linkTooltip: "Gem og link til blokke.",
                +  runTooltip: "Kør programmet, der er defineret af blokkene i arbejdsområdet.",
                +  badCode: "Programfejl:\n%1",
                +  timeout: "Maksimale antal udførelsesgentagelser overskredet.",
                +  trashTooltip: "Kassér alle blokke.",
                +  catLogic: "Logik",
                +  catLoops: "Løkker",
                +  catMath: "Matematik",
                +  catText: "Tekst",
                +  catLists: "Lister",
                +  catColour: "Farve",
                +  catVariables: "Variabler",
                +  catFunctions: "Funktioner",
                +  listVariable: "liste",
                +  textVariable: "tekst",
                +  httpRequestError: "Der var et problem med forespørgslen.",
                +  linkAlert: "Del dine blokke med dette link:\n\n%1",
                +  hashError: "Beklager, '%1' passer ikke med nogen gemt Blockly fil.",
                +  xmlError: "Kunne ikke hente din gemte fil.  Måske er den lavet med en anden udgave af Blockly?",
                +  badXml: "Fejl under fortolkningen af XML:\n%1\n\nVælg 'OK' for at opgive dine ændringer eller 'Afbryd' for at redigere XML-filen yderligere."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/de.js b/blockly/webif/static/blockly/demos/code/msg/de.js
                new file mode 100644
                index 000000000..422f9187d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/de.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Code",
                +  blocks: "Bausteine",
                +  linkTooltip: "Speichern und auf Bausteine verlinken.",
                +  runTooltip: "Das Programm ausführen, das von den Bausteinen im Arbeitsbereich definiert ist.",
                +  badCode: "Programmfehler:\n%1",
                +  timeout: "Die maximalen Ausführungswiederholungen wurden überschritten.",
                +  trashTooltip: "Alle Bausteine verwerfen.",
                +  catLogic: "Logik",
                +  catLoops: "Schleifen",
                +  catMath: "Mathematik",
                +  catText: "Text",
                +  catLists: "Listen",
                +  catColour: "Farbe",
                +  catVariables: "Variablen",
                +  catFunctions: "Funktionen",
                +  listVariable: "Liste",
                +  textVariable: "Text",
                +  httpRequestError: "Mit der Anfrage gab es ein Problem.",
                +  linkAlert: "Teile deine Bausteine mit diesem Link:\n\n%1",
                +  hashError: "„%1“ stimmt leider mit keinem gespeicherten Programm überein.",
                +  xmlError: "Deine gespeicherte Datei konnte nicht geladen werden. Vielleicht wurde sie mit einer anderen Version von Blockly erstellt.",
                +  badXml: "Fehler beim Parsen von XML:\n%1\n\nWähle 'OK' zum Verwerfen deiner Änderungen oder 'Abbrechen' zum weiteren Bearbeiten des XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/el.js b/blockly/webif/static/blockly/demos/code/msg/el.js
                new file mode 100644
                index 000000000..c63b7a685
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/el.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Κώδικας",
                +  blocks: "Μπλοκ",
                +  linkTooltip: "Αποθηκεύει και συνδέει σε μπλοκ.",
                +  runTooltip: "Εκτελεί το πρόγραμμα που ορίζεται από τα μπλοκ στον χώρο εργασίας.",
                +  badCode: "Σφάλμα προγράμματος:\n%1",
                +  timeout: "Υπέρβαση μέγιστου αριθμού επαναλήψεων.",
                +  trashTooltip: "Απόρριψη όλων των μπλοκ.",
                +  catLogic: "Λογική",
                +  catLoops: "Επαναλήψεις",
                +  catMath: "Μαθηματικά",
                +  catText: "Κείμενο",
                +  catLists: "Λίστες",
                +  catColour: "Χρώμα",
                +  catVariables: "Μεταβλητές",
                +  catFunctions: "Συναρτήσεις",
                +  listVariable: "λίστα",
                +  textVariable: "κείμενο",
                +  httpRequestError: "Υπήρξε πρόβλημα με το αίτημα.",
                +  linkAlert: "Κοινοποίησε τα μπλοκ σου με αυτόν τον σύνδεσμο:\n\n%1",
                +  hashError: "Λυπάμαι, το «%1» δεν αντιστοιχεί σε κανένα αποθηκευμένο πρόγραμμα.",
                +  xmlError: "Δεν μπορώ να φορτώσω το αποθηκευμένο αρχείο σου.  Μήπως δημιουργήθηκε από μία παλιότερη έκδοση του Blockly;",
                +  badXml: "Σφάλμα ανάλυσης XML:\n%1\n\nΕπίλεξε «Εντάξει» για να εγκαταλείψεις τις αλλαγές σου ή «Ακύρωση» για να επεξεργαστείς το XML κι άλλο."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/en.js b/blockly/webif/static/blockly/demos/code/msg/en.js
                new file mode 100644
                index 000000000..8d52cf333
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/en.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Code",
                +  blocks: "Blocks",
                +  linkTooltip: "Save and link to blocks.",
                +  runTooltip: "Run the program defined by the blocks in the workspace.",
                +  badCode: "Program error:\n%1",
                +  timeout: "Maximum execution iterations exceeded.",
                +  trashTooltip: "Discard all blocks.",
                +  catLogic: "Logic",
                +  catLoops: "Loops",
                +  catMath: "Math",
                +  catText: "Text",
                +  catLists: "Lists",
                +  catColour: "Colour",
                +  catVariables: "Variables",
                +  catFunctions: "Functions",
                +  listVariable: "list",
                +  textVariable: "text",
                +  httpRequestError: "There was a problem with the request.",
                +  linkAlert: "Share your blocks with this link:\n\n%1",
                +  hashError: "Sorry, '%1' doesn't correspond with any saved program.",
                +  xmlError: "Could not load your saved file. Perhaps it was created with a different version of Blockly?",
                +  badXml: "Error parsing XML:\n%1\n\nSelect 'OK' to abandon your changes or 'Cancel' to further edit the XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/es.js b/blockly/webif/static/blockly/demos/code/msg/es.js
                new file mode 100644
                index 000000000..24358e368
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/es.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Código",
                +  blocks: "Bloques",
                +  linkTooltip: "Guarda conexión a los bloques.",
                +  runTooltip: "Ejecute el programa definido por los bloques en el área de trabajo.",
                +  badCode: "Error del programa:\n%1",
                +  timeout: "Se excedio el máximo de iteraciones ejecutadas permitidas.",
                +  trashTooltip: "Descartar todos los bloques.",
                +  catLogic: "Lógica",
                +  catLoops: "Secuencias",
                +  catMath: "Matemáticas",
                +  catText: "Texto",
                +  catLists: "Listas",
                +  catColour: "Color",
                +  catVariables: "Variables",
                +  catFunctions: "Funciones",
                +  listVariable: "lista",
                +  textVariable: "texto",
                +  httpRequestError: "Hubo un problema con la petición.",
                +  linkAlert: "Comparte tus bloques con este enlace:\n\n%1",
                +  hashError: "«%1» no corresponde con ningún programa guardado.",
                +  xmlError: "No se pudo cargar el archivo guardado.  ¿Quizá fue creado con otra versión de Blockly?",
                +  badXml: "Error de análisis XML:\n%1\n\nSelecciona OK para abandonar tus cambios o Cancelar para seguir editando el XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/et.js b/blockly/webif/static/blockly/demos/code/msg/et.js
                new file mode 100644
                index 000000000..320c39174
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/et.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kood",
                +  blocks: "Plokid",
                +  linkTooltip: "Salvesta ja tekita link plokkidele.",
                +  runTooltip: "Käivita töölaual olevate plokkidega defineeritud programm.",
                +  badCode: "Viga programmis:\n%1",
                +  timeout: "Käivitatavate iteratsioonide maksimaalne arv on ületatud.",
                +  trashTooltip: "Eemalda kõik plokid.",
                +  catLogic: "Loogika",
                +  catLoops: "Kordus",
                +  catMath: "Matemaatika",
                +  catText: "Tekst",
                +  catLists: "Loendid",
                +  catColour: "Värv",
                +  catVariables: "Muutujad",
                +  catFunctions: "Funktsioonid",
                +  listVariable: "loend",
                +  textVariable: "tekst",
                +  httpRequestError: "Probleem päringuga.",
                +  linkAlert: "Oma plokke saad jagada selle lingiga:\n\n%1",
                +  hashError: "Vabandust, kuid '%1' ei vasta ühelegi salvestatud programmile.",
                +  xmlError: "Su salvestatud faili ei õnnestunud laadida. Võibolla on see loodud mõne teise Blockly versiooniga?",
                +  badXml: "Viga XML-i parsimisel:\n%1\n\nTehtud muudatustest loobumiseks vajuta 'OK', XML-i muudatuste tegemise jätkamiseks 'Katkesta'."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/fa.js b/blockly/webif/static/blockly/demos/code/msg/fa.js
                new file mode 100644
                index 000000000..96dd966b0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/fa.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "کد",
                +  blocks: "بلوک‌ها",
                +  linkTooltip: "ذخیره و پیوند به بلوک‌ها.",
                +  runTooltip: "اجرای برنامهٔ تعریف‌شده توسط بلوک‌ها در فضای کار.",
                +  badCode: "خطای برنامه:\n%1",
                +  timeout: "حداکثر تکرارهای اجرا رد شده‌است.",
                +  trashTooltip: "دورریختن همهٔ بلوک‌ها.",
                +  catLogic: "منطق",
                +  catLoops: "حلقه‌ها",
                +  catMath: "ریاضی",
                +  catText: "متن",
                +  catLists: "فهرست‌ها",
                +  catColour: "رنگ",
                +  catVariables: "متغییرها",
                +  catFunctions: "توابع",
                +  listVariable: "فهرست",
                +  textVariable: "متن",
                +  httpRequestError: "مشکلی با درخواست وجود داشت.",
                +  linkAlert: "اشتراک‌گذاری بلاک‌هایتان با این پیوند:\n\n%1",
                +  hashError: "شرمنده، «%1» با هیچ برنامهٔ ذخیره‌شده‌ای تطبیق پیدا نکرد.",
                +  xmlError: "نتوانست پروندهٔ ذخیرهٔ شما بارگیری شود.  احتمالاً با نسخهٔ متفاوتی از بلوکی درست شده‌است؟",
                +  badXml: "خطای تجزیهٔ اکس‌ام‌ال:\n%1\n\n«باشد» را برای ذخیره و «فسخ» را برای ویرایش بیشتر اکس‌ام‌ال انتخاب کنید."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/fr.js b/blockly/webif/static/blockly/demos/code/msg/fr.js
                new file mode 100644
                index 000000000..60181131a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/fr.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Code",
                +  blocks: "Blocs",
                +  linkTooltip: "Sauvegarder et lier aux blocs.",
                +  runTooltip: "Lancer le programme défini par les blocs dans l’espace de travail.",
                +  badCode: "Erreur du programme :\n%1",
                +  timeout: "Nombre maximum d’itérations d’exécution dépassé.",
                +  trashTooltip: "Jeter tous les blocs.",
                +  catLogic: "Logique",
                +  catLoops: "Boucles",
                +  catMath: "Math",
                +  catText: "Texte",
                +  catLists: "Listes",
                +  catColour: "Couleur",
                +  catVariables: "Variables",
                +  catFunctions: "Fonctions",
                +  listVariable: "liste",
                +  textVariable: "texte",
                +  httpRequestError: "Il y a eu un problème avec la demande.",
                +  linkAlert: "Partagez vos blocs grâce à ce lien:\n\n%1",
                +  hashError: "Désolé, '%1' ne correspond à aucun programme sauvegardé.",
                +  xmlError: "Impossible de charger le fichier de sauvegarde.  Peut être a t-il été créé avec une autre version de Blockly?",
                +  badXml: "Erreur d’analyse du XML :\n%1\n\nSélectionner 'OK' pour abandonner vos modifications ou 'Annuler' pour continuer à modifier le XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/he.js b/blockly/webif/static/blockly/demos/code/msg/he.js
                new file mode 100644
                index 000000000..dc2826620
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/he.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "קוד",
                +  blocks: "קטעי קוד",
                +  linkTooltip: "שמירה וקישור לקטעי קוד.",
                +  runTooltip: "הרצת התכנית שהוגדרה על ידי קטעי הקוד שבמרחב העבודה.",
                +  badCode: "שגיאה בתכנית: %1",
                +  timeout: "חריגה ממספר פעולות חוזרות אפשריות.",
                +  trashTooltip: "השלך את כל קטעי הקוד.",
                +  catLogic: "לוגיקה",
                +  catLoops: "לולאות",
                +  catMath: "מתמטיקה",
                +  catText: "טקסט",
                +  catLists: "רשימות",
                +  catColour: "צבע",
                +  catVariables: "משתנים",
                +  catFunctions: "פונקציות",
                +  listVariable: "רשימה",
                +  textVariable: "טקסט",
                +  httpRequestError: "הבקשה נכשלה.",
                +  linkAlert: "ניתן לשתף את קטעי הקוד שלך באמצעות קישור זה:\n\n%1",
                +  hashError: "לצערנו, '%1' איננו מתאים לאף אחת מהתוכניות השמורות",
                +  xmlError: "נסיון הטעינה של הקובץ השמור שלך נכשל. האם ייתכן שהוא נוצר בגרסא שונה של בלוקלי?",
                +  badXml: "תקלה בפענוח XML:\n\n%1\n\nנא לבחור 'אישור' כדי לנטוש את השינויים שלך או 'ביטול' כדי להמשיך ולערוך את ה־XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/hrx.js b/blockly/webif/static/blockly/demos/code/msg/hrx.js
                new file mode 100644
                index 000000000..ca0dea3fc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/hrx.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Code",
                +  blocks: "Bausten",
                +  linkTooltip: "Speichre und auf Bausten verlinke.",
                +  runTooltip: "Das Programm ausfüahre, das von den Bausten im Oorweitsbereich definiert ist.",
                +  badCode: "Programmfehler:\n%1",
                +  timeout: "Die maximale Ausführungswiederholunge woore üwerschritt.",
                +  trashTooltip: "All Bausten verwerfe.",
                +  catLogic: "Logik",
                +  catLoops: "Schleife",
                +  catMath: "Mathematik",
                +  catText: "Text",
                +  catLists: "Liste",
                +  catColour: "Farreb",
                +  catVariables: "Variable",
                +  catFunctions: "Funktione",
                +  listVariable: "List",
                +  textVariable: "Text",
                +  httpRequestError: "Mit der Oonfroch hots en Problem geb.",
                +  linkAlert: "Tel von dein Bausten mit dem Link:\n\n%1",
                +  hashError: "„%1“ stimmt leider mit kenem üweren gespeicherte Programm.",
                +  xmlError: "Dein gespeicherte Datei könnt net gelood sin. Vielleicht woard se mit ener annre Version von Blockly erstellt.",
                +  badXml: "Fehler beim Parse von XML:\n%1\n\nWähle 'OK' zum Verwerfe von deiner Ändrunge orrer 'Abbreche' zum XML weiter beoorbeite."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/hu.js b/blockly/webif/static/blockly/demos/code/msg/hu.js
                new file mode 100644
                index 000000000..eee186863
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/hu.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kódszerkesztő",
                +  blocks: "Blokkok",
                +  linkTooltip: "Hivatkozás létrehozása",
                +  runTooltip: "Program futtatása.",
                +  badCode: "Program hiba:\n%1",
                +  timeout: "A program elérte a maximális végrehajtási időt.",
                +  trashTooltip: "Összes blokk törlése.",
                +  catLogic: "Logikai műveletek",
                +  catLoops: "Ciklusok",
                +  catMath: "Matematikai műveletek",
                +  catText: "Sztring műveletek",
                +  catLists: "Listakezelés",
                +  catColour: "Színek",
                +  catVariables: "Változók",
                +  catFunctions: "Eljárások",
                +  listVariable: "lista",
                +  textVariable: "szöveg",
                +  httpRequestError: "A kéréssel kapcsolatban probléma merült fel.",
                +  linkAlert: "Ezzel a hivatkozással tudod megosztani a programodat:\n\n%1",
                +  hashError: "Sajnos a '%1' hivatkozás nem tartozik egyetlen programhoz sem.",
                +  xmlError: "A programodat nem lehet betölteni.  Elképzelhető, hogy a Blockly egy másik verziójában készült?",
                +  badXml: "Hiba az XML feldolgozásakor:\n%1\n\nVáltozások elvetése?"
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ia.js b/blockly/webif/static/blockly/demos/code/msg/ia.js
                new file mode 100644
                index 000000000..5938458bb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ia.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Codice",
                +  blocks: "Blocos",
                +  linkTooltip: "Salveguardar e ligar a blocos.",
                +  runTooltip: "Executar le programma definite per le blocos in le spatio de travalio.",
                +  badCode: "Error del programma:\n%1",
                +  timeout: "Le numero de iterationes executate ha excedite le maximo.",
                +  trashTooltip: "Abandonar tote le blocos.",
                +  catLogic: "Logica",
                +  catLoops: "Buclas",
                +  catMath: "Mathematica",
                +  catText: "Texto",
                +  catLists: "Listas",
                +  catColour: "Color",
                +  catVariables: "Variabiles",
                +  catFunctions: "Functiones",
                +  listVariable: "lista",
                +  textVariable: "texto",
                +  httpRequestError: "Il habeva un problema con le requesta.",
                +  linkAlert: "Divide tu blocos con iste ligamine:\n\n%1",
                +  hashError: "Infelicemente, '%1' non corresponde a alcun programma salveguardate.",
                +  xmlError: "Impossibile cargar le file salveguardate. Pote esser que illo ha essite create con un altere version de Blockly?",
                +  badXml: "Error de analyse del XML:\n%1\n\nSelige 'OK' pro abandonar le modificationes o 'Cancellar' pro continuar a modificar le codice XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/is.js b/blockly/webif/static/blockly/demos/code/msg/is.js
                new file mode 100644
                index 000000000..fa5c40d80
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/is.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kóði",
                +  blocks: "Kubbar",
                +  linkTooltip: "Vista og tengja við kubba.",
                +  runTooltip: "Keyra forritið sem kubbarnir á vinnusvæðinu mynda.",
                +  badCode: "Villa í forriti:\n%1",
                +  timeout: "Forritið hefur endurtekið sig of oft.",
                +  trashTooltip: "Fleygja öllum kubbum.",
                +  catLogic: "Rökvísi",
                +  catLoops: "Lykkjur",
                +  catMath: "Reikningur",
                +  catText: "Texti",
                +  catLists: "Listar",
                +  catColour: "Litir",
                +  catVariables: "Breytur",
                +  catFunctions: "Stefjur",
                +  listVariable: "listi",
                +  textVariable: "texti",
                +  httpRequestError: "Það kom upp vandamál með beiðnina.",
                +  linkAlert: "Deildu kubbunum þínum með þessari krækju:",
                +  hashError: "Því miður, '%1' passar ekki við neitt vistað forrit.",
                +  xmlError: "Gat ekki hlaðið vistuðu skrána þína. Var hún kannske búin til í annarri útgáfu af Blockly?",
                +  badXml: "Villa við úrvinnslu XML:\n%1\n\nVeldu 'Í lagi' til að sleppa breytingum eða 'Hætta við' til að halda áfram með XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/it.js b/blockly/webif/static/blockly/demos/code/msg/it.js
                new file mode 100644
                index 000000000..cd69b66b3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/it.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Codice",
                +  blocks: "Blocchi",
                +  linkTooltip: "Salva e collega ai blocchi.",
                +  runTooltip: "Esegui il programma definito dai blocchi nell'area di lavoro.",
                +  badCode: "Errore programma:\n%1",
                +  timeout: "È stato superato il numero massimo consentito di interazioni eseguite.",
                +  trashTooltip: "Elimina tutti i blocchi.",
                +  catLogic: "Logica",
                +  catLoops: "Cicli",
                +  catMath: "Matematica",
                +  catText: "Testo",
                +  catLists: "Elenchi",
                +  catColour: "Colore",
                +  catVariables: "Variabili",
                +  catFunctions: "Funzioni",
                +  listVariable: "elenco",
                +  textVariable: "testo",
                +  httpRequestError: "La richiesta non è stata soddisfatta.",
                +  linkAlert: "Condividi i tuoi blocchi con questo collegamento:\n\n%1",
                +  hashError: "Mi spiace, '%1' non corrisponde ad alcun programma salvato.",
                +  xmlError: "Non è stato possibile caricare il documento.  Forse è stato creato con una versione diversa di Blockly?",
                +  badXml: "Errore durante l'analisi XML:\n%1\n\nSeleziona 'OK' per abbandonare le modifiche o 'Annulla' per continuare a modificare l'XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ja.js b/blockly/webif/static/blockly/demos/code/msg/ja.js
                new file mode 100644
                index 000000000..6d5041982
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ja.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "コード",
                +  blocks: "ブロック",
                +  linkTooltip: "ブロックの状態を保存してリンクを取得します。",
                +  runTooltip: "ブロックで作成したプログラムを実行します。",
                +  badCode: "プログラムのエラー:\n%1",
                +  timeout: "命令の実行回数が制限値を超えました。",
                +  trashTooltip: "すべてのブロックを消します。",
                +  catLogic: "論理",
                +  catLoops: "繰り返し",
                +  catMath: "数学",
                +  catText: "テキスト",
                +  catLists: "リスト",
                +  catColour: "色",
                +  catVariables: "変数",
                +  catFunctions: "関数",
                +  listVariable: "リスト",
                +  textVariable: "テキスト",
                +  httpRequestError: "ネットワーク接続のエラーです。",
                +  linkAlert: "ブロックの状態をこのリンクで共有できます:\n\n%1",
                +  hashError: "すみません。「%1」という名前のプログラムは保存されていません。",
                +  xmlError: "保存されたファイルを読み込めませんでした。別のバージョンのブロックリーで作成された可能性があります。",
                +  badXml: "XML のエラーです:\n%1\n\nXML の変更をやめるには「OK」、編集を続けるには「キャンセル」を選んでください。"
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/kab.js b/blockly/webif/static/blockly/demos/code/msg/kab.js
                new file mode 100644
                index 000000000..648ff7fb8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/kab.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Tangalt",
                +  blocks: "Iḥedran",
                +  linkTooltip: "Sekles sakin cudd ar iḥedran.",
                +  runTooltip: "Senker ahil i d-sbadun iḥedran di tallunt n umahil.",
                +  badCode: "Tuccḍa deg ahil :\n%1",
                +  timeout: "Amḍan afellay n wallusen n uselkem iɛeddan.",
                +  trashTooltip: "Ḍeggeṛ akk iḥedran.",
                +  catLogic: "Tameẓla",
                +  catLoops: "Tineddicin",
                +  catMath: "Tusnakt",
                +  catText: "Aḍris",
                +  catLists: "Tibdarin",
                +  catColour: "Ini",
                +  catVariables: "Imuttiyen",
                +  catFunctions: "Tiwiriwin",
                +  listVariable: "tabdart",
                +  textVariable: "aḍris",
                +  httpRequestError: "yella ugur deg usuter.",
                +  linkAlert: "Bḍu iḥedran-ik s useqdec n useɣwen-agi:\n\n%1",
                +  hashError: "Suref-aɣ, '%1' ur imenṭaḍ ulad d yiwen n wahil yettwaskelsen.",
                +  xmlError: "Ur izmir ara ad d-isali afaylu  n usekles. Ahatyettwarna s lqem-nniḍen n Blockly?",
                +  badXml: "Tuccḍa di tesleḍt n XML :\n%1\n\nFren 'IH' akken ad tzgleḍ asnifel-ik 'Sefsex' akken ad tkemmleḍ asnifel n XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ko.js b/blockly/webif/static/blockly/demos/code/msg/ko.js
                new file mode 100644
                index 000000000..990cb6f23
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ko.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "코드",
                +  blocks: "블록",
                +  linkTooltip: "블록을 저장하고 링크를 가져옵니다.",
                +  runTooltip: "작업 공간에서 블록으로 정의된 프로그램을 실행합니다.",
                +  badCode: "프로그램 오류:\n%1",
                +  timeout: "최대 실행 반복을 초과했습니다.",
                +  trashTooltip: "모든 블록을 버립니다.",
                +  catLogic: "논리",
                +  catLoops: "반복",
                +  catMath: "수학",
                +  catText: "텍스트",
                +  catLists: "목록",
                +  catColour: "색",
                +  catVariables: "변수",
                +  catFunctions: "기능",
                +  listVariable: "목록",
                +  textVariable: "텍스트",
                +  httpRequestError: "요청에 문제가 있습니다.",
                +  linkAlert: "다음 링크로 블록을 공유하세요:\n\n%1",
                +  hashError: "죄송하지만 '%1'은 어떤 저장된 프로그램으로 일치하지 않습니다.",
                +  xmlError: "저장된 파일을 불러올 수 없습니다. 혹시 블록리의 다른 버전으로 만들었습니까?",
                +  badXml: "XML 구문 분석 오류:\n%1\n\n바뀜을 포기하려면 '확인'을 선택하고 XML을 더 편집하려면 '취소'를 선택하세요."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/mk.js b/blockly/webif/static/blockly/demos/code/msg/mk.js
                new file mode 100644
                index 000000000..cc344a69c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/mk.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Код",
                +  blocks: "Блокчиња",
                +  linkTooltip: "Зачувај и стави врска до блокчињата.",
                +  runTooltip: "Пушти го програмот определен од блокчињата во работниот простор.",
                +  badCode: "Грешка во програмот:\n%1",
                +  timeout: "Го надминавте допуштениот број на повторувања во извршувањето.",
                +  trashTooltip: "Отстрани ги сите блокчиња.",
                +  catLogic: "Логика",
                +  catLoops: "Јамки",
                +  catMath: "Математика",
                +  catText: "Текст",
                +  catLists: "Списоци",
                +  catColour: "Боја",
                +  catVariables: "Променливи",
                +  catFunctions: "Функции",
                +  listVariable: "список",
                +  textVariable: "текст",
                +  httpRequestError: "Се појави проблем во барањето.",
                +  linkAlert: "Споделете ги вашите блокчиња со оваа врска:\n\n%1",
                +  hashError: "„%1“ не одговара на ниеден зачуван програм.",
                +  xmlError: "Не можев да ја вчитам зачуваната податотека. Да не сте ја создале со друга верзија на Blockly?",
                +  badXml: "Грешка при расчленувањето на XML:\n%1\n\nСтиснете на „ОК“ за да ги напуштите промените или на „Откажи“ ако сакате уште да ја уредувате XML-податотеката."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ms.js b/blockly/webif/static/blockly/demos/code/msg/ms.js
                new file mode 100644
                index 000000000..87ee8deef
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ms.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kod",
                +  blocks: "Blok",
                +  linkTooltip: "Simpan dan pautkan kepada blok.",
                +  runTooltip: "Jalankan aturcara yang ditetapkan oleh blok-blok di dalam ruang kerja.",
                +  badCode: "Ralat aturcara:\n%1",
                +  timeout: "Takat maksimum lelaran pelaksanaan dicecah.",
                +  trashTooltip: "Buang semua Blok.",
                +  catLogic: "Logik",
                +  catLoops: "Gelung",
                +  catMath: "Matematik",
                +  catText: "Teks",
                +  catLists: "Senarai",
                +  catColour: "Warna",
                +  catVariables: "Pemboleh ubah",
                +  catFunctions: "Fungsi",
                +  listVariable: "senarai",
                +  textVariable: "teks",
                +  httpRequestError: "Permintaan itu terdapat masalah.",
                +  linkAlert: "Kongsikan blok-blok anda dengan pautan ini:\n\n%1",
                +  hashError: "Maaf, '%1' tidak berpadanan dengan sebarang aturcara yang disimpan.",
                +  xmlError: "Fail simpanan anda tidak dapat dimuatkan. Jangan-jangan ia dicipta dengan versi Blockly yang berlainan?",
                +  badXml: "Ralat ketika menghuraikan XML:\n%1\n\nPilih 'OK' untuk melucutkan suntingan anda atau 'Batal' untuk bersambung menyunting XML-nya."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/nb.js b/blockly/webif/static/blockly/demos/code/msg/nb.js
                new file mode 100644
                index 000000000..60ac0394d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/nb.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kode",
                +  blocks: "Blokker",
                +  linkTooltip: "Lagre og lenke til blokker.",
                +  runTooltip: "Kjør programmet definert av blokken i arbeidsområdet.",
                +  badCode: "Programfeil:\n%1",
                +  timeout: "Det maksimale antallet utførte looper er oversteget.",
                +  trashTooltip: "Fjern alle blokker",
                +  catLogic: "Logikk",
                +  catLoops: "Looper",
                +  catMath: "Matte",
                +  catText: "Tekst",
                +  catLists: "Lister",
                +  catColour: "Farge",
                +  catVariables: "Variabler",
                +  catFunctions: "Funksjoner",
                +  listVariable: "Liste",
                +  textVariable: "Tekst",
                +  httpRequestError: "Det oppsto et problem med forespørselen din",
                +  linkAlert: "Del dine blokker med denne lenken:\n\n%1",
                +  hashError: "Beklager, '%1' samsvarer ikke med noe lagret program.",
                +  xmlError: "Kunne ikke laste inn filen. Kanskje den ble laget med en annen versjon av Blockly?",
                +  badXml: "Feil ved parsering av XML:\n%1\n\nVelg 'OK' for å avbryte endringene eller 'Cancel' for å fortsette å redigere XML-koden."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/nl.js b/blockly/webif/static/blockly/demos/code/msg/nl.js
                new file mode 100644
                index 000000000..339a5e882
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/nl.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Code",
                +  blocks: "Blokken",
                +  linkTooltip: "Opslaan en koppelen naar blokken.",
                +  runTooltip: "Voer het programma uit dat met de blokken in de werkruimte is gemaakt.",
                +  badCode: "Programmafout:\n%1",
                +  timeout: "Het maximale aantal iteraties is overschreden.",
                +  trashTooltip: "Alle blokken verwijderen",
                +  catLogic: "Logica",
                +  catLoops: "Lussen",
                +  catMath: "Formules",
                +  catText: "Tekst",
                +  catLists: "Lijsten",
                +  catColour: "Kleur",
                +  catVariables: "Variabelen",
                +  catFunctions: "Functies",
                +  listVariable: "lijst",
                +  textVariable: "tekst",
                +  httpRequestError: "Er is een probleem opgetreden tijdens het verwerken van het verzoek.",
                +  linkAlert: "Deel uw blokken via deze koppeling:\n\n%1",
                +  hashError: "\"%1\" komt helaas niet overeen met een opgeslagen bestand.",
                +  xmlError: "Uw opgeslagen bestand kan niet geladen worden. Is het misschien gemaakt met een andere versie van Blockly?",
                +  badXml: "Fout tijdens het verwerken van de XML:\n%1\n\nSelecteer \"OK\" om uw wijzigingen te negeren of \"Annuleren\" om de XML verder te bewerken."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/oc.js b/blockly/webif/static/blockly/demos/code/msg/oc.js
                new file mode 100644
                index 000000000..c184ac8fb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/oc.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Còde",
                +  blocks: "Blòts",
                +  linkTooltip: "Salva e liga als blòts.",
                +  runTooltip: "Aviar lo programa definit pels blòts dins l’espaci de trabalh.",
                +  badCode: "Error del programa :\n%1",
                +  timeout: "Nombre maximum d’iteracions d’execucion depassat.",
                +  trashTooltip: "Getar totes los blòts.",
                +  catLogic: "Logic",
                +  catLoops: "Boclas",
                +  catMath: "Math",
                +  catText: "Tèxte",
                +  catLists: "Listas",
                +  catColour: "Color",
                +  catVariables: "Variablas",
                +  catFunctions: "Foncions",
                +  listVariable: "lista",
                +  textVariable: "tèxte",
                +  httpRequestError: "I a agut un problèma amb la demanda.",
                +  linkAlert: "Partejatz vòstres blòts gràcia a aqueste ligam :\n\n%1",
                +  hashError: "O planhèm, '%1' correspond pas a un fichièr Blockly salvament.",
                +  xmlError: "Impossible de cargar lo fichièr de salvament.  Benlèu qu'es estat creat amb una autra version de Blockly ?",
                +  badXml: "Error d’analisi del XML :\n%1\n\nSeleccionar 'D'acòrdi' per abandonar vòstras modificacions o 'Anullar' per modificar encara lo XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/pl.js b/blockly/webif/static/blockly/demos/code/msg/pl.js
                new file mode 100644
                index 000000000..83bb05d2f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/pl.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kod",
                +  blocks: "Bloki",
                +  linkTooltip: "Zapisz i podlinkuj do bloków",
                +  runTooltip: "Uruchom program zdefinowany przez bloki w obszarze roboczym",
                +  badCode: "Błąd programu:\n%1",
                +  timeout: "Maksymalna liczba iteracji wykonywań przekroczona",
                +  trashTooltip: "Odrzuć wszystkie bloki.",
                +  catLogic: "Logika",
                +  catLoops: "Pętle",
                +  catMath: "Matematyka",
                +  catText: "Tekst",
                +  catLists: "Listy",
                +  catColour: "Kolor",
                +  catVariables: "Zmienne",
                +  catFunctions: "Funkcje",
                +  listVariable: "lista",
                +  textVariable: "tekst",
                +  httpRequestError: "Wystąpił problem z żądaniem.",
                +  linkAlert: "Udpostępnij swoje bloki korzystając z poniższego linku : \n\n\n%1",
                +  hashError: "Przepraszamy, \"%1\" nie odpowiada żadnemu zapisanemu programowi.",
                +  xmlError: "Nie można załadować zapisanego pliku. Być może został utworzony za pomocą innej wersji Blockly?",
                +  badXml: "Błąd parsowania XML : \n%1\n\nZaznacz 'OK' aby odrzucić twoje zmiany lub 'Cancel', żeby w przyszłości edytować XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/pms.js b/blockly/webif/static/blockly/demos/code/msg/pms.js
                new file mode 100644
                index 000000000..a7704f764
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/pms.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Còdes",
                +  blocks: "Blòch",
                +  linkTooltip: "Argistré e lijé ai blòch.",
                +  runTooltip: "Fé andé ël programa definì dai blòch ant lë spassi ëd travaj.",
                +  badCode: "Eror dël programa:\n%1",
                +  timeout: "Nùmer màssim d'arpetission d'esecussion sorpassà.",
                +  trashTooltip: "Scarté tuti ij blòch.",
                +  catLogic: "Lògica",
                +  catLoops: "Liasse",
                +  catMath: "Matemàtica",
                +  catText: "Test",
                +  catLists: "Liste",
                +  catColour: "Color",
                +  catVariables: "Variàbij",
                +  catFunctions: "Fonsion",
                +  listVariable: "lista",
                +  textVariable: "test",
                +  httpRequestError: "A-i é staje un problema con l'arcesta.",
                +  linkAlert: "Ch'a partagia ij sò blòch grassie a sta liura: %1",
                +  hashError: "An dëspias, '%1 a corëspond a gnun programa salvà.",
                +  xmlError: "A l'é nen podusse carié so archivi salvà. Miraco a l'é stàit creà con na version diferenta ëd Blockly?",
                +  badXml: "Eror d'anàlisi dl'XML:\n%1\n\nSelessioné 'Va bin' për lassé perde toe modìfiche o 'Anulé' për modifiché ancora l'XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/pt-br.js b/blockly/webif/static/blockly/demos/code/msg/pt-br.js
                new file mode 100644
                index 000000000..9b18d6360
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/pt-br.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Código",
                +  blocks: "Blocos",
                +  linkTooltip: "Salvar e ligar aos blocos.",
                +  runTooltip: "Execute o programa definido pelos blocos na área de trabalho.",
                +  badCode: "Erro no programa:\n%1",
                +  timeout: "Máximo de iterações de execução excedido.",
                +  trashTooltip: "Descartar todos os blocos.",
                +  catLogic: "Lógica",
                +  catLoops: "Laços",
                +  catMath: "Matemática",
                +  catText: "Texto",
                +  catLists: "Listas",
                +  catColour: "Cor",
                +  catVariables: "Variáveis",
                +  catFunctions: "Funções",
                +  listVariable: "lista",
                +  textVariable: "texto",
                +  httpRequestError: "Houve um problema com a requisição.",
                +  linkAlert: "Compartilhe seus blocos com este link:\n\n%1",
                +  hashError: "Desculpe, '%1' não corresponde a um programa salvo.",
                +  xmlError: "Não foi possível carregar seu arquivo salvo. Talvez ele tenha sido criado com uma versão diferente do Blockly?",
                +  badXml: "Erro de análise XML:\n%1\n\nSelecione 'OK' para abandonar suas mudanças ou 'Cancelar' para editar o XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ro.js b/blockly/webif/static/blockly/demos/code/msg/ro.js
                new file mode 100644
                index 000000000..cd3de11d7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ro.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Cod",
                +  blocks: "Blocuri",
                +  linkTooltip: "Salvează și adaugă la blocuri.",
                +  runTooltip: "Execută programul definit de către blocuri în spațiul de lucru.",
                +  badCode: "Eroare de program:\n%1",
                +  timeout: "Numărul maxim de iterații a fost depășit.",
                +  trashTooltip: "Șterge toate blocurile.",
                +  catLogic: "Logic",
                +  catLoops: "Bucle",
                +  catMath: "Matematică",
                +  catText: "Text",
                +  catLists: "Liste",
                +  catColour: "Culoare",
                +  catVariables: "Variabile",
                +  catFunctions: "Funcții",
                +  listVariable: "listă",
                +  textVariable: "text",
                +  httpRequestError: "A apărut o problemă la solicitare.",
                +  linkAlert: "Distribuie-ți blocurile folosind această legătură:\n\n%1",
                +  hashError: "Scuze, „%1” nu corespunde nici unui program salvat.",
                +  xmlError: "Sistemul nu a putut încărca fișierul salvat. Poate că a fost creat cu o altă versiune de Blockly?",
                +  badXml: "Eroare de parsare XML:\n%1\n\nAlege „OK” pentru a renunța la modificările efectuate sau „Revocare” pentru a modifica în continuare fișierul XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ru.js b/blockly/webif/static/blockly/demos/code/msg/ru.js
                new file mode 100644
                index 000000000..389e9052a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ru.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Код",
                +  blocks: "Блоки",
                +  linkTooltip: "Сохранить и показать ссылку на блоки.",
                +  runTooltip: "Запустить программу, заданную блоками в рабочей области.",
                +  badCode: "Ошибка программы:\n%1",
                +  timeout: "Превышено максимальное количество итераций.",
                +  trashTooltip: "Удалить все блоки.",
                +  catLogic: "Логические",
                +  catLoops: "Циклы",
                +  catMath: "Математика",
                +  catText: "Текст",
                +  catLists: "Списки",
                +  catColour: "Цвет",
                +  catVariables: "Переменные",
                +  catFunctions: "Функции",
                +  listVariable: "список",
                +  textVariable: "текст",
                +  httpRequestError: "Произошла проблема при запросе.",
                +  linkAlert: "Поделитесь своими блоками по этой ссылке:\n\n%1",
                +  hashError: "К сожалению, «%1» не соответствует ни одному сохраненному файлу Блокли.",
                +  xmlError: "Не удалось загрузить ваш сохраненный файл.  Возможно, он был создан в другой версии Блокли?",
                +  badXml: "Ошибка синтаксического анализа XML:\n%1\n\nВыберите 'ОК', чтобы отказаться от изменений или 'Cancel' для дальнейшего редактирования XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/sc.js b/blockly/webif/static/blockly/demos/code/msg/sc.js
                new file mode 100644
                index 000000000..82f94d61d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/sc.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Còdixi",
                +  blocks: "Brocus",
                +  linkTooltip: "Sarva e alliòngia a is brocus.",
                +  runTooltip: "Arròllia su programa cumpostu de is brocus in s'àrea de traballu.",
                +  badCode: "Errori in su Programa:\n%1",
                +  timeout: "Giai lòmpius a su màssimu numeru de repicus.",
                +  trashTooltip: "Boganci totu is brocus.",
                +  catLogic: "Lògica",
                +  catLoops: "Lòrigas",
                +  catMath: "Matemàtica",
                +  catText: "Testu",
                +  catLists: "Lista",
                +  catColour: "Colori",
                +  catVariables: "Variabilis",
                +  catFunctions: "Funtzionis",
                +  listVariable: "lista",
                +  textVariable: "testu",
                +  httpRequestError: "Ddui fut unu problema cun sa pregunta",
                +  linkAlert: "Poni is brocus tuus in custu acàpiu:\n\n%1",
                +  hashError: "Mi dispraxit, '%1' non torrat a pari cun nimancu unu de is programas sarvaus.",
                +  xmlError: "Non potzu carrigai su file sarvau. Fortzis est stètiu fatu cun d-una versioni diferenti de Blockly?",
                +  badXml: "Errori in s'anàlisi XML:\n%1\n\nCraca 'OK' po perdi is mudàntzias 'Anudda' po sighì a scriri su XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/sk.js b/blockly/webif/static/blockly/demos/code/msg/sk.js
                new file mode 100644
                index 000000000..3917df293
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/sk.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kód",
                +  blocks: "Bloky",
                +  linkTooltip: "Uložiť a zdieľať odkaz na tento program.",
                +  runTooltip: "Spustiť program, zložený z dielcov na pracovnej ploche.",
                +  badCode: "Chyba v programe:\n%1",
                +  timeout: "Bol prekročený maximálny počet opakovaní.",
                +  trashTooltip: "Zahodiť všetky dielce.",
                +  catLogic: "Logika",
                +  catLoops: "Cykly",
                +  catMath: "Matematické",
                +  catText: "Text",
                +  catLists: "Zoznamy",
                +  catColour: "Farby",
                +  catVariables: "Premenné",
                +  catFunctions: "Funkcie",
                +  listVariable: "zoznam",
                +  textVariable: "text",
                +  httpRequestError: "Problém so spracovaním požiadavky.",
                +  linkAlert: "Zdieľať tento program skopírovaním odkazu\n\n%1",
                +  hashError: "Prepáč, '%1' nie je meno žiadnemu uloženému programu.",
                +  xmlError: "Nebolo možné načítať uložený súbor. Možno bol vytvorený v inej verzii Blocky.",
                +  badXml: "Chyba pri parsovaní XML:\n%1\n\nStlačte 'OK' ak chcete zrušiť zmeny alebo 'Zrušiť' pre pokračovanie v úpravách XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/sr.js b/blockly/webif/static/blockly/demos/code/msg/sr.js
                new file mode 100644
                index 000000000..f9a026ca0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/sr.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Кôд",
                +  blocks: "Блокови",
                +  linkTooltip: "Сачувајте и повежите са блоковима.",
                +  runTooltip: "Покрените програм заснован на блоковима у радном простору.",
                +  badCode: "Грешка у програму:\n%1",
                +  timeout: "Достигнут је максималан број понављања у извршавању.",
                +  trashTooltip: "Одбаците све блокове.",
                +  catLogic: "Логика",
                +  catLoops: "Петље",
                +  catMath: "Математика",
                +  catText: "Текст",
                +  catLists: "Спискови",
                +  catColour: "Боја",
                +  catVariables: "Променљиве",
                +  catFunctions: "Процедуре",
                +  listVariable: "списак",
                +  textVariable: "текст",
                +  httpRequestError: "Дошло је до проблема у захтеву.",
                +  linkAlert: "Делите своје блокове овом везом:\n\n%1",
                +  hashError: "„%1“ не одговара ниједном сачуваном програму.",
                +  xmlError: "Не могу да учитам сачувану датотеку. Можда је направљена другом верзијом Blockly-ја.",
                +  badXml: "Грешка при рашчлањивању XML-а:\n%1\n\nПритисните „У реду“ да напустите измене или „Откажи“ да наставите са уређивањем XML датотеке."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/sv.js b/blockly/webif/static/blockly/demos/code/msg/sv.js
                new file mode 100644
                index 000000000..4134a4c7d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/sv.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kod",
                +  blocks: "Block",
                +  linkTooltip: "Spara och länka till block.",
                +  runTooltip: "Kör programmet som definierats av blocken i arbetsytan.",
                +  badCode: "Programfel:\n%1",
                +  timeout: "Det maximala antalet utförda loopar har överskridits.",
                +  trashTooltip: "Släng alla block.",
                +  catLogic: "Logik",
                +  catLoops: "Loopar",
                +  catMath: "Matematik",
                +  catText: "Text",
                +  catLists: "Listor",
                +  catColour: "Färg",
                +  catVariables: "Variabler",
                +  catFunctions: "Funktioner",
                +  listVariable: "lista",
                +  textVariable: "text",
                +  httpRequestError: "Det uppstod ett problem med begäran.",
                +  linkAlert: "Dela dina block med denna länk: \n\n%1",
                +  hashError: "Tyvärr, '%1' överensstämmer inte med något sparat program.",
                +  xmlError: "Kunde inte läsa din sparade fil. Den skapades kanske med en annan version av Blockly?",
                +  badXml: "Fel vid parsning av XML:\n%1\n\nKlicka på 'OK' för att strunta i dina ändringar eller 'Avbryt' för att fortsätta redigera XML-koden."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/ta.js b/blockly/webif/static/blockly/demos/code/msg/ta.js
                new file mode 100644
                index 000000000..ff472e2b7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/ta.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "கணினி நிரல்", //Code
                +  blocks: "நிரல் துண்டு", //block
                +  linkTooltip: "சேமித்து நிரல் துண்டிற்கு இணைக்க", //save and link to block
                +  runTooltip: "பணிமனை நினைவகத்தில் இயக்குக", //Run the program defined by the blocks in the workspace.
                +  badCode: "கணினி நிரல் கோளாறு:\n%1",
                +  timeout: "அதிகபட்ச அடுக்கின் அளவை மீரியது", //max iters reached/exceeded
                +  trashTooltip: "நீக்கு",
                +  catLogic: "தர்க வகை",
                +  catLoops: "மடக்கு வாக்கியம்",
                +  catMath: "கணிதம்",
                +  catText: "உரை",
                +  catLists: "பட்டியல்",
                +  catColour: "வண்ணம்",
                +  catVariables: "மாறிகள்",
                +  catFunctions: "சார்புகள்",
                +  listVariable: "பட்டியல் மாறி",
                +  textVariable: "உரை சரம்",
                +  httpRequestError: "இந்த செயலை இயக்குவதில் கோளாறு ஏற்பட்டது",
                +  linkAlert: "இந்த சுட்டி வழியாக நிரல் துண்டுகளை பகிரவும்:\n\n%1",
                +  hashError: "'%1' : இது சேமித்த நிரலாக தெரியவில்லை.",
                +  xmlError: "உங்களது நிரலை காணவில்லை; வேறு Blockly அத்தியாயத்தில் சேமித்தீரா?",
                +  badXml: "XML பகுப்பதில் கோளாறு:\n%1\n\nOK' கிளிக் செய்தால் மாற்றங்கள் இழப்பீர்கள்; பிழைகளுடன் தொடர 'Cancel' கிளிக் செய்யவும்."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/th.js b/blockly/webif/static/blockly/demos/code/msg/th.js
                new file mode 100644
                index 000000000..1ac36245b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/th.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "เขียนโปรแกรม",
                +  blocks: "บล็อก",
                +  linkTooltip: "บันทึกและสร้างลิงก์มายังบล็อกเหล่านี้",
                +  runTooltip: "เรียกใช้โปรแกรมตามที่กำหนดไว้ด้วยบล็อกที่อยู่ในพื้นที่ทำงาน",
                +  badCode: "โปรแกรมเกิดข้อผิดพลาด:\n%1",
                +  timeout: "โปรแกรมทำงานซ้ำคำสั่งเดิมมากเกินไป",
                +  trashTooltip: "ยกเลิกบล็อกทั้งหมด",
                +  catLogic: "ตรรกะ",
                +  catLoops: "การวนซ้ำ",
                +  catMath: "คณิตศาสตร์",
                +  catText: "ข้อความ",
                +  catLists: "รายการ",
                +  catColour: "สี",
                +  catVariables: "ตัวแปร",
                +  catFunctions: "ฟังก์ชัน",
                +  listVariable: "รายการ",
                +  textVariable: "ข้อความ",
                +  httpRequestError: "มีปัญหาเกี่ยวกับการร้องขอ",
                +  linkAlert: "แบ่งปันบล็อกของคุณด้วยลิงก์นี้:\n\n%1",
                +  hashError: "เสียใจด้วย '%1' ไม่ตรงกับโปรแกรมใดๆ ที่เคยบันทึกเอาไว้เลย",
                +  xmlError: "ไม่สามารถโหลดไฟล์ที่บันทึกไว้ของคุณได้ บางทีมันอาจจะถูกสร้างขึ้นด้วย Blockly รุ่นอื่นที่แตกต่างกัน?",
                +  badXml: "เกิดข้อผิดพลาดในการแยกวิเคราะห์ XML:\n%1\n\nเลือก 'ตกลง' เพื่อละทิ้งการเปลี่ยนแปลงต่างๆ ที่ทำไว้ หรือเลือก 'ยกเลิก' เพื่อแก้ไข XML ต่อไป"
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/tlh.js b/blockly/webif/static/blockly/demos/code/msg/tlh.js
                new file mode 100644
                index 000000000..8d0c056f9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/tlh.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "ngoq",
                +  blocks: "ngoghmey",
                +  linkTooltip: "",
                +  runTooltip: "",
                +  badCode: "Qagh:\n%1",
                +  timeout: "tlhoy nI'qu' poH.",
                +  trashTooltip: "",
                +  catLogic: "meq",
                +  catLoops: "vIHtaHbogh ghomey",
                +  catMath: "mI'QeD",
                +  catText: "ghItlhHommey",
                +  catLists: "tetlhmey",
                +  catColour: "rItlh",
                +  catVariables: "lIwmey",
                +  catFunctions: "mIwmey",
                +  listVariable: "tetlh",
                +  textVariable: "ghItlhHom",
                +  httpRequestError: "Qapbe' tlhobmeH QIn.",
                +  linkAlert: "latlhvaD ngoghmeylIj DangeHmeH Quvvam yIlo':\n\n%1",
                +  hashError: "Do'Ha', ngogh nab pollu'pu'bogh 'oHbe'law' \"%1\"'e'.",
                +  xmlError: "ngogh nablIj pollu'pu'bogh chu'qa'laHbe' vay'.  chaq pollu'pu'DI' ghunmeH ngogh pIm lo'lu'pu'.",
                +  badXml: "XML yajchu'laHbe' vay':\n%1\n\nchoHmeylIj DalonmeH \"ruch\" yIwIv pagh XML DachoHqa'meH \"qIl\" yIwIv."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/tr.js b/blockly/webif/static/blockly/demos/code/msg/tr.js
                new file mode 100644
                index 000000000..144830092
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/tr.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Kod",
                +  blocks: "Bloklar",
                +  linkTooltip: "Blokları ve bağlantı adresini kaydet.",
                +  runTooltip: "Çalışma alanında bloklar tarafından tanımlanan programını çalıştırın.",
                +  badCode: "Program hatası:\n %1",
                +  timeout: "Maksimum yürütme yinelemeleri aşıldı.",
                +  trashTooltip: "Bütün blokları at.",
                +  catLogic: "Mantık",
                +  catLoops: "Döngüler",
                +  catMath: "Matematik",
                +  catText: "Metin",
                +  catLists: "Listeler",
                +  catColour: "Renk",
                +  catVariables: "Değişkenler",
                +  catFunctions: "İşlevler",
                +  listVariable: "liste",
                +  textVariable: "metin",
                +  httpRequestError: "İstek ile ilgili bir problem var.",
                +  linkAlert: "Bloklarını bu bağlantı ile paylaş:\n\n%1",
                +  hashError: "Üzgünüz, '%1' hiç bir kaydedilmiş program ile uyuşmuyor.",
                +  xmlError: "Kaydedilen dosyanız yüklenemiyor\nBlockly'nin önceki sürümü ile kaydedilmiş olabilir mi?",
                +  badXml: "XML ayrıştırma hatası:\n%1\n\nDeğişikliklerden vazgeçmek için 'Tamam'ı, düzenlemeye devam etmek için 'İptal' seçeneğini seçiniz."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/uk.js b/blockly/webif/static/blockly/demos/code/msg/uk.js
                new file mode 100644
                index 000000000..6b3462721
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/uk.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Код",
                +  blocks: "Блоки",
                +  linkTooltip: "Зберегти і пов'язати з блоками.",
                +  runTooltip: "Запустіть програму, визначену блоками у робочій області.",
                +  badCode: "Помилка програми:\n%1",
                +  timeout: "Максимальне виконання ітерацій перевищено.",
                +  trashTooltip: "Відкинути всі блоки.",
                +  catLogic: "Логіка",
                +  catLoops: "Петлі",
                +  catMath: "Математика",
                +  catText: "Текст",
                +  catLists: "Списки",
                +  catColour: "Колір",
                +  catVariables: "Змінні",
                +  catFunctions: "Функції",
                +  listVariable: "список",
                +  textVariable: "текст",
                +  httpRequestError: "Виникла проблема із запитом.",
                +  linkAlert: "Поділитися вашим блоками через посилання:\n\n%1",
                +  hashError: "На жаль, \"%1\" не відповідає жодній збереженій програмі.",
                +  xmlError: "Не вдалося завантажити ваш збережений файл.  Можливо, він був створений з іншої версії Blockly?",
                +  badXml: "Помилка синтаксичного аналізу XML:\n%1\n\nВиберіть \"Гаразд\", щоб відмовитися від змін або 'Скасувати' для подальшого редагування XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/vi.js b/blockly/webif/static/blockly/demos/code/msg/vi.js
                new file mode 100644
                index 000000000..952d024b4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/vi.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "Chương trình",
                +  blocks: "Các mảnh",
                +  linkTooltip: "Lưu và lấy địa chỉ liên kết.",
                +  runTooltip: "Chạy chương trình.",
                +  badCode: "'Lỗi chương trình:\n%1",
                +  timeout: "Đã vượt quá số lần lặp cho phép.",
                +  trashTooltip: "Xóa tất cả mọi mảnh.",
                +  catLogic: "Logic",
                +  catLoops: "Vòng lặp",
                +  catMath: "Công thức toán",
                +  catText: "Văn bản",
                +  catLists: "Danh sách",
                +  catColour: "Màu",
                +  catVariables: "Biến",
                +  catFunctions: "Hàm",
                +  listVariable: "danh sách",
                +  textVariable: "văn bản",
                +  httpRequestError: "Hoạt động bị trục trặc, không thực hiện được yêu cầu của bạn.",
                +  linkAlert: "Chia sẻ chương trình của bạn với liên kết sau:\n\n %1",
                +  hashError: "Không tìm thấy chương trình được lưu ở '%1'.",
                +  xmlError: "Không mở được chương trình của bạn.  Có thể nó nằm trong một phiên bản khác của Blockly?",
                +  badXml: "Lỗi sử lý XML:\n %1\n\nChọn 'OK' để từ bỏ các thay đổi hoặc 'Hủy' để tiếp tục chỉnh sửa các XML."
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/zh-hans.js b/blockly/webif/static/blockly/demos/code/msg/zh-hans.js
                new file mode 100644
                index 000000000..abf8a6589
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/zh-hans.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "代码",
                +  blocks: "块",
                +  linkTooltip: "保存模块并生成链接。",
                +  runTooltip: "于工作区中运行块所定义的程式。",
                +  badCode: "程序错误:\n%1",
                +  timeout: "超过最大执行行数。",
                +  trashTooltip: "放弃所有块。",
                +  catLogic: "逻辑",
                +  catLoops: "循环",
                +  catMath: "数学",
                +  catText: "文本",
                +  catLists: "列表",
                +  catColour: "颜色",
                +  catVariables: "变量",
                +  catFunctions: "函数",
                +  listVariable: "列表",
                +  textVariable: "文本",
                +  httpRequestError: "请求存在问题。",
                +  linkAlert: "通过这个链接分享您的模块:\n\n%1",
                +  hashError: "对不起,没有任何已保存的程序对应'%1' 。",
                +  xmlError: "无法载入您保存的文件。您是否使用其他版本的Blockly创建该文件的?",
                +  badXml: "XML解析错误:\n%1\n\n选择“确定”以取消您对XML的修改,或选择“取消”以继续编辑XML。"
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/msg/zh-hant.js b/blockly/webif/static/blockly/demos/code/msg/zh-hant.js
                new file mode 100644
                index 000000000..48a8b5272
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/msg/zh-hant.js
                @@ -0,0 +1,24 @@
                +var MSG = {
                +  title: "程式碼",
                +  blocks: "積木",
                +  linkTooltip: "儲存積木組並提供連結。",
                +  runTooltip: "於工作區中執行積木組所定義的程式。",
                +  badCode: "程式錯誤:\n%1",
                +  timeout: "超過最大執行數。",
                +  trashTooltip: "捨棄所有積木。",
                +  catLogic: "邏輯",
                +  catLoops: "迴圈",
                +  catMath: "數學式",
                +  catText: "文字",
                +  catLists: "列表",
                +  catColour: "顏色",
                +  catVariables: "變量",
                +  catFunctions: "流程",
                +  listVariable: "列表",
                +  textVariable: "文字",
                +  httpRequestError: "命令出現錯誤。",
                +  linkAlert: "透過此連結分享您的積木組:\n\n%1",
                +  hashError: "對不起,「%1」並未對應任何已保存的程式。",
                +  xmlError: "未能載入您保存的檔案。或許它是由其他版本的Blockly創建?",
                +  badXml: "解析 XML 時出現錯誤:\n%1\n\n選擇'確定'以放棄您的更改,或選擇'取消'以進一步編輯 XML。"
                +};
                diff --git a/blockly/webif/static/blockly/demos/code/style.css b/blockly/webif/static/blockly/demos/code/style.css
                new file mode 100644
                index 000000000..e05664f24
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/code/style.css
                @@ -0,0 +1,163 @@
                +html, body {
                +  height: 100%;
                +}
                +
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  margin: 0;
                +  overflow: hidden;
                +}
                +
                +.farSide {
                +  text-align: right;
                +}
                +
                +html[dir="RTL"] .farSide {
                +  text-align: left;
                +}
                +
                +/* Buttons */
                +button {
                +  margin: 5px;
                +  padding: 10px;
                +  border-radius: 4px;
                +  border: 1px solid #ddd;
                +  font-size: large;
                +  background-color: #eee;
                +  color: #000;
                +}
                +button.primary {
                +  border: 1px solid #dd4b39;
                +  background-color: #dd4b39;
                +  color: #fff;
                +}
                +button.primary>img {
                +  opacity: 1;
                +}
                +button>img {
                +  opacity: 0.6;
                +  vertical-align: text-bottom;
                +}
                +button:hover>img {
                +  opacity: 1;
                +}
                +button:active {
                +  border: 1px solid #888 !important;
                +}
                +button:hover {
                +  box-shadow: 2px 2px 5px #888;
                +}
                +button.disabled:hover>img {
                +  opacity: 0.6;
                +}
                +button.disabled {
                +  display: none;
                +}
                +button.notext {
                +  font-size: 10%;
                +}
                +
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +  margin-left: 5px;
                +  margin-right: 5px;
                +}
                +
                +/* Tabs */
                +#tabRow>td {
                +  border: 1px solid #ccc;
                +  border-bottom: none;
                +}
                +td.tabon {
                +  border-bottom-color: #ddd !important;
                +  background-color: #ddd;
                +  padding: 5px 19px;
                +}
                +td.taboff {
                +  cursor: pointer;
                +  padding: 5px 19px;
                +}
                +td.taboff:hover {
                +  background-color: #eee;
                +}
                +td.tabmin {
                +  border-top-style: none !important;
                +  border-left-style: none !important;
                +  border-right-style: none !important;
                +}
                +td.tabmax {
                +  border-top-style: none !important;
                +  border-left-style: none !important;
                +  border-right-style: none !important;
                +  width: 99%;
                +  padding-left: 10px;
                +  padding-right: 10px;
                +  text-align: right;
                +}
                +html[dir=rtl] td.tabmax {
                +  text-align: left;
                +}
                +
                +table {
                +  border-collapse: collapse;
                +  margin: 0;
                +  padding: 0;
                +  border: none;
                +}
                +td {
                +  padding: 0;
                +  vertical-align: top;
                +}
                +.content {
                +  visibility: hidden;
                +  margin: 0;
                +  padding: 1ex;
                +  position: absolute;
                +  direction: ltr;
                +}
                +pre.content {
                +  border: 1px solid #ccc;
                +  overflow: scroll;
                +}
                +#content_blocks {
                +  padding: 0;
                +}
                +.blocklySvg {
                +  border-top: none !important;
                +}
                +#content_xml {
                +  resize: none;
                +  outline: none;
                +  border: 1px solid #ccc;
                +  font-family: monospace;
                +  overflow: scroll;
                +}
                +#languageMenu {
                +  vertical-align: top;
                +  margin-top: 15px;
                +  margin-right: 15px;
                +}
                +
                +/* Buttons */
                +button {
                +  padding: 1px 10px;
                +  margin: 1px 5px;
                +}
                +
                +/* Sprited icons. */
                +.icon21 {
                +  height: 21px;
                +  width: 21px;
                +  background-image: url(icons.png);
                +}
                +.trash {
                +  background-position: 0px 0px;
                +}
                +.link {
                +  background-position: -21px 0px;
                +}
                +.run {
                +  background-position: -42px 0px;
                +}
                diff --git a/blockly/webif/static/blockly/demos/custom-dialogs/custom-dialog.js b/blockly/webif/static/blockly/demos/custom-dialogs/custom-dialog.js
                new file mode 100644
                index 000000000..1892303a4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/custom-dialogs/custom-dialog.js
                @@ -0,0 +1,173 @@
                +/**
                + * Blockly Demos: Custom Dialogs
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * An example implementation of how one might replace Blockly's browser
                + * dialogs. This is just an example, and applications are not encouraged to use
                + * it verbatim.
                + *
                + * @namespace
                + */
                +CustomDialog = {};
                +
                +/** Override Blockly.alert() with custom implementation. */
                +Blockly.alert = function(message, callback) {
                +  console.log('Alert: ' + message);
                +  CustomDialog.show('Alert', message, {
                +    onCancel: callback
                +  });
                +};
                +
                +/** Override Blockly.confirm() with custom implementation. */
                +Blockly.confirm = function(message, callback) {
                +  console.log('Confirm: ' + message);
                +  CustomDialog.show('Confirm', message, {
                +    showOkay: true,
                +    onOkay: function() {
                +      callback(true)
                +    },
                +    showCancel: true,
                +    onCancel: function() {
                +      callback(false)
                +    }
                +  });
                +};
                +
                +/** Override Blockly.prompt() with custom implementation. */
                +Blockly.prompt = function(message, defaultValue, callback) {
                +  console.log('Prompt: ' + message);
                +  CustomDialog.show('Prompt', message, {
                +    showInput: true,
                +    showOkay: true,
                +    onOkay: function() {
                +      callback(CustomDialog.inputField.value)
                +    },
                +    showCancel: true,
                +    onCancel: function() {
                +      callback(null)
                +    }
                +  });
                +  CustomDialog.inputField.value = defaultValue;
                +};
                +
                +/** Hides any currently visible dialog. */
                +CustomDialog.hide = function() {
                +  if (CustomDialog.backdropDiv_) {
                +    CustomDialog.backdropDiv_.style.display = 'none'
                +    CustomDialog.dialogDiv_.style.display = 'none'
                +  }
                +};
                +
                +/**
                + * Shows the dialog.
                + * Allowed options:
                + *  - showOkay: Whether to show the OK button.
                + *  - showCancel: Whether to show the Cancel button.
                + *  - showInput: Whether to show the text input field.
                + *  - onOkay: Callback to handle the okay button.
                + *  - onCancel: Callback to handle the cancel button and backdrop clicks.
                + */
                +CustomDialog.show = function(title, message, options) {
                +  var backdropDiv = CustomDialog.backdropDiv_;
                +  var dialogDiv = CustomDialog.dialogDiv_;
                +  if (!dialogDiv) {
                +    // Generate HTML
                +    backdropDiv = document.createElement('div');
                +    backdropDiv.id = 'customDialogBackdrop';
                +    backdropDiv.style.cssText =
                +        'position: absolute;' +
                +        'top: 0; left: 0; right: 0; bottom: 0;' +
                +        'background-color: rgba(0, 0, 0, .7);';
                +    document.body.appendChild(backdropDiv);
                +
                +    dialogDiv = document.createElement('div');
                +    dialogDiv.id = 'customDialog';
                +    dialogDiv.style.cssText =
                +        'background-color: #fff;' +
                +        'width: 400px;' +
                +        'margin: 20px auto 0;' +
                +        'padding: 10px;';
                +    backdropDiv.appendChild(dialogDiv);
                +
                +    dialogDiv.onclick = function(event) {
                +      event.stopPropagation();
                +    };
                +
                +    CustomDialog.backdropDiv_ = backdropDiv;
                +    CustomDialog.dialogDiv_ = dialogDiv;
                +  }
                +  backdropDiv.style.display = 'block';
                +  dialogDiv.style.display = 'block';
                +
                +  dialogDiv.innerHTML =
                +      '<header class="customDialogTitle"></header>' +
                +      '<p class="customDialogMessage"></p>' +
                +      (options.showInput ? '<div><input id="customDialogInput"></div>' : '') +
                +      '<div class="customDialogButtons">' +
                +      (options.showCancel ? '<button id="customDialogCancel">Cancel</button>': '') +
                +      (options.showOkay ? '<button id="customDialogOkay">OK</button>': '') +
                +      '</div>';
                +  dialogDiv.getElementsByClassName('customDialogTitle')[0]
                +      .appendChild(document.createTextNode(title));
                +  dialogDiv.getElementsByClassName('customDialogMessage')[0]
                +      .appendChild(document.createTextNode(message));
                +
                +  var onOkay = function(event) {
                +    CustomDialog.hide();
                +    options.onOkay && options.onOkay();
                +    event && event.stopPropagation();
                +  };
                +  var onCancel = function(event) {
                +    CustomDialog.hide();
                +    options.onCancel && options.onCancel();
                +    event && event.stopPropagation();
                +  };
                +
                +  var dialogInput = document.getElementById('customDialogInput');
                +  CustomDialog.inputField = dialogInput;
                +  if (dialogInput) {
                +    dialogInput.focus();
                +
                +    dialogInput.onkeyup = function(event) {
                +      if (event.keyCode == 13) {
                +        // Process as OK when user hits enter.
                +        onOkay();
                +        return false;
                +      } else if (event.keyCode == 27)  {
                +        // Process as cancel when user hits esc.
                +        onCancel();
                +        return false;
                +      }
                +    };
                +  } else {
                +    var okay = document.getElementById('customDialogOkay');
                +    okay && okay.focus();
                +  }
                +
                +  if (options.showOkay) {
                +    document.getElementById('customDialogOkay')
                +        .addEventListener('click', onOkay);
                +  }
                +  if (options.showCancel) {
                +    document.getElementById('customDialogCancel')
                +        .addEventListener('click', onCancel);
                +  }
                +
                +  backdropDiv.onclick = onCancel;
                +};
                diff --git a/blockly/webif/static/blockly/demos/custom-dialogs/index.html b/blockly/webif/static/blockly/demos/custom-dialogs/index.html
                new file mode 100644
                index 000000000..42cba5477
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/custom-dialogs/index.html
                @@ -0,0 +1,57 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Custom Dialog</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Custom Dialog</h1>
                +
                +  <p>This is a simple demo of replacing modal browser dialogs with HTML.</p>
                +
                +  <p>Try creating new variables, creating variables with names already in
                +     use, or deleting multiple blocks on the workspace.
                +  </p>
                +
                +  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Inputs" colour="230">
                +      <block type="math_number" gap="32"></block>
                +      <block type="text"></block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +  </script>
                +  <script src="custom-dialog.js"></script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/fixed/icon.png b/blockly/webif/static/blockly/demos/fixed/icon.png
                new file mode 100644
                index 000000000..1158acf01
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/fixed/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/fixed/index.html b/blockly/webif/static/blockly/demos/fixed/index.html
                new file mode 100644
                index 000000000..680fa7691
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/fixed/index.html
                @@ -0,0 +1,47 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Fixed Blockly</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Fixed Blockly</h1>
                +
                +  <p>This is a simple demo of injecting Blockly into a fixed-sized 'div' element.</p>
                +
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure-blockly/web/fixed-size">injecting fixed-sized Blockly</a>&hellip;</p>
                +
                +  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <block type="controls_if"></block>
                +    <block type="logic_compare"></block>
                +    <block type="controls_repeat_ext"></block>
                +    <block type="math_number"></block>
                +    <block type="math_arithmetic"></block>
                +    <block type="text"></block>
                +    <block type="text_print"></block>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/generator/icon.png b/blockly/webif/static/blockly/demos/generator/icon.png
                new file mode 100644
                index 000000000..132016e3f
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/generator/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/generator/index.html b/blockly/webif/static/blockly/demos/generator/index.html
                new file mode 100644
                index 000000000..7bc483855
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/generator/index.html
                @@ -0,0 +1,145 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Generating JavaScript</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Generating JavaScript</h1>
                +
                +  <p>This is a simple demo of generating code from blocks.</p>
                +
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure/web/code-generators">Code Generators</a>&hellip;</p>
                +
                +  <p>
                +    <button onclick="showCode()">Show JavaScript</button>
                +    <button onclick="runCode()">Run JavaScript</button>
                +  </p>
                +
                +  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +    </category>
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_length"></block>
                +      <block type="text_print"></block>
                +    </category>
                +  </xml>
                +
                +  <xml id="startBlocks" style="display: none">
                +    <block type="controls_if" inline="false" x="20" y="20">
                +      <mutation else="1"></mutation>
                +      <value name="IF0">
                +        <block type="logic_compare" inline="true">
                +          <field name="OP">EQ</field>
                +          <value name="A">
                +            <block type="math_arithmetic" inline="true">
                +              <field name="OP">MULTIPLY</field>
                +              <value name="A">
                +                <block type="math_number">
                +                  <field name="NUM">6</field>
                +                </block>
                +              </value>
                +              <value name="B">
                +                <block type="math_number">
                +                  <field name="NUM">7</field>
                +                </block>
                +              </value>
                +            </block>
                +          </value>
                +          <value name="B">
                +            <block type="math_number">
                +              <field name="NUM">42</field>
                +            </block>
                +          </value>
                +        </block>
                +      </value>
                +      <statement name="DO0">
                +        <block type="text_print" inline="false">
                +          <value name="TEXT">
                +            <block type="text">
                +              <field name="TEXT">Don't panic</field>
                +            </block>
                +          </value>
                +        </block>
                +      </statement>
                +      <statement name="ELSE">
                +        <block type="text_print" inline="false">
                +          <value name="TEXT">
                +            <block type="text">
                +              <field name="TEXT">Panic</field>
                +            </block>
                +          </value>
                +        </block>
                +      </statement>
                +    </block>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +    Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
                +                               workspace);
                +
                +    function showCode() {
                +      // Generate JavaScript code and display it.
                +      Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
                +      var code = Blockly.JavaScript.workspaceToCode(workspace);
                +      alert(code);
                +    }
                +
                +    function runCode() {
                +      // Generate JavaScript code and run it.
                +      window.LoopTrap = 1000;
                +      Blockly.JavaScript.INFINITE_LOOP_TRAP =
                +          'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
                +      var code = Blockly.JavaScript.workspaceToCode(workspace);
                +      Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
                +      try {
                +        eval(code);
                +      } catch (e) {
                +        alert(e);
                +      }
                +    }
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/graph/icon.png b/blockly/webif/static/blockly/demos/graph/icon.png
                new file mode 100644
                index 000000000..ad8b582f6
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/graph/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/graph/index.html b/blockly/webif/static/blockly/demos/graph/index.html
                new file mode 100644
                index 000000000..4732070d9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/graph/index.html
                @@ -0,0 +1,358 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Graph</title>
                +  <script src="https://www.google.com/jsapi"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    #funcText {
                +      margin-top: 1em;
                +      margin-left: 1.5em;
                +      font-family: sans-serif;
                +    }
                +    #funcText>img {
                +      height: 3px;
                +      width: 15px;
                +      vertical-align: middle;
                +      margin-right: .5em;
                +    }
                +    #y1 {
                +      background-color: #36c;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Graph</h1>
                +
                +  <p>This is a demo of giving instant feedback as blocks are changed.</p>
                +
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure/web/code-generators#generating_code">Realtime generation</a>&hellip;</p>
                +
                +  <table>
                +    <tr>
                +      <td>
                +        <div id="visualization" style="width: 400px"></div>
                +      </td>
                +      <td>
                +        <div id="blocklyDiv" style="height: 400px"></div>
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <div id="funcText">
                +    <img id="y1" src="../../media/1x1.gif">
                +    ...
                +  </div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Variables">
                +      <block type="graph_get_x"></block>
                +    </category>
                +    <category name="Logic">
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +  </xml>
                +
                +  <xml id="startBlocks" style="display: none">
                +    <block type="graph_set_y" deletable="false" x="100" y="100">
                +      <value name="VALUE">
                +        <block type="math_arithmetic">
                +          <field name="OP">POWER</field>
                +          <value name="A">
                +            <block type="graph_get_x"></block>
                +            <shadow type="math_number">
                +              <field name="NUM">1</field>
                +            </shadow>
                +          </value>
                +          <value name="B">
                +            <block type="math_number">
                +              <field name="NUM">2</field>
                +            </block>
                +            <shadow type="math_number">
                +              <field name="NUM">1</field>
                +            </shadow>
                +          </value>
                +        </block>
                +      </value>
                +    </block>
                +  </xml>
                +
                +  <script>
                +// Load the Google Chart Tools Visualization API and the chart package.
                +if (typeof google == 'object') {
                +  google.load('visualization', '1', {packages: ['corechart']});
                +} else {
                +  alert('Unable to load Google\'s chart API.\n' +
                +        'Are you connected to the Internet?');
                +}
                +
                +// Define the custom blocks and their JS generators.
                +Blockly.Blocks['graph_get_x'] = {
                +  // x variable getter.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "x",
                +      "output": "Number",
                +      "colour": Blockly.Blocks.variables.HUE,
                +      "tooltip": Blockly.Msg.VARIABLES_GET_TOOLTIP,
                +      "helpUrl": Blockly.Msg.VARIABLES_GET_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.JavaScript['graph_get_x'] = function(block) {
                +  // x variable getter.
                +  return ['x', Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.Blocks['graph_set_y'] = {
                +  // y variable setter.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "y = %1",
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "VALUE",
                +          "check": "Number"
                +        }
                +      ],
                +      "colour": Blockly.Blocks.variables.HUE,
                +      "tooltip": Blockly.Msg.VARIABLES_SET_TOOLTIP,
                +      "helpUrl": Blockly.Msg.VARIABLES_SET_HELPURL
                +    });
                +  }
                +};
                +
                +Blockly.JavaScript['graph_set_y'] = function(block) {
                +  // y variable setter.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '';
                +  return 'y = ' + argument0 + ';';
                +};
                +
                +/**
                + * Create a namespace for the application.
                + */
                +var Graph = {};
                +
                +/**
                + * Main Blockly workspace.
                + * @type {Blockly.WorkspaceSvg}
                + */
                +Graph.workspace = null;
                +
                +/**
                + * Cached copy of the function string.
                + * @type {?string}
                + * @private
                + */
                +Graph.oldFormula_ = null;
                +
                +/**
                + * Drawing options for the Chart API.
                + * @type {!Object}
                + * @private
                + */
                +Graph.options_ = {
                +  //curveType: 'function',
                +  width: 400, height: 400,
                +  chartArea: {left: '10%', width: '85%', height: '85%'}
                +};
                +
                +/**
                + * Visualize the graph of y = f(x) using Google Chart Tools.
                + * For more documentation on Google Chart Tools, see this linechart example:
                + * https://developers.google.com/chart/interactive/docs/gallery/linechart
                + */
                +Graph.drawVisualization = function() {
                +  var formula = Blockly.JavaScript.workspaceToCode(Graph.workspace);
                +  if (formula === Graph.oldFormula_) {
                +    // No change in the formula, don't recompute.
                +    return;
                +  }
                +  Graph.oldFormula_ = formula;
                +
                +  // Create and populate the data table.
                +  var data = google.visualization.arrayToDataTable(Graph.plot(formula));
                +  // Create and draw the visualization, passing in the data and options.
                +  new google.visualization.LineChart(document.getElementById('visualization')).
                +      draw(data, Graph.options_);
                +
                +  // Create the "y = ..." label.  Find the relevant part of the code.
                +  formula = formula.substring(formula.indexOf('y = '));
                +  formula = formula.substring(0, formula.indexOf(';'));
                +  var funcText = document.getElementById('funcText');
                +  funcText.replaceChild(document.createTextNode(formula), funcText.lastChild);
                +};
                +
                +/**
                + * Plot points on the function y = f(x).
                + * @param {string} code JavaScript code.
                + * @return {!Array.<!Array>} 2D Array of points on the graph.
                + */
                +Graph.plot = function(code) {
                +  // Initialize a table with two column headings.
                +  var table = [];
                +  var y;
                +  // TODO: Improve range and scale of graph.
                +  for (var x = -10; x <= 10; x = Math.round((x + 0.1) * 10) / 10) {
                +    try {
                +      eval(code);
                +    } catch (e) {
                +      y = NaN;
                +    }
                +    if (!isNaN(y)) {
                +      // Prevent y from being displayed inconsistently, some in decimals, some
                +      // in scientific notation, often when y has accumulated rounding errors.
                +      y = Math.round(y * Math.pow(10, 14)) / Math.pow(10, 14);
                +      table.push([x, y]);
                +    }
                +  }
                +  // Add column heading to table.
                +  if (table.length) {
                +    table.unshift(['x', 'y']);
                +  } else {
                +    // If the table is empty, add a [0, 0] row to prevent graph error.
                +    table.unshift(['x', 'y'], [0, 0]);
                +  }
                +  return table;
                +};
                +
                +/**
                + * Force Blockly to resize into the available width.
                + */
                +Graph.resize = function() {
                +  var width = Math.max(window.innerWidth - 440, 250);
                +  document.getElementById('blocklyDiv').style.width = width + 'px';
                +  Blockly.svgResize(Graph.workspace);
                +};
                +
                +/**
                + * Initialize Blockly and the graph.  Called on page load.
                + */
                +Graph.init = function() {
                +  Graph.workspace = Blockly.inject('blocklyDiv',
                +      {collapse: false,
                +       disable: false,
                +       media: '../../media/',
                +       toolbox: document.getElementById('toolbox')});
                +  Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
                +                             Graph.workspace);
                +  Graph.workspace.clearUndo();
                +
                +  // When Blockly changes, update the graph.
                +  Graph.workspace.addChangeListener(Graph.drawVisualization);
                +  Graph.workspace.addChangeListener(Blockly.Events.disableOrphans);
                +  Graph.resize();
                +};
                +
                +window.addEventListener('load', Graph.init);
                +window.addEventListener('resize', Graph.resize);
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/headless/icon.png b/blockly/webif/static/blockly/demos/headless/icon.png
                new file mode 100644
                index 000000000..af9ebe714
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/headless/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/headless/index.html b/blockly/webif/static/blockly/demos/headless/index.html
                new file mode 100644
                index 000000000..62d49fdfa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/headless/index.html
                @@ -0,0 +1,120 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Headless</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../python_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    td {
                +      vertical-align: top;
                +    }
                +    textarea {
                +      width: 100%;
                +      height: 20em;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Headless</h1>
                +
                +  <p>This is a simple demo of generating Python code from XML with no graphics.
                +  This might be useful for server-side code generation.</p>
                +
                +  <table style="width: 100%">
                +    <tr>
                +      <td style="width:50%">
                +        <textarea id="xml_input">
                +<xml>
                +  <block type="controls_if" inline="false" x="20" y="20">
                +    <mutation else="1"></mutation>
                +    <value name="IF0">
                +      <block type="logic_compare" inline="true">
                +        <field name="OP">EQ</field>
                +        <value name="A">
                +          <block type="math_arithmetic" inline="true">
                +            <field name="OP">MULTIPLY</field>
                +            <value name="A">
                +              <block type="math_number">
                +                <field name="NUM">6</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="math_number">
                +                <field name="NUM">7</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="B">
                +          <block type="math_number">
                +            <field name="NUM">42</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +    <statement name="DO0">
                +      <block type="text_print" inline="false">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">Don't panic</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <statement name="ELSE">
                +      <block type="text_print" inline="false">
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">Panic</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                +        </textarea>
                +      </td>
                +      <td>
                +      </td>
                +      <td style="width:50%">
                +        <textarea id="code_output" readonly></textarea>
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <div style="text-align: center">
                +    <button onclick="generate()">Generate Python &#10548;</button>
                +  </div>
                +
                +  <script>
                +    function generate() {
                +      // Parse the XML into a tree.
                +      var xmlText = document.getElementById('xml_input').value;
                +      try {
                +        var xml = Blockly.Xml.textToDom(xmlText)
                +      } catch (e) {
                +        alert(e);
                +        return;
                +      }
                +      // Create a headless workspace.
                +      var workspace = new Blockly.Workspace();
                +      Blockly.Xml.domToWorkspace(xml, workspace);
                +      var code = Blockly.Python.workspaceToCode(workspace);
                +      document.getElementById('code_output').value = code;
                +    }
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/index.html b/blockly/webif/static/blockly/demos/index.html
                new file mode 100644
                index 000000000..13eee2c97
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/index.html
                @@ -0,0 +1,213 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demos</title>
                +  <style>
                +    body {
                +      margin: 0 10%;
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    td {
                +      padding: 1ex;
                +    }
                +    img {
                +      border: none;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt; Demos</h1>
                +
                +  <p>These demos are intended for developers who want to integrate Blockly with
                +  their own applications.</p>
                +
                +  <table>
                +    <tr>
                +      <td>
                +        <a href="fixed/index.html">
                +          <img src="fixed/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="fixed/index.html">Fixed Blockly</a></div>
                +        <div>Inject Blockly into a page as a fixed element.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="resizable/index.html">
                +          <img src="resizable/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="resizable/index.html">Resizable Blockly</a></div>
                +        <div>Inject Blockly into a page as a resizable element.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="toolbox/index.html">
                +          <img src="toolbox/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="toolbox/index.html">Defining the Toolbox</a></div>
                +        <div>Organize blocks into categories for the user.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="maxBlocks/index.html">
                +          <img src="maxBlocks/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="maxBlocks/index.html">Maximum Block Limit</a></div>
                +        <div>Limit the total number of blocks allowed (for academic exercises).</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="generator/index.html">
                +          <img src="generator/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="generator/index.html">Generate JavaScript</a></div>
                +        <div>Turn blocks into code and execute it.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="headless/index.html">
                +          <img src="headless/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="headless/index.html">Headless</a></div>
                +        <div>Generate code from XML without graphics.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="interpreter/index.html">
                +          <img src="interpreter/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div style="font-weight: bold">JS Interpreter</div>
                +        <div>Demo #1: <a href="interpreter/step-execution.html">Step by step execution in JavaScript.</a></div>
                +        <div>Demo #2: <a href="interpreter/async-execution.html">Asynchronous execution in JavaScript.</a></div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="graph/index.html">
                +          <img src="graph/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="graph/index.html">Graph</a></div>
                +        <div>Instant updates when blocks are changed.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="rtl/index.html">
                +          <img src="rtl/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="rtl/index.html">RTL</a></div>
                +        <div>See what Blockly looks like in right-to-left mode (for Arabic and Hebrew).</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="storage/index.html">
                +          <img src="storage/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="storage/index.html">Cloud Storage</a></div>
                +        <div>Save and load blocks with App Engine.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="mirror/index.html">
                +          <img src="mirror/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="mirror/index.html">Mirrored Blockly</a></div>
                +        <div>Two Blockly instances connected as master-slave.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="accessible/index.html">
                +          <img src="accessible/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="accessible/index.html">Accessible Blockly</a></div>
                +        <div>Version of Blockly accessible to screen readers.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="plane/index.html">
                +          <img src="plane/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="plane/index.html">Plane</a></div>
                +        <div>Using Closure Templates to support 35 languages.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="code/index.html">
                +          <img src="code/icon.png" height=80 width=100>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="code/index.html">Code Editor</a></div>
                +        <div>Export a Blockly program into JavaScript, Python, PHP, Lua, Dart, or XML.</div>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td>
                +        <a href="blockfactory/index.html">
                +          <img src="blockfactory/icon.png" height=80 width=173>
                +        </a>
                +      </td>
                +      <td>
                +        <div><a href="blockfactory/index.html">Blockly Developer Tools</a></div>
                +        <div>Build custom blocks and setup a toolbox using Blockly.</div>
                +      </td>
                +    </tr>
                +  </table>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/interpreter/acorn_interpreter.js b/blockly/webif/static/blockly/demos/interpreter/acorn_interpreter.js
                new file mode 100644
                index 000000000..05fd7397c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/interpreter/acorn_interpreter.js
                @@ -0,0 +1,169 @@
                +// Acorn: Copyright 2012 Marijn Haverbeke, MIT License
                +var mod$$inline_58=function(a){function b(a){n=a||{};for(var b in Ua)Object.prototype.hasOwnProperty.call(n,b)||(n[b]=Ua[b]);wa=n.sourceFile||null}function c(a,b){var c=Ab(k,a);b+=" ("+c.line+":"+c.column+")";var d=new SyntaxError(b);d.pos=a;d.loc=c;d.raisedAt=f;throw d;}function d(a){function b(a){if(1==a.length)return c+="return str === "+JSON.stringify(a[0])+";";c+="switch(str){";for(var va=0;va<a.length;++va)c+="case "+JSON.stringify(a[va])+":";c+="return true}return false;"}a=a.split(" ");var c=
                +"",d=[],e=0;a:for(;e<a.length;++e){for(var g=0;g<d.length;++g)if(d[g][0].length==a[e].length){d[g].push(a[e]);continue a}d.push([a[e]])}if(3<d.length){d.sort(function(a,b){return b.length-a.length});c+="switch(str.length){";for(e=0;e<d.length;++e)a=d[e],c+="case "+a[0].length+":",b(a);c+="}"}else b(a);return new Function("str",c)}function e(){this.line=G;this.column=f-D}function g(a,b){X=f;n.locations&&(ia=new e);p=a;l();H=b;R=a.beforeExpr}function h(){for(var a=f,b=n.onComment&&n.locations&&new e,
                +c=k.charCodeAt(f+=2);f<S&&10!==c&&13!==c&&8232!==c&&8233!==c;)++f,c=k.charCodeAt(f);if(n.onComment)n.onComment(!1,k.slice(a+2,f),a,f,b,n.locations&&new e)}function l(){for(;f<S;){var a=k.charCodeAt(f);if(32===a)++f;else if(13===a)++f,a=k.charCodeAt(f),10===a&&++f,n.locations&&(++G,D=f);else if(10===a||8232===a||8233===a)++f,n.locations&&(++G,D=f);else if(8<a&&14>a)++f;else if(47===a)if(a=k.charCodeAt(f+1),42===a){var a=n.onComment&&n.locations&&new e,b=f,d=k.indexOf("*/",f+=2);-1===d&&c(f-2,"Unterminated comment");
                +f=d+2;if(n.locations){Y.lastIndex=b;for(var g=void 0;(g=Y.exec(k))&&g.index<f;)++G,D=g.index+g[0].length}if(n.onComment)n.onComment(!0,k.slice(b+2,d),b,f,a,n.locations&&new e)}else if(47===a)h();else break;else if(160===a)++f;else if(5760<=a&&Bb.test(String.fromCharCode(a)))++f;else break}}function m(a){switch(a){case 46:return a=k.charCodeAt(f+1),48<=a&&57>=a?a=P(!0):(++f,a=g(xa)),a;case 40:return++f,g(I);case 41:return++f,g(E);case 59:return++f,g(J);case 44:return++f,g(L);case 91:return++f,g(ja);
                +case 93:return++f,g(ka);case 123:return++f,g(Z);case 125:return++f,g(T);case 58:return++f,g(aa);case 63:return++f,g(ya);case 48:if(a=k.charCodeAt(f+1),120===a||88===a)return f+=2,a=B(16),null==a&&c(x+2,"Expected hexadecimal number"),la(k.charCodeAt(f))&&c(f,"Identifier directly after number"),a=g(ba,a);case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return P(!1);case 34:case 39:a:{f++;for(var b="";;){f>=S&&c(x,"Unterminated string constant");var d=k.charCodeAt(f);if(d===a){++f;
                +a=g(da,b);break a}if(92===d){var d=k.charCodeAt(++f),e=/^[0-7]+/.exec(k.slice(f,f+3));for(e&&(e=e[0]);e&&255<parseInt(e,8);)e=e.slice(0,-1);"0"===e&&(e=null);++f;if(e)C&&c(f-2,"Octal literal in strict mode"),b+=String.fromCharCode(parseInt(e,8)),f+=e.length-1;else switch(d){case 110:b+="\n";break;case 114:b+="\r";break;case 120:b+=String.fromCharCode(ma(2));break;case 117:b+=String.fromCharCode(ma(4));break;case 85:b+=String.fromCharCode(ma(8));break;case 116:b+="\t";break;case 98:b+="\b";break;case 118:b+=
                +"\x0B";break;case 102:b+="\f";break;case 48:b+="\x00";break;case 13:10===k.charCodeAt(f)&&++f;case 10:n.locations&&(D=f,++G);break;default:b+=String.fromCharCode(d)}}else 13!==d&&10!==d&&8232!==d&&8233!==d||c(x,"Unterminated string constant"),b+=String.fromCharCode(d),++f}}return a;case 47:return a=k.charCodeAt(f+1),R?(++f,a=K()):a=61===a?t(U,2):t(za,1),a;case 37:case 42:return a=k.charCodeAt(f+1),a=61===a?t(U,2):t(Cb,1),a;case 124:case 38:return b=k.charCodeAt(f+1),a=b===a?t(124===a?Va:Wa,2):61===
                +b?t(U,2):t(124===a?Db:Eb,1),a;case 94:return a=k.charCodeAt(f+1),a=61===a?t(U,2):t(Fb,1),a;case 43:case 45:return b=k.charCodeAt(f+1),b===a?45==b&&62==k.charCodeAt(f+2)&&na.test(k.slice(M,f))?(f+=3,h(),l(),a=z()):a=t(Gb,2):a=61===b?t(U,2):t(Hb,1),a;case 60:case 62:return b=k.charCodeAt(f+1),d=1,b===a?(d=62===a&&62===k.charCodeAt(f+2)?3:2,a=61===k.charCodeAt(f+d)?t(U,d+1):t(Ib,d)):33==b&&60==a&&45==k.charCodeAt(f+2)&&45==k.charCodeAt(f+3)?(f+=4,h(),l(),a=z()):(61===b&&(d=61===k.charCodeAt(f+2)?3:2),
                +a=t(Jb,d)),a;case 61:case 33:return b=k.charCodeAt(f+1),a=61===b?t(Kb,61===k.charCodeAt(f+2)?3:2):t(61===a?Aa:Xa,1),a;case 126:return t(Xa,1)}return!1}function z(a){a?f=x+1:x=f;n.locations&&(oa=new e);if(a)return K();if(f>=S)return g(pa);var b=k.charCodeAt(f);if(la(b)||92===b)return Ya();a=m(b);if(!1===a){b=String.fromCharCode(b);if("\\"===b||Za.test(b))return Ya();c(f,"Unexpected character '"+b+"'")}return a}function t(a,b){var c=k.slice(f,f+b);f+=b;g(a,c)}function K(){for(var a,b,d=f;;){f>=S&&c(d,
                +"Unterminated regular expression");var e=k.charAt(f);na.test(e)&&c(d,"Unterminated regular expression");if(a)a=!1;else{if("["===e)b=!0;else if("]"===e&&b)b=!1;else if("/"===e&&!b)break;a="\\"===e}++f}a=k.slice(d,f);++f;(b=$a())&&!/^[gmsiy]*$/.test(b)&&c(d,"Invalid regexp flag");return g(Ba,new RegExp(a,b))}function B(a,b){for(var c=f,d=0,e=0,g=null==b?Infinity:b;e<g;++e){var h=k.charCodeAt(f),h=97<=h?h-97+10:65<=h?h-65+10:48<=h&&57>=h?h-48:Infinity;if(h>=a)break;++f;d=d*a+h}return f===c||null!=b&&
                +f-c!==b?null:d}function P(a){var b=f,d=!1,e=48===k.charCodeAt(f);a||null!==B(10)||c(b,"Invalid number");46===k.charCodeAt(f)&&(++f,B(10),d=!0);a=k.charCodeAt(f);if(69===a||101===a)a=k.charCodeAt(++f),43!==a&&45!==a||++f,null===B(10)&&c(b,"Invalid number"),d=!0;la(k.charCodeAt(f))&&c(f,"Identifier directly after number");a=k.slice(b,f);var h;d?h=parseFloat(a):e&&1!==a.length?/[89]/.test(a)||C?c(b,"Invalid number"):h=parseInt(a,8):h=parseInt(a,10);return g(ba,h)}function ma(a){a=B(16,a);null===a&&c(x,
                +"Bad character escape sequence");return a}function $a(){ca=!1;for(var a,b=!0,d=f;;){var e=k.charCodeAt(f);if(ab(e))ca&&(a+=k.charAt(f)),++f;else if(92===e){ca||(a=k.slice(d,f));ca=!0;117!=k.charCodeAt(++f)&&c(f,"Expecting Unicode escape sequence \\uXXXX");++f;var e=ma(4),g=String.fromCharCode(e);g||c(f-1,"Invalid Unicode escape");(b?la(e):ab(e))||c(f-4,"Invalid Unicode escape");a+=g}else break;b=!1}return ca?a:k.slice(d,f)}function Ya(){var a=$a(),b=V;ca||(Lb(a)?b=Ca[a]:(n.forbidReserved&&(3===n.ecmaVersion?
                +Mb:Nb)(a)||C&&bb(a))&&c(x,"The keyword '"+a+"' is reserved"));return g(b,a)}function r(){Da=x;M=X;Ea=ia;z()}function Fa(a){C=a;f=M;if(n.locations)for(;f<D;)D=k.lastIndexOf("\n",D-2)+1,--G;l();z()}function cb(){this.type=null;this.start=x;this.end=null}function db(){this.start=oa;this.end=null;null!==wa&&(this.source=wa)}function y(){var a=new cb;n.locations&&(a.loc=new db);n.directSourceFile&&(a.sourceFile=n.directSourceFile);n.ranges&&(a.range=[x,0]);return a}function Q(a){var b=new cb;b.start=a.start;
                +n.locations&&(b.loc=new db,b.loc.start=a.loc.start);n.ranges&&(b.range=[a.range[0],0]);return b}function q(a,b){a.type=b;a.end=M;n.locations&&(a.loc.end=Ea);n.ranges&&(a.range[1]=M);return a}function Ga(a){return 5<=n.ecmaVersion&&"ExpressionStatement"===a.type&&"Literal"===a.expression.type&&"use strict"===a.expression.value}function u(a){if(p===a)return r(),!0}function qa(){return!n.strictSemicolons&&(p===pa||p===T||na.test(k.slice(M,x)))}function W(){u(J)||qa()||N()}function v(a){p===a?r():N()}
                +function N(){c(x,"Unexpected token")}function ra(a){"Identifier"!==a.type&&"MemberExpression"!==a.type&&c(a.start,"Assigning to rvalue");C&&"Identifier"===a.type&&sa(a.name)&&c(a.start,"Assigning to "+a.name+" in strict mode")}function F(){(p===za||p===U&&"/="==H)&&z(!0);var a=p,b=y();switch(a){case Ha:case eb:r();var d=a===Ha;u(J)||qa()?b.label=null:p!==V?N():(b.label=O(),W());for(var e=0;e<w.length;++e){var g=w[e];if(null==b.label||g.name===b.label.name){if(null!=g.kind&&(d||"loop"===g.kind))break;
                +if(b.label&&d)break}}e===w.length&&c(b.start,"Unsyntactic "+a.keyword);return q(b,d?"BreakStatement":"ContinueStatement");case fb:return r(),W(),q(b,"DebuggerStatement");case gb:return r(),w.push(Ia),b.body=F(),w.pop(),v(Ja),b.test=ea(),W(),q(b,"DoWhileStatement");case hb:r();w.push(Ia);v(I);if(p===J)return Ka(b,null);if(p===La)return a=y(),r(),ib(a,!0),q(a,"VariableDeclaration"),1===a.declarations.length&&u(ta)?jb(b,a):Ka(b,a);a=A(!1,!0);return u(ta)?(ra(a),jb(b,a)):Ka(b,a);case Ma:return r(),Na(b,
                +!0);case kb:return r(),b.test=ea(),b.consequent=F(),b.alternate=u(lb)?F():null,q(b,"IfStatement");case mb:return fa||c(x,"'return' outside of function"),r(),u(J)||qa()?b.argument=null:(b.argument=A(),W()),q(b,"ReturnStatement");case Oa:r();b.discriminant=ea();b.cases=[];v(Z);for(w.push(Ob);p!=T;)p===Pa||p===nb?(a=p===Pa,e&&q(e,"SwitchCase"),b.cases.push(e=y()),e.consequent=[],r(),a?e.test=A():(d&&c(Da,"Multiple default clauses"),d=!0,e.test=null),v(aa)):(e||N(),e.consequent.push(F()));e&&q(e,"SwitchCase");
                +r();w.pop();return q(b,"SwitchStatement");case ob:return r(),na.test(k.slice(M,x))&&c(M,"Illegal newline after throw"),b.argument=A(),W(),q(b,"ThrowStatement");case pb:return r(),b.block=ga(),b.handler=null,p===qb&&(a=y(),r(),v(I),a.param=O(),C&&sa(a.param.name)&&c(a.param.start,"Binding "+a.param.name+" in strict mode"),v(E),a.guard=null,a.body=ga(),b.handler=q(a,"CatchClause")),b.guardedHandlers=rb,b.finalizer=u(sb)?ga():null,b.handler||b.finalizer||c(b.start,"Missing catch or finally clause"),
                +q(b,"TryStatement");case La:return r(),ib(b),W(),q(b,"VariableDeclaration");case Ja:return r(),b.test=ea(),w.push(Ia),b.body=F(),w.pop(),q(b,"WhileStatement");case tb:return C&&c(x,"'with' in strict mode"),r(),b.object=ea(),b.body=F(),q(b,"WithStatement");case Z:return ga();case J:return r(),q(b,"EmptyStatement");default:d=H;g=A();if(a===V&&"Identifier"===g.type&&u(aa)){for(e=0;e<w.length;++e)w[e].name===d&&c(g.start,"Label '"+d+"' is already declared");a=p.isLoop?"loop":p===Oa?"switch":null;w.push({name:d,
                +kind:a});b.body=F();w.pop();b.label=g;return q(b,"LabeledStatement")}b.expression=g;W();return q(b,"ExpressionStatement")}}function ea(){v(I);var a=A();v(E);return a}function ga(a){var b=y(),c=!0,d=!1,e;b.body=[];for(v(Z);!u(T);){var g=F();b.body.push(g);c&&a&&Ga(g)&&(e=d,Fa(d=!0));c=!1}d&&!e&&Fa(!1);return q(b,"BlockStatement")}function Ka(a,b){a.init=b;v(J);a.test=p===J?null:A();v(J);a.update=p===E?null:A();v(E);a.body=F();w.pop();return q(a,"ForStatement")}function jb(a,b){a.left=b;a.right=A();
                +v(E);a.body=F();w.pop();return q(a,"ForInStatement")}function ib(a,b){a.declarations=[];for(a.kind="var";;){var d=y();d.id=O();C&&sa(d.id.name)&&c(d.id.start,"Binding "+d.id.name+" in strict mode");d.init=u(Aa)?A(!0,b):null;a.declarations.push(q(d,"VariableDeclarator"));if(!u(L))break}return a}function A(a,b){var c=Qa(b);if(!a&&p===L){var d=Q(c);for(d.expressions=[c];u(L);)d.expressions.push(Qa(b));return q(d,"SequenceExpression")}return c}function Qa(a){var b;b=a;var c;c=b;c=Ra(Sa(),-1,c);if(u(ya)){var d=
                +Q(c);d.test=c;d.consequent=A(!0);v(aa);d.alternate=A(!0,b);b=q(d,"ConditionalExpression")}else b=c;return p.isAssign?(c=Q(b),c.operator=H,c.left=b,r(),c.right=Qa(a),ra(b),q(c,"AssignmentExpression")):b}function Ra(a,b,c){var d=p.binop;if(null!=d&&(!c||p!==ta)&&d>b){var e=Q(a);e.left=a;e.operator=H;a=p;r();e.right=Ra(Sa(),d,c);d=q(e,a===Va||a===Wa?"LogicalExpression":"BinaryExpression");return Ra(d,b,c)}return a}function Sa(){if(p.prefix){var a=y(),b=p.isUpdate;a.operator=H;R=a.prefix=!0;r();a.argument=
                +Sa();b?ra(a.argument):C&&"delete"===a.operator&&"Identifier"===a.argument.type&&c(a.start,"Deleting local variable in strict mode");return q(a,b?"UpdateExpression":"UnaryExpression")}for(b=ha(ua());p.postfix&&!qa();)a=Q(b),a.operator=H,a.prefix=!1,a.argument=b,ra(b),r(),b=q(a,"UpdateExpression");return b}function ha(a,b){if(u(xa)){var c=Q(a);c.object=a;c.property=O(!0);c.computed=!1;return ha(q(c,"MemberExpression"),b)}return u(ja)?(c=Q(a),c.object=a,c.property=A(),c.computed=!0,v(ka),ha(q(c,"MemberExpression"),
                +b)):!b&&u(I)?(c=Q(a),c.callee=a,c.arguments=Ta(E,!1),ha(q(c,"CallExpression"),b)):a}function ua(){switch(p){case ub:var a=y();r();return q(a,"ThisExpression");case V:return O();case ba:case da:case Ba:return a=y(),a.value=H,a.raw=k.slice(x,X),r(),q(a,"Literal");case vb:case wb:case xb:return a=y(),a.value=p.atomValue,a.raw=p.keyword,r(),q(a,"Literal");case I:var a=oa,b=x;r();var d=A();d.start=b;d.end=X;n.locations&&(d.loc.start=a,d.loc.end=ia);n.ranges&&(d.range=[b,X]);v(E);return d;case ja:return a=
                +y(),r(),a.elements=Ta(ka,!0,!0),q(a,"ArrayExpression");case Z:a=y();b=!0;d=!1;a.properties=[];for(r();!u(T);){if(b)b=!1;else if(v(L),n.allowTrailingCommas&&u(T))break;var e={key:p===ba||p===da?ua():O(!0)},g=!1,h;u(aa)?(e.value=A(!0),h=e.kind="init"):5<=n.ecmaVersion&&"Identifier"===e.key.type&&("get"===e.key.name||"set"===e.key.name)?(g=d=!0,h=e.kind=e.key.name,e.key=p===ba||p===da?ua():O(!0),p!==I&&N(),e.value=Na(y(),!1)):N();if("Identifier"===e.key.type&&(C||d))for(var f=0;f<a.properties.length;++f){var l=
                +a.properties[f];if(l.key.name===e.key.name){var m=h==l.kind||g&&"init"===l.kind||"init"===h&&("get"===l.kind||"set"===l.kind);m&&!C&&"init"===h&&"init"===l.kind&&(m=!1);m&&c(e.key.start,"Redefinition of property")}}a.properties.push(e)}return a=q(a,"ObjectExpression");case Ma:return a=y(),r(),Na(a,!1);case yb:return a=y(),r(),a.callee=ha(ua(),!0),u(I)?a.arguments=Ta(E,!1):a.arguments=rb,a=q(a,"NewExpression");default:N()}}function Na(a,b){p===V?a.id=O():b?N():a.id=null;a.params=[];var d=!0;for(v(I);!u(E);)d?
                +d=!1:v(L),a.params.push(O());var d=fa,e=w;fa=!0;w=[];a.body=ga(!0);fa=d;w=e;if(C||a.body.body.length&&Ga(a.body.body[0]))for(d=a.id?-1:0;d<a.params.length;++d)if(e=0>d?a.id:a.params[d],(bb(e.name)||sa(e.name))&&c(e.start,"Defining '"+e.name+"' in strict mode"),0<=d)for(var g=0;g<d;++g)e.name===a.params[g].name&&c(e.start,"Argument name clash in strict mode");return q(a,b?"FunctionDeclaration":"FunctionExpression")}function Ta(a,b,c){for(var d=[],e=!0;!u(a);){if(e)e=!1;else if(v(L),b&&n.allowTrailingCommas&&
                +u(a))break;c&&p===L?d.push(null):d.push(A(!0))}return d}function O(a){var b=y();b.name=p===V?H:a&&!n.forbidReserved&&p.keyword||N();R=!1;r();return q(b,"Identifier")}a.version="0.4.1";var n,k,S,wa;a.parse=function(a,c){k=String(a);S=k.length;b(c);G=1;f=D=0;R=!0;l();var d,g=n.program;Da=M=f;n.locations&&(Ea=new e);fa=C=null;w=[];z();d=g||y();var h=!0;g||(d.body=[]);for(;p!==pa;)g=F(),d.body.push(g),h&&Ga(g)&&Fa(!0),h=!1;return d=q(d,"Program")};var Ua=a.defaultOptions={ecmaVersion:5,strictSemicolons:!1,
                +allowTrailingCommas:!0,forbidReserved:!1,locations:!1,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null},Ab=a.getLineInfo=function(a,b){for(var c=1,d=0;;){Y.lastIndex=d;var e=Y.exec(a);if(e&&e.index<b)++c,d=e.index+e[0].length;else break}return{line:c,column:b-d}};a.tokenize=function(a,c){function d(a){z(a);e.start=x;e.end=X;e.startLoc=oa;e.endLoc=ia;e.type=p;e.value=H;return e}k=String(a);S=k.length;b(c);G=1;f=D=0;R=!0;l();var e={};d.jumpTo=function(a,b){f=a;if(n.locations){G=
                +1;D=Y.lastIndex=0;for(var c;(c=Y.exec(k))&&c.index<a;)++G,D=c.index+c[0].length}R=b;l()};return d};var f,x,X,oa,ia,p,H,R,G,D,Da,M,Ea,fa,w,C,rb=[],ba={type:"num"},Ba={type:"regexp"},da={type:"string"},V={type:"name"},pa={type:"eof"},Ha={keyword:"break"},Pa={keyword:"case",beforeExpr:!0},qb={keyword:"catch"},eb={keyword:"continue"},fb={keyword:"debugger"},nb={keyword:"default"},gb={keyword:"do",isLoop:!0},lb={keyword:"else",beforeExpr:!0},sb={keyword:"finally"},hb={keyword:"for",isLoop:!0},Ma={keyword:"function"},
                +kb={keyword:"if"},mb={keyword:"return",beforeExpr:!0},Oa={keyword:"switch"},ob={keyword:"throw",beforeExpr:!0},pb={keyword:"try"},La={keyword:"var"},Ja={keyword:"while",isLoop:!0},tb={keyword:"with"},yb={keyword:"new",beforeExpr:!0},ub={keyword:"this"},vb={keyword:"null",atomValue:null},wb={keyword:"true",atomValue:!0},xb={keyword:"false",atomValue:!1},ta={keyword:"in",binop:7,beforeExpr:!0},Ca={"break":Ha,"case":Pa,"catch":qb,"continue":eb,"debugger":fb,"default":nb,"do":gb,"else":lb,"finally":sb,
                +"for":hb,"function":Ma,"if":kb,"return":mb,"switch":Oa,"throw":ob,"try":pb,"var":La,"while":Ja,"with":tb,"null":vb,"true":wb,"false":xb,"new":yb,"in":ta,"instanceof":{keyword:"instanceof",binop:7,beforeExpr:!0},"this":ub,"typeof":{keyword:"typeof",prefix:!0,beforeExpr:!0},"void":{keyword:"void",prefix:!0,beforeExpr:!0},"delete":{keyword:"delete",prefix:!0,beforeExpr:!0}},ja={type:"[",beforeExpr:!0},ka={type:"]"},Z={type:"{",beforeExpr:!0},T={type:"}"},I={type:"(",beforeExpr:!0},E={type:")"},L={type:",",
                +beforeExpr:!0},J={type:";",beforeExpr:!0},aa={type:":",beforeExpr:!0},xa={type:"."},ya={type:"?",beforeExpr:!0},za={binop:10,beforeExpr:!0},Aa={isAssign:!0,beforeExpr:!0},U={isAssign:!0,beforeExpr:!0},Gb={postfix:!0,prefix:!0,isUpdate:!0},Xa={prefix:!0,beforeExpr:!0},Va={binop:1,beforeExpr:!0},Wa={binop:2,beforeExpr:!0},Db={binop:3,beforeExpr:!0},Fb={binop:4,beforeExpr:!0},Eb={binop:5,beforeExpr:!0},Kb={binop:6,beforeExpr:!0},Jb={binop:7,beforeExpr:!0},Ib={binop:8,beforeExpr:!0},Hb={binop:9,prefix:!0,
                +beforeExpr:!0},Cb={binop:10,beforeExpr:!0};a.tokTypes={bracketL:ja,bracketR:ka,braceL:Z,braceR:T,parenL:I,parenR:E,comma:L,semi:J,colon:aa,dot:xa,question:ya,slash:za,eq:Aa,name:V,eof:pa,num:ba,regexp:Ba,string:da};for(var zb in Ca)a.tokTypes["_"+zb]=Ca[zb];var Mb=d("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"),Nb=d("class enum extends super const export import"),
                +bb=d("implements interface let package private protected public static yield"),sa=d("eval arguments"),Lb=d("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"),Bb=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/,Za=RegExp("[\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]"),
                +Pb=RegExp("[\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]"),
                +na=/[\n\r\u2028\u2029]/,Y=/\r\n|[\n\r\u2028\u2029]/g,la=a.isIdentifierStart=function(a){return 65>a?36===a:91>a?!0:97>a?95===a:123>a?!0:170<=a&&Za.test(String.fromCharCode(a))},ab=a.isIdentifierChar=function(a){return 48>a?36===a:58>a?!0:65>a?!1:91>a?!0:97>a?95===a:123>a?!0:170<=a&&Pb.test(String.fromCharCode(a))},ca,Ia={kind:"loop"},Ob={kind:"switch"}};
                +"object"==typeof exports&&"object"==typeof module?mod$$inline_58(exports):"function"==typeof define&&define.amd?define(["exports"],mod$$inline_58):mod$$inline_58(this.acorn||(this.acorn={}));
                +// JS-Interpreter: Copyright 2013 Google Inc, Apache 2.0
                +var Interpreter=function(a,b){"string"==typeof a&&(a=acorn.parse(a,Interpreter.PARSE_OPTIONS));this.ast=a;this.initFunc_=b;this.paused_=!1;this.polyfills_=[];this.UNDEFINED=new Interpreter.Primitive(void 0,this);this.NULL=new Interpreter.Primitive(null,this);this.NAN=new Interpreter.Primitive(NaN,this);this.TRUE=new Interpreter.Primitive(!0,this);this.FALSE=new Interpreter.Primitive(!1,this);this.NUMBER_ZERO=new Interpreter.Primitive(0,this);this.NUMBER_ONE=new Interpreter.Primitive(1,this);this.STRING_EMPTY=
                +new Interpreter.Primitive("",this);b=this.createScope(this.ast,null);this.NAN.parent=this.NUMBER;this.TRUE.parent=this.BOOLEAN;this.FALSE.parent=this.BOOLEAN;this.NUMBER_ZERO.parent=this.NUMBER;this.NUMBER_ONE.parent=this.NUMBER;this.STRING_EMPTY.parent=this.STRING;this.ast=acorn.parse(this.polyfills_.join("\n"),Interpreter.PARSE_OPTIONS);this.polyfills_=void 0;this.stripLocations_(this.ast);this.stateStack=[{node:this.ast,scope:b,thisExpression:b,done:!1}];this.run();this.value=this.UNDEFINED;this.ast=
                +a;this.stateStack=[{node:this.ast,scope:b,thisExpression:b,done:!1}]};Interpreter.PARSE_OPTIONS={ecmaVersion:5};Interpreter.READONLY_DESCRIPTOR={configurable:!0,enumerable:!0,writable:!1};Interpreter.NONENUMERABLE_DESCRIPTOR={configurable:!0,enumerable:!1,writable:!0};Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR={configurable:!0,enumerable:!1,writable:!1};
                +Interpreter.prototype.appendCode=function(a){var b=this.stateStack[this.stateStack.length-1];if(!b||"Program"!=b.node.type)throw Error("Expecting original AST to start with a Program node.");"string"==typeof a&&(a=acorn.parse(a,Interpreter.PARSE_OPTIONS));if(!a||"Program"!=a.type)throw Error("Expecting new AST to start with a Program node.");this.populateScope_(a,b.scope);for(var c=0,d;d=a.body[c];c++)b.node.body.push(d);b.done=!1};
                +Interpreter.prototype.step=function(){var a=this.stateStack[0];if(!a||"Program"==a.node.type&&a.done)return!1;if(this.paused_)return!0;this["step"+a.node.type]();return a.node.end?!0:this.step()};Interpreter.prototype.run=function(){for(;!this.paused_&&this.step(););return this.paused_};
                +Interpreter.prototype.initGlobalScope=function(a){this.setProperty(a,"Infinity",this.createPrimitive(Infinity),Interpreter.READONLY_DESCRIPTOR);this.setProperty(a,"NaN",this.NAN,Interpreter.READONLY_DESCRIPTOR);this.setProperty(a,"undefined",this.UNDEFINED,Interpreter.READONLY_DESCRIPTOR);this.setProperty(a,"window",a,Interpreter.READONLY_DESCRIPTOR);this.setProperty(a,"self",a);this.initFunction(a);this.initObject(a);a.parent=this.OBJECT;this.initArray(a);this.initNumber(a);this.initString(a);this.initBoolean(a);
                +this.initDate(a);this.initMath(a);this.initRegExp(a);this.initJSON(a);this.initError(a);var b=this,c;c=function(a){a=a||b.UNDEFINED;return b.createPrimitive(isNaN(a.toNumber()))};this.setProperty(a,"isNaN",this.createNativeFunction(c));c=function(a){a=a||b.UNDEFINED;return b.createPrimitive(isFinite(a.toNumber()))};this.setProperty(a,"isFinite",this.createNativeFunction(c));this.setProperty(a,"parseFloat",this.getProperty(this.NUMBER,"parseFloat"));this.setProperty(a,"parseInt",this.getProperty(this.NUMBER,
                +"parseInt"));c=this.createObject(this.FUNCTION);c.eval=!0;this.setProperty(c,"length",this.NUMBER_ONE,Interpreter.READONLY_DESCRIPTOR);this.setProperty(a,"eval",c);for(var d=[[escape,"escape"],[unescape,"unescape"],[decodeURI,"decodeURI"],[decodeURIComponent,"decodeURIComponent"],[encodeURI,"encodeURI"],[encodeURIComponent,"encodeURIComponent"]],h=0;h<d.length;h++)c=function(a){return function(c){c=(c||b.UNDEFINED).toString();try{c=a(c)}catch(r){b.throwException(b.URI_ERROR,r.message)}return b.createPrimitive(c)}}(d[h][0]),
                +this.setProperty(a,d[h][1],this.createNativeFunction(c));this.initFunc_&&this.initFunc_(this,a)};
                +Interpreter.prototype.initFunction=function(a){var b=this,c;c=function(a){for(var c=this.parent==b.FUNCTION?this:b.createObject(b.FUNCTION),d=arguments.length?arguments[arguments.length-1].toString():"",p=[],r=0;r<arguments.length-1;r++)p.push(arguments[r].toString());p=p.join(", ");if(-1!=p.indexOf(")"))throw SyntaxError("Function arg string contains parenthesis");c.parentScope=b.stateStack[b.stateStack.length-1].scope;d=acorn.parse("$ = function("+p+") {"+d+"};",Interpreter.PARSE_OPTIONS);c.node=
                +d.body[0].expression.right;b.setProperty(c,"length",b.createPrimitive(c.node.length),Interpreter.READONLY_DESCRIPTOR);return c};this.FUNCTION=this.createObject(null);this.setProperty(a,"Function",this.FUNCTION);this.FUNCTION.type="function";this.setProperty(this.FUNCTION,"prototype",this.createObject(null));this.FUNCTION.nativeFunc=c;c=function(a,c){var d=b.stateStack[0];d.func_=this;d.funcThis_=a;d.arguments=[];if(c)if(b.isa(c,b.ARRAY))for(a=0;a<c.length;a++)d.arguments[a]=b.getProperty(c,a);else b.throwException(b.TYPE_ERROR,
                +"CreateListFromArrayLike called on non-object");d.doneArgs_=!0;d.doneExec_=!1};this.setNativeFunctionPrototype(this.FUNCTION,"apply",c);c=function(a,c){var d=b.stateStack[0];d.func_=this;d.funcThis_=a;d.arguments=[];for(var h=1;h<arguments.length;h++)d.arguments.push(arguments[h]);d.doneArgs_=!0;d.doneExec_=!1};this.setNativeFunctionPrototype(this.FUNCTION,"call",c);c=function(a,c){var d=b.createFunction(this.node,this.parentScope);a&&(d.boundThis_=a);d.boundArgs_=[];for(var h=1;h<arguments.length;h++)d.boundArgs_.push(arguments[h]);
                +return d};this.setNativeFunctionPrototype(this.FUNCTION,"bind",c);c=function(){return b.createPrimitive(this.toString())};this.setNativeFunctionPrototype(this.FUNCTION,"toString",c);this.setProperty(this.FUNCTION,"toString",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(){return b.createPrimitive(this.valueOf())};this.setNativeFunctionPrototype(this.FUNCTION,"valueOf",c);this.setProperty(this.FUNCTION,"valueOf",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR)};
                +Interpreter.prototype.initObject=function(a){var b=this,c;c=function(a){if(!a||a==b.UNDEFINED||a==b.NULL)return this.parent==b.OBJECT?this:b.createObject(b.OBJECT);if(a.isPrimitive){var c=b.createObject(a.parent);c.data=a.data;return c}return a};this.OBJECT=this.createNativeFunction(c);this.setProperty(a,"Object",this.OBJECT);c=function(a){var c=b.createObject(b.ARRAY),d=0,p;for(p in a.properties)b.setProperty(c,d,b.createPrimitive(p)),d++;return c};this.setProperty(this.OBJECT,"getOwnPropertyNames",
                +this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a){var c=b.createObject(b.ARRAY),d=0,p;for(p in a.properties)a.notEnumerable[p]||(b.setProperty(c,d,b.createPrimitive(p)),d++);return c};this.setProperty(this.OBJECT,"keys",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a,c,g){c=(c||b.UNDEFINED).toString();if(g instanceof Interpreter.Object)if(!a.properties[c]&&a.preventExtensions)b.throwException(b.TYPE_ERROR,"Can't define property "+c+", object is not extensible");
                +else{var d=b.getProperty(g,"value");d==b.UNDEFINED&&(d=null);var h=b.getProperty(g,"get"),v=b.getProperty(g,"set");g={configurable:b.pseudoToNative(b.getProperty(g,"configurable")),enumerable:b.pseudoToNative(b.getProperty(g,"enumerable")),writable:b.pseudoToNative(b.getProperty(g,"writable")),get:h==b.UNDEFINED?void 0:h,set:v==b.UNDEFINED?void 0:v};b.setProperty(a,c,d,g);return a}else b.throwException(b.TYPE_ERROR,"Property description must be an object.")};this.setProperty(this.OBJECT,"defineProperty",
                +this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);this.polyfills_.push("Object.defineProperty(Array.prototype, 'defineProperties', {configurable: true, value:","function(obj, props) {","var keys = Object.keys(props);","for (var i = 0; i < keys.length; i++) {","Object.defineProperty(obj, keys[i], props[keys[i]]);","}","return obj;","}","});","");c=function(a,c){c=(c||b.UNDEFINED).toString();if(!(c in a.properties))return b.UNDEFINED;var d=!a.notConfigurable[c],h=!a.notEnumerable[c],
                +r=!a.notWritable[c],v=a.getter[c],w=a.setter[c],q=b.createObject(b.OBJECT);b.setProperty(q,"configurable",b.createPrimitive(d));b.setProperty(q,"enumerable",b.createPrimitive(h));v||w?(b.setProperty(q,"getter",v),b.setProperty(q,"setter",w)):(b.setProperty(q,"writable",b.createPrimitive(r)),b.setProperty(q,"value",b.getProperty(a,c)));return q};this.setProperty(this.OBJECT,"getOwnPropertyDescriptor",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a){return a.parent&&
                +a.parent.properties&&a.parent.properties.prototype?a.parent.properties.prototype:b.NULL};this.setProperty(this.OBJECT,"getPrototypeOf",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a){return b.createPrimitive(!a.preventExtensions)};this.setProperty(this.OBJECT,"isExtensible",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a){a.isPrimitive||(a.preventExtensions=!0);return a};this.setProperty(this.OBJECT,"preventExtensions",this.createNativeFunction(c),
                +Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(){return b.createPrimitive(this.toString())};this.setNativeFunctionPrototype(this.OBJECT,"toString",c);c=function(){return b.createPrimitive(this.toString())};this.setNativeFunctionPrototype(this.OBJECT,"toLocaleString",c);c=function(){return b.createPrimitive(this.valueOf())};this.setNativeFunctionPrototype(this.OBJECT,"valueOf",c);c=function(a){if(this==b.NULL||this==b.UNDEFINED)b.throwException(b.TYPE_ERROR,"Cannot convert undefined or null to object");
                +else return a=(a||b.UNDEFINED).toString(),a in this.properties?b.TRUE:b.FALSE};this.setNativeFunctionPrototype(this.OBJECT,"hasOwnProperty",c);c=function(a){a=(a||b.UNDEFINED).toString();a=a in this.properties&&!this.notEnumerable[a];return b.createPrimitive(a)};this.setNativeFunctionPrototype(this.OBJECT,"propertyIsEnumerable",c);c=function(a){for(;;)if(a.parent&&a.parent.properties&&a.parent.properties.prototype){if(a=a.parent.properties.prototype,a==this)return b.createPrimitive(!0)}else return b.createPrimitive(!1)};
                +this.setNativeFunctionPrototype(this.OBJECT,"isPrototypeOf",c)};
                +Interpreter.prototype.initArray=function(a){var b=this,c=function(a,b){a=a?Math.floor(a.toNumber()):b;isNaN(a)&&(a=b);return a},d;d=function(a){var c=this.parent==b.ARRAY?this:b.createObject(b.ARRAY),d=arguments[0];if(d&&"number"==d.type)isNaN(b.arrayIndex(d))&&b.throwException(b.RANGE_ERROR,"Invalid array length"),c.length=d.data;else{for(d=0;d<arguments.length;d++)c.properties[d]=arguments[d];c.length=d}return c};this.ARRAY=this.createNativeFunction(d);this.setProperty(a,"Array",this.ARRAY);d=function(a){return b.createPrimitive(b.isa(a,
                +b.ARRAY))};this.setProperty(this.ARRAY,"isArray",this.createNativeFunction(d),Interpreter.NONENUMERABLE_DESCRIPTOR);d=function(){if(this.length){var a=this.properties[this.length-1];delete this.properties[this.length-1];this.length--}else a=b.UNDEFINED;return a};this.setNativeFunctionPrototype(this.ARRAY,"pop",d);d=function(a){for(var c=0;c<arguments.length;c++)this.properties[this.length]=arguments[c],this.length++;return b.createPrimitive(this.length)};this.setNativeFunctionPrototype(this.ARRAY,
                +"push",d);d=function(){if(this.length){for(var a=this.properties[0],c=1;c<this.length;c++)this.properties[c-1]=this.properties[c];this.length--;delete this.properties[this.length]}else a=b.UNDEFINED;return a};this.setNativeFunctionPrototype(this.ARRAY,"shift",d);d=function(a){for(var c=this.length-1;0<=c;c--)this.properties[c+arguments.length]=this.properties[c];this.length+=arguments.length;for(c=0;c<arguments.length;c++)this.properties[c]=arguments[c];return b.createPrimitive(this.length)};this.setNativeFunctionPrototype(this.ARRAY,
                +"unshift",d);d=function(){for(var a=0;a<this.length/2;a++){var b=this.properties[this.length-a-1];this.properties[this.length-a-1]=this.properties[a];this.properties[a]=b}return this};this.setNativeFunctionPrototype(this.ARRAY,"reverse",d);d=function(a,d,p){a=c(a,0);a=0>a?Math.max(this.length+a,0):Math.min(a,this.length);d=c(d,Infinity);d=Math.min(d,this.length-a);for(var g=b.createObject(b.ARRAY),h=a;h<a+d;h++)g.properties[g.length++]=this.properties[h],this.properties[h]=this.properties[h+d];for(h=
                +a+d;h<this.length-d;h++)this.properties[h]=this.properties[h+d];for(h=this.length-d;h<this.length;h++)delete this.properties[h];this.length-=d;for(h=this.length-1;h>=a;h--)this.properties[h+arguments.length-2]=this.properties[h];this.length+=arguments.length-2;for(h=2;h<arguments.length;h++)this.properties[a+h-2]=arguments[h];return g};this.setNativeFunctionPrototype(this.ARRAY,"splice",d);d=function(a,d){var g=b.createObject(b.ARRAY),h=c(a,0);0>h&&(h=this.length+h);h=Math.max(0,Math.min(h,this.length));
                +d=c(d,this.length);0>d&&(d=this.length+d);d=Math.max(0,Math.min(d,this.length));for(a=0;h<d;h++){var v=b.getProperty(this,h);b.setProperty(g,a++,v)}return g};this.setNativeFunctionPrototype(this.ARRAY,"slice",d);d=function(a){a=a&&void 0!==a.data?a.toString():void 0;for(var c=[],d=0;d<this.length;d++)c[d]=this.properties[d];return b.createPrimitive(c.join(a))};this.setNativeFunctionPrototype(this.ARRAY,"join",d);d=function(a){for(var c=b.createObject(b.ARRAY),d=0,h=0;h<this.length;h++){var v=b.getProperty(this,
                +h);b.setProperty(c,d++,v)}for(h=0;h<arguments.length;h++){var w=arguments[h];if(b.isa(w,b.ARRAY))for(var q=0;q<w.length;q++)v=b.getProperty(w,q),b.setProperty(c,d++,v);else b.setProperty(c,d++,w)}return c};this.setNativeFunctionPrototype(this.ARRAY,"concat",d);d=function(a,d){a=a||b.UNDEFINED;d=c(d,0);0>d&&(d=this.length+d);for(d=Math.max(0,d);d<this.length;d++){var h=b.getProperty(this,d);if(h.isPrimitive&&a.isPrimitive?h.data===a.data:h===a)return b.createPrimitive(d)}return b.createPrimitive(-1)};
                +this.setNativeFunctionPrototype(this.ARRAY,"indexOf",d);d=function(a,d){a=a||b.UNDEFINED;d=c(d,this.length);0>d&&(d=this.length+d);for(d=Math.min(d,this.length-1);0<=d;d--){var h=b.getProperty(this,d);if(h.isPrimitive&&a.isPrimitive?h.data===a.data:h===a)return b.createPrimitive(d)}return b.createPrimitive(-1)};this.setNativeFunctionPrototype(this.ARRAY,"lastIndexOf",d);this.polyfills_.push("Object.defineProperty(Array.prototype, 'every', {configurable: true, value:","function(callbackfn, thisArg) {",
                +"if (this == null || typeof callbackfn !== 'function') throw new TypeError;","var T, k;","var O = Object(this);","var len = O.length >>> 0;","if (arguments.length > 1) T = thisArg;","k = 0;","while (k < len) {","if (k in O && !callbackfn.call(T, O[k], k, O)) return false;","k++;","}","return true;","}","});","Object.defineProperty(Array.prototype, 'filter', {configurable: true, value:","function(fun/*, thisArg*/) {","if (this === void 0 || this === null || typeof fun !== 'function') throw new TypeError;",
                +"var t = Object(this);","var len = t.length >>> 0;","var res = [];","var thisArg = arguments.length >= 2 ? arguments[1] : void 0;","for (var i = 0; i < len; i++) {","if (i in t) {","var val = t[i];","if (fun.call(thisArg, val, i, t)) res.push(val);","}","}","return res;","}","});","Object.defineProperty(Array.prototype, 'forEach', {configurable: true, value:","function(callback, thisArg) {","if (this == null || typeof callback !== 'function') throw new TypeError;","var T, k;","var O = Object(this);",
                +"var len = O.length >>> 0;","if (arguments.length > 1) T = thisArg;","k = 0;","while (k < len) {","if (k in O) callback.call(T, O[k], k, O);","k++;","}","}","});","Object.defineProperty(Array.prototype, 'map', {configurable: true, value:","function(callback, thisArg) {","if (this == null || typeof callback !== 'function') new TypeError;","var T, A, k;","var O = Object(this);","var len = O.length >>> 0;","if (arguments.length > 1) T = thisArg;","A = new Array(len);","k = 0;","while (k < len) {","if (k in O) A[k] = callback.call(T, O[k], k, O);",
                +"k++;","}","return A;","}","});","Object.defineProperty(Array.prototype, 'reduce', {configurable: true, value:","function(callback /*, initialValue*/) {","if (this == null || typeof callback !== 'function') throw new TypeError;","var t = Object(this), len = t.length >>> 0, k = 0, value;","if (arguments.length == 2) {","value = arguments[1];","} else {","while (k < len && !(k in t)) k++;","if (k >= len) {","throw new TypeError('Reduce of empty array with no initial value');","}","value = t[k++];",
                +"}","for (; k < len; k++) {","if (k in t) value = callback(value, t[k], k, t);","}","return value;","}","});","Object.defineProperty(Array.prototype, 'reduceRight', {configurable: true, value:","function(callback /*, initialValue*/) {","if (null === this || 'undefined' === typeof this || 'function' !== typeof callback) throw new TypeError;","var t = Object(this), len = t.length >>> 0, k = len - 1, value;","if (arguments.length >= 2) {","value = arguments[1];","} else {","while (k >= 0 && !(k in t)) k--;",
                +"if (k < 0) {","throw new TypeError('Reduce of empty array with no initial value');","}","value = t[k--];","}","for (; k >= 0; k--) {","if (k in t) value = callback(value, t[k], k, t);","}","return value;","}","});","Object.defineProperty(Array.prototype, 'some', {configurable: true, value:","function(fun/*, thisArg*/) {","if (this == null || typeof fun !== 'function') throw new TypeError;","var t = Object(this);","var len = t.length >>> 0;","var thisArg = arguments.length >= 2 ? arguments[1] : void 0;",
                +"for (var i = 0; i < len; i++) {","if (i in t && fun.call(thisArg, t[i], i, t)) {","return true;","}","}","return false;","}","});","Object.defineProperty(Array.prototype, 'sort', {configurable: true, value:","function(opt_comp) {","for (var i = 0; i < this.length; i++) {","var changes = 0;","for (var j = 0; j < this.length - i - 1; j++) {","if (opt_comp ?opt_comp(this[j], this[j + 1]) > 0 : this[j] > this[j + 1]) {","var swap = this[j];","this[j] = this[j + 1];","this[j + 1] = swap;","changes++;",
                +"}","}","if (changes <= 1) break;","}","return this;","}","});","Object.defineProperty(Array.prototype, 'toLocaleString', {configurable: true, value:","function() {","var out = [];","for (var i = 0; i < this.length; i++) {","out[i] = (this[i] === null || this[i] === undefined) ? '' : this[i].toLocaleString();","}","return out.join(',');","}","});","")};
                +Interpreter.prototype.initNumber=function(a){var b=this,c;c=function(a){a=a?a.toNumber():0;if(this.parent!=b.NUMBER)return b.createPrimitive(a);this.data=a;return this};this.NUMBER=this.createNativeFunction(c);this.setProperty(a,"Number",this.NUMBER);a=["MAX_VALUE","MIN_VALUE","NaN","NEGATIVE_INFINITY","POSITIVE_INFINITY"];for(c=0;c<a.length;c++)this.setProperty(this.NUMBER,a[c],this.createPrimitive(Number[a[c]]));c=function(a){a=a||b.UNDEFINED;return b.createPrimitive(parseFloat(a.toString()))};
                +this.setProperty(this.NUMBER,"parseFloat",this.createNativeFunction(c));c=function(a,c){a=a||b.UNDEFINED;c=c||b.UNDEFINED;return b.createPrimitive(parseInt(a.toString(),c.toNumber()))};this.setProperty(this.NUMBER,"parseInt",this.createNativeFunction(c));c=function(a){a=a?a.toNumber():void 0;var c=this.toNumber();return b.createPrimitive(c.toExponential(a))};this.setNativeFunctionPrototype(this.NUMBER,"toExponential",c);c=function(a){a=a?a.toNumber():void 0;var c=this.toNumber();return b.createPrimitive(c.toFixed(a))};
                +this.setNativeFunctionPrototype(this.NUMBER,"toFixed",c);c=function(a){a=a?a.toNumber():void 0;var c=this.toNumber();return b.createPrimitive(c.toPrecision(a))};this.setNativeFunctionPrototype(this.NUMBER,"toPrecision",c);c=function(a){a=a?a.toNumber():10;var c=this.toNumber();return b.createPrimitive(c.toString(a))};this.setNativeFunctionPrototype(this.NUMBER,"toString",c);c=function(a,c){a=a?b.pseudoToNative(a):void 0;c=c?b.pseudoToNative(c):void 0;return b.createPrimitive(this.toNumber().toLocaleString(a,
                +c))};this.setNativeFunctionPrototype(this.NUMBER,"toLocaleString",c)};
                +Interpreter.prototype.initString=function(a){var b=this,c;c=function(a){a=a?a.toString():"";if(this.parent!=b.STRING)return b.createPrimitive(a);this.data=a;return this};this.STRING=this.createNativeFunction(c);this.setProperty(a,"String",this.STRING);c=function(a){for(var c=0;c<arguments.length;c++)arguments[c]=arguments[c].toNumber();return b.createPrimitive(String.fromCharCode.apply(String,arguments))};this.setProperty(this.STRING,"fromCharCode",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);
                +a=["toLowerCase","toUpperCase","toLocaleLowerCase","toLocaleUpperCase"];for(var d=0;d<a.length;d++)c=function(a){return function(){return b.createPrimitive(a.apply(this))}}(String.prototype[a[d]]),this.setNativeFunctionPrototype(this.STRING,a[d],c);c=function(){var a=this.toString();return b.createPrimitive(a.replace(/^\s+|\s+$/g,""))};this.setNativeFunctionPrototype(this.STRING,"trim",c);c=function(){var a=this.toString();return b.createPrimitive(a.replace(/^\s+/g,""))};this.setNativeFunctionPrototype(this.STRING,
                +"trimLeft",c);c=function(){var a=this.toString();return b.createPrimitive(a.replace(/\s+$/g,""))};this.setNativeFunctionPrototype(this.STRING,"trimRight",c);a=["charAt","charCodeAt","substring","slice","substr"];for(d=0;d<a.length;d++)c=function(a){return function(){for(var c=0;c<arguments.length;c++)arguments[c]=arguments[c].toNumber();return b.createPrimitive(a.apply(this,arguments))}}(String.prototype[a[d]]),this.setNativeFunctionPrototype(this.STRING,a[d],c);c=function(a,c){var d=this.toString();
                +a=(a||b.UNDEFINED).toString();c=c?c.toNumber():void 0;return b.createPrimitive(d.indexOf(a,c))};this.setNativeFunctionPrototype(this.STRING,"indexOf",c);c=function(a,c){var d=this.toString();a=(a||b.UNDEFINED).toString();c=c?c.toNumber():void 0;return b.createPrimitive(d.lastIndexOf(a,c))};this.setNativeFunctionPrototype(this.STRING,"lastIndexOf",c);c=function(a,c,d){a=(a||b.UNDEFINED).toString();c=c?b.pseudoToNative(c):void 0;d=d?b.pseudoToNative(d):void 0;return b.createPrimitive(this.toString().localeCompare(a,
                +c,d))};this.setNativeFunctionPrototype(this.STRING,"localeCompare",c);c=function(a,c){var d=this.toString();a=a?b.isa(a,b.REGEXP)?a.data:a.toString():void 0;c=c?c.toNumber():void 0;a=d.split(a,c);c=b.createObject(b.ARRAY);for(d=0;d<a.length;d++)b.setProperty(c,d,b.createPrimitive(a[d]));return c};this.setNativeFunctionPrototype(this.STRING,"split",c);c=function(a){for(var c=this.toString(),d=0;d<arguments.length;d++)c+=arguments[d].toString();return b.createPrimitive(c)};this.setNativeFunctionPrototype(this.STRING,
                +"concat",c);c=function(a){var c=this.toString();a=a?a.data:void 0;a=c.match(a);if(null===a)return b.NULL;for(var c=b.createObject(b.ARRAY),d=0;d<a.length;d++)b.setProperty(c,d,b.createPrimitive(a[d]));return c};this.setNativeFunctionPrototype(this.STRING,"match",c);c=function(a){var c=this.toString();a=a?a.data:void 0;return b.createPrimitive(c.search(a))};this.setNativeFunctionPrototype(this.STRING,"search",c);c=function(a,c){var d=this.toString();a=(a||b.UNDEFINED).valueOf();c=(c||b.UNDEFINED).toString();
                +return b.createPrimitive(d.replace(a,c))};this.setNativeFunctionPrototype(this.STRING,"replace",c)};Interpreter.prototype.initBoolean=function(a){var b=this,c;c=function(a){a=a?a.toBoolean():!1;if(this.parent!=b.BOOLEAN)return b.createPrimitive(a);this.data=a;return this};this.BOOLEAN=this.createNativeFunction(c);this.setProperty(a,"Boolean",this.BOOLEAN)};
                +Interpreter.prototype.initDate=function(a){var b=this,c;c=function(a,c,d,r,v,w,q){if(this.parent==b.DATE)var g=this;else return b.createPrimitive(Date());if(arguments.length)if(1!=arguments.length||"string"!=a.type&&!b.isa(a,b.STRING)){for(var h=[null],p=0;p<arguments.length;p++)h[p+1]=arguments[p]?arguments[p].toNumber():void 0;g.data=new (Function.prototype.bind.apply(Date,h))}else g.data=new Date(a.toString());else g.data=new Date;return g};this.DATE=this.createNativeFunction(c);this.setProperty(a,
                +"Date",this.DATE);c=function(){return b.createPrimitive((new Date).getTime())};this.setProperty(this.DATE,"now",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a){a=a?a.toString():void 0;return b.createPrimitive(Date.parse(a))};this.setProperty(this.DATE,"parse",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);c=function(a,c,d,r,v,w,q){for(var g=[],h=0;h<arguments.length;h++)g[h]=arguments[h]?arguments[h].toNumber():void 0;return b.createPrimitive(Date.UTC.apply(Date,
                +g))};this.setProperty(this.DATE,"UTC",this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR);a="getDate getDay getFullYear getHours getMilliseconds getMinutes getMonth getSeconds getTime getTimezoneOffset getUTCDate getUTCDay getUTCFullYear getUTCHours getUTCMilliseconds getUTCMinutes getUTCMonth getUTCSeconds getYear setDate setFullYear setHours setMilliseconds setMinutes setMonth setSeconds setTime setUTCDate setUTCFullYear setUTCHours setUTCMilliseconds setUTCMinutes setUTCMonth setUTCSeconds setYear toDateString toISOString toJSON toGMTString toLocaleDateString toLocaleString toLocaleTimeString toTimeString toUTCString".split(" ");
                +for(var d=0;d<a.length;d++)c=function(a){return function(c){for(var d=[],g=0;g<arguments.length;g++)d[g]=b.pseudoToNative(arguments[g]);return b.createPrimitive(this.data[a].apply(this.data,d))}}(a[d]),this.setNativeFunctionPrototype(this.DATE,a[d],c)};
                +Interpreter.prototype.initMath=function(a){var b=this,c=this.createObject(this.OBJECT);this.setProperty(a,"Math",c);var d="E LN2 LN10 LOG2E LOG10E PI SQRT1_2 SQRT2".split(" ");for(a=0;a<d.length;a++)this.setProperty(c,d[a],this.createPrimitive(Math[d[a]]),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);d="abs acos asin atan atan2 ceil cos exp floor log max min pow random round sin sqrt tan".split(" ");for(a=0;a<d.length;a++){var h=function(a){return function(){for(var c=0;c<arguments.length;c++)arguments[c]=
                +arguments[c].toNumber();return b.createPrimitive(a.apply(Math,arguments))}}(Math[d[a]]);this.setProperty(c,d[a],this.createNativeFunction(h),Interpreter.NONENUMERABLE_DESCRIPTOR)}};
                +Interpreter.prototype.initRegExp=function(a){var b=this,c;c=function(a,c){var d=this.parent==b.REGEXP?this:b.createObject(b.REGEXP);a=a?a.toString():"";c=c?c.toString():"";return b.populateRegExp_(d,new RegExp(a,c))};this.REGEXP=this.createNativeFunction(c);this.setProperty(a,"RegExp",this.REGEXP);this.setProperty(this.REGEXP.properties.prototype,"global",this.UNDEFINED,Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);this.setProperty(this.REGEXP.properties.prototype,"ignoreCase",this.UNDEFINED,Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);
                +this.setProperty(this.REGEXP.properties.prototype,"multiline",this.UNDEFINED,Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);this.setProperty(this.REGEXP.properties.prototype,"source",this.createPrimitive("(?:)"),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);c=function(a){a=a.toString();return b.createPrimitive(this.data.test(a))};this.setNativeFunctionPrototype(this.REGEXP,"test",c);c=function(a){a=a.toString();this.data.lastIndex=b.getProperty(this,"lastIndex").toNumber();a=this.data.exec(a);b.setProperty(this,
                +"lastIndex",b.createPrimitive(this.data.lastIndex));if(a){for(var c=b.createObject(b.ARRAY),d=0;d<a.length;d++)b.setProperty(c,d,b.createPrimitive(a[d]));b.setProperty(c,"index",b.createPrimitive(a.index));b.setProperty(c,"input",b.createPrimitive(a.input));return c}return b.NULL};this.setNativeFunctionPrototype(this.REGEXP,"exec",c)};
                +Interpreter.prototype.initJSON=function(a){var b=this,c=b.createObject(this.OBJECT);this.setProperty(a,"JSON",c);a=function(a){try{var c=JSON.parse(a.toString())}catch(g){b.throwException(b.SYNTAX_ERROR,g.message);return}return b.nativeToPseudo(c)};this.setProperty(c,"parse",this.createNativeFunction(a));a=function(a){a=b.pseudoToNative(a);return b.createPrimitive(JSON.stringify(a))};this.setProperty(c,"stringify",this.createNativeFunction(a))};
                +Interpreter.prototype.initError=function(a){var b=this;this.ERROR=this.createNativeFunction(function(a){var c=this.parent==b.ERROR?this:b.createObject(b.ERROR);a&&b.setProperty(c,"message",b.createPrimitive(String(a)),Interpreter.NONENUMERABLE_DESCRIPTOR);return c});this.setProperty(a,"Error",this.ERROR);this.setProperty(this.ERROR.properties.prototype,"message",this.STRING_EMPTY,Interpreter.NONENUMERABLE_DESCRIPTOR);this.setProperty(this.ERROR.properties.prototype,"name",this.createPrimitive("Error"),
                +Interpreter.NONENUMERABLE_DESCRIPTOR);var c=function(c){var d=b.createNativeFunction(function(a){var c=b.isa(this.parent,b.ERROR)?this:b.createObject(d);a&&b.setProperty(c,"message",b.createPrimitive(String(a)),Interpreter.NONENUMERABLE_DESCRIPTOR);return c});b.setProperty(d,"prototype",b.createObject(b.ERROR));b.setProperty(d.properties.prototype,"name",b.createPrimitive(c),Interpreter.NONENUMERABLE_DESCRIPTOR);b.setProperty(a,c,d);return d};c("EvalError");this.RANGE_ERROR=c("RangeError");this.REFERENCE_ERROR=
                +c("ReferenceError");this.SYNTAX_ERROR=c("SyntaxError");this.TYPE_ERROR=c("TypeError");this.URI_ERROR=c("URIError")};Interpreter.prototype.isa=function(a,b){if(!a||!b)return!1;for(;a.parent!=b;){if(!a.parent||!a.parent.properties.prototype)return!1;a=a.parent.properties.prototype}return!0};
                +Interpreter.prototype.comp=function(a,b){if(a.isPrimitive&&isNaN(a.data)||b.isPrimitive&&isNaN(b.data))return NaN;if(a===b)return 0;a=a.isPrimitive?a.data:a.toString();b=b.isPrimitive?b.data:b.toString();return a<b?-1:a>b?1:0};Interpreter.prototype.arrayIndex=function(a){a=Number(a);return!isFinite(a)||a!=Math.floor(a)||0>a?NaN:a};
                +Interpreter.Primitive=function(a,b){var c=typeof a;this.data=a;this.type=c;"number"==c?this.parent=b.NUMBER:"string"==c?this.parent=b.STRING:"boolean"==c&&(this.parent=b.BOOLEAN)};Interpreter.Primitive.prototype.data=void 0;Interpreter.Primitive.prototype.type="undefined";Interpreter.Primitive.prototype.parent=null;Interpreter.Primitive.prototype.isPrimitive=!0;Interpreter.Primitive.prototype.toBoolean=function(){return!!this.data};Interpreter.Primitive.prototype.toNumber=function(){return Number(this.data)};
                +Interpreter.Primitive.prototype.toString=function(){return String(this.data)};Interpreter.Primitive.prototype.valueOf=function(){return this.data};Interpreter.prototype.createPrimitive=function(a){return void 0===a?this.UNDEFINED:null===a?this.NULL:!0===a?this.TRUE:!1===a?this.FALSE:0===a?this.NUMBER_ZERO:1===a?this.NUMBER_ONE:""===a?this.STRING_EMPTY:a instanceof RegExp?this.populateRegExp_(this.createObject(this.REGEXP),a):new Interpreter.Primitive(a,this)};
                +Interpreter.Object=function(a){this.notConfigurable=Object.create(null);this.notEnumerable=Object.create(null);this.notWritable=Object.create(null);this.getter=Object.create(null);this.setter=Object.create(null);this.properties=Object.create(null);this.parent=a};Interpreter.Object.prototype.type="object";Interpreter.Object.prototype.parent=null;Interpreter.Object.prototype.isPrimitive=!1;Interpreter.Object.prototype.data=void 0;Interpreter.Object.prototype.toBoolean=function(){return!0};
                +Interpreter.Object.prototype.toNumber=function(){return Number(void 0===this.data?this.toString():this.data)};Interpreter.Object.prototype.toString=function(){return void 0===this.data?"["+this.type+"]":String(this.data)};Interpreter.Object.prototype.valueOf=function(){return void 0===this.data?this:this.data};
                +Interpreter.prototype.createObject=function(a){a=new Interpreter.Object(a);this.isa(a,this.FUNCTION)&&(a.type="function",this.setProperty(a,"prototype",this.createObject(this.OBJECT||null)));this.isa(a,this.ARRAY)&&(a.length=0,a.toString=function(){for(var a=[],c=0;c<this.length;c++){var d=this.properties[c];a[c]=!d||d.isPrimitive&&(null===d.data||void 0===d.data)?"":d.toString()}return a.join(",")});return a};
                +Interpreter.prototype.populateRegExp_=function(a,b){a.data=b;this.setProperty(a,"lastIndex",this.createPrimitive(b.lastIndex),Interpreter.NONENUMERABLE_DESCRIPTOR);this.setProperty(a,"source",this.createPrimitive(b.source),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);this.setProperty(a,"global",this.createPrimitive(b.global),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);this.setProperty(a,"ignoreCase",this.createPrimitive(b.ignoreCase),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);this.setProperty(a,
                +"multiline",this.createPrimitive(b.multiline),Interpreter.READONLY_NONENUMERABLE_DESCRIPTOR);a.toString=function(){return String(this.data)};a.valueOf=function(){return this.data};return a};Interpreter.prototype.createFunction=function(a,b){var c=this.createObject(this.FUNCTION);c.parentScope=b||this.getScope();c.node=a;this.setProperty(c,"length",this.createPrimitive(c.node.params.length),Interpreter.READONLY_DESCRIPTOR);return c};
                +Interpreter.prototype.createNativeFunction=function(a){var b=this.createObject(this.FUNCTION);b.nativeFunc=a;this.setProperty(b,"length",this.createPrimitive(a.length),Interpreter.READONLY_DESCRIPTOR);return b};Interpreter.prototype.createAsyncFunction=function(a){var b=this.createObject(this.FUNCTION);b.asyncFunc=a;this.setProperty(b,"length",this.createPrimitive(a.length),Interpreter.READONLY_DESCRIPTOR);return b};
                +Interpreter.prototype.nativeToPseudo=function(a){if("boolean"==typeof a||"number"==typeof a||"string"==typeof a||null===a||void 0===a||a instanceof RegExp)return this.createPrimitive(a);var b;if(a instanceof Array){b=this.createObject(this.ARRAY);for(var c=0;c<a.length;c++)this.setProperty(b,c,this.nativeToPseudo(a[c]))}else for(c in b=this.createObject(this.OBJECT),a)this.setProperty(b,c,this.nativeToPseudo(a[c]));return b};
                +Interpreter.prototype.pseudoToNative=function(a){if(a.isPrimitive||this.isa(a,this.NUMBER)||this.isa(a,this.STRING)||this.isa(a,this.BOOLEAN))return a.data;var b;if(this.isa(a,this.ARRAY)){b=[];for(var c=0;c<a.length;c++)b[c]=this.pseudoToNative(a.properties[c])}else for(c in b={},a.properties)b[c]=this.pseudoToNative(a.properties[c]);return b};
                +Interpreter.prototype.getProperty=function(a,b){b=b.toString();if(a==this.UNDEFINED||a==this.NULL)return this.throwException(this.TYPE_ERROR,"Cannot read property '"+b+"' of "+a),null;if(this.isa(a,this.STRING)){if("length"==b)return this.createPrimitive(a.data.length);var c=this.arrayIndex(b);if(!isNaN(c)&&c<a.data.length)return this.createPrimitive(a.data[c])}else if(this.isa(a,this.ARRAY)&&"length"==b)return this.createPrimitive(a.length);for(;;){if(a.properties&&b in a.properties)return(c=a.getter[b])?
                +(c.isGetter=!0,c):a.properties[b];if(a.parent&&a.parent.properties&&a.parent.properties.prototype)a=a.parent.properties.prototype;else break}return this.UNDEFINED};
                +Interpreter.prototype.hasProperty=function(a,b){b=b.toString();if(a.isPrimitive)throw TypeError("Primitive data type has no properties");if("length"==b&&(this.isa(a,this.STRING)||this.isa(a,this.ARRAY)))return!0;if(this.isa(a,this.STRING)){var c=this.arrayIndex(b);if(!isNaN(c)&&c<a.data.length)return!0}for(;;){if(a.properties&&b in a.properties)return!0;if(a.parent&&a.parent.properties&&a.parent.properties.prototype)a=a.parent.properties.prototype;else break}return!1};
                +Interpreter.prototype.setProperty=function(a,b,c,d){b=b.toString();d&&a.notConfigurable[b]&&this.throwException(this.TYPE_ERROR,"Cannot redefine property: "+b);if("object"!=typeof c)throw Error("Failure to wrap a value: "+c);a!=this.UNDEFINED&&a!=this.NULL||this.throwException(this.TYPE_ERROR,"Cannot set property '"+b+"' of "+a);d&&(d.get||d.set)&&(c||void 0!==d.writable)&&this.throwException(this.TYPE_ERROR,"Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");
                +if(!a.isPrimitive){if(this.isa(a,this.STRING)){var h=this.arrayIndex(b);if("length"==b||!isNaN(h)&&h<a.data.length)return}if(this.isa(a,this.ARRAY)){var g;if("length"==b){b=this.arrayIndex(c.toNumber());isNaN(b)&&this.throwException(this.RANGE_ERROR,"Invalid array length");if(b<a.length)for(g in a.properties)g=this.arrayIndex(g),!isNaN(g)&&b<=g&&delete a.properties[g];a.length=b;return}isNaN(g=this.arrayIndex(b))||(a.length=Math.max(a.length,g+1))}if(!a.properties[b]&&a.preventExtensions)a=this.getScope(),
                +a.strict&&this.throwException(this.TYPE_ERROR,"Can't add property "+b+", object is not extensible");else if(d)a.properties[b]=c,d.configurable||(a.notConfigurable[b]=!0),(c=d.get)?a.getter[b]=c:delete a.getter[b],(g=d.set)?a.setter[b]=g:delete a.setter[b],(h=d.enumerable||!1)?delete a.notEnumerable[b]:a.notEnumerable[b]=!0,c||g?(delete a.notWritable[b],a.properties[b]=this.UNDEFINED):(d=d.writable||!1)?delete a.notWritable[b]:a.notWritable[b]=!0;else{for(d=a;;){if(d.setter&&d.setter[b])return d.setter[b];
                +if(d.parent&&d.parent.properties&&d.parent.properties.prototype)d=d.parent.properties.prototype;else break}a.notWritable[b]||(a.properties[b]=c)}}};Interpreter.prototype.setNativeFunctionPrototype=function(a,b,c){this.setProperty(a.properties.prototype,b,this.createNativeFunction(c),Interpreter.NONENUMERABLE_DESCRIPTOR)};Interpreter.prototype.deleteProperty=function(a,b){b=b.toString();return a.isPrimitive||a.notWritable[b]||"length"==b&&this.isa(a,this.ARRAY)?!1:delete a.properties[b]};
                +Interpreter.prototype.getScope=function(){for(var a=0;a<this.stateStack.length;a++)if(this.stateStack[a].scope)return this.stateStack[a].scope;throw Error("No scope found.");};Interpreter.prototype.createScope=function(a,b){var c=this.createObject(null);(c.parentScope=b)||this.initGlobalScope(c);this.populateScope_(a,c);c.strict=!1;b&&b.strict?c.strict=!0:(a=a.body&&a.body[0])&&a.expression&&"Literal"==a.expression.type&&"use strict"==a.expression.value&&(c.strict=!0);return c};
                +Interpreter.prototype.createSpecialScope=function(a,b){if(!a)throw Error("parentScope required");b=b||this.createObject(null);b.parentScope=a;b.strict=a.strict;return b};Interpreter.prototype.getValueFromScope=function(a){var b=this.getScope();for(a=a.toString();b;){if(a in b.properties)return b.properties[a];b=b.parentScope}this.throwException(this.REFERENCE_ERROR,a+" is not defined");return null};
                +Interpreter.prototype.setValueToScope=function(a,b){var c=this.getScope(),d=c.strict;for(a=a.toString();c;){if(a in c.properties||!d&&!c.parentScope){c.notWritable[a]||(c.properties[a]=b);return}c=c.parentScope}this.throwException(this.REFERENCE_ERROR,a+" is not defined")};
                +Interpreter.prototype.populateScope_=function(a,b){if("VariableDeclaration"==a.type)for(var c=0;c<a.declarations.length;c++)this.setProperty(b,a.declarations[c].id.name,this.UNDEFINED);else{if("FunctionDeclaration"==a.type){this.setProperty(b,a.id.name,this.createFunction(a,b));return}if("FunctionExpression"==a.type)return}var d=a.constructor,h;for(h in a){var g=a[h];if(g&&"object"==typeof g)if(g instanceof Array)for(c=0;c<g.length;c++)g[c]&&g[c].constructor==d&&this.populateScope_(g[c],b);else g.constructor==
                +d&&this.populateScope_(g,b)}};Interpreter.prototype.stripLocations_=function(a){delete a.start;delete a.end;for(var b in a)if(a.hasOwnProperty(b)){var c=a[b];c&&"object"==typeof c&&this.stripLocations_(c)}};Interpreter.prototype.getValue=function(a){if(a instanceof Array){var b=a[0];a=a[1];return this.getProperty(b,a)}return this.getValueFromScope(a)};Interpreter.prototype.setValue=function(a,b){if(a instanceof Array){var c=a[0];a=a[1];return this.setProperty(c,a,b)}this.setValueToScope(a,b)};
                +Interpreter.prototype.throwException=function(a,b){if(this.stateStack[0].interpreter)try{this.stateStack[0].interpreter.throwException(a,b);return}catch(c){}void 0!==b&&(a=this.createObject(a),this.setProperty(a,"message",this.createPrimitive(b),Interpreter.NONENUMERABLE_DESCRIPTOR));this.executeException(a)};
                +Interpreter.prototype.executeException=function(a){do{this.stateStack.shift();var b=this.stateStack[0];if("TryStatement"==b.node.type){b.throwValue=a;return}}while(b&&"Program"!=b.node.type);if(this.isa(a,this.ERROR)){var b={EvalError:EvalError,RangeError:RangeError,ReferenceError:ReferenceError,SyntaxError:SyntaxError,TypeError:TypeError,URIError:URIError},c=this.getProperty(a,"name").toString();a=this.getProperty(a,"message").valueOf();b=b[c]||Error;a=b(a)}else a=a.toString();throw a;};
                +Interpreter.prototype.stepArrayExpression=function(){var a=this.stateStack[0],b=a.node,c=a.n||0;a.array?a.value&&this.setProperty(a.array,c-1,a.value):a.array=this.createObject(this.ARRAY);c<b.elements.length?(a.n=c+1,b.elements[c]?this.stateStack.unshift({node:b.elements[c]}):a.value=void 0):(a.array.length=a.n||0,this.stateStack.shift(),this.stateStack[0].value=a.array)};
                +Interpreter.prototype.stepAssignmentExpression=function(){var a=this.stateStack[0],b=a.node;if(a.doneLeft)if(a.doneRight)if(a.doneSetter_)this.stateStack.shift(),this.stateStack[0].value=a.doneSetter_;else{var c=a.value;if("="==b.operator)b=c;else{var d=a.leftValue.toNumber(),h=c.toNumber();if("+="==b.operator)"string"==a.leftValue.type||"string"==c.type?(b=a.leftValue.toString(),c=c.toString()):(b=d,c=h),b+=c;else if("-="==b.operator)b=d-h;else if("*="==b.operator)b=d*h;else if("/="==b.operator)b=
                +d/h;else if("%="==b.operator)b=d%h;else if("<<="==b.operator)b=d<<h;else if(">>="==b.operator)b=d>>h;else if(">>>="==b.operator)b=d>>>h;else if("&="==b.operator)b=d&h;else if("^="==b.operator)b=d^h;else if("|="==b.operator)b=d|h;else throw SyntaxError("Unknown assignment expression: "+b.operator);b=this.createPrimitive(b)}(c=this.setValue(a.leftSide,b))?(a.doneSetter_=b,this.stateStack.unshift({node:{type:"CallExpression"},doneCallee_:!0,funcThis_:a.leftSide[0],func_:c,doneArgs_:!0,arguments:[b]})):
                +(this.stateStack.shift(),this.stateStack[0].value=b)}else{a.leftSide||(a.leftSide=a.value);a.doneGetter_&&(a.leftValue=a.value);if(!a.doneGetter_&&"="!=b.operator&&(a.leftValue=this.getValue(a.leftSide),a.leftValue.isGetter)){a.leftValue.isGetter=!1;a.doneGetter_=!0;this.stateStack.unshift({node:{type:"CallExpression"},doneCallee_:!0,funcThis_:a.leftSide[0],func_:a.leftValue,doneArgs_:!0,arguments:[]});return}a.doneRight=!0;this.stateStack.unshift({node:b.right})}else a.doneLeft=!0,this.stateStack.unshift({node:b.left,
                +components:!0})};
                +Interpreter.prototype.stepBinaryExpression=function(){var a=this.stateStack[0],b=a.node;if(a.doneLeft)if(a.doneRight){this.stateStack.shift();var c=a.leftValue,a=a.value,d=this.comp(c,a);if("=="==b.operator||"!="==b.operator)c=c.isPrimitive&&a.isPrimitive?c.data==a.data:0===d,"!="==b.operator&&(c=!c);else if("==="==b.operator||"!=="==b.operator)c=c.isPrimitive&&a.isPrimitive?c.data===a.data:c===a,"!=="==b.operator&&(c=!c);else if(">"==b.operator)c=1==d;else if(">="==b.operator)c=1==d||0===d;else if("<"==
                +b.operator)c=-1==d;else if("<="==b.operator)c=-1==d||0===d;else if("+"==b.operator)c=c.isPrimitive?c.data:c.toString(),a=a.isPrimitive?a.data:a.toString(),c+=a;else if("in"==b.operator)c=this.hasProperty(a,c);else if("instanceof"==b.operator)this.isa(a,this.FUNCTION)||this.throwException(this.TYPE_ERROR,"Expecting a function in instanceof check"),c=this.isa(c,a);else if(c=c.toNumber(),a=a.toNumber(),"-"==b.operator)c-=a;else if("*"==b.operator)c*=a;else if("/"==b.operator)c/=a;else if("%"==b.operator)c%=
                +a;else if("&"==b.operator)c&=a;else if("|"==b.operator)c|=a;else if("^"==b.operator)c^=a;else if("<<"==b.operator)c<<=a;else if(">>"==b.operator)c>>=a;else if(">>>"==b.operator)c>>>=a;else throw SyntaxError("Unknown binary operator: "+b.operator);this.stateStack[0].value=this.createPrimitive(c)}else a.doneRight=!0,a.leftValue=a.value,this.stateStack.unshift({node:b.right});else a.doneLeft=!0,this.stateStack.unshift({node:b.left})};
                +Interpreter.prototype.stepBlockStatement=function(){var a=this.stateStack[0],b=a.node,c=a.n_||0;b.body[c]?(a.done=!1,a.n_=c+1,this.stateStack.unshift({node:b.body[c]})):(a.done=!0,"Program"!=a.node.type&&this.stateStack.shift())};
                +Interpreter.prototype.stepBreakStatement=function(){var a=this.stateStack.shift(),a=a.node,b=null;a.label&&(b=a.label.name);for(a=this.stateStack.shift();a&&"CallExpression"!=a.node.type&&"NewExpression"!=a.node.type;){if(b?b==a.label:a.isLoop||a.isSwitch)return;a=this.stateStack.shift()}throw SyntaxError("Illegal break statement");};
                +Interpreter.prototype.stepCallExpression=function(){var a=this.stateStack[0],b=a.node;if(a.doneCallee_){if(!a.func_){if("function"==a.value.type)a.func_=a.value;else{a.value.length&&(a.member_=a.value[0]);a.func_=this.getValue(a.value);if(!a.func_)return;if("function"!=a.func_.type){this.throwException(this.TYPE_ERROR,(a.value&&a.value.type)+" is not a function");return}}"NewExpression"==a.node.type?(a.funcThis_=this.createObject(a.func_),a.isConstructor_=!0):a.funcThis_=a.func_.boundThis_?a.func_.boundThis_:
                +a.value.length?a.value[0]:this.stateStack[this.stateStack.length-1].thisExpression;a.arguments=a.func_.boundArgs_?a.func_.boundArgs_.concat():[];a.n_=0}if(!a.doneArgs_){0!=a.n_&&a.arguments.push(a.value);if(b.arguments[a.n_]){this.stateStack.unshift({node:b.arguments[a.n_]});a.n_++;return}a.doneArgs_=!0}if(a.doneExec_)this.stateStack.shift(),this.stateStack[0].value=a.isConstructor_&&"object"!==a.value.type?a.funcThis_:a.value;else if(a.doneExec_=!0,a.func_.node){for(var b=this.createScope(a.func_.node.body,
                +a.func_.parentScope),c=0;c<a.func_.node.params.length;c++){var d=this.createPrimitive(a.func_.node.params[c].name),h=a.arguments.length>c?a.arguments[c]:this.UNDEFINED;this.setProperty(b,d,h)}d=this.createObject(this.ARRAY);for(c=0;c<a.arguments.length;c++)this.setProperty(d,this.createPrimitive(c),a.arguments[c]);this.setProperty(b,"arguments",d);b={node:a.func_.node.body,scope:b,thisExpression:a.funcThis_};this.stateStack.unshift(b);a.value=this.UNDEFINED}else if(a.func_.nativeFunc)a.value=a.func_.nativeFunc.apply(a.funcThis_,
                +a.arguments);else if(a.func_.asyncFunc){var g=this,b=function(b){a.value=b||g.UNDEFINED;g.paused_=!1},b=a.arguments.concat(b);a.func_.asyncFunc.apply(a.funcThis_,b);this.paused_=!0}else if(a.func_.eval)(b=a.arguments[0])?b.isPrimitive?(b=new Interpreter(b.toString()),b.stateStack[0].scope=this.getScope(),a={node:{type:"Eval_"},interpreter:b},this.stateStack.unshift(a)):a.value=b:a.value=this.UNDEFINED;else throw TypeError("function not a function (huh?)");}else a.doneCallee_=!0,this.stateStack.unshift({node:b.callee,
                +components:!0})};Interpreter.prototype.stepCatchClause=function(){var a=this.stateStack[0],b=a.node;if(a.doneBody)this.stateStack.shift();else{a.doneBody=!0;var c;if(b.param){c=this.createSpecialScope(this.getScope());var d=this.createPrimitive(b.param.name);this.setProperty(c,d,a.throwValue)}this.stateStack.unshift({node:b.body,scope:c})}};
                +Interpreter.prototype.stepConditionalExpression=function(){var a=this.stateStack[0];a.done?(this.stateStack.shift(),"ConditionalExpression"==a.node.type&&(this.stateStack[0].value=a.value)):a.test?(a.done=!0,a.value.toBoolean()&&a.node.consequent?this.stateStack.unshift({node:a.node.consequent}):!a.value.toBoolean()&&a.node.alternate&&this.stateStack.unshift({node:a.node.alternate})):(a.test=!0,this.stateStack.unshift({node:a.node.test}))};
                +Interpreter.prototype.stepContinueStatement=function(){var a=this.stateStack[0].node,b=null;a.label&&(b=a.label.name);for(a=this.stateStack[0];a&&"CallExpression"!=a.node.type&&"NewExpression"!=a.node.type;){if(a.isLoop&&(!b||b==a.label))return;this.stateStack.shift();a=this.stateStack[0]}throw SyntaxError("Illegal continue statement");};
                +Interpreter.prototype.stepDoWhileStatement=function(){var a=this.stateStack[0];a.isLoop=!0;"DoWhileStatement"==a.node.type&&void 0===a.test&&(a.value=this.TRUE,a.test=!0);a.test?(a.test=!1,a.value.toBoolean()?a.node.body&&this.stateStack.unshift({node:a.node.body}):this.stateStack.shift()):(a.test=!0,this.stateStack.unshift({node:a.node.test}))};Interpreter.prototype.stepEmptyStatement=function(){this.stateStack.shift()};
                +Interpreter.prototype.stepEval_=function(){var a=this.stateStack[0];a.interpreter.step()||(this.stateStack.shift(),this.stateStack[0].value=a.interpreter.value||this.UNDEFINED)};Interpreter.prototype.stepExpressionStatement=function(){var a=this.stateStack[0];a.done?(this.stateStack.shift(),this.value=a.value):(a.done=!0,this.stateStack.unshift({node:a.node.expression}))};
                +Interpreter.prototype.stepForInStatement=function(){var a=this.stateStack[0];a.isLoop=!0;var b=a.node;if(a.doneVariable_)if(a.doneObject_){"undefined"==typeof a.iterator&&(a.object=a.value,a.iterator=0);var c=null;a:do{var d=a.iterator,h;for(h in a.object.properties)if(!a.object.notEnumerable[h]){if(0==d){c=h;break a}d--}a.object=a.object.parent&&a.object.parent.properties.prototype;a.iterator=0}while(a.object);a.iterator++;null===c?this.stateStack.shift():(this.setValueToScope(a.variable,this.createPrimitive(c)),
                +b.body&&this.stateStack.unshift({node:b.body}))}else a.doneObject_=!0,a.variable=a.value,this.stateStack.unshift({node:b.right});else a.doneVariable_=!0,a=b.left,"VariableDeclaration"==a.type&&(a=a.declarations[0].id),this.stateStack.unshift({node:a,components:!0})};
                +Interpreter.prototype.stepForStatement=function(){var a=this.stateStack[0];a.isLoop=!0;var b=a.node,c=a.mode||0;0==c?(a.mode=1,b.init&&this.stateStack.unshift({node:b.init})):1==c?(a.mode=2,b.test&&this.stateStack.unshift({node:b.test})):2==c?(a.mode=3,b.test&&a.value&&!a.value.toBoolean()?this.stateStack.shift():b.body&&this.stateStack.unshift({node:b.body})):3==c&&(a.mode=1,b.update&&this.stateStack.unshift({node:b.update}))};Interpreter.prototype.stepFunctionDeclaration=function(){this.stateStack.shift()};
                +Interpreter.prototype.stepFunctionExpression=function(){var a=this.stateStack.shift();this.stateStack[0].value=this.createFunction(a.node)};Interpreter.prototype.stepIdentifier=function(){var a=this.stateStack.shift(),b=this.createPrimitive(a.node.name);this.stateStack[0].value=a.components?b:this.getValueFromScope(b)};Interpreter.prototype.stepIfStatement=Interpreter.prototype.stepConditionalExpression;
                +Interpreter.prototype.stepLabeledStatement=function(){var a=this.stateStack.shift();this.stateStack.unshift({node:a.node.body,label:a.node.label.name})};Interpreter.prototype.stepLiteral=function(){var a=this.stateStack.shift();this.stateStack[0].value=this.createPrimitive(a.node.value)};
                +Interpreter.prototype.stepLogicalExpression=function(){var a=this.stateStack[0],b=a.node;if("&&"!=b.operator&&"||"!=b.operator)throw SyntaxError("Unknown logical operator: "+b.operator);a.doneLeft_?a.doneRight_?(this.stateStack.shift(),this.stateStack[0].value=a.value):"&&"==b.operator&&!a.value.toBoolean()||"||"==b.operator&&a.value.toBoolean()?(this.stateStack.shift(),this.stateStack[0].value=a.value):(a.doneRight_=!0,this.stateStack.unshift({node:b.right})):(a.doneLeft_=!0,this.stateStack.unshift({node:b.left}))};
                +Interpreter.prototype.stepMemberExpression=function(){var a=this.stateStack[0],b=a.node;a.doneObject_?a.doneProperty_?(this.stateStack.shift(),a.components?this.stateStack[0].value=[a.object,a.value]:(b=this.getProperty(a.object,a.value))?b.isGetter?(b.isGetter=!1,this.stateStack.unshift({node:{type:"CallExpression"},doneCallee_:!0,funcThis_:a.object,func_:b,doneArgs_:!0,arguments:[]})):this.stateStack[0].value=b:(this.stateStack.unshift({}),this.throwException(this.TYPE_ERROR,"Cannot read property '"+
                +a.value+"' of "+a.object.toString()))):(a.doneProperty_=!0,a.object=a.value,this.stateStack.unshift({node:b.property,components:!b.computed})):(a.doneObject_=!0,this.stateStack.unshift({node:b.object}))};Interpreter.prototype.stepNewExpression=Interpreter.prototype.stepCallExpression;
                +Interpreter.prototype.stepObjectExpression=function(){var a=this.stateStack[0],b=a.node,c=a.valueToggle,d=a.n||0;a.object?c?a.key=a.value:(a.properties[a.key]||(a.properties[a.key]={}),a.properties[a.key][a.kind]=a.value):(a.object=this.createObject(this.OBJECT),a.properties=Object.create(null));if(b.properties[d])c?(a.n=d+1,this.stateStack.unshift({node:b.properties[d].value})):(a.kind=b.properties[d].kind,this.stateStack.unshift({node:b.properties[d].key,components:!0})),a.valueToggle=!c;else{for(var h in a.properties)b=
                +a.properties[h],"get"in b||"set"in b?(b={configurable:!0,enumerable:!0,get:b.get,set:b.set},this.setProperty(a.object,h,null,b)):this.setProperty(a.object,h,b.init);this.stateStack.shift();this.stateStack[0].value=a.object}};Interpreter.prototype.stepProgram=Interpreter.prototype.stepBlockStatement;
                +Interpreter.prototype.stepReturnStatement=function(){var a=this.stateStack[0],b=a.node;if(b.argument&&!a.done)a.done=!0,this.stateStack.unshift({node:b.argument});else{b=a.value||this.UNDEFINED;do{this.stateStack.shift();if(0==this.stateStack.length)throw SyntaxError("Illegal return statement");a=this.stateStack[0]}while("CallExpression"!=a.node.type&&"NewExpression"!=a.node.type);a.value=b}};
                +Interpreter.prototype.stepSequenceExpression=function(){var a=this.stateStack[0],b=a.node,c=a.n||0;b.expressions[c]?(a.n=c+1,this.stateStack.unshift({node:b.expressions[c]})):(this.stateStack.shift(),this.stateStack[0].value=a.value)};
                +Interpreter.prototype.stepSwitchStatement=function(){var a=this.stateStack[0];a.checked=a.checked||[];a.isSwitch=!0;if(a.test){a.switchValue||(a.switchValue=a.value);var b=a.index||0,c=a.node.cases[b];if(c)if(a.done||a.checked[b]||!c.test){if(a.done||!c.test||0==this.comp(a.value,a.switchValue)){a.done=!0;var d=a.n||0;if(c.consequent[d]){this.stateStack.unshift({node:c.consequent[d]});a.n=d+1;return}}a.n=0;a.index=b+1}else a.checked[b]=!0,this.stateStack.unshift({node:c.test});else this.stateStack.shift()}else a.test=
                +!0,this.stateStack.unshift({node:a.node.discriminant})};Interpreter.prototype.stepThisExpression=function(){this.stateStack.shift();for(var a=0;a<this.stateStack.length;a++)if(this.stateStack[a].thisExpression){this.stateStack[0].value=this.stateStack[a].thisExpression;return}throw Error("No this expression found.");};Interpreter.prototype.stepThrowStatement=function(){var a=this.stateStack[0],b=a.node;a.argument?this.throwException(a.value):(a.argument=!0,this.stateStack.unshift({node:b.argument}))};
                +Interpreter.prototype.stepTryStatement=function(){var a=this.stateStack[0],b=a.node;a.doneBlock?a.throwValue&&!a.doneHandler&&b.handler?(a.doneHandler=!0,this.stateStack.unshift({node:b.handler,throwValue:a.throwValue}),a.throwValue=null):!a.doneFinalizer&&b.finalizer?(a.doneFinalizer=!0,this.stateStack.unshift({node:b.finalizer})):a.throwValue?this.executeException(a.throwValue):this.stateStack.shift():(a.doneBlock=!0,this.stateStack.unshift({node:b.block}))};
                +Interpreter.prototype.stepUnaryExpression=function(){var a=this.stateStack[0],b=a.node;if(a.done){this.stateStack.shift();if("-"==b.operator)b=-a.value.toNumber();else if("+"==b.operator)b=a.value.toNumber();else if("!"==b.operator)b=!a.value.toBoolean();else if("~"==b.operator)b=~a.value.toNumber();else if("delete"==b.operator||"typeof"==b.operator){if(a.value.length)var c=a.value[0],a=a.value[1];else c=this.getScope(),a=a.value;b="delete"==b.operator?this.deleteProperty(c,a):this.getProperty(c,
                +a).type}else if("void"==b.operator)b=void 0;else throw SyntaxError("Unknown unary operator: "+b.operator);this.stateStack[0].value=this.createPrimitive(b)}else{a.done=!0;c={node:b.argument};if("delete"==b.operator||"typeof"==b.operator)c.components=!0;this.stateStack.unshift(c)}};
                +Interpreter.prototype.stepUpdateExpression=function(){var a=this.stateStack[0],b=a.node;if(a.doneLeft){a.leftSide||(a.leftSide=a.value);a.doneGetter_&&(a.leftValue=a.value);if(!a.doneGetter_){a.leftValue=this.getValue(a.leftSide);if(!a.leftValue)return;if(a.leftValue.isGetter){a.leftValue.isGetter=!1;a.doneGetter_=!0;this.stateStack.unshift({node:{type:"CallExpression"},doneCallee_:!0,funcThis_:a.leftSide[0],func_:a.leftValue,doneArgs_:!0,arguments:[]});return}}if(a.doneSetter_)this.stateStack.shift(),
                +this.stateStack[0].value=a.doneSetter_;else{var c=a.leftValue.toNumber(),d;if("++"==b.operator)d=this.createPrimitive(c+1);else if("--"==b.operator)d=this.createPrimitive(c-1);else throw SyntaxError("Unknown update expression: "+b.operator);b=b.prefix?d:this.createPrimitive(c);(c=this.setValue(a.leftSide,d))?(a.doneSetter_=b,this.stateStack.unshift({node:{type:"CallExpression"},doneCallee_:!0,funcThis_:a.leftSide[0],func_:c,doneArgs_:!0,arguments:[d]})):(this.stateStack.shift(),this.stateStack[0].value=
                +b)}}else a.doneLeft=!0,this.stateStack.unshift({node:b.argument,components:!0})};Interpreter.prototype.stepVariableDeclaration=function(){var a=this.stateStack[0],b=a.node,c=a.n||0;b.declarations[c]?(a.n=c+1,this.stateStack.unshift({node:b.declarations[c]})):this.stateStack.shift()};
                +Interpreter.prototype.stepVariableDeclarator=function(){var a=this.stateStack[0],b=a.node;b.init&&!a.done?(a.done=!0,this.stateStack.unshift({node:b.init})):(b.init&&this.setValue(this.createPrimitive(b.id.name),a.value),this.stateStack.shift())};
                +Interpreter.prototype.stepWithStatement=function(){var a=this.stateStack[0],b=a.node;a.doneObject?a.doneBody?this.stateStack.shift():(a.doneBody=!0,a=this.createSpecialScope(this.getScope(),a.value),this.stateStack.unshift({node:b.body,scope:a})):(a.doneObject=!0,this.stateStack.unshift({node:b.object}))};Interpreter.prototype.stepWhileStatement=Interpreter.prototype.stepDoWhileStatement;this.Interpreter=Interpreter;Interpreter.prototype.appendCode=Interpreter.prototype.appendCode;
                +Interpreter.prototype.createAsyncFunction=Interpreter.prototype.createAsyncFunction;Interpreter.prototype.step=Interpreter.prototype.step;Interpreter.prototype.run=Interpreter.prototype.run;
                diff --git a/blockly/webif/static/blockly/demos/interpreter/async-execution.html b/blockly/webif/static/blockly/demos/interpreter/async-execution.html
                new file mode 100644
                index 000000000..e68f0dc0d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/interpreter/async-execution.html
                @@ -0,0 +1,262 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Asynchronous Execution with JS Interpreter</title>
                +  <script src="acorn_interpreter.js"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <script src="wait_block.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Asynchronous Execution with JS Interpreter</h1>
                +
                +  <p>This is a demo of executing code asychronously (e.g., waiting for delays or user input) using the JavaScript interpreter.</p>
                +
                +  <p>&rarr; <a href="https://developers.google.com/blockly/guides/configure-blockly/web/running-javascript#js_interpreter">More info on running code with JS Interpreter</a></p>
                +
                +  <p>
                +    <button onclick="runCode()" id="runButton">Run JavaScript</button>
                +  </p>
                +
                +  <div style="width: 100%">
                +    <div id="blocklyDiv"
                +        style="display: inline-block; height: 480px; width: 58%"></div>
                +    <textarea id="output" disabled="disabled"
                +        style="display: inline-block; height: 480px; width: 38%;">
                +    </textarea>
                +  </div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +    </category>
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_length"></block>
                +      <block type="text_print"></block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Variables" custom="VARIABLE"></category>
                +    <category name="Functions" custom="PROCEDURE"></category>
                +  </xml>
                +
                +  <xml id="startBlocks" style="display: none">
                +    <block type="variables_set" id="set_n_initial" inline="true" x="20" y="20">
                +      <field name="VAR">n</field>
                +      <value name="VALUE">
                +        <block type="math_number">
                +          <field name="NUM">1</field>
                +        </block>
                +      </value>
                +      <next>
                +        <block type="controls_repeat_ext" id="repeat" inline="true">
                +          <value name="TIMES">
                +            <block type="math_number">
                +              <field name="NUM">4</field>
                +            </block>
                +          </value>
                +          <statement name="DO">
                +            <block type="wait_seconds" id="wait">
                +              <field name="SECONDS">1.0</field>
                +              <next>
                +                <block type="variables_set" id="set_n_update" inline="true">
                +                  <field name="VAR">n</field>
                +                  <value name="VALUE">
                +                    <block type="math_arithmetic" inline="true">
                +                      <field name="OP">MULTIPLY</field>
                +                      <value name="A">
                +                        <block type="variables_get">
                +                          <field name="VAR">n</field>
                +                        </block>
                +                      </value>
                +                      <value name="B">
                +                        <block type="math_number">
                +                          <field name="NUM">2</field>
                +                        </block>
                +                      </value>
                +                    </block>
                +                  </value>
                +                  <next>
                +                    <block type="text_print" id="print" inline="false">
                +                      <value name="TEXT">
                +                        <block type="variables_get">
                +                          <field name="VAR">n</field>
                +                        </block>
                +                      </value>
                +                    </block>
                +                  </next>
                +                </block>
                +              </next>
                +            </block>
                +          </statement>
                +        </block>
                +      </next>
                +    </block>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +    Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
                +                               workspace);
                +
                +    // Exit is used to signal the end of a script.
                +    Blockly.JavaScript.addReservedWords('exit');
                +
                +    var outputArea = document.getElementById('output');
                +    var runButton = document.getElementById('runButton');
                +    var myInterpreter = null;
                +    var runner;
                +
                +    function initApi(interpreter, scope) {
                +      // Add an API function for the alert() block, generated for "text_print" blocks.
                +      var wrapper = function(text) {
                +        text = text ? text.toString() : '';
                +        outputArea.value = outputArea.value + '\n' + text;
                +      };
                +      interpreter.setProperty(scope, 'alert',
                +          interpreter.createNativeFunction(wrapper));
                +
                +      // Add an API function for the prompt() block.
                +      var wrapper = function(text) {
                +        text = text ? text.toString() : '';
                +        return interpreter.createPrimitive(prompt(text));
                +      };
                +      interpreter.setProperty(scope, 'prompt',
                +          interpreter.createNativeFunction(wrapper));
                +
                +      // Add an API for the wait block.  See wait_block.js
                +      initInterpreterWaitForSeconds(interpreter, scope);
                +
                +      // Add an API function for highlighting blocks.
                +      var wrapper = function(id) {
                +        id = id ? id.toString() : '';
                +        return interpreter.createPrimitive(highlightBlock(id));
                +      };
                +      interpreter.setProperty(scope, 'highlightBlock',
                +          interpreter.createNativeFunction(wrapper));
                +    }
                +
                +    var highlightPause = false;
                +    var latestCode = '';
                +
                +    function highlightBlock(id) {
                +      workspace.highlightBlock(id);
                +      highlightPause = true;
                +    }
                +
                +    function resetStepUi(clearOutput) {
                +      workspace.highlightBlock(null);
                +      highlightPause = false;
                +      runButton.disabled = '';
                +
                +      if (clearOutput) {
                +        outputArea.value = 'Program output:\n=================';
                +      }
                +    }
                +
                +    function generateCodeAndLoadIntoInterpreter() {
                +      // Generate JavaScript code and parse it.
                +      Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
                +      Blockly.JavaScript.addReservedWords('highlightBlock');
                +      latestCode = Blockly.JavaScript.workspaceToCode(workspace);
                +
                +      resetStepUi(true);
                +    }
                +
                +    function resetInterpreter() {
                +      myInterpreter = null;
                +      if (runner) {
                +        clearTimeout(runner);
                +        runner = null;
                +      }
                +    }
                +
                +    function runCode() {
                +      if (!myInterpreter) {
                +        // First statement of this code.
                +        // Clear the program output.
                +        resetStepUi(true);
                +        runButton.disabled = 'disabled';
                +
                +        // And then show generated code in an alert.
                +        // In a timeout to allow the outputArea.value to reset first.
                +        setTimeout(function() {
                +          alert('Ready to execute the following code\n' +
                +            '===================================\n' +
                +            latestCode);
                +
                +          // Begin execution
                +          highlightPause = false;
                +          myInterpreter = new Interpreter(latestCode, initApi);
                +          runner = function() {
                +            if (myInterpreter) {
                +              var hasMore = myInterpreter.run();
                +              if (hasMore) {
                +                // Execution is currently blocked by some async call.
                +                // Try again later.
                +                setTimeout(runner, 10);
                +              } else {
                +                // Program is complete.
                +                outputArea.value += '\n\n<< Program complete >>';
                +                resetInterpreter();
                +                resetStepUi(false);
                +              }
                +            }
                +          };
                +          runner();
                +        }, 1);
                +        return;
                +      }
                +    }
                +
                +    // Load the interpreter now, and upon future changes.
                +    generateCodeAndLoadIntoInterpreter();
                +    workspace.addChangeListener(function(event) {
                +      if (!(event instanceof Blockly.Events.Ui)) {
                +        // Something changed. Parser needs to be reloaded.
                +        resetInterpreter();
                +        generateCodeAndLoadIntoInterpreter();
                +      }
                +    });
                +  </script>
                +</body>
                +</html>
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/demos/interpreter/icon.png b/blockly/webif/static/blockly/demos/interpreter/icon.png
                new file mode 100644
                index 000000000..02962833b
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/interpreter/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/interpreter/index.html b/blockly/webif/static/blockly/demos/interpreter/index.html
                new file mode 100644
                index 000000000..2245057c0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/interpreter/index.html
                @@ -0,0 +1,11 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8"/>
                +  <title>Redirecting...</title>
                +  <meta http-equiv="refresh" content="0;URL='step-execution.html'"/>
                +</head>
                +<body>
                +Redirecting to <a href="step-execution.html">step execution jsinterpreter demo</a>.
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/interpreter/step-execution.html b/blockly/webif/static/blockly/demos/interpreter/step-execution.html
                new file mode 100644
                index 000000000..8a8b95a6a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/interpreter/step-execution.html
                @@ -0,0 +1,251 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Step Execution with JS Interpreter</title>
                +  <script src="acorn_interpreter.js"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Step Execution with JS Interpreter</h1>
                +
                +  <p>This is a demo of executing code step-by-step with a sandboxed JavaScript interpreter.</p>
                +
                +  <p>The generator's <code>Blockly.JavaScript.STATEMENT_PREFIX</code> is assigned <code>'highlightBlock(%1);\n'</code>,
                +  where <code>%1</code> is the block id. The call to <code>highlightBlock()</code> will highlight the identified block
                +  and set the variable <code>highlightPause</code> to <code>true</code>.</p>
                +
                +  <p>"Parse JavaScript" will generate the code and load it into the interpreter. Then, each press of the
                +  "Step JavaScript" button will run the interpreter one step until the <code>highlightPause</code> is true.
                +  That is, until <code>highlightBlock()</code> has highlighted the block that will be executed on the next step.</p>
                +
                +  <p>&rarr; <a href="https://developers.google.com/blockly/guides/configure-blockly/web/running-javascript#js_interpreter">More info on running code with JS Interpreter</a></p>
                +
                +  <p>
                +    <button onclick="stepCode()" id="stepButton">Step JavaScript</button>
                +  </p>
                +
                +  <div style="width: 100%">
                +    <div id="blocklyDiv"
                +        style="display: inline-block; height: 480px; width: 58%"></div>
                +    <textarea id="output" disabled="disabled"
                +        style="display: inline-block; height: 480px; width: 38%;">
                +    </textarea>
                +  </div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +    </category>
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_length"></block>
                +      <block type="text_print"></block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Variables" custom="VARIABLE"></category>
                +    <category name="Functions" custom="PROCEDURE"></category>
                +  </xml>
                +
                +  <xml id="startBlocks" style="display: none">
                +    <block type="variables_set" id="set_n_initial" inline="true" x="20" y="20">
                +      <field name="VAR">n</field>
                +      <value name="VALUE">
                +        <block type="math_number">
                +          <field name="NUM">1</field>
                +        </block>
                +      </value>
                +      <next>
                +        <block type="controls_repeat_ext" id="repeat" inline="true">
                +          <value name="TIMES">
                +            <block type="math_number">
                +              <field name="NUM">4</field>
                +            </block>
                +          </value>
                +          <statement name="DO">
                +            <block type="variables_set" id="set_n_update" inline="true">
                +              <field name="VAR">n</field>
                +              <value name="VALUE">
                +                <block type="math_arithmetic" inline="true">
                +                  <field name="OP">MULTIPLY</field>
                +                  <value name="A">
                +                    <block type="variables_get">
                +                      <field name="VAR">n</field>
                +                    </block>
                +                  </value>
                +                  <value name="B">
                +                    <block type="math_number">
                +                      <field name="NUM">2</field>
                +                    </block>
                +                  </value>
                +                </block>
                +              </value>
                +              <next>
                +                <block type="text_print" id="print">
                +                  <value name="TEXT">
                +                    <block type="variables_get">
                +                      <field name="VAR">n</field>
                +                    </block>
                +                  </value>
                +                </block>
                +              </next>
                +            </block>
                +          </statement>
                +        </block>
                +      </next>
                +    </block>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +    Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
                +                               workspace);
                +
                +    var outputArea = document.getElementById('output');
                +    var stepButton = document.getElementById('stepButton');
                +    var myInterpreter = null;
                +
                +    function initApi(interpreter, scope) {
                +      // Add an API function for the alert() block, generated for "text_print" blocks.
                +      interpreter.setProperty(scope, 'alert',
                +          interpreter.createNativeFunction(function(text) {
                +        text = text ? text.toString() : '';
                +        outputArea.value += '\n' + text;
                +      }));
                +
                +      // Add an API function for the prompt() block.
                +      var wrapper = function(text) {
                +        text = text ? text.toString() : '';
                +        return interpreter.createPrimitive(prompt(text));
                +      };
                +      interpreter.setProperty(scope, 'prompt',
                +          interpreter.createNativeFunction(wrapper));
                +
                +      // Add an API function for highlighting blocks.
                +      var wrapper = function(id) {
                +        id = id ? id.toString() : '';
                +        return interpreter.createPrimitive(highlightBlock(id));
                +      };
                +      interpreter.setProperty(scope, 'highlightBlock',
                +          interpreter.createNativeFunction(wrapper));
                +    }
                +
                +    var highlightPause = false;
                +    var latestCode = '';
                +
                +    function highlightBlock(id) {
                +      workspace.highlightBlock(id);
                +      highlightPause = true;
                +    }
                +
                +    function resetStepUi(clearOutput) {
                +      workspace.highlightBlock(null);
                +      highlightPause = false;
                +
                +      if (clearOutput) {
                +        outputArea.value = 'Program output:\n=================';
                +      }
                +    }
                +
                +    function generateCodeAndLoadIntoInterpreter() {
                +      // Generate JavaScript code and parse it.
                +      Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
                +      Blockly.JavaScript.addReservedWords('highlightBlock');
                +      latestCode = Blockly.JavaScript.workspaceToCode(workspace);
                +
                +      resetStepUi(true);
                +    }
                +
                +    function stepCode() {
                +      if (!myInterpreter) {
                +        // First statement of this code.
                +        // Clear the program output.
                +        resetStepUi(true);
                +        myInterpreter = new Interpreter(latestCode, initApi);
                +
                +        // And then show generated code in an alert.
                +        // In a timeout to allow the outputArea.value to reset first.
                +        setTimeout(function() {
                +          alert('Ready to execute the following code\n' +
                +            '===================================\n' + latestCode);
                +          highlightPause = true;
                +          stepCode();
                +        }, 1);
                +        return;
                +      }
                +      highlightPause = false;
                +      do {
                +        try {
                +          var hasMoreCode = myInterpreter.step();
                +        } finally {
                +          if (!hasMoreCode) {
                +            // Program complete, no more code to execute.
                +            outputArea.value += '\n\n<< Program complete >>';
                +
                +            myInterpreter = null;
                +            resetStepUi(false);
                +
                +            // Cool down, to discourage accidentally restarting the program.
                +            stepButton.disabled = 'disabled';
                +            setTimeout(function() {
                +              stepButton.disabled = '';
                +            }, 2000);
                +
                +            return;
                +          }
                +        }
                +        // Keep executing until a highlight statement is reached,
                +        // or the code completes or errors.
                +      } while (hasMoreCode && !highlightPause);
                +    }
                +
                +    // Load the interpreter now, and upon future changes.
                +    generateCodeAndLoadIntoInterpreter();
                +    workspace.addChangeListener(function(event) {
                +      if (!(event instanceof Blockly.Events.Ui)) {
                +        // Something changed. Parser needs to be reloaded.
                +        generateCodeAndLoadIntoInterpreter();
                +      }
                +    });
                +  </script>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/interpreter/wait_block.js b/blockly/webif/static/blockly/demos/interpreter/wait_block.js
                new file mode 100644
                index 000000000..f64d84047
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/interpreter/wait_block.js
                @@ -0,0 +1,67 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Example "wait" block that will pause the interpreter for a
                + * number of seconds. Because wait is a blocking behavior, such blocks will
                + * only work in interpreted environments.
                + *
                + * See https://neil.fraser.name/software/JS-Interpreter/docs.html
                + */
                +Blockly.defineBlocksWithJsonArray([{
                +  "type": "wait_seconds",
                +  "message0": " wait %1 seconds",
                +  "args0": [{
                +    "type": "field_number",
                +    "name": "SECONDS",
                +    "min": 0,
                +    "max": 600,
                +    "value": 1
                +  }],
                +  "previousStatement": null,
                +  "nextStatement": null,
                +  "colour": "%{BKY_LOOPS_HUE}"
                +}]);
                +
                +/**
                + * Generator for wait block creates call to new method
                + * <code>waitForSeconds()</code>.
                + */
                +Blockly.JavaScript['wait_seconds'] = function(block) {
                +  var seconds = Number(block.getFieldValue('SECONDS'));
                +  var code = 'waitForSeconds(' + seconds + ');\n';
                +  return code;
                +};
                +
                +/**
                + * Register the interpreter asynchronous function
                + * <code>waitForSeconds()</code>.
                + */
                +function initInterpreterWaitForSeconds(interpreter, scope) {
                +  // Ensure function name does not conflict with variable names.
                +  Blockly.JavaScript.addReservedWords('waitForSeconds');
                +
                +  var wrapper = interpreter.createAsyncFunction(
                +    function(timeInSeconds, callback) {
                +      // Delay the call to the callback.
                +      setTimeout(callback, timeInSeconds * 1000);
                +    });
                +  interpreter.setProperty(scope, 'waitForSeconds', wrapper);
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/demos/maxBlocks/icon.png b/blockly/webif/static/blockly/demos/maxBlocks/icon.png
                new file mode 100644
                index 000000000..13bf65a9c
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/maxBlocks/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/maxBlocks/index.html b/blockly/webif/static/blockly/demos/maxBlocks/index.html
                new file mode 100644
                index 000000000..17a967339
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/maxBlocks/index.html
                @@ -0,0 +1,98 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Maximum Block Limit</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    #capacity {
                +      color: red;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Maximum Block Limit</h1>
                +
                +  <p>This is a demo of Blockly which has been restricted to a maximum of
                +  five blocks.</p>
                +
                +  <p><b>You have <span id="capacity"></span> block(s) left.</b></p>
                +
                +  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <field name="VAR">i</field>
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +        <value name="BY">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +    </category>
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_length"></block>
                +      <block type="text_print"></block>
                +    </category>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         maxBlocks: 5,
                +         toolbox: document.getElementById('toolbox')});
                +
                +    function onchange(event) {
                +      document.getElementById('capacity').textContent =
                +          workspace.remainingCapacity();
                +    }
                +
                +    workspace.addChangeListener(onchange);
                +    onchange();
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/minimap/icon.png b/blockly/webif/static/blockly/demos/minimap/icon.png
                new file mode 100644
                index 000000000..870caa070
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/minimap/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/minimap/index.html b/blockly/webif/static/blockly/demos/minimap/index.html
                new file mode 100644
                index 000000000..2e495fdb1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/minimap/index.html
                @@ -0,0 +1,90 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Minimap </title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <script src="minimap.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Minimap</h1>
                +
                +  <p>This is a simple demo showing how a minimap can be implemented.</p>
                +
                +  <table width="100%">
                +    <tr>
                +      <td>
                +        <div id="masterDiv" style="height: 480px; width: 900px;"></div>
                +      </td>
                +      <td>
                +        <div id="mapDiv" style="height: 480px; width: 200px;"></div>
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <xml id="toolbox" style="display: none">
                +    <block type="controls_if"></block>
                +    <block type="logic_compare"></block>
                +    <block type="controls_repeat_ext"></block>
                +    <block type="math_number"></block>
                +    <block type="math_arithmetic"></block>
                +    <block type="text"></block>
                +    <block type="text_print"></block>
                +    <block type="variables_get"><field name="VAR">i</field></block>
                +    <block type="variables_get"><field name="VAR">j</field></block>
                +    <block type="variables_get"><field name="VAR">k</field></block>
                +  </xml>
                +
                +  <script>
                +
                +  // Inject master workspace.
                +  var masterWorkspace = Blockly.inject('masterDiv',{
                +    media: '../../media/',
                +    scrollbars: true,
                +    toolbox: document.getElementById('toolbox')
                +  });
                +
                +  // Inject workspace for minimap.
                +  var minimapWorkspace = Blockly.inject('mapDiv',
                +    {media: '../../media/',
                +     readOnly: true,
                +     zoom:
                +      {controls: false,
                +      wheel: true,
                +      startScale: 0.1, //you can change this accorting to your needs.
                +      maxScale: 0.1,
                +      minScale: 0.01
                +      }});
                +
                +  // Initilizing the minimap.
                +  Minimap.init(masterWorkspace,minimapWorkspace);
                +
                +  </script>
                +  <style>
                +    .minimap{
                +      position:absolute;
                +    }
                +    .mapDragger{
                +      cursor: move;
                +      fill:rgb(0,0,255);
                +      stroke-width:0.5;
                +      stroke:rgb(0,0,0);
                +      fill-opacity:0.1;
                +  }
                +  </style>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/minimap/minimap.js b/blockly/webif/static/blockly/demos/minimap/minimap.js
                new file mode 100644
                index 000000000..4ac687e39
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/minimap/minimap.js
                @@ -0,0 +1,306 @@
                +/**
                +* Blockly Demos: Code
                +*
                +* Copyright 2017 Google Inc.
                +* https://developers.google.com/blockly/
                +*
                +* Licensed under the Apache License, Version 2.0 (the "License");
                +* you may not use this file except in compliance with the License.
                +* You may obtain a copy of the License at
                +*
                +*   http://www.apache.org/licenses/LICENSE-2.0
                +*
                +* Unless required by applicable law or agreed to in writing, software
                +* distributed under the License is distributed on an "AS IS" BASIS,
                +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +* See the License for the specific language governing permissions and
                +* limitations under the License.
                +*/
                +
                +/**
                +* @fileoverview JavaScript for Blockly's Minimap demo.
                +* @author karnpurohit@gmail.com (Karan Purohit)
                +*/
                +'use strict';
                +
                +/**
                +* Creating a seperate namespace for minimap.
                +*/
                +var Minimap = {};
                +
                +/**
                +* Initilize the workspace and minimap.
                +* @param {Workspace} workspace The main workspace of the user.
                +* @param {Workspace} minimap The workspace that will be used as a minimap.
                +*/
                +Minimap.init = function(workspace, minimap){
                +  this.workspace = workspace;
                +  this.minimap = minimap;
                +
                +  //Adding scroll callback functionlity to vScroll and hScroll just for this demo.
                +  //IMPORTANT: This should be changed when there is proper UI event handling
                +  //           api available and should be handled by workspace's event listeners.
                +  this.workspace.scrollbar.vScroll.setHandlePosition = function(newPosition){
                +    this.handlePosition_ = newPosition;
                +    this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
                +
                +    // Code above is same as the original setHandlePosition function in core/scrollbar.js.
                +    // New code starts from here.
                +
                +    // Get the absolutePosition.
                +    var absolutePosition = (this.handlePosition_ / this.ratio_);
                +
                +    // Firing the scroll change listener.
                +    Minimap.onScrollChange(absolutePosition, this.horizontal_);
                +  };
                +
                +  // Adding call back for horizontal scroll.
                +  this.workspace.scrollbar.hScroll.setHandlePosition = function(newPosition){
                +    this.handlePosition_ = newPosition;
                +    this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
                +
                +    // Code above is same as the original setHandlePosition function in core/scrollbar.js.
                +    // New code starts from here.
                +
                +    // Get the absolutePosition.
                +    var absolutePosition = (this.handlePosition_ / this.ratio_);
                +
                +    // Firing the scroll change listener.
                +    Minimap.onScrollChange(absolutePosition, this.horizontal_);
                +  };
                +
                +
                +  // Required to stop a positive feedback loop when user clicks minimap
                +  // and the scroll changes, which inturn may change minimap.
                +  this.disableScrollChange = false;
                +
                +  // Listen to events on the main workspace.
                +  this.workspace.addChangeListener(Minimap.mirrorEvent);
                +
                +  //Get rectangle bounding the minimap div.
                +  this.rect = document.getElementById('mapDiv').getBoundingClientRect();
                +
                +  // Create a svg overlay on the top of mapDiv for the minimap.
                +  this.svg = Blockly.utils.createSvgElement('svg', {
                +    'xmlns': 'http://www.w3.org/2000/svg',
                +    'xmlns:html': 'http://www.w3.org/1999/xhtml',
                +    'xmlns:xlink': 'http://www.w3.org/1999/xlink',
                +    'version': '1.1',
                +    'height': this.rect.bottom-this.rect.top,
                +    'width': this.rect.right-this.rect.left,
                +    'class': 'minimap',
                +  }, document.getElementById('mapDiv'));
                +  this.svg.style.top = this.rect.top + 'px';
                +  this.svg.style.left = this.rect.left + 'px';
                +
                +  // Creating a rectangle in the minimap that represents current view.
                +  Blockly.utils.createSvgElement('rect', {
                +    'width':100,
                +    'height':100,
                +    'class':'mapDragger'
                +  }, this.svg);
                +
                +  // Rectangle in the minimap that represents current view.
                +  this.mapDragger = this.svg.childNodes[0];
                +
                +  // Adding mouse events to the rectangle, to make it Draggable.
                +  // Using Blockly.bindEvent_ to attach mouse/touch listeners.
                +  Blockly.bindEvent_(this.mapDragger, "mousedown", null, Minimap.mousedown);
                +
                +  //When the window change, we need to resize the minimap window.
                +  window.addEventListener('resize', Minimap.repositionMinimap);
                +
                +  // Mouse up event for the minimap.
                +  this.svg.addEventListener('mouseup', Minimap.updateMapDragger);
                +
                +  //Boolen to check whether I am dragging the surface or not.
                +  this.isDragging = false;
                +};
                +
                +Minimap.mousedown = function(e){
                +  // Using Blockly.bindEvent_ to attach mouse/touch listeners.
                +  Minimap.mouseMoveBindData = Blockly.bindEvent_(document,"mousemove", null, Minimap.mousemove);
                +  Minimap.mouseUpBindData = Blockly.bindEvent_(document,"mouseup", null, Minimap.mouseup);
                +
                +  Minimap.isDragging=true;
                +  e.stopPropagation();
                +};
                +
                +Minimap.mouseup = function(e){
                +  Minimap.isDragging = false;
                +  // Removing listeners.
                +  Blockly.unbindEvent_(Minimap.mouseUpBindData);
                +  Blockly.unbindEvent_(Minimap.mouseMoveBindData);
                +  Minimap.updateMapDragger(e);
                +  e.stopPropagation();
                +};
                +
                +Minimap.mousemove = function(e){
                +  if(Minimap.isDragging){
                +    Minimap.updateMapDragger(e);
                +    e.stopPropagation();
                +  }
                +};
                +
                +/**
                +* Initilize the workspace and minimap.
                +* @param {Event} event Event that triggered in the main workspace.
                +*/
                +Minimap.mirrorEvent = function(event){
                +  if (event.type == Blockly.Events.UI) {
                +    return;  // Don't mirror UI events.
                +  }
                +  // Convert event to JSON.  This could then be transmitted across the net.
                +  var json = event.toJson();
                +  // Convert JSON back into an event, then execute it.
                +  var minimapEvent = Blockly.Events.fromJson(json, Minimap.minimap);
                +  minimapEvent.run(true);
                +  Minimap.scaleMinimap();
                +  Minimap.setDraggerHeight();
                +  Minimap.setDraggerWidth();
                +};
                +
                +/**
                +* Called when window is resized. Repositions the minimap overlay.
                +*/
                +Minimap.repositionMinimap = function(){
                +  Minimap.rect = document.getElementById('mapDiv').getBoundingClientRect();
                +  Minimap.svg.style.top = Minimap.rect.top + 'px';
                +  Minimap.svg.style.left = Minimap.rect.left + 'px';
                +};
                +
                +/**
                +* Updates the rectangle's height .
                +*/
                +Minimap.setDraggerHeight = function(){
                +  var workspaceMetrics = Minimap.workspace.getMetrics();
                +  var draggerHeight = (workspaceMetrics.viewHeight / Minimap.workspace.scale) * Minimap.minimap.scale;
                +  // It's zero when first block is placed.
                +  if(draggerHeight == 0){
                +    return;
                +  }
                +  Minimap.mapDragger.setAttribute("height", draggerHeight);
                +};
                +
                +/**
                +* Updates the rectangle's width.
                +*/
                +Minimap.setDraggerWidth = function(){
                +  var workspaceMetrics = Minimap.workspace.getMetrics();
                +  var draggerWidth = (workspaceMetrics.viewWidth / Minimap.workspace.scale) * Minimap.minimap.scale;
                +  // It's zero when first block is placed.
                +  if(draggerWidth == 0){
                +    return;
                +  }
                +  Minimap.mapDragger.setAttribute("width", draggerWidth);
                +};
                +
                +
                +/**
                +* Updates the overall position of the viewport of the minimap by appropriately
                +* using translate functions.
                +*/
                +Minimap.scaleMinimap = function(){
                +  var minimapBoundingBox = Minimap.minimap.getBlocksBoundingBox();
                +  var workspaceBoundingBox = Minimap.workspace.getBlocksBoundingBox();
                +  var workspaceMetrics = Minimap.workspace.getMetrics();
                +  var minimapMetrics = Minimap.minimap.getMetrics();
                +
                +  //Scaling the mimimap such that all the blocks can be seen in the viewport.
                +  //This padding is default because this is how to scrollbar(in main workspace) is implemented.
                +  var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
                +  var sidePadding = (workspaceMetrics.viewWidth) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
                +
                +  // If actual padding is more than half view ports height, change it to actual padding.
                +  if((workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
                +      * Minimap.minimap.scale / Minimap.workspace.scale > topPadding){
                +    topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
                +    * Minimap.minimap.scale / Minimap.workspace.scale;
                +  }
                +
                +  // If actual padding is more than half view ports height, change it to actual padding.
                +  if((workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
                +      * Minimap.minimap.scale / Minimap.workspace.scale > sidePadding){
                +    sidePadding = (workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
                +    * Minimap.minimap.scale / Minimap.workspace.scale;
                +  }
                +
                +  var scalex = (minimapMetrics.viewWidth - 2 * sidePadding) / minimapBoundingBox.width;
                +  var scaley = (minimapMetrics.viewHeight - 2 * topPadding) / minimapBoundingBox.height;
                +  Minimap.minimap.setScale(Math.min(scalex, scaley));
                +
                +  // Translating the minimap.
                +  Minimap.minimap.translate( - minimapMetrics.contentLeft * Minimap.minimap.scale + sidePadding,
                +                          - minimapMetrics.contentTop * Minimap.minimap.scale + topPadding);
                +};
                +
                +/**
                +* Handles the onclick event on the minimapBoundingBox. Changes mapDraggers position.
                +* @param {Event} e Event from the mouse click.
                +*/
                +Minimap.updateMapDragger = function(e){
                +  var y = e.clientY;
                +  var x = e.clientX;
                +  var draggerHeight = Minimap.mapDragger.getAttribute("height");
                +  var draggerWidth = Minimap.mapDragger.getAttribute("width");
                +
                +  var finalY = y - Minimap.rect.top - draggerHeight / 2;
                +  var finalX = x - Minimap.rect.left - draggerWidth / 2;
                +
                +  var maxValidY = (Minimap.workspace.getMetrics().contentHeight - Minimap.workspace.getMetrics().viewHeight)
                +                  * Minimap.minimap.scale;
                +  var maxValidX = (Minimap.workspace.getMetrics().contentWidth - Minimap.workspace.getMetrics().viewWidth)
                +                  * Minimap.minimap.scale;
                +
                +  if(y + draggerHeight / 2 > Minimap.rect.bottom){
                +    finalY = Minimap.rect.bottom - Minimap.rect.top - draggerHeight;
                +  }else if(y < Minimap.rect.top + draggerHeight / 2){
                +    finalY = 0;
                +  }
                +
                +  if(x + draggerWidth / 2 > Minimap.rect.right){
                +    finalX = Minimap.rect.right - Minimap.rect.left - draggerWidth;
                +  }else if(x < Minimap.rect.left + draggerWidth / 2){
                +    finalX = 0;
                +  }
                +
                +  // Do not go below lower bound of scrollbar.
                +  if(finalY > maxValidY){
                +    finalY = maxValidY;
                +  }
                +
                +  if(finalX > maxValidX){
                +    finalX = maxValidX;
                +  }
                +  Minimap.mapDragger.setAttribute("y", finalY);
                +  Minimap.mapDragger.setAttribute("x", finalX);
                +  // Required, otherwise creates a feedback loop.
                +  Minimap.disableScrollChange = true;
                +  Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) / Minimap.minimap.scale);
                +  Minimap.workspace.scrollbar.hScroll.set((finalX * Minimap.workspace.scale) / Minimap.minimap.scale);
                +  Minimap.disableScrollChange = false;
                +};
                +
                +/**
                +* Handles the onclick event on the minimapBoundingBox, paramaters are passed by
                +* the event handler.
                +* @param {Float} position This is the absolute postion of the scrollbar.
                +* @param {boolean} horizontal Informs if the change event if for horizontal(true)
                +*     scrollbar or vertical(false) scrollbar.
                +*/
                +Minimap.onScrollChange = function(position, horizontal){
                +
                +  if(Minimap.disableScrollChange){
                +    return;
                +  }
                +
                +  var newDraggerPosition = (position * Minimap.minimap.scale / Minimap.workspace.scale);
                +  if(horizontal){
                +    // Change the horizontal position of dragger.
                +    Minimap.mapDragger.setAttribute("x", newDraggerPosition);
                +  }
                +  else{
                +    // Change the vertical position of dragger.
                +    Minimap.mapDragger.setAttribute("y", newDraggerPosition);
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/demos/mirror/icon.png b/blockly/webif/static/blockly/demos/mirror/icon.png
                new file mode 100644
                index 000000000..45e2a9a29
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/mirror/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/mirror/index.html b/blockly/webif/static/blockly/demos/mirror/index.html
                new file mode 100644
                index 000000000..0098e92df
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/mirror/index.html
                @@ -0,0 +1,79 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Mirrored Blockly</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Mirrored Blockly</h1>
                +
                +  <p>This is a simple demo of a primary Blockly instance that controls a secondary Blockly instance with events.
                +  Open the JavaScript console to see the event passing.</p>
                +
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure/web/events">events</a>&hellip;</p>
                +
                +  <table width="100%">
                +    <tr>
                +      <td>
                +        <div id="primaryDiv" style="height: 480px; width: 600px;"></div>
                +      </td>
                +      <td>
                +        <div id="secondaryDiv" style="height: 480px; width: 430px;"></div>
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <xml id="toolbox" style="display: none">
                +    <block type="controls_if"></block>
                +    <block type="logic_compare"></block>
                +    <block type="controls_repeat_ext"></block>
                +    <block type="math_number"></block>
                +    <block type="math_arithmetic"></block>
                +    <block type="text"></block>
                +    <block type="text_print"></block>
                +    <block type="variables_get"><field name="VAR">i</field></block>
                +    <block type="variables_get"><field name="VAR">j</field></block>
                +    <block type="variables_get"><field name="VAR">k</field></block>
                +  </xml>
                +
                +  <script>
                +    // Inject primary workspace.
                +    var primaryWorkspace = Blockly.inject('primaryDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +    // Inject secondary workspace.
                +    var secondaryWorkspace = Blockly.inject('secondaryDiv',
                +        {media: '../../media/',
                +         readOnly: true});
                +    // Listen to events on primary workspace.
                +    primaryWorkspace.addChangeListener(mirrorEvent);
                +
                +    function mirrorEvent(primaryEvent) {
                +      if (primaryEvent.type == Blockly.Events.UI) {
                +        return;  // Don't mirror UI events.
                +      }
                +      // Convert event to JSON.  This could then be transmitted across the net.
                +      var json = primaryEvent.toJson();
                +      console.log(json);
                +      // Convert JSON back into an event, then execute it.
                +      var secondaryEvent = Blockly.Events.fromJson(json, secondaryWorkspace);
                +      secondaryEvent.run(true);
                +    }
                +</script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/plane/README.txt b/blockly/webif/static/blockly/demos/plane/README.txt
                new file mode 100644
                index 000000000..6da3fa65d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/README.txt
                @@ -0,0 +1,26 @@
                +This Blockly demo uses Closure Templates to create a multilingual application.
                +Any changes to the template.soy file require a recompile.  Here is the command
                +to generate a quick English version for debugging:
                +
                +java -jar soy/SoyToJsSrcCompiler.jar --outputPathFormat generated/en.js --srcs template.soy
                +
                +To generate a full set of language translations, first extract all the strings
                +from template.soy using this command:
                +
                +java -jar soy/SoyMsgExtractor.jar --outputFile xlf/extracted_msgs.xlf  template.soy
                +
                +This generates xlf/extracted_msgs.xlf, which may then be used by any
                +XLIFF-compatible translation console to generate a set of files with the
                +translated strings.  These should be placed in the xlf directory.
                +
                +Finally, generate all the language versions wih this command:
                +
                +java -jar soy/SoyToJsSrcCompiler.jar --locales ar,be-tarask,br,ca,da,de,el,en,es,fa,fr,he,hrx,hu,ia,is,it,ja,ko,ms,nb,nl,pl,pms,pt-br,ro,ru,sc,sv,th,tr,uk,vi,zh-hans,zh-hant --messageFilePathFormat xlf/translated_msgs_{LOCALE}.xlf --outputPathFormat "generated/{LOCALE}.js" template.soy
                +
                +This is the process that Google uses for maintaining Blockly Games in 40+
                +languages.  The XLIFF fromat is simple enough that it is trival to write a
                +Python script to reformat it into some other format (such as JSON) for
                +compatability with other translation consoles.
                +
                +For more information, see message translation for Closure Templates:
                +https://developers.google.com/closure/templates/docs/translation
                diff --git a/blockly/webif/static/blockly/demos/plane/blocks.js b/blockly/webif/static/blockly/demos/plane/blocks.js
                new file mode 100644
                index 000000000..18be29c5d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/blocks.js
                @@ -0,0 +1,103 @@
                +/**
                + * Blockly Demos: Plane Seat Calculator Blocks
                + *
                + * Copyright 2013 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Blocks for Blockly's Plane Seat Calculator application.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Blocks['plane_set_seats'] = {
                +  // Block seat variable setter.
                +  init: function() {
                +    this.setHelpUrl(Blockly.Msg.VARIABLES_SET_HELPURL);
                +    this.setColour(330);
                +    this.appendValueInput('VALUE')
                +        .appendField(Plane.getMsg('Plane_setSeats'));
                +    this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
                +    this.setDeletable(false);
                +  }
                +};
                +
                +Blockly.JavaScript['plane_set_seats'] = function(block) {
                +  // Generate JavaScript for seat variable setter.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || 'NaN';
                +  return argument0 + ';';
                +};
                +
                +Blockly.Blocks['plane_get_rows'] = {
                +  // Block for row variable getter.
                +  init: function() {
                +    this.setHelpUrl(Blockly.Msg.VARIABLES_GET_HELPURL);
                +    this.setColour(330);
                +    this.appendDummyInput()
                +        .appendField(Plane.getMsg('Plane_getRows'), 'title');
                +    this.setOutput(true, 'Number');
                +  },
                +  customUpdate: function() {
                +    this.setFieldValue(
                +        Plane.getMsg('Plane_getRows').replace('%1', Plane.rows1st), 'title');
                +  }
                +};
                +
                +Blockly.JavaScript['plane_get_rows'] = function(block) {
                +  // Generate JavaScript for row variable getter.
                +  return ['Plane.rows1st', Blockly.JavaScript.ORDER_MEMBER];
                +};
                +
                +Blockly.Blocks['plane_get_rows1st'] = {
                +  // Block for first class row variable getter.
                +  init: function() {
                +    this.setHelpUrl(Blockly.Msg.VARIABLES_GET_HELPURL);
                +    this.setColour(330);
                +    this.appendDummyInput()
                +        .appendField(Plane.getMsg('Plane_getRows1'), 'title');
                +    this.setOutput(true, 'Number');
                +  },
                +  customUpdate: function() {
                +    this.setFieldValue(
                +        Plane.getMsg('Plane_getRows1').replace('%1', Plane.rows1st), 'title');
                +  }
                +};
                +
                +Blockly.JavaScript['plane_get_rows1st'] = function(block) {
                +  // Generate JavaScript for first class row variable getter.
                +  return ['Plane.rows1st', Blockly.JavaScript.ORDER_MEMBER];
                +};
                +
                +Blockly.Blocks['plane_get_rows2nd'] = {
                +  // Block for second class row variable getter.
                +  init: function() {
                +    this.setHelpUrl(Blockly.Msg.VARIABLES_GET_HELPURL);
                +    this.setColour(330);
                +    this.appendDummyInput()
                +        .appendField(Plane.getMsg('Plane_getRows2'), 'title');
                +    this.setOutput(true, 'Number');
                +  },
                +  customUpdate: function() {
                +    this.setFieldValue(
                +        Plane.getMsg('Plane_getRows2').replace('%1', Plane.rows2nd), 'title');
                +  }
                +};
                +
                +Blockly.JavaScript['plane_get_rows2nd'] = function(block) {
                +  // Generate JavaScript for second class row variable getter.
                +  return ['Plane.rows2nd', Blockly.JavaScript.ORDER_MEMBER];
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ar.js b/blockly/webif/static/blockly/demos/plane/generated/ar.js
                new file mode 100644
                index 000000000..131094904
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ar.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">الصفوف: %1</span><span id="Plane_getRows">الصفوف (%1)</span><span id="Plane_rows1">صفوف الطبقة الأولى: %1</span><span id="Plane_getRows1">صفوف الطبقة الأولى (%1)</span><span id="Plane_rows2">صفوف الفئة الثانية: %1</span><span id="Plane_getRows2">صفوف الفئة الثانية: (%1)</span><span id="Plane_seats">المقاعد: %1</span><span id="Plane_placeholder">؟</span><span id="Plane_setSeats">المقاعد =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">آلة حاسبة لمقعد الطائرة</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'هنالك طائرة تحتوي على عدد من صفوف مقاعد الركاب. كل صف يحتوي على أربعة مقاعد.';
                +      break;
                +    case 2:
                +      output += 'طائرة بمقعدين في مقطورة الطيّار (للطيار ومساعده) وعدد من الصفوف يحتوي كل صف على أربعة مقاعد.';
                +      break;
                +    case 3:
                +      output += 'طائرة بمقعدين في مقطورة الطيّار (للطيار ومساعده) وعدد من المقاعد في صفوف الدرجة الأولى والثانية. كل صف من صفوف الدرجة الأولى يحتوي على أربعة مقاعد. ويحتوي كل صف في الدرجة الثانية على خمسة مقاعد.';
                +      break;
                +  }
                +  output += '</p><p>لبناء صيغة (أدناه) تقوم بحساب إجمالي عدد المقاعد في الطائرة عند تغيير الصفوف (أعلاه).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/be-tarask.js b/blockly/webif/static/blockly/demos/plane/generated/be-tarask.js
                new file mode 100644
                index 000000000..ba60f45e9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/be-tarask.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Радкоў: %1</span><span id="Plane_getRows">радкоў (%1)</span><span id="Plane_rows1">Радкі першага клясу: %1</span><span id="Plane_getRows1">радкі першага клясу (%1)</span><span id="Plane_rows2">Радкі другога клясу: %1</span><span id="Plane_getRows2">радкі другога клясу (%1)</span><span id="Plane_seats">Месцаў: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">месцаў =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Калькулятар месцаў у самалёце</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Самалёт мае некалькі шэрагаў пасажырскіх сядзеньняў. Кожная шэраг утрымлівае чатыры месцы.';
                +      break;
                +    case 2:
                +      output += 'Самалёт мае два месцы ў кабіне экіпажа (пілот і другі пілот), і некалькі шэрагаў пасажырскіх сядзеньняў. Кожны шэраг утрымлівае чатыры месцы.';
                +      break;
                +    case 3:
                +      output += 'Самалёт мае два месцы ў кабіне экіпажа (пілот і другі пілот), і некалькі пасажырскіх шэрагаў месцаў 1-га кляса і 2-га кляса. Кожны шэраг 1-га кляса утрымлівае чатыры месцы. Кожны шэраг 2-га кляса ўтрымлівае пяць месцаў.';
                +      break;
                +  }
                +  output += '</p><p>Пабудаваць формулу (ніжэй), якая падлічвае агульную колькасьць месцаў у самалёце пры зьмене радоў (гл. вышэй).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/br.js b/blockly/webif/static/blockly/demos/plane/generated/br.js
                new file mode 100644
                index 000000000..84c2fae88
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/br.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Renkennadoù : %1</span><span id="Plane_getRows">renkennadoù (%1)</span><span id="Plane_rows1">Renkennadoù kentañ klas : %1</span><span id="Plane_getRows1">Renkennadoù kentañ klas (%1)</span><span id="Plane_rows2">Renkennadoù eil klas : %1</span><span id="Plane_getRows2">Renkennadoù eil klas (%1)</span><span id="Plane_seats">Azezennoù : %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">azezennoù =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Jederez azezenn nijerez</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un nijerez he deus un toullad renkennadoù azezennoù evit ar veajourien. Peder azezenn a zo e pep renkennad.';
                +      break;
                +    case 2:
                +      output += 'En un nijerez ez eus div azezenn el logell leviañ(evit al loman hag an eil loman), hag ur toullad renkennadoù azezennoù evit an dremenidi. Peder azezenn zo e pep renkennad.';
                +      break;
                +    case 3:
                +      output += 'En un nijerez ez eus div azezenn el logell leviañ(evit al loman hag an eil loman), hag un toullad renkennadoù azezennoù tremenidi kentañ hag eil klas. Peder azezenn zo e pep renkennad kentañ klas. Pemp azezenn zo e pemp renkennad eil klas.';
                +      break;
                +  }
                +  output += '</p><p>Sevel ur formulenn (amañ dindan) evit jediñ an niver a azezennoù en holl en nijerez pa vez kemmet an niver a renkennadoù (amañ a-us).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ca.js b/blockly/webif/static/blockly/demos/plane/generated/ca.js
                new file mode 100644
                index 000000000..0b45f3ebe
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ca.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Files: %1</span><span id="Plane_getRows">files (%1)</span><span id="Plane_rows1">files de primera classe: %1</span><span id="Plane_getRows1">files de primera classe (%1)</span><span id="Plane_rows2">files de segona classe: %1</span><span id="Plane_getRows2">files de segona classe (%1)</span><span id="Plane_seats">Seients: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">seients =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculadora de seients d\'avió</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un avió té un nombre de files de seients de passatgers.  Cada fila conté quatre seients.';
                +      break;
                +    case 2:
                +      output += 'Un avió té dos seients en la cabina de vol (pel pilot i pel copilot) i un nombre de files de seients de passatgers. Cada fila conté quatre seients.';
                +      break;
                +    case 3:
                +      output += 'Un avió té dos seients en la cabina de vol (pel pilot i copilot) i un nombre de files per seients de passatgers de primera classe i de segona classe. Cada fila de primera classe conté quatre seients. Cada fila de segona classe conté cinc seients.';
                +      break;
                +  }
                +  output += '</p><p>Construïu una fórmula (a sota) que calculi el nombre total de seients de l\'avió a mida que canviïn les files (a dalt).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/da.js b/blockly/webif/static/blockly/demos/plane/generated/da.js
                new file mode 100644
                index 000000000..2c7965025
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/da.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rækker: %1</span><span id="Plane_getRows">rækker (%1)</span><span id="Plane_rows1">1. klasse rækker: %1</span><span id="Plane_getRows1">1. klasse rækker (%1)</span><span id="Plane_rows2">2. klasse rækker: %1</span><span id="Plane_getRows2">2. klasse rækker (%1)</span><span id="Plane_seats">Sæder: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sæder =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Flysædelommeregner</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Et fly har et antal rækker af passagersæder. Hver række indeholder fire sæder.';
                +      break;
                +    case 2:
                +      output += 'Et fly har to pladser i cockpittet (til pilot og med-pilot), og et antal rækker af passagersæder. Hver række indeholder fire sæder.';
                +      break;
                +    case 3:
                +      output += 'Et fly har to pladser i cockpittet (til pilot og med-pilot), og et antal rækker af 1. klasses og 2. klasses passagersæder. Hver 1. klasses række indeholder fire sæder. Hver 2. klasses række indeholder fem sæder.';
                +      break;
                +  }
                +  output += '</p><p>Opbyg en formel (nedenfor), der beregner det samlede antal pladser på flyet, hvis antal rækker ændres (ovenfor).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/de.js b/blockly/webif/static/blockly/demos/plane/generated/de.js
                new file mode 100644
                index 000000000..d28d31869
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/de.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Reihen: %1</span><span id="Plane_getRows">Reihen (%1)</span><span id="Plane_rows1">Reihen der 1. Klasse: %1</span><span id="Plane_getRows1">Reihen der 1. Klasse (%1)</span><span id="Plane_rows2">Reihen der 2. Klasse: %1</span><span id="Plane_getRows2">Reihen der 2. Klasse (%1)</span><span id="Plane_seats">Sitze: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">Sitze =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Flugzeugsitzrechner</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Ein Flugzeug hat eine Anzahl an Reihen mit Passagiersitzen. Jede Reihe enthält vier Sitze.';
                +      break;
                +    case 2:
                +      output += 'Ein Flugzeug hat zwei Sitze im Pilotenstand (für den Piloten und Co-Piloten) und eine Anzahl an Reihen mit Passagiersitzen. Jede Reihe enthält vier Sitze.';
                +      break;
                +    case 3:
                +      output += 'Ein Flugzeug hat zwei Sitze im Pilotenstand (für den Piloten und Co-Piloten) und eine Anzahl an Reihen mit Passagiersitzen der 1. und 2. Klasse. Jede 1.-Klasse-Reihe enthält vier Sitze. Jede 2.-Klasse-Reihe enthält fünf Sitze.';
                +      break;
                +  }
                +  output += '</p><p>Erstelle eine Formel (unten), die die gesamte Anzahl an Sitzen im Flugzeug berechnet, wenn die Reihen (oben) geändert werden.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/el.js b/blockly/webif/static/blockly/demos/plane/generated/el.js
                new file mode 100644
                index 000000000..f8219c86a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/el.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Σειρές: %1</span><span id="Plane_getRows">σειρές (%1)</span><span id="Plane_rows1">Σειρές 1ης θέσης: %1</span><span id="Plane_getRows1">Σειρές 1ης θέσης (%1)</span><span id="Plane_rows2">Σειρές 2ης θέσης: %1</span><span id="Plane_getRows2">Σειρές 2ης θέσης (%1)</span><span id="Plane_seats">Καθίσματα: %1</span><span id="Plane_placeholder">;</span><span id="Plane_setSeats">καθίσματα =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Υπολογισμός Θέσεων Σε Αεροπλάνο</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Ένα αεροπλάνο έχει έναν συγκεκριμένο αριθμό σειρών καθισμάτων επιβατών. Κάθε σειρά έχει τέσσερα καθίσματα.';
                +      break;
                +    case 2:
                +      output += 'Ένα αεροπλάνο έχει δύο καθίσματα στον θάλαμο διακυβέρνησης (για τον κυβερνήτη και τον συγκυβερνήτη), καθώς και έναν αριθμό από σειρές καθισμάτων επιβατών.  Κάθε σειρά έχει τέσσερα καθίσματα.';
                +      break;
                +    case 3:
                +      output += 'Ένα αεροπλάνο έχει δύο καθίσματα στον θάλαμο διακυβέρνησης (για τον κυβερνήτη και τον συγκυβερνήτη), καθώς και έναν αριθμό σειρών καθισμάτων για την 1η και 2η θέση. Κάθε σειρά της 1ης θέσης έχει τέσσερα καθίσματα και κάθε σειρά της 2ης θέσης έχει πέντε καθίσματα.';
                +      break;
                +  }
                +  output += '</p><p>Φτιάξε έναν τύπο (κάτω) που θα υπολογίζει τον συνολικό αριθμό καθισμάτων του αεροπλάνου καθώς αλλάζουν οι σειρές (πάνω).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/en.js b/blockly/webif/static/blockly/demos/plane/generated/en.js
                new file mode 100644
                index 000000000..1cbfc40ef
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/en.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rows: %1</span><span id="Plane_getRows">rows (%1)</span><span id="Plane_rows1">1st class rows: %1</span><span id="Plane_getRows1">1st class rows (%1)</span><span id="Plane_rows2">2nd class rows: %1</span><span id="Plane_getRows2">2nd class rows (%1)</span><span id="Plane_seats">Seats: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">seats =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Plane Seat Calculator</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'An airplane has a number of rows of passenger seats.  Each row contains four seats.';
                +      break;
                +    case 2:
                +      output += 'An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.';
                +      break;
                +    case 3:
                +      output += 'An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.';
                +      break;
                +  }
                +  output += '</p><p>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/es.js b/blockly/webif/static/blockly/demos/plane/generated/es.js
                new file mode 100644
                index 000000000..0a3b7812d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/es.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Filas: %1</span><span id="Plane_getRows">filas (%1)</span><span id="Plane_rows1">Filas de primera clase: %1</span><span id="Plane_getRows1">Filas de primera clase: (%1)</span><span id="Plane_rows2">Filas de segunda clase: %1</span><span id="Plane_getRows2">Filas de segunda clase: (%1)</span><span id="Plane_seats">Asientos: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">asientos =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculadora de asientos de avión</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un avión  tiene un número de filas de asientos de pasajeros. Cada fila contiene cuatro asientos.';
                +      break;
                +    case 2:
                +      output += 'Un avión tiene dos asientos en la cabina de vuelo (para el piloto y co-piloto), y un número de filas de asientos de pasajeros. Cada fila contiene cuatro asientos.';
                +      break;
                +    case 3:
                +      output += 'Un avión tiene dos asientos en la cabina de vuelo (para el piloto y co-piloto), y un número de filas de asientos para pasajeros de primera y segunda clase. Cada fila de la primera clase contiene cuatro asientos. Cada fila de la segunda clase contiene cinco asientos.';
                +      break;
                +  }
                +  output += '</p><p>Construir una fórmula (abajo) que calcule el número total de asientos en el avión cuando las filas sean cambiadas (arriba).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/et.js b/blockly/webif/static/blockly/demos/plane/generated/et.js
                new file mode 100644
                index 000000000..069c7cb28
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/et.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Ridu: %1</span><span id="Plane_getRows">rows (%1)</span><span id="Plane_rows1">1. klassi ridu: %1</span><span id="Plane_getRows1">1. klassi ridu (%1)</span><span id="Plane_rows2">2. klassi ridu: %1</span><span id="Plane_getRows2">2. klassi ridu (%1)</span><span id="Plane_seats">Istmeid: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">istmete arv =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Lennukiistmete kalkulaator</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Lennukis on reisijate istmed mitmes reas. Igas reas on neli istet.';
                +      break;
                +    case 2:
                +      output += 'Lennuki kokpitis on kaks istet (üks kummalegi piloodile) ja mingi arv istemridu reisijatele. Igas reas on neli istet.';
                +      break;
                +    case 3:
                +      output += 'Lennuki kokpitis on kaks istet (üks kummalegi piloodile), mingi arv ridu 1. klassi reisijatele ja mingi arv ridu 2. klassi reisijatele. Igas 1. klassi reas on neli istet, igas 2. klassi reas viis istet.';
                +      break;
                +  }
                +  output += '</p><p>Ehita plokkidest valem, mis arvutab istmete arvu lennukis õigesti sõltumata ridade arvust (seda saad muuta lennuki juures oleva liuguriga).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/fa.js b/blockly/webif/static/blockly/demos/plane/generated/fa.js
                new file mode 100644
                index 000000000..8f31707b8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/fa.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">ردیف: %1</span><span id="Plane_getRows">ردیف\u200Cها (%1)</span><span id="Plane_rows1">اولین ردیف کلاس: %1</span><span id="Plane_getRows1">اولین کلاس ردیف\u200Cها (%1)</span><span id="Plane_rows2">دومین کلاس ردیف: %1</span><span id="Plane_getRows2">دومین کلاس ردیف\u200Cها (%1)</span><span id="Plane_seats">صندلی\u200Cها: %1</span><span id="Plane_placeholder">؟</span><span id="Plane_setSeats">صندلی\u200Cها =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">محاسبه\u200Cگر صندلی\u200Cهای هواپیما</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'یک هواپیما تعداد از صندلی\u200Cهای مسافرین را دارد. هر ردیف شمال چهار صندلی است.';
                +      break;
                +    case 2:
                +      output += 'یک هواپیما دو صندلی در عرشهٔ پرواز دارد (برای خلبان و کمک خلبان) و تعدادی صندلی مسافرین.  هر ردیف شامل چهار صندلی است.';
                +      break;
                +    case 3:
                +      output += 'یک هواپیما دو صندلی در کابین خلبان دارد (برای خلبان و کمک خلبان) و تهداد از صندلی\u200Cها مسافرین درجه یک و درجه دو.  هر ردیف درجه یک شامل چهار صندلی است. هر ردیف درجه دو شامل پنج صندلی است.';
                +      break;
                +  }
                +  output += '</p><p>یک فرمول بسازید (پایین) که تعداد کل صندلی\u200Cهای هواپیما با تغییر ردیف را حساب کند (بالا).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/fr.js b/blockly/webif/static/blockly/demos/plane/generated/fr.js
                new file mode 100644
                index 000000000..29b17e98e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/fr.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rangées : %1</span><span id="Plane_getRows">rangées (%1)</span><span id="Plane_rows1">rangées de première classe : %1</span><span id="Plane_getRows1">rangées de première classe (%1)</span><span id="Plane_rows2">rangées de seconde classe : %1</span><span id="Plane_getRows2">rangées de seconde classe (%1)</span><span id="Plane_seats">Sièges : %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sièges =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculateur de sièges d’avion</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un avion a un nombre de rangées de sièges passager. Chaque rangée contient quatre sièges.';
                +      break;
                +    case 2:
                +      output += 'Un avion a deux sièges dans le poste de pilotage (pour le pilote et le copilote), et un certain nombre de rangées de sièges passager. Chaque rangée contient quatre sièges.';
                +      break;
                +    case 3:
                +      output += 'Un avion a deux sièges dans la cabine de pilotage (pour le pilote et le copilote), et un certain nombre de rangées de sièges passager de première et seconde classes. Chaque rangée de première classe contient quatre sièges. Chaque rangée de seconde classe contient cinq sièges.';
                +      break;
                +  }
                +  output += '</p><p>Construire une formule (ci-dessous) qui calcule le nombre total de sièges dans l’avion quand le nombre de rangées est modifié (ci-dessus).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/he.js b/blockly/webif/static/blockly/demos/plane/generated/he.js
                new file mode 100644
                index 000000000..40d73a554
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/he.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">שורות: %1</span><span id="Plane_getRows">שורות (%1)</span><span id="Plane_rows1">שורות במחלקה ראשונה: %1</span><span id="Plane_getRows1">שורות במחלקה ראשונה (%1)</span><span id="Plane_rows2">שורות במחלקה שנייה: %1</span><span id="Plane_getRows2">שורות במחלקה שנייה: (%1)</span><span id="Plane_seats">מושבים: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">מושבים =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">מחשבון מושב במטוס</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'במטוס יש מספר שורות עם מושבי נוסעים. בכל שורה יש ארבעה מושבים.';
                +      break;
                +    case 2:
                +      output += 'במטוס יש שני מושבים עבור הצוות (בשביל הטייס וטייס המשנה), ומספר שורות עם מושבי נוסעים. בכל שורה יש ארבעה מושבים.';
                +      break;
                +    case 3:
                +      output += 'במטוס יש שני מושבים עבור הצוות (בשביל הטייס וטייס המשנה), ומספר שורות מושבים במחלקת הנוסעים הראשונה ובמחלקת הנוסעים השנייה. כל שורה במחלקה הראשונה מכילה ארבעה מושבים. כל שורה במחלקה השנייה מכילה חמישה מושבים.';
                +      break;
                +  }
                +  output += '</p><p>בנה נוסחה (למטה) אשר תחשב את סך כל המושבים במטוס בהתאם לשינוי מספר השורות (למעלה).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/hrx.js b/blockly/webif/static/blockly/demos/plane/generated/hrx.js
                new file mode 100644
                index 000000000..6e356147f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/hrx.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Reihe: %1</span><span id="Plane_getRows">Reihe (%1)</span><span id="Plane_rows1">Reihe von der 1. Klasse: %1</span><span id="Plane_getRows1">Reihe von der 1. Klasse (%1)</span><span id="Plane_rows2">Reihe von der 2. Klasse: %1</span><span id="Plane_getRows2">Reihe von der 2. Klasse (%1)</span><span id="Plane_seats">Sitz: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">Sitze =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Fluchzeichsitzrechner</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'En Fluchzeich hot en Oonzohl an Reihe mit Passagiersitze. Jede Reih enthält vier Sitze.';
                +      break;
                +    case 2:
                +      output += 'En Fluchzeich hot zwooi Sitze im Pilotestand (für den Pilot und Co-Pilot) und en Oonzohl an Reihe mit Passagiersitze. Jede Reih enthält vier Sitze.';
                +      break;
                +    case 3:
                +      output += 'En Fluchzeich hot zwooi Sitze im Pilotstand (für den Pilot und Co-Pilot) und en Oonzohl an Reihe mit Passagiersitze der 1. und 2. Klasse. Jede 1.-Klasse-Reih enthält vier Sitze. Jede 2.-Klasse-Reih enthält fünf Sitze.';
                +      break;
                +  }
                +  output += '</p><p>Erstell en Formel (unne), die die gesamte Oonzohl an Sitze im Fluchzeich berechnet, wenn die Reihe (uwe) geännert sin.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/hu.js b/blockly/webif/static/blockly/demos/plane/generated/hu.js
                new file mode 100644
                index 000000000..67181e76e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/hu.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Sorok száma: %1</span><span id="Plane_getRows">Sorok száma (%1)</span><span id="Plane_rows1">1. osztály: %1 sor</span><span id="Plane_getRows1">1. osztály sorai (%1)</span><span id="Plane_rows2">2. osztály: %1 sor</span><span id="Plane_getRows2">2. osztály sorai (%1)</span><span id="Plane_seats">Ülések száma összesen: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">Ülések száma =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Repülőgép alkalmazás</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Egy repülőgépen az utasok több sorban ülnek az utastérben.  Az utastér minden sorában négy szék van.';
                +      break;
                +    case 2:
                +      output += 'Egy repülőgépnek 2 ülése van a pilótafülkében (a pilótának és a másodpilótának), az utasok több sorban ülnek az utastérben.  Az utastér minden sorában négy szék van.';
                +      break;
                +    case 3:
                +      output += 'Egy repülőgépnek 2 ülése van a pilótafülkében (a pilótának és a másodpilótának), az utasok 1. és 2. osztályon utazhatnak. Az 1. osztályon négy szék van egy sorban. A 2. osztályon öt szék van egy sorban.';
                +      break;
                +  }
                +  output += '</p><p>Készítsd el a képletet (lent) amivel kiszámolható, hogy hány ülés van összesen a repülőgépen annak függvényében, ahogy (fent) állítod a sorok számát.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ia.js b/blockly/webif/static/blockly/demos/plane/generated/ia.js
                new file mode 100644
                index 000000000..50b6dc859
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ia.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Filas: %1</span><span id="Plane_getRows">filas (%1)</span><span id="Plane_rows1">Filas de prime classe: %1</span><span id="Plane_getRows1">filas de prime classe (%1)</span><span id="Plane_rows2">Filas de secunde classe: %1</span><span id="Plane_getRows2">filas de secunde classe (%1)</span><span id="Plane_seats">Sedes: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sedes =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculator de sedias de avion</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un avion ha un numero de filas de sedes pro passageros. Cata fila contine quatro sedes.';
                +      break;
                +    case 2:
                +      output += 'Un avion ha duo sedes in le cabina (pro le pilota e le copilota) e un numero de filas de sedes pro passageros. Cata fila contine quatro sedes.';
                +      break;
                +    case 3:
                +      output += 'Un avion ha duo sedes in le cabina (pro le pilota e le copilota) e un numero de filas de sedes pro passageros del prime classe e del secunde classes. Cata fila del prime classe contine quatro sedes. Cata fila del secunde classe contine cinque sedes.';
                +      break;
                +  }
                +  output += '</p><p>Construe un formula (ci infra) que calcula le numero total de sedes in le avion quando le numero de filas es cambiate (ci supra).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/is.js b/blockly/webif/static/blockly/demos/plane/generated/is.js
                new file mode 100644
                index 000000000..e221c97fe
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/is.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Raðir: %1</span><span id="Plane_getRows">raðir (%1)</span><span id="Plane_rows1">Raðir 1. farrými: %1</span><span id="Plane_getRows1">raðir 1. farrými (%1)</span><span id="Plane_rows2">Raðir 2. farrými: %1</span><span id="Plane_getRows2">raðir 2. farrými (%1)</span><span id="Plane_seats">Sæti: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sæti =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Flugsætareiknir</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Flugvél er með einhvern fjölda sætaraða fyrir farþega. Í hverri röð eru fjögur sæti.';
                +      break;
                +    case 2:
                +      output += 'Flugvél er með tvö sæti í stjórnklefa (fyrir flugmanninn og aðstoðarflugmanninn) og einhvern fjölda sætaraða fyrir farþega. Hver sætaröð hefur fjögur sæti.';
                +      break;
                +    case 3:
                +      output += 'Flugvél er með tvö sæti í stjórnklefa (fyrir flugmanninn og aðstoðarflugmanninn) og einhvern fjölda sætaraða fyrir farþega á 1. og 2. farrými. Hver sætaröð á 1. farrými hefur fjögur sæti. Hver sætaröð á 2. farrými hefur fimm sæti.';
                +      break;
                +  }
                +  output += '</p><p>Búðu til formúlu (hér fyrir neðan) sem reiknar heildarfjölda sæta í flugvélinni eftir því sem röðunum er breytt (hér fyrir ofan).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/it.js b/blockly/webif/static/blockly/demos/plane/generated/it.js
                new file mode 100644
                index 000000000..4a7133716
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/it.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">File: %1</span><span id="Plane_getRows">file (%1)</span><span id="Plane_rows1">File 1ª classe: %1</span><span id="Plane_getRows1">file 1ª classe (%1)</span><span id="Plane_rows2">File 2ª classe: %1</span><span id="Plane_getRows2">File 2ª classe (%1)</span><span id="Plane_seats">Sedili: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sedili =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calcolo posti aereo</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un aeroplano ha un numero di file contenenti i posti a sedere dei passeggeri. Ogni fila, contiene quattro posti a sedere.';
                +      break;
                +    case 2:
                +      output += 'Un aeroplano ha due posti a sedere nella cabina di pilotaggio (per il pilota e co-pilota), e un numero di file con i posti a sedere dei passeggeri. Ogni fila contiene quattro posti.';
                +      break;
                +    case 3:
                +      output += 'Un aereo ha due posti nella cabina di pilotaggio (per il pilota e il co-pilota), e un numero di file in prima e seconda classe, con i posti a sedere dei passeggeri. Ogni fila della prima classe contiene quattro posti. Quelle invece della seconda classe, ne contengono cinque.';
                +      break;
                +  }
                +  output += '</p><p>Costruisci una formula (sotto) che calcola il numero totale di posti a sedere su un aeroplano, così come cambiano le file di posti (sopra).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ja.js b/blockly/webif/static/blockly/demos/plane/generated/ja.js
                new file mode 100644
                index 000000000..86bac971e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ja.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">列の数: %1</span><span id="Plane_getRows">列の数 (%1)</span><span id="Plane_rows1">ファーストクラスの列数: %1</span><span id="Plane_getRows1">ファーストクラスの列数 (%1)</span><span id="Plane_rows2">セカンドクラスの列数: %1</span><span id="Plane_getRows2">セカンドクラスの列数 (%1)</span><span id="Plane_seats">座席の数: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">座席の数 =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">飛行機座席計算機</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += '飛行機に乗客の座席の列があります。それぞれの列に 4 つの座席があります。';
                +      break;
                +    case 2:
                +      output += '飛行機には、操縦室の 2 つの座席 (操縦士と副操縦士) と、乗客の座席の列があります。それぞれの列に 4 つの座席があります。';
                +      break;
                +    case 3:
                +      output += '飛行機には、操縦室の 2 つの座席 (操縦士と副操縦士) と、ファーストクラスとセカンドクラスの乗客の座席の列があります。それぞれの列に、ファーストクラスでは 4 つの座席、セカンドクラスでは 5 つの座席があります。';
                +      break;
                +  }
                +  output += '</p><p>飛行機の座席の数を計算する式を、上で列の数を変更しても正しくなるように、下に入力してください。</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ko.js b/blockly/webif/static/blockly/demos/plane/generated/ko.js
                new file mode 100644
                index 000000000..464f63ff6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ko.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">행 수: %1</span><span id="Plane_getRows">행 수 (%1)</span><span id="Plane_rows1">1등석 행 수: %1</span><span id="Plane_getRows1">1등석 행 수 (%1)</span><span id="Plane_rows2">2등석 행 수: %1</span><span id="Plane_getRows2">2등석 행 수 (%1)</span><span id="Plane_seats">좌석 수: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">좌석수 =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">비행기 좌석 계산기</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += '비행기는 승객 좌석의 행 수가 있습니다. 각 행에는 시트 네 개가 포함되어 있습니다.';
                +      break;
                +    case 2:
                +      output += '비행기는 비행 갑판(조종사와 부조종사용)에서 좌석 두 개가 있고, 승객 좌석의 행 수가 있습니다. 각 행에는 시트 네 개가 포함되어 있습니다.';
                +      break;
                +    case 3:
                +      output += '비행기는 비행 갑판(조종사와 부조종사용)에서 좌석 두 개가 있고, 1등석과 2등석 승객 좌석의 행 수가 있습니다. 각 1등석 행에는 시트 네 개가 포함되어 있습니다. 각 2등석 행에는 시트 다섯 개가 포함되어 있습니다.';
                +      break;
                +  }
                +  output += '</p><p>행이 바뀐(위) 비행기에 좌석의 총 수를 계산하는 공식(아래)을 구축하세요.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ms.js b/blockly/webif/static/blockly/demos/plane/generated/ms.js
                new file mode 100644
                index 000000000..1a9a447da
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ms.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Baris: %1</span><span id="Plane_getRows">baris (%1)</span><span id="Plane_rows1">Baris kelas pertama: %1</span><span id="Plane_getRows1">baris kelas pertama (%1)</span><span id="Plane_rows2">Baris kelas kedua: %1</span><span id="Plane_getRows2">baris kelas kedua (%1)</span><span id="Plane_seats">Tempat duduk: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">tempat duduk =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Pengira Tempat Duduk Kapal Terbang</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Sebuah kapal terbang mempunyai sebilangan baris tempat duduk penumpang. Setiap baris mengandungi empat tempat duduk.';
                +      break;
                +    case 2:
                +      output += 'Sebuah kapal terbang mempunyai tempat duduk di kokpit (untuk juruterbang dan pembantunya) dan sebilangan baris tempat duduk penumpang. Setiap baris mengandungi empat tempat duduk.';
                +      break;
                +    case 3:
                +      output += 'Sebuah kapal terbang mempunyai tempat duduk di kokpit (untuk juruterbang dan pembantunya) dan sebilangan baris tempat duduk penumpang kelas pertama dan kelas kedua. Setiap baris kelas pertama mengandungi empat tempat duduk. Setiap baris kelas pertama mengandungi lima tempat duduk.';
                +      break;
                +  }
                +  output += '</p><p>Wujudkan formula (di bawah) yang mengira jumlah tempat duduk di dalam kapal terbang sedangkan baris-barisnya diubah (di atas).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/nb.js b/blockly/webif/static/blockly/demos/plane/generated/nb.js
                new file mode 100644
                index 000000000..c71cba543
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/nb.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rader: %1</span><span id="Plane_getRows">rader (%1)</span><span id="Plane_rows1">Rader i første klasse: %1</span><span id="Plane_getRows1">Rader i første klasse (%1)</span><span id="Plane_rows2">Rader i andre klasse: %1</span><span id="Plane_getRows2">Rader i andre klasse (%1)</span><span id="Plane_seats">Seter: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">seter =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Flysetekalkulator</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Et fly har et antall rader med passasjerseter. Hver rad inneholder fire seter.';
                +      break;
                +    case 2:
                +      output += 'Et fly har to seter i cockpit (for piloten og andrepiloten), og et antall rader med passasjerseter. Hver rad inneholder fire seter.';
                +      break;
                +    case 3:
                +      output += 'Et fly har to seter i cockpit (for piloten og andrepiloten), og et antall rader med passasjerseter på første og andre klasse. Hver av radene på første klasse har fire seter. Hver av radene på andre klasse har fem seter.';
                +      break;
                +  }
                +  output += '</p><p>Bygg en formel (under) som beregner det totale antall seter på flyet etter hvert som radene endres (over).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/nl.js b/blockly/webif/static/blockly/demos/plane/generated/nl.js
                new file mode 100644
                index 000000000..edad19f6d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/nl.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rijen: %1</span><span id="Plane_getRows">rijen (%1)</span><span id="Plane_rows1">Rijen 1e klas: %1</span><span id="Plane_getRows1">Rijen 1e klas (%1)</span><span id="Plane_rows2">Rijen 2e klas: %1</span><span id="Plane_getRows2">Rijen 2e klas (%1)</span><span id="Plane_seats">Zitplaatsen: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">stoelen=</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Vliegtuigstoelencalculator</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Een vliegtuig heeft een aantal rijen met stoelen. Iedere rij heeft vier stoelen.';
                +      break;
                +    case 2:
                +      output += 'Een vliegtuig heeft twee stoelen in de cockpit (voor de piloot en de copiloot) en een aantal rijen met stoelen voor passagiers. Iedere rij bevat vier stoelen.';
                +      break;
                +    case 3:
                +      output += 'Een vliegtuig heeft twee stoelen in de cockpit (voor de piloot en de copiloot) en een aantal rijen voor 1e klasse en 2e klasse passagiers. Iedere rij in de 1e klasse heeft vier stoelen. Iedere rij in de 2e klasse heeft vijf stoelen.';
                +      break;
                +  }
                +  output += '</p><p>Maak hieronder een formule die het totale aantal stoelen in het vliegtuig berekent als het aantal rijen hierboven wordt aangepast.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/pl.js b/blockly/webif/static/blockly/demos/plane/generated/pl.js
                new file mode 100644
                index 000000000..14b5ee6a1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/pl.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rzędów: %1</span><span id="Plane_getRows">rzędów (%1)</span><span id="Plane_rows1">Rzędów w pierwszej klasie: %1</span><span id="Plane_getRows1">Rzędów w pierwszej klasie (%1)</span><span id="Plane_rows2">Rzędów w drugiej klasie: %1</span><span id="Plane_getRows2">Rzędów w drugiej klasie (%1)</span><span id="Plane_seats">Siedzeń: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">siedzeń =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Kalkulator miejsc w samolocie.</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Samolot ma kilka rzędów siedzeń pasażerów. Każdy rząd zawiera cztery miejsca.';
                +      break;
                +    case 2:
                +      output += 'Samolot ma dwa miejsca w kabinie pilotów (dla pierwszego i drugiego pilota) oraz rzędy siedzeń dla pasażerów. Każdy taki rząd składa się z czterech siedzeń.';
                +      break;
                +    case 3:
                +      output += 'Samolot ma dwa miejsca w kabinie pilotów (dla pierwszego i drugiego pilota) oraz rzędy siedzeń dla pasażerów pierwszej i drugiej klasy. Każdy rząd pierwszej klasy składa się z czterech siedzeń. Każdy rząd drugiej klasy składa się z pięciu siedzeń.';
                +      break;
                +  }
                +  output += '</p><p>Zbuduj wzór (poniżej), który pozwala obliczyć łączną liczbę siedzeń w samolocie w funkcji zmieniającej się liczby rzędów (powyżej).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/pms.js b/blockly/webif/static/blockly/demos/plane/generated/pms.js
                new file mode 100644
                index 000000000..df45f2277
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/pms.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Linie: %1</span><span id="Plane_getRows">linie (%1)</span><span id="Plane_rows1">linie ëd prima classa: %1</span><span id="Plane_getRows1">linie ëd prima classa (%1)</span><span id="Plane_rows2">linie ëd seconda classa: %1</span><span id="Plane_getRows2">linie ëd seconda classa (%1)</span><span id="Plane_seats">Sedij: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">sedij =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calcolator ëd sedij d\'avion</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'N\'avion a l\'ha un nùmer ëd file ëd sedij da passëgé. Minca fila a l\'ha quatr sedij.';
                +      break;
                +    case 2:
                +      output += 'N\'avion a l\'ha doi sedij ant la cabin-a ëd pilotage (për ël pilòta e ël cò-pilòta), e un chèich nùmer ëd file ëd sedij pr\'ij passagé. Minca fila a conten quatr sedij.';
                +      break;
                +    case 3:
                +      output += 'N\'avion a l\'ha doi sedij ant la cabin-a ëd pilotage (për ël pilòta e ël cò-pilòta) e un chèich nùmer ëd file ëd sedij pr\'ij passagé ëd prima e sconda classa. Minca fila ëd prima classa a conten quatr sedij. Minca fila ëd seconda classa a conten sinch sedij.';
                +      break;
                +  }
                +  output += '</p><p>Fabriché na fórmola (sì-sota) ch\'a fa \'l cont dël nùmer total ëd sedij ant l\'avion cand che ël nùmer dle file a cangia (sì-dzora).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/pt-br.js b/blockly/webif/static/blockly/demos/plane/generated/pt-br.js
                new file mode 100644
                index 000000000..2e96d38ee
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/pt-br.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Filas: %1</span><span id="Plane_getRows">filas (%1)</span><span id="Plane_rows1">filas na primeira classe: %1</span><span id="Plane_getRows1">filas na primeira classe (%1)</span><span id="Plane_rows2">filas na segunda classe: %1</span><span id="Plane_getRows2">filas na segunda classe (%1)</span><span id="Plane_seats">Assentos: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">assentos =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculadora de Assentos em Avião</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Um avião tem um número de filas de assentos para os passageiros. Cada fila contém quatro assentos.';
                +      break;
                +    case 2:
                +      output += 'Um avião tem dois assentos na cabine de comando (para o piloto e o copiloto) e um número de filas de assentos para os passageiros. Cada fila contém quatro assentos.';
                +      break;
                +    case 3:
                +      output += 'Um avião tem dois assentos na cabine de comando (para o piloto e o copiloto) e um número de filas de assentos na primeira e na segunda classe. Cada fila da primeira classe contém quatro assentos. Cada fila da segunda classe contém cinco assentos.';
                +      break;
                +  }
                +  output += '</p><p>Elabore uma fórmula (abaixo) que calcule o número total de assentos no avião a medida que as filas são alteradas (acima).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ro.js b/blockly/webif/static/blockly/demos/plane/generated/ro.js
                new file mode 100644
                index 000000000..426a571fc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ro.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rânduri: %1</span><span id="Plane_getRows">rânduri (%1)</span><span id="Plane_rows1">rânduri de clasa I: %1</span><span id="Plane_getRows1">rânduri de clasa I (%1)</span><span id="Plane_rows2">rânduri de clasa a II-a: %1</span><span id="Plane_getRows2">rânduri de clasa a II-a (%1)</span><span id="Plane_seats">Scaune: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">scaune =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Calculator pentru locurile dintr-un avion</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Un avion are un număr de rânduri cu scaune pentru pasageri. Fiecare rând conține patru scaune.';
                +      break;
                +    case 2:
                +      output += 'Un avion are două scaune în carlingă (pentru pilot și copilot) și un număr de rânduri cu scaune pentru pasageri. Fiecare rând conține patru scaune.';
                +      break;
                +    case 3:
                +      output += 'Un avion are două scaune în carlingă (pentru pilot și copilot) și un număr de rânduri cu scaune de clasa I și clasa a II-a pentru pasageri. Fiecare rând de clasa I conține patru scaune. Fiecare rând de clasa a II-a conține cinci scaune.';
                +      break;
                +  }
                +  output += '</p><p>Construiește o formulă (mai jos) care calculează numărul total de locuri dintr-un avion în timp ce rândurile se schimbă (mai sus).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/ru.js b/blockly/webif/static/blockly/demos/plane/generated/ru.js
                new file mode 100644
                index 000000000..78f384b46
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/ru.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Рядов: %1</span><span id="Plane_getRows">ряды (%1)</span><span id="Plane_rows1">Рядов 1-го класса: %1</span><span id="Plane_getRows1">ряды 1-го класса (%1)</span><span id="Plane_rows2">Рядов 2-го класса: %1</span><span id="Plane_getRows2">ряды 2-го класса (%1)</span><span id="Plane_seats">Мест: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">места =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Калькулятор посадочных мест в самолёте</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'В самолёте несколько рядов с пассажирскими местами. В каждом ряду 4 места.';
                +      break;
                +    case 2:
                +      output += 'В самолёте 2 места для пилота и его помощника, а также несколько рядов с пассажирскими местами. В каждом ряду 4 места.';
                +      break;
                +    case 3:
                +      output += 'В самолёте 2 места для пилота и его помощника, несколько рядов с пассажирскими местами первого класса, а также несколько рядов с пассажирскими местами второго класса. В каждом ряду первого класса 4 места. В каждом ряду второго класса 5 мест.';
                +      break;
                +  }
                +  output += '</p><p>Постройте формулу в области ниже, которая поможет рассчитать общее количество мест в самолёте (как на рисунке выше).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/sc.js b/blockly/webif/static/blockly/demos/plane/generated/sc.js
                new file mode 100644
                index 000000000..453c5e796
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/sc.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Fileras: %1</span><span id="Plane_getRows">fileras (%1)</span><span id="Plane_rows1">fileras de primu classi: %1</span><span id="Plane_getRows1">fileras de primu classi (%1)</span><span id="Plane_rows2">fileras de segunda classi: %1</span><span id="Plane_getRows2">fileras de segunda classi (%1)</span><span id="Plane_seats">Cadironis: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">cadironis =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Fai su contu de is cadironis de unu aparèchiu</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Unu aparèchiu tenit unas cantu fileras de cadironis po passigeris. Dònnia filera tenit cuatru cadironis.';
                +      break;
                +    case 2:
                +      output += 'Unu aparèchiu tenit duus cadironis in sa cabina de cumandu (po su pilota e su co-pilota), e unas cantu fileras de cadironis po passigeris. Dònnia filera tenit cuatru cadironis.';
                +      break;
                +    case 3:
                +      output += 'Unu aparèchiu tenit duus cadironis in sa cabina de cumandu (po su pilota e su co-pilota), e unas cantu fileras de cadironis po passigeris de prima classi e de segunda classi. Dònnia filera de prima classi tenit cuatru cadironis. Dònnia filera de segunda classi tenit cincu cadironis.';
                +      break;
                +  }
                +  output += '</p><p>Cuncorda una formula (innoi asuta) chi cumpudit su numeru totali de postus a setzi in s\'aparechiu, a segunda de comenti mudant is fileras de postus (innoi in susu)</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/sv.js b/blockly/webif/static/blockly/demos/plane/generated/sv.js
                new file mode 100644
                index 000000000..acba58c02
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/sv.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Rader: %1</span><span id="Plane_getRows">rader (%1)</span><span id="Plane_rows1">Rader i första klass: %1</span><span id="Plane_getRows1">Rader i första klass (%1)</span><span id="Plane_rows2">Rader i andra klass: %1</span><span id="Plane_getRows2">Rader i andra klass (%1)</span><span id="Plane_seats">Säten: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">säten =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Plansäteskalkylator</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Ett flygplan har ett antal rader med passagerarsäten. Varje rad innehåller fyra säten.';
                +      break;
                +    case 2:
                +      output += 'Ett flygplan har två säten i cockpiten (ett för piloten och ett för andrepiloten) och ett antal rader med passagerarsäten. Varje rad innehåller fyra säten.';
                +      break;
                +    case 3:
                +      output += 'Ett flygplan har två säten i cockpiten (ett för piloten och ett för andrepiloten) och ett antal rader med passagerarsäten i första och andra klass. Varje rad i första klass innehåller fyra säten. Varje rad i andra klass innehåller fem säten.';
                +      break;
                +  }
                +  output += '</p><p>Bygg en formel (nedan) som beräknar det totala antalet säten på flygplanet när raderna ändras (ovan).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/th.js b/blockly/webif/static/blockly/demos/plane/generated/th.js
                new file mode 100644
                index 000000000..bfa8621ab
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/th.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">%1 แถว</span><span id="Plane_getRows">จำนวนแถว (%1)</span><span id="Plane_rows1">ชั้นเฟิร์สคลาส %1 แถว</span><span id="Plane_getRows1">จำนวนแถวชั้นเฟิร์สคลาส (%1)</span><span id="Plane_rows2">ชั้นธุรกิจ %1 แถว</span><span id="Plane_getRows2">จำนวนแถวชั้นธุรกิจ (%1)</span><span id="Plane_seats">คำนวณได้ทั้งหมด %1 ที่นั่ง</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">จำนวนที่นั่ง =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">ระบบคำนวณที่นั่งบนเครื่องบิน</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'ภายในเครื่องบินประกอบไปด้วยแถวของที่นั่งผู้โดยสาร ในแต่ละแถวจะมี 4 ที่นั่ง';
                +      break;
                +    case 2:
                +      output += 'ภายในเครื่องบินจะมีที่นั่งนักบินอยู่ 2 ที่ (สำหรับนักบิน และผู้ช่วยนักบิน) และมีแถวที่นั่งผู้โดยสารอยู่จำนวนหนึ่ง ในแต่ละแถวจะมี 4 ที่นั่ง';
                +      break;
                +    case 3:
                +      output += 'ภายในเครื่องบินจะมีที่นั่งนักบินอยู่ 2 ที่ (สำหรับนักบิน และผู้ช่วยนักบิน) และจะมีแถวที่นั่งสำหรับผู้โดยสาร "ชั้นเฟิร์สคลาส" และ "ชั้นธุรกิจ" อยู่จำนวนหนึ่ง โดยในชั้นเฟิร์สคลาสจะมีแถวละ 4 ที่นั่ง ส่วนในชั้นธุรกิจจะมีแถวละ 5 ที่นั่ง';
                +      break;
                +  }
                +  output += '</p><p>สร้างสูตรคำนวณ (ด้านล่าง) เพื่อคำนวณหาจำนวนที่นั่งทั้งหมดบนเครื่องบิน ตามจำนวนแถวที่เปลี่ยนไป (ด้านบน)</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/tr.js b/blockly/webif/static/blockly/demos/plane/generated/tr.js
                new file mode 100644
                index 000000000..e1bb1348a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/tr.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Sıralar: %1</span><span id="Plane_getRows">sıralar (%1)</span><span id="Plane_rows1">Birinci sınıf sıralar: (%1)</span><span id="Plane_getRows1">Birinci sınıf sıralar (%1)</span><span id="Plane_rows2">İkinci sınıf sıralar: %1</span><span id="Plane_getRows2">İkinci sınıf sıralar (%1)</span><span id="Plane_seats">Koltuklar: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">koltuklar =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Uçak Koltuğu Hesaplayıcı</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Bir uçağın belirli sayıda koltuk sırası vardır. Her sıra dört koltuk içerir.';
                +      break;
                +    case 2:
                +      output += 'Bir uçağın uçuş güvertesinde iki koltuğu (pilot ve yardımcı pilot için), ve belirli sayıda koltuk sırası vardır. Her sıra dört koltuk içerir.';
                +      break;
                +    case 3:
                +      output += 'Bir uçağın uçuş güvertesinde iki koltuğu (pilot ve yardımcı pilot için), ve belirli sayıda birinci sınıf ve ikinci sınıf yolcu koltuğu sırası vardır. Her birinci sınıf sıra dört koltuk içerir. Her ikinci sınıf sıra beş koltuk içerir.';
                +      break;
                +  }
                +  output += '</p><p>Sıralar(üstte) değiştikçe uçaktaki toplam koltuk sayısını hesaplayan bir formül(altta) oluşturun.</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/uk.js b/blockly/webif/static/blockly/demos/plane/generated/uk.js
                new file mode 100644
                index 000000000..047adfcd8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/uk.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Рядки: %1</span><span id="Plane_getRows">рядки (%1)</span><span id="Plane_rows1">рядів 1-го класу: %1</span><span id="Plane_getRows1">рядів 1-го класу (%1)</span><span id="Plane_rows2">рядів 2-го класу: %1</span><span id="Plane_getRows2">рядів 2-го класу (%1)</span><span id="Plane_seats">Місць: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">місць=</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Калькулятор місць у літаку</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Літак має кілька рядів пасажирських сидінь. Кожен ряд містить чотири місця.';
                +      break;
                +    case 2:
                +      output += 'Літак має два місця в кабіні екіпажу (пілот і другий пілот), і кілька рядів пасажирських сидінь. Кожен рядок містить чотири місця.';
                +      break;
                +    case 3:
                +      output += 'Літак має два місця в кабіні екіпажу (пілот і другий пілот), і кілька рядів 1-го класу 2-го класу пасажирських місць. Кожний ряд 1-го класу містить чотири місця. Кожен ряд 2-го класу містить п\'ять місць.';
                +      break;
                +  }
                +  output += '</p><p>Побудувати формулу (нижче), яка обчислює кількість місць на літаку при зміні рядків (див. вище).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/vi.js b/blockly/webif/static/blockly/demos/plane/generated/vi.js
                new file mode 100644
                index 000000000..61dc24ab6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/vi.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">Số hàng ghế: %1</span><span id="Plane_getRows">đếm số hàng ghế (%1)</span><span id="Plane_rows1">Hàng hạng nhất: %1</span><span id="Plane_getRows1">số hàng hạng nhất (%1)</span><span id="Plane_rows2">Hàng hạng hai: %1</span><span id="Plane_getRows2">số hàng hạng hai (%1)</span><span id="Plane_seats">Số chỗ ngồi: %1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">Tính số chỗ ngồi =</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">Máy bay ghế máy tính</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += 'Máy bay có một số hàng ghế hành khách.  Mỗi hàng có bốn chỗ ngồi.';
                +      break;
                +    case 2:
                +      output += 'Một máy bay có hai ghế trong buồng lái (dành cho phi công trưởng và phi công phụ), và một loạt hàng ghế cho hành khách. Mỗi hàng có bốn ghế (bốn chỗ ngồi).';
                +      break;
                +    case 3:
                +      output += 'Một chiếc máy bay này có hai chỗ ngồi ở sàn (cho phi công trưởng và phi công phó), và một số hàng ghế hạng 1 và hạng 2.  Mỗi hàng hạng 1 có bốn chỗ ngồi. Mỗi hàng hạng 2 có năm chỗ ngồi.';
                +      break;
                +  }
                +  output += '</p><p>Dưới đây hãy tạo công thức tính số chỗ ngồi trên máy bay để nó thay đổi tùy theo số lượng hàng ghế (hình trên).</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/zh-hans.js b/blockly/webif/static/blockly/demos/plane/generated/zh-hans.js
                new file mode 100644
                index 000000000..d8ea3d3b9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/zh-hans.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">行:%1</span><span id="Plane_getRows">行 (%1)</span><span id="Plane_rows1">头等行:%1</span><span id="Plane_getRows1">头等行(%1)</span><span id="Plane_rows2">经济等行:%1</span><span id="Plane_getRows2">经济等行(%1)</span><span id="Plane_seats">座位:%1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">座位=</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">飞机座位计算器</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += '一架飞机有一定量行数的乘客座位,每行共四座。';
                +      break;
                +    case 2:
                +      output += '一架飞机除了有两个座位供正副驾驶员,还有一定量行数的乘客座位。每行共四座。';
                +      break;
                +    case 3:
                +      output += '一架飞机除了有两个座位供正副驾驶员,还有一定量行数的头等及经济乘客座位。头等每行共四座,经济每行共五座。';
                +      break;
                +  }
                +  output += '</p><p>于下方写出一条公式以计算飞机上的座位总数。</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/generated/zh-hant.js b/blockly/webif/static/blockly/demos/plane/generated/zh-hant.js
                new file mode 100644
                index 000000000..a85010ef7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/generated/zh-hant.js
                @@ -0,0 +1,37 @@
                +// This file was automatically generated from template.soy.
                +// Please don't edit this file by hand.
                +
                +if (typeof planepage == 'undefined') { var planepage = {}; }
                +
                +
                +planepage.messages = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<div style="display: none"><span id="Plane_rows">排:%1</span><span id="Plane_getRows">排(%1)</span><span id="Plane_rows1">頭等艙:%1 排</span><span id="Plane_getRows1">頭等艙(%1)</span><span id="Plane_rows2">經濟艙:%1 排</span><span id="Plane_getRows2">經濟艙(%1)</span><span id="Plane_seats">座位:%1</span><span id="Plane_placeholder">?</span><span id="Plane_setSeats">座位=</span></div>';
                +};
                +
                +
                +planepage.start = function(opt_data, opt_ignored, opt_ijData) {
                +  var output = planepage.messages(null, null, opt_ijData) + '<table width="100%"><tr><td><h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt; <a href="../index.html">Demos</a>&rlm; &gt; <span id="title">飛機座位計算器</span> &nbsp; ';
                +  var iLimit37 = opt_ijData.maxLevel + 1;
                +  for (var i37 = 1; i37 < iLimit37; i37++) {
                +    output += ' ' + ((i37 == opt_ijData.level) ? '<span class="tab" id="selected">' + soy.$$escapeHtml(i37) + '</span>' : (i37 < opt_ijData.level) ? '<a class="tab previous" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>' : '<a class="tab" href="?lang=' + soy.$$escapeHtml(opt_ijData.lang) + '&level=' + soy.$$escapeHtml(i37) + '">' + soy.$$escapeHtml(i37) + '</a>');
                +  }
                +  output += '</h1></td><td class="farSide"><span ' + ((opt_ijData.lang == 'en') ? 'id="languageBorder"' : '') + ' style="padding: 10px"><select id="languageMenu"></select></span></td></tr></table><script src="slider.js"><\/script><svg id="plane" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="320" viewBox="0 110 600 320"><defs><g id="row1st"><rect class="seat1st" width="10" height="10" x="75" y="243" /><rect class="seat1st" width="10" height="10" x="75" y="254" /><rect class="seat1st" width="10" height="10" x="75" y="272" /><rect class="seat1st" width="10" height="10" x="75" y="283" /></g><g id="row2nd"><rect class="seat2nd" width="10" height="8" x="75" y="243" /><rect class="seat2nd" width="10" height="8" x="75" y="251" /><rect class="seat2nd" width="10" height="8" x="75" y="269" /><rect class="seat2nd" width="10" height="8" x="75" y="277" /><rect class="seat2nd" width="10" height="8" x="75" y="285" /></g><linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" style="stop-color:#fff;stop-opacity:0" /><stop offset="100%" style="stop-color:#fff;stop-opacity:1" /></linearGradient></defs><path d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z" id="wing" /><path d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z" id="tail" /><path d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z" id="fuselage" /><rect width="610" height="100" x="-5" y="110" fill="url(#grad1)" /><rect width="610" height="100" x="-5" y="330" fill="url(#grad2)" /><text id="row1stText" x="55" y="380"></text><text id="row2ndText" x="55" y="420"></text><text x="55" y="210"><tspan id="seatText"></tspan><tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan><tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan></text>' + ((opt_ijData.level > 1) ? '<rect id="crew_right" class="crew" width="10" height="10" x="35" y="254" /><rect id="crew_left" class="crew" width="10" height="10" x="35" y="272" />' : '') + '</svg><p>';
                +  switch (opt_ijData.level) {
                +    case 1:
                +      output += '一架飛機有一定量行數的乘客座位,每排都包含四個席位。';
                +      break;
                +    case 2:
                +      output += '一架飛機除了有兩個座位供正副機師,還有一定量行數的乘客座位。每排都包含四個席位。';
                +      break;
                +    case 3:
                +      output += '一架飛機除了有兩個座位供正副機師,還有一定量行數的頭等及經濟乘客座位。頭等艙每排都包含四個席位,經濟艙每排都包含五個席位。。';
                +      break;
                +  }
                +  output += '</p><p>於下方寫出一條公式以計算飛機上的座位總數。</p><script src="../../blockly_compressed.js"><\/script><script src="../../blocks_compressed.js"><\/script><script src="../../javascript_compressed.js"><\/script><script src="../../msg/js/' + soy.$$escapeHtml(opt_ijData.lang) + '.js"><\/script><script src="blocks.js"><\/script>' + planepage.toolbox(null, null, opt_ijData) + '<div id="blockly"></div>';
                +  return output;
                +};
                +
                +
                +planepage.toolbox = function(opt_data, opt_ignored, opt_ijData) {
                +  return '<xml id="toolbox" style="display: none"><block type="math_number"></block><block type="math_arithmetic"><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block><block type="math_arithmetic"><field name="OP">MULTIPLY</field><value name="A"><shadow type="math_number"><field name="NUM">1</field></shadow></value><value name="B"><shadow type="math_number"><field name="NUM">1</field></shadow></value></block>' + ((opt_ijData.level <= 2) ? '<block type="plane_get_rows"></block>' : '<block type="plane_get_rows1st"></block><block type="plane_get_rows2nd"></block>') + '</xml>';
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/icon.png b/blockly/webif/static/blockly/demos/plane/icon.png
                new file mode 100644
                index 000000000..0ebac70c6
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/plane/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/plane/index.html b/blockly/webif/static/blockly/demos/plane/index.html
                new file mode 100644
                index 000000000..dec1cd3cd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/index.html
                @@ -0,0 +1,19 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <meta name="google" value="notranslate">
                +  <title>Blockly Demo:</title>
                +  <link rel="stylesheet" href="style.css">
                +  <script src="soy/soyutils.js"></script>
                +  <script src="plane.js"></script>
                +</head>
                +<body>
                +  <script>
                +    document.write(planepage.start({}, null,
                +        {lang: Plane.LANG,
                +         level: Plane.LEVEL,
                +         maxLevel: Plane.MAX_LEVEL}));
                +  </script>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/plane/plane.js b/blockly/webif/static/blockly/demos/plane/plane.js
                new file mode 100644
                index 000000000..99e5c175c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/plane.js
                @@ -0,0 +1,445 @@
                +/**
                + * Blockly Demos: Plane Seat Calculator
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview JavaScript for Blockly's Plane Seat Calculator demo.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +/**
                + * Create a namespace for the application.
                + */
                +var Plane = {};
                +
                +/**
                + * Lookup for names of supported languages.  Keys should be in ISO 639 format.
                + */
                +Plane.LANGUAGE_NAME = {
                +  'ar': 'العربية',
                +  'be-tarask': 'Taraškievica',
                +  'br': 'Brezhoneg',
                +  'ca': 'Català',
                +  'da': 'Dansk',
                +  'de': 'Deutsch',
                +  'el': 'Ελληνικά',
                +  'en': 'English',
                +  'es': 'Español',
                +  'fa': 'فارسی',
                +  'fr': 'Français',
                +  'he': 'עברית',
                +  'hrx': 'Hunsrik',
                +  'hu': 'Magyar',
                +  'ia': 'Interlingua',
                +  'is': 'Íslenska',
                +  'it': 'Italiano',
                +  'ja': '日本語',
                +  'ko': '한국어',
                +  'ms': 'Bahasa Melayu',
                +  'nb': 'Norsk Bokmål',
                +  'nl': 'Nederlands, Vlaams',
                +  'pl': 'Polski',
                +  'pms': 'Piemontèis',
                +  'pt-br': 'Português Brasileiro',
                +  'ro': 'Română',
                +  'ru': 'Русский',
                +  'sc': 'Sardu',
                +  'sv': 'Svenska',
                +  'th': 'ภาษาไทย',
                +  'tr': 'Türkçe',
                +  'uk': 'Українська',
                +  'vi': 'Tiếng Việt',
                +  'zh-hans': '简体中文',
                +  'zh-hant': '正體中文'
                +};
                +
                +/**
                + * List of RTL languages.
                + */
                +Plane.LANGUAGE_RTL = ['ar', 'fa', 'he'];
                +
                +/**
                + * Main Blockly workspace.
                + * @type {Blockly.WorkspaceSvg}
                + */
                +Plane.workspace = null;
                +
                +/**
                + * Extracts a parameter from the URL.
                + * If the parameter is absent default_value is returned.
                + * @param {string} name The name of the parameter.
                + * @param {string} defaultValue Value to return if paramater not found.
                + * @return {string} The parameter value or the default value if not found.
                + */
                +Plane.getStringParamFromUrl = function(name, defaultValue) {
                +  var val = location.search.match(new RegExp('[?&]' + name + '=([^&]+)'));
                +  return val ? decodeURIComponent(val[1].replace(/\+/g, '%20')) : defaultValue;
                +};
                +
                +/**
                + * Extracts a numeric parameter from the URL.
                + * If the parameter is absent or less than min_value, min_value is
                + * returned.  If it is greater than max_value, max_value is returned.
                + * @param {string} name The name of the parameter.
                + * @param {number} minValue The minimum legal value.
                + * @param {number} maxValue The maximum legal value.
                + * @return {number} A number in the range [min_value, max_value].
                + */
                +Plane.getNumberParamFromUrl = function(name, minValue, maxValue) {
                +  var val = Number(Plane.getStringParamFromUrl(name, 'NaN'));
                +  return isNaN(val) ? minValue : Math.min(Math.max(minValue, val), maxValue);
                +};
                +
                +/**
                + * Get the language of this user from the URL.
                + * @return {string} User's language.
                + */
                +Plane.getLang = function() {
                +  var lang = Plane.getStringParamFromUrl('lang', '');
                +  if (Plane.LANGUAGE_NAME[lang] === undefined) {
                +    // Default to English.
                +    lang = 'en';
                +  }
                +  return lang;
                +};
                +
                +/**
                + * Is the current language (Plane.LANG) an RTL language?
                + * @return {boolean} True if RTL, false if LTR.
                + */
                +Plane.isRtl = function() {
                +  return Plane.LANGUAGE_RTL.indexOf(Plane.LANG) != -1;
                +};
                +
                +/**
                + * Load blocks saved in session/local storage.
                + * @param {string} defaultXml Text representation of default blocks.
                + */
                +Plane.loadBlocks = function(defaultXml) {
                +  try {
                +    var loadOnce = window.sessionStorage.loadOnceBlocks;
                +  } catch(e) {
                +    // Firefox sometimes throws a SecurityError when accessing sessionStorage.
                +    // Restarting Firefox fixes this, so it looks like a bug.
                +    var loadOnce = null;
                +  }
                +  if (loadOnce) {
                +    // Language switching stores the blocks during the reload.
                +    delete window.sessionStorage.loadOnceBlocks;
                +    var xml = Blockly.Xml.textToDom(loadOnce);
                +    Blockly.Xml.domToWorkspace(xml, Plane.workspace);
                +  } else if (defaultXml) {
                +    // Load the editor with default starting blocks.
                +    var xml = Blockly.Xml.textToDom(defaultXml);
                +    Blockly.Xml.domToWorkspace(xml, Plane.workspace);
                +  }
                +  Plane.workspace.clearUndo();
                +};
                +
                +/**
                + * Save the blocks and reload with a different language.
                + */
                +Plane.changeLanguage = function() {
                +  // Store the blocks for the duration of the reload.
                +  // This should be skipped for the index page, which has no blocks and does
                +  // not load Blockly.
                +  // MSIE 11 does not support sessionStorage on file:// URLs.
                +  if (typeof Blockly != 'undefined' && window.sessionStorage) {
                +    var xml = Blockly.Xml.workspaceToDom(Plane.workspace);
                +    var text = Blockly.Xml.domToText(xml);
                +    window.sessionStorage.loadOnceBlocks = text;
                +  }
                +
                +  var languageMenu = document.getElementById('languageMenu');
                +  var newLang = encodeURIComponent(
                +      languageMenu.options[languageMenu.selectedIndex].value);
                +  var search = window.location.search;
                +  if (search.length <= 1) {
                +    search = '?lang=' + newLang;
                +  } else if (search.match(/[?&]lang=[^&]*/)) {
                +    search = search.replace(/([?&]lang=)[^&]*/, '$1' + newLang);
                +  } else {
                +    search = search.replace(/\?/, '?lang=' + newLang + '&');
                +  }
                +
                +  window.location = window.location.protocol + '//' +
                +      window.location.host + window.location.pathname + search;
                +};
                +
                +/**
                + * Gets the message with the given key from the document.
                + * @param {string} key The key of the document element.
                + * @return {string} The textContent of the specified element,
                + *     or an error message if the element was not found.
                + */
                +Plane.getMsg = function(key) {
                +  var element = document.getElementById(key);
                +  if (element) {
                +    var text = element.textContent;
                +    // Convert newline sequences.
                +    text = text.replace(/\\n/g, '\n');
                +    return text;
                +  } else {
                +    return '[Unknown message: ' + key + ']';
                +  }
                +};
                +
                +/**
                + * User's language (e.g. "en").
                + * @type {string}
                + */
                +Plane.LANG = Plane.getLang();
                +
                +Plane.MAX_LEVEL = 3;
                +Plane.LEVEL = Plane.getNumberParamFromUrl('level', 1, Plane.MAX_LEVEL);
                +
                +Plane.rows1st = 0;
                +Plane.rows2nd = 0;
                +
                +/**
                + * Redraw the rows when the slider has moved.
                + * @param {number} value New slider position.
                + */
                +Plane.sliderChange = function(value) {
                +  var newRows = Math.round(value * 410 / 20);
                +  Plane.redraw(newRows);
                +};
                +
                +/**
                + * Change the text of a label.
                + * @param {string} id ID of element to change.
                + * @param {string} text New text.
                + */
                +Plane.setText = function(id, text) {
                +  var el = document.getElementById(id);
                +  while (el.firstChild) {
                +    el.removeChild(el.firstChild);
                +  }
                +  el.appendChild(document.createTextNode(text));
                +};
                +
                +/**
                + * Display a checkmark or cross next to the answer.
                + * @param {?boolean} ok True for checkmark, false for cross, null for nothing.
                + */
                +Plane.setCorrect = function(ok) {
                +  var yes = document.getElementById('seatYes');
                +  var no = document.getElementById('seatNo');
                +  yes.style.display = 'none';
                +  no.style.display = 'none';
                +  if (ok === true) {
                +    yes.style.display = 'block';
                +  } else if (ok === false) {
                +    no.style.display = 'block';
                +  }
                +};
                +
                +/**
                + * Initialize Blockly and the SVG plane.
                + */
                +Plane.init = function() {
                +  Plane.initLanguage();
                +
                +  // Fixes viewport for small screens.
                +  var viewport = document.querySelector('meta[name="viewport"]');
                +  if (viewport && screen.availWidth < 725) {
                +    viewport.setAttribute('content',
                +        'width=725, initial-scale=.35, user-scalable=no');
                +  }
                +
                +  Plane.workspace = Blockly.inject('blockly',
                +      {media: '../../media/',
                +       rtl: Plane.isRtl(),
                +       toolbox: document.getElementById('toolbox')});
                +
                +  var defaultXml =
                +      '<xml>' +
                +      '  <block type="plane_set_seats" deletable="false" x="70" y="70">' +
                +      '  </block>' +
                +      '</xml>';
                +  Plane.loadBlocks(defaultXml);
                +
                +  Plane.workspace.addChangeListener(Plane.recalculate);
                +  Plane.workspace.addChangeListener(Blockly.Events.disableOrphans);
                +
                +  // Initialize the slider.
                +  var svg = document.getElementById('plane');
                +  Plane.rowSlider = new Slider(60, 330, 425, svg, Plane.sliderChange);
                +  Plane.rowSlider.setValue(0.225);
                +
                +  // Draw five 1st class rows.
                +  Plane.redraw(5);
                +};
                +
                +/**
                + * Initialize the page language.
                + */
                +Plane.initLanguage = function() {
                +  // Set the page title with the content of the H1 title.
                +  document.title += ' ' + document.getElementById('title').textContent;
                +
                +  // Set the HTML's language and direction.
                +  // document.dir fails in Mozilla, use document.body.parentNode.dir instead.
                +  // https://bugzilla.mozilla.org/show_bug.cgi?id=151407
                +  var rtl = Plane.isRtl();
                +  document.head.parentElement.setAttribute('dir', rtl ? 'rtl' : 'ltr');
                +  document.head.parentElement.setAttribute('lang', Plane.LANG);
                +
                +  // Sort languages alphabetically.
                +  var languages = [];
                +  for (var lang in Plane.LANGUAGE_NAME) {
                +    languages.push([Plane.LANGUAGE_NAME[lang], lang]);
                +  }
                +  var comp = function(a, b) {
                +    // Sort based on first argument ('English', 'Русский', '简体字', etc).
                +    if (a[0] > b[0]) return 1;
                +    if (a[0] < b[0]) return -1;
                +    return 0;
                +  };
                +  languages.sort(comp);
                +  // Populate the language selection menu.
                +  var languageMenu = document.getElementById('languageMenu');
                +  languageMenu.options.length = 0;
                +  for (var i = 0; i < languages.length; i++) {
                +    var tuple = languages[i];
                +    var lang = tuple[tuple.length - 1];
                +    var option = new Option(tuple[0], lang);
                +    if (lang == Plane.LANG) {
                +      option.selected = true;
                +    }
                +    languageMenu.options.add(option);
                +  }
                +  languageMenu.addEventListener('change', Plane.changeLanguage, true);
                +};
                +
                +/**
                + * Use the blocks to calculate the number of seats.
                + * Display the calculated number.
                + */
                +Plane.recalculate = function() {
                +  // Find the 'set' block and use it as the formula root.
                +  var rootBlock = null;
                +  var blocks = Plane.workspace.getTopBlocks(false);
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    if (block.type == 'plane_set_seats') {
                +      rootBlock = block;
                +    }
                +  }
                +  var seats = NaN;
                +  Blockly.JavaScript.init(Plane.workspace);
                +  var code = Blockly.JavaScript.blockToCode(rootBlock);
                +  try {
                +    seats = eval(code);
                +  } catch (e) {
                +    // Allow seats to remain NaN.
                +  }
                +  Plane.setText('seatText',
                +      Plane.getMsg('Plane_seats').replace(
                +          '%1', isNaN(seats) ? '?' : seats));
                +  Plane.setCorrect(isNaN(seats) ? null : (Plane.answer() == seats));
                +
                +  // Update blocks to show values.
                +  function updateBlocks(blocks) {
                +    for (var i = 0, block; block = blocks[i]; i++) {
                +      block.customUpdate && block.customUpdate();
                +    }
                +  }
                +  updateBlocks(Plane.workspace.getAllBlocks());
                +  updateBlocks(Plane.workspace.flyout_.workspace_.getAllBlocks());
                +};
                +
                +/**
                + * Calculate the correct answer.
                + * @return {number} Number of seats.
                + */
                +Plane.answer = function() {
                +  if (Plane.LEVEL == 1) {
                +    return Plane.rows1st * 4;
                +  } else if (Plane.LEVEL == 2) {
                +    return 2 + (Plane.rows1st * 4);
                +  } else if (Plane.LEVEL == 3) {
                +    return 2 + (Plane.rows1st * 4) + (Plane.rows2nd * 5);
                +  }
                +  throw 'Unknown level.';
                +};
                +
                +/**
                + * Redraw the SVG to show a new number of rows.
                + * @param {number} newRows
                + */
                +Plane.redraw = function(newRows) {
                +  var rows1st = Plane.rows1st;
                +  var rows2nd = Plane.rows2nd;
                +  var svg = document.getElementById('plane');
                +  if (newRows != rows1st) {
                +    while (newRows < rows1st) {
                +      var row = document.getElementById('row1st' + rows1st);
                +      row.parentNode.removeChild(row);
                +      rows1st--;
                +    }
                +    while (newRows > rows1st) {
                +      rows1st++;
                +      var row = document.createElementNS('http://www.w3.org/2000/svg', 'use');
                +      row.setAttribute('id', 'row1st' + rows1st);
                +      // Row of 4 seats.
                +      row.setAttribute('x', (rows1st - 1) * 20);
                +      row.setAttributeNS('http://www.w3.org/1999/xlink',
                +          'xlink:href', '#row1st');
                +      svg.appendChild(row);
                +    }
                +
                +    if (Plane.LEVEL == 3) {
                +      newRows = Math.floor((21 - newRows) * 1.11);
                +      while (newRows < rows2nd) {
                +        var row = document.getElementById('row2nd' + rows2nd);
                +        row.parentNode.removeChild(row);
                +        rows2nd--;
                +      }
                +      while (newRows > rows2nd) {
                +        rows2nd++;
                +        var row = document.createElementNS('http://www.w3.org/2000/svg',
                +                                                    'use');
                +        row.setAttribute('id', 'row2nd' + rows2nd);
                +        row.setAttribute('x', 400 - (rows2nd - 1) * 18);
                +        row.setAttributeNS('http://www.w3.org/1999/xlink',
                +            'xlink:href', '#row2nd');
                +        svg.appendChild(row);
                +      }
                +    }
                +
                +    if (Plane.LEVEL < 3) {
                +      Plane.setText('row1stText',
                +          Plane.getMsg('Plane_rows').replace('%1', rows1st));
                +    } else {
                +      Plane.setText('row1stText',
                +          Plane.getMsg('Plane_rows1').replace('%1', rows1st));
                +      Plane.setText('row2ndText',
                +          Plane.getMsg('Plane_rows2').replace('%1', rows2nd));
                +    }
                +
                +    Plane.rows1st = rows1st;
                +    Plane.rows2nd = rows2nd;
                +    Plane.recalculate();
                +  }
                +};
                +
                +window.addEventListener('load', Plane.init);
                +
                +// Load the user's language pack.
                +document.write('<script src="generated/' + Plane.LANG + '.js"></script>\n');
                diff --git a/blockly/webif/static/blockly/demos/plane/slider.js b/blockly/webif/static/blockly/demos/plane/slider.js
                new file mode 100644
                index 000000000..2df67b834
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/slider.js
                @@ -0,0 +1,287 @@
                +/**
                + * Blockly Demos: SVG Slider
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview A slider control in SVG.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +
                +/**
                + * Object representing a horizontal slider widget.
                + * @param {number} x The horizontal offset of the slider.
                + * @param {number} y The vertical offset of the slider.
                + * @param {number} width The total width of the slider.
                + * @param {!Element} svgParent The SVG element to append the slider to.
                + * @param {Function=} opt_changeFunc Optional callback function that will be
                + *     called when the slider is moved.  The current value is passed.
                + * @constructor
                + */
                +var Slider = function(x, y, width, svgParent, opt_changeFunc) {
                +  this.KNOB_Y_ = y - 12;
                +  this.KNOB_MIN_X_ = x + 8;
                +  this.KNOB_MAX_X_ = x + width - 8;
                +  this.TARGET_OVERHANG_ = 20;
                +  this.value_ = 0.5;
                +  this.changeFunc_ = opt_changeFunc;
                +  this.animationTasks_ = [];
                +
                +  // Draw the slider.
                +  /*
                +  <line class="sliderTrack" x1="10" y1="35" x2="140" y2="35" />
                +  <rect style="opacity: 0" x="5" y="25" width="150" height="20" />
                +  <path id="knob"
                +      transform="translate(67, 23)"
                +      d="m 8,0 l -8,8 v 12 h 16 v -12 z" />
                +  <circle style="opacity: 0" r="20" cy="35" cx="75"></circle>
                +  */
                +  var track = document.createElementNS(Slider.SVG_NS_, 'line');
                +  track.setAttribute('class', 'sliderTrack');
                +  track.setAttribute('x1', x);
                +  track.setAttribute('y1', y);
                +  track.setAttribute('x2', x + width);
                +  track.setAttribute('y2', y);
                +  svgParent.appendChild(track);
                +  this.track_ = track;
                +  var rect = document.createElementNS(Slider.SVG_NS_, 'rect');
                +  rect.setAttribute('style', 'opacity: 0');
                +  rect.setAttribute('x', x - this.TARGET_OVERHANG_);
                +  rect.setAttribute('y', y - this.TARGET_OVERHANG_);
                +  rect.setAttribute('width',  width + 2 * this.TARGET_OVERHANG_);
                +  rect.setAttribute('height', 2 * this.TARGET_OVERHANG_);
                +  rect.setAttribute('rx', this.TARGET_OVERHANG_);
                +  rect.setAttribute('ry', this.TARGET_OVERHANG_);
                +  svgParent.appendChild(rect);
                +  this.trackTarget_ = rect;
                +  var knob = document.createElementNS(Slider.SVG_NS_, 'path');
                +  knob.setAttribute('class', 'sliderKnob');
                +  knob.setAttribute('d', 'm 0,0 l -8,8 v 12 h 16 v -12 z');
                +  svgParent.appendChild(knob);
                +  this.knob_ = knob;
                +  var circle = document.createElementNS(Slider.SVG_NS_, 'circle');
                +  circle.setAttribute('style', 'opacity: 0');
                +  circle.setAttribute('r', this.TARGET_OVERHANG_);
                +  circle.setAttribute('cy', y);
                +  svgParent.appendChild(circle);
                +  this.knobTarget_ = circle;
                +  this.setValue(0.5);
                +
                +  // Find the root SVG object.
                +  while (svgParent && svgParent.nodeName.toLowerCase() != 'svg') {
                +    svgParent = svgParent.parentNode;
                +  }
                +  this.SVG_ = svgParent;
                +
                +  // Bind the events to this slider.
                +  Slider.bindEvent_(this.knobTarget_, 'mousedown', this, this.knobMouseDown_);
                +  Slider.bindEvent_(this.knobTarget_, 'touchstart', this, this.knobMouseDown_);
                +  Slider.bindEvent_(this.trackTarget_, 'mousedown', this, this.rectMouseDown_);
                +  Slider.bindEvent_(this.SVG_, 'mouseup', null, Slider.knobMouseUp_);
                +  Slider.bindEvent_(this.SVG_, 'touchend', null, Slider.knobMouseUp_);
                +  Slider.bindEvent_(this.SVG_, 'mousemove', null, Slider.knobMouseMove_);
                +  Slider.bindEvent_(this.SVG_, 'touchmove', null, Slider.knobMouseMove_);
                +  Slider.bindEvent_(document, 'mouseover', null, Slider.mouseOver_);
                +};
                +
                +
                +Slider.SVG_NS_ = 'http://www.w3.org/2000/svg';
                +
                +Slider.activeSlider_ = null;
                +Slider.startMouseX_ = 0;
                +Slider.startKnobX_ = 0;
                +
                +/**
                + * Start a drag when clicking down on the knob.
                + * @param {!Event} e Mouse-down event.
                + * @private
                + */
                +Slider.prototype.knobMouseDown_ = function(e) {
                +  if (e.type == 'touchstart') {
                +    if (e.changedTouches.length != 1) {
                +      return;
                +    }
                +    Slider.touchToMouse_(e)
                +  }
                +  Slider.activeSlider_ = this;
                +  Slider.startMouseX_ = this.mouseToSvg_(e).x;
                +  Slider.startKnobX_ = 0;
                +  var transform = this.knob_.getAttribute('transform');
                +  if (transform) {
                +    var r = transform.match(/translate\(\s*([-\d.]+)/);
                +    if (r) {
                +      Slider.startKnobX_ = Number(r[1]);
                +    }
                +  }
                +  // Stop browser from attempting to drag the knob or
                +  // from scrolling/zooming the page.
                +  e.preventDefault();
                +};
                +
                +/**
                + * Stop a drag when clicking up anywhere.
                + * @param {Event} e Mouse-up event.
                + * @private
                + */
                +Slider.knobMouseUp_ = function(e) {
                +  Slider.activeSlider_ = null;
                +};
                +
                +/**
                + * Stop a drag when the mouse enters a node not part of the SVG.
                + * @param {Event} e Mouse-up event.
                + * @private
                + */
                +Slider.mouseOver_ = function(e) {
                +  if (!Slider.activeSlider_) {
                +    return;
                +  }
                +  var node = e.target;
                +  // Find the root SVG object.
                +  do {
                +    if (node == Slider.activeSlider_.SVG_) {
                +      return;
                +    }
                +  } while (node = node.parentNode);
                +  Slider.knobMouseUp_(e);
                +};
                +
                +/**
                + * Drag the knob to follow the mouse.
                + * @param {!Event} e Mouse-move event.
                + * @private
                + */
                +Slider.knobMouseMove_ = function(e) {
                +  var thisSlider = Slider.activeSlider_;
                +  if (!thisSlider) {
                +    return;
                +  }
                +  if (e.type == 'touchmove') {
                +    if (e.changedTouches.length != 1) {
                +      return;
                +    }
                +    Slider.touchToMouse_(e)
                +  }
                +  var x = thisSlider.mouseToSvg_(e).x - Slider.startMouseX_ +
                +      Slider.startKnobX_;
                +  thisSlider.setValue((x - thisSlider.KNOB_MIN_X_) /
                +      (thisSlider.KNOB_MAX_X_ - thisSlider.KNOB_MIN_X_));
                +};
                +
                +/**
                + * Jump to a new value when the track is clicked.
                + * @param {!Event} e Mouse-down event.
                + * @private
                + */
                +Slider.prototype.rectMouseDown_ = function(e) {
                +  if (e.type == 'touchstart') {
                +    if (e.changedTouches.length != 1) {
                +      return;
                +    }
                +    Slider.touchToMouse_(e)
                +  }
                +  var x = this.mouseToSvg_(e).x;
                +  this.animateValue((x - this.KNOB_MIN_X_) /
                +      (this.KNOB_MAX_X_ - this.KNOB_MIN_X_));
                +};
                +
                +/**
                + * Returns the slider's value (0.0 - 1.0).
                + * @return {number} Current value.
                + */
                +Slider.prototype.getValue = function() {
                +  return this.value_;
                +};
                +
                +/**
                + * Animates the slider's value (0.0 - 1.0).
                + * @param {number} value New value.
                + */
                +Slider.prototype.animateValue = function(value) {
                +  // Clear any ongoing animations.
                +  while (this.animationTasks_.length) {
                +    clearTimeout(this.animationTasks_.pop());
                +  }
                +  var duration = 200; // Milliseconds to animate for.
                +  var steps = 10; // Number of steps to animate.
                +  var oldValue = this.getValue();
                +  var thisSlider = this;
                +  var stepFunc = function(i) {
                +    return function() {
                +      var newVal = i * (value - oldValue) / (steps - 1) + oldValue;
                +      thisSlider.setValue(newVal);
                +    };
                +  }
                +  for (var i = 0; i < steps; i++) {
                +    this.animationTasks_.push(setTimeout(stepFunc(i), i * duration / steps));
                +  }
                +};
                +
                +/**
                + * Sets the slider's value (0.0 - 1.0).
                + * @param {number} value New value.
                + */
                +Slider.prototype.setValue = function(value) {
                +  this.value_ = Math.min(Math.max(value, 0), 1);
                +  var x = this.KNOB_MIN_X_ +
                +      (this.KNOB_MAX_X_ - this.KNOB_MIN_X_) * this.value_;
                +  this.knob_.setAttribute('transform',
                +      'translate(' + x + ',' + this.KNOB_Y_ + ')');
                +  this.knobTarget_.setAttribute('cx', x);
                +  this.changeFunc_ && this.changeFunc_(this.value_);
                +};
                +
                +/**
                + * Convert the mouse coordinates into SVG coordinates.
                + * @param {!Object} e Object with x and y mouse coordinates.
                + * @return {!Object} Object with x and y properties in SVG coordinates.
                + * @private
                + */
                +Slider.prototype.mouseToSvg_ = function(e) {
                +  var svgPoint = this.SVG_.createSVGPoint();
                +  svgPoint.x = e.clientX;
                +  svgPoint.y = e.clientY;
                +  var matrix = this.SVG_.getScreenCTM().inverse();
                +  return svgPoint.matrixTransform(matrix);
                +};
                +
                +/**
                + * Bind an event to a function call.
                + * @param {!Node} node Node upon which to listen.
                + * @param {string} name Event name to listen to (e.g. 'mousedown').
                + * @param {Object} thisObject The value of 'this' in the function.
                + * @param {!Function} func Function to call when event is triggered.
                + * @private
                + */
                +Slider.bindEvent_ = function(node, name, thisObject, func) {
                +  var wrapFunc = function(e) {
                +    func.apply(thisObject, arguments);
                +  };
                +  node.addEventListener(name, wrapFunc, false);
                +};
                +
                +/**
                + * Map the touch event's properties to be compatible with a mouse event.
                + * @param {TouchEvent} e Event to modify.
                + */
                +Slider.touchToMouse_ = function(e) {
                +  var touchPoint = e.changedTouches[0];
                +  e.clientX = touchPoint.clientX;
                +  e.clientY = touchPoint.clientY;
                +};
                diff --git a/blockly/webif/static/blockly/demos/plane/soy/COPYING b/blockly/webif/static/blockly/demos/plane/soy/COPYING
                new file mode 100644
                index 000000000..d64569567
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/soy/COPYING
                @@ -0,0 +1,202 @@
                +
                +                                 Apache License
                +                           Version 2.0, January 2004
                +                        http://www.apache.org/licenses/
                +
                +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
                +
                +   1. Definitions.
                +
                +      "License" shall mean the terms and conditions for use, reproduction,
                +      and distribution as defined by Sections 1 through 9 of this document.
                +
                +      "Licensor" shall mean the copyright owner or entity authorized by
                +      the copyright owner that is granting the License.
                +
                +      "Legal Entity" shall mean the union of the acting entity and all
                +      other entities that control, are controlled by, or are under common
                +      control with that entity. For the purposes of this definition,
                +      "control" means (i) the power, direct or indirect, to cause the
                +      direction or management of such entity, whether by contract or
                +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
                +      outstanding shares, or (iii) beneficial ownership of such entity.
                +
                +      "You" (or "Your") shall mean an individual or Legal Entity
                +      exercising permissions granted by this License.
                +
                +      "Source" form shall mean the preferred form for making modifications,
                +      including but not limited to software source code, documentation
                +      source, and configuration files.
                +
                +      "Object" form shall mean any form resulting from mechanical
                +      transformation or translation of a Source form, including but
                +      not limited to compiled object code, generated documentation,
                +      and conversions to other media types.
                +
                +      "Work" shall mean the work of authorship, whether in Source or
                +      Object form, made available under the License, as indicated by a
                +      copyright notice that is included in or attached to the work
                +      (an example is provided in the Appendix below).
                +
                +      "Derivative Works" shall mean any work, whether in Source or Object
                +      form, that is based on (or derived from) the Work and for which the
                +      editorial revisions, annotations, elaborations, or other modifications
                +      represent, as a whole, an original work of authorship. For the purposes
                +      of this License, Derivative Works shall not include works that remain
                +      separable from, or merely link (or bind by name) to the interfaces of,
                +      the Work and Derivative Works thereof.
                +
                +      "Contribution" shall mean any work of authorship, including
                +      the original version of the Work and any modifications or additions
                +      to that Work or Derivative Works thereof, that is intentionally
                +      submitted to Licensor for inclusion in the Work by the copyright owner
                +      or by an individual or Legal Entity authorized to submit on behalf of
                +      the copyright owner. For the purposes of this definition, "submitted"
                +      means any form of electronic, verbal, or written communication sent
                +      to the Licensor or its representatives, including but not limited to
                +      communication on electronic mailing lists, source code control systems,
                +      and issue tracking systems that are managed by, or on behalf of, the
                +      Licensor for the purpose of discussing and improving the Work, but
                +      excluding communication that is conspicuously marked or otherwise
                +      designated in writing by the copyright owner as "Not a Contribution."
                +
                +      "Contributor" shall mean Licensor and any individual or Legal Entity
                +      on behalf of whom a Contribution has been received by Licensor and
                +      subsequently incorporated within the Work.
                +
                +   2. Grant of Copyright License. Subject to the terms and conditions of
                +      this License, each Contributor hereby grants to You a perpetual,
                +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +      copyright license to reproduce, prepare Derivative Works of,
                +      publicly display, publicly perform, sublicense, and distribute the
                +      Work and such Derivative Works in Source or Object form.
                +
                +   3. Grant of Patent License. Subject to the terms and conditions of
                +      this License, each Contributor hereby grants to You a perpetual,
                +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
                +      (except as stated in this section) patent license to make, have made,
                +      use, offer to sell, sell, import, and otherwise transfer the Work,
                +      where such license applies only to those patent claims licensable
                +      by such Contributor that are necessarily infringed by their
                +      Contribution(s) alone or by combination of their Contribution(s)
                +      with the Work to which such Contribution(s) was submitted. If You
                +      institute patent litigation against any entity (including a
                +      cross-claim or counterclaim in a lawsuit) alleging that the Work
                +      or a Contribution incorporated within the Work constitutes direct
                +      or contributory patent infringement, then any patent licenses
                +      granted to You under this License for that Work shall terminate
                +      as of the date such litigation is filed.
                +
                +   4. Redistribution. You may reproduce and distribute copies of the
                +      Work or Derivative Works thereof in any medium, with or without
                +      modifications, and in Source or Object form, provided that You
                +      meet the following conditions:
                +
                +      (a) You must give any other recipients of the Work or
                +          Derivative Works a copy of this License; and
                +
                +      (b) You must cause any modified files to carry prominent notices
                +          stating that You changed the files; and
                +
                +      (c) You must retain, in the Source form of any Derivative Works
                +          that You distribute, all copyright, patent, trademark, and
                +          attribution notices from the Source form of the Work,
                +          excluding those notices that do not pertain to any part of
                +          the Derivative Works; and
                +
                +      (d) If the Work includes a "NOTICE" text file as part of its
                +          distribution, then any Derivative Works that You distribute must
                +          include a readable copy of the attribution notices contained
                +          within such NOTICE file, excluding those notices that do not
                +          pertain to any part of the Derivative Works, in at least one
                +          of the following places: within a NOTICE text file distributed
                +          as part of the Derivative Works; within the Source form or
                +          documentation, if provided along with the Derivative Works; or,
                +          within a display generated by the Derivative Works, if and
                +          wherever such third-party notices normally appear. The contents
                +          of the NOTICE file are for informational purposes only and
                +          do not modify the License. You may add Your own attribution
                +          notices within Derivative Works that You distribute, alongside
                +          or as an addendum to the NOTICE text from the Work, provided
                +          that such additional attribution notices cannot be construed
                +          as modifying the License.
                +
                +      You may add Your own copyright statement to Your modifications and
                +      may provide additional or different license terms and conditions
                +      for use, reproduction, or distribution of Your modifications, or
                +      for any such Derivative Works as a whole, provided Your use,
                +      reproduction, and distribution of the Work otherwise complies with
                +      the conditions stated in this License.
                +
                +   5. Submission of Contributions. Unless You explicitly state otherwise,
                +      any Contribution intentionally submitted for inclusion in the Work
                +      by You to the Licensor shall be under the terms and conditions of
                +      this License, without any additional terms or conditions.
                +      Notwithstanding the above, nothing herein shall supersede or modify
                +      the terms of any separate license agreement you may have executed
                +      with Licensor regarding such Contributions.
                +
                +   6. Trademarks. This License does not grant permission to use the trade
                +      names, trademarks, service marks, or product names of the Licensor,
                +      except as required for reasonable and customary use in describing the
                +      origin of the Work and reproducing the content of the NOTICE file.
                +
                +   7. Disclaimer of Warranty. Unless required by applicable law or
                +      agreed to in writing, Licensor provides the Work (and each
                +      Contributor provides its Contributions) on an "AS IS" BASIS,
                +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
                +      implied, including, without limitation, any warranties or conditions
                +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
                +      PARTICULAR PURPOSE. You are solely responsible for determining the
                +      appropriateness of using or redistributing the Work and assume any
                +      risks associated with Your exercise of permissions under this License.
                +
                +   8. Limitation of Liability. In no event and under no legal theory,
                +      whether in tort (including negligence), contract, or otherwise,
                +      unless required by applicable law (such as deliberate and grossly
                +      negligent acts) or agreed to in writing, shall any Contributor be
                +      liable to You for damages, including any direct, indirect, special,
                +      incidental, or consequential damages of any character arising as a
                +      result of this License or out of the use or inability to use the
                +      Work (including but not limited to damages for loss of goodwill,
                +      work stoppage, computer failure or malfunction, or any and all
                +      other commercial damages or losses), even if such Contributor
                +      has been advised of the possibility of such damages.
                +
                +   9. Accepting Warranty or Additional Liability. While redistributing
                +      the Work or Derivative Works thereof, You may choose to offer,
                +      and charge a fee for, acceptance of support, warranty, indemnity,
                +      or other liability obligations and/or rights consistent with this
                +      License. However, in accepting such obligations, You may act only
                +      on Your own behalf and on Your sole responsibility, not on behalf
                +      of any other Contributor, and only if You agree to indemnify,
                +      defend, and hold each Contributor harmless for any liability
                +      incurred by, or claims asserted against, such Contributor by reason
                +      of your accepting any such warranty or additional liability.
                +
                +   END OF TERMS AND CONDITIONS
                +
                +   APPENDIX: How to apply the Apache License to your work.
                +
                +      To apply the Apache License to your work, attach the following
                +      boilerplate notice, with the fields enclosed by brackets "[]"
                +      replaced with your own identifying information. (Don't include
                +      the brackets!)  The text should be enclosed in the appropriate
                +      comment syntax for the file format. We also recommend that a
                +      file or class name and description of purpose be included on the
                +      same "printed page" as the copyright notice for easier
                +      identification within third-party archives.
                +
                +   Copyright [yyyy] [name of copyright owner]
                +
                +   Licensed under the Apache License, Version 2.0 (the "License");
                +   you may not use this file except in compliance with the License.
                +   You may obtain a copy of the License at
                +
                +       http://www.apache.org/licenses/LICENSE-2.0
                +
                +   Unless required by applicable law or agreed to in writing, software
                +   distributed under the License is distributed on an "AS IS" BASIS,
                +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +   See the License for the specific language governing permissions and
                +   limitations under the License.
                diff --git a/blockly/webif/static/blockly/demos/plane/soy/README b/blockly/webif/static/blockly/demos/plane/soy/README
                new file mode 100644
                index 000000000..e3447f2d8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/soy/README
                @@ -0,0 +1,45 @@
                +// Copyright 2009 Google Inc.
                +//
                +// Licensed under the Apache License, Version 2.0 (the "License");
                +// you may not use this file except in compliance with the License.
                +// You may obtain a copy of the License at
                +//
                +//     http://www.apache.org/licenses/LICENSE-2.0
                +//
                +// Unless required by applicable law or agreed to in writing, software
                +// distributed under the License is distributed on an "AS IS" BASIS,
                +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +// See the License for the specific language governing permissions and
                +// limitations under the License.
                +
                +
                +Contents:
                +
                ++ SoyToJsSrcCompiler.jar
                +    Executable jar that compiles template files into JavaScript files.
                +
                ++ SoyMsgExtractor.jar
                +    Executable jar that extracts messages from template files into XLF files.
                +
                ++ soyutils.js
                +    Helper utilities required by all JavaScript code that SoyToJsSrcCompiler
                +    generates. Equivalent functionality to soyutils_usegoog.js, but this
                +    version does not need Closure Library.
                +
                +
                +Instructions:
                +
                ++ A simple Hello World for JavaScript:
                +    http://code.google.com/closure/templates/docs/helloworld_js.html
                +
                ++ Complete documentation:
                +    http://code.google.com/closure/templates/
                +
                ++ Closure Templates project on Google Code:
                +    http://code.google.com/p/closure-templates/
                +
                +
                +Notes:
                +
                ++ Closure Templates requires Java 6 or higher:
                +    http://www.java.com/
                diff --git a/blockly/webif/static/blockly/demos/plane/soy/soyutils.js b/blockly/webif/static/blockly/demos/plane/soy/soyutils.js
                new file mode 100644
                index 000000000..bde8e4133
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/soy/soyutils.js
                @@ -0,0 +1,2767 @@
                +/*
                + * Copyright 2008 Google Inc.
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *     http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview
                + * Utility functions and classes for Soy.
                + *
                + * <p>
                + * The top portion of this file contains utilities for Soy users:<ul>
                + *   <li> soy.StringBuilder: Compatible with the 'stringbuilder' code style.
                + *   <li> soy.renderElement: Render template and set as innerHTML of an element.
                + *   <li> soy.renderAsFragment: Render template and return as HTML fragment.
                + * </ul>
                + *
                + * <p>
                + * The bottom portion of this file contains utilities that should only be called
                + * by Soy-generated JS code. Please do not use these functions directly from
                + * your hand-writen code. Their names all start with '$$'.
                + *
                + * @author Garrett Boyer
                + * @author Mike Samuel
                + * @author Kai Huang
                + * @author Aharon Lanin
                + */
                +
                +
                +// COPIED FROM nogoog_shim.js
                +
                +// Create closure namespaces.
                +var goog = goog || {};
                +
                +
                +goog.DEBUG = false;
                +
                +
                +goog.inherits = function(childCtor, parentCtor) {
                +  /** @constructor */
                +  function tempCtor() {}
                +  tempCtor.prototype = parentCtor.prototype;
                +  childCtor.superClass_ = parentCtor.prototype;
                +  childCtor.prototype = new tempCtor();
                +  childCtor.prototype.constructor = childCtor;
                +};
                +
                +
                +// Just enough browser detection for this file.
                +if (!goog.userAgent) {
                +  goog.userAgent = (function() {
                +    var userAgent = "";
                +    if ("undefined" !== typeof navigator && navigator
                +        && "string" == typeof navigator.userAgent) {
                +      userAgent = navigator.userAgent;
                +    }
                +    var isOpera = userAgent.indexOf('Opera') == 0;
                +    return {
                +      jscript: {
                +        /**
                +         * @type {boolean}
                +         */
                +        HAS_JSCRIPT: 'ScriptEngine' in this
                +      },
                +      /**
                +       * @type {boolean}
                +       */
                +      OPERA: isOpera,
                +      /**
                +       * @type {boolean}
                +       */
                +      IE: !isOpera && userAgent.indexOf('MSIE') != -1,
                +      /**
                +       * @type {boolean}
                +       */
                +      WEBKIT: !isOpera && userAgent.indexOf('WebKit') != -1
                +    };
                +  })();
                +}
                +
                +if (!goog.asserts) {
                +  goog.asserts = {
                +    /**
                +     * @param {*} condition Condition to check.
                +     */
                +    assert: function (condition) {
                +      if (!condition) {
                +        throw Error('Assertion error');
                +      }
                +    },
                +    /**
                +     * @param {...*} var_args
                +     */
                +    fail: function (var_args) {}
                +  };
                +}
                +
                +
                +// Stub out the document wrapper used by renderAs*.
                +if (!goog.dom) {
                +  goog.dom = {};
                +  /**
                +   * @param {Document=} d
                +   * @constructor
                +   */
                +  goog.dom.DomHelper = function(d) {
                +    this.document_ = d || document;
                +  };
                +  /**
                +   * @return {!Document}
                +   */
                +  goog.dom.DomHelper.prototype.getDocument = function() {
                +    return this.document_;
                +  };
                +  /**
                +   * Creates a new element.
                +   * @param {string} name Tag name.
                +   * @return {!Element}
                +   */
                +  goog.dom.DomHelper.prototype.createElement = function(name) {
                +    return this.document_.createElement(name);
                +  };
                +  /**
                +   * Creates a new document fragment.
                +   * @return {!DocumentFragment}
                +   */
                +  goog.dom.DomHelper.prototype.createDocumentFragment = function() {
                +    return this.document_.createDocumentFragment();
                +  };
                +}
                +
                +
                +if (!goog.format) {
                +  goog.format = {
                +    insertWordBreaks: function(str, maxCharsBetweenWordBreaks) {
                +      str = String(str);
                +
                +      var resultArr = [];
                +      var resultArrLen = 0;
                +
                +      // These variables keep track of important state inside str.
                +      var isInTag = false;  // whether we're inside an HTML tag
                +      var isMaybeInEntity = false;  // whether we might be inside an HTML entity
                +      var numCharsWithoutBreak = 0;  // number of chars since last word break
                +      var flushIndex = 0;  // index of first char not yet flushed to resultArr
                +
                +      for (var i = 0, n = str.length; i < n; ++i) {
                +        var charCode = str.charCodeAt(i);
                +
                +        // If hit maxCharsBetweenWordBreaks, and not space next, then add <wbr>.
                +        if (numCharsWithoutBreak >= maxCharsBetweenWordBreaks &&
                +            // space
                +            charCode != 32) {
                +          resultArr[resultArrLen++] = str.substring(flushIndex, i);
                +          flushIndex = i;
                +          resultArr[resultArrLen++] = goog.format.WORD_BREAK;
                +          numCharsWithoutBreak = 0;
                +        }
                +
                +        if (isInTag) {
                +          // If inside an HTML tag and we see '>', it's the end of the tag.
                +          if (charCode == 62) {
                +            isInTag = false;
                +          }
                +
                +        } else if (isMaybeInEntity) {
                +          switch (charCode) {
                +            // Inside an entity, a ';' is the end of the entity.
                +            // The entity that just ended counts as one char, so increment
                +            // numCharsWithoutBreak.
                +          case 59:  // ';'
                +            isMaybeInEntity = false;
                +            ++numCharsWithoutBreak;
                +            break;
                +            // If maybe inside an entity and we see '<', we weren't actually in
                +            // an entity. But now we're inside and HTML tag.
                +          case 60:  // '<'
                +            isMaybeInEntity = false;
                +            isInTag = true;
                +            break;
                +            // If maybe inside an entity and we see ' ', we weren't actually in
                +            // an entity. Just correct the state and reset the
                +            // numCharsWithoutBreak since we just saw a space.
                +          case 32:  // ' '
                +            isMaybeInEntity = false;
                +            numCharsWithoutBreak = 0;
                +            break;
                +          }
                +
                +        } else {  // !isInTag && !isInEntity
                +          switch (charCode) {
                +            // When not within a tag or an entity and we see '<', we're now
                +            // inside an HTML tag.
                +          case 60:  // '<'
                +            isInTag = true;
                +            break;
                +            // When not within a tag or an entity and we see '&', we might be
                +            // inside an entity.
                +          case 38:  // '&'
                +            isMaybeInEntity = true;
                +            break;
                +            // When we see a space, reset the numCharsWithoutBreak count.
                +          case 32:  // ' '
                +            numCharsWithoutBreak = 0;
                +            break;
                +            // When we see a non-space, increment the numCharsWithoutBreak.
                +          default:
                +            ++numCharsWithoutBreak;
                +            break;
                +          }
                +        }
                +      }
                +
                +      // Flush the remaining chars at the end of the string.
                +      resultArr[resultArrLen++] = str.substring(flushIndex);
                +
                +      return resultArr.join('');
                +    },
                +    /**
                +     * String inserted as a word break by insertWordBreaks(). Safari requires
                +     * <wbr></wbr>, Opera needs the 'shy' entity, though this will give a
                +     * visible hyphen at breaks. Other browsers just use <wbr>.
                +     * @type {string}
                +     * @private
                +     */
                +    WORD_BREAK: goog.userAgent.WEBKIT
                +        ? '<wbr></wbr>' : goog.userAgent.OPERA ? '&shy;' : '<wbr>'
                +  };
                +}
                +
                +
                +if (!goog.i18n) {
                +  goog.i18n = {
                +    bidi: {
                +      /**
                +       * Check the directionality of a piece of text, return true if the piece
                +       * of text should be laid out in RTL direction.
                +       * @param {string} text The piece of text that need to be detected.
                +       * @param {boolean=} opt_isHtml Whether {@code text} is HTML/HTML-escaped.
                +       *     Default: false.
                +       * @return {boolean}
                +       * @private
                +       */
                +      detectRtlDirectionality: function(text, opt_isHtml) {
                +        text = soyshim.$$bidiStripHtmlIfNecessary_(text, opt_isHtml);
                +        return soyshim.$$bidiRtlWordRatio_(text)
                +            > soyshim.$$bidiRtlDetectionThreshold_;
                +      }
                +    }
                +  };
                +}
                +
                +/**
                + * Directionality enum.
                + * @enum {number}
                + */
                +goog.i18n.bidi.Dir = {
                +  RTL: -1,
                +  UNKNOWN: 0,
                +  LTR: 1
                +};
                +
                +
                +/**
                + * Convert a directionality given in various formats to a goog.i18n.bidi.Dir
                + * constant. Useful for interaction with different standards of directionality
                + * representation.
                + *
                + * @param {goog.i18n.bidi.Dir|number|boolean} givenDir Directionality given in
                + *     one of the following formats:
                + *     1. A goog.i18n.bidi.Dir constant.
                + *     2. A number (positive = LRT, negative = RTL, 0 = unknown).
                + *     3. A boolean (true = RTL, false = LTR).
                + * @return {goog.i18n.bidi.Dir} A goog.i18n.bidi.Dir constant matching the given
                + *     directionality.
                + */
                +goog.i18n.bidi.toDir = function(givenDir) {
                +  if (typeof givenDir == 'number') {
                +    return givenDir > 0 ? goog.i18n.bidi.Dir.LTR :
                +        givenDir < 0 ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.UNKNOWN;
                +  } else {
                +    return givenDir ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR;
                +  }
                +};
                +
                +
                +/**
                + * Utility class for formatting text for display in a potentially
                + * opposite-directionality context without garbling. Provides the following
                + * functionality:
                + *
                + * @param {goog.i18n.bidi.Dir|number|boolean} dir The context
                + *     directionality as a number
                + *     (positive = LRT, negative = RTL, 0 = unknown).
                + * @constructor
                + */
                +goog.i18n.BidiFormatter = function(dir) {
                +  this.dir_ = goog.i18n.bidi.toDir(dir);
                +};
                +
                +
                +/**
                + * Returns 'dir="ltr"' or 'dir="rtl"', depending on {@code text}'s estimated
                + * directionality, if it is not the same as the context directionality.
                + * Otherwise, returns the empty string.
                + *
                + * @param {string} text Text whose directionality is to be estimated.
                + * @param {boolean=} opt_isHtml Whether {@code text} is HTML / HTML-escaped.
                + *     Default: false.
                + * @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for
                + *     LTR text in non-LTR context; else, the empty string.
                + */
                +goog.i18n.BidiFormatter.prototype.dirAttr = function (text, opt_isHtml) {
                +  var dir = soy.$$bidiTextDir(text, opt_isHtml);
                +  return dir && dir != this.dir_ ? dir < 0 ? 'dir="rtl"' : 'dir="ltr"' : '';
                +};
                +
                +/**
                + * Returns the trailing horizontal edge, i.e. "right" or "left", depending on
                + * the global bidi directionality.
                + * @return {string} "left" for RTL context and "right" otherwise.
                + */
                +goog.i18n.BidiFormatter.prototype.endEdge = function () {
                +  return this.dir_ < 0 ? 'left' : 'right';
                +};
                +
                +/**
                + * Returns the Unicode BiDi mark matching the context directionality (LRM for
                + * LTR context directionality, RLM for RTL context directionality), or the
                + * empty string for neutral / unknown context directionality.
                + *
                + * @return {string} LRM for LTR context directionality and RLM for RTL context
                + *     directionality.
                + */
                +goog.i18n.BidiFormatter.prototype.mark = function () {
                +  return (
                +      (this.dir_ > 0) ? '\u200E' /*LRM*/ :
                +      (this.dir_ < 0) ? '\u200F' /*RLM*/ :
                +      '');
                +};
                +
                +/**
                + * Returns a Unicode BiDi mark matching the context directionality (LRM or RLM)
                + * if the directionality or the exit directionality of {@code text} are opposite
                + * to the context directionality. Otherwise returns the empty string.
                + *
                + * @param {string} text The input text.
                + * @param {boolean=} opt_isHtml Whether {@code text} is HTML / HTML-escaped.
                + *     Default: false.
                + * @return {string} A Unicode bidi mark matching the global directionality or
                + *     the empty string.
                + */
                +goog.i18n.BidiFormatter.prototype.markAfter = function (text, opt_isHtml) {
                +  var dir = soy.$$bidiTextDir(text, opt_isHtml);
                +  return soyshim.$$bidiMarkAfterKnownDir_(this.dir_, dir, text, opt_isHtml);
                +};
                +
                +/**
                + * Formats a string of unknown directionality for use in HTML output of the
                + * context directionality, so an opposite-directionality string is neither
                + * garbled nor garbles what follows it.
                + *
                + * @param {string} str The input text.
                + * @param {boolean=} placeholder This argument exists for consistency with the
                + *     Closure Library. Specifying it has no effect.
                + * @return {string} Input text after applying the above processing.
                + */
                +goog.i18n.BidiFormatter.prototype.spanWrap = function(str, placeholder) {
                +  str = String(str);
                +  var textDir = soy.$$bidiTextDir(str, true);
                +  var reset = soyshim.$$bidiMarkAfterKnownDir_(this.dir_, textDir, str, true);
                +  if (textDir > 0 && this.dir_ <= 0) {
                +    str = '<span dir="ltr">' + str + '</span>';
                +  } else if (textDir < 0 && this.dir_ >= 0) {
                +    str = '<span dir="rtl">' + str + '</span>';
                +  }
                +  return str + reset;
                +};
                +
                +/**
                + * Returns the leading horizontal edge, i.e. "left" or "right", depending on
                + * the global bidi directionality.
                + * @return {string} "right" for RTL context and "left" otherwise.
                + */
                +goog.i18n.BidiFormatter.prototype.startEdge = function () {
                +  return this.dir_ < 0 ? 'right' : 'left';
                +};
                +
                +/**
                + * Formats a string of unknown directionality for use in plain-text output of
                + * the context directionality, so an opposite-directionality string is neither
                + * garbled nor garbles what follows it.
                + * As opposed to {@link #spanWrap}, this makes use of unicode BiDi formatting
                + * characters. In HTML, its *only* valid use is inside of elements that do not
                + * allow mark-up, e.g. an 'option' tag.
                + *
                + * @param {string} str The input text.
                + * @param {boolean=} placeholder This argument exists for consistency with the
                + *     Closure Library. Specifying it has no effect.
                + * @return {string} Input text after applying the above processing.
                + */
                +goog.i18n.BidiFormatter.prototype.unicodeWrap = function(str, placeholder) {
                +  str = String(str);
                +  var textDir = soy.$$bidiTextDir(str, true);
                +  var reset = soyshim.$$bidiMarkAfterKnownDir_(this.dir_, textDir, str, true);
                +  if (textDir > 0 && this.dir_ <= 0) {
                +    str = '\u202A' + str + '\u202C';
                +  } else if (textDir < 0 && this.dir_ >= 0) {
                +    str = '\u202B' + str + '\u202C';
                +  }
                +  return str + reset;
                +};
                +
                +
                +if (!goog.string) {
                +  goog.string = {
                +    /**
                +     * Converts \r\n, \r, and \n to <br>s
                +     * @param {*} str The string in which to convert newlines.
                +     * @param {boolean=} opt_xml Whether to use XML compatible tags.
                +     * @return {string} A copy of {@code str} with converted newlines.
                +     */
                +    newLineToBr: function(str, opt_xml) {
                +
                +      str = String(str);
                +
                +      // This quick test helps in the case when there are no chars to replace,
                +      // in the worst case this makes barely a difference to the time taken.
                +      if (!goog.string.NEWLINE_TO_BR_RE_.test(str)) {
                +        return str;
                +      }
                +
                +      return str.replace(/(\r\n|\r|\n)/g, opt_xml ? '<br />' : '<br>');
                +    },
                +    urlEncode: encodeURIComponent,
                +    /**
                +     * Regular expression used within newlineToBr().
                +     * @type {RegExp}
                +     * @private
                +     */
                +    NEWLINE_TO_BR_RE_: /[\r\n]/
                +  };
                +}
                +
                +/**
                + * Utility class to facilitate much faster string concatenation in IE,
                + * using Array.join() rather than the '+' operator. For other browsers
                + * we simply use the '+' operator.
                + *
                + * @param {Object|number|string|boolean=} opt_a1 Optional first initial item
                + *     to append.
                + * @param {...Object|number|string|boolean} var_args Other initial items to
                + *     append, e.g., new goog.string.StringBuffer('foo', 'bar').
                + * @constructor
                + */
                +goog.string.StringBuffer = function(opt_a1, var_args) {
                +  /**
                +   * Internal buffer for the string to be concatenated.
                +   * @type {string|Array}
                +   * @private
                +   */
                +  this.buffer_ = goog.userAgent.jscript.HAS_JSCRIPT ? [] : '';
                +
                +  if (opt_a1 != null) {
                +    this.append.apply(this, arguments);
                +  }
                +};
                +
                +
                +/**
                + * Length of internal buffer (faster than calling buffer_.length).
                + * Only used for IE.
                + * @type {number}
                + * @private
                + */
                +goog.string.StringBuffer.prototype.bufferLength_ = 0;
                +
                +/**
                + * Appends one or more items to the string.
                + *
                + * Calling this with null, undefined, or empty arguments is an error.
                + *
                + * @param {Object|number|string|boolean} a1 Required first string.
                + * @param {Object|number|string|boolean=} opt_a2 Optional second string.
                + * @param {...Object|number|string|boolean} var_args Other items to append,
                + *     e.g., sb.append('foo', 'bar', 'baz').
                + * @return {goog.string.StringBuffer} This same StringBuilder object.
                + */
                +goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {
                +
                +  if (goog.userAgent.jscript.HAS_JSCRIPT) {
                +    if (opt_a2 == null) {  // no second argument (note: undefined == null)
                +      // Array assignment is 2x faster than Array push. Also, use a1
                +      // directly to avoid arguments instantiation, another 2x improvement.
                +      this.buffer_[this.bufferLength_++] = a1;
                +    } else {
                +      var arr = /**@type {Array.<number|string|boolean>}*/(this.buffer_);
                +      arr.push.apply(arr, arguments);
                +      this.bufferLength_ = this.buffer_.length;
                +    }
                +
                +  } else {
                +
                +    // Use a1 directly to avoid arguments instantiation for single-arg case.
                +    this.buffer_ += a1;
                +    if (opt_a2 != null) {  // no second argument (note: undefined == null)
                +      for (var i = 1; i < arguments.length; i++) {
                +        this.buffer_ += arguments[i];
                +      }
                +    }
                +  }
                +
                +  return this;
                +};
                +
                +
                +/**
                + * Clears the string.
                + */
                +goog.string.StringBuffer.prototype.clear = function() {
                +
                +  if (goog.userAgent.jscript.HAS_JSCRIPT) {
                +     this.buffer_.length = 0;  // reuse array to avoid creating new object
                +     this.bufferLength_ = 0;
                +
                +   } else {
                +     this.buffer_ = '';
                +   }
                +};
                +
                +
                +/**
                + * Returns the concatenated string.
                + *
                + * @return {string} The concatenated string.
                + */
                +goog.string.StringBuffer.prototype.toString = function() {
                +
                +  if (goog.userAgent.jscript.HAS_JSCRIPT) {
                +    var str = this.buffer_.join('');
                +    // Given a string with the entire contents, simplify the StringBuilder by
                +    // setting its contents to only be this string, rather than many fragments.
                +    this.clear();
                +    if (str) {
                +      this.append(str);
                +    }
                +    return str;
                +
                +  } else {
                +    return /** @type {string} */ (this.buffer_);
                +  }
                +};
                +
                +
                +if (!goog.soy) goog.soy = {
                +  /**
                +   * Helper function to render a Soy template and then set the
                +   * output string as the innerHTML of an element. It is recommended
                +   * to use this helper function instead of directly setting
                +   * innerHTML in your hand-written code, so that it will be easier
                +   * to audit the code for cross-site scripting vulnerabilities.
                +   *
                +   * @param {Function} template The Soy template defining element's content.
                +   * @param {Object=} opt_templateData The data for the template.
                +   * @param {Object=} opt_injectedData The injected data for the template.
                +   * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM
                +   *     nodes will be created.
                +   */
                +  renderAsElement: function(
                +    template, opt_templateData, opt_injectedData, opt_dom) {
                +    return /** @type {!Element} */ (soyshim.$$renderWithWrapper_(
                +        template, opt_templateData, opt_dom, true /* asElement */,
                +        opt_injectedData));
                +  },
                +  /**
                +   * Helper function to render a Soy template into a single node or
                +   * a document fragment. If the rendered HTML string represents a
                +   * single node, then that node is returned (note that this is
                +   * *not* a fragment, despite them name of the method). Otherwise a
                +   * document fragment is returned containing the rendered nodes.
                +   *
                +   * @param {Function} template The Soy template defining element's content.
                +   * @param {Object=} opt_templateData The data for the template.
                +   * @param {Object=} opt_injectedData The injected data for the template.
                +   * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM
                +   *     nodes will be created.
                +   * @return {!Node} The resulting node or document fragment.
                +   */
                +  renderAsFragment: function(
                +    template, opt_templateData, opt_injectedData, opt_dom) {
                +    return soyshim.$$renderWithWrapper_(
                +        template, opt_templateData, opt_dom, false /* asElement */,
                +        opt_injectedData);
                +  },
                +  /**
                +   * Helper function to render a Soy template and then set the output string as
                +   * the innerHTML of an element. It is recommended to use this helper function
                +   * instead of directly setting innerHTML in your hand-written code, so that it
                +   * will be easier to audit the code for cross-site scripting vulnerabilities.
                +   *
                +   * NOTE: New code should consider using goog.soy.renderElement instead.
                +   *
                +   * @param {Element} element The element whose content we are rendering.
                +   * @param {Function} template The Soy template defining the element's content.
                +   * @param {Object=} opt_templateData The data for the template.
                +   * @param {Object=} opt_injectedData The injected data for the template.
                +   */
                +  renderElement: function(
                +      element, template, opt_templateData, opt_injectedData) {
                +    element.innerHTML = template(opt_templateData, null, opt_injectedData);
                +  },
                +  data: {}
                +};
                +
                +
                +/**
                + * A type of textual content.
                + *
                + * This is an enum of type Object so that these values are unforgeable.
                + *
                + * @enum {!Object}
                + */
                +goog.soy.data.SanitizedContentKind = {
                +
                +  /**
                +   * A snippet of HTML that does not start or end inside a tag, comment, entity,
                +   * or DOCTYPE; and that does not contain any executable code
                +   * (JS, {@code <object>}s, etc.) from a different trust domain.
                +   */
                +  HTML: {},
                +
                +  /**
                +   * Executable Javascript code or expression, safe for insertion in a
                +   * script-tag or event handler context, known to be free of any
                +   * attacker-controlled scripts. This can either be side-effect-free
                +   * Javascript (such as JSON) or Javascript that entirely under Google's
                +   * control.
                +   */
                +  JS: goog.DEBUG ? {sanitizedContentJsStrChars: true} : {},
                +
                +  /**
                +   * A sequence of code units that can appear between quotes (either kind) in a
                +   * JS program without causing a parse error, and without causing any side
                +   * effects.
                +   * <p>
                +   * The content should not contain unescaped quotes, newlines, or anything else
                +   * that would cause parsing to fail or to cause a JS parser to finish the
                +   * string its parsing inside the content.
                +   * <p>
                +   * The content must also not end inside an escape sequence ; no partial octal
                +   * escape sequences or odd number of '{@code \}'s at the end.
                +   */
                +  JS_STR_CHARS: {},
                +
                +  /** A properly encoded portion of a URI. */
                +  URI: {},
                +
                +  /**
                +   * Repeated attribute names and values. For example,
                +   * {@code dir="ltr" foo="bar" onclick="trustedFunction()" checked}.
                +   */
                +  ATTRIBUTES: goog.DEBUG ? {sanitizedContentHtmlAttribute: true} : {},
                +
                +  // TODO: Consider separating rules, declarations, and values into
                +  // separate types, but for simplicity, we'll treat explicitly blessed
                +  // SanitizedContent as allowed in all of these contexts.
                +  /**
                +   * A CSS3 declaration, property, value or group of semicolon separated
                +   * declarations.
                +   */
                +  CSS: {},
                +
                +  /**
                +   * Unsanitized plain-text content.
                +   *
                +   * This is effectively the "null" entry of this enum, and is sometimes used
                +   * to explicitly mark content that should never be used unescaped. Since any
                +   * string is safe to use as text, being of ContentKind.TEXT makes no
                +   * guarantees about its safety in any other context such as HTML.
                +   */
                +  TEXT: {}
                +};
                +
                +
                +
                +/**
                + * A string-like object that carries a content-type.
                + *
                + * IMPORTANT! Do not create these directly, nor instantiate the subclasses.
                + * Instead, use a trusted, centrally reviewed library as endorsed by your team
                + * to generate these objects. Otherwise, you risk accidentally creating
                + * SanitizedContent that is attacker-controlled and gets evaluated unescaped in
                + * templates.
                + *
                + * @constructor
                + */
                +goog.soy.data.SanitizedContent = function() {
                +  throw Error('Do not instantiate directly');
                +};
                +
                +
                +/**
                + * The context in which this content is safe from XSS attacks.
                + * @type {goog.soy.data.SanitizedContentKind}
                + */
                +goog.soy.data.SanitizedContent.prototype.contentKind;
                +
                +
                +/**
                + * The already-safe content.
                + * @type {string}
                + */
                +goog.soy.data.SanitizedContent.prototype.content;
                +
                +
                +/** @override */
                +goog.soy.data.SanitizedContent.prototype.toString = function() {
                +  return this.content;
                +};
                +
                +
                +var soy = { esc: {} };
                +var soydata = {};
                +soydata.VERY_UNSAFE = {};
                +var soyshim = { $$DEFAULT_TEMPLATE_DATA_: {} };
                +/**
                + * Helper function to render a Soy template into a single node or a document
                + * fragment. If the rendered HTML string represents a single node, then that
                + * node is returned. Otherwise a document fragment is created and returned
                + * (wrapped in a DIV element if #opt_singleNode is true).
                + *
                + * @param {Function} template The Soy template defining the element's content.
                + * @param {Object=} opt_templateData The data for the template.
                + * @param {(goog.dom.DomHelper|Document)=} opt_dom The context in which DOM
                + *     nodes will be created.
                + * @param {boolean=} opt_asElement Whether to wrap the fragment in an
                + *     element if the template does not render a single element. If true,
                + *     result is always an Element.
                + * @param {Object=} opt_injectedData The injected data for the template.
                + * @return {!Node} The resulting node or document fragment.
                + * @private
                + */
                +soyshim.$$renderWithWrapper_ = function(
                +    template, opt_templateData, opt_dom, opt_asElement, opt_injectedData) {
                +
                +  var dom = opt_dom || document;
                +  var wrapper = dom.createElement('div');
                +  wrapper.innerHTML = template(
                +    opt_templateData || soyshim.$$DEFAULT_TEMPLATE_DATA_, undefined,
                +    opt_injectedData);
                +
                +  // If the template renders as a single element, return it.
                +  if (wrapper.childNodes.length == 1) {
                +    var firstChild = wrapper.firstChild;
                +    if (!opt_asElement || firstChild.nodeType == 1 /* Element */) {
                +      return /** @type {!Node} */ (firstChild);
                +    }
                +  }
                +
                +  // If we're forcing it to be a single element, return the wrapper DIV.
                +  if (opt_asElement) {
                +    return wrapper;
                +  }
                +
                +  // Otherwise, create and return a fragment.
                +  var fragment = dom.createDocumentFragment();
                +  while (wrapper.firstChild) {
                +    fragment.appendChild(wrapper.firstChild);
                +  }
                +  return fragment;
                +};
                +
                +
                +/**
                + * Returns a Unicode BiDi mark matching bidiGlobalDir (LRM or RLM) if the
                + * directionality or the exit directionality of text are opposite to
                + * bidiGlobalDir. Otherwise returns the empty string.
                + * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes
                + * in text, making the logic suitable for HTML and HTML-escaped text.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @param {number} dir text's directionality: 1 if ltr, -1 if rtl, 0 if unknown.
                + * @param {string} text The text whose directionality is to be estimated.
                + * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
                + *     Default: false.
                + * @return {string} A Unicode bidi mark matching bidiGlobalDir, or
                + *     the empty string when text's overall and exit directionalities both match
                + *     bidiGlobalDir, or bidiGlobalDir is 0 (unknown).
                + * @private
                + */
                +soyshim.$$bidiMarkAfterKnownDir_ = function(
                +    bidiGlobalDir, dir, text, opt_isHtml) {
                +  return (
                +      bidiGlobalDir > 0 && (dir < 0 ||
                +          soyshim.$$bidiIsRtlExitText_(text, opt_isHtml)) ? '\u200E' : // LRM
                +      bidiGlobalDir < 0 && (dir > 0 ||
                +          soyshim.$$bidiIsLtrExitText_(text, opt_isHtml)) ? '\u200F' : // RLM
                +      '');
                +};
                +
                +
                +/**
                + * Strips str of any HTML mark-up and escapes. Imprecise in several ways, but
                + * precision is not very important, since the result is only meant to be used
                + * for directionality detection.
                + * @param {string} str The string to be stripped.
                + * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
                + *     Default: false.
                + * @return {string} The stripped string.
                + * @private
                + */
                +soyshim.$$bidiStripHtmlIfNecessary_ = function(str, opt_isHtml) {
                +  return opt_isHtml ? str.replace(soyshim.$$BIDI_HTML_SKIP_RE_, ' ') : str;
                +};
                +
                +
                +/**
                + * Simplified regular expression for am HTML tag (opening or closing) or an HTML
                + * escape - the things we want to skip over in order to ignore their ltr
                + * characters.
                + * @type {RegExp}
                + * @private
                + */
                +soyshim.$$BIDI_HTML_SKIP_RE_ = /<[^>]*>|&[^;]+;/g;
                +
                +
                +/**
                + * A practical pattern to identify strong LTR character. This pattern is not
                + * theoretically correct according to unicode standard. It is simplified for
                + * performance and small code size.
                + * @type {string}
                + * @private
                + */
                +soyshim.$$bidiLtrChars_ =
                +    'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' +
                +    '\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF';
                +
                +
                +/**
                + * A practical pattern to identify strong neutral and weak character. This
                + * pattern is not theoretically correct according to unicode standard. It is
                + * simplified for performance and small code size.
                + * @type {string}
                + * @private
                + */
                +soyshim.$$bidiNeutralChars_ =
                +    '\u0000-\u0020!-@[-`{-\u00BF\u00D7\u00F7\u02B9-\u02FF\u2000-\u2BFF';
                +
                +
                +/**
                + * A practical pattern to identify strong RTL character. This pattern is not
                + * theoretically correct according to unicode standard. It is simplified for
                + * performance and small code size.
                + * @type {string}
                + * @private
                + */
                +soyshim.$$bidiRtlChars_ = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC';
                +
                +
                +/**
                + * Regular expressions to check if a piece of text is of RTL directionality
                + * on first character with strong directionality.
                + * @type {RegExp}
                + * @private
                + */
                +soyshim.$$bidiRtlDirCheckRe_ = new RegExp(
                +    '^[^' + soyshim.$$bidiLtrChars_ + ']*[' + soyshim.$$bidiRtlChars_ + ']');
                +
                +
                +/**
                + * Regular expressions to check if a piece of text is of neutral directionality.
                + * Url are considered as neutral.
                + * @type {RegExp}
                + * @private
                + */
                +soyshim.$$bidiNeutralDirCheckRe_ = new RegExp(
                +    '^[' + soyshim.$$bidiNeutralChars_ + ']*$|^http://');
                +
                +
                +/**
                + * Check the directionality of the a piece of text based on the first character
                + * with strong directionality.
                + * @param {string} str string being checked.
                + * @return {boolean} return true if rtl directionality is being detected.
                + * @private
                + */
                +soyshim.$$bidiIsRtlText_ = function(str) {
                +  return soyshim.$$bidiRtlDirCheckRe_.test(str);
                +};
                +
                +
                +/**
                + * Check the directionality of the a piece of text based on the first character
                + * with strong directionality.
                + * @param {string} str string being checked.
                + * @return {boolean} true if all characters have neutral directionality.
                + * @private
                + */
                +soyshim.$$bidiIsNeutralText_ = function(str) {
                +  return soyshim.$$bidiNeutralDirCheckRe_.test(str);
                +};
                +
                +
                +/**
                + * This constant controls threshold of rtl directionality.
                + * @type {number}
                + * @private
                + */
                +soyshim.$$bidiRtlDetectionThreshold_ = 0.40;
                +
                +
                +/**
                + * Returns the RTL ratio based on word count.
                + * @param {string} str the string that need to be checked.
                + * @return {number} the ratio of RTL words among all words with directionality.
                + * @private
                + */
                +soyshim.$$bidiRtlWordRatio_ = function(str) {
                +  var rtlCount = 0;
                +  var totalCount = 0;
                +  var tokens = str.split(' ');
                +  for (var i = 0; i < tokens.length; i++) {
                +    if (soyshim.$$bidiIsRtlText_(tokens[i])) {
                +      rtlCount++;
                +      totalCount++;
                +    } else if (!soyshim.$$bidiIsNeutralText_(tokens[i])) {
                +      totalCount++;
                +    }
                +  }
                +
                +  return totalCount == 0 ? 0 : rtlCount / totalCount;
                +};
                +
                +
                +/**
                + * Regular expressions to check if the last strongly-directional character in a
                + * piece of text is LTR.
                + * @type {RegExp}
                + * @private
                + */
                +soyshim.$$bidiLtrExitDirCheckRe_ = new RegExp(
                +    '[' + soyshim.$$bidiLtrChars_ + '][^' + soyshim.$$bidiRtlChars_ + ']*$');
                +
                +
                +/**
                + * Regular expressions to check if the last strongly-directional character in a
                + * piece of text is RTL.
                + * @type {RegExp}
                + * @private
                + */
                +soyshim.$$bidiRtlExitDirCheckRe_ = new RegExp(
                +    '[' + soyshim.$$bidiRtlChars_ + '][^' + soyshim.$$bidiLtrChars_ + ']*$');
                +
                +
                +/**
                + * Check if the exit directionality a piece of text is LTR, i.e. if the last
                + * strongly-directional character in the string is LTR.
                + * @param {string} str string being checked.
                + * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
                + *     Default: false.
                + * @return {boolean} Whether LTR exit directionality was detected.
                + * @private
                + */
                +soyshim.$$bidiIsLtrExitText_ = function(str, opt_isHtml) {
                +  str = soyshim.$$bidiStripHtmlIfNecessary_(str, opt_isHtml);
                +  return soyshim.$$bidiLtrExitDirCheckRe_.test(str);
                +};
                +
                +
                +/**
                + * Check if the exit directionality a piece of text is RTL, i.e. if the last
                + * strongly-directional character in the string is RTL.
                + * @param {string} str string being checked.
                + * @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
                + *     Default: false.
                + * @return {boolean} Whether RTL exit directionality was detected.
                + * @private
                + */
                +soyshim.$$bidiIsRtlExitText_ = function(str, opt_isHtml) {
                +  str = soyshim.$$bidiStripHtmlIfNecessary_(str, opt_isHtml);
                +  return soyshim.$$bidiRtlExitDirCheckRe_.test(str);
                +};
                +
                +
                +// =============================================================================
                +// COPIED FROM soyutils_usegoog.js
                +
                +
                +// -----------------------------------------------------------------------------
                +// StringBuilder (compatible with the 'stringbuilder' code style).
                +
                +
                +/**
                + * Utility class to facilitate much faster string concatenation in IE,
                + * using Array.join() rather than the '+' operator. For other browsers
                + * we simply use the '+' operator.
                + *
                + * @param {Object} var_args Initial items to append,
                + *     e.g., new soy.StringBuilder('foo', 'bar').
                + * @constructor
                + */
                +soy.StringBuilder = goog.string.StringBuffer;
                +
                +
                +// -----------------------------------------------------------------------------
                +// soydata: Defines typed strings, e.g. an HTML string {@code "a<b>c"} is
                +// semantically distinct from the plain text string {@code "a<b>c"} and smart
                +// templates can take that distinction into account.
                +
                +/**
                + * A type of textual content.
                + *
                + * This is an enum of type Object so that these values are unforgeable.
                + *
                + * @enum {!Object}
                + */
                +soydata.SanitizedContentKind = goog.soy.data.SanitizedContentKind;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.HTML}.
                + *
                + * The content is a string of HTML that can safely be embedded in a PCDATA
                + * context in your app.  If you would be surprised to find that an HTML
                + * sanitizer produced {@code s} (e.g.  it runs code or fetches bad URLs) and
                + * you wouldn't write a template that produces {@code s} on security or privacy
                + * grounds, then don't pass {@code s} here.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedHtml = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedHtml, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedHtml.prototype.contentKind = soydata.SanitizedContentKind.HTML;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.JS}.
                + *
                + * The content is Javascript source that when evaluated does not execute any
                + * attacker-controlled scripts.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedJs = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedJs, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedJs.prototype.contentKind =
                +    soydata.SanitizedContentKind.JS;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.JS_STR_CHARS}.
                + *
                + * The content can be safely inserted as part of a single- or double-quoted
                + * string without terminating the string.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedJsStrChars = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedJsStrChars, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedJsStrChars.prototype.contentKind =
                +    soydata.SanitizedContentKind.JS_STR_CHARS;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.URI}.
                + *
                + * The content is a URI chunk that the caller knows is safe to emit in a
                + * template.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedUri = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedUri, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedUri.prototype.contentKind = soydata.SanitizedContentKind.URI;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.ATTRIBUTES}.
                + *
                + * The content should be safely embeddable within an open tag, such as a
                + * key="value" pair.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedHtmlAttribute = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedHtmlAttribute, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedHtmlAttribute.prototype.contentKind =
                +    soydata.SanitizedContentKind.ATTRIBUTES;
                +
                +
                +/**
                + * Content of type {@link soydata.SanitizedContentKind.CSS}.
                + *
                + * The content is non-attacker-exploitable CSS, such as {@code color:#c3d9ff}.
                + *
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.SanitizedCss = function() {
                +  goog.soy.data.SanitizedContent.call(this);  // Throws an exception.
                +};
                +goog.inherits(soydata.SanitizedCss, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.SanitizedCss.prototype.contentKind =
                +    soydata.SanitizedContentKind.CSS;
                +
                +
                +/**
                + * Unsanitized plain text string.
                + *
                + * While all strings are effectively safe to use as a plain text, there are no
                + * guarantees about safety in any other context such as HTML. This is
                + * sometimes used to mark that should never be used unescaped.
                + *
                + * @param {*} content Plain text with no guarantees.
                + * @constructor
                + * @extends {goog.soy.data.SanitizedContent}
                + */
                +soydata.UnsanitizedText = function(content) {
                +  /** @override */
                +  this.content = String(content);
                +};
                +goog.inherits(soydata.UnsanitizedText, goog.soy.data.SanitizedContent);
                +
                +/** @override */
                +soydata.UnsanitizedText.prototype.contentKind =
                +    soydata.SanitizedContentKind.TEXT;
                +
                +
                +/**
                + * Creates a factory for SanitizedContent types.
                + *
                + * This is a hack so that the soydata.VERY_UNSAFE.ordainSanitized* can
                + * instantiate Sanitized* classes, without making the Sanitized* constructors
                + * publicly usable. Requiring all construction to use the VERY_UNSAFE names
                + * helps callers and their reviewers easily tell that creating SanitizedContent
                + * is not always safe and calls for careful review.
                + *
                + * @param {function(new: T, string)} ctor A constructor.
                + * @return {!function(*): T} A factory that takes content and returns a
                + *     new instance.
                + * @template T
                + * @private
                + */
                +soydata.$$makeSanitizedContentFactory_ = function(ctor) {
                +  /** @constructor */
                +  function InstantiableCtor() {}
                +  InstantiableCtor.prototype = ctor.prototype;
                +  return function(content) {
                +    var result = new InstantiableCtor();
                +    result.content = String(content);
                +    return result;
                +  };
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Sanitized content ordainers. Please use these with extreme caution (with the
                +// exception of markUnsanitizedText). A good recommendation is to limit usage
                +// of these to just a handful of files in your source tree where usages can be
                +// carefully audited.
                +
                +
                +/**
                + * Protects a string from being used in an noAutoescaped context.
                + *
                + * This is useful for content where there is significant risk of accidental
                + * unescaped usage in a Soy template. A great case is for user-controlled
                + * data that has historically been a source of vulernabilities.
                + *
                + * @param {*} content Text to protect.
                + * @return {!soydata.UnsanitizedText} A wrapper that is rejected by the
                + *     Soy noAutoescape print directive.
                + */
                +soydata.markUnsanitizedText = function(content) {
                +  return new soydata.UnsanitizedText(content);
                +};
                +
                +
                +/**
                + * Takes a leap of faith that the provided content is "safe" HTML.
                + *
                + * @param {*} content A string of HTML that can safely be embedded in
                + *     a PCDATA context in your app. If you would be surprised to find that an
                + *     HTML sanitizer produced {@code s} (e.g. it runs code or fetches bad URLs)
                + *     and you wouldn't write a template that produces {@code s} on security or
                + *     privacy grounds, then don't pass {@code s} here.
                + * @return {!soydata.SanitizedHtml} Sanitized content wrapper that
                + *     indicates to Soy not to escape when printed as HTML.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedHtml =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedHtml);
                +
                +
                +/**
                + * Takes a leap of faith that the provided content is "safe" (non-attacker-
                + * controlled, XSS-free) Javascript.
                + *
                + * @param {*} content Javascript source that when evaluated does not
                + *     execute any attacker-controlled scripts.
                + * @return {!soydata.SanitizedJs} Sanitized content wrapper that indicates to
                + *     Soy not to escape when printed as Javascript source.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedJs =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedJs);
                +
                +
                +// TODO: This function is probably necessary, either externally or internally
                +// as an implementation detail. Generally, plain text will always work here,
                +// as there's no harm to unescaping the string and then re-escaping when
                +// finally printed.
                +/**
                + * Takes a leap of faith that the provided content can be safely embedded in
                + * a Javascript string without re-esacping.
                + *
                + * @param {*} content Content that can be safely inserted as part of a
                + *     single- or double-quoted string without terminating the string.
                + * @return {!soydata.SanitizedJsStrChars} Sanitized content wrapper that
                + *     indicates to Soy not to escape when printed in a JS string.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedJsStrChars =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedJsStrChars);
                +
                +
                +/**
                + * Takes a leap of faith that the provided content is "safe" to use as a URI
                + * in a Soy template.
                + *
                + * This creates a Soy SanitizedContent object which indicates to Soy there is
                + * no need to escape it when printed as a URI (e.g. in an href or src
                + * attribute), such as if it's already been encoded or  if it's a Javascript:
                + * URI.
                + *
                + * @param {*} content A chunk of URI that the caller knows is safe to
                + *     emit in a template.
                + * @return {!soydata.SanitizedUri} Sanitized content wrapper that indicates to
                + *     Soy not to escape or filter when printed in URI context.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedUri =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedUri);
                +
                +
                +/**
                + * Takes a leap of faith that the provided content is "safe" to use as an
                + * HTML attribute.
                + *
                + * @param {*} content An attribute name and value, such as
                + *     {@code dir="ltr"}.
                + * @return {!soydata.SanitizedHtmlAttribute} Sanitized content wrapper that
                + *     indicates to Soy not to escape when printed as an HTML attribute.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedHtmlAttribute =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedHtmlAttribute);
                +
                +
                +/**
                + * Takes a leap of faith that the provided content is "safe" to use as CSS
                + * in a style attribute or block.
                + *
                + * @param {*} content CSS, such as {@code color:#c3d9ff}.
                + * @return {!soydata.SanitizedCss} Sanitized CSS wrapper that indicates to
                + *     Soy there is no need to escape or filter when printed in CSS context.
                + */
                +soydata.VERY_UNSAFE.ordainSanitizedCss =
                +    soydata.$$makeSanitizedContentFactory_(soydata.SanitizedCss);
                +
                +
                +// -----------------------------------------------------------------------------
                +// Public utilities.
                +
                +
                +/**
                + * Helper function to render a Soy template and then set the output string as
                + * the innerHTML of an element. It is recommended to use this helper function
                + * instead of directly setting innerHTML in your hand-written code, so that it
                + * will be easier to audit the code for cross-site scripting vulnerabilities.
                + *
                + * NOTE: New code should consider using goog.soy.renderElement instead.
                + *
                + * @param {Element} element The element whose content we are rendering.
                + * @param {Function} template The Soy template defining the element's content.
                + * @param {Object=} opt_templateData The data for the template.
                + * @param {Object=} opt_injectedData The injected data for the template.
                + */
                +soy.renderElement = goog.soy.renderElement;
                +
                +
                +/**
                + * Helper function to render a Soy template into a single node or a document
                + * fragment. If the rendered HTML string represents a single node, then that
                + * node is returned (note that this is *not* a fragment, despite them name of
                + * the method). Otherwise a document fragment is returned containing the
                + * rendered nodes.
                + *
                + * NOTE: New code should consider using goog.soy.renderAsFragment
                + * instead (note that the arguments are different).
                + *
                + * @param {Function} template The Soy template defining the element's content.
                + * @param {Object=} opt_templateData The data for the template.
                + * @param {Document=} opt_document The document used to create DOM nodes. If not
                + *     specified, global document object is used.
                + * @param {Object=} opt_injectedData The injected data for the template.
                + * @return {!Node} The resulting node or document fragment.
                + */
                +soy.renderAsFragment = function(
                +    template, opt_templateData, opt_document, opt_injectedData) {
                +  return goog.soy.renderAsFragment(
                +      template, opt_templateData, opt_injectedData,
                +      new goog.dom.DomHelper(opt_document));
                +};
                +
                +
                +/**
                + * Helper function to render a Soy template into a single node. If the rendered
                + * HTML string represents a single node, then that node is returned. Otherwise,
                + * a DIV element is returned containing the rendered nodes.
                + *
                + * NOTE: New code should consider using goog.soy.renderAsElement
                + * instead (note that the arguments are different).
                + *
                + * @param {Function} template The Soy template defining the element's content.
                + * @param {Object=} opt_templateData The data for the template.
                + * @param {Document=} opt_document The document used to create DOM nodes. If not
                + *     specified, global document object is used.
                + * @param {Object=} opt_injectedData The injected data for the template.
                + * @return {!Element} Rendered template contents, wrapped in a parent DIV
                + *     element if necessary.
                + */
                +soy.renderAsElement = function(
                +    template, opt_templateData, opt_document, opt_injectedData) {
                +  return goog.soy.renderAsElement(
                +      template, opt_templateData, opt_injectedData,
                +      new goog.dom.DomHelper(opt_document));
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Below are private utilities to be used by Soy-generated code only.
                +
                +
                +/**
                + * Builds an augmented map. The returned map will contain mappings from both
                + * the base map and the additional map. If the same key appears in both, then
                + * the value from the additional map will be visible, while the value from the
                + * base map will be hidden. The base map will be used, but not modified.
                + *
                + * @param {!Object} baseMap The original map to augment.
                + * @param {!Object} additionalMap A map containing the additional mappings.
                + * @return {!Object} An augmented map containing both the original and
                + *     additional mappings.
                + */
                +soy.$$augmentMap = function(baseMap, additionalMap) {
                +
                +  // Create a new map whose '__proto__' field is set to baseMap.
                +  /** @constructor */
                +  function TempCtor() {}
                +  TempCtor.prototype = baseMap;
                +  var augmentedMap = new TempCtor();
                +
                +  // Add the additional mappings to the new map.
                +  for (var key in additionalMap) {
                +    augmentedMap[key] = additionalMap[key];
                +  }
                +
                +  return augmentedMap;
                +};
                +
                +
                +/**
                + * Checks that the given map key is a string.
                + * @param {*} key Key to check.
                + * @return {string} The given key.
                + */
                +soy.$$checkMapKey = function(key) {
                +  if ((typeof key) != 'string') {
                +    throw Error(
                +        'Map literal\'s key expression must evaluate to string' +
                +        ' (encountered type "' + (typeof key) + '").');
                +  }
                +  return key;
                +};
                +
                +
                +/**
                + * Gets the keys in a map as an array. There are no guarantees on the order.
                + * @param {Object} map The map to get the keys of.
                + * @return {Array.<string>} The array of keys in the given map.
                + */
                +soy.$$getMapKeys = function(map) {
                +  var mapKeys = [];
                +  for (var key in map) {
                +    mapKeys.push(key);
                +  }
                +  return mapKeys;
                +};
                +
                +
                +/**
                + * Gets a consistent unique id for the given delegate template name. Two calls
                + * to this function will return the same id if and only if the input names are
                + * the same.
                + *
                + * <p> Important: This function must always be called with a string constant.
                + *
                + * <p> If Closure Compiler is not being used, then this is just this identity
                + * function. If Closure Compiler is being used, then each call to this function
                + * will be replaced with a short string constant, which will be consistent per
                + * input name.
                + *
                + * @param {string} delTemplateName The delegate template name for which to get a
                + *     consistent unique id.
                + * @return {string} A unique id that is consistent per input name.
                + *
                + * @consistentIdGenerator
                + */
                +soy.$$getDelTemplateId = function(delTemplateName) {
                +  return delTemplateName;
                +};
                +
                +
                +/**
                + * Map from registered delegate template key to the priority of the
                + * implementation.
                + * @type {Object}
                + * @private
                + */
                +soy.$$DELEGATE_REGISTRY_PRIORITIES_ = {};
                +
                +/**
                + * Map from registered delegate template key to the implementation function.
                + * @type {Object}
                + * @private
                + */
                +soy.$$DELEGATE_REGISTRY_FUNCTIONS_ = {};
                +
                +
                +/**
                + * Registers a delegate implementation. If the same delegate template key (id
                + * and variant) has been registered previously, then priority values are
                + * compared and only the higher priority implementation is stored (if
                + * priorities are equal, an error is thrown).
                + *
                + * @param {string} delTemplateId The delegate template id.
                + * @param {string} delTemplateVariant The delegate template variant (can be
                + *     empty string).
                + * @param {number} delPriority The implementation's priority value.
                + * @param {Function} delFn The implementation function.
                + */
                +soy.$$registerDelegateFn = function(
                +    delTemplateId, delTemplateVariant, delPriority, delFn) {
                +
                +  var mapKey = 'key_' + delTemplateId + ':' + delTemplateVariant;
                +  var currPriority = soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey];
                +  if (currPriority === undefined || delPriority > currPriority) {
                +    // Registering new or higher-priority function: replace registry entry.
                +    soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey] = delPriority;
                +    soy.$$DELEGATE_REGISTRY_FUNCTIONS_[mapKey] = delFn;
                +  } else if (delPriority == currPriority) {
                +    // Registering same-priority function: error.
                +    throw Error(
                +        'Encountered two active delegates with the same priority ("' +
                +            delTemplateId + ':' + delTemplateVariant + '").');
                +  } else {
                +    // Registering lower-priority function: do nothing.
                +  }
                +};
                +
                +
                +/**
                + * Retrieves the (highest-priority) implementation that has been registered for
                + * a given delegate template key (id and variant). If no implementation has
                + * been registered for the key, then the fallback is the same id with empty
                + * variant. If the fallback is also not registered, and allowsEmptyDefault is
                + * true, then returns an implementation that is equivalent to an empty template
                + * (i.e. rendered output would be empty string).
                + *
                + * @param {string} delTemplateId The delegate template id.
                + * @param {string} delTemplateVariant The delegate template variant (can be
                + *     empty string).
                + * @param {boolean} allowsEmptyDefault Whether to default to the empty template
                + *     function if there's no active implementation.
                + * @return {Function} The retrieved implementation function.
                + */
                +soy.$$getDelegateFn = function(
                +    delTemplateId, delTemplateVariant, allowsEmptyDefault) {
                +
                +  var delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_[
                +      'key_' + delTemplateId + ':' + delTemplateVariant];
                +  if (! delFn && delTemplateVariant != '') {
                +    // Fallback to empty variant.
                +    delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_['key_' + delTemplateId + ':'];
                +  }
                +
                +  if (delFn) {
                +    return delFn;
                +  } else if (allowsEmptyDefault) {
                +    return soy.$$EMPTY_TEMPLATE_FN_;
                +  } else {
                +    throw Error(
                +        'Found no active impl for delegate call to "' + delTemplateId + ':' +
                +            delTemplateVariant + '" (and not allowemptydefault="true").');
                +  }
                +};
                +
                +
                +/**
                + * Private helper soy.$$getDelegateFn(). This is the empty template function
                + * that is returned whenever there's no delegate implementation found.
                + *
                + * @param {Object.<string, *>=} opt_data
                + * @param {soy.StringBuilder=} opt_sb
                + * @param {Object.<string, *>=} opt_ijData
                + * @return {string}
                + * @private
                + */
                +soy.$$EMPTY_TEMPLATE_FN_ = function(opt_data, opt_sb, opt_ijData) {
                +  return '';
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Escape/filter/normalize.
                +
                +
                +/**
                + * Escapes HTML special characters in a string. Escapes double quote '"' in
                + * addition to '&', '<', and '>' so that a string can be included in an HTML
                + * tag attribute value within double quotes.
                + * Will emit known safe HTML as-is.
                + *
                + * @param {*} value The string-like value to be escaped. May not be a string,
                + *     but the value will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeHtml = function(value) {
                +  // TODO: Perhaps we should just ignore the contentKind property and instead
                +  // look only at the constructor.
                +  if (value && value.contentKind &&
                +      value.contentKind === goog.soy.data.SanitizedContentKind.HTML) {
                +    goog.asserts.assert(
                +        value.constructor === soydata.SanitizedHtml);
                +    return value.content;
                +  }
                +  return soy.esc.$$escapeHtmlHelper(value);
                +};
                +
                +
                +/**
                + * Strips unsafe tags to convert a string of untrusted HTML into HTML that
                + * is safe to embed.
                + *
                + * @param {*} value The string-like value to be escaped. May not be a string,
                + *     but the value will be coerced to a string.
                + * @return {string} A sanitized and normalized version of value.
                + */
                +soy.$$cleanHtml = function(value) {
                +  if (value && value.contentKind &&
                +      value.contentKind === goog.soy.data.SanitizedContentKind.HTML) {
                +    goog.asserts.assert(
                +        value.constructor === soydata.SanitizedHtml);
                +    return value.content;
                +  }
                +  return soy.$$stripHtmlTags(value, soy.esc.$$SAFE_TAG_WHITELIST_);
                +};
                +
                +
                +/**
                + * Escapes HTML special characters in a string so that it can be embedded in
                + * RCDATA.
                + * <p>
                + * Escapes HTML special characters so that the value will not prematurely end
                + * the body of a tag like {@code <textarea>} or {@code <title>}. RCDATA tags
                + * cannot contain other HTML entities, so it is not strictly necessary to escape
                + * HTML special characters except when part of that text looks like an HTML
                + * entity or like a close tag : {@code </textarea>}.
                + * <p>
                + * Will normalize known safe HTML to make sure that sanitized HTML (which could
                + * contain an innocuous {@code </textarea>} don't prematurely end an RCDATA
                + * element.
                + *
                + * @param {*} value The string-like value to be escaped. May not be a string,
                + *     but the value will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeHtmlRcdata = function(value) {
                +  if (value && value.contentKind &&
                +      value.contentKind === goog.soy.data.SanitizedContentKind.HTML) {
                +    goog.asserts.assert(
                +        value.constructor === soydata.SanitizedHtml);
                +    return soy.esc.$$normalizeHtmlHelper(value.content);
                +  }
                +  return soy.esc.$$escapeHtmlHelper(value);
                +};
                +
                +
                +/**
                + * Matches any/only HTML5 void elements' start tags.
                + * See http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
                + * @type {RegExp}
                + * @private
                + */
                +soy.$$HTML5_VOID_ELEMENTS_ = new RegExp(
                +    '^<(?:area|base|br|col|command|embed|hr|img|input' +
                +    '|keygen|link|meta|param|source|track|wbr)\\b');
                +
                +
                +/**
                + * Removes HTML tags from a string of known safe HTML.
                + * If opt_tagWhitelist is not specified or is empty, then
                + * the result can be used as an attribute value.
                + *
                + * @param {*} value The HTML to be escaped. May not be a string, but the
                + *     value will be coerced to a string.
                + * @param {Object.<string, number>=} opt_tagWhitelist Has an own property whose
                + *     name is a lower-case tag name and whose value is {@code 1} for
                + *     each element that is allowed in the output.
                + * @return {string} A representation of value without disallowed tags,
                + *     HTML comments, or other non-text content.
                + */
                +soy.$$stripHtmlTags = function(value, opt_tagWhitelist) {
                +  if (!opt_tagWhitelist) {
                +    // If we have no white-list, then use a fast track which elides all tags.
                +    return String(value).replace(soy.esc.$$HTML_TAG_REGEX_, '')
                +        // This is just paranoia since callers should normalize the result
                +        // anyway, but if they didn't, it would be necessary to ensure that
                +        // after the first replace non-tag uses of < do not recombine into
                +        // tags as in "<<foo>script>alert(1337)</<foo>script>".
                +        .replace(soy.esc.$$LT_REGEX_, '&lt;');
                +  }
                +
                +  // Escapes '[' so that we can use [123] below to mark places where tags
                +  // have been removed.
                +  var html = String(value).replace(/\[/g, '&#91;');
                +
                +  // Consider all uses of '<' and replace whitelisted tags with markers like
                +  // [1] which are indices into a list of approved tag names.
                +  // Replace all other uses of < and > with entities.
                +  var tags = [];
                +  html = html.replace(
                +    soy.esc.$$HTML_TAG_REGEX_,
                +    function(tok, tagName) {
                +      if (tagName) {
                +        tagName = tagName.toLowerCase();
                +        if (opt_tagWhitelist.hasOwnProperty(tagName) &&
                +            opt_tagWhitelist[tagName]) {
                +          var start = tok.charAt(1) === '/' ? '</' : '<';
                +          var index = tags.length;
                +          tags[index] = start + tagName + '>';
                +          return '[' + index + ']';
                +        }
                +      }
                +      return '';
                +    });
                +
                +  // Escape HTML special characters. Now there are no '<' in html that could
                +  // start a tag.
                +  html = soy.esc.$$normalizeHtmlHelper(html);
                +
                +  var finalCloseTags = soy.$$balanceTags_(tags);
                +
                +  // Now html contains no tags or less-than characters that could become
                +  // part of a tag via a replacement operation and tags only contains
                +  // approved tags.
                +  // Reinsert the white-listed tags.
                +  html = html.replace(
                +       /\[(\d+)\]/g, function(_, index) { return tags[index]; });
                +
                +  // Close any still open tags.
                +  // This prevents unclosed formatting elements like <ol> and <table> from
                +  // breaking the layout of containing HTML.
                +  return html + finalCloseTags;
                +};
                +
                +
                +/**
                + * Throw out any close tags that don't correspond to start tags.
                + * If {@code <table>} is used for formatting, embedded HTML shouldn't be able
                + * to use a mismatched {@code </table>} to break page layout.
                + *
                + * @param {Array.<string>} tags an array of tags that will be modified in place
                + *    include tags, the empty string, or concatenations of empty tags.
                + * @return {string} zero or more closed tags that close all elements that are
                + *    opened in tags but not closed.
                + * @private
                + */
                +soy.$$balanceTags_ = function(tags) {
                +  var open = [];
                +  for (var i = 0, n = tags.length; i < n; ++i) {
                +    var tag = tags[i];
                +    if (tag.charAt(1) === '/') {
                +      var openTagIndex = open.length - 1;
                +      // NOTE: This is essentially lastIndexOf, but it's not supported in IE.
                +      while (openTagIndex >= 0 && open[openTagIndex] != tag) {
                +        openTagIndex--;
                +      }
                +      if (openTagIndex < 0) {
                +        tags[i] = '';  // Drop close tag.
                +      } else {
                +        tags[i] = open.slice(openTagIndex).reverse().join('');
                +        open.length = openTagIndex;
                +      }
                +    } else if (!soy.$$HTML5_VOID_ELEMENTS_.test(tag)) {
                +      open.push('</' + tag.substring(1));
                +    }
                +  }
                +  return open.reverse().join('');
                +};
                +
                +
                +/**
                + * Escapes HTML special characters in an HTML attribute value.
                + *
                + * @param {*} value The HTML to be escaped. May not be a string, but the
                + *     value will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeHtmlAttribute = function(value) {
                +  if (value && value.contentKind) {
                +    // NOTE: We don't accept ATTRIBUTES here because ATTRIBUTES is
                +    // actually not the attribute value context, but instead k/v pairs.
                +    if (value.contentKind === goog.soy.data.SanitizedContentKind.HTML) {
                +      // NOTE: After removing tags, we also escape quotes ("normalize") so that
                +      // the HTML can be embedded in attribute context.
                +      goog.asserts.assert(
                +          value.constructor === soydata.SanitizedHtml);
                +      return soy.esc.$$normalizeHtmlHelper(soy.$$stripHtmlTags(value.content));
                +    }
                +  }
                +  return soy.esc.$$escapeHtmlHelper(value);
                +};
                +
                +
                +/**
                + * Escapes HTML special characters in a string including space and other
                + * characters that can end an unquoted HTML attribute value.
                + *
                + * @param {*} value The HTML to be escaped. May not be a string, but the
                + *     value will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeHtmlAttributeNospace = function(value) {
                +  if (value && value.contentKind) {
                +    if (value.contentKind === goog.soy.data.SanitizedContentKind.HTML) {
                +      goog.asserts.assert(value.constructor ===
                +          soydata.SanitizedHtml);
                +      return soy.esc.$$normalizeHtmlNospaceHelper(
                +          soy.$$stripHtmlTags(value.content));
                +    }
                +  }
                +  return soy.esc.$$escapeHtmlNospaceHelper(value);
                +};
                +
                +
                +/**
                + * Filters out strings that cannot be a substring of a valid HTML attribute.
                + *
                + * Note the input is expected to be key=value pairs.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} A valid HTML attribute name part or name/value pair.
                + *     {@code "zSoyz"} if the input is invalid.
                + */
                +soy.$$filterHtmlAttributes = function(value) {
                +  // NOTE: Explicitly no support for SanitizedContentKind.HTML, since that is
                +  // meaningless in this context, which is generally *between* html attributes.
                +  if (value &&
                +      value.contentKind === goog.soy.data.SanitizedContentKind.ATTRIBUTES) {
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedHtmlAttribute);
                +    // Add a space at the end to ensure this won't get merged into following
                +    // attributes, unless the interpretation is unambiguous (ending with quotes
                +    // or a space).
                +    return value.content.replace(/([^"'\s])$/, '$1 ');
                +  }
                +  // TODO: Dynamically inserting attributes that aren't marked as trusted is
                +  // probably unnecessary.  Any filtering done here will either be inadequate
                +  // for security or not flexible enough.  Having clients use kind="attributes"
                +  // in parameters seems like a wiser idea.
                +  return soy.esc.$$filterHtmlAttributesHelper(value);
                +};
                +
                +
                +/**
                + * Filters out strings that cannot be a substring of a valid HTML element name.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} A valid HTML element name part.
                + *     {@code "zSoyz"} if the input is invalid.
                + */
                +soy.$$filterHtmlElementName = function(value) {
                +  // NOTE: We don't accept any SanitizedContent here. HTML indicates valid
                +  // PCDATA, not tag names. A sloppy developer shouldn't be able to cause an
                +  // exploit:
                +  // ... {let userInput}script src=http://evil.com/evil.js{/let} ...
                +  // ... {param tagName kind="html"}{$userInput}{/param} ...
                +  // ... <{$tagName}>Hello World</{$tagName}>
                +  return soy.esc.$$filterHtmlElementNameHelper(value);
                +};
                +
                +
                +/**
                + * Escapes characters in the value to make it valid content for a JS string
                + * literal.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + * @deprecated
                + */
                +soy.$$escapeJs = function(value) {
                +  return soy.$$escapeJsString(value);
                +};
                +
                +
                +/**
                + * Escapes characters in the value to make it valid content for a JS string
                + * literal.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeJsString = function(value) {
                +  if (value &&
                +      value.contentKind === goog.soy.data.SanitizedContentKind.JS_STR_CHARS) {
                +    // TODO: It might still be worthwhile to normalize it to remove
                +    // unescaped quotes, null, etc: replace(/(?:^|[^\])['"]/g, '\\$
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedJsStrChars);
                +    return value.content;
                +  }
                +  return soy.esc.$$escapeJsStringHelper(value);
                +};
                +
                +
                +/**
                + * Encodes a value as a JavaScript literal.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} A JavaScript code representation of the input.
                + */
                +soy.$$escapeJsValue = function(value) {
                +  // We surround values with spaces so that they can't be interpolated into
                +  // identifiers by accident.
                +  // We could use parentheses but those might be interpreted as a function call.
                +  if (value == null) {  // Intentionally matches undefined.
                +    // Java returns null from maps where there is no corresponding key while
                +    // JS returns undefined.
                +    // We always output null for compatibility with Java which does not have a
                +    // distinct undefined value.
                +    return ' null ';
                +  }
                +  if (value.contentKind == goog.soy.data.SanitizedContentKind.JS) {
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedJs);
                +    return value.content;
                +  }
                +  switch (typeof value) {
                +    case 'boolean': case 'number':
                +      return ' ' + value + ' ';
                +    default:
                +      return "'" + soy.esc.$$escapeJsStringHelper(String(value)) + "'";
                +  }
                +};
                +
                +
                +/**
                + * Escapes characters in the string to make it valid content for a JS regular
                + * expression literal.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeJsRegex = function(value) {
                +  return soy.esc.$$escapeJsRegexHelper(value);
                +};
                +
                +
                +/**
                + * Matches all URI mark characters that conflict with HTML attribute delimiters
                + * or that cannot appear in a CSS uri.
                + * From <a href="http://www.w3.org/TR/CSS2/grammar.html">G.2: CSS grammar</a>
                + * <pre>
                + *     url        ([!#$%&*-~]|{nonascii}|{escape})*
                + * </pre>
                + *
                + * @type {RegExp}
                + * @private
                + */
                +soy.$$problematicUriMarks_ = /['()]/g;
                +
                +/**
                + * @param {string} ch A single character in {@link soy.$$problematicUriMarks_}.
                + * @return {string}
                + * @private
                + */
                +soy.$$pctEncode_ = function(ch) {
                +  return '%' + ch.charCodeAt(0).toString(16);
                +};
                +
                +/**
                + * Escapes a string so that it can be safely included in a URI.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeUri = function(value) {
                +  if (value && value.contentKind === goog.soy.data.SanitizedContentKind.URI) {
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedUri);
                +    return soy.$$normalizeUri(value);
                +  }
                +  // Apostophes and parentheses are not matched by encodeURIComponent.
                +  // They are technically special in URIs, but only appear in the obsolete mark
                +  // production in Appendix D.2 of RFC 3986, so can be encoded without changing
                +  // semantics.
                +  var encoded = soy.esc.$$escapeUriHelper(value);
                +  soy.$$problematicUriMarks_.lastIndex = 0;
                +  if (soy.$$problematicUriMarks_.test(encoded)) {
                +    return encoded.replace(soy.$$problematicUriMarks_, soy.$$pctEncode_);
                +  }
                +  return encoded;
                +};
                +
                +
                +/**
                + * Removes rough edges from a URI by escaping any raw HTML/JS string delimiters.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$normalizeUri = function(value) {
                +  return soy.esc.$$normalizeUriHelper(value);
                +};
                +
                +
                +/**
                + * Vets a URI's protocol and removes rough edges from a URI by escaping
                + * any raw HTML/JS string delimiters.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$filterNormalizeUri = function(value) {
                +  if (value && value.contentKind == goog.soy.data.SanitizedContentKind.URI) {
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedUri);
                +    return soy.$$normalizeUri(value);
                +  }
                +  return soy.esc.$$filterNormalizeUriHelper(value);
                +};
                +
                +
                +/**
                + * Escapes a string so it can safely be included inside a quoted CSS string.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} An escaped version of value.
                + */
                +soy.$$escapeCssString = function(value) {
                +  return soy.esc.$$escapeCssStringHelper(value);
                +};
                +
                +
                +/**
                + * Encodes a value as a CSS identifier part, keyword, or quantity.
                + *
                + * @param {*} value The value to escape. May not be a string, but the value
                + *     will be coerced to a string.
                + * @return {string} A safe CSS identifier part, keyword, or quanitity.
                + */
                +soy.$$filterCssValue = function(value) {
                +  if (value && value.contentKind === goog.soy.data.SanitizedContentKind.CSS) {
                +    goog.asserts.assert(value.constructor ===
                +        soydata.SanitizedCss);
                +    return value.content;
                +  }
                +  // Uses == to intentionally match null and undefined for Java compatibility.
                +  if (value == null) {
                +    return '';
                +  }
                +  return soy.esc.$$filterCssValueHelper(value);
                +};
                +
                +
                +/**
                + * Sanity-checks noAutoescape input for explicitly tainted content.
                + *
                + * SanitizedContentKind.TEXT is used to explicitly mark input that was never
                + * meant to be used unescaped.
                + *
                + * @param {*} value The value to filter.
                + * @return {string} The value, that we dearly hope will not cause an attack.
                + */
                +soy.$$filterNoAutoescape = function(value) {
                +  if (value && value.contentKind === goog.soy.data.SanitizedContentKind.TEXT) {
                +    // Fail in development mode.
                +    goog.asserts.fail(
                +        'Tainted SanitizedContentKind.TEXT for |noAutoescape: `%s`',
                +        [value.content]);
                +    // Return innocuous data in production.
                +    return 'zSoyz';
                +  }
                +  return String(value);
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Basic directives/functions.
                +
                +
                +/**
                + * Converts \r\n, \r, and \n to <br>s
                + * @param {*} str The string in which to convert newlines.
                + * @return {string} A copy of {@code str} with converted newlines.
                + */
                +soy.$$changeNewlineToBr = function(str) {
                +  return goog.string.newLineToBr(String(str), false);
                +};
                +
                +
                +/**
                + * Inserts word breaks ('wbr' tags) into a HTML string at a given interval. The
                + * counter is reset if a space is encountered. Word breaks aren't inserted into
                + * HTML tags or entities. Entites count towards the character count; HTML tags
                + * do not.
                + *
                + * @param {*} str The HTML string to insert word breaks into. Can be other
                + *     types, but the value will be coerced to a string.
                + * @param {number} maxCharsBetweenWordBreaks Maximum number of non-space
                + *     characters to allow before adding a word break.
                + * @return {string} The string including word breaks.
                + */
                +soy.$$insertWordBreaks = function(str, maxCharsBetweenWordBreaks) {
                +  return goog.format.insertWordBreaks(String(str), maxCharsBetweenWordBreaks);
                +};
                +
                +
                +/**
                + * Truncates a string to a given max length (if it's currently longer),
                + * optionally adding ellipsis at the end.
                + *
                + * @param {*} str The string to truncate. Can be other types, but the value will
                + *     be coerced to a string.
                + * @param {number} maxLen The maximum length of the string after truncation
                + *     (including ellipsis, if applicable).
                + * @param {boolean} doAddEllipsis Whether to add ellipsis if the string needs
                + *     truncation.
                + * @return {string} The string after truncation.
                + */
                +soy.$$truncate = function(str, maxLen, doAddEllipsis) {
                +
                +  str = String(str);
                +  if (str.length <= maxLen) {
                +    return str;  // no need to truncate
                +  }
                +
                +  // If doAddEllipsis, either reduce maxLen to compensate, or else if maxLen is
                +  // too small, just turn off doAddEllipsis.
                +  if (doAddEllipsis) {
                +    if (maxLen > 3) {
                +      maxLen -= 3;
                +    } else {
                +      doAddEllipsis = false;
                +    }
                +  }
                +
                +  // Make sure truncating at maxLen doesn't cut up a unicode surrogate pair.
                +  if (soy.$$isHighSurrogate_(str.charAt(maxLen - 1)) &&
                +      soy.$$isLowSurrogate_(str.charAt(maxLen))) {
                +    maxLen -= 1;
                +  }
                +
                +  // Truncate.
                +  str = str.substring(0, maxLen);
                +
                +  // Add ellipsis.
                +  if (doAddEllipsis) {
                +    str += '...';
                +  }
                +
                +  return str;
                +};
                +
                +/**
                + * Private helper for $$truncate() to check whether a char is a high surrogate.
                + * @param {string} ch The char to check.
                + * @return {boolean} Whether the given char is a unicode high surrogate.
                + * @private
                + */
                +soy.$$isHighSurrogate_ = function(ch) {
                +  return 0xD800 <= ch && ch <= 0xDBFF;
                +};
                +
                +/**
                + * Private helper for $$truncate() to check whether a char is a low surrogate.
                + * @param {string} ch The char to check.
                + * @return {boolean} Whether the given char is a unicode low surrogate.
                + * @private
                + */
                +soy.$$isLowSurrogate_ = function(ch) {
                +  return 0xDC00 <= ch && ch <= 0xDFFF;
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Bidi directives/functions.
                +
                +
                +/**
                + * Cache of bidi formatter by context directionality, so we don't keep on
                + * creating new objects.
                + * @type {!Object.<!goog.i18n.BidiFormatter>}
                + * @private
                + */
                +soy.$$bidiFormatterCache_ = {};
                +
                +
                +/**
                + * Returns cached bidi formatter for bidiGlobalDir, or creates a new one.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @return {goog.i18n.BidiFormatter} A formatter for bidiGlobalDir.
                + * @private
                + */
                +soy.$$getBidiFormatterInstance_ = function(bidiGlobalDir) {
                +  return soy.$$bidiFormatterCache_[bidiGlobalDir] ||
                +         (soy.$$bidiFormatterCache_[bidiGlobalDir] =
                +             new goog.i18n.BidiFormatter(bidiGlobalDir));
                +};
                +
                +
                +/**
                + * Estimate the overall directionality of text. If opt_isHtml, makes sure to
                + * ignore the LTR nature of the mark-up and escapes in text, making the logic
                + * suitable for HTML and HTML-escaped text.
                + * @param {string} text The text whose directionality is to be estimated.
                + * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
                + *     Default: false.
                + * @return {number} 1 if text is LTR, -1 if it is RTL, and 0 if it is neutral.
                + */
                +soy.$$bidiTextDir = function(text, opt_isHtml) {
                +  if (!text) {
                +    return 0;
                +  }
                +  return goog.i18n.bidi.detectRtlDirectionality(text, opt_isHtml) ? -1 : 1;
                +};
                +
                +
                +/**
                + * Returns 'dir="ltr"' or 'dir="rtl"', depending on text's estimated
                + * directionality, if it is not the same as bidiGlobalDir.
                + * Otherwise, returns the empty string.
                + * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes
                + * in text, making the logic suitable for HTML and HTML-escaped text.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @param {string} text The text whose directionality is to be estimated.
                + * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
                + *     Default: false.
                + * @return {soydata.SanitizedHtmlAttribute} 'dir="rtl"' for RTL text in non-RTL
                + *     context; 'dir="ltr"' for LTR text in non-LTR context;
                + *     else, the empty string.
                + */
                +soy.$$bidiDirAttr = function(bidiGlobalDir, text, opt_isHtml) {
                +  return soydata.VERY_UNSAFE.ordainSanitizedHtmlAttribute(
                +      soy.$$getBidiFormatterInstance_(bidiGlobalDir).dirAttr(text, opt_isHtml));
                +};
                +
                +
                +/**
                + * Returns a Unicode BiDi mark matching bidiGlobalDir (LRM or RLM) if the
                + * directionality or the exit directionality of text are opposite to
                + * bidiGlobalDir. Otherwise returns the empty string.
                + * If opt_isHtml, makes sure to ignore the LTR nature of the mark-up and escapes
                + * in text, making the logic suitable for HTML and HTML-escaped text.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @param {string} text The text whose directionality is to be estimated.
                + * @param {boolean=} opt_isHtml Whether text is HTML/HTML-escaped.
                + *     Default: false.
                + * @return {string} A Unicode bidi mark matching bidiGlobalDir, or the empty
                + *     string when text's overall and exit directionalities both match
                + *     bidiGlobalDir, or bidiGlobalDir is 0 (unknown).
                + */
                +soy.$$bidiMarkAfter = function(bidiGlobalDir, text, opt_isHtml) {
                +  var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
                +  return formatter.markAfter(text, opt_isHtml);
                +};
                +
                +
                +/**
                + * Returns str wrapped in a <span dir="ltr|rtl"> according to its directionality
                + * - but only if that is neither neutral nor the same as the global context.
                + * Otherwise, returns str unchanged.
                + * Always treats str as HTML/HTML-escaped, i.e. ignores mark-up and escapes when
                + * estimating str's directionality.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @param {*} str The string to be wrapped. Can be other types, but the value
                + *     will be coerced to a string.
                + * @return {string} The wrapped string.
                + */
                +soy.$$bidiSpanWrap = function(bidiGlobalDir, str) {
                +  var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
                +  return formatter.spanWrap(str + '', true);
                +};
                +
                +
                +/**
                + * Returns str wrapped in Unicode BiDi formatting characters according to its
                + * directionality, i.e. either LRE or RLE at the beginning and PDF at the end -
                + * but only if str's directionality is neither neutral nor the same as the
                + * global context. Otherwise, returns str unchanged.
                + * Always treats str as HTML/HTML-escaped, i.e. ignores mark-up and escapes when
                + * estimating str's directionality.
                + * @param {number} bidiGlobalDir The global directionality context: 1 if ltr, -1
                + *     if rtl, 0 if unknown.
                + * @param {*} str The string to be wrapped. Can be other types, but the value
                + *     will be coerced to a string.
                + * @return {string} The wrapped string.
                + */
                +soy.$$bidiUnicodeWrap = function(bidiGlobalDir, str) {
                +  var formatter = soy.$$getBidiFormatterInstance_(bidiGlobalDir);
                +  return formatter.unicodeWrap(str + '', true);
                +};
                +
                +
                +// -----------------------------------------------------------------------------
                +// Generated code.
                +
                +
                +
                +
                +// START GENERATED CODE FOR ESCAPERS.
                +
                +/**
                + * @type {function (*) : string}
                + */
                +soy.esc.$$escapeUriHelper = function(v) {
                +  return encodeURIComponent(String(v));
                +};
                +
                +/**
                + * Maps charcters to the escaped versions for the named escape directives.
                + * @type {Object.<string, string>}
                + * @private
                + */
                +soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = {
                +  '\x00': '\x26#0;',
                +  '\x22': '\x26quot;',
                +  '\x26': '\x26amp;',
                +  '\x27': '\x26#39;',
                +  '\x3c': '\x26lt;',
                +  '\x3e': '\x26gt;',
                +  '\x09': '\x26#9;',
                +  '\x0a': '\x26#10;',
                +  '\x0b': '\x26#11;',
                +  '\x0c': '\x26#12;',
                +  '\x0d': '\x26#13;',
                +  ' ': '\x26#32;',
                +  '-': '\x26#45;',
                +  '\/': '\x26#47;',
                +  '\x3d': '\x26#61;',
                +  '`': '\x26#96;',
                +  '\x85': '\x26#133;',
                +  '\xa0': '\x26#160;',
                +  '\u2028': '\x26#8232;',
                +  '\u2029': '\x26#8233;'
                +};
                +
                +/**
                + * A function that can be used with String.replace..
                + * @param {string} ch A single character matched by a compatible matcher.
                + * @return {string} A token in the output language.
                + * @private
                + */
                +soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_ = function(ch) {
                +  return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_[ch];
                +};
                +
                +/**
                + * Maps charcters to the escaped versions for the named escape directives.
                + * @type {Object.<string, string>}
                + * @private
                + */
                +soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = {
                +  '\x00': '\\x00',
                +  '\x08': '\\x08',
                +  '\x09': '\\t',
                +  '\x0a': '\\n',
                +  '\x0b': '\\x0b',
                +  '\x0c': '\\f',
                +  '\x0d': '\\r',
                +  '\x22': '\\x22',
                +  '\x26': '\\x26',
                +  '\x27': '\\x27',
                +  '\/': '\\\/',
                +  '\x3c': '\\x3c',
                +  '\x3d': '\\x3d',
                +  '\x3e': '\\x3e',
                +  '\\': '\\\\',
                +  '\x85': '\\x85',
                +  '\u2028': '\\u2028',
                +  '\u2029': '\\u2029',
                +  '$': '\\x24',
                +  '(': '\\x28',
                +  ')': '\\x29',
                +  '*': '\\x2a',
                +  '+': '\\x2b',
                +  ',': '\\x2c',
                +  '-': '\\x2d',
                +  '.': '\\x2e',
                +  ':': '\\x3a',
                +  '?': '\\x3f',
                +  '[': '\\x5b',
                +  ']': '\\x5d',
                +  '^': '\\x5e',
                +  '{': '\\x7b',
                +  '|': '\\x7c',
                +  '}': '\\x7d'
                +};
                +
                +/**
                + * A function that can be used with String.replace..
                + * @param {string} ch A single character matched by a compatible matcher.
                + * @return {string} A token in the output language.
                + * @private
                + */
                +soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_ = function(ch) {
                +  return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_[ch];
                +};
                +
                +/**
                + * Maps charcters to the escaped versions for the named escape directives.
                + * @type {Object.<string, string>}
                + * @private
                + */
                +soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_ = {
                +  '\x00': '\\0 ',
                +  '\x08': '\\8 ',
                +  '\x09': '\\9 ',
                +  '\x0a': '\\a ',
                +  '\x0b': '\\b ',
                +  '\x0c': '\\c ',
                +  '\x0d': '\\d ',
                +  '\x22': '\\22 ',
                +  '\x26': '\\26 ',
                +  '\x27': '\\27 ',
                +  '(': '\\28 ',
                +  ')': '\\29 ',
                +  '*': '\\2a ',
                +  '\/': '\\2f ',
                +  ':': '\\3a ',
                +  ';': '\\3b ',
                +  '\x3c': '\\3c ',
                +  '\x3d': '\\3d ',
                +  '\x3e': '\\3e ',
                +  '@': '\\40 ',
                +  '\\': '\\5c ',
                +  '{': '\\7b ',
                +  '}': '\\7d ',
                +  '\x85': '\\85 ',
                +  '\xa0': '\\a0 ',
                +  '\u2028': '\\2028 ',
                +  '\u2029': '\\2029 '
                +};
                +
                +/**
                + * A function that can be used with String.replace..
                + * @param {string} ch A single character matched by a compatible matcher.
                + * @return {string} A token in the output language.
                + * @private
                + */
                +soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_ = function(ch) {
                +  return soy.esc.$$ESCAPE_MAP_FOR_ESCAPE_CSS_STRING_[ch];
                +};
                +
                +/**
                + * Maps charcters to the escaped versions for the named escape directives.
                + * @type {Object.<string, string>}
                + * @private
                + */
                +soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = {
                +  '\x00': '%00',
                +  '\x01': '%01',
                +  '\x02': '%02',
                +  '\x03': '%03',
                +  '\x04': '%04',
                +  '\x05': '%05',
                +  '\x06': '%06',
                +  '\x07': '%07',
                +  '\x08': '%08',
                +  '\x09': '%09',
                +  '\x0a': '%0A',
                +  '\x0b': '%0B',
                +  '\x0c': '%0C',
                +  '\x0d': '%0D',
                +  '\x0e': '%0E',
                +  '\x0f': '%0F',
                +  '\x10': '%10',
                +  '\x11': '%11',
                +  '\x12': '%12',
                +  '\x13': '%13',
                +  '\x14': '%14',
                +  '\x15': '%15',
                +  '\x16': '%16',
                +  '\x17': '%17',
                +  '\x18': '%18',
                +  '\x19': '%19',
                +  '\x1a': '%1A',
                +  '\x1b': '%1B',
                +  '\x1c': '%1C',
                +  '\x1d': '%1D',
                +  '\x1e': '%1E',
                +  '\x1f': '%1F',
                +  ' ': '%20',
                +  '\x22': '%22',
                +  '\x27': '%27',
                +  '(': '%28',
                +  ')': '%29',
                +  '\x3c': '%3C',
                +  '\x3e': '%3E',
                +  '\\': '%5C',
                +  '{': '%7B',
                +  '}': '%7D',
                +  '\x7f': '%7F',
                +  '\x85': '%C2%85',
                +  '\xa0': '%C2%A0',
                +  '\u2028': '%E2%80%A8',
                +  '\u2029': '%E2%80%A9',
                +  '\uff01': '%EF%BC%81',
                +  '\uff03': '%EF%BC%83',
                +  '\uff04': '%EF%BC%84',
                +  '\uff06': '%EF%BC%86',
                +  '\uff07': '%EF%BC%87',
                +  '\uff08': '%EF%BC%88',
                +  '\uff09': '%EF%BC%89',
                +  '\uff0a': '%EF%BC%8A',
                +  '\uff0b': '%EF%BC%8B',
                +  '\uff0c': '%EF%BC%8C',
                +  '\uff0f': '%EF%BC%8F',
                +  '\uff1a': '%EF%BC%9A',
                +  '\uff1b': '%EF%BC%9B',
                +  '\uff1d': '%EF%BC%9D',
                +  '\uff1f': '%EF%BC%9F',
                +  '\uff20': '%EF%BC%A0',
                +  '\uff3b': '%EF%BC%BB',
                +  '\uff3d': '%EF%BC%BD'
                +};
                +
                +/**
                + * A function that can be used with String.replace..
                + * @param {string} ch A single character matched by a compatible matcher.
                + * @return {string} A token in the output language.
                + * @private
                + */
                +soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = function(ch) {
                +  return soy.esc.$$ESCAPE_MAP_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_[ch];
                +};
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_ESCAPE_HTML_ = /[\x00\x22\x26\x27\x3c\x3e]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_ = /[\x00\x22\x27\x3c\x3e]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x26\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_ = /[\x00\x09-\x0d \x22\x27\x2d\/\x3c-\x3e`\x85\xa0\u2028\u2029]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_ = /[\x00\x08-\x0d\x22\x26\x27\/\x3c-\x3e\\\x85\u2028\u2029]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_ = /[\x00\x08-\x0d\x22\x24\x26-\/\x3a\x3c-\x3f\x5b-\x5e\x7b-\x7d\x85\u2028\u2029]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_ = /[\x00\x08-\x0d\x22\x26-\x2a\/\x3a-\x3e@\\\x7b\x7d\x85\xa0\u2028\u2029]/g;
                +
                +/**
                + * Matches characters that need to be escaped for the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_ = /[\x00- \x22\x27-\x29\x3c\x3e\\\x7b\x7d\x7f\x85\xa0\u2028\u2029\uff01\uff03\uff04\uff06-\uff0c\uff0f\uff1a\uff1b\uff1d\uff1f\uff20\uff3b\uff3d]/g;
                +
                +/**
                + * A pattern that vets values produced by the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_ = /^(?!-*(?:expression|(?:moz-)?binding))(?:[.#]?-?(?:[_a-z0-9-]+)(?:-[_a-z0-9-]+)*-?|-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[a-z]{1,2}|%)?|!important|)$/i;
                +
                +/**
                + * A pattern that vets values produced by the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_ = /^(?:(?:https?|mailto):|[^&:\/?#]*(?:[\/?#]|$))/i;
                +
                +/**
                + * A pattern that vets values produced by the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTES_ = /^(?!style|on|action|archive|background|cite|classid|codebase|data|dsync|href|longdesc|src|usemap)(?:[a-z0-9_$:-]*)$/i;
                +
                +/**
                + * A pattern that vets values produced by the named directives.
                + * @type RegExp
                + * @private
                + */
                +soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_ = /^(?!script|style|title|textarea|xmp|no)[a-z0-9_$:-]*$/i;
                +
                +/**
                + * A helper for the Soy directive |escapeHtml
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$escapeHtmlHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_ESCAPE_HTML_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
                +};
                +
                +/**
                + * A helper for the Soy directive |normalizeHtml
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$normalizeHtmlHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
                +};
                +
                +/**
                + * A helper for the Soy directive |escapeHtmlNospace
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$escapeHtmlNospaceHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_ESCAPE_HTML_NOSPACE_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
                +};
                +
                +/**
                + * A helper for the Soy directive |normalizeHtmlNospace
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$normalizeHtmlNospaceHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_NORMALIZE_HTML_NOSPACE_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_HTML__AND__NORMALIZE_HTML__AND__ESCAPE_HTML_NOSPACE__AND__NORMALIZE_HTML_NOSPACE_);
                +};
                +
                +/**
                + * A helper for the Soy directive |escapeJsString
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$escapeJsStringHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_ESCAPE_JS_STRING_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_);
                +};
                +
                +/**
                + * A helper for the Soy directive |escapeJsRegex
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$escapeJsRegexHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_ESCAPE_JS_REGEX_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_JS_STRING__AND__ESCAPE_JS_REGEX_);
                +};
                +
                +/**
                + * A helper for the Soy directive |escapeCssString
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$escapeCssStringHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_ESCAPE_CSS_STRING_,
                +      soy.esc.$$REPLACER_FOR_ESCAPE_CSS_STRING_);
                +};
                +
                +/**
                + * A helper for the Soy directive |filterCssValue
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$filterCssValueHelper = function(value) {
                +  var str = String(value);
                +  if (!soy.esc.$$FILTER_FOR_FILTER_CSS_VALUE_.test(str)) {
                +    return 'zSoyz';
                +  }
                +  return str;
                +};
                +
                +/**
                + * A helper for the Soy directive |normalizeUri
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$normalizeUriHelper = function(value) {
                +  var str = String(value);
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_,
                +      soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_);
                +};
                +
                +/**
                + * A helper for the Soy directive |filterNormalizeUri
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$filterNormalizeUriHelper = function(value) {
                +  var str = String(value);
                +  if (!soy.esc.$$FILTER_FOR_FILTER_NORMALIZE_URI_.test(str)) {
                +    return '#zSoyz';
                +  }
                +  return str.replace(
                +      soy.esc.$$MATCHER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_,
                +      soy.esc.$$REPLACER_FOR_NORMALIZE_URI__AND__FILTER_NORMALIZE_URI_);
                +};
                +
                +/**
                + * A helper for the Soy directive |filterHtmlAttributes
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$filterHtmlAttributesHelper = function(value) {
                +  var str = String(value);
                +  if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ATTRIBUTES_.test(str)) {
                +    return 'zSoyz';
                +  }
                +  return str;
                +};
                +
                +/**
                + * A helper for the Soy directive |filterHtmlElementName
                + * @param {*} value Can be of any type but will be coerced to a string.
                + * @return {string} The escaped text.
                + */
                +soy.esc.$$filterHtmlElementNameHelper = function(value) {
                +  var str = String(value);
                +  if (!soy.esc.$$FILTER_FOR_FILTER_HTML_ELEMENT_NAME_.test(str)) {
                +    return 'zSoyz';
                +  }
                +  return str;
                +};
                +
                +/**
                + * Matches all tags, HTML comments, and DOCTYPEs in tag soup HTML.
                + * By removing these, and replacing any '<' or '>' characters with
                + * entities we guarantee that the result can be embedded into a
                + * an attribute without introducing a tag boundary.
                + *
                + * @type {RegExp}
                + * @private
                + */
                +soy.esc.$$HTML_TAG_REGEX_ = /<(?:!|\/?([a-zA-Z][a-zA-Z0-9:\-]*))(?:[^>'"]|"[^"]*"|'[^']*')*>/g;
                +
                +/**
                + * Matches all occurrences of '<'.
                + *
                + * @type {RegExp}
                + * @private
                + */
                +soy.esc.$$LT_REGEX_ = /</g;
                +
                +/**
                + * Maps lower-case names of innocuous tags to 1.
                + *
                + * @type {Object.<string,number>}
                + * @private
                + */
                +soy.esc.$$SAFE_TAG_WHITELIST_ = {'b': 1, 'br': 1, 'em': 1, 'i': 1, 's': 1, 'sub': 1, 'sup': 1, 'u': 1};
                +
                +// END GENERATED CODE
                diff --git a/blockly/webif/static/blockly/demos/plane/style.css b/blockly/webif/static/blockly/demos/plane/style.css
                new file mode 100644
                index 000000000..16e2c6f41
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/style.css
                @@ -0,0 +1,97 @@
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  margin-top: 0;
                +}
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +.farSide {
                +  text-align: right;
                +}
                +html[dir="RTL"] .farSide {
                +  text-align: left;
                +}
                +.tab {
                +  padding: 6px 12px;
                +  text-decoration: none;
                +  color: #000;
                +}
                +#selected {
                +  font-weight: bold;
                +  background-color: #ddd;
                +  border-radius: 20px;
                +}
                +
                +/* Pulse the language menu once to draw attention to it. */
                +#languageBorder {
                +  border-radius: 4px;
                +  animation: pulse 2s ease-in-out forwards;
                +  animation-delay: 2s;
                +}
                +@keyframes pulse {
                +    0% { background-color: #fff }
                +    50% { background-color: #f00 }
                +    100% { background-color: #fff }
                +}
                +
                +#blockly {
                +  height: 300px;
                +  width: 100%;
                +  border-style: solid;
                +  border-color: #ddd;
                +  border-width: 0 1px 1px 0;
                +}
                +
                +/* SVG Plane. */
                +#plane {
                +  overflow: hidden;
                +}
                +#fuselage {
                +  fill: #fff;
                +  stroke: #000;
                +}
                +#wing, #tail {
                +  fill: #ddd;
                +  stroke: #444;
                +}
                +.crew {
                +  fill: #f44;
                +  stroke: #000;
                +}
                +.seat1st {
                +  fill: #88f;
                +  stroke: #000;
                +}
                +.seat2nd {
                +  fill: #8b8;
                +  stroke: #000;
                +}
                +#seatYes, #seatNo {
                +  font-size: 40pt;
                +}
                +text {
                +  font-family: sans-serif;
                +  font-size: 20pt;
                +  fill: #444;
                +}
                +html[dir="RTL"] #plane text {
                +  text-anchor: end;
                +}
                +
                +/* Slider. */
                +.sliderTrack {
                +  stroke: #aaa;
                +  stroke-width: 6px;
                +  stroke-linecap: round;
                +}
                +.sliderKnob {
                +  fill: #ddd;
                +  stroke: #bbc;
                +  stroke-width: 1px;
                +  stroke-linejoin: round;
                +}
                +.sliderKnob:hover {
                +  fill: #eee;
                +}
                diff --git a/blockly/webif/static/blockly/demos/plane/template.soy b/blockly/webif/static/blockly/demos/plane/template.soy
                new file mode 100644
                index 000000000..5b19e99be
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/template.soy
                @@ -0,0 +1,225 @@
                +{namespace planepage}
                +
                +/**
                + * This is a Closure Template.
                + *
                + * See the README.txt for details.
                + */
                +
                +/**
                + * Translated messages for use in JavaScript.
                + */
                +{template .messages}
                +  <div style="display: none">
                +    <span id="Plane_rows">{msg meaning="Plane.rows" desc="page text - Total number of rows of seats on an airplane.\n\nParameters:\n* %1 - number of rows of seats on an airplane.  It is always an integer greater than or equal to zero."}Rows: %1{/msg}</span>
                +    <span id="Plane_getRows">{msg meaning="Plane.getRows" desc="block text - The number of rows on the airplane, to be used in a mathematical equation, such as: 'seats = 4 x '''rows (5)''''.\n\nParameters:\n* %1 - number of rows of seats on an airplane.  It is always an integer greater than or equal to zero."}rows (%1){/msg}</span>
                +    <span id="Plane_rows1">{msg meaning="Plane.rows1" desc="page text - The number of rows of first-class seats on the airplane.  You can see the block at [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=3].\n\nParameters:\n* %1 - number of rows of first-class seats on an airplane.  It is always an integer greater than or equal to zero."}1st class rows: %1{/msg}</span>
                +    <span id="Plane_getRows1">{msg meaning="Plane.getRows1" desc="block text - The number of rows of first-class seats on the, to be used in a mathematical equation.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=3].\n\nParameters:\n* %1 - number of rows of first-class seats on an airplane.  It is always an integer greater than or equal to zero."}1st class rows (%1){/msg}</span>
                +    <span id="Plane_rows2">{msg meaning="Plane.rows2" desc="page text - The number of rows of second-class seats on the airplane.  %1 is an integer greater or equal to zero.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=3].\n\nParameters:\n* %1 - number of rows of second-class seats on an airplane.  It is always an integer greater than or equal to zero."}2nd class rows: %1{/msg}</span>
                +    <span id="Plane_getRows2">{msg meaning="Plane.getRows2" desc="block text - The number of rows of second-class (also called 'economy class') seats on the airplane, to be used in a mathematical expression.\n\nParameters:\n* %1 - number of rows of second-class seats on an airplane.  It is always an integer greater than or equal to zero."}2nd class rows (%1){/msg}</span>
                +    <span id="Plane_seats">{msg meaning="Plane.seats" desc="page text - The total number of seats on the airplane.\n\nParameters:\n* %1 - number of seats on an airplane.  It is always either the next message or an integer greater than or equal to zero."}Seats: %1{/msg}</span>
                +    <span id="Plane_placeholder">{msg meaning="Plane.placeholder" desc="page text - A word or symbol indicating that this numeric value has not yet been determined."}?{/msg}</span>
                +    <span id="Plane_setSeats">{msg meaning="Plane.setSeats" desc="block text - The first half of a mathematical equation determining the number of seats in an airplane, such as: ''''seats =''' 4 x rows'."}seats ={/msg}</span>
                +  </div>
                +{/template}
                +
                +/**
                + * Web page structure.
                + */
                +{template .start}
                +  {call .messages /}
                +  <table width="100%">
                +    <tr>
                +      <td>
                +        <h1><a href="https://developers.google.com/blockly/">Blockly</a>&rlm; &gt;{sp}
                +          <a href="../index.html">Demos</a>&rlm; &gt;{sp}
                +          <span id="title">
                +            {msg meaning="Plane.plane" desc="title - Specifies that this is Blockly's '''Plane''' (airplane) tutorial.  The word 'plane' was chosen over 'airplane' in English because it is shorter and less formal."}
                +              Plane Seat Calculator
                +            {/msg}
                +          </span>
                +          {sp}&nbsp;{sp}
                +          {for $i in range(1, $ij.maxLevel + 1)}
                +            {sp}
                +            {if $i == $ij.level}
                +              <span class="tab" id="selected">{$i}</span>
                +            {else}
                +              {if $i < $ij.level}
                +                <a class="tab previous" href="?lang={$ij.lang}&level={$i}">{$i}</a>
                +              {else}
                +                <a class="tab" href="?lang={$ij.lang}&level={$i}">{$i}</a>
                +              {/if}
                +            {/if}
                +          {/for}
                +        </h1>
                +      </td>
                +      <td class="farSide">
                +        <span {if $ij.lang == 'en'}id="languageBorder"{/if} style="padding: 10px">
                +          <select id="languageMenu"></select>
                +        </span>
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <script src="slider.js"></script>
                +  <svg
                +     id="plane"
                +     xmlns="http://www.w3.org/2000/svg"
                +     xmlns:svg="http://www.w3.org/2000/svg"
                +     xmlns:xlink="http://www.w3.org/1999/xlink"
                +     version="1.1"
                +     width="600"
                +     height="320"
                +     viewBox="0 110 600 320">
                +    <defs>
                +      <g id="row1st">
                +        <rect
                +           class="seat1st"
                +           width="10" height="10"
                +           x="75" y="243" />
                +        <rect
                +           class="seat1st"
                +           width="10" height="10"
                +           x="75" y="254" />
                +        <rect
                +           class="seat1st"
                +           width="10" height="10"
                +           x="75" y="272" />
                +        <rect
                +           class="seat1st"
                +           width="10" height="10"
                +           x="75" y="283" />
                +      </g>
                +      <g id="row2nd">
                +        <rect
                +           class="seat2nd"
                +           width="10" height="8"
                +           x="75" y="243" />
                +        <rect
                +           class="seat2nd"
                +           width="10" height="8"
                +           x="75" y="251" />
                +        <rect
                +           class="seat2nd"
                +           width="10" height="8"
                +           x="75" y="269" />
                +        <rect
                +           class="seat2nd"
                +           width="10" height="8"
                +           x="75" y="277" />
                +        <rect
                +           class="seat2nd"
                +           width="10" height="8"
                +           x="75" y="285" />
                +      </g>
                +      <linearGradient id="grad1" x1="0%" y1="100%" x2="0%" y2="0%">
                +        <stop offset="0%" style="stop-color:#fff;stop-opacity:0" />
                +        <stop offset="100%" style="stop-color:#fff;stop-opacity:1" />
                +      </linearGradient>
                +      <linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
                +        <stop offset="0%" style="stop-color:#fff;stop-opacity:0" />
                +        <stop offset="100%" style="stop-color:#fff;stop-opacity:1" />
                +      </linearGradient>
                +    </defs>
                +    <path
                +        d="m 214,270 l 159,-254 31,-16 -74,189 0,162 74,189 -31,16 z"
                +        id="wing" />
                +    <path
                +        d="m 577,270 22,-93 -27,6 -44,88 44,88 27,6 z"
                +        id="tail" />
                +    <path
                +        d="m 577,270 l -94,24 h -407 c -38,0 -75,-13 -75,-26 c 0,-13 38,-26 75,-26 h 407 z"
                +        id="fuselage" />
                +    <rect
                +       width="610"
                +       height="100"
                +       x="-5"
                +       y="110"
                +       fill="url(#grad1)" />
                +    <rect
                +       width="610"
                +       height="100"
                +       x="-5"
                +       y="330"
                +       fill="url(#grad2)" />
                +    <text id="row1stText" x="55" y="380"></text>
                +    <text id="row2ndText" x="55" y="420"></text>
                +    <text x="55" y="210">
                +      <tspan id="seatText"></tspan>
                +      <tspan id="seatYes" style="fill: #0c0;" dy="10">&#x2713;</tspan>
                +      <tspan id="seatNo" style="fill: #f00;" dy="10">&#x2717;</tspan>
                +    </text>
                +    {if $ij.level > 1}
                +      <rect
                +          id="crew_right" class="crew"
                +          width="10" height="10"
                +          x="35" y="254" />
                +      <rect
                +          id="crew_left" class="crew"
                +          width="10" height="10"
                +          x="35" y="272" />
                +    {/if}
                +  </svg>
                +
                +  <p>
                +    {switch $ij.level}
                +      {case 1}
                +        {msg meaning="Plane.description1" desc="instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=1 this level], there is only one type of seat on the plane."}An airplane has a number of rows of passenger seats.  Each row contains four seats.{/msg}
                +      {case 2}
                +        {msg meaning="Plane.description2" desc="instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=2 this level], there are two types of seats on this plane."}An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.{/msg}
                +      {case 3}
                +        {msg meaning="Plane.description3" desc="instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=3 this level], there are three types of seats on this plane.  Be sure to use the same terms for '1st class' and '2nd class' as you did for the earlier messages."}An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.{/msg}
                +    {/switch}
                +  </p>
                +  <p>
                +    {msg meaning="Plane.instructions" desc="page text - This text appears below the airplane graphic and above the space for the user to create the formula.  The number of rows an the graphic may be changed by the user with a slider.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&level=1] for a picture."}Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).{/msg}
                +  </p>
                +
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../javascript_compressed.js"></script>
                +  <script src="../../msg/js/{$ij.lang}.js"></script>
                +  <script src="blocks.js"></script>
                +  {call .toolbox /}
                +  <div id="blockly"></div>
                +{/template}
                +
                +/**
                + * Toolboxes for each level.
                + */
                +{template .toolbox}
                +  <xml id="toolbox" style="display: none">
                +    <block type="math_number"></block>
                +    <block type="math_arithmetic">
                +      <value name="A">
                +        <shadow type="math_number">
                +          <field name="NUM">1</field>
                +        </shadow>
                +      </value>
                +      <value name="B">
                +        <shadow type="math_number">
                +          <field name="NUM">1</field>
                +        </shadow>
                +      </value>
                +    </block>
                +    <block type="math_arithmetic">
                +      <field name="OP">MULTIPLY</field>
                +      <value name="A">
                +        <shadow type="math_number">
                +          <field name="NUM">1</field>
                +        </shadow>
                +      </value>
                +      <value name="B">
                +        <shadow type="math_number">
                +          <field name="NUM">1</field>
                +        </shadow>
                +      </value>
                +    </block>
                +    {if $ij.level <= 2}
                +      <block type="plane_get_rows"></block>
                +    {else}
                +      <block type="plane_get_rows1st"></block>
                +      <block type="plane_get_rows2nd"></block>
                +    {/if}
                +  </xml>
                +{/template}
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/extracted_msgs.xlf b/blockly/webif/static/blockly/demos/plane/xlf/extracted_msgs.xlf
                new file mode 100644
                index 000000000..6a4fd44ff
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/extracted_msgs.xlf
                @@ -0,0 +1,77 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" xml:space="preserve" source-language="en">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <note priority="1" from="description">page text - Total number of rows of seats on an airplane.\n\nParameters:\n* %1 - number of rows of seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.rows</note>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <note priority="1" from="description">block text - The first half of a mathematical equation determining the number of seats in an airplane, such as: ''''seats =''' 4 x rows'.</note>
                +        <note priority="1" from="meaning">Plane.setSeats</note>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <note priority="1" from="description">instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=3 this level], there are three types of seats on this plane.  Be sure to use the same terms for '1st class' and '2nd class' as you did for the earlier messages.</note>
                +        <note priority="1" from="meaning">Plane.description3</note>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <note priority="1" from="description">page text - A word or symbol indicating that this numeric value has not yet been determined.</note>
                +        <note priority="1" from="meaning">Plane.placeholder</note>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <note priority="1" from="description">page text - This text appears below the airplane graphic and above the space for the user to create the formula.  The number of rows an the graphic may be changed by the user with a slider.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=1] for a picture.</note>
                +        <note priority="1" from="meaning">Plane.instructions</note>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <note priority="1" from="description">instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=2 this level], there are two types of seats on this plane.</note>
                +        <note priority="1" from="meaning">Plane.description2</note>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <note priority="1" from="description">block text - The number of rows of first-class seats on the, to be used in a mathematical equation.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=3].\n\nParameters:\n* %1 - number of rows of first-class seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.getRows1</note>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <note priority="1" from="description">page text - The number of rows of second-class seats on the airplane.  %1 is an integer greater or equal to zero.  See [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=3].\n\nParameters:\n* %1 - number of rows of second-class seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.rows2</note>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <note priority="1" from="description">page text - The total number of seats on the airplane.\n\nParameters:\n* %1 - number of seats on an airplane.  It is always either the next message or an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.seats</note>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <note priority="1" from="description">title - Specifies that this is Blockly's '''Plane''' (airplane) tutorial.  The word 'plane' was chosen over 'airplane' in English because it is shorter and less formal.</note>
                +        <note priority="1" from="meaning">Plane.plane</note>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <note priority="1" from="description">block text - The number of rows on the airplane, to be used in a mathematical equation, such as: 'seats = 4 x '''rows (5)''''.\n\nParameters:\n* %1 - number of rows of seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.getRows</note>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <note priority="1" from="description">page text - The number of rows of first-class seats on the airplane.  You can see the block at [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=3].\n\nParameters:\n* %1 - number of rows of first-class seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.rows1</note>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <note priority="1" from="description">instructions - Note that in [http://blockly-share.appspot.com/static/apps/plane/plane.html?lang=en&amp;level=1 this level], there is only one type of seat on the plane.</note>
                +        <note priority="1" from="meaning">Plane.description1</note>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <note priority="1" from="description">block text - The number of rows of second-class (also called 'economy class') seats on the airplane, to be used in a mathematical expression.\n\nParameters:\n* %1 - number of rows of second-class seats on an airplane.  It is always an integer greater than or equal to zero.</note>
                +        <note priority="1" from="meaning">Plane.getRows2</note>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ar.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ar.xlf
                new file mode 100644
                index 000000000..c9b8e1689
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ar.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ar">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>الصفوف: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>المقاعد =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>طائرة بمقعدين في مقطورة الطيّار (للطيار ومساعده) وعدد من المقاعد في صفوف الدرجة الأولى والثانية. كل صف من صفوف الدرجة الأولى يحتوي على أربعة مقاعد. ويحتوي كل صف في الدرجة الثانية على خمسة مقاعد.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>؟</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>لبناء صيغة (أدناه) تقوم بحساب إجمالي عدد المقاعد في الطائرة عند تغيير الصفوف (أعلاه).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>طائرة بمقعدين في مقطورة الطيّار (للطيار ومساعده) وعدد من الصفوف يحتوي كل صف على أربعة مقاعد.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>صفوف الطبقة الأولى (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>صفوف الفئة الثانية: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>المقاعد: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>آلة حاسبة لمقعد الطائرة</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>الصفوف (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>صفوف الطبقة الأولى: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>هنالك طائرة تحتوي على عدد من صفوف مقاعد الركاب. كل صف يحتوي على أربعة مقاعد.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>صفوف الفئة الثانية: (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_be-tarask.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_be-tarask.xlf
                new file mode 100644
                index 000000000..4580b5f1d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_be-tarask.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="be-tarask">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Радкоў: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>месцаў =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Самалёт мае два месцы ў кабіне экіпажа (пілот і другі пілот), і некалькі пасажырскіх шэрагаў месцаў 1-га кляса і 2-га кляса. Кожны шэраг 1-га кляса утрымлівае чатыры месцы. Кожны шэраг 2-га кляса ўтрымлівае пяць месцаў.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Пабудаваць формулу (ніжэй), якая падлічвае агульную колькасьць месцаў у самалёце пры зьмене радоў (гл. вышэй).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Самалёт мае два месцы ў кабіне экіпажа (пілот і другі пілот), і некалькі шэрагаў пасажырскіх сядзеньняў. Кожны шэраг утрымлівае чатыры месцы.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>радкі першага клясу (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Радкі другога клясу: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Месцаў: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Калькулятар месцаў у самалёце</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>радкоў (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Радкі першага клясу: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Самалёт мае некалькі шэрагаў пасажырскіх сядзеньняў. Кожная шэраг утрымлівае чатыры месцы.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>радкі другога клясу (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_br.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_br.xlf
                new file mode 100644
                index 000000000..4a7fc0c26
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_br.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="br">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Renkennadoù : %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>azezennoù =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>En un nijerez ez eus div azezenn el logell leviañ(evit al loman hag an eil loman), hag un toullad renkennadoù azezennoù tremenidi kentañ hag eil klas. Peder azezenn zo e pep renkennad kentañ klas. Pemp azezenn zo e pemp renkennad eil klas.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Sevel ur formulenn (amañ dindan) evit jediñ an niver a azezennoù en holl en nijerez pa vez kemmet an niver a renkennadoù (amañ a-us).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>En un nijerez ez eus div azezenn el logell leviañ(evit al loman hag an eil loman), hag ur toullad renkennadoù azezennoù evit an dremenidi. Peder azezenn zo e pep renkennad.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Renkennadoù kentañ klas (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Renkennadoù eil klas : %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Azezennoù : %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Jederez azezenn nijerez</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>renkennadoù (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Renkennadoù kentañ klas : %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un nijerez he deus un toullad renkennadoù azezennoù evit ar veajourien. Peder azezenn a zo e pep renkennad.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Renkennadoù eil klas (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ca.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ca.xlf
                new file mode 100644
                index 000000000..17dfe65e0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ca.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ca">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Files: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>seients =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un avió té dos seients en la cabina de vol (pel pilot i copilot) i un nombre de files per seients de passatgers de primera classe i de segona classe. Cada fila de primera classe conté quatre seients. Cada fila de segona classe conté cinc seients.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Construïu una fórmula (a sota) que calculi el nombre total de seients de l'avió a mida que canviïn les files (a dalt).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avió té dos seients en la cabina de vol (pel pilot i pel copilot) i un nombre de files de seients de passatgers. Cada fila conté quatre seients.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>files de primera classe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>files de segona classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Seients: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculadora de seients d'avió</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>files (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>files de primera classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avió té un nombre de files de seients de passatgers.  Cada fila conté quatre seients.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>files de segona classe (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_da.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_da.xlf
                new file mode 100644
                index 000000000..752fe24f5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_da.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="da">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rækker: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sæder =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Et fly har to pladser i cockpittet (til pilot og med-pilot), og et antal rækker af 1. klasses og 2. klasses passagersæder. Hver 1. klasses række indeholder fire sæder. Hver 2. klasses række indeholder fem sæder.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Opbyg en formel (nedenfor), der beregner det samlede antal pladser på flyet, hvis antal rækker ændres (ovenfor).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Et fly har to pladser i cockpittet (til pilot og med-pilot), og et antal rækker af passagersæder. Hver række indeholder fire sæder.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>1. klasse rækker (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>2. klasse rækker: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sæder: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Flysædelommeregner</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rækker (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>1. klasse rækker: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Et fly har et antal rækker af passagersæder. Hver række indeholder fire sæder.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>2. klasse rækker (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_de.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_de.xlf
                new file mode 100644
                index 000000000..f06bc7725
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_de.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="de">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Reihen: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>Sitze =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Ein Flugzeug hat zwei Sitze im Pilotenstand (für den Piloten und Co-Piloten) und eine Anzahl an Reihen mit Passagiersitzen der 1. und 2. Klasse. Jede 1.-Klasse-Reihe enthält vier Sitze. Jede 2.-Klasse-Reihe enthält fünf Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Erstelle eine Formel (unten), die die gesamte Anzahl an Sitzen im Flugzeug berechnet, wenn die Reihen (oben) geändert werden.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ein Flugzeug hat zwei Sitze im Pilotenstand (für den Piloten und Co-Piloten) und eine Anzahl an Reihen mit Passagiersitzen. Jede Reihe enthält vier Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Reihen der 1. Klasse (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Reihen der 2. Klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sitze: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Flugzeugsitzrechner</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>Reihen (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Reihen der 1. Klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ein Flugzeug hat eine Anzahl an Reihen mit Passagiersitzen. Jede Reihe enthält vier Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Reihen der 2. Klasse (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_el.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_el.xlf
                new file mode 100644
                index 000000000..5acb291d2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_el.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="el">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Σειρές: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>καθίσματα =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Ένα αεροπλάνο έχει δύο καθίσματα στον θάλαμο διακυβέρνησης (για τον κυβερνήτη και τον συγκυβερνήτη), καθώς και έναν αριθμό σειρών καθισμάτων για την 1η και 2η θέση. Κάθε σειρά της 1ης θέσης έχει τέσσερα καθίσματα και κάθε σειρά της 2ης θέσης έχει πέντε καθίσματα.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>;</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Φτιάξε έναν τύπο (κάτω) που θα υπολογίζει τον συνολικό αριθμό καθισμάτων του αεροπλάνου καθώς αλλάζουν οι σειρές (πάνω).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ένα αεροπλάνο έχει δύο καθίσματα στον θάλαμο διακυβέρνησης (για τον κυβερνήτη και τον συγκυβερνήτη), καθώς και έναν αριθμό από σειρές καθισμάτων επιβατών.  Κάθε σειρά έχει τέσσερα καθίσματα.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Σειρές 1ης θέσης (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Σειρές 2ης θέσης: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Καθίσματα: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Υπολογισμός Θέσεων Σε Αεροπλάνο</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>σειρές (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Σειρές 1ης θέσης: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ένα αεροπλάνο έχει έναν συγκεκριμένο αριθμό σειρών καθισμάτων επιβατών. Κάθε σειρά έχει τέσσερα καθίσματα.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Σειρές 2ης θέσης (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_en.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_en.xlf
                new file mode 100644
                index 000000000..e471a0008
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_en.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="en">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rows: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>seats =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>1st class rows (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>2nd class rows: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Seats: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Plane Seat Calculator</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rows (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>1st class rows: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>An airplane has a number of rows of passenger seats.  Each row contains four seats.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>2nd class rows (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_es.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_es.xlf
                new file mode 100644
                index 000000000..e2022b5f1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_es.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="es">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Filas: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>asientos =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un avión tiene dos asientos en la cabina de vuelo (para el piloto y co-piloto), y un número de filas de asientos para pasajeros de primera y segunda clase. Cada fila de la primera clase contiene cuatro asientos. Cada fila de la segunda clase contiene cinco asientos.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Construir una fórmula (abajo) que calcule el número total de asientos en el avión cuando las filas sean cambiadas (arriba).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avión tiene dos asientos en la cabina de vuelo (para el piloto y co-piloto), y un número de filas de asientos de pasajeros. Cada fila contiene cuatro asientos.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Filas de primera clase: (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Filas de segunda clase: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Asientos: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculadora de asientos de avión</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>filas (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Filas de primera clase: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avión  tiene un número de filas de asientos de pasajeros. Cada fila contiene cuatro asientos.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Filas de segunda clase: (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_et.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_et.xlf
                new file mode 100644
                index 000000000..d88be0a9f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_et.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="en">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Ridu: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>istmete arv =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Lennuki kokpitis on kaks istet (üks kummalegi piloodile), mingi arv ridu 1. klassi reisijatele ja mingi arv ridu 2. klassi reisijatele. Igas 1. klassi reas on neli istet, igas 2. klassi reas viis istet.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Ehita plokkidest valem, mis arvutab istmete arvu lennukis õigesti sõltumata ridade arvust (seda saad muuta lennuki juures oleva liuguriga).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Lennuki kokpitis on kaks istet (üks kummalegi piloodile) ja mingi arv istemridu reisijatele. Igas reas on neli istet.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>1. klassi ridu (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>2. klassi ridu: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Istmeid: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Lennukiistmete kalkulaator</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rows (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>1. klassi ridu: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Lennukis on reisijate istmed mitmes reas. Igas reas on neli istet.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>2. klassi ridu (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fa.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fa.xlf
                new file mode 100644
                index 000000000..264ec3104
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fa.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="fa">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>ردیف: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>صندلی‌ها =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>یک هواپیما دو صندلی در کابین خلبان دارد (برای خلبان و کمک خلبان) و تهداد از صندلی‌ها مسافرین درجه یک و درجه دو.  هر ردیف درجه یک شامل چهار صندلی است. هر ردیف درجه دو شامل پنج صندلی است.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>؟</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>یک فرمول بسازید (پایین) که تعداد کل صندلی‌های هواپیما با تغییر ردیف را حساب کند (بالا).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>یک هواپیما دو صندلی در عرشهٔ پرواز دارد (برای خلبان و کمک خلبان) و تعدادی صندلی مسافرین.  هر ردیف شامل چهار صندلی است.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>اولین کلاس ردیف‌ها (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>دومین کلاس ردیف: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>صندلی‌ها: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>محاسبه‌گر صندلی‌های هواپیما</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>ردیف‌ها (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>اولین ردیف کلاس: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>یک هواپیما تعداد از صندلی‌های مسافرین را دارد. هر ردیف شمال چهار صندلی است.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>دومین کلاس ردیف‌ها (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fr.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fr.xlf
                new file mode 100644
                index 000000000..9485da29b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_fr.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="fr">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rangées : %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sièges =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un avion a deux sièges dans la cabine de pilotage (pour le pilote et le copilote), et un certain nombre de rangées de sièges passager de première et seconde classes. Chaque rangée de première classe contient quatre sièges. Chaque rangée de seconde classe contient cinq sièges.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Construire une formule (ci-dessous) qui calcule le nombre total de sièges dans l’avion quand le nombre de rangées est modifié (ci-dessus).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion a deux sièges dans le poste de pilotage (pour le pilote et le copilote), et un certain nombre de rangées de sièges passager. Chaque rangée contient quatre sièges.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>rangées de première classe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>rangées de seconde classe : %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sièges : %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculateur de sièges d’avion</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rangées (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>rangées de première classe : %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion a un nombre de rangées de sièges passager. Chaque rangée contient quatre sièges.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>rangées de seconde classe (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_he.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_he.xlf
                new file mode 100644
                index 000000000..55ac148c5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_he.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="he">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>שורות: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>מושבים =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>במטוס יש שני מושבים עבור הצוות (בשביל הטייס וטייס המשנה), ומספר שורות מושבים במחלקת הנוסעים הראשונה ובמחלקת הנוסעים השנייה. כל שורה במחלקה הראשונה מכילה ארבעה מושבים. כל שורה במחלקה השנייה מכילה חמישה מושבים.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>בנה נוסחה (למטה) אשר תחשב את סך כל המושבים במטוס בהתאם לשינוי מספר השורות (למעלה).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>במטוס יש שני מושבים עבור הצוות (בשביל הטייס וטייס המשנה), ומספר שורות עם מושבי נוסעים. בכל שורה יש ארבעה מושבים.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>שורות במחלקה ראשונה (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>שורות במחלקה שנייה: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>מושבים: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>מחשבון מושב במטוס</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>שורות (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>שורות במחלקה ראשונה: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>במטוס יש מספר שורות עם מושבי נוסעים. בכל שורה יש ארבעה מושבים.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>שורות במחלקה שנייה: (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hrx.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hrx.xlf
                new file mode 100644
                index 000000000..263d30507
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hrx.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="hrx">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Reihe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>Sitze =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>En Fluchzeich hot zwooi Sitze im Pilotstand (für den Pilot und Co-Pilot) und en Oonzohl an Reihe mit Passagiersitze der 1. und 2. Klasse. Jede 1.-Klasse-Reih enthält vier Sitze. Jede 2.-Klasse-Reih enthält fünf Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Erstell en Formel (unne), die die gesamte Oonzohl an Sitze im Fluchzeich berechnet, wenn die Reihe (uwe) geännert sin.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>En Fluchzeich hot zwooi Sitze im Pilotestand (für den Pilot und Co-Pilot) und en Oonzohl an Reihe mit Passagiersitze. Jede Reih enthält vier Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Reihe von der 1. Klasse (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Reihe von der 2. Klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sitz: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Fluchzeichsitzrechner</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>Reihe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Reihe von der 1. Klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>En Fluchzeich hot en Oonzohl an Reihe mit Passagiersitze. Jede Reih enthält vier Sitze.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Reihe von der 2. Klasse (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hu.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hu.xlf
                new file mode 100644
                index 000000000..c44d1aa9d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_hu.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="hu">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Sorok száma: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>Ülések száma =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Egy repülőgépnek 2 ülése van a pilótafülkében (a pilótának és a másodpilótának), az utasok 1. és 2. osztályon utazhatnak. Az 1. osztályon négy szék van egy sorban. A 2. osztályon öt szék van egy sorban.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Készítsd el a képletet (lent) amivel kiszámolható, hogy hány ülés van összesen a repülőgépen annak függvényében, ahogy (fent) állítod a sorok számát.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Egy repülőgépnek 2 ülése van a pilótafülkében (a pilótának és a másodpilótának), az utasok több sorban ülnek az utastérben.  Az utastér minden sorában négy szék van.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>1. osztály sorai (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>2. osztály: %1 sor</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Ülések száma összesen: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Repülőgép alkalmazás</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>Sorok száma (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>1. osztály: %1 sor</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Egy repülőgépen az utasok több sorban ülnek az utastérben.  Az utastér minden sorában négy szék van.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>2. osztály sorai (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ia.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ia.xlf
                new file mode 100644
                index 000000000..83ae2c6d2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ia.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ia">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Filas: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sedes =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un avion ha duo sedes in le cabina (pro le pilota e le copilota) e un numero de filas de sedes pro passageros del prime classe e del secunde classes. Cata fila del prime classe contine quatro sedes. Cata fila del secunde classe contine cinque sedes.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Construe un formula (ci infra) que calcula le numero total de sedes in le avion quando le numero de filas es cambiate (ci supra).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion ha duo sedes in le cabina (pro le pilota e le copilota) e un numero de filas de sedes pro passageros. Cata fila contine quatro sedes.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>filas de prime classe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Filas de secunde classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sedes: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculator de sedias de avion</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>filas (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Filas de prime classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion ha un numero de filas de sedes pro passageros. Cata fila contine quatro sedes.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>filas de secunde classe (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_is.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_is.xlf
                new file mode 100644
                index 000000000..3810f4b34
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_is.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="is">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Raðir: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sæti =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Flugvél er með tvö sæti í stjórnklefa (fyrir flugmanninn og aðstoðarflugmanninn) og einhvern fjölda sætaraða fyrir farþega á 1. og 2. farrými. Hver sætaröð á 1. farrými hefur fjögur sæti. Hver sætaröð á 2. farrými hefur fimm sæti.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Búðu til formúlu (hér fyrir neðan) sem reiknar heildarfjölda sæta í flugvélinni eftir því sem röðunum er breytt (hér fyrir ofan).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Flugvél er með tvö sæti í stjórnklefa (fyrir flugmanninn og aðstoðarflugmanninn) og einhvern fjölda sætaraða fyrir farþega. Hver sætaröð hefur fjögur sæti.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>raðir 1. farrými (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Raðir 2. farrými: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sæti: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Flugsætareiknir</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>raðir (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Raðir 1. farrými: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Flugvél er með einhvern fjölda sætaraða fyrir farþega. Í hverri röð eru fjögur sæti.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>raðir 2. farrými (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_it.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_it.xlf
                new file mode 100644
                index 000000000..27bad0dcf
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_it.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="it">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>File: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sedili =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un aereo ha due posti nella cabina di pilotaggio (per il pilota e il co-pilota), e un numero di file in prima e seconda classe, con i posti a sedere dei passeggeri. Ogni fila della prima classe contiene quattro posti. Quelle invece della seconda classe, ne contengono cinque.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Costruisci una formula (sotto) che calcola il numero totale di posti a sedere su un aeroplano, così come cambiano le file di posti (sopra).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un aeroplano ha due posti a sedere nella cabina di pilotaggio (per il pilota e co-pilota), e un numero di file con i posti a sedere dei passeggeri. Ogni fila contiene quattro posti.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>file 1ª classe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>File 2ª classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sedili: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calcolo posti aereo</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>file (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>File 1ª classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un aeroplano ha un numero di file contenenti i posti a sedere dei passeggeri. Ogni fila, contiene quattro posti a sedere.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>File 2ª classe (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ja.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ja.xlf
                new file mode 100644
                index 000000000..b04624a27
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ja.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ja">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>列の数: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>座席の数 =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>飛行機には、操縦室の 2 つの座席 (操縦士と副操縦士) と、ファーストクラスとセカンドクラスの乗客の座席の列があります。それぞれの列に、ファーストクラスでは 4 つの座席、セカンドクラスでは 5 つの座席があります。</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>飛行機の座席の数を計算する式を、上で列の数を変更しても正しくなるように、下に入力してください。</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>飛行機には、操縦室の 2 つの座席 (操縦士と副操縦士) と、乗客の座席の列があります。それぞれの列に 4 つの座席があります。</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>ファーストクラスの列数 (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>セカンドクラスの列数: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>座席の数: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>飛行機座席計算機</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>列の数 (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>ファーストクラスの列数: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>飛行機に乗客の座席の列があります。それぞれの列に 4 つの座席があります。</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>セカンドクラスの列数 (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ko.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ko.xlf
                new file mode 100644
                index 000000000..07e23288e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ko.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ko">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>행 수: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>좌석수 =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>비행기는 비행 갑판(조종사와 부조종사용)에서 좌석 두 개가 있고, 1등석과 2등석 승객 좌석의 행 수가 있습니다. 각 1등석 행에는 시트 네 개가 포함되어 있습니다. 각 2등석 행에는 시트 다섯 개가 포함되어 있습니다.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>행이 바뀐(위) 비행기에 좌석의 총 수를 계산하는 공식(아래)을 구축하세요.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>비행기는 비행 갑판(조종사와 부조종사용)에서 좌석 두 개가 있고, 승객 좌석의 행 수가 있습니다. 각 행에는 시트 네 개가 포함되어 있습니다.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>1등석 행 수 (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>2등석 행 수: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>좌석 수: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>비행기 좌석 계산기</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>행 수 (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>1등석 행 수: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>비행기는 승객 좌석의 행 수가 있습니다. 각 행에는 시트 네 개가 포함되어 있습니다.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>2등석 행 수 (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ms.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ms.xlf
                new file mode 100644
                index 000000000..c34f084a3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ms.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ms">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Baris: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>tempat duduk =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Sebuah kapal terbang mempunyai tempat duduk di kokpit (untuk juruterbang dan pembantunya) dan sebilangan baris tempat duduk penumpang kelas pertama dan kelas kedua. Setiap baris kelas pertama mengandungi empat tempat duduk. Setiap baris kelas pertama mengandungi lima tempat duduk.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Wujudkan formula (di bawah) yang mengira jumlah tempat duduk di dalam kapal terbang sedangkan baris-barisnya diubah (di atas).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Sebuah kapal terbang mempunyai tempat duduk di kokpit (untuk juruterbang dan pembantunya) dan sebilangan baris tempat duduk penumpang. Setiap baris mengandungi empat tempat duduk.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>baris kelas pertama (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Baris kelas kedua: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Tempat duduk: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Pengira Tempat Duduk Kapal Terbang</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>baris (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Baris kelas pertama: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Sebuah kapal terbang mempunyai sebilangan baris tempat duduk penumpang. Setiap baris mengandungi empat tempat duduk.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>baris kelas kedua (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nb.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nb.xlf
                new file mode 100644
                index 000000000..99c9c6a99
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nb.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="nb">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rader: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>seter =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Et fly har to seter i cockpit (for piloten og andrepiloten), og et antall rader med passasjerseter på første og andre klasse. Hver av radene på første klasse har fire seter. Hver av radene på andre klasse har fem seter.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Bygg en formel (under) som beregner det totale antall seter på flyet etter hvert som radene endres (over).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Et fly har to seter i cockpit (for piloten og andrepiloten), og et antall rader med passasjerseter. Hver rad inneholder fire seter.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Rader i første klasse (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Rader i andre klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Seter: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Flysetekalkulator</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rader (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Rader i første klasse: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Et fly har et antall rader med passasjerseter. Hver rad inneholder fire seter.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Rader i andre klasse (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nl.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nl.xlf
                new file mode 100644
                index 000000000..6f36fa026
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_nl.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="nl">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rijen: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>stoelen=</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Een vliegtuig heeft twee stoelen in de cockpit (voor de piloot en de copiloot) en een aantal rijen voor 1e klasse en 2e klasse passagiers. Iedere rij in de 1e klasse heeft vier stoelen. Iedere rij in de 2e klasse heeft vijf stoelen.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Maak hieronder een formule die het totale aantal stoelen in het vliegtuig berekent als het aantal rijen hierboven wordt aangepast.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Een vliegtuig heeft twee stoelen in de cockpit (voor de piloot en de copiloot) en een aantal rijen met stoelen voor passagiers. Iedere rij bevat vier stoelen.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Rijen 1e klas (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Rijen 2e klas: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Zitplaatsen: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Vliegtuigstoelencalculator</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rijen (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Rijen 1e klas: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Een vliegtuig heeft een aantal rijen met stoelen. Iedere rij heeft vier stoelen.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Rijen 2e klas (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pl.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pl.xlf
                new file mode 100644
                index 000000000..4c8b044e2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pl.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="pl">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rzędów: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>siedzeń =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Samolot ma dwa miejsca w kabinie pilotów (dla pierwszego i drugiego pilota) oraz rzędy siedzeń dla pasażerów pierwszej i drugiej klasy. Każdy rząd pierwszej klasy składa się z czterech siedzeń. Każdy rząd drugiej klasy składa się z pięciu siedzeń.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Zbuduj wzór (poniżej), który pozwala obliczyć łączną liczbę siedzeń w samolocie w funkcji zmieniającej się liczby rzędów (powyżej).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Samolot ma dwa miejsca w kabinie pilotów (dla pierwszego i drugiego pilota) oraz rzędy siedzeń dla pasażerów. Każdy taki rząd składa się z czterech siedzeń.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Rzędów w pierwszej klasie (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Rzędów w drugiej klasie: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Siedzeń: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Kalkulator miejsc w samolocie.</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rzędów (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Rzędów w pierwszej klasie: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Samolot ma kilka rzędów siedzeń pasażerów. Każdy rząd zawiera cztery miejsca.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Rzędów w drugiej klasie (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pms.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pms.xlf
                new file mode 100644
                index 000000000..0fef91217
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pms.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="pms">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Linie: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>sedij =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>N'avion a l'ha doi sedij ant la cabin-a ëd pilotage (për ël pilòta e ël cò-pilòta) e un chèich nùmer ëd file ëd sedij pr'ij passagé ëd prima e sconda classa. Minca fila ëd prima classa a conten quatr sedij. Minca fila ëd seconda classa a conten sinch sedij.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Fabriché na fórmola (sì-sota) ch'a fa 'l cont dël nùmer total ëd sedij ant l'avion cand che ël nùmer dle file a cangia (sì-dzora).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>N'avion a l'ha doi sedij ant la cabin-a ëd pilotage (për ël pilòta e ël cò-pilòta), e un chèich nùmer ëd file ëd sedij pr'ij passagé. Minca fila a conten quatr sedij.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>linie ëd prima classa (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>linie ëd seconda classa: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Sedij: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calcolator ëd sedij d'avion</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>linie (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>linie ëd prima classa: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>N'avion a l'ha un nùmer ëd file ëd sedij da passëgé. Minca fila a l'ha quatr sedij.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>linie ëd seconda classa (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pt-br.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pt-br.xlf
                new file mode 100644
                index 000000000..7bdd9ccff
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_pt-br.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="pt-br">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Filas: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>assentos =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Um avião tem dois assentos na cabine de comando (para o piloto e o copiloto) e um número de filas de assentos na primeira e na segunda classe. Cada fila da primeira classe contém quatro assentos. Cada fila da segunda classe contém cinco assentos.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Elabore uma fórmula (abaixo) que calcule o número total de assentos no avião a medida que as filas são alteradas (acima).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Um avião tem dois assentos na cabine de comando (para o piloto e o copiloto) e um número de filas de assentos para os passageiros. Cada fila contém quatro assentos.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>filas na primeira classe (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>filas na segunda classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Assentos: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculadora de Assentos em Avião</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>filas (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>filas na primeira classe: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Um avião tem um número de filas de assentos para os passageiros. Cada fila contém quatro assentos.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>filas na segunda classe (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ro.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ro.xlf
                new file mode 100644
                index 000000000..614a3bda2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ro.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ro">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rânduri: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>scaune =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Un avion are două scaune în carlingă (pentru pilot și copilot) și un număr de rânduri cu scaune de clasa I și clasa a II-a pentru pasageri. Fiecare rând de clasa I conține patru scaune. Fiecare rând de clasa a II-a conține cinci scaune.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Construiește o formulă (mai jos) care calculează numărul total de locuri dintr-un avion în timp ce rândurile se schimbă (mai sus).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion are două scaune în carlingă (pentru pilot și copilot) și un număr de rânduri cu scaune pentru pasageri. Fiecare rând conține patru scaune.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>rânduri de clasa I (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>rânduri de clasa a II-a: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Scaune: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Calculator pentru locurile dintr-un avion</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rânduri (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>rânduri de clasa I: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Un avion are un număr de rânduri cu scaune pentru pasageri. Fiecare rând conține patru scaune.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>rânduri de clasa a II-a (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ru.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ru.xlf
                new file mode 100644
                index 000000000..d25b25458
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_ru.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="ru">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Рядов: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>места =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>В самолёте 2 места для пилота и его помощника, несколько рядов с пассажирскими местами первого класса, а также несколько рядов с пассажирскими местами второго класса. В каждом ряду первого класса 4 места. В каждом ряду второго класса 5 мест.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Постройте формулу в области ниже, которая поможет рассчитать общее количество мест в самолёте (как на рисунке выше).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>В самолёте 2 места для пилота и его помощника, а также несколько рядов с пассажирскими местами. В каждом ряду 4 места.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>ряды 1-го класса (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Рядов 2-го класса: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Мест: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Калькулятор посадочных мест в самолёте</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>ряды (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Рядов 1-го класса: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>В самолёте несколько рядов с пассажирскими местами. В каждом ряду 4 места.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>ряды 2-го класса (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sc.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sc.xlf
                new file mode 100644
                index 000000000..632812356
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sc.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="sc">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Fileras: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>cadironis =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Unu aparèchiu tenit duus cadironis in sa cabina de cumandu (po su pilota e su co-pilota), e unas cantu fileras de cadironis po passigeris de prima classi e de segunda classi. Dònnia filera de prima classi tenit cuatru cadironis. Dònnia filera de segunda classi tenit cincu cadironis.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Cuncorda una formula (innoi asuta) chi cumpudit su numeru totali de postus a setzi in s'aparechiu, a segunda de comenti mudant is fileras de postus (innoi in susu)</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Unu aparèchiu tenit duus cadironis in sa cabina de cumandu (po su pilota e su co-pilota), e unas cantu fileras de cadironis po passigeris. Dònnia filera tenit cuatru cadironis.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>fileras de primu classi (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>fileras de segunda classi: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Cadironis: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Fai su contu de is cadironis de unu aparèchiu</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>fileras (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>fileras de primu classi: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Unu aparèchiu tenit unas cantu fileras de cadironis po passigeris. Dònnia filera tenit cuatru cadironis.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>fileras de segunda classi (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sv.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sv.xlf
                new file mode 100644
                index 000000000..f3d836fba
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_sv.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="sv">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Rader: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>säten =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Ett flygplan har två säten i cockpiten (ett för piloten och ett för andrepiloten) och ett antal rader med passagerarsäten i första och andra klass. Varje rad i första klass innehåller fyra säten. Varje rad i andra klass innehåller fem säten.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Bygg en formel (nedan) som beräknar det totala antalet säten på flygplanet när raderna ändras (ovan).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ett flygplan har två säten i cockpiten (ett för piloten och ett för andrepiloten) och ett antal rader med passagerarsäten. Varje rad innehåller fyra säten.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Rader i första klass (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Rader i andra klass: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Säten: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Plansäteskalkylator</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>rader (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Rader i första klass: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Ett flygplan har ett antal rader med passagerarsäten. Varje rad innehåller fyra säten.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>Rader i andra klass (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_th.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_th.xlf
                new file mode 100644
                index 000000000..0967d4d19
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_th.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="th">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>%1 แถว</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>จำนวนที่นั่ง =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>ภายในเครื่องบินจะมีที่นั่งนักบินอยู่ 2 ที่ (สำหรับนักบิน และผู้ช่วยนักบิน) และจะมีแถวที่นั่งสำหรับผู้โดยสาร "ชั้นเฟิร์สคลาส" และ "ชั้นธุรกิจ" อยู่จำนวนหนึ่ง โดยในชั้นเฟิร์สคลาสจะมีแถวละ 4 ที่นั่ง ส่วนในชั้นธุรกิจจะมีแถวละ 5 ที่นั่ง</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>สร้างสูตรคำนวณ (ด้านล่าง) เพื่อคำนวณหาจำนวนที่นั่งทั้งหมดบนเครื่องบิน ตามจำนวนแถวที่เปลี่ยนไป (ด้านบน)</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>ภายในเครื่องบินจะมีที่นั่งนักบินอยู่ 2 ที่ (สำหรับนักบิน และผู้ช่วยนักบิน) และมีแถวที่นั่งผู้โดยสารอยู่จำนวนหนึ่ง ในแต่ละแถวจะมี 4 ที่นั่ง</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>จำนวนแถวชั้นเฟิร์สคลาส (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>ชั้นธุรกิจ %1 แถว</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>คำนวณได้ทั้งหมด %1 ที่นั่ง</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>ระบบคำนวณที่นั่งบนเครื่องบิน</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>จำนวนแถว (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>ชั้นเฟิร์สคลาส %1 แถว</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>ภายในเครื่องบินประกอบไปด้วยแถวของที่นั่งผู้โดยสาร ในแต่ละแถวจะมี 4 ที่นั่ง</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>จำนวนแถวชั้นธุรกิจ (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_tr.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_tr.xlf
                new file mode 100644
                index 000000000..678541a32
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_tr.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="tr">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Sıralar: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>koltuklar =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Bir uçağın uçuş güvertesinde iki koltuğu (pilot ve yardımcı pilot için), ve belirli sayıda birinci sınıf ve ikinci sınıf yolcu koltuğu sırası vardır. Her birinci sınıf sıra dört koltuk içerir. Her ikinci sınıf sıra beş koltuk içerir.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Sıralar(üstte) değiştikçe uçaktaki toplam koltuk sayısını hesaplayan bir formül(altta) oluşturun.</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Bir uçağın uçuş güvertesinde iki koltuğu (pilot ve yardımcı pilot için), ve belirli sayıda koltuk sırası vardır. Her sıra dört koltuk içerir.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>Birinci sınıf sıralar (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>İkinci sınıf sıralar: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Koltuklar: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Uçak Koltuğu Hesaplayıcı</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>sıralar (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Birinci sınıf sıralar: (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Bir uçağın belirli sayıda koltuk sırası vardır. Her sıra dört koltuk içerir.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>İkinci sınıf sıralar (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_uk.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_uk.xlf
                new file mode 100644
                index 000000000..d5e7682a5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_uk.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="uk">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Рядки: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>місць=</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Літак має два місця в кабіні екіпажу (пілот і другий пілот), і кілька рядів 1-го класу 2-го класу пасажирських місць. Кожний ряд 1-го класу містить чотири місця. Кожен ряд 2-го класу містить п'ять місць.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Побудувати формулу (нижче), яка обчислює кількість місць на літаку при зміні рядків (див. вище).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Літак має два місця в кабіні екіпажу (пілот і другий пілот), і кілька рядів пасажирських сидінь. Кожен рядок містить чотири місця.</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>рядів 1-го класу (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>рядів 2-го класу: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Місць: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Калькулятор місць у літаку</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>рядки (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>рядів 1-го класу: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Літак має кілька рядів пасажирських сидінь. Кожен ряд містить чотири місця.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>рядів 2-го класу (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_vi.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_vi.xlf
                new file mode 100644
                index 000000000..1f4ef6fcf
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_vi.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="vi">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>Số hàng ghế: %1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>Tính số chỗ ngồi =</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>Một chiếc máy bay này có hai chỗ ngồi ở sàn (cho phi công trưởng và phi công phó), và một số hàng ghế hạng 1 và hạng 2.  Mỗi hàng hạng 1 có bốn chỗ ngồi. Mỗi hàng hạng 2 có năm chỗ ngồi.</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>Dưới đây hãy tạo công thức tính số chỗ ngồi trên máy bay để nó thay đổi tùy theo số lượng hàng ghế (hình trên).</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Một máy bay có hai ghế trong buồng lái (dành cho phi công trưởng và phi công phụ), và một loạt hàng ghế cho hành khách. Mỗi hàng có bốn ghế (bốn chỗ ngồi).</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>số hàng hạng nhất (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>Hàng hạng hai: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>Số chỗ ngồi: %1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>Máy bay ghế máy tính</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>đếm số hàng ghế (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>Hàng hạng nhất: %1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>Máy bay có một số hàng ghế hành khách.  Mỗi hàng có bốn chỗ ngồi.</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>số hàng hạng hai (%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hans.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hans.xlf
                new file mode 100644
                index 000000000..2cbb7e858
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hans.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="zh-hans">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>行:%1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>座位=</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>一架飞机除了有两个座位供正副驾驶员,还有一定量行数的头等及经济乘客座位。头等每行共四座,经济每行共五座。</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>于下方写出一条公式以计算飞机上的座位总数。</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>一架飞机除了有两个座位供正副驾驶员,还有一定量行数的乘客座位。每行共四座。</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>头等行(%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>经济等行:%1</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>座位:%1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>飞机座位计算器</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>行 (%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>头等行:%1</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>一架飞机有一定量行数的乘客座位,每行共四座。</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>经济等行(%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hant.xlf b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hant.xlf
                new file mode 100644
                index 000000000..2dadf6d4e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/plane/xlf/translated_msgs_zh-hant.xlf
                @@ -0,0 +1,63 @@
                +<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle" datatype="x-soy-msg-bundle" source-language="en" target-language="zh-hant">
                +    <body>
                +      <trans-unit id="286555642257111053" datatype="html">
                +        <source>Rows: %1</source>
                +        <target>排:%1</target>
                +      </trans-unit>
                +      <trans-unit id="990695256953568910" datatype="html">
                +        <source>seats =</source>
                +        <target>座位=</target>
                +      </trans-unit>
                +      <trans-unit id="1327005465775917626" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of 1st class and 2nd class passenger seats.  Each 1st class row contains four seats. Each 2nd class row contains five seats.</source>
                +        <target>一架飛機除了有兩個座位供正副機師,還有一定量行數的頭等及經濟乘客座位。頭等艙每排都包含四個席位,經濟艙每排都包含五個席位。。</target>
                +      </trans-unit>
                +      <trans-unit id="1649099567159388799" datatype="html">
                +        <source>?</source>
                +        <target>?</target>
                +      </trans-unit>
                +      <trans-unit id="3872872459414039837" datatype="html">
                +        <source>Build a formula (below) that calculates the total number of seats on the airplane as the rows are changed (above).</source>
                +        <target>於下方寫出一條公式以計算飛機上的座位總數。</target>
                +      </trans-unit>
                +      <trans-unit id="4755413400587385256" datatype="html">
                +        <source>An airplane has two seats in the flight deck (for the pilot and co-pilot), and a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>一架飛機除了有兩個座位供正副機師,還有一定量行數的乘客座位。每排都包含四個席位。</target>
                +      </trans-unit>
                +      <trans-unit id="5622822520334788359" datatype="html">
                +        <source>1st class rows (%1)</source>
                +        <target>頭等艙(%1)</target>
                +      </trans-unit>
                +      <trans-unit id="6523489254328705062" datatype="html">
                +        <source>2nd class rows: %1</source>
                +        <target>經濟艙:%1 排</target>
                +      </trans-unit>
                +      <trans-unit id="6636919311618748816" datatype="html">
                +        <source>Seats: %1</source>
                +        <target>座位:%1</target>
                +      </trans-unit>
                +      <trans-unit id="6646116297668869388" datatype="html">
                +        <source>Plane Seat Calculator</source>
                +        <target>飛機座位計算器</target>
                +      </trans-unit>
                +      <trans-unit id="7030918043298347994" datatype="html">
                +        <source>rows (%1)</source>
                +        <target>排(%1)</target>
                +      </trans-unit>
                +      <trans-unit id="7091637686507441682" datatype="html">
                +        <source>1st class rows: %1</source>
                +        <target>頭等艙:%1 排</target>
                +      </trans-unit>
                +      <trans-unit id="7784699858027886282" datatype="html">
                +        <source>An airplane has a number of rows of passenger seats.  Each row contains four seats.</source>
                +        <target>一架飛機有一定量行數的乘客座位,每排都包含四個席位。</target>
                +      </trans-unit>
                +      <trans-unit id="8347578891541780742" datatype="html">
                +        <source>2nd class rows (%1)</source>
                +        <target>經濟艙(%1)</target>
                +      </trans-unit>
                +    </body>
                +  </file>
                +</xliff>
                diff --git a/blockly/webif/static/blockly/demos/resizable/icon.png b/blockly/webif/static/blockly/demos/resizable/icon.png
                new file mode 100644
                index 000000000..435527585
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/resizable/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/resizable/index.html b/blockly/webif/static/blockly/demos/resizable/index.html
                new file mode 100644
                index 000000000..e2ee1e06d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/resizable/index.html
                @@ -0,0 +1,52 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Resizable Blockly (Part 1)</title>
                +  <style>
                +    html, body {
                +      height: 100%;
                +      margin: 0;
                +    }
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +      overflow: hidden;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    table {
                +      height: 100%;
                +      width: 100%;
                +    }
                +    #blocklyArea {
                +      height: 99%;
                +      background: #fc9;
                +      text-align: center;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <table>
                +    <tr>
                +      <td>
                +        <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +          <a href="../index.html">Demos</a> &gt; Resizable Blockly (Part 1)</h1>
                +
                +        <p>The first step in creating a resizable Blockly workspace is to use
                +        CSS or tables to create an area for it.
                +        Next, <a href="overlay.html">inject Blockly</a> over that area.</p>
                +
                +        <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure/web/resizable">injecting resizable Blockly</a>&hellip;</p>
                +      </td>
                +    </tr>
                +    <tr>
                +      <td id="blocklyArea">
                +        Blockly will be positioned here.
                +      </td>
                +    </tr>
                +  </table>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/resizable/overlay.html b/blockly/webif/static/blockly/demos/resizable/overlay.html
                new file mode 100644
                index 000000000..2d9f41f9b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/resizable/overlay.html
                @@ -0,0 +1,93 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Resizable Blockly (Part 2)</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    html, body {
                +      height: 100%;
                +      margin: 0;
                +    }
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +      overflow: hidden;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    table {
                +      height: 100%;
                +      width: 100%;
                +    }
                +    #blocklyArea {
                +      height: 99%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <table>
                +    <tr>
                +      <td>
                +        <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +          <a href="../index.html">Demos</a> &gt; Resizable Blockly (Part 2)</h1>
                +
                +        <p>
                +          Once an <a href="index.html">area is defined</a>, Blockly can be
                +          injected and positioned over the area.
                +          A resize handler keeps it in position as the page changes.
                +        </p>
                +
                +        <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure/web/resizable">injecting resizable Blockly</a>&hellip;</p>
                +      </td>
                +    </tr>
                +    <tr>
                +      <td id="blocklyArea">
                +      </td>
                +    </tr>
                +  </table>
                +
                +  <div id="blocklyDiv" style="position: absolute"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <block type="controls_if"></block>
                +    <block type="logic_compare"></block>
                +    <block type="controls_repeat_ext"></block>
                +    <block type="math_number"></block>
                +    <block type="math_arithmetic"></block>
                +    <block type="text"></block>
                +    <block type="text_print"></block>
                +  </xml>
                +
                +  <script>
                +    var blocklyArea = document.getElementById('blocklyArea');
                +    var blocklyDiv = document.getElementById('blocklyDiv');
                +    var workspace = Blockly.inject(blocklyDiv,
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +    var onresize = function(e) {
                +      // Compute the absolute coordinates and dimensions of blocklyArea.
                +      var element = blocklyArea;
                +      var x = 0;
                +      var y = 0;
                +      do {
                +        x += element.offsetLeft;
                +        y += element.offsetTop;
                +        element = element.offsetParent;
                +      } while (element);
                +      // Position blocklyDiv over blocklyArea.
                +      blocklyDiv.style.left = x + 'px';
                +      blocklyDiv.style.top = y + 'px';
                +      blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
                +      blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
                +    };
                +    window.addEventListener('resize', onresize, false);
                +    onresize();
                +    Blockly.svgResize(workspace);
                +  </script>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/rtl/icon.png b/blockly/webif/static/blockly/demos/rtl/icon.png
                new file mode 100644
                index 000000000..e177e32a3
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/rtl/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/rtl/index.html b/blockly/webif/static/blockly/demos/rtl/index.html
                new file mode 100644
                index 000000000..fd84febd2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/rtl/index.html
                @@ -0,0 +1,204 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <meta name="google" value="notranslate">
                +  <title>Blockly Demo: RTL</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/ar.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    #blocklyDiv {
                +      height: 600px;
                +      width: 800px;
                +    }
                +  </style>
                +  <script>
                +    function init() {
                +      var workspace = Blockly.inject('blocklyDiv',
                +          {media: '../../media/',
                +           rtl: true,
                +           toolbox: document.getElementById('toolbox')});
                +      Blockly.Xml.domToWorkspace(document.getElementById('startBlocks'),
                +                                 workspace);
                +      //window.onbeforeunload = function() {
                +      //  return 'Leaving this page will result in the loss of your work.';
                +      //};
                +    }
                +  </script>
                +</head>
                +<body onload="init()">
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Right-to-Left</h1>
                +
                +  <div id="blocklyDiv"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="منطق">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="الحلقات">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +        <value name="BY">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="رياضيات">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +      <block type="math_trig"></block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property"></block>
                +      <block type="math_round"></block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo"></block>
                +      <block type="math_constrain">
                +        <value name="LOW">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="HIGH">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="نص">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +      <block type="text_length"></block>
                +      <block type="text_isEmpty"></block>
                +      <block type="text_indexOf"></block>
                +      <block type="text_charAt"></block>
                +      <block type="text_changeCase"></block>
                +      <block type="text_trim"></block>
                +      <block type="text_print"></block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="قوائم">
                +      <block type="lists_create_empty"></block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">5</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf"></block>
                +      <block type="lists_getIndex"></block>
                +      <block type="lists_setIndex"></block>
                +    </category>
                +    <category name="لون">
                +      <block type="colour_picker"></block>
                +      <block type="colour_rgb"></block>
                +      <block type="colour_blend"></block>
                +    </category>
                +    <category name="متغيرات" custom="VARIABLE"></category>
                +    <category name="إجراءات" custom="PROCEDURE"></category>
                +  </xml>
                +
                +  <xml id="startBlocks" style="display: none">
                +    <block type="controls_if" inline="false" x="-100" y="50">
                +      <value name="IF0">
                +        <block type="logic_compare" inline="true">
                +          <field name="OP">LT</field>
                +          <value name="A">
                +            <block type="variables_get">
                +              <field name="VAR">x</field>
                +            </block>
                +          </value>
                +          <value name="B">
                +            <block type="math_number">
                +              <field name="NUM">256</field>
                +            </block>
                +          </value>
                +        </block>
                +      </value>
                +      <statement name="DO0">
                +        <block type="variables_set" inline="false">
                +          <field name="VAR">x</field>
                +          <value name="VALUE">
                +            <block type="math_number">
                +              <field name="NUM">0</field>
                +            </block>
                +          </value>
                +          <next>
                +            <block type="text_print" inline="false">
                +              <value name="TEXT">
                +                <block type="text">
                +                  <field name="TEXT">أكثر من لعبة</field>
                +                </block>
                +              </value>
                +            </block>
                +          </next>
                +        </block>
                +      </statement>
                +    </block>
                +  </xml>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/storage/icon.png b/blockly/webif/static/blockly/demos/storage/icon.png
                new file mode 100644
                index 000000000..b8c50b245
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/storage/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/storage/index.html b/blockly/webif/static/blockly/demos/storage/index.html
                new file mode 100644
                index 000000000..57cad3304
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/storage/index.html
                @@ -0,0 +1,94 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Cloud Storage</title>
                +  <script src="/storage.js"></script>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +    #sorry {
                +      padding: 1ex;
                +      background-color: #f9edbe;
                +      border: solid 1px #f0c36d;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Cloud Storage</h1>
                +
                +  <p>This is a simple demo of cloud storage using App Engine.</p>
                +
                +  <script>
                +    if ('BlocklyStorage' in window) {
                +      BlocklyStorage.HTTPREQUEST_ERROR = 'There was a problem with the request.\n';
                +      BlocklyStorage.LINK_ALERT = 'Share your blocks with this link:\n\n%1';
                +      BlocklyStorage.HASH_ERROR = 'Sorry, "%1" doesn\'t correspond with any saved Blockly file.';
                +      BlocklyStorage.XML_ERROR = 'Could not load your saved file.\n'+
                +          'Perhaps it was created with a different version of Blockly?';
                +    } else {
                +      document.write('<p id="sorry">Sorry, cloud storage is not available.  This demo must be hosted on App Engine.</p>');
                +    }
                +  </script>
                +
                +  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure-blockly/web/cloud-storage">Cloud Storage</a>&hellip;</p>
                +
                +  <p>
                +    <button onclick="BlocklyStorage.link()">Save Blocks</button>
                +  </p>
                +
                +  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +    </category>
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_length"></block>
                +      <block type="text_print"></block>
                +    </category>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +
                +    // An href with #key trigers an AJAX call to retrieve saved blocks.
                +    if ('BlocklyStorage' in window && window.location.hash.length > 1) {
                +      BlocklyStorage.retrieveXml(window.location.hash.substring(1));
                +    }
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/demos/toolbox/icon.png b/blockly/webif/static/blockly/demos/toolbox/icon.png
                new file mode 100644
                index 000000000..336f39028
                Binary files /dev/null and b/blockly/webif/static/blockly/demos/toolbox/icon.png differ
                diff --git a/blockly/webif/static/blockly/demos/toolbox/index.html b/blockly/webif/static/blockly/demos/toolbox/index.html
                new file mode 100644
                index 000000000..4e81c02eb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/demos/toolbox/index.html
                @@ -0,0 +1,343 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +  <meta charset="utf-8">
                +  <title>Blockly Demo: Toolbox</title>
                +  <script src="../../blockly_compressed.js"></script>
                +  <script src="../../blocks_compressed.js"></script>
                +  <script src="../../msg/js/en.js"></script>
                +  <style>
                +    body {
                +      background-color: #fff;
                +      font-family: sans-serif;
                +    }
                +    h1 {
                +      font-weight: normal;
                +      font-size: 140%;
                +    }
                +  </style>
                +</head>
                +<body>
                +  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
                +    <a href="../index.html">Demos</a> &gt; Toolbox</h1>
                +
                +  <p>This is a demo of a complex category structure for the toolbox.</p>
                +
                +  <p>&rarr; More info on the <a href="https://developers.google.com/blockly/guides/configure/web/toolbox">Toolbox</a>&hellip;</p>
                +
                +  <div id="blocklyDiv" style="height: 600px; width: 800px;"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Logic">
                +      <category name="If">
                +        <block type="controls_if"></block>
                +        <block type="controls_if">
                +          <mutation else="1"></mutation>
                +        </block>
                +        <block type="controls_if">
                +          <mutation elseif="1" else="1"></mutation>
                +        </block>
                +      </category>
                +      <category name="Boolean">
                +        <block type="logic_compare"></block>
                +        <block type="logic_operation"></block>
                +        <block type="logic_negate"></block>
                +        <block type="logic_boolean"></block>
                +        <block type="logic_null"></block>
                +        <block type="logic_ternary"></block>
                +      </category>
                +    </category>
                +    <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <field name="VAR">i</field>
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +        <value name="BY">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +      <block type="math_trig"></block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property"></block>
                +      <block type="math_round"></block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo"></block>
                +      <block type="math_constrain">
                +        <value name="LOW">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="HIGH">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Lists">
                +      <block type="lists_create_empty"></block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">5</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf"></block>
                +      <block type="lists_getIndex"></block>
                +      <block type="lists_setIndex"></block>
                +    </category>
                +    <category name="Variables" custom="VARIABLE"></category>
                +    <category name="Functions" custom="PROCEDURE"></category>
                +    <sep></sep>
                +    <category name="Library" expanded="true">
                +      <category name="Randomize">
                +        <block type="procedures_defnoreturn">
                +          <mutation>
                +            <arg name="list"></arg>
                +          </mutation>
                +          <field name="NAME">randomize</field>
                +          <statement name="STACK">
                +            <block type="controls_for" inline="true">
                +              <field name="VAR">x</field>
                +              <value name="FROM">
                +                <block type="math_number">
                +                  <field name="NUM">1</field>
                +                </block>
                +              </value>
                +              <value name="TO">
                +                <block type="lists_length" inline="false">
                +                  <value name="VALUE">
                +                    <block type="variables_get">
                +                      <field name="VAR">list</field>
                +                    </block>
                +                  </value>
                +                </block>
                +              </value>
                +              <value name="BY">
                +                <block type="math_number">
                +                  <field name="NUM">1</field>
                +                </block>
                +              </value>
                +              <statement name="DO">
                +                <block type="variables_set" inline="false">
                +                  <field name="VAR">y</field>
                +                  <value name="VALUE">
                +                    <block type="math_random_int" inline="true">
                +                      <value name="FROM">
                +                        <block type="math_number">
                +                          <field name="NUM">1</field>
                +                        </block>
                +                      </value>
                +                      <value name="TO">
                +                        <block type="lists_length" inline="false">
                +                          <value name="VALUE">
                +                            <block type="variables_get">
                +                              <field name="VAR">list</field>
                +                            </block>
                +                          </value>
                +                        </block>
                +                      </value>
                +                    </block>
                +                  </value>
                +                  <next>
                +                    <block type="variables_set" inline="false">
                +                      <field name="VAR">temp</field>
                +                      <value name="VALUE">
                +                        <block type="lists_getIndex" inline="true">
                +                          <mutation statement="false" at="true"></mutation>
                +                          <field name="MODE">GET</field>
                +                          <field name="WHERE">FROM_START</field>
                +                          <value name="AT">
                +                            <block type="variables_get">
                +                              <field name="VAR">y</field>
                +                            </block>
                +                          </value>
                +                          <value name="VALUE">
                +                            <block type="variables_get">
                +                              <field name="VAR">list</field>
                +                            </block>
                +                          </value>
                +                        </block>
                +                      </value>
                +                      <next>
                +                        <block type="lists_setIndex" inline="false">
                +                          <value name="AT">
                +                            <block type="variables_get">
                +                              <field name="VAR">y</field>
                +                            </block>
                +                          </value>
                +                          <value name="LIST">
                +                            <block type="variables_get">
                +                              <field name="VAR">list</field>
                +                            </block>
                +                          </value>
                +                          <value name="TO">
                +                            <block type="lists_getIndex" inline="true">
                +                              <mutation statement="false" at="true"></mutation>
                +                              <field name="MODE">GET</field>
                +                              <field name="WHERE">FROM_START</field>
                +                              <value name="AT">
                +                                <block type="variables_get">
                +                                  <field name="VAR">x</field>
                +                                </block>
                +                              </value>
                +                              <value name="VALUE">
                +                                <block type="variables_get">
                +                                  <field name="VAR">list</field>
                +                                </block>
                +                              </value>
                +                            </block>
                +                          </value>
                +                          <next>
                +                            <block type="lists_setIndex" inline="false">
                +                              <value name="AT">
                +                                <block type="variables_get">
                +                                  <field name="VAR">x</field>
                +                                </block>
                +                              </value>
                +                              <value name="LIST">
                +                                <block type="variables_get">
                +                                  <field name="VAR">list</field>
                +                                </block>
                +                              </value>
                +                              <value name="TO">
                +                                <block type="variables_get">
                +                                  <field name="VAR">temp</field>
                +                                </block>
                +                              </value>
                +                            </block>
                +                          </next>
                +                        </block>
                +                      </next>
                +                    </block>
                +                  </next>
                +                </block>
                +              </statement>
                +            </block>
                +          </statement>
                +        </block>
                +      </category>
                +      <category name="Jabberwocky">
                +        <block type="text_print">
                +          <value name="TEXT">
                +            <block type="text">
                +              <field name="TEXT">'Twas brillig, and the slithy toves</field>
                +            </block>
                +          </value>
                +          <next>
                +            <block type="text_print">
                +              <value name="TEXT">
                +                <block type="text">
                +                  <field name="TEXT">  Did gyre and gimble in the wabe:</field>
                +                </block>
                +              </value>
                +              <next>
                +                <block type="text_print">
                +                  <value name="TEXT">
                +                    <block type="text">
                +                      <field name="TEXT">All mimsy were the borogroves,</field>
                +                    </block>
                +                  </value>
                +                  <next>
                +                    <block type="text_print">
                +                      <value name="TEXT">
                +                        <block type="text">
                +                          <field name="TEXT">  And the mome raths outgrabe.</field>
                +                        </block>
                +                      </value>
                +                    </block>
                +                  </next>
                +                </block>
                +              </next>
                +            </block>
                +          </next>
                +        </block>
                +        <block type="text_print">
                +          <value name="TEXT">
                +            <block type="text">
                +              <field name="TEXT">"Beware the Jabberwock, my son!</field>
                +            </block>
                +          </value>
                +          <next>
                +            <block type="text_print">
                +              <value name="TEXT">
                +                <block type="text">
                +                  <field name="TEXT">  The jaws that bite, the claws that catch!</field>
                +                </block>
                +              </value>
                +              <next>
                +                <block type="text_print">
                +                  <value name="TEXT">
                +                    <block type="text">
                +                      <field name="TEXT">Beware the Jubjub bird, and shun</field>
                +                    </block>
                +                  </value>
                +                  <next>
                +                    <block type="text_print">
                +                      <value name="TEXT">
                +                        <block type="text">
                +                          <field name="TEXT">  The frumious Bandersnatch!"</field>
                +                        </block>
                +                      </value>
                +                    </block>
                +                  </next>
                +                </block>
                +              </next>
                +            </block>
                +          </next>
                +        </block>
                +      </category>
                +    </category>
                +  </xml>
                +
                +  <script>
                +    var workspace = Blockly.inject('blocklyDiv',
                +        {media: '../../media/',
                +         toolbox: document.getElementById('toolbox')});
                +  </script>
                +
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/generators/dart.js b/blockly/webif/static/blockly/generators/dart.js
                new file mode 100644
                index 000000000..83ef76cd6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart.js
                @@ -0,0 +1,274 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Helper functions for generating Dart for blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart');
                +
                +goog.require('Blockly.Generator');
                +
                +
                +/**
                + * Dart code generator.
                + * @type {!Blockly.Generator}
                + */
                +Blockly.Dart = new Blockly.Generator('Dart');
                +
                +/**
                + * List of illegal variable names.
                + * This is not intended to be a security feature.  Blockly is 100% client-side,
                + * so bypassing this list is trivial.  This is intended to prevent users from
                + * accidentally clobbering a built-in object or function.
                + * @private
                + */
                +Blockly.Dart.addReservedWords(
                +    // https://www.dartlang.org/docs/spec/latest/dart-language-specification.pdf
                +    // Section 16.1.1
                +    'assert,break,case,catch,class,const,continue,default,do,else,enum,' +
                +    'extends,false,final,finally,for,if,in,is,new,null,rethrow,return,super,' +
                +    'switch,this,throw,true,try,var,void,while,with,' +
                +    // https://api.dartlang.org/dart_core.html
                +    'print,identityHashCode,identical,BidirectionalIterator,Comparable,' +
                +    'double,Function,int,Invocation,Iterable,Iterator,List,Map,Match,num,' +
                +    'Pattern,RegExp,Set,StackTrace,String,StringSink,Type,bool,DateTime,' +
                +    'Deprecated,Duration,Expando,Null,Object,RuneIterator,Runes,Stopwatch,' +
                +    'StringBuffer,Symbol,Uri,Comparator,AbstractClassInstantiationError,' +
                +    'ArgumentError,AssertionError,CastError,ConcurrentModificationError,' +
                +    'CyclicInitializationError,Error,Exception,FallThroughError,' +
                +    'FormatException,IntegerDivisionByZeroException,NoSuchMethodError,' +
                +    'NullThrownError,OutOfMemoryError,RangeError,StackOverflowError,' +
                +    'StateError,TypeError,UnimplementedError,UnsupportedError'
                +);
                +
                +/**
                + * Order of operation ENUMs.
                + * https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operator_table
                + */
                +Blockly.Dart.ORDER_ATOMIC = 0;         // 0 "" ...
                +Blockly.Dart.ORDER_UNARY_POSTFIX = 1;  // expr++ expr-- () [] . ?.
                +Blockly.Dart.ORDER_UNARY_PREFIX = 2;   // -expr !expr ~expr ++expr --expr
                +Blockly.Dart.ORDER_MULTIPLICATIVE = 3; // * / % ~/
                +Blockly.Dart.ORDER_ADDITIVE = 4;       // + -
                +Blockly.Dart.ORDER_SHIFT = 5;          // << >>
                +Blockly.Dart.ORDER_BITWISE_AND = 6;    // &
                +Blockly.Dart.ORDER_BITWISE_XOR = 7;    // ^
                +Blockly.Dart.ORDER_BITWISE_OR = 8;     // |
                +Blockly.Dart.ORDER_RELATIONAL = 9;     // >= > <= < as is is!
                +Blockly.Dart.ORDER_EQUALITY = 10;      // == !=
                +Blockly.Dart.ORDER_LOGICAL_AND = 11;   // &&
                +Blockly.Dart.ORDER_LOGICAL_OR = 12;    // ||
                +Blockly.Dart.ORDER_IF_NULL = 13;       // ??
                +Blockly.Dart.ORDER_CONDITIONAL = 14;   // expr ? expr : expr
                +Blockly.Dart.ORDER_CASCADE = 15;       // ..
                +Blockly.Dart.ORDER_ASSIGNMENT = 16;    // = *= /= ~/= %= += -= <<= >>= &= ^= |=
                +Blockly.Dart.ORDER_NONE = 99;          // (...)
                +
                +/**
                + * Initialise the database of variable names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.Dart.init = function(workspace) {
                +  // Create a dictionary of definitions to be printed before the code.
                +  Blockly.Dart.definitions_ = Object.create(null);
                +  // Create a dictionary mapping desired function names in definitions_
                +  // to actual function names (to avoid collisions with user functions).
                +  Blockly.Dart.functionNames_ = Object.create(null);
                +
                +  if (!Blockly.Dart.variableDB_) {
                +    Blockly.Dart.variableDB_ =
                +        new Blockly.Names(Blockly.Dart.RESERVED_WORDS_);
                +  } else {
                +    Blockly.Dart.variableDB_.reset();
                +  }
                +
                +  var defvars = [];
                +  var variables = workspace.getAllVariables();
                +  if (variables.length) {
                +    for (var i = 0; i < variables.length; i++) {
                +      defvars[i] = Blockly.Dart.variableDB_.getName(variables[i].name,
                +          Blockly.Variables.NAME_TYPE);
                +    }
                +    Blockly.Dart.definitions_['variables'] =
                +        'var ' + defvars.join(', ') + ';';
                +  }
                +};
                +
                +/**
                + * Prepend the generated code with the variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.Dart.finish = function(code) {
                +  // Indent every line.
                +  if (code) {
                +    code = Blockly.Dart.prefixLines(code, Blockly.Dart.INDENT);
                +  }
                +  code = 'main() {\n' + code + '}';
                +
                +  // Convert the definitions dictionary into a list.
                +  var imports = [];
                +  var definitions = [];
                +  for (var name in Blockly.Dart.definitions_) {
                +    var def = Blockly.Dart.definitions_[name];
                +    if (def.match(/^import\s/)) {
                +      imports.push(def);
                +    } else {
                +      definitions.push(def);
                +    }
                +  }
                +  // Clean up temporary data.
                +  delete Blockly.Dart.definitions_;
                +  delete Blockly.Dart.functionNames_;
                +  Blockly.Dart.variableDB_.reset();
                +  var allDefs = imports.join('\n') + '\n\n' + definitions.join('\n\n');
                +  return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n\n') + code;
                +};
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything.  A trailing semicolon is needed to make this legal.
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.Dart.scrubNakedValue = function(line) {
                +  return line + ';\n';
                +};
                +
                +/**
                + * Encode a string as a properly escaped Dart string, complete with quotes.
                + * @param {string} string Text to encode.
                + * @return {string} Dart string.
                + * @private
                + */
                +Blockly.Dart.quote_ = function(string) {
                +  // Can't use goog.string.quote since $ must also be escaped.
                +  string = string.replace(/\\/g, '\\\\')
                +                 .replace(/\n/g, '\\\n')
                +                 .replace(/\$/g, '\\$')
                +                 .replace(/'/g, '\\\'');
                +  return '\'' + string + '\'';
                +};
                +
                +/**
                + * Common tasks for generating Dart from blocks.
                + * Handles comments for the specified block and any connected value blocks.
                + * Calls any statements following this block.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The Dart code created for this block.
                + * @return {string} Dart code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.Dart.scrub_ = function(block, code) {
                +  var commentCode = '';
                +  // Only collect comments for blocks that aren't inline.
                +  if (!block.outputConnection || !block.outputConnection.targetConnection) {
                +    // Collect comment for this block.
                +    var comment = block.getCommentText();
                +    comment = Blockly.utils.wrap(comment, Blockly.Dart.COMMENT_WRAP - 3);
                +    if (comment) {
                +      if (block.getProcedureDef) {
                +        // Use documentation comment for function comments.
                +        commentCode += Blockly.Dart.prefixLines(comment + '\n', '/// ');
                +      } else {
                +        commentCode += Blockly.Dart.prefixLines(comment + '\n', '// ');
                +      }
                +    }
                +    // Collect comments for all value arguments.
                +    // Don't collect comments for nested statements.
                +    for (var i = 0; i < block.inputList.length; i++) {
                +      if (block.inputList[i].type == Blockly.INPUT_VALUE) {
                +        var childBlock = block.inputList[i].connection.targetBlock();
                +        if (childBlock) {
                +          var comment = Blockly.Dart.allNestedComments(childBlock);
                +          if (comment) {
                +            commentCode += Blockly.Dart.prefixLines(comment, '// ');
                +          }
                +        }
                +      }
                +    }
                +  }
                +  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
                +  var nextCode = Blockly.Dart.blockToCode(nextBlock);
                +  return commentCode + code + nextCode;
                +};
                +
                +/**
                + * Gets a property and adjusts the value while taking into account indexing.
                + * @param {!Blockly.Block} block The block.
                + * @param {string} atId The property ID of the element to get.
                + * @param {number=} opt_delta Value to add.
                + * @param {boolean=} opt_negate Whether to negate the value.
                + * @param {number=} opt_order The highest order acting on this value.
                + * @return {string|number}
                + */
                +Blockly.Dart.getAdjusted = function(block, atId, opt_delta, opt_negate,
                +    opt_order) {
                +  var delta = opt_delta || 0;
                +  var order = opt_order || Blockly.Dart.ORDER_NONE;
                +  if (block.workspace.options.oneBasedIndex) {
                +    delta--;
                +  }
                +  var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0';
                +  if (delta) {
                +    var at = Blockly.Dart.valueToCode(block, atId,
                +        Blockly.Dart.ORDER_ADDITIVE) || defaultAtIndex;
                +  } else if (opt_negate) {
                +    var at = Blockly.Dart.valueToCode(block, atId,
                +        Blockly.Dart.ORDER_UNARY_PREFIX) || defaultAtIndex;
                +  } else {
                +    var at = Blockly.Dart.valueToCode(block, atId, order) ||
                +        defaultAtIndex;
                +  }
                +
                +  if (Blockly.isNumber(at)) {
                +    // If the index is a naked number, adjust it right now.
                +    at = parseInt(at, 10) + delta;
                +    if (opt_negate) {
                +      at = -at;
                +    }
                +  } else {
                +    // If the index is dynamic, adjust it in code.
                +    if (delta > 0) {
                +      at = at + ' + ' + delta;
                +      var innerOrder = Blockly.Dart.ORDER_ADDITIVE;
                +    } else if (delta < 0) {
                +      at = at + ' - ' + -delta;
                +      var innerOrder = Blockly.Dart.ORDER_ADDITIVE;
                +    }
                +    if (opt_negate) {
                +      if (delta) {
                +        at = '-(' + at + ')';
                +      } else {
                +        at = '-' + at;
                +      }
                +      var innerOrder = Blockly.Dart.ORDER_UNARY_PREFIX;
                +    }
                +    innerOrder = Math.floor(innerOrder);
                +    order = Math.floor(order);
                +    if (innerOrder && order >= innerOrder) {
                +      at = '(' + at + ')';
                +    }
                +  }
                +  return at;
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/colour.js b/blockly/webif/static/blockly/generators/dart/colour.js
                new file mode 100644
                index 000000000..105608988
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/colour.js
                @@ -0,0 +1,128 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for colour blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.colour');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart.addReservedWords('Math');
                +
                +Blockly.Dart['colour_picker'] = function(block) {
                +  // Colour picker.
                +  var code = '\'' + block.getFieldValue('COLOUR') + '\'';
                +  return [code, Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['colour_random'] = function(block) {
                +  // Generate a random colour.
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'colour_random',
                +      ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +       '  String hex = \'0123456789abcdef\';',
                +       '  var rnd = new Math.Random();',
                +       '  return \'#${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\'',
                +       '      \'${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\'',
                +       '      \'${hex[rnd.nextInt(16)]}${hex[rnd.nextInt(16)]}\';',
                +       '}']);
                +  var code = functionName + '()';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['colour_rgb'] = function(block) {
                +  // Compose a colour from RGB components expressed as percentages.
                +  var red = Blockly.Dart.valueToCode(block, 'RED',
                +      Blockly.Dart.ORDER_NONE) || 0;
                +  var green = Blockly.Dart.valueToCode(block, 'GREEN',
                +      Blockly.Dart.ORDER_NONE) || 0;
                +  var blue = Blockly.Dart.valueToCode(block, 'BLUE',
                +      Blockly.Dart.ORDER_NONE) || 0;
                +
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'colour_rgb',
                +      ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(num r, num g, num b) {',
                +       '  num rn = (Math.max(Math.min(r, 100), 0) * 2.55).round();',
                +       '  String rs = rn.toInt().toRadixString(16);',
                +       '  rs = \'0$rs\';',
                +       '  rs = rs.substring(rs.length - 2);',
                +       '  num gn = (Math.max(Math.min(g, 100), 0) * 2.55).round();',
                +       '  String gs = gn.toInt().toRadixString(16);',
                +       '  gs = \'0$gs\';',
                +       '  gs = gs.substring(gs.length - 2);',
                +       '  num bn = (Math.max(Math.min(b, 100), 0) * 2.55).round();',
                +       '  String bs = bn.toInt().toRadixString(16);',
                +       '  bs = \'0$bs\';',
                +       '  bs = bs.substring(bs.length - 2);',
                +       '  return \'#$rs$gs$bs\';',
                +       '}']);
                +  var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['colour_blend'] = function(block) {
                +  // Blend two colours together.
                +  var c1 = Blockly.Dart.valueToCode(block, 'COLOUR1',
                +      Blockly.Dart.ORDER_NONE) || '\'#000000\'';
                +  var c2 = Blockly.Dart.valueToCode(block, 'COLOUR2',
                +      Blockly.Dart.ORDER_NONE) || '\'#000000\'';
                +  var ratio = Blockly.Dart.valueToCode(block, 'RATIO',
                +      Blockly.Dart.ORDER_NONE) || 0.5;
                +
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'colour_blend',
                +      ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(String c1, String c2, num ratio) {',
                +       '  ratio = Math.max(Math.min(ratio, 1), 0);',
                +       '  int r1 = int.parse(\'0x${c1.substring(1, 3)}\');',
                +       '  int g1 = int.parse(\'0x${c1.substring(3, 5)}\');',
                +       '  int b1 = int.parse(\'0x${c1.substring(5, 7)}\');',
                +       '  int r2 = int.parse(\'0x${c2.substring(1, 3)}\');',
                +       '  int g2 = int.parse(\'0x${c2.substring(3, 5)}\');',
                +       '  int b2 = int.parse(\'0x${c2.substring(5, 7)}\');',
                +       '  num rn = (r1 * (1 - ratio) + r2 * ratio).round();',
                +       '  String rs = rn.toInt().toRadixString(16);',
                +       '  num gn = (g1 * (1 - ratio) + g2 * ratio).round();',
                +       '  String gs = gn.toInt().toRadixString(16);',
                +       '  num bn = (b1 * (1 - ratio) + b2 * ratio).round();',
                +       '  String bs = bn.toInt().toRadixString(16);',
                +       '  rs = \'0$rs\';',
                +       '  rs = rs.substring(rs.length - 2);',
                +       '  gs = \'0$gs\';',
                +       '  gs = gs.substring(gs.length - 2);',
                +       '  bs = \'0$bs\';',
                +       '  bs = bs.substring(bs.length - 2);',
                +       '  return \'#$rs$gs$bs\';',
                +       '}']);
                +  var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/lists.js b/blockly/webif/static/blockly/generators/dart/lists.js
                new file mode 100644
                index 000000000..42552713c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/lists.js
                @@ -0,0 +1,461 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for list blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.lists');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart.addReservedWords('Math');
                +
                +Blockly.Dart['lists_create_empty'] = function(block) {
                +  // Create an empty list.
                +  return ['[]', Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['lists_create_with'] = function(block) {
                +  // Create a list with any number of elements of any type.
                +  var elements = new Array(block.itemCount_);
                +  for (var i = 0; i < block.itemCount_; i++) {
                +    elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i,
                +        Blockly.Dart.ORDER_NONE) || 'null';
                +  }
                +  var code = '[' + elements.join(', ') + ']';
                +  return [code, Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['lists_repeat'] = function(block) {
                +  // Create a list with one element repeated.
                +  var element = Blockly.Dart.valueToCode(block, 'ITEM',
                +      Blockly.Dart.ORDER_NONE) || 'null';
                +  var repeatCount = Blockly.Dart.valueToCode(block, 'NUM',
                +      Blockly.Dart.ORDER_NONE) || '0';
                +  var code = 'new List.filled(' + repeatCount + ', ' + element + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_length'] = function(block) {
                +  // String or array length.
                +  var list = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
                +  return [list + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var list = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
                +  return [list + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_indexOf'] = function(block) {
                +  // Find an item in the list.
                +  var operator = block.getFieldValue('END') == 'FIRST' ?
                +      'indexOf' : 'lastIndexOf';
                +  var item = Blockly.Dart.valueToCode(block, 'FIND',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  var list = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
                +  var code = list + '.' + operator + '(' + item + ')';
                +  if (block.workspace.options.oneBasedIndex) {
                +    return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE];
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_getIndex'] = function(block) {
                +  // Get element at index.
                +  // Note: Until January 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var listOrder = (where == 'RANDOM' || where == 'FROM_END') ?
                +      Blockly.Dart.ORDER_NONE : Blockly.Dart.ORDER_UNARY_POSTFIX;
                +  var list = Blockly.Dart.valueToCode(block, 'VALUE', listOrder) || '[]';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  // Closure, which accesses and modifies 'list'.
                +  function cacheList() {
                +    var listVar = Blockly.Dart.variableDB_.getDistinctName(
                +        'tmp_list', Blockly.Variables.NAME_TYPE);
                +    var code = 'List ' + listVar + ' = ' + list + ';\n';
                +    list = listVar;
                +    return code;
                +  }
                +  // If `list` would be evaluated more than once (which is the case for
                +  // RANDOM REMOVE and FROM_END) and is non-trivial, make sure to access it
                +  // only once.
                +  if (((where == 'RANDOM' && mode == 'REMOVE') || where == 'FROM_END') &&
                +      !list.match(/^\w+$/)) {
                +    // `list` is an expression, so we may not evaluate it more than once.
                +    if (where == 'RANDOM') {
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      // We can use multiple statements.
                +      var code = cacheList();
                +      var xVar = Blockly.Dart.variableDB_.getDistinctName(
                +          'tmp_x', Blockly.Variables.NAME_TYPE);
                +      code += 'int ' + xVar + ' = new Math.Random().nextInt(' + list +
                +          '.length);\n';
                +      code += list + '.removeAt(' + xVar + ');\n';
                +      return code;
                +    } else {  // where == 'FROM_END'
                +      if (mode == 'REMOVE') {
                +        // We can use multiple statements.
                +        var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        var code = cacheList();
                +        code += list + '.removeAt(' + list + '.length' + ' - ' + at + ');\n';
                +        return code;
                +
                +      } else if (mode == 'GET') {
                +        var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
                +        // We need to create a procedure to avoid reevaluating values.
                +        var functionName = Blockly.Dart.provideFunction_(
                +            'lists_get_from_end',
                +            ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(List my_list, num x) {',
                +              '  x = my_list.length - x;',
                +              '  return my_list[x];',
                +              '}']);
                +        var code = functionName + '(' + list + ', ' + at + ')';
                +        return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +      } else if (mode == 'GET_REMOVE') {
                +        var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
                +        // We need to create a procedure to avoid reevaluating values.
                +        var functionName = Blockly.Dart.provideFunction_(
                +            'lists_remove_from_end',
                +            ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(List my_list, num x) {',
                +              '  x = my_list.length - x;',
                +              '  return my_list.removeAt(x);',
                +              '}']);
                +        var code = functionName + '(' + list + ', ' + at + ')';
                +        return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +      }
                +    }
                +  } else {
                +    // Either `list` is a simple variable, or we only need to refer to `list`
                +    // once.
                +    switch (where) {
                +      case 'FIRST':
                +        if (mode == 'GET') {
                +          var code = list + '.first';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'GET_REMOVE') {
                +          var code = list + '.removeAt(0)';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'REMOVE') {
                +          return list + '.removeAt(0);\n';
                +        }
                +        break;
                +      case 'LAST':
                +        if (mode == 'GET') {
                +          var code = list + '.last';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'GET_REMOVE') {
                +          var code = list + '.removeLast()';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'REMOVE') {
                +          return list + '.removeLast();\n';
                +        }
                +        break;
                +      case 'FROM_START':
                +        var at = Blockly.Dart.getAdjusted(block, 'AT');
                +        if (mode == 'GET') {
                +          var code = list + '[' + at + ']';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'GET_REMOVE') {
                +          var code = list + '.removeAt(' + at + ')';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'REMOVE') {
                +          return list + '.removeAt(' + at + ');\n';
                +        }
                +        break;
                +      case 'FROM_END':
                +        var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        if (mode == 'GET') {
                +          var code = list + '[' + list + '.length - ' + at + ']';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
                +          var code = list + '.removeAt(' + list + '.length - ' + at + ')';
                +          if (mode == 'GET_REMOVE') {
                +            return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +          } else if (mode == 'REMOVE') {
                +            return code + ';\n';
                +          }
                +        }
                +        break;
                +      case 'RANDOM':
                +        Blockly.Dart.definitions_['import_dart_math'] =
                +            'import \'dart:math\' as Math;';
                +        if (mode == 'REMOVE') {
                +          // We can use multiple statements.
                +          var xVar = Blockly.Dart.variableDB_.getDistinctName(
                +              'tmp_x', Blockly.Variables.NAME_TYPE);
                +          var code = 'int ' + xVar + ' = new Math.Random().nextInt(' + list +
                +              '.length);\n';
                +          code += list + '.removeAt(' + xVar + ');\n';
                +          return code;
                +        } else if (mode == 'GET') {
                +          var functionName = Blockly.Dart.provideFunction_(
                +              'lists_get_random_item',
                +              ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List my_list) {',
                +                '  int x = new Math.Random().nextInt(my_list.length);',
                +                '  return my_list[x];',
                +                '}']);
                +          var code = functionName + '(' + list + ')';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        } else if (mode == 'GET_REMOVE') {
                +          var functionName = Blockly.Dart.provideFunction_(
                +              'lists_remove_random_item',
                +              ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List my_list) {',
                +                '  int x = new Math.Random().nextInt(my_list.length);',
                +                '  return my_list.removeAt(x);',
                +                '}']);
                +          var code = functionName + '(' + list + ')';
                +          return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +        }
                +        break;
                +    }
                +  }
                +  throw 'Unhandled combination (lists_getIndex).';
                +};
                +
                +Blockly.Dart['lists_setIndex'] = function(block) {
                +  // Set element at index.
                +  // Note: Until February 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var list = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
                +  var value = Blockly.Dart.valueToCode(block, 'TO',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || 'null';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  // Closure, which accesses and modifies 'list'.
                +  function cacheList() {
                +    if (list.match(/^\w+$/)) {
                +      return '';
                +    }
                +    var listVar = Blockly.Dart.variableDB_.getDistinctName(
                +        'tmp_list', Blockly.Variables.NAME_TYPE);
                +    var code = 'List ' + listVar + ' = ' + list + ';\n';
                +    list = listVar;
                +    return code;
                +  }
                +  switch (where) {
                +    case 'FIRST':
                +      if (mode == 'SET') {
                +        return list + '[0] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        return list + '.insert(0, ' + value + ');\n';
                +      }
                +      break;
                +    case 'LAST':
                +      if (mode == 'SET') {
                +        var code = cacheList();
                +        code += list + '[' + list + '.length - 1] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        return list + '.add(' + value + ');\n';
                +      }
                +      break;
                +    case 'FROM_START':
                +      var at = Blockly.Dart.getAdjusted(block, 'AT');
                +      if (mode == 'SET') {
                +        return list + '[' + at + '] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        return list + '.insert(' + at + ', ' + value + ');\n';
                +      }
                +      break;
                +    case 'FROM_END':
                +      var at = Blockly.Dart.getAdjusted(block, 'AT', 1, false,
                +          Blockly.Dart.ORDER_ADDITIVE);
                +      var code = cacheList();
                +      if (mode == 'SET') {
                +        code += list + '[' + list + '.length - ' + at + '] = ' + value +
                +            ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        code += list + '.insert(' + list + '.length - ' + at + ', ' +
                +            value + ');\n';
                +        return code;
                +      }
                +      break;
                +    case 'RANDOM':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var code = cacheList();
                +      var xVar = Blockly.Dart.variableDB_.getDistinctName(
                +          'tmp_x', Blockly.Variables.NAME_TYPE);
                +      code += 'int ' + xVar +
                +          ' = new Math.Random().nextInt(' + list + '.length);\n';
                +      if (mode == 'SET') {
                +        code += list + '[' + xVar + '] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        code += list + '.insert(' + xVar + ', ' + value + ');\n';
                +        return code;
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_setIndex).';
                +};
                +
                +Blockly.Dart['lists_getSublist'] = function(block) {
                +  // Get sublist.
                +  var list = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '[]';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (list.match(/^\w+$/) || (where1 != 'FROM_END' && where2 == 'FROM_START')) {
                +    // If the list is a is a variable or doesn't require a call for length,
                +    // don't generate a helper function.
                +    switch (where1) {
                +      case 'FROM_START':
                +        var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
                +        break;
                +      case 'FROM_END':
                +        var at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        at1 = list + '.length - ' + at1;
                +        break;
                +      case 'FIRST':
                +        var at1 = '0';
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    switch (where2) {
                +      case 'FROM_START':
                +        var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1);
                +        break;
                +      case 'FROM_END':
                +        var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        at2 = list + '.length - ' + at2;
                +        break;
                +      case 'LAST':
                +        // There is no second index if LAST option is chosen.
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    if (where2 == 'LAST') {
                +      var code = list + '.sublist(' + at1 + ')';
                +    } else {
                +      var code = list + '.sublist(' + at1 + ', ' + at2 + ')';
                +    }
                +  } else {
                +    var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.Dart.getAdjusted(block, 'AT2');
                +    var functionName = Blockly.Dart.provideFunction_(
                +        'lists_get_sublist',
                +        ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(list, where1, at1, where2, at2) {',
                +         '  int getAt(where, at) {',
                +         '    if (where == \'FROM_END\') {',
                +         '      at = list.length - 1 - at;',
                +         '    } else if (where == \'FIRST\') {',
                +         '      at = 0;',
                +         '    } else if (where == \'LAST\') {',
                +         '      at = list.length - 1;',
                +         '    } else if (where != \'FROM_START\') {',
                +         '      throw \'Unhandled option (lists_getSublist).\';',
                +         '    }',
                +         '    return at;',
                +         '  }',
                +         '  at1 = getAt(where1, at1);',
                +         '  at2 = getAt(where2, at2) + 1;',
                +         '  return list.sublist(at1, at2);',
                +         '}']);
                +    var code = functionName + '(' + list + ', \'' +
                +        where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_sort'] = function(block) {
                +  // Block for sorting a list.
                +  var list = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_NONE) || '[]';
                +  var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
                +  var type = block.getFieldValue('TYPE');
                +  var sortFunctionName = Blockly.Dart.provideFunction_(
                +      'lists_sort',
                +      ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(list, type, direction) {',
                +       '  var compareFuncs = {',
                +       '    "NUMERIC": (a, b) => direction * a.compareTo(b),',
                +       '    "TEXT": (a, b) => direction * ' +
                +          'a.toString().compareTo(b.toString()),',
                +       '    "IGNORE_CASE": ',
                +       '       (a, b) => direction * ',
                +       '      a.toString().toLowerCase().compareTo(b.toString().toLowerCase())',
                +       '  };',
                +       '  list = new List.from(list);', // Clone the list.
                +       '  var compare = compareFuncs[type];',
                +       '  list.sort(compare);',
                +       '  return list;',
                +       '}']);
                +  return [sortFunctionName + '(' + list + ', ' +
                +      '"' + type + '", ' + direction + ')',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_split'] = function(block) {
                +  // Block for splitting text into a list, or joining a list into text.
                +  var input = Blockly.Dart.valueToCode(block, 'INPUT',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX);
                +  var delimiter = Blockly.Dart.valueToCode(block, 'DELIM',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  var mode = block.getFieldValue('MODE');
                +  if (mode == 'SPLIT') {
                +    if (!input) {
                +      input = '\'\'';
                +    }
                +    var functionName = 'split';
                +  } else if (mode == 'JOIN') {
                +    if (!input) {
                +      input = '[]';
                +    }
                +    var functionName = 'join';
                +  } else {
                +    throw 'Unknown mode: ' + mode;
                +  }
                +  var code = input + '.' + functionName + '(' + delimiter + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['lists_reverse'] = function(block) {
                +  // Block for reversing a list.
                +  var list = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_NONE) || '[]';
                +  // XXX What should the operator precedence be for a `new`?
                +  var code = 'new List.from(' + list + '.reversed)';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/logic.js b/blockly/webif/static/blockly/generators/dart/logic.js
                new file mode 100644
                index 000000000..620b55da8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/logic.js
                @@ -0,0 +1,128 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for logic blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.logic');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart['controls_if'] = function(block) {
                +  // If/elseif/else condition.
                +  var n = 0;
                +  var code = '', branchCode, conditionCode;
                +  do {
                +    conditionCode = Blockly.Dart.valueToCode(block, 'IF' + n,
                +      Blockly.Dart.ORDER_NONE) || 'false';
                +    branchCode = Blockly.Dart.statementToCode(block, 'DO' + n);
                +    code += (n > 0 ? 'else ' : '') +
                +        'if (' + conditionCode + ') {\n' + branchCode + '}';
                +
                +    ++n;
                +  } while (block.getInput('IF' + n));
                +
                +  if (block.getInput('ELSE')) {
                +    branchCode = Blockly.Dart.statementToCode(block, 'ELSE');
                +    code += ' else {\n' + branchCode + '}';
                +  }
                +  return code + '\n';
                +};
                +
                +Blockly.Dart['controls_ifelse'] = Blockly.Dart['controls_if'];
                +
                +Blockly.Dart['logic_compare'] = function(block) {
                +  // Comparison operator.
                +  var OPERATORS = {
                +    'EQ': '==',
                +    'NEQ': '!=',
                +    'LT': '<',
                +    'LTE': '<=',
                +    'GT': '>',
                +    'GTE': '>='
                +  };
                +  var operator = OPERATORS[block.getFieldValue('OP')];
                +  var order = (operator == '==' || operator == '!=') ?
                +      Blockly.Dart.ORDER_EQUALITY : Blockly.Dart.ORDER_RELATIONAL;
                +  var argument0 = Blockly.Dart.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Dart['logic_operation'] = function(block) {
                +  // Operations 'and', 'or'.
                +  var operator = (block.getFieldValue('OP') == 'AND') ? '&&' : '||';
                +  var order = (operator == '&&') ? Blockly.Dart.ORDER_LOGICAL_AND :
                +      Blockly.Dart.ORDER_LOGICAL_OR;
                +  var argument0 = Blockly.Dart.valueToCode(block, 'A', order);
                +  var argument1 = Blockly.Dart.valueToCode(block, 'B', order);
                +  if (!argument0 && !argument1) {
                +    // If there are no arguments, then the return value is false.
                +    argument0 = 'false';
                +    argument1 = 'false';
                +  } else {
                +    // Single missing arguments have no effect on the return value.
                +    var defaultArgument = (operator == '&&') ? 'true' : 'false';
                +    if (!argument0) {
                +      argument0 = defaultArgument;
                +    }
                +    if (!argument1) {
                +      argument1 = defaultArgument;
                +    }
                +  }
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Dart['logic_negate'] = function(block) {
                +  // Negation.
                +  var order = Blockly.Dart.ORDER_UNARY_PREFIX;
                +  var argument0 = Blockly.Dart.valueToCode(block, 'BOOL', order) || 'true';
                +  var code = '!' + argument0;
                +  return [code, order];
                +};
                +
                +Blockly.Dart['logic_boolean'] = function(block) {
                +  // Boolean values true and false.
                +  var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false';
                +  return [code, Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['logic_null'] = function(block) {
                +  // Null data type.
                +  return ['null', Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['logic_ternary'] = function(block) {
                +  // Ternary operator.
                +  var value_if = Blockly.Dart.valueToCode(block, 'IF',
                +      Blockly.Dart.ORDER_CONDITIONAL) || 'false';
                +  var value_then = Blockly.Dart.valueToCode(block, 'THEN',
                +      Blockly.Dart.ORDER_CONDITIONAL) || 'null';
                +  var value_else = Blockly.Dart.valueToCode(block, 'ELSE',
                +      Blockly.Dart.ORDER_CONDITIONAL) || 'null';
                +  var code = value_if + ' ? ' + value_then + ' : ' + value_else;
                +  return [code, Blockly.Dart.ORDER_CONDITIONAL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/loops.js b/blockly/webif/static/blockly/generators/dart/loops.js
                new file mode 100644
                index 000000000..0dd7c0ce5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/loops.js
                @@ -0,0 +1,163 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for loop blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.loops');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart['controls_repeat_ext'] = function(block) {
                +  // Repeat n times.
                +  if (block.getField('TIMES')) {
                +    // Internal number.
                +    var repeats = String(Number(block.getFieldValue('TIMES')));
                +  } else {
                +    // External number.
                +    var repeats = Blockly.Dart.valueToCode(block, 'TIMES',
                +        Blockly.Dart.ORDER_ASSIGNMENT) || '0';
                +  }
                +  var branch = Blockly.Dart.statementToCode(block, 'DO');
                +  branch = Blockly.Dart.addLoopTrap(branch, block.id);
                +  var code = '';
                +  var loopVar = Blockly.Dart.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var endVar = repeats;
                +  if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
                +    var endVar = Blockly.Dart.variableDB_.getDistinctName(
                +        'repeat_end', Blockly.Variables.NAME_TYPE);
                +    code += 'var ' + endVar + ' = ' + repeats + ';\n';
                +  }
                +  code += 'for (int ' + loopVar + ' = 0; ' +
                +      loopVar + ' < ' + endVar + '; ' +
                +      loopVar + '++) {\n' +
                +      branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.Dart['controls_repeat'] = Blockly.Dart['controls_repeat_ext'];
                +
                +Blockly.Dart['controls_whileUntil'] = function(block) {
                +  // Do while/until loop.
                +  var until = block.getFieldValue('MODE') == 'UNTIL';
                +  var argument0 = Blockly.Dart.valueToCode(block, 'BOOL',
                +      until ? Blockly.Dart.ORDER_UNARY_PREFIX :
                +      Blockly.Dart.ORDER_NONE) || 'false';
                +  var branch = Blockly.Dart.statementToCode(block, 'DO');
                +  branch = Blockly.Dart.addLoopTrap(branch, block.id);
                +  if (until) {
                +    argument0 = '!' + argument0;
                +  }
                +  return 'while (' + argument0 + ') {\n' + branch + '}\n';
                +};
                +
                +Blockly.Dart['controls_for'] = function(block) {
                +  // For loop.
                +  var variable0 = Blockly.Dart.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.Dart.valueToCode(block, 'FROM',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'TO',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || '0';
                +  var increment = Blockly.Dart.valueToCode(block, 'BY',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || '1';
                +  var branch = Blockly.Dart.statementToCode(block, 'DO');
                +  branch = Blockly.Dart.addLoopTrap(branch, block.id);
                +  var code;
                +  if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) &&
                +      Blockly.isNumber(increment)) {
                +    // All arguments are simple numbers.
                +    var up = parseFloat(argument0) <= parseFloat(argument1);
                +    code = 'for (' + variable0 + ' = ' + argument0 + '; ' +
                +        variable0 + (up ? ' <= ' : ' >= ') + argument1 + '; ' +
                +        variable0;
                +    var step = Math.abs(parseFloat(increment));
                +    if (step == 1) {
                +      code += up ? '++' : '--';
                +    } else {
                +      code += (up ? ' += ' : ' -= ') + step;
                +    }
                +    code += ') {\n' + branch + '}\n';
                +  } else {
                +    code = '';
                +    // Cache non-trivial values to variables to prevent repeated look-ups.
                +    var startVar = argument0;
                +    if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) {
                +      var startVar = Blockly.Dart.variableDB_.getDistinctName(
                +          variable0 + '_start', Blockly.Variables.NAME_TYPE);
                +      code += 'var ' + startVar + ' = ' + argument0 + ';\n';
                +    }
                +    var endVar = argument1;
                +    if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) {
                +      var endVar = Blockly.Dart.variableDB_.getDistinctName(
                +          variable0 + '_end', Blockly.Variables.NAME_TYPE);
                +      code += 'var ' + endVar + ' = ' + argument1 + ';\n';
                +    }
                +    // Determine loop direction at start, in case one of the bounds
                +    // changes during loop execution.
                +    var incVar = Blockly.Dart.variableDB_.getDistinctName(
                +        variable0 + '_inc', Blockly.Variables.NAME_TYPE);
                +    code += 'num ' + incVar + ' = ';
                +    if (Blockly.isNumber(increment)) {
                +      code += Math.abs(increment) + ';\n';
                +    } else {
                +      code += '(' + increment + ').abs();\n';
                +    }
                +    code += 'if (' + startVar + ' > ' + endVar + ') {\n';
                +    code += Blockly.Dart.INDENT + incVar + ' = -' + incVar + ';\n';
                +    code += '}\n';
                +    code += 'for (' + variable0 + ' = ' + startVar + '; ' +
                +        incVar + ' >= 0 ? ' +
                +        variable0 + ' <= ' + endVar + ' : ' +
                +        variable0 + ' >= ' + endVar + '; ' +
                +        variable0 + ' += ' + incVar + ') {\n' +
                +        branch + '}\n';
                +  }
                +  return code;
                +};
                +
                +Blockly.Dart['controls_forEach'] = function(block) {
                +  // For each loop.
                +  var variable0 = Blockly.Dart.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || '[]';
                +  var branch = Blockly.Dart.statementToCode(block, 'DO');
                +  branch = Blockly.Dart.addLoopTrap(branch, block.id);
                +  var code = 'for (var ' + variable0 + ' in ' + argument0 + ') {\n' +
                +      branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.Dart['controls_flow_statements'] = function(block) {
                +  // Flow statements: continue, break.
                +  switch (block.getFieldValue('FLOW')) {
                +    case 'BREAK':
                +      return 'break;\n';
                +    case 'CONTINUE':
                +      return 'continue;\n';
                +  }
                +  throw 'Unknown flow statement.';
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/math.js b/blockly/webif/static/blockly/generators/dart/math.js
                new file mode 100644
                index 000000000..867822beb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/math.js
                @@ -0,0 +1,487 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for math blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.math');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart.addReservedWords('Math');
                +
                +Blockly.Dart['math_number'] = function(block) {
                +  // Numeric value.
                +  var code = parseFloat(block.getFieldValue('NUM'));
                +  var order;
                +  if (code == Infinity) {
                +    code = 'double.INFINITY';
                +    order = Blockly.Dart.ORDER_UNARY_POSTFIX;
                +  } else if (code == -Infinity) {
                +    code = '-double.INFINITY';
                +    order = Blockly.Dart.ORDER_UNARY_PREFIX;
                +  } else {
                +    // -4.abs() returns -4 in Dart due to strange order of operation choices.
                +    // -4 is actually an operator and a number.  Reflect this in the order.
                +    order = code < 0 ?
                +        Blockly.Dart.ORDER_UNARY_PREFIX : Blockly.Dart.ORDER_ATOMIC;
                +  }
                +  return [code, order];
                +};
                +
                +Blockly.Dart['math_arithmetic'] = function(block) {
                +  // Basic arithmetic operators, and power.
                +  var OPERATORS = {
                +    'ADD': [' + ', Blockly.Dart.ORDER_ADDITIVE],
                +    'MINUS': [' - ', Blockly.Dart.ORDER_ADDITIVE],
                +    'MULTIPLY': [' * ', Blockly.Dart.ORDER_MULTIPLICATIVE],
                +    'DIVIDE': [' / ', Blockly.Dart.ORDER_MULTIPLICATIVE],
                +    'POWER': [null, Blockly.Dart.ORDER_NONE]  // Handle power separately.
                +  };
                +  var tuple = OPERATORS[block.getFieldValue('OP')];
                +  var operator = tuple[0];
                +  var order = tuple[1];
                +  var argument0 = Blockly.Dart.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'B', order) || '0';
                +  var code;
                +  // Power in Dart requires a special case since it has no operator.
                +  if (!operator) {
                +    Blockly.Dart.definitions_['import_dart_math'] =
                +        'import \'dart:math\' as Math;';
                +    code = 'Math.pow(' + argument0 + ', ' + argument1 + ')';
                +    return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +  }
                +  code = argument0 + operator + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Dart['math_single'] = function(block) {
                +  // Math operators with single operand.
                +  var operator = block.getFieldValue('OP');
                +  var code;
                +  var arg;
                +  if (operator == 'NEG') {
                +    // Negation is a special case given its different operator precedence.
                +    arg = Blockly.Dart.valueToCode(block, 'NUM',
                +        Blockly.Dart.ORDER_UNARY_PREFIX) || '0';
                +    if (arg[0] == '-') {
                +      // --3 is not legal in Dart.
                +      arg = ' ' + arg;
                +    }
                +    code = '-' + arg;
                +    return [code, Blockly.Dart.ORDER_UNARY_PREFIX];
                +  }
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  if (operator == 'ABS' || operator.substring(0, 5) == 'ROUND') {
                +    arg = Blockly.Dart.valueToCode(block, 'NUM',
                +        Blockly.Dart.ORDER_UNARY_POSTFIX) || '0';
                +  } else if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
                +    arg = Blockly.Dart.valueToCode(block, 'NUM',
                +        Blockly.Dart.ORDER_MULTIPLICATIVE) || '0';
                +  } else {
                +    arg = Blockly.Dart.valueToCode(block, 'NUM',
                +        Blockly.Dart.ORDER_NONE) || '0';
                +  }
                +  // First, handle cases which generate values that don't need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'ABS':
                +      code = arg + '.abs()';
                +      break;
                +    case 'ROOT':
                +      code = 'Math.sqrt(' + arg + ')';
                +      break;
                +    case 'LN':
                +      code = 'Math.log(' + arg + ')';
                +      break;
                +    case 'EXP':
                +      code = 'Math.exp(' + arg + ')';
                +      break;
                +    case 'POW10':
                +      code = 'Math.pow(10,' + arg + ')';
                +      break;
                +    case 'ROUND':
                +      code = arg + '.round()';
                +      break;
                +    case 'ROUNDUP':
                +      code = arg + '.ceil()';
                +      break;
                +    case 'ROUNDDOWN':
                +      code = arg + '.floor()';
                +      break;
                +    case 'SIN':
                +      code = 'Math.sin(' + arg + ' / 180 * Math.PI)';
                +      break;
                +    case 'COS':
                +      code = 'Math.cos(' + arg + ' / 180 * Math.PI)';
                +      break;
                +    case 'TAN':
                +      code = 'Math.tan(' + arg + ' / 180 * Math.PI)';
                +      break;
                +  }
                +  if (code) {
                +    return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +  }
                +  // Second, handle cases which generate values that may need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'LOG10':
                +      code = 'Math.log(' + arg + ') / Math.log(10)';
                +      break;
                +    case 'ASIN':
                +      code = 'Math.asin(' + arg + ') / Math.PI * 180';
                +      break;
                +    case 'ACOS':
                +      code = 'Math.acos(' + arg + ') / Math.PI * 180';
                +      break;
                +    case 'ATAN':
                +      code = 'Math.atan(' + arg + ') / Math.PI * 180';
                +      break;
                +    default:
                +      throw 'Unknown math operator: ' + operator;
                +  }
                +  return [code, Blockly.Dart.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Dart['math_constant'] = function(block) {
                +  // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  var CONSTANTS = {
                +    'PI': ['Math.PI', Blockly.Dart.ORDER_UNARY_POSTFIX],
                +    'E': ['Math.E', Blockly.Dart.ORDER_UNARY_POSTFIX],
                +    'GOLDEN_RATIO':
                +        ['(1 + Math.sqrt(5)) / 2', Blockly.Dart.ORDER_MULTIPLICATIVE],
                +    'SQRT2': ['Math.SQRT2', Blockly.Dart.ORDER_UNARY_POSTFIX],
                +    'SQRT1_2': ['Math.SQRT1_2', Blockly.Dart.ORDER_UNARY_POSTFIX],
                +    'INFINITY': ['double.INFINITY', Blockly.Dart.ORDER_ATOMIC]
                +  };
                +  var constant = block.getFieldValue('CONSTANT');
                +  if (constant != 'INFINITY') {
                +    Blockly.Dart.definitions_['import_dart_math'] =
                +        'import \'dart:math\' as Math;';
                +  }
                +  return CONSTANTS[constant];
                +};
                +
                +Blockly.Dart['math_number_property'] = function(block) {
                +  // Check if a number is even, odd, prime, whole, positive, or negative
                +  // or if it is divisible by certain number. Returns true or false.
                +  var number_to_check = Blockly.Dart.valueToCode(block, 'NUMBER_TO_CHECK',
                +      Blockly.Dart.ORDER_MULTIPLICATIVE);
                +  if (!number_to_check) {
                +    return ['false', Blockly.Python.ORDER_ATOMIC];
                +  }
                +  var dropdown_property = block.getFieldValue('PROPERTY');
                +  var code;
                +  if (dropdown_property == 'PRIME') {
                +    // Prime is a special case as it is not a one-liner test.
                +    Blockly.Dart.definitions_['import_dart_math'] =
                +        'import \'dart:math\' as Math;';
                +    var functionName = Blockly.Dart.provideFunction_(
                +        'math_isPrime',
                +        ['bool ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
                +         '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
                +         '  if (n == 2 || n == 3) {',
                +         '    return true;',
                +         '  }',
                +         '  // False if n is null, negative, is 1, or not whole.',
                +         '  // And false if n is divisible by 2 or 3.',
                +         '  if (n == null || n <= 1 || n % 1 != 0 || n % 2 == 0 ||' +
                +            ' n % 3 == 0) {',
                +         '    return false;',
                +         '  }',
                +         '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
                +         '  for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {',
                +         '    if (n % (x - 1) == 0 || n % (x + 1) == 0) {',
                +         '      return false;',
                +         '    }',
                +         '  }',
                +         '  return true;',
                +         '}']);
                +    code = functionName + '(' + number_to_check + ')';
                +    return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +  }
                +  switch (dropdown_property) {
                +    case 'EVEN':
                +      code = number_to_check + ' % 2 == 0';
                +      break;
                +    case 'ODD':
                +      code = number_to_check + ' % 2 == 1';
                +      break;
                +    case 'WHOLE':
                +      code = number_to_check + ' % 1 == 0';
                +      break;
                +    case 'POSITIVE':
                +      code = number_to_check + ' > 0';
                +      break;
                +    case 'NEGATIVE':
                +      code = number_to_check + ' < 0';
                +      break;
                +    case 'DIVISIBLE_BY':
                +      var divisor = Blockly.Dart.valueToCode(block, 'DIVISOR',
                +          Blockly.Dart.ORDER_MULTIPLICATIVE);
                +      if (!divisor) {
                +        return ['false', Blockly.Python.ORDER_ATOMIC];
                +      }
                +      code = number_to_check + ' % ' + divisor + ' == 0';
                +      break;
                +  }
                +  return [code, Blockly.Dart.ORDER_EQUALITY];
                +};
                +
                +Blockly.Dart['math_change'] = function(block) {
                +  // Add to a variable in place.
                +  var argument0 = Blockly.Dart.valueToCode(block, 'DELTA',
                +      Blockly.Dart.ORDER_ADDITIVE) || '0';
                +  var varName = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return varName + ' = (' + varName + ' is num ? ' + varName + ' : 0) + ' +
                +      argument0 + ';\n';
                +};
                +
                +// Rounding functions have a single operand.
                +Blockly.Dart['math_round'] = Blockly.Dart['math_single'];
                +// Trigonometry functions have a single operand.
                +Blockly.Dart['math_trig'] = Blockly.Dart['math_single'];
                +
                +Blockly.Dart['math_on_list'] = function(block) {
                +  // Math functions for lists.
                +  var func = block.getFieldValue('OP');
                +  var list = Blockly.Dart.valueToCode(block, 'LIST',
                +      Blockly.Dart.ORDER_NONE) || '[]';
                +  var code;
                +  switch (func) {
                +    case 'SUM':
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_sum',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  num sumVal = 0;',
                +           '  myList.forEach((num entry) {sumVal += entry;});',
                +           '  return sumVal;',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MIN':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_min',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  if (myList.isEmpty) return null;',
                +           '  num minVal = myList[0];',
                +           '  myList.forEach((num entry) ' +
                +              '{minVal = Math.min(minVal, entry);});',
                +           '  return minVal;',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MAX':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_max',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  if (myList.isEmpty) return null;',
                +           '  num maxVal = myList[0];',
                +           '  myList.forEach((num entry) ' +
                +              '{maxVal = Math.max(maxVal, entry);});',
                +           '  return maxVal;',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'AVERAGE':
                +      // This operation exclude null and values that are not int or float:
                +      //   math_mean([null,null,"aString",1,9]) == 5.0.
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_mean',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  // First filter list for numbers only.',
                +           '  List localList = new List.from(myList);',
                +           '  localList.removeWhere((a) => a is! num);',
                +           '  if (localList.isEmpty) return null;',
                +           '  num sumVal = 0;',
                +           '  localList.forEach((num entry) {sumVal += entry;});',
                +           '  return sumVal / localList.length;',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MEDIAN':
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_median',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  // First filter list for numbers only, then sort, ' +
                +              'then return middle value',
                +           '  // or the average of two middle values if list has an ' +
                +              'even number of elements.',
                +           '  List localList = new List.from(myList);',
                +           '  localList.removeWhere((a) => a is! num);',
                +           '  if (localList.isEmpty) return null;',
                +           '  localList.sort((a, b) => (a - b));',
                +           '  int index = localList.length ~/ 2;',
                +           '  if (localList.length % 2 == 1) {',
                +           '    return localList[index];',
                +           '  } else {',
                +           '    return (localList[index - 1] + localList[index]) / 2;',
                +           '  }',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MODE':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      // As a list of numbers can contain more than one mode,
                +      // the returned result is provided as an array.
                +      // Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_modes',
                +          ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List values) {',
                +           '  List modes = [];',
                +           '  List counts = [];',
                +           '  int maxCount = 0;',
                +           '  for (int i = 0; i < values.length; i++) {',
                +           '    var value = values[i];',
                +           '    bool found = false;',
                +           '    int thisCount;',
                +           '    for (int j = 0; j < counts.length; j++) {',
                +           '      if (counts[j][0] == value) {',
                +           '        thisCount = ++counts[j][1];',
                +           '        found = true;',
                +           '        break;',
                +           '      }',
                +           '    }',
                +           '    if (!found) {',
                +           '      counts.add([value, 1]);',
                +           '      thisCount = 1;',
                +           '    }',
                +           '    maxCount = Math.max(thisCount, maxCount);',
                +           '  }',
                +           '  for (int j = 0; j < counts.length; j++) {',
                +           '    if (counts[j][1] == maxCount) {',
                +           '        modes.add(counts[j][0]);',
                +           '    }',
                +           '  }',
                +           '  return modes;',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'STD_DEV':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_standard_deviation',
                +          ['num ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  // First filter list for numbers only.',
                +           '  List numbers = new List.from(myList);',
                +           '  numbers.removeWhere((a) => a is! num);',
                +           '  if (numbers.isEmpty) return null;',
                +           '  num n = numbers.length;',
                +           '  num sum = 0;',
                +           '  numbers.forEach((x) => sum += x);',
                +           '  num mean = sum / n;',
                +           '  num sumSquare = 0;',
                +           '  numbers.forEach((x) => sumSquare += ' +
                +              'Math.pow(x - mean, 2));',
                +           '  return Math.sqrt(sumSquare / n);',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'RANDOM':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'math_random_item',
                +          ['dynamic ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(List myList) {',
                +           '  int x = new Math.Random().nextInt(myList.length);',
                +           '  return myList[x];',
                +           '}']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    default:
                +      throw 'Unknown operator: ' + func;
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['math_modulo'] = function(block) {
                +  // Remainder computation.
                +  var argument0 = Blockly.Dart.valueToCode(block, 'DIVIDEND',
                +      Blockly.Dart.ORDER_MULTIPLICATIVE) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'DIVISOR',
                +      Blockly.Dart.ORDER_MULTIPLICATIVE) || '0';
                +  var code = argument0 + ' % ' + argument1;
                +  return [code, Blockly.Dart.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Dart['math_constrain'] = function(block) {
                +  // Constrain a number between two limits.
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'LOW',
                +      Blockly.Dart.ORDER_NONE) || '0';
                +  var argument2 = Blockly.Dart.valueToCode(block, 'HIGH',
                +      Blockly.Dart.ORDER_NONE) || 'double.INFINITY';
                +  var code = 'Math.min(Math.max(' + argument0 + ', ' + argument1 + '), ' +
                +      argument2 + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['math_random_int'] = function(block) {
                +  // Random integer between [X] and [Y].
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  var argument0 = Blockly.Dart.valueToCode(block, 'FROM',
                +      Blockly.Dart.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Dart.valueToCode(block, 'TO',
                +      Blockly.Dart.ORDER_NONE) || '0';
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'math_random_int',
                +      ['int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {',
                +       '  if (a > b) {',
                +       '    // Swap a and b to ensure a is smaller.',
                +       '    num c = a;',
                +       '    a = b;',
                +       '    b = c;',
                +       '  }',
                +       '  return new Math.Random().nextInt(b - a + 1) + a;',
                +       '}']);
                +  var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['math_random_float'] = function(block) {
                +  // Random fraction between 0 and 1.
                +  Blockly.Dart.definitions_['import_dart_math'] =
                +      'import \'dart:math\' as Math;';
                +  return ['new Math.Random().nextDouble()', Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/procedures.js b/blockly/webif/static/blockly/generators/dart/procedures.js
                new file mode 100644
                index 000000000..ad2550cc7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/procedures.js
                @@ -0,0 +1,109 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for procedure blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.procedures');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart['procedures_defreturn'] = function(block) {
                +  // Define a procedure with a return value.
                +  var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var branch = Blockly.Dart.statementToCode(block, 'STACK');
                +  if (Blockly.Dart.STATEMENT_PREFIX) {
                +    branch = Blockly.Dart.prefixLines(
                +        Blockly.Dart.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + block.id + '\''), Blockly.Dart.INDENT) + branch;
                +  }
                +  if (Blockly.Dart.INFINITE_LOOP_TRAP) {
                +    branch = Blockly.Dart.INFINITE_LOOP_TRAP.replace(/%1/g,
                +        '\'' + block.id + '\'') + branch;
                +  }
                +  var returnValue = Blockly.Dart.valueToCode(block, 'RETURN',
                +      Blockly.Dart.ORDER_NONE) || '';
                +  if (returnValue) {
                +    returnValue = '  return ' + returnValue + ';\n';
                +  }
                +  var returnType = returnValue ? 'dynamic' : 'void';
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Dart.variableDB_.getName(block.arguments_[i],
                +        Blockly.Variables.NAME_TYPE);
                +  }
                +  var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
                +      branch + returnValue + '}';
                +  code = Blockly.Dart.scrub_(block, code);
                +  // Add % so as not to collide with helper functions in definitions list.
                +  Blockly.Dart.definitions_['%' + funcName] = code;
                +  return null;
                +};
                +
                +// Defining a procedure without a return value uses the same generator as
                +// a procedure with a return value.
                +Blockly.Dart['procedures_defnoreturn'] = Blockly.Dart['procedures_defreturn'];
                +
                +Blockly.Dart['procedures_callreturn'] = function(block) {
                +  // Call a procedure with a return value.
                +  var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Dart.valueToCode(block, 'ARG' + i,
                +        Blockly.Dart.ORDER_NONE) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['procedures_callnoreturn'] = function(block) {
                +  // Call a procedure with no return value.
                +  var funcName = Blockly.Dart.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Dart.valueToCode(block, 'ARG' + i,
                +        Blockly.Dart.ORDER_NONE) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ');\n';
                +  return code;
                +};
                +
                +Blockly.Dart['procedures_ifreturn'] = function(block) {
                +  // Conditionally return value from a procedure.
                +  var condition = Blockly.Dart.valueToCode(block, 'CONDITION',
                +      Blockly.Dart.ORDER_NONE) || 'false';
                +  var code = 'if (' + condition + ') {\n';
                +  if (block.hasReturnValue_) {
                +    var value = Blockly.Dart.valueToCode(block, 'VALUE',
                +        Blockly.Dart.ORDER_NONE) || 'null';
                +    code += '  return ' + value + ';\n';
                +  } else {
                +    code += '  return;\n';
                +  }
                +  code += '}\n';
                +  return code;
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/text.js b/blockly/webif/static/blockly/generators/dart/text.js
                new file mode 100644
                index 000000000..94c60f74b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/text.js
                @@ -0,0 +1,347 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for text blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.texts');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart.addReservedWords('Html,Math');
                +
                +Blockly.Dart['text'] = function(block) {
                +  // Text value.
                +  var code = Blockly.Dart.quote_(block.getFieldValue('TEXT'));
                +  return [code, Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['text_join'] = function(block) {
                +  // Create a string made up of any number of elements of any type.
                +  switch (block.itemCount_) {
                +    case 0:
                +      return ['\'\'', Blockly.Dart.ORDER_ATOMIC];
                +    case 1:
                +      var element = Blockly.Dart.valueToCode(block, 'ADD0',
                +              Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +      var code = element + '.toString()';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +    default:
                +      var elements = new Array(block.itemCount_);
                +      for (var i = 0; i < block.itemCount_; i++) {
                +        elements[i] = Blockly.Dart.valueToCode(block, 'ADD' + i,
                +                Blockly.Dart.ORDER_NONE) || '\'\'';
                +      }
                +      var code = '[' + elements.join(',') + '].join()';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +  }
                +};
                +
                +Blockly.Dart['text_append'] = function(block) {
                +  // Append to a variable in place.
                +  var varName = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  var value = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  return varName + ' = [' + varName + ', ' + value + '].join();\n';
                +};
                +
                +Blockly.Dart['text_length'] = function(block) {
                +  // String or array length.
                +  var text = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  return [text + '.length', Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  return [text + '.isEmpty', Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_indexOf'] = function(block) {
                +  // Search the text for a substring.
                +  var operator = block.getFieldValue('END') == 'FIRST' ?
                +      'indexOf' : 'lastIndexOf';
                +  var substring = Blockly.Dart.valueToCode(block, 'FIND',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  var text = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  var code = text + '.' + operator + '(' + substring + ')';
                +  if (block.workspace.options.oneBasedIndex) {
                +    return [code + ' + 1', Blockly.Dart.ORDER_ADDITIVE];
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_charAt'] = function(block) {
                +  // Get letter at index.
                +  // Note: Until January 2013 this block did not have the WHERE input.
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var text = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  switch (where) {
                +    case 'FIRST':
                +      var code = text + '[0]';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +    case 'FROM_START':
                +      var at = Blockly.Dart.getAdjusted(block, 'AT');
                +      var code = text + '[' + at + ']';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +    case 'LAST':
                +      at = 1;
                +      // Fall through.
                +    case 'FROM_END':
                +      var at = Blockly.Dart.getAdjusted(block, 'AT', 1);
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'text_get_from_end',
                +          ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(String text, num x) {',
                +           '  return text[text.length - x];',
                +           '}']);
                +      code = functionName + '(' + text + ', ' + at + ')';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +    case 'RANDOM':
                +      Blockly.Dart.definitions_['import_dart_math'] =
                +          'import \'dart:math\' as Math;';
                +      var functionName = Blockly.Dart.provideFunction_(
                +          'text_random_letter',
                +          ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(String text) {',
                +           '  int x = new Math.Random().nextInt(text.length);',
                +           '  return text[x];',
                +           '}']);
                +      code = functionName + '(' + text + ')';
                +      return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +  }
                +  throw 'Unhandled option (text_charAt).';
                +};
                +
                +Blockly.Dart['text_getSubstring'] = function(block) {
                +  // Get substring.
                +  var text = Blockly.Dart.valueToCode(block, 'STRING',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (where1 == 'FIRST' && where2 == 'LAST') {
                +    var code = text;
                +  } else if (text.match(/^'?\w+'?$/) ||
                +      (where1 != 'FROM_END' && where2 == 'FROM_START')) {
                +    // If the text is a variable or literal or doesn't require a call for
                +    // length, don't generate a helper function.
                +    switch (where1) {
                +      case 'FROM_START':
                +        var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
                +        break;
                +      case 'FROM_END':
                +        var at1 = Blockly.Dart.getAdjusted(block, 'AT1', 1, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        at1 = text + '.length - ' + at1;
                +        break;
                +      case 'FIRST':
                +        var at1 = '0';
                +        break;
                +      default:
                +        throw 'Unhandled option (text_getSubstring).';
                +    }
                +    switch (where2) {
                +      case 'FROM_START':
                +        var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 1);
                +        break;
                +      case 'FROM_END':
                +        var at2 = Blockly.Dart.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.Dart.ORDER_ADDITIVE);
                +        at2 = text + '.length - ' + at2;
                +        break;
                +      case 'LAST':
                +        break;
                +      default:
                +        throw 'Unhandled option (text_getSubstring).';
                +    }
                +    if (where2 == 'LAST') {
                +      var code = text + '.substring(' + at1 + ')';
                +    } else {
                +      var code = text + '.substring(' + at1 + ', ' + at2 + ')';
                +    }
                +  } else {
                +    var at1 = Blockly.Dart.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.Dart.getAdjusted(block, 'AT2');
                +    var functionName = Blockly.Dart.provideFunction_(
                +        'text_get_substring',
                +        ['List ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(text, where1, at1, where2, at2) {',
                +         '  int getAt(where, at) {',
                +         '    if (where == \'FROM_END\') {',
                +         '      at = text.length - 1 - at;',
                +         '    } else if (where == \'FIRST\') {',
                +         '      at = 0;',
                +         '    } else if (where == \'LAST\') {',
                +         '      at = text.length - 1;',
                +         '    } else if (where != \'FROM_START\') {',
                +         '      throw \'Unhandled option (text_getSubstring).\';',
                +         '    }',
                +         '    return at;',
                +         '  }',
                +         '  at1 = getAt(where1, at1);',
                +         '  at2 = getAt(where2, at2) + 1;',
                +         '  return text.substring(at1, at2);',
                +         '}']);
                +    var code = functionName + '(' + text + ', \'' +
                +        where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_changeCase'] = function(block) {
                +  // Change capitalization.
                +  var OPERATORS = {
                +    'UPPERCASE': '.toUpperCase()',
                +    'LOWERCASE': '.toLowerCase()',
                +    'TITLECASE': null
                +  };
                +  var operator = OPERATORS[block.getFieldValue('CASE')];
                +  var textOrder = operator ? Blockly.Dart.ORDER_UNARY_POSTFIX :
                +      Blockly.Dart.ORDER_NONE;
                +  var text = Blockly.Dart.valueToCode(block, 'TEXT', textOrder) || '\'\'';
                +  if (operator) {
                +    // Upper and lower case are functions built into Dart.
                +    var code = text + operator;
                +  } else {
                +    // Title case is not a native Dart function.  Define one.
                +    var functionName = Blockly.Dart.provideFunction_(
                +        'text_toTitleCase',
                +        ['String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(String str) {',
                +         '  RegExp exp = new RegExp(r\'\\b\');',
                +         '  List<String> list = str.split(exp);',
                +         '  final title = new StringBuffer();',
                +         '  for (String part in list) {',
                +         '    if (part.length > 0) {',
                +         '      title.write(part[0].toUpperCase());',
                +         '      if (part.length > 0) {',
                +         '        title.write(part.substring(1).toLowerCase());',
                +         '      }',
                +         '    }',
                +         '  }',
                +         '  return title.toString();',
                +         '}']);
                +    var code = functionName + '(' + text + ')';
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_trim'] = function(block) {
                +  // Trim spaces.
                +  var OPERATORS = {
                +    'LEFT': '.replaceFirst(new RegExp(r\'^\\s+\'), \'\')',
                +    'RIGHT': '.replaceFirst(new RegExp(r\'\\s+$\'), \'\')',
                +    'BOTH': '.trim()'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('MODE')];
                +  var text = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  return [text + operator, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_print'] = function(block) {
                +  // Print statement.
                +  var msg = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  return 'print(' + msg + ');\n';
                +};
                +
                +Blockly.Dart['text_prompt_ext'] = function(block) {
                +  // Prompt function.
                +  Blockly.Dart.definitions_['import_dart_html'] =
                +      'import \'dart:html\' as Html;';
                +  if (block.getField('TEXT')) {
                +    // Internal message.
                +    var msg = Blockly.Dart.quote_(block.getFieldValue('TEXT'));
                +  } else {
                +    // External message.
                +    var msg = Blockly.Dart.valueToCode(block, 'TEXT',
                +        Blockly.Dart.ORDER_NONE) || '\'\'';
                +  }
                +  var code = 'Html.window.prompt(' + msg + ', \'\')';
                +  var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
                +  if (toNumber) {
                +    Blockly.Dart.definitions_['import_dart_math'] =
                +        'import \'dart:math\' as Math;';
                +    code = 'Math.parseDouble(' + code + ')';
                +  }
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_prompt'] = Blockly.Dart['text_prompt_ext'];
                +
                +Blockly.Dart['text_count'] = function(block) {
                +  var text = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  var sub = Blockly.Dart.valueToCode(block, 'SUB',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  // Substring count is not a native Dart function.  Define one.
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'text_count',
                +      ['int ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +        '(String haystack, String needle) {',
                +        '  if (needle.length == 0) {',
                +        '    return haystack.length + 1;',
                +        '  }',
                +        '  int index = 0;',
                +        '  int count = 0;',
                +        '  while (index != -1) {',
                +        '    index = haystack.indexOf(needle, index);',
                +        '    if (index != -1) {',
                +        '      count++;',
                +        '     index += needle.length;',
                +        '    }',
                +        '  }',
                +        '  return count;',
                +        '}']);
                +  var code = functionName + '(' + text + ', ' + sub + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_replace'] = function(block) {
                +  var text = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  var from = Blockly.Dart.valueToCode(block, 'FROM',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  var to = Blockly.Dart.valueToCode(block, 'TO',
                +      Blockly.Dart.ORDER_NONE) || '\'\'';
                +  var code = text + '.replaceAll(' + from + ', ' + to + ')';
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                +
                +Blockly.Dart['text_reverse'] = function(block) {
                +  // There isn't a sensible way to do this in Dart. See:
                +  // http://stackoverflow.com/a/21613700/3529104
                +  // Implementing something is possibly better than not implementing anything?
                +  var text = Blockly.Dart.valueToCode(block, 'TEXT',
                +      Blockly.Dart.ORDER_UNARY_POSTFIX) || '\'\'';
                +  var code = 'new String.fromCharCodes(' + text + '.runes.toList().reversed)';
                +  // XXX What should the operator precedence be for a `new`?
                +  return [code, Blockly.Dart.ORDER_UNARY_POSTFIX];
                +};
                diff --git a/blockly/webif/static/blockly/generators/dart/variables.js b/blockly/webif/static/blockly/generators/dart/variables.js
                new file mode 100644
                index 000000000..446f7aa15
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/dart/variables.js
                @@ -0,0 +1,46 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for variable blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Dart.variables');
                +
                +goog.require('Blockly.Dart');
                +
                +
                +Blockly.Dart['variables_get'] = function(block) {
                +  // Variable getter.
                +  var code = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return [code, Blockly.Dart.ORDER_ATOMIC];
                +};
                +
                +Blockly.Dart['variables_set'] = function(block) {
                +  // Variable setter.
                +  var argument0 = Blockly.Dart.valueToCode(block, 'VALUE',
                +      Blockly.Dart.ORDER_ASSIGNMENT) || '0';
                +  var varName = Blockly.Dart.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return varName + ' = ' + argument0 + ';\n';
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript.js b/blockly/webif/static/blockly/generators/javascript.js
                new file mode 100644
                index 000000000..00b96bcc1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript.js
                @@ -0,0 +1,317 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Helper functions for generating JavaScript for blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript');
                +
                +goog.require('Blockly.Generator');
                +
                +
                +/**
                + * JavaScript code generator.
                + * @type {!Blockly.Generator}
                + */
                +Blockly.JavaScript = new Blockly.Generator('JavaScript');
                +
                +/**
                + * List of illegal variable names.
                + * This is not intended to be a security feature.  Blockly is 100% client-side,
                + * so bypassing this list is trivial.  This is intended to prevent users from
                + * accidentally clobbering a built-in object or function.
                + * @private
                + */
                +Blockly.JavaScript.addReservedWords(
                +    'Blockly,' +  // In case JS is evaled in the current window.
                +    // https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
                +    'break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with,' +
                +    'class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield,' +
                +    'const,null,true,false,' +
                +    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects
                +    'Array,ArrayBuffer,Boolean,Date,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Error,eval,EvalError,Float32Array,Float64Array,Function,Infinity,Int16Array,Int32Array,Int8Array,isFinite,isNaN,Iterator,JSON,Math,NaN,Number,Object,parseFloat,parseInt,RangeError,ReferenceError,RegExp,StopIteration,String,SyntaxError,TypeError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,undefined,uneval,URIError,' +
                +    // https://developer.mozilla.org/en/DOM/window
                +    'applicationCache,closed,Components,content,_content,controllers,crypto,defaultStatus,dialogArguments,directories,document,frameElement,frames,fullScreen,globalStorage,history,innerHeight,innerWidth,length,location,locationbar,localStorage,menubar,messageManager,mozAnimationStartTime,mozInnerScreenX,mozInnerScreenY,mozPaintCount,name,navigator,opener,outerHeight,outerWidth,pageXOffset,pageYOffset,parent,performance,personalbar,pkcs11,returnValue,screen,screenX,screenY,scrollbars,scrollMaxX,scrollMaxY,scrollX,scrollY,self,sessionStorage,sidebar,status,statusbar,toolbar,top,URL,window,' +
                +    'addEventListener,alert,atob,back,blur,btoa,captureEvents,clearImmediate,clearInterval,clearTimeout,close,confirm,disableExternalCapture,dispatchEvent,dump,enableExternalCapture,escape,find,focus,forward,GeckoActiveXObject,getAttention,getAttentionWithCycleCount,getComputedStyle,getSelection,home,matchMedia,maximize,minimize,moveBy,moveTo,mozRequestAnimationFrame,open,openDialog,postMessage,print,prompt,QueryInterface,releaseEvents,removeEventListener,resizeBy,resizeTo,restore,routeEvent,scroll,scrollBy,scrollByLines,scrollByPages,scrollTo,setCursor,setImmediate,setInterval,setResizable,setTimeout,showModalDialog,sizeToContent,stop,unescape,updateCommands,XPCNativeWrapper,XPCSafeJSObjectWrapper,' +
                +    'onabort,onbeforeunload,onblur,onchange,onclick,onclose,oncontextmenu,ondevicemotion,ondeviceorientation,ondragdrop,onerror,onfocus,onhashchange,onkeydown,onkeypress,onkeyup,onload,onmousedown,onmousemove,onmouseout,onmouseover,onmouseup,onmozbeforepaint,onpaint,onpopstate,onreset,onresize,onscroll,onselect,onsubmit,onunload,onpageshow,onpagehide,' +
                +    'Image,Option,Worker,' +
                +    // https://developer.mozilla.org/en/Gecko_DOM_Reference
                +    'Event,Range,File,FileReader,Blob,BlobBuilder,' +
                +    'Attr,CDATASection,CharacterData,Comment,console,DocumentFragment,DocumentType,DomConfiguration,DOMError,DOMErrorHandler,DOMException,DOMImplementation,DOMImplementationList,DOMImplementationRegistry,DOMImplementationSource,DOMLocator,DOMObject,DOMString,DOMStringList,DOMTimeStamp,DOMUserData,Entity,EntityReference,MediaQueryList,MediaQueryListListener,NameList,NamedNodeMap,Node,NodeFilter,NodeIterator,NodeList,Notation,Plugin,PluginArray,ProcessingInstruction,SharedWorker,Text,TimeRanges,Treewalker,TypeInfo,UserDataHandler,Worker,WorkerGlobalScope,' +
                +    'HTMLDocument,HTMLElement,HTMLAnchorElement,HTMLAppletElement,HTMLAudioElement,HTMLAreaElement,HTMLBaseElement,HTMLBaseFontElement,HTMLBodyElement,HTMLBRElement,HTMLButtonElement,HTMLCanvasElement,HTMLDirectoryElement,HTMLDivElement,HTMLDListElement,HTMLEmbedElement,HTMLFieldSetElement,HTMLFontElement,HTMLFormElement,HTMLFrameElement,HTMLFrameSetElement,HTMLHeadElement,HTMLHeadingElement,HTMLHtmlElement,HTMLHRElement,HTMLIFrameElement,HTMLImageElement,HTMLInputElement,HTMLKeygenElement,HTMLLabelElement,HTMLLIElement,HTMLLinkElement,HTMLMapElement,HTMLMenuElement,HTMLMetaElement,HTMLModElement,HTMLObjectElement,HTMLOListElement,HTMLOptGroupElement,HTMLOptionElement,HTMLOutputElement,HTMLParagraphElement,HTMLParamElement,HTMLPreElement,HTMLQuoteElement,HTMLScriptElement,HTMLSelectElement,HTMLSourceElement,HTMLSpanElement,HTMLStyleElement,HTMLTableElement,HTMLTableCaptionElement,HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement,HTMLTableColElement,HTMLTableRowElement,HTMLTableSectionElement,HTMLTextAreaElement,HTMLTimeElement,HTMLTitleElement,HTMLTrackElement,HTMLUListElement,HTMLUnknownElement,HTMLVideoElement,' +
                +    'HTMLCanvasElement,CanvasRenderingContext2D,CanvasGradient,CanvasPattern,TextMetrics,ImageData,CanvasPixelArray,HTMLAudioElement,HTMLVideoElement,NotifyAudioAvailableEvent,HTMLCollection,HTMLAllCollection,HTMLFormControlsCollection,HTMLOptionsCollection,HTMLPropertiesCollection,DOMTokenList,DOMSettableTokenList,DOMStringMap,RadioNodeList,' +
                +    'SVGDocument,SVGElement,SVGAElement,SVGAltGlyphElement,SVGAltGlyphDefElement,SVGAltGlyphItemElement,SVGAnimationElement,SVGAnimateElement,SVGAnimateColorElement,SVGAnimateMotionElement,SVGAnimateTransformElement,SVGSetElement,SVGCircleElement,SVGClipPathElement,SVGColorProfileElement,SVGCursorElement,SVGDefsElement,SVGDescElement,SVGEllipseElement,SVGFilterElement,SVGFilterPrimitiveStandardAttributes,SVGFEBlendElement,SVGFEColorMatrixElement,SVGFEComponentTransferElement,SVGFECompositeElement,SVGFEConvolveMatrixElement,SVGFEDiffuseLightingElement,SVGFEDisplacementMapElement,SVGFEDistantLightElement,SVGFEFloodElement,SVGFEGaussianBlurElement,SVGFEImageElement,SVGFEMergeElement,SVGFEMergeNodeElement,SVGFEMorphologyElement,SVGFEOffsetElement,SVGFEPointLightElement,SVGFESpecularLightingElement,SVGFESpotLightElement,SVGFETileElement,SVGFETurbulenceElement,SVGComponentTransferFunctionElement,SVGFEFuncRElement,SVGFEFuncGElement,SVGFEFuncBElement,SVGFEFuncAElement,SVGFontElement,SVGFontFaceElement,SVGFontFaceFormatElement,SVGFontFaceNameElement,SVGFontFaceSrcElement,SVGFontFaceUriElement,SVGForeignObjectElement,SVGGElement,SVGGlyphElement,SVGGlyphRefElement,SVGGradientElement,SVGLinearGradientElement,SVGRadialGradientElement,SVGHKernElement,SVGImageElement,SVGLineElement,SVGMarkerElement,SVGMaskElement,SVGMetadataElement,SVGMissingGlyphElement,SVGMPathElement,SVGPathElement,SVGPatternElement,SVGPolylineElement,SVGPolygonElement,SVGRectElement,SVGScriptElement,SVGStopElement,SVGStyleElement,SVGSVGElement,SVGSwitchElement,SVGSymbolElement,SVGTextElement,SVGTextPathElement,SVGTitleElement,SVGTRefElement,SVGTSpanElement,SVGUseElement,SVGViewElement,SVGVKernElement,' +
                +    'SVGAngle,SVGColor,SVGICCColor,SVGElementInstance,SVGElementInstanceList,SVGLength,SVGLengthList,SVGMatrix,SVGNumber,SVGNumberList,SVGPaint,SVGPoint,SVGPointList,SVGPreserveAspectRatio,SVGRect,SVGStringList,SVGTransform,SVGTransformList,' +
                +    'SVGAnimatedAngle,SVGAnimatedBoolean,SVGAnimatedEnumeration,SVGAnimatedInteger,SVGAnimatedLength,SVGAnimatedLengthList,SVGAnimatedNumber,SVGAnimatedNumberList,SVGAnimatedPreserveAspectRatio,SVGAnimatedRect,SVGAnimatedString,SVGAnimatedTransformList,' +
                +    'SVGPathSegList,SVGPathSeg,SVGPathSegArcAbs,SVGPathSegArcRel,SVGPathSegClosePath,SVGPathSegCurvetoCubicAbs,SVGPathSegCurvetoCubicRel,SVGPathSegCurvetoCubicSmoothAbs,SVGPathSegCurvetoCubicSmoothRel,SVGPathSegCurvetoQuadraticAbs,SVGPathSegCurvetoQuadraticRel,SVGPathSegCurvetoQuadraticSmoothAbs,SVGPathSegCurvetoQuadraticSmoothRel,SVGPathSegLinetoAbs,SVGPathSegLinetoHorizontalAbs,SVGPathSegLinetoHorizontalRel,SVGPathSegLinetoRel,SVGPathSegLinetoVerticalAbs,SVGPathSegLinetoVerticalRel,SVGPathSegMovetoAbs,SVGPathSegMovetoRel,ElementTimeControl,TimeEvent,SVGAnimatedPathData,' +
                +    'SVGAnimatedPoints,SVGColorProfileRule,SVGCSSRule,SVGExternalResourcesRequired,SVGFitToViewBox,SVGLangSpace,SVGLocatable,SVGRenderingIntent,SVGStylable,SVGTests,SVGTextContentElement,SVGTextPositioningElement,SVGTransformable,SVGUnitTypes,SVGURIReference,SVGViewSpec,SVGZoomAndPan');
                +
                +/**
                + * Order of operation ENUMs.
                + * https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence
                + */
                +Blockly.JavaScript.ORDER_ATOMIC = 0;           // 0 "" ...
                +Blockly.JavaScript.ORDER_NEW = 1.1;            // new
                +Blockly.JavaScript.ORDER_MEMBER = 1.2;         // . []
                +Blockly.JavaScript.ORDER_FUNCTION_CALL = 2;    // ()
                +Blockly.JavaScript.ORDER_INCREMENT = 3;        // ++
                +Blockly.JavaScript.ORDER_DECREMENT = 3;        // --
                +Blockly.JavaScript.ORDER_BITWISE_NOT = 4.1;    // ~
                +Blockly.JavaScript.ORDER_UNARY_PLUS = 4.2;     // +
                +Blockly.JavaScript.ORDER_UNARY_NEGATION = 4.3; // -
                +Blockly.JavaScript.ORDER_LOGICAL_NOT = 4.4;    // !
                +Blockly.JavaScript.ORDER_TYPEOF = 4.5;         // typeof
                +Blockly.JavaScript.ORDER_VOID = 4.6;           // void
                +Blockly.JavaScript.ORDER_DELETE = 4.7;         // delete
                +Blockly.JavaScript.ORDER_DIVISION = 5.1;       // /
                +Blockly.JavaScript.ORDER_MULTIPLICATION = 5.2; // *
                +Blockly.JavaScript.ORDER_MODULUS = 5.3;        // %
                +Blockly.JavaScript.ORDER_SUBTRACTION = 6.1;    // -
                +Blockly.JavaScript.ORDER_ADDITION = 6.2;       // +
                +Blockly.JavaScript.ORDER_BITWISE_SHIFT = 7;    // << >> >>>
                +Blockly.JavaScript.ORDER_RELATIONAL = 8;       // < <= > >=
                +Blockly.JavaScript.ORDER_IN = 8;               // in
                +Blockly.JavaScript.ORDER_INSTANCEOF = 8;       // instanceof
                +Blockly.JavaScript.ORDER_EQUALITY = 9;         // == != === !==
                +Blockly.JavaScript.ORDER_BITWISE_AND = 10;     // &
                +Blockly.JavaScript.ORDER_BITWISE_XOR = 11;     // ^
                +Blockly.JavaScript.ORDER_BITWISE_OR = 12;      // |
                +Blockly.JavaScript.ORDER_LOGICAL_AND = 13;     // &&
                +Blockly.JavaScript.ORDER_LOGICAL_OR = 14;      // ||
                +Blockly.JavaScript.ORDER_CONDITIONAL = 15;     // ?:
                +Blockly.JavaScript.ORDER_ASSIGNMENT = 16;      // = += -= *= /= %= <<= >>= ...
                +Blockly.JavaScript.ORDER_COMMA = 17;           // ,
                +Blockly.JavaScript.ORDER_NONE = 99;            // (...)
                +
                +/**
                + * List of outer-inner pairings that do NOT require parentheses.
                + * @type {!Array.<!Array.<number>>}
                + */
                +Blockly.JavaScript.ORDER_OVERRIDES = [
                +  // (foo()).bar -> foo().bar
                +  // (foo())[0] -> foo()[0]
                +  [Blockly.JavaScript.ORDER_FUNCTION_CALL, Blockly.JavaScript.ORDER_MEMBER],
                +  // (foo())() -> foo()()
                +  [Blockly.JavaScript.ORDER_FUNCTION_CALL, Blockly.JavaScript.ORDER_FUNCTION_CALL],
                +  // (foo.bar).baz -> foo.bar.baz
                +  // (foo.bar)[0] -> foo.bar[0]
                +  // (foo[0]).bar -> foo[0].bar
                +  // (foo[0])[1] -> foo[0][1]
                +  [Blockly.JavaScript.ORDER_MEMBER, Blockly.JavaScript.ORDER_MEMBER],
                +  // (foo.bar)() -> foo.bar()
                +  // (foo[0])() -> foo[0]()
                +  [Blockly.JavaScript.ORDER_MEMBER, Blockly.JavaScript.ORDER_FUNCTION_CALL],
                +
                +  // !(!foo) -> !!foo
                +  [Blockly.JavaScript.ORDER_LOGICAL_NOT, Blockly.JavaScript.ORDER_LOGICAL_NOT],
                +  // a * (b * c) -> a * b * c
                +  [Blockly.JavaScript.ORDER_MULTIPLICATION, Blockly.JavaScript.ORDER_MULTIPLICATION],
                +  // a + (b + c) -> a + b + c
                +  [Blockly.JavaScript.ORDER_ADDITION, Blockly.JavaScript.ORDER_ADDITION],
                +  // a && (b && c) -> a && b && c
                +  [Blockly.JavaScript.ORDER_LOGICAL_AND, Blockly.JavaScript.ORDER_LOGICAL_AND],
                +  // a || (b || c) -> a || b || c
                +  [Blockly.JavaScript.ORDER_LOGICAL_OR, Blockly.JavaScript.ORDER_LOGICAL_OR]
                +];
                +
                +/**
                + * Initialise the database of variable names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.JavaScript.init = function(workspace) {
                +  // Create a dictionary of definitions to be printed before the code.
                +  Blockly.JavaScript.definitions_ = Object.create(null);
                +  // Create a dictionary mapping desired function names in definitions_
                +  // to actual function names (to avoid collisions with user functions).
                +  Blockly.JavaScript.functionNames_ = Object.create(null);
                +
                +  if (!Blockly.JavaScript.variableDB_) {
                +    Blockly.JavaScript.variableDB_ =
                +        new Blockly.Names(Blockly.JavaScript.RESERVED_WORDS_);
                +  } else {
                +    Blockly.JavaScript.variableDB_.reset();
                +  }
                +
                +  var defvars = [];
                +  var variables = workspace.getAllVariables();
                +  if (variables.length) {
                +    for (var i = 0; i < variables.length; i++) {
                +      defvars[i] = Blockly.JavaScript.variableDB_.getName(variables[i].name,
                +          Blockly.Variables.NAME_TYPE);
                +    }
                +    Blockly.JavaScript.definitions_['variables'] =
                +        'var ' + defvars.join(', ') + ';';
                +  }
                +};
                +
                +/**
                + * Prepend the generated code with the variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.JavaScript.finish = function(code) {
                +  // Convert the definitions dictionary into a list.
                +  var definitions = [];
                +  for (var name in Blockly.JavaScript.definitions_) {
                +    definitions.push(Blockly.JavaScript.definitions_[name]);
                +  }
                +  // Clean up temporary data.
                +  delete Blockly.JavaScript.definitions_;
                +  delete Blockly.JavaScript.functionNames_;
                +  Blockly.JavaScript.variableDB_.reset();
                +  return definitions.join('\n\n') + '\n\n\n' + code;
                +};
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything.  A trailing semicolon is needed to make this legal.
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.JavaScript.scrubNakedValue = function(line) {
                +  return line + ';\n';
                +};
                +
                +/**
                + * Encode a string as a properly escaped JavaScript string, complete with
                + * quotes.
                + * @param {string} string Text to encode.
                + * @return {string} JavaScript string.
                + * @private
                + */
                +Blockly.JavaScript.quote_ = function(string) {
                +  // Can't use goog.string.quote since Google's style guide recommends
                +  // JS string literals use single quotes.
                +  string = string.replace(/\\/g, '\\\\')
                +                 .replace(/\n/g, '\\\n')
                +                 .replace(/'/g, '\\\'');
                +  return '\'' + string + '\'';
                +};
                +
                +/**
                + * Common tasks for generating JavaScript from blocks.
                + * Handles comments for the specified block and any connected value blocks.
                + * Calls any statements following this block.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The JavaScript code created for this block.
                + * @return {string} JavaScript code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.JavaScript.scrub_ = function(block, code) {
                +  var commentCode = '';
                +  // Only collect comments for blocks that aren't inline.
                +  if (!block.outputConnection || !block.outputConnection.targetConnection) {
                +    // Collect comment for this block.
                +    var comment = block.getCommentText();
                +    comment = Blockly.utils.wrap(comment, Blockly.JavaScript.COMMENT_WRAP - 3);
                +    if (comment) {
                +      if (block.getProcedureDef) {
                +        // Use a comment block for function comments.
                +        commentCode += '/**\n' +
                +                       Blockly.JavaScript.prefixLines(comment + '\n', ' * ') +
                +                       ' */\n';
                +      } else {
                +        commentCode += Blockly.JavaScript.prefixLines(comment + '\n', '// ');
                +      }
                +    }
                +    // Collect comments for all value arguments.
                +    // Don't collect comments for nested statements.
                +    for (var i = 0; i < block.inputList.length; i++) {
                +      if (block.inputList[i].type == Blockly.INPUT_VALUE) {
                +        var childBlock = block.inputList[i].connection.targetBlock();
                +        if (childBlock) {
                +          var comment = Blockly.JavaScript.allNestedComments(childBlock);
                +          if (comment) {
                +            commentCode += Blockly.JavaScript.prefixLines(comment, '// ');
                +          }
                +        }
                +      }
                +    }
                +  }
                +  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
                +  var nextCode = Blockly.JavaScript.blockToCode(nextBlock);
                +  return commentCode + code + nextCode;
                +};
                +
                +/**
                + * Gets a property and adjusts the value while taking into account indexing.
                + * @param {!Blockly.Block} block The block.
                + * @param {string} atId The property ID of the element to get.
                + * @param {number=} opt_delta Value to add.
                + * @param {boolean=} opt_negate Whether to negate the value.
                + * @param {number=} opt_order The highest order acting on this value.
                + * @return {string|number}
                + */
                +Blockly.JavaScript.getAdjusted = function(block, atId, opt_delta, opt_negate,
                +    opt_order) {
                +  var delta = opt_delta || 0;
                +  var order = opt_order || Blockly.JavaScript.ORDER_NONE;
                +  if (block.workspace.options.oneBasedIndex) {
                +    delta--;
                +  }
                +  var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0';
                +  if (delta > 0) {
                +    var at = Blockly.JavaScript.valueToCode(block, atId,
                +        Blockly.JavaScript.ORDER_ADDITION) || defaultAtIndex;
                +  } else if (delta < 0) {
                +    var at = Blockly.JavaScript.valueToCode(block, atId,
                +        Blockly.JavaScript.ORDER_SUBTRACTION) || defaultAtIndex;
                +  } else if (opt_negate) {
                +    var at = Blockly.JavaScript.valueToCode(block, atId,
                +        Blockly.JavaScript.ORDER_UNARY_NEGATION) || defaultAtIndex;
                +  } else {
                +    var at = Blockly.JavaScript.valueToCode(block, atId, order) ||
                +        defaultAtIndex;
                +  }
                +
                +  if (Blockly.isNumber(at)) {
                +    // If the index is a naked number, adjust it right now.
                +    at = parseFloat(at) + delta;
                +    if (opt_negate) {
                +      at = -at;
                +    }
                +  } else {
                +    // If the index is dynamic, adjust it in code.
                +    if (delta > 0) {
                +      at = at + ' + ' + delta;
                +      var innerOrder = Blockly.JavaScript.ORDER_ADDITION;
                +    } else if (delta < 0) {
                +      at = at + ' - ' + -delta;
                +      var innerOrder = Blockly.JavaScript.ORDER_SUBTRACTION;
                +    }
                +    if (opt_negate) {
                +      if (delta) {
                +        at = '-(' + at + ')';
                +      } else {
                +        at = '-' + at;
                +      }
                +      var innerOrder = Blockly.JavaScript.ORDER_UNARY_NEGATION;
                +    }
                +    innerOrder = Math.floor(innerOrder);
                +    order = Math.floor(order);
                +    if (innerOrder && order >= innerOrder) {
                +      at = '(' + at + ')';
                +    }
                +  }
                +  return at;
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/colour.js b/blockly/webif/static/blockly/generators/javascript/colour.js
                new file mode 100644
                index 000000000..21b372e9c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/colour.js
                @@ -0,0 +1,103 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for colour blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.colour');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['colour_picker'] = function(block) {
                +  // Colour picker.
                +  var code = '\'' + block.getFieldValue('COLOUR') + '\'';
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['colour_random'] = function(block) {
                +  // Generate a random colour.
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'colourRandom',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +        '  var num = Math.floor(Math.random() * Math.pow(2, 24));',
                +        '  return \'#\' + (\'00000\' + num.toString(16)).substr(-6);',
                +        '}']);
                +  var code = functionName + '()';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['colour_rgb'] = function(block) {
                +  // Compose a colour from RGB components expressed as percentages.
                +  var red = Blockly.JavaScript.valueToCode(block, 'RED',
                +      Blockly.JavaScript.ORDER_COMMA) || 0;
                +  var green = Blockly.JavaScript.valueToCode(block, 'GREEN',
                +      Blockly.JavaScript.ORDER_COMMA) || 0;
                +  var blue = Blockly.JavaScript.valueToCode(block, 'BLUE',
                +      Blockly.JavaScript.ORDER_COMMA) || 0;
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'colourRgb',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(r, g, b) {',
                +       '  r = Math.max(Math.min(Number(r), 100), 0) * 2.55;',
                +       '  g = Math.max(Math.min(Number(g), 100), 0) * 2.55;',
                +       '  b = Math.max(Math.min(Number(b), 100), 0) * 2.55;',
                +       '  r = (\'0\' + (Math.round(r) || 0).toString(16)).slice(-2);',
                +       '  g = (\'0\' + (Math.round(g) || 0).toString(16)).slice(-2);',
                +       '  b = (\'0\' + (Math.round(b) || 0).toString(16)).slice(-2);',
                +       '  return \'#\' + r + g + b;',
                +       '}']);
                +  var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['colour_blend'] = function(block) {
                +  // Blend two colours together.
                +  var c1 = Blockly.JavaScript.valueToCode(block, 'COLOUR1',
                +      Blockly.JavaScript.ORDER_COMMA) || '\'#000000\'';
                +  var c2 = Blockly.JavaScript.valueToCode(block, 'COLOUR2',
                +      Blockly.JavaScript.ORDER_COMMA) || '\'#000000\'';
                +  var ratio = Blockly.JavaScript.valueToCode(block, 'RATIO',
                +      Blockly.JavaScript.ORDER_COMMA) || 0.5;
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'colourBlend',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(c1, c2, ratio) {',
                +       '  ratio = Math.max(Math.min(Number(ratio), 1), 0);',
                +       '  var r1 = parseInt(c1.substring(1, 3), 16);',
                +       '  var g1 = parseInt(c1.substring(3, 5), 16);',
                +       '  var b1 = parseInt(c1.substring(5, 7), 16);',
                +       '  var r2 = parseInt(c2.substring(1, 3), 16);',
                +       '  var g2 = parseInt(c2.substring(3, 5), 16);',
                +       '  var b2 = parseInt(c2.substring(5, 7), 16);',
                +       '  var r = Math.round(r1 * (1 - ratio) + r2 * ratio);',
                +       '  var g = Math.round(g1 * (1 - ratio) + g2 * ratio);',
                +       '  var b = Math.round(b1 * (1 - ratio) + b2 * ratio);',
                +       '  r = (\'0\' + (r || 0).toString(16)).slice(-2);',
                +       '  g = (\'0\' + (g || 0).toString(16)).slice(-2);',
                +       '  b = (\'0\' + (b || 0).toString(16)).slice(-2);',
                +       '  return \'#\' + r + g + b;',
                +       '}']);
                +  var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/lists.js b/blockly/webif/static/blockly/generators/javascript/lists.js
                new file mode 100644
                index 000000000..d9075953f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/lists.js
                @@ -0,0 +1,402 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for list blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.lists');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['lists_create_empty'] = function(block) {
                +  // Create an empty list.
                +  return ['[]', Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['lists_create_with'] = function(block) {
                +  // Create a list with any number of elements of any type.
                +  var elements = new Array(block.itemCount_);
                +  for (var i = 0; i < block.itemCount_; i++) {
                +    elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
                +        Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  }
                +  var code = '[' + elements.join(', ') + ']';
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['lists_repeat'] = function(block) {
                +  // Create a list with one element repeated.
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'listsRepeat',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(value, n) {',
                +       '  var array = [];',
                +       '  for (var i = 0; i < n; i++) {',
                +       '    array[i] = value;',
                +       '  }',
                +       '  return array;',
                +       '}']);
                +  var element = Blockly.JavaScript.valueToCode(block, 'ITEM',
                +      Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  var repeatCount = Blockly.JavaScript.valueToCode(block, 'NUM',
                +      Blockly.JavaScript.ORDER_COMMA) || '0';
                +  var code = functionName + '(' + element + ', ' + repeatCount + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['lists_length'] = function(block) {
                +  // String or array length.
                +  var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +  return [list + '.length', Blockly.JavaScript.ORDER_MEMBER];
                +};
                +
                +Blockly.JavaScript['lists_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +  return ['!' + list + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
                +};
                +
                +Blockly.JavaScript['lists_indexOf'] = function(block) {
                +  // Find an item in the list.
                +  var operator = block.getFieldValue('END') == 'FIRST' ?
                +      'indexOf' : 'lastIndexOf';
                +  var item = Blockly.JavaScript.valueToCode(block, 'FIND',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  var list = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +  var code = list + '.' + operator + '(' + item + ')';
                +  if (block.workspace.options.oneBasedIndex) {
                +    return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION];
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['lists_getIndex'] = function(block) {
                +  // Get element at index.
                +  // Note: Until January 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var listOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_COMMA :
                +      Blockly.JavaScript.ORDER_MEMBER;
                +  var list = Blockly.JavaScript.valueToCode(block, 'VALUE', listOrder) || '[]';
                +
                +  switch (where) {
                +    case ('FIRST'):
                +      if (mode == 'GET') {
                +        var code = list + '[0]';
                +        return [code, Blockly.JavaScript.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.shift()';
                +        return [code, Blockly.JavaScript.ORDER_MEMBER];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.shift();\n';
                +      }
                +      break;
                +    case ('LAST'):
                +      if (mode == 'GET') {
                +        var code = list + '.slice(-1)[0]';
                +        return [code, Blockly.JavaScript.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.pop()';
                +        return [code, Blockly.JavaScript.ORDER_MEMBER];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.pop();\n';
                +      }
                +      break;
                +    case ('FROM_START'):
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT');
                +      if (mode == 'GET') {
                +        var code = list + '[' + at + ']';
                +        return [code, Blockly.JavaScript.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.splice(' + at + ', 1)[0]';
                +        return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.splice(' + at + ', 1);\n';
                +      }
                +      break;
                +    case ('FROM_END'):
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true);
                +      if (mode == 'GET') {
                +        var code = list + '.slice(' + at + ')[0]';
                +        return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.splice(' + at + ', 1)[0]';
                +        return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.splice(' + at + ', 1);';
                +      }
                +      break;
                +    case ('RANDOM'):
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'listsGetRandomItem',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(list, remove) {',
                +           '  var x = Math.floor(Math.random() * list.length);',
                +           '  if (remove) {',
                +           '    return list.splice(x, 1)[0];',
                +           '  } else {',
                +           '    return list[x];',
                +           '  }',
                +           '}']);
                +      code = functionName + '(' + list + ', ' + (mode != 'GET') + ')';
                +      if (mode == 'GET' || mode == 'GET_REMOVE') {
                +        return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return code + ';\n';
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_getIndex).';
                +};
                +
                +Blockly.JavaScript['lists_setIndex'] = function(block) {
                +  // Set element at index.
                +  // Note: Until February 2013 this block did not have MODE or WHERE inputs.
                +  var list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +      Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var value = Blockly.JavaScript.valueToCode(block, 'TO',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || 'null';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  // Closure, which accesses and modifies 'list'.
                +  function cacheList() {
                +    if (list.match(/^\w+$/)) {
                +      return '';
                +    }
                +    var listVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +        'tmpList', Blockly.Variables.NAME_TYPE);
                +    var code = 'var ' + listVar + ' = ' + list + ';\n';
                +    list = listVar;
                +    return code;
                +  }
                +  switch (where) {
                +    case ('FIRST'):
                +      if (mode == 'SET') {
                +        return list + '[0] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        return list + '.unshift(' + value + ');\n';
                +      }
                +      break;
                +    case ('LAST'):
                +      if (mode == 'SET') {
                +        var code = cacheList();
                +        code += list + '[' + list + '.length - 1] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        return list + '.push(' + value + ');\n';
                +      }
                +      break;
                +    case ('FROM_START'):
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT');
                +      if (mode == 'SET') {
                +        return list + '[' + at + '] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        return list + '.splice(' + at + ', 0, ' + value + ');\n';
                +      }
                +      break;
                +    case ('FROM_END'):
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, false,
                +          Blockly.JavaScript.ORDER_SUBTRACTION);
                +      var code = cacheList();
                +      if (mode == 'SET') {
                +        code += list + '[' + list + '.length - ' + at + '] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        code += list + '.splice(' + list + '.length - ' + at + ', 0, ' + value +
                +            ');\n';
                +        return code;
                +      }
                +      break;
                +    case ('RANDOM'):
                +      var code = cacheList();
                +      var xVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +          'tmpX', Blockly.Variables.NAME_TYPE);
                +      code += 'var ' + xVar + ' = Math.floor(Math.random() * ' + list +
                +          '.length);\n';
                +      if (mode == 'SET') {
                +        code += list + '[' + xVar + '] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        code += list + '.splice(' + xVar + ', 0, ' + value + ');\n';
                +        return code;
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_setIndex).';
                +};
                +
                +/**
                + * Returns an expression calculating the index into a list.
                + * @private
                + * @param {string} listName Name of the list, used to calculate length.
                + * @param {string} where The method of indexing, selected by dropdown in Blockly
                + * @param {string=} opt_at The optional offset when indexing from start/end.
                + * @return {string} Index expression.
                + */
                +Blockly.JavaScript.lists.getIndex_ = function(listName, where, opt_at) {
                +  if (where == 'FIRST') {
                +    return '0';
                +  } else if (where == 'FROM_END') {
                +    return listName + '.length - 1 - ' + opt_at;
                +  } else if (where == 'LAST') {
                +    return listName + '.length - 1';
                +  } else {
                +    return opt_at;
                +  }
                +};
                +
                +Blockly.JavaScript['lists_getSublist'] = function(block) {
                +  // Get sublist.
                +  var list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +      Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (where1 == 'FIRST' && where2 == 'LAST') {
                +    var code = list + '.slice(0)';
                +  } else if (list.match(/^\w+$/) ||
                +      (where1 != 'FROM_END' && where2 == 'FROM_START')) {
                +    // If the list is a variable or doesn't require a call for length, don't
                +    // generate a helper function.
                +    switch (where1) {
                +      case 'FROM_START':
                +        var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
                +        break;
                +      case 'FROM_END':
                +        var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false,
                +            Blockly.JavaScript.ORDER_SUBTRACTION);
                +        at1 = list + '.length - ' + at1;
                +        break;
                +      case 'FIRST':
                +        var at1 = '0';
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    switch (where2) {
                +      case 'FROM_START':
                +        var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1);
                +        break;
                +      case 'FROM_END':
                +        var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.JavaScript.ORDER_SUBTRACTION);
                +        at2 = list + '.length - ' + at2;
                +        break;
                +      case 'LAST':
                +        var at2 = list + '.length';
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    code = list + '.slice(' + at1 + ', ' + at2 + ')';
                +  } else {
                +    var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2');
                +    var getIndex_ = Blockly.JavaScript.lists.getIndex_;
                +    var wherePascalCase = {'FIRST': 'First', 'LAST': 'Last',
                +        'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'};
                +    var functionName = Blockly.JavaScript.provideFunction_(
                +        'subsequence' + wherePascalCase[where1] + wherePascalCase[where2],
                +        ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(sequence' +
                +            // The value for 'FROM_END' and'FROM_START' depends on `at` so
                +            // we add it as a parameter.
                +            ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', at1' : '') +
                +            ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', at2' : '') +
                +            ') {',
                +          '  var start = ' + getIndex_('sequence', where1, 'at1') + ';',
                +          '  var end = ' + getIndex_('sequence', where2, 'at2') + ' + 1;',
                +          '  return sequence.slice(start, end);',
                +          '}']);
                +    var code = functionName + '(' + list +
                +        // The value for 'FROM_END' and 'FROM_START' depends on `at` so we
                +        // pass it.
                +        ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
                +        ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
                +        ')';
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['lists_sort'] = function(block) {
                +  // Block for sorting a list.
                +  var list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +      Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]';
                +  var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
                +  var type = block.getFieldValue('TYPE');
                +  var getCompareFunctionName = Blockly.JavaScript.provideFunction_(
                +      'listsGetSortCompare',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(type, direction) {',
                +       '  var compareFuncs = {',
                +       '    "NUMERIC": function(a, b) {',
                +       '        return parseFloat(a) - parseFloat(b); },',
                +       '    "TEXT": function(a, b) {',
                +       '        return a.toString() > b.toString() ? 1 : -1; },',
                +       '    "IGNORE_CASE": function(a, b) {',
                +       '        return a.toString().toLowerCase() > ' +
                +          'b.toString().toLowerCase() ? 1 : -1; },',
                +       '  };',
                +       '  var compare = compareFuncs[type];',
                +       '  return function(a, b) { return compare(a, b) * direction; }',
                +       '}']);
                +  return [list + '.slice().sort(' +
                +      getCompareFunctionName + '("' + type + '", ' + direction + '))',
                +      Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['lists_split'] = function(block) {
                +  // Block for splitting text into a list, or joining a list into text.
                +  var input = Blockly.JavaScript.valueToCode(block, 'INPUT',
                +      Blockly.JavaScript.ORDER_MEMBER);
                +  var delimiter = Blockly.JavaScript.valueToCode(block, 'DELIM',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  var mode = block.getFieldValue('MODE');
                +  if (mode == 'SPLIT') {
                +    if (!input) {
                +      input = '\'\'';
                +    }
                +    var functionName = 'split';
                +  } else if (mode == 'JOIN') {
                +    if (!input) {
                +      input = '[]';
                +    }
                +    var functionName = 'join';
                +  } else {
                +    throw 'Unknown mode: ' + mode;
                +  }
                +  var code = input + '.' + functionName + '(' + delimiter + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['lists_reverse'] = function(block) {
                +  // Block for reversing a list.
                +  var list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +      Blockly.JavaScript.ORDER_FUNCTION_CALL) || '[]';
                +  var code = list + '.slice().reverse()';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/logic.js b/blockly/webif/static/blockly/generators/javascript/logic.js
                new file mode 100644
                index 000000000..1c4d4b620
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/logic.js
                @@ -0,0 +1,129 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for logic blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.logic');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['controls_if'] = function(block) {
                +  // If/elseif/else condition.
                +  var n = 0;
                +  var code = '', branchCode, conditionCode;
                +  do {
                +    conditionCode = Blockly.JavaScript.valueToCode(block, 'IF' + n,
                +      Blockly.JavaScript.ORDER_NONE) || 'false';
                +    branchCode = Blockly.JavaScript.statementToCode(block, 'DO' + n);
                +    code += (n > 0 ? ' else ' : '') +
                +        'if (' + conditionCode + ') {\n' + branchCode + '}';
                +
                +    ++n;
                +  } while (block.getInput('IF' + n));
                +
                +  if (block.getInput('ELSE')) {
                +    branchCode = Blockly.JavaScript.statementToCode(block, 'ELSE');
                +    code += ' else {\n' + branchCode + '}';
                +  }
                +  return code + '\n';
                +};
                +
                +Blockly.JavaScript['controls_ifelse'] = Blockly.JavaScript['controls_if'];
                +
                +Blockly.JavaScript['logic_compare'] = function(block) {
                +  // Comparison operator.
                +  var OPERATORS = {
                +    'EQ': '==',
                +    'NEQ': '!=',
                +    'LT': '<',
                +    'LTE': '<=',
                +    'GT': '>',
                +    'GTE': '>='
                +  };
                +  var operator = OPERATORS[block.getFieldValue('OP')];
                +  var order = (operator == '==' || operator == '!=') ?
                +      Blockly.JavaScript.ORDER_EQUALITY : Blockly.JavaScript.ORDER_RELATIONAL;
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.JavaScript['logic_operation'] = function(block) {
                +  // Operations 'and', 'or'.
                +  var operator = (block.getFieldValue('OP') == 'AND') ? '&&' : '||';
                +  var order = (operator == '&&') ? Blockly.JavaScript.ORDER_LOGICAL_AND :
                +      Blockly.JavaScript.ORDER_LOGICAL_OR;
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'A', order);
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'B', order);
                +  if (!argument0 && !argument1) {
                +    // If there are no arguments, then the return value is false.
                +    argument0 = 'false';
                +    argument1 = 'false';
                +  } else {
                +    // Single missing arguments have no effect on the return value.
                +    var defaultArgument = (operator == '&&') ? 'true' : 'false';
                +    if (!argument0) {
                +      argument0 = defaultArgument;
                +    }
                +    if (!argument1) {
                +      argument1 = defaultArgument;
                +    }
                +  }
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.JavaScript['logic_negate'] = function(block) {
                +  // Negation.
                +  var order = Blockly.JavaScript.ORDER_LOGICAL_NOT;
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'BOOL', order) ||
                +      'true';
                +  var code = '!' + argument0;
                +  return [code, order];
                +};
                +
                +Blockly.JavaScript['logic_boolean'] = function(block) {
                +  // Boolean values true and false.
                +  var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false';
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['logic_null'] = function(block) {
                +  // Null data type.
                +  return ['null', Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['logic_ternary'] = function(block) {
                +  // Ternary operator.
                +  var value_if = Blockly.JavaScript.valueToCode(block, 'IF',
                +      Blockly.JavaScript.ORDER_CONDITIONAL) || 'false';
                +  var value_then = Blockly.JavaScript.valueToCode(block, 'THEN',
                +      Blockly.JavaScript.ORDER_CONDITIONAL) || 'null';
                +  var value_else = Blockly.JavaScript.valueToCode(block, 'ELSE',
                +      Blockly.JavaScript.ORDER_CONDITIONAL) || 'null';
                +  var code = value_if + ' ? ' + value_then + ' : ' + value_else;
                +  return [code, Blockly.JavaScript.ORDER_CONDITIONAL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/loops.js b/blockly/webif/static/blockly/generators/javascript/loops.js
                new file mode 100644
                index 000000000..1a2ade593
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/loops.js
                @@ -0,0 +1,175 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for loop blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.loops');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['controls_repeat_ext'] = function(block) {
                +  // Repeat n times.
                +  if (block.getField('TIMES')) {
                +    // Internal number.
                +    var repeats = String(Number(block.getFieldValue('TIMES')));
                +  } else {
                +    // External number.
                +    var repeats = Blockly.JavaScript.valueToCode(block, 'TIMES',
                +        Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
                +  }
                +  var branch = Blockly.JavaScript.statementToCode(block, 'DO');
                +  branch = Blockly.JavaScript.addLoopTrap(branch, block.id);
                +  var code = '';
                +  var loopVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var endVar = repeats;
                +  if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
                +    var endVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +        'repeat_end', Blockly.Variables.NAME_TYPE);
                +    code += 'var ' + endVar + ' = ' + repeats + ';\n';
                +  }
                +  code += 'for (var ' + loopVar + ' = 0; ' +
                +      loopVar + ' < ' + endVar + '; ' +
                +      loopVar + '++) {\n' +
                +      branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.JavaScript['controls_repeat'] =
                +    Blockly.JavaScript['controls_repeat_ext'];
                +
                +Blockly.JavaScript['controls_whileUntil'] = function(block) {
                +  // Do while/until loop.
                +  var until = block.getFieldValue('MODE') == 'UNTIL';
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'BOOL',
                +      until ? Blockly.JavaScript.ORDER_LOGICAL_NOT :
                +      Blockly.JavaScript.ORDER_NONE) || 'false';
                +  var branch = Blockly.JavaScript.statementToCode(block, 'DO');
                +  branch = Blockly.JavaScript.addLoopTrap(branch, block.id);
                +  if (until) {
                +    argument0 = '!' + argument0;
                +  }
                +  return 'while (' + argument0 + ') {\n' + branch + '}\n';
                +};
                +
                +Blockly.JavaScript['controls_for'] = function(block) {
                +  // For loop.
                +  var variable0 = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'FROM',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'TO',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
                +  var increment = Blockly.JavaScript.valueToCode(block, 'BY',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '1';
                +  var branch = Blockly.JavaScript.statementToCode(block, 'DO');
                +  branch = Blockly.JavaScript.addLoopTrap(branch, block.id);
                +  var code;
                +  if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) &&
                +      Blockly.isNumber(increment)) {
                +    // All arguments are simple numbers.
                +    var up = parseFloat(argument0) <= parseFloat(argument1);
                +    code = 'for (' + variable0 + ' = ' + argument0 + '; ' +
                +        variable0 + (up ? ' <= ' : ' >= ') + argument1 + '; ' +
                +        variable0;
                +    var step = Math.abs(parseFloat(increment));
                +    if (step == 1) {
                +      code += up ? '++' : '--';
                +    } else {
                +      code += (up ? ' += ' : ' -= ') + step;
                +    }
                +    code += ') {\n' + branch + '}\n';
                +  } else {
                +    code = '';
                +    // Cache non-trivial values to variables to prevent repeated look-ups.
                +    var startVar = argument0;
                +    if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) {
                +      startVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +          variable0 + '_start', Blockly.Variables.NAME_TYPE);
                +      code += 'var ' + startVar + ' = ' + argument0 + ';\n';
                +    }
                +    var endVar = argument1;
                +    if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) {
                +      var endVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +          variable0 + '_end', Blockly.Variables.NAME_TYPE);
                +      code += 'var ' + endVar + ' = ' + argument1 + ';\n';
                +    }
                +    // Determine loop direction at start, in case one of the bounds
                +    // changes during loop execution.
                +    var incVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +        variable0 + '_inc', Blockly.Variables.NAME_TYPE);
                +    code += 'var ' + incVar + ' = ';
                +    if (Blockly.isNumber(increment)) {
                +      code += Math.abs(increment) + ';\n';
                +    } else {
                +      code += 'Math.abs(' + increment + ');\n';
                +    }
                +    code += 'if (' + startVar + ' > ' + endVar + ') {\n';
                +    code += Blockly.JavaScript.INDENT + incVar + ' = -' + incVar + ';\n';
                +    code += '}\n';
                +    code += 'for (' + variable0 + ' = ' + startVar + '; ' +
                +        incVar + ' >= 0 ? ' +
                +        variable0 + ' <= ' + endVar + ' : ' +
                +        variable0 + ' >= ' + endVar + '; ' +
                +        variable0 + ' += ' + incVar + ') {\n' +
                +        branch + '}\n';
                +  }
                +  return code;
                +};
                +
                +Blockly.JavaScript['controls_forEach'] = function(block) {
                +  // For each loop.
                +  var variable0 = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'LIST',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '[]';
                +  var branch = Blockly.JavaScript.statementToCode(block, 'DO');
                +  branch = Blockly.JavaScript.addLoopTrap(branch, block.id);
                +  var code = '';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  var listVar = argument0;
                +  if (!argument0.match(/^\w+$/)) {
                +    listVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +        variable0 + '_list', Blockly.Variables.NAME_TYPE);
                +    code += 'var ' + listVar + ' = ' + argument0 + ';\n';
                +  }
                +  var indexVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +      variable0 + '_index', Blockly.Variables.NAME_TYPE);
                +  branch = Blockly.JavaScript.INDENT + variable0 + ' = ' +
                +      listVar + '[' + indexVar + '];\n' + branch;
                +  code += 'for (var ' + indexVar + ' in ' + listVar + ') {\n' + branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.JavaScript['controls_flow_statements'] = function(block) {
                +  // Flow statements: continue, break.
                +  switch (block.getFieldValue('FLOW')) {
                +    case 'BREAK':
                +      return 'break;\n';
                +    case 'CONTINUE':
                +      return 'continue;\n';
                +  }
                +  throw 'Unknown flow statement.';
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/math.js b/blockly/webif/static/blockly/generators/javascript/math.js
                new file mode 100644
                index 000000000..a31b94392
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/math.js
                @@ -0,0 +1,411 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for math blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.math');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['math_number'] = function(block) {
                +  // Numeric value.
                +  var code = parseFloat(block.getFieldValue('NUM'));
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['math_arithmetic'] = function(block) {
                +  // Basic arithmetic operators, and power.
                +  var OPERATORS = {
                +    'ADD': [' + ', Blockly.JavaScript.ORDER_ADDITION],
                +    'MINUS': [' - ', Blockly.JavaScript.ORDER_SUBTRACTION],
                +    'MULTIPLY': [' * ', Blockly.JavaScript.ORDER_MULTIPLICATION],
                +    'DIVIDE': [' / ', Blockly.JavaScript.ORDER_DIVISION],
                +    'POWER': [null, Blockly.JavaScript.ORDER_COMMA]  // Handle power separately.
                +  };
                +  var tuple = OPERATORS[block.getFieldValue('OP')];
                +  var operator = tuple[0];
                +  var order = tuple[1];
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'B', order) || '0';
                +  var code;
                +  // Power in JavaScript requires a special case since it has no operator.
                +  if (!operator) {
                +    code = 'Math.pow(' + argument0 + ', ' + argument1 + ')';
                +    return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +  code = argument0 + operator + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.JavaScript['math_single'] = function(block) {
                +  // Math operators with single operand.
                +  var operator = block.getFieldValue('OP');
                +  var code;
                +  var arg;
                +  if (operator == 'NEG') {
                +    // Negation is a special case given its different operator precedence.
                +    arg = Blockly.JavaScript.valueToCode(block, 'NUM',
                +        Blockly.JavaScript.ORDER_UNARY_NEGATION) || '0';
                +    if (arg[0] == '-') {
                +      // --3 is not legal in JS.
                +      arg = ' ' + arg;
                +    }
                +    code = '-' + arg;
                +    return [code, Blockly.JavaScript.ORDER_UNARY_NEGATION];
                +  }
                +  if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
                +    arg = Blockly.JavaScript.valueToCode(block, 'NUM',
                +        Blockly.JavaScript.ORDER_DIVISION) || '0';
                +  } else {
                +    arg = Blockly.JavaScript.valueToCode(block, 'NUM',
                +        Blockly.JavaScript.ORDER_NONE) || '0';
                +  }
                +  // First, handle cases which generate values that don't need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'ABS':
                +      code = 'Math.abs(' + arg + ')';
                +      break;
                +    case 'ROOT':
                +      code = 'Math.sqrt(' + arg + ')';
                +      break;
                +    case 'LN':
                +      code = 'Math.log(' + arg + ')';
                +      break;
                +    case 'EXP':
                +      code = 'Math.exp(' + arg + ')';
                +      break;
                +    case 'POW10':
                +      code = 'Math.pow(10,' + arg + ')';
                +      break;
                +    case 'ROUND':
                +      code = 'Math.round(' + arg + ')';
                +      break;
                +    case 'ROUNDUP':
                +      code = 'Math.ceil(' + arg + ')';
                +      break;
                +    case 'ROUNDDOWN':
                +      code = 'Math.floor(' + arg + ')';
                +      break;
                +    case 'SIN':
                +      code = 'Math.sin(' + arg + ' / 180 * Math.PI)';
                +      break;
                +    case 'COS':
                +      code = 'Math.cos(' + arg + ' / 180 * Math.PI)';
                +      break;
                +    case 'TAN':
                +      code = 'Math.tan(' + arg + ' / 180 * Math.PI)';
                +      break;
                +  }
                +  if (code) {
                +    return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +  // Second, handle cases which generate values that may need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'LOG10':
                +      code = 'Math.log(' + arg + ') / Math.log(10)';
                +      break;
                +    case 'ASIN':
                +      code = 'Math.asin(' + arg + ') / Math.PI * 180';
                +      break;
                +    case 'ACOS':
                +      code = 'Math.acos(' + arg + ') / Math.PI * 180';
                +      break;
                +    case 'ATAN':
                +      code = 'Math.atan(' + arg + ') / Math.PI * 180';
                +      break;
                +    default:
                +      throw 'Unknown math operator: ' + operator;
                +  }
                +  return [code, Blockly.JavaScript.ORDER_DIVISION];
                +};
                +
                +Blockly.JavaScript['math_constant'] = function(block) {
                +  // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  var CONSTANTS = {
                +    'PI': ['Math.PI', Blockly.JavaScript.ORDER_MEMBER],
                +    'E': ['Math.E', Blockly.JavaScript.ORDER_MEMBER],
                +    'GOLDEN_RATIO':
                +        ['(1 + Math.sqrt(5)) / 2', Blockly.JavaScript.ORDER_DIVISION],
                +    'SQRT2': ['Math.SQRT2', Blockly.JavaScript.ORDER_MEMBER],
                +    'SQRT1_2': ['Math.SQRT1_2', Blockly.JavaScript.ORDER_MEMBER],
                +    'INFINITY': ['Infinity', Blockly.JavaScript.ORDER_ATOMIC]
                +  };
                +  return CONSTANTS[block.getFieldValue('CONSTANT')];
                +};
                +
                +Blockly.JavaScript['math_number_property'] = function(block) {
                +  // Check if a number is even, odd, prime, whole, positive, or negative
                +  // or if it is divisible by certain number. Returns true or false.
                +  var number_to_check = Blockly.JavaScript.valueToCode(block, 'NUMBER_TO_CHECK',
                +      Blockly.JavaScript.ORDER_MODULUS) || '0';
                +  var dropdown_property = block.getFieldValue('PROPERTY');
                +  var code;
                +  if (dropdown_property == 'PRIME') {
                +    // Prime is a special case as it is not a one-liner test.
                +    var functionName = Blockly.JavaScript.provideFunction_(
                +        'mathIsPrime',
                +        ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
                +         '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
                +         '  if (n == 2 || n == 3) {',
                +         '    return true;',
                +         '  }',
                +         '  // False if n is NaN, negative, is 1, or not whole.',
                +         '  // And false if n is divisible by 2 or 3.',
                +         '  if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 ||' +
                +            ' n % 3 == 0) {',
                +         '    return false;',
                +         '  }',
                +         '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
                +         '  for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {',
                +         '    if (n % (x - 1) == 0 || n % (x + 1) == 0) {',
                +         '      return false;',
                +         '    }',
                +         '  }',
                +         '  return true;',
                +         '}']);
                +    code = functionName + '(' + number_to_check + ')';
                +    return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +  switch (dropdown_property) {
                +    case 'EVEN':
                +      code = number_to_check + ' % 2 == 0';
                +      break;
                +    case 'ODD':
                +      code = number_to_check + ' % 2 == 1';
                +      break;
                +    case 'WHOLE':
                +      code = number_to_check + ' % 1 == 0';
                +      break;
                +    case 'POSITIVE':
                +      code = number_to_check + ' > 0';
                +      break;
                +    case 'NEGATIVE':
                +      code = number_to_check + ' < 0';
                +      break;
                +    case 'DIVISIBLE_BY':
                +      var divisor = Blockly.JavaScript.valueToCode(block, 'DIVISOR',
                +          Blockly.JavaScript.ORDER_MODULUS) || '0';
                +      code = number_to_check + ' % ' + divisor + ' == 0';
                +      break;
                +  }
                +  return [code, Blockly.JavaScript.ORDER_EQUALITY];
                +};
                +
                +Blockly.JavaScript['math_change'] = function(block) {
                +  // Add to a variable in place.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'DELTA',
                +      Blockly.JavaScript.ORDER_ADDITION) || '0';
                +  var varName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  return varName + ' = (typeof ' + varName + ' == \'number\' ? ' + varName +
                +      ' : 0) + ' + argument0 + ';\n';
                +};
                +
                +// Rounding functions have a single operand.
                +Blockly.JavaScript['math_round'] = Blockly.JavaScript['math_single'];
                +// Trigonometry functions have a single operand.
                +Blockly.JavaScript['math_trig'] = Blockly.JavaScript['math_single'];
                +
                +Blockly.JavaScript['math_on_list'] = function(block) {
                +  // Math functions for lists.
                +  var func = block.getFieldValue('OP');
                +  var list, code;
                +  switch (func) {
                +    case 'SUM':
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_MEMBER) || '[]';
                +      code = list + '.reduce(function(x, y) {return x + y;})';
                +      break;
                +    case 'MIN':
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_COMMA) || '[]';
                +      code = 'Math.min.apply(null, ' + list + ')';
                +      break;
                +    case 'MAX':
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_COMMA) || '[]';
                +      code = 'Math.max.apply(null, ' + list + ')';
                +      break;
                +    case 'AVERAGE':
                +      // mathMean([null,null,1,3]) == 2.0.
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'mathMean',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(myList) {',
                +            '  return myList.reduce(function(x, y) {return x + y;}) / ' +
                +                  'myList.length;',
                +            '}']);
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MEDIAN':
                +      // mathMedian([null,null,1,3]) == 2.0.
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'mathMedian',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(myList) {',
                +            '  var localList = myList.filter(function (x) ' +
                +              '{return typeof x == \'number\';});',
                +            '  if (!localList.length) return null;',
                +            '  localList.sort(function(a, b) {return b - a;});',
                +            '  if (localList.length % 2 == 0) {',
                +            '    return (localList[localList.length / 2 - 1] + ' +
                +              'localList[localList.length / 2]) / 2;',
                +            '  } else {',
                +            '    return localList[(localList.length - 1) / 2];',
                +            '  }',
                +            '}']);
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MODE':
                +      // As a list of numbers can contain more than one mode,
                +      // the returned result is provided as an array.
                +      // Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'mathModes',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(values) {',
                +            '  var modes = [];',
                +            '  var counts = [];',
                +            '  var maxCount = 0;',
                +            '  for (var i = 0; i < values.length; i++) {',
                +            '    var value = values[i];',
                +            '    var found = false;',
                +            '    var thisCount;',
                +            '    for (var j = 0; j < counts.length; j++) {',
                +            '      if (counts[j][0] === value) {',
                +            '        thisCount = ++counts[j][1];',
                +            '        found = true;',
                +            '        break;',
                +            '      }',
                +            '    }',
                +            '    if (!found) {',
                +            '      counts.push([value, 1]);',
                +            '      thisCount = 1;',
                +            '    }',
                +            '    maxCount = Math.max(thisCount, maxCount);',
                +            '  }',
                +            '  for (var j = 0; j < counts.length; j++) {',
                +            '    if (counts[j][1] == maxCount) {',
                +            '        modes.push(counts[j][0]);',
                +            '    }',
                +            '  }',
                +            '  return modes;',
                +            '}']);
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'STD_DEV':
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'mathStandardDeviation',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(numbers) {',
                +            '  var n = numbers.length;',
                +            '  if (!n) return null;',
                +            '  var mean = numbers.reduce(function(x, y) {return x + y;}) / n;',
                +            '  var variance = 0;',
                +            '  for (var j = 0; j < n; j++) {',
                +            '    variance += Math.pow(numbers[j] - mean, 2);',
                +            '  }',
                +            '  variance = variance / n;',
                +            '  return Math.sqrt(variance);',
                +            '}']);
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'RANDOM':
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'mathRandomList',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(list) {',
                +            '  var x = Math.floor(Math.random() * list.length);',
                +            '  return list[x];',
                +            '}']);
                +      list = Blockly.JavaScript.valueToCode(block, 'LIST',
                +          Blockly.JavaScript.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    default:
                +      throw 'Unknown operator: ' + func;
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['math_modulo'] = function(block) {
                +  // Remainder computation.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'DIVIDEND',
                +      Blockly.JavaScript.ORDER_MODULUS) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'DIVISOR',
                +      Blockly.JavaScript.ORDER_MODULUS) || '0';
                +  var code = argument0 + ' % ' + argument1;
                +  return [code, Blockly.JavaScript.ORDER_MODULUS];
                +};
                +
                +Blockly.JavaScript['math_constrain'] = function(block) {
                +  // Constrain a number between two limits.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_COMMA) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'LOW',
                +      Blockly.JavaScript.ORDER_COMMA) || '0';
                +  var argument2 = Blockly.JavaScript.valueToCode(block, 'HIGH',
                +      Blockly.JavaScript.ORDER_COMMA) || 'Infinity';
                +  var code = 'Math.min(Math.max(' + argument0 + ', ' + argument1 + '), ' +
                +      argument2 + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['math_random_int'] = function(block) {
                +  // Random integer between [X] and [Y].
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'FROM',
                +      Blockly.JavaScript.ORDER_COMMA) || '0';
                +  var argument1 = Blockly.JavaScript.valueToCode(block, 'TO',
                +      Blockly.JavaScript.ORDER_COMMA) || '0';
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'mathRandomInt',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(a, b) {',
                +       '  if (a > b) {',
                +       '    // Swap a and b to ensure a is smaller.',
                +       '    var c = a;',
                +       '    a = b;',
                +       '    b = c;',
                +       '  }',
                +       '  return Math.floor(Math.random() * (b - a + 1) + a);',
                +       '}']);
                +  var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['math_random_float'] = function(block) {
                +  // Random fraction between 0 and 1.
                +  return ['Math.random()', Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/procedures.js b/blockly/webif/static/blockly/generators/javascript/procedures.js
                new file mode 100644
                index 000000000..04845f9bd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/procedures.js
                @@ -0,0 +1,109 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for procedure blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.procedures');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['procedures_defreturn'] = function(block) {
                +  // Define a procedure with a return value.
                +  var funcName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var branch = Blockly.JavaScript.statementToCode(block, 'STACK');
                +  if (Blockly.JavaScript.STATEMENT_PREFIX) {
                +    branch = Blockly.JavaScript.prefixLines(
                +        Blockly.JavaScript.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + block.id + '\''), Blockly.JavaScript.INDENT) + branch;
                +  }
                +  if (Blockly.JavaScript.INFINITE_LOOP_TRAP) {
                +    branch = Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,
                +        '\'' + block.id + '\'') + branch;
                +  }
                +  var returnValue = Blockly.JavaScript.valueToCode(block, 'RETURN',
                +      Blockly.JavaScript.ORDER_NONE) || '';
                +  if (returnValue) {
                +    returnValue = '  return ' + returnValue + ';\n';
                +  }
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.JavaScript.variableDB_.getName(block.arguments_[i],
                +        Blockly.Variables.NAME_TYPE);
                +  }
                +  var code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' +
                +      branch + returnValue + '}';
                +  code = Blockly.JavaScript.scrub_(block, code);
                +  // Add % so as not to collide with helper functions in definitions list.
                +  Blockly.JavaScript.definitions_['%' + funcName] = code;
                +  return null;
                +};
                +
                +// Defining a procedure without a return value uses the same generator as
                +// a procedure with a return value.
                +Blockly.JavaScript['procedures_defnoreturn'] =
                +    Blockly.JavaScript['procedures_defreturn'];
                +
                +Blockly.JavaScript['procedures_callreturn'] = function(block) {
                +  // Call a procedure with a return value.
                +  var funcName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.JavaScript.valueToCode(block, 'ARG' + i,
                +        Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')';
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['procedures_callnoreturn'] = function(block) {
                +  // Call a procedure with no return value.
                +  var funcName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.JavaScript.valueToCode(block, 'ARG' + i,
                +        Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ');\n';
                +  return code;
                +};
                +
                +Blockly.JavaScript['procedures_ifreturn'] = function(block) {
                +  // Conditionally return value from a procedure.
                +  var condition = Blockly.JavaScript.valueToCode(block, 'CONDITION',
                +      Blockly.JavaScript.ORDER_NONE) || 'false';
                +  var code = 'if (' + condition + ') {\n';
                +  if (block.hasReturnValue_) {
                +    var value = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +        Blockly.JavaScript.ORDER_NONE) || 'null';
                +    code += '  return ' + value + ';\n';
                +  } else {
                +    code += '  return;\n';
                +  }
                +  code += '}\n';
                +  return code;
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/text.js b/blockly/webif/static/blockly/generators/javascript/text.js
                new file mode 100644
                index 000000000..9e2a375a2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/text.js
                @@ -0,0 +1,352 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for text blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.texts');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['text'] = function(block) {
                +  // Text value.
                +  var code = Blockly.JavaScript.quote_(block.getFieldValue('TEXT'));
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['text_join'] = function(block) {
                +  // Create a string made up of any number of elements of any type.
                +  switch (block.itemCount_) {
                +    case 0:
                +      return ['\'\'', Blockly.JavaScript.ORDER_ATOMIC];
                +    case 1:
                +      var element = Blockly.JavaScript.valueToCode(block, 'ADD0',
                +          Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +      var code = 'String(' + element + ')';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +    case 2:
                +      var element0 = Blockly.JavaScript.valueToCode(block, 'ADD0',
                +          Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +      var element1 = Blockly.JavaScript.valueToCode(block, 'ADD1',
                +          Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +      var code = 'String(' + element0 + ') + String(' + element1 + ')';
                +      return [code, Blockly.JavaScript.ORDER_ADDITION];
                +    default:
                +      var elements = new Array(block.itemCount_);
                +      for (var i = 0; i < block.itemCount_; i++) {
                +        elements[i] = Blockly.JavaScript.valueToCode(block, 'ADD' + i,
                +            Blockly.JavaScript.ORDER_COMMA) || '\'\'';
                +      }
                +      var code = '[' + elements.join(',') + '].join(\'\')';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +};
                +
                +Blockly.JavaScript['text_append'] = function(block) {
                +  // Append to a variable in place.
                +  var varName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var value = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  return varName + ' = String(' + varName + ') + String(' + value + ');\n';
                +};
                +
                +Blockly.JavaScript['text_length'] = function(block) {
                +  // String or array length.
                +  var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
                +  return [text + '.length', Blockly.JavaScript.ORDER_MEMBER];
                +};
                +
                +Blockly.JavaScript['text_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  return ['!' + text + '.length', Blockly.JavaScript.ORDER_LOGICAL_NOT];
                +};
                +
                +Blockly.JavaScript['text_indexOf'] = function(block) {
                +  // Search the text for a substring.
                +  var operator = block.getFieldValue('END') == 'FIRST' ?
                +      'indexOf' : 'lastIndexOf';
                +  var substring = Blockly.JavaScript.valueToCode(block, 'FIND',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  var code = text + '.' + operator + '(' + substring + ')';
                +  // Adjust index if using one-based indices.
                +  if (block.workspace.options.oneBasedIndex) {
                +    return [code + ' + 1', Blockly.JavaScript.ORDER_ADDITION];
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['text_charAt'] = function(block) {
                +  // Get letter at index.
                +  // Note: Until January 2013 this block did not have the WHERE input.
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var textOrder = (where == 'RANDOM') ? Blockly.JavaScript.ORDER_NONE :
                +      Blockly.JavaScript.ORDER_MEMBER;
                +  var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      textOrder) || '\'\'';
                +  switch (where) {
                +    case 'FIRST':
                +      var code = text + '.charAt(0)';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +    case 'LAST':
                +      var code = text + '.slice(-1)';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +    case 'FROM_START':
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT');
                +      // Adjust index if using one-based indices.
                +      var code = text + '.charAt(' + at + ')';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +    case 'FROM_END':
                +      var at = Blockly.JavaScript.getAdjusted(block, 'AT', 1, true);
                +      var code = text + '.slice(' + at + ').charAt(0)';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +    case 'RANDOM':
                +      var functionName = Blockly.JavaScript.provideFunction_(
                +          'textRandomLetter',
                +          ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +              '(text) {',
                +           '  var x = Math.floor(Math.random() * text.length);',
                +           '  return text[x];',
                +           '}']);
                +      var code = functionName + '(' + text + ')';
                +      return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +  throw 'Unhandled option (text_charAt).';
                +};
                +
                +/**
                + * Returns an expression calculating the index into a string.
                + * @private
                + * @param {string} stringName Name of the string, used to calculate length.
                + * @param {string} where The method of indexing, selected by dropdown in Blockly
                + * @param {string=} opt_at The optional offset when indexing from start/end.
                + * @return {string} Index expression.
                + */
                +Blockly.JavaScript.text.getIndex_ = function(stringName, where, opt_at) {
                +  if (where == 'FIRST') {
                +    return '0';
                +  } else if (where == 'FROM_END') {
                +    return stringName + '.length - 1 - ' + opt_at;
                +  } else if (where == 'LAST') {
                +    return stringName + '.length - 1';
                +  } else {
                +    return opt_at;
                +  }
                +};
                +
                +Blockly.JavaScript['text_getSubstring'] = function(block) {
                +  // Get substring.
                +  var text = Blockly.JavaScript.valueToCode(block, 'STRING',
                +      Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (where1 == 'FIRST' && where2 == 'LAST') {
                +    var code = text;
                +  } else if (text.match(/^'?\w+'?$/) ||
                +      (where1 != 'FROM_END' && where1 != 'LAST' &&
                +      where2 != 'FROM_END' && where2 != 'LAST')) {
                +    // If the text is a variable or literal or doesn't require a call for
                +    // length, don't generate a helper function.
                +    switch (where1) {
                +      case 'FROM_START':
                +        var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
                +        break;
                +      case 'FROM_END':
                +        var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1', 1, false,
                +            Blockly.JavaScript.ORDER_SUBTRACTION);
                +        at1 = text + '.length - ' + at1;
                +        break;
                +      case 'FIRST':
                +        var at1 = '0';
                +        break;
                +      default:
                +        throw 'Unhandled option (text_getSubstring).';
                +    }
                +    switch (where2) {
                +      case 'FROM_START':
                +        var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 1);
                +        break;
                +      case 'FROM_END':
                +        var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.JavaScript.ORDER_SUBTRACTION);
                +        at2 = text + '.length - ' + at2;
                +        break;
                +      case 'LAST':
                +        var at2 = text + '.length';
                +        break;
                +      default:
                +        throw 'Unhandled option (text_getSubstring).';
                +    }
                +    code = text + '.slice(' + at1 + ', ' + at2 + ')';
                +  } else {
                +    var at1 = Blockly.JavaScript.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.JavaScript.getAdjusted(block, 'AT2');
                +    var getIndex_ = Blockly.JavaScript.text.getIndex_;
                +    var wherePascalCase = {'FIRST': 'First', 'LAST': 'Last',
                +      'FROM_START': 'FromStart', 'FROM_END': 'FromEnd'};
                +    var functionName = Blockly.JavaScript.provideFunction_(
                +        'subsequence' + wherePascalCase[where1] + wherePascalCase[where2],
                +        ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +        '(sequence' +
                +        // The value for 'FROM_END' and'FROM_START' depends on `at` so
                +        // we add it as a parameter.
                +        ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', at1' : '') +
                +        ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', at2' : '') +
                +        ') {',
                +          '  var start = ' + getIndex_('sequence', where1, 'at1') + ';',
                +          '  var end = ' + getIndex_('sequence', where2, 'at2') + ' + 1;',
                +          '  return sequence.slice(start, end);',
                +          '}']);
                +    var code = functionName + '(' + text +
                +        // The value for 'FROM_END' and 'FROM_START' depends on `at` so we
                +        // pass it.
                +        ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
                +        ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
                +        ')';
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['text_changeCase'] = function(block) {
                +  // Change capitalization.
                +  var OPERATORS = {
                +    'UPPERCASE': '.toUpperCase()',
                +    'LOWERCASE': '.toLowerCase()',
                +    'TITLECASE': null
                +  };
                +  var operator = OPERATORS[block.getFieldValue('CASE')];
                +  var textOrder = operator ? Blockly.JavaScript.ORDER_MEMBER :
                +      Blockly.JavaScript.ORDER_NONE;
                +  var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      textOrder) || '\'\'';
                +  if (operator) {
                +    // Upper and lower case are functions built into JavaScript.
                +    var code = text + operator;
                +  } else {
                +    // Title case is not a native JavaScript function.  Define one.
                +    var functionName = Blockly.JavaScript.provideFunction_(
                +        'textToTitleCase',
                +        ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(str) {',
                +         '  return str.replace(/\\S+/g,',
                +         '      function(txt) {return txt[0].toUpperCase() + ' +
                +            'txt.substring(1).toLowerCase();});',
                +         '}']);
                +    var code = functionName + '(' + text + ')';
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['text_trim'] = function(block) {
                +  // Trim spaces.
                +  var OPERATORS = {
                +    'LEFT': ".replace(/^[\\s\\xa0]+/, '')",
                +    'RIGHT': ".replace(/[\\s\\xa0]+$/, '')",
                +    'BOTH': '.trim()'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('MODE')];
                +  var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  return [text + operator, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['text_print'] = function(block) {
                +  // Print statement.
                +  var msg = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  return 'window.alert(' + msg + ');\n';
                +};
                +
                +Blockly.JavaScript['text_prompt_ext'] = function(block) {
                +  // Prompt function.
                +  if (block.getField('TEXT')) {
                +    // Internal message.
                +    var msg = Blockly.JavaScript.quote_(block.getFieldValue('TEXT'));
                +  } else {
                +    // External message.
                +    var msg = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +        Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  }
                +  var code = 'window.prompt(' + msg + ')';
                +  var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
                +  if (toNumber) {
                +    code = 'parseFloat(' + code + ')';
                +  }
                +  return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.JavaScript['text_prompt'] = Blockly.JavaScript['text_prompt_ext'];
                +
                +Blockly.JavaScript['text_count'] = function(block) {
                +  var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  var sub = Blockly.JavaScript.valueToCode(block, 'SUB',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'textCount',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(haystack, needle) {',
                +       '  if (needle.length === 0) {',
                +       '    return haystack.length + 1;',
                +       '  } else {',
                +       '    return haystack.split(needle).length - 1;',
                +       '  }',
                +       '}']);
                +  var code = functionName + '(' + text + ', ' + sub + ')';
                +  return [code, Blockly.JavaScript.ORDER_SUBTRACTION];
                +};
                +
                +Blockly.JavaScript['text_replace'] = function(block) {
                +  var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  var from = Blockly.JavaScript.valueToCode(block, 'FROM',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  var to = Blockly.JavaScript.valueToCode(block, 'TO',
                +      Blockly.JavaScript.ORDER_NONE) || '\'\'';
                +  // The regex escaping code below is taken from the implementation of
                +  // goog.string.regExpEscape.
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'textReplace',
                +      ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(haystack, needle, replacement) {',
                +       '  needle = ' +
                +           'needle.replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g,"\\\\$1")',
                +       '                 .replace(/\\x08/g,"\\\\x08");',
                +       '  return haystack.replace(new RegExp(needle, \'g\'), replacement);',
                +       '}']);
                +  var code = functionName + '(' + text + ', ' + from + ', ' + to + ')';
                +  return [code, Blockly.JavaScript.ORDER_MEMBER];
                +};
                +
                +Blockly.JavaScript['text_reverse'] = function(block) {
                +  var text = Blockly.JavaScript.valueToCode(block, 'TEXT',
                +      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
                +  var code = text + '.split(\'\').reverse().join(\'\')';
                +  return [code, Blockly.JavaScript.ORDER_MEMBER];
                +};
                diff --git a/blockly/webif/static/blockly/generators/javascript/variables.js b/blockly/webif/static/blockly/generators/javascript/variables.js
                new file mode 100644
                index 000000000..fe0135b12
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/javascript/variables.js
                @@ -0,0 +1,46 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for variable blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.JavaScript.variables');
                +
                +goog.require('Blockly.JavaScript');
                +
                +
                +Blockly.JavaScript['variables_get'] = function(block) {
                +  // Variable getter.
                +  var code = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return [code, Blockly.JavaScript.ORDER_ATOMIC];
                +};
                +
                +Blockly.JavaScript['variables_set'] = function(block) {
                +  // Variable setter.
                +  var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
                +      Blockly.JavaScript.ORDER_ASSIGNMENT) || '0';
                +  var varName = Blockly.JavaScript.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  return varName + ' = ' + argument0 + ';\n';
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua.js b/blockly/webif/static/blockly/generators/lua.js
                new file mode 100644
                index 000000000..1118a31e4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua.js
                @@ -0,0 +1,194 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Helper functions for generating Lua for blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + * Based on Ellen Spertus's blocky-lua project.
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua');
                +
                +goog.require('Blockly.Generator');
                +
                +
                +/**
                + * Lua code generator.
                + * @type {!Blockly.Generator}
                + */
                +Blockly.Lua = new Blockly.Generator('Lua');
                +
                +/**
                + * List of illegal variable names.
                + * This is not intended to be a security feature.  Blockly is 100% client-side,
                + * so bypassing this list is trivial.  This is intended to prevent users from
                + * accidentally clobbering a built-in object or function.
                + * @private
                + */
                +Blockly.Lua.addReservedWords(
                +    // Special character
                +    '_,' +
                +    // From theoriginalbit's script:
                +    // https://github.com/espertus/blockly-lua/issues/6
                +    '__inext,assert,bit,colors,colours,coroutine,disk,dofile,error,fs,' +
                +    'fetfenv,getmetatable,gps,help,io,ipairs,keys,loadfile,loadstring,math,' +
                +    'native,next,os,paintutils,pairs,parallel,pcall,peripheral,print,' +
                +    'printError,rawequal,rawget,rawset,read,rednet,redstone,rs,select,' +
                +    'setfenv,setmetatable,sleep,string,table,term,textutils,tonumber,' +
                +    'tostring,turtle,type,unpack,vector,write,xpcall,_VERSION,__indext,' +
                +    // Not included in the script, probably because it wasn't enabled:
                +    'HTTP,' +
                +    // Keywords (http://www.lua.org/pil/1.3.html).
                +    'and,break,do,else,elseif,end,false,for,function,if,in,local,nil,not,or,' +
                +    'repeat,return,then,true,until,while,' +
                +    // Metamethods (http://www.lua.org/manual/5.2/manual.html).
                +    'add,sub,mul,div,mod,pow,unm,concat,len,eq,lt,le,index,newindex,call,' +
                +    // Basic functions (http://www.lua.org/manual/5.2/manual.html, section 6.1).
                +    'assert,collectgarbage,dofile,error,_G,getmetatable,inpairs,load,' +
                +    'loadfile,next,pairs,pcall,print,rawequal,rawget,rawlen,rawset,select,' +
                +    'setmetatable,tonumber,tostring,type,_VERSION,xpcall,' +
                +    // Modules (http://www.lua.org/manual/5.2/manual.html, section 6.3).
                +    'require,package,string,table,math,bit32,io,file,os,debug'
                +);
                +
                +/**
                + * Order of operation ENUMs.
                + * http://www.lua.org/manual/5.3/manual.html#3.4.8
                + */
                +Blockly.Lua.ORDER_ATOMIC = 0;          // literals
                +// The next level was not explicit in documentation and inferred by Ellen.
                +Blockly.Lua.ORDER_HIGH = 1;            // Function calls, tables[]
                +Blockly.Lua.ORDER_EXPONENTIATION = 2;  // ^
                +Blockly.Lua.ORDER_UNARY = 3;           // not # - ~
                +Blockly.Lua.ORDER_MULTIPLICATIVE = 4;  // * / %
                +Blockly.Lua.ORDER_ADDITIVE = 5;        // + -
                +Blockly.Lua.ORDER_CONCATENATION = 6;   // ..
                +Blockly.Lua.ORDER_RELATIONAL = 7;      // < > <=  >= ~= ==
                +Blockly.Lua.ORDER_AND = 8;             // and
                +Blockly.Lua.ORDER_OR = 9;              // or
                +Blockly.Lua.ORDER_NONE = 99;
                +
                +/**
                + * Note: Lua is not supporting zero-indexing since the language itself is
                + * one-indexed, so the generator does not repoct the oneBasedIndex configuration
                + * option used for lists and text.
                + */
                +
                +/**
                + * Initialise the database of variable names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.Lua.init = function(workspace) {
                +  // Create a dictionary of definitions to be printed before the code.
                +  Blockly.Lua.definitions_ = Object.create(null);
                +  // Create a dictionary mapping desired function names in definitions_
                +  // to actual function names (to avoid collisions with user functions).
                +  Blockly.Lua.functionNames_ = Object.create(null);
                +
                +  if (!Blockly.Lua.variableDB_) {
                +    Blockly.Lua.variableDB_ =
                +        new Blockly.Names(Blockly.Lua.RESERVED_WORDS_);
                +  } else {
                +    Blockly.Lua.variableDB_.reset();
                +  }
                +};
                +
                +/**
                + * Prepend the generated code with the variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.Lua.finish = function(code) {
                +  // Convert the definitions dictionary into a list.
                +  var definitions = [];
                +  for (var name in Blockly.Lua.definitions_) {
                +    definitions.push(Blockly.Lua.definitions_[name]);
                +  }
                +  // Clean up temporary data.
                +  delete Blockly.Lua.definitions_;
                +  delete Blockly.Lua.functionNames_;
                +  Blockly.Lua.variableDB_.reset();
                +  return definitions.join('\n\n') + '\n\n\n' + code;
                +};
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything. In Lua, an expression is not a legal statement, so we must assign
                + * the value to the (conventionally ignored) _.
                + * http://lua-users.org/wiki/ExpressionsAsStatements
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.Lua.scrubNakedValue = function(line) {
                +  return 'local _ = ' + line + '\n';
                +};
                +
                +/**
                + * Encode a string as a properly escaped Lua string, complete with
                + * quotes.
                + * @param {string} string Text to encode.
                + * @return {string} Lua string.
                + * @private
                + */
                +Blockly.Lua.quote_ = function(string) {
                +  string = string.replace(/\\/g, '\\\\')
                +                 .replace(/\n/g, '\\\n')
                +                 .replace(/'/g, '\\\'');
                +  return '\'' + string + '\'';
                +};
                +
                +/**
                + * Common tasks for generating Lua from blocks.
                + * Handles comments for the specified block and any connected value blocks.
                + * Calls any statements following this block.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The Lua code created for this block.
                + * @return {string} Lua code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.Lua.scrub_ = function(block, code) {
                +  var commentCode = '';
                +  // Only collect comments for blocks that aren't inline.
                +  if (!block.outputConnection || !block.outputConnection.targetConnection) {
                +    // Collect comment for this block.
                +    var comment = block.getCommentText();
                +    comment = Blockly.utils.wrap(comment, Blockly.Lua.COMMENT_WRAP - 3);
                +    if (comment) {
                +      commentCode += Blockly.Lua.prefixLines(comment, '-- ') + '\n';
                +    }
                +    // Collect comments for all value arguments.
                +    // Don't collect comments for nested statements.
                +    for (var i = 0; i < block.inputList.length; i++) {
                +      if (block.inputList[i].type == Blockly.INPUT_VALUE) {
                +        var childBlock = block.inputList[i].connection.targetBlock();
                +        if (childBlock) {
                +          comment = Blockly.Lua.allNestedComments(childBlock);
                +          if (comment) {
                +            commentCode += Blockly.Lua.prefixLines(comment, '-- ');
                +          }
                +        }
                +      }
                +    }
                +  }
                +  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
                +  var nextCode = Blockly.Lua.blockToCode(nextBlock);
                +  return commentCode + code + nextCode;
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/colour.js b/blockly/webif/static/blockly/generators/lua/colour.js
                new file mode 100644
                index 000000000..9175a9de9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/colour.js
                @@ -0,0 +1,90 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for colour blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.colour');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['colour_picker'] = function(block) {
                +  // Colour picker.
                +  var code = '\'' + block.getFieldValue('COLOUR') + '\'';
                +  return [code, Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['colour_random'] = function(block) {
                +  // Generate a random colour.
                +  var code = 'string.format("#%06x", math.random(0, 2^24 - 1))';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['colour_rgb'] = function(block) {
                +  // Compose a colour from RGB components expressed as percentages.
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'colour_rgb',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b)',
                +       '  r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)',
                +       '  g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)',
                +       '  b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)',
                +       '  return string.format("#%02x%02x%02x", r, g, b)',
                +       'end']);
                +  var r = Blockly.Lua.valueToCode(block, 'RED',
                +      Blockly.Lua.ORDER_NONE) || 0;
                +  var g = Blockly.Lua.valueToCode(block, 'GREEN',
                +      Blockly.Lua.ORDER_NONE) || 0;
                +  var b = Blockly.Lua.valueToCode(block, 'BLUE',
                +      Blockly.Lua.ORDER_NONE) || 0;
                +  var code = functionName + '(' + r + ', ' + g + ', ' + b + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['colour_blend'] = function(block) {
                +  // Blend two colours together.
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'colour_blend',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +           '(colour1, colour2, ratio)',
                +       '  local r1 = tonumber(string.sub(colour1, 2, 3), 16)',
                +       '  local r2 = tonumber(string.sub(colour2, 2, 3), 16)',
                +       '  local g1 = tonumber(string.sub(colour1, 4, 5), 16)',
                +       '  local g2 = tonumber(string.sub(colour2, 4, 5), 16)',
                +       '  local b1 = tonumber(string.sub(colour1, 6, 7), 16)',
                +       '  local b2 = tonumber(string.sub(colour2, 6, 7), 16)',
                +       '  local ratio = math.min(1, math.max(0, ratio))',
                +       '  local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)',
                +       '  local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)',
                +       '  local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)',
                +       '  return string.format("#%02x%02x%02x", r, g, b)',
                +       'end']);
                +  var colour1 = Blockly.Lua.valueToCode(block, 'COLOUR1',
                +      Blockly.Lua.ORDER_NONE) || '\'#000000\'';
                +  var colour2 = Blockly.Lua.valueToCode(block, 'COLOUR2',
                +      Blockly.Lua.ORDER_NONE) || '\'#000000\'';
                +  var ratio = Blockly.Lua.valueToCode(block, 'RATIO',
                +      Blockly.Lua.ORDER_NONE) || 0;
                +  var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/lists.js b/blockly/webif/static/blockly/generators/lua/lists.js
                new file mode 100644
                index 000000000..6b9fe006e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/lists.js
                @@ -0,0 +1,382 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for list blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.lists');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['lists_create_empty'] = function(block) {
                +  // Create an empty list.
                +  return ['{}', Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['lists_create_with'] = function(block) {
                +  // Create a list with any number of elements of any type.
                +  var elements = new Array(block.itemCount_);
                +  for (var i = 0; i < block.itemCount_; i++) {
                +    elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i,
                +        Blockly.Lua.ORDER_NONE) || 'None';
                +  }
                +  var code = '{' + elements.join(', ') + '}';
                +  return [code, Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['lists_repeat'] = function(block) {
                +  // Create a list with one element repeated.
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'create_list_repeated',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(item, count)',
                +       '  local t = {}',
                +       '  for i = 1, count do',
                +       '    table.insert(t, item)',
                +       '  end',
                +       '  return t',
                +       'end']);
                +  var element = Blockly.Lua.valueToCode(block, 'ITEM',
                +      Blockly.Lua.ORDER_NONE) || 'None';
                +  var repeatCount = Blockly.Lua.valueToCode(block, 'NUM',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var code = functionName + '(' + element + ', ' + repeatCount + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['lists_length'] = function(block) {
                +  // String or array length.
                +  var list = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_UNARY) || '{}';
                +  return ['#' + list, Blockly.Lua.ORDER_UNARY];
                +};
                +
                +Blockly.Lua['lists_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var list = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_UNARY) || '{}';
                +  var code = '#' + list + ' == 0';
                +  return [code, Blockly.Lua.ORDER_RELATIONAL];
                +};
                +
                +Blockly.Lua['lists_indexOf'] = function(block) {
                +  // Find an item in the list.
                +  var item = Blockly.Lua.valueToCode(block, 'FIND',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var list = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_NONE) || '{}';
                +  if (block.getFieldValue('END') == 'FIRST') {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'first_index',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)',
                +         '  for k, v in ipairs(t) do',
                +         '    if v == elem then',
                +         '      return k',
                +         '    end',
                +         '  end',
                +         '  return 0',
                +         'end']);
                +  } else {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'last_index',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t, elem)',
                +         '  for i = #t, 1, -1 do',
                +         '    if t[i] == elem then',
                +         '      return i',
                +         '    end',
                +         '  end',
                +         '  return 0',
                +         'end']);
                +  }
                +  var code = functionName + '(' + list + ', ' + item + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +/**
                + * Returns an expression calculating the index into a list.
                + * @private
                + * @param {string} listName Name of the list, used to calculate length.
                + * @param {string} where The method of indexing, selected by dropdown in Blockly
                + * @param {string=} opt_at The optional offset when indexing from start/end.
                + * @return {string} Index expression.
                + */
                +Blockly.Lua.lists.getIndex_ = function(listName, where, opt_at) {
                +  if (where == 'FIRST') {
                +    return '1';
                +  } else if (where == 'FROM_END') {
                +    return '#' + listName + ' + 1 - ' + opt_at;
                +  } else if (where == 'LAST') {
                +    return '#' + listName;
                +  } else if (where == 'RANDOM') {
                +    return 'math.random(#' + listName + ')';
                +  } else {
                +    return opt_at;
                +  }
                +};
                +
                +Blockly.Lua['lists_getIndex'] = function(block) {
                +  // Get element at index.
                +  // Note: Until January 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var list = Blockly.Lua.valueToCode(block, 'VALUE', Blockly.Lua.ORDER_HIGH) ||
                +      '{}';
                +  var getIndex_ = Blockly.Lua.lists.getIndex_;
                +
                +  // If `list` would be evaluated more than once (which is the case for LAST,
                +  // FROM_END, and RANDOM) and is non-trivial, make sure to access it only once.
                +  if ((where == 'LAST' || where == 'FROM_END' || where == 'RANDOM') &&
                +      !list.match(/^\w+$/)) {
                +    // `list` is an expression, so we may not evaluate it more than once.
                +    if (mode == 'REMOVE') {
                +      // We can use multiple statements.
                +      var atOrder = (where == 'FROM_END') ? Blockly.Lua.ORDER_ADDITIVE :
                +          Blockly.Lua.ORDER_NONE;
                +      var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
                +      var listVar = Blockly.Lua.variableDB_.getDistinctName(
                +          'tmp_list', Blockly.Variables.NAME_TYPE);
                +      at = getIndex_(listVar, where, at);
                +      var code = listVar + ' = ' + list + '\n' +
                +          'table.remove(' + listVar + ', ' + at + ')\n';
                +      return code;
                +    } else {
                +      // We need to create a procedure to avoid reevaluating values.
                +      var at = Blockly.Lua.valueToCode(block, 'AT', Blockly.Lua.ORDER_NONE) ||
                +          '1';
                +      if (mode == 'GET') {
                +        var functionName = Blockly.Lua.provideFunction_(
                +            'list_get_' + where.toLowerCase(),
                +            ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' +
                +                // The value for 'FROM_END' and'FROM_START' depends on `at` so
                +                // we add it as a parameter.
                +                ((where == 'FROM_END' || where == 'FROM_START') ?
                +                    ', at)' : ')'),
                +             '  return t[' + getIndex_('t', where, 'at') + ']',
                +             'end']);
                +      } else {  //  mode == 'GET_REMOVE'
                +        var functionName = Blockly.Lua.provideFunction_(
                +            'list_remove_' + where.toLowerCase(),
                +            ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t' +
                +                // The value for 'FROM_END' and'FROM_START' depends on `at` so
                +                // we add it as a parameter.
                +                ((where == 'FROM_END' || where == 'FROM_START') ?
                +                    ', at)' : ')'),
                +             '  return table.remove(t, ' + getIndex_('t', where, 'at') + ')',
                +             'end']);
                +      }
                +      var code = functionName + '(' + list +
                +          // The value for 'FROM_END' and 'FROM_START' depends on `at` so we
                +          // pass it.
                +          ((where == 'FROM_END' || where == 'FROM_START') ? ', ' + at : '') +
                +          ')';
                +      return [code, Blockly.Lua.ORDER_HIGH];
                +    }
                +  } else {
                +    // Either `list` is a simple variable, or we only need to refer to `list`
                +    // once.
                +    var atOrder = (mode == 'GET' && where == 'FROM_END') ?
                +        Blockly.Lua.ORDER_ADDITIVE : Blockly.Lua.ORDER_NONE;
                +    var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
                +    at = getIndex_(list, where, at);
                +    if (mode == 'GET') {
                +      var code = list + '[' + at + ']';
                +      return [code, Blockly.Lua.ORDER_HIGH];
                +    } else {
                +      var code = 'table.remove(' + list + ', ' + at + ')';
                +      if (mode == 'GET_REMOVE') {
                +        return [code, Blockly.Lua.ORDER_HIGH];
                +      } else {  // `mode` == 'REMOVE'
                +        return code + '\n';
                +      }
                +    }
                +  }
                +};
                +
                +Blockly.Lua['lists_setIndex'] = function(block) {
                +  // Set element at index.
                +  // Note: Until February 2013 this block did not have MODE or WHERE inputs.
                +  var list = Blockly.Lua.valueToCode(block, 'LIST',
                +      Blockly.Lua.ORDER_HIGH) || '{}';
                +  var mode = block.getFieldValue('MODE') || 'SET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var at = Blockly.Lua.valueToCode(block, 'AT',
                +      Blockly.Lua.ORDER_ADDITIVE) || '1';
                +  var value = Blockly.Lua.valueToCode(block, 'TO',
                +      Blockly.Lua.ORDER_NONE) || 'None';
                +  var getIndex_ = Blockly.Lua.lists.getIndex_;
                +
                +  var code = '';
                +  // If `list` would be evaluated more than once (which is the case for LAST,
                +  // FROM_END, and RANDOM) and is non-trivial, make sure to access it only once.
                +  if ((where == 'LAST' || where == 'FROM_END' || where == 'RANDOM') &&
                +      !list.match(/^\w+$/)) {
                +    // `list` is an expression, so we may not evaluate it more than once.
                +    // We can use multiple statements.
                +    var listVar = Blockly.Lua.variableDB_.getDistinctName(
                +        'tmp_list', Blockly.Variables.NAME_TYPE);
                +    code = listVar + ' = ' + list + '\n';
                +    list = listVar;
                +  }
                +  if (mode == 'SET') {
                +    code += list + '[' + getIndex_(list, where, at) + '] = ' + value;
                +  } else {  // `mode` == 'INSERT'
                +    // LAST is a special case, because we want to insert
                +    // *after* not *before*, the existing last element.
                +    code += 'table.insert(' + list + ', ' +
                +        (getIndex_(list, where, at) + (where == 'LAST' ? ' + 1' : '')) +
                +        ', ' + value + ')';
                +  }
                +  return code + '\n';
                +};
                +
                +Blockly.Lua['lists_getSublist'] = function(block) {
                +  // Get sublist.
                +  var list = Blockly.Lua.valueToCode(block, 'LIST',
                +      Blockly.Lua.ORDER_NONE) || '{}';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  var at1 = Blockly.Lua.valueToCode(block, 'AT1',
                +      Blockly.Lua.ORDER_NONE) || '1';
                +  var at2 = Blockly.Lua.valueToCode(block, 'AT2',
                +      Blockly.Lua.ORDER_NONE) || '1';
                +  var getIndex_ = Blockly.Lua.lists.getIndex_;
                +
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'list_sublist_' + where1.toLowerCase() + '_' + where2.toLowerCase(),
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(source' +
                +          // The value for 'FROM_END' and'FROM_START' depends on `at` so
                +          // we add it as a parameter.
                +          ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', at1' : '') +
                +          ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', at2' : '') +
                +          ')',
                +       '  local t = {}',
                +       '  local start = ' + getIndex_('source', where1, 'at1'),
                +       '  local finish = ' + getIndex_('source', where2, 'at2'),
                +       '  for i = start, finish do',
                +       '    table.insert(t, source[i])',
                +       '  end',
                +       '  return t',
                +       'end']);
                +  var code = functionName + '(' + list +
                +      // The value for 'FROM_END' and 'FROM_START' depends on `at` so we
                +      // pass it.
                +      ((where1 == 'FROM_END' || where1 == 'FROM_START') ? ', ' + at1 : '') +
                +      ((where2 == 'FROM_END' || where2 == 'FROM_START') ? ', ' + at2 : '') +
                +      ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['lists_sort'] = function(block) {
                +  // Block for sorting a list.
                +  var list = Blockly.Lua.valueToCode(
                +      block, 'LIST', Blockly.Lua.ORDER_NONE) || '{}';
                +  var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
                +  var type = block.getFieldValue('TYPE');
                +
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'list_sort',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(list, typev, direction)',
                +       '  local t = {}',
                +       '  for n,v in pairs(list) do table.insert(t, v) end', // Shallow-copy.
                +       '  local compareFuncs = {',
                +       '    NUMERIC = function(a, b)',
                +       '      return (tonumber(tostring(a)) or 0)',
                +       '          < (tonumber(tostring(b)) or 0) end,',
                +       '    TEXT = function(a, b)',
                +       '      return tostring(a) < tostring(b) end,',
                +       '    IGNORE_CASE = function(a, b)',
                +       '      return string.lower(tostring(a)) < string.lower(tostring(b)) end',
                +       '  }',
                +       '  local compareTemp = compareFuncs[typev]',
                +       '  local compare = compareTemp',
                +       '  if direction == -1',
                +       '  then compare = function(a, b) return compareTemp(b, a) end',
                +       '  end',
                +       '  table.sort(t, compare)',
                +       '  return t',
                +       'end']);
                +
                +  var code = functionName +
                +      '(' + list + ',"' + type + '", ' + direction + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['lists_split'] = function(block) {
                +  // Block for splitting text into a list, or joining a list into text.
                +  var input = Blockly.Lua.valueToCode(block, 'INPUT',
                +      Blockly.Lua.ORDER_NONE);
                +  var delimiter = Blockly.Lua.valueToCode(block, 'DELIM',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var mode = block.getFieldValue('MODE');
                +  var functionName;
                +  if (mode == 'SPLIT') {
                +    if (!input) {
                +      input = '\'\'';
                +    }
                +    functionName = Blockly.Lua.provideFunction_(
                +        'list_string_split',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(input, delim)',
                +         '  local t = {}',
                +         '  local pos = 1',
                +         '  while true do',
                +         '    next_delim = string.find(input, delim, pos)',
                +         '    if next_delim == nil then',
                +         '      table.insert(t, string.sub(input, pos))',
                +         '      break',
                +         '    else',
                +         '      table.insert(t, string.sub(input, pos, next_delim-1))',
                +         '      pos = next_delim + #delim',
                +         '    end',
                +         '  end',
                +         '  return t',
                +         'end']);
                +  } else if (mode == 'JOIN') {
                +    if (!input) {
                +      input = '{}';
                +    }
                +    functionName = 'table.concat';
                +  } else {
                +    throw 'Unknown mode: ' + mode;
                +  }
                +  var code = functionName + '(' + input + ', ' + delimiter + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['lists_reverse'] = function(block) {
                +  // Block for reversing a list.
                +  var list = Blockly.Lua.valueToCode(block, 'LIST',
                +      Blockly.Lua.ORDER_NONE) || '{}';
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'list_reverse',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(input)',
                +       '  local reversed = {}',
                +       '  for i = #input, 1, -1 do',
                +       '    table.insert(reversed, input[i])',
                +       '  end',
                +       '  return reversed',
                +       'end']);
                +  var code = 'list_reverse(' + list + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/logic.js b/blockly/webif/static/blockly/generators/lua/logic.js
                new file mode 100644
                index 000000000..033c52e33
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/logic.js
                @@ -0,0 +1,128 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for logic blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.logic');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['controls_if'] = function(block) {
                +  // If/elseif/else condition.
                +  var n = 0;
                +  var code = '', branchCode, conditionCode;
                +  do {
                +    conditionCode = Blockly.Lua.valueToCode(block, 'IF' + n,
                +      Blockly.Lua.ORDER_NONE) || 'false';
                +    branchCode = Blockly.Lua.statementToCode(block, 'DO' + n);
                +    code += (n > 0 ? 'else' : '') +
                +        'if ' + conditionCode + ' then\n' + branchCode;
                +
                +    ++n;
                +  } while (block.getInput('IF' + n));
                +
                +  if (block.getInput('ELSE')) {
                +    branchCode = Blockly.Lua.statementToCode(block, 'ELSE');
                +    code += 'else\n' + branchCode;
                +  }
                +  return code + 'end\n';
                +};
                +
                +Blockly.Lua['controls_ifelse'] = Blockly.Lua['controls_if'];
                +
                +Blockly.Lua['logic_compare'] = function(block) {
                +  // Comparison operator.
                +  var OPERATORS = {
                +    'EQ': '==',
                +    'NEQ': '~=',
                +    'LT': '<',
                +    'LTE': '<=',
                +    'GT': '>',
                +    'GTE': '>='
                +  };
                +  var operator = OPERATORS[block.getFieldValue('OP')];
                +  var argument0 = Blockly.Lua.valueToCode(block, 'A',
                +      Blockly.Lua.ORDER_RELATIONAL) || '0';
                +  var argument1 = Blockly.Lua.valueToCode(block, 'B',
                +      Blockly.Lua.ORDER_RELATIONAL) || '0';
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, Blockly.Lua.ORDER_RELATIONAL];
                +};
                +
                +Blockly.Lua['logic_operation'] = function(block) {
                +  // Operations 'and', 'or'.
                +  var operator = (block.getFieldValue('OP') == 'AND') ? 'and' : 'or';
                +  var order = (operator == 'and') ? Blockly.Lua.ORDER_AND :
                +      Blockly.Lua.ORDER_OR;
                +  var argument0 = Blockly.Lua.valueToCode(block, 'A', order);
                +  var argument1 = Blockly.Lua.valueToCode(block, 'B', order);
                +  if (!argument0 && !argument1) {
                +    // If there are no arguments, then the return value is false.
                +    argument0 = 'false';
                +    argument1 = 'false';
                +  } else {
                +    // Single missing arguments have no effect on the return value.
                +    var defaultArgument = (operator == 'and') ? 'true' : 'false';
                +    if (!argument0) {
                +      argument0 = defaultArgument;
                +    }
                +    if (!argument1) {
                +      argument1 = defaultArgument;
                +    }
                +  }
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Lua['logic_negate'] = function(block) {
                +  // Negation.
                +  var argument0 = Blockly.Lua.valueToCode(block, 'BOOL',
                +      Blockly.Lua.ORDER_UNARY) || 'true';
                +  var code = 'not ' + argument0;
                +  return [code, Blockly.Lua.ORDER_UNARY];
                +};
                +
                +Blockly.Lua['logic_boolean'] = function(block) {
                +  // Boolean values true and false.
                +  var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false';
                +  return [code, Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['logic_null'] = function(block) {
                +  // Null data type.
                +  return ['nil', Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['logic_ternary'] = function(block) {
                +  // Ternary operator.
                +  var value_if = Blockly.Lua.valueToCode(block, 'IF',
                +      Blockly.Lua.ORDER_AND) || 'false';
                +  var value_then = Blockly.Lua.valueToCode(block, 'THEN',
                +      Blockly.Lua.ORDER_AND) || 'nil';
                +  var value_else = Blockly.Lua.valueToCode(block, 'ELSE',
                +      Blockly.Lua.ORDER_OR) || 'nil';
                +  var code = value_if + ' and ' + value_then + ' or ' + value_else;
                +  return [code, Blockly.Lua.ORDER_OR];
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/loops.js b/blockly/webif/static/blockly/generators/lua/loops.js
                new file mode 100644
                index 000000000..785398ff7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/loops.js
                @@ -0,0 +1,166 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for loop blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.loops');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +/**
                + * This is the text used to implement a <pre>continue</pre>.
                + * It is also used to recognise <pre>continue</pre>s in generated code so that
                + * the appropriate label can be put at the end of the loop body.
                + * @const {string}
                + */
                +Blockly.Lua.CONTINUE_STATEMENT = 'goto continue\n';
                +
                +/**
                + * If the loop body contains a "goto continue" statement, add a continue label
                + * to the loop body. Slightly inefficient, as continue labels will be generated
                + * in all outer loops, but this is safer than duplicating the logic of
                + * blockToCode.
                + *
                + * @param {string} branch Generated code of the loop body
                + * @return {string} Generated label or '' if unnecessary
                + */
                +Blockly.Lua.addContinueLabel = function(branch) {
                +  if (branch.indexOf(Blockly.Lua.CONTINUE_STATEMENT) > -1) {
                +    return branch + Blockly.Lua.INDENT + '::continue::\n';
                +  } else {
                +    return branch;
                +  }
                +};
                +
                +Blockly.Lua['controls_repeat'] = function(block) {
                +  // Repeat n times (internal number).
                +  var repeats = parseInt(block.getFieldValue('TIMES'), 10);
                +  var branch = Blockly.Lua.statementToCode(block, 'DO') || '';
                +  branch = Blockly.Lua.addContinueLabel(branch);
                +  var loopVar = Blockly.Lua.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var code = 'for ' + loopVar + ' = 1, ' + repeats + ' do\n' + branch + 'end\n';
                +  return code;
                +};
                +
                +Blockly.Lua['controls_repeat_ext'] = function(block) {
                +  // Repeat n times (external number).
                +  var repeats = Blockly.Lua.valueToCode(block, 'TIMES',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  if (Blockly.isNumber(repeats)) {
                +    repeats = parseInt(repeats, 10);
                +  } else {
                +    repeats = 'math.floor(' + repeats + ')';
                +  }
                +  var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n';
                +  branch = Blockly.Lua.addContinueLabel(branch);
                +  var loopVar = Blockly.Lua.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var code = 'for ' + loopVar + ' = 1, ' + repeats + ' do\n' +
                +      branch + 'end\n';
                +  return code;
                +};
                +
                +Blockly.Lua['controls_whileUntil'] = function(block) {
                +  // Do while/until loop.
                +  var until = block.getFieldValue('MODE') == 'UNTIL';
                +  var argument0 = Blockly.Lua.valueToCode(block, 'BOOL',
                +      until ? Blockly.Lua.ORDER_UNARY :
                +      Blockly.Lua.ORDER_NONE) || 'false';
                +  var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n';
                +  branch = Blockly.Lua.addLoopTrap(branch, block.id);
                +  branch = Blockly.Lua.addContinueLabel(branch);
                +  if (until) {
                +    argument0 = 'not ' + argument0;
                +  }
                +  return 'while ' + argument0 + ' do\n' + branch + 'end\n';
                +};
                +
                +Blockly.Lua['controls_for'] = function(block) {
                +  // For loop.
                +  var variable0 = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var startVar = Blockly.Lua.valueToCode(block, 'FROM',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var endVar = Blockly.Lua.valueToCode(block, 'TO',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var increment = Blockly.Lua.valueToCode(block, 'BY',
                +      Blockly.Lua.ORDER_NONE) || '1';
                +  var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n';
                +  branch = Blockly.Lua.addLoopTrap(branch, block.id);
                +  branch = Blockly.Lua.addContinueLabel(branch);
                +  var code = '';
                +  var incValue;
                +  if (Blockly.isNumber(startVar) && Blockly.isNumber(endVar) &&
                +      Blockly.isNumber(increment)) {
                +    // All arguments are simple numbers.
                +    var up = parseFloat(startVar) <= parseFloat(endVar);
                +    var step = Math.abs(parseFloat(increment));
                +    incValue = (up ? '' : '-') + step;
                +  } else {
                +    code = '';
                +    // Determine loop direction at start, in case one of the bounds
                +    // changes during loop execution.
                +    incValue = Blockly.Lua.variableDB_.getDistinctName(
                +        variable0 + '_inc', Blockly.Variables.NAME_TYPE);
                +    code += incValue + ' = ';
                +    if (Blockly.isNumber(increment)) {
                +      code += Math.abs(increment) + '\n';
                +    } else {
                +      code += 'math.abs(' + increment + ')\n';
                +    }
                +    code += 'if (' + startVar + ') > (' + endVar + ') then\n';
                +    code += Blockly.Lua.INDENT + incValue + ' = -' + incValue + '\n';
                +    code += 'end\n';
                +  }
                +  code += 'for ' + variable0 + ' = ' + startVar + ', ' + endVar +
                +      ', ' + incValue;
                +  code += ' do\n' + branch + 'end\n';
                +  return code;
                +};
                +
                +Blockly.Lua['controls_forEach'] = function(block) {
                +  // For each loop.
                +  var variable0 = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.Lua.valueToCode(block, 'LIST',
                +      Blockly.Lua.ORDER_NONE) || '{}';
                +  var branch = Blockly.Lua.statementToCode(block, 'DO') || '\n';
                +  branch = Blockly.Lua.addContinueLabel(branch);
                +  var code = 'for _, ' + variable0 + ' in ipairs(' + argument0 + ') do \n' +
                +      branch + 'end\n';
                +  return code;
                +};
                +
                +Blockly.Lua['controls_flow_statements'] = function(block) {
                +  // Flow statements: continue, break.
                +  switch (block.getFieldValue('FLOW')) {
                +    case 'BREAK':
                +      return 'break\n';
                +    case 'CONTINUE':
                +      return Blockly.Lua.CONTINUE_STATEMENT;
                +  }
                +  throw 'Unknown flow statement.';
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/math.js b/blockly/webif/static/blockly/generators/lua/math.js
                new file mode 100644
                index 000000000..c104bfc16
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/math.js
                @@ -0,0 +1,425 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for math blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.math');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['math_number'] = function(block) {
                +  // Numeric value.
                +  var code = parseFloat(block.getFieldValue('NUM'));
                +  var order = code < 0 ? Blockly.Lua.ORDER_UNARY :
                +              Blockly.Lua.ORDER_ATOMIC;
                +  return [code, order];
                +};
                +
                +Blockly.Lua['math_arithmetic'] = function(block) {
                +  // Basic arithmetic operators, and power.
                +  var OPERATORS = {
                +    ADD: [' + ', Blockly.Lua.ORDER_ADDITIVE],
                +    MINUS: [' - ', Blockly.Lua.ORDER_ADDITIVE],
                +    MULTIPLY: [' * ', Blockly.Lua.ORDER_MULTIPLICATIVE],
                +    DIVIDE: [' / ', Blockly.Lua.ORDER_MULTIPLICATIVE],
                +    POWER: [' ^ ', Blockly.Lua.ORDER_EXPONENTIATION]
                +  };
                +  var tuple = OPERATORS[block.getFieldValue('OP')];
                +  var operator = tuple[0];
                +  var order = tuple[1];
                +  var argument0 = Blockly.Lua.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.Lua.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + operator + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Lua['math_single'] = function(block) {
                +  // Math operators with single operand.
                +  var operator = block.getFieldValue('OP');
                +  var code;
                +  var arg;
                +  if (operator == 'NEG') {
                +    // Negation is a special case given its different operator precedence.
                +    arg = Blockly.Lua.valueToCode(block, 'NUM',
                +        Blockly.Lua.ORDER_UNARY) || '0';
                +    return ['-' + arg, Blockly.Lua.ORDER_UNARY];
                +  }
                +  if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
                +    arg = Blockly.Lua.valueToCode(block, 'NUM',
                +        Blockly.Lua.ORDER_MULTIPLICATIVE) || '0';
                +  } else {
                +    arg = Blockly.Lua.valueToCode(block, 'NUM',
                +        Blockly.Lua.ORDER_NONE) || '0';
                +  }
                +  switch (operator) {
                +    case 'ABS':
                +      code = 'math.abs(' + arg + ')';
                +      break;
                +    case 'ROOT':
                +      code = 'math.sqrt(' + arg + ')';
                +      break;
                +    case 'LN':
                +      code = 'math.log(' + arg + ')';
                +      break;
                +    case 'LOG10':
                +      code = 'math.log10(' + arg + ')';
                +      break;
                +    case 'EXP':
                +      code = 'math.exp(' + arg + ')';
                +      break;
                +    case 'POW10':
                +      code = 'math.pow(10,' + arg + ')';
                +      break;
                +    case 'ROUND':
                +      // This rounds up.  Blockly does not specify rounding direction.
                +      code = 'math.floor(' + arg + ' + .5)';
                +      break;
                +    case 'ROUNDUP':
                +      code = 'math.ceil(' + arg + ')';
                +      break;
                +    case 'ROUNDDOWN':
                +      code = 'math.floor(' + arg + ')';
                +      break;
                +    case 'SIN':
                +      code = 'math.sin(math.rad(' + arg + '))';
                +      break;
                +    case 'COS':
                +      code = 'math.cos(math.rad(' + arg + '))';
                +      break;
                +    case 'TAN':
                +      code = 'math.tan(math.rad(' + arg + '))';
                +      break;
                +    case 'ASIN':
                +      code = 'math.deg(math.asin(' + arg + '))';
                +      break;
                +    case 'ACOS':
                +      code = 'math.deg(math.acos(' + arg + '))';
                +      break;
                +    case 'ATAN':
                +      code = 'math.deg(math.atan(' + arg + '))';
                +      break;
                +    default:
                +      throw 'Unknown math operator: ' + operator;
                +  }
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['math_constant'] = function(block) {
                +  // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  var CONSTANTS = {
                +    PI: ['math.pi', Blockly.Lua.ORDER_HIGH],
                +    E: ['math.exp(1)', Blockly.Lua.ORDER_HIGH],
                +    GOLDEN_RATIO: ['(1 + math.sqrt(5)) / 2', Blockly.Lua.ORDER_MULTIPLICATIVE],
                +    SQRT2: ['math.sqrt(2)', Blockly.Lua.ORDER_HIGH],
                +    SQRT1_2: ['math.sqrt(1 / 2)', Blockly.Lua.ORDER_HIGH],
                +    INFINITY: ['math.huge', Blockly.Lua.ORDER_HIGH]
                +  };
                +  return CONSTANTS[block.getFieldValue('CONSTANT')];
                +};
                +
                +Blockly.Lua['math_number_property'] = function(block) {
                +  // Check if a number is even, odd, prime, whole, positive, or negative
                +  // or if it is divisible by certain number. Returns true or false.
                +  var number_to_check = Blockly.Lua.valueToCode(block, 'NUMBER_TO_CHECK',
                +      Blockly.Lua.ORDER_MULTIPLICATIVE) || '0';
                +  var dropdown_property = block.getFieldValue('PROPERTY');
                +  var code;
                +  if (dropdown_property == 'PRIME') {
                +    // Prime is a special case as it is not a one-liner test.
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'math_isPrime',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(n)',
                +         '  -- https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
                +         '  if n == 2 or n == 3 then',
                +         '    return true',
                +         '  end',
                +         '  -- False if n is NaN, negative, is 1, or not whole.',
                +         '  -- And false if n is divisible by 2 or 3.',
                +         '  if not(n > 1) or n % 1 ~= 0 or n % 2 == 0 or n % 3 == 0 then',
                +         '    return false',
                +         '  end',
                +         '  -- Check all the numbers of form 6k +/- 1, up to sqrt(n).',
                +         '  for x = 6, math.sqrt(n) + 1.5, 6 do',
                +         '    if n % (x - 1) == 0 or n % (x + 1) == 0 then',
                +         '      return false',
                +         '    end',
                +         '  end',
                +         '  return true',
                +         'end']);
                +    code = functionName + '(' + number_to_check + ')';
                +    return [code, Blockly.Lua.ORDER_HIGH];
                +  }
                +  switch (dropdown_property) {
                +    case 'EVEN':
                +      code = number_to_check + ' % 2 == 0';
                +      break;
                +    case 'ODD':
                +      code = number_to_check + ' % 2 == 1';
                +      break;
                +    case 'WHOLE':
                +      code = number_to_check + ' % 1 == 0';
                +      break;
                +    case 'POSITIVE':
                +      code = number_to_check + ' > 0';
                +      break;
                +    case 'NEGATIVE':
                +      code = number_to_check + ' < 0';
                +      break;
                +    case 'DIVISIBLE_BY':
                +      var divisor = Blockly.Lua.valueToCode(block, 'DIVISOR',
                +          Blockly.Lua.ORDER_MULTIPLICATIVE);
                +      // If 'divisor' is some code that evals to 0, Lua will produce a nan.
                +      // Let's produce nil if we can determine this at compile-time.
                +      if (!divisor || divisor == '0') {
                +        return ['nil', Blockly.Lua.ORDER_ATOMIC];
                +      }
                +      // The normal trick to implement ?: with and/or doesn't work here:
                +      //   divisor == 0 and nil or number_to_check % divisor == 0
                +      // because nil is false, so allow a runtime failure. :-(
                +      code = number_to_check + ' % ' + divisor + ' == 0';
                +      break;
                +  }
                +  return [code, Blockly.Lua.ORDER_RELATIONAL];
                +};
                +
                +Blockly.Lua['math_change'] = function(block) {
                +  // Add to a variable in place.
                +  var argument0 = Blockly.Lua.valueToCode(block, 'DELTA',
                +      Blockly.Lua.ORDER_ADDITIVE) || '0';
                +  var varName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  return varName + ' = ' + varName + ' + ' + argument0 + '\n';
                +};
                +
                +// Rounding functions have a single operand.
                +Blockly.Lua['math_round'] = Blockly.Lua['math_single'];
                +// Trigonometry functions have a single operand.
                +Blockly.Lua['math_trig'] = Blockly.Lua['math_single'];
                +
                +Blockly.Lua['math_on_list'] = function(block) {
                +  // Math functions for lists.
                +  var func = block.getFieldValue('OP');
                +  var list = Blockly.Lua.valueToCode(block, 'LIST',
                +      Blockly.Lua.ORDER_NONE) || '{}';
                +  var functionName;
                +
                +  // Functions needed in more than one case.
                +  function provideSum() {
                +    return Blockly.Lua.provideFunction_(
                +        'math_sum',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +         '  local result = 0',
                +         '  for _, v in ipairs(t) do',
                +         '    result = result + v',
                +         '  end',
                +         '  return result',
                +         'end']);
                +  }
                +
                +  switch (func) {
                +    case 'SUM':
                +      functionName = provideSum();
                +      break;
                +
                +    case 'MIN':
                +      // Returns 0 for the empty list.
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_min',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  if #t == 0 then',
                +           '    return 0',
                +           '  end',
                +           '  local result = math.huge',
                +           '  for _, v in ipairs(t) do',
                +           '    if v < result then',
                +           '      result = v',
                +           '    end',
                +           '  end',
                +           '  return result',
                +           'end']);
                +      break;
                +
                +    case 'AVERAGE':
                +      // Returns 0 for the empty list.
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_average',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  if #t == 0 then',
                +           '    return 0',
                +           '  end',
                +           '  return ' + provideSum() + '(t) / #t',
                +           'end']);
                +      break;
                +
                +    case 'MAX':
                +      // Returns 0 for the empty list.
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_max',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  if #t == 0 then',
                +           '    return 0',
                +           '  end',
                +           '  local result = -math.huge',
                +           '  for _, v in ipairs(t) do',
                +           '    if v > result then',
                +           '      result = v',
                +           '    end',
                +           '  end',
                +           '  return result',
                +           'end']);
                +      break;
                +
                +    case 'MEDIAN':
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_median',
                +          // This operation excludes non-numbers.
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  -- Source: http://lua-users.org/wiki/SimpleStats',
                +           '  if #t == 0 then',
                +           '    return 0',
                +           '  end',
                +           '  local temp={}',
                +           '  for _, v in ipairs(t) do',
                +           '    if type(v) == "number" then',
                +           '      table.insert(temp, v)',
                +           '    end',
                +           '  end',
                +           '  table.sort(temp)',
                +           '  if #temp % 2 == 0 then',
                +           '    return (temp[#temp/2] + temp[(#temp/2)+1]) / 2',
                +           '  else',
                +           '    return temp[math.ceil(#temp/2)]',
                +           '  end',
                +           'end']);
                +      break;
                +
                +    case 'MODE':
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_modes',
                +          // As a list of numbers can contain more than one mode,
                +          // the returned result is provided as an array.
                +          // The Lua version includes non-numbers.
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  -- Source: http://lua-users.org/wiki/SimpleStats',
                +           '  local counts={}',
                +           '  for _, v in ipairs(t) do',
                +           '    if counts[v] == nil then',
                +           '      counts[v] = 1',
                +           '    else',
                +           '      counts[v] = counts[v] + 1',
                +           '    end',
                +           '  end',
                +           '  local biggestCount = 0',
                +           '  for _, v  in pairs(counts) do',
                +           '    if v > biggestCount then',
                +           '      biggestCount = v',
                +           '    end',
                +           '  end',
                +           '  local temp={}',
                +           '  for k, v in pairs(counts) do',
                +           '    if v == biggestCount then',
                +           '      table.insert(temp, k)',
                +           '    end',
                +           '  end',
                +           '  return temp',
                +           'end']);
                +      break;
                +
                +    case 'STD_DEV':
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_standard_deviation',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  local m',
                +           '  local vm',
                +           '  local total = 0',
                +           '  local count = 0',
                +           '  local result',
                +           '  m = #t == 0 and 0 or ' + provideSum() + '(t) / #t',
                +           '  for _, v in ipairs(t) do',
                +           "    if type(v) == 'number' then",
                +           '      vm = v - m',
                +           '      total = total + (vm * vm)',
                +           '      count = count + 1',
                +           '    end',
                +           '  end',
                +           '  result = math.sqrt(total / (count-1))',
                +           '  return result',
                +           'end']);
                +      break;
                +
                +    case 'RANDOM':
                +      functionName = Blockly.Lua.provideFunction_(
                +          'math_random_list',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(t)',
                +           '  if #t == 0 then',
                +           '    return nil',
                +           '  end',
                +           '  return t[math.random(#t)]',
                +           'end']);
                +      break;
                +
                +    default:
                +      throw 'Unknown operator: ' + func;
                +  }
                +  return [functionName + '(' + list + ')', Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['math_modulo'] = function(block) {
                +  // Remainder computation.
                +  var argument0 = Blockly.Lua.valueToCode(block, 'DIVIDEND',
                +      Blockly.Lua.ORDER_MULTIPLICATIVE) || '0';
                +  var argument1 = Blockly.Lua.valueToCode(block, 'DIVISOR',
                +      Blockly.Lua.ORDER_MULTIPLICATIVE) || '0';
                +  var code = argument0 + ' % ' + argument1;
                +  return [code, Blockly.Lua.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Lua['math_constrain'] = function(block) {
                +  // Constrain a number between two limits.
                +  var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Lua.valueToCode(block, 'LOW',
                +      Blockly.Lua.ORDER_NONE) || '-math.huge';
                +  var argument2 = Blockly.Lua.valueToCode(block, 'HIGH',
                +      Blockly.Lua.ORDER_NONE) || 'math.huge';
                +  var code = 'math.min(math.max(' + argument0 + ', ' + argument1 + '), ' +
                +      argument2 + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['math_random_int'] = function(block) {
                +  // Random integer between [X] and [Y].
                +  var argument0 = Blockly.Lua.valueToCode(block, 'FROM',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Lua.valueToCode(block, 'TO',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var code = 'math.random(' + argument0 + ', ' + argument1 + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['math_random_float'] = function(block) {
                +  // Random fraction between 0 and 1.
                +  return ['math.random()', Blockly.Lua.ORDER_HIGH];
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/procedures.js b/blockly/webif/static/blockly/generators/lua/procedures.js
                new file mode 100644
                index 000000000..b6d6cdda1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/procedures.js
                @@ -0,0 +1,111 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for procedure blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.procedures');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['procedures_defreturn'] = function(block) {
                +  // Define a procedure with a return value.
                +  var funcName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var branch = Blockly.Lua.statementToCode(block, 'STACK');
                +  if (Blockly.Lua.STATEMENT_PREFIX) {
                +    branch = Blockly.Lua.prefixLines(
                +        Blockly.Lua.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + block.id + '\''), Blockly.Lua.INDENT) + branch;
                +  }
                +  if (Blockly.Lua.INFINITE_LOOP_TRAP) {
                +    branch = Blockly.Lua.INFINITE_LOOP_TRAP.replace(/%1/g,
                +        '\'' + block.id + '\'') + branch;
                +  }
                +  var returnValue = Blockly.Lua.valueToCode(block, 'RETURN',
                +      Blockly.Lua.ORDER_NONE) || '';
                +  if (returnValue) {
                +    returnValue = '  return ' + returnValue + '\n';
                +  } else if (!branch) {
                +    branch = '';
                +  }
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Lua.variableDB_.getName(block.arguments_[i],
                +        Blockly.Variables.NAME_TYPE);
                +  }
                +  var code = 'function ' + funcName + '(' + args.join(', ') + ')\n' +
                +      branch + returnValue + 'end\n';
                +  code = Blockly.Lua.scrub_(block, code);
                +  // Add % so as not to collide with helper functions in definitions list.
                +  Blockly.Lua.definitions_['%' + funcName] = code;
                +  return null;
                +};
                +
                +// Defining a procedure without a return value uses the same generator as
                +// a procedure with a return value.
                +Blockly.Lua['procedures_defnoreturn'] =
                +    Blockly.Lua['procedures_defreturn'];
                +
                +Blockly.Lua['procedures_callreturn'] = function(block) {
                +  // Call a procedure with a return value.
                +  var funcName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Lua.valueToCode(block, 'ARG' + i,
                +        Blockly.Lua.ORDER_NONE) || 'nil';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['procedures_callnoreturn'] = function(block) {
                +  // Call a procedure with no return value.
                +  var funcName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Lua.valueToCode(block, 'ARG' + i,
                +        Blockly.Lua.ORDER_NONE) || 'nil';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')\n';
                +  return code;
                +};
                +
                +Blockly.Lua['procedures_ifreturn'] = function(block) {
                +  // Conditionally return value from a procedure.
                +  var condition = Blockly.Lua.valueToCode(block, 'CONDITION',
                +      Blockly.Lua.ORDER_NONE) || 'false';
                +  var code = 'if ' + condition + ' then\n';
                +  if (block.hasReturnValue_) {
                +    var value = Blockly.Lua.valueToCode(block, 'VALUE',
                +        Blockly.Lua.ORDER_NONE) || 'nil';
                +    code += '  return ' + value + '\n';
                +  } else {
                +    code += '  return\n';
                +  }
                +  code += 'end\n';
                +  return code;
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/text.js b/blockly/webif/static/blockly/generators/lua/text.js
                new file mode 100644
                index 000000000..8a2ac914a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/text.js
                @@ -0,0 +1,361 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for text blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.texts');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['text'] = function(block) {
                +  // Text value.
                +  var code = Blockly.Lua.quote_(block.getFieldValue('TEXT'));
                +  return [code, Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['text_join'] = function(block) {
                +  // Create a string made up of any number of elements of any type.
                +  if (block.itemCount_ == 0) {
                +    return ['\'\'', Blockly.Lua.ORDER_ATOMIC];
                +  } else if (block.itemCount_ == 1) {
                +    var element = Blockly.Lua.valueToCode(block, 'ADD0',
                +        Blockly.Lua.ORDER_NONE) || '\'\'';
                +    var code = 'tostring(' + element + ')';
                +    return [code, Blockly.Lua.ORDER_HIGH];
                +  } else if (block.itemCount_ == 2) {
                +    var element0 = Blockly.Lua.valueToCode(block, 'ADD0',
                +        Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
                +    var element1 = Blockly.Lua.valueToCode(block, 'ADD1',
                +        Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
                +    var code = element0 + ' .. ' + element1;
                +    return [code, Blockly.Lua.ORDER_CONCATENATION];
                +  } else {
                +    var elements = [];
                +    for (var i = 0; i < block.itemCount_; i++) {
                +      elements[i] = Blockly.Lua.valueToCode(block, 'ADD' + i,
                +          Blockly.Lua.ORDER_NONE) || '\'\'';
                +    }
                +    var code = 'table.concat({' + elements.join(', ') + '})';
                +    return [code, Blockly.Lua.ORDER_HIGH];
                +  }
                +};
                +
                +Blockly.Lua['text_append'] = function(block) {
                +  // Append to a variable in place.
                +  var varName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var value = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_CONCATENATION) || '\'\'';
                +  return varName + ' = ' + varName + ' .. ' + value + '\n';
                +};
                +
                +Blockly.Lua['text_length'] = function(block) {
                +  // String or array length.
                +  var text = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_UNARY) || '\'\'';
                +  return ['#' + text, Blockly.Lua.ORDER_UNARY];
                +};
                +
                +Blockly.Lua['text_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_UNARY) || '\'\'';
                +  return ['#' + text + ' == 0', Blockly.Lua.ORDER_RELATIONAL];
                +};
                +
                +Blockly.Lua['text_indexOf'] = function(block) {
                +  // Search the text for a substring.
                +  var substring = Blockly.Lua.valueToCode(block, 'FIND',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var text = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  if (block.getFieldValue('END') == 'FIRST') {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'firstIndexOf',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +             '(str, substr) ',
                +         '  local i = string.find(str, substr, 1, true)',
                +         '  if i == nil then',
                +         '    return 0',
                +         '  else',
                +         '    return i',
                +         '  end',
                +         'end']);
                +  } else {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'lastIndexOf',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +             '(str, substr)',
                +         '  local i = string.find(string.reverse(str), ' +
                +             'string.reverse(substr), 1, true)',
                +         '  if i then',
                +         '    return #str + 2 - i - #substr',
                +         '  end',
                +         '  return 0',
                +         'end']);
                +  }
                +  var code = functionName + '(' + text + ', ' + substring + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_charAt'] = function(block) {
                +  // Get letter at index.
                +  // Note: Until January 2013 this block did not have the WHERE input.
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var atOrder = (where == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
                +      Blockly.Lua.ORDER_NONE;
                +  var at = Blockly.Lua.valueToCode(block, 'AT', atOrder) || '1';
                +  var text = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var code;
                +  if (where == 'RANDOM') {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'text_random_letter',
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)',
                +         '  local index = math.random(string.len(str))',
                +         '  return string.sub(str, index, index)',
                +         'end']);
                +    code = functionName + '(' + text + ')';
                +  } else {
                +    if (where == 'FIRST') {
                +      var start = '1';
                +    } else if (where == 'LAST') {
                +      var start = '-1';
                +    } else {
                +      if (where == 'FROM_START') {
                +        var start = at;
                +      } else if (where == 'FROM_END') {
                +        var start = '-' + at;
                +      } else {
                +        throw 'Unhandled option (text_charAt).';
                +      }
                +    }
                +    if (start.match(/^-?\w*$/)) {
                +      code = 'string.sub(' + text + ', ' + start + ', ' + start + ')';
                +    } else {
                +      // use function to avoid reevaluation
                +      var functionName = Blockly.Lua.provideFunction_(
                +          'text_char_at',
                +          ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +               '(str, index)',
                +           '  return string.sub(str, index, index)',
                +           'end']);
                +      code = functionName + '(' + text + ', ' + start + ')';
                +    }
                +  }
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_getSubstring'] = function(block) {
                +  // Get substring.
                +  var text = Blockly.Lua.valueToCode(block, 'STRING',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +
                +  // Get start index.
                +  var where1 = block.getFieldValue('WHERE1');
                +  var at1Order = (where1 == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
                +      Blockly.Lua.ORDER_NONE;
                +  var at1 = Blockly.Lua.valueToCode(block, 'AT1', at1Order) || '1';
                +  if (where1 == 'FIRST') {
                +    var start = 1;
                +  } else if (where1 == 'FROM_START') {
                +    var start = at1;
                +  } else if (where1 == 'FROM_END') {
                +    var start = '-' + at1;
                +  } else {
                +    throw 'Unhandled option (text_getSubstring)';
                +  }
                +
                +  // Get end index.
                +  var where2 = block.getFieldValue('WHERE2');
                +  var at2Order = (where2 == 'FROM_END') ? Blockly.Lua.ORDER_UNARY :
                +      Blockly.Lua.ORDER_NONE;
                +  var at2 = Blockly.Lua.valueToCode(block, 'AT2', at2Order) || '1';
                +  if (where2 == 'LAST') {
                +    var end = -1;
                +  } else if (where2 == 'FROM_START') {
                +    var end = at2;
                +  } else if (where2 == 'FROM_END') {
                +    var end = '-' + at2;
                +  } else {
                +    throw 'Unhandled option (text_getSubstring)';
                +  }
                +  var code = 'string.sub(' + text + ', ' + start + ', ' + end + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_changeCase'] = function(block) {
                +  // Change capitalization.
                +  var operator = block.getFieldValue('CASE');
                +  var text = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  if (operator == 'UPPERCASE') {
                +    var functionName = 'string.upper';
                +  } else if (operator == 'LOWERCASE') {
                +    var functionName = 'string.lower';
                +  } else if (operator == 'TITLECASE') {
                +    var functionName = Blockly.Lua.provideFunction_(
                +        'text_titlecase',
                +        // There are shorter versions at
                +        // http://lua-users.org/wiki/SciteTitleCase
                +        // that do not preserve whitespace.
                +        ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(str)',
                +         '  local buf = {}',
                +         '  local inWord = false',
                +         '  for i = 1, #str do',
                +         '    local c = string.sub(str, i, i)',
                +         '    if inWord then',
                +         '      table.insert(buf, string.lower(c))',
                +         '      if string.find(c, "%s") then',
                +         '        inWord = false',
                +         '      end',
                +         '    else',
                +         '      table.insert(buf, string.upper(c))',
                +         '      inWord = true',
                +         '    end',
                +         '  end',
                +         '  return table.concat(buf)',
                +         'end']);
                +  }
                +  var code = functionName + '(' + text + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_trim'] = function(block) {
                +  // Trim spaces.
                +  var OPERATORS = {
                +    LEFT: '^%s*(,-)',
                +    RIGHT: '(.-)%s*$',
                +    BOTH: '^%s*(.-)%s*$'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('MODE')];
                +  var text = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var code = 'string.gsub(' + text + ', "' + operator + '", "%1")';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_print'] = function(block) {
                +  // Print statement.
                +  var msg = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  return 'print(' + msg + ')\n';
                +};
                +
                +Blockly.Lua['text_prompt_ext'] = function(block) {
                +  // Prompt function.
                +  if (block.getField('TEXT')) {
                +    // Internal message.
                +    var msg = Blockly.Lua.quote_(block.getFieldValue('TEXT'));
                +  } else {
                +    // External message.
                +    var msg = Blockly.Lua.valueToCode(block, 'TEXT',
                +        Blockly.Lua.ORDER_NONE) || '\'\'';
                +  }
                +
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'text_prompt',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(msg)',
                +       '  io.write(msg)',
                +       '  io.flush()',
                +       '  return io.read()',
                +       'end']);
                +  var code = functionName + '(' + msg + ')';
                +
                +  var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
                +  if (toNumber) {
                +    code = 'tonumber(' + code + ', 10)';
                +  }
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_prompt'] = Blockly.Lua['text_prompt_ext'];
                +
                +Blockly.Lua['text_count'] = function(block) {
                +  var text = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var sub = Blockly.Lua.valueToCode(block, 'SUB',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'text_count',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_
                +        + '(haystack, needle)',
                +        '  if #needle == 0 then',
                +        '    return #haystack + 1',
                +        '  end',
                +        '  local i = 1',
                +        '  local count = 0',
                +        '  while true do',
                +        '    i = string.find(haystack, needle, i, true)',
                +        '    if i == nil then',
                +        '      break',
                +        '    end',
                +        '    count = count + 1',
                +        '    i = i + #needle',
                +        '  end',
                +        '  return count',
                +        'end',
                +      ]);
                +  var code = functionName + '(' + text + ', ' + sub + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_replace'] = function(block) {
                +  var text = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var from = Blockly.Lua.valueToCode(block, 'FROM',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var to = Blockly.Lua.valueToCode(block, 'TO',
                +      Blockly.Lua.ORDER_NONE) || '\'\'';
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'text_replace',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_
                +        + '(haystack, needle, replacement)',
                +        '  local buf = {}',
                +        '  local i = 1',
                +        '  while i <= #haystack do',
                +        '    if string.sub(haystack, i, i + #needle - 1) == needle then',
                +        '      for j = 1, #replacement do',
                +        '        table.insert(buf, string.sub(replacement, j, j))',
                +        '      end',
                +        '      i = i + #needle',
                +        '    else',
                +        '      table.insert(buf, string.sub(haystack, i, i))',
                +        '      i = i + 1',
                +        '    end',
                +        '  end',
                +        '  return table.concat(buf)',
                +        'end',
                +      ]);
                +  var code = functionName + '(' + text + ', ' + from + ', ' + to + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                +
                +Blockly.Lua['text_reverse'] = function(block) {
                +  var text = Blockly.Lua.valueToCode(block, 'TEXT',
                +      Blockly.Lua.ORDER_HIGH) || '\'\'';
                +  var code = 'string.reverse(' + text + ')';
                +  return [code, Blockly.Lua.ORDER_HIGH];
                +};
                diff --git a/blockly/webif/static/blockly/generators/lua/variables.js b/blockly/webif/static/blockly/generators/lua/variables.js
                new file mode 100644
                index 000000000..10b53d1de
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/lua/variables.js
                @@ -0,0 +1,46 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for variable blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Lua.variables');
                +
                +goog.require('Blockly.Lua');
                +
                +
                +Blockly.Lua['variables_get'] = function(block) {
                +  // Variable getter.
                +  var code = Blockly.Lua.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return [code, Blockly.Lua.ORDER_ATOMIC];
                +};
                +
                +Blockly.Lua['variables_set'] = function(block) {
                +  // Variable setter.
                +  var argument0 = Blockly.Lua.valueToCode(block, 'VALUE',
                +      Blockly.Lua.ORDER_NONE) || '0';
                +  var varName = Blockly.Lua.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  return varName + ' = ' + argument0 + '\n';
                +};
                diff --git a/blockly/webif/static/blockly/generators/php.js b/blockly/webif/static/blockly/generators/php.js
                new file mode 100644
                index 000000000..2c65a6809
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php.js
                @@ -0,0 +1,304 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Helper functions for generating PHP for blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP');
                +
                +goog.require('Blockly.Generator');
                +
                +
                +/**
                + * PHP code generator.
                + * @type {!Blockly.Generator}
                + */
                +Blockly.PHP = new Blockly.Generator('PHP');
                +
                +/**
                + * List of illegal variable names.
                + * This is not intended to be a security feature.  Blockly is 100% client-side,
                + * so bypassing this list is trivial.  This is intended to prevent users from
                + * accidentally clobbering a built-in object or function.
                + * @private
                + */
                +Blockly.PHP.addReservedWords(
                +        // http://php.net/manual/en/reserved.keywords.php
                +    '__halt_compiler,abstract,and,array,as,break,callable,case,catch,class,' +
                +    'clone,const,continue,declare,default,die,do,echo,else,elseif,empty,' +
                +    'enddeclare,endfor,endforeach,endif,endswitch,endwhile,eval,exit,extends,' +
                +    'final,for,foreach,function,global,goto,if,implements,include,' +
                +    'include_once,instanceof,insteadof,interface,isset,list,namespace,new,or,' +
                +    'print,private,protected,public,require,require_once,return,static,' +
                +    'switch,throw,trait,try,unset,use,var,while,xor,' +
                +        // http://php.net/manual/en/reserved.constants.php
                +    'PHP_VERSION,PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,' +
                +    'PHP_VERSION_ID,PHP_EXTRA_VERSION,PHP_ZTS,PHP_DEBUG,PHP_MAXPATHLEN,' +
                +    'PHP_OS,PHP_SAPI,PHP_EOL,PHP_INT_MAX,PHP_INT_SIZE,DEFAULT_INCLUDE_PATH,' +
                +    'PEAR_INSTALL_DIR,PEAR_EXTENSION_DIR,PHP_EXTENSION_DIR,PHP_PREFIX,' +
                +    'PHP_BINDIR,PHP_BINARY,PHP_MANDIR,PHP_LIBDIR,PHP_DATADIR,PHP_SYSCONFDIR,' +
                +    'PHP_LOCALSTATEDIR,PHP_CONFIG_FILE_PATH,PHP_CONFIG_FILE_SCAN_DIR,' +
                +    'PHP_SHLIB_SUFFIX,E_ERROR,E_WARNING,E_PARSE,E_NOTICE,E_CORE_ERROR,' +
                +    'E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,' +
                +    'E_USER_WARNING,E_USER_NOTICE,E_DEPRECATED,E_USER_DEPRECATED,E_ALL,' +
                +    'E_STRICT,__COMPILER_HALT_OFFSET__,TRUE,FALSE,NULL,__CLASS__,__DIR__,' +
                +    '__FILE__,__FUNCTION__,__LINE__,__METHOD__,__NAMESPACE__,__TRAIT__'
                +);
                +
                +/**
                + * Order of operation ENUMs.
                + * http://php.net/manual/en/language.operators.precedence.php
                + */
                +Blockly.PHP.ORDER_ATOMIC = 0;             // 0 "" ...
                +Blockly.PHP.ORDER_CLONE = 1;              // clone
                +Blockly.PHP.ORDER_NEW = 1;                // new
                +Blockly.PHP.ORDER_MEMBER = 2.1;           // []
                +Blockly.PHP.ORDER_FUNCTION_CALL = 2.2;    // ()
                +Blockly.PHP.ORDER_POWER = 3;              // **
                +Blockly.PHP.ORDER_INCREMENT = 4;          // ++
                +Blockly.PHP.ORDER_DECREMENT = 4;          // --
                +Blockly.PHP.ORDER_BITWISE_NOT = 4;        // ~
                +Blockly.PHP.ORDER_CAST = 4;               // (int) (float) (string) (array) ...
                +Blockly.PHP.ORDER_SUPPRESS_ERROR = 4;     // @
                +Blockly.PHP.ORDER_INSTANCEOF = 5;         // instanceof
                +Blockly.PHP.ORDER_LOGICAL_NOT = 6;        // !
                +Blockly.PHP.ORDER_UNARY_PLUS = 7.1;       // +
                +Blockly.PHP.ORDER_UNARY_NEGATION = 7.2;   // -
                +Blockly.PHP.ORDER_MULTIPLICATION = 8.1;   // *
                +Blockly.PHP.ORDER_DIVISION = 8.2;         // /
                +Blockly.PHP.ORDER_MODULUS = 8.3;          // %
                +Blockly.PHP.ORDER_ADDITION = 9.1;         // +
                +Blockly.PHP.ORDER_SUBTRACTION = 9.2;      // -
                +Blockly.PHP.ORDER_STRING_CONCAT = 9.3;    // .
                +Blockly.PHP.ORDER_BITWISE_SHIFT = 10;     // << >>
                +Blockly.PHP.ORDER_RELATIONAL = 11;        // < <= > >=
                +Blockly.PHP.ORDER_EQUALITY = 12;          // == != === !== <> <=>
                +Blockly.PHP.ORDER_REFERENCE = 13;         // &
                +Blockly.PHP.ORDER_BITWISE_AND = 13;       // &
                +Blockly.PHP.ORDER_BITWISE_XOR = 14;       // ^
                +Blockly.PHP.ORDER_BITWISE_OR = 15;        // |
                +Blockly.PHP.ORDER_LOGICAL_AND = 16;       // &&
                +Blockly.PHP.ORDER_LOGICAL_OR = 17;        // ||
                +Blockly.PHP.ORDER_IF_NULL = 18;           // ??
                +Blockly.PHP.ORDER_CONDITIONAL = 19;       // ?:
                +Blockly.PHP.ORDER_ASSIGNMENT = 20;        // = += -= *= /= %= <<= >>= ...
                +Blockly.PHP.ORDER_LOGICAL_AND_WEAK = 21;  // and
                +Blockly.PHP.ORDER_LOGICAL_XOR = 22;       // xor
                +Blockly.PHP.ORDER_LOGICAL_OR_WEAK = 23;   // or
                +Blockly.PHP.ORDER_COMMA = 24;             // ,
                +Blockly.PHP.ORDER_NONE = 99;              // (...)
                +
                +/**
                + * List of outer-inner pairings that do NOT require parentheses.
                + * @type {!Array.<!Array.<number>>}
                + */
                +Blockly.PHP.ORDER_OVERRIDES = [
                +  // (foo()).bar() -> foo().bar()
                +  // (foo())[0] -> foo()[0]
                +  [Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_FUNCTION_CALL],
                +  // (foo[0])[1] -> foo[0][1]
                +  // (foo.bar).baz -> foo.bar.baz
                +  [Blockly.PHP.ORDER_MEMBER, Blockly.PHP.ORDER_MEMBER],
                +  // !(!foo) -> !!foo
                +  [Blockly.PHP.ORDER_LOGICAL_NOT, Blockly.PHP.ORDER_LOGICAL_NOT],
                +  // a * (b * c) -> a * b * c
                +  [Blockly.PHP.ORDER_MULTIPLICATION, Blockly.PHP.ORDER_MULTIPLICATION],
                +  // a + (b + c) -> a + b + c
                +  [Blockly.PHP.ORDER_ADDITION, Blockly.PHP.ORDER_ADDITION],
                +  // a && (b && c) -> a && b && c
                +  [Blockly.PHP.ORDER_LOGICAL_AND, Blockly.PHP.ORDER_LOGICAL_AND],
                +  // a || (b || c) -> a || b || c
                +  [Blockly.PHP.ORDER_LOGICAL_OR, Blockly.PHP.ORDER_LOGICAL_OR]
                +];
                +
                +/**
                + * Initialise the database of variable names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.PHP.init = function(workspace) {
                +  // Create a dictionary of definitions to be printed before the code.
                +  Blockly.PHP.definitions_ = Object.create(null);
                +  // Create a dictionary mapping desired function names in definitions_
                +  // to actual function names (to avoid collisions with user functions).
                +  Blockly.PHP.functionNames_ = Object.create(null);
                +
                +  if (!Blockly.PHP.variableDB_) {
                +    Blockly.PHP.variableDB_ =
                +        new Blockly.Names(Blockly.PHP.RESERVED_WORDS_, '$');
                +  } else {
                +    Blockly.PHP.variableDB_.reset();
                +  }
                +
                +  var defvars = [];
                +  var varName;
                +  var variables = Blockly.Variables.allVariables(workspace);
                +  for (var i = 0, variable; variable = variables[i]; i++) {
                +    varName = variable.name;
                +    defvars[i] = Blockly.PHP.variableDB_.getName(varName,
                +        Blockly.Variables.NAME_TYPE) + ';';
                +  }
                +  Blockly.PHP.definitions_['variables'] = defvars.join('\n');
                +};
                +
                +/**
                + * Prepend the generated code with the variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.PHP.finish = function(code) {
                +  // Convert the definitions dictionary into a list.
                +  var definitions = [];
                +  for (var name in Blockly.PHP.definitions_) {
                +    definitions.push(Blockly.PHP.definitions_[name]);
                +  }
                +  // Clean up temporary data.
                +  delete Blockly.PHP.definitions_;
                +  delete Blockly.PHP.functionNames_;
                +  Blockly.PHP.variableDB_.reset();
                +  return definitions.join('\n\n') + '\n\n\n' + code;
                +};
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything.  A trailing semicolon is needed to make this legal.
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.PHP.scrubNakedValue = function(line) {
                +  return line + ';\n';
                +};
                +
                +/**
                + * Encode a string as a properly escaped PHP string, complete with
                + * quotes.
                + * @param {string} string Text to encode.
                + * @return {string} PHP string.
                + * @private
                + */
                +Blockly.PHP.quote_ = function(string) {
                +  string = string.replace(/\\/g, '\\\\')
                +                 .replace(/\n/g, '\\\n')
                +                 .replace(/'/g, '\\\'');
                +  return '\'' + string + '\'';
                +};
                +
                +/**
                + * Common tasks for generating PHP from blocks.
                + * Handles comments for the specified block and any connected value blocks.
                + * Calls any statements following this block.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The PHP code created for this block.
                + * @return {string} PHP code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.PHP.scrub_ = function(block, code) {
                +  var commentCode = '';
                +  // Only collect comments for blocks that aren't inline.
                +  if (!block.outputConnection || !block.outputConnection.targetConnection) {
                +    // Collect comment for this block.
                +    var comment = block.getCommentText();
                +    comment = Blockly.utils.wrap(comment, Blockly.PHP.COMMENT_WRAP - 3);
                +    if (comment) {
                +      commentCode += Blockly.PHP.prefixLines(comment, '// ') + '\n';
                +    }
                +    // Collect comments for all value arguments.
                +    // Don't collect comments for nested statements.
                +    for (var i = 0; i < block.inputList.length; i++) {
                +      if (block.inputList[i].type == Blockly.INPUT_VALUE) {
                +        var childBlock = block.inputList[i].connection.targetBlock();
                +        if (childBlock) {
                +          var comment = Blockly.PHP.allNestedComments(childBlock);
                +          if (comment) {
                +            commentCode += Blockly.PHP.prefixLines(comment, '// ');
                +          }
                +        }
                +      }
                +    }
                +  }
                +  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
                +  var nextCode = Blockly.PHP.blockToCode(nextBlock);
                +  return commentCode + code + nextCode;
                +};
                +
                +/**
                + * Gets a property and adjusts the value while taking into account indexing.
                + * @param {!Blockly.Block} block The block.
                + * @param {string} atId The property ID of the element to get.
                + * @param {number=} opt_delta Value to add.
                + * @param {boolean=} opt_negate Whether to negate the value.
                + * @param {number=} opt_order The highest order acting on this value.
                + * @return {string|number}
                + */
                +Blockly.PHP.getAdjusted = function(block, atId, opt_delta, opt_negate,
                +    opt_order) {
                +  var delta = opt_delta || 0;
                +  var order = opt_order || Blockly.PHP.ORDER_NONE;
                +  if (block.workspace.options.oneBasedIndex) {
                +    delta--;
                +  }
                +  var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0';
                +  if (delta > 0) {
                +    var at = Blockly.PHP.valueToCode(block, atId,
                +            Blockly.PHP.ORDER_ADDITION) || defaultAtIndex;
                +  } else if (delta < 0) {
                +    var at = Blockly.PHP.valueToCode(block, atId,
                +            Blockly.PHP.ORDER_SUBTRACTION) || defaultAtIndex;
                +  } else if (opt_negate) {
                +    var at = Blockly.PHP.valueToCode(block, atId,
                +            Blockly.PHP.ORDER_UNARY_NEGATION) || defaultAtIndex;
                +  } else {
                +    var at = Blockly.PHP.valueToCode(block, atId, order) ||
                +        defaultAtIndex;
                +  }
                +
                +  if (Blockly.isNumber(at)) {
                +    // If the index is a naked number, adjust it right now.
                +    at = parseFloat(at) + delta;
                +    if (opt_negate) {
                +      at = -at;
                +    }
                +  } else {
                +    // If the index is dynamic, adjust it in code.
                +    if (delta > 0) {
                +      at = at + ' + ' + delta;
                +      var innerOrder = Blockly.PHP.ORDER_ADDITION;
                +    } else if (delta < 0) {
                +      at = at + ' - ' + -delta;
                +      var innerOrder = Blockly.PHP.ORDER_SUBTRACTION;
                +    }
                +    if (opt_negate) {
                +      if (delta) {
                +        at = '-(' + at + ')';
                +      } else {
                +        at = '-' + at;
                +      }
                +      var innerOrder = Blockly.PHP.ORDER_UNARY_NEGATION;
                +    }
                +    innerOrder = Math.floor(innerOrder);
                +    order = Math.floor(order);
                +    if (innerOrder && order >= innerOrder) {
                +      at = '(' + at + ')';
                +    }
                +  }
                +  return at;
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/colour.js b/blockly/webif/static/blockly/generators/php/colour.js
                new file mode 100644
                index 000000000..e73c17a95
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/colour.js
                @@ -0,0 +1,105 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for colour blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.colour');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['colour_picker'] = function(block) {
                +  // Colour picker.
                +  var code = '\'' + block.getFieldValue('COLOUR') + '\'';
                +  return [code, Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['colour_random'] = function(block) {
                +  // Generate a random colour.
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'colour_random',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +       '  return \'#\' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), ' +
                +          '6, \'0\', STR_PAD_LEFT);',
                +       '}']);
                +  var code = functionName + '()';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['colour_rgb'] = function(block) {
                +  // Compose a colour from RGB components expressed as percentages.
                +  var red = Blockly.PHP.valueToCode(block, 'RED',
                +      Blockly.PHP.ORDER_COMMA) || 0;
                +  var green = Blockly.PHP.valueToCode(block, 'GREEN',
                +      Blockly.PHP.ORDER_COMMA) || 0;
                +  var blue = Blockly.PHP.valueToCode(block, 'BLUE',
                +      Blockly.PHP.ORDER_COMMA) || 0;
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'colour_rgb',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($r, $g, $b) {',
                +       '  $r = round(max(min($r, 100), 0) * 2.55);',
                +       '  $g = round(max(min($g, 100), 0) * 2.55);',
                +       '  $b = round(max(min($b, 100), 0) * 2.55);',
                +       '  $hex = \'#\';',
                +       '  $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
                +       '  $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
                +       '  $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);',
                +       '  return $hex;',
                +       '}']);
                +  var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['colour_blend'] = function(block) {
                +  // Blend two colours together.
                +  var c1 = Blockly.PHP.valueToCode(block, 'COLOUR1',
                +      Blockly.PHP.ORDER_COMMA) || '\'#000000\'';
                +  var c2 = Blockly.PHP.valueToCode(block, 'COLOUR2',
                +      Blockly.PHP.ORDER_COMMA) || '\'#000000\'';
                +  var ratio = Blockly.PHP.valueToCode(block, 'RATIO',
                +      Blockly.PHP.ORDER_COMMA) || 0.5;
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'colour_blend',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($c1, $c2, $ratio) {',
                +       '  $ratio = max(min($ratio, 1), 0);',
                +       '  $r1 = hexdec(substr($c1, 1, 2));',
                +       '  $g1 = hexdec(substr($c1, 3, 2));',
                +       '  $b1 = hexdec(substr($c1, 5, 2));',
                +       '  $r2 = hexdec(substr($c2, 1, 2));',
                +       '  $g2 = hexdec(substr($c2, 3, 2));',
                +       '  $b2 = hexdec(substr($c2, 5, 2));',
                +       '  $r = round($r1 * (1 - $ratio) + $r2 * $ratio);',
                +       '  $g = round($g1 * (1 - $ratio) + $g2 * $ratio);',
                +       '  $b = round($b1 * (1 - $ratio) + $b2 * $ratio);',
                +       '  $hex = \'#\';',
                +       '  $hex .= str_pad(dechex($r), 2, \'0\', STR_PAD_LEFT);',
                +       '  $hex .= str_pad(dechex($g), 2, \'0\', STR_PAD_LEFT);',
                +       '  $hex .= str_pad(dechex($b), 2, \'0\', STR_PAD_LEFT);',
                +       '  return $hex;',
                +       '}']);
                +  var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/lists.js b/blockly/webif/static/blockly/generators/php/lists.js
                new file mode 100644
                index 000000000..3fd261695
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/lists.js
                @@ -0,0 +1,512 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for list blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +
                +/*
                + * Lists in PHP are known to break when non-variables are passed into blocks
                + * that require a list. PHP, unlike other languages, passes arrays as reference
                + * value instead of value so we are unable to support it to the extent we can
                + * for the other languages.
                + * For example, a ternary operator with two arrays will return the array by
                + * value and that cannot be passed into any of the built-in array functions for
                + * PHP (because only variables can be passed by reference).
                + * ex:  end(true ? list1 : list2)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.lists');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['lists_create_empty'] = function(block) {
                +  // Create an empty list.
                +  return ['array()', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_create_with'] = function(block) {
                +  // Create a list with any number of elements of any type.
                +  var code = new Array(block.itemCount_);
                +  for (var i = 0; i < block.itemCount_; i++) {
                +    code[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
                +        Blockly.PHP.ORDER_COMMA) || 'null';
                +  }
                +  code = 'array(' + code.join(', ') + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_repeat'] = function(block) {
                +  // Create a list with one element repeated.
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'lists_repeat',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($value, $count) {',
                +       '  $array = array();',
                +       '  for ($index = 0; $index < $count; $index++) {',
                +       '    $array[] = $value;',
                +       '  }',
                +       '  return $array;',
                +       '}']);
                +  var element = Blockly.PHP.valueToCode(block, 'ITEM',
                +      Blockly.PHP.ORDER_COMMA) || 'null';
                +  var repeatCount = Blockly.PHP.valueToCode(block, 'NUM',
                +      Blockly.PHP.ORDER_COMMA) || '0';
                +  var code = functionName + '(' + element + ', ' + repeatCount + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_length'] = function(block) {
                +  // String or array length.
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'length',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
                +       '  if (is_string($value)) {',
                +       '    return strlen($value);',
                +       '  } else {',
                +       '    return count($value);',
                +       '  }',
                +       '}']);
                +  var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  return [functionName + '(' + list + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
                +  return ['empty(' + argument0 + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_indexOf'] = function(block) {
                +  // Find an item in the list.
                +  var argument0 = Blockly.PHP.valueToCode(block, 'FIND',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_MEMBER) || '[]';
                +  if (block.workspace.options.oneBasedIndex) {
                +    var errorIndex = ' 0';
                +    var indexAdjustment = ' + 1';
                +  } else {
                +    var errorIndex = ' -1';
                +    var indexAdjustment = '';
                +  }
                +  if (block.getFieldValue('END') == 'FIRST') {
                +    // indexOf
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'indexOf',
                +        ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +            '($haystack, $needle) {',
                +         '  for ($index = 0; $index < count($haystack); $index++) {',
                +         '    if ($haystack[$index] == $needle) return $index' +
                +            indexAdjustment + ';',
                +         '  }',
                +         '  return ' + errorIndex + ';',
                +         '}']);
                +  } else {
                +    // lastIndexOf
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'lastIndexOf',
                +        ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +            '($haystack, $needle) {',
                +         '  $last = ' + errorIndex + ';',
                +         '  for ($index = 0; $index < count($haystack); $index++) {',
                +         '    if ($haystack[$index] == $needle) $last = $index' +
                +            indexAdjustment + ';',
                +         '  }',
                +         '  return $last;',
                +         '}']);
                +  }
                +
                +  var code = functionName + '(' + argument1 + ', ' + argument0 + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_getIndex'] = function(block) {
                +  // Get element at index.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  switch (where) {
                +    case 'FIRST':
                +      if (mode == 'GET') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_MEMBER) || 'array()';
                +        var code = list + '[0]';
                +        return [code, Blockly.PHP.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        var code = 'array_shift(' + list + ')';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        return 'array_shift(' + list + ');\n';
                +      }
                +      break;
                +    case 'LAST':
                +      if (mode == 'GET') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        var code = 'end(' + list + ')';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'GET_REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        var code = 'array_pop(' + list + ')';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        return 'array_pop(' + list + ');\n';
                +      }
                +      break;
                +    case 'FROM_START':
                +      var at = Blockly.PHP.getAdjusted(block, 'AT');
                +      if (mode == 'GET') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_MEMBER) || 'array()';
                +        var code = list + '[' + at + ']';
                +        return [code, Blockly.PHP.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_COMMA) || 'array()';
                +        var code = 'array_splice(' + list + ', ' + at + ', 1)[0]';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_COMMA) || 'array()';
                +        return 'array_splice(' + list + ', ' + at + ', 1);\n';
                +      }
                +      break;
                +    case 'FROM_END':
                +      if (mode == 'GET') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_COMMA) || 'array()';
                +        var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
                +        var code = 'array_slice(' + list + ', ' + at + ', 1)[0]';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'GET_REMOVE' || mode == 'REMOVE') {
                +        var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +                Blockly.PHP.ORDER_NONE) || 'array()';
                +        var at = Blockly.PHP.getAdjusted(block, 'AT', 1, false,
                +            Blockly.PHP.ORDER_SUBTRACTION);
                +        code = 'array_splice(' + list +
                +            ', count(' + list + ') - ' + at + ', 1)[0]';
                +        if (mode == 'GET_REMOVE') {
                +          return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +        } else if (mode == 'REMOVE') {
                +          return code + ';\n';
                +        }
                +      }
                +      break;
                +    case 'RANDOM':
                +      var list = Blockly.PHP.valueToCode(block, 'VALUE',
                +              Blockly.PHP.ORDER_NONE) || 'array()';
                +      if (mode == 'GET') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_get_random_item',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '($list) {',
                +             '  return $list[rand(0,count($list)-1)];',
                +             '}']);
                +        code = functionName + '(' + list + ')';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'GET_REMOVE') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_get_remove_random_item',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '(&$list) {',
                +             '  $x = rand(0,count($list)-1);',
                +             '  unset($list[$x]);',
                +             '  return array_values($list);',
                +             '}']);
                +        code = functionName + '(' + list + ')';
                +        return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_remove_random_item',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '(&$list) {',
                +             '  unset($list[rand(0,count($list)-1)]);',
                +             '}']);
                +        return functionName + '(' + list + ');\n';
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_getIndex).';
                +};
                +
                +Blockly.PHP['lists_setIndex'] = function(block) {
                +  // Set element at index.
                +  // Note: Until February 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var value = Blockly.PHP.valueToCode(block, 'TO',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || 'null';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  // Closure, which accesses and modifies 'list'.
                +  function cacheList() {
                +    if (list.match(/^\$\w+$/)) {
                +      return '';
                +    }
                +    var listVar = Blockly.PHP.variableDB_.getDistinctName(
                +        'tmp_list', Blockly.Variables.NAME_TYPE);
                +    var code = listVar + ' = &' + list + ';\n';
                +    list = listVar;
                +    return code;
                +  }
                +  switch (where) {
                +    case 'FIRST':
                +      if (mode == 'SET') {
                +        var list = Blockly.PHP.valueToCode(block, 'LIST',
                +                Blockly.PHP.ORDER_MEMBER) || 'array()';
                +        return list + '[0] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        var list = Blockly.PHP.valueToCode(block, 'LIST',
                +                Blockly.PHP.ORDER_COMMA) || 'array()';
                +        return 'array_unshift(' + list + ', ' + value + ');\n';
                +      }
                +      break;
                +    case 'LAST':
                +      var list = Blockly.PHP.valueToCode(block, 'LIST',
                +              Blockly.PHP.ORDER_COMMA) || 'array()';
                +      if (mode == 'SET') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_set_last_item',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '(&$list, $value) {',
                +             '  $list[count($list) - 1] = $value;',
                +             '}']);
                +        return functionName + '(' + list + ', ' + value + ');\n';
                +      } else if (mode == 'INSERT') {
                +        return 'array_push(' + list + ', ' + value + ');\n';
                +      }
                +      break;
                +    case 'FROM_START':
                +      var at = Blockly.PHP.getAdjusted(block, 'AT');
                +      if (mode == 'SET') {
                +        var list = Blockly.PHP.valueToCode(block, 'LIST',
                +                Blockly.PHP.ORDER_MEMBER) || 'array()';
                +        return list + '[' + at + '] = ' + value + ';\n';
                +      } else if (mode == 'INSERT') {
                +        var list = Blockly.PHP.valueToCode(block, 'LIST',
                +                Blockly.PHP.ORDER_COMMA) || 'array()';
                +        return 'array_splice(' + list + ', ' + at + ', 0, ' + value + ');\n';
                +      }
                +      break;
                +    case 'FROM_END':
                +      var list = Blockly.PHP.valueToCode(block, 'LIST',
                +              Blockly.PHP.ORDER_COMMA) || 'array()';
                +      var at = Blockly.PHP.getAdjusted(block, 'AT', 1);
                +      if (mode == 'SET') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_set_from_end',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '(&$list, $at, $value) {',
                +             '  $list[count($list) - $at] = $value;',
                +             '}']);
                +        return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
                +      } else if (mode == 'INSERT') {
                +        var functionName = Blockly.PHP.provideFunction_(
                +            'lists_insert_from_end',
                +            ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +                '(&$list, $at, $value) {',
                +             '  return array_splice($list, count($list) - $at, 0, $value);',
                +             '}']);
                +        return functionName + '(' + list + ', ' + at + ', ' + value + ');\n';
                +      }
                +      break;
                +    case 'RANDOM':
                +      var list = Blockly.PHP.valueToCode(block, 'LIST',
                +              Blockly.PHP.ORDER_REFERENCE) || 'array()';
                +      var code = cacheList();
                +      var xVar = Blockly.PHP.variableDB_.getDistinctName(
                +          'tmp_x', Blockly.Variables.NAME_TYPE);
                +      code += xVar + ' = rand(0, count(' + list + ')-1);\n';
                +      if (mode == 'SET') {
                +        code += list + '[' + xVar + '] = ' + value + ';\n';
                +        return code;
                +      } else if (mode == 'INSERT') {
                +        code += 'array_splice(' + list + ', ' + xVar + ', 0, ' + value +
                +            ');\n';
                +        return code;
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_setIndex).';
                +};
                +
                +Blockly.PHP['lists_getSublist'] = function(block) {
                +  // Get sublist.
                +  var list = Blockly.PHP.valueToCode(block, 'LIST',
                +      Blockly.PHP.ORDER_COMMA) || 'array()';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (where1 == 'FIRST' && where2 == 'LAST') {
                +    var code = list;
                +  } else if (list.match(/^\$\w+$/) ||
                +      (where1 != 'FROM_END' && where2 == 'FROM_START')) {
                +    // If the list is a simple value or doesn't require a call for length, don't
                +    // generate a helper function.
                +    switch (where1) {
                +      case 'FROM_START':
                +        var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
                +        break;
                +      case 'FROM_END':
                +        var at1 = Blockly.PHP.getAdjusted(block, 'AT1', 1, false,
                +            Blockly.PHP.ORDER_SUBTRACTION);
                +        at1 = 'count(' + list + ') - ' + at1;
                +        break;
                +      case 'FIRST':
                +        var at1 = '0';
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    switch (where2) {
                +      case 'FROM_START':
                +        var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.PHP.ORDER_SUBTRACTION);
                +        var length = at2 + ' - ';
                +        if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
                +          length += at1;
                +        } else {
                +          length += '(' + at1 + ')';
                +        }
                +        length += ' + 1';
                +        break;
                +      case 'FROM_END':
                +        var at2 = Blockly.PHP.getAdjusted(block, 'AT2', 0, false,
                +            Blockly.PHP.ORDER_SUBTRACTION);
                +        var length = 'count(' + list + ') - ' + at2 + ' - ';
                +        if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
                +          length += at1;
                +        } else {
                +          length += '(' + at1 + ')';
                +        }
                +        break;
                +      case 'LAST':
                +        var length = 'count(' + list + ') - ';
                +        if (Blockly.isNumber(String(at1)) || String(at1).match(/^\(.+\)$/)) {
                +          length += at1;
                +        } else {
                +          length += '(' + at1 + ')';
                +        }
                +        break;
                +      default:
                +        throw 'Unhandled option (lists_getSublist).';
                +    }
                +    code = 'array_slice(' + list + ', ' + at1 + ', ' + length + ')';
                +  } else {
                +    var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'lists_get_sublist',
                +        ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +            '($list, $where1, $at1, $where2, $at2) {',
                +         '  if ($where1 == \'FROM_END\') {',
                +         '    $at1 = count($list) - 1 - $at1;',
                +         '  } else if ($where1 == \'FIRST\') {',
                +         '    $at1 = 0;',
                +         '  } else if ($where1 != \'FROM_START\'){',
                +         '    throw new Exception(\'Unhandled option (lists_get_sublist).\');',
                +         '  }',
                +         '  $length = 0;',
                +         '  if ($where2 == \'FROM_START\') {',
                +         '    $length = $at2 - $at1 + 1;',
                +         '  } else if ($where2 == \'FROM_END\') {',
                +         '    $length = count($list) - $at1 - $at2;',
                +         '  } else if ($where2 == \'LAST\') {',
                +         '    $length = count($list) - $at1;',
                +         '  } else {',
                +         '    throw new Exception(\'Unhandled option (lists_get_sublist).\');',
                +         '  }',
                +         '  return array_slice($list, $at1, $length);',
                +         '}']);
                +    var code = functionName + '(' + list + ', \'' +
                +        where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
                +  }
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_sort'] = function(block) {
                +  // Block for sorting a list.
                +  var listCode = Blockly.PHP.valueToCode(block, 'LIST',
                +      Blockly.PHP.ORDER_COMMA) || 'array()';
                +  var direction = block.getFieldValue('DIRECTION') === '1' ? 1 : -1;
                +  var type = block.getFieldValue('TYPE');
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'lists_sort',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($list, $type, $direction) {',
                +       '  $sortCmpFuncs = array(',
                +       '    "NUMERIC" => "strnatcasecmp",',
                +       '    "TEXT" => "strcmp",',
                +       '    "IGNORE_CASE" => "strcasecmp"',
                +       '  );',
                +       '  $sortCmp = $sortCmpFuncs[$type];',
                +       '  $list2 = $list;', // Clone list.
                +       '  usort($list2, $sortCmp);',
                +       '  if ($direction == -1) {',
                +       '    $list2 = array_reverse($list2);',
                +       '  }',
                +       '  return $list2;',
                +       '}']);
                +  var sortCode = functionName +
                +      '(' + listCode + ', "' + type + '", ' + direction + ')';
                +  return [sortCode, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_split'] = function(block) {
                +  // Block for splitting text into a list, or joining a list into text.
                +  var value_input = Blockly.PHP.valueToCode(block, 'INPUT',
                +      Blockly.PHP.ORDER_COMMA);
                +  var value_delim = Blockly.PHP.valueToCode(block, 'DELIM',
                +      Blockly.PHP.ORDER_COMMA) || '\'\'';
                +  var mode = block.getFieldValue('MODE');
                +  if (mode == 'SPLIT') {
                +    if (!value_input) {
                +      value_input = '\'\'';
                +    }
                +    var functionName = 'explode';
                +  } else if (mode == 'JOIN') {
                +    if (!value_input) {
                +      value_input = 'array()';
                +    }
                +    var functionName = 'implode';
                +  } else {
                +    throw 'Unknown mode: ' + mode;
                +  }
                +  var code = functionName + '(' + value_delim + ', ' + value_input + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['lists_reverse'] = function(block) {
                +  // Block for reversing a list.
                +  var list = Blockly.PHP.valueToCode(block, 'LIST',
                +      Blockly.PHP.ORDER_COMMA) || '[]';
                +  var code = 'array_reverse(' + list + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/logic.js b/blockly/webif/static/blockly/generators/php/logic.js
                new file mode 100644
                index 000000000..475d2f703
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/logic.js
                @@ -0,0 +1,129 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for logic blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.logic');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['controls_if'] = function(block) {
                +  // If/elseif/else condition.
                +  var n = 0;
                +  var code = '', branchCode, conditionCode;
                +  do {
                +    conditionCode = Blockly.PHP.valueToCode(block, 'IF' + n,
                +      Blockly.PHP.ORDER_NONE) || 'false';
                +    branchCode = Blockly.PHP.statementToCode(block, 'DO' + n);
                +    code += (n > 0 ? ' else ' : '') +
                +        'if (' + conditionCode + ') {\n' + branchCode + '}';
                +
                +    ++n;
                +  } while (block.getInput('IF' + n));
                +
                +  if (block.getInput('ELSE')) {
                +    branchCode = Blockly.PHP.statementToCode(block, 'ELSE');
                +    code += ' else {\n' + branchCode + '}';
                +  }
                +  return code + '\n';
                +};
                +
                +Blockly.PHP['controls_ifelse'] = Blockly.PHP['controls_if'];
                +
                +Blockly.PHP['logic_compare'] = function(block) {
                +  // Comparison operator.
                +  var OPERATORS = {
                +    'EQ': '==',
                +    'NEQ': '!=',
                +    'LT': '<',
                +    'LTE': '<=',
                +    'GT': '>',
                +    'GTE': '>='
                +  };
                +  var operator = OPERATORS[block.getFieldValue('OP')];
                +  var order = (operator == '==' || operator == '!=') ?
                +      Blockly.PHP.ORDER_EQUALITY : Blockly.PHP.ORDER_RELATIONAL;
                +  var argument0 = Blockly.PHP.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.PHP['logic_operation'] = function(block) {
                +  // Operations 'and', 'or'.
                +  var operator = (block.getFieldValue('OP') == 'AND') ? '&&' : '||';
                +  var order = (operator == '&&') ? Blockly.PHP.ORDER_LOGICAL_AND :
                +      Blockly.PHP.ORDER_LOGICAL_OR;
                +  var argument0 = Blockly.PHP.valueToCode(block, 'A', order);
                +  var argument1 = Blockly.PHP.valueToCode(block, 'B', order);
                +  if (!argument0 && !argument1) {
                +    // If there are no arguments, then the return value is false.
                +    argument0 = 'false';
                +    argument1 = 'false';
                +  } else {
                +    // Single missing arguments have no effect on the return value.
                +    var defaultArgument = (operator == '&&') ? 'true' : 'false';
                +    if (!argument0) {
                +      argument0 = defaultArgument;
                +    }
                +    if (!argument1) {
                +      argument1 = defaultArgument;
                +    }
                +  }
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.PHP['logic_negate'] = function(block) {
                +  // Negation.
                +  var order = Blockly.PHP.ORDER_LOGICAL_NOT;
                +  var argument0 = Blockly.PHP.valueToCode(block, 'BOOL', order) ||
                +      'true';
                +  var code = '!' + argument0;
                +  return [code, order];
                +};
                +
                +Blockly.PHP['logic_boolean'] = function(block) {
                +  // Boolean values true and false.
                +  var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false';
                +  return [code, Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['logic_null'] = function(block) {
                +  // Null data type.
                +  return ['null', Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['logic_ternary'] = function(block) {
                +  // Ternary operator.
                +  var value_if = Blockly.PHP.valueToCode(block, 'IF',
                +      Blockly.PHP.ORDER_CONDITIONAL) || 'false';
                +  var value_then = Blockly.PHP.valueToCode(block, 'THEN',
                +      Blockly.PHP.ORDER_CONDITIONAL) || 'null';
                +  var value_else = Blockly.PHP.valueToCode(block, 'ELSE',
                +      Blockly.PHP.ORDER_CONDITIONAL) || 'null';
                +  var code = value_if + ' ? ' + value_then + ' : ' + value_else;
                +  return [code, Blockly.PHP.ORDER_CONDITIONAL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/loops.js b/blockly/webif/static/blockly/generators/php/loops.js
                new file mode 100644
                index 000000000..f306b1053
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/loops.js
                @@ -0,0 +1,164 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for loop blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.loops');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['controls_repeat_ext'] = function(block) {
                +  // Repeat n times.
                +  if (block.getField('TIMES')) {
                +    // Internal number.
                +    var repeats = String(Number(block.getFieldValue('TIMES')));
                +  } else {
                +    // External number.
                +    var repeats = Blockly.PHP.valueToCode(block, 'TIMES',
                +        Blockly.PHP.ORDER_ASSIGNMENT) || '0';
                +  }
                +  var branch = Blockly.PHP.statementToCode(block, 'DO');
                +  branch = Blockly.PHP.addLoopTrap(branch, block.id);
                +  var code = '';
                +  var loopVar = Blockly.PHP.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var endVar = repeats;
                +  if (!repeats.match(/^\w+$/) && !Blockly.isNumber(repeats)) {
                +    var endVar = Blockly.PHP.variableDB_.getDistinctName(
                +        'repeat_end', Blockly.Variables.NAME_TYPE);
                +    code += endVar + ' = ' + repeats + ';\n';
                +  }
                +  code += 'for (' + loopVar + ' = 0; ' +
                +      loopVar + ' < ' + endVar + '; ' +
                +      loopVar + '++) {\n' +
                +      branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.PHP['controls_repeat'] = Blockly.PHP['controls_repeat_ext'];
                +
                +Blockly.PHP['controls_whileUntil'] = function(block) {
                +  // Do while/until loop.
                +  var until = block.getFieldValue('MODE') == 'UNTIL';
                +  var argument0 = Blockly.PHP.valueToCode(block, 'BOOL',
                +      until ? Blockly.PHP.ORDER_LOGICAL_NOT :
                +      Blockly.PHP.ORDER_NONE) || 'false';
                +  var branch = Blockly.PHP.statementToCode(block, 'DO');
                +  branch = Blockly.PHP.addLoopTrap(branch, block.id);
                +  if (until) {
                +    argument0 = '!' + argument0;
                +  }
                +  return 'while (' + argument0 + ') {\n' + branch + '}\n';
                +};
                +
                +Blockly.PHP['controls_for'] = function(block) {
                +  // For loop.
                +  var variable0 = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.PHP.valueToCode(block, 'FROM',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'TO',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || '0';
                +  var increment = Blockly.PHP.valueToCode(block, 'BY',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || '1';
                +  var branch = Blockly.PHP.statementToCode(block, 'DO');
                +  branch = Blockly.PHP.addLoopTrap(branch, block.id);
                +  var code;
                +  if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) &&
                +      Blockly.isNumber(increment)) {
                +    // All arguments are simple numbers.
                +    var up = parseFloat(argument0) <= parseFloat(argument1);
                +    code = 'for (' + variable0 + ' = ' + argument0 + '; ' +
                +        variable0 + (up ? ' <= ' : ' >= ') + argument1 + '; ' +
                +        variable0;
                +    var step = Math.abs(parseFloat(increment));
                +    if (step == 1) {
                +      code += up ? '++' : '--';
                +    } else {
                +      code += (up ? ' += ' : ' -= ') + step;
                +    }
                +    code += ') {\n' + branch + '}\n';
                +  } else {
                +    code = '';
                +    // Cache non-trivial values to variables to prevent repeated look-ups.
                +    var startVar = argument0;
                +    if (!argument0.match(/^\w+$/) && !Blockly.isNumber(argument0)) {
                +      startVar = Blockly.PHP.variableDB_.getDistinctName(
                +          variable0 + '_start', Blockly.Variables.NAME_TYPE);
                +      code += startVar + ' = ' + argument0 + ';\n';
                +    }
                +    var endVar = argument1;
                +    if (!argument1.match(/^\w+$/) && !Blockly.isNumber(argument1)) {
                +      var endVar = Blockly.PHP.variableDB_.getDistinctName(
                +          variable0 + '_end', Blockly.Variables.NAME_TYPE);
                +      code += endVar + ' = ' + argument1 + ';\n';
                +    }
                +    // Determine loop direction at start, in case one of the bounds
                +    // changes during loop execution.
                +    var incVar = Blockly.PHP.variableDB_.getDistinctName(
                +        variable0 + '_inc', Blockly.Variables.NAME_TYPE);
                +    code += incVar + ' = ';
                +    if (Blockly.isNumber(increment)) {
                +      code += Math.abs(increment) + ';\n';
                +    } else {
                +      code += 'abs(' + increment + ');\n';
                +    }
                +    code += 'if (' + startVar + ' > ' + endVar + ') {\n';
                +    code += Blockly.PHP.INDENT + incVar + ' = -' + incVar + ';\n';
                +    code += '}\n';
                +    code += 'for (' + variable0 + ' = ' + startVar + '; ' +
                +        incVar + ' >= 0 ? ' +
                +        variable0 + ' <= ' + endVar + ' : ' +
                +        variable0 + ' >= ' + endVar + '; ' +
                +        variable0 + ' += ' + incVar + ') {\n' +
                +        branch + '}\n';
                +  }
                +  return code;
                +};
                +
                +Blockly.PHP['controls_forEach'] = function(block) {
                +  // For each loop.
                +  var variable0 = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.PHP.valueToCode(block, 'LIST',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || '[]';
                +  var branch = Blockly.PHP.statementToCode(block, 'DO');
                +  branch = Blockly.PHP.addLoopTrap(branch, block.id);
                +  var code = '';
                +  code += 'foreach (' + argument0 + ' as ' + variable0 +
                +      ') {\n' + branch + '}\n';
                +  return code;
                +};
                +
                +Blockly.PHP['controls_flow_statements'] = function(block) {
                +  // Flow statements: continue, break.
                +  switch (block.getFieldValue('FLOW')) {
                +    case 'BREAK':
                +      return 'break;\n';
                +    case 'CONTINUE':
                +      return 'continue;\n';
                +  }
                +  throw 'Unknown flow statement.';
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/math.js b/blockly/webif/static/blockly/generators/php/math.js
                new file mode 100644
                index 000000000..7789ba8fe
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/math.js
                @@ -0,0 +1,372 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for math blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.math');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['math_number'] = function(block) {
                +  // Numeric value.
                +  var code = parseFloat(block.getFieldValue('NUM'));
                +  if (code == Infinity) {
                +    code = 'INF';
                +  } else if (code == -Infinity) {
                +    code = '-INF';
                +  }
                +  return [code, Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['math_arithmetic'] = function(block) {
                +  // Basic arithmetic operators, and power.
                +  var OPERATORS = {
                +    'ADD': [' + ', Blockly.PHP.ORDER_ADDITION],
                +    'MINUS': [' - ', Blockly.PHP.ORDER_SUBTRACTION],
                +    'MULTIPLY': [' * ', Blockly.PHP.ORDER_MULTIPLICATION],
                +    'DIVIDE': [' / ', Blockly.PHP.ORDER_DIVISION],
                +    'POWER': [' ** ', Blockly.PHP.ORDER_POWER]
                +  };
                +  var tuple = OPERATORS[block.getFieldValue('OP')];
                +  var operator = tuple[0];
                +  var order = tuple[1];
                +  var argument0 = Blockly.PHP.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + operator + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.PHP['math_single'] = function(block) {
                +  // Math operators with single operand.
                +  var operator = block.getFieldValue('OP');
                +  var code;
                +  var arg;
                +  if (operator == 'NEG') {
                +    // Negation is a special case given its different operator precedence.
                +    arg = Blockly.PHP.valueToCode(block, 'NUM',
                +        Blockly.PHP.ORDER_UNARY_NEGATION) || '0';
                +    if (arg[0] == '-') {
                +      // --3 is not legal in JS.
                +      arg = ' ' + arg;
                +    }
                +    code = '-' + arg;
                +    return [code, Blockly.PHP.ORDER_UNARY_NEGATION];
                +  }
                +  if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
                +    arg = Blockly.PHP.valueToCode(block, 'NUM',
                +        Blockly.PHP.ORDER_DIVISION) || '0';
                +  } else {
                +    arg = Blockly.PHP.valueToCode(block, 'NUM',
                +        Blockly.PHP.ORDER_NONE) || '0';
                +  }
                +  // First, handle cases which generate values that don't need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'ABS':
                +      code = 'abs(' + arg + ')';
                +      break;
                +    case 'ROOT':
                +      code = 'sqrt(' + arg + ')';
                +      break;
                +    case 'LN':
                +      code = 'log(' + arg + ')';
                +      break;
                +    case 'EXP':
                +      code = 'exp(' + arg + ')';
                +      break;
                +    case 'POW10':
                +      code = 'pow(10,' + arg + ')';
                +      break;
                +    case 'ROUND':
                +      code = 'round(' + arg + ')';
                +      break;
                +    case 'ROUNDUP':
                +      code = 'ceil(' + arg + ')';
                +      break;
                +    case 'ROUNDDOWN':
                +      code = 'floor(' + arg + ')';
                +      break;
                +    case 'SIN':
                +      code = 'sin(' + arg + ' / 180 * pi())';
                +      break;
                +    case 'COS':
                +      code = 'cos(' + arg + ' / 180 * pi())';
                +      break;
                +    case 'TAN':
                +      code = 'tan(' + arg + ' / 180 * pi())';
                +      break;
                +  }
                +  if (code) {
                +    return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +  }
                +  // Second, handle cases which generate values that may need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'LOG10':
                +      code = 'log(' + arg + ') / log(10)';
                +      break;
                +    case 'ASIN':
                +      code = 'asin(' + arg + ') / pi() * 180';
                +      break;
                +    case 'ACOS':
                +      code = 'acos(' + arg + ') / pi() * 180';
                +      break;
                +    case 'ATAN':
                +      code = 'atan(' + arg + ') / pi() * 180';
                +      break;
                +    default:
                +      throw 'Unknown math operator: ' + operator;
                +  }
                +  return [code, Blockly.PHP.ORDER_DIVISION];
                +};
                +
                +Blockly.PHP['math_constant'] = function(block) {
                +  // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  var CONSTANTS = {
                +    'PI': ['M_PI', Blockly.PHP.ORDER_ATOMIC],
                +    'E': ['M_E', Blockly.PHP.ORDER_ATOMIC],
                +    'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.PHP.ORDER_DIVISION],
                +    'SQRT2': ['M_SQRT2', Blockly.PHP.ORDER_ATOMIC],
                +    'SQRT1_2': ['M_SQRT1_2', Blockly.PHP.ORDER_ATOMIC],
                +    'INFINITY': ['INF', Blockly.PHP.ORDER_ATOMIC]
                +  };
                +  return CONSTANTS[block.getFieldValue('CONSTANT')];
                +};
                +
                +Blockly.PHP['math_number_property'] = function(block) {
                +  // Check if a number is even, odd, prime, whole, positive, or negative
                +  // or if it is divisible by certain number. Returns true or false.
                +  var number_to_check = Blockly.PHP.valueToCode(block, 'NUMBER_TO_CHECK',
                +      Blockly.PHP.ORDER_MODULUS) || '0';
                +  var dropdown_property = block.getFieldValue('PROPERTY');
                +  var code;
                +  if (dropdown_property == 'PRIME') {
                +    // Prime is a special case as it is not a one-liner test.
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'math_isPrime',
                +        ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($n) {',
                +         '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
                +         '  if ($n == 2 || $n == 3) {',
                +         '    return true;',
                +         '  }',
                +         '  // False if n is NaN, negative, is 1, or not whole.',
                +         '  // And false if n is divisible by 2 or 3.',
                +         '  if (!is_numeric($n) || $n <= 1 || $n % 1 != 0 || $n % 2 == 0 ||' +
                +            ' $n % 3 == 0) {',
                +         '    return false;',
                +         '  }',
                +         '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
                +         '  for ($x = 6; $x <= sqrt($n) + 1; $x += 6) {',
                +         '    if ($n % ($x - 1) == 0 || $n % ($x + 1) == 0) {',
                +         '      return false;',
                +         '    }',
                +         '  }',
                +         '  return true;',
                +         '}']);
                +    code = functionName + '(' + number_to_check + ')';
                +    return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL];
                +  }
                +  switch (dropdown_property) {
                +    case 'EVEN':
                +      code = number_to_check + ' % 2 == 0';
                +      break;
                +    case 'ODD':
                +      code = number_to_check + ' % 2 == 1';
                +      break;
                +    case 'WHOLE':
                +      code = 'is_int(' + number_to_check + ')';
                +      break;
                +    case 'POSITIVE':
                +      code = number_to_check + ' > 0';
                +      break;
                +    case 'NEGATIVE':
                +      code = number_to_check + ' < 0';
                +      break;
                +    case 'DIVISIBLE_BY':
                +      var divisor = Blockly.PHP.valueToCode(block, 'DIVISOR',
                +          Blockly.PHP.ORDER_MODULUS) || '0';
                +      code = number_to_check + ' % ' + divisor + ' == 0';
                +      break;
                +  }
                +  return [code, Blockly.PHP.ORDER_EQUALITY];
                +};
                +
                +Blockly.PHP['math_change'] = function(block) {
                +  // Add to a variable in place.
                +  var argument0 = Blockly.PHP.valueToCode(block, 'DELTA',
                +      Blockly.PHP.ORDER_ADDITION) || '0';
                +  var varName = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  return varName + ' += ' + argument0 + ';\n';
                +};
                +
                +// Rounding functions have a single operand.
                +Blockly.PHP['math_round'] = Blockly.PHP['math_single'];
                +// Trigonometry functions have a single operand.
                +Blockly.PHP['math_trig'] = Blockly.PHP['math_single'];
                +
                +Blockly.PHP['math_on_list'] = function(block) {
                +  // Math functions for lists.
                +  var func = block.getFieldValue('OP');
                +  var list, code;
                +  switch (func) {
                +    case 'SUM':
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
                +      code = 'array_sum(' + list + ')';
                +      break;
                +    case 'MIN':
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
                +      code = 'min(' + list + ')';
                +      break;
                +    case 'MAX':
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_FUNCTION_CALL) || 'array()';
                +      code = 'max(' + list + ')';
                +      break;
                +    case 'AVERAGE':
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'math_mean',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +              '($myList) {',
                +           '  return array_sum($myList) / count($myList);',
                +           '}']);
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_NONE) || 'array()';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MEDIAN':
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'math_median',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +              '($arr) {',
                +           '  sort($arr,SORT_NUMERIC);',
                +           '  return (count($arr) % 2) ? $arr[floor(count($arr)/2)] : ',
                +           '      ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2)' +
                +              ' - 1]) / 2;',
                +           '}']);
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MODE':
                +      // As a list of numbers can contain more than one mode,
                +      // the returned result is provided as an array.
                +      // Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'math_modes',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +              '($values) {',
                +           '  if (empty($values)) return array();',
                +           '  $counts = array_count_values($values);',
                +           '  arsort($counts); // Sort counts in descending order',
                +           '  $modes = array_keys($counts, current($counts), true);',
                +           '  return $modes;',
                +           '}']);
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'STD_DEV':
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'math_standard_deviation',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +              '($numbers) {',
                +           '  $n = count($numbers);',
                +           '  if (!$n) return null;',
                +           '  $mean = array_sum($numbers) / count($numbers);',
                +           '  foreach($numbers as $key => $num) $devs[$key] = ' +
                +              'pow($num - $mean, 2);',
                +           '  return sqrt(array_sum($devs) / (count($devs) - 1));',
                +           '}']);
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +              Blockly.PHP.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'RANDOM':
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'math_random_list',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +              '($list) {',
                +           '  $x = rand(0, count($list)-1);',
                +           '  return $list[$x];',
                +           '}']);
                +      list = Blockly.PHP.valueToCode(block, 'LIST',
                +          Blockly.PHP.ORDER_NONE) || '[]';
                +      code = functionName + '(' + list + ')';
                +      break;
                +    default:
                +      throw 'Unknown operator: ' + func;
                +  }
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['math_modulo'] = function(block) {
                +  // Remainder computation.
                +  var argument0 = Blockly.PHP.valueToCode(block, 'DIVIDEND',
                +      Blockly.PHP.ORDER_MODULUS) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'DIVISOR',
                +      Blockly.PHP.ORDER_MODULUS) || '0';
                +  var code = argument0 + ' % ' + argument1;
                +  return [code, Blockly.PHP.ORDER_MODULUS];
                +};
                +
                +Blockly.PHP['math_constrain'] = function(block) {
                +  // Constrain a number between two limits.
                +  var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_COMMA) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'LOW',
                +      Blockly.PHP.ORDER_COMMA) || '0';
                +  var argument2 = Blockly.PHP.valueToCode(block, 'HIGH',
                +      Blockly.PHP.ORDER_COMMA) || 'Infinity';
                +  var code = 'min(max(' + argument0 + ', ' + argument1 + '), ' +
                +      argument2 + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['math_random_int'] = function(block) {
                +  // Random integer between [X] and [Y].
                +  var argument0 = Blockly.PHP.valueToCode(block, 'FROM',
                +      Blockly.PHP.ORDER_COMMA) || '0';
                +  var argument1 = Blockly.PHP.valueToCode(block, 'TO',
                +      Blockly.PHP.ORDER_COMMA) || '0';
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'math_random_int',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($a, $b) {',
                +       '  if ($a > $b) {',
                +       '    return rand($b, $a);',
                +       '  }',
                +       '  return rand($a, $b);',
                +       '}']);
                +  var code = functionName + '(' + argument0 + ', ' + argument1 + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['math_random_float'] = function(block) {
                +  // Random fraction between 0 and 1.
                +  return ['(float)rand()/(float)getrandmax()', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/procedures.js b/blockly/webif/static/blockly/generators/php/procedures.js
                new file mode 100644
                index 000000000..ac4f0244e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/procedures.js
                @@ -0,0 +1,123 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for procedure blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.procedures');
                +
                +goog.require('Blockly.PHP');
                +
                +Blockly.PHP['procedures_defreturn'] = function(block) {
                +  // Define a procedure with a return value.
                +  // First, add a 'global' statement for every variable that is not shadowed by
                +  // a local parameter.
                +  var globals = [];
                +  var varName;
                +  var workspace = block.workspace;
                +  var variables = workspace.getAllVariables() || [];
                +  for (var i = 0, variable; variable = variables[i]; i++) {
                +    varName = variable.name;
                +    if (block.arguments_.indexOf(varName) == -1) {
                +      globals.push(Blockly.PHP.variableDB_.getName(varName,
                +          Blockly.Variables.NAME_TYPE));
                +    }
                +  }
                +  globals = globals.length ? '  global ' + globals.join(', ') + ';\n' : '';
                +
                +  var funcName = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var branch = Blockly.PHP.statementToCode(block, 'STACK');
                +  if (Blockly.PHP.STATEMENT_PREFIX) {
                +    branch = Blockly.PHP.prefixLines(
                +        Blockly.PHP.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + block.id + '\''), Blockly.PHP.INDENT) + branch;
                +  }
                +  if (Blockly.PHP.INFINITE_LOOP_TRAP) {
                +    branch = Blockly.PHP.INFINITE_LOOP_TRAP.replace(/%1/g,
                +        '\'' + block.id + '\'') + branch;
                +  }
                +  var returnValue = Blockly.PHP.valueToCode(block, 'RETURN',
                +      Blockly.PHP.ORDER_NONE) || '';
                +  if (returnValue) {
                +    returnValue = '  return ' + returnValue + ';\n';
                +  }
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.PHP.variableDB_.getName(block.arguments_[i],
                +        Blockly.Variables.NAME_TYPE);
                +  }
                +  var code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' +
                +      globals + branch + returnValue + '}';
                +  code = Blockly.PHP.scrub_(block, code);
                +  // Add % so as not to collide with helper functions in definitions list.
                +  Blockly.PHP.definitions_['%' + funcName] = code;
                +  return null;
                +};
                +
                +// Defining a procedure without a return value uses the same generator as
                +// a procedure with a return value.
                +Blockly.PHP['procedures_defnoreturn'] =
                +    Blockly.PHP['procedures_defreturn'];
                +
                +Blockly.PHP['procedures_callreturn'] = function(block) {
                +  // Call a procedure with a return value.
                +  var funcName = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i,
                +        Blockly.PHP.ORDER_COMMA) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['procedures_callnoreturn'] = function(block) {
                +  // Call a procedure with no return value.
                +  var funcName = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.PHP.valueToCode(block, 'ARG' + i,
                +        Blockly.PHP.ORDER_COMMA) || 'null';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ');\n';
                +  return code;
                +};
                +
                +Blockly.PHP['procedures_ifreturn'] = function(block) {
                +  // Conditionally return value from a procedure.
                +  var condition = Blockly.PHP.valueToCode(block, 'CONDITION',
                +      Blockly.PHP.ORDER_NONE) || 'false';
                +  var code = 'if (' + condition + ') {\n';
                +  if (block.hasReturnValue_) {
                +    var value = Blockly.PHP.valueToCode(block, 'VALUE',
                +        Blockly.PHP.ORDER_NONE) || 'null';
                +    code += '  return ' + value + ';\n';
                +  } else {
                +    code += '  return;\n';
                +  }
                +  code += '}\n';
                +  return code;
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/text.js b/blockly/webif/static/blockly/generators/php/text.js
                new file mode 100644
                index 000000000..7903d31e7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/text.js
                @@ -0,0 +1,279 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for text blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.texts');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['text'] = function(block) {
                +  // Text value.
                +  var code = Blockly.PHP.quote_(block.getFieldValue('TEXT'));
                +  return [code, Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['text_join'] = function(block) {
                +  // Create a string made up of any number of elements of any type.
                +  if (block.itemCount_ == 0) {
                +    return ['\'\'', Blockly.PHP.ORDER_ATOMIC];
                +  } else if (block.itemCount_ == 1) {
                +    var element = Blockly.PHP.valueToCode(block, 'ADD0',
                +        Blockly.PHP.ORDER_NONE) || '\'\'';
                +    var code = element;
                +    return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +  } else if (block.itemCount_ == 2) {
                +    var element0 = Blockly.PHP.valueToCode(block, 'ADD0',
                +        Blockly.PHP.ORDER_NONE) || '\'\'';
                +    var element1 = Blockly.PHP.valueToCode(block, 'ADD1',
                +        Blockly.PHP.ORDER_NONE) || '\'\'';
                +    var code = element0 + ' . ' + element1;
                +    return [code, Blockly.PHP.ORDER_ADDITION];
                +  } else {
                +    var elements = new Array(block.itemCount_);
                +    for (var i = 0; i < block.itemCount_; i++) {
                +      elements[i] = Blockly.PHP.valueToCode(block, 'ADD' + i,
                +          Blockly.PHP.ORDER_COMMA) || '\'\'';
                +    }
                +    var code = 'implode(\'\', array(' + elements.join(',') + '))';
                +    return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +  }
                +};
                +
                +Blockly.PHP['text_append'] = function(block) {
                +  // Append to a variable in place.
                +  var varName = Blockly.PHP.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var value = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_ASSIGNMENT) || '\'\'';
                +  return varName + ' .= ' + value + ';\n';
                +};
                +
                +Blockly.PHP['text_length'] = function(block) {
                +  // String or array length.
                +  var functionName = Blockly.PHP.provideFunction_(
                +      'length',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($value) {',
                +       '  if (is_string($value)) {',
                +       '    return strlen($value);',
                +       '  } else {',
                +       '    return count($value);',
                +       '  }',
                +       '}']);
                +  var text = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  return [functionName + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  return ['empty(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_indexOf'] = function(block) {
                +  // Search the text for a substring.
                +  var operator = block.getFieldValue('END') == 'FIRST' ?
                +      'strpos' : 'strrpos';
                +  var substring = Blockly.PHP.valueToCode(block, 'FIND',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  var text = Blockly.PHP.valueToCode(block, 'VALUE',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  if (block.workspace.options.oneBasedIndex) {
                +    var errorIndex = ' 0';
                +    var indexAdjustment = ' + 1';
                +  } else {
                +    var errorIndex = ' -1';
                +    var indexAdjustment = '';
                +  }
                +  var functionName = Blockly.PHP.provideFunction_(
                +      block.getFieldValue('END') == 'FIRST' ?
                +          'text_indexOf' : 'text_lastIndexOf',
                +      ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +          '($text, $search) {',
                +       '  $pos = ' + operator + '($text, $search);',
                +       '  return $pos === false ? ' + errorIndex + ' : $pos' +
                +          indexAdjustment + ';',
                +       '}']);
                +  var code = functionName + '(' + text + ', ' + substring + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_charAt'] = function(block) {
                +  // Get letter at index.
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var textOrder = (where == 'RANDOM') ? Blockly.PHP.ORDER_NONE :
                +      Blockly.PHP.ORDER_COMMA;
                +  var text = Blockly.PHP.valueToCode(block, 'VALUE', textOrder) || '\'\'';
                +  switch (where) {
                +    case 'FIRST':
                +      var code = 'substr(' + text + ', 0, 1)';
                +      return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +    case 'LAST':
                +      var code = 'substr(' + text + ', -1)';
                +      return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +    case 'FROM_START':
                +      var at = Blockly.PHP.getAdjusted(block, 'AT');
                +      var code = 'substr(' + text + ', ' + at + ', 1)';
                +      return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +    case 'FROM_END':
                +      var at = Blockly.PHP.getAdjusted(block, 'AT', 1, true);
                +      var code = 'substr(' + text + ', ' + at + ', 1)';
                +      return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +    case 'RANDOM':
                +      var functionName = Blockly.PHP.provideFunction_(
                +          'text_random_letter',
                +          ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '($text) {',
                +           '  return $text[rand(0, strlen($text) - 1)];',
                +           '}']);
                +      code = functionName + '(' + text + ')';
                +      return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +  }
                +  throw 'Unhandled option (text_charAt).';
                +};
                +
                +Blockly.PHP['text_getSubstring'] = function(block) {
                +  // Get substring.
                +  var text = Blockly.PHP.valueToCode(block, 'STRING',
                +      Blockly.PHP.ORDER_FUNCTION_CALL) || '\'\'';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  if (where1 == 'FIRST' && where2 == 'LAST') {
                +    var code = text;
                +  } else {
                +    var at1 = Blockly.PHP.getAdjusted(block, 'AT1');
                +    var at2 = Blockly.PHP.getAdjusted(block, 'AT2');
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'text_get_substring',
                +        ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +            '($text, $where1, $at1, $where2, $at2) {',
                +         '  if ($where1 == \'FROM_END\') {',
                +         '    $at1 = strlen($text) - 1 - $at1;',
                +         '  } else if ($where1 == \'FIRST\') {',
                +         '    $at1 = 0;',
                +         '  } else if ($where1 != \'FROM_START\'){',
                +         '    throw new Exception(\'Unhandled option (text_get_substring).\');',
                +         '  }',
                +         '  $length = 0;',
                +         '  if ($where2 == \'FROM_START\') {',
                +         '    $length = $at2 - $at1 + 1;',
                +         '  } else if ($where2 == \'FROM_END\') {',
                +         '    $length = strlen($text) - $at1 - $at2;',
                +         '  } else if ($where2 == \'LAST\') {',
                +         '    $length = strlen($text) - $at1;',
                +         '  } else {',
                +         '    throw new Exception(\'Unhandled option (text_get_substring).\');',
                +         '  }',
                +         '  return substr($text, $at1, $length);',
                +         '}']);
                +    var code = functionName + '(' + text + ', \'' +
                +        where1 + '\', ' + at1 + ', \'' + where2 + '\', ' + at2 + ')';
                +  }
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_changeCase'] = function(block) {
                +  // Change capitalization.
                +  var text = Blockly.PHP.valueToCode(block, 'TEXT',
                +          Blockly.PHP.ORDER_NONE) || '\'\'';
                +  if (block.getFieldValue('CASE') == 'UPPERCASE') {
                +    var code = 'strtoupper(' + text + ')';
                +  } else if (block.getFieldValue('CASE') == 'LOWERCASE') {
                +    var code = 'strtolower(' + text + ')';
                +  } else if (block.getFieldValue('CASE') == 'TITLECASE') {
                +    var code = 'ucwords(strtolower(' + text + '))';
                +  }
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_trim'] = function(block) {
                +  // Trim spaces.
                +  var OPERATORS = {
                +    'LEFT': 'ltrim',
                +    'RIGHT': 'rtrim',
                +    'BOTH': 'trim'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('MODE')];
                +  var text = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  return [operator + '(' + text + ')', Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_print'] = function(block) {
                +  // Print statement.
                +  var msg = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  return 'print(' + msg + ');\n';
                +};
                +
                +Blockly.PHP['text_prompt_ext'] = function(block) {
                +  // Prompt function.
                +  if (block.getField('TEXT')) {
                +    // Internal message.
                +    var msg = Blockly.PHP.quote_(block.getFieldValue('TEXT'));
                +  } else {
                +    // External message.
                +    var msg = Blockly.PHP.valueToCode(block, 'TEXT',
                +        Blockly.PHP.ORDER_NONE) || '\'\'';
                +  }
                +  var code = 'readline(' + msg + ')';
                +  var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
                +  if (toNumber) {
                +    code = 'floatval(' + code + ')';
                +  }
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_prompt'] = Blockly.PHP['text_prompt_ext'];
                +
                +Blockly.PHP['text_count'] = function(block) {
                +  var text = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_MEMBER) || '\'\'';
                +  var sub = Blockly.PHP.valueToCode(block, 'SUB',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  var code = 'strlen(' + sub + ') === 0'
                +    + ' ? strlen(' + text + ') + 1'
                +    + ' : substr_count(' + text + ', ' + sub + ')';
                +  return [code, Blockly.PHP.ORDER_CONDITIONAL];
                +};
                +
                +Blockly.PHP['text_replace'] = function(block) {
                +  var text = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_MEMBER) || '\'\'';
                +  var from = Blockly.PHP.valueToCode(block, 'FROM',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  var to = Blockly.PHP.valueToCode(block, 'TO',
                +      Blockly.PHP.ORDER_NONE) || '\'\'';
                +  var code = 'str_replace(' + from + ', ' + to + ', ' + text + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.PHP['text_reverse'] = function(block) {
                +  var text = Blockly.PHP.valueToCode(block, 'TEXT',
                +      Blockly.PHP.ORDER_MEMBER) || '\'\'';
                +  var code = 'strrev(' + text + ')';
                +  return [code, Blockly.PHP.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/php/variables.js b/blockly/webif/static/blockly/generators/php/variables.js
                new file mode 100644
                index 000000000..466774b3f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/php/variables.js
                @@ -0,0 +1,46 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for variable blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.PHP.variables');
                +
                +goog.require('Blockly.PHP');
                +
                +
                +Blockly.PHP['variables_get'] = function(block) {
                +    // Variable getter.
                +    var code = Blockly.PHP.variableDB_.getName(block.getFieldValue('VAR'),
                +        Blockly.Variables.NAME_TYPE);
                +    return [code, Blockly.PHP.ORDER_ATOMIC];
                +};
                +
                +Blockly.PHP['variables_set'] = function(block) {
                +    // Variable setter.
                +    var argument0 = Blockly.PHP.valueToCode(block, 'VALUE',
                +            Blockly.PHP.ORDER_ASSIGNMENT) || '0';
                +    var varName = Blockly.PHP.variableDB_.getName(
                +        block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +    return varName + ' = ' + argument0 + ';\n';
                +};
                diff --git a/blockly/webif/static/blockly/generators/python.js b/blockly/webif/static/blockly/generators/python.js
                new file mode 100644
                index 000000000..e81a04234
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python.js
                @@ -0,0 +1,313 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Helper functions for generating Python for blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python');
                +
                +goog.require('Blockly.Generator');
                +
                +
                +/**
                + * Python code generator.
                + * @type {!Blockly.Generator}
                + */
                +Blockly.Python = new Blockly.Generator('Python');
                +
                +/**
                + * List of illegal variable names.
                + * This is not intended to be a security feature.  Blockly is 100% client-side,
                + * so bypassing this list is trivial.  This is intended to prevent users from
                + * accidentally clobbering a built-in object or function.
                + * @private
                + */
                +Blockly.Python.addReservedWords(
                +    // import keyword
                +    // print(','.join(sorted(keyword.kwlist)))
                +    // https://docs.python.org/3/reference/lexical_analysis.html#keywords
                +    // https://docs.python.org/2/reference/lexical_analysis.html#keywords
                +    'False,None,True,and,as,assert,break,class,continue,def,del,elif,else,' +
                +    'except,exec,finally,for,from,global,if,import,in,is,lambda,nonlocal,not,' +
                +    'or,pass,print,raise,return,try,while,with,yield,' +
                +    // https://docs.python.org/3/library/constants.html
                +    // https://docs.python.org/2/library/constants.html
                +    'NotImplemented,Ellipsis,__debug__,quit,exit,copyright,license,credits,' +
                +    // >>> print(','.join(sorted(dir(__builtins__))))
                +    // https://docs.python.org/3/library/functions.html
                +    // https://docs.python.org/2/library/functions.html
                +    'ArithmeticError,AssertionError,AttributeError,BaseException,' +
                +    'BlockingIOError,BrokenPipeError,BufferError,BytesWarning,' +
                +    'ChildProcessError,ConnectionAbortedError,ConnectionError,' +
                +    'ConnectionRefusedError,ConnectionResetError,DeprecationWarning,EOFError,' +
                +    'Ellipsis,EnvironmentError,Exception,FileExistsError,FileNotFoundError,' +
                +    'FloatingPointError,FutureWarning,GeneratorExit,IOError,ImportError,' +
                +    'ImportWarning,IndentationError,IndexError,InterruptedError,' +
                +    'IsADirectoryError,KeyError,KeyboardInterrupt,LookupError,MemoryError,' +
                +    'ModuleNotFoundError,NameError,NotADirectoryError,NotImplemented,' +
                +    'NotImplementedError,OSError,OverflowError,PendingDeprecationWarning,' +
                +    'PermissionError,ProcessLookupError,RecursionError,ReferenceError,' +
                +    'ResourceWarning,RuntimeError,RuntimeWarning,StandardError,' +
                +    'StopAsyncIteration,StopIteration,SyntaxError,SyntaxWarning,SystemError,' +
                +    'SystemExit,TabError,TimeoutError,TypeError,UnboundLocalError,' +
                +    'UnicodeDecodeError,UnicodeEncodeError,UnicodeError,' +
                +    'UnicodeTranslateError,UnicodeWarning,UserWarning,ValueError,Warning,' +
                +    'ZeroDivisionError,_,__build_class__,__debug__,__doc__,__import__,' +
                +    '__loader__,__name__,__package__,__spec__,abs,all,any,apply,ascii,' +
                +    'basestring,bin,bool,buffer,bytearray,bytes,callable,chr,classmethod,cmp,' +
                +    'coerce,compile,complex,copyright,credits,delattr,dict,dir,divmod,' +
                +    'enumerate,eval,exec,execfile,exit,file,filter,float,format,frozenset,' +
                +    'getattr,globals,hasattr,hash,help,hex,id,input,int,intern,isinstance,' +
                +    'issubclass,iter,len,license,list,locals,long,map,max,memoryview,min,' +
                +    'next,object,oct,open,ord,pow,print,property,quit,range,raw_input,reduce,' +
                +    'reload,repr,reversed,round,set,setattr,slice,sorted,staticmethod,str,' +
                +    'sum,super,tuple,type,unichr,unicode,vars,xrange,zip'
                +);
                +
                +/**
                + * Order of operation ENUMs.
                + * http://docs.python.org/reference/expressions.html#summary
                + */
                +Blockly.Python.ORDER_ATOMIC = 0;            // 0 "" ...
                +Blockly.Python.ORDER_COLLECTION = 1;        // tuples, lists, dictionaries
                +Blockly.Python.ORDER_STRING_CONVERSION = 1; // `expression...`
                +Blockly.Python.ORDER_MEMBER = 2.1;          // . []
                +Blockly.Python.ORDER_FUNCTION_CALL = 2.2;   // ()
                +Blockly.Python.ORDER_EXPONENTIATION = 3;    // **
                +Blockly.Python.ORDER_UNARY_SIGN = 4;        // + -
                +Blockly.Python.ORDER_BITWISE_NOT = 4;       // ~
                +Blockly.Python.ORDER_MULTIPLICATIVE = 5;    // * / // %
                +Blockly.Python.ORDER_ADDITIVE = 6;          // + -
                +Blockly.Python.ORDER_BITWISE_SHIFT = 7;     // << >>
                +Blockly.Python.ORDER_BITWISE_AND = 8;       // &
                +Blockly.Python.ORDER_BITWISE_XOR = 9;       // ^
                +Blockly.Python.ORDER_BITWISE_OR = 10;       // |
                +Blockly.Python.ORDER_RELATIONAL = 11;       // in, not in, is, is not,
                +                                            //     <, <=, >, >=, <>, !=, ==
                +Blockly.Python.ORDER_LOGICAL_NOT = 12;      // not
                +Blockly.Python.ORDER_LOGICAL_AND = 13;      // and
                +Blockly.Python.ORDER_LOGICAL_OR = 14;       // or
                +Blockly.Python.ORDER_CONDITIONAL = 15;      // if else
                +Blockly.Python.ORDER_LAMBDA = 16;           // lambda
                +Blockly.Python.ORDER_NONE = 99;             // (...)
                +
                +/**
                + * List of outer-inner pairings that do NOT require parentheses.
                + * @type {!Array.<!Array.<number>>}
                + */
                +Blockly.Python.ORDER_OVERRIDES = [
                +  // (foo()).bar -> foo().bar
                +  // (foo())[0] -> foo()[0]
                +  [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_MEMBER],
                +  // (foo())() -> foo()()
                +  [Blockly.Python.ORDER_FUNCTION_CALL, Blockly.Python.ORDER_FUNCTION_CALL],
                +  // (foo.bar).baz -> foo.bar.baz
                +  // (foo.bar)[0] -> foo.bar[0]
                +  // (foo[0]).bar -> foo[0].bar
                +  // (foo[0])[1] -> foo[0][1]
                +  [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_MEMBER],
                +  // (foo.bar)() -> foo.bar()
                +  // (foo[0])() -> foo[0]()
                +  [Blockly.Python.ORDER_MEMBER, Blockly.Python.ORDER_FUNCTION_CALL],
                +
                +  // not (not foo) -> not not foo
                +  [Blockly.Python.ORDER_LOGICAL_NOT, Blockly.Python.ORDER_LOGICAL_NOT],
                +  // a and (b and c) -> a and b and c
                +  [Blockly.Python.ORDER_LOGICAL_AND, Blockly.Python.ORDER_LOGICAL_AND],
                +  // a or (b or c) -> a or b or c
                +  [Blockly.Python.ORDER_LOGICAL_OR, Blockly.Python.ORDER_LOGICAL_OR]
                +];
                +
                +/**
                + * Initialise the database of variable names.
                + * @param {!Blockly.Workspace} workspace Workspace to generate code from.
                + */
                +Blockly.Python.init = function(workspace) {
                +  /**
                +   * Empty loops or conditionals are not allowed in Python.
                +   */
                +  Blockly.Python.PASS = this.INDENT + 'pass\n';
                +  // Create a dictionary of definitions to be printed before the code.
                +  Blockly.Python.definitions_ = Object.create(null);
                +  // Create a dictionary mapping desired function names in definitions_
                +  // to actual function names (to avoid collisions with user functions).
                +  Blockly.Python.functionNames_ = Object.create(null);
                +
                +  if (!Blockly.Python.variableDB_) {
                +    Blockly.Python.variableDB_ =
                +        new Blockly.Names(Blockly.Python.RESERVED_WORDS_);
                +  } else {
                +    Blockly.Python.variableDB_.reset();
                +  }
                +
                +  var defvars = [];
                +  var variables = workspace.getAllVariables();
                +  for (var i = 0; i < variables.length; i++) {
                +    defvars[i] = Blockly.Python.variableDB_.getName(variables[i].name,
                +        Blockly.Variables.NAME_TYPE) + ' = None';
                +  }
                +  Blockly.Python.definitions_['variables'] = defvars.join('\n');
                +};
                +
                +/**
                + * Prepend the generated code with the variable definitions.
                + * @param {string} code Generated code.
                + * @return {string} Completed code.
                + */
                +Blockly.Python.finish = function(code) {
                +  // Convert the definitions dictionary into a list.
                +  var imports = [];
                +  var definitions = [];
                +  for (var name in Blockly.Python.definitions_) {
                +    var def = Blockly.Python.definitions_[name];
                +    if (def.match(/^(from\s+\S+\s+)?import\s+\S+/)) {
                +      imports.push(def);
                +    } else {
                +      definitions.push(def);
                +    }
                +  }
                +  // Clean up temporary data.
                +  delete Blockly.Python.definitions_;
                +  delete Blockly.Python.functionNames_;
                +  Blockly.Python.variableDB_.reset();
                +  var allDefs = imports.join('\n') + '\n\n' + definitions.join('\n\n');
                +  return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n\n') + code;
                +};
                +
                +/**
                + * Naked values are top-level blocks with outputs that aren't plugged into
                + * anything.
                + * @param {string} line Line of generated code.
                + * @return {string} Legal line of code.
                + */
                +Blockly.Python.scrubNakedValue = function(line) {
                +  return line + '\n';
                +};
                +
                +/**
                + * Encode a string as a properly escaped Python string, complete with quotes.
                + * @param {string} string Text to encode.
                + * @return {string} Python string.
                + * @private
                + */
                +Blockly.Python.quote_ = function(string) {
                +  // Can't use goog.string.quote since % must also be escaped.
                +  string = string.replace(/\\/g, '\\\\')
                +                 .replace(/\n/g, '\\\n')
                +                 .replace(/\%/g, '\\%');
                +
                +  // Follow the CPython behaviour of repr() for a non-byte string.
                +  var quote = '\'';
                +  if (string.indexOf('\'') !== -1) {
                +    if (string.indexOf('"') === -1) {
                +      quote = '"';
                +    } else {
                +      string = string.replace(/'/g, '\\\'');
                +    }
                +  };
                +  return quote + string + quote;
                +};
                +
                +/**
                + * Common tasks for generating Python from blocks.
                + * Handles comments for the specified block and any connected value blocks.
                + * Calls any statements following this block.
                + * @param {!Blockly.Block} block The current block.
                + * @param {string} code The Python code created for this block.
                + * @return {string} Python code with comments and subsequent blocks added.
                + * @private
                + */
                +Blockly.Python.scrub_ = function(block, code) {
                +  var commentCode = '';
                +  // Only collect comments for blocks that aren't inline.
                +  if (!block.outputConnection || !block.outputConnection.targetConnection) {
                +    // Collect comment for this block.
                +    var comment = block.getCommentText();
                +    comment = Blockly.utils.wrap(comment, Blockly.Python.COMMENT_WRAP - 3);
                +    if (comment) {
                +      if (block.getProcedureDef) {
                +        // Use a comment block for function comments.
                +        commentCode += '"""' + comment + '\n"""\n';
                +      } else {
                +        commentCode += Blockly.Python.prefixLines(comment + '\n', '# ');
                +      }
                +    }
                +    // Collect comments for all value arguments.
                +    // Don't collect comments for nested statements.
                +    for (var i = 0; i < block.inputList.length; i++) {
                +      if (block.inputList[i].type == Blockly.INPUT_VALUE) {
                +        var childBlock = block.inputList[i].connection.targetBlock();
                +        if (childBlock) {
                +          var comment = Blockly.Python.allNestedComments(childBlock);
                +          if (comment) {
                +            commentCode += Blockly.Python.prefixLines(comment, '# ');
                +          }
                +        }
                +      }
                +    }
                +  }
                +  var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
                +  var nextCode = Blockly.Python.blockToCode(nextBlock);
                +  return commentCode + code + nextCode;
                +};
                +
                +/**
                + * Gets a property and adjusts the value, taking into account indexing, and
                + * casts to an integer.
                + * @param {!Blockly.Block} block The block.
                + * @param {string} atId The property ID of the element to get.
                + * @param {number=} opt_delta Value to add.
                + * @param {boolean=} opt_negate Whether to negate the value.
                + * @return {string|number}
                + */
                +Blockly.Python.getAdjustedInt = function(block, atId, opt_delta, opt_negate) {
                +  var delta = opt_delta || 0;
                +  if (block.workspace.options.oneBasedIndex) {
                +    delta--;
                +  }
                +  var defaultAtIndex = block.workspace.options.oneBasedIndex ? '1' : '0';
                +  var atOrder = delta ? Blockly.Python.ORDER_ADDITIVE :
                +      Blockly.Python.ORDER_NONE;
                +  var at = Blockly.Python.valueToCode(block, atId, atOrder) || defaultAtIndex;
                +
                +  if (Blockly.isNumber(at)) {
                +    // If the index is a naked number, adjust it right now.
                +    at = parseInt(at, 10) + delta;
                +    if (opt_negate) {
                +      at = -at;
                +    }
                +  } else {
                +    // If the index is dynamic, adjust it in code.
                +    if (delta > 0) {
                +      at = 'int(' + at + ' + ' + delta + ')';
                +    } else if (delta < 0) {
                +      at = 'int(' + at + ' - ' + -delta + ')';
                +    } else {
                +      at = 'int(' + at + ')';
                +    }
                +    if (opt_negate) {
                +      at = '-' + at;
                +    }
                +  }
                +  return at;
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/colour.js b/blockly/webif/static/blockly/generators/python/colour.js
                new file mode 100644
                index 000000000..68666a89b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/colour.js
                @@ -0,0 +1,86 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for colour blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.colour');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['colour_picker'] = function(block) {
                +  // Colour picker.
                +  var code = '\'' + block.getFieldValue('COLOUR') + '\'';
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['colour_random'] = function(block) {
                +  // Generate a random colour.
                +  Blockly.Python.definitions_['import_random'] = 'import random';
                +  var code = '\'#%06x\' % random.randint(0, 2**24 - 1)';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['colour_rgb'] = function(block) {
                +  // Compose a colour from RGB components expressed as percentages.
                +  var functionName = Blockly.Python.provideFunction_(
                +      'colour_rgb',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(r, g, b):',
                +       '  r = round(min(100, max(0, r)) * 2.55)',
                +       '  g = round(min(100, max(0, g)) * 2.55)',
                +       '  b = round(min(100, max(0, b)) * 2.55)',
                +       '  return \'#%02x%02x%02x\' % (r, g, b)']);
                +  var r = Blockly.Python.valueToCode(block, 'RED',
                +                                     Blockly.Python.ORDER_NONE) || 0;
                +  var g = Blockly.Python.valueToCode(block, 'GREEN',
                +                                     Blockly.Python.ORDER_NONE) || 0;
                +  var b = Blockly.Python.valueToCode(block, 'BLUE',
                +                                     Blockly.Python.ORDER_NONE) || 0;
                +  var code = functionName + '(' + r + ', ' + g + ', ' + b + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['colour_blend'] = function(block) {
                +  // Blend two colours together.
                +  var functionName = Blockly.Python.provideFunction_(
                +      'colour_blend',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(colour1, colour2, ratio):',
                +       '  r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)',
                +       '  g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)',
                +       '  b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)',
                +       '  ratio = min(1, max(0, ratio))',
                +       '  r = round(r1 * (1 - ratio) + r2 * ratio)',
                +       '  g = round(g1 * (1 - ratio) + g2 * ratio)',
                +       '  b = round(b1 * (1 - ratio) + b2 * ratio)',
                +       '  return \'#%02x%02x%02x\' % (r, g, b)']);
                +  var colour1 = Blockly.Python.valueToCode(block, 'COLOUR1',
                +      Blockly.Python.ORDER_NONE) || '\'#000000\'';
                +  var colour2 = Blockly.Python.valueToCode(block, 'COLOUR2',
                +      Blockly.Python.ORDER_NONE) || '\'#000000\'';
                +  var ratio = Blockly.Python.valueToCode(block, 'RATIO',
                +      Blockly.Python.ORDER_NONE) || 0;
                +  var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/lists.js b/blockly/webif/static/blockly/generators/python/lists.js
                new file mode 100644
                index 000000000..3d29acf22
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/lists.js
                @@ -0,0 +1,363 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for list blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.lists');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['lists_create_empty'] = function(block) {
                +  // Create an empty list.
                +  return ['[]', Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['lists_create_with'] = function(block) {
                +  // Create a list with any number of elements of any type.
                +  var elements = new Array(block.itemCount_);
                +  for (var i = 0; i < block.itemCount_; i++) {
                +    elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i,
                +        Blockly.Python.ORDER_NONE) || 'None';
                +  }
                +  var code = '[' + elements.join(', ') + ']';
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['lists_repeat'] = function(block) {
                +  // Create a list with one element repeated.
                +  var item = Blockly.Python.valueToCode(block, 'ITEM',
                +      Blockly.Python.ORDER_NONE) || 'None';
                +  var times = Blockly.Python.valueToCode(block, 'NUM',
                +      Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
                +  var code = '[' + item + '] * ' + times;
                +  return [code, Blockly.Python.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Python['lists_length'] = function(block) {
                +  // String or array length.
                +  var list = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '[]';
                +  return ['len(' + list + ')', Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['lists_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var list = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '[]';
                +  var code = 'not len(' + list + ')';
                +  return [code, Blockly.Python.ORDER_LOGICAL_NOT];
                +};
                +
                +Blockly.Python['lists_indexOf'] = function(block) {
                +  // Find an item in the list.
                +  var item = Blockly.Python.valueToCode(block, 'FIND',
                +      Blockly.Python.ORDER_NONE) || '[]';
                +  var list = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  if (block.workspace.options.oneBasedIndex) {
                +    var errorIndex = ' 0';
                +    var firstIndexAdjustment = ' + 1';
                +    var lastIndexAdjustment = '';
                +  } else {
                +    var errorIndex = ' -1';
                +    var firstIndexAdjustment = '';
                +    var lastIndexAdjustment = ' - 1';
                +  }
                +  if (block.getFieldValue('END') == 'FIRST') {
                +    var functionName = Blockly.Python.provideFunction_(
                +        'first_index',
                +        ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(my_list, elem):',
                +         '  try: index = my_list.index(elem)' + firstIndexAdjustment,
                +         '  except: index =' + errorIndex,
                +         '  return index']);
                +    var code = functionName + '(' + list + ', ' + item + ')';
                +    return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  }
                +  var functionName = Blockly.Python.provideFunction_(
                +      'last_index',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(my_list, elem):',
                +       '  try: index = len(my_list) - my_list[::-1].index(elem)' +
                +         lastIndexAdjustment,
                +       '  except: index =' + errorIndex,
                +       '  return index']);
                +  var code = functionName + '(' + list + ', ' + item + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['lists_getIndex'] = function(block) {
                +  // Get element at index.
                +  // Note: Until January 2013 this block did not have MODE or WHERE inputs.
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var listOrder = (where == 'RANDOM') ? Blockly.Python.ORDER_NONE :
                +      Blockly.Python.ORDER_MEMBER;
                +  var list = Blockly.Python.valueToCode(block, 'VALUE', listOrder) || '[]';
                +
                +  switch (where) {
                +    case 'FIRST':
                +      if (mode == 'GET') {
                +        var code = list + '[0]';
                +        return [code, Blockly.Python.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.pop(0)';
                +        return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.pop(0)\n';
                +      }
                +      break;
                +    case 'LAST':
                +      if (mode == 'GET') {
                +        var code = list + '[-1]';
                +        return [code, Blockly.Python.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.pop()';
                +        return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.pop()\n';
                +      }
                +      break;
                +    case 'FROM_START':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT');
                +      if (mode == 'GET') {
                +        var code = list + '[' + at + ']';
                +        return [code, Blockly.Python.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.pop(' + at + ')';
                +        return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.pop(' + at + ')\n';
                +      }
                +      break;
                +    case'FROM_END':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
                +      if (mode == 'GET') {
                +        var code = list + '[' + at + ']';
                +        return [code, Blockly.Python.ORDER_MEMBER];
                +      } else if (mode == 'GET_REMOVE') {
                +        var code = list + '.pop(' + at + ')';
                +        return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      } else if (mode == 'REMOVE') {
                +        return list + '.pop(' + at + ')\n';
                +      }
                +      break;
                +    case 'RANDOM':
                +      Blockly.Python.definitions_['import_random'] = 'import random';
                +      if (mode == 'GET') {
                +        code = 'random.choice(' + list + ')';
                +        return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      } else {
                +        var functionName = Blockly.Python.provideFunction_(
                +            'lists_remove_random_item',
                +            ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
                +              '  x = int(random.random() * len(myList))',
                +              '  return myList.pop(x)']);
                +        code = functionName + '(' + list + ')';
                +        if (mode == 'GET_REMOVE') {
                +          return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +        } else if (mode == 'REMOVE') {
                +          return code + '\n';
                +        }
                +      }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_getIndex).';
                +};
                +
                +Blockly.Python['lists_setIndex'] = function(block) {
                +  // Set element at index.
                +  // Note: Until February 2013 this block did not have MODE or WHERE inputs.
                +  var list = Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_MEMBER) || '[]';
                +  var mode = block.getFieldValue('MODE') || 'GET';
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var value = Blockly.Python.valueToCode(block, 'TO',
                +      Blockly.Python.ORDER_NONE) || 'None';
                +  // Cache non-trivial values to variables to prevent repeated look-ups.
                +  // Closure, which accesses and modifies 'list'.
                +  function cacheList() {
                +    if (list.match(/^\w+$/)) {
                +      return '';
                +    }
                +    var listVar = Blockly.Python.variableDB_.getDistinctName(
                +        'tmp_list', Blockly.Variables.NAME_TYPE);
                +    var code = listVar + ' = ' + list + '\n';
                +    list = listVar;
                +    return code;
                +  }
                +
                +  switch (where) {
                +    case 'FIRST':
                +      if (mode == 'SET') {
                +        return list + '[0] = ' + value + '\n';
                +      } else if (mode == 'INSERT') {
                +        return list + '.insert(0, ' + value + ')\n';
                +      }
                +      break;
                +    case 'LAST':
                +        if (mode == 'SET') {
                +          return list + '[-1] = ' + value + '\n';
                +        } else if (mode == 'INSERT') {
                +          return list + '.append(' + value + ')\n';
                +        }
                +      break;
                +    case 'FROM_START':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT');
                +        if (mode == 'SET') {
                +          return list + '[' + at + '] = ' + value + '\n';
                +        } else if (mode == 'INSERT') {
                +          return list + '.insert(' + at + ', ' + value + ')\n';
                +        }
                +      break;
                +    case 'FROM_END':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
                +        if (mode == 'SET') {
                +          return list + '[' + at + '] = ' + value + '\n';
                +        } else if (mode == 'INSERT') {
                +          return list + '.insert(' + at + ', ' + value + ')\n';
                +        }
                +      break;
                +    case 'RANDOM':
                +        Blockly.Python.definitions_['import_random'] = 'import random';
                +        var code = cacheList();
                +        var xVar = Blockly.Python.variableDB_.getDistinctName(
                +            'tmp_x', Blockly.Variables.NAME_TYPE);
                +        code += xVar + ' = int(random.random() * len(' + list + '))\n';
                +        if (mode == 'SET') {
                +          code += list + '[' + xVar + '] = ' + value + '\n';
                +          return code;
                +        } else if (mode == 'INSERT') {
                +          code += list + '.insert(' + xVar + ', ' + value + ')\n';
                +          return code;
                +        }
                +      break;
                +  }
                +  throw 'Unhandled combination (lists_setIndex).';
                +};
                +
                +Blockly.Python['lists_getSublist'] = function(block) {
                +  // Get sublist.
                +  var list = Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_MEMBER) || '[]';
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  switch (where1) {
                +    case 'FROM_START':
                +      var at1 = Blockly.Python.getAdjustedInt(block, 'AT1');
                +      if (at1 == '0') {
                +        at1 = '';
                +      }
                +      break;
                +    case 'FROM_END':
                +      var at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true);
                +      break;
                +    case 'FIRST':
                +      var at1 = '';
                +      break;
                +    default:
                +      throw 'Unhandled option (lists_getSublist)';
                +  }
                +  switch (where2) {
                +    case 'FROM_START':
                +      var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1);
                +      break;
                +    case 'FROM_END':
                +      var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 0, true);
                +      // Ensure that if the result calculated is 0 that sub-sequence will
                +      // include all elements as expected.
                +      if (!Blockly.isNumber(String(at2))) {
                +        Blockly.Python.definitions_['import_sys'] = 'import sys';
                +        at2 += ' or sys.maxsize';
                +      } else if (at2 == '0') {
                +        at2 = '';
                +      }
                +      break;
                +    case 'LAST':
                +      var at2 = '';
                +      break;
                +    default:
                +      throw 'Unhandled option (lists_getSublist)';
                +  }
                +  var code = list + '[' + at1 + ' : ' + at2 + ']';
                +  return [code, Blockly.Python.ORDER_MEMBER];
                +};
                +
                +Blockly.Python['lists_sort'] = function(block) {
                +  // Block for sorting a list.
                +  var list = (Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_NONE) || '[]');
                +  var type = block.getFieldValue('TYPE');
                +  var reverse = block.getFieldValue('DIRECTION') === '1' ? 'False' : 'True';
                +  var sortFunctionName = Blockly.Python.provideFunction_('lists_sort',
                +  ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +      '(my_list, type, reverse):',
                +    '  def try_float(s):',
                +    '    try:',
                +    '      return float(s)',
                +    '    except:',
                +    '      return 0',
                +    '  key_funcs = {',
                +    '    "NUMERIC": try_float,',
                +    '    "TEXT": str,',
                +    '    "IGNORE_CASE": lambda s: str(s).lower()',
                +    '  }',
                +    '  key_func = key_funcs[type]',
                +    '  list_cpy = list(my_list)', // Clone the list.
                +    '  return sorted(list_cpy, key=key_func, reverse=reverse)'
                +  ]);
                +
                +  var code = sortFunctionName +
                +      '(' + list + ', "' + type + '", ' + reverse + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['lists_split'] = function(block) {
                +  // Block for splitting text into a list, or joining a list into text.
                +  var mode = block.getFieldValue('MODE');
                +  if (mode == 'SPLIT') {
                +    var value_input = Blockly.Python.valueToCode(block, 'INPUT',
                +        Blockly.Python.ORDER_MEMBER) || '\'\'';
                +    var value_delim = Blockly.Python.valueToCode(block, 'DELIM',
                +        Blockly.Python.ORDER_NONE);
                +    var code = value_input + '.split(' + value_delim + ')';
                +  } else if (mode == 'JOIN') {
                +    var value_input = Blockly.Python.valueToCode(block, 'INPUT',
                +        Blockly.Python.ORDER_NONE) || '[]';
                +    var value_delim = Blockly.Python.valueToCode(block, 'DELIM',
                +        Blockly.Python.ORDER_MEMBER) || '\'\'';
                +    var code = value_delim + '.join(' + value_input + ')';
                +  } else {
                +    throw 'Unknown mode: ' + mode;
                +  }
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['lists_reverse'] = function(block) {
                +  // Block for reversing a list.
                +  var list = Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_NONE) || '[]';
                +  var code = 'list(reversed(' + list + '))';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/logic.js b/blockly/webif/static/blockly/generators/python/logic.js
                new file mode 100644
                index 000000000..fe0364868
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/logic.js
                @@ -0,0 +1,128 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for logic blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.logic');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['controls_if'] = function(block) {
                +  // If/elseif/else condition.
                +  var n = 0;
                +  var code = '', branchCode, conditionCode;
                +  do {
                +    conditionCode = Blockly.Python.valueToCode(block, 'IF' + n,
                +        Blockly.Python.ORDER_NONE) || 'False';
                +    branchCode = Blockly.Python.statementToCode(block, 'DO' + n) ||
                +        Blockly.Python.PASS;
                +    code += (n == 0 ? 'if ' : 'elif ' ) + conditionCode + ':\n' + branchCode;
                +
                +    ++n;
                +  } while (block.getInput('IF' + n));
                +
                +  if (block.getInput('ELSE')) {
                +    branchCode = Blockly.Python.statementToCode(block, 'ELSE') ||
                +        Blockly.Python.PASS;
                +    code += 'else:\n' + branchCode;
                +  }
                +  return code;
                +};
                +
                +Blockly.Python['controls_ifelse'] = Blockly.Python['controls_if'];
                +
                +Blockly.Python['logic_compare'] = function(block) {
                +  // Comparison operator.
                +  var OPERATORS = {
                +    'EQ': '==',
                +    'NEQ': '!=',
                +    'LT': '<',
                +    'LTE': '<=',
                +    'GT': '>',
                +    'GTE': '>='
                +  };
                +  var operator = OPERATORS[block.getFieldValue('OP')];
                +  var order = Blockly.Python.ORDER_RELATIONAL;
                +  var argument0 = Blockly.Python.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Python['logic_operation'] = function(block) {
                +  // Operations 'and', 'or'.
                +  var operator = (block.getFieldValue('OP') == 'AND') ? 'and' : 'or';
                +  var order = (operator == 'and') ? Blockly.Python.ORDER_LOGICAL_AND :
                +      Blockly.Python.ORDER_LOGICAL_OR;
                +  var argument0 = Blockly.Python.valueToCode(block, 'A', order);
                +  var argument1 = Blockly.Python.valueToCode(block, 'B', order);
                +  if (!argument0 && !argument1) {
                +    // If there are no arguments, then the return value is false.
                +    argument0 = 'False';
                +    argument1 = 'False';
                +  } else {
                +    // Single missing arguments have no effect on the return value.
                +    var defaultArgument = (operator == 'and') ? 'True' : 'False';
                +    if (!argument0) {
                +      argument0 = defaultArgument;
                +    }
                +    if (!argument1) {
                +      argument1 = defaultArgument;
                +    }
                +  }
                +  var code = argument0 + ' ' + operator + ' ' + argument1;
                +  return [code, order];
                +};
                +
                +Blockly.Python['logic_negate'] = function(block) {
                +  // Negation.
                +  var argument0 = Blockly.Python.valueToCode(block, 'BOOL',
                +      Blockly.Python.ORDER_LOGICAL_NOT) || 'True';
                +  var code = 'not ' + argument0;
                +  return [code, Blockly.Python.ORDER_LOGICAL_NOT];
                +};
                +
                +Blockly.Python['logic_boolean'] = function(block) {
                +  // Boolean values true and false.
                +  var code = (block.getFieldValue('BOOL') == 'TRUE') ? 'True' : 'False';
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['logic_null'] = function(block) {
                +  // Null data type.
                +  return ['None', Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['logic_ternary'] = function(block) {
                +  // Ternary operator.
                +  var value_if = Blockly.Python.valueToCode(block, 'IF',
                +      Blockly.Python.ORDER_CONDITIONAL) || 'False';
                +  var value_then = Blockly.Python.valueToCode(block, 'THEN',
                +      Blockly.Python.ORDER_CONDITIONAL) || 'None';
                +  var value_else = Blockly.Python.valueToCode(block, 'ELSE',
                +      Blockly.Python.ORDER_CONDITIONAL) || 'None';
                +  var code = value_then + ' if ' + value_if + ' else ' + value_else;
                +  return [code, Blockly.Python.ORDER_CONDITIONAL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/loops.js b/blockly/webif/static/blockly/generators/python/loops.js
                new file mode 100644
                index 000000000..3cb1ab900
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/loops.js
                @@ -0,0 +1,211 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for loop blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.loops');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['controls_repeat_ext'] = function(block) {
                +  // Repeat n times.
                +  if (block.getField('TIMES')) {
                +    // Internal number.
                +    var repeats = String(parseInt(block.getFieldValue('TIMES'), 10));
                +  } else {
                +    // External number.
                +    var repeats = Blockly.Python.valueToCode(block, 'TIMES',
                +        Blockly.Python.ORDER_NONE) || '0';
                +  }
                +  if (Blockly.isNumber(repeats)) {
                +    repeats = parseInt(repeats, 10);
                +  } else {
                +    repeats = 'int(' + repeats + ')';
                +  }
                +  var branch = Blockly.Python.statementToCode(block, 'DO');
                +  branch = Blockly.Python.addLoopTrap(branch, block.id) ||
                +      Blockly.Python.PASS;
                +  var loopVar = Blockly.Python.variableDB_.getDistinctName(
                +      'count', Blockly.Variables.NAME_TYPE);
                +  var code = 'for ' + loopVar + ' in range(' + repeats + '):\n' + branch;
                +  return code;
                +};
                +
                +Blockly.Python['controls_repeat'] = Blockly.Python['controls_repeat_ext'];
                +
                +Blockly.Python['controls_whileUntil'] = function(block) {
                +  // Do while/until loop.
                +  var until = block.getFieldValue('MODE') == 'UNTIL';
                +  var argument0 = Blockly.Python.valueToCode(block, 'BOOL',
                +      until ? Blockly.Python.ORDER_LOGICAL_NOT :
                +      Blockly.Python.ORDER_NONE) || 'False';
                +  var branch = Blockly.Python.statementToCode(block, 'DO');
                +  branch = Blockly.Python.addLoopTrap(branch, block.id) ||
                +      Blockly.Python.PASS;
                +  if (until) {
                +    argument0 = 'not ' + argument0;
                +  }
                +  return 'while ' + argument0 + ':\n' + branch;
                +};
                +
                +Blockly.Python['controls_for'] = function(block) {
                +  // For loop.
                +  var variable0 = Blockly.Python.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.Python.valueToCode(block, 'FROM',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'TO',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var increment = Blockly.Python.valueToCode(block, 'BY',
                +      Blockly.Python.ORDER_NONE) || '1';
                +  var branch = Blockly.Python.statementToCode(block, 'DO');
                +  branch = Blockly.Python.addLoopTrap(branch, block.id) ||
                +      Blockly.Python.PASS;
                +
                +  var code = '';
                +  var range;
                +
                +  // Helper functions.
                +  var defineUpRange = function() {
                +    return Blockly.Python.provideFunction_(
                +        'upRange',
                +        ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(start, stop, step):',
                +         '  while start <= stop:',
                +         '    yield start',
                +         '    start += abs(step)']);
                +  };
                +  var defineDownRange = function() {
                +    return Blockly.Python.provideFunction_(
                +        'downRange',
                +        ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +            '(start, stop, step):',
                +         '  while start >= stop:',
                +         '    yield start',
                +         '    start -= abs(step)']);
                +  };
                +  // Arguments are legal Python code (numbers or strings returned by scrub()).
                +  var generateUpDownRange = function(start, end, inc) {
                +    return '(' + start + ' <= ' + end + ') and ' +
                +        defineUpRange() + '(' + start + ', ' + end + ', ' + inc + ') or ' +
                +        defineDownRange() + '(' + start + ', ' + end + ', ' + inc + ')';
                +  };
                +
                +  if (Blockly.isNumber(argument0) && Blockly.isNumber(argument1) &&
                +      Blockly.isNumber(increment)) {
                +    // All parameters are simple numbers.
                +    argument0 = parseFloat(argument0);
                +    argument1 = parseFloat(argument1);
                +    increment = Math.abs(parseFloat(increment));
                +    if (argument0 % 1 === 0 && argument1 % 1 === 0 && increment % 1 === 0) {
                +      // All parameters are integers.
                +      if (argument0 <= argument1) {
                +        // Count up.
                +        argument1++;
                +        if (argument0 == 0 && increment == 1) {
                +          // If starting index is 0, omit it.
                +          range = argument1;
                +        } else {
                +          range = argument0 + ', ' + argument1;
                +        }
                +        // If increment isn't 1, it must be explicit.
                +        if (increment != 1) {
                +          range += ', ' + increment;
                +        }
                +      } else {
                +        // Count down.
                +        argument1--;
                +        range = argument0 + ', ' + argument1 + ', -' + increment;
                +      }
                +      range = 'range(' + range + ')';
                +    } else {
                +      // At least one of the parameters is not an integer.
                +      if (argument0 < argument1) {
                +        range = defineUpRange();
                +      } else {
                +        range = defineDownRange();
                +      }
                +      range += '(' + argument0 + ', ' + argument1 + ', ' + increment + ')';
                +    }
                +  } else {
                +    // Cache non-trivial values to variables to prevent repeated look-ups.
                +    var scrub = function(arg, suffix) {
                +      if (Blockly.isNumber(arg)) {
                +        // Simple number.
                +        arg = parseFloat(arg);
                +      } else if (arg.match(/^\w+$/)) {
                +        // Variable.
                +        arg = 'float(' + arg + ')';
                +      } else {
                +        // It's complicated.
                +        var varName = Blockly.Python.variableDB_.getDistinctName(
                +            variable0 + suffix, Blockly.Variables.NAME_TYPE);
                +        code += varName + ' = float(' + arg + ')\n';
                +        arg = varName;
                +      }
                +      return arg;
                +    };
                +    var startVar = scrub(argument0, '_start');
                +    var endVar = scrub(argument1, '_end');
                +    var incVar = scrub(increment, '_inc');
                +
                +    if (typeof startVar == 'number' && typeof endVar == 'number') {
                +      if (startVar < endVar) {
                +        range = defineUpRange(startVar, endVar, increment);
                +      } else {
                +        range = defineDownRange(startVar, endVar, increment);
                +      }
                +    } else {
                +      // We cannot determine direction statically.
                +      range = generateUpDownRange(startVar, endVar, increment);
                +    }
                +  }
                +  code += 'for ' + variable0 + ' in ' + range + ':\n' + branch;
                +  return code;
                +};
                +
                +Blockly.Python['controls_forEach'] = function(block) {
                +  // For each loop.
                +  var variable0 = Blockly.Python.variableDB_.getName(
                +      block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
                +  var argument0 = Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_RELATIONAL) || '[]';
                +  var branch = Blockly.Python.statementToCode(block, 'DO');
                +  branch = Blockly.Python.addLoopTrap(branch, block.id) ||
                +      Blockly.Python.PASS;
                +  var code = 'for ' + variable0 + ' in ' + argument0 + ':\n' + branch;
                +  return code;
                +};
                +
                +Blockly.Python['controls_flow_statements'] = function(block) {
                +  // Flow statements: continue, break.
                +  switch (block.getFieldValue('FLOW')) {
                +    case 'BREAK':
                +      return 'break\n';
                +    case 'CONTINUE':
                +      return 'continue\n';
                +  }
                +  throw 'Unknown flow statement.';
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/math.js b/blockly/webif/static/blockly/generators/python/math.js
                new file mode 100644
                index 000000000..a2595e00c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/math.js
                @@ -0,0 +1,388 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for math blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.math');
                +
                +goog.require('Blockly.Python');
                +
                +
                +// If any new block imports any library, add that library name here.
                +Blockly.Python.addReservedWords('math,random,Number');
                +
                +Blockly.Python['math_number'] = function(block) {
                +  // Numeric value.
                +  var code = parseFloat(block.getFieldValue('NUM'));
                +  var order;
                +  if (code == Infinity) {
                +    code = 'float("inf")';
                +    order = Blockly.Python.ORDER_FUNCTION_CALL;
                +  } else if (code == -Infinity) {
                +    code = '-float("inf")';
                +    order = Blockly.Python.ORDER_UNARY_SIGN;
                +  } else {
                +    order = code < 0 ? Blockly.Python.ORDER_UNARY_SIGN :
                +            Blockly.Python.ORDER_ATOMIC;
                +  }
                +  return [code, order];
                +};
                +
                +Blockly.Python['math_arithmetic'] = function(block) {
                +  // Basic arithmetic operators, and power.
                +  var OPERATORS = {
                +    'ADD': [' + ', Blockly.Python.ORDER_ADDITIVE],
                +    'MINUS': [' - ', Blockly.Python.ORDER_ADDITIVE],
                +    'MULTIPLY': [' * ', Blockly.Python.ORDER_MULTIPLICATIVE],
                +    'DIVIDE': [' / ', Blockly.Python.ORDER_MULTIPLICATIVE],
                +    'POWER': [' ** ', Blockly.Python.ORDER_EXPONENTIATION]
                +  };
                +  var tuple = OPERATORS[block.getFieldValue('OP')];
                +  var operator = tuple[0];
                +  var order = tuple[1];
                +  var argument0 = Blockly.Python.valueToCode(block, 'A', order) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'B', order) || '0';
                +  var code = argument0 + operator + argument1;
                +  return [code, order];
                +  // In case of 'DIVIDE', division between integers returns different results
                +  // in Python 2 and 3. However, is not an issue since Blockly does not
                +  // guarantee identical results in all languages.  To do otherwise would
                +  // require every operator to be wrapped in a function call.  This would kill
                +  // legibility of the generated code.
                +};
                +
                +Blockly.Python['math_single'] = function(block) {
                +  // Math operators with single operand.
                +  var operator = block.getFieldValue('OP');
                +  var code;
                +  var arg;
                +  if (operator == 'NEG') {
                +    // Negation is a special case given its different operator precedence.
                +    var code = Blockly.Python.valueToCode(block, 'NUM',
                +        Blockly.Python.ORDER_UNARY_SIGN) || '0';
                +    return ['-' + code, Blockly.Python.ORDER_UNARY_SIGN];
                +  }
                +  Blockly.Python.definitions_['import_math'] = 'import math';
                +  if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
                +    arg = Blockly.Python.valueToCode(block, 'NUM',
                +        Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
                +  } else {
                +    arg = Blockly.Python.valueToCode(block, 'NUM',
                +        Blockly.Python.ORDER_NONE) || '0';
                +  }
                +  // First, handle cases which generate values that don't need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'ABS':
                +      code = 'math.fabs(' + arg + ')';
                +      break;
                +    case 'ROOT':
                +      code = 'math.sqrt(' + arg + ')';
                +      break;
                +    case 'LN':
                +      code = 'math.log(' + arg + ')';
                +      break;
                +    case 'LOG10':
                +      code = 'math.log10(' + arg + ')';
                +      break;
                +    case 'EXP':
                +      code = 'math.exp(' + arg + ')';
                +      break;
                +    case 'POW10':
                +      code = 'math.pow(10,' + arg + ')';
                +      break;
                +    case 'ROUND':
                +      code = 'round(' + arg + ')';
                +      break;
                +    case 'ROUNDUP':
                +      code = 'math.ceil(' + arg + ')';
                +      break;
                +    case 'ROUNDDOWN':
                +      code = 'math.floor(' + arg + ')';
                +      break;
                +    case 'SIN':
                +      code = 'math.sin(' + arg + ' / 180.0 * math.pi)';
                +      break;
                +    case 'COS':
                +      code = 'math.cos(' + arg + ' / 180.0 * math.pi)';
                +      break;
                +    case 'TAN':
                +      code = 'math.tan(' + arg + ' / 180.0 * math.pi)';
                +      break;
                +  }
                +  if (code) {
                +    return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  }
                +  // Second, handle cases which generate values that may need parentheses
                +  // wrapping the code.
                +  switch (operator) {
                +    case 'ASIN':
                +      code = 'math.asin(' + arg + ') / math.pi * 180';
                +      break;
                +    case 'ACOS':
                +      code = 'math.acos(' + arg + ') / math.pi * 180';
                +      break;
                +    case 'ATAN':
                +      code = 'math.atan(' + arg + ') / math.pi * 180';
                +      break;
                +    default:
                +      throw 'Unknown math operator: ' + operator;
                +  }
                +  return [code, Blockly.Python.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Python['math_constant'] = function(block) {
                +  // Constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
                +  var CONSTANTS = {
                +    'PI': ['math.pi', Blockly.Python.ORDER_MEMBER],
                +    'E': ['math.e', Blockly.Python.ORDER_MEMBER],
                +    'GOLDEN_RATIO': ['(1 + math.sqrt(5)) / 2',
                +                     Blockly.Python.ORDER_MULTIPLICATIVE],
                +    'SQRT2': ['math.sqrt(2)', Blockly.Python.ORDER_MEMBER],
                +    'SQRT1_2': ['math.sqrt(1.0 / 2)', Blockly.Python.ORDER_MEMBER],
                +    'INFINITY': ['float(\'inf\')', Blockly.Python.ORDER_ATOMIC]
                +  };
                +  var constant = block.getFieldValue('CONSTANT');
                +  if (constant != 'INFINITY') {
                +    Blockly.Python.definitions_['import_math'] = 'import math';
                +  }
                +  return CONSTANTS[constant];
                +};
                +
                +Blockly.Python['math_number_property'] = function(block) {
                +  // Check if a number is even, odd, prime, whole, positive, or negative
                +  // or if it is divisible by certain number. Returns true or false.
                +  var number_to_check = Blockly.Python.valueToCode(block, 'NUMBER_TO_CHECK',
                +      Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
                +  var dropdown_property = block.getFieldValue('PROPERTY');
                +  var code;
                +  if (dropdown_property == 'PRIME') {
                +    Blockly.Python.definitions_['import_math'] = 'import math';
                +    Blockly.Python.definitions_['from_numbers_import_Number'] =
                +        'from numbers import Number';
                +    var functionName = Blockly.Python.provideFunction_(
                +        'math_isPrime',
                +        ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(n):',
                +         '  # https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
                +         '  # If n is not a number but a string, try parsing it.',
                +         '  if not isinstance(n, Number):',
                +         '    try:',
                +         '      n = float(n)',
                +         '    except:',
                +         '      return False',
                +         '  if n == 2 or n == 3:',
                +         '    return True',
                +         '  # False if n is negative, is 1, or not whole,' +
                +             ' or if n is divisible by 2 or 3.',
                +         '  if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:',
                +         '    return False',
                +         '  # Check all the numbers of form 6k +/- 1, up to sqrt(n).',
                +         '  for x in range(6, int(math.sqrt(n)) + 2, 6):',
                +         '    if n % (x - 1) == 0 or n % (x + 1) == 0:',
                +         '      return False',
                +         '  return True']);
                +    code = functionName + '(' + number_to_check + ')';
                +    return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  }
                +  switch (dropdown_property) {
                +    case 'EVEN':
                +      code = number_to_check + ' % 2 == 0';
                +      break;
                +    case 'ODD':
                +      code = number_to_check + ' % 2 == 1';
                +      break;
                +    case 'WHOLE':
                +      code = number_to_check + ' % 1 == 0';
                +      break;
                +    case 'POSITIVE':
                +      code = number_to_check + ' > 0';
                +      break;
                +    case 'NEGATIVE':
                +      code = number_to_check + ' < 0';
                +      break;
                +    case 'DIVISIBLE_BY':
                +      var divisor = Blockly.Python.valueToCode(block, 'DIVISOR',
                +          Blockly.Python.ORDER_MULTIPLICATIVE);
                +      // If 'divisor' is some code that evals to 0, Python will raise an error.
                +      if (!divisor || divisor == '0') {
                +        return ['False', Blockly.Python.ORDER_ATOMIC];
                +      }
                +      code = number_to_check + ' % ' + divisor + ' == 0';
                +      break;
                +  }
                +  return [code, Blockly.Python.ORDER_RELATIONAL];
                +};
                +
                +Blockly.Python['math_change'] = function(block) {
                +  // Add to a variable in place.
                +  Blockly.Python.definitions_['from_numbers_import_Number'] =
                +      'from numbers import Number';
                +  var argument0 = Blockly.Python.valueToCode(block, 'DELTA',
                +      Blockly.Python.ORDER_ADDITIVE) || '0';
                +  var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return varName + ' = (' + varName + ' if isinstance(' + varName +
                +      ', Number) else 0) + ' + argument0 + '\n';
                +};
                +
                +// Rounding functions have a single operand.
                +Blockly.Python['math_round'] = Blockly.Python['math_single'];
                +// Trigonometry functions have a single operand.
                +Blockly.Python['math_trig'] = Blockly.Python['math_single'];
                +
                +Blockly.Python['math_on_list'] = function(block) {
                +  // Math functions for lists.
                +  var func = block.getFieldValue('OP');
                +  var list = Blockly.Python.valueToCode(block, 'LIST',
                +      Blockly.Python.ORDER_NONE) || '[]';
                +  var code;
                +  switch (func) {
                +    case 'SUM':
                +      code = 'sum(' + list + ')';
                +      break;
                +    case 'MIN':
                +      code = 'min(' + list + ')';
                +      break;
                +    case 'MAX':
                +      code = 'max(' + list + ')';
                +      break;
                +    case 'AVERAGE':
                +      Blockly.Python.definitions_['from_numbers_import_Number'] =
                +          'from numbers import Number';
                +      var functionName = Blockly.Python.provideFunction_(
                +          'math_mean',
                +          // This operation excludes null and values that aren't int or float:',
                +          // math_mean([null, null, "aString", 1, 9]) == 5.0.',
                +          ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
                +           '  localList = [e for e in myList if isinstance(e, Number)]',
                +           '  if not localList: return',
                +           '  return float(sum(localList)) / len(localList)']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MEDIAN':
                +      Blockly.Python.definitions_['from_numbers_import_Number'] =
                +          'from numbers import Number';
                +      var functionName = Blockly.Python.provideFunction_(
                +          'math_median',
                +          // This operation excludes null values:
                +          // math_median([null, null, 1, 3]) == 2.0.
                +          ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(myList):',
                +           '  localList = sorted([e for e in myList if isinstance(e, Number)])',
                +           '  if not localList: return',
                +           '  if len(localList) % 2 == 0:',
                +           '    return (localList[len(localList) // 2 - 1] + ' +
                +               'localList[len(localList) // 2]) / 2.0',
                +           '  else:',
                +           '    return localList[(len(localList) - 1) // 2]']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'MODE':
                +      var functionName = Blockly.Python.provideFunction_(
                +          'math_modes',
                +          // As a list of numbers can contain more than one mode,
                +          // the returned result is provided as an array.
                +          // Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1].
                +          ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(some_list):',
                +           '  modes = []',
                +           '  # Using a lists of [item, count] to keep count rather than dict',
                +           '  # to avoid "unhashable" errors when the counted item is ' +
                +               'itself a list or dict.',
                +           '  counts = []',
                +           '  maxCount = 1',
                +           '  for item in some_list:',
                +           '    found = False',
                +           '    for count in counts:',
                +           '      if count[0] == item:',
                +           '        count[1] += 1',
                +           '        maxCount = max(maxCount, count[1])',
                +           '        found = True',
                +           '    if not found:',
                +           '      counts.append([item, 1])',
                +           '  for counted_item, item_count in counts:',
                +           '    if item_count == maxCount:',
                +           '      modes.append(counted_item)',
                +           '  return modes']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'STD_DEV':
                +      Blockly.Python.definitions_['import_math'] = 'import math';
                +      var functionName = Blockly.Python.provideFunction_(
                +          'math_standard_deviation',
                +          ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(numbers):',
                +           '  n = len(numbers)',
                +           '  if n == 0: return',
                +           '  mean = float(sum(numbers)) / n',
                +           '  variance = sum((x - mean) ** 2 for x in numbers) / n',
                +           '  return math.sqrt(variance)']);
                +      code = functionName + '(' + list + ')';
                +      break;
                +    case 'RANDOM':
                +      Blockly.Python.definitions_['import_random'] = 'import random';
                +      code = 'random.choice(' + list + ')';
                +      break;
                +    default:
                +      throw 'Unknown operator: ' + func;
                +  }
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['math_modulo'] = function(block) {
                +  // Remainder computation.
                +  var argument0 = Blockly.Python.valueToCode(block, 'DIVIDEND',
                +      Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'DIVISOR',
                +      Blockly.Python.ORDER_MULTIPLICATIVE) || '0';
                +  var code = argument0 + ' % ' + argument1;
                +  return [code, Blockly.Python.ORDER_MULTIPLICATIVE];
                +};
                +
                +Blockly.Python['math_constrain'] = function(block) {
                +  // Constrain a number between two limits.
                +  var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'LOW',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var argument2 = Blockly.Python.valueToCode(block, 'HIGH',
                +      Blockly.Python.ORDER_NONE) || 'float(\'inf\')';
                +  var code = 'min(max(' + argument0 + ', ' + argument1 + '), ' +
                +      argument2 + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['math_random_int'] = function(block) {
                +  // Random integer between [X] and [Y].
                +  Blockly.Python.definitions_['import_random'] = 'import random';
                +  var argument0 = Blockly.Python.valueToCode(block, 'FROM',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var argument1 = Blockly.Python.valueToCode(block, 'TO',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var code = 'random.randint(' + argument0 + ', ' + argument1 + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['math_random_float'] = function(block) {
                +  // Random fraction between 0 and 1.
                +  Blockly.Python.definitions_['import_random'] = 'import random';
                +  return ['random.random()', Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/procedures.js b/blockly/webif/static/blockly/generators/python/procedures.js
                new file mode 100644
                index 000000000..10d279a90
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/procedures.js
                @@ -0,0 +1,124 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for procedure blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.procedures');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['procedures_defreturn'] = function(block) {
                +  // Define a procedure with a return value.
                +  // First, add a 'global' statement for every variable that is not shadowed by
                +  // a local parameter.
                +  var globals = [];
                +  var varName;
                +  var workspace = block.workspace;
                +  var variables = workspace.getAllVariables() || [];
                +  for (var i = 0, variable; variable = variables[i]; i++) {
                +    varName = variable.name;
                +    if (block.arguments_.indexOf(varName) == -1) {
                +      globals.push(Blockly.Python.variableDB_.getName(varName,
                +          Blockly.Variables.NAME_TYPE));
                +    }
                +  }
                +  globals = globals.length ? '  global ' + globals.join(', ') + '\n' : '';
                +  var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var branch = Blockly.Python.statementToCode(block, 'STACK');
                +  if (Blockly.Python.STATEMENT_PREFIX) {
                +    branch = Blockly.Python.prefixLines(
                +        Blockly.Python.STATEMENT_PREFIX.replace(/%1/g,
                +        '\'' + block.id + '\''), Blockly.Python.INDENT) + branch;
                +  }
                +  if (Blockly.Python.INFINITE_LOOP_TRAP) {
                +    branch = Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g,
                +        '"' + block.id + '"') + branch;
                +  }
                +  var returnValue = Blockly.Python.valueToCode(block, 'RETURN',
                +      Blockly.Python.ORDER_NONE) || '';
                +  if (returnValue) {
                +    returnValue = '  return ' + returnValue + '\n';
                +  } else if (!branch) {
                +    branch = Blockly.Python.PASS;
                +  }
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Python.variableDB_.getName(block.arguments_[i],
                +        Blockly.Variables.NAME_TYPE);
                +  }
                +  var code = 'def ' + funcName + '(' + args.join(', ') + '):\n' +
                +      globals + branch + returnValue;
                +  code = Blockly.Python.scrub_(block, code);
                +  // Add % so as not to collide with helper functions in definitions list.
                +  Blockly.Python.definitions_['%' + funcName] = code;
                +  return null;
                +};
                +
                +// Defining a procedure without a return value uses the same generator as
                +// a procedure with a return value.
                +Blockly.Python['procedures_defnoreturn'] =
                +    Blockly.Python['procedures_defreturn'];
                +
                +Blockly.Python['procedures_callreturn'] = function(block) {
                +  // Call a procedure with a return value.
                +  var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Python.valueToCode(block, 'ARG' + i,
                +        Blockly.Python.ORDER_NONE) || 'None';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')';
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['procedures_callnoreturn'] = function(block) {
                +  // Call a procedure with no return value.
                +  var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
                +      Blockly.Procedures.NAME_TYPE);
                +  var args = [];
                +  for (var i = 0; i < block.arguments_.length; i++) {
                +    args[i] = Blockly.Python.valueToCode(block, 'ARG' + i,
                +        Blockly.Python.ORDER_NONE) || 'None';
                +  }
                +  var code = funcName + '(' + args.join(', ') + ')\n';
                +  return code;
                +};
                +
                +Blockly.Python['procedures_ifreturn'] = function(block) {
                +  // Conditionally return value from a procedure.
                +  var condition = Blockly.Python.valueToCode(block, 'CONDITION',
                +      Blockly.Python.ORDER_NONE) || 'False';
                +  var code = 'if ' + condition + ':\n';
                +  if (block.hasReturnValue_) {
                +    var value = Blockly.Python.valueToCode(block, 'VALUE',
                +        Blockly.Python.ORDER_NONE) || 'None';
                +    code += '  return ' + value + '\n';
                +  } else {
                +    code += '  return\n';
                +  }
                +  return code;
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/text.js b/blockly/webif/static/blockly/generators/python/text.js
                new file mode 100644
                index 000000000..0fefc77d9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/text.js
                @@ -0,0 +1,280 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for text blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.texts');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['text'] = function(block) {
                +  // Text value.
                +  var code = Blockly.Python.quote_(block.getFieldValue('TEXT'));
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['text_join'] = function(block) {
                +  // Create a string made up of any number of elements of any type.
                +  //Should we allow joining by '-' or ',' or any other characters?
                +  switch (block.itemCount_) {
                +    case 0:
                +      return ['\'\'', Blockly.Python.ORDER_ATOMIC];
                +      break;
                +    case 1:
                +      var element = Blockly.Python.valueToCode(block, 'ADD0',
                +              Blockly.Python.ORDER_NONE) || '\'\'';
                +      var code = 'str(' + element + ')';
                +      return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +      break;
                +    case 2:
                +      var element0 = Blockly.Python.valueToCode(block, 'ADD0',
                +              Blockly.Python.ORDER_NONE) || '\'\'';
                +      var element1 = Blockly.Python.valueToCode(block, 'ADD1',
                +              Blockly.Python.ORDER_NONE) || '\'\'';
                +      var code = 'str(' + element0 + ') + str(' + element1 + ')';
                +      return [code, Blockly.Python.ORDER_ADDITIVE];
                +      break;
                +    default:
                +      var elements = [];
                +      for (var i = 0; i < block.itemCount_; i++) {
                +        elements[i] = Blockly.Python.valueToCode(block, 'ADD' + i,
                +                Blockly.Python.ORDER_NONE) || '\'\'';
                +      }
                +      var tempVar = Blockly.Python.variableDB_.getDistinctName('x',
                +          Blockly.Variables.NAME_TYPE);
                +      var code = '\'\'.join([str(' + tempVar + ') for ' + tempVar + ' in [' +
                +          elements.join(', ') + ']])';
                +      return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  }
                +};
                +
                +Blockly.Python['text_append'] = function(block) {
                +  // Append to a variable in place.
                +  var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  var value = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  return varName + ' = str(' + varName + ') + str(' + value + ')\n';
                +};
                +
                +Blockly.Python['text_length'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  return ['len(' + text + ')', Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['text_isEmpty'] = function(block) {
                +  // Is the string null or array empty?
                +  var text = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  var code = 'not len(' + text + ')';
                +  return [code, Blockly.Python.ORDER_LOGICAL_NOT];
                +};
                +
                +Blockly.Python['text_indexOf'] = function(block) {
                +  // Search the text for a substring.
                +  // Should we allow for non-case sensitive???
                +  var operator = block.getFieldValue('END') == 'FIRST' ? 'find' : 'rfind';
                +  var substring = Blockly.Python.valueToCode(block, 'FIND',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  var text = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var code = text + '.' + operator + '(' + substring + ')';
                +  if (block.workspace.options.oneBasedIndex) {
                +    return [code + ' + 1', Blockly.Python.ORDER_ADDITIVE];
                +  }
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['text_charAt'] = function(block) {
                +  // Get letter at index.
                +  // Note: Until January 2013 this block did not have the WHERE input.
                +  var where = block.getFieldValue('WHERE') || 'FROM_START';
                +  var text = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  switch (where) {
                +    case 'FIRST':
                +      var code = text + '[0]';
                +      return [code, Blockly.Python.ORDER_MEMBER];
                +    case 'LAST':
                +      var code = text + '[-1]';
                +      return [code, Blockly.Python.ORDER_MEMBER];
                +    case 'FROM_START':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT');
                +      var code = text + '[' + at + ']';
                +      return [code, Blockly.Python.ORDER_MEMBER];
                +    case 'FROM_END':
                +      var at = Blockly.Python.getAdjustedInt(block, 'AT', 1, true);
                +      var code = text + '[' + at + ']';
                +      return [code, Blockly.Python.ORDER_MEMBER];
                +    case 'RANDOM':
                +      Blockly.Python.definitions_['import_random'] = 'import random';
                +      var functionName = Blockly.Python.provideFunction_(
                +          'text_random_letter',
                +          ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(text):',
                +           '  x = int(random.random() * len(text))',
                +           '  return text[x];']);
                +      code = functionName + '(' + text + ')';
                +      return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  }
                +  throw 'Unhandled option (text_charAt).';
                +};
                +
                +Blockly.Python['text_getSubstring'] = function(block) {
                +  // Get substring.
                +  var where1 = block.getFieldValue('WHERE1');
                +  var where2 = block.getFieldValue('WHERE2');
                +  var text = Blockly.Python.valueToCode(block, 'STRING',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  switch (where1) {
                +    case 'FROM_START':
                +      var at1 = Blockly.Python.getAdjustedInt(block, 'AT1');
                +      if (at1 == '0') {
                +        at1 = '';
                +      }
                +      break;
                +    case 'FROM_END':
                +      var at1 = Blockly.Python.getAdjustedInt(block, 'AT1', 1, true);
                +      break;
                +    case 'FIRST':
                +      var at1 = '';
                +      break;
                +    default:
                +      throw 'Unhandled option (text_getSubstring)';
                +  }
                +  switch (where2) {
                +    case 'FROM_START':
                +      var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 1);
                +      break;
                +    case 'FROM_END':
                +      var at2 = Blockly.Python.getAdjustedInt(block, 'AT2', 0, true);
                +      // Ensure that if the result calculated is 0 that sub-sequence will
                +      // include all elements as expected.
                +      if (!Blockly.isNumber(String(at2))) {
                +        Blockly.Python.definitions_['import_sys'] = 'import sys';
                +        at2 += ' or sys.maxsize';
                +      } else if (at2 == '0') {
                +        at2 = '';
                +      }
                +      break;
                +    case 'LAST':
                +      var at2 = '';
                +      break;
                +    default:
                +      throw 'Unhandled option (text_getSubstring)';
                +  }
                +  var code = text + '[' + at1 + ' : ' + at2 + ']';
                +  return [code, Blockly.Python.ORDER_MEMBER];
                +};
                +
                +Blockly.Python['text_changeCase'] = function(block) {
                +  // Change capitalization.
                +  var OPERATORS = {
                +    'UPPERCASE': '.upper()',
                +    'LOWERCASE': '.lower()',
                +    'TITLECASE': '.title()'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('CASE')];
                +  var text = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var code = text + operator;
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['text_trim'] = function(block) {
                +  // Trim spaces.
                +  var OPERATORS = {
                +    'LEFT': '.lstrip()',
                +    'RIGHT': '.rstrip()',
                +    'BOTH': '.strip()'
                +  };
                +  var operator = OPERATORS[block.getFieldValue('MODE')];
                +  var text = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var code = text + operator;
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['text_print'] = function(block) {
                +  // Print statement.
                +  var msg = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  return 'print(' + msg + ')\n';
                +};
                +
                +Blockly.Python['text_prompt_ext'] = function(block) {
                +  // Prompt function.
                +  var functionName = Blockly.Python.provideFunction_(
                +      'text_prompt',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(msg):',
                +       '  try:',
                +       '    return raw_input(msg)',
                +       '  except NameError:',
                +       '    return input(msg)']);
                +  if (block.getField('TEXT')) {
                +    // Internal message.
                +    var msg = Blockly.Python.quote_(block.getFieldValue('TEXT'));
                +  } else {
                +    // External message.
                +    var msg = Blockly.Python.valueToCode(block, 'TEXT',
                +        Blockly.Python.ORDER_NONE) || '\'\'';
                +  }
                +  var code = functionName + '(' + msg + ')';
                +  var toNumber = block.getFieldValue('TYPE') == 'NUMBER';
                +  if (toNumber) {
                +    code = 'float(' + code + ')';
                +  }
                +  return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +};
                +
                +Blockly.Python['text_prompt'] = Blockly.Python['text_prompt_ext'];
                +
                +Blockly.Python['text_count'] = function(block) {
                +  var text = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var sub = Blockly.Python.valueToCode(block, 'SUB',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  var code = text + '.count(' + sub + ')';
                +  return [code, Blockly.Python.ORDER_MEMBER];
                +};
                +
                +Blockly.Python['text_replace'] = function(block) {
                +  var text = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var from = Blockly.Python.valueToCode(block, 'FROM',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  var to = Blockly.Python.valueToCode(block, 'TO',
                +      Blockly.Python.ORDER_NONE) || '\'\'';
                +  var code = text + '.replace(' + from + ', ' + to + ')';
                +  return [code, Blockly.Python.ORDER_MEMBER];
                +};
                +
                +Blockly.Python['text_reverse'] = function(block) {
                +  var text = Blockly.Python.valueToCode(block, 'TEXT',
                +      Blockly.Python.ORDER_MEMBER) || '\'\'';
                +  var code = text + '[::-1]';
                +  return [code, Blockly.Python.ORDER_MEMBER];
                +};
                diff --git a/blockly/webif/static/blockly/generators/python/variables.js b/blockly/webif/static/blockly/generators/python/variables.js
                new file mode 100644
                index 000000000..00d9971af
                --- /dev/null
                +++ b/blockly/webif/static/blockly/generators/python/variables.js
                @@ -0,0 +1,46 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for variable blocks.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Python.variables');
                +
                +goog.require('Blockly.Python');
                +
                +
                +Blockly.Python['variables_get'] = function(block) {
                +  // Variable getter.
                +  var code = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +
                +Blockly.Python['variables_set'] = function(block) {
                +  // Variable setter.
                +  var argument0 = Blockly.Python.valueToCode(block, 'VALUE',
                +      Blockly.Python.ORDER_NONE) || '0';
                +  var varName = Blockly.Python.variableDB_.getName(block.getFieldValue('VAR'),
                +      Blockly.Variables.NAME_TYPE);
                +  return varName + ' = ' + argument0 + '\n';
                +};
                diff --git a/blockly/webif/static/blockly/i18n/common.py b/blockly/webif/static/blockly/i18n/common.py
                new file mode 100644
                index 000000000..90e584e16
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/common.py
                @@ -0,0 +1,234 @@
                +#!/usr/bin/python
                +
                +# Code shared by translation conversion scripts.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import codecs
                +import json
                +import os
                +from datetime import datetime
                +
                +class InputError(Exception):
                +    """Exception raised for errors in the input.
                +
                +    Attributes:
                +        location -- where error occurred
                +        msg -- explanation of the error
                +
                +    """
                +
                +    def __init__(self, location, msg):
                +        Exception.__init__(self, '{0}: {1}'.format(location, msg))
                +        self.location = location
                +        self.msg = msg
                +
                +
                +def read_json_file(filename):
                +  """Read a JSON file as UTF-8 into a dictionary, discarding @metadata.
                +
                +  Args:
                +    filename: The filename, which must end ".json".
                +
                +  Returns:
                +    The dictionary.
                +
                +  Raises:
                +    InputError: The filename did not end with ".json" or an error occurred
                +        while opening or reading the file.
                +  """
                +  if not filename.endswith('.json'):
                +    raise InputError(filename, 'filenames must end with ".json"')
                +  try:
                +    # Read in file.
                +    with codecs.open(filename, 'r', 'utf-8') as infile:
                +      defs = json.load(infile)
                +    if '@metadata' in defs:
                +      del defs['@metadata']
                +    return defs
                +  except ValueError, e:
                +    print('Error reading ' + filename)
                +    raise InputError(filename, str(e))
                +
                +
                +def _create_qqq_file(output_dir):
                +    """Creates a qqq.json file with message documentation for translatewiki.net.
                +
                +    The file consists of key-value pairs, where the keys are message ids and
                +    the values are descriptions for the translators of the messages.
                +    What documentation exists for the format can be found at:
                +    http://translatewiki.net/wiki/Translating:Localisation_for_developers#Message_documentation
                +
                +    The file should be closed by _close_qqq_file().
                +
                +    Parameters:
                +        output_dir: The output directory.
                +
                +    Returns:
                +        A pointer to a file to which a left brace and newline have been written.
                +
                +    Raises:
                +        IOError: An error occurred while opening or writing the file.
                +    """
                +    qqq_file_name = os.path.join(os.curdir, output_dir, 'qqq.json')
                +    qqq_file = codecs.open(qqq_file_name, 'w', 'utf-8')
                +    print 'Created file: ' + qqq_file_name
                +    qqq_file.write('{\n')
                +    return qqq_file
                +
                +
                +def _close_qqq_file(qqq_file):
                +    """Closes a qqq.json file created and opened by _create_qqq_file().
                +
                +    This writes the final newlines and right brace.
                +
                +    Args:
                +        qqq_file: A file created by _create_qqq_file().
                +
                +    Raises:
                +        IOError: An error occurred while writing to or closing the file.
                +    """
                +    qqq_file.write('\n}\n')
                +    qqq_file.close()
                +
                +
                +def _create_lang_file(author, lang, output_dir):
                +    """Creates a <lang>.json file for translatewiki.net.
                +
                +    The file consists of metadata, followed by key-value pairs, where the keys
                +    are message ids and the values are the messages in the language specified
                +    by the corresponding command-line argument.  The file should be closed by
                +    _close_lang_file().
                +
                +    Args:
                +        author: Name and email address of contact for translators.
                +        lang: ISO 639-1 source language code.
                +        output_dir: Relative directory for output files.
                +
                +    Returns:
                +        A pointer to a file to which the metadata has been written.
                +
                +    Raises:
                +        IOError: An error occurred while opening or writing the file.
                +    """
                +    lang_file_name = os.path.join(os.curdir, output_dir, lang + '.json')
                +    lang_file = codecs.open(lang_file_name, 'w', 'utf-8')
                +    print 'Created file: ' + lang_file_name
                +    # string.format doesn't like printing braces, so break up our writes.
                +    lang_file.write('{\n\t"@metadata": {')
                +    lang_file.write("""
                +\t\t"author": "{0}",
                +\t\t"lastupdated": "{1}",
                +\t\t"locale": "{2}",
                +\t\t"messagedocumentation" : "qqq"
                +""".format(author, str(datetime.now()), lang))
                +    lang_file.write('\t},\n')
                +    return lang_file
                +
                +
                +def _close_lang_file(lang_file):
                +    """Closes a <lang>.json file created with _create_lang_file().
                +
                +    This also writes the terminating left brace and newline.
                +
                +    Args:
                +        lang_file: A file opened with _create_lang_file().
                +
                +    Raises:
                +        IOError: An error occurred while writing to or closing the file.
                +    """
                +    lang_file.write('\n}\n')
                +    lang_file.close()
                +
                +
                +def _create_key_file(output_dir):
                +    """Creates a keys.json file mapping Closure keys to Blockly keys.
                +
                +    Args:
                +        output_dir: Relative directory for output files.
                +
                +    Raises:
                +        IOError: An error occurred while creating the file.
                +    """
                +    key_file_name = os.path.join(os.curdir, output_dir, 'keys.json')
                +    key_file = open(key_file_name, 'w')
                +    key_file.write('{\n')
                +    print 'Created file: ' + key_file_name
                +    return key_file
                +
                +
                +def _close_key_file(key_file):
                +    """Closes a key file created and opened with _create_key_file().
                +
                +    Args:
                +        key_file: A file created by _create_key_file().
                +
                +    Raises:
                +        IOError: An error occurred while writing to or closing the file.
                +    """
                +    key_file.write('\n}\n')
                +    key_file.close()
                +
                +
                +def write_files(author, lang, output_dir, units, write_key_file):
                +    """Writes the output files for the given units.
                +
                +    There are three possible output files:
                +    * lang_file: JSON file mapping meanings (e.g., Maze.turnLeft) to the
                +      English text.  The base name of the language file is specified by the
                +      "lang" command-line argument.
                +    * key_file: JSON file mapping meanings to Soy-generated keys (long hash
                +      codes).  This is only output if the parameter write_key_file is True.
                +    * qqq_file: JSON file mapping meanings to descriptions.
                +
                +    Args:
                +        author: Name and email address of contact for translators.
                +        lang: ISO 639-1 source language code.
                +        output_dir: Relative directory for output files.
                +        units: A list of dictionaries with entries for 'meaning', 'source',
                +            'description', and 'keys' (the last only if write_key_file is true),
                +            in the order desired in the output files.
                +        write_key_file: Whether to output a keys.json file.
                +
                +    Raises:
                +        IOError: An error occurs opening, writing to, or closing a file.
                +        KeyError: An expected key is missing from units.
                +    """
                +    lang_file = _create_lang_file(author, lang, output_dir)
                +    qqq_file = _create_qqq_file(output_dir)
                +    if write_key_file:
                +      key_file = _create_key_file(output_dir)
                +    first_entry = True
                +    for unit in units:
                +        if not first_entry:
                +            lang_file.write(',\n')
                +            if write_key_file:
                +              key_file.write(',\n')
                +            qqq_file.write(',\n')
                +        lang_file.write(u'\t"{0}": "{1}"'.format(
                +            unit['meaning'],
                +            unit['source'].replace('"', "'")))
                +        if write_key_file:
                +          key_file.write('"{0}": "{1}"'.format(unit['meaning'], unit['key']))
                +        qqq_file.write(u'\t"{0}": "{1}"'.format(
                +            unit['meaning'],
                +            unit['description'].replace('"', "'").replace(
                +                '{lb}', '{').replace('{rb}', '}')))
                +        first_entry = False
                +    _close_lang_file(lang_file)
                +    if write_key_file:
                +      _close_key_file(key_file)
                +    _close_qqq_file(qqq_file)
                diff --git a/blockly/webif/static/blockly/i18n/create_messages.py b/blockly/webif/static/blockly/i18n/create_messages.py
                new file mode 100644
                index 000000000..dc2620a31
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/create_messages.py
                @@ -0,0 +1,165 @@
                +#!/usr/bin/python
                +
                +# Generate .js files defining Blockly core and language messages.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import argparse
                +import codecs
                +import os
                +import re
                +import sys
                +from common import read_json_file
                +
                +
                +_NEWLINE_PATTERN = re.compile('[\n\r]')
                +
                +
                +def string_is_ascii(s):
                +  try:
                +    s.decode('ascii')
                +    return True
                +  except UnicodeEncodeError:
                +    return False
                +
                +def load_constants(filename):
                +  """Read in constants file, which must be output in every language."""
                +  constant_defs = read_json_file(filename);
                +  constants_text = '\n'
                +  for key in constant_defs:
                +    value = constant_defs[key]
                +    value = value.replace('"', '\\"')
                +    constants_text += '\nBlockly.Msg["{0}"] = "{1}";'.format(key, value)
                +  return constants_text
                +
                +def main():
                +  """Generate .js files defining Blockly core and language messages."""
                +
                +  # Process command-line arguments.
                +  parser = argparse.ArgumentParser(description='Convert JSON files to JS.')
                +  parser.add_argument('--source_lang', default='en',
                +                      help='ISO 639-1 source language code')
                +  parser.add_argument('--source_lang_file',
                +                      default=os.path.join('json', 'en.json'),
                +                      help='Path to .json file for source language')
                +  parser.add_argument('--source_synonym_file',
                +                      default=os.path.join('json', 'synonyms.json'),
                +                      help='Path to .json file with synonym definitions')
                +  parser.add_argument('--source_constants_file',
                +                      default=os.path.join('json', 'constants.json'),
                +                      help='Path to .json file with constant definitions')
                +  parser.add_argument('--output_dir', default='js/',
                +                      help='relative directory for output files')
                +  parser.add_argument('--key_file', default='keys.json',
                +                      help='relative path to input keys file')
                +  parser.add_argument('--quiet', action='store_true', default=False,
                +                      help='do not write anything to standard output')
                +  parser.add_argument('files', nargs='+', help='input files')
                +  args = parser.parse_args()
                +  if not args.output_dir.endswith(os.path.sep):
                +    args.output_dir += os.path.sep
                +
                +  # Read in source language .json file, which provides any values missing
                +  # in target languages' .json files.
                +  source_defs = read_json_file(os.path.join(os.curdir, args.source_lang_file))
                +  # Make sure the source file doesn't contain a newline or carriage return.
                +  for key, value in source_defs.items():
                +    if _NEWLINE_PATTERN.search(value):
                +      print('ERROR: definition of {0} in {1} contained a newline character.'.
                +            format(key, args.source_lang_file))
                +      sys.exit(1)
                +  sorted_keys = source_defs.keys()
                +  sorted_keys.sort()
                +
                +  # Read in synonyms file, which must be output in every language.
                +  synonym_defs = read_json_file(os.path.join(
                +      os.curdir, args.source_synonym_file))
                +  synonym_text = '\n'.join(['Blockly.Msg.{0} = Blockly.Msg.{1};'.format(
                +      key, synonym_defs[key]) for key in synonym_defs])
                +
                +  # Read in constants file, which must be output in every language.
                +  constants_text = load_constants(os.path.join(os.curdir, args.source_constants_file))
                +
                +  # Create each output file.
                +  for arg_file in args.files:
                +    (_, filename) = os.path.split(arg_file)
                +    target_lang = filename[:filename.index('.')]
                +    if target_lang not in ('qqq', 'keys', 'synonyms', 'constants'):
                +      target_defs = read_json_file(os.path.join(os.curdir, arg_file))
                +
                +      # Verify that keys are 'ascii'
                +      bad_keys = [key for key in target_defs if not string_is_ascii(key)]
                +      if bad_keys:
                +        print(u'These keys in {0} contain non ascii characters: {1}'.format(
                +            filename, ', '.join(bad_keys)))
                +
                +      # If there's a '\n' or '\r', remove it and print a warning.
                +      for key, value in target_defs.items():
                +        if _NEWLINE_PATTERN.search(value):
                +          print(u'WARNING: definition of {0} in {1} contained '
                +                'a newline character.'.
                +                format(key, arg_file))
                +          target_defs[key] = _NEWLINE_PATTERN.sub(' ', value)
                +
                +      # Output file.
                +      outname = os.path.join(os.curdir, args.output_dir, target_lang + '.js')
                +      with codecs.open(outname, 'w', 'utf-8') as outfile:
                +        outfile.write(
                +            """// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.{0}');
                +
                +goog.require('Blockly.Msg');
                +
                +""".format(target_lang.replace('-', '.')))
                +        # For each key in the source language file, output the target value
                +        # if present; otherwise, output the source language value with a
                +        # warning comment.
                +        for key in sorted_keys:
                +          if key in target_defs:
                +            value = target_defs[key]
                +            comment = ''
                +            del target_defs[key]
                +          else:
                +            value = source_defs[key]
                +            comment = '  // untranslated'
                +          value = value.replace('"', '\\"')
                +          outfile.write(u'Blockly.Msg["{0}"] = "{1}";{2}\n'.format(
                +              key, value, comment))
                +
                +        # Announce any keys defined only for target language.
                +        if target_defs:
                +          extra_keys = [key for key in target_defs if key not in synonym_defs]
                +          synonym_keys = [key for key in target_defs if key in synonym_defs]
                +          if not args.quiet:
                +            if extra_keys:
                +              print(u'These extra keys appeared in {0}: {1}'.format(
                +                  filename, ', '.join(extra_keys)))
                +            if synonym_keys:
                +              print(u'These synonym keys appeared in {0}: {1}'.format(
                +                  filename, ', '.join(synonym_keys)))
                +
                +        outfile.write(synonym_text)
                +        outfile.write(constants_text)
                +
                +      if not args.quiet:
                +        print('Created {0}.'.format(outname))
                +
                +
                +if __name__ == '__main__':
                +  main()
                diff --git a/blockly/webif/static/blockly/i18n/dedup_json.py b/blockly/webif/static/blockly/i18n/dedup_json.py
                new file mode 100644
                index 000000000..30e572dde
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/dedup_json.py
                @@ -0,0 +1,73 @@
                +#!/usr/bin/python
                +
                +# Consolidates duplicate key-value pairs in a JSON file.
                +# If the same key is used with different values, no warning is given,
                +# and there is no guarantee about which key-value pair will be output.
                +# There is also no guarantee as to the order of the key-value pairs
                +# output.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import argparse
                +import codecs
                +import json
                +from common import InputError
                +
                +
                +def main():
                +  """Parses arguments and iterates over files.
                +
                +  Raises:
                +    IOError: An I/O error occurred with an input or output file.
                +    InputError: Input JSON could not be parsed.
                +  """
                +
                +  # Set up argument parser.
                +  parser = argparse.ArgumentParser(
                +      description='Removes duplicate key-value pairs from JSON files.')
                +  parser.add_argument('--suffix', default='',
                +                      help='optional suffix for output files; '
                +                      'if empty, files will be changed in place')
                +  parser.add_argument('files', nargs='+', help='input files')
                +  args = parser.parse_args()
                +
                +  # Iterate over files.
                +  for filename in args.files:
                +    # Read in json using Python libraries.  This eliminates duplicates.
                +    print('Processing ' + filename + '...')
                +    try:
                +      with codecs.open(filename, 'r', 'utf-8') as infile:
                +        j = json.load(infile)
                +    except ValueError, e:
                +      print('Error reading ' + filename)
                +      raise InputError(file, str(e))
                +
                +    # Built up output strings as an array to make output of delimiters easier.
                +    output = []
                +    for key in j:
                +      if key != '@metadata':
                +        output.append('\t"' + key + '": "' +
                +                      j[key].replace('\n', '\\n') + '"')
                +
                +    # Output results.
                +    with codecs.open(filename + args.suffix, 'w', 'utf-8') as outfile:
                +      outfile.write('{\n')
                +      outfile.write(',\n'.join(output))
                +      outfile.write('\n}\n')
                +
                +
                +if __name__ == '__main__':
                +  main()
                diff --git a/blockly/webif/static/blockly/i18n/js_to_json.py b/blockly/webif/static/blockly/i18n/js_to_json.py
                new file mode 100644
                index 000000000..e48b1cee1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/js_to_json.py
                @@ -0,0 +1,136 @@
                +#!/usr/bin/python
                +
                +# Gives the translation status of the specified apps and languages.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +"""Extracts messages from .js files into .json files for translation.
                +
                +Specifically, lines with the following formats are extracted:
                +
                +    /// Here is a description of the following message.
                +    Blockly.SOME_KEY = 'Some value';
                +
                +Adjacent "///" lines are concatenated.
                +
                +There are two output files, each of which is proper JSON.  For each key, the
                +file en.json would get an entry of the form:
                +
                +    "Blockly.SOME_KEY", "Some value",
                +
                +The file qqq.json would get:
                +
                +    "Blockly.SOME_KEY", "Here is a description of the following message.",
                +
                +Commas would of course be omitted for the final entry of each value.
                +
                +@author Ellen Spertus (ellen.spertus@gmail.com)
                +"""
                +
                +import argparse
                +import codecs
                +import json
                +import os
                +import re
                +from common import write_files
                +
                +
                +_INPUT_DEF_PATTERN = re.compile("""Blockly.Msg.(\w*)\s*=\s*'(.*)';?\r?$""")
                +
                +_INPUT_SYN_PATTERN = re.compile(
                +    """Blockly.Msg.(\w*)\s*=\s*Blockly.Msg.(\w*);""")
                +
                +_CONSTANT_DESCRIPTION_PATTERN = re.compile(
                +    """{{Notranslate}}""", re.IGNORECASE)
                +
                +def main():
                +  # Set up argument parser.
                +  parser = argparse.ArgumentParser(description='Create translation files.')
                +  parser.add_argument(
                +      '--author',
                +      default='Ellen Spertus <ellen.spertus@gmail.com>',
                +      help='name and email address of contact for translators')
                +  parser.add_argument('--lang', default='en',
                +                      help='ISO 639-1 source language code')
                +  parser.add_argument('--output_dir', default='json',
                +                      help='relative directory for output files')
                +  parser.add_argument('--input_file', default='messages.js',
                +                      help='input file')
                +  parser.add_argument('--quiet', action='store_true', default=False,
                +                      help='only display warnings, not routine info')
                +  args = parser.parse_args()
                +  if (not args.output_dir.endswith(os.path.sep)):
                +    args.output_dir += os.path.sep
                +
                +  # Read and parse input file.
                +  results = []
                +  synonyms = {}
                +  constants = {}  # Values that are constant across all languages.
                +  description = ''
                +  infile = codecs.open(args.input_file, 'r', 'utf-8')
                +  for line in infile:
                +    if line.startswith('///'):
                +      if description:
                +        description = description + ' ' + line[3:].strip()
                +      else:
                +        description = line[3:].strip()
                +    else:
                +      match = _INPUT_DEF_PATTERN.match(line)
                +      if match:
                +        key = match.group(1)
                +        value = match.group(2).replace("\\'", "'")
                +        if not description:
                +          print('Warning: No description for ' + result['meaning'])
                +        if (description and _CONSTANT_DESCRIPTION_PATTERN.search(description)):
                +          constants[key] = value
                +        else:
                +          result = {}
                +          result['meaning'] = key
                +          result['source'] = value
                +          result['description'] = description
                +          results.append(result)
                +        description = ''
                +      else:
                +        match = _INPUT_SYN_PATTERN.match(line)
                +        if match:
                +          if description:
                +            print('Warning: Description preceding definition of synonym {0}.'.
                +                  format(match.group(1)))
                +            description = ''
                +          synonyms[match.group(1)] = match.group(2)
                +  infile.close()
                +
                +  # Create <lang_file>.json, keys.json, and qqq.json.
                +  write_files(args.author, args.lang, args.output_dir, results, False)
                +
                +  # Create synonyms.json.
                +  synonym_file_name = os.path.join(os.curdir, args.output_dir, 'synonyms.json')
                +  with open(synonym_file_name, 'w') as outfile:
                +    json.dump(synonyms, outfile)
                +  if not args.quiet:
                +    print("Wrote {0} synonym pairs to {1}.".format(
                +        len(synonyms), synonym_file_name))
                +
                +  # Create constants.json
                +  constants_file_name = os.path.join(os.curdir, args.output_dir, 'constants.json')
                +  with open(constants_file_name, 'w') as outfile:
                +    json.dump(constants, outfile)
                +  if not args.quiet:
                +    print("Wrote {0} constant pairs to {1}.".format(
                +        len(constants), synonym_file_name))
                +
                +if __name__ == '__main__':
                +  main()
                diff --git a/blockly/webif/static/blockly/i18n/json_to_js.py b/blockly/webif/static/blockly/i18n/json_to_js.py
                new file mode 100644
                index 000000000..f8c20f6af
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/json_to_js.py
                @@ -0,0 +1,185 @@
                +#!/usr/bin/python
                +
                +# Converts .json files into .js files for use within Blockly apps.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import argparse
                +import codecs      # for codecs.open(..., 'utf-8')
                +import glob
                +import json        # for json.load()
                +import os          # for os.path()
                +import subprocess  # for subprocess.check_call()
                +from common import InputError
                +from common import read_json_file
                +
                +
                +# Store parsed command-line arguments in global variable.
                +args = None
                +
                +
                +def _create_xlf(target_lang):
                +    """Creates a <target_lang>.xlf file for Soy.
                +
                +    Args:
                +        target_lang: The ISO 639 language code for the target language.
                +            This is used in the name of the file and in the metadata.
                +
                +    Returns:
                +        A pointer to a file to which the metadata has been written.
                +
                +    Raises:
                +        IOError: An error occurred while opening or writing the file.
                +    """
                +    filename = os.path.join(os.curdir, args.output_dir, target_lang + '.xlf')
                +    out_file = codecs.open(filename, 'w', 'utf-8')
                +    out_file.write("""<?xml version="1.0" encoding="UTF-8"?>
                +<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
                +  <file original="SoyMsgBundle"
                +        datatype="x-soy-msg-bundle"
                +        xml:space="preserve"
                +        source-language="{0}"
                +        target-language="{1}">
                +    <body>""".format(args.source_lang, target_lang))
                +    return out_file
                +
                +
                +def _close_xlf(xlf_file):
                +    """Closes a <target_lang>.xlf file created with create_xlf().
                +
                +    This includes writing the terminating XML.
                +
                +    Args:
                +        xlf_file: A pointer to a file created by _create_xlf().
                +
                +    Raises:
                +        IOError: An error occurred while writing to or closing the file.
                +    """
                +    xlf_file.write("""
                +    </body>
                +  </file>
                +</xliff>
                +""")
                +    xlf_file.close()
                +
                +
                +def _process_file(path_to_json, target_lang, key_dict):
                +    """Creates an .xlf file corresponding to the specified .json input file.
                +
                +    The name of the input file must be target_lang followed by '.json'.
                +    The name of the output file will be target_lang followed by '.js'.
                +
                +    Args:
                +        path_to_json: Path to the directory of xx.json files.
                +        target_lang: A IETF language code (RFC 4646), such as 'es' or 'pt-br'.
                +        key_dict: Dictionary mapping Blockly keys (e.g., Maze.turnLeft) to
                +            Closure keys (hash numbers).
                +
                +    Raises:
                +        IOError: An I/O error occurred with an input or output file.
                +        InputError: Input JSON could not be parsed.
                +        KeyError: Key found in input file but not in key file.
                +    """
                +    keyfile = os.path.join(path_to_json, target_lang + '.json')
                +    j = read_json_file(keyfile)
                +    out_file = _create_xlf(target_lang)
                +    for key in j:
                +        if key != '@metadata':
                +            try:
                +                identifier = key_dict[key]
                +            except KeyError, e:
                +                print('Key "%s" is in %s but not in %s' %
                +                      (key, keyfile, args.key_file))
                +                raise e
                +            target = j.get(key)
                +            out_file.write(u"""
                +      <trans-unit id="{0}" datatype="html">
                +        <target>{1}</target>
                +      </trans-unit>""".format(identifier, target))
                +    _close_xlf(out_file)
                +
                +
                +def main():
                +    """Parses arguments and iterates over files."""
                +
                +    # Set up argument parser.
                +    parser = argparse.ArgumentParser(description='Convert JSON files to JS.')
                +    parser.add_argument('--source_lang', default='en',
                +                        help='ISO 639-1 source language code')
                +    parser.add_argument('--output_dir', default='generated',
                +                        help='relative directory for output files')
                +    parser.add_argument('--key_file', default='json' + os.path.sep + 'keys.json',
                +                        help='relative path to input keys file')
                +    parser.add_argument('--template', default='template.soy')
                +    parser.add_argument('--path_to_jar',
                +                        default='..' + os.path.sep + 'apps' + os.path.sep
                +                        + '_soy',
                +                        help='relative path from working directory to '
                +                        'SoyToJsSrcCompiler.jar')
                +    parser.add_argument('files', nargs='+', help='input files')
                +
                +    # Initialize global variables.
                +    global args
                +    args = parser.parse_args()
                +
                +    # Make sure output_dir ends with slash.
                +    if (not args.output_dir.endswith(os.path.sep)):
                +      args.output_dir += os.path.sep
                +
                +    # Read in keys.json, mapping descriptions (e.g., Maze.turnLeft) to
                +    # Closure keys (long hash numbers).
                +    key_file = open(args.key_file)
                +    key_dict = json.load(key_file)
                +    key_file.close()
                +
                +    # Process each input file.
                +    print('Creating .xlf files...')
                +    processed_langs = []
                +    if len(args.files) == 1:
                +      # Windows does not expand globs automatically.
                +      args.files = glob.glob(args.files[0])
                +    for arg_file in args.files:
                +      (path_to_json, filename) = os.path.split(arg_file)
                +      if not filename.endswith('.json'):
                +        raise InputError(filename, 'filenames must end with ".json"')
                +      target_lang = filename[:filename.index('.')]
                +      if not target_lang in ('qqq', 'keys'):
                +        processed_langs.append(target_lang)
                +        _process_file(path_to_json, target_lang, key_dict)
                +
                +    # Output command line for Closure compiler.
                +    if processed_langs:
                +      print('Creating .js files...')
                +      processed_lang_list = ','.join(processed_langs)
                +      subprocess.check_call([
                +          'java',
                +          '-jar', os.path.join(args.path_to_jar, 'SoyToJsSrcCompiler.jar'),
                +          '--locales', processed_lang_list,
                +          '--messageFilePathFormat', args.output_dir + '{LOCALE}.xlf',
                +          '--outputPathFormat', args.output_dir + '{LOCALE}.js',
                +          '--srcs', args.template])
                +      if len(processed_langs) == 1:
                +        print('Created ' + processed_lang_list + '.js in ' + args.output_dir)
                +      else:
                +        print('Created {' + processed_lang_list + '}.js in ' + args.output_dir)
                +
                +      for lang in processed_langs:
                +        os.remove(args.output_dir + lang + '.xlf')
                +      print('Removed .xlf files.')
                +
                +
                +if __name__ == '__main__':
                +    main()
                diff --git a/blockly/webif/static/blockly/i18n/tests.py b/blockly/webif/static/blockly/i18n/tests.py
                new file mode 100644
                index 000000000..7e4fc49aa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/tests.py
                @@ -0,0 +1,47 @@
                +#!/usr/bin/python
                +# -*- coding: utf-8 -*-
                +
                +# Tests of i18n scripts.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import common
                +import re
                +import unittest
                +
                +class TestSequenceFunctions(unittest.TestCase):
                +  def test_insert_breaks(self):
                +    spaces = re.compile(r'\s+|\\n')
                +    def contains_all_chars(orig, result):
                +      return re.sub(spaces, '', orig) == re.sub(spaces, '', result)
                +
                +    sentences = [u'Quay Pegman qua bên trái hoặc bên phải 90 độ.',
                +                 u'Foo bar baz this is english that is okay bye.',
                +                 u'If there is a path in the specified direction, \nthen ' +
                +                 u'do some actions.',
                +                 u'If there is a path in the specified direction, then do ' +
                +                 u'the first block of actions. Otherwise, do the second ' +
                +                 u'block of actions.']
                +    for sentence in sentences:
                +      output = common.insert_breaks(sentence, 30, 50)
                +      self.assert_(contains_all_chars(sentence, output),
                +                   u'Mismatch between:\n{0}\n{1}'.format(
                +                       re.sub(spaces, '', sentence),
                +                       re.sub(spaces, '', output)))
                +
                +
                +if __name__ == '__main__':
                +    unittest.main()
                diff --git a/blockly/webif/static/blockly/i18n/xliff_to_json.py b/blockly/webif/static/blockly/i18n/xliff_to_json.py
                new file mode 100644
                index 000000000..b38b4d6ec
                --- /dev/null
                +++ b/blockly/webif/static/blockly/i18n/xliff_to_json.py
                @@ -0,0 +1,232 @@
                +#!/usr/bin/python
                +
                +# Converts .xlf files into .json files for use at http://translatewiki.net.
                +#
                +# Copyright 2013 Google Inc.
                +# https://developers.google.com/blockly/
                +#
                +# Licensed under the Apache License, Version 2.0 (the "License");
                +# you may not use this file except in compliance with the License.
                +# You may obtain a copy of the License at
                +#
                +#   http://www.apache.org/licenses/LICENSE-2.0
                +#
                +# Unless required by applicable law or agreed to in writing, software
                +# distributed under the License is distributed on an "AS IS" BASIS,
                +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                +# See the License for the specific language governing permissions and
                +# limitations under the License.
                +
                +import argparse
                +import os
                +import re
                +import subprocess
                +import sys
                +from xml.dom import minidom
                +from common import InputError
                +from common import write_files
                +
                +# Global variables
                +args = None  # Parsed command-line arguments.
                +
                +
                +def _parse_trans_unit(trans_unit):
                +    """Converts a trans-unit XML node into a more convenient dictionary format.
                +
                +    Args:
                +        trans_unit: An XML representation of a .xlf translation unit.
                +
                +    Returns:
                +        A dictionary with useful information about the translation unit.
                +        The returned dictionary is guaranteed to have an entry for 'key' and
                +        may have entries for 'source', 'target', 'description', and 'meaning'
                +        if present in the argument.
                +
                +    Raises:
                +        InputError: A required field was not present.
                +    """
                +
                +    def get_value(tag_name):
                +        elts = trans_unit.getElementsByTagName(tag_name)
                +        if not elts:
                +            return None
                +        elif len(elts) == 1:
                +            return ''.join([child.toxml() for child in elts[0].childNodes])
                +        else:
                +            raise InputError('', 'Unable to extract ' + tag_name)
                +
                +    result = {}
                +    key = trans_unit.getAttribute('id')
                +    if not key:
                +        raise InputError('', 'id attribute not found')
                +    result['key'] = key
                +
                +    # Get source and target, if present.
                +    try:
                +        result['source'] = get_value('source')
                +        result['target'] = get_value('target')
                +    except InputError, e:
                +        raise InputError(key, e.msg)
                +
                +    # Get notes, using the from value as key and the data as value.
                +    notes = trans_unit.getElementsByTagName('note')
                +    for note in notes:
                +        from_value = note.getAttribute('from')
                +        if from_value and len(note.childNodes) == 1:
                +            result[from_value] = note.childNodes[0].data
                +        else:
                +            raise InputError(key, 'Unable to extract ' + from_value)
                +
                +    return result
                +
                +
                +def _process_file(filename):
                +    """Builds list of translation units from input file.
                +
                +    Each translation unit in the input file includes:
                +    - an id (opaquely generated by Soy)
                +    - the Blockly name for the message
                +    - the text in the source language (generally English)
                +    - a description for the translator
                +
                +    The Soy and Blockly ids are joined with a hyphen and serve as the
                +    keys in both output files.  The value is the corresponding text (in the
                +    <lang>.json file) or the description (in the qqq.json file).
                +
                +    Args:
                +        filename: The name of an .xlf file produced by Closure.
                +
                +    Raises:
                +        IOError: An I/O error occurred with an input or output file.
                +        InputError: The input file could not be parsed or lacked required
                +            fields.
                +
                +    Returns:
                +        A list of dictionaries produced by parse_trans_unit().
                +    """
                +    try:
                +        results = []  # list of dictionaries (return value)
                +        names = []    # list of names of encountered keys (local variable)
                +        try:
                +            parsed_xml = minidom.parse(filename)
                +        except IOError:
                +            # Don't get caught by below handler
                +            raise
                +        except Exception, e:
                +            print
                +            raise InputError(filename, str(e))
                +
                +        # Make sure needed fields are present and non-empty.
                +        for trans_unit in parsed_xml.getElementsByTagName('trans-unit'):
                +            unit = _parse_trans_unit(trans_unit)
                +            for key in ['description', 'meaning', 'source']:
                +                if not key in unit or not unit[key]:
                +                    raise InputError(filename + ':' + unit['key'],
                +                                     key + ' not found')
                +            if unit['description'].lower() == 'ibid':
                +              if unit['meaning'] not in names:
                +                # If the term has not already been described, the use of 'ibid'
                +                # is an error.
                +                raise InputError(
                +                    filename,
                +                    'First encountered definition of: ' + unit['meaning']
                +                    + ' has definition: ' + unit['description']
                +                    + '.  This error can occur if the definition was not'
                +                    + ' provided on the first appearance of the message'
                +                    + ' or if the source (English-language) messages differ.')
                +              else:
                +                # If term has already been described, 'ibid' was used correctly,
                +                # and we output nothing.
                +                pass
                +            else:
                +              if unit['meaning'] in names:
                +                raise InputError(filename,
                +                                 'Second definition of: ' + unit['meaning'])
                +              names.append(unit['meaning'])
                +              results.append(unit)
                +
                +        return results
                +    except IOError, e:
                +        print 'Error with file {0}: {1}'.format(filename, e.strerror)
                +        sys.exit(1)
                +
                +
                +def sort_units(units, templates):
                +    """Sorts the translation units by their definition order in the template.
                +
                +    Args:
                +        units: A list of dictionaries produced by parse_trans_unit()
                +            that have a non-empty value for the key 'meaning'.
                +        templates: A string containing the Soy templates in which each of
                +            the units' meanings is defined.
                +
                +    Returns:
                +        A new list of translation units, sorted by the order in which
                +        their meaning is defined in the templates.
                +
                +    Raises:
                +        InputError: If a meaning definition cannot be found in the
                +            templates.
                +    """
                +    def key_function(unit):
                +        match = re.search(
                +            '\\smeaning\\s*=\\s*"{0}"\\s'.format(unit['meaning']),
                +            templates)
                +        if match:
                +            return match.start()
                +        else:
                +            raise InputError(args.templates,
                +                             'msg definition for meaning not found: ' +
                +                             unit['meaning'])
                +    return sorted(units, key=key_function)
                +
                +
                +def main():
                +    """Parses arguments and processes the specified file.
                +
                +    Raises:
                +        IOError: An I/O error occurred with an input or output file.
                +        InputError: Input files lacked required fields.
                +    """
                +    # Set up argument parser.
                +    parser = argparse.ArgumentParser(description='Create translation files.')
                +    parser.add_argument(
                +        '--author',
                +        default='Ellen Spertus <ellen.spertus@gmail.com>',
                +        help='name and email address of contact for translators')
                +    parser.add_argument('--lang', default='en',
                +                        help='ISO 639-1 source language code')
                +    parser.add_argument('--output_dir', default='json',
                +                        help='relative directory for output files')
                +    parser.add_argument('--xlf', help='file containing xlf definitions')
                +    parser.add_argument('--templates', default=['template.soy'], nargs='+',
                +                        help='relative path to Soy templates, comma or space '
                +                        'separated (used for ordering messages)')
                +    global args
                +    args = parser.parse_args()
                +
                +    # Make sure output_dir ends with slash.
                +    if (not args.output_dir.endswith(os.path.sep)):
                +      args.output_dir += os.path.sep
                +
                +    # Process the input file, and sort the entries.
                +    units = _process_file(args.xlf)
                +    files = []
                +    for arg in args.templates:
                +      for filename in arg.split(','):
                +        filename = filename.strip();
                +        if filename:
                +          with open(filename) as myfile:
                +            files.append(' '.join(line.strip() for line in myfile))
                +    sorted_units = sort_units(units, ' '.join(files))
                +
                +    # Write the output files.
                +    write_files(args.author, args.lang, args.output_dir, sorted_units, True)
                +
                +    # Delete the input .xlf file.
                +    os.remove(args.xlf)
                +    print('Removed ' + args.xlf)
                +
                +
                +if __name__ == '__main__':
                +    main()
                diff --git a/blockly/webif/static/blockly/javascript_compressed.js b/blockly/webif/static/blockly/javascript_compressed.js
                new file mode 100644
                index 000000000..cf91cab53
                --- /dev/null
                +++ b/blockly/webif/static/blockly/javascript_compressed.js
                @@ -0,0 +1,111 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Language
                +
                + Copyright 2012 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.JavaScript=new Blockly.Generator("JavaScript");Blockly.JavaScript.addReservedWords("Blockly,break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with,class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield,const,null,true,false,Array,ArrayBuffer,Boolean,Date,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Error,eval,EvalError,Float32Array,Float64Array,Function,Infinity,Int16Array,Int32Array,Int8Array,isFinite,isNaN,Iterator,JSON,Math,NaN,Number,Object,parseFloat,parseInt,RangeError,ReferenceError,RegExp,StopIteration,String,SyntaxError,TypeError,Uint16Array,Uint32Array,Uint8Array,Uint8ClampedArray,undefined,uneval,URIError,applicationCache,closed,Components,content,_content,controllers,crypto,defaultStatus,dialogArguments,directories,document,frameElement,frames,fullScreen,globalStorage,history,innerHeight,innerWidth,length,location,locationbar,localStorage,menubar,messageManager,mozAnimationStartTime,mozInnerScreenX,mozInnerScreenY,mozPaintCount,name,navigator,opener,outerHeight,outerWidth,pageXOffset,pageYOffset,parent,performance,personalbar,pkcs11,returnValue,screen,screenX,screenY,scrollbars,scrollMaxX,scrollMaxY,scrollX,scrollY,self,sessionStorage,sidebar,status,statusbar,toolbar,top,URL,window,addEventListener,alert,atob,back,blur,btoa,captureEvents,clearImmediate,clearInterval,clearTimeout,close,confirm,disableExternalCapture,dispatchEvent,dump,enableExternalCapture,escape,find,focus,forward,GeckoActiveXObject,getAttention,getAttentionWithCycleCount,getComputedStyle,getSelection,home,matchMedia,maximize,minimize,moveBy,moveTo,mozRequestAnimationFrame,open,openDialog,postMessage,print,prompt,QueryInterface,releaseEvents,removeEventListener,resizeBy,resizeTo,restore,routeEvent,scroll,scrollBy,scrollByLines,scrollByPages,scrollTo,setCursor,setImmediate,setInterval,setResizable,setTimeout,showModalDialog,sizeToContent,stop,unescape,updateCommands,XPCNativeWrapper,XPCSafeJSObjectWrapper,onabort,onbeforeunload,onblur,onchange,onclick,onclose,oncontextmenu,ondevicemotion,ondeviceorientation,ondragdrop,onerror,onfocus,onhashchange,onkeydown,onkeypress,onkeyup,onload,onmousedown,onmousemove,onmouseout,onmouseover,onmouseup,onmozbeforepaint,onpaint,onpopstate,onreset,onresize,onscroll,onselect,onsubmit,onunload,onpageshow,onpagehide,Image,Option,Worker,Event,Range,File,FileReader,Blob,BlobBuilder,Attr,CDATASection,CharacterData,Comment,console,DocumentFragment,DocumentType,DomConfiguration,DOMError,DOMErrorHandler,DOMException,DOMImplementation,DOMImplementationList,DOMImplementationRegistry,DOMImplementationSource,DOMLocator,DOMObject,DOMString,DOMStringList,DOMTimeStamp,DOMUserData,Entity,EntityReference,MediaQueryList,MediaQueryListListener,NameList,NamedNodeMap,Node,NodeFilter,NodeIterator,NodeList,Notation,Plugin,PluginArray,ProcessingInstruction,SharedWorker,Text,TimeRanges,Treewalker,TypeInfo,UserDataHandler,Worker,WorkerGlobalScope,HTMLDocument,HTMLElement,HTMLAnchorElement,HTMLAppletElement,HTMLAudioElement,HTMLAreaElement,HTMLBaseElement,HTMLBaseFontElement,HTMLBodyElement,HTMLBRElement,HTMLButtonElement,HTMLCanvasElement,HTMLDirectoryElement,HTMLDivElement,HTMLDListElement,HTMLEmbedElement,HTMLFieldSetElement,HTMLFontElement,HTMLFormElement,HTMLFrameElement,HTMLFrameSetElement,HTMLHeadElement,HTMLHeadingElement,HTMLHtmlElement,HTMLHRElement,HTMLIFrameElement,HTMLImageElement,HTMLInputElement,HTMLKeygenElement,HTMLLabelElement,HTMLLIElement,HTMLLinkElement,HTMLMapElement,HTMLMenuElement,HTMLMetaElement,HTMLModElement,HTMLObjectElement,HTMLOListElement,HTMLOptGroupElement,HTMLOptionElement,HTMLOutputElement,HTMLParagraphElement,HTMLParamElement,HTMLPreElement,HTMLQuoteElement,HTMLScriptElement,HTMLSelectElement,HTMLSourceElement,HTMLSpanElement,HTMLStyleElement,HTMLTableElement,HTMLTableCaptionElement,HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement,HTMLTableColElement,HTMLTableRowElement,HTMLTableSectionElement,HTMLTextAreaElement,HTMLTimeElement,HTMLTitleElement,HTMLTrackElement,HTMLUListElement,HTMLUnknownElement,HTMLVideoElement,HTMLCanvasElement,CanvasRenderingContext2D,CanvasGradient,CanvasPattern,TextMetrics,ImageData,CanvasPixelArray,HTMLAudioElement,HTMLVideoElement,NotifyAudioAvailableEvent,HTMLCollection,HTMLAllCollection,HTMLFormControlsCollection,HTMLOptionsCollection,HTMLPropertiesCollection,DOMTokenList,DOMSettableTokenList,DOMStringMap,RadioNodeList,SVGDocument,SVGElement,SVGAElement,SVGAltGlyphElement,SVGAltGlyphDefElement,SVGAltGlyphItemElement,SVGAnimationElement,SVGAnimateElement,SVGAnimateColorElement,SVGAnimateMotionElement,SVGAnimateTransformElement,SVGSetElement,SVGCircleElement,SVGClipPathElement,SVGColorProfileElement,SVGCursorElement,SVGDefsElement,SVGDescElement,SVGEllipseElement,SVGFilterElement,SVGFilterPrimitiveStandardAttributes,SVGFEBlendElement,SVGFEColorMatrixElement,SVGFEComponentTransferElement,SVGFECompositeElement,SVGFEConvolveMatrixElement,SVGFEDiffuseLightingElement,SVGFEDisplacementMapElement,SVGFEDistantLightElement,SVGFEFloodElement,SVGFEGaussianBlurElement,SVGFEImageElement,SVGFEMergeElement,SVGFEMergeNodeElement,SVGFEMorphologyElement,SVGFEOffsetElement,SVGFEPointLightElement,SVGFESpecularLightingElement,SVGFESpotLightElement,SVGFETileElement,SVGFETurbulenceElement,SVGComponentTransferFunctionElement,SVGFEFuncRElement,SVGFEFuncGElement,SVGFEFuncBElement,SVGFEFuncAElement,SVGFontElement,SVGFontFaceElement,SVGFontFaceFormatElement,SVGFontFaceNameElement,SVGFontFaceSrcElement,SVGFontFaceUriElement,SVGForeignObjectElement,SVGGElement,SVGGlyphElement,SVGGlyphRefElement,SVGGradientElement,SVGLinearGradientElement,SVGRadialGradientElement,SVGHKernElement,SVGImageElement,SVGLineElement,SVGMarkerElement,SVGMaskElement,SVGMetadataElement,SVGMissingGlyphElement,SVGMPathElement,SVGPathElement,SVGPatternElement,SVGPolylineElement,SVGPolygonElement,SVGRectElement,SVGScriptElement,SVGStopElement,SVGStyleElement,SVGSVGElement,SVGSwitchElement,SVGSymbolElement,SVGTextElement,SVGTextPathElement,SVGTitleElement,SVGTRefElement,SVGTSpanElement,SVGUseElement,SVGViewElement,SVGVKernElement,SVGAngle,SVGColor,SVGICCColor,SVGElementInstance,SVGElementInstanceList,SVGLength,SVGLengthList,SVGMatrix,SVGNumber,SVGNumberList,SVGPaint,SVGPoint,SVGPointList,SVGPreserveAspectRatio,SVGRect,SVGStringList,SVGTransform,SVGTransformList,SVGAnimatedAngle,SVGAnimatedBoolean,SVGAnimatedEnumeration,SVGAnimatedInteger,SVGAnimatedLength,SVGAnimatedLengthList,SVGAnimatedNumber,SVGAnimatedNumberList,SVGAnimatedPreserveAspectRatio,SVGAnimatedRect,SVGAnimatedString,SVGAnimatedTransformList,SVGPathSegList,SVGPathSeg,SVGPathSegArcAbs,SVGPathSegArcRel,SVGPathSegClosePath,SVGPathSegCurvetoCubicAbs,SVGPathSegCurvetoCubicRel,SVGPathSegCurvetoCubicSmoothAbs,SVGPathSegCurvetoCubicSmoothRel,SVGPathSegCurvetoQuadraticAbs,SVGPathSegCurvetoQuadraticRel,SVGPathSegCurvetoQuadraticSmoothAbs,SVGPathSegCurvetoQuadraticSmoothRel,SVGPathSegLinetoAbs,SVGPathSegLinetoHorizontalAbs,SVGPathSegLinetoHorizontalRel,SVGPathSegLinetoRel,SVGPathSegLinetoVerticalAbs,SVGPathSegLinetoVerticalRel,SVGPathSegMovetoAbs,SVGPathSegMovetoRel,ElementTimeControl,TimeEvent,SVGAnimatedPathData,SVGAnimatedPoints,SVGColorProfileRule,SVGCSSRule,SVGExternalResourcesRequired,SVGFitToViewBox,SVGLangSpace,SVGLocatable,SVGRenderingIntent,SVGStylable,SVGTests,SVGTextContentElement,SVGTextPositioningElement,SVGTransformable,SVGUnitTypes,SVGURIReference,SVGViewSpec,SVGZoomAndPan");
                +Blockly.JavaScript.ORDER_ATOMIC=0;Blockly.JavaScript.ORDER_NEW=1.1;Blockly.JavaScript.ORDER_MEMBER=1.2;Blockly.JavaScript.ORDER_FUNCTION_CALL=2;Blockly.JavaScript.ORDER_INCREMENT=3;Blockly.JavaScript.ORDER_DECREMENT=3;Blockly.JavaScript.ORDER_BITWISE_NOT=4.1;Blockly.JavaScript.ORDER_UNARY_PLUS=4.2;Blockly.JavaScript.ORDER_UNARY_NEGATION=4.3;Blockly.JavaScript.ORDER_LOGICAL_NOT=4.4;Blockly.JavaScript.ORDER_TYPEOF=4.5;Blockly.JavaScript.ORDER_VOID=4.6;Blockly.JavaScript.ORDER_DELETE=4.7;
                +Blockly.JavaScript.ORDER_DIVISION=5.1;Blockly.JavaScript.ORDER_MULTIPLICATION=5.2;Blockly.JavaScript.ORDER_MODULUS=5.3;Blockly.JavaScript.ORDER_SUBTRACTION=6.1;Blockly.JavaScript.ORDER_ADDITION=6.2;Blockly.JavaScript.ORDER_BITWISE_SHIFT=7;Blockly.JavaScript.ORDER_RELATIONAL=8;Blockly.JavaScript.ORDER_IN=8;Blockly.JavaScript.ORDER_INSTANCEOF=8;Blockly.JavaScript.ORDER_EQUALITY=9;Blockly.JavaScript.ORDER_BITWISE_AND=10;Blockly.JavaScript.ORDER_BITWISE_XOR=11;Blockly.JavaScript.ORDER_BITWISE_OR=12;
                +Blockly.JavaScript.ORDER_LOGICAL_AND=13;Blockly.JavaScript.ORDER_LOGICAL_OR=14;Blockly.JavaScript.ORDER_CONDITIONAL=15;Blockly.JavaScript.ORDER_ASSIGNMENT=16;Blockly.JavaScript.ORDER_COMMA=17;Blockly.JavaScript.ORDER_NONE=99;
                +Blockly.JavaScript.ORDER_OVERRIDES=[[Blockly.JavaScript.ORDER_FUNCTION_CALL,Blockly.JavaScript.ORDER_MEMBER],[Blockly.JavaScript.ORDER_FUNCTION_CALL,Blockly.JavaScript.ORDER_FUNCTION_CALL],[Blockly.JavaScript.ORDER_MEMBER,Blockly.JavaScript.ORDER_MEMBER],[Blockly.JavaScript.ORDER_MEMBER,Blockly.JavaScript.ORDER_FUNCTION_CALL],[Blockly.JavaScript.ORDER_LOGICAL_NOT,Blockly.JavaScript.ORDER_LOGICAL_NOT],[Blockly.JavaScript.ORDER_MULTIPLICATION,Blockly.JavaScript.ORDER_MULTIPLICATION],[Blockly.JavaScript.ORDER_ADDITION,
                +Blockly.JavaScript.ORDER_ADDITION],[Blockly.JavaScript.ORDER_LOGICAL_AND,Blockly.JavaScript.ORDER_LOGICAL_AND],[Blockly.JavaScript.ORDER_LOGICAL_OR,Blockly.JavaScript.ORDER_LOGICAL_OR]];
                +Blockly.JavaScript.init=function(a){Blockly.JavaScript.definitions_=Object.create(null);Blockly.JavaScript.functionNames_=Object.create(null);Blockly.JavaScript.variableDB_?Blockly.JavaScript.variableDB_.reset():Blockly.JavaScript.variableDB_=new Blockly.Names(Blockly.JavaScript.RESERVED_WORDS_);var b=[];a=a.getAllVariables();if(a.length){for(var c=0;c<a.length;c++)b[c]=Blockly.JavaScript.variableDB_.getName(a[c].name,Blockly.Variables.NAME_TYPE);Blockly.JavaScript.definitions_.variables="var "+b.join(", ")+
                +";"}};Blockly.JavaScript.finish=function(a){var b=[],c;for(c in Blockly.JavaScript.definitions_)b.push(Blockly.JavaScript.definitions_[c]);delete Blockly.JavaScript.definitions_;delete Blockly.JavaScript.functionNames_;Blockly.JavaScript.variableDB_.reset();return b.join("\n\n")+"\n\n\n"+a};Blockly.JavaScript.scrubNakedValue=function(a){return a+";\n"};Blockly.JavaScript.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/'/g,"\\'");return"'"+a+"'"};
                +Blockly.JavaScript.scrub_=function(a,b){var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();(d=Blockly.utils.wrap(d,Blockly.JavaScript.COMMENT_WRAP-3))&&(c=a.getProcedureDef?c+("/**\n"+Blockly.JavaScript.prefixLines(d+"\n"," * ")+" */\n"):c+Blockly.JavaScript.prefixLines(d+"\n","// "));for(var e=0;e<a.inputList.length;e++)a.inputList[e].type==Blockly.INPUT_VALUE&&(d=a.inputList[e].connection.targetBlock())&&(d=Blockly.JavaScript.allNestedComments(d))&&(c+=
                +Blockly.JavaScript.prefixLines(d,"// "))}e=a.nextConnection&&a.nextConnection.targetBlock();e=Blockly.JavaScript.blockToCode(e);return c+b+e};
                +Blockly.JavaScript.getAdjusted=function(a,b,c,d,e){c=c||0;e=e||Blockly.JavaScript.ORDER_NONE;a.workspace.options.oneBasedIndex&&c--;var f=a.workspace.options.oneBasedIndex?"1":"0";a=0<c?Blockly.JavaScript.valueToCode(a,b,Blockly.JavaScript.ORDER_ADDITION)||f:0>c?Blockly.JavaScript.valueToCode(a,b,Blockly.JavaScript.ORDER_SUBTRACTION)||f:d?Blockly.JavaScript.valueToCode(a,b,Blockly.JavaScript.ORDER_UNARY_NEGATION)||f:Blockly.JavaScript.valueToCode(a,b,e)||f;if(Blockly.isNumber(a))a=parseFloat(a)+c,
                +d&&(a=-a);else{if(0<c){a=a+" + "+c;var g=Blockly.JavaScript.ORDER_ADDITION}else 0>c&&(a=a+" - "+-c,g=Blockly.JavaScript.ORDER_SUBTRACTION);d&&(a=c?"-("+a+")":"-"+a,g=Blockly.JavaScript.ORDER_UNARY_NEGATION);g=Math.floor(g);e=Math.floor(e);g&&e>=g&&(a="("+a+")")}return a};Blockly.JavaScript.colour={};Blockly.JavaScript.colour_picker=function(a){return["'"+a.getFieldValue("COLOUR")+"'",Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.colour_random=function(a){return[Blockly.JavaScript.provideFunction_("colourRandom",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"() {","  var num = Math.floor(Math.random() * Math.pow(2, 24));","  return '#' + ('00000' + num.toString(16)).substr(-6);","}"])+"()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.colour_rgb=function(a){var b=Blockly.JavaScript.valueToCode(a,"RED",Blockly.JavaScript.ORDER_COMMA)||0,c=Blockly.JavaScript.valueToCode(a,"GREEN",Blockly.JavaScript.ORDER_COMMA)||0;a=Blockly.JavaScript.valueToCode(a,"BLUE",Blockly.JavaScript.ORDER_COMMA)||0;return[Blockly.JavaScript.provideFunction_("colourRgb",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(r, g, b) {","  r = Math.max(Math.min(Number(r), 100), 0) * 2.55;","  g = Math.max(Math.min(Number(g), 100), 0) * 2.55;",
                +"  b = Math.max(Math.min(Number(b), 100), 0) * 2.55;","  r = ('0' + (Math.round(r) || 0).toString(16)).slice(-2);","  g = ('0' + (Math.round(g) || 0).toString(16)).slice(-2);","  b = ('0' + (Math.round(b) || 0).toString(16)).slice(-2);","  return '#' + r + g + b;","}"])+"("+b+", "+c+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.colour_blend=function(a){var b=Blockly.JavaScript.valueToCode(a,"COLOUR1",Blockly.JavaScript.ORDER_COMMA)||"'#000000'",c=Blockly.JavaScript.valueToCode(a,"COLOUR2",Blockly.JavaScript.ORDER_COMMA)||"'#000000'";a=Blockly.JavaScript.valueToCode(a,"RATIO",Blockly.JavaScript.ORDER_COMMA)||.5;return[Blockly.JavaScript.provideFunction_("colourBlend",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(c1, c2, ratio) {","  ratio = Math.max(Math.min(Number(ratio), 1), 0);","  var r1 = parseInt(c1.substring(1, 3), 16);",
                +"  var g1 = parseInt(c1.substring(3, 5), 16);","  var b1 = parseInt(c1.substring(5, 7), 16);","  var r2 = parseInt(c2.substring(1, 3), 16);","  var g2 = parseInt(c2.substring(3, 5), 16);","  var b2 = parseInt(c2.substring(5, 7), 16);","  var r = Math.round(r1 * (1 - ratio) + r2 * ratio);","  var g = Math.round(g1 * (1 - ratio) + g2 * ratio);","  var b = Math.round(b1 * (1 - ratio) + b2 * ratio);","  r = ('0' + (r || 0).toString(16)).slice(-2);","  g = ('0' + (g || 0).toString(16)).slice(-2);","  b = ('0' + (b || 0).toString(16)).slice(-2);",
                +"  return '#' + r + g + b;","}"])+"("+b+", "+c+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.lists={};Blockly.JavaScript.lists_create_empty=function(a){return["[]",Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.JavaScript.valueToCode(a,"ADD"+c,Blockly.JavaScript.ORDER_COMMA)||"null";return["["+b.join(", ")+"]",Blockly.JavaScript.ORDER_ATOMIC]};
                +Blockly.JavaScript.lists_repeat=function(a){var b=Blockly.JavaScript.provideFunction_("listsRepeat",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(value, n) {","  var array = [];","  for (var i = 0; i < n; i++) {","    array[i] = value;","  }","  return array;","}"]),c=Blockly.JavaScript.valueToCode(a,"ITEM",Blockly.JavaScript.ORDER_COMMA)||"null";a=Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_COMMA)||"0";return[b+"("+c+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.lists_length=function(a){return[(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_MEMBER)||"[]")+".length",Blockly.JavaScript.ORDER_MEMBER]};Blockly.JavaScript.lists_isEmpty=function(a){return["!"+(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_MEMBER)||"[]")+".length",Blockly.JavaScript.ORDER_LOGICAL_NOT]};
                +Blockly.JavaScript.lists_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"indexOf":"lastIndexOf",c=Blockly.JavaScript.valueToCode(a,"FIND",Blockly.JavaScript.ORDER_NONE)||"''",b=(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_MEMBER)||"[]")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.JavaScript.ORDER_ADDITION]:[b,Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.lists_getIndex=function(a){var b=a.getFieldValue("MODE")||"GET",c=a.getFieldValue("WHERE")||"FROM_START";var d=Blockly.JavaScript.valueToCode(a,"VALUE","RANDOM"==c?Blockly.JavaScript.ORDER_COMMA:Blockly.JavaScript.ORDER_MEMBER)||"[]";switch(c){case "FIRST":if("GET"==b)return[d+"[0]",Blockly.JavaScript.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".shift()",Blockly.JavaScript.ORDER_MEMBER];if("REMOVE"==b)return d+".shift();\n";break;case "LAST":if("GET"==b)return[d+".slice(-1)[0]",
                +Blockly.JavaScript.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop()",Blockly.JavaScript.ORDER_MEMBER];if("REMOVE"==b)return d+".pop();\n";break;case "FROM_START":a=Blockly.JavaScript.getAdjusted(a,"AT");if("GET"==b)return[d+"["+a+"]",Blockly.JavaScript.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".splice("+a+", 1)[0]",Blockly.JavaScript.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".splice("+a+", 1);\n";break;case "FROM_END":a=Blockly.JavaScript.getAdjusted(a,"AT",1,!0);if("GET"==b)return[d+".slice("+
                +a+")[0]",Blockly.JavaScript.ORDER_FUNCTION_CALL];if("GET_REMOVE"==b)return[d+".splice("+a+", 1)[0]",Blockly.JavaScript.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".splice("+a+", 1);";break;case "RANDOM":d=Blockly.JavaScript.provideFunction_("listsGetRandomItem",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(list, remove) {","  var x = Math.floor(Math.random() * list.length);","  if (remove) {","    return list.splice(x, 1)[0];","  } else {","    return list[x];","  }","}"])+"("+d+
                +", "+("GET"!=b)+")";if("GET"==b||"GET_REMOVE"==b)return[d,Blockly.JavaScript.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+";\n"}throw"Unhandled combination (lists_getIndex).";};
                +Blockly.JavaScript.lists_setIndex=function(a){function b(){if(c.match(/^\w+$/))return"";var a=Blockly.JavaScript.variableDB_.getDistinctName("tmpList",Blockly.Variables.NAME_TYPE),b="var "+a+" = "+c+";\n";c=a;return b}var c=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_MEMBER)||"[]",d=a.getFieldValue("MODE")||"GET",e=a.getFieldValue("WHERE")||"FROM_START",f=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_ASSIGNMENT)||"null";switch(e){case "FIRST":if("SET"==d)return c+
                +"[0] = "+f+";\n";if("INSERT"==d)return c+".unshift("+f+");\n";break;case "LAST":if("SET"==d)return a=b(),a+(c+"["+c+".length - 1] = "+f+";\n");if("INSERT"==d)return c+".push("+f+");\n";break;case "FROM_START":e=Blockly.JavaScript.getAdjusted(a,"AT");if("SET"==d)return c+"["+e+"] = "+f+";\n";if("INSERT"==d)return c+".splice("+e+", 0, "+f+");\n";break;case "FROM_END":e=Blockly.JavaScript.getAdjusted(a,"AT",1,!1,Blockly.JavaScript.ORDER_SUBTRACTION);a=b();if("SET"==d)return a+(c+"["+c+".length - "+e+
                +"] = "+f+";\n");if("INSERT"==d)return a+(c+".splice("+c+".length - "+e+", 0, "+f+");\n");break;case "RANDOM":a=b();e=Blockly.JavaScript.variableDB_.getDistinctName("tmpX",Blockly.Variables.NAME_TYPE);a+="var "+e+" = Math.floor(Math.random() * "+c+".length);\n";if("SET"==d)return a+(c+"["+e+"] = "+f+";\n");if("INSERT"==d)return a+(c+".splice("+e+", 0, "+f+");\n")}throw"Unhandled combination (lists_setIndex).";};
                +Blockly.JavaScript.lists.getIndex_=function(a,b,c){return"FIRST"==b?"0":"FROM_END"==b?a+".length - 1 - "+c:"LAST"==b?a+".length - 1":c};
                +Blockly.JavaScript.lists_getSublist=function(a){var b=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_MEMBER)||"[]",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if("FIRST"==c&&"LAST"==d)var e=b+".slice(0)";else if(b.match(/^\w+$/)||"FROM_END"!=c&&"FROM_START"==d){switch(c){case "FROM_START":e=Blockly.JavaScript.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.JavaScript.getAdjusted(a,"AT1",1,!1,Blockly.JavaScript.ORDER_SUBTRACTION);e=b+".length - "+e;break;case "FIRST":e=
                +"0";break;default:throw"Unhandled option (lists_getSublist).";}switch(d){case "FROM_START":a=Blockly.JavaScript.getAdjusted(a,"AT2",1);break;case "FROM_END":a=Blockly.JavaScript.getAdjusted(a,"AT2",0,!1,Blockly.JavaScript.ORDER_SUBTRACTION);a=b+".length - "+a;break;case "LAST":a=b+".length";break;default:throw"Unhandled option (lists_getSublist).";}e=b+".slice("+e+", "+a+")"}else{e=Blockly.JavaScript.getAdjusted(a,"AT1");a=Blockly.JavaScript.getAdjusted(a,"AT2");var f=Blockly.JavaScript.lists.getIndex_,
                +g={FIRST:"First",LAST:"Last",FROM_START:"FromStart",FROM_END:"FromEnd"};e=Blockly.JavaScript.provideFunction_("subsequence"+g[c]+g[d],["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(sequence"+("FROM_END"==c||"FROM_START"==c?", at1":"")+("FROM_END"==d||"FROM_START"==d?", at2":"")+") {","  var start = "+f("sequence",c,"at1")+";","  var end = "+f("sequence",d,"at2")+" + 1;","  return sequence.slice(start, end);","}"])+"("+b+("FROM_END"==c||"FROM_START"==c?", "+e:"")+("FROM_END"==d||"FROM_START"==
                +d?", "+a:"")+")"}return[e,Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.lists_sort=function(a){var b=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_FUNCTION_CALL)||"[]",c="1"===a.getFieldValue("DIRECTION")?1:-1;a=a.getFieldValue("TYPE");var d=Blockly.JavaScript.provideFunction_("listsGetSortCompare",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(type, direction) {","  var compareFuncs = {",'    "NUMERIC": function(a, b) {',"        return parseFloat(a) - parseFloat(b); },",'    "TEXT": function(a, b) {',"        return a.toString() > b.toString() ? 1 : -1; },",
                +'    "IGNORE_CASE": function(a, b) {',"        return a.toString().toLowerCase() > b.toString().toLowerCase() ? 1 : -1; },","  };","  var compare = compareFuncs[type];","  return function(a, b) { return compare(a, b) * direction; }","}"]);return[b+".slice().sort("+d+'("'+a+'", '+c+"))",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.lists_split=function(a){var b=Blockly.JavaScript.valueToCode(a,"INPUT",Blockly.JavaScript.ORDER_MEMBER),c=Blockly.JavaScript.valueToCode(a,"DELIM",Blockly.JavaScript.ORDER_NONE)||"''";a=a.getFieldValue("MODE");if("SPLIT"==a)b||(b="''"),a="split";else if("JOIN"==a)b||(b="[]"),a="join";else throw"Unknown mode: "+a;return[b+"."+a+"("+c+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.lists_reverse=function(a){return[(Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_FUNCTION_CALL)||"[]")+".slice().reverse()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.logic={};Blockly.JavaScript.controls_if=function(a){var b=0,c="";do{var d=Blockly.JavaScript.valueToCode(a,"IF"+b,Blockly.JavaScript.ORDER_NONE)||"false";var e=Blockly.JavaScript.statementToCode(a,"DO"+b);c+=(0<b?" else ":"")+"if ("+d+") {\n"+e+"}";++b}while(a.getInput("IF"+b));a.getInput("ELSE")&&(e=Blockly.JavaScript.statementToCode(a,"ELSE"),c+=" else {\n"+e+"}");return c+"\n"};Blockly.JavaScript.controls_ifelse=Blockly.JavaScript.controls_if;
                +Blockly.JavaScript.logic_compare=function(a){var b={EQ:"==",NEQ:"!=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c="=="==b||"!="==b?Blockly.JavaScript.ORDER_EQUALITY:Blockly.JavaScript.ORDER_RELATIONAL,d=Blockly.JavaScript.valueToCode(a,"A",c)||"0";a=Blockly.JavaScript.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
                +Blockly.JavaScript.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"&&":"||",c="&&"==b?Blockly.JavaScript.ORDER_LOGICAL_AND:Blockly.JavaScript.ORDER_LOGICAL_OR,d=Blockly.JavaScript.valueToCode(a,"A",c);a=Blockly.JavaScript.valueToCode(a,"B",c);if(d||a){var e="&&"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]};
                +Blockly.JavaScript.logic_negate=function(a){var b=Blockly.JavaScript.ORDER_LOGICAL_NOT;return["!"+(Blockly.JavaScript.valueToCode(a,"BOOL",b)||"true"),b]};Blockly.JavaScript.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.logic_null=function(a){return["null",Blockly.JavaScript.ORDER_ATOMIC]};
                +Blockly.JavaScript.logic_ternary=function(a){var b=Blockly.JavaScript.valueToCode(a,"IF",Blockly.JavaScript.ORDER_CONDITIONAL)||"false",c=Blockly.JavaScript.valueToCode(a,"THEN",Blockly.JavaScript.ORDER_CONDITIONAL)||"null";a=Blockly.JavaScript.valueToCode(a,"ELSE",Blockly.JavaScript.ORDER_CONDITIONAL)||"null";return[b+" ? "+c+" : "+a,Blockly.JavaScript.ORDER_CONDITIONAL]};Blockly.JavaScript.loops={};
                +Blockly.JavaScript.controls_repeat_ext=function(a){var b=a.getField("TIMES")?String(Number(a.getFieldValue("TIMES"))):Blockly.JavaScript.valueToCode(a,"TIMES",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0";var c=Blockly.JavaScript.statementToCode(a,"DO"),c=Blockly.JavaScript.addLoopTrap(c,a.id),d="",e=Blockly.JavaScript.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE);a=b;b.match(/^\w+$/)||Blockly.isNumber(b)||(a=Blockly.JavaScript.variableDB_.getDistinctName("repeat_end",Blockly.Variables.NAME_TYPE),
                +d+="var "+a+" = "+b+";\n");return d+("for (var "+e+" = 0; "+e+" < "+a+"; "+e+"++) {\n"+c+"}\n")};Blockly.JavaScript.controls_repeat=Blockly.JavaScript.controls_repeat_ext;
                +Blockly.JavaScript.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.JavaScript.valueToCode(a,"BOOL",b?Blockly.JavaScript.ORDER_LOGICAL_NOT:Blockly.JavaScript.ORDER_NONE)||"false",d=Blockly.JavaScript.statementToCode(a,"DO"),d=Blockly.JavaScript.addLoopTrap(d,a.id);b&&(c="!"+c);return"while ("+c+") {\n"+d+"}\n"};
                +Blockly.JavaScript.controls_for=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);var c=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0";var d=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0",e=Blockly.JavaScript.valueToCode(a,"BY",Blockly.JavaScript.ORDER_ASSIGNMENT)||"1",f=Blockly.JavaScript.statementToCode(a,"DO"),f=Blockly.JavaScript.addLoopTrap(f,a.id);if(Blockly.isNumber(c)&&
                +Blockly.isNumber(d)&&Blockly.isNumber(e)){var g=parseFloat(c)<=parseFloat(d);a="for ("+b+" = "+c+"; "+b+(g?" <= ":" >= ")+d+"; "+b;b=Math.abs(parseFloat(e));a=(1==b?a+(g?"++":"--"):a+((g?" += ":" -= ")+b))+(") {\n"+f+"}\n")}else a="",g=c,c.match(/^\w+$/)||Blockly.isNumber(c)||(g=Blockly.JavaScript.variableDB_.getDistinctName(b+"_start",Blockly.Variables.NAME_TYPE),a+="var "+g+" = "+c+";\n"),c=d,d.match(/^\w+$/)||Blockly.isNumber(d)||(c=Blockly.JavaScript.variableDB_.getDistinctName(b+"_end",Blockly.Variables.NAME_TYPE),
                +a+="var "+c+" = "+d+";\n"),d=Blockly.JavaScript.variableDB_.getDistinctName(b+"_inc",Blockly.Variables.NAME_TYPE),a+="var "+d+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+";\n"):a+("Math.abs("+e+");\n"),a=a+("if ("+g+" > "+c+") {\n")+(Blockly.JavaScript.INDENT+d+" = -"+d+";\n"),a+="}\n",a+="for ("+b+" = "+g+"; "+d+" >= 0 ? "+b+" <= "+c+" : "+b+" >= "+c+"; "+b+" += "+d+") {\n"+f+"}\n";return a};
                +Blockly.JavaScript.controls_forEach=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_ASSIGNMENT)||"[]",d=Blockly.JavaScript.statementToCode(a,"DO"),d=Blockly.JavaScript.addLoopTrap(d,a.id);a="";var e=c;c.match(/^\w+$/)||(e=Blockly.JavaScript.variableDB_.getDistinctName(b+"_list",Blockly.Variables.NAME_TYPE),a+="var "+e+" = "+c+";\n");c=Blockly.JavaScript.variableDB_.getDistinctName(b+
                +"_index",Blockly.Variables.NAME_TYPE);d=Blockly.JavaScript.INDENT+b+" = "+e+"["+c+"];\n"+d;return a+("for (var "+c+" in "+e+") {\n"+d+"}\n")};Blockly.JavaScript.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break;\n";case "CONTINUE":return"continue;\n"}throw"Unknown flow statement.";};Blockly.JavaScript.math={};Blockly.JavaScript.math_number=function(a){return[parseFloat(a.getFieldValue("NUM")),Blockly.JavaScript.ORDER_ATOMIC]};
                +Blockly.JavaScript.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.JavaScript.ORDER_ADDITION],MINUS:[" - ",Blockly.JavaScript.ORDER_SUBTRACTION],MULTIPLY:[" * ",Blockly.JavaScript.ORDER_MULTIPLICATION],DIVIDE:[" / ",Blockly.JavaScript.ORDER_DIVISION],POWER:[null,Blockly.JavaScript.ORDER_COMMA]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.JavaScript.valueToCode(a,"A",b)||"0";a=Blockly.JavaScript.valueToCode(a,"B",b)||"0";return c?[d+c+a,b]:["Math.pow("+d+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b)return a=Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_UNARY_NEGATION)||"0","-"==a[0]&&(a=" "+a),["-"+a,Blockly.JavaScript.ORDER_UNARY_NEGATION];a="SIN"==b||"COS"==b||"TAN"==b?Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_DIVISION)||"0":Blockly.JavaScript.valueToCode(a,"NUM",Blockly.JavaScript.ORDER_NONE)||"0";switch(b){case "ABS":var c="Math.abs("+a+")";break;case "ROOT":c="Math.sqrt("+
                +a+")";break;case "LN":c="Math.log("+a+")";break;case "EXP":c="Math.exp("+a+")";break;case "POW10":c="Math.pow(10,"+a+")";break;case "ROUND":c="Math.round("+a+")";break;case "ROUNDUP":c="Math.ceil("+a+")";break;case "ROUNDDOWN":c="Math.floor("+a+")";break;case "SIN":c="Math.sin("+a+" / 180 * Math.PI)";break;case "COS":c="Math.cos("+a+" / 180 * Math.PI)";break;case "TAN":c="Math.tan("+a+" / 180 * Math.PI)"}if(c)return[c,Blockly.JavaScript.ORDER_FUNCTION_CALL];switch(b){case "LOG10":c="Math.log("+a+
                +") / Math.log(10)";break;case "ASIN":c="Math.asin("+a+") / Math.PI * 180";break;case "ACOS":c="Math.acos("+a+") / Math.PI * 180";break;case "ATAN":c="Math.atan("+a+") / Math.PI * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.JavaScript.ORDER_DIVISION]};
                +Blockly.JavaScript.math_constant=function(a){return{PI:["Math.PI",Blockly.JavaScript.ORDER_MEMBER],E:["Math.E",Blockly.JavaScript.ORDER_MEMBER],GOLDEN_RATIO:["(1 + Math.sqrt(5)) / 2",Blockly.JavaScript.ORDER_DIVISION],SQRT2:["Math.SQRT2",Blockly.JavaScript.ORDER_MEMBER],SQRT1_2:["Math.SQRT1_2",Blockly.JavaScript.ORDER_MEMBER],INFINITY:["Infinity",Blockly.JavaScript.ORDER_ATOMIC]}[a.getFieldValue("CONSTANT")]};
                +Blockly.JavaScript.math_number_property=function(a){var b=Blockly.JavaScript.valueToCode(a,"NUMBER_TO_CHECK",Blockly.JavaScript.ORDER_MODULUS)||"0",c=a.getFieldValue("PROPERTY");if("PRIME"==c)return[Blockly.JavaScript.provideFunction_("mathIsPrime",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(n) {","  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods","  if (n == 2 || n == 3) {","    return true;","  }","  // False if n is NaN, negative, is 1, or not whole.","  // And false if n is divisible by 2 or 3.",
                +"  if (isNaN(n) || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) {","    return false;","  }","  // Check all the numbers of form 6k +/- 1, up to sqrt(n).","  for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {","    if (n % (x - 1) == 0 || n % (x + 1) == 0) {","      return false;","    }","  }","  return true;","}"])+"("+b+")",Blockly.JavaScript.ORDER_FUNCTION_CALL];switch(c){case "EVEN":var d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=
                +b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.JavaScript.valueToCode(a,"DIVISOR",Blockly.JavaScript.ORDER_MODULUS)||"0",d=b+" % "+a+" == 0"}return[d,Blockly.JavaScript.ORDER_EQUALITY]};Blockly.JavaScript.math_change=function(a){var b=Blockly.JavaScript.valueToCode(a,"DELTA",Blockly.JavaScript.ORDER_ADDITION)||"0";a=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);return a+" = (typeof "+a+" == 'number' ? "+a+" : 0) + "+b+";\n"};
                +Blockly.JavaScript.math_round=Blockly.JavaScript.math_single;Blockly.JavaScript.math_trig=Blockly.JavaScript.math_single;
                +Blockly.JavaScript.math_on_list=function(a){var b=a.getFieldValue("OP");switch(b){case "SUM":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_MEMBER)||"[]";a+=".reduce(function(x, y) {return x + y;})";break;case "MIN":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_COMMA)||"[]";a="Math.min.apply(null, "+a+")";break;case "MAX":a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_COMMA)||"[]";a="Math.max.apply(null, "+a+")";break;case "AVERAGE":b=Blockly.JavaScript.provideFunction_("mathMean",
                +["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(myList) {","  return myList.reduce(function(x, y) {return x + y;}) / myList.length;","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "MEDIAN":b=Blockly.JavaScript.provideFunction_("mathMedian",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(myList) {","  var localList = myList.filter(function (x) {return typeof x == 'number';});","  if (!localList.length) return null;",
                +"  localList.sort(function(a, b) {return b - a;});","  if (localList.length % 2 == 0) {","    return (localList[localList.length / 2 - 1] + localList[localList.length / 2]) / 2;","  } else {","    return localList[(localList.length - 1) / 2];","  }","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "MODE":b=Blockly.JavaScript.provideFunction_("mathModes",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(values) {","  var modes = [];",
                +"  var counts = [];","  var maxCount = 0;","  for (var i = 0; i < values.length; i++) {","    var value = values[i];","    var found = false;","    var thisCount;","    for (var j = 0; j < counts.length; j++) {","      if (counts[j][0] === value) {","        thisCount = ++counts[j][1];","        found = true;","        break;","      }","    }","    if (!found) {","      counts.push([value, 1]);","      thisCount = 1;","    }","    maxCount = Math.max(thisCount, maxCount);","  }","  for (var j = 0; j < counts.length; j++) {",
                +"    if (counts[j][1] == maxCount) {","        modes.push(counts[j][0]);","    }","  }","  return modes;","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "STD_DEV":b=Blockly.JavaScript.provideFunction_("mathStandardDeviation",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(numbers) {","  var n = numbers.length;","  if (!n) return null;","  var mean = numbers.reduce(function(x, y) {return x + y;}) / n;","  var variance = 0;",
                +"  for (var j = 0; j < n; j++) {","    variance += Math.pow(numbers[j] - mean, 2);","  }","  variance = variance / n;","  return Math.sqrt(variance);","}"]);a=Blockly.JavaScript.valueToCode(a,"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "RANDOM":b=Blockly.JavaScript.provideFunction_("mathRandomList",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(list) {","  var x = Math.floor(Math.random() * list.length);","  return list[x];","}"]);a=Blockly.JavaScript.valueToCode(a,
                +"LIST",Blockly.JavaScript.ORDER_NONE)||"[]";a=b+"("+a+")";break;default:throw"Unknown operator: "+b;}return[a,Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_modulo=function(a){var b=Blockly.JavaScript.valueToCode(a,"DIVIDEND",Blockly.JavaScript.ORDER_MODULUS)||"0";a=Blockly.JavaScript.valueToCode(a,"DIVISOR",Blockly.JavaScript.ORDER_MODULUS)||"0";return[b+" % "+a,Blockly.JavaScript.ORDER_MODULUS]};
                +Blockly.JavaScript.math_constrain=function(a){var b=Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_COMMA)||"0",c=Blockly.JavaScript.valueToCode(a,"LOW",Blockly.JavaScript.ORDER_COMMA)||"0";a=Blockly.JavaScript.valueToCode(a,"HIGH",Blockly.JavaScript.ORDER_COMMA)||"Infinity";return["Math.min(Math.max("+b+", "+c+"), "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.math_random_int=function(a){var b=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_COMMA)||"0";a=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_COMMA)||"0";return[Blockly.JavaScript.provideFunction_("mathRandomInt",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(a, b) {","  if (a > b) {","    // Swap a and b to ensure a is smaller.","    var c = a;","    a = b;","    b = c;","  }","  return Math.floor(Math.random() * (b - a + 1) + a);",
                +"}"])+"("+b+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_random_float=function(a){return["Math.random()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.procedures={};
                +Blockly.JavaScript.procedures_defreturn=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=Blockly.JavaScript.statementToCode(a,"STACK");Blockly.JavaScript.STATEMENT_PREFIX&&(c=Blockly.JavaScript.prefixLines(Blockly.JavaScript.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+"'"),Blockly.JavaScript.INDENT)+c);Blockly.JavaScript.INFINITE_LOOP_TRAP&&(c=Blockly.JavaScript.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var d=Blockly.JavaScript.valueToCode(a,
                +"RETURN",Blockly.JavaScript.ORDER_NONE)||"";d&&(d="  return "+d+";\n");for(var e=[],f=0;f<a.arguments_.length;f++)e[f]=Blockly.JavaScript.variableDB_.getName(a.arguments_[f],Blockly.Variables.NAME_TYPE);c="function "+b+"("+e.join(", ")+") {\n"+c+d+"}";c=Blockly.JavaScript.scrub_(a,c);Blockly.JavaScript.definitions_["%"+b]=c;return null};Blockly.JavaScript.procedures_defnoreturn=Blockly.JavaScript.procedures_defreturn;
                +Blockly.JavaScript.procedures_callreturn=function(a){for(var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.JavaScript.valueToCode(a,"ARG"+d,Blockly.JavaScript.ORDER_COMMA)||"null";return[b+"("+c.join(", ")+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.procedures_callnoreturn=function(a){for(var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.JavaScript.valueToCode(a,"ARG"+d,Blockly.JavaScript.ORDER_COMMA)||"null";return b+"("+c.join(", ")+");\n"};
                +Blockly.JavaScript.procedures_ifreturn=function(a){var b="if ("+(Blockly.JavaScript.valueToCode(a,"CONDITION",Blockly.JavaScript.ORDER_NONE)||"false")+") {\n";a.hasReturnValue_?(a=Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_NONE)||"null",b+="  return "+a+";\n"):b+="  return;\n";return b+"}\n"};Blockly.JavaScript.texts={};Blockly.JavaScript.text=function(a){return[Blockly.JavaScript.quote_(a.getFieldValue("TEXT")),Blockly.JavaScript.ORDER_ATOMIC]};
                +Blockly.JavaScript.text_join=function(a){switch(a.itemCount_){case 0:return["''",Blockly.JavaScript.ORDER_ATOMIC];case 1:return["String("+(Blockly.JavaScript.valueToCode(a,"ADD0",Blockly.JavaScript.ORDER_NONE)||"''")+")",Blockly.JavaScript.ORDER_FUNCTION_CALL];case 2:var b=Blockly.JavaScript.valueToCode(a,"ADD0",Blockly.JavaScript.ORDER_NONE)||"''";a=Blockly.JavaScript.valueToCode(a,"ADD1",Blockly.JavaScript.ORDER_NONE)||"''";return["String("+b+") + String("+a+")",Blockly.JavaScript.ORDER_ADDITION];
                +default:for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.JavaScript.valueToCode(a,"ADD"+c,Blockly.JavaScript.ORDER_COMMA)||"''";a="["+b.join(",")+"].join('')";return[a,Blockly.JavaScript.ORDER_FUNCTION_CALL]}};Blockly.JavaScript.text_append=function(a){var b=Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);a=Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_NONE)||"''";return b+" = String("+b+") + String("+a+");\n"};
                +Blockly.JavaScript.text_length=function(a){return[(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_FUNCTION_CALL)||"''")+".length",Blockly.JavaScript.ORDER_MEMBER]};Blockly.JavaScript.text_isEmpty=function(a){return["!"+(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_MEMBER)||"''")+".length",Blockly.JavaScript.ORDER_LOGICAL_NOT]};
                +Blockly.JavaScript.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"indexOf":"lastIndexOf",c=Blockly.JavaScript.valueToCode(a,"FIND",Blockly.JavaScript.ORDER_NONE)||"''",b=(Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_MEMBER)||"''")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.JavaScript.ORDER_ADDITION]:[b,Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.JavaScript.valueToCode(a,"VALUE","RANDOM"==b?Blockly.JavaScript.ORDER_NONE:Blockly.JavaScript.ORDER_MEMBER)||"''";switch(b){case "FIRST":return[c+".charAt(0)",Blockly.JavaScript.ORDER_FUNCTION_CALL];case "LAST":return[c+".slice(-1)",Blockly.JavaScript.ORDER_FUNCTION_CALL];case "FROM_START":return a=Blockly.JavaScript.getAdjusted(a,"AT"),[c+".charAt("+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL];case "FROM_END":return a=
                +Blockly.JavaScript.getAdjusted(a,"AT",1,!0),[c+".slice("+a+").charAt(0)",Blockly.JavaScript.ORDER_FUNCTION_CALL];case "RANDOM":return[Blockly.JavaScript.provideFunction_("textRandomLetter",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(text) {","  var x = Math.floor(Math.random() * text.length);","  return text[x];","}"])+"("+c+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]}throw"Unhandled option (text_charAt).";};
                +Blockly.JavaScript.text.getIndex_=function(a,b,c){return"FIRST"==b?"0":"FROM_END"==b?a+".length - 1 - "+c:"LAST"==b?a+".length - 1":c};
                +Blockly.JavaScript.text_getSubstring=function(a){var b=Blockly.JavaScript.valueToCode(a,"STRING",Blockly.JavaScript.ORDER_FUNCTION_CALL)||"''",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if("FIRST"==c&&"LAST"==d)var e=b;else if(b.match(/^'?\w+'?$/)||"FROM_END"!=c&&"LAST"!=c&&"FROM_END"!=d&&"LAST"!=d){switch(c){case "FROM_START":e=Blockly.JavaScript.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.JavaScript.getAdjusted(a,"AT1",1,!1,Blockly.JavaScript.ORDER_SUBTRACTION);e=b+".length - "+
                +e;break;case "FIRST":e="0";break;default:throw"Unhandled option (text_getSubstring).";}switch(d){case "FROM_START":a=Blockly.JavaScript.getAdjusted(a,"AT2",1);break;case "FROM_END":a=Blockly.JavaScript.getAdjusted(a,"AT2",0,!1,Blockly.JavaScript.ORDER_SUBTRACTION);a=b+".length - "+a;break;case "LAST":a=b+".length";break;default:throw"Unhandled option (text_getSubstring).";}e=b+".slice("+e+", "+a+")"}else{e=Blockly.JavaScript.getAdjusted(a,"AT1");a=Blockly.JavaScript.getAdjusted(a,"AT2");var f=Blockly.JavaScript.text.getIndex_,
                +g={FIRST:"First",LAST:"Last",FROM_START:"FromStart",FROM_END:"FromEnd"};e=Blockly.JavaScript.provideFunction_("subsequence"+g[c]+g[d],["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(sequence"+("FROM_END"==c||"FROM_START"==c?", at1":"")+("FROM_END"==d||"FROM_START"==d?", at2":"")+") {","  var start = "+f("sequence",c,"at1")+";","  var end = "+f("sequence",d,"at2")+" + 1;","  return sequence.slice(start, end);","}"])+"("+b+("FROM_END"==c||"FROM_START"==c?", "+e:"")+("FROM_END"==d||"FROM_START"==
                +d?", "+a:"")+")"}return[e,Blockly.JavaScript.ORDER_FUNCTION_CALL]};
                +Blockly.JavaScript.text_changeCase=function(a){var b={UPPERCASE:".toUpperCase()",LOWERCASE:".toLowerCase()",TITLECASE:null}[a.getFieldValue("CASE")];a=Blockly.JavaScript.valueToCode(a,"TEXT",b?Blockly.JavaScript.ORDER_MEMBER:Blockly.JavaScript.ORDER_NONE)||"''";return[b?a+b:Blockly.JavaScript.provideFunction_("textToTitleCase",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(str) {","  return str.replace(/\\S+/g,","      function(txt) {return txt[0].toUpperCase() + txt.substring(1).toLowerCase();});","}"])+
                +"("+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.text_trim=function(a){var b={LEFT:".replace(/^[\\s\\xa0]+/, '')",RIGHT:".replace(/[\\s\\xa0]+$/, '')",BOTH:".trim()"}[a.getFieldValue("MODE")];return[(Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_MEMBER)||"''")+b,Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.text_print=function(a){return"window.alert("+(Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_NONE)||"''")+");\n"};
                +Blockly.JavaScript.text_prompt_ext=function(a){var b="window.prompt("+(a.getField("TEXT")?Blockly.JavaScript.quote_(a.getFieldValue("TEXT")):Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_NONE)||"''")+")";"NUMBER"==a.getFieldValue("TYPE")&&(b="parseFloat("+b+")");return[b,Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.text_prompt=Blockly.JavaScript.text_prompt_ext;
                +Blockly.JavaScript.text_count=function(a){var b=Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_MEMBER)||"''";a=Blockly.JavaScript.valueToCode(a,"SUB",Blockly.JavaScript.ORDER_NONE)||"''";return[Blockly.JavaScript.provideFunction_("textCount",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(haystack, needle) {","  if (needle.length === 0) {","    return haystack.length + 1;","  } else {","    return haystack.split(needle).length - 1;","  }","}"])+"("+b+", "+a+")",Blockly.JavaScript.ORDER_SUBTRACTION]};
                +Blockly.JavaScript.text_replace=function(a){var b=Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_MEMBER)||"''",c=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_NONE)||"''";a=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_NONE)||"''";return[Blockly.JavaScript.provideFunction_("textReplace",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(haystack, needle, replacement) {",'  needle = needle.replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g,"\\\\$1")',
                +'                 .replace(/\\x08/g,"\\\\x08");',"  return haystack.replace(new RegExp(needle, 'g'), replacement);","}"])+"("+b+", "+c+", "+a+")",Blockly.JavaScript.ORDER_MEMBER]};Blockly.JavaScript.text_reverse=function(a){return[(Blockly.JavaScript.valueToCode(a,"TEXT",Blockly.JavaScript.ORDER_MEMBER)||"''")+".split('').reverse().join('')",Blockly.JavaScript.ORDER_MEMBER]};Blockly.JavaScript.variables={};Blockly.JavaScript.variables_get=function(a){return[Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.variables_set=function(a){var b=Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_ASSIGNMENT)||"0";return Blockly.JavaScript.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" = "+b+";\n"};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/lua_compressed.js b/blockly/webif/static/blockly/lua_compressed.js
                new file mode 100644
                index 000000000..c71e25bc6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/lua_compressed.js
                @@ -0,0 +1,96 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Language
                +
                + Copyright 2016 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Lua=new Blockly.Generator("Lua");Blockly.Lua.addReservedWords("_,__inext,assert,bit,colors,colours,coroutine,disk,dofile,error,fs,fetfenv,getmetatable,gps,help,io,ipairs,keys,loadfile,loadstring,math,native,next,os,paintutils,pairs,parallel,pcall,peripheral,print,printError,rawequal,rawget,rawset,read,rednet,redstone,rs,select,setfenv,setmetatable,sleep,string,table,term,textutils,tonumber,tostring,turtle,type,unpack,vector,write,xpcall,_VERSION,__indext,HTTP,and,break,do,else,elseif,end,false,for,function,if,in,local,nil,not,or,repeat,return,then,true,until,while,add,sub,mul,div,mod,pow,unm,concat,len,eq,lt,le,index,newindex,call,assert,collectgarbage,dofile,error,_G,getmetatable,inpairs,load,loadfile,next,pairs,pcall,print,rawequal,rawget,rawlen,rawset,select,setmetatable,tonumber,tostring,type,_VERSION,xpcall,require,package,string,table,math,bit32,io,file,os,debug");
                +Blockly.Lua.ORDER_ATOMIC=0;Blockly.Lua.ORDER_HIGH=1;Blockly.Lua.ORDER_EXPONENTIATION=2;Blockly.Lua.ORDER_UNARY=3;Blockly.Lua.ORDER_MULTIPLICATIVE=4;Blockly.Lua.ORDER_ADDITIVE=5;Blockly.Lua.ORDER_CONCATENATION=6;Blockly.Lua.ORDER_RELATIONAL=7;Blockly.Lua.ORDER_AND=8;Blockly.Lua.ORDER_OR=9;Blockly.Lua.ORDER_NONE=99;
                +Blockly.Lua.init=function(a){Blockly.Lua.definitions_=Object.create(null);Blockly.Lua.functionNames_=Object.create(null);Blockly.Lua.variableDB_?Blockly.Lua.variableDB_.reset():Blockly.Lua.variableDB_=new Blockly.Names(Blockly.Lua.RESERVED_WORDS_)};Blockly.Lua.finish=function(a){var b=[],c;for(c in Blockly.Lua.definitions_)b.push(Blockly.Lua.definitions_[c]);delete Blockly.Lua.definitions_;delete Blockly.Lua.functionNames_;Blockly.Lua.variableDB_.reset();return b.join("\n\n")+"\n\n\n"+a};
                +Blockly.Lua.scrubNakedValue=function(a){return"local _ = "+a+"\n"};Blockly.Lua.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/'/g,"\\'");return"'"+a+"'"};
                +Blockly.Lua.scrub_=function(a,b){var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();(d=Blockly.utils.wrap(d,Blockly.Lua.COMMENT_WRAP-3))&&(c+=Blockly.Lua.prefixLines(d,"-- ")+"\n");for(var e=0;e<a.inputList.length;e++)a.inputList[e].type==Blockly.INPUT_VALUE&&(d=a.inputList[e].connection.targetBlock())&&(d=Blockly.Lua.allNestedComments(d))&&(c+=Blockly.Lua.prefixLines(d,"-- "))}e=a.nextConnection&&a.nextConnection.targetBlock();e=Blockly.Lua.blockToCode(e);
                +return c+b+e};Blockly.Lua.colour={};Blockly.Lua.colour_picker=function(a){return["'"+a.getFieldValue("COLOUR")+"'",Blockly.Lua.ORDER_ATOMIC]};Blockly.Lua.colour_random=function(a){return['string.format("#%06x", math.random(0, 2^24 - 1))',Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.colour_rgb=function(a){var b=Blockly.Lua.provideFunction_("colour_rgb",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(r, g, b)","  r = math.floor(math.min(100, math.max(0, r)) * 2.55 + .5)","  g = math.floor(math.min(100, math.max(0, g)) * 2.55 + .5)","  b = math.floor(math.min(100, math.max(0, b)) * 2.55 + .5)",'  return string.format("#%02x%02x%02x", r, g, b)',"end"]),c=Blockly.Lua.valueToCode(a,"RED",Blockly.Lua.ORDER_NONE)||0,d=Blockly.Lua.valueToCode(a,"GREEN",Blockly.Lua.ORDER_NONE)||
                +0;a=Blockly.Lua.valueToCode(a,"BLUE",Blockly.Lua.ORDER_NONE)||0;return[b+"("+c+", "+d+", "+a+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.colour_blend=function(a){var b=Blockly.Lua.provideFunction_("colour_blend",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(colour1, colour2, ratio)","  local r1 = tonumber(string.sub(colour1, 2, 3), 16)","  local r2 = tonumber(string.sub(colour2, 2, 3), 16)","  local g1 = tonumber(string.sub(colour1, 4, 5), 16)","  local g2 = tonumber(string.sub(colour2, 4, 5), 16)","  local b1 = tonumber(string.sub(colour1, 6, 7), 16)","  local b2 = tonumber(string.sub(colour2, 6, 7), 16)","  local ratio = math.min(1, math.max(0, ratio))",
                +"  local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)","  local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)","  local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)",'  return string.format("#%02x%02x%02x", r, g, b)',"end"]),c=Blockly.Lua.valueToCode(a,"COLOUR1",Blockly.Lua.ORDER_NONE)||"'#000000'",d=Blockly.Lua.valueToCode(a,"COLOUR2",Blockly.Lua.ORDER_NONE)||"'#000000'";a=Blockly.Lua.valueToCode(a,"RATIO",Blockly.Lua.ORDER_NONE)||0;return[b+"("+c+", "+d+", "+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.lists={};Blockly.Lua.lists_create_empty=function(a){return["{}",Blockly.Lua.ORDER_ATOMIC]};Blockly.Lua.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Lua.valueToCode(a,"ADD"+c,Blockly.Lua.ORDER_NONE)||"None";return["{"+b.join(", ")+"}",Blockly.Lua.ORDER_ATOMIC]};
                +Blockly.Lua.lists_repeat=function(a){var b=Blockly.Lua.provideFunction_("create_list_repeated",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(item, count)","  local t = {}","  for i = 1, count do","    table.insert(t, item)","  end","  return t","end"]),c=Blockly.Lua.valueToCode(a,"ITEM",Blockly.Lua.ORDER_NONE)||"None";a=Blockly.Lua.valueToCode(a,"NUM",Blockly.Lua.ORDER_NONE)||"0";return[b+"("+c+", "+a+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.lists_length=function(a){return["#"+(Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_UNARY)||"{}"),Blockly.Lua.ORDER_UNARY]};Blockly.Lua.lists_isEmpty=function(a){return["#"+(Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_UNARY)||"{}")+" == 0",Blockly.Lua.ORDER_RELATIONAL]};
                +Blockly.Lua.lists_indexOf=function(a){var b=Blockly.Lua.valueToCode(a,"FIND",Blockly.Lua.ORDER_NONE)||"''",c=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"{}";return[("FIRST"==a.getFieldValue("END")?Blockly.Lua.provideFunction_("first_index",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t, elem)","  for k, v in ipairs(t) do","    if v == elem then","      return k","    end","  end","  return 0","end"]):Blockly.Lua.provideFunction_("last_index",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+
                +"(t, elem)","  for i = #t, 1, -1 do","    if t[i] == elem then","      return i","    end","  end","  return 0","end"]))+"("+c+", "+b+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.lists.getIndex_=function(a,b,c){return"FIRST"==b?"1":"FROM_END"==b?"#"+a+" + 1 - "+c:"LAST"==b?"#"+a:"RANDOM"==b?"math.random(#"+a+")":c};
                +Blockly.Lua.lists_getIndex=function(a){var b=a.getFieldValue("MODE")||"GET";var c=a.getFieldValue("WHERE")||"FROM_START";var d=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_HIGH)||"{}",e=Blockly.Lua.lists.getIndex_;if("LAST"!=c&&"FROM_END"!=c&&"RANDOM"!=c||d.match(/^\w+$/)){var f="GET"==b&&"FROM_END"==c?Blockly.Lua.ORDER_ADDITIVE:Blockly.Lua.ORDER_NONE;a=Blockly.Lua.valueToCode(a,"AT",f)||"1";a=e(d,c,a);if("GET"==b)return[d+"["+a+"]",Blockly.Lua.ORDER_HIGH];c="table.remove("+d+", "+a+")";return"GET_REMOVE"==
                +b?[c,Blockly.Lua.ORDER_HIGH]:c+"\n"}if("REMOVE"==b)return f="FROM_END"==c?Blockly.Lua.ORDER_ADDITIVE:Blockly.Lua.ORDER_NONE,a=Blockly.Lua.valueToCode(a,"AT",f)||"1",b=Blockly.Lua.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),a=e(b,c,a),b+" = "+d+"\ntable.remove("+b+", "+a+")\n";a=Blockly.Lua.valueToCode(a,"AT",Blockly.Lua.ORDER_NONE)||"1";return[("GET"==b?Blockly.Lua.provideFunction_("list_get_"+c.toLowerCase(),["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t"+("FROM_END"==
                +c||"FROM_START"==c?", at)":")"),"  return t["+e("t",c,"at")+"]","end"]):Blockly.Lua.provideFunction_("list_remove_"+c.toLowerCase(),["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t"+("FROM_END"==c||"FROM_START"==c?", at)":")"),"  return table.remove(t, "+e("t",c,"at")+")","end"]))+"("+d+("FROM_END"==c||"FROM_START"==c?", "+a:"")+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.lists_setIndex=function(a){var b=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_HIGH)||"{}",c=a.getFieldValue("MODE")||"SET",d=a.getFieldValue("WHERE")||"FROM_START",e=Blockly.Lua.valueToCode(a,"AT",Blockly.Lua.ORDER_ADDITIVE)||"1";a=Blockly.Lua.valueToCode(a,"TO",Blockly.Lua.ORDER_NONE)||"None";var f=Blockly.Lua.lists.getIndex_,g="";if(("LAST"==d||"FROM_END"==d||"RANDOM"==d)&&!b.match(/^\w+$/))var h=Blockly.Lua.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),g=
                +h+" = "+b+"\n",b=h;g="SET"==c?g+(b+"["+f(b,d,e)+"] = "+a):g+("table.insert("+b+", "+(f(b,d,e)+("LAST"==d?" + 1":""))+", "+a+")");return g+"\n"};
                +Blockly.Lua.lists_getSublist=function(a){var b=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_NONE)||"{}",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2"),e=Blockly.Lua.valueToCode(a,"AT1",Blockly.Lua.ORDER_NONE)||"1";a=Blockly.Lua.valueToCode(a,"AT2",Blockly.Lua.ORDER_NONE)||"1";var f=Blockly.Lua.lists.getIndex_;return[Blockly.Lua.provideFunction_("list_sublist_"+c.toLowerCase()+"_"+d.toLowerCase(),["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(source"+("FROM_END"==c||"FROM_START"==
                +c?", at1":"")+("FROM_END"==d||"FROM_START"==d?", at2":"")+")","  local t = {}","  local start = "+f("source",c,"at1"),"  local finish = "+f("source",d,"at2"),"  for i = start, finish do","    table.insert(t, source[i])","  end","  return t","end"])+"("+b+("FROM_END"==c||"FROM_START"==c?", "+e:"")+("FROM_END"==d||"FROM_START"==d?", "+a:"")+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.lists_sort=function(a){var b=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_NONE)||"{}",c="1"===a.getFieldValue("DIRECTION")?1:-1;a=a.getFieldValue("TYPE");return[Blockly.Lua.provideFunction_("list_sort",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(list, typev, direction)","  local t = {}","  for n,v in pairs(list) do table.insert(t, v) end","  local compareFuncs = {","    NUMERIC = function(a, b)","      return (tonumber(tostring(a)) or 0)","          < (tonumber(tostring(b)) or 0) end,",
                +"    TEXT = function(a, b)","      return tostring(a) < tostring(b) end,","    IGNORE_CASE = function(a, b)","      return string.lower(tostring(a)) < string.lower(tostring(b)) end","  }","  local compareTemp = compareFuncs[typev]","  local compare = compareTemp","  if direction == -1","  then compare = function(a, b) return compareTemp(b, a) end","  end","  table.sort(t, compare)","  return t","end"])+"("+b+',"'+a+'", '+c+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.lists_split=function(a){var b=Blockly.Lua.valueToCode(a,"INPUT",Blockly.Lua.ORDER_NONE),c=Blockly.Lua.valueToCode(a,"DELIM",Blockly.Lua.ORDER_NONE)||"''";a=a.getFieldValue("MODE");if("SPLIT"==a)b||(b="''"),a=Blockly.Lua.provideFunction_("list_string_split",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(input, delim)","  local t = {}","  local pos = 1","  while true do","    next_delim = string.find(input, delim, pos)","    if next_delim == nil then","      table.insert(t, string.sub(input, pos))",
                +"      break","    else","      table.insert(t, string.sub(input, pos, next_delim-1))","      pos = next_delim + #delim","    end","  end","  return t","end"]);else if("JOIN"==a)b||(b="{}"),a="table.concat";else throw"Unknown mode: "+a;return[a+"("+b+", "+c+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.lists_reverse=function(a){a=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_NONE)||"{}";Blockly.Lua.provideFunction_("list_reverse",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(input)","  local reversed = {}","  for i = #input, 1, -1 do","    table.insert(reversed, input[i])","  end","  return reversed","end"]);return["list_reverse("+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.logic={};Blockly.Lua.controls_if=function(a){var b=0,c="";do{var d=Blockly.Lua.valueToCode(a,"IF"+b,Blockly.Lua.ORDER_NONE)||"false";var e=Blockly.Lua.statementToCode(a,"DO"+b);c+=(0<b?"else":"")+"if "+d+" then\n"+e;++b}while(a.getInput("IF"+b));a.getInput("ELSE")&&(e=Blockly.Lua.statementToCode(a,"ELSE"),c+="else\n"+e);return c+"end\n"};Blockly.Lua.controls_ifelse=Blockly.Lua.controls_if;
                +Blockly.Lua.logic_compare=function(a){var b={EQ:"==",NEQ:"~=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c=Blockly.Lua.valueToCode(a,"A",Blockly.Lua.ORDER_RELATIONAL)||"0";a=Blockly.Lua.valueToCode(a,"B",Blockly.Lua.ORDER_RELATIONAL)||"0";return[c+" "+b+" "+a,Blockly.Lua.ORDER_RELATIONAL]};
                +Blockly.Lua.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"and":"or",c="and"==b?Blockly.Lua.ORDER_AND:Blockly.Lua.ORDER_OR,d=Blockly.Lua.valueToCode(a,"A",c);a=Blockly.Lua.valueToCode(a,"B",c);if(d||a){var e="and"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]};Blockly.Lua.logic_negate=function(a){return["not "+(Blockly.Lua.valueToCode(a,"BOOL",Blockly.Lua.ORDER_UNARY)||"true"),Blockly.Lua.ORDER_UNARY]};
                +Blockly.Lua.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.Lua.ORDER_ATOMIC]};Blockly.Lua.logic_null=function(a){return["nil",Blockly.Lua.ORDER_ATOMIC]};Blockly.Lua.logic_ternary=function(a){var b=Blockly.Lua.valueToCode(a,"IF",Blockly.Lua.ORDER_AND)||"false",c=Blockly.Lua.valueToCode(a,"THEN",Blockly.Lua.ORDER_AND)||"nil";a=Blockly.Lua.valueToCode(a,"ELSE",Blockly.Lua.ORDER_OR)||"nil";return[b+" and "+c+" or "+a,Blockly.Lua.ORDER_OR]};Blockly.Lua.loops={};Blockly.Lua.CONTINUE_STATEMENT="goto continue\n";Blockly.Lua.addContinueLabel=function(a){return-1<a.indexOf(Blockly.Lua.CONTINUE_STATEMENT)?a+Blockly.Lua.INDENT+"::continue::\n":a};Blockly.Lua.controls_repeat=function(a){var b=parseInt(a.getFieldValue("TIMES"),10);a=Blockly.Lua.statementToCode(a,"DO")||"";a=Blockly.Lua.addContinueLabel(a);return"for "+Blockly.Lua.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE)+" = 1, "+b+" do\n"+a+"end\n"};
                +Blockly.Lua.controls_repeat_ext=function(a){var b=Blockly.Lua.valueToCode(a,"TIMES",Blockly.Lua.ORDER_NONE)||"0",b=Blockly.isNumber(b)?parseInt(b,10):"math.floor("+b+")";a=Blockly.Lua.statementToCode(a,"DO")||"\n";a=Blockly.Lua.addContinueLabel(a);return"for "+Blockly.Lua.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE)+" = 1, "+b+" do\n"+a+"end\n"};
                +Blockly.Lua.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.Lua.valueToCode(a,"BOOL",b?Blockly.Lua.ORDER_UNARY:Blockly.Lua.ORDER_NONE)||"false",d=Blockly.Lua.statementToCode(a,"DO")||"\n",d=Blockly.Lua.addLoopTrap(d,a.id),d=Blockly.Lua.addContinueLabel(d);b&&(c="not "+c);return"while "+c+" do\n"+d+"end\n"};
                +Blockly.Lua.controls_for=function(a){var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Lua.valueToCode(a,"FROM",Blockly.Lua.ORDER_NONE)||"0",d=Blockly.Lua.valueToCode(a,"TO",Blockly.Lua.ORDER_NONE)||"0",e=Blockly.Lua.valueToCode(a,"BY",Blockly.Lua.ORDER_NONE)||"1",f=Blockly.Lua.statementToCode(a,"DO")||"\n",f=Blockly.Lua.addLoopTrap(f,a.id),f=Blockly.Lua.addContinueLabel(f);a="";if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&Blockly.isNumber(e)){var g=
                +parseFloat(c)<=parseFloat(d);e=Math.abs(parseFloat(e));g=(g?"":"-")+e}else a="",g=Blockly.Lua.variableDB_.getDistinctName(b+"_inc",Blockly.Variables.NAME_TYPE),a+=g+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+"\n"):a+("math.abs("+e+")\n"),a=a+("if ("+c+") > ("+d+") then\n")+(Blockly.Lua.INDENT+g+" = -"+g+"\n"),a+="end\n";return a+("for "+b+" = "+c+", "+d+", "+g)+(" do\n"+f+"end\n")};
                +Blockly.Lua.controls_forEach=function(a){var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_NONE)||"{}";a=Blockly.Lua.statementToCode(a,"DO")||"\n";a=Blockly.Lua.addContinueLabel(a);return"for _, "+b+" in ipairs("+c+") do \n"+a+"end\n"};
                +Blockly.Lua.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break\n";case "CONTINUE":return Blockly.Lua.CONTINUE_STATEMENT}throw"Unknown flow statement.";};Blockly.Lua.math={};Blockly.Lua.math_number=function(a){a=parseFloat(a.getFieldValue("NUM"));return[a,0>a?Blockly.Lua.ORDER_UNARY:Blockly.Lua.ORDER_ATOMIC]};
                +Blockly.Lua.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.Lua.ORDER_ADDITIVE],MINUS:[" - ",Blockly.Lua.ORDER_ADDITIVE],MULTIPLY:[" * ",Blockly.Lua.ORDER_MULTIPLICATIVE],DIVIDE:[" / ",Blockly.Lua.ORDER_MULTIPLICATIVE],POWER:[" ^ ",Blockly.Lua.ORDER_EXPONENTIATION]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.Lua.valueToCode(a,"A",b)||"0";a=Blockly.Lua.valueToCode(a,"B",b)||"0";return[d+c+a,b]};
                +Blockly.Lua.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b)return a=Blockly.Lua.valueToCode(a,"NUM",Blockly.Lua.ORDER_UNARY)||"0",["-"+a,Blockly.Lua.ORDER_UNARY];a="SIN"==b||"COS"==b||"TAN"==b?Blockly.Lua.valueToCode(a,"NUM",Blockly.Lua.ORDER_MULTIPLICATIVE)||"0":Blockly.Lua.valueToCode(a,"NUM",Blockly.Lua.ORDER_NONE)||"0";switch(b){case "ABS":b="math.abs("+a+")";break;case "ROOT":b="math.sqrt("+a+")";break;case "LN":b="math.log("+a+")";break;case "LOG10":b="math.log10("+a+")";break;
                +case "EXP":b="math.exp("+a+")";break;case "POW10":b="math.pow(10,"+a+")";break;case "ROUND":b="math.floor("+a+" + .5)";break;case "ROUNDUP":b="math.ceil("+a+")";break;case "ROUNDDOWN":b="math.floor("+a+")";break;case "SIN":b="math.sin(math.rad("+a+"))";break;case "COS":b="math.cos(math.rad("+a+"))";break;case "TAN":b="math.tan(math.rad("+a+"))";break;case "ASIN":b="math.deg(math.asin("+a+"))";break;case "ACOS":b="math.deg(math.acos("+a+"))";break;case "ATAN":b="math.deg(math.atan("+a+"))";break;default:throw"Unknown math operator: "+
                +b;}return[b,Blockly.Lua.ORDER_HIGH]};Blockly.Lua.math_constant=function(a){return{PI:["math.pi",Blockly.Lua.ORDER_HIGH],E:["math.exp(1)",Blockly.Lua.ORDER_HIGH],GOLDEN_RATIO:["(1 + math.sqrt(5)) / 2",Blockly.Lua.ORDER_MULTIPLICATIVE],SQRT2:["math.sqrt(2)",Blockly.Lua.ORDER_HIGH],SQRT1_2:["math.sqrt(1 / 2)",Blockly.Lua.ORDER_HIGH],INFINITY:["math.huge",Blockly.Lua.ORDER_HIGH]}[a.getFieldValue("CONSTANT")]};
                +Blockly.Lua.math_number_property=function(a){var b=Blockly.Lua.valueToCode(a,"NUMBER_TO_CHECK",Blockly.Lua.ORDER_MULTIPLICATIVE)||"0",c=a.getFieldValue("PROPERTY");if("PRIME"==c)return[Blockly.Lua.provideFunction_("math_isPrime",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(n)","  -- https://en.wikipedia.org/wiki/Primality_test#Naive_methods","  if n == 2 or n == 3 then","    return true","  end","  -- False if n is NaN, negative, is 1, or not whole.","  -- And false if n is divisible by 2 or 3.",
                +"  if not(n > 1) or n % 1 ~= 0 or n % 2 == 0 or n % 3 == 0 then","    return false","  end","  -- Check all the numbers of form 6k +/- 1, up to sqrt(n).","  for x = 6, math.sqrt(n) + 1.5, 6 do","    if n % (x - 1) == 0 or n % (x + 1) == 0 then","      return false","    end","  end","  return true","end"])+"("+b+")",Blockly.Lua.ORDER_HIGH];switch(c){case "EVEN":var d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=b+" > 0";break;case "NEGATIVE":d=
                +b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.Lua.valueToCode(a,"DIVISOR",Blockly.Lua.ORDER_MULTIPLICATIVE);if(!a||"0"==a)return["nil",Blockly.Lua.ORDER_ATOMIC];d=b+" % "+a+" == 0"}return[d,Blockly.Lua.ORDER_RELATIONAL]};Blockly.Lua.math_change=function(a){var b=Blockly.Lua.valueToCode(a,"DELTA",Blockly.Lua.ORDER_ADDITIVE)||"0";a=Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);return a+" = "+a+" + "+b+"\n"};Blockly.Lua.math_round=Blockly.Lua.math_single;
                +Blockly.Lua.math_trig=Blockly.Lua.math_single;
                +Blockly.Lua.math_on_list=function(a){function b(){return Blockly.Lua.provideFunction_("math_sum",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  local result = 0","  for _, v in ipairs(t) do","    result = result + v","  end","  return result","end"])}var c=a.getFieldValue("OP");a=Blockly.Lua.valueToCode(a,"LIST",Blockly.Lua.ORDER_NONE)||"{}";switch(c){case "SUM":c=b();break;case "MIN":c=Blockly.Lua.provideFunction_("math_min",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)",
                +"  if #t == 0 then","    return 0","  end","  local result = math.huge","  for _, v in ipairs(t) do","    if v < result then","      result = v","    end","  end","  return result","end"]);break;case "AVERAGE":c=Blockly.Lua.provideFunction_("math_average",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  if #t == 0 then","    return 0","  end","  return "+b()+"(t) / #t","end"]);break;case "MAX":c=Blockly.Lua.provideFunction_("math_max",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+
                +"(t)","  if #t == 0 then","    return 0","  end","  local result = -math.huge","  for _, v in ipairs(t) do","    if v > result then","      result = v","    end","  end","  return result","end"]);break;case "MEDIAN":c=Blockly.Lua.provideFunction_("math_median",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  -- Source: http://lua-users.org/wiki/SimpleStats","  if #t == 0 then","    return 0","  end","  local temp={}","  for _, v in ipairs(t) do",'    if type(v) == "number" then',"      table.insert(temp, v)",
                +"    end","  end","  table.sort(temp)","  if #temp % 2 == 0 then","    return (temp[#temp/2] + temp[(#temp/2)+1]) / 2","  else","    return temp[math.ceil(#temp/2)]","  end","end"]);break;case "MODE":c=Blockly.Lua.provideFunction_("math_modes",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  -- Source: http://lua-users.org/wiki/SimpleStats","  local counts={}","  for _, v in ipairs(t) do","    if counts[v] == nil then","      counts[v] = 1","    else","      counts[v] = counts[v] + 1",
                +"    end","  end","  local biggestCount = 0","  for _, v  in pairs(counts) do","    if v > biggestCount then","      biggestCount = v","    end","  end","  local temp={}","  for k, v in pairs(counts) do","    if v == biggestCount then","      table.insert(temp, k)","    end","  end","  return temp","end"]);break;case "STD_DEV":c=Blockly.Lua.provideFunction_("math_standard_deviation",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  local m","  local vm","  local total = 0","  local count = 0",
                +"  local result","  m = #t == 0 and 0 or "+b()+"(t) / #t","  for _, v in ipairs(t) do","    if type(v) == 'number' then","      vm = v - m","      total = total + (vm * vm)","      count = count + 1","    end","  end","  result = math.sqrt(total / (count-1))","  return result","end"]);break;case "RANDOM":c=Blockly.Lua.provideFunction_("math_random_list",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(t)","  if #t == 0 then","    return nil","  end","  return t[math.random(#t)]","end"]);break;
                +default:throw"Unknown operator: "+c;}return[c+"("+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.math_modulo=function(a){var b=Blockly.Lua.valueToCode(a,"DIVIDEND",Blockly.Lua.ORDER_MULTIPLICATIVE)||"0";a=Blockly.Lua.valueToCode(a,"DIVISOR",Blockly.Lua.ORDER_MULTIPLICATIVE)||"0";return[b+" % "+a,Blockly.Lua.ORDER_MULTIPLICATIVE]};
                +Blockly.Lua.math_constrain=function(a){var b=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"0",c=Blockly.Lua.valueToCode(a,"LOW",Blockly.Lua.ORDER_NONE)||"-math.huge";a=Blockly.Lua.valueToCode(a,"HIGH",Blockly.Lua.ORDER_NONE)||"math.huge";return["math.min(math.max("+b+", "+c+"), "+a+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.math_random_int=function(a){var b=Blockly.Lua.valueToCode(a,"FROM",Blockly.Lua.ORDER_NONE)||"0";a=Blockly.Lua.valueToCode(a,"TO",Blockly.Lua.ORDER_NONE)||"0";return["math.random("+b+", "+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.math_random_float=function(a){return["math.random()",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.procedures={};
                +Blockly.Lua.procedures_defreturn=function(a){var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=Blockly.Lua.statementToCode(a,"STACK");Blockly.Lua.STATEMENT_PREFIX&&(c=Blockly.Lua.prefixLines(Blockly.Lua.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+"'"),Blockly.Lua.INDENT)+c);Blockly.Lua.INFINITE_LOOP_TRAP&&(c=Blockly.Lua.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var d=Blockly.Lua.valueToCode(a,"RETURN",Blockly.Lua.ORDER_NONE)||"";d?d="  return "+d+"\n":
                +c||(c="");for(var e=[],f=0;f<a.arguments_.length;f++)e[f]=Blockly.Lua.variableDB_.getName(a.arguments_[f],Blockly.Variables.NAME_TYPE);c="function "+b+"("+e.join(", ")+")\n"+c+d+"end\n";c=Blockly.Lua.scrub_(a,c);Blockly.Lua.definitions_["%"+b]=c;return null};Blockly.Lua.procedures_defnoreturn=Blockly.Lua.procedures_defreturn;
                +Blockly.Lua.procedures_callreturn=function(a){for(var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Lua.valueToCode(a,"ARG"+d,Blockly.Lua.ORDER_NONE)||"nil";return[b+"("+c.join(", ")+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.procedures_callnoreturn=function(a){for(var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Lua.valueToCode(a,"ARG"+d,Blockly.Lua.ORDER_NONE)||"nil";return b+"("+c.join(", ")+")\n"};
                +Blockly.Lua.procedures_ifreturn=function(a){var b="if "+(Blockly.Lua.valueToCode(a,"CONDITION",Blockly.Lua.ORDER_NONE)||"false")+" then\n";a.hasReturnValue_?(a=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"nil",b+="  return "+a+"\n"):b+="  return\n";return b+"end\n"};Blockly.Lua.texts={};Blockly.Lua.text=function(a){return[Blockly.Lua.quote_(a.getFieldValue("TEXT")),Blockly.Lua.ORDER_ATOMIC]};
                +Blockly.Lua.text_join=function(a){if(0==a.itemCount_)return["''",Blockly.Lua.ORDER_ATOMIC];if(1==a.itemCount_)return["tostring("+(Blockly.Lua.valueToCode(a,"ADD0",Blockly.Lua.ORDER_NONE)||"''")+")",Blockly.Lua.ORDER_HIGH];if(2==a.itemCount_){var b=Blockly.Lua.valueToCode(a,"ADD0",Blockly.Lua.ORDER_CONCATENATION)||"''";a=Blockly.Lua.valueToCode(a,"ADD1",Blockly.Lua.ORDER_CONCATENATION)||"''";return[b+" .. "+a,Blockly.Lua.ORDER_CONCATENATION]}for(var b=[],c=0;c<a.itemCount_;c++)b[c]=Blockly.Lua.valueToCode(a,
                +"ADD"+c,Blockly.Lua.ORDER_NONE)||"''";return["table.concat({"+b.join(", ")+"})",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.text_append=function(a){var b=Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);a=Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_CONCATENATION)||"''";return b+" = "+b+" .. "+a+"\n"};Blockly.Lua.text_length=function(a){return["#"+(Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_UNARY)||"''"),Blockly.Lua.ORDER_UNARY]};
                +Blockly.Lua.text_isEmpty=function(a){return["#"+(Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_UNARY)||"''")+" == 0",Blockly.Lua.ORDER_RELATIONAL]};
                +Blockly.Lua.text_indexOf=function(a){var b=Blockly.Lua.valueToCode(a,"FIND",Blockly.Lua.ORDER_NONE)||"''",c=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"''";return[("FIRST"==a.getFieldValue("END")?Blockly.Lua.provideFunction_("firstIndexOf",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(str, substr) ","  local i = string.find(str, substr, 1, true)","  if i == nil then","    return 0","  else","    return i","  end","end"]):Blockly.Lua.provideFunction_("lastIndexOf",["function "+
                +Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(str, substr)","  local i = string.find(string.reverse(str), string.reverse(substr), 1, true)","  if i then","    return #str + 2 - i - #substr","  end","  return 0","end"]))+"("+c+", "+b+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START";var c=Blockly.Lua.valueToCode(a,"AT","FROM_END"==b?Blockly.Lua.ORDER_UNARY:Blockly.Lua.ORDER_NONE)||"1";a=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"''";if("RANDOM"==b)b=Blockly.Lua.provideFunction_("text_random_letter",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(str)","  local index = math.random(string.len(str))","  return string.sub(str, index, index)","end"]),a=b+"("+a+")";else{if("FIRST"==
                +b)c="1";else if("LAST"==b)c="-1";else if("FROM_START"!=b)if("FROM_END"==b)c="-"+c;else throw"Unhandled option (text_charAt).";c.match(/^-?\w*$/)?a="string.sub("+a+", "+c+", "+c+")":(b=Blockly.Lua.provideFunction_("text_char_at",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(str, index)","  return string.sub(str, index, index)","end"]),a=b+"("+a+", "+c+")")}return[a,Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.text_getSubstring=function(a){var b=Blockly.Lua.valueToCode(a,"STRING",Blockly.Lua.ORDER_NONE)||"''";var c=a.getFieldValue("WHERE1");var d=Blockly.Lua.valueToCode(a,"AT1","FROM_END"==c?Blockly.Lua.ORDER_UNARY:Blockly.Lua.ORDER_NONE)||"1";if("FIRST"==c)c=1;else if("FROM_START"==c)c=d;else if("FROM_END"==c)c="-"+d;else throw"Unhandled option (text_getSubstring)";d=a.getFieldValue("WHERE2");a=Blockly.Lua.valueToCode(a,"AT2","FROM_END"==d?Blockly.Lua.ORDER_UNARY:Blockly.Lua.ORDER_NONE)||"1";
                +if("LAST"==d)a=-1;else if("FROM_START"!=d)if("FROM_END"==d)a="-"+a;else throw"Unhandled option (text_getSubstring)";return["string.sub("+b+", "+c+", "+a+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.text_changeCase=function(a){var b,c=a.getFieldValue("CASE");a=Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''";"UPPERCASE"==c?b="string.upper":"LOWERCASE"==c?b="string.lower":"TITLECASE"==c&&(b=Blockly.Lua.provideFunction_("text_titlecase",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(str)","  local buf = {}","  local inWord = false","  for i = 1, #str do","    local c = string.sub(str, i, i)","    if inWord then","      table.insert(buf, string.lower(c))",'      if string.find(c, "%s") then',
                +"        inWord = false","      end","    else","      table.insert(buf, string.upper(c))","      inWord = true","    end","  end","  return table.concat(buf)","end"]));return[b+"("+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.text_trim=function(a){var b={LEFT:"^%s*(,-)",RIGHT:"(.-)%s*$",BOTH:"^%s*(.-)%s*$"}[a.getFieldValue("MODE")];return["string.gsub("+(Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''")+', "'+b+'", "%1")',Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.text_print=function(a){return"print("+(Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''")+")\n"};
                +Blockly.Lua.text_prompt_ext=function(a){var b=a.getField("TEXT")?Blockly.Lua.quote_(a.getFieldValue("TEXT")):Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''";b=Blockly.Lua.provideFunction_("text_prompt",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(msg)","  io.write(msg)","  io.flush()","  return io.read()","end"])+"("+b+")";"NUMBER"==a.getFieldValue("TYPE")&&(b="tonumber("+b+", 10)");return[b,Blockly.Lua.ORDER_HIGH]};Blockly.Lua.text_prompt=Blockly.Lua.text_prompt_ext;
                +Blockly.Lua.text_count=function(a){var b=Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''";a=Blockly.Lua.valueToCode(a,"SUB",Blockly.Lua.ORDER_NONE)||"''";return[Blockly.Lua.provideFunction_("text_count",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(haystack, needle)","  if #needle == 0 then","    return #haystack + 1","  end","  local i = 1","  local count = 0","  while true do","    i = string.find(haystack, needle, i, true)","    if i == nil then","      break","    end","    count = count + 1",
                +"    i = i + #needle","  end","  return count","end"])+"("+b+", "+a+")",Blockly.Lua.ORDER_HIGH]};
                +Blockly.Lua.text_replace=function(a){var b=Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_NONE)||"''",c=Blockly.Lua.valueToCode(a,"FROM",Blockly.Lua.ORDER_NONE)||"''";a=Blockly.Lua.valueToCode(a,"TO",Blockly.Lua.ORDER_NONE)||"''";return[Blockly.Lua.provideFunction_("text_replace",["function "+Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_+"(haystack, needle, replacement)","  local buf = {}","  local i = 1","  while i <= #haystack do","    if string.sub(haystack, i, i + #needle - 1) == needle then","      for j = 1, #replacement do",
                +"        table.insert(buf, string.sub(replacement, j, j))","      end","      i = i + #needle","    else","      table.insert(buf, string.sub(haystack, i, i))","      i = i + 1","    end","  end","  return table.concat(buf)","end"])+"("+b+", "+c+", "+a+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.text_reverse=function(a){return["string.reverse("+(Blockly.Lua.valueToCode(a,"TEXT",Blockly.Lua.ORDER_HIGH)||"''")+")",Blockly.Lua.ORDER_HIGH]};Blockly.Lua.variables={};Blockly.Lua.variables_get=function(a){return[Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),Blockly.Lua.ORDER_ATOMIC]};Blockly.Lua.variables_set=function(a){var b=Blockly.Lua.valueToCode(a,"VALUE",Blockly.Lua.ORDER_NONE)||"0";return Blockly.Lua.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" = "+b+"\n"};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/media/1x1.gif b/blockly/webif/static/blockly/media/1x1.gif
                new file mode 100644
                index 000000000..308551123
                Binary files /dev/null and b/blockly/webif/static/blockly/media/1x1.gif differ
                diff --git a/blockly/webif/static/blockly/media/click.mp3 b/blockly/webif/static/blockly/media/click.mp3
                new file mode 100644
                index 000000000..4534b0ddc
                Binary files /dev/null and b/blockly/webif/static/blockly/media/click.mp3 differ
                diff --git a/blockly/webif/static/blockly/media/click.ogg b/blockly/webif/static/blockly/media/click.ogg
                new file mode 100644
                index 000000000..e8ae42a61
                Binary files /dev/null and b/blockly/webif/static/blockly/media/click.ogg differ
                diff --git a/blockly/webif/static/blockly/media/click.wav b/blockly/webif/static/blockly/media/click.wav
                new file mode 100644
                index 000000000..41a50cd76
                Binary files /dev/null and b/blockly/webif/static/blockly/media/click.wav differ
                diff --git a/blockly/webif/static/blockly/media/delete.mp3 b/blockly/webif/static/blockly/media/delete.mp3
                new file mode 100644
                index 000000000..442bd9c1f
                Binary files /dev/null and b/blockly/webif/static/blockly/media/delete.mp3 differ
                diff --git a/blockly/webif/static/blockly/media/delete.ogg b/blockly/webif/static/blockly/media/delete.ogg
                new file mode 100644
                index 000000000..67f84ac19
                Binary files /dev/null and b/blockly/webif/static/blockly/media/delete.ogg differ
                diff --git a/blockly/webif/static/blockly/media/delete.wav b/blockly/webif/static/blockly/media/delete.wav
                new file mode 100644
                index 000000000..18debcf96
                Binary files /dev/null and b/blockly/webif/static/blockly/media/delete.wav differ
                diff --git a/blockly/webif/static/blockly/media/disconnect.mp3 b/blockly/webif/static/blockly/media/disconnect.mp3
                new file mode 100644
                index 000000000..8cfaff6c0
                Binary files /dev/null and b/blockly/webif/static/blockly/media/disconnect.mp3 differ
                diff --git a/blockly/webif/static/blockly/media/disconnect.ogg b/blockly/webif/static/blockly/media/disconnect.ogg
                new file mode 100644
                index 000000000..467b527b4
                Binary files /dev/null and b/blockly/webif/static/blockly/media/disconnect.ogg differ
                diff --git a/blockly/webif/static/blockly/media/disconnect.wav b/blockly/webif/static/blockly/media/disconnect.wav
                new file mode 100644
                index 000000000..af5c25447
                Binary files /dev/null and b/blockly/webif/static/blockly/media/disconnect.wav differ
                diff --git a/blockly/webif/static/blockly/media/handclosed.cur b/blockly/webif/static/blockly/media/handclosed.cur
                new file mode 100644
                index 000000000..4851755a1
                Binary files /dev/null and b/blockly/webif/static/blockly/media/handclosed.cur differ
                diff --git a/blockly/webif/static/blockly/media/handdelete.cur b/blockly/webif/static/blockly/media/handdelete.cur
                new file mode 100644
                index 000000000..170320fc2
                Binary files /dev/null and b/blockly/webif/static/blockly/media/handdelete.cur differ
                diff --git a/blockly/webif/static/blockly/media/handopen.cur b/blockly/webif/static/blockly/media/handopen.cur
                new file mode 100644
                index 000000000..da44588b2
                Binary files /dev/null and b/blockly/webif/static/blockly/media/handopen.cur differ
                diff --git a/blockly/webif/static/blockly/media/quote0.png b/blockly/webif/static/blockly/media/quote0.png
                new file mode 100644
                index 000000000..b2fd10f69
                Binary files /dev/null and b/blockly/webif/static/blockly/media/quote0.png differ
                diff --git a/blockly/webif/static/blockly/media/quote1.png b/blockly/webif/static/blockly/media/quote1.png
                new file mode 100644
                index 000000000..826583e0a
                Binary files /dev/null and b/blockly/webif/static/blockly/media/quote1.png differ
                diff --git a/blockly/webif/static/blockly/media/sprites.png b/blockly/webif/static/blockly/media/sprites.png
                new file mode 100644
                index 000000000..7f704a5f1
                Binary files /dev/null and b/blockly/webif/static/blockly/media/sprites.png differ
                diff --git a/blockly/webif/static/blockly/media/sprites.svg b/blockly/webif/static/blockly/media/sprites.svg
                new file mode 100644
                index 000000000..3f09ef3a4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/media/sprites.svg
                @@ -0,0 +1,74 @@
                +<?xml version="1.0" encoding="utf-8" standalone="no"?>
                +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="96px" height="124px">
                +  <style type="text/css">
                +#background {
                +  fill: none;
                +}
                +.arrows {
                +  fill: #000;
                +  stroke: none;
                +}
                +.selected>.arrows {
                +  fill: #fff;
                +}
                +.checkmark {
                +  fill: #000;
                +  font-family: sans-serif;
                +  font-size: 10pt;
                +  text-anchor: middle;
                +}
                +.trash {
                +  fill: #888;
                +}
                +.zoom {
                +  fill: none;
                +  stroke: #888;
                +  stroke-width: 2;
                +  stroke-linecap: round;
                +}
                +.zoom>.center {
                +  fill: #888;
                +  stroke-width: 0;
                +}
                +  </style>
                +  <rect id="background" width="96" height="124" x="0" y="0" />
                +
                +  <g>
                +    <path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
                +    <path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
                +    <path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
                +  </g>
                +  <g class="selected" transform="translate(0, 16)">
                +    <path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
                +    <path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
                +    <path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
                +  </g>
                +
                +  <text class="checkmark" x="55.5" y="28">&#10003;</text>
                +
                +  <g class="trash">
                +    <path d="M 2,41 v 6 h 42 v -6 h -10.5 l -3,-3 h -15 l -3,3 z" />
                +    <rect width="36" height="20" x="5" y="50" />
                +    <rect width="36" height="42" x="5" y="50" rx="4" ry="4" />
                +  </g>
                +
                +  <g class="zoom">
                +    <circle r="11.5" cx="16" cy="108" />
                +    <circle r="4.3" cx="16" cy="108" class="center" />
                +    <path d="m 28,108 h3" />
                +    <path d="m 1,108 h3" />
                +    <path d="m 16,120 v3" />
                +    <path d="m 16,93 v3" />
                +  </g>
                +
                +  <g class="zoom">
                +    <circle r="15" cx="48" cy="108" />
                +    <path d="m 48,101.6 v12.8" />
                +    <path d="m 41.6,108 h12.8" />
                +  </g>
                +
                +  <g class="zoom">
                +    <circle r="15" cx="80" cy="108" />
                +    <path d="m 73.6,108 h12.8" />
                +  </g>
                +</svg>
                diff --git a/blockly/webif/static/blockly/msg/js/ab.js b/blockly/webif/static/blockly/msg/js/ab.js
                new file mode 100644
                index 000000000..492f145b7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ab.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ab');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Иацҵатәуп ахцәажәара";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ишәыҧсах аҵакы";
                +Blockly.Msg["CLEAN_UP"] = "Иқәгатәуп аблокқәа";
                +Blockly.Msg["COLLAPSE_ALL"] = "Иеикәрҳәтәуп Аблокқәа";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Иеикәрҳәтәуп Аблокқәа";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "аҧштәы 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "аҧштәы 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "аҧштәы 1 ахәҭа";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "еилаҵатәуп";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ru.wikipedia.org/wiki/Аҧштәы";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Иалышәх аҧштәы";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "иарбанзаалакь аҧштәы";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Иалнахуеит аҧштәы машәыршақә";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "жәҩангәҧштәы";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "аиаҵәа";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "аҟаҧшь";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "аҧштәы аҟынтәи";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ацикл иҭыҵтәуп";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ииастәуп ацикл анаҩстәи ашьаҿахьы";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Иааннакылоит абри ацикл.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Агәҽанҵара:Ари аблок ахархәара амоуп ацикл аҩныҵҟа мацара.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for each item %1 in list %2";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "ацикл %1 ала %2 инаркны %3 рҟынӡа ашьаҿа %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Иацнаҵоит аҭагыазаашьа аблок \"акәзар\" ахь";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "акәымзар";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "акәымзар";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "акәзар";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Аҭагылазаашьа иашазар, инанагӡоит акомандақәа.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Аҭагылазаашьа иашазар, инанагӡоит актәи аблок акомандақәа. Акәымзар инанагӡоит аҩбатәи аблок акомандақәа.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://ru.wikipedia.org/wiki/Ацикл_(апрограммаркра)";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "инагӡатәуп";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "инагӡалатәуп %1 - нтә";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Инанагӡоит акомандақәа кырынтә";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "инагӡалатәуп акәымзар";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "инагӡалатәуп акәзар";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Аҭагылазаашьа мцнаҵы, инанагӡалоит акомандақәа.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Аҭагылазаашьа иашанаҵ, инанагӡалоит акомандақәа.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Ианыхтәуп аблокқәа (%1) зегьы?";
                +Blockly.Msg["DELETE_BLOCK"] = "Ианыхтәуп аблок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Ианыхтәуп аҽеиҭак '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Ианыхтәуп %1 блокк";
                +Blockly.Msg["DISABLE_BLOCK"] = "Иаҿыхтәуп Аблок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Акопиа ахыхтәуп";
                +Blockly.Msg["ENABLE_BLOCK"] = "Иаҿыхтәуп Аблокқәа";
                +Blockly.Msg["EXPAND_ALL"] = "Иаарҧштәуп Аблокқәа";
                +Blockly.Msg["EXPAND_BLOCK"] = "Иаарҧштәуп Аблокқәа";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputs";  // untranslated
                +Blockly.Msg["HELP"] = "Ацхыраара";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";  // untranslated
                +Blockly.Msg["IOS_CANCEL"] = "Аҟәыхра";
                +Blockly.Msg["IOS_ERROR"] = "Агха";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Аоператорқәа азин рыҭара";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "Аҭаларҭа";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Иацҵатәуп";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Иацҵатәуп аҽеиҭак";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Ианыхтәуп";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Ахьӡ аҧсахра";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Аҽеиҭак ахьӡ";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "иаҧцатәуп иҭацәу ахьӡынҵа";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "ахьӡынҵа";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Иацнаҵоит аелемент ахьӡынҵахьы";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "актәи";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "№ анҵәамнҭа аҟынтәи";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "игатәуп";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "аҵыхәтәантәи";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "иарбанзаалакь";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ианыхтәуп";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Иҳанаҭоит ахьӡынҵа актәи аелемент.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Иҳанаҭоит ахьӡынҵа аҵыхәтәантәи аелемент.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Иҳанаҭоит ахьӡынҵа иарбанзаалакь елементк.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Ианнахәуеит ахьӡынҵа актәи аелемент.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Ианнахәуеит ахьӡынҵа аҵыхәтәантәи аелемент.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Ианнахәуеит ахьӡынҵа иарбанзаалакь елементк.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "№ ала";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 - аҵыхәтәантәи аелемент.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 - актәи аелемент.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "ахьӡынҵа аҟны";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ҭацәуп";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Иҳанаҭоит аиаша, ахьӡынҵа ҭацәызар.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "аура %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Иҳанаҭоит ахьӡынҵа аура.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "=";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "ибжьаргылатәуп";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "иаҭатәуп";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "еиҵоу-еиҳауала";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "еиҳау-еиҵоуала";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "еилыҧшаатәуп %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Еилыҧшаатәуп ахьӡынҵа акопиа.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "ахыҧхьаӡаратәи";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "алфавитла";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "амц";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Иҳанаҭоит аҵакы аиаша ма амц";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "аиаша";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://ru.wikipedia.org/wiki/Аиҟарамра";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 акәӡам";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "акагьы";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Иҳанаҭоит акагьы";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "and";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ма";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "амц акәзар";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "аиаша акәзар";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ru.wikipedia.org/wiki/Арифметика";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Иҳанаҭоит ҩ-хыҧхьаӡарак реицҵалыҵ.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Иҳанаҭоит ҩ-хыҧхьаӡарак ршалыҵ.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Иҳанаҭоит ҩ-хыҧхьаӡарак реигырхалыҵ.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Иҳанаҭоит ҩ-хыҧхьаӡарак рышьҭыхлыҵ.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "иеизырҳатәуп %1 %2 рыла";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Иацнаҵоит ахыҧхьаӡара аҽеиҭак'%1' ахь.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ru.wikipedia.org/wiki/Аматематикатә_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Иҳанаҭооит аконстантақәа руак: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) ма ∞ (аҵыхәаҧҵәарадара).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ишоит ала";
                +Blockly.Msg["MATH_IS_EVEN"] = "еиҩшо";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "иҵоурам";
                +Blockly.Msg["MATH_IS_ODD"] = "еиҩымшо";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "иҵоуроу";
                +Blockly.Msg["MATH_IS_PRIME"] = "имариоу";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "аибга";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://ru.wikipedia.org/wiki/Ашара_цәынхала";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "ацәынха %1 : %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Иҳанаҭоит ацәынха ҩ-хыҧхьаӡарак ршараан.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ru.wikipedia.org/wiki/Ахыҧхьаӡара";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Ахыҧхьаӡара.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "ахьӡынҵа арифметикатә бжьара";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "ахьӡынҵа аҟны иреиҳау";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "ахьӡынҵа амедиана";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "ахьӡынҵа аҟны иреиҵо";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "ахьӡынҵа амода";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "ахьӡынҵа иарбанзаалакь аелемент";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "ахьӡынҵа аицҵалыҵ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Иҳанаҭоит ахьӡынҵа аҟны ахыҧхьаӡарақәа зегьы рарифметикатә бжьара.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Иҳанаҭоит ахьӡынҵа аҟны иреиҳау ахыҧхьаӡара.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Иҳанаҭоит ахьӡынҵа аҟны ахыҧхьаӡарақәа зегьы рмедиана.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Иҳанаҭоит ахьӡынҵа аҟны иреицо ахыҧхьаӡара.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Иҳанаҭоит ахьӡынҵа аҟны иарбанзаалакь елементк.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Иҳанаҭоит ахьӡынҵа иаҵанакуа ахыҧхьаӡарақәа зегьы реицҵалыҵ.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "иарбанзаалакь ахыҧхьашара 0 инаркны (иалаҵаны)  1 аҟынӡа";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "иарбанзаалакь еибгоу ахыҧхьаӡара %1 инаркны %2 нӡа";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ru.wikipedia.org/wiki/Ахыркәшара";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ихыркәшатәуп";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ихыркәшатәуп еиҵоу ахь";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ихыркәшатәуп еиҳау ахь";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "амодуль";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Иҳанаҭоит ахыҧхьаӡара амодуль.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Иҳанаҭоит ахыҧхьаӡара иҧсабаратәу алагорифм.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Иҳанаҭоит ахыҧхьаӡара ажәабатә логари̓фм";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Иҳанаҭоит иаҿагыло ахыҧхьаӡара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ru.wikipedia.org/wiki/Атригонометриатә_функциақәа";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Иҳанаҭоит арккосинус градусла.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Иҳанаҭоит арксинус градусла.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Иҳанаҭоит арктангенс градусла.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Иҳанаҭоит акосинус градусла.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Иҳанаҭоит асинус градусла.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Иҳанаҭоит атангенс градусла.";
                +Blockly.Msg["NEW_VARIABLE"] = "Иаҧҵатәуп аҽеиҭак";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Аҽеиҭак ахьӡ ҿыц:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "Аоператорқәа азин рыҭара";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ru.wikipedia.org/wiki/Ацхыраагӡатә программа";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ru.wikipedia.org/wiki/Ацхыраагӡатә программа";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Абри афункциа ахҳәа азыҟашәҵа...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "иҟаҵатәуп џьара акы";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "азы";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "ирхынҳәтәуп";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "апараметр ахьӡ:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "апараметрқәа";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Аиҭаҟаҵара";
                +Blockly.Msg["REMOVE_COMMENT"] = "Ианыхтәуп ахцәажәара";
                +Blockly.Msg["RENAME_VARIABLE"] = "Аҽеиҭак ахьӡ ҧсахтәуп";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";  // untranslated
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "%1 ахьы иацҵатәуп атеқст %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Иацҵатәуп атеқст аҽеиҭак «%1» ахь.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "игатәуп актәи анбан";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "игатәуп анбан №";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "игатәуп аҵыхәтәантәи анбан";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "игатәуп иарбанзаалакь нбанк";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "атеқст %1 %2 аҟны";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Иацҵатәуп аелемент атеқст ахь.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "иеиҧшьтәуп";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "атеқст аҟны";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "атеқст %1 %2 %3 аҟны";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ҭацәуп";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "аура %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "икьыҧхьтәуп %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ru.wikipedia.org/wiki/Ацәаҳәатә_хкы";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Анбан, ажәа ма ацәаҳәа атеқст аҟны.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Иахьа";
                +Blockly.Msg["UNDO"] = "Иаҟәыхтәуп";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "аелемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Иҳанаҭоит аҽеиҭак аҵакы.";
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ar.js b/blockly/webif/static/blockly/msg/js/ar.js
                new file mode 100644
                index 000000000..01e491d6e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ar.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ar');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "أضف تعليقًا";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "تغيير قيمة:";
                +Blockly.Msg["CLEAN_UP"] = "ترتيب القطع";
                +Blockly.Msg["COLLAPSE_ALL"] = "إخفاء القطع";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "إخفاء القطعة";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "اللون 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "اللون 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "نسبة";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "دمج";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "دمج لونين ببعضهما البعض بنسبة (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ar.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "اختر لون من اللوحة.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "لون عشوائي";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "اختر لون بشكل عشوائي.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "أزرق";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "أخضر";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "أحمر";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "لون مع";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "إنشئ لون بالكمية المحددة من الأحمر, الأخضر والأزرق. بحيث يجب تكون كافة القيم بين 0 و 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "اخرج من الحلقة";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "استمر ابتداءا من التكرار التالي من الحلقة";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "اخرج من الحلقة الحالية.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "تخط ما تبقى من هذه الحلقة، واستمر ابتداءا من التكرار التالي.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "تحذير: يمكن استخدام هذه القطعة فقط داخل حلقة.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "لكل عنصر %1 في قائمة %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "لكل عنصر في قائمة ما، عين المتغير '%1' لهذا الغنصر، ومن ثم نفذ بعض الأوامر.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "عد بـ %1 من %2 إلى %3 بمعدل %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "اجعل المتغير  %1 يأخذ القيم من رقم البداية الى رقم النهاية، وقم بالعد داخل المجال المحدد، وطبق أوامر القطع المحددة.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "إضف شرطا إلى القطعة الشرطية \"إذا\".";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "أضف شرط \"نهاية، إجمع\" إلى القطعة الشرطية \"إذا\".";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "أضف, إزل, أو أعد ترتيب المقاطع لإعادة تكوين القطعة الشرطية \"إذا\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "والا";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "وإﻻ إذا";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "إذا";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "إذا كانت قيمة ما تساوي صحيح, إذن قم بتنفيذ أمر ما.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "إذا كانت قيمة ما تساوي \"صحيح\"، إذن قم بتنفيذ أول قطعة من الأوامر. والا ،قم بتنفيذ القطعة الثانية من الأوامر.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "إذا كانت القيمة الأولى تساوي \"صحيح\", إذن قم بتنفيذ القطعة الأولى من الأوامر. والا, إذا كانت القيمة الثانية تساوي \"صحيح\", قم بتنفيذ القطعة الثانية من الأوامر.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "إذا كانت القيمة الأولى تساوي \"صحيح\", إذن قم بتنفيذ القطعة الأولى من الأوامر. والا , إذا كانت القيمة الثانية تساوي \"صحيح\", قم بتنفيذ القطعة الثانية من الأوامر. إذا لم تكن هناك أي قيمة تساوي صحيح, قم بتنفيذ آخر قطعة من الأوامر.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "نفّذ";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "كرر  %1 مرات";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "نفّذ بعض الأوامر عدة مرات.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "اكرّر حتى";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "اكرّر طالما";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "بما ان القيمة خاطئة, نفّذ بعض الأوامر.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "بما ان القيمة صحيحة, نفّذ بعض الأوامر.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "حذف %1 قطعة؟";
                +Blockly.Msg["DELETE_BLOCK"] = "احذف القطعة";
                +Blockly.Msg["DELETE_VARIABLE"] = "حذف المتغير %1";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "حذف%1 1 استخدامات المتغير '%2'؟";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "احذف %1 قطع";
                +Blockly.Msg["DISABLE_BLOCK"] = "عطّل القطعة";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "مكرر";
                +Blockly.Msg["ENABLE_BLOCK"] = "أعد تفعيل القطعة";
                +Blockly.Msg["EXPAND_ALL"] = "وسٌّع القطع";
                +Blockly.Msg["EXPAND_BLOCK"] = "وسٌّع القطعة";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ادخال خارجي";
                +Blockly.Msg["HELP"] = "مساعدة";
                +Blockly.Msg["INLINE_INPUTS"] = "ادخال خطي";
                +Blockly.Msg["IOS_CANCEL"] = "ألغِ";
                +Blockly.Msg["IOS_ERROR"] = "خطأ";
                +Blockly.Msg["IOS_OK"] = "أوافق";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "أضف";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "احذف";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "لا يمكنك استخدام اسم متغير فارغ.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "أعد التسمية";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "اسم المتغير";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "إنشئ قائمة فارغة";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "تقوم بإرجاع قائمة، طولها 0, لا تحتوي على أية سجلات البيانات";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "قائمة";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "أضف, إزل, أو أعد ترتيب المقاطع لإعادة تكوين القطعة قائمة القطع التالية.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "أتشئ قائمة مع";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "أضف عنصرا إلى القائمة.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "أنشيء قائمة من أي عدد من العناصر.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "أول";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# من نهاية";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "احصل على";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "احصل على و ازل";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "أخير";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "عشوائي";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ازل";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "يرجع العنصر الأول في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "يقوم بإرجاع العنصر في الموضع المحدد في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "يرجع العنصر الأخير في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "يرجع عنصرا عشوائيا في قائمة.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "يزيل ويرجع العنصر الأول في قائمة.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "يزيل ويقوم بإرجاع العنصر في الموضع المحدد في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "يزيل ويرجع العنصر الأخير في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "يزيل و يرجع عنصرا عشوائيا في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "يزيل العنصر الأول في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "يزيل العنصر الموجود في الموضع المحدد في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "يزيل العنصر الأخير في قائمة ما.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "يزيل عنصرا عشوائيا في قائمة ما.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "إلى # من نهاية";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "إلى #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "إلى الأخير";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "احصل على قائمة فرعية من الأول";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "احصل  على قائمة فرعية من # من نهاية";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "احصل على قائمة فرعية من #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "يقوم بإنشاء نسخة من الجزء المحدد من قائمة ما.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 هو العنصر الأخير.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 هو العنصر الأول.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "ابحث على على التواجد الأول للعنصر";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "ابحث على التواجد الأخير للعنصر";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "تقوم بإرجاع مؤشر التواجد  الأول/الأخير في القائمة.  تقوم بإرجاع %1 إذا لم يتم العثور على النص.";
                +Blockly.Msg["LISTS_INLIST"] = "في قائمة";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 فارغ";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "يرجع \"صحيح\" إذا كانت القائمة فارغة.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "الطول من %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "تقوم بإرجاع طول قائمة.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "إنشئ قائمة مع العنصر  %1 %2 مرات";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "انشئ قائمة تتألف من القيمة المعطاة متكررة لعدد محدد من المرات.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "مثل";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "أدخل في";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "تعيين";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "يقوم بإدراج هذا العنصر في بداية قائمة.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "يقوم بإدخال العنصر في الموضع المحدد في قائمة ما.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "ألصق هذا العنصر بنهاية قائمة.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "ادخل العنصر عشوائياً في القائمة.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "يحدد العنصر الأول في قائمة.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "يحدد العنصر في الموضع المحدد في قائمة ما.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "يحدد العنصر الأخير في قائمة.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "يحدد عنصرا عشوائيا في قائمة.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "تصاعديا";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "تنازليا";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "رتب %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "فرز نسخة من القائمة.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "أبجديا، وتجاهل الحالة";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "رقمي";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "أبجديًا";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "إعداد قائمة من النصوص";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "إعداد نص من القائمة";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "ضم قائمة النصوص في نص واحد، مفصولة بواسطة محدد.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "تقسيم النص إلى قائمة من النصوص، وكسر في كل محدد";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "مع محدد";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "خاطئ";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "يرجع صحيح أو خاطئ.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "صحيح";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "يرجع صحيح إذا كان كلا المدخلات مساوية بعضها البعض.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "يرجع صحيح إذا كان الإدخال الأول أكبر من الإدخال الثاني.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "يرجع صحيح إذا كان الإدخال الأول أكبر من أو يساوي الإدخال الثاني.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "يرجع صحيح إذا كان الإدخال الأول أصغر من الإدخال الثاني.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "يرجع صحيح إذا كان الإدخال الأول أصغر من أو يساوي الإدخال الثاني.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "يرجع صحيح إذا كانت كلا المدخلات غير مساوية لبعضها البعض.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ليس %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "يرجع صحيح إذا كان الإدخال خاطئ .  يرجع خاطئ إذا كان الإدخال صحيح.";
                +Blockly.Msg["LOGIC_NULL"] = "فارغ";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "ترجع ملغى.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "و";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "أو";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "ترجع صحيح إذا كان كلا المٌدخلات صحيح.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "ترجع صحيح إذا كان واحد على الأقل من المدخلات صحيح.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "اختبار";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "إذا كانت العبارة خاطئة";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "إذا كانت العبارة صحيحة";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "تحقق الشرط في 'الاختبار'. إذا كان الشرط صحيح، يقوم بإرجاع قيمة 'اذا كانت العبارة صحيحة'؛ خلاف ذلك يرجع قيمة 'اذا كانت العبارة خاطئة'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ar.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8%D9%8A%D8%A7%D8%AA";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "يرجع مجموع الرقمين.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "يرجع حاصل قسمة الرقمين.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "يرجع الفرق بين الرقمين.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "يرجع حاصل ضرب الرقمين.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "يرجع الرقم الأول مرفوع إلى تربيع الرقم الثاني.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "غير %1 بـ %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "إضف رقم إلى متغير '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "ير جع واحد من الثوابت الشائعة : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "تقيد %1 منخفض %2 مرتفع %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "تقييد العددليكون بين الحدود المحددة (ضمناً).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "قابل للقسمة";
                +Blockly.Msg["MATH_IS_EVEN"] = "هو زوجي";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "هو سالب";
                +Blockly.Msg["MATH_IS_ODD"] = "هو فرذي";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "هو موجب";
                +Blockly.Msg["MATH_IS_PRIME"] = "هو أولي";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "تحقق إذا كان عدد ما زوجيا، فرذيا, أوليا، صحيحا،موجبا أو سالبا، أو إذا كان قابلا للقسمة على عدد معين.  يرجع صحيح أو خاطئ.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "هو صحيح";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "باقي %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "يرجع الباقي من قسمة الرقمين.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ar.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "عدد ما.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "متوسط القائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "الحد الأقصى لقائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "متوسط القائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "الحد الأدنى من قائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "منوال القائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "عنصر عشوائي من القائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "الانحراف المعياري للقائمة";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "مجموع القائمة";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "يرجع المعدل (الوسط الحسابي) للقيم الرقمية في القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "يرجع أكبر عدد في القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "يرجع وسيط العدد في القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "يرجع أصغر رقم في القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "يرجع قائمة من العنصر أو العناصر الأكثر شيوعاً في القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "يرجع عنصر عشوائي من القائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "يرجع الانحراف المعياري للقائمة.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "يرجع مجموع كافة الأرقام الموجودة في القائمة.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "كسر عشوائي";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "يرجع جزء عشوائي بين 0.0 (ضمنياً) و 1.0 (خارجيا).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = " عدد صحيح عشوائي من %1 إلى %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "يرجع عدد صحيح عشوائي بين حدين محددين, ضمنيا.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "تقريب";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "تقريب إلى اصغر عدد صحيح";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "تقريب الى اكبر عدد صحيح";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "تقريب الى اكبر عدد صحيح أو الى اصغر عدد صحيح.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ar.wikipedia.org/wiki/%D8%AC%D8%B0%D8%B1_%D8%AA%D8%B1%D8%A8%D9%8A%D8%B9%D9%8A";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "مطلق";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "الجذر التربيعي";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "يرجع القيمة المطلقة لرقم.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "يرجع ه‍ (e) مرفوعا لأس بقيمة الرقم المدخل.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "يرجع اللوغاريتم الطبيعي لرقم.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "يرجع لوغاريتم عدد معين للاساس 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "يرجع عدد سالب.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "يرجع مضروب الرقم 10 في نفسه .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "يرجع الجذر التربيعي للرقم.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "جيب تمام";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "جيب";
                +Blockly.Msg["MATH_TRIG_TAN"] = "ظل";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "يرجع قوس جيب التمام لرقم.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "يرجع قوس الجيب للرقم.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "يرجع قوس الظل للرقم.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "يرجع جيب التمام لدرجة (لا زواية نصف قطرية).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "يرجع جيب التمام لدرجة (لا زواية نصف قطرية).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "يرجع الظل لدرجة (لا دائرة نصف قطرية).";
                +Blockly.Msg["NEW_VARIABLE"] = "إنشاء متغير...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "اسم المتغير الجديد:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "اسمح بالبيانات";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "مع:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "تشغيل الدالة المعرفة من قبل المستخدم '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "تشغيل الدالة المعرفة من قبل المستخدم %1 واستخدام  مخرجاتها.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "مع:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "إنشئ '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "صف هذه الوظيفة...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "القيام بشيء ما";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "إلى";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "انشئ دالة بدون مخرجات .";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "يرجع";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "انشئ دالة مع المخرجات.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "تحذير: هذه الدالة تحتوي على معلمات مكررة.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "تسليط الضوء على تعريف الدالة";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "إذا كانت القيمة صحيحة ، اذان قم بارجاع القيمة الثانية.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "تحذير:هذه القطعة تستخدم فقط داخل تعريف دالة.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "اسم الإدخال:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "أضف مدخلا إلى الوظيفة.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "المدخلات";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "إضافة أو إزالة أو إعادة ترتيب المدخلات لهذه المهمة.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "إعادة";
                +Blockly.Msg["REMOVE_COMMENT"] = "أزل التعليق";
                +Blockly.Msg["RENAME_VARIABLE"] = "إعادة تسمية المتغير...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "إعادة تسمية كافة المتغيرات '%1' إلى:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "إلصق جزءا من النص إلى متغير '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "الى حروف صغيرة";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "الى حروف العنوان";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "الى حروف كبيرة";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "يرجع نسخة من النص في حالة مختلفة.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "احصل على الحرف الأول";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "الحصول على الحرف # من نهاية";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "الحصول على الحرف #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "احصل على آخر حرف";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "الحصول على حرف عشوائي";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "يرجع حرف ما في الموضع المحدد.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "إضف عنصر إلى النص.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "الانضمام إلى";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "أضف, إحذف, أو أعد ترتيب المقاطع لإعادة تكوين النص من القطع التالية.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "إلى حرف # من نهاية";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "إلى حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "إلى آخر حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "في النص";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "الحصول على سلسلة فرعية من الحرف الأول";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "الحصول على سلسلة حروف فرعية من الحرف # من نهاية";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "الحصول على سلسلة حروف فرعية من الحرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "يرجع جزء معين من النص.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "ابحث عن التواجد الأول للنص";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "ابحث عن التواجد الأخير للنص";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "تقوم بإرجاع مؤشر التواجد الأول/الأخير للنص الأول في النص الثاني.  تقوم بإرجاع %1 إذا لم يتم العثور على النص.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 فارغ";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "يرجع \"صحيح\" إذا كان النص المقدم فارغ.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "انشئ نص مع";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "أنشئ جزء من النص بالصاق أي عدد من العناصر ببعضها البعض.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "تقوم بإرجاع عدد الاحرف (بما في ذلك الفراغات) في النص المقدم.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "اطبع %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "اطبع النص المحدد أو العدد أو قيمة أخرى.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "انتظر ادخال المستخذم لرقم ما.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "انتظر ادخال المستخدم لنص ما.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "انتظر ادخال المستخدم لرقم ما مع اظهار رسالة";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "انتظر ادخال المستخدم لنص ما مع اظهار رسالة";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "يعكس ترتيب حروف النص";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "حرف أو كلمة أو سطر من النص.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "إزالة الفراغات من كلا الجانبين";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "إزالة الفراغات من الجانب الأيسر من";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "إزالة الفراغات من الجانب الأيمن من";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "يرجع نسخة من النص مع حذف من أحد أو كلا الفراغات من أطرافه.";
                +Blockly.Msg["TODAY"] = "اليوم";
                +Blockly.Msg["UNDO"] = "رجوع";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "البند";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "انشئ 'التعيين %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "يرجع قيمة هذا المتغير.";
                +Blockly.Msg["VARIABLES_SET"] = "تعيين %1 إلى %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "انشئ 'احصل على %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "تعيين هذا المتغير لتكون مساوية للقيمة المدخلة.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "المتغير '%1' موجود بالفعل";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/az.js b/blockly/webif/static/blockly/msg/js/az.js
                new file mode 100644
                index 000000000..83f670d55
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/az.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.az');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Şərh əlavə et";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Qiyməti dəyiş:";
                +Blockly.Msg["CLEAN_UP"] = "Blokları təmizlə";
                +Blockly.Msg["COLLAPSE_ALL"] = "Blokları yığ";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Bloku yığ";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "rəng 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "rəng 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "nisbət";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "qarışdır";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "İki rəngi verilmiş nisbətdə (0,0 - 1,0) qarışdırır.";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://az.wikipedia.org/wiki/Rəng";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Palitradan bir rəng seçin.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "təsadüfi rəng";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Təsadüfi bir rəng seçin.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "mavi";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "yaşıl";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "qırmızı";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "rənglə";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Qırmızı, yaşıl və mavinin göstərilən miqdarı ilə bir rəng düzəlt. Bütün qiymətlər 0 ilə 100 arasında olmalıdır.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "dövrdən çıx";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "dövrün növbəti addımından davam et";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Cari dövrdən çıx.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Bu dövrün qalanını ötür və növbəti addımla davam et.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Xəbərdarlıq: Bu blok ancaq dövr daxilində istifadə oluna bilər.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "hər element üçün %1 siyahıda %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Siyahıdakı hər element üçün \"%1\" dəyişənini elementə mənimsət və bundan sonra bəzi əmrləri yerinə yetir.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "say: %1 %2 ilə başlayıb, %3 qiymətinə kimi %4 qədər dəyiş";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "\"%1\" dəyişəni başlanğıc ədəddən son ədədə qədər göstərilən aralıqla qiymətlər aldıqca göstərilən blokları yerinə yetir.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "\"Əgər\" blokuna bir şərt əlavə et.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "\"Əgər\" blokuna qalan bütün halları əhatə edəb son bir şərt əlavə et.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Bu \"əgər\" blokunu dəyişdirmək üçün bölümlərin yenisini əlavə et, sil və ya yerini dəyiş.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "əks halda";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "əks halda əgər";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "əgər";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Əgər qiymət doğrudursa, onda bəzi əmrləri yerinə yetir.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Əgər qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda isə ikinci əmrlər blokunu yerinə yetir.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Əgər birinci qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda əgər ikinci qiymət doğrudursa, onda ikinci əmrlər blokunu yerinə yetir.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Əgər birinci qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda əgər ikinci qiymət doğrudursa, onda ikinci əmrlər blokunu yerinə yetir. Əgər qiymətlərdən heç biri doğru deyilsə, onda axırıncı əmrlər blokunu yerinə yetir.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://az.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "icra et";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 dəfə təkrar et";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Bəzi əmrləri bir neçə dəfə yerinə yetir.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "təkrar et, ta ki";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "təkrar et, hələ ki";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Hələ ki, qiymət \"yalan\"dır, bəzi əmrləri yerinə yetir.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Hələ ki, qiymət \"doğru\"dur, bəzi əmrləri yerinə yetir.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Bütün %1 blok silinsin?";
                +Blockly.Msg["DELETE_BLOCK"] = "Bloku sil";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 bloku sil";
                +Blockly.Msg["DISABLE_BLOCK"] = "Bloku söndür";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Dublikat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Bloku aktivləşdir";
                +Blockly.Msg["EXPAND_ALL"] = "Blokları aç";
                +Blockly.Msg["EXPAND_BLOCK"] = "Bloku aç";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Xarici girişlər";
                +Blockly.Msg["HELP"] = "Kömək";
                +Blockly.Msg["INLINE_INPUTS"] = "Sətiriçi girişlər";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "boş siyahı düzəlt";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Heç bir verilən qeyd olunmamış, uzunluğu 0 olan bir siyahı verir";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "siyahı";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Bu siyahı blokunu yenidən konfigurasiya etmək üçün bölmələri əlavə edin, silin və ya yerlərini dəyişin.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "bunlardan siyahı düzəlt";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Siyahıya element əlavə edin.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "İstənilən ölçülü siyahı yaradın.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "birinci";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "axırdan # nömrəli";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "götür";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "götür və sil";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "axırıncı";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "təsadüfi";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "yığışdır";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Siyahının ilk elementini qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Siyahıdan təyin olunmuş indeksli elementi qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Siyahının son elementini qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Siyahıdan hər hansı təsadüfi elementi qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Siyahıdan ilk elementi silir və qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Siyahıdan təyin olunmuş indeksli elementi silir və qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Siyahıdan son elementi silir və qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Siyahıdan təsadufi elementi silir və qaytarır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Siyahıdan ilk elementi silir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Siyahıdan təyin olunmuş indeksli elementi silir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Siyahıdan son elementi silir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Siyahıdan təsadüfi bir elementi silir.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "sondan # nömrəliyə";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "# nömrəliyə";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "Sonuncuya";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "Birincidən alt-siyahını alın";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "# sonuncudan alt-siyahını alın";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "# - dən alt-siyahını alın";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Siyahının təyin olunmuş hissəsinin surətini yaradın.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 son elementdir.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ilk elementdir.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Element ilə ilk rastlaşma indeksini müəyyən edin";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "Element ilə son rastlaşma indeksini müəyyən edin";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Siyahıda element ilə ilk/son rastlaşma indeksini qaytarır. Əgər tekst siyahıda tapılmazsa, %1 qaytarılır.";
                +Blockly.Msg["LISTS_INLIST"] = "siyahıda";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 boşdur";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Siyahı boşdursa \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 siyahısının uzunluğu";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Siyahının uzunluğunu verir.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "%1 elementinin %2 dəfə təkrarlandığı siyahı düzəlt";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Təyin olunmuş elementin/qiymətin təyin olunmuş sayda təkrarlandığı siyahını yaradır.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "Kimi";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "daxil et";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "təyin et";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Elementi siyahının əvvəlinə daxil edir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Elementi siyahıda göstərilən yerə daxil edir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Elementi siyahının sonuna artırır.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Elementi siyahıda təsadüfi seçilmiş bir yerə atır.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Siyahıda birinci elementi təyin edir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Siyahının göstərilən yerdəki elementini təyin edir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Siyahının sonuncu elementini təyin edir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Siyahının təsadüfi seçilmiş bir elementini təyin edir.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "səhf";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "\"doğru\" və ya \"səhf\" cavanını qaytarır.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "doğru";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://az.wikipedia.org/wiki/bərabərsizlik_(riyazi)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Girişlər bir birinə bərabərdirsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Birinci giriş ikincidən böyükdürsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Birinci giriş ikincidən böyük və ya bərarbərdirsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Birinci giriş ikincidən kiçikdirsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Birinci giriş ikincidən kiçik və ya bərarbərdirsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Girişlər bərabər deyillərsə \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 deyil";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Giriş \"yalan\"-dursa \"doğru\" cavabını qaytarır. Giriş \"doğru\"-dursa \"səhf\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_NULL"] = "boş";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Boş cavab qaytarır.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "və";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "və ya";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Hər iki giriş \"doğru\"-dursa \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Girişlərdən heç olmasa biri \"doğru\"-dursa \"doğru\" cavabını qaytarır.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "əgər səhfdirsə";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "əgər doğrudursa";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'Yoxla' əmrindəki şərtə nəzər yetirin. Əgər şərt \"doğru\"-dursa \"əgər doğru\", əks halda isə \"əgər yalan\" cavabını qaytarır.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://az.wikipedia.org/wiki/Hesab";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "İki ədədin cəmini qaytarır.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "İki ədədin nisbətini qaytarır.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "İki ədədin fərqini qaytarır.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "İki ədədin hasilini verir.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Birinci ədədin ikinci ədəd dərəcəsindən qüvvətini qaytarır.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "dəyiş: %1 buna: %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "'%1' dəyişəninin üzərinə bir ədəd artır.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://az.wikipedia.org/wiki/Riyazi_sabitlər";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Ümumi sabitlərdən birini qaytarır π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), və ya ∞ (sonsuzluq).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1 üçün ən aşağı %2, ən yuxarı %3 olmağı tələb et";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Bir ədədin verilmiş iki ədəd arasında olmasını tələb edir (sərhədlər də daxil olmaqla).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "bölünür";
                +Blockly.Msg["MATH_IS_EVEN"] = "cütdür";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "mənfidir";
                +Blockly.Msg["MATH_IS_ODD"] = "təkdir";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "müsətdir";
                +Blockly.Msg["MATH_IS_PRIME"] = "sadədir";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Bir ədədin cüt, tək, sadə, tam, müsbət, mənfi olmasını və ya müəyyən bir ədədə bölünməsini yoxlayır. \"Doğru\" və ya \"yalan\" qiymətini qaytarır.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "tamdır";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 bölməsinin qalığı";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "İki ədədin nisbətindən alınan qalığı qaytarır.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://az.wikipedia.org/wiki/Ədəd";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Ədəd.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "siyahının ədədi ortası";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "siyahının maksimumu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "siyahının medianı";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "siyahının minimumu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "Siyahı modları( Ən çox rastlaşılan elementləri)";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "siyahıdan təsadüfi seçilmiş bir element";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "Siyahının standart deviasiyası";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Siyahının cəmi";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Siyahıdaki ədədlərin ədədi ortasını qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Siyahıdaki ən böyük elementi qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Siyahının median elementini qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Siyahıdaki ən kiçik ədədi qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Siyahıdaki ən çox rastlanan element(lər)dən ibarət siyahı qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Siyahıdan təsadüfi bir element qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Siyahının standart deviasiyasını qaytarır.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Siyahıdakı bütün ədədlərin cəmini qaytarır.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "təsadüfi kəsr";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "0.0 (daxil olmaqla) və 1.0 (daxil olmamaqla) ədədlərinin arasından təsadüfi bir kəsr ədəd qaytarır.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "%1 ilə %2 arasından təsadüfi tam ədəd";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Verilmiş iki ədəd arasından (ədədrlər də daxil olmaqla) təsadüfi bir tam ədəd qaytarır.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "yuvarlaqlaşdır";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "aşağı yuvarlaqlaşdır";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "yuxarı yuvarlaqlaşdır";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Ədədi aşağı və ya yuxari yuvarlaqşdır.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://az.wikipedia.org/wiki/Kvadrat_kökləri";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "modul";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadrat kök";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Ədədin modulunu qaytarır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "e sabitinin verilmiş ədədə qüvvətini qaytarır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Ədədin natural loqarifmini tapır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Ədədin 10-cu dərəcədən loqarifmini tapır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Ədədin əksini qaytarır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "10-un verilmiş ədədə qüvvətini qaytarır.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Ədədin kvadrat kökünü qaytarır.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "arccos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://az.wikipedia.org/wiki/Triqonometrik_funksiyalar";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tg";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Ədədin arccosinusunu qaytarır.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Ədədin arcsinusunu qaytarır.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Ədədin arctanqensini qaytarır.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Dərəcənin kosinusunu qaytarır (radianın yox).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Dərəcənin sinusunu qaytar (radianın yox).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Dərəcənin tangensini qaytar (radianın yox).";
                +Blockly.Msg["NEW_VARIABLE"] = "Yeni dəyişən...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Yeni dəyişənin adı:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ilə:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Yaradılmış '%1' funksiyasını çalışdır.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Yaradılmış '%1' funksiyasını çalışdır və nəticəni istifadə et.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ilə:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' yarat";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "hansısa əməliyyat";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "icra et:";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Nəticəsi olmayan funksiya yaradır.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "qaytar";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Nəticəsi olan funksiya yaradır.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Xəbərdarlıq: Bu funksiyanın təkrar olunmuş parametrləri var.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Funksiyanın təyinatını vurğula";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Əgər bir dəyər \"doğru\"-dursa onda ikinci dəyəri qaytar.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Xəbərdarlıq: Bu blok ancaq bir funksiyanın təyinatı daxilində işlədilə bilər.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Giriş adı:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "girişlər";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Şərhi sil";
                +Blockly.Msg["RENAME_VARIABLE"] = "Dəyişənin adını dəyiş...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Bütün '%1' dəyişənlərinin adını buna dəyiş:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "'%1' dəyişəninin sonuna nəsə əlavə et.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "kiçik hərflərlə";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Baş Hərflərlə";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "BÖYÜK HƏRFLƏRLƏ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Mətndə hərflərin böyük-kiçikliyini dəyiş.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "birinci hərfi götür";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "axırdan bu nömrəli hərfi götür";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "bu nömrəli hərfi götür";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "axırıncı hərfi götür";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "təsadüfi hərf götür";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Göstərilən mövqedəki hərfi qaytarır.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Mətnə bir element əlavə et.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "birləşdir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Bu mətn blokunu yenidən konfigurasiya etmək üçün bölmələri əlavə edin, silin və ya yerlərini dəyişin.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "axırdan bu nömrəli hərfə qədər";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "bu nömrəli hərfə qədər";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "son hərfə qədər";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "mətndə";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "Mətnin surətini ilk hərfdən";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "Mətnin surətini sondan bu nömrəli # hərfdən";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "Mətnin surətini bu nömrəli hərfdən";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Mətnin təyin olunmuş hissəsini qaytarır.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "Bu mətn ilə ilk rastlaşmanı tap:";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "Bu mətn ilə son rastlaşmanı tap:";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Birinci mətnin ikinci mətndə ilk/son rastlaşma indeksini qaytarır. Əgər rastlaşma baş verməzsə, %1 qaytarır.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 boşdur";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Verilmiş mətn boşdursa, doğru qiymətini qaytarır.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "Verilmişlərlə mətn yarat";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "İxtiyari sayda elementlərinin birləşməsi ilə mətn parçası yarat.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 - ın uzunluğu";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Verilmiş mətndəki hərflərin(sözlər arası boşluqlar sayılmaqla) sayını qaytarır.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 - i çap elə";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Təyin olunmuş mətn, ədəd və ya hər hansı bir başqa elementi çap elə.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "İstifadəçiyə ədəd daxil etməsi üçün sorğu/tələb göndərin.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "İstifadəçiyə mətn daxil etməsi üçün sorğu/tələb göndərin.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "İstifadəçiyə ədəd daxil etməsi üçün sorğunu/tələbi ismarıc kimi göndərin";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "İstifadəçiyə mətn daxil etməsi üçün sorğunu/tələbi ismarıc ilə göndərin";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Mətndəki hərf, söz və ya sətir.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "Boşluqları hər iki tərəfdən pozun";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "Boşluqlari yalnız sol tərəfdən pozun";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "Boşluqları yalnız sağ tərəfdən pozun";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Mətnin hər iki və ya yalnız bir tərəfdən olan boşluqları pozulmuş surətini qaytarın.";
                +Blockly.Msg["TODAY"] = "Bugün";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'%1 - i təyin et' - i yarat";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Bu dəyişənin qiymətini qaytarır.";
                +Blockly.Msg["VARIABLES_SET"] = "%1 - i bu qiymət ilə təyin et: %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'%1 - i götür' - ü yarat";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Bu dəyişəni daxil edilmiş qiymətə bərabər edir.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ba.js b/blockly/webif/static/blockly/msg/js/ba.js
                new file mode 100644
                index 000000000..72822e51b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ba.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ba');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Фекер өҫтәргә";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Мәғәнәне үҙгәртегеҙ:";
                +Blockly.Msg["CLEAN_UP"] = "Блоктарҙы таҙартырға";
                +Blockly.Msg["COLLAPSE_ALL"] = "Блоктарҙы төрөргә";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Блокты төрөргә";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "1-се төҫ";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "2-се төҫ";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "1-се төҫтөң өлөшө";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "ҡатнаштырырға";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Ике төҫтө бирелгән нисбәттә болғата (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Төҫ";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Палитранан төҫ һайлағыҙ.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "осраҡлы төҫ";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Төҫтө осраҡлылыҡ буйынса һайлай.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "зәңгәр";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "йәшелдән";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ҡыҙылдан";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "ошонан төҫ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Бирелгән нисбәттәрҙә ҡыҙылдан, йәшелдән һәм зәңгәрҙән төҫ барлыҡҡа килә. Бөтә мәғәнәләр 0 менән 100 араһында булырға тейеш.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "циклдан сығырға";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "циклдың киләһе аҙымына күсергә";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Был циклды өҙә.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Циклдың ҡалдығын төшөрөп ҡалдыра һәм киләһе аҙымға күсә.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Иҫкәртеү: был блок цикл эсендә генә ҡулланыла ала.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "һәр элемент өсөн %1 исемлектә %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Исемлектәге һәр элемент өсөн үҙгәреүсәнгә элементтың '%1' мәғәнәһен бирә һәм күрһәтелгән командаларҙы үтәй.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Үҙгәреүсәнгә башынан аҙағына тиклем тәғәйен аҙым менән %1 мәғәнәне бирә һәм күрһәтелгән командаларҙы үтәй.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "\"Әгәр\" блогына шарт өҫтәй";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Бер шарт та дөрөҫ булмаған осраҡҡа йомғаҡлау ярҙамсы блогын өҫтәргә.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "\"Әгәр\" блогын ҡабаттан төҙөү өсөн киҫәктәрҙе өҫтәгеҙ, юйҙырығыҙ, урындарын алмаштырығыҙ.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "юғиһә";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "юғиһә, әгәр";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "әгәр";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Мәғәнә дөрөҫ булғанда, командаларҙы үтәй.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Шарт дөрөҫ булғанда, командаларҙың беренсе блогын үтәй. Улай булмаһа, командаларҙың икенсе блогы үтәлә.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Беренсе шарт дөрөҫ булһа, командаларҙың беренсе блогын үтәй. Икенсе шарт дөрөҫ булһа, командаларҙың икенсе блогын үтәй.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Беренсе шарт дөрөҫ булһа, командаларҙың беренсе блогын үтәй. Әгәр икенсе шарт дөрөҫ булһа, командаларҙың икенсе блогын үтәй. Бер шарт та дөрөҫ булмаһа, команда блоктарының һуңғыһын үтәй.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/Цикл_(программалау)";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "үтәргә";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = " %1 тапҡыр ҡабатларға";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Командаларҙы бер нисә тапҡыр үтәй.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ҡабатларға, әлегә юҡ";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ҡабатларға, әлегә";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Мәғәнә ялған булғанда, командаларҙы ҡабатлай.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Мәғәнә дөрөҫ булғанда, командаларҙы ҡабатлай.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Бөтә %1 блоктарҙы юйырғамы?";
                +Blockly.Msg["DELETE_BLOCK"] = "Блокты юйҙырырға";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = " %1 блокты юйҙырырға";
                +Blockly.Msg["DISABLE_BLOCK"] = "Блокты һүндерергә";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Күсереп алырға";
                +Blockly.Msg["ENABLE_BLOCK"] = "Блокты тоҡандырырға";
                +Blockly.Msg["EXPAND_ALL"] = "Блоктарҙы йәйергә";
                +Blockly.Msg["EXPAND_BLOCK"] = "Блокты йәйергә";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Тышҡы өҫтәлмә";
                +Blockly.Msg["HELP"] = "Ярҙам";
                +Blockly.Msg["INLINE_INPUTS"] = "Эске өҫтәлмә";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "исемлек";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "менән исемлек төҙөргә";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "беренсе";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# аҙағынан";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "алырға";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "алырға һәм юйырға";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "аҙаҡҡы";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "осраҡлы";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "юйырға";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "исемлеккә";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 буш";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "оҙонлоғо %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "кеүек";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "өҫтәп ҡуйырға";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "йыйылма";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ялған";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Дөрөҫ йәки ялғанды ҡайтара.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "дөрөҫ";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(математика)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Өҫтәмәләр тигеҙ булһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Беренсе өҫтәмә икенсеһенән ҙурыраҡ булһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Беренсе өҫтәмә икенсеһенән бәләкәйерәк йә уға тиң булһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Беренсе өҫтәмә икенсеһенән бәләкәйерәк булһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Беренсе өҫтәмә икенсеһенән бәләкәйерәк йә уға тиң булһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Өҫтәмәләр тигеҙ булмаһа, дөрөҫ мәғәнәһен кире ҡайтара.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 түгел";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Өҫтәлмә ялған булһа, дөрөҫ аңлатманы ҡайтара. Өҫтәлмә дөрөҫ булһа, ялған аңлатманы ҡайтара.";
                +Blockly.Msg["LOGIC_NULL"] = "нуль";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Нулде ҡайтара.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "һәм";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "йәки";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Әгәр ҙә ике өҫтәлмә лә тап килһә, дөрөҫ аңлатманы кире ҡайтара.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Өҫтәлмәләрҙең береһе генә дөрөҫ булһа, дөрөҫ аңлатманы ҡайтара.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "тест";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "әгәр ялған булһа";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "әгәр дөрөҫ булһа";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Һайлау шартын тикшерә. Әгәр ул дөрөҫ булһа, беренсе мәғәнәне, хата булһа, икенсе мәғәнәне ҡайтара.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ba.wikipedia.org/wiki/Арифметика";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Ике һандың суммаһын ҡайтара.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Ике һандың бүлендеген ҡайтара.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Ике һандың айырмаһын ҡайтара.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Ике һандың ҡабатландығын ҡайтара.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Дәрәжәгә күтәрелгән икенсе һандан тәүгеһенә ҡайтара.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://ba.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%1 тан %2 ҡа арттырырға";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Үҙгәреүсән һанға өҫтәй '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ba.wikipedia.org/wiki/Математик_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Таралған константаның береһен күрһәтә: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) йәки ∞ (сикһеҙлек).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "сикләргә %1 аҫтан %2 өҫтән %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Һанды аҫтан һәм өҫтән сикләй (сиктәгеләрен индереп).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "бүленә";
                +Blockly.Msg["MATH_IS_EVEN"] = "тағы";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "тиҫкәре";
                +Blockly.Msg["MATH_IS_ODD"] = "сәйер";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ыңғай";
                +Blockly.Msg["MATH_IS_PRIME"] = "ябай";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Һандың йоп, таҡ, ябай, бөтөн, ыңғай, кире йәки билдәле һанға ҡарата ниндәй булыуын тикшерә. Дөрөҫ йә ялған мәғәнәһен күрһәтә.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "бөтөн";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://ba.wikipedia.org/wiki/Ҡалдыҡ_менән_бүлеү";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "ҡалдыҡ %1 : %2 араһында";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Ике һанды бүлеү ҡалдығын күрһәтә.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ba.wikipedia.org/wiki/Һан";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Рәт.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "исемлектең уртаса арифметик дәүмәле";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "исемлектәге иң ҙуры";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "исемлек медианаһы";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Исемлектәге иң бәләкәйе";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "исемлек модалары";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "исемлектең осраҡлы элементы";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "исемлекте стандарт кире ҡағыу";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "исемлек суммаһы";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Исемлектең уртаса арифметик дәүмәле күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Исемлектең иң ҙур һанын  күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Исемлек медианаһын күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Исемлектәге иң бәләкәй һанды күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Исемлектең иң күп осраған элементтарын күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Исемлектең осраҡлы элементын күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Исемлекте стандарт кире ҡағыуҙы күрһәтә.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Исемлектәрҙәге һандар суммаһын күрһәтә.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://ba.wikipedia.org/wiki/Ялған осраҡлы_һандар_генераторы";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "0 (үҙен дә индереп) һәм 1 араһындағы осраҡлы һан";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://ba.wikipedia.org/wiki/Ялған осраҡлы_һандар_генераторы";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "%1-ҙән %2-гә тиклем осраҡлы бөтөн һан";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Ике бирелгән һан араһындағы (үҙҙәрен дә индереп) осраҡлы һанды күрһәтә.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ba.wikipedia.org/wiki/Т=Түңәрәкләү";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "түңәрәк";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "бәләкәйгә тиклем түңәрәкләргә";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ҙурына тиклем түңәрәкләргә";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Һанды ҙурына йә бәләкәйенә тиклем түңәрәкләргә.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ba.wikipedia.org/wiki/Квадрат_тамыр";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "абсолют";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "квадрат тамыр";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Һандың модулен ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Күрһәтелгән дәрәжәлә ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Һандың натураль логаритмын ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Һандың унынсы логаритмын ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Кире һанды ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Күрһәтелгән 10-сы дәрәжәлә ҡайтара.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Һандың квадрат тамырын ҡайтара.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ba..wikipedia.org/wiki/Тригонометрик_функциялар";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Арккосинусты градустарҙа күрһәтә.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Арксинусты градустарҙа күрһәтә.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Арктангенсты градустарҙа күрһәтә.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Мөйөштөң косинусын градустарҙа ҡайтара.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Мөйөштөң синусын градустарҙа ҡайтара.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Мөйөштөң тангенсын градустарҙа күрһәтә.";
                +Blockly.Msg["NEW_VARIABLE"] = "Яңы үҙгәреүсән...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Яңы үҙгәреүсәндең исеме:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' төҙөргә";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "кире ҡайтарыу";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "инеү исеме:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "инеү";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "документтарҙы үҙгәртергә";
                +Blockly.Msg["REMOVE_COMMENT"] = "Аңлатмаларҙы юйырға";
                +Blockly.Msg["RENAME_VARIABLE"] = "Үҙгәреүсәндең исемен алмаштырырға...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Бөтә '%1' үҙгәреүсәндәрҙең исемен ошолай алмаштырырға:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Үҙгәреүсән «%1»-гә текст өҫтәргә.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "тәүге хәрефте алырға";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "№ хәрефен аҙаҡтан алырға";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "хат алырға #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "һуңғы хәрефте алырға";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "осраҡлы хәрефте алырға";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Текстҡа элемент өҫтәү.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ҡушылығыҙ";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "# хатҡа";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "һуңғы хәрефкә тиклем";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "текста";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "текстың тәүге инеүен табырға";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "Текстың һуңғы инеүен табырға";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 буш";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "текст төҙөргә";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Элементтарҙың теләһә күпме һанын берләштереп текст фрагментын булдыра.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "оҙонлоғо %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Бирелгән текстағы символдар һанын (буш урындар менән бергә) кире ҡайтара.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 баҫтырырға";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Текстың хәрефе, һүҙе йәки юлы.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Бөгөн";
                +Blockly.Msg["UNDO"] = "Кире алырға";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "элемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/bcc.js b/blockly/webif/static/blockly/msg/js/bcc.js
                new file mode 100644
                index 000000000..337f146f2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/bcc.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.bcc');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "افزودن نظر";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "تغییر مقدار:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "فروپاشی بلوک‌ها";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "فروپاشی بلوک";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "رنگ ۱";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "رنگ ۲";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "نسبت";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "مخلوط";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%86%DA%AF";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "انتخاب یک رنگ از تخته‌رنگ.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "رنگ تصادفی";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "انتخاب یک رنگ به شکل تصادفی.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "آبی";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "سبز";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "قرمز";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "رنگ با";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ساخت یک رنگ با مقدار مشخص‌شده‌ای از قرمز، سبز و آبی. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "شکستن حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ادامه با تکرار بعدی حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "شکستن حلقهٔ شامل.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "برای هر مورد %1 در فهرست %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "با تعداد %1 از %2 به %3 با گام‌های %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "افزودن یک شرط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "اضافه‌کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "اضافه، حذف یا ترتیب‌سازی قسمت‌ها برای تنظیم مجدد این بلوک اگر مسدود است.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "آنگاه";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "اگر آنگاه";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "اگر";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AD%D9%84%D9%82%D9%87_%D9%81%D9%88%D8%B1";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "انجام";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 بار تکرار";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "انجام چند عبارت چندین بار.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "تکرار تا";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "تکرار در حالی که";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "حذف بلوک";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "حذف بلوک‌های %1";
                +Blockly.Msg["DISABLE_BLOCK"] = "غیرفعال‌سازی بلوک";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "تکراری";
                +Blockly.Msg["ENABLE_BLOCK"] = "فعال‌سازی بلوک";
                +Blockly.Msg["EXPAND_ALL"] = "گسترش بلوک‌ها";
                +Blockly.Msg["EXPAND_BLOCK"] = "گسترش بلوک";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ورودی‌های خارجی";
                +Blockly.Msg["HELP"] = "کومک";
                +Blockly.Msg["INLINE_INPUTS"] = "ورودی‌های درون خطی";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "ایجاد فهرست خالی";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "فهرست";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "اضافه‌کردن، حذف‌کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "ایجاد فهرست با";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "اضافه‌کردن یک مورد به فهرست.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "فهرستی از هر عددی از موارد می‌سازد.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "اولین";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# از انتها";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "گرفتن";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "گرفتن و حذف‌کردن";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "اهرین";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "تصادفی";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "حذف‌کردن";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "اولین مورد یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "موردی در محل مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "آخرین مورد در یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "یک مورد تصادفی در یک فهرست بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "اولین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "آخرین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "یک مورد تصادفی را یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "به # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "به #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "به آخرین";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "گرفتن زیرمجموعه‌ای از ابتدا";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "گرفتن زیرمجموعه‌ای از # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "گرفتن زیرمجموعه‌ای از #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 آخرین مورد است.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 اولین مورد است.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "آخرین رخداد متن را بیاب";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "یافتن آخرین رخ‌داد مورد";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر متن موجود نبود.";
                +Blockly.Msg["LISTS_INLIST"] = "در فهرست";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "طول یک فهرست را برمی‌گرداند.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "به‌عنوان";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "درج در";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "مجموعه";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "موردی به ته فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "موردی به ته فهرست الحاق می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "مورد را به صورت تصادفی در یک فهرست می‌افزاید.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "اولین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "آخرین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "یک مورد تصادفی در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ناصحیح";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "بازگرداندن یکی از صحیح یا ناصحیح.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "صحیح";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D9%86%D8%A7%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1%DB%8C";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "نه %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_NULL"] = "تهی";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "تهی بازمی‌گرداند.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "و";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "یا";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "آزمایش";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "اگر ناصحیح";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "اگر صحیح";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "بازگرداندن مقدار جمع دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "بازگرداندن باقی‌ماندهٔ دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "بازگرداندن تفاوت دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "بازگرداندن حاصلضرب دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%A7%D8%B5%D8%B7%D9%84%D8%A7%D8%AD_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C#.D8.A7.D9.81.D8.B2.D8.A7.DB.8C.D8.B4_.D8.B4.D9.85.D8.A7.D8.B1.D9.86.D8.AF.D9.87";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "تغییر %1 با %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "افزودن یک عدد به متغیر '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AB%D8%A7%D8%A8%D8%AA_%D8%B1%DB%8C%D8%A7%D8%B6%DB%8C";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "یکی از مقادیر مشترک را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "محدودکردن %1 پایین %2 بالا %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "تقسیم شده بر";
                +Blockly.Msg["MATH_IS_EVEN"] = "زوج است";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "منفی است";
                +Blockly.Msg["MATH_IS_ODD"] = "فرد است";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "مثبت است";
                +Blockly.Msg["MATH_IS_PRIME"] = "عدد اول است";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "کامل است";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B9%D9%85%D9%84%DB%8C%D8%A7%D8%AA_%D9%BE%DB%8C%D9%85%D8%A7%D9%86%D9%87";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "باقی‌ماندهٔ %1 + %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "یک عدد.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "میانگین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "بزرگ‌ترین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "میانهٔ فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "کوچکترین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "مد فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "مورد تصادفی از فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "انحراف معیار فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "جمع فهرست";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "میانهٔ عدد در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "کوچک‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "موردی تصادفی از فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "انحراف معیار فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "جمع همهٔ عددهای فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "کسر تصادفی";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "عدد صحیح تصادفی بین %1 تا %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "گردکردن";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "گرد به پایین";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "گرد به بالا";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "گردکردن یک عدد به بالا یا پایین.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%DB%8C%D8%B4%D9%87_%D8%AF%D9%88%D9%85";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "مطلق";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ریشهٔ دوم";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "قدر مطلق یک عدد را بازمی‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "بازگرداندن توان e یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "لوگاریتم طبیعی یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "منفی‌شدهٔ یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "بازگرداندن توان ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ریشهٔ دوم یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%D9%87%D8%A7%DB%8C_%D9%85%D8%AB%D9%84%D8%AB%D8%A7%D8%AA%DB%8C";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "بازگرداندن آرک‌کسینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "بازگرداندن آرک‌سینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "بازگرداندن آرک‌تانژانت درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "بازگرداندن کسینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "بازگرداندن سینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "بازگرداندن تانژانت یک درجه (نه رادیان).";
                +Blockly.Msg["NEW_VARIABLE"] = "متغیر تازه...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "نام متغیر تازه:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "اجازه اظهارات";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1».";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "ساختن «%1»";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "انجام چیزی";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "به";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "تابعی می‌سازد بدون هیچ خروجی.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "بازگشت";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "تابعی با یک خروجی می‌سازد.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "اخطار: این تابعی پارامتر تکراری دارد.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "برجسته‌سازی تعریف تابع";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "اگر یک مقدار صحیح است، مقدار دوم را برگردان.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "نام ورودی:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "اضافه کردن ورودی به تابع.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ورودی‌ها";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "حذف نظر";
                +Blockly.Msg["RENAME_VARIABLE"] = "تغییر نام متغیر...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "تغییر نام همهٔ متغیرهای «%1» به:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "الحاق متنی به متغیر «%1».";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "به حروف کوچک";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "به حروف بزرگ عنوان";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "به حروف بزرگ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "بازگرداندن کپی متن در حالتی متفاوت.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "گرفتن اولین حرف";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "گرفتن حرف # از آخر";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "گرفتن حرف #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "گرفتن آخرین حرف";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "گرفتن حرف تصادفی";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "حرفی در موقعیت مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "افزودن یک مورد به متن.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "عضویت";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "اضافه، حذف یا ترتیب‌سازی قسمت‌ها برای تنظیم مجدد این بلوک اگر مسدود است.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "به حرف # از انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "به حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "گرفتن آخرین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "در متن";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "گرفتن زیرمتن از اولین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "گرفتن زیرمتن از حرف # به انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "گرفتن زیرمتن از حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "اولین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "آخرین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "اضافه‌کردن صحیح اگر متن فراهم‌شده خالی است.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ایجاد متن با";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "چاپ %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "اعلان برای کاربر با یک عدد.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "اعلان برای کاربر برای یک متن.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "اعلان برای عدد با پیام";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "اعلان برای متن با پیام";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D8%B4%D8%AA%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "یک حرف، کلمه یا خطی از متن.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "تراشیدن فاصله‌ها از  هر دو طرف";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.";
                +Blockly.Msg["TODAY"] = "Today";  // untranslated
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "مورد";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "درست‌کردن «تنظیم %1»";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "مقدار این متغیر را بر می‌گرداند.";
                +Blockly.Msg["VARIABLES_SET"] = "مجموعه %1 به %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "درست‌کردن «تنظیم %1»";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "متغیر برابر با خروجی را مشخص می‌کند.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/be-tarask.js b/blockly/webif/static/blockly/msg/js/be-tarask.js
                new file mode 100644
                index 000000000..407847834
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/be-tarask.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.be.tarask');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Дадаць камэнтар";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Немагчыма выдаліць зьменную «%1», таму што яна зьяўляецца часткай вызначэньня функцыі «%2»";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Зьмяніць значэньне:";
                +Blockly.Msg["CLEAN_UP"] = "Ачысьціць блёкі";
                +Blockly.Msg["COLLAPSE_ALL"] = "Згарнуць блёкі";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Згарнуць блёк";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "колер 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "колер 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "дзеля";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "зьмяшаць";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Зьмешвае два колеры ў дадзенай прапорцыі (0.0 — 1.0)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BB%D0%B5%D1%80";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Абярыце колер з палітры.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "выпадковы колер";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Абраць выпадковы колер.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "сіняга";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зялёнага";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "чырвонага";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "колер з";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Стварыць колер з абранымі прапорцыямі чырвонага, зялёнага і сіняга. Усе значэньні павінны быць ад 0 да 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "перарваць цыкль";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "працягнуць з наступнага кроку цыклю";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Спыніць гэты цыкль.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Прапусьціць рэшту цыклю і перайсьці да наступнага кроку.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Увага: гэты блёк можа быць выкарыстаны толькі ў цыклі.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "для кожнага элемэнта %1 у сьпісе %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Для кожнага элемэнту сьпісу прысвойвае зьменнай '%1' ягонае значэньне і выконвае пэўныя апэрацыі.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "лічыць з %1 ад %2 да %3 па %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Прысвойвае зьменнай \"%1\" значэньні ад пачатковага да канчатковага значэньня, улічваючы зададзены крок, і выконвае абраныя блёкі.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Дадаць умову да блёку «калі».";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Дадаць заключную ўмову для ўсіх астатніх варыянтаў блёку «калі».";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Дадаць, выдаліць ці пераставіць сэкцыі для пераканфігураваньня гэтага блёку «калі».";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "інакш";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "інакш, калі";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "калі";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Калі значэньне ісьціна, выканаць пэўныя апэрацыі.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Калі значэньне ісьціна, выканаць першы блёк апэрацыяў, інакш выканаць другі блёк.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Калі першае значэньне ісьціна, выканаць першы блёк апэрацыяў. Інакш, калі другое значэньне ісьціна, выканаць другі блёк апэрацыяў.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Калі першае значэньне ісьціна, выканаць першы блёк апэрацыяў. Інакш, калі другое значэньне ісьціна, выканаць другі блёк апэрацыяў. Калі ніводнае з значэньняў не сапраўднае, выканаць апошні блёк апэрацыяў.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "выканаць";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "паўтарыць %1 раз(ы)";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Выконвае апэрацыі некалькі разоў.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "паўтараць, пакуль не";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "паўтараць, пакуль";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Пакуль значэньне хлусьня, выконваць пэўныя апэрацыі.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Пакуль значэньне ісьціна, выконваць пэўныя апэрацыі.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Выдаліць усе блёкі %1?";
                +Blockly.Msg["DELETE_BLOCK"] = "Выдаліць блёк";
                +Blockly.Msg["DELETE_VARIABLE"] = "Выдаліць зьменную «%1»";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Выдаліць %1 выкарыстаньняў зьменнай «%2»?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Выдаліць %1 блёкі";
                +Blockly.Msg["DISABLE_BLOCK"] = "Адключыць блёк";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Капіяваць";
                +Blockly.Msg["ENABLE_BLOCK"] = "Уключыць блёк";
                +Blockly.Msg["EXPAND_ALL"] = "Разгарнуць блёкі";
                +Blockly.Msg["EXPAND_BLOCK"] = "Разгарнуць блёк";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Зьнешнія ўваходы";
                +Blockly.Msg["HELP"] = "Дапамога";
                +Blockly.Msg["INLINE_INPUTS"] = "Унутраныя ўваходы";
                +Blockly.Msg["IOS_CANCEL"] = "Адмяніць";
                +Blockly.Msg["IOS_ERROR"] = "Памылка";
                +Blockly.Msg["IOS_OK"] = "Добра";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Дадаць уваходныя зьвесткі";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Дазволіць сьцьверджаньні";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Уваходныя зьвесткі гэтай функцыі дублююцца.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "УВАХОДНЫЯ ЗЬВЕСТКІ";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Дадаць";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Дадаць зьменную";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Выдаліць";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Вы ня можаце выкарыстоўваць пустую назву зьменнай.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Перайменаваць";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Назва зьменнай";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "стварыць пусты сьпіс";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Вяртае сьпіс даўжынёй 0, які ня ўтрымлівае запісаў зьвестак";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "сьпіс";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Дадаць, выдаліць ці пераставіць сэкцыі для пераканфігураваньня гэтага блёку.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "стварыць сьпіс з";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Дадаць элемэнт да сьпісу.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Ставарае сьпіс зь любой колькасьцю элемэнтаў.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "першы";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "№ з канца";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "атрымаць";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "атрымаць і выдаліць";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "апошні";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "выпадковы";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "выдаліць";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Вяртае першы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Вяртае элемэнт у пазначанай пазыцыі ў сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Вяртае апошні элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Вяртае выпадковы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Выдаляе і вяртае першы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Выдаляе і вяртае элемэнт у пазначанай пазыцыі ў сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Выдаляе і вяртае апошні элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Выдаляе і вяртае выпадковы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Выдаляе першы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Выдаляе элемэнт у пазначанай пазыцыі ў сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Выдаляе апошні элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Выдаляе выпадковы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "па № з канца";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "да #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "да апошняга";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "атрымаць падсьпіс зь першага";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "атрымаць падсьпіс з № з канца";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "атрымаць падсьпіс з №";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Стварае копію пазначанай часткі сьпісу.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "№%1 — апошні элемэнт.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "№%1 — першы элемэнт.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "знайсьці першае ўваходжаньне элемэнту";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "знайсьці апошняе ўваходжаньне элемэнту";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Вяртае індэкс першага/апошняга ўваходжаньня элемэнту ў сьпіс. Вяртае %1, калі элемэнт ня знойдзены.";
                +Blockly.Msg["LISTS_INLIST"] = "у сьпісе";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 пусты";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Вяртае значэньне ісьціна, калі сьпіс пусты.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "даўжыня %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Вяртае даўжыню сьпісу.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "стварыць сьпіс з элемэнту %1, які паўтараецца %2 разоў";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Стварае сьпіс, які ўтрымлівае пададзеную колькасьць копіяў элемэнту.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "адваротна %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Зьмяняе парадак копіі сьпісу на адваротны.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "як";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "уставіць у";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "усталяваць";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Устаўляе элемэнт у пачатак сьпісу.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Устаўляе элемэнт у пазначанай пазыцыі ў сьпісе.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Дадае элемэнт у канец сьпісу.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Выпадковым чынам устаўляе элемэнт у сьпіс.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Задае першы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Задае элемэнт у пазначанай пазыцыі ў сьпісе.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Задае апошні элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Задае выпадковы элемэнт у сьпісе.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "па павелічэньні";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "па зьмяншэньні";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "сартаваць %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Сартаваць копію сьпісу.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "паводле альфабэту, ігнараваць рэгістар";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "як лікі";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "паводле альфабэту";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "стварыць сьпіс з тэксту";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "стварыць тэкст са сьпісу";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Аб’ядноўвае сьпіс тэкстаў у адзін тэкст па падзяляльніках.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Падзяліць тэкст у сьпіс тэкстаў, па падзяляльніках.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "з падзяляльнікам";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "хлусьня";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Вяртае «ісьціна» ці «хлусьня».";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "ісьціна";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%9D%D1%8F%D1%80%D0%BE%D1%9E%D0%BD%D0%B0%D1%81%D1%8C%D1%86%D1%8C";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Вяртае «ісьціна», калі абодва ўводы роўныя.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Вяртае «ісьціна», калі першы ўвод большы за другі.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Вяртае «ісьціна», калі першы ўвод большы ці роўны другому.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Вяртае «ісьціна», калі першы ўвод меншы за другі.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Вяртае «ісьціна», калі першы ўвод меншы ці роўны другому.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Вяртае «ісьціна», калі абодва ўводы ня роўныя.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "не %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Вяртае «ісьціна», калі ўвод непраўдзівы. Вяртае «хлусьня», калі ўвод праўдзівы.";
                +Blockly.Msg["LOGIC_NULL"] = "нічога";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Вяртае нічога.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "і";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ці";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Вяртае «ісьціна», калі абодва ўводы праўдзівыя.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Вяртае «ісьціна», калі прынамсі адзін з уводаў праўдзівы.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "тэст";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "калі хлусьня";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "калі ісьціна";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Праверыць умову ў 'тэст'. Калі ўмова праўдзівая, будзе вернутае значэньне «калі ісьціна»; інакш будзе вернутае «калі хлусьня».";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%82%D0%BC%D1%8D%D1%82%D1%8B%D0%BA%D0%B0";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Вяртае суму двух лікаў.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Вяртае дзель двух лікаў.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Вяртае рознасьць двух лікаў.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Вяртае здабытак двух лікаў.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Вяртае першы лік у ступені другога ліку.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "зьмяніць %1 на %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Дадае лічбу да зьменнай '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D1%8D%D0%BC%D0%B0%D1%82%D1%8B%D1%87%D0%BD%D0%B0%D1%8F_%D0%BA%D0%B0%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B0";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Вяртае адну з агульных канстантаў: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0,707...) або ∞ (бясконцасьць).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "абмежаваць %1 зьнізу %2 зьверху %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Абмяжоўвае колькасьць ніжняй і верхняй межамі (уключна).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "дзяліць на";
                +Blockly.Msg["MATH_IS_EVEN"] = "парная";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "адмоўная";
                +Blockly.Msg["MATH_IS_ODD"] = "няпарная";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "станоўчая";
                +Blockly.Msg["MATH_IS_PRIME"] = "простая";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Правярае, ці зьяўляецца лік парным, няпарным, простым, станоўчым, адмоўным, ці ён дзеліцца на пэўны лік без астатку. Вяртае значэньне ісьціна або няпраўда.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "цэлая";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "рэшта дзяленьня %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Вяртае рэшту дзяленьня двух лікаў.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%9B%D1%96%D0%BA";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Лік.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "сярэдняя ў сьпісе";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "мінімальная ў сьпісе";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "мэдыяна сьпісу";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "мінімальная ў сьпісе";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "рэжымы сьпісу";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "выпадковы элемэнт сьпісу";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "стандартнае адхіленьне сьпісу";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Сума сьпісу";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Вяртае сярэднеарытмэтычнае значэньне лікавых значэньняў у сьпісе.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Вяртае найменшы лік у сьпісе.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Вяртае мэдыяну сьпісу.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Вяртае найменшы лік у сьпісе.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Вяртае сьпіс самых распаўсюджаных элемэнтаў у сьпісе.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Вяртае выпадковы элемэнт сьпісу.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Вяртае стандартнае адхіленьне сьпісу.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Вяртае суму ўсіх лікаў у сьпісе.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "выпадковая дроб";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Вяртае выпадковую дроб у дыяпазоне ад 0,0 (уключна) да 1,0.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "выпадковая цэлая з %1 для %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Вяртае выпадковы цэлы лік паміж двума зададзенымі абмежаваньнямі ўключна.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "акругліць";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "акругліць да меншага";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "акругліць да большага";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Акругленьне ліку да большага ці меншага.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%9A%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D1%8B_%D0%BA%D0%BE%D1%80%D0%B0%D0%BD%D1%8C";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "модуль";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "квадратны корань";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Вяртае модуль ліку.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Вяртае e ў ступені ліку.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Вяртае натуральны лягарытм ліку.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Вяртае дзесятковы лягарытм ліку.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Вяртае супрацьлеглы лік.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Вяртае 10 у ступені ліку.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Вяртае квадратны корань ліку.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://be-x-old.wikipedia.org/wiki/%D0%A2%D1%80%D1%8B%D0%B3%D0%B0%D0%BD%D0%B0%D0%BC%D1%8D%D1%82%D1%80%D1%8B%D1%8F#.D0.A2.D1.80.D1.8B.D0.B3.D0.B0.D0.BD.D0.B0.D0.BC.D1.8D.D1.82.D1.80.D1.8B.D1.87.D0.BD.D1.8B.D1.8F_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D1.8B.D1.96";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Вяртае арккосынус ліку.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Вяртае арксынус ліку.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Вяртае арктангэнс ліку.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Вяртае косынус кута ў градусах.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Вяртае сынус кута ў градусах.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Вяртае тангэнс кута ў градусах.";
                +Blockly.Msg["NEW_VARIABLE"] = "Стварыць зьменную…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Імя новай зьменнай:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "дазволіць зацьвярджэньне";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "з:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Запусьціць функцыю вызначаную карыстальнікам '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Запусьціць функцыю вызначаную карыстальнікам '%1' і выкарыстаць яе вынік.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "з:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Стварыць '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Апішыце гэтую функцыю…";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "зрабіць што-небудзь";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "да";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Стварае функцыю бяз выніку.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "вярнуць";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Стварае функцыю з вынікам.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Увага: гэтая функцыя мае парамэтры-дублікаты.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Падсьвяціць вызначэньне функцыі";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Калі значэньне ісьціна, вярнуць другое значэньне.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Папярэджаньне: гэты блёк можа выкарыстоўвацца толькі ў вызначанай функцыі.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "назва парамэтру:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Дадаць уваходныя парамэтры ў функцыю.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "парамэтры";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Дадаць, выдаліць ці запісаць чаргу ўваходных парамэтраў для гэтай функцыі.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Працэдура з назвай «%1» ужо існуе.";
                +Blockly.Msg["REDO"] = "Паўтарыць";
                +Blockly.Msg["REMOVE_COMMENT"] = "Выдаліць камэнтар";
                +Blockly.Msg["RENAME_VARIABLE"] = "Перайменаваць зьменную…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Перайменаваць усе назвы зьменных '%1' на:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "да %1 дадаць тэкст %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Дадаць які-небудзь тэкст да зьменнай '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "да ніжняга рэгістру";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Вялікія Першыя Літары";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "да ВЕРХНЯГА РЭГІСТРУ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Вярнуць копію тэксту зь іншай велічынёй літар.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "узяць першую літару";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "узяць літару № з канца";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "узяць літару №";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "узяць апошнюю літару";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "узяць выпадковую літару";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "у тэксьце %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Вяртае літару ў пазначанай пазыцыі.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "падлічыць %1 сярод %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Падлічвае колькі разоў нейкі тэкст сустракаецца ўнутры нейкага іншага тэксту.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Дадаць элемэнт да тэксту.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "далучыць";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Дадайце, выдаліце ці зьмяніце парадак разьдзелаў для перадачы тэкставага блёку.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "да літары № з канца";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "да літары №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "да апошняй літары";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "у тэксьце";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "атрымаць падрадок зь першай літары";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "узяць падрадок зь літары № з канца";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "узяць падрадок зь літары №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Вяртае пазначаную частку тэксту.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "знайсьці першае ўваходжаньне тэксту";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "знайсьці апошняе ўваходжаньне тэксту";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "у тэксьце %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Вяртае індэкс першага/апошняга ўваходжаньня першага тэксту ў другі тэкст. Вяртае %1, калі тэкст ня знойдзены.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 пусты";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Вяртае значэньне ісьціна, калі тэкст пусты.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "стварыць тэкст з";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Стварае фрагмэнт тэксту аб’яднаньнем любой колькасьці элемэнтаў.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "даўжыня %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Вяртае колькасьць літараў (у тым ліку прабелы) у пададзеным тэксьце.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "друкаваць %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Надрукаваць пазначаны тэкст, лічбу ці іншыя сымбалі.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Запытаць у карыстальніка лічбу.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Запытаць у карыстальніка тэкст.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "запытаць лічбу з падказкай";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "запытаць тэкст з падказкай";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "замяніць %1 на %2 у %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Замяняе ўсе выпадкі нейкага тэксту на іншы тэкст.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "адваротна %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Мяняе парадак сымбаляў у тэксьце на адваротны.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Літара, слова ці радок тэксту.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "абрэзаць прабелы з абодвух бакоў";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "абрэзаць прабелы зь левага боку";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "абрэзаць прабелы з правага боку";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Вяртае копію тэксту з прабеламі, выдаленымі ад аднаго ці абодвух бакоў.";
                +Blockly.Msg["TODAY"] = "Сёньня";
                +Blockly.Msg["UNDO"] = "Скасаваць";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "аб’ект";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Стварыць блёк «усталяваць %1»";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Вяртае значэньне гэтай зьменнай.";
                +Blockly.Msg["VARIABLES_SET"] = "усталяваць %1 да %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Стварыць блёк «атрымаць %1»";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Надаць гэтай зьменнай значэньне ўстаўкі.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Зьменная з назвай «%1» ужо існуе.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/bg.js b/blockly/webif/static/blockly/msg/js/bg.js
                new file mode 100644
                index 000000000..8ad0a0b0e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/bg.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.bg');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Добави коментар";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Променливата '%1' не може да бъде изтрита, защото е част от определението на функцията '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Промени стойността:";
                +Blockly.Msg["CLEAN_UP"] = "Премахни блокове";
                +Blockly.Msg["COLLAPSE_ALL"] = "Скрий блокове";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Скрий блок";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "цвят 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "цвят 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "съотношение";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "смеси";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Смесва два цвят в дадено съотношение (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://bg.wikipedia.org/wiki/Цвят_(оптика)";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Избери цвят от палитрата.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "случаен цвят";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Избери цвят на случаен принцип.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "син";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зелен";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "червен";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "оцвети с";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Създай цвят с избраните пропорции, червено, зелено и синьо. Всички стойности трябва да бъдат от 0 до 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "прекъсни цикъла";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "премини към следващата стъпка от цикъла";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Прекъсни цикъла, в който се съдържа тази команда.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Премини към следващата стъпка от цикъла";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Предупреждение: Този блок може да се използва само в цикъл.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "за всеки елемент %1 в списъка %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "За всеки елемент в списък присвои елемента на променливата '%1' и след това изпълни командите.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "преброй чрез %1 от %2 до %3 през %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Нека променлива '%1' премине през стойностите от началното до крайното число през зададената стъпка и изпълни избраните блокове.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Добави условие към „ако“ блока.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Добави окончателно, прихващащо всички останали случаи условие към блок „ако“.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Добави, премахни или пренареди частите, за да промениш този „ако“ блок.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "иначе";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "иначе ако";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ако";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ако стойността е вярна, изпълни операциите.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ако стойността е вярна, изпълни първият блок. Иначе, изпълни вторият блок.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ако първата стойност е вярна, изпълни първия блок. Иначе, ако втората стойност е вярна, изпълни втория блок.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ако първата стойност е вярна, изпълни първия блок. В противен случай, ако втората стойност е вярна, изпълни втория блок. Ако нито една от стойностите не е вярна, изпълни последния блок.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://bg.wikipedia.org/wiki/Цикъл_(програмиране)#For_.D1.86.D0.B8.D0.BA.D1.8A.D0.BB.D1.8A.D1.82";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "изпълни";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "Повтори %1 пъти";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Изпълнява команди няколко пъти.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "повтаряй докато";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "повтаряй докато е вярно, че";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Изпълни командите, ако стойността не е вярна.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Изпълни командите, ако стойността е вярна.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Изтриване на всички 1% блокове?";
                +Blockly.Msg["DELETE_BLOCK"] = "Изтрий блок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Изтриване на променливата \"%1\"";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Изтриване на %1 използване на променлива '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Изтрий %1 блока";
                +Blockly.Msg["DISABLE_BLOCK"] = "Деактивирай блок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Копирай";
                +Blockly.Msg["ENABLE_BLOCK"] = "Активирай блок";
                +Blockly.Msg["EXPAND_ALL"] = "Покажи блокове";
                +Blockly.Msg["EXPAND_BLOCK"] = "Покажи блок";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Външни входове";
                +Blockly.Msg["HELP"] = "Помощ";
                +Blockly.Msg["INLINE_INPUTS"] = "Вътрешни входове";
                +Blockly.Msg["IOS_CANCEL"] = "Отказ";
                +Blockly.Msg["IOS_ERROR"] = "Грешка";
                +Blockly.Msg["IOS_OK"] = "Добре";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Добавяне на данни";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Позволи твърденията";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Тази функция има дублирани входни данни.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "Входни данни";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Добавяне";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Добавяне на променлива";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Изтриване";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Не може да използвате празно име за променлива";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Преименуване";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Име на променливата";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "създай празен списък";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Връща списък с дължина 0, не съдържащ данни";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "списък";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Добави, премахни или пренареди частите, за да промениш този списъчен блок.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "създай списък с";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Добави елемент към текста.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Създай списък с произволен брой елементи.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "първия";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "№ от края";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "вземи";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "вземи и премахни";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "последния";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "произволен";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "премахни";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Връща първия елемент в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Връща елемента на определената позиция в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Връща последния елемент в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Връща случаен елемент от списъка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Премахва и връща първия елемент в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Премахва и връща елемента на определена позиция в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Премахва и връща последния елемент в списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Премахва и връща случаен елемент от списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Премахва първия елемент от списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Премахва елемент на определена позиция от списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Премахва последния елемент от списък.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Премахва случаен елемент от списък.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "до № открая";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "до №";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "до края";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "вземи подсписък от първия";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "вземи подсписък от № от края";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "вземи подсписък от №";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Копира част от списък.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 е последният елемент.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 е първият елемент.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "намери първата поява на елемента";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "намери последната поява на елемента";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Връща индекса на първото/последното появяване на елемента в списъка. Връща %1, ако елементът не е намерен.";
                +Blockly.Msg["LISTS_INLIST"] = "в списъка";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 е празен";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Връща стойност вярно, ако списъкът е празен.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "дължината на %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Връща дължината на списък.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "създай списък от %1 повторен %2 пъти";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Създава списък, състоящ се от определен брой копия на елемента.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "промени реда на обратно %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Промени реда на списъка на обратно.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "следното";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "вмъкни на позиция";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "промени";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Вмъква елемент в началото на списъка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Вмъква елемент на определена позиция в списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Добави елемент в края на списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Вмъква елемент на произволно място в списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Променя първия елемент в списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Променя елемента на определена позиция в списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Променя последния елемент в списък.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Променя случаен елемент от списък.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "възходящо";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "низходящо";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "сортиране по %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Подреди копие на списъка.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "по азбучен ред, без отчитане на малки и главни букви";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "в числов ред";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "по азбучен ред";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "Направи списък от текст";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "направи текст от списък";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Събира списък от текстове в един текст, раделени с разделител.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Разделя текст в списък на текстове, по всеки разделител.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "с разделител";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "невярно";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Връща вярно или невярно.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "вярно";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Върни вярно, ако двата параметъра са еднакви.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Върни истина, ако първия параметър е по-голям от втория.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Върни истина, ако първия параметър е по-голям или равен на втория.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Върни вярно, ако първият параметър е по-малък от втория.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Върни истина, ако първия параметър е по-малък или равен на втория.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Върни вярно, ако двата параметъра са различни.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "не %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Върни вярно, ако параметърът е неверен. Върни невярно, ако параметърът е верен.";
                +Blockly.Msg["LOGIC_NULL"] = "нула";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Връща нула.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "и";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "или";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Върни вярно, ако и двата параметъра са верни.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Върни „вярно“, ако поне един от входовете е верен.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "тест";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "Ако е невярно";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "Ако е вярно";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Провери условието в „тест“. Ако условието е истина, върни стойността „ако е вярно“, иначе върни стойността „ако е невярно“.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://bg.wikipedia.org/wiki/Аритметика";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Върни сумата на двете числа.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Върни частното на двете числа.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Върни разликата на двете числа.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Върни произведението на двете числа.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Върни първото число, повдигнато на степен на второто число.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://bg.wikipedia.org/wiki/Събиране";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "промени %1 на %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Добави число към променлива '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "http://bg.wikipedia.org/wiki/Константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Връща една от често срещаните константи: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) или ∞ (безкрайност).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "ограничи %1 между %2 и %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Ограничи число да бъде в определените граници (включително).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "се дели на";
                +Blockly.Msg["MATH_IS_EVEN"] = "е четно";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "е отрицателно";
                +Blockly.Msg["MATH_IS_ODD"] = "е нечетно";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "е положително";
                +Blockly.Msg["MATH_IS_PRIME"] = "е просто";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Проверете дали дадено число е четно, нечетно, просто, цяло, положително, отрицателно или дали се дели на друго число. Връща вярно или невярно.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "е цяло";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "http://bg.wikipedia.org/wiki/Остатък";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "остатъка от делението на %1 на %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Върни остатъка от деление на две числа.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://bg.wikipedia.org/wiki/Число";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Число.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "средната стойност на числата в списъка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "най-голямата стойност в списъка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "медианата на списък";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "най-малката стойност в списъка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "режими на списъка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "случаен елемент от списъка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "стандартно отклонение на списък";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "сума на списъка";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Върни средната стойност (аритметичното средно) на числата в списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Върни най-голямото число в списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Върни медианата в списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Върни най-малкото число в списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Върни списък на най-често срещаните елементи в списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Върни случаен елемент от списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Връща стандартното отклонение на списъка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Върни сумата на всички числа в списъка.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://bg.wikipedia.org/wiki/Генератор_на_случайни_числа";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "случайно дробно число";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Върни случайно дробно число между 0.0 (включително) и 1.0 (без да го включва)";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://bg.wikipedia.org/wiki/Генератор_на_случайни_числа";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "случайно цяло число между %1 и %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Върни случайно число в определените граници (включително).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "закръгли";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "закръгли надолу";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "закръгли нагоре";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Закръгли число нагоре или надолу.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "абсолютна";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "корен квадратен";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Връща абсолютната стойност на число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Върни е (неперовото число) на степен зададеното число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Върни натуралния логаритъм от число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Върни десетичния логаритъм на число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Върни числото с обърнат знак.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Върни 10 на степен зададеното число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Връща корен квадратен от число.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://bg.wikipedia.org/wiki/Тригонометрична_функция";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Върни аркускосинус от число.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Върни аркуссинус от число.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Върни аркустангенс от число.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Върни косинус от ъгъл в градуси (не в радиани)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Върни синус от ъгъл в градуси (не в радиани)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Върни тангенс от ъгъл в градуси (не в радиани)";
                +Blockly.Msg["NEW_VARIABLE"] = "Създаване на променлива...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Ново име на променливата:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "позволи операциите";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "с:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://bg.wikipedia.org/wiki/Подпрограма";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Изпълни дефинирана от потребителя функция „%1“.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://bg.wikipedia.org/wiki/Подпрограма";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Изпълни дефинирана от потребителя функция „%1“ и използвай резултата.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "с:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Създай '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Опишете тази функция...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "направиш";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "за да";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Създава функция, която не връща резултат.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "върни";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Създава функция, която връща резултат.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Предупреждение: Тази функция има дублиращи се параметри.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Покажи дефиницията на функцията";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ако стойността е вярна, върни втората стойност.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Предупреждение: Този блок може да се използва само във функция.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "име на параметър:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Добавяне на параметър към функцията.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "вход";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Добави, премахни или пренареди входните параметри за тази функция.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Процедура с име '%1' вече съществува.";
                +Blockly.Msg["REDO"] = "Повторение";
                +Blockly.Msg["REMOVE_COMMENT"] = "Премахни коментар";
                +Blockly.Msg["RENAME_VARIABLE"] = "Преименувай променливата...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Преименувай всички '%1' променливи на:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "добавете текст %2 към %1";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Добави текст към променливата „%1“.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "с малки букви";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "с Главна Буква На Всяка Дума";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "с ГЛАВНИ БУКВИ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Връща копие на текста със сменени малки и главни букви.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "вземи първата буква";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "вземи буква № от края";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "вземи буква №";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "вземи последната буква";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "вземи произволна буква";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "в текст %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Връща буквата в определена позиция.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "пресмята броя на %1 в %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Преброй колко пъти даден текст се среща в друг текст.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Добави елемент към текста.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "свържи";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Добави, премахни или пренареди частите, за да промениш този текстов блок.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "до буква № от края";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "до буква №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "до последната буква.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "в текста";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "вземи текста от първата буква";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "вземи текста от буква № (броено отзад-напред)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "вземи текста от буква №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Връща определена част от текста.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "намери първата поява на текста";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "намери последната поява на текста";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "в текст %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Връща индекса на първото/последното срещане на първия текст във втория текст. Връща %1, ако текстът не е намерен.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 е празен";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Връща вярно, ако текста е празен.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "създай текст с";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Създай текст като съчетаеш няколко елемента.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "дължината на %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Връща броя на символите (включително и интервалите) в текста.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "отпечатай %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Отпечатай текста, числото или друга стойност.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Питай потребителя за число.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Питай потребителя за текст.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "питай за число със съобщение";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "питай за текст със съобщение";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "замяна на %1 с %2 в %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Замени всички появи на даден текст в друг текст.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "промени реда на обратно %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Промени реда на знаците в текста на обратно.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://bg.wikipedia.org/wiki/Низ";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Буква, дума или ред";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "премахни интервалите от двете страни";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "премахни интервалите отляво";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "премахни интервалите отдясно";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Връща копие на текста с премахнати интервали от единия или двата края.";
                +Blockly.Msg["TODAY"] = "Днес";
                +Blockly.Msg["UNDO"] = "Отмяна";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "елемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Създай „промени стойността на %1“";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Връща стойността на тази променлива.";
                +Blockly.Msg["VARIABLES_SET"] = "нека %1 бъде %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Създай „вземи стойността на %1“";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Установява променливата със стойността на входа.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Променлива с име '%1' вече съществува.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/bn.js b/blockly/webif/static/blockly/msg/js/bn.js
                new file mode 100644
                index 000000000..1aed32f47
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/bn.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.bn');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "মন্তব্য যোগ করুন";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "মান পরিবর্তন করুন:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Collapse Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Collapse Block";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "রং ১";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "রং ২";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "অনুপাত";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "মিশ্রণ";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "প্রদত্ত অনুপাত(০.০ - ১.০) অনুসারে দুটি রং একসাথে মিশ্রিত করুন।";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "প্যালেট থেকে একটি রং পছন্দ করুন";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "এলোমেলো রং";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "এলোমেলোভাবে একটি রং পছন্দ করুন।";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "নীল";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "সবুজ";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "লাল";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "রং সহ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "একটি রং তৈরি করুন নির্দিষ্ট পরিমাণে লাল, সবুজ এবং নীল রং মিশ্রিত করে। প্রত্যেকটির মান অবশ্যই ০ থেকে ১০০ এর মধ্যে হতে হবে।";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "সর্তকীবার্তা: এই ব্লকটি শুধুমাত্র লুপের মধ্যে ব্যবহার করা যাবে।";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "প্রত্যেকটি পদের জন্য %1 তালিকার মধ্যে %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "গণনা কর %1 %4 দিয়ে %2 থেকে %3";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "যদি নামক ব্লক এ একটি শর্ত যোগ করুন।";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "নতুবা";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "নতুবা যদি";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "যদি";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "করুন";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 বার পুনরাবৃত্তি করো";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repeat until";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repeat while";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "ব্লকটি মুছে ফেল";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 ব্লক অপসারণ কর";
                +Blockly.Msg["DISABLE_BLOCK"] = "ব্লকটি বিকল কর";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "প্রতিলিপি";
                +Blockly.Msg["ENABLE_BLOCK"] = "ব্লকটি সচল কর";
                +Blockly.Msg["EXPAND_ALL"] = "ব্লকগুলো সম্প্রসারিত কর";
                +Blockly.Msg["EXPAND_BLOCK"] = "ব্লকটি সম্প্রসারিত কর";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "বহি:স্থ ইনপুট";
                +Blockly.Msg["HELP"] = "সাহায্য";
                +Blockly.Msg["INLINE_INPUTS"] = "সারি ইনপুট";
                +Blockly.Msg["IOS_CANCEL"] = "বাতিল";
                +Blockly.Msg["IOS_ERROR"] = "ত্রুটি";
                +Blockly.Msg["IOS_OK"] = "ঠিক আছে";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "যোগ";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "অপসারণ";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "খালি তালিকা তৈরি করুন";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "পাঠাবে একটি তালিকা, দের্ঘ্য হবে ০, কোন উপাত্ত থাকবে না";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "তালিকা";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "তালিকায় একটি পদ যোগ করুন।";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "যেকোন সংখ্যক পদ নিয়ে একটি তালিকা তৈরি করুন।";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "প্রথম";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# শেষ থেকে";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "নিন";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "নিন ও সরান";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "শেষ";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "এলোমেলো";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "অপসারণ";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "তালিকার প্রথম পদটি পাঠাবে।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "তালিকার শেষ পদটি পাঠাবে।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "এলোমেলোভাবে তালিকার যেকোন একটি পদ পাঠাবে।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "অপসারণ করুন এবং তালিকার প্রথম পদটি পাঠান।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "অপসারণ করুন এবং তালিকার শেষ পদটি পাঠান।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "অপসারণ করুন এবং তালিকার এলোমেলো একটি পদ পাঠান।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "তালিকার প্রথম পদটি অপসারণ করা হয়েছে।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "তালিকার শেষ পদটি অপসারণ করা হয়েছে।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "তালিকা থেকে এলোমেলো একটি পদ অপসারণ করা হয়েছে।";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "আইটেমের প্রথম সংঘটন খুঁজুন";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "আইটেমের শেষ সংঘটন খুঁজুন";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "তালিকার মধ্যে";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 খালি";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "পাঠাবে সত্য যদি তালিকাটি খালি হয়।";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1-এর দৈর্ঘ্য";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "একটি তালিকার দৈর্ঘ্য পাঠাবে।";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "একটি তালিকার একটি অনুলিপি উল্টান";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "লিখা থেকে তালিকা তৈরি করুন";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "তালিকা থেকে লিখা তৈরি করুন";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "মিথ্যা";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "পাঠাবে হয় সত্য অথবা মিথ্যা।";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "সত্য";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "পাঠাবে সত্য যদি উভয় ইনপুটই সমান হয়।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে বড় হয়।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে বড় অথবা সমান হয়।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে ছোট হয়।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে ছোট অথবা সমান হয়।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "পাঠাবে সত্য যদি উভয় ইনপুটই সমান না হয়।";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 নয়";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "পাঠাবে সত্য যদি ইনপুট মিথ্যা হয়। পাঠাবে মিথ্যা যদি ইনপুট সত্য হয়।";
                +Blockly.Msg["LOGIC_NULL"] = "কিছু না";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "কিছু ফেরত দিবে না।";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "এবং";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "অথবা";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "পাঠাবে সত্য যদি উভয় ইনপুটই সত্য হয়।";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "পাঠাবে সত্য যদি অন্ততপক্ষে যেকোন একটি ইনপুট সত্য হয়।";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "পরীক্ষা";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "যদি মিথ্যা হয়";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "যদি সত্য হয়";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "পাঠাবে দুটি সংখ্যার যোগফল।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "পাঠাবে দুটি সংখ্যার ভাগফল।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "পাঠাবে দুটি সংখ্যার বিয়োগফল।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "পাঠাবে দুটি সংখ্যার গুণফল।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%2 দ্বারা %1 পরিবর্তন";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "দ্বারা বিভাজ্য";
                +Blockly.Msg["MATH_IS_EVEN"] = "জোড় সংখ্যা";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "নেতিবাচক";
                +Blockly.Msg["MATH_IS_ODD"] = "বিজোড় সংখ্যা";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ইতিবাচক";
                +Blockly.Msg["MATH_IS_PRIME"] = "মৌলিক সংখ্যা";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";  // untranslated
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 এর ভাগশেষ";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://bn.wikipedia.org/wiki/সংখ্যা";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "একটি সংখ্যা।";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "তালিকার গড়";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "তালিকার মধ্যে সর্বোচ্চ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "তালিকার মধ্যমা";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "তালিকার মধ্যে সর্বনিম্ন";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "তালিকার এলোমেলো পদ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "তালিকার যোগফল";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "পাঠাবে তালিকার সব সংখ্যার গড়।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "তালিকার মধ্যে সর্বোচ্চ সংখ্যাটি পাঠাও";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "তালিকার মধ্যমা সংখ্যাটি পাঠাবে।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "তালিকার মধ্যে সর্বনিম্ন সংখ্যাটি পাঠাও";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "তালিকা থেকে এলোমেলোভাবে একটি পদ পাঠাবে।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "পাঠাবে তালিকার সব সংখ্যার যোগফল।";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "এলোমেলো ভগ্নাংশ";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";  // untranslated
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "পরম";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "বর্গমূল";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "পাঠাবে সংখ্যার পরমমান।";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "পাঠাবে একটি সংখ্যার বর্গমূল।";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "চলক তৈরি করুন...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "নতুন চলকের নাম:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "এতে";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "আউটপুট ছাড়া একটি ক্রিয়া তৈরি করুন।";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "পাঠাবে";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "আউটপুট সহ একটি ক্রিয়া তৈরি করুন।";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "ক্রিয়ার সংজ্ঞা উজ্জল করুন";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "যদি মান সত্য হয় তাহলে দ্বিতীয় মান পাঠাবে।";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "ইনপুটের নাম:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "ক্রিয়াতে একটি ইনপুট যোগ করুন।";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "পুনরায় করুন";
                +Blockly.Msg["REMOVE_COMMENT"] = "মন্তব্য সরাও";
                +Blockly.Msg["RENAME_VARIABLE"] = "চলকের নাম পরিবর্তন...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";  // untranslated
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "ছোটহাতের অক্ষরে";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "বড়হাতের অক্ষরে";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "লেখাটিতে একটি পদ যোগ করুন।";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "যোগ";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 খালি";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "পাঠাবে সত্য যদি সরবরাহকৃত লেখাটি খালি হয়।";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1-এর দৈর্ঘ্য";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 মুদ্রণ করুন";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "%1 উল্টান";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "একটি অক্ষর, শব্দ অথবা বাক্য।";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "উভয় পাশ থেকে খালি অংশ ছাটাই";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "বামপাশ থেকে খালি অংশ ছাটাই";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "ডানপাশ থেকে খালি অংশ ছাটাই";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "আজ";
                +Blockly.Msg["UNDO"] = "পূর্বাবস্থা";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "পদ";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'%1 নিন' তৈরি করুন";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/br.js b/blockly/webif/static/blockly/msg/js/br.js
                new file mode 100644
                index 000000000..b2521dc23
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/br.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.br');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Ouzhpennañ un evezhiadenn";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Ne ch'aller ket dilemel an argemm \"%1\" dre m'eo lod eus dielfennadur an arc'hwel \"%2\"";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Kemmañ an dalvoudenn :";
                +Blockly.Msg["CLEAN_UP"] = "Naetaat ar bloc'hoù";
                +Blockly.Msg["COLLAPSE_ALL"] = "Bihanaat ar bloc'hoù";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Bihanaat ar bloc'h";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "liv 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "liv 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "feur";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "meskañ";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "a gemmesk daou liv gant ur feur roet(0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "http://br.wikipedia.org/wiki/Liv";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Dibab ul liv diwar al livaoueg.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "liv dargouezhek";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Tennañ ul liv d'ar sord";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "glas";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "gwer";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ruz";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "liv gant";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Krouiñ ul liv gant ar c'hementad spisaet a ruz, a wer hag a c'hlas. Etre 0 ha 100 e tle bezañ an holl dalvoudoù.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "Mont e-maez an adlañsañ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "Kenderc'hel gant iteradur nevez ar rodell";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Mont e-maez ar boukl engronnus.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Lammat ar rest eus ar rodell, ha kenderc'hel gant an iteradur war-lerc'h.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Diwallit : ne c'hall ar bloc'h-mañ bezañ implijet nemet e-barzh ur boukl.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "evit pep elfenn %1 er roll %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Evit pep elfenn en ur roll, reiñ talvoud an elfenn d'an argemmenn '%1', ha seveniñ urzhioù zo da c'houde.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "kontañ gant %1 eus %2 da %3 dre %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Ober e doare ma kemero an argemmenn \"%1\" an talvoudennoù adalek niverenn an deroù betek niverenn an dibenn, en ur inkremantiñ an esaouenn, ha seveniñ an urzhioù spisaet.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Ouzhpennañ un amplegad d'ar bloc'h ma.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Ouzhpennañ un amplegad dibenn lak-pep-tra d'ar bloc'h ma.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h ma.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "a-hend-all";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "mod all ma";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ma";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ma vez gwir un dalvoudenn, seveniñ urzhioù zo neuze.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ma vez gwir un dalvoudenn, seveniñ ar c'henañ bloc'had urzhioù neuze. Anez seveniñ an eil bloc'had urzhioù.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ma vez gwir an dalvoudenn gentañ, seveniñ ar c'hentañ bloc'had urzhioù neuze. Anez ma vez gwir an eil talvoudenn, seveniñ an eil bloc'had urzhioù.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ma vez gwir an dalvoudenn gentañ, seveniñ ar c'hentañ bloc'had. Anez, ma vez gwir an eil talvoudenn, seveniñ an eil bloc'had urzhioù. Ma ne vez gwir talvoudenn ebet, seveniñ ar bloc'had diwezhañ a urzhioù.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ober";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "adober %1 gwech";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Seveniñ urzhioù zo meur a wech";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "adober betek";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "adober keit ha ma";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Keit ha ma vez faos un dalvoudenn,seveniñ urzhioù zo neuze.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Keit ha ma vez gwir un dalvoudenn, seveniñ urzhioù zo neuze.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Diverkañ an holl vloc'hoù %1 ?";
                +Blockly.Msg["DELETE_BLOCK"] = "Dilemel ar bloc'h";
                +Blockly.Msg["DELETE_VARIABLE"] = "Lemel an argemm '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Lemel %1 implij eus an argemm '%2' ?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Dilemel %1 bloc'h";
                +Blockly.Msg["DISABLE_BLOCK"] = "Diweredekaat ar bloc'h";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Eiladuriñ";
                +Blockly.Msg["ENABLE_BLOCK"] = "Gweredekaat ar bloc'h";
                +Blockly.Msg["EXPAND_ALL"] = "Astenn ar bloc'hoù";
                +Blockly.Msg["EXPAND_BLOCK"] = "Astenn ar bloc'h";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Monedoù diavaez";
                +Blockly.Msg["HELP"] = "Skoazell";
                +Blockly.Msg["INLINE_INPUTS"] = "Monedoù enlinenn";
                +Blockly.Msg["IOS_CANCEL"] = "Nullañ";
                +Blockly.Msg["IOS_ERROR"] = "Fazi";
                +Blockly.Msg["IOS_OK"] = "Mat eo";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Ouzhpennañ ur moned";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Urzhioù aotreet";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "An arc'hwel-mañ en eus monedoù eiladet.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "MONEDOÙ";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Ouzhpennañ";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Ouzhpennañ un argemm";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Diverkañ";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Ne c'hallit ket implijout un anv argemm goullo.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Adenvel";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Anv an argemenn";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "krouiñ ur roll goullo";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Distreiñ ul listenn, 0 a hirder, n'eus enrolladenn ebet enni";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "roll";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h listenn-mañ.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "krouiñ ur roll gant";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Ouzhpennañ un elfenn d'ar roll";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Krouiñ ur roll gant un niver bennak a elfennoù.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "kentañ";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# adalek ar fin";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "tapout";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "tapout ha lemel";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "diwezhañ";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "dre zegouezh";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "lemel";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Distreiñ an elfenn gentañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Distreiñ an elfenn el lec'h meneget en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Distreiñ un elfenn diwezhañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Distreiñ un elfenn dre zegouezh en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Lemel ha distreiñ a ra an elfenn gentañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Lemel ha distreiñ a ra an elfenn el lec'h meneget en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Lemel ha distreiñ a ra an elfenn diwezhañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Lemel ha distreiñ a ra an elfenn dre zegouezh en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Lemel a ra an elfenn gentañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Lemel a ra an elfenn el lec'h meneget en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Distreiñ a ra an elfenn diwezhañ en ul listenn.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Lemel a ra un elfenn dre zegouezh en ul listenn.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "betek # adalek an dibenn";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "da #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "betek ar fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "Kaout an islistenn adalek an deroù";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "Kaout an islistenn adalek # adalek an dibenn";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "Kaout an islistenn adalek #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Krouiñ un eilad eus lodenn spisaet ul listenn.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 eo an elfenn gentañ.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 eo an elfenn gentañ.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "kavout reveziadenn gentañ un elfenn";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "kavout reveziadenn diwezhañ un elfenn";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Distreiñ meneger ar c'hentañ/an eil reveziadenn eus an elfenn en ul listenn. Distreiñ %1 ma n'eo ket kavet an destenn.";
                +Blockly.Msg["LISTS_INLIST"] = "el listenn";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 zo goullo";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Distreiñ gwir m'eo goullo al listenn.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "hirder %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Distreiñ hirder ul listenn.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Krouiñ ul listenn gant an elfenn %1 arreet div wech";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Krouiñ ul listenn a c'hoarvez eus an dalvoudenn roet arreet an niver a wech meneget";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "eilpennañ %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Eilpennañ un eilskrid eus ur roll.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "evel";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "ensoc'hañ evel";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "termenañ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Ensoc'hañ a ra an elfenn e deroù ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Ensoc'hañ a ra an elfenn el lec'h meneget en ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Ouzhpennañ a ra an elfenn e fin al listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Ensoc'hañ a ra an elfenn dre zegouezh en ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Termenañ a ra an elfenn gentañ en ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Termenañ a ra an elfenn el lec'h meneget en ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Termenañ a ra an elfenn diwezhañ en ul listenn.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Termenañ a ra un elfenn dre zegouezh en ul listenn.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "war gresk";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "war zigresk";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "Rummañ%1,%2,%3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Rummañ un eilenn eus ar roll";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "Dre urzh al lizherenneg, hep derc'hel kont eus an direnneg";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "niverel";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "Dre urzh al lizherenneg";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "Krouiñ ul listenn diwar an destenn";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "Krouiñ un destenn diwar al listenn";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Bodañ ul listennad testennoù en ul listenn hepken, o tispartiañ anezho gant un dispartier.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Troc'hañ un destenn en ul listennad testennoù, o troc'hañ e pep dispartier.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "gant an dispartier";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "gaou";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Distreiñ pe gwir pe faos";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "gwir";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Distreiñ gwir m'eo par an daou voned.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Distreiñ gwir m'eo brasoc'h ar moned kentañ eget an eil.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Distreiñ gwir m'eo brasoc'h ar moned kentañ eget an eil pe par dezhañ.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Distreiñ gwir m'eo bihanoc'h ar moned kentañ eget an eil.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Distreiñ gwir m'eo bihanoc'h ar moned kentañ eget an eil pe m'eo par dezhañ.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Distreiñ gwir ma n'eo ket par an daou voned.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nann %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Distreiñ gwir m'eo faos ar moned. Distreiñ faos m'eo gwir ar moned.";
                +Blockly.Msg["LOGIC_NULL"] = "Null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Distreiñ null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ha(g)";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "pe";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Distreiñ gwir m'eo gwir an da daou voned.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Distreiñ gwir m'eo gwir unan eus an daou voned da nebeutañ.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "amprouad";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "m'eo gaou";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "m'eo gwir";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Gwiriañ an amplegad e 'prouad'. M'eo gwir an amplegad, distreiñ an dalvoudenn 'm'eo gwir'; anez distreiñ ar moned 'm'eo faos'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://br.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Distreiñ sammad daou niver.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Distreiñ rannad daou niver.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Distreiñ diforc'h daou niver";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Distreiñ liesad daou niver.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Distreiñ an niver kentañ lakaet dindan gallouter an eil niver.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "kemmañ %1 gant %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Ouzhpennañ un niver d'an argemm '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Distreiñ unan eus  digemmennoù red : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (anvevenn).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "destrizhañ %1 etre %2 ha %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Destrizhañ un niver da vezañ etre ar bevennoù spisaet (enlakaet)";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "a zo rannadus dre";
                +Blockly.Msg["MATH_IS_EVEN"] = "zo par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "a zo negativel";
                +Blockly.Msg["MATH_IS_ODD"] = "zo ampar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "a zo pozitivel";
                +Blockly.Msg["MATH_IS_PRIME"] = "zo kentañ";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Gwiriañ m'eo par, anpar, kentañ, muiel, leiel un niverenn pe ma c'haller rannañ anezhi dre un niver roet zo. Distreiñ gwir pe faos.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "zo anterin";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "rest eus %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Distreiñ dilerc'h rannadur an div niver";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://br.wikipedia.org/wiki/Niver";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un niver.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "Keitat al listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Uc'hegenn al listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Kreizad al listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Izegenn al listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modoù stankañ el listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Elfennn eus al listenn tennet d'ar sord";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "forc'had standart eus al listenn";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Sammad al listenn";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Distreiñ keitad (niveroniel) an talvoudennoù niverel el listenn.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Distreiñ an niver brasañ el listenn.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Distreiñ an niver kreiz el listenn";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Distreiñ an niver bihanañ el listenn";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Distreiñ ul listennad elfennoù stankoc'h el listenn.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Distreiñ un elfenn zargouezhek el listenn";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Distreiñ forc'had standart al listenn.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Distreiñ sammad an holl niveroù zo el listenn.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "Rann dargouezhek";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Distreiñ ur rann dargouezhek etre 0.0 (enkaelat) hag 1.0 (ezkaelat).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "anterin dargouezhek etre %1 ha %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Distreiñ un anterin dargouezhek etre an div vevenn spisaet, endalc'het.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "Rontaat";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "Rontaat dindan";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "Rontaat a-us";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Rontaat un niver dindan pe a-us";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://br.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "dizave";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "gwrizienn garrez";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Distreiñ talvoud dizave un niver.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Distreiñ galloudad un niver.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Distreiñ logaritm naturel un niver";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Distreiñ logaritm diazez 10 un niver";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Distreiñ enebad un niver";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Distreiñ 10 da c'halloudad un niver.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Distreiñ gwrizienn garrez un niver";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://br.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Distreiñ ark kosinuz un niver";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Distreiñ ark sinuz un niver";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Distreiñ ark tangent un niver";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Distreiñ kosinuz ur c'horn (ket e radianoù)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Distreiñ sinuz ur c'horn (ket e radianoù)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Distreiñ tangent ur c'horn (ket e radianoù).";
                +Blockly.Msg["NEW_VARIABLE"] = "Krouiñ un argemm nevez...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Anv an argemmenn nevez :";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "aotren an disklêriadurioù";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "gant :";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Seveniñ an arc'hwel '%1' termenet gant an implijer.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Seveniñ an arc'hwel '%1' termenet gant an implijer hag implijout e zisoc'h.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "gant :";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Krouiñ '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Deskrivañ an arc'hwel-mañ...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "ober un dra bennak";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "da";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Krouiñ un arc'hwel hep mont er-maez.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "distreiñ";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Kouiñ un arc'hwel gant ur mont er-maez";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Diwallit : an arc'hwel-mañ en deus arventennoù eiladet.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Dreislinennañ termenadur an arc'hwel";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ma'z eo gwir un dalvoudenn, distreiñ un eil talvoudenn neuze.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Diwallit : Gallout a rafe ar bloc'h bezañ implijet e termenadur un arc'hwel hepken.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Anv ar moned";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Ouzhpennañ ur moned d'an arc'hwel.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "Monedoù";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Ouzhpennañ, lemel, pe adkempenn monedoù an arc'hwel-mañ.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Un argerzhadur anvet '%1' zo anezhañ dija.";
                +Blockly.Msg["REDO"] = "Adober";
                +Blockly.Msg["REMOVE_COMMENT"] = "Lemel an evezhiadenn kuit";
                +Blockly.Msg["RENAME_VARIABLE"] = "Adenvel an argemmenn...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Adenvel an holl argemmennoù '%1' e :";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "Ouzhpennañ an destenn %2 da %1";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Ouzhpennañ testenn d'an argemmenn'%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "e lizherennoù bihan";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Gant Ur Bennlizherenn E Deroù Pep Ger";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "e PENNLIZHERENNOÙ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Distreiñ un eilenn eus an eilenn en un direnneg all";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "tapout al lizherenn gentañ";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "Kaout al lizherenn # adalek an dibenn.";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "Kaout al lizherenn #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "tapout al lizherenn ziwezhañ";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "Kaout ul lizherenn dre zegouezh";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "en destenn %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Distreiñ al lizherenn d'al lec'h spisaet.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "niver %1 war %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Kontañ pet gwech e c'hoarvez un destenn bennak en un destenn bennak all.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Ouzhpennañ un elfenn d'an destenn.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "stagañ";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h testenn-mañ.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "Betek al lizherenn # adalek an dibenn.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "betek al lizherenn #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "d'al lizherenn diwezhañ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "en destenn";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "Kaout an ischadenn adalek al lizherenn gentañ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "Kaout an ischadenn adalek al lizherenn # betek an dibenn";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "Kaout an ischadenn adalek al lizherenn #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Distreiñ un tamm spisaet eus an destenn.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "kavout reveziadenn gentañ an destenn";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "kavout reveziadenn diwezhañ an destenn";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "en destenn %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Distreiñ meneger ar c'hentañ/an eil reveziadenn eus ar chadenn gentañ en eil chadenn. Distreiñ %1 ma n'eo ket kavet ar chadenn.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 zo goullo";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Adkas gwir m'eo goullo an destenn roet.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "krouiñ un destenn gant";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Krouit un tamm testenn en ur gevelstrollañ un niver bennak a elfennoù";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "hirder %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Distreiñ an niver a lizherennoù(en ur gontañ an esaouennoù e-barzh) en destenn roet.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "moullañ %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Moullañ an destenn, an niverenn pe un dalvoudenn spisaet all";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Goulenn un niver gant an implijer.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Goulenn un destenn gant an implijer.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "pedadenn evit un niver gant ur c'hemennad";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "pedadenn evit un destenn gant ur c'hemennad";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "erlec'hiañ %1 gant %2 e %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Erlec'hiañ holl reveziadennoù un destenn bennak gant un destenn all.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "eilpennañ %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Eilpennañ urzh an arouezennoù en destenn.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Ul lizherenn, ur ger pe ul linennad testenn.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "Lemel an esaouennoù en daou du";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "Lemel an esaouennoù eus an tu kleiz";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "Lemel an esaouennoù eus an tu dehou";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Distreiñ un eilenn eus an destenn gant an esaouennoù lamet eus un tu pe eus an daou du";
                +Blockly.Msg["TODAY"] = "Hiziv";
                +Blockly.Msg["UNDO"] = "Dizober";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "elfenn";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Krouiñ 'termenañ %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Distreiñ talvoud an argemm-mañ.";
                +Blockly.Msg["VARIABLES_SET"] = "termenañ %1 da %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Krouiñ 'kaout %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Termenañ a ra argemm-mañ evit ma vo par da dalvoudenn ar moned.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Un argemm anvet '%1' zo anezhañ dija.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ca.js b/blockly/webif/static/blockly/msg/js/ca.js
                new file mode 100644
                index 000000000..d8b86a662
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ca.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ca');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Afegeix un comentari";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Canvia valor:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Contraure blocs";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Contraure bloc";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "color 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "color 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporció";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "barreja";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Barreja dos colors amb una proporció donada (0,0 - 1,0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ca.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Escolliu un color de la paleta.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "color aleatori";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Escolliu un color a l'atzar.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blau";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verd";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "vermell";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "color amb";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Crear un color amb les quantitats especificades de vermell, verd i blau. Tots els valors han de ser entre 0 i 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "sortir del bucle";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continuar amb la següent iteració del bucle";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Sortir del bucle interior.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Ometre la resta d'aquest bucle, i continuar amb la següent iteració.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Advertència: Aquest bloc només es pot utilitzar dins d'un bucle.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "per a cada element %1 en la llista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Per a cada element en la llista, desar l'element dins la variable '%1', i llavors executar unes sentències.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "comptar amb %1 des de %2 fins a %3 en increments de %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Fer que la variable \"%1\" prengui els valors des del nombre inicial fins al nombre final, incrementant a cada pas l'interval indicat, i executar els blocs especificats.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Afegeix una condició al bloc 'si'.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Afegeix una condició final, que recull qualsevol altra possibilitat, al bloc 'si'.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Afegeix, esborra o reordena seccions per reconfigurar aquest bloc 'si'.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "si no";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "si no, si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si un valor és cert, llavors executar unes sentències.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si un valor és cert, llavors executar el primer bloc de sentències. En cas contrari, executar el segon bloc de sentències.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si el primer valor és cert, llavors executar el primer bloc de sentències. En cas contrari, si el segon valor és cert, executar el segon bloc de sentències.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si el primer valor és cert, llavors executar el primer bloc de sentències. En cas contrari, si el segon valor és cert, executar el segon bloc de sentències. Si cap dels valors és cert, executar l'últim bloc de sentències.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://ca.wikipedia.org/wiki/Bucle_For";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fer";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repetir %1 vegades";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Executar unes sentències diverses vegades.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repetir fins que";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repetir mentre";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Mentre un valor sigui fals, llavors executar unes sentències.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Mentre un valor sigui cert, llavors executar unes sentències.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Esborrar els %1 blocs?";
                +Blockly.Msg["DELETE_BLOCK"] = "Esborra bloc";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Esborra %1 blocs";
                +Blockly.Msg["DISABLE_BLOCK"] = "Desactiva bloc";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplica";
                +Blockly.Msg["ENABLE_BLOCK"] = "Activa bloc";
                +Blockly.Msg["EXPAND_ALL"] = "Expandir blocs";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expandir bloc";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entrades externes";
                +Blockly.Msg["HELP"] = "Ajuda";
                +Blockly.Msg["INLINE_INPUTS"] = "Entrades en línia";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "crear llista buida";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Retorna una llista, de longitud 0, que no conté cap dada.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "llista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Afegeix, esborra o reordena seccions per reconfigurar aquest bloc de llista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "crear llista amb";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Afegeix un element a la llista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Crea una llista amb qualsevol nombre d'elements.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primer";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "núm.# des del final";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "recupera";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "recupera i esborra";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "últim";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "a l'atzar";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "esborra";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Retorna el primer element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Retorna l'element de la posició especificada a la llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Retorna l'últim element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Retorna un element a l'atzar d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Esborra i retorna el primer element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Esborra i retorna l'element de la posició especificada de la llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Esborra i retorna l'últim element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Esborra i retorna un element a l'atzar d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Esborra el primer element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Esborra l'element de la posició especificada de la llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Esborra l'últim element d'una llista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Esborra un element a l'atzar d'una llista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "fins # des del final";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "fins #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "fins l'últim";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "recupera sub-llista des del principi";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "recupera sub-llista des de # des del final";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "recupera sub-llista des de #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Crea una còpia de la part especificada d'una llista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 és l'últim element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 és el primer element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "buscar primera aparició d'un element";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "buscar última aparició d'un element";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Retorna l'índex de la primera/última aparició d'un element a la llista. Retorna %1 si no s'hi troba el text.";
                +Blockly.Msg["LISTS_INLIST"] = "en la llista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 és buida";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Retorna cert si la llista és buida.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longitud de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Retorna la longitud d'una llista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "crea llista amb element %1 repetit %2 vegades";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Crea una llista formada pel valor donat, repetit tantes vegades com s'indiqui.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "com";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insereix a";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "modifica";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insereix l'element al principi d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insereix l'element a la posició especificada d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Afegeix l'element al final d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Insereix l'element en una posició a l'atzar d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Modifica el primer element d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Modifica l'element de la posició especificada d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Modifica l'últim element d'una llista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Modifica un element a l'atzar d'una llista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "fals";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Retorna o bé cert o bé fals.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "cert";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://ca.wikipedia.org/wiki/Inequaci%C3%B3";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Retorna cert si totes dues entrades són iguals.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Retorna cert si la primera entrada és més gran que la segona entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Retorna cert si la primera entrada és més gran o igual a la segona entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Retorna cert si la primera entrada és més petita que la segona entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Retorna cert si la primera entra és més petita o igual a la segona entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Retorna cert si totes dues entrades són diferents.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "no %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Retorna cert si l'entrada és falsa. Retorna fals si l'entrada és certa.";
                +Blockly.Msg["LOGIC_NULL"] = "nul";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Retorna nul.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "i";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Retorna cer si totes dues entrades són certes.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Retorna cert si almenys una de les entrades és certa.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "condició";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "si és fals";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "si és cert";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Comprova la condició de 'condició'. Si la condició és certa, retorna el valor 'si és cert'; en cas contrari, retorna el valor 'si és fals'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ca.wikipedia.org/wiki/Aritm%C3%A8tica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Retorna la suma dels dos nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Retorna el quocient dels dos nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Retorna la diferència entre els dos nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Retorna el producte del dos nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Retorna el primer nombre elevat a la potència indicada pel segon nombre.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://ca.wikipedia.org/wiki/Suma";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "canvia %1 per %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Afegeix un nombre a la variable '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ca.wikipedia.org/wiki/Constant_matem%C3%A0tica";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Retorna una de les constants més habituals: π (3,141…), e (2,718…), φ (1,618…), sqrt(2) (1,414…), sqrt(½) (0,707…), o ∞ (infinit).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "limitar %1 entre %2 i %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Limita un nombre perquè estigui entre els límits especificats (inclosos).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "és divisible per";
                +Blockly.Msg["MATH_IS_EVEN"] = "és parell";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "és negatiu";
                +Blockly.Msg["MATH_IS_ODD"] = "és senar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "és positiu";
                +Blockly.Msg["MATH_IS_PRIME"] = "és primer";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Comprova si un nombre és parell, senar, enter, positium negatiu, o si és divisible per un cert nombre. Retorna cert o fals.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "és enter";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://ca.wikipedia.org/wiki/Residu_%28aritm%C3%A8tica%29";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "residu de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Retorna el residu de dividir els dos nombres.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ca.wikipedia.org/wiki/Nombre";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un nombre.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "mitjana de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "màxim de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mínim de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "moda de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "element aleatori de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "desviació estàndard de llista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma de llista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Retorna la mitjana (mitjana aritmètica) dels valors numèrics de la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Retorna el nombre més gran de la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Retorna la mediana de la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Retorna el nombre més petit de la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Retorna una llista dels elements que apareixen més vegades a la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Retorna un element aleatori de la lllista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Retorna la desviació estàndard de la llista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Retorna la suma de tots els nombres de la llista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://ca.wikipedia.org/wiki/Generaci%C3%B3_de_nombres_aleatoris";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fracció aleatòria";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Retorna una fracció aleatòria entre 0,0 (inclòs) i 1,0 (exclòs).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://ca.wikipedia.org/wiki/Generaci%C3%B3_de_nombres_aleatoris";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "nombre aleatori entre %1 i %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Retorna un nombre aleatori entre els dos límits especificats, inclosos.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ca.wikipedia.org/wiki/Arrodoniment";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arrodonir";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arrodonir cap avall";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arrodonir cap amunt";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arrodonir un nombre cap amunt o cap avall.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ca.wikipedia.org/wiki/Arrel_quadrada";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "arrel quadrada";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Retorna el valor absolut d'un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Retorna ''e'' elevat a la potència del nombre indicat.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Retorna el logaritme natural d'un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Retorna el logaritme en base 10 d'un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Retorna l'oposat d'un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Retorna 10 elevat a la potència del nombre indicat.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Retorna l'arrel quadrada d'un nombre.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ca.wikipedia.org/wiki/Funci%C3%B3_trigonom%C3%A8trica";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Retorna l'arccosinus d'un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Retorna l'arcsinus d'un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Retorna l'arctangent d'un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Retorna el cosinus d'un grau (no radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Retorna el sinus d'un grau (no radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Retorna la tangent d'un grau (no radiant).";
                +Blockly.Msg["NEW_VARIABLE"] = "Crea una variable…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nou nom de variable:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permetre declaracions";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "amb:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ca.wikipedia.org/wiki/Procediment_%28Programació%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Executa la funció definida per usuari '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ca.wikipedia.org/wiki/Procediment_%28Programació%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Executa la funció definida per l'usuari '%1' i utilitza la seva sortida.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "amb:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Crear '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "fes alguna cosa";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "a";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crea una funció sense sortida.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retorna";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Crea una funció amb una sortida.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Advertència: Aquesta funció té paràmetres duplicats.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Iluminar la definició de la funció";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Si el valor és cert, llavors retorna un segon valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Advertència: Aquest bloc només es pot utilitzar dins de la definició d'una funció.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nom d'entrada:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Afegir una entrada per la funció.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entrades";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Afegir, eliminar o canviar l'ordre de les entrades per aquesta funció.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Elimina el comentari";
                +Blockly.Msg["RENAME_VARIABLE"] = "Reanomena variable...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Reanomena totes les variables '%1' a:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Afegir un text a la variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "a minúscules";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "a Text De Títol";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "a MAJÚSCULES";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Retorna una còpia del text amb diferents majúscules/minúscules.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "recupera la primera lletra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "recupera la lletra núm.# des del final";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "recupera la lletra núm.#";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "recupera l'última lletra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "recupera una lletra a l'atzar";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Recupera la lletra de la posició especificada.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Afegeix un element al text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Afegeix, esborrar o reordenar seccions per reconfigurar aquest bloc de text.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "fins a la lletra núm.# des del final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "fins a la lletra núm.#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "fins a l'última lletra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "en el text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "recupera subcadena des de la primera lletra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "recupera subcadena des de la lletra núm.# des del final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "recupera subcadena des de la lletra núm.#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Recupera una part especificada del text.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "trobar la primera aparició del text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "trobar l'última aparició del text";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Retorna l'índex de la primera/última aparició del primer text dins el segon. Retorna %1 si no es troba el text.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 està buit";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Retorna cert si el text proporcionat està buit.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "crear text amb";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Crea un tros de text per unió de qualsevol nombre d'elements.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "llargària de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Retorna el nombre de lletres (espais inclosos) en el text proporcionat.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "imprimir %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Imprimir el text, el nombre o altre valor especificat.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Demana que l'usuari introdueixi un nombre.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Demana que l'usuari introdueixi un text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "demanar un nombre amb el missatge";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "demanar text amb el missatge";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ca.wikipedia.org/wiki/Cadena_%28inform%C3%A0tica%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Una lletra, paraula o línia de text.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "retalla espais de tots dos extrems de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "retalla espais de l'esquerra de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "retalla espais de la dreta de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Retorna una còpia del text on s'han esborrat els espais d'un o dels dos extrems.";
                +Blockly.Msg["TODAY"] = "Today";  // untranslated
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crea 'modifica %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Retorna el valor d'aquesta variable.";
                +Blockly.Msg["VARIABLES_SET"] = "modifica %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Crear 'recupera %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Modifica aquesta variable al valor introduït.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/cs.js b/blockly/webif/static/blockly/msg/js/cs.js
                new file mode 100644
                index 000000000..b75d6fba0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/cs.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.cs');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Přidat komentář";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Změnit hodnotu:";
                +Blockly.Msg["CLEAN_UP"] = "Uspořádat bloky";
                +Blockly.Msg["COLLAPSE_ALL"] = "Sbalit bloky";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Sbalit blok";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "barva 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "barva 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "poměr";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "smíchat";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Smíchá dvě barvy v daném poměru (0.0–1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://cs.wikipedia.org/wiki/Barva";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Vyberte barvu z palety.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "náhodná barva";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Zvolte barvu náhodně.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "modrá";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zelená";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "červená";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "obarvěte barvou";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Vytvoř barvu se zadaným množstvím červené, zelené a modré.  Všechny hodnoty musí být mezi 0 a 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "vyskočit ze smyčky";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "pokračuj dalším opakováním smyčky";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Vyskoč z vnitřní smyčky.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Přeskoč zbytek této smyčky a pokračuj dalším opakováním.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Upozornění: Tento blok může být použit pouze uvnitř smyčky.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "pro každou položku %1 v seznamu %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Pro každou položku v seznamu nastavte do proměnné '%1' danou položku a proveďte nějaké operace.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "počítat s %1 od %2 do %3 po %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Nechá proměnnou '%1' nabývat hodnot od počátečního do koncového čísla po daném přírůstku a provádí s ní příslušné bloky.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Přidat podmínku do \"pokud\" bloku.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Přidej konečnou podmínku zahrnující ostatní případy do bloku \"pokud\".";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Přidej, odstraň či uspořádej sekce k přenastavení tohoto bloku \"pokud\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "jinak";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "nebo pokud";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "pokud";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Je-li hodnota pravda, proveď určité příkazy.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Je-li hodnota pravda, proveď první blok příkazů.  V opačném případě proveď druhý blok příkazů.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Je-li první hodnota pravdivá, proveď první blok příkazů. V opačném případě, je-li pravdivá druhá hodnota, proveď druhý blok příkazů.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Je-li první hodnota pravda, proveď první blok příkazů.  Je-li druhá hodnota pravda, proveď druhý blok příkazů.  Pokud žádná hodnota není pravda, proveď poslední blok příkazů.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://cs.wikipedia.org/wiki/Cyklus_pro";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "dělej";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "opakuj %1 krát";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Proveď určité příkazy několikrát.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "opakovat dokud";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "opakovat když";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Dokud je hodnota nepravdivá, prováděj určité příkazy.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Dokud je hodnota pravdivá, prováděj určité příkazy.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Smazat všech %1 bloků?";
                +Blockly.Msg["DELETE_BLOCK"] = "Smazat blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Smazat %1 bloků";
                +Blockly.Msg["DISABLE_BLOCK"] = "Deaktivovat blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplikovat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Povolit blok";
                +Blockly.Msg["EXPAND_ALL"] = "Rozbalit bloky";
                +Blockly.Msg["EXPAND_BLOCK"] = "Rozbalit blok";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "vnější vstupy";
                +Blockly.Msg["HELP"] = "Nápověda";
                +Blockly.Msg["INLINE_INPUTS"] = "Vložené vstupy";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Chyba";
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "vstupy";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Přidat";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Smazat";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Přejmenovat";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "vytvořit prázdný seznam";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Vrátí seznam nulové délky, který neobsahuje žádné datové záznamy";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "seznam";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Přidat, odebrat nebo změnit pořadí oddílů tohoto seznamu bloku.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "vytvořit seznam s";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Přidat položku do seznamu.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Vytvoř seznam s libovolným počtem položek.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "první";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# od konce";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "získat";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "získat a odstranit";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "poslední";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "náhodné";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "odstranit";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Vrátí první položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Získá položku z určené pozice v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Vrátí poslední položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Vrátí náhodnou položku ze seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Odstraní a vrátí první položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Odstraní a získá položku z určené pozice v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Odstraní a vrátí poslední položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Odstraní a vrátí náhodnou položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Odstraní první položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Odebere položku na konkrétním místě v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Odstraní poslední položku v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Odstraní náhodou položku v seznamu.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "do # od konce";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "do #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "jako poslední";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "získat podseznam od první položky";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "získat podseznam od # od konce";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "získat podseznam od #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Vytvoří kopii určené části seznamu.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 je poslední položka.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 je první položka.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "najít první výskyt položky";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "najít poslední výskyt položky";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Vrací index prvního/posledního výskytu položky v seznamu. Vrací %1, pokud položka nebyla nalezena.";
                +Blockly.Msg["LISTS_INLIST"] = "v seznamu";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 je prázdné";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Vrátí hodnotu pravda, pokud je seznam prázdný.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "délka %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Vrací počet položek v seznamu.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "vytvoř seznam s položkou %1 opakovanou %1 krát";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Vytváří seznam obsahující danou hodnotu n-krát.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "jako";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "vložit na";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "nastavit";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Vložit položku na začátek seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Vloží položku na určenou pozici v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Připojí položku na konec seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Připojí položku náhodně do seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Nastaví první položku v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Nastaví položku na konkrétní místo v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Nastaví poslední položku v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Nastaví náhodnou položku v seznamu.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "vzestupně";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "sestupně";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "seřadit %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Seřadit kopii seznamu.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "abecedně, na velikosti písmen nezáleží";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "číselné";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "abecedně";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "udělat z textu seznam";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "udělat ze seznamu text";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Spojit seznam textů do jednoho textu, rozdělaného oddělovači.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Rozdělit text do seznamu textů, lámání na oddělovačích.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "s oddělovačem";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "nepravda";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Vrací pravda nebo nepravda.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "pravda";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://cs.wikipedia.org/wiki/Nerovnost_(matematika)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Vrátí hodnotu pravda, pokud se oba vstupy rovnají jeden druhému.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Navrátí hodnotu pravda, pokud první vstup je větší než druhý vstup.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Navrátí hodnotu pravda, pokud je první vstup větší a nebo rovný druhému vstupu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Navrátí hodnotu pravda, pokud je první vstup menší než druhý vstup.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Navrátí hodnotu pravda, pokud je první vstup menší a nebo rovný druhému vstupu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Vrátí hodnotu pravda, pokud se oba vstupy nerovnají sobě navzájem.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ne %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Navrátí hodnotu pravda, pokud je vstup nepravda. Navrátí hodnotu nepravda, pokud je vstup pravda.";
                +Blockly.Msg["LOGIC_NULL"] = "prázdný";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Vrátí prázdnou hodnotu";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "a";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "nebo";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Vrátí hodnotu pravda, pokud oba dva vstupy jsou pravdivé.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Vrátí hodnotu pravda, pokud alespoň jeden ze vstupů má hodnotu pravda.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://cs.wikipedia.org/wiki/Ternární operátor (programování)";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "pokud nepravda";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "pokud pravda";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Zkontroluje podmínku v \"testu\". Když je podmínka pravda, vrátí hodnotu \"pokud pravda\"; v opačném případě vrátí hodnotu \"pokud nepravda\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://cs.wikipedia.org/wiki/Aritmetika";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Vrátí součet dvou čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Vrátí podíl dvou čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Vrátí rozdíl dvou čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Vrátí součin dvou čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Vrátí první číslo umocněné na druhé číslo.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "zaměň %1 za %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Přičti číslo k proměnné '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Vraťte jednu z následujících konstant: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (nekonečno).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "omez %1 na rozmezí od %2 do %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Omezí číslo tak, aby bylo ve stanovených mezích (včetně).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "je dělitelné číslem";
                +Blockly.Msg["MATH_IS_EVEN"] = "je sudé";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "je záporné";
                +Blockly.Msg["MATH_IS_ODD"] = "je liché";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "je kladné";
                +Blockly.Msg["MATH_IS_PRIME"] = "je prvočíslo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrola, zda je číslo sudé, liché, prvočíslo, celé, kladné, záporné nebo zda je dělitelné daným číslem. Vrací pravdu nebo nepravdu.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "je celé";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://cs.wikipedia.org/wiki/Modul%C3%A1rn%C3%AD_aritmetika";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "zbytek po dělení %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Vrátí zbytek po dělení dvou čísel.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://cs.wikipedia.org/wiki/Číslo";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Číslo.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "průměr v seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "největší v seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "medián v seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "nejmenší v seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "nejčastější ze seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "náhodná položka seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "směrodatná odchylka ze seznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma seznamu";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Vrátí průměr (aritmetický průměr) číselných hodnot v seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Vrátí největší číslo v seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Vrátí medián seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Vrátí nejmenší číslo v seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Vrátí seznam nejčastějších položek seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Vrátí náhodnou položku ze seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Vrátí směrodatnou odchylku seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Vrátí součet všech čísel v seznamu.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://cs.wikipedia.org/wiki/Gener%C3%A1tor_n%C3%A1hodn%C3%BDch_%C4%8D%C3%ADsel";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "náhodné číslo mezi 0 (včetně) do 1";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Vrátí náhodné číslo mezi 0,0 (včetně) až 1,0";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://cs.wikipedia.org/wiki/Gener%C3%A1tor_n%C3%A1hodn%C3%BDch_%C4%8D%C3%ADsel";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "náhodné celé číslo od %1 do %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Vrací náhodné celé číslo mezi dvěma určenými mezemi, včetně mezních hodnot.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "zaokrouhlit";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "zaokrouhlit dolů";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "zaokrouhlit nahoru";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Zaokrouhlit číslo nahoru nebo dolů.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://cs.wikipedia.org/wiki/Druhá_odmocnina";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolutní hodnota";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "druhá odmocnina";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Vrátí absolutní hodnotu čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Vrátí mocninu čísla e.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Vrátí přirozený logaritmus čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Vrátí desítkový logaritmus čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Vrátí zápornou hodnotu čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Vrátí mocninu čísla 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Vrátí druhou odmocninu čísla.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Vrátí arkus kosinus čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Vrátí arkus sinus čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Vrátí arkus tangens čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Vrátí kosinus úhlu ve stupních.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Vrátí sinus úhlu ve stupních.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Vrátí tangens úhlu ve stupních.";
                +Blockly.Msg["NEW_VARIABLE"] = "Nová proměnná...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nový název proměnné:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "povolit příkazy";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "s:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://cs.wikipedia.org/wiki/Podprogram";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Spustí uživatelem definovanou funkci '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://cs.wikipedia.org/wiki/Podprogram";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Spustí uživatelem definovanou funkci '%1' a použije její výstup.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "s:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Vytvořit '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Popište tuto funkci...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://cs.wikipedia.org/w/index.php?title=Funkce_(programování)";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "proveď něco";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "k provedení";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Vytvořit funkci bez výstupu.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://cs.wikipedia.org/w/index.php?title=Funkce_(programování)";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "navrátit";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Vytvořit funkci s výstupem.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Upozornění: Tato funkce má duplicitní parametry.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Zvýraznit definici funkce";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Je-li hodnota pravda, pak vrátí druhou hodnotu.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Varování: Tento blok může být použit pouze uvnitř definici funkce.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "vstupní jméno:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Přidat vstupy do funkce.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "vstupy";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Přidat, odebrat nebo změnit pořadí vstupů této funkce.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Znovu";
                +Blockly.Msg["REMOVE_COMMENT"] = "Odstranit komentář";
                +Blockly.Msg["RENAME_VARIABLE"] = "Přejmenovat proměnnou...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Přejmenuj všech '%1' proměnných na:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Přidá určitý text k proměnné '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "na malá písmena";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "na Počáteční Velká Písmena";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "na VELKÁ PÍSMENA";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Vrátí kopii textu s jinou velikostí písmen.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "získat první písmeno";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "získat # písmeno od konce";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "získat písmeno #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "získat poslední písmeno";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "získat náhodné písmeno";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Získat písmeno na konkrétní pozici.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Přidat položku do textu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "spojit";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Přidat, odebrat nebo změnit pořadí oddílů tohoto textového bloku.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "do # písmene od konce";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "do písmene #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "do posledního písmene";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "v textu";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "získat podřetězec od prvního písmene";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "získat podřetězec od písmene # od konce";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "získat podřetězec od písmene #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Získat zadanou část textu.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "najít první výskyt textu";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "najít poslední výskyt textu";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Vrátí index prvního/posledního výskytu prvního textu v druhém textu.  Pokud text není nalezen, vypíše %1.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 je prázdný";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Vrátí pravda pokud je zadaný text prázdný.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "vytvořit text s";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Vytvoří kousek textu spojením libovolného počtu položek.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "délka %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Vrátí počet písmen (včetně mezer) v zadaném textu.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "tisk %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Tisk zadaného textu, čísla nebo jiné hodnoty.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Výzva pro uživatele k zadání čísla.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Výzva pro uživatele k zadání nějakého textu.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "výzva k zadání čísla se zprávou";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "výzva k zadání textu se zprávou";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://cs.wikipedia.org/wiki/Textov%C3%BD_%C5%99et%C4%9Bzec";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Písmeno, slovo nebo řádek textu.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "odstranit mezery z obou stran";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "odstranit mezery z levé strany";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "odstranit mezery z pravé strany";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Vrátí kopii textu s odstraněnými mezerami z jednoho nebo obou konců.";
                +Blockly.Msg["TODAY"] = "Dnes";
                +Blockly.Msg["UNDO"] = "Zpět";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "položka";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Vytvořit \"nastavit %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Vrátí hodnotu této proměnné.";
                +Blockly.Msg["VARIABLES_SET"] = "nastavit %1 na %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Vytvořit \"získat %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Nastaví tuto proměnnou, aby se rovnala vstupu.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/da.js b/blockly/webif/static/blockly/msg/js/da.js
                new file mode 100644
                index 000000000..9e2561fe4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/da.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.da');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Tilføj kommentar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Skift værdi:";
                +Blockly.Msg["CLEAN_UP"] = "Ryd op i blokke";
                +Blockly.Msg["COLLAPSE_ALL"] = "Fold blokkene sammen";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Fold blokken sammen";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "farve 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "farve 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "i forholdet";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "bland";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blander to farver sammen i et bestemt forhold (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://da.wikipedia.org/wiki/Farve";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Vælg en farve fra paletten.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "tilfældig farve";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Vælg en tilfældig farve.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blå";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grøn";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rød";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "farve med";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Lav en farve med den angivne mængde af rød, grøn og blå. Alle værdier skal være mellem 0 og 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "bryd ud af løkken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "fortsæt med den næste gentagelse i løkken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Bryd ud af den omgivende løkke.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Spring resten af denne løkke over, og fortsæt med den næste gentagelse.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Advarsel: Denne blok kan kun bruges i en løkke.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for hvert element %1 i listen %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For hvert element i en liste, sæt variablen '%1' til elementet, og udfør derefter nogle kommandoer.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "tæl med %1 fra %2 til %3 med %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Få variablen \"%1\" til at have værdierne fra startværdien til slutværdien, mens der tælles med det angivne interval, og udfør de angivne blokke.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Tilføj en betingelse til denne \"hvis\" blok.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Tilføj en sidste fang-alt betingelse, til denne \"hvis\" blok.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne \"hvis\" blok.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "ellers";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "ellers hvis";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "hvis";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Hvis en værdi er sand, så udfør nogle kommandoer.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Hvis en værdi er sand, så udfør den første blok af kommandoer. Ellers udfør den anden blok af kommandoer.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Hvis den første værdi er sand, så udfør den første blok af kommandoer.  Ellers, hvis den anden værdi er sand, så udfør den anden blok af kommandoer.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Hvis den første værdi er sand, så udfør den første blok af kommandoer. Ellers, hvis den anden værdi er sand, så udfør den anden blok af kommandoer. Hvis ingen af værdierne er sande, så udfør den sidste blok af kommandoer.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://da.wikipedia.org/wiki/For-l%C3%B8kke";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "udfør";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "gentag %1 gange";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Udfør nogle kommandoer flere gange.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "gentag indtil";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "gentag sålænge";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Udfør nogle kommandoer, sålænge en værdi er falsk.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Udfør nogle kommandoer, sålænge en værdi er sand.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Slet alle %1 blokke?";
                +Blockly.Msg["DELETE_BLOCK"] = "Slet blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Slet %1 blokke";
                +Blockly.Msg["DISABLE_BLOCK"] = "Deaktivér blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplikér";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktivér blok";
                +Blockly.Msg["EXPAND_ALL"] = "Fold blokkene ud";
                +Blockly.Msg["EXPAND_BLOCK"] = "Fold blokken ud";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Udvendige inputs";
                +Blockly.Msg["HELP"] = "Hjælp";
                +Blockly.Msg["INLINE_INPUTS"] = "Indlejrede inputs";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "opret en tom liste";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returnerer en liste af længde 0, som ikke indeholder nogen data";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne blok.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "opret liste med";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Føj et element til listen.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Opret en liste med et vilkårligt antal elementer.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "første";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# fra slutningen";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "hent";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "hent og fjern";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "sidste";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "tilfældig";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "fjern";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returnerer det første element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returnerer elementet på den angivne position på en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returnerer den sidste element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returnerer et tilfældigt element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Fjerner og returnerer det første element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Fjerner og returnerer elementet på den angivne position på en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Fjerner og returnerer det sidste element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Fjerner og returnerer et tilfældigt element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Fjerner det første element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Fjerner elementet på den angivne position på en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Fjerner sidste element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Fjerner et tilfældigt element i en liste.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "til # fra slutningen";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "til #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "til sidste";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "hent underliste fra første";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "hent underliste fra # fra slutningen";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "hent underliste fra #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Opretter en kopi af den angivne del af en liste.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 er det sidste element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 er det første element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find første forekomst af elementet";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find sidste forekomst af elementet";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returnerer indeks for første/sidste forekomst af elementet i listen. Returnerer %1, hvis elementet ikke kan findes.";
                +Blockly.Msg["LISTS_INLIST"] = "i listen";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 er tom";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returnerer sand, hvis listen er tom.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "længden af %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returnerer længden af en liste.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "opret liste med elementet %1 gentaget %2 gange";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Opretter en liste bestående af den givne værdi gentaget et bestemt antal gange.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "som";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "indsæt ved";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "sæt";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Indsætter elementet i starten af en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Indsætter elementet på den angivne position i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Føj elementet til slutningen af en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Indsætter elementet tilfældigt i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sætter det første element i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sætter elementet på den angivne position i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sætter det sidste element i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sætter et tilfældigt element i en liste.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "stigende";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "faldende";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "nummerorden";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetisk";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "lav tekst til liste";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "lav liste til tekst";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Saml en liste af tekster til én tekst, der er adskilt af et skilletegn.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Bryd tekst op i en liste af tekster med brud ved hvert skilletegn.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "med skilletegn";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falsk";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returnerer enten sand eller falsk.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "sand";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://da.wikipedia.org/wiki/Ulighed_(matematik)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Returnere sand, hvis begge inputs er lig med hinanden.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Returnere sand, hvis det første input er større end det andet input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Returnere sand, hvis det første input er større end eller lig med det andet input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Returnere sand, hvis det første input er mindre end det andet input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Returnere sand, hvis det første input er mindre end eller lig med det andet input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Returnere sand, hvis begge inputs ikke er lig med hinanden.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ikke %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returnerer sand, hvis input er falsk. Returnerer falsk, hvis input er sandt.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returnerer null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "og";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "eller";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Returnere sand, hvis begge inputs er sande.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Returnere sand, hvis mindst et af inputtene er sande.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "hvis falsk";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "hvis sand";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kontrollér betingelsen i 'test'. Hvis betingelsen er sand, returnér \"hvis sand\" værdien; ellers returnér \"hvis falsk\" værdien.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://da.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Returnere summen af de to tal.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Returnere kvotienten af de to tal.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Returnere forskellen mellem de to tal.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Returnere produktet af de to tal.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Returnere det første tal opløftet til potensen af det andet tal.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "skift %1 med %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Læg et tal til variablen '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://da.wikipedia.org/wiki/Matematisk_konstant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Returnere en af de ofte brugte konstanter: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(2) (1.414…), sqrt(½) (0.707…) eller ∞ (uendeligt).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "begræns %1 til mellem %2 og %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Begræns et tal til at være mellem de angivne grænser (inklusiv).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = ":";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "er deleligt med";
                +Blockly.Msg["MATH_IS_EVEN"] = "er lige";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "er negativt";
                +Blockly.Msg["MATH_IS_ODD"] = "er ulige";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "er positivt";
                +Blockly.Msg["MATH_IS_PRIME"] = "er et primtal";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrollere, om et tal er lige, ulige, primtal, helt, positivt, negativt, eller om det er deleligt med bestemt tal. Returnere sandt eller falskt.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "er helt";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://da.wikipedia.org/wiki/Modulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resten af %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Returner resten fra at dividere de to tal.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://da.wikipedia.org/wiki/Tal";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Et tal.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "gennemsnit af listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "største tal i listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "listens median";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mindste tal i listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "listens typetal";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "tilfældigt element fra listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standardafvigelsen for listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summen af listen";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Returner gennemsnittet (middelværdien) af de numeriske værdier i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Returner det største tal i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Returner listens median.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Returner det mindste tal i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Returner en liste over de mest almindelige elementer på listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Returner et tilfældigt element fra listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Returner standardafvigelsen for listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Returner summen af alle tal i listen.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://da.wikipedia.org/wiki/Tilfældighedsgenerator";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "tilfældigt decimaltal (mellem 0 og 1)";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Returner et tilfældigt decimaltal mellem 0,0 (inklusiv) og 1,0 (eksklusiv).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://da.wikipedia.org/wiki/Tilfældighedsgenerator";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "tilfældigt heltal mellem %1 og %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Returner et tilfældigt heltal mellem de to angivne grænser (inklusiv).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://da.wikipedia.org/wiki/Afrunding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "afrund";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "rund ned";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "rund op";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Runde et tal op eller ned.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://da.wikipedia.org/wiki/Kvadratrod";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadratrod";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Returnere den absolutte værdi af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Returnere e til potensen af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Returnere den naturlige logaritme af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Returnere 10-talslogaritmen af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Returnere negationen af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Returnere 10 til potensen af et tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Returnere kvadratroden af et tal.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://da.wikipedia.org/wiki/Trigonometrisk_funktion";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Returnere arcus cosinus af et tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Returnere arcus sinus af et tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Returnere arcus tangens af et tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Returnere cosinus af en vinkel (i grader).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Returnere sinus af en vinkel (i grader).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Returnere tangens af en vinkel (i grader).";
                +Blockly.Msg["NEW_VARIABLE"] = "Ny variabel...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Navn til den nye variabel:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "tillad erklæringer";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://da.wikipedia.org/wiki/Funktion_%28programmering%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Kør den brugerdefinerede funktion '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://da.wikipedia.org/wiki/Funktion_%28programmering%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Kør den brugerdefinerede funktion '%1' og brug dens returværdi.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Opret '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Beskriv denne funktion...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "gøre noget";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "for at";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Opretter en funktion der ikke har nogen returværdi.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "returnér";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Opretter en funktion der har en returværdi.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Advarsel: Denne funktion har dublerede parametre.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Markér funktionsdefinitionen";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Hvis en værdi er sand, så returnér en anden værdi.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Advarsel: Denne blok kan kun anvendes inden for en funktionsdefinition.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "parameternavn:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Tilføj en parameter til funktionen.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "parametre";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Tilføje, fjerne eller ændre rækkefølgen af parametre til denne funktion.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Fjern kommentar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Omdøb variabel...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Omdøb alle '%1' variabler til:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Tilføj noget tekst til variablen '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "til små bogstaver";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "til Stort Begyndelsesbogstav";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "til STORE BOGSTAVER";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Returner en kopi af teksten hvor bogstaverne enten er udelukkende store eller små, eller hvor første bogstav i hvert ord er stort.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "hent første bogstav";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "hent bogstav # fra slutningen";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "hent bogstav #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "hent sidste bogstav";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "hent tilfældigt bogstav";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returnerer bogstavet på den angivne placering.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Føj et element til teksten.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "sammenføj";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne tekstblok.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "til bogstav # fra slutningen";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "til bogstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "til sidste bogstav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "i teksten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "hent delstreng fra første bogstav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "hent delstreng fra bogstav # fra slutningen";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "hent delstreng fra bogstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returnerer den angivne del af teksten.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find første forekomst af teksten";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find sidste forekomst af teksten";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returnerer indeks for første/sidste forekomst af første tekst i den anden tekst.  Returnerer %1, hvis teksten ikke kan findes.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 er tom";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returnerer sand, hvis den angivne tekst er tom.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "lav en tekst med";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Lav et stykke tekst ved at sætte et antal elementer sammen.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "længden af %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returnerer antallet af bogstaver (herunder mellemrum) i den angivne tekst.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "skriv %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Skriv den angivne tekst, tal eller anden værdi.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Spørg brugeren efter et tal";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Spørg brugeren efter en tekst";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "spørg efter et tal med meddelelsen";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "spørg efter tekst med meddelelsen";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://da.wikipedia.org/wiki/Tekststreng";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "En bogstav, et ord eller en linje med tekst.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "fjern mellemrum fra begge sider af";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "fjern mellemrum fra venstre side af";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "fjern mellemrum fra højre side af";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Returner en kopi af teksten med mellemrum fjernet fra den ene eller begge sider.";
                +Blockly.Msg["TODAY"] = "I dag";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Opret 'sæt %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returnerer værdien af denne variabel.";
                +Blockly.Msg["VARIABLES_SET"] = "sæt %1 til %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Opret 'hent %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sætter denne variabel til at være lig med input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/de.js b/blockly/webif/static/blockly/msg/js/de.js
                new file mode 100644
                index 000000000..7592d65f9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/de.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.de');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Kommentar hinzufügen";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Die Variable „%1“ kann nicht gelöscht werden, da sie Teil der Definition der Funktion „%2“ ist.";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Wert ändern:";
                +Blockly.Msg["CLEAN_UP"] = "Bausteine aufräumen";
                +Blockly.Msg["COLLAPSE_ALL"] = "Alle Bausteine zusammenfalten";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Baustein zusammenfalten";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "Farbe 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "und Farbe 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "im Verhältnis";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mische";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Vermischt 2 Farben mit konfigurierbarem Farbverhältnis (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://de.wikipedia.org/wiki/Farbe";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Erzeugt eine Farbe aus der Palette.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "zufällige Farbe";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Erzeugt eine Farbe nach dem Zufallsprinzip.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blau";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grün";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "https://de.wikipedia.org/wiki/RGB-Farbraum";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rot";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "Farbe aus";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Erzeugt eine Farbe mit selbst definierten Rot-, Grün- und Blauwerten. Alle Werte müssen zwischen 0 und 100 liegen.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://de.wikipedia.org/wiki/Kontrollstruktur";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "die Schleife abbrechen";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "sofort mit nächstem Schleifendurchlauf fortfahren";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Die umgebende Schleife beenden.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Diese Anweisung abbrechen und mit dem nächsten Schleifendurchlauf fortfahren.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warnung: Dieser Baustein kann nur in einer Schleife verwendet werden.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://de.wikipedia.org/wiki/For-Schleife";
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "für jeden Wert %1 aus der Liste %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Führt eine Anweisung für jeden Wert in der Liste aus und setzt dabei die Variable \"%1\" auf den aktuellen Listenwert.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://de.wikipedia.org/wiki/For-Schleife";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "zähle %1 von %2 bis %3 in Schritten von %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Zählt die Variable \"%1\" von einem Startwert bis zu einem Endwert und führt für jeden Wert eine Anweisung aus.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Eine weitere Bedingung hinzufügen.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Eine sonst-Bedingung hinzufügen. Führt eine Anweisung aus, falls keine Bedingung zutrifft.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Hinzufügen, entfernen oder sortieren von Sektionen";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "sonst";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "sonst falls";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "falls";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Führt eine Anweisung aus, falls eine Bedingung wahr ist.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Führt die erste Anweisung aus, falls eine Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Führt die erste Anweisung aus, falls die erste Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus, falls die zweite Bedingung wahr ist.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Führe die erste Anweisung aus, falls die erste Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus, falls die zweite Bedingung wahr ist.  Führt die dritte Anweisung aus, falls keine der beiden Bedingungen wahr ist";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://de.wikipedia.org/wiki/For-Schleife";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "mache";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "wiederhole %1 mal:";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Eine Anweisung mehrfach ausführen.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://de.wikipedia.org/wiki/Schleife_%28Programmierung%29";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "wiederhole bis";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "wiederhole solange";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Führt Anweisungen aus solange die Bedingung unwahr ist.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Führt Anweisungen aus solange die Bedingung wahr ist.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Alle %1 Bausteine löschen?";
                +Blockly.Msg["DELETE_BLOCK"] = "Baustein löschen";
                +Blockly.Msg["DELETE_VARIABLE"] = "Die Variable „%1“ löschen";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "%1 Verwendungen der Variable „%2“ löschen?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 Bausteine löschen";
                +Blockly.Msg["DISABLE_BLOCK"] = "Baustein deaktivieren";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kopieren";
                +Blockly.Msg["ENABLE_BLOCK"] = "Baustein aktivieren";
                +Blockly.Msg["EXPAND_ALL"] = "Alle Bausteine entfalten";
                +Blockly.Msg["EXPAND_BLOCK"] = "Baustein entfalten";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "externe Eingänge";
                +Blockly.Msg["HELP"] = "Hilfe";
                +Blockly.Msg["INLINE_INPUTS"] = "interne Eingänge";
                +Blockly.Msg["IOS_CANCEL"] = "Abbrechen";
                +Blockly.Msg["IOS_ERROR"] = "Fehler";
                +Blockly.Msg["IOS_OK"] = "OKAY";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Parameter hinzufügen";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Anweisungen erlauben";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Diese Funktion hat doppelte Parameter.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "PARAMETER";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Hinzufügen";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Variable hinzufügen";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Löschen";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Du kannst keinen leeren Variablennamen verwenden.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Umbenennen";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Name der Variable";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "erzeuge eine leere Liste";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Erzeugt eine leere Liste ohne Inhalt.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "Liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Hinzufügen, entfernen und sortieren von Elementen.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "erzeuge Liste mit";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Ein Element zur Liste hinzufügen.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Erzeugt eine Liste aus den angegebenen Elementen.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "das erste";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "von hinten das";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "das";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "nimm";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "nimm und entferne";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "das letzte";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "ein zufälliges";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "entferne";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "Element";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Extrahiert das erste Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Extrahiert das Element an der angegebenen Position in der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Extrahiert das letzte Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Extrahiert ein zufälliges Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Extrahiert und entfernt das erste Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Extrahiert und entfernt das Element an der angegebenen Position aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Extrahiert und entfernt das letzte Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Extrahiert und entfernt ein zufälliges Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Entfernt das erste Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Entfernt das Element an der angegebenen Position aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Entfernt das letzte Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Entfernt ein zufälliges Element aus der Liste.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "bis von hinten";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "bis";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "bis letztes";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "nimm Teilliste ab erstes";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "nimm Teilliste ab von hinten";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "nimm Teilliste ab";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "Element";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Erstellt eine Kopie mit dem angegebenen Abschnitt der Liste.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ist das letzte Element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ist das erste Element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "suche erstes Auftreten von";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "suche letztes Auftreten von";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Sucht die Position (Index) eines Elementes in der Liste. Gibt %1 zurück, falls kein Element gefunden wurde.";
                +Blockly.Msg["LISTS_INLIST"] = "in der Liste";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ist leer";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Ist wahr, falls die Liste leer ist.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "Länge von %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Die Anzahl von Elementen in der Liste.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "erzeuge Liste mit %2 mal dem Element %1​";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Erzeugt eine Liste mit einer variablen Anzahl von Elementen";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "kehre %1 um";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Kehre eine Kopie einer Liste um.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "ein";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "füge als";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "setze für";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Fügt das Element an den Anfang der Liste an.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Fügt das Element an der angegebenen Position in die Liste ein.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Fügt das Element ans Ende der Liste an.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Fügt das Element zufällig in die Liste ein.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Setzt das erste Element in der Liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Setzt das Element an der angegebenen Position in der Liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Setzt das letzte Element in die Liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Setzt ein zufälliges Element in der Liste.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "aufsteigend";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "absteigend";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "%1 %2 %3 sortieren";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Eine Kopie einer Liste sortieren.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetisch, Großschreibung ignorieren";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerisch";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetisch";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "Liste aus Text erstellen";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "Text aus Liste erstellen";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Liste mit Texten in einen Text vereinen, getrennt durch ein Trennzeichen.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Text in eine Liste mit Texten aufteilen, unterbrochen bei jedem Trennzeichen.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "mit Trennzeichen";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "unwahr";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Ist entweder wahr oder unwahr";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "wahr";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://de.wikipedia.org/wiki/Vergleich_%28Zahlen%29";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Ist wahr, falls beide Werte gleich sind.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Ist wahr, falls der erste Wert größer als der zweite Wert ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Ist wahr, falls der erste Wert größer als oder gleich groß wie der zweite Wert ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Ist wahr, falls der erste Wert kleiner als der zweite Wert ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Ist wahr, falls der erste Wert kleiner als oder gleich groß wie der zweite Wert ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Ist wahr, falls beide Werte unterschiedlich sind.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nicht %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Ist wahr, falls der Eingabewert unwahr ist.  Ist unwahr, falls der Eingabewert wahr ist.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://de.wikipedia.org/wiki/Nullwert";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Ist \"null\".";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "und";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "oder";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Ist wahr, falls beide Werte wahr sind.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Ist wahr, falls einer der beiden Werte wahr ist.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "prüfe";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://de.wikipedia.org/wiki/%3F:#Auswahloperator";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "falls unwahr";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "falls wahr";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Überprüft eine Bedingung \"prüfe\". Falls die Bedingung wahr ist, wird der \"falls wahr\" Wert zurückgegeben, andernfalls der \"falls unwahr\" Wert";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://de.wikipedia.org/wiki/Grundrechenart";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Ist die Summe zweier Zahlen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Ist der Quotient zweier Zahlen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Ist die Differenz zweier Zahlen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Ist das Produkt zweier Zahlen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Ist die erste Zahl potenziert mit der zweiten Zahl.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://de.wikipedia.org/wiki/Inkrement_und_Dekrement";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "erhöhe %1 um %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Addiert eine Zahl zu \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://de.wikipedia.org/wiki/Mathematische_Konstante";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Mathematische Konstanten wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "begrenze %1 zwischen %2 und %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Begrenzt eine Zahl auf den Wertebereich zwischen zwei anderen Zahlen (inklusiv).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ist teilbar durch";
                +Blockly.Msg["MATH_IS_EVEN"] = "ist gerade";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ist negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "ist ungerade";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ist positiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "ist eine Primzahl";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Überprüft ob eine Zahl gerade, ungerade, eine Primzahl, ganzzahlig, positiv, negativ oder durch eine zweite Zahl teilbar ist.  Gibt wahr oder unwahr zurück.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "ist eine ganze Zahl";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://de.wikipedia.org/wiki/Modulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "Rest von %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Der Rest nach einer Division.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://de.wikipedia.org/wiki/Zahl";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Eine Zahl.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "http://www.sysplus.ch/einstieg.php?links=menu&seite=4125&grad=Crash&prog=Excel";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "Mittelwert der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Maximalwert der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Median der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Minimalwert der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "am häufigsten in der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Zufallswert aus der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "Standardabweichung der Liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Summe über die Liste";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Ist der Durchschnittswert aller Zahlen in einer Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Ist die größte Zahl in einer Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Ist der Median aller Zahlen in einer Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Ist die kleinste Zahl in einer Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Findet die Werte mit dem häufigstem Vorkommen in der Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Gibt einen zufälligen Wert aus der Liste zurück.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Ist die Standardabweichung aller Werte in der Liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Ist die Summe aller Zahlen in einer Liste.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://de.wikipedia.org/wiki/Zufallszahlen";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "Zufallszahl (0.0 - 1.0)";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Erzeugt eine Zufallszahl zwischen 0.0 (inklusiv) und 1.0 (exklusiv).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://de.wikipedia.org/wiki/Zufallszahlen";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "ganzzahlige Zufallszahl zwischen %1 und %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Erzeugt eine ganzzahlige Zufallszahl zwischen zwei Zahlen (inklusiv).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://de.wikipedia.org/wiki/Runden";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "runde";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "runde ab";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "runde auf";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Eine Zahl auf- oder abrunden.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://de.wikipedia.org/wiki/Quadratwurzel";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "Betrag";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "Quadratwurzel";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Ist der Betrag einer Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Ist Wert der Exponentialfunktion einer Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Ist der natürliche Logarithmus einer Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Ist der dekadische Logarithmus einer Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Negiert eine Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Rechnet 10 hoch eine Zahl.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Ist die Quadratwurzel einer Zahl.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://de.wikipedia.org/wiki/Trigonometrie";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Ist der Arkuskosinus des Eingabewertes.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Ist der Arkussinus des Eingabewertes.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Ist der Arkustangens des Eingabewertes.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Ist der Kosinus des Winkels.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Ist der Sinus des Winkels.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Ist der Tangens des Winkels.";
                +Blockly.Msg["NEW_VARIABLE"] = "Variable erstellen …";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Name der neuen Variable:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = ".";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "Anweisungen erlauben";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "mit:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://de.wikipedia.org/wiki/Unterprogramm";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Rufe einen Funktionsblock ohne Rückgabewert auf.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://de.wikipedia.org/wiki/Unterprogramm";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Rufe einen Funktionsblock mit Rückgabewert auf.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "mit:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Erzeuge \"Aufruf %1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Beschreibe diese Funktion …";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "etwas tun";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Ein Funktionsblock ohne Rückgabewert.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "gib zurück";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Ein Funktionsblock mit Rückgabewert.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warnung: Dieser Funktionsblock hat zwei gleich benannte Parameter.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Markiere Funktionsblock";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Gibt den zweiten Wert zurück und verlässt die Funktion, falls der erste Wert wahr ist.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warnung: Dieser Block darf nur innerhalb eines Funktionsblocks genutzt werden.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Variable:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Eine Eingabe zur Funktion hinzufügen.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "Parameter";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Die Eingaben zu dieser Funktion hinzufügen, entfernen oder neu anordnen.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Eine Prozedur namens „%1“ ist bereits vorhanden.";
                +Blockly.Msg["REDO"] = "Wiederholen";
                +Blockly.Msg["REMOVE_COMMENT"] = "Kommentar entfernen";
                +Blockly.Msg["RENAME_VARIABLE"] = "Variable umbenennen …";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Alle \"%1\" Variablen umbenennen in:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "zu %1 Text %2 anhängen";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Text an die Variable \"%1\" anhängen.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "wandel um in kleinbuchstaben";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "wandel um in Substantive";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "wandel um in GROSSBUCHSTABEN";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Wandelt Schreibweise von Texten um, in Großbuchstaben, Kleinbuchstaben oder den ersten Buchstaben jedes Wortes groß und die anderen klein.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "nimm ersten";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "nimm von hinten";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "nimm";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "nimm letzten";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "nimm zufälligen";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "Buchstaben";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "im Text %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Extrahiert einen Buchstaben von einer bestimmten Position.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "zähle %1 in %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Zähle, wie oft ein Text innerhalb eines anderen Textes vorkommt.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Ein Element zum Text hinzufügen.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "verbinden";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Hinzufügen, entfernen und sortieren von Elementen.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "bis von hinten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "bis";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "bis letzter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "im Text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "nimm Teil ab erster";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "nimm Teil ab von hinten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "nimm Teil ab";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "Buchstabe";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Gibt den angegebenen Textabschnitt zurück.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "suche erstes Auftreten des Begriffs";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "suche letztes Auftreten des Begriffs";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "im Text %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Findet das erste / letzte Auftreten eines Suchbegriffs in einem Text.  Gibt die Position des Begriffs zurück oder %1 falls der Suchbegriff nicht gefunden wurde.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ist leer";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Ist wahr, falls der Text keine Zeichen enthält ist.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "erstelle Text aus";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Erstellt einen Text durch das Verbinden von mehreren Textelementen.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "Länge von %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Die Anzahl von Zeichen in einem Text (inkl. Leerzeichen).";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "gib aus %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Gibt den Text aus.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Fragt den Benutzer nach einer Zahl.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Fragt den Benutzer nach einem Text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "frage nach Zahl mit Hinweis";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "frage nach Text mit Hinweis";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "ersetze %1 durch %2 in %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Ersetze alle Vorkommen eines Textes innerhalb eines anderen Textes.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "kehre %1 um";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Kehre die Reihenfolge der Zeichen im Text um.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://de.wikipedia.org/wiki/Zeichenkette";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Ein Buchstabe, Text oder Satz.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "entferne Leerzeichen vom Anfang und vom Ende (links und rechts)";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "entferne Leerzeichen vom Anfang (links)";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "entferne Leerzeichen vom Ende (rechts)";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Entfernt Leerzeichen vom Anfang und / oder Ende eines Textes.";
                +Blockly.Msg["TODAY"] = "Heute";
                +Blockly.Msg["UNDO"] = "Rückgängig";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "etwas";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Erzeuge \"Schreibe %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Gibt den Wert der Variable zurück.";
                +Blockly.Msg["VARIABLES_SET"] = "setze %1 auf %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Erzeuge \"Lese %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Setzt den Wert einer Variable.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Eine Variable namens „%1“ ist bereits vorhanden.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/diq.js b/blockly/webif/static/blockly/msg/js/diq.js
                new file mode 100644
                index 000000000..30bd506f0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/diq.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.diq');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Tefsir cı ke";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Erci bıvurne:";
                +Blockly.Msg["CLEAN_UP"] = "Blokan pak ke";
                +Blockly.Msg["COLLAPSE_ALL"] = "Blokan teng ke";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Bloki teng ke";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "reng 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "reng 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "nısbet";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "tewde";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://diq.wikipedia.org/wiki/Reng";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Şıma palet ra yew reng weçinê.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "rengo rastameye";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Tesadufi yu ren bıweçin";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "kewe";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "kıho";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "sur";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "komponentên rengan";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Şıma renganê sûr, aşıl u kohoy ra rengê do spesifik vırazê. Gani ê pêro 0 u 100 miyan de bıbê.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "Çerxen ra vec";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "Gama bin da çerxeni ra dewam ke";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Öujtewada çerxeni ra bıvıci";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Diqat: No bloke şeno teyna yew çerxiyayış miyan de bıgırweyo.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "Lista %2 de her item %1 rê";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Yew lista de her item rê, varyansê '%1' itemi rê vırazê, u dıma tayê akerdışi (beyani) bıdê";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Bloq da if'i rê yu şert dekerê de.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "çıniyose";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "niyose";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Eger yew vaye raşto, o taw şıma tayê akerdışi kerê.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "bıke";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 fıni tekrar ke";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Şıma tayêna reyi akerdışi kerê.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "hend tekrar ke";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "Tekrar kerdış de";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Yew erc xırabo se tay beyanati bıd";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Yew erc raşto se yu beyanat bıd.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Pêro %1 bloki besteriyê?";
                +Blockly.Msg["DELETE_BLOCK"] = "Bloki bestere";
                +Blockly.Msg["DELETE_VARIABLE"] = "Şıma vırnaoğê '%1'i besterê";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "%1 ke vırnayışê '%2'i gırweneno, besteriyo?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 blokan bestere";
                +Blockly.Msg["DISABLE_BLOCK"] = "Çengi devre ra vec";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Zewnc";
                +Blockly.Msg["ENABLE_BLOCK"] = "Bloki feal ke";
                +Blockly.Msg["EXPAND_ALL"] = "Blokan hera ke";
                +Blockly.Msg["EXPAND_BLOCK"] = "Bloki hera ke";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Cıkewtışê xarıciy";
                +Blockly.Msg["HELP"] = "Peşti";
                +Blockly.Msg["INLINE_INPUTS"] = "Cıkerdışê xomiyani";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "lista venge vıraze";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "Liste ya vıraz";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Yew nesne dekerê lista miyan";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "verên";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# peyniye ra";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "bıgê";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "Bıgi u wedarne";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "peyên";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "raştameye";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "wedare";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "Peyni # ra hetana";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "#'ya";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "Hetana pey";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 objeyo peyên o";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 objeyo sıfteyên o";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Sıfte bıyayena cay obcey bıvin";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "lista de";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 vengo";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Eger kı lista venga se raşt keno çerğ";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Derganiya yu lister dano.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "zey";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "De fi";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "ca ke";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "zeydıyen";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "Kemeyen";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "Kılm %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "Amoriyal";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "Alfabetik";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "Hududoxi ya";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ğelet";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Raşt yana çep erc dano";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "raşt";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 niyo";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "veng";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Veng çarneno ra.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "û";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ya zi";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Eger her dı cıkewtışi zi raştê, şıma ageyrê.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "eke ğeleto";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "eke raşto";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Şerta'test'i test keno.  Eger ke şert raşta se erca 'raşt'i çarneno, çepo se erca 'çep'  çarneno.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%2, keno %1 vurneno";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Heryen sabitan ra yewi çerx ke:π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (bêsonp).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "Leteyêno";
                +Blockly.Msg["MATH_IS_EVEN"] = "zewnco";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "negatifo";
                +Blockly.Msg["MATH_IS_ODD"] = "kıto";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "pozitifo";
                +Blockly.Msg["MATH_IS_PRIME"] = "bıngehên";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "tamo";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 ra menden";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Dı amoran ra amora menden çerx ke";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://diq.wikipedia.org/wiki/Numre";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Yew numre.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "Averacê lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Tewr gırdê lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Wertey lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Tewr qıcê lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "listey modi";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Raştamaye objeya lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "koma liste";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Liste ra raştamaye yew elementi çerx ke";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "Raştamaye nimande amor";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "gılor ke";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "Loğê cêri ke";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "Loğê cori ke";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Yu amorer loğê cêri yana cori ke";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "mutlaq";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "karekok";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Ena amorer nêravêrde deyne çerx ke.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "Vuriyayeyo bıvıraz...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Namey vuriyayeyê newi:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "Çıyan rê mısafe bıd";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ebe:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ebe:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' vıraze";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Nê fonksiyoni beyan ke...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "Çıyê bık";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "rê";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Yew fonksiyono çap nêdate vırazeno";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "peyser biya";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Yew fonksiyono çap daye vırazeno";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "namey cıkewtışi:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "cıkewtışi";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Newe ke";
                +Blockly.Msg["REMOVE_COMMENT"] = "Tefsiri Wedare";
                +Blockly.Msg["RENAME_VARIABLE"] = "Vuriyayey fına name ke...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Pêro vırnayışê '%1' reyna name ke:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "Herfanê werdiyana";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Ser herf gırd";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "HERFANÊ GIRDANA";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "Herfa sıfti bıgi";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "# ra tepya herfan bıgi";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "Herfa # bıgi";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "Herfa peyên bıgi";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "Raştamaye yu herf bıgi";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Şınasnaye pozisyon de yu herfer çerğ keno";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "gıre de";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "metın de";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "# ra substring gêno";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Tay letey metini çerğ keno";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 vengo";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ya metin vıraz";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Yu herfa,  satır yana çekuya metini";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Ewro";
                +Blockly.Msg["UNDO"] = "Peyser biya";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "unsur";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'get %1' vıraz";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Yew vırnayış be namey '%1' xora est.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/el.js b/blockly/webif/static/blockly/msg/js/el.js
                new file mode 100644
                index 000000000..e7a6840a8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/el.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.el');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Πρόσθεσε Το Σχόλιο";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Άλλαξε την τιμή:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Σύμπτυξε Όλα Τα Μπλοκ";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Σύμπτυξε Το Μπλοκ";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "χρώμα 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "χρώμα 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "αναλογία";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "μείγμα";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Συνδυάζει δύο χρώματα μαζί με μια δεδομένη αναλογία (0.0 - 1,0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%A7%CF%81%CF%8E%CE%BC%CE%B1";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Επιτρέπει επιλογή χρώματος από την παλέτα.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "τυχαίο χρώμα";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Επιλέγει χρώμα τυχαία.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "μπλε";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "πράσινο";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "κόκκινο";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "χρώμα με";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Δημιουργεί χρώμα με το συγκεκριμένο ποσό του κόκκινου, πράσινου και μπλε που ορίζεις. Όλες οι τιμές πρέπει να είναι μεταξύ 0 και 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "φεύγει από το μπλοκ επαναλήψεως";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "συνέχισε με την επόμενη επανάληψη του μπλοκ επαναλήψεως";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Ξεφεύγει (βγαίνει έξω) από την επανάληψη.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Παραλείπει το υπόλοιπο τμήμα αυτού του μπλοκ επαναλήψεως, και συνεχίζει με την επόμενη επανάληψη.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Προειδοποίηση: Αυτό το μπλοκ μπορεί να χρησιμοποιηθεί μόνο μέσα σε μια επανάληψη.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "για κάθε στοιχείο %1 στη λίστα %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Για κάθε στοιχείο σε μια λίστα, ορίζει τη μεταβλητή «%1» στο στοιχείο και, στη συνέχεια, εκτελεί κάποιες εντολές.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "Blockly";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "μέτρησε με %1 από το %2 έως το %3 ανά %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Η μεταβλητή «%1» παίρνει τιμές ξεκινώντας από τον αριθμό έναρξης μέχρι τον αριθμό τέλους αυξάνοντας κάθε φορά με το καθορισμένο βήμα και εκτελώντας το καθορισμένο μπλοκ.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Πρόσθετει μια κατάσταση/συνθήκη στο μπλοκ «εάν».";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Προσθέτει μια τελική κατάσταση/συνθήκη, που πιάνει όλες τις άλλες περιπτώσεις, στο μπλοκ «εάν».";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Προσθέτει, αφαιρεί ή αναδιατάσσει τα τμήματα για να αναδιαμορφώσει αυτό το μπλοκ «εάν».";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "αλλιώς";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "εναλλακτικά εάν";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "εάν";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Αν μια τιμή είναι αληθής, τότε εκτελεί κάποιες εντολές.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Αν μια τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών. Διαφορετικά, εκτελεί το δεύτερο τμήμα εντολών.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Αν η πρώτη τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών. Διαφορετικά, αν η δεύτερη τιμή είναι αληθής, εκτελεί το δεύτερο μπλοκ εντολών.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Αν η πρώτη τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών.  Διαφορετικά, αν η δεύτερη τιμή είναι αληθής, εκτελεί το δεύτερο τμήμα εντολών. Αν καμία από τις τιμές δεν είναι αληθής, εκτελεί το τελευταίο τμήμα εντολών.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "κάνε";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "επανάλαβε %1 φορές";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Εκτελεί κάποιες εντολές αρκετές φορές.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "επανάλαβε μέχρι";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "επανάλαβε ενώ";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Ενόσω μια τιμή είναι ψευδής, τότε εκτελεί κάποιες εντολές.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Ενόσω μια τιμή είναι αληθής, τότε εκτελεί κάποιες εντολές.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Να διαγραφούν και τα %1 μπλοκ;";
                +Blockly.Msg["DELETE_BLOCK"] = "Διάγραψε Το Μπλοκ";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Διάγραψε %1 Μπλοκ";
                +Blockly.Msg["DISABLE_BLOCK"] = "Απενεργοποίησε Το Μπλοκ";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Διπλότυπο";
                +Blockly.Msg["ENABLE_BLOCK"] = "Ενεργοποίησε Το Μπλοκ";
                +Blockly.Msg["EXPAND_ALL"] = "Επέκτεινε Όλα Τα Μπλοκ";
                +Blockly.Msg["EXPAND_BLOCK"] = "Επέκτεινε Το Μπλοκ";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Εξωτερικές Είσοδοι";
                +Blockly.Msg["HELP"] = "Βοήθεια";
                +Blockly.Msg["INLINE_INPUTS"] = "Εσωτερικές Είσοδοι";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "δημιούργησε κενή λίστα";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Επιστρέφει μια λίστα, με μήκος 0, η οποία δεν περιέχει εγγραφές δεδομένων";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "λίστα";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Προσθέτει, αφαιρεί ή αναδιατάσσει τα τμήματα για να αναδιαμορφώσει αυτό το μπλοκ λίστας.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "δημιούργησε λίστα με";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Προσθέτει αντικείμενο στη λίστα.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Δημιουργεί λίστα με οποιονδήποτε αριθμό αντικειμένων.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "πρώτο";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# από το τέλος";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "πάρε";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "πάρε και αφαίρεσε";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "τελευταίο";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "τυχαίο";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "αφαίρεσε";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Επιστρέφει το πρώτο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Επιστρέφει το στοιχείο στην καθορισμένη θέση σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Επιστρέφει το τελευταίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Επιστρέφει ένα τυχαίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Καταργεί και επιστρέφει το πρώτο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Καταργεί και επιστρέφει το στοιχείο στην καθορισμένη θέση σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Καταργεί και επιστρέφει το τελευταίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Καταργεί και επιστρέφει ένα τυχαίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Καταργεί το πρώτο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Καταργεί το στοιχείο στην καθορισμένη θέση σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Καταργεί το τελευταίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Καταργεί ένα τυχαίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "έως # από το τέλος";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "έως #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "έως το τελευταίο";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "Blockly";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "πάρε υπολίστα από την αρχή";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "πάρε υπολίστα από # από το τέλος";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "πάρε υπολίστα από #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Δημιουργεί ένα αντίγραφο του καθορισμένου τμήματος μιας λίστας.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Το %1 είναι το τελευταίο στοιχείο.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Το %1 είναι το πρώτο στοιχείο.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "βρες την πρώτη εμφάνιση του στοιχείου";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "Blockly";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "βρες την τελευταία εμφάνιση του στοιχείου";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Επιστρέφει τον δείκτη της πρώτης/τελευταίας εμφάνισης του στοιχείου στη λίστα.  Επιστρέφει τιμή %1, αν το στοιχείο δεν βρεθεί.";
                +Blockly.Msg["LISTS_INLIST"] = "στη λίστα";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "το %1 είναι κενό";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Επιστρέφει αληθής αν η λίστα είναι κενή.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "Blockly";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "το μήκος του %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Επιστρέφει το μήκος μιας λίστας.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "Blockly";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "δημιούργησε λίστα με το στοιχείο %1 να επαναλαμβάνεται %2 φορές";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Δημιουργεί μια λίστα που αποτελείται από την δεδομένη τιμή που επαναλαμβάνεται για συγκεκριμένο αριθμό επαναλήψεων.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "σε";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "είσαγε στο";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "όρισε";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Εισάγει το στοιχείο στην αρχή μιας λίστας.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Εισάγει το στοιχείο στην καθορισμένη θέση σε μια λίστα.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Αναθέτει το στοιχείο στο τέλος μιας λίστας.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Εισάγει το στοιχείο τυχαία σε μια λίστα.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Ορίζει το πρώτο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Ορίζει το στοιχείο στην καθορισμένη θέση σε μια λίστα.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Ορίζει το τελευταίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Ορίζει ένα τυχαίο στοιχείο σε μια λίστα.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "Αύξουσα";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "Φθίνουσα";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "αριθμητικό";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "Αλφαβητικά";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "κάνετε λίστα από το κείμενο";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "κάνετε κείμενο από τη λίστα";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Ενώστε μια λίστα κειμένων σε ένα κείμενο, που χωρίζονται από ένα διαχωριστικό.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Διαίρεση του κειμένου σε μια λίστα κειμένων, με σπάσιμο σε κάθε διαχωριστικό.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "με διαχωριστικό";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ψευδής";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Επιστρέφει είτε αληθής είτε ψευδής.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "αληθής";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Επιστρέφει αληθής αν και οι δύο είσοδοι είναι ίσες μεταξύ τους.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μεγαλύτερη από τη δεύτερη είσοδο.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη ή ίση με τη δεύτερη είσοδο.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη από τη δεύτερη είσοδο.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη από ή ίση με τη δεύτερη είσοδο.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Επιστρέφει αληθής αν και οι δύο είσοδοι δεν είναι ίσες μεταξύ τους.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "όχι %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Επιστρέφει αληθής αν η είσοδος είναι ψευδής. Επιστρέφει ψευδής αν η είσοδος είναι αληθής.";
                +Blockly.Msg["LOGIC_NULL"] = "κενό";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Επιστρέφει κενό.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "και";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ή";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Επιστρέφει αληθής αν και οι δύο είσοδοι είναι αληθής.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Επιστρέφει αληθής αν τουλάχιστον μια από τις εισόδους είναι αληθής.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "έλεγχος";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "εάν είναι ψευδής";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "εάν είναι αληθής";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Ελέγχει την κατάσταση/συνθήκη στον «έλεγχο». Αν η κατάσταση/συνθήκη είναι αληθής, επιστρέφει την τιμή «εάν αληθής», διαφορετικά επιστρέφει την τιμή «εάν ψευδής».";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CE%B7%CF%84%CE%B9%CE%BA%CE%AE";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Επιστρέφει το άθροισμα των δύο αριθμών.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Επιστρέφει το πηλίκο των δύο αριθμών.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Επιστρέφει τη διαφορά των δύο αριθμών.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Επιστρέφει το γινόμενο των δύο αριθμών.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Επιστρέφει τον πρώτο αριθμό υψωμένο στη δύναμη του δεύτερου αριθμού.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%A0%CF%81%CF%8C%CF%83%CE%B8%CE%B5%CF%83%CE%B7";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "άλλαξε %1 από %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Προσθέτει έναν αριθμό στη μεταβλητή «%1».";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Επιστρέφει μία από τις κοινές σταθερές: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...), ή ∞ (άπειρο).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "περιόρισε %1 χαμηλή %2 υψηλή %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Περιορίζει έναν αριθμό μεταξύ των προβλεπόμενων ορίων (χωρίς αποκλεισμούς).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "είναι διαιρετός από το";
                +Blockly.Msg["MATH_IS_EVEN"] = "είναι άρτιος";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "είναι αρνητικός";
                +Blockly.Msg["MATH_IS_ODD"] = "είναι περιττός";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "είναι θετικός";
                +Blockly.Msg["MATH_IS_PRIME"] = "είναι πρώτος";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Ελέγχει αν ένας αριθμός είναι άρτιος, περιττός, πρώτος, ακέραιος, θετικός, αρνητικός, ή αν είναι διαιρετός από έναν ορισμένο αριθμό. Επιστρέφει αληθής ή ψευδής.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "είναι ακέραιος";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "υπόλοιπο της %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Επιστρέφει το υπόλοιπο της διαίρεσης των δύο αριθμών.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Ένας αριθμός.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "μέσος όρος λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "μεγαλύτερος λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "διάμεσος λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "μικρότερος λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "μορφές λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "τυχαίο στοιχείο λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "τυπική απόκλιση λίστας";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "άθροισμα λίστας";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Επιστρέφει τον αριθμητικό μέσο όρο από τις αριθμητικές τιμές στη λίστα.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Επιστρέφει τον μεγαλύτερο αριθμό στη λίστα.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Επιστρέφει τον διάμεσο της λίστας.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Επιστρέφει τον μικρότερο αριθμό στη λίστα.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Επιστρέφει μια λίστα με τα πιο κοινά στοιχεία στη λίστα.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Επιστρέφει ένα τυχαίο στοιχείο από τη λίστα.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Επιστρέφει την τυπική απόκλιση της λίστας.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Επιστρέφει το άθροισμα όλων των αριθμών στη λίστα.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^ ύψωση σε δύναμη";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%93%CE%B5%CE%BD%CE%BD%CE%AE%CF%84%CF%81%CE%B9%CE%B1_%CE%A4%CF%85%CF%87%CE%B1%CE%AF%CF%89%CE%BD_%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8E%CE%BD";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "τυχαίο κλάσμα";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Επιστρέψει ένα τυχαία κλάσμα μεταξύ 0,0 (κλειστό) και 1,0 (ανοικτό).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "τυχαίος ακέραιος από το %1 έως το %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Επιστρέφει έναν τυχαίο ακέραιο αριθμό μεταξύ δύο συγκεκριμένων ορίων (εντός - συμπεριλαμβανομένων και των ακραίων τιμών).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "στρογγυλοποίησε";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "στρογγυλοποίησε προς τα κάτω";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "στρογγυλοποίησε προς τα πάνω";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Στρογγυλοποιεί έναν αριθμό προς τα πάνω ή προς τα κάτω.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%A4%CE%B5%CF%84%CF%81%CE%B1%CE%B3%CF%89%CE%BD%CE%B9%CE%BA%CE%AE_%CF%81%CE%AF%CE%B6%CE%B1";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "απόλυτη";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "τετραγωνική ρίζα";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Επιστρέφει την απόλυτη τιμή ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Επιστρέφει το e υψωμένο στη δύναμη ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Επιστρέφει τον νεπέρειο λογάριθμο ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Επιστρέφει τον λογάριθμο με βάση το 10 ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Επιστρέφει την αρνητική ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Επιστρέφει το 10 υψωμένο στη δύναμη ενός αριθμού.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Επιστρέφει την τετραγωνική ρίζα ενός αριθμού.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "συν";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%A4%CF%81%CE%B9%CE%B3%CF%89%CE%BD%CE%BF%CE%BC%CE%B5%CF%84%CF%81%CE%B9%CE%BA%CE%AE_%CF%83%CF%85%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7";
                +Blockly.Msg["MATH_TRIG_SIN"] = "ημ";
                +Blockly.Msg["MATH_TRIG_TAN"] = "εφ";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Επιστρέφει το τόξο συνημίτονου ενός αριθμού.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Επιστρέφει το τόξο ημίτονου ενός αριθμού.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Επιστρέφει το τόξο εφαπτομένης ενός αριθμού.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Επιστρέφει το συνημίτονο ενός βαθμού (όχι ακτινίου).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Επιστρέφει το ημίτονο ενός βαθμού (όχι ακτινίου).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Επιστρέφει την εφαπτομένη ενός βαθμού (όχι ακτινίου).";
                +Blockly.Msg["NEW_VARIABLE"] = "Νέα μεταβλητή...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Νέο όνομα μεταβλητής:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "να επιτρέπονται οι δηλώσεις";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "με:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%94%CE%B9%CE%B1%CE%B4%CE%B9%CE%BA%CE%B1%CF%83%CE%AF%CE%B1_%28%CF%85%CF%80%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CF%83%CF%84%CE%AD%CF%82%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Εκτελεί την ορισμένη από τον χρήστη συνάρτηση «%1».";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%94%CE%B9%CE%B1%CE%B4%CE%B9%CE%BA%CE%B1%CF%83%CE%AF%CE%B1_%28%CF%85%CF%80%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CF%83%CF%84%CE%AD%CF%82%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Εκτελεί την ορισμένη από τον χρήστη συνάρτηση «%1» και χρησιμοποίησε την έξοδό της.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "με:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Δημιούργησε «%1»";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "κάνε κάτι";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "στο";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Δημιουργεί μια συνάρτηση χωρίς έξοδο.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "επέστρεψε";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Δημιουργεί μια συνάρτηση με μια έξοδο.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Προειδοποίηση: Αυτή η συνάρτηση έχει διπλότυπες παραμέτρους.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Επισημάνετε τον ορισμό συνάρτησης";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Αν μια τιμή είναι αληθής, τότε επιστρέφει τη δεύτερη τιμή.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Προειδοποίηση: Αυτό το μπλοκ μπορεί να χρησιμοποιηθεί μόνο στον ορισμό μιας συνάρτησης.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "όνομα εισόδου:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Πρόσθεσε μια είσοδος στη συνάρτηση";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "είσοδοι";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Προσθέτει, αφαιρεί ή αναδιατάσσει εισόδους σε αυτήν τη λειτουργία";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Ακύρωση αναίρεσης";
                +Blockly.Msg["REMOVE_COMMENT"] = "Αφαίρεσε Το Σχόλιο";
                +Blockly.Msg["RENAME_VARIABLE"] = "Μετονόμασε τη μεταβλητή...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Μετονόμασε όλες τις μεταβλητές «%1» σε:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Αναθέτει κείμενο στη μεταβλητή «%1».";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "σε πεζά";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "σε Λέξεις Με Πρώτα Κεφαλαία";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "σε ΚΕΦΑΛΑΙΑ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Επιστρέφει ένα αντίγραφο του κειμένου σε διαφορετική μορφή γραμμάτων.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "πάρε το πρώτο γράμμα";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "πάρε το γράμμα # από το τέλος";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "πάρε το γράμμα #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "πάρε το τελευταίο γράμμα";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "πάρε τυχαίο γράμμα";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Επιστρέφει το γράμμα στην καθορισμένη θέση.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Μετρά πόσες φορές κάποιο κείμενο εμφανίζεται μέσα σε ένα άλλο κείμενο.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Προσθέτει ένα στοιχείο στο κείμενο.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ένωσε";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Προσθέτει, αφαιρεί ή αναδιατάσσει τους τομείς για να αναδιαμορφώσει αυτό το μπλοκ κειμένου.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "μέχρι το # γράμμα από το τέλος";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "μέχρι το # γράμμα";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "μέχρι το τελευταίο γράμμα";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "στο κείμενο";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "πάρε τη δευτερεύουσα συμβολοσειρά από το πρώτο γράμμα";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "πάρε τη δευτερεύουσα συμβολοσειρά από το # γράμμα από το τέλος";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "πάρε τη δευτερεύουσα συμβολοσειρά από το # γράμμα";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Επιστρέφει ένα συγκεκριμένο τμήμα του κειμένου.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "βρες την πρώτη εμφάνιση του κειμένου";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "βρες την τελευταία εμφάνιση του κειμένου";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Επιστρέφει τον δείκτη της πρώτης/τελευταίας εμφάνισης του πρώτου κειμένου στο δεύτερο κείμενο.  Επιστρέφει τιμή %1, αν δε βρει το κείμενο.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "το %1 είναι κενό";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Επιστρέφει αληθής αν το παρεχόμενο κείμενο είναι κενό.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "δημιούργησε κείμενο με";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Δημιουργεί ένα κομμάτι κειμένου ενώνοντας έναν  απεριόριστο αριθμό αντικειμένων.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "το μήκος του %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Επιστρέφει το πλήθος των γραμμάτων (συμπεριλαμβανομένων και των κενών διαστημάτων) στο παρεχόμενο κείμενο.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "εκτύπωσε %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Εκτυπώνει το καθορισμένο κείμενο, αριθμό ή άλλη τιμή.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Δημιουργεί προτροπή για τον χρήστη για να δώσει ένα αριθμό.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Δημιουργεί προτροπή για το χρήστη για να δώσει κάποιο κείμενο.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "πρότρεψε με μήνυμα για να δοθεί αριθμός";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "πρότρεψε με μήνυμα για να δοθεί κείμενο";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://el.wikipedia.org/wiki/%CE%A3%CF%85%CE%BC%CE%B2%CE%BF%CE%BB%CE%BF%CF%83%CE%B5%CE%B9%CF%81%CE%AC";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Ένα γράμμα, μια λέξη ή μια γραμμή κειμένου.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "περίκοψε τα κενά και από τις δυο πλευρές του";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "περίκοψε τα κενά από την αριστερή πλευρά του";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "περίκοψε τα κενά από την δεξιά πλευρά του";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Επιστρέφει ένα αντίγραφο του κειμένου με αφαιρεμένα τα κενά από το ένα ή και τα δύο άκρα.";
                +Blockly.Msg["TODAY"] = "Σήμερα";
                +Blockly.Msg["UNDO"] = "Αναίρεση";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "αντικείμενο";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Δημιούργησε «όρισε %1»";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Επιστρέφει την τιμή αυτής της μεταβλητής.";
                +Blockly.Msg["VARIABLES_SET"] = "όρισε %1 μέχρι το %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Δημιούργησε «πάρε %1»";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Ορίζει αυτή τη μεταβλητή να είναι ίση με την είσοδο.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/en-gb.js b/blockly/webif/static/blockly/msg/js/en-gb.js
                new file mode 100644
                index 000000000..d20e6a59d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/en-gb.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.en.gb');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Add Comment";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Change value:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";
                +Blockly.Msg["COLLAPSE_ALL"] = "Collapse Blocks";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Collapse Block";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "colour 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "colour 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ratio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blend";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Colour";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choose a colour from the palette.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "random colour";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Choose a colour at random.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blue";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "green";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "red";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colour with";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue.  All values must be between 0 and 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for each item %1 in list %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "else";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "else if";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "if";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "do";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repeat %1 times";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repeat until";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repeat while";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";
                +Blockly.Msg["DELETE_BLOCK"] = "Delete Block";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Delete %1 Blocks";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disable Block";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicate";
                +Blockly.Msg["ENABLE_BLOCK"] = "Enable Block";
                +Blockly.Msg["EXPAND_ALL"] = "Expand Blocks";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expand Block";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputs";
                +Blockly.Msg["HELP"] = "Help";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "first";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# from end";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "last";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "random";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "in list";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descendente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returns either true or false.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "true";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "not %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "and";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "or";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "if false";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "if true";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";
                +Blockly.Msg["MATH_IS_EVEN"] = "is even";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "is negative";
                +Blockly.Msg["MATH_IS_ODD"] = "is odd";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "is positive";
                +Blockly.Msg["MATH_IS_PRIME"] = "is prime";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "average of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "max of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";  // untranslated
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "New variable...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "New variable name:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";
                +Blockly.Msg["REMOVE_COMMENT"] = "Remove Comment";
                +Blockly.Msg["RENAME_VARIABLE"] = "Rename variable...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Today";
                +Blockly.Msg["UNDO"] = "Undo";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/en.js b/blockly/webif/static/blockly/msg/js/en.js
                new file mode 100644
                index 000000000..9b6576329
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/en.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.en');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Add Comment";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Change value:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";
                +Blockly.Msg["COLLAPSE_ALL"] = "Collapse Blocks";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Collapse Block";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "colour 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "colour 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ratio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blend";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choose a colour from the palette.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "random colour";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Choose a colour at random.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blue";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "green";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "red";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colour with";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for each item %1 in list %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "else";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "else if";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "if";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "do";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repeat %1 times";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repeat until";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repeat while";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";
                +Blockly.Msg["DELETE_BLOCK"] = "Delete Block";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Delete %1 Blocks";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disable Block";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicate";
                +Blockly.Msg["ENABLE_BLOCK"] = "Enable Block";
                +Blockly.Msg["EXPAND_ALL"] = "Expand Blocks";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expand Block";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputs";
                +Blockly.Msg["HELP"] = "Help";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";
                +Blockly.Msg["IOS_ERROR"] = "Error";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "first";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# from end";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "last";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "random";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remove";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";
                +Blockly.Msg["LISTS_INLIST"] = "in list";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returns either true or false.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "true";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "not %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "and";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "or";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "if false";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "if true";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";
                +Blockly.Msg["MATH_IS_EVEN"] = "is even";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "is negative";
                +Blockly.Msg["MATH_IS_ODD"] = "is odd";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "is positive";
                +Blockly.Msg["MATH_IS_PRIME"] = "is prime";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "average of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "max of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "Create variable...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "New variable name:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";
                +Blockly.Msg["REDO"] = "Redo";
                +Blockly.Msg["REMOVE_COMMENT"] = "Remove Comment";
                +Blockly.Msg["RENAME_VARIABLE"] = "Rename variable...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";
                +Blockly.Msg["TODAY"] = "Today";
                +Blockly.Msg["UNDO"] = "Undo";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/eo.js b/blockly/webif/static/blockly/msg/js/eo.js
                new file mode 100644
                index 000000000..beaa3e293
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/eo.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.eo');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Aldoni komenton";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ŝangi valoron:";
                +Blockly.Msg["CLEAN_UP"] = "Purigi blokojn";
                +Blockly.Msg["COLLAPSE_ALL"] = "Faldi blokojn";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Faldi blokon";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "koloro 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "koloro 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporcio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blend";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://eo.wikipedia.org/wiki/Koloro";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Elekti koloron el la paletro.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "hazarda koloro";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Elekti hazardan koloron.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blua";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verda";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ruĝa";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "kolorigi per";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "eliri el la ciklo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "daŭrigi je la venonta ripeto de la ciklo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Eliri el la enhava ciklo.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Pretersalti la ceteron de tiu ĉi ciklo kaj daŭrigi je la venonta ripeto.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Averto: tiu ĉi bloko uzeblas nur ene de ciklo.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "por ĉiu elemento %1 en la listo %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Aldoni kondiĉon al la bloko 'se'";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Aldoni 'aliokaze' kondiĉon al la 'se' bloko.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "alie";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "alie se";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Plenumi ordonojn se la valoro estas vero.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Plenumi la unuan blokon de ordonoj se la valoro estas vero, se ne, la duan.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fari";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ripeti %1 fojojn";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Plenumi kelkajn ordonojn plurfoje.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ripeti ĝis";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ripeti dum";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Plenumi ordonojn dum valoro egalas malvero.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Plenumi ordonojn dum la valoro egalas vero.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Ĉu forigi ĉiujn %1 blokojn?";
                +Blockly.Msg["DELETE_BLOCK"] = "Forigi blokon";
                +Blockly.Msg["DELETE_VARIABLE"] = "Forigi la varianton '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Ĉu forigi %1 uzojn de la varianto '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Forigi %1 blokojn";
                +Blockly.Msg["DISABLE_BLOCK"] = "Malŝalti blokon";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duobligi";
                +Blockly.Msg["ENABLE_BLOCK"] = "Ŝalti blokon";
                +Blockly.Msg["EXPAND_ALL"] = "Malfaldi blokojn";
                +Blockly.Msg["EXPAND_BLOCK"] = "Malfaldi blokon";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Eksteraj eniroj";
                +Blockly.Msg["HELP"] = "Helpo";
                +Blockly.Msg["INLINE_INPUTS"] = "Entekstaj eniroj";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "krei malplenan liston";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Listo, de longo 0, sen datumaj registroj, estos liverita.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "listo";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Aldoni, forigi aŭ oridigi sekciojn por reagordi tiun ĉi blokon de listo.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "krei liston kun";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Aldoni elementon al la listo.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Krei liston kun ajna nombro de elementoj.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "unuan";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "#el la fino";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "akiri";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "akiri kaj forigi";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "lastan";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "hazardan";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "forigi";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "La unua elemento en la listo esto liverita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "La elemento en la specifita pozicio en la listo estos liverita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "La lasta elemento en la listo estos liverita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Hazarda elemento en la listo estos liverita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "La unua elemento en la listo estos liverita kaj forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "La elemento en la specifita pozicio de la listo estos liverita kaj forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "La lasta elemento en la listo estos liverita kaj forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Hazarda elemento en la listo estos liverita kaj forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "La unua elemento en la listo estos forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "La elemento en la specifita pozicio en la listo estos forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "La lasta elemento en la listo estos forigita.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Hazarda elemento en la listo estos forigita.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 estas la lasta elemento.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 estas la unua elemento.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "trovi la unuan aperon de elemento";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "trovi la lastan aperon de elemento";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "La indekso de la unua/lasta apero de la elemento en la listo estos liverita. %1 estos liverita se la elemento ne estas trovita.";
                +Blockly.Msg["LISTS_INLIST"] = "en la listo";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 malplenas";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Vero estos liverita, se la listo malplenas.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longo de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "La longo de listo estos liverita.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "krei liston kun elemento %1 ripetita %2 fojojn";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Listo kun la specifita nombro de elementoj, kiuj havos la donitan valoron, estos kreita.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "kiel";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "enmeti je";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "difini";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falsa";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "La rezulto egalas ĉu vero, ĉu malvero.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "vera";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://eo.wikipedia.org/wiki/Neegala%C4%B5o_(pli_granda,_malpli_granda)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Vero estos liverita, se la du eniroj egalas.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Vero estos liverita, se la unua eniro estas pli granda ol la dua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Vero estos liverita, se la unua eniro estas pli granda aŭ egala al la dua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Vero estos liverita, se la unua eniro estas pli eta ol la dua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Vero estos liverita, se la unua eniro estas pli eta aŭ egala al la dua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Vero estos liverita, se la du eniroj ne egalas.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "maligi %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Se la eniro egalas vero, la rezulto egalas malvero. Se la eniro egalas malvero, la rezulto egalas vero.";
                +Blockly.Msg["LOGIC_NULL"] = "null";  // untranslated
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "kaj";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "aŭ";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Vero estos liverita, se la du eniroj egalas veron.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Vero estos liverita, se almenaŭ unu el la eniroj egalas veron.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "testi";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se estas malvero";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se estas vero";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kontroli la kondiĉon en 'testo'. Se la kondiĉo egalas veron, liveri la valoron 'se estas vero', aliokaze liveri la valoron 'se estas malvero'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://eo.wikipedia.org/wiki/Aritmetiko";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "La sumo de la du nombroj estos liverita.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "La kvociento de la du nombroj estos liverita.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "La diferenco inter la du nombroj estos liverita.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "La produto de la du numeroj estos liverita.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Aldoni nombro al varianto '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://eo.wikipedia.org/wiki/Matematika_konstanto";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "limigi %1 inter %2 kaj %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "La nombro estos limigita tiel ke ĝi egalas la limojn aŭ troviĝas inter ili.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "estas dividebla de";
                +Blockly.Msg["MATH_IS_EVEN"] = "estas para";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "estas negativa";
                +Blockly.Msg["MATH_IS_ODD"] = "estas nepara";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "estas pozitiva";
                +Blockly.Msg["MATH_IS_PRIME"] = "estas primo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Vero aŭ malvero estos liverita, depende de la rezulto de kontrolo, ĉu nombro estas para, nepara, pozitiva, negativa, aŭ dividebla de iu nombro.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "estas entjero";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://eo.wikipedia.org/wiki/Resto";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "La resto de la divido de du nombroj estos liverita.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://eo.wikipedia.org/wiki/Nombro";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Nombro.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "listmezumo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "listmaksimumo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "listminimumo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "reĝimoj de listo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "hazarda elemento el la listo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "Norma devio de la listo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sumo de listo";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "La aritmetika meznombro de la numeroj en la listo estos liverita.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "La plej granda numero en la listo estos redonita.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "La plej eta nombro en la listo estos redonita.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Elemento el la listo estos hazarde liverita.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "La norma devio de la listo estos liverita.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "La sumo de ĉiuj nombro en la listo estos liverita.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "hazarda entjero inter %1 kaj %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Nombro estos hazarde liverita, tiel ke ĝi egalas la limojn aŭ troviĝas inter ili.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "rondigi";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "rondigi malsupren";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "Rondigi supren";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Rondigi nombroj, supren aŭ malsupren.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://eo.wikipedia.org/wiki/Kvadrata_radiko";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluta";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadrata radiko";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "La absoluta valoro de nombro estos liverita.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "La rezulto de la potenco de e je la nombro.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "La natura logaritmo de nombro estos liverita.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "La dekbaza logaritmo de numero estos liverita.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "La negativigo de numero estos liverita.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "La kvadrata radiko de nombro estos liverita.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://eo.wikipedia.org/wiki/Trigonometria_funkcio";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "La sinusarko de nombro estos liverita.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "La targentarko de nombro estos liverita.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "Nova varianto...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nova nomo de varianto:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Krei '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Refari";
                +Blockly.Msg["REMOVE_COMMENT"] = "Forigi komenton";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renomi varianton...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renomi ĉiujn '%1' variantojn kiel:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "en la teksto";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 malplenas";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longo de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "presi %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Presi la specifitan tekston, nombron aŭ alian valoron.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Peti nombron al uzanto.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Peti tekston al uzanto.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "forigi spacojn el la dekstra flanko de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Hodiaŭ";
                +Blockly.Msg["UNDO"] = "Malfari";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "elemento";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Jam ekzistas varianto kun la nomo '%1'.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/es.js b/blockly/webif/static/blockly/msg/js/es.js
                new file mode 100644
                index 000000000..29c404022
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/es.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.es');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Añadir comentario";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "No se puede eliminar la variable \"%1\" porque es parte de la definición de la función \"%2\"";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Cambiar el valor:";
                +Blockly.Msg["CLEAN_UP"] = "Limpiar los bloques";
                +Blockly.Msg["COLLAPSE_ALL"] = "Contraer bloques";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Contraer bloque";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "color 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "color 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporción";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "combinar";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Combina dos colores con una proporción determinada (0,0–1,0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://es.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Elige un color de la paleta.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "color aleatorio";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Elige un color al azar.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "azul";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rojo";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colorear con";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Crea un color con cantidades específicas de rojo, verde y azul. Todos los valores deben encontrarse entre 0 y 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "romper el bucle";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continuar con la siguiente iteración del bucle";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Romper el bucle que lo contiene.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Saltar el resto de este bucle, y continuar con la siguiente iteración.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "ADVERTENCIA: Este bloque puede usarse sólo dentro de un bucle.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://es.wikipedia.org/wiki/Foreach";
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "para cada elemento %1 en la lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Para cada elemento en una lista, establecer la variable '%1' al elemento y luego hacer algunas declaraciones.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "contar con %1 desde %2 hasta %3 de a %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Hacer que la variable \"%1\" tome los valores desde el número de inicio hasta el número final, contando con el intervalo especificado, y hacer los bloques especificados.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Agregar una condición a este bloque.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Agregar una condición general final a este bloque.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Agregar, eliminar o reordenar las secciones para reconfigurar este bloque.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "sino";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "sino si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si un valor es verdadero, entonces hacer algunas declaraciones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si un valor es verdadero, entonces hacer el primer bloque de declaraciones.  De lo contrario, hacer el segundo bloque de declaraciones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si el primer valor es verdadero, entonces hacer el primer bloque de declaraciones. De lo contrario, si el segundo valor es verdadero, hacer el segundo bloque de declaraciones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si el primer valor es verdadero, entonces hacer el primer bloque de declaraciones. De lo contrario, si el segundo valor es verdadero, hacer el segundo bloque de declaraciones. Si ninguno de los valores son verdaderos, hacer el último bloque de declaraciones.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://es.wikipedia.org/wiki/Bucle_for";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "hacer";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repetir %1 veces";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Hacer algunas declaraciones varias veces.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repetir hasta";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repetir mientras";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Mientras un valor sea falso, entonces hacer algunas declaraciones.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Mientras un valor sea verdadero, entonces hacer algunas declaraciones.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "¿Eliminar todos los %1 bloques?";
                +Blockly.Msg["DELETE_BLOCK"] = "Eliminar bloque";
                +Blockly.Msg["DELETE_VARIABLE"] = "Borrar la variable \"%1\"";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "¿Borrar %1 usos de la variable \"%2\"?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Eliminar %1 bloques";
                +Blockly.Msg["DISABLE_BLOCK"] = "Desactivar bloque";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicar";
                +Blockly.Msg["ENABLE_BLOCK"] = "Activar bloque";
                +Blockly.Msg["EXPAND_ALL"] = "Expandir bloques";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expandir bloque";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entradas externas";
                +Blockly.Msg["HELP"] = "Ayuda";
                +Blockly.Msg["INLINE_INPUTS"] = "Entradas en línea";
                +Blockly.Msg["IOS_CANCEL"] = "Cancelar";
                +Blockly.Msg["IOS_ERROR"] = "Error";
                +Blockly.Msg["IOS_OK"] = "Aceptar";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Añadir entrada";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Permitir declaraciones";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Esta función tiene entradas duplicadas.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ENTRADAS";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Añadir";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Añadir variable";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Borrar";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "No puedes usar un nombre de variable vacío.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Renombrar";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nombre de la variable";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "crear lista vacía";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Devuelve una lista, de longitud 0, sin ningún dato";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Agregar, eliminar o reorganizar las secciones para reconfigurar este bloque de lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "crear lista con";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Agregar un elemento a la lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Crear una lista con cualquier número de elementos.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primero";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# del final";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obtener";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obtener y eliminar";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "último";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleatorio";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "eliminar";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Devuelve el primer elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Devuelve el elemento en la posición especificada en una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Devuelve el último elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Devuelve un elemento aleatorio en una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Elimina y devuelve el primer elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Elimina y devuelve el elemento en la posición especificada en una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Elimina y devuelve el último elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Elimina y devuelve un elemento aleatorio en una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Elimina el primer elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Elimina el elemento en la posición especificada en una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Elimina el último elemento de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Elimina un elemento aleatorio en una lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "hasta # del final";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "hasta #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "hasta el último";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "obtener sublista desde el primero";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "obtener sublista desde # del final";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "obtener sublista desde #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Crea una copia de la parte especificada de una lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 es el último elemento.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 es el primer elemento.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "encontrar la primera aparición del elemento";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "encontrar la última aparición del elemento";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Devuelve el índice de la primera/última aparición del elemento en la lista. Devuelve %1 si el elemento no se encuentra.";
                +Blockly.Msg["LISTS_INLIST"] = "en la lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 está vacía";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Devuelve verdadero si la lista está vacía.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longitud de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Devuelve la longitud de una lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "crear lista con el elemento %1 repetido %2 veces";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Crea una lista que consta de un valor dado repetido el número de veces especificado.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "invertir %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Invertir una copia de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "como";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insertar en";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "establecer";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserta el elemento al inicio de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserta el elemento en la posición especificada en una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Añade el elemento al final de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserta el elemento aleatoriamente en una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Establece el primer elemento de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Establece el elemento en la posición especificada en una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Establece el último elemento de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Establece un elemento aleatorio en una lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascendente";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descendente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "orden %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordenar una copia de una lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabético, ignorar mayúscula/minúscula";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numérico";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabético";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "hacer lista a partir de texto";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "hacer texto a partir de lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Unir una lista de textos en un solo texto, separado por un delimitador.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dividir el texto en una lista de textos, separando en cada delimitador.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "con delimitador";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falso";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Devuelve verdadero o falso.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "verdadero";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://es.wikipedia.org/wiki/Desigualdad_matemática";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Devuelve verdadero si ambas entradas son iguales.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Devuelve verdadero si la primera entrada es mayor que la segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Devuelve verdadero si la primera entrada es mayor o igual a la segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Devuelve verdadero si la primera entrada es menor que la segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Devuelve verdadero si la primera entrada es menor que o igual a la segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Devuelve verdadero si ambas entradas son distintas.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "no %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Devuelve verdadero si la entrada es falsa. Devuelve falso si la entrada es verdadera.";
                +Blockly.Msg["LOGIC_NULL"] = "nulo";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Devuelve nulo.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "y";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Devuelve verdadero si ambas entradas son verdaderas.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Devuelve verdadero si al menos una de las entradas es verdadera.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "prueba";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "si es falso";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "si es verdadero";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Comprueba la condición en \"prueba\". Si la condición es verdadera, devuelve el valor \"si es verdadero\"; de lo contrario, devuelve el valor \"si es falso\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://es.wikipedia.org/wiki/Aritmética";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Devuelve la suma de ambos números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Devuelve el cociente de ambos números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Devuelve la diferencia de ambos números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Devuelve el producto de ambos números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Devuelve el primer número elevado a la potencia del segundo.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "añadir %2 a %1";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Añadir un número a la variable «%1».";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://es.wikipedia.org/wiki/Anexo:Constantes_matemáticas";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Devuelve una de las constantes comunes: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) o ∞ (infinito).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "limitar %1 entre %2 y %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Limitar un número entre los límites especificados (inclusive).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "es divisible por";
                +Blockly.Msg["MATH_IS_EVEN"] = "es par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "es negativo";
                +Blockly.Msg["MATH_IS_ODD"] = "es impar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "es positivo";
                +Blockly.Msg["MATH_IS_PRIME"] = "es primo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Comprueba si un número es par, impar, primo, entero, positivo, negativo, o si es divisible por un número determinado. Devuelve verdadero o falso.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "es entero";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Devuelve el resto al dividir los dos números.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://es.wikipedia.org/wiki/Número";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un número.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "promedio de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "máximo de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mínimo de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modas de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "elemento aleatorio de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "desviación estándar de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma de la lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Devuelve el promedio (media aritmética) de los valores numéricos en la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Devuelve el número más grande en la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Devuelve la mediana en la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Devuelve el número más pequeño en la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Devuelve una lista de los elementos más comunes en la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Devuelve un elemento aleatorio de la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Devuelve la desviación estándar de la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Devuelve la suma de todos los números en la lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://es.wikipedia.org/wiki/Generador_de_números_aleatorios";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fracción aleatoria";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Devuelve una fracción aleatoria entre 0,0 (ambos inclusive) y 1.0 (exclusivo).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://es.wikipedia.org/wiki/Generador_de_números_aleatorios";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "entero aleatorio de %1 a %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Devuelve un entero aleatorio entre los dos límites especificados, inclusive.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://es.wikipedia.org/wiki/Redondeo";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "redondear";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "redondear a la baja";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "redondear al alza";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Redondear un número al alza o a la baja.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://es.wikipedia.org/wiki/Ra%C3%ADz_cuadrada";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluto";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "raíz cuadrada";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Devuelve el valor absoluto de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Devuelve e a la potencia de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Devuelve el logaritmo natural de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Devuelve el logaritmo base 10 de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Devuelve la negación de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Devuelve 10 a la potencia de un número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Devuelve la raíz cuadrada de un número.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://es.wikipedia.org/wiki/Función_trigonométrica";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Devuelve el arcocoseno de un número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Devuelve el arcoseno de un número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Devuelve el arcotangente de un número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Devuelve el coseno de un grado (no radián).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Devuelve el seno de un grado (no radián).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Devuelve la tangente de un grado (no radián).";
                +Blockly.Msg["NEW_VARIABLE"] = "Crear variable…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nombre de variable nueva:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permitir declaraciones";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://es.wikipedia.org/wiki/Subrutina";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Ejecuta la función definida por el usuario '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://es.wikipedia.org/wiki/Subrutina";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Ejecuta la función definida por el usuario '%1' y usa su salida.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Crear '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe esta función...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "hacer algo";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "para";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crea una función sin salida.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "devuelve";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Crea una función con una salida.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Advertencia: Esta función tiene parámetros duplicados.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Destacar definición de la función";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Si un valor es verdadero, entonces devuelve un segundo valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Advertencia: Este bloque solo puede ser utilizado dentro de la definición de una función.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nombre de entrada:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Añadir una entrada a la función.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entradas";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Añadir, eliminar o reordenar entradas para esta función.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Ya existe un procedimiento llamado \"%1\".";
                +Blockly.Msg["REDO"] = "Rehacer";
                +Blockly.Msg["REMOVE_COMMENT"] = "Eliminar comentario";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renombrar la variable…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renombrar todas las variables «%1» a:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "a %1 añade el texto %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Añadir texto a la variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "a minúsculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "a Mayúsculas Cada Palabra";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "a MAYÚSCULAS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Devuelve una copia del texto en un tamaño diferente.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obtener la primera letra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obtener la letra # del final";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obtener la letra #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obtener la última letra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obtener letra aleatoria";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "en el texto %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Devuelve la letra en la posición especificada.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "contar %1 en %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Cuantas veces aparece un texto dentro de otro texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Agregar un elemento al texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Agregar, eliminar o reordenar las secciones para reconfigurar este bloque de texto.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "hasta la letra # del final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "hasta la letra #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "hasta la última letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "en el texto";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "obtener subcadena desde la primera letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "obtener subcadena desde la letra # del final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "obtener subcadena desde la letra #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Devuelve una porción determinada del texto.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "encontrar la primera aparición del texto";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "encontrar la última aparición del texto";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "en el texto %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Devuelve el índice de la primera/última aparición del primer texto en el segundo texto. Devuelve %1 si el texto no se encuentra.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 está vacío";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Devuelve verdadero si el texto proporcionado está vacío.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "crear texto con";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Crear un fragmento de texto al unir cualquier número de elementos.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longitud de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Devuelve el número de letras (espacios incluidos) del texto proporcionado.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "imprimir %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Imprimir el texto, número u otro valor especificado.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Solicitar al usuario un número.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Solicitar al usuario un texto.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "solicitar número con el mensaje";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "solicitar texto con el mensaje";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "reemplazar %1 con %2 en %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Reemplazar todas las veces que un texto dentro de otro texto.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "invertir %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Invierte el orden de los caracteres en el texto.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://es.wikipedia.org/wiki/Cadena_de_caracteres";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Una letra, palabra o línea de texto.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "quitar espacios de ambos lados de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "quitar espacios iniciales de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "quitar espacios finales de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Devuelve una copia del texto sin los espacios de uno o ambos extremos.";
                +Blockly.Msg["TODAY"] = "Hoy";
                +Blockly.Msg["UNDO"] = "Deshacer";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "elemento";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crear 'establecer %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Devuelve el valor de esta variable.";
                +Blockly.Msg["VARIABLES_SET"] = "establecer %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Crear 'obtener %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Establece esta variable para que sea igual a la entrada.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Ya existe una variable llamada \"%1\".";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/et.js b/blockly/webif/static/blockly/msg/js/et.js
                new file mode 100644
                index 000000000..b2a30fc9b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/et.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.et');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Lisa kommentaar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Muuda väärtust:";
                +Blockly.Msg["CLEAN_UP"] = "Korista plokid kokku";
                +Blockly.Msg["COLLAPSE_ALL"] = "Tõmba plokid kokku";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Tõmba plokk kokku";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "1. värvist";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "2. värvist";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "suhtega";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "segu";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Segab kaks värvi määratud suhtega (0.0 - 1.0) kokku.";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Valitud värv paletist.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "juhuslik värv";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Juhuslikult valitud värv.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "sinisest";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "rohelisest";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "punasest";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "segu";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Tekitab värvi määratud hulgast punasest, rohelisest ja sinisest. Kõik väärtused peavad olema 0 ja 100 vahel.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "välju kordusest";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "katkesta see kordus ja liigu järgmisele";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Väljub kordusest ja liigub edasi korduse järel oleva koodi käivitamisele.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Katkestab korduses oleva koodi käivitamise ja käivitab järgmise korduse.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Hoiatus: Seda plokki saab kasutada ainult korduse sees.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "iga elemendiga %1 loendis %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Iga elemendiga loendis anna muutujale '%1' elemendi väärtus ja kõivita plokis olevad käsud.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "loendus muutujaga %1 alates %2 kuni %3, %4 kaupa";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Annab muutujale '%1' väärtused ühest numbrist teiseni, muutes seda intervalli kaupa ja käivitab igal muudatusel ploki sees oleva koodi.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Lisab „kui“ plokile tingimuse.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Lisab „kui“ plokile lõpliku tingimuseta koodiploki.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Selle „kui“ ploki muutmine sektsioonide lisamise, eemaldamise ja järjestamisega.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "vastasel juhul";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "vastasel juhul, kui";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "kui";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Kui avaldis on tõene, käivita ploki sees olevad käsud.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Kui avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul käivita käsud teisest plokist.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist. Kui ükski avaldistest pole tõene, käivita käsud viimasest plokist.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "käivita";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 korda";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Plokis olevate käskude käivitamine määratud arv kordi.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "seni kuni pole";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "seni kuni on";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Plokis olevaid käske korratakse seni kui avaldis pole tõene.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Plokis olevaid käske korratakse seni kui avaldis on tõene.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Kas kustutada kõik %1 plokki?";
                +Blockly.Msg["DELETE_BLOCK"] = "Kustuta plokk";
                +Blockly.Msg["DELETE_VARIABLE"] = "Kustuta muutuja '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Kas kustutada %1 kohas kasutatav muutuja '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Kustuta %1 plokki";
                +Blockly.Msg["DISABLE_BLOCK"] = "Keela ploki kasutamine";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Tekita duplikaat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Luba ploki kasutamine";
                +Blockly.Msg["EXPAND_ALL"] = "Laota plokid laiali";
                +Blockly.Msg["EXPAND_BLOCK"] = "Laota plokk laiali";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Sisendid ploki taga";
                +Blockly.Msg["HELP"] = "Abi";
                +Blockly.Msg["INLINE_INPUTS"] = "Sisendid ploki sees";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "tühi loend";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Tagastab loendi, mille pikkus on 0 ja milles pole ühtegi elementi.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "loend";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Loendiploki elementide lisamine, eemaldamine või järjestuse muutmine.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "uus loend";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Elemendi lisamine loendisse.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Tekitab mistahes arvust elementidest loendi.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "esimene element";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "element # (lõpust)";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "element #";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "võetud";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "võetud ja eemaldatud";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "viimane element";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "juhuslik element";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "eemalda";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Tagastab loendi esimese elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Tagastab loendis määratud asukohal oleva elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Tagastab loendi viimase elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Tagastab loendi juhusliku elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Tagastab ja eemaldab loendist esimese elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Tagastab ja eemaldab loendist määratud asukohal oleva elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Tagastab ja eemaldab loendist viimase elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Tagastab ja eemaldab loendist juhusliku elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Eemaldab loendist esimese elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Eemaldab loendist määratud asukohal oleva elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Eemaldab loendist viimase elemendi.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Eemaldab loendist juhusliku elemendi.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "elemendini # (lõpust)";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "elemendini #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "lõpuni";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "alamloend algusest";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "alamloend elemendist # (lõpust)";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "alamloend elemendist #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Tekitab loendi määratud osast koopia.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Viimane element on %1.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Esimene element on %1.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "esimene leitud";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "viimase leitud";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Tagastab esimese/viimase loendist leitud objekti asukoha (objekti järjekorranumbri loendis). Kui objekti ei leita, tagastab %1.";
                +Blockly.Msg["LISTS_INLIST"] = "loendis";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 on tühi";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Tagastab „tõene“ kui loend on tühi.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 pikkus";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Tagastab loendi pikkuse.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "loend pikkusega %2 elemendist %1";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Tekitab uue loendi, millesse lisatakse ühte elementi pikkusega määratud arv kordi.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = ", väärtus";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "lisa asukohale";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "asenda";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Lisab loendi algusesse uue elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Lisab määratud asukohale loendis uue elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Lisab loendi lõppu uue elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Lisab juhuslikule kohale loendis uue elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Asendab loendis esimese elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Asendab loendis määratud kohal oleva elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Asendab loendis viimase elemendi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Asendab loendis juhusliku elemendi.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "kasvavalt";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "kahanevalt";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "%1 %2 sorteeritud %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Loendi koopia sorteerimine.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "tähestiku järgi (tähesuurust eirates)";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "arvväärtuste järgi";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "tähestiku järgi";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "loend, tekitatud tekstist";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "tekst, tekitatud loendist";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Ühendab tekstide loendis olevad tükid üheks tekstiks, asetades tükkide vahele eraldaja.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Tükeldab teksti eraldajade kohalt ja asetab tükid tekstide loendisse.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "eraldajaga";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "väär";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Tagastab tõeväärtuse – kas „tõene“ või „väär“.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "tõene";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Tagastab „tõene“, kui avaldiste väärtused on võrdsed.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Tagastab „tõene“, kui esimese avaldise väärtus on suurem kui teise väärtus.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Tagastab „tõene“, kui esimese avaldise väärtus on suurem või võrdne teise väärtusega.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem kui teise väärtus.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem või võrdne teise väärtusega.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Tagastab „tõene“, kui avaldiste väärtused pole võrdsed.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "pole %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Tagastab „tõene“, kui avaldis on väär. Tagastab „väär“, kui avaldis on tõene.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Tagastab nulli.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ja";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "või";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Tagastab „tõene“, kui mõlemad avaldised on tõesed.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Tagastab „tõene“, kui vähemalt üks avaldistest on tõene.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "tingimus";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "kui väär";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "kui tõene";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kui tingimuse väärtus on tõene, tagastab „kui tõene“ väärtuse, vastasel juhul „kui väär“ väärtuse.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://et.wikipedia.org/wiki/Aritmeetika";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Tagastab kahe arvu summa.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Tagastab kahe arvu jagatise.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Tagastab kahe arvu vahe.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Tagastab kahe arvu korrutise.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Tagastab esimese arvu teise arvu astmes.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "muuda %1 %2 võrra";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Lisab arvu muutujale '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Tagastab ühe konstantidest: π (3,141…), e (2,718…), φ (1.618…), √2) (1,414…), √½ (0,707…), või ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1 piirang %2 ja %3 vahele";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Piirab arvu väärtuse toodud piiridesse (piirarvud kaasa arvatud).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "jagub arvuga";
                +Blockly.Msg["MATH_IS_EVEN"] = "on paarisarv";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "on negatiivne arv";
                +Blockly.Msg["MATH_IS_ODD"] = "on paaritu arv";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "on positiivne arv";
                +Blockly.Msg["MATH_IS_PRIME"] = "on algarv";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrollib kas arv on paarisarv, paaritu arv, algarv, täisarv, positiivne, negatiivne või jagub kindla arvuga. Tagastab „tõene“ või „väär“.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "on täisarv";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 jääk";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Tagastab esimese numbri teisega jagamisel tekkiva jäägi.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://et.wikipedia.org/wiki/Arv";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Arv.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "loendi keskmine";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "loendi maksimum";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "loendi mediaan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "loendi miinimum";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "loendi moodid";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "juhuslik element loendist";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "loendi standardhälve";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "loendi summa";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Tagastab loendis olevate arvväärtuste aritmeetilise keskmise.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Tagastab suurima loendis oleva arvu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Tagastab väikseima loendis oleva arvu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Tagastab loendi kõige sagedamini esinevate loendi liikmetega.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Tagastab juhusliku elemendi loendist.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Tagastab loendi standardhälbe.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Tagastab kõigi loendis olevate arvude summa.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "juhuslik murdosa";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Tagastab juhusliku murdosa 0.0 (kaasa arvatud) and 1.0 (välja arvatud) vahel.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "juhuslik täisarv %1 ja %2 vahel";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Tagastab juhusliku täisarvu toodud piiride vahel (piirarvud kaasa arvatud).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ümarda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ümarda alla";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ümarda üles";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Ümardab arvu üles või alla.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://et.wikipedia.org/wiki/Ruutjuur";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluutväärtus";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ruutjuur";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Tagastab arvu absoluutväärtuse.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Tagasta e arvu astmes.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Tagastab arvu naturaallogaritmi.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Tagastab arvu kümnendlogaritm.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Tagastab arvu vastandväärtuse.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Tagastab 10 arvu astmes.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Tagastab arvu ruutjuure.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://et.wikipedia.org/wiki/Trigonomeetrilised_funktsioonid";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Tagastab arvu arkuskoosiinuse.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Tagastab arvu arkussiinuse.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Tagastab arvu arkustangensi.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Tagastab arvu (kraadid) kosiinuse.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Tagastab arvu (kraadid) siinuse.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Tagastab arvu (kraadid) tangensi.";
                +Blockly.Msg["NEW_VARIABLE"] = "Uus muutuja ...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Uue muutuja nimi:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "kood plokis";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "sisenditega:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Käivitab kasutaja defineeritud funktsiooni '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "sisenditega:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Tekita '%1' plokk";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Funktsiooni kirjeldus ...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "teeme midagi";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "funktsioon";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Tekitab funktsiooni, mis ei tagasta midagi.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "tagasta";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Tekitab funktsiooni, mis tagastab midagi.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Hoiatus: Sel funktsioonil on mitu sama nimega sisendit.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Tõsta funktsiooni definitsioon esile";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Kui väärtus on tõene, tagastatakse teine väärtus.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Hoiatus: Seda plokki saab kasutada ainult funktsiooni definitsioonis.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "sisend nimega:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Lisab funktsioonile sisendi.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "sisendid";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Funktsiooni sisendite lisamine, eemaldamine või järjestuse muutmine.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Tee uuesti";
                +Blockly.Msg["REMOVE_COMMENT"] = "Eemalda kommentaar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Nimeta muutuja ümber ...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Muutuja „%1“ uus nimi:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Lisab teksti muutuja „%1“ väärtuse lõppu.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "väikeste tähtedega";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Suurte Esitähtedega";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "SUURTE TÄHTEDEGA";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Tagastab muudetud tähesuurusega teksti koopia.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "esimene sümbol";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "lõpust sümbol #";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "sümbol #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "viimane sümbol";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "juhuslik sümbol";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Tagastab tekstis määratud asukohal oleva sümboli.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Objekti lisamine tekstile.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ühenda";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Tekstiploki muutmine sektsioonide lisamise, eemaldamise või järjestuse muutmisega.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "kuni (lõpust) sümbolini #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "kuni sümbolini #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "kuni viimase sümbolini";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "tekstist";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "alates esimesest sümbolist";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "alates (lõpust) sümbolist #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "alates sümbolist #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Tagastab määratud tüki tekstist.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "esimese leitud tekstitüki";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "viimase leitud tekstitüki";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Tagastab esimesest tekstist esimese/viimase leitud teise teksti asukoha (indeksi). Kui teksti ei leita, tagastab %1.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 on tühi";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Tagastab „tõene“, kui tekstis pole ühtegi sümbolit.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "tekita tekst";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Tekitab teksti ühendades mistahes arvu elemente.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 pikkus";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Tagastab sümbolite aru (ka tühikud) toodud tekstis.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "trüki %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Trükib määratud teksti, numbri või mõne muu objekti väärtuse.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Küsib kasutajalt teadet näidates mingit arvu.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Küsib kasutajalt teadet näidates mingit teksti.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "kasutajalt küsitud arv teatega";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "kasutajalt küsitud tekst teatega";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Täht, sõna või rida teksti.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "mõlemalt poolt eemaldatud tühikutega";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "algusest eemaldatud tühikutega";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "lõpust eemaldatud tühikutega";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Tagastab koopia tekstist, millel on tühikud ühelt või mõlemalt poolt eemaldatud.";
                +Blockly.Msg["TODAY"] = "Täna";
                +Blockly.Msg["UNDO"] = "Võta tagasi";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "objekt";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Tekita 'määra „%1“ väärtuseks' plokk";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Tagastab selle muutuja väärtuse.";
                +Blockly.Msg["VARIABLES_SET"] = "määra %1 väärtuseks %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Tekita '„%1“ väärtus' plokk";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Määrab selle muutuja väärtuse võrdseks sisendi väärtusega.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "'%1'-nimeline muutuja on juba olemas.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/fa.js b/blockly/webif/static/blockly/msg/js/fa.js
                new file mode 100644
                index 000000000..854474c38
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/fa.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.fa');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "افزودن نظر";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "متغیر '%1' را نمی‌توان پاک کرد، زیرا جزیی از تعریف متغیر '%2' می‌باشد";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "تغییر مقدار:";
                +Blockly.Msg["CLEAN_UP"] = "تمیز کردن بلوک‌ها";
                +Blockly.Msg["COLLAPSE_ALL"] = "فروپاشی بلوک‌ها";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "فروپاشی بلوک";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "رنگ ۱";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "رنگ ۲";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "نسبت";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "مخلوط";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%86%DA%AF";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "انتخاب یک رنگ از تخته‌رنگ.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "رنگ تصادفی";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "انتخاب یک رنگ به شکل تصادفی.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "آبی";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "سبز";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "قرمز";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "رنگ با";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ساخت یک رنگ با مقدار مشخص‌شده‌ای از قرمز، سبز و آبی. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "خروج از حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ادامه با تکرار بعدی حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "شکستن حلقهٔ شامل.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "برای هر مورد %1 در فهرست %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "با تعداد %1 از %2 به %3 با گام‌های %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "افزودن یک شرط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "اضافه کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "افزودن، حذف یا بازمرتب‌سازی قسمت‌ها برای پیکربندی دوبارهٔ این بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "درغیر اینصورت";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "درغیر اینصورت اگر";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "اگر";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AD%D9%84%D9%82%D9%87_%D9%81%D9%88%D8%B1";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "انجام";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 بار تکرار";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "انجام چند عبارت چندین بار.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "تکرار تا زمانی که";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "تکرار در حالی که";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "حذف همهٔ بلاک‌های %1؟";
                +Blockly.Msg["DELETE_BLOCK"] = "حذف بلوک";
                +Blockly.Msg["DELETE_VARIABLE"] = "متغیر '%1'را پاک کنید";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "تعداد %1 استفاده از متغیر '%2' پاک شود؟";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "حذف بلوک‌های %1";
                +Blockly.Msg["DISABLE_BLOCK"] = "غیرفعال‌سازی بلوک";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "تکراری";
                +Blockly.Msg["ENABLE_BLOCK"] = "فعال‌سازی بلوک";
                +Blockly.Msg["EXPAND_ALL"] = "گسترش بلوک‌ها";
                +Blockly.Msg["EXPAND_BLOCK"] = "گسترش بلوک";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ورودی‌های خارجی";
                +Blockly.Msg["HELP"] = "راهنما";
                +Blockly.Msg["INLINE_INPUTS"] = "ورودی‌های درون خطی";
                +Blockly.Msg["IOS_CANCEL"] = "لغو";
                +Blockly.Msg["IOS_ERROR"] = "خطا";
                +Blockly.Msg["IOS_OK"] = "تأیید";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ افزودن ورودی";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ورودی‌ها";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "افزودن";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ افزودن متغیر";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "حذف";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "نام متغیر نمی‌تواند خالی باشد";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "تغییر نام";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "نام متغیر";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "ایجاد فهرست خالی";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "فهرست";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "اضافه کردن، حذف کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "ایجاد فهرست با";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "اضافه کردن یک مورد به فهرست.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "فهرستی از هر عددی از موارد می‌سازد.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "اولین";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# از انتها";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "گرفتن";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "گرفتن و حذف‌کردن";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "آخرین";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "تصادفی";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "حذف‌کردن";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "اولین مورد یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "موردی در محل مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "آخرین مورد در یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "یک مورد تصادفی در یک فهرست بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "اولین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "آخرین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "یک مورد تصادفی را یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "به # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "به #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "به آخرین";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "گرفتن زیرمجموعه‌ای از ابتدا";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "گرفتن زیرمجموعه‌ای از # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "گرفتن زیرمجموعه‌ای از #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 آخرین مورد است.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 اولین مورد است.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "یافتن اولین رخ‌داد مورد";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "یافتن آخرین رخ‌داد مورد";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر آیتم موجود نبود.";
                +Blockly.Msg["LISTS_INLIST"] = "در فهرست";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "طول یک فهرست را برمی‌گرداند.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "معکوس %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "به عنوان";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "درج در";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "مجموعه";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "موردی به ته فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "موردی به ته فهرست الحاق می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "مورد را به صورت تصادفی در یک فهرست می‌افزاید.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "اولین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "آخرین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "یک مورد تصادفی در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "صعودی";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "نزولی";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "حروفی ، رد کردن مورد";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "عددی";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "حروفی ، الفبایی";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "ایجاد فهرست از متن";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "ایجاد متن از فهرست";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "همراه جداساز";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ناصحیح";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "بازگرداندن یکی از صحیح یا ناصحیح.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "صحیح";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D9%86%D8%A7%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1%DB%8C";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "نه %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_NULL"] = "تهی";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "تهی بازمی‌گرداند.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "و";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "یا";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "آزمایش";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "اگر ناصحیح";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "اگر صحیح";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "بازگرداندن مقدار جمع دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "بازگرداندن باقی‌ماندهٔ دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "بازگرداندن تفاوت دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "بازگرداندن حاصلضرب دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%A7%D8%B5%D8%B7%D9%84%D8%A7%D8%AD_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C#.D8.A7.D9.81.D8.B2.D8.A7.DB.8C.D8.B4_.D8.B4.D9.85.D8.A7.D8.B1.D9.86.D8.AF.D9.87";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "تغییر %1 با %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "افزودن یک عدد به متغیر '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AB%D8%A7%D8%A8%D8%AA_%D8%B1%DB%8C%D8%A7%D8%B6%DB%8C";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "یکی از مقادیر ثابت جهانی را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "محدودکردن %1 پایین %2 بالا %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "تقسیم شده بر";
                +Blockly.Msg["MATH_IS_EVEN"] = "زوج است";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "منفی است";
                +Blockly.Msg["MATH_IS_ODD"] = "فرد است";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "مثبت است";
                +Blockly.Msg["MATH_IS_PRIME"] = "عدد اول است";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "کامل است";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B9%D9%85%D9%84%DB%8C%D8%A7%D8%AA_%D9%BE%DB%8C%D9%85%D8%A7%D9%86%D9%87";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "باقی‌ماندهٔ %1 + %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "یک عدد.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "میانگین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "بزرگ‌ترین عدد در فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "میانهٔ فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "کوچک‌ترین عدد در فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "مد فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "مورد تصادفی از فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "انحراف معیار فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "جمع فهرست";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "میانهٔ عدد در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "کوچک‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "موردی تصادفی از فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "انحراف معیار فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "جمع همهٔ عددهای فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "کسر تصادفی";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "عدد صحیح تصادفی بین %1 تا %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "گردکردن";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "گرد به پایین";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "گرد به بالا";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "گردکردن یک عدد به بالا یا پایین.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%DB%8C%D8%B4%D9%87_%D8%AF%D9%88%D9%85";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "مطلق";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ریشهٔ دوم";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "قدر مطلق یک عدد را بازمی‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "بازگرداندن توان e یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "لوگاریتم طبیعی یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "منفی‌شدهٔ یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "بازگرداندن توان ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ریشهٔ دوم یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%D9%87%D8%A7%DB%8C_%D9%85%D8%AB%D9%84%D8%AB%D8%A7%D8%AA%DB%8C";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "بازگرداندن آرک‌کسینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "بازگرداندن آرک‌سینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "بازگرداندن آرک‌تانژانت درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "بازگرداندن کسینوس یک زاویه درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "بازگرداندن سینوس یک زاویه به درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "بازگرداندن تانژانت یک زاویه به درجه (نه رادیان).";
                +Blockly.Msg["NEW_VARIABLE"] = "ایجاد متغیر...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "نام متغیر تازه:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "اجازه اظهارات";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1».";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "ساختن «%1»";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "توصیف این عملکرد...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "انجام چیزی";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "به";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "تابعی می‌سازد بدون هیچ خروجی.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "بازگشت";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "تابعی با یک خروجی می‌سازد.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "اخطار: این تابعی پارامتر تکراری دارد.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "برجسته‌سازی تعریف تابع";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "اگر یک مقدار صحیح است، مقدار دوم را برگردان.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "نام ورودی:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "اضافه کردن ورودی به تابع.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ورودی‌ها";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "انجام دوباره";
                +Blockly.Msg["REMOVE_COMMENT"] = "حذف نظر";
                +Blockly.Msg["RENAME_VARIABLE"] = "تغییر نام متغیر...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "تغییر نام همهٔ متغیرهای «%1» به:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "الحاق متنی به متغیر «%1».";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "به حروف کوچک";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "به حروف بزرگ عنوان";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "به حروف بزرگ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "بازگرداندن کپی متن در حالتی متفاوت.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "گرفتن اولین حرف";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "گرفتن حرف # از آخر";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "گرفتن حرف #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "گرفتن آخرین حرف";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "گرفتن حرف تصادفی";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "حرفی در موقعیت مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "تعداد %1 را در %2 بشمار";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "تعداد دفعاتی که یک متن درون یک متن دیگر تکرار شده است را برمی‌گرداند";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "افزودن یک مورد به متن.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "عضویت";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "اضافه کردن، حذف یا مرتب‌سازی بحش‌ها برای تنظیم مجدد این بلوک متنی.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "به حرف # از انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "به حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "به آخرین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "در متن";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "گرفتن زیرمتن از اولین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "گرفتن زیرمتن از حرف # به انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "گرفتن زیرمتن از حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "اولین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "آخرین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "اضافه کردن صحیح اگر متن فراهم‌شده خالی است.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ایجاد متن با";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "چاپ %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "اعلان برای کاربر با یک عدد.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "اعلان برای کاربر برای یک متن.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "اعلان برای عدد با پیام";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "اعلان برای متن با پیام";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "درون %3، متن %1 را با %2 جایگزین کن";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "معکوس %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "چینش کاراکترها درون متن را برعکس می‌کند";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://fa.wikipedia.org/wiki/%D8%B1%D8%B4%D8%AA%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "یک حرف، کلمه یا خطی از متن.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "تراشیدن فاصله‌ها از  هر دو طرف";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.";
                +Blockly.Msg["TODAY"] = "امروز";
                +Blockly.Msg["UNDO"] = "واگردانی";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "مورد";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "درست‌کردن «تنظیم %1»";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "مقدار این متغیر را بر می‌گرداند.";
                +Blockly.Msg["VARIABLES_SET"] = "مجموعه %1 به %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "درست‌کردن «گرفتن %1»";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "متغیر برابر با خروجی را مشخص می‌کند.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "متغیری با نام '%1' هم اکنون وجود دارد";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/fi.js b/blockly/webif/static/blockly/msg/js/fi.js
                new file mode 100644
                index 000000000..dfe1944f7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/fi.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.fi');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Lisää kommentti";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Muuta arvoa:";
                +Blockly.Msg["CLEAN_UP"] = "Siivoa lohkot";
                +Blockly.Msg["COLLAPSE_ALL"] = "Sulje lohkot";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Sulje lohko";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "väri 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "väri 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "suhde";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "sekoitus";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Sekoittaa kaksi väriä keskenään annetussa suhteessa (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://fi.wikipedia.org/wiki/V%C3%A4ri";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Valitse väri paletista.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "satunnainen väri";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Valitse väri sattumanvaraisesti.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "sininen";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "vihreä";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "punainen";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "väri, jossa on";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Luo väri, jossa on tietty määrä punaista, vihreää ja sinistä. Kaikkien arvojen tulee olla välillä 0 - 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "poistu silmukasta";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "jatka silmukan seuraavaan toistoon";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Poistu sisemmästä silmukasta.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Ohita loput tästä silmukasta ja siirry seuraavaan toistoon.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Varoitus: Tätä lohkoa voi käyttää vain silmukan sisällä.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "kullekin kohteelle %1 listassa %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Aseta muuttujan %1 arvoksi kukin listan kohde vuorollaan ja suorita joukko lausekkeita.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "laske %1 Väli %2-%3 %4:n välein";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Aseta muuttujaan \"%1\" arvot alkuarvosta loppuarvoon annetun askeleen välein ja suorita joka askeleella annettu koodilohko.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Lisää ehto \"jos\" lohkoon.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Lisää lopullinen \"muuten\" lohko \"jos\" lohkoon.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Lisää, poista tai järjestele osioita tässä \"jos\" lohkossa.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "muuten";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "muuten jos";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "jos";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Jos arvo on tosi, suorita lauseke.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Jos arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten suorita toinen lohko lausekkeita.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Jos ensimmäinen arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten, jos toinen arvo on tosi, suorita toinen lohko lausekkeita.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Jos ensimmäinen arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten, jos toinen arvo on tosi, suorita toinen lohko lausekkeita. Jos mikään arvoista ei ole tosi, suorita viimeinen lohko lausekkeita.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "tee";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "toista %1 kertaa";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Suorita joukko lausekkeita useampi kertaa.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "toista kunnes";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "toista niin kauan kuin";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Niin kauan kuin arvo on epätosi, suorita joukko lausekkeita.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Niin kauan kuin arvo on tosi, suorita joukko lausekkeita.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Poistetaanko kaikki %1 lohkoa?";
                +Blockly.Msg["DELETE_BLOCK"] = "Poista lohko";
                +Blockly.Msg["DELETE_VARIABLE"] = "Poista muuttuja '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Poistetaanko %1 käyttöä muuttujalta '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Poista %1 lohkoa";
                +Blockly.Msg["DISABLE_BLOCK"] = "Passivoi lohko";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kopioi";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktivoi lohko";
                +Blockly.Msg["EXPAND_ALL"] = "Laajenna lohkot";
                +Blockly.Msg["EXPAND_BLOCK"] = "Laajenna lohko";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Ulkoiset syötteet";
                +Blockly.Msg["HELP"] = "Apua";
                +Blockly.Msg["INLINE_INPUTS"] = "Tuo syötteet";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Virhe";
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Lisää";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Lisää muuttuja";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Poista";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "Luo tyhjä lista";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Palauta tyhjä lista, pituus 0";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Listää, poista tai järjestele uudestaan osioita tässä lohkossa.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "luo lista";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Lisää kohde listaan.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Luo lista, jossa on mikä tahansa määrä kohteita.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "ensimmäinen";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "nro (lopusta laskien)";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "nro";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "hae";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "hae ja poista";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "viimeinen";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "satunnainen";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "poista";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Palauta ensimmäinen kohde listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Palauta kohde annetusta kohdasta listaa.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Palauttaa listan viimeisen kohteen.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Palauttaa satunnaisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Poistaa ja palauttaa ensimmäisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Poistaa ja palauttaa kohteen listan annetusta kohdasta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Poistaa ja palauttaa viimeisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Poistaa ja palauttaa satunnaisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Poistaa ensimmäisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Poistaa kohteen listalta annetusta kohtaa.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Poistaa viimeisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Poistaa satunnaisen kohteen listalta.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "päättyen kohtaan (lopusta laskien)";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "päättyen kohtaan";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "viimeinen";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "hae osalista alkaen alusta";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "hae osalista alkaen kohdasta (lopusta laskien)";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "hae osalista alkaen kohdasta";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Luo kopio määrätystä kohden listaa.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Numero %1 tarkoittaa listan viimeistä kohdetta.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Numero %1 tarkoittaa listan ensimmäistä kohdetta.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "etsi ensimmäinen esiintymä kohteelle";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "etsi viimeinen esiintymä kohteelle";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Palauttaa kohteen ensimmäisen/viimeisen esiintymän kohdan listassa. Palauttaa %1 jos kohdetta ei löydy.";
                +Blockly.Msg["LISTS_INLIST"] = "listassa";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 on tyhjä";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Palauttaa tosi, jos lista on tyhjä.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1:n pituus";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Palauttaa listan pituuden.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "luo lista, jossa kohde %1 toistuu %2 kertaa";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Luo listan, jossa annettu arvo toistuu määrätyn monta kertaa.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "kohteeksi";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "lisää kohtaan";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "aseta";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Lisää kohteen listan kärkeen.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Lisää kohteen annettuun kohtaan listassa.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Lisää kohteen listan loppuun.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Lisää kohteen satunnaiseen kohtaan listassa.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Asettaa listan ensimmäisen kohteen.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Asettaa kohteen annettuun kohtaan listassa.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Asettaa listan viimeisen kohteen.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Asettaa satunnaisen kohteen listassa.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "nouseva";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "laskeva";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "lajittele %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Lajittele kopio luettelosta.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "aakkosjärjestyksessä, ohita kapitaalit";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeerinen";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "aakkosjärjestys";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "tee lista tekstistä";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "tee listasta teksti";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Yhdistä luettelon tekstit yhdeksi tekstiksi, erotettuina välimerkillä.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Jaa teksti osiin erotinmerkin perusteella ja järjestä osat listaksi.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "erottimen kanssa";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "epätosi";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Palauttaa joko tosi tai epätosi.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "tosi";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://fi.wikipedia.org/wiki/Ep%C3%A4yht%C3%A4l%C3%B6";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Palauta tosi, jos syötteet ovat keskenään samat.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Palauttaa tosi, jos ensimmäinen syöte on suurempi, kuin toinen.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Palauttaa tosi, jos ensimmäinen syöte on suurempi tai yhtä suuri, kuin toinen.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Palauttaa tosi, jos ensimmäinen syöte on pienempi, kuin toinen.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Palauttaa tosi, jos ensimmäinen syöte on pienempi tai yhtä suuri, kuin toinen.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Palauttaa tosi, jos syötteet eivät ole keskenään samoja.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ei %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Palauttaa tosi, jos syöte on epätosi. Palauttaa epätosi, jos syöte on tosi.";
                +Blockly.Msg["LOGIC_NULL"] = "ei mitään";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Palauttaa \"ei mitään\"-arvon.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ja";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "tai";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Palauttaa tosi, jos kummatkin syötteet ovat tosia.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Palauttaa tosi, jos ainakin yksi syötteistä on tosi.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "testi";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "jos epätosi";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "jos tosi";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Tarkistaa testin ehdon. Jos ehto on tosi, palauttaa \"jos tosi\" arvon, muuten palauttaa \"jos epätosi\" arvon.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "http://fi.wikipedia.org/wiki/Aritmetiikka";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Palauttaa kahden luvun summan.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Palauttaa jakolaskun osamäärän.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Palauttaa kahden luvun erotuksen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Palauttaa kertolaskun tulon.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Palauttaa ensimmäisen luvun korotettuna toisen luvun potenssiin.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://fi.wikipedia.org/wiki/Yhteenlasku";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "muuta %1 arvolla %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Lisää arvo muuttujaan '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Palauttaa jonkin seuraavista vakioista: π (3.141…), e (2.718…), φ (1.618…), neliöjuuri(2) (1.414…), neliöjuuri(½) (0.707…), or ∞ (ääretön).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "rajoita %1 vähintään %2 enintään %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Rajoittaa arvon annetulle suljetulle välille.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "on jaollinen luvulla";
                +Blockly.Msg["MATH_IS_EVEN"] = "on parillinen";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "on negatiivinen";
                +Blockly.Msg["MATH_IS_ODD"] = "on pariton";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "on positiivinen";
                +Blockly.Msg["MATH_IS_PRIME"] = "on alkuluku";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Tarkistaa onko numero parillinen, pariton, alkuluku, kokonaisluku, positiivinen, negatiivinen, tai jos se on jaollinen toisella luvulla. Palauttaa tosi tai epätosi.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "on kokonaisluku";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 jakojäännös";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Palauttaa jakolaskun jakojäännöksen.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "⋅";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://fi.wikipedia.org/wiki/Luku";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Luku.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "keskiarvo luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "suurin luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "keskiluku luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "pienin luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "tyyppiarvo luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "satunnainen valinta luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "keskihajonta luvuista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summa luvuista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Palauttaa aritmeettisen keskiarvon annetuista luvuista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Palauttaa suurimman annetuista luvuista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Palauttaa annettujen lukujen keskiluvun.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Palauttaa pienimmän annetuista luvuista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Palauttaa luettelon yleisimmistä luvuista annetussa listassa.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Palauttaa satunnaisesti valitun luvun annetuista luvuista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Palauttaa annettujen lukujen keskihajonnan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Palauttaa kaikkien annettujen lukujen summan.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://fi.wikipedia.org/wiki/Satunnaisluku";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "satunnainen murtoluku";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Palauttaa satunnaisen luvun oikealta puoliavoimesta välistä [0.0, 1.0).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://fi.wikipedia.org/wiki/Satunnaisluku";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "Palauttaa satunnaisen kokonaisluvun väliltä %1-%2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Palauttaa satunnaisen kokonaisluvun kahden annetun arvon suljetulta väliltä.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://fi.wikipedia.org/wiki/Py%C3%B6rist%C3%A4minen";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "pyöristä";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "pyöristä alaspäin";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "pyöristä ylöspäin";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Pyöristää luvun ylös- tai alaspäin.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://fi.wikipedia.org/wiki/Neli%C3%B6juuri";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "itseisarvo";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "neliöjuuri";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Palauttaa luvun itseisarvon.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Palauttaa e potenssiin luku.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Palauttaa luvun luonnollisen logaritmin.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Palauttaa luvun kymmenkantaisen logaritmin.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Palauttaa numeron vastaluvun.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Palauttaa 10 potenssiin luku.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Palauttaa luvun neliöjuuren.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://fi.wikipedia.org/wiki/Trigonometrinen_funktio";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Palauttaa luvun arkuskosinin.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Palauttaa luvun arkussinin.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Palauttaa luvun arkustangentin.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Palauttaa asteluvun (ei radiaanin) kosinin.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Palauttaa asteluvun (ei radiaanin) sinin.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Palauttaa asteluvun (ei radiaanin) tangentin.";
                +Blockly.Msg["NEW_VARIABLE"] = "Luo muuttuja...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Uuden muuttujan nimi:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "salli kommentit";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "parametrit:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://fi.wikipedia.org/wiki/Aliohjelma";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Suorittaa käyttäjän määrittelemä funktio '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://fi.wikipedia.org/wiki/Aliohjelma";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Suorittaa käyttäjän määrittelemän funktion '%1' ja käyttää sen tuotosta.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "parametrit:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Luo '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Kuvaile tämä funktio...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "tee jotain";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "tehdäksesi";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Luo funktio, jolla ei ole tuotosta.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "palauta";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Luo funktio, jolla ei ole tuotosta.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Varoitus: tällä funktiolla on sama parametri useamman kerran.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Korosta funktion määritelmä";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Jos arvo on tosi, palauta toinen arvo.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Varoitus: tätä lohkoa voi käyttää vain funktion määrityksessä.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "syötteen nimi:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Lisää sisääntulon funktioon.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "syötteet";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Lisää, poista tai järjestele uudelleen tämän toiminnon tulot.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Tee uudelleen";
                +Blockly.Msg["REMOVE_COMMENT"] = "Poista kommentti";
                +Blockly.Msg["RENAME_VARIABLE"] = "Nimeä uudelleen muuttuja...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Nimeä uudelleen kaikki '%1' muuttujaa:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Lisää tekstiä muuttujaan '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "pienet kirjaimet";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "isot alkukirjaimet";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "isot kirjaimet";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Palauttaa kopion tekstistä eri kirjainkoossa.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "hae ensimmäinen kirjain";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "Hae kirjain nro (lopusta laskien)";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "Hae kirjain nro";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "hae viimeinen kirjain";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "hae satunnainen kirjain";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Palauttaa annetussa kohdassa olevan kirjaimen.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Lisää kohteen tekstiin.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "liitä";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Lisää, poista tai uudelleen järjestä osioita tässä lohkossa.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "kirjaimeen nro (lopusta laskien)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "kirjaimeen nro";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "viimeiseen kirjaimeen";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "merkkijonosta";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "hae osa alkaen ensimmäisestä kirjaimesta";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "hae osa alkaen kirjaimesta nro (lopusta laskien)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "hae osa alkaen kirjaimesta nro";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Palauttaa määrätyn osan tekstistä.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "etsi ensimmäinen esiintymä merkkijonolle";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "etsi viimeinen esiintymä merkkijonolle";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Palauttaa ensin annetun tekstin ensimmäisen/viimeisen esiintymän osoitteen toisessa tekstissä. Palauttaa osoitteen %1 jos tekstiä ei löytynyt.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 on tyhjä";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Palauttaa tosi, jos annettu teksti on tyhjä.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "luo teksti";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Luo merkkijonon liittämällä yhteen minkä tahansa määrän kohteita.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1:n pituus";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Palauttaa annetussa tekstissä olevien merkkien määrän (välilyönnit mukaan lukien).";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "tulosta %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Tulostaa annetun tekstin, numeron tai muun arvon.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Kehottaa käyttäjää syöttämään numeron.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Kehottaa käyttäjää syöttämään tekstiä.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "käyttäen annettua viestiä, kehottaa syöttämään numeron";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "käyttäen annettua viestiä, kehottaa syöttämään tekstiä";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://fi.wikipedia.org/wiki/Merkkijono";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Kirjain, sana tai rivi tekstiä.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "poistaa välilyönnit kummaltakin puolelta";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "poistaa välilyönnit vasemmalta puolelta";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "poistaa välilyönnit oikealta puolelta";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Palauttaa kopion tekstistä siten, että välilyönnit on poistettu yhdestä tai molemmista päistä.";
                +Blockly.Msg["TODAY"] = "Tänään";
                +Blockly.Msg["UNDO"] = "Kumoa";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "kohde";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Luo 'aseta %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Palauttaa muuttujan arvon.";
                +Blockly.Msg["VARIABLES_SET"] = "aseta %1 arvoksi %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Luo 'hae %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Asettaa muutujan arvoksi annetun syötteen.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Muuttuja nimeltään '%1' jo olemassa.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/fr.js b/blockly/webif/static/blockly/msg/js/fr.js
                new file mode 100644
                index 000000000..f30cb798a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/fr.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.fr');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Ajouter un commentaire";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Impossible de supprimer la variable '%1' parce qu’elle fait partie de la définition de la fonction '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Modifier la valeur :";
                +Blockly.Msg["CLEAN_UP"] = "Nettoyer les blocs";
                +Blockly.Msg["COLLAPSE_ALL"] = "Réduire les blocs";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Réduire le bloc";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "couleur 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "couleur 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "taux";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mélanger";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Mélange deux couleurs dans une proportion donnée (de 0.0 à 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://fr.wikipedia.org/wiki/Couleur";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choisir une couleur dans la palette.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "couleur aléatoire";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Choisir une couleur au hasard.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "bleu";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "vert";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rouge";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colorier en";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Créer une couleur avec la quantité spécifiée de rouge, vert et bleu. Les valeurs doivent être comprises entre 0 et 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "quitter la boucle";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "passer à l’itération de boucle suivante";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Sortir de la boucle englobante.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Sauter le reste de cette boucle, et poursuivre avec l’itération suivante.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Attention : Ce bloc ne devrait être utilisé que dans une boucle.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "pour chaque élément %1 dans la liste %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Pour chaque élément d’une liste, assigner la valeur de l’élément à la variable '%1', puis exécuter des instructions.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "compter avec %1 de %2 à %3 par %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Faire prendre à la variable « %1 » les valeurs depuis le nombre de début jusqu’au nombre de fin, en s’incrémentant du pas spécifié, et exécuter les instructions spécifiées.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Ajouter une condition au bloc si.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Ajouter une condition finale fourre-tout au bloc si.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Ajouter, supprimer ou réordonner les sections pour reconfigurer ce bloc si.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "sinon";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "sinon si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si une valeur est vraie, alors exécuter certains ordres.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si une valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, exécuter le second bloc d’ordres.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si la première valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, si la seconde valeur est vraie, exécuter le second bloc d’ordres.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si la première valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, si la seconde valeur est vraie, exécuter le second bloc d’ordres. Si aucune des valeurs n’est vraie, exécuter le dernier bloc d’ordres.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "http://fr.wikipedia.org/wiki/Boucle_for";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "faire";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "répéter %1 fois";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Exécuter des instructions plusieurs fois.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "répéter jusqu’à";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "répéter tant que";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Tant qu’une valeur est fausse, alors exécuter des instructions.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Tant qu’une valeur est vraie, alors exécuter des instructions.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Supprimer ces %1 blocs ?";
                +Blockly.Msg["DELETE_BLOCK"] = "Supprimer le bloc";
                +Blockly.Msg["DELETE_VARIABLE"] = "Supprimer la variable '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Supprimer %1 utilisations de la variable '%2' ?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Supprimer %1 blocs";
                +Blockly.Msg["DISABLE_BLOCK"] = "Désactiver le bloc";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Dupliquer";
                +Blockly.Msg["ENABLE_BLOCK"] = "Activer le bloc";
                +Blockly.Msg["EXPAND_ALL"] = "Développer les blocs";
                +Blockly.Msg["EXPAND_BLOCK"] = "Développer le bloc";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entrées externes";
                +Blockly.Msg["HELP"] = "Aide";
                +Blockly.Msg["INLINE_INPUTS"] = "Entrées en ligne";
                +Blockly.Msg["IOS_CANCEL"] = "Annuler";
                +Blockly.Msg["IOS_ERROR"] = "Erreur";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Ajouter une entrée";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Ordres autorisés";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Cette fonction a des entrées dupliquées.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ENTRÉES";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Ajouter";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Ajouter une variable";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Supprimer";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Vous ne pouvez pas utiliser un nom de variable vide.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Renommer";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nom de la variable";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "créer une liste vide";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Renvoyer une liste, de longueur 0, ne contenant aucun enregistrement";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Ajouter, supprimer, ou réordonner les sections pour reconfigurer ce bloc de liste.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "créer une liste avec";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Ajouter un élément à la liste.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Créer une liste avec un nombre quelconque d’éléments.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "premier";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# depuis la fin";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obtenir";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obtenir et supprimer";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "dernier";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aléatoire";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "supprimer";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Renvoie le premier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Renvoie l’élément à la position indiquée dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Renvoie le dernier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Renvoie un élément au hasard dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Supprime et renvoie le premier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Supprime et renvoie l’élément à la position indiquée dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Supprime et renvoie le dernier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Supprime et renvoie un élément au hasard dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Supprime le premier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Supprime l’élément à la position indiquée dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Supprime le dernier élément dans une liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Supprime un élément au hasard dans une liste.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "jusqu’à # depuis la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "jusqu’à #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "jusqu’à la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "obtenir la sous-liste depuis le début";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "obtenir la sous-liste depuis # depuis la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "obtenir la sous-liste depuis #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Crée une copie de la partie spécifiée d’une liste.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 est le dernier élément.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 est le premier élément.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "trouver la première occurrence de l’élément";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "trouver la dernière occurrence de l’élément";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Renvoie l’index de la première/dernière occurrence de l’élément dans la liste. Renvoie %1 si l'élément n'est pas trouvé.";
                +Blockly.Msg["LISTS_INLIST"] = "dans la liste";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 est vide";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Renvoie vrai si la liste est vide.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longueur de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Renvoie la longueur d’une liste.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "créer une liste avec l’élément %1 répété %2 fois";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Crée une liste consistant en la valeur fournie répétée le nombre de fois indiqué.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "inverser %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Inverser la copie d’une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "comme";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insérer en";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "mettre";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insère l’élément au début d’une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insère l’élément à la position indiquée dans une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Ajouter l’élément à la fin d’une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Insère l’élément au hasard dans une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Fixe le premier élément dans une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Met à jour l’élément à la position indiquée dans une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Fixe le dernier élément dans une liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Fixe un élément au hasard dans une liste.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "croissant";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "décroissant";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "trier %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Trier une copie d’une liste.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabétique, en ignorant la casse";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numérique";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabétique";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "créer une liste depuis le texte";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "créer un texte depuis la liste";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Réunir une liste de textes en un seul, en les séparant par un séparateur.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Couper un texte en une liste de textes, en coupant à chaque séparateur.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "avec le séparateur";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "faux";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Renvoie soit vrai soit faux.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "vrai";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://fr.wikipedia.org/wiki/Inegalite_(mathematiques)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Renvoyer vrai si les deux entrées sont égales.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Renvoyer vrai si la première entrée est plus grande que la seconde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Renvoyer vrai si la première entrée est plus grande ou égale à la seconde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Renvoyer vrai si la première entrée est plus petite que la seconde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Renvoyer vrai si la première entrée est plus petite ou égale à la seconde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Renvoyer vrai si les deux entrées sont différentes.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "pas %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Renvoie vrai si l’entrée est fausse. Renvoie faux si l’entrée est vraie.";
                +Blockly.Msg["LOGIC_NULL"] = "nul";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Renvoie nul.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "et";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ou";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Renvoyer vrai si les deux entrées sont vraies.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Renvoyer vrai si au moins une des entrées est vraie.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "si faux";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "si vrai";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Vérifier la condition dans 'test'. Si elle est vraie, renvoie la valeur 'si vrai' ; sinon renvoie la valeur 'si faux'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://fr.wikipedia.org/wiki/Arithmetique";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Renvoie la somme des deux nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Renvoie le quotient des deux nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Renvoie la différence des deux nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Renvoie le produit des deux nombres.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Renvoie le premier nombre élevé à la puissance du second.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "incrémenter %1 de %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Ajouter un nombre à la variable '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Renvoie une des constantes courantes : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infini).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "contraindre %1 entre %2 et %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Contraindre un nombre à être entre les limites spécifiées (incluses).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "est divisible par";
                +Blockly.Msg["MATH_IS_EVEN"] = "est pair";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "est négatif";
                +Blockly.Msg["MATH_IS_ODD"] = "est impair";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "est positif";
                +Blockly.Msg["MATH_IS_PRIME"] = "est premier";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Vérifier si un nombre est pair, impair, premier, entier, positif, négatif, ou s’il est divisible par un certain nombre. Renvoie vrai ou faux.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "est entier";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "reste de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Renvoyer le reste de la division euclidienne des deux nombres.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://fr.wikipedia.org/wiki/Nombre";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un nombre.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "moyenne de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maximum de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "médiane de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimum de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "majoritaires de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "élément aléatoire de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "écart-type de la liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "somme de la liste";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Renvoyer la moyenne (arithmétique) des valeurs numériques dans la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Renvoyer le plus grand nombre dans la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Renvoyer le nombre médian de la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Renvoyer le plus petit nombre dans la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Renvoyer une liste des élément(s) le(s) plus courant(s) dans la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Renvoyer un élément dans la liste au hasard.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Renvoyer l’écart-type de la liste.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Renvoyer la somme de tous les nombres dans la liste.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fraction aléatoire";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Renvoyer une fraction aléatoire entre 0.0 (inclus) et 1.0 (exclus).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "entier aléatoire entre %1 et %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Renvoyer un entier aléatoire entre les deux limites spécifiées, incluses.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arrondir";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arrondir par défaut";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arrondir par excès";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arrondir un nombre au-dessus ou au-dessous.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://fr.wikipedia.org/wiki/Racine_carree";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "valeur absolue";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "racine carrée";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Renvoie la valeur absolue d’un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Renvoie e à la puissance d’un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Renvoie le logarithme naturel d’un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Renvoie le logarithme base 10 d’un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Renvoie l’opposé d’un nombre";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Renvoie 10 à la puissance d’un nombre.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Renvoie la racine carrée d’un nombre.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Renvoie l’arccosinus d’un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Renvoie l’arcsinus d’un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Renvoie l’arctangente d’un nombre.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Renvoie le cosinus d’un angle en degrés (pas en radians).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Renvoie le sinus d’un angle en degrés (pas en radians).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Renvoie la tangente d’un angle en degrés (pas en radians).";
                +Blockly.Msg["NEW_VARIABLE"] = "Créer une variable...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nouveau nom de la variable :";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "autoriser les ordres";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "avec :";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://fr.wikipedia.org/wiki/Sous-programme";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Exécuter la fonction '%1' définie par l’utilisateur.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://fr.wikipedia.org/wiki/Sous-programme";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Exécuter la fonction '%1' définie par l’utilisateur et utiliser son résultat.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "avec :";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Créer '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Décrire cette fonction…";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "faire quelque chose";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "pour";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crée une fonction sans sortie.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retour";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Crée une fonction avec une sortie.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Attention : Cette fonction a des paramètres en double.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Surligner la définition de la fonction";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Si une valeur est vraie, alors renvoyer une seconde valeur.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Attention : Ce bloc pourrait n’être utilisé que dans une définition de fonction.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nom de l’entrée :";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Ajouter une entrée à la fonction.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entrées";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Ajouter, supprimer, ou réarranger les entrées de cette fonction.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Une procédure appelée '%1' existe déjà.";
                +Blockly.Msg["REDO"] = "Refaire";
                +Blockly.Msg["REMOVE_COMMENT"] = "Supprimer un commentaire";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renommer la variable…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renommer toutes les variables « %1 » en :";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "ajouter le texte %2 à %1";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Ajouter du texte à la variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "en minuscules";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "en Majuscule Au Début De Chaque Mot";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "en MAJUSCULES";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Renvoyer une copie du texte dans une autre casse.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obtenir la première lettre";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obtenir la lettre # depuis la fin";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obtenir la lettre #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obtenir la dernière lettre";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obtenir une lettre au hasard";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "dans le texte %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Renvoie la lettre à la position indiquée.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "nombre %1 sur %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Compter combien de fois un texte donné apparait dans un autre.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Ajouter un élément au texte.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "joindre";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Ajouter, supprimer, ou réordonner des sections pour reconfigurer ce bloc de texte.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "jusqu’à la lettre # depuis la fin";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "jusqu’à la lettre #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "jusqu’à la dernière lettre";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "dans le texte";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "obtenir la sous-chaîne depuis la première lettre";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "obtenir la sous-chaîne depuis la lettre # depuis la fin";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "obtenir la sous-chaîne depuis la lettre #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Renvoie une partie indiquée du texte.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "trouver la première occurrence de la chaîne";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "trouver la dernière occurrence de la chaîne";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "dans le texte %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Renvoie l’index de la première/dernière occurrence de la première chaîne dans la seconde. Renvoie %1 si la chaîne n’est pas trouvée.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 est vide";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Renvoie vrai si le texte fourni est vide.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "créer un texte avec";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Créer un morceau de texte en agrégeant un nombre quelconque d’éléments.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longueur de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Renvoie le nombre de lettres (espaces compris) dans le texte fourni.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "afficher %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Afficher le texte, le nombre ou une autre valeur spécifié.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Demander un nombre à l’utilisateur.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Demander un texte à l’utilisateur.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "invite pour un nombre avec un message";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "invite pour un texte avec un message";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "remplacer %1 par %2 dans %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Remplacer toutes les occurrences d’un texte par un autre.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "inverser %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Inverse l’ordre des caractères dans le texte.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Une lettre, un mot ou une ligne de texte.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "supprimer les espaces des deux côtés";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "supprimer les espaces du côté gauche";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "supprimer les espaces du côté droit";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Renvoyer une copie du texte avec les espaces supprimés d’un bout ou des deux.";
                +Blockly.Msg["TODAY"] = "Aujourd'hui";
                +Blockly.Msg["UNDO"] = "Annuler";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "élément";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Créer 'fixer %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Renvoie la valeur de cette variable.";
                +Blockly.Msg["VARIABLES_SET"] = "fixer %1 à %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Créer 'obtenir %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Fixe cette variable pour qu’elle soit égale à la valeur de l’entrée.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Une variable appelée '%1' existe déjà.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/he.js b/blockly/webif/static/blockly/msg/js/he.js
                new file mode 100644
                index 000000000..40ad539f0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/he.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.he');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "הוסף תגובה";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "שנה ערך:";
                +Blockly.Msg["CLEAN_UP"] = "סידור בלוקים";
                +Blockly.Msg["COLLAPSE_ALL"] = "צמצם קטעי קוד";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "צמצם קטע קוד";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "צבע 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "צבע 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "יחס";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "ערבב";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "מערבב שני צבעים יחד עם יחס נתון(0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "http://he.wikipedia.org/wiki/%D7%A6%D7%91%D7%A2";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "בחר צבע מן הצבעים.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "צבע אקראי";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "בחר צבא אקראי.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "כחול";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "ירוק";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "אדום";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "צבע עם";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "צור צבע עם הסכום המצוין של אדום, ירוק וכחול. כל הערכים חייבים להיות בין 0 ל100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "צא מהלולאה";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "המשך עם האיטרציה הבאה של הלולאה";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "צא אל מחוץ ללולאה הכוללת.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "דלג על שאר הלולאה והמשך עם האיטרציה הבאה.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "אזהרה: בלוק זה עשוי לשמש רק בתוך לולאה.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "לכל פריט %1 ברשימה %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "לכל פריט ברשימה, להגדיר את המשתנה '%1' לפריט הזה, ולאחר מכן לעשות כמה פעולות.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "תספור עם %1 מ- %2 ל- %3 עד- %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "תוסיף תנאי לבלוק If.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "לסיום, כל התנאים תקפים לגבי בלוק If.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "תוסיף, תמחק, או תסדר מחדש כדי להגדיר מחדש את הבלוק If.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "אחרת";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "אחרת אם";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "אם";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "אם ערך נכון, לבצע כמה פעולות.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "אם הערך הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, לבצע את הבלוק השני של הפעולות.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "אם הערך הראשון הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, אם הערך השני הוא אמת, לבצע את הבלוק השני של הפעולות.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "אם הערך הראשון הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, אם הערך השני הוא אמת, לבצע את הבלוק השני של הפעולות. אם אף אחד מהם אינו נכון, לבצע את הבלוק האחרון של הפעולות.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "http://he.wikipedia.org/wiki/בקרת_זרימה";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "תעשה";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "חזור על הפעולה %1 פעמים";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "לעשות כמה פעולות מספר פעמים.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "חזור עד ש...";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "חזור כל עוד";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "בזמן שהערך שווה לשגוי, תעשה מספר חישובים.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "כל עוד הערך הוא אמת, לעשות כמה פעולות.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "האם למחוק את כל %1 קטעי הקוד?";
                +Blockly.Msg["DELETE_BLOCK"] = "מחק קטע קוד";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "מחק %1 קטעי קוד";
                +Blockly.Msg["DISABLE_BLOCK"] = "נטרל קטע קוד";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "שכפל";
                +Blockly.Msg["ENABLE_BLOCK"] = "הפעל קטע קוד";
                +Blockly.Msg["EXPAND_ALL"] = "הרחב קטעי קוד";
                +Blockly.Msg["EXPAND_BLOCK"] = "הרחב קטע קוד";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "קלטים חיצוניים";
                +Blockly.Msg["HELP"] = "עזרה";
                +Blockly.Msg["INLINE_INPUTS"] = "קלטים פנימיים";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "צור רשימה ריקה";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "החזר רשימה,באורך 0, המכילה רשומות נתונים";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "רשימה";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "תוסיף, תמחק, או תסדר מחדש כדי להגדיר מחדש את הבלוק If.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "צור רשימה עם";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "הוסף פריט לרשימה.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "צור רשימה עם כל מספר של פריטים.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "ראשון";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# מהסוף";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "לקבל";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "קבל ומחק";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "אחרון";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "אקראי";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "הסרה";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "מחזיר את הפריט הראשון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "מחזיר פריט במיקום שצוין ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "מחזיר את הפריט האחרון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "מחזיר פריט אקראי מהרשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "מסיר ומחזיר את הפריט הראשון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "מסיר ומחזיר את הפריט במיקום שצוין ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "מסיר ומחזיר את הפריט האחרון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "מחק והחזר פריט אקראי מהרשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "הסר את הפריט הראשון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "מחזיר פריט במיקום שצוין ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "הסר את הפריט הראשון ברשימה.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "הסר פריט אקראי ברשימה.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ל # מהסוף";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "ל #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "לאחרון";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "לקבל חלק מהרשימה החל מהתחלה";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "לקבל חלק מהרשימה החל מ-# עד הסוף";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "לקבל חלק מהרשימה החל מ-#";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "יוצרת עותק של חלק מסוים מהרשימה.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 הוא הפריט האחרון.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 הוא הפריט הראשון.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "מחזירה את המיקום הראשון של פריט ברשימה";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "מחזירה את המיקום האחרון של פריט ברשימה";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "מחזירה את האינדקס של המופע הראשון/האחרון של הפריט ברשימה.  מחזירה %1 אם הפריט אינו נמצא.";
                +Blockly.Msg["LISTS_INLIST"] = "ברשימה";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 הוא ריק";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "מחזיר אמת אם הרשימה ריקה.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "אורכו של %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "מחזירה את האורך של רשימה.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "ליצור רשימה עם הפריט %1 %2 פעמים";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "יוצר רשימה המורכבת מהערך נתון חוזר מספר פעמים שצוין.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "כמו";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "הכנס ב";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "הגדר";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "מכניס את הפריט בתחילת רשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "מכניס את הפריט במיקום שצוין ברשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "מוסיף את הפריט בסוף רשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "הוסף פריט באופן אקראי ברשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "מגדיר את הפריט הראשון ברשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "מגדיר את הפריט במיקום שצוין ברשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "מגדיר את הפריט האחרון ברשימה.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "מגדיר פריט אקראי ברשימה.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "סדר עולה";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "סדר יורד";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "סדר אלפביתי, לא תלוי רישיות";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "סדר אלפביתי";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "יצירת רשימה מטקסט";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "יצירת טקסט מרשימה";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "שגוי";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "תחזיר אם נכון או אם שגוי.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "נכון";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "תחזיר נכון אם שני הקלטים שווים אחד לשני.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "תחזיר נכון אם הקלט הראשון גדול יותר מהקלט השני.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "תחזיר נכון אם הקלט הראשון גדול יותר או שווה לכניסה השנייה.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "תחזיר אמת (true) אם הקלט הראשון הוא קטן יותר מאשר הקלט השני.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "תחזיר אמת אם הקלט הראשון הוא קטן יותר או שווה לקלט השני.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "תחזיר אמת אם שני הקלטים אינם שווים זה לזה.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "לא %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "החזר אמת אם הקלט הוא שקר. החזר שקר אם הקלט אמת.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "תחזיר ריק.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ו";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "או";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "תחזיר נכון אם שני הקלטים נכונים.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "תחזיר נכון אם מתקיים לפחות אחד מהקלטים נכונים.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "בדיקה";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "אם שגוי";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "אם נכון";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "בדוק את התנאי ב'מבחן'. אם התנאי נכון, תחזיר את הערך 'אם נכון'; אחרת תחזיר את הערך 'אם שגוי'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://he.wikipedia.org/wiki/ארבע_פעולות_החשבון";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "תחזיר את סכום שני המספרים.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "החזרת המנה של שני המספרים.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "החזרת ההפרש בין שני מספרים.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "החזרת תוצאת הכפל בין שני מספרים.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "החזרת המספר הראשון בחזקת המספר השני.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "שינוי %1 על־ידי %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "הוסף מספר למשתנה '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "מתחלק ב";
                +Blockly.Msg["MATH_IS_EVEN"] = "זוגי";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "שלילי";
                +Blockly.Msg["MATH_IS_ODD"] = "אי-זוגי";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "חיובי";
                +Blockly.Msg["MATH_IS_PRIME"] = "ראשוני";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "שלם";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "שארית החילוק %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "החזרת השארית מחלוקת שני המספרים.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://he.wikipedia.org/wiki/מספר_ממשי";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "מספר.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "ממוצע של רשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "מקסימום של רשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "חציון של רשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "מינימום של רשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "שכיחי הרשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "פריט אקראי מרשימה";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "סכום של רשימה";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "תחזיר את המספר הגדול ביותר ברשימה.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "תחזיר את המספר החיצוני ביותר ברשימה.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "תחזיר את המספר הקטן ביותר ברשימה.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "החזרת רשימה של הפריטים הנפוצים ביותר ברשימה";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "תחזיר רכיב אקראי מרשימה.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "החזרת הסכום של המספרים ברשימה.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "שבר אקראי";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://he.wikipedia.org/wiki/עיגול_(אריתמטיקה)";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "עיגול";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "עיגול למטה";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "עיגול למעלה";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "עיגול מספר למעלה או למטה.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://he.wikipedia.org/wiki/שורש_ריבועי";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "ערך מוחלט";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "שורש ריבועי";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "החזרת הערך המוחלט של מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "החזרת e בחזקת מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "החזרת הלוגריתם הטבעי של מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "החזרת הלוגריתם לפי בסיס עשר של מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "החזרת הערך הנגדי של מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "החזרת 10 בחזקת מספר.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "החזרת השורש הריבועי של מספר.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://he.wikipedia.org/wiki/פונקציות_טריגונומטריות";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "החזרת הקוסינוס של מעלה (לא רדיאן).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "החזרת הסינוס של מעלה (לא רדיאן).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "החזרת הטנגס של מעלה (לא רדיאן).";
                +Blockly.Msg["NEW_VARIABLE"] = "משתנה חדש...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "שם המשתנה החדש:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "לאפשר פעולות";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "עם:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://he.wikipedia.org/wiki/שגרה_(תכנות)";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "להפעיל את הפונקציה המוגדרת על-ידי המשתמש '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://he.wikipedia.org/wiki/שגרה_(תכנות)";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "להפעיל את הפונקציה המוגדרת על-ידי המשתמש '%1' ולהשתמש הפלט שלה.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "עם:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "ליצור '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "לעשות משהו";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "לביצוע:";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "יצירת פונקציה ללא פלט.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "להחזיר";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "יצירת פונקציה עם פלט.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "אזהרה: לפונקציה זו יש פרמטרים כפולים.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "הדגש הגדרה של פונקציה";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "אם ערך נכון, אז להחזיר ערך שני.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "אזהרה: בלוק זה עשוי לשמש רק בתוך הגדרה של פונקציה.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "שם הקלט:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "הוסף קלט לפונקציה";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "מקורות קלט";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "הוסף, הסר או סדר מחדש קלטים לפונקציה זו";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "ביצוע חוזר";
                +Blockly.Msg["REMOVE_COMMENT"] = "הסר תגובה";
                +Blockly.Msg["RENAME_VARIABLE"] = "שנה את שם המשתנה...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "שנה את שם כל '%1' המשתנים ל:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "לאותיות קטנות (עבור טקסט באנגלית)";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "לאותיות גדולות בתחילת כל מילה (עבור טקסט באנגלית)";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "לאותיות גדולות (עבור טקסט באנגלית)";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "צירוף";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "לאות # מהסוף";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "לאות #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "מחזירה את האינדקס של המופע הראשון/האחרון בטקסט הראשון לתוך הטקסט השני. מחזירה %1 אם הטקסט אינו נמצא.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "יצירת טקסט עם";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "הדפס %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "להדפיס טקסט, מספר או ערך אחר שצוין";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "בקש מהמשתמש מספר.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "בקשה למשתמש להזין טקסט כלשהו.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "בקשה למספר עם הודעה";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "בקשה להזנת טקסט עם הודעה";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "אות, מילה, או שורת טקסט.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "למחוק רווחים משני הקצוות";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "למחוק רווחים מימין";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "למחוק רווחים משמאל";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "להחזיר עותק של הטקסט לאחר מחיקת רווחים מאחד או משני הקצוות.";
                +Blockly.Msg["TODAY"] = "היום";
                +Blockly.Msg["UNDO"] = "ביטול";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "פריט";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "ליצור 'הגדר %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "להחזיר את הערך של משתנה זה.";
                +Blockly.Msg["VARIABLES_SET"] = "הגדר %1 ל- %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "ליצור 'קרא %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "מגדיר משתנה זה להיות שווה לקלט.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/hi.js b/blockly/webif/static/blockly/msg/js/hi.js
                new file mode 100644
                index 000000000..b3af3ea27
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/hi.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.hi');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "टिप्पणी छोड़ें";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "मान परिवर्तित करें:";
                +Blockly.Msg["CLEAN_UP"] = "खानों को साफ करें";
                +Blockly.Msg["COLLAPSE_ALL"] = "ब्लॉक संक्षिप्त करें";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ब्लॉक को संक्षिप्त करें";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "रंग 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "रंग 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "अनुपात";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "मिश्रण करें";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "दिए गए अनुपात (0.0 - 1.0) के साथ दो रंगों का मिश्रण करता है।";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "पैलेट से एक रंग चुनें।";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "रैन्डम रंग";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "रैन्डम्ली एक रंग चयन करें।";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "नीला";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "हरा";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "लाल";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "इसके साथ रंग करें";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "लाल, हरा और नीले की निर्दिष्ट मात्रा के साथ एक रंग बनायें। सभी मान ० से १०० के बीच होने चाहिए।";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "लूप से बाहर निकलें";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "लूप का अगला आईटरेशन जारी रखें";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "भीतरी लूप से बाहर निकलें।";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "बाकी बचे लूप को छोड़ें, और अगला आईटरेशन जारी रखें।";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "सावधान: ये ब्लॉक केवल लूप के अंदर इस्तेमाल किया जा सकता है।";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "प्रत्येक आइटम के लिए %1 सूची में %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "सूची के प्रत्येक आयटम के लिए, आयटम में चर का मान '%1' रखें और बाद में कुछ कथन लिखें।";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "काउंट करें";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "यदि ब्लॉक मे एक शर्त जोड़ें।";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "एल्स";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "एल्स इफ";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "इफ";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "यदी मान ट्रू है, तो कुछ स्टेट्मेंट्स चलाएँ।";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "यदि एक मान सत्य है तो कथनों का प्रथम खण्ड बनायें। अन्यथा कथनों का दूसरा भाग निर्मित करें।";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "डू";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 बार दोहराएँ";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "कुछ स्टेट्मन्ट कई बार चलाएँ।";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "दोहराएँ जब तक";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "दोहराएँ जब कि";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "जब तक मान फॉल्स है, तब तक कुछ स्टेट्मेंट्स चलाएँ।";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "जब तक मान ट्रू है, तब तक कुछ स्टेट्मेंट्स चलाएँ।";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "सभी %1 खानों को हटा दें?";
                +Blockly.Msg["DELETE_BLOCK"] = "ब्लॉक हटाएँ";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "'%2' चर के %1 उपयोग को हटाएँ?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 ब्लॉक हटाएँ";
                +Blockly.Msg["DISABLE_BLOCK"] = "ब्लॉक को अक्षम करें";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "कॉपी करें";
                +Blockly.Msg["ENABLE_BLOCK"] = "ब्लॉक को सक्षम करें";
                +Blockly.Msg["EXPAND_ALL"] = "ब्लॉक विस्तार करें";
                +Blockly.Msg["EXPAND_BLOCK"] = "ब्लॉक का विस्तार करें";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "बाहरी इनपुट";
                +Blockly.Msg["HELP"] = "सहायता";
                +Blockly.Msg["INLINE_INPUTS"] = "इनलाइन इनपुट";
                +Blockly.Msg["IOS_CANCEL"] = "रद्द करें";
                +Blockly.Msg["IOS_ERROR"] = "त्रुटि";
                +Blockly.Msg["IOS_OK"] = "ठीक है";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "जोड़ें";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ चर जोड़ें";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "हटाएँ";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "आप रिक्त चर नाम उपयोग नहीं कर सकते";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "नाम बदलें";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "चर का नाम";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "खाली सूची बनाएँ";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "सूची";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "इसके सूची बनाएँ";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "सूची मे एक आइटम जोड़ें।";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "कितने भी आइटम वाली एक सूची बनाएँ।";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "पहला";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "अंत से #";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "प्राप्त";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "प्राप्त करे और हटाए";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "आखिरी";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "रैन्डम";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "निकालें";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "सूची का पहला आइटम रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "सूची का आखरी आइटम रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "सूची से रैन्डम आइटम रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "सूची का पहला आइटम निकालता है और रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "सूची का आखरी आइटम निकालता है और रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "सूची से रैन्डम आइटम निकालता है और रिटर्न करता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "सूची का पहला आइटम निकालता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "सूची का आखरी आइटम निकालता है।";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "सूची से रैन्डम आइटम निकालता है।";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "सूची के बताए गये भाग की कॉपी बनता है।";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "आइटम पहली बार जहाँ आया है उसे ढूढ़े";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "आइटम आखरी बार जहाँ आया है उसे ढूढ़े";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "सूची में";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 खाली है";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "यदि सूची खाली है तो ट्रू रिटर्न करता है।";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 की लंबाई";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "सूची की लंबाई रिटर्न करता है।";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "सैट करें";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "आइटम को सूची के शुरू में इनसर्ट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "सूची मे बताए गये स्थान में आइटम इनसर्ट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "आइटम को सूची के अंत में जोड़ता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "आइटम को सूची में रैन्डम्ली इनसर्ट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "सूची में पहला आइटम सैट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "सूची मे बताए गये स्थान में आइटम सैट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "सूची में आखरी आइटम सैट करता है।";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "सूची में रैन्डम आइटम सैट करता है।";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "अंकीय";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "फॉल्स";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "ट्रू या फॉल्स रिटर्न करता है।";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "ट्रू";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "ट्रू रिटर्न करें यदि दोनो इनपुट इक दूसरे के बराबर हों।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से बड़ा हो।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से बड़ा हो या बराबर हो।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से छोटा हो।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से छोटा हो या बराबर हो।";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "ट्रू रिटर्न करें यदि दोनो इनपुट इक दूसरे के बराबर नहीं हों।";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "NOT (पूरक) %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "ट्रू रिटर्न करता है यदि इनपुट फॉल्स है। फॉल्स रिटर्न करता है यदि इनपुट ट्रू है।";
                +Blockly.Msg["LOGIC_NULL"] = "NULL (अमान्य)";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "null (अमान्य) रिटर्न करता है।";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "AND (तथा)";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "OR (अथवा)";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "ट्रू रिटर्न करें यदि दोनो इनपुट ट्रू हों।";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "ट्रू रिटर्न करें यदि दोनो मे से इक इनपुट ट्रू हो।";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "टेस्ट";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "यदि फॉल्स है";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "यदि ट्रू है";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "दो संख्याओं का योग रिटर्न करें।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "दो संख्याओं का भागफल रिटर्न करें।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "दो संख्याओं का अंतर रिटर्न करें।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "दो संख्याओं का गुणन रिटर्न करें।";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "संख्या को चर '%1' से जोड़ें।";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "इसके द्वारा विभाज्य है";
                +Blockly.Msg["MATH_IS_EVEN"] = "सम है";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ऋणात्मक है";
                +Blockly.Msg["MATH_IS_ODD"] = "विषम है";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "धनात्मक है";
                +Blockly.Msg["MATH_IS_PRIME"] = "अभाज्य है";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "पूर्णांक है";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 का शेषफल";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "दो संख्याओं के भाग का शेषफल रिटर्न करें।";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "एक संख्या।";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "सूची का औसत मान";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "सूची मे अधिकतम";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "सूची की माध्यिका";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "सूची मे न्यूनतम";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "सूची का मोड";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "सूची का रैन्डम आइटम";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "सूची का मानक विचलन";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "सूची का योग";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "सूची मे सबसे बड़ी संख्या रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "सूची की माध्यिका संख्या रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "सूची मे सबसे छोटी संख्या रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "सूची मे सबसे आम आइटम(s) की सूची रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "सूची से एक रैन्डम आइटम रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "सूची का मानक विचलन रिटर्न करें।";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "सूची की सभी संख्याओं का योग रिटर्न करें।";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "रैन्डम अंश";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "%1 से %2 तक रैन्डम पूर्णांक";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "पूर्णांक बनाएँ";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "घटा के पूर्णांक बनाएँ";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "बड़ा के पूर्णांक बनाएँ";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "संख्या को बड़ा या घटा के पूर्णांक बनाएँ।";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "परम";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "वर्गमूल";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "संख्या का परम मान रिटर्न करें।";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "संख्या का प्राकृतिक लघुगणक रिटर्न करें।";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "संख्या का मूल 10 लघुगणक रिटर्न करें।";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "संख्या का निषेध मान रिटर्न करें।";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "संख्या का वर्गमूल रिटर्न करें।";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "संख्या का आर्ककोसाइन रिटर्न करें।";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "संख्या का आर्कसाइन रिटर्न करें।";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "संख्या का आर्कटैन्जन्ट रिटर्न करें।";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "डिग्री का कोसाइन रिटर्न करें (रेडियन नही)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "डिग्री का साइन रिटर्न करें (रेडियन नही)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "डिग्री का टैन्जन्ट रिटर्न करें (रेडियन नही)";
                +Blockly.Msg["NEW_VARIABLE"] = "चर बनाएँ...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "नए चर का नाम:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = ": के साथ";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "यूज़र द्वारा वर्णन किया गया फ़ंक्शन '%1' चलाएँ।";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "यूज़र द्वारा वर्णन किया गया फ़ंक्शन '%1' चलाएँ और उसका आउटपुट इस्तेमाल करें।";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = ": के साथ";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' बनाएँ";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "इस फंकशन को समझाएँ...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "कुछ करें";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "बिना आउटपुट वाला एक फ़ंक्शन बनाता है।";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "रिटर्न";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "आउटपुट वाला एक फ़ंक्शन बनाता है।";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "सावधान: इस फ़ंक्शन मे डुप्लिकेट पैरामीटर हैं।";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "फ़ंक्शन परिभाषा को हाइलाइट करें";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "यदि एक मान ट्रू है तो, दूसरा मान रिटर्न करें।";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "सावधान: ये ब्लॉक फ़ंक्शन परिभाषा के अंदर ही इस्तेमाल किया जा सकता।";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "इनपुट का नाम:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "फंगक्शन को इनपुट प्रदान करें।";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "इनपुट";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "फिर से करें";
                +Blockly.Msg["REMOVE_COMMENT"] = "टिप्पणी हटायें";
                +Blockly.Msg["RENAME_VARIABLE"] = "चर का नाम बदलें...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "सभी '%1' चरों के नाम बदलें:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "कुछ टेक्स्ट इस चर '%1' से जोड़ें।";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "छोटे अक्षर मे";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "टाइटल केस मे";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "बड़े अक्षर मे";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "टेक्स्ट की कॉपी भिन्न केस (अक्षर से संबंधित) मे रिटर्न करें।";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "पहला अक्षर पाएँ";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "आखिर से अक्षर # पाएँ";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "अक्षर # पाएँ";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "आखरी अक्षर पाएँ";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "रैन्डम अक्षर पाएँ";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "बताई गयी जगह से अक्षर रिटर्न करता है";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "सूची मे एक आइटम जोड़ें।";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "जोड़";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "आखिर से यहाँ तक अक्षर #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "यहाँ तक अक्षर #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "यहाँ तक आखरी अक्षर";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "इस टेक्स्ट मे";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "पहले अक्षर से सबस्ट्रिंग पाएँ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "आखरी अक्षर # से सबस्ट्रिंग पाएँ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "अक्षर # से सबस्ट्रिंग पाएँ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "टेक्स्ट का बताया गया अंश रिटर्न करता है";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "टेक्स्ट पहली बार जहाँ आया है उसे ढूढ़े";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "टेक्स्ट आखरी बार जहाँ आया है उसे ढूढ़े";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 खाली है";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "ट्रू रिटर्न करता है यदि दिया गया टेक्स्ट खाली है।";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "इसके साथ टेक्स्ट बनाएँ";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 की लंबाई";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "दिए गये टेक्स्ट मे अक्षरों की संख्या रिटर्न करता है (खाली स्थान मिला के)।";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "प्रिंट करें %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "दिया गया टेक्स्ट प्रिंट करें, संख्या या अन्य मान।";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "यूज़र से संख्या के लिए प्रॉम्प्ट करें।";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "यूज़र से कुछ टेक्स्ट के लिए प्रॉम्प्ट करें।";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "सूचना के साथ संख्या के लिए प्रॉम्प्ट करें";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "सूचना के साथ टेक्स्ट के लिए प्रॉम्प्ट करें";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "एक अक्षर, शब्द, या टेक्स्ट की पंक्ति।";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "रिक्त स्थान को इस टेक्स्ट के दोनों तरफ से निकालें";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "रिक्त स्थान को इस टेक्स्ट के बायें तरफ से निकालें";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "रिक्त स्थान को इस टेक्स्ट के दाईं तरफ से निकालें";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "आज";
                +Blockly.Msg["UNDO"] = "पूर्ववत करें";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "आइटम";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "सेट '%1' बनाएँ";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "इस चर का मान रिटर्न करता है।";
                +Blockly.Msg["VARIABLES_SET"] = "सेट करें %1 को %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "इस चर को इनपुट के बराबर सेट करता है।";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "प्राचल नाम '%1' पहले से मौजूद है।";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/hrx.js b/blockly/webif/static/blockly/msg/js/hrx.js
                new file mode 100644
                index 000000000..02232403f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/hrx.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.hrx');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Kommentar hinzufüche";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Neie Variable...";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Blocke zusammerfalte";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Block zusammerfalte";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "Farreb 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "mit Farreb 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "im Verhältniss";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "misch";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Vermischt 2 Farwe mit konfigurierbare Farrebverhältniss (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://hrx.wikipedia.org/wiki/Farreb";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Wähl en Farreb von der Palett.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "zufälliche Farwe";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Wähl en Farreb noh dem Zufallsprinzip.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blau";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grün";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rot";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "Färreb mit";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Kreiere ene Farreb mit sellrbst definierte rot, grün und blau Wearte. All Wearte müsse zwischich 0 und 100 liehe.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ausbreche aus der Schleif";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "mit der nächste Iteration fortfoohre aus der Schleifa";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Die umgebne Schleif beenne.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Die Oonweisung abbreche und mit der nächste Schleifiteration fortfoohre.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warnung: Die block sollt nuar in en Schleif verwennet sin.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "Für Weart %1 aus der List %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Füahr en Oonweisung für jede Weart in der List aus und setzt dabei die Variable \"%1\" uff den aktuelle List Weart.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "Zähl %1 von %2 bis %3 mit %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Zähl die Variable \"%1\" von enem Startweart bis zu enem Zielweart und füahrefür jede Weart en Oonweisung aus.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "En weitre Bedingung hinzufüche.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "En orrer Bedingung hinzufüche, füahrt en Oonweisung aus falls ken Bedingung zutrifft.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Hinzufüche, entferne orrer sortiere von Sektione";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "orrer";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "orrer wenn";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "wenn";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Wenn en Bedingung woahr (true) ist, dann füahr en Oonweisung aus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Wenn en Bedingung woahr (true) ist, dann füahr die earscht Oonweisung aus.  Ansonscht füahr die zwooite Oonweisung aus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Wenn der erschte Bedingung woahr (true) ist, dann füahr die erschte Oonweisung aus.  Orrer wenn die zwooite Bedingung woahr (true) ist, dann füahr die zwooite Oonweisung aus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Wenn der erscht Bedingung woahr (true) ist, dann füahr die erschte Oonweisung aus.  Orrer wenn die zwooite Bedingung woahr (true) ist, dann füahr die zwooite Oonweisung aus.  Falls ken der beide Bedingungen woahr (true) ist, dann füahr die dritte Oonweisung aus.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://hrx.wikipedia.org/wiki/For-Schleif";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "mach";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "wiederhol %1 mol";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "En Oonweisung meahrfach ausführe.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "Repetiere bis";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "Repetier solang";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Füahr die Oonweisung solang aus wie die Bedingung falsch (false) ist.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Füahr die Oonweisung solang aus wie die Bedingung woahr (true) ist.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "All %1 Bausten lösche?";
                +Blockly.Msg["DELETE_BLOCK"] = "Block lösche";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Block %1 lösche";
                +Blockly.Msg["DISABLE_BLOCK"] = "Block deaktivieren";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kopieren";
                +Blockly.Msg["ENABLE_BLOCK"] = "Block aktivieren";
                +Blockly.Msg["EXPAND_ALL"] = "Blocke expandiere";
                +Blockly.Msg["EXPAND_BLOCK"] = "Block entfalte";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputsexterne Ingänge";
                +Blockly.Msg["HELP"] = "Hellef";
                +Blockly.Msg["INLINE_INPUTS"] = "interne Ingänge";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "Generier/erzeich en leear List";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Generier/erzeich en leear List ohne Inhalt.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "List";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Hinzufüche, entferne und sortiere von Elemente.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "Erzeich List mit";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "En Element zur List hinzufüche.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Generier/erzeich en List mit konfigurierte Elemente.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "earste";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "#te von hinne";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "Nehm";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "Nehm und entfern";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "letzte";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "zufälliches";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "Entfern";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Extrahiert das earste Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Extrahiert das Element zu en definierte Stell von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Extrahiert das letzte Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Extrahiert en zufälliches Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Extrahiert und entfernt das earste Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Extrahiert und entfernt das Element zu en definierte Stell von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Extrahiert und entfernt das letzte Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Extrahiert und entfernt en zufälliches Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Entfernt das earste Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Entfernt das Element zu en definierte Stell von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Entfernt das letzte Element von der List.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Entfernt en zufälliches Element von der List.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "zu # vom End";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "zu #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "zum Letzte";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "hol Unnerliste vom Earste";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "hol Unnerliste von # vom End";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "hol Unnerlist von #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Generiert en Kopie von en definierte Tel von en List.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ist das letzte Element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ist das earschte Element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Such earstes Voarkommniss";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "Such letztes Voarkommniss";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Sucht die Position (index) von en Element in der List Gebt %1 zurück wenn nixs gefunn woard.";
                +Blockly.Msg["LISTS_INLIST"] = "in der List";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ist leear?";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Ist woahr (true), wenn die List leear ist.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "länge %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Die Oonzoohl von Elemente in der List.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Erzich List mit Element %1 wiederhol das %2 mol";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Erzeicht en List mit en variable Oonzoohl von Elemente";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "uff";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "tue ren setz an";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "setz";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Tut das Element an en Oonfang von en List ren setze.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Tut das Element ren setze an en definierte Stell an en List.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Oonhängt das Element zu en List sei End.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Tut das Element zufällich an en List ren setze.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.Setzt das earschte Element an en list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Setzt das Element zu en definierte Stell in en List.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Setzt das letzte Element an en List.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Setzt en zufälliches Element an en List.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falsch";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Ist entweder woahr (true) orrer falsch (false)";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "woahr";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://hrx.wikipedia.org/wiki/Vergleich_%28Zahlen%29";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Ist woahr (true) wenn beide Wearte identisch sind.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Ist woahr (true) wenn der erschte Weart grösser als der zwooite Weart ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Ist woahr (true) wenn der erschte Weart grösser als orrer gleich gross wie zwooite Weart ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Ist woahr (true) wenn der earschte Weart klener als der zwooite Weart ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Ist woahr (true) wenn der earscht Weart klener als orrer gleich gross wie zwooite Weart ist.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Ist woahr (true) wenn beide Wearte unnerschiedlich sind.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "net %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Ist woahr (true) wenn der Ingäweweart falsch (false) ist.  Ist falsch (false) wenn der Ingäweweart woahr (true) ist.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Is NULL.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "und";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "orrer";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Ist woahr (true) wenn beide Wearte woahr (true) sind.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Ist woahr (true) wenn en von der beide Wearte woahr (true) ist.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "wenn falsch";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "wenn woahr";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Üwerprüft en Bedingung \"test\". Wenn die Bedingung woahr ist weerd der \"wenn woahr\" Weart zurückgeb, annerfalls der \"wenn falsch\" Weart";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://hrx.wikipedia.org/wiki/Grundrechenoort";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Ist die Summe zwooier Wearte.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Ist der Quotient zwooier Wearte.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Ist die Differenz zwooier Wearte.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Ist das Produkt zwooier Wearte.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Ist der earschte Weart potenziert mit dem zoiten Weart.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://hrx.wikipedia.org/wiki/Inkrement_und_Dekrement";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "mach höcher / erhöhe %1 um %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Addiert en Weart zur Variable \"%1\" hinzu.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://hrx.wikipedia.org/wiki/Mathematische_Konstante";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Mathematische Konstante wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "begrenze %1 von %2 bis %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Begrenzt den Weartebereich mittels von / bis Wearte. (inklusiv)";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ist telbar/kann getelt sin doorrich";
                +Blockly.Msg["MATH_IS_EVEN"] = "ist grood";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ist negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "ist ungrood";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ist positiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "ist en Primenzoohl";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Üwerprüft ob en Zoohl grood, ungrood, en Primenzoohl, ganzzoohlich, positiv, negativ orrer doorrich en zwooite Zoohl telbar ist.  Gebt woahr (true) orrer falsch (false) zurück.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "ganze Zoohl";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://hrx.wikipedia.org/wiki/Modulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "Rest von %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Der Rest noh en Division.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://hrx.wikipedia.org/wiki/Zoohl";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "En Zoohl.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "Mittelweart en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Maximalweart en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Median von en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Minimalweart von en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "Restweart von en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Zufallsweart von en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "Standart/Padrong Abweichung von en List";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Summe von en List";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Ist der Doorrichschnittsweart von aller Wearte in en List.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Ist der grösste Weart in en List.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Ist der Zentralweart von aller Wearte in en List.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Ist der klenste Weart in en List.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Findt den am häifichste voarkommend Weart in en List.  Falls ken Weart öftersch voarkomme als all annre, weard die originale List zurückgeche";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Geb en Zufallsweart aus der List zurück.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Ist die standartiesierte/padronisierte Standartabweichung/Padrongabweichung von aller Wearte in der List";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Ist die Summ aller Wearte in en List.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://hex.wikipedia.org/wiki/Zufallszoohle";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "Zufallszoohl (0.0 -1.0)";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Generier/erzeich en Zufallszoohl zwischich 0.0 (inklusiv) und 1.0 (exklusiv).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://hrx.wikipedia.org/wiki/Zufallszahlen";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "ganzoohlicher Zufallswearte zwischich %1 bis %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Generier/erzeich en ganzähliche Zufallsweart zwischich zwooi Wearte (inklusiv).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://hrx.wikipedia.org/wiki/Runden";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "runde";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ab runde";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "uff runde";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "En Zoohl uff orrer ab runde.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://hrx.wikipedia.org/wiki/Quadratwoorzel";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "Absolutweart";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "Quadratwoorzel";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Ist der Absolutweart von en Weart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Ist Weart von der Exponentialfunktion von en Weart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Ist der natüarliche Logarithmus von en Weart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Ist der dekoodische Logarithmus von en Weart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Negiert en Weart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Rechnet 10 hoch Ingäbweart.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Ist die Qudratwoorzel von en Weart.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://hrx.wikipedia.org/wiki/Trigonometrie";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Ist der Arcuscosinus von en Ingabweart.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Ist der Arcussinus von en Ingäbweart.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Ist der Arcustangens von en Ingäbweart.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Ist der Cosinus von en Winkel.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Ist der Sinus von en Winkel.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Ist der Tangens von en Winkel.";
                +Blockly.Msg["NEW_VARIABLE"] = "Neie Variable...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Die neie Variable sei Noome:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "mit:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://hrx.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Ruf en Funktionsblock ohne Rückgäweart uff.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://hrx.wikipedia.org/wiki/Prozedur_%28Programmierung%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Ruf en Funktionsblock mit Rückgäbweart uff.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "mit:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Generier/erzeich \"Uffruf %1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "Funktionsblock";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "zu";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "En Funktionsblock ohne Rückgäbweart.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "geb zurück";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "En Funktionsblock mit Rückgäbweart.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warnung: die Funktionsblock hot doppelt Parameter.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Markiear Funktionsblock";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Wenn der earste Weart woahr (true) ist, Geb den zwooite Weart zurück.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warnung: Der Block därref nuar innich en Funktionsblock genutzt sin.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Markiear Funktionsblock";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Generier/erzeich \"Uffruf %1\"";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "Parameter";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Variable:";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Kommentar entferne";
                +Blockly.Msg["RENAME_VARIABLE"] = "Die neie Variable sei Noome:";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "All \"%1\" Variable umbenenne in:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Text an die Variable \"%1\" oonhänge.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "umwandle in klenbuchstoobe";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "umwandle in Wörter";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "umwandle in GROSSBUCHSTOOBE";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Wandelt Schreibweise von Texte um, in Grossbuchstoobe, Klenbuchstoobe orrer den earste Buchstoob von jedes Wort gross und die annre klen.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "hol earschte Buchstoob";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "hol Buchstoob # von End";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "hol Buchstoob #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "hol letztes Wort";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "hol zufälliches Buchstoob";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Extrahiear en Buchstoob von en spezifizierte Position.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "En Element zum Text hinzufüche.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "verbinne";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Hinzufüche, entfernne und sortiere von Elemente.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "bis #te Buchstoob von hinne";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "bis Buchstoob #te";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "bis letzte Buchstoob";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in Text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "earschte Buchstoob";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "hol #te Buchstoob von hinne";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "hol substring Buchstoob #te";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Schickt en bestimmstes Tel von dem Text retuar.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "Such der Begriff sein earstes Voarkommniss";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "Suche der Begriff sein letztes Vorkommniss.";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Findt das earste / letzte Voarkommniss von en Suchbegriffes in enem Text.  Gebt die Position von dem Begriff orrer %1 zurück.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ist leer?";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Ist woahr (true), wenn der Text leer ist.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "Erstell Text aus";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Erstellt en Text doorrich das verbinne von mehre Textelemente.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "läng %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Die Oonzoohl von Zeiche in enem Text. (inkl. Leerzeiche)";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "Ausgäb %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Geb den Inhalt von en Variable aus.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Frocht den Benutzer noh en Zoohl.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Frocht den Benutzer noh enem Text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Frächt noh Zoohl mit Hinweis";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Frocht noh Text mit Hinweis";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)https://hrx.wikipedia.org/wiki/Zeichenkette";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "En Buchstoob, Text orrer Satz.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "entfern Leerzeiche von Oonfang und End Seite";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "entferne Leerzeiche von Oonfang Seite";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "entferne Leerzeiche von End Seite von";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Entfernt Leerzeiche vom Oonfang und / orrer End von en Text.";
                +Blockly.Msg["TODAY"] = "Today";  // untranslated
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "Element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Generier/erzeiche \"Schreibe %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Gebt der Variable sein Weart zurück.";
                +Blockly.Msg["VARIABLES_SET"] = "Schreib %1 zu %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Generier/erzeich \"Lese %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Setzt en Variable sei Weart.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/hu.js b/blockly/webif/static/blockly/msg/js/hu.js
                new file mode 100644
                index 000000000..6c2e90a12
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/hu.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.hu');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Megjegyzés hozzáadása";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Érték módosítása:";
                +Blockly.Msg["CLEAN_UP"] = "Blokkok kiürítése";
                +Blockly.Msg["COLLAPSE_ALL"] = "Blokkok összecsukása";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Blokk összecsukása";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "szín 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "szín 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "arány";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "színkeverés";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Két színt kever össze a megadott arányban (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://hu.wikipedia.org/wiki/Szín";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Válassz színt a palettáról.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "véletlen szín";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Véletlenszerűen kiválasztott szín.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "kék";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zöld";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "vörös";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "Szín";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Szín előállítása a megadott vörös, zöld, és kék értékekkel.  Minden értéknek 0 és 100 közé kell esnie.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "befejezi az ismétlést";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "folytatja a következővel";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Megszakítja az utasítást tartalmazó ciklust.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Kihagyja a ciklus további részét, és elölről kezdi a következő elemmel.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Figyelem: Ez a blokk csak cikluson belül használható.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "minden %1 elemre a %2 listában";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "A '%1' változó minden lépésben megkapja a lista adott elemének értékét, és végrehajt vele néhány utasítást.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "számolj %1 értékével %2 és %3 között %4 lépésközzel";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "A(z) '%1' változó felveszi a kezdőérték és a végérték közötti értékeket a meghatározott lépésközzel. Eközben a meghatározott blokkokat hajtja végre.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Feltétel hozzáadása a ha blokkhoz.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Végső feltétel hozzáadása a ha blokkhoz.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "A ha blokk testreszabásához bővítsd, töröld vagy rendezd át a részeit.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "különben";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "különben ha";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ha";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ha a kifejezés igaz, akkor végrehajtja az utasításokat.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ha a kifejezés igaz, akkor végrehajtja az első utasításblokkot. Különben a második utasításblokk kerül végrehajtásra.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ha az első kifejezés igaz, akkor végrehajtja az első utasításblokkot. Különben, ha a második kifejezés igaz, akkor végrehajtja a második utasítás blokkot.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ha az első kifejezés igaz, akkor végrehajtjuk az első utasítás blokkot.  Ha a második kifejezés igaz, akkor végrehajtjuk a második utasítás blokkot.  Amennyiben egyik kifejezés sem igaz, akkor az utolsó utasítás blokk kerül végrehajtásra.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://hu.wikipedia.org/wiki/Ciklus_(programoz%C3%A1s)#Sz.C3.A1ml.C3.A1l.C3.B3s_.28FOR.29_ciklus";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ismételd %1 alkalommal";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Megadott kódrészlet ismételt végrehajtása.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ismételd amíg";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ismételd amíg";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Amíg a feltétel hamis, végrehajtja az utasításokat.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Amíg a feltétel igaz, végrehajtja az utasításokat.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Az összes %1 blokk törlése?";
                +Blockly.Msg["DELETE_BLOCK"] = "Blokk törlése";
                +Blockly.Msg["DELETE_VARIABLE"] = "A(z) „%1” változó törlése";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "A(z) „%2” változó %1 használatának törlése?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 blokk törlése";
                +Blockly.Msg["DISABLE_BLOCK"] = "Blokk letiltása";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Másolat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Blokk engedélyezése";
                +Blockly.Msg["EXPAND_ALL"] = "Blokkok kinyitása";
                +Blockly.Msg["EXPAND_BLOCK"] = "Blokk kinyitása";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Külső kapcsolatok";
                +Blockly.Msg["HELP"] = "Súgó";
                +Blockly.Msg["INLINE_INPUTS"] = "Belső kapcsolatok";
                +Blockly.Msg["IOS_CANCEL"] = "Mégse";
                +Blockly.Msg["IOS_ERROR"] = "Hiba";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Ennek a függvénynek kettőzött bemenete van.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Hozzáadás";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Változó hozzáadása";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Törlés";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Nem használhat üres változónevet.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Átnevezés";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Változó neve";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "üres lista";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Elemeket nem tartalmazó üres listát ad eredményül";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "Lista készítés, elemek:";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Elem hozzáadása listához.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Listát készít a megadott elemekből.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "az első";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "a végétől számított";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "az elejétől számított";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "listából értéke";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "listából kivétele";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "az utolsó";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "bármely";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "listából törlése";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "elemnek";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "A lista első elemét adja eredményül.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "A lista megadott sorszámú elemét adja eredményül.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "A lista utolsó elemét adja eredményül.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "A lista véletlenszerűen választott elemét adja eredményül.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Az első elem kivétele a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "A megadott sorszámú elem kivétele a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Az utolsó elem kivétele a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Véletlenszerűen választott elem kivétele a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Az első elem törlése a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "A megadott sorszámú elem törlése a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Az utolsó elem törlése a listából.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Véletlenszerűen választott elem törlése a listából.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "és a végétől számított";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "és az elejétől számított";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "és az utolsó";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "részlistája az első";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "részlistája a végétől számított";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "részlistája az elejétől számított";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "elem között";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "A lista adott részéről másolat.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 az utolsó elemet jelenti.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 az első elemet jelenti.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "listában első előfordulásaː";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "listában utolsó előfordulásaː";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "A megadott elem első vagy utolsó előfordulásával tér vissza. Ha nem talál ilyen elemet, akkor %1 a visszatérési érték.";
                +Blockly.Msg["LISTS_INLIST"] = "A(z)";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 üres lista?";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Az eredmény igaz, ha a lista nem tartalmaz elemeket.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 lista hossza";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "A lista elemszámát adja eredményül.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Lista készítése %1 elemet %2 alkalommal hozzáadva";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "A megadtott elem felhasználásával n elemű listát készít";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "elemkéntː";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "listába szúrd be";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "listába állítsd be";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Beszúrás a lista elejére.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Beszúrás a megadott sorszámú elem elé a listában.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Beszúrás a lista végére.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Beszúrás véletlenszerűen választott elem elé a listában.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Az első elem cseréje a listában.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "A megadott sorszámú elem cseréje a listában.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Az utolsó elem cseréje a listában.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Véletlenszerűen választott elem cseréje a listában.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "növekvő";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "csökkenő";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "%1 %2 %3 rendezés";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Egy lista egy másolatának rendezése.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "betűrendben nagybetű figyelmen kívül hagyásával";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerikus";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "betűrendben";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "lista készítése szövegből";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "sztring készítése listából";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "A lista elemeit összefűzi szöveggé a határoló karaktereket is felhasználva.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Listát készít a határoló karaktereknél törve a szöveget.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "határoló karakter";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "hamis";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Igaz, vagy hamis érték";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "igaz";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://hu.wikipedia.org/wiki/Egyenl%C5%91tlens%C3%A9g";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Igaz, ha a kifejezés két oldala egyenlő.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Igaz, ha a bal oldali kifejezés nagyobb, mint a jobb oldali.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Igaz, ha a bal oldali kifejezés nagyobb vagy egyenlő, mint a jobb oldali.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Igaz, ha a bal oldali kifejezés kisebb, mint a jobb oldali.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Igaz, ha a bal oldali kifejezés kisebb vagy egyenlő, mint a jobb oldali.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Igaz, ha a kifejezés két oldala nem egyenlő..";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nem %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Igaz, ha a kifejezés hamis.  Hamis, ha a kifejezés igaz.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "null érték.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "és";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "vagy";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Igaz, ha mindkét kifejezés igaz.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Igaz, ha legalább az egyik kifejezés igaz.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "vizsgáld meg:";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "érték, ha hamis:";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "érték, ha igaz:";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kiértékeli a megvizsgálandó kifejezést. Ha a kifejezés igaz, visszatér az \"érték, ha igaz\" értékkel, különben az \"érték, ha hamis\" értékkel.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://hu.wikipedia.org/wiki/Matematikai_m%C5%B1velet";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Két szám összege.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Két szám hányadosa.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Két szám különbsége.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Két szám szorzata.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Az első számnak a második számmal megegyező hatványa.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://hu.wikipedia.org/wiki/JavaScript#Aritmetikai_oper.C3.A1torok";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "növeld %1 értékét %2 -vel";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "A \"%1\" változó értékének növelése egy számmal.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://hu.wikipedia.org/wiki/Matematikai_konstans";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Ismert matematikai konstans: π (3.141…), e (2.718…), φ (1.618…), gyök(2) (1.414…), gyök(½) (0.707…), vagy ∞ (végtelen).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "korlátozd %1-t %2 és %3 közé";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Egy változó értékének korlátozása a megadott zárt intervallumra.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "-nek osztója";
                +Blockly.Msg["MATH_IS_EVEN"] = "páros";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "negatív";
                +Blockly.Msg["MATH_IS_ODD"] = "páratlan";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "pozitív";
                +Blockly.Msg["MATH_IS_PRIME"] = "prím";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Ellenőrzi, hogy a szám páros, páratlan, prím, egész, pozitív vagy negatív-e, illetve osztható-e a másodikkal. Igaz, vagy hamis értéket ad eredményül.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "egész";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://hu.wikipedia.org/wiki/Eg%C3%A9szr%C3%A9sz#Als.C3.B3_eg.C3.A9szr.C3.A9sz";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 maradéka";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Az egész osztás maradékát adja eredméynül.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://hu.wikipedia.org/wiki/Sz%C3%A1m";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Egy szám.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "lista elemeinek átlaga";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "lista legnagyobb eleme";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "lista mediánja";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "lista legkisebb eleme";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "lista módusza";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "lista véletlen eleme";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "lista elemeinek szórása";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "lista elemeinek összege";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "A lista elemeinek átlagát adja eredményül.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "A lista legnagyobb elemét adja vissza.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "A lista elemeinek mediánját adja eredményül.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "A lista legkisebb elemét adja vissza.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "A lista elemeinek móduszát adja eredményül.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "A lista egy véletlen elemét adja eredményül.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "A lista elemeinek szórását adja eredményül.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "A lista elemeinek összegét adja eredményül.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://hu.wikipedia.org/wiki/V%C3%A9letlen";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "véletlen tört";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Véletlen tört érték 0.0 és 1.0 között.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://hu.wikipedia.org/wiki/V%C3%A9letlen";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "véletlen egész szám %1 között %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Véletlen egész szám a megadott zárt intervallumon belül.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://hu.wikipedia.org/wiki/Eg%C3%A9szr%C3%A9sz#Kerek.C3.ADt.C3.A9s";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "kerekítsd";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "kerekítsd lefelé";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "kerekítsd felfelé";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Egy szám kerekítése felfelé vagy lefelé.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://hu.wikipedia.org/wiki/Gy%C3%B6kvon%C3%A1s";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "abszolútérték";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "négyzetgyök";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "A szám abszolútértéke.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Az e megadott számú hatványa.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "A szám természetes alapú logaritmusa.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "A szám 10-es alapú logaritmusa.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "A szám -1 szerese.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "A 10 megadott számú hatványa.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "A szám négyzetgyöke.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://hu.wikipedia.org/wiki/Sz%C3%B6gf%C3%BCggv%C3%A9nyek";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "A fokban megadott szög arkusz koszinusz értéke.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "A fokban megadott szög arkusz szinusz értéke.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "A fokban megadott szög arkusz tangens értéke.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "A fokban megadott szög koszinusz értéke.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "A fokban megadott szög szinusz értéke.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "A fokban megadott szög tangens értéke.";
                +Blockly.Msg["NEW_VARIABLE"] = "Változó létrehozása…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Az új változó neve:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = ".";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "utasítások engedélyezése";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "paraméterlistaː";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://hu.wikipedia.org/wiki/F%C3%BCggv%C3%A9ny_(programoz%C3%A1s)";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Végrehajtja az eljárást.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://hu.wikipedia.org/wiki/F%C3%BCggv%C3%A9ny_(programoz%C3%A1s)";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Meghívja a függvényt.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "paraméterlistaː";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "„%1” létrehozása";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Írj erről a funkcióról...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "név";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "Eljárás";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Eljárás (nem ad vissza eredményt).";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "eredménye";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Függvény eredménnyel.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Figyelem: Az eljárásban azonos elnevezésű paramétert adtál meg.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Függvénydefiníció kiemelése";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ha az érték igaz, akkor visszatér a függvény értékével.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Figyelem: Ez a blokk csak függvénydefiníción belül használható.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "változó:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Bemenet hozzáadása a függvényhez.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "paraméterek";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Bemenetek hozzáadása, eltávolítása vagy átrendezése ehhez a függvényhez.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Újra";
                +Blockly.Msg["REMOVE_COMMENT"] = "Megjegyzés eltávolítása";
                +Blockly.Msg["RENAME_VARIABLE"] = "Változó átnevezése…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Minden „%1” változó átnevezése erre:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Szöveget fűz a \"%1\" változó értékéhez.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "kisbetűs";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Címként Formázott";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "NAGYBETŰS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "első";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "hátulról";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "elölről";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "utolsó";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "véletlen";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "karaktere";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "A szöveg egy megadott karakterét adja eredményül.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Elem hozzáfűzése a szöveghez.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "fűzd össze";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Összefűzéssel, törléssel vagy rendezéssel kapcsolato sblokkok szöveg szerkesztéséhez.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "betűtől a hátulról számított";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "betűtől a(z)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "betűtől az utolsó";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "a";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "szövegben válaszd ki az első";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "szövegben válaszd ki a hátulról a(z)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "szövegben válaszd ki a(z)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "betűig tartó betűsort";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "A megadott szövegrészletet adja eredményül.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "szövegben az első előfordulásának helye";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "szövegben az utolsó előfordulásának helye";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "A keresett szöveg első vagy utolsó előfordulásával tér vissza.  %1 esetén a szövegrészlet nem található.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 üres";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Igaz, ha a vizsgált szöveg hossza 0.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "fűzd össze";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Tetszőleges számú szövegrészletet fűz össze egybefüggő szöveggé.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 hossza";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "A megadott szöveg karaktereinek számát adja eredményül (beleértve a szóközöket).";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "Üzenet %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Megejelníti a megadott kaakterláncot üzenetként a képernyőn.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Számot kér be a felhasználótól.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Szöveget kér be a felhasználótól.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Kérj be számot";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Kérj be szöveget";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "%1 cseréje %2-vel %3-ban";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://hu.wikipedia.org/wiki/String";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Egy betű, szó vagy szöveg egy sora.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "szóközök levágása mindkét végéről";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "szóközök levágása az elejéről";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "szóközök levágása a végéről";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Levágja a megadott szöveg végeiről a szóközöket.";
                +Blockly.Msg["TODAY"] = "Ma";
                +Blockly.Msg["UNDO"] = "Visszavonás";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "változó";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Készíts \"%1=\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "A változó értékét adja eredményül.";
                +Blockly.Msg["VARIABLES_SET"] = "%1 %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Készíts \"%1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "A változónak adhatunk értéket.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A(z) „%1” nevű változó már létezik.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ia.js b/blockly/webif/static/blockly/msg/js/ia.js
                new file mode 100644
                index 000000000..17498a0b7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ia.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ia');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Adder commento";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Cambiar valor:";
                +Blockly.Msg["CLEAN_UP"] = "Clarar le blocos";
                +Blockly.Msg["COLLAPSE_ALL"] = "Plicar blocos";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Plicar bloco";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "color 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "color 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ration";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "miscer";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Misce duo colores con un ration specificate (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ia.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Elige un color del paletta.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "color aleatori";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Eliger un color al hasardo.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blau";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rubie";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colorar con";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Crear un color con le quantitate specificate de rubie, verde e blau. Tote le valores debe esser inter 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "escappar del bucla";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continuar con le proxime iteration del bucla";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Escappar del bucla continente.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Saltar le resto de iste bucla e continuar con le proxime iteration.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Attention: Iste bloco pote solmente esser usate in un bucla.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "pro cata elemento %1 in lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Pro cata elemento in un lista, mitter lo in le variabile '%1' e exequer certe instructiones.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "contar con %1 de %2 a %3 per %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Mitter in le variabile '%1' le valores ab le numero initial usque al numero final, con passos secundo le intervallo specificate, e exequer le blocos specificate.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Adder un condition al bloco \"si\".";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Adder un condition final de reserva al bloco \"si\".";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Adde, remove o reordina sectiones pro reconfigurar iste bloco \"si\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "si non";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "si non si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si un valor es ver, exequer certe instructiones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si un valor es ver, exequer le prime bloco de instructiones. Si non, exequer le secunde bloco de instructiones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si le prime valor es ver, exequer le prime bloco de instructiones. Si non, si le secunde valor es ver, exequer le secunde bloco de instructiones.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si le prime valor es ver, exequer le prime bloco de instructiones. Si non, si le secunde valor es ver, exequer le secunde bloco de instructiones. Si necun del valores es ver, exequer le ultime bloco de instructiones.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "face";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repeter %1 vices";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Exequer certe instructiones plure vices.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repeter usque a";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repeter durante que";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Durante que un valor es false, exequer certe instructiones.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Durante que un valor es ver, exequer certe instructiones.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Deler tote le %1 blocos?";
                +Blockly.Msg["DELETE_BLOCK"] = "Deler bloco";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Deler %1 blocos";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disactivar bloco";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicar";
                +Blockly.Msg["ENABLE_BLOCK"] = "Activar bloco";
                +Blockly.Msg["EXPAND_ALL"] = "Displicar blocos";
                +Blockly.Msg["EXPAND_BLOCK"] = "Displicar bloco";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entrata externe";
                +Blockly.Msg["HELP"] = "Adjuta";
                +Blockly.Msg["INLINE_INPUTS"] = "Entrata interne";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "crear un lista vacue";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Retorna un lista, de longitude 0, sin datos.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Adde, remove o reordina sectiones pro reconfigurar iste bloco de listas.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "crear lista con";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Adder un elemento al lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Crear un lista con un numero qualcunque de elementos.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "prime";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "№ ab fin";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "prender";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "prender e remover";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ultime";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleatori";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remover";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Retorna le prime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Retorna le elemento presente al position specificate in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Retorna le ultime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Retorna un elemento aleatori in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Remove e retorna le prime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Remove e retorna le elemento presente al position specificate in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Remove e retorna le ultime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Remove e retorna un elemento aleatori in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Remove le prime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Remove le elemento presente al position specificate in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Remove le ultime elemento in un lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Remove un elemento aleatori in un lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "usque al № ab fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "usque al №";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "usque al ultime";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "prender sublista ab initio";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "prender sublista ab le fin ab №";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "prender sublista ab №";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Crea un copia del parte specificate de un lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "№ %1 es le ultime elemento.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "№ %1 es le prime elemento.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "cercar le prime occurrentia del elemento";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "cercar le ultime occurrentia del elemento";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Retorna le indice del prime/ultime occurrentia del elemento in le lista. Retorna %1 si le elemento non es trovate.";
                +Blockly.Msg["LISTS_INLIST"] = "in lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 es vacue";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Retorna ver si le lista es vacue.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longitude de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Retorna le longitude de un lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "crear lista con elemento %1 repetite %2 vices";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Crea un lista que contine le valor fornite, repetite le numero specificate de vices.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "a";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserer in";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "mitter";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insere le elemento al initio de un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insere le elemento al position specificate in un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Adjunge le elemento al fin de un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Insere le elemento a un position aleatori in un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Defini le valor del prime elemento in un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Defini le valor del elemento al position specificate in un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Defini le valor del ultime elemento in un lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Defini le valor de un elemento aleatori in un lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascendente";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descendente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "ordinamento %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordinar un copia de un lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignorar majuscula/minuscula";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "Crear un lista per un texto";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "crear un texto per un lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Unir un lista de textos, separate per un delimitator, in un sol texto.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Divider texto in un lista de textos, separante lo a cata delimitator.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "con delimitator";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Retorna o ver o false.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "ver";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Retornar ver si le duo entratas es equal.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Retornar ver si le prime entrata es major que le secunde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Retornar ver si le prime entrata es major que o equal al secunde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Retornar ver si le prime entrata es minor que le secunde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Retornar ver si le prime entrata es minor que o equal al secunde.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Retornar ver si le duo entratas non es equal.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "non %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Retornar ver si le entrata es false. Retornar false si le entrata es ver.";
                +Blockly.Msg["LOGIC_NULL"] = "nulle";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Retorna nulle.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Retornar ver si ambe entratas es ver.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Retornar ver si al minus un del entratas es ver.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "si false";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "si ver";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Verificar le condition in 'test'. Si le condition es ver, retorna le valor de 'si ver'; si non, retorna le valor de 'si false'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ia.wikipedia.org/wiki/Arithmetica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Retornar le summa del duo numeros.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Retornar le quotiente del duo numeros.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Retornar le differentia del duo numeros.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Retornar le producto del duo numeros.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Retornar le prime numero elevate al potentia del secunde numero.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "cambiar %1 per %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Adder un numero al variabile '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Retornar un del constantes commun: π (3,141…), e (2,718…), φ (1,618…), sqrt(2) (1,414…), sqrt(½) (0,707…) o ∞ (infinite).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "limitar %1 inter %2 e %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Limitar un numero a esser inter le limites specificate (incluse).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "es divisibile per";
                +Blockly.Msg["MATH_IS_EVEN"] = "es par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "es negative";
                +Blockly.Msg["MATH_IS_ODD"] = "es impare";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "es positive";
                +Blockly.Msg["MATH_IS_PRIME"] = "es prime";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Verificar si un numero es par, impare, prime, integre, positive, negative, o divisibile per un certe numero. Retorna ver o false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "es integre";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Retornar le resto del division del duo numeros.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ia.wikipedia.org/wiki/Numero";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un numero.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "media del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maximo del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimo del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modas del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "elemento aleatori del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviation standard del lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summa del lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Retornar le media arithmetic del valores numeric in le lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Retornar le numero le plus grande in le lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Retornar le numero median del lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Retornar le numero le plus parve in le lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Retornar un lista del elemento(s) le plus commun in le lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Retornar un elemento aleatori del lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Retornar le deviation standard del lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Retornar le summa de tote le numeros in le lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fraction aleatori";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Retornar un fraction aleatori inter 0.0 (incluse) e 1.0 (excluse).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "numero integre aleatori inter %1 e %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Retornar un numero integre aleatori inter le duo limites specificate, incluse.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ia.wikipedia.org/wiki/Rotundamento";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arrotundar";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arrotundar a infra";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arrotundar a supra";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arrotundar un numero a supra o a infra.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ia.wikipedia.org/wiki/Radice_quadrate";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "radice quadrate";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Retornar le valor absolute de un numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Retornar e elevate al potentia del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Retornar le logarithmo natural de un numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Retornar le logarithmo in base 10 del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Retornar le negation de un numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Retornar 10 elevate al potentia de un numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Retornar le radice quadrate de un numero.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Retornar le arcocosino de un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Retornar le arcosino de un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Retornar le arcotangente de un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Retornar le cosino de un grado (non radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Retornar le sino de un grado (non radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Retornar le tangente de un grado (non radiano).";
                +Blockly.Msg["NEW_VARIABLE"] = "Nove variabile...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nomine del nove variabile:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permitter declarationes";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Executar le function '%1' definite per le usator.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Executar le function '%1' definite per le usator e usar su resultato.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Crear '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe iste function...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "facer qualcosa";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "pro";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crea un function que non retorna un valor.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retornar";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Crea un function que retorna un valor.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Attention: Iste function ha parametros duplicate.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Accentuar le definition del function";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Si un valor es ver, alora retornar un secunde valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Attention: Iste bloco pote solmente esser usate in le definition de un function.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nomine del entrata:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Adder un entrata al function.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entratas";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Adder, remover o reordinar le entratas pro iste function.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Refacer";
                +Blockly.Msg["REMOVE_COMMENT"] = "Remover commento";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renominar variabile...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renominar tote le variabiles '%1' a:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Adjunger un texto al variabile '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "in minusculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "con Initiales Majuscule";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "in MAJUSCULAS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Retornar un copia del texto con differente majusculas/minusculas.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "prender le prime littera";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "prender ab le fin le littera №";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "prender le littera №";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "prender le ultime littera";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "prender un littera aleatori";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Retorna le littera presente al position specificate.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Adder un elemento al texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Adde, remove o reordina sectiones pro reconfigurar iste bloco de texto.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "ab le fin usque al littera №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "usque al littera №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "usque al ultime littera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in le texto";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "prender subcatena ab le prime littera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "prender subcatena ab le fin ab le littera №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "prender subcatena ab le littera №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Retorna le parte specificate del texto.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "cercar le prime occurrentia del texto";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "cercar le ultime occurrentia del texto";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Retorna le indice del prime/ultime occurrentia del prime texto in le secunde texto. Retorna %1 si le texto non es trovate.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 es vacue";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Retorna ver si le texto fornite es vacue.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "crear texto con";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Crear un pecia de texto uniente un certe numero de elementos.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longitude de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Retorna le numero de litteras (incluse spatios) in le texto fornite.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "scriber %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Scriber le texto, numero o altere valor specificate.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Peter un numero al usator.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Peter un texto al usator.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "peter un numero con le message";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "peter un texto con le message";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Un littera, parola o linea de texto.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "remover spatios de ambe lateres de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "remover spatios del sinistre latere de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "remover spatios del dextre latere de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Retornar un copia del texto con spatios eliminate de un extremitate o ambes.";
                +Blockly.Msg["TODAY"] = "Hodie";
                +Blockly.Msg["UNDO"] = "Disfacer";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "cosa";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crea 'mitter %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Retorna le valor de iste variabile.";
                +Blockly.Msg["VARIABLES_SET"] = "mitter %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Crear 'prender %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Mitte iste variabile al valor del entrata.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/id.js b/blockly/webif/static/blockly/msg/js/id.js
                new file mode 100644
                index 000000000..24bf778b6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/id.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.id');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Tambahkan Komentar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ubah nilai:";
                +Blockly.Msg["CLEAN_UP"] = "Bersihkan Blok";
                +Blockly.Msg["COLLAPSE_ALL"] = "Ciutkan Blok";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Ciutkan Blok";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "warna 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "warna 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "rasio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "campur";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Campur dua warna secara bersamaan dengan perbandingan (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Pilih warna dari daftar warna.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "Warna acak";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Pilih warna secara acak.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "biru";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "hijau";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "merah";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "Dengan warna";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Buatlah warna dengan jumlah yang ditentukan dari merah, hijau dan biru. Semua nilai harus antarai 0 sampai 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "keluar dari perulangan";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "lanjutkan dengan langkah perulangan berikutnya";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Keluar dari perulangan.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Abaikan sisa dari perulangan ini, dan lanjutkan dengan langkah berikutnya.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Peringatan: Blok ini hanya dapat digunakan dalam perulangan.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "untuk setiap item %1 di dalam list %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Untuk tiap-tiap item di dalam list, tetapkan variabel '%1' ke dalam item, selanjutnya kerjakan beberapa statement.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "Cacah dengan %1 dari %2 ke %3 dengan step / penambahan %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Menggunakan variabel \"%1\" dengan mengambil nilai dari batas awal hingga ke batas akhir, dengan interval tertentu, dan mengerjakan block tertentu.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Tambahkan prasyarat ke dalam blok IF.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Terakhir, tambahkan kondisi tangkap-semua kedalam blok IF.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Tambahkan, hapus, atau susun kembali bagian untuk mengkonfigurasi blok IF ini.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "lainnya";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "atau jika";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "jika";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Jika nilainya benar, maka lakukan beberapa perintah.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Jika nilainya benar, maka kerjakan perintah blok pertama. Jika tidak, kerjakan perintah blok kedua.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Jika nilai pertama benar, maka kerjakan perintah blok pertama. Sebaliknya, jika nilai kedua benar, kerjakan perintah blok kedua.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Jika nilai pertama benar, maka kerjakan perintah blok pertama. Sebaliknya, jika nilai kedua benar, kerjakan perintah blok kedua. Jika dua-duanya tidak benar, kerjakan perintah blok terakhir.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "kerjakan";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ulangi %1 kali";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Lakukan beberapa perintah beberapa kali.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ulangi sampai";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ulangi jika";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Selagi nilainya salah, maka lakukan beberapa perintah.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Selagi nilainya benar, maka lakukan beberapa perintah.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Hapus semua %1 blok?";
                +Blockly.Msg["DELETE_BLOCK"] = "Hapus Blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Hapus variabel '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Hapus %1 yang digunakan pada variabel '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Hapus %1 Blok";
                +Blockly.Msg["DISABLE_BLOCK"] = "Nonaktifkan Blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplikat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktifkan Blok";
                +Blockly.Msg["EXPAND_ALL"] = "Kembangkan Blok";
                +Blockly.Msg["EXPAND_BLOCK"] = "Kembangkan Blok";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Input Eksternal";
                +Blockly.Msg["HELP"] = "Bantuan";
                +Blockly.Msg["INLINE_INPUTS"] = "Input Inline";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "buat list kosong";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Kembalikan list, dengan panjang 0, tidak berisi data";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Tambahkan, hapus, atau susun ulang bagian untuk mengkonfigurasi blok list ini.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "buat list dengan";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Tambahkan sebuah item ke list.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Buat sebuah list dengan sejumlah item.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "pertama";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# dari akhir";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "dapatkan";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "dapatkan dan hapus";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "terakhir";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "acak";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "Hapus";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Kembalikan item pertama dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Kembalikan item di posisi tertentu dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Kembalikan item terakhir dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Kembalikan item acak dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Hapus dan kembalikan item pertama dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Hapus dan kembalikan item di posisi tertentu dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Hapus dan kembalikan item terakhir dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Hapus dan kembalikan item acak dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Hapus item pertama dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Hapus item di posisi tertentu dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Hapus item terakhir dalam list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Hapus sebuah item acak dalam list.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ke # dari akhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "ke #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "ke yang paling akhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "dapatkan sub-list dari pertama";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "dapatkan sub-list dari nomor # dari akhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "dapatkan sub-list dari #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Buat salinan bagian tertentu dari list.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 adalah item terakhir.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 adalah item pertama.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "cari kejadian pertama item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "cari kejadian terakhir item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Kembalikan indeks dari item pertama/terakhir kali muncul dalam list. Kembalikan %1 jika item tidak ditemukan.";
                +Blockly.Msg["LISTS_INLIST"] = "dalam list";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 kosong";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Kembalikan benar jika list kosong.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "panjang dari %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Kembalikan panjang list.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "buat list dengan item %1 diulang %2 kali";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Buat sebuah list yang terdiri dari nilai yang diberikan diulang sebanyak jumlah yang ditentukan.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "sebagai";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "sisipkan di";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "tetapkan";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Sisipkan item di bagian awal dari list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Sisipkan item ke dalam posisi yang telah ditentukan di dalam list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Tambahkan item ke bagian akhir list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Sisipkan item secara acak ke dalam list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Tetapkan item pertama di dalam list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Tetapkan item ke dalam posisi yang telah ditentukan di dalam list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Menetapkan item terakhir dalam list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Tetapkan secara acak sebuah item dalam list.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "menaik";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "menurun";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "urutkan %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Urutkan salinan dari daftar";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "sesuai abjad, abaikan kasus";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "sesuai nomor";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "sesuai abjad";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "buat list dari teks";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "buat teks dari list";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Gabung daftar teks menjadi satu teks, yang dipisahkan oleh pembatas.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Membagi teks ke dalam daftar teks, pisahkan pada setiap pembatas.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "dengan pembatas";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "salah";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Kembalikan benar atau salah.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "benar";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Kembalikan benar jika kedua input sama satu dengan lainnya.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Kembalikan benar jika input pertama lebih besar dari input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Kembalikan benar jika input pertama lebih besar dari atau sama dengan input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Kembalikan benar jika input pertama lebih kecil dari input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Kembalikan benar jika input pertama lebih kecil atau sama dengan input kedua .";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Kembalikan benar jika kedua input tidak sama satu dengan lainnya.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "bukan (not) %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Kembalikan benar jika input salah. Kembalikan salah jika input benar.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Kembalikan null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "dan";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "atau";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Kembalikan benar jika kedua input adalah benar.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Kembalikan benar jika minimal satu input nilainya benar.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "jika salah";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "jika benar";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Periksa kondisi di 'test'. Jika kondisi benar, kembalikan nilai 'if true'; jika sebaliknya kembalikan nilai 'if false'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://id.wikipedia.org/wiki/Aritmetika";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Kembalikan jumlah dari kedua angka.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Kembalikan hasil bagi dari kedua angka.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Kembalikan selisih dari kedua angka.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Kembalikan perkalian dari kedua angka.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Kembalikan angka pertama pangkat angka kedua.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "ubah %1 oleh %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Tambahkan angka kedalam variabel '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Kembalikan salah satu konstanta: π (3,141…), e (2,718…), φ (1,618…), akar(2) (1,414…), akar(½) (0.707…), atau ∞ (tak terhingga).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "Batasi %1 rendah %2 tinggi %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Batasi angka antara batas yang ditentukan (inklusif).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "dapat dibagi oleh";
                +Blockly.Msg["MATH_IS_EVEN"] = "adalah bilangan genap";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "adalah bilangan negatif";
                +Blockly.Msg["MATH_IS_ODD"] = "adalah bilangan ganjil";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "adalah bilangan positif";
                +Blockly.Msg["MATH_IS_PRIME"] = "adalah bilangan pokok";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Periksa apakah angka adalah bilangan genap, bilangan ganjil, bilangan pokok, bilangan bulat, bilangan positif, bilangan negatif, atau apakan bisa dibagi oleh angka tertentu. Kembalikan benar atau salah.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "adalah bilangan bulat";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "sisa dari %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Kembalikan sisa dari pembagian ke dua angka.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Suatu angka.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "rata-rata dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maksimum dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimum dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "mode-mode dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "item acak dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviasi standar dari list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "jumlah dari list";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Kembalikan rata-rata (mean aritmetik) dari nilai numerik dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Kembalikan angka terbesar dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Kembalikan median dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Kembalikan angka terkecil dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Kembalikan list berisi item yang paling umum dari dalam list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Kembalikan elemen acak dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Kembalikan standard deviasi dari list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Kembalikan jumlah dari seluruh bilangan dari list.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "nilai pecahan acak";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Kembalikan nilai pecahan acak antara 0.0 (inklusif) dan 1.0 (eksklusif).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "acak bulat dari %1 sampai %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Kembalikan bilangan acak antara dua batas yang ditentukan, inklusif.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "membulatkan";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "membulatkan kebawah";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "membulatkan keatas";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Bulatkan suatu bilangan naik atau turun.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "mutlak";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "akar";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Kembalikan nilai absolut angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Kembalikan 10 pangkat angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Kembalikan logaritma natural dari angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Kembalikan dasar logaritma 10 dari angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Kembalikan penyangkalan terhadap angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Kembalikan 10 pangkat angka.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Kembalikan akar dari angka.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Kembalikan acosine dari angka.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Kembalikan asin dari angka.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Kembalikan atan dari angka.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Kembalikan cosinus dari derajat (bukan radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Kembalikan sinus dari derajat (bukan radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Kembalikan tangen dari derajat (bukan radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "Buat variabel...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nama variabel baru:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "memungkinkan pernyataan";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "dengan:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Menjalankan fungsi '%1' yang ditetapkan pengguna.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Menjalankan fungsi  '%1' yang ditetapkan pengguna dan menggunakan outputnya.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "dengan:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Buat '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Jelaskan fungsi ini...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "buat sesuatu";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "untuk";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Buat sebuah fungsi tanpa output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "kembali";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Buat sebuah fungsi dengan satu output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Peringatan: Fungsi ini memiliki parameter duplikat.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Sorot definisi fungsi";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Jika nilai yang benar, kemudian kembalikan nilai kedua.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Peringatan: Blok ini dapat digunakan hanya dalam definisi fungsi.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "masukan Nama:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Tambahkan masukan ke fungsi.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "input";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Menambah, menghapus, atau menyusun ulang masukan untuk fungsi ini.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Lakukan ulang";
                +Blockly.Msg["REMOVE_COMMENT"] = "Hapus Komentar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Ubah nama variabel...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Ubah nama semua variabel '%1' menjadi:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Tambahkan beberapa teks ke variabel '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "menjadi huruf kecil";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "menjadi huruf pertama kapital";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "menjadi huruf kapital";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Kembalikan kopi dari text dengan kapitalisasi yang berbeda.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "ambil  huruf pertama";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "ambil  huruf nomor # dari belakang";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "ambil huruf ke #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "ambil  huruf terakhir";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "ambil huruf secara acak";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Kembalikan karakter dari posisi tertentu.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Tambahkan suatu item ke dalam teks.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Tambah, ambil, atau susun ulang teks blok.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "pada huruf nomer # dari terakhir";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "pada huruf #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "pada huruf terakhir";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in teks";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "ambil bagian teks (substring) dari huruf pertama";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "ambil bagian teks (substring) dari huruf ke # dari terakhir";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "ambil bagian teks (substring) dari huruf no #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Kembalikan spesifik bagian dari teks.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "temukan kejadian pertama dalam teks";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "temukan kejadian terakhir dalam teks";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Kembalikan indeks pertama dan terakhir dari kejadian pertama/terakhir dari teks pertama dalam teks kedua.  Kembalikan %1 jika teks tidak ditemukan.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 kosong";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Kembalikan benar jika teks yang disediakan kosong.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "buat teks dengan";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Buat teks dengan cara gabungkan sejumlah item.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "panjang dari %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Kembalikan sejumlah huruf (termasuk spasi) dari teks yang disediakan.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "cetak %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Cetak teks yant ditentukan, angka atau ninlai lainnya.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Meminta pengguna untuk memberi sebuah angka.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Meminta pengguna untuk memberi beberapa teks.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Meminta angka dengan pesan";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "meminta teks dengan pesan";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Huruf, kata atau baris teks.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "pangkas ruang dari kedua belah sisi";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "pangkas ruang dari sisi kiri";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "pangkas ruang dari sisi kanan";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Kembali salinan teks dengan spasi dihapus dari satu atau kedua ujungnya.";
                +Blockly.Msg["TODAY"] = "Hari ini";
                +Blockly.Msg["UNDO"] = "Urungkan";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Buat 'set %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Kembalikan nilai variabel ini.";
                +Blockly.Msg["VARIABLES_SET"] = "tetapkan %1 untuk %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Buat 'get %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "tetapkan variabel ini dengan input yang sama.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Sebuah variabel dengan nama '%1' sudah ada.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/is.js b/blockly/webif/static/blockly/msg/js/is.js
                new file mode 100644
                index 000000000..5ccc623a8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/is.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.is');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Skrifa skýringu";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Breyta gildi:";
                +Blockly.Msg["CLEAN_UP"] = "Hreinsa kubba";
                +Blockly.Msg["COLLAPSE_ALL"] = "Loka kubbum";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Loka kubbi";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "litur 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "litur 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "hlutfall";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blöndun";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blandar tveimur litum í gefnu hlutfalli (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Velja lit úr litakorti.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "einhver litur";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Velja einhvern lit af handahófi.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blátt";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grænt";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rauður";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "litur";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Búa til lit úr tilteknu magni af rauðu, grænu og bláu. Allar tölurnar verða að vera á bilinu 0 til 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "fara út úr lykkju";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "fara beint í næstu umferð lykkjunnar";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Fara út úr umlykjandi lykkju.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Sleppa afganginum af lykkjunni og fara beint í næstu umferð hennar.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Aðvörun: Þennan kubb má aðeins nota innan lykkju.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "fyrir hvert %1 í lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Fyrir hvert atriði í lista er breyta '%1' stillt á atriðið og skipanir gerðar.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "telja með %1 frá %2 til %3 um %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Láta breytuna '%1' taka inn gildi frá fyrstu tölu til síðustu tölu, hlaupandi á tiltekna bilinu og gera tilteknu kubbana.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Bæta skilyrði við EF kubbinn.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Bæta við hluta EF kubbs sem grípur öll tilfelli sem uppfylla ekki hin skilyrðin.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Bæta við, fjarlægja eða umraða til að breyta skipan þessa EF kubbs.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "annars";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "annars ef";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ef";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ef gildi er satt skal gera einhverjar skipanir.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ef gildi er satt skal gera skipanir í fyrri kubbnum. Annars skal gera skipanir í seinni kubbnum.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ef fyrra gildið er satt skal gera skipanir í fyrri kubbnum. Annars, ef seinna gildið er satt, þá skal gera skipanir í seinni kubbnum.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ef fyrra gildið er satt skal gera skipanir í fyrri kubbnum. Annars, ef seinna gildið er satt, skal gera skipanir í seinni kubbnum. Ef hvorugt gildið er satt, skal gera skipanir í síðasta kubbnum.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "gera";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "endurtaka %1 sinnum";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Gera eitthvað aftur og aftur.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "endurtaka þar til";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "endurtaka á meðan";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Endurtaka eitthvað á meðan gildi er ósatt.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Endurtaka eitthvað á meðan gildi er satt.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Eyða öllum %1 kubbunum?";
                +Blockly.Msg["DELETE_BLOCK"] = "Eyða kubbi";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Eyða %1 kubbum";
                +Blockly.Msg["DISABLE_BLOCK"] = "Óvirkja kubb";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Afrita";
                +Blockly.Msg["ENABLE_BLOCK"] = "Virkja kubb";
                +Blockly.Msg["EXPAND_ALL"] = "Opna kubba";
                +Blockly.Msg["EXPAND_BLOCK"] = "Opna kubb";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Ytri inntök";
                +Blockly.Msg["HELP"] = "Hjálp";
                +Blockly.Msg["INLINE_INPUTS"] = "Innri inntök";
                +Blockly.Msg["IOS_CANCEL"] = "Hætta við";
                +Blockly.Msg["IOS_ERROR"] = "Villa";
                +Blockly.Msg["IOS_OK"] = "Í lagi";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Bæta við";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Eyða";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Endurnefna";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nafn breytu";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "búa til tóman lista";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Skilar lista með lengdina 0 án gagna";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "listi";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Bæta við, fjarlægja eða umraða hlutum til að breyta skipan þessa listakubbs.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "búa til lista með";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Bæta atriði við listann.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Búa til lista með einhverjum fjölda atriða.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "fyrsta";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# frá enda";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "sækja";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "sækja og fjarlægja";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "síðasta";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "eitthvert";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "fjarlægja";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Skilar fyrsta atriði í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Skilar atriðinu í hinum tiltekna stað í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Skilar síðasta atriði í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Skilar einhverju atriði úr lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Fjarlægir og skilar fyrsta atriðinu í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Fjarlægir og skilar atriðinu á hinum tiltekna stað í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Fjarlægir og skilar síðasta atriðinu í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Fjarlægir og skilar einhverju atriði úr lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Fjarlægir fyrsta atriðið í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Fjarlægir atriðið á hinum tiltekna stað í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Fjarlægir síðasta atriðið í lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Fjarlægir eitthvert atriði úr lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "til # frá enda";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "til #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "til síðasta";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "sækja undirlista frá fyrsta";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "sækja undirlista frá # frá enda";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "sækja undirlista frá #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Býr til afrit af tilteknum hluta lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 er síðasta atriðið.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 er fyrsta atriðið.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "finna fyrsta tilfelli atriðis";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "finna síðasta tilfelli atriðis";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Finnur hvar atriðið kemur fyrir fyrst/síðast í listanum og skilar sæti þess. Skilar %1 ef atriðið finnst ekki.";
                +Blockly.Msg["LISTS_INLIST"] = "í lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 er tómur";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Skilar sönnu ef listinn er tómur.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "lengd %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Skilar lengd lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "búa til lista með atriði %1 endurtekið %2 sinnum";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Býr til lista sem inniheldur tiltekna gildið endurtekið tiltekið oft.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "snúa við %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "sem";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "bæta við";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "setja í";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Bætir atriðinu fremst í listann.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Bætir atriðinu í listann á tilteknum stað.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Bætir atriðinu aftan við listann.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Bætir atriðinu einhversstaðar við listann.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Setur atriðið í fyrsta sæti lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Setur atriðið í tiltekna sætið í listanum.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Setur atriðið í síðasta sæti lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Setur atriðið í eitthvert sæti lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "hækkandi";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "lækkandi";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "raða %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Raða afriti lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "í stafrófsröð án tillits til stafstöðu";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "í númeraröð";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "í stafrófsröð";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "gera lista úr texta";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "gera texta úr lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Sameinar lista af textum í einn texta, með skiltákn á milli.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Skiptir texta í lista af textum, með skil við hvert skiltákn.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "með skiltákni";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ósatt";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Skilar annað hvort sönnu eða ósönnu.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "satt";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Skila sönnu ef inntökin eru jöfn.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Skila sönnu ef fyrra inntakið er stærra en seinna inntakið.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Skila sönnu ef fyrra inntakið er stærra en eða jafnt og seinna inntakið.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Skila sönnu ef fyrra inntakið er minna en seinna inntakið.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Skila sönnu ef fyrra inntakið er minna en eða jafnt og seinna inntakið.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Skila sönnu ef inntökin eru ekki jöfn.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ekki %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Skilar sönnu ef inntakið er ósatt. Skilar ósönnu ef inntakið er satt.";
                +Blockly.Msg["LOGIC_NULL"] = "tómagildi";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Skilar tómagildi.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "og";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "eða";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Skila sönnu ef bæði inntökin eru sönn.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Skila sönnu ef að minnsta kosti eitt inntak er satt.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "prófun";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ef ósatt";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ef satt";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kanna skilyrðið í 'prófun'. Skilar 'ef satt' gildinu ef skilyrðið er satt, en skilar annars 'ef ósatt' gildinu.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Skila summu talnanna tveggja.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Skila deilingu talnanna.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Skila mismun talnanna.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Skila margfeldi talnanna.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Skila fyrri tölunni í veldinu seinni talan.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "breyta %1 um %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Bæta tölu við breytu '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Skila algengum fasta: π (3.141…), e (2.718…), φ (1.618…), kvrót(2) (1.414…), kvrót(½) (0.707…) eða ∞ (óendanleika).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "þröngva %1 lægst %2 hæst %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Þröngva tölu til að vera innan hinna tilgreindu marka (að báðum meðtöldum).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "er\u00A0deilanleg með";
                +Blockly.Msg["MATH_IS_EVEN"] = "er\u00A0jöfn tala";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "er neikvæð";
                +Blockly.Msg["MATH_IS_ODD"] = "er oddatala";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "er jákvæð";
                +Blockly.Msg["MATH_IS_PRIME"] = "er prímtala";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kanna hvort tala sé jöfn tala, oddatala, jákvæð, neikvæð eða deilanleg með tiltekinni tölu. Skilar sönnu eða ósönnu.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "er heiltala";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "afgangur af %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Skila afgangi deilingar með tölunum.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Tala.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "meðaltal lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "stærst í lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "miðgildi lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minnst í lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "tíðast í lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "eitthvað úr lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "staðalfrávik lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summa lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Skila meðaltali talna í listanum.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Skila stærstu tölu í listanum.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Skila miðgildi listans.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Skila minnstu tölu í listanum.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Skila lista yfir tíðustu gildin í listanum.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Skila einhverju atriði úr listanum.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Skila staðalfráviki lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Skila summu allra talna í listanum.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "slembibrot";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Skila broti sem er valið af handahófi úr tölum á bilinu frá og með 0.0 til (en ekki með) 1.0.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "slembitala frá %1 til %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Skila heiltölu sem valin er af handahófi og er innan tilgreindra marka, að báðum meðtöldum.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "námunda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "námunda niður";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "námunda upp";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Námunda tölu upp eða niður.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "algildi";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvaðratrót";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Skila algildi tölu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Skila e í veldi tölu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Skila náttúrlegum lógaritma tölu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Skila tugalógaritma tölu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Skila neitun tölu (tölunni með öfugu formerki).";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Skila 10 í veldi tölu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Skila kvaðratrót tölu.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Skila arkarkósínusi tölu.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Skila arkarsínusi tölu.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Skila arkartangensi tölu.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Skila kósínusi horns gefnu í gráðum.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Skila sínusi horns gefnu í gráðum.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Skila tangensi horns gefnu í gráðum.";
                +Blockly.Msg["NEW_VARIABLE"] = "Ný breyta...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Heiti nýrrar breytu:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "leyfa setningar";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "með:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Keyra heimatilbúna fallið '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Keyra heimatilbúna fallið '%1' og nota úttak þess.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "með:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Búa til '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Lýstu þessari aðgerð/falli...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "gera eitthvað";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "til að";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Býr til fall sem skilar engu.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "skila";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Býr til fall sem skilar úttaki.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Aðvörun: Þetta fall er með tvítekna stika.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Sýna skilgreiningu falls";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ef gildi er satt, skal skila öðru gildi.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Aðvörun: Þennan kubb má aðeins nota í skilgreiningu falls.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "heiti inntaks:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Bæta inntaki við fallið.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inntök";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Bæta við, fjarlægja eða umraða inntökum fyrir þetta fall.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Endurtaka";
                +Blockly.Msg["REMOVE_COMMENT"] = "Fjarlægja skýringu";
                +Blockly.Msg["RENAME_VARIABLE"] = "Endurnefna breytu...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Endurnefna allar '%1' breyturnar:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Bæta texta við breytuna '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "í lágstafi";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "í Upphafstafi";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "í HÁSTAFI";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Skila afriti af textanum með annarri stafastöðu.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "sækja fyrsta staf";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "sækja staf # frá enda";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "sækja staf #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "sækja síðasta staf";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "sækja einhvern staf";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Skila staf á tilteknum stað.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Bæta atriði við textann.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "tengja";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Bæta við, fjarlægja eða umraða hlutum til að breyta skipan þessa textakubbs.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "að staf # frá enda";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "að staf #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "að síðasta staf";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "í texta";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "sækja textabút frá fyrsta staf";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "sækja textabút frá staf # frá enda";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "sækja textabút frá staf #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Skilar tilteknum hluta textans.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "finna fyrsta tilfelli texta";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "finna síðasta tilfelli texta";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Finnur fyrsta/síðasta tilfelli fyrri textans í seinni textanum og skilar sæti hans. Skilar %1 ef textinn finnst ekki.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 er tómur";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Skilar sönnu ef gefni textinn er tómur.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "búa til texta með";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Búa til texta með því að tengja saman einhvern fjölda atriða.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "lengd %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Skilar fjölda stafa (með bilum) í gefna textanum.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "prenta %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Prenta tiltekinn texta, tölu eða annað gildi.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Biðja notandann um tölu.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Biðja notandann um texta.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "biðja um tölu með skilaboðum";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "biðja um texta með skilaboðum";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "skipta %1 út með %2 í %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "snúa við %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Stafur, orð eða textalína.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "eyða bilum báðum megin við";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "eyða bilum vinstra megin við";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "eyða bilum hægra megin við";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Skila afriti af textanum þar sem möguleg bil við báða enda hafa verið fjarlægð.";
                +Blockly.Msg["TODAY"] = "Í dag";
                +Blockly.Msg["UNDO"] = "Afturkalla";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "atriði";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Búa til 'stilla %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Skilar gildi þessarar breytu.";
                +Blockly.Msg["VARIABLES_SET"] = "stilla %1 á %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Búa til 'sækja %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Stillir þessa breytu á innihald inntaksins.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/it.js b/blockly/webif/static/blockly/msg/js/it.js
                new file mode 100644
                index 000000000..e2eeda4dd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/it.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.it');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Aggiungi commento";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Non si può cancellare la variabile '%1' perché è parte della definizione della funzione '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Modifica valore:";
                +Blockly.Msg["CLEAN_UP"] = "Pulisci i blocchi";
                +Blockly.Msg["COLLAPSE_ALL"] = "Comprimi blocchi";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Comprimi blocco";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "colore 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "colore 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "rapporto";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "miscela";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Mescola due colori insieme con un determinato rapporto (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://it.wikipedia.org/wiki/Colore";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Scegli un colore dalla tavolozza.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "colore casuale";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Scegli un colore a caso.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blu";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rosso";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colora con";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Crea un colore con la quantità specificata di rosso, verde e blu. Tutti i valori devono essere compresi tra 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "esce dal ciclo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "prosegui con la successiva iterazione del ciclo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Esce dal ciclo.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Salta il resto di questo ciclo e prosegue con la successiva iterazione.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Attenzioneː Questo blocco può essere usato solo in un ciclo.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "per ogni elemento %1 nella lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Per ogni elemento in una lista, imposta la variabile '%1'  pari all'elemento e quindi esegue alcune istruzioni.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "conta con %1 da %2 a %3 per %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Fa sì che la variabile '%1' prenda tutti i valori a partire dal numero di partenza fino a quello di arrivo, con passo pari all'intervallo specificato, ed esegue il blocco indicato.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Aggiungi una condizione al blocco se.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Aggiungi una condizione finale pigliatutto al blocco se.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Aggiungi, elimina o riordina le sezioni per riconfigurare questo blocco se.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "altrimenti";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "altrimenti se";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Se un valore è vero allora esegue alcune istruzioni.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Se un valore è vero allora esegue il primo blocco di istruzioni. Altrimenti esegue il secondo blocco di istruzioni.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Se il primo valore è vero allora esegue un primo blocco di istruzioni. Altrimenti, se il secondo valore è vero, esegue un secondo blocco di istruzioni.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Se il primo valore è vero allora esegue un primo blocco di istruzioni. Altrimenti, se il secondo valore è vero, esegue un secondo blocco di istruzioni. Se nessuno dei valori è vero esegue l'ultimo blocco di istruzioni.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://it.wikipedia.org/wiki/Ciclo_for";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fai";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ripeti %1 volte";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Esegue alcune istruzione diverse volte.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ripeti fino a che";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ripeti mentre";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Finché un valore è falso, esegue alcune istruzioni.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Finché un valore è vero, esegue alcune istruzioni.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Cancellare tutti i %1 blocchi?";
                +Blockly.Msg["DELETE_BLOCK"] = "Cancella blocco";
                +Blockly.Msg["DELETE_VARIABLE"] = "Cancella la variabile '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Cancella %1 usi della variabile '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Cancella %1 blocchi";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disattiva blocco";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplica";
                +Blockly.Msg["ENABLE_BLOCK"] = "Attiva blocco";
                +Blockly.Msg["EXPAND_ALL"] = "Espandi blocchi";
                +Blockly.Msg["EXPAND_BLOCK"] = "Espandi blocco";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Ingressi esterni";
                +Blockly.Msg["HELP"] = "Aiuto";
                +Blockly.Msg["INLINE_INPUTS"] = "Ingressi in linea";
                +Blockly.Msg["IOS_CANCEL"] = "Annulla";
                +Blockly.Msg["IOS_ERROR"] = "Errore";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Aggiungi input";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Consenti dichiarazioni";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Questa funzione ha entrate duplicate.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Aggiungi";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Aggiungi variabile";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Cancella";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Non puoi utilizzare un nome di variabile vuoto.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rinomina";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nome variabile";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "crea lista vuota";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Restituisce una lista, di lunghezza 0, contenente nessun record di dati";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Aggiungi, rimuovi o riordina le sezioni per riconfigurare il blocco lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "crea lista con";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Aggiunge un elemento alla lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Crea una lista con un certo numero di elementi.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primo";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# dalla fine";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "prendi";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "prendi e rimuovi";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ultimo";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "casuale";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "rimuovi";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Restituisce il primo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Restituisce l'elemento nella posizione indicata della lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Restituisce l'ultimo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Restituisce un elemento casuale in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Rimuove e restituisce il primo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Rimuove e restituisce l'elemento nella posizione indicata in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Restituisce e rimuove l'ultimo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Restituisce e rimuove un elemento casuale in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Rimuove il primo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Rimuove l'elemento nella posizione indicata in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Rimuove l'ultimo elemento in una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Rimuove un elemento casuale in una lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "da # dalla fine";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "fino a #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "dagli ultimi";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "prendi sotto-lista dall'inizio";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "prendi sotto-lista da # dalla fine";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "prendi sotto-lista da #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Crea una copia della porzione specificata di una lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 corrisponde all'ultimo elemento.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 corrisponde al primo elemento.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "trova la prima occorrenza dell'elemento";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "trova l'ultima occorrenza dell'elemento";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Restituisce l'indice della prima/ultima occorrenza dell'elemento nella lista. Restituisce %1 se l'elemento non viene trovato.";
                +Blockly.Msg["LISTS_INLIST"] = "nella lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 è vuota";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Restituisce vero se la lista è vuota.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "lunghezza di %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Restituisce la lunghezza della lista";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "crea una lista con l'elemento %1 ripetuto %2 volte";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Crea una lista costituita dal valore indicato ripetuto per il numero di volte specificato.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "inverti %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Inverti una copia di un elenco.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "come";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserisci in";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "imposta";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserisci l'elemento all'inizio della lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserisci un elemento nella posizione indicata in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Aggiungi un elemento alla fine di una lista";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserisce l'elemento casualmente in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Imposta il primo elemento in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Imposta l'elemento nella posizione indicata di una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Imposta l'ultimo elemento in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Imposta un elemento casuale in una lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "crescente";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "decrescente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "ordinamento %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordina una copia di un elenco.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetico, ignorare differenze maiuscole e minuscole";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerico";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetico";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "crea lista da testo";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "crea testo da lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Unisci una lista di testi in un unico testo, separato da un delimitatore.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dividi il testo in un elenco di testi, interrompendo ad ogni delimitatore.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "con delimitatore";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falso";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Restituisce vero o falso.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "vero";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://it.wikipedia.org/wiki/Disuguaglianza";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Restituisce vero se gli input sono uno uguale all'altro.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Restituisce vero se il primo input è maggiore o uguale al secondo.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Restituisce uguale se il primo input è maggiore o uguale al secondo input.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Restituisce vero se il primo input è minore del secondo.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Restituisce vero se il primo input è minore o uguale al secondo.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Restituisce vero se gli input non sono uno uguale all'altro.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "non %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Restituisce vero se l'input è falso. Restituisce falso se l'input è vero.";
                +Blockly.Msg["LOGIC_NULL"] = "nullo";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Restituisce valore nullo.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Restituisce vero se entrambi gli input sono veri.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Restituisce vero se almeno uno degli input è vero.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se falso";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se vero";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Verifica la condizione in 'test'. Se questa è vera restituisce il valore 'se vero' altrimenti restituisce il valore 'se falso'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://it.wikipedia.org/wiki/Aritmetica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Restituisce la somma dei due numeri.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Restituisce il quoziente dei due numeri.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Restituisce la differenza dei due numeri.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Restituisce il prodotto dei due numeri.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Restituisce il primo numero elevato alla potenza del secondo numero.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://it.wikipedia.org/wiki/Addizione";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "cambia %1 di %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Aggiunge un numero alla variabile '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://it.wikipedia.org/wiki/Costante_matematica";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Restituisce una delle costanti comuniː π (3.141…), e (2.718…), φ (1.618…), radq(2) (1.414…), radq(½) (0.707…) o ∞ (infinito).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "costringi %1 da %2 a %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Costringe un numero all'interno dei limiti indicati (compresi).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "è divisibile per";
                +Blockly.Msg["MATH_IS_EVEN"] = "è pari";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "è negativo";
                +Blockly.Msg["MATH_IS_ODD"] = "è dispari";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "è positivo";
                +Blockly.Msg["MATH_IS_PRIME"] = "è primo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Verifica se un numero è pari, dispari, primo, intero, positivo, negativo o se è divisibile per un certo numero. Restituisce vero o falso.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "è intero";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://it.wikipedia.org/wiki/Resto";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto di %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Restituisce il resto della divisione di due numeri.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://it.wikipedia.org/wiki/Numero";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un numero.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "media della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "massimo della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimo della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "mode della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "elemento casuale della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviazione standard della lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "somma la lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Restituisce la media (media aritmetica) dei valori numerici nella lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Restituisce il più grande numero della lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Restituisce il valore mediano della lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Restituisce il più piccolo numero della lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Restituisce una lista degli elementi più frequenti nella lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Restituisce un elemento casuale della lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Restituisce la deviazione standard della lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Restituisce la somma si tutti i numeri nella lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://it.wikipedia.org/wiki/Numeri_pseudo-casuali";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "frazione casuale";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Restituisce una frazione compresa fra 0.0 (incluso) e 1.0 (escluso).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://it.wikipedia.org/wiki/Numeri_pseudo-casuali";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "intero casuale da %1 a %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Restituisce un numero intero casuale compreso tra i due limiti indicati (inclusi).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://it.wikipedia.org/wiki/Arrotondamento";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arrotonda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arrotonda verso il basso";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arrotonda verso l'alto";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arrotonda un numero verso l'alto o verso il basso.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://it.wikipedia.org/wiki/Radice_quadrata";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "assoluto";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "radice quadrata";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Restituisce il valore assoluto del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Restituisce e elevato alla potenza del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Restituisce il logaritmo naturale del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Restituisce il logaritmo in base 10 del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Restituisce l'opposto del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Restituisce 10 elevato alla potenza del numero.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Restituisce la radice quadrata del numero.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://it.wikipedia.org/wiki/Funzione_trigonometrica";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Restituisce l'arco-coseno di un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Restituisce l'arco-seno di un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Restituisce l'arco-tangente di un numero.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Restituisce il coseno di un angolo espresso in gradi (non radianti).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Restituisce il seno di un angolo espresso in gradi (non radianti).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Restituisce la tangente di un angolo espresso in gradi (non radianti).";
                +Blockly.Msg["NEW_VARIABLE"] = "Crea variabile...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nome della nuova variabile:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "consenti dichiarazioni";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "conː";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://it.wikipedia.org/wiki/Funzione (informatica)";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Esegue la funzione definita dall'utente '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://it.wikipedia.org/wiki/Funzione (informatica)";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Esegue la funzione definita dall'utente '%1' ed usa il suo output.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "conː";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Crea '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Descrivi questa funzione...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "fai qualcosa";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "per";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crea una funzione senza output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "ritorna";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Crea una funzione con un output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Attenzioneː Questa funzione ha parametri duplicati.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Evidenzia definizione di funzione";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Se un valore è vero allora restituisce un secondo valore.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Attenzioneː Questo blocco può essere usato solo all'interno di una definizione di funzione.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nome inputː";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Aggiungi un input alla funzione.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "input";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Aggiungi, rimuovi o riordina input alla funzione.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Una procedura denominata '%1' esiste già.";
                +Blockly.Msg["REDO"] = "Ripeti";
                +Blockly.Msg["REMOVE_COMMENT"] = "Rimuovi commento";
                +Blockly.Msg["RENAME_VARIABLE"] = "Rinomina variabile...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rinomina tutte le variabili '%1' in:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "a %1 aggiungi il testo %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Aggiunge del testo alla variabile '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "in minuscolo";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "con Iniziali Maiuscole";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "in MAIUSCOLO";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Restituisce una copia del testo in un diverso formato maiuscole/minuscole.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "prendi la prima lettera";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "prendi la lettera # dalla fine";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "prendi la lettera #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "prendi l'ultima lettera";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "prendi lettera casuale";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "nel testo %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Restituisce la lettera nella posizione indicata.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "conta %1 in %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Contare quante volte una parte di testo si ripete all'interno di qualche altro testo.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Aggiungi un elemento al testo.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unisci";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Aggiungi, rimuovi o riordina le sezioni per riconfigurare questo blocco testo.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "alla lettera # dalla fine";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "alla lettera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "all'ultima lettera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "nel testo";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "prendi sotto-stringa dalla prima lettera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "prendi sotto-stringa dalla lettera # dalla fine";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "prendi sotto-stringa dalla lettera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Restituisce la porzione di testo indicata.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "trova la prima occorrenza del testo";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "trova l'ultima occorrenza del testo";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "nel testo %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Restituisce l'indice della prima occorrenza del primo testo all'interno del secondo testo. Restituisce %1 se il testo non viene trovato.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 è vuoto";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Restituisce vero se il testo fornito è vuoto.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "crea testo con";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Crea un blocco di testo unendo un certo numero di elementi.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "lunghezza di %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Restituisce il numero di lettere (inclusi gli spazi) nel testo fornito.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "scrivi %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Scrive il testo, numero o altro valore indicato.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Richiedi un numero all'utente.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Richiede del testo da parte dell'utente.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "richiedi numero con messaggio";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "richiedi testo con messaggio";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "sostituisci %1 con %2 in %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "sostituisci tutte le occorrenze di un certo testo con qualche altro testo.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "inverti %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Inverte l'ordine dei caratteri nel testo.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://it.wikipedia.org/wiki/Stringa_(informatica)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Una lettera, una parola o una linea di testo.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "rimuovi spazi da entrambi gli estremi";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "rimuovi spazi a sinistra";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "rimuovi spazi a destra";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Restituisce una copia del testo con gli spazi rimossi ad uno o entrambe le estremità.";
                +Blockly.Msg["TODAY"] = "Oggi";
                +Blockly.Msg["UNDO"] = "Annulla";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "elemento";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crea 'imposta %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Restituisce il valore di una variabile.";
                +Blockly.Msg["VARIABLES_SET"] = "imposta %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Crea 'prendi %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Imposta questa variabile ad essere pari all'input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Una variabile denominata '%1' esiste già.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ja.js b/blockly/webif/static/blockly/msg/js/ja.js
                new file mode 100644
                index 000000000..1d40d57fd
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ja.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ja');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "コメントを追加";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "値を変える:";
                +Blockly.Msg["CLEAN_UP"] = "ブロックを整理する";
                +Blockly.Msg["COLLAPSE_ALL"] = "ブロックを折りたたむ";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ブロックを折りたたむ";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "色 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "色 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "比率";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "ブレンド";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "2色を与えられた比率(0.0~1.0)で混ぜます。";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ja.wikipedia.org/wiki/色";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "パレットから色を選んでください。";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "ランダムな色";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "ランダムな色を選ぶ。";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "青";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "緑";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "赤";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "色づけ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "赤、緑、および青の指定された量で色を作成します。すべての値は 0 ~ 100 の間でなければなりません。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ループから抜け出します";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ループの次の反復処理を続行します";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "入っているループから抜け出します。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "このループの残りの部分をスキップして、ループの繰り返しを続けます。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "注意: このブロックは、ループ内でのみ使用できます。";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "リスト%2の各項目%1について";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "リストの各項目について、その項目を変数'%1'として、いくつかのステートメントを実行します。";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "カウントする( 変数: %1 範囲: %2 ~ %3 間隔: %4 )";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "変数 '%1' が開始番号から終了番号まで指定した間隔での値をとって、指定したブロックを実行する。";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "「もしも」のブロックに条件を追加します。";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Ifブロックに、すべてをキャッチする条件を追加。";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "追加、削除、またはセクションを順序変更して、ブロックをこれを再構成します。";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "他";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "他でもしも";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "もしも";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "値が true の場合、ステートメントを実行します。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "値が true 場合は、ステートメントの最初のブロックを行います。それ以外の場合は、ステートメントの 2 番目のブロックを行います。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "最初の値が true 場合は、ステートメントの最初のブロックを行います。それ以外の場合は、2 番目の値が true の場合、ステートメントの 2 番目のブロックをします。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "最初の値が true 場合は、ステートメントの最初のブロックを行います。2 番目の値が true の場合は、ステートメントの 2 番目のブロックを行います。それ以外の場合は最後のブロックのステートメントを行います。";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://ja.wikipedia.org/wiki/for文";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "実行";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 回繰り返します";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "いくつかのステートメントを数回実行します。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "繰り返す:終わる条件";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "繰り返す:続ける条件";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "値がfalseの間、いくつかのステートメントを実行する。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "値がtrueの間、いくつかのステートメントを実行する。";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "%1件のすべてのブロックを削除しますか?";
                +Blockly.Msg["DELETE_BLOCK"] = "ブロックを削除";
                +Blockly.Msg["DELETE_VARIABLE"] = "変数 '%1' を削除";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "%1か所で使われている変数 '%2' を削除しますか?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 個のブロックを削除";
                +Blockly.Msg["DISABLE_BLOCK"] = "ブロックを無効にする";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "複製";
                +Blockly.Msg["ENABLE_BLOCK"] = "ブロックを有効にする";
                +Blockly.Msg["EXPAND_ALL"] = "ブロックを展開する";
                +Blockly.Msg["EXPAND_BLOCK"] = "ブロックを展開する";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "外部入力";
                +Blockly.Msg["HELP"] = "ヘルプ";
                +Blockly.Msg["INLINE_INPUTS"] = "インライン入力";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "空のリストを作成";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "長さ0でデータ・レコードを含まない空のリストを返す";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "リスト";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "追加、削除、またはセクションの順序変更をして、このリスト・ブロックを再構成する。";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "以下を使ってリストを作成:";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "リストに項目を追加。";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "項目数が不定のリストを作成。";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "最初";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "後ろから #";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "取得";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "取得と削除";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "最後";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "ランダム";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "削除";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "リストの最初の項目を返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "リスト内の指定位置にある項目を返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "リストの最後の項目を返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "ランダム アイテム リストを返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "リスト内の最初の項目を削除し返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "リスト内の指定位置にある項目を削除し、返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "リスト内の最後の項目を削除したあと返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "リストのランダムなアイテムを削除し返します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "リスト内の最初の項目を削除します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "リスト内の指定された項目を削除します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "リスト内の最後の項目を削除します。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "リスト内にあるアイテムをランダムに削除します。";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "最後から#へ";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "#へ";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "最後へ";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "最初からサブリストを取得する。";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "端から #のサブリストを取得します。";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "# からサブディレクトリのリストを取得します。";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "リストの指定された部分のコピーを作成してくださ。";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 は、最後の項目です。";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 は、最初の項目です。";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "最初に見つかった項目を検索します。";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "最後に見つかったアイテムを見つける";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "リスト項目の最初/最後に出現するインデックス位置を返します。項目が見つからない場合は %1 を返します。";
                +Blockly.Msg["LISTS_INLIST"] = "リストで";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1が空";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "リストが空の場合は、true を返します。";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1の長さ";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "リストの長さを返します。";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "項目%1を%2回繰り返したリストを作成";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "与えられた値を指定された回数繰り返してリストを作成。";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "%1を逆順に";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "リストのコピーを逆順にする。";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "として";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "挿入位置:";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "セット";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "リストの先頭に項目を挿入します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "リスト内の指定位置に項目を挿入します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "リストの末尾に項目を追加します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "リストに項目をランダムに挿入します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "リスト内に最初の項目を設定します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "リスト内の指定された位置に項目を設定します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "リスト内の最後の項目を設定します。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "リスト内にランダムなアイテムを設定します。";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "昇順";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "降順";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "並べ替え(タイプ:%1、順番:%2、項目のリスト:%3)";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "リストのコピーを並べ替え";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "アルファベット順(大文字・小文字の区別無し)";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "数値順";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "アルファベット順";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "テキストからリストを作る";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "リストからテキストを作る";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "テキストのリストを区切り記号で区切られた一つのテキストにする";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "テキストを区切り記号で分割したリストにする";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "区切り記号";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "True または false を返します。";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "true";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://ja.wikipedia.org/wiki/不等式";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "もし両方がお互いに等しく入力した場合は true を返します。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "最初の入力が 2 番目の入力よりも大きい場合は true を返します。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "もし入力がふたつめの入よりも大きかったらtrueをり返します。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "最初の入力が 2 番目の入力よりも小さいい場合は true を返します。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "もし、最初の入力が二つ目入力より少ないか、おなじであったらTRUEをかえしてください";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "両方の入力が互いに等しくない場合に true を返します。";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://ja.wikipedia.org/wiki/否定";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1ではない";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "入力が false の場合は、true を返します。入力が true の場合は false を返します。";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "null を返します。";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "かつ";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "または";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "両方の入力が true のときに true を返します。";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "少なくとも 1 つの入力が true のときに true を返します。";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "テスト";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://ja.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "false の場合";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "true の場合";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'テスト' の条件をチェックします。条件が true の場合、'true' の値を返します。それ以外の場合 'false' のを返します。";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ja.wikipedia.org/wiki/算術";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "2 つの数の合計を返します。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "2 つの数の商を返します。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "2 つの数の差を返します。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "2 つの数の積を返します。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "最初の数を2 番目の値で累乗した結果を返します。";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://ja.wikipedia.org/wiki/加法";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "変更 %1 に %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "変数'%1'に数をたす。";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ja.wikipedia.org/wiki/数学定数";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "いずれかの共通の定数のを返す: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (無限).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1の下限を%2に上限を%3に制限";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "指定した上限と下限の間に値を制限する(上限と下限の値を含む)。";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "は以下で割りきれる:";
                +Blockly.Msg["MATH_IS_EVEN"] = "は偶数";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "は負";
                +Blockly.Msg["MATH_IS_ODD"] = "は奇数";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "は正";
                +Blockly.Msg["MATH_IS_PRIME"] = "は素数";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "数字が、偶数、奇数、素数、整数、正数、負数、または特定の数で割り切れるかどうかを判定し、true か false を返します。";
                +Blockly.Msg["MATH_IS_WHOLE"] = "は整数";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1÷%2の余り";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "2つの数値の割り算の余りを返す。";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ja.wikipedia.org/wiki/数";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "数です。";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "リストの平均";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "リストの最大値";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "リストの中央値";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "リストの最小値";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "一覧モード";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "リストからランダムに選ばれた項目";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "リストの標準偏差";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "リストの合計";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "リストの数値の平均 (算術平均) を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "リストの最大値を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "リストの中央値を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "リストの最小値を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "リスト中の最頻項目のリストを返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "リストからランダムに選ばれた要素を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "リストの標準偏差を返す。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "リストの数値を足して返す。";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "1未満の正の乱数";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "0.0以上で1.0未満の範囲の乱数を返します。";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "%1から%2までのランダムな整数";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "指定された(上下限を含む)範囲のランダムな整数を返します。";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ja.wikipedia.org/wiki/端数処理";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "四捨五入";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "切り捨て";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "切り上げ";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "数値を切り上げるか切り捨てる";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ja.wikipedia.org/wiki/平方根";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "絶対値";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "平方根";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "絶対値を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "ネイピア数eの数値乗を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "数値の自然対数を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "底が10の対数を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "負の数を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "10の数値乗を返す。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "平方根を返す。";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ja.wikipedia.org/wiki/三角関数";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "アークコサイン(arccosin)を返す。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "アークサイン(arcsin)を返す。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "アークタンジェント(arctan)を返す。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "(ラジアンではなく)度数の余弦(cosin)を返す。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "(ラジアンではなく)度数の正弦(sin)を返す。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "(ラジアンではなく)度数の正接(tan)を返す。";
                +Blockly.Msg["NEW_VARIABLE"] = "変数の作成…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "新しい変数の名前:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "ステートメントを許可";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "対象:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ja.wikipedia.org/wiki/サブルーチン";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "ユーザー定義関数 '%1' を実行します。";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ja.wikipedia.org/wiki/サブルーチン";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "ユーザー定義関数 '%1' を実行し、その出力を使用します。";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "対象:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' を作成";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "この関数の説明…";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://ja.wikipedia.org/wiki/サブルーチン";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "何かしてください";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "宛先";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "出力なしの関数を作成します。";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://ja.wikipedia.org/wiki/サブルーチン";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "返す";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "一つの出力を持つ関数を作成します。";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "警告: この関数には重複するパラメーターがあります。";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "関数の内容を強調表示します。";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "1番目の値が true の場合、2番目の値を返します。";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "警告: このブロックは、関数定義内でのみ使用できます。";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "入力名:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "関数への入力の追加。";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "入力";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "この関数への入力の追加、削除、順番変更。";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "やり直す";
                +Blockly.Msg["REMOVE_COMMENT"] = "コメントを削除";
                +Blockly.Msg["RENAME_VARIABLE"] = "変数の名前を変える…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "選択した%1の変数すべての名前を変える:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "変数 '%1' にテキストを追加。";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "小文字に";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "タイトル ケースに";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "大文字に変換する";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "別のケースに、テキストのコピーを返します。";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "最初の文字を得る";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "一番最後の言葉、キャラクターを所得";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "で、文字# を取得";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "最後の文字を得る";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "ランダムな文字を得る";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "指定された位置に文字を返します。";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "%2に含まれる%1の数を数える";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "とある文が別の文のなかに使われた回数を数える。";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "テキストへ項目を追加。";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "結合";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "セクションを追加、削除、または順序変更して、ブロックを再構成。";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "文字列の# 終わりからの#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "# の文字";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "最後のの文字";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "テキストで";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "部分文字列を取得する。";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "部分文字列を取得する #端から得る";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "文字列からの部分文字列を取得 #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "テキストの指定部分を返します。";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "で以下のテキストの最初の出現箇所を検索:";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "テキストの最後の出現箇所を検索";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "二番目のテキストの中で一番目のテキストが最初/最後に出現したインデックスを返す。テキストが見つからない場合は%1を返す。";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1が空";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "与えられたテキストが空の場合は true を返す。";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "テキストの作成:";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "任意の数の項目一部を一緒に接合してテキストを作成。";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1の長さ";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "与えられたテキストの(スペースを含む)文字数を返す。";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 を印刷します。";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "指定したテキスト、番号または他の値を印刷します。";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "ユーザーに数値のインプットを求める。";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "ユーザーにテキスト入力を求める。";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "メッセージで番号の入力を求める";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "メッセージでテキスト入力を求める";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "%3に含まれる%1を%2に置換";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "文に含まれるキーワードを置換する。";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "%1を逆順に";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "文の文字を逆順にする。";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ja.wikipedia.org/wiki/文字列";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "文字、単語、または行のテキスト。";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "両端のスペースを取り除く";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "左端のスペースを取り除く";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "右端のスペースを取り除く";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "スペースを 1 つまたは両方の端から削除したのち、テキストのコピーを返します。";
                +Blockly.Msg["TODAY"] = "今日";
                +Blockly.Msg["UNDO"] = "取り消す";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "項目";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'セット%1を作成します。";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "この変数の値を返します。";
                +Blockly.Msg["VARIABLES_SET"] = "セット %1 宛先 %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'%1 を取得' を作成します。";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "この入力を変数と等しくなるように設定します。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "変数名 '%1' は既に存在しています。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ko.js b/blockly/webif/static/blockly/msg/js/ko.js
                new file mode 100644
                index 000000000..6435f0440
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ko.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ko');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "댓글 추가";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "'%2' 함수 정의의 일부이기 때문에 '%1' 변수를 삭제할 수 없습니다";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "값 바꾸기:";
                +Blockly.Msg["CLEAN_UP"] = "블록 정리";
                +Blockly.Msg["COLLAPSE_ALL"] = "블록 축소";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "블록 축소";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "색 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "색 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "비율";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "혼합";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "두 색을 주어진 비율로 혼합 (0.0 - 1.0)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ko.wikipedia.org/wiki/색";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "팔레트에서 색을 고릅니다";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "임의 색상";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "무작위로 색을 고릅니다.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "파랑";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "초록";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "빨강";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "색";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "빨강,파랑,초록의 값을 이용하여 색을 만드십시오. 모든 값은 0과 100 사이에 있어야 합니다.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://ko.wikipedia.org/wiki/%EC%A0%9C%EC%96%B4_%ED%9D%90%EB%A6%84";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "반복 중단";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "다음 반복";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "현재 반복 실행 블럭을 빠져나갑니다.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "나머지 반복 부분을 더 이상 실행하지 않고, 다음 반복을 수행합니다.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "경고 : 이 블록은 반복 실행 블럭 안에서만 사용됩니다.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://ko.wikipedia.org/wiki/For_%EB%A3%A8%ED%94%84#.EC.9E.84.EC.9D.98.EC.9D.98_.EC.A7.91.ED.95.A9";
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "각 항목에 대해 %1 목록으로 %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "리스트 안에 들어있는 각 아이템들을, 순서대로 변수 '%1' 에 한 번씩 저장시키고, 그 때 마다 명령을 실행합니다.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://ko.wikipedia.org/wiki/For_%EB%A3%A8%ED%94%84";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "으로 계산 %1 %2에서 %4을 이용하여 %3로";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "변수 \"%1\"은 지정된 간격으로 시작 수에서 끝 수까지를 세어 지정된 블록을 수행해야 합니다.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "\"만약\" 블럭에 조건 검사를 추가합니다.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "\"만약\" 블럭의 마지막에, 모든 검사 결과가 거짓인 경우 실행할 부분을 추가합니다.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://ko.wikipedia.org/wiki/%EC%A1%B0%EA%B1%B4%EB%AC%B8";
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "섹션을 추가, 제거하거나 순서를 변경하여 이 if 블럭을 재구성합니다.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "아니라면";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "다른 경우";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "만약";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "조건식의 계산 결과가 참이면, 명령을 실행합니다.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 그렇지 않으면 두 번째 블럭의 명령을 실행합니다.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "첫 번째 조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 두 번째 조건식의 계산 결과가 참이면, 두 번째 블럭의 명령을 실행합니다.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "첫 번째 조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 두 번째 조건식의 계산 결과가 참이면, 두 번째 블럭의 명령을 실행하고, ... , 어떤 조건식의 계산 결과도 참이 아니면, 마지막 블럭의 명령을 실행합니다.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://ko.wikipedia.org/wiki/For_루프";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "하기";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1회 반복";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "여러 번 반복해 명령들을 실행합니다.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://ko.wikipedia.org/wiki/While_%EB%A3%A8%ED%94%84";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "다음까지 반복";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "동안 반복";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "값이 거짓일 때, 몇 가지 선언을 합니다.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "값이 참일 때, 몇 가지 선언을 합니다.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "모든 블록 %1개를 삭제하겠습니까?";
                +Blockly.Msg["DELETE_BLOCK"] = "블록 삭제";
                +Blockly.Msg["DELETE_VARIABLE"] = "'%1' 변수를 삭제합니다";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "'%2' 변수에서 %1을(를) 삭제하시겠습니까?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "블록 %1개 삭제";
                +Blockly.Msg["DISABLE_BLOCK"] = "블록 비활성화";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "중복됨";
                +Blockly.Msg["ENABLE_BLOCK"] = "블록 활성화";
                +Blockly.Msg["EXPAND_ALL"] = "블록 확장";
                +Blockly.Msg["EXPAND_BLOCK"] = "블록 확장";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "외부 입력";
                +Blockly.Msg["HELP"] = "도움말";
                +Blockly.Msg["INLINE_INPUTS"] = "내부 입력";
                +Blockly.Msg["IOS_CANCEL"] = "취소";
                +Blockly.Msg["IOS_ERROR"] = "오류";
                +Blockly.Msg["IOS_OK"] = "확인";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ 입력 추가";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "이 기능은 중복된 입력이 있습니다.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "추가";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ 변수 추가";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "삭제";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "비어있는 변수 이름을 사용할 수 없습니다.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "이름 바꾸기";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "변수 이름";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "빈 리스트 생성";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "데이터 레코드가 없는, 길이가 0인 목록을 반환합니다.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "리스트";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "섹션을 추가, 제거하거나 순서를 변경하여 이 리스트 블럭을 재구성합니다.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "리스트 만들기";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "아이템을 리스트에 추가합니다.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "원하는 수의 항목들로 목록을 생성합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "첫 번째";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "마지막 번째 위치부터, # 번째";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "가져오기";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "잘라 내기";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "마지막";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "임의로";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "삭제";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "첫 번째 아이템을 찾아 돌려줍니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "목록에서 특정 위치의 항목을 반환합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "마지막 아이템을 찾아 돌려줍니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "리스트의 아이템들 중, 랜덤으로 선택해 돌려줍니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "첫 번째 아이템을 찾아내 돌려주고, 그 아이템을 리스트에서 삭제합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "목록의 특정 위치에 있는 항목을 제거하고 반환합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "마지막 아이템을 찾아내 돌려주고, 그 아이템을 리스트에서 삭제합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "목록에서 임의 위치의 아이템을 찾아내 삭제하고 돌려줍니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "리스트에서 첫 번째 아이템을 삭제합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "목록에서 특정 위치의 항목을 삭제합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "리스트에서 마지막 아이템을 찾아 삭제합니다.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "리스트에서 랜덤하게 아이템을 삭제합니다.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "끝에서부터 # 번째로";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "앞에서부터 # 번째로";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "마지막으로";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "첫 번째 위치부터, 서브 리스트 추출";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "마지막부터 # 번째 위치부터, 서브 리스트 추출";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "처음 # 번째 위치부터, 서브 리스트 추출";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "목록의 특정 부분에 대한 복사본을 만듭니다.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1은(는) 마지막 항목입니다.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1은 첫 번째 항목입니다.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "처음으로 나타난 위치";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "마지막으로 나타난 위치";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "목록에서 항목이 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 항목이 없으면 %1을 반환합니다.";
                +Blockly.Msg["LISTS_INLIST"] = "리스트";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1이 비어 있습니다";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "목록이 비었을 때 참을 반환합니다.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1의 길이";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "목록의 길이를 반환합니다.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "%1을 %2번 넣어, 리스트 생성";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "원하는 값을, 원하는 갯수 만큼 넣어, 목록을 생성합니다.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "에";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "에서 원하는 위치에 삽입";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "에서 설정";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "항목을 목록의 처음 위치에 삽입합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "목록의 특정 위치에 항목을 삽입합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "리스트의 마지막에 아이템을 추가합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "목록에서 임의 위치에 아이템을 삽입합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "첫 번째 위치의 아이템으로 설정합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "목록의 특정 위치에 있는 항목으로 설정합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "마지막 아이템으로 설정합니다.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "목록에서 임의 위치의 아이템을 설정합니다.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "오름차순";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "내림차순";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "정렬 %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "목록의 사본을 정렬합니다.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "알파벳순 (대소문자 구분 안 함)";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "숫자순";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "알파벳순";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "텍스트에서 목록 만들기";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "목록에서 텍스트 만들기";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "구분 기호로 구분하여 텍스트 목록을 하나의 텍스트에 병합합니다.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "각 속보, 텍스트의 목록들에서 텍스트를 분할합니다.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "분리와";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "거짓";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://ko.wikipedia.org/wiki/%EC%A7%84%EB%A6%BF%EA%B0%92";
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "참 혹은 거짓 모두 반환합니다.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "참";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://ko.wikipedia.org/wiki/부등식";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "두 값이 같으면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "첫 번째 값이 두 번째 값보다 크면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "첫 번째 값이 두 번째 값보다 크거나 같으면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "첫 번째 값이 두 번째 값보다 작으면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "첫 번째 값이 두 번째 값보다 작거나 같으면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "두 값이 서로 다르면, 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://ko.wikipedia.org/wiki/%EB%B6%80%EC%A0%95";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1가 아닙니다";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "입력값이 거짓이라면 참을 반환합니다. 참이라면 거짓을 반환합니다.";
                +Blockly.Msg["LOGIC_NULL"] = "빈 값";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "빈 값을 반환합니다.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "그리고";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://ko.wikipedia.org/wiki/%EB%B6%88_%EB%85%BC%EB%A6%AC";
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "또는";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "두 값이 모두 참(true) 값이면, 참 값을 돌려줍니다.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "적어도 하나의 값이 참일 경우 참을 반환합니다.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "테스트";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://ko.wikipedia.org/wiki/물음표";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "만약 거짓이라면";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "만약 참이라면";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'test'의 조건을 검사합니다. 조건이 참이면 'if true' 값을 반환합니다. 거짓이면 'if false' 값을 반환합니다.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ko.wikipedia.org/wiki/산술";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "두 수의 합을 반환합니다.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "두 수의 나눈 결과를 반환합니다.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "두 수간의 차이를 반환합니다.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "두 수의 곱을 반환합니다.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "첫 번째 수를 두 번째 수 만큼, 거듭제곱 한 결과값을 돌려줍니다.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "바꾸기 %1 만큼 %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "변수 '%1' 에 저장되어있는 값에, 어떤 수를 더해, 변수에 다시 저장합니다.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ko.wikipedia.org/wiki/수학_상수";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "일반적인 상수 값들 중 하나를 돌려줍니다. : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://ko.wikipedia.org/wiki/%ED%81%B4%EB%9E%A8%ED%95%91_(%EA%B7%B8%EB%9E%98%ED%94%BD)";
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1의 값을, 최소 %2 최대 %3으로 조정";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "어떤 수를, 특정 범위의 값이 되도록 강제로 조정합니다.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "가 다음 수로 나누어 떨어지면 :";
                +Blockly.Msg["MATH_IS_EVEN"] = "가 짝수(even) 이면";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "가 음(-)수 이면";
                +Blockly.Msg["MATH_IS_ODD"] = "가 홀수(odd) 이면";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "가 양(+)수 이면";
                +Blockly.Msg["MATH_IS_PRIME"] = "가 소수(prime) 이면";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "어떤 수가 짝 수, 홀 수, 소 수, 정 수, 양 수, 음 수, 나누어 떨어지는 수 인지 검사해 결과값을 돌려줍니다. 참(true) 또는 거짓(false) 값을 돌려줌.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "가 정수이면";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2의 나머지";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "첫 번째 수를 두 번째 수로 나눈, 나머지 값을 돌려줍니다.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "x";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ko.wikipedia.org/wiki/수_(수학)";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "수";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "평균값";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "최대값";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "중간값";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "최소값";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "가장 여러 개 있는 값";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "목록의 임의 항목";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "표준 편차";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "합";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "리스트에 들어있는 수(값)들에 대해, 산술 평균(arithmetic mean) 한 값을 돌려줍니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "리스트에 들어있는 수(값) 들 중, 가장 큰(max) 수(값)를 돌려줍니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "리스트에 들어있는 수(값) 들 중, 중간(median) 수(값)를 돌려줍니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "리스트에 들어있는 수(값) 들 중, 가장 작은(min) 수(값)를 돌려줍니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "리스트에 들어있는 아이템들 중에서, 가장 여러 번 들어있는 아이템들을 리스트로 만들어 돌려줍니다. (최빈값, modes)";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "목록에서 임의의 아이템을 돌려줍니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "이 리스트의 표준 편차를 반환합니다.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "리스트에 들어있는 수(값)들을, 모두 합(sum) 한, 총합(sum)을 돌려줍니다.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "임의 분수";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "0.0 (포함)과 1.0 (배타적) 사이의 임의 분수 값을 돌려줍니다.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "랜덤정수(%1<= n <=%2)";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "두 주어진 제한된 범위 사이의 임의 정수값을 돌려줍니다.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ko.wikipedia.org/wiki/반올림";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "반올림";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "버림";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "올림";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "어떤 수를 반올림/올림/버림한 결과를, 정수값으로 돌려줍니다.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ko.wikipedia.org/wiki/제곱근";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "절대값";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "제곱근";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "어떤 수의 절대값(absolute)을 계산한 결과를, 정수값으로 돌려줍니다.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "e의 거듭제곱 값을 반환합니다.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "어떤 수의, 자연로그(natural logarithm) 값을 돌려줍니다.(밑 e, 예시 log e x)";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "어떤 수의, 기본로그(logarithm) 값을 돌려줍니다.(밑 10, 예시 log 10 x)";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "음(-)/양(+), 부호를 반대로 하여 값을 돌려줍니다.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "10의 거듭제곱 값을 반환합니다.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "숫자의 제곱근을 반환합니다.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ko.wikipedia.org/wiki/삼각함수";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "어떤 수에 대한, acos(arccosine) 값을 돌려줍니다.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "어떤 수에 대한, asin(arcsine) 값을 돌려줍니다.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "어떤 수에 대한, atan(arctangent) 값을 돌려줍니다.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "각도의 코사인을 반환합니다. (라디안 아님)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "각도의 사인을 반환합니다. (라디안 아님)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "각도의 탄젠트를 반환합니다. (라디안 아님)";
                +Blockly.Msg["NEW_VARIABLE"] = "변수 만들기...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "새 변수 이름:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "서술 허가";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "사용:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ko.wikipedia.org/wiki/함수_(프로그래밍)";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "미리 정의해 둔 '%1' 함수를 실행합니다.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ko.wikipedia.org/wiki/함수_(프로그래밍)";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "미리 정의해 둔 '%1' 함수를 실행하고, 함수를 실행한 결과 값을 돌려줍니다.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "사용:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' 생성";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "이 함수를 설명하세요...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "함수 이름";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "함수";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "실행 후, 결과 값을 돌려주지 않는 함수를 만듭니다.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "다음을 돌려줌";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "실행 후, 결과 값을 돌려주는 함수를 만듭니다.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "경고: 이 함수에는, 같은 이름을 사용하는 매개 변수들이 있습니다.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "함수 정의 찾기";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "값이 참이라면, 두 번째 값을 반환합니다.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "경고: 이 블럭은, 함수 정의 블럭 안에서만 사용할 수 있습니다.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "매개 변수:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "함수에 값을 더합니다.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "매개 변수들";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "이 함수를 추가, 삭제, 혹은 재정렬합니다.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "다시 실행";
                +Blockly.Msg["REMOVE_COMMENT"] = "내용 제거";
                +Blockly.Msg["RENAME_VARIABLE"] = "변수 이름 바꾸기:";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "'%1' 변수 이름을 바꾸기:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "'%1' 변수의 끝에 일부 텍스트를 덧붙입니다.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "소문자로";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "첫 문자만 대문자로";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "대문자로";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "영문 대소문자 형태를 변경해 돌려줍니다.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "에서, 첫 번째 문자 얻기";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "에서, 마지막부터 # 번째 위치의 문자 얻기";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "에서, 앞에서부터 # 번째 위치의 문자 얻기";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "에서, 마지막 문자 얻기";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "에서, 랜덤하게 한 문자 얻기";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "텍스트 %1 %2에서";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "특정 번째 위치에서, 문자를 얻어내 돌려줍니다.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "텍스트에 항목을 추가합니다.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "가입";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "섹션을 추가, 제거하거나 순서를 변경하여 이 텍스트 블럭을 재구성합니다.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "끝에서부터 # 번째 문자까지";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "# 번째 문자까지";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "마지막 문자까지";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "문장";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "에서, 처음부터 얻어냄";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "에서, 마지막에서 # 번째부터 얻어냄";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "에서, 처음부터 # 번째 문자부터 얻어냄";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "문장 중 일부를 얻어내 돌려줍니다.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "에서 다음 문장이 처음으로 나타난 위치 찾기 :";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "에서 다음 문장이 마지막으로 나타난 위치 찾기 :";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "두 번째 텍스트에서 첫 번째 텍스트가 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 텍스트가 없으면 %1을 반환합니다.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1이 비어 있습니다";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "입력된 문장이, 빈 문장(\"\")이면 참(true) 값을 돌려줍니다.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "텍스트 만들기";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "여러 개의 아이템들을 연결해(묶어), 새로운 문장을 만듭니다.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "다음 문장의 문자 개수 %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "입력된 문장의, 문자 개수를 돌려줍니다.(공백문자 포함)";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "다음 내용 출력 %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "원하는 문장, 수, 값 등을 출력합니다.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "수에 대해 사용자의 입력을 받습니다.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "문장에 대해 사용자의 입력을 받습니다.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "메시지를 활용해 수 입력";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "메시지를 활용해 문장 입력";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ko.wikipedia.org/wiki/문자열";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "문자, 단어, 문장.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "양쪽의 공백 문자 제거";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "왼쪽의 공백 문자 제거";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "오른쪽의 공백 문자 제거";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "문장의 왼쪽/오른쪽/양쪽에서 스페이스 문자를 제거해 돌려줍니다.";
                +Blockly.Msg["TODAY"] = "오늘";
                +Blockly.Msg["UNDO"] = "실행 취소";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "항목";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'집합 %1' 생성";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://ko.wikipedia.org/wiki/%EB%B3%80%EC%88%98_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "변수에 저장 되어있는 값을 돌려줍니다.";
                +Blockly.Msg["VARIABLES_SET"] = "%1를 %2로 설정";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'%1 값 읽기' 블럭 생성";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://ko.wikipedia.org/wiki/%EB%B3%80%EC%88%98_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "변수의 값을 입력한 값으로 변경해 줍니다.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "'%1' 변수는 이미 존재합니다.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/lb.js b/blockly/webif/static/blockly/msg/js/lb.js
                new file mode 100644
                index 000000000..65bab97c0
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/lb.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.lb');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Bemierkung derbäisetzen";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Wäert änneren:";
                +Blockly.Msg["CLEAN_UP"] = "Bléck opraumen";
                +Blockly.Msg["COLLAPSE_ALL"] = "Bléck zesummeklappen";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Block zesummeklappen";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "Faarf 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "Faarf 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ratio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mëschen";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Sicht eng Faarf an der Palette eraus.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "zoufälleg Faarf";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Eng zoufälleg Faarf eraussichen.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blo";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "gréng";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "rout";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "fierwe mat";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "fir all Element %1 an der Lëscht %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "zielt mat %1 vun %2 bis %3 mat %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "soss";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "else if";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "wann";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "maach";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1-mol widderhuelen";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "widderhuele bis";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "Widderhuel soulaang";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Féiert d'Uweisungen aus, soulaang wéi de Wäert falsch ass.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Féiert d'Uweisungen aus, soulaang wéi de Wäert richteg ass";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "Block läschen";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 Bléck läschen";
                +Blockly.Msg["DISABLE_BLOCK"] = "Block desaktivéieren";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Eng Kopie maachen";
                +Blockly.Msg["ENABLE_BLOCK"] = "Block aktivéieren";
                +Blockly.Msg["EXPAND_ALL"] = "Bléck opklappen";
                +Blockly.Msg["EXPAND_BLOCK"] = "Block opklappen";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputs";  // untranslated
                +Blockly.Msg["HELP"] = "Hëllef";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";  // untranslated
                +Blockly.Msg["IOS_CANCEL"] = "Ofbriechen";
                +Blockly.Msg["IOS_ERROR"] = "Feeler";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Derbäisetzen";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Variabel derbäisetzen";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Läschen";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Dir kënnt keen eidelen Numm fir eng Variabel benotzen.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Ëmbenennen";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Numm vun der Variabel";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "Lëscht";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "En Element op d'Lëscht derbäisetzen.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "éischt";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# vun hannen";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "lescht";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "Zoufall";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ewechhuelen";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Schéckt en zoufällegt Element aus enger Lëscht zréck.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Hëlt dat lescht Element aus enger Lëscht eraus.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Hëlt en zoufällegt Element aus enger Lëscht eraus.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ass dat éischt Element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ass dat éischt Element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "an der Lëscht";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ass eidel";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "Längt vu(n) %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "%1 ëmdréinen";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "als";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "asetzen op";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Setzt d'Element um Enn vun enger Lëscht derbäi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Setzt d'Element op eng zoufälleg Plaz an d'Lëscht derbäi.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Setzt en zoufällegt Element an eng Lëscht.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeresch";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetesch";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falsch";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Schéckt entweder richteg oder falsch zréck.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "wouer";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "net %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "an";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "oder";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "Test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "wa falsch";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "wa wouer";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Den Total vun den zwou Zuelen zréckginn.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "D'Produkt vun den zwou Zuelen zréckginn.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "änneren %1 ëm %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";  // untranslated
                +Blockly.Msg["MATH_IS_EVEN"] = "ass gerued";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ass negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "ass ongerued";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ass positiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "ass eng Primzuel";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "ass eng ganz Zuel";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "Rescht vu(n) %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";  // untranslated
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Eng Zuel.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "Moyenne vun der Lëscht";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Maximum aus der Lëscht";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "zoufällegt Element vun enger Lëscht";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Schéckt de gréisste Wäert aus enger Lëscht zréck.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "zoufälleg ganz Zuel tëscht %1 a(n) %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "opronnen";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ofrënnen";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "oprënnen";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Eng Zuel op- oder ofrënnen.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://lb.wikipedia.org/wiki/Racine carrée";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "Quadratwuerzel";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "Variabel uleeën...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Neie variabelen Numm:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "mat:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "mat:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Dës Funktioun beschreiwen...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "eppes maachen";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "zréck";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Et gëtt schonn eng Prozedur mam Numm '%1'.";
                +Blockly.Msg["REDO"] = "Widderhuelen";
                +Blockly.Msg["REMOVE_COMMENT"] = "Bemierkung ewechhuelen";
                +Blockly.Msg["RENAME_VARIABLE"] = "Variabel ëmbenennen...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "All '%1' Variabelen ëmbenennen op:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "am Text %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "En Element bei den Text derbäisetzen.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "bis bei de Buschtaf #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "bis bei de leschte Buschtaw";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "am Text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "am Text %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ass eidel";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "Längt vu(n) %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 drécken";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Frot de Benotzer no engem Text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "%1 duerch %2 a(n) %3 ersetzen";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "All Kéiers wou e bestëmmten Text do ass duerch en aneren Text ersetzen.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Dréint d'Reiefolleg vun den Zeechen am Text ëm.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "E Buschtaf, e Wuert oder eng Textzeil.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Haut";
                +Blockly.Msg["UNDO"] = "Réckgängeg maachen";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "Element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/lki.js b/blockly/webif/static/blockly/msg/js/lki.js
                new file mode 100644
                index 000000000..f92772f9a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/lki.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.lki');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "گةپ دائن";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "تةغییر مقدار:";
                +Blockly.Msg["CLEAN_UP"] = "تمیزکردن بلاکةل";
                +Blockly.Msg["COLLAPSE_ALL"] = "چؤیچانن/پشکانن بلاکةل";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "چؤیچانن/پشکانن بلاک";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "رةنگ 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "رةنگ 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "نسبت";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "قاتی پاتی";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/رةنگ";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "رةنگێ إژ تةختة رةنگ انتخاب کةن";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "رةنگ بةختةکی";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = ".رةنگئ بةختةکی انتخاب کةن";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "کاوو";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "سؤز";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "سۆر";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "رةنگ وة";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ساخت یک رنگ با مقدار مشخص‌شده‌ای از سۆر، سؤز و کاوو. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "شکانِن حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ادامه با تکرار بعدی حلقه";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "شکستن حلقهٔ شامل.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "ئةرا هر مورد %1 وۀ نام لیست%2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "با تعداد %1 از %2 به %3 با گام‌های %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "افزودن یک شرط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "اضافه‌کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "افزودن، حذف یا بازمرتب‌سازی قسمت‌ها برای پیکربندی دوبارهٔ این بلوک اگر.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "آنگاه";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "اگر آنگاه";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "اگر";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://lki.wikipedia.org/wiki/حلقه_فور";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "انجوم بی";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%بار تکرار 1";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "انجام چةن عبارت چندین گِل.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "تکرار تا وةختێ گإ";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "تکرار در حالی که";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "حةذف کؤل %1 بلاکةل?";
                +Blockly.Msg["DELETE_BLOCK"] = "پاک کردن بلاک";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "حةذف %1 بلاکةل";
                +Blockly.Msg["DISABLE_BLOCK"] = "إ کار کةتن(غیرفعال‌سازی) بلاک";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "کؤپی کردن";
                +Blockly.Msg["ENABLE_BLOCK"] = "إ کارآشتن(فعال)بلاک";
                +Blockly.Msg["EXPAND_ALL"] = "کةلنگآ کردِن بلاکةل";
                +Blockly.Msg["EXPAND_BLOCK"] = "کةلنگآ کردِن بلاک";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ورودیةل خروجی";
                +Blockly.Msg["HELP"] = "کؤمةک";
                +Blockly.Msg["INLINE_INPUTS"] = "ورودیةل نوم جا";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "ایجاد فهرست خالی";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "لیست";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "اضافه‌کردن، حذف‌کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "ایجاد فهرست با";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "اضافه‌کردن یک مورد به فهرست.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "فهرستی از هر عددی از موارد می‌سازد.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "إژ أؤةل";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# إژ دؤما آخر";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "گِرتِن";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "گِرتِن و حةذف کردن";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "دؤمائن/آخرین";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "بةختةکی";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "حةذف کردن";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "اولین مورد یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "موردی در محل مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "آخرین مورد در یک فهرست را بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "یک مورد تصادفی در یک فهرست بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "اولین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "آخرین مورد را در یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "یک مورد تصادفی را یک فهرست حذف می‌کند.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "به # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "به #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "به آخرین";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "گرفتن زیرمجموعه‌ای از ابتدا";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "گرفتن زیرمجموعه‌ای از # از انتها";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "گرفتن زیرمجموعه‌ای از #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 آخرین مورد است.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 اولین مورد است.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "یافتن اولین رخ‌داد مورد";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "یافتن آخرین رخ‌داد مورد";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر آیتم موجود نبود.";
                +Blockly.Msg["LISTS_INLIST"] = "در فهرست";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "طول یک فهرست را برمی‌گرداند.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "به عنوان";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "درج در";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "مجموعه";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "موردی به ته فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "موردی به ته فهرست الحاق می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "مورد را به صورت تصادفی در یک فهرست می‌افزاید.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "اولین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "آخرین مورد در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "یک مورد تصادفی در یک فهرست را تعیین می‌کند.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "ساخت لیست إژ متن";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "ساخت متن إژ لیست";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "همراه جداساز";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "نادرست";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "بازگرداندن یکی از صحیح یا ناصحیح.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "درست";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "نه %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_NULL"] = "پةتی/خالی";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "تهی باز می گرداند";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "و";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "یا";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "آزمائشت";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "اگر نادرست";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "اگر درست";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "بازگرداندن مقدار جمع دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "بازگرداندن باقی‌ماندهٔ دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "بازگرداندن تفاوت دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "بازگرداندن حاصلضرب دو عدد.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "تغییر %1 با %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "افزودن یک عدد به متغیر '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "یکی از مقادیر مشترک را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "محدودکردن %1 پایین %2 بالا %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "تقسیم شده بر";
                +Blockly.Msg["MATH_IS_EVEN"] = "زوج است";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "منفی است";
                +Blockly.Msg["MATH_IS_ODD"] = "فرد است";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "مثبت است";
                +Blockly.Msg["MATH_IS_PRIME"] = "عدد اول است";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "کامل است";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "باقی‌ماندهٔ %1 + %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "شؤمارە یەک";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "میانگین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "بزرگ‌ترین فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "میانهٔ فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "گوجةرتةرین لیست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "مد فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "مورد تصادفی از فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "انحراف معیار فهرست";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "جمع لیست";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "میانهٔ عدد در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "کوچک‌ترین عدد در فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "موردی تصادفی از فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "انحراف معیار فهرست را بر می‌گرداند.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "جمع همهٔ عددهای فهرست را باز می‌گرداند.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "کسر تصادفی";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "عدد صحیح تصادفی بین %1 تا %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "گردکردن";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "گرد به پایین";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "گرد به بالا";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "گردکردن یک عدد به بالا یا پایین.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "مطلق";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ریشهٔ دوم";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "قدر مطلق یک عدد را بازمی‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "بازگرداندن توان e یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "لوگاریتم طبیعی یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "منفی‌شدهٔ یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "بازگرداندن توان ۱۰ یک عدد.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ریشهٔ دوم یک عدد را باز می‌گرداند.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "بازگرداندن آرک‌کسینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = ".(بازگرداندن آرک‌سینوس درجه (نه رادیان";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "بازگرداندن آرک‌تانژانت درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "بازگرداندن کسینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "بازگرداندن سینوس درجه (نه رادیان).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "بازگرداندن تانژانت یک درجه (نه رادیان).";
                +Blockly.Msg["NEW_VARIABLE"] = "متغیر تازه...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "نام متغیر تازه:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "اجازه اظهارات";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1».";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "با:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "ساختن «%1»";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "انجام چیزی";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "به";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "تابعی می‌سازد بدون هیچ خروجی.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "بازگشت";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "تابعی با یک خروجی می‌سازد.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "اخطار: این تابعی پارامتر تکراری دارد.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "برجسته‌سازی تعریف تابع";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "اگر یک مقدار صحیح است، مقدار دوم را برگردان.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "نام ورودی:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "اضافه کردن ورودی به تابع.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ورودی‌ها";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "پاک کردن گةپةل/قِسةل";
                +Blockly.Msg["RENAME_VARIABLE"] = "تغییر نام متغیر...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "تغییر نام همهٔ متغیرهای «%1» به:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "الحاق متنی به متغیر «%1».";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "به حروف کوچک";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "به حروف بزرگ عنوان";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "به حروف بزرگ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "بازگرداندن کپی متن در حالتی متفاوت.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "گرفتن اولین حرف";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "گرفتن حرف # از آخر";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "گرفتن حرف #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "گرفتن آخرین حرف";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "گرفتن حرف تصادفی";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "حرفی در موقعیت مشخص‌شده بر می‌گرداند.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "افزودن یک مورد به متن.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "نام نؤیسی";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "اضافه‌کردن، حذف یا مرتب‌سازی بحش‌ها برای تنظیم مجدد این بلوک متنی.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "به حرف # از انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "به حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "به آخرین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "در متن";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "گرفتن زیرمتن از اولین حرف";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "گرفتن زیرمتن از حرف # به انتها";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "گرفتن زیرمتن از حرف #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "اولین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "آخرین رخداد متن را بیاب";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 خالی است";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "اضافه‌کردن صحیح اگر متن فراهم‌شده خالی است.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ایجاد متن با";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "طول %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "چاپ %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "اعلان برای کاربر با یک عدد.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "اعلان برای کاربر برای یک متن.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "اعلان برای عدد با پیام";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "اعلان برای متن با پیام";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "یک حرف، کلمه یا خطی از متن.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "تراشیدن فاصله‌ها از  هر دو طرف";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "تراشیدن فاصله‌ها از  طرف چپ";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.";
                +Blockly.Msg["TODAY"] = "ایمڕۆ";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "آیتم";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "درست‌کردن «تنظیم %1»";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "مقدار این متغیر را بر می‌گرداند.";
                +Blockly.Msg["VARIABLES_SET"] = "مجموعه %1 به %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "درست‌کردن «گرفتن %1»";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "متغیر برابر با خروجی را مشخص می‌کند.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/lrc.js b/blockly/webif/static/blockly/msg/js/lrc.js
                new file mode 100644
                index 000000000..076cb614b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/lrc.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.lrc');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "نظرتونه اضاف بکید";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "ارزشت آلشت کو:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "کوچک کردن برشتیا";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "کوچک کردن برشت";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "رن 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "رن 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "نسوت";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "شیوسته";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "هر کوم د رنگیانه وا نسوت دائه بیه به شیون(0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "یه رن د رنگ دو انتخاو بکید";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "رن بختکی";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "یه رنگ بختکی انتخاو بکید";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "آوی";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "سوز";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "سور";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "رن وا";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "حلقه نه خراو کو";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "حلقه شومل بیه نه خراو کو";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "سی هر قلم %1 د نوم گه %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "اشماردن وا %1 د %2 سی %3 وا %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "هنی";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "هنی ار";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ار";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "انجوم بئه";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 تکرار کو چن بار";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "تا تکرار کو";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "تا تکرار کو";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "پاکسا کردن برشت";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "پاکسا کردن%1 د برشتیا";
                +Blockly.Msg["DISABLE_BLOCK"] = "ناکشتگر کردن برشت";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "کپی کردن";
                +Blockly.Msg["ENABLE_BLOCK"] = "کنشتگر کردن برشت";
                +Blockly.Msg["EXPAND_ALL"] = "گپ کردن برشتیا";
                +Blockly.Msg["EXPAND_BLOCK"] = "گپ کردن برشت";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "داده یا وه دری";
                +Blockly.Msg["HELP"] = "هومياری";
                +Blockly.Msg["INLINE_INPUTS"] = "داده یا مئنجا";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "یه گل نوم گه حالی راس بکیت";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "نوم گه";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "اولی";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# تا آخر";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "گرتن";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "گرتن و جاوه جا بیئن";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "آخر";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "بختكی";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ؤرداشتن";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "سی#";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "سی آخر";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "د نوم گه";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 حالیه";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "چی";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "بنه د";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "غلط";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "هم غلط و هم راس ورگن";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "راست و دوروست";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "نه %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "خمثی";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "و";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "یا";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "آزماشت کردن";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ار غلط بی";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ار درس بی";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "وه انازه دو گل شماره ورگن.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "آلشت بكيد %1 وا %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "یه وا بهر بیه";
                +Blockly.Msg["MATH_IS_EVEN"] = "همیشه هیئش";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "منفیه";
                +Blockly.Msg["MATH_IS_ODD"] = "تهنائه";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "مثبته";
                +Blockly.Msg["MATH_IS_PRIME"] = "وه اوله";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "همشه";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "یه شماره.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "مینجاگه نوم گه";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "بیشترونه د نومگه";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "مینجا نوم گه";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "کمترونه د نومگه";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "بیشری د نومگه";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "جم کردن نومگه";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "گرد کردن";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "وه هار گرد کردن";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "وه رو گرد کردن";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "تموم و کمال";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "چارسوک ریشه";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "آلشتگر تازه...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "نوم آلشتگر تازه:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "وا:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "وا:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "راس کردن%1";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "یه کار انجوم بیئت";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "سی";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "ورگنیئن";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "نوم داده:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "داده یا";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "نظر جا وه جا کو";
                +Blockly.Msg["RENAME_VARIABLE"] = "د نو نوم نیائن آلشتگر...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "د نو نوم نیائن %1 د تموم آلشتگریا د:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "سی واج کؤچک";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "سی حرف گپ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "پیوسن";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "سی واج# تا آخر";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "سی واج#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "سی آخرین واج";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "د متن";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 حالیه";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "راس کردن متن وا";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "ئمروٙ";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "قلم";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "میزوکاری %1 سی %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/lt.js b/blockly/webif/static/blockly/msg/js/lt.js
                new file mode 100644
                index 000000000..8ba3f8c87
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/lt.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.lt');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Palikti komentarą";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Keisti reikšmę:";
                +Blockly.Msg["CLEAN_UP"] = "Išvalyti blokus";
                +Blockly.Msg["COLLAPSE_ALL"] = "Suskleisti blokus";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Suskleisti bloką";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "1 spalva";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "2 spalva";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "santykis";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "sumaišyk";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Sumaišo dvi spalvas su pateiktu santykiu (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://lt.wikipedia.org/wiki/Spalva";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Pasirinkti spalvą iš paletės.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "atsitiktinė spalva";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Pasirinkti spalvą atsitiktinai.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "mėlyna";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "žalia";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "raudona";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "spalva su";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Spalvą galima sudaryti iš raudonos, žalios ir mėlynos dedamųjų. Kiekvienos intensyvumas nuo 0 iki 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "nutraukti kartojimą";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "šį kartą praleisti likusius veiksmus ir tęsti kartojimą";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Nutraukia (artimiausią) vykstantį kartojimą.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Praleidžia žemiau išvardintus kartojimo veiksmus (ir tęsia darbą nuo kartojimo pradinio veiksmo).";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Atsargiai: šis blokas gali būt naudojamas tik kartojimo bloko viduje.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "kartok su kiekvienu %1 iš sąrašo %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Kartok veiksmus, kol kintamasis \"%1\" paeiliui gauna kiekvieną sąrašo reikšmę.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "kartok, kai %1 kinta nuo %2 iki %3 po %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Imama kintamoji '%1' reikšmė nuo pradinio skaičiaus iki pabaigos skaičiaus, skaičiuojant nustatytais intervalais ir atliekant nustatytus blokus.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Pridėti sąlygą „jei“ blokui.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Pridėti veiksmų vykdymo variantą/\"šaką\", kai netenkinama nė viena sąlyga.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Galite pridėt/pašalinti/pertvarkyti  sąlygų \"šakas\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "kitu atveju";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "arba jei";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "jei";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Jeigu sąlyga tenkinama, tai atlik veiksmus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Jei sąlyga tenkinama, atlikti jai priklausančius veiksmus, o jei ne -- atlikti kitus nurodytus veiksmus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Jei pirma sąlyga tenkinama, atlikti jai priklausančius veiksmus, O jei ne, tikrinti antrą sąlygą -- ir jei ši tenkinama, atlikti jos veiksmus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Jei pirma sąlyga tenkinama, atlikti jai priklausančius veiksmus, O jei ne, tikrinti antrą sąlygą -- ir jei ši tenkinama, atlikti jos veiksmus. Kitais atvejais -- atlikti paskutinio bloko veiksmus.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "daryti";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "pakartokite %1 kartus";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Leidžia atlikti išvardintus veiksmus kelis kartus.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "kartok, kol pasieksi";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "kartok kol";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Kartoja veiksmus, kol bus pasiekta nurodyta sąlyga.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Kartoja veiksmus, kol sąlyga tenkinama.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Ištrinti visus %1 blokus?";
                +Blockly.Msg["DELETE_BLOCK"] = "Ištrinti bloką";
                +Blockly.Msg["DELETE_VARIABLE"] = "Ištrinti „%1“ kintamąjį";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Ištrinti %1 blokus";
                +Blockly.Msg["DISABLE_BLOCK"] = "Išjungti bloką";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kopijuoti";
                +Blockly.Msg["ENABLE_BLOCK"] = "Įjungti bloką";
                +Blockly.Msg["EXPAND_ALL"] = "Išskleisti blokus";
                +Blockly.Msg["EXPAND_BLOCK"] = "Išskleisti bloką";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Išdėstyti stulpeliu, kai daug parametrų";
                +Blockly.Msg["HELP"] = "Pagalba";
                +Blockly.Msg["INLINE_INPUTS"] = "Išdėstyti vienoje eilutėje";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "tuščias sąrašas";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Grąžina sąrašą, ilgio 0, neturintį duomenų";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "sąrašas";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Pridėti, pašalinti arba paskirstyti skyrius, kad pertvarkyti šį teksto bloką.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "sukurti sąrašą su";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Pridėti elementą į sąrašą.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Sukurti sąrašą iš bet kokio skaičiaus elementų.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "pirmas";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# nuo galo";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "paimk";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "paimk ir ištrink";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "paskutinis";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "atsitiktinis";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "pašalinti";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Grąžina pirmąjį sąrašo elementą.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Gražina objektą į nurodyta poziciją sąraše.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Grąžina paskutinį elementą iš sąrašo.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Grąžina atsitiktinį elementą iš sąrašo.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "iki # nuo galo";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "iki #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "iki galo";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "sąrašo dalis nuo pradžios";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "sąrašo dalis nuo # nuo galo";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "sąrašo dalis nuo #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 yra paskutinis objektas.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 yra pirmasis objektas.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "rask pirmą reikšmę";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "rask paskutinę reikšmę";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Grąžina pirmos/paskutinės reikšmės eilės nr. sąraše. Grąžina %1, jei reikšmės neranda.";
                +Blockly.Msg["LISTS_INLIST"] = "sąraše";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 yra tuščias";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Grąžina „true“, jeigu sąrašas tuščias.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "ilgis %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Grąžina sąrašo ilgį.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "sukurk sąrašą, kuriame %1 bus %2 kartus";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "kaip";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "įterpk į vietą";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "priskirk elementui";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Įterpią objektą į nurodytą poziciją sąraše.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "didėjančia tvarka";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "mažėjančia tvarka";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "rūšiuoti %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Rūšiuoti sąrašo kopiją.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "abecėlės, ignoruoti raidžių dydį";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "skaitmeninis";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "abėcėlės";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "su dalikliu";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "klaidinga";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Reikšmė gali būti \"teisinga\"/\"Taip\" arba \"klaidinga\"/\"Ne\".";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "tiesa";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Tenkinama, jei abu reiškiniai lygūs.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Grįžti tiesa, jei pirmoji įvestis didesnė nei antroji įvestis.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Grįžti tiesa, jei pirma įvestis didesnė arba lygi antrajai įvesčiai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Grįžti tiesa, jei pirma įvestis mažesnė nei antra įvestis.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Grįžti tiesa, jei pirma įvestis mažesnė arba lygi antrajai įvesčiai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Grįžti tiesa, jeigu abi įvestys ne lygios tarpusavyje.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ne %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Grįžti tiesa, jei įvestis klaidinga. Grįžti klaidinga, jei įvestis teisinga.";
                +Blockly.Msg["LOGIC_NULL"] = "nieko";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Reikšmė nebuvo nurodyta...";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ir";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "arba";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Bus teisinga, kai abi sąlygos bus tenkinamos.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Grįžti tiesa, jei bent viena įvestis teisinga.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "sąlyga";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "jei ne";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "jei taip";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Jeigu sąlygą tenkinama, grąžina pirmą reikšmę, o jei ne - antrąją.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Grąžina dviejų skaičių sumą.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Grąžina dviejų skaičių dalmenį.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Grąžina dviejų skaičių skirtumą.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Grąžina dviejų skaičių sandaugą.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Grąžina pirmą skaičių pakeltą laipsniu pagal antrą skaičių.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "padidink %1 (emptypage) %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Prideda skaičių prie kintamojo '%1'. Kai skaičius neigiamas - gaunasi atimtis.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Grįžti viena iš pagrindinių konstantų: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (begalybė).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "apribok %1 tarp %2 ir %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Apriboti skaičių, kad būtų tarp nustatytų ribų (imtinai).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "yra dalus iš";
                +Blockly.Msg["MATH_IS_EVEN"] = "yra lyginis";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "yra neigiamas";
                +Blockly.Msg["MATH_IS_ODD"] = "yra nelyginis";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "yra teigiamas";
                +Blockly.Msg["MATH_IS_PRIME"] = "yra pirminis";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Patikrina skaičiaus savybę: (ne)lyginis/pirminis/sveikasis/teigiamas/neigiamas/dalus iš x.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "yra sveikasis";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "dalybos liekana %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Grįžti likučiu nuo dviejų skaičių dalybos.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://lt.wikipedia.org/wiki/Skaičius";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Skaičius.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "vidurkis";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "didžiausia reikšmė sąraše";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana sąrašui";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mažiausia reikšmė sąraše";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "statistinė moda sąrašui";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "atsitiktinis elementas iš sąrašo";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standartinis nuokrypis sąraše";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Grįžti vidurkiu (aritmetinis vidurkis) iš skaitinių reikšmių sąraše.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Grįžti didžiausiu skaičiumi sąraše.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Grąžinti sąrašo medianą.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Grįžti mažiausiu skaičiumi sąraše.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Grąžinti sąrašą dažniausių elementų sąraše.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Grąžinti atsitiktinį elementą iš sąrašo.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Grįžti standartine pakraipa iš sąrašo.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "didžiausia reikšmė";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "atsitiktinė trupmena";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Atsitiktinė trupmena nuo 0 (imtinai) iki 1 (neimtinai).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "atsitiktinis sveikas sk. nuo %1 iki %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Grįžti atsitiktinį sveikąjį skaičių tarp dviejų nustatytų ribų, imtinai.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://lt.wikipedia.org/wiki/Apvalinimas";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "apvalink";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "apvalink žemyn";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "apvalink aukštyn";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Suapvalinti skaičių į žemesnę ar aukštesnę reikšmę.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "modulis";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadratinė šaknis";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Skaičiaus modulis - reikšmė be ženklo (panaikina minusą).";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Grąžinti skaičių laipsniu e.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Grąžinti skaičiaus natūrinį logaritmą.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Grįžti 10 pagrindinių logaritmų iš skaičiaus.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Grąžina skaičiui priešingą skaičių.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Grąžinti skaičių laipsniu 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Grįžti kvadratinę šaknį iš skaičiaus.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://lt.wikipedia.org/wiki/Trigonometrinės_funkcijos";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Grąžinti skaičiaus arkkosinusą.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Grąžinti skaičiaus arksinusą.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Grąžinti skaičiaus arktangentą.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Grąžinti laipsnio kosinusą (ne radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Grąžinti laipsnio sinusą (ne radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Grąžinti laipsnio tangentą (ne radiano).";
                +Blockly.Msg["NEW_VARIABLE"] = "Naujas kintamasis...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Naujo kintamojo pavadinimas:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "leisti vidinius veiksmus";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "pagal:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Vykdyti sukurtą komandą \"%1\".";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Įvykdyti komandą \"%1\" ir naudoti jos suskaičiuotą (atiduotą) reikšmę.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "su:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Sukurti \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "daryk kažką";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "komanda:";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Sukuria procedūrą - komandą, kuri nepateikia jokio rezultato (tik atlieka veiksmus).";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "duok";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Sukuria funkciją - komandą, kuri ne tik atlieka veiksmus bet ir pateikia (grąžina/duoda) rezultatą.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Ši komanda turi du vienodus gaunamų duomenų pavadinimus.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Jeigu pirma reikšmė yra teisinga (sąlyga tenkinama), grąžina antrą reikšmę.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Perspėjimas: šis blokas gali būti naudojamas tik aprašant funkciją.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "parametro pavadinimas:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Pridėti funkcijos parametrą (gaunamų duomenų pavadinimą).";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "gaunami duomenys (parametrai)";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Tvarkyti komandos gaunamus duomenis (parametrus).";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Atkurti";
                +Blockly.Msg["REMOVE_COMMENT"] = "Pašalinti komentarą";
                +Blockly.Msg["RENAME_VARIABLE"] = "Pervardyti kintamajį...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Pervadinti visus '%1' kintamuosius į:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Pridėti tekstą prie kintamojo '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = " mažosiom raidėm";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = " Pavadinimo Raidėmis";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = " DIDŽIOSIOM RAIDĖM";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Kitu atvėju, grąžina teksto kopiją.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "gauti pirmą raidę";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "raidė nuo galo #";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "gauti raidę #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "gauti paskutinę raidę";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "gauti atsitiktinę raidę";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Grąžina raidę į tam tikrą poziciją.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "skaičius %1 iš %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Suskaičiuoti, kiek kartų šis tekstas kartojasi kitame tekste.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Pridėti teksto elementą.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "sujunk";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Pridėti, pašalinti arba paskirstyti skyrius, kad pertvarkyti šį teksto bloką.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "iki raidės nuo galo #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "iki raidės #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "iki pabaigos";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "tekste";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "dalis nuo pradžios";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "dalis nuo raidės #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "dalis nuo raidės #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Grąžina tam tikrą teksto dalį.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "rask,kur pirmą kartą paminėta";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "rask,kur paskutinį kartą paminėta";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Grąžina pirmą/paskutinę pirmo teksto reikšmę antrame tekste. Grąžina %1, jei tekstas nerastas.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 yra tuščias";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Grįžti tiesa, jei numatytas tekstas tuščias.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "sukurti tekstą su";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Sukurti teksto fragmentą sujungiant bet kokį skaičių fragmentų.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "teksto %1 ilgis";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Suranda teksto simbolių kiekį (įskaitant ir tarpus)";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "spausdinti %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Spausdinti nurodytą tekstą, skaičių ar kitą reikšmę.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prašyti vartotoją įvesti skaičių.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prašyti vartotoją įvesti tekstą.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "paprašyk įvesti skaičių :";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "paprašyk įvesti tekstą :";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "pakeisti %1 į %2 šiame %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Pašalinti visas teksto dalis kitame tekste.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "atbulai %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Apversti teksto simbolių tvarką.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Tekstas (arba žodis, ar raidė)";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "išvalyk tarpus šonuose";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "išvalyk tarpus pradžioje";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "išvalyk tarpus pabaigoje";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Grąžina teksto kopiją, pašalinus tarpus iš vieno ar abiejų kraštų.";
                +Blockly.Msg["TODAY"] = "Šiandien";
                +Blockly.Msg["UNDO"] = "Anuliuoti";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "elementas";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Sukurk \"priskirk %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "priskirk %1 = %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Sukurti 'kintamasis %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/lv.js b/blockly/webif/static/blockly/msg/js/lv.js
                new file mode 100644
                index 000000000..59a912df3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/lv.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.lv');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Pievienot komentāru";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Mainīt vērtību:";
                +Blockly.Msg["CLEAN_UP"] = "Sakopt blokus";
                +Blockly.Msg["COLLAPSE_ALL"] = "Sakļaut blokus";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Sakļaut bloku";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "1. krāsa";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "2. krāsa";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "attiecība";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "sajaukt";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Sajauc kopā divas krāsas ar doto attiecību (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://lv.wikipedia.org/wiki/Krāsa";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Izvēlēties krāsu no paletes.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "nejauša krāsa";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Izvēlēties krāsu pēc nejaušības principa.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "zila";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zaļa";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "sarkana";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "veido krāsu no";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Izveidot krāsu ar norādīto daudzumu sarkanā, zaļā un zilā toņu. Visas vērtības ir starp 0 un 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "iet ārā no cikla";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "turpināt ar cikla nākamo iterāciju";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Iet ārā no iekļaujošā cikla";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Nepildīt atlikušo cikla daļu bet sākt nākamo iterāciju.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Brīdinājums: šo bloku drīkst izmantot tikai cikla iekšienē.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "visiem %1 no saraksta %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Katram objektam no saraksta piešķirt mainīgajam '%1' šo objektu un izpildīt komandas.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "skaitīt %1 no %2 līdz %3 ar soli %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Ļauj mainīgajam '%1' pieņemt vērtības no sākuma līdz beigu vērtībai, un izpildīt iekļautos blokus katrai no šīm pieņemtajām vērtībām.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Pievienot nosacījumu \"ja\" blokam.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Pievienot gala nosacījumu \"ja\" blokam.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Pievienot, noņemt vai mainīt sekciju secību šim \"ja\" blokam.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "citādi";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "citādi, ja";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ja";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ja vērtība ir patiesa, tad izpildīt komandas.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ja vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi izpildīt otro bloku ar komandām.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ja pirmā vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi, ja otrā vērtība ir patiesa, izpildīt otro bloku ar komandām.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ja pirmā vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi, ja otrā vērtība ir patiesa, izpildīt otro bloku ar komandām. Ja neviena no vertībām nav patiesa, tad izpildīt pēdējo bloku ar komandām.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://lv.wikipedia.org/wiki/Cikls";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "izpildi";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "atkārtot %1 reizes";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Izpildīt komandas vairākas reizes.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "atkārtot līdz";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "atkārtot kamēr";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Izpildīt komandas, kamēr vērtība ir nepatiesa.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Izpildīt komandas, kamēr vērtība ir patiesa.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Izdzēst visus %1 blokus?";
                +Blockly.Msg["DELETE_BLOCK"] = "Izmest bloku";
                +Blockly.Msg["DELETE_VARIABLE"] = "Izdzēst mainīgo \"%1\"";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Mainīgais \"%2\" tiek izmantots %1 vietās. Dzēst?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Izmest %1 blokus";
                +Blockly.Msg["DISABLE_BLOCK"] = "Atspējot bloku";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Dublēt";
                +Blockly.Msg["ENABLE_BLOCK"] = "Iespējot bloku";
                +Blockly.Msg["EXPAND_ALL"] = "Izvērst blokus";
                +Blockly.Msg["EXPAND_BLOCK"] = "Izvērst bloku";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Ārējie ievaddati";
                +Blockly.Msg["HELP"] = "Palīdzība";
                +Blockly.Msg["INLINE_INPUTS"] = "Iekšējie ievaddati";
                +Blockly.Msg["IOS_CANCEL"] = "Atcelt";
                +Blockly.Msg["IOS_ERROR"] = "Kļūda";
                +Blockly.Msg["IOS_OK"] = "Labi";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Pievienot";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Pievienot mainīgo";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Dzēst";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Pārsaukt";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Mainīgā nosaukums";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "izveidot tukšu sarakstu";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Izveidot sarakstu bez elementiem tajā.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "saraksts";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Pievienot, noņemt vai mainīt sekciju secību šim \"saraksta\" blokam.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "izveidot sarakstu no";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Pievienot objektu sarakstam.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Izveidot sarakstu no jebkura skaita vienību.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "pirmo";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "no beigām numur";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "paņemt";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "paņemt uz dzēst";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "pēdējo";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "nejauši izvēlētu";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "dzēst";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Atgriež pirmo saraksta elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Atgriež norādīto elementu no saraksta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Atgriež pēdējo saraksta elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Atgriež nejauši izvēlētu saraksta elementu";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Atgriež un izdzēš saraksta pirmo elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Atgriež un izdzēš no saraksta norādīto elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Atgriež un izdzēš saraksta pēdējo elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Atgriež un izdzēš no saraksta nejauši izvēlētu elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Izdēš pirmo saraksta elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Izdēš norādīto elementu no saraksta.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Izdēš pēdējo saraksta elementu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Izdzēš no saraksta nejauši izvēlētu elementu.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "līdz pozīcijai no beigām";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "līdz pozīcijai";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "līdz beigām";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "paņemt apakšsarakstu no sākuma";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "paņemt apakšsarakstu no beigām no pozīcijas";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "paņemt apakšsarakstu no pozīcijas";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Nokopēt daļu no dotā saraksta.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Saraksta elementu numerācija no beigām sākas no %1";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Saraksta elementu numerācija sākas no %1";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "atrast pirmo elementu, kas vienāds ar";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "atrast pēdējo elementu, kas vienāds ar";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Atgriež pozīciju sarakstā, kurā atrodas dotais objekts. Atgriež %1 ja objekts neatrodas sarakstā.";
                +Blockly.Msg["LISTS_INLIST"] = "sarakstā";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ir tukšs";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Patiess, ja saraksts ir tukšs.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 garums";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Atgriež elementu skaitu srakstā.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "saraksts no %1 atkārtots %2 reizes";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Izveido sarakstu, kas sastāv no dotās vērtības noteiktu reižu skaita.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "kā";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "ievieto";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "aizvieto";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Ievieto elementu saraksta sākumā.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Ievieto sarakstā elementu norādītajā pozīcijā.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Pievieno elementu saraksta beigās.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Ievieto sarakstā jaunu elementu nejauši izvēlētā pozīcijā.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Aizvieto elementu saraksta sākumā.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Aizvieto sarakstā elementu norādītajā pozīcijā.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Aizvieto elementu saraksta beigās.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Aizvieto sarakstā elementu nejauši izvēlētā pozīcijā.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "augošā";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "dilstošā";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "Sakārtot sarakstu no %3 elementiem %2 secībā %1";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Saraksta sakārtota kopija.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "pēc alfabēta, ignorēt mazos/lielos burtus";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "skaitliski";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "pēc alfabēta";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "vārdu saraksts no teksta";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "izveidot tekstu no saraksta";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Apvienot tekstu izmantojot atdalītāju.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Sadalīt tekstu vārdos izmantojot atdalītāju.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "ar atdalītāju";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "aplams";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Atgriež rezultātu \"patiess\" vai \"aplams\".";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "patiess";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://lv.wikipedia.org/wiki/Nevien%C4%81d%C4%ABba";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Patiess, ja abas puses ir vienādas.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Patiess, ja kreisā puse ir lielāka par labo pusi.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Patiess, ja kreisā puse ir lielāka vai vienāda ar labo pusi.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Patiess, ja kreisā puse ir mazāka par labo pusi.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Patiess, ja kreisā puse ir mazāka vai vienāda ar labo pusi.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Patiess, ja abas puses nav vienādas.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ne %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Patiess, ja arguments ir aplams.";
                +Blockly.Msg["LOGIC_NULL"] = "nekas";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Atgriež neko.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "un";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "vai";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Patiess, ja abas puses ir patiesas.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Patiess, ja vismaz viena puse ir patiesa.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "nosacījums";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ja aplams";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ja patiess";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Pārbaudīt nosacījumu. Ja 'nosacījums' ir patiess, atgriež vērtību 'ja patiess', pretējā gadījumā vērtību 'ja aplams'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://lv.wikipedia.org/wiki/Aritm%C4%93tika";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Atgriež divu skaitļu summu.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Atgriež divu skaitļu dalījumu.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Atgriež divu skaitļu starpību.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Atgriež divu skaitļu reizinājumu.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Atgriež pirmo skaitli kāpinātu pakāpē otrais skaitlis.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "izmainīt %1 par %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Pieskaitīt doto skaitli mainīgajam '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Atgriež kādu no matemātikas konstantēm: π (3.141…), e (2.718…), φ (1.618…), √(2) (1.414…), √(½) (0.707…), ∞ (bezgalība).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "ierobežot %1 no %2 līdz %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Ierobežo skaitli no noteiktajās robežās (ieskaitot galapunktus).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "dalās bez atlikuma ar";
                +Blockly.Msg["MATH_IS_EVEN"] = "ir pāra";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ir negatīvs";
                +Blockly.Msg["MATH_IS_ODD"] = "ir nepāra";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ir pozitīvs";
                +Blockly.Msg["MATH_IS_PRIME"] = "ir pirmskaitlis";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Pārbauda, vai skaitlis ir pāra, nepāra, vesels, pozitīvs, negatīvs vai dalās ar noteiktu skaitli. Atgriež \"patiess\" vai \"aplams\".";
                +Blockly.Msg["MATH_IS_WHOLE"] = "ir vesels";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "atlikums no %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Atlikums no divu skaitļu dalījuma.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://lv.wikipedia.org/wiki/Skaitlis";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Skaitlis.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "vidējais";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "lielākais";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediāna";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mazākais";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "moda";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "nejaušs";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standartnovirze";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summa";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Atgriež dotā saraksta vidējo aritmētisko vērtību.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Atgriež lielāko vērtību no saraksta.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Atgriež dotā saraksta mediānas vērtību.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Atgriež mazāko vērtību no saraksta.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Atgriež dotā saraksta biežāk sastopamās vērtības (modas).";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Atgriež nejauši izvēlētu vērtību no dotā saraksta.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Atgriež dotā saraksta standartnovirzi.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Saskaitīt visus skaitļus no dotā saraksta.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "nejaušs skaitlis [0..1)";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Atgriež nejaušu reālo skaitli robežās no 0 (iekļaujot) līdz 1 (neiekļaujot).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "nejaušs vesels skaitlis no %1 līdz %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Atgriež nejaušu veselu skaitli dotajās robežās (iekļaujot galapunktus)";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "noapaļot";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "apaļot uz leju";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "apaļot uz augšu";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Noapaļot skaitli uz augšu vai uz leju.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://lv.wikipedia.org/wiki/Kvadr%C4%81tsakne";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolūtā vērtība";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadrātsakne";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Atgriež skaitļa absolūto vērtību.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Atgriež e pakāpē dotais skaitlis.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Atgriež skaitļa naturālo logaritmu.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Atgriež skaitļa logaritmu pie bāzes 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Atgriež pretējo skaitli.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Atgriež 10 pakāpē dotais skaitlis.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Atgriež skaitļa kvadrātsakni.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://lv.wikipedia.org/wiki/Trigonometrisk%C4%81s_funkcijas";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Arkkosinuss (grādos).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Arksinuss (grādos).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Arktangenss (grādos).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Kosinuss no grādiem (nevis radiāniem).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Sinuss no grādiem (nevis radiāniem).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Tangenss no grādiem (nevis radiāniem).";
                +Blockly.Msg["NEW_VARIABLE"] = "Izveidot mainīgo...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Jaunā mainīgā vārds:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "atļaut apakškomandas";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ar:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Izpildīt iepriekš definētu funkcju '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Izpildīt iepriekš definētu funkcju '%1' un izmantot tās rezultātu.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ar:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Izveidot '%1' izsaukumu";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Funkcijas apraksts...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "darīt kaut ko";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "funkcija";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Izveido funkciju, kas neatgriež rezultātu.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "atgriezt";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Izveido funkciju, kas atgriež rezultātu.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Brīdinājums: funkcijai ir vienādi argumenti.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Izcelt funkcijas definīciju";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ja pirmā vērtība ir \"patiesa\", tad atgriezt otro vērtību.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Brīdinājums: Šo bloku var izmantot tikai funkcijas definīcijā.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "arguments:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Pievienot funkcijai argumentu.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "argumenti";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Pievienot, pārkārtot vai dzēst funkcijas argumentus.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Atcelt atsaukšanu";
                +Blockly.Msg["REMOVE_COMMENT"] = "Noņemt komentāru";
                +Blockly.Msg["RENAME_VARIABLE"] = "Pārdēvēt mainīgo...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Pārdēvējiet visus '%1' mainīgos:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Pievienot tekstu mainīgajam '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "kā mazie burti";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "kā Nosaukuma Burti";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "kā LIELIE BURTI";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Atgriež teksta kopiju ar mainītiem lielajiem/mazajiem burtiem.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "paņemt pirmo burtu";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "paņemt no beigām burtu #";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "paņemt burtu #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "paņemt pēdējo burtu";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "paņemt nejaušu burtu";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Atgriež burtu dotajā pozīcijā.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Pievienot tekstam objektu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "savienot";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Pievienot, noņemt vai mainīt sekciju secību šim \"teksta\" blokam.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "līdz burtam nr (no beigām)";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "līdz burtam nr";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "līdz pēdējam burtam";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "no teksta";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "paņemt apakšvirkni no sākuma";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "paņemt apakšvirkni no beigām sākot ar burta nr";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "paņemt apakšvirkni sākot no burta nr";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Atgriež norādīto teksta daļu.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "meklēt pirmo vietu, kur sākas teksts";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "meklēt pēdējo vietu, kur sākas teksts";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Meklē pirmā teksta rindu otrajā tekstā. Atgriež pozīciju otrajā tekstā, kurā sākas pirmais teksts. Atgriež %1 ja pirmā teksta rinda nav atrasta.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ir tukšs";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Patiess, ja teksts ir tukšs.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "veidot tekstu no";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Izveidot tekstu savienojot dotos argumentus.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "garums tekstam %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Atgriež burtu skaitu (ieskaitot atstarpes) dotajā tekstā.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "parādīt %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Parādīt norādīto tekstu vai skaitli.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Palūgt lietotāju ievadīt skaitli.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Palūgt lietotāju ievadīt tekstu.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "palūgt ievadīt skaitli ar ziņu";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "palūgt ievadīt tekstu ar ziņu";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Burts, vārds vai jebkāda teksta rinda.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "Dzēst atstarpes no abām pusēm";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "Dzēst atstarpes no sākuma";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "Dzēst atstarpes no beigām";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Atgriež teksta kopiju ar noņemtām atstarpēm vienā vai otrā galā.";
                +Blockly.Msg["TODAY"] = "Šodiena";
                +Blockly.Msg["UNDO"] = "Atsaukt";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "vienums";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Izveidot piešķiršanu mainīgajam %1";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Atgriež mainīgā vērtību.";
                +Blockly.Msg["VARIABLES_SET"] = "piešķirt mainīgajam %1 vērtību %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Izveidot 'ņem %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Piešķirt mainīgajam vērtību.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Mainīgais '%1' jau eksistē.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/mk.js b/blockly/webif/static/blockly/msg/js/mk.js
                new file mode 100644
                index 000000000..f922ff3be
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/mk.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.mk');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Додај коментар:";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Смена на вредност:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Собери блокови";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Собери блок";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "боја 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "боја 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "сооднос";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "смешај";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Меша две бои во даден сооднос (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://mk.wikipedia.org/wiki/Боја";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Изберете боја од палетата.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "случајна боја";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Избери боја на тепка.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "сина";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зелена";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "црвена";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "боја со";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Создајте боја со укажаните износи на црвена, зелена и сина. Сите вредности мора да бидат помеѓу 0 и 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "излези од јамката";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "продолжи со следното повторување на јамката";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Излези од содржечката јамка.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "за секој елемент %1 на списокот %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Му ја задава променливата „%1“ на секој елемент на списокот, а потоа исполнува наредби.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "број со %1 од %2 до %3 со %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Променливата \"%1\" да ги земе вредностите од почетниот до завршниот број, броејќи според укажаниот интервал и ги исполнува укажаните блокови.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Додава, отстранува или прередува делови за прераспоредување на овој блок „ако“.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "инаку";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "инаку ако";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ако";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://mk.wikipedia.org/wiki/For-јамка";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "исполни";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "повтори %1 пати";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Исполнува наредби неколку пати.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "повторувај сè до";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "повторувај додека";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Додека вредноста е невистинита, исполнува наредби.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Додека вредноста е вистинита, исполнува наредби.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Да ги избришам сите %1 блокчиња?";
                +Blockly.Msg["DELETE_BLOCK"] = "Избриши блок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Избриши %1 блока";
                +Blockly.Msg["DISABLE_BLOCK"] = "Исклучи блок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Ископирај";
                +Blockly.Msg["ENABLE_BLOCK"] = "Вклучи блок";
                +Blockly.Msg["EXPAND_ALL"] = "Рашири блокови";
                +Blockly.Msg["EXPAND_BLOCK"] = "Рашири го блокови";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Надворешен внос";
                +Blockly.Msg["HELP"] = "Помош";
                +Blockly.Msg["INLINE_INPUTS"] = "Внатрешен внос";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "first";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# from end";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "last";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "random";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "in list";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "невистина";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Дава или вистина или невистина.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "вистина";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://mk.wikipedia.org/wiki/Неравенство";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Дава вистина ако обата вноса се еднакви.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Дава вистина ако првиот внос е поголем од вториот.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Дава вистина ако првиот внос е поголем или еднаков на вториот.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Дава вистина ако првиот внос е помал од вториот.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Дава вистина ако првиот внос е помал или еднаков на  вториот.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Дава вистина ако обата вноса не се еднакви.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "не %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Дава вистина ако вносот е невистинит. Дава невистина ако вносот е вистинит.";
                +Blockly.Msg["LOGIC_NULL"] = "ништо";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Дава ништо.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "и";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "или";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Дава вистина ако обата вноса се вистинити.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Дава вистина ако барем еден од вносовите е вистинит.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "испробај";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ако е невистинито";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ако е вистинито";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter?uselang=mk";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "повиши %1 за %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Ѝ додава број на променливата „%1“.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://mk.wikipedia.org/wiki/Математичка_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Дава една од вообичаените константи: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), или ∞ (бесконечност).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "е делив со";
                +Blockly.Msg["MATH_IS_EVEN"] = "е парен";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "е негативен";
                +Blockly.Msg["MATH_IS_ODD"] = "е непарен";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "е позитивен";
                +Blockly.Msg["MATH_IS_PRIME"] = "е прост";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Проверува дали бројот е парен, непарен, прост, цел, позитивен, негативен или делив со некој број. Дава вистина или невистина.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "е цел";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";  // untranslated
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "просек на списокот";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "најголем на списокот";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "медијана на списокот";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "најмал на списокот";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "модул на списокот";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "збир од списокот";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Дава просек (аритметичка средина) од броевите на списокот.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Го дава најголемиот број на списокот.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Дава медијана од броевите на списокот.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Го дава најмалиот број на списокот.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Дава список на најзастапен(и) елемент(и) на списокот.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Дава збир од сите броеви на списокот.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://mk.wikipedia.org/wiki/Заокружување";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "заокружи";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "заокружи на помало";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "заокружи на поголемо";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Го заокружува бројот на поголем или помал.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "Нова променлива...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Назив на новата променлива:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Отстрани коментар";
                +Blockly.Msg["RENAME_VARIABLE"] = "Преименувај променлива...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Преименувај ги сите променливи „%1“ во:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Today";  // untranslated
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "елемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ms.js b/blockly/webif/static/blockly/msg/js/ms.js
                new file mode 100644
                index 000000000..41bd908e4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ms.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ms');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Berikan Komen";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ubah nilai:";
                +Blockly.Msg["CLEAN_UP"] = "Kemaskan Blok";
                +Blockly.Msg["COLLAPSE_ALL"] = "Lipat Blok²";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Lipat Blok";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "warna 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "warna 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "nisbah";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "adun";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Campurkan dua warna sekali pada nisbah yang ditentukan (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ms.wikipedia.org/wiki/Warna";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Pilih satu warna daripada palet.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "warna rawak";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Pilih satu warna secara rawak.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "biru";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "hijau";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "merah";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "warnakan";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Peroleh satu warna dengan menentukan amaun campuran merah, hijau dan biru. Kesemua nilai haruslah antara 0 hingga 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "hentikan gelung";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "teruskan dengan lelaran gelung seterusnya";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Keluar dari gelung pengandung.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Langkau seluruh gelung yang tinggal dan bersambung dengan lelaran seterusnya.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Amaran: Blok ini hanya boleh digunakan dalam satu gelung.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "untuk setiap perkara %1 dalam senarai %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Untuk setiap perkara dalam senarai, tetapkan pembolehubah '%1' pada perkara, kemudian lakukan beberapa perintah.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "kira dengan %1 dari %2 hingga %3 selang %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Gunakan pembolehubah '%1' pada nilai-nilai dari nombor pangkal hingga nombor hujung, mengira mengikut selang yang ditentukan, dan lakukan blok-blok yang tertentu.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Tambah satu syarat kepada blok jika.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Tambah yang terakhir, alihkan semua keadaan ke blok jika.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Tambah, alih keluar, atau susun semula bahagian-bahagian untuk menyusun semula blok jika.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "lain";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "lain jika";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "jika";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Jika nilai yang benar, lakukan beberapa penyata.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Jika suatu nilai benar, lakukan penyata blok pertama.  Jika tidak, bina penyata blok kedua.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Jika nilai yang pertama adalah benar, lakukan penyata pertama blok.  Sebaliknya, jika nilai kedua adalah benar, lakukan penyata blok kedua.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Jika nilai yang pertama adalah benar, lakukan penyata blok pertama.  Sebaliknya, jika nilai kedua adalah benar, lakukan penyata blok kedua.  Jika tiada nilai adalah benar, lakukan penyata blok terakhir.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "lakukan";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ulang %1 kali";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Lakukan perintah berulang kali.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ulangi sehingga";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ulangi apabila";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Lakukan beberapa perintah apabila nilainya palsu (false).";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Lakukan beberapa perintah apabila nilainya benar (true).";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Hapuskan kesemua %1 blok?";
                +Blockly.Msg["DELETE_BLOCK"] = "Hapuskan Blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Hapuskan %1 Blok";
                +Blockly.Msg["DISABLE_BLOCK"] = "Matikan Blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Pendua";
                +Blockly.Msg["ENABLE_BLOCK"] = "Hidupkan Blok";
                +Blockly.Msg["EXPAND_ALL"] = "Buka Blok²";
                +Blockly.Msg["EXPAND_BLOCK"] = "Buka Blok";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Input Luaran";
                +Blockly.Msg["HELP"] = "Bantuan";
                +Blockly.Msg["INLINE_INPUTS"] = "Input Sebaris";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "Wujudkan senarai kosong";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Kembalikan senarai panjang 0, yang tidak mengandungi rekod data";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "senarai";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Tambah, alih keluar, atau susun semula bahagian-bahagian untuk menyusun semula senarai blok.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "wujudkan senarai dengan";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Tambah item ke dalam senarai.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Wujudkan senarai dengan apa jua nombor item.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "pertama";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# dari akhir";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "dapatkan";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "dapat dan alihkan";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "terakhir";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "rawak";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "alihkan";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Kembalikan item pertama dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Kembalikan item dalam kedudukan yang ditetapkan dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Kembalikan item pertama dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Kembalikan item rawak dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Alihkan dan kembalikan item pertama dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Alihkan dan kembalikan item mengikut spesifikasi posisi dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Alihkan dan kembalikan item terakhir dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Alihkan dan kembalikan item rawak dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Alihkan item pertama dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Alihkan item pada posisi mengikut spesifikasi dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Alihkan item terakhir dalam senarai.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Alihkan item rawak dalam senarai.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ke  # dari akhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "ke #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "ke akhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "dapatkan sub-senarai daripada pertama";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "dapatkan sub-senarai daripada # daripada terakhir";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "dapatkan sub-senarai daripada #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Wujudkan salinan bahagian yang ditentukan dari senarai.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ialah item terakhir.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ialah item pertama.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "cari pertama item kejadian";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "cari kejadian akhir item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Menyatakan indeks kejadian pertama/terakhir item berkenaan dalam senarai. Menyatakan %1 jika item berkenaan tidak ditemui.";
                +Blockly.Msg["LISTS_INLIST"] = "dalam senarai";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 adalah kosong";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Kembalikan benar jika senarai kosong.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "panjang %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Kembalikan panjang senarai";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "wujudkan senarai dengan item %1 diulangi %2 kali";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Wujudkan senarai yang terdiri daripada nilai berulang mengikut nombor yang ditentukan.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "sebagai";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "masukkan pada";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Selit item pada permulaan senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Masukkan item pada posisi yand ditentukan dalam senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Tambahkan item dalam senarai akhir.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Selit item secara rawak di dalam senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Set item pertama dalam senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Masukkan item pada posisi yang ditentukan dalam senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Set item terakhir dalam senarai.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Set item rawak dalam senarai.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "buat senarai dgn teks";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "buat teks drpd senarai";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Cantumkan senarai teks menjadi satu teks, dipecahkan oleh delimiter.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Pecahkan teks kepada senarai teks, berpecah di setiap delimiter.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "dengan delimiter";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "palsu";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Kembalikan samada benar atau palsu.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "benar";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://id.wikipedia.org/wiki/Pertidaksamaan";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Kembali benar jika kedua-dua input benar antara satu sama lain.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Kembali benar jika input pertama adalah lebih besar daripada input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Kembali benar jika input pertama adalah lebih besar daripada atau sama dengan input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Kembali benar jika input pertama adalah lebih kecil daripada input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Kembali benar jika input pertama adalah lebih kecil daripada atau sama dengan input kedua.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Taip balik benar jika kedua-dua input tidak sama.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "bukan %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "'Benar' akan dibalas jika inputnya salah. 'Salah' akan dibalas jika inputnya benar.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "dan";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "atau";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "Jika palsu";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "Jika benar";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ms.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Kembalikan jumlah kedua-dua bilangan.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Taip balik hasil bahagi dua nombor tersebut.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Taip balik hasil tolak dua nombor tersebut.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Taip balik hasil darab dua nombor tersebut.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://id.wikipedia.org/wiki/Perjumlahan";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "perubahan %1 oleh %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Tambah nombor kepada pembolehubah '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ms.wikipedia.org/wiki/Pemalar_matematik";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "Boleh dibahagikan dengan";
                +Blockly.Msg["MATH_IS_EVEN"] = "Adalah genap";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "negatif";
                +Blockly.Msg["MATH_IS_ODD"] = "aneh";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "adalah positif";
                +Blockly.Msg["MATH_IS_PRIME"] = "is prime";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number.  Returns true or false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://id.wikipedia.org/wiki/Operasi_modulus";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Taip balik baki yang didapat daripada pembahagian dua nombor tersebut.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ms.wikipedia.org/wiki/Nombor";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Suatu nombor.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "purata daripada senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "Max senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Median senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min dalam senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "jenis senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Item rawak daripada senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "sisihan piawai bagi senarai";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Jumlah senarai";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Kembalikan purata (min aritmetik) nilai-nilai angka di dalam senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Pulangkan jumlah terbesar dalam senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Kembalikan nombor median dalam senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Kembalikan nombor terkecil dalam senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Kembali senarai item yang paling biasa dalam senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Kembalikan elemen rawak daripada senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Kembali dengan sisihan piawai daripada senarai.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Kembalikan jumlah semua nombor dalam senarai.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "pecahan rawak";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Kembali sebahagian kecil rawak antara 0.0 (inklusif) dan 1.0 (eksklusif).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "integer rawak dari %1ke %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Kembalikan integer rawak diantara dua had yang ditentukan, inklusif.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "pusingan";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "Pusingan ke bawah";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "pusingan ke atas";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Bulat nombor yang naik atau turun.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ms.wikipedia.org/wiki/Punca_kuasa_dua";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "mutlak";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "Punca kuasa dua";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Kembalikan nilai mutlak suatu nombor.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Kembalikan e kepada kuasa nombor.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Kembali dalam logaritma nombor asli.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Kembali logarithm 10 asas nombor.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Kembalikan nombor yang songsang.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Kembalikan 10 kepada kuasa nombor.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Kembalikan punca kuasa nombor.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ms.wikipedia.org/wiki/Fungsi_trigonometri";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Kembali arccosine beberapa nombor.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Kembalikan arcsince beberapa nombor.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Kembalikan beberapa nombor arctangent.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Kembalikan darjah kosinus (bukan radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Kembalikan darjah sine (bukan radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Kembalikan darjah tangen (bukan radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "Pembolehubah baru...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nama pembolehubah baru:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "bolehkan kenyataan";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "dengan:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ms.wikipedia.org/wiki/Fungsi";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ms.wikipedia.org/wiki/Fungsi";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "dengan:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Hasilkan '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Terangkan fungsi ini...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "Buat sesuatu";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "Untuk";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Menghasilkan suatu fungsi tanpa output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "kembali";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Mencipta satu fungsi dengan pengeluaran.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Amaran: Fungsi ini mempunyai parameter yang berganda.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Serlahkan definisi fungsi";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Amaran: Blok ini hanya boleh digunakan dalam fungsi definisi.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Nama input:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Tambah satu input pada fungsi.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "Input-input";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Tambah, alih keluar atau susun semula input pada fungsi ini.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Padamkan Komen";
                +Blockly.Msg["RENAME_VARIABLE"] = "Tukar nama pembolehubah...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Tukar nama semua pembolehubah '%1' kepada:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "Kepada huruf kecil";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "Kepada HURUF BESAR";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "Dapatkan abjad terakhir";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "Dapatkan abjad rawak";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "Sertai";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "untuk huruf terakhir";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "dalam teks";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "mencari kejadian pertama teks";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "mencari kejadian terakhir teks";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Kembalikan Indeks kejadian pertama/terakhir dari teks pertama ke dalam teks kedua.  Kembalikan %1 Jika teks tidak ditemui.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 adalah kosong";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Kembalikan benar jika teks yang disediakan adalah kosong.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "hasilkan teks dengan";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Hasilkan sebahagian teks dengan menghubungkan apa jua nombor item.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "panjang %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Kembalikan jumlah huruf (termasuk ruang) dalam teks yang disediakan.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "cetak %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Cetak teks yang ditentukan, nombor atau nilai lain.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Peringatan kepada pengguna untuk nombor.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Peringatkan pengguna untuk sebahagian teks.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Prom untuk nombor dengan mesej";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Prom untuk teks dengan mesej";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ms.wikipedia.org/wiki/Rentetan";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Huruf, perkataan, atau baris teks.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "mengurangkan kawasan dari kedua-dua belah";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "mengurangkan ruang dari sebelah kiri";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "mengurangkan kawasan dari sisi kanan";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Kembali salinan teks dengan ruang yang dikeluarkan daripada satu atau hujung kedua belah.";
                +Blockly.Msg["TODAY"] = "Hari ini";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "Perkara";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Hasilkan 'set %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Kembalikan nilai pemboleh ubah ini.";
                +Blockly.Msg["VARIABLES_SET"] = "set %1 ke %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Hasilkan 'set %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Set pembolehubah ini supaya sama dengan input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/nb.js b/blockly/webif/static/blockly/msg/js/nb.js
                new file mode 100644
                index 000000000..b7debbe85
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/nb.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.nb');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Legg til kommentar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Kan ikke slette variabelen «%1» fordi den er del av definisjonen for funksjonen «%2»";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Bytt verdi:";
                +Blockly.Msg["CLEAN_UP"] = "Rydd opp Blocks";
                +Blockly.Msg["COLLAPSE_ALL"] = "Skjul blokker";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Skjul blokk";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "farge 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "farge 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "forhold";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blande";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blander to farger sammen med et gitt forhold (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Velg en farge fra paletten.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "tilfeldig farge";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Velg en tilfeldig farge.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blå";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grønn";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rød";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "farge med";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Lag en farge med angitt verdi av rød, grønn og blå. Alle verdier må være mellom 0 og 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "bryt ut av løkken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "fortsett med neste gjentakelse av løkken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Bryt ut av den gjeldende løkken.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Hopp over resten av denne løkken og fortsett med neste gjentakelse.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Advarsel: Denne blokken kan kun brukes innenfor en løkke.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for hvert element %1 i listen %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For hvert element i en liste, angi variabelen '%1' til elementet, og deretter lag noen setninger.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "tell med %1 fra %2 til %3 med %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Ha variabel \"%1\" ta verdiene fra start nummer til slutt nummer, telle med spesifisert intervall og lag de spesifiserte blokkene.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Legg til en betingelse til hvis blokken.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Legg til hva som skal skje hvis de andre ikke slår til.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Legg til, fjern eller flytt seksjoner i denne hvis-blokken.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "ellers";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "ellers hvis";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "hvis";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Hvis dette er sant, så gjør følgende.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Hvis dette er sant, så utfør den første blokken av instruksjoner. Hvis ikke, utfør den andre blokken.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Hvis det første stemmer, så utfør den første blokken av instruksjoner. Ellers, hvis det andre stemmer, utfør den andre blokken av instruksjoner.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Hvis den første verdien er sann, så utfør den første blokken med setninger. Ellers, hvis den andre verdien er sann, så utfør den andre blokken med setninger. Hvis ingen av verdiene er sanne, så utfør den siste blokken med setninger.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "gjør";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "gjenta %1 ganger";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Gjenta noen instruksjoner flere ganger.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "gjenta til";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "gjenta mens";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Så lenge et utsagn ikke stemmer, gjør noen instruksjoner.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Så lenge et utsagn stemmer, utfør noen instruksjoner.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Slett alle %1 blokker?";
                +Blockly.Msg["DELETE_BLOCK"] = "Slett blokk";
                +Blockly.Msg["DELETE_VARIABLE"] = "Slett variabelen «%1»";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Slett %1 bruk av variabelen «%2»?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Slett %1 blokker";
                +Blockly.Msg["DISABLE_BLOCK"] = "Deaktiver blokk";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "duplikat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktiver blokk";
                +Blockly.Msg["EXPAND_ALL"] = "Utvid blokker";
                +Blockly.Msg["EXPAND_BLOCK"] = "Utvid blokk";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Eksterne kilder";
                +Blockly.Msg["HELP"] = "Hjelp";
                +Blockly.Msg["INLINE_INPUTS"] = "Interne kilder";
                +Blockly.Msg["IOS_CANCEL"] = "Avbryt";
                +Blockly.Msg["IOS_ERROR"] = "Feil";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Legg til parameter";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Tillat kommandoer";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Denne funksjonen har duplikatparametere.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "PARAMETERE";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Legg til";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Legg til variabel";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Slett";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Du kan ikke bruke et tomt variabelnavn.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Endre navn";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variabelnavn";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "opprett en tom liste";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returnerer en tom liste, altså med lengde 0";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Legg til, fjern eller endre rekkefølgen for å endre på denne delen av listen.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "lag en liste med";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Tilføy et element til listen.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Lag en liste med et vilkårlig antall elementer.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "først";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# fra slutten";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "hent";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "hent og fjern";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "siste";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "tilfeldig";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "fjern";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returnerer det første elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returner elementet på den angitte posisjonen i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returnerer det siste elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returnerer et tilfeldig element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Fjerner og returnerer det første elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Fjerner og returnerer elementet ved en gitt posisjon i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Fjerner og returnerer det siste elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Fjerner og returnerer et tilfeldig element i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Fjerner det første elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Fjerner et element ved en gitt posisjon i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Fjerner det siste elementet i en liste.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Fjerner et tilfeldig element i en liste.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "til # fra slutten";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "til #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "til siste";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "Hent en del av listen";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "Hent de siste # elementene";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "Hent del-listen fra #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Kopiérer en ønsket del av en liste.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 er det siste elementet.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 er det første elementet.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "finn første forekomst av elementet";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "finn siste forekomst av elementet";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returnerer indeksen av den første/siste forekomsten av elementet i lista. Returnerer %1 hvis ikke funnet.";
                +Blockly.Msg["LISTS_INLIST"] = "i listen";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 er tom";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returnerer sann hvis listen er tom.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "lengden på %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returnerer lengden til en liste.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Lag en liste hvor elementet %1 forekommer %2 ganger";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Lager en liste hvor den gitte verdien gjentas et antall ganger.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverser %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverser en kopi av ei liste.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "som";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "sett inn ved";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "sett";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Setter inn elementet i starten av en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Setter inn elementet ved den angitte posisjonen i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Tilføy elementet til slutten av en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Setter inn elementet ved en tilfeldig posisjon i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Angir det første elementet i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Setter inn elementet ved den angitte posisjonen i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Angir det siste elementet i en liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Angir et tilfeldig element i en liste.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "stigende";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "synkende";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sorter %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sorter en kopi av en liste.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetisk, ignorert store/små bokstaver";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerisk";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetisk";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "lag liste av tekst";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "lag tekst av liste";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Føy sammen en liste tekster til én tekst, avskilt av en avgrenser.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Splitt teksten til en liste med tekster, brutt ved hver avgrenser.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "med avgrenser";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "usann";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returnerer enten sann eller usann.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "sann";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Returnerer sann hvis begge inputene er like hverandre.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Returnerer sant hvis det første argumentet er større enn den andre argumentet.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Returnerer sant hvis det første argumentet er større enn eller likt det andre argumentet.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Returnerer sant hvis det første argumentet er mindre enn det andre argumentet.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Returnerer sant hvis det første argumentet er mindre enn eller likt det andre argumentet.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Returnerer sant hvis begge argumentene er ulike hverandre.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ikke %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returnerer sant hvis argumentet er usant. Returnerer usant hvis argumentet er sant.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returnerer null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "og";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "eller";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Returnerer sant hvis begge argumentene er sanne.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Returnerer sant hvis minst ett av argumentene er sant.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "hvis usant";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "hvis sant";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Sjekk betingelsen i 'test'. Hvis betingelsen er sann, da returneres 'hvis sant' verdien. Hvis ikke returneres 'hvis usant' verdien.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://no.wikipedia.org/wiki/Aritmetikk";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Returnerer summen av to tall.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Returner kvotienten av to tall.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Returner differansen mellom to tall.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Returner produktet av to tall.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Returner det første tallet opphøyd i den andre tallet.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "endre %1 ved %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Addere et tall til variabelen '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Returner en av felleskonstantene π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), eller ∞ (uendelig).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "begrense %1 lav %2 høy %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Begrens et tall til å være mellom de angitte grenseverdiene (inklusiv).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "er delelig med";
                +Blockly.Msg["MATH_IS_EVEN"] = "er et partall";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "er negativer negativt";
                +Blockly.Msg["MATH_IS_ODD"] = "er et oddetall";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "er positivt";
                +Blockly.Msg["MATH_IS_PRIME"] = "er et primtall";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Sjekk om et tall er et partall, oddetall, primtall, heltall, positivt, negativt, eller om det er delelig med et annet tall. Returnerer sant eller usant.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "er et heltall";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resten av %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Returner resten fra delingen av to tall.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "x";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Et tall.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "gjennomsnittet av listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maksimum av liste";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "medianen til listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimum av listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "Listens typetall";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "tilfeldig element i listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standardavviket til listen";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summen av listen";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Returner det aritmetiske gjennomsnittet av tallene i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Returner det største tallet i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Returner listens median.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Returner det minste tallet i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Returner en liste av de vanligste elementene i listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Returner et tilfeldig element fra listen.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Returner listens standardavvik.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Returner summen av alle tallene i listen.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "tilfeldig flyttall";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Returner et tilfeldig flyttall mellom 0.0 (inkludert) og 1.0 (ikke inkludert).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "Et tilfeldig heltall mellom %1 og %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Returner et tilfeldig tall mellom de to spesifiserte grensene, inkludert de to.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "avrunding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "rund ned";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "rund opp";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Avrund et tall ned eller opp.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluttverdi";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadratrot";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Returner absoluttverdien av et tall.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Returner e opphøyd i et tall.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Returner den naturlige logaritmen til et tall.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Returner base-10 logaritmen til et tall.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Returner det negative tallet.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Returner 10 opphøyd i et tall.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Returner kvadratroten av et tall.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Returner arccosinus til et tall.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Returner arcsinus til et tall.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Returner arctangens til et tall.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Returner cosinus av en vinkel (ikke radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Returner sinus av en vinkel (ikke radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Returner tangenten av en vinkel (ikke radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "Opprett variabel...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nytt variabelnavn:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "tillat uttalelser";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Kjør den brukerdefinerte funksjonen '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Kjør den brukerdefinerte funksjonen'%1' og bruk resultatet av den.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Opprett '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Beskriv denne funksjonen...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "gjør noe";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "til";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Opprett en funksjon som ikke har noe resultat.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "returner";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Oppretter en funksjon som har et resultat.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Advarsel: Denne funksjonen har duplikate parametere.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Marker funksjonsdefinisjonen";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Hvis en verdi er sann, returner da en annen verdi.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Advarsel: Denne blokken kan bare benyttes innenfor en funksjonsdefinisjon.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Navn på parameter:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Legg til en input til funksjonen.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "parametere";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Legg til, fjern eller endre rekkefølgen på input til denne funksjonen.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Gjør om";
                +Blockly.Msg["REMOVE_COMMENT"] = "Fjern kommentar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Gi nytt navn til variabel...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Endre navnet til alle '%1' variabler til:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Tilføy tekst til variabelen '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "til små bokstaver";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "til store forbokstaver";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "til STORE BOKSTAVER";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Returnerer en kopi av teksten der store og små bokstaver er byttet om.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "hent første bokstav";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "hent bokstav # fra slutten";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "hent bokstav #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "hent den siste bokstaven";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "hent en tilfeldig bokstav";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returnerer bokstaven på angitt plassering.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "tell %1 i %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Tell hvor mange ganger noe tekst dukker opp i annen tekst.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Legg til et element til teksten.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "føy sammen";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Legg til, fjern eller forandre rekkefølgen for å forandre på denne tekstblokken.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "til bokstav # fra slutten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "til bokstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "til siste bokstav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "i tekst";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "hent delstreng fra første bokstav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "hent delstreng fra bokstav # fra slutten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "hent delstreng fra bokstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returnerer den angitte delen av teksten.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "finn første forekomst av tekst";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "finn siste forekomst av tekst";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returnerer posisjonen for første/siste forekomsten av den første tekst i den andre teksten.  Returnerer %1 hvis teksten ikke blir funnet.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 er tom";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returnerer sann hvis den angitte teksten er tom.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "lage tekst med";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Opprett en tekst ved å sette sammen et antall elementer.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "lengden av %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returnerer antall bokstaver (inkludert mellomrom) i den angitte teksten.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "skriv ut %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Skriv ut angitt tekst, tall eller annet innhold.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Be brukeren om et tall.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Spør brukeren om tekst.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "spør om et tall med en melding";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "spør om tekst med en melding";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "erstatt %1 med %2 i %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Erstatter alle forekomster av noe tekst i en annen tekst.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverser %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverserer rekkefølgen på tegnene i teksten.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "En bokstav, ett ord eller en linje med tekst.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "fjern mellomrom fra begge sider av";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "fjern mellomrom fra venstre side av";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "fjern mellomrom fra høyre side av";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Returner en kopi av teksten med mellomrom fjernet fra en eller begge sidene.";
                +Blockly.Msg["TODAY"] = "I dag";
                +Blockly.Msg["UNDO"] = "Angre";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Opprett 'sett %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returnerer verdien av denne variabelen.";
                +Blockly.Msg["VARIABLES_SET"] = "sett %1 til %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Opprett 'hent %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Setter verdien av denne variablen lik parameteren.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "En variabel med navn «%1» finnes allerede.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/nl.js b/blockly/webif/static/blockly/msg/js/nl.js
                new file mode 100644
                index 000000000..08a2cada8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/nl.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.nl');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Reactie toevoegen";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "De variabele \"%1\" kan niet verwijderd worden omdat die onderdeel uitmaakt van de definitie van de functie \"%2\"";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Waarde wijzigen:";
                +Blockly.Msg["CLEAN_UP"] = "Blokken opschonen";
                +Blockly.Msg["COLLAPSE_ALL"] = "Blokken samenvouwen";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Blok samenvouwen";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "kleur 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "kleur 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "verhouding";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mengen";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Mengt twee kleuren samen met een bepaalde verhouding (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://nl.wikipedia.org/wiki/Kleur";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Kies een kleur in het palet.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "willekeurige kleur";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Kies een willekeurige kleur.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blauw";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "groen";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rood";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "kleuren met";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Maak een kleur met de opgegeven hoeveelheid rood, groen en blauw.  Alle waarden moeten tussen 0 en 100 liggen.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "uit lus breken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "doorgaan met de volgende iteratie van de lus";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "uit de bovenliggende lus breken";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "De rest van deze lus overslaan en doorgaan met de volgende herhaling.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Waarschuwing: dit blok mag alleen gebruikt worden in een lus.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "voor ieder item %1 in lijst %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Voor ieder item in een lijst, stel de variabele \"%1\" in op het item en voer daarna opdrachten uit.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "rekenen met %1 van %2 tot %3 in stappen van %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Laat de variabele \"%1\" de waarden aannemen van het beginnummer tot het laatste nummer, tellende met het opgegeven interval, en met uitvoering van de opgegeven blokken.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Voeg een voorwaarde toe aan het als-blok.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Voeg een laatste, vang-alles conditie toe aan het als-statement.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Voeg stukken toe, verwijder of wijzig de volgorde om dit \"als\"-blok te wijzigen.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "anders";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "anders als";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "als";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Als een waarde waar is, voer dan opdrachten uit.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Als een waarde waar is, voert dan het eerste blok met opdrachten uit. Voer andere het tweede blok met opdrachten uit.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Als de eerste waarde waar is, voer dan het eerste blok met opdrachten uit. Voer anders, als de tweede waarde waar is, het tweede blok met opdrachten uit.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Als de eerste waarde \"waar\" is, voer dan het eerste blok uit. Voer anders wanneer de tweede waarde \"waar\" is, het tweede blok uit. Als geen van beide waarden waar zijn, voer dan het laatste blok uit.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://nl.wikipedia.org/wiki/Repetitie_(informatica)#For_en_Foreach";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "voer uit";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 keer herhalen";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Voer een aantal opdrachten meerdere keren uit.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "herhalen totdat";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "herhalen zolang";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Terwijl een waarde onwaar is de volgende opdrachten uitvoeren.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Terwijl een waarde waar is de volgende opdrachten uitvoeren.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Alle %1 blokken verwijderen?";
                +Blockly.Msg["DELETE_BLOCK"] = "Blok verwijderen";
                +Blockly.Msg["DELETE_VARIABLE"] = "Verwijder de variabele \"%1\"";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "%1 gebruiken van de variabele \"%2\" verwijderen?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 blokken verwijderen";
                +Blockly.Msg["DISABLE_BLOCK"] = "Blok uitschakelen";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicaat";
                +Blockly.Msg["ENABLE_BLOCK"] = "Blok inschakelen";
                +Blockly.Msg["EXPAND_ALL"] = "Blokken uitvouwen";
                +Blockly.Msg["EXPAND_BLOCK"] = "Blok uitvouwen";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Externe invoer";
                +Blockly.Msg["HELP"] = "Hulp";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline invoer";
                +Blockly.Msg["IOS_CANCEL"] = "Annuleren";
                +Blockly.Msg["IOS_ERROR"] = "Fout";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Invoer toevoegen";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Statements toestaan";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Deze functie heeft dubbele invoeren.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INVOER";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Toevoegen";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Variabele toevoegen";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Verwijderen";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "U kunt geen lege variabelenaam gebruiken.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Hernoemen";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variabelenaam";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "maak een lege lijst";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Geeft een lijst terug met lengte 0, zonder items";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lijst";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Voeg stukken toe, verwijder ze of wijzig de volgorde om dit lijstblok aan te passen.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "maak een lijst met";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Voeg iets toe aan de lijst.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Maak een lijst met een willekeurig aantal items.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "eerste";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# van einde";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "haal op";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "haal op en verwijder";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "laatste";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "willekeurig";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "verwijder";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Geeft het eerste item in een lijst terug.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Geeft het item op de opgegeven positie in een lijst.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Geeft het laatste item in een lijst terug.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Geeft een willekeurig item uit een lijst.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Geeft het laatste item in een lijst terug en verwijdert het.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Geeft het item op de opgegeven positie in een lijst terug en verwijdert het.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Geeft het laatste item uit een lijst terug en verwijdert het.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Geeft een willekeurig item in een lijst terug en verwijdert het.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Verwijdert het eerste item in een lijst.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Verwijdert het item op de opgegeven positie in een lijst.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Verwijdert het laatste item uit een lijst.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Verwijdert een willekeurig item uit een lijst.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "naar # vanaf einde";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "naar item";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "naar laatste";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "haal sublijst op vanaf eerste";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "haal sublijst op van positie vanaf einde";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "haal sublijst op vanaf positie";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Maakt een kopie van het opgegeven deel van de lijst.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Item %1 is het laatste item.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Item %1 is het eerste item.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "zoek eerste voorkomen van item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "zoek laatste voorkomen van item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Geeft de index terug van het eerste of laatste voorkomen van een item in de lijst. Geeft %1 terug als het item niet is gevonden.";
                +Blockly.Msg["LISTS_INLIST"] = "in lijst";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is leeg";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Geeft waar terug als de lijst leeg is.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "lengte van %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Geeft de lengte van een lijst terug.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Maak lijst met item %1, %2 keer herhaald";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Maakt een lijst die bestaat uit de opgegeven waarde, het opgegeven aantal keer herhaald.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "%1 omkeren";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Keert een kopie van een lijst om.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "als";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "tussenvoegen op";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "stel in";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Voegt het item toe aan het begin van de lijst.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Voegt het item op een opgegeven positie in een lijst in.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Voeg het item aan het einde van een lijst toe.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Voegt het item op een willekeurige positie in de lijst in.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Stelt het eerste item in een lijst in.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Zet het item op de opgegeven positie in de lijst.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Stelt het laatste item van een lijst in.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Stelt een willekeurig item uit de lijst in.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "oplopend";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "aflopend";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sorteer %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sorteer een kopie van een lijst.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetisch, negeer hoofd-/kleine letters";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeriek";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetisch";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "lijst maken van tekst";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "tekst maken van lijst";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Lijst van tekstdelen samenvoegen in één stuk tekst, waarbij de tekstdelen gescheiden zijn door een scheidingsteken.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Tekst splitsen in een lijst van teksten op basis van een scheidingsteken.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "met scheidingsteken";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "onwaar";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Geeft \"waar\" of \"onwaar\" terug.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "waar";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://nl.wikipedia.org/wiki/Ongelijkheid_(wiskunde)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Geeft \"waar\", als beide waarden gelijk aan elkaar zijn.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Geeft \"waar\" terug als de eerste invoer meer is dan de tweede invoer.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Geeft \"waar\" terug als de eerste invoer groter is of gelijk aan de tweede invoer.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Geeft \"waar\" als de eerste invoer kleiner is dan de tweede invoer.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Geeft \"waar\" terug als de eerste invoer kleiner of gelijk is aan de tweede invoer.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Geeft \"waar\" terug als de waarden niet gelijk zijn aan elkaar.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "niet %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Geeft \"waar\" terug als de invoer \"onwaar\" is. Geeft \"onwaar\" als de invoer \"waar\" is.";
                +Blockly.Msg["LOGIC_NULL"] = "niets";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Geeft niets terug.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "en";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "of";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Geeft waar als beide waarden waar zijn.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Geeft \"waar\" terug als in ieder geval één van de waarden waar is.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "als onwaar";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "als waar";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Test de voorwaarde in \"test\". Als de voorwaarde \"waar\" is, geef de waarde van \"als waar\" terug; geef anders de waarde van \"als onwaar\" terug.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://nl.wikipedia.org/wiki/Rekenen";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Geeft de som van 2 getallen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Geeft de gedeelde waarde van twee getallen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Geeft het verschil van de twee getallen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Geeft het product terug van de twee getallen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Geeft het eerste getal tot de macht van het tweede getal.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%1 wijzigen met %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Voegt een getal toe aan variabele \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://nl.wikipedia.org/wiki/Wiskundige_constante";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Geeft een van de vaak voorkomende constante waardes:  π (3.141…), e (2.718…), φ (1.618…), √2 (1.414…), √½ (0.707…), of ∞ (oneindig).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "beperk %1 van minimaal %2 tot maximaal %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Beperk een getal tussen de twee opgegeven limieten (inclusief).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is deelbaar door";
                +Blockly.Msg["MATH_IS_EVEN"] = "is even";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "is negatief";
                +Blockly.Msg["MATH_IS_ODD"] = "is oneven";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "is positief";
                +Blockly.Msg["MATH_IS_PRIME"] = "is priemgetal";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Test of een getal even, oneven, een priemgetal, geheel, positief of negatief is, of deelbaar is door een bepaald getal. Geeft \"waar\" of \"onwaar\".";
                +Blockly.Msg["MATH_IS_WHOLE"] = "is geheel getal";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://nl.wikipedia.org/wiki/Modulair_rekenen";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "restgetal van %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Geeft het restgetal van het resultaat van de deling van de twee getallen.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://nl.wikipedia.org/wiki/Getal_%28wiskunde%29";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Een getal.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "gemiddelde van lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "hoogste uit lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediaan van lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "laagste uit lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modi van lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "willekeurige item van lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standaarddeviatie van lijst";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "som van lijst";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Geeft het gemiddelde terug van de numerieke waardes in een lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Geeft het grootste getal in een lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Geeft de mediaan in de lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Geeft het kleinste getal uit een lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Geeft een lijst van de meest voorkomende onderdelen in de lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Geeft een willekeurig item uit de lijst terug.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Geeft de standaardafwijking van de lijst.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Geeft de som van alle getallen in de lijst.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://nl.wikipedia.org/wiki/Toevalsgenerator";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "willekeurige fractie";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Geeft een willekeurige fractie tussen 0.0 (inclusief) en 1.0 (exclusief).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://nl.wikipedia.org/wiki/Toevalsgenerator";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "willekeurig geheel getal van %1 tot %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Geeft een willekeurig getal tussen de 2 opgegeven limieten in, inclusief.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://nl.wikipedia.org/wiki/Afronden";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "afronden";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "naar beneden afronden";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "omhoog afronden";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Rondt een getal af omhoog of naar beneden.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://nl.wikipedia.org/wiki/Vierkantswortel";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "wortel";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Geeft de absolute waarde van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Geeft e tot de macht van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Geeft het natuurlijk logaritme van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Geeft het logaritme basis 10 van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Geeft de negatief van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Geeft 10 tot de macht van een getal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Geeft de wortel van een getal.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://nl.wikipedia.org/wiki/Goniometrische_functie";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Geeft de arccosinus van een getal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Geeft de arcsinus van een getal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Geeft de arctangens van een getal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Geeft de cosinus van een graad (geen radialen).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Geeft de sinus van een graad (geen radialen).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Geeft de tangens van een graad (geen radialen).";
                +Blockly.Msg["NEW_VARIABLE"] = "Variabele maken...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nieuwe variabelenaam:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "statements toestaan";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "met:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://nl.wikipedia.org/wiki/Subprogramma";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Voer de door de gebruiker gedefinieerde functie \"%1\" uit.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://nl.wikipedia.org/wiki/Subprogramma";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Voer de door de gebruiker gedefinieerde functie \"%1\" uit en gebruik de uitvoer.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "met:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Maak \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Deze functie beschrijven...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://nl.wikipedia.org/wiki/Subprogramma";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "doe iets";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "om";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Maakt een functie zonder uitvoer.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://nl.wikipedia.org/wiki/Subprogramma";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "uitvoeren";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Maakt een functie met een uitvoer.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Waarschuwing: deze functie heeft parameters met dezelfde naam.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Accentueer functiedefinitie";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Als de eerste waarde \"waar\" is, geef dan de tweede waarde terug.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Waarschuwing: dit blok mag alleen gebruikt worden binnen de definitie van een functie.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "invoernaam:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Een invoer aan de functie toevoegen.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ingangen";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Invoer van deze functie toevoegen, verwijderen of herordenen.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Er bestaat al een variabele met de naam \"%1\".";
                +Blockly.Msg["REDO"] = "Opnieuw";
                +Blockly.Msg["REMOVE_COMMENT"] = "Opmerking verwijderen";
                +Blockly.Msg["RENAME_VARIABLE"] = "Variabele hernoemen...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Alle variabelen \"%1\" hernoemen naar:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "voor%1 voeg tekst toe van %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Voeg tekst toe aan de variabele \"%1\".";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "naar kleine letters";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "naar Hoofdletter Per Woord";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "naar HOOFDLETTERS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Geef een kopie van de tekst met veranderde hoofdletters terug.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "haal eerste letter op";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "haal letter # op vanaf einde";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "haal letter # op";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "haal laatste letter op";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "haal willekeurige letter op";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in tekst %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Geeft de letter op de opgegeven positie terug.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "%1 in %2 tellen";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Tel hoe vaak bepaalde tekst voorkomt in andere tekst.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Voegt een item aan de tekst toe.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "samenvoegen";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Toevoegen, verwijderen of volgorde wijzigen van secties om dit tekstblok opnieuw in te stellen.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "van letter # tot einde";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "naar letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "naar laatste letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in tekst";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "haal subtekst op van eerste letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "haal subtekst op vanaf letter # vanaf einde";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "haal subtekst op vanaf letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Geeft het opgegeven onderdeel van de tekst terug.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "zoek eerste voorkomen van tekst";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "zoek het laatste voorkomen van tekst";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in tekst %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Geeft de index terug van het eerste of laatste voorkomen van de eerste tekst in de tweede tekst. Geeft %1 terug als de tekst niet gevonden is.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is leeg";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Geeft \"waar\" terug, als de opgegeven tekst leeg is.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "maak tekst met";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Maakt een stuk tekst door één of meer items samen te voegen.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "lengte van %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Geeft het aantal tekens terug (inclusief spaties) in de opgegeven tekst.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "tekst weergeven: %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Drukt de opgegeven tekst, getal of een andere waarde af.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Vraagt de gebruiker om een getal in te voeren.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Vraagt de gebruiker om invoer.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "vraagt de gebruiker om een getal met de tekst";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "vraagt om invoer met bericht";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "vervang %1 door %2 in %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Vervang alle voorkomens van tekst in een andere tekst.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "%1 omkeren";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Keert de volgorde van de tekens in de tekst om.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://nl.wikipedia.org/wiki/String_%28informatica%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Een letter, woord of een regel tekst.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "spaties van beide kanten afhalen van";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "spaties van de linkerkant verwijderen van";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "spaties van de rechterkant verwijderen van";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Geeft een kopie van de tekst met verwijderde spaties van één of beide kanten.";
                +Blockly.Msg["TODAY"] = "Vandaag";
                +Blockly.Msg["UNDO"] = "Ongedaan maken";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Maak \"verander %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Geeft de waarde van deze variabele.";
                +Blockly.Msg["VARIABLES_SET"] = "stel %1 in op %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Maak 'opvragen van %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Verandert de waarde van de variabele naar de waarde van de invoer.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Er bestaat al een variabele met de naam \"%1\".";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/oc.js b/blockly/webif/static/blockly/msg/js/oc.js
                new file mode 100644
                index 000000000..d114f67ff
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/oc.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.oc');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Apondre un comentari";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Modificar la valor :";
                +Blockly.Msg["CLEAN_UP"] = "Netejar los blòts";
                +Blockly.Msg["COLLAPSE_ALL"] = "Redusir los blòts";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Redusir lo blòt";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "color 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "color 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ratio";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mesclar";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://oc.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choose a colour from the palette.";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "color aleatòria";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Causir una color a l'azard.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blau";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verd";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "roge";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "coloriar amb";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "per cada element %1 dins la lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "comptar amb %1 de %2 a %3 per %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "siquenon";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "siquenon se";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://oc.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "far";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repetir %1 còps";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repetir fins a";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repetir tant que";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Suprimir totes los %1 blòts ?";
                +Blockly.Msg["DELETE_BLOCK"] = "Suprimir lo blòt";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Suprimir %1 blòts";
                +Blockly.Msg["DISABLE_BLOCK"] = "Desactivar lo blòt";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicar";
                +Blockly.Msg["ENABLE_BLOCK"] = "Activar lo blòt";
                +Blockly.Msg["EXPAND_ALL"] = "Desvolopar los blòts";
                +Blockly.Msg["EXPAND_BLOCK"] = "Desvolopar lo blòt";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entradas extèrnas";
                +Blockly.Msg["HELP"] = "Ajuda";
                +Blockly.Msg["INLINE_INPUTS"] = "Entradas en linha";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "crear una lista amb";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primièr";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# dempuèi la fin";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obténer";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obténer e suprimir";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "darrièr";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleatòri";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "suprimit";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "fins a # dempuèi la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "fins a #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "fins a la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "dins la lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "coma";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserir en";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "metre";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "creissent";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descreissent";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetic";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "amb lo separador";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "fals";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returns either true or false.";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "verai";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Renviar verai se las doas entradas son egalas.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Renviar verai se las doas entradas son diferentas.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "pas %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "nul";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Renvia nul.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Renviar verai se las doas entradas son vertadièras.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "tèst";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se fals";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se verai";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://oc.wikipedia.org/wiki/Aritmetica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "incrementar %1 per %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "es devesible per";
                +Blockly.Msg["MATH_IS_EVEN"] = "es par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "es negatiu";
                +Blockly.Msg["MATH_IS_ODD"] = "es impar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "es positiu";
                +Blockly.Msg["MATH_IS_PRIME"] = "es primièr";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "es entièr";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://oc.wikipedia.org/wiki/Nombre";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un nombre.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "mejana de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maximum de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimum de la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "soma de la lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arredondir";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arredondir a l’inferior";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arredondir al superior";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "raiç carrada";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "Crear una variabla...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nom de la novèla variabla :";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "amb :";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "amb :";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Crear '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "far quicòm";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "a";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retorn";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nom de l’entrada :";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entradas";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Refar";
                +Blockly.Msg["REMOVE_COMMENT"] = "Suprimir un comentari";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renomenar la variabla…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renomenar totas las variablas « %1 » a :";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "en minusculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "en MAJUSCULAS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obténer la primièra letra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obténer la letra # dempuèi la fin";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obténer la letra #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obténer la darrièra letra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obténer una letra a l'azard";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Renvia la letra a la posicion indicada.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "jónher";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "fins a la letra #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "dins lo tèxte";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 es void";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longor de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "afichar %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "Uèi";
                +Blockly.Msg["UNDO"] = "Anullar";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crear 'fixar %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "fixar %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/pl.js b/blockly/webif/static/blockly/msg/js/pl.js
                new file mode 100644
                index 000000000..328e094a3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/pl.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.pl');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Dodaj komentarz";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Zmień wartość:";
                +Blockly.Msg["CLEAN_UP"] = "Uporządkuj bloki";
                +Blockly.Msg["COLLAPSE_ALL"] = "Zwiń bloki";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Zwiń blok";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "kolor 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "kolor 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporcja";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "wymieszaj";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Miesza dwa kolory w danej proporcji (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Wybierz kolor z palety.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "losowy kolor";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Wybierz kolor w sposób losowy.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "niebieski";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zielony";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "czerwony";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "kolor z";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Połącz czerwony, zielony i niebieski w odpowiednich proporcjach, tak aby powstał nowy kolor. Zawartość każdego z nich określa liczba z przedziału od 0 do 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "wyjdź z pętli";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "przejdź do kolejnej iteracji pętli";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Wyjdź z zawierającej pętli.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Pomiń resztę pętli i kontynuuj w kolejnej iteracji.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Uwaga: Ten blok może być użyty tylko w pętli.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "dla każdego elementu %1 na liście %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Dla każdego elementu listy ustaw zmienną %1 na ten element, a następnie wykonaj kilka instrukcji.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "licz z %1 od %2 do %3 co %4 (wartość kroku)";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Przypisuje zmiennej %1 wartości od numeru startowego do numeru końcowego, licząc co określony interwał, wykonując określone bloki.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Dodaj warunek do bloku „jeśli”.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Dodaj ostatni warunek do bloku „jeśli”, gdy żaden wcześniejszy nie był spełniony.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Dodaj, usuń lub zmień kolejność bloków, żeby zmodyfikować ten blok „jeśli”.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "w przeciwnym razie";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "w przeciwnym razie, jeśli";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "jeśli";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Jeśli wartość jest prawdziwa, to wykonaj kilka instrukcji.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Jeśli wartość jest prawdziwa, to wykonaj pierwszy blok instrukcji.  W przeciwnym razie, wykonaj drugi blok instrukcji.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Jeśli pierwsza wartość jest prawdziwa, to wykonaj pierwszy blok instrukcji.  W przeciwnym razie, jeśli druga wartość jest prawdziwa, to wykonaj drugi blok instrukcji.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Jeśli pierwsza wartość jest prawdziwa, wykonaj pierwszy blok instrukcji.  W przeciwnym razie jeśli druga wartość jest prawdziwa, wykonaj drugi blok instrukcji.  Jeżeli żadna z wartości nie jest prawdziwa, wykonaj ostatni blok instrukcji.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "wykonaj";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "powtórz %1 razy";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Wykonaj niektóre instrukcje kilka razy.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "powtarzaj aż";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "powtarzaj dopóki";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Gdy wartość jest nieprawdziwa, wykonaj kilka instrukcji.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Gdy wartość jest prawdziwa, wykonaj kilka instrukcji.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Usunąć wszystkie %1 bloki(ów)?";
                +Blockly.Msg["DELETE_BLOCK"] = "Usuń blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Usuń %1 bloki(ów)";
                +Blockly.Msg["DISABLE_BLOCK"] = "Wyłącz blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Powiel";
                +Blockly.Msg["ENABLE_BLOCK"] = "Włącz blok";
                +Blockly.Msg["EXPAND_ALL"] = "Rozwiń bloki";
                +Blockly.Msg["EXPAND_BLOCK"] = "Rozwiń blok";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Zewnętrzne wejścia";
                +Blockly.Msg["HELP"] = "Pomoc";
                +Blockly.Msg["INLINE_INPUTS"] = "Wbudowane wejścia";
                +Blockly.Msg["IOS_CANCEL"] = "Anuluj";
                +Blockly.Msg["IOS_ERROR"] = "Błąd";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Dodaj wejście";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "WEJŚCIA";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Dodaj";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Skasuj";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Zmień nazwę";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "utwórz pustą listę";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Zwraca listę, o długości 0, nie zawierającą rekordów z danymi";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Dodaj, usuń lub zmień kolejność sekcji żeby skonfigurować ten blok listy.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "Tworzenie listy z";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Dodaj element do listy.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Utwórz listę z dowolną ilością elementów.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "pierwszy";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# od końca";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "pobierz";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "Pobierz i usuń";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ostatni";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "losowy";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "usuń";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Zwraca pierwszy element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Zwraca element z konkretnej pozycji na liście.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Zwraca ostatni element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Zwraca losowy element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Usuwa i zwraca pierwszy element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Usuwa i zwraca element z określonej pozycji na liście.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Usuwa i zwraca ostatni element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Usuwa i zwraca losowy element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Usuwa pierwszy element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Usuwa element z określonej pozycji na liście.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Usuwa ostatni element z listy.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Usuwa losowy element z listy.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "do # od końca";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "do #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "do ostatniego";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "Pobierz listę podrzędną z pierwszego";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "Pobierz listę podrzędną z # od końca";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "Pobierz listę podrzędną z #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Tworzy kopię z określoną część listy.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 to ostatni element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 to pierwszy element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "znaleźć pierwsze wystąpienie elementu";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "znajduje ostatanie wystąpienie elementu";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Zwraca indeks pierwszego/ostatniego wystąpienia elementu na liście. Zwraca wartość %1, jeśli tekst nie zostanie znaleziony.";
                +Blockly.Msg["LISTS_INLIST"] = "na liście";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 jest pusty";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Zwraca \"prawda\" jeśli lista jest pusta.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "długość %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Zwraca długość listy.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "stwórz listę, powtarzając element %1 %2 razy";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Tworzy listę składającą się z podanej wartości powtórzonej odpowiednią liczbę razy.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "odwróć %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "jako";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "wstaw w";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "ustaw";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Wstawia element na początku listy.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Wstawia element w odpowiednim miejscu na liście.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Dodaj element na koniec listy.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Wstawia element w losowym miejscu na liście.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Ustawia pierwszy element na liście.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Ustawia element w określonym miejscu na liście.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Ustawia ostatni element na liście.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Ustawia losowy element na liście.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "rosnąco";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "malejąco";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sortuj %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sortuj kopię listy.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetycznie, bez uwzględniania wielkości liter";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerycznie";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetycznie";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "stwórz listę z tekstu";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "stwórz tekst z listy";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Łączy listę tekstów w jeden tekst, rozdzielany separatorem.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Rozdziela tekst na listę mniejszych tekstów, dzieląc na każdym separatorze.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "z separatorem";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "fałsz";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Zwraca 'prawda' lub 'fałsz'.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "prawda";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://pl.wikipedia.org/wiki/Nierówność";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Zwróć \"prawda\", jeśli oba wejścia są sobie równe.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Zwróć \"prawda\" jeśli pierwsze wejście jest większe od drugiego.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Zwróć \"prawda\", jeśli pierwsze wejście jest większe lub równe drugiemu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Zwróć \"prawda\" jeśli pierwsze wejście jest mniejsze od drugiego.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Zwróć \"prawda\", jeśli pierwsze wejście jest mniejsze lub równe drugiemu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Zwróć \"prawda\", jeśli oba wejścia są sobie nierówne.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nie %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Zwraca \"prawda\", jeśli dane wejściowe są fałszywe.  Zwraca \"fałsz\", jeśli dana wejściowa jest prawdziwa.";
                +Blockly.Msg["LOGIC_NULL"] = "nic";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Zwraca nic.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "i";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "lub";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Zwróć \"prawda\" jeśli oba dane elementy mają wartość \"prawda\".";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Zwróć \"prawda\" jeśli co najmniej jeden dany element ma wartość \"prawda\".";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "jeśli fałsz";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "jeśli prawda";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Sprawdź warunek w „test”. Jeśli warunek jest prawdziwy, to zwróci „jeśli prawda”; jeśli nie jest prawdziwy to zwróci „jeśli fałsz”.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://pl.wikipedia.org/wiki/Arytmetyka";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Zwróć sumę dwóch liczb.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Zwróć iloraz dwóch liczb.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Zwróć różnicę dwóch liczb.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Zwróć iloczyn dwóch liczb.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Zwróć pierwszą liczbę podniesioną do potęgi o wykładniku drugiej liczby.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "zmień %1 o %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Dodaj liczbę do zmiennej '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://pl.wikipedia.org/wiki/Stała_(matematyka)";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Zwróć jedną wspólną stałą: π (3.141), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) lub ∞ (nieskończoność).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "ogranicz %1 z dołu %2 z góry %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Ogranicz liczbę, aby była w określonych granicach (włącznie).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "/";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "jest podzielna przez";
                +Blockly.Msg["MATH_IS_EVEN"] = "jest parzysta";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "jest ujemna";
                +Blockly.Msg["MATH_IS_ODD"] = "jest nieparzysta";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "jest dodatnia";
                +Blockly.Msg["MATH_IS_PRIME"] = "jest liczbą pierwszą";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Sprawdź, czy liczba jest parzysta, nieparzysta, pierwsza, całkowita, dodatnia, ujemna, lub czy jest podzielna przez podaną liczbę. Zwraca wartość \"prawda\" lub \"fałsz\".";
                +Blockly.Msg["MATH_IS_WHOLE"] = "jest liczbą całkowitą";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://pl.wikipedia.org/wiki/Modulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "reszta z dzielenia %1 przez %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Zwróć resztę z dzielenia dwóch liczb przez siebie.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Liczba.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "średnia elementów listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maksymalna wartość z listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimalna wartość z listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "dominanty listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "losowy element z listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "odchylenie standardowe listy";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma elementów listy";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Zwróć średnią (średnią arytmetyczną) wartości liczbowych z listy.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Zwróć największą liczbę w liście.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Zwróć medianę listy.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Zwróć najmniejszą liczbę w liście.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Zwróć listę najczęściej występujących elementów w liście.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Zwróć losowy element z listy.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Zwróć odchylenie standardowe listy.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Zwróć sumę wszystkich liczb z listy.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "losowy ułamek";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Zwróć losowy ułamek między 0.0 (włącznie), a 1.0 (wyłącznie).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "losowa liczba całkowita od %1 do %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Zwróć losową liczbę całkowitą w ramach dwóch wyznaczonych granic, włącznie.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://pl.wikipedia.org/wiki/Zaokrąglanie";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "zaokrąglij";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "zaokrąglij w dół";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "zaokrąglij w górę";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Zaokrąglij w górę lub w dół.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://pl.wikipedia.org/wiki/Pierwiastek_kwadratowy";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "wartość bezwzględna";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "pierwiastek kwadratowy";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Zwróć wartość bezwzględną danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Zwróć e do potęgi danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Zwróć logarytm naturalny danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Zwraca logarytm dziesiętny danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Zwróć negację danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Zwróć 10 do potęgi danej liczby.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Zwróć pierwiastek kwadratowy danej liczby.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "arccos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctg";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://pl.wikipedia.org/wiki/Funkcje_trygonometryczne";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tg";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Zwróć arcus cosinus danej liczby.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Zwróć arcus sinus danej liczby.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Zwróć arcus tangens danej liczby.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Zwróć wartość cosinusa o stopniu (nie w radianach).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Zwróć wartość sinusa o stopniu (nie w radianach).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Zwróć tangens o stopniu (nie w radianach).";
                +Blockly.Msg["NEW_VARIABLE"] = "Stwórz zmienną...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nowa nazwa zmiennej:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "zezwól na instrukcje";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "z:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://pl.wikipedia.org/wiki/Podprogram";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Uruchom funkcję zdefiniowaną przez użytkownika '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://pl.wikipedia.org/wiki/Podprogram";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Uruchom funkcję zdefiniowaną przez użytkownika '%1' i skorzystaj z jej wyniku.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "z:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Stwórz '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Opisz tę funkcję...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "zrób coś";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "do";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Tworzy funkcję bez wyniku.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "zwróć";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Tworzy funkcję z wynikiem.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Uwaga: Ta funkcja ma powtórzone parametry.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Podświetl definicję funkcji";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Jeśli wartość jest prawdziwa, zwróć drugą wartość.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Uwaga: Ten blok może być używany tylko w definicji funkcji.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nazwa wejścia:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Dodaj dane wejściowe do funkcji.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "wejścia";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Dodaj, usuń lub zmień kolejność danych wejściowych dla tej funkcji.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Ponów";
                +Blockly.Msg["REMOVE_COMMENT"] = "Usuń komentarz";
                +Blockly.Msg["RENAME_VARIABLE"] = "Zmień nazwę zmiennej...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Zmień nazwy wszystkich '%1' zmiennych na:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Dołącz tekst do zmiennej '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "zmień na małe litery";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "zmień na od Wielkich Liter";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "zmień na WIELKIE LITERY";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Zwraca kopię tekstu z inną wielkością liter.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "pobierz pierwszą literę";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "pobierz literę # od końca";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "pobierz literę #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "pobierz ostatnią literę";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "pobierz losową literę";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "w tekście %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Zwraca literę z określonej pozycji.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Dodaj element do tekstu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "połącz";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Dodaj, usuń lub zmień kolejność sekcji, aby zmodyfikować blok tekstowy.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "do # litery od końca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "do # litery";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "do ostatniej litery";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "w tekście";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "pobierz podciąg od pierwszej litery";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "pobierz podciąg od # litery od końca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "pobierz podciąg od # litery";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Zwraca określoną część tekstu.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "znajdź pierwsze wystąpienie tekstu";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "znajdź ostatnie wystąpienie tekstu";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "w tekście %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Zwraca indeks pierwszego/ostatniego wystąpienia pierwszego tekstu w drugim tekście. Zwraca wartość %1, jeśli tekst nie został znaleziony.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 jest pusty";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Zwraca prawda (true), jeśli podany tekst jest pusty.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "utwórz tekst z";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Tworzy fragment tekstu, łącząc ze sobą dowolną liczbę tekstów.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "długość %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Zwraca liczbę liter (łącznie ze spacjami) w podanym tekście.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "wydrukuj %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Drukuj określony tekst, liczbę lub inną wartość.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Zapytaj użytkownika  o liczbę.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Zapytaj użytkownika o jakiś tekst.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "poproś o liczbę z tą wiadomością";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "poproś o tekst z tą wiadomością";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "odwróć %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://pl.wikipedia.org/wiki/Tekstowy_typ_danych";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Litera, wyraz lub linia tekstu.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "usuń spacje po obu stronach";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "usuń spacje z lewej strony";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "usuń spacje z prawej strony";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Zwraca kopię tekstu z usuniętymi spacjami z jednego lub z obu końców tekstu.";
                +Blockly.Msg["TODAY"] = "Dzisiaj";
                +Blockly.Msg["UNDO"] = "Cofnij";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Utwórz blok 'ustaw %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Zwraca wartość tej zmiennej.";
                +Blockly.Msg["VARIABLES_SET"] = "przypisz %1 wartość %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Utwórz blok 'pobierz %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Nadaj tej zmiennej wartość.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Zmienna o nazwie '%1' już istnieje.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/pms.js b/blockly/webif/static/blockly/msg/js/pms.js
                new file mode 100644
                index 000000000..67c5d8e13
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/pms.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.pms');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Gionté un coment";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "As peul nen eliminesse la variàbil '%1' përchè a l'é part ëd la definission dla fonsion '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Modifiché ël valor:";
                +Blockly.Msg["CLEAN_UP"] = "Dëscancelé ij blòch";
                +Blockly.Msg["COLLAPSE_ALL"] = "Arduve ij blòch";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Arduve ël blòch";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "color 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "color 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "rapòrt";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mës-cé";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "A mës-cia doi color ansema con un rapòrt dàit (0,0 - 1,0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Serne un color ant la taulòssa.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "color a asar";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Serne un color a asar.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "bleu";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verd";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ross";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "coloré con";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Creé un color con la quantità spessificà ëd ross, verd e bleu. Tuti ij valor a devo esse antra 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "seurte da la liassa";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continué con l'iterassion sucessiva dla liassa";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Seurte da la liassa anglobanta.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Sauté ël rest ëd sa liassa, e continué con l'iterassion apress.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Atension: Ës blòch a peul mach esse dovrà andrinta a na liassa.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "për minca n'element %1 ant la lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Për minca element an na lista, dé ël valor ëd l'element a la variàbil '%1', peui eseguì chèiche anstrussion.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "conté con %1 da %2 a %3 për %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Fé an manera che la variàbil \"%1\" a pija ij valor dal nùmer inissial fin-a al nùmer final, an contand për l'antërval ëspessificà, e eseguì ij bloch ëspessificà.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Gionté na condission al blòch si.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Gionté na condission final ch'a cheuj tut al blòch si.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Gionté, gavé o riordiné le session për cinfiguré torna ës blòch si.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "dësnò";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "dësnò si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si un valor a l'é ver, antlora eseguì chèiche anstrussion.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si un valor a l'é ver, antlora eseguì ël prim blòch d'anstrussion. Dësnò, eseguì ël second blòch d'anstrussion.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si ël prim valor a l'é ver, antlora fé andé ël prim blòch d'anstrussion. Dësnò, si ël second valor a l'é ver, fé andé ël second blòch d'anstrussion.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si ël prim valor a l'é ver, antlora fé andé ël prim blòch d'anstrussion. Dësnò, si ël second valor a l'é ver, fé andé ël second blòcj d'anstrussion. Si gnun dij valor a l'é ver, fé andé l'ùltim blòch d'anstrussion.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fé";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "arpete %1 vire";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Eseguì chèiche anstrussion vàire vire.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "arpete fin-a a";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "arpete antramentre che";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Cand un valor a l'é fàuss, eseguì chèiche anstrussion.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Cand un valor a l'é ver, eseguì chèiche anstrussion.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Scancelé tuti ij %1 blòch?";
                +Blockly.Msg["DELETE_BLOCK"] = "Scancelé ël blòch";
                +Blockly.Msg["DELETE_VARIABLE"] = "Eliminé la variàbil '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Eliminé %1 utilisassion ëd la variàbil '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Scancelé %1 blòch";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disativé ël blòch";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Dupliché";
                +Blockly.Msg["ENABLE_BLOCK"] = "Ativé ël blòch";
                +Blockly.Msg["EXPAND_ALL"] = "Dësvlupé ij blòch";
                +Blockly.Msg["EXPAND_BLOCK"] = "Dësvlupé ël blòch";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Imission esterne";
                +Blockly.Msg["HELP"] = "Agiut";
                +Blockly.Msg["INLINE_INPUTS"] = "Imission an linia";
                +Blockly.Msg["IOS_CANCEL"] = "Anulé";
                +Blockly.Msg["IOS_ERROR"] = "Eror";
                +Blockly.Msg["IOS_OK"] = "Va bin";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Gionté n'imission";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Përmëtte le diciairassion";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Costa imission a dj'imission duplicà.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "IMISSION";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Gionté";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Gionté na variàbil";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Eliminé";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "A peul nen dovré un nòm ëd variàbil veuid.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Arnominé";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nòm ëd la variàbil";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "creé na lista veuida";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Smon-e na lista, ëd longheur 0, ch'a conten gnun-a argistrassion";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Gionté, gavé o riordiné le session për configuré torna cost blòch ëd lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "creé na lista con";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Gionté n'element a la lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Creé na lista con un nùmer qualsëssìa d'element.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "prim";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# da la fin";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "oten-e";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "oten-e e eliminé";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ùltim";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "a l'ancàpit";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "eliminé";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "A smon ël prim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "A smon l'element a la posission ëspessificà an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "A smon l'ùltim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "A smon n'element a l'ancàpit an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "A gava e a smon ël prim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "A gava e a smon l'element a la posission ëspessificà an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "A gava e a smon l'ùltim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "A gava e a smon n'element a l'ancàpit an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "A gava ël prim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "A gava l'element a la posission ëspessificà an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "A gava l'ùltim element an na lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "A gava n'element a l'ancàpit da na lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "fin-a a # da la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "fin-a a #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "fin-a a l'ùltim";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "oten-e la sot-lista dal prim";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "oten-e la sot-lista da # da la fin";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "oten-e la sot-lista da #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "A crea na còpia dël tòch ëspessificà ëd na lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 a l'é l'ùltim element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 a l'é ël prim element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "trové la prima ocorensa dl'element";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "trové l'ùltima ocorensa dl'element";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "A smon l'ìndes ëd la prima/ùltima ocorensa dl'element ant la lista. A smon %1 se l'element a l'é nen trovà.";
                +Blockly.Msg["LISTS_INLIST"] = "ant la lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 a l'é veuid";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "A smon ver se la lista a l'é veuida.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longheur ëd %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "A smon la longheur ¨d na lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "creé na lista con l'element %1 arpetù %2 vire";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "A crea na lista ch'a consist dël valor dàit arpetù ël nùmer ëspessificà ëd vire.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "anversé %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Anversé na còpia ëd na lista";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "tanme";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "anserì an";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "buté";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "A anseriss l'element al prinsipi ëd na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "A anseriss l'element a la posission ëspessificà an na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Gionté l'element a la fin ëd na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "A anseriss l'element a l'ancàpit an na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "A fissa ël prim element an na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "A fissa l'element a la posission ëspessificà an na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "A fissa l'ùltim element an na lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "A fissa n'element a l'ancàpit an na lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "chërsent";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "calant";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "ordiné %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordiné na còpia ëd na lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabétich, ignorand ël caràter minùscol o majùscol";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numérich";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabétich";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "fé na lista da 'n test";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "fé 'n test da na lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Gionze na lista ëd test ant un test sol, separandje con un separator.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Divide un test an na lista ëd test, tajand a minca 'n separator.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "con ël separator";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "fàuss";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "A rëspond ver o fàuss.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "ver";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Rësponde ver si le doe imission a son uguaj.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Rësponde ver si la prima imission a l'é pi granda che la sconda.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Rësponde ver si la prima imission a l'é pi granda o ugual a la sconda.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Rësponde ver si la prima imission a l'é pi cita dla sconda.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Rësponde ver si la prima imission a l'é pi cita o ugual a la sconda.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Rësponde ver si le doe imission a son nen uguaj.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nen %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "A rëspond ver se l'imission a l'é fàussa. A rëspond fàuss se l'imission a l'é vera.";
                +Blockly.Msg["LOGIC_NULL"] = "gnente";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "A rëspond gnente.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Rësponde ver se tute doe j'imission a son vere.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Rësponde ver se almanch un-a d'imission a l'é vera.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "preuva";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se fàuss";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se ver";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Controlé la condission an 'preuva'. Se la condission a l'é vera, a rëspond con ël valor 'se ver'; dësnò a rëspond con ël valor 'se fàuss'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "A smon la soma ëd doi nùmer.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "A smon ël cossient dij doi nùmer.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "A smon la diferensa dij doi nùmer.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "A smon ël prodot dij doi nùmer.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "A smon ël prim nùmer alvà a la potensa dël second.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "ancrementé %1 për %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Gionté un nùmer a la variàbil '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "A smon un-a dle costante comun-e π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) o ∞ (infinì).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "limité %1 antra %2 e %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Limité un nùmer a esse antra le limitassion ëspessificà (comprèise).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "a l'é divisìbil për";
                +Blockly.Msg["MATH_IS_EVEN"] = "a l'é cobi";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "a l'é negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "a l'é dëscobi";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "a l'é positiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "a l'é prim";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "A contròla si un nùmer a l'é cobi, dëscobi, prim, antreghm positiv, negativ, o s'a l'é divisìbil për un nùmer dàit. A rëspond ver o fàuss.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "a l'é antregh";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resta ëd %1:%2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "A smon la resta ëd la division dij doi nùmer.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un nùmer.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "media dla lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "màssim ëd la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mesan-a dla lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "mìnim ëd la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "mòde dla lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "element a l'ancàpit ëd la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviassion ëstàndard ëd la lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "soma dla lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "A smon la media (aritmética) dij valor numérich ant la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "A smon ël pi gròss nùmer ëd la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "A smon ël nùmer mesan ëd la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "A smon ël pi cit nùmer ëd la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "A smon na lista dj'element pi frequent ëd la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "A smon n'element a l'ancàpit da la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "A smon la deviassion ëstàndard ëd la lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "A smon la soma ëd tuti ij nùmer ant la lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "frassion aleatòria";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "A smon na frassion aleatòria antra 0,0 (comprèis) e 1,0 (esclus).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "antregh aleatòri antra %1 e %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "A smon n'antregh aleatòri antra ij doi lìmit ëspessificà, comprèis.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ariondé";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ariondé për difet";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ariondé për ecess";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "A arionda un nùmer për difet o ecess.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "assolù";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "rèis quadra";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "A smon ël valor assolù d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "A smon e a la potensa d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "A smon ël logaritm natural d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "A smon ël logaritm an base 10 d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "A smon l'opòst d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "A smon 10 a la potensa d'un nùmer.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "A smon la rèis quadra d'un nùmer.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "A smon l'arch-cosen d'un nùmer.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "A smon l'arch-sen d'un nùmer.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "A smon l'arch-tangenta d'un nùmer.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "A smon ël cosen ëd n'àngol an gré (pa an radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "A smon ël sen ëd n'àngol an gré (pa an radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "A smon la tangenta ëd n'àngol an gré (pa an radiant).";
                +Blockly.Msg["NEW_VARIABLE"] = "Creé na variàbil...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nòm ëd la neuva variàbil:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "përmëtte le diciairassion";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Eseguì la fonsion '%1' definìa da l'utent.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Eseguì la fonsion '%1' definìa da l'utent e dovré sò arzultà.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Creé '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Descrive sa fonsion...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "fé cheicòs";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "a";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "A crea na fonsion sensa surtìa.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "artorn";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "A crea na fonsion con na surtìa.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Atension: Costa fonsion a l'ha dij paràmeter duplicà.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Sot-ligné la definission dla fonsion";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Se un valor a l'é ver, antlora smon-e un second valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Atension: Ës blòch a podria esse dovrà mach an na definission ëd fonsion.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nòm ëd l'imission:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Gionté n'imission a la fonsion.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "imission";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Gionté, gavé o riordiné j'imission ëd sa fonsion.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Na procedura ciamà '%1' a esist già.";
                +Blockly.Msg["REDO"] = "Fé torna";
                +Blockly.Msg["REMOVE_COMMENT"] = "Scancelé un coment";
                +Blockly.Msg["RENAME_VARIABLE"] = "Arnomé la variàbil...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Arnomé tute le variàbij '%1' 'me:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "a %1 taché ël test %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Taché dël test a la variàbil '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "an minùscul";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "an Majùscol A L'Ancamin Ëd Minca Paròla";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "an MAJÙSCOL";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "A smon na còpia dël test ant un caràter diferent.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "oten-e la prima litra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "oten-e la litra # da la fin";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "oten-e la litra #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "oten-e l'ùltima litra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "oten-e na litra a l'ancàpit";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "ant ël test %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "A smon la litra ant la posission ëspessificà.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "nùmer %1 su %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Conté vàire vire un test dàit a compariss an n'àutr test.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Gionté n'element al test.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "gionze";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Gionté, gavé o riordiné le session për configuré torna ës blòch ëd test.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "fin-a a la litra # da la fin";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "fin-a a la litra #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "fin-a a l'ùltima litra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "ant ël test";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "oten-e la sota-stringa da la prima litra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "oten-e la sota-stringa da la litra # da la fin";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "oten-e la sota-stringa da la litra #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "A smon un tòch ëspessificà dël test.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "trové la prima ocorensa dël test";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "trové l'ùltima ocorensa dël test";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "ant ël test %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "A smon l'ìndes dla prima/ùltima ocorensa dël prim test ant ël second test. A smon %1 se ël test a l'é nen trovà.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 a l'é veuid";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "A smon ver se ël test fornì a l'é veuid.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "creé ël test con";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Creé un tòch ëd test an gionzend un nùmer qualsëssìa d'element.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longheur ëd %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "A smon ël nùmer ëd litre (spassi comprèis) ant ël test fornì.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "smon-e %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Smon-e ël test, ël nùmer o n'àutr valor ëspessificà.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Ciamé un nùmer a l'utent.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Ciamé un test a l'utent.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "anvit për un nùmer con un mëssagi";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "anvit për un test con un mëssagi";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "rampiassé %1 con %2 an %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Rampiassé tute j'ocorense d'un test con n'àutr.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "Anversé %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Anversé l'òrdin dij caràter ant ël test.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Na litra, na paròla o na linia ëd test.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "gavé jë spassi da le doe bande ëd";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "gavé jë spassi da la banda snistra ëd";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "gavé jë spassi da la banda drita ëd";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "A smon na còpia dël test con jë spassi gavà da n'estremità o da tute doe.";
                +Blockly.Msg["TODAY"] = "Ancheuj";
                +Blockly.Msg["UNDO"] = "Anulé";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Creé 'fissé %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "A smon ël valor ëd sa variàbil.";
                +Blockly.Msg["VARIABLES_SET"] = "fissé %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Creé 'oten-e %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Fissé costa variàbil ugual al valor d'imission.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Na variàbil con ël nòm '%1' a esist già.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/pt-br.js b/blockly/webif/static/blockly/msg/js/pt-br.js
                new file mode 100644
                index 000000000..3fa878779
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/pt-br.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.pt.br');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Adicionar comentário";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Não se pode deletar a variável '%1' porque é parte da definição da função '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Mudar valor:";
                +Blockly.Msg["CLEAN_UP"] = "Limpar blocos";
                +Blockly.Msg["COLLAPSE_ALL"] = "Colapsar Blocos";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Colapsar Bloco";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "cor 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "cor 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporção";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "misturar";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Mistura duas cores em uma dada proporção (0,0 - 1,0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://pt.wikipedia.org/wiki/Cor";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Escolher uma cor da palheta de cores.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "cor aleatória";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Escolher cor de forma aleatória.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "azul";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "vermelho";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colorir com";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Criar uma cor com a quantidade especificada de vermelho, verde e azul. Todos os valores devem estar entre 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "encerra o laço";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continua com a próxima iteração do laço";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Encerra o laço.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Ignora o resto deste laço, e continua com a próxima iteração.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Atenção: Este bloco só pode ser usado dentro de um laço.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "para cada item %1 na lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Para cada item em uma lista, atribua o item à variável '%1' e então realize algumas instruções.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "contar com %1 de %2 até %3 por %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Faça com que a variável '%1' assuma os valores do número inicial ao número final, contando de acordo com o intervalo especificado e execute os blocos especificados.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Acrescente uma condição para o bloco se.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Acrescente uma condição final para o bloco se.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Acrescente, remova ou reordene seções para reconfigurar este bloco.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "senão";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "senão se";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Se um valor for verdadeiro, então realize algumas instruções.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Se um valor for verdadeiro, então realize o primeiro bloco de instruções. Senão, realize o segundo bloco de instruções.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Se o primeiro valor for verdadeiro, então realize o primeiro bloco de instruções. Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções. Se nenhum dos blocos for verdadeiro, realize o último bloco de instruções.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://pt.wikipedia.org/wiki/Estrutura_de_repeti%C3%A7%C3%A3o#Repeti.C3.A7.C3.A3o_com_vari.C3.A1vel_de_controle";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "faça";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repita %1 vezes";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Faça algumas instruções várias vezes.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repita até";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repita enquanto";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Enquanto um valor for falso, então faça algumas instruções.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Enquanto um valor for verdadeiro, então faça algumas instruções.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Deletar todos os blocos %1?";
                +Blockly.Msg["DELETE_BLOCK"] = "Deletar bloco";
                +Blockly.Msg["DELETE_VARIABLE"] = "Deletar a variável '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Deletar %1 usos da variável '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Deletar %1 blocos";
                +Blockly.Msg["DISABLE_BLOCK"] = "Desabilitar bloco";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicar";
                +Blockly.Msg["ENABLE_BLOCK"] = "Habilitar bloco";
                +Blockly.Msg["EXPAND_ALL"] = "Expandir blocos";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expandir bloco";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entradas externas";
                +Blockly.Msg["HELP"] = "Ajuda";
                +Blockly.Msg["INLINE_INPUTS"] = "Entradas incorporadas";
                +Blockly.Msg["IOS_CANCEL"] = "blockly:IOS Cancelar/pt-br";
                +Blockly.Msg["IOS_ERROR"] = "Erro";
                +Blockly.Msg["IOS_OK"] = "Ok";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Adicionar Entrada";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Permitir declarações";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Essa função tem entradas duplicadas.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ENTRADAS";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Adicionar";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Adicionar Variável";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Deletar";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Você não pode usar um nome de variável vazio.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Blockly:Renomear varioas botoens/pt-br";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nome variavel";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "criar lista vazia";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Retorna uma lista, de tamanho 0, contendo nenhum registro";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Acrescenta, remove ou reordena seções para reconfigurar este bloco de lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "criar lista com";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Acrescenta um item à lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Cria uma lista com a quantidade de itens informada.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primeiro";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "nº a partir do final";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "nº";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obter";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obter e remover";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "último";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleatório";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remover";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Retorna o primeiro item em uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Retorna o item da lista na posição especificada.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Retorna o último item em uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Retorna um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Remove e retorna o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Remove e retorna o item na posição especificada em uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Remove e retorna o último item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Remove e retorna um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Remove o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Remove o item na posição especificada em uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Remove o último item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Remove um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "até nº a partir do final";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "até nº";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "até último";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "obtém sublista a partir do primeiro";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "obtém sublista de nº a partir do final";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "obtém sublista de nº";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Cria uma cópia da porção especificada de uma lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 é o último item.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 é o primeiro item.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "encontre a primeira ocorrência do item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "encontre a última ocorrência do item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Retorna o índice da primeira/última ocorrência do item na lista.  Retorna %1 se o item não for encontrado.";
                +Blockly.Msg["LISTS_INLIST"] = "na lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 é vazia";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Retorna ao verdadeiro se a lista estiver vazia.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "tamanho de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Retorna o tamanho de uma lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "criar lista com item %1 repetido %2 vezes";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Cria uma lista consistindo no valor informado repetido o número de vezes especificado.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Listas#invertendo-uma-lista";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "inverter %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Inverter uma cópia da lista.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "como";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserir em";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "definir";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insere o item no início de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insere o item na posição especificada em uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Insere o item no final de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Insere o item em uma posição qualquer de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Define o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Define o item da posição especificada de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Define o último item de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Define um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascendente";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descendente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "ordenar %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordenar uma cópia de uma lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabético, ignorar maiúscula/minúscula";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numérico";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabético";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "Fazer uma lista a partir do texto";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "fazer um texto a partir da lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Juntar uma lista de textos em um único texto, separado por um delimitador.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dividir o texto em uma lista de textos, separando-o em cada delimitador.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "com delimitador";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falso";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Retorna verdadeiro ou falso.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "verdadeiro";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://pt.wikipedia.org/wiki/Inequa%C3%A7%C3%A3o";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Retorna verdadeiro se ambas as entradas forem iguais.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Retorna verdadeiro se a primeira entrada for maior que a segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Retorna verdadeiro se a primeira entrada for maior ou igual à segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Retorna verdadeiro se a primeira entrada for menor que a segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Retorna verdadeiro se a primeira entrada for menor ou igual à segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Retorna verdadeiro se ambas as entradas forem diferentes.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "não %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Retorna verdadeiro se a entrada for falsa.  Retorna falsa se a entrada for verdadeira.";
                +Blockly.Msg["LOGIC_NULL"] = "nulo";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Retorna nulo.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ou";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Retorna verdadeiro se ambas as entradas forem verdadeiras.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Retorna verdadeiro se uma das estradas for verdadeira.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "teste";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se falso";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se verdadeiro";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Avalia a condição em \"teste\". Se a condição for verdadeira retorna o valor \"se verdadeiro\", senão retorna o valor \"se falso\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://pt.wikipedia.org/wiki/Aritm%C3%A9tica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Retorna a soma dos dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Retorna o quociente da divisão dos dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Retorna a diferença entre os dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Retorna o produto dos dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Retorna o primeiro número elevado à potência do segundo número.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://pt.wikipedia.org/wiki/Adi%C3%A7%C3%A3o";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "alterar %1 por %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Soma um número à variável \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://pt.wikipedia.org/wiki/Anexo:Lista_de_constantes_matem%C3%A1ticas";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Retorna uma das constantes comuns: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infinito).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "restringe %1 inferior %2 superior %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Restringe um número entre os limites especificados (inclusivo).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "é divisível por";
                +Blockly.Msg["MATH_IS_EVEN"] = "é par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "é negativo";
                +Blockly.Msg["MATH_IS_ODD"] = "é ímpar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "é positivo";
                +Blockly.Msg["MATH_IS_PRIME"] = "é primo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Verifica se um número é par, ímpar, inteiro, positivo, negativo, ou se é divisível por outro número.  Retorna verdadeiro ou falso.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "é inteiro";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto da divisão de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Retorna o resto da divisão de dois números.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://pt.wikipedia.org/wiki/N%C3%BAmero";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Um número.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "média da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maior da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "menor da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "moda da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "item aleatório da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "desvio padrão da lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "soma de uma lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Retorna a média aritmética dos números da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Retorna o maior número da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Retorna a mediana dos números da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Retorna o menor número da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Retorna uma lista do(s) item(ns) mais comum(ns) da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Retorna um elemento aleatório da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Retorna o desvio padrão dos números da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Retorna a soma de todos os números na lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://pt.wikipedia.org/wiki/Gerador_de_n%C3%BAmeros_pseudoaleat%C3%B3rios";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fração aleatória";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Retorna uma fração aleatória entre 0.0 (inclusivo) e 1.0 (exclusivo).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://pt.wikipedia.org/wiki/Gerador_de_n%C3%BAmeros_pseudoaleat%C3%B3rios";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "inteiro aleatório entre %1 e %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Retorna um número inteiro entre os dois limites informados, inclusivo.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://pt.wikipedia.org/wiki/Arredondamento";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arredonda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arredonda para baixo";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arredonda para cima";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arredonda um número para cima ou para baixo.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://pt.wikipedia.org/wiki/Raiz_quadrada";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluto";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "raiz quadrada";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Retorna o valor absoluto de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Retorna o número e elevado à potência de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Retorna o logaritmo natural de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Retorna o logaritmo em base 10 de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Retorna o oposto de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Retorna 10 elevado à potência de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Retorna a raiz quadrada de um número.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_trigonom%C3%A9trica";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Retorna o arco cosseno de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Retorna o arco seno de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Retorna o arco tangente de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Retorna o cosseno de um grau (não radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Retorna o seno de um grau (não radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Retorna a tangente de um grau (não radiano).";
                +Blockly.Msg["NEW_VARIABLE"] = "Criar variável...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nome da nova variável:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permitir declarações";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "com:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://pt.wikipedia.org/wiki/Sub-rotina";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Executa a função definida pelo usuário \"%1\".";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://pt.wikipedia.org/wiki/Sub-rotina";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Executa a função definida pelo usuário \"%1\" e usa seu retorno.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "com:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Criar \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Descreva esta função...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "faça algo";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "para";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Cria uma função que não tem retorno.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retorna";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Cria uma função que possui um valor de retorno.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Atenção: Esta função tem parâmetros duplicados.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Destacar definição da função";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Se um valor é verdadeiro, então retorna um valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Atenção: Este bloco só pode ser utilizado dentro da definição de uma função.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nome da entrada:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Adiciona uma entrada para esta função";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entradas";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Adiciona, remove, ou reordena as entradas para esta função.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Um procedimento chamado '%1' já existe.";
                +Blockly.Msg["REDO"] = "Refazer";
                +Blockly.Msg["REMOVE_COMMENT"] = "Remover comentário";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renomear variável...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renomear todas as variáveis '%1' para:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "para %1 anexar texto %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Acrescentar um pedaço de texto à variável \"%1\".";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "para minúsculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "para Nomes Próprios";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "para MAIÚSCULAS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Retorna uma cópia do texto em um formato diferente.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obter primeira letra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obter letra # a partir do final";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obter letra nº";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obter última letra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obter letra aleatória";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "no texto %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Retorna a letra na posição especificada.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "Contar %1 em %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Calcule quantas vezes algum texto aparece centro de algum outro texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Acrescentar um item ao texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Acrescenta, remove ou reordena seções para reconfigurar este bloco de texto.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "até letra nº a partir do final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "até letra nº";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "até última letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "no texto";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "obter trecho de primeira letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "obter trecho de letra nº a partir do final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "obter trecho de letra nº";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Retorna o trecho de texto especificado.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "encontre a primeira ocorrência do item";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "encontre a última ocorrência do texto";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "no texto %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto.  Retorna %1 se o texto não for encontrado.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 é vazio";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Retorna verdadeiro se o texto fornecido for vazio.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "criar texto com";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Criar um pedaço de texto juntando qualquer número de itens.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "tamanho de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Retorna o número de letras (incluindo espaços) no texto fornecido.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "imprime %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Imprime o texto, número ou valor especificado.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Pede ao usuário um número.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Pede ao usuário um texto.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Pede um número com uma mensagem";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Pede um texto com uma mensagem";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Texto#substituindo-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "substituir %1 por %2 em %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Substitua todas as ocorrências de algum texto dentro de algum outro texto.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Texto#invertendo-texto";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "inverter %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Inverter a ordem dos caracteres no texto.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://pt.wikipedia.org/wiki/Cadeia_de_caracteres";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Uma letra, palavra ou linha de texto.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "remover espaços de ambos os lados de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "remover espaços à esquerda de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "remover espaços à direita de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Retorna uma cópia do texto com os espaços removidos de uma ou ambas extremidades.";
                +Blockly.Msg["TODAY"] = "Hoje";
                +Blockly.Msg["UNDO"] = "Desfazer";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Criar \"definir %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Retorna o valor desta variável.";
                +Blockly.Msg["VARIABLES_SET"] = "definir %1 para %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Criar \"obter %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Define esta variável para o valor da entrada.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variável chamada '%1' já existe.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/pt.js b/blockly/webif/static/blockly/msg/js/pt.js
                new file mode 100644
                index 000000000..9d0bda8c8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/pt.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.pt');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Adicionar Comentário";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Não se pode eliminar a variável '%1' porque faz parte da definição da função '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Alterar valor:";
                +Blockly.Msg["CLEAN_UP"] = "Limpar Blocos";
                +Blockly.Msg["COLLAPSE_ALL"] = "Ocultar Blocos";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Ocultar Bloco";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "cor 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "cor 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporção";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "misturar";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Mistura duas cores com a proporção indicada (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "http://pt.wikipedia.org/wiki/Cor";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Escolha uma cor da paleta de cores.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "cor aleatória";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Escolha uma cor aleatoriamente.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "azul";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "vermelho";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "pinte com";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Cria uma cor de acordo com a quantidade especificada de vermelho, verde e azul. Todos os valores devem estar entre 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "sair do ciclo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continuar com a próxima iteração do ciclo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Sair do ciclo que está contido.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Ignorar o resto deste ciclo, e continuar com a próxima iteração.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Atenção: Este bloco só pode ser usado dentro de um ciclo.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "para cada item %1 na lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Para cada item numa lista, define a variável \"%1\" para o item e então faz algumas instruções.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "contar com %1 de %2 até %3 de %3 em %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Faz com que a variável \"%1\" assuma os valores desde o número inicial até ao número final, contando de acordo com o intervalo especificado e executa os blocos especificados.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Acrescente uma condição ao bloco se.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Acrescente uma condição de excepação final para o bloco se.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Acrescente, remova ou reordene secções para reconfigurar este bloco se.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "senão";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "senão se";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "se";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Se um valor é verdadeiro, então realize alguns passos.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Se um valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, realize o segundo bloco de instruções";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.  Se nenhum dos blocos for verdadeiro, realize o último bloco de instruções.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "http://pt.wikipedia.org/wiki/Estrutura_de_repeti%C3%A7%C3%A3o#Repeti.C3.A7.C3.A3o_com_vari.C3.A1vel_de_controle";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "faça";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repetir %1 vez";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Faça algumas instruções várias vezes.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repetir até";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repetir enquanto";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Enquanto um valor for falso, então faça algumas instruções.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Enquanto um valor for verdadeiro, então faça algumas instruções.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Eliminar todos os %1 blocos?";
                +Blockly.Msg["DELETE_BLOCK"] = "Eliminar Bloco";
                +Blockly.Msg["DELETE_VARIABLE"] = "Eliminar a variável '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Eliminar %1 utilizações da variável '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Eliminar %1 Blocos";
                +Blockly.Msg["DISABLE_BLOCK"] = "Desativar Bloco";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicar";
                +Blockly.Msg["ENABLE_BLOCK"] = "Ativar Bloco";
                +Blockly.Msg["EXPAND_ALL"] = "Expandir Blocos";
                +Blockly.Msg["EXPAND_BLOCK"] = "Expandir Bloco";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Entradas Externas";
                +Blockly.Msg["HELP"] = "Ajuda";
                +Blockly.Msg["INLINE_INPUTS"] = "Entradas Em Linhas";
                +Blockly.Msg["IOS_CANCEL"] = "Cancelar";
                +Blockly.Msg["IOS_ERROR"] = "Erro";
                +Blockly.Msg["IOS_OK"] = "Aceitar";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Adicionar entrada";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Permitir declarações";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Essa função tem entradas duplicadas.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ENTRADAS";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Adicionar";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Adicionar Variável";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Eliminar";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Você não pode usar um nome de variável vazio.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Renomear";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Nome da variável";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "criar lista vazia";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Retorna uma lista, de tamanho 0, contendo nenhum registo";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Acrescente, remova ou reordene as seções para reconfigurar este bloco lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "criar lista com";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Acrescenta um item à lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Cria uma lista com qualquer número de itens.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primeiro";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# a partir do final";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obter";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obter e remover";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "último";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleatório";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remover";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Retorna o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Retorna o item na posição especificada da lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Retorna o último item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Retorna um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Remove e retorna o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Remove e retorna o item na posição especificada de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Remove e retorna o último item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Remove e retorna um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Remove o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Remove o item de uma posição especifica da lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Remove o último item de uma lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Remove um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "até #, a partir do final";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "até #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "para o último";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "obtem sublista da primeira lista";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "obtem sublista de # a partir do final";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "obtem sublista de #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Cria uma cópia da porção especificada de uma lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 é o último item.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 é o primeiro item.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "encontre a primeira ocorrência do item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "encontre a última ocorrência do item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Retorna a posição da primeira/última ocorrência do item na lista.  Retorna %1 se o item não for encontrado.";
                +Blockly.Msg["LISTS_INLIST"] = "na lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 está vazia";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Retona verdadeiro se a lista estiver vazia.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "tamanho de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Retorna o tamanho de uma lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "criar lista com o item %1 repetido %2 vezes";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Cria uma lista constituída por um dado valor repetido o número de vezes especificado.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "inverter %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Inverter uma cópia da lista.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "como";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserir em";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "definir";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insere o item no início da lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insere o item numa posição especificada numa lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Insere o item no final da lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Insere o item numa posição aleatória de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Define o primeiro item de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Define o item na posição especificada de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Define o último item de uma lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Define um item aleatório de uma lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascendente";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descendente";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "ordenar %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Ordenar uma cópia de uma lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabética, ignorar maiúsculas/minúsculas";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numérica";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabética";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "fazer lista a partir de texto";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "fazer texto a partir da lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Juntar uma lista de textos num único texto, separado por um delimitador.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dividir o texto numa lista de textos, separando-o em cada delimitador.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "com delimitador";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falso";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Retorna verdadeiro ou falso.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "verdadeiro";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "http://pt.wikipedia.org/wiki/Inequa%C3%A7%C3%A3o";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Retorna verdadeiro se ambas as entradas forem iguais entre si.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Retorna verdadeiro se a primeira entrada for maior que a segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Retorna verdadeiro se a primeira entrada for maior ou igual à segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Retorna verdadeiro se a primeira entrada for menor que a segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Retorna verdadeiro se a primeira entrada for menor ou igual à segunda entrada.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Retorna verdadeiro se ambas as entradas forem diferentes entre si.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "não %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Retorna verdadeiro se a entrada for falsa.  Retorna falso se a entrada for verdadeira.";
                +Blockly.Msg["LOGIC_NULL"] = "nulo";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "http://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Retorna nulo.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "e";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ou";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Retorna verdadeiro se ambas as entradas forem verdadeiras.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Retorna verdadeiro se pelo menos uma das estradas for verdadeira.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "teste";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "http://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "se falso";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "se verdadeiro";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Avalia a condição em \"teste\". Se a condição for verdadeira retorna o valor \"se verdadeiro\", senão retorna o valor \"se falso\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "http://pt.wikipedia.org/wiki/Aritm%C3%A9tica";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Retorna a soma de dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Retorna o quociente da divisão de dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Retorna a diferença de dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Retorna o produto de dois números.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Retorna o primeiro número elevado à potência do segundo número.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "http://pt.wikipedia.org/wiki/Adi%C3%A7%C3%A3o";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "alterar %1 por %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Soma um número à variável \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "http://pt.wikipedia.org/wiki/Anexo:Lista_de_constantes_matem%C3%A1ticas";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Retorna uma das constantes comuns: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infinito).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "restringe %1 inferior %2 superior %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Restringe um número entre os limites especificados (inclusive).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "é divisível por";
                +Blockly.Msg["MATH_IS_EVEN"] = "é par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "é negativo";
                +Blockly.Msg["MATH_IS_ODD"] = "é impar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "é positivo";
                +Blockly.Msg["MATH_IS_PRIME"] = "é primo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Verifica se um número é par, impar, primo, inteiro, positivo, negativo, ou se é divisível por outro número.  Retorna verdadeiro ou falso.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "é inteiro";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "http://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resto da divisão de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Retorna o resto da divisão de dois números.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "http://pt.wikipedia.org/wiki/N%C3%BAmero";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Um número.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "média de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maior de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "menor de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "moda de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "item aleatório de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "desvio padrão de uma lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "soma da lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Retorna a média aritmética dos valores números da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Retorna o maior número da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Retorna a mediana da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Retorna o menor número da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Retorna a lista de item(ns) mais comum(ns) da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Retorna um elemento aleatório da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Retorna o desvio padrão dos números da lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Retorna a soma de todos os números da lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "http://pt.wikipedia.org/wiki/N%C3%BAmero_aleat%C3%B3rio";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fração aleatória";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Insere uma fração aleatória entre 0.0 (inclusive) e 1.0 (exclusive).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "http://pt.wikipedia.org/wiki/N%C3%BAmero_aleat%C3%B3rio";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "inteiro aleatório entre %1 e %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Retorna um número inteiro entre os dois limites especificados, inclusive.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "http://pt.wikipedia.org/wiki/Arredondamento";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arredonda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arredonda para baixo";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "arredonda para cima";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arredonda um número para cima ou para baixo.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "http://pt.wikipedia.org/wiki/Raiz_quadrada";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluto";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "raíz quadrada";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Retorna o valor absoluto de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Retorna o número e elevado à potência de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Retorna o logarítmo natural de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Retorna o logarítmo em base 10 de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Retorna o oposto de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Retorna 10 elevado à potência de um número.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Retorna a raiz quadrada de um número.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "http://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_trigonom%C3%A9trica";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Retorna o arco cosseno de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Retorna o arco seno de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Retorna o arco tangente de um número.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Retorna o cosseno de um grau (não radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Retorna o seno de um grau (não radiano).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Retorna a tangente de um grau (não radiano).";
                +Blockly.Msg["NEW_VARIABLE"] = "Criar variável…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nome da nova variável:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permitir declarações";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "com:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://pt.wikipedia.org/wiki/Sub-rotina";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Executa a função \"%1\".";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://pt.wikipedia.org/wiki/Sub-rotina";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Executa a função \"%1\" e usa o seu retorno.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "com:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Criar \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Descreva esta função...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "faz algo";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "para";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Cria uma função que não tem retorno.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "retorna";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Cria uma função que possui um valor de retorno.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Atenção: Esta função tem parâmetros duplicados.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Destacar definição da função";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "se o valor é verdadeiro, então retorna um segundo valor.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Atenção: Este bloco só pode ser utilizado dentro da definição de uma função.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nome da entrada:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Adicionar uma entrada para a função.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "entradas";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Adicionar, remover ou reordenar as entradas para esta função.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Refazer";
                +Blockly.Msg["REMOVE_COMMENT"] = "Remover Comentário";
                +Blockly.Msg["RENAME_VARIABLE"] = "Renomear variável...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Renomear todas as variáveis '%1' para:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Acrescentar um pedaço de texto à variável \"%1\".";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "para minúsculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "para Iniciais Maiúsculas";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "para MAIÚSCULAS";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Retorna uma cópia do texto em formato diferente.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obter primeira letra";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obter letra nº a partir do final";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obter letra nº";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obter última letra";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obter letra aleatória";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Retorna a letra na posição especificada.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "contar %1 em %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Conte quantas vezes um certo texto aparece dentro de algum outro texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Acrescentar um item ao texto.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "unir";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Acrescenta, remove ou reordena seções para reconfigurar este bloco de texto.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "até letra nº a partir do final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "até letra nº";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "até última letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "no texto";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "obter subsequência a partir da primeira letra";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "obter subsequência de tamanho # a partir do final";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "obter subsequência de tamanho #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Retorna a parte especificada do texto.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "primeira ocorrência do texto";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "última ocorrência do texto";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto. Retorna %1 se o texto não for encontrado.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 está vazio";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Retorna verdadeiro se o texto fornecido estiver vazio.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "criar texto com";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Criar um pedaço de texto juntando qualquer número de itens.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "tamanho de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Devolve o número de letras (incluindo espaços) do texto fornecido.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "imprime %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Imprime o texto, número ou outro valor especificado.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Pede ao utilizador um número.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Pede ao utilizador um texto.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "pede um número com a mensagem";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Pede um texto com a mensagem";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "substituir %1 por %2 em %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Substituir todas as ocorrências de um certo texto dentro de algum outro texto.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Inverte a ordem dos caracteres no texto.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "http://pt.wikipedia.org/wiki/Cadeia_de_caracteres";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Uma letra, palavra ou linha de texto.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "remover espaços de ambos os lados";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "remover espaços à esquerda de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "remover espaços à direita";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Retorna uma cópia do texto com os espaços removidos de uma ou ambas as extremidades.";
                +Blockly.Msg["TODAY"] = "Hoje";
                +Blockly.Msg["UNDO"] = "Desfazer";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Criar \"definir %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Retorna o valor desta variável.";
                +Blockly.Msg["VARIABLES_SET"] = "definir %1 para %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Criar \"obter %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Define esta variável para o valor inserido.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Já existe uma variável com o nome de '%1'.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ro.js b/blockly/webif/static/blockly/msg/js/ro.js
                new file mode 100644
                index 000000000..0b676f6bb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ro.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ro');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Adaugă un comentariu";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Schimbaţi valoarea:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Restrange blocurile";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Restrange blocul";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "culoare 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "culoare 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "Raport";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "amestec";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Amestecă două culori cu un raport dat (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ro.wikipedia.org/wiki/Culoare";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Alege o culoare din paleta de culori.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "culoare aleatorie";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Alege o culoare la întâmplare.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "albastru";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "verde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "roşu";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colorează cu";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Creează o culoare cu suma specificată de roşu, verde şi albastru.  Toate valorile trebuie să fie între 0 şi 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ieşi din bucla";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continuă cu următoarea iterație a buclei";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Ieși din bucla care conţine.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Sari peste restul aceastei bucle, şi continuă cu urmatoarea iteratie.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Avertisment: Acest bloc pote fi utilizat numai în interiorul unei bucle.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "pentru fiecare element %1 în listă %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Pentru fiecare element din listă, setaţi variabila '%1' ca valoarea elementului, şi apoi faceţi unele declaraţii.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "numără cu %1 de la %2 la %3 prin %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Cu variablia \"%1\" ia o valoare din numărul început la numărul final, numara in intervalul specificat, apoi face blocurile specificate.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Adăugaţi o condiţie in blocul if.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Adauga o stare finala, cuprinde toata conditia din blocul if.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Adaugă, elimină sau reordonează secţiuni pentru a reconfigura acest bloc if.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "altfel";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "altfel dacă";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "dacă";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Dacă o valoare este adevărată, atunci fa unele declaraţii.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Dacă o valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, face al doilea bloc de declaraţii.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Dacă prima valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, dacă a doua valoare este adevărat, face al doilea bloc de declaraţii.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Dacă prima valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, dacă a doua valoare este adevărat, face al doilea bloc de declaraţii.  În cazul în care niciuna din  valorilor nu este adevărat, face ultimul bloc de declaraţii.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fă";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repetă de %1 ori";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Face unele afirmaţii de mai multe ori.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "Repetaţi până când";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repetă în timp ce";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "În timp ce o valoare este adevărat, atunci face unele declaraţii.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "În timp ce o valoare este adevărat, atunci face unele declaraţii.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Ștergi toate cele %1 (de) blocuri?";
                +Blockly.Msg["DELETE_BLOCK"] = "Șterge Bloc";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Ștergeți %1 Blocuri";
                +Blockly.Msg["DISABLE_BLOCK"] = "Dezactivaţi bloc";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicati";
                +Blockly.Msg["ENABLE_BLOCK"] = "Permite bloc";
                +Blockly.Msg["EXPAND_ALL"] = "Extinde blocuri";
                +Blockly.Msg["EXPAND_BLOCK"] = "Extinde bloc";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Intrări externe";
                +Blockly.Msg["HELP"] = "Ajutor";
                +Blockly.Msg["INLINE_INPUTS"] = "Intrări în linie";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "creează listă goală";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returnează o listă, de lungime 0, care nu conţine înregistrări de date";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "listă";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Adaugă, elimină sau reordonează secţiuni ca să reconfiguraţi aceste blocuri de listă.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "creează listă cu";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Adăugaţi un element la listă.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Creaţi o listă cu orice număr de elemente.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primul";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# de la sfârșit";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "obţine";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "obţine şi elimină";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ultimul";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "aleator";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "elimină";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returnează primul element dintr-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returneaza elementul la poziţia specificată într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returnează ultimul element într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returneaza un element aleatoriu într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Elimină şi returnează primul element într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Elimină şi returneaza elementul la poziţia specificată într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Elimină şi returnează ultimul element într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Elimină şi returnează un element aleatoriu într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Elimină primul element într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Elimină elementul la poziţia specificată într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Elimină ultimul element într-o listă.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Elimină un element aleatoriu într-o listă.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "la # de la sfarsit";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "la #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "la ultima";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "obţine sub-lista de la primul";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "obţine sub-lista de la # de la sfârşitul";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "obţine sub-lista de la #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creează o copie a porţiunii specificate dintr-o listă.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 este ultimul element.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 este primul element.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Găseşte prima apariţie a elementului";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "găseşte ultima apariţie a elementului";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Revine la indexul de la prima/ultima apariție a elementului din listă. Returnează %1 dacă elementul nu este găsit.";
                +Blockly.Msg["LISTS_INLIST"] = "în listă";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 este gol";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returnează adevărat dacă lista este goală.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "lungime de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returnează lungimea unei liste.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "creaza lista cu %1 elemente repetate de %2 ori";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creează o listă alcătuită dintr-o anumită valoare repetată de numărul specificat de ori.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "ca";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "introduceţi la";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "seteaza";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserează elementul la începutul unei liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserează elementul la poziţia specificată într-o listă.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Adăugă elementul la sfârşitul unei liste.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserează elementul aleatoriu într-o listă.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Setează primul element într-o listă.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Setează elementul la poziţia specificată într-o listă.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Setează ultimul element într-o listă.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Setează un element aleator într-o listă.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "convertește textul în listă";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "convertește lista în text";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Concatenează o listă de texte (alternate cu separatorul) într-un text unic";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Împarte textul într-o listă de texte, despărțite prin fiecare separator";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "cu separatorul";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "fals";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returnează adevărat sau fals.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "adevărat";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Returnează adevărat dacă ambele intrări sunt egale.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Returnează adevărat dacă prima intrare este mai mare decât a doua intrare.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Returnează adevărat dacă prima intrare este mai mare sau egală cu a doua intrare.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Returnează adevărat dacă prima intrare este mai mică decât a doua intrare.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Returnează adevărat dacă prima intrare este mai mică sau egală cu a doua intrare.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Returnează adevărat daca cele două intrări nu sunt egale.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "non %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returnează adevărat dacă intrarea este falsă.  Returnează fals dacă intrarea este adevărată.";
                +Blockly.Msg["LOGIC_NULL"] = "nul";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "returnează nul.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "şi";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "sau";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Returnează adevărat daca ambele intrări sunt adevărate.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Returnează adevărat dacă cel puţin una din intrări este adevărată.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "dacă este fals";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "dacă este adevărat";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Verifică condiţia din \"test\". Dacă condiţia este adevărată, returnează valoarea \"în cazul în care adevărat\"; în caz contrar întoarce valoarea \"în cazul în care e fals\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ro.wikipedia.org/wiki/Aritmetic%C4%83";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Returnează suma a două numere.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Returnează câtul celor două numere.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Returneaza diferenţa dintre cele două numere.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Returnează produsul celor două numere.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Returneaza numărul rezultat prin ridicarea primului număr la puterea celui de-al doilea.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "schimbă %1 de %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Adaugă un număr variabilei '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ro.wikipedia.org/wiki/Constant%C4%83_matematic%C4%83";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Întoarcă una din constantele comune: π (3.141...), e (2.718...), φ (1,618...), sqrt(2) (1.414...), sqrt(½) (0.707...) sau ∞ (infinitate).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrânge %1 redus %2 ridicat %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrânge un număr să fie între limitele specificate (inclusiv).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "este divizibil cu";
                +Blockly.Msg["MATH_IS_EVEN"] = "este par";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "este negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "este impar";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "este pozitiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "este prim";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Verifică dacă un număr este un par, impar, prim, întreg, pozitiv, negativ, sau dacă este divizibil cu un anumit număr.  Returnează true sau false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "este întreg";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "restul la %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Întoarce restul din împărţirea celor două numere.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Un număr.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "media listei";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maximul listei";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "media listei";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimul listei";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "moduri de listă";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "element aleatoriu din lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviația standard a listei";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma listei";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Întoarce media (aritmetică) a valorilor numerice în listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Întoarce cel mai mare număr din listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Întoarce numărul median în listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Returnează cel mai mic număr din listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Returnează o listă cu cel(e) mai frecvent(e) element(e) din listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Returnează un element aleatoriu din listă.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Întoarce deviația standard a listei.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Returnează suma tuturor numerelor din lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fracții aleatorii";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Returnează o fracţie aleatoare între 0.0 (inclusiv) si 1.0 (exclusiv).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "un număr întreg aleator de la %1 la %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Returnează un număr întreg aleator aflat între cele două limite specificate, inclusiv.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "rotund";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "rotunjit";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "rotunjește în sus";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Rotunjirea unui număr în sus sau în jos.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolută";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "rădăcina pătrată";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Returnează valoarea absolută a unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Returnează e la puterea unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Întoarce logaritmul natural al unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Returnează logaritmul în baza 10 a unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Returnează negaţia unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Returnează 10 la puterea unui număr.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Returnează rădăcina pătrată a unui număr.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "arccos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctg";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ro.wikipedia.org/wiki/Funcții_trigonometrice";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tg";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Returnează arccosinusul unui număr.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Returnează arcsinusul unui număr.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Returnează arctangenta unui număr.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Întoarce cosinusul unui grad (nu radianul).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Întoarce cosinusul unui grad (nu radianul).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Întoarce tangenta unui grad (nu radianul).";
                +Blockly.Msg["NEW_VARIABLE"] = "Variabilă nouă...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Noul nume de variabilă:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permite declarațiile";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "cu:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Executați funcția '%1 'definită de utilizator.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Executați funcția '%1 'definită de utilizator şi folosiţi producţia sa.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "cu:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Creaţi '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "fă ceva";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "la";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Crează o funcţie cu nici o ieşire.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://ro.wikipedia.org/wiki/Subrutină";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "returnează";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creează o funcţie cu o ieşire.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Atenţie: Această funcţie are parametri duplicaţi.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Evidenţiază definiţia funcţiei";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Dacă o valoare este adevărată, atunci returnează valoarea a doua.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Avertisment: Acest bloc poate fi utilizat numai în definiţia unei funcţii.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nume de intrare:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Adaugă un parametru de intrare pentru funcție.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "intrări";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Adăugă, șterge sau reordonează parametrii de intrare ai acestei funcții.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Elimină comentariu";
                +Blockly.Msg["RENAME_VARIABLE"] = "Redenumirea variabilei...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Redenumeşte toate variabilele '%1' în:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Adăugaţi text la variabila '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "la litere mici";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "către Titlul de caz";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "la MAJUSCULE";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Întoarce o copie a textului într-un caz diferit.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "obţine prima litera";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "obţine litera # de la sfârșit";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "obtine litera #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "obţine o litera oarecare";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "obtine o litera oarecare";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returnează litera la poziția specificată.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Adaugă un element în text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "alăturaţi-vă";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Adaugă, elimină sau reordonează secțiuni ca să reconfigureze blocul text.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "la litera # de la sfarsit";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "la litera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "la ultima literă";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "în text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "obţine un subșir de la prima literă";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "obține un subșir de la litera # de la sfârșit";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "obține subșir de la litera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returnează o anumită parte din text.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "găseşte prima apariţie a textului";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "găseşte ultima apariţie a textului";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returnează indicele primei/ultimei apariţii din primul text în al doilea text.  Returnează %1 dacă textul nu este găsit.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 este gol";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returnează adevărat dacă textul furnizat este gol.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "crează text cu";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Creaţi o bucată de text prin unirea oricărui număr de elemente.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "lungime de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returnează numărul de litere (inclusiv spaţiile) în textul furnizat.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "imprimare %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Afișează textul specificat, numărul sau altă valoare.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Solicită utilizatorul pentru un număr.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Solicită utilizatorul pentru text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "solicită pentru număr cu mesaj";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "solicită pentru text cu mesaj";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "O literă, cuvânt sau linie de text.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "taie spațiile de pe ambele părți ale";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "tăiaţi spațiile din partea stângă a";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "taie spațiile din partea dreaptă a";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Returnează o copie a textului fără spațiile de la unul sau ambele capete.";
                +Blockly.Msg["TODAY"] = "Astăzi";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Crează 'set %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returnează valoarea acestei variabile.";
                +Blockly.Msg["VARIABLES_SET"] = "seteaza %1 la %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Crează 'get %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Setează această variabilă sa fie egală la intrare.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ru.js b/blockly/webif/static/blockly/msg/js/ru.js
                new file mode 100644
                index 000000000..fc1d4dffa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ru.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ru');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Добавить комментарий";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Невозможно удалить переменную '%1', поскольку она является частью определения функции '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Измените значение:";
                +Blockly.Msg["CLEAN_UP"] = "Убрать блоки";
                +Blockly.Msg["COLLAPSE_ALL"] = "Свернуть блоки";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Свернуть блок";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "цвет 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "цвет 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "доля цвета 1";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "смешать";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Смешивает два цвета в заданном соотношении (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://ru.wikipedia.org/wiki/Цвет";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Выберите цвет из палитры.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "случайный цвет";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Выбирает цвет случайным образом.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "синего";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зелёного";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "красного";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "цвет из";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Создаёт цвет с указанной пропорцией  красного, зеленого и синего.  Все значения должны быть между 0 и 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "выйти из цикла";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "перейти к следующему шагу цикла";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Прерывает этот цикл.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Пропускает остаток цикла и переходит к следующему шагу.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Предупреждение: этот блок может использоваться только внутри цикла.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "для каждого элемента %1 в списке %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Для каждого элемента в списке, присваивает переменной '%1' значение элемента  и выполняет указанные  команды.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "цикл по %1 от %2 до %3 с шагом %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Присваивает переменной '%1' значения от начального до конечного с заданным шагом и выполняет указанные команды.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Добавляет условие к блоку \"если\"";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Добавить заключительный подблок для случая, когда все условия ложны.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Добавьте, удалите, переставьте фрагменты для переделки блока \"если\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "иначе";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "иначе если";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "если";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Если условие истинно, выполняет команды.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Если условие истинно, выполняет первый блок команд. Иначе выполняется второй блок команд.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Если первое условие истинно, то выполняет первый блок команд. Иначе, если второе условие истинно, выполняет второй блок команд.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Если первое условие истинно, то выполняет первый блок команд.  В противном случае, если второе условие истинно, выполняет второй блок команд.  Если ни одно из условий не истинно, выполняет последний блок команд.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://ru.wikipedia.org/wiki/Цикл_(программирование)";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "выполнить";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "повторить %1 раз";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Выполняет некоторые команды несколько раз.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "повторять, пока не";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "повторять, пока";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Пока значение ложно, выполняет команды";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Пока значение истинно, выполняет команды.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Удалить все блоки (%1)?";
                +Blockly.Msg["DELETE_BLOCK"] = "Удалить блок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Удалить переменную '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Удалить %1 использований переменной '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Удалить %1 блоков";
                +Blockly.Msg["DISABLE_BLOCK"] = "Отключить блок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Скопировать";
                +Blockly.Msg["ENABLE_BLOCK"] = "Включить блок";
                +Blockly.Msg["EXPAND_ALL"] = "Развернуть блоки";
                +Blockly.Msg["EXPAND_BLOCK"] = "Развернуть блок";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Вставки снаружи";
                +Blockly.Msg["HELP"] = "Справка";
                +Blockly.Msg["INLINE_INPUTS"] = "Вставки внутри";
                +Blockly.Msg["IOS_CANCEL"] = "Отмена";
                +Blockly.Msg["IOS_ERROR"] = "Ошибка";
                +Blockly.Msg["IOS_OK"] = "ОК";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Добавить входную переменную";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Разрешить операторы";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "У этой функции есть дублирующиеся входные переменные.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ВХОД";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Добавить";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Добавить переменную";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Удалить";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Вы не можете использовать пустое имя переменной.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Переименовать";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Имя переменной";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "создать пустой список";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Возвращает список длины 0, не содержащий данных";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "список";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Добавьте, удалите, переставьте элементы для переделки блока списка.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "создать список из";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Добавляет элемент к списку.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Создаёт список с любым числом элементов.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "первый";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "№ с конца";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "взять";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "взять и удалить";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "последний";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "произвольный";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "удалить";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Возвращает первый элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Возвращает элемент в указанной позиции списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Возвращает последний элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Возвращает случайный элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Удаляет и возвращает первый элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Удаляет и возвращает элемент в указанной позиции списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Удаляет и возвращает последний элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Удаляет и возвращает случайный элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Удаляет первый элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Удаляет элемент в указанной позиции списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Удаляет последний элемент списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Удаляет случайный элемент списка.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "по № с конца";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "по №";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "по последний";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "взять подсписок с первого";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "взять подсписок с № с конца";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "взять подсписок с №";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Создаёт копию указанной части списка.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 - последний элемент.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 - первый элемент.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "найти первое вхождение элемента";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "найти последнее вхождение элемента";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Возвращает номер позиции первого/последнего вхождения элемента в списке. Возвращает %1, если элемент не найден.";
                +Blockly.Msg["LISTS_INLIST"] = "в списке";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 пуст";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Возвращает значение истина, если список пуст.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "длина %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Возвращает длину списка.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "создать список из элемента %1, повторяющегося %2 раз";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Создаёт список, состоящий из заданного числа копий элемента.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "изменить порядок на обратный %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Изменить порядок списка на обратный.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "=";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "вставить в";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "присвоить";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Вставляет элемент в начало списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Вставляет элемент в указанной позиции списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Добавляет элемент в конец списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Вставляет элемент в случайное место в списке.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Присваивает значение первому элементу списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Присваивает значение элементу в указанной позиции списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Присваивает значение последнему элементу списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Присваивает значение случайному элементу списка.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "по возрастанию";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "по убыванию";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "сортировать %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Сортировать копию списка.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "по алфавиту, без учёта регистра";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "числовая";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "по алфавиту";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "сделать список из текста";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "собрать текст из списка";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Соединяет сптсок текстов в один текст с разделителями.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Разбивает текст в список текстов, по разделителям.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "с разделителем";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ложь";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Возвращает значение истина или ложь.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "истина";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://ru.wikipedia.org/wiki/Неравенство";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Возвращает положительное значение, если вводы равны.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Возвращает значение истина, если первая вставка больше второй.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Возвращает значение истина, если первая вставка больше или равна  второй.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Возвращает положительное значение, если первый ввод меньше второго.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Возвращает значение истина, если первая вставка меньше или равна  второй.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Возвращает положительное значение, если вводы не равны.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "не %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Возвращает значение истина, если вставка ложна.  Возвращает значение ложь, если вставка истинна.";
                +Blockly.Msg["LOGIC_NULL"] = "ничто";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Возвращает ничто.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "и";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "или";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Возвращает значение истина, если обе вставки истинны.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Возвращает значение истина, если хотя бы одна из вставок истинна.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "выбрать по";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://ru.wikipedia.org/wiki/Тернарная_условная_операция";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "если ложь";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "если истина";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Проверяет условие выбора. Если условие истинно, возвращает первое значение, в противном случае возвращает второе значение.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ru.wikipedia.org/wiki/Арифметика";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Возвращает сумму двух чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Возвращает частное от деления первого числа на второе.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Возвращает разность двух чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Возвращает произведение двух чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Возвращает первое число, возведённое в степень второго числа.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B8%D0%BE%D0%BC%D0%B0_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29#.D0.98.D0.BD.D0.BA.D1.80.D0.B5.D0.BC.D0.B5.D0.BD.D1.82";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "увеличить %1 на %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Добавляет число к переменной '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ru.wikipedia.org/wiki/Математическая_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Возвращает одну из распространённых  констант: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) или ∞ (бесконечность).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "ограничить %1 снизу %2 сверху %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Ограничивает число нижней и верхней границами (включительно).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "делится на";
                +Blockly.Msg["MATH_IS_EVEN"] = "чётное";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "отрицательное";
                +Blockly.Msg["MATH_IS_ODD"] = "нечётное";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "положительное";
                +Blockly.Msg["MATH_IS_PRIME"] = "простое";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Проверяет, является ли число чётным, нечётным, простым, целым, положительным, отрицательным или оно кратно определённому числу.  Возвращает значение истина или ложь.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "целое";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://ru.wikipedia.org/wiki/Деление_с_остатком";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "остаток от %1 : %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Возвращает остаток от деления двух чисел.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ru.wikipedia.org/wiki/Число";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Число.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "среднее арифметическое списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "наибольшее в списке";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "медиана списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "наименьшее в списке";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "моды списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "случайный элемент списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "стандартное отклонение списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "сумма списка";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Возвращает среднее арифметическое списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Возвращает наибольшее число списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Возвращает медиану списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Возвращает наименьшее число списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Возвращает список наиболее часто встречающихся элементов списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Возвращает случайный элемент списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Возвращает стандартное отклонение списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Возвращает сумму всех чисел в списке.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://ru.wikipedia.org/wiki/Генератор_псевдослучайных_чисел";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "случайное число от 0 (включительно) до 1";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Возвращает случайное число от 0.0 (включительно) до 1.0.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://ru.wikipedia.org/wiki/Генератор_псевдослучайных_чисел";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "случайное целое число от %1 для %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Возвращает случайное число между двумя заданными пределами (включая и их).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://ru.wikipedia.org/wiki/Округление";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "округлить";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "округлить к меньшему";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "округлить к большему";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Округляет число до большего или меньшего.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ru.wikipedia.org/wiki/Квадратный_корень";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "модуль";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "квадратный корень";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Возвращает модуль числа";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Возвращает е в указанной степени.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Возвращает натуральный логарифм числа.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Возвращает десятичный логарифм числа.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Возвращает противоположное число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Возвращает 10 в указанной степени.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Возвращает квадратный корень числа.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ru.wikipedia.org/wiki/Тригонометрические_функции";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Возвращает арккосинус (в градусах).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Возвращает арксинус (в градусах).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Возвращает арктангенс (в градусах)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Возвращает косинус угла в градусах.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Возвращает синус угла в градусах.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Возвращает тангенс угла в градусах.";
                +Blockly.Msg["NEW_VARIABLE"] = "Создать переменную…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Имя новой переменной:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "разрешить операторы";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "с:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://ru.wikipedia.org/wiki/Подпрограмма";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Исполняет определённую пользователем процедуру '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://ru.wikipedia.org/wiki/Подпрограмма";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Исполняет определённую пользователем процедуру '%1' и возвращает вычисленное  значение.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "с:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Создать вызов '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Опишите эту функцию…";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "выполнить что-то";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "чтобы";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Создаёт процедуру, не возвращающую значение.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "вернуть";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Создаёт процедуру, возвращающую значение.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Предупреждение: эта функция имеет повторяющиеся параметры.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Выделить определение процедуры";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Если первое значение истинно, возвращает второе значение.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Предупреждение: Этот блок может использоваться только внутри определения функции.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "имя параметра:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Добавить входной параметр в функцию.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "параметры";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Добавить, удалить или изменить порядок входных параметров для этой функции.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Процедура с именем '%1' уже существует.";
                +Blockly.Msg["REDO"] = "Повторить";
                +Blockly.Msg["REMOVE_COMMENT"] = "Удалить комментарий";
                +Blockly.Msg["RENAME_VARIABLE"] = "Переименовать переменную…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Переименовать все переменные '%1' в:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "к %1 добавить текст %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Добавить текст к переменной «%1».";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "в строчные буквы";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "в Заглавные Начальные Буквы";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "в ЗАГЛАВНЫЕ БУКВЫ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Возвращает копию текста с ЗАГЛАВНЫМИ или строчными буквами.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "взять первую букву";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "взять букву № с конца";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "взять букву №";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "взять последнюю букву";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "взять случайную букву";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "в тексте %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Возвращает букву в указанной позиции.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "подсчитать количество %1 в %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Подсчитать, сколько раз отрывок текста появляется в другом тексте.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Добавить элемент к тексту.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "соединить";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Добавьте, удалите, переставьте фрагменты для переделки текстового блока.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "по букву № с конца";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "по букву №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "по последнюю букву";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "в тексте";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "взять подстроку с первой буквы";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "взять подстроку с буквы № с конца";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "взять подстроку с буквы №";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Возвращает указанную часть текста.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "найти первое вхождение текста";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "найти последнее вхождение текста";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "в тексте %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Возвращает номер позиции первого/последнего вхождения первого текста во  втором.  Возвращает %1, если текст не найден.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 пуст";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Возвращает значение истина, если предоставленный текст пуст.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "создать текст из";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Создаёт фрагмент текста, объединяя любое число элементов";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "длина %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Возвращает число символов (включая пробелы) в заданном тексте.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "напечатать %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Печатает текст, число или другой объект.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Запросить у пользователя число.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Запросить у пользователя текст.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "запросить число с подсказкой";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "запросить текст с подсказкой";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "заменить %1 на %2 в %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Заменить все вхождения некоторого текста другим текстом.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "изменить порядок на обратный %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Меняет порядок символов в тексте на обратный.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ru.wikipedia.org/wiki/Строковый_тип";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Буква, слово или строка текста.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "обрезать пробелы с двух сторон";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "обрезать пробелы слева";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "обрезать пробелы справа";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Возвращает копию текста с пробелами, удалеными с одного или обоих концов.";
                +Blockly.Msg["TODAY"] = "Сегодня";
                +Blockly.Msg["UNDO"] = "Отменить";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "элемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Создать блок \"присвоить\" для %1";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Возвращает значение этой переменной.";
                +Blockly.Msg["VARIABLES_SET"] = "присвоить %1 = %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Создать вставку %1";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Присваивает переменной значение вставки.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Переменная с именем '%1' уже существует.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sc.js b/blockly/webif/static/blockly/msg/js/sc.js
                new file mode 100644
                index 000000000..969b2867d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sc.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sc');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Agiunghe unu cumentu";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Muda valori:";
                +Blockly.Msg["CLEAN_UP"] = "Lìmpia is brocus";
                +Blockly.Msg["COLLAPSE_ALL"] = "Serra e stringi Brocus";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Serra e stringi Brocu";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "colori 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "colori 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "raportu";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mestura";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Amestura duus coloris cun unu raportu (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Scebera unu colori de sa tauledda.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "Unu colori a brítiu";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Scebera unu colori a brítiu.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blue";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "birdi";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "arrùbiu";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "colora cun";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Cuncorda unu colori cun su tanti de arrubiu, birdi, e blue. Totu is valoris depint essi intra 0 e 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "sàrtiat a foras de sa lòriga";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "sighit cun su repicu afatànti";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Bessit de sa lòriga.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Sartiat su chi abarrat de sa loriga, e sighit cun su repicu afatànti.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Amonestu: Custu brocu ddu podis ponni sceti aintru de una lòriga.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "po dònnia item %1 in lista %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Po dònnia item in sa lista, ponit sa variàbili '%1' pari a s'item, e tandu fait pariga de cumandus.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "po %1 de %2 fintzas %3 a passus de %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Fait pigai a sa variàbili \"%1\" i valoris de su primu numeru a s'urtimu, a su passu impostau e fait su brocu.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Aciungi una cunditzioni a su brocu si.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Aciungi una urtima cunditzioni piga-totu a su brocu si.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu si.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "sinuncas";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "sinuncas si";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "si";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Si su valori est berus, tandu fait pariga de cumandus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Si su valori est berus, tandu fai su primu brocu de is cumandus. Sinuncas, fai su segundu brocu de is cumandus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Si su primu valori est beridadi, tandu fai su primu brocu de is cumandus. Sinuncas, si su segundu valori est beridadi, fai su segundu brocu de is cumandus.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Si su primu valori est berus, tandu fai su primu brocu de is cumandus. Sinuncas, si su segundu valori est berus, fai su segundu brocu de is cumandus. Si mancu unu valori est berus, tandu fai s'urtimu brocu de is cumandus.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "fai";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repiti %1 bortas";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Fait pariga de cumandus prus bortas.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repiti fintzas";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repiti interis";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Interis su valori est frassu, tandu fai pariga de cumandus.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Interis su valori est berus, tandu fai pariga de cumandus.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Scancellu su %1 de is brocus?";
                +Blockly.Msg["DELETE_BLOCK"] = "Fùlia Blocu";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Fulia %1 Blocus";
                +Blockly.Msg["DISABLE_BLOCK"] = "Disabìlita Blocu";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Dùplica";
                +Blockly.Msg["ENABLE_BLOCK"] = "Abìlita Blocu";
                +Blockly.Msg["EXPAND_ALL"] = "Aberi Brocus";
                +Blockly.Msg["EXPAND_BLOCK"] = "Aberi Brocu";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Intradas esternas";
                +Blockly.Msg["HELP"] = "Agiudu";
                +Blockly.Msg["INLINE_INPUTS"] = "Intradas in lìnia";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "fait una lista buida";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Torrat una lista, de longària 0, chena records de datus.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "fait una lista cun";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Acciungi unu item a sa lista.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Fait una lista cun calisiollat numeru de items.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "primu";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# de sa fini";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "piga";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "piga e fùlia";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "urtimu";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "a brìtiu (random)";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "fùlia";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Torrat su primu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Torrat s'elementu de su postu inditau de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Torrat s'urtimu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Torrat un'elementu a brìtiu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Fùliat e torrat su primu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Fùliat e torrat s'elementu de su postu inditau de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Fùliat e torrat s'urtimu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Fùliat e torrat un'elementu a brìtiu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Fùliat su primu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Fùliat s'elementu de su postu inditau de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Fùliat s'urtimu elementu de una lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Fùliat unu elementu a brìtiu de una lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "a # de sa fini";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "fintzas a #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "a s'urtimu";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "bogandi suta-lista de su primu";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "bogandi suta-lista de # de sa fini.";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "bogandi suta-lista de #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Fait una copia de sa parti inditada de sa lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 est po s'urtimu elementu.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 est po su primu elementu.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "circa prima ocasioni de s'item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "circa urtima ocasioni de s'item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Torrat s'indixi de sa primu/urtima ocasioni de s'item in sa lista. Torrat %1 si s'item non s'agatat.";
                +Blockly.Msg["LISTS_INLIST"] = "in lista";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 est buidu";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Torrat berus si sa lista est buida.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "longària de %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Torrat sa longària de una lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "fait una lista cun item %1 repitiu %2 bortas";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Fait una lista cun unu numeru giau repitiu su tanti de is bortas inditadas.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "a";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "inserta a";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "imposta";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Insertat s'elementu a su cumintzu de sa lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Insertat s'elementu in su postu inditau in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Aciungit s'elementu a sa fini de sa lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Aciungit s'elementu a brítiu in sa lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Impostat su primu elementu in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Impostat s'elementu in su postu inditau de una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Impostat s'urtimu elementu in una lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Impostat unu elementu random in una lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "fai una lista de unu testu";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "fai unu testu de una lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Auni una lista de testus in d-unu sceti, ponendi separadoris.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dividi su testu in un'elencu de testus, firmendi po dònnia separadori.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "cun  separadori";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "frassu";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Torrat berus o frassu.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "berus";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Torrat berus si is inputs funt unu uguali a s'àteru.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Torrat berus si su primu input est prus mannu de s'àteru.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Torrat berus si su primu input est prus mannu o uguali a s'àteru.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Torrat berus si su primu input est prus piticu de s'àteru.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Torrat berus si su primu input est prus piticu o uguali a s'àteru.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Torrat berus si is inputs non funt unu uguali a s'àteru.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "non %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Torrat berus si s'input est frassu. Torrat frassu si s'input est berus.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Torrat null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "and";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "or";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Torrat berus si ambos is inputs funt berus.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Torrat berus si assumancu unu de is inputs est berus.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "cumpròa";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "si frassu";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "si berus";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "‎Cumproa sa cunditzioni in 'cumproa'. Si sa cunditzioni est berus, torrat su valori 'si berus'; sinuncas torrat su valori 'si frassu'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Torrat sa summa de is duus nùmerus.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Torrat su cuotzienti de is duus nùmerus.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Torrat sa diferèntzia de is duus nùmerus.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Torrat su produtu de is duus nùmerus.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Torrat su primu numeru artziau a sa potenza de su segundu nùmeru.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "muda %1 de %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Aciungi unu numeru a sa variabili '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Torrat una de is costantis comunas: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), o ∞ (infiniu).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "custringi %1 de %2 a %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Custringi unu numeru aintru de is liminaxus giaus (cumprendius).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "fait a ddu dividi po";
                +Blockly.Msg["MATH_IS_EVEN"] = "est paris";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "est negativu";
                +Blockly.Msg["MATH_IS_ODD"] = "est dísparu";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "est positivu";
                +Blockly.Msg["MATH_IS_PRIME"] = "est primu";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Cumprova si unu numeru est paris, dìsparis, primu, intreu, positivu, negativu o si fait a ddu dividi po unu numeru giau. Torrat berus o frassu.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "est intreu";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "arrestu de %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Torrat s'arrestu de sa divisioni de duus numerus.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Unu numeru";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "mèdia de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "massimu de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "medianu de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimu de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modas de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "unu item a brìtiu de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "deviadura standard de sa lista";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "suma sa lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Torrat sa mèdia (aritimètica) de is valoris de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Torrat su numeru prus mannu de sa lista";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Torrat su numeru medianu de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Torrat su numeru prus piticu de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Torrat una lista de is itams prus frecuentis de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Torrat unu item a brìtiu de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Torrat sa deviadura standard de sa lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Torrat sa suma de totu is numerus de sa lista.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "una fratzioni a brìtiu";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Torrat una fratzioni a brìtiu intra 0.0 (cumpresu) e 1.0 (bogau).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "numeru intreu a brítiu de %1 a %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Torrat unu numeru intreu a brìtiu intra duus nùmerus giaus (cumpresus).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "arretunda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "arretunda faci a bàsciu.";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "Arretunda faci a susu";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Arretunda unu numeru faci a susu o faci a bàsciu.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "assolutu";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "arraxina cuadra";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Torrat su valori assolútu de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Torrat (e) a sa potèntzia de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Torrat su logaritmu naturali de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Torrat su logaritmu a basi 10 de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Torrat su valori negau de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Torrat (10) a sa potèntzia de unu numeru.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Torrat s'arraxina cuadra de unu numeru.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Torrat su arccosinu de unu numeru.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Torrat su arcsinu de unu numeru.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Torrat su arctangenti de unu numeru.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Torrat su cosinu de unu gradu (no radianti).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Torrat su sinu de unu gradu (no radianti).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Torrat sa tangenti de unu gradu (no radianti).";
                +Blockly.Msg["NEW_VARIABLE"] = "Variabili noa...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nòmini de sa variabili noa:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "permiti decraratzionis";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "con:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Arròllia sa funtzione '%1' cuncordada dae s'impitadore.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Arròllia sa funtzione '%1' cuncordada dae s'impitadore e imprea s'output suu.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "cun";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Ingenerau'%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "fait calincuna cosa";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "po";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Fait una funtzioni chena output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "torrat";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Fait una funtzioni cun output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Amonestu: Custa funtzioni tenit parametrus duplicaus.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Marca sa definitzioni de funtzioni.";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Si unu valori est berus, tandu torrat unu segundu valori.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Amonestu: Custu brocu ddu podis ponni sceti aintru de una funtzioni.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "nomini input:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Aciungi un input a sa funtzioni.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Aciungi, fùlia, o assenta is inputs a custa funtzioni.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Fùlia unu cumentu";
                +Blockly.Msg["RENAME_VARIABLE"] = "Muda nòmini a variabili...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "A is variabilis '%1' muda nòmini a:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Aciungit testu a sa variàbili '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "a minúdu";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "cun Primu lìtera a Mauschínu";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "a mauschínu";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Torrat una copia de su testu inditau mudendi mauschínu/minúdu.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "piga sa prima lìtera";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "piga sa lìtera # de sa fini";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "piga sa lìtera #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "piga s'urtima lìtera";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "piga una lìtera a brìtiu";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Torrat sa lìtera de su postu giau.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Acciungi unu item a su testu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "auni a pari";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu de testu.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "a sa lìtera # de sa fini";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "a sa lìtera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "a s'urtima lìtera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in su testu";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "piga suta-stringa de sa primu lìtera";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "piga suta-stringa de sa lìtera # fintzas a fini";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "piga suta-stringa de sa lìtera #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Torrat su testu inditau.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "circa prima ocasioni de su testu";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "circa urtima ocasioni de su testu";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Torrat s'indixi de sa primu/urtima ocasioni de su primu testu in su segundu testu. Torrat %1 si su testu no ddu agatat.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 est buidu";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Torrat berus si su testu giau est buidu.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "scri testu cun";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Fait unu testu ponendi a pari parigas de items.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "longària de %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Torrat su numeru de lìteras (cun is spàtzius) in su testu giau.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "scri %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Scri su testu, numeru o àteru valori.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Pregonta unu nùmeru a s'impitadore.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Pregonta testu a s'impitadore.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "pregonta po unu numeru";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "pregonta po su testu";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Una lìtera, paràula, o linia de testu.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "bogat spàtzius de ambus càbudus de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "bogat spàtzius de su càbudu de manca de";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "bogat spàtzius de su càbudu de dereta de";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Torrat una copia de su testu bogaus is spàtzius de unu o de ambus is càbudus.";
                +Blockly.Msg["TODAY"] = "Oe";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Fait 'imposta %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Torrat su valori de custa variabili.";
                +Blockly.Msg["VARIABLES_SET"] = "imposta %1 a %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Fait 'piga %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Imposta custa variabili uguali a s'input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sd.js b/blockly/webif/static/blockly/msg/js/sd.js
                new file mode 100644
                index 000000000..79c6cfe87
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sd.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sd');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "تاثرات ڏيو";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "قدر بدلايو";
                +Blockly.Msg["CLEAN_UP"] = "بندشون هٽايو";
                +Blockly.Msg["COLLAPSE_ALL"] = "بلاڪَ ڍڪيو";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "بلاڪ ڍڪيو";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "رنگ 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "رنگ 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "تناسب";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blend";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "ڄاڻايل تناسب سان ٻہ رنگ پاڻ ۾ ملايو (0.0-1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "رنگ دٻيءَ مان رنگ چونڊيو.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "بلا ترتيب رنگ";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "ڪو بہ ‌ڃڳ چونڊيو.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "نيرو";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "سائو";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ڳاڙهو";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "سان رڱيو";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ڳاڙهي، سائي، ۽ نيري جو مقدار ڄاڻائي گھربل رنگ ٺاهيو. سمورا قدر 0 ۽ 100 جي وچ ۾ هجن.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "چڪر مان ٻاهر نڪرو";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "چڪر جاري رکندر نئين ڦيري پايو";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for each item %1 in list %2";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "نہ تہ";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "نہ تہ جي";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "جيڪڏهن";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ڪريو";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "1٪ ڀيرا ورجايو";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ورجايو جيستائين";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ورجايو جڏهن";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "بلاڪ ڊاهيو";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "1٪ بلاڪ ڊاهيو";
                +Blockly.Msg["DISABLE_BLOCK"] = "بلاڪ کي غيرفعال بڻايو";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "نقل";
                +Blockly.Msg["ENABLE_BLOCK"] = "بلاڪ کي فعال بڻايو";
                +Blockly.Msg["EXPAND_ALL"] = "بلاڪَ نمايو";
                +Blockly.Msg["EXPAND_BLOCK"] = "بلاڪ نمايو";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "خارجي ڄاڻ";
                +Blockly.Msg["HELP"] = "مدد";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";  // untranslated
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "خالي فهرست تخليق ڪريو";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "لسٽ";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "فهرست ۾ ڪا شي شامل ڪريو.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "پهريون";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# آخر کان";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "آخري";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "بي ترتيب";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "هٽايو";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ڏانهن # آخر کان";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "ڏانهن #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "آخري ڏانهن";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "فهرست ۾";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "جيان";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "تي داخل ڪريو";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "ميڙ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ڪُوڙ";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "درست يا غير درست وراڻي ٿو.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "سچ";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "جيڪڏهن ٻئي ان پُٽس برابر آهن تہ درست وراڻيو";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان وڏو آهي تہ درست وراڻيو.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان وڏو آهي يا ٻئي برابر آهن تہ درست وراڻيو.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان ننڍو آهي تہ درست وراڻيو";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان ننڍو آهي يا ٻئي برابر آهن تہ درست وراڻيو";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "جيڪڏهن ٻئي ان پُٽس اڻ برابر آهن تہ درست وراڻيو";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "نڪي %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "ان پُٽ غير درست آهي تہ درست وراڻيو. ان پُٽ درست آهي تہ غير درست وراڻيو.";
                +Blockly.Msg["LOGIC_NULL"] = "null";  // untranslated
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "۽";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "يا";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "جيڪڏهن ٻئي ان پُٽ درست آهن تہ درست وراڻيو.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "جيڪڏهن ٻنهي ان پُٽس مان ڪو هڪ بہ درست آهي تہ درست وراڻيو.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "جيڪڏهن ڪوڙو";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "جيڪڏهن سچو";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "ٻن انگن جي جوڙ اپت ڏيو.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "ٻنهي انگن جي ونڊ ڏيو.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "ٻنهي انگن جو تفاوت ڏيو.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "ٻنهي انگن جي ضرب اُپت ڏيو.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%1 کي %2 سان مَٽايو";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/رياضياتي استقلال";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "سان ونڊجندڙ آهي";
                +Blockly.Msg["MATH_IS_EVEN"] = "ٻڌي آهي";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ڪاٽو آهي";
                +Blockly.Msg["MATH_IS_ODD"] = "اِڪي آهي";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "واڌو آهي";
                +Blockly.Msg["MATH_IS_PRIME"] = "مفرد آهي";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "سڄو آهي";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";  // untranslated
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "ڪو انگ.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "لسٽ جي سراسري";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "لسٽ جو وڏي ۾ وڏو قدر";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "لسٽ جو مڌيان";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "لسٽ جو ننڍي ۾ ننڍو قدر";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "فهرست جو وچور";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "لسٽ ۾ وڏي کان وڏو قدر ڄاڻايو.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "لسٽ جو مڌيان انگ ڄاڻايو.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "لسٽ ۾ ننڍي کان ننڍو قدر ڄاڻايو.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "هيٺ ڦيرايو (رائونڊ ڊائون)";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ويڙهيو (رائونڊ اَپ)";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/ٻيون مول";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "ٺپ";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ٻيون مول";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "ڪنهن انگ جو قدرتي لاگ ڄاڻايو.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "ڪنهن انگ جو 10 بنيادي لاگ ڄاڻايو.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "ڪنهن انگ جو ڪاٽو ڄاڻايو.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ڪنهن انگ جو ٻيون مول ڄاڻايو.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/ٽڪنڊور ڪاڄ";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "نئون ڦرڻو...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "ڦرڻي جو نئون نالو:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "سان:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "سان:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "تخليق ڪريو '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "ڪجھ ڪريو";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "ڏانهن";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "واپس ورو";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ان پُٽس";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "ٻيهر ڪريو";
                +Blockly.Msg["REMOVE_COMMENT"] = "تاثرات مِٽايو";
                +Blockly.Msg["RENAME_VARIABLE"] = "ڦرڻي کي نئون نالو ڏيو...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";  // untranslated
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "ننڍن اکر ڏانهن";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "وڏن اکرن ڏانهن";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "شامل ٿيو";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "متن ۾";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "ڇاپيو %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "ڄاڻايل تحرير، انگ يا ڪو ٻيو قدر ڇاپيو.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "اڄ";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "اسم";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/shn.js b/blockly/webif/static/blockly/msg/js/shn.js
                new file mode 100644
                index 000000000..afd98b4fb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/shn.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.shn');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "သႂ်ႇၶေႃႈၵႂၢမ်း";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "လႅၵ်ႈလၢႆႈၼမ်ႉၵတ်ႉ";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "ပလွၵ်ႉတင်းၼမ် လႅဝ်";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ပလွၵ်ႉလႅဝ်";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "သီ 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "သီ 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "သႅၼ်း";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "လေႃးလႄး";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "ဢဝ်သီသွင်ဢၼ်လေႃးၵၼ် ၸွမ်းၼမ် သႅၼ်းဢၼ်ပၼ်ဝႆႉ (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color သီ";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "လိူၵ်ႈသီ တမ်ႈတီႈ ၽႃးလႅတ်ႉ";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "သီလၢမ်းလိမ်း";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "လိူၵ်ႈသီတမ်ႈတီႈလွၵ်းလၢမ်းလိမ်း";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "သွမ်ႇ";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "ၶဵဝ်";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "လီင်";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "ႁူမ်ႈၵိုၵ်းသီ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ႁဵတ်းတူၺ်း သီဢၼ်ၼိုင်ႈ ၸွမ်းၼင်ႇမၵ်းမၼ်ႈဝႆႉ ၼႂ်းၶႂၢင်ႇ သီလႅင်, ၶဵဝ် လႄႈ သွမ်ႇ။ ၼမ်ႉၼၵ်းသီ တေလႆႈမီးၼႂ်းဝူင်ႈၵၢင် 0 တေႃႇ 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ဢွၵ်ႇတီႈၶွပ်ႇမူၼ်း";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "သိုပ်ႇပၼ်ႇထႅင်ႈ ၶွပ်ႇမူၼ်းတၢင်ႇဢၼ်";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "ၵိုတ်းပႅတ်ႈ ၶွပ်ႇမူၼ်း ဢၼ်မီးဝႆႉ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "ဝဵၼ်ႉဝႆႉ ၶွပ်ႇမူၼ်း ဢၼ်ၵိုတ်းၸိူဝ်ႈဝႆႉ, သေ သိုပ်ႇထႅင်ႈတၢင်ႇဢၼ်";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "ၾၢင်ႉ: ပလွၵ်ႉဢၼ်ၼႆႉ ၵူၺ်းၸႂ်ႉလူၺ်ႈတႃႇ ၶွပ်ႇမူၼ်းၵူၺ်း";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "တႃႇၵူႈဢၼ်ဢၼ် ၼႂ်း %1 သဵၼ်ႈမၢႆ %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "တႄႇဢၢၼ်ႇၵိုၵ်း %1 တေႃႇ %2 တေႃႇ %3 လူၺ်ႈ %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "သင်ဝႃႈ ပလွၵ်ႉၸိုင် သႂ်ႇပၼ်လွင်ႈတၢင်းမၼ်း တမ်ႈ";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "သႂ်ႇၵမ်းလိုၼ်း, သင်ဝႃႈ ပလွၵ်ႉၸိုင် ဢဝ်လွင်ႈတၢင်းမၼ်းတင်းသဵင်ႈ တမ်ႈ";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "လိူဝ်သေၼၼ်ႉ";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "သင်ဝႃႈ လိူဝ်သေၼၼ်ႉ";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "သင်ဝႃႈ";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢၼ်ႇမႅၼ်ႈယဝ်ႉၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ လိူဝ်သေၼၼ်ႉ ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႉၼိုင်ႈ မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႆသွင်မၢၼ်ႇမႅၼ်ႈၸိုင်  ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႆၼိုင်ႈ မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ လိူဝ်သေၼၼ်ႉ, သင်ဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢႆသွင် မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ) ဢမ်ႇမီးလွင်ႈမၢၼ်ႇမႅၼ်ႈ သင်ၸိုင် ႁဵတ်းပႅတ်ႈပလွၵ်ႉ ၵမ်းလိုမ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop တႃႇတူင်ႇမူၼ်း";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ႁဵတ်း";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ပၼ်ႇၶိုၼ်း %1 ၵမ်း";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ တင်းၼမ်";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "တိုၵ်ႉလိုမ်ႉထိုင်";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ၶၢဝ်းတိုၵ်ႉလိုမ်ႉ";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) ဢမ်ႇမၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ် ၵမ်ႈၽွင်ႈ";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢၼ်ႇမႅၼ်ႈယဝ်ႉၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "မွတ်ႇပလွၵ်ႉ";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "မွတ်ႇပလွၵ်ႉ %1";
                +Blockly.Msg["DISABLE_BLOCK"] = "ဢမ်ႇၸၢင်ႈပလွၵ်ႉ";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "ထုတ်ႇ";
                +Blockly.Msg["ENABLE_BLOCK"] = "ၵမ်ႉထႅမ်ပၼ် ပလွၵ်ႉ";
                +Blockly.Msg["EXPAND_ALL"] = "ၶႂၢၵ်ႈပလွၵ်ႉတင်းၼမ်";
                +Blockly.Msg["EXPAND_BLOCK"] = "ၶႂၢၵ်ႈပလွၵ်ႉ";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ၶိူင်ႈဢၼ်လုၵ်ႉတၢင်းၼွၵ်ႈၶဝ်ႈမႃး";
                +Blockly.Msg["HELP"] = "ၸွႆႈထႅမ်";
                +Blockly.Msg["INLINE_INPUTS"] = "ၶိူင်ႈဢၼ်ၶဝ်ႈမႃးၸွမ်းလႅင်း";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "first";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# from end";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "last";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "random";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remove";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "in list";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ဢမ်ႇၼႅၼ်ႈၼႃ";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "မၢၼ်ႇမႅၼ်ႈလႄႈသင် ဢမ်ႇၼႅၼ်ႈၼႃလႄႈသင် ႁူၼ်ၶိုၼ်း";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "မၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(ပၢႆးၼပ်ႉ)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင် မိူၼ်တၢင်ႇဢၼ်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း ယႂ်ႇလိူဝ် ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း ယႂ်ႇလိူဝ် ဢမ်ႇၼၼ် ၽဵင်ႇပဵင်း ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း မိူၼ် ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း မိူၼ် ဢမ်ႇၼၼ် ၽဵင်ႇပဵင်း ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင် ဢမ်ႇမိူၼ်တၢင်ႇဢၼ်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ဢမ်ႇၸႂ်ႈ %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢမ်ႇၼႅၼ်ႈၼႃၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ။ သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢၼ်ႇမႅၼ်ႈၸိုင် ၶိုၼ်းမူၼ်ႉမႄး ႁႂ်ႈၼႅၼ်ႈၼႃ";
                +Blockly.Msg["LOGIC_NULL"] = "ဢမ်ႇၶဝ်ႈၶႂၢင်ႇ";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "လဵဝ်ၶိုၼ်း ဢမ်ႇၶဝ်ႈၶႂၢင်ႇ";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "လႄႈ";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ဢမ်ႇၼၼ်";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင်ဢၼ် မၢၼ်ႇမႅၼ်ႈၸိုင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ၵမ်းလိုၼ်းသုတ်း မၢၼ်ႇမႅၼ်ႈၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "ၸၢမ်း";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "သင်ဝႃႈ ဢမ်ႇၼႅၼ်ႈၼႃ";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "သင်ဝႃႈ မၢၼ်ႇမႅၼ်ႈ";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "ၸၢမ်းၵူတ်ႇတူၺ်း သၢႆငၢႆ။ သင်ဝႃႈ သၢႆငၢႆမၢၼ်ႇမႅၼ်ႈ, လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) 'သင်မၢၼ်ႇမႅၼ်ႈ'; လိူဝ်ၼၼ်ႉ လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) 'သင်ဢမ်ႇၼႅၼ်ႈၼႃ'။";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/ပၢႆးၼပ်ႉ";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "လဵဝ်ၶိုၼ်း တၢင်းၼမ် ၼႂ်းမၢႆၼပ်ႉ သွင်";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "လဵဝ်ၶိုၼ်း ပမႃႇၼ ၼႂ်းမၢႆၼပ်ႉ သွင်";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "လဵဝ်ၶိုၼ်း ဢၼ်ပႅၵ်ႇပိူင်ႈ ၼႂ်းမၢႆၼပ်ႉ သွင်";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "လဵဝ်ၶိုၼ်း ဢၼ်ဢဝ်ဢွၵ်ႇ ၼႂ်းမၢႆၼပ်ႉ သွင်";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "လဵဝ်ၶိုၼ်း တူဝ်ၼပ်ႉမၢႆၼိုင်ႈၼႆႉ ၸွႆႈႁႅင်းပၼ် တူဝ်ၼပ်ႉမၢႆသွင်";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";  // untranslated
                +Blockly.Msg["MATH_IS_EVEN"] = "ပဵၼ်ၵူပ်ႉ";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "is negative";  // untranslated
                +Blockly.Msg["MATH_IS_ODD"] = "ပဵၼ်ၵိၵ်ႈ";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "is positive";  // untranslated
                +Blockly.Msg["MATH_IS_PRIME"] = "is prime";  // untranslated
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";  // untranslated
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";  // untranslated
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/မၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "မၢႆၼပ်ႉ ၼိုင်ႈဢၼ်";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "average of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "max of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";  // untranslated
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root (မၢႆတူပ်ႉမိူၼ်)";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "ပၵတိ";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "မၢႆတူပ်ႉမိူၼ်";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) ပၵတိ ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "လဵဝ်ၶိုၼ်း e ၵႂႃႇတီႈ ပႃႇဝႃႇ ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "လဵဝ်ၶိုၼ်း လွၵ်းလၢႆးၼပ်ႉ ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "လဵဝ်ၶိုၼ်း ပိုၼ်ႉထၢၼ် 10 လွၵ်းလၢႆးၼပ်ႉ ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "လဵဝ်ၶိုၼ်း ဢၼ်သၢၼ်ၶတ်း ၼႂ်း မၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "လဵဝ်ၶိုၼ်း 10 ၵႂႃႇတီႈ ပႃႇဝႃႇ ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "လဵဝ်ၶိုၼ်း မၢႆတူပ်ႉမိူၼ် ၼႂ်းမၢႆၼပ်ႉ";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "လၢႆႈဢၼ်မႂ်ႇ";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "ၸိုဝ်ႈဢၼ်လၢႆႈမႂ်ႇ";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";  // untranslated
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";  // untranslated
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "ဢဝ်ဢွၵ်ႇ ၶေႃႈၵႂၢမ်း";
                +Blockly.Msg["RENAME_VARIABLE"] = "လိုမ်ႉၶိုၼ်း ဢၼ်လၢႆႈမႂ်ႇ";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "လိုမ်ႉၶိုၼ်း ဢၼ်လၢႆႈမႂ်ႇၸိူဝ်းၼၼ်ႉ '%1' ထိုင်";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";  // untranslated
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "မိူဝ်ႈၼႆႉ";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "ဢၼ်";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";  // untranslated
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";  // untranslated
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";  // untranslated
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sk.js b/blockly/webif/static/blockly/msg/js/sk.js
                new file mode 100644
                index 000000000..b6ff2a2c2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sk.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sk');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Pridať komentár";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Zmeniť hodnotu:";
                +Blockly.Msg["CLEAN_UP"] = "Narovnať bloky";
                +Blockly.Msg["COLLAPSE_ALL"] = "Zvinúť bloky";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Zvinúť blok";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "farba 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "farba 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "pomer";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "zmiešať";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Zmieša dve farby v danom pomere (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Zvoľte farbu z palety.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "náhodná farba";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Zvoliť farbu náhodne.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "modrá";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zelená";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "červená";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "ofarbiť s";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Vytvoriť farbu pomocou zadaného množstva červenej, zelenej a modrej. Množstvo musí byť medzi 0 a 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "opustiť slučku";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "prejdi na nasledujúce opakovanie slučky";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Opustiť túto slučku.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Vynechať zvyšok tejto slučky a pokračovať ďalším opakovaním.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Upozornenie: Tento blok sa môže používať len v rámci slučky.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "pre každý prvok %1 v zozname %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Pre každý prvok v zozname priraď jeho hodnotu do premenej '%1' a vykonaj príkazy.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "počítať s %1 od %2 do %3 o %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Nechá premennú '%1' nadobúdať hodnoty od začiatočného čísla po konečné s daným medzikrokom a vykoná zadané bloky.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Pridať podmienku k \"ak\" bloku.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Pridať poslednú záchytnú podmienku k \"ak\" bloku.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Pridať, odstrániť alebo zmeniť poradie oddielov tohto \"ak\" bloku.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "inak";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "inak ak";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ak";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Ak je hodnota pravda, vykonaj príkazy.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Ak je hodnota pravda, vykonaj príkazy v prvom bloku. Inak vykonaj príkazy v druhom bloku.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ak je prvá hodnota pravda, vykonaj príkazy v prvom bloku. Inak, ak je druhá hodnota pravda, vykonaj príkazy v druhom bloku.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ak je prvá hodnota pravda, vykonaj príkazy v prvom bloku. Inak, ak je druhá hodnota pravda, vykonaj príkazy v druhom bloku. Ak ani jedna hodnota nie je pravda, vykonaj príkazy v poslednom bloku.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "rob";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "opakuj %1 krát";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Opakuj určité príkazy viackrát.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "opakuj kým nebude";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "opakuj kým";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Kým je hodnota nepravdivá, vykonávaj príkazy.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Kým je hodnota pravdivá, vykonávaj príkazy.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Zmazať všetkých %1 dielcov?";
                +Blockly.Msg["DELETE_BLOCK"] = "Odstrániť blok";
                +Blockly.Msg["DELETE_VARIABLE"] = "Odstrániť premennú '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Odstrániť %1 použití premennej '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Odstrániť %1 blokov";
                +Blockly.Msg["DISABLE_BLOCK"] = "Vypnúť blok";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplikovať";
                +Blockly.Msg["ENABLE_BLOCK"] = "Povoliť blok";
                +Blockly.Msg["EXPAND_ALL"] = "Rozvinúť bloky";
                +Blockly.Msg["EXPAND_BLOCK"] = "Rozvinúť blok";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Vonkajšie vstupy";
                +Blockly.Msg["HELP"] = "Pomoc";
                +Blockly.Msg["INLINE_INPUTS"] = "Riadkové vstupy";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "prázdny zoznam";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Vráti zoznam nulovej dĺžky, ktorý neobsahuje žiadne prvky.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "zoznam";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Pridaj, odstráň alebo zmeň poradie v tomto zoznamovom bloku.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "vytvor zoznam s";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Pridaj prvok do zoznamu.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Vytvor zoznam s ľubovoľným počtom prvkov.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "prvý";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# od konca";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "zisti";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "zisti a odstráň";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "posledný";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "náhodný";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "odstráň";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Vráti počiatočný prvok zoznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Vráti prvok na určenej pozícii v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Vráti posledný prvok zoznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Vráti náhodný prvok zoznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Odstráni a vráti prvý prvok v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Odstráni a vráti prvok z určenej pozície v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Odstráni a vráti posledný prvok v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Odstráni a vráti náhodný prvok v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Odstráni prvý prvok v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Odstráni prvok na určenej pozícii v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Odstráni posledný prvok v zozname.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Odstráni náhodný prvok v zozname.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "po # od konca";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "po #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "po koniec";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "Získať podzoznam od začiatku";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "Získať podzoznam od # od konca";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "získať podzoznam od #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Skopíruje určený úsek zoznamu.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 je posledný prvok.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 je počiatočný prvok.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "nájdi prvý výskyt prvku";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "nájdi posledný výskyt prvku";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Vráti index prvého/posledného výskytu prvku v zozname. Ak sa nič nenašlo, vráti %1.";
                +Blockly.Msg["LISTS_INLIST"] = "v zozname";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 je prázdny";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Vráti pravda, ak je zoznam prázdny.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "dĺžka %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Vráti dĺžku zoznamu";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "vytvor zoznam s prvkom %1 opakovaným %2 krát";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Vytvorí zoznam s niekoľkými rovnakými prvkami s danou hodnotou.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "ako";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "vložiť na";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "nastaviť";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Vsunie prvok na začiatok zoznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Vsunie prvok na určenú pozíciu v zozname.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Pripojí prvok na koniec zoznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Vsunie prvok na náhodné miesto v zozname.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Nastaví prvý prvok v zozname.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Nastaví prvok na určenej pozícii v zozname.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Nastaví posledný prvok v zozname.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Nastaví posledný prvok v zozname.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "Vzostupne";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "Zostupne";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "zoradiť %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Zoradiť kópiu zoznamu.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "abecedne, ignorovať veľkosť písmen";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numericky";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "abecedne";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "vytvoriť zoznam z textu";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "vytvoriť text zo zoznamu";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Spojiť zoznam textov do jedného textu s oddeľovačmi.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Rozdelenie textu do zoznamu textov, lámanie na oddeľovačoch.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "s oddeľovačom";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "nepravda";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Vráť buď hodnotu pravda alebo nepravda.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "pravda";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Vráť hodnotu pravda, ak sú vstupy rovnaké.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Vráť hodnotu pravda ak prvý vstup je väčší než druhý.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Vráť hodnotu pravda ak prvý vstup je väčší alebo rovný druhému.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Vráť hodnotu pravda, ak prvý vstup je menší než druhý.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Vráť hodnotu pravda ak prvý vstup je menší alebo rovný druhému.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Vráť hodnotu pravda, ak vstupy nie sú rovnaké.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "nie je %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Vráti hodnotu pravda, ak je vstup nepravda. Vráti hodnotu nepravda ak je vstup pravda.";
                +Blockly.Msg["LOGIC_NULL"] = "nič";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Vráti hodnotu nula.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "a";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "alebo";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Vráť hodnotu pravda, ak sú vstupy pravdivé.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Vráť hodnotu pravda, ak je aspoň jeden vstup pravda.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ak nepravda";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ak pravda";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Skontroluj podmienku testom. Ak je podmienka pravda, vráť hodnotu \"ak pravda\", inak vráť hodnotu \"ak nepravda\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Vráť súčet dvoch čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Vráť podiel dvoch čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Vráť rozdiel dvoch čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Vráť súčin dvoch čísel.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Vráť prvé číslo umocnené druhým.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "zmeniť %1 o %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Pridaj číslo do premennej \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant‎";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Vráť jednu zo zvyčajných konštánt: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), alebo ∞ (nekonečno).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "obmedz %1 od %2 do %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Obmedzí číslo do zadaných hraníc (vrátane).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "je deliteľné";
                +Blockly.Msg["MATH_IS_EVEN"] = "je párne";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "je záporné";
                +Blockly.Msg["MATH_IS_ODD"] = "je nepárne";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "je kladné";
                +Blockly.Msg["MATH_IS_PRIME"] = "je prvočíslo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Skontroluj či je číslo párne, nepárne, celé, kladné, záporné alebo deliteľné určitým číslom. Vráť hodnotu pravda alebo nepravda.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "je celé číslo";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "zvyšok po delení %1 + %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Vráť zvyšok po delení jedného čísla druhým.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Číslo.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "priemer zoznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "najväčšie v zozname";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "medián zoznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "najmenšie v zozname";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "najčastejšie v zozname";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "náhodný prvok zoznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "smerodajná odchýlka zoznamu";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "súčet zoznamu";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Vráť aritmetický priemer čísel v zozname.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Vrátiť najväčšie číslo v zozname.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Vráť medián čísel v zozname.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Vrátiť najmenšie číslo v zozname.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Vrátiť najčastejší prvok v zozname.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Vráť náhodne zvolený prvok zoznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Vráť smeroddajnú odchýlku zoznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Vráť súčet všetkých čísel v zozname.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "náhodné číslo od 0 do 1";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Vráť náhodné číslo z intervalu 0.0 (vrátane) až 1.0.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "náhodné celé číslo od %1 do %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Vráť náhodné celé číslo z určeného intervalu (vrátane).";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "zaokrúhli";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "zaokrúhli nadol";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "zaokrúhli nahor";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Zaokrúhli číslo nahor alebo nadol.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolútna hodnota";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "druhá odmocnina";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Vráť absolútnu hodnotu čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Vráť e umocnené číslom.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Vráť prirodzený logaritmus čísla.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Vráť logaritmus čísla so základom 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Vráť opačné číslo.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Vráť 10 umocnené číslom.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Vráť druhú odmocninu čísla.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "arccos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Vráť arkus kosínus čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Vráť arkus sínus čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Vráť arkus tangens čísla.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Vráť kosínus uhla (v stupňoch).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Vráť sínus uhla (v stupňoch).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Vráť tangens uhla (v stupňoch).";
                +Blockly.Msg["NEW_VARIABLE"] = "Vytvoriť premennú...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Názov novej premennej:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "povoliť príkazy";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "s:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Spustí používateľom definovanú funkciu '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Spustí používateľom definovanú funkciu '%1' a použije jej výstup.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "s:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Vytvoriť '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Doplň, čo robí táto funkcia...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "urob niečo";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "na";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Vytvorí funciu bez výstupu.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "vrátiť";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Vytvorí funkciu s výstupom.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Upozornenie: Táto funkcia má duplicitné parametre.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Zvýrazniť definíciu funkcie";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Ak je hodnota pravda, tak vráti druhú hodnotu.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Upozornenie: Tento blok môže byť len vo vnútri funkcie.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "názov vstupu:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Pridať vstup do funkcie.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "vstupy";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Pridať, odstrániť alebo zmeniť poradie vstupov tejto funkcie.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Znova";
                +Blockly.Msg["REMOVE_COMMENT"] = "Odstrániť komentár";
                +Blockly.Msg["RENAME_VARIABLE"] = "Premenovať premennú...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Premenovať všetky premenné '%1' na:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Pridaj určitý text do premennej '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "na malé písmená";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "na Veľké Začiatočné Písmená";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "na VEĽKÉ PÍSMENÁ";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Vráť kópiu textu s inou veľkosťou písmen.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "zisti prvé písmeno";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "zisti # písmeno od konca";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "zisti písmeno #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "zisti posledné písmeno";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "vyber náhodné písmeno";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Vráti písmeno na určenej pozícii.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "počet výskytov %1 v %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Počet výskytov textu nachádzajúcom sa v inom texte.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Pridaj prvok do textu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "spoj";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Pridaj, odstráň alebo zmeň poradie oddielov v tomto textovom bloku.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "po # písmeno od konca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "po písmeno #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "po koniec";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "v texte";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "vyber podreťazec od začiatku";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "vyber podreťazec od # písmena od konca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "vyber podreťazec od písmena #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Vráti určenú časť textu.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "nájdi prvý výskyt textu";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "nájdi posledný výskyt textu";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Vráti index prvého/posledného výskytu prvého textu v druhom texte. Ak nenájde, vráti %1.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 je prázdny";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Vráti hodnotu pravda, ak zadaný text je prázdny.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "vytvor text z";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Vytvor text spojením určitého počtu prvkov.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "dĺžka %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Vráti počet písmen (s medzerami) v zadanom texte.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "píš %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Napíš zadaný text, číslo alebo hodnotu.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Výzva pre používateľa na zadanie čísla.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Výzva pre používateľa na zadanie textu.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "výzva na zadanie čísla so správou";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "výzva za zadanie textu so správou";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "zameniť %1 za %2 v reťazci %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Zameniť všetky výskyty textu za iný text.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "text odzadu %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Obrátiť poradie písmen v texte.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Písmeno, slovo alebo riadok textu.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "odstráň medzery z oboch strán";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "odstráň medzery z ľavej strany";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "odstráň medzery z pravej strany";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Vráť kópiu textu bez medzier na jednom alebo oboch koncoch.";
                +Blockly.Msg["TODAY"] = "Dnes";
                +Blockly.Msg["UNDO"] = "Späť";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "prvok";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Vytvoriť \"nastaviť %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Vráti hodnotu tejto premennej.";
                +Blockly.Msg["VARIABLES_SET"] = "nastaviť %1 na %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Vytvoriť \"získať %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Nastaví túto premennú, aby sa rovnala vstupu.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Premenná s názvom %1 už existuje.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sl.js b/blockly/webif/static/blockly/msg/js/sl.js
                new file mode 100644
                index 000000000..b24957385
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sl.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sl');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Dodaj komentar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Spremeni vrednost:";
                +Blockly.Msg["CLEAN_UP"] = "Ponastavi kocke";
                +Blockly.Msg["COLLAPSE_ALL"] = "Skrči kocke";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Skrči kocko";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "barva 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "barva 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "razmerje";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "mešanica";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Zmeša dve barvi v danem razmerju (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Izberi barvo s palete.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "naključna barva";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Izbere naključno barvo.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "modra";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "zelena";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "rdeča";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "določena barva";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Ustvari barvo z določeno količino rdeče, zelene in modre. Vse vrednosti morajo biti med 0 in 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "izstopi iz zanke";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "nadaljuj z naslednjo ponovitvijo zanke";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Izstopi iz trenutne zanke.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Preskoči preostanek te zanke in nadaljuje z naslednjo ponovitvijo.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Pozor: To kocko lahko uporabiš samo znotraj zanke.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "za vsak element %1 v seznamu %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Za vsak element v seznamu, nastavi spremenljivko '%1' na ta element. Pri tem se izvedejo določene kocke.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "štej s/z %1 od %2 do %3 s korakom %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Vrednost spremenljivke '%1' se spreminja od začetnega števila do končnega števila, z določenim korakom. Pri tem se izvedejo določene kocke.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Dodaj pogoj »če« kocki.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Dodaj končni pogoj »če« kocki.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Dodaj, odstrani ali spremeni vrstni red odsekov za ponovno nastavitev »če« kocke.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "sicer";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "sicer če";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "če";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Če je vrednost resnična, izvedi določene kocke.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Če je vrednost resnična, izvedi prvo skupino kock. Sicer izvedi drugo skupino kock.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Če je prva vrednost resnična, izvedi prvo skupino kock. Sicer, če je resnična druga vrednost, izvedi drugo skupino kock.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Če je prva vrednost resnična, izvedi prvo skupino kock. Sicer, če je resnična druga vrednost, izvedi drugo skupino kock. Če nobena izmed vrednosti ni resnična, izvedi zadnjo skupino kock.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "izvedi";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ponavljaj %1 krat";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Kocke se izvedejo večkrat.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ponavljaj dokler";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ponavljaj";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Kocke se izvajajo dokler je vrednost neresnična.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Kocke se izvajajo dokler je vrednost resnična.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Izbrišem vseh %1 kock?";
                +Blockly.Msg["DELETE_BLOCK"] = "Izbriši kocko";
                +Blockly.Msg["DELETE_VARIABLE"] = "Izbriši spremenljivko »%1«";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Izbrišem %1 uporab spremenljivke »%2«?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Izbriši kocke";
                +Blockly.Msg["DISABLE_BLOCK"] = "Onemogoči kocko";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Podvoji";
                +Blockly.Msg["ENABLE_BLOCK"] = "Omogoči kocko";
                +Blockly.Msg["EXPAND_ALL"] = "Razširi kocke";
                +Blockly.Msg["EXPAND_BLOCK"] = "Razširi kocko";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Vnosi zunaj";
                +Blockly.Msg["HELP"] = "Pomoč";
                +Blockly.Msg["INLINE_INPUTS"] = "Vnosi v vrsti";
                +Blockly.Msg["IOS_CANCEL"] = "Prekliči";
                +Blockly.Msg["IOS_ERROR"] = "Napaka";
                +Blockly.Msg["IOS_OK"] = "V redu";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Ime spremenljivke";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "ustvari prazen seznam";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Vrne seznam, dolžine 0, ki ne vsebuje nobenih podatkov.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "seznam";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Doda, odstrani ali spremeni vrstni red elementov tega seznama.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "ustvari seznam s/z";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Doda element seznamu.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Ustvari seznam s poljubnim številom elementov.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "prvo mesto";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "mesto št. od konca";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "št.";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "vrni";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "odstrani in vrni";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "zadnje mesto";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "naključno mesto";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "odstrani";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Vrne prvi element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Vrne element na določenem mestu v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Vrne zadnji element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Vrne naključni element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Odstrani in vrne prvi element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Odstrani in vrne element na določenem mestu v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Odstrani in vrne zadnji element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Odstrani in vrne naključni element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Odstrani prvi element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Odstrani element na določenem mestu v seznamu.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Odstrani zadnji element seznama.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Odstrani naključni element seznama.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "do mesta št. od konca";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "do mesta št.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "do zadnjega mesta";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "ustvari podseznam od prvega mesta";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "ustvari podseznam od mesta št. od konca";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "ustvari podseznam od mesta št.";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Ustvari nov seznam, kot kopijo določenega dela seznama.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Zadnji element je št. %1.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Prvi element je št. %1.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "najdi prvo pojavitev elementa";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "najdi zadnjo pojavitev elementa";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Vrne mesto (indeks) prve/zadnje pojavitve elementa v seznamu. Če elementa ne najde, vrne %1.";
                +Blockly.Msg["LISTS_INLIST"] = "v seznamu";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 je prazen";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Vrne resnično, če je seznam prazen.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "dolžina %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Vrne dolžino seznama.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "ustvari seznam z elementom %1, ki se ponovi %2 krat";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Ustvari seznam z danim elementom, ki se poljubno mnogo krat ponovi.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "element";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "vstavi na";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "nastavi na";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Vstavi element na začetek seznama.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Vstavi element na določeno mesto v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Doda element na konec seznama.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Vstavi element na naključno mesto v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Nastavi prvi element seznama.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Nastavi element na določenem mestu v seznamu.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Nastavi zadnji element seznama.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Nastavi naključni element seznama.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "naraščajoče";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "padajoče";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "uredi %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Uredi kopijo seznama.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "abecedno, brez velikosti črk";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "številčno";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "abecedno";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "ustvari seznam iz besedila";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "ustvari besedilo iz seznama";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Združi seznam besedil v eno besedilo, ločeno z ločilom.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Razdruži besedilo v seznam besedil. Za razdruževanje besedila uporabi ločilo.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "z ločilom";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "neresnično";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Vrne resnično ali neresnično.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "resnično";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Vrne resnično, če sta vnosa enaka.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Vrne resnično, če je prvi vnos večji od drugega.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Vrne resnično, če je prvi vnos večji ali enak drugemu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Vrne resnično, če je prvi vnos manjši od drugega.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Vrne resnično, če je prvi vnos manjši ali enak drugemu.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Vrne resnično, če vnosa nista enaka.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ne %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Vrne resnično, če je vnos neresničen. Vrne neresnično, če je vnos resničen.";
                +Blockly.Msg["LOGIC_NULL"] = "prazno";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Vrne prazno.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "in";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ali";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Vrne resnično, če sta oba vnosa resnična.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Vrne resnično, če je vsaj eden od vnosov resničen.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "če neresnično";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "če resnično";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Preveri pogoj v »testu«. Če je pogoj resničen, potem vrne vrednost »če resnično«; sicer vrne vrednost »če neresnično«.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Vrne vsoto dveh števil.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Vrne kvocient dveh števil.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Vrne razliko dveh števil.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Vrne zmnožek dveh števil.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Vrne prvo število na potenco drugega števila.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "spremeni %1 za %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Prišteje število k spremenljivki '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Vrne eno izmed običajnih konstant: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ali ∞ (neskončno).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_%28graphics%29";
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "omeji %1 na najmanj %2 in največ %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Omeji število, da bo med določenima (vključenima) mejama.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "je deljivo s/z";
                +Blockly.Msg["MATH_IS_EVEN"] = "je sodo";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "je negativno";
                +Blockly.Msg["MATH_IS_ODD"] = "je liho";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "je pozitivno";
                +Blockly.Msg["MATH_IS_PRIME"] = "je praštevilo";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Preveri, če je število sodo, liho, praštevilo, celo, pozitivno, negativno ali, če je deljivo z določenim številom. Vrne resnično ali neresnično.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "je celo";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "ostanek pri %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Vrne ostanek pri deljenju dveh števil.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Število.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "povprečje seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "maksimum seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minimum seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modus seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "naključni element seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standardni odklon seznama";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "vsota seznama";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Vrne povprečje (aritmetično sredino) števil na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Vrne največje število na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Vrne mediano števil na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Vrne najmanjše število na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Vrne seznam najpogostejšega elementa(-ov) na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Vrne naključno število izmed števil na seznamu.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Vrne standardni odklon seznama.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Vrne vsoto vseh števil na seznamu.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "naključni ulomek";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Vrne naključni ulomek med (vključno) 0.0 in 1.0 (izključno).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "naključno število med %1 in %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Vrne naključno število med dvema določenima mejama, vključno z mejama.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "zaokroži";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "zaokroži navzdol";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "zaokroži navzgor";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Zaokroži število navzgor ali navzdol.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolutno";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadratni koren";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Vrne absolutno vrednost števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Vrne e na potenco števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Vrne naravni logaritem števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Vrne desetiški logaritem števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Vrne negacijo števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Vrne 10 na potenco števila.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Vrne kvadratni koren števila.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Vrne arkus kosinus števila.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Vrne arkus sinus števila.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Vrne arkus tangens števila.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Vrne kosinus kota v stopinjah (ne radianih).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Vrne sinus kota v stopinjah (ne radianih).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Vrne tangens kota v stopinjah (ne radianih).";
                +Blockly.Msg["NEW_VARIABLE"] = "Ustvari spremenljivko ...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Ime nove spremenljivke:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "dovoli korake";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "s/z:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Izvede uporabniško funkcijo '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Izvede uporabniško funkcijo '%1' in uporabi njen izhod.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "s/z:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Ustvari '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Opišite funkcijo ...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "nekaj";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "izvedi";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Ustvari funkcijo brez izhoda.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "vrni";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Ustvari funkcijo z izhodom.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Pozor: Ta funkcija ima podvojene parametre.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Označi definicijo funkcije";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Če je vrednost resnična, vrne drugo vrednost.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Pozor: To kocko lahko uporabiš samo znotraj definicije funkcije.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "ime vnosa:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Funkciji doda vnos.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "vnosi";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Doda, odstrani ali spremeni vrstni red vnosov te funkcije.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Ponovi";
                +Blockly.Msg["REMOVE_COMMENT"] = "Odstrani komentar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Preimenuj spremenljivko...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Preimenuj vse spremenljivke '%1' v:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Doda besedilo k spremenljivki '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "v male črke";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "v Velike Začetnice";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "v VELIKE ČRKE";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Vrne kopijo besedila v drugi obliki.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "vrni prvo črko";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "vrni črko št. od konca";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "vrni črko št.";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "vrni zadnjo črko";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "vrni naključno črko";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Vrne črko na določenem mestu v besedilu.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Doda element k besedilu.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "združi";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Doda, odstrani ali spremeni vrstni red elementov tega besedila.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "do črke št. od konca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "do črke št.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "do zadnje črke";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "iz besedila";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "vrni del od prve črke";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "vrni del od črke št. od konca";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "vrni del od črke št.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Vrne določen del besedila.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "najdi prvo pojavitev besedila";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "najdi zadnjo pojavitev besedila";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Vrne mesto (indeks) prve/zadnje pojavitve drugega besedila v prvem besedilu. Če besedila ne najde, vrne %1.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 je prazno";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Vrne resnično, če je določeno besedilo prazno.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ustvari besedilo iz";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Ustvari besedilo tako, da združi poljubno število elementov.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "dolžina %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Vrne število črk oz. znakov (vključno s presledki) v določenem besedilu.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "izpiši %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Izpiše določeno besedilo, število ali drugo vrednost.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Vpraša uporabnika za vnos števila.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Vpraša uporabnika za vnos besedila.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "vprašaj za število s sporočilom";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "vprašaj za besedilo s sporočilom";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Črka, beseda ali vrstica besedila.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "odstrani presledke z obeh strani";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "odstrani presledke z leve strani";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "odstrani presledke z desne strani";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Vrne kopijo besedila z odstranjenimi presledki z ene ali obeh strani.";
                +Blockly.Msg["TODAY"] = "Danes";
                +Blockly.Msg["UNDO"] = "Razveljavi";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "element";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Ustvari 'nastavi %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Vrne vrednost spremenljivke.";
                +Blockly.Msg["VARIABLES_SET"] = "nastavi %1 na %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Ustvari 'vrni %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Nastavi, da je vrednost spremenljivke enaka vnosu.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Spremenljivka »%1« že obstaja.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sq.js b/blockly/webif/static/blockly/msg/js/sq.js
                new file mode 100644
                index 000000000..63102e8d6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sq.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sq');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Vendos nje Koment";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ndrysho Vlerat:";
                +Blockly.Msg["CLEAN_UP"] = "Pastro blloqet";
                +Blockly.Msg["COLLAPSE_ALL"] = "Mbyll blloqet";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Mbyll bllokun";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "Ngjyra 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "Ngjyra 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "Perpjesetim";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "Përzierje";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Perzien dy ngjyra së bashku me një raport të dhënë (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "http://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Zgjidh nje ngjyre nga nje game ngjyrash.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "ngjyre e rastesishme";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Zgjidhni një ngjyrë në mënyrë të rastësishme.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blu";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "jeshile";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "e kuqe";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "ngjyre me";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Krijo një ngjyrë me shumën e specifikuar te te kuqes, te gjelbëres, dhe bluse. Te gjitha vlerat duhet te jene mes 0 dhe 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "dil nga nje faze perseritese";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "vazhdo me elementin tjeter te nje faze perseritese";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Ndahu nga unaza.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Kapërce pjesën e mbetur të unazës, dhe vazhdo me ripërsëritjen tjetër.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Paralajmërim: Ky bllok mund të përdoret vetëm brenda unazës.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "per cdo produkt %1 ne liste %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Per cdo produkt ne nje \"liste\" \"vendos\" ndryshoren '%1' produktit, dhe pastaj bej disa deklarata.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "numero me %1 nga %2 ne %3 me nga %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Bëje identifikuesin \"%1\" që ta ketë vlerat prej numrit të fillimit deri tek numri i fundit, duke numëruar nga intervali i specifikuar, dhe ti bëj blloqet e specifikuara.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "\"Vendos\" \"kushtein\"tek \"pjesa\" \"if\"";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Shto një përfundues, që i mbërrin të gjitha kushtet në bllokun nëse.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këte bllok nëse.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "përndryshe";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "përndryshe nëse";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "nëse";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Nëse një vlerë është e saktë, atëherë ekzekuto disa fjali.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Nëse një vlerë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, ekzekuto bllokun e dytë të fjalive.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Nëse vlera e parë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, nëse vlera e dytë është e saktë, ekzekuto bllokun e dytë të fjalive.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Nëse vlera e parë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, nëse vlera e dytë është e saktë, ekzekuto bllokun e dytë të fjalive. Nëse asnjëra nga vlerat nuk është e saktë, ekzekuto bllokun e fundit të fjalive.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "http://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ekzekuto";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "përsërit %1 herë";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Ekzekuto disa fjali disa herë.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "përsërit derisa";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "përsërit përderisa";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Përderisa një vlerë është e pasaktë, atëherë ekzekuto disa fjali.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Përderisa një vlerë është e saktë, atëherë ekzekuto disa fjali.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Fshijë të gjitha %1 të blloqeve?";
                +Blockly.Msg["DELETE_BLOCK"] = "Fshij bllokun";
                +Blockly.Msg["DELETE_VARIABLE"] = "Fshi variablën '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Fshi përdorimin %1 të variablës '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Fshij %1 blloqe";
                +Blockly.Msg["DISABLE_BLOCK"] = "Çaktivizo bllokun";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kopjo";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktivizo bllokun";
                +Blockly.Msg["EXPAND_ALL"] = "Zmadho blloqet";
                +Blockly.Msg["EXPAND_BLOCK"] = "Zmadho bllokun";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Hyrjet e jashtme";
                +Blockly.Msg["HELP"] = "Ndihmë";
                +Blockly.Msg["INLINE_INPUTS"] = "Hyrjet e brendshme";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "krijo një listë të zbrazët";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Kthen një listë, te gjatësisë 0, duke mos përmbajtur asnjë regjistrim të të dhënave";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "listë";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këtë bllok të listës.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "krijo listë me";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Shto një send në listë.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Krijo një listë me ndonjë numbër të sendeve.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "i parë";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# nga fundi";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "merr";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "merr dhe fshij";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "i fundit";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "i rastësishëm";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "largo";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Rikthen tek artikulli i par në list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Kthen një send në pozicionin e specifikuar në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Kthen artikullin e fundit në list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Kthen një send të rastësishëm në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Fshin dhe kthen sendin e parë në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Fshin dhe kthen sendin në pozicionin e specifikuar në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Fshin dhe kthen sendin e fundit në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Fshin dhe kthen një send të rastësishëm në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Fshin sendin e parë në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Fshin sendin në pozicionin e specifikuar në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Fshin sendin e fundit në listë.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Kthen një send të rastësishëm në listë.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "tek # nga fundi";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "tek #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "tek i fundit";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "merr nën-listën nga i pari";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "merr nën listën nga # nga fundi";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "merr nën-listën nga #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Krijon në kopje të pjesës së specifikuar të listës.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 është sendi i fundit.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 është sendi i parë.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "gjen ndodhjen e parë të sendit";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "gjen ndodhjen e fundit të sendit";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Kthen indeksin e ndodhjes së parë/fudit të sendit në listë. Kthen %1 nëse teksti nuk është gjetur.";
                +Blockly.Msg["LISTS_INLIST"] = "në listë";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 është e zbraztë";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Kthehet i saktë nëse lista është e zbraztë.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "gjatësia e %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Kthen gjatësinë e listës.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "krijo listën me sendin %1 të përsëritur %2 herë";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Krijon në listë qe përmban vlerën e dhënë të përsëritur aq herë sa numri i specifikuar.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "sikurse";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "fut në";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "vendos";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Fut sendin në fillim të listës.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Fut sendin në pozicionin e specifikuar të listës.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Bashkangjit sendin në fund të listës.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Fut sendin rastësisht në listë.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Vendos sendin e parë në listë.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Vendos sendin në pozicionin e specifikuar në listë.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Vendos sendin e fundit në listë.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Vendos një send të rastësishëm në listë.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ngjitje";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "zbritje";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "rendit %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Rendit një kopje të listës.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetike, injoro madhësinë e shkronjave";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numerike";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetike";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "bëj listë nga teksti";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "bëj tekst nga lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "e pasaktë";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Kthehet ose të saktë ose të pasaktë.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "e saktë";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "http://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Ktheje të saktë nëse të dy hyrjet janë të barabarta me njëra-tjetrën.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Ktheje të saktë nëse hyrja e parë është më e madhe se hyrja e dytë.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Ktheje të saktë nëse hyrja e parë është më e madhe ose e barabartë me hyrjen e dytë.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Ktheje të saktë nëse hyrja e parë është më e vogël se hyrja e dytë.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Ktheje të saktë nëse hyrja e parë është më e vogël ose e barabartë me hyrjen e dytë.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Ktheje të saktë nëse të dy hyrjet nuk janë të barabarta me njëra-tjetrën.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "jo %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Kthehet e saktë nëse hyrja është e pasaktë. Kthehet e pasaktë nëse hyrja është e saktë.";
                +Blockly.Msg["LOGIC_NULL"] = "pavlerë";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "http://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Kthehet e pavlerë.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "dhe";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ose";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Kthehet të saktë nëse të dy hyrjet janë të sakta.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Kthehet e saktë nëse së paku njëra nga hyrjet është e saktë.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "http://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "nëse e pasaktë";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "nëse e saktë";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kontrollo kushtin në 'test'. Nëse kushti është i saktë, kthen vlerën 'nëse e saktë'; përndryshe kthen vlerën 'nëse e pasaktë'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "http://sq.wikipedia.org/wiki/Aritmetika";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Kthen shumën e dy numrave.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Kthen herësin e dy numrave.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Kthen ndryshimin e dy numrave.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Kthen produktin e dy numrave.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Kthen numrin e parë të ngritur në fuqinë e numrit të dytë.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "http://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "ndrysho %1 nga %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Shto një numër në ndryshoren '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "http://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Kthen një nga konstantet e përbashkëta: : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infiniti).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "detyro %1 e ulët %2 e lartë %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Vëni një numër që të jetë në mes të kufive të specifikuara(përfshirëse).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "është i pjestueshme me";
                +Blockly.Msg["MATH_IS_EVEN"] = "është çift";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "është negativ";
                +Blockly.Msg["MATH_IS_ODD"] = "është tek";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "është pozitiv";
                +Blockly.Msg["MATH_IS_PRIME"] = "është prim";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrollo nëse një numër është çift, tek, prim, i plotë, pozitiv, negativ, ose nëse është i pjestueshëm me një numër të caktuar. Kthehet e saktë ose e pasaktë.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "është i plotë";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "http://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "mbetësi i %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Kthen mbetësin nga pjestimi i dy numrave.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "x";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "http://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Një numër.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "mesatarja e listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "numri më i madh i listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "mediana e listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "numri më i ulët i listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modat e listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "send i rastësishëm i listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "devijimi standard i listës";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "mbledhja e listës";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Kthen mesatarën (kuptimi aritmetik) i vlerave numerike të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Kthe numrin më të madh të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Kthe numrin median të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Kthe numrin me të vogël të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Kthe listën e sendit(eve) më të zakonshme të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Kthe një element të rastësishëm nga lista.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Kthe devijimin standard të listës.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Kthe shumën e të gjithë numrave të listës.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "http://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "fraksioni i rastësishëm";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Kthe fraksionin e rastësishëm në mes të 0.0 (përfshirëse) dhe 1.0 (jopërfshirëse).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "http://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "numër i plotë i rastësishëm nga %1 deri në %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Kthe një numër të plotë të rastësishëm të dy kufijve të specifikuar, të përfshirë.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "http://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "rrumbullakësimi";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "rrumbullakësimi i ulët";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "rrumbullakësimi i lartë";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Rrumbullakësimi i numrit të lartë ose të ulët.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "http://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "rrënja katrore";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Kthen vlerën absolute të një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Kthen e në fuqinë e një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Kthen logaritmën natyrale të një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Kthen 10 logaritmet bazë të një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Kthe negacionin e një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Kthen 10 në fuqinë e një numri.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Kthen rrënjën katrore të një numri.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acosinus";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asinus";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atangjentë";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "http://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Rikthe cos-1 e nje numeri.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Rikthe sin-1 e nje numeri.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Kthe tg-1 e nje numeri.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Kthe kosinusin e nje grade (jo ne radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Kthe kosinusin e nje kendi (jo ne radiant).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Kthe tangentin e nje kendi (jo radiant).";
                +Blockly.Msg["NEW_VARIABLE"] = "Krijo variabël...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Emri i identifikatorit të ri:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "me:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Lësho funksionin e definuar nga përdoruesi '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Lëho funksionin e definuar nga përdoruesi '%1' dhe përdor daljen e tij.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "me:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Krijo '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "bëj diqka";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "te";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Krijon një funksion pa dalje.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "rikthe";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Krijon një funksion me një dalje.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Paralajmërim: Ky funksion ka parametra të dyfishuar.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Thekso definicionin e funksionit";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Nëse një vlerë është e saktë, atëherë kthe një vlerë të dytë.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Paralajmërim: Ky bllok mund të përdoret vetëm brenda definicionit të funksionit.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "Fut emrin:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "Informacioni i futur";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Ribëj";
                +Blockly.Msg["REMOVE_COMMENT"] = "Fshij komentin";
                +Blockly.Msg["RENAME_VARIABLE"] = "Ndrysho emrin variables...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Ndrysho emrin e te gjitha '%1' variablave ne :";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "shto tekst tek varibla '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "me shkronja te vogla shtypi";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Fillimi me shkronje te madhe shtypi";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "me shkronja te medha shtypi";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Kthe nje kopje te tekstit ne nje rast te ndryshem.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "merr shkronjen e pare";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "merr shkronjen # nga fundi";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "merr shkronjen #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "merr shkronjen e fundit";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "merr nje shkronje te rastesishme";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Kthe nje shkronje nga nje pozicion i caktuar.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "numro %1 në %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Shto nje gje ne tekst";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "bashkangjit";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këtë bllok teksti.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "ne shkronjen # nga fundi";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "ne shkronjen #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "tek shkronja e fundit";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "ne tekst";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "merr vlerat qe vazhdojne me shkronjen e pare";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "merr nenvargun nga shkronja # nga fundi";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "Merr nenvargun nga shkronja #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Pergjigjet me nje pjese te caktuar teksti.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "gjej rastisjen e pare te tekstit";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "gjej rastisjen e fundit te tekstit";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Pergjigjet me indeksin e pare/fundit te rastisjes se tekstit te pare ne tekstin e dyte. Pergjigjet me %1 ne qofte se teksti nuk u gjet.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 eshte bosh";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Kthehet e vertete neqoftese teksti i dhene eshte bosh.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "krijo tekst me";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Krijo nje pjese te tekstit duke bashkuar se bashku disa sende";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "gjatesi %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Pergjigjet me nje numer shkronjash (duke perfshire hapesire) ne tekstin e dhene.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "printo %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Printo tekstin e caktuar, numer ose vlere tjeter.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Kerkoji perdoruesit nje numer.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Kerkoji perdoruesit ca tekst.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "kerko nje numer me njoftim";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "kerko tekst me njoftim";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "http://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Nje shkronje, fjale, ose rresht teksti.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "prit hapesirat nga te dyja anet";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "prit hapesirat nga ana e majte";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "prit hapesirat nga ana e djathte";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Pergjigju me nje kopje te tekstit me hapesira te fshira nga njera ane ose te dyja anet.";
                +Blockly.Msg["TODAY"] = "Sot";
                +Blockly.Msg["UNDO"] = "Zhbëj";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "send";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Krijo 'vendos %1";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Pergjigjet me nje vlere te kesaj variable.";
                +Blockly.Msg["VARIABLES_SET"] = "vendos %1 ne %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Krijo 'merr %1";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Vendos kete variable te jete e barabarte me te dhenat ne hyrje.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Një variabël e quajtur '%1' tashmë ekziston.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sr.js b/blockly/webif/static/blockly/msg/js/sr.js
                new file mode 100644
                index 000000000..1eb7b3bdb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sr.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sr');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Додај коментар";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Не могу да обришем варијаблу ’%1’ јер је део дефиниције функције ’%2’";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Промените вредност:";
                +Blockly.Msg["CLEAN_UP"] = "Уклони блокове";
                +Blockly.Msg["COLLAPSE_ALL"] = "Скупи блокове";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Скупи блок";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "боја 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "боја 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "однос";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "помешај";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Помешати две боје заједно са датим односом (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://sr.wikipedia.org/wiki/Боја";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Изаберите боју са палете.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "случајна боја";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Изаберите боју насумице.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "плава";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зелена";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "црвена";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "боја са";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Креирај боју са одређеном количином црвене,зелене, и плаве. Све вредности морају бити између 0 и 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "Изађите из петље";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "настави са следећом итерацијом петље";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Напусти садржај петље.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Прескочи остатак ове петље, и настави са следећом итерацијом(понављанјем).";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Упозорење: Овај блок може да се употреби само унутар петље.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "за сваку ставку %1 на списку %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "За сваку ставку унутар листе, подеси промењиву '%1' по ставци, и онда начини неке изјаве-наредбе.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "преброј са %1 од %2 до %3 од %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Имај промењиву \"%1\" узми вредности од почетног броја до задњег броја, бројећи по одређеном интервалу, и изврши одређене блокове.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Додајте услов блоку „ако“.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Додај коначни, catch-all  (ухвати све) услове иф блока.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Додај, уклони, или преуреди делове како бих реконфигурисали овај иф блок.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "иначе";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "иначе-ако";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ако";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "ако је вредност тачна, онда изврши неке наредбе-изјаве.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "ако је вредност тачна, онда изврши први блок наредби, У супротном, изврши други блок наредби.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Ако је прва вредност тачна, онда изврши први блок наредби, у супротном, ако је друга вредност тачна , изврши други блок наредби.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Ако је прва вредност тачна, онда изврши први блок наредби, у супротном, ако је друга вредност тачна , изврши други блок наредби. Ако ни једна од вредности није тачна, изврши последнји блок наредби.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://sr.wikipedia.org/wiki/For_петља";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "изврши";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "понови %1 пута";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Одрадити неке наредбе неколико пута.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "понављати до";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "понављати док";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Док вредност није тачна, онда извршити неке наредбе.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Док је вредност тачна, онда извршите неке наредбе.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Да обришем свих %1 блокова?";
                +Blockly.Msg["DELETE_BLOCK"] = "Обриши блок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Обриши променљиву '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Да обришем %1 употреба променљиве '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Обриши %1 блокова";
                +Blockly.Msg["DISABLE_BLOCK"] = "Онемогући блок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Дуплирај";
                +Blockly.Msg["ENABLE_BLOCK"] = "Омогући блок";
                +Blockly.Msg["EXPAND_ALL"] = "Прошири блокове";
                +Blockly.Msg["EXPAND_BLOCK"] = "Прошири блок";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Спољни улази";
                +Blockly.Msg["HELP"] = "Помоћ";
                +Blockly.Msg["INLINE_INPUTS"] = "Унутрашњи улази";
                +Blockly.Msg["IOS_CANCEL"] = "Откажи";
                +Blockly.Msg["IOS_ERROR"] = "Грешка";
                +Blockly.Msg["IOS_OK"] = "У реду";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Додај унос";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Дозволи изјаве";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Ова функција има дуплициране уносе.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "УНОСИ";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Додај";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Додај варијаблу";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Обриши";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Не можете да користите празно име варијабле.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Преименуј";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Име варијабле";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "направи празан списак";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "враћа листу, дужине 0, не садржавајући  евиденцију података";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "списак";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Додајте, избришите, или преуредите делове како би се реорганизовали овај блок листе.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "направи списак са";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Додајте ставку на списак.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Креирај листу са било којим бројем ставки.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "прва";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# са краја";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "преузми";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "преузми и уклони";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "последња";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "случајна";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "уклони";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Враћа прву ставку на списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Враћа ставку на одређену позицију на листи.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Враћа последњу ставку на списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Враћа случајну ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Уклања и враћа прву ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Уклања и враћа ставку са одређеног положаја на списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Уклања и враћа последњу ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Уклања и враћа случајну ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Уклања прву ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Уклања ставку са одређеног положаја на списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Уклања последњу ставку са списка.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Уклања случајну ставку са списка.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "до # од краја";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "до #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "до последње";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "преузми подсписак од прве";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "преузми подсписак из # са краја";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "преузми подсписак од #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Прави копију одређеног дела листе.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 је последња ставка.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 је прва ставка.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "пронађи прво појављивање ставке";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "пронађи последње појављивање ставке";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Враћа број првог и/последњег уласка елемента у листу. Враћа %1 Ако елемент није пронађен.";
                +Blockly.Msg["LISTS_INLIST"] = "на списку";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 је празан";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Враћа вредност тачно ако је листа празна.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "дужина списка %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Враћа дужину списка.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "Направити листу са ставком %1 која се понавлја %2 пута";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Прави листу која се састоји од задане вредности коју понавлјамо одређени број шута.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "обрнуто %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Обрни копију списка.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "као";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "убаци на";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "постави";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Убацује ставку на почетак списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Убацује ставку на одређени положај на списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Додајте ставку на крај списка.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Убацује ставку на случајно место на списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Поставља прву ставку на списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Поставља ставку на одређени положај на списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Поставља последњу ставку на списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Поставља случајну ставку на списку.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "растуће";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "опадајуће";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "сортирај %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Сортирајте копију списка.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "азбучно, игнориши мала и велика слова";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "као бројеве";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "азбучно";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "направите листу са текста";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "да текст из листе";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Да се придружи листу текстова у један текст, подељених за раздвајање.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Поделити текст у листу текстова, разбијање на сваком граничник.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "са раздвајање";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "нетачно";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Враћа или тачно или нетачно.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "тачно";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://sr.wikipedia.org/wiki/Неједнакост";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Враћа вредност „тачно“ ако су оба улаза једнака.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Враћа вредност „тачно“ ако је први улаз већи од другог.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Враћа вредност „тачно“ ако је први улаз већи или једнак другом.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Враћа вредност „тачно“ ако је први улаз мањи од другог.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Враћа вредност „тачно“ ако је први улаз мањи или једнак другом.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Враћа вредност „тачно“ ако су оба улаза неједнака.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "није %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Враћа вредност „тачно“ ако је улаз нетачан. Враћа вредност „нетачно“ ако је улаз тачан.";
                +Blockly.Msg["LOGIC_NULL"] = "без вредности";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Враћа „без вредности“.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "и";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "или";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Враћа вредност „тачно“ ако су оба улаза тачна.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Враћа вредност „тачно“ ако је бар један од улаза тачан.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "проба";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ако је нетачно";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ако је тачно";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Провери услов у 'test'. Ако је услов тачан, тада враћа 'if true' вредност; у другом случају враћа 'if false' вредност.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Вратите збир два броја.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Враћа количник два броја.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Враћа разлику два броја.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Враћа производ два броја.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Враћа први број степенован другим.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "промени %1 за %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Додајте број променљивој „%1“.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://sr.wikipedia.org/wiki/Математичка_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "врати једну од заједничких константи: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), или ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "ограничи %1 ниско %2 високо %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Ограничава број на доње и горње границе (укључиво).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "је дељив са";
                +Blockly.Msg["MATH_IS_EVEN"] = "је паран";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "је негативан";
                +Blockly.Msg["MATH_IS_ODD"] = "је непаран";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "је позитиван";
                +Blockly.Msg["MATH_IS_PRIME"] = "је прост";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Провјерава да ли је број паран, непаран, прост, цио, позитиван, негативан, или да ли је делјив са одређеним бројем. Враћа тачно или нетачно.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "је цео";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://sr.wikipedia.org/wiki/Конгруенција";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "подсетник од %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Враћа подсетник од дељења два броја.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Неки број.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "просек списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "макс. списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "медијана списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "мин. списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "модус списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "случајна ставка списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "стандардна девијација списка";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "збир списка";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Враћа просек нумеричких вредности са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Враћа највећи број са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Враћа медијану са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Враћа најмањи број са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Враћа најчешће ставке са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Враћа случајни елемент са списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Враћа стандардну девијацију списка.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Враћа збир свих бројева са списка.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://sr.wikipedia.org/wiki/Генератор_случајних_бројева";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "случајни разломак";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Враћа случајни разломак између 0.0 (укључиво) и 1.0 (искључиво).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://sr.wikipedia.org/wiki/Генератор_случајних_бројева";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "сличајно одабрани цијели број од %1 до %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Враћа случајно одабрани цели број између две одређене границе, уклјучиво.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://sr.wikipedia.org/wiki/Заокруживање";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "заокружи";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "заокружи наниже";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "заокружи навише";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Заокружите број на већу или мању вредност.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://sr.wikipedia.org/wiki/Квадратни_корен";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "апсолутан";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "квадратни корен";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Враћа апсолутну вредност броја.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "вратити е на власти броја.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Враћа природни логаритам броја.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Враћа логаритам броја са основом 10.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Враћа негацију броја.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Враћа 10-ти степен броја.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Враћа квадратни корен броја.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "арц цос";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "арц син";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "арц тан";
                +Blockly.Msg["MATH_TRIG_COS"] = "цос";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://sr.wikipedia.org/wiki/Тригонометријске_функције";
                +Blockly.Msg["MATH_TRIG_SIN"] = "син";
                +Blockly.Msg["MATH_TRIG_TAN"] = "тан";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Враћа аркус косинус броја.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Враћа аркус броја.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Враћа аркус тангенс броја.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Враћа косинус степена (не радијан).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Враћа синус степена (не радијан).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Враћа тангенс степена (не радијан).";
                +Blockly.Msg["NEW_VARIABLE"] = "Направи променљиву…";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Име нове променљиве:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "дозволити изреке";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "са:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Покрените прилагођену функцију „%1“.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Покрените прилагођену функцију „%1“ и користи њен излаз.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "са:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Направи „%1“";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Описати ову функцију...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "урадите нешто";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "да";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Прави функцију без излаза.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "врати";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Прави функцију са излазом.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Упозорење: Ова функција има дупликате параметара.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Истакни дефиницију функције";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Уколико је вредност тачна, врати другу вредност.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Упозорење: Овај блок се може користити једино у дефиницији функције.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "назив улаза:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Додајте улазна функција.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "улази";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Да додате, уклоните или переупорядочить улаза за ову функцију.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Понови";
                +Blockly.Msg["REMOVE_COMMENT"] = "Уклони коментар";
                +Blockly.Msg["RENAME_VARIABLE"] = "Преименуј променљиву…";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Преименујте све „%1“ променљиве у:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Додајте текст на променљиву „%1“.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "малим словима";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "свака реч великим словом";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "великим словима";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Враћа примерак текста са другачијом величином слова.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "преузми прво слово";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "преузми слово # са краја";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "преузми слово #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "преузми последње слово";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "преузми случајно слово";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Враћа слово на одређени положај.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "број %1 у %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Броји колико пута се неки текст појављује унутар неког другог текста.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Додајте ставку у текст.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "спајањем";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Додај, уклони, или другачије поредај одјелке како би изнова поставили овај текст блок.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "слову # са краја";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "слову #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "последњем слову";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "у тексту";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "преузми подниску из првог слова";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "преузми подниску из слова # са краја";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "преузми подниску из слова #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Враћа одређени део текста.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "пронађи прво појављивање текста";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "пронађи последње појављивање текста";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Враћа однос првог/заднјег појавлјиванја текста у другом тексту. Врађа %1 ако текст није пронађен.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 је празан";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Враћа тачно ако је доставлјени текст празан.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "напиши текст са";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Направити дио текста спајајући различите ставке.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "дужина текста %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Враћа број слова (уклјучујући размаке) у датом тексту.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "прикажи %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Прикажите одређени текст, број или другу вредност на екрану.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Питајте корисника за број.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Питајте корисника за унос текста.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "питај за број са поруком";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "питај за текст са поруком";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "замена %1 са %2 у %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Замена свих појава неког текста унутар неког другог текста.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "обрнуто %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Обрће редослед карактера у тексту.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://sr.wikipedia.org/wiki/Ниска";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Слово, реч или ред текста.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "трим празнине са обе стране";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "скратити простор са леве стране";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "скратити простор са десне стране";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Враћа копију текста са уклонјеним простором са једног од два краја.";
                +Blockly.Msg["TODAY"] = "Данас";
                +Blockly.Msg["UNDO"] = "Опозови";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "ставка";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Направи „постави %1“";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Враћа вредност ове променљиве.";
                +Blockly.Msg["VARIABLES_SET"] = "постави %1 у %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Направи „преузми %1“";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Поставља променљиву тако да буде једнака улазу.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Променљива под именом '%1' већ постоји.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/sv.js b/blockly/webif/static/blockly/msg/js/sv.js
                new file mode 100644
                index 000000000..c59c99d30
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/sv.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.sv');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Lägg till kommentar";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Kan inte radera variabeln '%1' eftersom den är en del av definition för funktionen '%2'";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Ändra värde:";
                +Blockly.Msg["CLEAN_UP"] = "Rada upp block";
                +Blockly.Msg["COLLAPSE_ALL"] = "Fäll ihop block";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Fäll ihop block";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "färg 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "färg 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "förhållande";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "blanda";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blandar ihop två färger med ett bestämt förhållande (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://sv.wikipedia.org/wiki/Färg";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Välj en färg från paletten.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "slumpfärg";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Slumpa fram en färg.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "blå";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "grön";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "röd";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "färg med";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Skapa en färg med det angivna mängden röd, grön och blå. Alla värden måste vara mellan 0 och 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "bryt ut ur loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "fortsätta med nästa upprepning av loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Bryt ut ur den innehållande upprepningen.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Hoppa över resten av denna loop och fortsätt med nästa loop.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Varning: Detta block kan endast användas i en loop.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "för varje föremål %1 i listan %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "För varje objekt i en lista, ange variabeln '%1' till objektet, och utför sedan några kommandon.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "räkna med %1 från %2 till %3 med %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Låt variabeln \"%1\" ta värden från starttalet till sluttalet, beräknat med det angivna intervallet, och utför de angivna blocken.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Lägg till ett villkor blocket \"om\".";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Lägg till ett sista villkor som täcker alla alternativ som är kvar för \"if\"-blocket.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Lägg till, ta bort eller ändra ordningen för sektioner för att omkonfigurera blocket \"om\".";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "annars";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "annars om";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "om";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Om ett värde är sant, utför några kommandon.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Om värdet är sant, utför det första kommandoblocket. Annars utför det andra kommandoblocket.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Om det första värdet är sant, utför det första kommandoblocket. Annars, om det andra värdet är sant, utför det andra kommandoblocket.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Om det första värdet är sant, utför det första kommandoblocket. Annars, om det andra värdet är sant, utför det andra kommandoblocket. Om ingen av värdena är sanna, utför det sista kommandoblocket.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "utför";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "upprepa %1 gånger";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Utför några kommandon flera gånger.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "upprepa tills";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "upprepa medan";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Medan ett värde är falskt, utför några kommandon.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Medan ett värde är sant, utför några kommandon.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Radera alla %1 block?";
                +Blockly.Msg["DELETE_BLOCK"] = "Radera block";
                +Blockly.Msg["DELETE_VARIABLE"] = "Radera variabeln \"%1\"";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Radera %1 användningar av variabeln \"%2\"?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Radera %1 block";
                +Blockly.Msg["DISABLE_BLOCK"] = "Inaktivera block";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicera";
                +Blockly.Msg["ENABLE_BLOCK"] = "Aktivera block";
                +Blockly.Msg["EXPAND_ALL"] = "Fäll ut block";
                +Blockly.Msg["EXPAND_BLOCK"] = "Fäll ut block";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Externa inmatningar";
                +Blockly.Msg["HELP"] = "Hjälp";
                +Blockly.Msg["INLINE_INPUTS"] = "Radinmatning";
                +Blockly.Msg["IOS_CANCEL"] = "Avbryt";
                +Blockly.Msg["IOS_ERROR"] = "Fel";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Lägg till inmatning";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Tillåt kommandon";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Denna funktion har dubblettinmatningar.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INMATNINGAR";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Lägg till";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Lägg till variabel";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Radera";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Du kan inte använda ett tomt variabelnamn.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Döp om";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variabelnamn";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "skapa tom lista";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Ger tillbaka en lista utan någon data, alltså med längden 0";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "lista";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Lägg till, ta bort eller ändra ordningen på objekten för att göra om det här \"list\"-blocket.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "skapa lista med";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Lägg till ett föremål till listan.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Skapa en lista med valfritt antal föremål.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "första";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# från slutet";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "hämta";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "hämta och ta bort";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "sista";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "slumpad";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ta bort";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returnerar det första objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Ger tillbaka objektet på den efterfrågade positionen i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returnerar det sista objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returnerar ett slumpmässigt objekt i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Tar bort och återställer det första objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Tar bort och återställer objektet på den specificerade positionen i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Tar bort och återställer det sista objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Tar bort och återställer ett slumpmässigt objekt i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Tar bort det första objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Tar bort objektet på den specificerade positionen i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Tar bort det sista objektet i en lista.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Tar bort en slumpmässig post i en lista.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "till # från slutet";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "till #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "till sista";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "få underlista från första";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "få underlista från # från slutet";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "få underlista från #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Skapar en kopia av den specificerade delen av en lista.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 är det sista objektet.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 är det första objektet.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "hitta första förekomsten av objektet";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "hitta sista förekomsten av objektet";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Ger tillbaka den första/sista förekomsten av objektet i listan. Returnerar %1 om objektet inte hittas.";
                +Blockly.Msg["LISTS_INLIST"] = "i listan";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 är tom";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returnerar sant om listan är tom.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "längden på %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returnerar längden på en lista.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "skapa lista med föremålet %1 upprepat %2 gånger";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Skapar en lista som innehåller ett valt värde upprepat ett bestämt antalet gånger.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "vänd på %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Vänd på en kopia av en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "som";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "Sätt in vid";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "ange";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "sätter in objektet i början av en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Sätter in objektet vid en specificerad position i en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Lägg till objektet i slutet av en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "sätter in objektet på en slumpad position i en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Anger det första objektet i en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sätter in objektet vid en specificerad position i en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Anger det sista elementet i en lista.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sätter in ett slumpat objekt i en lista.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "stigande";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "fallande";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sortera %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sortera en kopia av en lista.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetiskt, ignorera skiftläge";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeriskt";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetiskt";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "skapa lista från text";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "skapa text från lista";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Sammanfoga en textlista till en text, som separeras av en avgränsare.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Dela upp text till en textlista och bryt vid varje avgränsare.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "med avgränsare";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "falskt";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returnerar antingen sant eller falskt.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "sant";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://sv.wikipedia.org/wiki/Olikhet";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Ger tillbaka sant om båda värdena är lika med varandra.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Ger tillbaka sant om det första värdet är större än det andra.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Ger tillbaka sant om det första värdet är större än eller lika med det andra.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Ger tillbaka sant om det första värdet är mindre än det andra.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Ger tillbaka sant om det första värdet är mindre än eller lika med det andra.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Ger tillbaka sant om båda värdena inte är lika med varandra.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "inte %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Ger tillbaka sant om inmatningen är falsk. Ger tillbaka falskt och inmatningen är sann.";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://sv.wikipedia.org/wiki/Null";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returnerar null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "och";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "eller";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Ger tillbaka sant om båda värdena är sanna.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Ger tillbaka sant om minst ett av värdena är sant.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "om falskt";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "om sant";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kontrollera villkoret i \"test\". Om villkoret är sant, ge tillbaka \"om sant\"-värdet; annars ge tillbaka \"om falskt\"-värdet.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://sv.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Returnerar summan av de två talen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Returnerar kvoten av de två talen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Returnerar differensen mellan de två talen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Returnerar produkten av de två talen.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Ger tillbaka det första talet upphöjt till det andra talet.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "ändra %1 med %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Lägg till ett tal till variabeln '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://sv.wikipedia.org/wiki/Matematisk_konstant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Returnerar en av de vanliga konstanterna: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) eller ∞ (oändligt).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "begränsa %1 till mellan %2 och %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Begränsa ett tal till att mellan de angivna gränsvärden (inkluderande).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "är delbart med";
                +Blockly.Msg["MATH_IS_EVEN"] = "är jämnt";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "är negativt";
                +Blockly.Msg["MATH_IS_ODD"] = "är ojämnt";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "är positivt";
                +Blockly.Msg["MATH_IS_PRIME"] = "är ett primtal";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrollera om ett tal är jämnt, ojämnt, helt, positivt, negativt eller det är delbart med ett bestämt tal. Returnerar med sant eller falskt.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "är helt";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "resten av %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Returnerar kvoten från divisionen av de två talen.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://sv.wikipedia.org/wiki/Tal";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Ett tal.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "medelvärdet av listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "högsta talet i listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "medianen av listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "minsta talet i listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "typvärdet i listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "slumpmässigt objekt i listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standardavvikelsen i listan";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "summan av listan";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Ger tillbaka medelvärdet (aritmetiskt) av de numeriska värdena i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Ger tillbaka det största talet i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Returnerar medianen av talen i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Ger tillbaka det minsta talet i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Ger tillbaka en lista med de(t) vanligaste objekte(t/n) i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Returnerar ett slumpmässigt element från listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Ger tillbaka standardavvikelsen i listan.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Ger tillbaka summan av alla talen i listan.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://sv.wikipedia.org/wiki/Slumptalsgenerator";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "slumpat decimaltal";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Ger tillbaka ett slumpat decimaltal mellan 0.0 (inkluderat) och 1.0 (exkluderat).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://sv.wikipedia.org/wiki/Slumptalsgenerator";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "slumpartat heltal från %1 till %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Ger tillbaka ett slumpat heltal mellan två värden, inkluderande.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://sv.wikipedia.org/wiki/Avrundning";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "avrunda";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "avrunda nedåt";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "avrunda uppåt";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Avrunda ett tal uppåt eller nedåt.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://sv.wikipedia.org/wiki/Kvadratrot";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolut";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "kvadratrot";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Returnerar absolutvärdet av ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Ger tillbaka e upphöjt i ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Returnera den naturliga logaritmen av ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Returnerar logaritmen för bas 10 av ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Returnerar negationen av ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Ger tillbaka 10 upphöjt i ett tal.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Returnerar kvadratroten av ett tal.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "arccos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "arcsin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "arctan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://sv.wikipedia.org/wiki/Trigonometrisk_funktion";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Ger tillbaka arcus cosinus (arccos) för ett tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Ger tillbaka arcus sinus (arcsin) för ett tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Ger tillbaka arcus tangens (arctan) av ett tal.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Ger tillbaka cosinus för en grad (inte radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Ger tillbaka sinus för en grad (inte radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Ger tillbaka tangens för en grad (inte radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "Skapa variabel...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Nytt variabelnamn:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "tillåta uttalanden";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Kör den användardefinierade funktionen \"%1\".";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Kör den användardefinierade funktionen \"%1\" och använd resultatet av den.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "med:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Skapa '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Beskriv denna funktion...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://sv.wikipedia.org/wiki/Funktion_%28programmering%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "göra något";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "för att";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Skapar en funktion utan output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://sv.wikipedia.org/wiki/Funktion_%28programmering%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "returnera";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Skapar en funktion med output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Varning: Denna funktion har dubbla parametrar.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Markera funktionsdefinition";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Om ett värde är sant returneras ett andra värde.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Varning: Detta block får användas endast i en funktionsdefinition.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "inmatningsnamn:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Lägg till en inmatning till funktionen.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inmatningar";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Lägg till, ta bort och ändra ordningen för inmatningar till denna funktion.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "En procedur som heter \"%1\" finns redan.";
                +Blockly.Msg["REDO"] = "Gör om";
                +Blockly.Msg["REMOVE_COMMENT"] = "Radera kommentar";
                +Blockly.Msg["RENAME_VARIABLE"] = "Byt namn på variabel...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Byt namn på alla'%1'-variabler till:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "för att %1 lägga till text %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Lägg till lite text till variabeln '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "till gemener";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "till Versala Initialer";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "till VERSALER";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Returnerar en kopia av texten i ett annat skiftläge.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "hämta första bokstaven";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "hämta bokstaven # från slutet";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "hämta bokstaven #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "hämta sista bokstaven";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "hämta slumpad bokstav";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "i texten %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Ger tillbaka bokstaven på den specificerade positionen.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "räkna %1 i %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Räkna hur många gånger en text förekommer inom en annan text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Lägg till ett föremål till texten.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "sammanfoga";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Lägg till, ta bort eller ändra ordningen för sektioner för att omkonfigurera detta textblock.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "till bokstav # från slutet";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "till bokstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "till sista bokstaven";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "i texten";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "få textdel från första bokstaven";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "få textdel från bokstav # från slutet";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "få textdel från bokstav #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Ger tillbaka en viss del av texten.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "hitta första förekomsten av texten";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "hitta sista förekomsten av texten";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "i texten %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Ger tillbaka indexet för den första/sista förekomsten av första texten i den andra texten.  Ger tillbaka %1 om texten inte hittas.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 är tom";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returnerar sant om den angivna texten är tom.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "skapa text med";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Skapa en textbit genom att sammanfoga ett valfritt antal föremål.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "längden på %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Ger tillbaka antalet bokstäver (inklusive mellanslag) i den angivna texten.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "skriv %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Skriv den angivna texten, talet eller annat värde.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Fråga användaren efter ett tal.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Fråga användaren efter lite text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "fråga efter ett tal med meddelande";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "fråga efter text med meddelande";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "ersätt %1 med %2 i %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Ersätt alla förekomster av en text inom en annan text.";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "vänd på %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Vänder på teckenordningen i texten.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://sv.wikipedia.org/wiki/Str%C3%A4ng_%28data%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "En bokstav, ord eller textrad.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "ta bort mellanrum från båda sidorna av";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "ta bort mellanrum från vänstra sidan av";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "ta bort mellanrum från högra sidan av";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Returnerar en kopia av texten med borttagna mellanrum från en eller båda ändar.";
                +Blockly.Msg["TODAY"] = "Idag";
                +Blockly.Msg["UNDO"] = "Ångra";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "föremål";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Skapa \"välj %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returnerar värdet av denna variabel.";
                +Blockly.Msg["VARIABLES_SET"] = "ange %1 till %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Skapa 'hämta %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Gör så att den här variabeln blir lika med inputen.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "En variabel som heter \"%1\" finns redan.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/ta.js b/blockly/webif/static/blockly/msg/js/ta.js
                new file mode 100644
                index 000000000..89257ceb9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/ta.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.ta');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "கருத்தை சேர்";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "மதிப்பை மாற்றவும்:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "உறுப்புகளை மரை";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "உறுப்பை மரை";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "நிறம் 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "நிறம் 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "விகிதம்";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "கலப்பு (வண்ணம்)";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "கொடுக்கப்பட்ட விகதத்தில் (0.0 - 1.0) இரு நிறங்களை கலக்குக.";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "வண்ண தட்டிலிருந்து ஒரு நிறத்தைத் தேர்ந்தெடுக்கவும்.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "தற்போக்கு நிறம்";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "தற்போக்கில் ஒரு நிறத்தை தேர்ந்தெடுக்கவும்.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "நீலம்";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "பச்சை";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "சிகப்பு";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "நிறத்துடன்";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "குறிப்பிட்ட அளவு சிவப்பு,பச்சை மற்றும் நீலம் சேர்த்து புது நிறம் உருவாக்கு. மதிப்புகள் 0 முதல் 100 வரை மட்டுமே இருக்க வேண்டும்.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "மடக்கு கட்டளையை நிறுத்து.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "மடக்கு கட்டளையின் அடுத்த இயக்கநிலைக்கு செல்";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "மடக்கு கட்டளையின் இயக்கத்தில் இருந்து நிறுத்து.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "மடக்கு கட்டளையின் மீதியை விட்டுவிட்டு அடுத்த இயக்கநிலைக்கு செல்";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "எச்சரிக்கை : மடக்கு கூற்றில் இந்த தொகுதி ஒரு முறை மட்டுமே செயல்படுத்தப் படலாம்.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "உருப்படி ஒவ்வொன்றாக %1 பட்டியலில் உள்ள %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "பட்டியலில் உள்ள உருப்படியில் ஒவ்வொன்றாக, மாறியின் பொருள் '%1' ஆக  வைக்க.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "மாறியை வைத்து எண்ண %1 %2 இல் இருந்து %3 வரை %4-இன் படியாக";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "முதல் எண்ணில்  இருந்து கடை எண் வரை எடுத்துக்கொள்ள  ஒரு மாறியை வைத்துக்கொள், குறித்த இடைவெளியை  சேர்த்தவறே தொகுதிகளை செயலாக்கு.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "ஆனால் தொகுப்பிற்கு நிபந்தனை சேர்க்க";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "ஆனால் தொகுப்பிற்கு விதிவிலக்கு காப்பை சேர்க்க";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "கட்டளைகளை தொகுப்பு திருத்துதம் செய்";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "இல்லையெனில்";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "இல்லைஆனால்";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "எனில்";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை இயக்கு.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை தொகுப்பு இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை தொகுப்பு இயக்கு.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை தொகுப்பு இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை தொகுப்பு இயக்கு. இரண்டும் இல்லை என்றால் கடைசி தொகுப்பு இயக்கு.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "செய்க";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "'%1' முரை திரும்ப செய்";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "கட்டளைகளை பல முரை செய்ய";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "பலமுரை திரும்ப செய் (முடயேனில்)";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "பலமுரை திரும்ப செய் (வரை)";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "மாறி பொய் ஆக உள்ள வரை, கட்டளைகளை இயக்கு";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "அனைத்து %1 நிரல் துண்டுகளையும் அழிக்கவா??";
                +Blockly.Msg["DELETE_BLOCK"] = "உறுப்பை நீக்கு";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 உறுப்பை நீக்கு";
                +Blockly.Msg["DISABLE_BLOCK"] = "உறுப்பை இயங்காது செய்";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "மறுநகல்";
                +Blockly.Msg["ENABLE_BLOCK"] = "உறுப்பை இயங்குமாரு செய்";
                +Blockly.Msg["EXPAND_ALL"] = "உறுப்புகளை  காட்டு";
                +Blockly.Msg["EXPAND_BLOCK"] = "உறுப்பை காட்டு";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "வெளி கருவிகளுடன் உள்ளீடு";
                +Blockly.Msg["HELP"] = "உதவி";
                +Blockly.Msg["INLINE_INPUTS"] = "சூழமைவில் உள்ளீடு";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "காலி பட்டியல் உருவாக்க";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "காலி பட்டியல் பின்கொடு.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "பட்டியல்";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "கட்டளைகளை தொகுப்பு திருத்துதம் செய்";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "வைத்து பட்டியல் உருவாக்க";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "பட்டியலில் ஒரு பொருளை சேர்க்க.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "இவ்வளவு உருப்படிகளை கொண்டு வேண்டுமாலும் ஒரு பட்டியலை உருவாக்கு.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "முதல்";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "கடைசியில் இருந்து #";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "எடு";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "பெற்று நீக்குக";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "கடைசி";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "ஏதோ ஒன்று";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "நீக்குக";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "பட்டியல் முதல் உருப்படியை பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "பட்டியலில்  இடத்தில் உருப்படி பின்கொடு.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "பட்டியல் கடைசி உருப்படியை பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "பட்டியல் சீரற்ற உருப்படியை பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "பட்டியல் முதல் உருப்படியை நீக்கியபின் பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "பட்டியலில் கேட்ட இடத்தின் உருப்படி நீக்கி பின்கொடு.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "பட்டியல் இறுதி உருப்படியை நீக்கியபின் பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "பட்டியல் சீரற்ற உருப்படியை நீக்கியபின் பின்கொடு,";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "பட்டியலில் முதல் உருப்படியை நீக்கு";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "பட்டியலில் கேட்ட இடத்தின் உருப்படி நீக்கு.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "பட்டியலில் கடைசி உருப்படியை நீக்கு";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "பட்டியல் சீரற்ற உருப்படியை நீக்கு,";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "முடிவில் இருந்து # வரை";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "# வரை";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "முடிவு வரை";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "# முதலில் இருந்து பகுதி பட்டியலை கொடு";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "# கடைசியில் இருந்து பகுதி பட்டியலை கொடு";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "பகுதி பட்டியலை # இடத்தில் இருந்து கொடு";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "குறிப்பட்ட பகுதி பட்டியலின் நகலை கொடு";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 கடைசி உருப்படி.ி";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 முதல் உருப்படி.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "உரையில் முதல் தோற்ற இடத்தை காட்டு";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "உரையில் கடைசி தோற்ற இடத்தை காட்டு";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "பட்டியலில் மதிப்பின் முதல், கடைசி தோற்ற இடத்தை பின்கொடு. காணாவிட்டால் %1 பின்கொடு.";
                +Blockly.Msg["LISTS_INLIST"] = "பட்டியலில் உள்ள";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 காலியானது";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "பட்டியல் காலியானது மெய் பின்கொடு,";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 இன் நீளம்";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "பட்டியல் நீளம் பின்கொடு";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "உருப்படி %1-யை, %2 தடவைகள் உள்ளவாறு ஒரு பட்டியலை உருவாக்கு";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "கொடுக்க பட்ட மதிப்பை, கூறியுள்ள தடவைகள் உள்ளவாறு ஒரு பட்டியலை உருவாக்கு";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "இதுபொல";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "அவ்விடத்தில் நுழை";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "நியமி";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "மதிப்பை பட்டியலின் முதலில் நுழை";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "பட்டியலில் கேட்ட இடத்தில் உருப்படியை நுழை.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "மதிப்பை பட்டியலின் முடிவில் நுழை";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "மதிப்பை பட்டியலின் சீற்ற இடத்தில் நுழை";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "மதிப்பை பட்டியலில் முதல் உருப்படியில் வை";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "பட்டியலில் கேட்ட இடத்தில் உருப்படியை வை.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "மதிப்பை பட்டியலில் கடைசி உருப்படியில் வை";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "மதிப்பை பட்டியலில் சீரற்ற உருப்படியில் வை";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "உரையில் இருந்து பட்டியல் உருவாக்கு";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "பட்டியலில் இருந்து உரை உருவாக்கு";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "வரம்புச் சுட்டியை இடையில் இட்டு, உரைதுண்டுகளை ஒன்று சேர்";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "உரையை வரம்புச் சுட்டி கொண்டு துண்டாக்கு.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "தடை எழுத்து";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "பொய்";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "மெய், அல்லது பொய் பின்கொடு.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "மெய்";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "இரண்டு மாறியும் ஈடானால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "முதல் உள்ளீடு இரண்டாவதைவிட அதிகமாக இருந்தால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "முதல் உள்ளீடு இரண்டாவதைவிட அதிகமாக அல்ல சமமாக இருந்தால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "முதல் உள்ளீடு இரண்டாவதைவிட குறைவாக இருந்தால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "முதல் உள்ளீடு இரண்டாவதைவிட குறைவாக அல்ல சமமாக இருந்தால், மெய் பின்கொடு";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "இரண்டு மாறியும் ஈடாகாவிட்டால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 இல்லை";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "மெய் ஆனால், பொய் பின்கொடு. பொய் ஆனால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_NULL"] = "பூஜியம்";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "பூஜியம் பின்கொடு";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "மற்றும்";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "அல்லது";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "இரண்டு மாறியும் மெய் ஆனால், மெய் பின்கொடு.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "ஏதேனும் ஒரு மதிப்பு மெய் ஆனால், மெய் பின்கொடு";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "சோதனை";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "பொய்யெனில்";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "மெய்யெனில்";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'test' உள்ள நிபந்தனையை சரிபார்க்கவும், நிபந்தனை மெய்யானால்,'if true'வை  பின்கொடுக்கும் இல்லையெனில்  'if false'வை  பின்கொடுக்கும்.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A4%E0%AE%AE%E0%AF%8D";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "இரு எண்களின் கூட்டை பின்கொடு";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "இரு எண்களின் வகுத்தல் பின்கொடு";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "இரு எண்களின் கழிப்பை பின்கொடு";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "இரு எண்களின் பெருக்கலை பின்கொடு";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "முதல் உள்ளீடு இரண்டாவது எண் அளவான அடுக்கு பெருக்கை கணித்து பின்கொடு.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "மாற்று %1 மூலம் %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "எண்னை '%1' மதிப்பால் கூட்டு,";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A4_%E0%AE%AE%E0%AE%BE%E0%AE%B1%E0%AE%BF%E0%AE%B2%E0%AE%BF";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "ஒரு மாறிலியை பின்கொடு π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (முடிவிலி).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1 மாறியை %2 மேலும் %3 கீழும் வற்புறுத்து";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "எண் மாறி வீசுகளம் உள்ளடங்கிய வாறு வற்புறுத்து";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ஆல் வகுபடக் கூடியது";
                +Blockly.Msg["MATH_IS_EVEN"] = "2-ஆல் பகும்";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "எண் குறைவானதா  ?";
                +Blockly.Msg["MATH_IS_ODD"] = "2-ஆல் பகாத";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "எண் நேர்ம முழுதானதா  ?";
                +Blockly.Msg["MATH_IS_PRIME"] = "எண் பகாத்தனிதானதா?";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "எண் முழுதானதா?";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2ன் மீதி";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "இரண்டு எண்கள் மூலம் பிரிவில் இருந்து எஞ்சியதை பின்கொடு.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%8E%E0%AE%A3%E0%AF%8D";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "ஒரு எண்.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "பட்டியலின் எண் சராசரி";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "பட்டியலின் மிகுதி";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "பட்டியலின் நடுக்கோடு";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "பட்டியலின் கறைவு";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "பட்டியலின் பொதுவகைகள்";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "ஒரு பட்டியலில் இருந்து சீரற்ற உருப்படி";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "பட்டியலின் நியமவிலகல்";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "பட்டியலின் கூட்டு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "முழு பட்டியலின் எண் சராசரி பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "பட்டியலின் அதிகமான எண் பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "பட்டியலின் நடுக்கோடு பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "பட்டியலின் குறைவான எண் பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "பட்டியலின் பொதுவகைகள் பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "ஒரு பட்டியலில் இருந்து சீரற்ற உருப்படி பின்கொடு";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "பட்டியலின் நியமவிலகலை பின்கொடு.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "முழு பட்டியலின் எண் சமம் பின்கொடு,";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "சீரற்ற எண் பின்னம்";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "சீரற்ற எண் பின்னம், 0.0 இல் இருந்து 1.0 உட்பட, பின்கொடு.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "வீசுகளம் %1 இல் இருந்து %2 உள்ளடங்கிய வாறு  சீரற்ற எண்";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "வீசுகளம் இல் இருந்த (உள்ளடங்கிய) வாறு  சீரற்ற எண் பின்கொடு.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "முழுமையாக்கு";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "கீழ்வழி முழுமையாக்கு";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "மேல்வழி முழுமையாக்கு";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "மேல்/கீழ் வழி முழு எண் ஆக மாற்று.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%B5%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%82%E0%AE%B2%E0%AE%AE%E0%AF%8D";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "தனித்த";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "வர்க்கமூலம்";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "ஒரு எண்ணின் தனித்த மதிப்பை பின்கொடு";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "e-இன் எண் அடுக்கு  பெருக்கை பின்கொடு.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "ஒரு எண்ணின் (இயற்கை) மடக்கை மதிப்பை பின்கொடு.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "ஒரு எண்ணின் (10) மடக்கை மதிப்பை பின்கொடு.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "ஒரு எண்ணின் எதிர்மறை மதிப்பை பின்கொடு";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "10-இன் எண் அடுக்கு  பெருக்கை பின்கொடு.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ஒரு எண்ணின் வர்க்கமூலத்தைத் தரும்.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%AE%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8B%E0%AE%A3%E0%AE%B5%E0%AE%BF%E0%AE%AF%E0%AE%B2%E0%AF%8D_%E0%AE%9A%E0%AE%BE%E0%AE%B0%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AF%8D";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "மதிப்பின் நேர்மாறு கோசைன் பின்கொடு";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "மதிப்பின் நேர்மாறு சைன் பின்கொடு";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "மதிப்பின் நேர்மாறு டேஞ்சன்டு பின்கொடு";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "டிகிரீ கோசைன் மதிப்பை பின்கொடு";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "டிகிரீ சைன் மதிப்பை பின்கொடு.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "டிகிரீ டேஞ்சன்டு மதிப்பை பின்கொடு";
                +Blockly.Msg["NEW_VARIABLE"] = "புதிய மாறிலி...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "புதிய மாறிலியின் பெயர்:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "வாக்குமூலங்களை அனுமதிக்கவும்";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "இத்துடன்";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "பயனரின் '%1' செயற்கூற்றை ஓட்டு.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "பயனரின் '%1' செயற்கூற்றை ஓட்டி வரும் வெளியீட்டை பயன்படுத்து.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "இத்துடன்:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' உருவாக்குக";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "கட்டளைகள் செய்ய (இடம்காட்டி)";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "இந்த மாறியிற்கு";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "வெளியீடு இல்லாத ஒரு செயல்பாடு உருவாக்குகிறது";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "பின்கொடு";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "வெளியீடு உள்ள ஒரு செயல்பாடு உருவாக்குகிறது";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "எச்சரிக்கை: இந்த செயற்கூறில் போலியான அளபுருக்கள் உண்டு.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "நிரல்பாகத்தை விளக்கமாக காட்டு";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "மதிப்பு உண்மையானால், இரண்டாவது மதிப்பை பின்கொடு.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "பெயரை உள்ளிடுக:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "செயல்கூறுக்கு ஒரு உள்ளீட்டை சேர்.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "உள்ளீடுகள்";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "செயல்கூறுகளின் உள்ளீட்டை சேர், நீக்கு, or மீண்டும் வரிசை செய்.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "கருத்தை நீக்கு";
                +Blockly.Msg["RENAME_VARIABLE"] = "மாறிலியை மறுபெயரிடுக...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "அனைத்து '%1' மாறிலிகளையும் பின்வருமாறு மறுபெயரிடுக:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "'%1' மாறியில் உரையை சேர்";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "சின்ன எழுத்துக்கு மாற்று";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "தலைப்பு எழுத்துக்கு மாற்று";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "பொரிய எழுத்துக்கு மாற்று";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "உரை நகல் எடுத்து பொரிய/சின்ன எழுத்து மாற்றி பின்கொடு.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "முதல் எழுத்தைப் பெறுக";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "முடிவில் இருந்து # எழுத்தை எடு";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "# எழுத்தை எடு";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "இறுதி எழுத்தைப் பெறுக";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "சமவாய்ப்புள்ள எழுத்தை எடு";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "கூறிய இடத்தில் உள்ள எழுத்தை எடு";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "உருபடியை உரையில் சேர்க்க.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "சேர்க்க";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "தொகுப்பு உரை திருத்துதம் செய்";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "எழுத்து கடைசியில் இருந்து # வரை";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "எழுத்து # வரை";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "கடைசி எழுத்து  வரை";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "உரையில்";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "-இல் உட்கணம் முதல் எழுத்திலிருந்து";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "-இல் உட்கணம் கடைசி # எழுத்திலிருந்து";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "-இல் உட்கணம் # எழுத்திலிருந்து";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "உரையின் குறியிடப்பட்ட சரம் பின்கொடு";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "உரையில் முதல் தோற்ற இடத்தை பின்கொடு";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "உரையில் கடைசி தோற்ற இடத்தை பின்கொடு";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "இரண்டாவது உரையில் முதல் உரையின் முதல்/கடை இருக்கை குறிஎண்ணை பின்கொடு.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 காலியானது";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "காலியானது என்றால் மெய் மதிப்பை பின்கொடு";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "வைத்து உரை உருவாக்க";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "பல பொருட்களை ஒன்றாக சேர்வதன் மூலம் உரை உருவாக்க.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1ன் நீளம்";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "தொடரில் உள்ள எழுத்துக்களின் (இடைவெளிகளையும் சேர்த்து) எண்ணிகையை பின்கொடு.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 அச்சிடுக";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "மதிப்பை அச்சிடு";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "எண்-உள்ளீடு தூண்டுதலை காட்டு";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "உரை-உள்ளீடு தூண்டுதலை காட்டு";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "உரை கொண்டு எண்-உள்ளீடு தூண்டுதலை காட்டு";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "உரை கொண்டு உரை-உள்ளீடு தூண்டுதலை காட்டு";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://ta.wikipedia.org/wiki/%E0%AE%9A%E0%AE%B0%E0%AE%AE%E0%AF%8D_%28%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A9%E0%AE%BF%E0%AE%AF%E0%AE%BF%E0%AE%AF%E0%AE%B2%E0%AF%8D%29";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "எழுத்து, சரம், சொல், அல்லது உரை சொற்தொடர்.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "இரு பக்கத்திலும் இடைவெளி எழுத்து நேர்த்தி செய்.";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "இடது பக்கத்தில் இடைவெளி எழுத்து நேர்த்தி செய்.";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "வலது பக்கத்தில் இடைவெளி எழுத்து நேர்த்தி செய்.";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "உரை நகல் எடுத்து இடைவெளி எழுத்து நீக்கி பின்கொடு.";
                +Blockly.Msg["TODAY"] = "இன்று";
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "உருப்படி";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'%1 நியமி' உருவாக்கு";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "இந்த மாறி மதிப்பை பின்கொடு";
                +Blockly.Msg["VARIABLES_SET"] = "நியமி %1 இந்த மாறியிற்கு %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'எடு %1' உருவாக்கு";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "மாறியின் மதிப்பாய் உள்ளீட்டு மதிப்பை வை.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/tcy.js b/blockly/webif/static/blockly/msg/js/tcy.js
                new file mode 100644
                index 000000000..4bf0a8826
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/tcy.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.tcy');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "ಟಿಪ್ಪಣಿ ಸೇರ್ಸಲೆ";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "ಮೌಲ್ಯೊನು ಬದಲ್ ಮಲ್ಪು";
                +Blockly.Msg["CLEAN_UP"] = "ಬ್ಲಾಕ್‍ಲೆನ್ ಸ್ವೊಚ್ಚೊ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["COLLAPSE_ALL"] = "ಮಾತಾ ತಡೆಕ್ಲೆನ ಮಾಹಿತಿನ್ ಎಲ್ಯ ಮಲ್ಪು";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ಎಲ್ಯೆ ಮಲ್ತ್‌ದ್ ತಡೆಲೆ";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "ಬಣ್ಣೊ ೧(ಒಂಜಿ)";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "ಬಣ್ಣೊ ೨(ರಡ್ಡ್)";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "ಅನುಪಾತೊ";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "ಬೆರಕ್ಕೆ ಮಲ್ಪು";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "ಕೊರಿನ ಅನುಪಾತೊಡು (0.0- 1.0) ರಡ್ಡ್ ಬಣ್ಣೊಲೆನ್ ಬೆರಕೆ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/ಬಣ್ಣೊ";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "ಬಣ್ಣೊ ಪಟೊಡ್ದು ಒಂಜಿ ಬಣ್ಣೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "ಒವ್ವೇ ಒಂಜಿ ಬಣ್ಣೊ";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಬಣ್ಣೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "ನೀಲಿ";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "ಪಚ್ಚೆ";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ಕೆಂಪು";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "ಬಣ್ಣೊದ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "ತೊಜಪಾಯಿನ ಪ್ರಮಾಣೊದ ಕೆಂಪು, ಪಚ್ಚೆ ಬೊಕ್ಕ ನೀಲಿ ಬಣ್ಣೊಡ್ದು ಒಂಜಿ ಬಣ್ಣೊನು ಉಂಡು ಮಲ್ಪುಲೆ. ಮಾತಾ ಮೌಲ್ಯೊಲು 0 ಬುಕ್ಕೊ 100 ತ ನಡುಟೆ ಇಪ್ಪೊಡು.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ಲೂಪ್ ಕಡಿಯುನಿ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "ಬೊಕ್ಕದ ಲೂಪ್ ಪುನರಾವರ್ತನೆದೊಟ್ಟುಗು ದುಂಬರಿಲೆ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "ಇತ್ತಿನ ಲೂಪ್‍ಡ್ದ್ ಪದಿಯಿ ಬಲೆ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "ಈ ಲೂಪುನು ಅರ್ದೊಡೆ ಬುಡುದ್ ಬೊಕ್ಕ ನನತ್ತ ಪುನರಾವರ್ತನೆಗ್ ದುಂಬರಿಲೆ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "ಎಚ್ಚರೊ: ಈ ತಡೆನ್ ಕಾಲಿ ಒಂಜಿ ಲೂಪುದುಲಯಿ ಮಾತ್ರ ಗಳಸೊಲಿ.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "%2 ಪಟ್ಟಿಡ್ ಪ್ರತಿ ಒಂಜಿ ವಿಸಯ %1 ಗ್";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಪ್ರತಿ ವಿಸಯೊಗು, '%1' ವ್ಯತ್ಯಾಯೊನು ವಿಸಯೊಗು ಜೋಡಾಲೆ, ಬೊಕ್ಕ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "%2 ಡ್ದ್ %3 ಮುಟ %4 ಸರ್ತಿ %1 ದ ಒಟ್ಟುಗು ಗೆನ್ಪು";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "ನಿರ್ದಿಸ್ಟೊ ಮದ್ಯಂತರೊದ ಮೂಲಕೊ ದೆತೊಂದು '%1' ವ್ಯತ್ಯಯೊಡ್ ಸುರುತ್ತ ಅಂಕೆಡ್ದ್ ಕಡೆತ್ತ ಅಂಕೆ ಮುಟ್ಟದ ಮೌಲ್ಯೊನು ದೆತ್ತೊನಾವ್ ಬೊಕ್ಕ ನಿಗಂಟ್ ಮಲ್ತಿನ ತಡೆಕ್ಲೆನ್ ಮಲ್ಪು";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "'ಒಂಜಿ ವೇಲೆ' ತಡೆಕ್ಕ್ ಒಂಜಿ ಶರ್ತನ್ ಸೇರಾವ್";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "'ಒಂಜಿ ವೇಲೆ' ತಡೆಕ್ಕ್ ಒಂಜಿ ಕಡೆತ್ತ ಮಾತೆನ್ಲಾ-ಪತ್ತ್ (catch-all) ಶರ್ತನ್ ಸೇರಾವ್";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "ಸೇರಾವ್, ದೆತ್ತ್‌ ಬುಡು, ಅತ್ತಂಡ ಈ 'ಒಂಜಿ ವೇಲೆ' ತಡೆನ್ ಕುಡ ಸಂರಚಣೆ ಮಲ್ಪೆರೆ ವಿಭಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "ಅತ್ತಂಡ";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "ಅತ್ತಂಡ";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ಒಂಜಿ ವೇಲೆ";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "ಮೌಲ್ಯ ನಿಜ ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "ಸುರುತ್ತ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ, ರಡ್ಡನೆ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್ಂಡ, ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "ಸುರುತ್ತ ಮೌಲ್ಯೊ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ, ರಡ್ಡನೆದ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್ಂಡ, ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು. ಒಂಜೇಲೆ ಒವ್ವೇ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತಿಜಿಂಡ, ಪಾತೆರೊಲೆನ ಕಡೆತ್ತ ತಡೆ ಮಲ್ಪು.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ಮಲ್ಪುಲೆ";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = " %1 ಸರ್ತಿ ಕೂಡೊರ ಮಲ್ಪು";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಸ್ತ್ ಸರ್ತಿ ಮಲ್ಪು";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ಉಂದು ನಿಜ ಆಪಿಲೆಕೊ ಕುಡೊರ ಮಲ್ಪು:";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ಉಂದು ನಿಜ ಆಂಡ ಕುಡೊರ ಮಲ್ಪು:";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "ಮೌಲ್ಯ ತಪ್ಪು ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "ಮೌಲ್ಯ ನಿಜ ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "ಮಾತ %1 ಬ್ಲಾಕ್‍ಲೆನ್ ದೆತ್ತ್‌ದ್ ಬುಡೊಡೆ?";
                +Blockly.Msg["DELETE_BLOCK"] = "ಬ್ಲಾಕ್‍ನ್ ಮಾಜಾವು";
                +Blockly.Msg["DELETE_VARIABLE"] = "'%1' ವ್ಯತ್ಯಯೊನು ಮಾಜಾಲೆ";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "'%2' ವ್ಯತ್ಯಯೊದ %1 ಉಪಯೋಗೊಲೆನ್ ಮಾಜಾವೊಡೆ?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 ಬ್ಲಾಕ್‍ಲೆನ್ ಮಾಜಾವು";
                +Blockly.Msg["DISABLE_BLOCK"] = "ಬ್ಲಾಕ್‍ನ್ ದೆತ್ತ್‌ಪಾಡ್";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "ನಕಲ್";
                +Blockly.Msg["ENABLE_BLOCK"] = "ತಡೆನ್ ಸಕ್ರಿಯೊ ಮಲ್ಪು";
                +Blockly.Msg["EXPAND_ALL"] = "ಮಾತಾ ತಡೆಕ್ಲೆನ ಮಾಹಿತಿನ್ ಪರಡಾವು";
                +Blockly.Msg["EXPAND_BLOCK"] = "ಬ್ಲಾಕ್‍ದ ಮಾಹಿತಿನ್ ಪರಡಾವು";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "ಪಿದಯಿದ ಪರಿಪು";
                +Blockly.Msg["HELP"] = "ಸಕಾಯೊ";
                +Blockly.Msg["INLINE_INPUTS"] = "ಉಳಸಾಲ್‍ದ ಉಳಪರಿಪು";
                +Blockly.Msg["IOS_CANCEL"] = "ವಜಾ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["IOS_ERROR"] = "ದೋಷ";
                +Blockly.Msg["IOS_OK"] = "ಸರಿ";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ ಇನ್‌ಪುಟ್ ಸೇರಾಲೆ";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "ಹೇಳಿಕೆಗ್ ಅವಕಾಸೊ";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "ಈ ಕಾರ್ಯೊಡು ಡುಪ್ಲಿಕೇಟ್ ಇನ್‌ಪುಟ್ ಉಂಡು.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "ಇನ್‌ಪುಟ್‌ಲು";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "ಸೇರಾಲೆ";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ ವ್ಯತ್ಯಯೊನು ಸೇರಾಲೆ";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "ಮಾಜಾಲೆ";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "ವ್ಯತ್ಯಯೊದ ಪುದರ್‌ನ್ ಖಾಲಿ ಬುಡಿಯೆರೆ ಆಪುಜಿ";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "ಪೊಸ ಪುದರ್";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "ವ್ಯತ್ಯಯೊದ ಪುದರ್";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "ಕಾಲಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "ಒಂಜಿ ಪಟ್ಟಿ, ೦ ಉದ್ದೊದ, ಒವ್ವೇ ಮಾಹಿತಿ ದಾಂತಿನ ದಾಖಲೆ ಪಿರಕೊರು.";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "ಪಟ್ಟಿ";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "ಈ ಪಟ್ಟಿ ತಡೆನ್ ಕುಡ ಸಂರಚನೆ ಮಲ್ಪೆರೆ ಸೇರಾಲೆ, ದೆತ್ತ್ ಬುಡುಲೆ, ಅತ್ತಂಡ ವಿಬಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "ಒಟ್ಟುಗು ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "ಪಟ್ಟಿಗ್ ಒಂಜಿ ವಿಸಯೊನು ಸೇರಾಲೆ.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "ಏತೇ ವಿಸಯೊಲುಪ್ಪುನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "ಸುರುತ";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "ಅಕೇರಿಡ್ದ್ #";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "ದೆತೊನು";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "ದೆತ್ತೊನು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡು";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ಕಡೆತ";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "ಗೊತ್ತು ಗುರಿದಾಂತಿನ";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "ದೆಪ್ಪುಲೆ";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ಅಕೇರಿಡ್ದ್ # ಗ್";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "# ಗ್";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "ಅಕೇರಿಗ್";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "ಸುರುಡ್ದು ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "ಅಕೇರಿಡ್ದ್ # ಡ್ದ್ ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "# ಡ್ದ್ ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "ಪಟ್ಯೊದ ನಿರ್ದಿಷ್ಟ ಬಾಗೊದ ಪ್ರತಿನ್ ಉಂಡುಮಲ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ಅಕೇರಿತ ವಿಸಯೊ";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ಸುರುತ ವಿಸಯೊ";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "ವಿಸಯೊ ಸುರುಕ್ಕು ಬತ್ತಿನೇನ್ ನಾಡ್";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "ವಿಸಯೊ ಅಕೇರಿಗ್ ಬತ್ತಿನೇನ್ ನಾಡ್";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ವಿಸಯೊ ಸುರುಕ್ಕು/ಅಕೇರಿಗ್ ಬತ್ತಿನೆತ್ತ ಸೂಚಿನ್ ಪಿರಕೊರ್ಪುಂಡು. ವಿಸಯೊ ತಿಕ್ಕಿಜ್ಜಾಂಡ %1 ನ್ ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_INLIST"] = "ಪಟ್ಟಿಡ್";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ಕಾಲಿ";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "ಪಟ್ಯೊ ಖಾಲಿ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 ಉದ್ದೊ";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "ಪಟ್ಟಿದ ಉದ್ದೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "%1 ವಿಸಯೊ %2 ಸರ್ತಿ ಪುನರಾವರ್ತನೆ ಆದುಪ್ಪುನ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ.";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "ಕೊರಿನ ಮೌಲ್ಯೊ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಸಂಕ್ಯೆದಾತ್ ಸರ್ತಿ ಪುನರಾವರ್ತನೆ ಆದುಪ್ಪುನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "ಲೆಕ";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "ಸೇರಾವ್";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "ಸೆಟ್ ಮಲ್ಪು";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "ಒಂಜಿ ಪಟ್ಟಿದ ಸುರುಕ್ಕು ವಿಸಯೊನು ಸೇರಾವುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಸೇರಾವುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "ಒಂಜಿ ಪಟ್ಟಿದ ಅಕೇರಿಗ್ ವಿಸಯೊನು ಸೇರಾವುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಓಲಾಂಡಲ ವಿಸಯೊನು ಸೇರಾವುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ಏರುನು";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "ಜಪ್ಪುನು";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "%1 %2 %3 ಇಂಗಡಿಪು";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "ಒಂಜಿ ಪಟ್ಟಿದ ಒಂಜಿ ಪ್ರತಿನ್ ಇಂಗಡಿಪು";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "ಅಕ್ಷರೊ, ನಮೂನೆ (case) ಅಲಕ್ಷ್ಯೊ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "ಸಂಖ್ಯೆ";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "ಅಕ್ಷರೊ";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "ಪಟ್ಯೊಲೆ ಪಟ್ಟಿನ್ ತಯಾರ್ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "ಪಟ್ಟಿದ ಪಟ್ಯೊನು ತಯಾರ್ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "ಪಟ್ಯೊಲೆನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಮಿತಿಸೂಚಕೊದ ಮೂಲಕೊ ಬೇತೆ ಮಲ್ತ್‌ದ್ ಒಂಜಿ ಪಟ್ಯೊಗು ಸೇರಾಲೆ.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "ಪಟ್ಯೊಲೆನ್ ಪ್ರತಿ ಮಿತಿಸೂಚಕೊಡು ತುಂಡು ಮಲ್ತ್‌ದ್ ಪಟ್ಯೊಲೆನ ಒಂಜಿ ಪಟ್ಟಿಗ್ ಬಾಗೊ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "ಮಿತಿಸೂಚಕೊದ ಒಟ್ಟುಗು";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "ಸುಲ್ಲು";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "ಒಂಜೆ ನಿಜ ಅತ್ತಂಡ ಸುಲ್ಲುನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "ಸತ್ಯೊ";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "ರಡ್ದ್ ಇನ್‌ಪುಟ್‌ಲಾ ಸಮ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಮಲ್ಲ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಮಲ್ಲ ಅತ್ತಂಡ ಅಯಿಕ್ಕ್ ಸಮ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಎಲ್ಯ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಎಲ್ಯ ಅತ್ತಂಡ ಅಯಿಕ್ಕ್ ಸಮ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "ರಡ್ದ್ ಇನ್‌ಪುಟ್‌ಲಾ ಸಮ ಅತ್ತಾಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 ಅತ್ತ್";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "ಇನ್‌ಪುಟ್ ಸುಲ್ಲಾದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು. ಇನ್‌ಪುಟ್ ನಿಜ ಆದಿತ್ತ್ಂಡ, 'ಸುಲ್ಲು'ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["LOGIC_NULL"] = "ಸೊನ್ನೆ";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "ಸೊನ್ನೆನ್ ಪಿರಕೊರ್ಪುಂಡು";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ಬುಕ್ಕೊ";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "ಅತ್ತಂಡ";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "ರಡ್ಡ್‌ಲಾ ಇನ್‌ಪುಟ್ ನಿಜ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಇನ್‌ಪುಟ್ ನಿಜ ಆಂಡಲಾ, 'ನಿಜ'ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "ಪರೀಕ್ಷೆ";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ಒಂಜಿ ವೇಲೆ ಸುಲ್ಲಾಂಡ";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ಒಂಜಿ ವೇಲೆ ನಿಜ ಆಂಡ";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'ಪರೀಕ್ಷೆ'ಡ್ ಶರ್ತನ್ ಸರಿತೂಲೆ. ಶರ್ತ ನಿಜವಾದಿತ್ತ್ಂಡ, 'ಒಂಜಿ ವೇಲೆ ನಿಜ ಆಂಡ' ಮೌಲ್ಯೊನು ಪಿರಕೊರ್ಪುಂಡು; ಇಜ್ಜಿಂಡ 'ಒಂಜಿ ವೇಲೆ ಸುಲ್ಲಾಂಡ' ಮೌಲ್ಯೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/ಅಂಕಗಣಿತ";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "ರಡ್ಡ್ ಸಂಖ್ಯೆದ ಮೊತ್ತನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "ಸಂಖ್ಯೆದ ಭಾಗಲಬ್ದೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "ರಡ್ಡ ಸ್ಂಖ್ಯೆದ ವ್ಯತ್ಯಾಸೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "ಸಂಖ್ಯೆದ ಗುಣಲಬ್ಧೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "ಸುರುತ್ತ ಸಂಖ್ಯೆದ ಘಾತೊನು ರಡ್ಡನೆ ಸಂಖ್ಯೆಗ್ ಏರ್ಪಾದ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%1 ನ್ %2 ಟ್ ಬದಲ್ ಮಲ್ಪು";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "'%1' ವ್ಯತ್ಯಯೊಗು ಒಂಜಿ ಸಂಖ್ಯೆನ್ ಸೇರಾವ್";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/ಗಣಿತ_ನಿರಂತರ";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "ಒಂಜಿ ಸಾಮಾನ್ಯ ಸ್ಥಿರಾಂಕೊನು ಪಿರಕೊರು: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%2 ಕಮ್ಮಿ %3 ಜಾಸ್ತಿ %1 ನಿರ್ಬಂಧ ಮಲ್ಪು";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "ನಿಗದಿತ ಮಿತಿತ ನಡುಟು ಒಂಜಿ ಸಂಖ್ಯೆನ್ ನಿರ್ಬಂಧ ಮಲ್ಪು";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ಭಾಗಿಪೊಲಿ";
                +Blockly.Msg["MATH_IS_EVEN"] = "ಸಮ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ಋಣ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_IS_ODD"] = "ಬೆಸ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ಧನ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_IS_PRIME"] = "ಅವಿಭಾಜ್ಯ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "ಒಂಜಿ ಸಂಖ್ಯೆ ಸಮನಾ, ಬೆಸನಾ, ಅವಿಭಾಜ್ಯನಾ, ಪೂರ್ಣನಾ, ಧನನಾ, ಋಣನಾ, ಅತ್ತಂಡ ಅವೆನ್ ಬೇತೆ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಸಂಖ್ಯೆಡ್ದ್ ಭಾಗಿಪೊಲಿಯಾ ಪಂದ್ ಪರೀಕ್ಷೆ ಮಲ್ಪು. ನಿಜ ಅತ್ತಂಡ ಸುಲ್ಲುನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "ಪೂರ್ಣ ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/ಮೋಡ್ಯುಲೊ_ಒಪರೇಶನ್";
                +Blockly.Msg["MATH_MODULO_TITLE"] = " %1 ÷ %2 ತ ಶೇಷ";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "ರಡ್ಡ್ ಸಂಖ್ಯೆಲೆನ್ ಭಾಗ ಮಲ್ತ್‌ದ್ ಶೇಷೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/ಸಂಖ್ಯೆ";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "ಅ ನಂಬ್ರೊ";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "ಪಟ್ಟಿದ ಸರಾಸರಿ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "ಪಟ್ಟಿಡ್ ಮಲ್ಲವ್";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "ಪಟ್ಟಿದ ನಡುತ್ತವ್";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "ಪಟ್ಟಿಡ್ ಕಿಞ್ಞವ್";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "ಪಟ್ಟಿದ ಮಸ್ತ್ ಸಾಮಾನ್ಯ ಮೌಲ್ಯ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "ಪಟ್ಟಿದ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಷಯ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "ಪಟ್ಟಿದ ಪ್ರಮಾಣಿತ ವಿಚಲನ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "ಪಟ್ಟಿದ ಮೊತ್ತ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಾತಾ ಸಂಖ್ಯೆಲೆನ ಸರಾಸರಿನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಲ್ಲ ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ನಡುತ್ತ ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ಕಿಞ್ಞ ಸಂಕ್ಯೆನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಸ್ತ್ ಸಾಮಾನ್ಯ ವಿಷಯೊನು ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "ಪಟ್ಟಿದ ಒವ್ವಾಂಡಲ ಒಂಜಿ ಅಂಶೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "ಪಟ್ಟಿದ ಪ್ರಮಾಣಿತ ವಿಚಲನೊನು ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಾತಾ ಸಂಖ್ಯೆಲೆನ ಮೊತ್ತನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/ರಾಂಡಮ್_ನಂಬರ್_ಜನರೇಶನ್";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಭಿನ್ನರಾಶಿ";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "0.0 (ಸೇರ್‌ದ್) ಬೊಕ್ಕ 1.0 (ಸೇರಂದೆ) ನಡುತ ಒವ್ವಾಂಡಲ ಒಂಜಿ ಭಿನ್ನರಾಶಿನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/ರಾಂಡಮ್_ನಂಬರ್_ಜನರೇಶನ್";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = " %1 ಡ್ದ್ %2 ಯಾದೃಚ್ಛಿಕ ಪೂರ್ಣಾಂಕೊ";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "ರಡ್ಡ್ ನಿಗದಿತ ಮಿತಿತ ನಡುತ್ತ ಯಾದೃಚ್ಛಿಕ ಪೂರ್ಣಾಂಕೊನು ಪಿರಕೊರು";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/ಪೂರ್ಣಾಂಕೊ";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ರೌಂಡ್";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ತಿರ್ತ್‌ಗ್ ರೌಂಡ್";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ಮಿತ್ತ್‌ಗ್ ರೌಂಡ್";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "ಒಂಜಿ ಸಂಖ್ಯೆನ್ ಮಿತ್ತ್‌ಗ್ ಅತ್ತಂಡ ತಿರ್ತ್‌ಗ್ ರೌಂಡ್ ಮಲ್ಪು";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "ಸಂಪೂರ್ನೊ";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ವರ್ಗಮೂಲೊ";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "ಸಂಖ್ಯೆದ ಸರಿಯಾಯಿನ ಮೌಲ್ಯೊನು ಕೊರು";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "ಒಂಜಿ ಸಂಖ್ಯೆದ ಘಾತೊಗು 'e'ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "ಸಂಖ್ಯೆದ ಪ್ರಾಕೃತಿಕ ಲಘುಗಣಕನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "ಸಂಖ್ಯೆದ ದಶಮಾನ ಲಘುಗಣಕನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "ಸಂಖ್ಯೆದ ನಿಷೇಧೊನು ಪಿರಕೊರು";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "ಒಂಜಿ ಸಂಖ್ಯೆದ ಘಾತೊಗು ೧೦ನ್ ಪಿರಕೊರು";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "ಸಂಖ್ಯೆದ ವರ್ಗಮೂಲೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/ತ್ರಿಕೋನಮಿತಿದ_ಕಾರ್ಯೊಲು";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌‌ಕೊಸೈನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌ಸೈನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌ಟ್ಯಾನ್‌ಜ್ಂಟ್ ಪಿರಕೊರು.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "ಒಂಜಿ ಡಿಗ್ರಿದ ಕೊಸೈನ್ (cosine) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "ಒಂಜಿ ಡಿಗ್ರಿದ ಸೈನ್ (sine) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "ಒಂಜಿ ಡಿಗ್ರಿದ ಟ್ಯಾನ್‌ಜೆಂಟ್ (tangent) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).";
                +Blockly.Msg["NEW_VARIABLE"] = "ವ್ಯತ್ಯಯೊನು ಉಂಡು ಮಲ್ಪುಲೆ";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "ಪೊಸ ವ್ಯತ್ಯಯೊದ ಪುದರ್:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "ಹೇಳಿಕೆಗ್ ಅವಕಾಸೊ";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ಒಟ್ಟುಗು:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "'%1' ಬಳಕೆದಾರೆರೆ ಕಾರ್ಯೊನು ನಡಪಾಲೆ.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = " ಬಳಕೆದಾರೆರೆ ಕಾರ್ಯೊ '%1' ನು ನಡಪಾಲೆ ಬುಕ್ಕೊ ಅಯಿತ ಉತ್ಪಾದನೆನ್ ಗಲಸ್‌ಲೆ.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ಒಟ್ಟುಗು:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = " '%1'ನ್ ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "ಈ ಕಾರ್ಯೊನು ಇವರಿಪುಲೆ...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "ಎಂಚಿನಾಂಡಲ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "ಇಂದೆಕ್";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "ಔಟ್‌ಪುಟ್ ದಾಂತಿನ ಕಾರ್ಯೊನು ಉಂಡುಮಲ್ಪುಂಡು.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "ಪಿರಕೊರು";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "ಔಟ್‌ಪುಟ್ ಇತ್ತಿನ ಕಾರ್ಯೊನು ಉಂಡುಮಲ್ಪುಂಡು.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "ಎಚ್ಚರಿಕೆ: ಈ ಕಾರ್ಯೊಡು ನಕಲಿ ಮಾನದಂಡೊ ಉಂಡು.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "ದೆರ್ತ್ ತೋಜುನ ಕಾರ್ಯೊದ ವ್ಯಾಕ್ಯಾನೊ";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "ಮೌಲ್ಯೊ ಸತ್ಯೊ ಆಂಡ, ರಡ್ಡನೆ ಮೌಲ್ಯೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "ಎಚ್ಚರಿಕೆ: ಒಂಜಿ ಕಾರ್ಯ ವ್ಯಾಕ್ಯಾನೊದುಲಯಿ ಮಾತ್ರ ಈ ತಡೆನ್ ಗಲಸೊಲಿ.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "ಉಲಪರಿಪುದ ಪುದರ್:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "ಕಾರ್ಯೊಗು ಒಂಜಿ ಉಲಪರಿಪುನು ಸೇರಲೆ.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "ಉಲಪರಿಪು";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "ಸೇರಾಲೆ, ದೆತ್ತ್‌ ಬುಡುಲೆ, ಅತ್ತಂಡ ಈ ಕಾರ್ಯೊಗು ಉಲಪರಿಪುಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "'%1' ಪನ್ಪಿ ಪುದರ್‌ದ ಕಾರ್ಯೊವಿದಾನೊ ದುಂಬೆ ಅಸ್ತಿತ್ವೊಡು ಉಂಡು.";
                +Blockly.Msg["REDO"] = "ಕುಡ ಮಲ್ಪು";
                +Blockly.Msg["REMOVE_COMMENT"] = "ಟಿಪ್ಪಣಿನ್ ದೆತ್ತ್‌ದ್ ಬುಡ್ಲೆ";
                +Blockly.Msg["RENAME_VARIABLE"] = "ವ್ಯತ್ಯಯೊಗು ಕುಡೊರ ಪುದರ್ ದೀಲೆ";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "ಮಾತಾ '%1' ವ್ಯತ್ಯಯೊಲೆನ ಪುದರ್‌ನ್ ನೆಕ್ಕ್ ಬದಲ್ ಮಲ್ಪುಲೆ:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "%1 ವ್ಯತ್ಯಯೊಗು ಕೆಲವು ಪಟ್ಯೊಲೆನ್ ಸೇರಾವ್";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "ಎಲ್ಯ ಅಕ್ಷರೊಗು";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "ತರೆಬರವುದ ಅಕ್ಷರೊಗು";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "ಮಲ್ಲ ಅಕ್ಷರೊಗು";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "ಪಟ್ಯೊದ ಒಂಜಿ ನಕಲ್‍ನ್ ಬೇತೆ ನಮೂನೆಡ್ (case) ಪಿರಕೊರು.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "ಸುರುತ್ತ ಅಕ್ಷರೊನು ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ನ್ ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "ಅಕ್ಸರೊ #ನ್ ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "ಅಕೇರಿದ ಅಕ್ಷರೊನು ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಅಕ್ಷರೊನು ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "%1 %2 ಪದೊಟ್ಟು";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "ಅಕ್ಷರೊನು ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "ಪಟ್ಯೊಗು ಒಂಜಿ ವಿಷಯೊನು ಸೇರಾವ್";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ಸೇರಾವ್";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "ಈ ಪಠ್ಯ ತಡೆನ್ ಕುಡ ಸಂರಚಣೆ ಮಲ್ಪೆರೆ, ಸೇರಾವ್, ದೆತ್ತ್ ಬುಡು, ಅತ್ತಂಡ ವಿಭಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪು.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ಗು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "ಅಕ್ಷರೊ #ಗು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "ಅಕೇರಿದ ಅಕ್ಷರೊಗು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "ಪಟ್ಯೊಡು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "ಸುರುತ್ತ ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊನು ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊನು ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊ ದೆತ್ತೊನು";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "ಪಟ್ಯೊದ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಬಾಗೊನು ಪಿರಕೊರ್ಪುಂಡು.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "ಪಟ್ಯೊ ಸುರುಕ್ಕು ಬತ್ತಿನೇನ್ ನಾಡ್";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "ಪಟ್ಯೊ ಅಕೇರಿಗ್ ಬತ್ತಿನೇನ್ ನಾಡ್";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "ರಡ್ಡನೆ ಪಟ್ಯೊಡು ಉಪ್ಪುನ ಸುರುತ ಪಟ್ಯೊ ಸುರುಕ್ಕು/ಅಕೇರಿಗ್ ಬತ್ತಿನೆತ್ತ ಸೂಚಿನ್ ಪಿರಕೊರು. ಪಟ್ಯೊ ತಿಕ್ಕಿಜ್ಜಾಂಡ %1 ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ಖಾಲಿ";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "ಕೊರಿನ ಪಟ್ಯೊ ಖಾಲಿ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ನೆಡ್ದ್ ಪಟ್ಯೊನು ಉಂಡು ಮಲ್ಪು";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "ಏತಾಂಡಲ ವಿಷಯಲೆನ್ ಒಟ್ಟುಗು ಸೇರಾದ್ ಒಂಜಿ ಪಟ್ಯೊದ ತುಂಡುನು ಉಂಡುಮಲ್ಪು.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 ಉದ್ದೊ";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "ಕೊರಿನ ಪಟ್ಯೊದ ಅಕ್ಷರೊಲೆನ (ಅಂತರೊಲು ಸೇರ್‌ದ್) ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 ಮುದ್ರಣ";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "ನಿರ್ದಿಷ್ಟ ಪಟ್ಯೊ, ಸಂಖ್ಯೆ ಅತ್ತಂಡ ಬೇತೆ ಮೌಲ್ಯೊನು ಮುದ್ರಿಪುಲೆ.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "ಒಂಜಿ ಸಂಖ್ಯೆಗ್ ಸದಸ್ಯೆರೆನ್ ಕೇನ್";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "ಕೆಲವು ಪಟ್ಯೊಗು ಸದಸ್ಯೆರೆನ್ ಕೇನ್.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "ಸಂದೇಶೊದೊಟ್ಟುಗು ಸಂಕ್ಯೆನ್ ಕೇನ್";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "ಸಂದೇಶೊದೊಟ್ಟುಗು ಪಟ್ಯೊಗು ಕೇನ್.";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/ಸ್ಟ್ರಿಂಗ್_(ಕಂಪ್ಯೂಟರ್_ಸೈನ್ಸ್)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "ಒಂಜಿ ಅಕ್ಷರೊ, ಪದೊ ಅತ್ತಂಡ ಪಾಟೊದ ಒಂಜಿ ಸಾಲ್";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "ರಡ್ಡ್ ಮೆಯಿತ್ತಲ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "ಎಡತ್ತ ಮೆಯಿತ್ತ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "ಬಲತ್ತ ಮೆಯಿತ್ತ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "ಒಂಜಿ ಅತ್ತಂಡ ರಡ್ಡ್ ಕೊಡಿಡ್ದ್ ಅಂತರೊಲೆನ್ (space) ದೆತ್ತ್‌ದ್ ಪಟ್ಯೊದ ಪ್ರತಿನ್ ಪಿರಕೊರು.";
                +Blockly.Msg["TODAY"] = "ಇನಿ";
                +Blockly.Msg["UNDO"] = "ದುಂಬುದಲೆಕೊ";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "ವಸ್ತು";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'ಸೆಟ್ %1' ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "ಈ ವ್ಯತ್ಯಯೊದ ಮೌಲ್ಯೊನು ಪಿರಕೊರು.";
                +Blockly.Msg["VARIABLES_SET"] = "%1 ನ್ %2 ಕ್ಕ್ ಸೆಟ್ ಮಲ್ಪುಲೆ";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'ದೆತ್ತೊನು %1' ಉಂಡುಮಲ್ಪುಲೆ";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "ಈ ವ್ಯತ್ಯಯೊನು ಇನ್‌ಪುಟ್‌ಗ್ ಸಮ ಆಪಿಲೆಕ ಸೆಟ್ ಮಲ್ಪುಂಡು.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "'%1' ಪನ್ಪಿ ಪುದರ್‌ದ ವ್ಯತ್ಯಯೊ ದುಂಬೆ ಅಸ್ತಿತ್ವೊಡು ಉಂಡು.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/th.js b/blockly/webif/static/blockly/msg/js/th.js
                new file mode 100644
                index 000000000..7cfdc84d2
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/th.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.th');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "ใส่คำอธิบาย";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "เปลี่ยนค่า:";
                +Blockly.Msg["CLEAN_UP"] = "จัดเรียงบล็อกให้เป็นแถว";
                +Blockly.Msg["COLLAPSE_ALL"] = "ย่อบล็อก";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ย่อบล็อก";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "สีที่ 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "สีที่ 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "อัตราส่วน";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "ผสม";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "ผสมสองสีเข้าด้วยกันด้วยอัตราส่วน (0.0 - 1.0)";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://th.wikipedia.org/wiki/สี";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "เลือกสีจากจานสี";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "สุ่มสี";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "เลือกสีแบบสุ่ม";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "ค่าสีน้ำเงิน";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "ค่าสีเขียว";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "ค่าสีแดง";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "สีที่ประกอบด้วย";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "สร้างสีด้วยการกำหนดค่าสีแดง เขียว และน้ำเงิน ค่าทั้งหมดต้องอยู่ระหว่าง 0 ถึง 100";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "ออกจากการวนซ้ำ";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "เริ่มการวนซ้ำรอบต่อไป";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "ออกจากการวนซ้ำที่อยู่";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "ข้ามคำสั่งที่เหลืออยู่ และเริ่มต้นวนซ้ำรอบต่อไป";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "คำเตือน: บล็อกนี้ใช้งานได้ภายในการวนซ้ำเท่านั้น";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "จากทุกรายการ %1 ในรายชื่อ %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "จากทุกรายการในรายชื่อ ตั้งค่าตัวแปร \"%1\" เป็นรายการ และทำตามคำสั่งที่กำหนดไว้";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "นับด้วย %1 จาก %2 จนถึง %3 เปลี่ยนค่าทีละ %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "ตัวแปร '%1' จะเริ่มจากจำนวนเริ่มต้น ไปจนถึงจำนวนสุดท้าย ตามระยะที่กำหนด และ ทำบล็อกที่กำหนดไว้";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "กำหนดเงื่อนไขของบล็อก \"ถ้า\"";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "เพิ่มสิ่งสุดท้าย ที่จะตรวจจับความเป็นไปได้ทั้งหมดของบล็อก \"ถ้า\"";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "เพิ่ม ลบ หรือจัดเรียงบล็อก \"ถ้า\" นี้ใหม่";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "นอกเหนือจากนี้";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "นอกเหนือจากนี้ ถ้า";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "ถ้า";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "ว่าเงื่อนไขเป็นจริง ก็จะ \"ทำ\" ตามที่กำหนด";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "ถ้าเงื่อนไขเป็นจริง ก็จะ \"ทำ\" ตามที่กำหนด แต่ถ้าเงื่อนไขเป็นเท็จก็จะทำ \"นอกเหนือจากนี้\"";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "ถ้าเงื่อนไขแรกเป็นจริง ก็จะทำตามคำสั่งในบล็อกแรก แต่ถ้าไม่ก็จะไปตรวจเงื่อนไขที่สอง ถ้าเงื่อนไขที่สองเป็นจริง ก็จะทำตามเงื่อนไขในบล็อกที่สองนี้";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "ถ้าเงื่อนไขแรกเป็นจริง ก็จะทำคำสั่งในบล็อกแรก จากนั้นจะข้ามคำสั่งในบล็อกที่เหลือ แต่ถ้าเงื่อนไขแรกเป็นเท็จ ก็จะทำการตรวจเงื่อนไขที่สอง ถ้าเงื่อนไขที่สองเป็นจริง ก็จะทำตามคำสั่งในบล็อกที่สอง จากนั้นจะข้ามคำสั่งในบล็อกที่เหลือ แต่ถ้าทั้งเงื่อนไขแรกและเงื่อนไขที่สองเป็นเท็จทั้งหมด ก็จะมาทำบล็อกที่สาม";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ทำ:";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ทำซ้ำ %1 ครั้ง";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "ทำซ้ำบางคำสั่งหลายครั้ง";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ทำซ้ำจนกระทั่ง";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ทำซ้ำขณะที่";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "ขณะที่ค่าเป็นเท็จ ก็จะทำบางคำสั่ง";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "ขณะที่ค่าเป็นจริง ก็จะทำบางคำสั่ง";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "ลบ %1 บล็อกทั้งหมด?";
                +Blockly.Msg["DELETE_BLOCK"] = "ลบบล็อก";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "ลบ %1 บล็อก";
                +Blockly.Msg["DISABLE_BLOCK"] = "ปิดใช้งานบล็อก";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "ทำสำเนา";
                +Blockly.Msg["ENABLE_BLOCK"] = "เปิดใช้งานบล็อก";
                +Blockly.Msg["EXPAND_ALL"] = "ขยายบล็อก";
                +Blockly.Msg["EXPAND_BLOCK"] = "ขยายบล็อก";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "อินพุตภายนอก";
                +Blockly.Msg["HELP"] = "ช่วยเหลือ";
                +Blockly.Msg["INLINE_INPUTS"] = "อินพุตในบรรทัด";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "สร้างรายการเปล่า";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "สร้างรายการเปล่า (ความยาวเป็น 0) ยังไม่มีข้อมูลใดๆ อยู่";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "รายการ";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "เพิ่ม ลบ หรือจัดเรียงบล็อกรายการนี้ใหม่";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "สร้างข้อความด้วย";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "เพิ่มไอเท็มเข้าไปในรายการ";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "สร้างรายการพร้อมด้วยไอเท็ม";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "แรกสุด";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# จากท้าย";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "เรียกดู";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "เรียกดูและเอาออก";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "ท้ายสุด";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "สุ่ม";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "เอาออก";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "คืนค่าไอเท็มอันแรกในรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "คืนค่าเป็นไอเท็มตามตำแหน่งที่ระบุ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "คืนค่าไอเท็มอันสุดท้ายในรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "คืนค่าไอเท็มแบบสุ่มจากรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "เอาออก และคืนค่าไอเท็มอันแรกในรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "เอาออก และคืนค่าไอเท็มในตำแหน่งที่ระบุจากรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "เอาออก และคืนค่าไอเท็มอันสุดท้ายในรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "เอาออก และคืนค่าไอเท็มแบบสุ่มจากรายการ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "เอาไอเท็มแรกสุดในรายการออก";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "คืนค่าเป็นไอเท็มตามตำแหน่งที่ระบุ";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "เอาไอเท็มอันท้ายสุดในรายการออก";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "เอาไอเท็มแบบสุ่มจากรายการออก";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "ถึง #  จากท้ายสุด";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "จนถึง #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "ถึง ท้ายสุด";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "ดึงรายการย่อยทั้งแต่แรกสุด";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "ดึงรายการย่อยจาก # จากท้ายสุด";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "ดึงรายการย่อยจาก #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "สร้างสำเนารายการในช่วงที่กำหนด";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 คือไอเท็มอันท้ายสุด";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 คือไอเท็มอันแรกสุด";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "หาอันแรกที่พบ";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "หาอันสุดท้ายที่พบ";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "คืนค่าตำแหน่งของไอเท็มอันแรก/สุดท้ายที่พบในรายการ คืนค่า %1 ถ้าหาไม่พบ";
                +Blockly.Msg["LISTS_INLIST"] = "ในรายการ";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ว่างเปล่า";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "คืนค่าเป็นจริง ถ้ารายการยังว่างเปล่า";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "ความยาวของ %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "ส่งคืนค่าความยาวของรายการ";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "สร้างรายการที่มีไอเท็ม %1 จำนวน %2";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "สร้างรายการที่ประกอบด้วยค่าตามที่ระบุในจำนวนตามที่ต้องการ";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "เป็น";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "แทรกที่";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "กำหนด";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "แทรกไอเท็มเข้าไปเป็นอันแรกสุดของรายการ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "แทรกไอเท็มเข้าไปในตำแหน่งที่กำหนด";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "เพิ่มไอเท็มเข้าไปท้ายสุดของรายการ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "เพิ่มไอเท็มเข้าไปในรายการแบบสุ่ม";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "กำหนดไอเท็มอันแรกในรายการ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "กำหนดไอเท็มในตำแหน่งที่ระบุในรายการ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "กำหนดไอเท็มอันสุดท้ายในรายการ";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "กำหนดไอเท็มแบบสุ่มในรายการ";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "น้อยไปหามาก";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "มากไปหาน้อย";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "เรียงลำดับ %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "เรียงลำดับสำเนาของรายชื่อ";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "ตัวอักษร";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "ตัวเลข";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "ตัวอักษร";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "สร้างรายการจากข้อความ";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "สร้างข้อความจากรายการ";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "รวมรายการข้อความเป็นข้อความเดียว แบ่งด้วยตัวคั่น";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "แบ่งข้อความเป็นรายการข้อความ แยกแต่ละรายการด้วยตัวคั่น";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "ด้วยตัวคั่น";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "เท็จ";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "คืนค่าเป็นจริงหรือเท็จ";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "จริง";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://th.wikipedia.org/wiki/อสมการ";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่ทั้งสองค่านั้นเท่ากัน";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "คืนค่าเป็น \"จริง\" ถ้าค่าแรกมากกว่าค่าที่สอง";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "คืนค่าเป็น \"จริง\" ถ้าค่าแรกมากกว่าหรือเท่ากับค่าที่สอง";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "คืนค่าเป็น \"จริง\" ถ้าค่าแรกน้อยกว่าค่าที่สอง";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "คืนค่าเป็น \"จริง\" ถ้าค่าแรกน้อยกว่าหรือเท่ากับค่าที่สอง";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่ทั้งสองค่านั้นไม่เท่ากัน";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "ไม่ %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่เป็นเท็จ คืนค่าเป็น \"เท็จ\" ถ้าค่าที่ใส่เป็นจริง";
                +Blockly.Msg["LOGIC_NULL"] = "ไม่กำหนด";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "คืนค่า \"ไม่กำหนด\"";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "และ";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "หรือ";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "คืนค่าเป็น \"จริง\" ถ้าค่าทั้งสองค่าเป็นจริง";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "คืนค่าเป็น \"จริง\" ถ้ามีอย่างน้อยหนึ่งค่าที่เป็นจริง";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "ทดสอบ";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "ถ้า เป็นเท็จ";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "ถ้า เป็นจริง";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "ตรวจสอบเงื่อนไขใน \"ทดสอบ\" ถ้าเงื่อนไขเป็นจริง จะคืนค่า \"ถ้า เป็นจริง\" ถ้าเงื่อนไขเป็นเท็จ จะคืนค่า \"ถ้า เป็นเท็จ\"";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://th.wikipedia.org/wiki/เลขคณิต";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "คืนค่าผลรวมของตัวเลขทั้งสองจำนวน";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "คืนค่าผลหารของตัวเลขทั้งสองจำนวน";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "คืนค่าผลต่างของตัวเลขทั้งสองจำนวน";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "คืนค่าผลคูณของตัวเลขทั้งสองจำนวน";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "คืนค่าผลการยกกำลัง โดยตัวเลขแรกเป็นฐาน และตัวเลขที่สองเป็นเลขชี้กำลัง";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "เปลี่ยนค่า %1 เป็น %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "เพิ่มค่าของตัวแปร \"%1\"";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://th.wikipedia.org/wiki/ค่าคงตัวทางคณิตศาสตร์";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "คืนค่าคงตัวทางคณิตศาสตร์ที่พบบ่อยๆ เช่น π (3.141…), e (2.718…), φ (1.618…), รากที่สอง (1.414…), รากที่ ½ (0.707…), ∞ (อนันต์)";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "จำกัดค่า %1 ต่ำสุด %2 สูงสุด %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "จำกัดค่าของตัวเลขให้อยู่ในช่วงที่กำหนด";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "หารลงตัว";
                +Blockly.Msg["MATH_IS_EVEN"] = "เป็นจำนวนคู่";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "เป็นเลขติดลบ";
                +Blockly.Msg["MATH_IS_ODD"] = "เป็นจำนวนคี่";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "เป็นเลขบวก";
                +Blockly.Msg["MATH_IS_PRIME"] = "เป็นจำนวนเฉพาะ";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "ตรวจว่าตัวเลขเป็นจำนวนคู่ จำนวนคี่ จำนวนเฉพาะ จำนวนเต็ม เลขบวก เลขติดลบ หรือหารด้วยเลขที่กำหนดลงตัวหรือไม่ คืนค่าเป็นจริงหรือเท็จ";
                +Blockly.Msg["MATH_IS_WHOLE"] = "เป็นเลขจำนวนเต็ม";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "เศษของ %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "คืนค่าเศษที่ได้จากการหารของตัวเลขทั้งสองจำนวน";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://th.wikipedia.org/wiki/จำนวน";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "จำนวน";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "ค่าเฉลี่ยของรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "มากที่สุดในรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "ค่ามัธยฐานของรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "น้อยที่สุดในรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "ฐานนิยมของรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "สุ่มรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "ส่วนเบี่ยงเบนมาตรฐานของรายการ";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "ผลรวมของรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "คืนค่าเฉลี่ยของรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "คืนค่าตัวเลขที่มากที่สุดในรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "คืนค่ามัธยฐานของรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "คืนค่าตัวเลขที่น้อยที่สุดในรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "คืนค่าฐานนิยมของรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "สุ่มคืนค่าสิ่งที่อยู่ในรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "คืนค่าส่วนเบี่ยงเบนมาตรฐานของรายการ";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "คืนค่าผลรวมของตัวเลขทั้งหมดในรายการ";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "สุ่มเลขเศษส่วน";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "สุ่มเลขเศษส่วน ตั้งแต่ 0.0 แต่ไม่เกิน 1.0";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "สุ่มเลขจำนวนเต็มตั้งแต่ %1 จนถึง %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "สุ่มเลขจำนวนเต็มจากช่วงที่กำหนด";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://th.wikipedia.org/wiki/การปัดเศษ";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ปัดเศษ";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ปัดเศษลง";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ปัดเศษขึ้น";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "ปัดเศษของตัวเลขขึ้นหรือลง";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "ค่าสัมบูรณ์";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "รากที่สอง";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "คืนค่าค่าสัมบูรณ์ของตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "คืนค่า e ยกกำลังด้วยตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "คืนค่าลอการิทึมธรรมชาติของตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "คืนค่าลอการิทึมฐานสิบของตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "คืนค่าติดลบของตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "คืนค่า 10 ยกกำลังด้วยตัวเลข";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "คืนค่ารากที่สองของตัวเลข";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://th.wikipedia.org/wiki/ฟังก์ชันตรีโกณมิติ";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "คืนค่า arccosine ของตัวเลข";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "คืนค่า arcsine ของตัวเลข";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "คืนค่า arctangent ของตัวเลข";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "คืนค่า cosine ขององศา (ไม่ใช่เรเดียน)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "คืนค่า sine ขององศา (ไม่ใช่เรเดียน)";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "คืนค่า tangent ขององศา (ไม่ใช่เรเดียน)";
                +Blockly.Msg["NEW_VARIABLE"] = "สร้างตัวแปร...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "ชื่อตัวแปรใหม่:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "ข้อความที่ใช้ได้";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ด้วย:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_(computer_science)";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "เรียกใช้ฟังก์ชันที่สร้างโดยผู้ใช้ \"%1\"";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_(computer_science)";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "เรียกใช้ฟังก์ชันที่สร้างโดยผู้ใช้ \"%1\" และใช้ผลลัพธ์ของมัน";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ด้วย:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "สร้าง \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "อธิบายฟังก์ชันนี้";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "ทำอะไรบางอย่าง";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "ถึง";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "สร้างฟังก์ชันที่ไม่มีผลลัพธ์";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "คืนค่า";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "สร้างฟังก์ชันที่มีผลลัพธ์";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "ระวัง: ฟังก์ชันนี้มีพารามิเตอร์ที่มีชื่อซ้ำกัน";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "เน้นฟังก์ชันนิยาม";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "ถ้ามีค่าเป็นจริง ให้คืนค่าที่สอง";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "ระวัง: บล็อกนี้ใช้เฉพาะในการสร้างฟังก์ชันเท่านั้น";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "ชื่อนำเข้า:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "เพิ่มค่าป้อนเข้าฟังก์ชัน";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "นำเข้า";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "เพิ่ม, ลบ, หรือจัดเรียง ข้อมูลที่ป้อนเข้าฟังก์ชันนี้";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "ทำซ้ำ";
                +Blockly.Msg["REMOVE_COMMENT"] = "เอาคำอธิบายออก";
                +Blockly.Msg["RENAME_VARIABLE"] = "เปลี่ยนชื่อตัวแปร...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "เปลี่ยนชื่อตัวแปร '%1' ทั้งหมดเป็น:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "ต่อข้อความให้ตัวแปร \"%1\"";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "เปลี่ยนเป็น ตัวพิมพ์เล็ก";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "เปลี่ยนเป็น ตัวอักษรแรกเป็นตัวพิมพ์ใหญ่";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "เปลี่ยนเป็น ตัวพิมพ์ใหญ่";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "คืนค่าสำเนาของข้อความในกรณีต่างๆ";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "ดึง ตัวอักษรตัวแรก";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "ดึง ตัวอักษรตัวที่ # จากท้าย";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "ดึง ตัวอักษรตัวที่";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "ดึง ตัวอักษรตัวสุดท้าย";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "ถึงตัวอักษรแบบสุ่ม";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "คืนค่าตัวอักษรจากตำแหน่งที่ระบุ";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "เพิ่มรายการเข้าไปในข้อความ";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "รวม";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "เพิ่ม ลบ หรือจัดเรียงบล็อกข้อความนี้ใหม่";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "จนถึง ตัวอักษรที่ # จากท้าย";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "จนถึง ตัวอักษรที่";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "จนถึง ตัวอักษรสุดท้าย";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "ในข้อความ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "แยกข้อความย่อยตั้งแต่ ตัวอักษรแรก";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "แยกข้อความย่อยตั้งแต่ ตัวอักษรที่ # จากท้าย";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "แยกข้อความย่อยตั้งแต่ ตัวอักษรที่";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "คืนค่าบางส่วนของข้อความ";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "หาข้อความแรกที่พบ";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "หาข้อความสุดท้ายที่พบ";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "คืนค่าตำแหน่งที่พบข้อความแรกอยู่ในข้อความที่สอง คืนค่า %1 ถ้าหาไม่พบ";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 ว่าง";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "คืนค่าจริง ถ้าข้อความยังว่าง";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "สร้างข้อความด้วย";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "สร้างข้อความด้วยการรวมจำนวนของรายการเข้าด้วยกัน";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "ความยาวของ %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "คืนค่าความยาวของข้อความ (รวมช่องว่าง)";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "พิมพ์ %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "พิมพ์ข้อความ ตัวเลข หรือค่าอื่นๆ";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "แสดงหน้าต่างให้ผู้ใช้ใส่ตัวเลข";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "แสดงหน้าต่างให้ผู้ใช้ใส่ข้อความ";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "แสดงหน้าต่างตัวเลข";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "แสดงหน้าต่างข้อความ";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://th.wikipedia.org/wiki/สายอักขระ";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "ตัวหนังสือ คำ หรือข้อความ";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "ลบช่องว่างทั้งสองข้างของ";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "ลบช่องว่างด้านหน้าของ";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "ลบช่องว่างข้างท้ายของ";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "คืนค่าสำเนาของข้อความที่ลบเอาช่องว่างหน้าและหลังข้อความออกแล้ว";
                +Blockly.Msg["TODAY"] = "วันนี้";
                +Blockly.Msg["UNDO"] = "ย้อนกลับ";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "รายการ";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "สร้าง \"กำหนด %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "คืนค่าของตัวแปรนี้";
                +Blockly.Msg["VARIABLES_SET"] = "กำหนด %1 จนถึง %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "สร้าง \"get %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "กำหนดให้ตัวแปรนี้เท่ากับการป้อนข้อมูล";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/tl.js b/blockly/webif/static/blockly/msg/js/tl.js
                new file mode 100644
                index 000000000..8d1815a93
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/tl.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.tl');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Dagdag komento";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "pagbago ng value:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "bloke";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "bloke";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "kulay 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "kulay 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "proporsyon";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "halo";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Paghalo ng dalawang kulay kasama ng ibinigay na proporsyon (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "http://en.wikipedia.org/wiki/Color";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "pagpili ng kulay sa paleta.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "iba ibang kulay";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "pagpili ng iba't ibang kulay.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "asul";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "berde";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "pula";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "kulayan ng";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "gumawa ng kulay ng may espisipikong dami ng kulay pula, berde, at asul. lahat ng halaga ay dapat sa pagitan ng 0 at 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "putulin ang paulit ulit";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "Magpatuloy sa susunod na pag-ulit ng loop";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Hatiin ang nilalaman ng loop.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Laktawan ang natitirang bahagi ng loop, at magpatuloy sa susunod na pag-ulit.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Babala: Ang block ito ay maaari lamang magamit sa loob ng loop.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "sa bawat bagay %1 sa listahan %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Para sa bawat item sa isang list, i-set ang variable ng '%1' sa mga item, at pagkatapos ay gumawa ng ilang mga statements.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "bilangin %1 mula %2 hanggang %3 ng %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Magkaroon ng mga variable na \"%1\" na tanggalin ng mga halaga mula sa simulang numero hanggang sa dulong numero, at bilangin sa pamamagitan ng tinukoy na agwat, at gawin ang mga tinukoy na mga blocks.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Mag dagdag ng condition sa if block.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Mag Add ng final, kunin lahat ng condition sa if block.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Mag Add, remove o kaya mag reorder ng sections para maayos ang if block.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "else";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "else if";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "kung";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "kung ang value ay true,  gagawin ang do statements.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Kung ang value ay true, gagawin ang unang block ng do statements. Kung hindi, gagawin ang pangalawang block ng statement.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Kung ang unang value ay true, gagawin ang first block ng statement. Kung hindi, kung ang second value ay true, gagawin ang second block ng statement.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Kung ang first value ay true, gagawin ang first block ng statement. Kung hindi true ang second value, gagawin ang second block ng statement. Kung wala sa mga values ay true, gagawin ang last block ng statements.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "http://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "gawin";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "ulitin %1 beses";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "gumawa ng ilang pangungusap ng ilang ulit.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "ulitin hanggang";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "ulitin habang";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Habang ang value ay false, gagawin ang ibang statements.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Habang ang value ay true, gagawin ang ibang statements.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";  // untranslated
                +Blockly.Msg["DELETE_BLOCK"] = "burahin ang bloke";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "burahin %1 ng bloke";
                +Blockly.Msg["DISABLE_BLOCK"] = "Ipangwalang bisa ang Block";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Kaparehas";
                +Blockly.Msg["ENABLE_BLOCK"] = "Bigyan ng bisa ang Block";
                +Blockly.Msg["EXPAND_ALL"] = "Palawakin ang Blocks";
                +Blockly.Msg["EXPAND_BLOCK"] = "Palawakin ang Block";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Panlabas na Inputs";
                +Blockly.Msg["HELP"] = "Tulong";
                +Blockly.Msg["INLINE_INPUTS"] = "Inline na Inputs";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "Gumawa ng walang laman na list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Ibabalik ang list, na may haba na 0, nag lalaman ng walang data records";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Magdagdag, mag tanggal or mag ayos ng sections para muling maayos ang listahan ng block.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "gumawa ng list kasama";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Mag dagdag ng item sa list.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Gumawa ng list na may kahit anong number ng items.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "Una";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# mula katapusan";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "kunin";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "kunin at tanggalin";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "huli";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "nang hindi pinipili";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "tanggalin";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Ibalik ang unang item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Ibalik ang item sa itinakdang posisyon sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Ibalik ang huling item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Nag babalik ng hindi pinipiling item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Nag tatanggal at nag babalik ng mga unang item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Nag tatanggal at nag babalik ng mga items sa tinukoy na posisyon sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Nag tatanggal at nag babalik ng huling item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Nag tatanggal at nag babalik ng mga hindi pinipiling item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Nag tatanggal ng unang item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Nag tatanggal ng item sa tinukoy na posisyon sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Nag tatanggal ng huling item sa list.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Nag tatanggal ng item mula sa walang pinipiling list.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "mula # hanggang huli";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "mula #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "hanggang huli";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "pag kuha ng sub-list mula sa una";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "pag kuha ng sub-list mula sa # mula huli";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "pag kuha ng sub-list mula #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Gumagawa ng kopya ng tinukoy na bahagi ng list.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 ay ang huling item.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ay ang unang item.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Hanapin ang unang pangyayari ng item";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "hanapin ang huling pangyayari ng item";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Pagbalik ng index ng una/huli pangyayari ng item sa list. Pagbalik ng %1 kung ang item ay hindi makita.";
                +Blockly.Msg["LISTS_INLIST"] = "sa list";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 ay walang laman";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Nagbabalik ng true kung ang list ay walang laman.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "haba ng %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Pag balik ng haba ng list.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "pag gawa ng list kasama ng item %1 inuulit %2 beses";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Pag gawa ng list na binubuo ng binigay na value at inulit na tinuloy na bilang ng beses.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "gaya ng";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "isingit sa";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Nag singit ng item sa simula ng list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Nag singit ng item sa tinukoy na posistion sa list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Idagdag ang item sa huli ng isang list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Isingit ang item ng walang pinipili sa isang list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Pag set ng unang item sa isang list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Pag set ng item sa tinukoy na position sa isang list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Pag set sa huling item sa isang list.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Pag set ng walang pinipiling item sa isang list.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "mali";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Nag babalik ng true or false.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "tama";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "http://en.wikipedia.org/wiki/Inequality_(mathematics)";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Nag babalik ng true kung ang pinasok ay parehong magkatumbas.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Nagbabalik ng true kung ang unang pinasok ay mas malaki kaysa pangalawang pinasok.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Nag babalik ng true kung ang unang pinasok ay mas malaki or katumbas ng pangalawang pinasok.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Nag babalik ng true kung ang unang pinasok ay maliit kaysa sa pangalawang pinasok.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Nag babalik ng true kung ang unang pinasok ay maliit sa o katumbas sa pangalawang pinasok.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "not %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false.  Returns false if the input is true.";
                +Blockly.Msg["LOGIC_NULL"] = "blangko";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "http://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "at";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "o";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "http://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "kung mali";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "kung tama";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "http://en.wikipedia.org/wiki/Arithmetic";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "http://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "baguhin %1 by %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "http://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";
                +Blockly.Msg["MATH_IS_EVEN"] = "is even";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "ay negatibo";
                +Blockly.Msg["MATH_IS_ODD"] = "is odd";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "ay positibo";
                +Blockly.Msg["MATH_IS_PRIME"] = "is prime";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number.  Returns true or false.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "is whole";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "http://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "http://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "average of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "max of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "http://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "http://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "http://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "http://en.wikipedia.org/wiki/Square_root";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "http://en.wikipedia.org/wiki/Trigonometric_functions";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";
                +Blockly.Msg["NEW_VARIABLE"] = "New variable...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "New variable name:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";  // untranslated
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Redo";  // untranslated
                +Blockly.Msg["REMOVE_COMMENT"] = "Remove Comment";
                +Blockly.Msg["RENAME_VARIABLE"] = "Rename variable...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of first text in the second text.  Returns %1 if text is not found.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "http://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";
                +Blockly.Msg["TODAY"] = "Today";  // untranslated
                +Blockly.Msg["UNDO"] = "Undo";  // untranslated
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";
                +Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/tlh.js b/blockly/webif/static/blockly/msg/js/tlh.js
                new file mode 100644
                index 000000000..e8cdc43c8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/tlh.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.tlh');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "QInHom chel";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "choH:";
                +Blockly.Msg["CLEAN_UP"] = "ngoghmeyvaD tlhegh rurmoH";
                +Blockly.Msg["COLLAPSE_ALL"] = "ngoghmey DejmoH";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "ngogh DejmoH";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "rItlh wa'";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "rItlh cha'";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "'ar";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "DuD";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";  // untranslated
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choose a colour from the palette.";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "rItlh vISaHbe'";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Choose a colour at random.";  // untranslated
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "chal rItlh";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "tI rItlh";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "'Iw rItlh";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "rItlh wIv";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "gho Haw'";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "gho taHqa'";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "yIqIm! ghoDaq neH ngoghvam lo'laH vay'.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "ngIq Doch %1 ngaSbogh tetlh %2 nuDDI'";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "togh %1 mung %2 ghoch %3 Do %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "pagh";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "pagh teHchugh";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "teHchugh";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";  // untranslated
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "ruch";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1-logh qaSmoH";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "teHpa' qaSmoH";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "teHtaHvIS qaSmoH";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";  // untranslated
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Hoch %1 ngoghmey Qaw'?";
                +Blockly.Msg["DELETE_BLOCK"] = "ngogh Qaw'";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 ngoghmey Qaw'";
                +Blockly.Msg["DISABLE_BLOCK"] = "ngogh Qotlh";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "velqa' chenmoH";
                +Blockly.Msg["ENABLE_BLOCK"] = "ngogh QotlhHa'";
                +Blockly.Msg["EXPAND_ALL"] = "ngoghmey DejHa'moH";
                +Blockly.Msg["EXPAND_BLOCK"] = "ngogh DejHa'moH";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Hur rar";
                +Blockly.Msg["HELP"] = "QaH";
                +Blockly.Msg["INLINE_INPUTS"] = "qoD rar";
                +Blockly.Msg["IOS_CANCEL"] = "Cancel";  // untranslated
                +Blockly.Msg["IOS_ERROR"] = "Error";  // untranslated
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "tetlh chIm";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "tetlh";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "tetlh ghom";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "wa'DIch";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# Qav";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "Suq";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "Suq vaj pej";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "Qav";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "Sahbe'";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "pej";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "mojaQ # Qav";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "mojaQ #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "mojaQ Qav";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "tetlhHom moHaq wa'DIch";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "tetlhHom moHaq # Qav";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "tetlhHom moHaq #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "Suq";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Doch sam wa'DIch";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "Doch sam Qav";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";  // untranslated
                +Blockly.Msg["LISTS_INLIST"] = "tetlhDaq";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 chIm'a'";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "chuq %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "tetlh ghom %2 Dochmey %1 pus";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "Dos";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "lIH";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "choH";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";  // untranslated
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";  // untranslated
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "tetlh ghermeH ghItlh wav";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "ghItlh chenmoHmeH tetlh gherHa'";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "rarwI'Hom lo'";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "teHbe'";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returns either true or false.";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "teH";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";  // untranslated
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "yoymoH %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";  // untranslated
                +Blockly.Msg["LOGIC_NULL"] = "paghna'";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "'ej";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "qoj";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "chov";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "teHbe'chugh";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "teHchugh";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";  // untranslated
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";  // untranslated
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";  // untranslated
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "choH %1 chel %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";  // untranslated
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "jon %1 bIng %2 Dung %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";  // untranslated
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "wav'a'";
                +Blockly.Msg["MATH_IS_EVEN"] = "lang'a' mI'";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "bIng pagh";
                +Blockly.Msg["MATH_IS_ODD"] = "ror'a' mI'";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "Dung pagh";
                +Blockly.Msg["MATH_IS_PRIME"] = "potlh'a' mI'";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";  // untranslated
                +Blockly.Msg["MATH_IS_WHOLE"] = "ngoHlaHbe''a'";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";  // untranslated
                +Blockly.Msg["MATH_MODULO_TITLE"] = "ratlwI' SIm %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";  // untranslated
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";  // untranslated
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "beQwI' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "tInwI''a' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "beQwI'botlh SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "machwI''a' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "beQwI' motlh SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "SaHbe' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "motlhbe'wI' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "chelwI' SIm tetlh";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";  // untranslated
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";  // untranslated
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "mI'HomSaHbe'";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";  // untranslated
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "ngoH mI'SaHbe' bIng %1 Dung %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";  // untranslated
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";  // untranslated
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ngoH";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "bIng ngoH";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "Dung ngoH";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";  // untranslated
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "Dung pagh choH";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "cha'DIch wav";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";  // untranslated
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";  // untranslated
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";  // untranslated
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";  // untranslated
                +Blockly.Msg["NEW_VARIABLE"] = "lIw chu'...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "lIw chu' pong:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "mu'tlhegh chaw'";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "qel:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";  // untranslated
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "qel:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "chel '%1'";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "mIw yIDel...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "mIw";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "ruch";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "chegh";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";  // untranslated
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "ghuHmoHna': qelwI' cha'logh chen.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "mIwna' wew";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "ghoHmoHna': ngoghvam ngaSbe' mIwDaq.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "pong:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";  // untranslated
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "qelwI'mey";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";  // untranslated
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "vangqa'";
                +Blockly.Msg["REMOVE_COMMENT"] = "QInHom chelHa'";
                +Blockly.Msg["RENAME_VARIABLE"] = "lIw pong choH...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Hoch \"%1\" lIwmey pongmey choH:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "machchoH";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "DojchoH";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "tInchoH";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "mu'Hom wa'DIch";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "mu'Hom # Qav";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "mu'Hom #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "mu'Hom Qav";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "mu'Hom SaHbe'";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "Suq";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";  // untranslated
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ghom";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "mojaq mu'Hom # Qav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "mojaq mu'Hom #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "mojaq mu'Hom Qav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "ghItlhDaq";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "ghItlhHom moHaq mu'Hom wa'DIch";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "ghItlhHom moHaq mu'Hom # Qav";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "ghItlhHom moHaq mu'Hom #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "Suq";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "ghItlh wa'DIch Sam";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "ghItlh Qav Sam";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 chIm'a'";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";  // untranslated
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ghItlh ghom";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "chuq %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";  // untranslated
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "maq %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "mI' tlhob 'ej maq";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "ghItln tlhob 'ej maq";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";  // untranslated
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";  // untranslated
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "poSnIHlogh pei";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "poSlogh pei";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "nIHlogh pei";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";  // untranslated
                +Blockly.Msg["TODAY"] = "DaHjaj";
                +Blockly.Msg["UNDO"] = "vangHa'";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "Doch";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "chel 'choH %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";  // untranslated
                +Blockly.Msg["VARIABLES_SET"] = "choH %1 %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "chel 'Suq %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";  // untranslated
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/tr.js b/blockly/webif/static/blockly/msg/js/tr.js
                new file mode 100644
                index 000000000..e44b52d44
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/tr.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.tr');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Yorum Ekle";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "'%1' değişkeni, '%2' fonksiyonunun tanımının bir parçası olduğu için silinemez";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Değeri değiştir:";
                +Blockly.Msg["CLEAN_UP"] = "Blokları temizle";
                +Blockly.Msg["COLLAPSE_ALL"] = "Blokları Daralt";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Blok'u Daralt";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "renk 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "renk 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "oran";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "karıştır";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Verilen bir orana bağlı olarak iki rengi karıştırır. (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://tr.wikipedia.org/wiki/Renk";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Paletten bir renk seçin.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "rastgele renk";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Rastgele bir renk seçin.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "mavi";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "yeşil";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "kırmızı";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "renk değerleri";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Kırmızı, yeşil ve mavinin belirtilen miktarıyla bir renk oluşturun.  Tüm değerler 0 ile 100 arasında olmalıdır.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "döngüden çık";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "döngünün sonraki adımından devam et";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "İçeren döngüden çık.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Bu döngünün geri kalanını atlayın ve sonraki adım ile devam edin.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Uyarı: Bu blok sadece bir döngü içinde kullanılabilir.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "her öğe için %1 listede %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Bir listedeki her öğe için  '%1' değişkenini maddeye atayın  ve bundan sonra bazı açıklamalar yapın.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "ile sayılır %1 %2 den %3 ye, her adımda %4 değişim";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Başlangıç sayısından bitiş sayısına kadar belirtilen aralık ve belirtilen engeller ile devam eden değerler alan '%1' değişkeni oluştur.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "If bloğuna bir koşul ekleyin.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "If bloğuna kalan durumları \"yakalayan\" bir son ekle.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "If bloğuna ekle, kaldır veya yeniden düzenleme yap.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "değilse";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "değilse eğer";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "eğer";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Eğer değişken true , yani gerçekleşmiş ise , ardından gelen işlemi yerine getir .";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Eğer değişken true, yani gerçekleşiyor ise ilk blok'taki işlemleri yerine getir, Aksi halde ikinci blok'taki işlemleri yerine getir.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Eğer ilk değişken true, yani koşul gerçekleşmiş ise ilk blok içerisindeki işlem(ler)i gerçekleştir. Eğer ikinci değişken true ise, ikinci bloktaki işlem(ler)i gerçekleştir .";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Eğer ilk değer true, yani olumlu ise, ilk blok'taki işlem(ler)i gerçekleştir. İlk değer true değil ama ikinci değer true ise, ikinci bloktaki işlem(ler)i gerçekleştir. Eğer değerlerin hiçbiri true değil ise son blok'taki işlem(ler)i gerçekleştir.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://tr.wikipedia.org/wiki/For_d%C3%B6ng%C3%BCs%C3%BC";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "yap";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 kez tekrarla";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Bazı işlemleri birkaç kez yap.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "kadar tekrarla";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "tekrar ederken";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Bir değer yanlış olduğunda bazı beyanlarda bulun.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Bir değer doğru olduğunda bazı beyanlarda bulun.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Tüm %1 blok silinsin mi?";
                +Blockly.Msg["DELETE_BLOCK"] = "Bloğu Sil";
                +Blockly.Msg["DELETE_VARIABLE"] = "'%1' değişkenini silmek istiyor musunuz?";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "'%2' değişkeninin %1 kullanımını silmek istiyor musunuz?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "%1 Blokları Sil";
                +Blockly.Msg["DISABLE_BLOCK"] = "Bloğu Devre Dışı Bırak";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Çoğalt";
                +Blockly.Msg["ENABLE_BLOCK"] = "Bloğu Etkinleştir";
                +Blockly.Msg["EXPAND_ALL"] = "Blokları Genişlet";
                +Blockly.Msg["EXPAND_BLOCK"] = "Bloğu Genişlet";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Harici Girişler";
                +Blockly.Msg["HELP"] = "Yardım";
                +Blockly.Msg["INLINE_INPUTS"] = "Satır içi girdiler";
                +Blockly.Msg["IOS_CANCEL"] = "İptal";
                +Blockly.Msg["IOS_ERROR"] = "Hata";
                +Blockly.Msg["IOS_OK"] = "OK";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Giriş Ekle";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Açıklamalara izin ver";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "Girdiler";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Ekle";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Değişkeni ekle";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Sil";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Değişken adı kısmı boş bırakılamaz.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Yeniden adlandır";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Değişken adı";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "Boş liste oluştur";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Veri kaydı içermeyen uzunluğu 0 olan bir listeyi verir";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "liste";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Bu liste bloğunu yeniden yapılandırmak için bölüm ekle,kaldır veya yeniden çağır.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "İle liste oluşturma";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Listeye bir nesne ekle.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Herhangi sayıda nesne içeren bir liste oluştur.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "ilk";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# sonundan";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "# Kare";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "Al";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "al ve kaldır";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "son";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "rastgele";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "kaldır";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Listedeki ilk öğeyi verir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Listede belirli pozisyondaki bir öğeyi verir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Listedeki son öğeyi verir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Listedeki rastgele bir öğeyi verir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Kaldırır ve listedeki ilk öğeyi döndürür.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Kaldırır ve listede belirtilen konumdaki bir öğeyi döndürür.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Kaldırır ve listedeki son öğeyi döndürür.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Kaldırır ve listedeki rastgele bir öğeyi verir.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Listedeki ilk nesneyi kaldırır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Bir liste içerisinde , tanımlanan pozisyonda ki öğeyi kaldırır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Listedeki son nesneyi kaldırır.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Listedeki rastgele bir nesneyi kaldırır.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "Sondan #'a kadar";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "#'a";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "Sona kadar";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "ilk öğeden alt liste al";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "# işaretinden sonra gelen ifadeye göre  alt liste al , # sondan";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "# dan alt liste al";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Listenin belirli bir kısmının kopyasını yaratır.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 son öğedir.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 ilk öğedir.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "Öğenin ilk varolduğu yeri bul";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "Öğenin son varolduğu yeri bul";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Listedeki öğenin ilk/son oluşumunun indeksini döndürür. Eğer öğe bulunamaz ise %1 döndürür.";
                +Blockly.Msg["LISTS_INLIST"] = "Listede";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 boş";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Eğer liste boş ise true döndürür .";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1'in uzunluğu";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Bir listenin uzunluğunu verir.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "%1 nesnenin %2 kez tekrarlandığı bir liste yarat";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Verilen bir değerin , belirli bir sayıda tekrarlanmasından oluşan bir liste yaratır .";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Bir listenin bir kopyasını tersine çevirin.";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "olarak";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "e yerleştir";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "yerleştir";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Nesneyi listenin başlangıcına ekler.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Bir öğeyi belirtilen pozisyona göre listeye yerleştirir .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Öğeyi listenin sonuna ekle .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Bir öğeyi listeye rast gele ekler .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Bir listenin ilk öğesini yerleştirir .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Bir öğeyi belirtilen yere göre listeye yerleştirir .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Bir listedeki son öğeyi yerleştirir .";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Listeye rast gele bir öğe yerleştirir .";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "artan";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "azalan";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "kısa %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Listenin kısa bir kopyası.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alfabetik, gözardı et";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "sayısal";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alfabetik";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "metinden liste yap";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "listeden metin yap";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Bir sınırlayıcı tarafından kesilen metinlerin listesini bir metine ekle.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Her sınırlayıcıda kesen metinleri bir metin listesine ayır.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "sınırlayıcı ile";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false = Olumsuz";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Ya 'True' yada 'False' değerini verir.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "Olumlu";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://tr.wikipedia.org/wiki/E%C5%9Fitsizlikler";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Girilen iki değer birbirine eşitse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Girilen ilk değer ikinci değerden daha büyükse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Girilen ilk değer ikinci değerden büyük veya eşitse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Girilen ilk değer ikinci değerden küçükse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Girilen ilk değer ikinci değerden küçük veya eşitse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Girilen iki değerde birbirine eşit değilse \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 değil";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Girilen değer yanlışsa \"True\" değerini verir.Girilen değer doğruysa \"False\" değerini verir.";
                +Blockly.Msg["LOGIC_NULL"] = "sıfır";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "sıfır verir.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "ve";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "veya";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Girilen iki değerde doğruysa \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Girilen iki değerden en az biri doğruysa \"True\" değerini verir.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "yanlış ise";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "doğru ise";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "'test'deki şartı test eder. Eğer şart doğru ise 'doğru' değeri döndürür, aksi halde 'yanlış' değeri döndürür.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://tr.wikipedia.org/wiki/Aritmetik";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "İki rakamın toplamını döndür.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "İki sayının bölümünü döndür.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "İki sayını farkını döndür.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "İki sayının çarpımını döndür.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "İlk sayinin ikincinin kuvvetine yükseltilmişini döndür.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "%1'i %2 kadar değiştir";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "'%1' değişkenine bir sayı ekle.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Yaygın sabitlerden birini döndür:π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (sonsuz).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1 i en düşük %2 en yüksek %3 ile sınırla";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Bir sayıyı belirli iki sayı arasında sınırlandır(dahil).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "bölünebilir";
                +Blockly.Msg["MATH_IS_EVEN"] = "çift";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "negatif";
                +Blockly.Msg["MATH_IS_ODD"] = "tek";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "pozitif";
                +Blockly.Msg["MATH_IS_PRIME"] = "asal";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Bir sayinin çift mi tek mi , tam mı, asal mı , pozitif mi, negatif mi, veya tam bir  sayıyla bölünebilirliğini kontrol et.'True' veya 'False' değerini döndür.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "Bütün olduğunu";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 nin kalanı";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "İki sayının bölümünden kalanı döndür.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "x";
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Bir sayı.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "listenin ortalaması";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "en büyük sayı";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "Listenin medyanı";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "Listenin en küçüğü";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "Listenin modları";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "Listenin rastgele öğesi";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "Listenin standart sapması";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "Listenin toplamı";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Listedeki sayısal değerlerin ortalamasını (aritmetik anlamda) döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Listenin en büyüğünü döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Listenin medyanını döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Listenin en küçüğünü döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Listede ki en yaygın öğe veya öğelerinin listesini döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Listeden rastgele bir element döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Listenin standart sapmasını döndür.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Listede ki tüm sayıların toplamını döndür.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "üst alma";
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://tr.wikipedia.org/wiki/Rastgele_say%C4%B1_%C3%BCretimi";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "Rast gele kesirli sayı , yada parça";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "0.0(dahil) ve 1.0 (hariç) sayıları arasında bir sayı döndür .";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://tr.wikipedia.org/wiki/Rastgele_say%C4%B1_%C3%BCretimi";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "%1 ile %2 arasında rastgele tam sayı üret";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Herhangi iki sayı arasında , sayılar dahil olmak üzere , rastgele bir tam sayı döndür.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding Yuvarlama fonksiyonu için araştırma yapınız, sayfanın Türkçe çevirisi henüz mevcut değil.";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "Yuvarla";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "aşağı yuvarla";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "yukarı yuvarla";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Bir sayı yı yukarı yada aşağı yuvarla .";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://tr.wikipedia.org/wiki/Karek%C3%B6k";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "Kesin";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "Kare kök";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Bir sayının tam değerini döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Bir sayının e ' inci  kuvvetini döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Bir sayının doğal logaritmasını döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Bir sayının 10  temelinde logaritmasını döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Bir sayıyı geçersiz olarak döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Bir sayının 10. kuvvetini döndür .";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Bir sayının karekökü nü döndür .";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "tire";
                +Blockly.Msg["MATH_TRIG_ACOS"] = "akosünüs";
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asinüs";
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atanjant";
                +Blockly.Msg["MATH_TRIG_COS"] = "kosünüs";
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://tr.wikipedia.org/wiki/Trigonometrik_fonksiyonlar";
                +Blockly.Msg["MATH_TRIG_SIN"] = "Sinüs";
                +Blockly.Msg["MATH_TRIG_TAN"] = "tanjant";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Bir sayının ters kosunusunu döndür .";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Bir sayının ters sinüsünü döndür .";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Bir sayının ters tanjantını döndür .";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Bir açının kosinüsünü döndür(radyan olarak değil).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Bir açının sinüsünü döndür(radyan olarak değil).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Bir açının tanjantını döndür(radyan olarak değil).";
                +Blockly.Msg["NEW_VARIABLE"] = "Değişken oluştur...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Yeni değişken ismi :";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "Eğer ifadelerine izin ver";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "ile :";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Kullanıcı tanımlı fonksiyonu çalıştır '%1' .";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Kullanıcı tanımlı fonksiyonu çalıştır '%1' ve çıktısını kullan .";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "ile :";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "'%1' oluştur";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Bu işlevi açıkla...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "birşey yap";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "e";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Çıktı vermeyen bir fonksiyon yaratır .";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "Geri dön";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Çıktı veren bir fonksiyon oluşturur.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Uyarı: Bu fonksiyon yinelenen parametreler vardır.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Fonksiyon tanımı vurgulamak";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Eğer değer doğruysa, ikinci değere geri dön.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Uyarı: Bu blok yalnızca bir fonksiyon tanımı içinde kullanılır.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "girdi adı:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "İşleve bir girdi ekleyin.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "girdiler";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Bu işlevin girdilerini ekleyin, çıkarın, ya da yeniden sıralayın.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "A procedure named '%1' already exists.";  // untranslated
                +Blockly.Msg["REDO"] = "Yinele";
                +Blockly.Msg["REMOVE_COMMENT"] = "Yorumu Sil";
                +Blockly.Msg["RENAME_VARIABLE"] = "Değişkeni yeniden adlandır...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Tüm '%1' değişkenlerini yeniden isimlendir:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Değişken '%1' e bazı metinler ekleyin.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "küçük harf";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Baş Harfler Büyük";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "büyük harf";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Metnin bir kopyasını farklı bir harf durumunda (HEPSİ BÜYÜK - hepsi küçük) getirir.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "İlk harfini al";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "# dan sona harfleri al";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "# harfini al";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "son harfi al";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "Rastgele bir harf al";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Belirli pozisyonda ki bir harfi döndürür.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Metine bir öğe ekle.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "Katıl";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Bu metin bloğunu düzenlemek için bölüm ekle,sil veya yeniden görevlendir.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "Sondan # harfe";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "# harfe";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "son harfe";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "metinde";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "ilk harften başlayarak alt-string alma";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "n inci harften sona kadar alt-string alma";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "n inci harften alt-string alma";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Metinin belirli bir kısmını döndürür.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "Metnin ilk varolduğu yeri bul";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "Metnin son varolduğu yeri bul";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "İlk metnin ikinci metnin içindeki ilk ve son varoluşlarının indeksini döndürür.Metin bulunamadıysa %1 döndürür.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 boş";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Verilen metin boşsa true(doğru) değerini verir.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "ile metin oluştur";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Herhangi bir sayıda ki öğeleri bir araya getirerek metnin bir parçasını oluştur.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 in uzunluğu";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Yazı içerisinde verilen harflerin ( harf arasındaki boşluklar dahil) sayısını verir .";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "%1 ' i Yaz";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Belirli bir metni,sayıyı veya başka bir değeri yaz.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Kullanıcıdan sayı al .";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Kullanıcıdan Yazım al .";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Kullanıcıdan sayı al , istek mesajı göstererek";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Kullanıcıdan yazım al , istek mesajıyla";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Metnin bir harfi,kelimesi veya satırı.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "iki tarafından da boşlukları temizle";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "solundan boşlukları temizle";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "sağından boşlukları temizle";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Metnin bir veya her iki sondan da boşlukları silinmiş şekilde kopyasını verir.";
                +Blockly.Msg["TODAY"] = "Bugün";
                +Blockly.Msg["UNDO"] = "Geri al";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "öge";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "'set %1' oluştur";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Bu değişkenin değerini verir.";
                +Blockly.Msg["VARIABLES_SET"] = "Atamak %1 e %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "'get %1' oluştur";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Bu değişkeni girilen değere eşitler.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "'%1' isimli değişken adı zaten var.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/uk.js b/blockly/webif/static/blockly/msg/js/uk.js
                new file mode 100644
                index 000000000..05f583c40
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/uk.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.uk');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Додати коментар";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Змінити значення:";
                +Blockly.Msg["CLEAN_UP"] = "Вирівняти блоки";
                +Blockly.Msg["COLLAPSE_ALL"] = "Згорнути блоки";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Згорнути блок";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "колір 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "колір 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "співвідношення";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "змішати";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Змішує два кольори разом у вказаному співвідношені (0.0 - 1.0).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://uk.wikipedia.org/wiki/Колір";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Вибрати колір з палітри.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "випадковий колір";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Вибрати колір навмання.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "синій";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "зелений";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";
                +Blockly.Msg["COLOUR_RGB_RED"] = "червоний";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "колір з";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Створити колір зі вказаними рівнями червоного, зеленого та синього. Усі значення мають бути від 0 до 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "перервати цикл";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "продовжити з наступної ітерації циклу";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Перервати виконання циклу.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Пропустити залишок цього циклу і перейти до виконання наступної ітерації.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Попередження: цей блок може бути використаний тільки в межах циклу.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "для кожного елемента %1 у списку %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Для кожного елемента в списку змінна '%1' отримує значення елемента, а потім виконуються певні дії.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "рахувати з %1 від %2 до %3 через %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Наявна змінна \"%1\" набуває значень від початкового до кінцевого, враховуючи заданий інтервал, і виконуються вказані блоки.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Додайте умову до блока 'якщо'.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Додати остаточну, всеосяжну умову до блоку 'якщо'.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Додайте, вилучіть або змініть порядок секцій, щоб переналаштувати цей блок 'якщо'.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "інакше";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "інакше якщо";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "якщо";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Якщо значення істинне, то виконати певні дії.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Якщо значення істинне, то виконується перший блок операторів. В іншому випадку виконується другий блок операторів.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Якщо перше значення істинне, то виконується перший блок операторів. В іншому випадку, якщо друге значення істина, то виконується другий блок операторів.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Якщо перше значення істинне, то виконується перший блок операторів. В іншому випадку, якщо друге значення істинне, то виконується другий блок операторів. Якщо жодне із значень не є істинним, то виконується останній блок операторів.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://uk.wikipedia.org/wiki/Цикл_(програмування)#.D0.A6.D0.B8.D0.BA.D0.BB_.D0.B7_.D0.BB.D1.96.D1.87.D0.B8.D0.BB.D1.8C.D0.BD.D0.B8.D0.BA.D0.BE.D0.BC";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "виконати";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "повторити %1 разів";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Виконати певні дії декілька разів.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "повторювати, доки не";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "повторювати поки";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Поки значення хибне, виконувати певні дії.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Поки значення істинне, виконувати певні дії.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Вилучити всі блоки %1?";
                +Blockly.Msg["DELETE_BLOCK"] = "Видалити блок";
                +Blockly.Msg["DELETE_VARIABLE"] = "Вилучити змінну '%1'";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Вилучити %1 використання змінної '%2'?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Видалити %1 блоків";
                +Blockly.Msg["DISABLE_BLOCK"] = "Вимкнути блок";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Дублювати";
                +Blockly.Msg["ENABLE_BLOCK"] = "Увімкнути блок";
                +Blockly.Msg["EXPAND_ALL"] = "Розгорнути блоки";
                +Blockly.Msg["EXPAND_BLOCK"] = "Розгорнути блок";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Зовнішні входи";
                +Blockly.Msg["HELP"] = "Довідка";
                +Blockly.Msg["INLINE_INPUTS"] = "Вбудовані входи";
                +Blockly.Msg["IOS_CANCEL"] = "Скасувати";
                +Blockly.Msg["IOS_ERROR"] = "Помилка";
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Додати";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Додати змінну";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Видалити";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Перейменувати";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Назва змінної";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "створити порожній список";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Повертає список, довжиною 0, що не містить записів даних";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "список";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Додайте, вилучіть або змініть порядок секцій для переналаштування блока списку.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "створити список з";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Додати елемент до списку.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Створює список з будь-якою кількістю елементів.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "перший";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# з кінця";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "отримати";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "отримати і вилучити";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "останній";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "випадковий";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "вилучити";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "-ий.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Повертає перший елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Повертає елемент у заданій позиції у списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Повертає останній елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Повертає випадковий елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Видаляє і повертає перший елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Видаляє і повертає елемент у заданій позиції у списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Видаляє і повертає останній елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Видаляє і повертає випадковий елемент списоку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Вилучає перший елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Вилучає зі списку елемент у вказаній позиції.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Вилучає останній елемент списку.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Вилучає випадковий елемент списку.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "до # з кінця";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "до #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "до останнього";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "отримати вкладений список з першого";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "отримати вкладений список від # з кінця";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "отримати вкладений список з #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "символу.";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Створює копію вказаної частини списку.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 - це останній елемент.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 - це перший елемент.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "знайти перше входження елемента";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "знайти останнє входження елемента";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Повертає індекс першого/останнього входження елемента у списку. Повертає %1, якщо елемент не знайдено.";
                +Blockly.Msg["LISTS_INLIST"] = "у списку";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 є порожнім";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Повертає істину, якщо список порожній.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "довжина %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Повертає довжину списку.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "створити список з елемента %1 повтореного %2 разів";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Створює список, що складається з заданого значення повтореного задану кількість разів.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "як";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "вставити в";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "встановити";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Вставляє елемент на початок списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Вставка елемента у вказану позицію списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Додає елемент у кінці списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Випадковим чином вставляє елемент у список.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Задає перший елемент списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Задає елемент списку у вказаній позиції.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Задає останній елемент списку.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Задає випадковий елемент у списку.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "за зростанням";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "за спаданням";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "сортувати %3 %1 %2";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Сортувати копію списку.";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "за абеткою, ігноруючи регістр";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "як числа";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "за абеткою";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "зробити з тексту список";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "зробити зі списку текст";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Злити список текстів у єдиний текст, відокремивши розділювачами.";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Поділити текст на список текстів, розриваючи на кожному розділювачі.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "з розділювачем";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "хибність";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Повертає значення істина або хибність.";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "істина";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://uk.wikipedia.org/wiki/Нерівність";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Повертає істину, якщо обидва входи рівні один одному.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Повертає істину, якщо перше вхідне значення більше, ніж друге.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Повертає істину, якщо перше вхідне значення більше або дорівнює другому.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Повертає істину, якщо перше вхідне значення менше, ніж друге.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Повертає істину, якщо перше вхідне значення менше або дорівнює другому.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Повертає істину, якщо обидва входи не дорівнюють один одному.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "не %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Повертає істину, якщо вхідне значення хибне. Повертає хибність, якщо вхідне значення істинне.";
                +Blockly.Msg["LOGIC_NULL"] = "ніщо";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Повертає ніщо.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "та";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "або";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Повертає істину, якщо обидва входи істинні.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Повертає істину, якщо принаймні один з входів істинний.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "тест";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "якщо хибність";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "якщо істина";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Перевіряє умову в 'тест'. Якщо умова істинна, то повертає  значення 'якщо істина'; в іншому випадку повертає значення 'якщо хибність'.";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://uk.wikipedia.org/wiki/Арифметика";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Повертає суму двох чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Повертає частку двох чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Повертає різницю двох чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Повертає добуток двох чисел.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Повертає перше число, піднесене до степеня, вираженого другим числом.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "змінити %1 на %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Додати число до змінної '%1'.";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://uk.wikipedia.org/wiki/Математична_константа";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Повертає одну з поширених констант: π (3.141...), e (2.718...), φ (1,618...), sqrt(2) (1.414...), sqrt(½) (0.707...) або ∞ (нескінченність).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "обмежити %1 від %2 до %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Обмежує число вказаними межами (включно).";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "ділиться на";
                +Blockly.Msg["MATH_IS_EVEN"] = "парне";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "від'ємне";
                +Blockly.Msg["MATH_IS_ODD"] = "непарне";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "додатне";
                +Blockly.Msg["MATH_IS_PRIME"] = "просте";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Перевіряє, чи число парне, непарне, просте, ціле, додатне, від'ємне або чи воно ділиться на певне число без остачі. Повертає істину або хибність.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "ціле";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://uk.wikipedia.org/wiki/Ділення_з_остачею";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "остача від %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Повертає остачу від ділення двох чисел.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://uk.wikipedia.org/wiki/Число";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Число.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "http://www.mapleprimes.com/questions/100441-Applying-Function-To-List-Of-Numbers";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "середнє списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "максимум списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "медіана списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "мінімум списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "моди списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "випадковий елемент списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "стандартне відхилення списку";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "сума списку";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Повертає середнє (арифметичне) числових значень у списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Повертає найбільше число у списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Повертає медіану списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Повертає найменше число у списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Повертає перелік найпоширеніших елементів у списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Повертає випадковий елемент зі списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Повертає стандартне відхилення списку.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Повертає суму всіх чисел у списку.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://uk.wikipedia.org/wiki/Генерація_випадкових_чисел";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "випадковий дріб";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Повертає випадковий дріб від 0,0 (включно) та 1.0 (не включно).";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://uk.wikipedia.org/wiki/Генерація_випадкових_чисел";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "випадкове ціле число від %1 до %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Повертає випадкове ціле число між двома заданими межами включно.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://uk.wikipedia.org/wiki/Округлення";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "округлити";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "округлити до меншого";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "округлити до більшого";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Округлення числа до більшого або до меншого.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://uk.wikipedia.org/wiki/Квадратний_корінь";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "модуль";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "квадратний корінь";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Повертає модуль числа.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Повертає e у степені.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Повертає натуральний логарифм числа.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Повертає десятковий логарифм числа.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Повертає протилежне число.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Повертає 10 у степені.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Повертає квадратний корінь з числа.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://uk.wikipedia.org/wiki/Тригонометричні_функції";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Повертає арккосинус числа.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Повертає арксинус числа.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Повертає арктангенс числа.";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Повертає косинус кута в градусах (не в радіанах).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Повертає синус кута в градусах (не в радіанах).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Повертає тангенс кута в градусах (не в радіанах).";
                +Blockly.Msg["NEW_VARIABLE"] = "Створити змінну...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Нова назва змінної:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "-ий.";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "дозволити дії";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "з:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://uk.wikipedia.org/wiki/Підпрограма";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Запустити користувацьку функцію \"%1\".";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://uk.wikipedia.org/wiki/Підпрограма";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Запустити користувацьку функцію \"%1\" і використати її вивід.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "з:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Створити \"%1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Опишіть цю функцію...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "блок тексту";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://uk.wikipedia.org/wiki/Підпрограма";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "щось зробити";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "до";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Створює функцію без виводу.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://uk.wikipedia.org/wiki/Підпрограма";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "повернути";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Створює функцію з виводом.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Увага: ця функція має дубльовані параметри.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Підсвітити визначення функції";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Якщо значення істинне, то повернути друге значення.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Попередження: цей блок може використовуватися лише в межах визначення функції.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "назва входу:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Додати до функції вхідні параметри.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "входи";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Додайте, вилучіть або змініть порядок вхідних параметрів для цієї функції.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Процес з назвою '%1' вже існує.";
                +Blockly.Msg["REDO"] = "Повторити";
                +Blockly.Msg["REMOVE_COMMENT"] = "Видалити коментар";
                +Blockly.Msg["RENAME_VARIABLE"] = "Перейменувати змінну...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Перейменувати усі змінні \"%1\" до:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Додати деякий текст до змінної '%1'.";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "до нижнього регістру";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Великі Перші Букви";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "до ВЕРХНЬОГО регістру";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "В іншому випадку повертає копію тексту.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "отримати перший символ";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "отримати символ # з кінця";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "отримати символ #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm";
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "отримати останній символ";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "отримати випадковий символ";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "-ий.";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Повертає символ у зазначеній позиції.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";  // untranslated
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";  // untranslated
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Додати елемент до тексту.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "приєднати";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Додайте, вилучіть або змініть порядок секцій для переналаштування текстового блоку.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "до символу # з кінця";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "до символу #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "до останнього символу";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "у тексті";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "отримати підрядок від першого символу";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "отримати підрядок від символу # з кінця";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "отримати підрядок від символу #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "-ого.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Повертає заданий фрагмент тексту.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "знайти перше входження тексту";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "знайти останнє входження тексту";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Повертає індекс першого/останнього входження першого тексту в другий. Повертає %1, якщо текст не знайдено.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 є порожнім";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Повертає істину, якщо вказаний текст порожній.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_8.html";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "створити текст з";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Створити фрагмент тексту шляхом з'єднування будь-якого числа елементів.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "довжина %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Повертає число символів (включно з пропусками) у даному тексті.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "друк %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Надрукувати заданий текст, числа або інші значення.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Запитати у користувача число.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Запитати у користувача деякий текст.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "запит числа з повідомленням";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "запит тексту з повідомленням";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";  // untranslated
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://uk.wikipedia.org/wiki/Рядок_(програмування)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Символ, слово або рядок тексту.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "вилучити крайні пропуски з обох кінців";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "вилучити пропуски з лівого боку";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "вилучити пропуски з правого боку";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Повертає копію тексту з вилученими пропусками з одного або обох кінців.";
                +Blockly.Msg["TODAY"] = "Сьогодні";
                +Blockly.Msg["UNDO"] = "Скасувати";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "елемент";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Створити 'встановити %1'";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Повертає значення цієї змінної.";
                +Blockly.Msg["VARIABLES_SET"] = "встановити %1 до %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Створити 'отримати %1'";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Задає цю змінну рівною входу.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Змінна з назвою '%1' вже існує.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/vi.js b/blockly/webif/static/blockly/msg/js/vi.js
                new file mode 100644
                index 000000000..b5a1dd2a5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/vi.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.vi');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "Thêm Chú Giải";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";  // untranslated
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "Thay giá trị thành:";
                +Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";  // untranslated
                +Blockly.Msg["COLLAPSE_ALL"] = "Thu Nhỏ Mọi Mảnh";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "Thu Nhỏ Mảnh";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "màu 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "màu 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "tỉ lệ";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "pha";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Pha hai màu với nhau theo tỉ lệ (0 - 100).";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://vi.wikipedia.org/wiki/M%C3%A0u_s%E1%BA%AFc";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Chọn một màu từ bảng màu.";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "màu bất kỳ";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "chọn một màu bất kỳ.";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "màu xanh dương";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "màu xanh lá cây";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "màu đỏ";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "tạo màu từ";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Tạo màu từ ba màu: đỏ, xanh lá cây, xanh dương với số lượng cụ thể.  Mỗi số phải có giá trị từ 0 đến 100.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "thoát";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "sang lần lặp tiếp theo";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Thoát khỏi vòng lặp hiện tại.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Bỏ qua phần còn lại trong vòng lặp này, và sang lần lặp tiếp theo.";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Chú ý: Mảnh này chỉ có thế dùng trong các vòng lặp.";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "với mỗi thành phần %1 trong danh sách %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Trong một danh sách, lấy từng thành phần, gán vào biến \"%1\", rồi thực hiện một số lệnh.";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "đếm theo %1 từ %2 đến %3 mỗi lần thêm %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Đếm từ số đầu đến số cuối. Khi đến mỗi số, gán số vào biến \"%1\" rồi thực hiện các lệnh.";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Thêm một điều kiện vào mảnh nếu.";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Cuối cùng, khi không điều kiện nào đúng.";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Thêm, bỏ, hoặc đổi thứ tự các mảnh con để tạo cấu trúc mới cho mảnh nếu.";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "nếu không";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "nếu không nếu";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "nếu";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Nếu điều kiện đúng, thực hiện các lệnh.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu sai, thực hiện các lệnh sau.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu không, nếu điều kiện thứ hai đúng, thực hiện các lệnh thứ hai.";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu không, nếu điều kiện thứ hai đúng, thực hiện các lệnh thứ hai.  Nếu không điều kiện nào đúng, thực hiện các lệnh cuối cùng.";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "thực hiện";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "lặp lại %1 lần";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Thực hiện các lệnh vài lần.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "lặp lại cho đến khi";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "lặp lại trong khi";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Miễn là điều kiện còn sai, thì thực hiện các lệnh.  Khi điều kiện đúng thì ngưng.";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Miễn là điều kiện còn đúng, thì thực hiện các lệnh.";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "Xóa hết %1 mảnh?";
                +Blockly.Msg["DELETE_BLOCK"] = "Xóa Mảnh Này";
                +Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";  // untranslated
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";  // untranslated
                +Blockly.Msg["DELETE_X_BLOCKS"] = "Xóa %1 Mảnh";
                +Blockly.Msg["DISABLE_BLOCK"] = "Ngưng Tác Dụng";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "Tạo Bản Sao";
                +Blockly.Msg["ENABLE_BLOCK"] = "Phục Hồi Tác Dụng";
                +Blockly.Msg["EXPAND_ALL"] = "Mở Lớn Mọi Mảnh";
                +Blockly.Msg["EXPAND_BLOCK"] = "Mở Lớn Mảnh";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "Chỗ Gắn Bên Ngoài";
                +Blockly.Msg["HELP"] = "Trợ Giúp";
                +Blockly.Msg["INLINE_INPUTS"] = "Chỗ Gắn Cùng Dòng";
                +Blockly.Msg["IOS_CANCEL"] = "Hủy bỏ";
                +Blockly.Msg["IOS_ERROR"] = "Lỗi";
                +Blockly.Msg["IOS_OK"] = "OK";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";  // untranslated
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "Hàm này có chứa các input trùng nhau.";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";  // untranslated
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Thêm";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Thêm biến";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Xóa";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Bạn không thể không nhập tên biến.";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Đổi tên";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Tên biến";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "tạo danh sách trống";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Hoàn trả một danh sách, với độ dài 0, không có thành tố nào cả";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "danh sách";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Thêm, bỏ, hoặc sắp xếp lại các thành phần để tạo dựng mảnh danh sách này.";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "tạo danh sách gồm";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Thêm vật vào danh sách.";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Tạo một danh sách bao gồm nhiều vậts, với một số lượng bất kỳ.";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "đầu tiên";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "(đếm từ cuối) thứ";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "thứ";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "lấy thành tố";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "lấy và xóa thành tố";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "cuối cùng";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "bất kỳ";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "xóa thành tố";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Hoàn trả thành tố đầu tiên trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Hoàn trả thành tố trong danh sách ở vị trí ấn định.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Hoàn trả thành tố cuối cùng trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Hoàn trả một thành tố bất kỳ trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Hoàn trả và xóa thành tố đầu tiên trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Hoàn trả và xóa thành tố trong danh sách ở vị trí ấn định.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Hoàn trả và xóa thành tố cuối cùng trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Hoàn trả và xóa mộtthành tố bất kỳ trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Xóa thành tố đầu tiên trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Xóa thành tố trong danh sách ở vị trí ấn định.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Xóa thành tố cuối cùng trong danh sách.";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Xóa thành tố bất kỳ trong danh sách.";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "đến (đếm từ cuối) thứ";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "đến thứ";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "đến cuối cùng";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "lấy một danh sách con từ đầu tiên";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "lấy một danh sách con từ (đếm từ cuối) từ vị trí thứ";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "lấy một danh sách con từ vị trí thứ";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Lấy một mảng của danh sách này để tạo danh sách con.";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 là thành tố cuối cùng.";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 là thành tố đầu tiên.";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "tìm sự có mặt đầu tiên của vật";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "tìm sự có mặt cuối cùng của vật";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Hoàn trả vị trí xuất hiện đầu tiên/cuối cùng của vật trong danh sách. Nếu không tìm thấy thì hoàn trả số %1.";
                +Blockly.Msg["LISTS_INLIST"] = "trong dánh sách";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 trống rỗng";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Hoàn trả “đúng\" nếu danh sách không có thành tử nào.";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "độ dài của %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Hoàn trả độ dài của một danh sách.";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "tạo danh sách gồm một vật %1 lặp lại %2 lần";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Tạo danh sách gồm một số lượng vật nhất định với mỗi vật đều giống nhau.";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";  // untranslated
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "đảo ngược %1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "giá trị";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "chèn vào vị trí";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "đặt";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Chèn vật vào đầu danh sách.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Chèn vật vào danh sách theo vị trí ấn định.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Gắn thêm vật vào cuối danh sách.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Gắn chèn vật vào danh sách ở vị trí ngẫu nhiên.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Đặt giá trị của thành tố đầu tiên trong danh sách.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Đặt giá trị của thành tố ở vị trí ấn định trong một danh sách.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Đặt giá trị của thành tố cuối cùng trong danh sách.";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Đặt giá trị của thành tố ngẫu nhiên trong danh sách.";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";  // untranslated
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "tăng dần";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "giảm dần";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "sắp xếp %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";  // untranslated
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "chữ cái, không phân biệt hoa/thường";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "số";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "chữ cái";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "tạo danh sách từ văn bản";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "tạo văn bản từ danh sách";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Tách văn bản thành một danh sách các văn bản nhỏ, ngắt bởi các ký tự phân cách.";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "với ký tự phân cách";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "sai";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Hoàn trả \"đúng\" hoặc \"sai\".";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "đúng";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://vi.wikipedia.org/wiki/B%E1%BA%A5t_%C4%91%E1%BA%B3ng_th%E1%BB%A9c";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Hoàn trả giá trị \"đúng\" (true) nếu giá trị hai đầu vào bằng nhau.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất lớn hơn đầu vào thứ hai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất lớn hơn hoặc bằng đầu vào thứ hai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất nhỏ hơn đầu vào thứ hai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất nhỏ hơn hoặc bằng đầu vào thứ hai.";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Hoàn trả giá trị \"đúng\" (true) nếu giá trị hai đầu vào không bằng nhau.";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "không %1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Hoàn trả \"đúng\" (true) nếu đầu vào sai.  Hoàn trả \"sai\" (false) nếu đầu vào đúng.";
                +Blockly.Msg["LOGIC_NULL"] = "trống không";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Hoàn trả trống không.";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "và";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "hoặc";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Hoàn trả \"đúng\" (true) nếu cả hai đầu vào đều đúng.";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Hoàn trả \"đúng\" (true) nếu ít nhất một trong hai đầu vào đúng.";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "kiểm tra";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";  // untranslated
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "nếu sai";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "nếu đúng";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kiểm tra điều kiện. Nếu điều kiện đúng, hoàn trả giá trị từ mệnh đề \"nếu đúng\" nếu không đúng, hoàn trả giá trị từ mệnh đề \"nếu sai\".";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://vi.wikipedia.org/wiki/S%E1%BB%91_h%E1%BB%8Dc";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Hoàn trả tổng của hai con số.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Hoàn trả thương của hai con số.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Hoàn trả hiệu của hai con số.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Hoàn trả tích của hai con số.";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Hoàn trả số lũy thừa với số thứ nhất là cơ số và số thứ hai là số mũ.";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://vi.wikipedia.org/wiki/Ph%C3%A9p_c%E1%BB%99ng";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "cộng vào %1 giá trị %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Cộng số đầu vào vào biến \"%1\".";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Hoàn trả các đẳng số thường gặp: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (vô cực).";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "giới hạn %1 không dưới %2 không hơn %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Giới hạn số đầu vào để không dưới số thứ nhất và không hơn số thứ hai.";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "chia hết cho";
                +Blockly.Msg["MATH_IS_EVEN"] = "là số chẵn";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "là số âm";
                +Blockly.Msg["MATH_IS_ODD"] = "là số lẻ";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "là số dương";
                +Blockly.Msg["MATH_IS_PRIME"] = "là số nguyên tố";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "Kiểm tra con số xem nó có phải là số chẵn, lẻ, nguyên tố, nguyên, dương, âm,  hay xem nó có chia hết cho số đầu vào hay không.  Hoàn trả đúng hay sai.";
                +Blockly.Msg["MATH_IS_WHOLE"] = "là số nguyên";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "số dư của %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Chia số thứ nhất cho số thứ hai rồi hoàn trả số dư từ.";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://vi.wikipedia.org/wiki/S%E1%BB%91";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Một con số.";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "giá trị trung bình của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "số lớn nhât của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "số trung vị của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "số nhỏ nhất của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "các mode của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "một số bất kỳ của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "độ lệch chuẩn của một danh sách";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "tổng của một danh sách";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Hoàn trả giá trị trung bình từ của danh sách số.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Hoàn trả số lớn nhất trong tất cả các số trong danh sách.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Hoàn trả số trung vị của danh sách số.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Hoàn trả số nhỏ nhất trong tất cả các số trong danh sách.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Hoàn trả các số có mặt nhiều nhất trong danh sách.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Hoàn trả một số bất kỳ từ các số trong danh sách.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Hoàn trả độ lệch chuẩn của danh sách số.";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Hoàn trả tổng số của tất cả các số trong danh sách.";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "phân số bất kỳ";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Hoàn trả một phân số bất kỳ không nhỏ hơn 0.0 và không lớn hơn 1.0.";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "Một số nguyên bất kỳ từ %1 đến %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Hoàn trả một số nguyên bất kỳ lớn hơn hoặc bằng số đầu và nhỏ hơn hoặc bằng số sau.";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "làm tròn";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "làm tròn xuống";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "làm tròn lên";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Làm tròn lên hoặc tròn xuống số đầu vào.";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://vi.wikipedia.org/wiki/C%C4%83n_b%E1%BA%ADc_hai";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "giá trị tuyệt đối";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "căn bật hai";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Hoàn trả giá trị tuyệt đối của số đầu vào.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Hoàn trả lũy thừa của số e với số mũ đầu vào.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Hoàn trả lôgarit tự nhiên của số đầu vào.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Hoàn trả lôgarit cơ số 10 của số đầu vào.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Đổi dấu của số đầu vào: âm thành dương và dương thành âm, và hoàn trả số mới.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Hoàn trả lũy thừa của số 10 với số mũ đầu vào.";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Hoàn trả căn bật hai của số đầu vào.";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://vi.wikipedia.org/wiki/H%C3%A0m_l%C6%B0%E1%BB%A3ng_gi%C3%A1c";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Hoàn trả Arccos của một góc (theo độ).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Hoàn trả Arcsin của một góc (theo độ).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Hoàn trả Arctang của một góc (theo độ).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Hoàn trả Cos của một góc (theo độ).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Hoàn trả Sin của một góc (theo độ).";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Hoàn trả Tang của một góc (theo độ).";
                +Blockly.Msg["NEW_VARIABLE"] = "Tạo biến...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "Tên của biến mới:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "cho phép báo cáo";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "với:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Chạy một thủ tục không có giá trị hoàn trả.";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Chạy một thủ tục có giá trị hoàn trả.";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "với:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "Tạo mảnh \"thực hiện %1\"";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Mô tả hàm này...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "làm gì đó";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "thủ tục để";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Một thủ tục không có giá trị hoàn trả.";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "hoàn trả";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Một thủ tục có giá trị hoàn trả.";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Chú ý: Thủ tục này có lặp lại tên các tham số.";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Làm nổi bật thủ tục";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Khi điều kiện đúng thì hoàn trả một giá trị.";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Chú ý: Mảnh này chỉ có thể dùng trong một thủ tục.";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "biến:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Thêm một đầu vào cho hàm.";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "các tham số";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Thêm, xóa hoặc sắp xếp lại các đầu vào cho hàm này.";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "Một hàm có tên '%1' đã tồn tại.";
                +Blockly.Msg["REDO"] = "Làm lại";
                +Blockly.Msg["REMOVE_COMMENT"] = "Xóa Chú Giải";
                +Blockly.Msg["RENAME_VARIABLE"] = "Thay tên biến...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Thay tên tất cả \"%1\" biến này thành:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Thêm một mảng văn bản vào biến \"%1\".";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "thành chữ thường";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "thành Chữ In Đầu Mỗi Từ";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "thành CHỮ IN HOA";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Hoàn trả văn bản sau khi chuyển đổi chữ in hoa hay thường.";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "lấy ký tự đầu tiên";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "lấy từ phía cuối, ký tự thứ";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "lấy ký tự thứ";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "lấy ký tự cuối cùng";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "lấy ký tự bất kỳ";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "trong văn bản %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Hoàn trả ký tự ở vị trí đặt ra.";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";  // untranslated
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "đến %1 trong %2";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Đếm số lần một đoạn văn bản xuất hiện trong một đoạn văn bản khác.";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "thêm vật mới vào văn bản.";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "kết nối";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Thêm, bỏ, hoặc sắp xếp lại các thành phần để tạo dựng mảnh văn bản này.";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "đến từ phía cuối, ký tự thứ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "đến ký tự thứ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "đến ký tự cuối cùng";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "trong văn bản";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "lấy từ ký tự đầu tiên";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "lấy từ phía cuối, ký tự thứ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "lấy từ ký tự thứ";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Hoàn trả một mảng ký tự ấn định từ trong văn bản.";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "tìm sự có mặt đầu tiên của";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "tìm sự có mặt cuối cùng của";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "trong văn bản %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Hoàn trả vị trí xuất hiện đầu/cuối của văn bản thứ nhất trong văn bản thứ hai.  Nếu không tìm thấy thì hoàn trả số %1.";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 trống không";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Hoàn trả “đúng nếu văn bản không có ký tự nào.";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "";
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "tạo văn bản từ";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Tạo một văn bản từ các thành phần.";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "độ dài của %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Hoàn trả số lượng ký tự (kể cả khoảng trắng) trong văn bản đầu vào.";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "in lên màng hình %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "In ra màng hình một văn bản, con số, hay một giá trị đầu vào khác.";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Xin người dùng nhập vào một con số.";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Xin người dùng nhập vào một văn bản.";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "Xin người dùng nhập vào con số với dòng hướng dẫn";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "Xin người dùng nhập vào văn bản với dòng hướng dẫn";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";  // untranslated
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "thay thế %1 bằng %2 trong %3";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";  // untranslated
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "đảo ngược %1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Đảo ngược thứ tự của các chữ cái trong văn bản.";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/string_(computer_science)";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Một ký tự, một từ, hay một dòng.";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "cắt các không gian từ cả hai mặt của";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "cắt các không gian từ bên trái của";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "cắt các không gian từ bên phải của";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Hoàn trả bản sao của văn bản sau khi xóa khoảng trắng từ một hoặc hai bên.";
                +Blockly.Msg["TODAY"] = "Hôm nay";
                +Blockly.Msg["UNDO"] = "Hoàn tác";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "vật";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Tạo mảnh \"đặt vào %1\"";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Hoàn trả giá trị của.";
                +Blockly.Msg["VARIABLES_SET"] = "cho %1 bằng %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Tạo mảnh \"lấy %1\"";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Đặt giá trị của biến này thành...";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "Một biến có tên '%1' đã tồn tại.";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/zh-hans.js b/blockly/webif/static/blockly/msg/js/zh-hans.js
                new file mode 100644
                index 000000000..e93881786
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/zh-hans.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.zh.hans');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "添加注释";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "不能删除变量“%1”,因为它是功能“%2”定义的一部分";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "更改值:";
                +Blockly.Msg["CLEAN_UP"] = "整理块";
                +Blockly.Msg["COLLAPSE_ALL"] = "折叠块";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "折叠块";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "颜色1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "颜色2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "比例";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "混合";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "用一个给定的比率(0.0-1.0)混合两种颜色。";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://zh.wikipedia.org/wiki/颜色";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "从调色板中选择一种颜色。";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "随机颜色";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "随机选择一种颜色。";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "蓝色";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "绿色";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "红色";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "颜色";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "通过指定红色、绿色和蓝色的量创建一种颜色。所有的值必须在0和100之间。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "中断循环";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "继续下一次循环";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "中断包含它的循环。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "跳过这个循环的剩余部分,并继续下一次迭代。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "警告:此块仅可用于在一个循环内。";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "为每个项目 %1 在列表中 %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "遍历每个列表中的项目,将变量“%1”设定到该项中,然后执行某些语句。";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "使用 %1 从范围 %2 到 %3 每隔 %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "从起始数到结尾数中取出变量“%1”的值,按指定的时间间隔,执行指定的块。";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "在if语句块中增加一个条件。";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "添加一个最终的,包括所有情况的节到if块中。";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "增加、删除或重新排列各节来重新配置“if”块。";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "否则";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "否则如果";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "如果";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "如果值为真,执行一些语句。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "如果值为真,则执行第一块语句。否则,则执行第二块语句。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "如果第一个值为真,则执行第一块的语句。否则,如果第二个值为真,则执行第二块的语句。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "如果第一个值为真,则执行第一块对语句。否则,如果第二个值为真,则执行语句的第二块。如果没有值为真,则执行最后一块的语句。";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://zh.wikipedia.org/wiki/For循环";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "执行";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "重复 %1 次";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "多次执行一些语句。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "重复直到";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "重复当";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "只要值为假,执行一些语句。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "只要值为真,执行一些语句。";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "删除所有%1块吗?";
                +Blockly.Msg["DELETE_BLOCK"] = "删除块";
                +Blockly.Msg["DELETE_VARIABLE"] = "删除“%1”变量";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "删除“%2”变量的%1用途么?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "删除 %1 块";
                +Blockly.Msg["DISABLE_BLOCK"] = "禁用块";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "复制";
                +Blockly.Msg["ENABLE_BLOCK"] = "启用块";
                +Blockly.Msg["EXPAND_ALL"] = "展开块";
                +Blockly.Msg["EXPAND_BLOCK"] = "展开块";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "外部输入";
                +Blockly.Msg["HELP"] = "帮助";
                +Blockly.Msg["INLINE_INPUTS"] = "单行输入";
                +Blockly.Msg["IOS_CANCEL"] = "取消";
                +Blockly.Msg["IOS_ERROR"] = "错误";
                +Blockly.Msg["IOS_OK"] = "确定";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+添加输入";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "允许声明";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "此功能有重复输入内容。";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "输入";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "添加";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+添加变量";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "删除";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "您不能使用空变量名称。";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "重命名";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "变量名称";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "创建空列表";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "返回一个列表,长度为 0,不包含任何数据记录";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "列表";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "增加、删除或重新排列各部分以此重新配置这个列表块。";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "建立列表使用";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "将一个项添加到列表中。";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "建立一个具有任意数量项目的列表。";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "第一";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "倒数第#";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "取得";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "取出并移除";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "最后";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "随机";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "移除";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "空白";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "返回列表中的第一个项目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "返回在列表中的指定位置的项。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "返回列表中的最后一项。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "随机返回列表中的一个项目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "移除并返回列表中的第一个项目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "移除并返回列表中的指定位置的项。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "移除并返回列表中的最后一个项目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "移除并返回列表中的一个随机项目中。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "移除列表中的第一项";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "移除在列表中的指定位置的项。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "移除列表中的最后一项";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "删除列表中的一个随机的项。";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "到倒数第#";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "到#";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "到最后";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "从头获得子列表";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "从倒数#取得子列表";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "从#取得子列表";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "空白";
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "复制列表中指定的部分。";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1是最后一项。";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1是第一个项目。";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "找出第一个项出现";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "找出最后一个项出现";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "返回在列表中的第一/最后一个匹配项的索引值。如果找不到项目则返回%1。";
                +Blockly.Msg["LISTS_INLIST"] = "在列表中";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1是空的";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "如果改列表为空,则返回真。";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1的长度";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "返回列表的长度。";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "建立列表使用项 %1 重复 %2 次";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "建立包含指定重复次数的值的列表。";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "倒转%1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "倒转一个列表的拷贝。";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "为";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "插入在";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "设置";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "在列表的起始处添加该项。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "插入在列表中指定位置的项。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "将该项追加到列表的末尾。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "在列表中随机插入项。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "设置列表中的第一个项目。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "设置在列表中指定位置的项。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "设置列表中的最后一项。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "设置列表中一个随机的项目。";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "升序";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "降序";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "排序%1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "排序一个列表的拷贝。";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "按字母排序,忽略大小写";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "按数字排序";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "按字母排序";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "从文本制作列表";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "从列表拆出文本";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "加入文本列表至一个文本,由分隔符分隔。";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "拆分文本到文本列表,按每个分隔符拆分。";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "用分隔符";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "假";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "返回真或假。";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "真";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://zh.wikipedia.org/wiki/不等";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "如果两个输入结果相等,则返回真。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "如果第一个输入结果比第二个大,则返回真。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "如果第一个输入结果大于或等于第二个输入结果,则返回真。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "如果第一个输入结果比第二个小,则返回真。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "如果第一个输入结果小于或等于第二个输入结果,则返回真。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "如果两个输入结果不相等,则返回真。";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "非%1";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "如果输入结果为假,则返回真;如果输入结果为真,则返回假。";
                +Blockly.Msg["LOGIC_NULL"] = "空";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "返回空值。";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "和";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "或";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "如果两个输入结果都为真,则返回真。";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "如果至少有一个输入结果为真,则返回真。";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "测试";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://zh.wikipedia.org/wiki/条件运算符";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "如果为假";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "如果为真";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "检查“test”中的条件。如果条件为真,则返回“if true”的值,否则,则返回“if false”的值。";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://zh.wikipedia.org/wiki/算术";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "返回两个数字的和。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "返回两个数字的商。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "返回两个数字的区别。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "返回两个数字的乘积。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "返回第一个数的第二个数次幂。";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://zh.wikipedia.org/wiki/加法";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "更改 %1 从 %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "将一个数添加到变量“%1”。";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://zh.wikipedia.org/wiki/数学常数";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "返回一个常见常量:π (3.141…)、e (2.718…)、φ (1.618…)、平方根 (1.414…)、开平方根 (0.707…)或∞ (infinity)。";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "限制数字 %1 介于 (低) %2 到 (高) %3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "限制数字介于两个指定的数字之间";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "可被整除";
                +Blockly.Msg["MATH_IS_EVEN"] = "是偶数";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "为负";
                +Blockly.Msg["MATH_IS_ODD"] = "是奇数";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "为正";
                +Blockly.Msg["MATH_IS_PRIME"] = "是质数";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "如果数字是偶数、奇数、非负整数、正数、负数或如果它可被某数字整除,则返回真或假。";
                +Blockly.Msg["MATH_IS_WHOLE"] = "为整数";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://zh.wikipedia.org/wiki/模除";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "取余数自 %1 ÷ %2";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "返回这两个数字相除后的余数。";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://zh.wikipedia.org/wiki/数";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "一个数字。";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "列表中的平均数";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "列表中的最大值";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "列表中位数";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "列表中的最小值";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "列表模式";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "列表的随机项";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "列表中的标准差";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "列表中的数的总和";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "返回列表中的数值的平均值。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "返回列表中最大数。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "返回列表中的中位数。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "返回列表中最小数。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "返回列表中的最常见的项的列表。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "从列表中返回一个随机的元素。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "返回列表的标准偏差。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "返回列表中的所有数字的和。";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://zh.wikipedia.org/wiki/随机数生成器";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "随机分数";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "返回介于(包含)0.0到1.0之间的随机数。";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://zh.wikipedia.org/wiki/随机数生成器";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "从 %1 到 %2 之间的随机整数";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "返回两个指定的范围(含)之间的随机整数。";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://zh.wikipedia.org/wiki/数值修约";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "向下舍入";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "向下舍入";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "向上舍入";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "数字向上或向下舍入。";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://zh.wikipedia.org/wiki/平方根";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "绝对";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "平方根";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "返回一个数的绝对值。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "返回一个数的e次幂。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "返回一个数的自然对数。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "返回一个数的对数。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "返回一个数的逻辑非。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "返回一个数的10次幂。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "返回一个数的平方根。";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://zh.wikipedia.org/wiki/三角函数";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "返回一个数的反余弦值。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "返回一个数的反正弦值。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "返回指定角度的反正切值。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "返回指定角度的余弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "返回指定角度的正弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "返回指定角度的正切值(非弧度)。";
                +Blockly.Msg["NEW_VARIABLE"] = "创建变量...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "新变量的名称:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "空白";
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "允许声明";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "与:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程序";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "运行用户定义的函数“%1”。";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程序";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "运行用户定义的函数“%1”,并使用它的输出值。";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "与:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "创建“%1”";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "描述该功能...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "空白";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程序";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "做点什么";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "至";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "创建一个不带输出值的函数。";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程序";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "返回";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "创建一个有输出值的函数。";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "警告: 此函数具有重复参数。";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "突出显示函数定义";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "如果值为真,则返回第二个值。";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "警告: 仅在定义函数内可使用此块。";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "输入名称:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "添加函数输入。";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "输入";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "添加、删除或重新排此函数的输入。";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "已存在名为“%1”的步骤。";
                +Blockly.Msg["REDO"] = "重做";
                +Blockly.Msg["REMOVE_COMMENT"] = "删除注释";
                +Blockly.Msg["RENAME_VARIABLE"] = "重命名变量...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "将所有“%1”变量重命名为:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "至%1附加文本%2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "将一些文本追加到变量“%1”。";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "转为小写";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "将首字母大写";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "转为大写";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "在不同大小写下复制并返回这段文字。";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "获得第一个字符";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "获得倒数第#个字符";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "获得字符#";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "获得最后一个字符";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "获取随机的字母";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "空白";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "在文本%1 %2中";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "返回位于指定位置的字母。";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "将%1计算在%2之内";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "计算在一些其他文本中,部分文本重现了多少次。";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "将一个项添加到文本中。";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "加入";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "添加、移除或重新排列各节来重新配置这个文本块。";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "到倒数第#个字符";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "到字符#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "到最后一个字符";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "自文本";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "取得一段字串自第一个字符";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "取得一段字串自倒数第#个字符";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "取得一段字串自#";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "空白";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "返回指定的部分文本。";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "寻找第一个出现的文本";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "寻找最后一个出现的文本";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "在文本%1 %2 %3中";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "返回在第二个字串中的第一/最后一个匹配项的索引值。如果未找到则返回%1。";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1是空的";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "如果提供的文本为空,则返回真。";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "建立字串使用";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "通过串起任意数量的项以建立一段文字。";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1的长度";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "返回提供文本的字母数(包括空格)。";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "打印%1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "打印指定的文字、数字或其他值。";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "提示用户输入数字。";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "提示用户输入一些文本。";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "输入数字并显示提示消息";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "输入数字并显示提示消息";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "在%3中,将%1替换为%2";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "在某些其他文本中,替换部分文本的所有事件。";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "倒转%1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "倒转文本中字符的排序。";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://zh.wikipedia.org/wiki/字符串";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "一个字母、单词或一行文本。";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "消除两侧空格";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "消除左侧空格";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "消除右侧空格";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "复制这段文字的同时删除两端多余的空格。";
                +Blockly.Msg["TODAY"] = "今天";
                +Blockly.Msg["UNDO"] = "撤销";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "项目";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "创建“设定%1”";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "返回此变量的值。";
                +Blockly.Msg["VARIABLES_SET"] = "赋值 %1 到 %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "创建“获得%1”";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "设置此变量,以使它和输入值相等。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "已存在名为“%1”的变量。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/js/zh-hant.js b/blockly/webif/static/blockly/msg/js/zh-hant.js
                new file mode 100644
                index 000000000..dfee5f22c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/js/zh-hant.js
                @@ -0,0 +1,426 @@
                +// This file was automatically generated.  Do not modify.
                +
                +'use strict';
                +
                +goog.provide('Blockly.Msg.zh.hant');
                +
                +goog.require('Blockly.Msg');
                +
                +Blockly.Msg["ADD_COMMENT"] = "加入註解";
                +Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "無法刪除變數「%1」,因為這是功能「%2」定義的一部份內容";
                +Blockly.Msg["CHANGE_VALUE_TITLE"] = "修改值:";
                +Blockly.Msg["CLEAN_UP"] = "整理積木";
                +Blockly.Msg["COLLAPSE_ALL"] = "收合積木";
                +Blockly.Msg["COLLAPSE_BLOCK"] = "收合積木";
                +Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "顏色 1";
                +Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "顏色 2";
                +Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/";  // untranslated
                +Blockly.Msg["COLOUR_BLEND_RATIO"] = "比例";
                +Blockly.Msg["COLOUR_BLEND_TITLE"] = "混合";
                +Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "用一個給定的比率(0.0-1.0)混合兩種顏色。";
                +Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://zh.wikipedia.org/wiki/顏色";
                +Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "從調色板中選擇一種顏色。";
                +Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";  // untranslated
                +Blockly.Msg["COLOUR_RANDOM_TITLE"] = "隨機顏色";
                +Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "隨機選擇一種顏色。";
                +Blockly.Msg["COLOUR_RGB_BLUE"] = "藍";
                +Blockly.Msg["COLOUR_RGB_GREEN"] = "綠";
                +Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html";  // untranslated
                +Blockly.Msg["COLOUR_RGB_RED"] = "紅";
                +Blockly.Msg["COLOUR_RGB_TITLE"] = "顏色";
                +Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "透過指定紅、綠、 藍色的值來建立一種顏色。所有的值必須介於 0 和 100 之間。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";  // untranslated
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "中斷循環";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "繼續下一個循環";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "中斷當前的循環。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "跳過這個循環的其餘步驟,並繼續下一次的循環。";
                +Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "警告: 此積木僅可用於迴圈內。";
                +Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";  // untranslated
                +Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "取出每個 %1 自清單 %2";
                +Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "遍歷每個清單中的項目,將變數「%1」設定到該項目中,然後執行某些陳述式。";
                +Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";  // untranslated
                +Blockly.Msg["CONTROLS_FOR_TITLE"] = "循環計數 %1 從 %2 到 %3 間隔數 %4";
                +Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "從起始數到結尾數中取出變數「%1」的值,按指定的時間間隔,執行指定的積木。";
                +Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "添加條件到「如果」積木。";
                +Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "加入一個最終、所有條件都執行的區塊到「如果」積木中。";
                +Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";  // untranslated
                +Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "添加、 刪除或重新排列各區塊以重新配置這個「如果」積木。";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "否則";
                +Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "否則如果";
                +Blockly.Msg["CONTROLS_IF_MSG_IF"] = "如果";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "當值為 true 時,執行一些陳述式。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "當值為 true 時,執行第一個陳述式,否則,執行第二個陳述式。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "如果第一個值為 true,則執行第一個陳述式。否則,當第二個值為 true 時,則執行第二個陳述式。";
                +Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "如果第一個值為 true,則執行第一個陳述式。否則當第二個值為 true 時,則執行第二個陳述式。如果前幾個敘述都不為 ture,則執行最後一個陳述式。";
                +Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://zh.wikipedia.org/wiki/For迴圈";
                +Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "執行";
                +Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "重複 %1 次";
                +Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "重複執行指定的陳述式多次。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";  // untranslated
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "重複 直到";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "重複 當";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "當值為 false 時,執行一些陳述式。";
                +Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "當值為 true 時,執行一些陳述式。";
                +Blockly.Msg["DELETE_ALL_BLOCKS"] = "刪除共 %1 個積木?";
                +Blockly.Msg["DELETE_BLOCK"] = "刪除積木";
                +Blockly.Msg["DELETE_VARIABLE"] = "刪除變數「%1」";
                +Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "刪除%1使用的「%2」變數?";
                +Blockly.Msg["DELETE_X_BLOCKS"] = "刪除 %1 個積木";
                +Blockly.Msg["DISABLE_BLOCK"] = "停用積木";
                +Blockly.Msg["DUPLICATE_BLOCK"] = "複製";
                +Blockly.Msg["ENABLE_BLOCK"] = "啟用積木";
                +Blockly.Msg["EXPAND_ALL"] = "展開積木";
                +Blockly.Msg["EXPAND_BLOCK"] = "展開積木";
                +Blockly.Msg["EXTERNAL_INPUTS"] = "多行輸入";
                +Blockly.Msg["HELP"] = "幫助";
                +Blockly.Msg["INLINE_INPUTS"] = "單行輸入";
                +Blockly.Msg["IOS_CANCEL"] = "取消";
                +Blockly.Msg["IOS_ERROR"] = "錯誤";
                +Blockly.Msg["IOS_OK"] = "確定";
                +Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ 添加輸入";
                +Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "允許聲明";
                +Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "此功能有重複輸入內容。";
                +Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "輸入";
                +Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "添加";
                +Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ 添加變數";
                +Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "刪除";
                +Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "您不能使用不帶名的變數名稱。";
                +Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "重新命名";
                +Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "變數名稱";
                +Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";  // untranslated
                +Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "建立空的清單";
                +Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "返回一個長度(項目數量)為 0 的清單,不包含任何資料記錄";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "清單";
                +Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "添加、刪除或重新排列各區塊以重新配置這個「清單」積木。";
                +Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "使用這些值建立清單";
                +Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "添加一個項目到清單裡。";
                +Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "建立一個具備任意數量項目的清單。";
                +Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "第一筆";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "倒數第 # 筆";
                +Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_GET"] = "取得";
                +Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "取得並移除";
                +Blockly.Msg["LISTS_GET_INDEX_LAST"] = "最後一筆";
                +Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "隨機";
                +Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "移除";
                +Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "返回清單中的第一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "返回在清單中指定位置的項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "返回清單中的最後一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "返回清單中隨機一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "移除並返回清單中的第一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "移除並返回清單中的指定位置的項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "移除並返回清單中的最後一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "移除並返回清單中的隨機項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "移除清單中的第一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "移除在清單中指定位置的項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "移除清單中的最後一個項目。";
                +Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "移除清單中隨機一個項目。";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "到 # 倒數";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "到 #";
                +Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "到 最後面";
                +Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "取得子清單 從 最前面";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "取得子清單 從 # 倒數";
                +Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "取得子清單 從 #";
                +Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";  // untranslated
                +Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "複製清單中指定的部分。";
                +Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 是最後一個項目。";
                +Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 是第一個項目。";
                +Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "從 最前面 索引項目";
                +Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";  // untranslated
                +Blockly.Msg["LISTS_INDEX_OF_LAST"] = "從 最後面 索引項目";
                +Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "在清單中檢索是否有包含項目,如果有,返回從頭/倒數算起的索引值。如果沒有則返回 %1。";
                +Blockly.Msg["LISTS_INLIST"] = "自清單";
                +Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";  // untranslated
                +Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 值為空";
                +Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "如果該清單為空,則返回 true。";
                +Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";  // untranslated
                +Blockly.Msg["LISTS_LENGTH_TITLE"] = "長度 %1";
                +Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "返回清單的長度(項目數)。";
                +Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";  // untranslated
                +Blockly.Msg["LISTS_REPEAT_TITLE"] = "建立清單使用項目 %1 重複 %2 次";
                +Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "建立一個清單,項目中包含指定重複次數的值。";
                +Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
                +Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "反轉%1";
                +Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "反轉清單的複製內容。";
                +Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";  // untranslated
                +Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "為";
                +Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "添加";
                +Blockly.Msg["LISTS_SET_INDEX_SET"] = "設定";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "添加一個項目到清單中的第一個位置。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "添加一個項目到清單中的指定位置。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "添加一個項目到清單中的最後一個位置。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "添加一個項目到清單中的隨機位置。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "設定清單中的第一個項目。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "設定清單中指定位置的項目。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "設定清單中的最後一個項目。";
                +Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "設定清單中隨機一個項目。";
                +Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
                +Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "升序";
                +Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "降序";
                +Blockly.Msg["LISTS_SORT_TITLE"] = "排列 %1 %2 %3";
                +Blockly.Msg["LISTS_SORT_TOOLTIP"] = "排序清單的複製內容。";
                +Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "依字母排序,忽略大小寫";
                +Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "依數字";
                +Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "依字母";
                +Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";  // untranslated
                +Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "從文本製作清單";
                +Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "從清單拆出文本";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "串起清單項目成一個文本,並用分隔符號分開。";
                +Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "將文本變成清單項目,按分隔符號拆分。";
                +Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "用分隔符";
                +Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
                +Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";  // untranslated
                +Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "返回 true 或 false。";
                +Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "true";
                +Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://zh.wikipedia.org/wiki/不等";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "如果這兩個輸入區塊的結果相等,返回 true。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "如果第一個輸入結果大於第二個,返回 true。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "如果第一個輸入結果大於或等於第二個,返回 true。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "如果第一個輸入結果比第二個小,返回 true。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "如果第一個輸入結果小於或等於第二個,返回 true。";
                +Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "如果這兩個輸入區塊的結果不相等,返回 true。";
                +Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";  // untranslated
                +Blockly.Msg["LOGIC_NEGATE_TITLE"] = "%1 不成立";
                +Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "如果輸入結果是 false,則返回 true。如果輸入結果是 true,則返回 false。";
                +Blockly.Msg["LOGIC_NULL"] = "null";
                +Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";  // untranslated
                +Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "返回 null。";
                +Blockly.Msg["LOGIC_OPERATION_AND"] = "且";
                +Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";  // untranslated
                +Blockly.Msg["LOGIC_OPERATION_OR"] = "或";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "如果兩個輸入結果都為 true,則返回 true。";
                +Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "如果至少一個輸入結果為 true,返回 true。";
                +Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "測試";
                +Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://zh.wikipedia.org/wiki/條件運算符";
                +Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "如果為 false";
                +Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "如果為 true";
                +Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "檢查「測試」中的條件。如果條件為 true,將返回「如果為 true」的值;否則,返回「如果為 false」的值。";
                +Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";  // untranslated
                +Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://zh.wikipedia.org/wiki/算術";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "返回兩個數字的總和。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "返回兩個數字的商。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "返回兩個數字的差。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "返回兩個數字的乘積。";
                +Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "返回第二個數字的指數的第一個數字。";
                +Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://zh.wikipedia.org/wiki/加法";
                +Blockly.Msg["MATH_CHANGE_TITLE"] = "修改 %1 自 %2";
                +Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "將數字加到變數「%1」。";
                +Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://zh.wikipedia.org/wiki/數學常數";
                +Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "返回一個的常見常量: π (3.141......),e (2.718...)、 φ (1.618...)、 開方(2) (1.414......)、 開方(½) (0.707......) 或 ∞ (無窮大)。";
                +Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";  // untranslated
                +Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "限制數字 %1 介於(低)%2 到(高)%3";
                +Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "限制數字介於兩個指定的數字之間(包含)。";
                +Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";  // untranslated
                +Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "可被整除";
                +Blockly.Msg["MATH_IS_EVEN"] = "是偶數";
                +Blockly.Msg["MATH_IS_NEGATIVE"] = "是負值";
                +Blockly.Msg["MATH_IS_ODD"] = "是奇數";
                +Blockly.Msg["MATH_IS_POSITIVE"] = "是正值";
                +Blockly.Msg["MATH_IS_PRIME"] = "是質數";
                +Blockly.Msg["MATH_IS_TOOLTIP"] = "如果數字是偶數,奇數,非負整數,正數、 負數,或如果它是可被某數字整除,則返回 true 或 false。";
                +Blockly.Msg["MATH_IS_WHOLE"] = "是非負整數";
                +Blockly.Msg["MATH_MODULO_HELPURL"] = "https://zh.wikipedia.org/wiki/模除";
                +Blockly.Msg["MATH_MODULO_TITLE"] = "%1 除以 %2 的餘數";
                +Blockly.Msg["MATH_MODULO_TOOLTIP"] = "回傳兩個數字相除的餘數。";
                +Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";  // untranslated
                +Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://zh.wikipedia.org/wiki/數";
                +Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "一個數字。";
                +Blockly.Msg["MATH_ONLIST_HELPURL"] = "";  // untranslated
                +Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "平均數 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "最大值 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "中位數 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "最小值 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "比較眾數 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "隨機抽取 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "標準差 自清單";
                +Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "數字總和 自清單";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "返回清單中數值的平均值(算術平均值)。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "返回清單項目中最大的數字。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "返回清單中數值的中位數。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "返回清單項目中最小的數字。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "返回一個清單中的最常見的項目。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "從清單中返回一個隨機的項目。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "返回清單中數字的標準差。";
                +Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "返回清單中的所有數字的總和。";
                +Blockly.Msg["MATH_POWER_SYMBOL"] = "^";  // untranslated
                +Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://zh.wikipedia.org/wiki/隨機數生成器";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "隨機取分數";
                +Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "在 0.0(包含)和 1.0(不包含)之間隨機取一個數。";
                +Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://zh.wikipedia.org/wiki/隨機數生成器";
                +Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "隨機取數 %1 到 %2";
                +Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "在指定二個數之間隨機取一個數(包含)。";
                +Blockly.Msg["MATH_ROUND_HELPURL"] = "https://zh.wikipedia.org/wiki/數值簡化";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "四捨五入";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "無條件捨去";
                +Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "無條件進位";
                +Blockly.Msg["MATH_ROUND_TOOLTIP"] = "將數字無條件進位或無條件捨去。";
                +Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://zh.wikipedia.org/wiki/平方根";
                +Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "絕對值";
                +Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "開根號";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "返回指定數字的絕對值。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "返回指定數字指數的 e";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "返回指定數字的自然對數。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "返回指定數字的對數。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "返回指定數字的 negation。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "返回指定數字指數的10的冪次。";
                +Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "返回指定數字的平方根。";
                +Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";  // untranslated
                +Blockly.Msg["MATH_TRIG_ACOS"] = "acos";  // untranslated
                +Blockly.Msg["MATH_TRIG_ASIN"] = "asin";  // untranslated
                +Blockly.Msg["MATH_TRIG_ATAN"] = "atan";  // untranslated
                +Blockly.Msg["MATH_TRIG_COS"] = "cos";  // untranslated
                +Blockly.Msg["MATH_TRIG_HELPURL"] = "https://zh.wikipedia.org/wiki/三角函數";
                +Blockly.Msg["MATH_TRIG_SIN"] = "sin";  // untranslated
                +Blockly.Msg["MATH_TRIG_TAN"] = "tan";  // untranslated
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "返回指定角度的反餘弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "返回指定角度的反正弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "返回指定角度的反正切值。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "返回指定角度的餘弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "返回指定角度的正弦值(非弧度)。";
                +Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "返回指定角度的正切值(非弧度)。";
                +Blockly.Msg["NEW_VARIABLE"] = "建立變數...";
                +Blockly.Msg["NEW_VARIABLE_TITLE"] = "新變數名稱:";
                +Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "允許陳述式";
                +Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "與:";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/%E5%AD%90%E7%A8%8B%E5%BA%8F";
                +Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "執行使用者定義的函式「%1」。";
                +Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/%E5%AD%90%E7%A8%8B%E5%BA%8F";
                +Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "執行使用者定義的函式「%1」,並使用它的回傳值。";
                +Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "與:";
                +Blockly.Msg["PROCEDURES_CREATE_DO"] = "建立「%1」";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "描述此函式...";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";  // untranslated
                +Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程式";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "做些什麼";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "到";
                +Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "創建一個無回傳值的函式。";
                +Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://zh.wikipedia.org/wiki/子程式";
                +Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "返回";
                +Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "創建一個有回傳值的的函式。";
                +Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "警告: 此函式中有重複的參數。";
                +Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "反白顯示函式定義";
                +Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";  // untranslated
                +Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "如果值為 true,則返回第二個值。";
                +Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "警告:這個積木只可以在定義函式時使用。";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "輸入名稱:";
                +Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "添加一個輸入區塊到函式。";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "輸入";
                +Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "添加、刪除或重新排列此函式的輸入。";
                +Blockly.Msg["PROCEDURE_ALREADY_EXISTS"] = "一個名為「%1」的程序已存在。";
                +Blockly.Msg["REDO"] = "重試";
                +Blockly.Msg["REMOVE_COMMENT"] = "移除註解";
                +Blockly.Msg["RENAME_VARIABLE"] = "重新命名變數...";
                +Blockly.Msg["RENAME_VARIABLE_TITLE"] = "將所有「%1」變數重新命名為:";
                +Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_APPEND_TITLE"] = "至 %1 套用文字 %2";
                +Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "添加一些文字到變數「%1」之後。";
                +Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";  // untranslated
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "轉成 英文小寫";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "轉成 英文首字大寫";
                +Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "轉成 英文大寫";
                +Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "使用不同的大小寫複製這段文字。";
                +Blockly.Msg["TEXT_CHARAT_FIRST"] = "取得 第一個字元";
                +Blockly.Msg["TEXT_CHARAT_FROM_END"] = "取得 倒數第 # 個字元";
                +Blockly.Msg["TEXT_CHARAT_FROM_START"] = "取得 字元 #";
                +Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";  // untranslated
                +Blockly.Msg["TEXT_CHARAT_LAST"] = "取得 最後一個字元";
                +Blockly.Msg["TEXT_CHARAT_RANDOM"] = "取得 任意字元";
                +Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
                +Blockly.Msg["TEXT_CHARAT_TITLE"] = "在文字 %1 %2";
                +Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "返回位於指定位置的字元。";
                +Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
                +Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "在%2計算%1";
                +Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "計算某些文字在內容裡的出現次數。";
                +Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "添加一個項目到字串中。";
                +Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "加入";
                +Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "添加、刪除或重新排列各區塊以重新配置這個文字積木。";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "到 倒數第 # 個字元";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "到 字元 #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "到 最後一個字元";
                +Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "在字串";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "取得 第一個字元";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "取得 倒數第 # 個字元";
                +Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "取得 字元 #";
                +Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";  // untranslated
                +Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "返回指定的部分文字。";
                +Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";  // untranslated
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "從 最前面 索引字串";
                +Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "從 最後面 索引字串";
                +Blockly.Msg["TEXT_INDEXOF_TITLE"] = "在文字 %1 %2 %3";
                +Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "在字串1中檢索是否有包含字串2,如果有,返回從頭/倒數算起的索引值。如果沒有則返回 %1。";
                +Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";  // untranslated
                +Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 為空";
                +Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "如果提供的字串為空,則返回 true。";
                +Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";  // untranslated
                +Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "字串組合";
                +Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "通過連接任意數量的項目來建立一串文字。";
                +Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";  // untranslated
                +Blockly.Msg["TEXT_LENGTH_TITLE"] = "長度 %1";
                +Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "返回這串文字的字元數(包含空格)。";
                +Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";  // untranslated
                +Blockly.Msg["TEXT_PRINT_TITLE"] = "輸出 %1";
                +Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "輸出指定的文字、 數字或其他值。";
                +Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";  // untranslated
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "輸入數字";
                +Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "輸入文字";
                +Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "輸入 數字 並顯示提示訊息";
                +Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "輸入 文字 並顯示提示訊息";
                +Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
                +Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "在%3以%2取代%1";
                +Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "取代在內容裡的全部某些文字。";
                +Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
                +Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "反轉%1";
                +Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "反轉排序在文字裡的字元。";
                +Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://zh.wikipedia.org/wiki/字串";
                +Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "一個字元、一個單詞,或一串文字。";
                +Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";  // untranslated
                +Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "消除兩側空格";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "消除左側空格";
                +Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "消除右側空格";
                +Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "複製這段文字,同時刪除兩端多餘的空格。";
                +Blockly.Msg["TODAY"] = "今天";
                +Blockly.Msg["UNDO"] = "復原";
                +Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "變數";
                +Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "建立「賦值 %1」";
                +Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";  // untranslated
                +Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "返回此變數的值。";
                +Blockly.Msg["VARIABLES_SET"] = "賦值 %1 成 %2";
                +Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "建立「取得 %1」";
                +Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";  // untranslated
                +Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "設定此變數,好和輸入結果相等。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "一個名為「%1」的變數已存在。";
                +Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another variable of type '%2'.";  // untranslated
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +
                +Blockly.Msg["MATH_HUE"] = "230";
                +Blockly.Msg["LOOPS_HUE"] = "120";
                +Blockly.Msg["LISTS_HUE"] = "260";
                +Blockly.Msg["LOGIC_HUE"] = "210";
                +Blockly.Msg["VARIABLES_HUE"] = "330";
                +Blockly.Msg["TEXTS_HUE"] = "160";
                +Blockly.Msg["PROCEDURES_HUE"] = "290";
                +Blockly.Msg["COLOUR_HUE"] = "20";
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/json/ab.json b/blockly/webif/static/blockly/msg/json/ab.json
                new file mode 100644
                index 000000000..bc6104bf7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ab.json
                @@ -0,0 +1,191 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Абухба Андрей"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "аелемент",
                +	"TODAY": "Иахьа",
                +	"DUPLICATE_BLOCK": "Акопиа ахыхтәуп",
                +	"ADD_COMMENT": "Иацҵатәуп ахцәажәара",
                +	"REMOVE_COMMENT": "Ианыхтәуп ахцәажәара",
                +	"DELETE_BLOCK": "Ианыхтәуп аблок",
                +	"DELETE_X_BLOCKS": "Ианыхтәуп %1 блокк",
                +	"DELETE_ALL_BLOCKS": "Ианыхтәуп аблокқәа (%1) зегьы?",
                +	"CLEAN_UP": "Иқәгатәуп аблокқәа",
                +	"COLLAPSE_BLOCK": "Иеикәрҳәтәуп Аблокқәа",
                +	"COLLAPSE_ALL": "Иеикәрҳәтәуп Аблокқәа",
                +	"EXPAND_BLOCK": "Иаарҧштәуп Аблокқәа",
                +	"EXPAND_ALL": "Иаарҧштәуп Аблокқәа",
                +	"DISABLE_BLOCK": "Иаҿыхтәуп Аблок",
                +	"ENABLE_BLOCK": "Иаҿыхтәуп Аблокқәа",
                +	"HELP": "Ацхыраара",
                +	"UNDO": "Иаҟәыхтәуп",
                +	"REDO": "Аиҭаҟаҵара",
                +	"CHANGE_VALUE_TITLE": "Ишәыҧсах аҵакы",
                +	"RENAME_VARIABLE": "Аҽеиҭак ахьӡ ҧсахтәуп",
                +	"NEW_VARIABLE": "Иаҧҵатәуп аҽеиҭак",
                +	"NEW_VARIABLE_TITLE": "Аҽеиҭак ахьӡ ҿыц:",
                +	"DELETE_VARIABLE": "Ианыхтәуп аҽеиҭак '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://ru.wikipedia.org/wiki/Аҧштәы",
                +	"COLOUR_PICKER_TOOLTIP": "Иалышәх аҧштәы",
                +	"COLOUR_RANDOM_TITLE": "иарбанзаалакь аҧштәы",
                +	"COLOUR_RANDOM_TOOLTIP": "Иалнахуеит аҧштәы машәыршақә",
                +	"COLOUR_RGB_TITLE": "аҧштәы аҟынтәи",
                +	"COLOUR_RGB_RED": "аҟаҧшь",
                +	"COLOUR_RGB_GREEN": "аиаҵәа",
                +	"COLOUR_RGB_BLUE": "жәҩангәҧштәы",
                +	"COLOUR_BLEND_TITLE": "еилаҵатәуп",
                +	"COLOUR_BLEND_COLOUR1": "аҧштәы 1",
                +	"COLOUR_BLEND_COLOUR2": "аҧштәы 2",
                +	"COLOUR_BLEND_RATIO": "аҧштәы 1 ахәҭа",
                +	"CONTROLS_REPEAT_HELPURL": "https://ru.wikipedia.org/wiki/Ацикл_(апрограммаркра)",
                +	"CONTROLS_REPEAT_TITLE": "инагӡалатәуп %1 - нтә",
                +	"CONTROLS_REPEAT_INPUT_DO": "инагӡатәуп",
                +	"CONTROLS_REPEAT_TOOLTIP": "Инанагӡоит акомандақәа кырынтә",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "инагӡалатәуп акәзар",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "инагӡалатәуп акәымзар",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Аҭагылазаашьа иашанаҵ, инанагӡалоит акомандақәа.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Аҭагылазаашьа мцнаҵы, инанагӡалоит акомандақәа.",
                +	"CONTROLS_FOR_TITLE": "ацикл %1 ала %2 инаркны %3 рҟынӡа ашьаҿа %4",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ацикл иҭыҵтәуп",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ииастәуп ацикл анаҩстәи ашьаҿахьы",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Иааннакылоит абри ацикл.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Агәҽанҵара:Ари аблок ахархәара амоуп ацикл аҩныҵҟа мацара.",
                +	"CONTROLS_IF_TOOLTIP_1": "Аҭагылазаашьа иашазар, инанагӡоит акомандақәа.",
                +	"CONTROLS_IF_TOOLTIP_2": "Аҭагылазаашьа иашазар, инанагӡоит актәи аблок акомандақәа. Акәымзар инанагӡоит аҩбатәи аблок акомандақәа.",
                +	"CONTROLS_IF_MSG_IF": "акәзар",
                +	"CONTROLS_IF_MSG_ELSEIF": "акәымзар",
                +	"CONTROLS_IF_MSG_ELSE": "акәымзар",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Иацнаҵоит аҭагыазаашьа аблок \"акәзар\" ахь",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Аҟәыхра",
                +	"IOS_ERROR": "Агха",
                +	"IOS_PROCEDURES_INPUTS": "Аҭаларҭа",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Аоператорқәа азин рыҭара",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Иацҵатәуп аҽеиҭак",
                +	"IOS_VARIABLES_ADD_BUTTON": "Иацҵатәуп",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Ахьӡ аҧсахра",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Ианыхтәуп",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Аҽеиҭак ахьӡ",
                +	"LOGIC_COMPARE_HELPURL": "https://ru.wikipedia.org/wiki/Аиҟарамра",
                +	"LOGIC_OPERATION_OR": "ма",
                +	"LOGIC_NEGATE_TITLE": "%1 акәӡам",
                +	"LOGIC_BOOLEAN_TRUE": "аиаша",
                +	"LOGIC_BOOLEAN_FALSE": "амц",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Иҳанаҭоит аҵакы аиаша ма амц",
                +	"LOGIC_NULL": "акагьы",
                +	"LOGIC_NULL_TOOLTIP": "Иҳанаҭоит акагьы",
                +	"LOGIC_TERNARY_IF_TRUE": "аиаша акәзар",
                +	"LOGIC_TERNARY_IF_FALSE": "амц акәзар",
                +	"MATH_NUMBER_HELPURL": "https://ru.wikipedia.org/wiki/Ахыҧхьаӡара",
                +	"MATH_NUMBER_TOOLTIP": "Ахыҧхьаӡара.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ru.wikipedia.org/wiki/Арифметика",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Иҳанаҭоит ҩ-хыҧхьаӡарак реицҵалыҵ.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Иҳанаҭоит ҩ-хыҧхьаӡарак реигырхалыҵ.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Иҳанаҭоит ҩ-хыҧхьаӡарак рышьҭыхлыҵ.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Иҳанаҭоит ҩ-хыҧхьаӡарак ршалыҵ.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "амодуль",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Иҳанаҭоит ахыҧхьаӡара амодуль.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Иҳанаҭоит иаҿагыло ахыҧхьаӡара.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Иҳанаҭоит ахыҧхьаӡара иҧсабаратәу алагорифм.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Иҳанаҭоит ахыҧхьаӡара ажәабатә логари̓фм",
                +	"MATH_TRIG_HELPURL": "https://ru.wikipedia.org/wiki/Атригонометриатә_функциақәа",
                +	"MATH_TRIG_TOOLTIP_SIN": "Иҳанаҭоит асинус градусла.",
                +	"MATH_TRIG_TOOLTIP_COS": "Иҳанаҭоит акосинус градусла.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Иҳанаҭоит атангенс градусла.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Иҳанаҭоит арксинус градусла.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Иҳанаҭоит арккосинус градусла.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Иҳанаҭоит арктангенс градусла.",
                +	"MATH_CONSTANT_HELPURL": "https://ru.wikipedia.org/wiki/Аматематикатә_константа",
                +	"MATH_CONSTANT_TOOLTIP": "Иҳанаҭооит аконстантақәа руак: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) ма ∞ (аҵыхәаҧҵәарадара).",
                +	"MATH_IS_EVEN": "еиҩшо",
                +	"MATH_IS_ODD": "еиҩымшо",
                +	"MATH_IS_PRIME": "имариоу",
                +	"MATH_IS_WHOLE": "аибга",
                +	"MATH_IS_POSITIVE": "иҵоуроу",
                +	"MATH_IS_NEGATIVE": "иҵоурам",
                +	"MATH_IS_DIVISIBLE_BY": "ишоит ала",
                +	"MATH_CHANGE_TITLE": "иеизырҳатәуп %1 %2 рыла",
                +	"MATH_CHANGE_TOOLTIP": "Иацнаҵоит ахыҧхьаӡара аҽеиҭак'%1' ахь.",
                +	"MATH_ROUND_HELPURL": "https://ru.wikipedia.org/wiki/Ахыркәшара",
                +	"MATH_ROUND_OPERATOR_ROUND": "ихыркәшатәуп",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ихыркәшатәуп еиҳау ахь",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ихыркәшатәуп еиҵоу ахь",
                +	"MATH_ONLIST_OPERATOR_SUM": "ахьӡынҵа аицҵалыҵ",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Иҳанаҭоит ахьӡынҵа иаҵанакуа ахыҧхьаӡарақәа зегьы реицҵалыҵ.",
                +	"MATH_ONLIST_OPERATOR_MIN": "ахьӡынҵа аҟны иреиҵо",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Иҳанаҭоит ахьӡынҵа аҟны иреицо ахыҧхьаӡара.",
                +	"MATH_ONLIST_OPERATOR_MAX": "ахьӡынҵа аҟны иреиҳау",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Иҳанаҭоит ахьӡынҵа аҟны иреиҳау ахыҧхьаӡара.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "ахьӡынҵа арифметикатә бжьара",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Иҳанаҭоит ахьӡынҵа аҟны ахыҧхьаӡарақәа зегьы рарифметикатә бжьара.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "ахьӡынҵа амедиана",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Иҳанаҭоит ахьӡынҵа аҟны ахыҧхьаӡарақәа зегьы рмедиана.",
                +	"MATH_ONLIST_OPERATOR_MODE": "ахьӡынҵа амода",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "ахьӡынҵа иарбанзаалакь аелемент",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Иҳанаҭоит ахьӡынҵа аҟны иарбанзаалакь елементк.",
                +	"MATH_MODULO_HELPURL": "https://ru.wikipedia.org/wiki/Ашара_цәынхала",
                +	"MATH_MODULO_TITLE": "ацәынха %1 : %2",
                +	"MATH_MODULO_TOOLTIP": "Иҳанаҭоит ацәынха ҩ-хыҧхьаӡарак ршараан.",
                +	"MATH_RANDOM_INT_TITLE": "иарбанзаалакь еибгоу ахыҧхьаӡара %1 инаркны %2 нӡа",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "иарбанзаалакь ахыҧхьашара 0 инаркны (иалаҵаны)  1 аҟынӡа",
                +	"TEXT_TEXT_HELPURL": "https://ru.wikipedia.org/wiki/Ацәаҳәатә_хкы",
                +	"TEXT_TEXT_TOOLTIP": "Анбан, ажәа ма ацәаҳәа атеқст аҟны.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "иеиҧшьтәуп",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Иацҵатәуп аелемент атеқст ахь.",
                +	"TEXT_APPEND_TITLE": "%1 ахьы иацҵатәуп атеқст %2",
                +	"TEXT_APPEND_TOOLTIP": "Иацҵатәуп атеқст аҽеиҭак «%1» ахь.",
                +	"TEXT_LENGTH_TITLE": "аура %1",
                +	"TEXT_ISEMPTY_TITLE": "%1 ҭацәуп",
                +	"TEXT_INDEXOF_TITLE": "атеқст %1 %2 %3 аҟны",
                +	"TEXT_CHARAT_TITLE": "атеқст %1 %2 аҟны",
                +	"TEXT_CHARAT_FROM_START": "игатәуп анбан №",
                +	"TEXT_CHARAT_FIRST": "игатәуп актәи анбан",
                +	"TEXT_CHARAT_LAST": "игатәуп аҵыхәтәантәи анбан",
                +	"TEXT_CHARAT_RANDOM": "игатәуп иарбанзаалакь нбанк",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "атеқст аҟны",
                +	"TEXT_PRINT_TITLE": "икьыҧхьтәуп %1",
                +	"LISTS_CREATE_EMPTY_TITLE": "иаҧцатәуп иҭацәу ахьӡынҵа",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "ахьӡынҵа",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Иацнаҵоит аелемент ахьӡынҵахьы",
                +	"LISTS_LENGTH_TITLE": "аура %1",
                +	"LISTS_LENGTH_TOOLTIP": "Иҳанаҭоит ахьӡынҵа аура.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ҭацәуп",
                +	"LISTS_ISEMPTY_TOOLTIP": "Иҳанаҭоит аиаша, ахьӡынҵа ҭацәызар.",
                +	"LISTS_INLIST": "ахьӡынҵа аҟны",
                +	"LISTS_GET_INDEX_GET": "игатәуп",
                +	"LISTS_GET_INDEX_REMOVE": "ианыхтәуп",
                +	"LISTS_GET_INDEX_FROM_END": "№ анҵәамнҭа аҟынтәи",
                +	"LISTS_GET_INDEX_FIRST": "актәи",
                +	"LISTS_GET_INDEX_LAST": "аҵыхәтәантәи",
                +	"LISTS_GET_INDEX_RANDOM": "иарбанзаалакь",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 - актәи аелемент.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 - аҵыхәтәантәи аелемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Иҳанаҭоит ахьӡынҵа актәи аелемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Иҳанаҭоит ахьӡынҵа аҵыхәтәантәи аелемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Иҳанаҭоит ахьӡынҵа иарбанзаалакь елементк.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Ианнахәуеит ахьӡынҵа актәи аелемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Ианнахәуеит ахьӡынҵа аҵыхәтәантәи аелемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Ианнахәуеит ахьӡынҵа иарбанзаалакь елементк.",
                +	"LISTS_SET_INDEX_SET": "иаҭатәуп",
                +	"LISTS_SET_INDEX_INSERT": "ибжьаргылатәуп",
                +	"LISTS_SET_INDEX_INPUT_TO": "=",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "№ ала",
                +	"LISTS_SORT_TITLE": "еилыҧшаатәуп %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Еилыҧшаатәуп ахьӡынҵа акопиа.",
                +	"LISTS_SORT_ORDER_ASCENDING": "еиҵоу-еиҳауала",
                +	"LISTS_SORT_ORDER_DESCENDING": "еиҳау-еиҵоуала",
                +	"LISTS_SORT_TYPE_NUMERIC": "ахыҧхьаӡаратәи",
                +	"LISTS_SORT_TYPE_TEXT": "алфавитла",
                +	"VARIABLES_GET_TOOLTIP": "Иҳанаҭоит аҽеиҭак аҵакы.",
                +	"PROCEDURES_DEFNORETURN_TITLE": "азы",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "иҟаҵатәуп џьара акы",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Абри афункциа ахҳәа азыҟашәҵа...",
                +	"PROCEDURES_DEFRETURN_RETURN": "ирхынҳәтәуп",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Аоператорқәа азин рыҭара",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ru.wikipedia.org/wiki/Ацхыраагӡатә программа",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ru.wikipedia.org/wiki/Ацхыраагӡатә программа",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "апараметрқәа",
                +	"PROCEDURES_MUTATORARG_TITLE": "апараметр ахьӡ:"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ar.json b/blockly/webif/static/blockly/msg/json/ar.json
                new file mode 100644
                index 000000000..8c2a4cf5e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ar.json
                @@ -0,0 +1,343 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Meno25",
                +			"Test Create account",
                +			"아라",
                +			"Diyariq",
                +			"محمد أحمد عبد الفتاح",
                +			"Moud hosny",
                +			"ديفيد",
                +			"Samir",
                +			"Mido"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "البند",
                +	"TODAY": "اليوم",
                +	"DUPLICATE_BLOCK": "مكرر",
                +	"ADD_COMMENT": "أضف تعليقًا",
                +	"REMOVE_COMMENT": "أزل التعليق",
                +	"EXTERNAL_INPUTS": "ادخال خارجي",
                +	"INLINE_INPUTS": "ادخال خطي",
                +	"DELETE_BLOCK": "احذف القطعة",
                +	"DELETE_X_BLOCKS": "احذف %1 قطع",
                +	"DELETE_ALL_BLOCKS": "حذف %1 قطعة؟",
                +	"CLEAN_UP": "ترتيب القطع",
                +	"COLLAPSE_BLOCK": "إخفاء القطعة",
                +	"COLLAPSE_ALL": "إخفاء القطع",
                +	"EXPAND_BLOCK": "وسٌّع القطعة",
                +	"EXPAND_ALL": "وسٌّع القطع",
                +	"DISABLE_BLOCK": "عطّل القطعة",
                +	"ENABLE_BLOCK": "أعد تفعيل القطعة",
                +	"HELP": "مساعدة",
                +	"UNDO": "رجوع",
                +	"REDO": "إعادة",
                +	"CHANGE_VALUE_TITLE": "تغيير قيمة:",
                +	"RENAME_VARIABLE": "إعادة تسمية المتغير...",
                +	"RENAME_VARIABLE_TITLE": "إعادة تسمية كافة المتغيرات '%1' إلى:",
                +	"NEW_VARIABLE": "إنشاء متغير...",
                +	"NEW_VARIABLE_TITLE": "اسم المتغير الجديد:",
                +	"VARIABLE_ALREADY_EXISTS": "المتغير '%1' موجود بالفعل",
                +	"DELETE_VARIABLE_CONFIRMATION": "حذف%1 1 استخدامات المتغير '%2'؟",
                +	"DELETE_VARIABLE": "حذف المتغير %1",
                +	"COLOUR_PICKER_HELPURL": "https://ar.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "اختر لون من اللوحة.",
                +	"COLOUR_RANDOM_TITLE": "لون عشوائي",
                +	"COLOUR_RANDOM_TOOLTIP": "اختر لون بشكل عشوائي.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "لون مع",
                +	"COLOUR_RGB_RED": "أحمر",
                +	"COLOUR_RGB_GREEN": "أخضر",
                +	"COLOUR_RGB_BLUE": "أزرق",
                +	"COLOUR_RGB_TOOLTIP": "إنشئ لون بالكمية المحددة من الأحمر, الأخضر والأزرق. بحيث يجب تكون كافة القيم بين 0 و 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "دمج",
                +	"COLOUR_BLEND_COLOUR1": "اللون 1",
                +	"COLOUR_BLEND_COLOUR2": "اللون 2",
                +	"COLOUR_BLEND_RATIO": "نسبة",
                +	"COLOUR_BLEND_TOOLTIP": "دمج لونين ببعضهما البعض بنسبة (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "كرر  %1 مرات",
                +	"CONTROLS_REPEAT_INPUT_DO": "نفّذ",
                +	"CONTROLS_REPEAT_TOOLTIP": "نفّذ بعض الأوامر عدة مرات.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "اكرّر طالما",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "اكرّر حتى",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "بما ان القيمة صحيحة, نفّذ بعض الأوامر.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "بما ان القيمة خاطئة, نفّذ بعض الأوامر.",
                +	"CONTROLS_FOR_TOOLTIP": "اجعل المتغير  %1 يأخذ القيم من رقم البداية الى رقم النهاية، وقم بالعد داخل المجال المحدد، وطبق أوامر القطع المحددة.",
                +	"CONTROLS_FOR_TITLE": "عد بـ %1 من %2 إلى %3 بمعدل %4",
                +	"CONTROLS_FOREACH_TITLE": "لكل عنصر %1 في قائمة %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "لكل عنصر في قائمة ما، عين المتغير '%1' لهذا الغنصر، ومن ثم نفذ بعض الأوامر.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "اخرج من الحلقة",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "استمر ابتداءا من التكرار التالي من الحلقة",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "اخرج من الحلقة الحالية.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "تخط ما تبقى من هذه الحلقة، واستمر ابتداءا من التكرار التالي.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "تحذير: يمكن استخدام هذه القطعة فقط داخل حلقة.",
                +	"CONTROLS_IF_TOOLTIP_1": "إذا كانت قيمة ما تساوي صحيح, إذن قم بتنفيذ أمر ما.",
                +	"CONTROLS_IF_TOOLTIP_2": "إذا كانت قيمة ما تساوي \"صحيح\"، إذن قم بتنفيذ أول قطعة من الأوامر. والا ،قم بتنفيذ القطعة الثانية من الأوامر.",
                +	"CONTROLS_IF_TOOLTIP_3": "إذا كانت القيمة الأولى تساوي \"صحيح\", إذن قم بتنفيذ القطعة الأولى من الأوامر. والا, إذا كانت القيمة الثانية تساوي \"صحيح\", قم بتنفيذ القطعة الثانية من الأوامر.",
                +	"CONTROLS_IF_TOOLTIP_4": "إذا كانت القيمة الأولى تساوي \"صحيح\", إذن قم بتنفيذ القطعة الأولى من الأوامر. والا , إذا كانت القيمة الثانية تساوي \"صحيح\", قم بتنفيذ القطعة الثانية من الأوامر. إذا لم تكن هناك أي قيمة تساوي صحيح, قم بتنفيذ آخر قطعة من الأوامر.",
                +	"CONTROLS_IF_MSG_IF": "إذا",
                +	"CONTROLS_IF_MSG_ELSEIF": "وإﻻ إذا",
                +	"CONTROLS_IF_MSG_ELSE": "والا",
                +	"CONTROLS_IF_IF_TOOLTIP": "أضف, إزل, أو أعد ترتيب المقاطع لإعادة تكوين القطعة الشرطية \"إذا\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "إضف شرطا إلى القطعة الشرطية \"إذا\".",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "أضف شرط \"نهاية، إجمع\" إلى القطعة الشرطية \"إذا\".",
                +	"IOS_OK": "أوافق",
                +	"IOS_CANCEL": "ألغِ",
                +	"IOS_ERROR": "خطأ",
                +	"IOS_VARIABLES_ADD_BUTTON": "أضف",
                +	"IOS_VARIABLES_RENAME_BUTTON": "أعد التسمية",
                +	"IOS_VARIABLES_DELETE_BUTTON": "احذف",
                +	"IOS_VARIABLES_VARIABLE_NAME": "اسم المتغير",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "لا يمكنك استخدام اسم متغير فارغ.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "يرجع صحيح إذا كان كلا المدخلات مساوية بعضها البعض.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "يرجع صحيح إذا كانت كلا المدخلات غير مساوية لبعضها البعض.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "يرجع صحيح إذا كان الإدخال الأول أصغر من الإدخال الثاني.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "يرجع صحيح إذا كان الإدخال الأول أصغر من أو يساوي الإدخال الثاني.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "يرجع صحيح إذا كان الإدخال الأول أكبر من الإدخال الثاني.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "يرجع صحيح إذا كان الإدخال الأول أكبر من أو يساوي الإدخال الثاني.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "ترجع صحيح إذا كان كلا المٌدخلات صحيح.",
                +	"LOGIC_OPERATION_AND": "و",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "ترجع صحيح إذا كان واحد على الأقل من المدخلات صحيح.",
                +	"LOGIC_OPERATION_OR": "أو",
                +	"LOGIC_NEGATE_TITLE": "ليس %1",
                +	"LOGIC_NEGATE_TOOLTIP": "يرجع صحيح إذا كان الإدخال خاطئ .  يرجع خاطئ إذا كان الإدخال صحيح.",
                +	"LOGIC_BOOLEAN_TRUE": "صحيح",
                +	"LOGIC_BOOLEAN_FALSE": "خاطئ",
                +	"LOGIC_BOOLEAN_TOOLTIP": "يرجع صحيح أو خاطئ.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "فارغ",
                +	"LOGIC_NULL_TOOLTIP": "ترجع ملغى.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "اختبار",
                +	"LOGIC_TERNARY_IF_TRUE": "إذا كانت العبارة صحيحة",
                +	"LOGIC_TERNARY_IF_FALSE": "إذا كانت العبارة خاطئة",
                +	"LOGIC_TERNARY_TOOLTIP": "تحقق الشرط في 'الاختبار'. إذا كان الشرط صحيح، يقوم بإرجاع قيمة 'اذا كانت العبارة صحيحة'؛ خلاف ذلك يرجع قيمة 'اذا كانت العبارة خاطئة'.",
                +	"MATH_NUMBER_HELPURL": "https://ar.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF",
                +	"MATH_NUMBER_TOOLTIP": "عدد ما.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "جيب",
                +	"MATH_TRIG_COS": "جيب تمام",
                +	"MATH_TRIG_TAN": "ظل",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://ar.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8%D9%8A%D8%A7%D8%AA",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "يرجع مجموع الرقمين.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "يرجع الفرق بين الرقمين.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "يرجع حاصل ضرب الرقمين.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "يرجع حاصل قسمة الرقمين.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "يرجع الرقم الأول مرفوع إلى تربيع الرقم الثاني.",
                +	"MATH_SINGLE_HELPURL": "https://ar.wikipedia.org/wiki/%D8%AC%D8%B0%D8%B1_%D8%AA%D8%B1%D8%A8%D9%8A%D8%B9%D9%8A",
                +	"MATH_SINGLE_OP_ROOT": "الجذر التربيعي",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "يرجع الجذر التربيعي للرقم.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "مطلق",
                +	"MATH_SINGLE_TOOLTIP_ABS": "يرجع القيمة المطلقة لرقم.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "يرجع عدد سالب.",
                +	"MATH_SINGLE_TOOLTIP_LN": "يرجع اللوغاريتم الطبيعي لرقم.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "يرجع لوغاريتم عدد معين للاساس 10.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "يرجع ه‍ (e) مرفوعا لأس بقيمة الرقم المدخل.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "يرجع مضروب الرقم 10 في نفسه .",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "يرجع جيب التمام لدرجة (لا زواية نصف قطرية).",
                +	"MATH_TRIG_TOOLTIP_COS": "يرجع جيب التمام لدرجة (لا زواية نصف قطرية).",
                +	"MATH_TRIG_TOOLTIP_TAN": "يرجع الظل لدرجة (لا دائرة نصف قطرية).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "يرجع قوس الجيب للرقم.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "يرجع قوس جيب التمام لرقم.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "يرجع قوس الظل للرقم.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "ير جع واحد من الثوابت الشائعة : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "هو زوجي",
                +	"MATH_IS_ODD": "هو فرذي",
                +	"MATH_IS_PRIME": "هو أولي",
                +	"MATH_IS_WHOLE": "هو صحيح",
                +	"MATH_IS_POSITIVE": "هو موجب",
                +	"MATH_IS_NEGATIVE": "هو سالب",
                +	"MATH_IS_DIVISIBLE_BY": "قابل للقسمة",
                +	"MATH_IS_TOOLTIP": "تحقق إذا كان عدد ما زوجيا، فرذيا, أوليا، صحيحا،موجبا أو سالبا، أو إذا كان قابلا للقسمة على عدد معين.  يرجع صحيح أو خاطئ.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "غير %1 بـ %2",
                +	"MATH_CHANGE_TOOLTIP": "إضف رقم إلى متغير '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "تقريب الى اكبر عدد صحيح أو الى اصغر عدد صحيح.",
                +	"MATH_ROUND_OPERATOR_ROUND": "تقريب",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "تقريب الى اكبر عدد صحيح",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "تقريب إلى اصغر عدد صحيح",
                +	"MATH_ONLIST_OPERATOR_SUM": "مجموع القائمة",
                +	"MATH_ONLIST_TOOLTIP_SUM": "يرجع مجموع كافة الأرقام الموجودة في القائمة.",
                +	"MATH_ONLIST_OPERATOR_MIN": "الحد الأدنى من قائمة",
                +	"MATH_ONLIST_TOOLTIP_MIN": "يرجع أصغر رقم في القائمة.",
                +	"MATH_ONLIST_OPERATOR_MAX": "الحد الأقصى لقائمة",
                +	"MATH_ONLIST_TOOLTIP_MAX": "يرجع أكبر عدد في القائمة.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "متوسط القائمة",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "يرجع المعدل (الوسط الحسابي) للقيم الرقمية في القائمة.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "متوسط القائمة",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "يرجع وسيط العدد في القائمة.",
                +	"MATH_ONLIST_OPERATOR_MODE": "منوال القائمة",
                +	"MATH_ONLIST_TOOLTIP_MODE": "يرجع قائمة من العنصر أو العناصر الأكثر شيوعاً في القائمة.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "الانحراف المعياري للقائمة",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "يرجع الانحراف المعياري للقائمة.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "عنصر عشوائي من القائمة",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "يرجع عنصر عشوائي من القائمة.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "باقي %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "يرجع الباقي من قسمة الرقمين.",
                +	"MATH_CONSTRAIN_TITLE": "تقيد %1 منخفض %2 مرتفع %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "تقييد العددليكون بين الحدود المحددة (ضمناً).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": " عدد صحيح عشوائي من %1 إلى %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "يرجع عدد صحيح عشوائي بين حدين محددين, ضمنيا.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "كسر عشوائي",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "يرجع جزء عشوائي بين 0.0 (ضمنياً) و 1.0 (خارجيا).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "حرف أو كلمة أو سطر من النص.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "انشئ نص مع",
                +	"TEXT_JOIN_TOOLTIP": "أنشئ جزء من النص بالصاق أي عدد من العناصر ببعضها البعض.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "الانضمام إلى",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "أضف, إحذف, أو أعد ترتيب المقاطع لإعادة تكوين النص من القطع التالية.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "إضف عنصر إلى النص.",
                +	"TEXT_APPEND_TOOLTIP": "إلصق جزءا من النص إلى متغير '%1'.",
                +	"TEXT_LENGTH_TITLE": "طول %1",
                +	"TEXT_LENGTH_TOOLTIP": "تقوم بإرجاع عدد الاحرف (بما في ذلك الفراغات) في النص المقدم.",
                +	"TEXT_ISEMPTY_TITLE": "%1 فارغ",
                +	"TEXT_ISEMPTY_TOOLTIP": "يرجع \"صحيح\" إذا كان النص المقدم فارغ.",
                +	"TEXT_INDEXOF_TOOLTIP": "تقوم بإرجاع مؤشر التواجد الأول/الأخير للنص الأول في النص الثاني.  تقوم بإرجاع %1 إذا لم يتم العثور على النص.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "ابحث عن التواجد الأول للنص",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "ابحث عن التواجد الأخير للنص",
                +	"TEXT_CHARAT_FROM_START": "الحصول على الحرف #",
                +	"TEXT_CHARAT_FROM_END": "الحصول على الحرف # من نهاية",
                +	"TEXT_CHARAT_FIRST": "احصل على الحرف الأول",
                +	"TEXT_CHARAT_LAST": "احصل على آخر حرف",
                +	"TEXT_CHARAT_RANDOM": "الحصول على حرف عشوائي",
                +	"TEXT_CHARAT_TOOLTIP": "يرجع حرف ما في الموضع المحدد.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "يرجع جزء معين من النص.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "في النص",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "الحصول على سلسلة حروف فرعية من الحرف #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "الحصول على سلسلة حروف فرعية من الحرف # من نهاية",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "الحصول على سلسلة فرعية من الحرف الأول",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "إلى حرف #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "إلى حرف # من نهاية",
                +	"TEXT_GET_SUBSTRING_END_LAST": "إلى آخر حرف",
                +	"TEXT_CHANGECASE_TOOLTIP": "يرجع نسخة من النص في حالة مختلفة.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "الى حروف كبيرة",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "الى حروف صغيرة",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "الى حروف العنوان",
                +	"TEXT_TRIM_TOOLTIP": "يرجع نسخة من النص مع حذف من أحد أو كلا الفراغات من أطرافه.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "إزالة الفراغات من كلا الجانبين",
                +	"TEXT_TRIM_OPERATOR_LEFT": "إزالة الفراغات من الجانب الأيسر من",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "إزالة الفراغات من الجانب الأيمن من",
                +	"TEXT_PRINT_TITLE": "اطبع %1",
                +	"TEXT_PRINT_TOOLTIP": "اطبع النص المحدد أو العدد أو قيمة أخرى.",
                +	"TEXT_PROMPT_TYPE_TEXT": "انتظر ادخال المستخدم لنص ما مع اظهار رسالة",
                +	"TEXT_PROMPT_TYPE_NUMBER": "انتظر ادخال المستخدم لرقم ما مع اظهار رسالة",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "انتظر ادخال المستخذم لرقم ما.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "انتظر ادخال المستخدم لنص ما.",
                +	"TEXT_REVERSE_TOOLTIP": "يعكس ترتيب حروف النص",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "إنشئ قائمة فارغة",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "تقوم بإرجاع قائمة، طولها 0, لا تحتوي على أية سجلات البيانات",
                +	"LISTS_CREATE_WITH_TOOLTIP": "أنشيء قائمة من أي عدد من العناصر.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "أتشئ قائمة مع",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "قائمة",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "أضف, إزل, أو أعد ترتيب المقاطع لإعادة تكوين القطعة قائمة القطع التالية.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "أضف عنصرا إلى القائمة.",
                +	"LISTS_REPEAT_TOOLTIP": "انشئ قائمة تتألف من القيمة المعطاة متكررة لعدد محدد من المرات.",
                +	"LISTS_REPEAT_TITLE": "إنشئ قائمة مع العنصر  %1 %2 مرات",
                +	"LISTS_LENGTH_TITLE": "الطول من %1",
                +	"LISTS_LENGTH_TOOLTIP": "تقوم بإرجاع طول قائمة.",
                +	"LISTS_ISEMPTY_TITLE": "%1 فارغ",
                +	"LISTS_ISEMPTY_TOOLTIP": "يرجع \"صحيح\" إذا كانت القائمة فارغة.",
                +	"LISTS_INLIST": "في قائمة",
                +	"LISTS_INDEX_OF_FIRST": "ابحث على على التواجد الأول للعنصر",
                +	"LISTS_INDEX_OF_LAST": "ابحث على التواجد الأخير للعنصر",
                +	"LISTS_INDEX_OF_TOOLTIP": "تقوم بإرجاع مؤشر التواجد  الأول/الأخير في القائمة.  تقوم بإرجاع %1 إذا لم يتم العثور على النص.",
                +	"LISTS_GET_INDEX_GET": "احصل على",
                +	"LISTS_GET_INDEX_GET_REMOVE": "احصل على و ازل",
                +	"LISTS_GET_INDEX_REMOVE": "ازل",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# من نهاية",
                +	"LISTS_GET_INDEX_FIRST": "أول",
                +	"LISTS_GET_INDEX_LAST": "أخير",
                +	"LISTS_GET_INDEX_RANDOM": "عشوائي",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 هو العنصر الأول.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 هو العنصر الأخير.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "يقوم بإرجاع العنصر في الموضع المحدد في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "يرجع العنصر الأول في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "يرجع العنصر الأخير في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "يرجع عنصرا عشوائيا في قائمة.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "يزيل ويقوم بإرجاع العنصر في الموضع المحدد في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "يزيل ويرجع العنصر الأول في قائمة.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "يزيل ويرجع العنصر الأخير في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "يزيل و يرجع عنصرا عشوائيا في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "يزيل العنصر الموجود في الموضع المحدد في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "يزيل العنصر الأول في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "يزيل العنصر الأخير في قائمة ما.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "يزيل عنصرا عشوائيا في قائمة ما.",
                +	"LISTS_SET_INDEX_SET": "تعيين",
                +	"LISTS_SET_INDEX_INSERT": "أدخل في",
                +	"LISTS_SET_INDEX_INPUT_TO": "مثل",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "يحدد العنصر في الموضع المحدد في قائمة ما.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "يحدد العنصر الأول في قائمة.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "يحدد العنصر الأخير في قائمة.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "يحدد عنصرا عشوائيا في قائمة.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "يقوم بإدخال العنصر في الموضع المحدد في قائمة ما.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "يقوم بإدراج هذا العنصر في بداية قائمة.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "ألصق هذا العنصر بنهاية قائمة.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "ادخل العنصر عشوائياً في القائمة.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "احصل على قائمة فرعية من #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "احصل  على قائمة فرعية من # من نهاية",
                +	"LISTS_GET_SUBLIST_START_FIRST": "احصل على قائمة فرعية من الأول",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "إلى #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "إلى # من نهاية",
                +	"LISTS_GET_SUBLIST_END_LAST": "إلى الأخير",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "يقوم بإنشاء نسخة من الجزء المحدد من قائمة ما.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "رتب %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "فرز نسخة من القائمة.",
                +	"LISTS_SORT_ORDER_ASCENDING": "تصاعديا",
                +	"LISTS_SORT_ORDER_DESCENDING": "تنازليا",
                +	"LISTS_SORT_TYPE_NUMERIC": "رقمي",
                +	"LISTS_SORT_TYPE_TEXT": "أبجديًا",
                +	"LISTS_SORT_TYPE_IGNORECASE": "أبجديا، وتجاهل الحالة",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "إعداد قائمة من النصوص",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "إعداد نص من القائمة",
                +	"LISTS_SPLIT_WITH_DELIMITER": "مع محدد",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "تقسيم النص إلى قائمة من النصوص، وكسر في كل محدد",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "ضم قائمة النصوص في نص واحد، مفصولة بواسطة محدد.",
                +	"VARIABLES_GET_TOOLTIP": "يرجع قيمة هذا المتغير.",
                +	"VARIABLES_GET_CREATE_SET": "انشئ 'التعيين %1'",
                +	"VARIABLES_SET": "تعيين %1 إلى %2",
                +	"VARIABLES_SET_TOOLTIP": "تعيين هذا المتغير لتكون مساوية للقيمة المدخلة.",
                +	"VARIABLES_SET_CREATE_GET": "انشئ 'احصل على %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "إلى",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "القيام بشيء ما",
                +	"PROCEDURES_BEFORE_PARAMS": "مع:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "مع:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "انشئ دالة بدون مخرجات .",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "صف هذه الوظيفة...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "يرجع",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "انشئ دالة مع المخرجات.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "اسمح بالبيانات",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "تحذير: هذه الدالة تحتوي على معلمات مكررة.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "تشغيل الدالة المعرفة من قبل المستخدم '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "تشغيل الدالة المعرفة من قبل المستخدم %1 واستخدام  مخرجاتها.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "المدخلات",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "إضافة أو إزالة أو إعادة ترتيب المدخلات لهذه المهمة.",
                +	"PROCEDURES_MUTATORARG_TITLE": "اسم الإدخال:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "أضف مدخلا إلى الوظيفة.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "تسليط الضوء على تعريف الدالة",
                +	"PROCEDURES_CREATE_DO": "إنشئ '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "إذا كانت القيمة صحيحة ، اذان قم بارجاع القيمة الثانية.",
                +	"PROCEDURES_IFRETURN_WARNING": "تحذير:هذه القطعة تستخدم فقط داخل تعريف دالة."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/az.json b/blockly/webif/static/blockly/msg/json/az.json
                new file mode 100644
                index 000000000..a6499719a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/az.json
                @@ -0,0 +1,292 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Cekli829",
                +			"AZISS"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Bugün",
                +	"DUPLICATE_BLOCK": "Dublikat",
                +	"ADD_COMMENT": "Şərh əlavə et",
                +	"REMOVE_COMMENT": "Şərhi sil",
                +	"EXTERNAL_INPUTS": "Xarici girişlər",
                +	"INLINE_INPUTS": "Sətiriçi girişlər",
                +	"DELETE_BLOCK": "Bloku sil",
                +	"DELETE_X_BLOCKS": "%1 bloku sil",
                +	"DELETE_ALL_BLOCKS": "Bütün %1 blok silinsin?",
                +	"CLEAN_UP": "Blokları təmizlə",
                +	"COLLAPSE_BLOCK": "Bloku yığ",
                +	"COLLAPSE_ALL": "Blokları yığ",
                +	"EXPAND_BLOCK": "Bloku aç",
                +	"EXPAND_ALL": "Blokları aç",
                +	"DISABLE_BLOCK": "Bloku söndür",
                +	"ENABLE_BLOCK": "Bloku aktivləşdir",
                +	"HELP": "Kömək",
                +	"CHANGE_VALUE_TITLE": "Qiyməti dəyiş:",
                +	"RENAME_VARIABLE": "Dəyişənin adını dəyiş...",
                +	"RENAME_VARIABLE_TITLE": "Bütün '%1' dəyişənlərinin adını buna dəyiş:",
                +	"NEW_VARIABLE": "Yeni dəyişən...",
                +	"NEW_VARIABLE_TITLE": "Yeni dəyişənin adı:",
                +	"COLOUR_PICKER_HELPURL": "https://az.wikipedia.org/wiki/Rəng",
                +	"COLOUR_PICKER_TOOLTIP": "Palitradan bir rəng seçin.",
                +	"COLOUR_RANDOM_TITLE": "təsadüfi rəng",
                +	"COLOUR_RANDOM_TOOLTIP": "Təsadüfi bir rəng seçin.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "rənglə",
                +	"COLOUR_RGB_RED": "qırmızı",
                +	"COLOUR_RGB_GREEN": "yaşıl",
                +	"COLOUR_RGB_BLUE": "mavi",
                +	"COLOUR_RGB_TOOLTIP": "Qırmızı, yaşıl və mavinin göstərilən miqdarı ilə bir rəng düzəlt. Bütün qiymətlər 0 ilə 100 arasında olmalıdır.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "qarışdır",
                +	"COLOUR_BLEND_COLOUR1": "rəng 1",
                +	"COLOUR_BLEND_COLOUR2": "rəng 2",
                +	"COLOUR_BLEND_RATIO": "nisbət",
                +	"COLOUR_BLEND_TOOLTIP": "İki rəngi verilmiş nisbətdə (0,0 - 1,0) qarışdırır.",
                +	"CONTROLS_REPEAT_HELPURL": "https://az.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "%1 dəfə təkrar et",
                +	"CONTROLS_REPEAT_INPUT_DO": "icra et",
                +	"CONTROLS_REPEAT_TOOLTIP": "Bəzi əmrləri bir neçə dəfə yerinə yetir.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "təkrar et, hələ ki",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "təkrar et, ta ki",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Hələ ki, qiymət \"doğru\"dur, bəzi əmrləri yerinə yetir.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Hələ ki, qiymət \"yalan\"dır, bəzi əmrləri yerinə yetir.",
                +	"CONTROLS_FOR_TOOLTIP": "\"%1\" dəyişəni başlanğıc ədəddən son ədədə qədər göstərilən aralıqla qiymətlər aldıqca göstərilən blokları yerinə yetir.",
                +	"CONTROLS_FOR_TITLE": "say: %1 %2 ilə başlayıb, %3 qiymətinə kimi %4 qədər dəyiş",
                +	"CONTROLS_FOREACH_TITLE": "hər element üçün %1 siyahıda %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Siyahıdakı hər element üçün \"%1\" dəyişənini elementə mənimsət və bundan sonra bəzi əmrləri yerinə yetir.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "dövrdən çıx",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "dövrün növbəti addımından davam et",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Cari dövrdən çıx.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Bu dövrün qalanını ötür və növbəti addımla davam et.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Xəbərdarlıq: Bu blok ancaq dövr daxilində istifadə oluna bilər.",
                +	"CONTROLS_IF_TOOLTIP_1": "Əgər qiymət doğrudursa, onda bəzi əmrləri yerinə yetir.",
                +	"CONTROLS_IF_TOOLTIP_2": "Əgər qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda isə ikinci əmrlər blokunu yerinə yetir.",
                +	"CONTROLS_IF_TOOLTIP_3": "Əgər birinci qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda əgər ikinci qiymət doğrudursa, onda ikinci əmrlər blokunu yerinə yetir.",
                +	"CONTROLS_IF_TOOLTIP_4": "Əgər birinci qiymət doğrudursa, onda birinci əmrlər blokunu yerinə yetir. Əks halda əgər ikinci qiymət doğrudursa, onda ikinci əmrlər blokunu yerinə yetir. Əgər qiymətlərdən heç biri doğru deyilsə, onda axırıncı əmrlər blokunu yerinə yetir.",
                +	"CONTROLS_IF_MSG_IF": "əgər",
                +	"CONTROLS_IF_MSG_ELSEIF": "əks halda əgər",
                +	"CONTROLS_IF_MSG_ELSE": "əks halda",
                +	"CONTROLS_IF_IF_TOOLTIP": "Bu \"əgər\" blokunu dəyişdirmək üçün bölümlərin yenisini əlavə et, sil və ya yerini dəyiş.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "\"Əgər\" blokuna bir şərt əlavə et.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "\"Əgər\" blokuna qalan bütün halları əhatə edəb son bir şərt əlavə et.",
                +	"LOGIC_COMPARE_HELPURL": "https://az.wikipedia.org/wiki/bərabərsizlik_(riyazi)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Girişlər bir birinə bərabərdirsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Girişlər bərabər deyillərsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Birinci giriş ikincidən kiçikdirsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Birinci giriş ikincidən kiçik və ya bərarbərdirsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Birinci giriş ikincidən böyükdürsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Birinci giriş ikincidən böyük və ya bərarbərdirsə \"doğru\" cavabını qaytarır.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Hər iki giriş \"doğru\"-dursa \"doğru\" cavabını qaytarır.",
                +	"LOGIC_OPERATION_AND": "və",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Girişlərdən heç olmasa biri \"doğru\"-dursa \"doğru\" cavabını qaytarır.",
                +	"LOGIC_OPERATION_OR": "və ya",
                +	"LOGIC_NEGATE_TITLE": "%1 deyil",
                +	"LOGIC_NEGATE_TOOLTIP": "Giriş \"yalan\"-dursa \"doğru\" cavabını qaytarır. Giriş \"doğru\"-dursa \"səhf\" cavabını qaytarır.",
                +	"LOGIC_BOOLEAN_TRUE": "doğru",
                +	"LOGIC_BOOLEAN_FALSE": "səhf",
                +	"LOGIC_BOOLEAN_TOOLTIP": "\"doğru\" və ya \"səhf\" cavanını qaytarır.",
                +	"LOGIC_NULL": "boş",
                +	"LOGIC_NULL_TOOLTIP": "Boş cavab qaytarır.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "əgər doğrudursa",
                +	"LOGIC_TERNARY_IF_FALSE": "əgər səhfdirsə",
                +	"LOGIC_TERNARY_TOOLTIP": "'Yoxla' əmrindəki şərtə nəzər yetirin. Əgər şərt \"doğru\"-dursa \"əgər doğru\", əks halda isə \"əgər yalan\" cavabını qaytarır.",
                +	"MATH_NUMBER_HELPURL": "https://az.wikipedia.org/wiki/Ədəd",
                +	"MATH_NUMBER_TOOLTIP": "Ədəd.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tg",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "arccos",
                +	"MATH_TRIG_ATAN": "arctan",
                +	"MATH_ARITHMETIC_HELPURL": "https://az.wikipedia.org/wiki/Hesab",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "İki ədədin cəmini qaytarır.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "İki ədədin fərqini qaytarır.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "İki ədədin hasilini verir.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "İki ədədin nisbətini qaytarır.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Birinci ədədin ikinci ədəd dərəcəsindən qüvvətini qaytarır.",
                +	"MATH_SINGLE_HELPURL": "https://az.wikipedia.org/wiki/Kvadrat_kökləri",
                +	"MATH_SINGLE_OP_ROOT": "kvadrat kök",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Ədədin kvadrat kökünü qaytarır.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "modul",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Ədədin modulunu qaytarır.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Ədədin əksini qaytarır.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Ədədin natural loqarifmini tapır.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Ədədin 10-cu dərəcədən loqarifmini tapır.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "e sabitinin verilmiş ədədə qüvvətini qaytarır.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "10-un verilmiş ədədə qüvvətini qaytarır.",
                +	"MATH_TRIG_HELPURL": "https://az.wikipedia.org/wiki/Triqonometrik_funksiyalar",
                +	"MATH_TRIG_TOOLTIP_SIN": "Dərəcənin sinusunu qaytar (radianın yox).",
                +	"MATH_TRIG_TOOLTIP_COS": "Dərəcənin kosinusunu qaytarır (radianın yox).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Dərəcənin tangensini qaytar (radianın yox).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Ədədin arcsinusunu qaytarır.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Ədədin arccosinusunu qaytarır.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Ədədin arctanqensini qaytarır.",
                +	"MATH_CONSTANT_HELPURL": "https://az.wikipedia.org/wiki/Riyazi_sabitlər",
                +	"MATH_CONSTANT_TOOLTIP": "Ümumi sabitlərdən birini qaytarır π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), və ya ∞ (sonsuzluq).",
                +	"MATH_IS_EVEN": "cütdür",
                +	"MATH_IS_ODD": "təkdir",
                +	"MATH_IS_PRIME": "sadədir",
                +	"MATH_IS_WHOLE": "tamdır",
                +	"MATH_IS_POSITIVE": "müsətdir",
                +	"MATH_IS_NEGATIVE": "mənfidir",
                +	"MATH_IS_DIVISIBLE_BY": "bölünür",
                +	"MATH_IS_TOOLTIP": "Bir ədədin cüt, tək, sadə, tam, müsbət, mənfi olmasını və ya müəyyən bir ədədə bölünməsini yoxlayır. \"Doğru\" və ya \"yalan\" qiymətini qaytarır.",
                +	"MATH_CHANGE_TITLE": "dəyiş: %1 buna: %2",
                +	"MATH_CHANGE_TOOLTIP": "'%1' dəyişəninin üzərinə bir ədəd artır.",
                +	"MATH_ROUND_TOOLTIP": "Ədədi aşağı və ya yuxari yuvarlaqşdır.",
                +	"MATH_ROUND_OPERATOR_ROUND": "yuvarlaqlaşdır",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "yuxarı yuvarlaqlaşdır",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "aşağı yuvarlaqlaşdır",
                +	"MATH_ONLIST_OPERATOR_SUM": "Siyahının cəmi",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Siyahıdakı bütün ədədlərin cəmini qaytarır.",
                +	"MATH_ONLIST_OPERATOR_MIN": "siyahının minimumu",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Siyahıdaki ən kiçik ədədi qaytarır.",
                +	"MATH_ONLIST_OPERATOR_MAX": "siyahının maksimumu",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Siyahıdaki ən böyük elementi qaytarır.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "siyahının ədədi ortası",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Siyahıdaki ədədlərin ədədi ortasını qaytarır.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "siyahının medianı",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Siyahının median elementini qaytarır.",
                +	"MATH_ONLIST_OPERATOR_MODE": "Siyahı modları( Ən çox rastlaşılan elementləri)",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Siyahıdaki ən çox rastlanan element(lər)dən ibarət siyahı qaytarır.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "Siyahının standart deviasiyası",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Siyahının standart deviasiyasını qaytarır.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "siyahıdan təsadüfi seçilmiş bir element",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Siyahıdan təsadüfi bir element qaytarır.",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 bölməsinin qalığı",
                +	"MATH_MODULO_TOOLTIP": "İki ədədin nisbətindən alınan qalığı qaytarır.",
                +	"MATH_CONSTRAIN_TITLE": "%1 üçün ən aşağı %2, ən yuxarı %3 olmağı tələb et",
                +	"MATH_CONSTRAIN_TOOLTIP": "Bir ədədin verilmiş iki ədəd arasında olmasını tələb edir (sərhədlər də daxil olmaqla).",
                +	"MATH_RANDOM_INT_TITLE": "%1 ilə %2 arasından təsadüfi tam ədəd",
                +	"MATH_RANDOM_INT_TOOLTIP": "Verilmiş iki ədəd arasından (ədədrlər də daxil olmaqla) təsadüfi bir tam ədəd qaytarır.",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "təsadüfi kəsr",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0 (daxil olmaqla) və 1.0 (daxil olmamaqla) ədədlərinin arasından təsadüfi bir kəsr ədəd qaytarır.",
                +	"TEXT_TEXT_TOOLTIP": "Mətndəki hərf, söz və ya sətir.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "Verilmişlərlə mətn yarat",
                +	"TEXT_JOIN_TOOLTIP": "İxtiyari sayda elementlərinin birləşməsi ilə mətn parçası yarat.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "birləşdir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Bu mətn blokunu yenidən konfigurasiya etmək üçün bölmələri əlavə edin, silin və ya yerlərini dəyişin.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Mətnə bir element əlavə et.",
                +	"TEXT_APPEND_TOOLTIP": "'%1' dəyişəninin sonuna nəsə əlavə et.",
                +	"TEXT_LENGTH_TITLE": "%1 - ın uzunluğu",
                +	"TEXT_LENGTH_TOOLTIP": "Verilmiş mətndəki hərflərin(sözlər arası boşluqlar sayılmaqla) sayını qaytarır.",
                +	"TEXT_ISEMPTY_TITLE": "%1 boşdur",
                +	"TEXT_ISEMPTY_TOOLTIP": "Verilmiş mətn boşdursa, doğru qiymətini qaytarır.",
                +	"TEXT_INDEXOF_TOOLTIP": "Birinci mətnin ikinci mətndə ilk/son rastlaşma indeksini qaytarır. Əgər rastlaşma baş verməzsə, %1 qaytarır.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "Bu mətn ilə ilk rastlaşmanı tap:",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "Bu mətn ilə son rastlaşmanı tap:",
                +	"TEXT_CHARAT_FROM_START": "bu nömrəli hərfi götür",
                +	"TEXT_CHARAT_FROM_END": "axırdan bu nömrəli hərfi götür",
                +	"TEXT_CHARAT_FIRST": "birinci hərfi götür",
                +	"TEXT_CHARAT_LAST": "axırıncı hərfi götür",
                +	"TEXT_CHARAT_RANDOM": "təsadüfi hərf götür",
                +	"TEXT_CHARAT_TOOLTIP": "Göstərilən mövqedəki hərfi qaytarır.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Mətnin təyin olunmuş hissəsini qaytarır.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "mətndə",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "Mətnin surətini bu nömrəli hərfdən",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "Mətnin surətini sondan bu nömrəli # hərfdən",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "Mətnin surətini ilk hərfdən",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "bu nömrəli hərfə qədər",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "axırdan bu nömrəli hərfə qədər",
                +	"TEXT_GET_SUBSTRING_END_LAST": "son hərfə qədər",
                +	"TEXT_CHANGECASE_TOOLTIP": "Mətndə hərflərin böyük-kiçikliyini dəyiş.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "BÖYÜK HƏRFLƏRLƏ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "kiçik hərflərlə",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Baş Hərflərlə",
                +	"TEXT_TRIM_TOOLTIP": "Mətnin hər iki və ya yalnız bir tərəfdən olan boşluqları pozulmuş surətini qaytarın.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "Boşluqları hər iki tərəfdən pozun",
                +	"TEXT_TRIM_OPERATOR_LEFT": "Boşluqlari yalnız sol tərəfdən pozun",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "Boşluqları yalnız sağ tərəfdən pozun",
                +	"TEXT_PRINT_TITLE": "%1 - i çap elə",
                +	"TEXT_PRINT_TOOLTIP": "Təyin olunmuş mətn, ədəd və ya hər hansı bir başqa elementi çap elə.",
                +	"TEXT_PROMPT_TYPE_TEXT": "İstifadəçiyə mətn daxil etməsi üçün sorğunu/tələbi ismarıc ilə göndərin",
                +	"TEXT_PROMPT_TYPE_NUMBER": "İstifadəçiyə ədəd daxil etməsi üçün sorğunu/tələbi ismarıc kimi göndərin",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "İstifadəçiyə ədəd daxil etməsi üçün sorğu/tələb göndərin.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "İstifadəçiyə mətn daxil etməsi üçün sorğu/tələb göndərin.",
                +	"LISTS_CREATE_EMPTY_TITLE": "boş siyahı düzəlt",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Heç bir verilən qeyd olunmamış, uzunluğu 0 olan bir siyahı verir",
                +	"LISTS_CREATE_WITH_TOOLTIP": "İstənilən ölçülü siyahı yaradın.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "bunlardan siyahı düzəlt",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "siyahı",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Bu siyahı blokunu yenidən konfigurasiya etmək üçün bölmələri əlavə edin, silin və ya yerlərini dəyişin.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Siyahıya element əlavə edin.",
                +	"LISTS_REPEAT_TOOLTIP": "Təyin olunmuş elementin/qiymətin təyin olunmuş sayda təkrarlandığı siyahını yaradır.",
                +	"LISTS_REPEAT_TITLE": "%1 elementinin %2 dəfə təkrarlandığı siyahı düzəlt",
                +	"LISTS_LENGTH_TITLE": "%1 siyahısının uzunluğu",
                +	"LISTS_LENGTH_TOOLTIP": "Siyahının uzunluğunu verir.",
                +	"LISTS_ISEMPTY_TITLE": "%1 boşdur",
                +	"LISTS_ISEMPTY_TOOLTIP": "Siyahı boşdursa \"doğru\" cavabını qaytarır.",
                +	"LISTS_INLIST": "siyahıda",
                +	"LISTS_INDEX_OF_FIRST": "Element ilə ilk rastlaşma indeksini müəyyən edin",
                +	"LISTS_INDEX_OF_LAST": "Element ilə son rastlaşma indeksini müəyyən edin",
                +	"LISTS_INDEX_OF_TOOLTIP": "Siyahıda element ilə ilk/son rastlaşma indeksini qaytarır. Əgər tekst siyahıda tapılmazsa, %1 qaytarılır.",
                +	"LISTS_GET_INDEX_GET": "götür",
                +	"LISTS_GET_INDEX_GET_REMOVE": "götür və sil",
                +	"LISTS_GET_INDEX_REMOVE": "yığışdır",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "axırdan # nömrəli",
                +	"LISTS_GET_INDEX_FIRST": "birinci",
                +	"LISTS_GET_INDEX_LAST": "axırıncı",
                +	"LISTS_GET_INDEX_RANDOM": "təsadüfi",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ilk elementdir.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 son elementdir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Siyahıdan təyin olunmuş indeksli elementi qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Siyahının ilk elementini qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Siyahının son elementini qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Siyahıdan hər hansı təsadüfi elementi qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Siyahıdan təyin olunmuş indeksli elementi silir və qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Siyahıdan ilk elementi silir və qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Siyahıdan son elementi silir və qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Siyahıdan təsadufi elementi silir və qaytarır.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Siyahıdan təyin olunmuş indeksli elementi silir.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Siyahıdan ilk elementi silir.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Siyahıdan son elementi silir.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Siyahıdan təsadüfi bir elementi silir.",
                +	"LISTS_SET_INDEX_SET": "təyin et",
                +	"LISTS_SET_INDEX_INSERT": "daxil et",
                +	"LISTS_SET_INDEX_INPUT_TO": "Kimi",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Siyahının göstərilən yerdəki elementini təyin edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Siyahıda birinci elementi təyin edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Siyahının sonuncu elementini təyin edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Siyahının təsadüfi seçilmiş bir elementini təyin edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Elementi siyahıda göstərilən yerə daxil edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Elementi siyahının əvvəlinə daxil edir.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Elementi siyahının sonuna artırır.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Elementi siyahıda təsadüfi seçilmiş bir yerə atır.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "# - dən alt-siyahını alın",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "# sonuncudan alt-siyahını alın",
                +	"LISTS_GET_SUBLIST_START_FIRST": "Birincidən alt-siyahını alın",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "# nömrəliyə",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "sondan # nömrəliyə",
                +	"LISTS_GET_SUBLIST_END_LAST": "Sonuncuya",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Siyahının təyin olunmuş hissəsinin surətini yaradın.",
                +	"VARIABLES_GET_TOOLTIP": "Bu dəyişənin qiymətini qaytarır.",
                +	"VARIABLES_GET_CREATE_SET": "'%1 - i təyin et' - i yarat",
                +	"VARIABLES_SET": "%1 - i bu qiymət ilə təyin et: %2",
                +	"VARIABLES_SET_TOOLTIP": "Bu dəyişəni daxil edilmiş qiymətə bərabər edir.",
                +	"VARIABLES_SET_CREATE_GET": "'%1 - i götür' - ü yarat",
                +	"PROCEDURES_DEFNORETURN_TITLE": "icra et:",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "hansısa əməliyyat",
                +	"PROCEDURES_BEFORE_PARAMS": "ilə:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ilə:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Nəticəsi olmayan funksiya yaradır.",
                +	"PROCEDURES_DEFRETURN_RETURN": "qaytar",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Nəticəsi olan funksiya yaradır.",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Xəbərdarlıq: Bu funksiyanın təkrar olunmuş parametrləri var.",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Yaradılmış '%1' funksiyasını çalışdır.",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Yaradılmış '%1' funksiyasını çalışdır və nəticəni istifadə et.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "girişlər",
                +	"PROCEDURES_MUTATORARG_TITLE": "Giriş adı:",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Funksiyanın təyinatını vurğula",
                +	"PROCEDURES_CREATE_DO": "'%1' yarat",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Əgər bir dəyər \"doğru\"-dursa onda ikinci dəyəri qaytar.",
                +	"PROCEDURES_IFRETURN_WARNING": "Xəbərdarlıq: Bu blok ancaq bir funksiyanın təyinatı daxilində işlədilə bilər."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ba.json b/blockly/webif/static/blockly/msg/json/ba.json
                new file mode 100644
                index 000000000..2683254b6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ba.json
                @@ -0,0 +1,207 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Alfiya55",
                +			"Ләйсән",
                +			"Айсар",
                +			"Кутлубаева Кунсулу Закиевна",
                +			"Азат Хәлилов",
                +			"Танзиля Кутлугильдина"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "элемент",
                +	"TODAY": "Бөгөн",
                +	"DUPLICATE_BLOCK": "Күсереп алырға",
                +	"ADD_COMMENT": "Фекер өҫтәргә",
                +	"REMOVE_COMMENT": "Аңлатмаларҙы юйырға",
                +	"EXTERNAL_INPUTS": "Тышҡы өҫтәлмә",
                +	"INLINE_INPUTS": "Эске өҫтәлмә",
                +	"DELETE_BLOCK": "Блокты юйҙырырға",
                +	"DELETE_X_BLOCKS": " %1 блокты юйҙырырға",
                +	"DELETE_ALL_BLOCKS": "Бөтә %1 блоктарҙы юйырғамы?",
                +	"CLEAN_UP": "Блоктарҙы таҙартырға",
                +	"COLLAPSE_BLOCK": "Блокты төрөргә",
                +	"COLLAPSE_ALL": "Блоктарҙы төрөргә",
                +	"EXPAND_BLOCK": "Блокты йәйергә",
                +	"EXPAND_ALL": "Блоктарҙы йәйергә",
                +	"DISABLE_BLOCK": "Блокты һүндерергә",
                +	"ENABLE_BLOCK": "Блокты тоҡандырырға",
                +	"HELP": "Ярҙам",
                +	"UNDO": "Кире алырға",
                +	"REDO": "документтарҙы үҙгәртергә",
                +	"CHANGE_VALUE_TITLE": "Мәғәнәне үҙгәртегеҙ:",
                +	"RENAME_VARIABLE": "Үҙгәреүсәндең исемен алмаштырырға...",
                +	"RENAME_VARIABLE_TITLE": "Бөтә '%1' үҙгәреүсәндәрҙең исемен ошолай алмаштырырға:",
                +	"NEW_VARIABLE": "Яңы үҙгәреүсән...",
                +	"NEW_VARIABLE_TITLE": "Яңы үҙгәреүсәндең исеме:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Төҫ",
                +	"COLOUR_PICKER_TOOLTIP": "Палитранан төҫ һайлағыҙ.",
                +	"COLOUR_RANDOM_TITLE": "осраҡлы төҫ",
                +	"COLOUR_RANDOM_TOOLTIP": "Төҫтө осраҡлылыҡ буйынса һайлай.",
                +	"COLOUR_RGB_TITLE": "ошонан төҫ",
                +	"COLOUR_RGB_RED": "ҡыҙылдан",
                +	"COLOUR_RGB_GREEN": "йәшелдән",
                +	"COLOUR_RGB_BLUE": "зәңгәр",
                +	"COLOUR_RGB_TOOLTIP": "Бирелгән нисбәттәрҙә ҡыҙылдан, йәшелдән һәм зәңгәрҙән төҫ барлыҡҡа килә. Бөтә мәғәнәләр 0 менән 100 араһында булырға тейеш.",
                +	"COLOUR_BLEND_TITLE": "ҡатнаштырырға",
                +	"COLOUR_BLEND_COLOUR1": "1-се төҫ",
                +	"COLOUR_BLEND_COLOUR2": "2-се төҫ",
                +	"COLOUR_BLEND_RATIO": "1-се төҫтөң өлөшө",
                +	"COLOUR_BLEND_TOOLTIP": "Ике төҫтө бирелгән нисбәттә болғата (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/Цикл_(программалау)",
                +	"CONTROLS_REPEAT_TITLE": " %1 тапҡыр ҡабатларға",
                +	"CONTROLS_REPEAT_INPUT_DO": "үтәргә",
                +	"CONTROLS_REPEAT_TOOLTIP": "Командаларҙы бер нисә тапҡыр үтәй.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ҡабатларға, әлегә",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ҡабатларға, әлегә юҡ",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Мәғәнә дөрөҫ булғанда, командаларҙы ҡабатлай.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Мәғәнә ялған булғанда, командаларҙы ҡабатлай.",
                +	"CONTROLS_FOR_TOOLTIP": "Үҙгәреүсәнгә башынан аҙағына тиклем тәғәйен аҙым менән %1 мәғәнәне бирә һәм күрһәтелгән командаларҙы үтәй.",
                +	"CONTROLS_FOREACH_TITLE": "һәр элемент өсөн %1 исемлектә %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Исемлектәге һәр элемент өсөн үҙгәреүсәнгә элементтың '%1' мәғәнәһен бирә һәм күрһәтелгән командаларҙы үтәй.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "циклдан сығырға",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "циклдың киләһе аҙымына күсергә",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Был циклды өҙә.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Циклдың ҡалдығын төшөрөп ҡалдыра һәм киләһе аҙымға күсә.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Иҫкәртеү: был блок цикл эсендә генә ҡулланыла ала.",
                +	"CONTROLS_IF_TOOLTIP_1": "Мәғәнә дөрөҫ булғанда, командаларҙы үтәй.",
                +	"CONTROLS_IF_TOOLTIP_2": "Шарт дөрөҫ булғанда, командаларҙың беренсе блогын үтәй. Улай булмаһа, командаларҙың икенсе блогы үтәлә.",
                +	"CONTROLS_IF_TOOLTIP_3": "Беренсе шарт дөрөҫ булһа, командаларҙың беренсе блогын үтәй. Икенсе шарт дөрөҫ булһа, командаларҙың икенсе блогын үтәй.",
                +	"CONTROLS_IF_TOOLTIP_4": "Беренсе шарт дөрөҫ булһа, командаларҙың беренсе блогын үтәй. Әгәр икенсе шарт дөрөҫ булһа, командаларҙың икенсе блогын үтәй. Бер шарт та дөрөҫ булмаһа, команда блоктарының һуңғыһын үтәй.",
                +	"CONTROLS_IF_MSG_IF": "әгәр",
                +	"CONTROLS_IF_MSG_ELSEIF": "юғиһә, әгәр",
                +	"CONTROLS_IF_MSG_ELSE": "юғиһә",
                +	"CONTROLS_IF_IF_TOOLTIP": "\"Әгәр\" блогын ҡабаттан төҙөү өсөн киҫәктәрҙе өҫтәгеҙ, юйҙырығыҙ, урындарын алмаштырығыҙ.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "\"Әгәр\" блогына шарт өҫтәй",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Бер шарт та дөрөҫ булмаған осраҡҡа йомғаҡлау ярҙамсы блогын өҫтәргә.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(математика)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Өҫтәмәләр тигеҙ булһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Өҫтәмәләр тигеҙ булмаһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Беренсе өҫтәмә икенсеһенән бәләкәйерәк булһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Беренсе өҫтәмә икенсеһенән бәләкәйерәк йә уға тиң булһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Беренсе өҫтәмә икенсеһенән ҙурыраҡ булһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Беренсе өҫтәмә икенсеһенән бәләкәйерәк йә уға тиң булһа, дөрөҫ мәғәнәһен кире ҡайтара.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Әгәр ҙә ике өҫтәлмә лә тап килһә, дөрөҫ аңлатманы кире ҡайтара.",
                +	"LOGIC_OPERATION_AND": "һәм",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Өҫтәлмәләрҙең береһе генә дөрөҫ булһа, дөрөҫ аңлатманы ҡайтара.",
                +	"LOGIC_OPERATION_OR": "йәки",
                +	"LOGIC_NEGATE_TITLE": "%1 түгел",
                +	"LOGIC_NEGATE_TOOLTIP": "Өҫтәлмә ялған булһа, дөрөҫ аңлатманы ҡайтара. Өҫтәлмә дөрөҫ булһа, ялған аңлатманы ҡайтара.",
                +	"LOGIC_BOOLEAN_TRUE": "дөрөҫ",
                +	"LOGIC_BOOLEAN_FALSE": "ялған",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Дөрөҫ йәки ялғанды ҡайтара.",
                +	"LOGIC_NULL": "нуль",
                +	"LOGIC_NULL_TOOLTIP": "Нулде ҡайтара.",
                +	"LOGIC_TERNARY_CONDITION": "тест",
                +	"LOGIC_TERNARY_IF_TRUE": "әгәр дөрөҫ булһа",
                +	"LOGIC_TERNARY_IF_FALSE": "әгәр ялған булһа",
                +	"LOGIC_TERNARY_TOOLTIP": "Һайлау шартын тикшерә. Әгәр ул дөрөҫ булһа, беренсе мәғәнәне, хата булһа, икенсе мәғәнәне ҡайтара.",
                +	"MATH_NUMBER_HELPURL": "https://ba.wikipedia.org/wiki/Һан",
                +	"MATH_NUMBER_TOOLTIP": "Рәт.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ba.wikipedia.org/wiki/Арифметика",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Ике һандың суммаһын ҡайтара.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Ике һандың айырмаһын ҡайтара.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Ике һандың ҡабатландығын ҡайтара.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Ике һандың бүлендеген ҡайтара.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Дәрәжәгә күтәрелгән икенсе һандан тәүгеһенә ҡайтара.",
                +	"MATH_SINGLE_HELPURL": "https://ba.wikipedia.org/wiki/Квадрат_тамыр",
                +	"MATH_SINGLE_OP_ROOT": "квадрат тамыр",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Һандың квадрат тамырын ҡайтара.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "абсолют",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Һандың модулен ҡайтара.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Кире һанды ҡайтара.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Һандың натураль логаритмын ҡайтара.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Һандың унынсы логаритмын ҡайтара.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Күрһәтелгән дәрәжәлә ҡайтара.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Күрһәтелгән 10-сы дәрәжәлә ҡайтара.",
                +	"MATH_TRIG_HELPURL": "https://ba..wikipedia.org/wiki/Тригонометрик_функциялар",
                +	"MATH_TRIG_TOOLTIP_SIN": "Мөйөштөң синусын градустарҙа ҡайтара.",
                +	"MATH_TRIG_TOOLTIP_COS": "Мөйөштөң косинусын градустарҙа ҡайтара.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Мөйөштөң тангенсын градустарҙа күрһәтә.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Арксинусты градустарҙа күрһәтә.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Арккосинусты градустарҙа күрһәтә.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Арктангенсты градустарҙа күрһәтә.",
                +	"MATH_CONSTANT_HELPURL": "https://ba.wikipedia.org/wiki/Математик_константа",
                +	"MATH_CONSTANT_TOOLTIP": "Таралған константаның береһен күрһәтә: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) йәки ∞ (сикһеҙлек).",
                +	"MATH_IS_EVEN": "тағы",
                +	"MATH_IS_ODD": "сәйер",
                +	"MATH_IS_PRIME": "ябай",
                +	"MATH_IS_WHOLE": "бөтөн",
                +	"MATH_IS_POSITIVE": "ыңғай",
                +	"MATH_IS_NEGATIVE": "тиҫкәре",
                +	"MATH_IS_DIVISIBLE_BY": "бүленә",
                +	"MATH_IS_TOOLTIP": "Һандың йоп, таҡ, ябай, бөтөн, ыңғай, кире йәки билдәле һанға ҡарата ниндәй булыуын тикшерә. Дөрөҫ йә ялған мәғәнәһен күрһәтә.",
                +	"MATH_CHANGE_HELPURL": "https://ba.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%1 тан %2 ҡа арттырырға",
                +	"MATH_CHANGE_TOOLTIP": "Үҙгәреүсән һанға өҫтәй '%1'.",
                +	"MATH_ROUND_HELPURL": "https://ba.wikipedia.org/wiki/Т=Түңәрәкләү",
                +	"MATH_ROUND_TOOLTIP": "Һанды ҙурына йә бәләкәйенә тиклем түңәрәкләргә.",
                +	"MATH_ROUND_OPERATOR_ROUND": "түңәрәк",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ҙурына тиклем түңәрәкләргә",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "бәләкәйгә тиклем түңәрәкләргә",
                +	"MATH_ONLIST_OPERATOR_SUM": "исемлек суммаһы",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Исемлектәрҙәге һандар суммаһын күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_MIN": "Исемлектәге иң бәләкәйе",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Исемлектәге иң бәләкәй һанды күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_MAX": "исемлектәге иң ҙуры",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Исемлектең иң ҙур һанын  күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "исемлектең уртаса арифметик дәүмәле",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Исемлектең уртаса арифметик дәүмәле күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "исемлек медианаһы",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Исемлек медианаһын күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_MODE": "исемлек модалары",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Исемлектең иң күп осраған элементтарын күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "исемлекте стандарт кире ҡағыу",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Исемлекте стандарт кире ҡағыуҙы күрһәтә.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "исемлектең осраҡлы элементы",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Исемлектең осраҡлы элементын күрһәтә.",
                +	"MATH_MODULO_HELPURL": "https://ba.wikipedia.org/wiki/Ҡалдыҡ_менән_бүлеү",
                +	"MATH_MODULO_TITLE": "ҡалдыҡ %1 : %2 араһында",
                +	"MATH_MODULO_TOOLTIP": "Ике һанды бүлеү ҡалдығын күрһәтә.",
                +	"MATH_CONSTRAIN_TITLE": "сикләргә %1 аҫтан %2 өҫтән %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Һанды аҫтан һәм өҫтән сикләй (сиктәгеләрен индереп).",
                +	"MATH_RANDOM_INT_HELPURL": "https://ba.wikipedia.org/wiki/Ялған осраҡлы_һандар_генераторы",
                +	"MATH_RANDOM_INT_TITLE": "%1-ҙән %2-гә тиклем осраҡлы бөтөн һан",
                +	"MATH_RANDOM_INT_TOOLTIP": "Ике бирелгән һан араһындағы (үҙҙәрен дә индереп) осраҡлы һанды күрһәтә.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://ba.wikipedia.org/wiki/Ялған осраҡлы_һандар_генераторы",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "0 (үҙен дә индереп) һәм 1 араһындағы осраҡлы һан",
                +	"TEXT_TEXT_TOOLTIP": "Текстың хәрефе, һүҙе йәки юлы.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "текст төҙөргә",
                +	"TEXT_JOIN_TOOLTIP": "Элементтарҙың теләһә күпме һанын берләштереп текст фрагментын булдыра.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "ҡушылығыҙ",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Текстҡа элемент өҫтәү.",
                +	"TEXT_APPEND_TOOLTIP": "Үҙгәреүсән «%1»-гә текст өҫтәргә.",
                +	"TEXT_LENGTH_TITLE": "оҙонлоғо %1",
                +	"TEXT_LENGTH_TOOLTIP": "Бирелгән текстағы символдар һанын (буш урындар менән бергә) кире ҡайтара.",
                +	"TEXT_ISEMPTY_TITLE": "%1 буш",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "текстың тәүге инеүен табырға",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "Текстың һуңғы инеүен табырға",
                +	"TEXT_CHARAT_FROM_START": "хат алырға #",
                +	"TEXT_CHARAT_FROM_END": "№ хәрефен аҙаҡтан алырға",
                +	"TEXT_CHARAT_FIRST": "тәүге хәрефте алырға",
                +	"TEXT_CHARAT_LAST": "һуңғы хәрефте алырға",
                +	"TEXT_CHARAT_RANDOM": "осраҡлы хәрефте алырға",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "текста",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "# хатҡа",
                +	"TEXT_GET_SUBSTRING_END_LAST": "һуңғы хәрефкә тиклем",
                +	"TEXT_PRINT_TITLE": "%1 баҫтырырға",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "менән исемлек төҙөргә",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "исемлек",
                +	"LISTS_LENGTH_TITLE": "оҙонлоғо %1",
                +	"LISTS_ISEMPTY_TITLE": "%1 буш",
                +	"LISTS_INLIST": "исемлеккә",
                +	"LISTS_GET_INDEX_GET": "алырға",
                +	"LISTS_GET_INDEX_GET_REMOVE": "алырға һәм юйырға",
                +	"LISTS_GET_INDEX_REMOVE": "юйырға",
                +	"LISTS_GET_INDEX_FROM_END": "# аҙағынан",
                +	"LISTS_GET_INDEX_FIRST": "беренсе",
                +	"LISTS_GET_INDEX_LAST": "аҙаҡҡы",
                +	"LISTS_GET_INDEX_RANDOM": "осраҡлы",
                +	"LISTS_SET_INDEX_SET": "йыйылма",
                +	"LISTS_SET_INDEX_INSERT": "өҫтәп ҡуйырға",
                +	"LISTS_SET_INDEX_INPUT_TO": "кеүек",
                +	"PROCEDURES_DEFRETURN_RETURN": "кире ҡайтарыу",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "инеү",
                +	"PROCEDURES_MUTATORARG_TITLE": "инеү исеме:",
                +	"PROCEDURES_CREATE_DO": "'%1' төҙөргә"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/bcc.json b/blockly/webif/static/blockly/msg/json/bcc.json
                new file mode 100644
                index 000000000..da6c6a66f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/bcc.json
                @@ -0,0 +1,285 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Baloch Afghanistan"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "مورد",
                +	"DUPLICATE_BLOCK": "تکراری",
                +	"ADD_COMMENT": "افزودن نظر",
                +	"REMOVE_COMMENT": "حذف نظر",
                +	"EXTERNAL_INPUTS": "ورودی‌های خارجی",
                +	"INLINE_INPUTS": "ورودی‌های درون خطی",
                +	"DELETE_BLOCK": "حذف بلوک",
                +	"DELETE_X_BLOCKS": "حذف بلوک‌های %1",
                +	"COLLAPSE_BLOCK": "فروپاشی بلوک",
                +	"COLLAPSE_ALL": "فروپاشی بلوک‌ها",
                +	"EXPAND_BLOCK": "گسترش بلوک",
                +	"EXPAND_ALL": "گسترش بلوک‌ها",
                +	"DISABLE_BLOCK": "غیرفعال‌سازی بلوک",
                +	"ENABLE_BLOCK": "فعال‌سازی بلوک",
                +	"HELP": "کومک",
                +	"CHANGE_VALUE_TITLE": "تغییر مقدار:",
                +	"RENAME_VARIABLE": "تغییر نام متغیر...",
                +	"RENAME_VARIABLE_TITLE": "تغییر نام همهٔ متغیرهای «%1» به:",
                +	"NEW_VARIABLE": "متغیر تازه...",
                +	"NEW_VARIABLE_TITLE": "نام متغیر تازه:",
                +	"COLOUR_PICKER_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%86%DA%AF",
                +	"COLOUR_PICKER_TOOLTIP": "انتخاب یک رنگ از تخته‌رنگ.",
                +	"COLOUR_RANDOM_TITLE": "رنگ تصادفی",
                +	"COLOUR_RANDOM_TOOLTIP": "انتخاب یک رنگ به شکل تصادفی.",
                +	"COLOUR_RGB_TITLE": "رنگ با",
                +	"COLOUR_RGB_RED": "قرمز",
                +	"COLOUR_RGB_GREEN": "سبز",
                +	"COLOUR_RGB_BLUE": "آبی",
                +	"COLOUR_RGB_TOOLTIP": "ساخت یک رنگ با مقدار مشخص‌شده‌ای از قرمز، سبز و آبی. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.",
                +	"COLOUR_BLEND_TITLE": "مخلوط",
                +	"COLOUR_BLEND_COLOUR1": "رنگ ۱",
                +	"COLOUR_BLEND_COLOUR2": "رنگ ۲",
                +	"COLOUR_BLEND_RATIO": "نسبت",
                +	"COLOUR_BLEND_TOOLTIP": "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)",
                +	"CONTROLS_REPEAT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AD%D9%84%D9%82%D9%87_%D9%81%D9%88%D8%B1",
                +	"CONTROLS_REPEAT_TITLE": "%1 بار تکرار",
                +	"CONTROLS_REPEAT_INPUT_DO": "انجام",
                +	"CONTROLS_REPEAT_TOOLTIP": "انجام چند عبارت چندین بار.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "تکرار در حالی که",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "تکرار تا",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_FOR_TOOLTIP": "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.",
                +	"CONTROLS_FOR_TITLE": "با تعداد %1 از %2 به %3 با گام‌های %4",
                +	"CONTROLS_FOREACH_TITLE": "برای هر مورد %1 در فهرست %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "شکستن حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ادامه با تکرار بعدی حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "شکستن حلقهٔ شامل.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.",
                +	"CONTROLS_IF_TOOLTIP_1": "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_2": "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_3": "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_4": "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.",
                +	"CONTROLS_IF_MSG_IF": "اگر",
                +	"CONTROLS_IF_MSG_ELSEIF": "اگر آنگاه",
                +	"CONTROLS_IF_MSG_ELSE": "آنگاه",
                +	"CONTROLS_IF_IF_TOOLTIP": "اضافه، حذف یا ترتیب‌سازی قسمت‌ها برای تنظیم مجدد این بلوک اگر مسدود است.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "افزودن یک شرط به بلوک اگر.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "اضافه‌کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.",
                +	"LOGIC_COMPARE_HELPURL": "https://fa.wikipedia.org/wiki/%D9%86%D8%A7%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1%DB%8C",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_AND": "و",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_OR": "یا",
                +	"LOGIC_NEGATE_TITLE": "نه %1",
                +	"LOGIC_NEGATE_TOOLTIP": "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.",
                +	"LOGIC_BOOLEAN_TRUE": "صحیح",
                +	"LOGIC_BOOLEAN_FALSE": "ناصحیح",
                +	"LOGIC_BOOLEAN_TOOLTIP": "بازگرداندن یکی از صحیح یا ناصحیح.",
                +	"LOGIC_NULL": "تهی",
                +	"LOGIC_NULL_TOOLTIP": "تهی بازمی‌گرداند.",
                +	"LOGIC_TERNARY_CONDITION": "آزمایش",
                +	"LOGIC_TERNARY_IF_TRUE": "اگر صحیح",
                +	"LOGIC_TERNARY_IF_FALSE": "اگر ناصحیح",
                +	"LOGIC_TERNARY_TOOLTIP": "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.",
                +	"MATH_NUMBER_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF",
                +	"MATH_NUMBER_TOOLTIP": "یک عدد.",
                +	"MATH_ARITHMETIC_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "بازگرداندن مقدار جمع دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "بازگرداندن تفاوت دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "بازگرداندن حاصلضرب دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "بازگرداندن باقی‌ماندهٔ دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.",
                +	"MATH_SINGLE_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%DB%8C%D8%B4%D9%87_%D8%AF%D9%88%D9%85",
                +	"MATH_SINGLE_OP_ROOT": "ریشهٔ دوم",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ریشهٔ دوم یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "مطلق",
                +	"MATH_SINGLE_TOOLTIP_ABS": "قدر مطلق یک عدد را بازمی‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "منفی‌شدهٔ یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LN": "لوگاریتم طبیعی یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "بازگرداندن توان e یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "بازگرداندن توان ۱۰ یک عدد.",
                +	"MATH_TRIG_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%D9%87%D8%A7%DB%8C_%D9%85%D8%AB%D9%84%D8%AB%D8%A7%D8%AA%DB%8C",
                +	"MATH_TRIG_TOOLTIP_SIN": "بازگرداندن سینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_COS": "بازگرداندن کسینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_TAN": "بازگرداندن تانژانت یک درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "بازگرداندن آرک‌سینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ACOS": "بازگرداندن آرک‌کسینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "بازگرداندن آرک‌تانژانت درجه (نه رادیان).",
                +	"MATH_CONSTANT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AB%D8%A7%D8%A8%D8%AA_%D8%B1%DB%8C%D8%A7%D8%B6%DB%8C",
                +	"MATH_CONSTANT_TOOLTIP": "یکی از مقادیر مشترک را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).",
                +	"MATH_IS_EVEN": "زوج است",
                +	"MATH_IS_ODD": "فرد است",
                +	"MATH_IS_PRIME": "عدد اول است",
                +	"MATH_IS_WHOLE": "کامل است",
                +	"MATH_IS_POSITIVE": "مثبت است",
                +	"MATH_IS_NEGATIVE": "منفی است",
                +	"MATH_IS_DIVISIBLE_BY": "تقسیم شده بر",
                +	"MATH_IS_TOOLTIP": "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.",
                +	"MATH_CHANGE_HELPURL": "https://fa.wikipedia.org/wiki/%D8%A7%D8%B5%D8%B7%D9%84%D8%A7%D8%AD_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C#.D8.A7.D9.81.D8.B2.D8.A7.DB.8C.D8.B4_.D8.B4.D9.85.D8.A7.D8.B1.D9.86.D8.AF.D9.87",
                +	"MATH_CHANGE_TITLE": "تغییر %1 با %2",
                +	"MATH_CHANGE_TOOLTIP": "افزودن یک عدد به متغیر '%1'.",
                +	"MATH_ROUND_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"MATH_ROUND_TOOLTIP": "گردکردن یک عدد به بالا یا پایین.",
                +	"MATH_ROUND_OPERATOR_ROUND": "گردکردن",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "گرد به بالا",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "گرد به پایین",
                +	"MATH_ONLIST_OPERATOR_SUM": "جمع فهرست",
                +	"MATH_ONLIST_TOOLTIP_SUM": "جمع همهٔ عددهای فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MIN": "کوچکترین فهرست",
                +	"MATH_ONLIST_TOOLTIP_MIN": "کوچک‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MAX": "بزرگ‌ترین فهرست",
                +	"MATH_ONLIST_TOOLTIP_MAX": "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "میانگین فهرست",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "میانهٔ فهرست",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "میانهٔ عدد در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MODE": "مد فهرست",
                +	"MATH_ONLIST_TOOLTIP_MODE": "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "انحراف معیار فهرست",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "انحراف معیار فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "مورد تصادفی از فهرست",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "موردی تصادفی از فهرست را بر می‌گرداند.",
                +	"MATH_MODULO_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B9%D9%85%D9%84%DB%8C%D8%A7%D8%AA_%D9%BE%DB%8C%D9%85%D8%A7%D9%86%D9%87",
                +	"MATH_MODULO_TITLE": "باقی‌ماندهٔ %1 + %2",
                +	"MATH_MODULO_TOOLTIP": "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.",
                +	"MATH_CONSTRAIN_TITLE": "محدودکردن %1 پایین %2 بالا %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).",
                +	"MATH_RANDOM_INT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C",
                +	"MATH_RANDOM_INT_TITLE": "عدد صحیح تصادفی بین %1 تا %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "کسر تصادفی",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).",
                +	"TEXT_TEXT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D8%B4%D8%AA%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"TEXT_TEXT_TOOLTIP": "یک حرف، کلمه یا خطی از متن.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ایجاد متن با",
                +	"TEXT_JOIN_TOOLTIP": "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "عضویت",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "اضافه، حذف یا ترتیب‌سازی قسمت‌ها برای تنظیم مجدد این بلوک اگر مسدود است.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "افزودن یک مورد به متن.",
                +	"TEXT_APPEND_TOOLTIP": "الحاق متنی به متغیر «%1».",
                +	"TEXT_LENGTH_TITLE": "طول %1",
                +	"TEXT_LENGTH_TOOLTIP": "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.",
                +	"TEXT_ISEMPTY_TITLE": "%1 خالی است",
                +	"TEXT_ISEMPTY_TOOLTIP": "اضافه‌کردن صحیح اگر متن فراهم‌شده خالی است.",
                +	"TEXT_INDEXOF_TOOLTIP": "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "اولین رخداد متن را بیاب",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "آخرین رخداد متن را بیاب",
                +	"TEXT_CHARAT_FROM_START": "گرفتن حرف #",
                +	"TEXT_CHARAT_FROM_END": "گرفتن حرف # از آخر",
                +	"TEXT_CHARAT_FIRST": "گرفتن اولین حرف",
                +	"TEXT_CHARAT_LAST": "گرفتن آخرین حرف",
                +	"TEXT_CHARAT_RANDOM": "گرفتن حرف تصادفی",
                +	"TEXT_CHARAT_TOOLTIP": "حرفی در موقعیت مشخص‌شده بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "در متن",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "گرفتن زیرمتن از حرف #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "گرفتن زیرمتن از حرف # به انتها",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "گرفتن زیرمتن از اولین حرف",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "به حرف #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "به حرف # از انتها",
                +	"TEXT_GET_SUBSTRING_END_LAST": "گرفتن آخرین حرف",
                +	"TEXT_CHANGECASE_TOOLTIP": "بازگرداندن کپی متن در حالتی متفاوت.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "به حروف بزرگ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "به حروف کوچک",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "به حروف بزرگ عنوان",
                +	"TEXT_TRIM_TOOLTIP": "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "تراشیدن فاصله‌ها از  هر دو طرف",
                +	"TEXT_TRIM_OPERATOR_LEFT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_PRINT_TITLE": "چاپ %1",
                +	"TEXT_PRINT_TOOLTIP": "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.",
                +	"TEXT_PROMPT_TYPE_TEXT": "اعلان برای متن با پیام",
                +	"TEXT_PROMPT_TYPE_NUMBER": "اعلان برای عدد با پیام",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "اعلان برای کاربر با یک عدد.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "اعلان برای کاربر برای یک متن.",
                +	"LISTS_CREATE_EMPTY_TITLE": "ایجاد فهرست خالی",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "فهرستی از هر عددی از موارد می‌سازد.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "ایجاد فهرست با",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "فهرست",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "اضافه‌کردن، حذف‌کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "اضافه‌کردن یک مورد به فهرست.",
                +	"LISTS_REPEAT_TOOLTIP": "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.",
                +	"LISTS_REPEAT_TITLE": "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد",
                +	"LISTS_LENGTH_TITLE": "طول %1",
                +	"LISTS_LENGTH_TOOLTIP": "طول یک فهرست را برمی‌گرداند.",
                +	"LISTS_ISEMPTY_TITLE": "%1 خالی است",
                +	"LISTS_ISEMPTY_TOOLTIP": "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.",
                +	"LISTS_INLIST": "در فهرست",
                +	"LISTS_INDEX_OF_FIRST": "آخرین رخداد متن را بیاب",
                +	"LISTS_INDEX_OF_LAST": "یافتن آخرین رخ‌داد مورد",
                +	"LISTS_INDEX_OF_TOOLTIP": "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر متن موجود نبود.",
                +	"LISTS_GET_INDEX_GET": "گرفتن",
                +	"LISTS_GET_INDEX_GET_REMOVE": "گرفتن و حذف‌کردن",
                +	"LISTS_GET_INDEX_REMOVE": "حذف‌کردن",
                +	"LISTS_GET_INDEX_FROM_END": "# از انتها",
                +	"LISTS_GET_INDEX_FIRST": "اولین",
                +	"LISTS_GET_INDEX_LAST": "اهرین",
                +	"LISTS_GET_INDEX_RANDOM": "تصادفی",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 اولین مورد است.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 آخرین مورد است.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "موردی در محل مشخص‌شده بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "اولین مورد یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "آخرین مورد در یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "یک مورد تصادفی در یک فهرست بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "اولین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "آخرین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "یک مورد تصادفی را یک فهرست حذف می‌کند.",
                +	"LISTS_SET_INDEX_SET": "مجموعه",
                +	"LISTS_SET_INDEX_INSERT": "درج در",
                +	"LISTS_SET_INDEX_INPUT_TO": "به‌عنوان",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "اولین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "آخرین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "یک مورد تصادفی در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "موردی به ته فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "موردی به ته فهرست الحاق می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "مورد را به صورت تصادفی در یک فهرست می‌افزاید.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "گرفتن زیرمجموعه‌ای از #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "گرفتن زیرمجموعه‌ای از # از انتها",
                +	"LISTS_GET_SUBLIST_START_FIRST": "گرفتن زیرمجموعه‌ای از ابتدا",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "به #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "به # از انتها",
                +	"LISTS_GET_SUBLIST_END_LAST": "به آخرین",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.",
                +	"VARIABLES_GET_TOOLTIP": "مقدار این متغیر را بر می‌گرداند.",
                +	"VARIABLES_GET_CREATE_SET": "درست‌کردن «تنظیم %1»",
                +	"VARIABLES_SET": "مجموعه %1 به %2",
                +	"VARIABLES_SET_TOOLTIP": "متغیر برابر با خروجی را مشخص می‌کند.",
                +	"VARIABLES_SET_CREATE_GET": "درست‌کردن «تنظیم %1»",
                +	"PROCEDURES_DEFNORETURN_TITLE": "به",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "انجام چیزی",
                +	"PROCEDURES_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "تابعی می‌سازد بدون هیچ خروجی.",
                +	"PROCEDURES_DEFRETURN_RETURN": "بازگشت",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "تابعی با یک خروجی می‌سازد.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "اجازه اظهارات",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "اخطار: این تابعی پارامتر تکراری دارد.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1».",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ورودی‌ها",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.",
                +	"PROCEDURES_MUTATORARG_TITLE": "نام ورودی:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "اضافه کردن ورودی به تابع.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "برجسته‌سازی تعریف تابع",
                +	"PROCEDURES_CREATE_DO": "ساختن «%1»",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "اگر یک مقدار صحیح است، مقدار دوم را برگردان.",
                +	"PROCEDURES_IFRETURN_WARNING": "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/be-tarask.json b/blockly/webif/static/blockly/msg/json/be-tarask.json
                new file mode 100644
                index 000000000..872011bd5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/be-tarask.json
                @@ -0,0 +1,341 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Renessaince",
                +			"Jim-by",
                +			"Red Winged Duck"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "аб’ект",
                +	"TODAY": "Сёньня",
                +	"DUPLICATE_BLOCK": "Капіяваць",
                +	"ADD_COMMENT": "Дадаць камэнтар",
                +	"REMOVE_COMMENT": "Выдаліць камэнтар",
                +	"EXTERNAL_INPUTS": "Зьнешнія ўваходы",
                +	"INLINE_INPUTS": "Унутраныя ўваходы",
                +	"DELETE_BLOCK": "Выдаліць блёк",
                +	"DELETE_X_BLOCKS": "Выдаліць %1 блёкі",
                +	"DELETE_ALL_BLOCKS": "Выдаліць усе блёкі %1?",
                +	"CLEAN_UP": "Ачысьціць блёкі",
                +	"COLLAPSE_BLOCK": "Згарнуць блёк",
                +	"COLLAPSE_ALL": "Згарнуць блёкі",
                +	"EXPAND_BLOCK": "Разгарнуць блёк",
                +	"EXPAND_ALL": "Разгарнуць блёкі",
                +	"DISABLE_BLOCK": "Адключыць блёк",
                +	"ENABLE_BLOCK": "Уключыць блёк",
                +	"HELP": "Дапамога",
                +	"UNDO": "Скасаваць",
                +	"REDO": "Паўтарыць",
                +	"CHANGE_VALUE_TITLE": "Зьмяніць значэньне:",
                +	"RENAME_VARIABLE": "Перайменаваць зьменную…",
                +	"RENAME_VARIABLE_TITLE": "Перайменаваць усе назвы зьменных '%1' на:",
                +	"NEW_VARIABLE": "Стварыць зьменную…",
                +	"NEW_VARIABLE_TITLE": "Імя новай зьменнай:",
                +	"VARIABLE_ALREADY_EXISTS": "Зьменная з назвай «%1» ужо існуе.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Зьменная з назвай «%1» ужо існуе зь іншым тыпам «%2».",
                +	"PROCEDURE_ALREADY_EXISTS": "Працэдура з назвай «%1» ужо існуе.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Выдаліць %1 выкарыстаньняў зьменнай «%2»?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Немагчыма выдаліць зьменную «%1», таму што яна зьяўляецца часткай вызначэньня функцыі «%2»",
                +	"DELETE_VARIABLE": "Выдаліць зьменную «%1»",
                +	"COLOUR_PICKER_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BB%D0%B5%D1%80",
                +	"COLOUR_PICKER_TOOLTIP": "Абярыце колер з палітры.",
                +	"COLOUR_RANDOM_TITLE": "выпадковы колер",
                +	"COLOUR_RANDOM_TOOLTIP": "Абраць выпадковы колер.",
                +	"COLOUR_RGB_TITLE": "колер з",
                +	"COLOUR_RGB_RED": "чырвонага",
                +	"COLOUR_RGB_GREEN": "зялёнага",
                +	"COLOUR_RGB_BLUE": "сіняга",
                +	"COLOUR_RGB_TOOLTIP": "Стварыць колер з абранымі прапорцыямі чырвонага, зялёнага і сіняга. Усе значэньні павінны быць ад 0 да 100.",
                +	"COLOUR_BLEND_TITLE": "зьмяшаць",
                +	"COLOUR_BLEND_COLOUR1": "колер 1",
                +	"COLOUR_BLEND_COLOUR2": "колер 2",
                +	"COLOUR_BLEND_RATIO": "дзеля",
                +	"COLOUR_BLEND_TOOLTIP": "Зьмешвае два колеры ў дадзенай прапорцыі (0.0 — 1.0)",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "паўтарыць %1 раз(ы)",
                +	"CONTROLS_REPEAT_INPUT_DO": "выканаць",
                +	"CONTROLS_REPEAT_TOOLTIP": "Выконвае апэрацыі некалькі разоў.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "паўтараць, пакуль",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "паўтараць, пакуль не",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Пакуль значэньне ісьціна, выконваць пэўныя апэрацыі.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Пакуль значэньне хлусьня, выконваць пэўныя апэрацыі.",
                +	"CONTROLS_FOR_TOOLTIP": "Прысвойвае зьменнай \"%1\" значэньні ад пачатковага да канчатковага значэньня, улічваючы зададзены крок, і выконвае абраныя блёкі.",
                +	"CONTROLS_FOR_TITLE": "лічыць з %1 ад %2 да %3 па %4",
                +	"CONTROLS_FOREACH_TITLE": "для кожнага элемэнта %1 у сьпісе %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Для кожнага элемэнту сьпісу прысвойвае зьменнай '%1' ягонае значэньне і выконвае пэўныя апэрацыі.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "перарваць цыкль",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "працягнуць з наступнага кроку цыклю",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Спыніць гэты цыкль.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Прапусьціць рэшту цыклю і перайсьці да наступнага кроку.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Увага: гэты блёк можа быць выкарыстаны толькі ў цыклі.",
                +	"CONTROLS_IF_TOOLTIP_1": "Калі значэньне ісьціна, выканаць пэўныя апэрацыі.",
                +	"CONTROLS_IF_TOOLTIP_2": "Калі значэньне ісьціна, выканаць першы блёк апэрацыяў, інакш выканаць другі блёк.",
                +	"CONTROLS_IF_TOOLTIP_3": "Калі першае значэньне ісьціна, выканаць першы блёк апэрацыяў. Інакш, калі другое значэньне ісьціна, выканаць другі блёк апэрацыяў.",
                +	"CONTROLS_IF_TOOLTIP_4": "Калі першае значэньне ісьціна, выканаць першы блёк апэрацыяў. Інакш, калі другое значэньне ісьціна, выканаць другі блёк апэрацыяў. Калі ніводнае з значэньняў не сапраўднае, выканаць апошні блёк апэрацыяў.",
                +	"CONTROLS_IF_MSG_IF": "калі",
                +	"CONTROLS_IF_MSG_ELSEIF": "інакш, калі",
                +	"CONTROLS_IF_MSG_ELSE": "інакш",
                +	"CONTROLS_IF_IF_TOOLTIP": "Дадаць, выдаліць ці пераставіць сэкцыі для пераканфігураваньня гэтага блёку «калі».",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Дадаць умову да блёку «калі».",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Дадаць заключную ўмову для ўсіх астатніх варыянтаў блёку «калі».",
                +	"IOS_OK": "Добра",
                +	"IOS_CANCEL": "Адмяніць",
                +	"IOS_ERROR": "Памылка",
                +	"IOS_PROCEDURES_INPUTS": "УВАХОДНЫЯ ЗЬВЕСТКІ",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Дадаць уваходныя зьвесткі",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Дазволіць сьцьверджаньні",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Уваходныя зьвесткі гэтай функцыі дублююцца.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Дадаць зьменную",
                +	"IOS_VARIABLES_ADD_BUTTON": "Дадаць",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Перайменаваць",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Выдаліць",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Назва зьменнай",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Вы ня можаце выкарыстоўваць пустую назву зьменнай.",
                +	"LOGIC_COMPARE_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%9D%D1%8F%D1%80%D0%BE%D1%9E%D0%BD%D0%B0%D1%81%D1%8C%D1%86%D1%8C",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Вяртае «ісьціна», калі абодва ўводы роўныя.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Вяртае «ісьціна», калі абодва ўводы ня роўныя.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Вяртае «ісьціна», калі першы ўвод меншы за другі.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Вяртае «ісьціна», калі першы ўвод меншы ці роўны другому.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Вяртае «ісьціна», калі першы ўвод большы за другі.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Вяртае «ісьціна», калі першы ўвод большы ці роўны другому.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Вяртае «ісьціна», калі абодва ўводы праўдзівыя.",
                +	"LOGIC_OPERATION_AND": "і",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Вяртае «ісьціна», калі прынамсі адзін з уводаў праўдзівы.",
                +	"LOGIC_OPERATION_OR": "ці",
                +	"LOGIC_NEGATE_TITLE": "не %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Вяртае «ісьціна», калі ўвод непраўдзівы. Вяртае «хлусьня», калі ўвод праўдзівы.",
                +	"LOGIC_BOOLEAN_TRUE": "ісьціна",
                +	"LOGIC_BOOLEAN_FALSE": "хлусьня",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Вяртае «ісьціна» ці «хлусьня».",
                +	"LOGIC_NULL": "нічога",
                +	"LOGIC_NULL_TOOLTIP": "Вяртае нічога.",
                +	"LOGIC_TERNARY_CONDITION": "тэст",
                +	"LOGIC_TERNARY_IF_TRUE": "калі ісьціна",
                +	"LOGIC_TERNARY_IF_FALSE": "калі хлусьня",
                +	"LOGIC_TERNARY_TOOLTIP": "Праверыць умову ў 'тэст'. Калі ўмова праўдзівая, будзе вернутае значэньне «калі ісьціна»; інакш будзе вернутае «калі хлусьня».",
                +	"MATH_NUMBER_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%9B%D1%96%D0%BA",
                +	"MATH_NUMBER_TOOLTIP": "Лік.",
                +	"MATH_ARITHMETIC_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%82%D0%BC%D1%8D%D1%82%D1%8B%D0%BA%D0%B0",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Вяртае суму двух лікаў.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Вяртае рознасьць двух лікаў.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Вяртае здабытак двух лікаў.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Вяртае дзель двух лікаў.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Вяртае першы лік у ступені другога ліку.",
                +	"MATH_SINGLE_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%9A%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D1%8B_%D0%BA%D0%BE%D1%80%D0%B0%D0%BD%D1%8C",
                +	"MATH_SINGLE_OP_ROOT": "квадратны корань",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Вяртае квадратны корань ліку.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "модуль",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Вяртае модуль ліку.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Вяртае супрацьлеглы лік.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Вяртае натуральны лягарытм ліку.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Вяртае дзесятковы лягарытм ліку.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Вяртае e ў ступені ліку.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Вяртае 10 у ступені ліку.",
                +	"MATH_TRIG_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%A2%D1%80%D1%8B%D0%B3%D0%B0%D0%BD%D0%B0%D0%BC%D1%8D%D1%82%D1%80%D1%8B%D1%8F#.D0.A2.D1.80.D1.8B.D0.B3.D0.B0.D0.BD.D0.B0.D0.BC.D1.8D.D1.82.D1.80.D1.8B.D1.87.D0.BD.D1.8B.D1.8F_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D1.8B.D1.96",
                +	"MATH_TRIG_TOOLTIP_SIN": "Вяртае сынус кута ў градусах.",
                +	"MATH_TRIG_TOOLTIP_COS": "Вяртае косынус кута ў градусах.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Вяртае тангэнс кута ў градусах.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Вяртае арксынус ліку.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Вяртае арккосынус ліку.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Вяртае арктангэнс ліку.",
                +	"MATH_CONSTANT_HELPURL": "https://be-x-old.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D1%8D%D0%BC%D0%B0%D1%82%D1%8B%D1%87%D0%BD%D0%B0%D1%8F_%D0%BA%D0%B0%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82%D0%B0",
                +	"MATH_CONSTANT_TOOLTIP": "Вяртае адну з агульных канстантаў: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0,707...) або ∞ (бясконцасьць).",
                +	"MATH_IS_EVEN": "парная",
                +	"MATH_IS_ODD": "няпарная",
                +	"MATH_IS_PRIME": "простая",
                +	"MATH_IS_WHOLE": "цэлая",
                +	"MATH_IS_POSITIVE": "станоўчая",
                +	"MATH_IS_NEGATIVE": "адмоўная",
                +	"MATH_IS_DIVISIBLE_BY": "дзяліць на",
                +	"MATH_IS_TOOLTIP": "Правярае, ці зьяўляецца лік парным, няпарным, простым, станоўчым, адмоўным, ці ён дзеліцца на пэўны лік без астатку. Вяртае значэньне ісьціна або няпраўда.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "зьмяніць %1 на %2",
                +	"MATH_CHANGE_TOOLTIP": "Дадае лічбу да зьменнай '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Акругленьне ліку да большага ці меншага.",
                +	"MATH_ROUND_OPERATOR_ROUND": "акругліць",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "акругліць да большага",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "акругліць да меншага",
                +	"MATH_ONLIST_OPERATOR_SUM": "Сума сьпісу",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Вяртае суму ўсіх лікаў у сьпісе.",
                +	"MATH_ONLIST_OPERATOR_MIN": "мінімальная ў сьпісе",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Вяртае найменшы лік у сьпісе.",
                +	"MATH_ONLIST_OPERATOR_MAX": "мінімальная ў сьпісе",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Вяртае найменшы лік у сьпісе.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "сярэдняя ў сьпісе",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Вяртае сярэднеарытмэтычнае значэньне лікавых значэньняў у сьпісе.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "мэдыяна сьпісу",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Вяртае мэдыяну сьпісу.",
                +	"MATH_ONLIST_OPERATOR_MODE": "рэжымы сьпісу",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Вяртае сьпіс самых распаўсюджаных элемэнтаў у сьпісе.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "стандартнае адхіленьне сьпісу",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Вяртае стандартнае адхіленьне сьпісу.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "выпадковы элемэнт сьпісу",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Вяртае выпадковы элемэнт сьпісу.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "рэшта дзяленьня %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Вяртае рэшту дзяленьня двух лікаў.",
                +	"MATH_CONSTRAIN_TITLE": "абмежаваць %1 зьнізу %2 зьверху %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Абмяжоўвае колькасьць ніжняй і верхняй межамі (уключна).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "выпадковая цэлая з %1 для %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Вяртае выпадковы цэлы лік паміж двума зададзенымі абмежаваньнямі ўключна.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "выпадковая дроб",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Вяртае выпадковую дроб у дыяпазоне ад 0,0 (уключна) да 1,0.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Літара, слова ці радок тэксту.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "стварыць тэкст з",
                +	"TEXT_JOIN_TOOLTIP": "Стварае фрагмэнт тэксту аб’яднаньнем любой колькасьці элемэнтаў.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "далучыць",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Дадайце, выдаліце ці зьмяніце парадак разьдзелаў для перадачы тэкставага блёку.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Дадаць элемэнт да тэксту.",
                +	"TEXT_APPEND_TITLE": "да %1 дадаць тэкст %2",
                +	"TEXT_APPEND_TOOLTIP": "Дадаць які-небудзь тэкст да зьменнай '%1'.",
                +	"TEXT_LENGTH_TITLE": "даўжыня %1",
                +	"TEXT_LENGTH_TOOLTIP": "Вяртае колькасьць літараў (у тым ліку прабелы) у пададзеным тэксьце.",
                +	"TEXT_ISEMPTY_TITLE": "%1 пусты",
                +	"TEXT_ISEMPTY_TOOLTIP": "Вяртае значэньне ісьціна, калі тэкст пусты.",
                +	"TEXT_INDEXOF_TOOLTIP": "Вяртае індэкс першага/апошняга ўваходжаньня першага тэксту ў другі тэкст. Вяртае %1, калі тэкст ня знойдзены.",
                +	"TEXT_INDEXOF_TITLE": "у тэксьце %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "знайсьці першае ўваходжаньне тэксту",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "знайсьці апошняе ўваходжаньне тэксту",
                +	"TEXT_CHARAT_TITLE": "у тэксьце %1 %2",
                +	"TEXT_CHARAT_FROM_START": "узяць літару №",
                +	"TEXT_CHARAT_FROM_END": "узяць літару № з канца",
                +	"TEXT_CHARAT_FIRST": "узяць першую літару",
                +	"TEXT_CHARAT_LAST": "узяць апошнюю літару",
                +	"TEXT_CHARAT_RANDOM": "узяць выпадковую літару",
                +	"TEXT_CHARAT_TOOLTIP": "Вяртае літару ў пазначанай пазыцыі.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Вяртае пазначаную частку тэксту.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "у тэксьце",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "узяць падрадок зь літары №",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "узяць падрадок зь літары № з канца",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "атрымаць падрадок зь першай літары",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "да літары №",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "да літары № з канца",
                +	"TEXT_GET_SUBSTRING_END_LAST": "да апошняй літары",
                +	"TEXT_CHANGECASE_TOOLTIP": "Вярнуць копію тэксту зь іншай велічынёй літар.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "да ВЕРХНЯГА РЭГІСТРУ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "да ніжняга рэгістру",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Вялікія Першыя Літары",
                +	"TEXT_TRIM_TOOLTIP": "Вяртае копію тэксту з прабеламі, выдаленымі ад аднаго ці абодвух бакоў.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "абрэзаць прабелы з абодвух бакоў",
                +	"TEXT_TRIM_OPERATOR_LEFT": "абрэзаць прабелы зь левага боку",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "абрэзаць прабелы з правага боку",
                +	"TEXT_PRINT_TITLE": "друкаваць %1",
                +	"TEXT_PRINT_TOOLTIP": "Надрукаваць пазначаны тэкст, лічбу ці іншыя сымбалі.",
                +	"TEXT_PROMPT_TYPE_TEXT": "запытаць тэкст з падказкай",
                +	"TEXT_PROMPT_TYPE_NUMBER": "запытаць лічбу з падказкай",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Запытаць у карыстальніка лічбу.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Запытаць у карыстальніка тэкст.",
                +	"TEXT_COUNT_MESSAGE0": "падлічыць %1 сярод %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Падлічвае колькі разоў нейкі тэкст сустракаецца ўнутры нейкага іншага тэксту.",
                +	"TEXT_REPLACE_MESSAGE0": "замяніць %1 на %2 у %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Замяняе ўсе выпадкі нейкага тэксту на іншы тэкст.",
                +	"TEXT_REVERSE_MESSAGE0": "адваротна %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Мяняе парадак сымбаляў у тэксьце на адваротны.",
                +	"LISTS_CREATE_EMPTY_TITLE": "стварыць пусты сьпіс",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Вяртае сьпіс даўжынёй 0, які ня ўтрымлівае запісаў зьвестак",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Ставарае сьпіс зь любой колькасьцю элемэнтаў.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "стварыць сьпіс з",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "сьпіс",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Дадаць, выдаліць ці пераставіць сэкцыі для пераканфігураваньня гэтага блёку.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Дадаць элемэнт да сьпісу.",
                +	"LISTS_REPEAT_TOOLTIP": "Стварае сьпіс, які ўтрымлівае пададзеную колькасьць копіяў элемэнту.",
                +	"LISTS_REPEAT_TITLE": "стварыць сьпіс з элемэнту %1, які паўтараецца %2 разоў",
                +	"LISTS_LENGTH_TITLE": "даўжыня %1",
                +	"LISTS_LENGTH_TOOLTIP": "Вяртае даўжыню сьпісу.",
                +	"LISTS_ISEMPTY_TITLE": "%1 пусты",
                +	"LISTS_ISEMPTY_TOOLTIP": "Вяртае значэньне ісьціна, калі сьпіс пусты.",
                +	"LISTS_INLIST": "у сьпісе",
                +	"LISTS_INDEX_OF_FIRST": "знайсьці першае ўваходжаньне элемэнту",
                +	"LISTS_INDEX_OF_LAST": "знайсьці апошняе ўваходжаньне элемэнту",
                +	"LISTS_INDEX_OF_TOOLTIP": "Вяртае індэкс першага/апошняга ўваходжаньня элемэнту ў сьпіс. Вяртае %1, калі элемэнт ня знойдзены.",
                +	"LISTS_GET_INDEX_GET": "атрымаць",
                +	"LISTS_GET_INDEX_GET_REMOVE": "атрымаць і выдаліць",
                +	"LISTS_GET_INDEX_REMOVE": "выдаліць",
                +	"LISTS_GET_INDEX_FROM_END": "№ з канца",
                +	"LISTS_GET_INDEX_FIRST": "першы",
                +	"LISTS_GET_INDEX_LAST": "апошні",
                +	"LISTS_GET_INDEX_RANDOM": "выпадковы",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "№%1 — першы элемэнт.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "№%1 — апошні элемэнт.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Вяртае элемэнт у пазначанай пазыцыі ў сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Вяртае першы элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Вяртае апошні элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Вяртае выпадковы элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Выдаляе і вяртае элемэнт у пазначанай пазыцыі ў сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Выдаляе і вяртае першы элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Выдаляе і вяртае апошні элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Выдаляе і вяртае выпадковы элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Выдаляе элемэнт у пазначанай пазыцыі ў сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Выдаляе першы элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Выдаляе апошні элемэнт у сьпісе.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Выдаляе выпадковы элемэнт у сьпісе.",
                +	"LISTS_SET_INDEX_SET": "усталяваць",
                +	"LISTS_SET_INDEX_INSERT": "уставіць у",
                +	"LISTS_SET_INDEX_INPUT_TO": "як",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Задае элемэнт у пазначанай пазыцыі ў сьпісе.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Задае першы элемэнт у сьпісе.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Задае апошні элемэнт у сьпісе.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Задае выпадковы элемэнт у сьпісе.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Устаўляе элемэнт у пазначанай пазыцыі ў сьпісе.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Устаўляе элемэнт у пачатак сьпісу.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Дадае элемэнт у канец сьпісу.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Выпадковым чынам устаўляе элемэнт у сьпіс.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "атрымаць падсьпіс з №",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "атрымаць падсьпіс з № з канца",
                +	"LISTS_GET_SUBLIST_START_FIRST": "атрымаць падсьпіс зь першага",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "да #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "па № з канца",
                +	"LISTS_GET_SUBLIST_END_LAST": "да апошняга",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Стварае копію пазначанай часткі сьпісу.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "сартаваць %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Сартаваць копію сьпісу.",
                +	"LISTS_SORT_ORDER_ASCENDING": "па павелічэньні",
                +	"LISTS_SORT_ORDER_DESCENDING": "па зьмяншэньні",
                +	"LISTS_SORT_TYPE_NUMERIC": "як лікі",
                +	"LISTS_SORT_TYPE_TEXT": "паводле альфабэту",
                +	"LISTS_SORT_TYPE_IGNORECASE": "паводле альфабэту, ігнараваць рэгістар",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "стварыць сьпіс з тэксту",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "стварыць тэкст са сьпісу",
                +	"LISTS_SPLIT_WITH_DELIMITER": "з падзяляльнікам",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Падзяліць тэкст у сьпіс тэкстаў, па падзяляльніках.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Аб’ядноўвае сьпіс тэкстаў у адзін тэкст па падзяляльніках.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "адваротна %1",
                +	"LISTS_REVERSE_TOOLTIP": "Зьмяняе парадак копіі сьпісу на адваротны.",
                +	"VARIABLES_GET_TOOLTIP": "Вяртае значэньне гэтай зьменнай.",
                +	"VARIABLES_GET_CREATE_SET": "Стварыць блёк «усталяваць %1»",
                +	"VARIABLES_SET": "усталяваць %1 да %2",
                +	"VARIABLES_SET_TOOLTIP": "Надаць гэтай зьменнай значэньне ўстаўкі.",
                +	"VARIABLES_SET_CREATE_GET": "Стварыць блёк «атрымаць %1»",
                +	"PROCEDURES_DEFNORETURN_TITLE": "да",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "зрабіць што-небудзь",
                +	"PROCEDURES_BEFORE_PARAMS": "з:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "з:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Стварае функцыю бяз выніку.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Апішыце гэтую функцыю…",
                +	"PROCEDURES_DEFRETURN_RETURN": "вярнуць",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Стварае функцыю з вынікам.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "дазволіць зацьвярджэньне",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Увага: гэтая функцыя мае парамэтры-дублікаты.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Запусьціць функцыю вызначаную карыстальнікам '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Запусьціць функцыю вызначаную карыстальнікам '%1' і выкарыстаць яе вынік.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "парамэтры",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Дадаць, выдаліць ці запісаць чаргу ўваходных парамэтраў для гэтай функцыі.",
                +	"PROCEDURES_MUTATORARG_TITLE": "назва парамэтру:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Дадаць уваходныя парамэтры ў функцыю.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Падсьвяціць вызначэньне функцыі",
                +	"PROCEDURES_CREATE_DO": "Стварыць '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Калі значэньне ісьціна, вярнуць другое значэньне.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Папярэджаньне: гэты блёк можа выкарыстоўвацца толькі ў вызначанай функцыі."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/bg.json b/blockly/webif/static/blockly/msg/json/bg.json
                new file mode 100644
                index 000000000..11994dbac
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/bg.json
                @@ -0,0 +1,342 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Gkostov",
                +			"Vodnokon4e",
                +			"Alpinistbg",
                +			"Miroslav35232",
                +			"StanProg"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "елемент",
                +	"TODAY": "Днес",
                +	"DUPLICATE_BLOCK": "Копирай",
                +	"ADD_COMMENT": "Добави коментар",
                +	"REMOVE_COMMENT": "Премахни коментар",
                +	"EXTERNAL_INPUTS": "Външни входове",
                +	"INLINE_INPUTS": "Вътрешни входове",
                +	"DELETE_BLOCK": "Изтрий блок",
                +	"DELETE_X_BLOCKS": "Изтрий %1 блока",
                +	"DELETE_ALL_BLOCKS": "Изтриване на всички 1% блокове?",
                +	"CLEAN_UP": "Премахни блокове",
                +	"COLLAPSE_BLOCK": "Скрий блок",
                +	"COLLAPSE_ALL": "Скрий блокове",
                +	"EXPAND_BLOCK": "Покажи блок",
                +	"EXPAND_ALL": "Покажи блокове",
                +	"DISABLE_BLOCK": "Деактивирай блок",
                +	"ENABLE_BLOCK": "Активирай блок",
                +	"HELP": "Помощ",
                +	"UNDO": "Отмяна",
                +	"REDO": "Повторение",
                +	"CHANGE_VALUE_TITLE": "Промени стойността:",
                +	"RENAME_VARIABLE": "Преименувай променливата...",
                +	"RENAME_VARIABLE_TITLE": "Преименувай всички '%1' променливи на:",
                +	"NEW_VARIABLE": "Създаване на променлива...",
                +	"NEW_VARIABLE_TITLE": "Ново име на променливата:",
                +	"VARIABLE_ALREADY_EXISTS": "Променлива с име '%1' вече съществува.",
                +	"PROCEDURE_ALREADY_EXISTS": "Процедура с име '%1' вече съществува.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Изтриване на %1 използване на променлива '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Променливата '%1' не може да бъде изтрита, защото е част от определението на функцията '%2'",
                +	"DELETE_VARIABLE": "Изтриване на променливата \"%1\"",
                +	"COLOUR_PICKER_HELPURL": "https://bg.wikipedia.org/wiki/Цвят_(оптика)",
                +	"COLOUR_PICKER_TOOLTIP": "Избери цвят от палитрата.",
                +	"COLOUR_RANDOM_TITLE": "случаен цвят",
                +	"COLOUR_RANDOM_TOOLTIP": "Избери цвят на случаен принцип.",
                +	"COLOUR_RGB_TITLE": "оцвети с",
                +	"COLOUR_RGB_RED": "червен",
                +	"COLOUR_RGB_GREEN": "зелен",
                +	"COLOUR_RGB_BLUE": "син",
                +	"COLOUR_RGB_TOOLTIP": "Създай цвят с избраните пропорции, червено, зелено и синьо. Всички стойности трябва да бъдат от 0 до 100.",
                +	"COLOUR_BLEND_TITLE": "смеси",
                +	"COLOUR_BLEND_COLOUR1": "цвят 1",
                +	"COLOUR_BLEND_COLOUR2": "цвят 2",
                +	"COLOUR_BLEND_RATIO": "съотношение",
                +	"COLOUR_BLEND_TOOLTIP": "Смесва два цвят в дадено съотношение (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://bg.wikipedia.org/wiki/Цикъл_(програмиране)#For_.D1.86.D0.B8.D0.BA.D1.8A.D0.BB.D1.8A.D1.82",
                +	"CONTROLS_REPEAT_TITLE": "Повтори %1 пъти",
                +	"CONTROLS_REPEAT_INPUT_DO": "изпълни",
                +	"CONTROLS_REPEAT_TOOLTIP": "Изпълнява команди няколко пъти.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "повтаряй докато е вярно, че",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "повтаряй докато",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Изпълни командите, ако стойността е вярна.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Изпълни командите, ако стойността не е вярна.",
                +	"CONTROLS_FOR_TOOLTIP": "Нека променлива '%1' премине през стойностите от началното до крайното число през зададената стъпка и изпълни избраните блокове.",
                +	"CONTROLS_FOR_TITLE": "преброй чрез %1 от %2 до %3 през %4",
                +	"CONTROLS_FOREACH_TITLE": "за всеки елемент %1 в списъка %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "За всеки елемент в списък присвои елемента на променливата '%1' и след това изпълни командите.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "прекъсни цикъла",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "премини към следващата стъпка от цикъла",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Прекъсни цикъла, в който се съдържа тази команда.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Премини към следващата стъпка от цикъла",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Предупреждение: Този блок може да се използва само в цикъл.",
                +	"CONTROLS_IF_TOOLTIP_1": "Ако стойността е вярна, изпълни операциите.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ако стойността е вярна, изпълни първият блок. Иначе, изпълни вторият блок.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ако първата стойност е вярна, изпълни първия блок. Иначе, ако втората стойност е вярна, изпълни втория блок.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ако първата стойност е вярна, изпълни първия блок. В противен случай, ако втората стойност е вярна, изпълни втория блок. Ако нито една от стойностите не е вярна, изпълни последния блок.",
                +	"CONTROLS_IF_MSG_IF": "ако",
                +	"CONTROLS_IF_MSG_ELSEIF": "иначе ако",
                +	"CONTROLS_IF_MSG_ELSE": "иначе",
                +	"CONTROLS_IF_IF_TOOLTIP": "Добави, премахни или пренареди частите, за да промениш този „ако“ блок.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Добави условие към „ако“ блока.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Добави окончателно, прихващащо всички останали случаи условие към блок „ако“.",
                +	"IOS_OK": "Добре",
                +	"IOS_CANCEL": "Отказ",
                +	"IOS_ERROR": "Грешка",
                +	"IOS_PROCEDURES_INPUTS": "Входни данни",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Добавяне на данни",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Позволи твърденията",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Тази функция има дублирани входни данни.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Добавяне на променлива",
                +	"IOS_VARIABLES_ADD_BUTTON": "Добавяне",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Преименуване",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Изтриване",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Име на променливата",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Не може да използвате празно име за променлива",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Върни вярно, ако двата параметъра са еднакви.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Върни вярно, ако двата параметъра са различни.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Върни вярно, ако първият параметър е по-малък от втория.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Върни истина, ако първия параметър е по-малък или равен на втория.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Върни истина, ако първия параметър е по-голям от втория.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Върни истина, ако първия параметър е по-голям или равен на втория.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Върни вярно, ако и двата параметъра са верни.",
                +	"LOGIC_OPERATION_AND": "и",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Върни „вярно“, ако поне един от входовете е верен.",
                +	"LOGIC_OPERATION_OR": "или",
                +	"LOGIC_NEGATE_TITLE": "не %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Върни вярно, ако параметърът е неверен. Върни невярно, ако параметърът е верен.",
                +	"LOGIC_BOOLEAN_TRUE": "вярно",
                +	"LOGIC_BOOLEAN_FALSE": "невярно",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Връща вярно или невярно.",
                +	"LOGIC_NULL": "нула",
                +	"LOGIC_NULL_TOOLTIP": "Връща нула.",
                +	"LOGIC_TERNARY_CONDITION": "тест",
                +	"LOGIC_TERNARY_IF_TRUE": "Ако е вярно",
                +	"LOGIC_TERNARY_IF_FALSE": "Ако е невярно",
                +	"LOGIC_TERNARY_TOOLTIP": "Провери условието в „тест“. Ако условието е истина, върни стойността „ако е вярно“, иначе върни стойността „ако е невярно“.",
                +	"MATH_NUMBER_HELPURL": "https://bg.wikipedia.org/wiki/Число",
                +	"MATH_NUMBER_TOOLTIP": "Число.",
                +	"MATH_ARITHMETIC_HELPURL": "https://bg.wikipedia.org/wiki/Аритметика",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Върни сумата на двете числа.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Върни разликата на двете числа.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Върни произведението на двете числа.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Върни частното на двете числа.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Върни първото число, повдигнато на степен на второто число.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "корен квадратен",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Връща корен квадратен от число.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "абсолютна",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Връща абсолютната стойност на число.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Върни числото с обърнат знак.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Върни натуралния логаритъм от число.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Върни десетичния логаритъм на число.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Върни е (неперовото число) на степен зададеното число.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Върни 10 на степен зададеното число.",
                +	"MATH_TRIG_HELPURL": "https://bg.wikipedia.org/wiki/Тригонометрична_функция",
                +	"MATH_TRIG_TOOLTIP_SIN": "Върни синус от ъгъл в градуси (не в радиани)",
                +	"MATH_TRIG_TOOLTIP_COS": "Върни косинус от ъгъл в градуси (не в радиани)",
                +	"MATH_TRIG_TOOLTIP_TAN": "Върни тангенс от ъгъл в градуси (не в радиани)",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Върни аркуссинус от число.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Върни аркускосинус от число.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Върни аркустангенс от число.",
                +	"MATH_CONSTANT_HELPURL": "http://bg.wikipedia.org/wiki/Константа",
                +	"MATH_CONSTANT_TOOLTIP": "Връща една от често срещаните константи: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) или ∞ (безкрайност).",
                +	"MATH_IS_EVEN": "е четно",
                +	"MATH_IS_ODD": "е нечетно",
                +	"MATH_IS_PRIME": "е просто",
                +	"MATH_IS_WHOLE": "е цяло",
                +	"MATH_IS_POSITIVE": "е положително",
                +	"MATH_IS_NEGATIVE": "е отрицателно",
                +	"MATH_IS_DIVISIBLE_BY": "се дели на",
                +	"MATH_IS_TOOLTIP": "Проверете дали дадено число е четно, нечетно, просто, цяло, положително, отрицателно или дали се дели на друго число. Връща вярно или невярно.",
                +	"MATH_CHANGE_HELPURL": "https://bg.wikipedia.org/wiki/Събиране",
                +	"MATH_CHANGE_TITLE": "промени %1 на %2",
                +	"MATH_CHANGE_TOOLTIP": "Добави число към променлива '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Закръгли число нагоре или надолу.",
                +	"MATH_ROUND_OPERATOR_ROUND": "закръгли",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "закръгли нагоре",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "закръгли надолу",
                +	"MATH_ONLIST_OPERATOR_SUM": "сума на списъка",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Върни сумата на всички числа в списъка.",
                +	"MATH_ONLIST_OPERATOR_MIN": "най-малката стойност в списъка",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Върни най-малкото число в списъка.",
                +	"MATH_ONLIST_OPERATOR_MAX": "най-голямата стойност в списъка",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Върни най-голямото число в списъка.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "средната стойност на числата в списъка",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Върни средната стойност (аритметичното средно) на числата в списъка.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "медианата на списък",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Върни медианата в списъка.",
                +	"MATH_ONLIST_OPERATOR_MODE": "режими на списъка",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Върни списък на най-често срещаните елементи в списъка.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "стандартно отклонение на списък",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Връща стандартното отклонение на списъка.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "случаен елемент от списъка",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Върни случаен елемент от списъка.",
                +	"MATH_MODULO_HELPURL": "http://bg.wikipedia.org/wiki/Остатък",
                +	"MATH_MODULO_TITLE": "остатъка от делението на %1 на %2",
                +	"MATH_MODULO_TOOLTIP": "Върни остатъка от деление на две числа.",
                +	"MATH_CONSTRAIN_TITLE": "ограничи %1 между %2 и %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Ограничи число да бъде в определените граници (включително).",
                +	"MATH_RANDOM_INT_HELPURL": "https://bg.wikipedia.org/wiki/Генератор_на_случайни_числа",
                +	"MATH_RANDOM_INT_TITLE": "случайно цяло число между %1 и %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Върни случайно число в определените граници (включително).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://bg.wikipedia.org/wiki/Генератор_на_случайни_числа",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "случайно дробно число",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Върни случайно дробно число между 0.0 (включително) и 1.0 (без да го включва)",
                +	"TEXT_TEXT_HELPURL": "https://bg.wikipedia.org/wiki/Низ",
                +	"TEXT_TEXT_TOOLTIP": "Буква, дума или ред",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "създай текст с",
                +	"TEXT_JOIN_TOOLTIP": "Създай текст като съчетаеш няколко елемента.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "свържи",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Добави, премахни или пренареди частите, за да промениш този текстов блок.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Добави елемент към текста.",
                +	"TEXT_APPEND_TITLE": "добавете текст %2 към %1",
                +	"TEXT_APPEND_TOOLTIP": "Добави текст към променливата „%1“.",
                +	"TEXT_LENGTH_TITLE": "дължината на %1",
                +	"TEXT_LENGTH_TOOLTIP": "Връща броя на символите (включително и интервалите) в текста.",
                +	"TEXT_ISEMPTY_TITLE": "%1 е празен",
                +	"TEXT_ISEMPTY_TOOLTIP": "Връща вярно, ако текста е празен.",
                +	"TEXT_INDEXOF_TOOLTIP": "Връща индекса на първото/последното срещане на първия текст във втория текст. Връща %1, ако текстът не е намерен.",
                +	"TEXT_INDEXOF_TITLE": "в текст %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "намери първата поява на текста",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "намери последната поява на текста",
                +	"TEXT_CHARAT_TITLE": "в текст %1 %2",
                +	"TEXT_CHARAT_FROM_START": "вземи буква №",
                +	"TEXT_CHARAT_FROM_END": "вземи буква № от края",
                +	"TEXT_CHARAT_FIRST": "вземи първата буква",
                +	"TEXT_CHARAT_LAST": "вземи последната буква",
                +	"TEXT_CHARAT_RANDOM": "вземи произволна буква",
                +	"TEXT_CHARAT_TOOLTIP": "Връща буквата в определена позиция.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Връща определена част от текста.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "в текста",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "вземи текста от буква №",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "вземи текста от буква № (броено отзад-напред)",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "вземи текста от първата буква",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "до буква №",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "до буква № от края",
                +	"TEXT_GET_SUBSTRING_END_LAST": "до последната буква.",
                +	"TEXT_CHANGECASE_TOOLTIP": "Връща копие на текста със сменени малки и главни букви.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "с ГЛАВНИ БУКВИ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "с малки букви",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "с Главна Буква На Всяка Дума",
                +	"TEXT_TRIM_TOOLTIP": "Връща копие на текста с премахнати интервали от единия или двата края.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "премахни интервалите от двете страни",
                +	"TEXT_TRIM_OPERATOR_LEFT": "премахни интервалите отляво",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "премахни интервалите отдясно",
                +	"TEXT_PRINT_TITLE": "отпечатай %1",
                +	"TEXT_PRINT_TOOLTIP": "Отпечатай текста, числото или друга стойност.",
                +	"TEXT_PROMPT_TYPE_TEXT": "питай за текст със съобщение",
                +	"TEXT_PROMPT_TYPE_NUMBER": "питай за число със съобщение",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Питай потребителя за число.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Питай потребителя за текст.",
                +	"TEXT_COUNT_MESSAGE0": "пресмята броя на %1 в %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Преброй колко пъти даден текст се среща в друг текст.",
                +	"TEXT_REPLACE_MESSAGE0": "замяна на %1 с %2 в %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Замени всички появи на даден текст в друг текст.",
                +	"TEXT_REVERSE_MESSAGE0": "промени реда на обратно %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Промени реда на знаците в текста на обратно.",
                +	"LISTS_CREATE_EMPTY_TITLE": "създай празен списък",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Връща списък с дължина 0, не съдържащ данни",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Създай списък с произволен брой елементи.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "създай списък с",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "списък",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Добави, премахни или пренареди частите, за да промениш този списъчен блок.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Добави елемент към текста.",
                +	"LISTS_REPEAT_TOOLTIP": "Създава списък, състоящ се от определен брой копия на елемента.",
                +	"LISTS_REPEAT_TITLE": "създай списък от %1 повторен %2 пъти",
                +	"LISTS_LENGTH_TITLE": "дължината на %1",
                +	"LISTS_LENGTH_TOOLTIP": "Връща дължината на списък.",
                +	"LISTS_ISEMPTY_TITLE": "%1 е празен",
                +	"LISTS_ISEMPTY_TOOLTIP": "Връща стойност вярно, ако списъкът е празен.",
                +	"LISTS_INLIST": "в списъка",
                +	"LISTS_INDEX_OF_FIRST": "намери първата поява на елемента",
                +	"LISTS_INDEX_OF_LAST": "намери последната поява на елемента",
                +	"LISTS_INDEX_OF_TOOLTIP": "Връща индекса на първото/последното появяване на елемента в списъка. Връща %1, ако елементът не е намерен.",
                +	"LISTS_GET_INDEX_GET": "вземи",
                +	"LISTS_GET_INDEX_GET_REMOVE": "вземи и премахни",
                +	"LISTS_GET_INDEX_REMOVE": "премахни",
                +	"LISTS_GET_INDEX_FROM_END": "№ от края",
                +	"LISTS_GET_INDEX_FIRST": "първия",
                +	"LISTS_GET_INDEX_LAST": "последния",
                +	"LISTS_GET_INDEX_RANDOM": "произволен",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 е първият елемент.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 е последният елемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Връща елемента на определената позиция в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Връща първия елемент в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Връща последния елемент в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Връща случаен елемент от списъка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Премахва и връща елемента на определена позиция в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Премахва и връща първия елемент в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Премахва и връща последния елемент в списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Премахва и връща случаен елемент от списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Премахва елемент на определена позиция от списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Премахва първия елемент от списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Премахва последния елемент от списък.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Премахва случаен елемент от списък.",
                +	"LISTS_SET_INDEX_SET": "промени",
                +	"LISTS_SET_INDEX_INSERT": "вмъкни на позиция",
                +	"LISTS_SET_INDEX_INPUT_TO": "следното",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Променя елемента на определена позиция в списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Променя първия елемент в списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Променя последния елемент в списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Променя случаен елемент от списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Вмъква елемент на определена позиция в списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Вмъква елемент в началото на списъка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Добави елемент в края на списък.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Вмъква елемент на произволно място в списък.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "вземи подсписък от №",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "вземи подсписък от № от края",
                +	"LISTS_GET_SUBLIST_START_FIRST": "вземи подсписък от първия",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "до №",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "до № открая",
                +	"LISTS_GET_SUBLIST_END_LAST": "до края",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Копира част от списък.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "сортиране по %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Подреди копие на списъка.",
                +	"LISTS_SORT_ORDER_ASCENDING": "възходящо",
                +	"LISTS_SORT_ORDER_DESCENDING": "низходящо",
                +	"LISTS_SORT_TYPE_NUMERIC": "в числов ред",
                +	"LISTS_SORT_TYPE_TEXT": "по азбучен ред",
                +	"LISTS_SORT_TYPE_IGNORECASE": "по азбучен ред, без отчитане на малки и главни букви",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "Направи списък от текст",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "направи текст от списък",
                +	"LISTS_SPLIT_WITH_DELIMITER": "с разделител",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Разделя текст в списък на текстове, по всеки разделител.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Събира списък от текстове в един текст, раделени с разделител.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "промени реда на обратно %1",
                +	"LISTS_REVERSE_TOOLTIP": "Промени реда на списъка на обратно.",
                +	"VARIABLES_GET_TOOLTIP": "Връща стойността на тази променлива.",
                +	"VARIABLES_GET_CREATE_SET": "Създай „промени стойността на %1“",
                +	"VARIABLES_SET": "нека %1 бъде %2",
                +	"VARIABLES_SET_TOOLTIP": "Установява променливата със стойността на входа.",
                +	"VARIABLES_SET_CREATE_GET": "Създай „вземи стойността на %1“",
                +	"PROCEDURES_DEFNORETURN_TITLE": "за да",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "направиш",
                +	"PROCEDURES_BEFORE_PARAMS": "с:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "с:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Създава функция, която не връща резултат.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Опишете тази функция...",
                +	"PROCEDURES_DEFRETURN_RETURN": "върни",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Създава функция, която връща резултат.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "позволи операциите",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Предупреждение: Тази функция има дублиращи се параметри.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://bg.wikipedia.org/wiki/Подпрограма",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Изпълни дефинирана от потребителя функция „%1“.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://bg.wikipedia.org/wiki/Подпрограма",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Изпълни дефинирана от потребителя функция „%1“ и използвай резултата.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "вход",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Добави, премахни или пренареди входните параметри за тази функция.",
                +	"PROCEDURES_MUTATORARG_TITLE": "име на параметър:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Добавяне на параметър към функцията.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Покажи дефиницията на функцията",
                +	"PROCEDURES_CREATE_DO": "Създай '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ако стойността е вярна, върни втората стойност.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Предупреждение: Този блок може да се използва само във функция."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/bn.json b/blockly/webif/static/blockly/msg/json/bn.json
                new file mode 100644
                index 000000000..aa6ea45c5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/bn.json
                @@ -0,0 +1,163 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Aftabuzzaman",
                +			"Rakibul",
                +			"Tauhid16",
                +			"MasterMinhaz",
                +			"এম আবু সাঈদ"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "পদ",
                +	"TODAY": "আজ",
                +	"DUPLICATE_BLOCK": "প্রতিলিপি",
                +	"ADD_COMMENT": "মন্তব্য যোগ করুন",
                +	"REMOVE_COMMENT": "মন্তব্য সরাও",
                +	"EXTERNAL_INPUTS": "বহি:স্থ ইনপুট",
                +	"INLINE_INPUTS": "সারি ইনপুট",
                +	"DELETE_BLOCK": "ব্লকটি মুছে ফেল",
                +	"DELETE_X_BLOCKS": "%1 ব্লক অপসারণ কর",
                +	"EXPAND_BLOCK": "ব্লকটি সম্প্রসারিত কর",
                +	"EXPAND_ALL": "ব্লকগুলো সম্প্রসারিত কর",
                +	"DISABLE_BLOCK": "ব্লকটি বিকল কর",
                +	"ENABLE_BLOCK": "ব্লকটি সচল কর",
                +	"HELP": "সাহায্য",
                +	"UNDO": "পূর্বাবস্থা",
                +	"REDO": "পুনরায় করুন",
                +	"CHANGE_VALUE_TITLE": "মান পরিবর্তন করুন:",
                +	"RENAME_VARIABLE": "চলকের নাম পরিবর্তন...",
                +	"NEW_VARIABLE": "চলক তৈরি করুন...",
                +	"NEW_VARIABLE_TITLE": "নতুন চলকের নাম:",
                +	"COLOUR_PICKER_TOOLTIP": "প্যালেট থেকে একটি রং পছন্দ করুন",
                +	"COLOUR_RANDOM_TITLE": "এলোমেলো রং",
                +	"COLOUR_RANDOM_TOOLTIP": "এলোমেলোভাবে একটি রং পছন্দ করুন।",
                +	"COLOUR_RGB_TITLE": "রং সহ",
                +	"COLOUR_RGB_RED": "লাল",
                +	"COLOUR_RGB_GREEN": "সবুজ",
                +	"COLOUR_RGB_BLUE": "নীল",
                +	"COLOUR_RGB_TOOLTIP": "একটি রং তৈরি করুন নির্দিষ্ট পরিমাণে লাল, সবুজ এবং নীল রং মিশ্রিত করে। প্রত্যেকটির মান অবশ্যই ০ থেকে ১০০ এর মধ্যে হতে হবে।",
                +	"COLOUR_BLEND_TITLE": "মিশ্রণ",
                +	"COLOUR_BLEND_COLOUR1": "রং ১",
                +	"COLOUR_BLEND_COLOUR2": "রং ২",
                +	"COLOUR_BLEND_RATIO": "অনুপাত",
                +	"COLOUR_BLEND_TOOLTIP": "প্রদত্ত অনুপাত(০.০ - ১.০) অনুসারে দুটি রং একসাথে মিশ্রিত করুন।",
                +	"CONTROLS_REPEAT_TITLE": "%1 বার পুনরাবৃত্তি করো",
                +	"CONTROLS_REPEAT_INPUT_DO": "করুন",
                +	"CONTROLS_FOR_TITLE": "গণনা কর %1 %4 দিয়ে %2 থেকে %3",
                +	"CONTROLS_FOREACH_TITLE": "প্রত্যেকটি পদের জন্য %1 তালিকার মধ্যে %2",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "সর্তকীবার্তা: এই ব্লকটি শুধুমাত্র লুপের মধ্যে ব্যবহার করা যাবে।",
                +	"CONTROLS_IF_MSG_IF": "যদি",
                +	"CONTROLS_IF_MSG_ELSEIF": "নতুবা যদি",
                +	"CONTROLS_IF_MSG_ELSE": "নতুবা",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "যদি নামক ব্লক এ একটি শর্ত যোগ করুন।",
                +	"IOS_OK": "ঠিক আছে",
                +	"IOS_CANCEL": "বাতিল",
                +	"IOS_ERROR": "ত্রুটি",
                +	"IOS_VARIABLES_ADD_BUTTON": "যোগ",
                +	"IOS_VARIABLES_DELETE_BUTTON": "অপসারণ",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "পাঠাবে সত্য যদি উভয় ইনপুটই সমান হয়।",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "পাঠাবে সত্য যদি উভয় ইনপুটই সমান না হয়।",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে ছোট হয়।",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে ছোট অথবা সমান হয়।",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে বড় হয়।",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "পাঠাবে সত্য যদি প্রথম ইনপুট দ্বিতীয় ইনপুট থেকে বড় অথবা সমান হয়।",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "পাঠাবে সত্য যদি উভয় ইনপুটই সত্য হয়।",
                +	"LOGIC_OPERATION_AND": "এবং",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "পাঠাবে সত্য যদি অন্ততপক্ষে যেকোন একটি ইনপুট সত্য হয়।",
                +	"LOGIC_OPERATION_OR": "অথবা",
                +	"LOGIC_NEGATE_TITLE": "%1 নয়",
                +	"LOGIC_NEGATE_TOOLTIP": "পাঠাবে সত্য যদি ইনপুট মিথ্যা হয়। পাঠাবে মিথ্যা যদি ইনপুট সত্য হয়।",
                +	"LOGIC_BOOLEAN_TRUE": "সত্য",
                +	"LOGIC_BOOLEAN_FALSE": "মিথ্যা",
                +	"LOGIC_BOOLEAN_TOOLTIP": "পাঠাবে হয় সত্য অথবা মিথ্যা।",
                +	"LOGIC_NULL": "কিছু না",
                +	"LOGIC_NULL_TOOLTIP": "কিছু ফেরত দিবে না।",
                +	"LOGIC_TERNARY_CONDITION": "পরীক্ষা",
                +	"LOGIC_TERNARY_IF_TRUE": "যদি সত্য হয়",
                +	"LOGIC_TERNARY_IF_FALSE": "যদি মিথ্যা হয়",
                +	"MATH_NUMBER_HELPURL": "https://bn.wikipedia.org/wiki/সংখ্যা",
                +	"MATH_NUMBER_TOOLTIP": "একটি সংখ্যা।",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "পাঠাবে দুটি সংখ্যার যোগফল।",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "পাঠাবে দুটি সংখ্যার বিয়োগফল।",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "পাঠাবে দুটি সংখ্যার গুণফল।",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "পাঠাবে দুটি সংখ্যার ভাগফল।",
                +	"MATH_SINGLE_OP_ROOT": "বর্গমূল",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "পাঠাবে একটি সংখ্যার বর্গমূল।",
                +	"MATH_SINGLE_OP_ABSOLUTE": "পরম",
                +	"MATH_SINGLE_TOOLTIP_ABS": "পাঠাবে সংখ্যার পরমমান।",
                +	"MATH_IS_EVEN": "জোড় সংখ্যা",
                +	"MATH_IS_ODD": "বিজোড় সংখ্যা",
                +	"MATH_IS_PRIME": "মৌলিক সংখ্যা",
                +	"MATH_IS_POSITIVE": "ইতিবাচক",
                +	"MATH_IS_NEGATIVE": "নেতিবাচক",
                +	"MATH_IS_DIVISIBLE_BY": "দ্বারা বিভাজ্য",
                +	"MATH_CHANGE_TITLE": "%2 দ্বারা %1 পরিবর্তন",
                +	"MATH_ONLIST_OPERATOR_SUM": "তালিকার যোগফল",
                +	"MATH_ONLIST_TOOLTIP_SUM": "পাঠাবে তালিকার সব সংখ্যার যোগফল।",
                +	"MATH_ONLIST_OPERATOR_MIN": "তালিকার মধ্যে সর্বনিম্ন",
                +	"MATH_ONLIST_TOOLTIP_MIN": "তালিকার মধ্যে সর্বনিম্ন সংখ্যাটি পাঠাও",
                +	"MATH_ONLIST_OPERATOR_MAX": "তালিকার মধ্যে সর্বোচ্চ",
                +	"MATH_ONLIST_TOOLTIP_MAX": "তালিকার মধ্যে সর্বোচ্চ সংখ্যাটি পাঠাও",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "তালিকার গড়",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "পাঠাবে তালিকার সব সংখ্যার গড়।",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "তালিকার মধ্যমা",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "তালিকার মধ্যমা সংখ্যাটি পাঠাবে।",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "তালিকার এলোমেলো পদ",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "তালিকা থেকে এলোমেলোভাবে একটি পদ পাঠাবে।",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 এর ভাগশেষ",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "এলোমেলো ভগ্নাংশ",
                +	"TEXT_TEXT_TOOLTIP": "একটি অক্ষর, শব্দ অথবা বাক্য।",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "যোগ",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "লেখাটিতে একটি পদ যোগ করুন।",
                +	"TEXT_LENGTH_TITLE": "%1-এর দৈর্ঘ্য",
                +	"TEXT_ISEMPTY_TITLE": "%1 খালি",
                +	"TEXT_ISEMPTY_TOOLTIP": "পাঠাবে সত্য যদি সরবরাহকৃত লেখাটি খালি হয়।",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "বড়হাতের অক্ষরে",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "ছোটহাতের অক্ষরে",
                +	"TEXT_TRIM_OPERATOR_BOTH": "উভয় পাশ থেকে খালি অংশ ছাটাই",
                +	"TEXT_TRIM_OPERATOR_LEFT": "বামপাশ থেকে খালি অংশ ছাটাই",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "ডানপাশ থেকে খালি অংশ ছাটাই",
                +	"TEXT_PRINT_TITLE": "%1 মুদ্রণ করুন",
                +	"TEXT_REVERSE_MESSAGE0": "%1 উল্টান",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"LISTS_CREATE_EMPTY_TITLE": "খালি তালিকা তৈরি করুন",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "পাঠাবে একটি তালিকা, দের্ঘ্য হবে ০, কোন উপাত্ত থাকবে না",
                +	"LISTS_CREATE_WITH_TOOLTIP": "যেকোন সংখ্যক পদ নিয়ে একটি তালিকা তৈরি করুন।",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "তালিকা",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "তালিকায় একটি পদ যোগ করুন।",
                +	"LISTS_LENGTH_TITLE": "%1-এর দৈর্ঘ্য",
                +	"LISTS_LENGTH_TOOLTIP": "একটি তালিকার দৈর্ঘ্য পাঠাবে।",
                +	"LISTS_ISEMPTY_TITLE": "%1 খালি",
                +	"LISTS_ISEMPTY_TOOLTIP": "পাঠাবে সত্য যদি তালিকাটি খালি হয়।",
                +	"LISTS_INLIST": "তালিকার মধ্যে",
                +	"LISTS_INDEX_OF_FIRST": "আইটেমের প্রথম সংঘটন খুঁজুন",
                +	"LISTS_INDEX_OF_LAST": "আইটেমের শেষ সংঘটন খুঁজুন",
                +	"LISTS_GET_INDEX_GET": "নিন",
                +	"LISTS_GET_INDEX_GET_REMOVE": "নিন ও সরান",
                +	"LISTS_GET_INDEX_REMOVE": "অপসারণ",
                +	"LISTS_GET_INDEX_FROM_END": "# শেষ থেকে",
                +	"LISTS_GET_INDEX_FIRST": "প্রথম",
                +	"LISTS_GET_INDEX_LAST": "শেষ",
                +	"LISTS_GET_INDEX_RANDOM": "এলোমেলো",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "তালিকার প্রথম পদটি পাঠাবে।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "তালিকার শেষ পদটি পাঠাবে।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "এলোমেলোভাবে তালিকার যেকোন একটি পদ পাঠাবে।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "অপসারণ করুন এবং তালিকার প্রথম পদটি পাঠান।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "অপসারণ করুন এবং তালিকার শেষ পদটি পাঠান।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "অপসারণ করুন এবং তালিকার এলোমেলো একটি পদ পাঠান।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "তালিকার প্রথম পদটি অপসারণ করা হয়েছে।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "তালিকার শেষ পদটি অপসারণ করা হয়েছে।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "তালিকা থেকে এলোমেলো একটি পদ অপসারণ করা হয়েছে।",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "লিখা থেকে তালিকা তৈরি করুন",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "তালিকা থেকে লিখা তৈরি করুন",
                +	"LISTS_REVERSE_TOOLTIP": "একটি তালিকার একটি অনুলিপি উল্টান",
                +	"VARIABLES_SET_CREATE_GET": "'%1 নিন' তৈরি করুন",
                +	"PROCEDURES_DEFNORETURN_TITLE": "এতে",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "আউটপুট ছাড়া একটি ক্রিয়া তৈরি করুন।",
                +	"PROCEDURES_DEFRETURN_RETURN": "পাঠাবে",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "আউটপুট সহ একটি ক্রিয়া তৈরি করুন।",
                +	"PROCEDURES_MUTATORARG_TITLE": "ইনপুটের নাম:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "ক্রিয়াতে একটি ইনপুট যোগ করুন।",
                +	"PROCEDURES_HIGHLIGHT_DEF": "ক্রিয়ার সংজ্ঞা উজ্জল করুন",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "যদি মান সত্য হয় তাহলে দ্বিতীয় মান পাঠাবে।"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/br.json b/blockly/webif/static/blockly/msg/json/br.json
                new file mode 100644
                index 000000000..85312c599
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/br.json
                @@ -0,0 +1,343 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Fohanno",
                +			"Y-M D",
                +			"Gwenn-Ael",
                +			"Fulup"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "elfenn",
                +	"TODAY": "Hiziv",
                +	"DUPLICATE_BLOCK": "Eiladuriñ",
                +	"ADD_COMMENT": "Ouzhpennañ un evezhiadenn",
                +	"REMOVE_COMMENT": "Lemel an evezhiadenn kuit",
                +	"EXTERNAL_INPUTS": "Monedoù diavaez",
                +	"INLINE_INPUTS": "Monedoù enlinenn",
                +	"DELETE_BLOCK": "Dilemel ar bloc'h",
                +	"DELETE_X_BLOCKS": "Dilemel %1 bloc'h",
                +	"DELETE_ALL_BLOCKS": "Diverkañ an holl vloc'hoù %1 ?",
                +	"CLEAN_UP": "Naetaat ar bloc'hoù",
                +	"COLLAPSE_BLOCK": "Bihanaat ar bloc'h",
                +	"COLLAPSE_ALL": "Bihanaat ar bloc'hoù",
                +	"EXPAND_BLOCK": "Astenn ar bloc'h",
                +	"EXPAND_ALL": "Astenn ar bloc'hoù",
                +	"DISABLE_BLOCK": "Diweredekaat ar bloc'h",
                +	"ENABLE_BLOCK": "Gweredekaat ar bloc'h",
                +	"HELP": "Skoazell",
                +	"UNDO": "Dizober",
                +	"REDO": "Adober",
                +	"CHANGE_VALUE_TITLE": "Kemmañ an dalvoudenn :",
                +	"RENAME_VARIABLE": "Adenvel an argemmenn...",
                +	"RENAME_VARIABLE_TITLE": "Adenvel an holl argemmennoù '%1' e :",
                +	"NEW_VARIABLE": "Krouiñ un argemm nevez...",
                +	"NEW_VARIABLE_TITLE": "Anv an argemmenn nevez :",
                +	"VARIABLE_ALREADY_EXISTS": "Un argemm anvet '%1' zo anezhañ dija.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Un argemenn anvet '%1' zo c'hoazh evit un argemenn all eus ar seurt '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Un argerzhadur anvet '%1' zo anezhañ dija.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Lemel %1 implij eus an argemm '%2' ?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Ne ch'aller ket dilemel an argemm \"%1\" dre m'eo lod eus dielfennadur an arc'hwel \"%2\"",
                +	"DELETE_VARIABLE": "Lemel an argemm '%1'",
                +	"COLOUR_PICKER_HELPURL": "http://br.wikipedia.org/wiki/Liv",
                +	"COLOUR_PICKER_TOOLTIP": "Dibab ul liv diwar al livaoueg.",
                +	"COLOUR_RANDOM_TITLE": "liv dargouezhek",
                +	"COLOUR_RANDOM_TOOLTIP": "Tennañ ul liv d'ar sord",
                +	"COLOUR_RGB_TITLE": "liv gant",
                +	"COLOUR_RGB_RED": "ruz",
                +	"COLOUR_RGB_GREEN": "gwer",
                +	"COLOUR_RGB_BLUE": "glas",
                +	"COLOUR_RGB_TOOLTIP": "Krouiñ ul liv gant ar c'hementad spisaet a ruz, a wer hag a c'hlas. Etre 0 ha 100 e tle bezañ an holl dalvoudoù.",
                +	"COLOUR_BLEND_TITLE": "meskañ",
                +	"COLOUR_BLEND_COLOUR1": "liv 1",
                +	"COLOUR_BLEND_COLOUR2": "liv 2",
                +	"COLOUR_BLEND_RATIO": "feur",
                +	"COLOUR_BLEND_TOOLTIP": "a gemmesk daou liv gant ur feur roet(0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "adober %1 gwech",
                +	"CONTROLS_REPEAT_INPUT_DO": "ober",
                +	"CONTROLS_REPEAT_TOOLTIP": "Seveniñ urzhioù zo meur a wech",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "adober keit ha ma",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "adober betek",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Keit ha ma vez gwir un dalvoudenn, seveniñ urzhioù zo neuze.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Keit ha ma vez faos un dalvoudenn,seveniñ urzhioù zo neuze.",
                +	"CONTROLS_FOR_TOOLTIP": "Ober e doare ma kemero an argemmenn \"%1\" an talvoudennoù adalek niverenn an deroù betek niverenn an dibenn, en ur inkremantiñ an esaouenn, ha seveniñ an urzhioù spisaet.",
                +	"CONTROLS_FOR_TITLE": "kontañ gant %1 eus %2 da %3 dre %4",
                +	"CONTROLS_FOREACH_TITLE": "evit pep elfenn %1 er roll %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Evit pep elfenn en ur roll, reiñ talvoud an elfenn d'an argemmenn '%1', ha seveniñ urzhioù zo da c'houde.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "Mont e-maez an adlañsañ",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "Kenderc'hel gant iteradur nevez ar rodell",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Mont e-maez ar boukl engronnus.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Lammat ar rest eus ar rodell, ha kenderc'hel gant an iteradur war-lerc'h.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Diwallit : ne c'hall ar bloc'h-mañ bezañ implijet nemet e-barzh ur boukl.",
                +	"CONTROLS_IF_TOOLTIP_1": "Ma vez gwir un dalvoudenn, seveniñ urzhioù zo neuze.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ma vez gwir un dalvoudenn, seveniñ ar c'henañ bloc'had urzhioù neuze. Anez seveniñ an eil bloc'had urzhioù.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ma vez gwir an dalvoudenn gentañ, seveniñ ar c'hentañ bloc'had urzhioù neuze. Anez ma vez gwir an eil talvoudenn, seveniñ an eil bloc'had urzhioù.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ma vez gwir an dalvoudenn gentañ, seveniñ ar c'hentañ bloc'had. Anez, ma vez gwir an eil talvoudenn, seveniñ an eil bloc'had urzhioù. Ma ne vez gwir talvoudenn ebet, seveniñ ar bloc'had diwezhañ a urzhioù.",
                +	"CONTROLS_IF_MSG_IF": "ma",
                +	"CONTROLS_IF_MSG_ELSEIF": "mod all ma",
                +	"CONTROLS_IF_MSG_ELSE": "a-hend-all",
                +	"CONTROLS_IF_IF_TOOLTIP": "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h ma.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Ouzhpennañ un amplegad d'ar bloc'h ma.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Ouzhpennañ un amplegad dibenn lak-pep-tra d'ar bloc'h ma.",
                +	"IOS_OK": "Mat eo",
                +	"IOS_CANCEL": "Nullañ",
                +	"IOS_ERROR": "Fazi",
                +	"IOS_PROCEDURES_INPUTS": "MONEDOÙ",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Ouzhpennañ ur moned",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Urzhioù aotreet",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "An arc'hwel-mañ en eus monedoù eiladet.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Ouzhpennañ un argemm",
                +	"IOS_VARIABLES_ADD_BUTTON": "Ouzhpennañ",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Adenvel",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Diverkañ",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Anv an argemenn",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Ne c'hallit ket implijout un anv argemm goullo.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Distreiñ gwir m'eo par an daou voned.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Distreiñ gwir ma n'eo ket par an daou voned.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Distreiñ gwir m'eo bihanoc'h ar moned kentañ eget an eil.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Distreiñ gwir m'eo bihanoc'h ar moned kentañ eget an eil pe m'eo par dezhañ.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Distreiñ gwir m'eo brasoc'h ar moned kentañ eget an eil.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Distreiñ gwir m'eo brasoc'h ar moned kentañ eget an eil pe par dezhañ.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Distreiñ gwir m'eo gwir an da daou voned.",
                +	"LOGIC_OPERATION_AND": "ha(g)",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Distreiñ gwir m'eo gwir unan eus an daou voned da nebeutañ.",
                +	"LOGIC_OPERATION_OR": "pe",
                +	"LOGIC_NEGATE_TITLE": "nann %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Distreiñ gwir m'eo faos ar moned. Distreiñ faos m'eo gwir ar moned.",
                +	"LOGIC_BOOLEAN_TRUE": "gwir",
                +	"LOGIC_BOOLEAN_FALSE": "gaou",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Distreiñ pe gwir pe faos",
                +	"LOGIC_NULL": "Null",
                +	"LOGIC_NULL_TOOLTIP": "Distreiñ null.",
                +	"LOGIC_TERNARY_CONDITION": "amprouad",
                +	"LOGIC_TERNARY_IF_TRUE": "m'eo gwir",
                +	"LOGIC_TERNARY_IF_FALSE": "m'eo gaou",
                +	"LOGIC_TERNARY_TOOLTIP": "Gwiriañ an amplegad e 'prouad'. M'eo gwir an amplegad, distreiñ an dalvoudenn 'm'eo gwir'; anez distreiñ ar moned 'm'eo faos'.",
                +	"MATH_NUMBER_HELPURL": "https://br.wikipedia.org/wiki/Niver",
                +	"MATH_NUMBER_TOOLTIP": "Un niver.",
                +	"MATH_ARITHMETIC_HELPURL": "https://br.wikipedia.org/wiki/Aritmetik",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Distreiñ sammad daou niver.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Distreiñ diforc'h daou niver",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Distreiñ liesad daou niver.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Distreiñ rannad daou niver.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Distreiñ an niver kentañ lakaet dindan gallouter an eil niver.",
                +	"MATH_SINGLE_HELPURL": "https://br.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "gwrizienn garrez",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Distreiñ gwrizienn garrez un niver",
                +	"MATH_SINGLE_OP_ABSOLUTE": "dizave",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Distreiñ talvoud dizave un niver.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Distreiñ enebad un niver",
                +	"MATH_SINGLE_TOOLTIP_LN": "Distreiñ logaritm naturel un niver",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Distreiñ logaritm diazez 10 un niver",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Distreiñ galloudad un niver.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Distreiñ 10 da c'halloudad un niver.",
                +	"MATH_TRIG_HELPURL": "https://br.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Distreiñ sinuz ur c'horn (ket e radianoù)",
                +	"MATH_TRIG_TOOLTIP_COS": "Distreiñ kosinuz ur c'horn (ket e radianoù)",
                +	"MATH_TRIG_TOOLTIP_TAN": "Distreiñ tangent ur c'horn (ket e radianoù).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Distreiñ ark sinuz un niver",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Distreiñ ark kosinuz un niver",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Distreiñ ark tangent un niver",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Distreiñ unan eus  digemmennoù red : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (anvevenn).",
                +	"MATH_IS_EVEN": "zo par",
                +	"MATH_IS_ODD": "zo ampar",
                +	"MATH_IS_PRIME": "zo kentañ",
                +	"MATH_IS_WHOLE": "zo anterin",
                +	"MATH_IS_POSITIVE": "a zo pozitivel",
                +	"MATH_IS_NEGATIVE": "a zo negativel",
                +	"MATH_IS_DIVISIBLE_BY": "a zo rannadus dre",
                +	"MATH_IS_TOOLTIP": "Gwiriañ m'eo par, anpar, kentañ, muiel, leiel un niverenn pe ma c'haller rannañ anezhi dre un niver roet zo. Distreiñ gwir pe faos.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "kemmañ %1 gant %2",
                +	"MATH_CHANGE_TOOLTIP": "Ouzhpennañ un niver d'an argemm '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Rontaat un niver dindan pe a-us",
                +	"MATH_ROUND_OPERATOR_ROUND": "Rontaat",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Rontaat a-us",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "Rontaat dindan",
                +	"MATH_ONLIST_OPERATOR_SUM": "Sammad al listenn",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Distreiñ sammad an holl niveroù zo el listenn.",
                +	"MATH_ONLIST_OPERATOR_MIN": "Izegenn al listenn",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Distreiñ an niver bihanañ el listenn",
                +	"MATH_ONLIST_OPERATOR_MAX": "Uc'hegenn al listenn",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Distreiñ an niver brasañ el listenn.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "Keitat al listenn",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Distreiñ keitad (niveroniel) an talvoudennoù niverel el listenn.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Kreizad al listenn",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Distreiñ an niver kreiz el listenn",
                +	"MATH_ONLIST_OPERATOR_MODE": "modoù stankañ el listenn",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Distreiñ ul listennad elfennoù stankoc'h el listenn.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "forc'had standart eus al listenn",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Distreiñ forc'had standart al listenn.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Elfennn eus al listenn tennet d'ar sord",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Distreiñ un elfenn zargouezhek el listenn",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "rest eus %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Distreiñ dilerc'h rannadur an div niver",
                +	"MATH_CONSTRAIN_TITLE": "destrizhañ %1 etre %2 ha %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Destrizhañ un niver da vezañ etre ar bevennoù spisaet (enlakaet)",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "anterin dargouezhek etre %1 ha %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Distreiñ un anterin dargouezhek etre an div vevenn spisaet, endalc'het.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "Rann dargouezhek",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Distreiñ ur rann dargouezhek etre 0.0 (enkaelat) hag 1.0 (ezkaelat).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Ul lizherenn, ur ger pe ul linennad testenn.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "krouiñ un destenn gant",
                +	"TEXT_JOIN_TOOLTIP": "Krouit un tamm testenn en ur gevelstrollañ un niver bennak a elfennoù",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "stagañ",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h testenn-mañ.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Ouzhpennañ un elfenn d'an destenn.",
                +	"TEXT_APPEND_TITLE": "Ouzhpennañ an destenn %2 da %1",
                +	"TEXT_APPEND_TOOLTIP": "Ouzhpennañ testenn d'an argemmenn'%1'.",
                +	"TEXT_LENGTH_TITLE": "hirder %1",
                +	"TEXT_LENGTH_TOOLTIP": "Distreiñ an niver a lizherennoù(en ur gontañ an esaouennoù e-barzh) en destenn roet.",
                +	"TEXT_ISEMPTY_TITLE": "%1 zo goullo",
                +	"TEXT_ISEMPTY_TOOLTIP": "Adkas gwir m'eo goullo an destenn roet.",
                +	"TEXT_INDEXOF_TOOLTIP": "Distreiñ meneger ar c'hentañ/an eil reveziadenn eus ar chadenn gentañ en eil chadenn. Distreiñ %1 ma n'eo ket kavet ar chadenn.",
                +	"TEXT_INDEXOF_TITLE": "en destenn %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "kavout reveziadenn gentañ an destenn",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "kavout reveziadenn diwezhañ an destenn",
                +	"TEXT_CHARAT_TITLE": "en destenn %1 %2",
                +	"TEXT_CHARAT_FROM_START": "Kaout al lizherenn #",
                +	"TEXT_CHARAT_FROM_END": "Kaout al lizherenn # adalek an dibenn.",
                +	"TEXT_CHARAT_FIRST": "tapout al lizherenn gentañ",
                +	"TEXT_CHARAT_LAST": "tapout al lizherenn ziwezhañ",
                +	"TEXT_CHARAT_RANDOM": "Kaout ul lizherenn dre zegouezh",
                +	"TEXT_CHARAT_TOOLTIP": "Distreiñ al lizherenn d'al lec'h spisaet.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Distreiñ un tamm spisaet eus an destenn.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "en destenn",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "Kaout an ischadenn adalek al lizherenn #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "Kaout an ischadenn adalek al lizherenn # betek an dibenn",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "Kaout an ischadenn adalek al lizherenn gentañ",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "betek al lizherenn #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "Betek al lizherenn # adalek an dibenn.",
                +	"TEXT_GET_SUBSTRING_END_LAST": "d'al lizherenn diwezhañ",
                +	"TEXT_CHANGECASE_TOOLTIP": "Distreiñ un eilenn eus an eilenn en un direnneg all",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "e PENNLIZHERENNOÙ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "e lizherennoù bihan",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Gant Ur Bennlizherenn E Deroù Pep Ger",
                +	"TEXT_TRIM_TOOLTIP": "Distreiñ un eilenn eus an destenn gant an esaouennoù lamet eus un tu pe eus an daou du",
                +	"TEXT_TRIM_OPERATOR_BOTH": "Lemel an esaouennoù en daou du",
                +	"TEXT_TRIM_OPERATOR_LEFT": "Lemel an esaouennoù eus an tu kleiz",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "Lemel an esaouennoù eus an tu dehou",
                +	"TEXT_PRINT_TITLE": "moullañ %1",
                +	"TEXT_PRINT_TOOLTIP": "Moullañ an destenn, an niverenn pe un dalvoudenn spisaet all",
                +	"TEXT_PROMPT_TYPE_TEXT": "pedadenn evit un destenn gant ur c'hemennad",
                +	"TEXT_PROMPT_TYPE_NUMBER": "pedadenn evit un niver gant ur c'hemennad",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Goulenn un niver gant an implijer.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Goulenn un destenn gant an implijer.",
                +	"TEXT_COUNT_MESSAGE0": "niver %1 war %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Kontañ pet gwech e c'hoarvez un destenn bennak en un destenn bennak all.",
                +	"TEXT_REPLACE_MESSAGE0": "erlec'hiañ %1 gant %2 e %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Erlec'hiañ holl reveziadennoù un destenn bennak gant un destenn all.",
                +	"TEXT_REVERSE_MESSAGE0": "eilpennañ %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Eilpennañ urzh an arouezennoù en destenn.",
                +	"LISTS_CREATE_EMPTY_TITLE": "krouiñ ur roll goullo",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Distreiñ ul listenn, 0 a hirder, n'eus enrolladenn ebet enni",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Krouiñ ur roll gant un niver bennak a elfennoù.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "krouiñ ur roll gant",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "roll",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h listenn-mañ.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Ouzhpennañ un elfenn d'ar roll",
                +	"LISTS_REPEAT_TOOLTIP": "Krouiñ ul listenn a c'hoarvez eus an dalvoudenn roet arreet an niver a wech meneget",
                +	"LISTS_REPEAT_TITLE": "Krouiñ ul listenn gant an elfenn %1 arreet div wech",
                +	"LISTS_LENGTH_TITLE": "hirder %1",
                +	"LISTS_LENGTH_TOOLTIP": "Distreiñ hirder ul listenn.",
                +	"LISTS_ISEMPTY_TITLE": "%1 zo goullo",
                +	"LISTS_ISEMPTY_TOOLTIP": "Distreiñ gwir m'eo goullo al listenn.",
                +	"LISTS_INLIST": "el listenn",
                +	"LISTS_INDEX_OF_FIRST": "kavout reveziadenn gentañ un elfenn",
                +	"LISTS_INDEX_OF_LAST": "kavout reveziadenn diwezhañ un elfenn",
                +	"LISTS_INDEX_OF_TOOLTIP": "Distreiñ meneger ar c'hentañ/an eil reveziadenn eus an elfenn en ul listenn. Distreiñ %1 ma n'eo ket kavet an destenn.",
                +	"LISTS_GET_INDEX_GET": "tapout",
                +	"LISTS_GET_INDEX_GET_REMOVE": "tapout ha lemel",
                +	"LISTS_GET_INDEX_REMOVE": "lemel",
                +	"LISTS_GET_INDEX_FROM_END": "# adalek ar fin",
                +	"LISTS_GET_INDEX_FIRST": "kentañ",
                +	"LISTS_GET_INDEX_LAST": "diwezhañ",
                +	"LISTS_GET_INDEX_RANDOM": "dre zegouezh",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 eo an elfenn gentañ.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 eo an elfenn gentañ.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Distreiñ an elfenn el lec'h meneget en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Distreiñ an elfenn gentañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Distreiñ un elfenn diwezhañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Distreiñ un elfenn dre zegouezh en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Lemel ha distreiñ a ra an elfenn el lec'h meneget en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Lemel ha distreiñ a ra an elfenn gentañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Lemel ha distreiñ a ra an elfenn diwezhañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Lemel ha distreiñ a ra an elfenn dre zegouezh en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Lemel a ra an elfenn el lec'h meneget en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Lemel a ra an elfenn gentañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Distreiñ a ra an elfenn diwezhañ en ul listenn.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Lemel a ra un elfenn dre zegouezh en ul listenn.",
                +	"LISTS_SET_INDEX_SET": "termenañ",
                +	"LISTS_SET_INDEX_INSERT": "ensoc'hañ evel",
                +	"LISTS_SET_INDEX_INPUT_TO": "evel",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Termenañ a ra an elfenn el lec'h meneget en ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Termenañ a ra an elfenn gentañ en ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Termenañ a ra an elfenn diwezhañ en ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Termenañ a ra un elfenn dre zegouezh en ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Ensoc'hañ a ra an elfenn el lec'h meneget en ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Ensoc'hañ a ra an elfenn e deroù ul listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Ouzhpennañ a ra an elfenn e fin al listenn.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Ensoc'hañ a ra an elfenn dre zegouezh en ul listenn.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "Kaout an islistenn adalek #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "Kaout an islistenn adalek # adalek an dibenn",
                +	"LISTS_GET_SUBLIST_START_FIRST": "Kaout an islistenn adalek an deroù",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "da #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "betek # adalek an dibenn",
                +	"LISTS_GET_SUBLIST_END_LAST": "betek ar fin",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Krouiñ un eilad eus lodenn spisaet ul listenn.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_SORT_TITLE": "Rummañ%1,%2,%3",
                +	"LISTS_SORT_TOOLTIP": "Rummañ un eilenn eus ar roll",
                +	"LISTS_SORT_ORDER_ASCENDING": "war gresk",
                +	"LISTS_SORT_ORDER_DESCENDING": "war zigresk",
                +	"LISTS_SORT_TYPE_NUMERIC": "niverel",
                +	"LISTS_SORT_TYPE_TEXT": "Dre urzh al lizherenneg",
                +	"LISTS_SORT_TYPE_IGNORECASE": "Dre urzh al lizherenneg, hep derc'hel kont eus an direnneg",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "Krouiñ ul listenn diwar an destenn",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "Krouiñ un destenn diwar al listenn",
                +	"LISTS_SPLIT_WITH_DELIMITER": "gant an dispartier",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Troc'hañ un destenn en ul listennad testennoù, o troc'hañ e pep dispartier.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Bodañ ul listennad testennoù en ul listenn hepken, o tispartiañ anezho gant un dispartier.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "eilpennañ %1",
                +	"LISTS_REVERSE_TOOLTIP": "Eilpennañ un eilskrid eus ur roll.",
                +	"VARIABLES_GET_TOOLTIP": "Distreiñ talvoud an argemm-mañ.",
                +	"VARIABLES_GET_CREATE_SET": "Krouiñ 'termenañ %1'",
                +	"VARIABLES_SET": "termenañ %1 da %2",
                +	"VARIABLES_SET_TOOLTIP": "Termenañ a ra argemm-mañ evit ma vo par da dalvoudenn ar moned.",
                +	"VARIABLES_SET_CREATE_GET": "Krouiñ 'kaout %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "da",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "ober un dra bennak",
                +	"PROCEDURES_BEFORE_PARAMS": "gant :",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "gant :",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Krouiñ un arc'hwel hep mont er-maez.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Deskrivañ an arc'hwel-mañ...",
                +	"PROCEDURES_DEFRETURN_RETURN": "distreiñ",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Kouiñ un arc'hwel gant ur mont er-maez",
                +	"PROCEDURES_ALLOW_STATEMENTS": "aotren an disklêriadurioù",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Diwallit : an arc'hwel-mañ en deus arventennoù eiladet.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Seveniñ an arc'hwel '%1' termenet gant an implijer.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Seveniñ an arc'hwel '%1' termenet gant an implijer hag implijout e zisoc'h.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "Monedoù",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Ouzhpennañ, lemel, pe adkempenn monedoù an arc'hwel-mañ.",
                +	"PROCEDURES_MUTATORARG_TITLE": "Anv ar moned",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Ouzhpennañ ur moned d'an arc'hwel.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Dreislinennañ termenadur an arc'hwel",
                +	"PROCEDURES_CREATE_DO": "Krouiñ '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ma'z eo gwir un dalvoudenn, distreiñ un eil talvoudenn neuze.",
                +	"PROCEDURES_IFRETURN_WARNING": "Diwallit : Gallout a rafe ar bloc'h bezañ implijet e termenadur un arc'hwel hepken."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ca.json b/blockly/webif/static/blockly/msg/json/ca.json
                new file mode 100644
                index 000000000..50d3d7a0c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ca.json
                @@ -0,0 +1,290 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Alvaro Vidal-Abarca",
                +			"Espertus",
                +			"Hiperpobla",
                +			"Jaumeortola",
                +			"Fitoschido"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"DUPLICATE_BLOCK": "Duplica",
                +	"ADD_COMMENT": "Afegeix un comentari",
                +	"REMOVE_COMMENT": "Elimina el comentari",
                +	"EXTERNAL_INPUTS": "Entrades externes",
                +	"INLINE_INPUTS": "Entrades en línia",
                +	"DELETE_BLOCK": "Esborra bloc",
                +	"DELETE_X_BLOCKS": "Esborra %1 blocs",
                +	"DELETE_ALL_BLOCKS": "Esborrar els %1 blocs?",
                +	"COLLAPSE_BLOCK": "Contraure bloc",
                +	"COLLAPSE_ALL": "Contraure blocs",
                +	"EXPAND_BLOCK": "Expandir bloc",
                +	"EXPAND_ALL": "Expandir blocs",
                +	"DISABLE_BLOCK": "Desactiva bloc",
                +	"ENABLE_BLOCK": "Activa bloc",
                +	"HELP": "Ajuda",
                +	"CHANGE_VALUE_TITLE": "Canvia valor:",
                +	"RENAME_VARIABLE": "Reanomena variable...",
                +	"RENAME_VARIABLE_TITLE": "Reanomena totes les variables '%1' a:",
                +	"NEW_VARIABLE": "Crea una variable…",
                +	"NEW_VARIABLE_TITLE": "Nou nom de variable:",
                +	"COLOUR_PICKER_HELPURL": "https://ca.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Escolliu un color de la paleta.",
                +	"COLOUR_RANDOM_TITLE": "color aleatori",
                +	"COLOUR_RANDOM_TOOLTIP": "Escolliu un color a l'atzar.",
                +	"COLOUR_RGB_TITLE": "color amb",
                +	"COLOUR_RGB_RED": "vermell",
                +	"COLOUR_RGB_GREEN": "verd",
                +	"COLOUR_RGB_BLUE": "blau",
                +	"COLOUR_RGB_TOOLTIP": "Crear un color amb les quantitats especificades de vermell, verd i blau. Tots els valors han de ser entre 0 i 100.",
                +	"COLOUR_BLEND_TITLE": "barreja",
                +	"COLOUR_BLEND_COLOUR1": "color 1",
                +	"COLOUR_BLEND_COLOUR2": "color 2",
                +	"COLOUR_BLEND_RATIO": "proporció",
                +	"COLOUR_BLEND_TOOLTIP": "Barreja dos colors amb una proporció donada (0,0 - 1,0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://ca.wikipedia.org/wiki/Bucle_For",
                +	"CONTROLS_REPEAT_TITLE": "repetir %1 vegades",
                +	"CONTROLS_REPEAT_INPUT_DO": "fer",
                +	"CONTROLS_REPEAT_TOOLTIP": "Executar unes sentències diverses vegades.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repetir mentre",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repetir fins que",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Mentre un valor sigui cert, llavors executar unes sentències.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Mentre un valor sigui fals, llavors executar unes sentències.",
                +	"CONTROLS_FOR_TOOLTIP": "Fer que la variable \"%1\" prengui els valors des del nombre inicial fins al nombre final, incrementant a cada pas l'interval indicat, i executar els blocs especificats.",
                +	"CONTROLS_FOR_TITLE": "comptar amb %1 des de %2 fins a %3 en increments de %4",
                +	"CONTROLS_FOREACH_TITLE": "per a cada element %1 en la llista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Per a cada element en la llista, desar l'element dins la variable '%1', i llavors executar unes sentències.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "sortir del bucle",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuar amb la següent iteració del bucle",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Sortir del bucle interior.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Ometre la resta d'aquest bucle, i continuar amb la següent iteració.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Advertència: Aquest bloc només es pot utilitzar dins d'un bucle.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si un valor és cert, llavors executar unes sentències.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si un valor és cert, llavors executar el primer bloc de sentències. En cas contrari, executar el segon bloc de sentències.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si el primer valor és cert, llavors executar el primer bloc de sentències. En cas contrari, si el segon valor és cert, executar el segon bloc de sentències.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si el primer valor és cert, llavors executar el primer bloc de sentències. En cas contrari, si el segon valor és cert, executar el segon bloc de sentències. Si cap dels valors és cert, executar l'últim bloc de sentències.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "si no, si",
                +	"CONTROLS_IF_MSG_ELSE": "si no",
                +	"CONTROLS_IF_IF_TOOLTIP": "Afegeix, esborra o reordena seccions per reconfigurar aquest bloc 'si'.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Afegeix una condició al bloc 'si'.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Afegeix una condició final, que recull qualsevol altra possibilitat, al bloc 'si'.",
                +	"LOGIC_COMPARE_HELPURL": "https://ca.wikipedia.org/wiki/Inequaci%C3%B3",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Retorna cert si totes dues entrades són iguals.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Retorna cert si totes dues entrades són diferents.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Retorna cert si la primera entrada és més petita que la segona entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Retorna cert si la primera entra és més petita o igual a la segona entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Retorna cert si la primera entrada és més gran que la segona entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Retorna cert si la primera entrada és més gran o igual a la segona entrada.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Retorna cer si totes dues entrades són certes.",
                +	"LOGIC_OPERATION_AND": "i",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Retorna cert si almenys una de les entrades és certa.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "no %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Retorna cert si l'entrada és falsa. Retorna fals si l'entrada és certa.",
                +	"LOGIC_BOOLEAN_TRUE": "cert",
                +	"LOGIC_BOOLEAN_FALSE": "fals",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Retorna o bé cert o bé fals.",
                +	"LOGIC_NULL": "nul",
                +	"LOGIC_NULL_TOOLTIP": "Retorna nul.",
                +	"LOGIC_TERNARY_CONDITION": "condició",
                +	"LOGIC_TERNARY_IF_TRUE": "si és cert",
                +	"LOGIC_TERNARY_IF_FALSE": "si és fals",
                +	"LOGIC_TERNARY_TOOLTIP": "Comprova la condició de 'condició'. Si la condició és certa, retorna el valor 'si és cert'; en cas contrari, retorna el valor 'si és fals'.",
                +	"MATH_NUMBER_HELPURL": "https://ca.wikipedia.org/wiki/Nombre",
                +	"MATH_NUMBER_TOOLTIP": "Un nombre.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ca.wikipedia.org/wiki/Aritm%C3%A8tica",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Retorna la suma dels dos nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Retorna la diferència entre els dos nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Retorna el producte del dos nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Retorna el quocient dels dos nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Retorna el primer nombre elevat a la potència indicada pel segon nombre.",
                +	"MATH_SINGLE_HELPURL": "https://ca.wikipedia.org/wiki/Arrel_quadrada",
                +	"MATH_SINGLE_OP_ROOT": "arrel quadrada",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Retorna l'arrel quadrada d'un nombre.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Retorna el valor absolut d'un nombre.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Retorna l'oposat d'un nombre.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Retorna el logaritme natural d'un nombre.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Retorna el logaritme en base 10 d'un nombre.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Retorna ''e'' elevat a la potència del nombre indicat.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Retorna 10 elevat a la potència del nombre indicat.",
                +	"MATH_TRIG_HELPURL": "https://ca.wikipedia.org/wiki/Funci%C3%B3_trigonom%C3%A8trica",
                +	"MATH_TRIG_TOOLTIP_SIN": "Retorna el sinus d'un grau (no radiant).",
                +	"MATH_TRIG_TOOLTIP_COS": "Retorna el cosinus d'un grau (no radiant).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Retorna la tangent d'un grau (no radiant).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Retorna l'arcsinus d'un nombre.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Retorna l'arccosinus d'un nombre.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Retorna l'arctangent d'un nombre.",
                +	"MATH_CONSTANT_HELPURL": "https://ca.wikipedia.org/wiki/Constant_matem%C3%A0tica",
                +	"MATH_CONSTANT_TOOLTIP": "Retorna una de les constants més habituals: π (3,141…), e (2,718…), φ (1,618…), sqrt(2) (1,414…), sqrt(½) (0,707…), o ∞ (infinit).",
                +	"MATH_IS_EVEN": "és parell",
                +	"MATH_IS_ODD": "és senar",
                +	"MATH_IS_PRIME": "és primer",
                +	"MATH_IS_WHOLE": "és enter",
                +	"MATH_IS_POSITIVE": "és positiu",
                +	"MATH_IS_NEGATIVE": "és negatiu",
                +	"MATH_IS_DIVISIBLE_BY": "és divisible per",
                +	"MATH_IS_TOOLTIP": "Comprova si un nombre és parell, senar, enter, positium negatiu, o si és divisible per un cert nombre. Retorna cert o fals.",
                +	"MATH_CHANGE_HELPURL": "https://ca.wikipedia.org/wiki/Suma",
                +	"MATH_CHANGE_TITLE": "canvia %1 per %2",
                +	"MATH_CHANGE_TOOLTIP": "Afegeix un nombre a la variable '%1'.",
                +	"MATH_ROUND_HELPURL": "https://ca.wikipedia.org/wiki/Arrodoniment",
                +	"MATH_ROUND_TOOLTIP": "Arrodonir un nombre cap amunt o cap avall.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arrodonir",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arrodonir cap amunt",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arrodonir cap avall",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma de llista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Retorna la suma de tots els nombres de la llista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "mínim de llista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Retorna el nombre més petit de la llista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "màxim de llista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Retorna el nombre més gran de la llista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "mitjana de llista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Retorna la mitjana (mitjana aritmètica) dels valors numèrics de la llista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana de llista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Retorna la mediana de la llista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "moda de llista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Retorna una llista dels elements que apareixen més vegades a la llista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "desviació estàndard de llista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Retorna la desviació estàndard de la llista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "element aleatori de llista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Retorna un element aleatori de la lllista.",
                +	"MATH_MODULO_HELPURL": "https://ca.wikipedia.org/wiki/Residu_%28aritm%C3%A8tica%29",
                +	"MATH_MODULO_TITLE": "residu de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Retorna el residu de dividir els dos nombres.",
                +	"MATH_CONSTRAIN_TITLE": "limitar %1 entre %2 i %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Limita un nombre perquè estigui entre els límits especificats (inclosos).",
                +	"MATH_RANDOM_INT_HELPURL": "https://ca.wikipedia.org/wiki/Generaci%C3%B3_de_nombres_aleatoris",
                +	"MATH_RANDOM_INT_TITLE": "nombre aleatori entre %1 i %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Retorna un nombre aleatori entre els dos límits especificats, inclosos.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://ca.wikipedia.org/wiki/Generaci%C3%B3_de_nombres_aleatoris",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fracció aleatòria",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Retorna una fracció aleatòria entre 0,0 (inclòs) i 1,0 (exclòs).",
                +	"TEXT_TEXT_HELPURL": "https://ca.wikipedia.org/wiki/Cadena_%28inform%C3%A0tica%29",
                +	"TEXT_TEXT_TOOLTIP": "Una lletra, paraula o línia de text.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "crear text amb",
                +	"TEXT_JOIN_TOOLTIP": "Crea un tros de text per unió de qualsevol nombre d'elements.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Afegeix, esborrar o reordenar seccions per reconfigurar aquest bloc de text.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Afegeix un element al text.",
                +	"TEXT_APPEND_TOOLTIP": "Afegir un text a la variable '%1'.",
                +	"TEXT_LENGTH_TITLE": "llargària de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Retorna el nombre de lletres (espais inclosos) en el text proporcionat.",
                +	"TEXT_ISEMPTY_TITLE": "%1 està buit",
                +	"TEXT_ISEMPTY_TOOLTIP": "Retorna cert si el text proporcionat està buit.",
                +	"TEXT_INDEXOF_TOOLTIP": "Retorna l'índex de la primera/última aparició del primer text dins el segon. Retorna %1 si no es troba el text.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "trobar la primera aparició del text",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "trobar l'última aparició del text",
                +	"TEXT_CHARAT_FROM_START": "recupera la lletra núm.#",
                +	"TEXT_CHARAT_FROM_END": "recupera la lletra núm.# des del final",
                +	"TEXT_CHARAT_FIRST": "recupera la primera lletra",
                +	"TEXT_CHARAT_LAST": "recupera l'última lletra",
                +	"TEXT_CHARAT_RANDOM": "recupera una lletra a l'atzar",
                +	"TEXT_CHARAT_TOOLTIP": "Recupera la lletra de la posició especificada.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Recupera una part especificada del text.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "en el text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "recupera subcadena des de la lletra núm.#",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "recupera subcadena des de la lletra núm.# des del final",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "recupera subcadena des de la primera lletra",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "fins a la lletra núm.#",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "fins a la lletra núm.# des del final",
                +	"TEXT_GET_SUBSTRING_END_LAST": "fins a l'última lletra",
                +	"TEXT_CHANGECASE_TOOLTIP": "Retorna una còpia del text amb diferents majúscules/minúscules.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "a MAJÚSCULES",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "a minúscules",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "a Text De Títol",
                +	"TEXT_TRIM_TOOLTIP": "Retorna una còpia del text on s'han esborrat els espais d'un o dels dos extrems.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "retalla espais de tots dos extrems de",
                +	"TEXT_TRIM_OPERATOR_LEFT": "retalla espais de l'esquerra de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "retalla espais de la dreta de",
                +	"TEXT_PRINT_TITLE": "imprimir %1",
                +	"TEXT_PRINT_TOOLTIP": "Imprimir el text, el nombre o altre valor especificat.",
                +	"TEXT_PROMPT_TYPE_TEXT": "demanar text amb el missatge",
                +	"TEXT_PROMPT_TYPE_NUMBER": "demanar un nombre amb el missatge",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Demana que l'usuari introdueixi un nombre.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Demana que l'usuari introdueixi un text.",
                +	"LISTS_CREATE_EMPTY_TITLE": "crear llista buida",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Retorna una llista, de longitud 0, que no conté cap dada.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Crea una llista amb qualsevol nombre d'elements.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "crear llista amb",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "llista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Afegeix, esborra o reordena seccions per reconfigurar aquest bloc de llista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Afegeix un element a la llista.",
                +	"LISTS_REPEAT_TOOLTIP": "Crea una llista formada pel valor donat, repetit tantes vegades com s'indiqui.",
                +	"LISTS_REPEAT_TITLE": "crea llista amb element %1 repetit %2 vegades",
                +	"LISTS_LENGTH_TITLE": "longitud de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Retorna la longitud d'una llista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 és buida",
                +	"LISTS_ISEMPTY_TOOLTIP": "Retorna cert si la llista és buida.",
                +	"LISTS_INLIST": "en la llista",
                +	"LISTS_INDEX_OF_FIRST": "buscar primera aparició d'un element",
                +	"LISTS_INDEX_OF_LAST": "buscar última aparició d'un element",
                +	"LISTS_INDEX_OF_TOOLTIP": "Retorna l'índex de la primera/última aparició d'un element a la llista. Retorna %1 si no s'hi troba el text.",
                +	"LISTS_GET_INDEX_GET": "recupera",
                +	"LISTS_GET_INDEX_GET_REMOVE": "recupera i esborra",
                +	"LISTS_GET_INDEX_REMOVE": "esborra",
                +	"LISTS_GET_INDEX_FROM_END": "núm.# des del final",
                +	"LISTS_GET_INDEX_FIRST": "primer",
                +	"LISTS_GET_INDEX_LAST": "últim",
                +	"LISTS_GET_INDEX_RANDOM": "a l'atzar",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 és el primer element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 és l'últim element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Retorna l'element de la posició especificada a la llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Retorna el primer element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Retorna l'últim element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Retorna un element a l'atzar d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Esborra i retorna l'element de la posició especificada de la llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Esborra i retorna el primer element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Esborra i retorna l'últim element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Esborra i retorna un element a l'atzar d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Esborra l'element de la posició especificada de la llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Esborra el primer element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Esborra l'últim element d'una llista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Esborra un element a l'atzar d'una llista.",
                +	"LISTS_SET_INDEX_SET": "modifica",
                +	"LISTS_SET_INDEX_INSERT": "insereix a",
                +	"LISTS_SET_INDEX_INPUT_TO": "com",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Modifica l'element de la posició especificada d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Modifica el primer element d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Modifica l'últim element d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Modifica un element a l'atzar d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insereix l'element a la posició especificada d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insereix l'element al principi d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Afegeix l'element al final d'una llista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Insereix l'element en una posició a l'atzar d'una llista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "recupera sub-llista des de #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "recupera sub-llista des de # des del final",
                +	"LISTS_GET_SUBLIST_START_FIRST": "recupera sub-llista des del principi",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "fins #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "fins # des del final",
                +	"LISTS_GET_SUBLIST_END_LAST": "fins l'últim",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Crea una còpia de la part especificada d'una llista.",
                +	"VARIABLES_GET_TOOLTIP": "Retorna el valor d'aquesta variable.",
                +	"VARIABLES_GET_CREATE_SET": "Crea 'modifica %1'",
                +	"VARIABLES_SET": "modifica %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Modifica aquesta variable al valor introduït.",
                +	"VARIABLES_SET_CREATE_GET": "Crear 'recupera %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "a",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "fes alguna cosa",
                +	"PROCEDURES_BEFORE_PARAMS": "amb:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "amb:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crea una funció sense sortida.",
                +	"PROCEDURES_DEFRETURN_RETURN": "retorna",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Crea una funció amb una sortida.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permetre declaracions",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Advertència: Aquesta funció té paràmetres duplicats.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ca.wikipedia.org/wiki/Procediment_%28Programació%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Executa la funció definida per usuari '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ca.wikipedia.org/wiki/Procediment_%28Programació%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Executa la funció definida per l'usuari '%1' i utilitza la seva sortida.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entrades",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Afegir, eliminar o canviar l'ordre de les entrades per aquesta funció.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nom d'entrada:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Afegir una entrada per la funció.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Iluminar la definició de la funció",
                +	"PROCEDURES_CREATE_DO": "Crear '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Si el valor és cert, llavors retorna un segon valor.",
                +	"PROCEDURES_IFRETURN_WARNING": "Advertència: Aquest bloc només es pot utilitzar dins de la definició d'una funció."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/constants.json b/blockly/webif/static/blockly/msg/json/constants.json
                new file mode 100644
                index 000000000..5b5010359
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/constants.json
                @@ -0,0 +1 @@
                +{"MATH_HUE": "230", "LOOPS_HUE": "120", "LISTS_HUE": "260", "LOGIC_HUE": "210", "VARIABLES_HUE": "330", "TEXTS_HUE": "160", "PROCEDURES_HUE": "290", "COLOUR_HUE": "20"}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/json/cs.json b/blockly/webif/static/blockly/msg/json/cs.json
                new file mode 100644
                index 000000000..f8b8205f4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/cs.json
                @@ -0,0 +1,333 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Chmee2",
                +			"Rosnicka.kacka",
                +			"Matěj Grabovský",
                +			"Espertus",
                +			"Utar",
                +			"Clon",
                +			"Koo6",
                +			"Vtmarvin",
                +			"Dvorapa",
                +			"Dita"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "položka",
                +	"TODAY": "Dnes",
                +	"DUPLICATE_BLOCK": "Duplikovat",
                +	"ADD_COMMENT": "Přidat komentář",
                +	"REMOVE_COMMENT": "Odstranit komentář",
                +	"EXTERNAL_INPUTS": "vnější vstupy",
                +	"INLINE_INPUTS": "Vložené vstupy",
                +	"DELETE_BLOCK": "Smazat blok",
                +	"DELETE_X_BLOCKS": "Smazat %1 bloků",
                +	"DELETE_ALL_BLOCKS": "Smazat všech %1 bloků?",
                +	"CLEAN_UP": "Uspořádat bloky",
                +	"COLLAPSE_BLOCK": "Sbalit blok",
                +	"COLLAPSE_ALL": "Sbalit bloky",
                +	"EXPAND_BLOCK": "Rozbalit blok",
                +	"EXPAND_ALL": "Rozbalit bloky",
                +	"DISABLE_BLOCK": "Deaktivovat blok",
                +	"ENABLE_BLOCK": "Povolit blok",
                +	"HELP": "Nápověda",
                +	"UNDO": "Zpět",
                +	"REDO": "Znovu",
                +	"CHANGE_VALUE_TITLE": "Změnit hodnotu:",
                +	"RENAME_VARIABLE": "Přejmenovat proměnnou...",
                +	"RENAME_VARIABLE_TITLE": "Přejmenuj všech '%1' proměnných na:",
                +	"NEW_VARIABLE": "Nová proměnná...",
                +	"NEW_VARIABLE_TITLE": "Nový název proměnné:",
                +	"COLOUR_PICKER_HELPURL": "https://cs.wikipedia.org/wiki/Barva",
                +	"COLOUR_PICKER_TOOLTIP": "Vyberte barvu z palety.",
                +	"COLOUR_RANDOM_TITLE": "náhodná barva",
                +	"COLOUR_RANDOM_TOOLTIP": "Zvolte barvu náhodně.",
                +	"COLOUR_RGB_TITLE": "obarvěte barvou",
                +	"COLOUR_RGB_RED": "červená",
                +	"COLOUR_RGB_GREEN": "zelená",
                +	"COLOUR_RGB_BLUE": "modrá",
                +	"COLOUR_RGB_TOOLTIP": "Vytvoř barvu se zadaným množstvím červené, zelené a modré.  Všechny hodnoty musí být mezi 0 a 100.",
                +	"COLOUR_BLEND_TITLE": "smíchat",
                +	"COLOUR_BLEND_COLOUR1": "barva 1",
                +	"COLOUR_BLEND_COLOUR2": "barva 2",
                +	"COLOUR_BLEND_RATIO": "poměr",
                +	"COLOUR_BLEND_TOOLTIP": "Smíchá dvě barvy v daném poměru (0.0–1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://cs.wikipedia.org/wiki/Cyklus_pro",
                +	"CONTROLS_REPEAT_TITLE": "opakuj %1 krát",
                +	"CONTROLS_REPEAT_INPUT_DO": "dělej",
                +	"CONTROLS_REPEAT_TOOLTIP": "Proveď určité příkazy několikrát.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "opakovat když",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "opakovat dokud",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Dokud je hodnota pravdivá, prováděj určité příkazy.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Dokud je hodnota nepravdivá, prováděj určité příkazy.",
                +	"CONTROLS_FOR_TOOLTIP": "Nechá proměnnou '%1' nabývat hodnot od počátečního do koncového čísla po daném přírůstku a provádí s ní příslušné bloky.",
                +	"CONTROLS_FOR_TITLE": "počítat s %1 od %2 do %3 po %4",
                +	"CONTROLS_FOREACH_TITLE": "pro každou položku %1 v seznamu %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Pro každou položku v seznamu nastavte do proměnné '%1' danou položku a proveďte nějaké operace.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "vyskočit ze smyčky",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "pokračuj dalším opakováním smyčky",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Vyskoč z vnitřní smyčky.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Přeskoč zbytek této smyčky a pokračuj dalším opakováním.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Upozornění: Tento blok může být použit pouze uvnitř smyčky.",
                +	"CONTROLS_IF_TOOLTIP_1": "Je-li hodnota pravda, proveď určité příkazy.",
                +	"CONTROLS_IF_TOOLTIP_2": "Je-li hodnota pravda, proveď první blok příkazů.  V opačném případě proveď druhý blok příkazů.",
                +	"CONTROLS_IF_TOOLTIP_3": "Je-li první hodnota pravdivá, proveď první blok příkazů. V opačném případě, je-li pravdivá druhá hodnota, proveď druhý blok příkazů.",
                +	"CONTROLS_IF_TOOLTIP_4": "Je-li první hodnota pravda, proveď první blok příkazů.  Je-li druhá hodnota pravda, proveď druhý blok příkazů.  Pokud žádná hodnota není pravda, proveď poslední blok příkazů.",
                +	"CONTROLS_IF_MSG_IF": "pokud",
                +	"CONTROLS_IF_MSG_ELSEIF": "nebo pokud",
                +	"CONTROLS_IF_MSG_ELSE": "jinak",
                +	"CONTROLS_IF_IF_TOOLTIP": "Přidej, odstraň či uspořádej sekce k přenastavení tohoto bloku \"pokud\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Přidat podmínku do \"pokud\" bloku.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Přidej konečnou podmínku zahrnující ostatní případy do bloku \"pokud\".",
                +	"IOS_ERROR": "Chyba",
                +	"IOS_PROCEDURES_INPUTS": "vstupy",
                +	"IOS_VARIABLES_ADD_BUTTON": "Přidat",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Přejmenovat",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Smazat",
                +	"LOGIC_COMPARE_HELPURL": "https://cs.wikipedia.org/wiki/Nerovnost_(matematika)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Vrátí hodnotu pravda, pokud se oba vstupy rovnají jeden druhému.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Vrátí hodnotu pravda, pokud se oba vstupy nerovnají sobě navzájem.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Navrátí hodnotu pravda, pokud je první vstup menší než druhý vstup.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Navrátí hodnotu pravda, pokud je první vstup menší a nebo rovný druhému vstupu.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Navrátí hodnotu pravda, pokud první vstup je větší než druhý vstup.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Navrátí hodnotu pravda, pokud je první vstup větší a nebo rovný druhému vstupu.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Vrátí hodnotu pravda, pokud oba dva vstupy jsou pravdivé.",
                +	"LOGIC_OPERATION_AND": "a",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Vrátí hodnotu pravda, pokud alespoň jeden ze vstupů má hodnotu pravda.",
                +	"LOGIC_OPERATION_OR": "nebo",
                +	"LOGIC_NEGATE_TITLE": "ne %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Navrátí hodnotu pravda, pokud je vstup nepravda. Navrátí hodnotu nepravda, pokud je vstup pravda.",
                +	"LOGIC_BOOLEAN_TRUE": "pravda",
                +	"LOGIC_BOOLEAN_FALSE": "nepravda",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Vrací pravda nebo nepravda.",
                +	"LOGIC_NULL": "prázdný",
                +	"LOGIC_NULL_TOOLTIP": "Vrátí prázdnou hodnotu",
                +	"LOGIC_TERNARY_HELPURL": "https://cs.wikipedia.org/wiki/Ternární operátor (programování)",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "pokud pravda",
                +	"LOGIC_TERNARY_IF_FALSE": "pokud nepravda",
                +	"LOGIC_TERNARY_TOOLTIP": "Zkontroluje podmínku v \"testu\". Když je podmínka pravda, vrátí hodnotu \"pokud pravda\"; v opačném případě vrátí hodnotu \"pokud nepravda\".",
                +	"MATH_NUMBER_HELPURL": "https://cs.wikipedia.org/wiki/Číslo",
                +	"MATH_NUMBER_TOOLTIP": "Číslo.",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "arctan",
                +	"MATH_ARITHMETIC_HELPURL": "https://cs.wikipedia.org/wiki/Aritmetika",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Vrátí součet dvou čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Vrátí rozdíl dvou čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Vrátí součin dvou čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Vrátí podíl dvou čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Vrátí první číslo umocněné na druhé číslo.",
                +	"MATH_SINGLE_HELPURL": "https://cs.wikipedia.org/wiki/Druhá_odmocnina",
                +	"MATH_SINGLE_OP_ROOT": "druhá odmocnina",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Vrátí druhou odmocninu čísla.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolutní hodnota",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Vrátí absolutní hodnotu čísla.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Vrátí zápornou hodnotu čísla.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Vrátí přirozený logaritmus čísla.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Vrátí desítkový logaritmus čísla.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Vrátí mocninu čísla e.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Vrátí mocninu čísla 10.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Vrátí sinus úhlu ve stupních.",
                +	"MATH_TRIG_TOOLTIP_COS": "Vrátí kosinus úhlu ve stupních.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Vrátí tangens úhlu ve stupních.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Vrátí arkus sinus čísla.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Vrátí arkus kosinus čísla.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Vrátí arkus tangens čísla.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Vraťte jednu z následujících konstant: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (nekonečno).",
                +	"MATH_IS_EVEN": "je sudé",
                +	"MATH_IS_ODD": "je liché",
                +	"MATH_IS_PRIME": "je prvočíslo",
                +	"MATH_IS_WHOLE": "je celé",
                +	"MATH_IS_POSITIVE": "je kladné",
                +	"MATH_IS_NEGATIVE": "je záporné",
                +	"MATH_IS_DIVISIBLE_BY": "je dělitelné číslem",
                +	"MATH_IS_TOOLTIP": "Kontrola, zda je číslo sudé, liché, prvočíslo, celé, kladné, záporné nebo zda je dělitelné daným číslem. Vrací pravdu nebo nepravdu.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "zaměň %1 za %2",
                +	"MATH_CHANGE_TOOLTIP": "Přičti číslo k proměnné '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Zaokrouhlit číslo nahoru nebo dolů.",
                +	"MATH_ROUND_OPERATOR_ROUND": "zaokrouhlit",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "zaokrouhlit nahoru",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "zaokrouhlit dolů",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma seznamu",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Vrátí součet všech čísel v seznamu.",
                +	"MATH_ONLIST_OPERATOR_MIN": "nejmenší v seznamu",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Vrátí nejmenší číslo v seznamu.",
                +	"MATH_ONLIST_OPERATOR_MAX": "největší v seznamu",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Vrátí největší číslo v seznamu.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "průměr v seznamu",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Vrátí průměr (aritmetický průměr) číselných hodnot v seznamu.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "medián v seznamu",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Vrátí medián seznamu.",
                +	"MATH_ONLIST_OPERATOR_MODE": "nejčastější ze seznamu",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Vrátí seznam nejčastějších položek seznamu.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "směrodatná odchylka ze seznamu",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Vrátí směrodatnou odchylku seznamu.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "náhodná položka seznamu",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Vrátí náhodnou položku ze seznamu.",
                +	"MATH_MODULO_HELPURL": "https://cs.wikipedia.org/wiki/Modul%C3%A1rn%C3%AD_aritmetika",
                +	"MATH_MODULO_TITLE": "zbytek po dělení %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Vrátí zbytek po dělení dvou čísel.",
                +	"MATH_CONSTRAIN_TITLE": "omez %1 na rozmezí od %2 do %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Omezí číslo tak, aby bylo ve stanovených mezích (včetně).",
                +	"MATH_RANDOM_INT_HELPURL": "https://cs.wikipedia.org/wiki/Gener%C3%A1tor_n%C3%A1hodn%C3%BDch_%C4%8D%C3%ADsel",
                +	"MATH_RANDOM_INT_TITLE": "náhodné celé číslo od %1 do %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Vrací náhodné celé číslo mezi dvěma určenými mezemi, včetně mezních hodnot.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://cs.wikipedia.org/wiki/Gener%C3%A1tor_n%C3%A1hodn%C3%BDch_%C4%8D%C3%ADsel",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "náhodné číslo mezi 0 (včetně) do 1",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Vrátí náhodné číslo mezi 0,0 (včetně) až 1,0",
                +	"TEXT_TEXT_HELPURL": "https://cs.wikipedia.org/wiki/Textov%C3%BD_%C5%99et%C4%9Bzec",
                +	"TEXT_TEXT_TOOLTIP": "Písmeno, slovo nebo řádek textu.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "vytvořit text s",
                +	"TEXT_JOIN_TOOLTIP": "Vytvoří kousek textu spojením libovolného počtu položek.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "spojit",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Přidat, odebrat nebo změnit pořadí oddílů tohoto textového bloku.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Přidat položku do textu.",
                +	"TEXT_APPEND_TOOLTIP": "Přidá určitý text k proměnné '%1'.",
                +	"TEXT_LENGTH_TITLE": "délka %1",
                +	"TEXT_LENGTH_TOOLTIP": "Vrátí počet písmen (včetně mezer) v zadaném textu.",
                +	"TEXT_ISEMPTY_TITLE": "%1 je prázdný",
                +	"TEXT_ISEMPTY_TOOLTIP": "Vrátí pravda pokud je zadaný text prázdný.",
                +	"TEXT_INDEXOF_TOOLTIP": "Vrátí index prvního/posledního výskytu prvního textu v druhém textu.  Pokud text není nalezen, vypíše %1.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "najít první výskyt textu",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "najít poslední výskyt textu",
                +	"TEXT_CHARAT_FROM_START": "získat písmeno #",
                +	"TEXT_CHARAT_FROM_END": "získat # písmeno od konce",
                +	"TEXT_CHARAT_FIRST": "získat první písmeno",
                +	"TEXT_CHARAT_LAST": "získat poslední písmeno",
                +	"TEXT_CHARAT_RANDOM": "získat náhodné písmeno",
                +	"TEXT_CHARAT_TOOLTIP": "Získat písmeno na konkrétní pozici.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Získat zadanou část textu.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "v textu",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "získat podřetězec od písmene #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "získat podřetězec od písmene # od konce",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "získat podřetězec od prvního písmene",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "do písmene #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "do # písmene od konce",
                +	"TEXT_GET_SUBSTRING_END_LAST": "do posledního písmene",
                +	"TEXT_CHANGECASE_TOOLTIP": "Vrátí kopii textu s jinou velikostí písmen.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "na VELKÁ PÍSMENA",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "na malá písmena",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "na Počáteční Velká Písmena",
                +	"TEXT_TRIM_TOOLTIP": "Vrátí kopii textu s odstraněnými mezerami z jednoho nebo obou konců.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "odstranit mezery z obou stran",
                +	"TEXT_TRIM_OPERATOR_LEFT": "odstranit mezery z levé strany",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "odstranit mezery z pravé strany",
                +	"TEXT_PRINT_TITLE": "tisk %1",
                +	"TEXT_PRINT_TOOLTIP": "Tisk zadaného textu, čísla nebo jiné hodnoty.",
                +	"TEXT_PROMPT_TYPE_TEXT": "výzva k zadání textu se zprávou",
                +	"TEXT_PROMPT_TYPE_NUMBER": "výzva k zadání čísla se zprávou",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Výzva pro uživatele k zadání čísla.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Výzva pro uživatele k zadání nějakého textu.",
                +	"LISTS_CREATE_EMPTY_TITLE": "vytvořit prázdný seznam",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Vrátí seznam nulové délky, který neobsahuje žádné datové záznamy",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Vytvoř seznam s libovolným počtem položek.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "vytvořit seznam s",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "seznam",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Přidat, odebrat nebo změnit pořadí oddílů tohoto seznamu bloku.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Přidat položku do seznamu.",
                +	"LISTS_REPEAT_TOOLTIP": "Vytváří seznam obsahující danou hodnotu n-krát.",
                +	"LISTS_REPEAT_TITLE": "vytvoř seznam s položkou %1 opakovanou %1 krát",
                +	"LISTS_LENGTH_TITLE": "délka %1",
                +	"LISTS_LENGTH_TOOLTIP": "Vrací počet položek v seznamu.",
                +	"LISTS_ISEMPTY_TITLE": "%1 je prázdné",
                +	"LISTS_ISEMPTY_TOOLTIP": "Vrátí hodnotu pravda, pokud je seznam prázdný.",
                +	"LISTS_INLIST": "v seznamu",
                +	"LISTS_INDEX_OF_FIRST": "najít první výskyt položky",
                +	"LISTS_INDEX_OF_LAST": "najít poslední výskyt položky",
                +	"LISTS_INDEX_OF_TOOLTIP": "Vrací index prvního/posledního výskytu položky v seznamu. Vrací %1, pokud položka nebyla nalezena.",
                +	"LISTS_GET_INDEX_GET": "získat",
                +	"LISTS_GET_INDEX_GET_REMOVE": "získat a odstranit",
                +	"LISTS_GET_INDEX_REMOVE": "odstranit",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# od konce",
                +	"LISTS_GET_INDEX_FIRST": "první",
                +	"LISTS_GET_INDEX_LAST": "poslední",
                +	"LISTS_GET_INDEX_RANDOM": "náhodné",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 je první položka.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 je poslední položka.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Získá položku z určené pozice v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Vrátí první položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Vrátí poslední položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Vrátí náhodnou položku ze seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Odstraní a získá položku z určené pozice v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Odstraní a vrátí první položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Odstraní a vrátí poslední položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Odstraní a vrátí náhodnou položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Odebere položku na konkrétním místě v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Odstraní první položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Odstraní poslední položku v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Odstraní náhodou položku v seznamu.",
                +	"LISTS_SET_INDEX_SET": "nastavit",
                +	"LISTS_SET_INDEX_INSERT": "vložit na",
                +	"LISTS_SET_INDEX_INPUT_TO": "jako",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Nastaví položku na konkrétní místo v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Nastaví první položku v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Nastaví poslední položku v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Nastaví náhodnou položku v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Vloží položku na určenou pozici v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Vložit položku na začátek seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Připojí položku na konec seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Připojí položku náhodně do seznamu.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "získat podseznam od #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "získat podseznam od # od konce",
                +	"LISTS_GET_SUBLIST_START_FIRST": "získat podseznam od první položky",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "do #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "do # od konce",
                +	"LISTS_GET_SUBLIST_END_LAST": "jako poslední",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Vytvoří kopii určené části seznamu.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "seřadit %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Seřadit kopii seznamu.",
                +	"LISTS_SORT_ORDER_ASCENDING": "vzestupně",
                +	"LISTS_SORT_ORDER_DESCENDING": "sestupně",
                +	"LISTS_SORT_TYPE_NUMERIC": "číselné",
                +	"LISTS_SORT_TYPE_TEXT": "abecedně",
                +	"LISTS_SORT_TYPE_IGNORECASE": "abecedně, na velikosti písmen nezáleží",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "udělat z textu seznam",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "udělat ze seznamu text",
                +	"LISTS_SPLIT_WITH_DELIMITER": "s oddělovačem",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Rozdělit text do seznamu textů, lámání na oddělovačích.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Spojit seznam textů do jednoho textu, rozdělaného oddělovači.",
                +	"VARIABLES_GET_TOOLTIP": "Vrátí hodnotu této proměnné.",
                +	"VARIABLES_GET_CREATE_SET": "Vytvořit \"nastavit %1\"",
                +	"VARIABLES_SET": "nastavit %1 na %2",
                +	"VARIABLES_SET_TOOLTIP": "Nastaví tuto proměnnou, aby se rovnala vstupu.",
                +	"VARIABLES_SET_CREATE_GET": "Vytvořit \"získat %1\"",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://cs.wikipedia.org/w/index.php?title=Funkce_(programování)",
                +	"PROCEDURES_DEFNORETURN_TITLE": "k provedení",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "proveď něco",
                +	"PROCEDURES_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Vytvořit funkci bez výstupu.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Popište tuto funkci...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://cs.wikipedia.org/w/index.php?title=Funkce_(programování)",
                +	"PROCEDURES_DEFRETURN_RETURN": "navrátit",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Vytvořit funkci s výstupem.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "povolit příkazy",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Upozornění: Tato funkce má duplicitní parametry.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://cs.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Spustí uživatelem definovanou funkci '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://cs.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Spustí uživatelem definovanou funkci '%1' a použije její výstup.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "vstupy",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Přidat, odebrat nebo změnit pořadí vstupů této funkce.",
                +	"PROCEDURES_MUTATORARG_TITLE": "vstupní jméno:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Přidat vstupy do funkce.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Zvýraznit definici funkce",
                +	"PROCEDURES_CREATE_DO": "Vytvořit '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Je-li hodnota pravda, pak vrátí druhou hodnotu.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Varování: Tento blok může být použit pouze uvnitř definici funkce."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/da.json b/blockly/webif/static/blockly/msg/json/da.json
                new file mode 100644
                index 000000000..aa1a87ced
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/da.json
                @@ -0,0 +1,341 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Christian List",
                +			"RickiRunge",
                +			"MGA73",
                +			"Mads Haupt",
                +			"Tjernobyl",
                +			"Joedalton"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "I dag",
                +	"DUPLICATE_BLOCK": "Duplikér",
                +	"ADD_COMMENT": "Tilføj kommentar",
                +	"REMOVE_COMMENT": "Fjern kommentar",
                +	"EXTERNAL_INPUTS": "Udvendige inputs",
                +	"INLINE_INPUTS": "Indlejrede inputs",
                +	"DELETE_BLOCK": "Slet blok",
                +	"DELETE_X_BLOCKS": "Slet %1 blokke",
                +	"DELETE_ALL_BLOCKS": "Slet alle %1 blokke?",
                +	"CLEAN_UP": "Ryd op i blokke",
                +	"COLLAPSE_BLOCK": "Fold blokken sammen",
                +	"COLLAPSE_ALL": "Fold blokkene sammen",
                +	"EXPAND_BLOCK": "Fold blokken ud",
                +	"EXPAND_ALL": "Fold blokkene ud",
                +	"DISABLE_BLOCK": "Deaktivér blok",
                +	"ENABLE_BLOCK": "Aktivér blok",
                +	"HELP": "Hjælp",
                +	"UNDO": "Fortryd",
                +	"REDO": "Omgør",
                +	"CHANGE_VALUE_TITLE": "Skift værdi:",
                +	"RENAME_VARIABLE": "Omdøb variabel...",
                +	"RENAME_VARIABLE_TITLE": "Omdøb alle '%1' variabler til:",
                +	"NEW_VARIABLE": "Opret variabel ...",
                +	"NEW_VARIABLE_TITLE": "Navn til den nye variabel:",
                +	"VARIABLE_ALREADY_EXISTS": "En variabel med navnet »%1« findes allerede.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "En variabel med navnet »%1« findes allerede for en anden variabel af typen »%2«.",
                +	"PROCEDURE_ALREADY_EXISTS": "En procedure navngivet »%1« findes allerede.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Slet %1's brug af variablen »%2«?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Kan ikke slette variablen »%1« da den er en del af definitionen af funktionen »%2«",
                +	"DELETE_VARIABLE": "Slet variablen »%1«",
                +	"COLOUR_PICKER_HELPURL": "https://da.wikipedia.org/wiki/Farve",
                +	"COLOUR_PICKER_TOOLTIP": "Vælg en farve fra paletten.",
                +	"COLOUR_RANDOM_TITLE": "tilfældig farve",
                +	"COLOUR_RANDOM_TOOLTIP": "Vælg en tilfældig farve.",
                +	"COLOUR_RGB_TITLE": "farve med",
                +	"COLOUR_RGB_RED": "rød",
                +	"COLOUR_RGB_GREEN": "grøn",
                +	"COLOUR_RGB_BLUE": "blå",
                +	"COLOUR_RGB_TOOLTIP": "Lav en farve med den angivne mængde af rød, grøn og blå. Alle værdier skal være mellem 0 og 100.",
                +	"COLOUR_BLEND_TITLE": "bland",
                +	"COLOUR_BLEND_COLOUR1": "farve 1",
                +	"COLOUR_BLEND_COLOUR2": "farve 2",
                +	"COLOUR_BLEND_RATIO": "i forholdet",
                +	"COLOUR_BLEND_TOOLTIP": "Blander to farver sammen i et bestemt forhold (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://da.wikipedia.org/wiki/For-l%C3%B8kke",
                +	"CONTROLS_REPEAT_TITLE": "gentag %1 gange",
                +	"CONTROLS_REPEAT_INPUT_DO": "udfør",
                +	"CONTROLS_REPEAT_TOOLTIP": "Udfør nogle kommandoer flere gange.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "gentag sålænge",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "gentag indtil",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Udfør nogle kommandoer, sålænge en værdi er sand.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Udfør nogle kommandoer, sålænge en værdi er falsk.",
                +	"CONTROLS_FOR_TOOLTIP": "Få variablen \"%1\" til at have værdierne fra startværdien til slutværdien, mens der tælles med det angivne interval, og udfør de angivne blokke.",
                +	"CONTROLS_FOR_TITLE": "tæl med %1 fra %2 til %3 med %4",
                +	"CONTROLS_FOREACH_TITLE": "for hvert element %1 i listen %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "For hvert element i en liste, sæt variablen '%1' til elementet, og udfør derefter nogle kommandoer.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "bryd ud af løkken",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "fortsæt med den næste gentagelse i løkken",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Bryd ud af den omgivende løkke.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Spring resten af denne løkke over, og fortsæt med den næste gentagelse.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Advarsel: Denne blok kan kun bruges i en løkke.",
                +	"CONTROLS_IF_TOOLTIP_1": "Hvis en værdi er sand, så udfør nogle kommandoer.",
                +	"CONTROLS_IF_TOOLTIP_2": "Hvis en værdi er sand, så udfør den første blok af kommandoer. Ellers udfør den anden blok af kommandoer.",
                +	"CONTROLS_IF_TOOLTIP_3": "Hvis den første værdi er sand, så udfør den første blok af kommandoer.  Ellers, hvis den anden værdi er sand, så udfør den anden blok af kommandoer.",
                +	"CONTROLS_IF_TOOLTIP_4": "Hvis den første værdi er sand, så udfør den første blok af kommandoer. Ellers, hvis den anden værdi er sand, så udfør den anden blok af kommandoer. Hvis ingen af værdierne er sande, så udfør den sidste blok af kommandoer.",
                +	"CONTROLS_IF_MSG_IF": "hvis",
                +	"CONTROLS_IF_MSG_ELSEIF": "ellers hvis",
                +	"CONTROLS_IF_MSG_ELSE": "ellers",
                +	"CONTROLS_IF_IF_TOOLTIP": "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne \"hvis\" blok.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Tilføj en betingelse til denne \"hvis\" blok.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Tilføj en sidste fang-alt betingelse, til denne \"hvis\" blok.",
                +	"IOS_OK": "O.k.",
                +	"IOS_CANCEL": "Annuller",
                +	"IOS_ERROR": "Fejl",
                +	"IOS_PROCEDURES_INPUTS": "INDDATA",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Tilføj inddata",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Tillad udsagn",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Denne funktion har duplikerede inddata.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Tilføj variabel",
                +	"IOS_VARIABLES_ADD_BUTTON": "Tilføj",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Omdøb",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Slet",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Variabelnavn",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Du kan ikke bruge et tomt variabelnavn.",
                +	"LOGIC_COMPARE_HELPURL": "https://da.wikipedia.org/wiki/Ulighed_(matematik)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Returnere sand, hvis begge inputs er lig med hinanden.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Returnere sand, hvis begge inputs ikke er lig med hinanden.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Returnere sand, hvis det første input er mindre end det andet input.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Returnere sand, hvis det første input er mindre end eller lig med det andet input.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Returnere sand, hvis det første input er større end det andet input.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Returnere sand, hvis det første input er større end eller lig med det andet input.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Returnere sand, hvis begge inputs er sande.",
                +	"LOGIC_OPERATION_AND": "og",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Returnere sand, hvis mindst et af inputtene er sande.",
                +	"LOGIC_OPERATION_OR": "eller",
                +	"LOGIC_NEGATE_TITLE": "ikke %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returnerer sand, hvis input er falsk. Returnerer falsk, hvis input er sandt.",
                +	"LOGIC_BOOLEAN_TRUE": "sand",
                +	"LOGIC_BOOLEAN_FALSE": "falsk",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returnerer enten sand eller falsk.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returnerer null.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "hvis sand",
                +	"LOGIC_TERNARY_IF_FALSE": "hvis falsk",
                +	"LOGIC_TERNARY_TOOLTIP": "Kontrollér betingelsen i 'test'. Hvis betingelsen er sand, returnér \"hvis sand\" værdien; ellers returnér \"hvis falsk\" værdien.",
                +	"MATH_NUMBER_HELPURL": "https://da.wikipedia.org/wiki/Tal",
                +	"MATH_NUMBER_TOOLTIP": "Et tal.",
                +	"MATH_DIVISION_SYMBOL": ":",
                +	"MATH_ARITHMETIC_HELPURL": "https://da.wikipedia.org/wiki/Aritmetik",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Returnere summen af de to tal.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Returnere forskellen mellem de to tal.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Returnere produktet af de to tal.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Returnere kvotienten af de to tal.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Returnere det første tal opløftet til potensen af det andet tal.",
                +	"MATH_SINGLE_HELPURL": "https://da.wikipedia.org/wiki/Kvadratrod",
                +	"MATH_SINGLE_OP_ROOT": "kvadratrod",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Returnere kvadratroden af et tal.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Returnere den absolutte værdi af et tal.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Returnere negationen af et tal.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Returnere den naturlige logaritme af et tal.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Returnere 10-talslogaritmen af et tal.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Returnere e til potensen af et tal.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Returnere 10 til potensen af et tal.",
                +	"MATH_TRIG_HELPURL": "https://da.wikipedia.org/wiki/Trigonometrisk_funktion",
                +	"MATH_TRIG_TOOLTIP_SIN": "Returnere sinus af en vinkel (i grader).",
                +	"MATH_TRIG_TOOLTIP_COS": "Returnere cosinus af en vinkel (i grader).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Returnere tangens af en vinkel (i grader).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Returnere arcus sinus af et tal.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Returnere arcus cosinus af et tal.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Returnere arcus tangens af et tal.",
                +	"MATH_CONSTANT_HELPURL": "https://da.wikipedia.org/wiki/Matematisk_konstant",
                +	"MATH_CONSTANT_TOOLTIP": "Returnere en af de ofte brugte konstanter: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(2) (1.414…), sqrt(½) (0.707…) eller ∞ (uendeligt).",
                +	"MATH_IS_EVEN": "er lige",
                +	"MATH_IS_ODD": "er ulige",
                +	"MATH_IS_PRIME": "er et primtal",
                +	"MATH_IS_WHOLE": "er helt",
                +	"MATH_IS_POSITIVE": "er positivt",
                +	"MATH_IS_NEGATIVE": "er negativt",
                +	"MATH_IS_DIVISIBLE_BY": "er deleligt med",
                +	"MATH_IS_TOOLTIP": "Kontrollere, om et tal er lige, ulige, primtal, helt, positivt, negativt, eller om det er deleligt med bestemt tal. Returnere sandt eller falskt.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "skift %1 med %2",
                +	"MATH_CHANGE_TOOLTIP": "Læg et tal til variablen '%1'.",
                +	"MATH_ROUND_HELPURL": "https://da.wikipedia.org/wiki/Afrunding",
                +	"MATH_ROUND_TOOLTIP": "Runde et tal op eller ned.",
                +	"MATH_ROUND_OPERATOR_ROUND": "afrund",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "rund op",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "rund ned",
                +	"MATH_ONLIST_OPERATOR_SUM": "summen af listen",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Returner summen af alle tal i listen.",
                +	"MATH_ONLIST_OPERATOR_MIN": "mindste tal i listen",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Returner det mindste tal i listen.",
                +	"MATH_ONLIST_OPERATOR_MAX": "største tal i listen",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Returner det største tal i listen.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "gennemsnit af listen",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Returner gennemsnittet (middelværdien) af de numeriske værdier i listen.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "listens median",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Returner listens median.",
                +	"MATH_ONLIST_OPERATOR_MODE": "listens typetal",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Returner en liste over de mest almindelige elementer på listen.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standardafvigelsen for listen",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Returner standardafvigelsen for listen.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "tilfældigt element fra listen",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Returner et tilfældigt element fra listen.",
                +	"MATH_MODULO_HELPURL": "https://da.wikipedia.org/wiki/Modulo",
                +	"MATH_MODULO_TITLE": "resten af %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Returner resten fra at dividere de to tal.",
                +	"MATH_CONSTRAIN_TITLE": "begræns %1 til mellem %2 og %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Begræns et tal til at være mellem de angivne grænser (inklusiv).",
                +	"MATH_RANDOM_INT_HELPURL": "https://da.wikipedia.org/wiki/Tilfældighedsgenerator",
                +	"MATH_RANDOM_INT_TITLE": "tilfældigt heltal mellem %1 og %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Returner et tilfældigt heltal mellem de to angivne grænser (inklusiv).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://da.wikipedia.org/wiki/Tilfældighedsgenerator",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "tilfældigt decimaltal (mellem 0 og 1)",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Returner et tilfældigt decimaltal mellem 0,0 (inklusiv) og 1,0 (eksklusiv).",
                +	"TEXT_TEXT_HELPURL": "https://da.wikipedia.org/wiki/Tekststreng",
                +	"TEXT_TEXT_TOOLTIP": "En bogstav, et ord eller en linje med tekst.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "lav en tekst med",
                +	"TEXT_JOIN_TOOLTIP": "Lav et stykke tekst ved at sætte et antal elementer sammen.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "sammenføj",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne tekstblok.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Føj et element til teksten.",
                +	"TEXT_APPEND_TITLE": "til %1 tilføj tekst %2",
                +	"TEXT_APPEND_TOOLTIP": "Tilføj noget tekst til variablen '%1'.",
                +	"TEXT_LENGTH_TITLE": "længden af %1",
                +	"TEXT_LENGTH_TOOLTIP": "Returnerer antallet af bogstaver (herunder mellemrum) i den angivne tekst.",
                +	"TEXT_ISEMPTY_TITLE": "%1 er tom",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returnerer sand, hvis den angivne tekst er tom.",
                +	"TEXT_INDEXOF_TOOLTIP": "Returnerer indeks for første/sidste forekomst af første tekst i den anden tekst.  Returnerer %1, hvis teksten ikke kan findes.",
                +	"TEXT_INDEXOF_TITLE": "i tekst %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "find første forekomst af teksten",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "find sidste forekomst af teksten",
                +	"TEXT_CHARAT_TITLE": "i tekst %1 %2",
                +	"TEXT_CHARAT_FROM_START": "hent bogstav #",
                +	"TEXT_CHARAT_FROM_END": "hent bogstav # fra slutningen",
                +	"TEXT_CHARAT_FIRST": "hent første bogstav",
                +	"TEXT_CHARAT_LAST": "hent sidste bogstav",
                +	"TEXT_CHARAT_RANDOM": "hent tilfældigt bogstav",
                +	"TEXT_CHARAT_TOOLTIP": "Returnerer bogstavet på den angivne placering.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returnerer den angivne del af teksten.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "i teksten",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "hent delstreng fra bogstav #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "hent delstreng fra bogstav # fra slutningen",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "hent delstreng fra første bogstav",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "til bogstav #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "til bogstav # fra slutningen",
                +	"TEXT_GET_SUBSTRING_END_LAST": "til sidste bogstav",
                +	"TEXT_CHANGECASE_TOOLTIP": "Returner en kopi af teksten hvor bogstaverne enten er udelukkende store eller små, eller hvor første bogstav i hvert ord er stort.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "til STORE BOGSTAVER",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "til små bogstaver",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "til Stort Begyndelsesbogstav",
                +	"TEXT_TRIM_TOOLTIP": "Returner en kopi af teksten med mellemrum fjernet fra den ene eller begge sider.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "fjern mellemrum fra begge sider af",
                +	"TEXT_TRIM_OPERATOR_LEFT": "fjern mellemrum fra venstre side af",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "fjern mellemrum fra højre side af",
                +	"TEXT_PRINT_TITLE": "skriv %1",
                +	"TEXT_PRINT_TOOLTIP": "Skriv den angivne tekst, tal eller anden værdi.",
                +	"TEXT_PROMPT_TYPE_TEXT": "spørg efter tekst med meddelelsen",
                +	"TEXT_PROMPT_TYPE_NUMBER": "spørg efter et tal med meddelelsen",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Spørg brugeren efter et tal",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Spørg brugeren efter en tekst",
                +	"TEXT_COUNT_MESSAGE0": "tæl %1 i %2",
                +	"TEXT_COUNT_TOOLTIP": "Tæl hvor mange gange noget tekst fremgår i en anden tekst.",
                +	"TEXT_REPLACE_MESSAGE0": "erstat %1 med %2 i %3",
                +	"TEXT_REPLACE_TOOLTIP": "Erstat alle forekomster af noget tekst i en anden tekst.",
                +	"TEXT_REVERSE_MESSAGE0": "vend %1 om",
                +	"TEXT_REVERSE_TOOLTIP": "Vender rækkefølgen om for tegnene i teksten.",
                +	"LISTS_CREATE_EMPTY_TITLE": "opret en tom liste",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Returnerer en liste af længde 0, som ikke indeholder nogen data",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Opret en liste med et vilkårligt antal elementer.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "opret liste med",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "liste",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Tilføj, fjern eller byt om på rækkefølgen af delene for at konfigurere denne blok.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Føj et element til listen.",
                +	"LISTS_REPEAT_TOOLTIP": "Opretter en liste bestående af den givne værdi gentaget et bestemt antal gange.",
                +	"LISTS_REPEAT_TITLE": "opret liste med elementet %1 gentaget %2 gange",
                +	"LISTS_LENGTH_TITLE": "længden af %1",
                +	"LISTS_LENGTH_TOOLTIP": "Returnerer længden af en liste.",
                +	"LISTS_ISEMPTY_TITLE": "%1 er tom",
                +	"LISTS_ISEMPTY_TOOLTIP": "Returnerer sand, hvis listen er tom.",
                +	"LISTS_INLIST": "i listen",
                +	"LISTS_INDEX_OF_FIRST": "find første forekomst af elementet",
                +	"LISTS_INDEX_OF_LAST": "find sidste forekomst af elementet",
                +	"LISTS_INDEX_OF_TOOLTIP": "Returnerer indeks for første/sidste forekomst af elementet i listen. Returnerer %1, hvis elementet ikke kan findes.",
                +	"LISTS_GET_INDEX_GET": "hent",
                +	"LISTS_GET_INDEX_GET_REMOVE": "hent og fjern",
                +	"LISTS_GET_INDEX_REMOVE": "fjern",
                +	"LISTS_GET_INDEX_FROM_END": "# fra slutningen",
                +	"LISTS_GET_INDEX_FIRST": "første",
                +	"LISTS_GET_INDEX_LAST": "sidste",
                +	"LISTS_GET_INDEX_RANDOM": "tilfældig",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 er det første element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 er det sidste element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Returnerer elementet på den angivne position på en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Returnerer det første element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Returnerer den sidste element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Returnerer et tilfældigt element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Fjerner og returnerer elementet på den angivne position på en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Fjerner og returnerer det første element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Fjerner og returnerer det sidste element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Fjerner og returnerer et tilfældigt element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Fjerner elementet på den angivne position på en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Fjerner det første element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Fjerner sidste element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Fjerner et tilfældigt element i en liste.",
                +	"LISTS_SET_INDEX_SET": "sæt",
                +	"LISTS_SET_INDEX_INSERT": "indsæt ved",
                +	"LISTS_SET_INDEX_INPUT_TO": "som",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Sætter elementet på den angivne position i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Sætter det første element i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Sætter det sidste element i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Sætter et tilfældigt element i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Indsætter elementet på den angivne position i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Indsætter elementet i starten af en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Føj elementet til slutningen af en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Indsætter elementet tilfældigt i en liste.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "hent underliste fra #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "hent underliste fra # fra slutningen",
                +	"LISTS_GET_SUBLIST_START_FIRST": "hent underliste fra første",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "til #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "til # fra slutningen",
                +	"LISTS_GET_SUBLIST_END_LAST": "til sidste",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Opretter en kopi af den angivne del af en liste.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sorter %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sorter en kopi af en liste.",
                +	"LISTS_SORT_ORDER_ASCENDING": "stigende",
                +	"LISTS_SORT_ORDER_DESCENDING": "faldende",
                +	"LISTS_SORT_TYPE_NUMERIC": "nummerorden",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetisk",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetisk, ignorer store/små bogstaver",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "lav tekst til liste",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "lav liste til tekst",
                +	"LISTS_SPLIT_WITH_DELIMITER": "med skilletegn",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Bryd tekst op i en liste af tekster med brud ved hvert skilletegn.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Saml en liste af tekster til én tekst, der er adskilt af et skilletegn.",
                +	"LISTS_REVERSE_MESSAGE0": "vend %1 om",
                +	"LISTS_REVERSE_TOOLTIP": "Vend en kopi af en liste om.",
                +	"VARIABLES_GET_TOOLTIP": "Returnerer værdien af denne variabel.",
                +	"VARIABLES_GET_CREATE_SET": "Opret 'sæt %1'",
                +	"VARIABLES_SET": "sæt %1 til %2",
                +	"VARIABLES_SET_TOOLTIP": "Sætter denne variabel til at være lig med input.",
                +	"VARIABLES_SET_CREATE_GET": "Opret 'hent %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "for at",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "gøre noget",
                +	"PROCEDURES_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Opretter en funktion der ikke har nogen returværdi.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Beskriv denne funktion...",
                +	"PROCEDURES_DEFRETURN_RETURN": "returnér",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Opretter en funktion der har en returværdi.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "tillad erklæringer",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Advarsel: Denne funktion har dublerede parametre.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Kør den brugerdefinerede funktion '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Kør den brugerdefinerede funktion '%1' og brug dens returværdi.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "parametre",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Tilføje, fjerne eller ændre rækkefølgen af parametre til denne funktion.",
                +	"PROCEDURES_MUTATORARG_TITLE": "parameternavn:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Tilføj en parameter til funktionen.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Markér funktionsdefinitionen",
                +	"PROCEDURES_CREATE_DO": "Opret '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Hvis en værdi er sand, så returnér en anden værdi.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Advarsel: Denne blok kan kun anvendes inden for en funktionsdefinition."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/de.json b/blockly/webif/static/blockly/msg/json/de.json
                new file mode 100644
                index 000000000..4f18b2776
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/de.json
                @@ -0,0 +1,377 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Metalhead64",
                +			"M165437",
                +			"Dan-yell",
                +			"아라",
                +			"Octycs",
                +			"Cvanca",
                +			"THINK",
                +			"Zgtm"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "etwas",
                +	"TODAY": "Heute",
                +	"DUPLICATE_BLOCK": "Kopieren",
                +	"ADD_COMMENT": "Kommentar hinzufügen",
                +	"REMOVE_COMMENT": "Kommentar entfernen",
                +	"EXTERNAL_INPUTS": "externe Eingänge",
                +	"INLINE_INPUTS": "interne Eingänge",
                +	"DELETE_BLOCK": "Baustein löschen",
                +	"DELETE_X_BLOCKS": "%1 Bausteine löschen",
                +	"DELETE_ALL_BLOCKS": "Alle %1 Bausteine löschen?",
                +	"CLEAN_UP": "Bausteine aufräumen",
                +	"COLLAPSE_BLOCK": "Baustein zusammenfalten",
                +	"COLLAPSE_ALL": "Alle Bausteine zusammenfalten",
                +	"EXPAND_BLOCK": "Baustein entfalten",
                +	"EXPAND_ALL": "Alle Bausteine entfalten",
                +	"DISABLE_BLOCK": "Baustein deaktivieren",
                +	"ENABLE_BLOCK": "Baustein aktivieren",
                +	"HELP": "Hilfe",
                +	"UNDO": "Rückgängig",
                +	"REDO": "Wiederholen",
                +	"CHANGE_VALUE_TITLE": "Wert ändern:",
                +	"RENAME_VARIABLE": "Variable umbenennen …",
                +	"RENAME_VARIABLE_TITLE": "Alle \"%1\" Variablen umbenennen in:",
                +	"NEW_VARIABLE": "Variable erstellen …",
                +	"NEW_VARIABLE_TITLE": "Name der neuen Variable:",
                +	"VARIABLE_ALREADY_EXISTS": "Eine Variable namens „%1“ ist bereits vorhanden.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Eine Variable namens „%1“ ist bereits für eine andere Variable des Typs „%2“ vorhanden.",
                +	"PROCEDURE_ALREADY_EXISTS": "Eine Prozedur namens „%1“ ist bereits vorhanden.",
                +	"DELETE_VARIABLE_CONFIRMATION": "%1 Verwendungen der Variable „%2“ löschen?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Die Variable „%1“ kann nicht gelöscht werden, da sie Teil der Definition der Funktion „%2“ ist.",
                +	"DELETE_VARIABLE": "Die Variable „%1“ löschen",
                +	"COLOUR_PICKER_HELPURL": "https://de.wikipedia.org/wiki/Farbe",
                +	"COLOUR_PICKER_TOOLTIP": "Erzeugt eine Farbe aus der Palette.",
                +	"COLOUR_RANDOM_TITLE": "zufällige Farbe",
                +	"COLOUR_RANDOM_TOOLTIP": "Erzeugt eine Farbe nach dem Zufallsprinzip.",
                +	"COLOUR_RGB_HELPURL": "https://de.wikipedia.org/wiki/RGB-Farbraum",
                +	"COLOUR_RGB_TITLE": "Farbe aus",
                +	"COLOUR_RGB_RED": "rot",
                +	"COLOUR_RGB_GREEN": "grün",
                +	"COLOUR_RGB_BLUE": "blau",
                +	"COLOUR_RGB_TOOLTIP": "Erzeugt eine Farbe mit selbst definierten Rot-, Grün- und Blauwerten. Alle Werte müssen zwischen 0 und 100 liegen.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "mische",
                +	"COLOUR_BLEND_COLOUR1": "Farbe 1",
                +	"COLOUR_BLEND_COLOUR2": "und Farbe 2",
                +	"COLOUR_BLEND_RATIO": "im Verhältnis",
                +	"COLOUR_BLEND_TOOLTIP": "Vermischt 2 Farben mit konfigurierbarem Farbverhältnis (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://de.wikipedia.org/wiki/For-Schleife",
                +	"CONTROLS_REPEAT_TITLE": "wiederhole %1 mal:",
                +	"CONTROLS_REPEAT_INPUT_DO": "mache",
                +	"CONTROLS_REPEAT_TOOLTIP": "Eine Anweisung mehrfach ausführen.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://de.wikipedia.org/wiki/Schleife_%28Programmierung%29",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "wiederhole solange",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "wiederhole bis",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Führt Anweisungen aus solange die Bedingung wahr ist.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Führt Anweisungen aus solange die Bedingung unwahr ist.",
                +	"CONTROLS_FOR_HELPURL": "https://de.wikipedia.org/wiki/For-Schleife",
                +	"CONTROLS_FOR_TOOLTIP": "Zählt die Variable \"%1\" von einem Startwert bis zu einem Endwert und führt für jeden Wert eine Anweisung aus.",
                +	"CONTROLS_FOR_TITLE": "zähle %1 von %2 bis %3 in Schritten von %4",
                +	"CONTROLS_FOREACH_HELPURL": "https://de.wikipedia.org/wiki/For-Schleife",
                +	"CONTROLS_FOREACH_TITLE": "für jeden Wert %1 aus der Liste %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Führt eine Anweisung für jeden Wert in der Liste aus und setzt dabei die Variable \"%1\" auf den aktuellen Listenwert.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://de.wikipedia.org/wiki/Kontrollstruktur",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "die Schleife abbrechen",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "sofort mit nächstem Schleifendurchlauf fortfahren",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Die umgebende Schleife beenden.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Diese Anweisung abbrechen und mit dem nächsten Schleifendurchlauf fortfahren.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Warnung: Dieser Baustein kann nur in einer Schleife verwendet werden.",
                +	"CONTROLS_IF_TOOLTIP_1": "Führt eine Anweisung aus, falls eine Bedingung wahr ist.",
                +	"CONTROLS_IF_TOOLTIP_2": "Führt die erste Anweisung aus, falls eine Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus.",
                +	"CONTROLS_IF_TOOLTIP_3": "Führt die erste Anweisung aus, falls die erste Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus, falls die zweite Bedingung wahr ist.",
                +	"CONTROLS_IF_TOOLTIP_4": "Führe die erste Anweisung aus, falls die erste Bedingung wahr ist.  Führt ansonsten die zweite Anweisung aus, falls die zweite Bedingung wahr ist.  Führt die dritte Anweisung aus, falls keine der beiden Bedingungen wahr ist",
                +	"CONTROLS_IF_MSG_IF": "falls",
                +	"CONTROLS_IF_MSG_ELSEIF": "sonst falls",
                +	"CONTROLS_IF_MSG_ELSE": "sonst",
                +	"CONTROLS_IF_IF_TOOLTIP": "Hinzufügen, entfernen oder sortieren von Sektionen",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Eine weitere Bedingung hinzufügen.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Eine sonst-Bedingung hinzufügen. Führt eine Anweisung aus, falls keine Bedingung zutrifft.",
                +	"IOS_OK": "OKAY",
                +	"IOS_CANCEL": "Abbrechen",
                +	"IOS_ERROR": "Fehler",
                +	"IOS_PROCEDURES_INPUTS": "PARAMETER",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Parameter hinzufügen",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Anweisungen erlauben",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Diese Funktion hat doppelte Parameter.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Variable hinzufügen",
                +	"IOS_VARIABLES_ADD_BUTTON": "Hinzufügen",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Umbenennen",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Löschen",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Name der Variable",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Du kannst keinen leeren Variablennamen verwenden.",
                +	"LOGIC_COMPARE_HELPURL": "https://de.wikipedia.org/wiki/Vergleich_%28Zahlen%29",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Ist wahr, falls beide Werte gleich sind.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Ist wahr, falls beide Werte unterschiedlich sind.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Ist wahr, falls der erste Wert kleiner als der zweite Wert ist.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Ist wahr, falls der erste Wert kleiner als oder gleich groß wie der zweite Wert ist.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Ist wahr, falls der erste Wert größer als der zweite Wert ist.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Ist wahr, falls der erste Wert größer als oder gleich groß wie der zweite Wert ist.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Ist wahr, falls beide Werte wahr sind.",
                +	"LOGIC_OPERATION_AND": "und",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Ist wahr, falls einer der beiden Werte wahr ist.",
                +	"LOGIC_OPERATION_OR": "oder",
                +	"LOGIC_NEGATE_TITLE": "nicht %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Ist wahr, falls der Eingabewert unwahr ist.  Ist unwahr, falls der Eingabewert wahr ist.",
                +	"LOGIC_BOOLEAN_TRUE": "wahr",
                +	"LOGIC_BOOLEAN_FALSE": "unwahr",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Ist entweder wahr oder unwahr",
                +	"LOGIC_NULL_HELPURL": "https://de.wikipedia.org/wiki/Nullwert",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Ist \"null\".",
                +	"LOGIC_TERNARY_HELPURL": "https://de.wikipedia.org/wiki/%3F:#Auswahloperator",
                +	"LOGIC_TERNARY_CONDITION": "prüfe",
                +	"LOGIC_TERNARY_IF_TRUE": "falls wahr",
                +	"LOGIC_TERNARY_IF_FALSE": "falls unwahr",
                +	"LOGIC_TERNARY_TOOLTIP": "Überprüft eine Bedingung \"prüfe\". Falls die Bedingung wahr ist, wird der \"falls wahr\" Wert zurückgegeben, andernfalls der \"falls unwahr\" Wert",
                +	"MATH_NUMBER_HELPURL": "https://de.wikipedia.org/wiki/Zahl",
                +	"MATH_NUMBER_TOOLTIP": "Eine Zahl.",
                +	"MATH_ARITHMETIC_HELPURL": "https://de.wikipedia.org/wiki/Grundrechenart",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Ist die Summe zweier Zahlen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Ist die Differenz zweier Zahlen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Ist das Produkt zweier Zahlen.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Ist der Quotient zweier Zahlen.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Ist die erste Zahl potenziert mit der zweiten Zahl.",
                +	"MATH_SINGLE_HELPURL": "https://de.wikipedia.org/wiki/Quadratwurzel",
                +	"MATH_SINGLE_OP_ROOT": "Quadratwurzel",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Ist die Quadratwurzel einer Zahl.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "Betrag",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Ist der Betrag einer Zahl.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Negiert eine Zahl.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Ist der natürliche Logarithmus einer Zahl.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Ist der dekadische Logarithmus einer Zahl.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Ist Wert der Exponentialfunktion einer Zahl.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Rechnet 10 hoch eine Zahl.",
                +	"MATH_TRIG_HELPURL": "https://de.wikipedia.org/wiki/Trigonometrie",
                +	"MATH_TRIG_TOOLTIP_SIN": "Ist der Sinus des Winkels.",
                +	"MATH_TRIG_TOOLTIP_COS": "Ist der Kosinus des Winkels.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Ist der Tangens des Winkels.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Ist der Arkussinus des Eingabewertes.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Ist der Arkuskosinus des Eingabewertes.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Ist der Arkustangens des Eingabewertes.",
                +	"MATH_CONSTANT_HELPURL": "https://de.wikipedia.org/wiki/Mathematische_Konstante",
                +	"MATH_CONSTANT_TOOLTIP": "Mathematische Konstanten wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).",
                +	"MATH_IS_EVEN": "ist gerade",
                +	"MATH_IS_ODD": "ist ungerade",
                +	"MATH_IS_PRIME": "ist eine Primzahl",
                +	"MATH_IS_WHOLE": "ist eine ganze Zahl",
                +	"MATH_IS_POSITIVE": "ist positiv",
                +	"MATH_IS_NEGATIVE": "ist negativ",
                +	"MATH_IS_DIVISIBLE_BY": "ist teilbar durch",
                +	"MATH_IS_TOOLTIP": "Überprüft ob eine Zahl gerade, ungerade, eine Primzahl, ganzzahlig, positiv, negativ oder durch eine zweite Zahl teilbar ist.  Gibt wahr oder unwahr zurück.",
                +	"MATH_CHANGE_HELPURL": "https://de.wikipedia.org/wiki/Inkrement_und_Dekrement",
                +	"MATH_CHANGE_TITLE": "erhöhe %1 um %2",
                +	"MATH_CHANGE_TOOLTIP": "Addiert eine Zahl zu \"%1\".",
                +	"MATH_ROUND_HELPURL": "https://de.wikipedia.org/wiki/Runden",
                +	"MATH_ROUND_TOOLTIP": "Eine Zahl auf- oder abrunden.",
                +	"MATH_ROUND_OPERATOR_ROUND": "runde",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "runde auf",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "runde ab",
                +	"MATH_ONLIST_HELPURL": "http://www.sysplus.ch/einstieg.php?links=menu&seite=4125&grad=Crash&prog=Excel",
                +	"MATH_ONLIST_OPERATOR_SUM": "Summe über die Liste",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Ist die Summe aller Zahlen in einer Liste.",
                +	"MATH_ONLIST_OPERATOR_MIN": "Minimalwert der Liste",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Ist die kleinste Zahl in einer Liste.",
                +	"MATH_ONLIST_OPERATOR_MAX": "Maximalwert der Liste",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Ist die größte Zahl in einer Liste.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "Mittelwert der Liste",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Ist der Durchschnittswert aller Zahlen in einer Liste.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Median der Liste",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Ist der Median aller Zahlen in einer Liste.",
                +	"MATH_ONLIST_OPERATOR_MODE": "am häufigsten in der Liste",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Findet die Werte mit dem häufigstem Vorkommen in der Liste.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "Standardabweichung der Liste",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Ist die Standardabweichung aller Werte in der Liste.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Zufallswert aus der Liste",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Gibt einen zufälligen Wert aus der Liste zurück.",
                +	"MATH_MODULO_HELPURL": "https://de.wikipedia.org/wiki/Modulo",
                +	"MATH_MODULO_TITLE": "Rest von %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Der Rest nach einer Division.",
                +	"MATH_CONSTRAIN_TITLE": "begrenze %1 zwischen %2 und %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Begrenzt eine Zahl auf den Wertebereich zwischen zwei anderen Zahlen (inklusiv).",
                +	"MATH_RANDOM_INT_HELPURL": "https://de.wikipedia.org/wiki/Zufallszahlen",
                +	"MATH_RANDOM_INT_TITLE": "ganzzahlige Zufallszahl zwischen %1 und %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Erzeugt eine ganzzahlige Zufallszahl zwischen zwei Zahlen (inklusiv).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://de.wikipedia.org/wiki/Zufallszahlen",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "Zufallszahl (0.0 - 1.0)",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Erzeugt eine Zufallszahl zwischen 0.0 (inklusiv) und 1.0 (exklusiv).",
                +	"TEXT_TEXT_HELPURL": "https://de.wikipedia.org/wiki/Zeichenkette",
                +	"TEXT_TEXT_TOOLTIP": "Ein Buchstabe, Text oder Satz.",
                +	"TEXT_JOIN_HELPURL": "",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "erstelle Text aus",
                +	"TEXT_JOIN_TOOLTIP": "Erstellt einen Text durch das Verbinden von mehreren Textelementen.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "verbinden",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Hinzufügen, entfernen und sortieren von Elementen.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Ein Element zum Text hinzufügen.",
                +	"TEXT_APPEND_TITLE": "zu %1 Text %2 anhängen",
                +	"TEXT_APPEND_TOOLTIP": "Text an die Variable \"%1\" anhängen.",
                +	"TEXT_LENGTH_TITLE": "Länge von %1",
                +	"TEXT_LENGTH_TOOLTIP": "Die Anzahl von Zeichen in einem Text (inkl. Leerzeichen).",
                +	"TEXT_ISEMPTY_TITLE": "%1 ist leer",
                +	"TEXT_ISEMPTY_TOOLTIP": "Ist wahr, falls der Text keine Zeichen enthält ist.",
                +	"TEXT_INDEXOF_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"TEXT_INDEXOF_TOOLTIP": "Findet das erste / letzte Auftreten eines Suchbegriffs in einem Text.  Gibt die Position des Begriffs zurück oder %1 falls der Suchbegriff nicht gefunden wurde.",
                +	"TEXT_INDEXOF_TITLE": "im Text %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "suche erstes Auftreten des Begriffs",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "suche letztes Auftreten des Begriffs",
                +	"TEXT_CHARAT_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"TEXT_CHARAT_TITLE": "im Text %1 %2",
                +	"TEXT_CHARAT_FROM_START": "nimm",
                +	"TEXT_CHARAT_FROM_END": "nimm von hinten",
                +	"TEXT_CHARAT_FIRST": "nimm ersten",
                +	"TEXT_CHARAT_LAST": "nimm letzten",
                +	"TEXT_CHARAT_RANDOM": "nimm zufälligen",
                +	"TEXT_CHARAT_TAIL": "Buchstaben",
                +	"TEXT_CHARAT_TOOLTIP": "Extrahiert einen Buchstaben von einer bestimmten Position.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Gibt den angegebenen Textabschnitt zurück.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "im Text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "nimm Teil ab",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "nimm Teil ab von hinten",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "nimm Teil ab erster",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "bis",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "bis von hinten",
                +	"TEXT_GET_SUBSTRING_END_LAST": "bis letzter",
                +	"TEXT_GET_SUBSTRING_TAIL": "Buchstabe",
                +	"TEXT_CHANGECASE_TOOLTIP": "Wandelt Schreibweise von Texten um, in Großbuchstaben, Kleinbuchstaben oder den ersten Buchstaben jedes Wortes groß und die anderen klein.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "wandel um in GROSSBUCHSTABEN",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "wandel um in kleinbuchstaben",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "wandel um in Substantive",
                +	"TEXT_TRIM_TOOLTIP": "Entfernt Leerzeichen vom Anfang und / oder Ende eines Textes.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "entferne Leerzeichen vom Anfang und vom Ende (links und rechts)",
                +	"TEXT_TRIM_OPERATOR_LEFT": "entferne Leerzeichen vom Anfang (links)",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "entferne Leerzeichen vom Ende (rechts)",
                +	"TEXT_PRINT_TITLE": "gib aus %1",
                +	"TEXT_PRINT_TOOLTIP": "Gibt den Text aus.",
                +	"TEXT_PROMPT_TYPE_TEXT": "frage nach Text mit Hinweis",
                +	"TEXT_PROMPT_TYPE_NUMBER": "frage nach Zahl mit Hinweis",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Fragt den Benutzer nach einer Zahl.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Fragt den Benutzer nach einem Text.",
                +	"TEXT_COUNT_MESSAGE0": "zähle %1 in %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Zähle, wie oft ein Text innerhalb eines anderen Textes vorkommt.",
                +	"TEXT_REPLACE_MESSAGE0": "ersetze %1 durch %2 in %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Ersetze alle Vorkommen eines Textes innerhalb eines anderen Textes.",
                +	"TEXT_REVERSE_MESSAGE0": "kehre %1 um",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Kehre die Reihenfolge der Zeichen im Text um.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "erzeuge eine leere Liste",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Erzeugt eine leere Liste ohne Inhalt.",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Erzeugt eine Liste aus den angegebenen Elementen.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "erzeuge Liste mit",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "Liste",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Hinzufügen, entfernen und sortieren von Elementen.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Ein Element zur Liste hinzufügen.",
                +	"LISTS_REPEAT_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"LISTS_REPEAT_TOOLTIP": "Erzeugt eine Liste mit einer variablen Anzahl von Elementen",
                +	"LISTS_REPEAT_TITLE": "erzeuge Liste mit %2 mal dem Element %1​",
                +	"LISTS_LENGTH_TITLE": "Länge von %1",
                +	"LISTS_LENGTH_TOOLTIP": "Die Anzahl von Elementen in der Liste.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ist leer",
                +	"LISTS_ISEMPTY_TOOLTIP": "Ist wahr, falls die Liste leer ist.",
                +	"LISTS_INLIST": "in der Liste",
                +	"LISTS_INDEX_OF_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"LISTS_INDEX_OF_FIRST": "suche erstes Auftreten von",
                +	"LISTS_INDEX_OF_LAST": "suche letztes Auftreten von",
                +	"LISTS_INDEX_OF_TOOLTIP": "Sucht die Position (Index) eines Elementes in der Liste. Gibt %1 zurück, falls kein Element gefunden wurde.",
                +	"LISTS_GET_INDEX_GET": "nimm",
                +	"LISTS_GET_INDEX_GET_REMOVE": "nimm und entferne",
                +	"LISTS_GET_INDEX_REMOVE": "entferne",
                +	"LISTS_GET_INDEX_FROM_START": "das",
                +	"LISTS_GET_INDEX_FROM_END": "von hinten das",
                +	"LISTS_GET_INDEX_FIRST": "das erste",
                +	"LISTS_GET_INDEX_LAST": "das letzte",
                +	"LISTS_GET_INDEX_RANDOM": "ein zufälliges",
                +	"LISTS_GET_INDEX_TAIL": "Element",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ist das erste Element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ist das letzte Element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Extrahiert das Element an der angegebenen Position in der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Extrahiert das erste Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Extrahiert das letzte Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Extrahiert ein zufälliges Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Extrahiert und entfernt das Element an der angegebenen Position aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Extrahiert und entfernt das erste Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Extrahiert und entfernt das letzte Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Extrahiert und entfernt ein zufälliges Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Entfernt das Element an der angegebenen Position aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Entfernt das erste Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Entfernt das letzte Element aus der Liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Entfernt ein zufälliges Element aus der Liste.",
                +	"LISTS_SET_INDEX_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"LISTS_SET_INDEX_SET": "setze für",
                +	"LISTS_SET_INDEX_INSERT": "füge als",
                +	"LISTS_SET_INDEX_INPUT_TO": "ein",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Setzt das Element an der angegebenen Position in der Liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Setzt das erste Element in der Liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Setzt das letzte Element in die Liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Setzt ein zufälliges Element in der Liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Fügt das Element an der angegebenen Position in die Liste ein.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Fügt das Element an den Anfang der Liste an.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Fügt das Element ans Ende der Liste an.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Fügt das Element zufällig in die Liste ein.",
                +	"LISTS_GET_SUBLIST_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "nimm Teilliste ab",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "nimm Teilliste ab von hinten",
                +	"LISTS_GET_SUBLIST_START_FIRST": "nimm Teilliste ab erstes",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "bis",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "bis von hinten",
                +	"LISTS_GET_SUBLIST_END_LAST": "bis letztes",
                +	"LISTS_GET_SUBLIST_TAIL": "Element",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Erstellt eine Kopie mit dem angegebenen Abschnitt der Liste.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "%1 %2 %3 sortieren",
                +	"LISTS_SORT_TOOLTIP": "Eine Kopie einer Liste sortieren.",
                +	"LISTS_SORT_ORDER_ASCENDING": "aufsteigend",
                +	"LISTS_SORT_ORDER_DESCENDING": "absteigend",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerisch",
                +	"LISTS_SORT_TYPE_TEXT": "alphabetisch",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alphabetisch, Großschreibung ignorieren",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "Liste aus Text erstellen",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "Text aus Liste erstellen",
                +	"LISTS_SPLIT_WITH_DELIMITER": "mit Trennzeichen",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Text in eine Liste mit Texten aufteilen, unterbrochen bei jedem Trennzeichen.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Liste mit Texten in einen Text vereinen, getrennt durch ein Trennzeichen.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "kehre %1 um",
                +	"LISTS_REVERSE_TOOLTIP": "Kehre eine Kopie einer Liste um.",
                +	"ORDINAL_NUMBER_SUFFIX": ".",
                +	"VARIABLES_GET_HELPURL": "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29",
                +	"VARIABLES_GET_TOOLTIP": "Gibt den Wert der Variable zurück.",
                +	"VARIABLES_GET_CREATE_SET": "Erzeuge \"Schreibe %1\"",
                +	"VARIABLES_SET_HELPURL": "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29",
                +	"VARIABLES_SET": "setze %1 auf %2",
                +	"VARIABLES_SET_TOOLTIP": "Setzt den Wert einer Variable.",
                +	"VARIABLES_SET_CREATE_GET": "Erzeuge \"Lese %1\"",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "etwas tun",
                +	"PROCEDURES_BEFORE_PARAMS": "mit:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "mit:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Ein Funktionsblock ohne Rückgabewert.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Beschreibe diese Funktion …",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "gib zurück",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Ein Funktionsblock mit Rückgabewert.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Anweisungen erlauben",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Warnung: Dieser Funktionsblock hat zwei gleich benannte Parameter.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://de.wikipedia.org/wiki/Unterprogramm",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Rufe einen Funktionsblock ohne Rückgabewert auf.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://de.wikipedia.org/wiki/Unterprogramm",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Rufe einen Funktionsblock mit Rückgabewert auf.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "Parameter",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Die Eingaben zu dieser Funktion hinzufügen, entfernen oder neu anordnen.",
                +	"PROCEDURES_MUTATORARG_TITLE": "Variable:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Eine Eingabe zur Funktion hinzufügen.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Markiere Funktionsblock",
                +	"PROCEDURES_CREATE_DO": "Erzeuge \"Aufruf %1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Gibt den zweiten Wert zurück und verlässt die Funktion, falls der erste Wert wahr ist.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Warnung: Dieser Block darf nur innerhalb eines Funktionsblocks genutzt werden."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/diq.json b/blockly/webif/static/blockly/msg/json/diq.json
                new file mode 100644
                index 000000000..711e0ad28
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/diq.json
                @@ -0,0 +1,185 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Kumkumuk",
                +			"Marmase",
                +			"Mirzali",
                +			"Gırd"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "unsur",
                +	"TODAY": "Ewro",
                +	"DUPLICATE_BLOCK": "Zewnc",
                +	"ADD_COMMENT": "Tefsir cı ke",
                +	"REMOVE_COMMENT": "Tefsiri Wedare",
                +	"EXTERNAL_INPUTS": "Cıkewtışê xarıciy",
                +	"INLINE_INPUTS": "Cıkerdışê xomiyani",
                +	"DELETE_BLOCK": "Bloki bestere",
                +	"DELETE_X_BLOCKS": "%1 blokan bestere",
                +	"DELETE_ALL_BLOCKS": "Pêro %1 bloki besteriyê?",
                +	"CLEAN_UP": "Blokan pak ke",
                +	"COLLAPSE_BLOCK": "Bloki teng ke",
                +	"COLLAPSE_ALL": "Blokan teng ke",
                +	"EXPAND_BLOCK": "Bloki hera ke",
                +	"EXPAND_ALL": "Blokan hera ke",
                +	"DISABLE_BLOCK": "Çengi devre ra vec",
                +	"ENABLE_BLOCK": "Bloki feal ke",
                +	"HELP": "Peşti",
                +	"UNDO": "Peyser biya",
                +	"REDO": "Newe ke",
                +	"CHANGE_VALUE_TITLE": "Erci bıvurne:",
                +	"RENAME_VARIABLE": "Vuriyayey fına name ke...",
                +	"RENAME_VARIABLE_TITLE": "Pêro vırnayışê '%1' reyna name ke:",
                +	"NEW_VARIABLE": "Vuriyayeyo bıvıraz...",
                +	"NEW_VARIABLE_TITLE": "Namey vuriyayeyê newi:",
                +	"VARIABLE_ALREADY_EXISTS": "Yew vırnayış be namey '%1' xora est.",
                +	"DELETE_VARIABLE_CONFIRMATION": "%1 ke vırnayışê '%2'i gırweneno, besteriyo?",
                +	"DELETE_VARIABLE": "Şıma vırnaoğê '%1'i besterê",
                +	"COLOUR_PICKER_HELPURL": "https://diq.wikipedia.org/wiki/Reng",
                +	"COLOUR_PICKER_TOOLTIP": "Şıma palet ra yew reng weçinê.",
                +	"COLOUR_RANDOM_TITLE": "rengo rastameye",
                +	"COLOUR_RANDOM_TOOLTIP": "Tesadufi yu ren bıweçin",
                +	"COLOUR_RGB_TITLE": "komponentên rengan",
                +	"COLOUR_RGB_RED": "sur",
                +	"COLOUR_RGB_GREEN": "kıho",
                +	"COLOUR_RGB_BLUE": "kewe",
                +	"COLOUR_RGB_TOOLTIP": "Şıma renganê sûr, aşıl u kohoy ra rengê do spesifik vırazê. Gani ê pêro 0 u 100 miyan de bıbê.",
                +	"COLOUR_BLEND_TITLE": "tewde",
                +	"COLOUR_BLEND_COLOUR1": "reng 1",
                +	"COLOUR_BLEND_COLOUR2": "reng 2",
                +	"COLOUR_BLEND_RATIO": "nısbet",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "%1 fıni tekrar ke",
                +	"CONTROLS_REPEAT_INPUT_DO": "bıke",
                +	"CONTROLS_REPEAT_TOOLTIP": "Şıma tayêna reyi akerdışi kerê.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "Tekrar kerdış de",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "hend tekrar ke",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Yew erc raşto se yu beyanat bıd.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Yew erc xırabo se tay beyanati bıd",
                +	"CONTROLS_FOREACH_TITLE": "Lista %2 de her item %1 rê",
                +	"CONTROLS_FOREACH_TOOLTIP": "Yew lista de her item rê, varyansê '%1' itemi rê vırazê, u dıma tayê akerdışi (beyani) bıdê",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "Çerxen ra vec",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "Gama bin da çerxeni ra dewam ke",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Öujtewada çerxeni ra bıvıci",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Diqat: No bloke şeno teyna yew çerxiyayış miyan de bıgırweyo.",
                +	"CONTROLS_IF_TOOLTIP_1": "Eger yew vaye raşto, o taw şıma tayê akerdışi kerê.",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "niyose",
                +	"CONTROLS_IF_MSG_ELSE": "çıniyose",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Bloq da if'i rê yu şert dekerê de.",
                +	"IOS_OK": "TEMAM",
                +	"IOS_CANCEL": "Bıtexelne",
                +	"IOS_ERROR": "Xeta",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Bestere",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Eger her dı cıkewtışi zi raştê, şıma ageyrê.",
                +	"LOGIC_OPERATION_AND": "û",
                +	"LOGIC_OPERATION_OR": "ya zi",
                +	"LOGIC_NEGATE_TITLE": "%1 niyo",
                +	"LOGIC_BOOLEAN_TRUE": "raşt",
                +	"LOGIC_BOOLEAN_FALSE": "ğelet",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Raşt yana çep erc dano",
                +	"LOGIC_NULL": "veng",
                +	"LOGIC_NULL_TOOLTIP": "Veng çarneno ra.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "eke raşto",
                +	"LOGIC_TERNARY_IF_FALSE": "eke ğeleto",
                +	"LOGIC_TERNARY_TOOLTIP": "Şerta'test'i test keno.  Eger ke şert raşta se erca 'raşt'i çarneno, çepo se erca 'çep'  çarneno.",
                +	"MATH_NUMBER_HELPURL": "https://diq.wikipedia.org/wiki/Numre",
                +	"MATH_NUMBER_TOOLTIP": "Yew numre.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Aritmetik",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "karekok",
                +	"MATH_SINGLE_OP_ABSOLUTE": "mutlaq",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Ena amorer nêravêrde deyne çerx ke.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Heryen sabitan ra yewi çerx ke:π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (bêsonp).",
                +	"MATH_IS_EVEN": "zewnco",
                +	"MATH_IS_ODD": "kıto",
                +	"MATH_IS_PRIME": "bıngehên",
                +	"MATH_IS_WHOLE": "tamo",
                +	"MATH_IS_POSITIVE": "pozitifo",
                +	"MATH_IS_NEGATIVE": "negatifo",
                +	"MATH_IS_DIVISIBLE_BY": "Leteyêno",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%2, keno %1 vurneno",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Yu amorer loğê cêri yana cori ke",
                +	"MATH_ROUND_OPERATOR_ROUND": "gılor ke",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Loğê cori ke",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "Loğê cêri ke",
                +	"MATH_ONLIST_OPERATOR_SUM": "koma liste",
                +	"MATH_ONLIST_OPERATOR_MIN": "Tewr qıcê lista",
                +	"MATH_ONLIST_OPERATOR_MAX": "Tewr gırdê lista",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "Averacê lista",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Wertey lista",
                +	"MATH_ONLIST_OPERATOR_MODE": "listey modi",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Raştamaye objeya lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Liste ra raştamaye yew elementi çerx ke",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 ra menden",
                +	"MATH_MODULO_TOOLTIP": "Dı amoran ra amora menden çerx ke",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "Raştamaye nimande amor",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Yu herfa,  satır yana çekuya metini",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ya metin vıraz",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "gıre de",
                +	"TEXT_ISEMPTY_TITLE": "%1 vengo",
                +	"TEXT_CHARAT_FROM_START": "Herfa # bıgi",
                +	"TEXT_CHARAT_FROM_END": "# ra tepya herfan bıgi",
                +	"TEXT_CHARAT_FIRST": "Herfa sıfti bıgi",
                +	"TEXT_CHARAT_LAST": "Herfa peyên bıgi",
                +	"TEXT_CHARAT_RANDOM": "Raştamaye yu herf bıgi",
                +	"TEXT_CHARAT_TOOLTIP": "Şınasnaye pozisyon de yu herfer çerğ keno",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Tay letey metini çerğ keno",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "metın de",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "# ra substring gêno",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "HERFANÊ GIRDANA",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "Herfanê werdiyana",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Ser herf gırd",
                +	"LISTS_CREATE_EMPTY_TITLE": "lista venge vıraze",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "Liste ya vıraz",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "liste",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Yew nesne dekerê lista miyan",
                +	"LISTS_LENGTH_TOOLTIP": "Derganiya yu lister dano.",
                +	"LISTS_ISEMPTY_TITLE": "%1 vengo",
                +	"LISTS_ISEMPTY_TOOLTIP": "Eger kı lista venga se raşt keno çerğ",
                +	"LISTS_INLIST": "lista de",
                +	"LISTS_INDEX_OF_FIRST": "Sıfte bıyayena cay obcey bıvin",
                +	"LISTS_GET_INDEX_GET": "bıgê",
                +	"LISTS_GET_INDEX_GET_REMOVE": "Bıgi u wedarne",
                +	"LISTS_GET_INDEX_REMOVE": "wedare",
                +	"LISTS_GET_INDEX_FROM_END": "# peyniye ra",
                +	"LISTS_GET_INDEX_FIRST": "verên",
                +	"LISTS_GET_INDEX_LAST": "peyên",
                +	"LISTS_GET_INDEX_RANDOM": "raştameye",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 objeyo sıfteyên o",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 objeyo peyên o",
                +	"LISTS_SET_INDEX_SET": "ca ke",
                +	"LISTS_SET_INDEX_INSERT": "De fi",
                +	"LISTS_SET_INDEX_INPUT_TO": "zey",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "#'ya",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "Peyni # ra hetana",
                +	"LISTS_GET_SUBLIST_END_LAST": "Hetana pey",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "Kılm %1 %2 %3",
                +	"LISTS_SORT_ORDER_ASCENDING": "zeydıyen",
                +	"LISTS_SORT_ORDER_DESCENDING": "Kemeyen",
                +	"LISTS_SORT_TYPE_NUMERIC": "Amoriyal",
                +	"LISTS_SORT_TYPE_TEXT": "Alfabetik",
                +	"LISTS_SPLIT_WITH_DELIMITER": "Hududoxi ya",
                +	"VARIABLES_SET_CREATE_GET": "'get %1' vıraz",
                +	"PROCEDURES_DEFNORETURN_TITLE": "rê",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "Çıyê bık",
                +	"PROCEDURES_BEFORE_PARAMS": "ebe:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ebe:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Yew fonksiyono çap nêdate vırazeno",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Nê fonksiyoni beyan ke...",
                +	"PROCEDURES_DEFRETURN_RETURN": "peyser biya",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Yew fonksiyono çap daye vırazeno",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Çıyan rê mısafe bıd",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "cıkewtışi",
                +	"PROCEDURES_MUTATORARG_TITLE": "namey cıkewtışi:",
                +	"PROCEDURES_CREATE_DO": "'%1' vıraze"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/el.json b/blockly/webif/static/blockly/msg/json/el.json
                new file mode 100644
                index 000000000..a1dd248e9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/el.json
                @@ -0,0 +1,341 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Azountas",
                +			"Espertus",
                +			"Evropi",
                +			"Namatreasure",
                +			"Sfyrakis",
                +			"Glavkos",
                +			"Gchr",
                +			"아라",
                +			"Geraki",
                +			"Ανώνυμος Βικιπαιδιστής",
                +			"GR",
                +			"Stam.nikos",
                +			"Themelis"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "αντικείμενο",
                +	"TODAY": "Σήμερα",
                +	"DUPLICATE_BLOCK": "Διπλότυπο",
                +	"ADD_COMMENT": "Πρόσθεσε Το Σχόλιο",
                +	"REMOVE_COMMENT": "Αφαίρεσε Το Σχόλιο",
                +	"EXTERNAL_INPUTS": "Εξωτερικές Είσοδοι",
                +	"INLINE_INPUTS": "Εσωτερικές Είσοδοι",
                +	"DELETE_BLOCK": "Διάγραψε Το Μπλοκ",
                +	"DELETE_X_BLOCKS": "Διάγραψε %1 Μπλοκ",
                +	"DELETE_ALL_BLOCKS": "Να διαγραφούν και τα %1 μπλοκ;",
                +	"COLLAPSE_BLOCK": "Σύμπτυξε Το Μπλοκ",
                +	"COLLAPSE_ALL": "Σύμπτυξε Όλα Τα Μπλοκ",
                +	"EXPAND_BLOCK": "Επέκτεινε Το Μπλοκ",
                +	"EXPAND_ALL": "Επέκτεινε Όλα Τα Μπλοκ",
                +	"DISABLE_BLOCK": "Απενεργοποίησε Το Μπλοκ",
                +	"ENABLE_BLOCK": "Ενεργοποίησε Το Μπλοκ",
                +	"HELP": "Βοήθεια",
                +	"UNDO": "Αναίρεση",
                +	"REDO": "Ακύρωση αναίρεσης",
                +	"CHANGE_VALUE_TITLE": "Άλλαξε την τιμή:",
                +	"RENAME_VARIABLE": "Μετονόμασε τη μεταβλητή...",
                +	"RENAME_VARIABLE_TITLE": "Μετονόμασε όλες τις μεταβλητές «%1» σε:",
                +	"NEW_VARIABLE": "Νέα μεταβλητή...",
                +	"NEW_VARIABLE_TITLE": "Νέο όνομα μεταβλητής:",
                +	"VARIABLE_ALREADY_EXISTS": "Η μεταβλητή με το όνομα \"%1\" υπάρχει ήδη",
                +	"COLOUR_PICKER_HELPURL": "https://el.wikipedia.org/wiki/%CE%A7%CF%81%CF%8E%CE%BC%CE%B1",
                +	"COLOUR_PICKER_TOOLTIP": "Επιτρέπει επιλογή χρώματος από την παλέτα.",
                +	"COLOUR_RANDOM_TITLE": "τυχαίο χρώμα",
                +	"COLOUR_RANDOM_TOOLTIP": "Επιλέγει χρώμα τυχαία.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "χρώμα με",
                +	"COLOUR_RGB_RED": "κόκκινο",
                +	"COLOUR_RGB_GREEN": "πράσινο",
                +	"COLOUR_RGB_BLUE": "μπλε",
                +	"COLOUR_RGB_TOOLTIP": "Δημιουργεί χρώμα με το συγκεκριμένο ποσό του κόκκινου, πράσινου και μπλε που ορίζεις. Όλες οι τιμές πρέπει να είναι μεταξύ 0 και 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "μείγμα",
                +	"COLOUR_BLEND_COLOUR1": "χρώμα 1",
                +	"COLOUR_BLEND_COLOUR2": "χρώμα 2",
                +	"COLOUR_BLEND_RATIO": "αναλογία",
                +	"COLOUR_BLEND_TOOLTIP": "Συνδυάζει δύο χρώματα μαζί με μια δεδομένη αναλογία (0.0 - 1,0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "επανάλαβε %1 φορές",
                +	"CONTROLS_REPEAT_INPUT_DO": "κάνε",
                +	"CONTROLS_REPEAT_TOOLTIP": "Εκτελεί κάποιες εντολές αρκετές φορές.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "επανάλαβε ενώ",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "επανάλαβε μέχρι",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Ενόσω μια τιμή είναι αληθής, τότε εκτελεί κάποιες εντολές.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Ενόσω μια τιμή είναι ψευδής, τότε εκτελεί κάποιες εντολές.",
                +	"CONTROLS_FOR_HELPURL": "Blockly",
                +	"CONTROLS_FOR_TOOLTIP": "Η μεταβλητή «%1» παίρνει τιμές ξεκινώντας από τον αριθμό έναρξης μέχρι τον αριθμό τέλους αυξάνοντας κάθε φορά με το καθορισμένο βήμα και εκτελώντας το καθορισμένο μπλοκ.",
                +	"CONTROLS_FOR_TITLE": "μέτρησε με %1 από το %2 έως το %3 ανά %4",
                +	"CONTROLS_FOREACH_TITLE": "για κάθε στοιχείο %1 στη λίστα %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Για κάθε στοιχείο σε μια λίστα, ορίζει τη μεταβλητή «%1» στο στοιχείο και, στη συνέχεια, εκτελεί κάποιες εντολές.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "φεύγει από το μπλοκ επαναλήψεως",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "συνέχισε με την επόμενη επανάληψη του μπλοκ επαναλήψεως",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Ξεφεύγει (βγαίνει έξω) από την επανάληψη.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Παραλείπει το υπόλοιπο τμήμα αυτού του μπλοκ επαναλήψεως, και συνεχίζει με την επόμενη επανάληψη.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Προειδοποίηση: Αυτό το μπλοκ μπορεί να χρησιμοποιηθεί μόνο μέσα σε μια επανάληψη.",
                +	"CONTROLS_IF_TOOLTIP_1": "Αν μια τιμή είναι αληθής, τότε εκτελεί κάποιες εντολές.",
                +	"CONTROLS_IF_TOOLTIP_2": "Αν μια τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών. Διαφορετικά, εκτελεί το δεύτερο τμήμα εντολών.",
                +	"CONTROLS_IF_TOOLTIP_3": "Αν η πρώτη τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών. Διαφορετικά, αν η δεύτερη τιμή είναι αληθής, εκτελεί το δεύτερο μπλοκ εντολών.",
                +	"CONTROLS_IF_TOOLTIP_4": "Αν η πρώτη τιμή είναι αληθής, τότε εκτελεί το πρώτο τμήμα εντολών.  Διαφορετικά, αν η δεύτερη τιμή είναι αληθής, εκτελεί το δεύτερο τμήμα εντολών. Αν καμία από τις τιμές δεν είναι αληθής, εκτελεί το τελευταίο τμήμα εντολών.",
                +	"CONTROLS_IF_MSG_IF": "εάν",
                +	"CONTROLS_IF_MSG_ELSEIF": "εναλλακτικά εάν",
                +	"CONTROLS_IF_MSG_ELSE": "αλλιώς",
                +	"CONTROLS_IF_IF_TOOLTIP": "Προσθέτει, αφαιρεί ή αναδιατάσσει τα τμήματα για να αναδιαμορφώσει αυτό το μπλοκ «εάν».",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Πρόσθετει μια κατάσταση/συνθήκη στο μπλοκ «εάν».",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Προσθέτει μια τελική κατάσταση/συνθήκη, που πιάνει όλες τις άλλες περιπτώσεις, στο μπλοκ «εάν».",
                +	"IOS_OK": "ΟΚ",
                +	"IOS_ERROR": "Σφάλμα",
                +	"IOS_VARIABLES_ADD_BUTTON": "Προσθήκη",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Διαγραφή",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Επιστρέφει αληθής αν και οι δύο είσοδοι είναι ίσες μεταξύ τους.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Επιστρέφει αληθής αν και οι δύο είσοδοι δεν είναι ίσες μεταξύ τους.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη από τη δεύτερη είσοδο.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη από ή ίση με τη δεύτερη είσοδο.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μεγαλύτερη από τη δεύτερη είσοδο.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Επιστρέφει αληθής αν η πρώτη είσοδος είναι μικρότερη ή ίση με τη δεύτερη είσοδο.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Επιστρέφει αληθής αν και οι δύο είσοδοι είναι αληθής.",
                +	"LOGIC_OPERATION_AND": "και",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Επιστρέφει αληθής αν τουλάχιστον μια από τις εισόδους είναι αληθής.",
                +	"LOGIC_OPERATION_OR": "ή",
                +	"LOGIC_NEGATE_TITLE": "όχι %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Επιστρέφει αληθής αν η είσοδος είναι ψευδής. Επιστρέφει ψευδής αν η είσοδος είναι αληθής.",
                +	"LOGIC_BOOLEAN_TRUE": "αληθής",
                +	"LOGIC_BOOLEAN_FALSE": "ψευδής",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Επιστρέφει είτε αληθής είτε ψευδής.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "κενό",
                +	"LOGIC_NULL_TOOLTIP": "Επιστρέφει κενό.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "έλεγχος",
                +	"LOGIC_TERNARY_IF_TRUE": "εάν είναι αληθής",
                +	"LOGIC_TERNARY_IF_FALSE": "εάν είναι ψευδής",
                +	"LOGIC_TERNARY_TOOLTIP": "Ελέγχει την κατάσταση/συνθήκη στον «έλεγχο». Αν η κατάσταση/συνθήκη είναι αληθής, επιστρέφει την τιμή «εάν αληθής», διαφορετικά επιστρέφει την τιμή «εάν ψευδής».",
                +	"MATH_NUMBER_HELPURL": "https://el.wikipedia.org/wiki/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82",
                +	"MATH_NUMBER_TOOLTIP": "Ένας αριθμός.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^ ύψωση σε δύναμη",
                +	"MATH_TRIG_SIN": "ημ",
                +	"MATH_TRIG_COS": "συν",
                +	"MATH_TRIG_TAN": "εφ",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://el.wikipedia.org/wiki/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CE%B7%CF%84%CE%B9%CE%BA%CE%AE",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Επιστρέφει το άθροισμα των δύο αριθμών.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Επιστρέφει τη διαφορά των δύο αριθμών.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Επιστρέφει το γινόμενο των δύο αριθμών.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Επιστρέφει το πηλίκο των δύο αριθμών.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Επιστρέφει τον πρώτο αριθμό υψωμένο στη δύναμη του δεύτερου αριθμού.",
                +	"MATH_SINGLE_HELPURL": "https://el.wikipedia.org/wiki/%CE%A4%CE%B5%CF%84%CF%81%CE%B1%CE%B3%CF%89%CE%BD%CE%B9%CE%BA%CE%AE_%CF%81%CE%AF%CE%B6%CE%B1",
                +	"MATH_SINGLE_OP_ROOT": "τετραγωνική ρίζα",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Επιστρέφει την τετραγωνική ρίζα ενός αριθμού.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "απόλυτη",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Επιστρέφει την απόλυτη τιμή ενός αριθμού.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Επιστρέφει την αρνητική ενός αριθμού.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Επιστρέφει τον νεπέρειο λογάριθμο ενός αριθμού.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Επιστρέφει τον λογάριθμο με βάση το 10 ενός αριθμού.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Επιστρέφει το e υψωμένο στη δύναμη ενός αριθμού.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Επιστρέφει το 10 υψωμένο στη δύναμη ενός αριθμού.",
                +	"MATH_TRIG_HELPURL": "https://el.wikipedia.org/wiki/%CE%A4%CF%81%CE%B9%CE%B3%CF%89%CE%BD%CE%BF%CE%BC%CE%B5%CF%84%CF%81%CE%B9%CE%BA%CE%AE_%CF%83%CF%85%CE%BD%CE%AC%CF%81%CF%84%CE%B7%CF%83%CE%B7",
                +	"MATH_TRIG_TOOLTIP_SIN": "Επιστρέφει το ημίτονο ενός βαθμού (όχι ακτινίου).",
                +	"MATH_TRIG_TOOLTIP_COS": "Επιστρέφει το συνημίτονο ενός βαθμού (όχι ακτινίου).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Επιστρέφει την εφαπτομένη ενός βαθμού (όχι ακτινίου).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Επιστρέφει το τόξο ημίτονου ενός αριθμού.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Επιστρέφει το τόξο συνημίτονου ενός αριθμού.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Επιστρέφει το τόξο εφαπτομένης ενός αριθμού.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Επιστρέφει μία από τις κοινές σταθερές: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...), ή ∞ (άπειρο).",
                +	"MATH_IS_EVEN": "είναι άρτιος",
                +	"MATH_IS_ODD": "είναι περιττός",
                +	"MATH_IS_PRIME": "είναι πρώτος",
                +	"MATH_IS_WHOLE": "είναι ακέραιος",
                +	"MATH_IS_POSITIVE": "είναι θετικός",
                +	"MATH_IS_NEGATIVE": "είναι αρνητικός",
                +	"MATH_IS_DIVISIBLE_BY": "είναι διαιρετός από το",
                +	"MATH_IS_TOOLTIP": "Ελέγχει αν ένας αριθμός είναι άρτιος, περιττός, πρώτος, ακέραιος, θετικός, αρνητικός, ή αν είναι διαιρετός από έναν ορισμένο αριθμό. Επιστρέφει αληθής ή ψευδής.",
                +	"MATH_CHANGE_HELPURL": "https://el.wikipedia.org/wiki/%CE%A0%CF%81%CF%8C%CF%83%CE%B8%CE%B5%CF%83%CE%B7",
                +	"MATH_CHANGE_TITLE": "άλλαξε %1 από %2",
                +	"MATH_CHANGE_TOOLTIP": "Προσθέτει έναν αριθμό στη μεταβλητή «%1».",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Στρογγυλοποιεί έναν αριθμό προς τα πάνω ή προς τα κάτω.",
                +	"MATH_ROUND_OPERATOR_ROUND": "στρογγυλοποίησε",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "στρογγυλοποίησε προς τα πάνω",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "στρογγυλοποίησε προς τα κάτω",
                +	"MATH_ONLIST_OPERATOR_SUM": "άθροισμα λίστας",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Επιστρέφει το άθροισμα όλων των αριθμών στη λίστα.",
                +	"MATH_ONLIST_OPERATOR_MIN": "μικρότερος λίστας",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Επιστρέφει τον μικρότερο αριθμό στη λίστα.",
                +	"MATH_ONLIST_OPERATOR_MAX": "μεγαλύτερος λίστας",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Επιστρέφει τον μεγαλύτερο αριθμό στη λίστα.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "μέσος όρος λίστας",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Επιστρέφει τον αριθμητικό μέσο όρο από τις αριθμητικές τιμές στη λίστα.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "διάμεσος λίστας",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Επιστρέφει τον διάμεσο της λίστας.",
                +	"MATH_ONLIST_OPERATOR_MODE": "μορφές λίστας",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Επιστρέφει μια λίστα με τα πιο κοινά στοιχεία στη λίστα.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "τυπική απόκλιση λίστας",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Επιστρέφει την τυπική απόκλιση της λίστας.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "τυχαίο στοιχείο λίστας",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Επιστρέφει ένα τυχαίο στοιχείο από τη λίστα.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "υπόλοιπο της %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Επιστρέφει το υπόλοιπο της διαίρεσης των δύο αριθμών.",
                +	"MATH_CONSTRAIN_TITLE": "περιόρισε %1 χαμηλή %2 υψηλή %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Περιορίζει έναν αριθμό μεταξύ των προβλεπόμενων ορίων (χωρίς αποκλεισμούς).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "τυχαίος ακέραιος από το %1 έως το %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Επιστρέφει έναν τυχαίο ακέραιο αριθμό μεταξύ δύο συγκεκριμένων ορίων (εντός - συμπεριλαμβανομένων και των ακραίων τιμών).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://el.wikipedia.org/wiki/%CE%93%CE%B5%CE%BD%CE%BD%CE%AE%CF%84%CF%81%CE%B9%CE%B1_%CE%A4%CF%85%CF%87%CE%B1%CE%AF%CF%89%CE%BD_%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8E%CE%BD",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "τυχαίο κλάσμα",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Επιστρέψει ένα τυχαία κλάσμα μεταξύ 0,0 (κλειστό) και 1,0 (ανοικτό).",
                +	"TEXT_TEXT_HELPURL": "https://el.wikipedia.org/wiki/%CE%A3%CF%85%CE%BC%CE%B2%CE%BF%CE%BB%CE%BF%CF%83%CE%B5%CE%B9%CF%81%CE%AC",
                +	"TEXT_TEXT_TOOLTIP": "Ένα γράμμα, μια λέξη ή μια γραμμή κειμένου.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "δημιούργησε κείμενο με",
                +	"TEXT_JOIN_TOOLTIP": "Δημιουργεί ένα κομμάτι κειμένου ενώνοντας έναν  απεριόριστο αριθμό αντικειμένων.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "ένωσε",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Προσθέτει, αφαιρεί ή αναδιατάσσει τους τομείς για να αναδιαμορφώσει αυτό το μπλοκ κειμένου.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Προσθέτει ένα στοιχείο στο κείμενο.",
                +	"TEXT_APPEND_TOOLTIP": "Αναθέτει κείμενο στη μεταβλητή «%1».",
                +	"TEXT_LENGTH_TITLE": "το μήκος του %1",
                +	"TEXT_LENGTH_TOOLTIP": "Επιστρέφει το πλήθος των γραμμάτων (συμπεριλαμβανομένων και των κενών διαστημάτων) στο παρεχόμενο κείμενο.",
                +	"TEXT_ISEMPTY_TITLE": "το %1 είναι κενό",
                +	"TEXT_ISEMPTY_TOOLTIP": "Επιστρέφει αληθής αν το παρεχόμενο κείμενο είναι κενό.",
                +	"TEXT_INDEXOF_TOOLTIP": "Επιστρέφει τον δείκτη της πρώτης/τελευταίας εμφάνισης του πρώτου κειμένου στο δεύτερο κείμενο.  Επιστρέφει τιμή %1, αν δε βρει το κείμενο.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "βρες την πρώτη εμφάνιση του κειμένου",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "βρες την τελευταία εμφάνιση του κειμένου",
                +	"TEXT_CHARAT_FROM_START": "πάρε το γράμμα #",
                +	"TEXT_CHARAT_FROM_END": "πάρε το γράμμα # από το τέλος",
                +	"TEXT_CHARAT_FIRST": "πάρε το πρώτο γράμμα",
                +	"TEXT_CHARAT_LAST": "πάρε το τελευταίο γράμμα",
                +	"TEXT_CHARAT_RANDOM": "πάρε τυχαίο γράμμα",
                +	"TEXT_CHARAT_TOOLTIP": "Επιστρέφει το γράμμα στην καθορισμένη θέση.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Επιστρέφει ένα συγκεκριμένο τμήμα του κειμένου.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "στο κείμενο",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "πάρε τη δευτερεύουσα συμβολοσειρά από το # γράμμα",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "πάρε τη δευτερεύουσα συμβολοσειρά από το # γράμμα από το τέλος",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "πάρε τη δευτερεύουσα συμβολοσειρά από το πρώτο γράμμα",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "μέχρι το # γράμμα",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "μέχρι το # γράμμα από το τέλος",
                +	"TEXT_GET_SUBSTRING_END_LAST": "μέχρι το τελευταίο γράμμα",
                +	"TEXT_CHANGECASE_TOOLTIP": "Επιστρέφει ένα αντίγραφο του κειμένου σε διαφορετική μορφή γραμμάτων.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "σε ΚΕΦΑΛΑΙΑ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "σε πεζά",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "σε Λέξεις Με Πρώτα Κεφαλαία",
                +	"TEXT_TRIM_TOOLTIP": "Επιστρέφει ένα αντίγραφο του κειμένου με αφαιρεμένα τα κενά από το ένα ή και τα δύο άκρα.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "περίκοψε τα κενά και από τις δυο πλευρές του",
                +	"TEXT_TRIM_OPERATOR_LEFT": "περίκοψε τα κενά από την αριστερή πλευρά του",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "περίκοψε τα κενά από την δεξιά πλευρά του",
                +	"TEXT_PRINT_TITLE": "εκτύπωσε %1",
                +	"TEXT_PRINT_TOOLTIP": "Εκτυπώνει το καθορισμένο κείμενο, αριθμό ή άλλη τιμή.",
                +	"TEXT_PROMPT_TYPE_TEXT": "πρότρεψε με μήνυμα για να δοθεί κείμενο",
                +	"TEXT_PROMPT_TYPE_NUMBER": "πρότρεψε με μήνυμα για να δοθεί αριθμός",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Δημιουργεί προτροπή για τον χρήστη για να δώσει ένα αριθμό.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Δημιουργεί προτροπή για το χρήστη για να δώσει κάποιο κείμενο.",
                +	"TEXT_COUNT_TOOLTIP": "Μετρά πόσες φορές κάποιο κείμενο εμφανίζεται μέσα σε ένα άλλο κείμενο.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "δημιούργησε κενή λίστα",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Επιστρέφει μια λίστα, με μήκος 0, η οποία δεν περιέχει εγγραφές δεδομένων",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Δημιουργεί λίστα με οποιονδήποτε αριθμό αντικειμένων.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "δημιούργησε λίστα με",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "λίστα",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Προσθέτει, αφαιρεί ή αναδιατάσσει τα τμήματα για να αναδιαμορφώσει αυτό το μπλοκ λίστας.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Προσθέτει αντικείμενο στη λίστα.",
                +	"LISTS_REPEAT_HELPURL": "Blockly",
                +	"LISTS_REPEAT_TOOLTIP": "Δημιουργεί μια λίστα που αποτελείται από την δεδομένη τιμή που επαναλαμβάνεται για συγκεκριμένο αριθμό επαναλήψεων.",
                +	"LISTS_REPEAT_TITLE": "δημιούργησε λίστα με το στοιχείο %1 να επαναλαμβάνεται %2 φορές",
                +	"LISTS_LENGTH_HELPURL": "Blockly",
                +	"LISTS_LENGTH_TITLE": "το μήκος του %1",
                +	"LISTS_LENGTH_TOOLTIP": "Επιστρέφει το μήκος μιας λίστας.",
                +	"LISTS_ISEMPTY_TITLE": "το %1 είναι κενό",
                +	"LISTS_ISEMPTY_TOOLTIP": "Επιστρέφει αληθής αν η λίστα είναι κενή.",
                +	"LISTS_INLIST": "στη λίστα",
                +	"LISTS_INDEX_OF_HELPURL": "Blockly",
                +	"LISTS_INDEX_OF_FIRST": "βρες την πρώτη εμφάνιση του στοιχείου",
                +	"LISTS_INDEX_OF_LAST": "βρες την τελευταία εμφάνιση του στοιχείου",
                +	"LISTS_INDEX_OF_TOOLTIP": "Επιστρέφει τον δείκτη της πρώτης/τελευταίας εμφάνισης του στοιχείου στη λίστα.  Επιστρέφει τιμή %1, αν το στοιχείο δεν βρεθεί.",
                +	"LISTS_GET_INDEX_GET": "πάρε",
                +	"LISTS_GET_INDEX_GET_REMOVE": "πάρε και αφαίρεσε",
                +	"LISTS_GET_INDEX_REMOVE": "αφαίρεσε",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# από το τέλος",
                +	"LISTS_GET_INDEX_FIRST": "πρώτο",
                +	"LISTS_GET_INDEX_LAST": "τελευταίο",
                +	"LISTS_GET_INDEX_RANDOM": "τυχαίο",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Το %1 είναι το πρώτο στοιχείο.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Το %1 είναι το τελευταίο στοιχείο.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Επιστρέφει το στοιχείο στην καθορισμένη θέση σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Επιστρέφει το πρώτο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Επιστρέφει το τελευταίο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Επιστρέφει ένα τυχαίο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Καταργεί και επιστρέφει το στοιχείο στην καθορισμένη θέση σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Καταργεί και επιστρέφει το πρώτο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Καταργεί και επιστρέφει το τελευταίο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Καταργεί και επιστρέφει ένα τυχαίο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Καταργεί το στοιχείο στην καθορισμένη θέση σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Καταργεί το πρώτο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Καταργεί το τελευταίο στοιχείο σε μια λίστα.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Καταργεί ένα τυχαίο στοιχείο σε μια λίστα.",
                +	"LISTS_SET_INDEX_SET": "όρισε",
                +	"LISTS_SET_INDEX_INSERT": "είσαγε στο",
                +	"LISTS_SET_INDEX_INPUT_TO": "σε",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Ορίζει το στοιχείο στην καθορισμένη θέση σε μια λίστα.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Ορίζει το πρώτο στοιχείο σε μια λίστα.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Ορίζει το τελευταίο στοιχείο σε μια λίστα.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Ορίζει ένα τυχαίο στοιχείο σε μια λίστα.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Εισάγει το στοιχείο στην καθορισμένη θέση σε μια λίστα.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Εισάγει το στοιχείο στην αρχή μιας λίστας.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Αναθέτει το στοιχείο στο τέλος μιας λίστας.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Εισάγει το στοιχείο τυχαία σε μια λίστα.",
                +	"LISTS_GET_SUBLIST_HELPURL": "Blockly",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "πάρε υπολίστα από #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "πάρε υπολίστα από # από το τέλος",
                +	"LISTS_GET_SUBLIST_START_FIRST": "πάρε υπολίστα από την αρχή",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "έως #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "έως # από το τέλος",
                +	"LISTS_GET_SUBLIST_END_LAST": "έως το τελευταίο",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Δημιουργεί ένα αντίγραφο του καθορισμένου τμήματος μιας λίστας.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_ORDER_ASCENDING": "Αύξουσα",
                +	"LISTS_SORT_ORDER_DESCENDING": "Φθίνουσα",
                +	"LISTS_SORT_TYPE_NUMERIC": "αριθμητικό",
                +	"LISTS_SORT_TYPE_TEXT": "Αλφαβητικά",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "κάνετε λίστα από το κείμενο",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "κάνετε κείμενο από τη λίστα",
                +	"LISTS_SPLIT_WITH_DELIMITER": "με διαχωριστικό",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Διαίρεση του κειμένου σε μια λίστα κειμένων, με σπάσιμο σε κάθε διαχωριστικό.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Ενώστε μια λίστα κειμένων σε ένα κείμενο, που χωρίζονται από ένα διαχωριστικό.",
                +	"VARIABLES_GET_TOOLTIP": "Επιστρέφει την τιμή αυτής της μεταβλητής.",
                +	"VARIABLES_GET_CREATE_SET": "Δημιούργησε «όρισε %1»",
                +	"VARIABLES_SET": "όρισε %1 μέχρι το %2",
                +	"VARIABLES_SET_TOOLTIP": "Ορίζει αυτή τη μεταβλητή να είναι ίση με την είσοδο.",
                +	"VARIABLES_SET_CREATE_GET": "Δημιούργησε «πάρε %1»",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "στο",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "κάνε κάτι",
                +	"PROCEDURES_BEFORE_PARAMS": "με:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "με:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Δημιουργεί μια συνάρτηση χωρίς έξοδο.",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "επέστρεψε",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Δημιουργεί μια συνάρτηση με μια έξοδο.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "να επιτρέπονται οι δηλώσεις",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Προειδοποίηση: Αυτή η συνάρτηση έχει διπλότυπες παραμέτρους.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://el.wikipedia.org/wiki/%CE%94%CE%B9%CE%B1%CE%B4%CE%B9%CE%BA%CE%B1%CF%83%CE%AF%CE%B1_%28%CF%85%CF%80%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CF%83%CF%84%CE%AD%CF%82%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Εκτελεί την ορισμένη από τον χρήστη συνάρτηση «%1».",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://el.wikipedia.org/wiki/%CE%94%CE%B9%CE%B1%CE%B4%CE%B9%CE%BA%CE%B1%CF%83%CE%AF%CE%B1_%28%CF%85%CF%80%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CF%83%CF%84%CE%AD%CF%82%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Εκτελεί την ορισμένη από τον χρήστη συνάρτηση «%1» και χρησιμοποίησε την έξοδό της.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "είσοδοι",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Προσθέτει, αφαιρεί ή αναδιατάσσει εισόδους σε αυτήν τη λειτουργία",
                +	"PROCEDURES_MUTATORARG_TITLE": "όνομα εισόδου:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Πρόσθεσε μια είσοδος στη συνάρτηση",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Επισημάνετε τον ορισμό συνάρτησης",
                +	"PROCEDURES_CREATE_DO": "Δημιούργησε «%1»",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Αν μια τιμή είναι αληθής, τότε επιστρέφει τη δεύτερη τιμή.",
                +	"PROCEDURES_IFRETURN_WARNING": "Προειδοποίηση: Αυτό το μπλοκ μπορεί να χρησιμοποιηθεί μόνο στον ορισμό μιας συνάρτησης."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/en-gb.json b/blockly/webif/static/blockly/msg/json/en-gb.json
                new file mode 100644
                index 000000000..a6a662173
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/en-gb.json
                @@ -0,0 +1,139 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Andibing",
                +			"Codynguyen1116",
                +			"Shirayuki"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Today",
                +	"DUPLICATE_BLOCK": "Duplicate",
                +	"ADD_COMMENT": "Add Comment",
                +	"REMOVE_COMMENT": "Remove Comment",
                +	"EXTERNAL_INPUTS": "External Inputs",
                +	"INLINE_INPUTS": "Inline Inputs",
                +	"DELETE_BLOCK": "Delete Block",
                +	"DELETE_X_BLOCKS": "Delete %1 Blocks",
                +	"DELETE_ALL_BLOCKS": "Delete all %1 blocks?",
                +	"CLEAN_UP": "Clean up Blocks",
                +	"COLLAPSE_BLOCK": "Collapse Block",
                +	"COLLAPSE_ALL": "Collapse Blocks",
                +	"EXPAND_BLOCK": "Expand Block",
                +	"EXPAND_ALL": "Expand Blocks",
                +	"DISABLE_BLOCK": "Disable Block",
                +	"ENABLE_BLOCK": "Enable Block",
                +	"HELP": "Help",
                +	"UNDO": "Undo",
                +	"REDO": "Redo",
                +	"CHANGE_VALUE_TITLE": "Change value:",
                +	"RENAME_VARIABLE": "Rename variable...",
                +	"RENAME_VARIABLE_TITLE": "Rename all '%1' variables to:",
                +	"NEW_VARIABLE": "New variable...",
                +	"NEW_VARIABLE_TITLE": "New variable name:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Colour",
                +	"COLOUR_PICKER_TOOLTIP": "Choose a colour from the palette.",
                +	"COLOUR_RANDOM_TITLE": "random colour",
                +	"COLOUR_RANDOM_TOOLTIP": "Choose a colour at random.",
                +	"COLOUR_RGB_TITLE": "colour with",
                +	"COLOUR_RGB_RED": "red",
                +	"COLOUR_RGB_GREEN": "green",
                +	"COLOUR_RGB_BLUE": "blue",
                +	"COLOUR_RGB_TOOLTIP": "Create a colour with the specified amount of red, green, and blue.  All values must be between 0 and 100.",
                +	"COLOUR_BLEND_TITLE": "blend",
                +	"COLOUR_BLEND_COLOUR1": "colour 1",
                +	"COLOUR_BLEND_COLOUR2": "colour 2",
                +	"COLOUR_BLEND_RATIO": "ratio",
                +	"COLOUR_BLEND_TOOLTIP": "Blends two colours together with a given ratio (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repeat %1 times",
                +	"CONTROLS_REPEAT_INPUT_DO": "do",
                +	"CONTROLS_REPEAT_TOOLTIP": "Do some statements several times.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repeat while",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repeat until",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "While a value is true, then do some statements.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "While a value is false, then do some statements.",
                +	"CONTROLS_FOR_TOOLTIP": "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.",
                +	"CONTROLS_FOR_TITLE": "count with %1 from %2 to %3 by %4",
                +	"CONTROLS_FOREACH_TITLE": "for each item %1 in list %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "For each item in a list, set the variable '%1' to the item, and then do some statements.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "break out of loop",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continue with next iteration of loop",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Break out of the containing loop.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Skip the rest of this loop, and continue with the next iteration.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Warning: This block may only be used within a loop.",
                +	"CONTROLS_IF_TOOLTIP_1": "If a value is true, then do some statements.",
                +	"CONTROLS_IF_TOOLTIP_2": "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.",
                +	"CONTROLS_IF_TOOLTIP_3": "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.",
                +	"CONTROLS_IF_TOOLTIP_4": "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.",
                +	"CONTROLS_IF_MSG_IF": "if",
                +	"CONTROLS_IF_MSG_ELSEIF": "else if",
                +	"CONTROLS_IF_MSG_ELSE": "else",
                +	"CONTROLS_IF_IF_TOOLTIP": "Add, remove, or reorder sections to reconfigure this if block.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Add a condition to the if block.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Add a final, catch-all condition to the if block.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Return true if both inputs equal each other.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Return true if both inputs are not equal to each other.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Return true if the first input is smaller than the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Return true if the first input is smaller than or equal to the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Return true if the first input is greater than the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Return true if the first input is greater than or equal to the second input.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Return true if both inputs are true.",
                +	"LOGIC_OPERATION_AND": "and",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Return true if at least one of the inputs is true.",
                +	"LOGIC_OPERATION_OR": "or",
                +	"LOGIC_NEGATE_TITLE": "not %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returns true if the input is false. Returns false if the input is true.",
                +	"LOGIC_BOOLEAN_TRUE": "true",
                +	"LOGIC_BOOLEAN_FALSE": "false",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returns either true or false.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returns null.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "if true",
                +	"LOGIC_TERNARY_IF_FALSE": "if false",
                +	"LOGIC_TERNARY_TOOLTIP": "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "A number.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Return the sum of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Return the difference of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Return the product of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Return the quotient of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Return the first number raised to the power of the second number.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "square root",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Return the square root of a number.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolute",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Return the absolute value of a number.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Return the negation of a number.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Return the natural logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Return the base 10 logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Return e to the power of a number.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Return 10 to the power of a number.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Return the sine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Return the cosine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Return the tangent of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Return the arcsine of a number.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Return the arccosine of a number.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Return the arctangent of a number.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "is even",
                +	"MATH_IS_ODD": "is odd",
                +	"MATH_IS_PRIME": "is prime",
                +	"MATH_IS_WHOLE": "is whole",
                +	"MATH_IS_POSITIVE": "is positive",
                +	"MATH_IS_NEGATIVE": "is negative",
                +	"MATH_IS_DIVISIBLE_BY": "is divisible by",
                +	"MATH_IS_TOOLTIP": "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "change %1 by %2",
                +	"MATH_CHANGE_TOOLTIP": "Add a number to variable '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Round a number up or down.",
                +	"MATH_ROUND_OPERATOR_ROUND": "round",
                +	"LISTS_SORT_ORDER_DESCENDING": "descendente"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/en.json b/blockly/webif/static/blockly/msg/json/en.json
                new file mode 100644
                index 000000000..26f063be5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/en.json
                @@ -0,0 +1,397 @@
                +{
                +	"@metadata": {
                +		"author": "Ellen Spertus <ellen.spertus@gmail.com>",
                +		"lastupdated": "2017-07-31 17:25:19.178683",
                +		"locale": "en",
                +		"messagedocumentation" : "qqq"
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Today",
                +	"DUPLICATE_BLOCK": "Duplicate",
                +	"ADD_COMMENT": "Add Comment",
                +	"REMOVE_COMMENT": "Remove Comment",
                +	"EXTERNAL_INPUTS": "External Inputs",
                +	"INLINE_INPUTS": "Inline Inputs",
                +	"DELETE_BLOCK": "Delete Block",
                +	"DELETE_X_BLOCKS": "Delete %1 Blocks",
                +	"DELETE_ALL_BLOCKS": "Delete all %1 blocks?",
                +	"CLEAN_UP": "Clean up Blocks",
                +	"COLLAPSE_BLOCK": "Collapse Block",
                +	"COLLAPSE_ALL": "Collapse Blocks",
                +	"EXPAND_BLOCK": "Expand Block",
                +	"EXPAND_ALL": "Expand Blocks",
                +	"DISABLE_BLOCK": "Disable Block",
                +	"ENABLE_BLOCK": "Enable Block",
                +	"HELP": "Help",
                +	"UNDO": "Undo",
                +	"REDO": "Redo",
                +	"CHANGE_VALUE_TITLE": "Change value:",
                +	"RENAME_VARIABLE": "Rename variable...",
                +	"RENAME_VARIABLE_TITLE": "Rename all '%1' variables to:",
                +	"NEW_VARIABLE": "Create variable...",
                +	"NEW_VARIABLE_TITLE": "New variable name:",
                +	"VARIABLE_ALREADY_EXISTS": "A variable named '%1' already exists.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "A variable named '%1' already exists for another variable of type '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "A procedure named '%1' already exists.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Delete %1 uses of the '%2' variable?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Can't delete the variable '%1' because it's part of the definition of the function '%2'",
                +	"DELETE_VARIABLE": "Delete the '%1' variable",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Choose a colour from the palette.",
                +	"COLOUR_RANDOM_HELPURL": "http://randomcolour.com",
                +	"COLOUR_RANDOM_TITLE": "random colour",
                +	"COLOUR_RANDOM_TOOLTIP": "Choose a colour at random.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "colour with",
                +	"COLOUR_RGB_RED": "red",
                +	"COLOUR_RGB_GREEN": "green",
                +	"COLOUR_RGB_BLUE": "blue",
                +	"COLOUR_RGB_TOOLTIP": "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "blend",
                +	"COLOUR_BLEND_COLOUR1": "colour 1",
                +	"COLOUR_BLEND_COLOUR2": "colour 2",
                +	"COLOUR_BLEND_RATIO": "ratio",
                +	"COLOUR_BLEND_TOOLTIP": "Blends two colours together with a given ratio (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repeat %1 times",
                +	"CONTROLS_REPEAT_INPUT_DO": "do",
                +	"CONTROLS_REPEAT_TOOLTIP": "Do some statements several times.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://github.com/google/blockly/wiki/Loops#repeat",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repeat while",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repeat until",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "While a value is true, then do some statements.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "While a value is false, then do some statements.",
                +	"CONTROLS_FOR_HELPURL": "https://github.com/google/blockly/wiki/Loops#count-with",
                +	"CONTROLS_FOR_TOOLTIP": "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.",
                +	"CONTROLS_FOR_TITLE": "count with %1 from %2 to %3 by %4",
                +	"CONTROLS_FOREACH_HELPURL": "https://github.com/google/blockly/wiki/Loops#for-each",
                +	"CONTROLS_FOREACH_TITLE": "for each item %1 in list %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "For each item in a list, set the variable '%1' to the item, and then do some statements.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "break out of loop",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continue with next iteration of loop",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Break out of the containing loop.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Skip the rest of this loop, and continue with the next iteration.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Warning: This block may only be used within a loop.",
                +	"CONTROLS_IF_HELPURL": "https://github.com/google/blockly/wiki/IfElse",
                +	"CONTROLS_IF_TOOLTIP_1": "If a value is true, then do some statements.",
                +	"CONTROLS_IF_TOOLTIP_2": "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.",
                +	"CONTROLS_IF_TOOLTIP_3": "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.",
                +	"CONTROLS_IF_TOOLTIP_4": "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.",
                +	"CONTROLS_IF_MSG_IF": "if",
                +	"CONTROLS_IF_MSG_ELSEIF": "else if",
                +	"CONTROLS_IF_MSG_ELSE": "else",
                +	"CONTROLS_IF_IF_TOOLTIP": "Add, remove, or reorder sections to reconfigure this if block.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Add a condition to the if block.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Add a final, catch-all condition to the if block.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Cancel",
                +	"IOS_ERROR": "Error",
                +	"IOS_PROCEDURES_INPUTS": "INPUTS",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Add Input",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Allow statements",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "This function has duplicate inputs.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Add Variable",
                +	"IOS_VARIABLES_ADD_BUTTON": "Add",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Rename",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Delete",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Variable name",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "You can't use an empty variable name.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Return true if both inputs equal each other.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Return true if both inputs are not equal to each other.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Return true if the first input is smaller than the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Return true if the first input is smaller than or equal to the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Return true if the first input is greater than the second input.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Return true if the first input is greater than or equal to the second input.",
                +	"LOGIC_OPERATION_HELPURL": "https://github.com/google/blockly/wiki/Logic#logical-operations",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Return true if both inputs are true.",
                +	"LOGIC_OPERATION_AND": "and",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Return true if at least one of the inputs is true.",
                +	"LOGIC_OPERATION_OR": "or",
                +	"LOGIC_NEGATE_HELPURL": "https://github.com/google/blockly/wiki/Logic#not",
                +	"LOGIC_NEGATE_TITLE": "not %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returns true if the input is false. Returns false if the input is true.",
                +	"LOGIC_BOOLEAN_HELPURL": "https://github.com/google/blockly/wiki/Logic#values",
                +	"LOGIC_BOOLEAN_TRUE": "true",
                +	"LOGIC_BOOLEAN_FALSE": "false",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returns either true or false.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returns null.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "if true",
                +	"LOGIC_TERNARY_IF_FALSE": "if false",
                +	"LOGIC_TERNARY_TOOLTIP": "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "A number.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Return the sum of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Return the difference of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Return the product of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Return the quotient of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Return the first number raised to the power of the second number.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "square root",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Return the square root of a number.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolute",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Return the absolute value of a number.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Return the negation of a number.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Return the natural logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Return the base 10 logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Return e to the power of a number.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Return 10 to the power of a number.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Return the sine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Return the cosine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Return the tangent of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Return the arcsine of a number.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Return the arccosine of a number.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Return the arctangent of a number.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "is even",
                +	"MATH_IS_ODD": "is odd",
                +	"MATH_IS_PRIME": "is prime",
                +	"MATH_IS_WHOLE": "is whole",
                +	"MATH_IS_POSITIVE": "is positive",
                +	"MATH_IS_NEGATIVE": "is negative",
                +	"MATH_IS_DIVISIBLE_BY": "is divisible by",
                +	"MATH_IS_TOOLTIP": "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "change %1 by %2",
                +	"MATH_CHANGE_TOOLTIP": "Add a number to variable '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Round a number up or down.",
                +	"MATH_ROUND_OPERATOR_ROUND": "round",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "round up",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "round down",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "sum of list",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Return the sum of all the numbers in the list.",
                +	"MATH_ONLIST_OPERATOR_MIN": "min of list",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Return the smallest number in the list.",
                +	"MATH_ONLIST_OPERATOR_MAX": "max of list",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Return the largest number in the list.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "average of list",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Return the average (arithmetic mean) of the numeric values in the list.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "median of list",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Return the median number in the list.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modes of list",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Return a list of the most common item(s) in the list.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standard deviation of list",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Return the standard deviation of the list.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "random item of list",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Return a random element from the list.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "remainder of %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Return the remainder from dividing the two numbers.",
                +	"MATH_CONSTRAIN_HELPURL": "https://en.wikipedia.org/wiki/Clamping_(graphics)",
                +	"MATH_CONSTRAIN_TITLE": "constrain %1 low %2 high %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Constrain a number to be between the specified limits (inclusive).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "random integer from %1 to %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Return a random integer between the two specified limits, inclusive.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "random fraction",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "A letter, word, or line of text.",
                +	"TEXT_JOIN_HELPURL": "https://github.com/google/blockly/wiki/Text#text-creation",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "create text with",
                +	"TEXT_JOIN_TOOLTIP": "Create a piece of text by joining together any number of items.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "join",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Add, remove, or reorder sections to reconfigure this text block.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Add an item to the text.",
                +	"TEXT_APPEND_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_APPEND_TITLE": "to %1 append text %2",
                +	"TEXT_APPEND_TOOLTIP": "Append some text to variable '%1'.",
                +	"TEXT_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_LENGTH_TITLE": "length of %1",
                +	"TEXT_LENGTH_TOOLTIP": "Returns the number of letters (including spaces) in the provided text.",
                +	"TEXT_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Text#checking-for-empty-text",
                +	"TEXT_ISEMPTY_TITLE": "%1 is empty",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returns true if the provided text is empty.",
                +	"TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text",
                +	"TEXT_INDEXOF_TOOLTIP": "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.",
                +	"TEXT_INDEXOF_TITLE": "in text %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "find first occurrence of text",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "find last occurrence of text",
                +	"TEXT_CHARAT_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-text",
                +	"TEXT_CHARAT_TITLE": "in text %1 %2",
                +	"TEXT_CHARAT_FROM_START": "get letter #",
                +	"TEXT_CHARAT_FROM_END": "get letter # from end",
                +	"TEXT_CHARAT_FIRST": "get first letter",
                +	"TEXT_CHARAT_LAST": "get last letter",
                +	"TEXT_CHARAT_RANDOM": "get random letter",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Returns the letter at the specified position.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returns a specified portion of the text.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "get substring from letter #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "get substring from letter # from end",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "get substring from first letter",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "to letter #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "to letter # from end",
                +	"TEXT_GET_SUBSTRING_END_LAST": "to last letter",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_HELPURL": "https://github.com/google/blockly/wiki/Text#adjusting-text-case",
                +	"TEXT_CHANGECASE_TOOLTIP": "Return a copy of the text in a different case.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "to UPPER CASE",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "to lower case",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "to Title Case",
                +	"TEXT_TRIM_HELPURL": "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces",
                +	"TEXT_TRIM_TOOLTIP": "Return a copy of the text with spaces removed from one or both ends.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "trim spaces from both sides of",
                +	"TEXT_TRIM_OPERATOR_LEFT": "trim spaces from left side of",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "trim spaces from right side of",
                +	"TEXT_PRINT_HELPURL": "https://github.com/google/blockly/wiki/Text#printing-text",
                +	"TEXT_PRINT_TITLE": "print %1",
                +	"TEXT_PRINT_TOOLTIP": "Print the specified text, number or other value.",
                +	"TEXT_PROMPT_HELPURL": "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user",
                +	"TEXT_PROMPT_TYPE_TEXT": "prompt for text with message",
                +	"TEXT_PROMPT_TYPE_NUMBER": "prompt for number with message",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Prompt for user for a number.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Prompt for user for some text.",
                +	"TEXT_COUNT_MESSAGE0": "count %1 in %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Count how many times some text occurs within some other text.",
                +	"TEXT_REPLACE_MESSAGE0": "replace %1 with %2 in %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Replace all occurances of some text within some other text.",
                +	"TEXT_REVERSE_MESSAGE0": "reverse %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Reverses the order of the characters in the text.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "create empty list",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Returns a list, of length 0, containing no data records",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Create a list with any number of items.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "create list with",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "list",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Add, remove, or reorder sections to reconfigure this list block.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Add an item to the list.",
                +	"LISTS_REPEAT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_REPEAT_TOOLTIP": "Creates a list consisting of the given value repeated the specified number of times.",
                +	"LISTS_REPEAT_TITLE": "create list with item %1 repeated %2 times",
                +	"LISTS_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Lists#length-of",
                +	"LISTS_LENGTH_TITLE": "length of %1",
                +	"LISTS_LENGTH_TOOLTIP": "Returns the length of a list.",
                +	"LISTS_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#is-empty",
                +	"LISTS_ISEMPTY_TITLE": "%1 is empty",
                +	"LISTS_ISEMPTY_TOOLTIP": "Returns true if the list is empty.",
                +	"LISTS_INLIST": "in list",
                +	"LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list",
                +	"LISTS_INDEX_OF_FIRST": "find first occurrence of item",
                +	"LISTS_INDEX_OF_LAST": "find last occurrence of item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.",
                +	"LISTS_GET_INDEX_GET": "get",
                +	"LISTS_GET_INDEX_GET_REMOVE": "get and remove",
                +	"LISTS_GET_INDEX_REMOVE": "remove",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# from end",
                +	"LISTS_GET_INDEX_FIRST": "first",
                +	"LISTS_GET_INDEX_LAST": "last",
                +	"LISTS_GET_INDEX_RANDOM": "random",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 is the first item.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 is the last item.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Returns the item at the specified position in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Returns the first item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Returns the last item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Returns a random item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Removes and returns the item at the specified position in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Removes and returns the first item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Removes and returns the last item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Removes and returns a random item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Removes the item at the specified position in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Removes the first item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Removes the last item in a list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Removes a random item in a list.",
                +	"LISTS_SET_INDEX_HELPURL": "https://github.com/google/blockly/wiki/Lists#in-list--set",
                +	"LISTS_SET_INDEX_SET": "set",
                +	"LISTS_SET_INDEX_INSERT": "insert at",
                +	"LISTS_SET_INDEX_INPUT_TO": "as",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Sets the item at the specified position in a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Sets the first item in a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Sets the last item in a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Sets a random item in a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserts the item at the specified position in a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Inserts the item at the start of a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Append the item to the end of a list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Inserts the item randomly in a list.",
                +	"LISTS_GET_SUBLIST_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-a-sublist",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "get sub-list from #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "get sub-list from # from end",
                +	"LISTS_GET_SUBLIST_START_FIRST": "get sub-list from first",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "to #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "to # from end",
                +	"LISTS_GET_SUBLIST_END_LAST": "to last",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Creates a copy of the specified portion of a list.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sort %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sort a copy of a list.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ascending",
                +	"LISTS_SORT_ORDER_DESCENDING": "descending",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeric",
                +	"LISTS_SORT_TYPE_TEXT": "alphabetic",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alphabetic, ignore case",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "make list from text",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "make text from list",
                +	"LISTS_SPLIT_WITH_DELIMITER": "with delimiter",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Split text into a list of texts, breaking at each delimiter.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Join a list of texts into one text, separated by a delimiter.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "reverse %1",
                +	"LISTS_REVERSE_TOOLTIP": "Reverse a copy of a list.",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_HELPURL": "https://github.com/google/blockly/wiki/Variables#get",
                +	"VARIABLES_GET_TOOLTIP": "Returns the value of this variable.",
                +	"VARIABLES_GET_CREATE_SET": "Create 'set %1'",
                +	"VARIABLES_SET_HELPURL": "https://github.com/google/blockly/wiki/Variables#set",
                +	"VARIABLES_SET": "set %1 to %2",
                +	"VARIABLES_SET_TOOLTIP": "Sets this variable to be equal to the input.",
                +	"VARIABLES_SET_CREATE_GET": "Create 'get %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_DEFNORETURN_TITLE": "to",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "do something",
                +	"PROCEDURES_BEFORE_PARAMS": "with:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "with:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Creates a function with no output.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Describe this function...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_DEFRETURN_RETURN": "return",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Creates a function with an output.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "allow statements",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Warning: This function has duplicate parameters.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Run the user-defined function '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Run the user-defined function '%1' and use its output.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inputs",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Add, remove, or reorder inputs to this function.",
                +	"PROCEDURES_MUTATORARG_TITLE": "input name:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Add an input to the function.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Highlight function definition",
                +	"PROCEDURES_CREATE_DO": "Create '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "If a value is true, then return a second value.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Warning: This block may be used only within a function definition."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/eo.json b/blockly/webif/static/blockly/msg/json/eo.json
                new file mode 100644
                index 000000000..0de759849
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/eo.json
                @@ -0,0 +1,194 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Etrapani",
                +			"Ochilov",
                +			"Orikrin1998",
                +			"Robin van der Vliet"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "elemento",
                +	"TODAY": "Hodiaŭ",
                +	"DUPLICATE_BLOCK": "Duobligi",
                +	"ADD_COMMENT": "Aldoni komenton",
                +	"REMOVE_COMMENT": "Forigi komenton",
                +	"EXTERNAL_INPUTS": "Eksteraj eniroj",
                +	"INLINE_INPUTS": "Entekstaj eniroj",
                +	"DELETE_BLOCK": "Forigi blokon",
                +	"DELETE_X_BLOCKS": "Forigi %1 blokojn",
                +	"DELETE_ALL_BLOCKS": "Ĉu forigi ĉiujn %1 blokojn?",
                +	"CLEAN_UP": "Purigi blokojn",
                +	"COLLAPSE_BLOCK": "Faldi blokon",
                +	"COLLAPSE_ALL": "Faldi blokojn",
                +	"EXPAND_BLOCK": "Malfaldi blokon",
                +	"EXPAND_ALL": "Malfaldi blokojn",
                +	"DISABLE_BLOCK": "Malŝalti blokon",
                +	"ENABLE_BLOCK": "Ŝalti blokon",
                +	"HELP": "Helpo",
                +	"UNDO": "Malfari",
                +	"REDO": "Refari",
                +	"CHANGE_VALUE_TITLE": "Ŝangi valoron:",
                +	"RENAME_VARIABLE": "Renomi varianton...",
                +	"RENAME_VARIABLE_TITLE": "Renomi ĉiujn '%1' variantojn kiel:",
                +	"NEW_VARIABLE": "Nova varianto...",
                +	"NEW_VARIABLE_TITLE": "Nova nomo de varianto:",
                +	"VARIABLE_ALREADY_EXISTS": "Jam ekzistas varianto kun la nomo '%1'.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Ĉu forigi %1 uzojn de la varianto '%2'?",
                +	"DELETE_VARIABLE": "Forigi la varianton '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://eo.wikipedia.org/wiki/Koloro",
                +	"COLOUR_PICKER_TOOLTIP": "Elekti koloron el la paletro.",
                +	"COLOUR_RANDOM_TITLE": "hazarda koloro",
                +	"COLOUR_RANDOM_TOOLTIP": "Elekti hazardan koloron.",
                +	"COLOUR_RGB_TITLE": "kolorigi per",
                +	"COLOUR_RGB_RED": "ruĝa",
                +	"COLOUR_RGB_GREEN": "verda",
                +	"COLOUR_RGB_BLUE": "blua",
                +	"COLOUR_BLEND_COLOUR1": "koloro 1",
                +	"COLOUR_BLEND_COLOUR2": "koloro 2",
                +	"COLOUR_BLEND_RATIO": "proporcio",
                +	"CONTROLS_REPEAT_TITLE": "ripeti %1 fojojn",
                +	"CONTROLS_REPEAT_INPUT_DO": "fari",
                +	"CONTROLS_REPEAT_TOOLTIP": "Plenumi kelkajn ordonojn plurfoje.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ripeti dum",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ripeti ĝis",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Plenumi ordonojn dum la valoro egalas vero.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Plenumi ordonojn dum valoro egalas malvero.",
                +	"CONTROLS_FOREACH_TITLE": "por ĉiu elemento %1 en la listo %2",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "eliri el la ciklo",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "daŭrigi je la venonta ripeto de la ciklo",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Eliri el la enhava ciklo.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Pretersalti la ceteron de tiu ĉi ciklo kaj daŭrigi je la venonta ripeto.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Averto: tiu ĉi bloko uzeblas nur ene de ciklo.",
                +	"CONTROLS_IF_TOOLTIP_1": "Plenumi ordonojn se la valoro estas vero.",
                +	"CONTROLS_IF_TOOLTIP_2": "Plenumi la unuan blokon de ordonoj se la valoro estas vero, se ne, la duan.",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "alie se",
                +	"CONTROLS_IF_MSG_ELSE": "alie",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Aldoni kondiĉon al la bloko 'se'",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Aldoni 'aliokaze' kondiĉon al la 'se' bloko.",
                +	"LOGIC_COMPARE_HELPURL": "https://eo.wikipedia.org/wiki/Neegala%C4%B5o_(pli_granda,_malpli_granda)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Vero estos liverita, se la du eniroj egalas.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Vero estos liverita, se la du eniroj ne egalas.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Vero estos liverita, se la unua eniro estas pli eta ol la dua.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Vero estos liverita, se la unua eniro estas pli eta aŭ egala al la dua.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Vero estos liverita, se la unua eniro estas pli granda ol la dua.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Vero estos liverita, se la unua eniro estas pli granda aŭ egala al la dua.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Vero estos liverita, se la du eniroj egalas veron.",
                +	"LOGIC_OPERATION_AND": "kaj",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Vero estos liverita, se almenaŭ unu el la eniroj egalas veron.",
                +	"LOGIC_OPERATION_OR": "aŭ",
                +	"LOGIC_NEGATE_TITLE": "maligi %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Se la eniro egalas vero, la rezulto egalas malvero. Se la eniro egalas malvero, la rezulto egalas vero.",
                +	"LOGIC_BOOLEAN_TRUE": "vera",
                +	"LOGIC_BOOLEAN_FALSE": "falsa",
                +	"LOGIC_BOOLEAN_TOOLTIP": "La rezulto egalas ĉu vero, ĉu malvero.",
                +	"LOGIC_TERNARY_CONDITION": "testi",
                +	"LOGIC_TERNARY_IF_TRUE": "se estas vero",
                +	"LOGIC_TERNARY_IF_FALSE": "se estas malvero",
                +	"LOGIC_TERNARY_TOOLTIP": "Kontroli la kondiĉon en 'testo'. Se la kondiĉo egalas veron, liveri la valoron 'se estas vero', aliokaze liveri la valoron 'se estas malvero'.",
                +	"MATH_NUMBER_HELPURL": "https://eo.wikipedia.org/wiki/Nombro",
                +	"MATH_NUMBER_TOOLTIP": "Nombro.",
                +	"MATH_ARITHMETIC_HELPURL": "https://eo.wikipedia.org/wiki/Aritmetiko",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "La sumo de la du nombroj estos liverita.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "La diferenco inter la du nombroj estos liverita.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "La produto de la du numeroj estos liverita.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "La kvociento de la du nombroj estos liverita.",
                +	"MATH_SINGLE_HELPURL": "https://eo.wikipedia.org/wiki/Kvadrata_radiko",
                +	"MATH_SINGLE_OP_ROOT": "kvadrata radiko",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "La kvadrata radiko de nombro estos liverita.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluta",
                +	"MATH_SINGLE_TOOLTIP_ABS": "La absoluta valoro de nombro estos liverita.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "La negativigo de numero estos liverita.",
                +	"MATH_SINGLE_TOOLTIP_LN": "La natura logaritmo de nombro estos liverita.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "La dekbaza logaritmo de numero estos liverita.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "La rezulto de la potenco de e je la nombro.",
                +	"MATH_TRIG_HELPURL": "https://eo.wikipedia.org/wiki/Trigonometria_funkcio",
                +	"MATH_TRIG_TOOLTIP_ASIN": "La sinusarko de nombro estos liverita.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "La targentarko de nombro estos liverita.",
                +	"MATH_CONSTANT_HELPURL": "https://eo.wikipedia.org/wiki/Matematika_konstanto",
                +	"MATH_IS_EVEN": "estas para",
                +	"MATH_IS_ODD": "estas nepara",
                +	"MATH_IS_PRIME": "estas primo",
                +	"MATH_IS_WHOLE": "estas entjero",
                +	"MATH_IS_POSITIVE": "estas pozitiva",
                +	"MATH_IS_NEGATIVE": "estas negativa",
                +	"MATH_IS_DIVISIBLE_BY": "estas dividebla de",
                +	"MATH_IS_TOOLTIP": "Vero aŭ malvero estos liverita, depende de la rezulto de kontrolo, ĉu nombro estas para, nepara, pozitiva, negativa, aŭ dividebla de iu nombro.",
                +	"MATH_CHANGE_TOOLTIP": "Aldoni nombro al varianto '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Rondigi nombroj, supren aŭ malsupren.",
                +	"MATH_ROUND_OPERATOR_ROUND": "rondigi",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Rondigi supren",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "rondigi malsupren",
                +	"MATH_ONLIST_OPERATOR_SUM": "sumo de listo",
                +	"MATH_ONLIST_TOOLTIP_SUM": "La sumo de ĉiuj nombro en la listo estos liverita.",
                +	"MATH_ONLIST_OPERATOR_MIN": "listminimumo",
                +	"MATH_ONLIST_TOOLTIP_MIN": "La plej eta nombro en la listo estos redonita.",
                +	"MATH_ONLIST_OPERATOR_MAX": "listmaksimumo",
                +	"MATH_ONLIST_TOOLTIP_MAX": "La plej granda numero en la listo estos redonita.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "listmezumo",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "La aritmetika meznombro de la numeroj en la listo estos liverita.",
                +	"MATH_ONLIST_OPERATOR_MODE": "reĝimoj de listo",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "Norma devio de la listo",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "La norma devio de la listo estos liverita.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "hazarda elemento el la listo",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Elemento el la listo estos hazarde liverita.",
                +	"MATH_MODULO_HELPURL": "https://eo.wikipedia.org/wiki/Resto",
                +	"MATH_MODULO_TITLE": "resto de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "La resto de la divido de du nombroj estos liverita.",
                +	"MATH_CONSTRAIN_TITLE": "limigi %1 inter %2 kaj %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "La nombro estos limigita tiel ke ĝi egalas la limojn aŭ troviĝas inter ili.",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "hazarda entjero inter %1 kaj %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Nombro estos hazarde liverita, tiel ke ĝi egalas la limojn aŭ troviĝas inter ili.",
                +	"TEXT_LENGTH_TITLE": "longo de %1",
                +	"TEXT_ISEMPTY_TITLE": "%1 malplenas",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "en la teksto",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "forigi spacojn el la dekstra flanko de",
                +	"TEXT_PRINT_TITLE": "presi %1",
                +	"TEXT_PRINT_TOOLTIP": "Presi la specifitan tekston, nombron aŭ alian valoron.",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Peti nombron al uzanto.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Peti tekston al uzanto.",
                +	"LISTS_CREATE_EMPTY_TITLE": "krei malplenan liston",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Listo, de longo 0, sen datumaj registroj, estos liverita.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Krei liston kun ajna nombro de elementoj.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "krei liston kun",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "listo",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Aldoni, forigi aŭ oridigi sekciojn por reagordi tiun ĉi blokon de listo.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Aldoni elementon al la listo.",
                +	"LISTS_REPEAT_TOOLTIP": "Listo kun la specifita nombro de elementoj, kiuj havos la donitan valoron, estos kreita.",
                +	"LISTS_REPEAT_TITLE": "krei liston kun elemento %1 ripetita %2 fojojn",
                +	"LISTS_LENGTH_TITLE": "longo de %1",
                +	"LISTS_LENGTH_TOOLTIP": "La longo de listo estos liverita.",
                +	"LISTS_ISEMPTY_TITLE": "%1 malplenas",
                +	"LISTS_ISEMPTY_TOOLTIP": "Vero estos liverita, se la listo malplenas.",
                +	"LISTS_INLIST": "en la listo",
                +	"LISTS_INDEX_OF_FIRST": "trovi la unuan aperon de elemento",
                +	"LISTS_INDEX_OF_LAST": "trovi la lastan aperon de elemento",
                +	"LISTS_INDEX_OF_TOOLTIP": "La indekso de la unua/lasta apero de la elemento en la listo estos liverita. %1 estos liverita se la elemento ne estas trovita.",
                +	"LISTS_GET_INDEX_GET": "akiri",
                +	"LISTS_GET_INDEX_GET_REMOVE": "akiri kaj forigi",
                +	"LISTS_GET_INDEX_REMOVE": "forigi",
                +	"LISTS_GET_INDEX_FROM_END": "#el la fino",
                +	"LISTS_GET_INDEX_FIRST": "unuan",
                +	"LISTS_GET_INDEX_LAST": "lastan",
                +	"LISTS_GET_INDEX_RANDOM": "hazardan",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 estas la unua elemento.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 estas la lasta elemento.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "La elemento en la specifita pozicio en la listo estos liverita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "La unua elemento en la listo esto liverita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "La lasta elemento en la listo estos liverita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Hazarda elemento en la listo estos liverita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "La elemento en la specifita pozicio de la listo estos liverita kaj forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "La unua elemento en la listo estos liverita kaj forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "La lasta elemento en la listo estos liverita kaj forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Hazarda elemento en la listo estos liverita kaj forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "La elemento en la specifita pozicio en la listo estos forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "La unua elemento en la listo estos forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "La lasta elemento en la listo estos forigita.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Hazarda elemento en la listo estos forigita.",
                +	"LISTS_SET_INDEX_SET": "difini",
                +	"LISTS_SET_INDEX_INSERT": "enmeti je",
                +	"LISTS_SET_INDEX_INPUT_TO": "kiel",
                +	"PROCEDURES_CREATE_DO": "Krei '%1'"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/es.json b/blockly/webif/static/blockly/msg/json/es.json
                new file mode 100644
                index 000000000..303ce50cc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/es.json
                @@ -0,0 +1,350 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Fitoschido",
                +			"VegaDark",
                +			"WeSiToS",
                +			"Macofe",
                +			"Codynguyen1116",
                +			"Indiralena",
                +			"Rubentl134",
                +			"Martineduardo",
                +			"Julián L",
                +			"Luisangelrg"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "elemento",
                +	"TODAY": "Hoy",
                +	"DUPLICATE_BLOCK": "Duplicar",
                +	"ADD_COMMENT": "Añadir comentario",
                +	"REMOVE_COMMENT": "Eliminar comentario",
                +	"EXTERNAL_INPUTS": "Entradas externas",
                +	"INLINE_INPUTS": "Entradas en línea",
                +	"DELETE_BLOCK": "Eliminar bloque",
                +	"DELETE_X_BLOCKS": "Eliminar %1 bloques",
                +	"DELETE_ALL_BLOCKS": "¿Eliminar todos los %1 bloques?",
                +	"CLEAN_UP": "Limpiar los bloques",
                +	"COLLAPSE_BLOCK": "Contraer bloque",
                +	"COLLAPSE_ALL": "Contraer bloques",
                +	"EXPAND_BLOCK": "Expandir bloque",
                +	"EXPAND_ALL": "Expandir bloques",
                +	"DISABLE_BLOCK": "Desactivar bloque",
                +	"ENABLE_BLOCK": "Activar bloque",
                +	"HELP": "Ayuda",
                +	"UNDO": "Deshacer",
                +	"REDO": "Rehacer",
                +	"CHANGE_VALUE_TITLE": "Cambiar el valor:",
                +	"RENAME_VARIABLE": "Renombrar la variable…",
                +	"RENAME_VARIABLE_TITLE": "Renombrar todas las variables «%1» a:",
                +	"NEW_VARIABLE": "Crear variable…",
                +	"NEW_VARIABLE_TITLE": "Nombre de variable nueva:",
                +	"VARIABLE_ALREADY_EXISTS": "Ya existe una variable llamada \"%1\".",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Ya existe una variable nombrada \"%1\" para otra variable del tipo \"%2\".",
                +	"PROCEDURE_ALREADY_EXISTS": "Ya existe un procedimiento llamado \"%1\".",
                +	"DELETE_VARIABLE_CONFIRMATION": "¿Borrar %1 usos de la variable \"%2\"?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "No se puede eliminar la variable \"%1\" porque es parte de la definición de la función \"%2\"",
                +	"DELETE_VARIABLE": "Borrar la variable \"%1\"",
                +	"COLOUR_PICKER_HELPURL": "https://es.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Elige un color de la paleta.",
                +	"COLOUR_RANDOM_TITLE": "color aleatorio",
                +	"COLOUR_RANDOM_TOOLTIP": "Elige un color al azar.",
                +	"COLOUR_RGB_TITLE": "colorear con",
                +	"COLOUR_RGB_RED": "rojo",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "azul",
                +	"COLOUR_RGB_TOOLTIP": "Crea un color con cantidades específicas de rojo, verde y azul. Todos los valores deben encontrarse entre 0 y 100.",
                +	"COLOUR_BLEND_TITLE": "combinar",
                +	"COLOUR_BLEND_COLOUR1": "color 1",
                +	"COLOUR_BLEND_COLOUR2": "color 2",
                +	"COLOUR_BLEND_RATIO": "proporción",
                +	"COLOUR_BLEND_TOOLTIP": "Combina dos colores con una proporción determinada (0,0–1,0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://es.wikipedia.org/wiki/Bucle_for",
                +	"CONTROLS_REPEAT_TITLE": "repetir %1 veces",
                +	"CONTROLS_REPEAT_INPUT_DO": "hacer",
                +	"CONTROLS_REPEAT_TOOLTIP": "Hacer algunas declaraciones varias veces.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repetir mientras",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repetir hasta",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Mientras un valor sea verdadero, entonces hacer algunas declaraciones.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Mientras un valor sea falso, entonces hacer algunas declaraciones.",
                +	"CONTROLS_FOR_TOOLTIP": "Hacer que la variable \"%1\" tome los valores desde el número de inicio hasta el número final, contando con el intervalo especificado, y hacer los bloques especificados.",
                +	"CONTROLS_FOR_TITLE": "contar con %1 desde %2 hasta %3 de a %4",
                +	"CONTROLS_FOREACH_HELPURL": "https://es.wikipedia.org/wiki/Foreach",
                +	"CONTROLS_FOREACH_TITLE": "para cada elemento %1 en la lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Para cada elemento en una lista, establecer la variable '%1' al elemento y luego hacer algunas declaraciones.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "romper el bucle",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuar con la siguiente iteración del bucle",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Romper el bucle que lo contiene.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Saltar el resto de este bucle, y continuar con la siguiente iteración.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Atención: este bloque puede usarse solamente dentro de un bucle.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si un valor es verdadero, entonces hacer algunas declaraciones.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si un valor es verdadero, entonces hacer el primer bloque de declaraciones.  De lo contrario, hacer el segundo bloque de declaraciones.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si el primer valor es verdadero, entonces hacer el primer bloque de declaraciones. De lo contrario, si el segundo valor es verdadero, hacer el segundo bloque de declaraciones.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si el primer valor es verdadero, entonces hacer el primer bloque de declaraciones. De lo contrario, si el segundo valor es verdadero, hacer el segundo bloque de declaraciones. Si ninguno de los valores son verdaderos, hacer el último bloque de declaraciones.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "sino si",
                +	"CONTROLS_IF_MSG_ELSE": "sino",
                +	"CONTROLS_IF_IF_TOOLTIP": "Agregar, eliminar o reordenar las secciones para reconfigurar este bloque.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Agregar una condición a este bloque.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Agregar una condición general final a este bloque.",
                +	"IOS_OK": "Aceptar",
                +	"IOS_CANCEL": "Cancelar",
                +	"IOS_ERROR": "Error",
                +	"IOS_PROCEDURES_INPUTS": "ENTRADAS",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Añadir entrada",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Permitir declaraciones",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Esta función tiene entradas duplicadas.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Añadir variable",
                +	"IOS_VARIABLES_ADD_BUTTON": "Añadir",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Renombrar",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Borrar",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nombre de la variable",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "No puedes usar un nombre de variable vacío.",
                +	"LOGIC_COMPARE_HELPURL": "https://es.wikipedia.org/wiki/Desigualdad_matemática",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Devuelve verdadero si ambas entradas son iguales.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Devuelve verdadero si ambas entradas son distintas.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Devuelve verdadero si la primera entrada es menor que la segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Devuelve verdadero si la primera entrada es menor que o igual a la segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Devuelve verdadero si la primera entrada es mayor que la segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Devuelve verdadero si la primera entrada es mayor o igual a la segunda entrada.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Devuelve verdadero si ambas entradas son verdaderas.",
                +	"LOGIC_OPERATION_AND": "y",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Devuelve verdadero si al menos una de las entradas es verdadera.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "no %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Devuelve verdadero si la entrada es falsa. Devuelve falso si la entrada es verdadera.",
                +	"LOGIC_BOOLEAN_TRUE": "verdadero",
                +	"LOGIC_BOOLEAN_FALSE": "falso",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Devuelve verdadero o falso.",
                +	"LOGIC_NULL": "nulo",
                +	"LOGIC_NULL_TOOLTIP": "Devuelve nulo.",
                +	"LOGIC_TERNARY_CONDITION": "prueba",
                +	"LOGIC_TERNARY_IF_TRUE": "si es verdadero",
                +	"LOGIC_TERNARY_IF_FALSE": "si es falso",
                +	"LOGIC_TERNARY_TOOLTIP": "Comprueba la condición en \"prueba\". Si la condición es verdadera, devuelve el valor \"si es verdadero\"; de lo contrario, devuelve el valor \"si es falso\".",
                +	"MATH_NUMBER_HELPURL": "https://es.wikipedia.org/wiki/Número",
                +	"MATH_NUMBER_TOOLTIP": "Un número.",
                +	"MATH_ARITHMETIC_HELPURL": "https://es.wikipedia.org/wiki/Aritmética",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Devuelve la suma de ambos números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Devuelve la diferencia de ambos números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Devuelve el producto de ambos números.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Devuelve el cociente de ambos números.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Devuelve el primer número elevado a la potencia del segundo.",
                +	"MATH_SINGLE_HELPURL": "https://es.wikipedia.org/wiki/Ra%C3%ADz_cuadrada",
                +	"MATH_SINGLE_OP_ROOT": "raíz cuadrada",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Devuelve la raíz cuadrada de un número.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluto",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Devuelve el valor absoluto de un número.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Devuelve la negación de un número.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Devuelve el logaritmo natural de un número.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Devuelve el logaritmo base 10 de un número.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Devuelve e a la potencia de un número.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Devuelve 10 a la potencia de un número.",
                +	"MATH_TRIG_HELPURL": "https://es.wikipedia.org/wiki/Función_trigonométrica",
                +	"MATH_TRIG_TOOLTIP_SIN": "Devuelve el seno de un grado (no radián).",
                +	"MATH_TRIG_TOOLTIP_COS": "Devuelve el coseno de un grado (no radián).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Devuelve la tangente de un grado (no radián).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Devuelve el arcoseno de un número.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Devuelve el arcocoseno de un número.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Devuelve el arcotangente de un número.",
                +	"MATH_CONSTANT_HELPURL": "https://es.wikipedia.org/wiki/Anexo:Constantes_matemáticas",
                +	"MATH_CONSTANT_TOOLTIP": "Devuelve una de las constantes comunes: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) o ∞ (infinito).",
                +	"MATH_IS_EVEN": "es par",
                +	"MATH_IS_ODD": "es impar",
                +	"MATH_IS_PRIME": "es primo",
                +	"MATH_IS_WHOLE": "es entero",
                +	"MATH_IS_POSITIVE": "es positivo",
                +	"MATH_IS_NEGATIVE": "es negativo",
                +	"MATH_IS_DIVISIBLE_BY": "es divisible por",
                +	"MATH_IS_TOOLTIP": "Comprueba si un número es par, impar, primo, entero, positivo, negativo, o si es divisible por un número determinado. Devuelve verdadero o falso.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "añadir %2 a %1",
                +	"MATH_CHANGE_TOOLTIP": "Añadir un número a la variable «%1».",
                +	"MATH_ROUND_HELPURL": "https://es.wikipedia.org/wiki/Redondeo",
                +	"MATH_ROUND_TOOLTIP": "Redondear un número al alza o a la baja.",
                +	"MATH_ROUND_OPERATOR_ROUND": "redondear",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "redondear al alza",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "redondear a la baja",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma de la lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Devuelve la suma de todos los números en la lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "mínimo de la lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Devuelve el número más pequeño en la lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "máximo de la lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Devuelve el número más grande en la lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "promedio de la lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Devuelve el promedio (media aritmética) de los valores numéricos en la lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana de la lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Devuelve la mediana en la lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modas de la lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Devuelve una lista de los elementos más comunes en la lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "desviación estándar de la lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Devuelve la desviación estándar de la lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "elemento aleatorio de la lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Devuelve un elemento aleatorio de la lista.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "resto de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Devuelve el resto al dividir los dos números.",
                +	"MATH_CONSTRAIN_TITLE": "limitar %1 entre %2 y %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Limitar un número entre los límites especificados (inclusive).",
                +	"MATH_RANDOM_INT_HELPURL": "https://es.wikipedia.org/wiki/Generador_de_números_aleatorios",
                +	"MATH_RANDOM_INT_TITLE": "entero aleatorio de %1 a %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Devuelve un entero aleatorio entre los dos límites especificados, inclusive.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://es.wikipedia.org/wiki/Generador_de_números_aleatorios",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fracción aleatoria",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Devuelve una fracción aleatoria entre 0,0 (ambos inclusive) y 1.0 (exclusivo).",
                +	"TEXT_TEXT_HELPURL": "https://es.wikipedia.org/wiki/Cadena_de_caracteres",
                +	"TEXT_TEXT_TOOLTIP": "Una letra, palabra o línea de texto.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "crear texto con",
                +	"TEXT_JOIN_TOOLTIP": "Crear un fragmento de texto al unir cualquier número de elementos.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Agregar, eliminar o reordenar las secciones para reconfigurar este bloque de texto.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Agregar un elemento al texto.",
                +	"TEXT_APPEND_TITLE": "a %1 añade el texto %2",
                +	"TEXT_APPEND_TOOLTIP": "Añadir texto a la variable '%1'.",
                +	"TEXT_LENGTH_TITLE": "longitud de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Devuelve el número de letras (espacios incluidos) del texto proporcionado.",
                +	"TEXT_ISEMPTY_TITLE": "%1 está vacío",
                +	"TEXT_ISEMPTY_TOOLTIP": "Devuelve verdadero si el texto proporcionado está vacío.",
                +	"TEXT_INDEXOF_TOOLTIP": "Devuelve el índice de la primera/última aparición del primer texto en el segundo texto. Devuelve %1 si el texto no se encuentra.",
                +	"TEXT_INDEXOF_TITLE": "en el texto %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "encontrar la primera aparición del texto",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "encontrar la última aparición del texto",
                +	"TEXT_CHARAT_TITLE": "en el texto %1 %2",
                +	"TEXT_CHARAT_FROM_START": "obtener la letra #",
                +	"TEXT_CHARAT_FROM_END": "obtener la letra # del final",
                +	"TEXT_CHARAT_FIRST": "obtener la primera letra",
                +	"TEXT_CHARAT_LAST": "obtener la última letra",
                +	"TEXT_CHARAT_RANDOM": "obtener letra aleatoria",
                +	"TEXT_CHARAT_TOOLTIP": "Devuelve la letra en la posición especificada.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Devuelve una porción determinada del texto.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "en el texto",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "obtener subcadena desde la letra #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "obtener subcadena desde la letra # del final",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "obtener subcadena desde la primera letra",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "hasta la letra #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "hasta la letra # del final",
                +	"TEXT_GET_SUBSTRING_END_LAST": "hasta la última letra",
                +	"TEXT_CHANGECASE_TOOLTIP": "Devuelve una copia del texto en un tamaño diferente.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "a MAYÚSCULAS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "a minúsculas",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "a Mayúsculas Cada Palabra",
                +	"TEXT_TRIM_TOOLTIP": "Devuelve una copia del texto sin los espacios de uno o ambos extremos.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "quitar espacios de ambos lados de",
                +	"TEXT_TRIM_OPERATOR_LEFT": "quitar espacios iniciales de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "quitar espacios finales de",
                +	"TEXT_PRINT_TITLE": "imprimir %1",
                +	"TEXT_PRINT_TOOLTIP": "Imprimir el texto, número u otro valor especificado.",
                +	"TEXT_PROMPT_TYPE_TEXT": "solicitar texto con el mensaje",
                +	"TEXT_PROMPT_TYPE_NUMBER": "solicitar número con el mensaje",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Solicitar al usuario un número.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Solicitar al usuario un texto.",
                +	"TEXT_COUNT_MESSAGE0": "contar %1 en %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Cuantas veces aparece un texto dentro de otro texto.",
                +	"TEXT_REPLACE_MESSAGE0": "reemplazar %1 con %2 en %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Reemplazar todas las veces que un texto dentro de otro texto.",
                +	"TEXT_REVERSE_MESSAGE0": "invertir %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Invierte el orden de los caracteres en el texto.",
                +	"LISTS_CREATE_EMPTY_TITLE": "crear lista vacía",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Devuelve una lista, de longitud 0, sin ningún dato",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Crear una lista con cualquier número de elementos.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "crear lista con",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Agregar, eliminar o reorganizar las secciones para reconfigurar este bloque de lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Agregar un elemento a la lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Crea una lista que consta de un valor dado repetido el número de veces especificado.",
                +	"LISTS_REPEAT_TITLE": "crear lista con el elemento %1 repetido %2 veces",
                +	"LISTS_LENGTH_TITLE": "longitud de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Devuelve la longitud de una lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 está vacía",
                +	"LISTS_ISEMPTY_TOOLTIP": "Devuelve verdadero si la lista está vacía.",
                +	"LISTS_INLIST": "en la lista",
                +	"LISTS_INDEX_OF_FIRST": "encontrar la primera aparición del elemento",
                +	"LISTS_INDEX_OF_LAST": "encontrar la última aparición del elemento",
                +	"LISTS_INDEX_OF_TOOLTIP": "Devuelve el índice de la primera/última aparición del elemento en la lista. Devuelve %1 si el elemento no se encuentra.",
                +	"LISTS_GET_INDEX_GET": "obtener",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obtener y eliminar",
                +	"LISTS_GET_INDEX_REMOVE": "eliminar",
                +	"LISTS_GET_INDEX_FROM_END": "# del final",
                +	"LISTS_GET_INDEX_FIRST": "primero",
                +	"LISTS_GET_INDEX_LAST": "último",
                +	"LISTS_GET_INDEX_RANDOM": "aleatorio",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 es el primer elemento.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 es el último elemento.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Devuelve el elemento en la posición especificada en una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Devuelve el primer elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Devuelve el último elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Devuelve un elemento aleatorio en una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Elimina y devuelve el elemento en la posición especificada en una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Elimina y devuelve el primer elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Elimina y devuelve el último elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Elimina y devuelve un elemento aleatorio en una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Elimina el elemento en la posición especificada en una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Elimina el primer elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Elimina el último elemento de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Elimina un elemento aleatorio en una lista.",
                +	"LISTS_SET_INDEX_SET": "establecer",
                +	"LISTS_SET_INDEX_INSERT": "insertar en",
                +	"LISTS_SET_INDEX_INPUT_TO": "como",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Establece el elemento en la posición especificada en una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Establece el primer elemento de una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Establece el último elemento de una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Establece un elemento aleatorio en una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserta el elemento en la posición especificada en una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Inserta el elemento al inicio de una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Añade el elemento al final de una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Inserta el elemento aleatoriamente en una lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "obtener sublista desde #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "obtener sublista desde # del final",
                +	"LISTS_GET_SUBLIST_START_FIRST": "obtener sublista desde el primero",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "hasta #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "hasta # del final",
                +	"LISTS_GET_SUBLIST_END_LAST": "hasta el último",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Crea una copia de la parte especificada de una lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "orden %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordenar una copia de una lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ascendente",
                +	"LISTS_SORT_ORDER_DESCENDING": "descendente",
                +	"LISTS_SORT_TYPE_NUMERIC": "numérico",
                +	"LISTS_SORT_TYPE_TEXT": "alfabético",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabético, ignorar mayúscula/minúscula",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "hacer lista a partir de texto",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "hacer texto a partir de lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "con delimitador",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dividir el texto en una lista de textos, separando en cada delimitador.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Unir una lista de textos en un solo texto, separado por un delimitador.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "invertir %1",
                +	"LISTS_REVERSE_TOOLTIP": "Invertir una copia de una lista.",
                +	"VARIABLES_GET_TOOLTIP": "Devuelve el valor de esta variable.",
                +	"VARIABLES_GET_CREATE_SET": "Crear 'establecer %1'",
                +	"VARIABLES_SET": "establecer %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Establece esta variable para que sea igual a la entrada.",
                +	"VARIABLES_SET_CREATE_GET": "Crear 'obtener %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "para",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "hacer algo",
                +	"PROCEDURES_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crea una función sin salida.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Describe esta función...",
                +	"PROCEDURES_DEFRETURN_RETURN": "devuelve",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Crea una función con una salida.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permitir declaraciones",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Advertencia: Esta función tiene parámetros duplicados.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://es.wikipedia.org/wiki/Subrutina",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Ejecuta la función definida por el usuario '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://es.wikipedia.org/wiki/Subrutina",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Ejecuta la función definida por el usuario '%1' y usa su salida.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entradas",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Añadir, eliminar o reordenar entradas para esta función.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nombre de entrada:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Añadir una entrada a la función.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Destacar definición de la función",
                +	"PROCEDURES_CREATE_DO": "Crear '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Si un valor es verdadero, entonces devuelve un segundo valor.",
                +	"PROCEDURES_IFRETURN_WARNING": "Advertencia: Este bloque solo puede ser utilizado dentro de la definición de una función."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/et.json b/blockly/webif/static/blockly/msg/json/et.json
                new file mode 100644
                index 000000000..fc9f3aba8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/et.json
                @@ -0,0 +1,309 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Aivarannamaa",
                +			"Hasso"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "objekt",
                +	"TODAY": "Täna",
                +	"DUPLICATE_BLOCK": "Tekita duplikaat",
                +	"ADD_COMMENT": "Lisa kommentaar",
                +	"REMOVE_COMMENT": "Eemalda kommentaar",
                +	"EXTERNAL_INPUTS": "Sisendid ploki taga",
                +	"INLINE_INPUTS": "Sisendid ploki sees",
                +	"DELETE_BLOCK": "Kustuta plokk",
                +	"DELETE_X_BLOCKS": "Kustuta %1 plokki",
                +	"DELETE_ALL_BLOCKS": "Kas kustutada kõik %1 plokki?",
                +	"CLEAN_UP": "Korista plokid kokku",
                +	"COLLAPSE_BLOCK": "Tõmba plokk kokku",
                +	"COLLAPSE_ALL": "Tõmba plokid kokku",
                +	"EXPAND_BLOCK": "Laota plokk laiali",
                +	"EXPAND_ALL": "Laota plokid laiali",
                +	"DISABLE_BLOCK": "Keela ploki kasutamine",
                +	"ENABLE_BLOCK": "Luba ploki kasutamine",
                +	"HELP": "Abi",
                +	"UNDO": "Võta tagasi",
                +	"REDO": "Tee uuesti",
                +	"CHANGE_VALUE_TITLE": "Muuda väärtust:",
                +	"RENAME_VARIABLE": "Nimeta muutuja ümber ...",
                +	"RENAME_VARIABLE_TITLE": "Muutuja „%1“ uus nimi:",
                +	"NEW_VARIABLE": "Uus muutuja ...",
                +	"NEW_VARIABLE_TITLE": "Uue muutuja nimi:",
                +	"VARIABLE_ALREADY_EXISTS": "'%1'-nimeline muutuja on juba olemas.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Kas kustutada %1 kohas kasutatav muutuja '%2'?",
                +	"DELETE_VARIABLE": "Kustuta muutuja '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Valitud värv paletist.",
                +	"COLOUR_RANDOM_TITLE": "juhuslik värv",
                +	"COLOUR_RANDOM_TOOLTIP": "Juhuslikult valitud värv.",
                +	"COLOUR_RGB_TITLE": "segu",
                +	"COLOUR_RGB_RED": "punasest",
                +	"COLOUR_RGB_GREEN": "rohelisest",
                +	"COLOUR_RGB_BLUE": "sinisest",
                +	"COLOUR_RGB_TOOLTIP": "Tekitab värvi määratud hulgast punasest, rohelisest ja sinisest. Kõik väärtused peavad olema 0 ja 100 vahel.",
                +	"COLOUR_BLEND_TITLE": "segu",
                +	"COLOUR_BLEND_COLOUR1": "1. värvist",
                +	"COLOUR_BLEND_COLOUR2": "2. värvist",
                +	"COLOUR_BLEND_RATIO": "suhtega",
                +	"COLOUR_BLEND_TOOLTIP": "Segab kaks värvi määratud suhtega (0.0 - 1.0) kokku.",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "%1 korda",
                +	"CONTROLS_REPEAT_INPUT_DO": "käivita",
                +	"CONTROLS_REPEAT_TOOLTIP": "Plokis olevate käskude käivitamine määratud arv kordi.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "seni kuni on",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "seni kuni pole",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Plokis olevaid käske korratakse seni kui avaldis on tõene.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Plokis olevaid käske korratakse seni kui avaldis pole tõene.",
                +	"CONTROLS_FOR_TOOLTIP": "Annab muutujale '%1' väärtused ühest numbrist teiseni, muutes seda intervalli kaupa ja käivitab igal muudatusel ploki sees oleva koodi.",
                +	"CONTROLS_FOR_TITLE": "loendus muutujaga %1 alates %2 kuni %3, %4 kaupa",
                +	"CONTROLS_FOREACH_TITLE": "iga elemendiga %1 loendis %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Iga elemendiga loendis anna muutujale '%1' elemendi väärtus ja kõivita plokis olevad käsud.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "välju kordusest",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "katkesta see kordus ja liigu järgmisele",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Väljub kordusest ja liigub edasi korduse järel oleva koodi käivitamisele.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Katkestab korduses oleva koodi käivitamise ja käivitab järgmise korduse.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Hoiatus: Seda plokki saab kasutada ainult korduse sees.",
                +	"CONTROLS_IF_TOOLTIP_1": "Kui avaldis on tõene, käivita ploki sees olevad käsud.",
                +	"CONTROLS_IF_TOOLTIP_2": "Kui avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul käivita käsud teisest plokist.",
                +	"CONTROLS_IF_TOOLTIP_3": "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist.",
                +	"CONTROLS_IF_TOOLTIP_4": "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist. Kui ükski avaldistest pole tõene, käivita käsud viimasest plokist.",
                +	"CONTROLS_IF_MSG_IF": "kui",
                +	"CONTROLS_IF_MSG_ELSEIF": "vastasel juhul, kui",
                +	"CONTROLS_IF_MSG_ELSE": "vastasel juhul",
                +	"CONTROLS_IF_IF_TOOLTIP": "Selle „kui“ ploki muutmine sektsioonide lisamise, eemaldamise ja järjestamisega.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Lisab „kui“ plokile tingimuse.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Lisab „kui“ plokile lõpliku tingimuseta koodiploki.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Tagastab „tõene“, kui avaldiste väärtused on võrdsed.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Tagastab „tõene“, kui avaldiste väärtused pole võrdsed.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem kui teise väärtus.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem või võrdne teise väärtusega.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Tagastab „tõene“, kui esimese avaldise väärtus on suurem kui teise väärtus.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Tagastab „tõene“, kui esimese avaldise väärtus on suurem või võrdne teise väärtusega.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Tagastab „tõene“, kui mõlemad avaldised on tõesed.",
                +	"LOGIC_OPERATION_AND": "ja",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Tagastab „tõene“, kui vähemalt üks avaldistest on tõene.",
                +	"LOGIC_OPERATION_OR": "või",
                +	"LOGIC_NEGATE_TITLE": "pole %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Tagastab „tõene“, kui avaldis on väär. Tagastab „väär“, kui avaldis on tõene.",
                +	"LOGIC_BOOLEAN_TRUE": "tõene",
                +	"LOGIC_BOOLEAN_FALSE": "väär",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Tagastab tõeväärtuse – kas „tõene“ või „väär“.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Tagastab nulli.",
                +	"LOGIC_TERNARY_CONDITION": "tingimus",
                +	"LOGIC_TERNARY_IF_TRUE": "kui tõene",
                +	"LOGIC_TERNARY_IF_FALSE": "kui väär",
                +	"LOGIC_TERNARY_TOOLTIP": "Kui tingimuse väärtus on tõene, tagastab „kui tõene“ väärtuse, vastasel juhul „kui väär“ väärtuse.",
                +	"MATH_NUMBER_HELPURL": "https://et.wikipedia.org/wiki/Arv",
                +	"MATH_NUMBER_TOOLTIP": "Arv.",
                +	"MATH_ARITHMETIC_HELPURL": "https://et.wikipedia.org/wiki/Aritmeetika",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Tagastab kahe arvu summa.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Tagastab kahe arvu vahe.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Tagastab kahe arvu korrutise.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Tagastab kahe arvu jagatise.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Tagastab esimese arvu teise arvu astmes.",
                +	"MATH_SINGLE_HELPURL": "https://et.wikipedia.org/wiki/Ruutjuur",
                +	"MATH_SINGLE_OP_ROOT": "ruutjuur",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Tagastab arvu ruutjuure.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluutväärtus",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Tagastab arvu absoluutväärtuse.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Tagastab arvu vastandväärtuse.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Tagastab arvu naturaallogaritmi.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Tagastab arvu kümnendlogaritm.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Tagasta e arvu astmes.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Tagastab 10 arvu astmes.",
                +	"MATH_TRIG_HELPURL": "https://et.wikipedia.org/wiki/Trigonomeetrilised_funktsioonid",
                +	"MATH_TRIG_TOOLTIP_SIN": "Tagastab arvu (kraadid) siinuse.",
                +	"MATH_TRIG_TOOLTIP_COS": "Tagastab arvu (kraadid) kosiinuse.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Tagastab arvu (kraadid) tangensi.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Tagastab arvu arkussiinuse.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Tagastab arvu arkuskoosiinuse.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Tagastab arvu arkustangensi.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Tagastab ühe konstantidest: π (3,141…), e (2,718…), φ (1.618…), √2) (1,414…), √½ (0,707…), või ∞ (infinity).",
                +	"MATH_IS_EVEN": "on paarisarv",
                +	"MATH_IS_ODD": "on paaritu arv",
                +	"MATH_IS_PRIME": "on algarv",
                +	"MATH_IS_WHOLE": "on täisarv",
                +	"MATH_IS_POSITIVE": "on positiivne arv",
                +	"MATH_IS_NEGATIVE": "on negatiivne arv",
                +	"MATH_IS_DIVISIBLE_BY": "jagub arvuga",
                +	"MATH_IS_TOOLTIP": "Kontrollib kas arv on paarisarv, paaritu arv, algarv, täisarv, positiivne, negatiivne või jagub kindla arvuga. Tagastab „tõene“ või „väär“.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "muuda %1 %2 võrra",
                +	"MATH_CHANGE_TOOLTIP": "Lisab arvu muutujale '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Ümardab arvu üles või alla.",
                +	"MATH_ROUND_OPERATOR_ROUND": "ümarda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ümarda üles",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ümarda alla",
                +	"MATH_ONLIST_OPERATOR_SUM": "loendi summa",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Tagastab kõigi loendis olevate arvude summa.",
                +	"MATH_ONLIST_OPERATOR_MIN": "loendi miinimum",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Tagastab väikseima loendis oleva arvu.",
                +	"MATH_ONLIST_OPERATOR_MAX": "loendi maksimum",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Tagastab suurima loendis oleva arvu.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "loendi keskmine",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Tagastab loendis olevate arvväärtuste aritmeetilise keskmise.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "loendi mediaan",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Return the median number in the list.",
                +	"MATH_ONLIST_OPERATOR_MODE": "loendi moodid",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Tagastab loendi kõige sagedamini esinevate loendi liikmetega.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "loendi standardhälve",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Tagastab loendi standardhälbe.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "juhuslik element loendist",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Tagastab juhusliku elemendi loendist.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 jääk",
                +	"MATH_MODULO_TOOLTIP": "Tagastab esimese numbri teisega jagamisel tekkiva jäägi.",
                +	"MATH_CONSTRAIN_TITLE": "%1 piirang %2 ja %3 vahele",
                +	"MATH_CONSTRAIN_TOOLTIP": "Piirab arvu väärtuse toodud piiridesse (piirarvud kaasa arvatud).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "juhuslik täisarv %1 ja %2 vahel",
                +	"MATH_RANDOM_INT_TOOLTIP": "Tagastab juhusliku täisarvu toodud piiride vahel (piirarvud kaasa arvatud).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "juhuslik murdosa",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Tagastab juhusliku murdosa 0.0 (kaasa arvatud) and 1.0 (välja arvatud) vahel.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Täht, sõna või rida teksti.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "tekita tekst",
                +	"TEXT_JOIN_TOOLTIP": "Tekitab teksti ühendades mistahes arvu elemente.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "ühenda",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Tekstiploki muutmine sektsioonide lisamise, eemaldamise või järjestuse muutmisega.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Objekti lisamine tekstile.",
                +	"TEXT_APPEND_TOOLTIP": "Lisab teksti muutuja „%1“ väärtuse lõppu.",
                +	"TEXT_LENGTH_TITLE": "%1 pikkus",
                +	"TEXT_LENGTH_TOOLTIP": "Tagastab sümbolite aru (ka tühikud) toodud tekstis.",
                +	"TEXT_ISEMPTY_TITLE": "%1 on tühi",
                +	"TEXT_ISEMPTY_TOOLTIP": "Tagastab „tõene“, kui tekstis pole ühtegi sümbolit.",
                +	"TEXT_INDEXOF_TOOLTIP": "Tagastab esimesest tekstist esimese/viimase leitud teise teksti asukoha (indeksi). Kui teksti ei leita, tagastab %1.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "esimese leitud tekstitüki",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "viimase leitud tekstitüki",
                +	"TEXT_CHARAT_FROM_START": "sümbol #",
                +	"TEXT_CHARAT_FROM_END": "lõpust sümbol #",
                +	"TEXT_CHARAT_FIRST": "esimene sümbol",
                +	"TEXT_CHARAT_LAST": "viimane sümbol",
                +	"TEXT_CHARAT_RANDOM": "juhuslik sümbol",
                +	"TEXT_CHARAT_TOOLTIP": "Tagastab tekstis määratud asukohal oleva sümboli.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Tagastab määratud tüki tekstist.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "tekstist",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "alates sümbolist #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "alates (lõpust) sümbolist #",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "alates esimesest sümbolist",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "kuni sümbolini #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "kuni (lõpust) sümbolini #",
                +	"TEXT_GET_SUBSTRING_END_LAST": "kuni viimase sümbolini",
                +	"TEXT_CHANGECASE_TOOLTIP": "Tagastab muudetud tähesuurusega teksti koopia.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "SUURTE TÄHTEDEGA",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "väikeste tähtedega",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Suurte Esitähtedega",
                +	"TEXT_TRIM_TOOLTIP": "Tagastab koopia tekstist, millel on tühikud ühelt või mõlemalt poolt eemaldatud.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "mõlemalt poolt eemaldatud tühikutega",
                +	"TEXT_TRIM_OPERATOR_LEFT": "algusest eemaldatud tühikutega",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "lõpust eemaldatud tühikutega",
                +	"TEXT_PRINT_TITLE": "trüki %1",
                +	"TEXT_PRINT_TOOLTIP": "Trükib määratud teksti, numbri või mõne muu objekti väärtuse.",
                +	"TEXT_PROMPT_TYPE_TEXT": "kasutajalt küsitud tekst teatega",
                +	"TEXT_PROMPT_TYPE_NUMBER": "kasutajalt küsitud arv teatega",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Küsib kasutajalt teadet näidates mingit arvu.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Küsib kasutajalt teadet näidates mingit teksti.",
                +	"LISTS_CREATE_EMPTY_TITLE": "tühi loend",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Tagastab loendi, mille pikkus on 0 ja milles pole ühtegi elementi.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Tekitab mistahes arvust elementidest loendi.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "uus loend",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "loend",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Loendiploki elementide lisamine, eemaldamine või järjestuse muutmine.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Elemendi lisamine loendisse.",
                +	"LISTS_REPEAT_TOOLTIP": "Tekitab uue loendi, millesse lisatakse ühte elementi pikkusega määratud arv kordi.",
                +	"LISTS_REPEAT_TITLE": "loend pikkusega %2 elemendist %1",
                +	"LISTS_LENGTH_TITLE": "%1 pikkus",
                +	"LISTS_LENGTH_TOOLTIP": "Tagastab loendi pikkuse.",
                +	"LISTS_ISEMPTY_TITLE": "%1 on tühi",
                +	"LISTS_ISEMPTY_TOOLTIP": "Tagastab „tõene“ kui loend on tühi.",
                +	"LISTS_INLIST": "loendis",
                +	"LISTS_INDEX_OF_FIRST": "esimene leitud",
                +	"LISTS_INDEX_OF_LAST": "viimase leitud",
                +	"LISTS_INDEX_OF_TOOLTIP": "Tagastab esimese/viimase loendist leitud objekti asukoha (objekti järjekorranumbri loendis). Kui objekti ei leita, tagastab %1.",
                +	"LISTS_GET_INDEX_GET": "võetud",
                +	"LISTS_GET_INDEX_GET_REMOVE": "võetud ja eemaldatud",
                +	"LISTS_GET_INDEX_REMOVE": "eemalda",
                +	"LISTS_GET_INDEX_FROM_START": "element #",
                +	"LISTS_GET_INDEX_FROM_END": "element # (lõpust)",
                +	"LISTS_GET_INDEX_FIRST": "esimene element",
                +	"LISTS_GET_INDEX_LAST": "viimane element",
                +	"LISTS_GET_INDEX_RANDOM": "juhuslik element",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Esimene element on %1.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Viimane element on %1.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Tagastab loendis määratud asukohal oleva elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Tagastab loendi esimese elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Tagastab loendi viimase elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Tagastab loendi juhusliku elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Tagastab ja eemaldab loendist määratud asukohal oleva elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Tagastab ja eemaldab loendist esimese elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Tagastab ja eemaldab loendist viimase elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Tagastab ja eemaldab loendist juhusliku elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Eemaldab loendist määratud asukohal oleva elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Eemaldab loendist esimese elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Eemaldab loendist viimase elemendi.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Eemaldab loendist juhusliku elemendi.",
                +	"LISTS_SET_INDEX_SET": "asenda",
                +	"LISTS_SET_INDEX_INSERT": "lisa asukohale",
                +	"LISTS_SET_INDEX_INPUT_TO": ", väärtus",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Asendab loendis määratud kohal oleva elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Asendab loendis esimese elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Asendab loendis viimase elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Asendab loendis juhusliku elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Lisab määratud asukohale loendis uue elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Lisab loendi algusesse uue elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Lisab loendi lõppu uue elemendi.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Lisab juhuslikule kohale loendis uue elemendi.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "alamloend elemendist #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "alamloend elemendist # (lõpust)",
                +	"LISTS_GET_SUBLIST_START_FIRST": "alamloend algusest",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "elemendini #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "elemendini # (lõpust)",
                +	"LISTS_GET_SUBLIST_END_LAST": "lõpuni",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Tekitab loendi määratud osast koopia.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "%1 %2 sorteeritud %3",
                +	"LISTS_SORT_TOOLTIP": "Loendi koopia sorteerimine.",
                +	"LISTS_SORT_ORDER_ASCENDING": "kasvavalt",
                +	"LISTS_SORT_ORDER_DESCENDING": "kahanevalt",
                +	"LISTS_SORT_TYPE_NUMERIC": "arvväärtuste järgi",
                +	"LISTS_SORT_TYPE_TEXT": "tähestiku järgi",
                +	"LISTS_SORT_TYPE_IGNORECASE": "tähestiku järgi (tähesuurust eirates)",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "loend, tekitatud tekstist",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "tekst, tekitatud loendist",
                +	"LISTS_SPLIT_WITH_DELIMITER": "eraldajaga",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Tükeldab teksti eraldajade kohalt ja asetab tükid tekstide loendisse.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Ühendab tekstide loendis olevad tükid üheks tekstiks, asetades tükkide vahele eraldaja.",
                +	"VARIABLES_GET_TOOLTIP": "Tagastab selle muutuja väärtuse.",
                +	"VARIABLES_GET_CREATE_SET": "Tekita 'määra „%1“ väärtuseks' plokk",
                +	"VARIABLES_SET": "määra %1 väärtuseks %2",
                +	"VARIABLES_SET_TOOLTIP": "Määrab selle muutuja väärtuse võrdseks sisendi väärtusega.",
                +	"VARIABLES_SET_CREATE_GET": "Tekita '„%1“ väärtus' plokk",
                +	"PROCEDURES_DEFNORETURN_TITLE": "funktsioon",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "teeme midagi",
                +	"PROCEDURES_BEFORE_PARAMS": "sisenditega:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "sisenditega:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Tekitab funktsiooni, mis ei tagasta midagi.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Funktsiooni kirjeldus ...",
                +	"PROCEDURES_DEFRETURN_RETURN": "tagasta",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Tekitab funktsiooni, mis tagastab midagi.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "kood plokis",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Hoiatus: Sel funktsioonil on mitu sama nimega sisendit.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Käivitab kasutaja defineeritud funktsiooni '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Run the user-defined function '%1' and use its output.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "sisendid",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Funktsiooni sisendite lisamine, eemaldamine või järjestuse muutmine.",
                +	"PROCEDURES_MUTATORARG_TITLE": "sisend nimega:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Lisab funktsioonile sisendi.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Tõsta funktsiooni definitsioon esile",
                +	"PROCEDURES_CREATE_DO": "Tekita '%1' plokk",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Kui väärtus on tõene, tagastatakse teine väärtus.",
                +	"PROCEDURES_IFRETURN_WARNING": "Hoiatus: Seda plokki saab kasutada ainult funktsiooni definitsioonis."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/fa.json b/blockly/webif/static/blockly/msg/json/fa.json
                new file mode 100644
                index 000000000..f719395ea
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/fa.json
                @@ -0,0 +1,327 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Ebraminio",
                +			"Reza1615",
                +			"Alirezaaa",
                +			"Mehran",
                +			"MohandesWiki",
                +			"Dalba",
                +			"Hamisun",
                +			"Nhzandi"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "مورد",
                +	"TODAY": "امروز",
                +	"DUPLICATE_BLOCK": "تکراری",
                +	"ADD_COMMENT": "افزودن نظر",
                +	"REMOVE_COMMENT": "حذف نظر",
                +	"EXTERNAL_INPUTS": "ورودی‌های خارجی",
                +	"INLINE_INPUTS": "ورودی‌های درون خطی",
                +	"DELETE_BLOCK": "حذف بلوک",
                +	"DELETE_X_BLOCKS": "حذف بلوک‌های %1",
                +	"DELETE_ALL_BLOCKS": "حذف همهٔ بلاک‌های %1؟",
                +	"CLEAN_UP": "تمیز کردن بلوک‌ها",
                +	"COLLAPSE_BLOCK": "فروپاشی بلوک",
                +	"COLLAPSE_ALL": "فروپاشی بلوک‌ها",
                +	"EXPAND_BLOCK": "گسترش بلوک",
                +	"EXPAND_ALL": "گسترش بلوک‌ها",
                +	"DISABLE_BLOCK": "غیرفعال‌سازی بلوک",
                +	"ENABLE_BLOCK": "فعال‌سازی بلوک",
                +	"HELP": "راهنما",
                +	"UNDO": "واگردانی",
                +	"REDO": "انجام دوباره",
                +	"CHANGE_VALUE_TITLE": "تغییر مقدار:",
                +	"RENAME_VARIABLE": "تغییر نام متغیر...",
                +	"RENAME_VARIABLE_TITLE": "تغییر نام همهٔ متغیرهای «%1» به:",
                +	"NEW_VARIABLE": "ایجاد متغیر...",
                +	"NEW_VARIABLE_TITLE": "نام متغیر تازه:",
                +	"VARIABLE_ALREADY_EXISTS": "متغیری با نام '%1' هم اکنون وجود دارد",
                +	"DELETE_VARIABLE_CONFIRMATION": "تعداد %1 استفاده از متغیر '%2' پاک شود؟",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "متغیر '%1' را نمی‌توان پاک کرد، زیرا جزیی از تعریف متغیر '%2' می‌باشد",
                +	"DELETE_VARIABLE": "متغیر '%1'را پاک کنید",
                +	"COLOUR_PICKER_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%86%DA%AF",
                +	"COLOUR_PICKER_TOOLTIP": "انتخاب یک رنگ از تخته‌رنگ.",
                +	"COLOUR_RANDOM_TITLE": "رنگ تصادفی",
                +	"COLOUR_RANDOM_TOOLTIP": "انتخاب یک رنگ به شکل تصادفی.",
                +	"COLOUR_RGB_TITLE": "رنگ با",
                +	"COLOUR_RGB_RED": "قرمز",
                +	"COLOUR_RGB_GREEN": "سبز",
                +	"COLOUR_RGB_BLUE": "آبی",
                +	"COLOUR_RGB_TOOLTIP": "ساخت یک رنگ با مقدار مشخص‌شده‌ای از قرمز، سبز و آبی. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.",
                +	"COLOUR_BLEND_TITLE": "مخلوط",
                +	"COLOUR_BLEND_COLOUR1": "رنگ ۱",
                +	"COLOUR_BLEND_COLOUR2": "رنگ ۲",
                +	"COLOUR_BLEND_RATIO": "نسبت",
                +	"COLOUR_BLEND_TOOLTIP": "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)",
                +	"CONTROLS_REPEAT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AD%D9%84%D9%82%D9%87_%D9%81%D9%88%D8%B1",
                +	"CONTROLS_REPEAT_TITLE": "%1 بار تکرار",
                +	"CONTROLS_REPEAT_INPUT_DO": "انجام",
                +	"CONTROLS_REPEAT_TOOLTIP": "انجام چند عبارت چندین بار.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "تکرار در حالی که",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "تکرار تا زمانی که",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_FOR_TOOLTIP": "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.",
                +	"CONTROLS_FOR_TITLE": "با تعداد %1 از %2 به %3 با گام‌های %4",
                +	"CONTROLS_FOREACH_TITLE": "برای هر مورد %1 در فهرست %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "خروج از حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ادامه با تکرار بعدی حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "شکستن حلقهٔ شامل.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.",
                +	"CONTROLS_IF_TOOLTIP_1": "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_2": "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_3": "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_4": "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.",
                +	"CONTROLS_IF_MSG_IF": "اگر",
                +	"CONTROLS_IF_MSG_ELSEIF": "درغیر اینصورت اگر",
                +	"CONTROLS_IF_MSG_ELSE": "درغیر اینصورت",
                +	"CONTROLS_IF_IF_TOOLTIP": "افزودن، حذف یا بازمرتب‌سازی قسمت‌ها برای پیکربندی دوبارهٔ این بلوک اگر.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "افزودن یک شرط به بلوک اگر.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "اضافه کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.",
                +	"IOS_OK": "تأیید",
                +	"IOS_CANCEL": "لغو",
                +	"IOS_ERROR": "خطا",
                +	"IOS_PROCEDURES_INPUTS": "ورودی‌ها",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ افزودن ورودی",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ افزودن متغیر",
                +	"IOS_VARIABLES_ADD_BUTTON": "افزودن",
                +	"IOS_VARIABLES_RENAME_BUTTON": "تغییر نام",
                +	"IOS_VARIABLES_DELETE_BUTTON": "حذف",
                +	"IOS_VARIABLES_VARIABLE_NAME": "نام متغیر",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "نام متغیر نمی‌تواند خالی باشد",
                +	"LOGIC_COMPARE_HELPURL": "https://fa.wikipedia.org/wiki/%D9%86%D8%A7%D8%A8%D8%B1%D8%A7%D8%A8%D8%B1%DB%8C",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_AND": "و",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_OR": "یا",
                +	"LOGIC_NEGATE_TITLE": "نه %1",
                +	"LOGIC_NEGATE_TOOLTIP": "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.",
                +	"LOGIC_BOOLEAN_TRUE": "صحیح",
                +	"LOGIC_BOOLEAN_FALSE": "ناصحیح",
                +	"LOGIC_BOOLEAN_TOOLTIP": "بازگرداندن یکی از صحیح یا ناصحیح.",
                +	"LOGIC_NULL": "تهی",
                +	"LOGIC_NULL_TOOLTIP": "تهی بازمی‌گرداند.",
                +	"LOGIC_TERNARY_CONDITION": "آزمایش",
                +	"LOGIC_TERNARY_IF_TRUE": "اگر صحیح",
                +	"LOGIC_TERNARY_IF_FALSE": "اگر ناصحیح",
                +	"LOGIC_TERNARY_TOOLTIP": "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.",
                +	"MATH_NUMBER_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B9%D8%AF%D8%AF",
                +	"MATH_NUMBER_TOOLTIP": "یک عدد.",
                +	"MATH_ARITHMETIC_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AD%D8%B3%D8%A7%D8%A8",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "بازگرداندن مقدار جمع دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "بازگرداندن تفاوت دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "بازگرداندن حاصلضرب دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "بازگرداندن باقی‌ماندهٔ دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.",
                +	"MATH_SINGLE_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%DB%8C%D8%B4%D9%87_%D8%AF%D9%88%D9%85",
                +	"MATH_SINGLE_OP_ROOT": "ریشهٔ دوم",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ریشهٔ دوم یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "مطلق",
                +	"MATH_SINGLE_TOOLTIP_ABS": "قدر مطلق یک عدد را بازمی‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "منفی‌شدهٔ یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LN": "لوگاریتم طبیعی یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "بازگرداندن توان e یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "بازگرداندن توان ۱۰ یک عدد.",
                +	"MATH_TRIG_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%D9%87%D8%A7%DB%8C_%D9%85%D8%AB%D9%84%D8%AB%D8%A7%D8%AA%DB%8C",
                +	"MATH_TRIG_TOOLTIP_SIN": "بازگرداندن سینوس یک زاویه به درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_COS": "بازگرداندن کسینوس یک زاویه درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_TAN": "بازگرداندن تانژانت یک زاویه به درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "بازگرداندن آرک‌سینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ACOS": "بازگرداندن آرک‌کسینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "بازگرداندن آرک‌تانژانت درجه (نه رادیان).",
                +	"MATH_CONSTANT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AB%D8%A7%D8%A8%D8%AA_%D8%B1%DB%8C%D8%A7%D8%B6%DB%8C",
                +	"MATH_CONSTANT_TOOLTIP": "یکی از مقادیر ثابت جهانی را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).",
                +	"MATH_IS_EVEN": "زوج است",
                +	"MATH_IS_ODD": "فرد است",
                +	"MATH_IS_PRIME": "عدد اول است",
                +	"MATH_IS_WHOLE": "کامل است",
                +	"MATH_IS_POSITIVE": "مثبت است",
                +	"MATH_IS_NEGATIVE": "منفی است",
                +	"MATH_IS_DIVISIBLE_BY": "تقسیم شده بر",
                +	"MATH_IS_TOOLTIP": "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.",
                +	"MATH_CHANGE_HELPURL": "https://fa.wikipedia.org/wiki/%D8%A7%D8%B5%D8%B7%D9%84%D8%A7%D8%AD_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C#.D8.A7.D9.81.D8.B2.D8.A7.DB.8C.D8.B4_.D8.B4.D9.85.D8.A7.D8.B1.D9.86.D8.AF.D9.87",
                +	"MATH_CHANGE_TITLE": "تغییر %1 با %2",
                +	"MATH_CHANGE_TOOLTIP": "افزودن یک عدد به متغیر '%1'.",
                +	"MATH_ROUND_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"MATH_ROUND_TOOLTIP": "گردکردن یک عدد به بالا یا پایین.",
                +	"MATH_ROUND_OPERATOR_ROUND": "گردکردن",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "گرد به بالا",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "گرد به پایین",
                +	"MATH_ONLIST_OPERATOR_SUM": "جمع فهرست",
                +	"MATH_ONLIST_TOOLTIP_SUM": "جمع همهٔ عددهای فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MIN": "کوچک‌ترین عدد در فهرست",
                +	"MATH_ONLIST_TOOLTIP_MIN": "کوچک‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MAX": "بزرگ‌ترین عدد در فهرست",
                +	"MATH_ONLIST_TOOLTIP_MAX": "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "میانگین فهرست",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "میانهٔ فهرست",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "میانهٔ عدد در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MODE": "مد فهرست",
                +	"MATH_ONLIST_TOOLTIP_MODE": "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "انحراف معیار فهرست",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "انحراف معیار فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "مورد تصادفی از فهرست",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "موردی تصادفی از فهرست را بر می‌گرداند.",
                +	"MATH_MODULO_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B9%D9%85%D9%84%DB%8C%D8%A7%D8%AA_%D9%BE%DB%8C%D9%85%D8%A7%D9%86%D9%87",
                +	"MATH_MODULO_TITLE": "باقی‌ماندهٔ %1 + %2",
                +	"MATH_MODULO_TOOLTIP": "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.",
                +	"MATH_CONSTRAIN_TITLE": "محدودکردن %1 پایین %2 بالا %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).",
                +	"MATH_RANDOM_INT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C",
                +	"MATH_RANDOM_INT_TITLE": "عدد صحیح تصادفی بین %1 تا %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%AA%D9%88%D9%84%DB%8C%D8%AF_%D8%A7%D8%B9%D8%AF%D8%A7%D8%AF_%D8%AA%D8%B5%D8%A7%D8%AF%D9%81%DB%8C",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "کسر تصادفی",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).",
                +	"TEXT_TEXT_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D8%B4%D8%AA%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"TEXT_TEXT_TOOLTIP": "یک حرف، کلمه یا خطی از متن.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ایجاد متن با",
                +	"TEXT_JOIN_TOOLTIP": "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "عضویت",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "اضافه کردن، حذف یا مرتب‌سازی بحش‌ها برای تنظیم مجدد این بلوک متنی.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "افزودن یک مورد به متن.",
                +	"TEXT_APPEND_TOOLTIP": "الحاق متنی به متغیر «%1».",
                +	"TEXT_LENGTH_TITLE": "طول %1",
                +	"TEXT_LENGTH_TOOLTIP": "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.",
                +	"TEXT_ISEMPTY_TITLE": "%1 خالی است",
                +	"TEXT_ISEMPTY_TOOLTIP": "اضافه کردن صحیح اگر متن فراهم‌شده خالی است.",
                +	"TEXT_INDEXOF_TOOLTIP": "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "اولین رخداد متن را بیاب",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "آخرین رخداد متن را بیاب",
                +	"TEXT_CHARAT_FROM_START": "گرفتن حرف #",
                +	"TEXT_CHARAT_FROM_END": "گرفتن حرف # از آخر",
                +	"TEXT_CHARAT_FIRST": "گرفتن اولین حرف",
                +	"TEXT_CHARAT_LAST": "گرفتن آخرین حرف",
                +	"TEXT_CHARAT_RANDOM": "گرفتن حرف تصادفی",
                +	"TEXT_CHARAT_TOOLTIP": "حرفی در موقعیت مشخص‌شده بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "در متن",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "گرفتن زیرمتن از حرف #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "گرفتن زیرمتن از حرف # به انتها",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "گرفتن زیرمتن از اولین حرف",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "به حرف #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "به حرف # از انتها",
                +	"TEXT_GET_SUBSTRING_END_LAST": "به آخرین حرف",
                +	"TEXT_CHANGECASE_TOOLTIP": "بازگرداندن کپی متن در حالتی متفاوت.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "به حروف بزرگ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "به حروف کوچک",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "به حروف بزرگ عنوان",
                +	"TEXT_TRIM_TOOLTIP": "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "تراشیدن فاصله‌ها از  هر دو طرف",
                +	"TEXT_TRIM_OPERATOR_LEFT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_PRINT_TITLE": "چاپ %1",
                +	"TEXT_PRINT_TOOLTIP": "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.",
                +	"TEXT_PROMPT_TYPE_TEXT": "اعلان برای متن با پیام",
                +	"TEXT_PROMPT_TYPE_NUMBER": "اعلان برای عدد با پیام",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "اعلان برای کاربر با یک عدد.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "اعلان برای کاربر برای یک متن.",
                +	"TEXT_COUNT_MESSAGE0": "تعداد %1 را در %2 بشمار",
                +	"TEXT_COUNT_TOOLTIP": "تعداد دفعاتی که یک متن درون یک متن دیگر تکرار شده است را برمی‌گرداند",
                +	"TEXT_REPLACE_MESSAGE0": "درون %3، متن %1 را با %2 جایگزین کن",
                +	"TEXT_REVERSE_MESSAGE0": "معکوس %1",
                +	"TEXT_REVERSE_TOOLTIP": "چینش کاراکترها درون متن را برعکس می‌کند",
                +	"LISTS_CREATE_EMPTY_TITLE": "ایجاد فهرست خالی",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "فهرستی از هر عددی از موارد می‌سازد.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "ایجاد فهرست با",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "فهرست",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "اضافه کردن، حذف کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "اضافه کردن یک مورد به فهرست.",
                +	"LISTS_REPEAT_TOOLTIP": "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.",
                +	"LISTS_REPEAT_TITLE": "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد",
                +	"LISTS_LENGTH_TITLE": "طول %1",
                +	"LISTS_LENGTH_TOOLTIP": "طول یک فهرست را برمی‌گرداند.",
                +	"LISTS_ISEMPTY_TITLE": "%1 خالی است",
                +	"LISTS_ISEMPTY_TOOLTIP": "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.",
                +	"LISTS_INLIST": "در فهرست",
                +	"LISTS_INDEX_OF_FIRST": "یافتن اولین رخ‌داد مورد",
                +	"LISTS_INDEX_OF_LAST": "یافتن آخرین رخ‌داد مورد",
                +	"LISTS_INDEX_OF_TOOLTIP": "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر آیتم موجود نبود.",
                +	"LISTS_GET_INDEX_GET": "گرفتن",
                +	"LISTS_GET_INDEX_GET_REMOVE": "گرفتن و حذف‌کردن",
                +	"LISTS_GET_INDEX_REMOVE": "حذف‌کردن",
                +	"LISTS_GET_INDEX_FROM_END": "# از انتها",
                +	"LISTS_GET_INDEX_FIRST": "اولین",
                +	"LISTS_GET_INDEX_LAST": "آخرین",
                +	"LISTS_GET_INDEX_RANDOM": "تصادفی",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 اولین مورد است.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 آخرین مورد است.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "موردی در محل مشخص‌شده بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "اولین مورد یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "آخرین مورد در یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "یک مورد تصادفی در یک فهرست بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "اولین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "آخرین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "یک مورد تصادفی را یک فهرست حذف می‌کند.",
                +	"LISTS_SET_INDEX_SET": "مجموعه",
                +	"LISTS_SET_INDEX_INSERT": "درج در",
                +	"LISTS_SET_INDEX_INPUT_TO": "به عنوان",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "اولین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "آخرین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "یک مورد تصادفی در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "موردی به ته فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "موردی به ته فهرست الحاق می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "مورد را به صورت تصادفی در یک فهرست می‌افزاید.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "گرفتن زیرمجموعه‌ای از #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "گرفتن زیرمجموعه‌ای از # از انتها",
                +	"LISTS_GET_SUBLIST_START_FIRST": "گرفتن زیرمجموعه‌ای از ابتدا",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "به #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "به # از انتها",
                +	"LISTS_GET_SUBLIST_END_LAST": "به آخرین",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.",
                +	"LISTS_SORT_ORDER_ASCENDING": "صعودی",
                +	"LISTS_SORT_ORDER_DESCENDING": "نزولی",
                +	"LISTS_SORT_TYPE_NUMERIC": "عددی",
                +	"LISTS_SORT_TYPE_TEXT": "حروفی ، الفبایی",
                +	"LISTS_SORT_TYPE_IGNORECASE": "حروفی ، رد کردن مورد",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "ایجاد فهرست از متن",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "ایجاد متن از فهرست",
                +	"LISTS_SPLIT_WITH_DELIMITER": "همراه جداساز",
                +	"LISTS_REVERSE_MESSAGE0": "معکوس %1",
                +	"VARIABLES_GET_TOOLTIP": "مقدار این متغیر را بر می‌گرداند.",
                +	"VARIABLES_GET_CREATE_SET": "درست‌کردن «تنظیم %1»",
                +	"VARIABLES_SET": "مجموعه %1 به %2",
                +	"VARIABLES_SET_TOOLTIP": "متغیر برابر با خروجی را مشخص می‌کند.",
                +	"VARIABLES_SET_CREATE_GET": "درست‌کردن «گرفتن %1»",
                +	"PROCEDURES_DEFNORETURN_TITLE": "به",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "انجام چیزی",
                +	"PROCEDURES_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "تابعی می‌سازد بدون هیچ خروجی.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "توصیف این عملکرد...",
                +	"PROCEDURES_DEFRETURN_RETURN": "بازگشت",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "تابعی با یک خروجی می‌سازد.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "اجازه اظهارات",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "اخطار: این تابعی پارامتر تکراری دارد.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1».",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://fa.wikipedia.org/wiki/%D8%B1%D9%88%DB%8C%D9%87_%28%D8%B9%D9%84%D9%88%D9%85_%D8%B1%D8%A7%DB%8C%D8%A7%D9%86%D9%87%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ورودی‌ها",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.",
                +	"PROCEDURES_MUTATORARG_TITLE": "نام ورودی:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "اضافه کردن ورودی به تابع.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "برجسته‌سازی تعریف تابع",
                +	"PROCEDURES_CREATE_DO": "ساختن «%1»",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "اگر یک مقدار صحیح است، مقدار دوم را برگردان.",
                +	"PROCEDURES_IFRETURN_WARNING": "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/fi.json b/blockly/webif/static/blockly/msg/json/fi.json
                new file mode 100644
                index 000000000..9ab85cdfa
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/fi.json
                @@ -0,0 +1,351 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Nike",
                +			"Silvonen",
                +			"Espertus",
                +			"Pettevi",
                +			"McSalama",
                +			"Espeox",
                +			"SNuutti",
                +			"PStudios",
                +			"Mikahama",
                +			"Pyscowicz",
                +			"Pahkiqaz",
                +			"Hopea"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "kohde",
                +	"TODAY": "Tänään",
                +	"DUPLICATE_BLOCK": "Kaksoiskappale",
                +	"ADD_COMMENT": "Lisää kommentti",
                +	"REMOVE_COMMENT": "Poista kommentti",
                +	"EXTERNAL_INPUTS": "Ulkoiset syötteet",
                +	"INLINE_INPUTS": "Tuo syötteet",
                +	"DELETE_BLOCK": "Poista lohko",
                +	"DELETE_X_BLOCKS": "Poista %1 lohkoa",
                +	"DELETE_ALL_BLOCKS": "Poistetaanko kaikki %1 lohkoa?",
                +	"CLEAN_UP": "Siivoa lohkot",
                +	"COLLAPSE_BLOCK": "Sulje lohko",
                +	"COLLAPSE_ALL": "Sulje lohkot",
                +	"EXPAND_BLOCK": "Laajenna lohko",
                +	"EXPAND_ALL": "Laajenna lohkot",
                +	"DISABLE_BLOCK": "Passivoi lohko",
                +	"ENABLE_BLOCK": "Aktivoi lohko",
                +	"HELP": "Apua",
                +	"UNDO": "Kumoa",
                +	"REDO": "Tee uudelleen",
                +	"CHANGE_VALUE_TITLE": "Muuta arvoa:",
                +	"RENAME_VARIABLE": "Nimeä uudelleen muuttuja...",
                +	"RENAME_VARIABLE_TITLE": "Nimeä uudelleen kaikki '%1' muuttujaa:",
                +	"NEW_VARIABLE": "Luo muuttuja...",
                +	"NEW_VARIABLE_TITLE": "Uuden muuttujan nimi:",
                +	"VARIABLE_ALREADY_EXISTS": "Muuttuja nimeltään '%1' jo olemassa.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Muuttuja nimeltä '%1' on jo olemassa toiselle muuttujalle tyypiltään '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Toiminto nimeltään '%1' on jo olemassa.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Poistetaanko %1 käyttöä muuttujalta '%2'?",
                +	"DELETE_VARIABLE": "Poista muuttuja '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://fi.wikipedia.org/wiki/V%C3%A4ri",
                +	"COLOUR_PICKER_TOOLTIP": "Valitse väri paletista.",
                +	"COLOUR_RANDOM_TITLE": "satunnainen väri",
                +	"COLOUR_RANDOM_TOOLTIP": "Valitse väri sattumanvaraisesti.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "väri, jossa on",
                +	"COLOUR_RGB_RED": "punainen",
                +	"COLOUR_RGB_GREEN": "vihreä",
                +	"COLOUR_RGB_BLUE": "sininen",
                +	"COLOUR_RGB_TOOLTIP": "Luo väri, jossa on tietty määrä punaista, vihreää ja sinistä. Kaikkien arvojen tulee olla välillä 0 - 100.",
                +	"COLOUR_BLEND_TITLE": "sekoitus",
                +	"COLOUR_BLEND_COLOUR1": "väri 1",
                +	"COLOUR_BLEND_COLOUR2": "väri 2",
                +	"COLOUR_BLEND_RATIO": "suhde",
                +	"COLOUR_BLEND_TOOLTIP": "Sekoittaa kaksi väriä keskenään annetussa suhteessa (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "toista %1 kertaa",
                +	"CONTROLS_REPEAT_INPUT_DO": "tee",
                +	"CONTROLS_REPEAT_TOOLTIP": "Suorita joukko lausekkeita useampi kertaa.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "toista niin kauan kuin",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "toista kunnes",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Niin kauan kuin arvo on tosi, suorita joukko lausekkeita.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Niin kauan kuin arvo on epätosi, suorita joukko lausekkeita.",
                +	"CONTROLS_FOR_TOOLTIP": "Aseta muuttujaan \"%1\" arvot alkuarvosta loppuarvoon annetun askeleen välein ja suorita joka askeleella annettu koodilohko.",
                +	"CONTROLS_FOR_TITLE": "laske %1 Väli %2-%3 %4:n välein",
                +	"CONTROLS_FOREACH_TITLE": "kullekin kohteelle %1 listassa %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Aseta muuttujan %1 arvoksi kukin listan kohde vuorollaan ja suorita joukko lausekkeita.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "poistu silmukasta",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "jatka silmukan seuraavaan toistoon",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Poistu sisemmästä silmukasta.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Ohita loput tästä silmukasta ja siirry seuraavaan toistoon.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Varoitus: Tätä lohkoa voi käyttää vain silmukan sisällä.",
                +	"CONTROLS_IF_TOOLTIP_1": "Jos arvo on tosi, suorita lauseke.",
                +	"CONTROLS_IF_TOOLTIP_2": "Jos arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten suorita toinen lohko lausekkeita.",
                +	"CONTROLS_IF_TOOLTIP_3": "Jos ensimmäinen arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten, jos toinen arvo on tosi, suorita toinen lohko lausekkeita.",
                +	"CONTROLS_IF_TOOLTIP_4": "Jos ensimmäinen arvo on tosi, suorita ensimmäinen lohko lausekkeita. Muuten, jos toinen arvo on tosi, suorita toinen lohko lausekkeita. Jos mikään arvoista ei ole tosi, suorita viimeinen lohko lausekkeita.",
                +	"CONTROLS_IF_MSG_IF": "jos",
                +	"CONTROLS_IF_MSG_ELSEIF": "muuten jos",
                +	"CONTROLS_IF_MSG_ELSE": "muuten",
                +	"CONTROLS_IF_IF_TOOLTIP": "Lisää, poista tai järjestele osioita tässä \"jos\" lohkossa.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Lisää ehto \"jos\" lohkoon.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Lisää lopullinen \"muuten\" lohko \"jos\" lohkoon.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Peruuta",
                +	"IOS_ERROR": "Virhe",
                +	"IOS_PROCEDURES_INPUTS": "SYÖTTEET",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Lisää syöte",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Lisää muuttuja",
                +	"IOS_VARIABLES_ADD_BUTTON": "Lisää",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Nimeä uudelleen",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Poista",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Muuttujan nimi",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Et voi käyttää tyhjää muuttujan nimeä.",
                +	"LOGIC_COMPARE_HELPURL": "https://fi.wikipedia.org/wiki/Ep%C3%A4yht%C3%A4l%C3%B6",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Palauta tosi, jos syötteet ovat keskenään samat.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Palauttaa tosi, jos syötteet eivät ole keskenään samoja.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Palauttaa tosi, jos ensimmäinen syöte on pienempi, kuin toinen.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Palauttaa tosi, jos ensimmäinen syöte on pienempi tai yhtä suuri, kuin toinen.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Palauttaa tosi, jos ensimmäinen syöte on suurempi, kuin toinen.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Palauttaa tosi, jos ensimmäinen syöte on suurempi tai yhtä suuri, kuin toinen.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Palauttaa tosi, jos kummatkin syötteet ovat tosia.",
                +	"LOGIC_OPERATION_AND": "ja",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Palauttaa tosi, jos ainakin yksi syötteistä on tosi.",
                +	"LOGIC_OPERATION_OR": "tai",
                +	"LOGIC_NEGATE_TITLE": "ei %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Palauttaa tosi, jos syöte on epätosi. Palauttaa epätosi, jos syöte on tosi.",
                +	"LOGIC_BOOLEAN_TRUE": "tosi",
                +	"LOGIC_BOOLEAN_FALSE": "epätosi",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Palauttaa joko tosi tai epätosi.",
                +	"LOGIC_NULL": "ei mitään",
                +	"LOGIC_NULL_TOOLTIP": "Palauttaa \"ei mitään\"-arvon.",
                +	"LOGIC_TERNARY_CONDITION": "testi",
                +	"LOGIC_TERNARY_IF_TRUE": "jos tosi",
                +	"LOGIC_TERNARY_IF_FALSE": "jos epätosi",
                +	"LOGIC_TERNARY_TOOLTIP": "Tarkistaa testin ehdon. Jos ehto on tosi, palauttaa \"jos tosi\" arvon, muuten palauttaa \"jos epätosi\" arvon.",
                +	"MATH_NUMBER_HELPURL": "https://fi.wikipedia.org/wiki/Luku",
                +	"MATH_NUMBER_TOOLTIP": "Luku.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "⋅",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "http://fi.wikipedia.org/wiki/Aritmetiikka",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Palauttaa kahden luvun summan.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Palauttaa kahden luvun erotuksen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Palauttaa kertolaskun tulon.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Palauttaa jakolaskun osamäärän.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Palauttaa ensimmäisen luvun korotettuna toisen luvun potenssiin.",
                +	"MATH_SINGLE_HELPURL": "https://fi.wikipedia.org/wiki/Neli%C3%B6juuri",
                +	"MATH_SINGLE_OP_ROOT": "neliöjuuri",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Palauttaa luvun neliöjuuren.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "itseisarvo",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Palauttaa luvun itseisarvon.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Palauttaa numeron vastaluvun.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Palauttaa luvun luonnollisen logaritmin.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Palauttaa luvun kymmenkantaisen logaritmin.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Palauttaa e potenssiin luku.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Palauttaa 10 potenssiin luku.",
                +	"MATH_TRIG_HELPURL": "https://fi.wikipedia.org/wiki/Trigonometrinen_funktio",
                +	"MATH_TRIG_TOOLTIP_SIN": "Palauttaa asteluvun (ei radiaanin) sinin.",
                +	"MATH_TRIG_TOOLTIP_COS": "Palauttaa asteluvun (ei radiaanin) kosinin.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Palauttaa asteluvun (ei radiaanin) tangentin.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Palauttaa luvun arkussinin.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Palauttaa luvun arkuskosinin.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Palauttaa luvun arkustangentin.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Palauttaa jonkin seuraavista vakioista: π (3.141…), e (2.718…), φ (1.618…), neliöjuuri(2) (1.414…), neliöjuuri(½) (0.707…), or ∞ (ääretön).",
                +	"MATH_IS_EVEN": "on parillinen",
                +	"MATH_IS_ODD": "on pariton",
                +	"MATH_IS_PRIME": "on alkuluku",
                +	"MATH_IS_WHOLE": "on kokonaisluku",
                +	"MATH_IS_POSITIVE": "on positiivinen",
                +	"MATH_IS_NEGATIVE": "on negatiivinen",
                +	"MATH_IS_DIVISIBLE_BY": "on jaollinen luvulla",
                +	"MATH_IS_TOOLTIP": "Tarkistaa onko numero parillinen, pariton, alkuluku, kokonaisluku, positiivinen, negatiivinen, tai jos se on jaollinen toisella luvulla. Palauttaa tosi tai epätosi.",
                +	"MATH_CHANGE_HELPURL": "https://fi.wikipedia.org/wiki/Yhteenlasku",
                +	"MATH_CHANGE_TITLE": "muuta %1 arvolla %2",
                +	"MATH_CHANGE_TOOLTIP": "Lisää arvo muuttujaan '%1'.",
                +	"MATH_ROUND_HELPURL": "https://fi.wikipedia.org/wiki/Py%C3%B6rist%C3%A4minen",
                +	"MATH_ROUND_TOOLTIP": "Pyöristää luvun ylös- tai alaspäin.",
                +	"MATH_ROUND_OPERATOR_ROUND": "pyöristä",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "pyöristä ylöspäin",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "pyöristä alaspäin",
                +	"MATH_ONLIST_OPERATOR_SUM": "summa luvuista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Palauttaa kaikkien annettujen lukujen summan.",
                +	"MATH_ONLIST_OPERATOR_MIN": "pienin luvuista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Palauttaa pienimmän annetuista luvuista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "suurin luvuista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Palauttaa suurimman annetuista luvuista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "keskiarvo luvuista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Palauttaa aritmeettisen keskiarvon annetuista luvuista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "keskiluku luvuista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Palauttaa annettujen lukujen keskiluvun.",
                +	"MATH_ONLIST_OPERATOR_MODE": "tyyppiarvo luvuista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Palauttaa luettelon yleisimmistä luvuista annetussa listassa.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "keskihajonta luvuista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Palauttaa annettujen lukujen keskihajonnan.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "satunnainen valinta luvuista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Palauttaa satunnaisesti valitun luvun annetuista luvuista.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 jakojäännös",
                +	"MATH_MODULO_TOOLTIP": "Palauttaa jakolaskun jakojäännöksen.",
                +	"MATH_CONSTRAIN_TITLE": "rajoita %1 vähintään %2 enintään %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Rajoittaa arvon annetulle suljetulle välille.",
                +	"MATH_RANDOM_INT_HELPURL": "https://fi.wikipedia.org/wiki/Satunnaisluku",
                +	"MATH_RANDOM_INT_TITLE": "Palauttaa satunnaisen kokonaisluvun väliltä %1-%2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Palauttaa satunnaisen kokonaisluvun kahden annetun arvon suljetulta väliltä.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://fi.wikipedia.org/wiki/Satunnaisluku",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "satunnainen murtoluku",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Palauttaa satunnaisen luvun oikealta puoliavoimesta välistä [0.0, 1.0).",
                +	"TEXT_TEXT_HELPURL": "https://fi.wikipedia.org/wiki/Merkkijono",
                +	"TEXT_TEXT_TOOLTIP": "Kirjain, sana tai rivi tekstiä.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "luo teksti",
                +	"TEXT_JOIN_TOOLTIP": "Luo merkkijonon liittämällä yhteen minkä tahansa määrän kohteita.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "liitä",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Lisää, poista tai uudelleen järjestä osioita tässä lohkossa.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Lisää kohteen tekstiin.",
                +	"TEXT_APPEND_TOOLTIP": "Lisää tekstiä muuttujaan '%1'.",
                +	"TEXT_LENGTH_TITLE": "%1:n pituus",
                +	"TEXT_LENGTH_TOOLTIP": "Palauttaa annetussa tekstissä olevien merkkien määrän (välilyönnit mukaan lukien).",
                +	"TEXT_ISEMPTY_TITLE": "%1 on tyhjä",
                +	"TEXT_ISEMPTY_TOOLTIP": "Palauttaa tosi, jos annettu teksti on tyhjä.",
                +	"TEXT_INDEXOF_TOOLTIP": "Palauttaa ensin annetun tekstin ensimmäisen/viimeisen esiintymän osoitteen toisessa tekstissä. Palauttaa osoitteen %1 jos tekstiä ei löytynyt.",
                +	"TEXT_INDEXOF_TITLE": "tekstissä %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "etsi ensimmäinen esiintymä merkkijonolle",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "etsi viimeinen esiintymä merkkijonolle",
                +	"TEXT_CHARAT_TITLE": "tekstissä %1 %2",
                +	"TEXT_CHARAT_FROM_START": "Hae kirjain nro",
                +	"TEXT_CHARAT_FROM_END": "Hae kirjain nro (lopusta laskien)",
                +	"TEXT_CHARAT_FIRST": "hae ensimmäinen kirjain",
                +	"TEXT_CHARAT_LAST": "hae viimeinen kirjain",
                +	"TEXT_CHARAT_RANDOM": "hae satunnainen kirjain",
                +	"TEXT_CHARAT_TOOLTIP": "Palauttaa annetussa kohdassa olevan kirjaimen.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Palauttaa määrätyn osan tekstistä.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "merkkijonosta",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "hae osa alkaen kirjaimesta nro",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "hae osa alkaen kirjaimesta nro (lopusta laskien)",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "hae osa alkaen ensimmäisestä kirjaimesta",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "kirjaimeen nro",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "kirjaimeen nro (lopusta laskien)",
                +	"TEXT_GET_SUBSTRING_END_LAST": "viimeiseen kirjaimeen",
                +	"TEXT_CHANGECASE_TOOLTIP": "Palauttaa kopion tekstistä eri kirjainkoossa.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "isot kirjaimet",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "pienet kirjaimet",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "isot alkukirjaimet",
                +	"TEXT_TRIM_TOOLTIP": "Palauttaa kopion tekstistä siten, että välilyönnit on poistettu yhdestä tai molemmista päistä.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "poistaa välilyönnit kummaltakin puolelta",
                +	"TEXT_TRIM_OPERATOR_LEFT": "poistaa välilyönnit vasemmalta puolelta",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "poistaa välilyönnit oikealta puolelta",
                +	"TEXT_PRINT_TITLE": "tulosta %1",
                +	"TEXT_PRINT_TOOLTIP": "Tulostaa annetun tekstin, numeron tai muun arvon.",
                +	"TEXT_PROMPT_TYPE_TEXT": "käyttäen annettua viestiä, kehottaa syöttämään tekstiä",
                +	"TEXT_PROMPT_TYPE_NUMBER": "käyttäen annettua viestiä, kehottaa syöttämään numeron",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Kehottaa käyttäjää syöttämään numeron.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Kehottaa käyttäjää syöttämään tekstiä.",
                +	"TEXT_COUNT_MESSAGE0": "laske määrä '%1' '%2' sisällä",
                +	"TEXT_COUNT_TOOLTIP": "Laske kuiunka monta kertaa jokin teksti esiintyy jossakin toisessa tekstissä.",
                +	"TEXT_REVERSE_MESSAGE0": "%1 takaperin",
                +	"TEXT_REVERSE_TOOLTIP": "Muuttaa tekstin kirjainten järjestyksen toisin päin.",
                +	"LISTS_CREATE_EMPTY_TITLE": "Luo tyhjä lista",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Palauta tyhjä lista, pituus 0",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Luo lista, jossa on mikä tahansa määrä kohteita.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "luo lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Listää, poista tai järjestele uudestaan osioita tässä lohkossa.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Lisää kohde listaan.",
                +	"LISTS_REPEAT_TOOLTIP": "Luo listan, jossa annettu arvo toistuu määrätyn monta kertaa.",
                +	"LISTS_REPEAT_TITLE": "luo lista, jossa kohde %1 toistuu %2 kertaa",
                +	"LISTS_LENGTH_TITLE": "%1:n pituus",
                +	"LISTS_LENGTH_TOOLTIP": "Palauttaa listan pituuden.",
                +	"LISTS_ISEMPTY_TITLE": "%1 on tyhjä",
                +	"LISTS_ISEMPTY_TOOLTIP": "Palauttaa tosi, jos lista on tyhjä.",
                +	"LISTS_INLIST": "listassa",
                +	"LISTS_INDEX_OF_FIRST": "etsi ensimmäinen esiintymä kohteelle",
                +	"LISTS_INDEX_OF_LAST": "etsi viimeinen esiintymä kohteelle",
                +	"LISTS_INDEX_OF_TOOLTIP": "Palauttaa kohteen ensimmäisen/viimeisen esiintymän kohdan listassa. Palauttaa %1 jos kohdetta ei löydy.",
                +	"LISTS_GET_INDEX_GET": "hae",
                +	"LISTS_GET_INDEX_GET_REMOVE": "hae ja poista",
                +	"LISTS_GET_INDEX_REMOVE": "poista",
                +	"LISTS_GET_INDEX_FROM_START": "nro",
                +	"LISTS_GET_INDEX_FROM_END": "nro (lopusta laskien)",
                +	"LISTS_GET_INDEX_FIRST": "ensimmäinen",
                +	"LISTS_GET_INDEX_LAST": "viimeinen",
                +	"LISTS_GET_INDEX_RANDOM": "satunnainen",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Numero %1 tarkoittaa listan ensimmäistä kohdetta.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Numero %1 tarkoittaa listan viimeistä kohdetta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Palauta kohde annetusta kohdasta listaa.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Palauta ensimmäinen kohde listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Palauttaa listan viimeisen kohteen.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Palauttaa satunnaisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Poistaa ja palauttaa kohteen listan annetusta kohdasta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Poistaa ja palauttaa ensimmäisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Poistaa ja palauttaa viimeisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Poistaa ja palauttaa satunnaisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Poistaa kohteen listalta annetusta kohtaa.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Poistaa ensimmäisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Poistaa viimeisen kohteen listalta.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Poistaa satunnaisen kohteen listalta.",
                +	"LISTS_SET_INDEX_SET": "aseta",
                +	"LISTS_SET_INDEX_INSERT": "lisää kohtaan",
                +	"LISTS_SET_INDEX_INPUT_TO": "kohteeksi",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Asettaa kohteen annettuun kohtaan listassa.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Asettaa listan ensimmäisen kohteen.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Asettaa listan viimeisen kohteen.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Asettaa satunnaisen kohteen listassa.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Lisää kohteen annettuun kohtaan listassa.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Lisää kohteen listan kärkeen.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Lisää kohteen listan loppuun.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Lisää kohteen satunnaiseen kohtaan listassa.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "hae osalista alkaen kohdasta",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "hae osalista alkaen kohdasta (lopusta laskien)",
                +	"LISTS_GET_SUBLIST_START_FIRST": "hae osalista alkaen alusta",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "päättyen kohtaan",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "päättyen kohtaan (lopusta laskien)",
                +	"LISTS_GET_SUBLIST_END_LAST": "viimeinen",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Luo kopio määrätystä kohden listaa.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "lajittele %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Lajittele kopio luettelosta.",
                +	"LISTS_SORT_ORDER_ASCENDING": "nouseva",
                +	"LISTS_SORT_ORDER_DESCENDING": "laskeva",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeerinen",
                +	"LISTS_SORT_TYPE_TEXT": "aakkosjärjestys",
                +	"LISTS_SORT_TYPE_IGNORECASE": "aakkosjärjestyksessä, ohita kapitaalit",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "tee lista tekstistä",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "tee listasta teksti",
                +	"LISTS_SPLIT_WITH_DELIMITER": "erottimen kanssa",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Jaa teksti osiin erotinmerkin perusteella ja järjestä osat listaksi.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Yhdistä luettelon tekstit yhdeksi tekstiksi, erotettuina välimerkillä.",
                +	"VARIABLES_GET_TOOLTIP": "Palauttaa muuttujan arvon.",
                +	"VARIABLES_GET_CREATE_SET": "Luo 'aseta %1'",
                +	"VARIABLES_SET": "aseta %1 arvoksi %2",
                +	"VARIABLES_SET_TOOLTIP": "Asettaa muutujan arvoksi annetun syötteen.",
                +	"VARIABLES_SET_CREATE_GET": "Luo 'hae %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "tehdäksesi",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "tee jotain",
                +	"PROCEDURES_BEFORE_PARAMS": "parametrit:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "parametrit:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Luo funktio, jolla ei ole tuotosta.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Kuvaile tämä funktio...",
                +	"PROCEDURES_DEFRETURN_RETURN": "palauta",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Luo funktio, jolla ei ole tuotosta.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "salli kommentit",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Varoitus: tällä funktiolla on sama parametri useamman kerran.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://fi.wikipedia.org/wiki/Aliohjelma",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Suorittaa käyttäjän määrittelemä funktio '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://fi.wikipedia.org/wiki/Aliohjelma",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Suorittaa käyttäjän määrittelemän funktion '%1' ja käyttää sen tuotosta.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "syötteet",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Lisää, poista tai järjestele uudelleen tämän toiminnon tulot.",
                +	"PROCEDURES_MUTATORARG_TITLE": "syötteen nimi:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Lisää sisääntulon funktioon.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Korosta funktion määritelmä",
                +	"PROCEDURES_CREATE_DO": "Luo '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Jos arvo on tosi, palauta toinen arvo.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Varoitus: tätä lohkoa voi käyttää vain funktion määrityksessä."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/fr.json b/blockly/webif/static/blockly/msg/json/fr.json
                new file mode 100644
                index 000000000..9746df4f4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/fr.json
                @@ -0,0 +1,353 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"Gomoko",
                +			"ProfGra",
                +			"Wladek92",
                +			"Fredlefred",
                +			"Grimault",
                +			"Rixed",
                +			"Frigory",
                +			"Appr"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "élément",
                +	"TODAY": "Aujourd'hui",
                +	"DUPLICATE_BLOCK": "Dupliquer",
                +	"ADD_COMMENT": "Ajouter un commentaire",
                +	"REMOVE_COMMENT": "Supprimer un commentaire",
                +	"EXTERNAL_INPUTS": "Entrées externes",
                +	"INLINE_INPUTS": "Entrées en ligne",
                +	"DELETE_BLOCK": "Supprimer le bloc",
                +	"DELETE_X_BLOCKS": "Supprimer %1 blocs",
                +	"DELETE_ALL_BLOCKS": "Supprimer ces %1 blocs ?",
                +	"CLEAN_UP": "Nettoyer les blocs",
                +	"COLLAPSE_BLOCK": "Réduire le bloc",
                +	"COLLAPSE_ALL": "Réduire les blocs",
                +	"EXPAND_BLOCK": "Développer le bloc",
                +	"EXPAND_ALL": "Développer les blocs",
                +	"DISABLE_BLOCK": "Désactiver le bloc",
                +	"ENABLE_BLOCK": "Activer le bloc",
                +	"HELP": "Aide",
                +	"UNDO": "Annuler",
                +	"REDO": "Refaire",
                +	"CHANGE_VALUE_TITLE": "Modifier la valeur :",
                +	"RENAME_VARIABLE": "Renommer la variable…",
                +	"RENAME_VARIABLE_TITLE": "Renommer toutes les variables « %1 » en :",
                +	"NEW_VARIABLE": "Créer une variable...",
                +	"NEW_VARIABLE_TITLE": "Nouveau nom de la variable :",
                +	"VARIABLE_ALREADY_EXISTS": "Une variable appelée '%1' existe déjà.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Une variable nommée '%1' existe déjà pour une autre variable de type '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Une procédure appelée '%1' existe déjà.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Supprimer %1 utilisations de la variable '%2' ?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Impossible de supprimer la variable '%1' parce qu’elle fait partie de la définition de la fonction '%2'",
                +	"DELETE_VARIABLE": "Supprimer la variable '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://fr.wikipedia.org/wiki/Couleur",
                +	"COLOUR_PICKER_TOOLTIP": "Choisir une couleur dans la palette.",
                +	"COLOUR_RANDOM_TITLE": "couleur aléatoire",
                +	"COLOUR_RANDOM_TOOLTIP": "Choisir une couleur au hasard.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "colorier en",
                +	"COLOUR_RGB_RED": "rouge",
                +	"COLOUR_RGB_GREEN": "vert",
                +	"COLOUR_RGB_BLUE": "bleu",
                +	"COLOUR_RGB_TOOLTIP": "Créer une couleur avec la quantité spécifiée de rouge, vert et bleu. Les valeurs doivent être comprises entre 0 et 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "mélanger",
                +	"COLOUR_BLEND_COLOUR1": "couleur 1",
                +	"COLOUR_BLEND_COLOUR2": "couleur 2",
                +	"COLOUR_BLEND_RATIO": "taux",
                +	"COLOUR_BLEND_TOOLTIP": "Mélange deux couleurs dans une proportion donnée (de 0.0 à 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "http://fr.wikipedia.org/wiki/Boucle_for",
                +	"CONTROLS_REPEAT_TITLE": "répéter %1 fois",
                +	"CONTROLS_REPEAT_INPUT_DO": "faire",
                +	"CONTROLS_REPEAT_TOOLTIP": "Exécuter des instructions plusieurs fois.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "répéter tant que",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "répéter jusqu’à",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Tant qu’une valeur est vraie, alors exécuter des instructions.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Tant qu’une valeur est fausse, alors exécuter des instructions.",
                +	"CONTROLS_FOR_TOOLTIP": "Faire prendre à la variable « %1 » les valeurs depuis le nombre de début jusqu’au nombre de fin, en s’incrémentant du pas spécifié, et exécuter les instructions spécifiées.",
                +	"CONTROLS_FOR_TITLE": "compter avec %1 de %2 à %3 par %4",
                +	"CONTROLS_FOREACH_TITLE": "pour chaque élément %1 dans la liste %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Pour chaque élément d’une liste, assigner la valeur de l’élément à la variable '%1', puis exécuter des instructions.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "quitter la boucle",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "passer à l’itération de boucle suivante",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Sortir de la boucle englobante.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sauter le reste de cette boucle, et poursuivre avec l’itération suivante.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Attention : Ce bloc ne devrait être utilisé que dans une boucle.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si une valeur est vraie, alors exécuter certains ordres.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si une valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, exécuter le second bloc d’ordres.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si la première valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, si la seconde valeur est vraie, exécuter le second bloc d’ordres.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si la première valeur est vraie, alors exécuter le premier bloc d’ordres. Sinon, si la seconde valeur est vraie, exécuter le second bloc d’ordres. Si aucune des valeurs n’est vraie, exécuter le dernier bloc d’ordres.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "sinon si",
                +	"CONTROLS_IF_MSG_ELSE": "sinon",
                +	"CONTROLS_IF_IF_TOOLTIP": "Ajouter, supprimer ou réordonner les sections pour reconfigurer ce bloc si.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Ajouter une condition au bloc si.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Ajouter une condition finale fourre-tout au bloc si.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Annuler",
                +	"IOS_ERROR": "Erreur",
                +	"IOS_PROCEDURES_INPUTS": "ENTRÉES",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Ajouter une entrée",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Ordres autorisés",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Cette fonction a des entrées dupliquées.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Ajouter une variable",
                +	"IOS_VARIABLES_ADD_BUTTON": "Ajouter",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Renommer",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Supprimer",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nom de la variable",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Vous ne pouvez pas utiliser un nom de variable vide.",
                +	"LOGIC_COMPARE_HELPURL": "https://fr.wikipedia.org/wiki/Inegalite_(mathematiques)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Renvoyer vrai si les deux entrées sont égales.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Renvoyer vrai si les deux entrées sont différentes.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Renvoyer vrai si la première entrée est plus petite que la seconde.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Renvoyer vrai si la première entrée est plus petite ou égale à la seconde.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Renvoyer vrai si la première entrée est plus grande que la seconde.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Renvoyer vrai si la première entrée est plus grande ou égale à la seconde.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Renvoyer vrai si les deux entrées sont vraies.",
                +	"LOGIC_OPERATION_AND": "et",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Renvoyer vrai si au moins une des entrées est vraie.",
                +	"LOGIC_OPERATION_OR": "ou",
                +	"LOGIC_NEGATE_TITLE": "pas %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Renvoie vrai si l’entrée est fausse. Renvoie faux si l’entrée est vraie.",
                +	"LOGIC_BOOLEAN_TRUE": "vrai",
                +	"LOGIC_BOOLEAN_FALSE": "faux",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Renvoie soit vrai soit faux.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "nul",
                +	"LOGIC_NULL_TOOLTIP": "Renvoie nul.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "si vrai",
                +	"LOGIC_TERNARY_IF_FALSE": "si faux",
                +	"LOGIC_TERNARY_TOOLTIP": "Vérifier la condition dans 'test'. Si elle est vraie, renvoie la valeur 'si vrai' ; sinon renvoie la valeur 'si faux'.",
                +	"MATH_NUMBER_HELPURL": "https://fr.wikipedia.org/wiki/Nombre",
                +	"MATH_NUMBER_TOOLTIP": "Un nombre.",
                +	"MATH_ARITHMETIC_HELPURL": "https://fr.wikipedia.org/wiki/Arithmetique",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Renvoie la somme des deux nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Renvoie la différence des deux nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Renvoie le produit des deux nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Renvoie le quotient des deux nombres.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Renvoie le premier nombre élevé à la puissance du second.",
                +	"MATH_SINGLE_HELPURL": "https://fr.wikipedia.org/wiki/Racine_carree",
                +	"MATH_SINGLE_OP_ROOT": "racine carrée",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Renvoie la racine carrée d’un nombre.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "valeur absolue",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Renvoie la valeur absolue d’un nombre.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Renvoie l’opposé d’un nombre",
                +	"MATH_SINGLE_TOOLTIP_LN": "Renvoie le logarithme naturel d’un nombre.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Renvoie le logarithme base 10 d’un nombre.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Renvoie e à la puissance d’un nombre.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Renvoie 10 à la puissance d’un nombre.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Renvoie le sinus d’un angle en degrés (pas en radians).",
                +	"MATH_TRIG_TOOLTIP_COS": "Renvoie le cosinus d’un angle en degrés (pas en radians).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Renvoie la tangente d’un angle en degrés (pas en radians).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Renvoie l’arcsinus d’un nombre.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Renvoie l’arccosinus d’un nombre.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Renvoie l’arctangente d’un nombre.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Renvoie une des constantes courantes : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infini).",
                +	"MATH_IS_EVEN": "est pair",
                +	"MATH_IS_ODD": "est impair",
                +	"MATH_IS_PRIME": "est premier",
                +	"MATH_IS_WHOLE": "est entier",
                +	"MATH_IS_POSITIVE": "est positif",
                +	"MATH_IS_NEGATIVE": "est négatif",
                +	"MATH_IS_DIVISIBLE_BY": "est divisible par",
                +	"MATH_IS_TOOLTIP": "Vérifier si un nombre est pair, impair, premier, entier, positif, négatif, ou s’il est divisible par un certain nombre. Renvoie vrai ou faux.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "incrémenter %1 de %2",
                +	"MATH_CHANGE_TOOLTIP": "Ajouter un nombre à la variable '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Arrondir un nombre au-dessus ou au-dessous.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arrondir",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arrondir par excès",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arrondir par défaut",
                +	"MATH_ONLIST_OPERATOR_SUM": "somme de la liste",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Renvoyer la somme de tous les nombres dans la liste.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimum de la liste",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Renvoyer le plus petit nombre dans la liste.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maximum de la liste",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Renvoyer le plus grand nombre dans la liste.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "moyenne de la liste",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Renvoyer la moyenne (arithmétique) des valeurs numériques dans la liste.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "médiane de la liste",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Renvoyer le nombre médian de la liste.",
                +	"MATH_ONLIST_OPERATOR_MODE": "majoritaires de la liste",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Renvoyer une liste des élément(s) le(s) plus courant(s) dans la liste.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "écart-type de la liste",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Renvoyer l’écart-type de la liste.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "élément aléatoire de la liste",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Renvoyer un élément dans la liste au hasard.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "reste de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Renvoyer le reste de la division euclidienne des deux nombres.",
                +	"MATH_CONSTRAIN_TITLE": "contraindre %1 entre %2 et %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Contraindre un nombre à être entre les limites spécifiées (incluses).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "entier aléatoire entre %1 et %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Renvoyer un entier aléatoire entre les deux limites spécifiées, incluses.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fraction aléatoire",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Renvoyer une fraction aléatoire entre 0.0 (inclus) et 1.0 (exclus).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Une lettre, un mot ou une ligne de texte.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "créer un texte avec",
                +	"TEXT_JOIN_TOOLTIP": "Créer un morceau de texte en agrégeant un nombre quelconque d’éléments.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "joindre",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Ajouter, supprimer, ou réordonner des sections pour reconfigurer ce bloc de texte.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Ajouter un élément au texte.",
                +	"TEXT_APPEND_TITLE": "ajouter le texte %2 à %1",
                +	"TEXT_APPEND_TOOLTIP": "Ajouter du texte à la variable '%1'.",
                +	"TEXT_LENGTH_TITLE": "longueur de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Renvoie le nombre de lettres (espaces compris) dans le texte fourni.",
                +	"TEXT_ISEMPTY_TITLE": "%1 est vide",
                +	"TEXT_ISEMPTY_TOOLTIP": "Renvoie vrai si le texte fourni est vide.",
                +	"TEXT_INDEXOF_TOOLTIP": "Renvoie l’index de la première/dernière occurrence de la première chaîne dans la seconde. Renvoie %1 si la chaîne n’est pas trouvée.",
                +	"TEXT_INDEXOF_TITLE": "dans le texte %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "trouver la première occurrence de la chaîne",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "trouver la dernière occurrence de la chaîne",
                +	"TEXT_CHARAT_TITLE": "dans le texte %1 %2",
                +	"TEXT_CHARAT_FROM_START": "obtenir la lettre #",
                +	"TEXT_CHARAT_FROM_END": "obtenir la lettre # depuis la fin",
                +	"TEXT_CHARAT_FIRST": "obtenir la première lettre",
                +	"TEXT_CHARAT_LAST": "obtenir la dernière lettre",
                +	"TEXT_CHARAT_RANDOM": "obtenir une lettre au hasard",
                +	"TEXT_CHARAT_TOOLTIP": "Renvoie la lettre à la position indiquée.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Renvoie une partie indiquée du texte.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "dans le texte",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "obtenir la sous-chaîne depuis la lettre #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "obtenir la sous-chaîne depuis la lettre # depuis la fin",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "obtenir la sous-chaîne depuis la première lettre",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "jusqu’à la lettre #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "jusqu’à la lettre # depuis la fin",
                +	"TEXT_GET_SUBSTRING_END_LAST": "jusqu’à la dernière lettre",
                +	"TEXT_CHANGECASE_TOOLTIP": "Renvoyer une copie du texte dans une autre casse.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "en MAJUSCULES",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "en minuscules",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "en Majuscule Au Début De Chaque Mot",
                +	"TEXT_TRIM_TOOLTIP": "Renvoyer une copie du texte avec les espaces supprimés d’un bout ou des deux.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "supprimer les espaces des deux côtés",
                +	"TEXT_TRIM_OPERATOR_LEFT": "supprimer les espaces du côté gauche",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "supprimer les espaces du côté droit",
                +	"TEXT_PRINT_TITLE": "afficher %1",
                +	"TEXT_PRINT_TOOLTIP": "Afficher le texte, le nombre ou une autre valeur spécifié.",
                +	"TEXT_PROMPT_TYPE_TEXT": "invite pour un texte avec un message",
                +	"TEXT_PROMPT_TYPE_NUMBER": "invite pour un nombre avec un message",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Demander un nombre à l’utilisateur.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Demander un texte à l’utilisateur.",
                +	"TEXT_COUNT_MESSAGE0": "nombre %1 sur %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Compter combien de fois un texte donné apparait dans un autre.",
                +	"TEXT_REPLACE_MESSAGE0": "remplacer %1 par %2 dans %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Remplacer toutes les occurrences d’un texte par un autre.",
                +	"TEXT_REVERSE_MESSAGE0": "inverser %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Inverse l’ordre des caractères dans le texte.",
                +	"LISTS_CREATE_EMPTY_TITLE": "créer une liste vide",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Renvoyer une liste, de longueur 0, ne contenant aucun enregistrement",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Créer une liste avec un nombre quelconque d’éléments.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "créer une liste avec",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "liste",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Ajouter, supprimer, ou réordonner les sections pour reconfigurer ce bloc de liste.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Ajouter un élément à la liste.",
                +	"LISTS_REPEAT_TOOLTIP": "Crée une liste consistant en la valeur fournie répétée le nombre de fois indiqué.",
                +	"LISTS_REPEAT_TITLE": "créer une liste avec l’élément %1 répété %2 fois",
                +	"LISTS_LENGTH_TITLE": "longueur de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Renvoie la longueur d’une liste.",
                +	"LISTS_ISEMPTY_TITLE": "%1 est vide",
                +	"LISTS_ISEMPTY_TOOLTIP": "Renvoie vrai si la liste est vide.",
                +	"LISTS_INLIST": "dans la liste",
                +	"LISTS_INDEX_OF_FIRST": "trouver la première occurrence de l’élément",
                +	"LISTS_INDEX_OF_LAST": "trouver la dernière occurrence de l’élément",
                +	"LISTS_INDEX_OF_TOOLTIP": "Renvoie l’index de la première/dernière occurrence de l’élément dans la liste. Renvoie %1 si l'élément n'est pas trouvé.",
                +	"LISTS_GET_INDEX_GET": "obtenir",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obtenir et supprimer",
                +	"LISTS_GET_INDEX_REMOVE": "supprimer",
                +	"LISTS_GET_INDEX_FROM_END": "# depuis la fin",
                +	"LISTS_GET_INDEX_FIRST": "premier",
                +	"LISTS_GET_INDEX_LAST": "dernier",
                +	"LISTS_GET_INDEX_RANDOM": "aléatoire",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 est le premier élément.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 est le dernier élément.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Renvoie l’élément à la position indiquée dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Renvoie le premier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Renvoie le dernier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Renvoie un élément au hasard dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Supprime et renvoie l’élément à la position indiquée dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Supprime et renvoie le premier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Supprime et renvoie le dernier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Supprime et renvoie un élément au hasard dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Supprime l’élément à la position indiquée dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Supprime le premier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Supprime le dernier élément dans une liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Supprime un élément au hasard dans une liste.",
                +	"LISTS_SET_INDEX_SET": "mettre",
                +	"LISTS_SET_INDEX_INSERT": "insérer en",
                +	"LISTS_SET_INDEX_INPUT_TO": "comme",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Met à jour l’élément à la position indiquée dans une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Fixe le premier élément dans une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Fixe le dernier élément dans une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Fixe un élément au hasard dans une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insère l’élément à la position indiquée dans une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insère l’élément au début d’une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Ajouter l’élément à la fin d’une liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Insère l’élément au hasard dans une liste.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "obtenir la sous-liste depuis #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "obtenir la sous-liste depuis # depuis la fin",
                +	"LISTS_GET_SUBLIST_START_FIRST": "obtenir la sous-liste depuis le début",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "jusqu’à #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "jusqu’à # depuis la fin",
                +	"LISTS_GET_SUBLIST_END_LAST": "jusqu’à la fin",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Crée une copie de la partie spécifiée d’une liste.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "trier %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Trier une copie d’une liste.",
                +	"LISTS_SORT_ORDER_ASCENDING": "croissant",
                +	"LISTS_SORT_ORDER_DESCENDING": "décroissant",
                +	"LISTS_SORT_TYPE_NUMERIC": "numérique",
                +	"LISTS_SORT_TYPE_TEXT": "alphabétique",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alphabétique, en ignorant la casse",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "créer une liste depuis le texte",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "créer un texte depuis la liste",
                +	"LISTS_SPLIT_WITH_DELIMITER": "avec le séparateur",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Couper un texte en une liste de textes, en coupant à chaque séparateur.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Réunir une liste de textes en un seul, en les séparant par un séparateur.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "inverser %1",
                +	"LISTS_REVERSE_TOOLTIP": "Inverser la copie d’une liste.",
                +	"VARIABLES_GET_TOOLTIP": "Renvoie la valeur de cette variable.",
                +	"VARIABLES_GET_CREATE_SET": "Créer 'fixer %1'",
                +	"VARIABLES_SET": "fixer %1 à %2",
                +	"VARIABLES_SET_TOOLTIP": "Fixe cette variable pour qu’elle soit égale à la valeur de l’entrée.",
                +	"VARIABLES_SET_CREATE_GET": "Créer 'obtenir %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "pour",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "faire quelque chose",
                +	"PROCEDURES_BEFORE_PARAMS": "avec :",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "avec :",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crée une fonction sans sortie.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Décrire cette fonction…",
                +	"PROCEDURES_DEFRETURN_RETURN": "retour",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Crée une fonction avec une sortie.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "autoriser les ordres",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Attention : Cette fonction a des paramètres en double.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://fr.wikipedia.org/wiki/Sous-programme",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Exécuter la fonction '%1' définie par l’utilisateur.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://fr.wikipedia.org/wiki/Sous-programme",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Exécuter la fonction '%1' définie par l’utilisateur et utiliser son résultat.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entrées",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Ajouter, supprimer, ou réarranger les entrées de cette fonction.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nom de l’entrée :",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Ajouter une entrée à la fonction.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Surligner la définition de la fonction",
                +	"PROCEDURES_CREATE_DO": "Créer '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Si une valeur est vraie, alors renvoyer une seconde valeur.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Attention : Ce bloc pourrait n’être utilisé que dans une définition de fonction."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/he.json b/blockly/webif/static/blockly/msg/json/he.json
                new file mode 100644
                index 000000000..1b6a9a8d5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/he.json
                @@ -0,0 +1,275 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Dorongol",
                +			"YaronSh",
                +			"Amire80",
                +			"Inkbug",
                +			"Yona b",
                +			"Noamrotem",
                +			"Dvb",
                +			"LaG roiL",
                +			"아라",
                +			"Elyashiv",
                +			"Guycn2"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "פריט",
                +	"TODAY": "היום",
                +	"DUPLICATE_BLOCK": "שכפל",
                +	"ADD_COMMENT": "הוסף תגובה",
                +	"REMOVE_COMMENT": "הסר תגובה",
                +	"EXTERNAL_INPUTS": "קלטים חיצוניים",
                +	"INLINE_INPUTS": "קלטים פנימיים",
                +	"DELETE_BLOCK": "מחק קטע קוד",
                +	"DELETE_X_BLOCKS": "מחק %1 קטעי קוד",
                +	"DELETE_ALL_BLOCKS": "האם למחוק את כל %1 קטעי הקוד?",
                +	"CLEAN_UP": "סידור בלוקים",
                +	"COLLAPSE_BLOCK": "צמצם קטע קוד",
                +	"COLLAPSE_ALL": "צמצם קטעי קוד",
                +	"EXPAND_BLOCK": "הרחב קטע קוד",
                +	"EXPAND_ALL": "הרחב קטעי קוד",
                +	"DISABLE_BLOCK": "נטרל קטע קוד",
                +	"ENABLE_BLOCK": "הפעל קטע קוד",
                +	"HELP": "עזרה",
                +	"UNDO": "ביטול",
                +	"REDO": "ביצוע חוזר",
                +	"CHANGE_VALUE_TITLE": "שנה ערך:",
                +	"RENAME_VARIABLE": "שנה את שם המשתנה...",
                +	"RENAME_VARIABLE_TITLE": "שנה את שם כל '%1' המשתנים ל:",
                +	"NEW_VARIABLE": "משתנה חדש...",
                +	"NEW_VARIABLE_TITLE": "שם המשתנה החדש:",
                +	"COLOUR_PICKER_HELPURL": "http://he.wikipedia.org/wiki/%D7%A6%D7%91%D7%A2",
                +	"COLOUR_PICKER_TOOLTIP": "בחר צבע מן הצבעים.",
                +	"COLOUR_RANDOM_TITLE": "צבע אקראי",
                +	"COLOUR_RANDOM_TOOLTIP": "בחר צבא אקראי.",
                +	"COLOUR_RGB_TITLE": "צבע עם",
                +	"COLOUR_RGB_RED": "אדום",
                +	"COLOUR_RGB_GREEN": "ירוק",
                +	"COLOUR_RGB_BLUE": "כחול",
                +	"COLOUR_RGB_TOOLTIP": "צור צבע עם הסכום המצוין של אדום, ירוק וכחול. כל הערכים חייבים להיות בין 0 ל100.",
                +	"COLOUR_BLEND_TITLE": "ערבב",
                +	"COLOUR_BLEND_COLOUR1": "צבע 1",
                +	"COLOUR_BLEND_COLOUR2": "צבע 2",
                +	"COLOUR_BLEND_RATIO": "יחס",
                +	"COLOUR_BLEND_TOOLTIP": "מערבב שני צבעים יחד עם יחס נתון(0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "http://he.wikipedia.org/wiki/בקרת_זרימה",
                +	"CONTROLS_REPEAT_TITLE": "חזור על הפעולה %1 פעמים",
                +	"CONTROLS_REPEAT_INPUT_DO": "תעשה",
                +	"CONTROLS_REPEAT_TOOLTIP": "לעשות כמה פעולות מספר פעמים.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "חזור כל עוד",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "חזור עד ש...",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "כל עוד הערך הוא אמת, לעשות כמה פעולות.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "בזמן שהערך שווה לשגוי, תעשה מספר חישובים.",
                +	"CONTROLS_FOR_TITLE": "תספור עם %1 מ- %2 ל- %3 עד- %4",
                +	"CONTROLS_FOREACH_TITLE": "לכל פריט %1 ברשימה %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "לכל פריט ברשימה, להגדיר את המשתנה '%1' לפריט הזה, ולאחר מכן לעשות כמה פעולות.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "צא מהלולאה",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "המשך עם האיטרציה הבאה של הלולאה",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "צא אל מחוץ ללולאה הכוללת.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "דלג על שאר הלולאה והמשך עם האיטרציה הבאה.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "אזהרה: בלוק זה עשוי לשמש רק בתוך לולאה.",
                +	"CONTROLS_IF_TOOLTIP_1": "אם ערך נכון, לבצע כמה פעולות.",
                +	"CONTROLS_IF_TOOLTIP_2": "אם הערך הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, לבצע את הבלוק השני של הפעולות.",
                +	"CONTROLS_IF_TOOLTIP_3": "אם הערך הראשון הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, אם הערך השני הוא אמת, לבצע את הבלוק השני של הפעולות.",
                +	"CONTROLS_IF_TOOLTIP_4": "אם הערך הראשון הוא אמת, לבצע את הבלוק הראשון של הפעולות. אחרת, אם הערך השני הוא אמת, לבצע את הבלוק השני של הפעולות. אם אף אחד מהם אינו נכון, לבצע את הבלוק האחרון של הפעולות.",
                +	"CONTROLS_IF_MSG_IF": "אם",
                +	"CONTROLS_IF_MSG_ELSEIF": "אחרת אם",
                +	"CONTROLS_IF_MSG_ELSE": "אחרת",
                +	"CONTROLS_IF_IF_TOOLTIP": "תוסיף, תמחק, או תסדר מחדש כדי להגדיר מחדש את הבלוק If.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "תוסיף תנאי לבלוק If.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "לסיום, כל התנאים תקפים לגבי בלוק If.",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "תחזיר נכון אם שני הקלטים שווים אחד לשני.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "תחזיר אמת אם שני הקלטים אינם שווים זה לזה.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "תחזיר אמת (true) אם הקלט הראשון הוא קטן יותר מאשר הקלט השני.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "תחזיר אמת אם הקלט הראשון הוא קטן יותר או שווה לקלט השני.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "תחזיר נכון אם הקלט הראשון גדול יותר מהקלט השני.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "תחזיר נכון אם הקלט הראשון גדול יותר או שווה לכניסה השנייה.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "תחזיר נכון אם שני הקלטים נכונים.",
                +	"LOGIC_OPERATION_AND": "ו",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "תחזיר נכון אם מתקיים לפחות אחד מהקלטים נכונים.",
                +	"LOGIC_OPERATION_OR": "או",
                +	"LOGIC_NEGATE_TITLE": "לא %1",
                +	"LOGIC_NEGATE_TOOLTIP": "החזר אמת אם הקלט הוא שקר. החזר שקר אם הקלט אמת.",
                +	"LOGIC_BOOLEAN_TRUE": "נכון",
                +	"LOGIC_BOOLEAN_FALSE": "שגוי",
                +	"LOGIC_BOOLEAN_TOOLTIP": "תחזיר אם נכון או אם שגוי.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "תחזיר ריק.",
                +	"LOGIC_TERNARY_CONDITION": "בדיקה",
                +	"LOGIC_TERNARY_IF_TRUE": "אם נכון",
                +	"LOGIC_TERNARY_IF_FALSE": "אם שגוי",
                +	"LOGIC_TERNARY_TOOLTIP": "בדוק את התנאי ב'מבחן'. אם התנאי נכון, תחזיר את הערך 'אם נכון'; אחרת תחזיר את הערך 'אם שגוי'.",
                +	"MATH_NUMBER_HELPURL": "https://he.wikipedia.org/wiki/מספר_ממשי",
                +	"MATH_NUMBER_TOOLTIP": "מספר.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://he.wikipedia.org/wiki/ארבע_פעולות_החשבון",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "תחזיר את סכום שני המספרים.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "החזרת ההפרש בין שני מספרים.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "החזרת תוצאת הכפל בין שני מספרים.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "החזרת המנה של שני המספרים.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "החזרת המספר הראשון בחזקת המספר השני.",
                +	"MATH_SINGLE_HELPURL": "https://he.wikipedia.org/wiki/שורש_ריבועי",
                +	"MATH_SINGLE_OP_ROOT": "שורש ריבועי",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "החזרת השורש הריבועי של מספר.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "ערך מוחלט",
                +	"MATH_SINGLE_TOOLTIP_ABS": "החזרת הערך המוחלט של מספר.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "החזרת הערך הנגדי של מספר.",
                +	"MATH_SINGLE_TOOLTIP_LN": "החזרת הלוגריתם הטבעי של מספר.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "החזרת הלוגריתם לפי בסיס עשר של מספר.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "החזרת e בחזקת מספר.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "החזרת 10 בחזקת מספר.",
                +	"MATH_TRIG_HELPURL": "https://he.wikipedia.org/wiki/פונקציות_טריגונומטריות",
                +	"MATH_TRIG_TOOLTIP_SIN": "החזרת הסינוס של מעלה (לא רדיאן).",
                +	"MATH_TRIG_TOOLTIP_COS": "החזרת הקוסינוס של מעלה (לא רדיאן).",
                +	"MATH_TRIG_TOOLTIP_TAN": "החזרת הטנגס של מעלה (לא רדיאן).",
                +	"MATH_IS_EVEN": "זוגי",
                +	"MATH_IS_ODD": "אי-זוגי",
                +	"MATH_IS_PRIME": "ראשוני",
                +	"MATH_IS_WHOLE": "שלם",
                +	"MATH_IS_POSITIVE": "חיובי",
                +	"MATH_IS_NEGATIVE": "שלילי",
                +	"MATH_IS_DIVISIBLE_BY": "מתחלק ב",
                +	"MATH_CHANGE_TITLE": "שינוי %1 על־ידי %2",
                +	"MATH_CHANGE_TOOLTIP": "הוסף מספר למשתנה '%1'.",
                +	"MATH_ROUND_HELPURL": "https://he.wikipedia.org/wiki/עיגול_(אריתמטיקה)",
                +	"MATH_ROUND_TOOLTIP": "עיגול מספר למעלה או למטה.",
                +	"MATH_ROUND_OPERATOR_ROUND": "עיגול",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "עיגול למעלה",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "עיגול למטה",
                +	"MATH_ONLIST_OPERATOR_SUM": "סכום של רשימה",
                +	"MATH_ONLIST_TOOLTIP_SUM": "החזרת הסכום של המספרים ברשימה.",
                +	"MATH_ONLIST_OPERATOR_MIN": "מינימום של רשימה",
                +	"MATH_ONLIST_TOOLTIP_MIN": "תחזיר את המספר הקטן ביותר ברשימה.",
                +	"MATH_ONLIST_OPERATOR_MAX": "מקסימום של רשימה",
                +	"MATH_ONLIST_TOOLTIP_MAX": "תחזיר את המספר הגדול ביותר ברשימה.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "ממוצע של רשימה",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "חציון של רשימה",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "תחזיר את המספר החיצוני ביותר ברשימה.",
                +	"MATH_ONLIST_OPERATOR_MODE": "שכיחי הרשימה",
                +	"MATH_ONLIST_TOOLTIP_MODE": "החזרת רשימה של הפריטים הנפוצים ביותר ברשימה",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "פריט אקראי מרשימה",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "תחזיר רכיב אקראי מרשימה.",
                +	"MATH_MODULO_TITLE": "שארית החילוק %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "החזרת השארית מחלוקת שני המספרים.",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "שבר אקראי",
                +	"TEXT_TEXT_TOOLTIP": "אות, מילה, או שורת טקסט.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "יצירת טקסט עם",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "צירוף",
                +	"TEXT_INDEXOF_TOOLTIP": "מחזירה את האינדקס של המופע הראשון/האחרון בטקסט הראשון לתוך הטקסט השני. מחזירה %1 אם הטקסט אינו נמצא.",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "לאות #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "לאות # מהסוף",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "לאותיות גדולות (עבור טקסט באנגלית)",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "לאותיות קטנות (עבור טקסט באנגלית)",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "לאותיות גדולות בתחילת כל מילה (עבור טקסט באנגלית)",
                +	"TEXT_TRIM_TOOLTIP": "להחזיר עותק של הטקסט לאחר מחיקת רווחים מאחד או משני הקצוות.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "למחוק רווחים משני הקצוות",
                +	"TEXT_TRIM_OPERATOR_LEFT": "למחוק רווחים מימין",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "למחוק רווחים משמאל",
                +	"TEXT_PRINT_TITLE": "הדפס %1",
                +	"TEXT_PRINT_TOOLTIP": "להדפיס טקסט, מספר או ערך אחר שצוין",
                +	"TEXT_PROMPT_TYPE_TEXT": "בקשה להזנת טקסט עם הודעה",
                +	"TEXT_PROMPT_TYPE_NUMBER": "בקשה למספר עם הודעה",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "בקש מהמשתמש מספר.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "בקשה למשתמש להזין טקסט כלשהו.",
                +	"LISTS_CREATE_EMPTY_TITLE": "צור רשימה ריקה",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "החזר רשימה,באורך 0, המכילה רשומות נתונים",
                +	"LISTS_CREATE_WITH_TOOLTIP": "צור רשימה עם כל מספר של פריטים.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "צור רשימה עם",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "רשימה",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "תוסיף, תמחק, או תסדר מחדש כדי להגדיר מחדש את הבלוק If.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "הוסף פריט לרשימה.",
                +	"LISTS_REPEAT_TOOLTIP": "יוצר רשימה המורכבת מהערך נתון חוזר מספר פעמים שצוין.",
                +	"LISTS_REPEAT_TITLE": "ליצור רשימה עם הפריט %1 %2 פעמים",
                +	"LISTS_LENGTH_TITLE": "אורכו של %1",
                +	"LISTS_LENGTH_TOOLTIP": "מחזירה את האורך של רשימה.",
                +	"LISTS_ISEMPTY_TITLE": "%1 הוא ריק",
                +	"LISTS_ISEMPTY_TOOLTIP": "מחזיר אמת אם הרשימה ריקה.",
                +	"LISTS_INLIST": "ברשימה",
                +	"LISTS_INDEX_OF_FIRST": "מחזירה את המיקום הראשון של פריט ברשימה",
                +	"LISTS_INDEX_OF_LAST": "מחזירה את המיקום האחרון של פריט ברשימה",
                +	"LISTS_INDEX_OF_TOOLTIP": "מחזירה את האינדקס של המופע הראשון/האחרון של הפריט ברשימה.  מחזירה %1 אם הפריט אינו נמצא.",
                +	"LISTS_GET_INDEX_GET": "לקבל",
                +	"LISTS_GET_INDEX_GET_REMOVE": "קבל ומחק",
                +	"LISTS_GET_INDEX_REMOVE": "הסרה",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# מהסוף",
                +	"LISTS_GET_INDEX_FIRST": "ראשון",
                +	"LISTS_GET_INDEX_LAST": "אחרון",
                +	"LISTS_GET_INDEX_RANDOM": "אקראי",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 הוא הפריט הראשון.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 הוא הפריט האחרון.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "מחזיר פריט במיקום שצוין ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "מחזיר את הפריט הראשון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "מחזיר את הפריט האחרון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "מחזיר פריט אקראי מהרשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "מסיר ומחזיר את הפריט במיקום שצוין ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "מסיר ומחזיר את הפריט הראשון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "מסיר ומחזיר את הפריט האחרון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "מחק והחזר פריט אקראי מהרשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "מחזיר פריט במיקום שצוין ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "הסר את הפריט הראשון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "הסר את הפריט הראשון ברשימה.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "הסר פריט אקראי ברשימה.",
                +	"LISTS_SET_INDEX_SET": "הגדר",
                +	"LISTS_SET_INDEX_INSERT": "הכנס ב",
                +	"LISTS_SET_INDEX_INPUT_TO": "כמו",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "מגדיר את הפריט במיקום שצוין ברשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "מגדיר את הפריט הראשון ברשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "מגדיר את הפריט האחרון ברשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "מגדיר פריט אקראי ברשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "מכניס את הפריט במיקום שצוין ברשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "מכניס את הפריט בתחילת רשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "מוסיף את הפריט בסוף רשימה.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "הוסף פריט באופן אקראי ברשימה.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "לקבל חלק מהרשימה החל מ-#",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "לקבל חלק מהרשימה החל מ-# עד הסוף",
                +	"LISTS_GET_SUBLIST_START_FIRST": "לקבל חלק מהרשימה החל מהתחלה",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "ל #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ל # מהסוף",
                +	"LISTS_GET_SUBLIST_END_LAST": "לאחרון",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "יוצרת עותק של חלק מסוים מהרשימה.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_ORDER_ASCENDING": "סדר עולה",
                +	"LISTS_SORT_ORDER_DESCENDING": "סדר יורד",
                +	"LISTS_SORT_TYPE_TEXT": "סדר אלפביתי",
                +	"LISTS_SORT_TYPE_IGNORECASE": "סדר אלפביתי, לא תלוי רישיות",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "יצירת רשימה מטקסט",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "יצירת טקסט מרשימה",
                +	"VARIABLES_GET_TOOLTIP": "להחזיר את הערך של משתנה זה.",
                +	"VARIABLES_GET_CREATE_SET": "ליצור 'הגדר %1'",
                +	"VARIABLES_SET": "הגדר %1 ל- %2",
                +	"VARIABLES_SET_TOOLTIP": "מגדיר משתנה זה להיות שווה לקלט.",
                +	"VARIABLES_SET_CREATE_GET": "ליצור 'קרא %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "לביצוע:",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "לעשות משהו",
                +	"PROCEDURES_BEFORE_PARAMS": "עם:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "עם:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "יצירת פונקציה ללא פלט.",
                +	"PROCEDURES_DEFRETURN_RETURN": "להחזיר",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "יצירת פונקציה עם פלט.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "לאפשר פעולות",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "אזהרה: לפונקציה זו יש פרמטרים כפולים.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://he.wikipedia.org/wiki/שגרה_(תכנות)",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "להפעיל את הפונקציה המוגדרת על-ידי המשתמש '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://he.wikipedia.org/wiki/שגרה_(תכנות)",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "להפעיל את הפונקציה המוגדרת על-ידי המשתמש '%1' ולהשתמש הפלט שלה.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "מקורות קלט",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "הוסף, הסר או סדר מחדש קלטים לפונקציה זו",
                +	"PROCEDURES_MUTATORARG_TITLE": "שם הקלט:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "הוסף קלט לפונקציה",
                +	"PROCEDURES_HIGHLIGHT_DEF": "הדגש הגדרה של פונקציה",
                +	"PROCEDURES_CREATE_DO": "ליצור '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "אם ערך נכון, אז להחזיר ערך שני.",
                +	"PROCEDURES_IFRETURN_WARNING": "אזהרה: בלוק זה עשוי לשמש רק בתוך הגדרה של פונקציה."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/hi.json b/blockly/webif/static/blockly/msg/json/hi.json
                new file mode 100644
                index 000000000..79354d8cc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/hi.json
                @@ -0,0 +1,340 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Bl707",
                +			"संजीव कुमार",
                +			"Phoenix303",
                +			"Sfic",
                +			"Earlyengineers",
                +			"Sachinkatiyar"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "वस्तु",
                +	"TODAY": "आज",
                +	"DUPLICATE_BLOCK": "कॉपी करें",
                +	"ADD_COMMENT": "टिप्पणी छोड़ें",
                +	"REMOVE_COMMENT": "टिप्पणी हटायें",
                +	"EXTERNAL_INPUTS": "बाहरी इनपुट",
                +	"INLINE_INPUTS": "इनलाइन इनपुट",
                +	"DELETE_BLOCK": "ब्लॉक हटाएँ",
                +	"DELETE_X_BLOCKS": "%1 ब्लॉक हटाएँ",
                +	"DELETE_ALL_BLOCKS": "सभी %1 खानों को हटा दें?",
                +	"CLEAN_UP": "खानों को साफ करें",
                +	"COLLAPSE_BLOCK": "ब्लॉक को संक्षिप्त करें",
                +	"COLLAPSE_ALL": "ब्लॉक संक्षिप्त करें",
                +	"EXPAND_BLOCK": "ब्लॉक का विस्तार करें",
                +	"EXPAND_ALL": "ब्लॉक विस्तार करें",
                +	"DISABLE_BLOCK": "ब्लॉक को अक्षम करें",
                +	"ENABLE_BLOCK": "ब्लॉक को सक्षम करें",
                +	"HELP": "सहायता",
                +	"UNDO": "पूर्ववत करें",
                +	"REDO": "फिर से करें",
                +	"CHANGE_VALUE_TITLE": "मान परिवर्तित करें:",
                +	"RENAME_VARIABLE": "चर का नाम बदलें...",
                +	"RENAME_VARIABLE_TITLE": "सभी '%1' चरों के नाम बदलें:",
                +	"NEW_VARIABLE": "चर बनाएँ...",
                +	"NEW_VARIABLE_TITLE": "नए चर का नाम:",
                +	"VARIABLE_ALREADY_EXISTS": "प्राचल नाम '%1' पहले से मौजूद है।",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "'%1' नाम का एक चर पहले से '%2' प्रकार के अन्य चर के लिए मौजूद है।",
                +	"PROCEDURE_ALREADY_EXISTS": "'%1' नाम की एक प्रक्रिया पहले से मौजूद है।",
                +	"DELETE_VARIABLE_CONFIRMATION": "'%2' चर के %1 उपयोग को हटाएँ?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "चर '%1' को नहीं हटा सकता क्योंकि यह फ़ंक्शन '%2' की परिभाषा का हिस्सा है",
                +	"DELETE_VARIABLE": "'%1' चर को हटाएँ",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "पैलेट से एक रंग चुनें।",
                +	"COLOUR_RANDOM_TITLE": "कोई भी रंग",
                +	"COLOUR_RANDOM_TOOLTIP": "कोई भी एक रंग का चयन करें।",
                +	"COLOUR_RGB_TITLE": "इसके साथ रंग करें",
                +	"COLOUR_RGB_RED": "लाल",
                +	"COLOUR_RGB_GREEN": "हरा",
                +	"COLOUR_RGB_BLUE": "नीला",
                +	"COLOUR_RGB_TOOLTIP": "लाल, हरा और नीले की निर्दिष्ट मात्रा के साथ एक रंग बनायें। सभी मान ० से १०० के बीच होने चाहिए।",
                +	"COLOUR_BLEND_TITLE": "मिश्रण करें",
                +	"COLOUR_BLEND_COLOUR1": "रंग 1",
                +	"COLOUR_BLEND_COLOUR2": "रंग 2",
                +	"COLOUR_BLEND_RATIO": "अनुपात",
                +	"COLOUR_BLEND_TOOLTIP": "दिए गए अनुपात (0.0 - 1.0) के साथ दो रंगों का मिश्रण करता है।",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "%1 बार दोहराएँ",
                +	"CONTROLS_REPEAT_INPUT_DO": "करें",
                +	"CONTROLS_REPEAT_TOOLTIP": "कुछ विवरण कई बार चलाएँ।",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "दोहराएँ जब कि",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "दोहराएँ जब तक",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "जब तक मान सही है, तब तक कुछ विवरण चलाएँ।",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "जब तक मान गलत है, तब तक कुछ विवरण चलाएँ।",
                +	"CONTROLS_FOR_TOOLTIP": "क्या चर '%1' प्रारंभ संख्या से अंत संख्या तक मानों को लेता है, निर्दिष्ट अंतराल के अनुसार गिनती करता है, और निर्दिष्ट रुकावटों को करता है।",
                +	"CONTROLS_FOR_TITLE": "%1 से %2 से %3 तक %4 के साथ गिनती करें",
                +	"CONTROLS_FOREACH_TITLE": "प्रत्येक वस्तु के लिए %1 सूची में %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "सूची के प्रत्येक वस्तु के लिए, वस्तु में चर का मान '%1' रखें और बाद में कुछ कथन लिखें।",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "फंदे से बाहर निकलें",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "फंदे की अगली यात्रा के साथ जारी रखें",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "भीतरी फंदे से बाहर निकलें।",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "बाकी बचे फंदे को छोड़ें, और अगली यात्रा जारी रखें।",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "सावधान: ये ब्लॉक केवल लूप के अंदर इस्तेमाल किया जा सकता है।",
                +	"CONTROLS_IF_TOOLTIP_1": "यदी मान सही है, तो कुछ विवरण चलाएँ।",
                +	"CONTROLS_IF_TOOLTIP_2": "यदि एक मान सत्य है तो कथनों का प्रथम खण्ड बनायें। अन्यथा कथनों का दूसरा भाग निर्मित करें।",
                +	"CONTROLS_IF_TOOLTIP_3": "यदि पहले मान सही है, तो बयानों का पहला खंड करें। अन्यथा, यदि दूसरा मान सत्य है, तो बयानों का दूसरा खंड करें।",
                +	"CONTROLS_IF_TOOLTIP_4": "यदि पहला मान सही है, तो बयानों का पहला खंड करें। अन्यथा, यदि दूसरा मान सत्य है, तो बयानों का दूसरा खंड करें। यदि कोई भी मान सही नहीं है, तो बयानों का अंतिम खंड करें।",
                +	"CONTROLS_IF_MSG_IF": "यदि",
                +	"CONTROLS_IF_MSG_ELSEIF": "यदि अन्य",
                +	"CONTROLS_IF_MSG_ELSE": "अन्य",
                +	"CONTROLS_IF_IF_TOOLTIP": "भाग को समनरूप बनाने के लिए जोङें, हटाएं, या पुनः व्यवस्थित करें यदि यह बंद है।",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "एक शर्त जोड़ें यदि ब्लॉक है।",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "यदि ब्लॉक है तो इसके लिए एक अंतिम, कैच-सभी स्थिति जोड़ें।",
                +	"IOS_OK": "ठीक है",
                +	"IOS_CANCEL": "रद्द करें",
                +	"IOS_ERROR": "त्रुटि",
                +	"IOS_PROCEDURES_INPUTS": "इनपुट",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ इनपुट जोड़ें",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "बयानों की अनुमति दें",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "इस फंक्शन में नकली निवेश हैं।",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ चर जोड़ें",
                +	"IOS_VARIABLES_ADD_BUTTON": "जोड़ें",
                +	"IOS_VARIABLES_RENAME_BUTTON": "नाम बदलें",
                +	"IOS_VARIABLES_DELETE_BUTTON": "हटाएँ",
                +	"IOS_VARIABLES_VARIABLE_NAME": "चर का नाम",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "आप रिक्त चर नाम उपयोग नहीं कर सकते",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "ट्रू रिटर्न करें यदि दोनो इनपुट इक दूसरे के बराबर हों।",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "ट्रू रिटर्न करें यदि दोनो इनपुट इक दूसरे के बराबर नहीं हों।",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से छोटा हो।",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से छोटा हो या बराबर हो।",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से बड़ा हो।",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "ट्रू रिटर्न करें यदि पहला इनपुट दूसरे इनपुट से बड़ा हो या बराबर हो।",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "ट्रू रिटर्न करें यदि दोनो इनपुट ट्रू हों।",
                +	"LOGIC_OPERATION_AND": "AND (तथा)",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "ट्रू रिटर्न करें यदि दोनो मे से इक इनपुट ट्रू हो।",
                +	"LOGIC_OPERATION_OR": "OR (अथवा)",
                +	"LOGIC_NEGATE_TITLE": "NOT (पूरक) %1",
                +	"LOGIC_NEGATE_TOOLTIP": "ट्रू रिटर्न करता है यदि इनपुट फॉल्स है। फॉल्स रिटर्न करता है यदि इनपुट ट्रू है।",
                +	"LOGIC_BOOLEAN_TRUE": "सही",
                +	"LOGIC_BOOLEAN_FALSE": "गलत",
                +	"LOGIC_BOOLEAN_TOOLTIP": "ट्रू या फॉल्स रिटर्न करता है।",
                +	"LOGIC_NULL": "NULL (अमान्य)",
                +	"LOGIC_NULL_TOOLTIP": "null (अमान्य) रिटर्न करता है।",
                +	"LOGIC_TERNARY_CONDITION": "टेस्ट",
                +	"LOGIC_TERNARY_IF_TRUE": "यदि सही है",
                +	"LOGIC_TERNARY_IF_FALSE": "यदि गलत है",
                +	"LOGIC_TERNARY_TOOLTIP": "'परीक्षण' में हालत की जांच करें। यदि स्थिति सही है, तो 'सच' मान लौटाता है; अन्यथा वापस लौटता 'अगर झूठा'मान देता है।",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "एक संख्या।",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "दो संख्याओं का योग रिटर्न करें।",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "दो संख्याओं का अंतर रिटर्न करें।",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "दो संख्याओं का गुणन रिटर्न करें।",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "दो संख्याओं का भागफल रिटर्न करें।",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "दूसरे नंबर की शक्ति को उठाए गए पहले नंबर पर लौटें",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "वर्गमूल",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "संख्या का वर्गमूल रिटर्न करें।",
                +	"MATH_SINGLE_OP_ABSOLUTE": "परम",
                +	"MATH_SINGLE_TOOLTIP_ABS": "संख्या का परम मान रिटर्न करें।",
                +	"MATH_SINGLE_TOOLTIP_NEG": "संख्या का निषेध मान रिटर्न करें।",
                +	"MATH_SINGLE_TOOLTIP_LN": "संख्या का प्राकृतिक लघुगणक रिटर्न करें।",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "संख्या का मूल 10 लघुगणक रिटर्न करें।",
                +	"MATH_SINGLE_TOOLTIP_EXP": "किसी संख्या की शक्ति को वापस ई करें।",
                +	"MATH_SINGLE_TOOLTIP_POW10": "किसी संख्या की शक्ति पर 10 लौटें।",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "डिग्री का साइन रिटर्न करें (रेडियन नही)",
                +	"MATH_TRIG_TOOLTIP_COS": "डिग्री का कोसाइन रिटर्न करें (रेडियन नही)",
                +	"MATH_TRIG_TOOLTIP_TAN": "डिग्री का टैन्जन्ट रिटर्न करें (रेडियन नही)",
                +	"MATH_TRIG_TOOLTIP_ASIN": "संख्या का आर्कसाइन रिटर्न करें।",
                +	"MATH_TRIG_TOOLTIP_ACOS": "संख्या का आर्ककोसाइन रिटर्न करें।",
                +	"MATH_TRIG_TOOLTIP_ATAN": "संख्या का आर्कटैन्जन्ट रिटर्न करें।",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "सामान्य स्थिरांक में से एक को वापस लौटें:π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity)।",
                +	"MATH_IS_EVEN": "सम है",
                +	"MATH_IS_ODD": "विषम है",
                +	"MATH_IS_PRIME": "अभाज्य है",
                +	"MATH_IS_WHOLE": "पूर्णांक है",
                +	"MATH_IS_POSITIVE": "धनात्मक है",
                +	"MATH_IS_NEGATIVE": "ऋणात्मक है",
                +	"MATH_IS_DIVISIBLE_BY": "इसके द्वारा विभाज्य है",
                +	"MATH_IS_TOOLTIP": "जांचें कि क्या कोई संख्या एक सम, विषम, मुख्य, संपूर्ण, सकारात्मक, नकारात्मक है या यदि वह निश्चित संख्या से विभाजित है। वास्तविक या गलत रिटर्न देता है।",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%1 को %2 से बदलें",
                +	"MATH_CHANGE_TOOLTIP": "संख्या को चर '%1' से जोड़ें।",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "संख्या को बड़ा या घटा के पूर्णांक बनाएँ।",
                +	"MATH_ROUND_OPERATOR_ROUND": "पूर्णांक बनाएँ",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "बड़ा के पूर्णांक बनाएँ",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "घटा के पूर्णांक बनाएँ",
                +	"MATH_ONLIST_OPERATOR_SUM": "सूची का योग",
                +	"MATH_ONLIST_TOOLTIP_SUM": "सूची की सभी संख्याओं का योग रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_MIN": "सूची मे न्यूनतम",
                +	"MATH_ONLIST_TOOLTIP_MIN": "सूची मे सबसे छोटी संख्या रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_MAX": "सूची मे अधिकतम",
                +	"MATH_ONLIST_TOOLTIP_MAX": "सूची में सबसे बड़ी संख्या रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "सूची का औसत मान",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "सूची में संख्यात्मक मानों का औसत (अंकगणित माध्य) लौटें।",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "सूची की माध्यिका",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "सूची की माध्यिका संख्या रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_MODE": "सूची का मोड",
                +	"MATH_ONLIST_TOOLTIP_MODE": "सूची मे सबसे आम आइटम(s) की सूची रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "सूची का मानक विचलन",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "सूची का मानक विचलन रिटर्न करें।",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "सूची का रैन्डम आइटम",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "सूची से एक रैन्डम आइटम रिटर्न करें।",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 का शेषफल",
                +	"MATH_MODULO_TOOLTIP": "दो संख्याओं के भाग का शेषफल रिटर्न करें।",
                +	"MATH_CONSTRAIN_TITLE": "%1 कम %2 उच्च %3 बाधित करें",
                +	"MATH_CONSTRAIN_TOOLTIP": "एक संख्या को निर्दिष्ट सीमा (सम्मिलित) के बीच बाधित करें।",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "%1 से %2 तक रैन्डम पूर्णांक",
                +	"MATH_RANDOM_INT_TOOLTIP": "दो निर्दिष्ट सीमाओं, समावेशी के बीच एक यादृच्छिक पूर्णांक लौटें।",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "रैन्डम अंश",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0 (समावेशी) और 1.0 (विशिष्ट) के बीच एक यादृच्छिक अंश पर लौटें।",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "एक अक्षर, शब्द, या टेक्स्ट की पंक्ति।",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "इसके साथ टेक्स्ट बनाएँ",
                +	"TEXT_JOIN_TOOLTIP": "किसी भी संख्या के मदों को एक साथ जोड़ कर पाठ का एक टुकड़ा बनाएं।",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "जोड़",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "भाग को समनरूप बनाने के लिए जोङें, हटाएं, या पुनः व्यवस्थित करें यदि यह बंद है।",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "सूची मे एक आइटम जोड़ें।",
                +	"TEXT_APPEND_TITLE": "%1 में पाठ %2 को जोड़ें",
                +	"TEXT_APPEND_TOOLTIP": "कुछ टेक्स्ट इस चर '%1' से जोड़ें।",
                +	"TEXT_LENGTH_TITLE": "%1 की लंबाई",
                +	"TEXT_LENGTH_TOOLTIP": "दिए गये टेक्स्ट मे अक्षरों की संख्या रिटर्न करता है (खाली स्थान मिला के)।",
                +	"TEXT_ISEMPTY_TITLE": "%1 खाली है",
                +	"TEXT_ISEMPTY_TOOLTIP": "ट्रू रिटर्न करता है यदि दिया गया टेक्स्ट खाली है।",
                +	"TEXT_INDEXOF_TOOLTIP": "दूसरे पाठ में पहले पाठ की पहली/अंतिम घटना का सूचक देता है। यदि पाठ नहीं मिला है तो %1 रिटर्न होता है।",
                +	"TEXT_INDEXOF_TITLE": "पाठ %1 %2 %3 में",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "टेक्स्ट पहली बार जहाँ आया है उसे ढूढ़े",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "टेक्स्ट आखरी बार जहाँ आया है उसे ढूढ़े",
                +	"TEXT_CHARAT_TITLE": "पाठ %1 %2 में",
                +	"TEXT_CHARAT_FROM_START": "अक्षर # पाएँ",
                +	"TEXT_CHARAT_FROM_END": "आखिर से अक्षर # पाएँ",
                +	"TEXT_CHARAT_FIRST": "पहला अक्षर पाएँ",
                +	"TEXT_CHARAT_LAST": "आखरी अक्षर पाएँ",
                +	"TEXT_CHARAT_RANDOM": "रैन्डम अक्षर पाएँ",
                +	"TEXT_CHARAT_TOOLTIP": "बताई गयी जगह से अक्षर रिटर्न करता है",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "टेक्स्ट का बताया गया अंश रिटर्न करता है",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "इस टेक्स्ट मे",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "अक्षर # से सबस्ट्रिंग पाएँ",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "आखरी अक्षर # से सबस्ट्रिंग पाएँ",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "पहले अक्षर से सबस्ट्रिंग पाएँ",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "यहाँ तक अक्षर #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "आखिर से यहाँ तक अक्षर #",
                +	"TEXT_GET_SUBSTRING_END_LAST": "यहाँ तक आखरी अक्षर",
                +	"TEXT_CHANGECASE_TOOLTIP": "टेक्स्ट की कॉपी भिन्न केस (अक्षर से संबंधित) मे रिटर्न करें।",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "बड़े अक्षर मे",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "छोटे अक्षर मे",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "टाइटल केस मे",
                +	"TEXT_TRIM_TOOLTIP": "एक या दोनों सिरों से हटाए गए रिक्त स्थान के साथ पाठ की एक प्रति लौटाएं।",
                +	"TEXT_TRIM_OPERATOR_BOTH": "रिक्त स्थान को इस टेक्स्ट के दोनों तरफ से निकालें",
                +	"TEXT_TRIM_OPERATOR_LEFT": "रिक्त स्थान को इस टेक्स्ट के बायें तरफ से निकालें",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "रिक्त स्थान को इस टेक्स्ट के दाईं तरफ से निकालें",
                +	"TEXT_PRINT_TITLE": "प्रिंट करें %1",
                +	"TEXT_PRINT_TOOLTIP": "दिया गया टेक्स्ट प्रिंट करें, संख्या या अन्य मान।",
                +	"TEXT_PROMPT_TYPE_TEXT": "सूचना के साथ टेक्स्ट के लिए प्रॉम्प्ट करें",
                +	"TEXT_PROMPT_TYPE_NUMBER": "सूचना के साथ संख्या के लिए प्रॉम्प्ट करें",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "यूज़र से संख्या के लिए प्रॉम्प्ट करें।",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "यूज़र से कुछ टेक्स्ट के लिए प्रॉम्प्ट करें।",
                +	"TEXT_COUNT_MESSAGE0": "%1 को %2 में गिने",
                +	"TEXT_COUNT_TOOLTIP": "गिने, कितनी बार कुछ पाठ कुछ अन्य पाठ के अंदर समाहित होता है।",
                +	"TEXT_REPLACE_MESSAGE0": "%1 को %2 के साथ %3 में बदलें",
                +	"TEXT_REPLACE_TOOLTIP": "कुछ अन्य पाठ के अंदर कुछ पाठ की सभी जगहों को बदलें।",
                +	"TEXT_REVERSE_MESSAGE0": "%1 को बदल दें",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "पाठ में वर्णों के क्रम को उलट देता है।",
                +	"LISTS_CREATE_EMPTY_TITLE": "खाली सूची बनाएँ",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "0 लंबाई की, कोई भी डेटा ना रखने वाली एक सूची लौटती है",
                +	"LISTS_CREATE_WITH_TOOLTIP": "कितने भी आइटम वाली एक सूची बनाएँ।",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "इसके सूची बनाएँ",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "सूची",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "इस सूची ब्लॉक को पुन: आकार देने के लिए वर्गों को जोड़ें, निकालें, या पुन: क्रमित करें।",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "सूची मे एक आइटम जोड़ें।",
                +	"LISTS_REPEAT_TOOLTIP": "निर्धारित मान की बार-बार दोहराई गई एक सूची बनाता है।",
                +	"LISTS_REPEAT_TITLE": "वस्तु %1 के साथ %2 बार दोहराई गयी सूची बनाएं",
                +	"LISTS_LENGTH_TITLE": "%1 की लंबाई",
                +	"LISTS_LENGTH_TOOLTIP": "सूची की लंबाई रिटर्न करता है।",
                +	"LISTS_ISEMPTY_TITLE": "%1 खाली है",
                +	"LISTS_ISEMPTY_TOOLTIP": "यदि सूची खाली है तो ट्रू रिटर्न करता है।",
                +	"LISTS_INLIST": "सूची में",
                +	"LISTS_INDEX_OF_FIRST": "आइटम पहली बार जहाँ आया है उसे ढूढ़े",
                +	"LISTS_INDEX_OF_LAST": "आइटम आखरी बार जहाँ आया है उसे ढूढ़े",
                +	"LISTS_INDEX_OF_TOOLTIP": "सूची में आइटम की पहली/अंतिम घटना का सूचक देता है। यदि आइटम नहीं मिला है तो %1 रिटर्न होता है।",
                +	"LISTS_GET_INDEX_GET": "प्राप्त",
                +	"LISTS_GET_INDEX_GET_REMOVE": "प्राप्त करे और हटाए",
                +	"LISTS_GET_INDEX_REMOVE": "निकालें",
                +	"LISTS_GET_INDEX_FROM_END": "अंत से #",
                +	"LISTS_GET_INDEX_FIRST": "पहला",
                +	"LISTS_GET_INDEX_LAST": "आखिरी",
                +	"LISTS_GET_INDEX_RANDOM": "रैन्डम",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 पहली वस्तु है।",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 आखिरी वस्तु है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "एक सूची में निर्दिष्ट स्थान पर वस्तु को लौटाता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "सूची का पहला आइटम रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "सूची का आखरी आइटम रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "सूची से रैन्डम आइटम रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "एक सूची में निर्दिष्ट स्थिति में आइटम निकालता है और लौटाता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "सूची का पहला आइटम निकालता है और रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "सूची का आखरी आइटम निकालता है और रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "सूची से रैन्डम आइटम निकालता है और रिटर्न करता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "एक सूची में निर्दिष्ट स्थान पर आइटम निकाल देता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "सूची का पहला आइटम निकालता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "सूची का आखरी आइटम निकालता है।",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "सूची से रैन्डम आइटम निकालता है।",
                +	"LISTS_SET_INDEX_SET": "सैट करें",
                +	"LISTS_SET_INDEX_INSERT": "पर डालें",
                +	"LISTS_SET_INDEX_INPUT_TO": "बतौर",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "सूची मे बताए गये स्थान में आइटम सैट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "सूची में पहला आइटम सैट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "सूची में आखरी आइटम सैट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "सूची में रैन्डम आइटम सैट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "सूची मे बताए गये स्थान में आइटम इनसर्ट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "आइटम को सूची के शुरू में इनसर्ट करता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "आइटम को सूची के अंत में जोड़ता है।",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "आइटम को सूची में रैन्डम्ली इनसर्ट करता है।",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "# से उप-सूची प्राप्त करें",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "अंत से # से उप-सूची प्राप्त करें",
                +	"LISTS_GET_SUBLIST_START_FIRST": "प्रथम से उप-सूची प्राप्त करें",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "# को",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "अंतिम से # को",
                +	"LISTS_GET_SUBLIST_END_LAST": "अंत से",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "सूची के बताए गये भाग की कॉपी बनता है।",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"LISTS_SORT_TITLE": "%1 %2 %3 को छांटे",
                +	"LISTS_SORT_TOOLTIP": "एक सूची की एक प्रति को छांटे।",
                +	"LISTS_SORT_ORDER_ASCENDING": "बढ़ते क्रम",
                +	"LISTS_SORT_ORDER_DESCENDING": "बढ़ते क्रम में",
                +	"LISTS_SORT_TYPE_NUMERIC": "अंकीय",
                +	"LISTS_SORT_TYPE_TEXT": "वर्णक्रमानुसार",
                +	"LISTS_SORT_TYPE_IGNORECASE": "वर्णक्रमानुसार, मामले की अनदेखी करें",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "पाठ से एक सूची बनाएं",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "सूची से एक पाठ बनाएं",
                +	"LISTS_SPLIT_WITH_DELIMITER": "सीमांकक के साथ",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "ग्रंथों की सूची में पाठ को विभाजित करें, प्रत्येक सीमांकक पर तोड़कर।",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "ग्रंथों की एक सूची में शामिल करें, जो एक सीमांकक से अलग हो।",
                +	"LISTS_REVERSE_MESSAGE0": "%1 को बदल दें",
                +	"LISTS_REVERSE_TOOLTIP": "एक सूची की एक प्रति को छांटे।",
                +	"VARIABLES_GET_TOOLTIP": "इस चर का मान रिटर्न करता है।",
                +	"VARIABLES_GET_CREATE_SET": "सेट '%1' बनाएँ",
                +	"VARIABLES_SET": "सेट करें %1 को %2",
                +	"VARIABLES_SET_TOOLTIP": "इस चर को इनपुट के बराबर सेट करता है।",
                +	"VARIABLES_SET_CREATE_GET": "'प्राप्त करें %1' बनाएं",
                +	"PROCEDURES_DEFNORETURN_TITLE": "को",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "कुछ करें",
                +	"PROCEDURES_BEFORE_PARAMS": ": के साथ",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": ": के साथ",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "बिना आउटपुट वाला एक फ़ंक्शन बनाता है।",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "इस फंकशन को समझाएँ...",
                +	"PROCEDURES_DEFRETURN_RETURN": "वापस आएं",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "आउटपुट वाला एक फ़ंक्शन बनाता है।",
                +	"PROCEDURES_ALLOW_STATEMENTS": "बयानों की अनुमति दें",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "सावधान: इस फ़ंक्शन मे डुप्लिकेट पैरामीटर हैं।",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "यूज़र द्वारा वर्णन किया गया फ़ंक्शन '%1' चलाएँ।",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "यूज़र द्वारा वर्णन किया गया फ़ंक्शन '%1' चलाएँ और उसका आउटपुट इस्तेमाल करें।",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "इनपुट",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "इस फ़ंक्शन में इनपुट जोड़ें, निकालें, या पुन: क्रमित करें।",
                +	"PROCEDURES_MUTATORARG_TITLE": "इनपुट का नाम:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "फंगक्शन को इनपुट प्रदान करें।",
                +	"PROCEDURES_HIGHLIGHT_DEF": "फ़ंक्शन परिभाषा को हाइलाइट करें",
                +	"PROCEDURES_CREATE_DO": "'%1' बनाएँ",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "यदि एक मान ट्रू है तो, दूसरा मान रिटर्न करें।",
                +	"PROCEDURES_IFRETURN_WARNING": "सावधान: ये ब्लॉक फ़ंक्शन परिभाषा के अंदर ही इस्तेमाल किया जा सकता।"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/hrx.json b/blockly/webif/static/blockly/msg/json/hrx.json
                new file mode 100644
                index 000000000..671eac34e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/hrx.json
                @@ -0,0 +1,285 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Paul Beppler"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "Element",
                +	"DUPLICATE_BLOCK": "Kopieren",
                +	"ADD_COMMENT": "Kommentar hinzufüche",
                +	"REMOVE_COMMENT": "Kommentar entferne",
                +	"EXTERNAL_INPUTS": "External Inputsexterne Ingänge",
                +	"INLINE_INPUTS": "interne Ingänge",
                +	"DELETE_BLOCK": "Block lösche",
                +	"DELETE_X_BLOCKS": "Block %1 lösche",
                +	"DELETE_ALL_BLOCKS": "All %1 Bausten lösche?",
                +	"COLLAPSE_BLOCK": "Block zusammerfalte",
                +	"COLLAPSE_ALL": "Blocke zusammerfalte",
                +	"EXPAND_BLOCK": "Block entfalte",
                +	"EXPAND_ALL": "Blocke expandiere",
                +	"DISABLE_BLOCK": "Block deaktivieren",
                +	"ENABLE_BLOCK": "Block aktivieren",
                +	"HELP": "Hellef",
                +	"CHANGE_VALUE_TITLE": "Neie Variable...",
                +	"RENAME_VARIABLE": "Die neie Variable sei Noome:",
                +	"RENAME_VARIABLE_TITLE": "All \"%1\" Variable umbenenne in:",
                +	"NEW_VARIABLE": "Neie Variable...",
                +	"NEW_VARIABLE_TITLE": "Die neie Variable sei Noome:",
                +	"COLOUR_PICKER_HELPURL": "https://hrx.wikipedia.org/wiki/Farreb",
                +	"COLOUR_PICKER_TOOLTIP": "Wähl en Farreb von der Palett.",
                +	"COLOUR_RANDOM_TITLE": "zufälliche Farwe",
                +	"COLOUR_RANDOM_TOOLTIP": "Wähl en Farreb noh dem Zufallsprinzip.",
                +	"COLOUR_RGB_TITLE": "Färreb mit",
                +	"COLOUR_RGB_RED": "rot",
                +	"COLOUR_RGB_GREEN": "grün",
                +	"COLOUR_RGB_BLUE": "blau",
                +	"COLOUR_RGB_TOOLTIP": "Kreiere ene Farreb mit sellrbst definierte rot, grün und blau Wearte. All Wearte müsse zwischich 0 und 100 liehe.",
                +	"COLOUR_BLEND_TITLE": "misch",
                +	"COLOUR_BLEND_COLOUR1": "Farreb 1",
                +	"COLOUR_BLEND_COLOUR2": "mit Farreb 2",
                +	"COLOUR_BLEND_RATIO": "im Verhältniss",
                +	"COLOUR_BLEND_TOOLTIP": "Vermischt 2 Farwe mit konfigurierbare Farrebverhältniss (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://hrx.wikipedia.org/wiki/For-Schleif",
                +	"CONTROLS_REPEAT_TITLE": "wiederhol %1 mol",
                +	"CONTROLS_REPEAT_INPUT_DO": "mach",
                +	"CONTROLS_REPEAT_TOOLTIP": "En Oonweisung meahrfach ausführe.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "Repetier solang",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "Repetiere bis",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Füahr die Oonweisung solang aus wie die Bedingung woahr (true) ist.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Füahr die Oonweisung solang aus wie die Bedingung falsch (false) ist.",
                +	"CONTROLS_FOR_TOOLTIP": "Zähl die Variable \"%1\" von enem Startweart bis zu enem Zielweart und füahrefür jede Weart en Oonweisung aus.",
                +	"CONTROLS_FOR_TITLE": "Zähl %1 von %2 bis %3 mit %4",
                +	"CONTROLS_FOREACH_TITLE": "Für Weart %1 aus der List %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Füahr en Oonweisung für jede Weart in der List aus und setzt dabei die Variable \"%1\" uff den aktuelle List Weart.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ausbreche aus der Schleif",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "mit der nächste Iteration fortfoohre aus der Schleifa",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Die umgebne Schleif beenne.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Die Oonweisung abbreche und mit der nächste Schleifiteration fortfoohre.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Warnung: Die block sollt nuar in en Schleif verwennet sin.",
                +	"CONTROLS_IF_TOOLTIP_1": "Wenn en Bedingung woahr (true) ist, dann füahr en Oonweisung aus.",
                +	"CONTROLS_IF_TOOLTIP_2": "Wenn en Bedingung woahr (true) ist, dann füahr die earscht Oonweisung aus.  Ansonscht füahr die zwooite Oonweisung aus.",
                +	"CONTROLS_IF_TOOLTIP_3": "Wenn der erschte Bedingung woahr (true) ist, dann füahr die erschte Oonweisung aus.  Orrer wenn die zwooite Bedingung woahr (true) ist, dann füahr die zwooite Oonweisung aus.",
                +	"CONTROLS_IF_TOOLTIP_4": "Wenn der erscht Bedingung woahr (true) ist, dann füahr die erschte Oonweisung aus.  Orrer wenn die zwooite Bedingung woahr (true) ist, dann füahr die zwooite Oonweisung aus.  Falls ken der beide Bedingungen woahr (true) ist, dann füahr die dritte Oonweisung aus.",
                +	"CONTROLS_IF_MSG_IF": "wenn",
                +	"CONTROLS_IF_MSG_ELSEIF": "orrer wenn",
                +	"CONTROLS_IF_MSG_ELSE": "orrer",
                +	"CONTROLS_IF_IF_TOOLTIP": "Hinzufüche, entferne orrer sortiere von Sektione",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "En weitre Bedingung hinzufüche.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "En orrer Bedingung hinzufüche, füahrt en Oonweisung aus falls ken Bedingung zutrifft.",
                +	"LOGIC_COMPARE_HELPURL": "https://hrx.wikipedia.org/wiki/Vergleich_%28Zahlen%29",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Ist woahr (true) wenn beide Wearte identisch sind.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Ist woahr (true) wenn beide Wearte unnerschiedlich sind.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Ist woahr (true) wenn der earschte Weart klener als der zwooite Weart ist.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Ist woahr (true) wenn der earscht Weart klener als orrer gleich gross wie zwooite Weart ist.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Ist woahr (true) wenn der erschte Weart grösser als der zwooite Weart ist.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Ist woahr (true) wenn der erschte Weart grösser als orrer gleich gross wie zwooite Weart ist.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Ist woahr (true) wenn beide Wearte woahr (true) sind.",
                +	"LOGIC_OPERATION_AND": "und",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Ist woahr (true) wenn en von der beide Wearte woahr (true) ist.",
                +	"LOGIC_OPERATION_OR": "orrer",
                +	"LOGIC_NEGATE_TITLE": "net %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Ist woahr (true) wenn der Ingäweweart falsch (false) ist.  Ist falsch (false) wenn der Ingäweweart woahr (true) ist.",
                +	"LOGIC_BOOLEAN_TRUE": "woahr",
                +	"LOGIC_BOOLEAN_FALSE": "falsch",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Ist entweder woahr (true) orrer falsch (false)",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Is NULL.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "wenn woahr",
                +	"LOGIC_TERNARY_IF_FALSE": "wenn falsch",
                +	"LOGIC_TERNARY_TOOLTIP": "Üwerprüft en Bedingung \"test\". Wenn die Bedingung woahr ist weerd der \"wenn woahr\" Weart zurückgeb, annerfalls der \"wenn falsch\" Weart",
                +	"MATH_NUMBER_HELPURL": "https://hrx.wikipedia.org/wiki/Zoohl",
                +	"MATH_NUMBER_TOOLTIP": "En Zoohl.",
                +	"MATH_ARITHMETIC_HELPURL": "https://hrx.wikipedia.org/wiki/Grundrechenoort",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Ist die Summe zwooier Wearte.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Ist die Differenz zwooier Wearte.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Ist das Produkt zwooier Wearte.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Ist der Quotient zwooier Wearte.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Ist der earschte Weart potenziert mit dem zoiten Weart.",
                +	"MATH_SINGLE_HELPURL": "https://hrx.wikipedia.org/wiki/Quadratwoorzel",
                +	"MATH_SINGLE_OP_ROOT": "Quadratwoorzel",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Ist die Qudratwoorzel von en Weart.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "Absolutweart",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Ist der Absolutweart von en Weart.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Negiert en Weart.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Ist der natüarliche Logarithmus von en Weart.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Ist der dekoodische Logarithmus von en Weart.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Ist Weart von der Exponentialfunktion von en Weart.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Rechnet 10 hoch Ingäbweart.",
                +	"MATH_TRIG_HELPURL": "https://hrx.wikipedia.org/wiki/Trigonometrie",
                +	"MATH_TRIG_TOOLTIP_SIN": "Ist der Sinus von en Winkel.",
                +	"MATH_TRIG_TOOLTIP_COS": "Ist der Cosinus von en Winkel.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Ist der Tangens von en Winkel.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Ist der Arcussinus von en Ingäbweart.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Ist der Arcuscosinus von en Ingabweart.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Ist der Arcustangens von en Ingäbweart.",
                +	"MATH_CONSTANT_HELPURL": "https://hrx.wikipedia.org/wiki/Mathematische_Konstante",
                +	"MATH_CONSTANT_TOOLTIP": "Mathematische Konstante wie: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) oder ∞ (unendlich).",
                +	"MATH_IS_EVEN": "ist grood",
                +	"MATH_IS_ODD": "ist ungrood",
                +	"MATH_IS_PRIME": "ist en Primenzoohl",
                +	"MATH_IS_WHOLE": "ganze Zoohl",
                +	"MATH_IS_POSITIVE": "ist positiv",
                +	"MATH_IS_NEGATIVE": "ist negativ",
                +	"MATH_IS_DIVISIBLE_BY": "ist telbar/kann getelt sin doorrich",
                +	"MATH_IS_TOOLTIP": "Üwerprüft ob en Zoohl grood, ungrood, en Primenzoohl, ganzzoohlich, positiv, negativ orrer doorrich en zwooite Zoohl telbar ist.  Gebt woahr (true) orrer falsch (false) zurück.",
                +	"MATH_CHANGE_HELPURL": "https://hrx.wikipedia.org/wiki/Inkrement_und_Dekrement",
                +	"MATH_CHANGE_TITLE": "mach höcher / erhöhe %1 um %2",
                +	"MATH_CHANGE_TOOLTIP": "Addiert en Weart zur Variable \"%1\" hinzu.",
                +	"MATH_ROUND_HELPURL": "https://hrx.wikipedia.org/wiki/Runden",
                +	"MATH_ROUND_TOOLTIP": "En Zoohl uff orrer ab runde.",
                +	"MATH_ROUND_OPERATOR_ROUND": "runde",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "uff runde",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ab runde",
                +	"MATH_ONLIST_OPERATOR_SUM": "Summe von en List",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Ist die Summ aller Wearte in en List.",
                +	"MATH_ONLIST_OPERATOR_MIN": "Minimalweart von en List",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Ist der klenste Weart in en List.",
                +	"MATH_ONLIST_OPERATOR_MAX": "Maximalweart en List",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Ist der grösste Weart in en List.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "Mittelweart en List",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Ist der Doorrichschnittsweart von aller Wearte in en List.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Median von en List",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Ist der Zentralweart von aller Wearte in en List.",
                +	"MATH_ONLIST_OPERATOR_MODE": "Restweart von en List",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Findt den am häifichste voarkommend Weart in en List.  Falls ken Weart öftersch voarkomme als all annre, weard die originale List zurückgeche",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "Standart/Padrong Abweichung von en List",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Ist die standartiesierte/padronisierte Standartabweichung/Padrongabweichung von aller Wearte in der List",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Zufallsweart von en List",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Geb en Zufallsweart aus der List zurück.",
                +	"MATH_MODULO_HELPURL": "https://hrx.wikipedia.org/wiki/Modulo",
                +	"MATH_MODULO_TITLE": "Rest von %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Der Rest noh en Division.",
                +	"MATH_CONSTRAIN_TITLE": "begrenze %1 von %2 bis %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Begrenzt den Weartebereich mittels von / bis Wearte. (inklusiv)",
                +	"MATH_RANDOM_INT_HELPURL": "https://hrx.wikipedia.org/wiki/Zufallszahlen",
                +	"MATH_RANDOM_INT_TITLE": "ganzoohlicher Zufallswearte zwischich %1 bis %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Generier/erzeich en ganzähliche Zufallsweart zwischich zwooi Wearte (inklusiv).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://hex.wikipedia.org/wiki/Zufallszoohle",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "Zufallszoohl (0.0 -1.0)",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Generier/erzeich en Zufallszoohl zwischich 0.0 (inklusiv) und 1.0 (exklusiv).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)https://hrx.wikipedia.org/wiki/Zeichenkette",
                +	"TEXT_TEXT_TOOLTIP": "En Buchstoob, Text orrer Satz.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "Erstell Text aus",
                +	"TEXT_JOIN_TOOLTIP": "Erstellt en Text doorrich das verbinne von mehre Textelemente.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "verbinne",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Hinzufüche, entfernne und sortiere von Elemente.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "En Element zum Text hinzufüche.",
                +	"TEXT_APPEND_TOOLTIP": "Text an die Variable \"%1\" oonhänge.",
                +	"TEXT_LENGTH_TITLE": "läng %1",
                +	"TEXT_LENGTH_TOOLTIP": "Die Oonzoohl von Zeiche in enem Text. (inkl. Leerzeiche)",
                +	"TEXT_ISEMPTY_TITLE": "%1 ist leer?",
                +	"TEXT_ISEMPTY_TOOLTIP": "Ist woahr (true), wenn der Text leer ist.",
                +	"TEXT_INDEXOF_TOOLTIP": "Findt das earste / letzte Voarkommniss von en Suchbegriffes in enem Text.  Gebt die Position von dem Begriff orrer %1 zurück.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "Such der Begriff sein earstes Voarkommniss",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "Suche der Begriff sein letztes Vorkommniss.",
                +	"TEXT_CHARAT_FROM_START": "hol Buchstoob #",
                +	"TEXT_CHARAT_FROM_END": "hol Buchstoob # von End",
                +	"TEXT_CHARAT_FIRST": "hol earschte Buchstoob",
                +	"TEXT_CHARAT_LAST": "hol letztes Wort",
                +	"TEXT_CHARAT_RANDOM": "hol zufälliches Buchstoob",
                +	"TEXT_CHARAT_TOOLTIP": "Extrahiear en Buchstoob von en spezifizierte Position.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Schickt en bestimmstes Tel von dem Text retuar.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in Text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "hol substring Buchstoob #te",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "hol #te Buchstoob von hinne",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "earschte Buchstoob",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "bis Buchstoob #te",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "bis #te Buchstoob von hinne",
                +	"TEXT_GET_SUBSTRING_END_LAST": "bis letzte Buchstoob",
                +	"TEXT_CHANGECASE_TOOLTIP": "Wandelt Schreibweise von Texte um, in Grossbuchstoobe, Klenbuchstoobe orrer den earste Buchstoob von jedes Wort gross und die annre klen.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "umwandle in GROSSBUCHSTOOBE",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "umwandle in klenbuchstoobe",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "umwandle in Wörter",
                +	"TEXT_TRIM_TOOLTIP": "Entfernt Leerzeiche vom Oonfang und / orrer End von en Text.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "entfern Leerzeiche von Oonfang und End Seite",
                +	"TEXT_TRIM_OPERATOR_LEFT": "entferne Leerzeiche von Oonfang Seite",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "entferne Leerzeiche von End Seite von",
                +	"TEXT_PRINT_TITLE": "Ausgäb %1",
                +	"TEXT_PRINT_TOOLTIP": "Geb den Inhalt von en Variable aus.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Frocht noh Text mit Hinweis",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Frächt noh Zoohl mit Hinweis",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Frocht den Benutzer noh en Zoohl.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Frocht den Benutzer noh enem Text.",
                +	"LISTS_CREATE_EMPTY_TITLE": "Generier/erzeich en leear List",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Generier/erzeich en leear List ohne Inhalt.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Generier/erzeich en List mit konfigurierte Elemente.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "Erzeich List mit",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "List",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Hinzufüche, entferne und sortiere von Elemente.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "En Element zur List hinzufüche.",
                +	"LISTS_REPEAT_TOOLTIP": "Erzeicht en List mit en variable Oonzoohl von Elemente",
                +	"LISTS_REPEAT_TITLE": "Erzich List mit Element %1 wiederhol das %2 mol",
                +	"LISTS_LENGTH_TITLE": "länge %1",
                +	"LISTS_LENGTH_TOOLTIP": "Die Oonzoohl von Elemente in der List.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ist leear?",
                +	"LISTS_ISEMPTY_TOOLTIP": "Ist woahr (true), wenn die List leear ist.",
                +	"LISTS_INLIST": "in der List",
                +	"LISTS_INDEX_OF_FIRST": "Such earstes Voarkommniss",
                +	"LISTS_INDEX_OF_LAST": "Such letztes Voarkommniss",
                +	"LISTS_INDEX_OF_TOOLTIP": "Sucht die Position (index) von en Element in der List Gebt %1 zurück wenn nixs gefunn woard.",
                +	"LISTS_GET_INDEX_GET": "Nehm",
                +	"LISTS_GET_INDEX_GET_REMOVE": "Nehm und entfern",
                +	"LISTS_GET_INDEX_REMOVE": "Entfern",
                +	"LISTS_GET_INDEX_FROM_END": "#te von hinne",
                +	"LISTS_GET_INDEX_FIRST": "earste",
                +	"LISTS_GET_INDEX_LAST": "letzte",
                +	"LISTS_GET_INDEX_RANDOM": "zufälliches",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ist das earschte Element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ist das letzte Element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Extrahiert das Element zu en definierte Stell von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Extrahiert das earste Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Extrahiert das letzte Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Extrahiert en zufälliches Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Extrahiert und entfernt das Element zu en definierte Stell von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Extrahiert und entfernt das earste Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Extrahiert und entfernt das letzte Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Extrahiert und entfernt en zufälliches Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Entfernt das Element zu en definierte Stell von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Entfernt das earste Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Entfernt das letzte Element von der List.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Entfernt en zufälliches Element von der List.",
                +	"LISTS_SET_INDEX_SET": "setz",
                +	"LISTS_SET_INDEX_INSERT": "tue ren setz an",
                +	"LISTS_SET_INDEX_INPUT_TO": "uff",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Setzt das Element zu en definierte Stell in en List.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Sets the first item in a list.Setzt das earschte Element an en list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Setzt das letzte Element an en List.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Setzt en zufälliches Element an en List.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Tut das Element ren setze an en definierte Stell an en List.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Tut das Element an en Oonfang von en List ren setze.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Oonhängt das Element zu en List sei End.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Tut das Element zufällich an en List ren setze.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "hol Unnerlist von #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "hol Unnerliste von # vom End",
                +	"LISTS_GET_SUBLIST_START_FIRST": "hol Unnerliste vom Earste",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "zu #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "zu # vom End",
                +	"LISTS_GET_SUBLIST_END_LAST": "zum Letzte",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Generiert en Kopie von en definierte Tel von en List.",
                +	"VARIABLES_GET_TOOLTIP": "Gebt der Variable sein Weart zurück.",
                +	"VARIABLES_GET_CREATE_SET": "Generier/erzeiche \"Schreibe %1\"",
                +	"VARIABLES_SET": "Schreib %1 zu %2",
                +	"VARIABLES_SET_TOOLTIP": "Setzt en Variable sei Weart.",
                +	"VARIABLES_SET_CREATE_GET": "Generier/erzeich \"Lese %1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "zu",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "Funktionsblock",
                +	"PROCEDURES_BEFORE_PARAMS": "mit:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "mit:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "En Funktionsblock ohne Rückgäbweart.",
                +	"PROCEDURES_DEFRETURN_RETURN": "geb zurück",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "En Funktionsblock mit Rückgäbweart.",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Warnung: die Funktionsblock hot doppelt Parameter.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://hrx.wikipedia.org/wiki/Prozedur_%28Programmierung%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Ruf en Funktionsblock ohne Rückgäweart uff.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://hrx.wikipedia.org/wiki/Prozedur_%28Programmierung%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Ruf en Funktionsblock mit Rückgäbweart uff.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "Parameter",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Variable:",
                +	"PROCEDURES_MUTATORARG_TITLE": "Markiear Funktionsblock",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Generier/erzeich \"Uffruf %1\"",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Markiear Funktionsblock",
                +	"PROCEDURES_CREATE_DO": "Generier/erzeich \"Uffruf %1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Wenn der earste Weart woahr (true) ist, Geb den zwooite Weart zurück.",
                +	"PROCEDURES_IFRETURN_WARNING": "Warnung: Der Block därref nuar innich en Funktionsblock genutzt sin."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/hu.json b/blockly/webif/static/blockly/msg/json/hu.json
                new file mode 100644
                index 000000000..98ad78f19
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/hu.json
                @@ -0,0 +1,339 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"Takács Viktor László",
                +			"Dj",
                +			"Grin",
                +			"ViDam",
                +			"Csega",
                +			"Fitoschido",
                +			"Lajthabalazs",
                +			"Tacsipacsi",
                +			"Rodrigo",
                +			"Máté",
                +			"BanKris",
                +			"Notramo",
                +			"Urbalazs"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "változó",
                +	"TODAY": "Ma",
                +	"DUPLICATE_BLOCK": "Másolat",
                +	"ADD_COMMENT": "Megjegyzés hozzáadása",
                +	"REMOVE_COMMENT": "Megjegyzés eltávolítása",
                +	"EXTERNAL_INPUTS": "Külső kapcsolatok",
                +	"INLINE_INPUTS": "Belső kapcsolatok",
                +	"DELETE_BLOCK": "Blokk törlése",
                +	"DELETE_X_BLOCKS": "%1 blokk törlése",
                +	"DELETE_ALL_BLOCKS": "Az összes %1 blokk törlése?",
                +	"CLEAN_UP": "Blokkok kiürítése",
                +	"COLLAPSE_BLOCK": "Blokk összecsukása",
                +	"COLLAPSE_ALL": "Blokkok összecsukása",
                +	"EXPAND_BLOCK": "Blokk kinyitása",
                +	"EXPAND_ALL": "Blokkok kinyitása",
                +	"DISABLE_BLOCK": "Blokk letiltása",
                +	"ENABLE_BLOCK": "Blokk engedélyezése",
                +	"HELP": "Súgó",
                +	"UNDO": "Visszavonás",
                +	"REDO": "Újra",
                +	"CHANGE_VALUE_TITLE": "Érték módosítása:",
                +	"RENAME_VARIABLE": "Változó átnevezése…",
                +	"RENAME_VARIABLE_TITLE": "Minden „%1” változó átnevezése erre:",
                +	"NEW_VARIABLE": "Változó létrehozása…",
                +	"NEW_VARIABLE_TITLE": "Az új változó neve:",
                +	"VARIABLE_ALREADY_EXISTS": "A(z) „%1” nevű változó már létezik.",
                +	"DELETE_VARIABLE_CONFIRMATION": "A(z) „%2” változó %1 használatának törlése?",
                +	"DELETE_VARIABLE": "A(z) „%1” változó törlése",
                +	"COLOUR_PICKER_HELPURL": "https://hu.wikipedia.org/wiki/Szín",
                +	"COLOUR_PICKER_TOOLTIP": "Válassz színt a palettáról.",
                +	"COLOUR_RANDOM_TITLE": "véletlen szín",
                +	"COLOUR_RANDOM_TOOLTIP": "Véletlenszerűen kiválasztott szín.",
                +	"COLOUR_RGB_TITLE": "Szín",
                +	"COLOUR_RGB_RED": "vörös",
                +	"COLOUR_RGB_GREEN": "zöld",
                +	"COLOUR_RGB_BLUE": "kék",
                +	"COLOUR_RGB_TOOLTIP": "Szín előállítása a megadott vörös, zöld, és kék értékekkel.  Minden értéknek 0 és 100 közé kell esnie.",
                +	"COLOUR_BLEND_TITLE": "színkeverés",
                +	"COLOUR_BLEND_COLOUR1": "szín 1",
                +	"COLOUR_BLEND_COLOUR2": "szín 2",
                +	"COLOUR_BLEND_RATIO": "arány",
                +	"COLOUR_BLEND_TOOLTIP": "Két színt kever össze a megadott arányban (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://hu.wikipedia.org/wiki/Ciklus_(programoz%C3%A1s)#Sz.C3.A1ml.C3.A1l.C3.B3s_.28FOR.29_ciklus",
                +	"CONTROLS_REPEAT_TITLE": "ismételd %1 alkalommal",
                +	"CONTROLS_REPEAT_INPUT_DO": "",
                +	"CONTROLS_REPEAT_TOOLTIP": "Megadott kódrészlet ismételt végrehajtása.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ismételd amíg",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ismételd amíg",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Amíg a feltétel igaz, végrehajtja az utasításokat.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Amíg a feltétel hamis, végrehajtja az utasításokat.",
                +	"CONTROLS_FOR_TOOLTIP": "A(z) '%1' változó felveszi a kezdőérték és a végérték közötti értékeket a meghatározott lépésközzel. Eközben a meghatározott blokkokat hajtja végre.",
                +	"CONTROLS_FOR_TITLE": "számolj %1 értékével %2 és %3 között %4 lépésközzel",
                +	"CONTROLS_FOREACH_TITLE": "minden %1 elemre a %2 listában",
                +	"CONTROLS_FOREACH_TOOLTIP": "A '%1' változó minden lépésben megkapja a lista adott elemének értékét, és végrehajt vele néhány utasítást.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "befejezi az ismétlést",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "folytatja a következővel",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Megszakítja az utasítást tartalmazó ciklust.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Kihagyja a ciklus további részét, és elölről kezdi a következő elemmel.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Figyelem: Ez a blokk csak cikluson belül használható.",
                +	"CONTROLS_IF_TOOLTIP_1": "Ha a kifejezés igaz, akkor végrehajtja az utasításokat.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ha a kifejezés igaz, akkor végrehajtja az első utasításblokkot. Különben a második utasításblokk kerül végrehajtásra.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ha az első kifejezés igaz, akkor végrehajtja az első utasításblokkot. Különben, ha a második kifejezés igaz, akkor végrehajtja a második utasítás blokkot.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ha az első kifejezés igaz, akkor végrehajtjuk az első utasítás blokkot.  Ha a második kifejezés igaz, akkor végrehajtjuk a második utasítás blokkot.  Amennyiben egyik kifejezés sem igaz, akkor az utolsó utasítás blokk kerül végrehajtásra.",
                +	"CONTROLS_IF_MSG_IF": "ha",
                +	"CONTROLS_IF_MSG_ELSEIF": "különben ha",
                +	"CONTROLS_IF_MSG_ELSE": "különben",
                +	"CONTROLS_IF_IF_TOOLTIP": "A ha blokk testreszabásához bővítsd, töröld vagy rendezd át a részeit.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Feltétel hozzáadása a ha blokkhoz.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Végső feltétel hozzáadása a ha blokkhoz.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Mégse",
                +	"IOS_ERROR": "Hiba",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Ennek a függvénynek kettőzött bemenete van.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Változó hozzáadása",
                +	"IOS_VARIABLES_ADD_BUTTON": "Hozzáadás",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Átnevezés",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Törlés",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Változó neve",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Nem használhat üres változónevet.",
                +	"LOGIC_COMPARE_HELPURL": "https://hu.wikipedia.org/wiki/Egyenl%C5%91tlens%C3%A9g",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Igaz, ha a kifejezés két oldala egyenlő.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Igaz, ha a kifejezés két oldala nem egyenlő..",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Igaz, ha a bal oldali kifejezés kisebb, mint a jobb oldali.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Igaz, ha a bal oldali kifejezés kisebb vagy egyenlő, mint a jobb oldali.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Igaz, ha a bal oldali kifejezés nagyobb, mint a jobb oldali.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Igaz, ha a bal oldali kifejezés nagyobb vagy egyenlő, mint a jobb oldali.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Igaz, ha mindkét kifejezés igaz.",
                +	"LOGIC_OPERATION_AND": "és",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Igaz, ha legalább az egyik kifejezés igaz.",
                +	"LOGIC_OPERATION_OR": "vagy",
                +	"LOGIC_NEGATE_TITLE": "nem %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Igaz, ha a kifejezés hamis.  Hamis, ha a kifejezés igaz.",
                +	"LOGIC_BOOLEAN_TRUE": "igaz",
                +	"LOGIC_BOOLEAN_FALSE": "hamis",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Igaz, vagy hamis érték",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "null érték.",
                +	"LOGIC_TERNARY_CONDITION": "vizsgáld meg:",
                +	"LOGIC_TERNARY_IF_TRUE": "érték, ha igaz:",
                +	"LOGIC_TERNARY_IF_FALSE": "érték, ha hamis:",
                +	"LOGIC_TERNARY_TOOLTIP": "Kiértékeli a megvizsgálandó kifejezést. Ha a kifejezés igaz, visszatér az \"érték, ha igaz\" értékkel, különben az \"érték, ha hamis\" értékkel.",
                +	"MATH_NUMBER_HELPURL": "https://hu.wikipedia.org/wiki/Sz%C3%A1m",
                +	"MATH_NUMBER_TOOLTIP": "Egy szám.",
                +	"MATH_ARITHMETIC_HELPURL": "https://hu.wikipedia.org/wiki/Matematikai_m%C5%B1velet",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Két szám összege.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Két szám különbsége.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Két szám szorzata.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Két szám hányadosa.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Az első számnak a második számmal megegyező hatványa.",
                +	"MATH_SINGLE_HELPURL": "https://hu.wikipedia.org/wiki/Gy%C3%B6kvon%C3%A1s",
                +	"MATH_SINGLE_OP_ROOT": "négyzetgyök",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "A szám négyzetgyöke.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "abszolútérték",
                +	"MATH_SINGLE_TOOLTIP_ABS": "A szám abszolútértéke.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "A szám -1 szerese.",
                +	"MATH_SINGLE_TOOLTIP_LN": "A szám természetes alapú logaritmusa.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "A szám 10-es alapú logaritmusa.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Az e megadott számú hatványa.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "A 10 megadott számú hatványa.",
                +	"MATH_TRIG_HELPURL": "https://hu.wikipedia.org/wiki/Sz%C3%B6gf%C3%BCggv%C3%A9nyek",
                +	"MATH_TRIG_TOOLTIP_SIN": "A fokban megadott szög szinusz értéke.",
                +	"MATH_TRIG_TOOLTIP_COS": "A fokban megadott szög koszinusz értéke.",
                +	"MATH_TRIG_TOOLTIP_TAN": "A fokban megadott szög tangens értéke.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "A fokban megadott szög arkusz szinusz értéke.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "A fokban megadott szög arkusz koszinusz értéke.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "A fokban megadott szög arkusz tangens értéke.",
                +	"MATH_CONSTANT_HELPURL": "https://hu.wikipedia.org/wiki/Matematikai_konstans",
                +	"MATH_CONSTANT_TOOLTIP": "Ismert matematikai konstans: π (3.141…), e (2.718…), φ (1.618…), gyök(2) (1.414…), gyök(½) (0.707…), vagy ∞ (végtelen).",
                +	"MATH_IS_EVEN": "páros",
                +	"MATH_IS_ODD": "páratlan",
                +	"MATH_IS_PRIME": "prím",
                +	"MATH_IS_WHOLE": "egész",
                +	"MATH_IS_POSITIVE": "pozitív",
                +	"MATH_IS_NEGATIVE": "negatív",
                +	"MATH_IS_DIVISIBLE_BY": "-nek osztója",
                +	"MATH_IS_TOOLTIP": "Ellenőrzi, hogy a szám páros, páratlan, prím, egész, pozitív vagy negatív-e, illetve osztható-e a másodikkal. Igaz, vagy hamis értéket ad eredményül.",
                +	"MATH_CHANGE_HELPURL": "https://hu.wikipedia.org/wiki/JavaScript#Aritmetikai_oper.C3.A1torok",
                +	"MATH_CHANGE_TITLE": "növeld %1 értékét %2 -vel",
                +	"MATH_CHANGE_TOOLTIP": "A \"%1\" változó értékének növelése egy számmal.",
                +	"MATH_ROUND_HELPURL": "https://hu.wikipedia.org/wiki/Eg%C3%A9szr%C3%A9sz#Kerek.C3.ADt.C3.A9s",
                +	"MATH_ROUND_TOOLTIP": "Egy szám kerekítése felfelé vagy lefelé.",
                +	"MATH_ROUND_OPERATOR_ROUND": "kerekítsd",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "kerekítsd felfelé",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "kerekítsd lefelé",
                +	"MATH_ONLIST_OPERATOR_SUM": "lista elemeinek összege",
                +	"MATH_ONLIST_TOOLTIP_SUM": "A lista elemeinek összegét adja eredményül.",
                +	"MATH_ONLIST_OPERATOR_MIN": "lista legkisebb eleme",
                +	"MATH_ONLIST_TOOLTIP_MIN": "A lista legkisebb elemét adja vissza.",
                +	"MATH_ONLIST_OPERATOR_MAX": "lista legnagyobb eleme",
                +	"MATH_ONLIST_TOOLTIP_MAX": "A lista legnagyobb elemét adja vissza.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "lista elemeinek átlaga",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "A lista elemeinek átlagát adja eredményül.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "lista mediánja",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "A lista elemeinek mediánját adja eredményül.",
                +	"MATH_ONLIST_OPERATOR_MODE": "lista módusza",
                +	"MATH_ONLIST_TOOLTIP_MODE": "A lista elemeinek móduszát adja eredményül.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "lista elemeinek szórása",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "A lista elemeinek szórását adja eredményül.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "lista véletlen eleme",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "A lista egy véletlen elemét adja eredményül.",
                +	"MATH_MODULO_HELPURL": "https://hu.wikipedia.org/wiki/Eg%C3%A9szr%C3%A9sz#Als.C3.B3_eg.C3.A9szr.C3.A9sz",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 maradéka",
                +	"MATH_MODULO_TOOLTIP": "Az egész osztás maradékát adja eredméynül.",
                +	"MATH_CONSTRAIN_TITLE": "korlátozd %1-t %2 és %3 közé",
                +	"MATH_CONSTRAIN_TOOLTIP": "Egy változó értékének korlátozása a megadott zárt intervallumra.",
                +	"MATH_RANDOM_INT_HELPURL": "https://hu.wikipedia.org/wiki/V%C3%A9letlen",
                +	"MATH_RANDOM_INT_TITLE": "véletlen egész szám %1 között %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Véletlen egész szám a megadott zárt intervallumon belül.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://hu.wikipedia.org/wiki/V%C3%A9letlen",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "véletlen tört",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Véletlen tört érték 0.0 és 1.0 között.",
                +	"TEXT_TEXT_HELPURL": "https://hu.wikipedia.org/wiki/String",
                +	"TEXT_TEXT_TOOLTIP": "Egy betű, szó vagy szöveg egy sora.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "fűzd össze",
                +	"TEXT_JOIN_TOOLTIP": "Tetszőleges számú szövegrészletet fűz össze egybefüggő szöveggé.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "fűzd össze",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Összefűzéssel, törléssel vagy rendezéssel kapcsolato sblokkok szöveg szerkesztéséhez.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Elem hozzáfűzése a szöveghez.",
                +	"TEXT_APPEND_TOOLTIP": "Szöveget fűz a \"%1\" változó értékéhez.",
                +	"TEXT_LENGTH_TITLE": "%1 hossza",
                +	"TEXT_LENGTH_TOOLTIP": "A megadott szöveg karaktereinek számát adja eredményül (beleértve a szóközöket).",
                +	"TEXT_ISEMPTY_TITLE": "%1 üres",
                +	"TEXT_ISEMPTY_TOOLTIP": "Igaz, ha a vizsgált szöveg hossza 0.",
                +	"TEXT_INDEXOF_TOOLTIP": "A keresett szöveg első vagy utolsó előfordulásával tér vissza.  %1 esetén a szövegrészlet nem található.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "szövegben az első előfordulásának helye",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "szövegben az utolsó előfordulásának helye",
                +	"TEXT_CHARAT_FROM_START": "elölről",
                +	"TEXT_CHARAT_FROM_END": "hátulról",
                +	"TEXT_CHARAT_FIRST": "első",
                +	"TEXT_CHARAT_LAST": "utolsó",
                +	"TEXT_CHARAT_RANDOM": "véletlen",
                +	"TEXT_CHARAT_TAIL": "karaktere",
                +	"TEXT_CHARAT_TOOLTIP": "A szöveg egy megadott karakterét adja eredményül.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "A megadott szövegrészletet adja eredményül.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "a",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "szövegben válaszd ki a(z)",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "szövegben válaszd ki a hátulról a(z)",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "szövegben válaszd ki az első",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "betűtől a(z)",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "betűtől a hátulról számított",
                +	"TEXT_GET_SUBSTRING_END_LAST": "betűtől az utolsó",
                +	"TEXT_GET_SUBSTRING_TAIL": "betűig tartó betűsort",
                +	"TEXT_CHANGECASE_TOOLTIP": "Return a copy of the text in a different case.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "NAGYBETŰS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "kisbetűs",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Címként Formázott",
                +	"TEXT_TRIM_TOOLTIP": "Levágja a megadott szöveg végeiről a szóközöket.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "szóközök levágása mindkét végéről",
                +	"TEXT_TRIM_OPERATOR_LEFT": "szóközök levágása az elejéről",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "szóközök levágása a végéről",
                +	"TEXT_PRINT_TITLE": "Üzenet %1",
                +	"TEXT_PRINT_TOOLTIP": "Megejelníti a megadott kaakterláncot üzenetként a képernyőn.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Kérj be szöveget",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Kérj be számot",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Számot kér be a felhasználótól.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Szöveget kér be a felhasználótól.",
                +	"TEXT_REPLACE_MESSAGE0": "%1 cseréje %2-vel %3-ban",
                +	"LISTS_CREATE_EMPTY_TITLE": "üres lista",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Elemeket nem tartalmazó üres listát ad eredményül",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Listát készít a megadott elemekből.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "Lista készítés, elemek:",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Add, remove, or reorder sections to reconfigure this list block.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Elem hozzáadása listához.",
                +	"LISTS_REPEAT_TOOLTIP": "A megadtott elem felhasználásával n elemű listát készít",
                +	"LISTS_REPEAT_TITLE": "Lista készítése %1 elemet %2 alkalommal hozzáadva",
                +	"LISTS_LENGTH_TITLE": "%1 lista hossza",
                +	"LISTS_LENGTH_TOOLTIP": "A lista elemszámát adja eredményül.",
                +	"LISTS_ISEMPTY_TITLE": "%1 üres lista?",
                +	"LISTS_ISEMPTY_TOOLTIP": "Az eredmény igaz, ha a lista nem tartalmaz elemeket.",
                +	"LISTS_INLIST": "A(z)",
                +	"LISTS_INDEX_OF_FIRST": "listában első előfordulásaː",
                +	"LISTS_INDEX_OF_LAST": "listában utolsó előfordulásaː",
                +	"LISTS_INDEX_OF_TOOLTIP": "A megadott elem első vagy utolsó előfordulásával tér vissza. Ha nem talál ilyen elemet, akkor %1 a visszatérési érték.",
                +	"LISTS_GET_INDEX_GET": "listából értéke",
                +	"LISTS_GET_INDEX_GET_REMOVE": "listából kivétele",
                +	"LISTS_GET_INDEX_REMOVE": "listából törlése",
                +	"LISTS_GET_INDEX_FROM_START": "az elejétől számított",
                +	"LISTS_GET_INDEX_FROM_END": "a végétől számított",
                +	"LISTS_GET_INDEX_FIRST": "az első",
                +	"LISTS_GET_INDEX_LAST": "az utolsó",
                +	"LISTS_GET_INDEX_RANDOM": "bármely",
                +	"LISTS_GET_INDEX_TAIL": "elemnek",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 az első elemet jelenti.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 az utolsó elemet jelenti.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "A lista megadott sorszámú elemét adja eredményül.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "A lista első elemét adja eredményül.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "A lista utolsó elemét adja eredményül.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "A lista véletlenszerűen választott elemét adja eredményül.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "A megadott sorszámú elem kivétele a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Az első elem kivétele a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Az utolsó elem kivétele a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Véletlenszerűen választott elem kivétele a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "A megadott sorszámú elem törlése a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Az első elem törlése a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Az utolsó elem törlése a listából.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Véletlenszerűen választott elem törlése a listából.",
                +	"LISTS_SET_INDEX_SET": "listába állítsd be",
                +	"LISTS_SET_INDEX_INSERT": "listába szúrd be",
                +	"LISTS_SET_INDEX_INPUT_TO": "elemkéntː",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "A megadott sorszámú elem cseréje a listában.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Az első elem cseréje a listában.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Az utolsó elem cseréje a listában.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Véletlenszerűen választott elem cseréje a listában.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Beszúrás a megadott sorszámú elem elé a listában.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Beszúrás a lista elejére.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Beszúrás a lista végére.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Beszúrás véletlenszerűen választott elem elé a listában.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "részlistája az elejétől számított",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "részlistája a végétől számított",
                +	"LISTS_GET_SUBLIST_START_FIRST": "részlistája az első",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "és az elejétől számított",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "és a végétől számított",
                +	"LISTS_GET_SUBLIST_END_LAST": "és az utolsó",
                +	"LISTS_GET_SUBLIST_TAIL": "elem között",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "A lista adott részéről másolat.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "%1 %2 %3 rendezés",
                +	"LISTS_SORT_TOOLTIP": "Egy lista egy másolatának rendezése.",
                +	"LISTS_SORT_ORDER_ASCENDING": "növekvő",
                +	"LISTS_SORT_ORDER_DESCENDING": "csökkenő",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerikus",
                +	"LISTS_SORT_TYPE_TEXT": "betűrendben",
                +	"LISTS_SORT_TYPE_IGNORECASE": "betűrendben nagybetű figyelmen kívül hagyásával",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "lista készítése szövegből",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "sztring készítése listából",
                +	"LISTS_SPLIT_WITH_DELIMITER": "határoló karakter",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Listát készít a határoló karaktereknél törve a szöveget.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "A lista elemeit összefűzi szöveggé a határoló karaktereket is felhasználva.",
                +	"ORDINAL_NUMBER_SUFFIX": ".",
                +	"VARIABLES_GET_TOOLTIP": "A változó értékét adja eredményül.",
                +	"VARIABLES_GET_CREATE_SET": "Készíts \"%1=\"",
                +	"VARIABLES_SET": "%1 %2",
                +	"VARIABLES_SET_TOOLTIP": "A változónak adhatunk értéket.",
                +	"VARIABLES_SET_CREATE_GET": "Készíts \"%1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "Eljárás",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "név",
                +	"PROCEDURES_BEFORE_PARAMS": "paraméterlistaː",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "paraméterlistaː",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Eljárás (nem ad vissza eredményt).",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Írj erről a funkcióról...",
                +	"PROCEDURES_DEFRETURN_RETURN": "eredménye",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Függvény eredménnyel.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "utasítások engedélyezése",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Figyelem: Az eljárásban azonos elnevezésű paramétert adtál meg.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://hu.wikipedia.org/wiki/F%C3%BCggv%C3%A9ny_(programoz%C3%A1s)",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Végrehajtja az eljárást.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://hu.wikipedia.org/wiki/F%C3%BCggv%C3%A9ny_(programoz%C3%A1s)",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Meghívja a függvényt.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "paraméterek",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Bemenetek hozzáadása, eltávolítása vagy átrendezése ehhez a függvényhez.",
                +	"PROCEDURES_MUTATORARG_TITLE": "változó:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Bemenet hozzáadása a függvényhez.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Függvénydefiníció kiemelése",
                +	"PROCEDURES_CREATE_DO": "„%1” létrehozása",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ha az érték igaz, akkor visszatér a függvény értékével.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Figyelem: Ez a blokk csak függvénydefiníción belül használható."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ia.json b/blockly/webif/static/blockly/msg/json/ia.json
                new file mode 100644
                index 000000000..0df31950c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ia.json
                @@ -0,0 +1,294 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"McDutchie",
                +			"Karmwiki"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "cosa",
                +	"TODAY": "Hodie",
                +	"DUPLICATE_BLOCK": "Duplicar",
                +	"ADD_COMMENT": "Adder commento",
                +	"REMOVE_COMMENT": "Remover commento",
                +	"EXTERNAL_INPUTS": "Entrata externe",
                +	"INLINE_INPUTS": "Entrata interne",
                +	"DELETE_BLOCK": "Deler bloco",
                +	"DELETE_X_BLOCKS": "Deler %1 blocos",
                +	"DELETE_ALL_BLOCKS": "Deler tote le %1 blocos?",
                +	"CLEAN_UP": "Clarar le blocos",
                +	"COLLAPSE_BLOCK": "Plicar bloco",
                +	"COLLAPSE_ALL": "Plicar blocos",
                +	"EXPAND_BLOCK": "Displicar bloco",
                +	"EXPAND_ALL": "Displicar blocos",
                +	"DISABLE_BLOCK": "Disactivar bloco",
                +	"ENABLE_BLOCK": "Activar bloco",
                +	"HELP": "Adjuta",
                +	"UNDO": "Disfacer",
                +	"REDO": "Refacer",
                +	"CHANGE_VALUE_TITLE": "Cambiar valor:",
                +	"RENAME_VARIABLE": "Renominar variabile...",
                +	"RENAME_VARIABLE_TITLE": "Renominar tote le variabiles '%1' a:",
                +	"NEW_VARIABLE": "Nove variabile...",
                +	"NEW_VARIABLE_TITLE": "Nomine del nove variabile:",
                +	"COLOUR_PICKER_HELPURL": "https://ia.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Elige un color del paletta.",
                +	"COLOUR_RANDOM_TITLE": "color aleatori",
                +	"COLOUR_RANDOM_TOOLTIP": "Eliger un color al hasardo.",
                +	"COLOUR_RGB_TITLE": "colorar con",
                +	"COLOUR_RGB_RED": "rubie",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "blau",
                +	"COLOUR_RGB_TOOLTIP": "Crear un color con le quantitate specificate de rubie, verde e blau. Tote le valores debe esser inter 0 e 100.",
                +	"COLOUR_BLEND_TITLE": "miscer",
                +	"COLOUR_BLEND_COLOUR1": "color 1",
                +	"COLOUR_BLEND_COLOUR2": "color 2",
                +	"COLOUR_BLEND_RATIO": "ration",
                +	"COLOUR_BLEND_TOOLTIP": "Misce duo colores con un ration specificate (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repeter %1 vices",
                +	"CONTROLS_REPEAT_INPUT_DO": "face",
                +	"CONTROLS_REPEAT_TOOLTIP": "Exequer certe instructiones plure vices.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repeter durante que",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repeter usque a",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Durante que un valor es ver, exequer certe instructiones.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Durante que un valor es false, exequer certe instructiones.",
                +	"CONTROLS_FOR_TOOLTIP": "Mitter in le variabile '%1' le valores ab le numero initial usque al numero final, con passos secundo le intervallo specificate, e exequer le blocos specificate.",
                +	"CONTROLS_FOR_TITLE": "contar con %1 de %2 a %3 per %4",
                +	"CONTROLS_FOREACH_TITLE": "pro cata elemento %1 in lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Pro cata elemento in un lista, mitter lo in le variabile '%1' e exequer certe instructiones.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "escappar del bucla",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuar con le proxime iteration del bucla",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Escappar del bucla continente.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Saltar le resto de iste bucla e continuar con le proxime iteration.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Attention: Iste bloco pote solmente esser usate in un bucla.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si un valor es ver, exequer certe instructiones.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si un valor es ver, exequer le prime bloco de instructiones. Si non, exequer le secunde bloco de instructiones.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si le prime valor es ver, exequer le prime bloco de instructiones. Si non, si le secunde valor es ver, exequer le secunde bloco de instructiones.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si le prime valor es ver, exequer le prime bloco de instructiones. Si non, si le secunde valor es ver, exequer le secunde bloco de instructiones. Si necun del valores es ver, exequer le ultime bloco de instructiones.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "si non si",
                +	"CONTROLS_IF_MSG_ELSE": "si non",
                +	"CONTROLS_IF_IF_TOOLTIP": "Adde, remove o reordina sectiones pro reconfigurar iste bloco \"si\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Adder un condition al bloco \"si\".",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Adder un condition final de reserva al bloco \"si\".",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Retornar ver si le duo entratas es equal.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Retornar ver si le duo entratas non es equal.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Retornar ver si le prime entrata es minor que le secunde.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Retornar ver si le prime entrata es minor que o equal al secunde.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Retornar ver si le prime entrata es major que le secunde.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Retornar ver si le prime entrata es major que o equal al secunde.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Retornar ver si ambe entratas es ver.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Retornar ver si al minus un del entratas es ver.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "non %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Retornar ver si le entrata es false. Retornar false si le entrata es ver.",
                +	"LOGIC_BOOLEAN_TRUE": "ver",
                +	"LOGIC_BOOLEAN_FALSE": "false",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Retorna o ver o false.",
                +	"LOGIC_NULL": "nulle",
                +	"LOGIC_NULL_TOOLTIP": "Retorna nulle.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "si ver",
                +	"LOGIC_TERNARY_IF_FALSE": "si false",
                +	"LOGIC_TERNARY_TOOLTIP": "Verificar le condition in 'test'. Si le condition es ver, retorna le valor de 'si ver'; si non, retorna le valor de 'si false'.",
                +	"MATH_NUMBER_HELPURL": "https://ia.wikipedia.org/wiki/Numero",
                +	"MATH_NUMBER_TOOLTIP": "Un numero.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ia.wikipedia.org/wiki/Arithmetica",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Retornar le summa del duo numeros.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Retornar le differentia del duo numeros.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Retornar le producto del duo numeros.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Retornar le quotiente del duo numeros.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Retornar le prime numero elevate al potentia del secunde numero.",
                +	"MATH_SINGLE_HELPURL": "https://ia.wikipedia.org/wiki/Radice_quadrate",
                +	"MATH_SINGLE_OP_ROOT": "radice quadrate",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Retornar le radice quadrate de un numero.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolute",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Retornar le valor absolute de un numero.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Retornar le negation de un numero.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Retornar le logarithmo natural de un numero.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Retornar le logarithmo in base 10 del numero.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Retornar e elevate al potentia del numero.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Retornar 10 elevate al potentia de un numero.",
                +	"MATH_TRIG_TOOLTIP_SIN": "Retornar le sino de un grado (non radiano).",
                +	"MATH_TRIG_TOOLTIP_COS": "Retornar le cosino de un grado (non radiano).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Retornar le tangente de un grado (non radiano).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Retornar le arcosino de un numero.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Retornar le arcocosino de un numero.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Retornar le arcotangente de un numero.",
                +	"MATH_CONSTANT_TOOLTIP": "Retornar un del constantes commun: π (3,141…), e (2,718…), φ (1,618…), sqrt(2) (1,414…), sqrt(½) (0,707…) o ∞ (infinite).",
                +	"MATH_IS_EVEN": "es par",
                +	"MATH_IS_ODD": "es impare",
                +	"MATH_IS_PRIME": "es prime",
                +	"MATH_IS_WHOLE": "es integre",
                +	"MATH_IS_POSITIVE": "es positive",
                +	"MATH_IS_NEGATIVE": "es negative",
                +	"MATH_IS_DIVISIBLE_BY": "es divisibile per",
                +	"MATH_IS_TOOLTIP": "Verificar si un numero es par, impare, prime, integre, positive, negative, o divisibile per un certe numero. Retorna ver o false.",
                +	"MATH_CHANGE_TITLE": "cambiar %1 per %2",
                +	"MATH_CHANGE_TOOLTIP": "Adder un numero al variabile '%1'.",
                +	"MATH_ROUND_HELPURL": "https://ia.wikipedia.org/wiki/Rotundamento",
                +	"MATH_ROUND_TOOLTIP": "Arrotundar un numero a supra o a infra.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arrotundar",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arrotundar a supra",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arrotundar a infra",
                +	"MATH_ONLIST_OPERATOR_SUM": "summa del lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Retornar le summa de tote le numeros in le lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimo del lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Retornar le numero le plus parve in le lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maximo del lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Retornar le numero le plus grande in le lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "media del lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Retornar le media arithmetic del valores numeric in le lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana del lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Retornar le numero median del lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modas del lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Retornar un lista del elemento(s) le plus commun in le lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviation standard del lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Retornar le deviation standard del lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "elemento aleatori del lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Retornar un elemento aleatori del lista.",
                +	"MATH_MODULO_TITLE": "resto de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Retornar le resto del division del duo numeros.",
                +	"MATH_CONSTRAIN_TITLE": "limitar %1 inter %2 e %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Limitar un numero a esser inter le limites specificate (incluse).",
                +	"MATH_RANDOM_INT_TITLE": "numero integre aleatori inter %1 e %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Retornar un numero integre aleatori inter le duo limites specificate, incluse.",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fraction aleatori",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Retornar un fraction aleatori inter 0.0 (incluse) e 1.0 (excluse).",
                +	"TEXT_TEXT_TOOLTIP": "Un littera, parola o linea de texto.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "crear texto con",
                +	"TEXT_JOIN_TOOLTIP": "Crear un pecia de texto uniente un certe numero de elementos.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Adde, remove o reordina sectiones pro reconfigurar iste bloco de texto.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Adder un elemento al texto.",
                +	"TEXT_APPEND_TOOLTIP": "Adjunger un texto al variabile '%1'.",
                +	"TEXT_LENGTH_TITLE": "longitude de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Retorna le numero de litteras (incluse spatios) in le texto fornite.",
                +	"TEXT_ISEMPTY_TITLE": "%1 es vacue",
                +	"TEXT_ISEMPTY_TOOLTIP": "Retorna ver si le texto fornite es vacue.",
                +	"TEXT_INDEXOF_TOOLTIP": "Retorna le indice del prime/ultime occurrentia del prime texto in le secunde texto. Retorna %1 si le texto non es trovate.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "cercar le prime occurrentia del texto",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "cercar le ultime occurrentia del texto",
                +	"TEXT_CHARAT_FROM_START": "prender le littera №",
                +	"TEXT_CHARAT_FROM_END": "prender ab le fin le littera №",
                +	"TEXT_CHARAT_FIRST": "prender le prime littera",
                +	"TEXT_CHARAT_LAST": "prender le ultime littera",
                +	"TEXT_CHARAT_RANDOM": "prender un littera aleatori",
                +	"TEXT_CHARAT_TOOLTIP": "Retorna le littera presente al position specificate.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Retorna le parte specificate del texto.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in le texto",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "prender subcatena ab le littera №",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "prender subcatena ab le fin ab le littera №",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "prender subcatena ab le prime littera",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "usque al littera №",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "ab le fin usque al littera №",
                +	"TEXT_GET_SUBSTRING_END_LAST": "usque al ultime littera",
                +	"TEXT_CHANGECASE_TOOLTIP": "Retornar un copia del texto con differente majusculas/minusculas.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "in MAJUSCULAS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "in minusculas",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "con Initiales Majuscule",
                +	"TEXT_TRIM_TOOLTIP": "Retornar un copia del texto con spatios eliminate de un extremitate o ambes.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "remover spatios de ambe lateres de",
                +	"TEXT_TRIM_OPERATOR_LEFT": "remover spatios del sinistre latere de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "remover spatios del dextre latere de",
                +	"TEXT_PRINT_TITLE": "scriber %1",
                +	"TEXT_PRINT_TOOLTIP": "Scriber le texto, numero o altere valor specificate.",
                +	"TEXT_PROMPT_TYPE_TEXT": "peter un texto con le message",
                +	"TEXT_PROMPT_TYPE_NUMBER": "peter un numero con le message",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Peter un numero al usator.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Peter un texto al usator.",
                +	"LISTS_CREATE_EMPTY_TITLE": "crear un lista vacue",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Retorna un lista, de longitude 0, sin datos.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Crear un lista con un numero qualcunque de elementos.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "crear lista con",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Adde, remove o reordina sectiones pro reconfigurar iste bloco de listas.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Adder un elemento al lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Crea un lista que contine le valor fornite, repetite le numero specificate de vices.",
                +	"LISTS_REPEAT_TITLE": "crear lista con elemento %1 repetite %2 vices",
                +	"LISTS_LENGTH_TITLE": "longitude de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Retorna le longitude de un lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 es vacue",
                +	"LISTS_ISEMPTY_TOOLTIP": "Retorna ver si le lista es vacue.",
                +	"LISTS_INLIST": "in lista",
                +	"LISTS_INDEX_OF_FIRST": "cercar le prime occurrentia del elemento",
                +	"LISTS_INDEX_OF_LAST": "cercar le ultime occurrentia del elemento",
                +	"LISTS_INDEX_OF_TOOLTIP": "Retorna le indice del prime/ultime occurrentia del elemento in le lista. Retorna %1 si le elemento non es trovate.",
                +	"LISTS_GET_INDEX_GET": "prender",
                +	"LISTS_GET_INDEX_GET_REMOVE": "prender e remover",
                +	"LISTS_GET_INDEX_REMOVE": "remover",
                +	"LISTS_GET_INDEX_FROM_END": "№ ab fin",
                +	"LISTS_GET_INDEX_FIRST": "prime",
                +	"LISTS_GET_INDEX_LAST": "ultime",
                +	"LISTS_GET_INDEX_RANDOM": "aleatori",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "№ %1 es le prime elemento.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "№ %1 es le ultime elemento.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Retorna le elemento presente al position specificate in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Retorna le prime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Retorna le ultime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Retorna un elemento aleatori in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Remove e retorna le elemento presente al position specificate in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Remove e retorna le prime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Remove e retorna le ultime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Remove e retorna un elemento aleatori in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Remove le elemento presente al position specificate in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Remove le prime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Remove le ultime elemento in un lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Remove un elemento aleatori in un lista.",
                +	"LISTS_SET_INDEX_SET": "mitter",
                +	"LISTS_SET_INDEX_INSERT": "inserer in",
                +	"LISTS_SET_INDEX_INPUT_TO": "a",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Defini le valor del elemento al position specificate in un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Defini le valor del prime elemento in un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Defini le valor del ultime elemento in un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Defini le valor de un elemento aleatori in un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insere le elemento al position specificate in un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insere le elemento al initio de un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Adjunge le elemento al fin de un lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Insere le elemento a un position aleatori in un lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "prender sublista ab №",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "prender sublista ab le fin ab №",
                +	"LISTS_GET_SUBLIST_START_FIRST": "prender sublista ab initio",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "usque al №",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "usque al № ab fin",
                +	"LISTS_GET_SUBLIST_END_LAST": "usque al ultime",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Crea un copia del parte specificate de un lista.",
                +	"LISTS_SORT_TITLE": "ordinamento %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordinar un copia de un lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ascendente",
                +	"LISTS_SORT_ORDER_DESCENDING": "descendente",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeric",
                +	"LISTS_SORT_TYPE_TEXT": "alphabetic",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alphabetic, ignorar majuscula/minuscula",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "Crear un lista per un texto",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "crear un texto per un lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "con delimitator",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Divider texto in un lista de textos, separante lo a cata delimitator.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Unir un lista de textos, separate per un delimitator, in un sol texto.",
                +	"VARIABLES_GET_TOOLTIP": "Retorna le valor de iste variabile.",
                +	"VARIABLES_GET_CREATE_SET": "Crea 'mitter %1'",
                +	"VARIABLES_SET": "mitter %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Mitte iste variabile al valor del entrata.",
                +	"VARIABLES_SET_CREATE_GET": "Crear 'prender %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "pro",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "facer qualcosa",
                +	"PROCEDURES_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crea un function que non retorna un valor.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Describe iste function...",
                +	"PROCEDURES_DEFRETURN_RETURN": "retornar",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Crea un function que retorna un valor.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permitter declarationes",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Attention: Iste function ha parametros duplicate.",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Executar le function '%1' definite per le usator.",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Executar le function '%1' definite per le usator e usar su resultato.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entratas",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Adder, remover o reordinar le entratas pro iste function.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nomine del entrata:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Adder un entrata al function.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Accentuar le definition del function",
                +	"PROCEDURES_CREATE_DO": "Crear '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Si un valor es ver, alora retornar un secunde valor.",
                +	"PROCEDURES_IFRETURN_WARNING": "Attention: Iste bloco pote solmente esser usate in le definition de un function."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/id.json b/blockly/webif/static/blockly/msg/json/id.json
                new file mode 100644
                index 000000000..b4ca1d6e7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/id.json
                @@ -0,0 +1,331 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Kenrick95",
                +			"아라",
                +			"Mirws",
                +			"Marwan Mohamad",
                +			"Kasimtan",
                +			"Arifin.wijaya"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Hari ini",
                +	"DUPLICATE_BLOCK": "Duplikat",
                +	"ADD_COMMENT": "Tambahkan Komentar",
                +	"REMOVE_COMMENT": "Hapus Komentar",
                +	"EXTERNAL_INPUTS": "Input Eksternal",
                +	"INLINE_INPUTS": "Input Inline",
                +	"DELETE_BLOCK": "Hapus Blok",
                +	"DELETE_X_BLOCKS": "Hapus %1 Blok",
                +	"DELETE_ALL_BLOCKS": "Hapus semua %1 blok?",
                +	"CLEAN_UP": "Bersihkan Blok",
                +	"COLLAPSE_BLOCK": "Ciutkan Blok",
                +	"COLLAPSE_ALL": "Ciutkan Blok",
                +	"EXPAND_BLOCK": "Kembangkan Blok",
                +	"EXPAND_ALL": "Kembangkan Blok",
                +	"DISABLE_BLOCK": "Nonaktifkan Blok",
                +	"ENABLE_BLOCK": "Aktifkan Blok",
                +	"HELP": "Bantuan",
                +	"UNDO": "Urungkan",
                +	"REDO": "Lakukan ulang",
                +	"CHANGE_VALUE_TITLE": "Ubah nilai:",
                +	"RENAME_VARIABLE": "Ubah nama variabel...",
                +	"RENAME_VARIABLE_TITLE": "Ubah nama semua variabel '%1' menjadi:",
                +	"NEW_VARIABLE": "Buat variabel...",
                +	"NEW_VARIABLE_TITLE": "Nama variabel baru:",
                +	"VARIABLE_ALREADY_EXISTS": "Sebuah variabel dengan nama '%1' sudah ada.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Hapus %1 yang digunakan pada variabel '%2'?",
                +	"DELETE_VARIABLE": "Hapus variabel '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Pilih warna dari daftar warna.",
                +	"COLOUR_RANDOM_TITLE": "Warna acak",
                +	"COLOUR_RANDOM_TOOLTIP": "Pilih warna secara acak.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "Dengan warna",
                +	"COLOUR_RGB_RED": "merah",
                +	"COLOUR_RGB_GREEN": "hijau",
                +	"COLOUR_RGB_BLUE": "biru",
                +	"COLOUR_RGB_TOOLTIP": "Buatlah warna dengan jumlah yang ditentukan dari merah, hijau dan biru. Semua nilai harus antarai 0 sampai 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "campur",
                +	"COLOUR_BLEND_COLOUR1": "warna 1",
                +	"COLOUR_BLEND_COLOUR2": "warna 2",
                +	"COLOUR_BLEND_RATIO": "rasio",
                +	"COLOUR_BLEND_TOOLTIP": "Campur dua warna secara bersamaan dengan perbandingan (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "ulangi %1 kali",
                +	"CONTROLS_REPEAT_INPUT_DO": "kerjakan",
                +	"CONTROLS_REPEAT_TOOLTIP": "Lakukan beberapa perintah beberapa kali.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ulangi jika",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ulangi sampai",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Selagi nilainya benar, maka lakukan beberapa perintah.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Selagi nilainya salah, maka lakukan beberapa perintah.",
                +	"CONTROLS_FOR_TOOLTIP": "Menggunakan variabel \"%1\" dengan mengambil nilai dari batas awal hingga ke batas akhir, dengan interval tertentu, dan mengerjakan block tertentu.",
                +	"CONTROLS_FOR_TITLE": "Cacah dengan %1 dari %2 ke %3 dengan step / penambahan %4",
                +	"CONTROLS_FOREACH_TITLE": "untuk setiap item %1 di dalam list %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Untuk tiap-tiap item di dalam list, tetapkan variabel '%1' ke dalam item, selanjutnya kerjakan beberapa statement.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "keluar dari perulangan",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "lanjutkan dengan langkah perulangan berikutnya",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Keluar dari perulangan.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Abaikan sisa dari perulangan ini, dan lanjutkan dengan langkah berikutnya.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Peringatan: Blok ini hanya dapat digunakan dalam perulangan.",
                +	"CONTROLS_IF_TOOLTIP_1": "Jika nilainya benar, maka lakukan beberapa perintah.",
                +	"CONTROLS_IF_TOOLTIP_2": "Jika nilainya benar, maka kerjakan perintah blok pertama. Jika tidak, kerjakan perintah blok kedua.",
                +	"CONTROLS_IF_TOOLTIP_3": "Jika nilai pertama benar, maka kerjakan perintah blok pertama. Sebaliknya, jika nilai kedua benar, kerjakan perintah blok kedua.",
                +	"CONTROLS_IF_TOOLTIP_4": "Jika nilai pertama benar, maka kerjakan perintah blok pertama. Sebaliknya, jika nilai kedua benar, kerjakan perintah blok kedua. Jika dua-duanya tidak benar, kerjakan perintah blok terakhir.",
                +	"CONTROLS_IF_MSG_IF": "jika",
                +	"CONTROLS_IF_MSG_ELSEIF": "atau jika",
                +	"CONTROLS_IF_MSG_ELSE": "lainnya",
                +	"CONTROLS_IF_IF_TOOLTIP": "Tambahkan, hapus, atau susun kembali bagian untuk mengkonfigurasi blok IF ini.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Tambahkan prasyarat ke dalam blok IF.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Terakhir, tambahkan kondisi tangkap-semua kedalam blok IF.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Kembalikan benar jika kedua input sama satu dengan lainnya.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Kembalikan benar jika kedua input tidak sama satu dengan lainnya.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Kembalikan benar jika input pertama lebih kecil dari input kedua.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Kembalikan benar jika input pertama lebih kecil atau sama dengan input kedua .",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Kembalikan benar jika input pertama lebih besar dari input kedua.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Kembalikan benar jika input pertama lebih besar dari atau sama dengan input kedua.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Kembalikan benar jika kedua input adalah benar.",
                +	"LOGIC_OPERATION_AND": "dan",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Kembalikan benar jika minimal satu input nilainya benar.",
                +	"LOGIC_OPERATION_OR": "atau",
                +	"LOGIC_NEGATE_TITLE": "bukan (not) %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Kembalikan benar jika input salah. Kembalikan salah jika input benar.",
                +	"LOGIC_BOOLEAN_TRUE": "benar",
                +	"LOGIC_BOOLEAN_FALSE": "salah",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Kembalikan benar atau salah.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Kembalikan null.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "jika benar",
                +	"LOGIC_TERNARY_IF_FALSE": "jika salah",
                +	"LOGIC_TERNARY_TOOLTIP": "Periksa kondisi di 'test'. Jika kondisi benar, kembalikan nilai 'if true'; jika sebaliknya kembalikan nilai 'if false'.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Suatu angka.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://id.wikipedia.org/wiki/Aritmetika",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Kembalikan jumlah dari kedua angka.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Kembalikan selisih dari kedua angka.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Kembalikan perkalian dari kedua angka.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Kembalikan hasil bagi dari kedua angka.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Kembalikan angka pertama pangkat angka kedua.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "akar",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Kembalikan akar dari angka.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "mutlak",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Kembalikan nilai absolut angka.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Kembalikan penyangkalan terhadap angka.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Kembalikan logaritma natural dari angka.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Kembalikan dasar logaritma 10 dari angka.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Kembalikan 10 pangkat angka.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Kembalikan 10 pangkat angka.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Kembalikan sinus dari derajat (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Kembalikan cosinus dari derajat (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Kembalikan tangen dari derajat (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Kembalikan asin dari angka.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Kembalikan acosine dari angka.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Kembalikan atan dari angka.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Kembalikan salah satu konstanta: π (3,141…), e (2,718…), φ (1,618…), akar(2) (1,414…), akar(½) (0.707…), atau ∞ (tak terhingga).",
                +	"MATH_IS_EVEN": "adalah bilangan genap",
                +	"MATH_IS_ODD": "adalah bilangan ganjil",
                +	"MATH_IS_PRIME": "adalah bilangan pokok",
                +	"MATH_IS_WHOLE": "adalah bilangan bulat",
                +	"MATH_IS_POSITIVE": "adalah bilangan positif",
                +	"MATH_IS_NEGATIVE": "adalah bilangan negatif",
                +	"MATH_IS_DIVISIBLE_BY": "dapat dibagi oleh",
                +	"MATH_IS_TOOLTIP": "Periksa apakah angka adalah bilangan genap, bilangan ganjil, bilangan pokok, bilangan bulat, bilangan positif, bilangan negatif, atau apakan bisa dibagi oleh angka tertentu. Kembalikan benar atau salah.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "ubah %1 oleh %2",
                +	"MATH_CHANGE_TOOLTIP": "Tambahkan angka kedalam variabel '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Bulatkan suatu bilangan naik atau turun.",
                +	"MATH_ROUND_OPERATOR_ROUND": "membulatkan",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "membulatkan keatas",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "membulatkan kebawah",
                +	"MATH_ONLIST_OPERATOR_SUM": "jumlah dari list",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Kembalikan jumlah dari seluruh bilangan dari list.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimum dari list",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Kembalikan angka terkecil dari list.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maksimum dari list",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Kembalikan angka terbesar dari list.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "rata-rata dari list",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Kembalikan rata-rata (mean aritmetik) dari nilai numerik dari list.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "median dari list",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Kembalikan median dari list.",
                +	"MATH_ONLIST_OPERATOR_MODE": "mode-mode dari list",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Kembalikan list berisi item yang paling umum dari dalam list.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviasi standar dari list",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Kembalikan standard deviasi dari list.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "item acak dari list",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Kembalikan elemen acak dari list.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "sisa dari %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Kembalikan sisa dari pembagian ke dua angka.",
                +	"MATH_CONSTRAIN_TITLE": "Batasi %1 rendah %2 tinggi %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Batasi angka antara batas yang ditentukan (inklusif).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "acak bulat dari %1 sampai %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Kembalikan bilangan acak antara dua batas yang ditentukan, inklusif.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "nilai pecahan acak",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Kembalikan nilai pecahan acak antara 0.0 (inklusif) dan 1.0 (eksklusif).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Huruf, kata atau baris teks.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "buat teks dengan",
                +	"TEXT_JOIN_TOOLTIP": "Buat teks dengan cara gabungkan sejumlah item.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "join",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Tambah, ambil, atau susun ulang teks blok.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Tambahkan suatu item ke dalam teks.",
                +	"TEXT_APPEND_TOOLTIP": "Tambahkan beberapa teks ke variabel '%1'.",
                +	"TEXT_LENGTH_TITLE": "panjang dari %1",
                +	"TEXT_LENGTH_TOOLTIP": "Kembalikan sejumlah huruf (termasuk spasi) dari teks yang disediakan.",
                +	"TEXT_ISEMPTY_TITLE": "%1 kosong",
                +	"TEXT_ISEMPTY_TOOLTIP": "Kembalikan benar jika teks yang disediakan kosong.",
                +	"TEXT_INDEXOF_TOOLTIP": "Kembalikan indeks pertama dan terakhir dari kejadian pertama/terakhir dari teks pertama dalam teks kedua.  Kembalikan %1 jika teks tidak ditemukan.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "temukan kejadian pertama dalam teks",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "temukan kejadian terakhir dalam teks",
                +	"TEXT_CHARAT_FROM_START": "ambil huruf ke #",
                +	"TEXT_CHARAT_FROM_END": "ambil  huruf nomor # dari belakang",
                +	"TEXT_CHARAT_FIRST": "ambil  huruf pertama",
                +	"TEXT_CHARAT_LAST": "ambil  huruf terakhir",
                +	"TEXT_CHARAT_RANDOM": "ambil huruf secara acak",
                +	"TEXT_CHARAT_TOOLTIP": "Kembalikan karakter dari posisi tertentu.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Kembalikan spesifik bagian dari teks.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in teks",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "ambil bagian teks (substring) dari huruf no #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "ambil bagian teks (substring) dari huruf ke # dari terakhir",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "ambil bagian teks (substring) dari huruf pertama",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "pada huruf #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "pada huruf nomer # dari terakhir",
                +	"TEXT_GET_SUBSTRING_END_LAST": "pada huruf terakhir",
                +	"TEXT_CHANGECASE_TOOLTIP": "Kembalikan kopi dari text dengan kapitalisasi yang berbeda.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "menjadi huruf kapital",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "menjadi huruf kecil",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "menjadi huruf pertama kapital",
                +	"TEXT_TRIM_TOOLTIP": "Kembali salinan teks dengan spasi dihapus dari satu atau kedua ujungnya.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "pangkas ruang dari kedua belah sisi",
                +	"TEXT_TRIM_OPERATOR_LEFT": "pangkas ruang dari sisi kiri",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "pangkas ruang dari sisi kanan",
                +	"TEXT_PRINT_TITLE": "cetak %1",
                +	"TEXT_PRINT_TOOLTIP": "Cetak teks yant ditentukan, angka atau ninlai lainnya.",
                +	"TEXT_PROMPT_TYPE_TEXT": "meminta teks dengan pesan",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Meminta angka dengan pesan",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Meminta pengguna untuk memberi sebuah angka.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Meminta pengguna untuk memberi beberapa teks.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "buat list kosong",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Kembalikan list, dengan panjang 0, tidak berisi data",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Buat sebuah list dengan sejumlah item.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "buat list dengan",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "list",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Tambahkan, hapus, atau susun ulang bagian untuk mengkonfigurasi blok list ini.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Tambahkan sebuah item ke list.",
                +	"LISTS_REPEAT_TOOLTIP": "Buat sebuah list yang terdiri dari nilai yang diberikan diulang sebanyak jumlah yang ditentukan.",
                +	"LISTS_REPEAT_TITLE": "buat list dengan item %1 diulang %2 kali",
                +	"LISTS_LENGTH_TITLE": "panjang dari %1",
                +	"LISTS_LENGTH_TOOLTIP": "Kembalikan panjang list.",
                +	"LISTS_ISEMPTY_TITLE": "%1 kosong",
                +	"LISTS_ISEMPTY_TOOLTIP": "Kembalikan benar jika list kosong.",
                +	"LISTS_INLIST": "dalam list",
                +	"LISTS_INDEX_OF_FIRST": "cari kejadian pertama item",
                +	"LISTS_INDEX_OF_LAST": "cari kejadian terakhir item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Kembalikan indeks dari item pertama/terakhir kali muncul dalam list. Kembalikan %1 jika item tidak ditemukan.",
                +	"LISTS_GET_INDEX_GET": "dapatkan",
                +	"LISTS_GET_INDEX_GET_REMOVE": "dapatkan dan hapus",
                +	"LISTS_GET_INDEX_REMOVE": "Hapus",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# dari akhir",
                +	"LISTS_GET_INDEX_FIRST": "pertama",
                +	"LISTS_GET_INDEX_LAST": "terakhir",
                +	"LISTS_GET_INDEX_RANDOM": "acak",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 adalah item pertama.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 adalah item terakhir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Kembalikan item di posisi tertentu dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Kembalikan item pertama dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Kembalikan item terakhir dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Kembalikan item acak dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Hapus dan kembalikan item di posisi tertentu dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Hapus dan kembalikan item pertama dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Hapus dan kembalikan item terakhir dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Hapus dan kembalikan item acak dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Hapus item di posisi tertentu dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Hapus item pertama dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Hapus item terakhir dalam list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Hapus sebuah item acak dalam list.",
                +	"LISTS_SET_INDEX_SET": "tetapkan",
                +	"LISTS_SET_INDEX_INSERT": "sisipkan di",
                +	"LISTS_SET_INDEX_INPUT_TO": "sebagai",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Tetapkan item ke dalam posisi yang telah ditentukan di dalam list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Tetapkan item pertama di dalam list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Menetapkan item terakhir dalam list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Tetapkan secara acak sebuah item dalam list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Sisipkan item ke dalam posisi yang telah ditentukan di dalam list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Sisipkan item di bagian awal dari list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Tambahkan item ke bagian akhir list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Sisipkan item secara acak ke dalam list.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "dapatkan sub-list dari #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "dapatkan sub-list dari nomor # dari akhir",
                +	"LISTS_GET_SUBLIST_START_FIRST": "dapatkan sub-list dari pertama",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "ke #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ke # dari akhir",
                +	"LISTS_GET_SUBLIST_END_LAST": "ke yang paling akhir",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Buat salinan bagian tertentu dari list.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "urutkan %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Urutkan salinan dari daftar",
                +	"LISTS_SORT_ORDER_ASCENDING": "menaik",
                +	"LISTS_SORT_ORDER_DESCENDING": "menurun",
                +	"LISTS_SORT_TYPE_NUMERIC": "sesuai nomor",
                +	"LISTS_SORT_TYPE_TEXT": "sesuai abjad",
                +	"LISTS_SORT_TYPE_IGNORECASE": "sesuai abjad, abaikan kasus",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "buat list dari teks",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "buat teks dari list",
                +	"LISTS_SPLIT_WITH_DELIMITER": "dengan pembatas",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Membagi teks ke dalam daftar teks, pisahkan pada setiap pembatas.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Gabung daftar teks menjadi satu teks, yang dipisahkan oleh pembatas.",
                +	"VARIABLES_GET_TOOLTIP": "Kembalikan nilai variabel ini.",
                +	"VARIABLES_GET_CREATE_SET": "Buat 'set %1'",
                +	"VARIABLES_SET": "tetapkan %1 untuk %2",
                +	"VARIABLES_SET_TOOLTIP": "tetapkan variabel ini dengan input yang sama.",
                +	"VARIABLES_SET_CREATE_GET": "Buat 'get %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "untuk",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "buat sesuatu",
                +	"PROCEDURES_BEFORE_PARAMS": "dengan:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "dengan:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Buat sebuah fungsi tanpa output.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Jelaskan fungsi ini...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "kembali",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Buat sebuah fungsi dengan satu output.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "memungkinkan pernyataan",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Peringatan: Fungsi ini memiliki parameter duplikat.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Menjalankan fungsi '%1' yang ditetapkan pengguna.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Menjalankan fungsi  '%1' yang ditetapkan pengguna dan menggunakan outputnya.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "input",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Menambah, menghapus, atau menyusun ulang masukan untuk fungsi ini.",
                +	"PROCEDURES_MUTATORARG_TITLE": "masukan Nama:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Tambahkan masukan ke fungsi.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Sorot definisi fungsi",
                +	"PROCEDURES_CREATE_DO": "Buat '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Jika nilai yang benar, kemudian kembalikan nilai kedua.",
                +	"PROCEDURES_IFRETURN_WARNING": "Peringatan: Blok ini dapat digunakan hanya dalam definisi fungsi."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/is.json b/blockly/webif/static/blockly/msg/json/is.json
                new file mode 100644
                index 000000000..99617cf3d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/is.json
                @@ -0,0 +1,363 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Jonbg",
                +			"아라",
                +			"Gaddi00",
                +			"Sveinki",
                +			"Sveinn í Felli"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "atriði",
                +	"TODAY": "Í dag",
                +	"DUPLICATE_BLOCK": "Afrita",
                +	"ADD_COMMENT": "Skrifa skýringu",
                +	"REMOVE_COMMENT": "Fjarlægja skýringu",
                +	"EXTERNAL_INPUTS": "Ytri inntök",
                +	"INLINE_INPUTS": "Innri inntök",
                +	"DELETE_BLOCK": "Eyða kubbi",
                +	"DELETE_X_BLOCKS": "Eyða %1 kubbum",
                +	"DELETE_ALL_BLOCKS": "Eyða öllum %1 kubbunum?",
                +	"CLEAN_UP": "Hreinsa kubba",
                +	"COLLAPSE_BLOCK": "Loka kubbi",
                +	"COLLAPSE_ALL": "Loka kubbum",
                +	"EXPAND_BLOCK": "Opna kubb",
                +	"EXPAND_ALL": "Opna kubba",
                +	"DISABLE_BLOCK": "Óvirkja kubb",
                +	"ENABLE_BLOCK": "Virkja kubb",
                +	"HELP": "Hjálp",
                +	"UNDO": "Afturkalla",
                +	"REDO": "Endurtaka",
                +	"CHANGE_VALUE_TITLE": "Breyta gildi:",
                +	"RENAME_VARIABLE": "Endurnefna breytu...",
                +	"RENAME_VARIABLE_TITLE": "Endurnefna allar '%1' breyturnar:",
                +	"NEW_VARIABLE": "Ný breyta...",
                +	"NEW_VARIABLE_TITLE": "Heiti nýrrar breytu:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Velja lit úr litakorti.",
                +	"COLOUR_RANDOM_TITLE": "einhver litur",
                +	"COLOUR_RANDOM_TOOLTIP": "Velja einhvern lit af handahófi.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "litur",
                +	"COLOUR_RGB_RED": "rauður",
                +	"COLOUR_RGB_GREEN": "grænt",
                +	"COLOUR_RGB_BLUE": "blátt",
                +	"COLOUR_RGB_TOOLTIP": "Búa til lit úr tilteknu magni af rauðu, grænu og bláu. Allar tölurnar verða að vera á bilinu 0 til 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "blöndun",
                +	"COLOUR_BLEND_COLOUR1": "litur 1",
                +	"COLOUR_BLEND_COLOUR2": "litur 2",
                +	"COLOUR_BLEND_RATIO": "hlutfall",
                +	"COLOUR_BLEND_TOOLTIP": "Blandar tveimur litum í gefnu hlutfalli (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "endurtaka %1 sinnum",
                +	"CONTROLS_REPEAT_INPUT_DO": "gera",
                +	"CONTROLS_REPEAT_TOOLTIP": "Gera eitthvað aftur og aftur.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://github.com/google/blockly/wiki/Loops#repeat",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "endurtaka á meðan",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "endurtaka þar til",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Endurtaka eitthvað á meðan gildi er satt.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Endurtaka eitthvað á meðan gildi er ósatt.",
                +	"CONTROLS_FOR_HELPURL": "https://github.com/google/blockly/wiki/Loops#count-with",
                +	"CONTROLS_FOR_TOOLTIP": "Láta breytuna '%1' taka inn gildi frá fyrstu tölu til síðustu tölu, hlaupandi á tiltekna bilinu og gera tilteknu kubbana.",
                +	"CONTROLS_FOR_TITLE": "telja með %1 frá %2 til %3 um %4",
                +	"CONTROLS_FOREACH_TITLE": "fyrir hvert %1 í lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Fyrir hvert atriði í lista er breyta '%1' stillt á atriðið og skipanir gerðar.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "fara út úr lykkju",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "fara beint í næstu umferð lykkjunnar",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Fara út úr umlykjandi lykkju.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sleppa afganginum af lykkjunni og fara beint í næstu umferð hennar.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Aðvörun: Þennan kubb má aðeins nota innan lykkju.",
                +	"CONTROLS_IF_HELPURL": "https://github.com/google/blockly/wiki/IfElse",
                +	"CONTROLS_IF_TOOLTIP_1": "Ef gildi er satt skal gera einhverjar skipanir.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ef gildi er satt skal gera skipanir í fyrri kubbnum. Annars skal gera skipanir í seinni kubbnum.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ef fyrra gildið er satt skal gera skipanir í fyrri kubbnum. Annars, ef seinna gildið er satt, þá skal gera skipanir í seinni kubbnum.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ef fyrra gildið er satt skal gera skipanir í fyrri kubbnum. Annars, ef seinna gildið er satt, skal gera skipanir í seinni kubbnum. Ef hvorugt gildið er satt, skal gera skipanir í síðasta kubbnum.",
                +	"CONTROLS_IF_MSG_IF": "ef",
                +	"CONTROLS_IF_MSG_ELSEIF": "annars ef",
                +	"CONTROLS_IF_MSG_ELSE": "annars",
                +	"CONTROLS_IF_IF_TOOLTIP": "Bæta við, fjarlægja eða umraða til að breyta skipan þessa EF kubbs.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Bæta skilyrði við EF kubbinn.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Bæta við hluta EF kubbs sem grípur öll tilfelli sem uppfylla ekki hin skilyrðin.",
                +	"IOS_OK": "Í lagi",
                +	"IOS_CANCEL": "Hætta við",
                +	"IOS_ERROR": "Villa",
                +	"IOS_VARIABLES_ADD_BUTTON": "Bæta við",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Endurnefna",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Eyða",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nafn breytu",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Skila sönnu ef inntökin eru jöfn.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Skila sönnu ef inntökin eru ekki jöfn.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Skila sönnu ef fyrra inntakið er minna en seinna inntakið.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Skila sönnu ef fyrra inntakið er minna en eða jafnt og seinna inntakið.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Skila sönnu ef fyrra inntakið er stærra en seinna inntakið.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Skila sönnu ef fyrra inntakið er stærra en eða jafnt og seinna inntakið.",
                +	"LOGIC_OPERATION_HELPURL": "https://github.com/google/blockly/wiki/Logic#logical-operations",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Skila sönnu ef bæði inntökin eru sönn.",
                +	"LOGIC_OPERATION_AND": "og",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Skila sönnu ef að minnsta kosti eitt inntak er satt.",
                +	"LOGIC_OPERATION_OR": "eða",
                +	"LOGIC_NEGATE_HELPURL": "https://github.com/google/blockly/wiki/Logic#not",
                +	"LOGIC_NEGATE_TITLE": "ekki %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Skilar sönnu ef inntakið er ósatt. Skilar ósönnu ef inntakið er satt.",
                +	"LOGIC_BOOLEAN_HELPURL": "https://github.com/google/blockly/wiki/Logic#values",
                +	"LOGIC_BOOLEAN_TRUE": "satt",
                +	"LOGIC_BOOLEAN_FALSE": "ósatt",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Skilar annað hvort sönnu eða ósönnu.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "tómagildi",
                +	"LOGIC_NULL_TOOLTIP": "Skilar tómagildi.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "prófun",
                +	"LOGIC_TERNARY_IF_TRUE": "ef satt",
                +	"LOGIC_TERNARY_IF_FALSE": "ef ósatt",
                +	"LOGIC_TERNARY_TOOLTIP": "Kanna skilyrðið í 'prófun'. Skilar 'ef satt' gildinu ef skilyrðið er satt, en skilar annars 'ef ósatt' gildinu.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Tala.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Skila summu talnanna tveggja.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Skila mismun talnanna.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Skila margfeldi talnanna.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Skila deilingu talnanna.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Skila fyrri tölunni í veldinu seinni talan.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "kvaðratrót",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Skila kvaðratrót tölu.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "algildi",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Skila algildi tölu.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Skila neitun tölu (tölunni með öfugu formerki).",
                +	"MATH_SINGLE_TOOLTIP_LN": "Skila náttúrlegum lógaritma tölu.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Skila tugalógaritma tölu.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Skila e í veldi tölu.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Skila 10 í veldi tölu.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Skila sínusi horns gefnu í gráðum.",
                +	"MATH_TRIG_TOOLTIP_COS": "Skila kósínusi horns gefnu í gráðum.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Skila tangensi horns gefnu í gráðum.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Skila arkarsínusi tölu.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Skila arkarkósínusi tölu.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Skila arkartangensi tölu.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Skila algengum fasta: π (3.141…), e (2.718…), φ (1.618…), kvrót(2) (1.414…), kvrót(½) (0.707…) eða ∞ (óendanleika).",
                +	"MATH_IS_EVEN": "er\\u00A0jöfn tala",
                +	"MATH_IS_ODD": "er oddatala",
                +	"MATH_IS_PRIME": "er prímtala",
                +	"MATH_IS_WHOLE": "er heiltala",
                +	"MATH_IS_POSITIVE": "er jákvæð",
                +	"MATH_IS_NEGATIVE": "er neikvæð",
                +	"MATH_IS_DIVISIBLE_BY": "er\\u00A0deilanleg með",
                +	"MATH_IS_TOOLTIP": "Kanna hvort tala sé jöfn tala, oddatala, jákvæð, neikvæð eða deilanleg með tiltekinni tölu. Skilar sönnu eða ósönnu.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "breyta %1 um %2",
                +	"MATH_CHANGE_TOOLTIP": "Bæta tölu við breytu '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Námunda tölu upp eða niður.",
                +	"MATH_ROUND_OPERATOR_ROUND": "námunda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "námunda upp",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "námunda niður",
                +	"MATH_ONLIST_OPERATOR_SUM": "summa lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Skila summu allra talna í listanum.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minnst í lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Skila minnstu tölu í listanum.",
                +	"MATH_ONLIST_OPERATOR_MAX": "stærst í lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Skila stærstu tölu í listanum.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "meðaltal lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Skila meðaltali talna í listanum.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "miðgildi lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Skila miðgildi listans.",
                +	"MATH_ONLIST_OPERATOR_MODE": "tíðast í lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Skila lista yfir tíðustu gildin í listanum.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "staðalfrávik lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Skila staðalfráviki lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "eitthvað úr lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Skila einhverju atriði úr listanum.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "afgangur af %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Skila afgangi deilingar með tölunum.",
                +	"MATH_CONSTRAIN_TITLE": "þröngva %1 lægst %2 hæst %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Þröngva tölu til að vera innan hinna tilgreindu marka (að báðum meðtöldum).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "slembitala frá %1 til %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Skila heiltölu sem valin er af handahófi og er innan tilgreindra marka, að báðum meðtöldum.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "slembibrot",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Skila broti sem er valið af handahófi úr tölum á bilinu frá og með 0.0 til (en ekki með) 1.0.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Stafur, orð eða textalína.",
                +	"TEXT_JOIN_HELPURL": "https://github.com/google/blockly/wiki/Text#text-creation",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "búa til texta með",
                +	"TEXT_JOIN_TOOLTIP": "Búa til texta með því að tengja saman einhvern fjölda atriða.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "tengja",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Bæta við, fjarlægja eða umraða hlutum til að breyta skipan þessa textakubbs.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Bæta atriði við textann.",
                +	"TEXT_APPEND_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_APPEND_TOOLTIP": "Bæta texta við breytuna '%1'.",
                +	"TEXT_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_LENGTH_TITLE": "lengd %1",
                +	"TEXT_LENGTH_TOOLTIP": "Skilar fjölda stafa (með bilum) í gefna textanum.",
                +	"TEXT_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Text#checking-for-empty-text",
                +	"TEXT_ISEMPTY_TITLE": "%1 er tómur",
                +	"TEXT_ISEMPTY_TOOLTIP": "Skilar sönnu ef gefni textinn er tómur.",
                +	"TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text",
                +	"TEXT_INDEXOF_TOOLTIP": "Finnur fyrsta/síðasta tilfelli fyrri textans í seinni textanum og skilar sæti hans. Skilar %1 ef textinn finnst ekki.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "finna fyrsta tilfelli texta",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "finna síðasta tilfelli texta",
                +	"TEXT_CHARAT_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-text",
                +	"TEXT_CHARAT_FROM_START": "sækja staf #",
                +	"TEXT_CHARAT_FROM_END": "sækja staf # frá enda",
                +	"TEXT_CHARAT_FIRST": "sækja fyrsta staf",
                +	"TEXT_CHARAT_LAST": "sækja síðasta staf",
                +	"TEXT_CHARAT_RANDOM": "sækja einhvern staf",
                +	"TEXT_CHARAT_TOOLTIP": "Skila staf á tilteknum stað.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Skilar tilteknum hluta textans.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "í texta",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "sækja textabút frá staf #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "sækja textabút frá staf # frá enda",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "sækja textabút frá fyrsta staf",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "að staf #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "að staf # frá enda",
                +	"TEXT_GET_SUBSTRING_END_LAST": "að síðasta staf",
                +	"TEXT_CHANGECASE_HELPURL": "https://github.com/google/blockly/wiki/Text#adjusting-text-case",
                +	"TEXT_CHANGECASE_TOOLTIP": "Skila afriti af textanum með annarri stafastöðu.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "í HÁSTAFI",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "í lágstafi",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "í Upphafstafi",
                +	"TEXT_TRIM_HELPURL": "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces",
                +	"TEXT_TRIM_TOOLTIP": "Skila afriti af textanum þar sem möguleg bil við báða enda hafa verið fjarlægð.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "eyða bilum báðum megin við",
                +	"TEXT_TRIM_OPERATOR_LEFT": "eyða bilum vinstra megin við",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "eyða bilum hægra megin við",
                +	"TEXT_PRINT_HELPURL": "https://github.com/google/blockly/wiki/Text#printing-text",
                +	"TEXT_PRINT_TITLE": "prenta %1",
                +	"TEXT_PRINT_TOOLTIP": "Prenta tiltekinn texta, tölu eða annað gildi.",
                +	"TEXT_PROMPT_HELPURL": "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user",
                +	"TEXT_PROMPT_TYPE_TEXT": "biðja um texta með skilaboðum",
                +	"TEXT_PROMPT_TYPE_NUMBER": "biðja um tölu með skilaboðum",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Biðja notandann um tölu.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Biðja notandann um texta.",
                +	"TEXT_REPLACE_MESSAGE0": "skipta %1 út með %2 í %3",
                +	"TEXT_REVERSE_MESSAGE0": "snúa við %1",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "búa til tóman lista",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Skilar lista með lengdina 0 án gagna",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Búa til lista með einhverjum fjölda atriða.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "búa til lista með",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "listi",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Bæta við, fjarlægja eða umraða hlutum til að breyta skipan þessa listakubbs.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Bæta atriði við listann.",
                +	"LISTS_REPEAT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_REPEAT_TOOLTIP": "Býr til lista sem inniheldur tiltekna gildið endurtekið tiltekið oft.",
                +	"LISTS_REPEAT_TITLE": "búa til lista með atriði %1 endurtekið %2 sinnum",
                +	"LISTS_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Lists#length-of",
                +	"LISTS_LENGTH_TITLE": "lengd %1",
                +	"LISTS_LENGTH_TOOLTIP": "Skilar lengd lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 er tómur",
                +	"LISTS_ISEMPTY_TOOLTIP": "Skilar sönnu ef listinn er tómur.",
                +	"LISTS_INLIST": "í lista",
                +	"LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list",
                +	"LISTS_INDEX_OF_FIRST": "finna fyrsta tilfelli atriðis",
                +	"LISTS_INDEX_OF_LAST": "finna síðasta tilfelli atriðis",
                +	"LISTS_INDEX_OF_TOOLTIP": "Finnur hvar atriðið kemur fyrir fyrst/síðast í listanum og skilar sæti þess. Skilar %1 ef atriðið finnst ekki.",
                +	"LISTS_GET_INDEX_GET": "sækja",
                +	"LISTS_GET_INDEX_GET_REMOVE": "sækja og fjarlægja",
                +	"LISTS_GET_INDEX_REMOVE": "fjarlægja",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# frá enda",
                +	"LISTS_GET_INDEX_FIRST": "fyrsta",
                +	"LISTS_GET_INDEX_LAST": "síðasta",
                +	"LISTS_GET_INDEX_RANDOM": "eitthvert",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 er fyrsta atriðið.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 er síðasta atriðið.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Skilar atriðinu í hinum tiltekna stað í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Skilar fyrsta atriði í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Skilar síðasta atriði í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Skilar einhverju atriði úr lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Fjarlægir og skilar atriðinu á hinum tiltekna stað í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Fjarlægir og skilar fyrsta atriðinu í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Fjarlægir og skilar síðasta atriðinu í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Fjarlægir og skilar einhverju atriði úr lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Fjarlægir atriðið á hinum tiltekna stað í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Fjarlægir fyrsta atriðið í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Fjarlægir síðasta atriðið í lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Fjarlægir eitthvert atriði úr lista.",
                +	"LISTS_SET_INDEX_HELPURL": "https://github.com/google/blockly/wiki/Lists#in-list--set",
                +	"LISTS_SET_INDEX_SET": "setja í",
                +	"LISTS_SET_INDEX_INSERT": "bæta við",
                +	"LISTS_SET_INDEX_INPUT_TO": "sem",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Setur atriðið í tiltekna sætið í listanum.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Setur atriðið í fyrsta sæti lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Setur atriðið í síðasta sæti lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Setur atriðið í eitthvert sæti lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Bætir atriðinu í listann á tilteknum stað.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Bætir atriðinu fremst í listann.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Bætir atriðinu aftan við listann.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Bætir atriðinu einhversstaðar við listann.",
                +	"LISTS_GET_SUBLIST_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-a-sublist",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "sækja undirlista frá #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "sækja undirlista frá # frá enda",
                +	"LISTS_GET_SUBLIST_START_FIRST": "sækja undirlista frá fyrsta",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "til #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "til # frá enda",
                +	"LISTS_GET_SUBLIST_END_LAST": "til síðasta",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Býr til afrit af tilteknum hluta lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "raða %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Raða afriti lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "hækkandi",
                +	"LISTS_SORT_ORDER_DESCENDING": "lækkandi",
                +	"LISTS_SORT_TYPE_NUMERIC": "í númeraröð",
                +	"LISTS_SORT_TYPE_TEXT": "í stafrófsröð",
                +	"LISTS_SORT_TYPE_IGNORECASE": "í stafrófsröð án tillits til stafstöðu",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "gera lista úr texta",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "gera texta úr lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "með skiltákni",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Skiptir texta í lista af textum, með skil við hvert skiltákn.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Sameinar lista af textum í einn texta, með skiltákn á milli.",
                +	"LISTS_REVERSE_MESSAGE0": "snúa við %1",
                +	"VARIABLES_GET_HELPURL": "https://github.com/google/blockly/wiki/Variables#get",
                +	"VARIABLES_GET_TOOLTIP": "Skilar gildi þessarar breytu.",
                +	"VARIABLES_GET_CREATE_SET": "Búa til 'stilla %1'",
                +	"VARIABLES_SET_HELPURL": "https://github.com/google/blockly/wiki/Variables#set",
                +	"VARIABLES_SET": "stilla %1 á %2",
                +	"VARIABLES_SET_TOOLTIP": "Stillir þessa breytu á innihald inntaksins.",
                +	"VARIABLES_SET_CREATE_GET": "Búa til 'sækja %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "til að",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "gera eitthvað",
                +	"PROCEDURES_BEFORE_PARAMS": "með:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "með:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Býr til fall sem skilar engu.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Lýstu þessari aðgerð/falli...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "skila",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Býr til fall sem skilar úttaki.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "leyfa setningar",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Aðvörun: Þetta fall er með tvítekna stika.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Keyra heimatilbúna fallið '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Keyra heimatilbúna fallið '%1' og nota úttak þess.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inntök",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Bæta við, fjarlægja eða umraða inntökum fyrir þetta fall.",
                +	"PROCEDURES_MUTATORARG_TITLE": "heiti inntaks:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Bæta inntaki við fallið.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Sýna skilgreiningu falls",
                +	"PROCEDURES_CREATE_DO": "Búa til '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ef gildi er satt, skal skila öðru gildi.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Aðvörun: Þennan kubb má aðeins nota í skilgreiningu falls."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/it.json b/blockly/webif/static/blockly/msg/json/it.json
                new file mode 100644
                index 000000000..90bf54f51
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/it.json
                @@ -0,0 +1,346 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Beta16",
                +			"Espertus",
                +			"Nerimic",
                +			"Gbonanome",
                +			"Gianfranco",
                +			"Federico Mugnaini",
                +			"JackLantern",
                +			"Selven",
                +			"Samuele2002",
                +			"Greis"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "elemento",
                +	"TODAY": "Oggi",
                +	"DUPLICATE_BLOCK": "Duplica",
                +	"ADD_COMMENT": "Aggiungi commento",
                +	"REMOVE_COMMENT": "Rimuovi commento",
                +	"EXTERNAL_INPUTS": "Ingressi esterni",
                +	"INLINE_INPUTS": "Ingressi in linea",
                +	"DELETE_BLOCK": "Cancella blocco",
                +	"DELETE_X_BLOCKS": "Cancella %1 blocchi",
                +	"DELETE_ALL_BLOCKS": "Cancellare tutti i %1 blocchi?",
                +	"CLEAN_UP": "Pulisci i blocchi",
                +	"COLLAPSE_BLOCK": "Comprimi blocco",
                +	"COLLAPSE_ALL": "Comprimi blocchi",
                +	"EXPAND_BLOCK": "Espandi blocco",
                +	"EXPAND_ALL": "Espandi blocchi",
                +	"DISABLE_BLOCK": "Disattiva blocco",
                +	"ENABLE_BLOCK": "Attiva blocco",
                +	"HELP": "Aiuto",
                +	"UNDO": "Annulla",
                +	"REDO": "Ripeti",
                +	"CHANGE_VALUE_TITLE": "Modifica valore:",
                +	"RENAME_VARIABLE": "Rinomina variabile...",
                +	"RENAME_VARIABLE_TITLE": "Rinomina tutte le variabili '%1' in:",
                +	"NEW_VARIABLE": "Crea variabile...",
                +	"NEW_VARIABLE_TITLE": "Nome della nuova variabile:",
                +	"VARIABLE_ALREADY_EXISTS": "Una variabile denominata '%1' esiste già.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Una variabile nominata \"%1\" esiste già per un'altra variabile del tipo \"%2\".",
                +	"PROCEDURE_ALREADY_EXISTS": "Una procedura denominata '%1' esiste già.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Cancella %1 usi della variabile '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Non si può cancellare la variabile '%1' perché è parte della definizione della funzione '%2'",
                +	"DELETE_VARIABLE": "Cancella la variabile '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://it.wikipedia.org/wiki/Colore",
                +	"COLOUR_PICKER_TOOLTIP": "Scegli un colore dalla tavolozza.",
                +	"COLOUR_RANDOM_TITLE": "colore casuale",
                +	"COLOUR_RANDOM_TOOLTIP": "Scegli un colore a caso.",
                +	"COLOUR_RGB_TITLE": "colora con",
                +	"COLOUR_RGB_RED": "rosso",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "blu",
                +	"COLOUR_RGB_TOOLTIP": "Crea un colore con la quantità specificata di rosso, verde e blu. Tutti i valori devono essere compresi tra 0 e 100.",
                +	"COLOUR_BLEND_TITLE": "miscela",
                +	"COLOUR_BLEND_COLOUR1": "colore 1",
                +	"COLOUR_BLEND_COLOUR2": "colore 2",
                +	"COLOUR_BLEND_RATIO": "rapporto",
                +	"COLOUR_BLEND_TOOLTIP": "Mescola due colori insieme con un determinato rapporto (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://it.wikipedia.org/wiki/Ciclo_for",
                +	"CONTROLS_REPEAT_TITLE": "ripeti %1 volte",
                +	"CONTROLS_REPEAT_INPUT_DO": "fai",
                +	"CONTROLS_REPEAT_TOOLTIP": "Esegue alcune istruzione diverse volte.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ripeti mentre",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ripeti fino a che",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Finché un valore è vero, esegue alcune istruzioni.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Finché un valore è falso, esegue alcune istruzioni.",
                +	"CONTROLS_FOR_TOOLTIP": "Fa sì che la variabile '%1' prenda tutti i valori a partire dal numero di partenza fino a quello di arrivo, con passo pari all'intervallo specificato, ed esegue il blocco indicato.",
                +	"CONTROLS_FOR_TITLE": "conta con %1 da %2 a %3 per %4",
                +	"CONTROLS_FOREACH_TITLE": "per ogni elemento %1 nella lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Per ogni elemento in una lista, imposta la variabile '%1'  pari all'elemento e quindi esegue alcune istruzioni.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "esce dal ciclo",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "prosegui con la successiva iterazione del ciclo",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Esce dal ciclo.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Salta il resto di questo ciclo e prosegue con la successiva iterazione.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Attenzioneː Questo blocco può essere usato solo in un ciclo.",
                +	"CONTROLS_IF_TOOLTIP_1": "Se un valore è vero allora esegue alcune istruzioni.",
                +	"CONTROLS_IF_TOOLTIP_2": "Se un valore è vero allora esegue il primo blocco di istruzioni. Altrimenti esegue il secondo blocco di istruzioni.",
                +	"CONTROLS_IF_TOOLTIP_3": "Se il primo valore è vero allora esegue un primo blocco di istruzioni. Altrimenti, se il secondo valore è vero, esegue un secondo blocco di istruzioni.",
                +	"CONTROLS_IF_TOOLTIP_4": "Se il primo valore è vero allora esegue un primo blocco di istruzioni. Altrimenti, se il secondo valore è vero, esegue un secondo blocco di istruzioni. Se nessuno dei valori è vero esegue l'ultimo blocco di istruzioni.",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "altrimenti se",
                +	"CONTROLS_IF_MSG_ELSE": "altrimenti",
                +	"CONTROLS_IF_IF_TOOLTIP": "Aggiungi, elimina o riordina le sezioni per riconfigurare questo blocco se.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Aggiungi una condizione al blocco se.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Aggiungi una condizione finale pigliatutto al blocco se.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Annulla",
                +	"IOS_ERROR": "Errore",
                +	"IOS_PROCEDURES_INPUTS": "INPUTS",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Aggiungi input",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Consenti dichiarazioni",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Questa funzione ha entrate duplicate.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Aggiungi variabile",
                +	"IOS_VARIABLES_ADD_BUTTON": "Aggiungi",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Rinomina",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Cancella",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nome variabile",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Non puoi utilizzare un nome di variabile vuoto.",
                +	"LOGIC_COMPARE_HELPURL": "https://it.wikipedia.org/wiki/Disuguaglianza",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Restituisce vero se gli input sono uno uguale all'altro.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Restituisce vero se gli input non sono uno uguale all'altro.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Restituisce vero se il primo input è minore del secondo.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Restituisce vero se il primo input è minore o uguale al secondo.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Restituisce vero se il primo input è maggiore o uguale al secondo.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Restituisce uguale se il primo input è maggiore o uguale al secondo input.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Restituisce vero se entrambi gli input sono veri.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Restituisce vero se almeno uno degli input è vero.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "non %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Restituisce vero se l'input è falso. Restituisce falso se l'input è vero.",
                +	"LOGIC_BOOLEAN_TRUE": "vero",
                +	"LOGIC_BOOLEAN_FALSE": "falso",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Restituisce vero o falso.",
                +	"LOGIC_NULL": "nullo",
                +	"LOGIC_NULL_TOOLTIP": "Restituisce valore nullo.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "se vero",
                +	"LOGIC_TERNARY_IF_FALSE": "se falso",
                +	"LOGIC_TERNARY_TOOLTIP": "Verifica la condizione in 'test'. Se questa è vera restituisce il valore 'se vero' altrimenti restituisce il valore 'se falso'.",
                +	"MATH_NUMBER_HELPURL": "https://it.wikipedia.org/wiki/Numero",
                +	"MATH_NUMBER_TOOLTIP": "Un numero.",
                +	"MATH_ARITHMETIC_HELPURL": "https://it.wikipedia.org/wiki/Aritmetica",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Restituisce la somma dei due numeri.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Restituisce la differenza dei due numeri.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Restituisce il prodotto dei due numeri.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Restituisce il quoziente dei due numeri.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Restituisce il primo numero elevato alla potenza del secondo numero.",
                +	"MATH_SINGLE_HELPURL": "https://it.wikipedia.org/wiki/Radice_quadrata",
                +	"MATH_SINGLE_OP_ROOT": "radice quadrata",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Restituisce la radice quadrata del numero.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "assoluto",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Restituisce il valore assoluto del numero.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Restituisce l'opposto del numero.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Restituisce il logaritmo naturale del numero.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Restituisce il logaritmo in base 10 del numero.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Restituisce e elevato alla potenza del numero.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Restituisce 10 elevato alla potenza del numero.",
                +	"MATH_TRIG_HELPURL": "https://it.wikipedia.org/wiki/Funzione_trigonometrica",
                +	"MATH_TRIG_TOOLTIP_SIN": "Restituisce il seno di un angolo espresso in gradi (non radianti).",
                +	"MATH_TRIG_TOOLTIP_COS": "Restituisce il coseno di un angolo espresso in gradi (non radianti).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Restituisce la tangente di un angolo espresso in gradi (non radianti).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Restituisce l'arco-seno di un numero.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Restituisce l'arco-coseno di un numero.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Restituisce l'arco-tangente di un numero.",
                +	"MATH_CONSTANT_HELPURL": "https://it.wikipedia.org/wiki/Costante_matematica",
                +	"MATH_CONSTANT_TOOLTIP": "Restituisce una delle costanti comuniː π (3.141…), e (2.718…), φ (1.618…), radq(2) (1.414…), radq(½) (0.707…) o ∞ (infinito).",
                +	"MATH_IS_EVEN": "è pari",
                +	"MATH_IS_ODD": "è dispari",
                +	"MATH_IS_PRIME": "è primo",
                +	"MATH_IS_WHOLE": "è intero",
                +	"MATH_IS_POSITIVE": "è positivo",
                +	"MATH_IS_NEGATIVE": "è negativo",
                +	"MATH_IS_DIVISIBLE_BY": "è divisibile per",
                +	"MATH_IS_TOOLTIP": "Verifica se un numero è pari, dispari, primo, intero, positivo, negativo o se è divisibile per un certo numero. Restituisce vero o falso.",
                +	"MATH_CHANGE_HELPURL": "https://it.wikipedia.org/wiki/Addizione",
                +	"MATH_CHANGE_TITLE": "cambia %1 di %2",
                +	"MATH_CHANGE_TOOLTIP": "Aggiunge un numero alla variabile '%1'.",
                +	"MATH_ROUND_HELPURL": "https://it.wikipedia.org/wiki/Arrotondamento",
                +	"MATH_ROUND_TOOLTIP": "Arrotonda un numero verso l'alto o verso il basso.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arrotonda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arrotonda verso l'alto",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arrotonda verso il basso",
                +	"MATH_ONLIST_OPERATOR_SUM": "somma la lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Restituisce la somma si tutti i numeri nella lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimo della lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Restituisce il più piccolo numero della lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "massimo della lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Restituisce il più grande numero della lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "media della lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Restituisce la media (media aritmetica) dei valori numerici nella lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana della lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Restituisce il valore mediano della lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "mode della lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Restituisce una lista degli elementi più frequenti nella lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviazione standard della lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Restituisce la deviazione standard della lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "elemento casuale della lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Restituisce un elemento casuale della lista.",
                +	"MATH_MODULO_HELPURL": "https://it.wikipedia.org/wiki/Resto",
                +	"MATH_MODULO_TITLE": "resto di %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Restituisce il resto della divisione di due numeri.",
                +	"MATH_CONSTRAIN_TITLE": "costringi %1 da %2 a %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Costringe un numero all'interno dei limiti indicati (compresi).",
                +	"MATH_RANDOM_INT_HELPURL": "https://it.wikipedia.org/wiki/Numeri_pseudo-casuali",
                +	"MATH_RANDOM_INT_TITLE": "intero casuale da %1 a %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Restituisce un numero intero casuale compreso tra i due limiti indicati (inclusi).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://it.wikipedia.org/wiki/Numeri_pseudo-casuali",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "frazione casuale",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Restituisce una frazione compresa fra 0.0 (incluso) e 1.0 (escluso).",
                +	"TEXT_TEXT_HELPURL": "https://it.wikipedia.org/wiki/Stringa_(informatica)",
                +	"TEXT_TEXT_TOOLTIP": "Una lettera, una parola o una linea di testo.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "crea testo con",
                +	"TEXT_JOIN_TOOLTIP": "Crea un blocco di testo unendo un certo numero di elementi.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unisci",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Aggiungi, rimuovi o riordina le sezioni per riconfigurare questo blocco testo.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Aggiungi un elemento al testo.",
                +	"TEXT_APPEND_TITLE": "a %1 aggiungi il testo %2",
                +	"TEXT_APPEND_TOOLTIP": "Aggiunge del testo alla variabile '%1'.",
                +	"TEXT_LENGTH_TITLE": "lunghezza di %1",
                +	"TEXT_LENGTH_TOOLTIP": "Restituisce il numero di lettere (inclusi gli spazi) nel testo fornito.",
                +	"TEXT_ISEMPTY_TITLE": "%1 è vuoto",
                +	"TEXT_ISEMPTY_TOOLTIP": "Restituisce vero se il testo fornito è vuoto.",
                +	"TEXT_INDEXOF_TOOLTIP": "Restituisce l'indice della prima occorrenza del primo testo all'interno del secondo testo. Restituisce %1 se il testo non viene trovato.",
                +	"TEXT_INDEXOF_TITLE": "nel testo %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "trova la prima occorrenza del testo",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "trova l'ultima occorrenza del testo",
                +	"TEXT_CHARAT_TITLE": "nel testo %1 %2",
                +	"TEXT_CHARAT_FROM_START": "prendi la lettera #",
                +	"TEXT_CHARAT_FROM_END": "prendi la lettera # dalla fine",
                +	"TEXT_CHARAT_FIRST": "prendi la prima lettera",
                +	"TEXT_CHARAT_LAST": "prendi l'ultima lettera",
                +	"TEXT_CHARAT_RANDOM": "prendi lettera casuale",
                +	"TEXT_CHARAT_TOOLTIP": "Restituisce la lettera nella posizione indicata.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Restituisce la porzione di testo indicata.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "nel testo",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "prendi sotto-stringa dalla lettera #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "prendi sotto-stringa dalla lettera # dalla fine",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "prendi sotto-stringa dalla prima lettera",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "alla lettera #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "alla lettera # dalla fine",
                +	"TEXT_GET_SUBSTRING_END_LAST": "all'ultima lettera",
                +	"TEXT_CHANGECASE_TOOLTIP": "Restituisce una copia del testo in un diverso formato maiuscole/minuscole.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "in MAIUSCOLO",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "in minuscolo",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "con Iniziali Maiuscole",
                +	"TEXT_TRIM_TOOLTIP": "Restituisce una copia del testo con gli spazi rimossi ad uno o entrambe le estremità.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "rimuovi spazi da entrambi gli estremi",
                +	"TEXT_TRIM_OPERATOR_LEFT": "rimuovi spazi a sinistra",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "rimuovi spazi a destra",
                +	"TEXT_PRINT_TITLE": "scrivi %1",
                +	"TEXT_PRINT_TOOLTIP": "Scrive il testo, numero o altro valore indicato.",
                +	"TEXT_PROMPT_TYPE_TEXT": "richiedi testo con messaggio",
                +	"TEXT_PROMPT_TYPE_NUMBER": "richiedi numero con messaggio",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Richiedi un numero all'utente.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Richiede del testo da parte dell'utente.",
                +	"TEXT_COUNT_MESSAGE0": "conta %1 in %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Contare quante volte una parte di testo si ripete all'interno di qualche altro testo.",
                +	"TEXT_REPLACE_MESSAGE0": "sostituisci %1 con %2 in %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "sostituisci tutte le occorrenze di un certo testo con qualche altro testo.",
                +	"TEXT_REVERSE_MESSAGE0": "inverti %1",
                +	"TEXT_REVERSE_TOOLTIP": "Inverte l'ordine dei caratteri nel testo.",
                +	"LISTS_CREATE_EMPTY_TITLE": "crea lista vuota",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Restituisce una lista, di lunghezza 0, contenente nessun record di dati",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Crea una lista con un certo numero di elementi.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "crea lista con",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Aggiungi, rimuovi o riordina le sezioni per riconfigurare il blocco lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Aggiunge un elemento alla lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Crea una lista costituita dal valore indicato ripetuto per il numero di volte specificato.",
                +	"LISTS_REPEAT_TITLE": "crea una lista con l'elemento %1 ripetuto %2 volte",
                +	"LISTS_LENGTH_TITLE": "lunghezza di %1",
                +	"LISTS_LENGTH_TOOLTIP": "Restituisce la lunghezza della lista",
                +	"LISTS_ISEMPTY_TITLE": "%1 è vuota",
                +	"LISTS_ISEMPTY_TOOLTIP": "Restituisce vero se la lista è vuota.",
                +	"LISTS_INLIST": "nella lista",
                +	"LISTS_INDEX_OF_FIRST": "trova la prima occorrenza dell'elemento",
                +	"LISTS_INDEX_OF_LAST": "trova l'ultima occorrenza dell'elemento",
                +	"LISTS_INDEX_OF_TOOLTIP": "Restituisce l'indice della prima/ultima occorrenza dell'elemento nella lista. Restituisce %1 se l'elemento non viene trovato.",
                +	"LISTS_GET_INDEX_GET": "prendi",
                +	"LISTS_GET_INDEX_GET_REMOVE": "prendi e rimuovi",
                +	"LISTS_GET_INDEX_REMOVE": "rimuovi",
                +	"LISTS_GET_INDEX_FROM_END": "# dalla fine",
                +	"LISTS_GET_INDEX_FIRST": "primo",
                +	"LISTS_GET_INDEX_LAST": "ultimo",
                +	"LISTS_GET_INDEX_RANDOM": "casuale",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 corrisponde al primo elemento.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 corrisponde all'ultimo elemento.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Restituisce l'elemento nella posizione indicata della lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Restituisce il primo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Restituisce l'ultimo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Restituisce un elemento casuale in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Rimuove e restituisce l'elemento nella posizione indicata in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Rimuove e restituisce il primo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Restituisce e rimuove l'ultimo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Restituisce e rimuove un elemento casuale in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Rimuove l'elemento nella posizione indicata in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Rimuove il primo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Rimuove l'ultimo elemento in una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Rimuove un elemento casuale in una lista.",
                +	"LISTS_SET_INDEX_SET": "imposta",
                +	"LISTS_SET_INDEX_INSERT": "inserisci in",
                +	"LISTS_SET_INDEX_INPUT_TO": "come",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Imposta l'elemento nella posizione indicata di una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Imposta il primo elemento in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Imposta l'ultimo elemento in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Imposta un elemento casuale in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserisci un elemento nella posizione indicata in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Inserisci l'elemento all'inizio della lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Aggiungi un elemento alla fine di una lista",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Inserisce l'elemento casualmente in una lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "prendi sotto-lista da #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "prendi sotto-lista da # dalla fine",
                +	"LISTS_GET_SUBLIST_START_FIRST": "prendi sotto-lista dall'inizio",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "fino a #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "da # dalla fine",
                +	"LISTS_GET_SUBLIST_END_LAST": "dagli ultimi",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Crea una copia della porzione specificata di una lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "ordinamento %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordina una copia di un elenco.",
                +	"LISTS_SORT_ORDER_ASCENDING": "crescente",
                +	"LISTS_SORT_ORDER_DESCENDING": "decrescente",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerico",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetico",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetico, ignorare differenze maiuscole e minuscole",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "crea lista da testo",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "crea testo da lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "con delimitatore",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dividi il testo in un elenco di testi, interrompendo ad ogni delimitatore.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Unisci una lista di testi in un unico testo, separato da un delimitatore.",
                +	"LISTS_REVERSE_MESSAGE0": "inverti %1",
                +	"LISTS_REVERSE_TOOLTIP": "Inverti una copia di un elenco.",
                +	"VARIABLES_GET_TOOLTIP": "Restituisce il valore di una variabile.",
                +	"VARIABLES_GET_CREATE_SET": "Crea 'imposta %1'",
                +	"VARIABLES_SET": "imposta %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Imposta questa variabile ad essere pari all'input.",
                +	"VARIABLES_SET_CREATE_GET": "Crea 'prendi %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "per",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "fai qualcosa",
                +	"PROCEDURES_BEFORE_PARAMS": "conː",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "conː",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crea una funzione senza output.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Descrivi questa funzione...",
                +	"PROCEDURES_DEFRETURN_RETURN": "ritorna",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Crea una funzione con un output.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "consenti dichiarazioni",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Attenzioneː Questa funzione ha parametri duplicati.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://it.wikipedia.org/wiki/Funzione (informatica)",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Esegue la funzione definita dall'utente '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://it.wikipedia.org/wiki/Funzione (informatica)",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Esegue la funzione definita dall'utente '%1' ed usa il suo output.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "input",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Aggiungi, rimuovi o riordina input alla funzione.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nome inputː",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Aggiungi un input alla funzione.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Evidenzia definizione di funzione",
                +	"PROCEDURES_CREATE_DO": "Crea '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Se un valore è vero allora restituisce un secondo valore.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Attenzioneː Questo blocco può essere usato solo all'interno di una definizione di funzione."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ja.json b/blockly/webif/static/blockly/msg/json/ja.json
                new file mode 100644
                index 000000000..cb860d522
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ja.json
                @@ -0,0 +1,362 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Shirayuki",
                +			"Oda",
                +			"아라",
                +			"Otokoume",
                +			"Sujiniku",
                +			"Sgk",
                +			"TAKAHASHI Shuuji",
                +			"Suiato",
                +			"ネイ"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "項目",
                +	"TODAY": "今日",
                +	"DUPLICATE_BLOCK": "複製",
                +	"ADD_COMMENT": "コメントを追加",
                +	"REMOVE_COMMENT": "コメントを削除",
                +	"EXTERNAL_INPUTS": "外部入力",
                +	"INLINE_INPUTS": "インライン入力",
                +	"DELETE_BLOCK": "ブロックを削除",
                +	"DELETE_X_BLOCKS": "%1 個のブロックを削除",
                +	"DELETE_ALL_BLOCKS": "%1件のすべてのブロックを削除しますか?",
                +	"CLEAN_UP": "ブロックを整理する",
                +	"COLLAPSE_BLOCK": "ブロックを折りたたむ",
                +	"COLLAPSE_ALL": "ブロックを折りたたむ",
                +	"EXPAND_BLOCK": "ブロックを展開する",
                +	"EXPAND_ALL": "ブロックを展開する",
                +	"DISABLE_BLOCK": "ブロックを無効にする",
                +	"ENABLE_BLOCK": "ブロックを有効にする",
                +	"HELP": "ヘルプ",
                +	"UNDO": "取り消す",
                +	"REDO": "やり直す",
                +	"CHANGE_VALUE_TITLE": "値を変える:",
                +	"RENAME_VARIABLE": "変数の名前を変える…",
                +	"RENAME_VARIABLE_TITLE": "選択した%1の変数すべての名前を変える:",
                +	"NEW_VARIABLE": "変数の作成…",
                +	"NEW_VARIABLE_TITLE": "新しい変数の名前:",
                +	"VARIABLE_ALREADY_EXISTS": "変数名 '%1' は既に存在しています。",
                +	"DELETE_VARIABLE_CONFIRMATION": "%1か所で使われている変数 '%2' を削除しますか?",
                +	"DELETE_VARIABLE": "変数 '%1' を削除",
                +	"COLOUR_PICKER_HELPURL": "https://ja.wikipedia.org/wiki/色",
                +	"COLOUR_PICKER_TOOLTIP": "パレットから色を選んでください。",
                +	"COLOUR_RANDOM_TITLE": "ランダムな色",
                +	"COLOUR_RANDOM_TOOLTIP": "ランダムな色を選ぶ。",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "色づけ",
                +	"COLOUR_RGB_RED": "赤",
                +	"COLOUR_RGB_GREEN": "緑",
                +	"COLOUR_RGB_BLUE": "青",
                +	"COLOUR_RGB_TOOLTIP": "赤、緑、および青の指定された量で色を作成します。すべての値は 0 ~ 100 の間でなければなりません。",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "ブレンド",
                +	"COLOUR_BLEND_COLOUR1": "色 1",
                +	"COLOUR_BLEND_COLOUR2": "色 2",
                +	"COLOUR_BLEND_RATIO": "比率",
                +	"COLOUR_BLEND_TOOLTIP": "2色を与えられた比率(0.0~1.0)で混ぜます。",
                +	"CONTROLS_REPEAT_HELPURL": "https://ja.wikipedia.org/wiki/for文",
                +	"CONTROLS_REPEAT_TITLE": "%1 回繰り返します",
                +	"CONTROLS_REPEAT_INPUT_DO": "実行",
                +	"CONTROLS_REPEAT_TOOLTIP": "いくつかのステートメントを数回実行します。",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "繰り返す:続ける条件",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "繰り返す:終わる条件",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "値がtrueの間、いくつかのステートメントを実行する。",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "値がfalseの間、いくつかのステートメントを実行する。",
                +	"CONTROLS_FOR_TOOLTIP": "変数 '%1' が開始番号から終了番号まで指定した間隔での値をとって、指定したブロックを実行する。",
                +	"CONTROLS_FOR_TITLE": "カウントする( 変数: %1 範囲: %2 ~ %3 間隔: %4 )",
                +	"CONTROLS_FOREACH_TITLE": "リスト%2の各項目%1について",
                +	"CONTROLS_FOREACH_TOOLTIP": "リストの各項目について、その項目を変数'%1'として、いくつかのステートメントを実行します。",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ループから抜け出します",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ループの次の反復処理を続行します",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "入っているループから抜け出します。",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "このループの残りの部分をスキップして、ループの繰り返しを続けます。",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "注意: このブロックは、ループ内でのみ使用できます。",
                +	"CONTROLS_IF_TOOLTIP_1": "値が true の場合、ステートメントを実行します。",
                +	"CONTROLS_IF_TOOLTIP_2": "値が true 場合は、ステートメントの最初のブロックを行います。それ以外の場合は、ステートメントの 2 番目のブロックを行います。",
                +	"CONTROLS_IF_TOOLTIP_3": "最初の値が true 場合は、ステートメントの最初のブロックを行います。それ以外の場合は、2 番目の値が true の場合、ステートメントの 2 番目のブロックをします。",
                +	"CONTROLS_IF_TOOLTIP_4": "最初の値が true 場合は、ステートメントの最初のブロックを行います。2 番目の値が true の場合は、ステートメントの 2 番目のブロックを行います。それ以外の場合は最後のブロックのステートメントを行います。",
                +	"CONTROLS_IF_MSG_IF": "もしも",
                +	"CONTROLS_IF_MSG_ELSEIF": "他でもしも",
                +	"CONTROLS_IF_MSG_ELSE": "他",
                +	"CONTROLS_IF_IF_TOOLTIP": "追加、削除、またはセクションを順序変更して、ブロックをこれを再構成します。",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "「もしも」のブロックに条件を追加します。",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Ifブロックに、すべてをキャッチする条件を追加。",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "キャンセル",
                +	"IOS_ERROR": "エラー",
                +	"IOS_VARIABLES_ADD_BUTTON": "追加",
                +	"IOS_VARIABLES_RENAME_BUTTON": "名前を変更",
                +	"IOS_VARIABLES_DELETE_BUTTON": "削除",
                +	"IOS_VARIABLES_VARIABLE_NAME": "変数名",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "空の変数名は使用できません。",
                +	"LOGIC_COMPARE_HELPURL": "https://ja.wikipedia.org/wiki/不等式",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "もし両方がお互いに等しく入力した場合は true を返します。",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "両方の入力が互いに等しくない場合に true を返します。",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "最初の入力が 2 番目の入力よりも小さいい場合は true を返します。",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "もし、最初の入力が二つ目入力より少ないか、おなじであったらTRUEをかえしてください",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "最初の入力が 2 番目の入力よりも大きい場合は true を返します。",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "もし入力がふたつめの入よりも大きかったらtrueをり返します。",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "両方の入力が true のときに true を返します。",
                +	"LOGIC_OPERATION_AND": "かつ",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "少なくとも 1 つの入力が true のときに true を返します。",
                +	"LOGIC_OPERATION_OR": "または",
                +	"LOGIC_NEGATE_HELPURL": "https://ja.wikipedia.org/wiki/否定",
                +	"LOGIC_NEGATE_TITLE": "%1ではない",
                +	"LOGIC_NEGATE_TOOLTIP": "入力が false の場合は、true を返します。入力が true の場合は false を返します。",
                +	"LOGIC_BOOLEAN_TRUE": "true",
                +	"LOGIC_BOOLEAN_FALSE": "false",
                +	"LOGIC_BOOLEAN_TOOLTIP": "True または false を返します。",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "null を返します。",
                +	"LOGIC_TERNARY_HELPURL": "https://ja.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "テスト",
                +	"LOGIC_TERNARY_IF_TRUE": "true の場合",
                +	"LOGIC_TERNARY_IF_FALSE": "false の場合",
                +	"LOGIC_TERNARY_TOOLTIP": "'テスト' の条件をチェックします。条件が true の場合、'true' の値を返します。それ以外の場合 'false' のを返します。",
                +	"MATH_NUMBER_HELPURL": "https://ja.wikipedia.org/wiki/数",
                +	"MATH_NUMBER_TOOLTIP": "数です。",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://ja.wikipedia.org/wiki/算術",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "2 つの数の合計を返します。",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "2 つの数の差を返します。",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "2 つの数の積を返します。",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "2 つの数の商を返します。",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "最初の数を2 番目の値で累乗した結果を返します。",
                +	"MATH_SINGLE_HELPURL": "https://ja.wikipedia.org/wiki/平方根",
                +	"MATH_SINGLE_OP_ROOT": "平方根",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "平方根を返す。",
                +	"MATH_SINGLE_OP_ABSOLUTE": "絶対値",
                +	"MATH_SINGLE_TOOLTIP_ABS": "絶対値を返す。",
                +	"MATH_SINGLE_TOOLTIP_NEG": "負の数を返す。",
                +	"MATH_SINGLE_TOOLTIP_LN": "数値の自然対数を返す。",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "底が10の対数を返す。",
                +	"MATH_SINGLE_TOOLTIP_EXP": "ネイピア数eの数値乗を返す。",
                +	"MATH_SINGLE_TOOLTIP_POW10": "10の数値乗を返す。",
                +	"MATH_TRIG_HELPURL": "https://ja.wikipedia.org/wiki/三角関数",
                +	"MATH_TRIG_TOOLTIP_SIN": "(ラジアンではなく)度数の正弦(sin)を返す。",
                +	"MATH_TRIG_TOOLTIP_COS": "(ラジアンではなく)度数の余弦(cosin)を返す。",
                +	"MATH_TRIG_TOOLTIP_TAN": "(ラジアンではなく)度数の正接(tan)を返す。",
                +	"MATH_TRIG_TOOLTIP_ASIN": "アークサイン(arcsin)を返す。",
                +	"MATH_TRIG_TOOLTIP_ACOS": "アークコサイン(arccosin)を返す。",
                +	"MATH_TRIG_TOOLTIP_ATAN": "アークタンジェント(arctan)を返す。",
                +	"MATH_CONSTANT_HELPURL": "https://ja.wikipedia.org/wiki/数学定数",
                +	"MATH_CONSTANT_TOOLTIP": "いずれかの共通の定数のを返す: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (無限).",
                +	"MATH_IS_EVEN": "は偶数",
                +	"MATH_IS_ODD": "は奇数",
                +	"MATH_IS_PRIME": "は素数",
                +	"MATH_IS_WHOLE": "は整数",
                +	"MATH_IS_POSITIVE": "は正",
                +	"MATH_IS_NEGATIVE": "は負",
                +	"MATH_IS_DIVISIBLE_BY": "は以下で割りきれる:",
                +	"MATH_IS_TOOLTIP": "数字が、偶数、奇数、素数、整数、正数、負数、または特定の数で割り切れるかどうかを判定し、true か false を返します。",
                +	"MATH_CHANGE_HELPURL": "https://ja.wikipedia.org/wiki/加法",
                +	"MATH_CHANGE_TITLE": "変更 %1 に %2",
                +	"MATH_CHANGE_TOOLTIP": "変数'%1'に数をたす。",
                +	"MATH_ROUND_HELPURL": "https://ja.wikipedia.org/wiki/端数処理",
                +	"MATH_ROUND_TOOLTIP": "数値を切り上げるか切り捨てる",
                +	"MATH_ROUND_OPERATOR_ROUND": "四捨五入",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "切り上げ",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "切り捨て",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "リストの合計",
                +	"MATH_ONLIST_TOOLTIP_SUM": "リストの数値を足して返す。",
                +	"MATH_ONLIST_OPERATOR_MIN": "リストの最小値",
                +	"MATH_ONLIST_TOOLTIP_MIN": "リストの最小値を返す。",
                +	"MATH_ONLIST_OPERATOR_MAX": "リストの最大値",
                +	"MATH_ONLIST_TOOLTIP_MAX": "リストの最大値を返す。",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "リストの平均",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "リストの数値の平均 (算術平均) を返す。",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "リストの中央値",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "リストの中央値を返す。",
                +	"MATH_ONLIST_OPERATOR_MODE": "一覧モード",
                +	"MATH_ONLIST_TOOLTIP_MODE": "リスト中の最頻項目のリストを返す。",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "リストの標準偏差",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "リストの標準偏差を返す。",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "リストからランダムに選ばれた項目",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "リストからランダムに選ばれた要素を返す。",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1÷%2の余り",
                +	"MATH_MODULO_TOOLTIP": "2つの数値の割り算の余りを返す。",
                +	"MATH_CONSTRAIN_TITLE": "%1の下限を%2に上限を%3に制限",
                +	"MATH_CONSTRAIN_TOOLTIP": "指定した上限と下限の間に値を制限する(上限と下限の値を含む)。",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "%1から%2までのランダムな整数",
                +	"MATH_RANDOM_INT_TOOLTIP": "指定された(上下限を含む)範囲のランダムな整数を返します。",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "1未満の正の乱数",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0以上で1.0未満の範囲の乱数を返します。",
                +	"TEXT_TEXT_HELPURL": "https://ja.wikipedia.org/wiki/文字列",
                +	"TEXT_TEXT_TOOLTIP": "文字、単語、または行のテキスト。",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "テキストの作成:",
                +	"TEXT_JOIN_TOOLTIP": "任意の数の項目一部を一緒に接合してテキストを作成。",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "結合",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "セクションを追加、削除、または順序変更して、ブロックを再構成。",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "テキストへ項目を追加。",
                +	"TEXT_APPEND_TOOLTIP": "変数 '%1' にテキストを追加。",
                +	"TEXT_LENGTH_TITLE": "%1の長さ",
                +	"TEXT_LENGTH_TOOLTIP": "与えられたテキストの(スペースを含む)文字数を返す。",
                +	"TEXT_ISEMPTY_TITLE": "%1が空",
                +	"TEXT_ISEMPTY_TOOLTIP": "与えられたテキストが空の場合は true を返す。",
                +	"TEXT_INDEXOF_TOOLTIP": "二番目のテキストの中で一番目のテキストが最初/最後に出現したインデックスを返す。テキストが見つからない場合は%1を返す。",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "で以下のテキストの最初の出現箇所を検索:",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "テキストの最後の出現箇所を検索",
                +	"TEXT_CHARAT_FROM_START": "で、文字# を取得",
                +	"TEXT_CHARAT_FROM_END": "一番最後の言葉、キャラクターを所得",
                +	"TEXT_CHARAT_FIRST": "最初の文字を得る",
                +	"TEXT_CHARAT_LAST": "最後の文字を得る",
                +	"TEXT_CHARAT_RANDOM": "ランダムな文字を得る",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "指定された位置に文字を返します。",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "テキストの指定部分を返します。",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "テキストで",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "文字列からの部分文字列を取得 #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "部分文字列を取得する #端から得る",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "部分文字列を取得する。",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "# の文字",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "文字列の# 終わりからの#",
                +	"TEXT_GET_SUBSTRING_END_LAST": "最後のの文字",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "別のケースに、テキストのコピーを返します。",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "大文字に変換する",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "小文字に",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "タイトル ケースに",
                +	"TEXT_TRIM_TOOLTIP": "スペースを 1 つまたは両方の端から削除したのち、テキストのコピーを返します。",
                +	"TEXT_TRIM_OPERATOR_BOTH": "両端のスペースを取り除く",
                +	"TEXT_TRIM_OPERATOR_LEFT": "左端のスペースを取り除く",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "右端のスペースを取り除く",
                +	"TEXT_PRINT_TITLE": "%1 を印刷します。",
                +	"TEXT_PRINT_TOOLTIP": "指定したテキスト、番号または他の値を印刷します。",
                +	"TEXT_PROMPT_TYPE_TEXT": "メッセージでテキスト入力を求める",
                +	"TEXT_PROMPT_TYPE_NUMBER": "メッセージで番号の入力を求める",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "ユーザーに数値のインプットを求める。",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "ユーザーにテキスト入力を求める。",
                +	"TEXT_COUNT_MESSAGE0": "%2に含まれる%1の数を数える",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "とある文が別の文のなかに使われた回数を数える。",
                +	"TEXT_REPLACE_MESSAGE0": "%3に含まれる%1を%2に置換",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "文に含まれるキーワードを置換する。",
                +	"TEXT_REVERSE_MESSAGE0": "%1を逆順に",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "文の文字を逆順にする。",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "空のリストを作成",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "長さ0でデータ・レコードを含まない空のリストを返す",
                +	"LISTS_CREATE_WITH_TOOLTIP": "項目数が不定のリストを作成。",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "以下を使ってリストを作成:",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "リスト",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "追加、削除、またはセクションの順序変更をして、このリスト・ブロックを再構成する。",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "リストに項目を追加。",
                +	"LISTS_REPEAT_TOOLTIP": "与えられた値を指定された回数繰り返してリストを作成。",
                +	"LISTS_REPEAT_TITLE": "項目%1を%2回繰り返したリストを作成",
                +	"LISTS_LENGTH_TITLE": "%1の長さ",
                +	"LISTS_LENGTH_TOOLTIP": "リストの長さを返します。",
                +	"LISTS_ISEMPTY_TITLE": "%1が空",
                +	"LISTS_ISEMPTY_TOOLTIP": "リストが空の場合は、true を返します。",
                +	"LISTS_INLIST": "リストで",
                +	"LISTS_INDEX_OF_FIRST": "最初に見つかった項目を検索します。",
                +	"LISTS_INDEX_OF_LAST": "最後に見つかったアイテムを見つける",
                +	"LISTS_INDEX_OF_TOOLTIP": "リスト項目の最初/最後に出現するインデックス位置を返します。項目が見つからない場合は %1 を返します。",
                +	"LISTS_GET_INDEX_GET": "取得",
                +	"LISTS_GET_INDEX_GET_REMOVE": "取得と削除",
                +	"LISTS_GET_INDEX_REMOVE": "削除",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "後ろから #",
                +	"LISTS_GET_INDEX_FIRST": "最初",
                +	"LISTS_GET_INDEX_LAST": "最後",
                +	"LISTS_GET_INDEX_RANDOM": "ランダム",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 は、最初の項目です。",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 は、最後の項目です。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "リスト内の指定位置にある項目を返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "リストの最初の項目を返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "リストの最後の項目を返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "ランダム アイテム リストを返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "リスト内の指定位置にある項目を削除し、返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "リスト内の最初の項目を削除し返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "リスト内の最後の項目を削除したあと返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "リストのランダムなアイテムを削除し返します。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "リスト内の指定された項目を削除します。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "リスト内の最初の項目を削除します。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "リスト内の最後の項目を削除します。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "リスト内にあるアイテムをランダムに削除します。",
                +	"LISTS_SET_INDEX_SET": "セット",
                +	"LISTS_SET_INDEX_INSERT": "挿入位置:",
                +	"LISTS_SET_INDEX_INPUT_TO": "として",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "リスト内の指定された位置に項目を設定します。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "リスト内に最初の項目を設定します。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "リスト内の最後の項目を設定します。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "リスト内にランダムなアイテムを設定します。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "リスト内の指定位置に項目を挿入します。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "リストの先頭に項目を挿入します。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "リストの末尾に項目を追加します。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "リストに項目をランダムに挿入します。",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "# からサブディレクトリのリストを取得します。",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "端から #のサブリストを取得します。",
                +	"LISTS_GET_SUBLIST_START_FIRST": "最初からサブリストを取得する。",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "#へ",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "最後から#へ",
                +	"LISTS_GET_SUBLIST_END_LAST": "最後へ",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "リストの指定された部分のコピーを作成してくださ。",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "並べ替え(タイプ:%1、順番:%2、項目のリスト:%3)",
                +	"LISTS_SORT_TOOLTIP": "リストのコピーを並べ替え",
                +	"LISTS_SORT_ORDER_ASCENDING": "昇順",
                +	"LISTS_SORT_ORDER_DESCENDING": "降順",
                +	"LISTS_SORT_TYPE_NUMERIC": "数値順",
                +	"LISTS_SORT_TYPE_TEXT": "アルファベット順",
                +	"LISTS_SORT_TYPE_IGNORECASE": "アルファベット順(大文字・小文字の区別無し)",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "テキストからリストを作る",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "リストからテキストを作る",
                +	"LISTS_SPLIT_WITH_DELIMITER": "区切り記号",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "テキストを区切り記号で分割したリストにする",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "テキストのリストを区切り記号で区切られた一つのテキストにする",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "%1を逆順に",
                +	"LISTS_REVERSE_TOOLTIP": "リストのコピーを逆順にする。",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_TOOLTIP": "この変数の値を返します。",
                +	"VARIABLES_GET_CREATE_SET": "'セット%1を作成します。",
                +	"VARIABLES_SET": "セット %1 宛先 %2",
                +	"VARIABLES_SET_TOOLTIP": "この入力を変数と等しくなるように設定します。",
                +	"VARIABLES_SET_CREATE_GET": "'%1 を取得' を作成します。",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://ja.wikipedia.org/wiki/サブルーチン",
                +	"PROCEDURES_DEFNORETURN_TITLE": "宛先",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "何かしてください",
                +	"PROCEDURES_BEFORE_PARAMS": "対象:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "対象:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "出力なしの関数を作成します。",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "この関数の説明…",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://ja.wikipedia.org/wiki/サブルーチン",
                +	"PROCEDURES_DEFRETURN_RETURN": "返す",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "一つの出力を持つ関数を作成します。",
                +	"PROCEDURES_ALLOW_STATEMENTS": "ステートメントを許可",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "警告: この関数には重複するパラメーターがあります。",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ja.wikipedia.org/wiki/サブルーチン",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "ユーザー定義関数 '%1' を実行します。",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ja.wikipedia.org/wiki/サブルーチン",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "ユーザー定義関数 '%1' を実行し、その出力を使用します。",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "入力",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "この関数への入力の追加、削除、順番変更。",
                +	"PROCEDURES_MUTATORARG_TITLE": "入力名:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "関数への入力の追加。",
                +	"PROCEDURES_HIGHLIGHT_DEF": "関数の内容を強調表示します。",
                +	"PROCEDURES_CREATE_DO": "'%1' を作成",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "1番目の値が true の場合、2番目の値を返します。",
                +	"PROCEDURES_IFRETURN_WARNING": "警告: このブロックは、関数定義内でのみ使用できます。"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/kab.json b/blockly/webif/static/blockly/msg/json/kab.json
                new file mode 100644
                index 000000000..caa2c82e7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/kab.json
                @@ -0,0 +1,336 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Amaziɣ maziɣ",
                +			"Belkacem77",
                +			"Alem"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "aferdis",
                +	"TODAY": "Ass-a",
                +	"DUPLICATE_BLOCK": "Sleg",
                +	"ADD_COMMENT": "Rnu awennit",
                +	"REMOVE_COMMENT": "Kkes awennit",
                +	"EXTERNAL_INPUTS": "Inekcam izɣarayen",
                +	"INLINE_INPUTS": "Inekcam srid",
                +	"DELETE_BLOCK": "Kkes iḥder",
                +	"DELETE_X_BLOCKS": "Kkes %1 n iḥder",
                +	"DELETE_ALL_BLOCKS": "Kkes %1 n iḥedran meṛṛa?",
                +	"CLEAN_UP": "Sfeḍ iḥedran",
                +	"COLLAPSE_BLOCK": "Fneẓ iḥder",
                +	"COLLAPSE_ALL": "Fneẓ iḥedran",
                +	"EXPAND_BLOCK": "Snefli iḥder",
                +	"EXPAND_ALL": "Snefli iḥedran",
                +	"DISABLE_BLOCK": "Sens iḥder",
                +	"ENABLE_BLOCK": "Sens iḥedran",
                +	"HELP": "Tallelt",
                +	"UNDO": "Err-d",
                +	"REDO": "Uɣal",
                +	"CHANGE_VALUE_TITLE": "Snifel azal:",
                +	"RENAME_VARIABLE": "Snifel isem n umutti...",
                +	"RENAME_VARIABLE_TITLE": "Snifel akk imuttiyen '%1' ar:",
                +	"NEW_VARIABLE": "rnu amutti...",
                +	"NEW_VARIABLE_TITLE": "Isem amaynut n wazal",
                +	"VARIABLE_ALREADY_EXISTS": "Amutti s yisem '%1' yella yakan.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Amutti s yisem '%1' yella yakan i umutti-nniḍen s wanaw '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Tasekkirt s yisem '%1' tella yakan.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Kkes %1 n useqdec n umutti '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Ur izmir ara ad yekkes amutti '%1' acku yedda di tbadut n twuri '%2'",
                +	"DELETE_VARIABLE": "Kkes amutti '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://kab.wikipedia.org/wiki/Ini",
                +	"COLOUR_PICKER_TOOLTIP": "Fren ini seg ugalis.",
                +	"COLOUR_RANDOM_TITLE": "ini agacuran",
                +	"COLOUR_RANDOM_TOOLTIP": "Fren ini s wudem agacuran.",
                +	"COLOUR_RGB_TITLE": "ini s",
                +	"COLOUR_RGB_RED": "azeggwaɣ",
                +	"COLOUR_RGB_GREEN": "azegzaw",
                +	"COLOUR_RGB_BLUE": "anili",
                +	"COLOUR_RGB_TOOLTIP": "Rnu ini s tnecta yettunefk s tesmekta n uzeggaɣ, azegzaw, akked unili. Yessefk akk azalen ad ilin gar 0 akked 100.",
                +	"COLOUR_BLEND_TITLE": "rkwec",
                +	"COLOUR_BLEND_COLOUR1": "ini 1",
                +	"COLOUR_BLEND_COLOUR2": "ini 2",
                +	"COLOUR_BLEND_RATIO": "afmiḍi",
                +	"COLOUR_BLEND_TOOLTIP": "Sexleḍ sin n yiniten d tesmekta (gar 0.0 ar 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "Ales %1 n tikal",
                +	"CONTROLS_REPEAT_INPUT_DO": "eg",
                +	"CONTROLS_REPEAT_TOOLTIP": "Selkem ddeqs n tinaḍin ddeqs n tikal.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ales skud",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ales arama",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Skud azal d idetti, selkem ihi tinadin.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Skud azal d ucciḍ, selkem ihi tinadin.",
                +	"CONTROLS_FOR_TOOLTIP": "Mudd i umutti '%1' azalen seg umḍan n tazwara arama d umḍan n tagara, stmerna n usurif yettunefken, sakin selkem tiaḍin yettunefken.",
                +	"CONTROLS_FOR_TITLE": "siḍen akked %1 seg %2 ar %3 s %4",
                +	"CONTROLS_FOREACH_TITLE": "i yal aferdis  %1 di tebdart %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "I yal aferdis n tebdart, mudd azal n uferdis i umutti '%1', sakin selkem tinaḍin.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ffeɣ seg tneddict",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "kemmel s wallus d tneddict d-iteddun",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Ffeɣ si tneddict tamagbart.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Zgel ayen i d-yeqqimen di tneddict-agi, sakin kemmel allus d-iteddun.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Ɣur-k: Iḥder-agi yessefk ad yettwaseqdec di tneddict.",
                +	"CONTROLS_IF_TOOLTIP_1": "ma yella azal d idetti, ihi selkem kra n tinaḍin.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ma yella zal d idetti, selkem iḥder amezwaru. Neɣ ma ulac, selkem iḥder wis sin.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ma yella azal amezwaru d idetti, selkem iḥder amezwaru. Neɣ ma azal wis sin d ucciḍ, selkem iḥ€der wis sin.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ma yella azal amezwaru d idetti, selkem iḥeder amezwaru. Neɣ, ma yella azal wis sin d idetti, selkem iḥder wis sin. Ma yella ula d yisen seg-sen mačči d idetti, selkem iḥder aneggaru.",
                +	"CONTROLS_IF_MSG_IF": "ma",
                +	"CONTROLS_IF_MSG_ELSEIF": "neɣ ma",
                +	"CONTROLS_IF_MSG_ELSE": "neɣ",
                +	"CONTROLS_IF_IF_TOOLTIP": "Rnu, kkes, neq ales ales asmizzwer n tgezmiyin akken ad talseḍ tawila n iḥder-agi ma.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Rni tawtilt i yiḥder ma.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Rnu tawtilt taneggarut i yiḥder ma igebren akk tinaḍin.",
                +	"IOS_OK": "IH",
                +	"IOS_CANCEL": "Sefsex",
                +	"IOS_ERROR": "Tuccḍa",
                +	"IOS_PROCEDURES_INPUTS": "INEKCAM",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Rnu anekcum",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Sireg asmizzwer",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Tawuri-a ɣur-s inekcam imsinen.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Rnu amutti",
                +	"IOS_VARIABLES_ADD_BUTTON": "Rnu",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Snifel isem",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Kkes",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Isem n umutti",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Ur tezmireḍ ara ad tesqedceḍ isem n umutti amaynut.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Ad yerr idetti ma yella i sin n inekcam d imegduya.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Ad d-yerr idetti ma yella i sin n inekcam mačči d imegduya.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Ad d-yerr idetti ma yella anekcam amezwaru meẓẓi ɣef wis sin.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Ad d-yerr idetti ma yella anekcam amezwaru meẓẓi neɣ yegda wis sin.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Ad d-yerr idetti ma yella anekcam amezwaru meqqeṛ ɣef wis sin.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Ad d-yerr idetti ma yella anekcam amezwaru meqqeṛ neɣ yegda wis sin.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Ad d-yerr idetti ma yella inekcam d idettiyen.",
                +	"LOGIC_OPERATION_AND": "akked",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Ad d-yerr idetti ma yella ɣarsum yiwen seg inekcam d idetti.",
                +	"LOGIC_OPERATION_OR": "neɣ",
                +	"LOGIC_NEGATE_TITLE": "mačči %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Ad d-yerr idetti ma yella anekcam d ucciḍ. Ad d-yerr ucciḍ ma yella anekcam d idetti.",
                +	"LOGIC_BOOLEAN_TRUE": "idetti",
                +	"LOGIC_BOOLEAN_FALSE": "ucciḍ",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Ad d-yerr idetti neɣ ucciḍ",
                +	"LOGIC_NULL": "Ilem",
                +	"LOGIC_NULL_TOOLTIP": "Ad d-yerr ilem",
                +	"LOGIC_TERNARY_CONDITION": "sekyed",
                +	"LOGIC_TERNARY_IF_TRUE": "ma d idetti",
                +	"LOGIC_TERNARY_IF_FALSE": "ma ucciḍ",
                +	"LOGIC_TERNARY_TOOLTIP": "Senqed tawtilt deg 'sekyed'. Ma yella d idetti, ad d-yerr azal 'ma idetti', ma ulac ad d-yerr azam 'ma ucciḍ'.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Amḍan.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Ad d-yerr tmerni n sin n imiḍanen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Ad d-yerr tmernit n sin n imiḍanen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Ad d-yerr tukksa gar sin n imiḍanen.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Ad d-yerr aful n sin n imḍanen.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Ad d-yerr amḍan amezwaru uzmir wis sin.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "aẓar uzmir 2",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Ad d-yerr aẓaṛ uzmir sin n umiḍan.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "azal amagdez",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Ad d-yerr azal amagdez n umiḍan.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Ad d-yerr ugmiḍ n umḍan.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Ad d-yerr alugaritm agamawan n umiḍan.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Ad d-yerr alugaritm 10 n umiḍan.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Ad d-yerr e uzmir amiḍan.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Ad d-yerr 10 uzmir amiḍan.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Ad d-yerr asinus n teɣmert s tfesna (mačči aṛadyan).",
                +	"MATH_TRIG_TOOLTIP_COS": "Ad d-yerr akusinus n teɣmert s tfesna (mačči aṛadyan).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Ad d-yerr taslayt n teɣmert s tfesna (mačči aṛadyan).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Ad d-yerr taganzi n usinus n umḍan.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Ad d-yerr taganzi n ukusinus n umḍan.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Ad d-yerr taganzi n teslayt n umiḍan.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Ad d-yerr yiwet seg tmezgiyin yettwasnen : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), neɣ ∞ (ifeḍ).",
                +	"MATH_IS_EVEN": "d ayugan",
                +	"MATH_IS_ODD": "d aryugan",
                +	"MATH_IS_PRIME": "d amenzu",
                +	"MATH_IS_WHOLE": "d ummid",
                +	"MATH_IS_POSITIVE": "d ufrar",
                +	"MATH_IS_NEGATIVE": "d uzdir",
                +	"MATH_IS_DIVISIBLE_BY": "d ubṭay ɣef",
                +	"MATH_IS_TOOLTIP": "Senqed ma yella amḍan d ayugan, d aryugan, d amenzu, d ummid, d ufrar, d uzdir, neɣ d ybṭay ɣef kra n umḍan. Ad d-yerr idettu neɣ ucciḍ.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "snifel %1 s %2",
                +	"MATH_CHANGE_TOOLTIP": "Rnu amḍan i umutti '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Saẓ amiḍan d asawen neɣ d akesser.",
                +	"MATH_ROUND_OPERATOR_ROUND": "Saẓ",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Saẓ d asawen",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "Saẓ d akesser",
                +	"MATH_ONLIST_OPERATOR_SUM": "Timernit n tebdart",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Ad d-yerr timernit n imḍanen meṛṛa deg tebdart.",
                +	"MATH_ONLIST_OPERATOR_MIN": "adday n tebdart",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Ad d-yerr amḍan  ameẓẓyan di tebdart.",
                +	"MATH_ONLIST_OPERATOR_MAX": "afellay n tebdart",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Ad d-yerr amḍan  ameqqran di tebdart.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "talemmast n tebdart",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Ad d-yerr talemmas( tasnamḍant) n wazalen umḍinen di tebdart.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "tanammast n tebdart",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Ad d-yerr amḍan n anammas n tebdart.",
                +	"MATH_ONLIST_OPERATOR_MODE": "Tigwtiwin n tebdart",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Ad d-yerr tabdart n iferdisen i d-yettuɣalen s waṭas di tebdart.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "azza n tebdart",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Ad d-yerr azza n tebdart.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "aferdis agacuran n tebdart",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Ad d-yerr aferdis seg tebdart s wudem agacuran.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "tasagert n %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Ad d-yerr tasagert n beṭṭu n sin n imḍanen.",
                +	"MATH_CONSTRAIN_TITLE": "Err tamara i %1 gar %2 akked %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Err tamara n umiḍan akken ad yili gar snat n tlisa (ddant).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "ummid agacuran gar %1 akked %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Ad d-yerr ummid agacuran gar snat n tlisa, ddant.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "tirẓi tagacurant",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Ad d-yerr tirẓi tagacurant gar 0.0 (yedda) akked 1.0 (ur yeddi ara).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Asekkil, awal neɣ izirig n uḍris.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "rnu aḍṛis s",
                +	"TEXT_JOIN_TOOLTIP": "Ad yernu taceqquft n uḍris s usdukel gar yal amḍan n iferdisen.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "sdukkel",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Rnu, kkes, neɣ ales asmizzwer n tgezmiyin akken ad talseḍ tawila n iḥder-agi.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Rnu aferdis ar uḍris.",
                +	"TEXT_APPEND_TITLE": "Rnu aḍris %2 ar %1",
                +	"TEXT_APPEND_TOOLTIP": "Rnu aḍris ar umutti '%1'.",
                +	"TEXT_LENGTH_TITLE": "teɣzi n %1",
                +	"TEXT_LENGTH_TOOLTIP": "Ad d-yerr amḍan n isekkilen (ddab ula d imellalen) deg uḍris d-ittunefken.",
                +	"TEXT_ISEMPTY_TITLE": "%1 d ilem",
                +	"TEXT_ISEMPTY_TOOLTIP": "Add d-yerr idetti ma yella aḍris d ilem.",
                +	"TEXT_INDEXOF_TOOLTIP": "Ad d-yerr amatar n tmeḍriwt tamezwarut/taneggarut n uḍris amewaru deg uḍris wis sin. Ad d-yerr %1 ma yella ulac adris.",
                +	"TEXT_INDEXOF_TITLE": "deg uḍris %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "af-d timeḍriwt tamezwarut n uḍris",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "af-d timeḍriwt taneggarut deg uḍris",
                +	"TEXT_CHARAT_TITLE": "deg uḍris %1 %2",
                +	"TEXT_CHARAT_FROM_START": "awi asekkel #",
                +	"TEXT_CHARAT_FROM_END": "awi-d asekkil # si tagara",
                +	"TEXT_CHARAT_FIRST": "awi-d asekkil amezwaru",
                +	"TEXT_CHARAT_LAST": "awi-d asekkil aneggaru",
                +	"TEXT_CHARAT_RANDOM": "awi-d asekkil s wudem agacuran",
                +	"TEXT_CHARAT_TOOLTIP": "Ad d-yerr asekkil deg wuṭṭun yettwammlen.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Ad d-yerr aḥric yettwammlen deg uḍris.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "deg uḍris",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "awi-d azrir asnawan seg usekkil #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "awi-d azrir asnawan seg usekkil # si tagara",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "awi-d azrir asnawan seg usekkil amezwaru",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "arama d asekkil #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "arama d asekkil # si tagara",
                +	"TEXT_GET_SUBSTRING_END_LAST": "arama d asekkil aneggaru",
                +	"TEXT_CHANGECASE_TOOLTIP": "Ad d-yerr anɣel n uḍris s truẓi-nniḍen.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "s USEKKIL AMEQQRAN",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "s usekkil ameẓẓyan",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "s Umeqqran Di Tazwara n Yal Awal.",
                +	"TEXT_TRIM_TOOLTIP": "Ad d-yerr anɣel n uḍris s isekkilen ilmawen yettwakksen seg ixf neɣ i sin.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "Tukksa n isekkilen imellalen seg sin n idisan",
                +	"TEXT_TRIM_OPERATOR_LEFT": "tukksa n isekkilen seg uzelmaḍ",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "tukksa n isekkilen seg uyeffus",
                +	"TEXT_PRINT_TITLE": "ad d-yesken %1",
                +	"TEXT_PRINT_TOOLTIP": "Sken aḍris, amḍan neɣ azal-nniḍen d-ittunefken.",
                +	"TEXT_PROMPT_TYPE_TEXT": "aneftaɣ i uḍris s yizen",
                +	"TEXT_PROMPT_TYPE_NUMBER": "aneftaɣ i umḍan s yizen",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Suter amḍan i useqdac.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Suter aḍris i useqdac.",
                +	"TEXT_COUNT_MESSAGE0": "amḍan %1 ɣef %2",
                +	"TEXT_COUNT_TOOLTIP": "Ad isiḍen amḍan n tmeḍriwt n uḍris deg ayeḍ.",
                +	"TEXT_REPLACE_MESSAGE0": "semselsi %1 s %2 di %3",
                +	"TEXT_REPLACE_TOOLTIP": "As isemselsi akk timeḍriwin n uḍris s wayeḍ.",
                +	"TEXT_REVERSE_MESSAGE0": "tti %1",
                +	"TEXT_REVERSE_TOOLTIP": "Ad yetti asmizzwer n isekkilen deg uḍris.",
                +	"LISTS_CREATE_EMPTY_TITLE": "rnu tabdart tilemt",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Ad d-yerr tabdart n teɣzi 0 ur yegbiren ara ikalasen",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Ad yernu tabdart s umḍan n iferdisen.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "rnu tabdart s",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "tabdart",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Rnu, kkes, neɣ ales asmizzwer n tgezmiyin akken ad talseḍ tawila n iḥder-agi n tebdart.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Ad yernu aferdis ar tebdart.",
                +	"LISTS_REPEAT_TOOLTIP": "Ad yernu tabdart inetmen n wazal yettunefken ddeqs n tikal s umḍan yettwammlen.",
                +	"LISTS_REPEAT_TITLE": "ad yernu tabdart s uferdis %1 s tmeḍriwt %2",
                +	"LISTS_LENGTH_TITLE": "teɣzi n %1",
                +	"LISTS_LENGTH_TOOLTIP": "Ad d-yerr teɣzi n tebdart.",
                +	"LISTS_ISEMPTY_TITLE": "%1 d ilem",
                +	"LISTS_ISEMPTY_TOOLTIP": "Ad d-yerr idetti ma yella tabdart d tilemt.",
                +	"LISTS_INLIST": "di tebdart",
                +	"LISTS_INDEX_OF_FIRST": "aff-d timeḍriwt tamezwarut n uferdis",
                +	"LISTS_INDEX_OF_LAST": "af-d timeḍriwt taneggarut n uferdis",
                +	"LISTS_INDEX_OF_TOOLTIP": "Ad d-yerr amatar n tmeḍriwt tamezwarut/taneggarut n uferdis amewaru deg tebdart. Ad d-yerr %1 ma yella ulac aferdis.",
                +	"LISTS_GET_INDEX_GET": "awi",
                +	"LISTS_GET_INDEX_GET_REMOVE": "awi u kkes",
                +	"LISTS_GET_INDEX_REMOVE": "kkes",
                +	"LISTS_GET_INDEX_FROM_END": "# si tagara",
                +	"LISTS_GET_INDEX_FIRST": "amezwaru",
                +	"LISTS_GET_INDEX_LAST": "aneggaru",
                +	"LISTS_GET_INDEX_RANDOM": "agacuran",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 d aferdis amezwaru.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 d aferdis aneggaru.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Ad d-yerr aferdis n wadig yettwammlen deg tabdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Ad d-yerr aferdis amezwaru n tebdart..",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Ad d-yerr aferdis aneggaru di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Ad yerr aferdis agacuran di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Ad yekkes sakin ad d-yerr aferdis n wadig yettwammlen deg tabdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Ad yekkes sakin ad -yerr aferdis amezwaru di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Ad yekkes sakin ad -yerr aferdis aneggaru di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Ad yekkes sakin ad d-yerr aferdis agacuran di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Ad yekkes aferdis n wadig yettwammlen deg tabdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Ad yekkes aferdis amezwaru n tebdart..",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Ad yekkes aferdis aneggaru di tebdart.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Ad yekkes aferdis agacuran di tebdart.",
                +	"LISTS_SET_INDEX_SET": "sbadu",
                +	"LISTS_SET_INDEX_INSERT": "ger s",
                +	"LISTS_SET_INDEX_INPUT_TO": "am",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Ad yesbadu aferdis n wadig yettwammlen deg tabdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Ad d-yerr aferdis amezwaru di tebdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Ad d-yerr aferdis aneggaru di tebdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Ad yesbadu aferdis agacuran di tebdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Ad iger aferdis n wadig yettwammlen deg tabdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Ad iger aferdis di tazwara n tebdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Ad yernu aferdis ar tagara n  tebdart.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Ad iger aferdis s wudem agacuran deg tebdart.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "awi-d tabdart tasnawant seg #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "awi-d tabdart tasnawant seg # si tagara",
                +	"LISTS_GET_SUBLIST_START_FIRST": "awi-d tabdart tasnawant si tazwara",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "ar #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ar # si tagara",
                +	"LISTS_GET_SUBLIST_END_LAST": "ar tagara",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Ad yernu anɣel n uḥric yettwammlen n tebdart.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "smizzwer %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Smizzwer anɣel n tebdart.",
                +	"LISTS_SORT_ORDER_ASCENDING": "igemmen",
                +	"LISTS_SORT_ORDER_DESCENDING": "amnusruy",
                +	"LISTS_SORT_TYPE_NUMERIC": "umḍin",
                +	"LISTS_SORT_TYPE_TEXT": "agemmayan",
                +	"LISTS_SORT_TYPE_IGNORECASE": "agemmayan, anef i truẓi n usekkil",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "rnu tabdart seg uḍris",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "rnu aḍris si tebdart",
                +	"LISTS_SPLIT_WITH_DELIMITER": "s unabraz",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Ad yegzem aḍris ɣef ddeqs n tebdarin n yoiḍrisen, s unegzum yal anabraz.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "ad yesdukel tabdart n yiḍrisen deg iwen s usnabraz.",
                +	"LISTS_REVERSE_MESSAGE0": "tti %1",
                +	"LISTS_REVERSE_TOOLTIP": "Tti anɣel n tebdart.",
                +	"VARIABLES_GET_TOOLTIP": "Ad d-yerr azal n umutti-agi.",
                +	"VARIABLES_GET_CREATE_SET": "Rnu 'sbadu %1'",
                +	"VARIABLES_SET": "sbadu %1 ar %2",
                +	"VARIABLES_SET_TOOLTIP": "Ad yesbadu amutti-agi akken ad yegdu azal n unekcam.",
                +	"VARIABLES_SET_CREATE_GET": "Rnu 'awi-d %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "i",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "eg kra",
                +	"PROCEDURES_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Rnu tawuri s war anekcam.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Seglem tawuri-agi...",
                +	"PROCEDURES_DEFRETURN_RETURN": "tuɣalin",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "ad yernu tawuri s tuffɣa.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Sireg asmizzwer",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Ɣur-k: Tawuri-agi ɣur-s iɣewwaṛen usligen.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Selkem tawuri '%1' yesbadu u seqdac.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Selkem tawuri '%1' yesbadu useqdace sakin seqdec agmuḍ-is.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inekcam",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Rnu, kkes neɣ ales asmizzwer n inekcam i twuri-agi.",
                +	"PROCEDURES_MUTATORARG_TITLE": "isem n unekcum:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "rnu anekcam ar twuri-agi.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Sebruṛeq tabadut n twuri",
                +	"PROCEDURES_CREATE_DO": "rnu '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "ma yella azal d idetti, ad d-yerr azal-nniḍen wis sin.",
                +	"PROCEDURES_IFRETURN_WARNING": "Ɣur-k: Iḥder-agi yezmer ur yettwaseqdac ara ala di tebadut n twuri-agi."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ko.json b/blockly/webif/static/blockly/msg/json/ko.json
                new file mode 100644
                index 000000000..77e6092d5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ko.json
                @@ -0,0 +1,393 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Hym411",
                +			"아라",
                +			"Priviet",
                +			"Revi",
                +			"SeoJeongHo",
                +			"Alex00728",
                +			"Kurousagi",
                +			"Lemondoge",
                +			"Ykhwong",
                +			"Jerrykim306",
                +			"Onebone"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "항목",
                +	"TODAY": "오늘",
                +	"DUPLICATE_BLOCK": "복제",
                +	"ADD_COMMENT": "메모 추가",
                +	"REMOVE_COMMENT": "내용 제거",
                +	"EXTERNAL_INPUTS": "외부 입력",
                +	"INLINE_INPUTS": "내부 입력",
                +	"DELETE_BLOCK": "블록 삭제",
                +	"DELETE_X_BLOCKS": "블록 %1개 삭제",
                +	"DELETE_ALL_BLOCKS": "모든 블록 %1개를 삭제하겠습니까?",
                +	"CLEAN_UP": "블록 정리",
                +	"COLLAPSE_BLOCK": "블록 축소",
                +	"COLLAPSE_ALL": "블록 축소",
                +	"EXPAND_BLOCK": "블록 확장",
                +	"EXPAND_ALL": "블록 확장",
                +	"DISABLE_BLOCK": "블록 비활성화",
                +	"ENABLE_BLOCK": "블록 활성화",
                +	"HELP": "도움말",
                +	"UNDO": "실행 취소",
                +	"REDO": "다시 실행",
                +	"CHANGE_VALUE_TITLE": "값 바꾸기:",
                +	"RENAME_VARIABLE": "변수 이름 바꾸기:",
                +	"RENAME_VARIABLE_TITLE": "'%1' 변수 이름을 바꾸기:",
                +	"NEW_VARIABLE": "변수 만들기...",
                +	"NEW_VARIABLE_TITLE": "새 변수 이름:",
                +	"VARIABLE_ALREADY_EXISTS": "'%1' 변수는 이미 존재합니다.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "'%1' 변수는 '%2' 유형의 다른 변수에 대해 이미 존재합니다.",
                +	"PROCEDURE_ALREADY_EXISTS": "'%1' 함수는 이미 존재합니다.",
                +	"DELETE_VARIABLE_CONFIRMATION": "'%2' 변수에서 %1을(를) 삭제하시겠습니까?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "'%2' 함수 정의의 일부이기 때문에 '%1' 변수를 삭제할 수 없습니다",
                +	"DELETE_VARIABLE": "'%1' 변수를 삭제합니다",
                +	"COLOUR_PICKER_HELPURL": "https://ko.wikipedia.org/wiki/색",
                +	"COLOUR_PICKER_TOOLTIP": "팔레트에서 색을 고릅니다",
                +	"COLOUR_RANDOM_TITLE": "임의 색상",
                +	"COLOUR_RANDOM_TOOLTIP": "무작위로 색을 고릅니다.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "색",
                +	"COLOUR_RGB_RED": "빨강",
                +	"COLOUR_RGB_GREEN": "초록",
                +	"COLOUR_RGB_BLUE": "파랑",
                +	"COLOUR_RGB_TOOLTIP": "빨강,파랑,초록의 값을 이용하여 색을 만드십시오. 모든 값은 0과 100 사이에 있어야 합니다.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "혼합",
                +	"COLOUR_BLEND_COLOUR1": "색 1",
                +	"COLOUR_BLEND_COLOUR2": "색 2",
                +	"COLOUR_BLEND_RATIO": "비율",
                +	"COLOUR_BLEND_TOOLTIP": "두 색을 주어진 비율로 혼합 (0.0 - 1.0)",
                +	"CONTROLS_REPEAT_HELPURL": "https://ko.wikipedia.org/wiki/For_루프",
                +	"CONTROLS_REPEAT_TITLE": "%1회 반복",
                +	"CONTROLS_REPEAT_INPUT_DO": "하기",
                +	"CONTROLS_REPEAT_TOOLTIP": "여러 번 반복해 명령들을 실행합니다.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://ko.wikipedia.org/wiki/While_%EB%A3%A8%ED%94%84",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "동안 반복",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "다음까지 반복",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "값이 참일 때, 몇 가지 선언을 합니다.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "값이 거짓일 때, 몇 가지 선언을 합니다.",
                +	"CONTROLS_FOR_HELPURL": "https://ko.wikipedia.org/wiki/For_%EB%A3%A8%ED%94%84",
                +	"CONTROLS_FOR_TOOLTIP": "변수 \"%1\"은 지정된 간격으로 시작 수에서 끝 수까지를 세어 지정된 블록을 수행해야 합니다.",
                +	"CONTROLS_FOR_TITLE": "으로 계산 %1 %2에서 %4을 이용하여 %3로",
                +	"CONTROLS_FOREACH_HELPURL": "https://ko.wikipedia.org/wiki/For_%EB%A3%A8%ED%94%84#.EC.9E.84.EC.9D.98.EC.9D.98_.EC.A7.91.ED.95.A9",
                +	"CONTROLS_FOREACH_TITLE": "각 항목에 대해 %1 목록으로 %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "리스트 안에 들어있는 각 아이템들을, 순서대로 변수 '%1' 에 한 번씩 저장시키고, 그 때 마다 명령을 실행합니다.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://ko.wikipedia.org/wiki/%EC%A0%9C%EC%96%B4_%ED%9D%90%EB%A6%84",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "반복 중단",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "다음 반복",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "현재 반복 실행 블럭을 빠져나갑니다.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "나머지 반복 부분을 더 이상 실행하지 않고, 다음 반복을 수행합니다.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "경고 : 이 블록은 반복 실행 블럭 안에서만 사용됩니다.",
                +	"CONTROLS_IF_HELPURL": "https://ko.wikipedia.org/wiki/%EC%A1%B0%EA%B1%B4%EB%AC%B8",
                +	"CONTROLS_IF_TOOLTIP_1": "조건식의 계산 결과가 참이면, 명령을 실행합니다.",
                +	"CONTROLS_IF_TOOLTIP_2": "조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 그렇지 않으면 두 번째 블럭의 명령을 실행합니다.",
                +	"CONTROLS_IF_TOOLTIP_3": "첫 번째 조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 두 번째 조건식의 계산 결과가 참이면, 두 번째 블럭의 명령을 실행합니다.",
                +	"CONTROLS_IF_TOOLTIP_4": "첫 번째 조건식의 계산 결과가 참이면, 첫 번째 블럭의 명령을 실행하고, 두 번째 조건식의 계산 결과가 참이면, 두 번째 블럭의 명령을 실행하고, ... , 어떤 조건식의 계산 결과도 참이 아니면, 마지막 블럭의 명령을 실행합니다.",
                +	"CONTROLS_IF_MSG_IF": "만약",
                +	"CONTROLS_IF_MSG_ELSEIF": "다른 경우",
                +	"CONTROLS_IF_MSG_ELSE": "아니라면",
                +	"CONTROLS_IF_IF_TOOLTIP": "섹션을 추가, 제거하거나 순서를 변경하여 이 if 블럭을 재구성합니다.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "\"만약\" 블럭에 조건 검사를 추가합니다.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "\"만약\" 블럭의 마지막에, 모든 검사 결과가 거짓인 경우 실행할 부분을 추가합니다.",
                +	"IOS_OK": "확인",
                +	"IOS_CANCEL": "취소",
                +	"IOS_ERROR": "오류",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ 입력 추가",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "이 기능은 중복된 입력이 있습니다.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ 변수 추가",
                +	"IOS_VARIABLES_ADD_BUTTON": "추가",
                +	"IOS_VARIABLES_RENAME_BUTTON": "이름 바꾸기",
                +	"IOS_VARIABLES_DELETE_BUTTON": "삭제",
                +	"IOS_VARIABLES_VARIABLE_NAME": "변수 이름",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "비어있는 변수 이름을 사용할 수 없습니다.",
                +	"LOGIC_COMPARE_HELPURL": "https://ko.wikipedia.org/wiki/부등식",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "두 값이 같으면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "두 값이 서로 다르면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "첫 번째 값이 두 번째 값보다 작으면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "첫 번째 값이 두 번째 값보다 작거나 같으면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "첫 번째 값이 두 번째 값보다 크면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "첫 번째 값이 두 번째 값보다 크거나 같으면, 참(true) 값을 돌려줍니다.",
                +	"LOGIC_OPERATION_HELPURL": "https://ko.wikipedia.org/wiki/%EB%B6%88_%EB%85%BC%EB%A6%AC",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "두 값이 모두 참(true) 값이면, 참 값을 돌려줍니다.",
                +	"LOGIC_OPERATION_AND": "그리고",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "적어도 하나의 값이 참일 경우 참을 반환합니다.",
                +	"LOGIC_OPERATION_OR": "또는",
                +	"LOGIC_NEGATE_HELPURL": "https://ko.wikipedia.org/wiki/%EB%B6%80%EC%A0%95",
                +	"LOGIC_NEGATE_TITLE": "%1가 아닙니다",
                +	"LOGIC_NEGATE_TOOLTIP": "입력값이 거짓이라면 참을 반환합니다. 참이라면 거짓을 반환합니다.",
                +	"LOGIC_BOOLEAN_HELPURL": "https://ko.wikipedia.org/wiki/%EC%A7%84%EB%A6%BF%EA%B0%92",
                +	"LOGIC_BOOLEAN_TRUE": "참",
                +	"LOGIC_BOOLEAN_FALSE": "거짓",
                +	"LOGIC_BOOLEAN_TOOLTIP": "참 혹은 거짓 모두 반환합니다.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "빈 값",
                +	"LOGIC_NULL_TOOLTIP": "빈 값을 반환합니다.",
                +	"LOGIC_TERNARY_HELPURL": "https://ko.wikipedia.org/wiki/물음표",
                +	"LOGIC_TERNARY_CONDITION": "테스트",
                +	"LOGIC_TERNARY_IF_TRUE": "만약 참이라면",
                +	"LOGIC_TERNARY_IF_FALSE": "만약 거짓이라면",
                +	"LOGIC_TERNARY_TOOLTIP": "'test'의 조건을 검사합니다. 조건이 참이면 'if true' 값을 반환합니다. 거짓이면 'if false' 값을 반환합니다.",
                +	"MATH_NUMBER_HELPURL": "https://ko.wikipedia.org/wiki/수_(수학)",
                +	"MATH_NUMBER_TOOLTIP": "수",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "x",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://ko.wikipedia.org/wiki/산술",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "두 수의 합을 반환합니다.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "두 수간의 차이를 반환합니다.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "두 수의 곱을 반환합니다.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "두 수의 나눈 결과를 반환합니다.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "첫 번째 수를 두 번째 수 만큼, 거듭제곱 한 결과값을 돌려줍니다.",
                +	"MATH_SINGLE_HELPURL": "https://ko.wikipedia.org/wiki/제곱근",
                +	"MATH_SINGLE_OP_ROOT": "제곱근",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "숫자의 제곱근을 반환합니다.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "절대값",
                +	"MATH_SINGLE_TOOLTIP_ABS": "어떤 수의 절대값(absolute)을 계산한 결과를, 정수값으로 돌려줍니다.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "음(-)/양(+), 부호를 반대로 하여 값을 돌려줍니다.",
                +	"MATH_SINGLE_TOOLTIP_LN": "어떤 수의, 자연로그(natural logarithm) 값을 돌려줍니다.(밑 e, 예시 log e x)",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "어떤 수의, 기본로그(logarithm) 값을 돌려줍니다.(밑 10, 예시 log 10 x)",
                +	"MATH_SINGLE_TOOLTIP_EXP": "e의 거듭제곱 값을 반환합니다.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "10의 거듭제곱 값을 반환합니다.",
                +	"MATH_TRIG_HELPURL": "https://ko.wikipedia.org/wiki/삼각함수",
                +	"MATH_TRIG_TOOLTIP_SIN": "각도의 사인을 반환합니다. (라디안 아님)",
                +	"MATH_TRIG_TOOLTIP_COS": "각도의 코사인을 반환합니다. (라디안 아님)",
                +	"MATH_TRIG_TOOLTIP_TAN": "각도의 탄젠트를 반환합니다. (라디안 아님)",
                +	"MATH_TRIG_TOOLTIP_ASIN": "어떤 수에 대한, asin(arcsine) 값을 돌려줍니다.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "어떤 수에 대한, acos(arccosine) 값을 돌려줍니다.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "어떤 수에 대한, atan(arctangent) 값을 돌려줍니다.",
                +	"MATH_CONSTANT_HELPURL": "https://ko.wikipedia.org/wiki/수학_상수",
                +	"MATH_CONSTANT_TOOLTIP": "일반적인 상수 값들 중 하나를 돌려줍니다. : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "가 짝수(even) 이면",
                +	"MATH_IS_ODD": "가 홀수(odd) 이면",
                +	"MATH_IS_PRIME": "가 소수(prime) 이면",
                +	"MATH_IS_WHOLE": "가 정수이면",
                +	"MATH_IS_POSITIVE": "가 양(+)수 이면",
                +	"MATH_IS_NEGATIVE": "가 음(-)수 이면",
                +	"MATH_IS_DIVISIBLE_BY": "가 다음 수로 나누어 떨어지면 :",
                +	"MATH_IS_TOOLTIP": "어떤 수가 짝 수, 홀 수, 소 수, 정 수, 양 수, 음 수, 나누어 떨어지는 수 인지 검사해 결과값을 돌려줍니다. 참(true) 또는 거짓(false) 값을 돌려줌.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "바꾸기 %1 만큼 %2",
                +	"MATH_CHANGE_TOOLTIP": "변수 '%1' 에 저장되어있는 값에, 어떤 수를 더해, 변수에 다시 저장합니다.",
                +	"MATH_ROUND_HELPURL": "https://ko.wikipedia.org/wiki/반올림",
                +	"MATH_ROUND_TOOLTIP": "어떤 수를 반올림/올림/버림한 결과를, 정수값으로 돌려줍니다.",
                +	"MATH_ROUND_OPERATOR_ROUND": "반올림",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "올림",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "버림",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "합",
                +	"MATH_ONLIST_TOOLTIP_SUM": "리스트에 들어있는 수(값)들을, 모두 합(sum) 한, 총합(sum)을 돌려줍니다.",
                +	"MATH_ONLIST_OPERATOR_MIN": "최소값",
                +	"MATH_ONLIST_TOOLTIP_MIN": "리스트에 들어있는 수(값) 들 중, 가장 작은(min) 수(값)를 돌려줍니다.",
                +	"MATH_ONLIST_OPERATOR_MAX": "최대값",
                +	"MATH_ONLIST_TOOLTIP_MAX": "리스트에 들어있는 수(값) 들 중, 가장 큰(max) 수(값)를 돌려줍니다.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "평균값",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "리스트에 들어있는 수(값)들에 대해, 산술 평균(arithmetic mean) 한 값을 돌려줍니다.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "중간값",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "리스트에 들어있는 수(값) 들 중, 중간(median) 수(값)를 돌려줍니다.",
                +	"MATH_ONLIST_OPERATOR_MODE": "가장 여러 개 있는 값",
                +	"MATH_ONLIST_TOOLTIP_MODE": "리스트에 들어있는 아이템들 중에서, 가장 여러 번 들어있는 아이템들을 리스트로 만들어 돌려줍니다. (최빈값, modes)",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "표준 편차",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "이 리스트의 표준 편차를 반환합니다.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "목록의 임의 항목",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "목록에서 임의의 아이템을 돌려줍니다.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2의 나머지",
                +	"MATH_MODULO_TOOLTIP": "첫 번째 수를 두 번째 수로 나눈, 나머지 값을 돌려줍니다.",
                +	"MATH_CONSTRAIN_HELPURL": "https://ko.wikipedia.org/wiki/%ED%81%B4%EB%9E%A8%ED%95%91_(%EA%B7%B8%EB%9E%98%ED%94%BD)",
                +	"MATH_CONSTRAIN_TITLE": "%1의 값을, 최소 %2 최대 %3으로 조정",
                +	"MATH_CONSTRAIN_TOOLTIP": "어떤 수를, 특정 범위의 값이 되도록 강제로 조정합니다.",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "랜덤정수(%1<= n <=%2)",
                +	"MATH_RANDOM_INT_TOOLTIP": "두 주어진 제한된 범위 사이의 임의 정수값을 돌려줍니다.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "임의 분수",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0 (포함)과 1.0 (배타적) 사이의 임의 분수 값을 돌려줍니다.",
                +	"TEXT_TEXT_HELPURL": "https://ko.wikipedia.org/wiki/문자열",
                +	"TEXT_TEXT_TOOLTIP": "문자, 단어, 문장.",
                +	"TEXT_JOIN_HELPURL": "https://github.com/google/blockly/wiki/Text#text-creation",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "텍스트 만들기",
                +	"TEXT_JOIN_TOOLTIP": "여러 개의 아이템들을 연결해(묶어), 새로운 문장을 만듭니다.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "가입",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "섹션을 추가, 제거하거나 순서를 변경하여 이 텍스트 블럭을 재구성합니다.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "텍스트에 항목을 추가합니다.",
                +	"TEXT_APPEND_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_APPEND_TOOLTIP": "'%1' 변수의 끝에 일부 텍스트를 덧붙입니다.",
                +	"TEXT_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_LENGTH_TITLE": "다음 문장의 문자 개수 %1",
                +	"TEXT_LENGTH_TOOLTIP": "입력된 문장의, 문자 개수를 돌려줍니다.(공백문자 포함)",
                +	"TEXT_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Text#checking-for-empty-text",
                +	"TEXT_ISEMPTY_TITLE": "%1이 비어 있습니다",
                +	"TEXT_ISEMPTY_TOOLTIP": "입력된 문장이, 빈 문장(\"\")이면 참(true) 값을 돌려줍니다.",
                +	"TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text",
                +	"TEXT_INDEXOF_TOOLTIP": "두 번째 텍스트에서 첫 번째 텍스트가 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 텍스트가 없으면 %1을 반환합니다.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "에서 다음 문장이 처음으로 나타난 위치 찾기 :",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "에서 다음 문장이 마지막으로 나타난 위치 찾기 :",
                +	"TEXT_CHARAT_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-text",
                +	"TEXT_CHARAT_TITLE": "텍스트 %1 %2에서",
                +	"TEXT_CHARAT_FROM_START": "에서, 앞에서부터 # 번째 위치의 문자 얻기",
                +	"TEXT_CHARAT_FROM_END": "에서, 마지막부터 # 번째 위치의 문자 얻기",
                +	"TEXT_CHARAT_FIRST": "에서, 첫 번째 문자 얻기",
                +	"TEXT_CHARAT_LAST": "에서, 마지막 문자 얻기",
                +	"TEXT_CHARAT_RANDOM": "에서, 랜덤하게 한 문자 얻기",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "특정 번째 위치에서, 문자를 얻어내 돌려줍니다.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "문장 중 일부를 얻어내 돌려줍니다.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "문장",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "에서, 처음부터 # 번째 문자부터 얻어냄",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "에서, 마지막에서 # 번째부터 얻어냄",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "에서, 처음부터 얻어냄",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "# 번째 문자까지",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "끝에서부터 # 번째 문자까지",
                +	"TEXT_GET_SUBSTRING_END_LAST": "마지막 문자까지",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_HELPURL": "https://github.com/google/blockly/wiki/Text#adjusting-text-case",
                +	"TEXT_CHANGECASE_TOOLTIP": "영문 대소문자 형태를 변경해 돌려줍니다.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "대문자로",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "소문자로",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "첫 문자만 대문자로",
                +	"TEXT_TRIM_HELPURL": "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces",
                +	"TEXT_TRIM_TOOLTIP": "문장의 왼쪽/오른쪽/양쪽에서 스페이스 문자를 제거해 돌려줍니다.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "양쪽의 공백 문자 제거",
                +	"TEXT_TRIM_OPERATOR_LEFT": "왼쪽의 공백 문자 제거",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "오른쪽의 공백 문자 제거",
                +	"TEXT_PRINT_HELPURL": "https://github.com/google/blockly/wiki/Text#printing-text",
                +	"TEXT_PRINT_TITLE": "다음 내용 출력 %1",
                +	"TEXT_PRINT_TOOLTIP": "원하는 문장, 수, 값 등을 출력합니다.",
                +	"TEXT_PROMPT_HELPURL": "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user",
                +	"TEXT_PROMPT_TYPE_TEXT": "메시지를 활용해 문장 입력",
                +	"TEXT_PROMPT_TYPE_NUMBER": "메시지를 활용해 수 입력",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "수에 대해 사용자의 입력을 받습니다.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "문장에 대해 사용자의 입력을 받습니다.",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "빈 리스트 생성",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "데이터 레코드가 없는, 길이가 0인 목록을 반환합니다.",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "원하는 수의 항목들로 목록을 생성합니다.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "리스트 만들기",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "리스트",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "섹션을 추가, 제거하거나 순서를 변경하여 이 리스트 블럭을 재구성합니다.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "아이템을 리스트에 추가합니다.",
                +	"LISTS_REPEAT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_REPEAT_TOOLTIP": "원하는 값을, 원하는 갯수 만큼 넣어, 목록을 생성합니다.",
                +	"LISTS_REPEAT_TITLE": "%1을 %2번 넣어, 리스트 생성",
                +	"LISTS_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Lists#length-of",
                +	"LISTS_LENGTH_TITLE": "%1의 길이",
                +	"LISTS_LENGTH_TOOLTIP": "목록의 길이를 반환합니다.",
                +	"LISTS_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#is-empty",
                +	"LISTS_ISEMPTY_TITLE": "%1이 비어 있습니다",
                +	"LISTS_ISEMPTY_TOOLTIP": "목록이 비었을 때 참을 반환합니다.",
                +	"LISTS_INLIST": "리스트",
                +	"LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list",
                +	"LISTS_INDEX_OF_FIRST": "처음으로 나타난 위치",
                +	"LISTS_INDEX_OF_LAST": "마지막으로 나타난 위치",
                +	"LISTS_INDEX_OF_TOOLTIP": "목록에서 항목이 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 항목이 없으면 %1을 반환합니다.",
                +	"LISTS_GET_INDEX_GET": "가져오기",
                +	"LISTS_GET_INDEX_GET_REMOVE": "잘라 내기",
                +	"LISTS_GET_INDEX_REMOVE": "삭제",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "마지막 번째 위치부터, # 번째",
                +	"LISTS_GET_INDEX_FIRST": "첫 번째",
                +	"LISTS_GET_INDEX_LAST": "마지막",
                +	"LISTS_GET_INDEX_RANDOM": "임의로",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1은 첫 번째 항목입니다.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1은(는) 마지막 항목입니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "목록에서 특정 위치의 항목을 반환합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "첫 번째 아이템을 찾아 돌려줍니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "마지막 아이템을 찾아 돌려줍니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "리스트의 아이템들 중, 랜덤으로 선택해 돌려줍니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "목록의 특정 위치에 있는 항목을 제거하고 반환합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "첫 번째 아이템을 찾아내 돌려주고, 그 아이템을 리스트에서 삭제합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "마지막 아이템을 찾아내 돌려주고, 그 아이템을 리스트에서 삭제합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "목록에서 임의 위치의 아이템을 찾아내 삭제하고 돌려줍니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "목록에서 특정 위치의 항목을 삭제합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "리스트에서 첫 번째 아이템을 삭제합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "리스트에서 마지막 아이템을 찾아 삭제합니다.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "리스트에서 랜덤하게 아이템을 삭제합니다.",
                +	"LISTS_SET_INDEX_HELPURL": "https://github.com/google/blockly/wiki/Lists#in-list--set",
                +	"LISTS_SET_INDEX_SET": "에서 설정",
                +	"LISTS_SET_INDEX_INSERT": "에서 원하는 위치에 삽입",
                +	"LISTS_SET_INDEX_INPUT_TO": "에",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "목록의 특정 위치에 있는 항목으로 설정합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "첫 번째 위치의 아이템으로 설정합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "마지막 아이템으로 설정합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "목록에서 임의 위치의 아이템을 설정합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "목록의 특정 위치에 항목을 삽입합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "항목을 목록의 처음 위치에 삽입합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "리스트의 마지막에 아이템을 추가합니다.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "목록에서 임의 위치에 아이템을 삽입합니다.",
                +	"LISTS_GET_SUBLIST_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-a-sublist",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "처음 # 번째 위치부터, 서브 리스트 추출",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "마지막부터 # 번째 위치부터, 서브 리스트 추출",
                +	"LISTS_GET_SUBLIST_START_FIRST": "첫 번째 위치부터, 서브 리스트 추출",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "앞에서부터 # 번째로",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "끝에서부터 # 번째로",
                +	"LISTS_GET_SUBLIST_END_LAST": "마지막으로",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "목록의 특정 부분에 대한 복사본을 만듭니다.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "정렬 %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "목록의 사본을 정렬합니다.",
                +	"LISTS_SORT_ORDER_ASCENDING": "오름차순",
                +	"LISTS_SORT_ORDER_DESCENDING": "내림차순",
                +	"LISTS_SORT_TYPE_NUMERIC": "숫자순",
                +	"LISTS_SORT_TYPE_TEXT": "알파벳순",
                +	"LISTS_SORT_TYPE_IGNORECASE": "알파벳순 (대소문자 구분 안 함)",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "텍스트에서 목록 만들기",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "목록에서 텍스트 만들기",
                +	"LISTS_SPLIT_WITH_DELIMITER": "분리와",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "각 속보, 텍스트의 목록들에서 텍스트를 분할합니다.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "구분 기호로 구분하여 텍스트 목록을 하나의 텍스트에 병합합니다.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_HELPURL": "https://ko.wikipedia.org/wiki/%EB%B3%80%EC%88%98_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)",
                +	"VARIABLES_GET_TOOLTIP": "변수에 저장 되어있는 값을 돌려줍니다.",
                +	"VARIABLES_GET_CREATE_SET": "'집합 %1' 생성",
                +	"VARIABLES_SET_HELPURL": "https://ko.wikipedia.org/wiki/%EB%B3%80%EC%88%98_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)",
                +	"VARIABLES_SET": "%1를 %2로 설정",
                +	"VARIABLES_SET_TOOLTIP": "변수의 값을 입력한 값으로 변경해 줍니다.",
                +	"VARIABLES_SET_CREATE_GET": "'%1 값 읽기' 블럭 생성",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "함수",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "함수 이름",
                +	"PROCEDURES_BEFORE_PARAMS": "사용:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "사용:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "실행 후, 결과 값을 돌려주지 않는 함수를 만듭니다.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "이 함수를 설명하세요...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "다음을 돌려줌",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "실행 후, 결과 값을 돌려주는 함수를 만듭니다.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "서술 허가",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "경고: 이 함수에는, 같은 이름을 사용하는 매개 변수들이 있습니다.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ko.wikipedia.org/wiki/함수_(프로그래밍)",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "미리 정의해 둔 '%1' 함수를 실행합니다.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ko.wikipedia.org/wiki/함수_(프로그래밍)",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "미리 정의해 둔 '%1' 함수를 실행하고, 함수를 실행한 결과 값을 돌려줍니다.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "매개 변수들",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "이 함수를 추가, 삭제, 혹은 재정렬합니다.",
                +	"PROCEDURES_MUTATORARG_TITLE": "매개 변수:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "함수에 값을 더합니다.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "함수 정의 찾기",
                +	"PROCEDURES_CREATE_DO": "'%1' 생성",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "값이 참이라면, 두 번째 값을 반환합니다.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "경고: 이 블럭은, 함수 정의 블럭 안에서만 사용할 수 있습니다."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/lb.json b/blockly/webif/static/blockly/msg/json/lb.json
                new file mode 100644
                index 000000000..029ac9572
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/lb.json
                @@ -0,0 +1,141 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Robby",
                +			"Soued031",
                +			"Les Meloures"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "Element",
                +	"TODAY": "Haut",
                +	"DUPLICATE_BLOCK": "Eng Kopie maachen",
                +	"ADD_COMMENT": "Bemierkung derbäisetzen",
                +	"REMOVE_COMMENT": "Bemierkung ewechhuelen",
                +	"DELETE_BLOCK": "Block läschen",
                +	"DELETE_X_BLOCKS": "%1 Bléck läschen",
                +	"CLEAN_UP": "Bléck opraumen",
                +	"COLLAPSE_BLOCK": "Block zesummeklappen",
                +	"COLLAPSE_ALL": "Bléck zesummeklappen",
                +	"EXPAND_BLOCK": "Block opklappen",
                +	"EXPAND_ALL": "Bléck opklappen",
                +	"DISABLE_BLOCK": "Block desaktivéieren",
                +	"ENABLE_BLOCK": "Block aktivéieren",
                +	"HELP": "Hëllef",
                +	"UNDO": "Réckgängeg maachen",
                +	"REDO": "Widderhuelen",
                +	"CHANGE_VALUE_TITLE": "Wäert änneren:",
                +	"RENAME_VARIABLE": "Variabel ëmbenennen...",
                +	"RENAME_VARIABLE_TITLE": "All '%1' Variabelen ëmbenennen op:",
                +	"NEW_VARIABLE": "Variabel uleeën...",
                +	"NEW_VARIABLE_TITLE": "Neie variabelen Numm:",
                +	"PROCEDURE_ALREADY_EXISTS": "Et gëtt schonn eng Prozedur mam Numm '%1'.",
                +	"COLOUR_PICKER_TOOLTIP": "Sicht eng Faarf an der Palette eraus.",
                +	"COLOUR_RANDOM_TITLE": "zoufälleg Faarf",
                +	"COLOUR_RANDOM_TOOLTIP": "Eng zoufälleg Faarf eraussichen.",
                +	"COLOUR_RGB_TITLE": "fierwe mat",
                +	"COLOUR_RGB_RED": "rout",
                +	"COLOUR_RGB_GREEN": "gréng",
                +	"COLOUR_RGB_BLUE": "blo",
                +	"COLOUR_BLEND_TITLE": "mëschen",
                +	"COLOUR_BLEND_COLOUR1": "Faarf 1",
                +	"COLOUR_BLEND_COLOUR2": "Faarf 2",
                +	"COLOUR_BLEND_RATIO": "ratio",
                +	"CONTROLS_REPEAT_TITLE": "%1-mol widderhuelen",
                +	"CONTROLS_REPEAT_INPUT_DO": "maach",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "Widderhuel soulaang",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "widderhuele bis",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Féiert d'Uweisungen aus, soulaang wéi de Wäert richteg ass",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Féiert d'Uweisungen aus, soulaang wéi de Wäert falsch ass.",
                +	"CONTROLS_FOR_TITLE": "zielt mat %1 vun %2 bis %3 mat %4",
                +	"CONTROLS_FOREACH_TITLE": "fir all Element %1 an der Lëscht %2",
                +	"CONTROLS_IF_MSG_IF": "wann",
                +	"CONTROLS_IF_MSG_ELSE": "soss",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Ofbriechen",
                +	"IOS_ERROR": "Feeler",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Variabel derbäisetzen",
                +	"IOS_VARIABLES_ADD_BUTTON": "Derbäisetzen",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Ëmbenennen",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Läschen",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Numm vun der Variabel",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Dir kënnt keen eidelen Numm fir eng Variabel benotzen.",
                +	"LOGIC_OPERATION_AND": "an",
                +	"LOGIC_OPERATION_OR": "oder",
                +	"LOGIC_NEGATE_TITLE": "net %1",
                +	"LOGIC_BOOLEAN_TRUE": "wouer",
                +	"LOGIC_BOOLEAN_FALSE": "falsch",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Schéckt entweder richteg oder falsch zréck.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "Test",
                +	"LOGIC_TERNARY_IF_TRUE": "wa wouer",
                +	"LOGIC_TERNARY_IF_FALSE": "wa falsch",
                +	"MATH_NUMBER_TOOLTIP": "Eng Zuel.",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Den Total vun den zwou Zuelen zréckginn.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "D'Produkt vun den zwou Zuelen zréckginn.",
                +	"MATH_SINGLE_HELPURL": "https://lb.wikipedia.org/wiki/Racine carrée",
                +	"MATH_SINGLE_OP_ROOT": "Quadratwuerzel",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_IS_EVEN": "ass gerued",
                +	"MATH_IS_ODD": "ass ongerued",
                +	"MATH_IS_PRIME": "ass eng Primzuel",
                +	"MATH_IS_WHOLE": "ass eng ganz Zuel",
                +	"MATH_IS_POSITIVE": "ass positiv",
                +	"MATH_IS_NEGATIVE": "ass negativ",
                +	"MATH_CHANGE_TITLE": "änneren %1 ëm %2",
                +	"MATH_ROUND_TOOLTIP": "Eng Zuel op- oder ofrënnen.",
                +	"MATH_ROUND_OPERATOR_ROUND": "opronnen",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "oprënnen",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ofrënnen",
                +	"MATH_ONLIST_OPERATOR_MAX": "Maximum aus der Lëscht",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Schéckt de gréisste Wäert aus enger Lëscht zréck.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "Moyenne vun der Lëscht",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "zoufällegt Element vun enger Lëscht",
                +	"MATH_MODULO_TITLE": "Rescht vu(n) %1 ÷ %2",
                +	"MATH_RANDOM_INT_TITLE": "zoufälleg ganz Zuel tëscht %1 a(n) %2",
                +	"TEXT_TEXT_TOOLTIP": "E Buschtaf, e Wuert oder eng Textzeil.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "En Element bei den Text derbäisetzen.",
                +	"TEXT_LENGTH_TITLE": "Längt vu(n) %1",
                +	"TEXT_ISEMPTY_TITLE": "%1 ass eidel",
                +	"TEXT_INDEXOF_TITLE": "am Text %1 %2 %3",
                +	"TEXT_CHARAT_TITLE": "am Text %1 %2",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "am Text",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "bis bei de Buschtaf #",
                +	"TEXT_GET_SUBSTRING_END_LAST": "bis bei de leschte Buschtaw",
                +	"TEXT_PRINT_TITLE": "%1 drécken",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Frot de Benotzer no engem Text.",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_REPLACE_MESSAGE0": "%1 duerch %2 a(n) %3 ersetzen",
                +	"TEXT_REPLACE_TOOLTIP": "All Kéiers wou e bestëmmten Text do ass duerch en aneren Text ersetzen.",
                +	"TEXT_REVERSE_TOOLTIP": "Dréint d'Reiefolleg vun den Zeechen am Text ëm.",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "Lëscht",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "En Element op d'Lëscht derbäisetzen.",
                +	"LISTS_LENGTH_TITLE": "Längt vu(n) %1",
                +	"LISTS_ISEMPTY_TITLE": "%1 ass eidel",
                +	"LISTS_INLIST": "an der Lëscht",
                +	"LISTS_GET_INDEX_REMOVE": "ewechhuelen",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# vun hannen",
                +	"LISTS_GET_INDEX_FIRST": "éischt",
                +	"LISTS_GET_INDEX_LAST": "lescht",
                +	"LISTS_GET_INDEX_RANDOM": "Zoufall",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ass dat éischt Element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ass dat éischt Element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Schéckt en zoufällegt Element aus enger Lëscht zréck.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Hëlt dat lescht Element aus enger Lëscht eraus.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Hëlt en zoufällegt Element aus enger Lëscht eraus.",
                +	"LISTS_SET_INDEX_INSERT": "asetzen op",
                +	"LISTS_SET_INDEX_INPUT_TO": "als",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Setzt en zoufällegt Element an eng Lëscht.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Setzt d'Element um Enn vun enger Lëscht derbäi.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Setzt d'Element op eng zoufälleg Plaz an d'Lëscht derbäi.",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeresch",
                +	"LISTS_SORT_TYPE_TEXT": "alphabetesch",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "%1 ëmdréinen",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "eppes maachen",
                +	"PROCEDURES_BEFORE_PARAMS": "mat:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "mat:",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Dës Funktioun beschreiwen...",
                +	"PROCEDURES_DEFRETURN_RETURN": "zréck"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/lki.json b/blockly/webif/static/blockly/msg/json/lki.json
                new file mode 100644
                index 000000000..4aa5c8c8b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/lki.json
                @@ -0,0 +1,292 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Hosseinblue",
                +			"Lakzon"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "آیتم",
                +	"TODAY": "ایمڕۆ",
                +	"DUPLICATE_BLOCK": "کؤپی کردن",
                +	"ADD_COMMENT": "گةپ دائن",
                +	"REMOVE_COMMENT": "پاک کردن گةپةل/قِسةل",
                +	"EXTERNAL_INPUTS": "ورودیةل خروجی",
                +	"INLINE_INPUTS": "ورودیةل نوم جا",
                +	"DELETE_BLOCK": "پاک کردن بلاک",
                +	"DELETE_X_BLOCKS": "حةذف %1 بلاکةل",
                +	"DELETE_ALL_BLOCKS": "حةذف کؤل %1 بلاکةل?",
                +	"CLEAN_UP": "تمیزکردن بلاکةل",
                +	"COLLAPSE_BLOCK": "چؤیچانن/پشکانن بلاک",
                +	"COLLAPSE_ALL": "چؤیچانن/پشکانن بلاکةل",
                +	"EXPAND_BLOCK": "کةلنگآ کردِن بلاک",
                +	"EXPAND_ALL": "کةلنگآ کردِن بلاکةل",
                +	"DISABLE_BLOCK": "إ کار کةتن(غیرفعال‌سازی) بلاک",
                +	"ENABLE_BLOCK": "إ کارآشتن(فعال)بلاک",
                +	"HELP": "کؤمةک",
                +	"CHANGE_VALUE_TITLE": "تةغییر مقدار:",
                +	"RENAME_VARIABLE": "تغییر نام متغیر...",
                +	"RENAME_VARIABLE_TITLE": "تغییر نام همهٔ متغیرهای «%1» به:",
                +	"NEW_VARIABLE": "متغیر تازه...",
                +	"NEW_VARIABLE_TITLE": "نام متغیر تازه:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/رةنگ",
                +	"COLOUR_PICKER_TOOLTIP": "رةنگێ إژ تةختة رةنگ انتخاب کةن",
                +	"COLOUR_RANDOM_TITLE": "رةنگ بةختةکی",
                +	"COLOUR_RANDOM_TOOLTIP": ".رةنگئ بةختةکی انتخاب کةن",
                +	"COLOUR_RGB_TITLE": "رةنگ وة",
                +	"COLOUR_RGB_RED": "سۆر",
                +	"COLOUR_RGB_GREEN": "سؤز",
                +	"COLOUR_RGB_BLUE": "کاوو",
                +	"COLOUR_RGB_TOOLTIP": "ساخت یک رنگ با مقدار مشخص‌شده‌ای از سۆر، سؤز و کاوو. همهٔ مقادیر باید بین ۰ تا ۱۰۰ باشند.",
                +	"COLOUR_BLEND_TITLE": "قاتی پاتی",
                +	"COLOUR_BLEND_COLOUR1": "رةنگ 1",
                +	"COLOUR_BLEND_COLOUR2": "رةنگ 2",
                +	"COLOUR_BLEND_RATIO": "نسبت",
                +	"COLOUR_BLEND_TOOLTIP": "دو رنگ را با نسبت مشخص‌شده مخلوط می‌کند (۰٫۰ - ۱٫۰)",
                +	"CONTROLS_REPEAT_HELPURL": "https://lki.wikipedia.org/wiki/حلقه_فور",
                +	"CONTROLS_REPEAT_TITLE": "%بار تکرار 1",
                +	"CONTROLS_REPEAT_INPUT_DO": "انجوم بی",
                +	"CONTROLS_REPEAT_TOOLTIP": "انجام چةن عبارت چندین گِل.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "تکرار در حالی که",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "تکرار تا وةختێ گإ",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "تا زمانی که یک مقدار صحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "تا زمانی که یک مقدار ناصحیح است، چند عبارت را انجام بده.",
                +	"CONTROLS_FOR_TOOLTIP": "متغیر %1 را در مقادیر شروع‌شده از عدد انتهای  به عدد انتهایی را دارد، با فواصل مشخص‌شده می‌شمارد و این بلوک مشخص‌شده را انجام می‌دهد.",
                +	"CONTROLS_FOR_TITLE": "با تعداد %1 از %2 به %3 با گام‌های %4",
                +	"CONTROLS_FOREACH_TITLE": "ئةرا هر مورد %1 وۀ نام لیست%2",
                +	"CONTROLS_FOREACH_TOOLTIP": "برای هر مورد در این فهرست، تنظیم متغیر «%1» به مورد و انجام تعدادی عبارت.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "شکانِن حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ادامه با تکرار بعدی حلقه",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "شکستن حلقهٔ شامل.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "پریدن از بقیهٔ حلقه و ادامه با تکرار بعدی.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "اخطار: این بلوک ممکن است فقط داخل یک حلقه استفاده شود.",
                +	"CONTROLS_IF_TOOLTIP_1": "اگر یک مقدار صحیح است، سپس چند عبارت را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_2": "اگر یک مقدار صحیح است، اول بلوک اول عبارات را انجام بده.  در غیر این صورت بلوک دوم عبارات انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_3": "اگر مقدار اول صحیح بود، از آن بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم صحیح است، بلوک دوم عبارات را انجام بده.",
                +	"CONTROLS_IF_TOOLTIP_4": "اگر مقدار اول درست است، بلوک اول عبارات را انجام بده.  در غیر این صورت، اگر مقدار دوم درست باشد بلوک دوم عبارات را انجام بده.  اگر هیچ از مقادیر درست نبود، آخرین بلوک عبارات را انجام بده.",
                +	"CONTROLS_IF_MSG_IF": "اگر",
                +	"CONTROLS_IF_MSG_ELSEIF": "اگر آنگاه",
                +	"CONTROLS_IF_MSG_ELSE": "آنگاه",
                +	"CONTROLS_IF_IF_TOOLTIP": "افزودن، حذف یا بازمرتب‌سازی قسمت‌ها برای پیکربندی دوبارهٔ این بلوک اگر.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "افزودن یک شرط به بلوک اگر.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "اضافه‌کردن نهایی، گرفتن همهٔ شرایط به بلوک اگر.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "بازگشت صحیح اگر هر دو ورودی با یکدیگر برابر باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "برگرداندن صحیح اگر هر دو ورودی با یکدیگر برابر نباشند.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "بازگرداندن صحیح اگر ورودی اول کوچکتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "بازگرداندن صحیح اگر ورودی اول کوچکتر یا مساوی با ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "بازگرداندن صحیح اگر ورودی اول بزرگتر از ورودی دوم باشد.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "بازگرداندن صحیح اگر ورودی اول بزرگتر یا مساوی یا ورودی دوم باشد.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "بازگرداندن صحیح اگر هر دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_AND": "و",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "بازگرداندن صحیح اگر یکی از دو ورودی صحیح باشد.",
                +	"LOGIC_OPERATION_OR": "یا",
                +	"LOGIC_NEGATE_TITLE": "نه %1",
                +	"LOGIC_NEGATE_TOOLTIP": "صجیج باز می‌گرداند اگر ورودی نا صحیح باشند. ناصحیح بازمی‌گرداند اگر ورودی صحیح باشد.",
                +	"LOGIC_BOOLEAN_TRUE": "درست",
                +	"LOGIC_BOOLEAN_FALSE": "نادرست",
                +	"LOGIC_BOOLEAN_TOOLTIP": "بازگرداندن یکی از صحیح یا ناصحیح.",
                +	"LOGIC_NULL": "پةتی/خالی",
                +	"LOGIC_NULL_TOOLTIP": "تهی باز می گرداند",
                +	"LOGIC_TERNARY_CONDITION": "آزمائشت",
                +	"LOGIC_TERNARY_IF_TRUE": "اگر درست",
                +	"LOGIC_TERNARY_IF_FALSE": "اگر نادرست",
                +	"LOGIC_TERNARY_TOOLTIP": "بررسی وضعیت در «آزمایش». اگر وضعیت صحیح باشد، مقدار «اگر صحیح» را بر می‌گرداند در غیر اینصورت مقدار «اگر ناصحیح» را.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "شؤمارە یەک",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "بازگرداندن مقدار جمع دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "بازگرداندن تفاوت دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "بازگرداندن حاصلضرب دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "بازگرداندن باقی‌ماندهٔ دو عدد.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "بازگرداندن اولین عددی که از توان عدد دوم حاصل شده باشد.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "ریشهٔ دوم",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ریشهٔ دوم یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "مطلق",
                +	"MATH_SINGLE_TOOLTIP_ABS": "قدر مطلق یک عدد را بازمی‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "منفی‌شدهٔ یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LN": "لوگاریتم طبیعی یک عدد را باز می‌گرداند.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "بازگرداندن لگاریتم بر پایهٔ ۱۰ یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "بازگرداندن توان e یک عدد.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "بازگرداندن توان ۱۰ یک عدد.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "بازگرداندن سینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_COS": "بازگرداندن کسینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_TAN": "بازگرداندن تانژانت یک درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ASIN": ".(بازگرداندن آرک‌سینوس درجه (نه رادیان",
                +	"MATH_TRIG_TOOLTIP_ACOS": "بازگرداندن آرک‌کسینوس درجه (نه رادیان).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "بازگرداندن آرک‌تانژانت درجه (نه رادیان).",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "یکی از مقادیر مشترک را برمی‌گرداند: π (۳٫۱۴۱…)، e (۲٫۷۱۸...)، φ (۱٫۶۱۸)، sqrt(۲) (۱٫۴۱۴)، sqrt(۱/۲) (۰٫۷۰۷...) و یا ∞ (بی‌نهایت).",
                +	"MATH_IS_EVEN": "زوج است",
                +	"MATH_IS_ODD": "فرد است",
                +	"MATH_IS_PRIME": "عدد اول است",
                +	"MATH_IS_WHOLE": "کامل است",
                +	"MATH_IS_POSITIVE": "مثبت است",
                +	"MATH_IS_NEGATIVE": "منفی است",
                +	"MATH_IS_DIVISIBLE_BY": "تقسیم شده بر",
                +	"MATH_IS_TOOLTIP": "بررسی می‌کند که آیا یک عدد زوج، فرد، اول، کامل، مثبت، منفی یا بخش‌پذیر عدد خاصی باشد را بررسی می‌کند. درست یا نادرست باز می‌گرداند.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "تغییر %1 با %2",
                +	"MATH_CHANGE_TOOLTIP": "افزودن یک عدد به متغیر '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "گردکردن یک عدد به بالا یا پایین.",
                +	"MATH_ROUND_OPERATOR_ROUND": "گردکردن",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "گرد به بالا",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "گرد به پایین",
                +	"MATH_ONLIST_OPERATOR_SUM": "جمع لیست",
                +	"MATH_ONLIST_TOOLTIP_SUM": "جمع همهٔ عددهای فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MIN": "گوجةرتةرین لیست",
                +	"MATH_ONLIST_TOOLTIP_MIN": "کوچک‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MAX": "بزرگ‌ترین فهرست",
                +	"MATH_ONLIST_TOOLTIP_MAX": "بزرگ‌ترین عدد در فهرست را باز می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "میانگین فهرست",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "میانگین (میانگین ریاضی) مقادیر عددی فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "میانهٔ فهرست",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "میانهٔ عدد در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_MODE": "مد فهرست",
                +	"MATH_ONLIST_TOOLTIP_MODE": "شایع‌ترین قلم(های) در فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "انحراف معیار فهرست",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "انحراف معیار فهرست را بر می‌گرداند.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "مورد تصادفی از فهرست",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "موردی تصادفی از فهرست را بر می‌گرداند.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "باقی‌ماندهٔ %1 + %2",
                +	"MATH_MODULO_TOOLTIP": "باقی‌ماندهٔ تقسیم دو عدد را بر می‌گرداند.",
                +	"MATH_CONSTRAIN_TITLE": "محدودکردن %1 پایین %2 بالا %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "محدودکردن یک عدد بین محدودیت‌های مشخص‌شده (بسته).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "عدد صحیح تصادفی بین %1 تا %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "یک عدد تصادفی بین دو مقدار مشخص‌شده به صورت بسته باز می‌گرداند.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "کسر تصادفی",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "بازگرداندن کسری تصادفی بین ۰٫۰ (بسته) تا ۱٫۰ (باز).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "یک حرف، کلمه یا خطی از متن.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ایجاد متن با",
                +	"TEXT_JOIN_TOOLTIP": "یک تکه‌ای از متن را با چسپاندن همهٔ تعداد از موارد ایجاد می‌کند.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "نام نؤیسی",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "اضافه‌کردن، حذف یا مرتب‌سازی بحش‌ها برای تنظیم مجدد این بلوک متنی.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "افزودن یک مورد به متن.",
                +	"TEXT_APPEND_TOOLTIP": "الحاق متنی به متغیر «%1».",
                +	"TEXT_LENGTH_TITLE": "طول %1",
                +	"TEXT_LENGTH_TOOLTIP": "بازگرداندن عددی از حروف (شامل فاصله‌ها) در متن فراهم‌شده.",
                +	"TEXT_ISEMPTY_TITLE": "%1 خالی است",
                +	"TEXT_ISEMPTY_TOOLTIP": "اضافه‌کردن صحیح اگر متن فراهم‌شده خالی است.",
                +	"TEXT_INDEXOF_TOOLTIP": "شاخصی از اولین آخرین رخ‌داد متن اول در متن دوم بر می‌گرداند. اگر متن یافت نشد %1 باز می‌گرداند.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "اولین رخداد متن را بیاب",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "آخرین رخداد متن را بیاب",
                +	"TEXT_CHARAT_FROM_START": "گرفتن حرف #",
                +	"TEXT_CHARAT_FROM_END": "گرفتن حرف # از آخر",
                +	"TEXT_CHARAT_FIRST": "گرفتن اولین حرف",
                +	"TEXT_CHARAT_LAST": "گرفتن آخرین حرف",
                +	"TEXT_CHARAT_RANDOM": "گرفتن حرف تصادفی",
                +	"TEXT_CHARAT_TOOLTIP": "حرفی در موقعیت مشخص‌شده بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "قسمت مشخصی‌شده‌ای از متن را بر می‌گرداند.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "در متن",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "گرفتن زیرمتن از حرف #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "گرفتن زیرمتن از حرف # به انتها",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "گرفتن زیرمتن از اولین حرف",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "به حرف #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "به حرف # از انتها",
                +	"TEXT_GET_SUBSTRING_END_LAST": "به آخرین حرف",
                +	"TEXT_CHANGECASE_TOOLTIP": "بازگرداندن کپی متن در حالتی متفاوت.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "به حروف بزرگ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "به حروف کوچک",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "به حروف بزرگ عنوان",
                +	"TEXT_TRIM_TOOLTIP": "کپی از متن با فاصله‌های حذف‌شده از یک یا هر دو پایان باز می‌گرداند.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "تراشیدن فاصله‌ها از  هر دو طرف",
                +	"TEXT_TRIM_OPERATOR_LEFT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "تراشیدن فاصله‌ها از  طرف چپ",
                +	"TEXT_PRINT_TITLE": "چاپ %1",
                +	"TEXT_PRINT_TOOLTIP": "چاپ متن، عدد یا هر مقدار دیگر مشخص‌شده.",
                +	"TEXT_PROMPT_TYPE_TEXT": "اعلان برای متن با پیام",
                +	"TEXT_PROMPT_TYPE_NUMBER": "اعلان برای عدد با پیام",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "اعلان برای کاربر با یک عدد.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "اعلان برای کاربر برای یک متن.",
                +	"LISTS_CREATE_EMPTY_TITLE": "ایجاد فهرست خالی",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "فهرستی با طول صفر شامل هیچ رکورد داده‌ای بر می‌گرداند.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "فهرستی از هر عددی از موارد می‌سازد.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "ایجاد فهرست با",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "لیست",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "اضافه‌کردن، حذف‌کردن یا ترتیب‌سازی مجدد بخش‌ها این بلوک فهرستی.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "اضافه‌کردن یک مورد به فهرست.",
                +	"LISTS_REPEAT_TOOLTIP": "فهرستی شامل مقادیر داده‌شدهٔ تکرار شده عدد مشخص‌شده می‌سازد.",
                +	"LISTS_REPEAT_TITLE": "فهرستی با %1 تکرارشده به اندازهٔ %2 می‌سازد",
                +	"LISTS_LENGTH_TITLE": "طول %1",
                +	"LISTS_LENGTH_TOOLTIP": "طول یک فهرست را برمی‌گرداند.",
                +	"LISTS_ISEMPTY_TITLE": "%1 خالی است",
                +	"LISTS_ISEMPTY_TOOLTIP": "اگر فهرست خالی است مقدار صجیج بر می‌گرداند.",
                +	"LISTS_INLIST": "در فهرست",
                +	"LISTS_INDEX_OF_FIRST": "یافتن اولین رخ‌داد مورد",
                +	"LISTS_INDEX_OF_LAST": "یافتن آخرین رخ‌داد مورد",
                +	"LISTS_INDEX_OF_TOOLTIP": "شاخصی از اولین/آخرین رخ‌داد مورد در فهرست را بر می‌گرداند. %1 بر می‌گرداند اگر آیتم موجود نبود.",
                +	"LISTS_GET_INDEX_GET": "گِرتِن",
                +	"LISTS_GET_INDEX_GET_REMOVE": "گِرتِن و حةذف کردن",
                +	"LISTS_GET_INDEX_REMOVE": "حةذف کردن",
                +	"LISTS_GET_INDEX_FROM_END": "# إژ دؤما آخر",
                +	"LISTS_GET_INDEX_FIRST": "إژ أؤةل",
                +	"LISTS_GET_INDEX_LAST": "دؤمائن/آخرین",
                +	"LISTS_GET_INDEX_RANDOM": "بةختةکی",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 اولین مورد است.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 آخرین مورد است.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "موردی در محل مشخص‌شده بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "اولین مورد یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "آخرین مورد در یک فهرست را بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "یک مورد تصادفی در یک فهرست بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "مورد در محل مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "اولین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "آخرین مورد مشخص‌شده در فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "مورد تصادفی‌ای را در فهرست حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "مورد مشخص‌شده در موقعیت مشخص در یک فهرست را حذف و بر می‌گرداند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "اولین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "آخرین مورد را در یک فهرست حذف می‌کند.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "یک مورد تصادفی را یک فهرست حذف می‌کند.",
                +	"LISTS_SET_INDEX_SET": "مجموعه",
                +	"LISTS_SET_INDEX_INSERT": "درج در",
                +	"LISTS_SET_INDEX_INPUT_TO": "به عنوان",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "مورد مشخص‌شده در یک فهرست را قرار می‌دهد.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "اولین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "آخرین مورد در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "یک مورد تصادفی در یک فهرست را تعیین می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "موردی در موقعیت مشخص‌شده در یک فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "موردی به ته فهرست اضافه می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "موردی به ته فهرست الحاق می‌کند.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "مورد را به صورت تصادفی در یک فهرست می‌افزاید.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "گرفتن زیرمجموعه‌ای از #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "گرفتن زیرمجموعه‌ای از # از انتها",
                +	"LISTS_GET_SUBLIST_START_FIRST": "گرفتن زیرمجموعه‌ای از ابتدا",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "به #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "به # از انتها",
                +	"LISTS_GET_SUBLIST_END_LAST": "به آخرین",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "کپی از قسمت مشخص‌شدهٔ لیست درست می‌کند.",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "ساخت لیست إژ متن",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "ساخت متن إژ لیست",
                +	"LISTS_SPLIT_WITH_DELIMITER": "همراه جداساز",
                +	"VARIABLES_GET_TOOLTIP": "مقدار این متغیر را بر می‌گرداند.",
                +	"VARIABLES_GET_CREATE_SET": "درست‌کردن «تنظیم %1»",
                +	"VARIABLES_SET": "مجموعه %1 به %2",
                +	"VARIABLES_SET_TOOLTIP": "متغیر برابر با خروجی را مشخص می‌کند.",
                +	"VARIABLES_SET_CREATE_GET": "درست‌کردن «گرفتن %1»",
                +	"PROCEDURES_DEFNORETURN_TITLE": "به",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "انجام چیزی",
                +	"PROCEDURES_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "با:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "تابعی می‌سازد بدون هیچ خروجی.",
                +	"PROCEDURES_DEFRETURN_RETURN": "بازگشت",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "تابعی با یک خروجی می‌سازد.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "اجازه اظهارات",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "اخطار: این تابعی پارامتر تکراری دارد.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1».",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "اجرای تابع تعریف‌شده توسط کاربر «%1» و استفاده از خروجی آن.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ورودی‌ها",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "افزودن، حذف یا دوباره مرتب‌کردن ورودی این تابع.",
                +	"PROCEDURES_MUTATORARG_TITLE": "نام ورودی:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "اضافه کردن ورودی به تابع.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "برجسته‌سازی تعریف تابع",
                +	"PROCEDURES_CREATE_DO": "ساختن «%1»",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "اگر یک مقدار صحیح است، مقدار دوم را برگردان.",
                +	"PROCEDURES_IFRETURN_WARNING": "اخطار: این بلوک احتمالاً فقط داخل یک تابع استفاده می‌شود."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/lrc.json b/blockly/webif/static/blockly/msg/json/lrc.json
                new file mode 100644
                index 000000000..81d49bb55
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/lrc.json
                @@ -0,0 +1,130 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Mogoeilor"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "قلم",
                +	"TODAY": "ئمروٙ",
                +	"DUPLICATE_BLOCK": "کپی کردن",
                +	"ADD_COMMENT": "نظرتونه اضاف بکید",
                +	"REMOVE_COMMENT": "نظر جا وه جا کو",
                +	"EXTERNAL_INPUTS": "داده یا وه دری",
                +	"INLINE_INPUTS": "داده یا مئنجا",
                +	"DELETE_BLOCK": "پاکسا کردن برشت",
                +	"DELETE_X_BLOCKS": "پاکسا کردن%1 د برشتیا",
                +	"COLLAPSE_BLOCK": "کوچک کردن برشت",
                +	"COLLAPSE_ALL": "کوچک کردن برشتیا",
                +	"EXPAND_BLOCK": "گپ کردن برشت",
                +	"EXPAND_ALL": "گپ کردن برشتیا",
                +	"DISABLE_BLOCK": "ناکشتگر کردن برشت",
                +	"ENABLE_BLOCK": "کنشتگر کردن برشت",
                +	"HELP": "هومياری",
                +	"CHANGE_VALUE_TITLE": "ارزشت آلشت کو:",
                +	"RENAME_VARIABLE": "د نو نوم نیائن آلشتگر...",
                +	"RENAME_VARIABLE_TITLE": "د نو نوم نیائن %1 د تموم آلشتگریا د:",
                +	"NEW_VARIABLE": "آلشتگر تازه...",
                +	"NEW_VARIABLE_TITLE": "نوم آلشتگر تازه:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "یه رن د رنگ دو انتخاو بکید",
                +	"COLOUR_RANDOM_TITLE": "رن بختکی",
                +	"COLOUR_RANDOM_TOOLTIP": "یه رنگ بختکی انتخاو بکید",
                +	"COLOUR_RGB_TITLE": "رن وا",
                +	"COLOUR_RGB_RED": "سور",
                +	"COLOUR_RGB_GREEN": "سوز",
                +	"COLOUR_RGB_BLUE": "آوی",
                +	"COLOUR_BLEND_TITLE": "شیوسته",
                +	"COLOUR_BLEND_COLOUR1": "رن 1",
                +	"COLOUR_BLEND_COLOUR2": "رن 2",
                +	"COLOUR_BLEND_RATIO": "نسوت",
                +	"COLOUR_BLEND_TOOLTIP": "هر کوم د رنگیانه وا نسوت دائه بیه به شیون(0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "%1 تکرار کو چن بار",
                +	"CONTROLS_REPEAT_INPUT_DO": "انجوم بئه",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "تا تکرار کو",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "تا تکرار کو",
                +	"CONTROLS_FOR_TITLE": "اشماردن وا %1 د %2 سی %3 وا %4",
                +	"CONTROLS_FOREACH_TITLE": "سی هر قلم %1 د نوم گه %2",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "حلقه نه خراو کو",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "حلقه شومل بیه نه خراو کو",
                +	"CONTROLS_IF_MSG_IF": "ار",
                +	"CONTROLS_IF_MSG_ELSEIF": "هنی ار",
                +	"CONTROLS_IF_MSG_ELSE": "هنی",
                +	"LOGIC_OPERATION_AND": "و",
                +	"LOGIC_OPERATION_OR": "یا",
                +	"LOGIC_NEGATE_TITLE": "نه %1",
                +	"LOGIC_BOOLEAN_TRUE": "راست و دوروست",
                +	"LOGIC_BOOLEAN_FALSE": "غلط",
                +	"LOGIC_BOOLEAN_TOOLTIP": "هم غلط و هم راس ورگن",
                +	"LOGIC_NULL": "خمثی",
                +	"LOGIC_TERNARY_CONDITION": "آزماشت کردن",
                +	"LOGIC_TERNARY_IF_TRUE": "ار درس بی",
                +	"LOGIC_TERNARY_IF_FALSE": "ار غلط بی",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "یه شماره.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "وه انازه دو گل شماره ورگن.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "چارسوک ریشه",
                +	"MATH_SINGLE_OP_ABSOLUTE": "تموم و کمال",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_IS_EVEN": "همیشه هیئش",
                +	"MATH_IS_ODD": "تهنائه",
                +	"MATH_IS_PRIME": "وه اوله",
                +	"MATH_IS_WHOLE": "همشه",
                +	"MATH_IS_POSITIVE": "مثبته",
                +	"MATH_IS_NEGATIVE": "منفیه",
                +	"MATH_IS_DIVISIBLE_BY": "یه وا بهر بیه",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "آلشت بكيد %1 وا %2",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_OPERATOR_ROUND": "گرد کردن",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "وه رو گرد کردن",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "وه هار گرد کردن",
                +	"MATH_ONLIST_OPERATOR_SUM": "جم کردن نومگه",
                +	"MATH_ONLIST_OPERATOR_MIN": "کمترونه د نومگه",
                +	"MATH_ONLIST_OPERATOR_MAX": "بیشترونه د نومگه",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "مینجاگه نوم گه",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "مینجا نوم گه",
                +	"MATH_ONLIST_OPERATOR_MODE": "بیشری د نومگه",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "راس کردن متن وا",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "پیوسن",
                +	"TEXT_ISEMPTY_TITLE": "%1 حالیه",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "د متن",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "سی واج#",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "سی واج# تا آخر",
                +	"TEXT_GET_SUBSTRING_END_LAST": "سی آخرین واج",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "سی حرف گپ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "سی واج کؤچک",
                +	"LISTS_CREATE_EMPTY_TITLE": "یه گل نوم گه حالی راس بکیت",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "نوم گه",
                +	"LISTS_ISEMPTY_TITLE": "%1 حالیه",
                +	"LISTS_INLIST": "د نوم گه",
                +	"LISTS_GET_INDEX_GET": "گرتن",
                +	"LISTS_GET_INDEX_GET_REMOVE": "گرتن و جاوه جا بیئن",
                +	"LISTS_GET_INDEX_REMOVE": "ؤرداشتن",
                +	"LISTS_GET_INDEX_FROM_END": "# تا آخر",
                +	"LISTS_GET_INDEX_FIRST": "اولی",
                +	"LISTS_GET_INDEX_LAST": "آخر",
                +	"LISTS_GET_INDEX_RANDOM": "بختكی",
                +	"LISTS_SET_INDEX_INSERT": "بنه د",
                +	"LISTS_SET_INDEX_INPUT_TO": "چی",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "سی#",
                +	"LISTS_GET_SUBLIST_END_LAST": "سی آخر",
                +	"VARIABLES_SET": "میزوکاری %1 سی %2",
                +	"PROCEDURES_DEFNORETURN_TITLE": "سی",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "یه کار انجوم بیئت",
                +	"PROCEDURES_BEFORE_PARAMS": "وا:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "وا:",
                +	"PROCEDURES_DEFRETURN_RETURN": "ورگنیئن",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "داده یا",
                +	"PROCEDURES_MUTATORARG_TITLE": "نوم داده:",
                +	"PROCEDURES_CREATE_DO": "راس کردن%1"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/lt.json b/blockly/webif/static/blockly/msg/json/lt.json
                new file mode 100644
                index 000000000..53a48c18f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/lt.json
                @@ -0,0 +1,292 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Eitvys200",
                +			"Jurgis",
                +			"Zygimantus",
                +			"Nuodas"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "elementas",
                +	"TODAY": "Šiandien",
                +	"DUPLICATE_BLOCK": "Kopijuoti",
                +	"ADD_COMMENT": "Palikti komentarą",
                +	"REMOVE_COMMENT": "Pašalinti komentarą",
                +	"EXTERNAL_INPUTS": "Išdėstyti stulpeliu, kai daug parametrų",
                +	"INLINE_INPUTS": "Išdėstyti vienoje eilutėje",
                +	"DELETE_BLOCK": "Ištrinti bloką",
                +	"DELETE_X_BLOCKS": "Ištrinti %1 blokus",
                +	"DELETE_ALL_BLOCKS": "Ištrinti visus %1 blokus?",
                +	"CLEAN_UP": "Išvalyti blokus",
                +	"COLLAPSE_BLOCK": "Suskleisti bloką",
                +	"COLLAPSE_ALL": "Suskleisti blokus",
                +	"EXPAND_BLOCK": "Išskleisti bloką",
                +	"EXPAND_ALL": "Išskleisti blokus",
                +	"DISABLE_BLOCK": "Išjungti bloką",
                +	"ENABLE_BLOCK": "Įjungti bloką",
                +	"HELP": "Pagalba",
                +	"UNDO": "Anuliuoti",
                +	"REDO": "Atkurti",
                +	"CHANGE_VALUE_TITLE": "Keisti reikšmę:",
                +	"RENAME_VARIABLE": "Pervardyti kintamajį...",
                +	"RENAME_VARIABLE_TITLE": "Pervadinti visus '%1' kintamuosius į:",
                +	"NEW_VARIABLE": "Naujas kintamasis...",
                +	"NEW_VARIABLE_TITLE": "Naujo kintamojo pavadinimas:",
                +	"DELETE_VARIABLE": "Ištrinti „%1“ kintamąjį",
                +	"COLOUR_PICKER_HELPURL": "https://lt.wikipedia.org/wiki/Spalva",
                +	"COLOUR_PICKER_TOOLTIP": "Pasirinkti spalvą iš paletės.",
                +	"COLOUR_RANDOM_TITLE": "atsitiktinė spalva",
                +	"COLOUR_RANDOM_TOOLTIP": "Pasirinkti spalvą atsitiktinai.",
                +	"COLOUR_RGB_TITLE": "spalva su",
                +	"COLOUR_RGB_RED": "raudona",
                +	"COLOUR_RGB_GREEN": "žalia",
                +	"COLOUR_RGB_BLUE": "mėlyna",
                +	"COLOUR_RGB_TOOLTIP": "Spalvą galima sudaryti iš raudonos, žalios ir mėlynos dedamųjų. Kiekvienos intensyvumas nuo 0 iki 100.",
                +	"COLOUR_BLEND_TITLE": "sumaišyk",
                +	"COLOUR_BLEND_COLOUR1": "1 spalva",
                +	"COLOUR_BLEND_COLOUR2": "2 spalva",
                +	"COLOUR_BLEND_RATIO": "santykis",
                +	"COLOUR_BLEND_TOOLTIP": "Sumaišo dvi spalvas su pateiktu santykiu (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "pakartokite %1 kartus",
                +	"CONTROLS_REPEAT_INPUT_DO": "daryti",
                +	"CONTROLS_REPEAT_TOOLTIP": "Leidžia atlikti išvardintus veiksmus kelis kartus.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "kartok kol",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "kartok, kol pasieksi",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Kartoja veiksmus, kol sąlyga tenkinama.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Kartoja veiksmus, kol bus pasiekta nurodyta sąlyga.",
                +	"CONTROLS_FOR_TOOLTIP": "Imama kintamoji '%1' reikšmė nuo pradinio skaičiaus iki pabaigos skaičiaus, skaičiuojant nustatytais intervalais ir atliekant nustatytus blokus.",
                +	"CONTROLS_FOR_TITLE": "kartok, kai %1 kinta nuo %2 iki %3 po %4",
                +	"CONTROLS_FOREACH_TITLE": "kartok su kiekvienu %1 iš sąrašo %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Kartok veiksmus, kol kintamasis \"%1\" paeiliui gauna kiekvieną sąrašo reikšmę.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "nutraukti kartojimą",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "šį kartą praleisti likusius veiksmus ir tęsti kartojimą",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Nutraukia (artimiausią) vykstantį kartojimą.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Praleidžia žemiau išvardintus kartojimo veiksmus (ir tęsia darbą nuo kartojimo pradinio veiksmo).",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Atsargiai: šis blokas gali būt naudojamas tik kartojimo bloko viduje.",
                +	"CONTROLS_IF_TOOLTIP_1": "Jeigu sąlyga tenkinama, tai atlik veiksmus.",
                +	"CONTROLS_IF_TOOLTIP_2": "Jei sąlyga tenkinama, atlikti jai priklausančius veiksmus, o jei ne -- atlikti kitus nurodytus veiksmus.",
                +	"CONTROLS_IF_TOOLTIP_3": "Jei pirma sąlyga tenkinama, atlikti jai priklausančius veiksmus, O jei ne, tikrinti antrą sąlygą -- ir jei ši tenkinama, atlikti jos veiksmus.",
                +	"CONTROLS_IF_TOOLTIP_4": "Jei pirma sąlyga tenkinama, atlikti jai priklausančius veiksmus, O jei ne, tikrinti antrą sąlygą -- ir jei ši tenkinama, atlikti jos veiksmus. Kitais atvejais -- atlikti paskutinio bloko veiksmus.",
                +	"CONTROLS_IF_MSG_IF": "jei",
                +	"CONTROLS_IF_MSG_ELSEIF": "arba jei",
                +	"CONTROLS_IF_MSG_ELSE": "kitu atveju",
                +	"CONTROLS_IF_IF_TOOLTIP": "Galite pridėt/pašalinti/pertvarkyti  sąlygų \"šakas\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Pridėti sąlygą „jei“ blokui.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Pridėti veiksmų vykdymo variantą/\"šaką\", kai netenkinama nė viena sąlyga.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Tenkinama, jei abu reiškiniai lygūs.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Grįžti tiesa, jeigu abi įvestys ne lygios tarpusavyje.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Grįžti tiesa, jei pirma įvestis mažesnė nei antra įvestis.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Grįžti tiesa, jei pirma įvestis mažesnė arba lygi antrajai įvesčiai.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Grįžti tiesa, jei pirmoji įvestis didesnė nei antroji įvestis.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Grįžti tiesa, jei pirma įvestis didesnė arba lygi antrajai įvesčiai.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Bus teisinga, kai abi sąlygos bus tenkinamos.",
                +	"LOGIC_OPERATION_AND": "ir",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Grįžti tiesa, jei bent viena įvestis teisinga.",
                +	"LOGIC_OPERATION_OR": "arba",
                +	"LOGIC_NEGATE_TITLE": "ne %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Grįžti tiesa, jei įvestis klaidinga. Grįžti klaidinga, jei įvestis teisinga.",
                +	"LOGIC_BOOLEAN_TRUE": "tiesa",
                +	"LOGIC_BOOLEAN_FALSE": "klaidinga",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Reikšmė gali būti \"teisinga\"/\"Taip\" arba \"klaidinga\"/\"Ne\".",
                +	"LOGIC_NULL": "nieko",
                +	"LOGIC_NULL_TOOLTIP": "Reikšmė nebuvo nurodyta...",
                +	"LOGIC_TERNARY_CONDITION": "sąlyga",
                +	"LOGIC_TERNARY_IF_TRUE": "jei taip",
                +	"LOGIC_TERNARY_IF_FALSE": "jei ne",
                +	"LOGIC_TERNARY_TOOLTIP": "Jeigu sąlygą tenkinama, grąžina pirmą reikšmę, o jei ne - antrąją.",
                +	"MATH_NUMBER_HELPURL": "https://lt.wikipedia.org/wiki/Skaičius",
                +	"MATH_NUMBER_TOOLTIP": "Skaičius.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Grąžina dviejų skaičių sumą.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Grąžina dviejų skaičių skirtumą.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Grąžina dviejų skaičių sandaugą.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Grąžina dviejų skaičių dalmenį.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Grąžina pirmą skaičių pakeltą laipsniu pagal antrą skaičių.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "kvadratinė šaknis",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Grįžti kvadratinę šaknį iš skaičiaus.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "modulis",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Skaičiaus modulis - reikšmė be ženklo (panaikina minusą).",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Grąžina skaičiui priešingą skaičių.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Grąžinti skaičiaus natūrinį logaritmą.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Grįžti 10 pagrindinių logaritmų iš skaičiaus.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Grąžinti skaičių laipsniu e.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Grąžinti skaičių laipsniu 10.",
                +	"MATH_TRIG_HELPURL": "https://lt.wikipedia.org/wiki/Trigonometrinės_funkcijos",
                +	"MATH_TRIG_TOOLTIP_SIN": "Grąžinti laipsnio sinusą (ne radiano).",
                +	"MATH_TRIG_TOOLTIP_COS": "Grąžinti laipsnio kosinusą (ne radiano).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Grąžinti laipsnio tangentą (ne radiano).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Grąžinti skaičiaus arksinusą.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Grąžinti skaičiaus arkkosinusą.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Grąžinti skaičiaus arktangentą.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Grįžti viena iš pagrindinių konstantų: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (begalybė).",
                +	"MATH_IS_EVEN": "yra lyginis",
                +	"MATH_IS_ODD": "yra nelyginis",
                +	"MATH_IS_PRIME": "yra pirminis",
                +	"MATH_IS_WHOLE": "yra sveikasis",
                +	"MATH_IS_POSITIVE": "yra teigiamas",
                +	"MATH_IS_NEGATIVE": "yra neigiamas",
                +	"MATH_IS_DIVISIBLE_BY": "yra dalus iš",
                +	"MATH_IS_TOOLTIP": "Patikrina skaičiaus savybę: (ne)lyginis/pirminis/sveikasis/teigiamas/neigiamas/dalus iš x.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "padidink %1 (emptypage) %2",
                +	"MATH_CHANGE_TOOLTIP": "Prideda skaičių prie kintamojo '%1'. Kai skaičius neigiamas - gaunasi atimtis.",
                +	"MATH_ROUND_HELPURL": "https://lt.wikipedia.org/wiki/Apvalinimas",
                +	"MATH_ROUND_TOOLTIP": "Suapvalinti skaičių į žemesnę ar aukštesnę reikšmę.",
                +	"MATH_ROUND_OPERATOR_ROUND": "apvalink",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "apvalink aukštyn",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "apvalink žemyn",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma",
                +	"MATH_ONLIST_TOOLTIP_SUM": "didžiausia reikšmė",
                +	"MATH_ONLIST_OPERATOR_MIN": "mažiausia reikšmė sąraše",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Grįžti mažiausiu skaičiumi sąraše.",
                +	"MATH_ONLIST_OPERATOR_MAX": "didžiausia reikšmė sąraše",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Grįžti didžiausiu skaičiumi sąraše.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "vidurkis",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Grįžti vidurkiu (aritmetinis vidurkis) iš skaitinių reikšmių sąraše.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana sąrašui",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Grąžinti sąrašo medianą.",
                +	"MATH_ONLIST_OPERATOR_MODE": "statistinė moda sąrašui",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Grąžinti sąrašą dažniausių elementų sąraše.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standartinis nuokrypis sąraše",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Grįžti standartine pakraipa iš sąrašo.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "atsitiktinis elementas iš sąrašo",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Grąžinti atsitiktinį elementą iš sąrašo.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "dalybos liekana %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Grįžti likučiu nuo dviejų skaičių dalybos.",
                +	"MATH_CONSTRAIN_TITLE": "apribok %1 tarp %2 ir %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Apriboti skaičių, kad būtų tarp nustatytų ribų (imtinai).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "atsitiktinis sveikas sk. nuo %1 iki %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Grįžti atsitiktinį sveikąjį skaičių tarp dviejų nustatytų ribų, imtinai.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "atsitiktinė trupmena",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Atsitiktinė trupmena nuo 0 (imtinai) iki 1 (neimtinai).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Tekstas (arba žodis, ar raidė)",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "sukurti tekstą su",
                +	"TEXT_JOIN_TOOLTIP": "Sukurti teksto fragmentą sujungiant bet kokį skaičių fragmentų.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "sujunk",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Pridėti, pašalinti arba paskirstyti skyrius, kad pertvarkyti šį teksto bloką.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Pridėti teksto elementą.",
                +	"TEXT_APPEND_TOOLTIP": "Pridėti tekstą prie kintamojo '%1'.",
                +	"TEXT_LENGTH_TITLE": "teksto %1 ilgis",
                +	"TEXT_LENGTH_TOOLTIP": "Suranda teksto simbolių kiekį (įskaitant ir tarpus)",
                +	"TEXT_ISEMPTY_TITLE": "%1 yra tuščias",
                +	"TEXT_ISEMPTY_TOOLTIP": "Grįžti tiesa, jei numatytas tekstas tuščias.",
                +	"TEXT_INDEXOF_TOOLTIP": "Grąžina pirmą/paskutinę pirmo teksto reikšmę antrame tekste. Grąžina %1, jei tekstas nerastas.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "rask,kur pirmą kartą paminėta",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "rask,kur paskutinį kartą paminėta",
                +	"TEXT_CHARAT_FROM_START": "gauti raidę #",
                +	"TEXT_CHARAT_FROM_END": "raidė nuo galo #",
                +	"TEXT_CHARAT_FIRST": "gauti pirmą raidę",
                +	"TEXT_CHARAT_LAST": "gauti paskutinę raidę",
                +	"TEXT_CHARAT_RANDOM": "gauti atsitiktinę raidę",
                +	"TEXT_CHARAT_TOOLTIP": "Grąžina raidę į tam tikrą poziciją.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Grąžina tam tikrą teksto dalį.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "tekste",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "dalis nuo raidės #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "dalis nuo raidės #",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "dalis nuo pradžios",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "iki raidės #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "iki raidės nuo galo #",
                +	"TEXT_GET_SUBSTRING_END_LAST": "iki pabaigos",
                +	"TEXT_CHANGECASE_TOOLTIP": "Kitu atvėju, grąžina teksto kopiją.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": " DIDŽIOSIOM RAIDĖM",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": " mažosiom raidėm",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": " Pavadinimo Raidėmis",
                +	"TEXT_TRIM_TOOLTIP": "Grąžina teksto kopiją, pašalinus tarpus iš vieno ar abiejų kraštų.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "išvalyk tarpus šonuose",
                +	"TEXT_TRIM_OPERATOR_LEFT": "išvalyk tarpus pradžioje",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "išvalyk tarpus pabaigoje",
                +	"TEXT_PRINT_TITLE": "spausdinti %1",
                +	"TEXT_PRINT_TOOLTIP": "Spausdinti nurodytą tekstą, skaičių ar kitą reikšmę.",
                +	"TEXT_PROMPT_TYPE_TEXT": "paprašyk įvesti tekstą :",
                +	"TEXT_PROMPT_TYPE_NUMBER": "paprašyk įvesti skaičių :",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Prašyti vartotoją įvesti skaičių.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Prašyti vartotoją įvesti tekstą.",
                +	"TEXT_COUNT_MESSAGE0": "skaičius %1 iš %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Suskaičiuoti, kiek kartų šis tekstas kartojasi kitame tekste.",
                +	"TEXT_REPLACE_MESSAGE0": "pakeisti %1 į %2 šiame %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Pašalinti visas teksto dalis kitame tekste.",
                +	"TEXT_REVERSE_MESSAGE0": "atbulai %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REVERSE_TOOLTIP": "Apversti teksto simbolių tvarką.",
                +	"LISTS_CREATE_EMPTY_TITLE": "tuščias sąrašas",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Grąžina sąrašą, ilgio 0, neturintį duomenų",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Sukurti sąrašą iš bet kokio skaičiaus elementų.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "sukurti sąrašą su",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "sąrašas",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Pridėti, pašalinti arba paskirstyti skyrius, kad pertvarkyti šį teksto bloką.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Pridėti elementą į sąrašą.",
                +	"LISTS_REPEAT_TITLE": "sukurk sąrašą, kuriame %1 bus %2 kartus",
                +	"LISTS_LENGTH_TITLE": "ilgis %1",
                +	"LISTS_LENGTH_TOOLTIP": "Grąžina sąrašo ilgį.",
                +	"LISTS_ISEMPTY_TITLE": "%1 yra tuščias",
                +	"LISTS_ISEMPTY_TOOLTIP": "Grąžina „true“, jeigu sąrašas tuščias.",
                +	"LISTS_INLIST": "sąraše",
                +	"LISTS_INDEX_OF_FIRST": "rask pirmą reikšmę",
                +	"LISTS_INDEX_OF_LAST": "rask paskutinę reikšmę",
                +	"LISTS_INDEX_OF_TOOLTIP": "Grąžina pirmos/paskutinės reikšmės eilės nr. sąraše. Grąžina %1, jei reikšmės neranda.",
                +	"LISTS_GET_INDEX_GET": "paimk",
                +	"LISTS_GET_INDEX_GET_REMOVE": "paimk ir ištrink",
                +	"LISTS_GET_INDEX_REMOVE": "pašalinti",
                +	"LISTS_GET_INDEX_FROM_END": "# nuo galo",
                +	"LISTS_GET_INDEX_FIRST": "pirmas",
                +	"LISTS_GET_INDEX_LAST": "paskutinis",
                +	"LISTS_GET_INDEX_RANDOM": "atsitiktinis",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 yra pirmasis objektas.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 yra paskutinis objektas.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Gražina objektą į nurodyta poziciją sąraše.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Grąžina pirmąjį sąrašo elementą.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Grąžina paskutinį elementą iš sąrašo.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Grąžina atsitiktinį elementą iš sąrašo.",
                +	"LISTS_SET_INDEX_SET": "priskirk elementui",
                +	"LISTS_SET_INDEX_INSERT": "įterpk į vietą",
                +	"LISTS_SET_INDEX_INPUT_TO": "kaip",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Įterpią objektą į nurodytą poziciją sąraše.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "sąrašo dalis nuo #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "sąrašo dalis nuo # nuo galo",
                +	"LISTS_GET_SUBLIST_START_FIRST": "sąrašo dalis nuo pradžios",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "iki #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "iki # nuo galo",
                +	"LISTS_GET_SUBLIST_END_LAST": "iki galo",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "rūšiuoti %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Rūšiuoti sąrašo kopiją.",
                +	"LISTS_SORT_ORDER_ASCENDING": "didėjančia tvarka",
                +	"LISTS_SORT_ORDER_DESCENDING": "mažėjančia tvarka",
                +	"LISTS_SORT_TYPE_NUMERIC": "skaitmeninis",
                +	"LISTS_SORT_TYPE_TEXT": "abėcėlės",
                +	"LISTS_SORT_TYPE_IGNORECASE": "abecėlės, ignoruoti raidžių dydį",
                +	"LISTS_SPLIT_WITH_DELIMITER": "su dalikliu",
                +	"VARIABLES_GET_CREATE_SET": "Sukurk \"priskirk %1\"",
                +	"VARIABLES_SET": "priskirk %1 = %2",
                +	"VARIABLES_SET_CREATE_GET": "Sukurti 'kintamasis %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "komanda:",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "daryk kažką",
                +	"PROCEDURES_BEFORE_PARAMS": "pagal:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "su:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Sukuria procedūrą - komandą, kuri nepateikia jokio rezultato (tik atlieka veiksmus).",
                +	"PROCEDURES_DEFRETURN_RETURN": "duok",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Sukuria funkciją - komandą, kuri ne tik atlieka veiksmus bet ir pateikia (grąžina/duoda) rezultatą.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "leisti vidinius veiksmus",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Ši komanda turi du vienodus gaunamų duomenų pavadinimus.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Vykdyti sukurtą komandą \"%1\".",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Įvykdyti komandą \"%1\" ir naudoti jos suskaičiuotą (atiduotą) reikšmę.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "gaunami duomenys (parametrai)",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Tvarkyti komandos gaunamus duomenis (parametrus).",
                +	"PROCEDURES_MUTATORARG_TITLE": "parametro pavadinimas:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Pridėti funkcijos parametrą (gaunamų duomenų pavadinimą).",
                +	"PROCEDURES_CREATE_DO": "Sukurti \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Jeigu pirma reikšmė yra teisinga (sąlyga tenkinama), grąžina antrą reikšmę.",
                +	"PROCEDURES_IFRETURN_WARNING": "Perspėjimas: šis blokas gali būti naudojamas tik aprašant funkciją."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/lv.json b/blockly/webif/static/blockly/msg/json/lv.json
                new file mode 100644
                index 000000000..47dd9d231
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/lv.json
                @@ -0,0 +1,317 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Elomage",
                +			"Janis",
                +			"Papuass",
                +			"Silraks"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "vienums",
                +	"TODAY": "Šodiena",
                +	"DUPLICATE_BLOCK": "Dublēt",
                +	"ADD_COMMENT": "Pievienot komentāru",
                +	"REMOVE_COMMENT": "Noņemt komentāru",
                +	"EXTERNAL_INPUTS": "Ārējie ievaddati",
                +	"INLINE_INPUTS": "Iekšējie ievaddati",
                +	"DELETE_BLOCK": "Izmest bloku",
                +	"DELETE_X_BLOCKS": "Izmest %1 blokus",
                +	"DELETE_ALL_BLOCKS": "Izdzēst visus %1 blokus?",
                +	"CLEAN_UP": "Sakopt blokus",
                +	"COLLAPSE_BLOCK": "Sakļaut bloku",
                +	"COLLAPSE_ALL": "Sakļaut blokus",
                +	"EXPAND_BLOCK": "Izvērst bloku",
                +	"EXPAND_ALL": "Izvērst blokus",
                +	"DISABLE_BLOCK": "Atspējot bloku",
                +	"ENABLE_BLOCK": "Iespējot bloku",
                +	"HELP": "Palīdzība",
                +	"UNDO": "Atsaukt",
                +	"REDO": "Atcelt atsaukšanu",
                +	"CHANGE_VALUE_TITLE": "Mainīt vērtību:",
                +	"RENAME_VARIABLE": "Pārdēvēt mainīgo...",
                +	"RENAME_VARIABLE_TITLE": "Pārdēvējiet visus '%1' mainīgos:",
                +	"NEW_VARIABLE": "Izveidot mainīgo...",
                +	"NEW_VARIABLE_TITLE": "Jaunā mainīgā vārds:",
                +	"VARIABLE_ALREADY_EXISTS": "Mainīgais '%1' jau eksistē.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Mainīgais \"%2\" tiek izmantots %1 vietās. Dzēst?",
                +	"DELETE_VARIABLE": "Izdzēst mainīgo \"%1\"",
                +	"COLOUR_PICKER_HELPURL": "https://lv.wikipedia.org/wiki/Krāsa",
                +	"COLOUR_PICKER_TOOLTIP": "Izvēlēties krāsu no paletes.",
                +	"COLOUR_RANDOM_TITLE": "nejauša krāsa",
                +	"COLOUR_RANDOM_TOOLTIP": "Izvēlēties krāsu pēc nejaušības principa.",
                +	"COLOUR_RGB_TITLE": "veido krāsu no",
                +	"COLOUR_RGB_RED": "sarkana",
                +	"COLOUR_RGB_GREEN": "zaļa",
                +	"COLOUR_RGB_BLUE": "zila",
                +	"COLOUR_RGB_TOOLTIP": "Izveidot krāsu ar norādīto daudzumu sarkanā, zaļā un zilā toņu. Visas vērtības ir starp 0 un 100.",
                +	"COLOUR_BLEND_TITLE": "sajaukt",
                +	"COLOUR_BLEND_COLOUR1": "1. krāsa",
                +	"COLOUR_BLEND_COLOUR2": "2. krāsa",
                +	"COLOUR_BLEND_RATIO": "attiecība",
                +	"COLOUR_BLEND_TOOLTIP": "Sajauc kopā divas krāsas ar doto attiecību (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://lv.wikipedia.org/wiki/Cikls",
                +	"CONTROLS_REPEAT_TITLE": "atkārtot %1 reizes",
                +	"CONTROLS_REPEAT_INPUT_DO": "izpildi",
                +	"CONTROLS_REPEAT_TOOLTIP": "Izpildīt komandas vairākas reizes.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "atkārtot kamēr",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "atkārtot līdz",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Izpildīt komandas, kamēr vērtība ir patiesa.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Izpildīt komandas, kamēr vērtība ir nepatiesa.",
                +	"CONTROLS_FOR_TOOLTIP": "Ļauj mainīgajam '%1' pieņemt vērtības no sākuma līdz beigu vērtībai, un izpildīt iekļautos blokus katrai no šīm pieņemtajām vērtībām.",
                +	"CONTROLS_FOR_TITLE": "skaitīt %1 no %2 līdz %3 ar soli %4",
                +	"CONTROLS_FOREACH_TITLE": "visiem %1 no saraksta %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Katram objektam no saraksta piešķirt mainīgajam '%1' šo objektu un izpildīt komandas.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "iet ārā no cikla",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "turpināt ar cikla nākamo iterāciju",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Iet ārā no iekļaujošā cikla",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Nepildīt atlikušo cikla daļu bet sākt nākamo iterāciju.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Brīdinājums: šo bloku drīkst izmantot tikai cikla iekšienē.",
                +	"CONTROLS_IF_TOOLTIP_1": "Ja vērtība ir patiesa, tad izpildīt komandas.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ja vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi izpildīt otro bloku ar komandām.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ja pirmā vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi, ja otrā vērtība ir patiesa, izpildīt otro bloku ar komandām.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ja pirmā vērtība ir patiesa, tad izpildīt pirmo bloku ar komandām. Citādi, ja otrā vērtība ir patiesa, izpildīt otro bloku ar komandām. Ja neviena no vertībām nav patiesa, tad izpildīt pēdējo bloku ar komandām.",
                +	"CONTROLS_IF_MSG_IF": "ja",
                +	"CONTROLS_IF_MSG_ELSEIF": "citādi, ja",
                +	"CONTROLS_IF_MSG_ELSE": "citādi",
                +	"CONTROLS_IF_IF_TOOLTIP": "Pievienot, noņemt vai mainīt sekciju secību šim \"ja\" blokam.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Pievienot nosacījumu \"ja\" blokam.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Pievienot gala nosacījumu \"ja\" blokam.",
                +	"IOS_OK": "Labi",
                +	"IOS_CANCEL": "Atcelt",
                +	"IOS_ERROR": "Kļūda",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Pievienot mainīgo",
                +	"IOS_VARIABLES_ADD_BUTTON": "Pievienot",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Pārsaukt",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Dzēst",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Mainīgā nosaukums",
                +	"LOGIC_COMPARE_HELPURL": "https://lv.wikipedia.org/wiki/Nevien%C4%81d%C4%ABba",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Patiess, ja abas puses ir vienādas.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Patiess, ja abas puses nav vienādas.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Patiess, ja kreisā puse ir mazāka par labo pusi.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Patiess, ja kreisā puse ir mazāka vai vienāda ar labo pusi.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Patiess, ja kreisā puse ir lielāka par labo pusi.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Patiess, ja kreisā puse ir lielāka vai vienāda ar labo pusi.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Patiess, ja abas puses ir patiesas.",
                +	"LOGIC_OPERATION_AND": "un",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Patiess, ja vismaz viena puse ir patiesa.",
                +	"LOGIC_OPERATION_OR": "vai",
                +	"LOGIC_NEGATE_TITLE": "ne %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Patiess, ja arguments ir aplams.",
                +	"LOGIC_BOOLEAN_TRUE": "patiess",
                +	"LOGIC_BOOLEAN_FALSE": "aplams",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Atgriež rezultātu \"patiess\" vai \"aplams\".",
                +	"LOGIC_NULL": "nekas",
                +	"LOGIC_NULL_TOOLTIP": "Atgriež neko.",
                +	"LOGIC_TERNARY_CONDITION": "nosacījums",
                +	"LOGIC_TERNARY_IF_TRUE": "ja patiess",
                +	"LOGIC_TERNARY_IF_FALSE": "ja aplams",
                +	"LOGIC_TERNARY_TOOLTIP": "Pārbaudīt nosacījumu. Ja 'nosacījums' ir patiess, atgriež vērtību 'ja patiess', pretējā gadījumā vērtību 'ja aplams'.",
                +	"MATH_NUMBER_HELPURL": "https://lv.wikipedia.org/wiki/Skaitlis",
                +	"MATH_NUMBER_TOOLTIP": "Skaitlis.",
                +	"MATH_ARITHMETIC_HELPURL": "https://lv.wikipedia.org/wiki/Aritm%C4%93tika",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Atgriež divu skaitļu summu.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Atgriež divu skaitļu starpību.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Atgriež divu skaitļu reizinājumu.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Atgriež divu skaitļu dalījumu.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Atgriež pirmo skaitli kāpinātu pakāpē otrais skaitlis.",
                +	"MATH_SINGLE_HELPURL": "https://lv.wikipedia.org/wiki/Kvadr%C4%81tsakne",
                +	"MATH_SINGLE_OP_ROOT": "kvadrātsakne",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Atgriež skaitļa kvadrātsakni.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolūtā vērtība",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Atgriež skaitļa absolūto vērtību.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Atgriež pretējo skaitli.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Atgriež skaitļa naturālo logaritmu.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Atgriež skaitļa logaritmu pie bāzes 10.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Atgriež e pakāpē dotais skaitlis.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Atgriež 10 pakāpē dotais skaitlis.",
                +	"MATH_TRIG_HELPURL": "https://lv.wikipedia.org/wiki/Trigonometrisk%C4%81s_funkcijas",
                +	"MATH_TRIG_TOOLTIP_SIN": "Sinuss no grādiem (nevis radiāniem).",
                +	"MATH_TRIG_TOOLTIP_COS": "Kosinuss no grādiem (nevis radiāniem).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Tangenss no grādiem (nevis radiāniem).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Arksinuss (grādos).",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Arkkosinuss (grādos).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Arktangenss (grādos).",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Atgriež kādu no matemātikas konstantēm: π (3.141…), e (2.718…), φ (1.618…), √(2) (1.414…), √(½) (0.707…), ∞ (bezgalība).",
                +	"MATH_IS_EVEN": "ir pāra",
                +	"MATH_IS_ODD": "ir nepāra",
                +	"MATH_IS_PRIME": "ir pirmskaitlis",
                +	"MATH_IS_WHOLE": "ir vesels",
                +	"MATH_IS_POSITIVE": "ir pozitīvs",
                +	"MATH_IS_NEGATIVE": "ir negatīvs",
                +	"MATH_IS_DIVISIBLE_BY": "dalās bez atlikuma ar",
                +	"MATH_IS_TOOLTIP": "Pārbauda, vai skaitlis ir pāra, nepāra, vesels, pozitīvs, negatīvs vai dalās ar noteiktu skaitli. Atgriež \"patiess\" vai \"aplams\".",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "izmainīt %1 par %2",
                +	"MATH_CHANGE_TOOLTIP": "Pieskaitīt doto skaitli mainīgajam '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Noapaļot skaitli uz augšu vai uz leju.",
                +	"MATH_ROUND_OPERATOR_ROUND": "noapaļot",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "apaļot uz augšu",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "apaļot uz leju",
                +	"MATH_ONLIST_OPERATOR_SUM": "summa",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Saskaitīt visus skaitļus no dotā saraksta.",
                +	"MATH_ONLIST_OPERATOR_MIN": "mazākais",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Atgriež mazāko vērtību no saraksta.",
                +	"MATH_ONLIST_OPERATOR_MAX": "lielākais",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Atgriež lielāko vērtību no saraksta.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "vidējais",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Atgriež dotā saraksta vidējo aritmētisko vērtību.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediāna",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Atgriež dotā saraksta mediānas vērtību.",
                +	"MATH_ONLIST_OPERATOR_MODE": "moda",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Atgriež dotā saraksta biežāk sastopamās vērtības (modas).",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standartnovirze",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Atgriež dotā saraksta standartnovirzi.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "nejaušs",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Atgriež nejauši izvēlētu vērtību no dotā saraksta.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "atlikums no %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Atlikums no divu skaitļu dalījuma.",
                +	"MATH_CONSTRAIN_TITLE": "ierobežot %1 no %2 līdz %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Ierobežo skaitli no noteiktajās robežās (ieskaitot galapunktus).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "nejaušs vesels skaitlis no %1 līdz %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Atgriež nejaušu veselu skaitli dotajās robežās (iekļaujot galapunktus)",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "nejaušs skaitlis [0..1)",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Atgriež nejaušu reālo skaitli robežās no 0 (iekļaujot) līdz 1 (neiekļaujot).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Burts, vārds vai jebkāda teksta rinda.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "veidot tekstu no",
                +	"TEXT_JOIN_TOOLTIP": "Izveidot tekstu savienojot dotos argumentus.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "savienot",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Pievienot, noņemt vai mainīt sekciju secību šim \"teksta\" blokam.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Pievienot tekstam objektu.",
                +	"TEXT_APPEND_TOOLTIP": "Pievienot tekstu mainīgajam '%1'.",
                +	"TEXT_LENGTH_TITLE": "garums tekstam %1",
                +	"TEXT_LENGTH_TOOLTIP": "Atgriež burtu skaitu (ieskaitot atstarpes) dotajā tekstā.",
                +	"TEXT_ISEMPTY_TITLE": "%1 ir tukšs",
                +	"TEXT_ISEMPTY_TOOLTIP": "Patiess, ja teksts ir tukšs.",
                +	"TEXT_INDEXOF_TOOLTIP": "Meklē pirmā teksta rindu otrajā tekstā.\nAtgriež pozīciju otrajā tekstā, kurā sākas pirmais teksts.\nAtgriež %1 ja pirmā teksta rinda nav atrasta.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "meklēt pirmo vietu, kur sākas teksts",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "meklēt pēdējo vietu, kur sākas teksts",
                +	"TEXT_CHARAT_FROM_START": "paņemt burtu #",
                +	"TEXT_CHARAT_FROM_END": "paņemt no beigām burtu #",
                +	"TEXT_CHARAT_FIRST": "paņemt pirmo burtu",
                +	"TEXT_CHARAT_LAST": "paņemt pēdējo burtu",
                +	"TEXT_CHARAT_RANDOM": "paņemt nejaušu burtu",
                +	"TEXT_CHARAT_TOOLTIP": "Atgriež burtu dotajā pozīcijā.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Atgriež norādīto teksta daļu.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "no teksta",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "paņemt apakšvirkni sākot no burta nr",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "paņemt apakšvirkni no beigām sākot ar burta nr",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "paņemt apakšvirkni no sākuma",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "līdz burtam nr",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "līdz burtam nr (no beigām)",
                +	"TEXT_GET_SUBSTRING_END_LAST": "līdz pēdējam burtam",
                +	"TEXT_CHANGECASE_TOOLTIP": "Atgriež teksta kopiju ar mainītiem lielajiem/mazajiem burtiem.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "kā LIELIE BURTI",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "kā mazie burti",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "kā Nosaukuma Burti",
                +	"TEXT_TRIM_TOOLTIP": "Atgriež teksta kopiju ar noņemtām atstarpēm vienā vai otrā galā.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "Dzēst atstarpes no abām pusēm",
                +	"TEXT_TRIM_OPERATOR_LEFT": "Dzēst atstarpes no sākuma",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "Dzēst atstarpes no beigām",
                +	"TEXT_PRINT_TITLE": "parādīt %1",
                +	"TEXT_PRINT_TOOLTIP": "Parādīt norādīto tekstu vai skaitli.",
                +	"TEXT_PROMPT_TYPE_TEXT": "palūgt ievadīt tekstu ar ziņu",
                +	"TEXT_PROMPT_TYPE_NUMBER": "palūgt ievadīt skaitli ar ziņu",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Palūgt lietotāju ievadīt skaitli.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Palūgt lietotāju ievadīt tekstu.",
                +	"LISTS_CREATE_EMPTY_TITLE": "izveidot tukšu sarakstu",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Izveidot sarakstu bez elementiem tajā.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Izveidot sarakstu no jebkura skaita vienību.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "izveidot sarakstu no",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "saraksts",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Pievienot, noņemt vai mainīt sekciju secību šim \"saraksta\" blokam.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Pievienot objektu sarakstam.",
                +	"LISTS_REPEAT_TOOLTIP": "Izveido sarakstu, kas sastāv no dotās vērtības noteiktu reižu skaita.",
                +	"LISTS_REPEAT_TITLE": "saraksts no %1 atkārtots %2 reizes",
                +	"LISTS_LENGTH_TITLE": "%1 garums",
                +	"LISTS_LENGTH_TOOLTIP": "Atgriež elementu skaitu srakstā.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ir tukšs",
                +	"LISTS_ISEMPTY_TOOLTIP": "Patiess, ja saraksts ir tukšs.",
                +	"LISTS_INLIST": "sarakstā",
                +	"LISTS_INDEX_OF_FIRST": "atrast pirmo elementu, kas vienāds ar",
                +	"LISTS_INDEX_OF_LAST": "atrast pēdējo elementu, kas vienāds ar",
                +	"LISTS_INDEX_OF_TOOLTIP": "Atgriež pozīciju sarakstā, kurā atrodas dotais objekts.\nAtgriež %1 ja objekts neatrodas sarakstā.",
                +	"LISTS_GET_INDEX_GET": "paņemt",
                +	"LISTS_GET_INDEX_GET_REMOVE": "paņemt uz dzēst",
                +	"LISTS_GET_INDEX_REMOVE": "dzēst",
                +	"LISTS_GET_INDEX_FROM_END": "no beigām numur",
                +	"LISTS_GET_INDEX_FIRST": "pirmo",
                +	"LISTS_GET_INDEX_LAST": "pēdējo",
                +	"LISTS_GET_INDEX_RANDOM": "nejauši izvēlētu",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Saraksta elementu numerācija sākas no %1",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Saraksta elementu numerācija no beigām sākas no %1",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Atgriež norādīto elementu no saraksta.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Atgriež pirmo saraksta elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Atgriež pēdējo saraksta elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Atgriež nejauši izvēlētu saraksta elementu",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Atgriež un izdzēš no saraksta norādīto elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Atgriež un izdzēš saraksta pirmo elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Atgriež un izdzēš saraksta pēdējo elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Atgriež un izdzēš no saraksta nejauši izvēlētu elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Izdēš norādīto elementu no saraksta.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Izdēš pirmo saraksta elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Izdēš pēdējo saraksta elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Izdzēš no saraksta nejauši izvēlētu elementu.",
                +	"LISTS_SET_INDEX_SET": "aizvieto",
                +	"LISTS_SET_INDEX_INSERT": "ievieto",
                +	"LISTS_SET_INDEX_INPUT_TO": "kā",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Aizvieto sarakstā elementu norādītajā pozīcijā.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Aizvieto elementu saraksta sākumā.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Aizvieto elementu saraksta beigās.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Aizvieto sarakstā elementu nejauši izvēlētā pozīcijā.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Ievieto sarakstā elementu norādītajā pozīcijā.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Ievieto elementu saraksta sākumā.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Pievieno elementu saraksta beigās.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Ievieto sarakstā jaunu elementu nejauši izvēlētā pozīcijā.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "paņemt apakšsarakstu no pozīcijas",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "paņemt apakšsarakstu no beigām no pozīcijas",
                +	"LISTS_GET_SUBLIST_START_FIRST": "paņemt apakšsarakstu no sākuma",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "līdz pozīcijai",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "līdz pozīcijai no beigām",
                +	"LISTS_GET_SUBLIST_END_LAST": "līdz beigām",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Nokopēt daļu no dotā saraksta.",
                +	"LISTS_SORT_TITLE": "Sakārtot sarakstu no %3 elementiem %2 secībā %1",
                +	"LISTS_SORT_TOOLTIP": "Saraksta sakārtota kopija.",
                +	"LISTS_SORT_ORDER_ASCENDING": "augošā",
                +	"LISTS_SORT_ORDER_DESCENDING": "dilstošā",
                +	"LISTS_SORT_TYPE_NUMERIC": "skaitliski",
                +	"LISTS_SORT_TYPE_TEXT": "pēc alfabēta",
                +	"LISTS_SORT_TYPE_IGNORECASE": "pēc alfabēta, ignorēt mazos/lielos burtus",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "vārdu saraksts no teksta",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "izveidot tekstu no saraksta",
                +	"LISTS_SPLIT_WITH_DELIMITER": "ar atdalītāju",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Sadalīt tekstu vārdos izmantojot atdalītāju.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Apvienot tekstu izmantojot atdalītāju.",
                +	"VARIABLES_GET_TOOLTIP": "Atgriež mainīgā vērtību.",
                +	"VARIABLES_GET_CREATE_SET": "Izveidot piešķiršanu mainīgajam %1",
                +	"VARIABLES_SET": "piešķirt mainīgajam %1 vērtību %2",
                +	"VARIABLES_SET_TOOLTIP": "Piešķirt mainīgajam vērtību.",
                +	"VARIABLES_SET_CREATE_GET": "Izveidot 'ņem %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "funkcija",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "darīt kaut ko",
                +	"PROCEDURES_BEFORE_PARAMS": "ar:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ar:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Izveido funkciju, kas neatgriež rezultātu.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Funkcijas apraksts...",
                +	"PROCEDURES_DEFRETURN_RETURN": "atgriezt",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Izveido funkciju, kas atgriež rezultātu.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "atļaut apakškomandas",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Brīdinājums: funkcijai ir vienādi argumenti.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Izpildīt iepriekš definētu funkcju '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Izpildīt iepriekš definētu funkcju '%1' un izmantot tās rezultātu.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "argumenti",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Pievienot, pārkārtot vai dzēst funkcijas argumentus.",
                +	"PROCEDURES_MUTATORARG_TITLE": "arguments:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Pievienot funkcijai argumentu.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Izcelt funkcijas definīciju",
                +	"PROCEDURES_CREATE_DO": "Izveidot '%1' izsaukumu",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ja pirmā vērtība ir \"patiesa\", tad atgriezt otro vērtību.",
                +	"PROCEDURES_IFRETURN_WARNING": "Brīdinājums: Šo bloku var izmantot tikai funkcijas definīcijā."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/mk.json b/blockly/webif/static/blockly/msg/json/mk.json
                new file mode 100644
                index 000000000..c9f8a866e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/mk.json
                @@ -0,0 +1,112 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Bjankuloski06"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "елемент",
                +	"DUPLICATE_BLOCK": "Ископирај",
                +	"ADD_COMMENT": "Додај коментар:",
                +	"REMOVE_COMMENT": "Отстрани коментар",
                +	"EXTERNAL_INPUTS": "Надворешен внос",
                +	"INLINE_INPUTS": "Внатрешен внос",
                +	"DELETE_BLOCK": "Избриши блок",
                +	"DELETE_X_BLOCKS": "Избриши %1 блока",
                +	"DELETE_ALL_BLOCKS": "Да ги избришам сите %1 блокчиња?",
                +	"COLLAPSE_BLOCK": "Собери блок",
                +	"COLLAPSE_ALL": "Собери блокови",
                +	"EXPAND_BLOCK": "Рашири го блокови",
                +	"EXPAND_ALL": "Рашири блокови",
                +	"DISABLE_BLOCK": "Исклучи блок",
                +	"ENABLE_BLOCK": "Вклучи блок",
                +	"HELP": "Помош",
                +	"CHANGE_VALUE_TITLE": "Смена на вредност:",
                +	"NEW_VARIABLE": "Нова променлива...",
                +	"NEW_VARIABLE_TITLE": "Назив на новата променлива:",
                +	"RENAME_VARIABLE": "Преименувај променлива...",
                +	"RENAME_VARIABLE_TITLE": "Преименувај ги сите променливи „%1“ во:",
                +	"COLOUR_PICKER_HELPURL": "https://mk.wikipedia.org/wiki/Боја",
                +	"COLOUR_PICKER_TOOLTIP": "Изберете боја од палетата.",
                +	"COLOUR_RANDOM_TITLE": "случајна боја",
                +	"COLOUR_RANDOM_TOOLTIP": "Избери боја на тепка.",
                +	"COLOUR_RGB_TITLE": "боја со",
                +	"COLOUR_RGB_RED": "црвена",
                +	"COLOUR_RGB_GREEN": "зелена",
                +	"COLOUR_RGB_BLUE": "сина",
                +	"COLOUR_RGB_TOOLTIP": "Создајте боја со укажаните износи на црвена, зелена и сина. Сите вредности мора да бидат помеѓу 0 и 100.",
                +	"COLOUR_BLEND_TITLE": "смешај",
                +	"COLOUR_BLEND_COLOUR1": "боја 1",
                +	"COLOUR_BLEND_COLOUR2": "боја 2",
                +	"COLOUR_BLEND_RATIO": "сооднос",
                +	"COLOUR_BLEND_TOOLTIP": "Меша две бои во даден сооднос (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://mk.wikipedia.org/wiki/For-јамка",
                +	"CONTROLS_REPEAT_TITLE": "повтори %1 пати",
                +	"CONTROLS_REPEAT_INPUT_DO": "исполни",
                +	"CONTROLS_REPEAT_TOOLTIP": "Исполнува наредби неколку пати.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "повторувај додека",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "повторувај сè до",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Додека вредноста е вистинита, исполнува наредби.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Додека вредноста е невистинита, исполнува наредби.",
                +	"CONTROLS_FOR_TOOLTIP": "Променливата \"%1\" да ги земе вредностите од почетниот до завршниот број, броејќи според укажаниот интервал и ги исполнува укажаните блокови.",
                +	"CONTROLS_FOR_TITLE": "број со %1 од %2 до %3 со %4",
                +	"CONTROLS_FOREACH_TITLE": "за секој елемент %1 на списокот %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Му ја задава променливата „%1“ на секој елемент на списокот, а потоа исполнува наредби.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "излези од јамката",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "продолжи со следното повторување на јамката",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Излези од содржечката јамка.",
                +	"CONTROLS_IF_MSG_IF": "ако",
                +	"CONTROLS_IF_MSG_ELSEIF": "инаку ако",
                +	"CONTROLS_IF_MSG_ELSE": "инаку",
                +	"CONTROLS_IF_IF_TOOLTIP": "Додава, отстранува или прередува делови за прераспоредување на овој блок „ако“.",
                +	"LOGIC_COMPARE_HELPURL": "https://mk.wikipedia.org/wiki/Неравенство",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Дава вистина ако обата вноса се еднакви.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Дава вистина ако обата вноса не се еднакви.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Дава вистина ако првиот внос е помал од вториот.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Дава вистина ако првиот внос е помал или еднаков на  вториот.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Дава вистина ако првиот внос е поголем од вториот.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Дава вистина ако првиот внос е поголем или еднаков на вториот.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Дава вистина ако обата вноса се вистинити.",
                +	"LOGIC_OPERATION_AND": "и",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Дава вистина ако барем еден од вносовите е вистинит.",
                +	"LOGIC_OPERATION_OR": "или",
                +	"LOGIC_NEGATE_TITLE": "не %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Дава вистина ако вносот е невистинит. Дава невистина ако вносот е вистинит.",
                +	"LOGIC_BOOLEAN_TRUE": "вистина",
                +	"LOGIC_BOOLEAN_FALSE": "невистина",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Дава или вистина или невистина.",
                +	"LOGIC_NULL": "ништо",
                +	"LOGIC_NULL_TOOLTIP": "Дава ништо.",
                +	"LOGIC_TERNARY_CONDITION": "испробај",
                +	"LOGIC_TERNARY_IF_TRUE": "ако е вистинито",
                +	"LOGIC_TERNARY_IF_FALSE": "ако е невистинито",
                +	"MATH_CONSTANT_HELPURL": "https://mk.wikipedia.org/wiki/Математичка_константа",
                +	"MATH_CONSTANT_TOOLTIP": "Дава една од вообичаените константи: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), или ∞ (бесконечност).",
                +	"MATH_IS_EVEN": "е парен",
                +	"MATH_IS_ODD": "е непарен",
                +	"MATH_IS_PRIME": "е прост",
                +	"MATH_IS_WHOLE": "е цел",
                +	"MATH_IS_POSITIVE": "е позитивен",
                +	"MATH_IS_NEGATIVE": "е негативен",
                +	"MATH_IS_DIVISIBLE_BY": "е делив со",
                +	"MATH_IS_TOOLTIP": "Проверува дали бројот е парен, непарен, прост, цел, позитивен, негативен или делив со некој број. Дава вистина или невистина.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter?uselang=mk",
                +	"MATH_CHANGE_TITLE": "повиши %1 за %2",
                +	"MATH_CHANGE_TOOLTIP": "Ѝ додава број на променливата „%1“.",
                +	"MATH_ROUND_HELPURL": "https://mk.wikipedia.org/wiki/Заокружување",
                +	"MATH_ROUND_TOOLTIP": "Го заокружува бројот на поголем или помал.",
                +	"MATH_ROUND_OPERATOR_ROUND": "заокружи",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "заокружи на поголемо",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "заокружи на помало",
                +	"MATH_ONLIST_OPERATOR_SUM": "збир од списокот",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Дава збир од сите броеви на списокот.",
                +	"MATH_ONLIST_OPERATOR_MIN": "најмал на списокот",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Го дава најмалиот број на списокот.",
                +	"MATH_ONLIST_OPERATOR_MAX": "најголем на списокот",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Го дава најголемиот број на списокот.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "просек на списокот",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Дава просек (аритметичка средина) од броевите на списокот.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "медијана на списокот",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Дава медијана од броевите на списокот.",
                +	"MATH_ONLIST_OPERATOR_MODE": "модул на списокот",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Дава список на најзастапен(и) елемент(и) на списокот."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ms.json b/blockly/webif/static/blockly/msg/json/ms.json
                new file mode 100644
                index 000000000..d0ed738cc
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ms.json
                @@ -0,0 +1,310 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Anakmalaysia",
                +			"Espertus"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "Perkara",
                +	"TODAY": "Hari ini",
                +	"DUPLICATE_BLOCK": "Pendua",
                +	"ADD_COMMENT": "Berikan Komen",
                +	"REMOVE_COMMENT": "Padamkan Komen",
                +	"EXTERNAL_INPUTS": "Input Luaran",
                +	"INLINE_INPUTS": "Input Sebaris",
                +	"DELETE_BLOCK": "Hapuskan Blok",
                +	"DELETE_X_BLOCKS": "Hapuskan %1 Blok",
                +	"DELETE_ALL_BLOCKS": "Hapuskan kesemua %1 blok?",
                +	"CLEAN_UP": "Kemaskan Blok",
                +	"COLLAPSE_BLOCK": "Lipat Blok",
                +	"COLLAPSE_ALL": "Lipat Blok²",
                +	"EXPAND_BLOCK": "Buka Blok",
                +	"EXPAND_ALL": "Buka Blok²",
                +	"DISABLE_BLOCK": "Matikan Blok",
                +	"ENABLE_BLOCK": "Hidupkan Blok",
                +	"HELP": "Bantuan",
                +	"CHANGE_VALUE_TITLE": "Ubah nilai:",
                +	"RENAME_VARIABLE": "Tukar nama pembolehubah...",
                +	"RENAME_VARIABLE_TITLE": "Tukar nama semua pembolehubah '%1' kepada:",
                +	"NEW_VARIABLE": "Pembolehubah baru...",
                +	"NEW_VARIABLE_TITLE": "Nama pembolehubah baru:",
                +	"COLOUR_PICKER_HELPURL": "https://ms.wikipedia.org/wiki/Warna",
                +	"COLOUR_PICKER_TOOLTIP": "Pilih satu warna daripada palet.",
                +	"COLOUR_RANDOM_TITLE": "warna rawak",
                +	"COLOUR_RANDOM_TOOLTIP": "Pilih satu warna secara rawak.",
                +	"COLOUR_RGB_TITLE": "warnakan",
                +	"COLOUR_RGB_RED": "merah",
                +	"COLOUR_RGB_GREEN": "hijau",
                +	"COLOUR_RGB_BLUE": "biru",
                +	"COLOUR_RGB_TOOLTIP": "Peroleh satu warna dengan menentukan amaun campuran merah, hijau dan biru. Kesemua nilai haruslah antara 0 hingga 100.",
                +	"COLOUR_BLEND_TITLE": "adun",
                +	"COLOUR_BLEND_COLOUR1": "warna 1",
                +	"COLOUR_BLEND_COLOUR2": "warna 2",
                +	"COLOUR_BLEND_RATIO": "nisbah",
                +	"COLOUR_BLEND_TOOLTIP": "Campurkan dua warna sekali pada nisbah yang ditentukan (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "ulang %1 kali",
                +	"CONTROLS_REPEAT_INPUT_DO": "lakukan",
                +	"CONTROLS_REPEAT_TOOLTIP": "Lakukan perintah berulang kali.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ulangi apabila",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ulangi sehingga",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Lakukan beberapa perintah apabila nilainya benar (true).",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Lakukan beberapa perintah apabila nilainya palsu (false).",
                +	"CONTROLS_FOR_TOOLTIP": "Gunakan pembolehubah '%1' pada nilai-nilai dari nombor pangkal hingga nombor hujung, mengira mengikut selang yang ditentukan, dan lakukan blok-blok yang tertentu.",
                +	"CONTROLS_FOR_TITLE": "kira dengan %1 dari %2 hingga %3 selang %4",
                +	"CONTROLS_FOREACH_TITLE": "untuk setiap perkara %1 dalam senarai %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Untuk setiap perkara dalam senarai, tetapkan pembolehubah '%1' pada perkara, kemudian lakukan beberapa perintah.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "hentikan gelung",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "teruskan dengan lelaran gelung seterusnya",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Keluar dari gelung pengandung.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Langkau seluruh gelung yang tinggal dan bersambung dengan lelaran seterusnya.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Amaran: Blok ini hanya boleh digunakan dalam satu gelung.",
                +	"CONTROLS_IF_TOOLTIP_1": "Jika nilai yang benar, lakukan beberapa penyata.",
                +	"CONTROLS_IF_TOOLTIP_2": "Jika suatu nilai benar, lakukan penyata blok pertama.  Jika tidak, bina penyata blok kedua.",
                +	"CONTROLS_IF_TOOLTIP_3": "Jika nilai yang pertama adalah benar, lakukan penyata pertama blok.  Sebaliknya, jika nilai kedua adalah benar, lakukan penyata blok kedua.",
                +	"CONTROLS_IF_TOOLTIP_4": "Jika nilai yang pertama adalah benar, lakukan penyata blok pertama.  Sebaliknya, jika nilai kedua adalah benar, lakukan penyata blok kedua.  Jika tiada nilai adalah benar, lakukan penyata blok terakhir.",
                +	"CONTROLS_IF_MSG_IF": "jika",
                +	"CONTROLS_IF_MSG_ELSEIF": "lain jika",
                +	"CONTROLS_IF_MSG_ELSE": "lain",
                +	"CONTROLS_IF_IF_TOOLTIP": "Tambah, alih keluar, atau susun semula bahagian-bahagian untuk menyusun semula blok jika.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Tambah satu syarat kepada blok jika.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Tambah yang terakhir, alihkan semua keadaan ke blok jika.",
                +	"LOGIC_COMPARE_HELPURL": "https://id.wikipedia.org/wiki/Pertidaksamaan",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Kembali benar jika kedua-dua input benar antara satu sama lain.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Taip balik benar jika kedua-dua input tidak sama.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Kembali benar jika input pertama adalah lebih kecil daripada input kedua.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Kembali benar jika input pertama adalah lebih kecil daripada atau sama dengan input kedua.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Kembali benar jika input pertama adalah lebih besar daripada input kedua.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Kembali benar jika input pertama adalah lebih besar daripada atau sama dengan input kedua.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Return true if both inputs are true.",
                +	"LOGIC_OPERATION_AND": "dan",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Return true if at least one of the inputs is true.",
                +	"LOGIC_OPERATION_OR": "atau",
                +	"LOGIC_NEGATE_TITLE": "bukan %1",
                +	"LOGIC_NEGATE_TOOLTIP": "'Benar' akan dibalas jika inputnya salah. 'Salah' akan dibalas jika inputnya benar.",
                +	"LOGIC_BOOLEAN_TRUE": "benar",
                +	"LOGIC_BOOLEAN_FALSE": "palsu",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Kembalikan samada benar atau palsu.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returns null.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "Jika benar",
                +	"LOGIC_TERNARY_IF_FALSE": "Jika palsu",
                +	"LOGIC_TERNARY_TOOLTIP": "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.",
                +	"MATH_NUMBER_HELPURL": "https://ms.wikipedia.org/wiki/Nombor",
                +	"MATH_NUMBER_TOOLTIP": "Suatu nombor.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://ms.wikipedia.org/wiki/Aritmetik",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Kembalikan jumlah kedua-dua bilangan.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Taip balik hasil tolak dua nombor tersebut.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Taip balik hasil darab dua nombor tersebut.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Taip balik hasil bahagi dua nombor tersebut.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Return the first number raised to the power of the second number.",
                +	"MATH_SINGLE_HELPURL": "https://ms.wikipedia.org/wiki/Punca_kuasa_dua",
                +	"MATH_SINGLE_OP_ROOT": "Punca kuasa dua",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Kembalikan punca kuasa nombor.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "mutlak",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Kembalikan nilai mutlak suatu nombor.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Kembalikan nombor yang songsang.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Kembali dalam logaritma nombor asli.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Kembali logarithm 10 asas nombor.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Kembalikan e kepada kuasa nombor.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Kembalikan 10 kepada kuasa nombor.",
                +	"MATH_TRIG_HELPURL": "https://ms.wikipedia.org/wiki/Fungsi_trigonometri",
                +	"MATH_TRIG_TOOLTIP_SIN": "Kembalikan darjah sine (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Kembalikan darjah kosinus (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Kembalikan darjah tangen (bukan radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Kembalikan arcsince beberapa nombor.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Kembali arccosine beberapa nombor.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Kembalikan beberapa nombor arctangent.",
                +	"MATH_CONSTANT_HELPURL": "https://ms.wikipedia.org/wiki/Pemalar_matematik",
                +	"MATH_CONSTANT_TOOLTIP": "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "Adalah genap",
                +	"MATH_IS_ODD": "aneh",
                +	"MATH_IS_PRIME": "is prime",
                +	"MATH_IS_WHOLE": "is whole",
                +	"MATH_IS_POSITIVE": "adalah positif",
                +	"MATH_IS_NEGATIVE": "negatif",
                +	"MATH_IS_DIVISIBLE_BY": "Boleh dibahagikan dengan",
                +	"MATH_IS_TOOLTIP": "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number.  Returns true or false.",
                +	"MATH_CHANGE_HELPURL": "https://id.wikipedia.org/wiki/Perjumlahan",
                +	"MATH_CHANGE_TITLE": "perubahan %1 oleh %2",
                +	"MATH_CHANGE_TOOLTIP": "Tambah nombor kepada pembolehubah '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Bulat nombor yang naik atau turun.",
                +	"MATH_ROUND_OPERATOR_ROUND": "pusingan",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "pusingan ke atas",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "Pusingan ke bawah",
                +	"MATH_ONLIST_OPERATOR_SUM": "Jumlah senarai",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Kembalikan jumlah semua nombor dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_MIN": "min dalam senarai",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Kembalikan nombor terkecil dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_MAX": "Max senarai",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Pulangkan jumlah terbesar dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "purata daripada senarai",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Kembalikan purata (min aritmetik) nilai-nilai angka di dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Median senarai",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Kembalikan nombor median dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_MODE": "jenis senarai",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Kembali senarai item yang paling biasa dalam senarai.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "sisihan piawai bagi senarai",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Kembali dengan sisihan piawai daripada senarai.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Item rawak daripada senarai",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Kembalikan elemen rawak daripada senarai.",
                +	"MATH_MODULO_HELPURL": "https://id.wikipedia.org/wiki/Operasi_modulus",
                +	"MATH_MODULO_TITLE": "remainder of %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Taip balik baki yang didapat daripada pembahagian dua nombor tersebut.",
                +	"MATH_CONSTRAIN_TITLE": "constrain %1 low %2 high %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Constrain a number to be between the specified limits (inclusive).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "integer rawak dari %1ke %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Kembalikan integer rawak diantara dua had yang ditentukan, inklusif.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "pecahan rawak",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Kembali sebahagian kecil rawak antara 0.0 (inklusif) dan 1.0 (eksklusif).",
                +	"TEXT_TEXT_HELPURL": "https://ms.wikipedia.org/wiki/Rentetan",
                +	"TEXT_TEXT_TOOLTIP": "Huruf, perkataan, atau baris teks.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "hasilkan teks dengan",
                +	"TEXT_JOIN_TOOLTIP": "Hasilkan sebahagian teks dengan menghubungkan apa jua nombor item.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "Sertai",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Add, remove, or reorder sections to reconfigure this text block.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Add an item to the text.",
                +	"TEXT_APPEND_TOOLTIP": "Append some text to variable '%1'.",
                +	"TEXT_LENGTH_TITLE": "panjang %1",
                +	"TEXT_LENGTH_TOOLTIP": "Kembalikan jumlah huruf (termasuk ruang) dalam teks yang disediakan.",
                +	"TEXT_ISEMPTY_TITLE": "%1 adalah kosong",
                +	"TEXT_ISEMPTY_TOOLTIP": "Kembalikan benar jika teks yang disediakan adalah kosong.",
                +	"TEXT_INDEXOF_TOOLTIP": "Kembalikan Indeks kejadian pertama/terakhir dari teks pertama ke dalam teks kedua.  Kembalikan %1 Jika teks tidak ditemui.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "mencari kejadian pertama teks",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "mencari kejadian terakhir teks",
                +	"TEXT_CHARAT_FROM_START": "get letter #",
                +	"TEXT_CHARAT_FROM_END": "get letter # from end",
                +	"TEXT_CHARAT_FIRST": "get first letter",
                +	"TEXT_CHARAT_LAST": "Dapatkan abjad terakhir",
                +	"TEXT_CHARAT_RANDOM": "Dapatkan abjad rawak",
                +	"TEXT_CHARAT_TOOLTIP": "Returns the letter at the specified position.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returns a specified portion of the text.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "dalam teks",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "get substring from letter #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "get substring from letter # from end",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "get substring from first letter",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "to letter #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "to letter # from end",
                +	"TEXT_GET_SUBSTRING_END_LAST": "untuk huruf terakhir",
                +	"TEXT_CHANGECASE_TOOLTIP": "Return a copy of the text in a different case.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "Kepada HURUF BESAR",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "Kepada huruf kecil",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "to Title Case",
                +	"TEXT_TRIM_TOOLTIP": "Kembali salinan teks dengan ruang yang dikeluarkan daripada satu atau hujung kedua belah.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "mengurangkan kawasan dari kedua-dua belah",
                +	"TEXT_TRIM_OPERATOR_LEFT": "mengurangkan ruang dari sebelah kiri",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "mengurangkan kawasan dari sisi kanan",
                +	"TEXT_PRINT_TITLE": "cetak %1",
                +	"TEXT_PRINT_TOOLTIP": "Cetak teks yang ditentukan, nombor atau nilai lain.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Prom untuk teks dengan mesej",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Prom untuk nombor dengan mesej",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Peringatan kepada pengguna untuk nombor.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Peringatkan pengguna untuk sebahagian teks.",
                +	"LISTS_CREATE_EMPTY_TITLE": "Wujudkan senarai kosong",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Kembalikan senarai panjang 0, yang tidak mengandungi rekod data",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Wujudkan senarai dengan apa jua nombor item.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "wujudkan senarai dengan",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "senarai",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Tambah, alih keluar, atau susun semula bahagian-bahagian untuk menyusun semula senarai blok.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Tambah item ke dalam senarai.",
                +	"LISTS_REPEAT_TOOLTIP": "Wujudkan senarai yang terdiri daripada nilai berulang mengikut nombor yang ditentukan.",
                +	"LISTS_REPEAT_TITLE": "wujudkan senarai dengan item %1 diulangi %2 kali",
                +	"LISTS_LENGTH_TITLE": "panjang %1",
                +	"LISTS_LENGTH_TOOLTIP": "Kembalikan panjang senarai",
                +	"LISTS_ISEMPTY_TITLE": "%1 adalah kosong",
                +	"LISTS_ISEMPTY_TOOLTIP": "Kembalikan benar jika senarai kosong.",
                +	"LISTS_INLIST": "dalam senarai",
                +	"LISTS_INDEX_OF_FIRST": "cari pertama item kejadian",
                +	"LISTS_INDEX_OF_LAST": "cari kejadian akhir item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Menyatakan indeks kejadian pertama/terakhir item berkenaan dalam senarai. Menyatakan %1 jika item berkenaan tidak ditemui.",
                +	"LISTS_GET_INDEX_GET": "dapatkan",
                +	"LISTS_GET_INDEX_GET_REMOVE": "dapat dan alihkan",
                +	"LISTS_GET_INDEX_REMOVE": "alihkan",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# dari akhir",
                +	"LISTS_GET_INDEX_FIRST": "pertama",
                +	"LISTS_GET_INDEX_LAST": "terakhir",
                +	"LISTS_GET_INDEX_RANDOM": "rawak",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ialah item pertama.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ialah item terakhir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Kembalikan item dalam kedudukan yang ditetapkan dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Kembalikan item pertama dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Kembalikan item pertama dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Kembalikan item rawak dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Alihkan dan kembalikan item mengikut spesifikasi posisi dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Alihkan dan kembalikan item pertama dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Alihkan dan kembalikan item terakhir dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Alihkan dan kembalikan item rawak dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Alihkan item pada posisi mengikut spesifikasi dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Alihkan item pertama dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Alihkan item terakhir dalam senarai.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Alihkan item rawak dalam senarai.",
                +	"LISTS_SET_INDEX_SET": "set",
                +	"LISTS_SET_INDEX_INSERT": "masukkan pada",
                +	"LISTS_SET_INDEX_INPUT_TO": "sebagai",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Masukkan item pada posisi yang ditentukan dalam senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Set item pertama dalam senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Set item terakhir dalam senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Set item rawak dalam senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Masukkan item pada posisi yand ditentukan dalam senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Selit item pada permulaan senarai.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Tambahkan item dalam senarai akhir.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Selit item secara rawak di dalam senarai.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "dapatkan sub-senarai daripada #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "dapatkan sub-senarai daripada # daripada terakhir",
                +	"LISTS_GET_SUBLIST_START_FIRST": "dapatkan sub-senarai daripada pertama",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "ke #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ke  # dari akhir",
                +	"LISTS_GET_SUBLIST_END_LAST": "ke akhir",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Wujudkan salinan bahagian yang ditentukan dari senarai.",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "buat senarai dgn teks",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "buat teks drpd senarai",
                +	"LISTS_SPLIT_WITH_DELIMITER": "dengan delimiter",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Pecahkan teks kepada senarai teks, berpecah di setiap delimiter.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Cantumkan senarai teks menjadi satu teks, dipecahkan oleh delimiter.",
                +	"VARIABLES_GET_TOOLTIP": "Kembalikan nilai pemboleh ubah ini.",
                +	"VARIABLES_GET_CREATE_SET": "Hasilkan 'set %1'",
                +	"VARIABLES_SET": "set %1 ke %2",
                +	"VARIABLES_SET_TOOLTIP": "Set pembolehubah ini supaya sama dengan input.",
                +	"VARIABLES_SET_CREATE_GET": "Hasilkan 'set %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "Untuk",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "Buat sesuatu",
                +	"PROCEDURES_BEFORE_PARAMS": "dengan:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "dengan:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Menghasilkan suatu fungsi tanpa output.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Terangkan fungsi ini...",
                +	"PROCEDURES_DEFRETURN_RETURN": "kembali",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Mencipta satu fungsi dengan pengeluaran.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "bolehkan kenyataan",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Amaran: Fungsi ini mempunyai parameter yang berganda.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ms.wikipedia.org/wiki/Fungsi",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Run the user-defined function '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ms.wikipedia.org/wiki/Fungsi",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Run the user-defined function '%1' and use its output.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "Input-input",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Tambah, alih keluar atau susun semula input pada fungsi ini.",
                +	"PROCEDURES_MUTATORARG_TITLE": "Nama input:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Tambah satu input pada fungsi.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Serlahkan definisi fungsi",
                +	"PROCEDURES_CREATE_DO": "Hasilkan '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "If a value is true, then return a second value.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Amaran: Blok ini hanya boleh digunakan dalam fungsi definisi."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/nb.json b/blockly/webif/static/blockly/msg/json/nb.json
                new file mode 100644
                index 000000000..55362e7ea
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/nb.json
                @@ -0,0 +1,368 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Cocu",
                +			"Kingu",
                +			"아라",
                +			"SuperPotato",
                +			"Jon Harald Søby"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "I dag",
                +	"DUPLICATE_BLOCK": "duplikat",
                +	"ADD_COMMENT": "Legg til kommentar",
                +	"REMOVE_COMMENT": "Fjern kommentar",
                +	"EXTERNAL_INPUTS": "Eksterne kilder",
                +	"INLINE_INPUTS": "Interne kilder",
                +	"DELETE_BLOCK": "Slett blokk",
                +	"DELETE_X_BLOCKS": "Slett %1 blokker",
                +	"DELETE_ALL_BLOCKS": "Slett alle %1 blokker?",
                +	"CLEAN_UP": "Rydd opp Blocks",
                +	"COLLAPSE_BLOCK": "Skjul blokk",
                +	"COLLAPSE_ALL": "Skjul blokker",
                +	"EXPAND_BLOCK": "Utvid blokk",
                +	"EXPAND_ALL": "Utvid blokker",
                +	"DISABLE_BLOCK": "Deaktiver blokk",
                +	"ENABLE_BLOCK": "Aktiver blokk",
                +	"HELP": "Hjelp",
                +	"UNDO": "Angre",
                +	"REDO": "Gjør om",
                +	"CHANGE_VALUE_TITLE": "Bytt verdi:",
                +	"RENAME_VARIABLE": "Gi nytt navn til variabel...",
                +	"RENAME_VARIABLE_TITLE": "Endre navnet til alle '%1' variabler til:",
                +	"NEW_VARIABLE": "Opprett variabel...",
                +	"NEW_VARIABLE_TITLE": "Nytt variabelnavn:",
                +	"VARIABLE_ALREADY_EXISTS": "En variabel med navn «%1» finnes allerede.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "En variabel med navn «%1» finnes allerede for en annen variabel av typen «%2».",
                +	"PROCEDURE_ALREADY_EXISTS": "En prosedyre med navn «%1» finnes allerede.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Slett %1 bruk av variabelen «%2»?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Kan ikke slette variabelen «%1» fordi den er del av definisjonen for funksjonen «%2»",
                +	"DELETE_VARIABLE": "Slett variabelen «%1»",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Velg en farge fra paletten.",
                +	"COLOUR_RANDOM_TITLE": "tilfeldig farge",
                +	"COLOUR_RANDOM_TOOLTIP": "Velg en tilfeldig farge.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "farge med",
                +	"COLOUR_RGB_RED": "rød",
                +	"COLOUR_RGB_GREEN": "grønn",
                +	"COLOUR_RGB_BLUE": "blå",
                +	"COLOUR_RGB_TOOLTIP": "Lag en farge med angitt verdi av rød, grønn og blå. Alle verdier må være mellom 0 og 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "blande",
                +	"COLOUR_BLEND_COLOUR1": "farge 1",
                +	"COLOUR_BLEND_COLOUR2": "farge 2",
                +	"COLOUR_BLEND_RATIO": "forhold",
                +	"COLOUR_BLEND_TOOLTIP": "Blander to farger sammen med et gitt forhold (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "gjenta %1 ganger",
                +	"CONTROLS_REPEAT_INPUT_DO": "gjør",
                +	"CONTROLS_REPEAT_TOOLTIP": "Gjenta noen instruksjoner flere ganger.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "gjenta mens",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "gjenta til",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Så lenge et utsagn stemmer, utfør noen instruksjoner.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Så lenge et utsagn ikke stemmer, gjør noen instruksjoner.",
                +	"CONTROLS_FOR_TOOLTIP": "Ha variabel \"%1\" ta verdiene fra start nummer til slutt nummer, telle med spesifisert intervall og lag de spesifiserte blokkene.",
                +	"CONTROLS_FOR_TITLE": "tell med %1 fra %2 til %3 med %4",
                +	"CONTROLS_FOREACH_TITLE": "for hvert element %1 i listen %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "For hvert element i en liste, angi variabelen '%1' til elementet, og deretter lag noen setninger.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "bryt ut av løkken",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "fortsett med neste gjentakelse av løkken",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Bryt ut av den gjeldende løkken.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Hopp over resten av denne løkken og fortsett med neste gjentakelse.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Advarsel: Denne blokken kan kun brukes innenfor en løkke.",
                +	"CONTROLS_IF_TOOLTIP_1": "Hvis dette er sant, så gjør følgende.",
                +	"CONTROLS_IF_TOOLTIP_2": "Hvis dette er sant, så utfør den første blokken av instruksjoner. Hvis ikke, utfør den andre blokken.",
                +	"CONTROLS_IF_TOOLTIP_3": "Hvis det første stemmer, så utfør den første blokken av instruksjoner. Ellers, hvis det andre stemmer, utfør den andre blokken av instruksjoner.",
                +	"CONTROLS_IF_TOOLTIP_4": "Hvis den første verdien er sann, så utfør den første blokken med setninger. Ellers, hvis den andre verdien er sann, så utfør den andre blokken med setninger. Hvis ingen av verdiene er sanne, så utfør den siste blokken med setninger.",
                +	"CONTROLS_IF_MSG_IF": "hvis",
                +	"CONTROLS_IF_MSG_ELSEIF": "ellers hvis",
                +	"CONTROLS_IF_MSG_ELSE": "ellers",
                +	"CONTROLS_IF_IF_TOOLTIP": "Legg til, fjern eller flytt seksjoner i denne hvis-blokken.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Legg til en betingelse til hvis blokken.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Legg til hva som skal skje hvis de andre ikke slår til.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Avbryt",
                +	"IOS_ERROR": "Feil",
                +	"IOS_PROCEDURES_INPUTS": "PARAMETERE",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Legg til parameter",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Tillat kommandoer",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Denne funksjonen har duplikatparametere.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Legg til variabel",
                +	"IOS_VARIABLES_ADD_BUTTON": "Legg til",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Endre navn",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Slett",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Variabelnavn",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Du kan ikke bruke et tomt variabelnavn.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Returnerer sann hvis begge inputene er like hverandre.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Returnerer sant hvis begge argumentene er ulike hverandre.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Returnerer sant hvis det første argumentet er mindre enn det andre argumentet.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Returnerer sant hvis det første argumentet er mindre enn eller likt det andre argumentet.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Returnerer sant hvis det første argumentet er større enn den andre argumentet.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Returnerer sant hvis det første argumentet er større enn eller likt det andre argumentet.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Returnerer sant hvis begge argumentene er sanne.",
                +	"LOGIC_OPERATION_AND": "og",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Returnerer sant hvis minst ett av argumentene er sant.",
                +	"LOGIC_OPERATION_OR": "eller",
                +	"LOGIC_NEGATE_TITLE": "ikke %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returnerer sant hvis argumentet er usant. Returnerer usant hvis argumentet er sant.",
                +	"LOGIC_BOOLEAN_TRUE": "sann",
                +	"LOGIC_BOOLEAN_FALSE": "usann",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returnerer enten sann eller usann.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returnerer null.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "hvis sant",
                +	"LOGIC_TERNARY_IF_FALSE": "hvis usant",
                +	"LOGIC_TERNARY_TOOLTIP": "Sjekk betingelsen i 'test'. Hvis betingelsen er sann, da returneres 'hvis sant' verdien. Hvis ikke returneres 'hvis usant' verdien.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Et tall.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "x",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://no.wikipedia.org/wiki/Aritmetikk",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Returnerer summen av to tall.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Returner differansen mellom to tall.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Returner produktet av to tall.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Returner kvotienten av to tall.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Returner det første tallet opphøyd i den andre tallet.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "kvadratrot",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Returner kvadratroten av et tall.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluttverdi",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Returner absoluttverdien av et tall.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Returner det negative tallet.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Returner den naturlige logaritmen til et tall.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Returner base-10 logaritmen til et tall.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Returner e opphøyd i et tall.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Returner 10 opphøyd i et tall.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Returner sinus av en vinkel (ikke radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Returner cosinus av en vinkel (ikke radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Returner tangenten av en vinkel (ikke radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Returner arcsinus til et tall.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Returner arccosinus til et tall.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Returner arctangens til et tall.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Returner en av felleskonstantene π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), eller ∞ (uendelig).",
                +	"MATH_IS_EVEN": "er et partall",
                +	"MATH_IS_ODD": "er et oddetall",
                +	"MATH_IS_PRIME": "er et primtall",
                +	"MATH_IS_WHOLE": "er et heltall",
                +	"MATH_IS_POSITIVE": "er positivt",
                +	"MATH_IS_NEGATIVE": "er negativer negativt",
                +	"MATH_IS_DIVISIBLE_BY": "er delelig med",
                +	"MATH_IS_TOOLTIP": "Sjekk om et tall er et partall, oddetall, primtall, heltall, positivt, negativt, eller om det er delelig med et annet tall. Returnerer sant eller usant.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "endre %1 ved %2",
                +	"MATH_CHANGE_TOOLTIP": "Addere et tall til variabelen '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Avrund et tall ned eller opp.",
                +	"MATH_ROUND_OPERATOR_ROUND": "avrunding",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "rund opp",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "rund ned",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "summen av listen",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Returner summen av alle tallene i listen.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimum av listen",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Returner det minste tallet i listen.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maksimum av liste",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Returner det største tallet i listen.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "gjennomsnittet av listen",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Returner det aritmetiske gjennomsnittet av tallene i listen.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "medianen til listen",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Returner listens median.",
                +	"MATH_ONLIST_OPERATOR_MODE": "Listens typetall",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Returner en liste av de vanligste elementene i listen.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standardavviket til listen",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Returner listens standardavvik.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "tilfeldig element i listen",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Returner et tilfeldig element fra listen.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "resten av %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Returner resten fra delingen av to tall.",
                +	"MATH_CONSTRAIN_TITLE": "begrense %1 lav %2 høy %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Begrens et tall til å være mellom de angitte grenseverdiene (inklusiv).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "Et tilfeldig heltall mellom %1 og %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Returner et tilfeldig tall mellom de to spesifiserte grensene, inkludert de to.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "tilfeldig flyttall",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Returner et tilfeldig flyttall mellom 0.0 (inkludert) og 1.0 (ikke inkludert).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "En bokstav, ett ord eller en linje med tekst.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "lage tekst med",
                +	"TEXT_JOIN_TOOLTIP": "Opprett en tekst ved å sette sammen et antall elementer.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "føy sammen",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Legg til, fjern eller forandre rekkefølgen for å forandre på denne tekstblokken.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Legg til et element til teksten.",
                +	"TEXT_APPEND_TITLE": "til %1, legg til teksten %2",
                +	"TEXT_APPEND_TOOLTIP": "Tilføy tekst til variabelen '%1'.",
                +	"TEXT_LENGTH_TITLE": "lengden av %1",
                +	"TEXT_LENGTH_TOOLTIP": "Returnerer antall bokstaver (inkludert mellomrom) i den angitte teksten.",
                +	"TEXT_ISEMPTY_TITLE": "%1 er tom",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returnerer sann hvis den angitte teksten er tom.",
                +	"TEXT_INDEXOF_TOOLTIP": "Returnerer posisjonen for første/siste forekomsten av den første tekst i den andre teksten.  Returnerer %1 hvis teksten ikke blir funnet.",
                +	"TEXT_INDEXOF_TITLE": "i teksten %1, %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "finn første forekomst av tekst",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "finn siste forekomst av tekst",
                +	"TEXT_CHARAT_TITLE": "i teksten %1, %2",
                +	"TEXT_CHARAT_FROM_START": "hent bokstav #",
                +	"TEXT_CHARAT_FROM_END": "hent bokstav # fra slutten",
                +	"TEXT_CHARAT_FIRST": "hent første bokstav",
                +	"TEXT_CHARAT_LAST": "hent den siste bokstaven",
                +	"TEXT_CHARAT_RANDOM": "hent en tilfeldig bokstav",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Returnerer bokstaven på angitt plassering.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returnerer den angitte delen av teksten.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "i tekst",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "hent delstreng fra bokstav #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "hent delstreng fra bokstav # fra slutten",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "hent delstreng fra første bokstav",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "til bokstav #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "til bokstav # fra slutten",
                +	"TEXT_GET_SUBSTRING_END_LAST": "til siste bokstav",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "Returnerer en kopi av teksten der store og små bokstaver er byttet om.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "til STORE BOKSTAVER",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "til små bokstaver",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "til store forbokstaver",
                +	"TEXT_TRIM_TOOLTIP": "Returner en kopi av teksten med mellomrom fjernet fra en eller begge sidene.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "fjern mellomrom fra begge sider av",
                +	"TEXT_TRIM_OPERATOR_LEFT": "fjern mellomrom fra venstre side av",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "fjern mellomrom fra høyre side av",
                +	"TEXT_PRINT_TITLE": "skriv ut %1",
                +	"TEXT_PRINT_TOOLTIP": "Skriv ut angitt tekst, tall eller annet innhold.",
                +	"TEXT_PROMPT_TYPE_TEXT": "spør om tekst med en melding",
                +	"TEXT_PROMPT_TYPE_NUMBER": "spør om et tall med en melding",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Be brukeren om et tall.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Spør brukeren om tekst.",
                +	"TEXT_COUNT_MESSAGE0": "tell %1 i %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Tell hvor mange ganger noe tekst dukker opp i annen tekst.",
                +	"TEXT_REPLACE_MESSAGE0": "erstatt %1 med %2 i %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Erstatter alle forekomster av noe tekst i en annen tekst.",
                +	"TEXT_REVERSE_MESSAGE0": "reverser %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Reverserer rekkefølgen på tegnene i teksten.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "opprett en tom liste",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Returnerer en tom liste, altså med lengde 0",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Lag en liste med et vilkårlig antall elementer.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "lag en liste med",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "liste",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Legg til, fjern eller endre rekkefølgen for å endre på denne delen av listen.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Tilføy et element til listen.",
                +	"LISTS_REPEAT_TOOLTIP": "Lager en liste hvor den gitte verdien gjentas et antall ganger.",
                +	"LISTS_REPEAT_TITLE": "Lag en liste hvor elementet %1 forekommer %2 ganger",
                +	"LISTS_LENGTH_TITLE": "lengden på %1",
                +	"LISTS_LENGTH_TOOLTIP": "Returnerer lengden til en liste.",
                +	"LISTS_ISEMPTY_TITLE": "%1 er tom",
                +	"LISTS_ISEMPTY_TOOLTIP": "Returnerer sann hvis listen er tom.",
                +	"LISTS_INLIST": "i listen",
                +	"LISTS_INDEX_OF_FIRST": "finn første forekomst av elementet",
                +	"LISTS_INDEX_OF_LAST": "finn siste forekomst av elementet",
                +	"LISTS_INDEX_OF_TOOLTIP": "Returnerer indeksen av den første/siste forekomsten av elementet i lista. Returnerer %1 hvis ikke funnet.",
                +	"LISTS_GET_INDEX_GET": "hent",
                +	"LISTS_GET_INDEX_GET_REMOVE": "hent og fjern",
                +	"LISTS_GET_INDEX_REMOVE": "fjern",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# fra slutten",
                +	"LISTS_GET_INDEX_FIRST": "først",
                +	"LISTS_GET_INDEX_LAST": "siste",
                +	"LISTS_GET_INDEX_RANDOM": "tilfeldig",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 er det første elementet.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 er det siste elementet.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Returner elementet på den angitte posisjonen i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Returnerer det første elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Returnerer det siste elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Returnerer et tilfeldig element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Fjerner og returnerer elementet ved en gitt posisjon i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Fjerner og returnerer det første elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Fjerner og returnerer det siste elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Fjerner og returnerer et tilfeldig element i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Fjerner et element ved en gitt posisjon i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Fjerner det første elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Fjerner det siste elementet i en liste.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Fjerner et tilfeldig element i en liste.",
                +	"LISTS_SET_INDEX_SET": "sett",
                +	"LISTS_SET_INDEX_INSERT": "sett inn ved",
                +	"LISTS_SET_INDEX_INPUT_TO": "som",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Setter inn elementet ved den angitte posisjonen i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Angir det første elementet i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Angir det siste elementet i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Angir et tilfeldig element i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Setter inn elementet ved den angitte posisjonen i en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Setter inn elementet i starten av en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Tilføy elementet til slutten av en liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Setter inn elementet ved en tilfeldig posisjon i en liste.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "Hent del-listen fra #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "Hent de siste # elementene",
                +	"LISTS_GET_SUBLIST_START_FIRST": "Hent en del av listen",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "til #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "til # fra slutten",
                +	"LISTS_GET_SUBLIST_END_LAST": "til siste",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Kopiérer en ønsket del av en liste.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sorter %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sorter en kopi av en liste.",
                +	"LISTS_SORT_ORDER_ASCENDING": "stigende",
                +	"LISTS_SORT_ORDER_DESCENDING": "synkende",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerisk",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetisk",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetisk, ignorert store/små bokstaver",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "lag liste av tekst",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "lag tekst av liste",
                +	"LISTS_SPLIT_WITH_DELIMITER": "med avgrenser",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Splitt teksten til en liste med tekster, brutt ved hver avgrenser.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Føy sammen en liste tekster til én tekst, avskilt av en avgrenser.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "reverser %1",
                +	"LISTS_REVERSE_TOOLTIP": "Reverser en kopi av ei liste.",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_TOOLTIP": "Returnerer verdien av denne variabelen.",
                +	"VARIABLES_GET_CREATE_SET": "Opprett 'sett %1'",
                +	"VARIABLES_SET": "sett %1 til %2",
                +	"VARIABLES_SET_TOOLTIP": "Setter verdien av denne variablen lik parameteren.",
                +	"VARIABLES_SET_CREATE_GET": "Opprett 'hent %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "til",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "gjør noe",
                +	"PROCEDURES_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Opprett en funksjon som ikke har noe resultat.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Beskriv denne funksjonen...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "returner",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Oppretter en funksjon som har et resultat.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "tillat uttalelser",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Advarsel: Denne funksjonen har duplikate parametere.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Kjør den brukerdefinerte funksjonen '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Kjør den brukerdefinerte funksjonen'%1' og bruk resultatet av den.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "parametere",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Legg til, fjern eller endre rekkefølgen på input til denne funksjonen.",
                +	"PROCEDURES_MUTATORARG_TITLE": "Navn på parameter:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Legg til en input til funksjonen.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Marker funksjonsdefinisjonen",
                +	"PROCEDURES_CREATE_DO": "Opprett '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Hvis en verdi er sann, returner da en annen verdi.",
                +	"PROCEDURES_IFRETURN_WARNING": "Advarsel: Denne blokken kan bare benyttes innenfor en funksjonsdefinisjon."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/nl.json b/blockly/webif/static/blockly/msg/json/nl.json
                new file mode 100644
                index 000000000..85021e177
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/nl.json
                @@ -0,0 +1,387 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Siebrand",
                +			"McDutchie",
                +			"Ribert",
                +			"MedShot",
                +			"아라",
                +			"JaapDeKleine",
                +			"Sjoerddebruin",
                +			"Lemondoge",
                +			"Jeleniccz",
                +			"Festina90"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Vandaag",
                +	"DUPLICATE_BLOCK": "Duplicaat",
                +	"ADD_COMMENT": "Reactie toevoegen",
                +	"REMOVE_COMMENT": "Opmerking verwijderen",
                +	"EXTERNAL_INPUTS": "Externe invoer",
                +	"INLINE_INPUTS": "Inline invoer",
                +	"DELETE_BLOCK": "Blok verwijderen",
                +	"DELETE_X_BLOCKS": "%1 blokken verwijderen",
                +	"DELETE_ALL_BLOCKS": "Alle %1 blokken verwijderen?",
                +	"CLEAN_UP": "Blokken opschonen",
                +	"COLLAPSE_BLOCK": "Blok samenvouwen",
                +	"COLLAPSE_ALL": "Blokken samenvouwen",
                +	"EXPAND_BLOCK": "Blok uitvouwen",
                +	"EXPAND_ALL": "Blokken uitvouwen",
                +	"DISABLE_BLOCK": "Blok uitschakelen",
                +	"ENABLE_BLOCK": "Blok inschakelen",
                +	"HELP": "Hulp",
                +	"UNDO": "Ongedaan maken",
                +	"REDO": "Opnieuw",
                +	"CHANGE_VALUE_TITLE": "Waarde wijzigen:",
                +	"RENAME_VARIABLE": "Variabele hernoemen...",
                +	"RENAME_VARIABLE_TITLE": "Alle variabelen \"%1\" hernoemen naar:",
                +	"NEW_VARIABLE": "Variabele maken...",
                +	"NEW_VARIABLE_TITLE": "Nieuwe variabelenaam:",
                +	"VARIABLE_ALREADY_EXISTS": "Er bestaat al een variabele met de naam \"%1\".",
                +	"PROCEDURE_ALREADY_EXISTS": "Er bestaat al een variabele met de naam \"%1\".",
                +	"DELETE_VARIABLE_CONFIRMATION": "%1 gebruiken van de variabele \"%2\" verwijderen?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "De variabele \"%1\" kan niet verwijderd worden omdat die onderdeel uitmaakt van de definitie van de functie \"%2\"",
                +	"DELETE_VARIABLE": "Verwijder de variabele \"%1\"",
                +	"COLOUR_PICKER_HELPURL": "https://nl.wikipedia.org/wiki/Kleur",
                +	"COLOUR_PICKER_TOOLTIP": "Kies een kleur in het palet.",
                +	"COLOUR_RANDOM_TITLE": "willekeurige kleur",
                +	"COLOUR_RANDOM_TOOLTIP": "Kies een willekeurige kleur.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "kleuren met",
                +	"COLOUR_RGB_RED": "rood",
                +	"COLOUR_RGB_GREEN": "groen",
                +	"COLOUR_RGB_BLUE": "blauw",
                +	"COLOUR_RGB_TOOLTIP": "Maak een kleur met de opgegeven hoeveelheid rood, groen en blauw.  Alle waarden moeten tussen 0 en 100 liggen.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "mengen",
                +	"COLOUR_BLEND_COLOUR1": "kleur 1",
                +	"COLOUR_BLEND_COLOUR2": "kleur 2",
                +	"COLOUR_BLEND_RATIO": "verhouding",
                +	"COLOUR_BLEND_TOOLTIP": "Mengt twee kleuren samen met een bepaalde verhouding (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://nl.wikipedia.org/wiki/Repetitie_(informatica)#For_en_Foreach",
                +	"CONTROLS_REPEAT_TITLE": "%1 keer herhalen",
                +	"CONTROLS_REPEAT_INPUT_DO": "voer uit",
                +	"CONTROLS_REPEAT_TOOLTIP": "Voer een aantal opdrachten meerdere keren uit.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://github.com/google/blockly/wiki/Loops#repeat",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "herhalen zolang",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "herhalen totdat",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Terwijl een waarde waar is de volgende opdrachten uitvoeren.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Terwijl een waarde onwaar is de volgende opdrachten uitvoeren.",
                +	"CONTROLS_FOR_HELPURL": "https://github.com/google/blockly/wiki/Loops#count-with",
                +	"CONTROLS_FOR_TOOLTIP": "Laat de variabele \"%1\" de waarden aannemen van het beginnummer tot het laatste nummer, tellende met het opgegeven interval, en met uitvoering van de opgegeven blokken.",
                +	"CONTROLS_FOR_TITLE": "rekenen met %1 van %2 tot %3 in stappen van %4",
                +	"CONTROLS_FOREACH_TITLE": "voor ieder item %1 in lijst %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Voor ieder item in een lijst, stel de variabele \"%1\" in op het item en voer daarna opdrachten uit.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "uit lus breken",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "doorgaan met de volgende iteratie van de lus",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "uit de bovenliggende lus breken",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "De rest van deze lus overslaan en doorgaan met de volgende herhaling.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Waarschuwing: dit blok mag alleen gebruikt worden in een lus.",
                +	"CONTROLS_IF_HELPURL": "https://github.com/google/blockly/wiki/IfElse",
                +	"CONTROLS_IF_TOOLTIP_1": "Als een waarde waar is, voer dan opdrachten uit.",
                +	"CONTROLS_IF_TOOLTIP_2": "Als een waarde waar is, voert dan het eerste blok met opdrachten uit. Voer andere het tweede blok met opdrachten uit.",
                +	"CONTROLS_IF_TOOLTIP_3": "Als de eerste waarde waar is, voer dan het eerste blok met opdrachten uit. Voer anders, als de tweede waarde waar is, het tweede blok met opdrachten uit.",
                +	"CONTROLS_IF_TOOLTIP_4": "Als de eerste waarde \"waar\" is, voer dan het eerste blok uit. Voer anders wanneer de tweede waarde \"waar\" is, het tweede blok uit. Als geen van beide waarden waar zijn, voer dan het laatste blok uit.",
                +	"CONTROLS_IF_MSG_IF": "als",
                +	"CONTROLS_IF_MSG_ELSEIF": "anders als",
                +	"CONTROLS_IF_MSG_ELSE": "anders",
                +	"CONTROLS_IF_IF_TOOLTIP": "Voeg stukken toe, verwijder of wijzig de volgorde om dit \"als\"-blok te wijzigen.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Voeg een voorwaarde toe aan het als-blok.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Voeg een laatste, vang-alles conditie toe aan het als-statement.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Annuleren",
                +	"IOS_ERROR": "Fout",
                +	"IOS_PROCEDURES_INPUTS": "INVOER",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Invoer toevoegen",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Statements toestaan",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Deze functie heeft dubbele invoeren.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Variabele toevoegen",
                +	"IOS_VARIABLES_ADD_BUTTON": "Toevoegen",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Hernoemen",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Verwijderen",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Variabelenaam",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "U kunt geen lege variabelenaam gebruiken.",
                +	"LOGIC_COMPARE_HELPURL": "https://nl.wikipedia.org/wiki/Ongelijkheid_(wiskunde)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Geeft \"waar\", als beide waarden gelijk aan elkaar zijn.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Geeft \"waar\" terug als de waarden niet gelijk zijn aan elkaar.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Geeft \"waar\" als de eerste invoer kleiner is dan de tweede invoer.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Geeft \"waar\" terug als de eerste invoer kleiner of gelijk is aan de tweede invoer.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Geeft \"waar\" terug als de eerste invoer meer is dan de tweede invoer.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Geeft \"waar\" terug als de eerste invoer groter is of gelijk aan de tweede invoer.",
                +	"LOGIC_OPERATION_HELPURL": "https://github.com/google/blockly/wiki/Logic#logical-operations",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Geeft waar als beide waarden waar zijn.",
                +	"LOGIC_OPERATION_AND": "en",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Geeft \"waar\" terug als in ieder geval één van de waarden waar is.",
                +	"LOGIC_OPERATION_OR": "of",
                +	"LOGIC_NEGATE_HELPURL": "https://github.com/google/blockly/wiki/Logic#not",
                +	"LOGIC_NEGATE_TITLE": "niet %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Geeft \"waar\" terug als de invoer \"onwaar\" is. Geeft \"onwaar\" als de invoer \"waar\" is.",
                +	"LOGIC_BOOLEAN_HELPURL": "https://github.com/google/blockly/wiki/Logic#values",
                +	"LOGIC_BOOLEAN_TRUE": "waar",
                +	"LOGIC_BOOLEAN_FALSE": "onwaar",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Geeft \"waar\" of \"onwaar\" terug.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "niets",
                +	"LOGIC_NULL_TOOLTIP": "Geeft niets terug.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "als waar",
                +	"LOGIC_TERNARY_IF_FALSE": "als onwaar",
                +	"LOGIC_TERNARY_TOOLTIP": "Test de voorwaarde in \"test\". Als de voorwaarde \"waar\" is, geef de waarde van \"als waar\" terug; geef anders de waarde van \"als onwaar\" terug.",
                +	"MATH_NUMBER_HELPURL": "https://nl.wikipedia.org/wiki/Getal_%28wiskunde%29",
                +	"MATH_NUMBER_TOOLTIP": "Een getal.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "arctan",
                +	"MATH_ARITHMETIC_HELPURL": "https://nl.wikipedia.org/wiki/Rekenen",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Geeft de som van 2 getallen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Geeft het verschil van de twee getallen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Geeft het product terug van de twee getallen.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Geeft de gedeelde waarde van twee getallen.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Geeft het eerste getal tot de macht van het tweede getal.",
                +	"MATH_SINGLE_HELPURL": "https://nl.wikipedia.org/wiki/Vierkantswortel",
                +	"MATH_SINGLE_OP_ROOT": "wortel",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Geeft de wortel van een getal.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluut",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Geeft de absolute waarde van een getal.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Geeft de negatief van een getal.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Geeft het natuurlijk logaritme van een getal.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Geeft het logaritme basis 10 van een getal.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Geeft e tot de macht van een getal.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Geeft 10 tot de macht van een getal.",
                +	"MATH_TRIG_HELPURL": "https://nl.wikipedia.org/wiki/Goniometrische_functie",
                +	"MATH_TRIG_TOOLTIP_SIN": "Geeft de sinus van een graad (geen radialen).",
                +	"MATH_TRIG_TOOLTIP_COS": "Geeft de cosinus van een graad (geen radialen).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Geeft de tangens van een graad (geen radialen).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Geeft de arcsinus van een getal.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Geeft de arccosinus van een getal.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Geeft de arctangens van een getal.",
                +	"MATH_CONSTANT_HELPURL": "https://nl.wikipedia.org/wiki/Wiskundige_constante",
                +	"MATH_CONSTANT_TOOLTIP": "Geeft een van de vaak voorkomende constante waardes:  π (3.141…), e (2.718…), φ (1.618…), √2 (1.414…), √½ (0.707…), of ∞ (oneindig).",
                +	"MATH_IS_EVEN": "is even",
                +	"MATH_IS_ODD": "is oneven",
                +	"MATH_IS_PRIME": "is priemgetal",
                +	"MATH_IS_WHOLE": "is geheel getal",
                +	"MATH_IS_POSITIVE": "is positief",
                +	"MATH_IS_NEGATIVE": "is negatief",
                +	"MATH_IS_DIVISIBLE_BY": "is deelbaar door",
                +	"MATH_IS_TOOLTIP": "Test of een getal even, oneven, een priemgetal, geheel, positief of negatief is, of deelbaar is door een bepaald getal. Geeft \"waar\" of \"onwaar\".",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%1 wijzigen met %2",
                +	"MATH_CHANGE_TOOLTIP": "Voegt een getal toe aan variabele \"%1\".",
                +	"MATH_ROUND_HELPURL": "https://nl.wikipedia.org/wiki/Afronden",
                +	"MATH_ROUND_TOOLTIP": "Rondt een getal af omhoog of naar beneden.",
                +	"MATH_ROUND_OPERATOR_ROUND": "afronden",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "omhoog afronden",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "naar beneden afronden",
                +	"MATH_ONLIST_OPERATOR_SUM": "som van lijst",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Geeft de som van alle getallen in de lijst.",
                +	"MATH_ONLIST_OPERATOR_MIN": "laagste uit lijst",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Geeft het kleinste getal uit een lijst.",
                +	"MATH_ONLIST_OPERATOR_MAX": "hoogste uit lijst",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Geeft het grootste getal in een lijst.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "gemiddelde van lijst",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Geeft het gemiddelde terug van de numerieke waardes in een lijst.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediaan van lijst",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Geeft de mediaan in de lijst.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modi van lijst",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Geeft een lijst van de meest voorkomende onderdelen in de lijst.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standaarddeviatie van lijst",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Geeft de standaardafwijking van de lijst.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "willekeurige item van lijst",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Geeft een willekeurig item uit de lijst terug.",
                +	"MATH_MODULO_HELPURL": "https://nl.wikipedia.org/wiki/Modulair_rekenen",
                +	"MATH_MODULO_TITLE": "restgetal van %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Geeft het restgetal van het resultaat van de deling van de twee getallen.",
                +	"MATH_CONSTRAIN_TITLE": "beperk %1 van minimaal %2 tot maximaal %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Beperk een getal tussen de twee opgegeven limieten (inclusief).",
                +	"MATH_RANDOM_INT_HELPURL": "https://nl.wikipedia.org/wiki/Toevalsgenerator",
                +	"MATH_RANDOM_INT_TITLE": "willekeurig geheel getal van %1 tot %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Geeft een willekeurig getal tussen de 2 opgegeven limieten in, inclusief.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://nl.wikipedia.org/wiki/Toevalsgenerator",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "willekeurige fractie",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Geeft een willekeurige fractie tussen 0.0 (inclusief) en 1.0 (exclusief).",
                +	"TEXT_TEXT_HELPURL": "https://nl.wikipedia.org/wiki/String_%28informatica%29",
                +	"TEXT_TEXT_TOOLTIP": "Een letter, woord of een regel tekst.",
                +	"TEXT_JOIN_HELPURL": "https://github.com/google/blockly/wiki/Text#text-creation",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "maak tekst met",
                +	"TEXT_JOIN_TOOLTIP": "Maakt een stuk tekst door één of meer items samen te voegen.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "samenvoegen",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Toevoegen, verwijderen of volgorde wijzigen van secties om dit tekstblok opnieuw in te stellen.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Voegt een item aan de tekst toe.",
                +	"TEXT_APPEND_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_APPEND_TITLE": "voor%1 voeg tekst toe van %2",
                +	"TEXT_APPEND_TOOLTIP": "Voeg tekst toe aan de variabele \"%1\".",
                +	"TEXT_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_LENGTH_TITLE": "lengte van %1",
                +	"TEXT_LENGTH_TOOLTIP": "Geeft het aantal tekens terug (inclusief spaties) in de opgegeven tekst.",
                +	"TEXT_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Text#checking-for-empty-text",
                +	"TEXT_ISEMPTY_TITLE": "%1 is leeg",
                +	"TEXT_ISEMPTY_TOOLTIP": "Geeft \"waar\" terug, als de opgegeven tekst leeg is.",
                +	"TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text",
                +	"TEXT_INDEXOF_TOOLTIP": "Geeft de index terug van het eerste of laatste voorkomen van de eerste tekst in de tweede tekst. Geeft %1 terug als de tekst niet gevonden is.",
                +	"TEXT_INDEXOF_TITLE": "in tekst %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "zoek eerste voorkomen van tekst",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "zoek het laatste voorkomen van tekst",
                +	"TEXT_CHARAT_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-text",
                +	"TEXT_CHARAT_TITLE": "in tekst %1 %2",
                +	"TEXT_CHARAT_FROM_START": "haal letter # op",
                +	"TEXT_CHARAT_FROM_END": "haal letter # op vanaf einde",
                +	"TEXT_CHARAT_FIRST": "haal eerste letter op",
                +	"TEXT_CHARAT_LAST": "haal laatste letter op",
                +	"TEXT_CHARAT_RANDOM": "haal willekeurige letter op",
                +	"TEXT_CHARAT_TOOLTIP": "Geeft de letter op de opgegeven positie terug.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Geeft het opgegeven onderdeel van de tekst terug.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in tekst",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "haal subtekst op vanaf letter #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "haal subtekst op vanaf letter # vanaf einde",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "haal subtekst op van eerste letter",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "naar letter #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "van letter # tot einde",
                +	"TEXT_GET_SUBSTRING_END_LAST": "naar laatste letter",
                +	"TEXT_CHANGECASE_HELPURL": "https://github.com/google/blockly/wiki/Text#adjusting-text-case",
                +	"TEXT_CHANGECASE_TOOLTIP": "Geef een kopie van de tekst met veranderde hoofdletters terug.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "naar HOOFDLETTERS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "naar kleine letters",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "naar Hoofdletter Per Woord",
                +	"TEXT_TRIM_HELPURL": "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces",
                +	"TEXT_TRIM_TOOLTIP": "Geeft een kopie van de tekst met verwijderde spaties van één of beide kanten.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "spaties van beide kanten afhalen van",
                +	"TEXT_TRIM_OPERATOR_LEFT": "spaties van de linkerkant verwijderen van",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "spaties van de rechterkant verwijderen van",
                +	"TEXT_PRINT_HELPURL": "https://github.com/google/blockly/wiki/Text#printing-text",
                +	"TEXT_PRINT_TITLE": "tekst weergeven: %1",
                +	"TEXT_PRINT_TOOLTIP": "Drukt de opgegeven tekst, getal of een andere waarde af.",
                +	"TEXT_PROMPT_HELPURL": "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user",
                +	"TEXT_PROMPT_TYPE_TEXT": "vraagt om invoer met bericht",
                +	"TEXT_PROMPT_TYPE_NUMBER": "vraagt de gebruiker om een getal met de tekst",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Vraagt de gebruiker om een getal in te voeren.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Vraagt de gebruiker om invoer.",
                +	"TEXT_COUNT_MESSAGE0": "%1 in %2 tellen",
                +	"TEXT_COUNT_TOOLTIP": "Tel hoe vaak bepaalde tekst voorkomt in andere tekst.",
                +	"TEXT_REPLACE_MESSAGE0": "vervang %1 door %2 in %3",
                +	"TEXT_REPLACE_TOOLTIP": "Vervang alle voorkomens van tekst in een andere tekst.",
                +	"TEXT_REVERSE_MESSAGE0": "%1 omkeren",
                +	"TEXT_REVERSE_TOOLTIP": "Keert de volgorde van de tekens in de tekst om.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "maak een lege lijst",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Geeft een lijst terug met lengte 0, zonder items",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Maak een lijst met een willekeurig aantal items.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "maak een lijst met",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lijst",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Voeg stukken toe, verwijder ze of wijzig de volgorde om dit lijstblok aan te passen.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Voeg iets toe aan de lijst.",
                +	"LISTS_REPEAT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_REPEAT_TOOLTIP": "Maakt een lijst die bestaat uit de opgegeven waarde, het opgegeven aantal keer herhaald.",
                +	"LISTS_REPEAT_TITLE": "Maak lijst met item %1, %2 keer herhaald",
                +	"LISTS_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Lists#length-of",
                +	"LISTS_LENGTH_TITLE": "lengte van %1",
                +	"LISTS_LENGTH_TOOLTIP": "Geeft de lengte van een lijst terug.",
                +	"LISTS_ISEMPTY_TITLE": "%1 is leeg",
                +	"LISTS_ISEMPTY_TOOLTIP": "Geeft waar terug als de lijst leeg is.",
                +	"LISTS_INLIST": "in lijst",
                +	"LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list",
                +	"LISTS_INDEX_OF_FIRST": "zoek eerste voorkomen van item",
                +	"LISTS_INDEX_OF_LAST": "zoek laatste voorkomen van item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Geeft de index terug van het eerste of laatste voorkomen van een item in de lijst. Geeft %1 terug als het item niet is gevonden.",
                +	"LISTS_GET_INDEX_GET": "haal op",
                +	"LISTS_GET_INDEX_GET_REMOVE": "haal op en verwijder",
                +	"LISTS_GET_INDEX_REMOVE": "verwijder",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# van einde",
                +	"LISTS_GET_INDEX_FIRST": "eerste",
                +	"LISTS_GET_INDEX_LAST": "laatste",
                +	"LISTS_GET_INDEX_RANDOM": "willekeurig",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Item %1 is het eerste item.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Item %1 is het laatste item.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Geeft het item op de opgegeven positie in een lijst.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Geeft het eerste item in een lijst terug.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Geeft het laatste item in een lijst terug.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Geeft een willekeurig item uit een lijst.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Geeft het item op de opgegeven positie in een lijst terug en verwijdert het.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Geeft het laatste item in een lijst terug en verwijdert het.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Geeft het laatste item uit een lijst terug en verwijdert het.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Geeft een willekeurig item in een lijst terug en verwijdert het.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Verwijdert het item op de opgegeven positie in een lijst.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Verwijdert het eerste item in een lijst.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Verwijdert het laatste item uit een lijst.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Verwijdert een willekeurig item uit een lijst.",
                +	"LISTS_SET_INDEX_HELPURL": "https://github.com/google/blockly/wiki/Lists#in-list--set",
                +	"LISTS_SET_INDEX_SET": "stel in",
                +	"LISTS_SET_INDEX_INSERT": "tussenvoegen op",
                +	"LISTS_SET_INDEX_INPUT_TO": "als",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Zet het item op de opgegeven positie in de lijst.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Stelt het eerste item in een lijst in.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Stelt het laatste item van een lijst in.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Stelt een willekeurig item uit de lijst in.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Voegt het item op een opgegeven positie in een lijst in.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Voegt het item toe aan het begin van de lijst.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Voeg het item aan het einde van een lijst toe.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Voegt het item op een willekeurige positie in de lijst in.",
                +	"LISTS_GET_SUBLIST_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-a-sublist",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "haal sublijst op vanaf positie",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "haal sublijst op van positie vanaf einde",
                +	"LISTS_GET_SUBLIST_START_FIRST": "haal sublijst op vanaf eerste",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "naar item",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "naar # vanaf einde",
                +	"LISTS_GET_SUBLIST_END_LAST": "naar laatste",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Maakt een kopie van het opgegeven deel van de lijst.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sorteer %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sorteer een kopie van een lijst.",
                +	"LISTS_SORT_ORDER_ASCENDING": "oplopend",
                +	"LISTS_SORT_ORDER_DESCENDING": "aflopend",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeriek",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetisch",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetisch, negeer hoofd-/kleine letters",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "lijst maken van tekst",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "tekst maken van lijst",
                +	"LISTS_SPLIT_WITH_DELIMITER": "met scheidingsteken",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Tekst splitsen in een lijst van teksten op basis van een scheidingsteken.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Lijst van tekstdelen samenvoegen in één stuk tekst, waarbij de tekstdelen gescheiden zijn door een scheidingsteken.",
                +	"LISTS_REVERSE_MESSAGE0": "%1 omkeren",
                +	"LISTS_REVERSE_TOOLTIP": "Keert een kopie van een lijst om.",
                +	"VARIABLES_GET_HELPURL": "https://github.com/google/blockly/wiki/Variables#get",
                +	"VARIABLES_GET_TOOLTIP": "Geeft de waarde van deze variabele.",
                +	"VARIABLES_GET_CREATE_SET": "Maak \"verander %1\"",
                +	"VARIABLES_SET_HELPURL": "https://github.com/google/blockly/wiki/Variables#set",
                +	"VARIABLES_SET": "stel %1 in op %2",
                +	"VARIABLES_SET_TOOLTIP": "Verandert de waarde van de variabele naar de waarde van de invoer.",
                +	"VARIABLES_SET_CREATE_GET": "Maak 'opvragen van %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://nl.wikipedia.org/wiki/Subprogramma",
                +	"PROCEDURES_DEFNORETURN_TITLE": "om",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "doe iets",
                +	"PROCEDURES_BEFORE_PARAMS": "met:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "met:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Maakt een functie zonder uitvoer.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Deze functie beschrijven...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://nl.wikipedia.org/wiki/Subprogramma",
                +	"PROCEDURES_DEFRETURN_RETURN": "uitvoeren",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Maakt een functie met een uitvoer.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "statements toestaan",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Waarschuwing: deze functie heeft parameters met dezelfde naam.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://nl.wikipedia.org/wiki/Subprogramma",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Voer de door de gebruiker gedefinieerde functie \"%1\" uit.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://nl.wikipedia.org/wiki/Subprogramma",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Voer de door de gebruiker gedefinieerde functie \"%1\" uit en gebruik de uitvoer.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ingangen",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Invoer van deze functie toevoegen, verwijderen of herordenen.",
                +	"PROCEDURES_MUTATORARG_TITLE": "invoernaam:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Een invoer aan de functie toevoegen.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Accentueer functiedefinitie",
                +	"PROCEDURES_CREATE_DO": "Maak \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Als de eerste waarde \"waar\" is, geef dan de tweede waarde terug.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Waarschuwing: dit blok mag alleen gebruikt worden binnen de definitie van een functie."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/oc.json b/blockly/webif/static/blockly/msg/json/oc.json
                new file mode 100644
                index 000000000..6a7d58f21
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/oc.json
                @@ -0,0 +1,132 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Cedric31"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Uèi",
                +	"DUPLICATE_BLOCK": "Duplicar",
                +	"ADD_COMMENT": "Apondre un comentari",
                +	"REMOVE_COMMENT": "Suprimir un comentari",
                +	"EXTERNAL_INPUTS": "Entradas extèrnas",
                +	"INLINE_INPUTS": "Entradas en linha",
                +	"DELETE_BLOCK": "Suprimir lo blòt",
                +	"DELETE_X_BLOCKS": "Suprimir %1 blòts",
                +	"DELETE_ALL_BLOCKS": "Suprimir totes los %1 blòts ?",
                +	"CLEAN_UP": "Netejar los blòts",
                +	"COLLAPSE_BLOCK": "Redusir lo blòt",
                +	"COLLAPSE_ALL": "Redusir los blòts",
                +	"EXPAND_BLOCK": "Desvolopar lo blòt",
                +	"EXPAND_ALL": "Desvolopar los blòts",
                +	"DISABLE_BLOCK": "Desactivar lo blòt",
                +	"ENABLE_BLOCK": "Activar lo blòt",
                +	"HELP": "Ajuda",
                +	"UNDO": "Anullar",
                +	"REDO": "Refar",
                +	"CHANGE_VALUE_TITLE": "Modificar la valor :",
                +	"RENAME_VARIABLE": "Renomenar la variabla…",
                +	"RENAME_VARIABLE_TITLE": "Renomenar totas las variablas « %1 » a :",
                +	"NEW_VARIABLE": "Crear una variabla...",
                +	"NEW_VARIABLE_TITLE": "Nom de la novèla variabla :",
                +	"COLOUR_PICKER_HELPURL": "https://oc.wikipedia.org/wiki/Color",
                +	"COLOUR_RANDOM_TITLE": "color aleatòria",
                +	"COLOUR_RANDOM_TOOLTIP": "Causir una color a l'azard.",
                +	"COLOUR_RGB_TITLE": "coloriar amb",
                +	"COLOUR_RGB_RED": "roge",
                +	"COLOUR_RGB_GREEN": "verd",
                +	"COLOUR_RGB_BLUE": "blau",
                +	"COLOUR_BLEND_TITLE": "mesclar",
                +	"COLOUR_BLEND_COLOUR1": "color 1",
                +	"COLOUR_BLEND_COLOUR2": "color 2",
                +	"COLOUR_BLEND_RATIO": "ratio",
                +	"CONTROLS_REPEAT_HELPURL": "https://oc.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repetir %1 còps",
                +	"CONTROLS_REPEAT_INPUT_DO": "far",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repetir tant que",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repetir fins a",
                +	"CONTROLS_FOR_TITLE": "comptar amb %1 de %2 a %3 per %4",
                +	"CONTROLS_FOREACH_TITLE": "per cada element %1 dins la lista %2",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "siquenon se",
                +	"CONTROLS_IF_MSG_ELSE": "siquenon",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Renviar verai se las doas entradas son egalas.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Renviar verai se las doas entradas son diferentas.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Renviar verai se las doas entradas son vertadièras.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "pas %1",
                +	"LOGIC_BOOLEAN_TRUE": "verai",
                +	"LOGIC_BOOLEAN_FALSE": "fals",
                +	"LOGIC_NULL": "nul",
                +	"LOGIC_NULL_TOOLTIP": "Renvia nul.",
                +	"LOGIC_TERNARY_CONDITION": "tèst",
                +	"LOGIC_TERNARY_IF_TRUE": "se verai",
                +	"LOGIC_TERNARY_IF_FALSE": "se fals",
                +	"MATH_NUMBER_HELPURL": "https://oc.wikipedia.org/wiki/Nombre",
                +	"MATH_NUMBER_TOOLTIP": "Un nombre.",
                +	"MATH_ARITHMETIC_HELPURL": "https://oc.wikipedia.org/wiki/Aritmetica",
                +	"MATH_SINGLE_OP_ROOT": "raiç carrada",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_IS_EVEN": "es par",
                +	"MATH_IS_ODD": "es impar",
                +	"MATH_IS_PRIME": "es primièr",
                +	"MATH_IS_WHOLE": "es entièr",
                +	"MATH_IS_POSITIVE": "es positiu",
                +	"MATH_IS_NEGATIVE": "es negatiu",
                +	"MATH_IS_DIVISIBLE_BY": "es devesible per",
                +	"MATH_CHANGE_TITLE": "incrementar %1 per %2",
                +	"MATH_ROUND_OPERATOR_ROUND": "arredondir",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arredondir al superior",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arredondir a l’inferior",
                +	"MATH_ONLIST_OPERATOR_SUM": "soma de la lista",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimum de la lista",
                +	"MATH_ONLIST_OPERATOR_MAX": "maximum de la lista",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "mejana de la lista",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana de la lista",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "jónher",
                +	"TEXT_LENGTH_TITLE": "longor de %1",
                +	"TEXT_ISEMPTY_TITLE": "%1 es void",
                +	"TEXT_CHARAT_FROM_START": "obténer la letra #",
                +	"TEXT_CHARAT_FROM_END": "obténer la letra # dempuèi la fin",
                +	"TEXT_CHARAT_FIRST": "obténer la primièra letra",
                +	"TEXT_CHARAT_LAST": "obténer la darrièra letra",
                +	"TEXT_CHARAT_RANDOM": "obténer una letra a l'azard",
                +	"TEXT_CHARAT_TOOLTIP": "Renvia la letra a la posicion indicada.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "dins lo tèxte",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "fins a la letra #",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "en MAJUSCULAS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "en minusculas",
                +	"TEXT_PRINT_TITLE": "afichar %1",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "crear una lista amb",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_INLIST": "dins la lista",
                +	"LISTS_GET_INDEX_GET": "obténer",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obténer e suprimir",
                +	"LISTS_GET_INDEX_REMOVE": "suprimit",
                +	"LISTS_GET_INDEX_FROM_END": "# dempuèi la fin",
                +	"LISTS_GET_INDEX_FIRST": "primièr",
                +	"LISTS_GET_INDEX_LAST": "darrièr",
                +	"LISTS_GET_INDEX_RANDOM": "aleatòri",
                +	"LISTS_SET_INDEX_SET": "metre",
                +	"LISTS_SET_INDEX_INSERT": "inserir en",
                +	"LISTS_SET_INDEX_INPUT_TO": "coma",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "fins a #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "fins a # dempuèi la fin",
                +	"LISTS_GET_SUBLIST_END_LAST": "fins a la fin",
                +	"LISTS_SORT_ORDER_ASCENDING": "creissent",
                +	"LISTS_SORT_ORDER_DESCENDING": "descreissent",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeric",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetic",
                +	"LISTS_SPLIT_WITH_DELIMITER": "amb lo separador",
                +	"VARIABLES_GET_CREATE_SET": "Crear 'fixar %1'",
                +	"VARIABLES_SET": "fixar %1 a %2",
                +	"PROCEDURES_DEFNORETURN_TITLE": "a",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "far quicòm",
                +	"PROCEDURES_BEFORE_PARAMS": "amb :",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "amb :",
                +	"PROCEDURES_DEFRETURN_RETURN": "retorn",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entradas",
                +	"PROCEDURES_MUTATORARG_TITLE": "nom de l’entrada :",
                +	"PROCEDURES_CREATE_DO": "Crear '%1'"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/pl.json b/blockly/webif/static/blockly/msg/json/pl.json
                new file mode 100644
                index 000000000..c0b901931
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/pl.json
                @@ -0,0 +1,379 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Cotidianis",
                +			"Faren",
                +			"Vengir",
                +			"Pbz",
                +			"Pio387",
                +			"아라",
                +			"Mateon1",
                +			"Expert3222",
                +			"Cirasean",
                +			"Fringoo",
                +			"Chrumps",
                +			"Woytecr",
                +			"Liuxinyu970226",
                +			"Krottyianock",
                +			"Mazab IZW",
                +			"Teeed",
                +			"InternerowyGołąb",
                +			"Wojtas"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Dzisiaj",
                +	"DUPLICATE_BLOCK": "Powiel",
                +	"ADD_COMMENT": "Dodaj Komentarz",
                +	"REMOVE_COMMENT": "Usuń komentarz",
                +	"EXTERNAL_INPUTS": "Zewnętrzne Wejścia",
                +	"INLINE_INPUTS": "Wbudowane Wejścia",
                +	"DELETE_BLOCK": "Usuń Klocek",
                +	"DELETE_X_BLOCKS": "Usuń %1 Bloki(ów)",
                +	"DELETE_ALL_BLOCKS": "Usunąć wszystkie klocki z %1?",
                +	"CLEAN_UP": "Uporządkuj Bloki",
                +	"COLLAPSE_BLOCK": "Zwiń Klocek",
                +	"COLLAPSE_ALL": "Zwiń Bloki",
                +	"EXPAND_BLOCK": "Rozwiń Klocek",
                +	"EXPAND_ALL": "Rozwiń Bloki",
                +	"DISABLE_BLOCK": "Wyłącz Klocek",
                +	"ENABLE_BLOCK": "Włącz Blok",
                +	"HELP": "Pomoc",
                +	"UNDO": "Cofnij",
                +	"REDO": "Ponów",
                +	"CHANGE_VALUE_TITLE": "Zmień wartość:",
                +	"RENAME_VARIABLE": "Zmień nazwę zmiennej...",
                +	"RENAME_VARIABLE_TITLE": "Zmień nazwy wszystkich '%1' zmiennych na:",
                +	"NEW_VARIABLE": "Utwórz zmienną...",
                +	"NEW_VARIABLE_TITLE": "Nowa nazwa zmiennej:",
                +	"VARIABLE_ALREADY_EXISTS": "Zmienna o nazwie '%1' już istnieje.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Zmienna o nazwie '%1' już istnieje i jest typu '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Procedura o nazwie '%1' już istnieje.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Usunąć %1 wystąpień zmiennej '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Nie można usunąć zmiennej '%1', ponieważ jest częścią definicji funkcji '%2'",
                +	"DELETE_VARIABLE": "Usuń zmienną '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Wybierz kolor z palety.",
                +	"COLOUR_RANDOM_TITLE": "losowy kolor",
                +	"COLOUR_RANDOM_TOOLTIP": "Wybierz kolor w sposób losowy.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "kolor z",
                +	"COLOUR_RGB_RED": "czerwony",
                +	"COLOUR_RGB_GREEN": "zielony",
                +	"COLOUR_RGB_BLUE": "niebieski",
                +	"COLOUR_RGB_TOOLTIP": "Utwórz kolor składający sie z podanej ilości czerwieni, zieleni i błękitu. Zakres wartości: 0 do 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "wymieszaj",
                +	"COLOUR_BLEND_COLOUR1": "kolor 1",
                +	"COLOUR_BLEND_COLOUR2": "kolor 2",
                +	"COLOUR_BLEND_RATIO": "proporcja",
                +	"COLOUR_BLEND_TOOLTIP": "Miesza dwa kolory w danej proporcji (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "powtórz %1 razy",
                +	"CONTROLS_REPEAT_INPUT_DO": "wykonaj",
                +	"CONTROLS_REPEAT_TOOLTIP": "Wykonaj niektóre instrukcje kilka razy.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "powtarzaj dopóki",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "powtarzaj aż do",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Dopóki wyrażenie jest prawdziwe, wykonaj zadane czynności.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Dopóki wyrażenie jest nieprawdziwe, wykonaj zadane czynności.",
                +	"CONTROLS_FOR_TOOLTIP": "Zmiennej '%1' przypisuje wartości z podanego zakresu z podanym interwałem i wykonuje zadane bloki.",
                +	"CONTROLS_FOR_TITLE": "licz z %1 od %2 do %3 co %4 (wartość kroku)",
                +	"CONTROLS_FOREACH_TITLE": "dla każdego elementu %1 listy %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Przypisz zmiennej '%1' kolejno wartość każdego elementu listy, a następnie wykonaj kilka instrukcji.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "przerwij pętlę",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "przejdź do kolejnej iteracji pętli",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Przerwij działanie pętli.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Pomiń resztę pętli i kontynuuj w kolejnej iteracji.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Uwaga: Ten klocek może być użyty tylko wewnątrz pętli.",
                +	"CONTROLS_IF_TOOLTIP_1": "Jeśli warunek jest spełniony, wykonaj zadane czynności.",
                +	"CONTROLS_IF_TOOLTIP_2": "Jeśli warunek jest spełniony, wykonaj pierwszy blok instrukcji.  W przeciwnym razie, wykonaj drugi blok instrukcji.",
                +	"CONTROLS_IF_TOOLTIP_3": "Jeśli pierwszy warunek jest spełniony, wykonaj pierwszy blok instrukcji.  W przeciwnym razie, jeśli drugi warunek jest spełniony, wykonaj drugi blok instrukcji.",
                +	"CONTROLS_IF_TOOLTIP_4": "Jeśli pierwszy warunek jest spełniony, wykonaj pierwszy blok czynności.  W przeciwnym razie jeśli drugi warunek jest spełniony, wykonaj drugi blok czynności.  Jeżeli żaden z warunków nie zostanie spełniony, wykonaj ostatni blok czynności.",
                +	"CONTROLS_IF_MSG_IF": "jeśli",
                +	"CONTROLS_IF_MSG_ELSEIF": "w przeciwnym razie, jeśli",
                +	"CONTROLS_IF_MSG_ELSE": "w przeciwnym razie",
                +	"CONTROLS_IF_IF_TOOLTIP": "Dodaj, usuń lub zmień kolejność czynności, żeby zmodyfikować ten klocek „jeśli”.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Dodaj warunek do klocka „jeśli”.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Dodaj ostatni zawsze prawdziwy warunek do klocka „jeśli”.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Anuluj",
                +	"IOS_ERROR": "Błąd",
                +	"IOS_PROCEDURES_INPUTS": "WEJŚCIA",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Dodaj Wejście",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Zezwalaj na czynności.",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Ta funkcja ma zduplikowane wejścia.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Dodaj Zmienną",
                +	"IOS_VARIABLES_ADD_BUTTON": "Dodaj",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Zmień nazwę",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Usuń",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nazwa zmiennej",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Nie możesz utworzyć funkcji bez nazwy.",
                +	"LOGIC_COMPARE_HELPURL": "https://pl.wikipedia.org/wiki/Nierówność",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Zwraca \"prawda\", jeśli wejścia są identyczne.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Zwraca \"prawda\", jeśli wejścia nie są identyczne.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Zwraca \"prawda\" jeśli pierwsze wejście jest mniejsze od drugiego.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Zwraca \"prawda\", jeśli pierwsze wejście jest mniejsze lub równe drugiemu.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Zwraca \"prawda\" jeśli pierwsze wejście jest większe od drugiego.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Zwraca \"prawda\", jeśli pierwsze wejście jest większe lub równe drugiemu.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Zwraca \"prawda\" jeśli na obydwóch wejściach jest \"prawda\".",
                +	"LOGIC_OPERATION_AND": "i",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Zwraca \"prawda\" jeśli co najmniej na jednyk wejściu jest \"prawda\".",
                +	"LOGIC_OPERATION_OR": "lub",
                +	"LOGIC_NEGATE_TITLE": "nie %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Zwraca \"prawda\", jeśli wejściu jest \"fałsz\". Zwraca \"fałsz\", jeśli na wejściu jest \"prawda\".",
                +	"LOGIC_BOOLEAN_TRUE": "prawda",
                +	"LOGIC_BOOLEAN_FALSE": "fałsz",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Zwraca 'prawda' lub 'fałsz'.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "nic",
                +	"LOGIC_NULL_TOOLTIP": "Zwraca nic.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "jeśli prawda",
                +	"LOGIC_TERNARY_IF_FALSE": "jeśli fałsz",
                +	"LOGIC_TERNARY_TOOLTIP": "Sprawdź warunek w „test”. Jeśli warunek jest prawdziwy, to zwróci „jeśli prawda”; jeśli nie jest prawdziwy to zwróci „jeśli fałsz”.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Liczba.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "/",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tg",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "arccos",
                +	"MATH_TRIG_ATAN": "arctg",
                +	"MATH_ARITHMETIC_HELPURL": "https://pl.wikipedia.org/wiki/Arytmetyka",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Zwróć sumę dwóch liczb.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Zwróć różnicę dwóch liczb.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Zwróć iloczyn dwóch liczb.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Zwróć iloraz dwóch liczb.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Zwróć pierwszą liczbę podniesioną do potęgi o wykładniku drugiej liczby.",
                +	"MATH_SINGLE_HELPURL": "https://pl.wikipedia.org/wiki/Pierwiastek_kwadratowy",
                +	"MATH_SINGLE_OP_ROOT": "pierwiastek kwadratowy",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Zwróć pierwiastek kwadratowy danej liczby.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "wartość bezwzględna",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Zwróć wartość bezwzględną danej liczby.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Zwróć negację danej liczby.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Zwróć logarytm naturalny danej liczby.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Zwraca logarytm dziesiętny danej liczby.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Zwróć e do potęgi danej liczby.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Zwróć 10 do potęgi danej liczby.",
                +	"MATH_TRIG_HELPURL": "https://pl.wikipedia.org/wiki/Funkcje_trygonometryczne",
                +	"MATH_TRIG_TOOLTIP_SIN": "Zwróć wartość sinusa o stopniu (nie w radianach).",
                +	"MATH_TRIG_TOOLTIP_COS": "Zwróć wartość cosinusa o stopniu (nie w radianach).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Zwróć tangens o stopniu (nie w radianach).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Zwróć arcus sinus danej liczby.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Zwróć arcus cosinus danej liczby.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Zwróć arcus tangens danej liczby.",
                +	"MATH_CONSTANT_HELPURL": "https://pl.wikipedia.org/wiki/Stała_(matematyka)",
                +	"MATH_CONSTANT_TOOLTIP": "Zwróć jedną wspólną stałą: π (3.141), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) lub ∞ (nieskończoność).",
                +	"MATH_IS_EVEN": "jest parzysta",
                +	"MATH_IS_ODD": "jest nieparzysta",
                +	"MATH_IS_PRIME": "jest liczbą pierwszą",
                +	"MATH_IS_WHOLE": "jest liczbą całkowitą",
                +	"MATH_IS_POSITIVE": "jest dodatnia",
                +	"MATH_IS_NEGATIVE": "jest ujemna",
                +	"MATH_IS_DIVISIBLE_BY": "jest podzielna przez",
                +	"MATH_IS_TOOLTIP": "Sprawdź, czy liczba jest parzysta, nieparzysta, pierwsza, całkowita, dodatnia, ujemna, lub czy jest podzielna przez podaną liczbę. Zwraca wartość \"prawda\" lub \"fałsz\".",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "zmień %1 o %2",
                +	"MATH_CHANGE_TOOLTIP": "Dodaj liczbę do zmiennej '%1'.",
                +	"MATH_ROUND_HELPURL": "https://pl.wikipedia.org/wiki/Zaokrąglanie",
                +	"MATH_ROUND_TOOLTIP": "Zaokrąglij w górę lub w dół.",
                +	"MATH_ROUND_OPERATOR_ROUND": "zaokrąglij",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "zaokrąglij w górę",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "zaokrąglij w dół",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma elementów listy",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Zwróć sumę wszystkich liczb z listy.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimalna wartość z listy",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Zwróć najmniejszą liczbę w liście.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maksymalna wartość z listy",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Zwróć największą liczbę w liście.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "średnia elementów listy",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Zwróć średnią (średnią arytmetyczną) wartości liczbowych z listy.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana listy",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Zwróć medianę listy.",
                +	"MATH_ONLIST_OPERATOR_MODE": "dominanty listy",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Zwróć listę najczęściej występujących elementów w liście.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "odchylenie standardowe listy",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Zwróć odchylenie standardowe listy.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "losowy element z listy",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Zwróć losowy element z listy.",
                +	"MATH_MODULO_HELPURL": "https://pl.wikipedia.org/wiki/Modulo",
                +	"MATH_MODULO_TITLE": "reszta z dzielenia %1 przez %2",
                +	"MATH_MODULO_TOOLTIP": "Zwróć resztę z dzielenia dwóch liczb przez siebie.",
                +	"MATH_CONSTRAIN_TITLE": "ogranicz %1 z dołu %2 z góry %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Ogranicz liczbę, aby była w określonych granicach (włącznie).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "losowa liczba całkowita od %1 do %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Zwróć losową liczbę całkowitą w ramach dwóch wyznaczonych granic, włącznie.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "losowy ułamek",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Zwróć losowy ułamek między 0.0 (włącznie), a 1.0 (wyłącznie).",
                +	"TEXT_TEXT_HELPURL": "https://pl.wikipedia.org/wiki/Tekstowy_typ_danych",
                +	"TEXT_TEXT_TOOLTIP": "Litera, wyraz lub linia tekstu.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "utwórz tekst z",
                +	"TEXT_JOIN_TOOLTIP": "Tworzy fragment tekstu, łącząc ze sobą dowolną liczbę tekstów.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "połącz",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Dodaj, usuń lub zmień kolejność sekcji, aby zmodyfikować klocek tekstowy.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Dodaj element do tekstu.",
                +	"TEXT_APPEND_TITLE": "dodaj tekst %2 do %1",
                +	"TEXT_APPEND_TOOLTIP": "Dołącz tekst do zmiennej '%1'.",
                +	"TEXT_LENGTH_TITLE": "długość %1",
                +	"TEXT_LENGTH_TOOLTIP": "Zwraca liczbę liter (łącznie ze spacjami) w podanym tekście.",
                +	"TEXT_ISEMPTY_TITLE": "%1 jest pusty",
                +	"TEXT_ISEMPTY_TOOLTIP": "Zwraca prawda (true), jeśli podany tekst jest pusty.",
                +	"TEXT_INDEXOF_TOOLTIP": "Zwraca indeks pierwszego/ostatniego wystąpienia pierwszego tekstu w drugim tekście. Zwraca wartość %1, jeśli tekst nie został znaleziony.",
                +	"TEXT_INDEXOF_TITLE": "w tekście %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "znajdź pierwsze wystąpienie tekstu",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "znajdź ostatnie wystąpienie tekstu",
                +	"TEXT_CHARAT_TITLE": "w tekście %1 %2",
                +	"TEXT_CHARAT_FROM_START": "pobierz literę #",
                +	"TEXT_CHARAT_FROM_END": "pobierz literę # od końca",
                +	"TEXT_CHARAT_FIRST": "pobierz pierwszą literę",
                +	"TEXT_CHARAT_LAST": "pobierz ostatnią literę",
                +	"TEXT_CHARAT_RANDOM": "pobierz losową literę",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Zwraca literę z określonej pozycji.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Zwraca określoną część tekstu.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "w tekście",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "pobierz podciąg od # litery",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "pobierz podciąg od # litery od końca",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "pobierz podciąg od pierwszej litery",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "do # litery",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "do # litery od końca",
                +	"TEXT_GET_SUBSTRING_END_LAST": "do ostatniej litery",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "Zwraca kopię tekstu z odwruconą wielkością liter.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "na WIELKIE LITERY",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "na małe litery",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "na Pierwsza Duża",
                +	"TEXT_TRIM_TOOLTIP": "Zwraca kopię tekstu z usuniętymi spacjami z jednego lub z obu końców tekstu.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "usuń spacje po obu stronach",
                +	"TEXT_TRIM_OPERATOR_LEFT": "usuń spacje z lewej strony",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "usuń spacje z prawej strony",
                +	"TEXT_PRINT_TITLE": "wydrukuj %1",
                +	"TEXT_PRINT_TOOLTIP": "Wyświetl określony tekst, liczbę lub inną wartość.",
                +	"TEXT_PROMPT_TYPE_TEXT": "poproś o tekst z tą wiadomością",
                +	"TEXT_PROMPT_TYPE_NUMBER": "poproś o liczbę z tą wiadomością",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Zapytaj użytkownika  o liczbę.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Zapytaj użytkownika o jakiś tekst.",
                +	"TEXT_COUNT_MESSAGE0": "policz %1 w %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Liczy ile razy dany tekst występuje w innym tekście.",
                +	"TEXT_REPLACE_MESSAGE0": "zamień %1 na %2 w %3",
                +	"TEXT_REPLACE_TOOLTIP": "Zastąp wszystkie wystąpienia danego tekstu innym.",
                +	"TEXT_REVERSE_MESSAGE0": "odwróć %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Odwraca kolejność znaków w tekście.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "utwórz pustą listę",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Zwraca listę o długości 0, nie zawierającą danych",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Utwórz listę z dowolną ilością elementów.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "utwórz listę z",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Dodaj, usuń lub zmień kolejność sekcji aby przekonfigurować blok tej listy.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Dodaj element do listy.",
                +	"LISTS_REPEAT_TOOLTIP": "Tworzy listę zawierającą podaną wartość powtórzoną żądaną ilość razy.",
                +	"LISTS_REPEAT_TITLE": "utwórz listę powtarzając %1 %2 razy.",
                +	"LISTS_LENGTH_TITLE": "długość %1",
                +	"LISTS_LENGTH_TOOLTIP": "Zwraca długość listy.",
                +	"LISTS_ISEMPTY_TITLE": "%1 jest pusta",
                +	"LISTS_ISEMPTY_TOOLTIP": "Zwraca \"prawda\" jeśli lista jest pusta.",
                +	"LISTS_INLIST": "na liście",
                +	"LISTS_INDEX_OF_FIRST": "znajdź pierwsze wystąpienie elementu",
                +	"LISTS_INDEX_OF_LAST": "znajdź ostatanie wystąpienie elementu",
                +	"LISTS_INDEX_OF_TOOLTIP": "Zwraca indeks pierwszego/ostatniego wystąpienia elementu z listy. Zwraca %1, jeśli nie zostanie znaleziony.",
                +	"LISTS_GET_INDEX_GET": "pobierz",
                +	"LISTS_GET_INDEX_GET_REMOVE": "zabierz",
                +	"LISTS_GET_INDEX_REMOVE": "usuń",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# od końca",
                +	"LISTS_GET_INDEX_FIRST": "pierwszy",
                +	"LISTS_GET_INDEX_LAST": "ostatni",
                +	"LISTS_GET_INDEX_RANDOM": "losowy",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 to pierwszy element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 to ostatni element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Zwraca element z konkretnej pozycji na liście.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Zwraca pierwszy element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Zwraca ostatni element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Zwraca losowy element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Usuwa i zwraca element z określonej pozycji na liście.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Usuwa i zwraca pierwszy element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Usuwa i zwraca ostatni element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Usuwa i zwraca losowy element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Usuwa element z określonej pozycji na liście.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Usuwa pierwszy element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Usuwa ostatni element z listy.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Usuwa losowy element z listy.",
                +	"LISTS_SET_INDEX_SET": "ustaw",
                +	"LISTS_SET_INDEX_INSERT": "wstaw w",
                +	"LISTS_SET_INDEX_INPUT_TO": "jako",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Ustawia element w określonym miejscu na liście.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Ustawia pierwszy element na liście.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Ustawia ostatni element na liście.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Ustawia losowy element na liście.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Wstawia element na żądanej pozycji listy.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Wstawia element na początku listy.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Dodaj element na koniec listy.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Wstawia element w losowym miejscu na liście.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "utwórz listę podrzędną z #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "utwórz listę podrzędną z # od końca",
                +	"LISTS_GET_SUBLIST_START_FIRST": "utwórz listę podrzędną od pierwszego",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "do #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "do # od końca",
                +	"LISTS_GET_SUBLIST_END_LAST": "do ostatniego",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Tworzy kopię żądanej części listy.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sortuj %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sortuj kopię listy.",
                +	"LISTS_SORT_ORDER_ASCENDING": "rosnąco",
                +	"LISTS_SORT_ORDER_DESCENDING": "malejąco",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerycznie",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetycznie",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetycznie, ignoruj wielkość liter",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "utwórz listę z tekstu",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "utwórz tekst z listy",
                +	"LISTS_SPLIT_WITH_DELIMITER": "z separatorem",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Rozdziela tekst zgodnie z separatorem tworząc listę z powstałych elementów.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Łączy listę tekstów w jeden tekst, rozdzielany separatorem.",
                +	"LISTS_REVERSE_MESSAGE0": "odwróć %1",
                +	"LISTS_REVERSE_TOOLTIP": "Odwraca kolejność danych w kopii listy.",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_TOOLTIP": "Zwraca wartość tej zmiennej.",
                +	"VARIABLES_GET_CREATE_SET": "Utwórz klocek 'ustaw %1'",
                +	"VARIABLES_SET": "przypisz %1 wartość %2",
                +	"VARIABLES_SET_TOOLTIP": "Wartości zmiennej i  wejście będą identyczne.",
                +	"VARIABLES_SET_CREATE_GET": "Utwórz klocek 'pobierz %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "do",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "zrób coś",
                +	"PROCEDURES_BEFORE_PARAMS": "z:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "z:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Tworzy funkcję nie posiadającą wyjścia.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Opisz tę funkcję...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "zwróć",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Tworzy funkcję posiadającą wyjście.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "zezwól na czynności",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Uwaga: Ta funkcja ma powtórzone parametry.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://pl.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Uruchom zdefiniowaną przez użytkownika funkcję '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://pl.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Uruchom zdefiniowaną przez użytkownika funkcję '%1' i użyj jej wyjścia.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "wejścia",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Dodaj, usuń lub zmień kolejność wejść tej funkcji.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nazwa wejścia:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Dodaj wejście do funkcji.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Podświetl definicję funkcji",
                +	"PROCEDURES_CREATE_DO": "Utwórz '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Jeśli warunek jest spełniony zwróć drugą wartość.",
                +	"PROCEDURES_IFRETURN_WARNING": "Uwaga: Ten klocek może być używany tylko w definicji funkcji."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/pms.json b/blockly/webif/static/blockly/msg/json/pms.json
                new file mode 100644
                index 000000000..6654d478c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/pms.json
                @@ -0,0 +1,341 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Borichèt"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Ancheuj",
                +	"DUPLICATE_BLOCK": "Dupliché",
                +	"ADD_COMMENT": "Gionté un coment",
                +	"REMOVE_COMMENT": "Scancelé un coment",
                +	"EXTERNAL_INPUTS": "Imission esterne",
                +	"INLINE_INPUTS": "Imission an linia",
                +	"DELETE_BLOCK": "Scancelé ël blòch",
                +	"DELETE_X_BLOCKS": "Scancelé %1 blòch",
                +	"DELETE_ALL_BLOCKS": "Scancelé tuti ij %1 blòch?",
                +	"CLEAN_UP": "Dëscancelé ij blòch",
                +	"COLLAPSE_BLOCK": "Arduve ël blòch",
                +	"COLLAPSE_ALL": "Arduve ij blòch",
                +	"EXPAND_BLOCK": "Dësvlupé ël blòch",
                +	"EXPAND_ALL": "Dësvlupé ij blòch",
                +	"DISABLE_BLOCK": "Disativé ël blòch",
                +	"ENABLE_BLOCK": "Ativé ël blòch",
                +	"HELP": "Agiut",
                +	"UNDO": "Anulé",
                +	"REDO": "Fé torna",
                +	"CHANGE_VALUE_TITLE": "Modifiché ël valor:",
                +	"RENAME_VARIABLE": "Arnomé la variàbil...",
                +	"RENAME_VARIABLE_TITLE": "Arnomé tute le variàbij '%1' 'me:",
                +	"NEW_VARIABLE": "Creé na variàbil...",
                +	"NEW_VARIABLE_TITLE": "Nòm ëd la neuva variàbil:",
                +	"VARIABLE_ALREADY_EXISTS": "Na variàbil con ël nòm '%1' a esist già.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Na variàbil ciamà '%1' a esist già për n'àutra variàbil ëd sòrt '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Na procedura ciamà '%1' a esist già.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Eliminé %1 utilisassion ëd la variàbil '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "As peul nen eliminesse la variàbil '%1' përchè a l'é part ëd la definission dla fonsion '%2'",
                +	"DELETE_VARIABLE": "Eliminé la variàbil '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Serne un color ant la taulòssa.",
                +	"COLOUR_RANDOM_TITLE": "color a asar",
                +	"COLOUR_RANDOM_TOOLTIP": "Serne un color a asar.",
                +	"COLOUR_RGB_TITLE": "coloré con",
                +	"COLOUR_RGB_RED": "ross",
                +	"COLOUR_RGB_GREEN": "verd",
                +	"COLOUR_RGB_BLUE": "bleu",
                +	"COLOUR_RGB_TOOLTIP": "Creé un color con la quantità spessificà ëd ross, verd e bleu. Tuti ij valor a devo esse antra 0 e 100.",
                +	"COLOUR_BLEND_TITLE": "mës-cé",
                +	"COLOUR_BLEND_COLOUR1": "color 1",
                +	"COLOUR_BLEND_COLOUR2": "color 2",
                +	"COLOUR_BLEND_RATIO": "rapòrt",
                +	"COLOUR_BLEND_TOOLTIP": "A mës-cia doi color ansema con un rapòrt dàit (0,0 - 1,0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "arpete %1 vire",
                +	"CONTROLS_REPEAT_INPUT_DO": "fé",
                +	"CONTROLS_REPEAT_TOOLTIP": "Eseguì chèiche anstrussion vàire vire.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "arpete antramentre che",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "arpete fin-a a",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Cand un valor a l'é ver, eseguì chèiche anstrussion.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Cand un valor a l'é fàuss, eseguì chèiche anstrussion.",
                +	"CONTROLS_FOR_TOOLTIP": "Fé an manera che la variàbil \"%1\" a pija ij valor dal nùmer inissial fin-a al nùmer final, an contand për l'antërval ëspessificà, e eseguì ij bloch ëspessificà.",
                +	"CONTROLS_FOR_TITLE": "conté con %1 da %2 a %3 për %4",
                +	"CONTROLS_FOREACH_TITLE": "për minca n'element %1 ant la lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Për minca element an na lista, dé ël valor ëd l'element a la variàbil '%1', peui eseguì chèiche anstrussion.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "seurte da la liassa",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continué con l'iterassion sucessiva dla liassa",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Seurte da la liassa anglobanta.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sauté ël rest ëd sa liassa, e continué con l'iterassion apress.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Atension: Ës blòch a peul mach esse dovrà andrinta a na liassa.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si un valor a l'é ver, antlora eseguì chèiche anstrussion.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si un valor a l'é ver, antlora eseguì ël prim blòch d'anstrussion. Dësnò, eseguì ël second blòch d'anstrussion.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si ël prim valor a l'é ver, antlora fé andé ël prim blòch d'anstrussion. Dësnò, si ël second valor a l'é ver, fé andé ël second blòch d'anstrussion.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si ël prim valor a l'é ver, antlora fé andé ël prim blòch d'anstrussion. Dësnò, si ël second valor a l'é ver, fé andé ël second blòcj d'anstrussion. Si gnun dij valor a l'é ver, fé andé l'ùltim blòch d'anstrussion.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "dësnò si",
                +	"CONTROLS_IF_MSG_ELSE": "dësnò",
                +	"CONTROLS_IF_IF_TOOLTIP": "Gionté, gavé o riordiné le session për cinfiguré torna ës blòch si.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Gionté na condission al blòch si.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Gionté na condission final ch'a cheuj tut al blòch si.",
                +	"IOS_OK": "Va bin",
                +	"IOS_CANCEL": "Anulé",
                +	"IOS_ERROR": "Eror",
                +	"IOS_PROCEDURES_INPUTS": "IMISSION",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Gionté n'imission",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Përmëtte le diciairassion",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Costa imission a dj'imission duplicà.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Gionté na variàbil",
                +	"IOS_VARIABLES_ADD_BUTTON": "Gionté",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Arnominé",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Eliminé",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nòm ëd la variàbil",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "A peul nen dovré un nòm ëd variàbil veuid.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Rësponde ver si le doe imission a son uguaj.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Rësponde ver si le doe imission a son nen uguaj.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Rësponde ver si la prima imission a l'é pi cita dla sconda.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Rësponde ver si la prima imission a l'é pi cita o ugual a la sconda.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Rësponde ver si la prima imission a l'é pi granda che la sconda.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Rësponde ver si la prima imission a l'é pi granda o ugual a la sconda.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Rësponde ver se tute doe j'imission a son vere.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Rësponde ver se almanch un-a d'imission a l'é vera.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "nen %1",
                +	"LOGIC_NEGATE_TOOLTIP": "A rëspond ver se l'imission a l'é fàussa. A rëspond fàuss se l'imission a l'é vera.",
                +	"LOGIC_BOOLEAN_TRUE": "ver",
                +	"LOGIC_BOOLEAN_FALSE": "fàuss",
                +	"LOGIC_BOOLEAN_TOOLTIP": "A rëspond ver o fàuss.",
                +	"LOGIC_NULL": "gnente",
                +	"LOGIC_NULL_TOOLTIP": "A rëspond gnente.",
                +	"LOGIC_TERNARY_CONDITION": "preuva",
                +	"LOGIC_TERNARY_IF_TRUE": "se ver",
                +	"LOGIC_TERNARY_IF_FALSE": "se fàuss",
                +	"LOGIC_TERNARY_TOOLTIP": "Controlé la condission an 'preuva'. Se la condission a l'é vera, a rëspond con ël valor 'se ver'; dësnò a rëspond con ël valor 'se fàuss'.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Un nùmer.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "A smon la soma ëd doi nùmer.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "A smon la diferensa dij doi nùmer.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "A smon ël prodot dij doi nùmer.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "A smon ël cossient dij doi nùmer.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "A smon ël prim nùmer alvà a la potensa dël second.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "rèis quadra",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "A smon la rèis quadra d'un nùmer.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "assolù",
                +	"MATH_SINGLE_TOOLTIP_ABS": "A smon ël valor assolù d'un nùmer.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "A smon l'opòst d'un nùmer.",
                +	"MATH_SINGLE_TOOLTIP_LN": "A smon ël logaritm natural d'un nùmer.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "A smon ël logaritm an base 10 d'un nùmer.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "A smon e a la potensa d'un nùmer.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "A smon 10 a la potensa d'un nùmer.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "A smon ël sen ëd n'àngol an gré (pa an radiant).",
                +	"MATH_TRIG_TOOLTIP_COS": "A smon ël cosen ëd n'àngol an gré (pa an radiant).",
                +	"MATH_TRIG_TOOLTIP_TAN": "A smon la tangenta ëd n'àngol an gré (pa an radiant).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "A smon l'arch-sen d'un nùmer.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "A smon l'arch-cosen d'un nùmer.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "A smon l'arch-tangenta d'un nùmer.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "A smon un-a dle costante comun-e π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) o ∞ (infinì).",
                +	"MATH_IS_EVEN": "a l'é cobi",
                +	"MATH_IS_ODD": "a l'é dëscobi",
                +	"MATH_IS_PRIME": "a l'é prim",
                +	"MATH_IS_WHOLE": "a l'é antregh",
                +	"MATH_IS_POSITIVE": "a l'é positiv",
                +	"MATH_IS_NEGATIVE": "a l'é negativ",
                +	"MATH_IS_DIVISIBLE_BY": "a l'é divisìbil për",
                +	"MATH_IS_TOOLTIP": "A contròla si un nùmer a l'é cobi, dëscobi, prim, antreghm positiv, negativ, o s'a l'é divisìbil për un nùmer dàit. A rëspond ver o fàuss.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "ancrementé %1 për %2",
                +	"MATH_CHANGE_TOOLTIP": "Gionté un nùmer a la variàbil '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "A arionda un nùmer për difet o ecess.",
                +	"MATH_ROUND_OPERATOR_ROUND": "ariondé",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ariondé për ecess",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ariondé për difet",
                +	"MATH_ONLIST_OPERATOR_SUM": "soma dla lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "A smon la soma ëd tuti ij nùmer ant la lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "mìnim ëd la lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "A smon ël pi cit nùmer ëd la lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "màssim ëd la lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "A smon ël pi gròss nùmer ëd la lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "media dla lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "A smon la media (aritmética) dij valor numérich ant la lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mesan-a dla lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "A smon ël nùmer mesan ëd la lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "mòde dla lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "A smon na lista dj'element pi frequent ëd la lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviassion ëstàndard ëd la lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "A smon la deviassion ëstàndard ëd la lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "element a l'ancàpit ëd la lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "A smon n'element a l'ancàpit da la lista.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "resta ëd %1:%2",
                +	"MATH_MODULO_TOOLTIP": "A smon la resta ëd la division dij doi nùmer.",
                +	"MATH_CONSTRAIN_TITLE": "limité %1 antra %2 e %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Limité un nùmer a esse antra le limitassion ëspessificà (comprèise).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "antregh aleatòri antra %1 e %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "A smon n'antregh aleatòri antra ij doi lìmit ëspessificà, comprèis.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "frassion aleatòria",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "A smon na frassion aleatòria antra 0,0 (comprèis) e 1,0 (esclus).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Na litra, na paròla o na linia ëd test.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "creé ël test con",
                +	"TEXT_JOIN_TOOLTIP": "Creé un tòch ëd test an gionzend un nùmer qualsëssìa d'element.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "gionze",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Gionté, gavé o riordiné le session për configuré torna ës blòch ëd test.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Gionté n'element al test.",
                +	"TEXT_APPEND_TITLE": "a %1 taché ël test %2",
                +	"TEXT_APPEND_TOOLTIP": "Taché dël test a la variàbil '%1'.",
                +	"TEXT_LENGTH_TITLE": "longheur ëd %1",
                +	"TEXT_LENGTH_TOOLTIP": "A smon ël nùmer ëd litre (spassi comprèis) ant ël test fornì.",
                +	"TEXT_ISEMPTY_TITLE": "%1 a l'é veuid",
                +	"TEXT_ISEMPTY_TOOLTIP": "A smon ver se ël test fornì a l'é veuid.",
                +	"TEXT_INDEXOF_TOOLTIP": "A smon l'ìndes dla prima/ùltima ocorensa dël prim test ant ël second test. A smon %1 se ël test a l'é nen trovà.",
                +	"TEXT_INDEXOF_TITLE": "ant ël test %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "trové la prima ocorensa dël test",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "trové l'ùltima ocorensa dël test",
                +	"TEXT_CHARAT_TITLE": "ant ël test %1 %2",
                +	"TEXT_CHARAT_FROM_START": "oten-e la litra #",
                +	"TEXT_CHARAT_FROM_END": "oten-e la litra # da la fin",
                +	"TEXT_CHARAT_FIRST": "oten-e la prima litra",
                +	"TEXT_CHARAT_LAST": "oten-e l'ùltima litra",
                +	"TEXT_CHARAT_RANDOM": "oten-e na litra a l'ancàpit",
                +	"TEXT_CHARAT_TOOLTIP": "A smon la litra ant la posission ëspessificà.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "A smon un tòch ëspessificà dël test.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ant ël test",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "oten-e la sota-stringa da la litra #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "oten-e la sota-stringa da la litra # da la fin",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "oten-e la sota-stringa da la prima litra",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "fin-a a la litra #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "fin-a a la litra # da la fin",
                +	"TEXT_GET_SUBSTRING_END_LAST": "fin-a a l'ùltima litra",
                +	"TEXT_CHANGECASE_TOOLTIP": "A smon na còpia dël test ant un caràter diferent.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "an MAJÙSCOL",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "an minùscul",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "an Majùscol A L'Ancamin Ëd Minca Paròla",
                +	"TEXT_TRIM_TOOLTIP": "A smon na còpia dël test con jë spassi gavà da n'estremità o da tute doe.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "gavé jë spassi da le doe bande ëd",
                +	"TEXT_TRIM_OPERATOR_LEFT": "gavé jë spassi da la banda snistra ëd",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "gavé jë spassi da la banda drita ëd",
                +	"TEXT_PRINT_TITLE": "smon-e %1",
                +	"TEXT_PRINT_TOOLTIP": "Smon-e ël test, ël nùmer o n'àutr valor ëspessificà.",
                +	"TEXT_PROMPT_TYPE_TEXT": "anvit për un test con un mëssagi",
                +	"TEXT_PROMPT_TYPE_NUMBER": "anvit për un nùmer con un mëssagi",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Ciamé un nùmer a l'utent.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Ciamé un test a l'utent.",
                +	"TEXT_COUNT_MESSAGE0": "nùmer %1 su %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Conté vàire vire un test dàit a compariss an n'àutr test.",
                +	"TEXT_REPLACE_MESSAGE0": "rampiassé %1 con %2 an %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Rampiassé tute j'ocorense d'un test con n'àutr.",
                +	"TEXT_REVERSE_MESSAGE0": "Anversé %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Anversé l'òrdin dij caràter ant ël test.",
                +	"LISTS_CREATE_EMPTY_TITLE": "creé na lista veuida",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Smon-e na lista, ëd longheur 0, ch'a conten gnun-a argistrassion",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Creé na lista con un nùmer qualsëssìa d'element.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "creé na lista con",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Gionté, gavé o riordiné le session për configuré torna cost blòch ëd lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Gionté n'element a la lista.",
                +	"LISTS_REPEAT_TOOLTIP": "A crea na lista ch'a consist dël valor dàit arpetù ël nùmer ëspessificà ëd vire.",
                +	"LISTS_REPEAT_TITLE": "creé na lista con l'element %1 arpetù %2 vire",
                +	"LISTS_LENGTH_TITLE": "longheur ëd %1",
                +	"LISTS_LENGTH_TOOLTIP": "A smon la longheur ¨d na lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 a l'é veuid",
                +	"LISTS_ISEMPTY_TOOLTIP": "A smon ver se la lista a l'é veuida.",
                +	"LISTS_INLIST": "ant la lista",
                +	"LISTS_INDEX_OF_FIRST": "trové la prima ocorensa dl'element",
                +	"LISTS_INDEX_OF_LAST": "trové l'ùltima ocorensa dl'element",
                +	"LISTS_INDEX_OF_TOOLTIP": "A smon l'ìndes ëd la prima/ùltima ocorensa dl'element ant la lista. A smon %1 se l'element a l'é nen trovà.",
                +	"LISTS_GET_INDEX_GET": "oten-e",
                +	"LISTS_GET_INDEX_GET_REMOVE": "oten-e e eliminé",
                +	"LISTS_GET_INDEX_REMOVE": "eliminé",
                +	"LISTS_GET_INDEX_FROM_END": "# da la fin",
                +	"LISTS_GET_INDEX_FIRST": "prim",
                +	"LISTS_GET_INDEX_LAST": "ùltim",
                +	"LISTS_GET_INDEX_RANDOM": "a l'ancàpit",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 a l'é ël prim element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 a l'é l'ùltim element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "A smon l'element a la posission ëspessificà an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "A smon ël prim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "A smon l'ùltim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "A smon n'element a l'ancàpit an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "A gava e a smon l'element a la posission ëspessificà an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "A gava e a smon ël prim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "A gava e a smon l'ùltim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "A gava e a smon n'element a l'ancàpit an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "A gava l'element a la posission ëspessificà an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "A gava ël prim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "A gava l'ùltim element an na lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "A gava n'element a l'ancàpit da na lista.",
                +	"LISTS_SET_INDEX_SET": "buté",
                +	"LISTS_SET_INDEX_INSERT": "anserì an",
                +	"LISTS_SET_INDEX_INPUT_TO": "tanme",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "A fissa l'element a la posission ëspessificà an na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "A fissa ël prim element an na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "A fissa l'ùltim element an na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "A fissa n'element a l'ancàpit an na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "A anseriss l'element a la posission ëspessificà an na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "A anseriss l'element al prinsipi ëd na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Gionté l'element a la fin ëd na lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "A anseriss l'element a l'ancàpit an na lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "oten-e la sot-lista da #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "oten-e la sot-lista da # da la fin",
                +	"LISTS_GET_SUBLIST_START_FIRST": "oten-e la sot-lista dal prim",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "fin-a a #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "fin-a a # da la fin",
                +	"LISTS_GET_SUBLIST_END_LAST": "fin-a a l'ùltim",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "A crea na còpia dël tòch ëspessificà ëd na lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "ordiné %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordiné na còpia ëd na lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "chërsent",
                +	"LISTS_SORT_ORDER_DESCENDING": "calant",
                +	"LISTS_SORT_TYPE_NUMERIC": "numérich",
                +	"LISTS_SORT_TYPE_TEXT": "alfabétich",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabétich, ignorand ël caràter minùscol o majùscol",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "fé na lista da 'n test",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "fé 'n test da na lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "con ël separator",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Divide un test an na lista ëd test, tajand a minca 'n separator.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Gionze na lista ëd test ant un test sol, separandje con un separator.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "anversé %1",
                +	"LISTS_REVERSE_TOOLTIP": "Anversé na còpia ëd na lista",
                +	"VARIABLES_GET_TOOLTIP": "A smon ël valor ëd sa variàbil.",
                +	"VARIABLES_GET_CREATE_SET": "Creé 'fissé %1'",
                +	"VARIABLES_SET": "fissé %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Fissé costa variàbil ugual al valor d'imission.",
                +	"VARIABLES_SET_CREATE_GET": "Creé 'oten-e %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "a",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "fé cheicòs",
                +	"PROCEDURES_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "A crea na fonsion sensa surtìa.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Descrive sa fonsion...",
                +	"PROCEDURES_DEFRETURN_RETURN": "artorn",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "A crea na fonsion con na surtìa.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "përmëtte le diciairassion",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Atension: Costa fonsion a l'ha dij paràmeter duplicà.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Eseguì la fonsion '%1' definìa da l'utent.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Eseguì la fonsion '%1' definìa da l'utent e dovré sò arzultà.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "imission",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Gionté, gavé o riordiné j'imission ëd sa fonsion.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nòm ëd l'imission:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Gionté n'imission a la fonsion.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Sot-ligné la definission dla fonsion",
                +	"PROCEDURES_CREATE_DO": "Creé '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Se un valor a l'é ver, antlora smon-e un second valor.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Atension: Ës blòch a podria esse dovrà mach an na definission ëd fonsion."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/pt-br.json b/blockly/webif/static/blockly/msg/json/pt-br.json
                new file mode 100644
                index 000000000..7e033cfc6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/pt-br.json
                @@ -0,0 +1,360 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"Prilopes",
                +			"Mordecaista",
                +			"Amgauna",
                +			"TheGabrielZaum",
                +			"Cainamarques",
                +			"Tuliouel",
                +			"Rodrigo codignoli",
                +			"Webysther",
                +			"Fasouzafreitas",
                +			"Almondega",
                +			"Rogerio Melfi",
                +			"Caçador de Palavras",
                +			"Luk3",
                +			"Cristofer Alves",
                +			"EVinente",
                +			"Lowvy",
                +			"Trigonometria87",
                +			"BarbaraAckles",
                +			"Mauricio",
                +			"Felipe L. Ewald"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Hoje",
                +	"DUPLICATE_BLOCK": "Duplicar",
                +	"ADD_COMMENT": "Adicionar comentário",
                +	"REMOVE_COMMENT": "Remover comentário",
                +	"EXTERNAL_INPUTS": "Entradas externas",
                +	"INLINE_INPUTS": "Entradas incorporadas",
                +	"DELETE_BLOCK": "Deletar bloco",
                +	"DELETE_X_BLOCKS": "Deletar %1 blocos",
                +	"DELETE_ALL_BLOCKS": "Deletar todos os blocos %1?",
                +	"CLEAN_UP": "Limpar blocos",
                +	"COLLAPSE_BLOCK": "Colapsar Bloco",
                +	"COLLAPSE_ALL": "Colapsar Blocos",
                +	"EXPAND_BLOCK": "Expandir bloco",
                +	"EXPAND_ALL": "Expandir blocos",
                +	"DISABLE_BLOCK": "Desabilitar bloco",
                +	"ENABLE_BLOCK": "Habilitar bloco",
                +	"HELP": "Ajuda",
                +	"UNDO": "Desfazer",
                +	"REDO": "Refazer",
                +	"CHANGE_VALUE_TITLE": "Mudar valor:",
                +	"RENAME_VARIABLE": "Renomear variável...",
                +	"RENAME_VARIABLE_TITLE": "Renomear todas as variáveis '%1' para:",
                +	"NEW_VARIABLE": "Criar variável...",
                +	"NEW_VARIABLE_TITLE": "Nome da nova variável:",
                +	"VARIABLE_ALREADY_EXISTS": "A variável chamada '%1' já existe.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Uma variável chamada '%1' já existe para outra variável do tipo '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Um procedimento chamado '%1' já existe.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Deletar %1 usos da variável '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Não se pode deletar a variável '%1' porque é parte da definição da função '%2'",
                +	"DELETE_VARIABLE": "Deletar a variável '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://pt.wikipedia.org/wiki/Cor",
                +	"COLOUR_PICKER_TOOLTIP": "Escolher uma cor da palheta de cores.",
                +	"COLOUR_RANDOM_TITLE": "cor aleatória",
                +	"COLOUR_RANDOM_TOOLTIP": "Escolher cor de forma aleatória.",
                +	"COLOUR_RGB_TITLE": "colorir com",
                +	"COLOUR_RGB_RED": "vermelho",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "azul",
                +	"COLOUR_RGB_TOOLTIP": "Criar uma cor com a quantidade especificada de vermelho, verde e azul. Todos os valores devem estar entre 0 e 100.",
                +	"COLOUR_BLEND_TITLE": "misturar",
                +	"COLOUR_BLEND_COLOUR1": "cor 1",
                +	"COLOUR_BLEND_COLOUR2": "cor 2",
                +	"COLOUR_BLEND_RATIO": "proporção",
                +	"COLOUR_BLEND_TOOLTIP": "Mistura duas cores em uma dada proporção (0,0 - 1,0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://pt.wikipedia.org/wiki/Estrutura_de_repeti%C3%A7%C3%A3o#Repeti.C3.A7.C3.A3o_com_vari.C3.A1vel_de_controle",
                +	"CONTROLS_REPEAT_TITLE": "repita %1 vezes",
                +	"CONTROLS_REPEAT_INPUT_DO": "faça",
                +	"CONTROLS_REPEAT_TOOLTIP": "Faça algumas instruções várias vezes.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repita enquanto",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repita até",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Enquanto um valor for verdadeiro, então faça algumas instruções.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Enquanto um valor for falso, então faça algumas instruções.",
                +	"CONTROLS_FOR_TOOLTIP": "Faça com que a variável '%1' assuma os valores do número inicial ao número final, contando de acordo com o intervalo especificado e execute os blocos especificados.",
                +	"CONTROLS_FOR_TITLE": "contar com %1 de %2 até %3 por %4",
                +	"CONTROLS_FOREACH_TITLE": "para cada item %1 na lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Para cada item em uma lista, atribua o item à variável '%1' e então realize algumas instruções.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "encerra o laço",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continua com a próxima iteração do laço",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Encerra o laço.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Ignora o resto deste laço, e continua com a próxima iteração.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Atenção: Este bloco só pode ser usado dentro de um laço.",
                +	"CONTROLS_IF_TOOLTIP_1": "Se um valor for verdadeiro, então realize algumas instruções.",
                +	"CONTROLS_IF_TOOLTIP_2": "Se um valor for verdadeiro, então realize o primeiro bloco de instruções. Senão, realize o segundo bloco de instruções.",
                +	"CONTROLS_IF_TOOLTIP_3": "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.",
                +	"CONTROLS_IF_TOOLTIP_4": "Se o primeiro valor for verdadeiro, então realize o primeiro bloco de instruções. Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções. Se nenhum dos blocos for verdadeiro, realize o último bloco de instruções.",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "senão se",
                +	"CONTROLS_IF_MSG_ELSE": "senão",
                +	"CONTROLS_IF_IF_TOOLTIP": "Acrescente, remova ou reordene seções para reconfigurar este bloco.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Acrescente uma condição para o bloco se.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Acrescente uma condição final para o bloco se.",
                +	"IOS_OK": "Ok",
                +	"IOS_CANCEL": "blockly:IOS Cancelar/pt-br",
                +	"IOS_ERROR": "Erro",
                +	"IOS_PROCEDURES_INPUTS": "ENTRADAS",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Adicionar Entrada",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Permitir declarações",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Essa função tem entradas duplicadas.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Adicionar Variável",
                +	"IOS_VARIABLES_ADD_BUTTON": "Adicionar",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Blockly:Renomear varioas botoens/pt-br",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Deletar",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nome variavel",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Você não pode usar um nome de variável vazio.",
                +	"LOGIC_COMPARE_HELPURL": "https://pt.wikipedia.org/wiki/Inequa%C3%A7%C3%A3o",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Retorna verdadeiro se ambas as entradas forem iguais.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Retorna verdadeiro se ambas as entradas forem diferentes.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Retorna verdadeiro se a primeira entrada for menor que a segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Retorna verdadeiro se a primeira entrada for menor ou igual à segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Retorna verdadeiro se a primeira entrada for maior que a segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Retorna verdadeiro se a primeira entrada for maior ou igual à segunda entrada.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Retorna verdadeiro se ambas as entradas forem verdadeiras.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Retorna verdadeiro se uma das estradas for verdadeira.",
                +	"LOGIC_OPERATION_OR": "ou",
                +	"LOGIC_NEGATE_TITLE": "não %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Retorna verdadeiro se a entrada for falsa.  Retorna falsa se a entrada for verdadeira.",
                +	"LOGIC_BOOLEAN_TRUE": "verdadeiro",
                +	"LOGIC_BOOLEAN_FALSE": "falso",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Retorna verdadeiro ou falso.",
                +	"LOGIC_NULL": "nulo",
                +	"LOGIC_NULL_TOOLTIP": "Retorna nulo.",
                +	"LOGIC_TERNARY_CONDITION": "teste",
                +	"LOGIC_TERNARY_IF_TRUE": "se verdadeiro",
                +	"LOGIC_TERNARY_IF_FALSE": "se falso",
                +	"LOGIC_TERNARY_TOOLTIP": "Avalia a condição em \"teste\". Se a condição for verdadeira retorna o valor \"se verdadeiro\", senão retorna o valor \"se falso\".",
                +	"MATH_NUMBER_HELPURL": "https://pt.wikipedia.org/wiki/N%C3%BAmero",
                +	"MATH_NUMBER_TOOLTIP": "Um número.",
                +	"MATH_ARITHMETIC_HELPURL": "https://pt.wikipedia.org/wiki/Aritm%C3%A9tica",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Retorna a soma dos dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Retorna a diferença entre os dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Retorna o produto dos dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Retorna o quociente da divisão dos dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Retorna o primeiro número elevado à potência do segundo número.",
                +	"MATH_SINGLE_HELPURL": "https://pt.wikipedia.org/wiki/Raiz_quadrada",
                +	"MATH_SINGLE_OP_ROOT": "raiz quadrada",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Retorna a raiz quadrada de um número.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluto",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Retorna o valor absoluto de um número.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Retorna o oposto de um número.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Retorna o logaritmo natural de um número.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Retorna o logaritmo em base 10 de um número.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Retorna o número e elevado à potência de um número.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Retorna 10 elevado à potência de um número.",
                +	"MATH_TRIG_HELPURL": "https://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_trigonom%C3%A9trica",
                +	"MATH_TRIG_TOOLTIP_SIN": "Retorna o seno de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_COS": "Retorna o cosseno de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Retorna a tangente de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Retorna o arco seno de um número.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Retorna o arco cosseno de um número.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Retorna o arco tangente de um número.",
                +	"MATH_CONSTANT_HELPURL": "https://pt.wikipedia.org/wiki/Anexo:Lista_de_constantes_matem%C3%A1ticas",
                +	"MATH_CONSTANT_TOOLTIP": "Retorna uma das constantes comuns: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infinito).",
                +	"MATH_IS_EVEN": "é par",
                +	"MATH_IS_ODD": "é ímpar",
                +	"MATH_IS_PRIME": "é primo",
                +	"MATH_IS_WHOLE": "é inteiro",
                +	"MATH_IS_POSITIVE": "é positivo",
                +	"MATH_IS_NEGATIVE": "é negativo",
                +	"MATH_IS_DIVISIBLE_BY": "é divisível por",
                +	"MATH_IS_TOOLTIP": "Verifica se um número é par, ímpar, inteiro, positivo, negativo, ou se é divisível por outro número.  Retorna verdadeiro ou falso.",
                +	"MATH_CHANGE_HELPURL": "https://pt.wikipedia.org/wiki/Adi%C3%A7%C3%A3o",
                +	"MATH_CHANGE_TITLE": "alterar %1 por %2",
                +	"MATH_CHANGE_TOOLTIP": "Soma um número à variável \"%1\".",
                +	"MATH_ROUND_HELPURL": "https://pt.wikipedia.org/wiki/Arredondamento",
                +	"MATH_ROUND_TOOLTIP": "Arredonda um número para cima ou para baixo.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arredonda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arredonda para cima",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arredonda para baixo",
                +	"MATH_ONLIST_OPERATOR_SUM": "soma de uma lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Retorna a soma de todos os números na lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "menor da lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Retorna o menor número da lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maior da lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Retorna o maior número da lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "média da lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Retorna a média aritmética dos números da lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana da lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Retorna a mediana dos números da lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "moda da lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Retorna uma lista do(s) item(ns) mais comum(ns) da lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "desvio padrão da lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Retorna o desvio padrão dos números da lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "item aleatório da lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Retorna um elemento aleatório da lista.",
                +	"MATH_MODULO_HELPURL": "https://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo",
                +	"MATH_MODULO_TITLE": "resto da divisão de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Retorna o resto da divisão de dois números.",
                +	"MATH_CONSTRAIN_TITLE": "restringe %1 inferior %2 superior %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Restringe um número entre os limites especificados (inclusivo).",
                +	"MATH_RANDOM_INT_HELPURL": "https://pt.wikipedia.org/wiki/Gerador_de_n%C3%BAmeros_pseudoaleat%C3%B3rios",
                +	"MATH_RANDOM_INT_TITLE": "inteiro aleatório entre %1 e %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Retorna um número inteiro entre os dois limites informados, inclusivo.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://pt.wikipedia.org/wiki/Gerador_de_n%C3%BAmeros_pseudoaleat%C3%B3rios",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fração aleatória",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Retorna uma fração aleatória entre 0.0 (inclusivo) e 1.0 (exclusivo).",
                +	"TEXT_TEXT_HELPURL": "https://pt.wikipedia.org/wiki/Cadeia_de_caracteres",
                +	"TEXT_TEXT_TOOLTIP": "Uma letra, palavra ou linha de texto.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "criar texto com",
                +	"TEXT_JOIN_TOOLTIP": "Criar um pedaço de texto juntando qualquer número de itens.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Acrescenta, remove ou reordena seções para reconfigurar este bloco de texto.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Acrescentar um item ao texto.",
                +	"TEXT_APPEND_TITLE": "para %1 anexar texto %2",
                +	"TEXT_APPEND_TOOLTIP": "Acrescentar um pedaço de texto à variável \"%1\".",
                +	"TEXT_LENGTH_TITLE": "tamanho de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Retorna o número de letras (incluindo espaços) no texto fornecido.",
                +	"TEXT_ISEMPTY_TITLE": "%1 é vazio",
                +	"TEXT_ISEMPTY_TOOLTIP": "Retorna verdadeiro se o texto fornecido for vazio.",
                +	"TEXT_INDEXOF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto.  Retorna %1 se o texto não for encontrado.",
                +	"TEXT_INDEXOF_TITLE": "no texto %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "encontre a primeira ocorrência do item",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "encontre a última ocorrência do texto",
                +	"TEXT_CHARAT_TITLE": "no texto %1 %2",
                +	"TEXT_CHARAT_FROM_START": "obter letra nº",
                +	"TEXT_CHARAT_FROM_END": "obter letra # a partir do final",
                +	"TEXT_CHARAT_FIRST": "obter primeira letra",
                +	"TEXT_CHARAT_LAST": "obter última letra",
                +	"TEXT_CHARAT_RANDOM": "obter letra aleatória",
                +	"TEXT_CHARAT_TOOLTIP": "Retorna a letra na posição especificada.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Retorna o trecho de texto especificado.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "no texto",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "obter trecho de letra nº",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "obter trecho de letra nº a partir do final",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "obter trecho de primeira letra",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "até letra nº",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "até letra nº a partir do final",
                +	"TEXT_GET_SUBSTRING_END_LAST": "até última letra",
                +	"TEXT_CHANGECASE_TOOLTIP": "Retorna uma cópia do texto em um formato diferente.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "para MAIÚSCULAS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "para minúsculas",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "para Nomes Próprios",
                +	"TEXT_TRIM_TOOLTIP": "Retorna uma cópia do texto com os espaços removidos de uma ou ambas extremidades.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "remover espaços de ambos os lados de",
                +	"TEXT_TRIM_OPERATOR_LEFT": "remover espaços à esquerda de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "remover espaços à direita de",
                +	"TEXT_PRINT_TITLE": "imprime %1",
                +	"TEXT_PRINT_TOOLTIP": "Imprime o texto, número ou valor especificado.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Pede um texto com uma mensagem",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Pede um número com uma mensagem",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Pede ao usuário um número.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Pede ao usuário um texto.",
                +	"TEXT_COUNT_MESSAGE0": "Contar %1 em %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Calcule quantas vezes algum texto aparece centro de algum outro texto.",
                +	"TEXT_REPLACE_MESSAGE0": "substituir %1 por %2 em %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Texto#substituindo-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Substitua todas as ocorrências de algum texto dentro de algum outro texto.",
                +	"TEXT_REVERSE_MESSAGE0": "inverter %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Texto#invertendo-texto",
                +	"TEXT_REVERSE_TOOLTIP": "Inverter a ordem dos caracteres no texto.",
                +	"LISTS_CREATE_EMPTY_TITLE": "criar lista vazia",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Retorna uma lista, de tamanho 0, contendo nenhum registro",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Cria uma lista com a quantidade de itens informada.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "criar lista com",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Acrescenta, remove ou reordena seções para reconfigurar este bloco de lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Acrescenta um item à lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Cria uma lista consistindo no valor informado repetido o número de vezes especificado.",
                +	"LISTS_REPEAT_TITLE": "criar lista com item %1 repetido %2 vezes",
                +	"LISTS_LENGTH_TITLE": "tamanho de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Retorna o tamanho de uma lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 é vazia",
                +	"LISTS_ISEMPTY_TOOLTIP": "Retorna ao verdadeiro se a lista estiver vazia.",
                +	"LISTS_INLIST": "na lista",
                +	"LISTS_INDEX_OF_FIRST": "encontre a primeira ocorrência do item",
                +	"LISTS_INDEX_OF_LAST": "encontre a última ocorrência do item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Retorna o índice da primeira/última ocorrência do item na lista.  Retorna %1 se o item não for encontrado.",
                +	"LISTS_GET_INDEX_GET": "obter",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obter e remover",
                +	"LISTS_GET_INDEX_REMOVE": "remover",
                +	"LISTS_GET_INDEX_FROM_START": "nº",
                +	"LISTS_GET_INDEX_FROM_END": "nº a partir do final",
                +	"LISTS_GET_INDEX_FIRST": "primeiro",
                +	"LISTS_GET_INDEX_LAST": "último",
                +	"LISTS_GET_INDEX_RANDOM": "aleatório",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 é o primeiro item.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 é o último item.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Retorna o item da lista na posição especificada.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Retorna o primeiro item em uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Retorna o último item em uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Retorna um item aleatório de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Remove e retorna o item na posição especificada em uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Remove e retorna o primeiro item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Remove e retorna o último item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Remove e retorna um item aleatório de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Remove o item na posição especificada em uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Remove o primeiro item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Remove o último item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Remove um item aleatório de uma lista.",
                +	"LISTS_SET_INDEX_SET": "definir",
                +	"LISTS_SET_INDEX_INSERT": "inserir em",
                +	"LISTS_SET_INDEX_INPUT_TO": "como",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Define o item da posição especificada de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Define o primeiro item de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Define o último item de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Define um item aleatório de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insere o item na posição especificada em uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insere o item no início de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Insere o item no final de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Insere o item em uma posição qualquer de uma lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "obtém sublista de nº",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "obtém sublista de nº a partir do final",
                +	"LISTS_GET_SUBLIST_START_FIRST": "obtém sublista a partir do primeiro",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "até nº",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "até nº a partir do final",
                +	"LISTS_GET_SUBLIST_END_LAST": "até último",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Cria uma cópia da porção especificada de uma lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "ordenar %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordenar uma cópia de uma lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ascendente",
                +	"LISTS_SORT_ORDER_DESCENDING": "descendente",
                +	"LISTS_SORT_TYPE_NUMERIC": "numérico",
                +	"LISTS_SORT_TYPE_TEXT": "alfabético",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabético, ignorar maiúscula/minúscula",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "Fazer uma lista a partir do texto",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "fazer um texto a partir da lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "com delimitador",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dividir o texto em uma lista de textos, separando-o em cada delimitador.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Juntar uma lista de textos em um único texto, separado por um delimitador.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Listas#invertendo-uma-lista",
                +	"LISTS_REVERSE_MESSAGE0": "inverter %1",
                +	"LISTS_REVERSE_TOOLTIP": "Inverter uma cópia da lista.",
                +	"VARIABLES_GET_TOOLTIP": "Retorna o valor desta variável.",
                +	"VARIABLES_GET_CREATE_SET": "Criar \"definir %1\"",
                +	"VARIABLES_SET": "definir %1 para %2",
                +	"VARIABLES_SET_TOOLTIP": "Define esta variável para o valor da entrada.",
                +	"VARIABLES_SET_CREATE_GET": "Criar \"obter %1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "para",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "faça algo",
                +	"PROCEDURES_BEFORE_PARAMS": "com:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "com:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Cria uma função que não tem retorno.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Descreva esta função...",
                +	"PROCEDURES_DEFRETURN_RETURN": "retorna",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Cria uma função que possui um valor de retorno.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permitir declarações",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Atenção: Esta função tem parâmetros duplicados.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://pt.wikipedia.org/wiki/Sub-rotina",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Executa a função definida pelo usuário \"%1\".",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://pt.wikipedia.org/wiki/Sub-rotina",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Executa a função definida pelo usuário \"%1\" e usa seu retorno.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entradas",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Adiciona, remove, ou reordena as entradas para esta função.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nome da entrada:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Adiciona uma entrada para esta função",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Destacar definição da função",
                +	"PROCEDURES_CREATE_DO": "Criar \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Se um valor é verdadeiro, então retorna um valor.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Atenção: Este bloco só pode ser utilizado dentro da definição de uma função."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/pt.json b/blockly/webif/static/blockly/msg/json/pt.json
                new file mode 100644
                index 000000000..d3f8217bf
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/pt.json
                @@ -0,0 +1,361 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Imperadeiro98",
                +			"Waldir",
                +			"Vitorvicentevalente",
                +			"아라",
                +			"Nicola Nascimento",
                +			"Önni",
                +			"Diniscoelho",
                +			"Fúlvio",
                +			"Mansil",
                +			"Mauricio"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Hoje",
                +	"DUPLICATE_BLOCK": "Duplicar",
                +	"ADD_COMMENT": "Adicionar Comentário",
                +	"REMOVE_COMMENT": "Remover Comentário",
                +	"EXTERNAL_INPUTS": "Entradas Externas",
                +	"INLINE_INPUTS": "Entradas Em Linhas",
                +	"DELETE_BLOCK": "Eliminar Bloco",
                +	"DELETE_X_BLOCKS": "Eliminar %1 Blocos",
                +	"DELETE_ALL_BLOCKS": "Eliminar todos os %1 blocos?",
                +	"CLEAN_UP": "Limpar Blocos",
                +	"COLLAPSE_BLOCK": "Ocultar Bloco",
                +	"COLLAPSE_ALL": "Ocultar Blocos",
                +	"EXPAND_BLOCK": "Expandir Bloco",
                +	"EXPAND_ALL": "Expandir Blocos",
                +	"DISABLE_BLOCK": "Desativar Bloco",
                +	"ENABLE_BLOCK": "Ativar Bloco",
                +	"HELP": "Ajuda",
                +	"UNDO": "Desfazer",
                +	"REDO": "Refazer",
                +	"CHANGE_VALUE_TITLE": "Alterar valor:",
                +	"RENAME_VARIABLE": "Renomear variável...",
                +	"RENAME_VARIABLE_TITLE": "Renomear todas as variáveis '%1' para:",
                +	"NEW_VARIABLE": "Criar variável…",
                +	"NEW_VARIABLE_TITLE": "Nome da nova variável:",
                +	"VARIABLE_ALREADY_EXISTS": "Já existe uma variável com o nome de '%1'.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Eliminar %1 utilizações da variável '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Não se pode eliminar a variável '%1' porque faz parte da definição da função '%2'",
                +	"DELETE_VARIABLE": "Eliminar a variável '%1'",
                +	"COLOUR_PICKER_HELPURL": "http://pt.wikipedia.org/wiki/Cor",
                +	"COLOUR_PICKER_TOOLTIP": "Escolha uma cor da paleta de cores.",
                +	"COLOUR_RANDOM_TITLE": "cor aleatória",
                +	"COLOUR_RANDOM_TOOLTIP": "Escolha uma cor aleatoriamente.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "pinte com",
                +	"COLOUR_RGB_RED": "vermelho",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "azul",
                +	"COLOUR_RGB_TOOLTIP": "Cria uma cor de acordo com a quantidade especificada de vermelho, verde e azul. Todos os valores devem estar entre 0 e 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "misturar",
                +	"COLOUR_BLEND_COLOUR1": "cor 1",
                +	"COLOUR_BLEND_COLOUR2": "cor 2",
                +	"COLOUR_BLEND_RATIO": "proporção",
                +	"COLOUR_BLEND_TOOLTIP": "Mistura duas cores com a proporção indicada (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "http://pt.wikipedia.org/wiki/Estrutura_de_repeti%C3%A7%C3%A3o#Repeti.C3.A7.C3.A3o_com_vari.C3.A1vel_de_controle",
                +	"CONTROLS_REPEAT_TITLE": "repetir %1 vez",
                +	"CONTROLS_REPEAT_INPUT_DO": "faça",
                +	"CONTROLS_REPEAT_TOOLTIP": "Faça algumas instruções várias vezes.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repetir enquanto",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repetir até",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Enquanto um valor for verdadeiro, então faça algumas instruções.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Enquanto um valor for falso, então faça algumas instruções.",
                +	"CONTROLS_FOR_TOOLTIP": "Faz com que a variável \"%1\" assuma os valores desde o número inicial até ao número final, contando de acordo com o intervalo especificado e executa os blocos especificados.",
                +	"CONTROLS_FOR_TITLE": "contar com %1 de %2 até %3 de %3 em %4",
                +	"CONTROLS_FOREACH_TITLE": "para cada item %1 na lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Para cada item numa lista, define a variável \"%1\" para o item e então faz algumas instruções.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "sair do ciclo",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuar com a próxima iteração do ciclo",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Sair do ciclo que está contido.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Ignorar o resto deste ciclo, e continuar com a próxima iteração.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Atenção: Este bloco só pode ser usado dentro de um ciclo.",
                +	"CONTROLS_IF_TOOLTIP_1": "Se um valor é verdadeiro, então realize alguns passos.",
                +	"CONTROLS_IF_TOOLTIP_2": "Se um valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, realize o segundo bloco de instruções",
                +	"CONTROLS_IF_TOOLTIP_3": "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.",
                +	"CONTROLS_IF_TOOLTIP_4": "Se o primeiro valor é verdadeiro, então realize o primeiro bloco de instruções.  Senão, se o segundo valor é verdadeiro, realize o segundo bloco de instruções.  Se nenhum dos blocos for verdadeiro, realize o último bloco de instruções.",
                +	"CONTROLS_IF_MSG_IF": "se",
                +	"CONTROLS_IF_MSG_ELSEIF": "senão se",
                +	"CONTROLS_IF_MSG_ELSE": "senão",
                +	"CONTROLS_IF_IF_TOOLTIP": "Acrescente, remova ou reordene secções para reconfigurar este bloco se.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Acrescente uma condição ao bloco se.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Acrescente uma condição de excepação final para o bloco se.",
                +	"IOS_OK": "Aceitar",
                +	"IOS_CANCEL": "Cancelar",
                +	"IOS_ERROR": "Erro",
                +	"IOS_PROCEDURES_INPUTS": "ENTRADAS",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Adicionar entrada",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Permitir declarações",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Essa função tem entradas duplicadas.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Adicionar Variável",
                +	"IOS_VARIABLES_ADD_BUTTON": "Adicionar",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Renomear",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Eliminar",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Nome da variável",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Você não pode usar um nome de variável vazio.",
                +	"LOGIC_COMPARE_HELPURL": "http://pt.wikipedia.org/wiki/Inequa%C3%A7%C3%A3o",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Retorna verdadeiro se ambas as entradas forem iguais entre si.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Retorna verdadeiro se ambas as entradas forem diferentes entre si.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Retorna verdadeiro se a primeira entrada for menor que a segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Retorna verdadeiro se a primeira entrada for menor ou igual à segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Retorna verdadeiro se a primeira entrada for maior que a segunda entrada.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Retorna verdadeiro se a primeira entrada for maior ou igual à segunda entrada.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Retorna verdadeiro se ambas as entradas forem verdadeiras.",
                +	"LOGIC_OPERATION_AND": "e",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Retorna verdadeiro se pelo menos uma das estradas for verdadeira.",
                +	"LOGIC_OPERATION_OR": "ou",
                +	"LOGIC_NEGATE_TITLE": "não %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Retorna verdadeiro se a entrada for falsa.  Retorna falso se a entrada for verdadeira.",
                +	"LOGIC_BOOLEAN_TRUE": "verdadeiro",
                +	"LOGIC_BOOLEAN_FALSE": "falso",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Retorna verdadeiro ou falso.",
                +	"LOGIC_NULL_HELPURL": "http://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "nulo",
                +	"LOGIC_NULL_TOOLTIP": "Retorna nulo.",
                +	"LOGIC_TERNARY_HELPURL": "http://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "teste",
                +	"LOGIC_TERNARY_IF_TRUE": "se verdadeiro",
                +	"LOGIC_TERNARY_IF_FALSE": "se falso",
                +	"LOGIC_TERNARY_TOOLTIP": "Avalia a condição em \"teste\". Se a condição for verdadeira retorna o valor \"se verdadeiro\", senão retorna o valor \"se falso\".",
                +	"MATH_NUMBER_HELPURL": "http://pt.wikipedia.org/wiki/N%C3%BAmero",
                +	"MATH_NUMBER_TOOLTIP": "Um número.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "http://pt.wikipedia.org/wiki/Aritm%C3%A9tica",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Retorna a soma de dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Retorna a diferença de dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Retorna o produto de dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Retorna o quociente da divisão de dois números.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Retorna o primeiro número elevado à potência do segundo número.",
                +	"MATH_SINGLE_HELPURL": "http://pt.wikipedia.org/wiki/Raiz_quadrada",
                +	"MATH_SINGLE_OP_ROOT": "raíz quadrada",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Retorna a raiz quadrada de um número.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absoluto",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Retorna o valor absoluto de um número.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Retorna o oposto de um número.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Retorna o logarítmo natural de um número.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Retorna o logarítmo em base 10 de um número.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Retorna o número e elevado à potência de um número.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Retorna 10 elevado à potência de um número.",
                +	"MATH_TRIG_HELPURL": "http://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_trigonom%C3%A9trica",
                +	"MATH_TRIG_TOOLTIP_SIN": "Retorna o seno de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_COS": "Retorna o cosseno de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Retorna a tangente de um grau (não radiano).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Retorna o arco seno de um número.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Retorna o arco cosseno de um número.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Retorna o arco tangente de um número.",
                +	"MATH_CONSTANT_HELPURL": "http://pt.wikipedia.org/wiki/Anexo:Lista_de_constantes_matem%C3%A1ticas",
                +	"MATH_CONSTANT_TOOLTIP": "Retorna uma das constantes comuns: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ou ∞ (infinito).",
                +	"MATH_IS_EVEN": "é par",
                +	"MATH_IS_ODD": "é impar",
                +	"MATH_IS_PRIME": "é primo",
                +	"MATH_IS_WHOLE": "é inteiro",
                +	"MATH_IS_POSITIVE": "é positivo",
                +	"MATH_IS_NEGATIVE": "é negativo",
                +	"MATH_IS_DIVISIBLE_BY": "é divisível por",
                +	"MATH_IS_TOOLTIP": "Verifica se um número é par, impar, primo, inteiro, positivo, negativo, ou se é divisível por outro número.  Retorna verdadeiro ou falso.",
                +	"MATH_CHANGE_HELPURL": "http://pt.wikipedia.org/wiki/Adi%C3%A7%C3%A3o",
                +	"MATH_CHANGE_TITLE": "alterar %1 por %2",
                +	"MATH_CHANGE_TOOLTIP": "Soma um número à variável \"%1\".",
                +	"MATH_ROUND_HELPURL": "http://pt.wikipedia.org/wiki/Arredondamento",
                +	"MATH_ROUND_TOOLTIP": "Arredonda um número para cima ou para baixo.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arredonda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "arredonda para cima",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arredonda para baixo",
                +	"MATH_ONLIST_OPERATOR_SUM": "soma da lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Retorna a soma de todos os números da lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "menor de uma lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Retorna o menor número da lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maior de uma lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Retorna o maior número da lista.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "média de uma lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Retorna a média aritmética dos valores números da lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana de uma lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Retorna a mediana da lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "moda de uma lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Retorna a lista de item(ns) mais comum(ns) da lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "desvio padrão de uma lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Retorna o desvio padrão dos números da lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "item aleatório de uma lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Retorna um elemento aleatório da lista.",
                +	"MATH_MODULO_HELPURL": "http://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo",
                +	"MATH_MODULO_TITLE": "resto da divisão de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Retorna o resto da divisão de dois números.",
                +	"MATH_CONSTRAIN_TITLE": "restringe %1 inferior %2 superior %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Restringe um número entre os limites especificados (inclusive).",
                +	"MATH_RANDOM_INT_HELPURL": "http://pt.wikipedia.org/wiki/N%C3%BAmero_aleat%C3%B3rio",
                +	"MATH_RANDOM_INT_TITLE": "inteiro aleatório entre %1 e %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Retorna um número inteiro entre os dois limites especificados, inclusive.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "http://pt.wikipedia.org/wiki/N%C3%BAmero_aleat%C3%B3rio",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fração aleatória",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Insere uma fração aleatória entre 0.0 (inclusive) e 1.0 (exclusive).",
                +	"TEXT_TEXT_HELPURL": "http://pt.wikipedia.org/wiki/Cadeia_de_caracteres",
                +	"TEXT_TEXT_TOOLTIP": "Uma letra, palavra ou linha de texto.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "criar texto com",
                +	"TEXT_JOIN_TOOLTIP": "Criar um pedaço de texto juntando qualquer número de itens.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "unir",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Acrescenta, remove ou reordena seções para reconfigurar este bloco de texto.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Acrescentar um item ao texto.",
                +	"TEXT_APPEND_TOOLTIP": "Acrescentar um pedaço de texto à variável \"%1\".",
                +	"TEXT_LENGTH_TITLE": "tamanho de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Devolve o número de letras (incluindo espaços) do texto fornecido.",
                +	"TEXT_ISEMPTY_TITLE": "%1 está vazio",
                +	"TEXT_ISEMPTY_TOOLTIP": "Retorna verdadeiro se o texto fornecido estiver vazio.",
                +	"TEXT_INDEXOF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto. Retorna %1 se o texto não for encontrado.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "primeira ocorrência do texto",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "última ocorrência do texto",
                +	"TEXT_CHARAT_FROM_START": "obter letra nº",
                +	"TEXT_CHARAT_FROM_END": "obter letra nº a partir do final",
                +	"TEXT_CHARAT_FIRST": "obter primeira letra",
                +	"TEXT_CHARAT_LAST": "obter última letra",
                +	"TEXT_CHARAT_RANDOM": "obter letra aleatória",
                +	"TEXT_CHARAT_TOOLTIP": "Retorna a letra na posição especificada.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Retorna a parte especificada do texto.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "no texto",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "obter subsequência de tamanho #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "obter subsequência de tamanho # a partir do final",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "obter subsequência a partir da primeira letra",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "até letra nº",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "até letra nº a partir do final",
                +	"TEXT_GET_SUBSTRING_END_LAST": "até última letra",
                +	"TEXT_CHANGECASE_TOOLTIP": "Retorna uma cópia do texto em formato diferente.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "para MAIÚSCULAS",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "para minúsculas",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "para Iniciais Maiúsculas",
                +	"TEXT_TRIM_TOOLTIP": "Retorna uma cópia do texto com os espaços removidos de uma ou ambas as extremidades.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "remover espaços de ambos os lados",
                +	"TEXT_TRIM_OPERATOR_LEFT": "remover espaços à esquerda de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "remover espaços à direita",
                +	"TEXT_PRINT_TITLE": "imprime %1",
                +	"TEXT_PRINT_TOOLTIP": "Imprime o texto, número ou outro valor especificado.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Pede um texto com a mensagem",
                +	"TEXT_PROMPT_TYPE_NUMBER": "pede um número com a mensagem",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Pede ao utilizador um número.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Pede ao utilizador um texto.",
                +	"TEXT_COUNT_MESSAGE0": "contar %1 em %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Conte quantas vezes um certo texto aparece dentro de algum outro texto.",
                +	"TEXT_REPLACE_MESSAGE0": "substituir %1 por %2 em %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Substituir todas as ocorrências de um certo texto dentro de algum outro texto.",
                +	"TEXT_REVERSE_MESSAGE0": "reverse %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Inverte a ordem dos caracteres no texto.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "criar lista vazia",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Retorna uma lista, de tamanho 0, contendo nenhum registo",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Cria uma lista com qualquer número de itens.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "criar lista com",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Acrescente, remova ou reordene as seções para reconfigurar este bloco lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Acrescenta um item à lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Cria uma lista constituída por um dado valor repetido o número de vezes especificado.",
                +	"LISTS_REPEAT_TITLE": "criar lista com o item %1 repetido %2 vezes",
                +	"LISTS_LENGTH_TITLE": "tamanho de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Retorna o tamanho de uma lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 está vazia",
                +	"LISTS_ISEMPTY_TOOLTIP": "Retona verdadeiro se a lista estiver vazia.",
                +	"LISTS_INLIST": "na lista",
                +	"LISTS_INDEX_OF_FIRST": "encontre a primeira ocorrência do item",
                +	"LISTS_INDEX_OF_LAST": "encontre a última ocorrência do item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do item na lista.  Retorna %1 se o item não for encontrado.",
                +	"LISTS_GET_INDEX_GET": "obter",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obter e remover",
                +	"LISTS_GET_INDEX_REMOVE": "remover",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# a partir do final",
                +	"LISTS_GET_INDEX_FIRST": "primeiro",
                +	"LISTS_GET_INDEX_LAST": "último",
                +	"LISTS_GET_INDEX_RANDOM": "aleatório",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 é o primeiro item.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 é o último item.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Retorna o item na posição especificada da lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Retorna o primeiro item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Retorna o último item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Retorna um item aleatório de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Remove e retorna o item na posição especificada de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Remove e retorna o primeiro item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Remove e retorna o último item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Remove e retorna um item aleatório de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Remove o item de uma posição especifica da lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Remove o primeiro item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Remove o último item de uma lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Remove um item aleatório de uma lista.",
                +	"LISTS_SET_INDEX_SET": "definir",
                +	"LISTS_SET_INDEX_INSERT": "inserir em",
                +	"LISTS_SET_INDEX_INPUT_TO": "como",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Define o item na posição especificada de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Define o primeiro item de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Define o último item de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Define um item aleatório de uma lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insere o item numa posição especificada numa lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insere o item no início da lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Insere o item no final da lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Insere o item numa posição aleatória de uma lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "obtem sublista de #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "obtem sublista de # a partir do final",
                +	"LISTS_GET_SUBLIST_START_FIRST": "obtem sublista da primeira lista",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "até #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "até #, a partir do final",
                +	"LISTS_GET_SUBLIST_END_LAST": "para o último",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Cria uma cópia da porção especificada de uma lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "ordenar %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Ordenar uma cópia de uma lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ascendente",
                +	"LISTS_SORT_ORDER_DESCENDING": "descendente",
                +	"LISTS_SORT_TYPE_NUMERIC": "numérica",
                +	"LISTS_SORT_TYPE_TEXT": "alfabética",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabética, ignorar maiúsculas/minúsculas",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "fazer lista a partir de texto",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "fazer texto a partir da lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "com delimitador",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dividir o texto numa lista de textos, separando-o em cada delimitador.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Juntar uma lista de textos num único texto, separado por um delimitador.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "inverter %1",
                +	"LISTS_REVERSE_TOOLTIP": "Inverter uma cópia da lista.",
                +	"VARIABLES_GET_TOOLTIP": "Retorna o valor desta variável.",
                +	"VARIABLES_GET_CREATE_SET": "Criar \"definir %1\"",
                +	"VARIABLES_SET": "definir %1 para %2",
                +	"VARIABLES_SET_TOOLTIP": "Define esta variável para o valor inserido.",
                +	"VARIABLES_SET_CREATE_GET": "Criar \"obter %1\"",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "para",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "faz algo",
                +	"PROCEDURES_BEFORE_PARAMS": "com:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "com:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Cria uma função que não tem retorno.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Descreva esta função...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "retorna",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Cria uma função que possui um valor de retorno.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permitir declarações",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Atenção: Esta função tem parâmetros duplicados.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://pt.wikipedia.org/wiki/Sub-rotina",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Executa a função \"%1\".",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://pt.wikipedia.org/wiki/Sub-rotina",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Executa a função \"%1\" e usa o seu retorno.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "entradas",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Adicionar, remover ou reordenar as entradas para esta função.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nome da entrada:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Adicionar uma entrada para a função.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Destacar definição da função",
                +	"PROCEDURES_CREATE_DO": "Criar \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "se o valor é verdadeiro, então retorna um segundo valor.",
                +	"PROCEDURES_IFRETURN_WARNING": "Atenção: Este bloco só pode ser utilizado dentro da definição de uma função."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/qqq.json b/blockly/webif/static/blockly/msg/json/qqq.json
                new file mode 100644
                index 000000000..69bf31f88
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/qqq.json
                @@ -0,0 +1,400 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"Liuxinyu970226",
                +			"Robby",
                +			"Shirayuki",
                +			"Metalhead64"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "default name - A simple, general default name for a variable, preferably short. For more context, see [[Translating:Blockly#infrequent_message_types]].\n{{Identical|Item}}",
                +	"TODAY": "button text - Button that sets a calendar to today's date.\n{{Identical|Today}}",
                +	"DUPLICATE_BLOCK": "context menu - Make a copy of the selected block (and any blocks it contains).\n{{Identical|Duplicate}}",
                +	"ADD_COMMENT": "context menu - Add a descriptive comment to the selected block.",
                +	"REMOVE_COMMENT": "context menu - Remove the descriptive comment from the selected block.",
                +	"EXTERNAL_INPUTS": "context menu - Change from 'external' to 'inline' mode for displaying blocks used as inputs to the selected block.  See [[Translating:Blockly#context_menus]].",
                +	"INLINE_INPUTS": "context menu - Change from 'internal' to 'external' mode for displaying blocks used as inputs to the selected block.  See [[Translating:Blockly#context_menus]].",
                +	"DELETE_BLOCK": "context menu - Permanently delete the selected block.",
                +	"DELETE_X_BLOCKS": "context menu - Permanently delete the %1 selected blocks.\n\nParameters:\n* %1 - an integer greater than 1.",
                +	"DELETE_ALL_BLOCKS": "confirmation prompt - Question the user if they really wanted to permanently delete all %1 blocks.\n\nParameters:\n* %1 - an integer greater than 1.",
                +	"CLEAN_UP": "context menu - Reposition all the blocks so that they form a neat line.",
                +	"COLLAPSE_BLOCK": "context menu - Make the appearance of the selected block smaller by hiding some information about it.",
                +	"COLLAPSE_ALL": "context menu - Make the appearance of all blocks smaller by hiding some information about it.  Use the same terminology as in the previous message.",
                +	"EXPAND_BLOCK": "context menu - Restore the appearance of the selected block by showing information about it that was hidden (collapsed) earlier.",
                +	"EXPAND_ALL": "context menu - Restore the appearance of all blocks by showing information about it that was hidden (collapsed) earlier.  Use the same terminology as in the previous message.",
                +	"DISABLE_BLOCK": "context menu - Make the selected block have no effect (unless reenabled).",
                +	"ENABLE_BLOCK": "context menu - Make the selected block have effect (after having been disabled earlier).",
                +	"HELP": "context menu - Provide helpful information about the selected block.\n{{Identical|Help}}",
                +	"UNDO": "context menu - Undo the previous action.\n{{Identical|Undo}}",
                +	"REDO": "context menu - Undo the previous undo action.\n{{Identical|Redo}}",
                +	"CHANGE_VALUE_TITLE": "prompt - This message is only seen in the Opera browser.  With most browsers, users can edit numeric values in blocks by just clicking and typing.  Opera does not allows this, so we have to open a new window and prompt users with this message to chanage a value.",
                +	"RENAME_VARIABLE": "dropdown choice - When the user clicks on a variable block, this is one of the dropdown menu choices.  It is used to rename the current variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].",
                +	"RENAME_VARIABLE_TITLE": "prompt - Prompts the user to enter the new name for the selected variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].\n\nParameters:\n* %1 - the name of the variable to be renamed.",
                +	"NEW_VARIABLE": "button text - Text on the button used to launch the variable creation dialogue.",
                +	"NEW_VARIABLE_TITLE": "prompt - Prompts the user to enter the name for a new variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].",
                +	"VARIABLE_ALREADY_EXISTS": "alert - Tells the user that the name they entered is already in use.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "alert - Tells the user that the name they entered is already in use for another type.",
                +	"PROCEDURE_ALREADY_EXISTS": "alert - Tells the user that the name they entered is already in use for a procedure.",
                +	"DELETE_VARIABLE_CONFIRMATION": "confirm -  Ask the user to confirm their deletion of multiple uses of a variable.",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "alert - Tell the user that they can't delete a variable because it's part of the definition of a function.",
                +	"DELETE_VARIABLE": "dropdown choice - Delete the currently selected variable.",
                +	"COLOUR_PICKER_HELPURL": "url - Information about colour.",
                +	"COLOUR_PICKER_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette].",
                +	"COLOUR_RANDOM_HELPURL": "url - A link that displays a random colour each time you visit it.",
                +	"COLOUR_RANDOM_TITLE": "block text - Title of block that generates a colour at random.",
                +	"COLOUR_RANDOM_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Colour#generating-a-random-colour https://github.com/google/blockly/wiki/Colour#generating-a-random-colour].",
                +	"COLOUR_RGB_HELPURL": "url - A link for color codes with percentages (0-100%) for each component, instead of the more common 0-255, which may be more difficult for beginners.",
                +	"COLOUR_RGB_TITLE": "block text - Title of block for [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].",
                +	"COLOUR_RGB_RED": "block input text - The amount of red (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Red}}",
                +	"COLOUR_RGB_GREEN": "block input text - The amount of green (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].",
                +	"COLOUR_RGB_BLUE": "block input text - The amount of blue (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Blue}}",
                +	"COLOUR_RGB_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].",
                +	"COLOUR_BLEND_HELPURL": "url - A useful link that displays blending of two colors.",
                +	"COLOUR_BLEND_TITLE": "block text - A verb for blending two shades of paint.",
                +	"COLOUR_BLEND_COLOUR1": "block input text - The first of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].",
                +	"COLOUR_BLEND_COLOUR2": "block input text - The second of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].",
                +	"COLOUR_BLEND_RATIO": "block input text - The proportion of the [https://github.com/google/blockly/wiki/Colour#blending-colours blend] containing the first color; the remaining proportion is of the second colour.  For example, if the first colour is red and the second color blue, a ratio of 1 would yield pure red, a ratio of .5 would yield purple (equal amounts of red and blue), and a ratio of 0 would yield pure blue.\n{{Identical|Ratio}}",
                +	"COLOUR_BLEND_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Colour#blending-colours https://github.com/google/blockly/wiki/Colour#blending-colours].",
                +	"CONTROLS_REPEAT_HELPURL": "url - Describes 'repeat loops' in computer programs; consider using the translation of the page [https://en.wikipedia.org/wiki/Control_flow http://en.wikipedia.org/wiki/Control_flow].",
                +	"CONTROLS_REPEAT_TITLE": "block input text - Title of [https://github.com/google/blockly/wiki/Loops#repeat repeat block].\n\nParameters:\n* %1 - the number of times the body of the loop should be repeated.",
                +	"CONTROLS_REPEAT_INPUT_DO": "block text - Preceding the blocks in the body of the loop.  See [https://github.com/google/blockly/wiki/Loops https://github.com/google/blockly/wiki/Loops].\n{{Identical|Do}}",
                +	"CONTROLS_REPEAT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat https://github.com/google/blockly/wiki/Loops#repeat].",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "url - Describes 'while loops' in computer programs; consider using the translation of [https://en.wikipedia.org/wiki/While_loop https://en.wikipedia.org/wiki/While_loop], if present, or [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow].",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-while repeat while] the following condition is true.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-until repeat until] the following condition becomes true.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while].",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-until https://github.com/google/blockly/wiki/Loops#repeat-until].",
                +	"CONTROLS_FOR_HELPURL": "url - Describes 'for loops' in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/For_loop https://en.wikipedia.org/wiki/For_loop], if present.",
                +	"CONTROLS_FOR_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Loops#count-with https://github.com/google/blockly/wiki/Loops#count-with].\n\nParameters:\n* %1 - the name of the loop variable.",
                +	"CONTROLS_FOR_TITLE": "block text - Repeatedly counts a variable (%1) starting with a (usually lower) number in a range (%2), ending with a (usually higher) number in a range (%3), and counting the iterations by a number of steps (%4).  As in [https://github.com/google/blockly/wiki/Loops#count-with https://github.com/google/blockly/wiki/Loops#count-with]. [[File:Blockly-count-with.png]]",
                +	"CONTROLS_FOREACH_HELPURL": "url - Describes 'for-each loops' in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Foreach https://en.wikipedia.org/wiki/Foreach] if present.",
                +	"CONTROLS_FOREACH_TITLE": "block text - Title of [https://github.com/google/blockly/wiki/Loops#for-each for each block]. Sequentially assigns every item in array %2 to the valiable %1.",
                +	"CONTROLS_FOREACH_TOOLTIP": "block text - Description of [https://github.com/google/blockly/wiki/Loops#for-each for each blocks].\n\nParameters:\n* %1 - the name of the loop variable.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "url - Describes control flow in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow], if it exists.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "dropdown - The current loop should be exited.  See [https://github.com/google/blockly/wiki/Loops#break https://github.com/google/blockly/wiki/Loops#break].",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "dropdown - The current iteration of the loop should be ended and the next should begin.  See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "tooltip - See [https://github.com/google/blockly/wiki/Loops#break-out-of-loop https://github.com/google/blockly/wiki/Loops#break-out-of-loop].",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "tooltip - See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "warning - The user has tried placing a block outside of a loop (for each, while, repeat, etc.), but this type of block may only be used within a loop.  See [https://github.com/google/blockly/wiki/Loops#loop-termination-blocks https://github.com/google/blockly/wiki/Loops#loop-termination-blocks].",
                +	"CONTROLS_IF_HELPURL": "url - Describes conditional statements (if-then-else) in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_else https://en.wikipedia.org/wiki/If_else], if present.",
                +	"CONTROLS_IF_TOOLTIP_1": "tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-blocks 'if' blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.",
                +	"CONTROLS_IF_TOOLTIP_2": "tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-blocks if-else blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.",
                +	"CONTROLS_IF_TOOLTIP_3": "tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-blocks if-else-if blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.",
                +	"CONTROLS_IF_TOOLTIP_4": "tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-else-blocks if-else-if-else blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.",
                +	"CONTROLS_IF_MSG_IF": "block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse]. It is recommended, but not essential, that this have text in common with the translation of 'else if'\n{{Identical|If}}",
                +	"CONTROLS_IF_MSG_ELSEIF": "block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].  The English words 'otherwise if' would probably be clearer than 'else if', but the latter is used because it is traditional and shorter.",
                +	"CONTROLS_IF_MSG_ELSE": "block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].  The English word 'otherwise' would probably be superior to 'else', but the latter is used because it is traditional and shorter.",
                +	"CONTROLS_IF_IF_TOOLTIP": "tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "tooltip - Describes the 'else if' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "tooltip - Describes the 'else' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].",
                +	"IOS_OK": "button text - Text on a button inside a dialogue window, which will accept or acknowledge the contents of the dialogue when pressed.\n{{Identical|OK}}",
                +	"IOS_CANCEL": "button text - Text on a button inside a dialogue window, which will close or cancel the dialogue when pressed.\n{{Identical|Cancel}}",
                +	"IOS_ERROR": "alert - Title text for an error dialogue.\n{{Identical|Error}}",
                +	"IOS_PROCEDURES_INPUTS": "header text - Title of a section that displays a list of parameters (aka. 'inputs') that have been defined for a procedure. This is used inside a dialogue window to configure a procedure.\n{{Identical|Input}}",
                +	"IOS_PROCEDURES_ADD_INPUT": "button text - Text on a button which will add a parameter (aka. 'input') to a procedure. This is used inside a dialogue window to configure a procedure. NOTE: The '+' should be preserved at the beginning of the text.",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "option text - Text describing an option to allow statements to be added within a procedure. This is used inside a dialogue window to configure a procedure.",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "alert - Error message when duplicate parameters (aka. 'inputs') have been defined on a procedure. This is used inside a dialogue window to configure procedure parameters.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "button text - Text on a button which will open a variable creation dialogue when pressed. NOTE: The '+' should be preserved at the beginning of the text.",
                +	"IOS_VARIABLES_ADD_BUTTON": "button text - Text on a button inside a variable creation dialogue, which will add a variable when pressed.\n{{Identical|Add}}",
                +	"IOS_VARIABLES_RENAME_BUTTON": "button text - Text on a button inside a variable rename dialogue, which will rename a variable when pressed.\n{{Identical|Rename}}",
                +	"IOS_VARIABLES_DELETE_BUTTON": "button text - Text on a button inside a variable deletion dialogue, which will delete a variable when pressed.\n{{Identical|Delete}}",
                +	"IOS_VARIABLES_VARIABLE_NAME": "placeholder text - Placeholder text used inside a text input, where a variable name should be entered.",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "alert - Error message that is displayed when the user attempts to create a variable without a name.",
                +	"LOGIC_COMPARE_HELPURL": "url - Information about comparisons.",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "tooltip - Describes the equals (=) block.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "tooltip - Describes the not equals (≠) block.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "tooltip - Describes the less than (<) block.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "tooltip - Describes the less than or equals (≤) block.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "tooltip - Describes the greater than (>) block.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "tooltip - Describes the greater than or equals (≥) block.",
                +	"LOGIC_OPERATION_HELPURL": "url - Information about the Boolean conjunction ('and') and disjunction ('or') operators.  Consider using the translation of [https://en.wikipedia.org/wiki/Boolean_logic https://en.wikipedia.org/wiki/Boolean_logic], if it exists in your language.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].",
                +	"LOGIC_OPERATION_AND": "block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}}",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].",
                +	"LOGIC_OPERATION_OR": "block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].\n{{Identical|Or}}",
                +	"LOGIC_NEGATE_HELPURL": "url - Information about logical negation.  The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language.",
                +	"LOGIC_NEGATE_TITLE": "block text - This is a unary operator that returns ''false'' when the input is ''true'', and ''true'' when the input is ''false''. \n\nParameters:\n* %1 - the input (which should be either the value 'true' or 'false')",
                +	"LOGIC_NEGATE_TOOLTIP": "tooltip - See [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation].",
                +	"LOGIC_BOOLEAN_HELPURL": "url - Information about the logic values ''true'' and ''false''.  Consider using the translation of [https://en.wikipedia.org/wiki/Truth_value https://en.wikipedia.org/wiki/Truth_value] if it exists in your language.",
                +	"LOGIC_BOOLEAN_TRUE": "block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''true''.\n{{Identical|True}}",
                +	"LOGIC_BOOLEAN_FALSE": "block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''false''.\n{{Identical|False}}",
                +	"LOGIC_BOOLEAN_TOOLTIP": "tooltip - Indicates that the block returns either of the two possible [https://en.wikipedia.org/wiki/Truth_value logical values].",
                +	"LOGIC_NULL_HELPURL": "url - Provide a link to the translation of [https://en.wikipedia.org/wiki/Nullable_type https://en.wikipedia.org/wiki/Nullable_type], if it exists in your language; otherwise, do not worry about translating this advanced concept.",
                +	"LOGIC_NULL": "block text - In computer languages, ''null'' is a special value that indicates that no value has been set.  You may use your language's word for 'nothing' or 'invalid'.\n{{Identical|Null}}",
                +	"LOGIC_NULL_TOOLTIP": "tooltip - This should use the word from the previous message.",
                +	"LOGIC_TERNARY_HELPURL": "url - Describes the programming language operator known as the ''ternary'' or ''conditional'' operator.  It is recommended that you use the translation of [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:] if it exists.",
                +	"LOGIC_TERNARY_CONDITION": "block input text - Label for the input whose value determines which of the other two inputs is returned.  In some programming languages, this is called a ''''predicate''''.",
                +	"LOGIC_TERNARY_IF_TRUE": "block input text - Indicates that the following input should be returned (used as output) if the test input is true.  Remember to try to keep block text terse (short).",
                +	"LOGIC_TERNARY_IF_FALSE": "block input text - Indicates that the following input should be returned (used as output) if the test input is false.",
                +	"LOGIC_TERNARY_TOOLTIP": "tooltip - See [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:].",
                +	"MATH_NUMBER_HELPURL": "url - Information about (real) numbers.",
                +	"MATH_NUMBER_TOOLTIP": "tooltip - Any positive or negative number, not necessarily an integer.",
                +	"MATH_ADDITION_SYMBOL": "{{optional}}\nmath - The symbol for the binary operation addition.",
                +	"MATH_SUBTRACTION_SYMBOL": "{{optional}}\nmath - The symbol for the binary operation indicating that the right operand should be subtracted from the left operand.",
                +	"MATH_DIVISION_SYMBOL": "{{optional}}\nmath - The binary operation indicating that the left operand should be divided by the right operand.",
                +	"MATH_MULTIPLICATION_SYMBOL": "{{optional}}\nmath - The symbol for the binary operation multiplication.",
                +	"MATH_POWER_SYMBOL": "{{optional}}\nmath - The symbol for the binary operation exponentiation.  Specifically, if the value of the left operand is L and the value of the right operand (the exponent) is R, multiply L by itself R times.  (Fractional and negative exponents are also legal.)",
                +	"MATH_TRIG_SIN": "math - The short name of the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].",
                +	"MATH_TRIG_COS": "math - The short name of the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].",
                +	"MATH_TRIG_TAN": "math - The short name of the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].",
                +	"MATH_TRIG_ASIN": "math - The short name of the ''inverse of'' the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].",
                +	"MATH_TRIG_ACOS": "math - The short name of the ''inverse of'' the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].",
                +	"MATH_TRIG_ATAN": "math - The short name of the ''inverse of'' the trigonometric function [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].",
                +	"MATH_ARITHMETIC_HELPURL": "url - Information about addition, subtraction, multiplication, division, and exponentiation.",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "tooltip - See [https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition].",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "tooltip - See [https://en.wikipedia.org/wiki/Subtraction https://en.wikipedia.org/wiki/Subtraction].",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "tooltip - See [https://en.wikipedia.org/wiki/Multiplication https://en.wikipedia.org/wiki/Multiplication].",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "tooltip - See [https://en.wikipedia.org/wiki/Division_(mathematics) https://en.wikipedia.org/wiki/Division_(mathematics)].",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "tooltip - See [https://en.wikipedia.org/wiki/Exponentiation https://en.wikipedia.org/wiki/Exponentiation].",
                +	"MATH_SINGLE_HELPURL": "url - Information about the square root operation.",
                +	"MATH_SINGLE_OP_ROOT": "dropdown - This computes the positive [https://en.wikipedia.org/wiki/Square_root square root] of its input.  For example, the square root of 16 is 4.",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "tooltip - Please use the same term as in the previous message.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "dropdown - This leaves positive numeric inputs changed and inverts negative inputs.  For example, the absolute value of 5 is 5; the absolute value of -5 is also 5.  For more information, see [https://en.wikipedia.org/wiki/Absolute_value https://en.wikipedia.org/wiki/Absolute_value].",
                +	"MATH_SINGLE_TOOLTIP_ABS": "tooltip - Please use the same term as in the previous message.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "tooltip - Calculates '''0-n''', where '''n''' is the single numeric input.",
                +	"MATH_SINGLE_TOOLTIP_LN": "tooltip - Calculates the [https://en.wikipedia.org/wiki/Natural_logarithm|natural logarithm] of its single numeric input.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "tooltip - Calculates the [https://en.wikipedia.org/wiki/Common_logarithm common logarithm] of its single numeric input.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "tooltip - Multiplies [https://en.wikipedia.org/wiki/E_(mathematical_constant) e] by itself n times, where n is the single numeric input.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "tooltip - Multiplies 10 by itself n times, where n is the single numeric input.",
                +	"MATH_TRIG_HELPURL": "url - Information about the trigonometric functions sine, cosine, tangent, and their inverses (ideally using degrees, not radians).",
                +	"MATH_TRIG_TOOLTIP_SIN": "tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.",
                +	"MATH_TRIG_TOOLTIP_COS": "tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.",
                +	"MATH_TRIG_TOOLTIP_TAN": "tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent sine function], using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent cosine] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent tangent] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.",
                +	"MATH_CONSTANT_HELPURL": "url - Information about the mathematical constants Pi (π), e, the golden ratio (φ), √ 2, √ 1/2, and infinity (∞).",
                +	"MATH_CONSTANT_TOOLTIP": "tooltip - Provides the specified [https://en.wikipedia.org/wiki/Mathematical_constant mathematical constant].",
                +	"MATH_IS_EVEN": "dropdown - A number is '''even''' if it is a multiple of 2.  For example, 4 is even (yielding true), but 3 is not (false).",
                +	"MATH_IS_ODD": "dropdown - A number is '''odd''' if it is not a multiple of 2.  For example, 3 is odd (yielding true), but 4 is not (false).  The opposite of 'odd' is 'even'.",
                +	"MATH_IS_PRIME": "dropdown - A number is [https://en.wikipedia.org/wiki/Prime prime] if it cannot be evenly divided by any positive integers except for 1 and itself.  For example, 5 is prime, but 6 is not because 2 × 3 = 6.",
                +	"MATH_IS_WHOLE": "dropdown - A number is '''whole''' if it is an [https://en.wikipedia.org/wiki/Integer integer].  For example, 5 is whole, but 5.1 is not.",
                +	"MATH_IS_POSITIVE": "dropdown - A number is '''positive''' if it is greater than 0.  (0 is neither negative nor positive.)",
                +	"MATH_IS_NEGATIVE": "dropdown - A number is '''negative''' if it is less than 0.  (0 is neither negative nor positive.)",
                +	"MATH_IS_DIVISIBLE_BY": "dropdown - A number x is divisible by y if y goes into x evenly.  For example, 10 is divisible by 5, but 10 is not divisible by 3.",
                +	"MATH_IS_TOOLTIP": "tooltip - This block lets the user specify via a dropdown menu whether to check if the numeric input is even, odd, prime, whole, positive, negative, or divisible by a given value.",
                +	"MATH_CHANGE_HELPURL": "url - Information about incrementing (increasing the value of) a variable. For other languages, just use the translation of the Wikipedia page about addition ([https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition]).",
                +	"MATH_CHANGE_TITLE": "- As in: ''change'' [the value of variable] ''item'' ''by'' 1 (e.g., if the variable named 'item' had the value 5, change it to 6). %1 is a variable name. %2 is the amount of change.",
                +	"MATH_CHANGE_TOOLTIP": "tooltip - This updates the value of the variable by adding to it the following numeric input.\n\nParameters:\n* %1 - the name of the variable whose value should be increased.",
                +	"MATH_ROUND_HELPURL": "url - Information about how numbers are rounded to the nearest integer",
                +	"MATH_ROUND_TOOLTIP": "tooltip - See [https://en.wikipedia.org/wiki/Rounding https://en.wikipedia.org/wiki/Rounding].",
                +	"MATH_ROUND_OPERATOR_ROUND": "dropdown - This rounds its input to the nearest whole number.  For example, 3.4 is rounded to 3.",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "dropdown - This rounds its input up to the nearest whole number.  For example, if the input was 2.2, the result would be 3.",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "dropdown - This rounds its input down to the nearest whole number.  For example, if the input was 3.8, the result would be 3.",
                +	"MATH_ONLIST_HELPURL": "url - Information about applying a function to a list of numbers.  (We were unable to find such information in English.  Feel free to skip this and any other URLs that are difficult.)",
                +	"MATH_ONLIST_OPERATOR_SUM": "dropdown - This computes the sum of the numeric elements in the list.  For example, the sum of the list {1, 4} is 5.",
                +	"MATH_ONLIST_TOOLTIP_SUM": "tooltip - Please use the same term for 'sum' as in the previous message.",
                +	"MATH_ONLIST_OPERATOR_MIN": "dropdown - This finds the smallest (minimum) number in a list.  For example, the smallest number in the list [-5, 0, 3] is -5.",
                +	"MATH_ONLIST_TOOLTIP_MIN": "tooltip - Please use the same term for 'min' or 'minimum' as in the previous message.",
                +	"MATH_ONLIST_OPERATOR_MAX": "dropdown - This finds the largest (maximum) number in a list.  For example, the largest number in the list [-5, 0, 3] is 3.",
                +	"MATH_ONLIST_TOOLTIP_MAX": "tooltip",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "dropdown - This adds up all of the numbers in a list and divides the sum by the number of elements in the list.  For example, the [https://en.wikipedia.org/wiki/Arithmetic_mean average] of the list [1, 2, 3, 4] is 2.5 (10/4).",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "tooltip - See [https://en.wikipedia.org/wiki/Arithmetic_mean https://en.wikipedia.org/wiki/Arithmetic_mean] for more informatin.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "dropdown - This finds the [https://en.wikipedia.org/wiki/Median median] of the numeric values in a list.  For example, the median of the list {1, 2, 7, 12, 13} is 7.",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "tooltip - See [https://en.wikipedia.org/wiki/Median median https://en.wikipedia.org/wiki/Median median] for more information.",
                +	"MATH_ONLIST_OPERATOR_MODE": "dropdown - This finds the most common numbers ([https://en.wikipedia.org/wiki/Mode_(statistics) modes]) in a list.  For example, the modes of the list {1, 3, 9, 3, 9}  are {3, 9}.",
                +	"MATH_ONLIST_TOOLTIP_MODE": "tooltip - See [https://en.wikipedia.org/wiki/Mode_(statistics) https://en.wikipedia.org/wiki/Mode_(statistics)] for more information.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "dropdown - This finds the [https://en.wikipedia.org/wiki/Standard_deviation standard deviation] of the numeric values in a list.",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "tooltip - See [https://en.wikipedia.org/wiki/Standard_deviation https://en.wikipedia.org/wiki/Standard_deviation] for more information.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "dropdown - This choose an element at random from a list.  Each element is chosen with equal probability.",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "tooltip - Please use same term for 'random' as in previous entry.",
                +	"MATH_MODULO_HELPURL": "url - information about the modulo (remainder) operation.",
                +	"MATH_MODULO_TITLE": "block text - Title of block providing the remainder when dividing the first numerical input by the second.  For example, the remainder of 10 divided by 3 is 1.\n\nParameters:\n* %1 - the dividend (10, in our example)\n* %2 - the divisor (3 in our example).",
                +	"MATH_MODULO_TOOLTIP": "tooltip - For example, the remainder of 10 divided by 3 is 1.",
                +	"MATH_CONSTRAIN_HELPURL": "url - Information about constraining a numeric value to be in a specific range.  (The English URL is not ideal.  Recall that translating URLs is the lowest priority.)",
                +	"MATH_CONSTRAIN_TITLE": "block text - The title of the block that '''constrain'''s (forces) a number to be in a given range. For example, if the number 150 is constrained to be between 5 and 100, the result will be 100. \n\nParameters:\n* %1 - the value to constrain (e.g., 150)\n* %2 - the minimum value (e.g., 5)\n* %3 - the maximum value (e.g., 100).",
                +	"MATH_CONSTRAIN_TOOLTIP": "tooltip - This compares a number ''x'' to a low value ''L'' and a high value ''H''.  If ''x'' is less then ''L'', the result is ''L''.  If ''x'' is greater than ''H'', the result is ''H''.  Otherwise, the result is ''x''.",
                +	"MATH_RANDOM_INT_HELPURL": "url - Information about how computers generate random numbers.",
                +	"MATH_RANDOM_INT_TITLE": "block text - The title of the block that generates a random integer (whole number) in the specified range.  For example, if the range is from 5 to 7, this returns 5, 6, or 7 with equal likelihood. %1 is a placeholder for the lower number, %2 is the placeholder for the larger number.",
                +	"MATH_RANDOM_INT_TOOLTIP": "tooltip - Return a random integer between two values specified as inputs.  For example, if one input was 7 and another 9, any of the numbers 7, 8, or 9 could be produced.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "url - Information about how computers generate random numbers (specifically, numbers in the range from 0 to just below 1).",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "block text - The title of the block that generates a random number greater than or equal to 0 and less than 1.",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "tooltip - Return a random fraction between 0 and 1.  The value may be equal to 0 but must be less than 1.",
                +	"TEXT_TEXT_HELPURL": "url - Information about how computers represent text (sometimes referred to as ''string''s).",
                +	"TEXT_TEXT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text https://github.com/google/blockly/wiki/Text].",
                +	"TEXT_JOIN_HELPURL": "url - Information on concatenating/appending pieces of text.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation].",
                +	"TEXT_JOIN_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation create text with] for more information.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "block text - This is shown when the programmer wants to change the number of pieces of text being joined together.  See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.\n{{Identical|Join}}",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.",
                +	"TEXT_APPEND_HELPURL": "url - This and the other text-related URLs are going to be hard to translate.  As always, it is okay to leave untranslated or paste in the English-language URL.  For these URLs, you might also consider a general URL about how computers represent text (such as the translation of [https://en.wikipedia.org/wiki/String_(computer_science) this Wikipedia page]).",
                +	"TEXT_APPEND_TITLE": "block input text - Message that the variable name at %1 will have the item at %2 appended to it. [[File:blockly-append-text.png]]",
                +	"TEXT_APPEND_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#text-modification https://github.com/google/blockly/wiki/Text#text-modification] for more information.\n\nParameters:\n* %1 - the name of the variable to which text should be appended",
                +	"TEXT_LENGTH_HELPURL": "url - Information about text on computers (usually referred to as 'strings').",
                +	"TEXT_LENGTH_TITLE": "block text - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length]. \n\nParameters:\n* %1 - the piece of text to take the length of",
                +	"TEXT_LENGTH_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length].",
                +	"TEXT_ISEMPTY_HELPURL": "url - Information about empty pieces of text on computers (usually referred to as 'empty strings').",
                +	"TEXT_ISEMPTY_TITLE": "block text - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text]. \n\nParameters:\n* %1 - the piece of text to test for emptiness",
                +	"TEXT_ISEMPTY_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text].",
                +	"TEXT_INDEXOF_HELPURL": "url - Information about finding a character in a piece of text.",
                +	"TEXT_INDEXOF_TOOLTIP": "tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode. See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text].",
                +	"TEXT_INDEXOF_TITLE": "block text - Title of blocks allowing users to find text.  See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text]. [[File:Blockly-find-text.png]]. In English the expanded message is 'in text %1 find (first|last) occurance of text %3' where %1 and %3 are added by the user. See TEXT_INDEXOF_OPERATOR_FIRST and TEXT_INDEXOF_OPERATOR_LAST for the dropdown text that replaces %2.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text]. [[File:Blockly-find-text.png]].",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text].  This would replace 'find first occurrence of text' below.  (For more information on how common text is factored out of dropdown menus, see [https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus)].) [[File:Blockly-find-text.png]].",
                +	"TEXT_CHARAT_HELPURL": "url - Information about extracting characters (letters, number, symbols, etc.) from text.",
                +	"TEXT_CHARAT_TITLE": "block text - Text for a block to extract a letter (or number, punctuation character, etc.) from a string, as shown below. %1 is added by the user and %2 is replaced by a dropdown of options, possibly followed by another user supplied string. TEXT_CHARAT_TAIL is then added to the end.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_FROM_START": "dropdown - Indicates that the letter (or number, punctuation character, etc.) with the specified index should be obtained from the preceding piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_FROM_END": "block text - Indicates that the letter (or number, punctuation character, etc.) with the specified index from the end of a given piece of text should be obtained. See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_FIRST": "block text - Indicates that the first letter of the following piece of text should be retrieved.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_LAST": "block text - Indicates that the last letter (or number, punctuation mark, etc.) of the following piece of text should be retrieved.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_RANDOM": "block text - Indicates that any letter (or number, punctuation mark, etc.) in the following piece of text should be randomly selected.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_TAIL": "block text - Text that goes after the rightmost block/dropdown when getting a single letter from a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/index.html#3m23km these blocks] or shown below.  For most languages, this will be blank. [[File:Blockly-text-get.png]]",
                +	"TEXT_CHARAT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].",
                +	"TEXT_GET_SUBSTRING_HELPURL": "url - Information about extracting characters from text.  Reminder: urls are the lowest priority translations.  Feel free to skip.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "block text - Precedes a piece of text from which a portion should be extracted. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "dropdown - Indicates that the following number specifies the position (relative to the start position) of the beginning of the region of text that should be obtained from the preceding piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "dropdown - Indicates that the following number specifies the position (relative to the end position) of the beginning of the region of text that should be obtained from the preceding piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. Note: If {{msg-blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will automatically appear ''after'' this and any other [https://translatewiki.net/wiki/Translating:Blockly#Ordinal_numbers ordinal numbers] on this block. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "block text - Indicates that a region starting with the first letter of the preceding piece of text should be extracted.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "dropdown - Indicates that the following number specifies the position (relative to the start position) of the end of the region of text that should be obtained from the preceding piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "dropdown - Indicates that the following number specifies the position (relative to the end position) of the end of the region of text that should be obtained from the preceding piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_END_LAST": "block text - Indicates that a region ending with the last letter of the preceding piece of text should be extracted.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text]. [[File:Blockly-get-substring.png]]",
                +	"TEXT_GET_SUBSTRING_TAIL": "block text - Text that should go after the rightmost block/dropdown when [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text extracting a region of text].  In most languages, this will be the empty string. [[File:Blockly-get-substring.png]]",
                +	"TEXT_CHANGECASE_HELPURL": "url - Information about the case of letters (upper-case and lower-case).",
                +	"TEXT_CHANGECASE_TOOLTIP": "tooltip - Describes a block to adjust the case of letters.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "block text - Indicates that all of the letters in the following piece of text should be capitalized.  If your language does not use case, you may indicate that this is not applicable to your language.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "block text - Indicates that all of the letters in the following piece of text should be converted to lower-case.  If your language does not use case, you may indicate that this is not applicable to your language.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "block text - Indicates that the first letter of each of the following words should be capitalized and the rest converted to lower-case.  If your language does not use case, you may indicate that this is not applicable to your language.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].",
                +	"TEXT_TRIM_HELPURL": "url - Information about trimming (removing) text off the beginning and ends of pieces of text.",
                +	"TEXT_TRIM_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].",
                +	"TEXT_TRIM_OPERATOR_BOTH": "dropdown - Removes spaces from the beginning and end of a piece of text.  See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].  Note that neither this nor the other options modify the original piece of text (that follows); the block just returns a version of the text without the specified spaces.",
                +	"TEXT_TRIM_OPERATOR_LEFT": "dropdown - Removes spaces from the beginning of a piece of text.  See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces https://github.com/google/blockly/wiki/Text#trimming-removing-spaces]. Note that in right-to-left scripts, this will remove spaces from the right side.",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "dropdown - Removes spaces from the end of a piece of text.  See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces https://github.com/google/blockly/wiki/Text#trimming-removing-spaces]. Note that in right-to-left scripts, this will remove spaces from the left side.",
                +	"TEXT_PRINT_HELPURL": "url - Information about displaying text on computers.",
                +	"TEXT_PRINT_TITLE": "block text - Display the input on the screen.  See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text]. \n\nParameters:\n* %1 - the value to print",
                +	"TEXT_PRINT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text].",
                +	"TEXT_PROMPT_HELPURL": "url - Information about getting text from users.",
                +	"TEXT_PROMPT_TYPE_TEXT": "dropdown - Specifies that a piece of text should be requested from the user with the following message.  See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text].",
                +	"TEXT_PROMPT_TYPE_NUMBER": "dropdown - Specifies that a number should be requested from the user with the following message.  See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text].",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "dropdown - Precedes the message with which the user should be prompted for a number.  See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text].",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "dropdown - Precedes the message with which the user should be prompted for some text. See [https://github.com/google/blockly/wiki/Text#printing-text https://github.com/google/blockly/wiki/Text#printing-text].",
                +	"TEXT_COUNT_MESSAGE0": "block text - Title of a block that counts the number of instances of a smaller pattern (%1) inside a longer string (%2).",
                +	"TEXT_COUNT_HELPURL": "url - Information about counting how many times a string appears in another string.",
                +	"TEXT_COUNT_TOOLTIP": "tooltip - Short description of a block that counts how many times some text occurs within some other text.",
                +	"TEXT_REPLACE_MESSAGE0": "block text - Title of a block that returns a copy of text (%3) with all instances of some smaller text (%1) replaced with other text (%2).",
                +	"TEXT_REPLACE_HELPURL": "url - Information about replacing each copy text (or string, in computer lingo) with other text.",
                +	"TEXT_REPLACE_TOOLTIP": "tooltip - Short description of a block that replaces copies of text in a large text with other text.",
                +	"TEXT_REVERSE_MESSAGE0": "block text - Title of block that returns a copy of text (%1) with the order of letters and characters reversed.",
                +	"TEXT_REVERSE_HELPURL": "url - Information about reversing a letters/characters in text.",
                +	"TEXT_REVERSE_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text].",
                +	"LISTS_CREATE_EMPTY_HELPURL": "url - Information on empty lists.",
                +	"LISTS_CREATE_EMPTY_TITLE": "block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].",
                +	"LISTS_CREATE_WITH_HELPURL": "url - Information on building lists.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "block text - This appears in a sub-block when [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs changing the number of inputs in a ''''create list with'''' block].\n{{Identical|List}}",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].",
                +	"LISTS_REPEAT_HELPURL": "url - Information about [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].",
                +	"LISTS_REPEAT_TOOLTIP": "url - See [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].",
                +	"LISTS_REPEAT_TITLE": "block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with]. \n\nParameters:\n* %1 - the item (text) to be repeated\n* %2 - the number of times to repeat it",
                +	"LISTS_LENGTH_HELPURL": "url - Information about how the length of a list is computed (i.e., by the total number of elements, not the number of different elements).",
                +	"LISTS_LENGTH_TITLE": "block text - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of]. \n\nParameters:\n* %1 - the list whose length is desired",
                +	"LISTS_LENGTH_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of Blockly:Lists:length of].",
                +	"LISTS_ISEMPTY_HELPURL": "url - See [https://github.com/google/blockly/wiki/Lists#is-empty https://github.com/google/blockly/wiki/Lists#is-empty].",
                +	"LISTS_ISEMPTY_TITLE": "block text - See [https://github.com/google/blockly/wiki/Lists#is-empty https://github.com/google/blockly/wiki/Lists#is-empty]. \n\nParameters:\n* %1 - the list to test",
                +	"LISTS_ISEMPTY_TOOLTIP": "block tooltip - See [https://github.com/google/blockly/wiki/Lists#is-empty https://github.com/google/blockly/wiki/Lists#is-empty].",
                +	"LISTS_INLIST": "block text - Title of blocks operating on [https://github.com/google/blockly/wiki/Lists lists].",
                +	"LISTS_INDEX_OF_HELPURL": "url - See [https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list].",
                +	"LISTS_INDEX_OF_FIRST": "dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list Lists#finding-items-in-a-list]. [[File:Blockly-list-find.png]]",
                +	"LISTS_INDEX_OF_LAST": "dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list]. [[File:Blockly-list-find.png]]",
                +	"LISTS_INDEX_OF_TOOLTIP": "tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode.  See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list]. [[File:Blockly-list-find.png]]",
                +	"LISTS_GET_INDEX_GET": "dropdown - Indicates that the user wishes to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item get an item from a list] without removing it from the list.",
                +	"LISTS_GET_INDEX_GET_REMOVE": "dropdown - Indicates that the user wishes to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item get and remove an item from a list], as opposed to merely getting it without modifying the list.",
                +	"LISTS_GET_INDEX_REMOVE": "dropdown - Indicates that the user wishes to [https://github.com/google/blockly/wiki/Lists#removing-an-item remove an item from a list].\n{{Identical|Remove}}",
                +	"LISTS_GET_INDEX_FROM_START": "dropdown - Indicates that an index relative to the front of the list should be used to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item get and/or remove an item from a list].  Note: If {{msg-blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will automatically appear ''after'' this number (and any other ordinal numbers on this block). See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_GET_INDEX_FROM_END": "dropdown - Indicates that an index relative to the end of the list should be used to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item access an item in a list]. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_GET_INDEX_FIRST": "dropdown - Indicates that the '''first''' item should be [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list]. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_GET_INDEX_LAST": "dropdown - Indicates that the '''last''' item should be [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list]. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_GET_INDEX_RANDOM": "dropdown - Indicates that a '''random''' item should be [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list]. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_GET_INDEX_TAIL": "block text - Text that should go after the rightmost block/dropdown when [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessing an item from a list].  In most languages, this will be the empty string. [[File:Blockly-list-get-item.png]]",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "tooltip - Indicates the ordinal number that the first item in a list is referenced by.  %1 will be replaced by either '#0' or '#1' depending on the indexing mode.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "tooltip - Indicates the ordinal number that the last item in a list is referenced by.  %1 will be replaced by either '#0' or '#1' depending on the indexing mode.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.",
                +	"LISTS_SET_INDEX_HELPURL": "url - Information about putting items in lists.",
                +	"LISTS_SET_INDEX_SET": "block text - [https://github.com/google/blockly/wiki/Lists#in-list--set Replaces an item in a list]. [[File:Blockly-in-list-set-insert.png]]",
                +	"LISTS_SET_INDEX_INSERT": "block text - [https://github.com/google/blockly/wiki/Lists#in-list--insert-at Inserts an item into a list]. [[File:Blockly-in-list-set-insert.png]]",
                +	"LISTS_SET_INDEX_INPUT_TO": "block text - The word(s) after the position in the list and before the item to be set/inserted. [[File:Blockly-in-list-set-insert.png]]",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'set' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'set' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'set' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'set' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'insert' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'insert' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'insert' block).",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the 'get' block, the idea is the same for the 'insert' block).",
                +	"LISTS_GET_SUBLIST_HELPURL": "url - Information describing extracting a sublist from an existing list.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "dropdown - Indicates that an index relative to the front of the list should be used to specify the beginning of the range from which to [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist]. [[File:Blockly-get-sublist.png]] Note: If {{msg-blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will automatically appear ''after'' this number (and any other ordinal numbers on this block). See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly.",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "dropdown - Indicates that an index relative to the end of the list should be used to specify the beginning of the range from which to [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].",
                +	"LISTS_GET_SUBLIST_START_FIRST": "dropdown - Indicates that the [https://github.com/google/blockly/wiki/Lists#getting-a-sublist sublist to extract] should begin with the list's first item.",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "dropdown - Indicates that an index relative to the front of the list should be used to specify the end of the range from which to [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist]. [[File:Blockly-get-sublist.png]]",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "dropdown - Indicates that an index relative to the end of the list should be used to specify the end of the range from which to [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist]. [[File:Blockly-get-sublist.png]]",
                +	"LISTS_GET_SUBLIST_END_LAST": "dropdown - Indicates that the '''last''' item in the given list should be [https://github.com/google/blockly/wiki/Lists#getting-a-sublist the end of the selected sublist]. [[File:Blockly-get-sublist.png]]",
                +	"LISTS_GET_SUBLIST_TAIL": "block text - This appears in the rightmost position ('tail') of the sublist block, as described at [https://github.com/google/blockly/wiki/Lists#getting-a-sublist https://github.com/google/blockly/wiki/Lists#getting-a-sublist]. In English and most other languages, this is the empty string. [[File:Blockly-get-sublist.png]]",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-sublist https://github.com/google/blockly/wiki/Lists#getting-a-sublist] for more information. [[File:Blockly-get-sublist.png]]",
                +	"LISTS_SORT_HELPURL": "{{optional}}\nurl - Information describing sorting a list.",
                +	"LISTS_SORT_TITLE": "Sort as type %1 (numeric or alphabetic) in order %2 (ascending or descending) a list of items %3.\n{{Identical|Sort}}",
                +	"LISTS_SORT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Lists#sorting-a-list].",
                +	"LISTS_SORT_ORDER_ASCENDING": "sorting order or direction from low to high value for numeric, or A-Z for alphabetic.\n{{Identical|Ascending}}",
                +	"LISTS_SORT_ORDER_DESCENDING": "sorting order or direction from high to low value for numeric, or Z-A for alphabetic.\n{{Identical|Descending}}",
                +	"LISTS_SORT_TYPE_NUMERIC": "sort by treating each item as a number.",
                +	"LISTS_SORT_TYPE_TEXT": "sort by treating each item alphabetically, case-sensitive.",
                +	"LISTS_SORT_TYPE_IGNORECASE": "sort by treating each item alphabetically, ignoring differences in case.",
                +	"LISTS_SPLIT_HELPURL": "url - Information describing splitting text into a list, or joining a list into text.",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "dropdown - Indicates that text will be split up into a list (e.g. 'a-b-c' -> ['a', 'b', 'c']).",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "dropdown - Indicates that a list will be joined together to form text (e.g. ['a', 'b', 'c'] -> 'a-b-c').",
                +	"LISTS_SPLIT_WITH_DELIMITER": "block text - Prompts for a letter to be used as a separator when splitting or joining text.",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "tooltip - See [https://github.com/google/blockly/wiki/Lists#make-list-from-text https://github.com/google/blockly/wiki/Lists#make-list-from-text] for more information.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "tooltip - See [https://github.com/google/blockly/wiki/Lists#make-text-from-list https://github.com/google/blockly/wiki/Lists#make-text-from-list] for more information.",
                +	"LISTS_REVERSE_HELPURL": "url - Information describing reversing a list.",
                +	"LISTS_REVERSE_MESSAGE0": "block text - Title of block that returns a copy of a list (%1) with the order of items reversed.",
                +	"LISTS_REVERSE_TOOLTIP": "tooltip - Short description for a block that reverses a copy of a list.",
                +	"ORDINAL_NUMBER_SUFFIX": "grammar - Text that follows an ordinal number (a number that indicates position relative to other numbers).  In most languages, such text appears before the number, so this should be blank.  An exception is Hungarian. See [[Translating:Blockly#Ordinal_numbers]] for more information.",
                +	"VARIABLES_GET_HELPURL": "url - Information about ''variables'' in computer programming.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.",
                +	"VARIABLES_GET_TOOLTIP": "tooltip - This gets the value of the named variable without modifying it.",
                +	"VARIABLES_GET_CREATE_SET": "context menu - Selecting this creates a block to set (change) the value of this variable. \n\nParameters:\n* %1 - the name of the variable.",
                +	"VARIABLES_SET_HELPURL": "url - Information about ''variables'' in computer programming.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.",
                +	"VARIABLES_SET": "block text - Change the value of a mathematical variable: '''set [the value of] x to 7'''.\n\nParameters:\n* %1 - the name of the variable.\n* %2 - the value to be assigned.",
                +	"VARIABLES_SET_TOOLTIP": "tooltip - This initializes or changes the value of the named variable.",
                +	"VARIABLES_SET_CREATE_GET": "context menu - Selecting this creates a block to get (change) the value of this variable.\n\nParameters:\n* %1 - the name of the variable.",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that do not have return values.",
                +	"PROCEDURES_DEFNORETURN_TITLE": "block text - This precedes the name of the function when defining it.  See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#c84aoc this sample function definition].",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "default name - This acts as a placeholder for the name of a function on a function definition block, as shown on [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#w7cfju this block]. The user will replace it with the function's name.",
                +	"PROCEDURES_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's defiition block.  See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function with parameters].",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's caller block.  See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function with parameters].",
                +	"PROCEDURES_DEFNORETURN_DO": "block text - This appears next to the function's 'body', the blocks that should be run when the function is called, as shown in [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function definition].",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "tooltip",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Placeholder text that the user is encouraged to replace with a description of what their function does.",
                +	"PROCEDURES_DEFRETURN_HELPURL": "url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that have return values.",
                +	"PROCEDURES_DEFRETURN_RETURN": "block text - This imperative or infinite verb precedes the value that is used as the return value (output) of this function.  See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#6ot5y5 this sample function that returns a value].",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "tooltip",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Label for a checkbox that controls if statements are allowed in a function.",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "alert - The user has created a function with two parameters that have the same name.  Every parameter must have a different name.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "url - Information about calling [https://en.wikipedia.org/wiki/Subroutine functions] that do not return values.",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "tooltip - This block causes the body (blocks inside) of the named function definition to be run.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "url - Information about calling [https://en.wikipedia.org/wiki/Subroutine functions] that return values.",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "tooltip - This block causes the body (blocks inside) of the named function definition to be run.\n\nParameters:\n* %1 - the name of the function.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "block text - This text appears on a block in a window that appears when the user clicks on the plus sign or star on a function definition block.  It refers to the set of parameters (referred to by the simpler term 'inputs') to the function.  See [[Translating:Blockly#function_definitions]].\n{{Identical|Input}}",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "tooltip",
                +	"PROCEDURES_MUTATORARG_TITLE": "block text - This text appears on a block in a window that appears when the user clicks on the plus sign or star on a function definition block].  It appears on the block for adding an individual parameter (referred to by the simpler term 'inputs') to the function. See [[Translating:Blockly#function_definitions]].",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "tooltip",
                +	"PROCEDURES_HIGHLIGHT_DEF": "context menu - This appears on the context menu for function calls.  Selecting it causes the corresponding function definition to be highlighted (as shown at [[Translating:Blockly#context_menus]].",
                +	"PROCEDURES_CREATE_DO": "context menu - This appears on the context menu for function definitions. Selecting it creates a block to call the function.\n\nParameters:\n* %1 - the name of the function.\n{{Identical|Create}}",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "tooltip - If the first value is true, this causes the second value to be returned immediately from the enclosing function.",
                +	"PROCEDURES_IFRETURN_HELPURL": "{{optional}}\nurl - Information about guard clauses.",
                +	"PROCEDURES_IFRETURN_WARNING": "warning - This appears if the user tries to use this block outside of a function definition."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ro.json b/blockly/webif/static/blockly/msg/json/ro.json
                new file mode 100644
                index 000000000..058ff3c02
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ro.json
                @@ -0,0 +1,316 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Minisarm",
                +			"Ely en",
                +			"Hugbear",
                +			"아라",
                +			"Ykhwong",
                +			"Wintereu"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Astăzi",
                +	"DUPLICATE_BLOCK": "Duplicati",
                +	"ADD_COMMENT": "Adaugă un comentariu",
                +	"REMOVE_COMMENT": "Elimină comentariu",
                +	"EXTERNAL_INPUTS": "Intrări externe",
                +	"INLINE_INPUTS": "Intrări în linie",
                +	"DELETE_BLOCK": "Șterge Bloc",
                +	"DELETE_X_BLOCKS": "Ștergeți %1 Blocuri",
                +	"DELETE_ALL_BLOCKS": "Ștergi toate cele %1 (de) blocuri?",
                +	"COLLAPSE_BLOCK": "Restrange blocul",
                +	"COLLAPSE_ALL": "Restrange blocurile",
                +	"EXPAND_BLOCK": "Extinde bloc",
                +	"EXPAND_ALL": "Extinde blocuri",
                +	"DISABLE_BLOCK": "Dezactivaţi bloc",
                +	"ENABLE_BLOCK": "Permite bloc",
                +	"HELP": "Ajutor",
                +	"CHANGE_VALUE_TITLE": "Schimbaţi valoarea:",
                +	"RENAME_VARIABLE": "Redenumirea variabilei...",
                +	"RENAME_VARIABLE_TITLE": "Redenumeşte toate variabilele '%1' în:",
                +	"NEW_VARIABLE": "Variabilă nouă...",
                +	"NEW_VARIABLE_TITLE": "Noul nume de variabilă:",
                +	"COLOUR_PICKER_HELPURL": "https://ro.wikipedia.org/wiki/Culoare",
                +	"COLOUR_PICKER_TOOLTIP": "Alege o culoare din paleta de culori.",
                +	"COLOUR_RANDOM_TITLE": "culoare aleatorie",
                +	"COLOUR_RANDOM_TOOLTIP": "Alege o culoare la întâmplare.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "colorează cu",
                +	"COLOUR_RGB_RED": "roşu",
                +	"COLOUR_RGB_GREEN": "verde",
                +	"COLOUR_RGB_BLUE": "albastru",
                +	"COLOUR_RGB_TOOLTIP": "Creează o culoare cu suma specificată de roşu, verde şi albastru.  Toate valorile trebuie să fie între 0 şi 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "amestec",
                +	"COLOUR_BLEND_COLOUR1": "culoare 1",
                +	"COLOUR_BLEND_COLOUR2": "culoare 2",
                +	"COLOUR_BLEND_RATIO": "Raport",
                +	"COLOUR_BLEND_TOOLTIP": "Amestecă două culori cu un raport dat (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repetă de %1 ori",
                +	"CONTROLS_REPEAT_INPUT_DO": "fă",
                +	"CONTROLS_REPEAT_TOOLTIP": "Face unele afirmaţii de mai multe ori.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repetă în timp ce",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "Repetaţi până când",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "În timp ce o valoare este adevărat, atunci face unele declaraţii.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "În timp ce o valoare este adevărat, atunci face unele declaraţii.",
                +	"CONTROLS_FOR_TOOLTIP": "Cu variablia \"%1\" ia o valoare din numărul început la numărul final, numara in intervalul specificat, apoi face blocurile specificate.",
                +	"CONTROLS_FOR_TITLE": "numără cu %1 de la %2 la %3 prin %4",
                +	"CONTROLS_FOREACH_TITLE": "pentru fiecare element %1 în listă %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Pentru fiecare element din listă, setaţi variabila '%1' ca valoarea elementului, şi apoi faceţi unele declaraţii.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ieşi din bucla",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "continuă cu următoarea iterație a buclei",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Ieși din bucla care conţine.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sari peste restul aceastei bucle, şi continuă cu urmatoarea iteratie.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Avertisment: Acest bloc pote fi utilizat numai în interiorul unei bucle.",
                +	"CONTROLS_IF_TOOLTIP_1": "Dacă o valoare este adevărată, atunci fa unele declaraţii.",
                +	"CONTROLS_IF_TOOLTIP_2": "Dacă o valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, face al doilea bloc de declaraţii.",
                +	"CONTROLS_IF_TOOLTIP_3": "Dacă prima valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, dacă a doua valoare este adevărat, face al doilea bloc de declaraţii.",
                +	"CONTROLS_IF_TOOLTIP_4": "Dacă prima valoare este adevărat, atunci face primul bloc de declaraţii.  Altfel, dacă a doua valoare este adevărat, face al doilea bloc de declaraţii.  În cazul în care niciuna din  valorilor nu este adevărat, face ultimul bloc de declaraţii.",
                +	"CONTROLS_IF_MSG_IF": "dacă",
                +	"CONTROLS_IF_MSG_ELSEIF": "altfel dacă",
                +	"CONTROLS_IF_MSG_ELSE": "altfel",
                +	"CONTROLS_IF_IF_TOOLTIP": "Adaugă, elimină sau reordonează secţiuni pentru a reconfigura acest bloc if.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Adăugaţi o condiţie in blocul if.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Adauga o stare finala, cuprinde toata conditia din blocul if.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Returnează adevărat dacă ambele intrări sunt egale.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Returnează adevărat daca cele două intrări nu sunt egale.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Returnează adevărat dacă prima intrare este mai mică decât a doua intrare.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Returnează adevărat dacă prima intrare este mai mică sau egală cu a doua intrare.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Returnează adevărat dacă prima intrare este mai mare decât a doua intrare.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Returnează adevărat dacă prima intrare este mai mare sau egală cu a doua intrare.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Returnează adevărat daca ambele intrări sunt adevărate.",
                +	"LOGIC_OPERATION_AND": "şi",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Returnează adevărat dacă cel puţin una din intrări este adevărată.",
                +	"LOGIC_OPERATION_OR": "sau",
                +	"LOGIC_NEGATE_TITLE": "non %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returnează adevărat dacă intrarea este falsă.  Returnează fals dacă intrarea este adevărată.",
                +	"LOGIC_BOOLEAN_TRUE": "adevărat",
                +	"LOGIC_BOOLEAN_FALSE": "fals",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returnează adevărat sau fals.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "nul",
                +	"LOGIC_NULL_TOOLTIP": "returnează nul.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "dacă este adevărat",
                +	"LOGIC_TERNARY_IF_FALSE": "dacă este fals",
                +	"LOGIC_TERNARY_TOOLTIP": "Verifică condiţia din \"test\". Dacă condiţia este adevărată, returnează valoarea \"în cazul în care adevărat\"; în caz contrar întoarce valoarea \"în cazul în care e fals\".",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Un număr.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tg",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "arccos",
                +	"MATH_TRIG_ATAN": "arctg",
                +	"MATH_ARITHMETIC_HELPURL": "https://ro.wikipedia.org/wiki/Aritmetic%C4%83",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Returnează suma a două numere.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Returneaza diferenţa dintre cele două numere.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Returnează produsul celor două numere.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Returnează câtul celor două numere.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Returneaza numărul rezultat prin ridicarea primului număr la puterea celui de-al doilea.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "rădăcina pătrată",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Returnează rădăcina pătrată a unui număr.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolută",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Returnează valoarea absolută a unui număr.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Returnează negaţia unui număr.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Întoarce logaritmul natural al unui număr.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Returnează logaritmul în baza 10 a unui număr.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Returnează e la puterea unui număr.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Returnează 10 la puterea unui număr.",
                +	"MATH_TRIG_HELPURL": "https://ro.wikipedia.org/wiki/Funcții_trigonometrice",
                +	"MATH_TRIG_TOOLTIP_SIN": "Întoarce cosinusul unui grad (nu radianul).",
                +	"MATH_TRIG_TOOLTIP_COS": "Întoarce cosinusul unui grad (nu radianul).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Întoarce tangenta unui grad (nu radianul).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Returnează arcsinusul unui număr.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Returnează arccosinusul unui număr.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Returnează arctangenta unui număr.",
                +	"MATH_CONSTANT_HELPURL": "https://ro.wikipedia.org/wiki/Constant%C4%83_matematic%C4%83",
                +	"MATH_CONSTANT_TOOLTIP": "Întoarcă una din constantele comune: π (3.141...), e (2.718...), φ (1,618...), sqrt(2) (1.414...), sqrt(½) (0.707...) sau ∞ (infinitate).",
                +	"MATH_IS_EVEN": "este par",
                +	"MATH_IS_ODD": "este impar",
                +	"MATH_IS_PRIME": "este prim",
                +	"MATH_IS_WHOLE": "este întreg",
                +	"MATH_IS_POSITIVE": "este pozitiv",
                +	"MATH_IS_NEGATIVE": "este negativ",
                +	"MATH_IS_DIVISIBLE_BY": "este divizibil cu",
                +	"MATH_IS_TOOLTIP": "Verifică dacă un număr este un par, impar, prim, întreg, pozitiv, negativ, sau dacă este divizibil cu un anumit număr.  Returnează true sau false.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "schimbă %1 de %2",
                +	"MATH_CHANGE_TOOLTIP": "Adaugă un număr variabilei '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Rotunjirea unui număr în sus sau în jos.",
                +	"MATH_ROUND_OPERATOR_ROUND": "rotund",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "rotunjește în sus",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "rotunjit",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma listei",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Returnează suma tuturor numerelor din lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimul listei",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Returnează cel mai mic număr din listă.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maximul listei",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Întoarce cel mai mare număr din listă.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "media listei",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Întoarce media (aritmetică) a valorilor numerice în listă.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "media listei",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Întoarce numărul median în listă.",
                +	"MATH_ONLIST_OPERATOR_MODE": "moduri de listă",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Returnează o listă cu cel(e) mai frecvent(e) element(e) din listă.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviația standard a listei",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Întoarce deviația standard a listei.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "element aleatoriu din lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Returnează un element aleatoriu din listă.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "restul la %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Întoarce restul din împărţirea celor două numere.",
                +	"MATH_CONSTRAIN_TITLE": "constrânge %1 redus %2 ridicat %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Constrânge un număr să fie între limitele specificate (inclusiv).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "un număr întreg aleator de la %1 la %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Returnează un număr întreg aleator aflat între cele două limite specificate, inclusiv.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fracții aleatorii",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Returnează o fracţie aleatoare între 0.0 (inclusiv) si 1.0 (exclusiv).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "O literă, cuvânt sau linie de text.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "crează text cu",
                +	"TEXT_JOIN_TOOLTIP": "Creaţi o bucată de text prin unirea oricărui număr de elemente.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "alăturaţi-vă",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Adaugă, elimină sau reordonează secțiuni ca să reconfigureze blocul text.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Adaugă un element în text.",
                +	"TEXT_APPEND_TOOLTIP": "Adăugaţi text la variabila '%1'.",
                +	"TEXT_LENGTH_TITLE": "lungime de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Returnează numărul de litere (inclusiv spaţiile) în textul furnizat.",
                +	"TEXT_ISEMPTY_TITLE": "%1 este gol",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returnează adevărat dacă textul furnizat este gol.",
                +	"TEXT_INDEXOF_TOOLTIP": "Returnează indicele primei/ultimei apariţii din primul text în al doilea text.  Returnează %1 dacă textul nu este găsit.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "găseşte prima apariţie a textului",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "găseşte ultima apariţie a textului",
                +	"TEXT_CHARAT_FROM_START": "obtine litera #",
                +	"TEXT_CHARAT_FROM_END": "obţine litera # de la sfârșit",
                +	"TEXT_CHARAT_FIRST": "obţine prima litera",
                +	"TEXT_CHARAT_LAST": "obţine o litera oarecare",
                +	"TEXT_CHARAT_RANDOM": "obtine o litera oarecare",
                +	"TEXT_CHARAT_TOOLTIP": "Returnează litera la poziția specificată.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returnează o anumită parte din text.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "în text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "obține subșir de la litera #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "obține un subșir de la litera # de la sfârșit",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "obţine un subșir de la prima literă",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "la litera #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "la litera # de la sfarsit",
                +	"TEXT_GET_SUBSTRING_END_LAST": "la ultima literă",
                +	"TEXT_CHANGECASE_TOOLTIP": "Întoarce o copie a textului într-un caz diferit.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "la MAJUSCULE",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "la litere mici",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "către Titlul de caz",
                +	"TEXT_TRIM_TOOLTIP": "Returnează o copie a textului fără spațiile de la unul sau ambele capete.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "taie spațiile de pe ambele părți ale",
                +	"TEXT_TRIM_OPERATOR_LEFT": "tăiaţi spațiile din partea stângă a",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "taie spațiile din partea dreaptă a",
                +	"TEXT_PRINT_TITLE": "imprimare %1",
                +	"TEXT_PRINT_TOOLTIP": "Afișează textul specificat, numărul sau altă valoare.",
                +	"TEXT_PROMPT_TYPE_TEXT": "solicită pentru text cu mesaj",
                +	"TEXT_PROMPT_TYPE_NUMBER": "solicită pentru număr cu mesaj",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Solicită utilizatorul pentru un număr.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Solicită utilizatorul pentru text.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "creează listă goală",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Returnează o listă, de lungime 0, care nu conţine înregistrări de date",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Creaţi o listă cu orice număr de elemente.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "creează listă cu",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "listă",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Adaugă, elimină sau reordonează secţiuni ca să reconfiguraţi aceste blocuri de listă.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Adăugaţi un element la listă.",
                +	"LISTS_REPEAT_TOOLTIP": "Creează o listă alcătuită dintr-o anumită valoare repetată de numărul specificat de ori.",
                +	"LISTS_REPEAT_TITLE": "creaza lista cu %1 elemente repetate de %2 ori",
                +	"LISTS_LENGTH_TITLE": "lungime de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Returnează lungimea unei liste.",
                +	"LISTS_ISEMPTY_TITLE": "%1 este gol",
                +	"LISTS_ISEMPTY_TOOLTIP": "Returnează adevărat dacă lista este goală.",
                +	"LISTS_INLIST": "în listă",
                +	"LISTS_INDEX_OF_FIRST": "Găseşte prima apariţie a elementului",
                +	"LISTS_INDEX_OF_LAST": "găseşte ultima apariţie a elementului",
                +	"LISTS_INDEX_OF_TOOLTIP": "Revine la indexul de la prima/ultima apariție a elementului din listă. Returnează %1 dacă elementul nu este găsit.",
                +	"LISTS_GET_INDEX_GET": "obţine",
                +	"LISTS_GET_INDEX_GET_REMOVE": "obţine şi elimină",
                +	"LISTS_GET_INDEX_REMOVE": "elimină",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# de la sfârșit",
                +	"LISTS_GET_INDEX_FIRST": "primul",
                +	"LISTS_GET_INDEX_LAST": "ultimul",
                +	"LISTS_GET_INDEX_RANDOM": "aleator",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 este primul element.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 este ultimul element.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Returneaza elementul la poziţia specificată într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Returnează primul element dintr-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Returnează ultimul element într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Returneaza un element aleatoriu într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Elimină şi returneaza elementul la poziţia specificată într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Elimină şi returnează primul element într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Elimină şi returnează ultimul element într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Elimină şi returnează un element aleatoriu într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Elimină elementul la poziţia specificată într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Elimină primul element într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Elimină ultimul element într-o listă.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Elimină un element aleatoriu într-o listă.",
                +	"LISTS_SET_INDEX_SET": "seteaza",
                +	"LISTS_SET_INDEX_INSERT": "introduceţi la",
                +	"LISTS_SET_INDEX_INPUT_TO": "ca",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Setează elementul la poziţia specificată într-o listă.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Setează primul element într-o listă.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Setează ultimul element într-o listă.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Setează un element aleator într-o listă.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserează elementul la poziţia specificată într-o listă.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Inserează elementul la începutul unei liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Adăugă elementul la sfârşitul unei liste.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Inserează elementul aleatoriu într-o listă.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "obţine sub-lista de la #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "obţine sub-lista de la # de la sfârşitul",
                +	"LISTS_GET_SUBLIST_START_FIRST": "obţine sub-lista de la primul",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "la #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "la # de la sfarsit",
                +	"LISTS_GET_SUBLIST_END_LAST": "la ultima",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Creează o copie a porţiunii specificate dintr-o listă.",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "convertește textul în listă",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "convertește lista în text",
                +	"LISTS_SPLIT_WITH_DELIMITER": "cu separatorul",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Împarte textul într-o listă de texte, despărțite prin fiecare separator",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Concatenează o listă de texte (alternate cu separatorul) într-un text unic",
                +	"VARIABLES_GET_TOOLTIP": "Returnează valoarea acestei variabile.",
                +	"VARIABLES_GET_CREATE_SET": "Crează 'set %1'",
                +	"VARIABLES_SET": "seteaza %1 la %2",
                +	"VARIABLES_SET_TOOLTIP": "Setează această variabilă sa fie egală la intrare.",
                +	"VARIABLES_SET_CREATE_GET": "Crează 'get %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "la",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "fă ceva",
                +	"PROCEDURES_BEFORE_PARAMS": "cu:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "cu:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Crează o funcţie cu nici o ieşire.",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://ro.wikipedia.org/wiki/Subrutină",
                +	"PROCEDURES_DEFRETURN_RETURN": "returnează",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Creează o funcţie cu o ieşire.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permite declarațiile",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Atenţie: Această funcţie are parametri duplicaţi.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Executați funcția '%1 'definită de utilizator.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Executați funcția '%1 'definită de utilizator şi folosiţi producţia sa.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "intrări",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Adăugă, șterge sau reordonează parametrii de intrare ai acestei funcții.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nume de intrare:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Adaugă un parametru de intrare pentru funcție.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Evidenţiază definiţia funcţiei",
                +	"PROCEDURES_CREATE_DO": "Creaţi '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Dacă o valoare este adevărată, atunci returnează valoarea a doua.",
                +	"PROCEDURES_IFRETURN_WARNING": "Avertisment: Acest bloc poate fi utilizat numai în definiţia unei funcţii."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/ru.json b/blockly/webif/static/blockly/msg/json/ru.json
                new file mode 100644
                index 000000000..d9bafb36b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ru.json
                @@ -0,0 +1,351 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"MS",
                +			"Okras",
                +			"RedFox",
                +			"Mailman",
                +			"Silovan",
                +			"Redredsonia",
                +			"Facenapalm",
                +			"Helpau"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "элемент",
                +	"TODAY": "Сегодня",
                +	"DUPLICATE_BLOCK": "Дублировать",
                +	"ADD_COMMENT": "Добавить комментарий",
                +	"REMOVE_COMMENT": "Удалить комментарий",
                +	"EXTERNAL_INPUTS": "Вставки снаружи",
                +	"INLINE_INPUTS": "Вставки внутри",
                +	"DELETE_BLOCK": "Удалить блок",
                +	"DELETE_X_BLOCKS": "Удалить %1 блоков",
                +	"DELETE_ALL_BLOCKS": "Удалить все блоки (%1)?",
                +	"CLEAN_UP": "Убрать блоки",
                +	"COLLAPSE_BLOCK": "Свернуть блок",
                +	"COLLAPSE_ALL": "Свернуть блоки",
                +	"EXPAND_BLOCK": "Развернуть блок",
                +	"EXPAND_ALL": "Развернуть блоки",
                +	"DISABLE_BLOCK": "Отключить блок",
                +	"ENABLE_BLOCK": "Включить блок",
                +	"HELP": "Справка",
                +	"UNDO": "Отменить",
                +	"REDO": "Повторить",
                +	"CHANGE_VALUE_TITLE": "Измените значение:",
                +	"RENAME_VARIABLE": "Переименовать переменную…",
                +	"RENAME_VARIABLE_TITLE": "Переименовать все переменные '%1' в:",
                +	"NEW_VARIABLE": "Создать переменную…",
                +	"NEW_VARIABLE_TITLE": "Имя новой переменной:",
                +	"VARIABLE_ALREADY_EXISTS": "Переменная с именем '%1' уже существует.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "Название переменной '%1' уже используется другой переменной типа '%2'.",
                +	"PROCEDURE_ALREADY_EXISTS": "Процедура с именем '%1' уже существует.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Удалить %1 использований переменной '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Невозможно удалить переменную '%1', поскольку она является частью определения функции '%2'",
                +	"DELETE_VARIABLE": "Удалить переменную '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://ru.wikipedia.org/wiki/Цвет",
                +	"COLOUR_PICKER_TOOLTIP": "Выберите цвет из палитры.",
                +	"COLOUR_RANDOM_TITLE": "случайный цвет",
                +	"COLOUR_RANDOM_TOOLTIP": "Выбирает цвет случайным образом.",
                +	"COLOUR_RGB_TITLE": "цвет из",
                +	"COLOUR_RGB_RED": "красного",
                +	"COLOUR_RGB_GREEN": "зелёного",
                +	"COLOUR_RGB_BLUE": "синего",
                +	"COLOUR_RGB_TOOLTIP": "Создаёт цвет с указанной пропорцией  красного, зеленого и синего.  Все значения должны быть между 0 и 100.",
                +	"COLOUR_BLEND_TITLE": "смешать",
                +	"COLOUR_BLEND_COLOUR1": "цвет 1",
                +	"COLOUR_BLEND_COLOUR2": "цвет 2",
                +	"COLOUR_BLEND_RATIO": "доля цвета 1",
                +	"COLOUR_BLEND_TOOLTIP": "Смешивает два цвета в заданном соотношении (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://ru.wikipedia.org/wiki/Цикл_(программирование)",
                +	"CONTROLS_REPEAT_TITLE": "повторить %1 раз",
                +	"CONTROLS_REPEAT_INPUT_DO": "выполнить",
                +	"CONTROLS_REPEAT_TOOLTIP": "Выполняет некоторые команды несколько раз.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "повторять, пока",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "повторять, пока не",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Пока значение истинно, выполняет команды.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Пока значение ложно, выполняет команды",
                +	"CONTROLS_FOR_TOOLTIP": "Присваивает переменной '%1' значения от начального до конечного с заданным шагом и выполняет указанные команды.",
                +	"CONTROLS_FOR_TITLE": "цикл по %1 от %2 до %3 с шагом %4",
                +	"CONTROLS_FOREACH_TITLE": "для каждого элемента %1 в списке %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Для каждого элемента в списке, присваивает переменной '%1' значение элемента  и выполняет указанные  команды.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "выйти из цикла",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "перейти к следующему шагу цикла",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Прерывает этот цикл.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Пропускает остаток цикла и переходит к следующему шагу.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Предупреждение: этот блок может использоваться только внутри цикла.",
                +	"CONTROLS_IF_TOOLTIP_1": "Если условие истинно, выполняет команды.",
                +	"CONTROLS_IF_TOOLTIP_2": "Если условие истинно, выполняет первый блок команд. Иначе выполняется второй блок команд.",
                +	"CONTROLS_IF_TOOLTIP_3": "Если первое условие истинно, то выполняет первый блок команд. Иначе, если второе условие истинно, выполняет второй блок команд.",
                +	"CONTROLS_IF_TOOLTIP_4": "Если первое условие истинно, то выполняет первый блок команд.  В противном случае, если второе условие истинно, выполняет второй блок команд.  Если ни одно из условий не истинно, выполняет последний блок команд.",
                +	"CONTROLS_IF_MSG_IF": "если",
                +	"CONTROLS_IF_MSG_ELSEIF": "иначе если",
                +	"CONTROLS_IF_MSG_ELSE": "иначе",
                +	"CONTROLS_IF_IF_TOOLTIP": "Добавьте, удалите, переставьте фрагменты для переделки блока \"если\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Добавляет условие к блоку \"если\"",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Добавить заключительный подблок для случая, когда все условия ложны.",
                +	"IOS_OK": "ОК",
                +	"IOS_CANCEL": "Отмена",
                +	"IOS_ERROR": "Ошибка",
                +	"IOS_PROCEDURES_INPUTS": "ВХОД",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Добавить входную переменную",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Разрешить операторы",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "У этой функции есть дублирующиеся входные переменные.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Добавить переменную",
                +	"IOS_VARIABLES_ADD_BUTTON": "Добавить",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Переименовать",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Удалить",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Имя переменной",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Вы не можете использовать пустое имя переменной.",
                +	"LOGIC_COMPARE_HELPURL": "https://ru.wikipedia.org/wiki/Неравенство",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Возвращает положительное значение, если вводы равны.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Возвращает положительное значение, если вводы не равны.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Возвращает положительное значение, если первый ввод меньше второго.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Возвращает значение истина, если первая вставка меньше или равна  второй.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Возвращает значение истина, если первая вставка больше второй.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Возвращает значение истина, если первая вставка больше или равна  второй.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Возвращает значение истина, если обе вставки истинны.",
                +	"LOGIC_OPERATION_AND": "и",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Возвращает значение истина, если хотя бы одна из вставок истинна.",
                +	"LOGIC_OPERATION_OR": "или",
                +	"LOGIC_NEGATE_TITLE": "не %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Возвращает значение истина, если вставка ложна.  Возвращает значение ложь, если вставка истинна.",
                +	"LOGIC_BOOLEAN_TRUE": "истина",
                +	"LOGIC_BOOLEAN_FALSE": "ложь",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Возвращает значение истина или ложь.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "ничто",
                +	"LOGIC_NULL_TOOLTIP": "Возвращает ничто.",
                +	"LOGIC_TERNARY_HELPURL": "https://ru.wikipedia.org/wiki/Тернарная_условная_операция",
                +	"LOGIC_TERNARY_CONDITION": "выбрать по",
                +	"LOGIC_TERNARY_IF_TRUE": "если истина",
                +	"LOGIC_TERNARY_IF_FALSE": "если ложь",
                +	"LOGIC_TERNARY_TOOLTIP": "Проверяет условие выбора. Если условие истинно, возвращает первое значение, в противном случае возвращает второе значение.",
                +	"MATH_NUMBER_HELPURL": "https://ru.wikipedia.org/wiki/Число",
                +	"MATH_NUMBER_TOOLTIP": "Число.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ru.wikipedia.org/wiki/Арифметика",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Возвращает сумму двух чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Возвращает разность двух чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Возвращает произведение двух чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Возвращает частное от деления первого числа на второе.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Возвращает первое число, возведённое в степень второго числа.",
                +	"MATH_SINGLE_HELPURL": "https://ru.wikipedia.org/wiki/Квадратный_корень",
                +	"MATH_SINGLE_OP_ROOT": "квадратный корень",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Возвращает квадратный корень числа.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "модуль",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Возвращает модуль числа",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Возвращает противоположное число.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Возвращает натуральный логарифм числа.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Возвращает десятичный логарифм числа.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Возвращает е в указанной степени.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Возвращает 10 в указанной степени.",
                +	"MATH_TRIG_HELPURL": "https://ru.wikipedia.org/wiki/Тригонометрические_функции",
                +	"MATH_TRIG_TOOLTIP_SIN": "Возвращает синус угла в градусах.",
                +	"MATH_TRIG_TOOLTIP_COS": "Возвращает косинус угла в градусах.",
                +	"MATH_TRIG_TOOLTIP_TAN": "Возвращает тангенс угла в градусах.",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Возвращает арксинус (в градусах).",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Возвращает арккосинус (в градусах).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Возвращает арктангенс (в градусах)",
                +	"MATH_CONSTANT_HELPURL": "https://ru.wikipedia.org/wiki/Математическая_константа",
                +	"MATH_CONSTANT_TOOLTIP": "Возвращает одну из распространённых  констант: π (3.141...), e (2.718...), φ (1.618...), sqrt(2) (1.414...), sqrt(½) (0.707...) или ∞ (бесконечность).",
                +	"MATH_IS_EVEN": "чётное",
                +	"MATH_IS_ODD": "нечётное",
                +	"MATH_IS_PRIME": "простое",
                +	"MATH_IS_WHOLE": "целое",
                +	"MATH_IS_POSITIVE": "положительное",
                +	"MATH_IS_NEGATIVE": "отрицательное",
                +	"MATH_IS_DIVISIBLE_BY": "делится на",
                +	"MATH_IS_TOOLTIP": "Проверяет, является ли число чётным, нечётным, простым, целым, положительным, отрицательным или оно кратно определённому числу.  Возвращает значение истина или ложь.",
                +	"MATH_CHANGE_HELPURL": "https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B8%D0%BE%D0%BC%D0%B0_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29#.D0.98.D0.BD.D0.BA.D1.80.D0.B5.D0.BC.D0.B5.D0.BD.D1.82",
                +	"MATH_CHANGE_TITLE": "увеличить %1 на %2",
                +	"MATH_CHANGE_TOOLTIP": "Добавляет число к переменной '%1'.",
                +	"MATH_ROUND_HELPURL": "https://ru.wikipedia.org/wiki/Округление",
                +	"MATH_ROUND_TOOLTIP": "Округляет число до большего или меньшего.",
                +	"MATH_ROUND_OPERATOR_ROUND": "округлить",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "округлить к большему",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "округлить к меньшему",
                +	"MATH_ONLIST_OPERATOR_SUM": "сумма списка",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Возвращает сумму всех чисел в списке.",
                +	"MATH_ONLIST_OPERATOR_MIN": "наименьшее в списке",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Возвращает наименьшее число списка.",
                +	"MATH_ONLIST_OPERATOR_MAX": "наибольшее в списке",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Возвращает наибольшее число списка.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "среднее арифметическое списка",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Возвращает среднее арифметическое списка.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "медиана списка",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Возвращает медиану списка.",
                +	"MATH_ONLIST_OPERATOR_MODE": "моды списка",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Возвращает список наиболее часто встречающихся элементов списка.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "стандартное отклонение списка",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Возвращает стандартное отклонение списка.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "случайный элемент списка",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Возвращает случайный элемент списка.",
                +	"MATH_MODULO_HELPURL": "https://ru.wikipedia.org/wiki/Деление_с_остатком",
                +	"MATH_MODULO_TITLE": "остаток от %1 : %2",
                +	"MATH_MODULO_TOOLTIP": "Возвращает остаток от деления двух чисел.",
                +	"MATH_CONSTRAIN_TITLE": "ограничить %1 снизу %2 сверху %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Ограничивает число нижней и верхней границами (включительно).",
                +	"MATH_RANDOM_INT_HELPURL": "https://ru.wikipedia.org/wiki/Генератор_псевдослучайных_чисел",
                +	"MATH_RANDOM_INT_TITLE": "случайное целое число от %1 для %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Возвращает случайное число между двумя заданными пределами (включая и их).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://ru.wikipedia.org/wiki/Генератор_псевдослучайных_чисел",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "случайное число от 0 (включительно) до 1",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Возвращает случайное число от 0.0 (включительно) до 1.0.",
                +	"TEXT_TEXT_HELPURL": "https://ru.wikipedia.org/wiki/Строковый_тип",
                +	"TEXT_TEXT_TOOLTIP": "Буква, слово или строка текста.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "создать текст из",
                +	"TEXT_JOIN_TOOLTIP": "Создаёт фрагмент текста, объединяя любое число элементов",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "соединить",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Добавьте, удалите, переставьте фрагменты для переделки текстового блока.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Добавить элемент к тексту.",
                +	"TEXT_APPEND_TITLE": "к %1 добавить текст %2",
                +	"TEXT_APPEND_TOOLTIP": "Добавить текст к переменной «%1».",
                +	"TEXT_LENGTH_TITLE": "длина %1",
                +	"TEXT_LENGTH_TOOLTIP": "Возвращает число символов (включая пробелы) в заданном тексте.",
                +	"TEXT_ISEMPTY_TITLE": "%1 пуст",
                +	"TEXT_ISEMPTY_TOOLTIP": "Возвращает значение истина, если предоставленный текст пуст.",
                +	"TEXT_INDEXOF_TOOLTIP": "Возвращает номер позиции первого/последнего вхождения первого текста во  втором.  Возвращает %1, если текст не найден.",
                +	"TEXT_INDEXOF_TITLE": "в тексте %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "найти первое вхождение текста",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "найти последнее вхождение текста",
                +	"TEXT_CHARAT_TITLE": "в тексте %1 %2",
                +	"TEXT_CHARAT_FROM_START": "взять букву №",
                +	"TEXT_CHARAT_FROM_END": "взять букву № с конца",
                +	"TEXT_CHARAT_FIRST": "взять первую букву",
                +	"TEXT_CHARAT_LAST": "взять последнюю букву",
                +	"TEXT_CHARAT_RANDOM": "взять случайную букву",
                +	"TEXT_CHARAT_TOOLTIP": "Возвращает букву в указанной позиции.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Возвращает указанную часть текста.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "в тексте",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "взять подстроку с буквы №",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "взять подстроку с буквы № с конца",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "взять подстроку с первой буквы",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "по букву №",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "по букву № с конца",
                +	"TEXT_GET_SUBSTRING_END_LAST": "по последнюю букву",
                +	"TEXT_CHANGECASE_TOOLTIP": "Возвращает копию текста с ЗАГЛАВНЫМИ или строчными буквами.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "в ЗАГЛАВНЫЕ БУКВЫ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "в строчные буквы",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "в Заглавные Начальные Буквы",
                +	"TEXT_TRIM_TOOLTIP": "Возвращает копию текста с пробелами, удалеными с одного или обоих концов.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "обрезать пробелы с двух сторон",
                +	"TEXT_TRIM_OPERATOR_LEFT": "обрезать пробелы слева",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "обрезать пробелы справа",
                +	"TEXT_PRINT_TITLE": "напечатать %1",
                +	"TEXT_PRINT_TOOLTIP": "Печатает текст, число или другой объект.",
                +	"TEXT_PROMPT_TYPE_TEXT": "запросить текст с подсказкой",
                +	"TEXT_PROMPT_TYPE_NUMBER": "запросить число с подсказкой",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Запросить у пользователя число.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Запросить у пользователя текст.",
                +	"TEXT_COUNT_MESSAGE0": "подсчитать количество %1 в %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Подсчитать, сколько раз отрывок текста появляется в другом тексте.",
                +	"TEXT_REPLACE_MESSAGE0": "заменить %1 на %2 в %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Заменить все вхождения некоторого текста другим текстом.",
                +	"TEXT_REVERSE_MESSAGE0": "изменить порядок на обратный %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Меняет порядок символов в тексте на обратный.",
                +	"LISTS_CREATE_EMPTY_TITLE": "создать пустой список",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Возвращает список длины 0, не содержащий данных",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Создаёт список с любым числом элементов.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "создать список из",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "список",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Добавьте, удалите, переставьте элементы для переделки блока списка.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Добавляет элемент к списку.",
                +	"LISTS_REPEAT_TOOLTIP": "Создаёт список, состоящий из заданного числа копий элемента.",
                +	"LISTS_REPEAT_TITLE": "создать список из элемента %1, повторяющегося %2 раз",
                +	"LISTS_LENGTH_TITLE": "длина %1",
                +	"LISTS_LENGTH_TOOLTIP": "Возвращает длину списка.",
                +	"LISTS_ISEMPTY_TITLE": "%1 пуст",
                +	"LISTS_ISEMPTY_TOOLTIP": "Возвращает значение истина, если список пуст.",
                +	"LISTS_INLIST": "в списке",
                +	"LISTS_INDEX_OF_FIRST": "найти первое вхождение элемента",
                +	"LISTS_INDEX_OF_LAST": "найти последнее вхождение элемента",
                +	"LISTS_INDEX_OF_TOOLTIP": "Возвращает номер позиции первого/последнего вхождения элемента в списке. Возвращает %1, если элемент не найден.",
                +	"LISTS_GET_INDEX_GET": "взять",
                +	"LISTS_GET_INDEX_GET_REMOVE": "взять и удалить",
                +	"LISTS_GET_INDEX_REMOVE": "удалить",
                +	"LISTS_GET_INDEX_FROM_END": "№ с конца",
                +	"LISTS_GET_INDEX_FIRST": "первый",
                +	"LISTS_GET_INDEX_LAST": "последний",
                +	"LISTS_GET_INDEX_RANDOM": "произвольный",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 - первый элемент.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 - последний элемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Возвращает элемент в указанной позиции списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Возвращает первый элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Возвращает последний элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Возвращает случайный элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Удаляет и возвращает элемент в указанной позиции списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Удаляет и возвращает первый элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Удаляет и возвращает последний элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Удаляет и возвращает случайный элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Удаляет элемент в указанной позиции списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Удаляет первый элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Удаляет последний элемент списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Удаляет случайный элемент списка.",
                +	"LISTS_SET_INDEX_SET": "присвоить",
                +	"LISTS_SET_INDEX_INSERT": "вставить в",
                +	"LISTS_SET_INDEX_INPUT_TO": "=",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Присваивает значение элементу в указанной позиции списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Присваивает значение первому элементу списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Присваивает значение последнему элементу списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Присваивает значение случайному элементу списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Вставляет элемент в указанной позиции списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Вставляет элемент в начало списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Добавляет элемент в конец списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Вставляет элемент в случайное место в списке.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "взять подсписок с №",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "взять подсписок с № с конца",
                +	"LISTS_GET_SUBLIST_START_FIRST": "взять подсписок с первого",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "по №",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "по № с конца",
                +	"LISTS_GET_SUBLIST_END_LAST": "по последний",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Создаёт копию указанной части списка.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "сортировать %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Сортировать копию списка.",
                +	"LISTS_SORT_ORDER_ASCENDING": "по возрастанию",
                +	"LISTS_SORT_ORDER_DESCENDING": "по убыванию",
                +	"LISTS_SORT_TYPE_NUMERIC": "числовая",
                +	"LISTS_SORT_TYPE_TEXT": "по алфавиту",
                +	"LISTS_SORT_TYPE_IGNORECASE": "по алфавиту, без учёта регистра",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "сделать список из текста",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "собрать текст из списка",
                +	"LISTS_SPLIT_WITH_DELIMITER": "с разделителем",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Разбивает текст в список текстов, по разделителям.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Соединяет сптсок текстов в один текст с разделителями.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "изменить порядок на обратный %1",
                +	"LISTS_REVERSE_TOOLTIP": "Изменить порядок списка на обратный.",
                +	"VARIABLES_GET_TOOLTIP": "Возвращает значение этой переменной.",
                +	"VARIABLES_GET_CREATE_SET": "Создать блок \"присвоить\" для %1",
                +	"VARIABLES_SET": "присвоить %1 = %2",
                +	"VARIABLES_SET_TOOLTIP": "Присваивает переменной значение вставки.",
                +	"VARIABLES_SET_CREATE_GET": "Создать вставку %1",
                +	"PROCEDURES_DEFNORETURN_TITLE": "чтобы",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "выполнить что-то",
                +	"PROCEDURES_BEFORE_PARAMS": "с:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "с:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Создаёт процедуру, не возвращающую значение.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Опишите эту функцию…",
                +	"PROCEDURES_DEFRETURN_RETURN": "вернуть",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Создаёт процедуру, возвращающую значение.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "разрешить операторы",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Предупреждение: эта функция имеет повторяющиеся параметры.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://ru.wikipedia.org/wiki/Подпрограмма",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Исполняет определённую пользователем процедуру '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://ru.wikipedia.org/wiki/Подпрограмма",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Исполняет определённую пользователем процедуру '%1' и возвращает вычисленное  значение.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "параметры",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Добавить, удалить или изменить порядок входных параметров для этой функции.",
                +	"PROCEDURES_MUTATORARG_TITLE": "имя параметра:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Добавить входной параметр в функцию.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Выделить определение процедуры",
                +	"PROCEDURES_CREATE_DO": "Создать вызов '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Если первое значение истинно, возвращает второе значение.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Предупреждение: Этот блок может использоваться только внутри определения функции."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sc.json b/blockly/webif/static/blockly/msg/json/sc.json
                new file mode 100644
                index 000000000..6940a59ef
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sc.json
                @@ -0,0 +1,295 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Via maxima",
                +			"Taxandru",
                +			"Uharteko"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"TODAY": "Oe",
                +	"DUPLICATE_BLOCK": "Dùplica",
                +	"ADD_COMMENT": "Agiunghe unu cumentu",
                +	"REMOVE_COMMENT": "Fùlia unu cumentu",
                +	"EXTERNAL_INPUTS": "Intradas esternas",
                +	"INLINE_INPUTS": "Intradas in lìnia",
                +	"DELETE_BLOCK": "Fùlia Blocu",
                +	"DELETE_X_BLOCKS": "Fulia %1 Blocus",
                +	"DELETE_ALL_BLOCKS": "Scancellu su %1 de is brocus?",
                +	"CLEAN_UP": "Lìmpia is brocus",
                +	"COLLAPSE_BLOCK": "Serra e stringi Brocu",
                +	"COLLAPSE_ALL": "Serra e stringi Brocus",
                +	"EXPAND_BLOCK": "Aberi Brocu",
                +	"EXPAND_ALL": "Aberi Brocus",
                +	"DISABLE_BLOCK": "Disabìlita Blocu",
                +	"ENABLE_BLOCK": "Abìlita Blocu",
                +	"HELP": "Agiudu",
                +	"CHANGE_VALUE_TITLE": "Muda valori:",
                +	"RENAME_VARIABLE": "Muda nòmini a variabili...",
                +	"RENAME_VARIABLE_TITLE": "A is variabilis '%1' muda nòmini a:",
                +	"NEW_VARIABLE": "Variabili noa...",
                +	"NEW_VARIABLE_TITLE": "Nòmini de sa variabili noa:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Scebera unu colori de sa tauledda.",
                +	"COLOUR_RANDOM_TITLE": "Unu colori a brítiu",
                +	"COLOUR_RANDOM_TOOLTIP": "Scebera unu colori a brítiu.",
                +	"COLOUR_RGB_TITLE": "colora cun",
                +	"COLOUR_RGB_RED": "arrùbiu",
                +	"COLOUR_RGB_GREEN": "birdi",
                +	"COLOUR_RGB_BLUE": "blue",
                +	"COLOUR_RGB_TOOLTIP": "Cuncorda unu colori cun su tanti de arrubiu, birdi, e blue. Totu is valoris depint essi intra 0 e 100.",
                +	"COLOUR_BLEND_TITLE": "mestura",
                +	"COLOUR_BLEND_COLOUR1": "colori 1",
                +	"COLOUR_BLEND_COLOUR2": "colori 2",
                +	"COLOUR_BLEND_RATIO": "raportu",
                +	"COLOUR_BLEND_TOOLTIP": "Amestura duus coloris cun unu raportu (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "repiti %1 bortas",
                +	"CONTROLS_REPEAT_INPUT_DO": "fai",
                +	"CONTROLS_REPEAT_TOOLTIP": "Fait pariga de cumandus prus bortas.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "repiti interis",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "repiti fintzas",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Interis su valori est berus, tandu fai pariga de cumandus.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Interis su valori est frassu, tandu fai pariga de cumandus.",
                +	"CONTROLS_FOR_TOOLTIP": "Fait pigai a sa variàbili \"%1\" i valoris de su primu numeru a s'urtimu, a su passu impostau e fait su brocu.",
                +	"CONTROLS_FOR_TITLE": "po %1 de %2 fintzas %3 a passus de %4",
                +	"CONTROLS_FOREACH_TITLE": "po dònnia item %1 in lista %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Po dònnia item in sa lista, ponit sa variàbili '%1' pari a s'item, e tandu fait pariga de cumandus.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "sàrtiat a foras de sa lòriga",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "sighit cun su repicu afatànti",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Bessit de sa lòriga.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Sartiat su chi abarrat de sa loriga, e sighit cun su repicu afatànti.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Amonestu: Custu brocu ddu podis ponni sceti aintru de una lòriga.",
                +	"CONTROLS_IF_TOOLTIP_1": "Si su valori est berus, tandu fait pariga de cumandus.",
                +	"CONTROLS_IF_TOOLTIP_2": "Si su valori est berus, tandu fai su primu brocu de is cumandus. Sinuncas, fai su segundu brocu de is cumandus.",
                +	"CONTROLS_IF_TOOLTIP_3": "Si su primu valori est beridadi, tandu fai su primu brocu de is cumandus. Sinuncas, si su segundu valori est beridadi, fai su segundu brocu de is cumandus.",
                +	"CONTROLS_IF_TOOLTIP_4": "Si su primu valori est berus, tandu fai su primu brocu de is cumandus. Sinuncas, si su segundu valori est berus, fai su segundu brocu de is cumandus. Si mancu unu valori est berus, tandu fai s'urtimu brocu de is cumandus.",
                +	"CONTROLS_IF_MSG_IF": "si",
                +	"CONTROLS_IF_MSG_ELSEIF": "sinuncas si",
                +	"CONTROLS_IF_MSG_ELSE": "sinuncas",
                +	"CONTROLS_IF_IF_TOOLTIP": "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu si.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Aciungi una cunditzioni a su brocu si.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Aciungi una urtima cunditzioni piga-totu a su brocu si.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Torrat berus si is inputs funt unu uguali a s'àteru.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Torrat berus si is inputs non funt unu uguali a s'àteru.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Torrat berus si su primu input est prus piticu de s'àteru.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Torrat berus si su primu input est prus piticu o uguali a s'àteru.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Torrat berus si su primu input est prus mannu de s'àteru.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Torrat berus si su primu input est prus mannu o uguali a s'àteru.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Torrat berus si ambos is inputs funt berus.",
                +	"LOGIC_OPERATION_AND": "and",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Torrat berus si assumancu unu de is inputs est berus.",
                +	"LOGIC_OPERATION_OR": "or",
                +	"LOGIC_NEGATE_TITLE": "non %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Torrat berus si s'input est frassu. Torrat frassu si s'input est berus.",
                +	"LOGIC_BOOLEAN_TRUE": "berus",
                +	"LOGIC_BOOLEAN_FALSE": "frassu",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Torrat berus o frassu.",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Torrat null.",
                +	"LOGIC_TERNARY_CONDITION": "cumpròa",
                +	"LOGIC_TERNARY_IF_TRUE": "si berus",
                +	"LOGIC_TERNARY_IF_FALSE": "si frassu",
                +	"LOGIC_TERNARY_TOOLTIP": "‎Cumproa sa cunditzioni in 'cumproa'. Si sa cunditzioni est berus, torrat su valori 'si berus'; sinuncas torrat su valori 'si frassu'.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Unu numeru",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Torrat sa summa de is duus nùmerus.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Torrat sa diferèntzia de is duus nùmerus.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Torrat su produtu de is duus nùmerus.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Torrat su cuotzienti de is duus nùmerus.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Torrat su primu numeru artziau a sa potenza de su segundu nùmeru.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "arraxina cuadra",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Torrat s'arraxina cuadra de unu numeru.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "assolutu",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Torrat su valori assolútu de unu numeru.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Torrat su valori negau de unu numeru.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Torrat su logaritmu naturali de unu numeru.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Torrat su logaritmu a basi 10 de unu numeru.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Torrat (e) a sa potèntzia de unu numeru.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Torrat (10) a sa potèntzia de unu numeru.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Torrat su sinu de unu gradu (no radianti).",
                +	"MATH_TRIG_TOOLTIP_COS": "Torrat su cosinu de unu gradu (no radianti).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Torrat sa tangenti de unu gradu (no radianti).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Torrat su arcsinu de unu numeru.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Torrat su arccosinu de unu numeru.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Torrat su arctangenti de unu numeru.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Torrat una de is costantis comunas: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), o ∞ (infiniu).",
                +	"MATH_IS_EVEN": "est paris",
                +	"MATH_IS_ODD": "est dísparu",
                +	"MATH_IS_PRIME": "est primu",
                +	"MATH_IS_WHOLE": "est intreu",
                +	"MATH_IS_POSITIVE": "est positivu",
                +	"MATH_IS_NEGATIVE": "est negativu",
                +	"MATH_IS_DIVISIBLE_BY": "fait a ddu dividi po",
                +	"MATH_IS_TOOLTIP": "Cumprova si unu numeru est paris, dìsparis, primu, intreu, positivu, negativu o si fait a ddu dividi po unu numeru giau. Torrat berus o frassu.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "muda %1 de %2",
                +	"MATH_CHANGE_TOOLTIP": "Aciungi unu numeru a sa variabili '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Arretunda unu numeru faci a susu o faci a bàsciu.",
                +	"MATH_ROUND_OPERATOR_ROUND": "arretunda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Arretunda faci a susu",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "arretunda faci a bàsciu.",
                +	"MATH_ONLIST_OPERATOR_SUM": "suma sa lista",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Torrat sa suma de totu is numerus de sa lista.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimu de sa lista",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Torrat su numeru prus piticu de sa lista.",
                +	"MATH_ONLIST_OPERATOR_MAX": "massimu de sa lista",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Torrat su numeru prus mannu de sa lista",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "mèdia de sa lista",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Torrat sa mèdia (aritimètica) de is valoris de sa lista.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "medianu de sa lista",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Torrat su numeru medianu de sa lista.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modas de sa lista",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Torrat una lista de is itams prus frecuentis de sa lista.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "deviadura standard de sa lista",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Torrat sa deviadura standard de sa lista.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "unu item a brìtiu de sa lista",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Torrat unu item a brìtiu de sa lista.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "arrestu de %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Torrat s'arrestu de sa divisioni de duus numerus.",
                +	"MATH_CONSTRAIN_TITLE": "custringi %1 de %2 a %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Custringi unu numeru aintru de is liminaxus giaus (cumprendius).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "numeru intreu a brítiu de %1 a %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Torrat unu numeru intreu a brìtiu intra duus nùmerus giaus (cumpresus).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "una fratzioni a brìtiu",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Torrat una fratzioni a brìtiu intra 0.0 (cumpresu) e 1.0 (bogau).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Una lìtera, paràula, o linia de testu.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "scri testu cun",
                +	"TEXT_JOIN_TOOLTIP": "Fait unu testu ponendi a pari parigas de items.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "auni a pari",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu de testu.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Acciungi unu item a su testu.",
                +	"TEXT_APPEND_TOOLTIP": "Aciungit testu a sa variàbili '%1'.",
                +	"TEXT_LENGTH_TITLE": "longària de %1",
                +	"TEXT_LENGTH_TOOLTIP": "Torrat su numeru de lìteras (cun is spàtzius) in su testu giau.",
                +	"TEXT_ISEMPTY_TITLE": "%1 est buidu",
                +	"TEXT_ISEMPTY_TOOLTIP": "Torrat berus si su testu giau est buidu.",
                +	"TEXT_INDEXOF_TOOLTIP": "Torrat s'indixi de sa primu/urtima ocasioni de su primu testu in su segundu testu. Torrat %1 si su testu no ddu agatat.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "circa prima ocasioni de su testu",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "circa urtima ocasioni de su testu",
                +	"TEXT_CHARAT_FROM_START": "piga sa lìtera #",
                +	"TEXT_CHARAT_FROM_END": "piga sa lìtera # de sa fini",
                +	"TEXT_CHARAT_FIRST": "piga sa prima lìtera",
                +	"TEXT_CHARAT_LAST": "piga s'urtima lìtera",
                +	"TEXT_CHARAT_RANDOM": "piga una lìtera a brìtiu",
                +	"TEXT_CHARAT_TOOLTIP": "Torrat sa lìtera de su postu giau.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Torrat su testu inditau.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in su testu",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "piga suta-stringa de sa lìtera #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "piga suta-stringa de sa lìtera # fintzas a fini",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "piga suta-stringa de sa primu lìtera",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "a sa lìtera #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "a sa lìtera # de sa fini",
                +	"TEXT_GET_SUBSTRING_END_LAST": "a s'urtima lìtera",
                +	"TEXT_CHANGECASE_TOOLTIP": "Torrat una copia de su testu inditau mudendi mauschínu/minúdu.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "a mauschínu",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "a minúdu",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "cun Primu lìtera a Mauschínu",
                +	"TEXT_TRIM_TOOLTIP": "Torrat una copia de su testu bogaus is spàtzius de unu o de ambus is càbudus.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "bogat spàtzius de ambus càbudus de",
                +	"TEXT_TRIM_OPERATOR_LEFT": "bogat spàtzius de su càbudu de manca de",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "bogat spàtzius de su càbudu de dereta de",
                +	"TEXT_PRINT_TITLE": "scri %1",
                +	"TEXT_PRINT_TOOLTIP": "Scri su testu, numeru o àteru valori.",
                +	"TEXT_PROMPT_TYPE_TEXT": "pregonta po su testu",
                +	"TEXT_PROMPT_TYPE_NUMBER": "pregonta po unu numeru",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Pregonta unu nùmeru a s'impitadore.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Pregonta testu a s'impitadore.",
                +	"LISTS_CREATE_EMPTY_TITLE": "fait una lista buida",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Torrat una lista, de longària 0, chena records de datus.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Fait una lista cun calisiollat numeru de items.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "fait una lista cun",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Aciungi, fùlia, o assenta is partis po torrai a sètiu custu brocu lista.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Acciungi unu item a sa lista.",
                +	"LISTS_REPEAT_TOOLTIP": "Fait una lista cun unu numeru giau repitiu su tanti de is bortas inditadas.",
                +	"LISTS_REPEAT_TITLE": "fait una lista cun item %1 repitiu %2 bortas",
                +	"LISTS_LENGTH_TITLE": "longària de %1",
                +	"LISTS_LENGTH_TOOLTIP": "Torrat sa longària de una lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 est buidu",
                +	"LISTS_ISEMPTY_TOOLTIP": "Torrat berus si sa lista est buida.",
                +	"LISTS_INLIST": "in lista",
                +	"LISTS_INDEX_OF_FIRST": "circa prima ocasioni de s'item",
                +	"LISTS_INDEX_OF_LAST": "circa urtima ocasioni de s'item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Torrat s'indixi de sa primu/urtima ocasioni de s'item in sa lista. Torrat %1 si s'item non s'agatat.",
                +	"LISTS_GET_INDEX_GET": "piga",
                +	"LISTS_GET_INDEX_GET_REMOVE": "piga e fùlia",
                +	"LISTS_GET_INDEX_REMOVE": "fùlia",
                +	"LISTS_GET_INDEX_FROM_END": "# de sa fini",
                +	"LISTS_GET_INDEX_FIRST": "primu",
                +	"LISTS_GET_INDEX_LAST": "urtimu",
                +	"LISTS_GET_INDEX_RANDOM": "a brìtiu (random)",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 est po su primu elementu.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 est po s'urtimu elementu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Torrat s'elementu de su postu inditau de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Torrat su primu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Torrat s'urtimu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Torrat un'elementu a brìtiu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Fùliat e torrat s'elementu de su postu inditau de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Fùliat e torrat su primu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Fùliat e torrat s'urtimu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Fùliat e torrat un'elementu a brìtiu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Fùliat s'elementu de su postu inditau de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Fùliat su primu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Fùliat s'urtimu elementu de una lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Fùliat unu elementu a brìtiu de una lista.",
                +	"LISTS_SET_INDEX_SET": "imposta",
                +	"LISTS_SET_INDEX_INSERT": "inserta a",
                +	"LISTS_SET_INDEX_INPUT_TO": "a",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Impostat s'elementu in su postu inditau de una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Impostat su primu elementu in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Impostat s'urtimu elementu in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Impostat unu elementu random in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Insertat s'elementu in su postu inditau in una lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Insertat s'elementu a su cumintzu de sa lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Aciungit s'elementu a sa fini de sa lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Aciungit s'elementu a brítiu in sa lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "bogandi suta-lista de #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "bogandi suta-lista de # de sa fini.",
                +	"LISTS_GET_SUBLIST_START_FIRST": "bogandi suta-lista de su primu",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "fintzas a #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "a # de sa fini",
                +	"LISTS_GET_SUBLIST_END_LAST": "a s'urtimu",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Fait una copia de sa parti inditada de sa lista.",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "fai una lista de unu testu",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "fai unu testu de una lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "cun  separadori",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dividi su testu in un'elencu de testus, firmendi po dònnia separadori.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Auni una lista de testus in d-unu sceti, ponendi separadoris.",
                +	"VARIABLES_GET_TOOLTIP": "Torrat su valori de custa variabili.",
                +	"VARIABLES_GET_CREATE_SET": "Fait 'imposta %1'",
                +	"VARIABLES_SET": "imposta %1 a %2",
                +	"VARIABLES_SET_TOOLTIP": "Imposta custa variabili uguali a s'input.",
                +	"VARIABLES_SET_CREATE_GET": "Fait 'piga %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "po",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "fait calincuna cosa",
                +	"PROCEDURES_BEFORE_PARAMS": "con:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "cun",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Fait una funtzioni chena output.",
                +	"PROCEDURES_DEFRETURN_RETURN": "torrat",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Fait una funtzioni cun output.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "permiti decraratzionis",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Amonestu: Custa funtzioni tenit parametrus duplicaus.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Arròllia sa funtzione '%1' cuncordada dae s'impitadore.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Arròllia sa funtzione '%1' cuncordada dae s'impitadore e imprea s'output suu.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inputs",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Aciungi, fùlia, o assenta is inputs a custa funtzioni.",
                +	"PROCEDURES_MUTATORARG_TITLE": "nomini input:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Aciungi un input a sa funtzioni.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Marca sa definitzioni de funtzioni.",
                +	"PROCEDURES_CREATE_DO": "Ingenerau'%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Si unu valori est berus, tandu torrat unu segundu valori.",
                +	"PROCEDURES_IFRETURN_WARNING": "Amonestu: Custu brocu ddu podis ponni sceti aintru de una funtzioni."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sd.json b/blockly/webif/static/blockly/msg/json/sd.json
                new file mode 100644
                index 000000000..f5482d0c9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sd.json
                @@ -0,0 +1,152 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Aursani",
                +			"Mehtab ahmed",
                +			"Indus Asia"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "اسم",
                +	"TODAY": "اڄ",
                +	"DUPLICATE_BLOCK": "نقل",
                +	"ADD_COMMENT": "راءِ ڏيو",
                +	"REMOVE_COMMENT": "راءِ ڊاهيو",
                +	"EXTERNAL_INPUTS": "ٻاهرين ڄاڻ",
                +	"DELETE_BLOCK": "بلاڪ ڊاهيو",
                +	"DELETE_X_BLOCKS": "1٪ بلاڪ ڊاهيو",
                +	"CLEAN_UP": "بندشون هٽايو",
                +	"COLLAPSE_BLOCK": "بلاڪ ڍڪيو",
                +	"COLLAPSE_ALL": "بلاڪَ ڍڪيو",
                +	"EXPAND_BLOCK": "بلاڪ نمايو",
                +	"EXPAND_ALL": "بلاڪَ نمايو",
                +	"DISABLE_BLOCK": "بلاڪ کي غيرفعال بڻايو",
                +	"ENABLE_BLOCK": "بلاڪ کي فعال بڻايو",
                +	"HELP": "مدد",
                +	"UNDO": "ڊاهيو",
                +	"REDO": "ٻيهر ڪريو",
                +	"CHANGE_VALUE_TITLE": "قدر بدلايو",
                +	"RENAME_VARIABLE": "ڦرڻي کي نئون نالو ڏيو...",
                +	"NEW_VARIABLE": "نئون ڦرڻو...",
                +	"NEW_VARIABLE_TITLE": "ڦرڻي جو نئون نالو:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "رنگ دٻيءَ مان رنگ چونڊيو.",
                +	"COLOUR_RANDOM_TITLE": "بنا ترتيب رنگ",
                +	"COLOUR_RANDOM_TOOLTIP": "ڪو بہ ‌رنگ چونڊيو.",
                +	"COLOUR_RGB_TITLE": "سان رڱيو",
                +	"COLOUR_RGB_RED": "ڳاڙهو",
                +	"COLOUR_RGB_GREEN": "سائو",
                +	"COLOUR_RGB_BLUE": "نيرو",
                +	"COLOUR_RGB_TOOLTIP": "ڳاڙهي، سائي، ۽ نيري جو مقدار ڄاڻائي گھربل رنگ ٺاهيو. سمورا قدر 0 ۽ 100 جي وچ ۾ هجن.",
                +	"COLOUR_BLEND_TITLE": "گڏيل",
                +	"COLOUR_BLEND_COLOUR1": "رنگ 1",
                +	"COLOUR_BLEND_COLOUR2": "رنگ 2",
                +	"COLOUR_BLEND_RATIO": "تناسب",
                +	"COLOUR_BLEND_TOOLTIP": "ڄاڻايل تناسب سان ٻہ رنگ پاڻ ۾ ملايو (0.0-1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "1٪ ڀيرا ورجايو",
                +	"CONTROLS_REPEAT_INPUT_DO": "ڪريو",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ورجايو جڏهن",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ورجايو جيستائين",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "چڪر مان ٻاهر نڪرو",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "چڪر جاري رکندي نئين ڦيري پايو",
                +	"CONTROLS_IF_MSG_IF": "جيڪڏهن",
                +	"CONTROLS_IF_MSG_ELSEIF": "نہ تہ جي",
                +	"CONTROLS_IF_MSG_ELSE": "نہ تہ",
                +	"IOS_OK": "ٺيڪ (او ڪي) آهي",
                +	"IOS_CANCEL": "رد",
                +	"IOS_ERROR": "چُڪَ",
                +	"IOS_VARIABLES_ADD_VARIABLE": "تبديل ٿيندڙ (ويريئيبل) وجهو",
                +	"IOS_VARIABLES_ADD_BUTTON": "شامل ڪيو",
                +	"IOS_VARIABLES_DELETE_BUTTON": "ڊاهيو",
                +	"IOS_VARIABLES_VARIABLE_NAME": "تبيديل ٿيندڙ (ويريئيبل) جو نالو",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "جيڪڏهن ٻئي ان پُٽس برابر آهن تہ درست وراڻيو",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "جيڪڏهن ٻئي ان پُٽس اڻ برابر آهن تہ درست وراڻيو",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان ننڍو آهي تہ درست وراڻيو",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان ننڍو آهي يا ٻئي برابر آهن تہ درست وراڻيو",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان وڏو آهي تہ درست وراڻيو.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "جيڪڏهن پهريون ان پُٽ ٻين ان پُٽ کان وڏو آهي يا ٻئي برابر آهن تہ درست وراڻيو.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "جيڪڏهن ٻئي ان پُٽ درست آهن تہ درست وراڻيو.",
                +	"LOGIC_OPERATION_AND": "۽",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "جيڪڏهن ٻنهي ان پُٽس مان ڪو هڪ بہ درست آهي تہ درست وراڻيو.",
                +	"LOGIC_OPERATION_OR": "يا",
                +	"LOGIC_NEGATE_TITLE": "نڪي %1",
                +	"LOGIC_NEGATE_TOOLTIP": "ان پُٽ غير درست آهي تہ درست وراڻيو. ان پُٽ درست آهي تہ غير درست وراڻيو.",
                +	"LOGIC_BOOLEAN_TRUE": "سچ",
                +	"LOGIC_BOOLEAN_FALSE": "ڪُوڙ",
                +	"LOGIC_BOOLEAN_TOOLTIP": "درست يا غير درست وراڻي ٿو.",
                +	"LOGIC_TERNARY_CONDITION": "پرک (ٽيسٽ)",
                +	"LOGIC_TERNARY_IF_TRUE": "جيڪڏهن سچو",
                +	"LOGIC_TERNARY_IF_FALSE": "جيڪڏهن ڪوڙو",
                +	"MATH_NUMBER_TOOLTIP": "ڪو انگ.",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "ٻن انگن جي جوڙ اپت ڏيو.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "ٻنهي انگن جو تفاوت ڏيو.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "ٻنهي انگن جي ضرب اُپت ڏيو.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "ٻنهي انگن جي ونڊ ڏيو.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/ٻيون مول",
                +	"MATH_SINGLE_OP_ROOT": "ٻيون مول",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ڪنهن انگ جو ٻيون مول ڄاڻايو.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "ٺپ",
                +	"MATH_SINGLE_TOOLTIP_NEG": "ڪنهن انگ جو ڪاٽو ڄاڻايو.",
                +	"MATH_SINGLE_TOOLTIP_LN": "ڪنهن انگ جو قدرتي لاگ ڄاڻايو.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "ڪنهن انگ جو 10 بنيادي لاگ ڄاڻايو.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/ٽڪنڊور ڪاڄ",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/رياضياتي استقلال",
                +	"MATH_IS_EVEN": "ٻڌي آهي",
                +	"MATH_IS_ODD": "اِڪي آهي",
                +	"MATH_IS_PRIME": "مفرد آهي",
                +	"MATH_IS_WHOLE": "سڄو آهي",
                +	"MATH_IS_POSITIVE": "واڌو آهي",
                +	"MATH_IS_NEGATIVE": "ڪاٽو آهي",
                +	"MATH_IS_DIVISIBLE_BY": "سان ونڊجندڙ آهي",
                +	"MATH_CHANGE_TITLE": "%1 کي %2 سان مَٽايو",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ويڙهيو (رائونڊ اَپ)",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "هيٺ ڦيرايو (رائونڊ ڊائون)",
                +	"MATH_ONLIST_OPERATOR_SUM": "فهرست جو وچور",
                +	"MATH_ONLIST_OPERATOR_MIN": "لسٽ جو ننڍي ۾ ننڍو قدر",
                +	"MATH_ONLIST_TOOLTIP_MIN": "لسٽ ۾ ننڍي کان ننڍو قدر ڄاڻايو.",
                +	"MATH_ONLIST_OPERATOR_MAX": "لسٽ جو وڏي ۾ وڏو قدر",
                +	"MATH_ONLIST_TOOLTIP_MAX": "لسٽ ۾ وڏي کان وڏو قدر ڄاڻايو.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "لسٽ جي سراسري",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "لسٽ جو مڌيان",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "لسٽ جو مڌيان انگ ڄاڻايو.",
                +	"MATH_ONLIST_OPERATOR_MODE": "فهرست جا طريقيڪا (موڊز آف لسٽ)",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "بي ترتيب جذن جي فهرست (رينڊم آئيٽم آف لسٽ)",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "سان مواد تخليق ڪيو (ڪريئيٽ ٽيڪسٽ وِد)",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "شامل ٿيو",
                +	"TEXT_INDEXOF_TITLE": "۾ متن %1 %2 %3",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "متن ۾",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "وڏن اکرن ڏانهن",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "ننڍن اکر ڏانهن",
                +	"TEXT_PRINT_TITLE": "ڇاپيو %1",
                +	"TEXT_PRINT_TOOLTIP": "ڄاڻايل تحرير، انگ يا ڪو ٻيو قدر ڇاپيو.",
                +	"TEXT_COUNT_MESSAGE0": "ڳڻيو %1 ۾ %2",
                +	"LISTS_CREATE_EMPTY_TITLE": "خالي فهرست تخليق ڪريو",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "سان فهرست تخليق ڪيو",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "لسٽ",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "فهرست ۾ ڪا شي شامل ڪريو.",
                +	"LISTS_ISEMPTY_TITLE": "%1 خالي آهي",
                +	"LISTS_INLIST": "فهرست ۾",
                +	"LISTS_GET_INDEX_REMOVE": "هٽايو",
                +	"LISTS_GET_INDEX_FROM_END": "# آخر کان",
                +	"LISTS_GET_INDEX_FIRST": "پهريون",
                +	"LISTS_GET_INDEX_LAST": "آخري",
                +	"LISTS_GET_INDEX_RANDOM": "بي ترتيب",
                +	"LISTS_SET_INDEX_SET": "ميڙ",
                +	"LISTS_SET_INDEX_INSERT": "تي داخل ڪريو",
                +	"LISTS_SET_INDEX_INPUT_TO": "جيان",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "ڏانهن #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ڏانهن # آخر کان",
                +	"LISTS_GET_SUBLIST_END_LAST": "آخري ڏانهن",
                +	"LISTS_SORT_TITLE": "ترتيب ڏيو %1 %2 %3",
                +	"LISTS_SORT_ORDER_ASCENDING": "اُڀو (اَسينڊنگ)",
                +	"LISTS_SORT_TYPE_TEXT": "الف ب وار (الفابيٽڪ)",
                +	"PROCEDURES_DEFNORETURN_TITLE": "ڏانهن",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "ڪجھ ڪريو",
                +	"PROCEDURES_BEFORE_PARAMS": "سان:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "سان:",
                +	"PROCEDURES_DEFRETURN_RETURN": "واپس ورو",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ان پُٽس",
                +	"PROCEDURES_CREATE_DO": "تخليق ڪريو '%1'"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/shn.json b/blockly/webif/static/blockly/msg/json/shn.json
                new file mode 100644
                index 000000000..0f747e58a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/shn.json
                @@ -0,0 +1,108 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Saosukham"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "ဢၼ်",
                +	"TODAY": "မိူဝ်ႈၼႆႉ",
                +	"DUPLICATE_BLOCK": "ထုတ်ႇ",
                +	"ADD_COMMENT": "သႂ်ႇၶေႃႈၵႂၢမ်း",
                +	"REMOVE_COMMENT": "ဢဝ်ဢွၵ်ႇ ၶေႃႈၵႂၢမ်း",
                +	"EXTERNAL_INPUTS": "ၶိူင်ႈဢၼ်လုၵ်ႉတၢင်းၼွၵ်ႈၶဝ်ႈမႃး",
                +	"INLINE_INPUTS": "ၶိူင်ႈဢၼ်ၶဝ်ႈမႃးၸွမ်းလႅင်း",
                +	"DELETE_BLOCK": "မွတ်ႇပလွၵ်ႉ",
                +	"DELETE_X_BLOCKS": "မွတ်ႇပလွၵ်ႉ %1",
                +	"COLLAPSE_BLOCK": "ပလွၵ်ႉလႅဝ်",
                +	"COLLAPSE_ALL": "ပလွၵ်ႉတင်းၼမ် လႅဝ်",
                +	"EXPAND_BLOCK": "ၶႂၢၵ်ႈပလွၵ်ႉ",
                +	"EXPAND_ALL": "ၶႂၢၵ်ႈပလွၵ်ႉတင်းၼမ်",
                +	"DISABLE_BLOCK": "ဢမ်ႇၸၢင်ႈပလွၵ်ႉ",
                +	"ENABLE_BLOCK": "ၵမ်ႉထႅမ်ပၼ် ပလွၵ်ႉ",
                +	"HELP": "ၸွႆႈထႅမ်",
                +	"CHANGE_VALUE_TITLE": "လႅၵ်ႈလၢႆႈၼမ်ႉၵတ်ႉ",
                +	"NEW_VARIABLE": "လၢႆႈဢၼ်မႂ်ႇ",
                +	"NEW_VARIABLE_TITLE": "ၸိုဝ်ႈဢၼ်လၢႆႈမႂ်ႇ",
                +	"RENAME_VARIABLE": "လိုမ်ႉၶိုၼ်း ဢၼ်လၢႆႈမႂ်ႇ",
                +	"RENAME_VARIABLE_TITLE": "လိုမ်ႉၶိုၼ်း ဢၼ်လၢႆႈမႂ်ႇၸိူဝ်းၼၼ်ႉ '%1' ထိုင်",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color သီ",
                +	"COLOUR_PICKER_TOOLTIP": "လိူၵ်ႈသီ တမ်ႈတီႈ ၽႃးလႅတ်ႉ",
                +	"COLOUR_RANDOM_TITLE": "သီလၢမ်းလိမ်း",
                +	"COLOUR_RANDOM_TOOLTIP": "လိူၵ်ႈသီတမ်ႈတီႈလွၵ်းလၢမ်းလိမ်း",
                +	"COLOUR_RGB_TITLE": "ႁူမ်ႈၵိုၵ်းသီ",
                +	"COLOUR_RGB_RED": "လီင်",
                +	"COLOUR_RGB_GREEN": "ၶဵဝ်",
                +	"COLOUR_RGB_BLUE": "သွမ်ႇ",
                +	"COLOUR_RGB_TOOLTIP": "ႁဵတ်းတူၺ်း သီဢၼ်ၼိုင်ႈ ၸွမ်းၼင်ႇမၵ်းမၼ်ႈဝႆႉ ၼႂ်းၶႂၢင်ႇ သီလႅင်, ၶဵဝ် လႄႈ သွမ်ႇ။ ၼမ်ႉၼၵ်းသီ တေလႆႈမီးၼႂ်းဝူင်ႈၵၢင် 0 တေႃႇ 100.",
                +	"COLOUR_BLEND_TITLE": "လေႃးလႄး",
                +	"COLOUR_BLEND_COLOUR1": "သီ 1",
                +	"COLOUR_BLEND_COLOUR2": "သီ 2",
                +	"COLOUR_BLEND_RATIO": "သႅၼ်း",
                +	"COLOUR_BLEND_TOOLTIP": "ဢဝ်သီသွင်ဢၼ်လေႃးၵၼ် ၸွမ်းၼမ် သႅၼ်းဢၼ်ပၼ်ဝႆႉ (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop တႃႇတူင်ႇမူၼ်း",
                +	"CONTROLS_REPEAT_TITLE": "ပၼ်ႇၶိုၼ်း %1 ၵမ်း",
                +	"CONTROLS_REPEAT_INPUT_DO": "ႁဵတ်း",
                +	"CONTROLS_REPEAT_TOOLTIP": "ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ တင်းၼမ်",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ၶၢဝ်းတိုၵ်ႉလိုမ်ႉ",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "တိုၵ်ႉလိုမ်ႉထိုင်",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢၼ်ႇမႅၼ်ႈယဝ်ႉၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) ဢမ်ႇမၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ် ၵမ်ႈၽွင်ႈ",
                +	"CONTROLS_FOR_TITLE": "တႄႇဢၢၼ်ႇၵိုၵ်း %1 တေႃႇ %2 တေႃႇ %3 လူၺ်ႈ %4",
                +	"CONTROLS_FOREACH_TITLE": "တႃႇၵူႈဢၼ်ဢၼ် ၼႂ်း %1 သဵၼ်ႈမၢႆ %2",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ဢွၵ်ႇတီႈၶွပ်ႇမူၼ်း",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "သိုပ်ႇပၼ်ႇထႅင်ႈ ၶွပ်ႇမူၼ်းတၢင်ႇဢၼ်",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "ၵိုတ်းပႅတ်ႈ ၶွပ်ႇမူၼ်း ဢၼ်မီးဝႆႉ",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "ဝဵၼ်ႉဝႆႉ ၶွပ်ႇမူၼ်း ဢၼ်ၵိုတ်းၸိူဝ်ႈဝႆႉ, သေ သိုပ်ႇထႅင်ႈတၢင်ႇဢၼ်",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "ၾၢင်ႉ: ပလွၵ်ႉဢၼ်ၼႆႉ ၵူၺ်းၸႂ်ႉလူၺ်ႈတႃႇ ၶွပ်ႇမူၼ်းၵူၺ်း",
                +	"CONTROLS_IF_TOOLTIP_1": "ပေႃးဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢၼ်ႇမႅၼ်ႈယဝ်ႉၸိုင် ႁဵတ်းၶေႃႈၵဵပ်းထွၼ်ၵမ်ႈၽွင်ႈ",
                +	"CONTROLS_IF_TOOLTIP_2": "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ လိူဝ်သေၼၼ်ႉ ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်",
                +	"CONTROLS_IF_TOOLTIP_3": "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႉၼိုင်ႈ မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႆသွင်မၢၼ်ႇမႅၼ်ႈၸိုင်  ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်",
                +	"CONTROLS_IF_TOOLTIP_4": "သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ)မၢႆၼိုင်ႈ မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပလွၵ်ႉဢွၼ်တၢင်းသုတ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ လိူဝ်သေၼၼ်ႉ, သင်ဝႃႈ ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) မၢႆသွင် မၢၼ်ႇမႅၼ်ႈၸိုင် ႁဵတ်းပႅတ်ႈ ပလွၵ်ႉသွင် တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။ သင်ဝႃႈ ၵႃႈၶၼ်(ၼမ်ႉၵတ်ႉ) ဢမ်ႇမီးလွင်ႈမၢၼ်ႇမႅၼ်ႈ သင်ၸိုင် ႁဵတ်းပႅတ်ႈပလွၵ်ႉ ၵမ်းလိုမ်း တီႈၼႂ်းၶေႃႈၵဵပ်းထွၼ်တ။",
                +	"CONTROLS_IF_MSG_IF": "သင်ဝႃႈ",
                +	"CONTROLS_IF_MSG_ELSEIF": "သင်ဝႃႈ လိူဝ်သေၼၼ်ႉ",
                +	"CONTROLS_IF_MSG_ELSE": "လိူဝ်သေၼၼ်ႉ",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "သင်ဝႃႈ ပလွၵ်ႉၸိုင် သႂ်ႇပၼ်လွင်ႈတၢင်းမၼ်း တမ်ႈ",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "သႂ်ႇၵမ်းလိုၼ်း, သင်ဝႃႈ ပလွၵ်ႉၸိုင် ဢဝ်လွင်ႈတၢင်းမၼ်းတင်းသဵင်ႈ တမ်ႈ",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(ပၢႆးၼပ်ႉ)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင် မိူၼ်တၢင်ႇဢၼ်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင် ဢမ်ႇမိူၼ်တၢင်ႇဢၼ်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း မိူၼ် ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း မိူၼ် ဢမ်ႇၼၼ် ၽဵင်ႇပဵင်း ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း ယႂ်ႇလိူဝ် ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢွၼ်တၢင်း ယႂ်ႇလိူဝ် ဢမ်ႇၼၼ် ၽဵင်ႇပဵင်း ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢႆသွင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ တင်းသွင်ဢၼ် မၢၼ်ႇမႅၼ်ႈၸိုင်ၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_OPERATION_AND": "လႄႈ",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ၵမ်းလိုၼ်းသုတ်း မၢၼ်ႇမႅၼ်ႈၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_OPERATION_OR": "ဢမ်ႇၼၼ်",
                +	"LOGIC_NEGATE_TITLE": "ဢမ်ႇၸႂ်ႈ %1",
                +	"LOGIC_NEGATE_TOOLTIP": "သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ ဢမ်ႇၼႅၼ်ႈၼႃၸိုင် မႄးၶိုၼ်း ႁႂ်ႈမၢၼ်ႇမႅၼ်ႈ။ သင်ဝႃႈ ဢၼ်ၽိူမ်ႉသႂ်ႇ မၢၼ်ႇမႅၼ်ႈၸိုင် ၶိုၼ်းမူၼ်ႉမႄး ႁႂ်ႈၼႅၼ်ႈၼႃ",
                +	"LOGIC_BOOLEAN_TRUE": "မၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_BOOLEAN_FALSE": "ဢမ်ႇၼႅၼ်ႈၼႃ",
                +	"LOGIC_BOOLEAN_TOOLTIP": "မၢၼ်ႇမႅၼ်ႈလႄႈသင် ဢမ်ႇၼႅၼ်ႈၼႃလႄႈသင် ႁူၼ်ၶိုၼ်း",
                +	"LOGIC_NULL": "ဢမ်ႇၶဝ်ႈၶႂၢင်ႇ",
                +	"LOGIC_NULL_TOOLTIP": "လဵဝ်ၶိုၼ်း ဢမ်ႇၶဝ်ႈၶႂၢင်ႇ",
                +	"LOGIC_TERNARY_CONDITION": "ၸၢမ်း",
                +	"LOGIC_TERNARY_IF_TRUE": "သင်ဝႃႈ မၢၼ်ႇမႅၼ်ႈ",
                +	"LOGIC_TERNARY_IF_FALSE": "သင်ဝႃႈ ဢမ်ႇၼႅၼ်ႈၼႃ",
                +	"LOGIC_TERNARY_TOOLTIP": "ၸၢမ်းၵူတ်ႇတူၺ်း သၢႆငၢႆ။ သင်ဝႃႈ သၢႆငၢႆမၢၼ်ႇမႅၼ်ႈ, လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) 'သင်မၢၼ်ႇမႅၼ်ႈ'; လိူဝ်ၼၼ်ႉ လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) 'သင်ဢမ်ႇၼႅၼ်ႈၼႃ'။",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/မၢႆၼပ်ႉ",
                +	"MATH_NUMBER_TOOLTIP": "မၢႆၼပ်ႉ ၼိုင်ႈဢၼ်",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/ပၢႆးၼပ်ႉ",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "လဵဝ်ၶိုၼ်း တၢင်းၼမ် ၼႂ်းမၢႆၼပ်ႉ သွင်",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "လဵဝ်ၶိုၼ်း ဢၼ်ပႅၵ်ႇပိူင်ႈ ၼႂ်းမၢႆၼပ်ႉ သွင်",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "လဵဝ်ၶိုၼ်း ဢၼ်ဢဝ်ဢွၵ်ႇ ၼႂ်းမၢႆၼပ်ႉ သွင်",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "လဵဝ်ၶိုၼ်း ပမႃႇၼ ၼႂ်းမၢႆၼပ်ႉ သွင်",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "လဵဝ်ၶိုၼ်း တူဝ်ၼပ်ႉမၢႆၼိုင်ႈၼႆႉ ၸွႆႈႁႅင်းပၼ် တူဝ်ၼပ်ႉမၢႆသွင်",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root (မၢႆတူပ်ႉမိူၼ်)",
                +	"MATH_SINGLE_OP_ROOT": "မၢႆတူပ်ႉမိူၼ်",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "လဵဝ်ၶိုၼ်း မၢႆတူပ်ႉမိူၼ် ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_SINGLE_OP_ABSOLUTE": "ပၵတိ",
                +	"MATH_SINGLE_TOOLTIP_ABS": "လဵဝ်ၶိုၼ်း ၵႃႈၶၼ် (ၼမ်ႉၵတ်ႉ) ပၵတိ ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_SINGLE_TOOLTIP_NEG": "လဵဝ်ၶိုၼ်း ဢၼ်သၢၼ်ၶတ်း ၼႂ်း မၢႆၼပ်ႉ",
                +	"MATH_SINGLE_TOOLTIP_LN": "လဵဝ်ၶိုၼ်း လွၵ်းလၢႆးၼပ်ႉ ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "လဵဝ်ၶိုၼ်း ပိုၼ်ႉထၢၼ် 10 လွၵ်းလၢႆးၼပ်ႉ ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_SINGLE_TOOLTIP_EXP": "လဵဝ်ၶိုၼ်း e ၵႂႃႇတီႈ ပႃႇဝႃႇ ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_SINGLE_TOOLTIP_POW10": "လဵဝ်ၶိုၼ်း 10 ၵႂႃႇတီႈ ပႃႇဝႃႇ ၼႂ်းမၢႆၼပ်ႉ",
                +	"MATH_IS_EVEN": "ပဵၼ်ၵူပ်ႉ",
                +	"MATH_IS_ODD": "ပဵၼ်ၵိၵ်ႈ"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sk.json b/blockly/webif/static/blockly/msg/json/sk.json
                new file mode 100644
                index 000000000..499da667f
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sk.json
                @@ -0,0 +1,343 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Jaroslav.micek",
                +			"Marian.stano",
                +			"Mark",
                +			"Kusavica",
                +			"Genhis",
                +			"Lexected",
                +			"Adams",
                +			"TomášPolonec",
                +			"Pmikolas44"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "prvok",
                +	"TODAY": "Dnes",
                +	"DUPLICATE_BLOCK": "Duplikovať",
                +	"ADD_COMMENT": "Pridať komentár",
                +	"REMOVE_COMMENT": "Odstrániť komentár",
                +	"EXTERNAL_INPUTS": "Vonkajšie vstupy",
                +	"INLINE_INPUTS": "Riadkové vstupy",
                +	"DELETE_BLOCK": "Odstrániť blok",
                +	"DELETE_X_BLOCKS": "Odstrániť %1 blokov",
                +	"DELETE_ALL_BLOCKS": "Zmazať všetkých %1 dielcov?",
                +	"CLEAN_UP": "Narovnať bloky",
                +	"COLLAPSE_BLOCK": "Zvinúť blok",
                +	"COLLAPSE_ALL": "Zvinúť bloky",
                +	"EXPAND_BLOCK": "Rozvinúť blok",
                +	"EXPAND_ALL": "Rozvinúť bloky",
                +	"DISABLE_BLOCK": "Vypnúť blok",
                +	"ENABLE_BLOCK": "Povoliť blok",
                +	"HELP": "Pomoc",
                +	"UNDO": "Späť",
                +	"REDO": "Znova",
                +	"CHANGE_VALUE_TITLE": "Zmeniť hodnotu:",
                +	"RENAME_VARIABLE": "Premenovať premennú...",
                +	"RENAME_VARIABLE_TITLE": "Premenovať všetky premenné '%1' na:",
                +	"NEW_VARIABLE": "Vytvoriť premennú...",
                +	"NEW_VARIABLE_TITLE": "Názov novej premennej:",
                +	"VARIABLE_ALREADY_EXISTS": "Premenná s názvom %1 už existuje.",
                +	"PROCEDURE_ALREADY_EXISTS": "Postup s názvom '%1' už existuje.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Odstrániť %1 použití premennej '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Nie je možné zmazať premennú „%1“, lebo je súčasťou definície funkcie „%2“",
                +	"DELETE_VARIABLE": "Odstrániť premennú '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Zvoľte farbu z palety.",
                +	"COLOUR_RANDOM_TITLE": "náhodná farba",
                +	"COLOUR_RANDOM_TOOLTIP": "Zvoliť farbu náhodne.",
                +	"COLOUR_RGB_TITLE": "ofarbiť s",
                +	"COLOUR_RGB_RED": "červená",
                +	"COLOUR_RGB_GREEN": "zelená",
                +	"COLOUR_RGB_BLUE": "modrá",
                +	"COLOUR_RGB_TOOLTIP": "Vytvoriť farbu pomocou zadaného množstva červenej, zelenej a modrej. Množstvo musí byť medzi 0 a 100.",
                +	"COLOUR_BLEND_TITLE": "zmiešať",
                +	"COLOUR_BLEND_COLOUR1": "farba 1",
                +	"COLOUR_BLEND_COLOUR2": "farba 2",
                +	"COLOUR_BLEND_RATIO": "pomer",
                +	"COLOUR_BLEND_TOOLTIP": "Zmieša dve farby v danom pomere (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "opakuj %1 krát",
                +	"CONTROLS_REPEAT_INPUT_DO": "rob",
                +	"CONTROLS_REPEAT_TOOLTIP": "Opakuj určité príkazy viackrát.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "opakuj kým",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "opakuj kým nebude",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Kým je hodnota pravdivá, vykonávaj príkazy.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Kým je hodnota nepravdivá, vykonávaj príkazy.",
                +	"CONTROLS_FOR_TOOLTIP": "Nechá premennú '%1' nadobúdať hodnoty od začiatočného čísla po konečné s daným medzikrokom a vykoná zadané bloky.",
                +	"CONTROLS_FOR_TITLE": "počítať s %1 od %2 do %3 o %4",
                +	"CONTROLS_FOREACH_TITLE": "pre každý prvok %1 v zozname %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Pre každý prvok v zozname priraď jeho hodnotu do premenej '%1' a vykonaj príkazy.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "opustiť slučku",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "prejdi na nasledujúce opakovanie slučky",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Opustiť túto slučku.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Vynechať zvyšok tejto slučky a pokračovať ďalším opakovaním.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Upozornenie: Tento blok sa môže používať len v rámci slučky.",
                +	"CONTROLS_IF_TOOLTIP_1": "Ak je hodnota pravda, vykonaj príkazy.",
                +	"CONTROLS_IF_TOOLTIP_2": "Ak je hodnota pravda, vykonaj príkazy v prvom bloku. Inak vykonaj príkazy v druhom bloku.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ak je prvá hodnota pravda, vykonaj príkazy v prvom bloku. Inak, ak je druhá hodnota pravda, vykonaj príkazy v druhom bloku.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ak je prvá hodnota pravda, vykonaj príkazy v prvom bloku. Inak, ak je druhá hodnota pravda, vykonaj príkazy v druhom bloku. Ak ani jedna hodnota nie je pravda, vykonaj príkazy v poslednom bloku.",
                +	"CONTROLS_IF_MSG_IF": "ak",
                +	"CONTROLS_IF_MSG_ELSEIF": "inak ak",
                +	"CONTROLS_IF_MSG_ELSE": "inak",
                +	"CONTROLS_IF_IF_TOOLTIP": "Pridať, odstrániť alebo zmeniť poradie oddielov tohto \"ak\" bloku.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Pridať podmienku k \"ak\" bloku.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Pridať poslednú záchytnú podmienku k \"ak\" bloku.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Zrušiť",
                +	"IOS_ERROR": "Chyba",
                +	"IOS_PROCEDURES_INPUTS": "Vstupy",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Pridať vstup",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Povoľujú príkazy",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Táto funkcia obsahuje duplikáty vstupov.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Pridať premennú",
                +	"IOS_VARIABLES_ADD_BUTTON": "Pridať",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Premenovať",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Zmazať",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Názov premennej",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Nie je možné použiť premennú bez mena.",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Vráť hodnotu pravda, ak sú vstupy rovnaké.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Vráť hodnotu pravda, ak vstupy nie sú rovnaké.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Vráť hodnotu pravda, ak prvý vstup je menší než druhý.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Vráť hodnotu pravda ak prvý vstup je menší alebo rovný druhému.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Vráť hodnotu pravda ak prvý vstup je väčší než druhý.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Vráť hodnotu pravda ak prvý vstup je väčší alebo rovný druhému.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Vráť hodnotu pravda, ak sú vstupy pravdivé.",
                +	"LOGIC_OPERATION_AND": "a",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Vráť hodnotu pravda, ak je aspoň jeden vstup pravda.",
                +	"LOGIC_OPERATION_OR": "alebo",
                +	"LOGIC_NEGATE_TITLE": "nie je %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Vráti hodnotu pravda, ak je vstup nepravda. Vráti hodnotu nepravda ak je vstup pravda.",
                +	"LOGIC_BOOLEAN_TRUE": "pravda",
                +	"LOGIC_BOOLEAN_FALSE": "nepravda",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Vráť buď hodnotu pravda alebo nepravda.",
                +	"LOGIC_NULL": "nič",
                +	"LOGIC_NULL_TOOLTIP": "Vráti hodnotu nula.",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "ak pravda",
                +	"LOGIC_TERNARY_IF_FALSE": "ak nepravda",
                +	"LOGIC_TERNARY_TOOLTIP": "Skontroluj podmienku testom. Ak je podmienka pravda, vráť hodnotu \"ak pravda\", inak vráť hodnotu \"ak nepravda\".",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Číslo.",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "arccos",
                +	"MATH_TRIG_ATAN": "arctan",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Vráť súčet dvoch čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Vráť rozdiel dvoch čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Vráť súčin dvoch čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Vráť podiel dvoch čísel.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Vráť prvé číslo umocnené druhým.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "druhá odmocnina",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Vráť druhú odmocninu čísla.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolútna hodnota",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Vráť absolútnu hodnotu čísla.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Vráť opačné číslo.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Vráť prirodzený logaritmus čísla.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Vráť logaritmus čísla so základom 10.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Vráť e umocnené číslom.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Vráť 10 umocnené číslom.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Vráť sínus uhla (v stupňoch).",
                +	"MATH_TRIG_TOOLTIP_COS": "Vráť kosínus uhla (v stupňoch).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Vráť tangens uhla (v stupňoch).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Vráť arkus sínus čísla.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Vráť arkus kosínus čísla.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Vráť arkus tangens čísla.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant‎",
                +	"MATH_CONSTANT_TOOLTIP": "Vráť jednu zo zvyčajných konštánt: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), alebo ∞ (nekonečno).",
                +	"MATH_IS_EVEN": "je párne",
                +	"MATH_IS_ODD": "je nepárne",
                +	"MATH_IS_PRIME": "je prvočíslo",
                +	"MATH_IS_WHOLE": "je celé číslo",
                +	"MATH_IS_POSITIVE": "je kladné",
                +	"MATH_IS_NEGATIVE": "je záporné",
                +	"MATH_IS_DIVISIBLE_BY": "je deliteľné",
                +	"MATH_IS_TOOLTIP": "Skontroluj či je číslo párne, nepárne, celé, kladné, záporné alebo deliteľné určitým číslom. Vráť hodnotu pravda alebo nepravda.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "zmeniť %1 o %2",
                +	"MATH_CHANGE_TOOLTIP": "Pridaj číslo do premennej \"%1\".",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Zaokrúhli číslo nahor alebo nadol.",
                +	"MATH_ROUND_OPERATOR_ROUND": "zaokrúhli",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "zaokrúhli nahor",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "zaokrúhli nadol",
                +	"MATH_ONLIST_OPERATOR_SUM": "súčet zoznamu",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Vráť súčet všetkých čísel v zozname.",
                +	"MATH_ONLIST_OPERATOR_MIN": "najmenšie v zozname",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Vrátiť najmenšie číslo v zozname.",
                +	"MATH_ONLIST_OPERATOR_MAX": "najväčšie v zozname",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Vrátiť najväčšie číslo v zozname.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "priemer zoznamu",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Vráť aritmetický priemer čísel v zozname.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "medián zoznamu",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Vráť medián čísel v zozname.",
                +	"MATH_ONLIST_OPERATOR_MODE": "najčastejšie v zozname",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Vrátiť najčastejší prvok v zozname.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "smerodajná odchýlka zoznamu",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Vráť smeroddajnú odchýlku zoznamu.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "náhodný prvok zoznamu",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Vráť náhodne zvolený prvok zoznamu.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "zvyšok po delení %1 + %2",
                +	"MATH_MODULO_TOOLTIP": "Vráť zvyšok po delení jedného čísla druhým.",
                +	"MATH_CONSTRAIN_TITLE": "obmedz %1 od %2 do %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Obmedzí číslo do zadaných hraníc (vrátane).",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "náhodné celé číslo od %1 do %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Vráť náhodné celé číslo z určeného intervalu (vrátane).",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "náhodné číslo od 0 do 1",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Vráť náhodné číslo z intervalu 0.0 (vrátane) až 1.0.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Písmeno, slovo alebo riadok textu.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "vytvor text z",
                +	"TEXT_JOIN_TOOLTIP": "Vytvor text spojením určitého počtu prvkov.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "spoj",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Pridaj, odstráň alebo zmeň poradie oddielov v tomto textovom bloku.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Pridaj prvok do textu.",
                +	"TEXT_APPEND_TITLE": "k %1 pripojiť text %2",
                +	"TEXT_APPEND_TOOLTIP": "Pridaj určitý text do premennej '%1'.",
                +	"TEXT_LENGTH_TITLE": "dĺžka %1",
                +	"TEXT_LENGTH_TOOLTIP": "Vráti počet písmen (s medzerami) v zadanom texte.",
                +	"TEXT_ISEMPTY_TITLE": "%1 je prázdny",
                +	"TEXT_ISEMPTY_TOOLTIP": "Vráti hodnotu pravda, ak zadaný text je prázdny.",
                +	"TEXT_INDEXOF_TOOLTIP": "Vráti index prvého/posledného výskytu prvého textu v druhom texte. Ak nenájde, vráti %1.",
                +	"TEXT_INDEXOF_TITLE": "v texte %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "nájdi prvý výskyt textu",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "nájdi posledný výskyt textu",
                +	"TEXT_CHARAT_TITLE": "v texte %1 %2",
                +	"TEXT_CHARAT_FROM_START": "zisti písmeno #",
                +	"TEXT_CHARAT_FROM_END": "zisti # písmeno od konca",
                +	"TEXT_CHARAT_FIRST": "zisti prvé písmeno",
                +	"TEXT_CHARAT_LAST": "zisti posledné písmeno",
                +	"TEXT_CHARAT_RANDOM": "vyber náhodné písmeno",
                +	"TEXT_CHARAT_TOOLTIP": "Vráti písmeno na určenej pozícii.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Vráti určenú časť textu.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "v texte",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "vyber podreťazec od písmena #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "vyber podreťazec od # písmena od konca",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "vyber podreťazec od začiatku",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "po písmeno #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "po # písmeno od konca",
                +	"TEXT_GET_SUBSTRING_END_LAST": "po koniec",
                +	"TEXT_CHANGECASE_TOOLTIP": "Vráť kópiu textu s inou veľkosťou písmen.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "na VEĽKÉ PÍSMENÁ",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "na malé písmená",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "na Veľké Začiatočné Písmená",
                +	"TEXT_TRIM_TOOLTIP": "Vráť kópiu textu bez medzier na jednom alebo oboch koncoch.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "odstráň medzery z oboch strán",
                +	"TEXT_TRIM_OPERATOR_LEFT": "odstráň medzery z ľavej strany",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "odstráň medzery z pravej strany",
                +	"TEXT_PRINT_TITLE": "píš %1",
                +	"TEXT_PRINT_TOOLTIP": "Napíš zadaný text, číslo alebo hodnotu.",
                +	"TEXT_PROMPT_TYPE_TEXT": "výzva za zadanie textu so správou",
                +	"TEXT_PROMPT_TYPE_NUMBER": "výzva na zadanie čísla so správou",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Výzva pre používateľa na zadanie čísla.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Výzva pre používateľa na zadanie textu.",
                +	"TEXT_COUNT_MESSAGE0": "počet výskytov %1 v %2",
                +	"TEXT_COUNT_TOOLTIP": "Počet výskytov textu nachádzajúcom sa v inom texte.",
                +	"TEXT_REPLACE_MESSAGE0": "zameniť %1 za %2 v reťazci %3",
                +	"TEXT_REPLACE_TOOLTIP": "Zameniť všetky výskyty textu za iný text.",
                +	"TEXT_REVERSE_MESSAGE0": "text odzadu %1",
                +	"TEXT_REVERSE_TOOLTIP": "Obrátiť poradie písmen v texte.",
                +	"LISTS_CREATE_EMPTY_TITLE": "prázdny zoznam",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Vráti zoznam nulovej dĺžky, ktorý neobsahuje žiadne prvky.",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Vytvor zoznam s ľubovoľným počtom prvkov.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "vytvor zoznam s",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "zoznam",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Pridaj, odstráň alebo zmeň poradie v tomto zoznamovom bloku.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Pridaj prvok do zoznamu.",
                +	"LISTS_REPEAT_TOOLTIP": "Vytvorí zoznam s niekoľkými rovnakými prvkami s danou hodnotou.",
                +	"LISTS_REPEAT_TITLE": "vytvor zoznam s prvkom %1 opakovaným %2 krát",
                +	"LISTS_LENGTH_TITLE": "dĺžka %1",
                +	"LISTS_LENGTH_TOOLTIP": "Vráti dĺžku zoznamu",
                +	"LISTS_ISEMPTY_TITLE": "%1 je prázdny",
                +	"LISTS_ISEMPTY_TOOLTIP": "Vráti pravda, ak je zoznam prázdny.",
                +	"LISTS_INLIST": "v zozname",
                +	"LISTS_INDEX_OF_FIRST": "nájdi prvý výskyt prvku",
                +	"LISTS_INDEX_OF_LAST": "nájdi posledný výskyt prvku",
                +	"LISTS_INDEX_OF_TOOLTIP": "Vráti index prvého/posledného výskytu prvku v zozname. Ak sa nič nenašlo, vráti %1.",
                +	"LISTS_GET_INDEX_GET": "zisti",
                +	"LISTS_GET_INDEX_GET_REMOVE": "zisti a odstráň",
                +	"LISTS_GET_INDEX_REMOVE": "odstráň",
                +	"LISTS_GET_INDEX_FROM_END": "# od konca",
                +	"LISTS_GET_INDEX_FIRST": "prvý",
                +	"LISTS_GET_INDEX_LAST": "posledný",
                +	"LISTS_GET_INDEX_RANDOM": "náhodný",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 je počiatočný prvok.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 je posledný prvok.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Vráti prvok na určenej pozícii v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Vráti počiatočný prvok zoznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Vráti posledný prvok zoznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Vráti náhodný prvok zoznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Odstráni a vráti prvok z určenej pozície v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Odstráni a vráti prvý prvok v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Odstráni a vráti posledný prvok v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Odstráni a vráti náhodný prvok v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Odstráni prvok na určenej pozícii v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Odstráni prvý prvok v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Odstráni posledný prvok v zozname.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Odstráni náhodný prvok v zozname.",
                +	"LISTS_SET_INDEX_SET": "nastaviť",
                +	"LISTS_SET_INDEX_INSERT": "vložiť na",
                +	"LISTS_SET_INDEX_INPUT_TO": "ako",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Nastaví prvok na určenej pozícii v zozname.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Nastaví prvý prvok v zozname.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Nastaví posledný prvok v zozname.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Nastaví posledný prvok v zozname.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Vsunie prvok na určenú pozíciu v zozname.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Vsunie prvok na začiatok zoznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Pripojí prvok na koniec zoznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Vsunie prvok na náhodné miesto v zozname.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "získať podzoznam od #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "Získať podzoznam od # od konca",
                +	"LISTS_GET_SUBLIST_START_FIRST": "Získať podzoznam od začiatku",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "po #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "po # od konca",
                +	"LISTS_GET_SUBLIST_END_LAST": "po koniec",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Skopíruje určený úsek zoznamu.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "zoradiť %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Zoradiť kópiu zoznamu.",
                +	"LISTS_SORT_ORDER_ASCENDING": "Vzostupne",
                +	"LISTS_SORT_ORDER_DESCENDING": "Zostupne",
                +	"LISTS_SORT_TYPE_NUMERIC": "numericky",
                +	"LISTS_SORT_TYPE_TEXT": "abecedne",
                +	"LISTS_SORT_TYPE_IGNORECASE": "abecedne, ignorovať veľkosť písmen",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "vytvoriť zoznam z textu",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "vytvoriť text zo zoznamu",
                +	"LISTS_SPLIT_WITH_DELIMITER": "s oddeľovačom",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Rozdelenie textu do zoznamu textov, lámanie na oddeľovačoch.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Spojiť zoznam textov do jedného textu s oddeľovačmi.",
                +	"VARIABLES_GET_TOOLTIP": "Vráti hodnotu tejto premennej.",
                +	"VARIABLES_GET_CREATE_SET": "Vytvoriť \"nastaviť %1\"",
                +	"VARIABLES_SET": "nastaviť %1 na %2",
                +	"VARIABLES_SET_TOOLTIP": "Nastaví túto premennú, aby sa rovnala vstupu.",
                +	"VARIABLES_SET_CREATE_GET": "Vytvoriť \"získať %1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "na",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "urob niečo",
                +	"PROCEDURES_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "s:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Vytvorí funciu bez výstupu.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Doplň, čo robí táto funkcia...",
                +	"PROCEDURES_DEFRETURN_RETURN": "vrátiť",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Vytvorí funkciu s výstupom.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "povoliť príkazy",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Upozornenie: Táto funkcia má duplicitné parametre.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://sk.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Spustí používateľom definovanú funkciu '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://sk.wikipedia.org/wiki/Podprogram",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Spustí používateľom definovanú funkciu '%1' a použije jej výstup.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "vstupy",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Pridať, odstrániť alebo zmeniť poradie vstupov tejto funkcie.",
                +	"PROCEDURES_MUTATORARG_TITLE": "názov vstupu:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Pridať vstup do funkcie.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Zvýrazniť definíciu funkcie",
                +	"PROCEDURES_CREATE_DO": "Vytvoriť '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Ak je hodnota pravda, tak vráti druhú hodnotu.",
                +	"PROCEDURES_IFRETURN_WARNING": "Upozornenie: Tento blok môže byť len vo vnútri funkcie."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sl.json b/blockly/webif/static/blockly/msg/json/sl.json
                new file mode 100644
                index 000000000..b553f90e4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sl.json
                @@ -0,0 +1,364 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Anzeljg",
                +			"Miloš Košir",
                +			"Dbc334",
                +			"HairyFotr"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "element",
                +	"TODAY": "Danes",
                +	"DUPLICATE_BLOCK": "Podvoji",
                +	"ADD_COMMENT": "Dodaj komentar",
                +	"REMOVE_COMMENT": "Odstrani komentar",
                +	"EXTERNAL_INPUTS": "Vnosi zunaj",
                +	"INLINE_INPUTS": "Vnosi v vrsti",
                +	"DELETE_BLOCK": "Izbriši kocko",
                +	"DELETE_X_BLOCKS": "Izbriši kocke",
                +	"DELETE_ALL_BLOCKS": "Izbrišem vseh %1 kock?",
                +	"CLEAN_UP": "Ponastavi kocke",
                +	"COLLAPSE_BLOCK": "Skrči kocko",
                +	"COLLAPSE_ALL": "Skrči kocke",
                +	"EXPAND_BLOCK": "Razširi kocko",
                +	"EXPAND_ALL": "Razširi kocke",
                +	"DISABLE_BLOCK": "Onemogoči kocko",
                +	"ENABLE_BLOCK": "Omogoči kocko",
                +	"HELP": "Pomoč",
                +	"UNDO": "Razveljavi",
                +	"REDO": "Ponovi",
                +	"CHANGE_VALUE_TITLE": "Spremeni vrednost:",
                +	"RENAME_VARIABLE": "Preimenuj spremenljivko...",
                +	"RENAME_VARIABLE_TITLE": "Preimenuj vse spremenljivke '%1' v:",
                +	"NEW_VARIABLE": "Ustvari spremenljivko ...",
                +	"NEW_VARIABLE_TITLE": "Ime nove spremenljivke:",
                +	"VARIABLE_ALREADY_EXISTS": "Spremenljivka »%1« že obstaja.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Izbrišem %1 uporab spremenljivke »%2«?",
                +	"DELETE_VARIABLE": "Izbriši spremenljivko »%1«",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Izberi barvo s palete.",
                +	"COLOUR_RANDOM_TITLE": "naključna barva",
                +	"COLOUR_RANDOM_TOOLTIP": "Izbere naključno barvo.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "določena barva",
                +	"COLOUR_RGB_RED": "rdeča",
                +	"COLOUR_RGB_GREEN": "zelena",
                +	"COLOUR_RGB_BLUE": "modra",
                +	"COLOUR_RGB_TOOLTIP": "Ustvari barvo z določeno količino rdeče, zelene in modre. Vse vrednosti morajo biti med 0 in 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "mešanica",
                +	"COLOUR_BLEND_COLOUR1": "barva 1",
                +	"COLOUR_BLEND_COLOUR2": "barva 2",
                +	"COLOUR_BLEND_RATIO": "razmerje",
                +	"COLOUR_BLEND_TOOLTIP": "Zmeša dve barvi v danem razmerju (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "ponavljaj %1 krat",
                +	"CONTROLS_REPEAT_INPUT_DO": "izvedi",
                +	"CONTROLS_REPEAT_TOOLTIP": "Kocke se izvedejo večkrat.",
                +	"CONTROLS_WHILEUNTIL_HELPURL": "https://github.com/google/blockly/wiki/Loops#repeat",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ponavljaj",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ponavljaj dokler",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Kocke se izvajajo dokler je vrednost resnična.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Kocke se izvajajo dokler je vrednost neresnična.",
                +	"CONTROLS_FOR_HELPURL": "https://github.com/google/blockly/wiki/Loops#count-with",
                +	"CONTROLS_FOR_TOOLTIP": "Vrednost spremenljivke '%1' se spreminja od začetnega števila do končnega števila, z določenim korakom. Pri tem se izvedejo določene kocke.",
                +	"CONTROLS_FOR_TITLE": "štej s/z %1 od %2 do %3 s korakom %4",
                +	"CONTROLS_FOREACH_HELPURL": "https://github.com/google/blockly/wiki/Loops#for-each",
                +	"CONTROLS_FOREACH_TITLE": "za vsak element %1 v seznamu %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Za vsak element v seznamu, nastavi spremenljivko '%1' na ta element. Pri tem se izvedejo določene kocke.",
                +	"CONTROLS_FLOW_STATEMENTS_HELPURL": "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "izstopi iz zanke",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "nadaljuj z naslednjo ponovitvijo zanke",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Izstopi iz trenutne zanke.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Preskoči preostanek te zanke in nadaljuje z naslednjo ponovitvijo.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Pozor: To kocko lahko uporabiš samo znotraj zanke.",
                +	"CONTROLS_IF_HELPURL": "https://github.com/google/blockly/wiki/IfElse",
                +	"CONTROLS_IF_TOOLTIP_1": "Če je vrednost resnična, izvedi določene kocke.",
                +	"CONTROLS_IF_TOOLTIP_2": "Če je vrednost resnična, izvedi prvo skupino kock. Sicer izvedi drugo skupino kock.",
                +	"CONTROLS_IF_TOOLTIP_3": "Če je prva vrednost resnična, izvedi prvo skupino kock. Sicer, če je resnična druga vrednost, izvedi drugo skupino kock.",
                +	"CONTROLS_IF_TOOLTIP_4": "Če je prva vrednost resnična, izvedi prvo skupino kock. Sicer, če je resnična druga vrednost, izvedi drugo skupino kock. Če nobena izmed vrednosti ni resnična, izvedi zadnjo skupino kock.",
                +	"CONTROLS_IF_MSG_IF": "če",
                +	"CONTROLS_IF_MSG_ELSEIF": "sicer če",
                +	"CONTROLS_IF_MSG_ELSE": "sicer",
                +	"CONTROLS_IF_IF_TOOLTIP": "Dodaj, odstrani ali spremeni vrstni red odsekov za ponovno nastavitev »če« kocke.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Dodaj pogoj »če« kocki.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Dodaj končni pogoj »če« kocki.",
                +	"IOS_OK": "V redu",
                +	"IOS_CANCEL": "Prekliči",
                +	"IOS_ERROR": "Napaka",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Ime spremenljivke",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Vrne resnično, če sta vnosa enaka.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Vrne resnično, če vnosa nista enaka.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Vrne resnično, če je prvi vnos manjši od drugega.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Vrne resnično, če je prvi vnos manjši ali enak drugemu.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Vrne resnično, če je prvi vnos večji od drugega.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Vrne resnično, če je prvi vnos večji ali enak drugemu.",
                +	"LOGIC_OPERATION_HELPURL": "https://github.com/google/blockly/wiki/Logic#logical-operations",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Vrne resnično, če sta oba vnosa resnična.",
                +	"LOGIC_OPERATION_AND": "in",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Vrne resnično, če je vsaj eden od vnosov resničen.",
                +	"LOGIC_OPERATION_OR": "ali",
                +	"LOGIC_NEGATE_HELPURL": "https://github.com/google/blockly/wiki/Logic#not",
                +	"LOGIC_NEGATE_TITLE": "ne %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Vrne resnično, če je vnos neresničen. Vrne neresnično, če je vnos resničen.",
                +	"LOGIC_BOOLEAN_HELPURL": "https://github.com/google/blockly/wiki/Logic#values",
                +	"LOGIC_BOOLEAN_TRUE": "resnično",
                +	"LOGIC_BOOLEAN_FALSE": "neresnično",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Vrne resnično ali neresnično.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "prazno",
                +	"LOGIC_NULL_TOOLTIP": "Vrne prazno.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "če resnično",
                +	"LOGIC_TERNARY_IF_FALSE": "če neresnično",
                +	"LOGIC_TERNARY_TOOLTIP": "Preveri pogoj v »testu«. Če je pogoj resničen, potem vrne vrednost »če resnično«; sicer vrne vrednost »če neresnično«.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Število.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Vrne vsoto dveh števil.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Vrne razliko dveh števil.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Vrne zmnožek dveh števil.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Vrne kvocient dveh števil.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Vrne prvo število na potenco drugega števila.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "kvadratni koren",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Vrne kvadratni koren števila.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolutno",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Vrne absolutno vrednost števila.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Vrne negacijo števila.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Vrne naravni logaritem števila.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Vrne desetiški logaritem števila.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Vrne e na potenco števila.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Vrne 10 na potenco števila.",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Vrne sinus kota v stopinjah (ne radianih).",
                +	"MATH_TRIG_TOOLTIP_COS": "Vrne kosinus kota v stopinjah (ne radianih).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Vrne tangens kota v stopinjah (ne radianih).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Vrne arkus sinus števila.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Vrne arkus kosinus števila.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Vrne arkus tangens števila.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Vrne eno izmed običajnih konstant: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), ali ∞ (neskončno).",
                +	"MATH_IS_EVEN": "je sodo",
                +	"MATH_IS_ODD": "je liho",
                +	"MATH_IS_PRIME": "je praštevilo",
                +	"MATH_IS_WHOLE": "je celo",
                +	"MATH_IS_POSITIVE": "je pozitivno",
                +	"MATH_IS_NEGATIVE": "je negativno",
                +	"MATH_IS_DIVISIBLE_BY": "je deljivo s/z",
                +	"MATH_IS_TOOLTIP": "Preveri, če je število sodo, liho, praštevilo, celo, pozitivno, negativno ali, če je deljivo z določenim številom. Vrne resnično ali neresnično.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "spremeni %1 za %2",
                +	"MATH_CHANGE_TOOLTIP": "Prišteje število k spremenljivki '%1'.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Zaokroži število navzgor ali navzdol.",
                +	"MATH_ROUND_OPERATOR_ROUND": "zaokroži",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "zaokroži navzgor",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "zaokroži navzdol",
                +	"MATH_ONLIST_OPERATOR_SUM": "vsota seznama",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Vrne vsoto vseh števil na seznamu.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minimum seznama",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Vrne najmanjše število na seznamu.",
                +	"MATH_ONLIST_OPERATOR_MAX": "maksimum seznama",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Vrne največje število na seznamu.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "povprečje seznama",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Vrne povprečje (aritmetično sredino) števil na seznamu.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana seznama",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Vrne mediano števil na seznamu.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modus seznama",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Vrne seznam najpogostejšega elementa(-ov) na seznamu.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standardni odklon seznama",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Vrne standardni odklon seznama.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "naključni element seznama",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Vrne naključno število izmed števil na seznamu.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "ostanek pri %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Vrne ostanek pri deljenju dveh števil.",
                +	"MATH_CONSTRAIN_HELPURL": "https://en.wikipedia.org/wiki/Clamping_%28graphics%29",
                +	"MATH_CONSTRAIN_TITLE": "omeji %1 na najmanj %2 in največ %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Omeji število, da bo med določenima (vključenima) mejama.",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "naključno število med %1 in %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Vrne naključno število med dvema določenima mejama, vključno z mejama.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "naključni ulomek",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Vrne naključni ulomek med (vključno) 0.0 in 1.0 (izključno).",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Črka, beseda ali vrstica besedila.",
                +	"TEXT_JOIN_HELPURL": "https://github.com/google/blockly/wiki/Text#text-creation",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ustvari besedilo iz",
                +	"TEXT_JOIN_TOOLTIP": "Ustvari besedilo tako, da združi poljubno število elementov.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "združi",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Doda, odstrani ali spremeni vrstni red elementov tega besedila.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Doda element k besedilu.",
                +	"TEXT_APPEND_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_APPEND_TOOLTIP": "Doda besedilo k spremenljivki '%1'.",
                +	"TEXT_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Text#text-modification",
                +	"TEXT_LENGTH_TITLE": "dolžina %1",
                +	"TEXT_LENGTH_TOOLTIP": "Vrne število črk oz. znakov (vključno s presledki) v določenem besedilu.",
                +	"TEXT_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Text#checking-for-empty-text",
                +	"TEXT_ISEMPTY_TITLE": "%1 je prazno",
                +	"TEXT_ISEMPTY_TOOLTIP": "Vrne resnično, če je določeno besedilo prazno.",
                +	"TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text",
                +	"TEXT_INDEXOF_TOOLTIP": "Vrne mesto (indeks) prve/zadnje pojavitve drugega besedila v prvem besedilu. Če besedila ne najde, vrne %1.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "najdi prvo pojavitev besedila",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "najdi zadnjo pojavitev besedila",
                +	"TEXT_CHARAT_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-text",
                +	"TEXT_CHARAT_FROM_START": "vrni črko št.",
                +	"TEXT_CHARAT_FROM_END": "vrni črko št. od konca",
                +	"TEXT_CHARAT_FIRST": "vrni prvo črko",
                +	"TEXT_CHARAT_LAST": "vrni zadnjo črko",
                +	"TEXT_CHARAT_RANDOM": "vrni naključno črko",
                +	"TEXT_CHARAT_TOOLTIP": "Vrne črko na določenem mestu v besedilu.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Vrne določen del besedila.",
                +	"TEXT_GET_SUBSTRING_HELPURL": "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "iz besedila",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "vrni del od črke št.",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "vrni del od črke št. od konca",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "vrni del od prve črke",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "do črke št.",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "do črke št. od konca",
                +	"TEXT_GET_SUBSTRING_END_LAST": "do zadnje črke",
                +	"TEXT_CHANGECASE_HELPURL": "https://github.com/google/blockly/wiki/Text#adjusting-text-case",
                +	"TEXT_CHANGECASE_TOOLTIP": "Vrne kopijo besedila v drugi obliki.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "v VELIKE ČRKE",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "v male črke",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "v Velike Začetnice",
                +	"TEXT_TRIM_HELPURL": "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces",
                +	"TEXT_TRIM_TOOLTIP": "Vrne kopijo besedila z odstranjenimi presledki z ene ali obeh strani.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "odstrani presledke z obeh strani",
                +	"TEXT_TRIM_OPERATOR_LEFT": "odstrani presledke z leve strani",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "odstrani presledke z desne strani",
                +	"TEXT_PRINT_HELPURL": "https://github.com/google/blockly/wiki/Text#printing-text",
                +	"TEXT_PRINT_TITLE": "izpiši %1",
                +	"TEXT_PRINT_TOOLTIP": "Izpiše določeno besedilo, število ali drugo vrednost.",
                +	"TEXT_PROMPT_HELPURL": "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user",
                +	"TEXT_PROMPT_TYPE_TEXT": "vprašaj za besedilo s sporočilom",
                +	"TEXT_PROMPT_TYPE_NUMBER": "vprašaj za število s sporočilom",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Vpraša uporabnika za vnos števila.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Vpraša uporabnika za vnos besedila.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "ustvari prazen seznam",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Vrne seznam, dolžine 0, ki ne vsebuje nobenih podatkov.",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Ustvari seznam s poljubnim številom elementov.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "ustvari seznam s/z",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "seznam",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Doda, odstrani ali spremeni vrstni red elementov tega seznama.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Doda element seznamu.",
                +	"LISTS_REPEAT_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_REPEAT_TOOLTIP": "Ustvari seznam z danim elementom, ki se poljubno mnogo krat ponovi.",
                +	"LISTS_REPEAT_TITLE": "ustvari seznam z elementom %1, ki se ponovi %2 krat",
                +	"LISTS_LENGTH_HELPURL": "https://github.com/google/blockly/wiki/Lists#length-of",
                +	"LISTS_LENGTH_TITLE": "dolžina %1",
                +	"LISTS_LENGTH_TOOLTIP": "Vrne dolžino seznama.",
                +	"LISTS_ISEMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#is-empty",
                +	"LISTS_ISEMPTY_TITLE": "%1 je prazen",
                +	"LISTS_ISEMPTY_TOOLTIP": "Vrne resnično, če je seznam prazen.",
                +	"LISTS_INLIST": "v seznamu",
                +	"LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list",
                +	"LISTS_INDEX_OF_FIRST": "najdi prvo pojavitev elementa",
                +	"LISTS_INDEX_OF_LAST": "najdi zadnjo pojavitev elementa",
                +	"LISTS_INDEX_OF_TOOLTIP": "Vrne mesto (indeks) prve/zadnje pojavitve elementa v seznamu. Če elementa ne najde, vrne %1.",
                +	"LISTS_GET_INDEX_GET": "vrni",
                +	"LISTS_GET_INDEX_GET_REMOVE": "odstrani in vrni",
                +	"LISTS_GET_INDEX_REMOVE": "odstrani",
                +	"LISTS_GET_INDEX_FROM_START": "št.",
                +	"LISTS_GET_INDEX_FROM_END": "mesto št. od konca",
                +	"LISTS_GET_INDEX_FIRST": "prvo mesto",
                +	"LISTS_GET_INDEX_LAST": "zadnje mesto",
                +	"LISTS_GET_INDEX_RANDOM": "naključno mesto",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "Prvi element je št. %1.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "Zadnji element je št. %1.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Vrne element na določenem mestu v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Vrne prvi element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Vrne zadnji element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Vrne naključni element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Odstrani in vrne element na določenem mestu v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Odstrani in vrne prvi element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Odstrani in vrne zadnji element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Odstrani in vrne naključni element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Odstrani element na določenem mestu v seznamu.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Odstrani prvi element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Odstrani zadnji element seznama.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Odstrani naključni element seznama.",
                +	"LISTS_SET_INDEX_HELPURL": "https://github.com/google/blockly/wiki/Lists#in-list--set",
                +	"LISTS_SET_INDEX_SET": "nastavi na",
                +	"LISTS_SET_INDEX_INSERT": "vstavi na",
                +	"LISTS_SET_INDEX_INPUT_TO": "element",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Nastavi element na določenem mestu v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Nastavi prvi element seznama.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Nastavi zadnji element seznama.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Nastavi naključni element seznama.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Vstavi element na določeno mesto v seznamu.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Vstavi element na začetek seznama.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Doda element na konec seznama.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Vstavi element na naključno mesto v seznamu.",
                +	"LISTS_GET_SUBLIST_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-a-sublist",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "ustvari podseznam od mesta št.",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "ustvari podseznam od mesta št. od konca",
                +	"LISTS_GET_SUBLIST_START_FIRST": "ustvari podseznam od prvega mesta",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "do mesta št.",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "do mesta št. od konca",
                +	"LISTS_GET_SUBLIST_END_LAST": "do zadnjega mesta",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Ustvari nov seznam, kot kopijo določenega dela seznama.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "uredi %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Uredi kopijo seznama.",
                +	"LISTS_SORT_ORDER_ASCENDING": "naraščajoče",
                +	"LISTS_SORT_ORDER_DESCENDING": "padajoče",
                +	"LISTS_SORT_TYPE_NUMERIC": "številčno",
                +	"LISTS_SORT_TYPE_TEXT": "abecedno",
                +	"LISTS_SORT_TYPE_IGNORECASE": "abecedno, brez velikosti črk",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "ustvari seznam iz besedila",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "ustvari besedilo iz seznama",
                +	"LISTS_SPLIT_WITH_DELIMITER": "z ločilom",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Razdruži besedilo v seznam besedil. Za razdruževanje besedila uporabi ločilo.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Združi seznam besedil v eno besedilo, ločeno z ločilom.",
                +	"VARIABLES_GET_HELPURL": "https://github.com/google/blockly/wiki/Variables#get",
                +	"VARIABLES_GET_TOOLTIP": "Vrne vrednost spremenljivke.",
                +	"VARIABLES_GET_CREATE_SET": "Ustvari 'nastavi %1'",
                +	"VARIABLES_SET_HELPURL": "https://github.com/google/blockly/wiki/Variables#set",
                +	"VARIABLES_SET": "nastavi %1 na %2",
                +	"VARIABLES_SET_TOOLTIP": "Nastavi, da je vrednost spremenljivke enaka vnosu.",
                +	"VARIABLES_SET_CREATE_GET": "Ustvari 'vrni %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "izvedi",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "nekaj",
                +	"PROCEDURES_BEFORE_PARAMS": "s/z:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "s/z:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Ustvari funkcijo brez izhoda.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Opišite funkcijo ...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "vrni",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Ustvari funkcijo z izhodom.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "dovoli korake",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Pozor: Ta funkcija ima podvojene parametre.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Izvede uporabniško funkcijo '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Izvede uporabniško funkcijo '%1' in uporabi njen izhod.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "vnosi",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Doda, odstrani ali spremeni vrstni red vnosov te funkcije.",
                +	"PROCEDURES_MUTATORARG_TITLE": "ime vnosa:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Funkciji doda vnos.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Označi definicijo funkcije",
                +	"PROCEDURES_CREATE_DO": "Ustvari '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Če je vrednost resnična, vrne drugo vrednost.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Pozor: To kocko lahko uporabiš samo znotraj definicije funkcije."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sq.json b/blockly/webif/static/blockly/msg/json/sq.json
                new file mode 100644
                index 000000000..ba01408be
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sq.json
                @@ -0,0 +1,323 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"아라",
                +			"Liridon",
                +			"Arianit"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "send",
                +	"TODAY": "Sot",
                +	"DUPLICATE_BLOCK": "Kopjo",
                +	"ADD_COMMENT": "Vendos nje Koment",
                +	"REMOVE_COMMENT": "Fshij komentin",
                +	"EXTERNAL_INPUTS": "Hyrjet e jashtme",
                +	"INLINE_INPUTS": "Hyrjet e brendshme",
                +	"DELETE_BLOCK": "Fshij bllokun",
                +	"DELETE_X_BLOCKS": "Fshij %1 blloqe",
                +	"DELETE_ALL_BLOCKS": "Fshijë të gjitha %1 të blloqeve?",
                +	"CLEAN_UP": "Pastro blloqet",
                +	"COLLAPSE_BLOCK": "Mbyll bllokun",
                +	"COLLAPSE_ALL": "Mbyll blloqet",
                +	"EXPAND_BLOCK": "Zmadho bllokun",
                +	"EXPAND_ALL": "Zmadho blloqet",
                +	"DISABLE_BLOCK": "Çaktivizo bllokun",
                +	"ENABLE_BLOCK": "Aktivizo bllokun",
                +	"HELP": "Ndihmë",
                +	"UNDO": "Zhbëj",
                +	"REDO": "Ribëj",
                +	"CHANGE_VALUE_TITLE": "Ndrysho Vlerat:",
                +	"RENAME_VARIABLE": "Ndrysho emrin variables...",
                +	"RENAME_VARIABLE_TITLE": "Ndrysho emrin e te gjitha '%1' variablave ne :",
                +	"NEW_VARIABLE": "Krijo variabël...",
                +	"NEW_VARIABLE_TITLE": "Emri i identifikatorit të ri:",
                +	"VARIABLE_ALREADY_EXISTS": "Një variabël e quajtur '%1' tashmë ekziston.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Fshi përdorimin %1 të variablës '%2'?",
                +	"DELETE_VARIABLE": "Fshi variablën '%1'",
                +	"COLOUR_PICKER_HELPURL": "http://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "Zgjidh nje ngjyre nga nje game ngjyrash.",
                +	"COLOUR_RANDOM_TITLE": "ngjyre e rastesishme",
                +	"COLOUR_RANDOM_TOOLTIP": "Zgjidhni një ngjyrë në mënyrë të rastësishme.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "ngjyre me",
                +	"COLOUR_RGB_RED": "e kuqe",
                +	"COLOUR_RGB_GREEN": "jeshile",
                +	"COLOUR_RGB_BLUE": "blu",
                +	"COLOUR_RGB_TOOLTIP": "Krijo një ngjyrë me shumën e specifikuar te te kuqes, te gjelbëres, dhe bluse. Te gjitha vlerat duhet te jene mes 0 dhe 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "Përzierje",
                +	"COLOUR_BLEND_COLOUR1": "Ngjyra 1",
                +	"COLOUR_BLEND_COLOUR2": "Ngjyra 2",
                +	"COLOUR_BLEND_RATIO": "Perpjesetim",
                +	"COLOUR_BLEND_TOOLTIP": "Perzien dy ngjyra së bashku me një raport të dhënë (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "http://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "përsërit %1 herë",
                +	"CONTROLS_REPEAT_INPUT_DO": "ekzekuto",
                +	"CONTROLS_REPEAT_TOOLTIP": "Ekzekuto disa fjali disa herë.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "përsërit përderisa",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "përsërit derisa",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Përderisa një vlerë është e saktë, atëherë ekzekuto disa fjali.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Përderisa një vlerë është e pasaktë, atëherë ekzekuto disa fjali.",
                +	"CONTROLS_FOR_TOOLTIP": "Bëje identifikuesin \"%1\" që ta ketë vlerat prej numrit të fillimit deri tek numri i fundit, duke numëruar nga intervali i specifikuar, dhe ti bëj blloqet e specifikuara.",
                +	"CONTROLS_FOR_TITLE": "numero me %1 nga %2 ne %3 me nga %4",
                +	"CONTROLS_FOREACH_TITLE": "per cdo produkt %1 ne liste %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Per cdo produkt ne nje \"liste\" \"vendos\" ndryshoren '%1' produktit, dhe pastaj bej disa deklarata.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "dil nga nje faze perseritese",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "vazhdo me elementin tjeter te nje faze perseritese",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Ndahu nga unaza.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Kapërce pjesën e mbetur të unazës, dhe vazhdo me ripërsëritjen tjetër.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Paralajmërim: Ky bllok mund të përdoret vetëm brenda unazës.",
                +	"CONTROLS_IF_TOOLTIP_1": "Nëse një vlerë është e saktë, atëherë ekzekuto disa fjali.",
                +	"CONTROLS_IF_TOOLTIP_2": "Nëse një vlerë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, ekzekuto bllokun e dytë të fjalive.",
                +	"CONTROLS_IF_TOOLTIP_3": "Nëse vlera e parë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, nëse vlera e dytë është e saktë, ekzekuto bllokun e dytë të fjalive.",
                +	"CONTROLS_IF_TOOLTIP_4": "Nëse vlera e parë është e saktë, atëherë ekzekuto bllokun e parë të fjalive. Përndryshe, nëse vlera e dytë është e saktë, ekzekuto bllokun e dytë të fjalive. Nëse asnjëra nga vlerat nuk është e saktë, ekzekuto bllokun e fundit të fjalive.",
                +	"CONTROLS_IF_MSG_IF": "nëse",
                +	"CONTROLS_IF_MSG_ELSEIF": "përndryshe nëse",
                +	"CONTROLS_IF_MSG_ELSE": "përndryshe",
                +	"CONTROLS_IF_IF_TOOLTIP": "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këte bllok nëse.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "\"Vendos\" \"kushtein\"tek \"pjesa\" \"if\"",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Shto një përfundues, që i mbërrin të gjitha kushtet në bllokun nëse.",
                +	"LOGIC_COMPARE_HELPURL": "http://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Ktheje të saktë nëse të dy hyrjet janë të barabarta me njëra-tjetrën.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Ktheje të saktë nëse të dy hyrjet nuk janë të barabarta me njëra-tjetrën.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Ktheje të saktë nëse hyrja e parë është më e vogël se hyrja e dytë.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Ktheje të saktë nëse hyrja e parë është më e vogël ose e barabartë me hyrjen e dytë.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Ktheje të saktë nëse hyrja e parë është më e madhe se hyrja e dytë.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Ktheje të saktë nëse hyrja e parë është më e madhe ose e barabartë me hyrjen e dytë.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Kthehet të saktë nëse të dy hyrjet janë të sakta.",
                +	"LOGIC_OPERATION_AND": "dhe",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Kthehet e saktë nëse së paku njëra nga hyrjet është e saktë.",
                +	"LOGIC_OPERATION_OR": "ose",
                +	"LOGIC_NEGATE_TITLE": "jo %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Kthehet e saktë nëse hyrja është e pasaktë. Kthehet e pasaktë nëse hyrja është e saktë.",
                +	"LOGIC_BOOLEAN_TRUE": "e saktë",
                +	"LOGIC_BOOLEAN_FALSE": "e pasaktë",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Kthehet ose të saktë ose të pasaktë.",
                +	"LOGIC_NULL_HELPURL": "http://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "pavlerë",
                +	"LOGIC_NULL_TOOLTIP": "Kthehet e pavlerë.",
                +	"LOGIC_TERNARY_HELPURL": "http://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "nëse e saktë",
                +	"LOGIC_TERNARY_IF_FALSE": "nëse e pasaktë",
                +	"LOGIC_TERNARY_TOOLTIP": "Kontrollo kushtin në 'test'. Nëse kushti është i saktë, kthen vlerën 'nëse e saktë'; përndryshe kthen vlerën 'nëse e pasaktë'.",
                +	"MATH_NUMBER_HELPURL": "http://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Një numër.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "x",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asinus",
                +	"MATH_TRIG_ACOS": "acosinus",
                +	"MATH_TRIG_ATAN": "atangjentë",
                +	"MATH_ARITHMETIC_HELPURL": "http://sq.wikipedia.org/wiki/Aritmetika",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Kthen shumën e dy numrave.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Kthen ndryshimin e dy numrave.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Kthen produktin e dy numrave.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Kthen herësin e dy numrave.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Kthen numrin e parë të ngritur në fuqinë e numrit të dytë.",
                +	"MATH_SINGLE_HELPURL": "http://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "rrënja katrore",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Kthen rrënjën katrore të një numri.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Kthen vlerën absolute të një numri.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Kthe negacionin e një numri.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Kthen logaritmën natyrale të një numri.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Kthen 10 logaritmet bazë të një numri.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Kthen e në fuqinë e një numri.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Kthen 10 në fuqinë e një numri.",
                +	"MATH_TRIG_HELPURL": "http://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Kthe kosinusin e nje kendi (jo ne radiant).",
                +	"MATH_TRIG_TOOLTIP_COS": "Kthe kosinusin e nje grade (jo ne radiant).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Kthe tangentin e nje kendi (jo radiant).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Rikthe sin-1 e nje numeri.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Rikthe cos-1 e nje numeri.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Kthe tg-1 e nje numeri.",
                +	"MATH_CONSTANT_HELPURL": "http://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Kthen një nga konstantet e përbashkëta: : π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infiniti).",
                +	"MATH_IS_EVEN": "është çift",
                +	"MATH_IS_ODD": "është tek",
                +	"MATH_IS_PRIME": "është prim",
                +	"MATH_IS_WHOLE": "është i plotë",
                +	"MATH_IS_POSITIVE": "është pozitiv",
                +	"MATH_IS_NEGATIVE": "është negativ",
                +	"MATH_IS_DIVISIBLE_BY": "është i pjestueshme me",
                +	"MATH_IS_TOOLTIP": "Kontrollo nëse një numër është çift, tek, prim, i plotë, pozitiv, negativ, ose nëse është i pjestueshëm me një numër të caktuar. Kthehet e saktë ose e pasaktë.",
                +	"MATH_CHANGE_HELPURL": "http://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "ndrysho %1 nga %2",
                +	"MATH_CHANGE_TOOLTIP": "Shto një numër në ndryshoren '%1'.",
                +	"MATH_ROUND_HELPURL": "http://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Rrumbullakësimi i numrit të lartë ose të ulët.",
                +	"MATH_ROUND_OPERATOR_ROUND": "rrumbullakësimi",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "rrumbullakësimi i lartë",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "rrumbullakësimi i ulët",
                +	"MATH_ONLIST_OPERATOR_SUM": "mbledhja e listës",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Kthe shumën e të gjithë numrave të listës.",
                +	"MATH_ONLIST_OPERATOR_MIN": "numri më i ulët i listës",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Kthe numrin me të vogël të listës.",
                +	"MATH_ONLIST_OPERATOR_MAX": "numri më i madh i listës",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Kthe numrin më të madh të listës.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "mesatarja e listës",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Kthen mesatarën (kuptimi aritmetik) i vlerave numerike të listës.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "mediana e listës",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Kthe numrin median të listës.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modat e listës",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Kthe listën e sendit(eve) më të zakonshme të listës.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "devijimi standard i listës",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Kthe devijimin standard të listës.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "send i rastësishëm i listës",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Kthe një element të rastësishëm nga lista.",
                +	"MATH_MODULO_HELPURL": "http://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "mbetësi i %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Kthen mbetësin nga pjestimi i dy numrave.",
                +	"MATH_CONSTRAIN_TITLE": "detyro %1 e ulët %2 e lartë %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Vëni një numër që të jetë në mes të kufive të specifikuara(përfshirëse).",
                +	"MATH_RANDOM_INT_HELPURL": "http://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "numër i plotë i rastësishëm nga %1 deri në %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Kthe një numër të plotë të rastësishëm të dy kufijve të specifikuar, të përfshirë.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "http://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "fraksioni i rastësishëm",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Kthe fraksionin e rastësishëm në mes të 0.0 (përfshirëse) dhe 1.0 (jopërfshirëse).",
                +	"TEXT_TEXT_HELPURL": "http://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Nje shkronje, fjale, ose rresht teksti.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "krijo tekst me",
                +	"TEXT_JOIN_TOOLTIP": "Krijo nje pjese te tekstit duke bashkuar se bashku disa sende",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "bashkangjit",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këtë bllok teksti.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Shto nje gje ne tekst",
                +	"TEXT_APPEND_TOOLTIP": "shto tekst tek varibla '%1'.",
                +	"TEXT_LENGTH_TITLE": "gjatesi %1",
                +	"TEXT_LENGTH_TOOLTIP": "Pergjigjet me nje numer shkronjash (duke perfshire hapesire) ne tekstin e dhene.",
                +	"TEXT_ISEMPTY_TITLE": "%1 eshte bosh",
                +	"TEXT_ISEMPTY_TOOLTIP": "Kthehet e vertete neqoftese teksti i dhene eshte bosh.",
                +	"TEXT_INDEXOF_TOOLTIP": "Pergjigjet me indeksin e pare/fundit te rastisjes se tekstit te pare ne tekstin e dyte. Pergjigjet me %1 ne qofte se teksti nuk u gjet.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "gjej rastisjen e pare te tekstit",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "gjej rastisjen e fundit te tekstit",
                +	"TEXT_CHARAT_FROM_START": "merr shkronjen #",
                +	"TEXT_CHARAT_FROM_END": "merr shkronjen # nga fundi",
                +	"TEXT_CHARAT_FIRST": "merr shkronjen e pare",
                +	"TEXT_CHARAT_LAST": "merr shkronjen e fundit",
                +	"TEXT_CHARAT_RANDOM": "merr nje shkronje te rastesishme",
                +	"TEXT_CHARAT_TOOLTIP": "Kthe nje shkronje nga nje pozicion i caktuar.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Pergjigjet me nje pjese te caktuar teksti.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ne tekst",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "Merr nenvargun nga shkronja #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "merr nenvargun nga shkronja # nga fundi",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "merr vlerat qe vazhdojne me shkronjen e pare",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "ne shkronjen #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "ne shkronjen # nga fundi",
                +	"TEXT_GET_SUBSTRING_END_LAST": "tek shkronja e fundit",
                +	"TEXT_CHANGECASE_TOOLTIP": "Kthe nje kopje te tekstit ne nje rast te ndryshem.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "me shkronja te medha shtypi",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "me shkronja te vogla shtypi",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Fillimi me shkronje te madhe shtypi",
                +	"TEXT_TRIM_TOOLTIP": "Pergjigju me nje kopje te tekstit me hapesira te fshira nga njera ane ose te dyja anet.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "prit hapesirat nga te dyja anet",
                +	"TEXT_TRIM_OPERATOR_LEFT": "prit hapesirat nga ana e majte",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "prit hapesirat nga ana e djathte",
                +	"TEXT_PRINT_TITLE": "printo %1",
                +	"TEXT_PRINT_TOOLTIP": "Printo tekstin e caktuar, numer ose vlere tjeter.",
                +	"TEXT_PROMPT_TYPE_TEXT": "kerko tekst me njoftim",
                +	"TEXT_PROMPT_TYPE_NUMBER": "kerko nje numer me njoftim",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Kerkoji perdoruesit nje numer.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Kerkoji perdoruesit ca tekst.",
                +	"TEXT_COUNT_MESSAGE0": "numro %1 në %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "krijo një listë të zbrazët",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Kthen një listë, te gjatësisë 0, duke mos përmbajtur asnjë regjistrim të të dhënave",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Krijo një listë me ndonjë numbër të sendeve.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "krijo listë me",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "listë",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Shto, fshij, ose rirregullo sektoret për ta rikonfiguruar këtë bllok të listës.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Shto një send në listë.",
                +	"LISTS_REPEAT_TOOLTIP": "Krijon në listë qe përmban vlerën e dhënë të përsëritur aq herë sa numri i specifikuar.",
                +	"LISTS_REPEAT_TITLE": "krijo listën me sendin %1 të përsëritur %2 herë",
                +	"LISTS_LENGTH_TITLE": "gjatësia e %1",
                +	"LISTS_LENGTH_TOOLTIP": "Kthen gjatësinë e listës.",
                +	"LISTS_ISEMPTY_TITLE": "%1 është e zbraztë",
                +	"LISTS_ISEMPTY_TOOLTIP": "Kthehet i saktë nëse lista është e zbraztë.",
                +	"LISTS_INLIST": "në listë",
                +	"LISTS_INDEX_OF_FIRST": "gjen ndodhjen e parë të sendit",
                +	"LISTS_INDEX_OF_LAST": "gjen ndodhjen e fundit të sendit",
                +	"LISTS_INDEX_OF_TOOLTIP": "Kthen indeksin e ndodhjes së parë/fudit të sendit në listë. Kthen %1 nëse teksti nuk është gjetur.",
                +	"LISTS_GET_INDEX_GET": "merr",
                +	"LISTS_GET_INDEX_GET_REMOVE": "merr dhe fshij",
                +	"LISTS_GET_INDEX_REMOVE": "largo",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# nga fundi",
                +	"LISTS_GET_INDEX_FIRST": "i parë",
                +	"LISTS_GET_INDEX_LAST": "i fundit",
                +	"LISTS_GET_INDEX_RANDOM": "i rastësishëm",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 është sendi i parë.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 është sendi i fundit.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Kthen një send në pozicionin e specifikuar në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Rikthen tek artikulli i par në list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Kthen artikullin e fundit në list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Kthen një send të rastësishëm në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Fshin dhe kthen sendin në pozicionin e specifikuar në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Fshin dhe kthen sendin e parë në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Fshin dhe kthen sendin e fundit në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Fshin dhe kthen një send të rastësishëm në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Fshin sendin në pozicionin e specifikuar në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Fshin sendin e parë në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Fshin sendin e fundit në listë.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Kthen një send të rastësishëm në listë.",
                +	"LISTS_SET_INDEX_SET": "vendos",
                +	"LISTS_SET_INDEX_INSERT": "fut në",
                +	"LISTS_SET_INDEX_INPUT_TO": "sikurse",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Vendos sendin në pozicionin e specifikuar në listë.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Vendos sendin e parë në listë.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Vendos sendin e fundit në listë.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Vendos një send të rastësishëm në listë.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Fut sendin në pozicionin e specifikuar të listës.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Fut sendin në fillim të listës.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Bashkangjit sendin në fund të listës.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Fut sendin rastësisht në listë.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "merr nën-listën nga #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "merr nën listën nga # nga fundi",
                +	"LISTS_GET_SUBLIST_START_FIRST": "merr nën-listën nga i pari",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "tek #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "tek # nga fundi",
                +	"LISTS_GET_SUBLIST_END_LAST": "tek i fundit",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Krijon në kopje të pjesës së specifikuar të listës.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "rendit %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Rendit një kopje të listës.",
                +	"LISTS_SORT_ORDER_ASCENDING": "ngjitje",
                +	"LISTS_SORT_ORDER_DESCENDING": "zbritje",
                +	"LISTS_SORT_TYPE_NUMERIC": "numerike",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetike",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetike, injoro madhësinë e shkronjave",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "bëj listë nga teksti",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "bëj tekst nga lista",
                +	"VARIABLES_GET_TOOLTIP": "Pergjigjet me nje vlere te kesaj variable.",
                +	"VARIABLES_GET_CREATE_SET": "Krijo 'vendos %1",
                +	"VARIABLES_SET": "vendos %1 ne %2",
                +	"VARIABLES_SET_TOOLTIP": "Vendos kete variable te jete e barabarte me te dhenat ne hyrje.",
                +	"VARIABLES_SET_CREATE_GET": "Krijo 'merr %1",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "te",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "bëj diqka",
                +	"PROCEDURES_BEFORE_PARAMS": "me:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "me:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Krijon një funksion pa dalje.",
                +	"PROCEDURES_DEFRETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "rikthe",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Krijon një funksion me një dalje.",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Paralajmërim: Ky funksion ka parametra të dyfishuar.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Lësho funksionin e definuar nga përdoruesi '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Lëho funksionin e definuar nga përdoruesi '%1' dhe përdor daljen e tij.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "Informacioni i futur",
                +	"PROCEDURES_MUTATORARG_TITLE": "Fut emrin:",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Thekso definicionin e funksionit",
                +	"PROCEDURES_CREATE_DO": "Krijo '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Nëse një vlerë është e saktë, atëherë kthe një vlerë të dytë.",
                +	"PROCEDURES_IFRETURN_WARNING": "Paralajmërim: Ky bllok mund të përdoret vetëm brenda definicionit të funksionit."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sr.json b/blockly/webif/static/blockly/msg/json/sr.json
                new file mode 100644
                index 000000000..d0a7f67e1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sr.json
                @@ -0,0 +1,363 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Rancher",
                +			"아라",
                +			"Perevod16",
                +			"Nikola Smolenski",
                +			"Obsuser"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "ставка",
                +	"TODAY": "Данас",
                +	"DUPLICATE_BLOCK": "Дуплирај",
                +	"ADD_COMMENT": "Додај коментар",
                +	"REMOVE_COMMENT": "Уклони коментар",
                +	"EXTERNAL_INPUTS": "Спољни улази",
                +	"INLINE_INPUTS": "Унутрашњи улази",
                +	"DELETE_BLOCK": "Обриши блок",
                +	"DELETE_X_BLOCKS": "Обриши %1 блокова",
                +	"DELETE_ALL_BLOCKS": "Да обришем свих %1 блокова?",
                +	"CLEAN_UP": "Уклони блокове",
                +	"COLLAPSE_BLOCK": "Скупи блок",
                +	"COLLAPSE_ALL": "Скупи блокове",
                +	"EXPAND_BLOCK": "Прошири блок",
                +	"EXPAND_ALL": "Прошири блокове",
                +	"DISABLE_BLOCK": "Онемогући блок",
                +	"ENABLE_BLOCK": "Омогући блок",
                +	"HELP": "Помоћ",
                +	"UNDO": "Опозови",
                +	"REDO": "Понови",
                +	"CHANGE_VALUE_TITLE": "Промените вредност:",
                +	"RENAME_VARIABLE": "Преименуј променљиву…",
                +	"RENAME_VARIABLE_TITLE": "Преименујте све „%1“ променљиве у:",
                +	"NEW_VARIABLE": "Направи променљиву…",
                +	"NEW_VARIABLE_TITLE": "Име нове променљиве:",
                +	"VARIABLE_ALREADY_EXISTS": "Променљива под именом '%1' већ постоји.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Да обришем %1 употреба променљиве '%2'?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Не могу да обришем варијаблу ’%1’ јер је део дефиниције функције ’%2’",
                +	"DELETE_VARIABLE": "Обриши променљиву '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://sr.wikipedia.org/wiki/Боја",
                +	"COLOUR_PICKER_TOOLTIP": "Изаберите боју са палете.",
                +	"COLOUR_RANDOM_TITLE": "случајна боја",
                +	"COLOUR_RANDOM_TOOLTIP": "Изаберите боју насумице.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "боја са",
                +	"COLOUR_RGB_RED": "црвена",
                +	"COLOUR_RGB_GREEN": "зелена",
                +	"COLOUR_RGB_BLUE": "плава",
                +	"COLOUR_RGB_TOOLTIP": "Креирај боју са одређеном количином црвене,зелене, и плаве. Све вредности морају бити између 0 и 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "помешај",
                +	"COLOUR_BLEND_COLOUR1": "боја 1",
                +	"COLOUR_BLEND_COLOUR2": "боја 2",
                +	"COLOUR_BLEND_RATIO": "однос",
                +	"COLOUR_BLEND_TOOLTIP": "Помешати две боје заједно са датим односом (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://sr.wikipedia.org/wiki/For_петља",
                +	"CONTROLS_REPEAT_TITLE": "понови %1 пута",
                +	"CONTROLS_REPEAT_INPUT_DO": "изврши",
                +	"CONTROLS_REPEAT_TOOLTIP": "Одрадити неке наредбе неколико пута.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "понављати док",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "понављати до",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Док је вредност тачна, онда извршите неке наредбе.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Док вредност није тачна, онда извршити неке наредбе.",
                +	"CONTROLS_FOR_TOOLTIP": "Имај промењиву \"%1\" узми вредности од почетног броја до задњег броја, бројећи по одређеном интервалу, и изврши одређене блокове.",
                +	"CONTROLS_FOR_TITLE": "преброј са %1 од %2 до %3 од %4",
                +	"CONTROLS_FOREACH_TITLE": "за сваку ставку %1 на списку %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "За сваку ставку унутар листе, подеси промењиву '%1' по ставци, и онда начини неке изјаве-наредбе.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "Изађите из петље",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "настави са следећом итерацијом петље",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Напусти садржај петље.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Прескочи остатак ове петље, и настави са следећом итерацијом(понављанјем).",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Упозорење: Овај блок може да се употреби само унутар петље.",
                +	"CONTROLS_IF_TOOLTIP_1": "ако је вредност тачна, онда изврши неке наредбе-изјаве.",
                +	"CONTROLS_IF_TOOLTIP_2": "ако је вредност тачна, онда изврши први блок наредби, У супротном, изврши други блок наредби.",
                +	"CONTROLS_IF_TOOLTIP_3": "Ако је прва вредност тачна, онда изврши први блок наредби, у супротном, ако је друга вредност тачна , изврши други блок наредби.",
                +	"CONTROLS_IF_TOOLTIP_4": "Ако је прва вредност тачна, онда изврши први блок наредби, у супротном, ако је друга вредност тачна , изврши други блок наредби. Ако ни једна од вредности није тачна, изврши последнји блок наредби.",
                +	"CONTROLS_IF_MSG_IF": "ако",
                +	"CONTROLS_IF_MSG_ELSEIF": "иначе-ако",
                +	"CONTROLS_IF_MSG_ELSE": "иначе",
                +	"CONTROLS_IF_IF_TOOLTIP": "Додај, уклони, или преуреди делове како бих реконфигурисали овај иф блок.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Додајте услов блоку „ако“.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Додај коначни, catch-all  (ухвати све) услове иф блока.",
                +	"IOS_OK": "У реду",
                +	"IOS_CANCEL": "Откажи",
                +	"IOS_ERROR": "Грешка",
                +	"IOS_PROCEDURES_INPUTS": "УНОСИ",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Додај унос",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Дозволи изјаве",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Ова функција има дуплициране уносе.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Додај варијаблу",
                +	"IOS_VARIABLES_ADD_BUTTON": "Додај",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Преименуј",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Обриши",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Име варијабле",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Не можете да користите празно име варијабле.",
                +	"LOGIC_COMPARE_HELPURL": "https://sr.wikipedia.org/wiki/Неједнакост",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Враћа вредност „тачно“ ако су оба улаза једнака.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Враћа вредност „тачно“ ако су оба улаза неједнака.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Враћа вредност „тачно“ ако је први улаз мањи од другог.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Враћа вредност „тачно“ ако је први улаз мањи или једнак другом.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Враћа вредност „тачно“ ако је први улаз већи од другог.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Враћа вредност „тачно“ ако је први улаз већи или једнак другом.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Враћа вредност „тачно“ ако су оба улаза тачна.",
                +	"LOGIC_OPERATION_AND": "и",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Враћа вредност „тачно“ ако је бар један од улаза тачан.",
                +	"LOGIC_OPERATION_OR": "или",
                +	"LOGIC_NEGATE_TITLE": "није %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Враћа вредност „тачно“ ако је улаз нетачан. Враћа вредност „нетачно“ ако је улаз тачан.",
                +	"LOGIC_BOOLEAN_TRUE": "тачно",
                +	"LOGIC_BOOLEAN_FALSE": "нетачно",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Враћа или тачно или нетачно.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "без вредности",
                +	"LOGIC_NULL_TOOLTIP": "Враћа „без вредности“.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "проба",
                +	"LOGIC_TERNARY_IF_TRUE": "ако је тачно",
                +	"LOGIC_TERNARY_IF_FALSE": "ако је нетачно",
                +	"LOGIC_TERNARY_TOOLTIP": "Провери услов у 'test'. Ако је услов тачан, тада враћа 'if true' вредност; у другом случају враћа 'if false' вредност.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Неки број.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "син",
                +	"MATH_TRIG_COS": "цос",
                +	"MATH_TRIG_TAN": "тан",
                +	"MATH_TRIG_ASIN": "арц син",
                +	"MATH_TRIG_ACOS": "арц цос",
                +	"MATH_TRIG_ATAN": "арц тан",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Вратите збир два броја.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Враћа разлику два броја.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Враћа производ два броја.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Враћа количник два броја.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Враћа први број степенован другим.",
                +	"MATH_SINGLE_HELPURL": "https://sr.wikipedia.org/wiki/Квадратни_корен",
                +	"MATH_SINGLE_OP_ROOT": "квадратни корен",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Враћа квадратни корен броја.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "апсолутан",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Враћа апсолутну вредност броја.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Враћа негацију броја.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Враћа природни логаритам броја.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Враћа логаритам броја са основом 10.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "вратити е на власти броја.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Враћа 10-ти степен броја.",
                +	"MATH_TRIG_HELPURL": "https://sr.wikipedia.org/wiki/Тригонометријске_функције",
                +	"MATH_TRIG_TOOLTIP_SIN": "Враћа синус степена (не радијан).",
                +	"MATH_TRIG_TOOLTIP_COS": "Враћа косинус степена (не радијан).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Враћа тангенс степена (не радијан).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Враћа аркус броја.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Враћа аркус косинус броја.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Враћа аркус тангенс броја.",
                +	"MATH_CONSTANT_HELPURL": "https://sr.wikipedia.org/wiki/Математичка_константа",
                +	"MATH_CONSTANT_TOOLTIP": "врати једну од заједничких константи: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), или ∞ (infinity).",
                +	"MATH_IS_EVEN": "је паран",
                +	"MATH_IS_ODD": "је непаран",
                +	"MATH_IS_PRIME": "је прост",
                +	"MATH_IS_WHOLE": "је цео",
                +	"MATH_IS_POSITIVE": "је позитиван",
                +	"MATH_IS_NEGATIVE": "је негативан",
                +	"MATH_IS_DIVISIBLE_BY": "је дељив са",
                +	"MATH_IS_TOOLTIP": "Провјерава да ли је број паран, непаран, прост, цио, позитиван, негативан, или да ли је делјив са одређеним бројем. Враћа тачно или нетачно.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "промени %1 за %2",
                +	"MATH_CHANGE_TOOLTIP": "Додајте број променљивој „%1“.",
                +	"MATH_ROUND_HELPURL": "https://sr.wikipedia.org/wiki/Заокруживање",
                +	"MATH_ROUND_TOOLTIP": "Заокружите број на већу или мању вредност.",
                +	"MATH_ROUND_OPERATOR_ROUND": "заокружи",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "заокружи навише",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "заокружи наниже",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "збир списка",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Враћа збир свих бројева са списка.",
                +	"MATH_ONLIST_OPERATOR_MIN": "мин. списка",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Враћа најмањи број са списка.",
                +	"MATH_ONLIST_OPERATOR_MAX": "макс. списка",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Враћа највећи број са списка.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "просек списка",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Враћа просек нумеричких вредности са списка.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "медијана списка",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Враћа медијану са списка.",
                +	"MATH_ONLIST_OPERATOR_MODE": "модус списка",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Враћа најчешће ставке са списка.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "стандардна девијација списка",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Враћа стандардну девијацију списка.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "случајна ставка списка",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Враћа случајни елемент са списка.",
                +	"MATH_MODULO_HELPURL": "https://sr.wikipedia.org/wiki/Конгруенција",
                +	"MATH_MODULO_TITLE": "подсетник од %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Враћа подсетник од дељења два броја.",
                +	"MATH_CONSTRAIN_TITLE": "ограничи %1 ниско %2 високо %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Ограничава број на доње и горње границе (укључиво).",
                +	"MATH_RANDOM_INT_HELPURL": "https://sr.wikipedia.org/wiki/Генератор_случајних_бројева",
                +	"MATH_RANDOM_INT_TITLE": "сличајно одабрани цијели број од %1 до %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Враћа случајно одабрани цели број између две одређене границе, уклјучиво.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://sr.wikipedia.org/wiki/Генератор_случајних_бројева",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "случајни разломак",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Враћа случајни разломак између 0.0 (укључиво) и 1.0 (искључиво).",
                +	"TEXT_TEXT_HELPURL": "https://sr.wikipedia.org/wiki/Ниска",
                +	"TEXT_TEXT_TOOLTIP": "Слово, реч или ред текста.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "напиши текст са",
                +	"TEXT_JOIN_TOOLTIP": "Направити дио текста спајајући различите ставке.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "спајањем",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Додај, уклони, или другачије поредај одјелке како би изнова поставили овај текст блок.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Додајте ставку у текст.",
                +	"TEXT_APPEND_TOOLTIP": "Додајте текст на променљиву „%1“.",
                +	"TEXT_LENGTH_TITLE": "дужина текста %1",
                +	"TEXT_LENGTH_TOOLTIP": "Враћа број слова (уклјучујући размаке) у датом тексту.",
                +	"TEXT_ISEMPTY_TITLE": "%1 је празан",
                +	"TEXT_ISEMPTY_TOOLTIP": "Враћа тачно ако је доставлјени текст празан.",
                +	"TEXT_INDEXOF_TOOLTIP": "Враћа однос првог/заднјег појавлјиванја текста у другом тексту. Врађа %1 ако текст није пронађен.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "пронађи прво појављивање текста",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "пронађи последње појављивање текста",
                +	"TEXT_CHARAT_FROM_START": "преузми слово #",
                +	"TEXT_CHARAT_FROM_END": "преузми слово # са краја",
                +	"TEXT_CHARAT_FIRST": "преузми прво слово",
                +	"TEXT_CHARAT_LAST": "преузми последње слово",
                +	"TEXT_CHARAT_RANDOM": "преузми случајно слово",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Враћа слово на одређени положај.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Враћа одређени део текста.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "у тексту",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "преузми подниску из слова #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "преузми подниску из слова # са краја",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "преузми подниску из првог слова",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "слову #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "слову # са краја",
                +	"TEXT_GET_SUBSTRING_END_LAST": "последњем слову",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "Враћа примерак текста са другачијом величином слова.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "великим словима",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "малим словима",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "свака реч великим словом",
                +	"TEXT_TRIM_TOOLTIP": "Враћа копију текста са уклонјеним простором са једног од два краја.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "трим празнине са обе стране",
                +	"TEXT_TRIM_OPERATOR_LEFT": "скратити простор са леве стране",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "скратити простор са десне стране",
                +	"TEXT_PRINT_TITLE": "прикажи %1",
                +	"TEXT_PRINT_TOOLTIP": "Прикажите одређени текст, број или другу вредност на екрану.",
                +	"TEXT_PROMPT_TYPE_TEXT": "питај за текст са поруком",
                +	"TEXT_PROMPT_TYPE_NUMBER": "питај за број са поруком",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Питајте корисника за број.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Питајте корисника за унос текста.",
                +	"TEXT_COUNT_MESSAGE0": "број %1 у %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Броји колико пута се неки текст појављује унутар неког другог текста.",
                +	"TEXT_REPLACE_MESSAGE0": "замена %1 са %2 у %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Замена свих појава неког текста унутар неког другог текста.",
                +	"TEXT_REVERSE_MESSAGE0": "обрнуто %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Обрће редослед карактера у тексту.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "направи празан списак",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "враћа листу, дужине 0, не садржавајући  евиденцију података",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Креирај листу са било којим бројем ставки.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "направи списак са",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "списак",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Додајте, избришите, или преуредите делове како би се реорганизовали овај блок листе.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Додајте ставку на списак.",
                +	"LISTS_REPEAT_TOOLTIP": "Прави листу која се састоји од задане вредности коју понавлјамо одређени број шута.",
                +	"LISTS_REPEAT_TITLE": "Направити листу са ставком %1 која се понавлја %2 пута",
                +	"LISTS_LENGTH_TITLE": "дужина списка %1",
                +	"LISTS_LENGTH_TOOLTIP": "Враћа дужину списка.",
                +	"LISTS_ISEMPTY_TITLE": "%1 је празан",
                +	"LISTS_ISEMPTY_TOOLTIP": "Враћа вредност тачно ако је листа празна.",
                +	"LISTS_INLIST": "на списку",
                +	"LISTS_INDEX_OF_FIRST": "пронађи прво појављивање ставке",
                +	"LISTS_INDEX_OF_LAST": "пронађи последње појављивање ставке",
                +	"LISTS_INDEX_OF_TOOLTIP": "Враћа број првог и/последњег уласка елемента у листу. Враћа %1 Ако елемент није пронађен.",
                +	"LISTS_GET_INDEX_GET": "преузми",
                +	"LISTS_GET_INDEX_GET_REMOVE": "преузми и уклони",
                +	"LISTS_GET_INDEX_REMOVE": "уклони",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# са краја",
                +	"LISTS_GET_INDEX_FIRST": "прва",
                +	"LISTS_GET_INDEX_LAST": "последња",
                +	"LISTS_GET_INDEX_RANDOM": "случајна",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 је прва ставка.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 је последња ставка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Враћа ставку на одређену позицију на листи.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Враћа прву ставку на списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Враћа последњу ставку на списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Враћа случајну ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Уклања и враћа ставку са одређеног положаја на списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Уклања и враћа прву ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Уклања и враћа последњу ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Уклања и враћа случајну ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Уклања ставку са одређеног положаја на списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Уклања прву ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Уклања последњу ставку са списка.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Уклања случајну ставку са списка.",
                +	"LISTS_SET_INDEX_SET": "постави",
                +	"LISTS_SET_INDEX_INSERT": "убаци на",
                +	"LISTS_SET_INDEX_INPUT_TO": "као",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Поставља ставку на одређени положај на списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Поставља прву ставку на списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Поставља последњу ставку на списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Поставља случајну ставку на списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Убацује ставку на одређени положај на списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Убацује ставку на почетак списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Додајте ставку на крај списка.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Убацује ставку на случајно место на списку.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "преузми подсписак од #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "преузми подсписак из # са краја",
                +	"LISTS_GET_SUBLIST_START_FIRST": "преузми подсписак од прве",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "до #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "до # од краја",
                +	"LISTS_GET_SUBLIST_END_LAST": "до последње",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Прави копију одређеног дела листе.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "сортирај %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Сортирајте копију списка.",
                +	"LISTS_SORT_ORDER_ASCENDING": "растуће",
                +	"LISTS_SORT_ORDER_DESCENDING": "опадајуће",
                +	"LISTS_SORT_TYPE_NUMERIC": "као бројеве",
                +	"LISTS_SORT_TYPE_TEXT": "азбучно",
                +	"LISTS_SORT_TYPE_IGNORECASE": "азбучно, игнориши мала и велика слова",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "направите листу са текста",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "да текст из листе",
                +	"LISTS_SPLIT_WITH_DELIMITER": "са раздвајање",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Поделити текст у листу текстова, разбијање на сваком граничник.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Да се придружи листу текстова у један текст, подељених за раздвајање.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "обрнуто %1",
                +	"LISTS_REVERSE_TOOLTIP": "Обрни копију списка.",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_TOOLTIP": "Враћа вредност ове променљиве.",
                +	"VARIABLES_GET_CREATE_SET": "Направи „постави %1“",
                +	"VARIABLES_SET": "постави %1 у %2",
                +	"VARIABLES_SET_TOOLTIP": "Поставља променљиву тако да буде једнака улазу.",
                +	"VARIABLES_SET_CREATE_GET": "Направи „преузми %1“",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "да",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "урадите нешто",
                +	"PROCEDURES_BEFORE_PARAMS": "са:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "са:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Прави функцију без излаза.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Описати ову функцију...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "врати",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Прави функцију са излазом.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "дозволити изреке",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Упозорење: Ова функција има дупликате параметара.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Покрените прилагођену функцију „%1“.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Покрените прилагођену функцију „%1“ и користи њен излаз.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "улази",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Да додате, уклоните или переупорядочить улаза за ову функцију.",
                +	"PROCEDURES_MUTATORARG_TITLE": "назив улаза:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Додајте улазна функција.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Истакни дефиницију функције",
                +	"PROCEDURES_CREATE_DO": "Направи „%1“",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Уколико је вредност тачна, врати другу вредност.",
                +	"PROCEDURES_IFRETURN_WARNING": "Упозорење: Овај блок се може користити једино у дефиницији функције."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/sv.json b/blockly/webif/static/blockly/msg/json/sv.json
                new file mode 100644
                index 000000000..d9ab3d690
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/sv.json
                @@ -0,0 +1,364 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Jopparn",
                +			"WikiPhoenix",
                +			"Abbedabb",
                +			"Aaoo",
                +			"아라"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "föremål",
                +	"TODAY": "Idag",
                +	"DUPLICATE_BLOCK": "Duplicera",
                +	"ADD_COMMENT": "Lägg till kommentar",
                +	"REMOVE_COMMENT": "Radera kommentar",
                +	"EXTERNAL_INPUTS": "Externa inmatningar",
                +	"INLINE_INPUTS": "Radinmatning",
                +	"DELETE_BLOCK": "Radera block",
                +	"DELETE_X_BLOCKS": "Radera %1 block",
                +	"DELETE_ALL_BLOCKS": "Radera alla %1 block?",
                +	"CLEAN_UP": "Rada upp block",
                +	"COLLAPSE_BLOCK": "Fäll ihop block",
                +	"COLLAPSE_ALL": "Fäll ihop block",
                +	"EXPAND_BLOCK": "Fäll ut block",
                +	"EXPAND_ALL": "Fäll ut block",
                +	"DISABLE_BLOCK": "Inaktivera block",
                +	"ENABLE_BLOCK": "Aktivera block",
                +	"HELP": "Hjälp",
                +	"UNDO": "Ångra",
                +	"REDO": "Gör om",
                +	"CHANGE_VALUE_TITLE": "Ändra värde:",
                +	"RENAME_VARIABLE": "Byt namn på variabel...",
                +	"RENAME_VARIABLE_TITLE": "Byt namn på alla'%1'-variabler till:",
                +	"NEW_VARIABLE": "Skapa variabel...",
                +	"NEW_VARIABLE_TITLE": "Nytt variabelnamn:",
                +	"VARIABLE_ALREADY_EXISTS": "En variabel som heter \"%1\" finns redan.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "En variabel med namnet \"%1\" finns redan för en annan variabeln av typen \"%2\".",
                +	"PROCEDURE_ALREADY_EXISTS": "En procedur som heter \"%1\" finns redan.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Radera %1 användningar av variabeln \"%2\"?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "Kan inte radera variabeln '%1' eftersom den är en del av definition för funktionen '%2'",
                +	"DELETE_VARIABLE": "Radera variabeln \"%1\"",
                +	"COLOUR_PICKER_HELPURL": "https://sv.wikipedia.org/wiki/Färg",
                +	"COLOUR_PICKER_TOOLTIP": "Välj en färg från paletten.",
                +	"COLOUR_RANDOM_TITLE": "slumpfärg",
                +	"COLOUR_RANDOM_TOOLTIP": "Slumpa fram en färg.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "färg med",
                +	"COLOUR_RGB_RED": "röd",
                +	"COLOUR_RGB_GREEN": "grön",
                +	"COLOUR_RGB_BLUE": "blå",
                +	"COLOUR_RGB_TOOLTIP": "Skapa en färg med det angivna mängden röd, grön och blå. Alla värden måste vara mellan 0 och 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "blanda",
                +	"COLOUR_BLEND_COLOUR1": "färg 1",
                +	"COLOUR_BLEND_COLOUR2": "färg 2",
                +	"COLOUR_BLEND_RATIO": "förhållande",
                +	"COLOUR_BLEND_TOOLTIP": "Blandar ihop två färger med ett bestämt förhållande (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "upprepa %1 gånger",
                +	"CONTROLS_REPEAT_INPUT_DO": "utför",
                +	"CONTROLS_REPEAT_TOOLTIP": "Utför några kommandon flera gånger.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "upprepa medan",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "upprepa tills",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Medan ett värde är sant, utför några kommandon.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Medan ett värde är falskt, utför några kommandon.",
                +	"CONTROLS_FOR_TOOLTIP": "Låt variabeln \"%1\" ta värden från starttalet till sluttalet, beräknat med det angivna intervallet, och utför de angivna blocken.",
                +	"CONTROLS_FOR_TITLE": "räkna med %1 från %2 till %3 med %4",
                +	"CONTROLS_FOREACH_TITLE": "för varje föremål %1 i listan %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "För varje objekt i en lista, ange variabeln '%1' till objektet, och utför sedan några kommandon.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "bryt ut ur loop",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "fortsätta med nästa upprepning av loop",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Bryt ut ur den innehållande upprepningen.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Hoppa över resten av denna loop och fortsätt med nästa loop.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Varning: Detta block kan endast användas i en loop.",
                +	"CONTROLS_IF_TOOLTIP_1": "Om ett värde är sant, utför några kommandon.",
                +	"CONTROLS_IF_TOOLTIP_2": "Om värdet är sant, utför det första kommandoblocket. Annars utför det andra kommandoblocket.",
                +	"CONTROLS_IF_TOOLTIP_3": "Om det första värdet är sant, utför det första kommandoblocket. Annars, om det andra värdet är sant, utför det andra kommandoblocket.",
                +	"CONTROLS_IF_TOOLTIP_4": "Om det första värdet är sant, utför det första kommandoblocket. Annars, om det andra värdet är sant, utför det andra kommandoblocket. Om ingen av värdena är sanna, utför det sista kommandoblocket.",
                +	"CONTROLS_IF_MSG_IF": "om",
                +	"CONTROLS_IF_MSG_ELSEIF": "annars om",
                +	"CONTROLS_IF_MSG_ELSE": "annars",
                +	"CONTROLS_IF_IF_TOOLTIP": "Lägg till, ta bort eller ändra ordningen för sektioner för att omkonfigurera blocket \"om\".",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Lägg till ett villkor blocket \"om\".",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Lägg till ett sista villkor som täcker alla alternativ som är kvar för \"if\"-blocket.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "Avbryt",
                +	"IOS_ERROR": "Fel",
                +	"IOS_PROCEDURES_INPUTS": "INMATNINGAR",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Lägg till inmatning",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Tillåt kommandon",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Denna funktion har dubblettinmatningar.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Lägg till variabel",
                +	"IOS_VARIABLES_ADD_BUTTON": "Lägg till",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Döp om",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Radera",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Variabelnamn",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Du kan inte använda ett tomt variabelnamn.",
                +	"LOGIC_COMPARE_HELPURL": "https://sv.wikipedia.org/wiki/Olikhet",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Ger tillbaka sant om båda värdena är lika med varandra.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Ger tillbaka sant om båda värdena inte är lika med varandra.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Ger tillbaka sant om det första värdet är mindre än det andra.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Ger tillbaka sant om det första värdet är mindre än eller lika med det andra.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Ger tillbaka sant om det första värdet är större än det andra.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Ger tillbaka sant om det första värdet är större än eller lika med det andra.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Ger tillbaka sant om båda värdena är sanna.",
                +	"LOGIC_OPERATION_AND": "och",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Ger tillbaka sant om minst ett av värdena är sant.",
                +	"LOGIC_OPERATION_OR": "eller",
                +	"LOGIC_NEGATE_TITLE": "inte %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Ger tillbaka sant om inmatningen är falsk. Ger tillbaka falskt och inmatningen är sann.",
                +	"LOGIC_BOOLEAN_TRUE": "sant",
                +	"LOGIC_BOOLEAN_FALSE": "falskt",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Returnerar antingen sant eller falskt.",
                +	"LOGIC_NULL_HELPURL": "https://sv.wikipedia.org/wiki/Null",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "Returnerar null.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "om sant",
                +	"LOGIC_TERNARY_IF_FALSE": "om falskt",
                +	"LOGIC_TERNARY_TOOLTIP": "Kontrollera villkoret i \"test\". Om villkoret är sant, ge tillbaka \"om sant\"-värdet; annars ge tillbaka \"om falskt\"-värdet.",
                +	"MATH_NUMBER_HELPURL": "https://sv.wikipedia.org/wiki/Tal",
                +	"MATH_NUMBER_TOOLTIP": "Ett tal.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "arcsin",
                +	"MATH_TRIG_ACOS": "arccos",
                +	"MATH_TRIG_ATAN": "arctan",
                +	"MATH_ARITHMETIC_HELPURL": "https://sv.wikipedia.org/wiki/Aritmetik",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Returnerar summan av de två talen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Returnerar differensen mellan de två talen.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Returnerar produkten av de två talen.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Returnerar kvoten av de två talen.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Ger tillbaka det första talet upphöjt till det andra talet.",
                +	"MATH_SINGLE_HELPURL": "https://sv.wikipedia.org/wiki/Kvadratrot",
                +	"MATH_SINGLE_OP_ROOT": "kvadratrot",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Returnerar kvadratroten av ett tal.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolut",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Returnerar absolutvärdet av ett tal.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Returnerar negationen av ett tal.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Returnera den naturliga logaritmen av ett tal.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Returnerar logaritmen för bas 10 av ett tal.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Ger tillbaka e upphöjt i ett tal.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Ger tillbaka 10 upphöjt i ett tal.",
                +	"MATH_TRIG_HELPURL": "https://sv.wikipedia.org/wiki/Trigonometrisk_funktion",
                +	"MATH_TRIG_TOOLTIP_SIN": "Ger tillbaka sinus för en grad (inte radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Ger tillbaka cosinus för en grad (inte radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Ger tillbaka tangens för en grad (inte radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Ger tillbaka arcus sinus (arcsin) för ett tal.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Ger tillbaka arcus cosinus (arccos) för ett tal.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Ger tillbaka arcus tangens (arctan) av ett tal.",
                +	"MATH_CONSTANT_HELPURL": "https://sv.wikipedia.org/wiki/Matematisk_konstant",
                +	"MATH_CONSTANT_TOOLTIP": "Returnerar en av de vanliga konstanterna: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…) eller ∞ (oändligt).",
                +	"MATH_IS_EVEN": "är jämnt",
                +	"MATH_IS_ODD": "är ojämnt",
                +	"MATH_IS_PRIME": "är ett primtal",
                +	"MATH_IS_WHOLE": "är helt",
                +	"MATH_IS_POSITIVE": "är positivt",
                +	"MATH_IS_NEGATIVE": "är negativt",
                +	"MATH_IS_DIVISIBLE_BY": "är delbart med",
                +	"MATH_IS_TOOLTIP": "Kontrollera om ett tal är jämnt, ojämnt, helt, positivt, negativt eller det är delbart med ett bestämt tal. Returnerar med sant eller falskt.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "ändra %1 med %2",
                +	"MATH_CHANGE_TOOLTIP": "Lägg till ett tal till variabeln '%1'.",
                +	"MATH_ROUND_HELPURL": "https://sv.wikipedia.org/wiki/Avrundning",
                +	"MATH_ROUND_TOOLTIP": "Avrunda ett tal uppåt eller nedåt.",
                +	"MATH_ROUND_OPERATOR_ROUND": "avrunda",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "avrunda uppåt",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "avrunda nedåt",
                +	"MATH_ONLIST_OPERATOR_SUM": "summan av listan",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Ger tillbaka summan av alla talen i listan.",
                +	"MATH_ONLIST_OPERATOR_MIN": "minsta talet i listan",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Ger tillbaka det minsta talet i listan.",
                +	"MATH_ONLIST_OPERATOR_MAX": "högsta talet i listan",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Ger tillbaka det största talet i listan.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "medelvärdet av listan",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Ger tillbaka medelvärdet (aritmetiskt) av de numeriska värdena i listan.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "medianen av listan",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Returnerar medianen av talen i listan.",
                +	"MATH_ONLIST_OPERATOR_MODE": "typvärdet i listan",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Ger tillbaka en lista med de(t) vanligaste objekte(t/n) i listan.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standardavvikelsen i listan",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Ger tillbaka standardavvikelsen i listan.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "slumpmässigt objekt i listan",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Returnerar ett slumpmässigt element från listan.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "resten av %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Returnerar kvoten från divisionen av de två talen.",
                +	"MATH_CONSTRAIN_TITLE": "begränsa %1 till mellan %2 och %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Begränsa ett tal till att mellan de angivna gränsvärden (inkluderande).",
                +	"MATH_RANDOM_INT_HELPURL": "https://sv.wikipedia.org/wiki/Slumptalsgenerator",
                +	"MATH_RANDOM_INT_TITLE": "slumpartat heltal från %1 till %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Ger tillbaka ett slumpat heltal mellan två värden, inkluderande.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://sv.wikipedia.org/wiki/Slumptalsgenerator",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "slumpat decimaltal",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Ger tillbaka ett slumpat decimaltal mellan 0.0 (inkluderat) och 1.0 (exkluderat).",
                +	"TEXT_TEXT_HELPURL": "https://sv.wikipedia.org/wiki/Str%C3%A4ng_%28data%29",
                +	"TEXT_TEXT_TOOLTIP": "En bokstav, ord eller textrad.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "skapa text med",
                +	"TEXT_JOIN_TOOLTIP": "Skapa en textbit genom att sammanfoga ett valfritt antal föremål.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "sammanfoga",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Lägg till, ta bort eller ändra ordningen för sektioner för att omkonfigurera detta textblock.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Lägg till ett föremål till texten.",
                +	"TEXT_APPEND_TITLE": "för att %1 lägga till text %2",
                +	"TEXT_APPEND_TOOLTIP": "Lägg till lite text till variabeln '%1'.",
                +	"TEXT_LENGTH_TITLE": "längden på %1",
                +	"TEXT_LENGTH_TOOLTIP": "Ger tillbaka antalet bokstäver (inklusive mellanslag) i den angivna texten.",
                +	"TEXT_ISEMPTY_TITLE": "%1 är tom",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returnerar sant om den angivna texten är tom.",
                +	"TEXT_INDEXOF_TOOLTIP": "Ger tillbaka indexet för den första/sista förekomsten av första texten i den andra texten.  Ger tillbaka %1 om texten inte hittas.",
                +	"TEXT_INDEXOF_TITLE": "i texten %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "hitta första förekomsten av texten",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "hitta sista förekomsten av texten",
                +	"TEXT_CHARAT_TITLE": "i texten %1 %2",
                +	"TEXT_CHARAT_FROM_START": "hämta bokstaven #",
                +	"TEXT_CHARAT_FROM_END": "hämta bokstaven # från slutet",
                +	"TEXT_CHARAT_FIRST": "hämta första bokstaven",
                +	"TEXT_CHARAT_LAST": "hämta sista bokstaven",
                +	"TEXT_CHARAT_RANDOM": "hämta slumpad bokstav",
                +	"TEXT_CHARAT_TOOLTIP": "Ger tillbaka bokstaven på den specificerade positionen.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Ger tillbaka en viss del av texten.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "i texten",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "få textdel från bokstav #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "få textdel från bokstav # från slutet",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "få textdel från första bokstaven",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "till bokstav #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "till bokstav # från slutet",
                +	"TEXT_GET_SUBSTRING_END_LAST": "till sista bokstaven",
                +	"TEXT_CHANGECASE_TOOLTIP": "Returnerar en kopia av texten i ett annat skiftläge.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "till VERSALER",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "till gemener",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "till Versala Initialer",
                +	"TEXT_TRIM_TOOLTIP": "Returnerar en kopia av texten med borttagna mellanrum från en eller båda ändar.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "ta bort mellanrum från båda sidorna av",
                +	"TEXT_TRIM_OPERATOR_LEFT": "ta bort mellanrum från vänstra sidan av",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "ta bort mellanrum från högra sidan av",
                +	"TEXT_PRINT_TITLE": "skriv %1",
                +	"TEXT_PRINT_TOOLTIP": "Skriv den angivna texten, talet eller annat värde.",
                +	"TEXT_PROMPT_TYPE_TEXT": "fråga efter text med meddelande",
                +	"TEXT_PROMPT_TYPE_NUMBER": "fråga efter ett tal med meddelande",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Fråga användaren efter ett tal.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Fråga användaren efter lite text.",
                +	"TEXT_COUNT_MESSAGE0": "räkna %1 i %2",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Räkna hur många gånger en text förekommer inom en annan text.",
                +	"TEXT_REPLACE_MESSAGE0": "ersätt %1 med %2 i %3",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "Ersätt alla förekomster av en text inom en annan text.",
                +	"TEXT_REVERSE_MESSAGE0": "vänd på %1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "Vänder på teckenordningen i texten.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "skapa tom lista",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Ger tillbaka en lista utan någon data, alltså med längden 0",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Skapa en lista med valfritt antal föremål.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "skapa lista med",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "lista",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Lägg till, ta bort eller ändra ordningen på objekten för att göra om det här \"list\"-blocket.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Lägg till ett föremål till listan.",
                +	"LISTS_REPEAT_TOOLTIP": "Skapar en lista som innehåller ett valt värde upprepat ett bestämt antalet gånger.",
                +	"LISTS_REPEAT_TITLE": "skapa lista med föremålet %1 upprepat %2 gånger",
                +	"LISTS_LENGTH_TITLE": "längden på %1",
                +	"LISTS_LENGTH_TOOLTIP": "Returnerar längden på en lista.",
                +	"LISTS_ISEMPTY_TITLE": "%1 är tom",
                +	"LISTS_ISEMPTY_TOOLTIP": "Returnerar sant om listan är tom.",
                +	"LISTS_INLIST": "i listan",
                +	"LISTS_INDEX_OF_FIRST": "hitta första förekomsten av objektet",
                +	"LISTS_INDEX_OF_LAST": "hitta sista förekomsten av objektet",
                +	"LISTS_INDEX_OF_TOOLTIP": "Ger tillbaka den första/sista förekomsten av objektet i listan. Returnerar %1 om objektet inte hittas.",
                +	"LISTS_GET_INDEX_GET": "hämta",
                +	"LISTS_GET_INDEX_GET_REMOVE": "hämta och ta bort",
                +	"LISTS_GET_INDEX_REMOVE": "ta bort",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# från slutet",
                +	"LISTS_GET_INDEX_FIRST": "första",
                +	"LISTS_GET_INDEX_LAST": "sista",
                +	"LISTS_GET_INDEX_RANDOM": "slumpad",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 är det första objektet.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 är det sista objektet.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Ger tillbaka objektet på den efterfrågade positionen i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Returnerar det första objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Returnerar det sista objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Returnerar ett slumpmässigt objekt i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Tar bort och återställer objektet på den specificerade positionen i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Tar bort och återställer det första objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Tar bort och återställer det sista objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Tar bort och återställer ett slumpmässigt objekt i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Tar bort objektet på den specificerade positionen i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Tar bort det första objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Tar bort det sista objektet i en lista.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Tar bort en slumpmässig post i en lista.",
                +	"LISTS_SET_INDEX_SET": "ange",
                +	"LISTS_SET_INDEX_INSERT": "Sätt in vid",
                +	"LISTS_SET_INDEX_INPUT_TO": "som",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Sätter in objektet vid en specificerad position i en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Anger det första objektet i en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Anger det sista elementet i en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Sätter in ett slumpat objekt i en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Sätter in objektet vid en specificerad position i en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "sätter in objektet i början av en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Lägg till objektet i slutet av en lista.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "sätter in objektet på en slumpad position i en lista.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "få underlista från #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "få underlista från # från slutet",
                +	"LISTS_GET_SUBLIST_START_FIRST": "få underlista från första",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "till #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "till # från slutet",
                +	"LISTS_GET_SUBLIST_END_LAST": "till sista",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Skapar en kopia av den specificerade delen av en lista.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "sortera %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Sortera en kopia av en lista.",
                +	"LISTS_SORT_ORDER_ASCENDING": "stigande",
                +	"LISTS_SORT_ORDER_DESCENDING": "fallande",
                +	"LISTS_SORT_TYPE_NUMERIC": "numeriskt",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetiskt",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetiskt, ignorera skiftläge",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "skapa lista från text",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "skapa text från lista",
                +	"LISTS_SPLIT_WITH_DELIMITER": "med avgränsare",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Dela upp text till en textlista och bryt vid varje avgränsare.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Sammanfoga en textlista till en text, som separeras av en avgränsare.",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "vänd på %1",
                +	"LISTS_REVERSE_TOOLTIP": "Vänd på en kopia av en lista.",
                +	"VARIABLES_GET_TOOLTIP": "Returnerar värdet av denna variabel.",
                +	"VARIABLES_GET_CREATE_SET": "Skapa \"välj %1\"",
                +	"VARIABLES_SET": "ange %1 till %2",
                +	"VARIABLES_SET_TOOLTIP": "Gör så att den här variabeln blir lika med inputen.",
                +	"VARIABLES_SET_CREATE_GET": "Skapa 'hämta %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://sv.wikipedia.org/wiki/Funktion_%28programmering%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "för att",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "göra något",
                +	"PROCEDURES_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "med:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Skapar en funktion utan output.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Beskriv denna funktion...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://sv.wikipedia.org/wiki/Funktion_%28programmering%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "returnera",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Skapar en funktion med output.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "tillåta uttalanden",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Varning: Denna funktion har dubbla parametrar.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Kör den användardefinierade funktionen \"%1\".",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Kör den användardefinierade funktionen \"%1\" och använd resultatet av den.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inmatningar",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Lägg till, ta bort och ändra ordningen för inmatningar till denna funktion.",
                +	"PROCEDURES_MUTATORARG_TITLE": "inmatningsnamn:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Lägg till en inmatning till funktionen.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Markera funktionsdefinition",
                +	"PROCEDURES_CREATE_DO": "Skapa '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Om ett värde är sant returneras ett andra värde.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Varning: Detta block får användas endast i en funktionsdefinition."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/synonyms.json b/blockly/webif/static/blockly/msg/json/synonyms.json
                new file mode 100644
                index 000000000..944aa9bda
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/synonyms.json
                @@ -0,0 +1 @@
                +{"PROCEDURES_DEFRETURN_TITLE": "PROCEDURES_DEFNORETURN_TITLE", "CONTROLS_IF_IF_TITLE_IF": "CONTROLS_IF_MSG_IF", "CONTROLS_WHILEUNTIL_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "CONTROLS_IF_MSG_THEN": "CONTROLS_REPEAT_INPUT_DO", "LISTS_GET_SUBLIST_INPUT_IN_LIST": "LISTS_INLIST", "CONTROLS_IF_ELSE_TITLE_ELSE": "CONTROLS_IF_MSG_ELSE", "PROCEDURES_DEFRETURN_PROCEDURE": "PROCEDURES_DEFNORETURN_PROCEDURE", "TEXT_CREATE_JOIN_ITEM_TITLE_ITEM": "VARIABLES_DEFAULT_NAME", "LISTS_GET_INDEX_INPUT_IN_LIST": "LISTS_INLIST", "PROCEDURES_DEFRETURN_COMMENT": "PROCEDURES_DEFNORETURN_COMMENT", "CONTROLS_IF_ELSEIF_TITLE_ELSEIF": "CONTROLS_IF_MSG_ELSEIF", "PROCEDURES_DEFRETURN_DO": "PROCEDURES_DEFNORETURN_DO", "CONTROLS_FOR_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "LISTS_GET_INDEX_HELPURL": "LISTS_INDEX_OF_HELPURL", "LISTS_INDEX_OF_INPUT_IN_LIST": "LISTS_INLIST", "CONTROLS_FOREACH_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "LISTS_CREATE_WITH_ITEM_TITLE": "VARIABLES_DEFAULT_NAME", "TEXT_APPEND_VARIABLE": "VARIABLES_DEFAULT_NAME", "MATH_CHANGE_TITLE_ITEM": "VARIABLES_DEFAULT_NAME", "LISTS_SET_INDEX_INPUT_IN_LIST": "LISTS_INLIST"}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/msg/json/ta.json b/blockly/webif/static/blockly/msg/json/ta.json
                new file mode 100644
                index 000000000..5b4c00561
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/ta.json
                @@ -0,0 +1,294 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"ElangoRamanujam",
                +			"Ezhillang",
                +			"Karuthan",
                +			"Thangamani-arun",
                +			"Mahir78"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "உருப்படி",
                +	"TODAY": "இன்று",
                +	"DUPLICATE_BLOCK": "மறுநகல்",
                +	"ADD_COMMENT": "கருத்தை சேர்",
                +	"REMOVE_COMMENT": "கருத்தை நீக்கு",
                +	"EXTERNAL_INPUTS": "வெளி கருவிகளுடன் உள்ளீடு",
                +	"INLINE_INPUTS": "சூழமைவில் உள்ளீடு",
                +	"DELETE_BLOCK": "உறுப்பை நீக்கு",
                +	"DELETE_X_BLOCKS": "%1 உறுப்பை நீக்கு",
                +	"DELETE_ALL_BLOCKS": "அனைத்து %1 நிரல் துண்டுகளையும் அழிக்கவா??",
                +	"COLLAPSE_BLOCK": "உறுப்பை மரை",
                +	"COLLAPSE_ALL": "உறுப்புகளை மரை",
                +	"EXPAND_BLOCK": "உறுப்பை காட்டு",
                +	"EXPAND_ALL": "உறுப்புகளை  காட்டு",
                +	"DISABLE_BLOCK": "உறுப்பை இயங்காது செய்",
                +	"ENABLE_BLOCK": "உறுப்பை இயங்குமாரு செய்",
                +	"HELP": "உதவி",
                +	"CHANGE_VALUE_TITLE": "மதிப்பை மாற்றவும்:",
                +	"RENAME_VARIABLE": "மாறிலியை மறுபெயரிடுக...",
                +	"RENAME_VARIABLE_TITLE": "அனைத்து '%1' மாறிலிகளையும் பின்வருமாறு மறுபெயரிடுக:",
                +	"NEW_VARIABLE": "புதிய மாறிலி...",
                +	"NEW_VARIABLE_TITLE": "புதிய மாறிலியின் பெயர்:",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "வண்ண தட்டிலிருந்து ஒரு நிறத்தைத் தேர்ந்தெடுக்கவும்.",
                +	"COLOUR_RANDOM_TITLE": "தற்போக்கு நிறம்",
                +	"COLOUR_RANDOM_TOOLTIP": "தற்போக்கில் ஒரு நிறத்தை தேர்ந்தெடுக்கவும்.",
                +	"COLOUR_RGB_TITLE": "நிறத்துடன்",
                +	"COLOUR_RGB_RED": "சிகப்பு",
                +	"COLOUR_RGB_GREEN": "பச்சை",
                +	"COLOUR_RGB_BLUE": "நீலம்",
                +	"COLOUR_RGB_TOOLTIP": "குறிப்பிட்ட அளவு சிவப்பு,பச்சை மற்றும் நீலம் சேர்த்து புது நிறம் உருவாக்கு. மதிப்புகள் 0 முதல் 100 வரை மட்டுமே இருக்க வேண்டும்.",
                +	"COLOUR_BLEND_TITLE": "கலப்பு (வண்ணம்)",
                +	"COLOUR_BLEND_COLOUR1": "நிறம் 1",
                +	"COLOUR_BLEND_COLOUR2": "நிறம் 2",
                +	"COLOUR_BLEND_RATIO": "விகிதம்",
                +	"COLOUR_BLEND_TOOLTIP": "கொடுக்கப்பட்ட விகதத்தில் (0.0 - 1.0) இரு நிறங்களை கலக்குக.",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "'%1' முரை திரும்ப செய்",
                +	"CONTROLS_REPEAT_INPUT_DO": "செய்க",
                +	"CONTROLS_REPEAT_TOOLTIP": "கட்டளைகளை பல முரை செய்ய",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "பலமுரை திரும்ப செய் (வரை)",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "பலமுரை திரும்ப செய் (முடயேனில்)",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "மாறி பொய் ஆக உள்ள வரை, கட்டளைகளை இயக்கு",
                +	"CONTROLS_FOR_TOOLTIP": "முதல் எண்ணில்  இருந்து கடை எண் வரை எடுத்துக்கொள்ள  ஒரு மாறியை வைத்துக்கொள், குறித்த இடைவெளியை  சேர்த்தவறே தொகுதிகளை செயலாக்கு.",
                +	"CONTROLS_FOR_TITLE": "மாறியை வைத்து எண்ண %1 %2 இல் இருந்து %3 வரை %4-இன் படியாக",
                +	"CONTROLS_FOREACH_TITLE": "உருப்படி ஒவ்வொன்றாக %1 பட்டியலில் உள்ள %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "பட்டியலில் உள்ள உருப்படியில் ஒவ்வொன்றாக, மாறியின் பொருள் '%1' ஆக  வைக்க.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "மடக்கு கட்டளையை நிறுத்து.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "மடக்கு கட்டளையின் அடுத்த இயக்கநிலைக்கு செல்",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "மடக்கு கட்டளையின் இயக்கத்தில் இருந்து நிறுத்து.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "மடக்கு கட்டளையின் மீதியை விட்டுவிட்டு அடுத்த இயக்கநிலைக்கு செல்",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "எச்சரிக்கை : மடக்கு கூற்றில் இந்த தொகுதி ஒரு முறை மட்டுமே செயல்படுத்தப் படலாம்.",
                +	"CONTROLS_IF_TOOLTIP_1": "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு",
                +	"CONTROLS_IF_TOOLTIP_2": "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை இயக்கு.",
                +	"CONTROLS_IF_TOOLTIP_3": "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை தொகுப்பு இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை தொகுப்பு இயக்கு.",
                +	"CONTROLS_IF_TOOLTIP_4": "மாறி உண்மை ஆக உள்ள வரை, கட்டளைகளை தொகுப்பு இயக்கு. அல்லது மற்ற (அடுத்த) கட்டளைகளை தொகுப்பு இயக்கு. இரண்டும் இல்லை என்றால் கடைசி தொகுப்பு இயக்கு.",
                +	"CONTROLS_IF_MSG_IF": "எனில்",
                +	"CONTROLS_IF_MSG_ELSEIF": "இல்லைஆனால்",
                +	"CONTROLS_IF_MSG_ELSE": "இல்லையெனில்",
                +	"CONTROLS_IF_IF_TOOLTIP": "கட்டளைகளை தொகுப்பு திருத்துதம் செய்",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "ஆனால் தொகுப்பிற்கு நிபந்தனை சேர்க்க",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "ஆனால் தொகுப்பிற்கு விதிவிலக்கு காப்பை சேர்க்க",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "இரண்டு மாறியும் ஈடானால், மெய் பின்கொடு.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "இரண்டு மாறியும் ஈடாகாவிட்டால், மெய் பின்கொடு.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "முதல் உள்ளீடு இரண்டாவதைவிட குறைவாக இருந்தால், மெய் பின்கொடு.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "முதல் உள்ளீடு இரண்டாவதைவிட குறைவாக அல்ல சமமாக இருந்தால், மெய் பின்கொடு",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "முதல் உள்ளீடு இரண்டாவதைவிட அதிகமாக இருந்தால், மெய் பின்கொடு.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "முதல் உள்ளீடு இரண்டாவதைவிட அதிகமாக அல்ல சமமாக இருந்தால், மெய் பின்கொடு.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "இரண்டு மாறியும் மெய் ஆனால், மெய் பின்கொடு.",
                +	"LOGIC_OPERATION_AND": "மற்றும்",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "ஏதேனும் ஒரு மதிப்பு மெய் ஆனால், மெய் பின்கொடு",
                +	"LOGIC_OPERATION_OR": "அல்லது",
                +	"LOGIC_NEGATE_TITLE": "%1 இல்லை",
                +	"LOGIC_NEGATE_TOOLTIP": "மெய் ஆனால், பொய் பின்கொடு. பொய் ஆனால், மெய் பின்கொடு.",
                +	"LOGIC_BOOLEAN_TRUE": "மெய்",
                +	"LOGIC_BOOLEAN_FALSE": "பொய்",
                +	"LOGIC_BOOLEAN_TOOLTIP": "மெய், அல்லது பொய் பின்கொடு.",
                +	"LOGIC_NULL": "பூஜியம்",
                +	"LOGIC_NULL_TOOLTIP": "பூஜியம் பின்கொடு",
                +	"LOGIC_TERNARY_CONDITION": "சோதனை",
                +	"LOGIC_TERNARY_IF_TRUE": "மெய்யெனில்",
                +	"LOGIC_TERNARY_IF_FALSE": "பொய்யெனில்",
                +	"LOGIC_TERNARY_TOOLTIP": "'test' உள்ள நிபந்தனையை சரிபார்க்கவும், நிபந்தனை மெய்யானால்,'if true'வை  பின்கொடுக்கும் இல்லையெனில்  'if false'வை  பின்கொடுக்கும்.",
                +	"MATH_NUMBER_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%8E%E0%AE%A3%E0%AF%8D",
                +	"MATH_NUMBER_TOOLTIP": "ஒரு எண்.",
                +	"MATH_ARITHMETIC_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%8E%E0%AE%A3%E0%AF%8D%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A4%E0%AE%AE%E0%AF%8D",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "இரு எண்களின் கூட்டை பின்கொடு",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "இரு எண்களின் கழிப்பை பின்கொடு",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "இரு எண்களின் பெருக்கலை பின்கொடு",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "இரு எண்களின் வகுத்தல் பின்கொடு",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "முதல் உள்ளீடு இரண்டாவது எண் அளவான அடுக்கு பெருக்கை கணித்து பின்கொடு.",
                +	"MATH_SINGLE_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%B5%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%82%E0%AE%B2%E0%AE%AE%E0%AF%8D",
                +	"MATH_SINGLE_OP_ROOT": "வர்க்கமூலம்",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ஒரு எண்ணின் வர்க்கமூலத்தைத் தரும்.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "தனித்த",
                +	"MATH_SINGLE_TOOLTIP_ABS": "ஒரு எண்ணின் தனித்த மதிப்பை பின்கொடு",
                +	"MATH_SINGLE_TOOLTIP_NEG": "ஒரு எண்ணின் எதிர்மறை மதிப்பை பின்கொடு",
                +	"MATH_SINGLE_TOOLTIP_LN": "ஒரு எண்ணின் (இயற்கை) மடக்கை மதிப்பை பின்கொடு.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "ஒரு எண்ணின் (10) மடக்கை மதிப்பை பின்கொடு.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "e-இன் எண் அடுக்கு  பெருக்கை பின்கொடு.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "10-இன் எண் அடுக்கு  பெருக்கை பின்கொடு.",
                +	"MATH_TRIG_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%AE%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8B%E0%AE%A3%E0%AE%B5%E0%AE%BF%E0%AE%AF%E0%AE%B2%E0%AF%8D_%E0%AE%9A%E0%AE%BE%E0%AE%B0%E0%AF%8D%E0%AE%AA%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AF%8D",
                +	"MATH_TRIG_TOOLTIP_SIN": "டிகிரீ சைன் மதிப்பை பின்கொடு.",
                +	"MATH_TRIG_TOOLTIP_COS": "டிகிரீ கோசைன் மதிப்பை பின்கொடு",
                +	"MATH_TRIG_TOOLTIP_TAN": "டிகிரீ டேஞ்சன்டு மதிப்பை பின்கொடு",
                +	"MATH_TRIG_TOOLTIP_ASIN": "மதிப்பின் நேர்மாறு சைன் பின்கொடு",
                +	"MATH_TRIG_TOOLTIP_ACOS": "மதிப்பின் நேர்மாறு கோசைன் பின்கொடு",
                +	"MATH_TRIG_TOOLTIP_ATAN": "மதிப்பின் நேர்மாறு டேஞ்சன்டு பின்கொடு",
                +	"MATH_CONSTANT_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A4_%E0%AE%AE%E0%AE%BE%E0%AE%B1%E0%AE%BF%E0%AE%B2%E0%AE%BF",
                +	"MATH_CONSTANT_TOOLTIP": "ஒரு மாறிலியை பின்கொடு π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (முடிவிலி).",
                +	"MATH_IS_EVEN": "2-ஆல் பகும்",
                +	"MATH_IS_ODD": "2-ஆல் பகாத",
                +	"MATH_IS_PRIME": "எண் பகாத்தனிதானதா?",
                +	"MATH_IS_WHOLE": "எண் முழுதானதா?",
                +	"MATH_IS_POSITIVE": "எண் நேர்ம முழுதானதா  ?",
                +	"MATH_IS_NEGATIVE": "எண் குறைவானதா  ?",
                +	"MATH_IS_DIVISIBLE_BY": "ஆல் வகுபடக் கூடியது",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "மாற்று %1 மூலம் %2",
                +	"MATH_CHANGE_TOOLTIP": "எண்னை '%1' மதிப்பால் கூட்டு,",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "மேல்/கீழ் வழி முழு எண் ஆக மாற்று.",
                +	"MATH_ROUND_OPERATOR_ROUND": "முழுமையாக்கு",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "மேல்வழி முழுமையாக்கு",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "கீழ்வழி முழுமையாக்கு",
                +	"MATH_ONLIST_OPERATOR_SUM": "பட்டியலின் கூட்டு",
                +	"MATH_ONLIST_TOOLTIP_SUM": "முழு பட்டியலின் எண் சமம் பின்கொடு,",
                +	"MATH_ONLIST_OPERATOR_MIN": "பட்டியலின் கறைவு",
                +	"MATH_ONLIST_TOOLTIP_MIN": "பட்டியலின் குறைவான எண் பின்கொடு",
                +	"MATH_ONLIST_OPERATOR_MAX": "பட்டியலின் மிகுதி",
                +	"MATH_ONLIST_TOOLTIP_MAX": "பட்டியலின் அதிகமான எண் பின்கொடு",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "பட்டியலின் எண் சராசரி",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "முழு பட்டியலின் எண் சராசரி பின்கொடு",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "பட்டியலின் நடுக்கோடு",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "பட்டியலின் நடுக்கோடு பின்கொடு",
                +	"MATH_ONLIST_OPERATOR_MODE": "பட்டியலின் பொதுவகைகள்",
                +	"MATH_ONLIST_TOOLTIP_MODE": "பட்டியலின் பொதுவகைகள் பின்கொடு",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "பட்டியலின் நியமவிலகல்",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "பட்டியலின் நியமவிலகலை பின்கொடு.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "ஒரு பட்டியலில் இருந்து சீரற்ற உருப்படி",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "ஒரு பட்டியலில் இருந்து சீரற்ற உருப்படி பின்கொடு",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2ன் மீதி",
                +	"MATH_MODULO_TOOLTIP": "இரண்டு எண்கள் மூலம் பிரிவில் இருந்து எஞ்சியதை பின்கொடு.",
                +	"MATH_CONSTRAIN_TITLE": "%1 மாறியை %2 மேலும் %3 கீழும் வற்புறுத்து",
                +	"MATH_CONSTRAIN_TOOLTIP": "எண் மாறி வீசுகளம் உள்ளடங்கிய வாறு வற்புறுத்து",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "வீசுகளம் %1 இல் இருந்து %2 உள்ளடங்கிய வாறு  சீரற்ற எண்",
                +	"MATH_RANDOM_INT_TOOLTIP": "வீசுகளம் இல் இருந்த (உள்ளடங்கிய) வாறு  சீரற்ற எண் பின்கொடு.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "சீரற்ற எண் பின்னம்",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "சீரற்ற எண் பின்னம், 0.0 இல் இருந்து 1.0 உட்பட, பின்கொடு.",
                +	"TEXT_TEXT_HELPURL": "https://ta.wikipedia.org/wiki/%E0%AE%9A%E0%AE%B0%E0%AE%AE%E0%AF%8D_%28%E0%AE%95%E0%AE%A3%E0%AE%BF%E0%AE%A9%E0%AE%BF%E0%AE%AF%E0%AE%BF%E0%AE%AF%E0%AE%B2%E0%AF%8D%29",
                +	"TEXT_TEXT_TOOLTIP": "எழுத்து, சரம், சொல், அல்லது உரை சொற்தொடர்.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "வைத்து உரை உருவாக்க",
                +	"TEXT_JOIN_TOOLTIP": "பல பொருட்களை ஒன்றாக சேர்வதன் மூலம் உரை உருவாக்க.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "சேர்க்க",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "தொகுப்பு உரை திருத்துதம் செய்",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "உருபடியை உரையில் சேர்க்க.",
                +	"TEXT_APPEND_TOOLTIP": "'%1' மாறியில் உரையை சேர்",
                +	"TEXT_LENGTH_TITLE": "%1ன் நீளம்",
                +	"TEXT_LENGTH_TOOLTIP": "தொடரில் உள்ள எழுத்துக்களின் (இடைவெளிகளையும் சேர்த்து) எண்ணிகையை பின்கொடு.",
                +	"TEXT_ISEMPTY_TITLE": "%1 காலியானது",
                +	"TEXT_ISEMPTY_TOOLTIP": "காலியானது என்றால் மெய் மதிப்பை பின்கொடு",
                +	"TEXT_INDEXOF_TOOLTIP": "இரண்டாவது உரையில் முதல் உரையின் முதல்/கடை இருக்கை குறிஎண்ணை பின்கொடு.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "உரையில் முதல் தோற்ற இடத்தை பின்கொடு",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "உரையில் கடைசி தோற்ற இடத்தை பின்கொடு",
                +	"TEXT_CHARAT_FROM_START": "# எழுத்தை எடு",
                +	"TEXT_CHARAT_FROM_END": "முடிவில் இருந்து # எழுத்தை எடு",
                +	"TEXT_CHARAT_FIRST": "முதல் எழுத்தைப் பெறுக",
                +	"TEXT_CHARAT_LAST": "இறுதி எழுத்தைப் பெறுக",
                +	"TEXT_CHARAT_RANDOM": "சமவாய்ப்புள்ள எழுத்தை எடு",
                +	"TEXT_CHARAT_TOOLTIP": "கூறிய இடத்தில் உள்ள எழுத்தை எடு",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "உரையின் குறியிடப்பட்ட சரம் பின்கொடு",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "உரையில்",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "-இல் உட்கணம் # எழுத்திலிருந்து",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "-இல் உட்கணம் கடைசி # எழுத்திலிருந்து",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "-இல் உட்கணம் முதல் எழுத்திலிருந்து",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "எழுத்து # வரை",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "எழுத்து கடைசியில் இருந்து # வரை",
                +	"TEXT_GET_SUBSTRING_END_LAST": "கடைசி எழுத்து  வரை",
                +	"TEXT_CHANGECASE_TOOLTIP": "உரை நகல் எடுத்து பொரிய/சின்ன எழுத்து மாற்றி பின்கொடு.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "பொரிய எழுத்துக்கு மாற்று",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "சின்ன எழுத்துக்கு மாற்று",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "தலைப்பு எழுத்துக்கு மாற்று",
                +	"TEXT_TRIM_TOOLTIP": "உரை நகல் எடுத்து இடைவெளி எழுத்து நீக்கி பின்கொடு.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "இரு பக்கத்திலும் இடைவெளி எழுத்து நேர்த்தி செய்.",
                +	"TEXT_TRIM_OPERATOR_LEFT": "இடது பக்கத்தில் இடைவெளி எழுத்து நேர்த்தி செய்.",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "வலது பக்கத்தில் இடைவெளி எழுத்து நேர்த்தி செய்.",
                +	"TEXT_PRINT_TITLE": "%1 அச்சிடுக",
                +	"TEXT_PRINT_TOOLTIP": "மதிப்பை அச்சிடு",
                +	"TEXT_PROMPT_TYPE_TEXT": "உரை கொண்டு உரை-உள்ளீடு தூண்டுதலை காட்டு",
                +	"TEXT_PROMPT_TYPE_NUMBER": "உரை கொண்டு எண்-உள்ளீடு தூண்டுதலை காட்டு",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "எண்-உள்ளீடு தூண்டுதலை காட்டு",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "உரை-உள்ளீடு தூண்டுதலை காட்டு",
                +	"LISTS_CREATE_EMPTY_TITLE": "காலி பட்டியல் உருவாக்க",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "காலி பட்டியல் பின்கொடு.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "இவ்வளவு உருப்படிகளை கொண்டு வேண்டுமாலும் ஒரு பட்டியலை உருவாக்கு.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "வைத்து பட்டியல் உருவாக்க",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "பட்டியல்",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "கட்டளைகளை தொகுப்பு திருத்துதம் செய்",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "பட்டியலில் ஒரு பொருளை சேர்க்க.",
                +	"LISTS_REPEAT_TOOLTIP": "கொடுக்க பட்ட மதிப்பை, கூறியுள்ள தடவைகள் உள்ளவாறு ஒரு பட்டியலை உருவாக்கு",
                +	"LISTS_REPEAT_TITLE": "உருப்படி %1-யை, %2 தடவைகள் உள்ளவாறு ஒரு பட்டியலை உருவாக்கு",
                +	"LISTS_LENGTH_TITLE": "%1 இன் நீளம்",
                +	"LISTS_LENGTH_TOOLTIP": "பட்டியல் நீளம் பின்கொடு",
                +	"LISTS_ISEMPTY_TITLE": "%1 காலியானது",
                +	"LISTS_ISEMPTY_TOOLTIP": "பட்டியல் காலியானது மெய் பின்கொடு,",
                +	"LISTS_INLIST": "பட்டியலில் உள்ள",
                +	"LISTS_INDEX_OF_FIRST": "உரையில் முதல் தோற்ற இடத்தை காட்டு",
                +	"LISTS_INDEX_OF_LAST": "உரையில் கடைசி தோற்ற இடத்தை காட்டு",
                +	"LISTS_INDEX_OF_TOOLTIP": "பட்டியலில் மதிப்பின் முதல், கடைசி தோற்ற இடத்தை பின்கொடு. காணாவிட்டால் %1 பின்கொடு.",
                +	"LISTS_GET_INDEX_GET": "எடு",
                +	"LISTS_GET_INDEX_GET_REMOVE": "பெற்று நீக்குக",
                +	"LISTS_GET_INDEX_REMOVE": "நீக்குக",
                +	"LISTS_GET_INDEX_FROM_END": "கடைசியில் இருந்து #",
                +	"LISTS_GET_INDEX_FIRST": "முதல்",
                +	"LISTS_GET_INDEX_LAST": "கடைசி",
                +	"LISTS_GET_INDEX_RANDOM": "ஏதோ ஒன்று",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 முதல் உருப்படி.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 கடைசி உருப்படி.ி",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "பட்டியலில்  இடத்தில் உருப்படி பின்கொடு.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "பட்டியல் முதல் உருப்படியை பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "பட்டியல் கடைசி உருப்படியை பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "பட்டியல் சீரற்ற உருப்படியை பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "பட்டியலில் கேட்ட இடத்தின் உருப்படி நீக்கி பின்கொடு.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "பட்டியல் முதல் உருப்படியை நீக்கியபின் பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "பட்டியல் இறுதி உருப்படியை நீக்கியபின் பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "பட்டியல் சீரற்ற உருப்படியை நீக்கியபின் பின்கொடு,",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "பட்டியலில் கேட்ட இடத்தின் உருப்படி நீக்கு.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "பட்டியலில் முதல் உருப்படியை நீக்கு",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "பட்டியலில் கடைசி உருப்படியை நீக்கு",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "பட்டியல் சீரற்ற உருப்படியை நீக்கு,",
                +	"LISTS_SET_INDEX_SET": "நியமி",
                +	"LISTS_SET_INDEX_INSERT": "அவ்விடத்தில் நுழை",
                +	"LISTS_SET_INDEX_INPUT_TO": "இதுபொல",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "பட்டியலில் கேட்ட இடத்தில் உருப்படியை வை.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "மதிப்பை பட்டியலில் முதல் உருப்படியில் வை",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "மதிப்பை பட்டியலில் கடைசி உருப்படியில் வை",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "மதிப்பை பட்டியலில் சீரற்ற உருப்படியில் வை",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "பட்டியலில் கேட்ட இடத்தில் உருப்படியை நுழை.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "மதிப்பை பட்டியலின் முதலில் நுழை",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "மதிப்பை பட்டியலின் முடிவில் நுழை",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "மதிப்பை பட்டியலின் சீற்ற இடத்தில் நுழை",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "பகுதி பட்டியலை # இடத்தில் இருந்து கொடு",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "# கடைசியில் இருந்து பகுதி பட்டியலை கொடு",
                +	"LISTS_GET_SUBLIST_START_FIRST": "# முதலில் இருந்து பகுதி பட்டியலை கொடு",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "# வரை",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "முடிவில் இருந்து # வரை",
                +	"LISTS_GET_SUBLIST_END_LAST": "முடிவு வரை",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "குறிப்பட்ட பகுதி பட்டியலின் நகலை கொடு",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "உரையில் இருந்து பட்டியல் உருவாக்கு",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "பட்டியலில் இருந்து உரை உருவாக்கு",
                +	"LISTS_SPLIT_WITH_DELIMITER": "தடை எழுத்து",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "உரையை வரம்புச் சுட்டி கொண்டு துண்டாக்கு.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "வரம்புச் சுட்டியை இடையில் இட்டு, உரைதுண்டுகளை ஒன்று சேர்",
                +	"VARIABLES_GET_TOOLTIP": "இந்த மாறி மதிப்பை பின்கொடு",
                +	"VARIABLES_GET_CREATE_SET": "'%1 நியமி' உருவாக்கு",
                +	"VARIABLES_SET": "நியமி %1 இந்த மாறியிற்கு %2",
                +	"VARIABLES_SET_TOOLTIP": "மாறியின் மதிப்பாய் உள்ளீட்டு மதிப்பை வை.",
                +	"VARIABLES_SET_CREATE_GET": "'எடு %1' உருவாக்கு",
                +	"PROCEDURES_DEFNORETURN_TITLE": "இந்த மாறியிற்கு",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "கட்டளைகள் செய்ய (இடம்காட்டி)",
                +	"PROCEDURES_BEFORE_PARAMS": "இத்துடன்",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "இத்துடன்:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "வெளியீடு இல்லாத ஒரு செயல்பாடு உருவாக்குகிறது",
                +	"PROCEDURES_DEFRETURN_RETURN": "பின்கொடு",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "வெளியீடு உள்ள ஒரு செயல்பாடு உருவாக்குகிறது",
                +	"PROCEDURES_ALLOW_STATEMENTS": "வாக்குமூலங்களை அனுமதிக்கவும்",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "எச்சரிக்கை: இந்த செயற்கூறில் போலியான அளபுருக்கள் உண்டு.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "பயனரின் '%1' செயற்கூற்றை ஓட்டு.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "பயனரின் '%1' செயற்கூற்றை ஓட்டி வரும் வெளியீட்டை பயன்படுத்து.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "உள்ளீடுகள்",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "செயல்கூறுகளின் உள்ளீட்டை சேர், நீக்கு, or மீண்டும் வரிசை செய்.",
                +	"PROCEDURES_MUTATORARG_TITLE": "பெயரை உள்ளிடுக:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "செயல்கூறுக்கு ஒரு உள்ளீட்டை சேர்.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "நிரல்பாகத்தை விளக்கமாக காட்டு",
                +	"PROCEDURES_CREATE_DO": "'%1' உருவாக்குக",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "மதிப்பு உண்மையானால், இரண்டாவது மதிப்பை பின்கொடு."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/tcy.json b/blockly/webif/static/blockly/msg/json/tcy.json
                new file mode 100644
                index 000000000..2d55361be
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/tcy.json
                @@ -0,0 +1,325 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Vishwanatha Badikana",
                +			"Bharathesha Alasandemajalu",
                +			"Kiranpoojary",
                +			"BHARATHESHA ALASANDEMAJALU"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "ವಸ್ತು",
                +	"TODAY": "ಇನಿ",
                +	"DUPLICATE_BLOCK": "ನಕಲ್",
                +	"ADD_COMMENT": "ಟಿಪ್ಪಣಿ ಸೇರ್ಸಲೆ",
                +	"REMOVE_COMMENT": "ಟಿಪ್ಪಣಿನ್ ದೆತ್ತ್‌ದ್ ಬುಡ್ಲೆ",
                +	"EXTERNAL_INPUTS": "ಪಿದಯಿದ ಪರಿಪು",
                +	"INLINE_INPUTS": "ಉಳಸಾಲ್‍ದ ಉಳಪರಿಪು",
                +	"DELETE_BLOCK": "ಬ್ಲಾಕ್‍ನ್ ಮಾಜಾವು",
                +	"DELETE_X_BLOCKS": "%1 ಬ್ಲಾಕ್‍ಲೆನ್ ಮಾಜಾವು",
                +	"DELETE_ALL_BLOCKS": "ಮಾತ %1 ಬ್ಲಾಕ್‍ಲೆನ್ ದೆತ್ತ್‌ದ್ ಬುಡೊಡೆ?",
                +	"CLEAN_UP": "ಬ್ಲಾಕ್‍ಲೆನ್ ಸ್ವೊಚ್ಚೊ ಮಲ್ಪುಲೆ",
                +	"COLLAPSE_BLOCK": "ಎಲ್ಯೆ ಮಲ್ತ್‌ದ್ ತಡೆಲೆ",
                +	"COLLAPSE_ALL": "ಮಾತಾ ತಡೆಕ್ಲೆನ ಮಾಹಿತಿನ್ ಎಲ್ಯ ಮಲ್ಪು",
                +	"EXPAND_BLOCK": "ಬ್ಲಾಕ್‍ದ ಮಾಹಿತಿನ್ ಪರಡಾವು",
                +	"EXPAND_ALL": "ಮಾತಾ ತಡೆಕ್ಲೆನ ಮಾಹಿತಿನ್ ಪರಡಾವು",
                +	"DISABLE_BLOCK": "ಬ್ಲಾಕ್‍ನ್ ದೆತ್ತ್‌ಪಾಡ್",
                +	"ENABLE_BLOCK": "ತಡೆನ್ ಸಕ್ರಿಯೊ ಮಲ್ಪು",
                +	"HELP": "ಸಕಾಯೊ",
                +	"UNDO": "ದುಂಬುದಲೆಕೊ",
                +	"REDO": "ಕುಡ ಮಲ್ಪು",
                +	"CHANGE_VALUE_TITLE": "ಮೌಲ್ಯೊನು ಬದಲ್ ಮಲ್ಪು",
                +	"RENAME_VARIABLE": "ವ್ಯತ್ಯಯೊಗು ಕುಡೊರ ಪುದರ್ ದೀಲೆ",
                +	"RENAME_VARIABLE_TITLE": "ಮಾತಾ '%1' ವ್ಯತ್ಯಯೊಲೆನ ಪುದರ್‌ನ್ ನೆಕ್ಕ್ ಬದಲ್ ಮಲ್ಪುಲೆ:",
                +	"NEW_VARIABLE": "ವ್ಯತ್ಯಯೊನು ಉಂಡು ಮಲ್ಪುಲೆ",
                +	"NEW_VARIABLE_TITLE": "ಪೊಸ ವ್ಯತ್ಯಯೊದ ಪುದರ್:",
                +	"VARIABLE_ALREADY_EXISTS": "'%1' ಪನ್ಪಿ ಪುದರ್‌ದ ವ್ಯತ್ಯಯೊ ದುಂಬೆ ಅಸ್ತಿತ್ವೊಡು ಉಂಡು.",
                +	"PROCEDURE_ALREADY_EXISTS": "'%1' ಪನ್ಪಿ ಪುದರ್‌ದ ಕಾರ್ಯೊವಿದಾನೊ ದುಂಬೆ ಅಸ್ತಿತ್ವೊಡು ಉಂಡು.",
                +	"DELETE_VARIABLE_CONFIRMATION": "'%2' ವ್ಯತ್ಯಯೊದ %1 ಉಪಯೋಗೊಲೆನ್ ಮಾಜಾವೊಡೆ?",
                +	"DELETE_VARIABLE": "'%1' ವ್ಯತ್ಯಯೊನು ಮಾಜಾಲೆ",
                +	"COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/ಬಣ್ಣೊ",
                +	"COLOUR_PICKER_TOOLTIP": "ಬಣ್ಣೊ ಪಟೊಡ್ದು ಒಂಜಿ ಬಣ್ಣೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ.",
                +	"COLOUR_RANDOM_TITLE": "ಒವ್ವೇ ಒಂಜಿ ಬಣ್ಣೊ",
                +	"COLOUR_RANDOM_TOOLTIP": "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಬಣ್ಣೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ",
                +	"COLOUR_RGB_TITLE": "ಬಣ್ಣೊದ",
                +	"COLOUR_RGB_RED": "ಕೆಂಪು",
                +	"COLOUR_RGB_GREEN": "ಪಚ್ಚೆ",
                +	"COLOUR_RGB_BLUE": "ನೀಲಿ",
                +	"COLOUR_RGB_TOOLTIP": "ತೊಜಪಾಯಿನ ಪ್ರಮಾಣೊದ ಕೆಂಪು, ಪಚ್ಚೆ ಬೊಕ್ಕ ನೀಲಿ ಬಣ್ಣೊಡ್ದು ಒಂಜಿ ಬಣ್ಣೊನು ಉಂಡು ಮಲ್ಪುಲೆ. ಮಾತಾ ಮೌಲ್ಯೊಲು 0 ಬುಕ್ಕೊ 100 ತ ನಡುಟೆ ಇಪ್ಪೊಡು.",
                +	"COLOUR_BLEND_TITLE": "ಬೆರಕ್ಕೆ ಮಲ್ಪು",
                +	"COLOUR_BLEND_COLOUR1": "ಬಣ್ಣೊ ೧(ಒಂಜಿ)",
                +	"COLOUR_BLEND_COLOUR2": "ಬಣ್ಣೊ ೨(ರಡ್ಡ್)",
                +	"COLOUR_BLEND_RATIO": "ಅನುಪಾತೊ",
                +	"COLOUR_BLEND_TOOLTIP": "ಕೊರಿನ ಅನುಪಾತೊಡು (0.0- 1.0) ರಡ್ಡ್ ಬಣ್ಣೊಲೆನ್ ಬೆರಕೆ ಮಲ್ಪುಂಡು.",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": " %1 ಸರ್ತಿ ಕೂಡೊರ ಮಲ್ಪು",
                +	"CONTROLS_REPEAT_INPUT_DO": "ಮಲ್ಪುಲೆ",
                +	"CONTROLS_REPEAT_TOOLTIP": "ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಸ್ತ್ ಸರ್ತಿ ಮಲ್ಪು",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ಉಂದು ನಿಜ ಆಂಡ ಕುಡೊರ ಮಲ್ಪು:",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ಉಂದು ನಿಜ ಆಪಿಲೆಕೊ ಕುಡೊರ ಮಲ್ಪು:",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "ಮೌಲ್ಯ ನಿಜ ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "ಮೌಲ್ಯ ತಪ್ಪು ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು",
                +	"CONTROLS_FOR_TOOLTIP": "ನಿರ್ದಿಸ್ಟೊ ಮದ್ಯಂತರೊದ ಮೂಲಕೊ ದೆತೊಂದು '%1' ವ್ಯತ್ಯಯೊಡ್ ಸುರುತ್ತ ಅಂಕೆಡ್ದ್ ಕಡೆತ್ತ ಅಂಕೆ ಮುಟ್ಟದ ಮೌಲ್ಯೊನು ದೆತ್ತೊನಾವ್ ಬೊಕ್ಕ ನಿಗಂಟ್ ಮಲ್ತಿನ ತಡೆಕ್ಲೆನ್ ಮಲ್ಪು",
                +	"CONTROLS_FOR_TITLE": "%2 ಡ್ದ್ %3 ಮುಟ %4 ಸರ್ತಿ %1 ದ ಒಟ್ಟುಗು ಗೆನ್ಪು",
                +	"CONTROLS_FOREACH_TITLE": "%2 ಪಟ್ಟಿಡ್ ಪ್ರತಿ ಒಂಜಿ ವಿಸಯ %1 ಗ್",
                +	"CONTROLS_FOREACH_TOOLTIP": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಪ್ರತಿ ವಿಸಯೊಗು, '%1' ವ್ಯತ್ಯಾಯೊನು ವಿಸಯೊಗು ಜೋಡಾಲೆ, ಬೊಕ್ಕ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪುಲೆ.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ಲೂಪ್ ಕಡಿಯುನಿ",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ಬೊಕ್ಕದ ಲೂಪ್ ಪುನರಾವರ್ತನೆದೊಟ್ಟುಗು ದುಂಬರಿಲೆ",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "ಇತ್ತಿನ ಲೂಪ್‍ಡ್ದ್ ಪದಿಯಿ ಬಲೆ",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "ಈ ಲೂಪುನು ಅರ್ದೊಡೆ ಬುಡುದ್ ಬೊಕ್ಕ ನನತ್ತ ಪುನರಾವರ್ತನೆಗ್ ದುಂಬರಿಲೆ",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "ಎಚ್ಚರೊ: ಈ ತಡೆನ್ ಕಾಲಿ ಒಂಜಿ ಲೂಪುದುಲಯಿ ಮಾತ್ರ ಗಳಸೊಲಿ.",
                +	"CONTROLS_IF_TOOLTIP_1": "ಮೌಲ್ಯ ನಿಜ ಆದಿತ್ತ್ಂಡ ಕೆಲವು ಪಾತೆರೊಲೆನ್ ಮಲ್ಪು",
                +	"CONTROLS_IF_TOOLTIP_2": "ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು.",
                +	"CONTROLS_IF_TOOLTIP_3": "ಸುರುತ್ತ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ, ರಡ್ಡನೆ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್ಂಡ, ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು.",
                +	"CONTROLS_IF_TOOLTIP_4": "ಸುರುತ್ತ ಮೌಲ್ಯೊ ನಿಜವಾದಿತ್ತ್‌ಂಡ, ಪಾತೆರೊಲೆನ ಸುರುತ್ತ ತಡೆ ಮಲ್ಪು. ಇಜ್ಜಿಂಡ, ರಡ್ಡನೆದ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತ್ಂಡ, ಪಾತೆರೊಲೆನ ರಡ್ಡನೆ ತಡೆ ಮಲ್ಪು. ಒಂಜೇಲೆ ಒವ್ವೇ ಮೌಲ್ಯ ನಿಜವಾದಿತ್ತಿಜಿಂಡ, ಪಾತೆರೊಲೆನ ಕಡೆತ್ತ ತಡೆ ಮಲ್ಪು.",
                +	"CONTROLS_IF_MSG_IF": "ಒಂಜಿ ವೇಲೆ",
                +	"CONTROLS_IF_MSG_ELSEIF": "ಅತ್ತಂಡ",
                +	"CONTROLS_IF_MSG_ELSE": "ಅತ್ತಂಡ",
                +	"CONTROLS_IF_IF_TOOLTIP": "ಸೇರಾವ್, ದೆತ್ತ್‌ ಬುಡು, ಅತ್ತಂಡ ಈ 'ಒಂಜಿ ವೇಲೆ' ತಡೆನ್ ಕುಡ ಸಂರಚಣೆ ಮಲ್ಪೆರೆ ವಿಭಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "'ಒಂಜಿ ವೇಲೆ' ತಡೆಕ್ಕ್ ಒಂಜಿ ಶರ್ತನ್ ಸೇರಾವ್",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "'ಒಂಜಿ ವೇಲೆ' ತಡೆಕ್ಕ್ ಒಂಜಿ ಕಡೆತ್ತ ಮಾತೆನ್ಲಾ-ಪತ್ತ್ (catch-all) ಶರ್ತನ್ ಸೇರಾವ್",
                +	"IOS_OK": "ಸರಿ",
                +	"IOS_CANCEL": "ವಜಾ ಮಲ್ಪುಲೆ",
                +	"IOS_ERROR": "ದೋಷ",
                +	"IOS_PROCEDURES_INPUTS": "ಇನ್‌ಪುಟ್‌ಲು",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ ಇನ್‌ಪುಟ್ ಸೇರಾಲೆ",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "ಹೇಳಿಕೆಗ್ ಅವಕಾಸೊ",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "ಈ ಕಾರ್ಯೊಡು ಡುಪ್ಲಿಕೇಟ್ ಇನ್‌ಪುಟ್ ಉಂಡು.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ ವ್ಯತ್ಯಯೊನು ಸೇರಾಲೆ",
                +	"IOS_VARIABLES_ADD_BUTTON": "ಸೇರಾಲೆ",
                +	"IOS_VARIABLES_RENAME_BUTTON": "ಪೊಸ ಪುದರ್",
                +	"IOS_VARIABLES_DELETE_BUTTON": "ಮಾಜಾಲೆ",
                +	"IOS_VARIABLES_VARIABLE_NAME": "ವ್ಯತ್ಯಯೊದ ಪುದರ್",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "ವ್ಯತ್ಯಯೊದ ಪುದರ್‌ನ್ ಖಾಲಿ ಬುಡಿಯೆರೆ ಆಪುಜಿ",
                +	"LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "ರಡ್ದ್ ಇನ್‌ಪುಟ್‌ಲಾ ಸಮ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "ರಡ್ದ್ ಇನ್‌ಪುಟ್‌ಲಾ ಸಮ ಅತ್ತಾಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಎಲ್ಯ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಎಲ್ಯ ಅತ್ತಂಡ ಅಯಿಕ್ಕ್ ಸಮ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಮಲ್ಲ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "ಸುರುತ್ತ ಇನ್‌ಪುಟ್ ರಡ್ಡನೆ ಇನ್‌ಪುಟ್‌ಡ್ದ್ ಮಲ್ಲ ಅತ್ತಂಡ ಅಯಿಕ್ಕ್ ಸಮ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "ರಡ್ಡ್‌ಲಾ ಇನ್‌ಪುಟ್ ನಿಜ ಆದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು",
                +	"LOGIC_OPERATION_AND": "ಬುಕ್ಕೊ",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಇನ್‌ಪುಟ್ ನಿಜ ಆಂಡಲಾ, 'ನಿಜ'ನ್ ಪಿರಕೊರು.",
                +	"LOGIC_OPERATION_OR": "ಅತ್ತಂಡ",
                +	"LOGIC_NEGATE_TITLE": "%1 ಅತ್ತ್",
                +	"LOGIC_NEGATE_TOOLTIP": "ಇನ್‌ಪುಟ್ ಸುಲ್ಲಾದಿತ್ತ್ಂಡ, 'ನಿಜ'ನ್ ಪಿರಕೊರು. ಇನ್‌ಪುಟ್ ನಿಜ ಆದಿತ್ತ್ಂಡ, 'ಸುಲ್ಲು'ನ್ ಪಿರಕೊರು.",
                +	"LOGIC_BOOLEAN_TRUE": "ಸತ್ಯೊ",
                +	"LOGIC_BOOLEAN_FALSE": "ಸುಲ್ಲು",
                +	"LOGIC_BOOLEAN_TOOLTIP": "ಒಂಜೆ ನಿಜ ಅತ್ತಂಡ ಸುಲ್ಲುನ್ ಪಿರಕೊರು",
                +	"LOGIC_NULL": "ಸೊನ್ನೆ",
                +	"LOGIC_NULL_TOOLTIP": "ಸೊನ್ನೆನ್ ಪಿರಕೊರ್ಪುಂಡು",
                +	"LOGIC_TERNARY_CONDITION": "ಪರೀಕ್ಷೆ",
                +	"LOGIC_TERNARY_IF_TRUE": "ಒಂಜಿ ವೇಲೆ ನಿಜ ಆಂಡ",
                +	"LOGIC_TERNARY_IF_FALSE": "ಒಂಜಿ ವೇಲೆ ಸುಲ್ಲಾಂಡ",
                +	"LOGIC_TERNARY_TOOLTIP": "'ಪರೀಕ್ಷೆ'ಡ್ ಶರ್ತನ್ ಸರಿತೂಲೆ. ಶರ್ತ ನಿಜವಾದಿತ್ತ್ಂಡ, 'ಒಂಜಿ ವೇಲೆ ನಿಜ ಆಂಡ' ಮೌಲ್ಯೊನು ಪಿರಕೊರ್ಪುಂಡು; ಇಜ್ಜಿಂಡ 'ಒಂಜಿ ವೇಲೆ ಸುಲ್ಲಾಂಡ' ಮೌಲ್ಯೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/ಸಂಖ್ಯೆ",
                +	"MATH_NUMBER_TOOLTIP": "ಅ ನಂಬ್ರೊ",
                +	"MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/ಅಂಕಗಣಿತ",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "ರಡ್ಡ್ ಸಂಖ್ಯೆದ ಮೊತ್ತನ್ ಪಿರಕೊರು.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "ರಡ್ಡ ಸ್ಂಖ್ಯೆದ ವ್ಯತ್ಯಾಸೊನು ಪಿರಕೊರು.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "ಸಂಖ್ಯೆದ ಗುಣಲಬ್ಧೊನು ಪಿರಕೊರು.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "ಸಂಖ್ಯೆದ ಭಾಗಲಬ್ದೊನು ಪಿರಕೊರು.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "ಸುರುತ್ತ ಸಂಖ್ಯೆದ ಘಾತೊನು ರಡ್ಡನೆ ಸಂಖ್ಯೆಗ್ ಏರ್ಪಾದ್ ಪಿರಕೊರು.",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ",
                +	"MATH_SINGLE_OP_ROOT": "ವರ್ಗಮೂಲೊ",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "ಸಂಖ್ಯೆದ ವರ್ಗಮೂಲೊನು ಪಿರಕೊರು.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "ಸಂಪೂರ್ನೊ",
                +	"MATH_SINGLE_TOOLTIP_ABS": "ಸಂಖ್ಯೆದ ಸರಿಯಾಯಿನ ಮೌಲ್ಯೊನು ಕೊರು",
                +	"MATH_SINGLE_TOOLTIP_NEG": "ಸಂಖ್ಯೆದ ನಿಷೇಧೊನು ಪಿರಕೊರು",
                +	"MATH_SINGLE_TOOLTIP_LN": "ಸಂಖ್ಯೆದ ಪ್ರಾಕೃತಿಕ ಲಘುಗಣಕನ್ ಪಿರಕೊರು",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "ಸಂಖ್ಯೆದ ದಶಮಾನ ಲಘುಗಣಕನ್ ಪಿರಕೊರು",
                +	"MATH_SINGLE_TOOLTIP_EXP": "ಒಂಜಿ ಸಂಖ್ಯೆದ ಘಾತೊಗು 'e'ನ್ ಪಿರಕೊರು.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "ಒಂಜಿ ಸಂಖ್ಯೆದ ಘಾತೊಗು ೧೦ನ್ ಪಿರಕೊರು",
                +	"MATH_TRIG_HELPURL": "https://en.wikipedia.org/wiki/ತ್ರಿಕೋನಮಿತಿದ_ಕಾರ್ಯೊಲು",
                +	"MATH_TRIG_TOOLTIP_SIN": "ಒಂಜಿ ಡಿಗ್ರಿದ ಸೈನ್ (sine) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).",
                +	"MATH_TRIG_TOOLTIP_COS": "ಒಂಜಿ ಡಿಗ್ರಿದ ಕೊಸೈನ್ (cosine) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).",
                +	"MATH_TRIG_TOOLTIP_TAN": "ಒಂಜಿ ಡಿಗ್ರಿದ ಟ್ಯಾನ್‌ಜೆಂಟ್ (tangent) ಪಿರಕೊರು (ರೇಡಿಯನ್ ಅತ್ತ್).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌ಸೈನ್ ಪಿರಕೊರು.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌‌ಕೊಸೈನ್ ಪಿರಕೊರು.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "ಒಂಜಿ ಸಂಖ್ಯೆದ ಆರ್ಕ್‌ಟ್ಯಾನ್‌ಜ್ಂಟ್ ಪಿರಕೊರು.",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/ಗಣಿತ_ನಿರಂತರ",
                +	"MATH_CONSTANT_TOOLTIP": "ಒಂಜಿ ಸಾಮಾನ್ಯ ಸ್ಥಿರಾಂಕೊನು ಪಿರಕೊರು: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "ಸಮ ಸಂಖ್ಯೆ",
                +	"MATH_IS_ODD": "ಬೆಸ ಸಂಖ್ಯೆ",
                +	"MATH_IS_PRIME": "ಅವಿಭಾಜ್ಯ ಸಂಖ್ಯೆ",
                +	"MATH_IS_WHOLE": "ಪೂರ್ಣ ಸಂಖ್ಯೆ",
                +	"MATH_IS_POSITIVE": "ಧನ ಸಂಖ್ಯೆ",
                +	"MATH_IS_NEGATIVE": "ಋಣ ಸಂಖ್ಯೆ",
                +	"MATH_IS_DIVISIBLE_BY": "ಭಾಗಿಪೊಲಿ",
                +	"MATH_IS_TOOLTIP": "ಒಂಜಿ ಸಂಖ್ಯೆ ಸಮನಾ, ಬೆಸನಾ, ಅವಿಭಾಜ್ಯನಾ, ಪೂರ್ಣನಾ, ಧನನಾ, ಋಣನಾ, ಅತ್ತಂಡ ಅವೆನ್ ಬೇತೆ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಸಂಖ್ಯೆಡ್ದ್ ಭಾಗಿಪೊಲಿಯಾ ಪಂದ್ ಪರೀಕ್ಷೆ ಮಲ್ಪು. ನಿಜ ಅತ್ತಂಡ ಸುಲ್ಲುನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%1 ನ್ %2 ಟ್ ಬದಲ್ ಮಲ್ಪು",
                +	"MATH_CHANGE_TOOLTIP": "'%1' ವ್ಯತ್ಯಯೊಗು ಒಂಜಿ ಸಂಖ್ಯೆನ್ ಸೇರಾವ್",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/ಪೂರ್ಣಾಂಕೊ",
                +	"MATH_ROUND_TOOLTIP": "ಒಂಜಿ ಸಂಖ್ಯೆನ್ ಮಿತ್ತ್‌ಗ್ ಅತ್ತಂಡ ತಿರ್ತ್‌ಗ್ ರೌಂಡ್ ಮಲ್ಪು",
                +	"MATH_ROUND_OPERATOR_ROUND": "ರೌಂಡ್",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ಮಿತ್ತ್‌ಗ್ ರೌಂಡ್",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ತಿರ್ತ್‌ಗ್ ರೌಂಡ್",
                +	"MATH_ONLIST_OPERATOR_SUM": "ಪಟ್ಟಿದ ಮೊತ್ತ",
                +	"MATH_ONLIST_TOOLTIP_SUM": "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಾತಾ ಸಂಖ್ಯೆಲೆನ ಮೊತ್ತನ್ ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_MIN": "ಪಟ್ಟಿಡ್ ಕಿಞ್ಞವ್",
                +	"MATH_ONLIST_TOOLTIP_MIN": "ಪಟ್ಟಿಡುಪ್ಪುನ ಕಿಞ್ಞ ಸಂಕ್ಯೆನ್ ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_MAX": "ಪಟ್ಟಿಡ್ ಮಲ್ಲವ್",
                +	"MATH_ONLIST_TOOLTIP_MAX": "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಲ್ಲ ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "ಪಟ್ಟಿದ ಸರಾಸರಿ",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಾತಾ ಸಂಖ್ಯೆಲೆನ ಸರಾಸರಿನ್ ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "ಪಟ್ಟಿದ ನಡುತ್ತವ್",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "ಪಟ್ಟಿಡುಪ್ಪುನ ನಡುತ್ತ ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_MODE": "ಪಟ್ಟಿದ ಮಸ್ತ್ ಸಾಮಾನ್ಯ ಮೌಲ್ಯ",
                +	"MATH_ONLIST_TOOLTIP_MODE": "ಪಟ್ಟಿಡುಪ್ಪುನ ಮಸ್ತ್ ಸಾಮಾನ್ಯ ವಿಷಯೊನು ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "ಪಟ್ಟಿದ ಪ್ರಮಾಣಿತ ವಿಚಲನ",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "ಪಟ್ಟಿದ ಪ್ರಮಾಣಿತ ವಿಚಲನೊನು ಪಿರಕೊರು",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "ಪಟ್ಟಿದ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಷಯ",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "ಪಟ್ಟಿದ ಒವ್ವಾಂಡಲ ಒಂಜಿ ಅಂಶೊನು ಪಿರಕೊರು.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/ಮೋಡ್ಯುಲೊ_ಒಪರೇಶನ್",
                +	"MATH_MODULO_TITLE": " %1 ÷ %2 ತ ಶೇಷ",
                +	"MATH_MODULO_TOOLTIP": "ರಡ್ಡ್ ಸಂಖ್ಯೆಲೆನ್ ಭಾಗ ಮಲ್ತ್‌ದ್ ಶೇಷೊನು ಪಿರಕೊರು.",
                +	"MATH_CONSTRAIN_TITLE": "%2 ಕಮ್ಮಿ %3 ಜಾಸ್ತಿ %1 ನಿರ್ಬಂಧ ಮಲ್ಪು",
                +	"MATH_CONSTRAIN_TOOLTIP": "ನಿಗದಿತ ಮಿತಿತ ನಡುಟು ಒಂಜಿ ಸಂಖ್ಯೆನ್ ನಿರ್ಬಂಧ ಮಲ್ಪು",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/ರಾಂಡಮ್_ನಂಬರ್_ಜನರೇಶನ್",
                +	"MATH_RANDOM_INT_TITLE": " %1 ಡ್ದ್ %2 ಯಾದೃಚ್ಛಿಕ ಪೂರ್ಣಾಂಕೊ",
                +	"MATH_RANDOM_INT_TOOLTIP": "ರಡ್ಡ್ ನಿಗದಿತ ಮಿತಿತ ನಡುತ್ತ ಯಾದೃಚ್ಛಿಕ ಪೂರ್ಣಾಂಕೊನು ಪಿರಕೊರು",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/ರಾಂಡಮ್_ನಂಬರ್_ಜನರೇಶನ್",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಭಿನ್ನರಾಶಿ",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0 (ಸೇರ್‌ದ್) ಬೊಕ್ಕ 1.0 (ಸೇರಂದೆ) ನಡುತ ಒವ್ವಾಂಡಲ ಒಂಜಿ ಭಿನ್ನರಾಶಿನ್ ಪಿರಕೊರು.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/ಸ್ಟ್ರಿಂಗ್_(ಕಂಪ್ಯೂಟರ್_ಸೈನ್ಸ್)",
                +	"TEXT_TEXT_TOOLTIP": "ಒಂಜಿ ಅಕ್ಷರೊ, ಪದೊ ಅತ್ತಂಡ ಪಾಟೊದ ಒಂಜಿ ಸಾಲ್",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ನೆಡ್ದ್ ಪಟ್ಯೊನು ಉಂಡು ಮಲ್ಪು",
                +	"TEXT_JOIN_TOOLTIP": "ಏತಾಂಡಲ ವಿಷಯಲೆನ್ ಒಟ್ಟುಗು ಸೇರಾದ್ ಒಂಜಿ ಪಟ್ಯೊದ ತುಂಡುನು ಉಂಡುಮಲ್ಪು.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "ಸೇರಾವ್",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "ಈ ಪಠ್ಯ ತಡೆನ್ ಕುಡ ಸಂರಚಣೆ ಮಲ್ಪೆರೆ, ಸೇರಾವ್, ದೆತ್ತ್ ಬುಡು, ಅತ್ತಂಡ ವಿಭಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪು.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "ಪಟ್ಯೊಗು ಒಂಜಿ ವಿಷಯೊನು ಸೇರಾವ್",
                +	"TEXT_APPEND_TOOLTIP": "%1 ವ್ಯತ್ಯಯೊಗು ಕೆಲವು ಪಟ್ಯೊಲೆನ್ ಸೇರಾವ್",
                +	"TEXT_LENGTH_TITLE": "%1 ಉದ್ದೊ",
                +	"TEXT_LENGTH_TOOLTIP": "ಕೊರಿನ ಪಟ್ಯೊದ ಅಕ್ಷರೊಲೆನ (ಅಂತರೊಲು ಸೇರ್‌ದ್) ಸಂಖ್ಯೆನ್ ಪಿರಕೊರು.",
                +	"TEXT_ISEMPTY_TITLE": "%1 ಖಾಲಿ",
                +	"TEXT_ISEMPTY_TOOLTIP": "ಕೊರಿನ ಪಟ್ಯೊ ಖಾಲಿ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು.",
                +	"TEXT_INDEXOF_TOOLTIP": "ರಡ್ಡನೆ ಪಟ್ಯೊಡು ಉಪ್ಪುನ ಸುರುತ ಪಟ್ಯೊ ಸುರುಕ್ಕು/ಅಕೇರಿಗ್ ಬತ್ತಿನೆತ್ತ ಸೂಚಿನ್ ಪಿರಕೊರು. ಪಟ್ಯೊ ತಿಕ್ಕಿಜ್ಜಾಂಡ %1 ನ್ ಪಿರಕೊರು.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "ಪಟ್ಯೊ ಸುರುಕ್ಕು ಬತ್ತಿನೇನ್ ನಾಡ್",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "ಪಟ್ಯೊ ಅಕೇರಿಗ್ ಬತ್ತಿನೇನ್ ನಾಡ್",
                +	"TEXT_CHARAT_TITLE": "%1 %2 ಪದೊಟ್ಟು",
                +	"TEXT_CHARAT_FROM_START": "ಅಕ್ಸರೊ #ನ್ ದೆತ್ತೊನು",
                +	"TEXT_CHARAT_FROM_END": "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ನ್ ದೆತ್ತೊನು",
                +	"TEXT_CHARAT_FIRST": "ಸುರುತ್ತ ಅಕ್ಷರೊನು ದೆತ್ತೊನು",
                +	"TEXT_CHARAT_LAST": "ಅಕೇರಿದ ಅಕ್ಷರೊನು ದೆತ್ತೊನು",
                +	"TEXT_CHARAT_RANDOM": "ಒವ್ವಾಂಡಲ ಒಂಜಿ ಅಕ್ಷರೊನು ದೆತ್ತೊನು",
                +	"TEXT_CHARAT_TOOLTIP": "ಅಕ್ಷರೊನು ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ಪಿರಕೊರ್ಪುಂಡು.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "ಪಟ್ಯೊದ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಬಾಗೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ಪಟ್ಯೊಡು",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊ ದೆತ್ತೊನು",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊನು ದೆತ್ತೊನು",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "ಸುರುತ್ತ ಅಕ್ಷರೊ #ಡ್ದು ಉಪವಾಕ್ಯೊನು ದೆತ್ತೊನು",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "ಅಕ್ಷರೊ #ಗು",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "ಅಕೇರಿಡ್ದ್ ಅಕ್ಷರೊ #ಗು",
                +	"TEXT_GET_SUBSTRING_END_LAST": "ಅಕೇರಿದ ಅಕ್ಷರೊಗು",
                +	"TEXT_CHANGECASE_TOOLTIP": "ಪಟ್ಯೊದ ಒಂಜಿ ನಕಲ್‍ನ್ ಬೇತೆ ನಮೂನೆಡ್ (case) ಪಿರಕೊರು.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "ಮಲ್ಲ ಅಕ್ಷರೊಗು",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "ಎಲ್ಯ ಅಕ್ಷರೊಗು",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "ತರೆಬರವುದ ಅಕ್ಷರೊಗು",
                +	"TEXT_TRIM_TOOLTIP": "ಒಂಜಿ ಅತ್ತಂಡ ರಡ್ಡ್ ಕೊಡಿಡ್ದ್ ಅಂತರೊಲೆನ್ (space) ದೆತ್ತ್‌ದ್ ಪಟ್ಯೊದ ಪ್ರತಿನ್ ಪಿರಕೊರು.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "ರಡ್ಡ್ ಮೆಯಿತ್ತಲ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.",
                +	"TEXT_TRIM_OPERATOR_LEFT": "ಎಡತ್ತ ಮೆಯಿತ್ತ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "ಬಲತ್ತ ಮೆಯಿತ್ತ ಅಂತರೊಲೆನ್ (space) ಕತ್ತೆರ್.",
                +	"TEXT_PRINT_TITLE": "%1 ಮುದ್ರಣ",
                +	"TEXT_PRINT_TOOLTIP": "ನಿರ್ದಿಷ್ಟ ಪಟ್ಯೊ, ಸಂಖ್ಯೆ ಅತ್ತಂಡ ಬೇತೆ ಮೌಲ್ಯೊನು ಮುದ್ರಿಪುಲೆ.",
                +	"TEXT_PROMPT_TYPE_TEXT": "ಸಂದೇಶೊದೊಟ್ಟುಗು ಪಟ್ಯೊಗು ಕೇನ್.",
                +	"TEXT_PROMPT_TYPE_NUMBER": "ಸಂದೇಶೊದೊಟ್ಟುಗು ಸಂಕ್ಯೆನ್ ಕೇನ್",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "ಒಂಜಿ ಸಂಖ್ಯೆಗ್ ಸದಸ್ಯೆರೆನ್ ಕೇನ್",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "ಕೆಲವು ಪಟ್ಯೊಗು ಸದಸ್ಯೆರೆನ್ ಕೇನ್.",
                +	"LISTS_CREATE_EMPTY_TITLE": "ಕಾಲಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "ಒಂಜಿ ಪಟ್ಟಿ, ೦ ಉದ್ದೊದ, ಒವ್ವೇ ಮಾಹಿತಿ ದಾಂತಿನ ದಾಖಲೆ ಪಿರಕೊರು.",
                +	"LISTS_CREATE_WITH_TOOLTIP": "ಏತೇ ವಿಸಯೊಲುಪ್ಪುನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "ಒಟ್ಟುಗು ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "ಪಟ್ಟಿ",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "ಈ ಪಟ್ಟಿ ತಡೆನ್ ಕುಡ ಸಂರಚನೆ ಮಲ್ಪೆರೆ ಸೇರಾಲೆ, ದೆತ್ತ್ ಬುಡುಲೆ, ಅತ್ತಂಡ ವಿಬಾಗೊಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "ಪಟ್ಟಿಗ್ ಒಂಜಿ ವಿಸಯೊನು ಸೇರಾಲೆ.",
                +	"LISTS_REPEAT_TOOLTIP": "ಕೊರಿನ ಮೌಲ್ಯೊ ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಸಂಕ್ಯೆದಾತ್ ಸರ್ತಿ ಪುನರಾವರ್ತನೆ ಆದುಪ್ಪುನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ.",
                +	"LISTS_REPEAT_TITLE": "%1 ವಿಸಯೊ %2 ಸರ್ತಿ ಪುನರಾವರ್ತನೆ ಆದುಪ್ಪುನ ಪಟ್ಟಿನ್ ಉಂಡುಮಲ್ಪುಲೆ.",
                +	"LISTS_LENGTH_TITLE": "%1 ಉದ್ದೊ",
                +	"LISTS_LENGTH_TOOLTIP": "ಪಟ್ಟಿದ ಉದ್ದೊನು ಪಿರಕೊರು.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ಕಾಲಿ",
                +	"LISTS_ISEMPTY_TOOLTIP": "ಪಟ್ಯೊ ಖಾಲಿ ಇತ್ತ್ಂಡ 'ನಿಜ'ನ್ ಪಿರಕೊರು.",
                +	"LISTS_INLIST": "ಪಟ್ಟಿಡ್",
                +	"LISTS_INDEX_OF_FIRST": "ವಿಸಯೊ ಸುರುಕ್ಕು ಬತ್ತಿನೇನ್ ನಾಡ್",
                +	"LISTS_INDEX_OF_LAST": "ವಿಸಯೊ ಅಕೇರಿಗ್ ಬತ್ತಿನೇನ್ ನಾಡ್",
                +	"LISTS_INDEX_OF_TOOLTIP": "ಪಟ್ಟಿಡುಪ್ಪುನ ವಿಸಯೊ ಸುರುಕ್ಕು/ಅಕೇರಿಗ್ ಬತ್ತಿನೆತ್ತ ಸೂಚಿನ್ ಪಿರಕೊರ್ಪುಂಡು. ವಿಸಯೊ ತಿಕ್ಕಿಜ್ಜಾಂಡ %1 ನ್ ಪಿರಕೊರ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_GET": "ದೆತೊನು",
                +	"LISTS_GET_INDEX_GET_REMOVE": "ದೆತ್ತೊನು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡು",
                +	"LISTS_GET_INDEX_REMOVE": "ದೆಪ್ಪುಲೆ",
                +	"LISTS_GET_INDEX_FROM_END": "ಅಕೇರಿಡ್ದ್ #",
                +	"LISTS_GET_INDEX_FIRST": "ಸುರುತ",
                +	"LISTS_GET_INDEX_LAST": "ಕಡೆತ",
                +	"LISTS_GET_INDEX_RANDOM": "ಗೊತ್ತು ಗುರಿದಾಂತಿನ",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ಸುರುತ ವಿಸಯೊ",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ಅಕೇರಿತ ವಿಸಯೊ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಪಿರಕೊರ್ಪುಂಡು ಬೊಕ್ಕ ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ದೆತ್ತ್ ಬುಡ್ಪುಂಡು.",
                +	"LISTS_SET_INDEX_SET": "ಸೆಟ್ ಮಲ್ಪು",
                +	"LISTS_SET_INDEX_INSERT": "ಸೇರಾವ್",
                +	"LISTS_SET_INDEX_INPUT_TO": "ಲೆಕ",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಸುರುತ್ತ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಅಕೇರಿದ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಒವ್ವಾಂಡಲ ಒಂಜಿ ವಿಸಯೊನು ಸೆಟ್ ಮಲ್ಪುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಡ್ ವಿಸಯೊನು ಸೇರಾವುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "ಒಂಜಿ ಪಟ್ಟಿದ ಸುರುಕ್ಕು ವಿಸಯೊನು ಸೇರಾವುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "ಒಂಜಿ ಪಟ್ಟಿದ ಅಕೇರಿಗ್ ವಿಸಯೊನು ಸೇರಾವುಂಡು.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "ಒಂಜಿ ಪಟ್ಟಿಡ್ ಓಲಾಂಡಲ ವಿಸಯೊನು ಸೇರಾವುಂಡು.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "# ಡ್ದ್ ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "ಅಕೇರಿಡ್ದ್ # ಡ್ದ್ ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು",
                +	"LISTS_GET_SUBLIST_START_FIRST": "ಸುರುಡ್ದು ಉಪ-ಪಟ್ಟಿನ್ ದೆತ್ತೊನು",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "# ಗ್",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ಅಕೇರಿಡ್ದ್ # ಗ್",
                +	"LISTS_GET_SUBLIST_END_LAST": "ಅಕೇರಿಗ್",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "ಪಟ್ಯೊದ ನಿರ್ದಿಷ್ಟ ಬಾಗೊದ ಪ್ರತಿನ್ ಉಂಡುಮಲ್ಪುಂಡು.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "%1 %2 %3 ಇಂಗಡಿಪು",
                +	"LISTS_SORT_TOOLTIP": "ಒಂಜಿ ಪಟ್ಟಿದ ಒಂಜಿ ಪ್ರತಿನ್ ಇಂಗಡಿಪು",
                +	"LISTS_SORT_ORDER_ASCENDING": "ಏರುನು",
                +	"LISTS_SORT_ORDER_DESCENDING": "ಜಪ್ಪುನು",
                +	"LISTS_SORT_TYPE_NUMERIC": "ಸಂಖ್ಯೆ",
                +	"LISTS_SORT_TYPE_TEXT": "ಅಕ್ಷರೊ",
                +	"LISTS_SORT_TYPE_IGNORECASE": "ಅಕ್ಷರೊ, ನಮೂನೆ (case) ಅಲಕ್ಷ್ಯೊ ಮಲ್ಪುಲೆ",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "ಪಟ್ಯೊಲೆ ಪಟ್ಟಿನ್ ತಯಾರ್ ಮಲ್ಪುಲೆ",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "ಪಟ್ಟಿದ ಪಟ್ಯೊನು ತಯಾರ್ ಮಲ್ಪುಲೆ",
                +	"LISTS_SPLIT_WITH_DELIMITER": "ಮಿತಿಸೂಚಕೊದ ಒಟ್ಟುಗು",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "ಪಟ್ಯೊಲೆನ್ ಪ್ರತಿ ಮಿತಿಸೂಚಕೊಡು ತುಂಡು ಮಲ್ತ್‌ದ್ ಪಟ್ಯೊಲೆನ ಒಂಜಿ ಪಟ್ಟಿಗ್ ಬಾಗೊ ಮಲ್ಪುಲೆ.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "ಪಟ್ಯೊಲೆನ ಒಂಜಿ ಪಟ್ಟಿನ್ ಮಿತಿಸೂಚಕೊದ ಮೂಲಕೊ ಬೇತೆ ಮಲ್ತ್‌ದ್ ಒಂಜಿ ಪಟ್ಯೊಗು ಸೇರಾಲೆ.",
                +	"VARIABLES_GET_TOOLTIP": "ಈ ವ್ಯತ್ಯಯೊದ ಮೌಲ್ಯೊನು ಪಿರಕೊರು.",
                +	"VARIABLES_GET_CREATE_SET": "'ಸೆಟ್ %1' ಉಂಡುಮಲ್ಪುಲೆ",
                +	"VARIABLES_SET": "%1 ನ್ %2 ಕ್ಕ್ ಸೆಟ್ ಮಲ್ಪುಲೆ",
                +	"VARIABLES_SET_TOOLTIP": "ಈ ವ್ಯತ್ಯಯೊನು ಇನ್‌ಪುಟ್‌ಗ್ ಸಮ ಆಪಿಲೆಕ ಸೆಟ್ ಮಲ್ಪುಂಡು.",
                +	"VARIABLES_SET_CREATE_GET": "'ದೆತ್ತೊನು %1' ಉಂಡುಮಲ್ಪುಲೆ",
                +	"PROCEDURES_DEFNORETURN_TITLE": "ಇಂದೆಕ್",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "ಎಂಚಿನಾಂಡಲ ಮಲ್ಪುಲೆ",
                +	"PROCEDURES_BEFORE_PARAMS": "ಒಟ್ಟುಗು:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ಒಟ್ಟುಗು:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "ಔಟ್‌ಪುಟ್ ದಾಂತಿನ ಕಾರ್ಯೊನು ಉಂಡುಮಲ್ಪುಂಡು.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "ಈ ಕಾರ್ಯೊನು ಇವರಿಪುಲೆ...",
                +	"PROCEDURES_DEFRETURN_RETURN": "ಪಿರಕೊರು",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "ಔಟ್‌ಪುಟ್ ಇತ್ತಿನ ಕಾರ್ಯೊನು ಉಂಡುಮಲ್ಪುಂಡು.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "ಹೇಳಿಕೆಗ್ ಅವಕಾಸೊ",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "ಎಚ್ಚರಿಕೆ: ಈ ಕಾರ್ಯೊಡು ನಕಲಿ ಮಾನದಂಡೊ ಉಂಡು.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "'%1' ಬಳಕೆದಾರೆರೆ ಕಾರ್ಯೊನು ನಡಪಾಲೆ.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/ವರ್ಗಮೂಲೊ",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": " ಬಳಕೆದಾರೆರೆ ಕಾರ್ಯೊ '%1' ನು ನಡಪಾಲೆ ಬುಕ್ಕೊ ಅಯಿತ ಉತ್ಪಾದನೆನ್ ಗಲಸ್‌ಲೆ.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "ಉಲಪರಿಪು",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "ಸೇರಾಲೆ, ದೆತ್ತ್‌ ಬುಡುಲೆ, ಅತ್ತಂಡ ಈ ಕಾರ್ಯೊಗು ಉಲಪರಿಪುಲೆನ್ ಕುಡ ಒತ್ತರೆ ಮಲ್ಪುಲೆ.",
                +	"PROCEDURES_MUTATORARG_TITLE": "ಉಲಪರಿಪುದ ಪುದರ್:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "ಕಾರ್ಯೊಗು ಒಂಜಿ ಉಲಪರಿಪುನು ಸೇರಲೆ.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "ದೆರ್ತ್ ತೋಜುನ ಕಾರ್ಯೊದ ವ್ಯಾಕ್ಯಾನೊ",
                +	"PROCEDURES_CREATE_DO": " '%1'ನ್ ಉಂಡುಮಲ್ಪುಲೆ",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "ಮೌಲ್ಯೊ ಸತ್ಯೊ ಆಂಡ, ರಡ್ಡನೆ ಮೌಲ್ಯೊನು ಪಿರಕೊರು.",
                +	"PROCEDURES_IFRETURN_WARNING": "ಎಚ್ಚರಿಕೆ: ಒಂಜಿ ಕಾರ್ಯ ವ್ಯಾಕ್ಯಾನೊದುಲಯಿ ಮಾತ್ರ ಈ ತಡೆನ್ ಗಲಸೊಲಿ."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/th.json b/blockly/webif/static/blockly/msg/json/th.json
                new file mode 100644
                index 000000000..01c051f8b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/th.json
                @@ -0,0 +1,307 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Azpirin",
                +			"Octahedron80",
                +			"Horus",
                +			"Roysheng"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "รายการ",
                +	"TODAY": "วันนี้",
                +	"DUPLICATE_BLOCK": "ทำสำเนา",
                +	"ADD_COMMENT": "ใส่คำอธิบาย",
                +	"REMOVE_COMMENT": "เอาคำอธิบายออก",
                +	"EXTERNAL_INPUTS": "อินพุตภายนอก",
                +	"INLINE_INPUTS": "อินพุตในบรรทัด",
                +	"DELETE_BLOCK": "ลบบล็อก",
                +	"DELETE_X_BLOCKS": "ลบ %1 บล็อก",
                +	"DELETE_ALL_BLOCKS": "ลบ %1 บล็อกทั้งหมด?",
                +	"CLEAN_UP": "จัดเรียงบล็อกให้เป็นแถว",
                +	"COLLAPSE_BLOCK": "ย่อบล็อก",
                +	"COLLAPSE_ALL": "ย่อบล็อก",
                +	"EXPAND_BLOCK": "ขยายบล็อก",
                +	"EXPAND_ALL": "ขยายบล็อก",
                +	"DISABLE_BLOCK": "ปิดใช้งานบล็อก",
                +	"ENABLE_BLOCK": "เปิดใช้งานบล็อก",
                +	"HELP": "ช่วยเหลือ",
                +	"UNDO": "ย้อนกลับ",
                +	"REDO": "ทำซ้ำ",
                +	"CHANGE_VALUE_TITLE": "เปลี่ยนค่า:",
                +	"RENAME_VARIABLE": "เปลี่ยนชื่อตัวแปร...",
                +	"RENAME_VARIABLE_TITLE": "เปลี่ยนชื่อตัวแปร '%1' ทั้งหมดเป็น:",
                +	"NEW_VARIABLE": "สร้างตัวแปร...",
                +	"NEW_VARIABLE_TITLE": "ชื่อตัวแปรใหม่:",
                +	"COLOUR_PICKER_HELPURL": "https://th.wikipedia.org/wiki/สี",
                +	"COLOUR_PICKER_TOOLTIP": "เลือกสีจากจานสี",
                +	"COLOUR_RANDOM_TITLE": "สุ่มสี",
                +	"COLOUR_RANDOM_TOOLTIP": "เลือกสีแบบสุ่ม",
                +	"COLOUR_RGB_TITLE": "สีที่ประกอบด้วย",
                +	"COLOUR_RGB_RED": "ค่าสีแดง",
                +	"COLOUR_RGB_GREEN": "ค่าสีเขียว",
                +	"COLOUR_RGB_BLUE": "ค่าสีน้ำเงิน",
                +	"COLOUR_RGB_TOOLTIP": "สร้างสีด้วยการกำหนดค่าสีแดง เขียว และน้ำเงิน ค่าทั้งหมดต้องอยู่ระหว่าง 0 ถึง 100",
                +	"COLOUR_BLEND_TITLE": "ผสม",
                +	"COLOUR_BLEND_COLOUR1": "สีที่ 1",
                +	"COLOUR_BLEND_COLOUR2": "สีที่ 2",
                +	"COLOUR_BLEND_RATIO": "อัตราส่วน",
                +	"COLOUR_BLEND_TOOLTIP": "ผสมสองสีเข้าด้วยกันด้วยอัตราส่วน (0.0 - 1.0)",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "ทำซ้ำ %1 ครั้ง",
                +	"CONTROLS_REPEAT_INPUT_DO": "ทำ:",
                +	"CONTROLS_REPEAT_TOOLTIP": "ทำซ้ำบางคำสั่งหลายครั้ง",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ทำซ้ำขณะที่",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ทำซ้ำจนกระทั่ง",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "ขณะที่ค่าเป็นจริง ก็จะทำบางคำสั่ง",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "ขณะที่ค่าเป็นเท็จ ก็จะทำบางคำสั่ง",
                +	"CONTROLS_FOR_TOOLTIP": "ตัวแปร '%1' จะเริ่มจากจำนวนเริ่มต้น ไปจนถึงจำนวนสุดท้าย ตามระยะที่กำหนด และ ทำบล็อกที่กำหนดไว้",
                +	"CONTROLS_FOR_TITLE": "นับด้วย %1 จาก %2 จนถึง %3 เปลี่ยนค่าทีละ %4",
                +	"CONTROLS_FOREACH_TITLE": "จากทุกรายการ %1 ในรายชื่อ %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "จากทุกรายการในรายชื่อ ตั้งค่าตัวแปร \"%1\" เป็นรายการ และทำตามคำสั่งที่กำหนดไว้",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ออกจากการวนซ้ำ",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "เริ่มการวนซ้ำรอบต่อไป",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "ออกจากการวนซ้ำที่อยู่",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "ข้ามคำสั่งที่เหลืออยู่ และเริ่มต้นวนซ้ำรอบต่อไป",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "คำเตือน: บล็อกนี้ใช้งานได้ภายในการวนซ้ำเท่านั้น",
                +	"CONTROLS_IF_TOOLTIP_1": "ว่าเงื่อนไขเป็นจริง ก็จะ \"ทำ\" ตามที่กำหนด",
                +	"CONTROLS_IF_TOOLTIP_2": "ถ้าเงื่อนไขเป็นจริง ก็จะ \"ทำ\" ตามที่กำหนด แต่ถ้าเงื่อนไขเป็นเท็จก็จะทำ \"นอกเหนือจากนี้\"",
                +	"CONTROLS_IF_TOOLTIP_3": "ถ้าเงื่อนไขแรกเป็นจริง ก็จะทำตามคำสั่งในบล็อกแรก แต่ถ้าไม่ก็จะไปตรวจเงื่อนไขที่สอง ถ้าเงื่อนไขที่สองเป็นจริง ก็จะทำตามเงื่อนไขในบล็อกที่สองนี้",
                +	"CONTROLS_IF_TOOLTIP_4": "ถ้าเงื่อนไขแรกเป็นจริง ก็จะทำคำสั่งในบล็อกแรก จากนั้นจะข้ามคำสั่งในบล็อกที่เหลือ แต่ถ้าเงื่อนไขแรกเป็นเท็จ ก็จะทำการตรวจเงื่อนไขที่สอง ถ้าเงื่อนไขที่สองเป็นจริง ก็จะทำตามคำสั่งในบล็อกที่สอง จากนั้นจะข้ามคำสั่งในบล็อกที่เหลือ แต่ถ้าทั้งเงื่อนไขแรกและเงื่อนไขที่สองเป็นเท็จทั้งหมด ก็จะมาทำบล็อกที่สาม",
                +	"CONTROLS_IF_MSG_IF": "ถ้า",
                +	"CONTROLS_IF_MSG_ELSEIF": "นอกเหนือจากนี้ ถ้า",
                +	"CONTROLS_IF_MSG_ELSE": "นอกเหนือจากนี้",
                +	"CONTROLS_IF_IF_TOOLTIP": "เพิ่ม ลบ หรือจัดเรียงบล็อก \"ถ้า\" นี้ใหม่",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "กำหนดเงื่อนไขของบล็อก \"ถ้า\"",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "เพิ่มสิ่งสุดท้าย ที่จะตรวจจับความเป็นไปได้ทั้งหมดของบล็อก \"ถ้า\"",
                +	"LOGIC_COMPARE_HELPURL": "https://th.wikipedia.org/wiki/อสมการ",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่ทั้งสองค่านั้นเท่ากัน",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่ทั้งสองค่านั้นไม่เท่ากัน",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "คืนค่าเป็น \"จริง\" ถ้าค่าแรกน้อยกว่าค่าที่สอง",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "คืนค่าเป็น \"จริง\" ถ้าค่าแรกน้อยกว่าหรือเท่ากับค่าที่สอง",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "คืนค่าเป็น \"จริง\" ถ้าค่าแรกมากกว่าค่าที่สอง",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "คืนค่าเป็น \"จริง\" ถ้าค่าแรกมากกว่าหรือเท่ากับค่าที่สอง",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "คืนค่าเป็น \"จริง\" ถ้าค่าทั้งสองค่าเป็นจริง",
                +	"LOGIC_OPERATION_AND": "และ",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "คืนค่าเป็น \"จริง\" ถ้ามีอย่างน้อยหนึ่งค่าที่เป็นจริง",
                +	"LOGIC_OPERATION_OR": "หรือ",
                +	"LOGIC_NEGATE_TITLE": "ไม่ %1",
                +	"LOGIC_NEGATE_TOOLTIP": "คืนค่าเป็น \"จริง\" ถ้าค่าที่ใส่เป็นเท็จ คืนค่าเป็น \"เท็จ\" ถ้าค่าที่ใส่เป็นจริง",
                +	"LOGIC_BOOLEAN_TRUE": "จริง",
                +	"LOGIC_BOOLEAN_FALSE": "เท็จ",
                +	"LOGIC_BOOLEAN_TOOLTIP": "คืนค่าเป็นจริงหรือเท็จ",
                +	"LOGIC_NULL": "ไม่กำหนด",
                +	"LOGIC_NULL_TOOLTIP": "คืนค่า \"ไม่กำหนด\"",
                +	"LOGIC_TERNARY_CONDITION": "ทดสอบ",
                +	"LOGIC_TERNARY_IF_TRUE": "ถ้า เป็นจริง",
                +	"LOGIC_TERNARY_IF_FALSE": "ถ้า เป็นเท็จ",
                +	"LOGIC_TERNARY_TOOLTIP": "ตรวจสอบเงื่อนไขใน \"ทดสอบ\" ถ้าเงื่อนไขเป็นจริง จะคืนค่า \"ถ้า เป็นจริง\" ถ้าเงื่อนไขเป็นเท็จ จะคืนค่า \"ถ้า เป็นเท็จ\"",
                +	"MATH_NUMBER_HELPURL": "https://th.wikipedia.org/wiki/จำนวน",
                +	"MATH_NUMBER_TOOLTIP": "จำนวน",
                +	"MATH_ARITHMETIC_HELPURL": "https://th.wikipedia.org/wiki/เลขคณิต",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "คืนค่าผลรวมของตัวเลขทั้งสองจำนวน",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "คืนค่าผลต่างของตัวเลขทั้งสองจำนวน",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "คืนค่าผลคูณของตัวเลขทั้งสองจำนวน",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "คืนค่าผลหารของตัวเลขทั้งสองจำนวน",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "คืนค่าผลการยกกำลัง โดยตัวเลขแรกเป็นฐาน และตัวเลขที่สองเป็นเลขชี้กำลัง",
                +	"MATH_SINGLE_HELPURL": "https://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "รากที่สอง",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "คืนค่ารากที่สองของตัวเลข",
                +	"MATH_SINGLE_OP_ABSOLUTE": "ค่าสัมบูรณ์",
                +	"MATH_SINGLE_TOOLTIP_ABS": "คืนค่าค่าสัมบูรณ์ของตัวเลข",
                +	"MATH_SINGLE_TOOLTIP_NEG": "คืนค่าติดลบของตัวเลข",
                +	"MATH_SINGLE_TOOLTIP_LN": "คืนค่าลอการิทึมธรรมชาติของตัวเลข",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "คืนค่าลอการิทึมฐานสิบของตัวเลข",
                +	"MATH_SINGLE_TOOLTIP_EXP": "คืนค่า e ยกกำลังด้วยตัวเลข",
                +	"MATH_SINGLE_TOOLTIP_POW10": "คืนค่า 10 ยกกำลังด้วยตัวเลข",
                +	"MATH_TRIG_HELPURL": "https://th.wikipedia.org/wiki/ฟังก์ชันตรีโกณมิติ",
                +	"MATH_TRIG_TOOLTIP_SIN": "คืนค่า sine ขององศา (ไม่ใช่เรเดียน)",
                +	"MATH_TRIG_TOOLTIP_COS": "คืนค่า cosine ขององศา (ไม่ใช่เรเดียน)",
                +	"MATH_TRIG_TOOLTIP_TAN": "คืนค่า tangent ขององศา (ไม่ใช่เรเดียน)",
                +	"MATH_TRIG_TOOLTIP_ASIN": "คืนค่า arcsine ของตัวเลข",
                +	"MATH_TRIG_TOOLTIP_ACOS": "คืนค่า arccosine ของตัวเลข",
                +	"MATH_TRIG_TOOLTIP_ATAN": "คืนค่า arctangent ของตัวเลข",
                +	"MATH_CONSTANT_HELPURL": "https://th.wikipedia.org/wiki/ค่าคงตัวทางคณิตศาสตร์",
                +	"MATH_CONSTANT_TOOLTIP": "คืนค่าคงตัวทางคณิตศาสตร์ที่พบบ่อยๆ เช่น π (3.141…), e (2.718…), φ (1.618…), รากที่สอง (1.414…), รากที่ ½ (0.707…), ∞ (อนันต์)",
                +	"MATH_IS_EVEN": "เป็นจำนวนคู่",
                +	"MATH_IS_ODD": "เป็นจำนวนคี่",
                +	"MATH_IS_PRIME": "เป็นจำนวนเฉพาะ",
                +	"MATH_IS_WHOLE": "เป็นเลขจำนวนเต็ม",
                +	"MATH_IS_POSITIVE": "เป็นเลขบวก",
                +	"MATH_IS_NEGATIVE": "เป็นเลขติดลบ",
                +	"MATH_IS_DIVISIBLE_BY": "หารลงตัว",
                +	"MATH_IS_TOOLTIP": "ตรวจว่าตัวเลขเป็นจำนวนคู่ จำนวนคี่ จำนวนเฉพาะ จำนวนเต็ม เลขบวก เลขติดลบ หรือหารด้วยเลขที่กำหนดลงตัวหรือไม่ คืนค่าเป็นจริงหรือเท็จ",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "เปลี่ยนค่า %1 เป็น %2",
                +	"MATH_CHANGE_TOOLTIP": "เพิ่มค่าของตัวแปร \"%1\"",
                +	"MATH_ROUND_HELPURL": "https://th.wikipedia.org/wiki/การปัดเศษ",
                +	"MATH_ROUND_TOOLTIP": "ปัดเศษของตัวเลขขึ้นหรือลง",
                +	"MATH_ROUND_OPERATOR_ROUND": "ปัดเศษ",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "ปัดเศษขึ้น",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "ปัดเศษลง",
                +	"MATH_ONLIST_OPERATOR_SUM": "ผลรวมของรายการ",
                +	"MATH_ONLIST_TOOLTIP_SUM": "คืนค่าผลรวมของตัวเลขทั้งหมดในรายการ",
                +	"MATH_ONLIST_OPERATOR_MIN": "น้อยที่สุดในรายการ",
                +	"MATH_ONLIST_TOOLTIP_MIN": "คืนค่าตัวเลขที่น้อยที่สุดในรายการ",
                +	"MATH_ONLIST_OPERATOR_MAX": "มากที่สุดในรายการ",
                +	"MATH_ONLIST_TOOLTIP_MAX": "คืนค่าตัวเลขที่มากที่สุดในรายการ",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "ค่าเฉลี่ยของรายการ",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "คืนค่าเฉลี่ยของรายการ",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "ค่ามัธยฐานของรายการ",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "คืนค่ามัธยฐานของรายการ",
                +	"MATH_ONLIST_OPERATOR_MODE": "ฐานนิยมของรายการ",
                +	"MATH_ONLIST_TOOLTIP_MODE": "คืนค่าฐานนิยมของรายการ",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "ส่วนเบี่ยงเบนมาตรฐานของรายการ",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "คืนค่าส่วนเบี่ยงเบนมาตรฐานของรายการ",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "สุ่มรายการ",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "สุ่มคืนค่าสิ่งที่อยู่ในรายการ",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "เศษของ %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "คืนค่าเศษที่ได้จากการหารของตัวเลขทั้งสองจำนวน",
                +	"MATH_CONSTRAIN_TITLE": "จำกัดค่า %1 ต่ำสุด %2 สูงสุด %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "จำกัดค่าของตัวเลขให้อยู่ในช่วงที่กำหนด",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "สุ่มเลขจำนวนเต็มตั้งแต่ %1 จนถึง %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "สุ่มเลขจำนวนเต็มจากช่วงที่กำหนด",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "สุ่มเลขเศษส่วน",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "สุ่มเลขเศษส่วน ตั้งแต่ 0.0 แต่ไม่เกิน 1.0",
                +	"TEXT_TEXT_HELPURL": "https://th.wikipedia.org/wiki/สายอักขระ",
                +	"TEXT_TEXT_TOOLTIP": "ตัวหนังสือ คำ หรือข้อความ",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "สร้างข้อความด้วย",
                +	"TEXT_JOIN_TOOLTIP": "สร้างข้อความด้วยการรวมจำนวนของรายการเข้าด้วยกัน",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "รวม",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "เพิ่ม ลบ หรือจัดเรียงบล็อกข้อความนี้ใหม่",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "เพิ่มรายการเข้าไปในข้อความ",
                +	"TEXT_APPEND_TOOLTIP": "ต่อข้อความให้ตัวแปร \"%1\"",
                +	"TEXT_LENGTH_TITLE": "ความยาวของ %1",
                +	"TEXT_LENGTH_TOOLTIP": "คืนค่าความยาวของข้อความ (รวมช่องว่าง)",
                +	"TEXT_ISEMPTY_TITLE": "%1 ว่าง",
                +	"TEXT_ISEMPTY_TOOLTIP": "คืนค่าจริง ถ้าข้อความยังว่าง",
                +	"TEXT_INDEXOF_TOOLTIP": "คืนค่าตำแหน่งที่พบข้อความแรกอยู่ในข้อความที่สอง คืนค่า %1 ถ้าหาไม่พบ",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "หาข้อความแรกที่พบ",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "หาข้อความสุดท้ายที่พบ",
                +	"TEXT_CHARAT_FROM_START": "ดึง ตัวอักษรตัวที่",
                +	"TEXT_CHARAT_FROM_END": "ดึง ตัวอักษรตัวที่ # จากท้าย",
                +	"TEXT_CHARAT_FIRST": "ดึง ตัวอักษรตัวแรก",
                +	"TEXT_CHARAT_LAST": "ดึง ตัวอักษรตัวสุดท้าย",
                +	"TEXT_CHARAT_RANDOM": "ถึงตัวอักษรแบบสุ่ม",
                +	"TEXT_CHARAT_TOOLTIP": "คืนค่าตัวอักษรจากตำแหน่งที่ระบุ",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "คืนค่าบางส่วนของข้อความ",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ในข้อความ",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "แยกข้อความย่อยตั้งแต่ ตัวอักษรที่",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "แยกข้อความย่อยตั้งแต่ ตัวอักษรที่ # จากท้าย",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "แยกข้อความย่อยตั้งแต่ ตัวอักษรแรก",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "จนถึง ตัวอักษรที่",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "จนถึง ตัวอักษรที่ # จากท้าย",
                +	"TEXT_GET_SUBSTRING_END_LAST": "จนถึง ตัวอักษรสุดท้าย",
                +	"TEXT_CHANGECASE_TOOLTIP": "คืนค่าสำเนาของข้อความในกรณีต่างๆ",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "เปลี่ยนเป็น ตัวพิมพ์ใหญ่",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "เปลี่ยนเป็น ตัวพิมพ์เล็ก",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "เปลี่ยนเป็น ตัวอักษรแรกเป็นตัวพิมพ์ใหญ่",
                +	"TEXT_TRIM_TOOLTIP": "คืนค่าสำเนาของข้อความที่ลบเอาช่องว่างหน้าและหลังข้อความออกแล้ว",
                +	"TEXT_TRIM_OPERATOR_BOTH": "ลบช่องว่างทั้งสองข้างของ",
                +	"TEXT_TRIM_OPERATOR_LEFT": "ลบช่องว่างด้านหน้าของ",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "ลบช่องว่างข้างท้ายของ",
                +	"TEXT_PRINT_TITLE": "พิมพ์ %1",
                +	"TEXT_PRINT_TOOLTIP": "พิมพ์ข้อความ ตัวเลข หรือค่าอื่นๆ",
                +	"TEXT_PROMPT_TYPE_TEXT": "แสดงหน้าต่างข้อความ",
                +	"TEXT_PROMPT_TYPE_NUMBER": "แสดงหน้าต่างตัวเลข",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "แสดงหน้าต่างให้ผู้ใช้ใส่ตัวเลข",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "แสดงหน้าต่างให้ผู้ใช้ใส่ข้อความ",
                +	"LISTS_CREATE_EMPTY_TITLE": "สร้างรายการเปล่า",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "สร้างรายการเปล่า (ความยาวเป็น 0) ยังไม่มีข้อมูลใดๆ อยู่",
                +	"LISTS_CREATE_WITH_TOOLTIP": "สร้างรายการพร้อมด้วยไอเท็ม",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "สร้างข้อความด้วย",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "รายการ",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "เพิ่ม ลบ หรือจัดเรียงบล็อกรายการนี้ใหม่",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "เพิ่มไอเท็มเข้าไปในรายการ",
                +	"LISTS_REPEAT_TOOLTIP": "สร้างรายการที่ประกอบด้วยค่าตามที่ระบุในจำนวนตามที่ต้องการ",
                +	"LISTS_REPEAT_TITLE": "สร้างรายการที่มีไอเท็ม %1 จำนวน %2",
                +	"LISTS_LENGTH_TITLE": "ความยาวของ %1",
                +	"LISTS_LENGTH_TOOLTIP": "ส่งคืนค่าความยาวของรายการ",
                +	"LISTS_ISEMPTY_TITLE": "%1 ว่างเปล่า",
                +	"LISTS_ISEMPTY_TOOLTIP": "คืนค่าเป็นจริง ถ้ารายการยังว่างเปล่า",
                +	"LISTS_INLIST": "ในรายการ",
                +	"LISTS_INDEX_OF_FIRST": "หาอันแรกที่พบ",
                +	"LISTS_INDEX_OF_LAST": "หาอันสุดท้ายที่พบ",
                +	"LISTS_INDEX_OF_TOOLTIP": "คืนค่าตำแหน่งของไอเท็มอันแรก/สุดท้ายที่พบในรายการ คืนค่า %1 ถ้าหาไม่พบ",
                +	"LISTS_GET_INDEX_GET": "เรียกดู",
                +	"LISTS_GET_INDEX_GET_REMOVE": "เรียกดูและเอาออก",
                +	"LISTS_GET_INDEX_REMOVE": "เอาออก",
                +	"LISTS_GET_INDEX_FROM_END": "# จากท้าย",
                +	"LISTS_GET_INDEX_FIRST": "แรกสุด",
                +	"LISTS_GET_INDEX_LAST": "ท้ายสุด",
                +	"LISTS_GET_INDEX_RANDOM": "สุ่ม",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 คือไอเท็มอันแรกสุด",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 คือไอเท็มอันท้ายสุด",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "คืนค่าเป็นไอเท็มตามตำแหน่งที่ระบุ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "คืนค่าไอเท็มอันแรกในรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "คืนค่าไอเท็มอันสุดท้ายในรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "คืนค่าไอเท็มแบบสุ่มจากรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "เอาออก และคืนค่าไอเท็มในตำแหน่งที่ระบุจากรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "เอาออก และคืนค่าไอเท็มอันแรกในรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "เอาออก และคืนค่าไอเท็มอันสุดท้ายในรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "เอาออก และคืนค่าไอเท็มแบบสุ่มจากรายการ",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "คืนค่าเป็นไอเท็มตามตำแหน่งที่ระบุ",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "เอาไอเท็มแรกสุดในรายการออก",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "เอาไอเท็มอันท้ายสุดในรายการออก",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "เอาไอเท็มแบบสุ่มจากรายการออก",
                +	"LISTS_SET_INDEX_SET": "กำหนด",
                +	"LISTS_SET_INDEX_INSERT": "แทรกที่",
                +	"LISTS_SET_INDEX_INPUT_TO": "เป็น",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "กำหนดไอเท็มในตำแหน่งที่ระบุในรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "กำหนดไอเท็มอันแรกในรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "กำหนดไอเท็มอันสุดท้ายในรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "กำหนดไอเท็มแบบสุ่มในรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "แทรกไอเท็มเข้าไปในตำแหน่งที่กำหนด",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "แทรกไอเท็มเข้าไปเป็นอันแรกสุดของรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "เพิ่มไอเท็มเข้าไปท้ายสุดของรายการ",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "เพิ่มไอเท็มเข้าไปในรายการแบบสุ่ม",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "ดึงรายการย่อยจาก #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "ดึงรายการย่อยจาก # จากท้ายสุด",
                +	"LISTS_GET_SUBLIST_START_FIRST": "ดึงรายการย่อยทั้งแต่แรกสุด",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "จนถึง #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "ถึง #  จากท้ายสุด",
                +	"LISTS_GET_SUBLIST_END_LAST": "ถึง ท้ายสุด",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "สร้างสำเนารายการในช่วงที่กำหนด",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "เรียงลำดับ %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "เรียงลำดับสำเนาของรายชื่อ",
                +	"LISTS_SORT_ORDER_ASCENDING": "น้อยไปหามาก",
                +	"LISTS_SORT_ORDER_DESCENDING": "มากไปหาน้อย",
                +	"LISTS_SORT_TYPE_NUMERIC": "ตัวเลข",
                +	"LISTS_SORT_TYPE_TEXT": "ตัวอักษร",
                +	"LISTS_SORT_TYPE_IGNORECASE": "ตัวอักษร",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "สร้างรายการจากข้อความ",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "สร้างข้อความจากรายการ",
                +	"LISTS_SPLIT_WITH_DELIMITER": "ด้วยตัวคั่น",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "แบ่งข้อความเป็นรายการข้อความ แยกแต่ละรายการด้วยตัวคั่น",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "รวมรายการข้อความเป็นข้อความเดียว แบ่งด้วยตัวคั่น",
                +	"VARIABLES_GET_TOOLTIP": "คืนค่าของตัวแปรนี้",
                +	"VARIABLES_GET_CREATE_SET": "สร้าง \"กำหนด %1\"",
                +	"VARIABLES_SET": "กำหนด %1 จนถึง %2",
                +	"VARIABLES_SET_TOOLTIP": "กำหนดให้ตัวแปรนี้เท่ากับการป้อนข้อมูล",
                +	"VARIABLES_SET_CREATE_GET": "สร้าง \"get %1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "ถึง",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "ทำอะไรบางอย่าง",
                +	"PROCEDURES_BEFORE_PARAMS": "ด้วย:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ด้วย:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "สร้างฟังก์ชันที่ไม่มีผลลัพธ์",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "อธิบายฟังก์ชันนี้",
                +	"PROCEDURES_DEFRETURN_RETURN": "คืนค่า",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "สร้างฟังก์ชันที่มีผลลัพธ์",
                +	"PROCEDURES_ALLOW_STATEMENTS": "ข้อความที่ใช้ได้",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "ระวัง: ฟังก์ชันนี้มีพารามิเตอร์ที่มีชื่อซ้ำกัน",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_(computer_science)",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "เรียกใช้ฟังก์ชันที่สร้างโดยผู้ใช้ \"%1\"",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_(computer_science)",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "เรียกใช้ฟังก์ชันที่สร้างโดยผู้ใช้ \"%1\" และใช้ผลลัพธ์ของมัน",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "นำเข้า",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "เพิ่ม, ลบ, หรือจัดเรียง ข้อมูลที่ป้อนเข้าฟังก์ชันนี้",
                +	"PROCEDURES_MUTATORARG_TITLE": "ชื่อนำเข้า:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "เพิ่มค่าป้อนเข้าฟังก์ชัน",
                +	"PROCEDURES_HIGHLIGHT_DEF": "เน้นฟังก์ชันนิยาม",
                +	"PROCEDURES_CREATE_DO": "สร้าง \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "ถ้ามีค่าเป็นจริง ให้คืนค่าที่สอง",
                +	"PROCEDURES_IFRETURN_WARNING": "ระวัง: บล็อกนี้ใช้เฉพาะในการสร้างฟังก์ชันเท่านั้น"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/tl.json b/blockly/webif/static/blockly/msg/json/tl.json
                new file mode 100644
                index 000000000..9d931b982
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/tl.json
                @@ -0,0 +1,301 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"아라"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "item",
                +	"DUPLICATE_BLOCK": "Kaparehas",
                +	"ADD_COMMENT": "Dagdag komento",
                +	"REMOVE_COMMENT": "Remove Comment",
                +	"EXTERNAL_INPUTS": "Panlabas na Inputs",
                +	"INLINE_INPUTS": "Inline na Inputs",
                +	"DELETE_BLOCK": "burahin ang bloke",
                +	"DELETE_X_BLOCKS": "burahin %1 ng bloke",
                +	"COLLAPSE_BLOCK": "bloke",
                +	"COLLAPSE_ALL": "bloke",
                +	"EXPAND_BLOCK": "Palawakin ang Block",
                +	"EXPAND_ALL": "Palawakin ang Blocks",
                +	"DISABLE_BLOCK": "Ipangwalang bisa ang Block",
                +	"ENABLE_BLOCK": "Bigyan ng bisa ang Block",
                +	"HELP": "Tulong",
                +	"CHANGE_VALUE_TITLE": "pagbago ng value:",
                +	"RENAME_VARIABLE": "Rename variable...",
                +	"RENAME_VARIABLE_TITLE": "Rename all '%1' variables to:",
                +	"NEW_VARIABLE": "New variable...",
                +	"NEW_VARIABLE_TITLE": "New variable name:",
                +	"COLOUR_PICKER_HELPURL": "http://en.wikipedia.org/wiki/Color",
                +	"COLOUR_PICKER_TOOLTIP": "pagpili ng kulay sa paleta.",
                +	"COLOUR_RANDOM_TITLE": "iba ibang kulay",
                +	"COLOUR_RANDOM_TOOLTIP": "pagpili ng iba't ibang kulay.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "kulayan ng",
                +	"COLOUR_RGB_RED": "pula",
                +	"COLOUR_RGB_GREEN": "berde",
                +	"COLOUR_RGB_BLUE": "asul",
                +	"COLOUR_RGB_TOOLTIP": "gumawa ng kulay ng may espisipikong dami ng kulay pula, berde, at asul. lahat ng halaga ay dapat sa pagitan ng 0 at 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "halo",
                +	"COLOUR_BLEND_COLOUR1": "kulay 1",
                +	"COLOUR_BLEND_COLOUR2": "kulay 2",
                +	"COLOUR_BLEND_RATIO": "proporsyon",
                +	"COLOUR_BLEND_TOOLTIP": "Paghalo ng dalawang kulay kasama ng ibinigay na proporsyon (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "http://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "ulitin %1 beses",
                +	"CONTROLS_REPEAT_INPUT_DO": "gawin",
                +	"CONTROLS_REPEAT_TOOLTIP": "gumawa ng ilang pangungusap ng ilang ulit.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "ulitin habang",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "ulitin hanggang",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Habang ang value ay true, gagawin ang ibang statements.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Habang ang value ay false, gagawin ang ibang statements.",
                +	"CONTROLS_FOR_TOOLTIP": "Magkaroon ng mga variable na \"%1\" na tanggalin ng mga halaga mula sa simulang numero hanggang sa dulong numero, at bilangin sa pamamagitan ng tinukoy na agwat, at gawin ang mga tinukoy na mga blocks.",
                +	"CONTROLS_FOR_TITLE": "bilangin %1 mula %2 hanggang %3 ng %4",
                +	"CONTROLS_FOREACH_TITLE": "sa bawat bagay %1 sa listahan %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Para sa bawat item sa isang list, i-set ang variable ng '%1' sa mga item, at pagkatapos ay gumawa ng ilang mga statements.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "putulin ang paulit ulit",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "Magpatuloy sa susunod na pag-ulit ng loop",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Hatiin ang nilalaman ng loop.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Laktawan ang natitirang bahagi ng loop, at magpatuloy sa susunod na pag-ulit.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Babala: Ang block ito ay maaari lamang magamit sa loob ng loop.",
                +	"CONTROLS_IF_TOOLTIP_1": "kung ang value ay true,  gagawin ang do statements.",
                +	"CONTROLS_IF_TOOLTIP_2": "Kung ang value ay true, gagawin ang unang block ng do statements. Kung hindi, gagawin ang pangalawang block ng statement.",
                +	"CONTROLS_IF_TOOLTIP_3": "Kung ang unang value ay true, gagawin ang first block ng statement. Kung hindi, kung ang second value ay true, gagawin ang second block ng statement.",
                +	"CONTROLS_IF_TOOLTIP_4": "Kung ang first value ay true, gagawin ang first block ng statement. Kung hindi true ang second value, gagawin ang second block ng statement. Kung wala sa mga values ay true, gagawin ang last block ng statements.",
                +	"CONTROLS_IF_MSG_IF": "kung",
                +	"CONTROLS_IF_MSG_ELSEIF": "else if",
                +	"CONTROLS_IF_MSG_ELSE": "else",
                +	"CONTROLS_IF_IF_TOOLTIP": "Mag Add, remove o kaya mag reorder ng sections para maayos ang if block.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Mag dagdag ng condition sa if block.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Mag Add ng final, kunin lahat ng condition sa if block.",
                +	"LOGIC_COMPARE_HELPURL": "http://en.wikipedia.org/wiki/Inequality_(mathematics)",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Nag babalik ng true kung ang pinasok ay parehong magkatumbas.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Return true if both inputs are not equal to each other.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Nag babalik ng true kung ang unang pinasok ay maliit kaysa sa pangalawang pinasok.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Nag babalik ng true kung ang unang pinasok ay maliit sa o katumbas sa pangalawang pinasok.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Nagbabalik ng true kung ang unang pinasok ay mas malaki kaysa pangalawang pinasok.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Nag babalik ng true kung ang unang pinasok ay mas malaki or katumbas ng pangalawang pinasok.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Return true if both inputs are true.",
                +	"LOGIC_OPERATION_AND": "at",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Return true if at least one of the inputs is true.",
                +	"LOGIC_OPERATION_OR": "o",
                +	"LOGIC_NEGATE_TITLE": "not %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Returns true if the input is false.  Returns false if the input is true.",
                +	"LOGIC_BOOLEAN_TRUE": "tama",
                +	"LOGIC_BOOLEAN_FALSE": "mali",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Nag babalik ng true or false.",
                +	"LOGIC_NULL_HELPURL": "http://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "blangko",
                +	"LOGIC_NULL_TOOLTIP": "Returns null.",
                +	"LOGIC_TERNARY_HELPURL": "http://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "kung tama",
                +	"LOGIC_TERNARY_IF_FALSE": "kung mali",
                +	"LOGIC_TERNARY_TOOLTIP": "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.",
                +	"MATH_NUMBER_HELPURL": "http://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "A number.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_ARITHMETIC_HELPURL": "http://en.wikipedia.org/wiki/Arithmetic",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Return the sum of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Return the difference of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Return the product of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Return the quotient of the two numbers.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Return the first number raised to the power of the second number.",
                +	"MATH_SINGLE_HELPURL": "http://en.wikipedia.org/wiki/Square_root",
                +	"MATH_SINGLE_OP_ROOT": "square root",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Return the square root of a number.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "absolute",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Return the absolute value of a number.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Return the negation of a number.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Return the natural logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Return the base 10 logarithm of a number.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Return e to the power of a number.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Return 10 to the power of a number.",
                +	"MATH_TRIG_HELPURL": "http://en.wikipedia.org/wiki/Trigonometric_functions",
                +	"MATH_TRIG_TOOLTIP_SIN": "Return the sine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_COS": "Return the cosine of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Return the tangent of a degree (not radian).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Return the arcsine of a number.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Return the arccosine of a number.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Return the arctangent of a number.",
                +	"MATH_CONSTANT_HELPURL": "http://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).",
                +	"MATH_IS_EVEN": "is even",
                +	"MATH_IS_ODD": "is odd",
                +	"MATH_IS_PRIME": "is prime",
                +	"MATH_IS_WHOLE": "is whole",
                +	"MATH_IS_POSITIVE": "ay positibo",
                +	"MATH_IS_NEGATIVE": "ay negatibo",
                +	"MATH_IS_DIVISIBLE_BY": "is divisible by",
                +	"MATH_IS_TOOLTIP": "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number.  Returns true or false.",
                +	"MATH_CHANGE_HELPURL": "http://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "baguhin %1 by %2",
                +	"MATH_CHANGE_TOOLTIP": "Add a number to variable '%1'.",
                +	"MATH_ROUND_HELPURL": "http://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Round a number up or down.",
                +	"MATH_ROUND_OPERATOR_ROUND": "round",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "round up",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "round down",
                +	"MATH_ONLIST_OPERATOR_SUM": "sum of list",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Return the sum of all the numbers in the list.",
                +	"MATH_ONLIST_OPERATOR_MIN": "min of list",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Return the smallest number in the list.",
                +	"MATH_ONLIST_OPERATOR_MAX": "max of list",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Return the largest number in the list.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "average of list",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Return the average (arithmetic mean) of the numeric values in the list.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "median of list",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Return the median number in the list.",
                +	"MATH_ONLIST_OPERATOR_MODE": "modes of list",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Return a list of the most common item(s) in the list.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "standard deviation of list",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Return the standard deviation of the list.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "random item of list",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Return a random element from the list.",
                +	"MATH_MODULO_HELPURL": "http://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "remainder of %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Return the remainder from dividing the two numbers.",
                +	"MATH_CONSTRAIN_TITLE": "constrain %1 low %2 high %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Constrain a number to be between the specified limits (inclusive).",
                +	"MATH_RANDOM_INT_HELPURL": "http://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "random integer from %1 to %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Return a random integer between the two specified limits, inclusive.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "http://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "random fraction",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).",
                +	"TEXT_TEXT_HELPURL": "http://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "A letter, word, or line of text.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "create text with",
                +	"TEXT_JOIN_TOOLTIP": "Create a piece of text by joining together any number of items.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "join",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Add, remove, or reorder sections to reconfigure this text block.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Add an item to the text.",
                +	"TEXT_APPEND_TOOLTIP": "Append some text to variable '%1'.",
                +	"TEXT_LENGTH_TITLE": "length of %1",
                +	"TEXT_LENGTH_TOOLTIP": "Returns the number of letters (including spaces) in the provided text.",
                +	"TEXT_ISEMPTY_TITLE": "%1 is empty",
                +	"TEXT_ISEMPTY_TOOLTIP": "Returns true if the provided text is empty.",
                +	"TEXT_INDEXOF_TOOLTIP": "Returns the index of the first/last occurrence of first text in the second text.  Returns %1 if text is not found.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "find first occurrence of text",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "find last occurrence of text",
                +	"TEXT_CHARAT_FROM_START": "get letter #",
                +	"TEXT_CHARAT_FROM_END": "get letter # from end",
                +	"TEXT_CHARAT_FIRST": "get first letter",
                +	"TEXT_CHARAT_LAST": "get last letter",
                +	"TEXT_CHARAT_RANDOM": "get random letter",
                +	"TEXT_CHARAT_TOOLTIP": "Returns the letter at the specified position.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Returns a specified portion of the text.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "in text",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "get substring from letter #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "get substring from letter # from end",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "get substring from first letter",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "to letter #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "to letter # from end",
                +	"TEXT_GET_SUBSTRING_END_LAST": "to last letter",
                +	"TEXT_CHANGECASE_TOOLTIP": "Return a copy of the text in a different case.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "to UPPER CASE",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "to lower case",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "to Title Case",
                +	"TEXT_TRIM_TOOLTIP": "Return a copy of the text with spaces removed from one or both ends.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "trim spaces from both sides",
                +	"TEXT_TRIM_OPERATOR_LEFT": "trim spaces from left side",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "trim spaces from right side",
                +	"TEXT_PRINT_TITLE": "print %1",
                +	"TEXT_PRINT_TOOLTIP": "Print the specified text, number or other value.",
                +	"TEXT_PROMPT_TYPE_TEXT": "prompt for text with message",
                +	"TEXT_PROMPT_TYPE_NUMBER": "prompt for number with message",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Prompt for user for a number.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Prompt for user for some text.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "Gumawa ng walang laman na list",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Ibabalik ang list, na may haba na 0, nag lalaman ng walang data records",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Gumawa ng list na may kahit anong number ng items.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "gumawa ng list kasama",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "list",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Magdagdag, mag tanggal or mag ayos ng sections para muling maayos ang listahan ng block.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Mag dagdag ng item sa list.",
                +	"LISTS_REPEAT_TOOLTIP": "Pag gawa ng list na binubuo ng binigay na value at inulit na tinuloy na bilang ng beses.",
                +	"LISTS_REPEAT_TITLE": "pag gawa ng list kasama ng item %1 inuulit %2 beses",
                +	"LISTS_LENGTH_TITLE": "haba ng %1",
                +	"LISTS_LENGTH_TOOLTIP": "Pag balik ng haba ng list.",
                +	"LISTS_ISEMPTY_TITLE": "%1 ay walang laman",
                +	"LISTS_ISEMPTY_TOOLTIP": "Nagbabalik ng true kung ang list ay walang laman.",
                +	"LISTS_INLIST": "sa list",
                +	"LISTS_INDEX_OF_FIRST": "Hanapin ang unang pangyayari ng item",
                +	"LISTS_INDEX_OF_LAST": "hanapin ang huling pangyayari ng item",
                +	"LISTS_INDEX_OF_TOOLTIP": "Pagbalik ng index ng una/huli pangyayari ng item sa list. Pagbalik ng %1 kung ang item ay hindi makita.",
                +	"LISTS_GET_INDEX_GET": "kunin",
                +	"LISTS_GET_INDEX_GET_REMOVE": "kunin at tanggalin",
                +	"LISTS_GET_INDEX_REMOVE": "tanggalin",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# mula katapusan",
                +	"LISTS_GET_INDEX_FIRST": "Una",
                +	"LISTS_GET_INDEX_LAST": "huli",
                +	"LISTS_GET_INDEX_RANDOM": "nang hindi pinipili",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ay ang unang item.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 ay ang huling item.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Ibalik ang item sa itinakdang posisyon sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Ibalik ang unang item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Ibalik ang huling item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Nag babalik ng hindi pinipiling item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Nag tatanggal at nag babalik ng mga items sa tinukoy na posisyon sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Nag tatanggal at nag babalik ng mga unang item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Nag tatanggal at nag babalik ng huling item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Nag tatanggal at nag babalik ng mga hindi pinipiling item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Nag tatanggal ng item sa tinukoy na posisyon sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Nag tatanggal ng unang item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Nag tatanggal ng huling item sa list.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Nag tatanggal ng item mula sa walang pinipiling list.",
                +	"LISTS_SET_INDEX_SET": "set",
                +	"LISTS_SET_INDEX_INSERT": "isingit sa",
                +	"LISTS_SET_INDEX_INPUT_TO": "gaya ng",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Pag set ng item sa tinukoy na position sa isang list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Pag set ng unang item sa isang list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Pag set sa huling item sa isang list.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Pag set ng walang pinipiling item sa isang list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Nag singit ng item sa tinukoy na posistion sa list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Nag singit ng item sa simula ng list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Idagdag ang item sa huli ng isang list.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Isingit ang item ng walang pinipili sa isang list.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "pag kuha ng sub-list mula #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "pag kuha ng sub-list mula sa # mula huli",
                +	"LISTS_GET_SUBLIST_START_FIRST": "pag kuha ng sub-list mula sa una",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "mula #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "mula # hanggang huli",
                +	"LISTS_GET_SUBLIST_END_LAST": "hanggang huli",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Gumagawa ng kopya ng tinukoy na bahagi ng list.",
                +	"VARIABLES_GET_TOOLTIP": "Returns the value of this variable.",
                +	"VARIABLES_GET_CREATE_SET": "Create 'set %1'",
                +	"VARIABLES_SET": "set %1 to %2",
                +	"VARIABLES_SET_TOOLTIP": "Sets this variable to be equal to the input.",
                +	"VARIABLES_SET_CREATE_GET": "Create 'get %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "to",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "do something",
                +	"PROCEDURES_BEFORE_PARAMS": "with:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "with:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Creates a function with no output.",
                +	"PROCEDURES_DEFRETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "return",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Creates a function with an output.",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Warning: This function has duplicate parameters.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Run the user-defined function '%1'.",
                +	"PROCEDURES_CALLRETURN_HELPURL": "http://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Run the user-defined function '%1' and use its output.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "inputs",
                +	"PROCEDURES_MUTATORARG_TITLE": "input name:",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Highlight function definition",
                +	"PROCEDURES_CREATE_DO": "Create '%1'",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "If a value is true, then return a second value.",
                +	"PROCEDURES_IFRETURN_WARNING": "Warning: This block may be used only within a function definition."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/tlh.json b/blockly/webif/static/blockly/msg/json/tlh.json
                new file mode 100644
                index 000000000..8be1d1dac
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/tlh.json
                @@ -0,0 +1,182 @@
                +{
                +	"@metadata": {
                +		"author": "Neil Fraser <fraser@google.com>",
                +		"lastupdated": "2014-03-24 23:00:00.000000",
                +		"locale": "tlh",
                +		"messagedocumentation" : "qqq"
                +	},
                +	"VARIABLES_DEFAULT_NAME": "Doch",
                +	"TODAY": "DaHjaj",
                +	"DUPLICATE_BLOCK": "velqa' chenmoH",
                +	"ADD_COMMENT": "QInHom chel",
                +	"REMOVE_COMMENT": "QInHom chelHa'",
                +	"EXTERNAL_INPUTS": "Hur rar",
                +	"INLINE_INPUTS": "qoD rar",
                +	"DELETE_BLOCK": "ngogh Qaw'",
                +	"DELETE_X_BLOCKS": "%1 ngoghmey Qaw'",
                +	"DELETE_ALL_BLOCKS": "Hoch %1 ngoghmey Qaw'?",
                +	"CLEAN_UP": "ngoghmeyvaD tlhegh rurmoH",
                +	"COLLAPSE_BLOCK": "ngogh DejmoH",
                +	"COLLAPSE_ALL": "ngoghmey DejmoH",
                +	"EXPAND_BLOCK": "ngogh DejHa'moH",
                +	"EXPAND_ALL": "ngoghmey DejHa'moH",
                +	"DISABLE_BLOCK": "ngogh Qotlh",
                +	"ENABLE_BLOCK": "ngogh QotlhHa'",
                +	"HELP": "QaH",
                +	"UNDO": "vangHa'",
                +	"REDO": "vangqa'",
                +	"CHANGE_VALUE_TITLE": "choH:",
                +	"NEW_VARIABLE": "lIw chu'...",
                +	"NEW_VARIABLE_TITLE": "lIw chu' pong:",
                +	"RENAME_VARIABLE": "lIw pong choH...",
                +	"RENAME_VARIABLE_TITLE": "Hoch \"%1\" lIwmey pongmey choH:",
                +	"COLOUR_RANDOM_TITLE": "rItlh vISaHbe'",
                +	"COLOUR_RGB_TITLE": "rItlh wIv",
                +	"COLOUR_RGB_RED": "'Iw rItlh",
                +	"COLOUR_RGB_GREEN": "tI rItlh",
                +	"COLOUR_RGB_BLUE": "chal rItlh",
                +	"COLOUR_BLEND_TITLE": "DuD",
                +	"COLOUR_BLEND_COLOUR1": "rItlh wa'",
                +	"COLOUR_BLEND_COLOUR2": "rItlh cha'",
                +	"COLOUR_BLEND_RATIO": "'ar",
                +	"CONTROLS_REPEAT_TITLE": "%1-logh qaSmoH",
                +	"CONTROLS_REPEAT_INPUT_DO": "ruch",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "teHtaHvIS qaSmoH",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "teHpa' qaSmoH",
                +	"CONTROLS_FOR_TITLE": "togh %1 mung %2 ghoch %3 Do %4",
                +	"CONTROLS_FOREACH_TITLE": "ngIq Doch %1 ngaSbogh tetlh %2 nuDDI'",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "gho Haw'",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "gho taHqa'",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "yIqIm! ghoDaq neH ngoghvam lo'laH vay'.",
                +	"CONTROLS_IF_MSG_IF": "teHchugh",
                +	"CONTROLS_IF_MSG_ELSEIF": "pagh teHchugh",
                +	"CONTROLS_IF_MSG_ELSE": "pagh",
                +	"LOGIC_OPERATION_AND": "'ej",
                +	"LOGIC_OPERATION_OR": "qoj",
                +	"LOGIC_NEGATE_TITLE": "yoymoH %1",
                +	"LOGIC_BOOLEAN_TRUE": "teH",
                +	"LOGIC_BOOLEAN_FALSE": "teHbe'",
                +	"LOGIC_NULL": "paghna'",
                +	"LOGIC_TERNARY_CONDITION": "chov",
                +	"LOGIC_TERNARY_IF_TRUE": "teHchugh",
                +	"LOGIC_TERNARY_IF_FALSE": "teHbe'chugh",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "-",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "×",
                +	"MATH_POWER_SYMBOL": "^",
                +	"MATH_TRIG_SIN": "sin",
                +	"MATH_TRIG_COS": "cos",
                +	"MATH_TRIG_TAN": "tan",
                +	"MATH_TRIG_ASIN": "asin",
                +	"MATH_TRIG_ACOS": "acos",
                +	"MATH_TRIG_ATAN": "atan",
                +	"MATH_SINGLE_OP_ROOT": "cha'DIch wav",
                +	"MATH_SINGLE_OP_ABSOLUTE": "Dung pagh choH",
                +	"MATH_IS_EVEN": "lang'a' mI'",
                +	"MATH_IS_ODD": "ror'a' mI'",
                +	"MATH_IS_PRIME": "potlh'a' mI'",
                +	"MATH_IS_WHOLE": "ngoHlaHbe''a'",
                +	"MATH_IS_POSITIVE": "Dung pagh",
                +	"MATH_IS_NEGATIVE": "bIng pagh",
                +	"MATH_IS_DIVISIBLE_BY": "wav'a'",
                +	"MATH_CHANGE_TITLE": "choH %1 chel %2",
                +	"MATH_ROUND_OPERATOR_ROUND": "ngoH",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "Dung ngoH",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "bIng ngoH",
                +	"MATH_ONLIST_OPERATOR_SUM": "chelwI' SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_MIN": "machwI''a' SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_MAX": "tInwI''a' SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "beQwI' SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "beQwI'botlh SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_MODE": "beQwI' motlh SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "motlhbe'wI' SIm tetlh",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "SaHbe' SIm tetlh",
                +	"MATH_MODULO_TITLE": "ratlwI' SIm %1 ÷ %2",
                +	"MATH_CONSTRAIN_TITLE": "jon %1 bIng %2 Dung %3",
                +	"MATH_RANDOM_INT_TITLE": "ngoH mI'SaHbe' bIng %1 Dung %2",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "mI'HomSaHbe'",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ghItlh ghom",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "ghom",
                +	"TEXT_APPEND_TO": "chel",
                +	"TEXT_APPEND_APPENDTEXT": "ghItlh",
                +	"TEXT_LENGTH_TITLE": "chuq %1",
                +	"TEXT_ISEMPTY_TITLE": "%1 chIm'a'",
                +	"TEXT_INDEXOF_INPUT_INTEXT": "ghItlhDaq",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "ghItlh wa'DIch Sam",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "ghItlh Qav Sam",
                +	"TEXT_INDEXOF_TAIL": "",
                +	"TEXT_CHARAT_INPUT_INTEXT": "ghItlhDaq",
                +	"TEXT_CHARAT_FROM_START": "mu'Hom #",
                +	"TEXT_CHARAT_FROM_END": "mu'Hom # Qav",
                +	"TEXT_CHARAT_FIRST": "mu'Hom wa'DIch",
                +	"TEXT_CHARAT_LAST": "mu'Hom Qav",
                +	"TEXT_CHARAT_RANDOM": "mu'Hom SaHbe'",
                +	"TEXT_CHARAT_TAIL": "Suq",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ghItlhDaq",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "ghItlhHom moHaq mu'Hom #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "ghItlhHom moHaq mu'Hom # Qav",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "ghItlhHom moHaq mu'Hom wa'DIch",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "mojaq mu'Hom #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "mojaq mu'Hom # Qav",
                +	"TEXT_GET_SUBSTRING_END_LAST": "mojaq mu'Hom Qav",
                +	"TEXT_GET_SUBSTRING_TAIL": "Suq",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "tInchoH",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "machchoH",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "DojchoH",
                +	"TEXT_TRIM_OPERATOR_BOTH": "poSnIHlogh pei",
                +	"TEXT_TRIM_OPERATOR_LEFT": "poSlogh pei",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "nIHlogh pei",
                +	"TEXT_PRINT_TITLE": "maq %1",
                +	"TEXT_PROMPT_TYPE_TEXT": "ghItln tlhob 'ej maq",
                +	"TEXT_PROMPT_TYPE_NUMBER": "mI' tlhob 'ej maq",
                +	"LISTS_CREATE_EMPTY_TITLE": "tetlh chIm",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "tetlh ghom",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "tetlh",
                +	"LISTS_REPEAT_TITLE": "tetlh ghom %2 Dochmey %1 pus",
                +	"LISTS_LENGTH_TITLE": "chuq %1",
                +	"LISTS_ISEMPTY_TITLE": "%1 chIm'a'",
                +	"LISTS_INLIST": "tetlhDaq",
                +	"LISTS_INDEX_OF_FIRST": "Doch sam wa'DIch",
                +	"LISTS_INDEX_OF_LAST": "Doch sam Qav",
                +	"LISTS_GET_INDEX_GET": "Suq",
                +	"LISTS_GET_INDEX_GET_REMOVE": "Suq vaj pej",
                +	"LISTS_GET_INDEX_REMOVE": "pej",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# Qav",
                +	"LISTS_GET_INDEX_FIRST": "wa'DIch",
                +	"LISTS_GET_INDEX_LAST": "Qav",
                +	"LISTS_GET_INDEX_RANDOM": "Sahbe'",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_SET_INDEX_SET": "choH",
                +	"LISTS_SET_INDEX_INSERT": "lIH",
                +	"LISTS_SET_INDEX_INPUT_TO": "Dos",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "tetlhHom moHaq #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "tetlhHom moHaq # Qav",
                +	"LISTS_GET_SUBLIST_START_FIRST": "tetlhHom moHaq wa'DIch",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "mojaQ #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "mojaQ # Qav",
                +	"LISTS_GET_SUBLIST_END_LAST": "mojaQ Qav",
                +	"LISTS_GET_SUBLIST_TAIL": "Suq",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "tetlh ghermeH ghItlh wav",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "ghItlh chenmoHmeH tetlh gherHa'",
                +	"LISTS_SPLIT_WITH_DELIMITER": "rarwI'Hom lo'",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_CREATE_SET": "chel 'choH %1'",
                +	"VARIABLES_SET": "choH %1 %2",
                +	"VARIABLES_SET_CREATE_GET": "chel 'Suq %1'",
                +	"PROCEDURES_DEFNORETURN_TITLE": "ruch",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "mIw",
                +	"PROCEDURES_BEFORE_PARAMS": "qel:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "qel:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "mIw yIDel...",
                +	"PROCEDURES_DEFRETURN_RETURN": "chegh",
                +	"PROCEDURES_ALLOW_STATEMENTS": "mu'tlhegh chaw'",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "ghuHmoHna': qelwI' cha'logh chen.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "qelwI'mey",
                +	"PROCEDURES_MUTATORARG_TITLE": "pong:",
                +	"PROCEDURES_HIGHLIGHT_DEF": "mIwna' wew",
                +	"PROCEDURES_CREATE_DO": "chel '%1'",
                +	"PROCEDURES_IFRETURN_WARNING": "ghoHmoHna': ngoghvam ngaSbe' mIwDaq."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/tr.json b/blockly/webif/static/blockly/msg/json/tr.json
                new file mode 100644
                index 000000000..aa0862bf9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/tr.json
                @@ -0,0 +1,377 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Meelo",
                +			"Joseph",
                +			"WikiBronze",
                +			"Mavrikant",
                +			"아라",
                +			"Watermelon juice",
                +			"Uğurkent",
                +			"McAang",
                +			"Gurkanht",
                +			"HakanIST",
                +			"Imabadplayer",
                +			"Kumkumuk",
                +			"Alpkant",
                +			"Bulgu",
                +			"By erdo can",
                +			"Azerhan Özen"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "öge",
                +	"TODAY": "Bugün",
                +	"DUPLICATE_BLOCK": "Çoğalt",
                +	"ADD_COMMENT": "Yorum Ekle",
                +	"REMOVE_COMMENT": "Yorumu Sil",
                +	"EXTERNAL_INPUTS": "Harici Girişler",
                +	"INLINE_INPUTS": "Satır içi girdiler",
                +	"DELETE_BLOCK": "Bloğu Sil",
                +	"DELETE_X_BLOCKS": "%1 Blokları Sil",
                +	"DELETE_ALL_BLOCKS": "Tüm %1 blok silinsin mi?",
                +	"CLEAN_UP": "Blokları temizle",
                +	"COLLAPSE_BLOCK": "Blok'u Daralt",
                +	"COLLAPSE_ALL": "Blokları Daralt",
                +	"EXPAND_BLOCK": "Bloğu Genişlet",
                +	"EXPAND_ALL": "Blokları Genişlet",
                +	"DISABLE_BLOCK": "Bloğu Devre Dışı Bırak",
                +	"ENABLE_BLOCK": "Bloğu Etkinleştir",
                +	"HELP": "Yardım",
                +	"UNDO": "Geri al",
                +	"REDO": "Yinele",
                +	"CHANGE_VALUE_TITLE": "Değeri değiştir:",
                +	"RENAME_VARIABLE": "Değişkeni yeniden adlandır...",
                +	"RENAME_VARIABLE_TITLE": "Tüm '%1' değişkenlerini yeniden isimlendir:",
                +	"NEW_VARIABLE": "Değişken oluştur...",
                +	"NEW_VARIABLE_TITLE": "Yeni değişken ismi :",
                +	"VARIABLE_ALREADY_EXISTS": "'%1' isimli değişken adı zaten var.",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "'%1' isimli değişken '%2' tipli başka bir değişkende tanımlı.",
                +	"PROCEDURE_ALREADY_EXISTS": "'%1' isimli prosedür zaten var.",
                +	"DELETE_VARIABLE_CONFIRMATION": "'%2' değişkeninin %1 kullanımını silmek istiyor musunuz?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "'%1' değişkeni, '%2' fonksiyonunun tanımının bir parçası olduğu için silinemez",
                +	"DELETE_VARIABLE": "'%1' değişkenini silmek istiyor musunuz?",
                +	"COLOUR_PICKER_HELPURL": "https://tr.wikipedia.org/wiki/Renk",
                +	"COLOUR_PICKER_TOOLTIP": "Paletten bir renk seçin.",
                +	"COLOUR_RANDOM_TITLE": "rastgele renk",
                +	"COLOUR_RANDOM_TOOLTIP": "Rastgele bir renk seçin.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "renk değerleri",
                +	"COLOUR_RGB_RED": "kırmızı",
                +	"COLOUR_RGB_GREEN": "yeşil",
                +	"COLOUR_RGB_BLUE": "mavi",
                +	"COLOUR_RGB_TOOLTIP": "Kırmızı, yeşil ve mavinin belirtilen miktarıyla bir renk oluşturun.  Tüm değerler 0 ile 100 arasında olmalıdır.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "karıştır",
                +	"COLOUR_BLEND_COLOUR1": "renk 1",
                +	"COLOUR_BLEND_COLOUR2": "renk 2",
                +	"COLOUR_BLEND_RATIO": "oran",
                +	"COLOUR_BLEND_TOOLTIP": "Verilen bir orana bağlı olarak iki rengi karıştırır. (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://tr.wikipedia.org/wiki/For_d%C3%B6ng%C3%BCs%C3%BC",
                +	"CONTROLS_REPEAT_TITLE": "%1 kez tekrarla",
                +	"CONTROLS_REPEAT_INPUT_DO": "yap",
                +	"CONTROLS_REPEAT_TOOLTIP": "Bazı işlemleri birkaç kez yap.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "tekrar ederken",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "kadar tekrarla",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Bir değer doğru olduğunda bazı beyanlarda bulun.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Bir değer yanlış olduğunda bazı beyanlarda bulun.",
                +	"CONTROLS_FOR_TOOLTIP": "Başlangıç sayısından bitiş sayısına kadar belirtilen aralık ve belirtilen engeller ile devam eden değerler alan '%1' değişkeni oluştur.",
                +	"CONTROLS_FOR_TITLE": "ile sayılır %1 %2 den %3 ye, her adımda %4 değişim",
                +	"CONTROLS_FOREACH_TITLE": "her öğe için %1 listede %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Bir listedeki her öğe için  '%1' değişkenini maddeye atayın  ve bundan sonra bazı açıklamalar yapın.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "döngüden çık",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "döngünün sonraki adımından devam et",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "İçeren döngüden çık.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Bu döngünün geri kalanını atlayın ve sonraki adım ile devam edin.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Uyarı: Bu blok sadece bir döngü içinde kullanılabilir.",
                +	"CONTROLS_IF_TOOLTIP_1": "Eğer değişken true , yani gerçekleşmiş ise , ardından gelen işlemi yerine getir .",
                +	"CONTROLS_IF_TOOLTIP_2": "Eğer değişken true, yani gerçekleşiyor ise ilk blok'taki işlemleri yerine getir, Aksi halde ikinci blok'taki işlemleri yerine getir.",
                +	"CONTROLS_IF_TOOLTIP_3": "Eğer ilk değişken true, yani koşul gerçekleşmiş ise ilk blok içerisindeki işlem(ler)i gerçekleştir. Eğer ikinci değişken true ise, ikinci bloktaki işlem(ler)i gerçekleştir .",
                +	"CONTROLS_IF_TOOLTIP_4": "Eğer ilk değer true, yani olumlu ise, ilk blok'taki işlem(ler)i gerçekleştir. İlk değer true değil ama ikinci değer true ise, ikinci bloktaki işlem(ler)i gerçekleştir. Eğer değerlerin hiçbiri true değil ise son blok'taki işlem(ler)i gerçekleştir.",
                +	"CONTROLS_IF_MSG_IF": "eğer",
                +	"CONTROLS_IF_MSG_ELSEIF": "değilse eğer",
                +	"CONTROLS_IF_MSG_ELSE": "değilse",
                +	"CONTROLS_IF_IF_TOOLTIP": "If bloğuna ekle, kaldır veya yeniden düzenleme yap.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "If bloğuna bir koşul ekleyin.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "If bloğuna kalan durumları \"yakalayan\" bir son ekle.",
                +	"IOS_OK": "OK",
                +	"IOS_CANCEL": "İptal",
                +	"IOS_ERROR": "Hata",
                +	"IOS_PROCEDURES_INPUTS": "Girdiler",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ Giriş Ekle",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "Açıklamalara izin ver",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Bu fonksiyonda mükerrer girdi tanımlı.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Değişkeni ekle",
                +	"IOS_VARIABLES_ADD_BUTTON": "Ekle",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Yeniden adlandır",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Sil",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Değişken adı",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Değişken adı kısmı boş bırakılamaz.",
                +	"LOGIC_COMPARE_HELPURL": "https://tr.wikipedia.org/wiki/E%C5%9Fitsizlikler",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Girilen iki değer birbirine eşitse \"True\" değerini verir.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Girilen iki değerde birbirine eşit değilse \"True\" değerini verir.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Girilen ilk değer ikinci değerden küçükse \"True\" değerini verir.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Girilen ilk değer ikinci değerden küçük veya eşitse \"True\" değerini verir.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Girilen ilk değer ikinci değerden daha büyükse \"True\" değerini verir.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Girilen ilk değer ikinci değerden büyük veya eşitse \"True\" değerini verir.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Girilen iki değerde doğruysa \"True\" değerini verir.",
                +	"LOGIC_OPERATION_AND": "ve",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Girilen iki değerden en az biri doğruysa \"True\" değerini verir.",
                +	"LOGIC_OPERATION_OR": "veya",
                +	"LOGIC_NEGATE_TITLE": "%1 değil",
                +	"LOGIC_NEGATE_TOOLTIP": "Girilen değer yanlışsa \"True\" değerini verir.Girilen değer doğruysa \"False\" değerini verir.",
                +	"LOGIC_BOOLEAN_TRUE": "Olumlu",
                +	"LOGIC_BOOLEAN_FALSE": "false = Olumsuz",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Ya 'True' yada 'False' değerini verir.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "sıfır",
                +	"LOGIC_NULL_TOOLTIP": "sıfır verir.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "test",
                +	"LOGIC_TERNARY_IF_TRUE": "doğru ise",
                +	"LOGIC_TERNARY_IF_FALSE": "yanlış ise",
                +	"LOGIC_TERNARY_TOOLTIP": "'test'deki şartı test eder. Eğer şart doğru ise 'doğru' değeri döndürür, aksi halde 'yanlış' değeri döndürür.",
                +	"MATH_NUMBER_HELPURL": "https://en.wikipedia.org/wiki/Number",
                +	"MATH_NUMBER_TOOLTIP": "Bir sayı.",
                +	"MATH_ADDITION_SYMBOL": "+",
                +	"MATH_SUBTRACTION_SYMBOL": "tire",
                +	"MATH_DIVISION_SYMBOL": "÷",
                +	"MATH_MULTIPLICATION_SYMBOL": "x",
                +	"MATH_POWER_SYMBOL": "üst alma",
                +	"MATH_TRIG_SIN": "Sinüs",
                +	"MATH_TRIG_COS": "kosünüs",
                +	"MATH_TRIG_TAN": "tanjant",
                +	"MATH_TRIG_ASIN": "asinüs",
                +	"MATH_TRIG_ACOS": "akosünüs",
                +	"MATH_TRIG_ATAN": "atanjant",
                +	"MATH_ARITHMETIC_HELPURL": "https://tr.wikipedia.org/wiki/Aritmetik",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "İki rakamın toplamını döndür.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "İki sayını farkını döndür.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "İki sayının çarpımını döndür.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "İki sayının bölümünü döndür.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "İlk sayinin ikincinin kuvvetine yükseltilmişini döndür.",
                +	"MATH_SINGLE_HELPURL": "https://tr.wikipedia.org/wiki/Karek%C3%B6k",
                +	"MATH_SINGLE_OP_ROOT": "Kare kök",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Bir sayının karekökü nü döndür .",
                +	"MATH_SINGLE_OP_ABSOLUTE": "Kesin",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Bir sayının tam değerini döndür .",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Bir sayıyı geçersiz olarak döndür .",
                +	"MATH_SINGLE_TOOLTIP_LN": "Bir sayının doğal logaritmasını döndür .",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Bir sayının 10  temelinde logaritmasını döndür .",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Bir sayının e ' inci  kuvvetini döndür .",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Bir sayının 10. kuvvetini döndür .",
                +	"MATH_TRIG_HELPURL": "https://tr.wikipedia.org/wiki/Trigonometrik_fonksiyonlar",
                +	"MATH_TRIG_TOOLTIP_SIN": "Bir açının sinüsünü döndür(radyan olarak değil).",
                +	"MATH_TRIG_TOOLTIP_COS": "Bir açının kosinüsünü döndür(radyan olarak değil).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Bir açının tanjantını döndür(radyan olarak değil).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Bir sayının ters sinüsünü döndür .",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Bir sayının ters kosunusunu döndür .",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Bir sayının ters tanjantını döndür .",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Yaygın sabitlerden birini döndür:π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (sonsuz).",
                +	"MATH_IS_EVEN": "çift",
                +	"MATH_IS_ODD": "tek",
                +	"MATH_IS_PRIME": "asal",
                +	"MATH_IS_WHOLE": "Bütün olduğunu",
                +	"MATH_IS_POSITIVE": "pozitif",
                +	"MATH_IS_NEGATIVE": "negatif",
                +	"MATH_IS_DIVISIBLE_BY": "bölünebilir",
                +	"MATH_IS_TOOLTIP": "Bir sayinin çift mi tek mi , tam mı, asal mı , pozitif mi, negatif mi, veya tam bir  sayıyla bölünebilirliğini kontrol et.'True' veya 'False' değerini döndür.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "%1'i %2 kadar değiştir",
                +	"MATH_CHANGE_TOOLTIP": "'%1' değişkenine bir sayı ekle.",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding Yuvarlama fonksiyonu için araştırma yapınız, sayfanın Türkçe çevirisi henüz mevcut değil.",
                +	"MATH_ROUND_TOOLTIP": "Bir sayı yı yukarı yada aşağı yuvarla .",
                +	"MATH_ROUND_OPERATOR_ROUND": "Yuvarla",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "yukarı yuvarla",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "aşağı yuvarla",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "Listenin toplamı",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Listede ki tüm sayıların toplamını döndür.",
                +	"MATH_ONLIST_OPERATOR_MIN": "Listenin en küçüğü",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Listenin en küçüğünü döndür.",
                +	"MATH_ONLIST_OPERATOR_MAX": "en büyük sayı",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Listenin en büyüğünü döndür.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "listenin ortalaması",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Listedeki sayısal değerlerin ortalamasını (aritmetik anlamda) döndür.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "Listenin medyanı",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Listenin medyanını döndür.",
                +	"MATH_ONLIST_OPERATOR_MODE": "Listenin modları",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Listede ki en yaygın öğe veya öğelerinin listesini döndür.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "Listenin standart sapması",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Listenin standart sapmasını döndür.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "Listenin rastgele öğesi",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Listeden rastgele bir element döndür.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "%1 ÷ %2 nin kalanı",
                +	"MATH_MODULO_TOOLTIP": "İki sayının bölümünden kalanı döndür.",
                +	"MATH_CONSTRAIN_TITLE": "%1 i en düşük %2 en yüksek %3 ile sınırla",
                +	"MATH_CONSTRAIN_TOOLTIP": "Bir sayıyı belirli iki sayı arasında sınırlandır(dahil).",
                +	"MATH_RANDOM_INT_HELPURL": "https://tr.wikipedia.org/wiki/Rastgele_say%C4%B1_%C3%BCretimi",
                +	"MATH_RANDOM_INT_TITLE": "%1 ile %2 arasında rastgele tam sayı üret",
                +	"MATH_RANDOM_INT_TOOLTIP": "Herhangi iki sayı arasında , sayılar dahil olmak üzere , rastgele bir tam sayı döndür.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://tr.wikipedia.org/wiki/Rastgele_say%C4%B1_%C3%BCretimi",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "Rast gele kesirli sayı , yada parça",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "0.0(dahil) ve 1.0 (hariç) sayıları arasında bir sayı döndür .",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/String_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Metnin bir harfi,kelimesi veya satırı.",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "ile metin oluştur",
                +	"TEXT_JOIN_TOOLTIP": "Herhangi bir sayıda ki öğeleri bir araya getirerek metnin bir parçasını oluştur.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "Katıl",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Bu metin bloğunu düzenlemek için bölüm ekle,sil veya yeniden görevlendir.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Metine bir öğe ekle.",
                +	"TEXT_APPEND_TITLE": "%1 için %2 metnini ekle.",
                +	"TEXT_APPEND_TOOLTIP": "Değişken '%1' e bazı metinler ekleyin.",
                +	"TEXT_LENGTH_TITLE": "%1 in uzunluğu",
                +	"TEXT_LENGTH_TOOLTIP": "Yazı içerisinde verilen harflerin ( harf arasındaki boşluklar dahil) sayısını verir .",
                +	"TEXT_ISEMPTY_TITLE": "%1 boş",
                +	"TEXT_ISEMPTY_TOOLTIP": "Verilen metin boşsa true(doğru) değerini verir.",
                +	"TEXT_INDEXOF_TOOLTIP": "İlk metnin ikinci metnin içindeki ilk ve son varoluşlarının indeksini döndürür.Metin bulunamadıysa %1 döndürür.",
                +	"TEXT_INDEXOF_TITLE": "%1 metni içinde %2.kez %3 metnini bul.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "Metnin ilk varolduğu yeri bul",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "Metnin son varolduğu yeri bul",
                +	"TEXT_CHARAT_TITLE": "%1 içinde %2",
                +	"TEXT_CHARAT_FROM_START": "# harfini al",
                +	"TEXT_CHARAT_FROM_END": "# dan sona harfleri al",
                +	"TEXT_CHARAT_FIRST": "İlk harfini al",
                +	"TEXT_CHARAT_LAST": "son harfi al",
                +	"TEXT_CHARAT_RANDOM": "Rastgele bir harf al",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Belirli pozisyonda ki bir harfi döndürür.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Metinin belirli bir kısmını döndürür.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "metinde",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "n inci harften alt-string alma",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "n inci harften sona kadar alt-string alma",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "ilk harften başlayarak alt-string alma",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "# harfe",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "Sondan # harfe",
                +	"TEXT_GET_SUBSTRING_END_LAST": "son harfe",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "Metnin bir kopyasını farklı bir harf durumunda (HEPSİ BÜYÜK - hepsi küçük) getirir.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "büyük harf",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "küçük harf",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Baş Harfler Büyük",
                +	"TEXT_TRIM_TOOLTIP": "Metnin bir veya her iki sondan da boşlukları silinmiş şekilde kopyasını verir.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "iki tarafından da boşlukları temizle",
                +	"TEXT_TRIM_OPERATOR_LEFT": "solundan boşlukları temizle",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "sağından boşlukları temizle",
                +	"TEXT_PRINT_TITLE": "%1 ' i Yaz",
                +	"TEXT_PRINT_TOOLTIP": "Belirli bir metni,sayıyı veya başka bir değeri yaz.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Kullanıcıdan yazım al , istek mesajıyla",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Kullanıcıdan sayı al , istek mesajı göstererek",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Kullanıcıdan sayı al .",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Kullanıcıdan Yazım al .",
                +	"TEXT_COUNT_MESSAGE0": "%1 içinde %2 yi say.",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "Başka bir metnin içinde kaç kez metnin geçtiğini say.",
                +	"TEXT_REPLACE_MESSAGE0": "%3 metni içinde %1 metnini %2 metni ile değiştir.",
                +	"TEXT_REPLACE_TOOLTIP": "Metni başka bir metnin içindeki tüm yerlerde değiştir.",
                +	"TEXT_REVERSE_MESSAGE0": "%1 karakterlerini ters çevir.",
                +	"TEXT_REVERSE_TOOLTIP": "Metnin içindeki karakterlerin sıralarını ters çevirir.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "Boş liste oluştur",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Veri kaydı içermeyen uzunluğu 0 olan bir listeyi verir",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Herhangi sayıda nesne içeren bir liste oluştur.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "İle liste oluşturma",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "liste",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Bu liste bloğunu yeniden yapılandırmak için bölüm ekle,kaldır veya yeniden çağır.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Listeye bir nesne ekle.",
                +	"LISTS_REPEAT_TOOLTIP": "Verilen bir değerin , belirli bir sayıda tekrarlanmasından oluşan bir liste yaratır .",
                +	"LISTS_REPEAT_TITLE": "%1 nesnenin %2 kez tekrarlandığı bir liste yarat",
                +	"LISTS_LENGTH_TITLE": "%1'in uzunluğu",
                +	"LISTS_LENGTH_TOOLTIP": "Bir listenin uzunluğunu verir.",
                +	"LISTS_ISEMPTY_TITLE": "%1 boş",
                +	"LISTS_ISEMPTY_TOOLTIP": "Eğer liste boş ise true döndürür .",
                +	"LISTS_INLIST": "Listede",
                +	"LISTS_INDEX_OF_FIRST": "Öğenin ilk varolduğu yeri bul",
                +	"LISTS_INDEX_OF_LAST": "Öğenin son varolduğu yeri bul",
                +	"LISTS_INDEX_OF_TOOLTIP": "Listedeki öğenin ilk/son oluşumunun indeksini döndürür. Eğer öğe bulunamaz ise %1 döndürür.",
                +	"LISTS_GET_INDEX_GET": "Al",
                +	"LISTS_GET_INDEX_GET_REMOVE": "al ve kaldır",
                +	"LISTS_GET_INDEX_REMOVE": "kaldır",
                +	"LISTS_GET_INDEX_FROM_START": "# Kare",
                +	"LISTS_GET_INDEX_FROM_END": "# sonundan",
                +	"LISTS_GET_INDEX_FIRST": "ilk",
                +	"LISTS_GET_INDEX_LAST": "son",
                +	"LISTS_GET_INDEX_RANDOM": "rastgele",
                +	"LISTS_GET_INDEX_TAIL": "",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 ilk öğedir.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 son öğedir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Listede belirli pozisyondaki bir öğeyi verir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Listedeki ilk öğeyi verir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Listedeki son öğeyi verir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Listedeki rastgele bir öğeyi verir.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Kaldırır ve listede belirtilen konumdaki bir öğeyi döndürür.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Kaldırır ve listedeki ilk öğeyi döndürür.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Kaldırır ve listedeki son öğeyi döndürür.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Kaldırır ve listedeki rastgele bir öğeyi verir.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Bir liste içerisinde , tanımlanan pozisyonda ki öğeyi kaldırır.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Listedeki ilk nesneyi kaldırır.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Listedeki son nesneyi kaldırır.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Listedeki rastgele bir nesneyi kaldırır.",
                +	"LISTS_SET_INDEX_SET": "yerleştir",
                +	"LISTS_SET_INDEX_INSERT": "e yerleştir",
                +	"LISTS_SET_INDEX_INPUT_TO": "olarak",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Bir öğeyi belirtilen yere göre listeye yerleştirir .",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Bir listenin ilk öğesini yerleştirir .",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Bir listedeki son öğeyi yerleştirir .",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Listeye rast gele bir öğe yerleştirir .",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Bir öğeyi belirtilen pozisyona göre listeye yerleştirir .",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Nesneyi listenin başlangıcına ekler.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Öğeyi listenin sonuna ekle .",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Bir öğeyi listeye rast gele ekler .",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "# dan alt liste al",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "# işaretinden sonra gelen ifadeye göre  alt liste al , # sondan",
                +	"LISTS_GET_SUBLIST_START_FIRST": "ilk öğeden alt liste al",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "#'a",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "Sondan #'a kadar",
                +	"LISTS_GET_SUBLIST_END_LAST": "Sona kadar",
                +	"LISTS_GET_SUBLIST_TAIL": "",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Listenin belirli bir kısmının kopyasını yaratır.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "kısa %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "Listenin kısa bir kopyası.",
                +	"LISTS_SORT_ORDER_ASCENDING": "artan",
                +	"LISTS_SORT_ORDER_DESCENDING": "azalan",
                +	"LISTS_SORT_TYPE_NUMERIC": "sayısal",
                +	"LISTS_SORT_TYPE_TEXT": "alfabetik",
                +	"LISTS_SORT_TYPE_IGNORECASE": "alfabetik, gözardı et",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "metinden liste yap",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "listeden metin yap",
                +	"LISTS_SPLIT_WITH_DELIMITER": "sınırlayıcı ile",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Her sınırlayıcıda kesen metinleri bir metin listesine ayır.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Bir sınırlayıcı tarafından kesilen metinlerin listesini bir metine ekle.",
                +	"LISTS_REVERSE_MESSAGE0": "%1 kalemlerini ters çevir.",
                +	"LISTS_REVERSE_TOOLTIP": "Bir listenin bir kopyasını tersine çevirin.",
                +	"ORDINAL_NUMBER_SUFFIX": "",
                +	"VARIABLES_GET_TOOLTIP": "Bu değişkenin değerini verir.",
                +	"VARIABLES_GET_CREATE_SET": "'set %1' oluştur",
                +	"VARIABLES_SET": "Atamak %1 e %2",
                +	"VARIABLES_SET_TOOLTIP": "Bu değişkeni girilen değere eşitler.",
                +	"VARIABLES_SET_CREATE_GET": "'get %1' oluştur",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFNORETURN_TITLE": "e",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "birşey yap",
                +	"PROCEDURES_BEFORE_PARAMS": "ile :",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "ile :",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Çıktı vermeyen bir fonksiyon yaratır .",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Bu işlevi açıkla...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29",
                +	"PROCEDURES_DEFRETURN_RETURN": "Geri dön",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Çıktı veren bir fonksiyon oluşturur.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "Eğer ifadelerine izin ver",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Uyarı: Bu fonksiyon yinelenen parametreler vardır.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Kullanıcı tanımlı fonksiyonu çalıştır '%1' .",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Subroutine",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Kullanıcı tanımlı fonksiyonu çalıştır '%1' ve çıktısını kullan .",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "girdiler",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Bu işlevin girdilerini ekleyin, çıkarın, ya da yeniden sıralayın.",
                +	"PROCEDURES_MUTATORARG_TITLE": "girdi adı:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "İşleve bir girdi ekleyin.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Fonksiyon tanımı vurgulamak",
                +	"PROCEDURES_CREATE_DO": "'%1' oluştur",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Eğer değer doğruysa, ikinci değere geri dön.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Uyarı: Bu blok yalnızca bir fonksiyon tanımı içinde kullanılır."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/uk.json b/blockly/webif/static/blockly/msg/json/uk.json
                new file mode 100644
                index 000000000..8ea4e52ed
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/uk.json
                @@ -0,0 +1,340 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Andriykopanytsia",
                +			"Base",
                +			"Igor Zavadsky",
                +			"Lxlalexlxl",
                +			"아라",
                +			"Visem",
                +			"Piramidion",
                +			"SimondR"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "елемент",
                +	"TODAY": "Сьогодні",
                +	"DUPLICATE_BLOCK": "Дублювати",
                +	"ADD_COMMENT": "Додати коментар",
                +	"REMOVE_COMMENT": "Видалити коментар",
                +	"EXTERNAL_INPUTS": "Зовнішні входи",
                +	"INLINE_INPUTS": "Вбудовані входи",
                +	"DELETE_BLOCK": "Видалити блок",
                +	"DELETE_X_BLOCKS": "Видалити %1 блоків",
                +	"DELETE_ALL_BLOCKS": "Вилучити всі блоки %1?",
                +	"CLEAN_UP": "Вирівняти блоки",
                +	"COLLAPSE_BLOCK": "Згорнути блок",
                +	"COLLAPSE_ALL": "Згорнути блоки",
                +	"EXPAND_BLOCK": "Розгорнути блок",
                +	"EXPAND_ALL": "Розгорнути блоки",
                +	"DISABLE_BLOCK": "Вимкнути блок",
                +	"ENABLE_BLOCK": "Увімкнути блок",
                +	"HELP": "Довідка",
                +	"UNDO": "Скасувати",
                +	"REDO": "Повторити",
                +	"CHANGE_VALUE_TITLE": "Змінити значення:",
                +	"RENAME_VARIABLE": "Перейменувати змінну...",
                +	"RENAME_VARIABLE_TITLE": "Перейменувати усі змінні \"%1\" до:",
                +	"NEW_VARIABLE": "Створити змінну...",
                +	"NEW_VARIABLE_TITLE": "Нова назва змінної:",
                +	"VARIABLE_ALREADY_EXISTS": "Змінна з назвою '%1' вже існує.",
                +	"PROCEDURE_ALREADY_EXISTS": "Процес з назвою '%1' вже існує.",
                +	"DELETE_VARIABLE_CONFIRMATION": "Вилучити %1 використання змінної '%2'?",
                +	"DELETE_VARIABLE": "Вилучити змінну '%1'",
                +	"COLOUR_PICKER_HELPURL": "https://uk.wikipedia.org/wiki/Колір",
                +	"COLOUR_PICKER_TOOLTIP": "Вибрати колір з палітри.",
                +	"COLOUR_RANDOM_TITLE": "випадковий колір",
                +	"COLOUR_RANDOM_TOOLTIP": "Вибрати колір навмання.",
                +	"COLOUR_RGB_HELPURL": "http://www.december.com/html/spec/colorper.html",
                +	"COLOUR_RGB_TITLE": "колір з",
                +	"COLOUR_RGB_RED": "червоний",
                +	"COLOUR_RGB_GREEN": "зелений",
                +	"COLOUR_RGB_BLUE": "синій",
                +	"COLOUR_RGB_TOOLTIP": "Створити колір зі вказаними рівнями червоного, зеленого та синього. Усі значення мають бути від 0 до 100.",
                +	"COLOUR_BLEND_HELPURL": "http://meyerweb.com/eric/tools/color-blend/",
                +	"COLOUR_BLEND_TITLE": "змішати",
                +	"COLOUR_BLEND_COLOUR1": "колір 1",
                +	"COLOUR_BLEND_COLOUR2": "колір 2",
                +	"COLOUR_BLEND_RATIO": "співвідношення",
                +	"COLOUR_BLEND_TOOLTIP": "Змішує два кольори разом у вказаному співвідношені (0.0 - 1.0).",
                +	"CONTROLS_REPEAT_HELPURL": "https://uk.wikipedia.org/wiki/Цикл_(програмування)#.D0.A6.D0.B8.D0.BA.D0.BB_.D0.B7_.D0.BB.D1.96.D1.87.D0.B8.D0.BB.D1.8C.D0.BD.D0.B8.D0.BA.D0.BE.D0.BC",
                +	"CONTROLS_REPEAT_TITLE": "повторити %1 разів",
                +	"CONTROLS_REPEAT_INPUT_DO": "виконати",
                +	"CONTROLS_REPEAT_TOOLTIP": "Виконати певні дії декілька разів.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "повторювати поки",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "повторювати, доки не",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Поки значення істинне, виконувати певні дії.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Поки значення хибне, виконувати певні дії.",
                +	"CONTROLS_FOR_TOOLTIP": "Наявна змінна \"%1\" набуває значень від початкового до кінцевого, враховуючи заданий інтервал, і виконуються вказані блоки.",
                +	"CONTROLS_FOR_TITLE": "рахувати з %1 від %2 до %3 через %4",
                +	"CONTROLS_FOREACH_TITLE": "для кожного елемента %1 у списку %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Для кожного елемента в списку змінна '%1' отримує значення елемента, а потім виконуються певні дії.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "перервати цикл",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "продовжити з наступної ітерації циклу",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Перервати виконання циклу.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Пропустити залишок цього циклу і перейти до виконання наступної ітерації.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Попередження: цей блок може бути використаний тільки в межах циклу.",
                +	"CONTROLS_IF_TOOLTIP_1": "Якщо значення істинне, то виконати певні дії.",
                +	"CONTROLS_IF_TOOLTIP_2": "Якщо значення істинне, то виконується перший блок операторів. В іншому випадку виконується другий блок операторів.",
                +	"CONTROLS_IF_TOOLTIP_3": "Якщо перше значення істинне, то виконується перший блок операторів. В іншому випадку, якщо друге значення істина, то виконується другий блок операторів.",
                +	"CONTROLS_IF_TOOLTIP_4": "Якщо перше значення істинне, то виконується перший блок операторів. В іншому випадку, якщо друге значення істинне, то виконується другий блок операторів. Якщо жодне із значень не є істинним, то виконується останній блок операторів.",
                +	"CONTROLS_IF_MSG_IF": "якщо",
                +	"CONTROLS_IF_MSG_ELSEIF": "інакше якщо",
                +	"CONTROLS_IF_MSG_ELSE": "інакше",
                +	"CONTROLS_IF_IF_TOOLTIP": "Додайте, вилучіть або змініть порядок секцій, щоб переналаштувати цей блок 'якщо'.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Додайте умову до блока 'якщо'.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Додати остаточну, всеосяжну умову до блоку 'якщо'.",
                +	"IOS_CANCEL": "Скасувати",
                +	"IOS_ERROR": "Помилка",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Додати змінну",
                +	"IOS_VARIABLES_ADD_BUTTON": "Додати",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Перейменувати",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Видалити",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Назва змінної",
                +	"LOGIC_COMPARE_HELPURL": "https://uk.wikipedia.org/wiki/Нерівність",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Повертає істину, якщо обидва входи рівні один одному.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Повертає істину, якщо обидва входи не дорівнюють один одному.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Повертає істину, якщо перше вхідне значення менше, ніж друге.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Повертає істину, якщо перше вхідне значення менше або дорівнює другому.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Повертає істину, якщо перше вхідне значення більше, ніж друге.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Повертає істину, якщо перше вхідне значення більше або дорівнює другому.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Повертає істину, якщо обидва входи істинні.",
                +	"LOGIC_OPERATION_AND": "та",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Повертає істину, якщо принаймні один з входів істинний.",
                +	"LOGIC_OPERATION_OR": "або",
                +	"LOGIC_NEGATE_TITLE": "не %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Повертає істину, якщо вхідне значення хибне. Повертає хибність, якщо вхідне значення істинне.",
                +	"LOGIC_BOOLEAN_TRUE": "істина",
                +	"LOGIC_BOOLEAN_FALSE": "хибність",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Повертає значення істина або хибність.",
                +	"LOGIC_NULL_HELPURL": "https://en.wikipedia.org/wiki/Nullable_type",
                +	"LOGIC_NULL": "ніщо",
                +	"LOGIC_NULL_TOOLTIP": "Повертає ніщо.",
                +	"LOGIC_TERNARY_HELPURL": "https://en.wikipedia.org/wiki/%3F:",
                +	"LOGIC_TERNARY_CONDITION": "тест",
                +	"LOGIC_TERNARY_IF_TRUE": "якщо істина",
                +	"LOGIC_TERNARY_IF_FALSE": "якщо хибність",
                +	"LOGIC_TERNARY_TOOLTIP": "Перевіряє умову в 'тест'. Якщо умова істинна, то повертає  значення 'якщо істина'; в іншому випадку повертає значення 'якщо хибність'.",
                +	"MATH_NUMBER_HELPURL": "https://uk.wikipedia.org/wiki/Число",
                +	"MATH_NUMBER_TOOLTIP": "Число.",
                +	"MATH_ARITHMETIC_HELPURL": "https://uk.wikipedia.org/wiki/Арифметика",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Повертає суму двох чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Повертає різницю двох чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Повертає добуток двох чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Повертає частку двох чисел.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Повертає перше число, піднесене до степеня, вираженого другим числом.",
                +	"MATH_SINGLE_HELPURL": "https://uk.wikipedia.org/wiki/Квадратний_корінь",
                +	"MATH_SINGLE_OP_ROOT": "квадратний корінь",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Повертає квадратний корінь з числа.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "модуль",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Повертає модуль числа.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Повертає протилежне число.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Повертає натуральний логарифм числа.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Повертає десятковий логарифм числа.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Повертає e у степені.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Повертає 10 у степені.",
                +	"MATH_TRIG_HELPURL": "https://uk.wikipedia.org/wiki/Тригонометричні_функції",
                +	"MATH_TRIG_TOOLTIP_SIN": "Повертає синус кута в градусах (не в радіанах).",
                +	"MATH_TRIG_TOOLTIP_COS": "Повертає косинус кута в градусах (не в радіанах).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Повертає тангенс кута в градусах (не в радіанах).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Повертає арксинус числа.",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Повертає арккосинус числа.",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Повертає арктангенс числа.",
                +	"MATH_CONSTANT_HELPURL": "https://uk.wikipedia.org/wiki/Математична_константа",
                +	"MATH_CONSTANT_TOOLTIP": "Повертає одну з поширених констант: π (3.141...), e (2.718...), φ (1,618...), sqrt(2) (1.414...), sqrt(½) (0.707...) або ∞ (нескінченність).",
                +	"MATH_IS_EVEN": "парне",
                +	"MATH_IS_ODD": "непарне",
                +	"MATH_IS_PRIME": "просте",
                +	"MATH_IS_WHOLE": "ціле",
                +	"MATH_IS_POSITIVE": "додатне",
                +	"MATH_IS_NEGATIVE": "від'ємне",
                +	"MATH_IS_DIVISIBLE_BY": "ділиться на",
                +	"MATH_IS_TOOLTIP": "Перевіряє, чи число парне, непарне, просте, ціле, додатне, від'ємне або чи воно ділиться на певне число без остачі. Повертає істину або хибність.",
                +	"MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter",
                +	"MATH_CHANGE_TITLE": "змінити %1 на %2",
                +	"MATH_CHANGE_TOOLTIP": "Додати число до змінної '%1'.",
                +	"MATH_ROUND_HELPURL": "https://uk.wikipedia.org/wiki/Округлення",
                +	"MATH_ROUND_TOOLTIP": "Округлення числа до більшого або до меншого.",
                +	"MATH_ROUND_OPERATOR_ROUND": "округлити",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "округлити до більшого",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "округлити до меншого",
                +	"MATH_ONLIST_HELPURL": "http://www.mapleprimes.com/questions/100441-Applying-Function-To-List-Of-Numbers",
                +	"MATH_ONLIST_OPERATOR_SUM": "сума списку",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Повертає суму всіх чисел у списку.",
                +	"MATH_ONLIST_OPERATOR_MIN": "мінімум списку",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Повертає найменше число у списку.",
                +	"MATH_ONLIST_OPERATOR_MAX": "максимум списку",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Повертає найбільше число у списку.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "середнє списку",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Повертає середнє (арифметичне) числових значень у списку.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "медіана списку",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Повертає медіану списку.",
                +	"MATH_ONLIST_OPERATOR_MODE": "моди списку",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Повертає перелік найпоширеніших елементів у списку.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "стандартне відхилення списку",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Повертає стандартне відхилення списку.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "випадковий елемент списку",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Повертає випадковий елемент зі списку.",
                +	"MATH_MODULO_HELPURL": "https://uk.wikipedia.org/wiki/Ділення_з_остачею",
                +	"MATH_MODULO_TITLE": "остача від %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Повертає остачу від ділення двох чисел.",
                +	"MATH_CONSTRAIN_TITLE": "обмежити %1 від %2 до %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Обмежує число вказаними межами (включно).",
                +	"MATH_RANDOM_INT_HELPURL": "https://uk.wikipedia.org/wiki/Генерація_випадкових_чисел",
                +	"MATH_RANDOM_INT_TITLE": "випадкове ціле число від %1 до %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Повертає випадкове ціле число між двома заданими межами включно.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://uk.wikipedia.org/wiki/Генерація_випадкових_чисел",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "випадковий дріб",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Повертає випадковий дріб від 0,0 (включно) та 1.0 (не включно).",
                +	"TEXT_TEXT_HELPURL": "https://uk.wikipedia.org/wiki/Рядок_(програмування)",
                +	"TEXT_TEXT_TOOLTIP": "Символ, слово або рядок тексту.",
                +	"TEXT_JOIN_HELPURL": "http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_8.html",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "створити текст з",
                +	"TEXT_JOIN_TOOLTIP": "Створити фрагмент тексту шляхом з'єднування будь-якого числа елементів.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "приєднати",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Додайте, вилучіть або змініть порядок секцій для переналаштування текстового блоку.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "Додати елемент до тексту.",
                +	"TEXT_APPEND_TOOLTIP": "Додати деякий текст до змінної '%1'.",
                +	"TEXT_LENGTH_TITLE": "довжина %1",
                +	"TEXT_LENGTH_TOOLTIP": "Повертає число символів (включно з пропусками) у даному тексті.",
                +	"TEXT_ISEMPTY_TITLE": "%1 є порожнім",
                +	"TEXT_ISEMPTY_TOOLTIP": "Повертає істину, якщо вказаний текст порожній.",
                +	"TEXT_INDEXOF_TOOLTIP": "Повертає індекс першого/останнього входження першого тексту в другий. Повертає %1, якщо текст не знайдено.",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "знайти перше входження тексту",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "знайти останнє входження тексту",
                +	"TEXT_CHARAT_HELPURL": "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm",
                +	"TEXT_CHARAT_FROM_START": "отримати символ #",
                +	"TEXT_CHARAT_FROM_END": "отримати символ # з кінця",
                +	"TEXT_CHARAT_FIRST": "отримати перший символ",
                +	"TEXT_CHARAT_LAST": "отримати останній символ",
                +	"TEXT_CHARAT_RANDOM": "отримати випадковий символ",
                +	"TEXT_CHARAT_TAIL": "-ий.",
                +	"TEXT_CHARAT_TOOLTIP": "Повертає символ у зазначеній позиції.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Повертає заданий фрагмент тексту.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "у тексті",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "отримати підрядок від символу #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "отримати підрядок від символу # з кінця",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "отримати підрядок від першого символу",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "до символу #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "до символу # з кінця",
                +	"TEXT_GET_SUBSTRING_END_LAST": "до останнього символу",
                +	"TEXT_GET_SUBSTRING_TAIL": "-ого.",
                +	"TEXT_CHANGECASE_TOOLTIP": "В іншому випадку повертає копію тексту.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "до ВЕРХНЬОГО регістру",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "до нижнього регістру",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "Великі Перші Букви",
                +	"TEXT_TRIM_TOOLTIP": "Повертає копію тексту з вилученими пропусками з одного або обох кінців.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "вилучити крайні пропуски з обох кінців",
                +	"TEXT_TRIM_OPERATOR_LEFT": "вилучити пропуски з лівого боку",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "вилучити пропуски з правого боку",
                +	"TEXT_PRINT_TITLE": "друк %1",
                +	"TEXT_PRINT_TOOLTIP": "Надрукувати заданий текст, числа або інші значення.",
                +	"TEXT_PROMPT_TYPE_TEXT": "запит тексту з повідомленням",
                +	"TEXT_PROMPT_TYPE_NUMBER": "запит числа з повідомленням",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Запитати у користувача число.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Запитати у користувача деякий текст.",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "створити порожній список",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Повертає список, довжиною 0, що не містить записів даних",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Створює список з будь-якою кількістю елементів.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "створити список з",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "список",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Додайте, вилучіть або змініть порядок секцій для переналаштування блока списку.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Додати елемент до списку.",
                +	"LISTS_REPEAT_TOOLTIP": "Створює список, що складається з заданого значення повтореного задану кількість разів.",
                +	"LISTS_REPEAT_TITLE": "створити список з елемента %1 повтореного %2 разів",
                +	"LISTS_LENGTH_TITLE": "довжина %1",
                +	"LISTS_LENGTH_TOOLTIP": "Повертає довжину списку.",
                +	"LISTS_ISEMPTY_TITLE": "%1 є порожнім",
                +	"LISTS_ISEMPTY_TOOLTIP": "Повертає істину, якщо список порожній.",
                +	"LISTS_INLIST": "у списку",
                +	"LISTS_INDEX_OF_FIRST": "знайти перше входження елемента",
                +	"LISTS_INDEX_OF_LAST": "знайти останнє входження елемента",
                +	"LISTS_INDEX_OF_TOOLTIP": "Повертає індекс першого/останнього входження елемента у списку. Повертає %1, якщо елемент не знайдено.",
                +	"LISTS_GET_INDEX_GET": "отримати",
                +	"LISTS_GET_INDEX_GET_REMOVE": "отримати і вилучити",
                +	"LISTS_GET_INDEX_REMOVE": "вилучити",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "# з кінця",
                +	"LISTS_GET_INDEX_FIRST": "перший",
                +	"LISTS_GET_INDEX_LAST": "останній",
                +	"LISTS_GET_INDEX_RANDOM": "випадковий",
                +	"LISTS_GET_INDEX_TAIL": "-ий.",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 - це перший елемент.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 - це останній елемент.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Повертає елемент у заданій позиції у списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Повертає перший елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Повертає останній елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Повертає випадковий елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Видаляє і повертає елемент у заданій позиції у списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Видаляє і повертає перший елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Видаляє і повертає останній елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Видаляє і повертає випадковий елемент списоку.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Вилучає зі списку елемент у вказаній позиції.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Вилучає перший елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Вилучає останній елемент списку.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Вилучає випадковий елемент списку.",
                +	"LISTS_SET_INDEX_SET": "встановити",
                +	"LISTS_SET_INDEX_INSERT": "вставити в",
                +	"LISTS_SET_INDEX_INPUT_TO": "як",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Задає елемент списку у вказаній позиції.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Задає перший елемент списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Задає останній елемент списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Задає випадковий елемент у списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Вставка елемента у вказану позицію списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Вставляє елемент на початок списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Додає елемент у кінці списку.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Випадковим чином вставляє елемент у список.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "отримати вкладений список з #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "отримати вкладений список від # з кінця",
                +	"LISTS_GET_SUBLIST_START_FIRST": "отримати вкладений список з першого",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "до #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "до # з кінця",
                +	"LISTS_GET_SUBLIST_END_LAST": "до останнього",
                +	"LISTS_GET_SUBLIST_TAIL": "символу.",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Створює копію вказаної частини списку.",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "сортувати %3 %1 %2",
                +	"LISTS_SORT_TOOLTIP": "Сортувати копію списку.",
                +	"LISTS_SORT_ORDER_ASCENDING": "за зростанням",
                +	"LISTS_SORT_ORDER_DESCENDING": "за спаданням",
                +	"LISTS_SORT_TYPE_NUMERIC": "як числа",
                +	"LISTS_SORT_TYPE_TEXT": "за абеткою",
                +	"LISTS_SORT_TYPE_IGNORECASE": "за абеткою, ігноруючи регістр",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "зробити з тексту список",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "зробити зі списку текст",
                +	"LISTS_SPLIT_WITH_DELIMITER": "з розділювачем",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Поділити текст на список текстів, розриваючи на кожному розділювачі.",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "Злити список текстів у єдиний текст, відокремивши розділювачами.",
                +	"ORDINAL_NUMBER_SUFFIX": "-ий.",
                +	"VARIABLES_GET_TOOLTIP": "Повертає значення цієї змінної.",
                +	"VARIABLES_GET_CREATE_SET": "Створити 'встановити %1'",
                +	"VARIABLES_SET": "встановити %1 до %2",
                +	"VARIABLES_SET_TOOLTIP": "Задає цю змінну рівною входу.",
                +	"VARIABLES_SET_CREATE_GET": "Створити 'отримати %1'",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://uk.wikipedia.org/wiki/Підпрограма",
                +	"PROCEDURES_DEFNORETURN_TITLE": "до",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "щось зробити",
                +	"PROCEDURES_BEFORE_PARAMS": "з:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "з:",
                +	"PROCEDURES_DEFNORETURN_DO": "блок тексту",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Створює функцію без виводу.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Опишіть цю функцію...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://uk.wikipedia.org/wiki/Підпрограма",
                +	"PROCEDURES_DEFRETURN_RETURN": "повернути",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Створює функцію з виводом.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "дозволити дії",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Увага: ця функція має дубльовані параметри.",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://uk.wikipedia.org/wiki/Підпрограма",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Запустити користувацьку функцію \"%1\".",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://uk.wikipedia.org/wiki/Підпрограма",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Запустити користувацьку функцію \"%1\" і використати її вивід.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "входи",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Додайте, вилучіть або змініть порядок вхідних параметрів для цієї функції.",
                +	"PROCEDURES_MUTATORARG_TITLE": "назва входу:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Додати до функції вхідні параметри.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Підсвітити визначення функції",
                +	"PROCEDURES_CREATE_DO": "Створити \"%1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Якщо значення істинне, то повернути друге значення.",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "Попередження: цей блок може використовуватися лише в межах визначення функції."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/vi.json b/blockly/webif/static/blockly/msg/json/vi.json
                new file mode 100644
                index 000000000..c0b9b7e6c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/vi.json
                @@ -0,0 +1,328 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Baonguyen21022003",
                +			"Espertus",
                +			"Qneutron",
                +			"Withoutaname",
                +			"Dstream",
                +			"Nguyenvanduocit"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "vật",
                +	"TODAY": "Hôm nay",
                +	"DUPLICATE_BLOCK": "Tạo Bản Sao",
                +	"ADD_COMMENT": "Thêm Chú Giải",
                +	"REMOVE_COMMENT": "Xóa Chú Giải",
                +	"EXTERNAL_INPUTS": "Chỗ Gắn Bên Ngoài",
                +	"INLINE_INPUTS": "Chỗ Gắn Cùng Dòng",
                +	"DELETE_BLOCK": "Xóa Mảnh Này",
                +	"DELETE_X_BLOCKS": "Xóa %1 Mảnh",
                +	"DELETE_ALL_BLOCKS": "Xóa hết %1 mảnh?",
                +	"COLLAPSE_BLOCK": "Thu Nhỏ Mảnh",
                +	"COLLAPSE_ALL": "Thu Nhỏ Mọi Mảnh",
                +	"EXPAND_BLOCK": "Mở Lớn Mảnh",
                +	"EXPAND_ALL": "Mở Lớn Mọi Mảnh",
                +	"DISABLE_BLOCK": "Ngưng Tác Dụng",
                +	"ENABLE_BLOCK": "Phục Hồi Tác Dụng",
                +	"HELP": "Trợ Giúp",
                +	"UNDO": "Hoàn tác",
                +	"REDO": "Làm lại",
                +	"CHANGE_VALUE_TITLE": "Thay giá trị thành:",
                +	"RENAME_VARIABLE": "Thay tên biến...",
                +	"RENAME_VARIABLE_TITLE": "Thay tên tất cả \"%1\" biến này thành:",
                +	"NEW_VARIABLE": "Tạo biến...",
                +	"NEW_VARIABLE_TITLE": "Tên của biến mới:",
                +	"VARIABLE_ALREADY_EXISTS": "Một biến có tên '%1' đã tồn tại.",
                +	"PROCEDURE_ALREADY_EXISTS": "Một hàm có tên '%1' đã tồn tại.",
                +	"COLOUR_PICKER_HELPURL": "https://vi.wikipedia.org/wiki/M%C3%A0u_s%E1%BA%AFc",
                +	"COLOUR_PICKER_TOOLTIP": "Chọn một màu từ bảng màu.",
                +	"COLOUR_RANDOM_TITLE": "màu bất kỳ",
                +	"COLOUR_RANDOM_TOOLTIP": "chọn một màu bất kỳ.",
                +	"COLOUR_RGB_TITLE": "tạo màu từ",
                +	"COLOUR_RGB_RED": "màu đỏ",
                +	"COLOUR_RGB_GREEN": "màu xanh lá cây",
                +	"COLOUR_RGB_BLUE": "màu xanh dương",
                +	"COLOUR_RGB_TOOLTIP": "Tạo màu từ ba màu: đỏ, xanh lá cây, xanh dương với số lượng cụ thể.  Mỗi số phải có giá trị từ 0 đến 100.",
                +	"COLOUR_BLEND_TITLE": "pha",
                +	"COLOUR_BLEND_COLOUR1": "màu 1",
                +	"COLOUR_BLEND_COLOUR2": "màu 2",
                +	"COLOUR_BLEND_RATIO": "tỉ lệ",
                +	"COLOUR_BLEND_TOOLTIP": "Pha hai màu với nhau theo tỉ lệ (0 - 100).",
                +	"CONTROLS_REPEAT_HELPURL": "https://en.wikipedia.org/wiki/For_loop",
                +	"CONTROLS_REPEAT_TITLE": "lặp lại %1 lần",
                +	"CONTROLS_REPEAT_INPUT_DO": "thực hiện",
                +	"CONTROLS_REPEAT_TOOLTIP": "Thực hiện các lệnh vài lần.",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "lặp lại trong khi",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "lặp lại cho đến khi",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Miễn là điều kiện còn đúng, thì thực hiện các lệnh.",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Miễn là điều kiện còn sai, thì thực hiện các lệnh.  Khi điều kiện đúng thì ngưng.",
                +	"CONTROLS_FOR_TOOLTIP": "Đếm từ số đầu đến số cuối. Khi đến mỗi số, gán số vào biến \"%1\" rồi thực hiện các lệnh.",
                +	"CONTROLS_FOR_TITLE": "đếm theo %1 từ %2 đến %3 mỗi lần thêm %4",
                +	"CONTROLS_FOREACH_TITLE": "với mỗi thành phần %1 trong danh sách %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "Trong một danh sách, lấy từng thành phần, gán vào biến \"%1\", rồi thực hiện một số lệnh.",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "thoát",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "sang lần lặp tiếp theo",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "Thoát khỏi vòng lặp hiện tại.",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "Bỏ qua phần còn lại trong vòng lặp này, và sang lần lặp tiếp theo.",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "Chú ý: Mảnh này chỉ có thế dùng trong các vòng lặp.",
                +	"CONTROLS_IF_TOOLTIP_1": "Nếu điều kiện đúng, thực hiện các lệnh.",
                +	"CONTROLS_IF_TOOLTIP_2": "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu sai, thực hiện các lệnh sau.",
                +	"CONTROLS_IF_TOOLTIP_3": "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu không, nếu điều kiện thứ hai đúng, thực hiện các lệnh thứ hai.",
                +	"CONTROLS_IF_TOOLTIP_4": "Nếu điều kiện đúng, thực hiện các lệnh đầu.  Nếu không, nếu điều kiện thứ hai đúng, thực hiện các lệnh thứ hai.  Nếu không điều kiện nào đúng, thực hiện các lệnh cuối cùng.",
                +	"CONTROLS_IF_MSG_IF": "nếu",
                +	"CONTROLS_IF_MSG_ELSEIF": "nếu không nếu",
                +	"CONTROLS_IF_MSG_ELSE": "nếu không",
                +	"CONTROLS_IF_IF_TOOLTIP": "Thêm, bỏ, hoặc đổi thứ tự các mảnh con để tạo cấu trúc mới cho mảnh nếu.",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "Thêm một điều kiện vào mảnh nếu.",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "Cuối cùng, khi không điều kiện nào đúng.",
                +	"IOS_CANCEL": "Hủy bỏ",
                +	"IOS_ERROR": "Lỗi",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "Hàm này có chứa các input trùng nhau.",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ Thêm biến",
                +	"IOS_VARIABLES_ADD_BUTTON": "Thêm",
                +	"IOS_VARIABLES_RENAME_BUTTON": "Đổi tên",
                +	"IOS_VARIABLES_DELETE_BUTTON": "Xóa",
                +	"IOS_VARIABLES_VARIABLE_NAME": "Tên biến",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "Bạn không thể không nhập tên biến.",
                +	"LOGIC_COMPARE_HELPURL": "https://vi.wikipedia.org/wiki/B%E1%BA%A5t_%C4%91%E1%BA%B3ng_th%E1%BB%A9c",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "Hoàn trả giá trị \"đúng\" (true) nếu giá trị hai đầu vào bằng nhau.",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "Hoàn trả giá trị \"đúng\" (true) nếu giá trị hai đầu vào không bằng nhau.",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất nhỏ hơn đầu vào thứ hai.",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất nhỏ hơn hoặc bằng đầu vào thứ hai.",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất lớn hơn đầu vào thứ hai.",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "Hoàn trả giá trị \"đúng\" (true) nếu đầu vào thứ nhất lớn hơn hoặc bằng đầu vào thứ hai.",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "Hoàn trả \"đúng\" (true) nếu cả hai đầu vào đều đúng.",
                +	"LOGIC_OPERATION_AND": "và",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "Hoàn trả \"đúng\" (true) nếu ít nhất một trong hai đầu vào đúng.",
                +	"LOGIC_OPERATION_OR": "hoặc",
                +	"LOGIC_NEGATE_TITLE": "không %1",
                +	"LOGIC_NEGATE_TOOLTIP": "Hoàn trả \"đúng\" (true) nếu đầu vào sai.  Hoàn trả \"sai\" (false) nếu đầu vào đúng.",
                +	"LOGIC_BOOLEAN_TRUE": "đúng",
                +	"LOGIC_BOOLEAN_FALSE": "sai",
                +	"LOGIC_BOOLEAN_TOOLTIP": "Hoàn trả \"đúng\" hoặc \"sai\".",
                +	"LOGIC_NULL": "trống không",
                +	"LOGIC_NULL_TOOLTIP": "Hoàn trả trống không.",
                +	"LOGIC_TERNARY_CONDITION": "kiểm tra",
                +	"LOGIC_TERNARY_IF_TRUE": "nếu đúng",
                +	"LOGIC_TERNARY_IF_FALSE": "nếu sai",
                +	"LOGIC_TERNARY_TOOLTIP": "Kiểm tra điều kiện. Nếu điều kiện đúng, hoàn trả giá trị từ mệnh đề \"nếu đúng\" nếu không đúng, hoàn trả giá trị từ mệnh đề \"nếu sai\".",
                +	"MATH_NUMBER_HELPURL": "https://vi.wikipedia.org/wiki/S%E1%BB%91",
                +	"MATH_NUMBER_TOOLTIP": "Một con số.",
                +	"MATH_ARITHMETIC_HELPURL": "https://vi.wikipedia.org/wiki/S%E1%BB%91_h%E1%BB%8Dc",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "Hoàn trả tổng của hai con số.",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "Hoàn trả hiệu của hai con số.",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "Hoàn trả tích của hai con số.",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "Hoàn trả thương của hai con số.",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "Hoàn trả số lũy thừa với số thứ nhất là cơ số và số thứ hai là số mũ.",
                +	"MATH_SINGLE_HELPURL": "https://vi.wikipedia.org/wiki/C%C4%83n_b%E1%BA%ADc_hai",
                +	"MATH_SINGLE_OP_ROOT": "căn bật hai",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "Hoàn trả căn bật hai của số đầu vào.",
                +	"MATH_SINGLE_OP_ABSOLUTE": "giá trị tuyệt đối",
                +	"MATH_SINGLE_TOOLTIP_ABS": "Hoàn trả giá trị tuyệt đối của số đầu vào.",
                +	"MATH_SINGLE_TOOLTIP_NEG": "Đổi dấu của số đầu vào: âm thành dương và dương thành âm, và hoàn trả số mới.",
                +	"MATH_SINGLE_TOOLTIP_LN": "Hoàn trả lôgarit tự nhiên của số đầu vào.",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "Hoàn trả lôgarit cơ số 10 của số đầu vào.",
                +	"MATH_SINGLE_TOOLTIP_EXP": "Hoàn trả lũy thừa của số e với số mũ đầu vào.",
                +	"MATH_SINGLE_TOOLTIP_POW10": "Hoàn trả lũy thừa của số 10 với số mũ đầu vào.",
                +	"MATH_TRIG_HELPURL": "https://vi.wikipedia.org/wiki/H%C3%A0m_l%C6%B0%E1%BB%A3ng_gi%C3%A1c",
                +	"MATH_TRIG_TOOLTIP_SIN": "Hoàn trả Sin của một góc (theo độ).",
                +	"MATH_TRIG_TOOLTIP_COS": "Hoàn trả Cos của một góc (theo độ).",
                +	"MATH_TRIG_TOOLTIP_TAN": "Hoàn trả Tang của một góc (theo độ).",
                +	"MATH_TRIG_TOOLTIP_ASIN": "Hoàn trả Arcsin của một góc (theo độ).",
                +	"MATH_TRIG_TOOLTIP_ACOS": "Hoàn trả Arccos của một góc (theo độ).",
                +	"MATH_TRIG_TOOLTIP_ATAN": "Hoàn trả Arctang của một góc (theo độ).",
                +	"MATH_CONSTANT_HELPURL": "https://en.wikipedia.org/wiki/Mathematical_constant",
                +	"MATH_CONSTANT_TOOLTIP": "Hoàn trả các đẳng số thường gặp: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (vô cực).",
                +	"MATH_IS_EVEN": "là số chẵn",
                +	"MATH_IS_ODD": "là số lẻ",
                +	"MATH_IS_PRIME": "là số nguyên tố",
                +	"MATH_IS_WHOLE": "là số nguyên",
                +	"MATH_IS_POSITIVE": "là số dương",
                +	"MATH_IS_NEGATIVE": "là số âm",
                +	"MATH_IS_DIVISIBLE_BY": "chia hết cho",
                +	"MATH_IS_TOOLTIP": "Kiểm tra con số xem nó có phải là số chẵn, lẻ, nguyên tố, nguyên, dương, âm,  hay xem nó có chia hết cho số đầu vào hay không.  Hoàn trả đúng hay sai.",
                +	"MATH_CHANGE_HELPURL": "https://vi.wikipedia.org/wiki/Ph%C3%A9p_c%E1%BB%99ng",
                +	"MATH_CHANGE_TITLE": "cộng vào %1 giá trị %2",
                +	"MATH_CHANGE_TOOLTIP": "Cộng số đầu vào vào biến \"%1\".",
                +	"MATH_ROUND_HELPURL": "https://en.wikipedia.org/wiki/Rounding",
                +	"MATH_ROUND_TOOLTIP": "Làm tròn lên hoặc tròn xuống số đầu vào.",
                +	"MATH_ROUND_OPERATOR_ROUND": "làm tròn",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "làm tròn lên",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "làm tròn xuống",
                +	"MATH_ONLIST_HELPURL": "",
                +	"MATH_ONLIST_OPERATOR_SUM": "tổng của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_SUM": "Hoàn trả tổng số của tất cả các số trong danh sách.",
                +	"MATH_ONLIST_OPERATOR_MIN": "số nhỏ nhất của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_MIN": "Hoàn trả số nhỏ nhất trong tất cả các số trong danh sách.",
                +	"MATH_ONLIST_OPERATOR_MAX": "số lớn nhât của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_MAX": "Hoàn trả số lớn nhất trong tất cả các số trong danh sách.",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "giá trị trung bình của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "Hoàn trả giá trị trung bình từ của danh sách số.",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "số trung vị của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "Hoàn trả số trung vị của danh sách số.",
                +	"MATH_ONLIST_OPERATOR_MODE": "các mode của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_MODE": "Hoàn trả các số có mặt nhiều nhất trong danh sách.",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "độ lệch chuẩn của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "Hoàn trả độ lệch chuẩn của danh sách số.",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "một số bất kỳ của một danh sách",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "Hoàn trả một số bất kỳ từ các số trong danh sách.",
                +	"MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation",
                +	"MATH_MODULO_TITLE": "số dư của %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "Chia số thứ nhất cho số thứ hai rồi hoàn trả số dư từ.",
                +	"MATH_CONSTRAIN_TITLE": "giới hạn %1 không dưới %2 không hơn %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "Giới hạn số đầu vào để không dưới số thứ nhất và không hơn số thứ hai.",
                +	"MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_INT_TITLE": "Một số nguyên bất kỳ từ %1 đến %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "Hoàn trả một số nguyên bất kỳ lớn hơn hoặc bằng số đầu và nhỏ hơn hoặc bằng số sau.",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "phân số bất kỳ",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "Hoàn trả một phân số bất kỳ không nhỏ hơn 0.0 và không lớn hơn 1.0.",
                +	"TEXT_TEXT_HELPURL": "https://en.wikipedia.org/wiki/string_(computer_science)",
                +	"TEXT_TEXT_TOOLTIP": "Một ký tự, một từ, hay một dòng.",
                +	"TEXT_JOIN_HELPURL": "",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "tạo văn bản từ",
                +	"TEXT_JOIN_TOOLTIP": "Tạo một văn bản từ các thành phần.",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "kết nối",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "Thêm, bỏ, hoặc sắp xếp lại các thành phần để tạo dựng mảnh văn bản này.",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "thêm vật mới vào văn bản.",
                +	"TEXT_APPEND_TOOLTIP": "Thêm một mảng văn bản vào biến \"%1\".",
                +	"TEXT_LENGTH_TITLE": "độ dài của %1",
                +	"TEXT_LENGTH_TOOLTIP": "Hoàn trả số lượng ký tự (kể cả khoảng trắng) trong văn bản đầu vào.",
                +	"TEXT_ISEMPTY_TITLE": "%1 trống không",
                +	"TEXT_ISEMPTY_TOOLTIP": "Hoàn trả “đúng nếu văn bản không có ký tự nào.",
                +	"TEXT_INDEXOF_TOOLTIP": "Hoàn trả vị trí xuất hiện đầu/cuối của văn bản thứ nhất trong văn bản thứ hai.  Nếu không tìm thấy thì hoàn trả số %1.",
                +	"TEXT_INDEXOF_TITLE": "trong văn bản %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "tìm sự có mặt đầu tiên của",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "tìm sự có mặt cuối cùng của",
                +	"TEXT_CHARAT_TITLE": "trong văn bản %1 %2",
                +	"TEXT_CHARAT_FROM_START": "lấy ký tự thứ",
                +	"TEXT_CHARAT_FROM_END": "lấy từ phía cuối, ký tự thứ",
                +	"TEXT_CHARAT_FIRST": "lấy ký tự đầu tiên",
                +	"TEXT_CHARAT_LAST": "lấy ký tự cuối cùng",
                +	"TEXT_CHARAT_RANDOM": "lấy ký tự bất kỳ",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "Hoàn trả ký tự ở vị trí đặt ra.",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "Hoàn trả một mảng ký tự ấn định từ trong văn bản.",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "trong văn bản",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "lấy từ ký tự thứ",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "lấy từ phía cuối, ký tự thứ",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "lấy từ ký tự đầu tiên",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "đến ký tự thứ",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "đến từ phía cuối, ký tự thứ",
                +	"TEXT_GET_SUBSTRING_END_LAST": "đến ký tự cuối cùng",
                +	"TEXT_GET_SUBSTRING_TAIL": "",
                +	"TEXT_CHANGECASE_TOOLTIP": "Hoàn trả văn bản sau khi chuyển đổi chữ in hoa hay thường.",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "thành CHỮ IN HOA",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "thành chữ thường",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "thành Chữ In Đầu Mỗi Từ",
                +	"TEXT_TRIM_TOOLTIP": "Hoàn trả bản sao của văn bản sau khi xóa khoảng trắng từ một hoặc hai bên.",
                +	"TEXT_TRIM_OPERATOR_BOTH": "cắt các không gian từ cả hai mặt của",
                +	"TEXT_TRIM_OPERATOR_LEFT": "cắt các không gian từ bên trái của",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "cắt các không gian từ bên phải của",
                +	"TEXT_PRINT_TITLE": "in lên màng hình %1",
                +	"TEXT_PRINT_TOOLTIP": "In ra màng hình một văn bản, con số, hay một giá trị đầu vào khác.",
                +	"TEXT_PROMPT_TYPE_TEXT": "Xin người dùng nhập vào văn bản với dòng hướng dẫn",
                +	"TEXT_PROMPT_TYPE_NUMBER": "Xin người dùng nhập vào con số với dòng hướng dẫn",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "Xin người dùng nhập vào một con số.",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "Xin người dùng nhập vào một văn bản.",
                +	"TEXT_COUNT_MESSAGE0": "đến %1 trong %2",
                +	"TEXT_COUNT_TOOLTIP": "Đếm số lần một đoạn văn bản xuất hiện trong một đoạn văn bản khác.",
                +	"TEXT_REPLACE_MESSAGE0": "thay thế %1 bằng %2 trong %3",
                +	"TEXT_REVERSE_MESSAGE0": "đảo ngược %1",
                +	"TEXT_REVERSE_TOOLTIP": "Đảo ngược thứ tự của các chữ cái trong văn bản.",
                +	"LISTS_CREATE_EMPTY_TITLE": "tạo danh sách trống",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "Hoàn trả một danh sách, với độ dài 0, không có thành tố nào cả",
                +	"LISTS_CREATE_WITH_TOOLTIP": "Tạo một danh sách bao gồm nhiều vậts, với một số lượng bất kỳ.",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "tạo danh sách gồm",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "danh sách",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Thêm, bỏ, hoặc sắp xếp lại các thành phần để tạo dựng mảnh danh sách này.",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Thêm vật vào danh sách.",
                +	"LISTS_REPEAT_TOOLTIP": "Tạo danh sách gồm một số lượng vật nhất định với mỗi vật đều giống nhau.",
                +	"LISTS_REPEAT_TITLE": "tạo danh sách gồm một vật %1 lặp lại %2 lần",
                +	"LISTS_LENGTH_TITLE": "độ dài của %1",
                +	"LISTS_LENGTH_TOOLTIP": "Hoàn trả độ dài của một danh sách.",
                +	"LISTS_ISEMPTY_TITLE": "%1 trống rỗng",
                +	"LISTS_ISEMPTY_TOOLTIP": "Hoàn trả “đúng\" nếu danh sách không có thành tử nào.",
                +	"LISTS_INLIST": "trong dánh sách",
                +	"LISTS_INDEX_OF_FIRST": "tìm sự có mặt đầu tiên của vật",
                +	"LISTS_INDEX_OF_LAST": "tìm sự có mặt cuối cùng của vật",
                +	"LISTS_INDEX_OF_TOOLTIP": "Hoàn trả vị trí xuất hiện đầu tiên/cuối cùng của vật trong danh sách. Nếu không tìm thấy thì hoàn trả số %1.",
                +	"LISTS_GET_INDEX_GET": "lấy thành tố",
                +	"LISTS_GET_INDEX_GET_REMOVE": "lấy và xóa thành tố",
                +	"LISTS_GET_INDEX_REMOVE": "xóa thành tố",
                +	"LISTS_GET_INDEX_FROM_START": "thứ",
                +	"LISTS_GET_INDEX_FROM_END": "(đếm từ cuối) thứ",
                +	"LISTS_GET_INDEX_FIRST": "đầu tiên",
                +	"LISTS_GET_INDEX_LAST": "cuối cùng",
                +	"LISTS_GET_INDEX_RANDOM": "bất kỳ",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 là thành tố đầu tiên.",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 là thành tố cuối cùng.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Hoàn trả thành tố trong danh sách ở vị trí ấn định.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Hoàn trả thành tố đầu tiên trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Hoàn trả thành tố cuối cùng trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Hoàn trả một thành tố bất kỳ trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Hoàn trả và xóa thành tố trong danh sách ở vị trí ấn định.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Hoàn trả và xóa thành tố đầu tiên trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Hoàn trả và xóa thành tố cuối cùng trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Hoàn trả và xóa mộtthành tố bất kỳ trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Xóa thành tố trong danh sách ở vị trí ấn định.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Xóa thành tố đầu tiên trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Xóa thành tố cuối cùng trong danh sách.",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Xóa thành tố bất kỳ trong danh sách.",
                +	"LISTS_SET_INDEX_SET": "đặt",
                +	"LISTS_SET_INDEX_INSERT": "chèn vào vị trí",
                +	"LISTS_SET_INDEX_INPUT_TO": "giá trị",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "Đặt giá trị của thành tố ở vị trí ấn định trong một danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Đặt giá trị của thành tố đầu tiên trong danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Đặt giá trị của thành tố cuối cùng trong danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Đặt giá trị của thành tố ngẫu nhiên trong danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Chèn vật vào danh sách theo vị trí ấn định.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Chèn vật vào đầu danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Gắn thêm vật vào cuối danh sách.",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Gắn chèn vật vào danh sách ở vị trí ngẫu nhiên.",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "lấy một danh sách con từ vị trí thứ",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "lấy một danh sách con từ (đếm từ cuối) từ vị trí thứ",
                +	"LISTS_GET_SUBLIST_START_FIRST": "lấy một danh sách con từ đầu tiên",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "đến thứ",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "đến (đếm từ cuối) thứ",
                +	"LISTS_GET_SUBLIST_END_LAST": "đến cuối cùng",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "Lấy một mảng của danh sách này để tạo danh sách con.",
                +	"LISTS_SORT_TITLE": "sắp xếp %1 %2 %3",
                +	"LISTS_SORT_ORDER_ASCENDING": "tăng dần",
                +	"LISTS_SORT_ORDER_DESCENDING": "giảm dần",
                +	"LISTS_SORT_TYPE_NUMERIC": "số",
                +	"LISTS_SORT_TYPE_TEXT": "chữ cái",
                +	"LISTS_SORT_TYPE_IGNORECASE": "chữ cái, không phân biệt hoa/thường",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "tạo danh sách từ văn bản",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "tạo văn bản từ danh sách",
                +	"LISTS_SPLIT_WITH_DELIMITER": "với ký tự phân cách",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "Tách văn bản thành một danh sách các văn bản nhỏ, ngắt bởi các ký tự phân cách.",
                +	"LISTS_REVERSE_MESSAGE0": "đảo ngược %1",
                +	"VARIABLES_GET_TOOLTIP": "Hoàn trả giá trị của.",
                +	"VARIABLES_GET_CREATE_SET": "Tạo mảnh \"đặt vào %1\"",
                +	"VARIABLES_SET": "cho %1 bằng %2",
                +	"VARIABLES_SET_TOOLTIP": "Đặt giá trị của biến này thành...",
                +	"VARIABLES_SET_CREATE_GET": "Tạo mảnh \"lấy %1\"",
                +	"PROCEDURES_DEFNORETURN_TITLE": "thủ tục để",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "làm gì đó",
                +	"PROCEDURES_BEFORE_PARAMS": "với:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "với:",
                +	"PROCEDURES_DEFNORETURN_DO": "",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "Một thủ tục không có giá trị hoàn trả.",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "Mô tả hàm này...",
                +	"PROCEDURES_DEFRETURN_RETURN": "hoàn trả",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "Một thủ tục có giá trị hoàn trả.",
                +	"PROCEDURES_ALLOW_STATEMENTS": "cho phép báo cáo",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "Chú ý: Thủ tục này có lặp lại tên các tham số.",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "Chạy một thủ tục không có giá trị hoàn trả.",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "Chạy một thủ tục có giá trị hoàn trả.",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "các tham số",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Thêm, xóa hoặc sắp xếp lại các đầu vào cho hàm này.",
                +	"PROCEDURES_MUTATORARG_TITLE": "biến:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "Thêm một đầu vào cho hàm.",
                +	"PROCEDURES_HIGHLIGHT_DEF": "Làm nổi bật thủ tục",
                +	"PROCEDURES_CREATE_DO": "Tạo mảnh \"thực hiện %1\"",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "Khi điều kiện đúng thì hoàn trả một giá trị.",
                +	"PROCEDURES_IFRETURN_WARNING": "Chú ý: Mảnh này chỉ có thể dùng trong một thủ tục."
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/zh-hans.json b/blockly/webif/static/blockly/msg/json/zh-hans.json
                new file mode 100644
                index 000000000..c33c82eb5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/zh-hans.json
                @@ -0,0 +1,363 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Espertus",
                +			"Liuxinyu970226",
                +			"Luotiancheng",
                +			"Qiyue2001",
                +			"Xiaomingyan",
                +			"Yfdyh000",
                +			"아라",
                +			"Hudafu",
                +			"Shatteredwind",
                +			"Duzc2",
                +			"Tonylianlong"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "项目",
                +	"TODAY": "今天",
                +	"DUPLICATE_BLOCK": "复制",
                +	"ADD_COMMENT": "添加注释",
                +	"REMOVE_COMMENT": "删除注释",
                +	"EXTERNAL_INPUTS": "外部输入",
                +	"INLINE_INPUTS": "单行输入",
                +	"DELETE_BLOCK": "删除块",
                +	"DELETE_X_BLOCKS": "删除 %1 块",
                +	"DELETE_ALL_BLOCKS": "删除所有%1块吗?",
                +	"CLEAN_UP": "整理块",
                +	"COLLAPSE_BLOCK": "折叠块",
                +	"COLLAPSE_ALL": "折叠块",
                +	"EXPAND_BLOCK": "展开块",
                +	"EXPAND_ALL": "展开块",
                +	"DISABLE_BLOCK": "禁用块",
                +	"ENABLE_BLOCK": "启用块",
                +	"HELP": "帮助",
                +	"UNDO": "撤销",
                +	"REDO": "重做",
                +	"CHANGE_VALUE_TITLE": "更改值:",
                +	"RENAME_VARIABLE": "重命名变量...",
                +	"RENAME_VARIABLE_TITLE": "将所有“%1”变量重命名为:",
                +	"NEW_VARIABLE": "创建变量...",
                +	"NEW_VARIABLE_TITLE": "新变量的名称:",
                +	"VARIABLE_ALREADY_EXISTS": "已存在名为“%1”的变量。",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "名叫“%1”的变量已存在,但作为另一个变量类型“%2”存在。",
                +	"PROCEDURE_ALREADY_EXISTS": "已存在名为“%1”的步骤。",
                +	"DELETE_VARIABLE_CONFIRMATION": "删除“%2”变量的%1用途么?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "不能删除变量“%1”,因为它是功能“%2”定义的一部分",
                +	"DELETE_VARIABLE": "删除“%1”变量",
                +	"COLOUR_PICKER_HELPURL": "https://zh.wikipedia.org/wiki/颜色",
                +	"COLOUR_PICKER_TOOLTIP": "从调色板中选择一种颜色。",
                +	"COLOUR_RANDOM_TITLE": "随机颜色",
                +	"COLOUR_RANDOM_TOOLTIP": "随机选择一种颜色。",
                +	"COLOUR_RGB_TITLE": "颜色",
                +	"COLOUR_RGB_RED": "红色",
                +	"COLOUR_RGB_GREEN": "绿色",
                +	"COLOUR_RGB_BLUE": "蓝色",
                +	"COLOUR_RGB_TOOLTIP": "通过指定红色、绿色和蓝色的量创建一种颜色。所有的值必须在0和100之间。",
                +	"COLOUR_BLEND_TITLE": "混合",
                +	"COLOUR_BLEND_COLOUR1": "颜色1",
                +	"COLOUR_BLEND_COLOUR2": "颜色2",
                +	"COLOUR_BLEND_RATIO": "比例",
                +	"COLOUR_BLEND_TOOLTIP": "用一个给定的比率(0.0-1.0)混合两种颜色。",
                +	"CONTROLS_REPEAT_HELPURL": "https://zh.wikipedia.org/wiki/For循环",
                +	"CONTROLS_REPEAT_TITLE": "重复 %1 次",
                +	"CONTROLS_REPEAT_INPUT_DO": "执行",
                +	"CONTROLS_REPEAT_TOOLTIP": "多次执行一些语句。",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "重复当",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "重复直到",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "只要值为真,执行一些语句。",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "只要值为假,执行一些语句。",
                +	"CONTROLS_FOR_TOOLTIP": "从起始数到结尾数中取出变量“%1”的值,按指定的时间间隔,执行指定的块。",
                +	"CONTROLS_FOR_TITLE": "使用 %1 从范围 %2 到 %3 每隔 %4",
                +	"CONTROLS_FOREACH_TITLE": "为每个项目 %1 在列表中 %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "遍历每个列表中的项目,将变量“%1”设定到该项中,然后执行某些语句。",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "中断循环",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "继续下一次循环",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "中断包含它的循环。",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "跳过这个循环的剩余部分,并继续下一次迭代。",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "警告:此块仅可用于在一个循环内。",
                +	"CONTROLS_IF_TOOLTIP_1": "如果值为真,执行一些语句。",
                +	"CONTROLS_IF_TOOLTIP_2": "如果值为真,则执行第一块语句。否则,则执行第二块语句。",
                +	"CONTROLS_IF_TOOLTIP_3": "如果第一个值为真,则执行第一块的语句。否则,如果第二个值为真,则执行第二块的语句。",
                +	"CONTROLS_IF_TOOLTIP_4": "如果第一个值为真,则执行第一块对语句。否则,如果第二个值为真,则执行语句的第二块。如果没有值为真,则执行最后一块的语句。",
                +	"CONTROLS_IF_MSG_IF": "如果",
                +	"CONTROLS_IF_MSG_ELSEIF": "否则如果",
                +	"CONTROLS_IF_MSG_ELSE": "否则",
                +	"CONTROLS_IF_IF_TOOLTIP": "增加、删除或重新排列各节来重新配置“if”块。",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "在if语句块中增加一个条件。",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "添加一个最终的,包括所有情况的节到if块中。",
                +	"IOS_OK": "确定",
                +	"IOS_CANCEL": "取消",
                +	"IOS_ERROR": "错误",
                +	"IOS_PROCEDURES_INPUTS": "输入",
                +	"IOS_PROCEDURES_ADD_INPUT": "+添加输入",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "允许声明",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "此功能有重复输入内容。",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+添加变量",
                +	"IOS_VARIABLES_ADD_BUTTON": "添加",
                +	"IOS_VARIABLES_RENAME_BUTTON": "重命名",
                +	"IOS_VARIABLES_DELETE_BUTTON": "删除",
                +	"IOS_VARIABLES_VARIABLE_NAME": "变量名称",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "您不能使用空变量名称。",
                +	"LOGIC_COMPARE_HELPURL": "https://zh.wikipedia.org/wiki/不等",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "如果两个输入结果相等,则返回真。",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "如果两个输入结果不相等,则返回真。",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "如果第一个输入结果比第二个小,则返回真。",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "如果第一个输入结果小于或等于第二个输入结果,则返回真。",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "如果第一个输入结果比第二个大,则返回真。",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "如果第一个输入结果大于或等于第二个输入结果,则返回真。",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "如果两个输入结果都为真,则返回真。",
                +	"LOGIC_OPERATION_AND": "和",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "如果至少有一个输入结果为真,则返回真。",
                +	"LOGIC_OPERATION_OR": "或",
                +	"LOGIC_NEGATE_HELPURL": "https://github.com/google/blockly/wiki/Logic#not",
                +	"LOGIC_NEGATE_TITLE": "非%1",
                +	"LOGIC_NEGATE_TOOLTIP": "如果输入结果为假,则返回真;如果输入结果为真,则返回假。",
                +	"LOGIC_BOOLEAN_TRUE": "真",
                +	"LOGIC_BOOLEAN_FALSE": "假",
                +	"LOGIC_BOOLEAN_TOOLTIP": "返回真或假。",
                +	"LOGIC_NULL": "空",
                +	"LOGIC_NULL_TOOLTIP": "返回空值。",
                +	"LOGIC_TERNARY_HELPURL": "https://zh.wikipedia.org/wiki/条件运算符",
                +	"LOGIC_TERNARY_CONDITION": "测试",
                +	"LOGIC_TERNARY_IF_TRUE": "如果为真",
                +	"LOGIC_TERNARY_IF_FALSE": "如果为假",
                +	"LOGIC_TERNARY_TOOLTIP": "检查“test”中的条件。如果条件为真,则返回“if true”的值,否则,则返回“if false”的值。",
                +	"MATH_NUMBER_HELPURL": "https://zh.wikipedia.org/wiki/数",
                +	"MATH_NUMBER_TOOLTIP": "一个数字。",
                +	"MATH_ARITHMETIC_HELPURL": "https://zh.wikipedia.org/wiki/算术",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "返回两个数字的和。",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "返回两个数字的区别。",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "返回两个数字的乘积。",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "返回两个数字的商。",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "返回第一个数的第二个数次幂。",
                +	"MATH_SINGLE_HELPURL": "https://zh.wikipedia.org/wiki/平方根",
                +	"MATH_SINGLE_OP_ROOT": "平方根",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "返回一个数的平方根。",
                +	"MATH_SINGLE_OP_ABSOLUTE": "绝对",
                +	"MATH_SINGLE_TOOLTIP_ABS": "返回一个数的绝对值。",
                +	"MATH_SINGLE_TOOLTIP_NEG": "返回一个数的逻辑非。",
                +	"MATH_SINGLE_TOOLTIP_LN": "返回一个数的自然对数。",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "返回一个数的对数。",
                +	"MATH_SINGLE_TOOLTIP_EXP": "返回一个数的e次幂。",
                +	"MATH_SINGLE_TOOLTIP_POW10": "返回一个数的10次幂。",
                +	"MATH_TRIG_HELPURL": "https://zh.wikipedia.org/wiki/三角函数",
                +	"MATH_TRIG_TOOLTIP_SIN": "返回指定角度的正弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_COS": "返回指定角度的余弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_TAN": "返回指定角度的正切值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_ASIN": "返回一个数的反正弦值。",
                +	"MATH_TRIG_TOOLTIP_ACOS": "返回一个数的反余弦值。",
                +	"MATH_TRIG_TOOLTIP_ATAN": "返回指定角度的反正切值。",
                +	"MATH_CONSTANT_HELPURL": "https://zh.wikipedia.org/wiki/数学常数",
                +	"MATH_CONSTANT_TOOLTIP": "返回一个常见常量:π (3.141…)、e (2.718…)、φ (1.618…)、平方根 (1.414…)、开平方根 (0.707…)或∞ (infinity)。",
                +	"MATH_IS_EVEN": "是偶数",
                +	"MATH_IS_ODD": "是奇数",
                +	"MATH_IS_PRIME": "是质数",
                +	"MATH_IS_WHOLE": "为整数",
                +	"MATH_IS_POSITIVE": "为正",
                +	"MATH_IS_NEGATIVE": "为负",
                +	"MATH_IS_DIVISIBLE_BY": "可被整除",
                +	"MATH_IS_TOOLTIP": "如果数字是偶数、奇数、非负整数、正数、负数或如果它可被某数字整除,则返回真或假。",
                +	"MATH_CHANGE_HELPURL": "https://zh.wikipedia.org/wiki/加法",
                +	"MATH_CHANGE_TITLE": "更改 %1 从 %2",
                +	"MATH_CHANGE_TOOLTIP": "将一个数添加到变量“%1”。",
                +	"MATH_ROUND_HELPURL": "https://zh.wikipedia.org/wiki/数值修约",
                +	"MATH_ROUND_TOOLTIP": "数字向上或向下舍入。",
                +	"MATH_ROUND_OPERATOR_ROUND": "向下舍入",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "向上舍入",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "向下舍入",
                +	"MATH_ONLIST_OPERATOR_SUM": "列表中的数的总和",
                +	"MATH_ONLIST_TOOLTIP_SUM": "返回列表中的所有数字的和。",
                +	"MATH_ONLIST_OPERATOR_MIN": "列表中的最小值",
                +	"MATH_ONLIST_TOOLTIP_MIN": "返回列表中最小数。",
                +	"MATH_ONLIST_OPERATOR_MAX": "列表中的最大值",
                +	"MATH_ONLIST_TOOLTIP_MAX": "返回列表中最大数。",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "列表中的平均数",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "返回列表中的数值的平均值。",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "列表中位数",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "返回列表中的中位数。",
                +	"MATH_ONLIST_OPERATOR_MODE": "列表模式",
                +	"MATH_ONLIST_TOOLTIP_MODE": "返回列表中的最常见的项的列表。",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "列表中的标准差",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "返回列表的标准偏差。",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "列表的随机项",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "从列表中返回一个随机的元素。",
                +	"MATH_MODULO_HELPURL": "https://zh.wikipedia.org/wiki/模除",
                +	"MATH_MODULO_TITLE": "取余数自 %1 ÷ %2",
                +	"MATH_MODULO_TOOLTIP": "返回这两个数字相除后的余数。",
                +	"MATH_CONSTRAIN_TITLE": "限制数字 %1 介于 (低) %2 到 (高) %3",
                +	"MATH_CONSTRAIN_TOOLTIP": "限制数字介于两个指定的数字之间",
                +	"MATH_RANDOM_INT_HELPURL": "https://zh.wikipedia.org/wiki/随机数生成器",
                +	"MATH_RANDOM_INT_TITLE": "从 %1 到 %2 之间的随机整数",
                +	"MATH_RANDOM_INT_TOOLTIP": "返回两个指定的范围(含)之间的随机整数。",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://zh.wikipedia.org/wiki/随机数生成器",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "随机分数",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "返回介于(包含)0.0到1.0之间的随机数。",
                +	"TEXT_TEXT_HELPURL": "https://zh.wikipedia.org/wiki/字符串",
                +	"TEXT_TEXT_TOOLTIP": "一个字母、单词或一行文本。",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "建立字串使用",
                +	"TEXT_JOIN_TOOLTIP": "通过串起任意数量的项以建立一段文字。",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "加入",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "添加、移除或重新排列各节来重新配置这个文本块。",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "将一个项添加到文本中。",
                +	"TEXT_APPEND_TITLE": "至%1附加文本%2",
                +	"TEXT_APPEND_TOOLTIP": "将一些文本追加到变量“%1”。",
                +	"TEXT_LENGTH_TITLE": "%1的长度",
                +	"TEXT_LENGTH_TOOLTIP": "返回提供文本的字母数(包括空格)。",
                +	"TEXT_ISEMPTY_TITLE": "%1是空的",
                +	"TEXT_ISEMPTY_TOOLTIP": "如果提供的文本为空,则返回真。",
                +	"TEXT_INDEXOF_TOOLTIP": "返回在第二个字串中的第一/最后一个匹配项的索引值。如果未找到则返回%1。",
                +	"TEXT_INDEXOF_TITLE": "在文本%1 %2 %3中",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "寻找第一个出现的文本",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "寻找最后一个出现的文本",
                +	"TEXT_CHARAT_TITLE": "在文本%1 %2中",
                +	"TEXT_CHARAT_FROM_START": "获得字符#",
                +	"TEXT_CHARAT_FROM_END": "获得倒数第#个字符",
                +	"TEXT_CHARAT_FIRST": "获得第一个字符",
                +	"TEXT_CHARAT_LAST": "获得最后一个字符",
                +	"TEXT_CHARAT_RANDOM": "获取随机的字母",
                +	"TEXT_CHARAT_TAIL": "空白",
                +	"TEXT_CHARAT_TOOLTIP": "返回位于指定位置的字母。",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "返回指定的部分文本。",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "自文本",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "取得一段字串自#",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "取得一段字串自倒数第#个字符",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "取得一段字串自第一个字符",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "到字符#",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "到倒数第#个字符",
                +	"TEXT_GET_SUBSTRING_END_LAST": "到最后一个字符",
                +	"TEXT_GET_SUBSTRING_TAIL": "空白",
                +	"TEXT_CHANGECASE_TOOLTIP": "在不同大小写下复制并返回这段文字。",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "转为大写",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "转为小写",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "将首字母大写",
                +	"TEXT_TRIM_TOOLTIP": "复制这段文字的同时删除两端多余的空格。",
                +	"TEXT_TRIM_OPERATOR_BOTH": "消除两侧空格",
                +	"TEXT_TRIM_OPERATOR_LEFT": "消除左侧空格",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "消除右侧空格",
                +	"TEXT_PRINT_TITLE": "打印%1",
                +	"TEXT_PRINT_TOOLTIP": "打印指定的文字、数字或其他值。",
                +	"TEXT_PROMPT_TYPE_TEXT": "输入数字并显示提示消息",
                +	"TEXT_PROMPT_TYPE_NUMBER": "输入数字并显示提示消息",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "提示用户输入数字。",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "提示用户输入一些文本。",
                +	"TEXT_COUNT_MESSAGE0": "将%1计算在%2之内",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "计算在一些其他文本中,部分文本重现了多少次。",
                +	"TEXT_REPLACE_MESSAGE0": "在%3中,将%1替换为%2",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "在某些其他文本中,替换部分文本的所有事件。",
                +	"TEXT_REVERSE_MESSAGE0": "倒转%1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "倒转文本中字符的排序。",
                +	"LISTS_CREATE_EMPTY_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-empty-list",
                +	"LISTS_CREATE_EMPTY_TITLE": "创建空列表",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "返回一个列表,长度为 0,不包含任何数据记录",
                +	"LISTS_CREATE_WITH_HELPURL": "https://github.com/google/blockly/wiki/Lists#create-list-with",
                +	"LISTS_CREATE_WITH_TOOLTIP": "建立一个具有任意数量项目的列表。",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "建立列表使用",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "列表",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "增加、删除或重新排列各部分以此重新配置这个列表块。",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "将一个项添加到列表中。",
                +	"LISTS_REPEAT_TOOLTIP": "建立包含指定重复次数的值的列表。",
                +	"LISTS_REPEAT_TITLE": "建立列表使用项 %1 重复 %2 次",
                +	"LISTS_LENGTH_TITLE": "%1的长度",
                +	"LISTS_LENGTH_TOOLTIP": "返回列表的长度。",
                +	"LISTS_ISEMPTY_TITLE": "%1是空的",
                +	"LISTS_ISEMPTY_TOOLTIP": "如果改列表为空,则返回真。",
                +	"LISTS_INLIST": "在列表中",
                +	"LISTS_INDEX_OF_FIRST": "找出第一个项出现",
                +	"LISTS_INDEX_OF_LAST": "找出最后一个项出现",
                +	"LISTS_INDEX_OF_TOOLTIP": "返回在列表中的第一/最后一个匹配项的索引值。如果找不到项目则返回%1。",
                +	"LISTS_GET_INDEX_GET": "取得",
                +	"LISTS_GET_INDEX_GET_REMOVE": "取出并移除",
                +	"LISTS_GET_INDEX_REMOVE": "移除",
                +	"LISTS_GET_INDEX_FROM_START": "#",
                +	"LISTS_GET_INDEX_FROM_END": "倒数第#",
                +	"LISTS_GET_INDEX_FIRST": "第一",
                +	"LISTS_GET_INDEX_LAST": "最后",
                +	"LISTS_GET_INDEX_RANDOM": "随机",
                +	"LISTS_GET_INDEX_TAIL": "空白",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1是第一个项目。",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1是最后一项。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "返回在列表中的指定位置的项。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "返回列表中的第一个项目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "返回列表中的最后一项。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "随机返回列表中的一个项目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "移除并返回列表中的指定位置的项。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "移除并返回列表中的第一个项目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "移除并返回列表中的最后一个项目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "移除并返回列表中的一个随机项目中。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "移除在列表中的指定位置的项。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "移除列表中的第一项",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "移除列表中的最后一项",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "删除列表中的一个随机的项。",
                +	"LISTS_SET_INDEX_SET": "设置",
                +	"LISTS_SET_INDEX_INSERT": "插入在",
                +	"LISTS_SET_INDEX_INPUT_TO": "为",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "设置在列表中指定位置的项。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "设置列表中的第一个项目。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "设置列表中的最后一项。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "设置列表中一个随机的项目。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "插入在列表中指定位置的项。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "在列表的起始处添加该项。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "将该项追加到列表的末尾。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "在列表中随机插入项。",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "从#取得子列表",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "从倒数#取得子列表",
                +	"LISTS_GET_SUBLIST_START_FIRST": "从头获得子列表",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "到#",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "到倒数第#",
                +	"LISTS_GET_SUBLIST_END_LAST": "到最后",
                +	"LISTS_GET_SUBLIST_TAIL": "空白",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "复制列表中指定的部分。",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "排序%1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "排序一个列表的拷贝。",
                +	"LISTS_SORT_ORDER_ASCENDING": "升序",
                +	"LISTS_SORT_ORDER_DESCENDING": "降序",
                +	"LISTS_SORT_TYPE_NUMERIC": "按数字排序",
                +	"LISTS_SORT_TYPE_TEXT": "按字母排序",
                +	"LISTS_SORT_TYPE_IGNORECASE": "按字母排序,忽略大小写",
                +	"LISTS_SPLIT_HELPURL": "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "从文本制作列表",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "从列表拆出文本",
                +	"LISTS_SPLIT_WITH_DELIMITER": "用分隔符",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "拆分文本到文本列表,按每个分隔符拆分。",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "加入文本列表至一个文本,由分隔符分隔。",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "倒转%1",
                +	"LISTS_REVERSE_TOOLTIP": "倒转一个列表的拷贝。",
                +	"ORDINAL_NUMBER_SUFFIX": "空白",
                +	"VARIABLES_GET_TOOLTIP": "返回此变量的值。",
                +	"VARIABLES_GET_CREATE_SET": "创建“设定%1”",
                +	"VARIABLES_SET": "赋值 %1 到 %2",
                +	"VARIABLES_SET_TOOLTIP": "设置此变量,以使它和输入值相等。",
                +	"VARIABLES_SET_CREATE_GET": "创建“获得%1”",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程序",
                +	"PROCEDURES_DEFNORETURN_TITLE": "至",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "做点什么",
                +	"PROCEDURES_BEFORE_PARAMS": "与:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "与:",
                +	"PROCEDURES_DEFNORETURN_DO": "空白",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "创建一个不带输出值的函数。",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "描述该功能...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程序",
                +	"PROCEDURES_DEFRETURN_RETURN": "返回",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "创建一个有输出值的函数。",
                +	"PROCEDURES_ALLOW_STATEMENTS": "允许声明",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "警告: 此函数具有重复参数。",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程序",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "运行用户定义的函数“%1”。",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程序",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "运行用户定义的函数“%1”,并使用它的输出值。",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "输入",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "添加、删除或重新排此函数的输入。",
                +	"PROCEDURES_MUTATORARG_TITLE": "输入名称:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "添加函数输入。",
                +	"PROCEDURES_HIGHLIGHT_DEF": "突出显示函数定义",
                +	"PROCEDURES_CREATE_DO": "创建“%1”",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "如果值为真,则返回第二个值。",
                +	"PROCEDURES_IFRETURN_HELPURL": "http://c2.com/cgi/wiki?GuardClause",
                +	"PROCEDURES_IFRETURN_WARNING": "警告: 仅在定义函数内可使用此块。"
                +}
                diff --git a/blockly/webif/static/blockly/msg/json/zh-hant.json b/blockly/webif/static/blockly/msg/json/zh-hant.json
                new file mode 100644
                index 000000000..dba798c0a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/json/zh-hant.json
                @@ -0,0 +1,350 @@
                +{
                +	"@metadata": {
                +		"authors": [
                +			"Gasolin",
                +			"Wehwei",
                +			"Liuxinyu970226",
                +			"LNDDYL",
                +			"Cwlin0416",
                +			"Kasimtan",
                +			"Kly",
                +			"Dnowba",
                +			"Dnow"
                +		]
                +	},
                +	"VARIABLES_DEFAULT_NAME": "變數",
                +	"TODAY": "今天",
                +	"DUPLICATE_BLOCK": "複製",
                +	"ADD_COMMENT": "加入註解",
                +	"REMOVE_COMMENT": "移除註解",
                +	"EXTERNAL_INPUTS": "多行輸入",
                +	"INLINE_INPUTS": "單行輸入",
                +	"DELETE_BLOCK": "刪除積木",
                +	"DELETE_X_BLOCKS": "刪除 %1 個積木",
                +	"DELETE_ALL_BLOCKS": "刪除共 %1 個積木?",
                +	"CLEAN_UP": "整理積木",
                +	"COLLAPSE_BLOCK": "收合積木",
                +	"COLLAPSE_ALL": "收合積木",
                +	"EXPAND_BLOCK": "展開積木",
                +	"EXPAND_ALL": "展開積木",
                +	"DISABLE_BLOCK": "停用積木",
                +	"ENABLE_BLOCK": "啟用積木",
                +	"HELP": "幫助",
                +	"UNDO": "復原",
                +	"REDO": "重試",
                +	"CHANGE_VALUE_TITLE": "修改值:",
                +	"RENAME_VARIABLE": "重新命名變數...",
                +	"RENAME_VARIABLE_TITLE": "將所有「%1」變數重新命名為:",
                +	"NEW_VARIABLE": "建立變數...",
                +	"NEW_VARIABLE_TITLE": "新變數名稱:",
                +	"VARIABLE_ALREADY_EXISTS": "一個名為「%1」的變數已存在。",
                +	"VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE": "用於其它「%2」類型的變數裡已存在名為「%1」的變數。",
                +	"PROCEDURE_ALREADY_EXISTS": "一個名為「%1」的程序已存在。",
                +	"DELETE_VARIABLE_CONFIRMATION": "刪除%1使用的「%2」變數?",
                +	"CANNOT_DELETE_VARIABLE_PROCEDURE": "無法刪除變數「%1」,因為這是功能「%2」定義的一部份內容",
                +	"DELETE_VARIABLE": "刪除變數「%1」",
                +	"COLOUR_PICKER_HELPURL": "https://zh.wikipedia.org/wiki/顏色",
                +	"COLOUR_PICKER_TOOLTIP": "從調色板中選擇一種顏色。",
                +	"COLOUR_RANDOM_TITLE": "隨機顏色",
                +	"COLOUR_RANDOM_TOOLTIP": "隨機選擇一種顏色。",
                +	"COLOUR_RGB_TITLE": "顏色",
                +	"COLOUR_RGB_RED": "紅",
                +	"COLOUR_RGB_GREEN": "綠",
                +	"COLOUR_RGB_BLUE": "藍",
                +	"COLOUR_RGB_TOOLTIP": "透過指定紅、綠、 藍色的值來建立一種顏色。所有的值必須介於 0 和 100 之間。",
                +	"COLOUR_BLEND_TITLE": "混合",
                +	"COLOUR_BLEND_COLOUR1": "顏色 1",
                +	"COLOUR_BLEND_COLOUR2": "顏色 2",
                +	"COLOUR_BLEND_RATIO": "比例",
                +	"COLOUR_BLEND_TOOLTIP": "用一個給定的比率(0.0-1.0)混合兩種顏色。",
                +	"CONTROLS_REPEAT_HELPURL": "https://zh.wikipedia.org/wiki/For迴圈",
                +	"CONTROLS_REPEAT_TITLE": "重複 %1 次",
                +	"CONTROLS_REPEAT_INPUT_DO": "執行",
                +	"CONTROLS_REPEAT_TOOLTIP": "重複執行指定的陳述式多次。",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "重複 當",
                +	"CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "重複 直到",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "當值為 true 時,執行一些陳述式。",
                +	"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "當值為 false 時,執行一些陳述式。",
                +	"CONTROLS_FOR_TOOLTIP": "從起始數到結尾數中取出變數「%1」的值,按指定的時間間隔,執行指定的積木。",
                +	"CONTROLS_FOR_TITLE": "循環計數 %1 從 %2 到 %3 間隔數 %4",
                +	"CONTROLS_FOREACH_TITLE": "取出每個 %1 自清單 %2",
                +	"CONTROLS_FOREACH_TOOLTIP": "遍歷每個清單中的項目,將變數「%1」設定到該項目中,然後執行某些陳述式。",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "中斷循環",
                +	"CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "繼續下一個循環",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "中斷當前的循環。",
                +	"CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE": "跳過這個循環的其餘步驟,並繼續下一次的循環。",
                +	"CONTROLS_FLOW_STATEMENTS_WARNING": "警告: 此積木僅可用於迴圈內。",
                +	"CONTROLS_IF_TOOLTIP_1": "當值為 true 時,執行一些陳述式。",
                +	"CONTROLS_IF_TOOLTIP_2": "當值為 true 時,執行第一個陳述式,否則,執行第二個陳述式。",
                +	"CONTROLS_IF_TOOLTIP_3": "如果第一個值為 true,則執行第一個陳述式。否則,當第二個值為 true 時,則執行第二個陳述式。",
                +	"CONTROLS_IF_TOOLTIP_4": "如果第一個值為 true,則執行第一個陳述式。否則當第二個值為 true 時,則執行第二個陳述式。如果前幾個敘述都不為 ture,則執行最後一個陳述式。",
                +	"CONTROLS_IF_MSG_IF": "如果",
                +	"CONTROLS_IF_MSG_ELSEIF": "否則如果",
                +	"CONTROLS_IF_MSG_ELSE": "否則",
                +	"CONTROLS_IF_IF_TOOLTIP": "添加、 刪除或重新排列各區塊以重新配置這個「如果」積木。",
                +	"CONTROLS_IF_ELSEIF_TOOLTIP": "添加條件到「如果」積木。",
                +	"CONTROLS_IF_ELSE_TOOLTIP": "加入一個最終、所有條件都執行的區塊到「如果」積木中。",
                +	"IOS_OK": "確定",
                +	"IOS_CANCEL": "取消",
                +	"IOS_ERROR": "錯誤",
                +	"IOS_PROCEDURES_INPUTS": "輸入",
                +	"IOS_PROCEDURES_ADD_INPUT": "+ 添加輸入",
                +	"IOS_PROCEDURES_ALLOW_STATEMENTS": "允許聲明",
                +	"IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR": "此功能有重複輸入內容。",
                +	"IOS_VARIABLES_ADD_VARIABLE": "+ 添加變數",
                +	"IOS_VARIABLES_ADD_BUTTON": "添加",
                +	"IOS_VARIABLES_RENAME_BUTTON": "重新命名",
                +	"IOS_VARIABLES_DELETE_BUTTON": "刪除",
                +	"IOS_VARIABLES_VARIABLE_NAME": "變數名稱",
                +	"IOS_VARIABLES_EMPTY_NAME_ERROR": "您不能使用不帶名的變數名稱。",
                +	"LOGIC_COMPARE_HELPURL": "https://zh.wikipedia.org/wiki/不等",
                +	"LOGIC_COMPARE_TOOLTIP_EQ": "如果這兩個輸入區塊的結果相等,返回 true。",
                +	"LOGIC_COMPARE_TOOLTIP_NEQ": "如果這兩個輸入區塊的結果不相等,返回 true。",
                +	"LOGIC_COMPARE_TOOLTIP_LT": "如果第一個輸入結果比第二個小,返回 true。",
                +	"LOGIC_COMPARE_TOOLTIP_LTE": "如果第一個輸入結果小於或等於第二個,返回 true。",
                +	"LOGIC_COMPARE_TOOLTIP_GT": "如果第一個輸入結果大於第二個,返回 true。",
                +	"LOGIC_COMPARE_TOOLTIP_GTE": "如果第一個輸入結果大於或等於第二個,返回 true。",
                +	"LOGIC_OPERATION_TOOLTIP_AND": "如果兩個輸入結果都為 true,則返回 true。",
                +	"LOGIC_OPERATION_AND": "且",
                +	"LOGIC_OPERATION_TOOLTIP_OR": "如果至少一個輸入結果為 true,返回 true。",
                +	"LOGIC_OPERATION_OR": "或",
                +	"LOGIC_NEGATE_TITLE": "%1 不成立",
                +	"LOGIC_NEGATE_TOOLTIP": "如果輸入結果是 false,則返回 true。如果輸入結果是 true,則返回 false。",
                +	"LOGIC_BOOLEAN_TRUE": "true",
                +	"LOGIC_BOOLEAN_FALSE": "false",
                +	"LOGIC_BOOLEAN_TOOLTIP": "返回 true 或 false。",
                +	"LOGIC_NULL": "null",
                +	"LOGIC_NULL_TOOLTIP": "返回 null。",
                +	"LOGIC_TERNARY_HELPURL": "https://zh.wikipedia.org/wiki/條件運算符",
                +	"LOGIC_TERNARY_CONDITION": "測試",
                +	"LOGIC_TERNARY_IF_TRUE": "如果為 true",
                +	"LOGIC_TERNARY_IF_FALSE": "如果為 false",
                +	"LOGIC_TERNARY_TOOLTIP": "檢查「測試」中的條件。如果條件為 true,將返回「如果為 true」的值;否則,返回「如果為 false」的值。",
                +	"MATH_NUMBER_HELPURL": "https://zh.wikipedia.org/wiki/數",
                +	"MATH_NUMBER_TOOLTIP": "一個數字。",
                +	"MATH_ARITHMETIC_HELPURL": "https://zh.wikipedia.org/wiki/算術",
                +	"MATH_ARITHMETIC_TOOLTIP_ADD": "返回兩個數字的總和。",
                +	"MATH_ARITHMETIC_TOOLTIP_MINUS": "返回兩個數字的差。",
                +	"MATH_ARITHMETIC_TOOLTIP_MULTIPLY": "返回兩個數字的乘積。",
                +	"MATH_ARITHMETIC_TOOLTIP_DIVIDE": "返回兩個數字的商。",
                +	"MATH_ARITHMETIC_TOOLTIP_POWER": "返回第二個數字的指數的第一個數字。",
                +	"MATH_SINGLE_HELPURL": "https://zh.wikipedia.org/wiki/平方根",
                +	"MATH_SINGLE_OP_ROOT": "開根號",
                +	"MATH_SINGLE_TOOLTIP_ROOT": "返回指定數字的平方根。",
                +	"MATH_SINGLE_OP_ABSOLUTE": "絕對值",
                +	"MATH_SINGLE_TOOLTIP_ABS": "返回指定數字的絕對值。",
                +	"MATH_SINGLE_TOOLTIP_NEG": "返回指定數字的 negation。",
                +	"MATH_SINGLE_TOOLTIP_LN": "返回指定數字的自然對數。",
                +	"MATH_SINGLE_TOOLTIP_LOG10": "返回指定數字的對數。",
                +	"MATH_SINGLE_TOOLTIP_EXP": "返回指定數字指數的 e",
                +	"MATH_SINGLE_TOOLTIP_POW10": "返回指定數字指數的10的冪次。",
                +	"MATH_TRIG_HELPURL": "https://zh.wikipedia.org/wiki/三角函數",
                +	"MATH_TRIG_TOOLTIP_SIN": "返回指定角度的正弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_COS": "返回指定角度的餘弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_TAN": "返回指定角度的正切值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_ASIN": "返回指定角度的反正弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_ACOS": "返回指定角度的反餘弦值(非弧度)。",
                +	"MATH_TRIG_TOOLTIP_ATAN": "返回指定角度的反正切值。",
                +	"MATH_CONSTANT_HELPURL": "https://zh.wikipedia.org/wiki/數學常數",
                +	"MATH_CONSTANT_TOOLTIP": "返回一個的常見常量: π (3.141......),e (2.718...)、 φ (1.618...)、 開方(2) (1.414......)、 開方(½) (0.707......) 或 ∞ (無窮大)。",
                +	"MATH_IS_EVEN": "是偶數",
                +	"MATH_IS_ODD": "是奇數",
                +	"MATH_IS_PRIME": "是質數",
                +	"MATH_IS_WHOLE": "是非負整數",
                +	"MATH_IS_POSITIVE": "是正值",
                +	"MATH_IS_NEGATIVE": "是負值",
                +	"MATH_IS_DIVISIBLE_BY": "可被整除",
                +	"MATH_IS_TOOLTIP": "如果數字是偶數,奇數,非負整數,正數、 負數,或如果它是可被某數字整除,則返回 true 或 false。",
                +	"MATH_CHANGE_HELPURL": "https://zh.wikipedia.org/wiki/加法",
                +	"MATH_CHANGE_TITLE": "修改 %1 自 %2",
                +	"MATH_CHANGE_TOOLTIP": "將數字加到變數「%1」。",
                +	"MATH_ROUND_HELPURL": "https://zh.wikipedia.org/wiki/數值簡化",
                +	"MATH_ROUND_TOOLTIP": "將數字無條件進位或無條件捨去。",
                +	"MATH_ROUND_OPERATOR_ROUND": "四捨五入",
                +	"MATH_ROUND_OPERATOR_ROUNDUP": "無條件進位",
                +	"MATH_ROUND_OPERATOR_ROUNDDOWN": "無條件捨去",
                +	"MATH_ONLIST_OPERATOR_SUM": "數字總和 自清單",
                +	"MATH_ONLIST_TOOLTIP_SUM": "返回清單中的所有數字的總和。",
                +	"MATH_ONLIST_OPERATOR_MIN": "最小值 自清單",
                +	"MATH_ONLIST_TOOLTIP_MIN": "返回清單項目中最小的數字。",
                +	"MATH_ONLIST_OPERATOR_MAX": "最大值 自清單",
                +	"MATH_ONLIST_TOOLTIP_MAX": "返回清單項目中最大的數字。",
                +	"MATH_ONLIST_OPERATOR_AVERAGE": "平均數 自清單",
                +	"MATH_ONLIST_TOOLTIP_AVERAGE": "返回清單中數值的平均值(算術平均值)。",
                +	"MATH_ONLIST_OPERATOR_MEDIAN": "中位數 自清單",
                +	"MATH_ONLIST_TOOLTIP_MEDIAN": "返回清單中數值的中位數。",
                +	"MATH_ONLIST_OPERATOR_MODE": "比較眾數 自清單",
                +	"MATH_ONLIST_TOOLTIP_MODE": "返回一個清單中的最常見的項目。",
                +	"MATH_ONLIST_OPERATOR_STD_DEV": "標準差 自清單",
                +	"MATH_ONLIST_TOOLTIP_STD_DEV": "返回清單中數字的標準差。",
                +	"MATH_ONLIST_OPERATOR_RANDOM": "隨機抽取 自清單",
                +	"MATH_ONLIST_TOOLTIP_RANDOM": "從清單中返回一個隨機的項目。",
                +	"MATH_MODULO_HELPURL": "https://zh.wikipedia.org/wiki/模除",
                +	"MATH_MODULO_TITLE": "%1 除以 %2 的餘數",
                +	"MATH_MODULO_TOOLTIP": "回傳兩個數字相除的餘數。",
                +	"MATH_CONSTRAIN_TITLE": "限制數字 %1 介於(低)%2 到(高)%3",
                +	"MATH_CONSTRAIN_TOOLTIP": "限制數字介於兩個指定的數字之間(包含)。",
                +	"MATH_RANDOM_INT_HELPURL": "https://zh.wikipedia.org/wiki/隨機數生成器",
                +	"MATH_RANDOM_INT_TITLE": "隨機取數 %1 到 %2",
                +	"MATH_RANDOM_INT_TOOLTIP": "在指定二個數之間隨機取一個數(包含)。",
                +	"MATH_RANDOM_FLOAT_HELPURL": "https://zh.wikipedia.org/wiki/隨機數生成器",
                +	"MATH_RANDOM_FLOAT_TITLE_RANDOM": "隨機取分數",
                +	"MATH_RANDOM_FLOAT_TOOLTIP": "在 0.0(包含)和 1.0(不包含)之間隨機取一個數。",
                +	"TEXT_TEXT_HELPURL": "https://zh.wikipedia.org/wiki/字串",
                +	"TEXT_TEXT_TOOLTIP": "一個字元、一個單詞,或一串文字。",
                +	"TEXT_JOIN_TITLE_CREATEWITH": "字串組合",
                +	"TEXT_JOIN_TOOLTIP": "通過連接任意數量的項目來建立一串文字。",
                +	"TEXT_CREATE_JOIN_TITLE_JOIN": "加入",
                +	"TEXT_CREATE_JOIN_TOOLTIP": "添加、刪除或重新排列各區塊以重新配置這個文字積木。",
                +	"TEXT_CREATE_JOIN_ITEM_TOOLTIP": "添加一個項目到字串中。",
                +	"TEXT_APPEND_TITLE": "至 %1 套用文字 %2",
                +	"TEXT_APPEND_TOOLTIP": "添加一些文字到變數「%1」之後。",
                +	"TEXT_LENGTH_TITLE": "長度 %1",
                +	"TEXT_LENGTH_TOOLTIP": "返回這串文字的字元數(包含空格)。",
                +	"TEXT_ISEMPTY_TITLE": "%1 為空",
                +	"TEXT_ISEMPTY_TOOLTIP": "如果提供的字串為空,則返回 true。",
                +	"TEXT_INDEXOF_TOOLTIP": "在字串1中檢索是否有包含字串2,如果有,返回從頭/倒數算起的索引值。如果沒有則返回 %1。",
                +	"TEXT_INDEXOF_TITLE": "在文字 %1 %2 %3",
                +	"TEXT_INDEXOF_OPERATOR_FIRST": "從 最前面 索引字串",
                +	"TEXT_INDEXOF_OPERATOR_LAST": "從 最後面 索引字串",
                +	"TEXT_CHARAT_TITLE": "在文字 %1 %2",
                +	"TEXT_CHARAT_FROM_START": "取得 字元 #",
                +	"TEXT_CHARAT_FROM_END": "取得 倒數第 # 個字元",
                +	"TEXT_CHARAT_FIRST": "取得 第一個字元",
                +	"TEXT_CHARAT_LAST": "取得 最後一個字元",
                +	"TEXT_CHARAT_RANDOM": "取得 任意字元",
                +	"TEXT_CHARAT_TAIL": "",
                +	"TEXT_CHARAT_TOOLTIP": "返回位於指定位置的字元。",
                +	"TEXT_GET_SUBSTRING_TOOLTIP": "返回指定的部分文字。",
                +	"TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "在字串",
                +	"TEXT_GET_SUBSTRING_START_FROM_START": "取得 字元 #",
                +	"TEXT_GET_SUBSTRING_START_FROM_END": "取得 倒數第 # 個字元",
                +	"TEXT_GET_SUBSTRING_START_FIRST": "取得 第一個字元",
                +	"TEXT_GET_SUBSTRING_END_FROM_START": "到 字元 #",
                +	"TEXT_GET_SUBSTRING_END_FROM_END": "到 倒數第 # 個字元",
                +	"TEXT_GET_SUBSTRING_END_LAST": "到 最後一個字元",
                +	"TEXT_CHANGECASE_TOOLTIP": "使用不同的大小寫複製這段文字。",
                +	"TEXT_CHANGECASE_OPERATOR_UPPERCASE": "轉成 英文大寫",
                +	"TEXT_CHANGECASE_OPERATOR_LOWERCASE": "轉成 英文小寫",
                +	"TEXT_CHANGECASE_OPERATOR_TITLECASE": "轉成 英文首字大寫",
                +	"TEXT_TRIM_TOOLTIP": "複製這段文字,同時刪除兩端多餘的空格。",
                +	"TEXT_TRIM_OPERATOR_BOTH": "消除兩側空格",
                +	"TEXT_TRIM_OPERATOR_LEFT": "消除左側空格",
                +	"TEXT_TRIM_OPERATOR_RIGHT": "消除右側空格",
                +	"TEXT_PRINT_TITLE": "輸出 %1",
                +	"TEXT_PRINT_TOOLTIP": "輸出指定的文字、 數字或其他值。",
                +	"TEXT_PROMPT_TYPE_TEXT": "輸入 文字 並顯示提示訊息",
                +	"TEXT_PROMPT_TYPE_NUMBER": "輸入 數字 並顯示提示訊息",
                +	"TEXT_PROMPT_TOOLTIP_NUMBER": "輸入數字",
                +	"TEXT_PROMPT_TOOLTIP_TEXT": "輸入文字",
                +	"TEXT_COUNT_MESSAGE0": "在%2計算%1",
                +	"TEXT_COUNT_HELPURL": "https://github.com/google/blockly/wiki/Text#counting-substrings",
                +	"TEXT_COUNT_TOOLTIP": "計算某些文字在內容裡的出現次數。",
                +	"TEXT_REPLACE_MESSAGE0": "在%3以%2取代%1",
                +	"TEXT_REPLACE_HELPURL": "https://github.com/google/blockly/wiki/Text#replacing-substrings",
                +	"TEXT_REPLACE_TOOLTIP": "取代在內容裡的全部某些文字。",
                +	"TEXT_REVERSE_MESSAGE0": "反轉%1",
                +	"TEXT_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Text#reversing-text",
                +	"TEXT_REVERSE_TOOLTIP": "反轉排序在文字裡的字元。",
                +	"LISTS_CREATE_EMPTY_TITLE": "建立空的清單",
                +	"LISTS_CREATE_EMPTY_TOOLTIP": "返回一個長度(項目數量)為 0 的清單,不包含任何資料記錄",
                +	"LISTS_CREATE_WITH_TOOLTIP": "建立一個具備任意數量項目的清單。",
                +	"LISTS_CREATE_WITH_INPUT_WITH": "使用這些值建立清單",
                +	"LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "清單",
                +	"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "添加、刪除或重新排列各區塊以重新配置這個「清單」積木。",
                +	"LISTS_CREATE_WITH_ITEM_TOOLTIP": "添加一個項目到清單裡。",
                +	"LISTS_REPEAT_TOOLTIP": "建立一個清單,項目中包含指定重複次數的值。",
                +	"LISTS_REPEAT_TITLE": "建立清單使用項目 %1 重複 %2 次",
                +	"LISTS_LENGTH_TITLE": "長度 %1",
                +	"LISTS_LENGTH_TOOLTIP": "返回清單的長度(項目數)。",
                +	"LISTS_ISEMPTY_TITLE": "%1 值為空",
                +	"LISTS_ISEMPTY_TOOLTIP": "如果該清單為空,則返回 true。",
                +	"LISTS_INLIST": "自清單",
                +	"LISTS_INDEX_OF_FIRST": "從 最前面 索引項目",
                +	"LISTS_INDEX_OF_LAST": "從 最後面 索引項目",
                +	"LISTS_INDEX_OF_TOOLTIP": "在清單中檢索是否有包含項目,如果有,返回從頭/倒數算起的索引值。如果沒有則返回 %1。",
                +	"LISTS_GET_INDEX_GET": "取得",
                +	"LISTS_GET_INDEX_GET_REMOVE": "取得並移除",
                +	"LISTS_GET_INDEX_REMOVE": "移除",
                +	"LISTS_GET_INDEX_FROM_END": "倒數第 # 筆",
                +	"LISTS_GET_INDEX_FIRST": "第一筆",
                +	"LISTS_GET_INDEX_LAST": "最後一筆",
                +	"LISTS_GET_INDEX_RANDOM": "隨機",
                +	"LISTS_INDEX_FROM_START_TOOLTIP": "%1 是第一個項目。",
                +	"LISTS_INDEX_FROM_END_TOOLTIP": "%1 是最後一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FROM": "返回在清單中指定位置的項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "返回清單中的第一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_LAST": "返回清單中的最後一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "返回清單中隨機一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "移除並返回清單中的指定位置的項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "移除並返回清單中的第一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "移除並返回清單中的最後一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "移除並返回清單中的隨機項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "移除在清單中指定位置的項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "移除清單中的第一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "移除清單中的最後一個項目。",
                +	"LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "移除清單中隨機一個項目。",
                +	"LISTS_SET_INDEX_SET": "設定",
                +	"LISTS_SET_INDEX_INSERT": "添加",
                +	"LISTS_SET_INDEX_INPUT_TO": "為",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FROM": "設定清單中指定位置的項目。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "設定清單中的第一個項目。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_LAST": "設定清單中的最後一個項目。",
                +	"LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "設定清單中隨機一個項目。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "添加一個項目到清單中的指定位置。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "添加一個項目到清單中的第一個位置。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "添加一個項目到清單中的最後一個位置。",
                +	"LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "添加一個項目到清單中的隨機位置。",
                +	"LISTS_GET_SUBLIST_START_FROM_START": "取得子清單 從 #",
                +	"LISTS_GET_SUBLIST_START_FROM_END": "取得子清單 從 # 倒數",
                +	"LISTS_GET_SUBLIST_START_FIRST": "取得子清單 從 最前面",
                +	"LISTS_GET_SUBLIST_END_FROM_START": "到 #",
                +	"LISTS_GET_SUBLIST_END_FROM_END": "到 # 倒數",
                +	"LISTS_GET_SUBLIST_END_LAST": "到 最後面",
                +	"LISTS_GET_SUBLIST_TOOLTIP": "複製清單中指定的部分。",
                +	"LISTS_SORT_HELPURL": "https://github.com/google/blockly/wiki/Lists#sorting-a-list",
                +	"LISTS_SORT_TITLE": "排列 %1 %2 %3",
                +	"LISTS_SORT_TOOLTIP": "排序清單的複製內容。",
                +	"LISTS_SORT_ORDER_ASCENDING": "升序",
                +	"LISTS_SORT_ORDER_DESCENDING": "降序",
                +	"LISTS_SORT_TYPE_NUMERIC": "依數字",
                +	"LISTS_SORT_TYPE_TEXT": "依字母",
                +	"LISTS_SORT_TYPE_IGNORECASE": "依字母排序,忽略大小寫",
                +	"LISTS_SPLIT_LIST_FROM_TEXT": "從文本製作清單",
                +	"LISTS_SPLIT_TEXT_FROM_LIST": "從清單拆出文本",
                +	"LISTS_SPLIT_WITH_DELIMITER": "用分隔符",
                +	"LISTS_SPLIT_TOOLTIP_SPLIT": "將文本變成清單項目,按分隔符號拆分。",
                +	"LISTS_SPLIT_TOOLTIP_JOIN": "串起清單項目成一個文本,並用分隔符號分開。",
                +	"LISTS_REVERSE_HELPURL": "https://github.com/google/blockly/wiki/Lists#reversing-a-list",
                +	"LISTS_REVERSE_MESSAGE0": "反轉%1",
                +	"LISTS_REVERSE_TOOLTIP": "反轉清單的複製內容。",
                +	"VARIABLES_GET_TOOLTIP": "返回此變數的值。",
                +	"VARIABLES_GET_CREATE_SET": "建立「賦值 %1」",
                +	"VARIABLES_SET": "賦值 %1 成 %2",
                +	"VARIABLES_SET_TOOLTIP": "設定此變數,好和輸入結果相等。",
                +	"VARIABLES_SET_CREATE_GET": "建立「取得 %1」",
                +	"PROCEDURES_DEFNORETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程式",
                +	"PROCEDURES_DEFNORETURN_TITLE": "到",
                +	"PROCEDURES_DEFNORETURN_PROCEDURE": "做些什麼",
                +	"PROCEDURES_BEFORE_PARAMS": "與:",
                +	"PROCEDURES_CALL_BEFORE_PARAMS": "與:",
                +	"PROCEDURES_DEFNORETURN_TOOLTIP": "創建一個無回傳值的函式。",
                +	"PROCEDURES_DEFNORETURN_COMMENT": "描述此函式...",
                +	"PROCEDURES_DEFRETURN_HELPURL": "https://zh.wikipedia.org/wiki/子程式",
                +	"PROCEDURES_DEFRETURN_RETURN": "返回",
                +	"PROCEDURES_DEFRETURN_TOOLTIP": "創建一個有回傳值的的函式。",
                +	"PROCEDURES_ALLOW_STATEMENTS": "允許陳述式",
                +	"PROCEDURES_DEF_DUPLICATE_WARNING": "警告: 此函式中有重複的參數。",
                +	"PROCEDURES_CALLNORETURN_HELPURL": "https://zh.wikipedia.org/wiki/%E5%AD%90%E7%A8%8B%E5%BA%8F",
                +	"PROCEDURES_CALLNORETURN_TOOLTIP": "執行使用者定義的函式「%1」。",
                +	"PROCEDURES_CALLRETURN_HELPURL": "https://zh.wikipedia.org/wiki/%E5%AD%90%E7%A8%8B%E5%BA%8F",
                +	"PROCEDURES_CALLRETURN_TOOLTIP": "執行使用者定義的函式「%1」,並使用它的回傳值。",
                +	"PROCEDURES_MUTATORCONTAINER_TITLE": "輸入",
                +	"PROCEDURES_MUTATORCONTAINER_TOOLTIP": "添加、刪除或重新排列此函式的輸入。",
                +	"PROCEDURES_MUTATORARG_TITLE": "輸入名稱:",
                +	"PROCEDURES_MUTATORARG_TOOLTIP": "添加一個輸入區塊到函式。",
                +	"PROCEDURES_HIGHLIGHT_DEF": "反白顯示函式定義",
                +	"PROCEDURES_CREATE_DO": "建立「%1」",
                +	"PROCEDURES_IFRETURN_TOOLTIP": "如果值為 true,則返回第二個值。",
                +	"PROCEDURES_IFRETURN_WARNING": "警告:這個積木只可以在定義函式時使用。"
                +}
                diff --git a/blockly/webif/static/blockly/msg/messages.js b/blockly/webif/static/blockly/msg/messages.js
                new file mode 100644
                index 000000000..6621717e1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/msg/messages.js
                @@ -0,0 +1,1187 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview English strings.
                + * @author fraser@google.com (Neil Fraser)
                + *
                + * After modifying this file, either run "build.py" from the parent directory,
                + * or run (from this directory):
                + * ../i18n/js_to_json.py
                + * to regenerate json/{en,qqq,synonyms}.json.
                + *
                + * To convert all of the json files to .js files, run:
                + * ../i18n/create_messages.py json/*.json
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Msg.en');
                +
                +goog.require('Blockly.Msg');
                +
                +
                +/**
                + * Due to the frequency of long strings, the 80-column wrap rule need not apply
                + * to message files.
                + */
                +
                +/**
                + * Each message is preceded with a tripple-slash comment that becomes the
                + * message descriptor.  The build process extracts these descriptors, adds
                + * them to msg/json/qqq.json, and they show up in the translation console.
                + */
                +
                +/// {{Notranslate}} Hue value for all logic blocks.
                +Blockly.Msg.LOGIC_HUE = '210';
                +/// {{Notranslate}} Hue value for all loop blocks.
                +Blockly.Msg.LOOPS_HUE = '120';
                +/// {{Notranslate}} Hue value for all math blocks.
                +Blockly.Msg.MATH_HUE = '230';
                +/// {{Notranslate}} Hue value for all text blocks.
                +Blockly.Msg.TEXTS_HUE = '160';
                +/// {{Notranslate}} Hue value for all list blocks.
                +Blockly.Msg.LISTS_HUE = '260';
                +/// {{Notranslate}} Hue value for all colour blocks.
                +Blockly.Msg.COLOUR_HUE = '20';
                +/// {{Notranslate}} Hue value for all variable blocks.
                +Blockly.Msg.VARIABLES_HUE = '330';
                +/// {{Notranslate}} Hue value for all procedure blocks.
                +Blockly.Msg.PROCEDURES_HUE = '290';
                +
                +/// default name - A simple, general default name for a variable, preferably short.
                +/// For more context, see
                +/// [[Translating:Blockly#infrequent_message_types]].\n{{Identical|Item}}
                +Blockly.Msg.VARIABLES_DEFAULT_NAME = 'item';
                +/// button text - Button that sets a calendar to today's date.\n{{Identical|Today}}
                +Blockly.Msg.TODAY = 'Today';
                +
                +// Context menus.
                +/// context menu - Make a copy of the selected block (and any blocks it contains).\n{{Identical|Duplicate}}
                +Blockly.Msg.DUPLICATE_BLOCK = 'Duplicate';
                +/// context menu - Add a descriptive comment to the selected block.
                +Blockly.Msg.ADD_COMMENT = 'Add Comment';
                +/// context menu - Remove the descriptive comment from the selected block.
                +Blockly.Msg.REMOVE_COMMENT = 'Remove Comment';
                +/// context menu - Change from 'external' to 'inline' mode for displaying blocks used as inputs to the selected block.  See [[Translating:Blockly#context_menus]].
                +Blockly.Msg.EXTERNAL_INPUTS = 'External Inputs';
                +/// context menu - Change from 'internal' to 'external' mode for displaying blocks used as inputs to the selected block.  See [[Translating:Blockly#context_menus]].
                +Blockly.Msg.INLINE_INPUTS = 'Inline Inputs';
                +/// context menu - Permanently delete the selected block.
                +Blockly.Msg.DELETE_BLOCK = 'Delete Block';
                +/// context menu - Permanently delete the %1 selected blocks.\n\nParameters:\n* %1 - an integer greater than 1.
                +Blockly.Msg.DELETE_X_BLOCKS = 'Delete %1 Blocks';
                +/// confirmation prompt - Question the user if they really wanted to permanently delete all %1 blocks.\n\nParameters:\n* %1 - an integer greater than 1.
                +Blockly.Msg.DELETE_ALL_BLOCKS = 'Delete all %1 blocks?';
                +/// context menu - Reposition all the blocks so that they form a neat line.
                +Blockly.Msg.CLEAN_UP = 'Clean up Blocks';
                +/// context menu - Make the appearance of the selected block smaller by hiding some information about it.
                +Blockly.Msg.COLLAPSE_BLOCK = 'Collapse Block';
                +/// context menu - Make the appearance of all blocks smaller by hiding some information about it.  Use the same terminology as in the previous message.
                +Blockly.Msg.COLLAPSE_ALL = 'Collapse Blocks';
                +/// context menu - Restore the appearance of the selected block by showing information about it that was hidden (collapsed) earlier.
                +Blockly.Msg.EXPAND_BLOCK = 'Expand Block';
                +/// context menu - Restore the appearance of all blocks by showing information about it that was hidden (collapsed) earlier.  Use the same terminology as in the previous message.
                +Blockly.Msg.EXPAND_ALL = 'Expand Blocks';
                +/// context menu - Make the selected block have no effect (unless reenabled).
                +Blockly.Msg.DISABLE_BLOCK = 'Disable Block';
                +/// context menu - Make the selected block have effect (after having been disabled earlier).
                +Blockly.Msg.ENABLE_BLOCK = 'Enable Block';
                +/// context menu - Provide helpful information about the selected block.\n{{Identical|Help}}
                +Blockly.Msg.HELP = 'Help';
                +/// context menu - Undo the previous action.\n{{Identical|Undo}}
                +Blockly.Msg.UNDO = 'Undo';
                +/// context menu - Undo the previous undo action.\n{{Identical|Redo}}
                +Blockly.Msg.REDO = 'Redo';
                +
                +// Variable renaming.
                +/// prompt - This message is only seen in the Opera browser.  With most browsers, users can edit numeric values in blocks by just clicking and typing.  Opera does not allows this, so we have to open a new window and prompt users with this message to chanage a value.
                +Blockly.Msg.CHANGE_VALUE_TITLE = 'Change value:';
                +/// dropdown choice - When the user clicks on a variable block, this is one of the dropdown menu choices.  It is used to rename the current variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].
                +Blockly.Msg.RENAME_VARIABLE = 'Rename variable...';
                +/// prompt - Prompts the user to enter the new name for the selected variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].\n\nParameters:\n* %1 - the name of the variable to be renamed.
                +Blockly.Msg.RENAME_VARIABLE_TITLE = 'Rename all "%1" variables to:';
                +
                +// Variable creation
                +/// button text - Text on the button used to launch the variable creation dialogue.
                +Blockly.Msg.NEW_VARIABLE = 'Create variable...';
                +/// prompt - Prompts the user to enter the name for a new variable.  See [https://github.com/google/blockly/wiki/Variables#dropdown-menu https://github.com/google/blockly/wiki/Variables#dropdown-menu].
                +Blockly.Msg.NEW_VARIABLE_TITLE = 'New variable name:';
                +/// alert - Tells the user that the name they entered is already in use.
                +Blockly.Msg.VARIABLE_ALREADY_EXISTS = 'A variable named "%1" already exists.';
                +/// alert - Tells the user that the name they entered is already in use for another type.
                +Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE = 'A variable named "%1" already exists for another variable of type "%2".';
                +/// alert - Tells the user that the name they entered is already in use for a procedure.
                +Blockly.Msg.PROCEDURE_ALREADY_EXISTS = 'A procedure named "%1" already exists.';
                +
                +// Variable deletion.
                +/// confirm -  Ask the user to confirm their deletion of multiple uses of a variable.
                +Blockly.Msg.DELETE_VARIABLE_CONFIRMATION = 'Delete %1 uses of the "%2" variable?';
                +/// alert - Tell the user that they can't delete a variable because it's part of the definition of a function.
                +Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE = 'Can\'t delete the variable "%1" because it\'s part of the definition of the function "%2"';
                +/// dropdown choice - Delete the currently selected variable.
                +Blockly.Msg.DELETE_VARIABLE = 'Delete the "%1" variable';
                +
                +// Colour Blocks.
                +/// url - Information about colour.
                +Blockly.Msg.COLOUR_PICKER_HELPURL = 'https://en.wikipedia.org/wiki/Color';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette https://github.com/google/blockly/wiki/Colour#picking-a-colour-from-a-palette].
                +Blockly.Msg.COLOUR_PICKER_TOOLTIP = 'Choose a colour from the palette.';
                +/// url - A link that displays a random colour each time you visit it.
                +Blockly.Msg.COLOUR_RANDOM_HELPURL = 'http://randomcolour.com';
                +/// block text - Title of block that generates a colour at random.
                +Blockly.Msg.COLOUR_RANDOM_TITLE = 'random colour';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Colour#generating-a-random-colour https://github.com/google/blockly/wiki/Colour#generating-a-random-colour].
                +Blockly.Msg.COLOUR_RANDOM_TOOLTIP = 'Choose a colour at random.';
                +/// url - A link for color codes with percentages (0-100%) for each component, instead of the more common 0-255, which may be more difficult for beginners.
                +Blockly.Msg.COLOUR_RGB_HELPURL = 'http://www.december.com/html/spec/colorper.html';
                +/// block text - Title of block for [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
                +Blockly.Msg.COLOUR_RGB_TITLE = 'colour with';
                +/// block input text - The amount of red (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Red}}
                +Blockly.Msg.COLOUR_RGB_RED = 'red';
                +/// block input text - The amount of green (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
                +Blockly.Msg.COLOUR_RGB_GREEN = 'green';
                +/// block input text - The amount of blue (from 0 to 100) to use when [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].\n{{Identical|Blue}}
                +Blockly.Msg.COLOUR_RGB_BLUE = 'blue';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components https://github.com/google/blockly/wiki/Colour#creating-a-colour-from-red-green-and-blue-components].
                +Blockly.Msg.COLOUR_RGB_TOOLTIP = 'Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.';
                +/// url - A useful link that displays blending of two colors.
                +Blockly.Msg.COLOUR_BLEND_HELPURL = 'http://meyerweb.com/eric/tools/color-blend/';
                +/// block text - A verb for blending two shades of paint.
                +Blockly.Msg.COLOUR_BLEND_TITLE = 'blend';
                +/// block input text - The first of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].
                +Blockly.Msg.COLOUR_BLEND_COLOUR1 = 'colour 1';
                +/// block input text - The second of two colours to [https://github.com/google/blockly/wiki/Colour#blending-colours blend].
                +Blockly.Msg.COLOUR_BLEND_COLOUR2 = 'colour 2';
                +/// block input text - The proportion of the [https://github.com/google/blockly/wiki/Colour#blending-colours blend] containing the first color; the remaining proportion is of the second colour.  For example, if the first colour is red and the second color blue, a ratio of 1 would yield pure red, a ratio of .5 would yield purple (equal amounts of red and blue), and a ratio of 0 would yield pure blue.\n{{Identical|Ratio}}
                +Blockly.Msg.COLOUR_BLEND_RATIO = 'ratio';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Colour#blending-colours https://github.com/google/blockly/wiki/Colour#blending-colours].
                +Blockly.Msg.COLOUR_BLEND_TOOLTIP = 'Blends two colours together with a given ratio (0.0 - 1.0).';
                +
                +// Loop Blocks.
                +/// url - Describes 'repeat loops' in computer programs; consider using the translation of the page [https://en.wikipedia.org/wiki/Control_flow http://en.wikipedia.org/wiki/Control_flow].
                +Blockly.Msg.CONTROLS_REPEAT_HELPURL = 'https://en.wikipedia.org/wiki/For_loop';
                +/// block input text - Title of [https://github.com/google/blockly/wiki/Loops#repeat repeat block].\n\nParameters:\n* %1 - the number of times the body of the loop should be repeated.
                +Blockly.Msg.CONTROLS_REPEAT_TITLE = 'repeat %1 times';
                +/// block text - Preceding the blocks in the body of the loop.  See [https://github.com/google/blockly/wiki/Loops https://github.com/google/blockly/wiki/Loops].\n{{Identical|Do}}
                +Blockly.Msg.CONTROLS_REPEAT_INPUT_DO = 'do';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat https://github.com/google/blockly/wiki/Loops#repeat].
                +Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = 'Do some statements several times.';
                +/// url - Describes 'while loops' in computer programs; consider using the translation of [https://en.wikipedia.org/wiki/While_loop https://en.wikipedia.org/wiki/While_loop], if present, or [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow].
                +Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL = 'https://github.com/google/blockly/wiki/Loops#repeat';
                +Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +/// dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-while repeat while] the following condition is true.
                +Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE = 'repeat while';
                +/// dropdown - Specifies that a loop should [https://github.com/google/blockly/wiki/Loops#repeat-until repeat until] the following condition becomes true.
                +Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL = 'repeat until';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while https://github.com/google/blockly/wiki/Loops#repeat-while Loops#repeat-while].
                +Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = 'While a value is true, then do some statements.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#repeat-until https://github.com/google/blockly/wiki/Loops#repeat-until].
                +Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = 'While a value is false, then do some statements.';
                +
                +/// url - Describes 'for loops' in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/For_loop https://en.wikipedia.org/wiki/For_loop], if present.
                +Blockly.Msg.CONTROLS_FOR_HELPURL = 'https://github.com/google/blockly/wiki/Loops#count-with';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#count-with https://github.com/google/blockly/wiki/Loops#count-with].\n\nParameters:\n* %1 - the name of the loop variable.
                +Blockly.Msg.CONTROLS_FOR_TOOLTIP = 'Have the variable "%1" take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.';
                +/// block text - Repeatedly counts a variable (%1)
                +/// starting with a (usually lower) number in a range (%2),
                +/// ending with a (usually higher) number in a range (%3), and counting the
                +/// iterations by a number of steps (%4).  As in
                +/// [https://github.com/google/blockly/wiki/Loops#count-with
                +/// https://github.com/google/blockly/wiki/Loops#count-with].
                +/// [[File:Blockly-count-with.png]]
                +Blockly.Msg.CONTROLS_FOR_TITLE = 'count with %1 from %2 to %3 by %4';
                +Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +
                +/// url - Describes 'for-each loops' in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Foreach https://en.wikipedia.org/wiki/Foreach] if present.
                +Blockly.Msg.CONTROLS_FOREACH_HELPURL = 'https://github.com/google/blockly/wiki/Loops#for-each';
                +/// block text - Title of [https://github.com/google/blockly/wiki/Loops#for-each for each block].
                +/// Sequentially assigns every item in array %2 to the valiable %1.
                +Blockly.Msg.CONTROLS_FOREACH_TITLE = 'for each item %1 in list %2';
                +Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +/// block text - Description of [https://github.com/google/blockly/wiki/Loops#for-each for each blocks].\n\nParameters:\n* %1 - the name of the loop variable.
                +Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = 'For each item in a list, set the variable "%1" to the item, and then do some statements.';
                +
                +/// url - Describes control flow in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Control_flow https://en.wikipedia.org/wiki/Control_flow], if it exists.
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL = 'https://github.com/google/blockly/wiki/Loops#loop-termination-blocks';
                +/// dropdown - The current loop should be exited.  See [https://github.com/google/blockly/wiki/Loops#break https://github.com/google/blockly/wiki/Loops#break].
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK = 'break out of loop';
                +/// dropdown - The current iteration of the loop should be ended and the next should begin.  See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE = 'continue with next iteration of loop';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#break-out-of-loop https://github.com/google/blockly/wiki/Loops#break-out-of-loop].
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK = 'Break out of the containing loop.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration https://github.com/google/blockly/wiki/Loops#continue-with-next-iteration].
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE = 'Skip the rest of this loop, and continue with the next iteration.';
                +/// warning - The user has tried placing a block outside of a loop (for each, while, repeat, etc.), but this type of block may only be used within a loop.  See [https://github.com/google/blockly/wiki/Loops#loop-termination-blocks https://github.com/google/blockly/wiki/Loops#loop-termination-blocks].
                +Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING = 'Warning: This block may only be used within a loop.';
                +
                +// Logic Blocks.
                +/// url - Describes conditional statements (if-then-else) in computer programs.  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_else https://en.wikipedia.org/wiki/If_else], if present.
                +Blockly.Msg.CONTROLS_IF_HELPURL = 'https://github.com/google/blockly/wiki/IfElse';
                +/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-blocks 'if' blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
                +Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = 'If a value is true, then do some statements.';
                +/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-blocks if-else blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
                +Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = 'If a value is true, then do the first block of statements. Otherwise, do the second block of statements.';
                +/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-blocks if-else-if blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
                +Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = 'If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.';
                +/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#if-else-if-else-blocks if-else-if-else blocks].  Consider using your language's translation of [https://en.wikipedia.org/wiki/If_statement https://en.wikipedia.org/wiki/If_statement], if present.
                +Blockly.Msg.CONTROLS_IF_TOOLTIP_4 = 'If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.';
                +/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].
                +/// It is recommended, but not essential, that this have text in common with the translation of 'else if'\n{{Identical|If}}
                +Blockly.Msg.CONTROLS_IF_MSG_IF = 'if';
                +/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].  The English words "otherwise if" would probably be clearer than "else if", but the latter is used because it is traditional and shorter.
                +Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = 'else if';
                +/// block text - See [https://github.com/google/blockly/wiki/IfElse https://github.com/google/blockly/wiki/IfElse].  The English word "otherwise" would probably be superior to "else", but the latter is used because it is traditional and shorter.
                +Blockly.Msg.CONTROLS_IF_MSG_ELSE = 'else';
                +Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
                +Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
                +/// tooltip - Describes [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
                +Blockly.Msg.CONTROLS_IF_IF_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this if block.';
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
                +/// tooltip - Describes the 'else if' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
                +Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = 'Add a condition to the if block.';
                +Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
                +/// tooltip - Describes the 'else' subblock during [https://github.com/google/blockly/wiki/IfElse#block-modification if block modification].
                +Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = 'Add a final, catch-all condition to the if block.';
                +
                +/// button text - Text on a button inside a dialogue window, which will accept or acknowledge the contents of the dialogue when pressed.\n{{Identical|OK}}
                +Blockly.Msg.IOS_OK = 'OK';
                +/// button text - Text on a button inside a dialogue window, which will close or cancel the dialogue when pressed.\n{{Identical|Cancel}}
                +Blockly.Msg.IOS_CANCEL = 'Cancel';
                +/// alert - Title text for an error dialogue.\n{{Identical|Error}}
                +Blockly.Msg.IOS_ERROR = 'Error';
                +/// header text - Title of a section that displays a list of parameters (aka. "inputs") that have been defined for a procedure. This is used inside a dialogue window to configure a procedure.\n{{Identical|Input}}
                +Blockly.Msg.IOS_PROCEDURES_INPUTS = 'INPUTS';
                +/// button text - Text on a button which will add a parameter (aka. "input") to a procedure. This is used inside a dialogue window to configure a procedure. NOTE: The "+" should be preserved at the beginning of the text.
                +Blockly.Msg.IOS_PROCEDURES_ADD_INPUT = '+ Add Input';
                +/// option text - Text describing an option to allow statements to be added within a procedure. This is used inside a dialogue window to configure a procedure.
                +Blockly.Msg.IOS_PROCEDURES_ALLOW_STATEMENTS = 'Allow statements';
                +/// alert - Error message when duplicate parameters (aka. "inputs") have been defined on a procedure. This is used inside a dialogue window to configure procedure parameters.
                +Blockly.Msg.IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR = 'This function has duplicate inputs.';
                +/// button text - Text on a button which will open a variable creation dialogue when pressed. NOTE: The "+" should be preserved at the beginning of the text.
                +Blockly.Msg.IOS_VARIABLES_ADD_VARIABLE = '+ Add Variable';
                +/// button text - Text on a button inside a variable creation dialogue, which will add a variable when pressed.\n{{Identical|Add}}
                +Blockly.Msg.IOS_VARIABLES_ADD_BUTTON = 'Add';
                +/// button text - Text on a button inside a variable rename dialogue, which will rename a variable when pressed.\n{{Identical|Rename}}
                +Blockly.Msg.IOS_VARIABLES_RENAME_BUTTON = 'Rename';
                +/// button text - Text on a button inside a variable deletion dialogue, which will delete a variable when pressed.\n{{Identical|Delete}}
                +Blockly.Msg.IOS_VARIABLES_DELETE_BUTTON = 'Delete';
                +/// placeholder text - Placeholder text used inside a text input, where a variable name should be entered.
                +Blockly.Msg.IOS_VARIABLES_VARIABLE_NAME = 'Variable name';
                +/// alert - Error message that is displayed when the user attempts to create a variable without a name.
                +Blockly.Msg.IOS_VARIABLES_EMPTY_NAME_ERROR = 'You can\'t use an empty variable name.';
                +
                +/// url - Information about comparisons.
                +Blockly.Msg.LOGIC_COMPARE_HELPURL = 'https://en.wikipedia.org/wiki/Inequality_(mathematics)';
                +/// tooltip - Describes the equals (=) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = 'Return true if both inputs equal each other.';
                +/// tooltip - Describes the not equals (≠) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = 'Return true if both inputs are not equal to each other.';
                +/// tooltip - Describes the less than (<) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = 'Return true if the first input is smaller than the second input.';
                +/// tooltip - Describes the less than or equals (≤) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = 'Return true if the first input is smaller than or equal to the second input.';
                +/// tooltip - Describes the greater than (>) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = 'Return true if the first input is greater than the second input.';
                +/// tooltip - Describes the greater than or equals (≥) block.
                +Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = 'Return true if the first input is greater than or equal to the second input.';
                +
                +/// url - Information about the Boolean conjunction ("and") and disjunction ("or") operators.  Consider using the translation of [https://en.wikipedia.org/wiki/Boolean_logic https://en.wikipedia.org/wiki/Boolean_logic], if it exists in your language.
                +Blockly.Msg.LOGIC_OPERATION_HELPURL = 'https://github.com/google/blockly/wiki/Logic#logical-operations';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].
                +Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = 'Return true if both inputs are true.';
                +/// block text - See [https://en.wikipedia.org/wiki/Logical_conjunction https://en.wikipedia.org/wiki/Logical_conjunction].\n{{Identical|And}}
                +Blockly.Msg.LOGIC_OPERATION_AND = 'and';
                +/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].
                +Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = 'Return true if at least one of the inputs is true.';
                +/// block text - See [https://en.wikipedia.org/wiki/Disjunction https://en.wikipedia.org/wiki/Disjunction].\n{{Identical|Or}}
                +Blockly.Msg.LOGIC_OPERATION_OR = 'or';
                +
                +/// url - Information about logical negation.  The translation of [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation] is recommended if it exists in the target language.
                +Blockly.Msg.LOGIC_NEGATE_HELPURL = 'https://github.com/google/blockly/wiki/Logic#not';
                +/// block text - This is a unary operator that returns ''false'' when the input is ''true'', and ''true'' when the input is ''false''.
                +/// \n\nParameters:\n* %1 - the input (which should be either the value "true" or "false")
                +Blockly.Msg.LOGIC_NEGATE_TITLE = 'not %1';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Logical_negation https://en.wikipedia.org/wiki/Logical_negation].
                +Blockly.Msg.LOGIC_NEGATE_TOOLTIP = 'Returns true if the input is false. Returns false if the input is true.';
                +
                +/// url - Information about the logic values ''true'' and ''false''.  Consider using the translation of [https://en.wikipedia.org/wiki/Truth_value https://en.wikipedia.org/wiki/Truth_value] if it exists in your language.
                +Blockly.Msg.LOGIC_BOOLEAN_HELPURL = 'https://github.com/google/blockly/wiki/Logic#values';
                +/// block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''true''.\n{{Identical|True}}
                +Blockly.Msg.LOGIC_BOOLEAN_TRUE = 'true';
                +/// block text - The word for the [https://en.wikipedia.org/wiki/Truth_value logical value] ''false''.\n{{Identical|False}}
                +Blockly.Msg.LOGIC_BOOLEAN_FALSE = 'false';
                +/// tooltip - Indicates that the block returns either of the two possible [https://en.wikipedia.org/wiki/Truth_value logical values].
                +Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = 'Returns either true or false.';
                +
                +/// url - Provide a link to the translation of [https://en.wikipedia.org/wiki/Nullable_type https://en.wikipedia.org/wiki/Nullable_type], if it exists in your language; otherwise, do not worry about translating this advanced concept.
                +Blockly.Msg.LOGIC_NULL_HELPURL = 'https://en.wikipedia.org/wiki/Nullable_type';
                +/// block text - In computer languages, ''null'' is a special value that indicates that no value has been set.  You may use your language's word for "nothing" or "invalid".\n{{Identical|Null}}
                +Blockly.Msg.LOGIC_NULL = 'null';
                +/// tooltip - This should use the word from the previous message.
                +Blockly.Msg.LOGIC_NULL_TOOLTIP = 'Returns null.';
                +
                +/// url - Describes the programming language operator known as the ''ternary'' or ''conditional'' operator.  It is recommended that you use the translation of [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:] if it exists.
                +Blockly.Msg.LOGIC_TERNARY_HELPURL = 'https://en.wikipedia.org/wiki/%3F:';
                +/// block input text - Label for the input whose value determines which of the other two inputs is returned.  In some programming languages, this is called a ''''predicate''''.
                +Blockly.Msg.LOGIC_TERNARY_CONDITION = 'test';
                +/// block input text - Indicates that the following input should be returned (used as output) if the test input is true.  Remember to try to keep block text terse (short).
                +Blockly.Msg.LOGIC_TERNARY_IF_TRUE = 'if true';
                +/// block input text - Indicates that the following input should be returned (used as output) if the test input is false.
                +Blockly.Msg.LOGIC_TERNARY_IF_FALSE = 'if false';
                +/// tooltip - See [https://en.wikipedia.org/wiki/%3F: https://en.wikipedia.org/wiki/%3F:].
                +Blockly.Msg.LOGIC_TERNARY_TOOLTIP = 'Check the condition in "test". If the condition is true, returns the "if true" value; otherwise returns the "if false" value.';
                +
                +// Math Blocks.
                +/// url - Information about (real) numbers.
                +Blockly.Msg.MATH_NUMBER_HELPURL = 'https://en.wikipedia.org/wiki/Number';
                +/// tooltip - Any positive or negative number, not necessarily an integer.
                +Blockly.Msg.MATH_NUMBER_TOOLTIP = 'A number.';
                +
                +/// {{optional}}\nmath - The symbol for the binary operation addition.
                +Blockly.Msg.MATH_ADDITION_SYMBOL = '+';
                +/// {{optional}}\nmath - The symbol for the binary operation indicating that the right operand should be
                +/// subtracted from the left operand.
                +Blockly.Msg.MATH_SUBTRACTION_SYMBOL = '-';
                +/// {{optional}}\nmath - The binary operation indicating that the left operand should be divided by
                +/// the right operand.
                +Blockly.Msg.MATH_DIVISION_SYMBOL = '÷';
                +/// {{optional}}\nmath - The symbol for the binary operation multiplication.
                +Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = '×';
                +/// {{optional}}\nmath - The symbol for the binary operation exponentiation.  Specifically, if the
                +/// value of the left operand is L and the value of the right operand (the exponent) is
                +/// R, multiply L by itself R times.  (Fractional and negative exponents are also legal.)
                +Blockly.Msg.MATH_POWER_SYMBOL = '^';
                +
                +/// math - The short name of the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].
                +Blockly.Msg.MATH_TRIG_SIN = 'sin';
                +/// math - The short name of the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].
                +Blockly.Msg.MATH_TRIG_COS = 'cos';
                +/// math - The short name of the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].
                +Blockly.Msg.MATH_TRIG_TAN = 'tan';
                +/// math - The short name of the ''inverse of'' the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine].
                +Blockly.Msg.MATH_TRIG_ASIN = 'asin';
                +/// math - The short name of the ''inverse of'' the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine].
                +Blockly.Msg.MATH_TRIG_ACOS = 'acos';
                +/// math - The short name of the ''inverse of'' the trigonometric function
                +/// [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent].
                +Blockly.Msg.MATH_TRIG_ATAN = 'atan';
                +
                +/// url - Information about addition, subtraction, multiplication, division, and exponentiation.
                +Blockly.Msg.MATH_ARITHMETIC_HELPURL = 'https://en.wikipedia.org/wiki/Arithmetic';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition].
                +Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = 'Return the sum of the two numbers.';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Subtraction https://en.wikipedia.org/wiki/Subtraction].
                +Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS = 'Return the difference of the two numbers.';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Multiplication https://en.wikipedia.org/wiki/Multiplication].
                +Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = 'Return the product of the two numbers.';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Division_(mathematics) https://en.wikipedia.org/wiki/Division_(mathematics)].
                +Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = 'Return the quotient of the two numbers.';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Exponentiation https://en.wikipedia.org/wiki/Exponentiation].
                +Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER = 'Return the first number raised to the power of the second number.';
                +
                +/// url - Information about the square root operation.
                +Blockly.Msg.MATH_SINGLE_HELPURL = 'https://en.wikipedia.org/wiki/Square_root';
                +/// dropdown - This computes the positive [https://en.wikipedia.org/wiki/Square_root square root] of its input.  For example, the square root of 16 is 4.
                +Blockly.Msg.MATH_SINGLE_OP_ROOT = 'square root';
                +/// tooltip - Please use the same term as in the previous message.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT = 'Return the square root of a number.';
                +/// dropdown - This leaves positive numeric inputs changed and inverts negative inputs.  For example, the absolute value of 5 is 5; the absolute value of -5 is also 5.  For more information, see [https://en.wikipedia.org/wiki/Absolute_value https://en.wikipedia.org/wiki/Absolute_value].
                +Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE = 'absolute';
                +/// tooltip - Please use the same term as in the previous message.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS = 'Return the absolute value of a number.';
                +
                +/// tooltip - Calculates '''0-n''', where '''n''' is the single numeric input.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG = 'Return the negation of a number.';
                +/// tooltip - Calculates the [https://en.wikipedia.org/wiki/Natural_logarithm|natural logarithm] of its single numeric input.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_LN = 'Return the natural logarithm of a number.';
                +/// tooltip - Calculates the [https://en.wikipedia.org/wiki/Common_logarithm common logarithm] of its single numeric input.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10 = 'Return the base 10 logarithm of a number.';
                +/// tooltip - Multiplies [https://en.wikipedia.org/wiki/E_(mathematical_constant) e] by itself n times, where n is the single numeric input.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP = 'Return e to the power of a number.';
                +/// tooltip - Multiplies 10 by itself n times, where n is the single numeric input.
                +Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10 = 'Return 10 to the power of a number.';
                +
                +/// url - Information about the trigonometric functions sine, cosine, tangent, and their inverses (ideally using degrees, not radians).
                +Blockly.Msg.MATH_TRIG_HELPURL = 'https://en.wikipedia.org/wiki/Trigonometric_functions';
                +/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent sine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_SIN = 'Return the sine of a degree (not radian).';
                +/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent cosine] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_COS = 'Return the cosine of a degree (not radian).';
                +/// tooltip - Return the [https://en.wikipedia.org/wiki/Trigonometric_functions#Sine.2C_cosine_and_tangent tangent] of an [https://en.wikipedia.org/wiki/Degree_(angle) angle in degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_TAN = 'Return the tangent of a degree (not radian).';
                +/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent sine function], using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN = 'Return the arcsine of a number.';
                +/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent cosine] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS = 'Return the arccosine of a number.';
                +/// tooltip - The [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions inverse] of the [https://en.wikipedia.org/wiki/Cosine#Sine.2C_cosine_and_tangent tangent] function, using [https://en.wikipedia.org/wiki/Degree_(angle) degrees], not radians.
                +Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN = 'Return the arctangent of a number.';
                +
                +/// url - Information about the mathematical constants Pi (π), e, the golden ratio (φ), √ 2, √ 1/2, and infinity (∞).
                +Blockly.Msg.MATH_CONSTANT_HELPURL = 'https://en.wikipedia.org/wiki/Mathematical_constant';
                +/// tooltip - Provides the specified [https://en.wikipedia.org/wiki/Mathematical_constant mathematical constant].
                +Blockly.Msg.MATH_CONSTANT_TOOLTIP = 'Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).';
                +/// dropdown - A number is '''even''' if it is a multiple of 2.  For example, 4 is even (yielding true), but 3 is not (false).
                +Blockly.Msg.MATH_IS_EVEN = 'is even';
                +/// dropdown - A number is '''odd''' if it is not a multiple of 2.  For example, 3 is odd (yielding true), but 4 is not (false).  The opposite of "odd" is "even".
                +Blockly.Msg.MATH_IS_ODD = 'is odd';
                +/// dropdown - A number is [https://en.wikipedia.org/wiki/Prime prime] if it cannot be evenly divided by any positive integers except for 1 and itself.  For example, 5 is prime, but 6 is not because 2 × 3 = 6.
                +Blockly.Msg.MATH_IS_PRIME = 'is prime';
                +/// dropdown - A number is '''whole''' if it is an [https://en.wikipedia.org/wiki/Integer integer].  For example, 5 is whole, but 5.1 is not.
                +Blockly.Msg.MATH_IS_WHOLE = 'is whole';
                +/// dropdown - A number is '''positive''' if it is greater than 0.  (0 is neither negative nor positive.)
                +Blockly.Msg.MATH_IS_POSITIVE = 'is positive';
                +/// dropdown - A number is '''negative''' if it is less than 0.  (0 is neither negative nor positive.)
                +Blockly.Msg.MATH_IS_NEGATIVE = 'is negative';
                +/// dropdown - A number x is divisible by y if y goes into x evenly.  For example, 10 is divisible by 5, but 10 is not divisible by 3.
                +Blockly.Msg.MATH_IS_DIVISIBLE_BY = 'is divisible by';
                +/// tooltip - This block lets the user specify via a dropdown menu whether to check if the numeric input is even, odd, prime, whole, positive, negative, or divisible by a given value.
                +Blockly.Msg.MATH_IS_TOOLTIP = 'Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.';
                +
                +/// url - Information about incrementing (increasing the value of) a variable.
                +/// For other languages, just use the translation of the Wikipedia page about
                +/// addition ([https://en.wikipedia.org/wiki/Addition https://en.wikipedia.org/wiki/Addition]).
                +Blockly.Msg.MATH_CHANGE_HELPURL = 'https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter';
                +/// - As in: ''change'' [the value of variable] ''item'' ''by'' 1 (e.g., if the variable named 'item' had the value 5, change it to 6).
                +/// %1 is a variable name.
                +/// %2 is the amount of change.
                +Blockly.Msg.MATH_CHANGE_TITLE = 'change %1 by %2';
                +Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +/// tooltip - This updates the value of the variable by adding to it the following numeric input.\n\nParameters:\n* %1 - the name of the variable whose value should be increased.
                +Blockly.Msg.MATH_CHANGE_TOOLTIP = 'Add a number to variable "%1".';
                +
                +/// url - Information about how numbers are rounded to the nearest integer
                +Blockly.Msg.MATH_ROUND_HELPURL = 'https://en.wikipedia.org/wiki/Rounding';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Rounding https://en.wikipedia.org/wiki/Rounding].
                +Blockly.Msg.MATH_ROUND_TOOLTIP = 'Round a number up or down.';
                +/// dropdown - This rounds its input to the nearest whole number.  For example, 3.4 is rounded to 3.
                +Blockly.Msg.MATH_ROUND_OPERATOR_ROUND = 'round';
                +/// dropdown - This rounds its input up to the nearest whole number.  For example, if the input was 2.2, the result would be 3.
                +Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP = 'round up';
                +/// dropdown - This rounds its input down to the nearest whole number.  For example, if the input was 3.8, the result would be 3.
                +Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN = 'round down';
                +
                +/// url - Information about applying a function to a list of numbers.  (We were unable to find such information in English.  Feel free to skip this and any other URLs that are difficult.)
                +Blockly.Msg.MATH_ONLIST_HELPURL = '';
                +/// dropdown - This computes the sum of the numeric elements in the list.  For example, the sum of the list {1, 4} is 5.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_SUM = 'sum of list';
                +/// tooltip - Please use the same term for "sum" as in the previous message.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM = 'Return the sum of all the numbers in the list.';
                +/// dropdown - This finds the smallest (minimum) number in a list.  For example, the smallest number in the list [-5, 0, 3] is -5.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_MIN = 'min of list';
                +/// tooltip - Please use the same term for "min" or "minimum" as in the previous message.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN = 'Return the smallest number in the list.';
                +/// dropdown - This finds the largest (maximum) number in a list.  For example, the largest number in the list [-5, 0, 3] is 3.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_MAX = 'max of list';
                +/// tooltip
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX = 'Return the largest number in the list.';
                +/// dropdown - This adds up all of the numbers in a list and divides the sum by the number of elements in the list.  For example, the [https://en.wikipedia.org/wiki/Arithmetic_mean average] of the list [1, 2, 3, 4] is 2.5 (10/4).
                +Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE = 'average of list';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Arithmetic_mean https://en.wikipedia.org/wiki/Arithmetic_mean] for more informatin.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE = 'Return the average (arithmetic mean) of the numeric values in the list.';
                +/// dropdown - This finds the [https://en.wikipedia.org/wiki/Median median] of the numeric values in a list.  For example, the median of the list {1, 2, 7, 12, 13} is 7.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN = 'median of list';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Median median https://en.wikipedia.org/wiki/Median median] for more information.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN = 'Return the median number in the list.';
                +/// dropdown - This finds the most common numbers ([https://en.wikipedia.org/wiki/Mode_(statistics) modes]) in a list.  For example, the modes of the list {1, 3, 9, 3, 9}  are {3, 9}.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = 'modes of list';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Mode_(statistics) https://en.wikipedia.org/wiki/Mode_(statistics)] for more information.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE = 'Return a list of the most common item(s) in the list.';
                +/// dropdown - This finds the [https://en.wikipedia.org/wiki/Standard_deviation standard deviation] of the numeric values in a list.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV = 'standard deviation of list';
                +/// tooltip - See [https://en.wikipedia.org/wiki/Standard_deviation https://en.wikipedia.org/wiki/Standard_deviation] for more information.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV = 'Return the standard deviation of the list.';
                +/// dropdown - This choose an element at random from a list.  Each element is chosen with equal probability.
                +Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM = 'random item of list';
                +/// tooltip - Please use same term for 'random' as in previous entry.
                +Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM = 'Return a random element from the list.';
                +
                +/// url - information about the modulo (remainder) operation.
                +Blockly.Msg.MATH_MODULO_HELPURL = 'https://en.wikipedia.org/wiki/Modulo_operation';
                +/// block text - Title of block providing the remainder when dividing the first numerical input by the second.  For example, the remainder of 10 divided by 3 is 1.\n\nParameters:\n* %1 - the dividend (10, in our example)\n* %2 - the divisor (3 in our example).
                +Blockly.Msg.MATH_MODULO_TITLE = 'remainder of %1 ÷ %2';
                +/// tooltip - For example, the remainder of 10 divided by 3 is 1.
                +Blockly.Msg.MATH_MODULO_TOOLTIP = 'Return the remainder from dividing the two numbers.';
                +
                +/// url - Information about constraining a numeric value to be in a specific range.  (The English URL is not ideal.  Recall that translating URLs is the lowest priority.)
                +Blockly.Msg.MATH_CONSTRAIN_HELPURL = 'https://en.wikipedia.org/wiki/Clamping_(graphics)';
                +/// block text - The title of the block that '''constrain'''s (forces) a number to be in a given range.
                +///For example, if the number 150 is constrained to be between 5 and 100, the result will be 100.
                +///\n\nParameters:\n* %1 - the value to constrain (e.g., 150)\n* %2 - the minimum value (e.g., 5)\n* %3 - the maximum value (e.g., 100).
                +Blockly.Msg.MATH_CONSTRAIN_TITLE = 'constrain %1 low %2 high %3';
                +/// tooltip - This compares a number ''x'' to a low value ''L'' and a high value ''H''.  If ''x'' is less then ''L'', the result is ''L''.  If ''x'' is greater than ''H'', the result is ''H''.  Otherwise, the result is ''x''.
                +Blockly.Msg.MATH_CONSTRAIN_TOOLTIP = 'Constrain a number to be between the specified limits (inclusive).';
                +
                +/// url - Information about how computers generate random numbers.
                +Blockly.Msg.MATH_RANDOM_INT_HELPURL = 'https://en.wikipedia.org/wiki/Random_number_generation';
                +/// block text - The title of the block that generates a random integer (whole number) in the specified range.  For example, if the range is from 5 to 7, this returns 5, 6, or 7 with equal likelihood. %1 is a placeholder for the lower number, %2 is the placeholder for the larger number.
                +Blockly.Msg.MATH_RANDOM_INT_TITLE = 'random integer from %1 to %2';
                +/// tooltip - Return a random integer between two values specified as inputs.  For example, if one input was 7 and another 9, any of the numbers 7, 8, or 9 could be produced.
                +Blockly.Msg.MATH_RANDOM_INT_TOOLTIP = 'Return a random integer between the two specified limits, inclusive.';
                +
                +/// url - Information about how computers generate random numbers (specifically, numbers in the range from 0 to just below 1).
                +Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL = 'https://en.wikipedia.org/wiki/Random_number_generation';
                +/// block text - The title of the block that generates a random number greater than or equal to 0 and less than 1.
                +Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM = 'random fraction';
                +/// tooltip - Return a random fraction between 0 and 1.  The value may be equal to 0 but must be less than 1.
                +Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP = 'Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).';
                +
                +// Text Blocks.
                +/// url - Information about how computers represent text (sometimes referred to as ''string''s).
                +Blockly.Msg.TEXT_TEXT_HELPURL = 'https://en.wikipedia.org/wiki/String_(computer_science)';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text https://github.com/google/blockly/wiki/Text].
                +Blockly.Msg.TEXT_TEXT_TOOLTIP = 'A letter, word, or line of text.';
                +
                +/// url - Information on concatenating/appending pieces of text.
                +Blockly.Msg.TEXT_JOIN_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-creation';
                +/// block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation].
                +Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH = 'create text with';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation create text with] for more information.
                +Blockly.Msg.TEXT_JOIN_TOOLTIP = 'Create a piece of text by joining together any number of items.';
                +
                +/// block text - This is shown when the programmer wants to change the number of pieces of text being joined together.  See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.\n{{Identical|Join}}
                +Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN = 'join';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.
                +Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this text block.';
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +/// block text - See [https://github.com/google/blockly/wiki/Text#text-creation https://github.com/google/blockly/wiki/Text#text-creation], specifically the last picture in the 'Text creation' section.
                +Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP = 'Add an item to the text.';
                +
                +/// url - This and the other text-related URLs are going to be hard to translate.  As always, it is okay to leave untranslated or paste in the English-language URL.  For these URLs, you might also consider a general URL about how computers represent text (such as the translation of [https://en.wikipedia.org/wiki/String_(computer_science) this Wikipedia page]).
                +Blockly.Msg.TEXT_APPEND_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-modification';
                +/// block input text - Message that the variable name at %1 will have the item at %2 appended to it.
                +/// [[File:blockly-append-text.png]]
                +Blockly.Msg.TEXT_APPEND_TITLE = 'to %1 append text %2';
                +Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-modification https://github.com/google/blockly/wiki/Text#text-modification] for more information.\n\nParameters:\n* %1 - the name of the variable to which text should be appended
                +Blockly.Msg.TEXT_APPEND_TOOLTIP = 'Append some text to variable "%1".';
                +
                +/// url - Information about text on computers (usually referred to as 'strings').
                +Blockly.Msg.TEXT_LENGTH_HELPURL = 'https://github.com/google/blockly/wiki/Text#text-modification';
                +/// block text - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length].
                +/// \n\nParameters:\n* %1 - the piece of text to take the length of
                +Blockly.Msg.TEXT_LENGTH_TITLE = 'length of %1';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#text-length https://github.com/google/blockly/wiki/Text#text-length].
                +Blockly.Msg.TEXT_LENGTH_TOOLTIP = 'Returns the number of letters (including spaces) in the provided text.';
                +
                +/// url - Information about empty pieces of text on computers (usually referred to as 'empty strings').
                +Blockly.Msg.TEXT_ISEMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Text#checking-for-empty-text';
                +/// block text - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text].
                +/// \n\nParameters:\n* %1 - the piece of text to test for emptiness
                +Blockly.Msg.TEXT_ISEMPTY_TITLE = '%1 is empty';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#checking-for-empty-text https://github.com/google/blockly/wiki/Text#checking-for-empty-text].
                +Blockly.Msg.TEXT_ISEMPTY_TOOLTIP = 'Returns true if the provided text is empty.';
                +
                +/// url - Information about finding a character in a piece of text.
                +Blockly.Msg.TEXT_INDEXOF_HELPURL = 'https://github.com/google/blockly/wiki/Text#finding-text';
                +/// tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode. See [https://github.com/google/blockly/wiki/Text#finding-text https://github.com/google/blockly/wiki/Text#finding-text].
                +Blockly.Msg.TEXT_INDEXOF_TOOLTIP = 'Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.';
                +/// block text - Title of blocks allowing users to find text.  See
                +/// [https://github.com/google/blockly/wiki/Text#finding-text
                +/// https://github.com/google/blockly/wiki/Text#finding-text].
                +/// [[File:Blockly-find-text.png]].
                +/// In English the expanded message is "in text %1 find (first|last) occurance of text %3"
                +/// where %1 and %3 are added by the user. See TEXT_INDEXOF_OPERATOR_FIRST and
                +/// TEXT_INDEXOF_OPERATOR_LAST for the dropdown text that replaces %2.
                +Blockly.Msg.TEXT_INDEXOF_TITLE = 'in text %1 %2 %3';
                +/// dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text
                +/// https://github.com/google/blockly/wiki/Text#finding-text].
                +/// [[File:Blockly-find-text.png]].
                +Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST = 'find first occurrence of text';
                +/// dropdown - See [https://github.com/google/blockly/wiki/Text#finding-text
                +/// https://github.com/google/blockly/wiki/Text#finding-text].  This would
                +/// replace "find first occurrence of text" below.  (For more information on
                +/// how common text is factored out of dropdown menus, see
                +/// [https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus
                +/// https://translatewiki.net/wiki/Translating:Blockly#Drop-Down_Menus)].)
                +/// [[File:Blockly-find-text.png]].
                +Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST = 'find last occurrence of text';
                +
                +/// url - Information about extracting characters (letters, number, symbols, etc.) from text.
                +Blockly.Msg.TEXT_CHARAT_HELPURL = 'https://github.com/google/blockly/wiki/Text#extracting-text';
                +/// block text - Text for a block to extract a letter (or number,
                +/// punctuation character, etc.) from a string, as shown below. %1 is added by
                +/// the user and %2 is replaced by a dropdown of options, possibly followed by
                +/// another user supplied string. TEXT_CHARAT_TAIL is then added to the end.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_TITLE = 'in text %1 %2'
                +/// dropdown - Indicates that the letter (or number, punctuation character, etc.) with the
                +/// specified index should be obtained from the preceding piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_FROM_START = 'get letter #';
                +/// block text - Indicates that the letter (or number, punctuation character, etc.) with the
                +/// specified index from the end of a given piece of text should be obtained. See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_FROM_END = 'get letter # from end';
                +/// block text - Indicates that the first letter of the following piece of text should be
                +/// retrieved.  See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_FIRST = 'get first letter';
                +/// block text - Indicates that the last letter (or number, punctuation mark, etc.) of the
                +/// following piece of text should be retrieved.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_LAST = 'get last letter';
                +/// block text - Indicates that any letter (or number, punctuation mark, etc.) in the
                +/// following piece of text should be randomly selected.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_RANDOM = 'get random letter';
                +/// block text - Text that goes after the rightmost block/dropdown when getting a single letter from
                +/// a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/index.html#3m23km these
                +/// blocks] or shown below.  For most languages, this will be blank.
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_TAIL = '';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-single-character].
                +/// [[File:Blockly-text-get.png]]
                +Blockly.Msg.TEXT_CHARAT_TOOLTIP = 'Returns the letter at the specified position.';
                +
                +/// See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP = 'Returns a specified portion of the text.';
                +/// url - Information about extracting characters from text.  Reminder: urls are the
                +/// lowest priority translations.  Feel free to skip.
                +Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL = 'https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text';
                +/// block text - Precedes a piece of text from which a portion should be extracted.
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT = 'in text';
                +/// dropdown - Indicates that the following number specifies the position (relative to the start
                +/// position) of the beginning of the region of text that should be obtained from the preceding
                +/// piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START = 'get substring from letter #';
                +/// dropdown - Indicates that the following number specifies the position (relative to the end
                +/// position) of the beginning of the region of text that should be obtained from the preceding
                +/// piece of text.  See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
                +/// automatically appear ''after'' this and any other
                +/// [https://translatewiki.net/wiki/Translating:Blockly#Ordinal_numbers ordinal numbers]
                +/// on this block.
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END = 'get substring from letter # from end';
                +/// block text - Indicates that a region starting with the first letter of the preceding piece
                +/// of text should be extracted.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST = 'get substring from first letter';
                +/// dropdown - Indicates that the following number specifies the position (relative to
                +/// the start position) of the end of the region of text that should be obtained from the
                +/// preceding piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START = 'to letter #';
                +/// dropdown - Indicates that the following number specifies the position (relative to the
                +/// end position) of the end of the region of text that should be obtained from the preceding
                +/// piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END = 'to letter # from end';
                +/// block text - Indicates that a region ending with the last letter of the preceding piece
                +/// of text should be extracted.  See
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST = 'to last letter';
                +/// block text - Text that should go after the rightmost block/dropdown when
                +/// [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text
                +/// extracting a region of text].  In most languages, this will be the empty string.
                +/// [[File:Blockly-get-substring.png]]
                +Blockly.Msg.TEXT_GET_SUBSTRING_TAIL = '';
                +
                +/// url - Information about the case of letters (upper-case and lower-case).
                +Blockly.Msg.TEXT_CHANGECASE_HELPURL = 'https://github.com/google/blockly/wiki/Text#adjusting-text-case';
                +/// tooltip - Describes a block to adjust the case of letters.  For more information on this block,
                +/// see [https://github.com/google/blockly/wiki/Text#adjusting-text-case
                +/// https://github.com/google/blockly/wiki/Text#adjusting-text-case].
                +Blockly.Msg.TEXT_CHANGECASE_TOOLTIP = 'Return a copy of the text in a different case.';
                +/// block text - Indicates that all of the letters in the following piece of text should be
                +/// capitalized.  If your language does not use case, you may indicate that this is not
                +/// applicable to your language.  For more information on this block, see
                +/// [https://github.com/google/blockly/wiki/Text#adjusting-text-case
                +/// https://github.com/google/blockly/wiki/Text#adjusting-text-case].
                +Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE = 'to UPPER CASE';
                +/// block text - Indicates that all of the letters in the following piece of text should be converted to lower-case.  If your language does not use case, you may indicate that this is not applicable to your language.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].
                +Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE = 'to lower case';
                +/// block text - Indicates that the first letter of each of the following words should be capitalized and the rest converted to lower-case.  If your language does not use case, you may indicate that this is not applicable to your language.  For more information on this block, see [https://github.com/google/blockly/wiki/Text#adjusting-text-case https://github.com/google/blockly/wiki/Text#adjusting-text-case].
                +Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE = 'to Title Case';
                +
                +/// url - Information about trimming (removing) text off the beginning and ends of pieces of text.
                +Blockly.Msg.TEXT_TRIM_HELPURL = 'https://github.com/google/blockly/wiki/Text#trimming-removing-spaces';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
                +/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
                +Blockly.Msg.TEXT_TRIM_TOOLTIP = 'Return a copy of the text with spaces removed from one or both ends.';
                +/// dropdown - Removes spaces from the beginning and end of a piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
                +/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].  Note that neither
                +/// this nor the other options modify the original piece of text (that follows);
                +/// the block just returns a version of the text without the specified spaces.
                +Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = 'trim spaces from both sides of';
                +/// dropdown - Removes spaces from the beginning of a piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
                +/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
                +/// Note that in right-to-left scripts, this will remove spaces from the right side.
                +Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = 'trim spaces from left side of';
                +/// dropdown - Removes spaces from the end of a piece of text.  See
                +/// [https://github.com/google/blockly/wiki/Text#trimming-removing-spaces
                +/// https://github.com/google/blockly/wiki/Text#trimming-removing-spaces].
                +/// Note that in right-to-left scripts, this will remove spaces from the left side.
                +Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = 'trim spaces from right side of';
                +
                +/// url - Information about displaying text on computers.
                +Blockly.Msg.TEXT_PRINT_HELPURL = 'https://github.com/google/blockly/wiki/Text#printing-text';
                +/// block text - Display the input on the screen.  See
                +/// [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +/// \n\nParameters:\n* %1 - the value to print
                +Blockly.Msg.TEXT_PRINT_TITLE = 'print %1';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +Blockly.Msg.TEXT_PRINT_TOOLTIP = 'Print the specified text, number or other value.';
                +/// url - Information about getting text from users.
                +Blockly.Msg.TEXT_PROMPT_HELPURL = 'https://github.com/google/blockly/wiki/Text#getting-input-from-the-user';
                +/// dropdown - Specifies that a piece of text should be requested from the user with
                +/// the following message.  See [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +Blockly.Msg.TEXT_PROMPT_TYPE_TEXT = 'prompt for text with message';
                +/// dropdown - Specifies that a number should be requested from the user with the
                +/// following message.  See [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER = 'prompt for number with message';
                +/// dropdown - Precedes the message with which the user should be prompted for
                +/// a number.  See [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER = 'Prompt for user for a number.';
                +/// dropdown - Precedes the message with which the user should be prompted for some text.
                +/// See [https://github.com/google/blockly/wiki/Text#printing-text
                +/// https://github.com/google/blockly/wiki/Text#printing-text].
                +Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT = 'Prompt for user for some text.';
                +
                +/// block text - Title of a block that counts the number of instances of
                +/// a smaller pattern (%1) inside a longer string (%2).
                +Blockly.Msg.TEXT_COUNT_MESSAGE0 = 'count %1 in %2';
                +/// url - Information about counting how many times a string appears in another string.
                +Blockly.Msg.TEXT_COUNT_HELPURL = 'https://github.com/google/blockly/wiki/Text#counting-substrings';
                +/// tooltip - Short description of a block that counts how many times some text occurs within some other text.
                +Blockly.Msg.TEXT_COUNT_TOOLTIP = 'Count how many times some text occurs within some other text.';
                +
                +/// block text - Title of a block that returns a copy of text (%3) with all
                +/// instances of some smaller text (%1) replaced with other text (%2).
                +Blockly.Msg.TEXT_REPLACE_MESSAGE0 = 'replace %1 with %2 in %3';
                +/// url - Information about replacing each copy text (or string, in computer lingo) with other text.
                +Blockly.Msg.TEXT_REPLACE_HELPURL = 'https://github.com/google/blockly/wiki/Text#replacing-substrings';
                +/// tooltip - Short description of a block that replaces copies of text in a large text with other text.
                +Blockly.Msg.TEXT_REPLACE_TOOLTIP = 'Replace all occurances of some text within some other text.';
                +
                +/// block text - Title of block that returns a copy of text (%1) with the order
                +/// of letters and characters reversed.
                +Blockly.Msg.TEXT_REVERSE_MESSAGE0 = 'reverse %1';
                +/// url - Information about reversing a letters/characters in text.
                +Blockly.Msg.TEXT_REVERSE_HELPURL = 'https://github.com/google/blockly/wiki/Text#reversing-text';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Text].
                +Blockly.Msg.TEXT_REVERSE_TOOLTIP = 'Reverses the order of the characters in the text.';
                +
                +// Lists Blocks.
                +/// url - Information on empty lists.
                +Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-empty-list';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].
                +Blockly.Msg.LISTS_CREATE_EMPTY_TITLE = 'create empty list';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#create-empty-list https://github.com/google/blockly/wiki/Lists#create-empty-list].
                +Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP = 'Returns a list, of length 0, containing no data records';
                +
                +/// url - Information on building lists.
                +Blockly.Msg.LISTS_CREATE_WITH_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-list-with';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].
                +Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP = 'Create a list with any number of items.';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with https://github.com/google/blockly/wiki/Lists#create-list-with].
                +Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH = 'create list with';
                +/// block text - This appears in a sub-block when [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs changing the number of inputs in a ''''create list with'''' block].\n{{Identical|List}}
                +Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD = 'list';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].
                +Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP = 'Add, remove, or reorder sections to reconfigure this list block.';
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs https://github.com/google/blockly/wiki/Lists#changing-number-of-inputs].
                +Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP = 'Add an item to the list.';
                +
                +/// url - Information about [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].
                +Blockly.Msg.LISTS_REPEAT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#create-list-with';
                +/// url - See [https://github.com/google/blockly/wiki/Lists#create-list-with creating a list with multiple copies of a single item].
                +Blockly.Msg.LISTS_REPEAT_TOOLTIP = 'Creates a list consisting of the given value repeated the specified number of times.';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#create-list-with
                +/// https://github.com/google/blockly/wiki/Lists#create-list-with].
                +///\n\nParameters:\n* %1 - the item (text) to be repeated\n* %2 - the number of times to repeat it
                +Blockly.Msg.LISTS_REPEAT_TITLE = 'create list with item %1 repeated %2 times';
                +
                +/// url - Information about how the length of a list is computed (i.e., by the total number of elements, not the number of different elements).
                +Blockly.Msg.LISTS_LENGTH_HELPURL = 'https://github.com/google/blockly/wiki/Lists#length-of';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of].
                +/// \n\nParameters:\n* %1 - the list whose length is desired
                +Blockly.Msg.LISTS_LENGTH_TITLE = 'length of %1';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#length-of https://github.com/google/blockly/wiki/Lists#length-of Blockly:Lists:length of].
                +Blockly.Msg.LISTS_LENGTH_TOOLTIP = 'Returns the length of a list.';
                +
                +/// url - See [https://github.com/google/blockly/wiki/Lists#is-empty https://github.com/google/blockly/wiki/Lists#is-empty].
                +Blockly.Msg.LISTS_ISEMPTY_HELPURL = 'https://github.com/google/blockly/wiki/Lists#is-empty';
                +/// block text - See [https://github.com/google/blockly/wiki/Lists#is-empty
                +/// https://github.com/google/blockly/wiki/Lists#is-empty].
                +/// \n\nParameters:\n* %1 - the list to test
                +Blockly.Msg.LISTS_ISEMPTY_TITLE = '%1 is empty';
                +/// block tooltip - See [https://github.com/google/blockly/wiki/Lists#is-empty
                +/// https://github.com/google/blockly/wiki/Lists#is-empty].
                +Blockly.Msg.LISTS_ISEMPTY_TOOLTIP = 'Returns true if the list is empty.';
                +
                +/// block text - Title of blocks operating on [https://github.com/google/blockly/wiki/Lists lists].
                +Blockly.Msg.LISTS_INLIST = 'in list';
                +
                +/// url - See [https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list
                +/// https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list].
                +Blockly.Msg.LISTS_INDEX_OF_HELPURL = 'https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list';
                +Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +/// dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
                +/// Lists#finding-items-in-a-list].
                +/// [[File:Blockly-list-find.png]]
                +Blockly.Msg.LISTS_INDEX_OF_FIRST = 'find first occurrence of item';
                +/// dropdown - See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
                +/// https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list].
                +/// [[File:Blockly-list-find.png]]
                +Blockly.Msg.LISTS_INDEX_OF_LAST = 'find last occurrence of item';
                +/// tooltip - %1 will be replaced by either the number 0 or -1 depending on the indexing mode.  See [https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list
                +/// https://github.com/google/blockly/wiki/Lists#finding-items-in-a-list].
                +/// [[File:Blockly-list-find.png]]
                +Blockly.Msg.LISTS_INDEX_OF_TOOLTIP = 'Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.';
                +
                +Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
                +/// dropdown - Indicates that the user wishes to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
                +/// get an item from a list] without removing it from the list.
                +Blockly.Msg.LISTS_GET_INDEX_GET = 'get';
                +/// dropdown - Indicates that the user wishes to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
                +/// get and remove an item from a list], as opposed to merely getting
                +/// it without modifying the list.
                +Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE = 'get and remove';
                +/// dropdown - Indicates that the user wishes to
                +/// [https://github.com/google/blockly/wiki/Lists#removing-an-item
                +/// remove an item from a list].\n{{Identical|Remove}}
                +Blockly.Msg.LISTS_GET_INDEX_REMOVE = 'remove';
                +/// dropdown - Indicates that an index relative to the front of the list should be used to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item get and/or remove
                +/// an item from a list].  Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
                +/// automatically appear ''after'' this number (and any other ordinal numbers on this block).
                +/// See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly.
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_FROM_START = '#';
                +/// dropdown - Indicates that an index relative to the end of the list should be used
                +/// to [https://github.com/google/blockly/wiki/Lists#getting-a-single-item access an item in a list].
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_FROM_END = '# from end';
                +/// dropdown - Indicates that the '''first''' item should be
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_FIRST = 'first';
                +/// dropdown - Indicates that the '''last''' item should be
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_LAST = 'last';
                +/// dropdown - Indicates that a '''random''' item should be
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item accessed in a list].
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_RANDOM = 'random';
                +/// block text - Text that should go after the rightmost block/dropdown when
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-single-item
                +/// accessing an item from a list].  In most languages, this will be the empty string.
                +/// [[File:Blockly-list-get-item.png]]
                +Blockly.Msg.LISTS_GET_INDEX_TAIL = '';
                +Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +/// tooltip - Indicates the ordinal number that the first item in a list is referenced by.  %1 will be replaced by either "#0" or "#1" depending on the indexing mode.
                +Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP = '%1 is the first item.';
                +/// tooltip - Indicates the ordinal number that the last item in a list is referenced by.  %1 will be replaced by either "#0" or "#1" depending on the indexing mode.
                +Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP = '%1 is the last item.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM = 'Returns the item at the specified position in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST = 'Returns the first item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST = 'Returns the last item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for more information.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM = 'Returns a random item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM = 'Removes and returns the item at the specified position in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST = 'Removes and returns the first item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST = 'Removes and returns the last item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM = 'Removes and returns a random item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for '#' or '# from end'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM = 'Removes the item at the specified position in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'first'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST = 'Removes the first item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'last'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST = 'Removes the last item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-and-removing-an-item] (for remove and return) and [https://github.com/google/blockly/wiki/Lists#getting-a-single-item] for 'random'.
                +Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM = 'Removes a random item in a list.';
                +/// url - Information about putting items in lists.
                +Blockly.Msg.LISTS_SET_INDEX_HELPURL = 'https://github.com/google/blockly/wiki/Lists#in-list--set';
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +/// block text - [https://github.com/google/blockly/wiki/Lists#in-list--set
                +/// Replaces an item in a list].
                +/// [[File:Blockly-in-list-set-insert.png]]
                +Blockly.Msg.LISTS_SET_INDEX_SET = 'set';
                +/// block text - [https://github.com/google/blockly/wiki/Lists#in-list--insert-at
                +/// Inserts an item into a list].
                +/// [[File:Blockly-in-list-set-insert.png]]
                +Blockly.Msg.LISTS_SET_INDEX_INSERT = 'insert at';
                +/// block text - The word(s) after the position in the list and before the item to be set/inserted.
                +/// [[File:Blockly-in-list-set-insert.png]]
                +Blockly.Msg.LISTS_SET_INDEX_INPUT_TO = 'as';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM = 'Sets the item at the specified position in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST = 'Sets the first item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = 'Sets the last item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "set" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = 'Sets a random item in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM = 'Inserts the item at the specified position in a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST = 'Inserts the item at the start of a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST = 'Append the item to the end of a list.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-single-item} (even though the page describes the "get" block, the idea is the same for the "insert" block).
                +Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM = 'Inserts the item randomly in a list.';
                +
                +/// url - Information describing extracting a sublist from an existing list.
                +Blockly.Msg.LISTS_GET_SUBLIST_HELPURL = 'https://github.com/google/blockly/wiki/Lists#getting-a-sublist';
                +Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
                +/// dropdown - Indicates that an index relative to the front of the list should be used
                +/// to specify the beginning of the range from which to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
                +/// [[File:Blockly-get-sublist.png]]
                +/// Note: If {{msg-Blockly|ORDINAL_NUMBER_SUFFIX}} is defined, it will
                +/// automatically appear ''after'' this number (and any other ordinal numbers on this block).
                +/// See [[Translating:Blockly#Ordinal_numbers]] for more information on ordinal numbers in Blockly.
                +Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START = 'get sub-list from #';
                +/// dropdown - Indicates that an index relative to the end of the list should be used
                +/// to specify the beginning of the range from which to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
                +Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END = 'get sub-list from # from end';
                +/// dropdown - Indicates that the
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist sublist to extract]
                +/// should begin with the list's first item.
                +Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST = 'get sub-list from first';
                +/// dropdown - Indicates that an index relative to the front of the list should be
                +/// used to specify the end of the range from which to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
                +/// [[File:Blockly-get-sublist.png]]
                +Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START = 'to #';
                +/// dropdown - Indicates that an index relative to the end of the list should be
                +/// used to specify the end of the range from which to
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist get a sublist].
                +/// [[File:Blockly-get-sublist.png]]
                +Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END = 'to # from end';
                +/// dropdown - Indicates that the '''last''' item in the given list should be
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist the end
                +/// of the selected sublist].
                +/// [[File:Blockly-get-sublist.png]]
                +Blockly.Msg.LISTS_GET_SUBLIST_END_LAST = 'to last';
                +/// block text - This appears in the rightmost position ("tail") of the
                +/// sublist block, as described at
                +/// [https://github.com/google/blockly/wiki/Lists#getting-a-sublist
                +/// https://github.com/google/blockly/wiki/Lists#getting-a-sublist].
                +/// In English and most other languages, this is the empty string.
                +/// [[File:Blockly-get-sublist.png]]
                +Blockly.Msg.LISTS_GET_SUBLIST_TAIL = '';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#getting-a-sublist
                +/// https://github.com/google/blockly/wiki/Lists#getting-a-sublist] for more information.
                +/// [[File:Blockly-get-sublist.png]]
                +Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP = 'Creates a copy of the specified portion of a list.';
                +
                +/// {{optional}}\nurl - Information describing sorting a list.
                +Blockly.Msg.LISTS_SORT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#sorting-a-list';
                +/// Sort as type %1 (numeric or alphabetic) in order %2 (ascending or descending) a list of items %3.\n{{Identical|Sort}}
                +Blockly.Msg.LISTS_SORT_TITLE = 'sort %1 %2 %3';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#sorting-a-list].
                +Blockly.Msg.LISTS_SORT_TOOLTIP = 'Sort a copy of a list.';
                +/// sorting order or direction from low to high value for numeric, or A-Z for alphabetic.\n{{Identical|Ascending}}
                +Blockly.Msg.LISTS_SORT_ORDER_ASCENDING = 'ascending';
                +/// sorting order or direction from high to low value for numeric, or Z-A for alphabetic.\n{{Identical|Descending}}
                +Blockly.Msg.LISTS_SORT_ORDER_DESCENDING = 'descending';
                +/// sort by treating each item as a number.
                +Blockly.Msg.LISTS_SORT_TYPE_NUMERIC = 'numeric';
                +/// sort by treating each item alphabetically, case-sensitive.
                +Blockly.Msg.LISTS_SORT_TYPE_TEXT = 'alphabetic';
                +/// sort by treating each item alphabetically, ignoring differences in case.
                +Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE = 'alphabetic, ignore case';
                +
                +/// url - Information describing splitting text into a list, or joining a list into text.
                +Blockly.Msg.LISTS_SPLIT_HELPURL = 'https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists';
                +/// dropdown - Indicates that text will be split up into a list (e.g. "a-b-c" -> ["a", "b", "c"]).
                +Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = 'make list from text';
                +/// dropdown - Indicates that a list will be joined together to form text (e.g. ["a", "b", "c"] -> "a-b-c").
                +Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = 'make text from list';
                +/// block text - Prompts for a letter to be used as a separator when splitting or joining text.
                +Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = 'with delimiter';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#make-list-from-text
                +/// https://github.com/google/blockly/wiki/Lists#make-list-from-text] for more information.
                +Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = 'Split text into a list of texts, breaking at each delimiter.';
                +/// tooltip - See [https://github.com/google/blockly/wiki/Lists#make-text-from-list
                +/// https://github.com/google/blockly/wiki/Lists#make-text-from-list] for more information.
                +Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = 'Join a list of texts into one text, separated by a delimiter.';
                +
                +/// url - Information describing reversing a list.
                +Blockly.Msg.LISTS_REVERSE_HELPURL = 'https://github.com/google/blockly/wiki/Lists#reversing-a-list';
                +/// block text - Title of block that returns a copy of a list (%1) with the order of items reversed.
                +Blockly.Msg.LISTS_REVERSE_MESSAGE0 = 'reverse %1';
                +/// tooltip - Short description for a block that reverses a copy of a list.
                +Blockly.Msg.LISTS_REVERSE_TOOLTIP = 'Reverse a copy of a list.';
                +
                +/// grammar - Text that follows an ordinal number (a number that indicates
                +/// position relative to other numbers).  In most languages, such text appears
                +/// before the number, so this should be blank.  An exception is Hungarian.
                +/// See [[Translating:Blockly#Ordinal_numbers]] for more information.
                +Blockly.Msg.ORDINAL_NUMBER_SUFFIX = '';
                +
                +// Variables Blocks.
                +/// url - Information about ''variables'' in computer programming.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.
                +Blockly.Msg.VARIABLES_GET_HELPURL = 'https://github.com/google/blockly/wiki/Variables#get';
                +/// tooltip - This gets the value of the named variable without modifying it.
                +Blockly.Msg.VARIABLES_GET_TOOLTIP = 'Returns the value of this variable.';
                +/// context menu - Selecting this creates a block to set (change) the value of this variable.
                +/// \n\nParameters:\n* %1 - the name of the variable.
                +Blockly.Msg.VARIABLES_GET_CREATE_SET = 'Create "set %1"';
                +
                +/// url - Information about ''variables'' in computer programming.  Consider using your language's translation of [https://en.wikipedia.org/wiki/Variable_(computer_science) https://en.wikipedia.org/wiki/Variable_(computer_science)], if it exists.
                +Blockly.Msg.VARIABLES_SET_HELPURL = 'https://github.com/google/blockly/wiki/Variables#set';
                +/// block text - Change the value of a mathematical variable: '''set [the value of] x to 7'''.\n\nParameters:\n* %1 - the name of the variable.\n* %2 - the value to be assigned.
                +Blockly.Msg.VARIABLES_SET = 'set %1 to %2';
                +/// tooltip - This initializes or changes the value of the named variable.
                +Blockly.Msg.VARIABLES_SET_TOOLTIP = 'Sets this variable to be equal to the input.';
                +/// context menu - Selecting this creates a block to get (change) the value of
                +/// this variable.\n\nParameters:\n* %1 - the name of the variable.
                +Blockly.Msg.VARIABLES_SET_CREATE_GET = 'Create "get %1"';
                +
                +// Procedures Blocks.
                +/// url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that do not have return values.
                +Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = 'https://en.wikipedia.org/wiki/Subroutine';
                +/// block text - This precedes the name of the function when defining it.  See
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#c84aoc this sample
                +/// function definition].
                +Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = 'to';
                +/// default name - This acts as a placeholder for the name of a function on a
                +/// function definition block, as shown on
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#w7cfju this block].
                +/// The user will replace it with the function's name.
                +Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = 'do something';
                +/// block text - This precedes the list of parameters on a function's defiition block.  See
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
                +/// function with parameters].
                +Blockly.Msg.PROCEDURES_BEFORE_PARAMS = 'with:';
                +/// block text - This precedes the list of parameters on a function's caller block.  See
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
                +/// function with parameters].
                +Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = 'with:';
                +/// block text - This appears next to the function's "body", the blocks that should be
                +/// run when the function is called, as shown in
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample
                +/// function definition].
                +Blockly.Msg.PROCEDURES_DEFNORETURN_DO = '';
                +/// tooltip
                +Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP = 'Creates a function with no output.';
                +/// Placeholder text that the user is encouraged to replace with a description of what their function does.
                +Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = 'Describe this function...';
                +/// url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that have return values.
                +Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL = 'https://en.wikipedia.org/wiki/Subroutine';
                +Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
                +Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
                +Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
                +/// block text - This imperative or infinite verb precedes the value that is used as the return value
                +/// (output) of this function.  See
                +/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#6ot5y5 this sample
                +/// function that returns a value].
                +Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = 'return';
                +/// tooltip
                +Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP = 'Creates a function with an output.';
                +/// Label for a checkbox that controls if statements are allowed in a function.
                +Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = 'allow statements';
                +
                +/// alert - The user has created a function with two parameters that have the same name.  Every parameter must have a different name.
                +Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING = 'Warning: This function has duplicate parameters.';
                +
                +/// url - Information about calling [https://en.wikipedia.org/wiki/Subroutine functions] that do not return values.
                +Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = 'https://en.wikipedia.org/wiki/Subroutine';
                +/// tooltip - This block causes the body (blocks inside) of the named function definition to be run.
                +Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = 'Run the user-defined function "%1".';
                +
                +/// url - Information about calling [https://en.wikipedia.org/wiki/Subroutine functions] that return values.
                +Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = 'https://en.wikipedia.org/wiki/Subroutine';
                +/// tooltip - This block causes the body (blocks inside) of the named function definition to be run.\n\nParameters:\n* %1 - the name of the function.
                +Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = 'Run the user-defined function "%1" and use its output.';
                +
                +/// block text - This text appears on a block in a window that appears when the user clicks
                +/// on the plus sign or star on a function definition block.  It refers to the set of parameters
                +/// (referred to by the simpler term "inputs") to the function.  See
                +/// [[Translating:Blockly#function_definitions]].\n{{Identical|Input}}
                +Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = 'inputs';
                +/// tooltip
                +Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = 'Add, remove, or reorder inputs to this function.';
                +/// block text - This text appears on a block in a window that appears when the user clicks
                +/// on the plus sign or star on a function definition block].  It appears on the block for
                +/// adding an individual parameter (referred to by the simpler term "inputs") to the function.
                +/// See [[Translating:Blockly#function_definitions]].
                +Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = 'input name:';
                +/// tooltip
                +Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = 'Add an input to the function.';
                +
                +/// context menu - This appears on the context menu for function calls.  Selecting
                +/// it causes the corresponding function definition to be highlighted (as shown at
                +/// [[Translating:Blockly#context_menus]].
                +Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF = 'Highlight function definition';
                +/// context menu - This appears on the context menu for function definitions.
                +/// Selecting it creates a block to call the function.\n\nParameters:\n* %1 - the name of the function.\n{{Identical|Create}}
                +Blockly.Msg.PROCEDURES_CREATE_DO = 'Create "%1"';
                +
                +/// tooltip - If the first value is true, this causes the second value to be returned
                +/// immediately from the enclosing function.
                +Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP = 'If a value is true, then return a second value.';
                +/// {{optional}}\nurl - Information about guard clauses.
                +Blockly.Msg.PROCEDURES_IFRETURN_HELPURL = 'http://c2.com/cgi/wiki?GuardClause';
                +/// warning - This appears if the user tries to use this block outside of a function definition.
                +Blockly.Msg.PROCEDURES_IFRETURN_WARNING = 'Warning: This block may be used only within a function definition.';
                diff --git a/blockly/webif/static/blockly/package.json b/blockly/webif/static/blockly/package.json
                new file mode 100644
                index 000000000..95a7ea9eb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/package.json
                @@ -0,0 +1,49 @@
                +{
                +  "name": "blockly",
                +  "version": "1.0.0",
                +  "description": "Blockly is a library for building visual programming editors.",
                +  "keywords": [
                +    "blockly"
                +  ],
                +  "repository": {
                +    "type": "git",
                +    "url": "https://github.com/google/blockly.git"
                +  },
                +  "bugs": {
                +    "url": "https://github.com/google/blockly/issues"
                +  },
                +  "homepage": "https://developers.google.com/blockly/",
                +  "author": {
                +    "name": "Neil Fraser"
                +  },
                +  "scripts": {
                +    "lint": "jshint .",
                +    "pretest": "scripts/test_setup.sh",
                +    "test": "node tests/jsunit/test_runner.js"
                +  },
                +  "license": "Apache-2.0",
                +  "private": true,
                +  "devDependencies": {
                +    "jshint": "latest"
                +  },
                +  "jshintConfig": {
                +    "globalstrict": true,
                +    "predef": [
                +      "Blockly",
                +      "goog",
                +      "window",
                +      "document",
                +      "soy",
                +      "XMLHttpRequest"
                +    ],
                +    "sub": true,
                +    "undef": true,
                +    "unused": true
                +  },
                +  "dependencies": {
                +    "install": "^0.8.8",
                +    "npm": "^4.4.4",
                +    "closure-library": "^1.43629075.2",
                +    "webdriverio": "^4.6.2"
                +  }
                +}
                diff --git a/blockly/webif/static/blockly/php_compressed.js b/blockly/webif/static/blockly/php_compressed.js
                new file mode 100644
                index 000000000..bbf2eecbe
                --- /dev/null
                +++ b/blockly/webif/static/blockly/php_compressed.js
                @@ -0,0 +1,104 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Language
                +
                + Copyright 2015 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.PHP=new Blockly.Generator("PHP");Blockly.PHP.addReservedWords("__halt_compiler,abstract,and,array,as,break,callable,case,catch,class,clone,const,continue,declare,default,die,do,echo,else,elseif,empty,enddeclare,endfor,endforeach,endif,endswitch,endwhile,eval,exit,extends,final,for,foreach,function,global,goto,if,implements,include,include_once,instanceof,insteadof,interface,isset,list,namespace,new,or,print,private,protected,public,require,require_once,return,static,switch,throw,trait,try,unset,use,var,while,xor,PHP_VERSION,PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_VERSION_ID,PHP_EXTRA_VERSION,PHP_ZTS,PHP_DEBUG,PHP_MAXPATHLEN,PHP_OS,PHP_SAPI,PHP_EOL,PHP_INT_MAX,PHP_INT_SIZE,DEFAULT_INCLUDE_PATH,PEAR_INSTALL_DIR,PEAR_EXTENSION_DIR,PHP_EXTENSION_DIR,PHP_PREFIX,PHP_BINDIR,PHP_BINARY,PHP_MANDIR,PHP_LIBDIR,PHP_DATADIR,PHP_SYSCONFDIR,PHP_LOCALSTATEDIR,PHP_CONFIG_FILE_PATH,PHP_CONFIG_FILE_SCAN_DIR,PHP_SHLIB_SUFFIX,E_ERROR,E_WARNING,E_PARSE,E_NOTICE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE,E_DEPRECATED,E_USER_DEPRECATED,E_ALL,E_STRICT,__COMPILER_HALT_OFFSET__,TRUE,FALSE,NULL,__CLASS__,__DIR__,__FILE__,__FUNCTION__,__LINE__,__METHOD__,__NAMESPACE__,__TRAIT__");
                +Blockly.PHP.ORDER_ATOMIC=0;Blockly.PHP.ORDER_CLONE=1;Blockly.PHP.ORDER_NEW=1;Blockly.PHP.ORDER_MEMBER=2.1;Blockly.PHP.ORDER_FUNCTION_CALL=2.2;Blockly.PHP.ORDER_POWER=3;Blockly.PHP.ORDER_INCREMENT=4;Blockly.PHP.ORDER_DECREMENT=4;Blockly.PHP.ORDER_BITWISE_NOT=4;Blockly.PHP.ORDER_CAST=4;Blockly.PHP.ORDER_SUPPRESS_ERROR=4;Blockly.PHP.ORDER_INSTANCEOF=5;Blockly.PHP.ORDER_LOGICAL_NOT=6;Blockly.PHP.ORDER_UNARY_PLUS=7.1;Blockly.PHP.ORDER_UNARY_NEGATION=7.2;Blockly.PHP.ORDER_MULTIPLICATION=8.1;
                +Blockly.PHP.ORDER_DIVISION=8.2;Blockly.PHP.ORDER_MODULUS=8.3;Blockly.PHP.ORDER_ADDITION=9.1;Blockly.PHP.ORDER_SUBTRACTION=9.2;Blockly.PHP.ORDER_STRING_CONCAT=9.3;Blockly.PHP.ORDER_BITWISE_SHIFT=10;Blockly.PHP.ORDER_RELATIONAL=11;Blockly.PHP.ORDER_EQUALITY=12;Blockly.PHP.ORDER_REFERENCE=13;Blockly.PHP.ORDER_BITWISE_AND=13;Blockly.PHP.ORDER_BITWISE_XOR=14;Blockly.PHP.ORDER_BITWISE_OR=15;Blockly.PHP.ORDER_LOGICAL_AND=16;Blockly.PHP.ORDER_LOGICAL_OR=17;Blockly.PHP.ORDER_IF_NULL=18;
                +Blockly.PHP.ORDER_CONDITIONAL=19;Blockly.PHP.ORDER_ASSIGNMENT=20;Blockly.PHP.ORDER_LOGICAL_AND_WEAK=21;Blockly.PHP.ORDER_LOGICAL_XOR=22;Blockly.PHP.ORDER_LOGICAL_OR_WEAK=23;Blockly.PHP.ORDER_COMMA=24;Blockly.PHP.ORDER_NONE=99;
                +Blockly.PHP.ORDER_OVERRIDES=[[Blockly.PHP.ORDER_MEMBER,Blockly.PHP.ORDER_FUNCTION_CALL],[Blockly.PHP.ORDER_MEMBER,Blockly.PHP.ORDER_MEMBER],[Blockly.PHP.ORDER_LOGICAL_NOT,Blockly.PHP.ORDER_LOGICAL_NOT],[Blockly.PHP.ORDER_MULTIPLICATION,Blockly.PHP.ORDER_MULTIPLICATION],[Blockly.PHP.ORDER_ADDITION,Blockly.PHP.ORDER_ADDITION],[Blockly.PHP.ORDER_LOGICAL_AND,Blockly.PHP.ORDER_LOGICAL_AND],[Blockly.PHP.ORDER_LOGICAL_OR,Blockly.PHP.ORDER_LOGICAL_OR]];
                +Blockly.PHP.init=function(a){Blockly.PHP.definitions_=Object.create(null);Blockly.PHP.functionNames_=Object.create(null);Blockly.PHP.variableDB_?Blockly.PHP.variableDB_.reset():Blockly.PHP.variableDB_=new Blockly.Names(Blockly.PHP.RESERVED_WORDS_,"$");var b=[],c;a=Blockly.Variables.allVariables(a);for(var d=0;c=a[d];d++)c=c.name,b[d]=Blockly.PHP.variableDB_.getName(c,Blockly.Variables.NAME_TYPE)+";";Blockly.PHP.definitions_.variables=b.join("\n")};
                +Blockly.PHP.finish=function(a){var b=[],c;for(c in Blockly.PHP.definitions_)b.push(Blockly.PHP.definitions_[c]);delete Blockly.PHP.definitions_;delete Blockly.PHP.functionNames_;Blockly.PHP.variableDB_.reset();return b.join("\n\n")+"\n\n\n"+a};Blockly.PHP.scrubNakedValue=function(a){return a+";\n"};Blockly.PHP.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/'/g,"\\'");return"'"+a+"'"};
                +Blockly.PHP.scrub_=function(a,b){var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();(d=Blockly.utils.wrap(d,Blockly.PHP.COMMENT_WRAP-3))&&(c+=Blockly.PHP.prefixLines(d,"// ")+"\n");for(var e=0;e<a.inputList.length;e++)a.inputList[e].type==Blockly.INPUT_VALUE&&(d=a.inputList[e].connection.targetBlock())&&(d=Blockly.PHP.allNestedComments(d))&&(c+=Blockly.PHP.prefixLines(d,"// "))}e=a.nextConnection&&a.nextConnection.targetBlock();e=Blockly.PHP.blockToCode(e);
                +return c+b+e};
                +Blockly.PHP.getAdjusted=function(a,b,c,d,e){c=c||0;e=e||Blockly.PHP.ORDER_NONE;a.workspace.options.oneBasedIndex&&c--;var g=a.workspace.options.oneBasedIndex?"1":"0";a=0<c?Blockly.PHP.valueToCode(a,b,Blockly.PHP.ORDER_ADDITION)||g:0>c?Blockly.PHP.valueToCode(a,b,Blockly.PHP.ORDER_SUBTRACTION)||g:d?Blockly.PHP.valueToCode(a,b,Blockly.PHP.ORDER_UNARY_NEGATION)||g:Blockly.PHP.valueToCode(a,b,e)||g;if(Blockly.isNumber(a))a=parseFloat(a)+c,d&&(a=-a);else{if(0<c){a=a+" + "+c;var f=Blockly.PHP.ORDER_ADDITION}else 0>c&&
                +(a=a+" - "+-c,f=Blockly.PHP.ORDER_SUBTRACTION);d&&(a=c?"-("+a+")":"-"+a,f=Blockly.PHP.ORDER_UNARY_NEGATION);f=Math.floor(f);e=Math.floor(e);f&&e>=f&&(a="("+a+")")}return a};Blockly.PHP.colour={};Blockly.PHP.colour_picker=function(a){return["'"+a.getFieldValue("COLOUR")+"'",Blockly.PHP.ORDER_ATOMIC]};Blockly.PHP.colour_random=function(a){return[Blockly.PHP.provideFunction_("colour_random",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"() {","  return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);","}"])+"()",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.colour_rgb=function(a){var b=Blockly.PHP.valueToCode(a,"RED",Blockly.PHP.ORDER_COMMA)||0,c=Blockly.PHP.valueToCode(a,"GREEN",Blockly.PHP.ORDER_COMMA)||0;a=Blockly.PHP.valueToCode(a,"BLUE",Blockly.PHP.ORDER_COMMA)||0;return[Blockly.PHP.provideFunction_("colour_rgb",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($r, $g, $b) {","  $r = round(max(min($r, 100), 0) * 2.55);","  $g = round(max(min($g, 100), 0) * 2.55);","  $b = round(max(min($b, 100), 0) * 2.55);","  $hex = '#';","  $hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);",
                +"  $hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);","  $hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);","  return $hex;","}"])+"("+b+", "+c+", "+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.colour_blend=function(a){var b=Blockly.PHP.valueToCode(a,"COLOUR1",Blockly.PHP.ORDER_COMMA)||"'#000000'",c=Blockly.PHP.valueToCode(a,"COLOUR2",Blockly.PHP.ORDER_COMMA)||"'#000000'";a=Blockly.PHP.valueToCode(a,"RATIO",Blockly.PHP.ORDER_COMMA)||.5;return[Blockly.PHP.provideFunction_("colour_blend",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($c1, $c2, $ratio) {","  $ratio = max(min($ratio, 1), 0);","  $r1 = hexdec(substr($c1, 1, 2));","  $g1 = hexdec(substr($c1, 3, 2));","  $b1 = hexdec(substr($c1, 5, 2));",
                +"  $r2 = hexdec(substr($c2, 1, 2));","  $g2 = hexdec(substr($c2, 3, 2));","  $b2 = hexdec(substr($c2, 5, 2));","  $r = round($r1 * (1 - $ratio) + $r2 * $ratio);","  $g = round($g1 * (1 - $ratio) + $g2 * $ratio);","  $b = round($b1 * (1 - $ratio) + $b2 * $ratio);","  $hex = '#';","  $hex .= str_pad(dechex($r), 2, '0', STR_PAD_LEFT);","  $hex .= str_pad(dechex($g), 2, '0', STR_PAD_LEFT);","  $hex .= str_pad(dechex($b), 2, '0', STR_PAD_LEFT);","  return $hex;","}"])+"("+b+", "+c+", "+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.lists={};Blockly.PHP.lists_create_empty=function(a){return["array()",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.PHP.valueToCode(a,"ADD"+c,Blockly.PHP.ORDER_COMMA)||"null";b="array("+b.join(", ")+")";return[b,Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_repeat=function(a){var b=Blockly.PHP.provideFunction_("lists_repeat",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($value, $count) {","  $array = array();","  for ($index = 0; $index < $count; $index++) {","    $array[] = $value;","  }","  return $array;","}"]),c=Blockly.PHP.valueToCode(a,"ITEM",Blockly.PHP.ORDER_COMMA)||"null";a=Blockly.PHP.valueToCode(a,"NUM",Blockly.PHP.ORDER_COMMA)||"0";return[b+"("+c+", "+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_length=function(a){var b=Blockly.PHP.provideFunction_("length",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($value) {","  if (is_string($value)) {","    return strlen($value);","  } else {","    return count($value);","  }","}"]);a=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"''";return[b+"("+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_isEmpty=function(a){return["empty("+(Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_FUNCTION_CALL)||"array()")+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_indexOf=function(a){var b=Blockly.PHP.valueToCode(a,"FIND",Blockly.PHP.ORDER_NONE)||"''",c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_MEMBER)||"[]";if(a.workspace.options.oneBasedIndex){var d=" 0";var e=" + 1"}else d=" -1",e="";return[("FIRST"==a.getFieldValue("END")?Blockly.PHP.provideFunction_("indexOf",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($haystack, $needle) {","  for ($index = 0; $index < count($haystack); $index++) {","    if ($haystack[$index] == $needle) return $index"+
                +e+";","  }","  return "+d+";","}"]):Blockly.PHP.provideFunction_("lastIndexOf",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($haystack, $needle) {","  $last = "+d+";","  for ($index = 0; $index < count($haystack); $index++) {","    if ($haystack[$index] == $needle) $last = $index"+e+";","  }","  return $last;","}"]))+"("+c+", "+b+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_getIndex=function(a){var b=a.getFieldValue("MODE")||"GET";switch(a.getFieldValue("WHERE")||"FROM_START"){case "FIRST":if("GET"==b){var c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_MEMBER)||"array()";return[c+"[0]",Blockly.PHP.ORDER_MEMBER]}if("GET_REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"array()",["array_shift("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL];if("REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||
                +"array()","array_shift("+c+");\n";break;case "LAST":if("GET"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"array()",["end("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL];if("GET_REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"array()",["array_pop("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL];if("REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"array()","array_pop("+c+");\n";break;case "FROM_START":var d=Blockly.PHP.getAdjusted(a,
                +"AT");if("GET"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_MEMBER)||"array()",[c+"["+d+"]",Blockly.PHP.ORDER_MEMBER];if("GET_REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_COMMA)||"array()",["array_splice("+c+", "+d+", 1)[0]",Blockly.PHP.ORDER_FUNCTION_CALL];if("REMOVE"==b)return c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_COMMA)||"array()","array_splice("+c+", "+d+", 1);\n";break;case "FROM_END":if("GET"==b)return c=Blockly.PHP.valueToCode(a,
                +"VALUE",Blockly.PHP.ORDER_COMMA)||"array()",d=Blockly.PHP.getAdjusted(a,"AT",1,!0),["array_slice("+c+", "+d+", 1)[0]",Blockly.PHP.ORDER_FUNCTION_CALL];if("GET_REMOVE"==b||"REMOVE"==b){c=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"array()";d=Blockly.PHP.getAdjusted(a,"AT",1,!1,Blockly.PHP.ORDER_SUBTRACTION);c="array_splice("+c+", count("+c+") - "+d+", 1)[0]";if("GET_REMOVE"==b)return[c,Blockly.PHP.ORDER_FUNCTION_CALL];if("REMOVE"==b)return c+";\n"}break;case "RANDOM":c=Blockly.PHP.valueToCode(a,
                +"VALUE",Blockly.PHP.ORDER_NONE)||"array()";if("GET"==b)return b=Blockly.PHP.provideFunction_("lists_get_random_item",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($list) {","  return $list[rand(0,count($list)-1)];","}"]),[b+"("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL];if("GET_REMOVE"==b)return b=Blockly.PHP.provideFunction_("lists_get_remove_random_item",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"(&$list) {","  $x = rand(0,count($list)-1);","  unset($list[$x]);","  return array_values($list);",
                +"}"]),[b+"("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL];if("REMOVE"==b)return b=Blockly.PHP.provideFunction_("lists_remove_random_item",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"(&$list) {","  unset($list[rand(0,count($list)-1)]);","}"]),b+"("+c+");\n"}throw"Unhandled combination (lists_getIndex).";};
                +Blockly.PHP.lists_setIndex=function(a){var b=a.getFieldValue("MODE")||"GET";var c=a.getFieldValue("WHERE")||"FROM_START";var d=Blockly.PHP.valueToCode(a,"TO",Blockly.PHP.ORDER_ASSIGNMENT)||"null";switch(c){case "FIRST":if("SET"==b)return c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_MEMBER)||"array()",c+"[0] = "+d+";\n";if("INSERT"==b)return c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"array()","array_unshift("+c+", "+d+");\n";break;case "LAST":c=Blockly.PHP.valueToCode(a,
                +"LIST",Blockly.PHP.ORDER_COMMA)||"array()";if("SET"==b)return b=Blockly.PHP.provideFunction_("lists_set_last_item",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"(&$list, $value) {","  $list[count($list) - 1] = $value;","}"]),b+"("+c+", "+d+");\n";if("INSERT"==b)return"array_push("+c+", "+d+");\n";break;case "FROM_START":var e=Blockly.PHP.getAdjusted(a,"AT");if("SET"==b)return c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_MEMBER)||"array()",c+"["+e+"] = "+d+";\n";if("INSERT"==b)return c=
                +Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"array()","array_splice("+c+", "+e+", 0, "+d+");\n";break;case "FROM_END":c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"array()";e=Blockly.PHP.getAdjusted(a,"AT",1);if("SET"==b)return b=Blockly.PHP.provideFunction_("lists_set_from_end",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"(&$list, $at, $value) {","  $list[count($list) - $at] = $value;","}"]),b+"("+c+", "+e+", "+d+");\n";if("INSERT"==b)return b=Blockly.PHP.provideFunction_("lists_insert_from_end",
                +["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"(&$list, $at, $value) {","  return array_splice($list, count($list) - $at, 0, $value);","}"]),b+"("+c+", "+e+", "+d+");\n";break;case "RANDOM":c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_REFERENCE)||"array()";c.match(/^\$\w+$/)?a="":(a=Blockly.PHP.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),e=a+" = &"+c+";\n",c=a,a=e);e=Blockly.PHP.variableDB_.getDistinctName("tmp_x",Blockly.Variables.NAME_TYPE);a+=e+" = rand(0, count("+
                +c+")-1);\n";if("SET"==b)return a+(c+"["+e+"] = "+d+";\n");if("INSERT"==b)return a+("array_splice("+c+", "+e+", 0, "+d+");\n")}throw"Unhandled combination (lists_setIndex).";};
                +Blockly.PHP.lists_getSublist=function(a){var b=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"array()";var c=a.getFieldValue("WHERE1");var d=a.getFieldValue("WHERE2");if("FIRST"==c&&"LAST"==d)var e=b;else if(b.match(/^\$\w+$/)||"FROM_END"!=c&&"FROM_START"==d){switch(c){case "FROM_START":e=Blockly.PHP.getAdjusted(a,"AT1");break;case "FROM_END":e=Blockly.PHP.getAdjusted(a,"AT1",1,!1,Blockly.PHP.ORDER_SUBTRACTION);e="count("+b+") - "+e;break;case "FIRST":e="0";break;default:throw"Unhandled option (lists_getSublist).";
                +}switch(d){case "FROM_START":a=Blockly.PHP.getAdjusted(a,"AT2",0,!1,Blockly.PHP.ORDER_SUBTRACTION);c=a+" - ";c=Blockly.isNumber(String(e))||String(e).match(/^\(.+\)$/)?c+e:c+("("+e+")");c+=" + 1";break;case "FROM_END":a=Blockly.PHP.getAdjusted(a,"AT2",0,!1,Blockly.PHP.ORDER_SUBTRACTION);c="count("+b+") - "+a+" - ";c=Blockly.isNumber(String(e))||String(e).match(/^\(.+\)$/)?c+e:c+("("+e+")");break;case "LAST":c="count("+b+") - ";c=Blockly.isNumber(String(e))||String(e).match(/^\(.+\)$/)?c+e:c+("("+
                +e+")");break;default:throw"Unhandled option (lists_getSublist).";}e="array_slice("+b+", "+e+", "+c+")"}else e=Blockly.PHP.getAdjusted(a,"AT1"),a=Blockly.PHP.getAdjusted(a,"AT2"),e=Blockly.PHP.provideFunction_("lists_get_sublist",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($list, $where1, $at1, $where2, $at2) {","  if ($where1 == 'FROM_END') {","    $at1 = count($list) - 1 - $at1;","  } else if ($where1 == 'FIRST') {","    $at1 = 0;","  } else if ($where1 != 'FROM_START'){","    throw new Exception('Unhandled option (lists_get_sublist).');",
                +"  }","  $length = 0;","  if ($where2 == 'FROM_START') {","    $length = $at2 - $at1 + 1;","  } else if ($where2 == 'FROM_END') {","    $length = count($list) - $at1 - $at2;","  } else if ($where2 == 'LAST') {","    $length = count($list) - $at1;","  } else {","    throw new Exception('Unhandled option (lists_get_sublist).');","  }","  return array_slice($list, $at1, $length);","}"])+"("+b+", '"+c+"', "+e+", '"+d+"', "+a+")";return[e,Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_sort=function(a){var b=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"array()",c="1"===a.getFieldValue("DIRECTION")?1:-1;a=a.getFieldValue("TYPE");return[Blockly.PHP.provideFunction_("lists_sort",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($list, $type, $direction) {","  $sortCmpFuncs = array(",'    "NUMERIC" => "strnatcasecmp",','    "TEXT" => "strcmp",','    "IGNORE_CASE" => "strcasecmp"',"  );","  $sortCmp = $sortCmpFuncs[$type];","  $list2 = $list;","  usort($list2, $sortCmp);",
                +"  if ($direction == -1) {","    $list2 = array_reverse($list2);","  }","  return $list2;","}"])+"("+b+', "'+a+'", '+c+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.lists_split=function(a){var b=Blockly.PHP.valueToCode(a,"INPUT",Blockly.PHP.ORDER_COMMA),c=Blockly.PHP.valueToCode(a,"DELIM",Blockly.PHP.ORDER_COMMA)||"''";a=a.getFieldValue("MODE");if("SPLIT"==a)b||(b="''"),a="explode";else if("JOIN"==a)b||(b="array()"),a="implode";else throw"Unknown mode: "+a;return[a+"("+c+", "+b+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.lists_reverse=function(a){return["array_reverse("+(Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_COMMA)||"[]")+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.logic={};Blockly.PHP.controls_if=function(a){var b=0,c="";do{var d=Blockly.PHP.valueToCode(a,"IF"+b,Blockly.PHP.ORDER_NONE)||"false";var e=Blockly.PHP.statementToCode(a,"DO"+b);c+=(0<b?" else ":"")+"if ("+d+") {\n"+e+"}";++b}while(a.getInput("IF"+b));a.getInput("ELSE")&&(e=Blockly.PHP.statementToCode(a,"ELSE"),c+=" else {\n"+e+"}");return c+"\n"};Blockly.PHP.controls_ifelse=Blockly.PHP.controls_if;
                +Blockly.PHP.logic_compare=function(a){var b={EQ:"==",NEQ:"!=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c="=="==b||"!="==b?Blockly.PHP.ORDER_EQUALITY:Blockly.PHP.ORDER_RELATIONAL,d=Blockly.PHP.valueToCode(a,"A",c)||"0";a=Blockly.PHP.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
                +Blockly.PHP.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"&&":"||",c="&&"==b?Blockly.PHP.ORDER_LOGICAL_AND:Blockly.PHP.ORDER_LOGICAL_OR,d=Blockly.PHP.valueToCode(a,"A",c);a=Blockly.PHP.valueToCode(a,"B",c);if(d||a){var e="&&"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]};Blockly.PHP.logic_negate=function(a){var b=Blockly.PHP.ORDER_LOGICAL_NOT;return["!"+(Blockly.PHP.valueToCode(a,"BOOL",b)||"true"),b]};
                +Blockly.PHP.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.PHP.ORDER_ATOMIC]};Blockly.PHP.logic_null=function(a){return["null",Blockly.PHP.ORDER_ATOMIC]};Blockly.PHP.logic_ternary=function(a){var b=Blockly.PHP.valueToCode(a,"IF",Blockly.PHP.ORDER_CONDITIONAL)||"false",c=Blockly.PHP.valueToCode(a,"THEN",Blockly.PHP.ORDER_CONDITIONAL)||"null";a=Blockly.PHP.valueToCode(a,"ELSE",Blockly.PHP.ORDER_CONDITIONAL)||"null";return[b+" ? "+c+" : "+a,Blockly.PHP.ORDER_CONDITIONAL]};Blockly.PHP.loops={};
                +Blockly.PHP.controls_repeat_ext=function(a){var b=a.getField("TIMES")?String(Number(a.getFieldValue("TIMES"))):Blockly.PHP.valueToCode(a,"TIMES",Blockly.PHP.ORDER_ASSIGNMENT)||"0";var c=Blockly.PHP.statementToCode(a,"DO"),c=Blockly.PHP.addLoopTrap(c,a.id),d="",e=Blockly.PHP.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE);a=b;b.match(/^\w+$/)||Blockly.isNumber(b)||(a=Blockly.PHP.variableDB_.getDistinctName("repeat_end",Blockly.Variables.NAME_TYPE),d+=a+" = "+b+";\n");return d+("for ("+
                +e+" = 0; "+e+" < "+a+"; "+e+"++) {\n"+c+"}\n")};Blockly.PHP.controls_repeat=Blockly.PHP.controls_repeat_ext;Blockly.PHP.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.PHP.valueToCode(a,"BOOL",b?Blockly.PHP.ORDER_LOGICAL_NOT:Blockly.PHP.ORDER_NONE)||"false",d=Blockly.PHP.statementToCode(a,"DO"),d=Blockly.PHP.addLoopTrap(d,a.id);b&&(c="!"+c);return"while ("+c+") {\n"+d+"}\n"};
                +Blockly.PHP.controls_for=function(a){var b=Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);var c=Blockly.PHP.valueToCode(a,"FROM",Blockly.PHP.ORDER_ASSIGNMENT)||"0";var d=Blockly.PHP.valueToCode(a,"TO",Blockly.PHP.ORDER_ASSIGNMENT)||"0",e=Blockly.PHP.valueToCode(a,"BY",Blockly.PHP.ORDER_ASSIGNMENT)||"1",g=Blockly.PHP.statementToCode(a,"DO"),g=Blockly.PHP.addLoopTrap(g,a.id);if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&Blockly.isNumber(e)){var f=parseFloat(c)<=parseFloat(d);
                +a="for ("+b+" = "+c+"; "+b+(f?" <= ":" >= ")+d+"; "+b;b=Math.abs(parseFloat(e));a=(1==b?a+(f?"++":"--"):a+((f?" += ":" -= ")+b))+(") {\n"+g+"}\n")}else a="",f=c,c.match(/^\w+$/)||Blockly.isNumber(c)||(f=Blockly.PHP.variableDB_.getDistinctName(b+"_start",Blockly.Variables.NAME_TYPE),a+=f+" = "+c+";\n"),c=d,d.match(/^\w+$/)||Blockly.isNumber(d)||(c=Blockly.PHP.variableDB_.getDistinctName(b+"_end",Blockly.Variables.NAME_TYPE),a+=c+" = "+d+";\n"),d=Blockly.PHP.variableDB_.getDistinctName(b+"_inc",Blockly.Variables.NAME_TYPE),
                +a+=d+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+";\n"):a+("abs("+e+");\n"),a=a+("if ("+f+" > "+c+") {\n")+(Blockly.PHP.INDENT+d+" = -"+d+";\n"),a+="}\n",a+="for ("+b+" = "+f+"; "+d+" >= 0 ? "+b+" <= "+c+" : "+b+" >= "+c+"; "+b+" += "+d+") {\n"+g+"}\n";return a};
                +Blockly.PHP.controls_forEach=function(a){var b=Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_ASSIGNMENT)||"[]",d=Blockly.PHP.statementToCode(a,"DO"),d=Blockly.PHP.addLoopTrap(d,a.id);return""+("foreach ("+c+" as "+b+") {\n"+d+"}\n")};
                +Blockly.PHP.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break;\n";case "CONTINUE":return"continue;\n"}throw"Unknown flow statement.";};Blockly.PHP.math={};Blockly.PHP.math_number=function(a){a=parseFloat(a.getFieldValue("NUM"));Infinity==a?a="INF":-Infinity==a&&(a="-INF");return[a,Blockly.PHP.ORDER_ATOMIC]};
                +Blockly.PHP.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.PHP.ORDER_ADDITION],MINUS:[" - ",Blockly.PHP.ORDER_SUBTRACTION],MULTIPLY:[" * ",Blockly.PHP.ORDER_MULTIPLICATION],DIVIDE:[" / ",Blockly.PHP.ORDER_DIVISION],POWER:[" ** ",Blockly.PHP.ORDER_POWER]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.PHP.valueToCode(a,"A",b)||"0";a=Blockly.PHP.valueToCode(a,"B",b)||"0";return[d+c+a,b]};
                +Blockly.PHP.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b)return a=Blockly.PHP.valueToCode(a,"NUM",Blockly.PHP.ORDER_UNARY_NEGATION)||"0","-"==a[0]&&(a=" "+a),["-"+a,Blockly.PHP.ORDER_UNARY_NEGATION];a="SIN"==b||"COS"==b||"TAN"==b?Blockly.PHP.valueToCode(a,"NUM",Blockly.PHP.ORDER_DIVISION)||"0":Blockly.PHP.valueToCode(a,"NUM",Blockly.PHP.ORDER_NONE)||"0";switch(b){case "ABS":var c="abs("+a+")";break;case "ROOT":c="sqrt("+a+")";break;case "LN":c="log("+a+")";break;case "EXP":c="exp("+
                +a+")";break;case "POW10":c="pow(10,"+a+")";break;case "ROUND":c="round("+a+")";break;case "ROUNDUP":c="ceil("+a+")";break;case "ROUNDDOWN":c="floor("+a+")";break;case "SIN":c="sin("+a+" / 180 * pi())";break;case "COS":c="cos("+a+" / 180 * pi())";break;case "TAN":c="tan("+a+" / 180 * pi())"}if(c)return[c,Blockly.PHP.ORDER_FUNCTION_CALL];switch(b){case "LOG10":c="log("+a+") / log(10)";break;case "ASIN":c="asin("+a+") / pi() * 180";break;case "ACOS":c="acos("+a+") / pi() * 180";break;case "ATAN":c="atan("+
                +a+") / pi() * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.PHP.ORDER_DIVISION]};Blockly.PHP.math_constant=function(a){return{PI:["M_PI",Blockly.PHP.ORDER_ATOMIC],E:["M_E",Blockly.PHP.ORDER_ATOMIC],GOLDEN_RATIO:["(1 + sqrt(5)) / 2",Blockly.PHP.ORDER_DIVISION],SQRT2:["M_SQRT2",Blockly.PHP.ORDER_ATOMIC],SQRT1_2:["M_SQRT1_2",Blockly.PHP.ORDER_ATOMIC],INFINITY:["INF",Blockly.PHP.ORDER_ATOMIC]}[a.getFieldValue("CONSTANT")]};
                +Blockly.PHP.math_number_property=function(a){var b=Blockly.PHP.valueToCode(a,"NUMBER_TO_CHECK",Blockly.PHP.ORDER_MODULUS)||"0",c=a.getFieldValue("PROPERTY");if("PRIME"==c)return[Blockly.PHP.provideFunction_("math_isPrime",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($n) {","  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods","  if ($n == 2 || $n == 3) {","    return true;","  }","  // False if n is NaN, negative, is 1, or not whole.","  // And false if n is divisible by 2 or 3.",
                +"  if (!is_numeric($n) || $n <= 1 || $n % 1 != 0 || $n % 2 == 0 || $n % 3 == 0) {","    return false;","  }","  // Check all the numbers of form 6k +/- 1, up to sqrt(n).","  for ($x = 6; $x <= sqrt($n) + 1; $x += 6) {","    if ($n % ($x - 1) == 0 || $n % ($x + 1) == 0) {","      return false;","    }","  }","  return true;","}"])+"("+b+")",Blockly.JavaScript.ORDER_FUNCTION_CALL];switch(c){case "EVEN":var d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d="is_int("+b+")";break;case "POSITIVE":d=
                +b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.PHP.valueToCode(a,"DIVISOR",Blockly.PHP.ORDER_MODULUS)||"0",d=b+" % "+a+" == 0"}return[d,Blockly.PHP.ORDER_EQUALITY]};Blockly.PHP.math_change=function(a){var b=Blockly.PHP.valueToCode(a,"DELTA",Blockly.PHP.ORDER_ADDITION)||"0";return Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" += "+b+";\n"};Blockly.PHP.math_round=Blockly.PHP.math_single;Blockly.PHP.math_trig=Blockly.PHP.math_single;
                +Blockly.PHP.math_on_list=function(a){var b=a.getFieldValue("OP");switch(b){case "SUM":a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_FUNCTION_CALL)||"array()";a="array_sum("+a+")";break;case "MIN":a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_FUNCTION_CALL)||"array()";a="min("+a+")";break;case "MAX":a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_FUNCTION_CALL)||"array()";a="max("+a+")";break;case "AVERAGE":b=Blockly.PHP.provideFunction_("math_mean",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+
                +"($myList) {","  return array_sum($myList) / count($myList);","}"]);a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_NONE)||"array()";a=b+"("+a+")";break;case "MEDIAN":b=Blockly.PHP.provideFunction_("math_median",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($arr) {","  sort($arr,SORT_NUMERIC);","  return (count($arr) % 2) ? $arr[floor(count($arr)/2)] : ","      ($arr[floor(count($arr)/2)] + $arr[floor(count($arr)/2) - 1]) / 2;","}"]);a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_NONE)||
                +"[]";a=b+"("+a+")";break;case "MODE":b=Blockly.PHP.provideFunction_("math_modes",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($values) {","  if (empty($values)) return array();","  $counts = array_count_values($values);","  arsort($counts); // Sort counts in descending order","  $modes = array_keys($counts, current($counts), true);","  return $modes;","}"]);a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "STD_DEV":b=Blockly.PHP.provideFunction_("math_standard_deviation",
                +["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($numbers) {","  $n = count($numbers);","  if (!$n) return null;","  $mean = array_sum($numbers) / count($numbers);","  foreach($numbers as $key => $num) $devs[$key] = pow($num - $mean, 2);","  return sqrt(array_sum($devs) / (count($devs) - 1));","}"]);a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_NONE)||"[]";a=b+"("+a+")";break;case "RANDOM":b=Blockly.PHP.provideFunction_("math_random_list",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+
                +"($list) {","  $x = rand(0, count($list)-1);","  return $list[$x];","}"]);a=Blockly.PHP.valueToCode(a,"LIST",Blockly.PHP.ORDER_NONE)||"[]";a=b+"("+a+")";break;default:throw"Unknown operator: "+b;}return[a,Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.math_modulo=function(a){var b=Blockly.PHP.valueToCode(a,"DIVIDEND",Blockly.PHP.ORDER_MODULUS)||"0";a=Blockly.PHP.valueToCode(a,"DIVISOR",Blockly.PHP.ORDER_MODULUS)||"0";return[b+" % "+a,Blockly.PHP.ORDER_MODULUS]};
                +Blockly.PHP.math_constrain=function(a){var b=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_COMMA)||"0",c=Blockly.PHP.valueToCode(a,"LOW",Blockly.PHP.ORDER_COMMA)||"0";a=Blockly.PHP.valueToCode(a,"HIGH",Blockly.PHP.ORDER_COMMA)||"Infinity";return["min(max("+b+", "+c+"), "+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.math_random_int=function(a){var b=Blockly.PHP.valueToCode(a,"FROM",Blockly.PHP.ORDER_COMMA)||"0";a=Blockly.PHP.valueToCode(a,"TO",Blockly.PHP.ORDER_COMMA)||"0";return[Blockly.PHP.provideFunction_("math_random_int",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($a, $b) {","  if ($a > $b) {","    return rand($b, $a);","  }","  return rand($a, $b);","}"])+"("+b+", "+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.math_random_float=function(a){return["(float)rand()/(float)getrandmax()",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.procedures={};
                +Blockly.PHP.procedures_defreturn=function(a){for(var b=[],c,d=a.workspace.getAllVariables()||[],e=0;c=d[e];e++)c=c.name,-1==a.arguments_.indexOf(c)&&b.push(Blockly.PHP.variableDB_.getName(c,Blockly.Variables.NAME_TYPE));b=b.length?"  global "+b.join(", ")+";\n":"";d=Blockly.PHP.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE);c=Blockly.PHP.statementToCode(a,"STACK");Blockly.PHP.STATEMENT_PREFIX&&(c=Blockly.PHP.prefixLines(Blockly.PHP.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+
                +"'"),Blockly.PHP.INDENT)+c);Blockly.PHP.INFINITE_LOOP_TRAP&&(c=Blockly.PHP.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var g=Blockly.PHP.valueToCode(a,"RETURN",Blockly.PHP.ORDER_NONE)||"";g&&(g="  return "+g+";\n");for(var f=[],e=0;e<a.arguments_.length;e++)f[e]=Blockly.PHP.variableDB_.getName(a.arguments_[e],Blockly.Variables.NAME_TYPE);b="function "+d+"("+f.join(", ")+") {\n"+b+c+g+"}";b=Blockly.PHP.scrub_(a,b);Blockly.PHP.definitions_["%"+d]=b;return null};
                +Blockly.PHP.procedures_defnoreturn=Blockly.PHP.procedures_defreturn;Blockly.PHP.procedures_callreturn=function(a){for(var b=Blockly.PHP.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.PHP.valueToCode(a,"ARG"+d,Blockly.PHP.ORDER_COMMA)||"null";return[b+"("+c.join(", ")+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.procedures_callnoreturn=function(a){for(var b=Blockly.PHP.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.PHP.valueToCode(a,"ARG"+d,Blockly.PHP.ORDER_COMMA)||"null";return b+"("+c.join(", ")+");\n"};
                +Blockly.PHP.procedures_ifreturn=function(a){var b="if ("+(Blockly.PHP.valueToCode(a,"CONDITION",Blockly.PHP.ORDER_NONE)||"false")+") {\n";a.hasReturnValue_?(a=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"null",b+="  return "+a+";\n"):b+="  return;\n";return b+"}\n"};Blockly.PHP.texts={};Blockly.PHP.text=function(a){return[Blockly.PHP.quote_(a.getFieldValue("TEXT")),Blockly.PHP.ORDER_ATOMIC]};
                +Blockly.PHP.text_join=function(a){if(0==a.itemCount_)return["''",Blockly.PHP.ORDER_ATOMIC];if(1==a.itemCount_)return[Blockly.PHP.valueToCode(a,"ADD0",Blockly.PHP.ORDER_NONE)||"''",Blockly.PHP.ORDER_FUNCTION_CALL];if(2==a.itemCount_){var b=Blockly.PHP.valueToCode(a,"ADD0",Blockly.PHP.ORDER_NONE)||"''";a=Blockly.PHP.valueToCode(a,"ADD1",Blockly.PHP.ORDER_NONE)||"''";return[b+" . "+a,Blockly.PHP.ORDER_ADDITION]}for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.PHP.valueToCode(a,"ADD"+
                +c,Blockly.PHP.ORDER_COMMA)||"''";return["implode('', array("+b.join(",")+"))",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_append=function(a){var b=Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);a=Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_ASSIGNMENT)||"''";return b+" .= "+a+";\n"};
                +Blockly.PHP.text_length=function(a){var b=Blockly.PHP.provideFunction_("length",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($value) {","  if (is_string($value)) {","    return strlen($value);","  } else {","    return count($value);","  }","}"]);a=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"''";return[b+"("+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_isEmpty=function(a){return["empty("+(Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"''")+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"strpos":"strrpos",c=Blockly.PHP.valueToCode(a,"FIND",Blockly.PHP.ORDER_NONE)||"''",d=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_NONE)||"''";if(a.workspace.options.oneBasedIndex){var e=" 0";var g=" + 1"}else e=" -1",g="";return[Blockly.PHP.provideFunction_("FIRST"==a.getFieldValue("END")?"text_indexOf":"text_lastIndexOf",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($text, $search) {","  $pos = "+b+"($text, $search);",
                +"  return $pos === false ? "+e+" : $pos"+g+";","}"])+"("+d+", "+c+")",Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.PHP.valueToCode(a,"VALUE","RANDOM"==b?Blockly.PHP.ORDER_NONE:Blockly.PHP.ORDER_COMMA)||"''";switch(b){case "FIRST":return["substr("+c+", 0, 1)",Blockly.PHP.ORDER_FUNCTION_CALL];case "LAST":return["substr("+c+", -1)",Blockly.PHP.ORDER_FUNCTION_CALL];case "FROM_START":return a=Blockly.PHP.getAdjusted(a,"AT"),["substr("+c+", "+a+", 1)",Blockly.PHP.ORDER_FUNCTION_CALL];case "FROM_END":return a=Blockly.PHP.getAdjusted(a,
                +"AT",1,!0),["substr("+c+", "+a+", 1)",Blockly.PHP.ORDER_FUNCTION_CALL];case "RANDOM":return[Blockly.PHP.provideFunction_("text_random_letter",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($text) {","  return $text[rand(0, strlen($text) - 1)];","}"])+"("+c+")",Blockly.PHP.ORDER_FUNCTION_CALL]}throw"Unhandled option (text_charAt).";};
                +Blockly.PHP.text_getSubstring=function(a){var b=Blockly.PHP.valueToCode(a,"STRING",Blockly.PHP.ORDER_FUNCTION_CALL)||"''";var c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");if("FIRST"!=c||"LAST"!=d){var e=Blockly.PHP.getAdjusted(a,"AT1");a=Blockly.PHP.getAdjusted(a,"AT2");b=Blockly.PHP.provideFunction_("text_get_substring",["function "+Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_+"($text, $where1, $at1, $where2, $at2) {","  if ($where1 == 'FROM_END') {","    $at1 = strlen($text) - 1 - $at1;","  } else if ($where1 == 'FIRST') {",
                +"    $at1 = 0;","  } else if ($where1 != 'FROM_START'){","    throw new Exception('Unhandled option (text_get_substring).');","  }","  $length = 0;","  if ($where2 == 'FROM_START') {","    $length = $at2 - $at1 + 1;","  } else if ($where2 == 'FROM_END') {","    $length = strlen($text) - $at1 - $at2;","  } else if ($where2 == 'LAST') {","    $length = strlen($text) - $at1;","  } else {","    throw new Exception('Unhandled option (text_get_substring).');","  }","  return substr($text, $at1, $length);",
                +"}"])+"("+b+", '"+c+"', "+e+", '"+d+"', "+a+")"}return[b,Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_changeCase=function(a){var b,c=Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_NONE)||"''";"UPPERCASE"==a.getFieldValue("CASE")?b="strtoupper("+c+")":"LOWERCASE"==a.getFieldValue("CASE")?b="strtolower("+c+")":"TITLECASE"==a.getFieldValue("CASE")&&(b="ucwords(strtolower("+c+"))");return[b,Blockly.PHP.ORDER_FUNCTION_CALL]};
                +Blockly.PHP.text_trim=function(a){var b={LEFT:"ltrim",RIGHT:"rtrim",BOTH:"trim"}[a.getFieldValue("MODE")];a=Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_NONE)||"''";return[b+"("+a+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_print=function(a){return"print("+(Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_NONE)||"''")+");\n"};
                +Blockly.PHP.text_prompt_ext=function(a){var b="readline("+(a.getField("TEXT")?Blockly.PHP.quote_(a.getFieldValue("TEXT")):Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_NONE)||"''")+")";"NUMBER"==a.getFieldValue("TYPE")&&(b="floatval("+b+")");return[b,Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_prompt=Blockly.PHP.text_prompt_ext;
                +Blockly.PHP.text_count=function(a){var b=Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_MEMBER)||"''";a=Blockly.PHP.valueToCode(a,"SUB",Blockly.PHP.ORDER_NONE)||"''";return["strlen("+a+") === 0 ? strlen("+b+") + 1 : substr_count("+b+", "+a+")",Blockly.PHP.ORDER_CONDITIONAL]};
                +Blockly.PHP.text_replace=function(a){var b=Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_MEMBER)||"''",c=Blockly.PHP.valueToCode(a,"FROM",Blockly.PHP.ORDER_NONE)||"''";a=Blockly.PHP.valueToCode(a,"TO",Blockly.PHP.ORDER_NONE)||"''";return["str_replace("+c+", "+a+", "+b+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.text_reverse=function(a){return["strrev("+(Blockly.PHP.valueToCode(a,"TEXT",Blockly.PHP.ORDER_MEMBER)||"''")+")",Blockly.PHP.ORDER_FUNCTION_CALL]};Blockly.PHP.variables={};Blockly.PHP.variables_get=function(a){return[Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),Blockly.PHP.ORDER_ATOMIC]};Blockly.PHP.variables_set=function(a){var b=Blockly.PHP.valueToCode(a,"VALUE",Blockly.PHP.ORDER_ASSIGNMENT)||"0";return Blockly.PHP.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" = "+b+";\n"};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/python_compressed.js b/blockly/webif/static/blockly/python_compressed.js
                new file mode 100644
                index 000000000..f7e6c4e25
                --- /dev/null
                +++ b/blockly/webif/static/blockly/python_compressed.js
                @@ -0,0 +1,97 @@
                +// Do not edit this file; automatically generated by build.py.
                +'use strict';
                +
                +/*
                +
                + Visual Blocks Language
                +
                + Copyright 2012 Google Inc.
                + https://developers.google.com/blockly/
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +   http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +Blockly.Python=new Blockly.Generator("Python");Blockly.Python.addReservedWords("False,None,True,and,as,assert,break,class,continue,def,del,elif,else,except,exec,finally,for,from,global,if,import,in,is,lambda,nonlocal,not,or,pass,print,raise,return,try,while,with,yield,NotImplemented,Ellipsis,__debug__,quit,exit,copyright,license,credits,ArithmeticError,AssertionError,AttributeError,BaseException,BlockingIOError,BrokenPipeError,BufferError,BytesWarning,ChildProcessError,ConnectionAbortedError,ConnectionError,ConnectionRefusedError,ConnectionResetError,DeprecationWarning,EOFError,Ellipsis,EnvironmentError,Exception,FileExistsError,FileNotFoundError,FloatingPointError,FutureWarning,GeneratorExit,IOError,ImportError,ImportWarning,IndentationError,IndexError,InterruptedError,IsADirectoryError,KeyError,KeyboardInterrupt,LookupError,MemoryError,ModuleNotFoundError,NameError,NotADirectoryError,NotImplemented,NotImplementedError,OSError,OverflowError,PendingDeprecationWarning,PermissionError,ProcessLookupError,RecursionError,ReferenceError,ResourceWarning,RuntimeError,RuntimeWarning,StandardError,StopAsyncIteration,StopIteration,SyntaxError,SyntaxWarning,SystemError,SystemExit,TabError,TimeoutError,TypeError,UnboundLocalError,UnicodeDecodeError,UnicodeEncodeError,UnicodeError,UnicodeTranslateError,UnicodeWarning,UserWarning,ValueError,Warning,ZeroDivisionError,_,__build_class__,__debug__,__doc__,__import__,__loader__,__name__,__package__,__spec__,abs,all,any,apply,ascii,basestring,bin,bool,buffer,bytearray,bytes,callable,chr,classmethod,cmp,coerce,compile,complex,copyright,credits,delattr,dict,dir,divmod,enumerate,eval,exec,execfile,exit,file,filter,float,format,frozenset,getattr,globals,hasattr,hash,help,hex,id,input,int,intern,isinstance,issubclass,iter,len,license,list,locals,long,map,max,memoryview,min,next,object,oct,open,ord,pow,print,property,quit,range,raw_input,reduce,reload,repr,reversed,round,set,setattr,slice,sorted,staticmethod,str,sum,super,tuple,type,unichr,unicode,vars,xrange,zip");
                +Blockly.Python.ORDER_ATOMIC=0;Blockly.Python.ORDER_COLLECTION=1;Blockly.Python.ORDER_STRING_CONVERSION=1;Blockly.Python.ORDER_MEMBER=2.1;Blockly.Python.ORDER_FUNCTION_CALL=2.2;Blockly.Python.ORDER_EXPONENTIATION=3;Blockly.Python.ORDER_UNARY_SIGN=4;Blockly.Python.ORDER_BITWISE_NOT=4;Blockly.Python.ORDER_MULTIPLICATIVE=5;Blockly.Python.ORDER_ADDITIVE=6;Blockly.Python.ORDER_BITWISE_SHIFT=7;Blockly.Python.ORDER_BITWISE_AND=8;Blockly.Python.ORDER_BITWISE_XOR=9;Blockly.Python.ORDER_BITWISE_OR=10;
                +Blockly.Python.ORDER_RELATIONAL=11;Blockly.Python.ORDER_LOGICAL_NOT=12;Blockly.Python.ORDER_LOGICAL_AND=13;Blockly.Python.ORDER_LOGICAL_OR=14;Blockly.Python.ORDER_CONDITIONAL=15;Blockly.Python.ORDER_LAMBDA=16;Blockly.Python.ORDER_NONE=99;
                +Blockly.Python.ORDER_OVERRIDES=[[Blockly.Python.ORDER_FUNCTION_CALL,Blockly.Python.ORDER_MEMBER],[Blockly.Python.ORDER_FUNCTION_CALL,Blockly.Python.ORDER_FUNCTION_CALL],[Blockly.Python.ORDER_MEMBER,Blockly.Python.ORDER_MEMBER],[Blockly.Python.ORDER_MEMBER,Blockly.Python.ORDER_FUNCTION_CALL],[Blockly.Python.ORDER_LOGICAL_NOT,Blockly.Python.ORDER_LOGICAL_NOT],[Blockly.Python.ORDER_LOGICAL_AND,Blockly.Python.ORDER_LOGICAL_AND],[Blockly.Python.ORDER_LOGICAL_OR,Blockly.Python.ORDER_LOGICAL_OR]];
                +Blockly.Python.init=function(a){Blockly.Python.PASS=this.INDENT+"pass\n";Blockly.Python.definitions_=Object.create(null);Blockly.Python.functionNames_=Object.create(null);Blockly.Python.variableDB_?Blockly.Python.variableDB_.reset():Blockly.Python.variableDB_=new Blockly.Names(Blockly.Python.RESERVED_WORDS_);var b=[];a=a.getAllVariables();for(var c=0;c<a.length;c++)b[c]=Blockly.Python.variableDB_.getName(a[c].name,Blockly.Variables.NAME_TYPE)+" = None";Blockly.Python.definitions_.variables=b.join("\n")};
                +Blockly.Python.finish=function(a){var b=[],c=[],d;for(d in Blockly.Python.definitions_){var e=Blockly.Python.definitions_[d];e.match(/^(from\s+\S+\s+)?import\s+\S+/)?b.push(e):c.push(e)}delete Blockly.Python.definitions_;delete Blockly.Python.functionNames_;Blockly.Python.variableDB_.reset();return(b.join("\n")+"\n\n"+c.join("\n\n")).replace(/\n\n+/g,"\n\n").replace(/\n*$/,"\n\n\n")+a};Blockly.Python.scrubNakedValue=function(a){return a+"\n"};
                +Blockly.Python.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/\%/g,"\\%");var b="'";-1!==a.indexOf("'")&&(-1===a.indexOf('"')?b='"':a=a.replace(/'/g,"\\'"));return b+a+b};
                +Blockly.Python.scrub_=function(a,b){var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();(d=Blockly.utils.wrap(d,Blockly.Python.COMMENT_WRAP-3))&&(c=a.getProcedureDef?c+('"""'+d+'\n"""\n'):c+Blockly.Python.prefixLines(d+"\n","# "));for(var e=0;e<a.inputList.length;e++)a.inputList[e].type==Blockly.INPUT_VALUE&&(d=a.inputList[e].connection.targetBlock())&&(d=Blockly.Python.allNestedComments(d))&&(c+=Blockly.Python.prefixLines(d,"# "))}e=a.nextConnection&&a.nextConnection.targetBlock();
                +e=Blockly.Python.blockToCode(e);return c+b+e};Blockly.Python.getAdjustedInt=function(a,b,c,d){c=c||0;a.workspace.options.oneBasedIndex&&c--;var e=a.workspace.options.oneBasedIndex?"1":"0";a=Blockly.Python.valueToCode(a,b,c?Blockly.Python.ORDER_ADDITIVE:Blockly.Python.ORDER_NONE)||e;Blockly.isNumber(a)?(a=parseInt(a,10)+c,d&&(a=-a)):(a=0<c?"int("+a+" + "+c+")":0>c?"int("+a+" - "+-c+")":"int("+a+")",d&&(a="-"+a));return a};Blockly.Python.colour={};Blockly.Python.colour_picker=function(a){return["'"+a.getFieldValue("COLOUR")+"'",Blockly.Python.ORDER_ATOMIC]};Blockly.Python.colour_random=function(a){Blockly.Python.definitions_.import_random="import random";return["'#%06x' % random.randint(0, 2**24 - 1)",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.colour_rgb=function(a){var b=Blockly.Python.provideFunction_("colour_rgb",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(r, g, b):","  r = round(min(100, max(0, r)) * 2.55)","  g = round(min(100, max(0, g)) * 2.55)","  b = round(min(100, max(0, b)) * 2.55)","  return '#%02x%02x%02x' % (r, g, b)"]),c=Blockly.Python.valueToCode(a,"RED",Blockly.Python.ORDER_NONE)||0,d=Blockly.Python.valueToCode(a,"GREEN",Blockly.Python.ORDER_NONE)||0;a=Blockly.Python.valueToCode(a,"BLUE",Blockly.Python.ORDER_NONE)||
                +0;return[b+"("+c+", "+d+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.colour_blend=function(a){var b=Blockly.Python.provideFunction_("colour_blend",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(colour1, colour2, ratio):","  r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)","  g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)","  b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)","  ratio = min(1, max(0, ratio))","  r = round(r1 * (1 - ratio) + r2 * ratio)","  g = round(g1 * (1 - ratio) + g2 * ratio)","  b = round(b1 * (1 - ratio) + b2 * ratio)",
                +"  return '#%02x%02x%02x' % (r, g, b)"]),c=Blockly.Python.valueToCode(a,"COLOUR1",Blockly.Python.ORDER_NONE)||"'#000000'",d=Blockly.Python.valueToCode(a,"COLOUR2",Blockly.Python.ORDER_NONE)||"'#000000'";a=Blockly.Python.valueToCode(a,"RATIO",Blockly.Python.ORDER_NONE)||0;return[b+"("+c+", "+d+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.lists={};Blockly.Python.lists_create_empty=function(a){return["[]",Blockly.Python.ORDER_ATOMIC]};Blockly.Python.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Python.valueToCode(a,"ADD"+c,Blockly.Python.ORDER_NONE)||"None";return["["+b.join(", ")+"]",Blockly.Python.ORDER_ATOMIC]};
                +Blockly.Python.lists_repeat=function(a){var b=Blockly.Python.valueToCode(a,"ITEM",Blockly.Python.ORDER_NONE)||"None";a=Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";return["["+b+"] * "+a,Blockly.Python.ORDER_MULTIPLICATIVE]};Blockly.Python.lists_length=function(a){return["len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"[]")+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.lists_isEmpty=function(a){return["not len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"[]")+")",Blockly.Python.ORDER_LOGICAL_NOT]};
                +Blockly.Python.lists_indexOf=function(a){var b=Blockly.Python.valueToCode(a,"FIND",Blockly.Python.ORDER_NONE)||"[]",c=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''";if(a.workspace.options.oneBasedIndex){var d=" 0";var e=" + 1";var f=""}else d=" -1",e="",f=" - 1";if("FIRST"==a.getFieldValue("END"))return a=Blockly.Python.provideFunction_("first_index",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, elem):","  try: index = my_list.index(elem)"+e,"  except: index ="+
                +d,"  return index"]),[a+"("+c+", "+b+")",Blockly.Python.ORDER_FUNCTION_CALL];a=Blockly.Python.provideFunction_("last_index",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, elem):","  try: index = len(my_list) - my_list[::-1].index(elem)"+f,"  except: index ="+d,"  return index"]);return[a+"("+c+", "+b+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.lists_getIndex=function(a){var b=a.getFieldValue("MODE")||"GET",c=a.getFieldValue("WHERE")||"FROM_START";var d=Blockly.Python.valueToCode(a,"VALUE","RANDOM"==c?Blockly.Python.ORDER_NONE:Blockly.Python.ORDER_MEMBER)||"[]";switch(c){case "FIRST":if("GET"==b)return[d+"[0]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop(0)",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop(0)\n";break;case "LAST":if("GET"==b)return[d+"[-1]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==
                +b)return[d+".pop()",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop()\n";break;case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT");if("GET"==b)return[d+"["+a+"]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop("+a+")",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop("+a+")\n";break;case "FROM_END":a=Blockly.Python.getAdjustedInt(a,"AT",1,!0);if("GET"==b)return[d+"["+a+"]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop("+a+")",
                +Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop("+a+")\n";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";if("GET"==b)return["random.choice("+d+")",Blockly.Python.ORDER_FUNCTION_CALL];d=Blockly.Python.provideFunction_("lists_remove_random_item",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):","  x = int(random.random() * len(myList))","  return myList.pop(x)"])+"("+d+")";if("GET_REMOVE"==b)return[d,Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==
                +b)return d+"\n"}throw"Unhandled combination (lists_getIndex).";};
                +Blockly.Python.lists_setIndex=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_MEMBER)||"[]",c=a.getFieldValue("MODE")||"GET",d=a.getFieldValue("WHERE")||"FROM_START",e=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"None";switch(d){case "FIRST":if("SET"==c)return b+"[0] = "+e+"\n";if("INSERT"==c)return b+".insert(0, "+e+")\n";break;case "LAST":if("SET"==c)return b+"[-1] = "+e+"\n";if("INSERT"==c)return b+".append("+e+")\n";break;case "FROM_START":a=Blockly.Python.getAdjustedInt(a,
                +"AT");if("SET"==c)return b+"["+a+"] = "+e+"\n";if("INSERT"==c)return b+".insert("+a+", "+e+")\n";break;case "FROM_END":a=Blockly.Python.getAdjustedInt(a,"AT",1,!0);if("SET"==c)return b+"["+a+"] = "+e+"\n";if("INSERT"==c)return b+".insert("+a+", "+e+")\n";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";b.match(/^\w+$/)?a="":(a=Blockly.Python.variableDB_.getDistinctName("tmp_list",Blockly.Variables.NAME_TYPE),d=a+" = "+b+"\n",b=a,a=d);d=Blockly.Python.variableDB_.getDistinctName("tmp_x",
                +Blockly.Variables.NAME_TYPE);a+=d+" = int(random.random() * len("+b+"))\n";if("SET"==c)return a+(b+"["+d+"] = "+e+"\n");if("INSERT"==c)return a+(b+".insert("+d+", "+e+")\n")}throw"Unhandled combination (lists_setIndex).";};
                +Blockly.Python.lists_getSublist=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_MEMBER)||"[]";var c=a.getFieldValue("WHERE1");var d=a.getFieldValue("WHERE2");switch(c){case "FROM_START":c=Blockly.Python.getAdjustedInt(a,"AT1");"0"==c&&(c="");break;case "FROM_END":c=Blockly.Python.getAdjustedInt(a,"AT1",1,!0);break;case "FIRST":c="";break;default:throw"Unhandled option (lists_getSublist)";}switch(d){case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT2",1);break;case "FROM_END":a=
                +Blockly.Python.getAdjustedInt(a,"AT2",0,!0);Blockly.isNumber(String(a))?"0"==a&&(a=""):(Blockly.Python.definitions_.import_sys="import sys",a+=" or sys.maxsize");break;case "LAST":a="";break;default:throw"Unhandled option (lists_getSublist)";}return[b+"["+c+" : "+a+"]",Blockly.Python.ORDER_MEMBER]};
                +Blockly.Python.lists_sort=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]",c=a.getFieldValue("TYPE");a="1"===a.getFieldValue("DIRECTION")?"False":"True";return[Blockly.Python.provideFunction_("lists_sort",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, type, reverse):","  def try_float(s):","    try:","      return float(s)","    except:","      return 0","  key_funcs = {",'    "NUMERIC": try_float,','    "TEXT": str,','    "IGNORE_CASE": lambda s: str(s).lower()',
                +"  }","  key_func = key_funcs[type]","  list_cpy = list(my_list)","  return sorted(list_cpy, key=key_func, reverse=reverse)"])+"("+b+', "'+c+'", '+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.lists_split=function(a){var b=a.getFieldValue("MODE");if("SPLIT"==b)b=Blockly.Python.valueToCode(a,"INPUT",Blockly.Python.ORDER_MEMBER)||"''",a=Blockly.Python.valueToCode(a,"DELIM",Blockly.Python.ORDER_NONE),a=b+".split("+a+")";else if("JOIN"==b)b=Blockly.Python.valueToCode(a,"INPUT",Blockly.Python.ORDER_NONE)||"[]",a=Blockly.Python.valueToCode(a,"DELIM",Blockly.Python.ORDER_MEMBER)||"''",a=a+".join("+b+")";else throw"Unknown mode: "+b;return[a,Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.lists_reverse=function(a){return["list(reversed("+(Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]")+"))",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.logic={};Blockly.Python.controls_if=function(a){var b=0,c="";do{var d=Blockly.Python.valueToCode(a,"IF"+b,Blockly.Python.ORDER_NONE)||"False";var e=Blockly.Python.statementToCode(a,"DO"+b)||Blockly.Python.PASS;c+=(0==b?"if ":"elif ")+d+":\n"+e;++b}while(a.getInput("IF"+b));a.getInput("ELSE")&&(e=Blockly.Python.statementToCode(a,"ELSE")||Blockly.Python.PASS,c+="else:\n"+e);return c};Blockly.Python.controls_ifelse=Blockly.Python.controls_if;
                +Blockly.Python.logic_compare=function(a){var b={EQ:"==",NEQ:"!=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c=Blockly.Python.ORDER_RELATIONAL,d=Blockly.Python.valueToCode(a,"A",c)||"0";a=Blockly.Python.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
                +Blockly.Python.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"and":"or",c="and"==b?Blockly.Python.ORDER_LOGICAL_AND:Blockly.Python.ORDER_LOGICAL_OR,d=Blockly.Python.valueToCode(a,"A",c);a=Blockly.Python.valueToCode(a,"B",c);if(d||a){var e="and"==b?"True":"False";d||(d=e);a||(a=e)}else a=d="False";return[d+" "+b+" "+a,c]};Blockly.Python.logic_negate=function(a){return["not "+(Blockly.Python.valueToCode(a,"BOOL",Blockly.Python.ORDER_LOGICAL_NOT)||"True"),Blockly.Python.ORDER_LOGICAL_NOT]};
                +Blockly.Python.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"True":"False",Blockly.Python.ORDER_ATOMIC]};Blockly.Python.logic_null=function(a){return["None",Blockly.Python.ORDER_ATOMIC]};
                +Blockly.Python.logic_ternary=function(a){var b=Blockly.Python.valueToCode(a,"IF",Blockly.Python.ORDER_CONDITIONAL)||"False",c=Blockly.Python.valueToCode(a,"THEN",Blockly.Python.ORDER_CONDITIONAL)||"None";a=Blockly.Python.valueToCode(a,"ELSE",Blockly.Python.ORDER_CONDITIONAL)||"None";return[c+" if "+b+" else "+a,Blockly.Python.ORDER_CONDITIONAL]};Blockly.Python.loops={};Blockly.Python.controls_repeat_ext=function(a){var b=a.getField("TIMES")?String(parseInt(a.getFieldValue("TIMES"),10)):Blockly.Python.valueToCode(a,"TIMES",Blockly.Python.ORDER_NONE)||"0";b=Blockly.isNumber(b)?parseInt(b,10):"int("+b+")";var c=Blockly.Python.statementToCode(a,"DO"),c=Blockly.Python.addLoopTrap(c,a.id)||Blockly.Python.PASS;return"for "+Blockly.Python.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE)+" in range("+b+"):\n"+c};
                +Blockly.Python.controls_repeat=Blockly.Python.controls_repeat_ext;Blockly.Python.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.Python.valueToCode(a,"BOOL",b?Blockly.Python.ORDER_LOGICAL_NOT:Blockly.Python.ORDER_NONE)||"False",d=Blockly.Python.statementToCode(a,"DO"),d=Blockly.Python.addLoopTrap(d,a.id)||Blockly.Python.PASS;b&&(c="not "+c);return"while "+c+":\n"+d};
                +Blockly.Python.controls_for=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"0",d=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"0",e=Blockly.Python.valueToCode(a,"BY",Blockly.Python.ORDER_NONE)||"1",f=Blockly.Python.statementToCode(a,"DO"),f=Blockly.Python.addLoopTrap(f,a.id)||Blockly.Python.PASS,g="",h=function(){return Blockly.Python.provideFunction_("upRange",
                +["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(start, stop, step):","  while start <= stop:","    yield start","    start += abs(step)"])},k=function(){return Blockly.Python.provideFunction_("downRange",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(start, stop, step):","  while start >= stop:","    yield start","    start -= abs(step)"])};a=function(a,b,c){return"("+a+" <= "+b+") and "+h()+"("+a+", "+b+", "+c+") or "+k()+"("+a+", "+b+", "+c+")"};if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&
                +Blockly.isNumber(e))c=parseFloat(c),d=parseFloat(d),e=Math.abs(parseFloat(e)),0===c%1&&0===d%1&&0===e%1?(c<=d?(d++,a=0==c&&1==e?d:c+", "+d,1!=e&&(a+=", "+e)):(d--,a=c+", "+d+", -"+e),a="range("+a+")"):(a=c<d?h():k(),a+="("+c+", "+d+", "+e+")");else{var l=function(a,c){if(Blockly.isNumber(a))a=parseFloat(a);else if(a.match(/^\w+$/))a="float("+a+")";else{var d=Blockly.Python.variableDB_.getDistinctName(b+c,Blockly.Variables.NAME_TYPE);g+=d+" = float("+a+")\n";a=d}return a},c=l(c,"_start"),d=l(d,"_end");
                +l(e,"_inc");a="number"==typeof c&&"number"==typeof d?c<d?h(c,d,e):k(c,d,e):a(c,d,e)}return g+="for "+b+" in "+a+":\n"+f};Blockly.Python.controls_forEach=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_RELATIONAL)||"[]",d=Blockly.Python.statementToCode(a,"DO"),d=Blockly.Python.addLoopTrap(d,a.id)||Blockly.Python.PASS;return"for "+b+" in "+c+":\n"+d};
                +Blockly.Python.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break\n";case "CONTINUE":return"continue\n"}throw"Unknown flow statement.";};Blockly.Python.math={};Blockly.Python.addReservedWords("math,random,Number");Blockly.Python.math_number=function(a){a=parseFloat(a.getFieldValue("NUM"));if(Infinity==a){a='float("inf")';var b=Blockly.Python.ORDER_FUNCTION_CALL}else-Infinity==a?(a='-float("inf")',b=Blockly.Python.ORDER_UNARY_SIGN):b=0>a?Blockly.Python.ORDER_UNARY_SIGN:Blockly.Python.ORDER_ATOMIC;return[a,b]};
                +Blockly.Python.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.Python.ORDER_ADDITIVE],MINUS:[" - ",Blockly.Python.ORDER_ADDITIVE],MULTIPLY:[" * ",Blockly.Python.ORDER_MULTIPLICATIVE],DIVIDE:[" / ",Blockly.Python.ORDER_MULTIPLICATIVE],POWER:[" ** ",Blockly.Python.ORDER_EXPONENTIATION]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.Python.valueToCode(a,"A",b)||"0";a=Blockly.Python.valueToCode(a,"B",b)||"0";return[d+c+a,b]};
                +Blockly.Python.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b){var c=Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_UNARY_SIGN)||"0";return["-"+c,Blockly.Python.ORDER_UNARY_SIGN]}Blockly.Python.definitions_.import_math="import math";a="SIN"==b||"COS"==b||"TAN"==b?Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_MULTIPLICATIVE)||"0":Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_NONE)||"0";switch(b){case "ABS":c="math.fabs("+a+")";break;case "ROOT":c="math.sqrt("+
                +a+")";break;case "LN":c="math.log("+a+")";break;case "LOG10":c="math.log10("+a+")";break;case "EXP":c="math.exp("+a+")";break;case "POW10":c="math.pow(10,"+a+")";break;case "ROUND":c="round("+a+")";break;case "ROUNDUP":c="math.ceil("+a+")";break;case "ROUNDDOWN":c="math.floor("+a+")";break;case "SIN":c="math.sin("+a+" / 180.0 * math.pi)";break;case "COS":c="math.cos("+a+" / 180.0 * math.pi)";break;case "TAN":c="math.tan("+a+" / 180.0 * math.pi)"}if(c)return[c,Blockly.Python.ORDER_FUNCTION_CALL];switch(b){case "ASIN":c=
                +"math.asin("+a+") / math.pi * 180";break;case "ACOS":c="math.acos("+a+") / math.pi * 180";break;case "ATAN":c="math.atan("+a+") / math.pi * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.Python.ORDER_MULTIPLICATIVE]};
                +Blockly.Python.math_constant=function(a){var b={PI:["math.pi",Blockly.Python.ORDER_MEMBER],E:["math.e",Blockly.Python.ORDER_MEMBER],GOLDEN_RATIO:["(1 + math.sqrt(5)) / 2",Blockly.Python.ORDER_MULTIPLICATIVE],SQRT2:["math.sqrt(2)",Blockly.Python.ORDER_MEMBER],SQRT1_2:["math.sqrt(1.0 / 2)",Blockly.Python.ORDER_MEMBER],INFINITY:["float('inf')",Blockly.Python.ORDER_ATOMIC]};a=a.getFieldValue("CONSTANT");"INFINITY"!=a&&(Blockly.Python.definitions_.import_math="import math");return b[a]};
                +Blockly.Python.math_number_property=function(a){var b=Blockly.Python.valueToCode(a,"NUMBER_TO_CHECK",Blockly.Python.ORDER_MULTIPLICATIVE)||"0",c=a.getFieldValue("PROPERTY");if("PRIME"==c)return Blockly.Python.definitions_.import_math="import math",Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number",[Blockly.Python.provideFunction_("math_isPrime",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(n):","  # https://en.wikipedia.org/wiki/Primality_test#Naive_methods",
                +"  # If n is not a number but a string, try parsing it.","  if not isinstance(n, Number):","    try:","      n = float(n)","    except:","      return False","  if n == 2 or n == 3:","    return True","  # False if n is negative, is 1, or not whole, or if n is divisible by 2 or 3.","  if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:","    return False","  # Check all the numbers of form 6k +/- 1, up to sqrt(n).","  for x in range(6, int(math.sqrt(n)) + 2, 6):","    if n % (x - 1) == 0 or n % (x + 1) == 0:",
                +"      return False","  return True"])+"("+b+")",Blockly.Python.ORDER_FUNCTION_CALL];switch(c){case "EVEN":var d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.Python.valueToCode(a,"DIVISOR",Blockly.Python.ORDER_MULTIPLICATIVE);if(!a||"0"==a)return["False",Blockly.Python.ORDER_ATOMIC];d=b+" % "+a+" == 0"}return[d,Blockly.Python.ORDER_RELATIONAL]};
                +Blockly.Python.math_change=function(a){Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";var b=Blockly.Python.valueToCode(a,"DELTA",Blockly.Python.ORDER_ADDITIVE)||"0";a=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);return a+" = ("+a+" if isinstance("+a+", Number) else 0) + "+b+"\n"};Blockly.Python.math_round=Blockly.Python.math_single;Blockly.Python.math_trig=Blockly.Python.math_single;
                +Blockly.Python.math_on_list=function(a){var b=a.getFieldValue("OP");a=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]";switch(b){case "SUM":b="sum("+a+")";break;case "MIN":b="min("+a+")";break;case "MAX":b="max("+a+")";break;case "AVERAGE":Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";b=Blockly.Python.provideFunction_("math_mean",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):","  localList = [e for e in myList if isinstance(e, Number)]",
                +"  if not localList: return","  return float(sum(localList)) / len(localList)"]);b=b+"("+a+")";break;case "MEDIAN":Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";b=Blockly.Python.provideFunction_("math_median",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):","  localList = sorted([e for e in myList if isinstance(e, Number)])","  if not localList: return","  if len(localList) % 2 == 0:","    return (localList[len(localList) // 2 - 1] + localList[len(localList) // 2]) / 2.0",
                +"  else:","    return localList[(len(localList) - 1) // 2]"]);b=b+"("+a+")";break;case "MODE":b=Blockly.Python.provideFunction_("math_modes",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(some_list):","  modes = []","  # Using a lists of [item, count] to keep count rather than dict",'  # to avoid "unhashable" errors when the counted item is itself a list or dict.',"  counts = []","  maxCount = 1","  for item in some_list:","    found = False","    for count in counts:","      if count[0] == item:",
                +"        count[1] += 1","        maxCount = max(maxCount, count[1])","        found = True","    if not found:","      counts.append([item, 1])","  for counted_item, item_count in counts:","    if item_count == maxCount:","      modes.append(counted_item)","  return modes"]);b=b+"("+a+")";break;case "STD_DEV":Blockly.Python.definitions_.import_math="import math";b=Blockly.Python.provideFunction_("math_standard_deviation",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(numbers):","  n = len(numbers)",
                +"  if n == 0: return","  mean = float(sum(numbers)) / n","  variance = sum((x - mean) ** 2 for x in numbers) / n","  return math.sqrt(variance)"]);b=b+"("+a+")";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";b="random.choice("+a+")";break;default:throw"Unknown operator: "+b;}return[b,Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.math_modulo=function(a){var b=Blockly.Python.valueToCode(a,"DIVIDEND",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";a=Blockly.Python.valueToCode(a,"DIVISOR",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";return[b+" % "+a,Blockly.Python.ORDER_MULTIPLICATIVE]};
                +Blockly.Python.math_constrain=function(a){var b=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"0",c=Blockly.Python.valueToCode(a,"LOW",Blockly.Python.ORDER_NONE)||"0";a=Blockly.Python.valueToCode(a,"HIGH",Blockly.Python.ORDER_NONE)||"float('inf')";return["min(max("+b+", "+c+"), "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.math_random_int=function(a){Blockly.Python.definitions_.import_random="import random";var b=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"0";a=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"0";return["random.randint("+b+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.math_random_float=function(a){Blockly.Python.definitions_.import_random="import random";return["random.random()",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.procedures={};
                +Blockly.Python.procedures_defreturn=function(a){for(var b=[],c,d=a.workspace.getAllVariables()||[],e=0;c=d[e];e++)c=c.name,-1==a.arguments_.indexOf(c)&&b.push(Blockly.Python.variableDB_.getName(c,Blockly.Variables.NAME_TYPE));b=b.length?"  global "+b.join(", ")+"\n":"";d=Blockly.Python.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE);c=Blockly.Python.statementToCode(a,"STACK");Blockly.Python.STATEMENT_PREFIX&&(c=Blockly.Python.prefixLines(Blockly.Python.STATEMENT_PREFIX.replace(/%1/g,"'"+
                +a.id+"'"),Blockly.Python.INDENT)+c);Blockly.Python.INFINITE_LOOP_TRAP&&(c=Blockly.Python.INFINITE_LOOP_TRAP.replace(/%1/g,'"'+a.id+'"')+c);var f=Blockly.Python.valueToCode(a,"RETURN",Blockly.Python.ORDER_NONE)||"";f?f="  return "+f+"\n":c||(c=Blockly.Python.PASS);for(var g=[],e=0;e<a.arguments_.length;e++)g[e]=Blockly.Python.variableDB_.getName(a.arguments_[e],Blockly.Variables.NAME_TYPE);b="def "+d+"("+g.join(", ")+"):\n"+b+c+f;b=Blockly.Python.scrub_(a,b);Blockly.Python.definitions_["%"+d]=b;return null};
                +Blockly.Python.procedures_defnoreturn=Blockly.Python.procedures_defreturn;Blockly.Python.procedures_callreturn=function(a){for(var b=Blockly.Python.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Python.valueToCode(a,"ARG"+d,Blockly.Python.ORDER_NONE)||"None";return[b+"("+c.join(", ")+")",Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.procedures_callnoreturn=function(a){for(var b=Blockly.Python.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=[],d=0;d<a.arguments_.length;d++)c[d]=Blockly.Python.valueToCode(a,"ARG"+d,Blockly.Python.ORDER_NONE)||"None";return b+"("+c.join(", ")+")\n"};
                +Blockly.Python.procedures_ifreturn=function(a){var b="if "+(Blockly.Python.valueToCode(a,"CONDITION",Blockly.Python.ORDER_NONE)||"False")+":\n";a.hasReturnValue_?(a=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"None",b+="  return "+a+"\n"):b+="  return\n";return b};Blockly.Python.texts={};Blockly.Python.text=function(a){return[Blockly.Python.quote_(a.getFieldValue("TEXT")),Blockly.Python.ORDER_ATOMIC]};
                +Blockly.Python.text_join=function(a){switch(a.itemCount_){case 0:return["''",Blockly.Python.ORDER_ATOMIC];case 1:return["str("+(Blockly.Python.valueToCode(a,"ADD0",Blockly.Python.ORDER_NONE)||"''")+")",Blockly.Python.ORDER_FUNCTION_CALL];case 2:var b=Blockly.Python.valueToCode(a,"ADD0",Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.valueToCode(a,"ADD1",Blockly.Python.ORDER_NONE)||"''";return["str("+b+") + str("+a+")",Blockly.Python.ORDER_ADDITIVE];default:for(var b=[],c=0;c<a.itemCount_;c++)b[c]=
                +Blockly.Python.valueToCode(a,"ADD"+c,Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.variableDB_.getDistinctName("x",Blockly.Variables.NAME_TYPE);a="''.join([str("+a+") for "+a+" in ["+b.join(", ")+"]])";return[a,Blockly.Python.ORDER_FUNCTION_CALL]}};Blockly.Python.text_append=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE);a=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''";return b+" = str("+b+") + str("+a+")\n"};
                +Blockly.Python.text_length=function(a){return["len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''")+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.text_isEmpty=function(a){return["not len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''")+")",Blockly.Python.ORDER_LOGICAL_NOT]};
                +Blockly.Python.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"find":"rfind",c=Blockly.Python.valueToCode(a,"FIND",Blockly.Python.ORDER_NONE)||"''",b=(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_MEMBER)||"''")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.Python.ORDER_ADDITIVE]:[b,Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_MEMBER)||"''";switch(b){case "FIRST":return[c+"[0]",Blockly.Python.ORDER_MEMBER];case "LAST":return[c+"[-1]",Blockly.Python.ORDER_MEMBER];case "FROM_START":return a=Blockly.Python.getAdjustedInt(a,"AT"),[c+"["+a+"]",Blockly.Python.ORDER_MEMBER];case "FROM_END":return a=Blockly.Python.getAdjustedInt(a,"AT",1,!0),[c+"["+a+"]",Blockly.Python.ORDER_MEMBER];case "RANDOM":return Blockly.Python.definitions_.import_random=
                +"import random",[Blockly.Python.provideFunction_("text_random_letter",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(text):","  x = int(random.random() * len(text))","  return text[x];"])+"("+c+")",Blockly.Python.ORDER_FUNCTION_CALL]}throw"Unhandled option (text_charAt).";};
                +Blockly.Python.text_getSubstring=function(a){var b=a.getFieldValue("WHERE1");var c=a.getFieldValue("WHERE2"),d=Blockly.Python.valueToCode(a,"STRING",Blockly.Python.ORDER_MEMBER)||"''";switch(b){case "FROM_START":b=Blockly.Python.getAdjustedInt(a,"AT1");"0"==b&&(b="");break;case "FROM_END":b=Blockly.Python.getAdjustedInt(a,"AT1",1,!0);break;case "FIRST":b="";break;default:throw"Unhandled option (text_getSubstring)";}switch(c){case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT2",1);break;case "FROM_END":a=
                +Blockly.Python.getAdjustedInt(a,"AT2",0,!0);Blockly.isNumber(String(a))?"0"==a&&(a=""):(Blockly.Python.definitions_.import_sys="import sys",a+=" or sys.maxsize");break;case "LAST":a="";break;default:throw"Unhandled option (text_getSubstring)";}return[d+"["+b+" : "+a+"]",Blockly.Python.ORDER_MEMBER]};
                +Blockly.Python.text_changeCase=function(a){var b={UPPERCASE:".upper()",LOWERCASE:".lower()",TITLECASE:".title()"}[a.getFieldValue("CASE")];return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+b,Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.text_trim=function(a){var b={LEFT:".lstrip()",RIGHT:".rstrip()",BOTH:".strip()"}[a.getFieldValue("MODE")];return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+b,Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.text_print=function(a){return"print("+(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''")+")\n"};
                +Blockly.Python.text_prompt_ext=function(a){var b=Blockly.Python.provideFunction_("text_prompt",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(msg):","  try:","    return raw_input(msg)","  except NameError:","    return input(msg)"]);var c=a.getField("TEXT")?Blockly.Python.quote_(a.getFieldValue("TEXT")):Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''";c=b+"("+c+")";"NUMBER"==a.getFieldValue("TYPE")&&(c="float("+c+")");return[c,Blockly.Python.ORDER_FUNCTION_CALL]};
                +Blockly.Python.text_prompt=Blockly.Python.text_prompt_ext;Blockly.Python.text_count=function(a){var b=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''";a=Blockly.Python.valueToCode(a,"SUB",Blockly.Python.ORDER_NONE)||"''";return[b+".count("+a+")",Blockly.Python.ORDER_MEMBER]};
                +Blockly.Python.text_replace=function(a){var b=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''",c=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"''";return[b+".replace("+c+", "+a+")",Blockly.Python.ORDER_MEMBER]};Blockly.Python.text_reverse=function(a){return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+"[::-1]",Blockly.Python.ORDER_MEMBER]};Blockly.Python.variables={};Blockly.Python.variables_get=function(a){return[Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),Blockly.Python.ORDER_ATOMIC]};Blockly.Python.variables_set=function(a){var b=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"0";return Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" = "+b+"\n"};
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/scripts/.selenium_connect.sh.swp b/blockly/webif/static/blockly/scripts/.selenium_connect.sh.swp
                new file mode 100644
                index 000000000..ceaa1343a
                Binary files /dev/null and b/blockly/webif/static/blockly/scripts/.selenium_connect.sh.swp differ
                diff --git a/blockly/webif/static/blockly/scripts/get_chromedriver.sh b/blockly/webif/static/blockly/scripts/get_chromedriver.sh
                new file mode 100644
                index 000000000..7bff39c16
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/get_chromedriver.sh
                @@ -0,0 +1,17 @@
                +#!/bin/bash
                +os_name=`uname`
                +chromedriver_dir="chromedriver"
                +if [ ! -d $chromedriver_dir ]; then
                +  mkdir $chromedriver_dir
                +fi
                +
                +echo "downloading chromedriver"
                +
                +if [[ $os_name == 'Linux' && ! -f $chromedriver_dir/chromedriver ]]; then
                +  cd chromedriver  && curl -L https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip > tmp.zip &&  unzip -o tmp.zip && rm tmp.zip 
                +  # wait until download finish
                +  sleep 5
                +elif [[ $os_name == 'Darwin' && ! -f $chromedriver_dir/chromedriver ]]; then
                +  cd chromedriver  &&  curl -L https://chromedriver.storage.googleapis.com/2.29/chromedriver_mac64.zip  | tar xz 
                +  sleep 5
                +fi
                diff --git a/blockly/webif/static/blockly/scripts/get_geckdriver.sh b/blockly/webif/static/blockly/scripts/get_geckdriver.sh
                new file mode 100644
                index 000000000..77fecd4ec
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/get_geckdriver.sh
                @@ -0,0 +1,15 @@
                +#!/bin/bash
                +os_name=`uname`
                +
                +if [ -f geckodriver ]; then
                +  exit 0
                +fi
                +echo "downloading gechdriver"
                +
                +if [[ $os_name == 'Linux' ]]; then
                +  cd ../ && curl -L https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz | tar xz
                +  sleep 5
                +elif [[ $os_name == 'Darwin' ]]; then
                +  cd ../ &&  curl -L https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-macos.tar.gz | tar xz
                +  sleep 5
                +fi
                diff --git a/blockly/webif/static/blockly/scripts/get_selenium.sh b/blockly/webif/static/blockly/scripts/get_selenium.sh
                new file mode 100644
                index 000000000..0dac3e9b5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/get_selenium.sh
                @@ -0,0 +1,14 @@
                +#!/bin/bash
                +DIR="../webdriverio-test"
                +FILE=selenium-server-standalone-3.0.1.jar
                +
                +if [ ! -d $DIR ]; then
                +  mkdir $DIR
                +fi
                +
                +echo "downloading selenium jar"
                +
                +if [ ! -f $DIR/$FILE ]; then
                +  cd $DIR  && curl -O http://selenium-release.storage.googleapis.com/3.0/selenium-server-standalone-3.0.1.jar
                +  sleep 5
                +fi
                diff --git a/blockly/webif/static/blockly/scripts/selenium_connect.sh b/blockly/webif/static/blockly/scripts/selenium_connect.sh
                new file mode 100644
                index 000000000..3fae90576
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/selenium_connect.sh
                @@ -0,0 +1,10 @@
                +#!/bin/bash
                +
                +#check if selenium server is up running
                +pid=`lsof -ti tcp:4444`
                +if [ $? -eq 0 ]
                +then
                +  kill -9 $pid 
                +fi
                +java -jar -Dwebdriver.gecko.driver=../geckodriver -Dwebdriver.chrome.driver="chromedriver/chromedriver" ../webdriverio-test/selenium-server-standalone-3.0.1.jar  &
                +
                diff --git a/blockly/webif/static/blockly/scripts/setup_linux_env.sh b/blockly/webif/static/blockly/scripts/setup_linux_env.sh
                new file mode 100644
                index 000000000..da3d0ce6c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/setup_linux_env.sh
                @@ -0,0 +1,8 @@
                +#!/bin/bash
                +
                +if [ "${TRAVIS_OS_NAME}" == "linux" ]
                +  then
                +    export CHROME_BIN="/usr/bin/google-chrome"
                +    export DISPLAY=:99.0
                +    sh -e /etc/init.d/xvfb start &
                +fi
                diff --git a/blockly/webif/static/blockly/scripts/setup_osx_env.sh b/blockly/webif/static/blockly/scripts/setup_osx_env.sh
                new file mode 100644
                index 000000000..92891f966
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/setup_osx_env.sh
                @@ -0,0 +1,8 @@
                +#!/bin/bash
                +  
                +if [ "${TRAVIS_OS_NAME}" == "osx" ]
                +  then
                +    brew cask install google-chrome 
                +    sudo Xvfb :99 -ac -screen 0 1024x768x8 &
                +    export CHROME_BIN="/Applications/Google Chrome.app" 
                +fi
                diff --git a/blockly/webif/static/blockly/scripts/test_setup.sh b/blockly/webif/static/blockly/scripts/test_setup.sh
                new file mode 100644
                index 000000000..4220923f3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/scripts/test_setup.sh
                @@ -0,0 +1,23 @@
                +#!/bin/bash
                +
                +EXIT_STATUS=0
                +
                +function check_command {
                +    "$@"
                +    local STATUS=$?
                +    if [ $STATUS -ne 0 ]; then
                +      echo "error with $1 ($STATUS)" >&2
                +      EXIT_STATUS=$STATUS
                +      fi
                +   }
                +
                +check_command scripts/get_geckdriver.sh
                +sleep 5
                +check_command scripts/get_selenium.sh 
                +sleep 5
                +check_command scripts/get_chromedriver.sh 
                +sleep 10
                +check_command scripts/selenium_connect.sh 
                +sleep 10
                +
                +exit $EXIT_STATUS
                diff --git a/blockly/webif/static/blockly/tests/blocks/index.html b/blockly/webif/static/blockly/tests/blocks/index.html
                new file mode 100644
                index 000000000..b528a85f5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/blocks/index.html
                @@ -0,0 +1,21 @@
                +<!DOCTYPE html>
                +<html>
                +  <head>
                +    <meta charset="utf-8">
                +    <title>Unit Tests for Blockly Blocks</title>
                +    <script src="../../blockly_compressed.js"></script>
                +    <script src="../../msg/js/en.js"></script>  <!-- TODO: Test messages in all languages. -->
                +    <script src="../../blocks/colour.js"></script>
                +    <script src="../../blocks/lists.js"></script>
                +    <script src="../../blocks/logic.js"></script>
                +    <script src="../../blocks/loops.js"></script>
                +    <script src="../../blocks/math.js"></script>
                +    <script src="../../blocks/procedures.js"></script>
                +    <script src="../../blocks/text.js"></script>
                +    <script src="../../blocks/variables.js"></script>
                +    <script>goog.require('goog.testing.jsunit');</script>
                +  </head>
                +  <body>
                +    <script src="logic_ternary_test.js"></script>
                +  </body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/blocks/logic_ternary_test.js b/blockly/webif/static/blockly/tests/blocks/logic_ternary_test.js
                new file mode 100644
                index 000000000..0157c5eed
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/blocks/logic_ternary_test.js
                @@ -0,0 +1,316 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function test_logic_ternary_structure() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    assertEquals(3, block.inputList && block.inputList.length);
                +    assertEquals(1, block.getInput('IF').connection.check_.length);
                +    assertEquals('Boolean', block.getInput('IF').connection.check_[0]);
                +    assertTrue(!!block.onchangeWrapper_); // Has onchange handler
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachSameTypeCheckInThenAndElseWithoutParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +
                +    var string1 = workspace.newBlock('text');
                +    var string2 = workspace.newBlock('text_charAt');
                +
                +    block.getInput('THEN').connection.connect(string1.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string1.getRootBlock());
                +    block.getInput('ELSE').connection.connect(string2.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string1.getRootBlock());  // Still connected.
                +    assertEquals(block, string2.getRootBlock());
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithoutParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(block, number.getRootBlock());
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachSameTypeCheckInThenAndElseWithMatchingParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var parent = workspace.newBlock('text_trim');
                +
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    assertEquals(parent, block.getRootBlock());
                +
                +    var string1 = workspace.newBlock('text');
                +    var string2 = workspace.newBlock('text_charAt');
                +
                +    block.getInput('THEN').connection.connect(string1.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string1.getRootBlock());
                +    block.getInput('ELSE').connection.connect(string2.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string1.getRootBlock());  // Input THEN still connected.
                +    assertEquals(parent, string2.getRootBlock());
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithUncheckedParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var parent = workspace.newBlock('text_print');
                +
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    assertEquals(parent, block.parentBlock_);
                +
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(parent, number.getRootBlock());
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithPermissiveParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var parent = workspace.newBlock('text_length');  // Allows String or Array
                +
                +    parent.getInput('VALUE').connection.connect(block.outputConnection);
                +    assertEquals(parent, block.parentBlock_);
                +
                +    var string = workspace.newBlock('text');
                +    var array = workspace.newBlock('lists_create_empty');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(array.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(parent, array.getRootBlock());
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachMismatchTypeToThen_breakWithParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var parent = workspace.newBlock('text_length');  // Allows String or Array
                +
                +    parent.getInput('VALUE').connection.connect(block.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.parentBlock_);
                +
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('ELSE').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());
                +
                +    // Adding mismatching number.
                +    block.getInput('THEN').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, block.getRootBlock());  // Disconnected from parent.
                +    assertEquals(block, number.getRootBlock());
                +    assertEquals(block, string.getRootBlock());  // ELSE string still connected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachMismatchTypeToElse_breakWithParent() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var parent = workspace.newBlock('text_length');  // Allows String or Array
                +
                +    parent.getInput('VALUE').connection.connect(block.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.parentBlock_);
                +
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Still connected to parent.
                +    assertEquals(parent, string.getRootBlock());
                +
                +    // Adding mismatching number.
                +    block.getInput('ELSE').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, block.getRootBlock());  // Disconnected from parent.
                +    assertEquals(block, number.getRootBlock());
                +    assertEquals(block, string.getRootBlock());  // THEN string still connected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachToUncheckedParentWithDifferentTypes() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(block, number.getRootBlock());
                +
                +    // Attaching to parent.
                +    var parent = workspace.newBlock('text_print');
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    assertEquals(parent, block.getRootBlock());
                +    assertEquals(parent, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(parent, number.getRootBlock());  // Input ELSE still connected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachToPermissiveParentWithDifferentTypes() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var string = workspace.newBlock('text');
                +    var array = workspace.newBlock('lists_create_empty');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(array.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(block, array.getRootBlock());
                +
                +    // Attaching to parent.
                +    var parent = workspace.newBlock('text_print');
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());
                +    assertEquals(parent, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(parent, array.getRootBlock());  // Input ELSE still connected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachToParentWithMismatchingThen_disconnectThen() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var number = workspace.newBlock('math_number');
                +    var string = workspace.newBlock('text');
                +
                +    block.getInput('THEN').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, number.getRootBlock());
                +    block.getInput('ELSE').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, number.getRootBlock());  // Input THEN still connected.
                +    assertEquals(block, string.getRootBlock());
                +
                +    // Attaching to parent.
                +    var parent = workspace.newBlock('text_trim');
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Successful connection to parent.
                +    assertEquals(parent, string.getRootBlock());  // Input ELSE still connected.
                +    assertEquals(number, number.getRootBlock());  // Input THEN disconnected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_logic_ternary_attachToParentWithMismatchingElse_disconnectElse() {
                +  var workspace = new Blockly.Workspace();
                +  try {
                +    var block = workspace.newBlock('logic_ternary');
                +    var string = workspace.newBlock('text');
                +    var number = workspace.newBlock('math_number');
                +
                +    block.getInput('THEN').connection.connect(string.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());
                +    block.getInput('ELSE').connection.connect(number.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(block, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(block, number.getRootBlock());
                +
                +    // Attaching to parent.
                +    var parent = workspace.newBlock('text_trim');
                +    parent.getInput('TEXT').connection.connect(block.outputConnection);
                +    Blockly.Events.fireNow_();  // Force synchronous onchange() call.
                +    assertEquals(parent, block.getRootBlock());  // Successful connection to parent.
                +    assertEquals(parent, string.getRootBlock());  // Input THEN still connected.
                +    assertEquals(number, number.getRootBlock());  // Input ELSE disconnected.
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                diff --git a/blockly/webif/static/blockly/tests/generators/colour.xml b/blockly/webif/static/blockly/tests/generators/colour.xml
                new file mode 100644
                index 000000000..bae853d4d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/colour.xml
                @@ -0,0 +1,261 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="procedures_defnoreturn" x="260" y="14">
                +    <field name="NAME">test colour picker</field>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +           <block type="text">
                +             <field name="TEXT">static colour</field>
                +           </block>
                +         </value>
                +        <value name="ACTUAL">
                +          <block type="colour_picker">
                +            <field name="COLOUR">#ff6600</field>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT">#ff6600</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="630" y="13">
                +    <field name="NAME">test rgb</field>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +           <block type="text">
                +             <field name="TEXT">from rgb</field>
                +           </block>
                +         </value>
                +        <value name="ACTUAL">
                +          <block type="colour_rgb" inline="false">
                +            <value name="RED">
                +              <block type="math_number">
                +                <field name="NUM">100</field>
                +              </block>
                +            </value>
                +            <value name="GREEN">
                +              <block type="math_number">
                +                <field name="NUM">40</field>
                +              </block>
                +            </value>
                +            <value name="BLUE">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT">#ff6600</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="unittest_main" x="-5" y="49">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test colour picker"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test blend"></mutation>
                +            <next>
                +              <block type="procedures_callnoreturn">
                +                <mutation name="test rgb"></mutation>
                +                <next>
                +                  <block type="procedures_callnoreturn">
                +                    <mutation name="test colour random"></mutation>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-7" y="223">
                +    <field name="NAME">test colour random</field>
                +    <statement name="STACK">
                +      <block type="controls_repeat_ext" inline="true">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +        <statement name="DO">
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">item</field>
                +            <value name="VALUE">
                +              <block type="colour_random"></block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">test name</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="text_length" inline="false">
                +                    <value name="VALUE">
                +                      <block type="variables_get">
                +                        <field name="VAR">item</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">7</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                       <block type="text">
                +                         <field name="TEXT">test name</field>
                +                       </block>
                +                     </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_charAt">
                +                        <mutation at="false"></mutation>
                +                        <field name="WHERE">FIRST</field>
                +                        <value name="VALUE">
                +                          <block type="variables_get">
                +                            <field name="VAR">item</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">#</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_for">
                +                        <field name="VAR">i</field>
                +                        <value name="FROM">
                +                          <block type="math_number">
                +                            <field name="NUM">2</field>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="math_number">
                +                            <field name="NUM">7</field>
                +                          </block>
                +                        </value>
                +                        <statement name="DO">
                +                          <block type="unittest_assertvalue" inline="false">
                +                            <value name="MESSAGE">
                +                               <block type="text">
                +                                 <field name="TEXT">test name</field>
                +                               </block>
                +                             </value>
                +                            <field name="EXPECTED">TRUE</field>
                +                            <value name="ACTUAL">
                +                              <block type="logic_compare">
                +                                <field name="OP">NEQ</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="text_indexOf" inline="false">
                +                                    <field name="END">FIRST</field>
                +                                    <value name="VALUE">
                +                                      <block type="text">
                +                                        <field name="TEXT">abcdefABDEF0123456789</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="FIND">
                +                                      <block type="text_charAt">
                +                                        <mutation at="true"></mutation>
                +                                        <field name="WHERE">FROM_START</field>
                +                                        <value name="VALUE">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">item</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">i</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </statement>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </statement>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="520" y="205">
                +    <field name="NAME">test blend</field>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +           <block type="text">
                +             <field name="TEXT">blend</field>
                +           </block>
                +         </value>
                +        <value name="ACTUAL">
                +          <block type="colour_blend" inline="false">
                +            <value name="COLOUR1">
                +              <block type="colour_picker">
                +                <field name="COLOUR">#ff0000</field>
                +              </block>
                +            </value>
                +            <value name="COLOUR2">
                +              <block type="colour_rgb" inline="false">
                +                <value name="RED">
                +                  <block type="math_number">
                +                    <field name="NUM">100</field>
                +                  </block>
                +                </value>
                +                <value name="GREEN">
                +                  <block type="math_number">
                +                    <field name="NUM">40</field>
                +                  </block>
                +                </value>
                +                <value name="BLUE">
                +                  <block type="math_number">
                +                    <field name="NUM">0</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="RATIO">
                +              <block type="math_number">
                +                <field name="NUM">0.4</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT">#ff2900</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/generators/functions.xml b/blockly/webif/static/blockly/tests/generators/functions.xml
                new file mode 100644
                index 000000000..b189ed355
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/functions.xml
                @@ -0,0 +1,559 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="0" y="1">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test procedure"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test function"></mutation>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">test recurse</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="procedures_callreturn" inline="false">
                +                    <mutation name="recurse">
                +                      <arg name="n"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">-1-2-1-3-1-2-1-</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-3" y="249">
                +    <field name="NAME">test procedure</field>
                +    <statement name="STACK">
                +      <block type="procedures_callnoreturn" inline="false">
                +        <mutation name="procedure 1">
                +          <arg name="proc x"></arg>
                +          <arg name="proc y"></arg>
                +        </mutation>
                +        <value name="ARG0">
                +          <block type="math_number">
                +            <field name="NUM">8</field>
                +          </block>
                +        </value>
                +        <value name="ARG1">
                +          <block type="math_number">
                +            <field name="NUM">2</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +               <block type="text">
                +                 <field name="TEXT">procedure with global</field>
                +               </block>
                +             </value>
                +            <value name="ACTUAL">
                +              <block type="variables_get">
                +                <field name="VAR">proc z</field>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">4</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="variables_set" inline="false">
                +                <field name="VAR">proc w</field>
                +                <value name="VALUE">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">FALSE</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="procedures_callnoreturn" inline="false">
                +                    <mutation name="procedure 2">
                +                      <arg name="proc x"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">FALSE</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertvalue" inline="false">
                +                        <value name="MESSAGE">
                +                           <block type="text">
                +                             <field name="TEXT">procedure no return</field>
                +                           </block>
                +                         </value>
                +                        <field name="EXPECTED">TRUE</field>
                +                        <value name="ACTUAL">
                +                          <block type="variables_get">
                +                            <field name="VAR">proc w</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="variables_set" inline="false">
                +                            <field name="VAR">proc w</field>
                +                            <value name="VALUE">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">FALSE</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="procedures_callnoreturn" inline="false">
                +                                <mutation name="procedure 2">
                +                                  <arg name="proc x"></arg>
                +                                </mutation>
                +                                <value name="ARG0">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertvalue" inline="false">
                +                                    <value name="MESSAGE">
                +                                       <block type="text">
                +                                         <field name="TEXT">procedure return</field>
                +                                       </block>
                +                                     </value>
                +                                    <field name="EXPECTED">FALSE</field>
                +                                    <value name="ACTUAL">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">proc w</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="302" y="277">
                +    <mutation>
                +      <arg name="proc x"></arg>
                +      <arg name="proc y"></arg>
                +    </mutation>
                +    <field name="NAME">procedure 1</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">proc z</field>
                +        <value name="VALUE">
                +          <block type="math_arithmetic">
                +            <field name="OP">DIVIDE</field>
                +            <value name="A">
                +              <block type="variables_get">
                +                <field name="VAR">proc x</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="variables_get">
                +                <field name="VAR">proc y</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="307" y="435">
                +    <mutation>
                +      <arg name="proc x"></arg>
                +    </mutation>
                +    <field name="NAME">procedure 2</field>
                +    <statement name="STACK">
                +      <block type="procedures_ifreturn">
                +        <mutation value="0"></mutation>
                +        <value name="CONDITION">
                +          <block type="variables_get">
                +            <field name="VAR">proc x</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">proc w</field>
                +            <value name="VALUE">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-2" y="731">
                +    <field name="NAME">test function</field>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +           <block type="text">
                +             <field name="TEXT">function with arguments</field>
                +           </block>
                +         </value>
                +        <value name="ACTUAL">
                +          <block type="procedures_callreturn" inline="false">
                +            <mutation name="function 1">
                +              <arg name="func x"></arg>
                +              <arg name="func y"></arg>
                +            </mutation>
                +            <value name="ARG0">
                +              <block type="math_number">
                +                <field name="NUM">2</field>
                +              </block>
                +            </value>
                +            <value name="ARG1">
                +              <block type="math_number">
                +                <field name="NUM">3</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">-1</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +               <block type="text">
                +                 <field name="TEXT">function with side effect</field>
                +               </block>
                +             </value>
                +            <value name="ACTUAL">
                +              <block type="variables_get">
                +                <field name="VAR">func z</field>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">side effect</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="variables_set" inline="false">
                +                <field name="VAR">func a</field>
                +                <value name="VALUE">
                +                  <block type="text">
                +                    <field name="TEXT">unchanged</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">func c</field>
                +                    <value name="VALUE">
                +                      <block type="text">
                +                        <field name="TEXT">global</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                           <block type="text">
                +                             <field name="TEXT">function with global</field>
                +                           </block>
                +                         </value>
                +                        <value name="ACTUAL">
                +                          <block type="procedures_callreturn" inline="false">
                +                            <mutation name="function 2">
                +                              <arg name="func a"></arg>
                +                            </mutation>
                +                            <value name="ARG0">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">3global</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                               <block type="text">
                +                                 <field name="TEXT">function with scope</field>
                +                               </block>
                +                             </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">func a</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">unchanged</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertvalue" inline="false">
                +                                <value name="MESSAGE">
                +                                   <block type="text">
                +                                     <field name="TEXT">function return</field>
                +                                   </block>
                +                                 </value>
                +                                <field name="EXPECTED">TRUE</field>
                +                                <value name="ACTUAL">
                +                                  <block type="procedures_callreturn" inline="false">
                +                                    <mutation name="function 3">
                +                                      <arg name="func a"></arg>
                +                                    </mutation>
                +                                    <value name="ARG0">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertvalue" inline="false">
                +                                    <value name="MESSAGE">
                +                                       <block type="text">
                +                                         <field name="TEXT">function no return</field>
                +                                       </block>
                +                                     </value>
                +                                    <field name="EXPECTED">FALSE</field>
                +                                    <value name="ACTUAL">
                +                                      <block type="procedures_callreturn" inline="false">
                +                                        <mutation name="function 3">
                +                                          <arg name="func a"></arg>
                +                                        </mutation>
                +                                        <value name="ARG0">
                +                                          <block type="logic_boolean">
                +                                            <field name="BOOL">FALSE</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" inline="false" x="-3" y="1384">
                +    <mutation>
                +      <arg name="func x"></arg>
                +      <arg name="func y"></arg>
                +    </mutation>
                +    <field name="NAME">function 1</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">func z</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">side effect</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="math_arithmetic">
                +        <field name="OP">MINUS</field>
                +        <value name="A">
                +          <block type="variables_get">
                +            <field name="VAR">func x</field>
                +          </block>
                +        </value>
                +        <value name="B">
                +          <block type="variables_get">
                +            <field name="VAR">func y</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defreturn" inline="false" x="-1" y="1503">
                +    <mutation>
                +      <arg name="func a"></arg>
                +    </mutation>
                +    <field name="NAME">function 2</field>
                +    <statement name="STACK">
                +      <block type="math_change" inline="false">
                +        <field name="VAR">func a</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="text_join" inline="false">
                +        <mutation items="2"></mutation>
                +        <value name="ADD0">
                +          <block type="variables_get">
                +            <field name="VAR">func a</field>
                +          </block>
                +        </value>
                +        <value name="ADD1">
                +          <block type="variables_get">
                +            <field name="VAR">func c</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defreturn" inline="false" x="0" y="1655">
                +    <mutation>
                +      <arg name="func a"></arg>
                +    </mutation>
                +    <field name="NAME">function 3</field>
                +    <statement name="STACK">
                +      <block type="procedures_ifreturn">
                +        <mutation value="1"></mutation>
                +        <value name="CONDITION">
                +          <block type="variables_get">
                +            <field name="VAR">func a</field>
                +          </block>
                +        </value>
                +        <value name="VALUE">
                +          <block type="logic_boolean">
                +            <field name="BOOL">TRUE</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="logic_boolean">
                +        <field name="BOOL">FALSE</field>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defreturn" inline="false" x="0" y="1789">
                +    <mutation>
                +      <arg name="n"></arg>
                +    </mutation>
                +    <field name="NAME">recurse</field>
                +    <statement name="STACK">
                +      <block type="controls_if" inline="false">
                +        <mutation else="1"></mutation>
                +        <value name="IF0">
                +          <block type="logic_compare">
                +            <field name="OP">GT</field>
                +            <value name="A">
                +              <block type="variables_get">
                +                <field name="VAR">n</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <statement name="DO0">
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">text</field>
                +            <value name="VALUE">
                +              <block type="text_join" inline="false">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="procedures_callreturn" inline="false">
                +                    <mutation name="recurse">
                +                      <arg name="n"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="math_arithmetic">
                +                        <field name="OP">MINUS</field>
                +                        <value name="A">
                +                          <block type="variables_get">
                +                            <field name="VAR">n</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="variables_get">
                +                    <field name="VAR">n</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="procedures_callreturn" inline="false">
                +                    <mutation name="recurse">
                +                      <arg name="n"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="math_arithmetic">
                +                        <field name="OP">MINUS</field>
                +                        <value name="A">
                +                          <block type="variables_get">
                +                            <field name="VAR">n</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +          </block>
                +        </statement>
                +        <statement name="ELSE">
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">text</field>
                +            <value name="VALUE">
                +              <block type="text">
                +                <field name="TEXT">-</field>
                +              </block>
                +            </value>
                +          </block>
                +        </statement>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="variables_get">
                +        <field name="VAR">text</field>
                +      </block>
                +    </value>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/generators/index.html b/blockly/webif/static/blockly/tests/generators/index.html
                new file mode 100644
                index 000000000..a4d39ae97
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/index.html
                @@ -0,0 +1,367 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +<meta charset="utf-8">
                +<title>Blockly Generator Tests</title>
                +<script src="../../blockly_uncompressed.js"></script>
                +
                +<script src="../../generators/javascript.js"></script>
                +<script src="unittest_javascript.js"></script>
                +<script src="../../generators/javascript/logic.js"></script>
                +<script src="../../generators/javascript/loops.js"></script>
                +<script src="../../generators/javascript/math.js"></script>
                +<script src="../../generators/javascript/text.js"></script>
                +<script src="../../generators/javascript/lists.js"></script>
                +<script src="../../generators/javascript/colour.js"></script>
                +<script src="../../generators/javascript/variables.js"></script>
                +<script src="../../generators/javascript/procedures.js"></script>
                +
                +<script src="../../generators/python.js"></script>
                +<script src="unittest_python.js"></script>
                +<script src="../../generators/python/logic.js"></script>
                +<script src="../../generators/python/loops.js"></script>
                +<script src="../../generators/python/math.js"></script>
                +<script src="../../generators/python/text.js"></script>
                +<script src="../../generators/python/lists.js"></script>
                +<script src="../../generators/python/colour.js"></script>
                +<script src="../../generators/python/variables.js"></script>
                +<script src="../../generators/python/procedures.js"></script>
                +
                +<script src="../../generators/php.js"></script>
                +<script src="unittest_php.js"></script>
                +<script src="../../generators/php/logic.js"></script>
                +<script src="../../generators/php/loops.js"></script>
                +<script src="../../generators/php/math.js"></script>
                +<script src="../../generators/php/text.js"></script>
                +<script src="../../generators/php/lists.js"></script>
                +<script src="../../generators/php/colour.js"></script>
                +<script src="../../generators/php/variables.js"></script>
                +<script src="../../generators/php/procedures.js"></script>
                +
                +<script src="../../generators/lua.js"></script>
                +<script src="unittest_lua.js"></script>
                +<script src="../../generators/lua/logic.js"></script>
                +<script src="../../generators/lua/loops.js"></script>
                +<script src="../../generators/lua/math.js"></script>
                +<script src="../../generators/lua/text.js"></script>
                +<script src="../../generators/lua/lists.js"></script>
                +<script src="../../generators/lua/colour.js"></script>
                +<script src="../../generators/lua/variables.js"></script>
                +<script src="../../generators/lua/procedures.js"></script>
                +
                +<script src="../../generators/dart.js"></script>
                +<script src="unittest_dart.js"></script>
                +<script src="../../generators/dart/logic.js"></script>
                +<script src="../../generators/dart/loops.js"></script>
                +<script src="../../generators/dart/math.js"></script>
                +<script src="../../generators/dart/text.js"></script>
                +<script src="../../generators/dart/lists.js"></script>
                +<script src="../../generators/dart/colour.js"></script>
                +<script src="../../generators/dart/variables.js"></script>
                +<script src="../../generators/dart/procedures.js"></script>
                +
                +<script src="unittest.js"></script>
                +<script src="../../msg/messages.js"></script>
                +<script src="../../blocks/logic.js"></script>
                +<script src="../../blocks/loops.js"></script>
                +<script src="../../blocks/math.js"></script>
                +<script src="../../blocks/text.js"></script>
                +<script src="../../blocks/lists.js"></script>
                +<script src="../../blocks/colour.js"></script>
                +<script src="../../blocks/variables.js"></script>
                +<script src="../../blocks/procedures.js"></script>
                +<script>
                +'use strict';
                +
                +var workspace = null;
                +
                +function start() {
                +  workspace = Blockly.inject('blocklyDiv',
                +      {grid:
                +         {spacing: 25,
                +          length: 3,
                +          colour: '#ccc',
                +          snap: true},
                +       media: '../../media/',
                +       toolbox: document.getElementById('toolbox'),
                +       zoom: {controls: true, wheel: true}
                +       });
                +  changeIndex();
                +}
                +
                +function loadXml() {
                +  var dropdown = document.getElementById('testUrl');
                +  var url = dropdown.options[dropdown.selectedIndex].value;
                +  if (!url) {
                +    url = window.prompt('Enter URL of test file.');
                +    if (!url) {
                +      return;
                +    }
                +  }
                +  var xmlText = fetchFile(url);
                +  if (xmlText !== null) {
                +    fromXml(xmlText);
                +  }
                +}
                +
                +function fetchFile(xmlUrl) {
                +  try {
                +    var xmlHttp = new XMLHttpRequest();
                +    xmlHttp.open('GET', xmlUrl, false);
                +    xmlHttp.setRequestHeader('Content-Type', 'text/xml');
                +    xmlHttp.send('');
                +  } catch (e) {
                +    // Attempt to diagnose the problem.
                +    var msg = 'Error: Unable to load XML data.\n';
                +    if (window.location.protocol == 'file:') {
                +      msg += 'This may be due to a security restriction preventing\n' +
                +          'access when using the file:// protocol.\n' +
                +          'Use an http webserver, or a less paranoid browser.\n';
                +    }
                +    alert(msg + '\n' + e);
                +    return null;
                +  }
                +  return xmlHttp.responseText;
                +}
                +
                +function fromXml(xmlText) {
                +  var output = document.getElementById('importExport');
                +  output.value = xmlText;
                +  output.scrollTop = 0;
                +  output.scrollLeft = 0;
                +  workspace.clear();
                +  try {
                +    var xmlDoc = Blockly.Xml.textToDom(xmlText);
                +  } catch (e) {
                +    alert('Error parsing XML:\n' + e);
                +    return;
                +  }
                +  Blockly.Xml.domToWorkspace(xmlDoc, workspace);
                +}
                +
                +function setOutput(text) {
                +  var output = document.getElementById('importExport');
                +  output.value = text;
                +  output.focus();
                +  output.select();
                +}
                +
                +function toXml() {
                +  var xmlDom = Blockly.Xml.workspaceToDom(workspace, /* opt_noId */ true);
                +  var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
                +  xmlText = xmlText.replace(/ id="\d+"/g, '');
                +  setOutput(xmlText);
                +}
                +
                +function toJavaScript() {
                +  var code = '\'use strict\';\n\n'
                +  code += Blockly.JavaScript.workspaceToCode(workspace);
                +  setOutput(code);
                +}
                +
                +function toPython() {
                +  var code = Blockly.Python.workspaceToCode(workspace);
                +  setOutput(code);
                +}
                +
                +function toPhp() {
                +  var code = Blockly.PHP.workspaceToCode(workspace);
                +  setOutput(code);
                +}
                +
                +function toLua() {
                +  var code = Blockly.Lua.workspaceToCode(workspace);
                +  setOutput(code);
                +}
                +
                +function toDart() {
                +  var code = Blockly.Dart.workspaceToCode(workspace);
                +  setOutput(code);
                +}
                +
                +function changeIndex() {
                +  var oneBasedIndex = document.getElementById('indexing').checked;
                +  workspace.options.oneBasedIndex = oneBasedIndex;
                +  workspace.toolbox_.flyout_.workspace_.options.oneBasedIndex = oneBasedIndex;
                +}
                +</script>
                +
                +<style>
                +html, body {
                +  height: 100%;
                +  overflow: hidden;
                +}
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  margin: 0 5px;
                +}
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +#blocklyDiv {
                +  float: right;
                +  height: 95%;
                +  width: 69%;
                +  margin-top: 5px;
                +}
                +#importExport {
                +  height: 100%;
                +  width: 100%;
                +}
                +</style>
                +</head>
                +<body onload="start()">
                +
                +  <div id="blocklyDiv"></div>
                +
                +  <xml id="toolbox" style="display: none">
                +    <category name="Unit test" colour="65">
                +      <block type="unittest_main"></block>
                +      <block type="unittest_assertequals">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="unittest_assertvalue">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="unittest_fail"></block>
                +      <block type="unittest_adjustindex"></block>
                +    </category>
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="controls_ifelse"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext"></block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for"></block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +      <block type="math_trig"></block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property"></block>
                +      <block type="math_round"></block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo"></block>
                +      <block type="math_constrain"></block>
                +      <block type="math_random_int"></block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append"></block>
                +      <block type="text_length"></block>
                +      <block type="text_isEmpty"></block>
                +      <block type="text_indexOf"></block>
                +      <block type="text_charAt"></block>
                +      <block type="text_getSubstring"></block>
                +      <block type="text_changeCase"></block>
                +      <block type="text_trim"></block>
                +      <block type="text_print"></block>
                +      <block type="text_prompt_ext"></block>
                +      <block type="text_count"></block>
                +      <block type="text_replace"></block>
                +      <block type="text_reverse"></block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_empty"></block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat"></block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf"></block>
                +      <block type="lists_getIndex"></block>
                +      <block type="lists_setIndex"></block>
                +      <block type="lists_getSublist"></block>
                +      <block type="lists_sort"></block>
                +      <block type="lists_split"></block>
                +      <block type="lists_reverse"></block>
                +    </category>
                +    <category name="Colour" colour="20">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb"></block>
                +      <block type="colour_blend"></block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +  </xml>
                +
                +  <table height="95%" width="30%"><tr><td valign="top">
                +    <h1>Blockly Generator Tests</h1>
                +
                +    <p><a href="https://developers.google.com/blockly/guides/modify/web/unit-testing">See the docs</a> for details on running the tests.
                +
                +    <p>
                +      <select id="testUrl">
                +        <option value="logic.xml">Logic</option>
                +        <option value="loops1.xml">Loops 1 (repeat, while, foreach)</option>
                +        <option value="loops2.xml">Loops 2 (count)</option>
                +        <option value="loops3.xml">Loops 3 (continue, break)</option>
                +        <option value="math.xml">Math</option>
                +        <option value="text.xml">Text</option>
                +        <option value="lists.xml">Lists</option>
                +        <option value="colour.xml">Colour</option>
                +        <option value="variables.xml">Variables</option>
                +        <option value="functions.xml">Functions</option>
                +        <option value="">Other...</option>
                +      </select>
                +      <input type="button" value="Load" onclick="loadXml()">
                +    </p>
                +
                +    <p>
                +      <input id="indexing" type="checkbox" onchange="changeIndex()" checked>
                +      <label for="indexing">Generate with one-based indexing</label>
                +    </p>
                +
                +    <p>
                +      Generate:
                +      <input type="button" value="XML" onclick="toXml()">
                +      <div style="display: inline-block;">
                +        <input type="button" value="JavaScript" onclick="toJavaScript()">
                +        <br><a target="_blank" href="https://repl.it/languages/javascript">interpreter</a>
                +      </div>
                +      <div style="display: inline-block;">
                +        <input type="button" value="Python" onclick="toPython()">
                +        <br><a target="_blank" href="https://repl.it/languages/python">interpreter</a>
                +      </div>
                +      <div style="display: inline-block;">
                +        <input type="button" value="PHP" onclick="toPhp()">
                +        <br><a target="_blank" href="https://repl.it/languages/php">interpreter</a>
                +      </div>
                +      <div style="display: inline-block;">
                +        <input type="button" value="Lua" onclick="toLua()">
                +        <br><a target="_blank" href="https://repl.it/languages/lua">interpreter</a>
                +      </div>
                +      <div style="display: inline-block;">
                +        <input type="button" value="Dart" onclick="toDart()">
                +        <br><a target="_blank" href="https://dartpad.dartlang.org/">interpreter</a>
                +      </div>
                +    </p>
                +  </td></tr><tr><td height="99%">
                +    <textarea id="importExport" readonly="readonly" wrap="off"></textarea>
                +  </td></tr></table>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/generators/lists.xml b/blockly/webif/static/blockly/tests/generators/lists.xml
                new file mode 100644
                index 000000000..aae25dfe6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/lists.xml
                @@ -0,0 +1,8284 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="13" y="13">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test create"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test empty"></mutation>
                +            <next>
                +              <block type="procedures_callnoreturn">
                +                <mutation name="test length"></mutation>
                +                <next>
                +                  <block type="procedures_callnoreturn">
                +                    <mutation name="test find simple"></mutation>
                +                    <next>
                +                      <block type="procedures_callnoreturn">
                +                        <mutation name="test find complex"></mutation>
                +                        <next>
                +                          <block type="procedures_callnoreturn">
                +                            <mutation name="test get simple"></mutation>
                +                            <next>
                +                              <block type="procedures_callnoreturn">
                +                                <mutation name="test get complex"></mutation>
                +                                <next>
                +                                  <block type="procedures_callnoreturn">
                +                                    <mutation name="test getRemove"></mutation>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn">
                +                                        <mutation name="test remove"></mutation>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn">
                +                                            <mutation name="test set"></mutation>
                +                                            <next>
                +                                              <block type="procedures_callnoreturn">
                +                                                <mutation name="test insert"></mutation>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn">
                +                                                    <mutation name="test sublist simple"></mutation>
                +                                                    <next>
                +                                                      <block type="procedures_callnoreturn">
                +                                                        <mutation name="test sublist complex"></mutation>
                +                                                        <next>
                +                                                          <block type="procedures_callnoreturn">
                +                                                            <mutation name="test join"></mutation>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn">
                +                                                                <mutation name="test split"></mutation>
                +                                                                <next>
                +                                                                  <block type="procedures_callnoreturn">
                +                                                                    <mutation name="test sort alphabetic"></mutation>
                +                                                                    <next>
                +                                                                      <block type="procedures_callnoreturn">
                +                                                                        <mutation name="test sort ignoreCase"></mutation>
                +                                                                        <next>
                +                                                                          <block type="procedures_callnoreturn">
                +                                                                            <mutation name="test sort numeric"></mutation>
                +                                                                            <next>
                +                                                                              <block type="procedures_callnoreturn">
                +                                                                                <mutation name="test reverse"></mutation>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="538">
                +    <mutation>
                +      <arg name="test name"></arg>
                +    </mutation>
                +    <field name="NAME">check number of calls</field>
                +    <comment pinned="false" h="78" w="257">Checks that the number of calls is one in order to confirm that a function was only called once.</comment>
                +    <statement name="STACK">
                +      <block type="text_append">
                +        <field name="VAR">test name</field>
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">number of calls</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="variables_get">
                +                <field name="VAR">test name</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="variables_get">
                +                <field name="VAR">number of calls</field>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="713">
                +    <field name="NAME">test create</field>
                +    <comment pinned="false" h="80" w="160">Tests the "create list with" and "create empty list" blocks.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">create empty</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="lists_create_with">
                +            <mutation items="0"></mutation>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="lists_create_empty"></block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">create items</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="2"></mutation>
                +                <value name="ADD0">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">love</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="2"></mutation>
                +                <value name="ADD0">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">love</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">create repeated</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_repeat" inline="true">
                +                    <value name="ITEM">
                +                      <block type="text">
                +                        <field name="TEXT">Eject</field>
                +                      </block>
                +                    </value>
                +                    <value name="NUM">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Eject</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Eject</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">Eject</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">create repeated order</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="lists_repeat" inline="true">
                +                        <value name="ITEM">
                +                          <block type="text">
                +                            <field name="TEXT">Eject</field>
                +                          </block>
                +                        </value>
                +                        <value name="NUM">
                +                          <block type="math_arithmetic">
                +                            <field name="OP">ADD</field>
                +                            <value name="A">
                +                              <block type="math_number">
                +                                <field name="NUM">0</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">3</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Eject</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Eject</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="text">
                +                            <field name="TEXT">Eject</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="1163">
                +    <mutation statements="false"></mutation>
                +    <field name="NAME">get empty list</field>
                +    <comment pinned="false" h="80" w="160">Creates an empty list for use with the empty test.</comment>
                +    <value name="RETURN">
                +      <block type="lists_create_empty"></block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1238">
                +    <field name="NAME">test empty</field>
                +    <comment pinned="false" h="80" w="160">Tests the "is empty" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">FALSE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">not empty</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="lists_isEmpty" inline="true">
                +            <value name="VALUE">
                +              <block type="lists_create_with" inline="false">
                +                <mutation items="1"></mutation>
                +                <value name="ADD0">
                +                  <block type="math_number">
                +                    <field name="NUM">0</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">TRUE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">empty</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_isEmpty" inline="true">
                +                <value name="VALUE">
                +                  <block type="lists_create_empty"></block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">empty complex</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_isEmpty" inline="true">
                +                    <value name="VALUE">
                +                      <block type="procedures_callreturn">
                +                        <mutation name="get empty list"></mutation>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">TRUE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">empty order</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="lists_isEmpty" inline="true">
                +                        <value name="VALUE">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="lists_create_empty"></block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1563">
                +    <field name="NAME">test length</field>
                +    <comment pinned="false" h="80" w="160">Tests the "length" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">zero length</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="lists_length" inline="false">
                +            <value name="VALUE">
                +              <block type="lists_create_empty"></block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">one length</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_length" inline="false">
                +                <value name="VALUE">
                +                  <block type="lists_create_with" inline="false">
                +                    <mutation items="1"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">cat</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">three length</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_length" inline="false">
                +                    <value name="VALUE">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">cat</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="lists_create_empty"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">3</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">two length order</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="lists_length" inline="false">
                +                        <value name="VALUE">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="lists_create_with" inline="false">
                +                                <mutation items="2"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="text">
                +                                    <field name="TEXT">cat</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1988">
                +    <field name="NAME">test find simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "find" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="4"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Alice</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Eve</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Bob</field>
                +              </block>
                +            </value>
                +            <value name="ADD3">
                +              <block type="text">
                +                <field name="TEXT">Eve</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">find first simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_indexOf" inline="false">
                +                <field name="END">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="FIND">
                +                  <block type="text">
                +                    <field name="TEXT">Eve</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="unittest_adjustindex">
                +                <value name="INDEX">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">find last simple</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_indexOf" inline="false">
                +                    <field name="END">LAST</field>
                +                    <value name="VALUE">
                +                      <block type="variables_get">
                +                        <field name="VAR">list</field>
                +                      </block>
                +                    </value>
                +                    <value name="FIND">
                +                      <block type="text">
                +                        <field name="TEXT">Eve</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">find none simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="lists_indexOf" inline="false">
                +                        <field name="END">FIRST</field>
                +                        <value name="VALUE">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="FIND">
                +                          <block type="text">
                +                            <field name="TEXT">Dave</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="unittest_adjustindex">
                +                        <value name="INDEX">
                +                          <block type="math_number">
                +                            <field name="NUM">-1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="2438">
                +    <field name="NAME">get names</field>
                +    <comment pinned="false" h="80" w="160">Creates a list for use with the find test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="lists_create_with" inline="true">
                +        <mutation items="4"></mutation>
                +        <value name="ADD0">
                +          <block type="text">
                +            <field name="TEXT">Alice</field>
                +          </block>
                +        </value>
                +        <value name="ADD1">
                +          <block type="text">
                +            <field name="TEXT">Eve</field>
                +          </block>
                +        </value>
                +        <value name="ADD2">
                +          <block type="text">
                +            <field name="TEXT">Bob</field>
                +          </block>
                +        </value>
                +        <value name="ADD3">
                +          <block type="text">
                +            <field name="TEXT">Eve</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="2563">
                +    <field name="NAME">test find complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "find" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">number of calls</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">find first complex</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_indexOf" inline="false">
                +                <field name="END">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="procedures_callreturn">
                +                    <mutation name="get names"></mutation>
                +                  </block>
                +                </value>
                +                <value name="FIND">
                +                  <block type="text">
                +                    <field name="TEXT">Eve</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="unittest_adjustindex">
                +                <value name="INDEX">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="procedures_callnoreturn" inline="true">
                +                <mutation name="check number of calls">
                +                  <arg name="test name"></arg>
                +                </mutation>
                +                <value name="ARG0">
                +                  <block type="text">
                +                    <field name="TEXT">find first complex</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">number of calls</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">find first order complex</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_indexOf" inline="false">
                +                            <field name="END">FIRST</field>
                +                            <value name="VALUE">
                +                              <block type="logic_ternary" inline="true">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="procedures_callreturn">
                +                                    <mutation name="get names"></mutation>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="FIND">
                +                              <block type="text">
                +                                <field name="TEXT">Eve</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="procedures_callnoreturn" inline="true">
                +                            <mutation name="check number of calls">
                +                              <arg name="test name"></arg>
                +                            </mutation>
                +                            <value name="ARG0">
                +                              <block type="text">
                +                                <field name="TEXT">find first order complex</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">number of calls</field>
                +                                <value name="VALUE">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">find last complex</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="lists_indexOf" inline="false">
                +                                        <field name="END">LAST</field>
                +                                        <value name="VALUE">
                +                                          <block type="procedures_callreturn">
                +                                            <mutation name="get names"></mutation>
                +                                          </block>
                +                                        </value>
                +                                        <value name="FIND">
                +                                          <block type="text">
                +                                            <field name="TEXT">Eve</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">3</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn" inline="true">
                +                                        <mutation name="check number of calls">
                +                                          <arg name="test name"></arg>
                +                                        </mutation>
                +                                        <value name="ARG0">
                +                                          <block type="text">
                +                                            <field name="TEXT">find last complex</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set">
                +                                            <field name="VAR">number of calls</field>
                +                                            <value name="VALUE">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">find last order complex</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="lists_indexOf" inline="false">
                +                                                    <field name="END">LAST</field>
                +                                                    <value name="VALUE">
                +                                                      <block type="logic_ternary" inline="true">
                +                                                        <value name="IF">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="THEN">
                +                                                          <block type="procedures_callreturn">
                +                                                            <mutation name="get names"></mutation>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ELSE">
                +                                                          <block type="logic_null"></block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="FIND">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Eve</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="unittest_adjustindex">
                +                                                    <value name="INDEX">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">3</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                    <mutation name="check number of calls">
                +                                                      <arg name="test name"></arg>
                +                                                    </mutation>
                +                                                    <value name="ARG0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">find last order complex</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set">
                +                                                        <field name="VAR">number of calls</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">find none complex</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="lists_indexOf" inline="false">
                +                                                                <field name="END">FIRST</field>
                +                                                                <value name="VALUE">
                +                                                                  <block type="procedures_callreturn">
                +                                                                    <mutation name="get names"></mutation>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="FIND">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">Dave</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="unittest_adjustindex">
                +                                                                <value name="INDEX">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">-1</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                <mutation name="check number of calls">
                +                                                                  <arg name="test name"></arg>
                +                                                                </mutation>
                +                                                                <value name="ARG0">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">find none complex</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set">
                +                                                                    <field name="VAR">number of calls</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">0</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">find none order complex</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="lists_indexOf" inline="false">
                +                                                                            <field name="END">FIRST</field>
                +                                                                            <value name="VALUE">
                +                                                                              <block type="logic_ternary" inline="true">
                +                                                                                <value name="IF">
                +                                                                                  <block type="logic_boolean">
                +                                                                                    <field name="BOOL">TRUE</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="THEN">
                +                                                                                  <block type="procedures_callreturn">
                +                                                                                    <mutation name="get names"></mutation>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ELSE">
                +                                                                                  <block type="logic_null"></block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="FIND">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">Dave</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="EXPECTED">
                +                                                                          <block type="unittest_adjustindex">
                +                                                                            <value name="INDEX">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">-1</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                            <mutation name="check number of calls">
                +                                                                              <arg name="test name"></arg>
                +                                                                            </mutation>
                +                                                                            <value name="ARG0">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">find none order complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="3738">
                +    <field name="NAME">test get simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Spock</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">McCoy</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">get first simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_getIndex">
                +                <mutation statement="false" at="false"></mutation>
                +                <field name="MODE">GET</field>
                +                <field name="WHERE">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">get last simple</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_getIndex">
                +                    <mutation statement="false" at="false"></mutation>
                +                    <field name="MODE">GET</field>
                +                    <field name="WHERE">LAST</field>
                +                    <value name="VALUE">
                +                      <block type="variables_get">
                +                        <field name="VAR">list</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">McCoy</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">TRUE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">get random simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_compare">
                +                        <field name="OP">GT</field>
                +                        <value name="A">
                +                          <block type="lists_indexOf" inline="false">
                +                            <field name="END">FIRST</field>
                +                            <value name="VALUE">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="FIND">
                +                              <block type="lists_getIndex">
                +                                <mutation statement="false" at="false"></mutation>
                +                                <field name="MODE">GET</field>
                +                                <field name="WHERE">RANDOM</field>
                +                                <value name="VALUE">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">list</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">-1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">get # simple</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_getIndex">
                +                            <mutation statement="false" at="true"></mutation>
                +                            <field name="MODE">GET</field>
                +                            <field name="WHERE">FROM_START</field>
                +                            <value name="VALUE">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="AT">
                +                              <block type="unittest_adjustindex">
                +                                <value name="INDEX">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">Spock</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">get # order simple</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="lists_getIndex">
                +                                <mutation statement="false" at="true"></mutation>
                +                                <field name="MODE">GET</field>
                +                                <field name="WHERE">FROM_START</field>
                +                                <value name="VALUE">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">list</field>
                +                                  </block>
                +                                </value>
                +                                <value name="AT">
                +                                  <block type="logic_ternary" inline="true">
                +                                    <value name="IF">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="THEN">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ELSE">
                +                                      <block type="logic_null"></block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">Spock</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">get #-end simple</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="lists_getIndex">
                +                                    <mutation statement="false" at="true"></mutation>
                +                                    <field name="MODE">GET</field>
                +                                    <field name="WHERE">FROM_END</field>
                +                                    <value name="VALUE">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">list</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="AT">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">2</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT">Kirk</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">get #-end order simple</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="lists_getIndex">
                +                                        <mutation statement="false" at="true"></mutation>
                +                                        <field name="MODE">GET</field>
                +                                        <field name="WHERE">FROM_END</field>
                +                                        <comment pinned="false" h="81" w="289">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                        <value name="VALUE">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT">
                +                                          <block type="math_arithmetic">
                +                                            <field name="OP">ADD</field>
                +                                            <value name="A">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="unittest_adjustindex">
                +                                                <value name="INDEX">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">2</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">Kirk</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="4538">
                +    <field name="NAME">get star wars</field>
                +    <comment pinned="false" h="80" w="160">Creates a list for use with the get test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="lists_create_with" inline="true">
                +        <mutation items="3"></mutation>
                +        <value name="ADD0">
                +          <block type="text">
                +            <field name="TEXT">Kirk</field>
                +          </block>
                +        </value>
                +        <value name="ADD1">
                +          <block type="text">
                +            <field name="TEXT">Spock</field>
                +          </block>
                +        </value>
                +        <value name="ADD2">
                +          <block type="text">
                +            <field name="TEXT">McCoy</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="4663">
                +    <field name="NAME">test get complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Spock</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">McCoy</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="variables_set">
                +            <field name="VAR">number of calls</field>
                +            <value name="VALUE">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">get first complex</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_getIndex">
                +                    <mutation statement="false" at="false"></mutation>
                +                    <field name="MODE">GET</field>
                +                    <field name="WHERE">FIRST</field>
                +                    <value name="VALUE">
                +                      <block type="procedures_callreturn">
                +                        <mutation name="get star wars"></mutation>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">Kirk</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="procedures_callnoreturn" inline="true">
                +                    <mutation name="check number of calls">
                +                      <arg name="test name"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="text">
                +                        <field name="TEXT">get first complex</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="variables_set">
                +                        <field name="VAR">number of calls</field>
                +                        <value name="VALUE">
                +                          <block type="math_number">
                +                            <field name="NUM">0</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">get first order complex</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="lists_getIndex">
                +                                <mutation statement="false" at="false"></mutation>
                +                                <field name="MODE">GET</field>
                +                                <field name="WHERE">FIRST</field>
                +                                <value name="VALUE">
                +                                  <block type="logic_ternary" inline="true">
                +                                    <value name="IF">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="THEN">
                +                                      <block type="procedures_callreturn">
                +                                        <mutation name="get star wars"></mutation>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ELSE">
                +                                      <block type="logic_null"></block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">Kirk</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="procedures_callnoreturn" inline="true">
                +                                <mutation name="check number of calls">
                +                                  <arg name="test name"></arg>
                +                                </mutation>
                +                                <value name="ARG0">
                +                                  <block type="text">
                +                                    <field name="TEXT">get first order complex</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="variables_set">
                +                                    <field name="VAR">number of calls</field>
                +                                    <value name="VALUE">
                +                                      <block type="math_number">
                +                                        <field name="NUM">0</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">get last complex</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="lists_getIndex">
                +                                            <mutation statement="false" at="false"></mutation>
                +                                            <field name="MODE">GET</field>
                +                                            <field name="WHERE">LAST</field>
                +                                            <value name="VALUE">
                +                                              <block type="procedures_callreturn">
                +                                                <mutation name="get star wars"></mutation>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">McCoy</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn" inline="true">
                +                                            <mutation name="check number of calls">
                +                                              <arg name="test name"></arg>
                +                                            </mutation>
                +                                            <value name="ARG0">
                +                                              <block type="text">
                +                                                <field name="TEXT">get last complex</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="variables_set">
                +                                                <field name="VAR">number of calls</field>
                +                                                <value name="VALUE">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">0</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">get last order complex</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="lists_getIndex">
                +                                                        <mutation statement="false" at="false"></mutation>
                +                                                        <field name="MODE">GET</field>
                +                                                        <field name="WHERE">LAST</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="logic_ternary" inline="true">
                +                                                            <value name="IF">
                +                                                              <block type="logic_boolean">
                +                                                                <field name="BOOL">TRUE</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="THEN">
                +                                                              <block type="procedures_callreturn">
                +                                                                <mutation name="get star wars"></mutation>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ELSE">
                +                                                              <block type="logic_null"></block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">McCoy</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                        <mutation name="check number of calls">
                +                                                          <arg name="test name"></arg>
                +                                                        </mutation>
                +                                                        <value name="ARG0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">get last order complex</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="variables_set">
                +                                                            <field name="VAR">number of calls</field>
                +                                                            <value name="VALUE">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">0</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertvalue" inline="false">
                +                                                                <field name="EXPECTED">TRUE</field>
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">get random complex</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="logic_compare">
                +                                                                    <field name="OP">GT</field>
                +                                                                    <value name="A">
                +                                                                      <block type="lists_indexOf" inline="false">
                +                                                                        <field name="END">FIRST</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="variables_get">
                +                                                                            <field name="VAR">list</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="FIND">
                +                                                                          <block type="lists_getIndex">
                +                                                                            <mutation statement="false" at="false"></mutation>
                +                                                                            <field name="MODE">GET</field>
                +                                                                            <field name="WHERE">RANDOM</field>
                +                                                                            <value name="VALUE">
                +                                                                              <block type="procedures_callreturn">
                +                                                                                <mutation name="get star wars"></mutation>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="B">
                +                                                                      <block type="unittest_adjustindex">
                +                                                                        <value name="INDEX">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">-1</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                    <mutation name="check number of calls">
                +                                                                      <arg name="test name"></arg>
                +                                                                    </mutation>
                +                                                                    <value name="ARG0">
                +                                                                      <block type="text">
                +                                                                        <field name="TEXT">get random complex</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="variables_set">
                +                                                                        <field name="VAR">number of calls</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">0</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertvalue" inline="false">
                +                                                                            <field name="EXPECTED">TRUE</field>
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">get random order complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="logic_compare">
                +                                                                                <field name="OP">GT</field>
                +                                                                                <value name="A">
                +                                                                                  <block type="lists_indexOf" inline="false">
                +                                                                                    <field name="END">FIRST</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">list</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="FIND">
                +                                                                                      <block type="lists_getIndex">
                +                                                                                        <mutation statement="false" at="false"></mutation>
                +                                                                                        <field name="MODE">GET</field>
                +                                                                                        <field name="WHERE">RANDOM</field>
                +                                                                                        <value name="VALUE">
                +                                                                                          <block type="logic_ternary">
                +                                                                                            <value name="IF">
                +                                                                                              <block type="logic_boolean">
                +                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="THEN">
                +                                                                                              <block type="procedures_callreturn">
                +                                                                                                <mutation name="get star wars"></mutation>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ELSE">
                +                                                                                              <block type="logic_null"></block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="B">
                +                                                                                  <block type="unittest_adjustindex">
                +                                                                                    <value name="INDEX">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">-1</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                <mutation name="check number of calls">
                +                                                                                  <arg name="test name"></arg>
                +                                                                                </mutation>
                +                                                                                <value name="ARG0">
                +                                                                                  <block type="text">
                +                                                                                    <field name="TEXT">get random order complex</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="variables_set">
                +                                                                                    <field name="VAR">number of calls</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">0</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">get # complex</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="lists_getIndex">
                +                                                                                            <mutation statement="false" at="true"></mutation>
                +                                                                                            <field name="MODE">GET</field>
                +                                                                                            <field name="WHERE">FROM_START</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="procedures_callreturn">
                +                                                                                                <mutation name="get star wars"></mutation>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="AT">
                +                                                                                              <block type="unittest_adjustindex">
                +                                                                                                <value name="INDEX">
                +                                                                                                  <block type="math_number">
                +                                                                                                    <field name="NUM">1</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">Spock</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                            <mutation name="check number of calls">
                +                                                                                              <arg name="test name"></arg>
                +                                                                                            </mutation>
                +                                                                                            <value name="ARG0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">get # complex</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="variables_set">
                +                                                                                                <field name="VAR">number of calls</field>
                +                                                                                                <value name="VALUE">
                +                                                                                                  <block type="math_number">
                +                                                                                                    <field name="NUM">0</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">get # order complex</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="lists_getIndex">
                +                                                                                                        <mutation statement="false" at="true"></mutation>
                +                                                                                                        <field name="MODE">GET</field>
                +                                                                                                        <field name="WHERE">FROM_START</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="logic_ternary">
                +                                                                                                            <value name="IF">
                +                                                                                                              <block type="logic_boolean">
                +                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="THEN">
                +                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                <mutation name="get star wars"></mutation>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ELSE">
                +                                                                                                              <block type="logic_null"></block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="AT">
                +                                                                                                          <block type="logic_ternary">
                +                                                                                                            <value name="IF">
                +                                                                                                              <block type="logic_boolean">
                +                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="THEN">
                +                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                <value name="INDEX">
                +                                                                                                                  <block type="math_number">
                +                                                                                                                    <field name="NUM">1</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ELSE">
                +                                                                                                              <block type="logic_null"></block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">Spock</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                                        <mutation name="check number of calls">
                +                                                                                                          <arg name="test name"></arg>
                +                                                                                                        </mutation>
                +                                                                                                        <value name="ARG0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">get # order complex</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="variables_set">
                +                                                                                                            <field name="VAR">number of calls</field>
                +                                                                                                            <value name="VALUE">
                +                                                                                                              <block type="math_number">
                +                                                                                                                <field name="NUM">0</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">get #-end complex</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="lists_getIndex">
                +                                                                                                                    <mutation statement="false" at="true"></mutation>
                +                                                                                                                    <field name="MODE">GET</field>
                +                                                                                                                    <field name="WHERE">FROM_END</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                        <mutation name="get star wars"></mutation>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="AT">
                +                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                        <value name="INDEX">
                +                                                                                                                          <block type="math_number">
                +                                                                                                                            <field name="NUM">2</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">Kirk</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                    <mutation name="check number of calls">
                +                                                                                                                      <arg name="test name"></arg>
                +                                                                                                                    </mutation>
                +                                                                                                                    <value name="ARG0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">get #-end complex</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="variables_set">
                +                                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                                        <value name="VALUE">
                +                                                                                                                          <block type="math_number">
                +                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">get #-end order complex</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="lists_getIndex">
                +                                                                                                                                <mutation statement="false" at="true"></mutation>
                +                                                                                                                                <field name="MODE">GET</field>
                +                                                                                                                                <field name="WHERE">FROM_END</field>
                +                                                                                                                                <comment pinned="false" h="87" w="299">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                                <value name="VALUE">
                +                                                                                                                                  <block type="logic_ternary" inline="true">
                +                                                                                                                                    <value name="IF">
                +                                                                                                                                      <block type="logic_boolean">
                +                                                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="THEN">
                +                                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                                        <mutation name="get star wars"></mutation>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="ELSE">
                +                                                                                                                                      <block type="logic_null"></block>
                +                                                                                                                                    </value>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="AT">
                +                                                                                                                                  <block type="math_arithmetic">
                +                                                                                                                                    <field name="OP">ADD</field>
                +                                                                                                                                    <value name="A">
                +                                                                                                                                      <block type="math_number">
                +                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="B">
                +                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                        <value name="INDEX">
                +                                                                                                                                          <block type="math_number">
                +                                                                                                                                            <field name="NUM">2</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <next>
                +                                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                <mutation name="check number of calls">
                +                                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                                </mutation>
                +                                                                                                                                <value name="ARG0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">get #-end order complex</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </next>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="6488">
                +    <field name="NAME">test getRemove</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get and remove" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Spock</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">McCoy</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">getremove first</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_getIndex">
                +                <mutation statement="false" at="false"></mutation>
                +                <field name="MODE">GET_REMOVE</field>
                +                <field name="WHERE">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">getremove first list</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="2"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Spock</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">McCoy</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">list</field>
                +                    <value name="VALUE">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Kirk</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Spock</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="text">
                +                            <field name="TEXT">McCoy</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">getremove first order</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_getIndex">
                +                            <mutation statement="false" at="false"></mutation>
                +                            <field name="MODE">GET_REMOVE</field>
                +                            <field name="WHERE">FIRST</field>
                +                            <value name="VALUE">
                +                              <block type="logic_ternary" inline="true">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">list</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">Kirk</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">getremove first order list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="2"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="text">
                +                                    <field name="TEXT">Spock</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="text">
                +                                    <field name="TEXT">McCoy</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">list</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="text">
                +                                        <field name="TEXT">Kirk</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="text">
                +                                        <field name="TEXT">Spock</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">McCoy</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">getremove last</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="lists_getIndex">
                +                                        <mutation statement="false" at="false"></mutation>
                +                                        <field name="MODE">GET_REMOVE</field>
                +                                        <field name="WHERE">LAST</field>
                +                                        <value name="VALUE">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">McCoy</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">getremove last list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="true">
                +                                            <mutation items="2"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="text">
                +                                                <field name="TEXT">Kirk</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="text">
                +                                                <field name="TEXT">Spock</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">list</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_with" inline="true">
                +                                                <mutation items="3"></mutation>
                +                                                <value name="ADD0">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Kirk</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD1">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Spock</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD2">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">McCoy</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">getremove last order</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="lists_getIndex">
                +                                                    <mutation statement="false" at="false"></mutation>
                +                                                    <field name="MODE">GET_REMOVE</field>
                +                                                    <field name="WHERE">LAST</field>
                +                                                    <value name="VALUE">
                +                                                      <block type="logic_ternary" inline="true">
                +                                                        <value name="IF">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="THEN">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">list</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ELSE">
                +                                                          <block type="logic_null"></block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">McCoy</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">getremove last order list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="true">
                +                                                        <mutation items="2"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Kirk</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Spock</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">list</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="lists_create_with" inline="true">
                +                                                            <mutation items="3"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Kirk</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Spock</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">McCoy</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertvalue" inline="false">
                +                                                            <field name="EXPECTED">TRUE</field>
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">getremove random</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="logic_compare">
                +                                                                <field name="OP">EQ</field>
                +                                                                <value name="A">
                +                                                                  <block type="lists_indexOf" inline="false">
                +                                                                    <field name="END">FIRST</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="FIND">
                +                                                                      <block type="lists_getIndex">
                +                                                                        <mutation statement="false" at="false"></mutation>
                +                                                                        <field name="MODE">GET_REMOVE</field>
                +                                                                        <field name="WHERE">RANDOM</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="variables_get">
                +                                                                            <field name="VAR">list</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="B">
                +                                                                  <block type="unittest_adjustindex">
                +                                                                    <value name="INDEX">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">-1</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">getremove random list</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="lists_length" inline="false">
                +                                                                    <value name="VALUE">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">2</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set" inline="false">
                +                                                                    <field name="VAR">list</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="lists_create_with" inline="true">
                +                                                                        <mutation items="3"></mutation>
                +                                                                        <value name="ADD0">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Kirk</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD1">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Spock</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD2">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">McCoy</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertvalue" inline="false">
                +                                                                        <field name="EXPECTED">TRUE</field>
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">getremove random order</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="logic_compare">
                +                                                                            <field name="OP">EQ</field>
                +                                                                            <value name="A">
                +                                                                              <block type="lists_indexOf" inline="false">
                +                                                                                <field name="END">FIRST</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="FIND">
                +                                                                                  <block type="lists_getIndex">
                +                                                                                    <mutation statement="false" at="false"></mutation>
                +                                                                                    <field name="MODE">GET_REMOVE</field>
                +                                                                                    <field name="WHERE">RANDOM</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="logic_ternary" inline="false">
                +                                                                                        <value name="IF">
                +                                                                                          <block type="logic_boolean">
                +                                                                                            <field name="BOOL">TRUE</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="THEN">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ELSE">
                +                                                                                          <block type="logic_null"></block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="B">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">-1</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">getremove random order list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="lists_length" inline="false">
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">2</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set" inline="false">
                +                                                                                <field name="VAR">list</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                    <mutation items="3"></mutation>
                +                                                                                    <value name="ADD0">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Kirk</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD1">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Spock</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD2">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">McCoy</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                    <value name="MESSAGE">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">getremove #</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ACTUAL">
                +                                                                                      <block type="lists_getIndex">
                +                                                                                        <mutation statement="false" at="true"></mutation>
                +                                                                                        <field name="MODE">GET_REMOVE</field>
                +                                                                                        <field name="WHERE">FROM_START</field>
                +                                                                                        <value name="VALUE">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="AT">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">1</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="EXPECTED">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Spock</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">getremove # list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                            <mutation items="2"></mutation>
                +                                                                                            <value name="ADD0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD1">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">McCoy</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set" inline="false">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                <mutation items="3"></mutation>
                +                                                                                                <value name="ADD0">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Kirk</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD1">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Spock</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD2">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">McCoy</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                <value name="MESSAGE">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">getremove # order</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ACTUAL">
                +                                                                                                  <block type="lists_getIndex">
                +                                                                                                    <mutation statement="false" at="true"></mutation>
                +                                                                                                    <field name="MODE">GET_REMOVE</field>
                +                                                                                                    <field name="WHERE">FROM_START</field>
                +                                                                                                    <value name="VALUE">
                +                                                                                                      <block type="logic_ternary" inline="false">
                +                                                                                                        <value name="IF">
                +                                                                                                          <block type="logic_boolean">
                +                                                                                                            <field name="BOOL">TRUE</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="THEN">
                +                                                                                                          <block type="variables_get">
                +                                                                                                            <field name="VAR">list</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ELSE">
                +                                                                                                          <block type="logic_null"></block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="AT">
                +                                                                                                      <block type="logic_ternary">
                +                                                                                                        <value name="IF">
                +                                                                                                          <block type="logic_boolean">
                +                                                                                                            <field name="BOOL">TRUE</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="THEN">
                +                                                                                                          <block type="unittest_adjustindex">
                +                                                                                                            <value name="INDEX">
                +                                                                                                              <block type="math_number">
                +                                                                                                                <field name="NUM">1</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ELSE">
                +                                                                                                          <block type="logic_null"></block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="EXPECTED">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Spock</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">getremove # order list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                        <mutation items="2"></mutation>
                +                                                                                                        <value name="ADD0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Kirk</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD1">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">McCoy</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set" inline="false">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                                            <mutation items="3"></mutation>
                +                                                                                                            <value name="ADD0">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD1">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Spock</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD2">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">McCoy</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                            <value name="MESSAGE">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">getremove #-end</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ACTUAL">
                +                                                                                                              <block type="lists_getIndex">
                +                                                                                                                <mutation statement="false" at="true"></mutation>
                +                                                                                                                <field name="MODE">GET_REMOVE</field>
                +                                                                                                                <field name="WHERE">FROM_END</field>
                +                                                                                                                <value name="VALUE">
                +                                                                                                                  <block type="variables_get">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="AT">
                +                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                    <value name="INDEX">
                +                                                                                                                      <block type="math_number">
                +                                                                                                                        <field name="NUM">2</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="EXPECTED">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">getremove #-end list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="variables_get">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                                                    <mutation items="2"></mutation>
                +                                                                                                                    <value name="ADD0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Spock</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD1">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">McCoy</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set" inline="false">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                                        <mutation items="3"></mutation>
                +                                                                                                                        <value name="ADD0">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Kirk</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD1">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Spock</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD2">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">McCoy</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                                                        <value name="MESSAGE">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">getremove #-end order</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ACTUAL">
                +                                                                                                                          <block type="lists_getIndex">
                +                                                                                                                            <mutation statement="false" at="true"></mutation>
                +                                                                                                                            <field name="MODE">GET_REMOVE</field>
                +                                                                                                                            <field name="WHERE">FROM_END</field>
                +                                                                                                                            <comment pinned="false" h="94" w="258">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                            <value name="VALUE">
                +                                                                                                                              <block type="logic_ternary" inline="true">
                +                                                                                                                                <value name="IF">
                +                                                                                                                                  <block type="logic_boolean">
                +                                                                                                                                    <field name="BOOL">TRUE</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="THEN">
                +                                                                                                                                  <block type="variables_get">
                +                                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ELSE">
                +                                                                                                                                  <block type="logic_null"></block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="AT">
                +                                                                                                                              <block type="math_arithmetic">
                +                                                                                                                                <field name="OP">ADD</field>
                +                                                                                                                                <value name="A">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="B">
                +                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                    <value name="INDEX">
                +                                                                                                                                      <block type="math_number">
                +                                                                                                                                        <field name="NUM">2</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="EXPECTED">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Kirk</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">getremove #-end order list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                                                <mutation items="2"></mutation>
                +                                                                                                                                <value name="ADD0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Spock</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD1">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">McCoy</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="8888">
                +    <field name="NAME">test remove</field>
                +    <comment pinned="false" h="80" w="160">Tests the "remove" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Kirk</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Spock</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">McCoy</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="lists_getIndex">
                +            <mutation statement="true" at="false"></mutation>
                +            <field name="MODE">REMOVE</field>
                +            <field name="WHERE">FIRST</field>
                +            <value name="VALUE">
                +              <block type="variables_get">
                +                <field name="VAR">list</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">remove first list</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="2"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Spock</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">McCoy</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">list</field>
                +                    <value name="VALUE">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Kirk</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Spock</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="text">
                +                            <field name="TEXT">McCoy</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="lists_getIndex">
                +                        <mutation statement="true" at="false"></mutation>
                +                        <field name="MODE">REMOVE</field>
                +                        <field name="WHERE">FIRST</field>
                +                        <value name="VALUE">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">remove first order list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="2"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="text">
                +                                    <field name="TEXT">Spock</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="text">
                +                                    <field name="TEXT">McCoy</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">list</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="text">
                +                                        <field name="TEXT">Kirk</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="text">
                +                                        <field name="TEXT">Spock</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">McCoy</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="lists_getIndex">
                +                                    <mutation statement="true" at="false"></mutation>
                +                                    <field name="MODE">REMOVE</field>
                +                                    <field name="WHERE">LAST</field>
                +                                    <value name="VALUE">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">list</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">remove last list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="true">
                +                                            <mutation items="2"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="text">
                +                                                <field name="TEXT">Kirk</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="text">
                +                                                <field name="TEXT">Spock</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">list</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_with" inline="true">
                +                                                <mutation items="3"></mutation>
                +                                                <value name="ADD0">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Kirk</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD1">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Spock</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD2">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">McCoy</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="lists_getIndex">
                +                                                <mutation statement="true" at="false"></mutation>
                +                                                <field name="MODE">REMOVE</field>
                +                                                <field name="WHERE">LAST</field>
                +                                                <value name="VALUE">
                +                                                  <block type="logic_ternary" inline="true">
                +                                                    <value name="IF">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">TRUE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="THEN">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ELSE">
                +                                                      <block type="logic_null"></block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">remove last order list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="true">
                +                                                        <mutation items="2"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Kirk</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Spock</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">list</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="lists_create_with" inline="true">
                +                                                            <mutation items="3"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Kirk</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Spock</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">McCoy</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="lists_getIndex">
                +                                                            <mutation statement="true" at="false"></mutation>
                +                                                            <field name="MODE">REMOVE</field>
                +                                                            <field name="WHERE">RANDOM</field>
                +                                                            <value name="VALUE">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">list</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">remove random list</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="lists_length" inline="false">
                +                                                                    <value name="VALUE">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">2</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set" inline="false">
                +                                                                    <field name="VAR">list</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="lists_create_with" inline="true">
                +                                                                        <mutation items="3"></mutation>
                +                                                                        <value name="ADD0">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Kirk</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD1">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Spock</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD2">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">McCoy</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="lists_getIndex">
                +                                                                        <mutation statement="true" at="false"></mutation>
                +                                                                        <field name="MODE">REMOVE</field>
                +                                                                        <field name="WHERE">RANDOM</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="logic_ternary" inline="true">
                +                                                                            <value name="IF">
                +                                                                              <block type="logic_boolean">
                +                                                                                <field name="BOOL">TRUE</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="THEN">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ELSE">
                +                                                                              <block type="logic_null"></block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">remove random order list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="lists_length" inline="false">
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">2</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set" inline="false">
                +                                                                                <field name="VAR">list</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                    <mutation items="3"></mutation>
                +                                                                                    <value name="ADD0">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Kirk</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD1">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Spock</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD2">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">McCoy</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="lists_getIndex">
                +                                                                                    <mutation statement="true" at="true"></mutation>
                +                                                                                    <field name="MODE">REMOVE</field>
                +                                                                                    <field name="WHERE">FROM_START</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">list</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="AT">
                +                                                                                      <block type="unittest_adjustindex">
                +                                                                                        <value name="INDEX">
                +                                                                                          <block type="math_number">
                +                                                                                            <field name="NUM">1</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">remove # list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                            <mutation items="2"></mutation>
                +                                                                                            <value name="ADD0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD1">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">McCoy</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set" inline="false">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                <mutation items="3"></mutation>
                +                                                                                                <value name="ADD0">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Kirk</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD1">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Spock</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD2">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">McCoy</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="lists_getIndex">
                +                                                                                                <mutation statement="true" at="true"></mutation>
                +                                                                                                <field name="MODE">REMOVE</field>
                +                                                                                                <field name="WHERE">FROM_START</field>
                +                                                                                                <value name="VALUE">
                +                                                                                                  <block type="logic_ternary" inline="false">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="AT">
                +                                                                                                  <block type="logic_ternary">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                        <value name="INDEX">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">1</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">remove # order list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                        <mutation items="2"></mutation>
                +                                                                                                        <value name="ADD0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Kirk</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD1">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">McCoy</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set" inline="false">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                                            <mutation items="3"></mutation>
                +                                                                                                            <value name="ADD0">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Kirk</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD1">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Spock</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD2">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">McCoy</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="lists_getIndex">
                +                                                                                                            <mutation statement="true" at="true"></mutation>
                +                                                                                                            <field name="MODE">REMOVE</field>
                +                                                                                                            <field name="WHERE">FROM_END</field>
                +                                                                                                            <value name="VALUE">
                +                                                                                                              <block type="variables_get">
                +                                                                                                                <field name="VAR">list</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="AT">
                +                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                <value name="INDEX">
                +                                                                                                                  <block type="math_number">
                +                                                                                                                    <field name="NUM">2</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">remove #-end list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="variables_get">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                                                    <mutation items="2"></mutation>
                +                                                                                                                    <value name="ADD0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Spock</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD1">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">McCoy</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set" inline="false">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                                        <mutation items="3"></mutation>
                +                                                                                                                        <value name="ADD0">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Kirk</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD1">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Spock</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD2">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">McCoy</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="lists_getIndex">
                +                                                                                                                        <mutation statement="true" at="true"></mutation>
                +                                                                                                                        <field name="MODE">REMOVE</field>
                +                                                                                                                        <field name="WHERE">FROM_END</field>
                +                                                                                                                        <comment pinned="false" h="94" w="256">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                        <value name="VALUE">
                +                                                                                                                          <block type="logic_ternary" inline="true">
                +                                                                                                                            <value name="IF">
                +                                                                                                                              <block type="logic_boolean">
                +                                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="THEN">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ELSE">
                +                                                                                                                              <block type="logic_null"></block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="AT">
                +                                                                                                                          <block type="math_arithmetic">
                +                                                                                                                            <field name="OP">ADD</field>
                +                                                                                                                            <value name="A">
                +                                                                                                                              <block type="math_number">
                +                                                                                                                                <field name="NUM">0</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="B">
                +                                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                                <value name="INDEX">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">2</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">remove #-end order list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                                                <mutation items="2"></mutation>
                +                                                                                                                                <value name="ADD0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Spock</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD1">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">McCoy</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="10713">
                +    <field name="NAME">test set</field>
                +    <comment pinned="false" h="80" w="160">Tests the "set" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Picard</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Riker</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Crusher</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="lists_setIndex">
                +            <mutation at="false"></mutation>
                +            <field name="MODE">SET</field>
                +            <field name="WHERE">FIRST</field>
                +            <value name="LIST">
                +              <block type="variables_get">
                +                <field name="VAR">list</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="text">
                +                <field name="TEXT">Jean-Luc</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">set first list</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Jean-Luc</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Riker</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">Crusher</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">list</field>
                +                    <value name="VALUE">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Picard</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Riker</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="text">
                +                            <field name="TEXT">Crusher</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="lists_setIndex">
                +                        <mutation at="false"></mutation>
                +                        <field name="MODE">SET</field>
                +                        <field name="WHERE">FIRST</field>
                +                        <value name="LIST">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="text">
                +                            <field name="TEXT">Jean-Luc</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">set first order list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="3"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="text">
                +                                    <field name="TEXT">Jean-Luc</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="text">
                +                                    <field name="TEXT">Riker</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD2">
                +                                  <block type="text">
                +                                    <field name="TEXT">Crusher</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">list</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="text">
                +                                        <field name="TEXT">Picard</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="text">
                +                                        <field name="TEXT">Riker</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">Crusher</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="lists_setIndex">
                +                                    <mutation at="false"></mutation>
                +                                    <field name="MODE">SET</field>
                +                                    <field name="WHERE">LAST</field>
                +                                    <value name="LIST">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">list</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="text">
                +                                        <field name="TEXT">Beverly</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">set last list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="true">
                +                                            <mutation items="3"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="text">
                +                                                <field name="TEXT">Picard</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="text">
                +                                                <field name="TEXT">Riker</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD2">
                +                                              <block type="text">
                +                                                <field name="TEXT">Beverly</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">list</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_with" inline="true">
                +                                                <mutation items="3"></mutation>
                +                                                <value name="ADD0">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Picard</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD1">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Riker</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD2">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Crusher</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="lists_setIndex">
                +                                                <mutation at="false"></mutation>
                +                                                <field name="MODE">SET</field>
                +                                                <field name="WHERE">LAST</field>
                +                                                <value name="LIST">
                +                                                  <block type="logic_ternary" inline="true">
                +                                                    <value name="IF">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">TRUE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="THEN">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ELSE">
                +                                                      <block type="logic_null"></block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="TO">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Beverly</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">set last order list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="true">
                +                                                        <mutation items="3"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Picard</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Riker</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD2">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Beverly</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">list</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="lists_create_with" inline="true">
                +                                                            <mutation items="3"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Picard</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Riker</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Crusher</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="lists_setIndex">
                +                                                            <mutation at="false"></mutation>
                +                                                            <field name="MODE">SET</field>
                +                                                            <field name="WHERE">RANDOM</field>
                +                                                            <value name="LIST">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">list</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="TO">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Data</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">set random list</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="lists_length" inline="false">
                +                                                                    <value name="VALUE">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">3</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set" inline="false">
                +                                                                    <field name="VAR">list</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="lists_create_with" inline="true">
                +                                                                        <mutation items="3"></mutation>
                +                                                                        <value name="ADD0">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Picard</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD1">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Riker</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD2">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Crusher</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="lists_setIndex">
                +                                                                        <mutation at="false"></mutation>
                +                                                                        <field name="MODE">SET</field>
                +                                                                        <field name="WHERE">RANDOM</field>
                +                                                                        <value name="LIST">
                +                                                                          <block type="logic_ternary" inline="true">
                +                                                                            <value name="IF">
                +                                                                              <block type="logic_boolean">
                +                                                                                <field name="BOOL">TRUE</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="THEN">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ELSE">
                +                                                                              <block type="logic_null"></block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="TO">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Data</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">set random order list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="lists_length" inline="false">
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">3</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set" inline="false">
                +                                                                                <field name="VAR">list</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                    <mutation items="3"></mutation>
                +                                                                                    <value name="ADD0">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Picard</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD1">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Riker</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD2">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Crusher</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="lists_setIndex">
                +                                                                                    <mutation at="true"></mutation>
                +                                                                                    <field name="MODE">SET</field>
                +                                                                                    <field name="WHERE">FROM_START</field>
                +                                                                                    <value name="LIST">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">list</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="AT">
                +                                                                                      <block type="unittest_adjustindex">
                +                                                                                        <value name="INDEX">
                +                                                                                          <block type="math_number">
                +                                                                                            <field name="NUM">2</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="TO">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Pulaski</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">set # list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                            <mutation items="3"></mutation>
                +                                                                                            <value name="ADD0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Picard</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD1">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Riker</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD2">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Pulaski</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set" inline="false">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                <mutation items="3"></mutation>
                +                                                                                                <value name="ADD0">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Picard</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD1">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Riker</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD2">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Crusher</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="lists_setIndex">
                +                                                                                                <mutation at="true"></mutation>
                +                                                                                                <field name="MODE">SET</field>
                +                                                                                                <field name="WHERE">FROM_START</field>
                +                                                                                                <value name="LIST">
                +                                                                                                  <block type="logic_ternary" inline="false">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="AT">
                +                                                                                                  <block type="logic_ternary" inline="false">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                        <value name="INDEX">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">2</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="TO">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Pulaski</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">set # order list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                        <mutation items="3"></mutation>
                +                                                                                                        <value name="ADD0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Picard</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD1">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Riker</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD2">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Pulaski</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set" inline="false">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                                            <mutation items="3"></mutation>
                +                                                                                                            <value name="ADD0">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Picard</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD1">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Riker</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD2">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Crusher</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="lists_setIndex">
                +                                                                                                            <mutation at="true"></mutation>
                +                                                                                                            <field name="MODE">SET</field>
                +                                                                                                            <field name="WHERE">FROM_END</field>
                +                                                                                                            <value name="LIST">
                +                                                                                                              <block type="variables_get">
                +                                                                                                                <field name="VAR">list</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="AT">
                +                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                <value name="INDEX">
                +                                                                                                                  <block type="math_number">
                +                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="TO">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Pulaski</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">set #-end list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="variables_get">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                                                    <mutation items="3"></mutation>
                +                                                                                                                    <value name="ADD0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Picard</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD1">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Riker</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD2">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Pulaski</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set" inline="false">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                                        <mutation items="3"></mutation>
                +                                                                                                                        <value name="ADD0">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Picard</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD1">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Riker</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD2">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Crusher</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="lists_setIndex">
                +                                                                                                                        <mutation at="true"></mutation>
                +                                                                                                                        <field name="MODE">SET</field>
                +                                                                                                                        <field name="WHERE">FROM_END</field>
                +                                                                                                                        <comment pinned="false" h="88" w="258">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                        <value name="LIST">
                +                                                                                                                          <block type="logic_ternary" inline="true">
                +                                                                                                                            <value name="IF">
                +                                                                                                                              <block type="logic_boolean">
                +                                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="THEN">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ELSE">
                +                                                                                                                              <block type="logic_null"></block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="AT">
                +                                                                                                                          <block type="math_arithmetic">
                +                                                                                                                            <field name="OP">ADD</field>
                +                                                                                                                            <value name="A">
                +                                                                                                                              <block type="math_number">
                +                                                                                                                                <field name="NUM">0</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="B">
                +                                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                                <value name="INDEX">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">1</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="TO">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Pulaski</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">set #-end order list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                                                <mutation items="3"></mutation>
                +                                                                                                                                <value name="ADD0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Picard</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD1">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Pulaski</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD2">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Crusher</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="12538">
                +    <field name="NAME">test insert</field>
                +    <comment pinned="false" h="80" w="160">Tests the "insert" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Picard</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Riker</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Crusher</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="lists_setIndex">
                +            <mutation at="false"></mutation>
                +            <field name="MODE">INSERT</field>
                +            <field name="WHERE">FIRST</field>
                +            <value name="LIST">
                +              <block type="variables_get">
                +                <field name="VAR">list</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="text">
                +                <field name="TEXT">Data</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">insert first list</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="4"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Data</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Picard</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">Riker</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD3">
                +                      <block type="text">
                +                        <field name="TEXT">Crusher</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">list</field>
                +                    <value name="VALUE">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Picard</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Riker</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="text">
                +                            <field name="TEXT">Crusher</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="lists_setIndex">
                +                        <mutation at="false"></mutation>
                +                        <field name="MODE">INSERT</field>
                +                        <field name="WHERE">FIRST</field>
                +                        <value name="LIST">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="text">
                +                            <field name="TEXT">Data</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">insert first order list</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="4"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="text">
                +                                    <field name="TEXT">Data</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="text">
                +                                    <field name="TEXT">Picard</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD2">
                +                                  <block type="text">
                +                                    <field name="TEXT">Riker</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD3">
                +                                  <block type="text">
                +                                    <field name="TEXT">Crusher</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">list</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="text">
                +                                        <field name="TEXT">Picard</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="text">
                +                                        <field name="TEXT">Riker</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">Crusher</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="lists_setIndex">
                +                                    <mutation at="false"></mutation>
                +                                    <field name="MODE">INSERT</field>
                +                                    <field name="WHERE">LAST</field>
                +                                    <value name="LIST">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">list</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="text">
                +                                        <field name="TEXT">Data</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">insert last list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">list</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="true">
                +                                            <mutation items="4"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="text">
                +                                                <field name="TEXT">Picard</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="text">
                +                                                <field name="TEXT">Riker</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD2">
                +                                              <block type="text">
                +                                                <field name="TEXT">Crusher</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD3">
                +                                              <block type="text">
                +                                                <field name="TEXT">Data</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">list</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_with" inline="true">
                +                                                <mutation items="3"></mutation>
                +                                                <value name="ADD0">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Picard</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD1">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Riker</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ADD2">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Crusher</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="lists_setIndex">
                +                                                <mutation at="false"></mutation>
                +                                                <field name="MODE">INSERT</field>
                +                                                <field name="WHERE">LAST</field>
                +                                                <value name="LIST">
                +                                                  <block type="logic_ternary" inline="true">
                +                                                    <value name="IF">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">TRUE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="THEN">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ELSE">
                +                                                      <block type="logic_null"></block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="TO">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Data</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">insert last order list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="true">
                +                                                        <mutation items="4"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Picard</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Riker</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD2">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Crusher</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD3">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Data</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">list</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="lists_create_with" inline="true">
                +                                                            <mutation items="3"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Picard</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Riker</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Crusher</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="lists_setIndex">
                +                                                            <mutation at="false"></mutation>
                +                                                            <field name="MODE">INSERT</field>
                +                                                            <field name="WHERE">RANDOM</field>
                +                                                            <value name="LIST">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">list</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="TO">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Data</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">insert random list</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="lists_length" inline="false">
                +                                                                    <value name="VALUE">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">4</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set" inline="false">
                +                                                                    <field name="VAR">list</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="lists_create_with" inline="true">
                +                                                                        <mutation items="3"></mutation>
                +                                                                        <value name="ADD0">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Picard</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD1">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Riker</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD2">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Crusher</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="lists_setIndex">
                +                                                                        <mutation at="false"></mutation>
                +                                                                        <field name="MODE">INSERT</field>
                +                                                                        <field name="WHERE">RANDOM</field>
                +                                                                        <value name="LIST">
                +                                                                          <block type="logic_ternary" inline="true">
                +                                                                            <value name="IF">
                +                                                                              <block type="logic_boolean">
                +                                                                                <field name="BOOL">TRUE</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="THEN">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ELSE">
                +                                                                              <block type="logic_null"></block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="TO">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Data</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">insert random order list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="lists_length" inline="false">
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">4</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set" inline="false">
                +                                                                                <field name="VAR">list</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                    <mutation items="3"></mutation>
                +                                                                                    <value name="ADD0">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Picard</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD1">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Riker</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ADD2">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Crusher</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="lists_setIndex">
                +                                                                                    <mutation at="true"></mutation>
                +                                                                                    <field name="MODE">INSERT</field>
                +                                                                                    <field name="WHERE">FROM_START</field>
                +                                                                                    <value name="LIST">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">list</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="AT">
                +                                                                                      <block type="unittest_adjustindex">
                +                                                                                        <value name="INDEX">
                +                                                                                          <block type="math_number">
                +                                                                                            <field name="NUM">2</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="TO">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">Data</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">insert # list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="variables_get">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                            <mutation items="4"></mutation>
                +                                                                                            <value name="ADD0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Picard</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD1">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Riker</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD2">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Data</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ADD3">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">Crusher</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set" inline="false">
                +                                                                                            <field name="VAR">list</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                <mutation items="3"></mutation>
                +                                                                                                <value name="ADD0">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Picard</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD1">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Riker</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ADD2">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Crusher</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="lists_setIndex">
                +                                                                                                <mutation at="true"></mutation>
                +                                                                                                <field name="MODE">INSERT</field>
                +                                                                                                <field name="WHERE">FROM_START</field>
                +                                                                                                <value name="LIST">
                +                                                                                                  <block type="logic_ternary" inline="false">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="AT">
                +                                                                                                  <block type="logic_ternary">
                +                                                                                                    <value name="IF">
                +                                                                                                      <block type="logic_boolean">
                +                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="THEN">
                +                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                        <value name="INDEX">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">2</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ELSE">
                +                                                                                                      <block type="logic_null"></block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="TO">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">Data</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">insert # order list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="variables_get">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                        <mutation items="4"></mutation>
                +                                                                                                        <value name="ADD0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Picard</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD1">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Riker</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD2">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Data</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="ADD3">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">Crusher</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set" inline="false">
                +                                                                                                        <field name="VAR">list</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                                            <mutation items="3"></mutation>
                +                                                                                                            <value name="ADD0">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Picard</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD1">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Riker</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ADD2">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Crusher</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="lists_setIndex">
                +                                                                                                            <mutation at="true"></mutation>
                +                                                                                                            <field name="MODE">INSERT</field>
                +                                                                                                            <field name="WHERE">FROM_END</field>
                +                                                                                                            <value name="LIST">
                +                                                                                                              <block type="variables_get">
                +                                                                                                                <field name="VAR">list</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="AT">
                +                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                <value name="INDEX">
                +                                                                                                                  <block type="math_number">
                +                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="TO">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">Data</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">insert #-end list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="variables_get">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                                                    <mutation items="4"></mutation>
                +                                                                                                                    <value name="ADD0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Picard</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD1">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Riker</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD2">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Data</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="ADD3">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">Crusher</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set" inline="false">
                +                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                                        <mutation items="3"></mutation>
                +                                                                                                                        <value name="ADD0">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Picard</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD1">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Riker</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ADD2">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Crusher</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="lists_setIndex">
                +                                                                                                                        <mutation at="true"></mutation>
                +                                                                                                                        <field name="MODE">INSERT</field>
                +                                                                                                                        <field name="WHERE">FROM_END</field>
                +                                                                                                                        <comment pinned="false" h="77" w="263">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                        <value name="LIST">
                +                                                                                                                          <block type="logic_ternary" inline="true">
                +                                                                                                                            <value name="IF">
                +                                                                                                                              <block type="logic_boolean">
                +                                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="THEN">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ELSE">
                +                                                                                                                              <block type="logic_null"></block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="AT">
                +                                                                                                                          <block type="math_arithmetic">
                +                                                                                                                            <field name="OP">ADD</field>
                +                                                                                                                            <value name="A">
                +                                                                                                                              <block type="math_number">
                +                                                                                                                                <field name="NUM">0</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="B">
                +                                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                                <value name="INDEX">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">1</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="TO">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">Data</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">insert #-end order list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="variables_get">
                +                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                                                <mutation items="4"></mutation>
                +                                                                                                                                <value name="ADD0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Picard</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD1">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Data</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD2">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Riker</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="ADD3">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">Crusher</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="14363">
                +    <field name="NAME">test sublist simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get sub-list" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="5"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Columbia</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Challenger</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Discovery</field>
                +              </block>
                +            </value>
                +            <value name="ADD3">
                +              <block type="text">
                +                <field name="TEXT">Atlantis</field>
                +              </block>
                +            </value>
                +            <value name="ADD4">
                +              <block type="text">
                +                <field name="TEXT">Endeavour</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">sublist # simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_getSublist">
                +                <mutation at1="true" at2="true"></mutation>
                +                <field name="WHERE1">FROM_START</field>
                +                <field name="WHERE2">FROM_START</field>
                +                <value name="LIST">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="AT1">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="AT2">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="2"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Challenger</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">Discovery</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">sublist # simple order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_getSublist">
                +                    <mutation at1="true" at2="true"></mutation>
                +                    <field name="WHERE1">FROM_START</field>
                +                    <field name="WHERE2">FROM_START</field>
                +                    <value name="LIST">
                +                      <block type="variables_get">
                +                        <field name="VAR">list</field>
                +                      </block>
                +                    </value>
                +                    <value name="AT1">
                +                      <block type="logic_ternary">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="AT2">
                +                      <block type="logic_ternary">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="2"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Challenger</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Discovery</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">sublist #-end simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="lists_getSublist">
                +                        <mutation at1="true" at2="true"></mutation>
                +                        <field name="WHERE1">FROM_END</field>
                +                        <field name="WHERE2">FROM_END</field>
                +                        <value name="LIST">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="AT1">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="AT2">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="2"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">Discovery</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="text">
                +                            <field name="TEXT">Atlantis</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">sublist #-end simple order</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_getSublist">
                +                            <mutation at1="true" at2="true"></mutation>
                +                            <field name="WHERE1">FROM_END</field>
                +                            <field name="WHERE2">FROM_END</field>
                +                            <comment pinned="false" h="80" w="265">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                            <value name="LIST">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <value name="AT1">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">ADD</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT2">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">ADD</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="lists_create_with" inline="true">
                +                            <mutation items="2"></mutation>
                +                            <value name="ADD0">
                +                              <block type="text">
                +                                <field name="TEXT">Discovery</field>
                +                              </block>
                +                            </value>
                +                            <value name="ADD1">
                +                              <block type="text">
                +                                <field name="TEXT">Atlantis</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">sublist first-last simple</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="lists_getSublist">
                +                                <mutation at1="false" at2="false"></mutation>
                +                                <field name="WHERE1">FIRST</field>
                +                                <field name="WHERE2">LAST</field>
                +                                <value name="LIST">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">list</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">changing list</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="5"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="text">
                +                                        <field name="TEXT">Columbia</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="text">
                +                                        <field name="TEXT">Challenger</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">Discovery</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD3">
                +                                      <block type="text">
                +                                        <field name="TEXT">Atlantis</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD4">
                +                                      <block type="text">
                +                                        <field name="TEXT">Endeavour</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="variables_set">
                +                                    <field name="VAR">list copy</field>
                +                                    <value name="VALUE">
                +                                      <block type="lists_getSublist">
                +                                        <mutation at1="false" at2="false"></mutation>
                +                                        <field name="WHERE1">FIRST</field>
                +                                        <field name="WHERE2">LAST</field>
                +                                        <value name="LIST">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">changing list</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="lists_getIndex">
                +                                        <mutation statement="true" at="false"></mutation>
                +                                        <field name="MODE">REMOVE</field>
                +                                        <field name="WHERE">RANDOM</field>
                +                                        <value name="VALUE">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">changing list</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="unittest_assertequals" inline="false">
                +                                            <value name="MESSAGE">
                +                                              <block type="text">
                +                                                <field name="TEXT">sublist first-last simple copy check</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ACTUAL">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">list copy</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="EXPECTED">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">list</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">sublist # #-end simple</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="lists_getSublist">
                +                                                    <mutation at1="true" at2="true"></mutation>
                +                                                    <field name="WHERE1">FROM_START</field>
                +                                                    <field name="WHERE2">FROM_END</field>
                +                                                    <value name="LIST">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">list</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT1">
                +                                                      <block type="unittest_adjustindex">
                +                                                        <value name="INDEX">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">1</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT2">
                +                                                      <block type="unittest_adjustindex">
                +                                                        <value name="INDEX">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">1</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="lists_create_with" inline="true">
                +                                                    <mutation items="3"></mutation>
                +                                                    <value name="ADD0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Challenger</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD1">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Discovery</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD2">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Atlantis</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">sublist #-end # simple</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="lists_getSublist">
                +                                                        <mutation at1="true" at2="true"></mutation>
                +                                                        <field name="WHERE1">FROM_END</field>
                +                                                        <field name="WHERE2">FROM_START</field>
                +                                                        <value name="LIST">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">list</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="AT1">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">2</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="AT2">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">3</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="true">
                +                                                        <mutation items="2"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Discovery</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">Atlantis</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="unittest_assertequals" inline="false">
                +                                                        <value name="MESSAGE">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">sublist first # simple</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ACTUAL">
                +                                                          <block type="lists_getSublist">
                +                                                            <mutation at1="false" at2="true"></mutation>
                +                                                            <field name="WHERE1">FIRST</field>
                +                                                            <field name="WHERE2">FROM_START</field>
                +                                                            <value name="LIST">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">list</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="AT2">
                +                                                              <block type="unittest_adjustindex">
                +                                                                <value name="INDEX">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">3</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="EXPECTED">
                +                                                          <block type="lists_create_with" inline="true">
                +                                                            <mutation items="4"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Columbia</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Challenger</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Discovery</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD3">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">Atlantis</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">sublist first #-end simple</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="lists_getSublist">
                +                                                                <mutation at1="false" at2="true"></mutation>
                +                                                                <field name="WHERE1">FIRST</field>
                +                                                                <field name="WHERE2">FROM_END</field>
                +                                                                <value name="LIST">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">list</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="AT2">
                +                                                                  <block type="unittest_adjustindex">
                +                                                                    <value name="INDEX">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">3</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="lists_create_with" inline="true">
                +                                                                <mutation items="2"></mutation>
                +                                                                <value name="ADD0">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">Columbia</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ADD1">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">Challenger</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">sublist # last simple</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="lists_getSublist">
                +                                                                    <mutation at1="true" at2="false"></mutation>
                +                                                                    <field name="WHERE1">FROM_START</field>
                +                                                                    <field name="WHERE2">LAST</field>
                +                                                                    <value name="LIST">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">list</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="AT1">
                +                                                                      <block type="unittest_adjustindex">
                +                                                                        <value name="INDEX">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">3</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="lists_create_with" inline="true">
                +                                                                    <mutation items="2"></mutation>
                +                                                                    <value name="ADD0">
                +                                                                      <block type="text">
                +                                                                        <field name="TEXT">Atlantis</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="ADD1">
                +                                                                      <block type="text">
                +                                                                        <field name="TEXT">Endeavour</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                    <value name="MESSAGE">
                +                                                                      <block type="text">
                +                                                                        <field name="TEXT">sublist #-end last simple</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="ACTUAL">
                +                                                                      <block type="lists_getSublist">
                +                                                                        <mutation at1="true" at2="false"></mutation>
                +                                                                        <field name="WHERE1">FROM_END</field>
                +                                                                        <field name="WHERE2">LAST</field>
                +                                                                        <value name="LIST">
                +                                                                          <block type="variables_get">
                +                                                                            <field name="VAR">list</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="AT1">
                +                                                                          <block type="unittest_adjustindex">
                +                                                                            <value name="INDEX">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">3</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="EXPECTED">
                +                                                                      <block type="lists_create_with" inline="true">
                +                                                                        <mutation items="4"></mutation>
                +                                                                        <value name="ADD0">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Challenger</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD1">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Discovery</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD2">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Atlantis</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ADD3">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">Endeavour</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">sublist all with # #-end simple</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="lists_getSublist">
                +                                                                            <mutation at1="true" at2="true"></mutation>
                +                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                            <field name="WHERE2">FROM_END</field>
                +                                                                            <value name="LIST">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT1">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">0</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT2">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">0</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="EXPECTED">
                +                                                                          <block type="variables_get">
                +                                                                            <field name="VAR">list</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">sublist all with #-end # simple</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="lists_getSublist">
                +                                                                                <mutation at1="true" at2="true"></mutation>
                +                                                                                <field name="WHERE1">FROM_END</field>
                +                                                                                <field name="WHERE2">FROM_START</field>
                +                                                                                <value name="LIST">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="AT1">
                +                                                                                  <block type="unittest_adjustindex">
                +                                                                                    <value name="INDEX">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">4</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="AT2">
                +                                                                                  <block type="unittest_adjustindex">
                +                                                                                    <value name="INDEX">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">4</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">list</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                <value name="MESSAGE">
                +                                                                                  <block type="text">
                +                                                                                    <field name="TEXT">sublist all with # #-end math simple</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ACTUAL">
                +                                                                                  <block type="lists_getSublist">
                +                                                                                    <mutation at1="true" at2="true"></mutation>
                +                                                                                    <field name="WHERE1">FROM_START</field>
                +                                                                                    <field name="WHERE2">FROM_END</field>
                +                                                                                    <comment pinned="false" h="93" w="347">Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end.</comment>
                +                                                                                    <value name="LIST">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">list</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="AT1">
                +                                                                                      <block type="math_arithmetic">
                +                                                                                        <field name="OP">ADD</field>
                +                                                                                        <value name="A">
                +                                                                                          <block type="math_number">
                +                                                                                            <field name="NUM">0</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="B">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">0</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="AT2">
                +                                                                                      <block type="math_arithmetic">
                +                                                                                        <field name="OP">ADD</field>
                +                                                                                        <value name="A">
                +                                                                                          <block type="math_number">
                +                                                                                            <field name="NUM">0</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="B">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">0</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="EXPECTED">
                +                                                                                  <block type="variables_get">
                +                                                                                    <field name="VAR">list</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="16238">
                +    <field name="NAME">get space shuttles</field>
                +    <comment pinned="false" h="80" w="160">Creates a list for use with the sublist test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="lists_create_with" inline="true">
                +        <mutation items="5"></mutation>
                +        <value name="ADD0">
                +          <block type="text">
                +            <field name="TEXT">Columbia</field>
                +          </block>
                +        </value>
                +        <value name="ADD1">
                +          <block type="text">
                +            <field name="TEXT">Challenger</field>
                +          </block>
                +        </value>
                +        <value name="ADD2">
                +          <block type="text">
                +            <field name="TEXT">Discovery</field>
                +          </block>
                +        </value>
                +        <value name="ADD3">
                +          <block type="text">
                +            <field name="TEXT">Atlantis</field>
                +          </block>
                +        </value>
                +        <value name="ADD4">
                +          <block type="text">
                +            <field name="TEXT">Endeavour</field>
                +          </block>
                +        </value>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="16363">
                +    <field name="NAME">test sublist complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get sub-list" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">number of calls</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">sublist # start complex</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_getSublist">
                +                <mutation at1="true" at2="true"></mutation>
                +                <field name="WHERE1">FROM_START</field>
                +                <field name="WHERE2">FROM_START</field>
                +                <value name="LIST">
                +                  <block type="procedures_callreturn">
                +                    <mutation name="get space shuttles"></mutation>
                +                  </block>
                +                </value>
                +                <value name="AT1">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="AT2">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="2"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Challenger</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">Discovery</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="procedures_callnoreturn" inline="true">
                +                <mutation name="check number of calls">
                +                  <arg name="test name"></arg>
                +                </mutation>
                +                <value name="ARG0">
                +                  <block type="text">
                +                    <field name="TEXT">sublist # start complex</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">number of calls</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">sublist # start order complex</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_getSublist">
                +                            <mutation at1="true" at2="true"></mutation>
                +                            <field name="WHERE1">FROM_START</field>
                +                            <field name="WHERE2">FROM_START</field>
                +                            <value name="LIST">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="procedures_callreturn">
                +                                    <mutation name="get space shuttles"></mutation>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT1">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT2">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="lists_create_with" inline="true">
                +                            <mutation items="2"></mutation>
                +                            <value name="ADD0">
                +                              <block type="text">
                +                                <field name="TEXT">Challenger</field>
                +                              </block>
                +                            </value>
                +                            <value name="ADD1">
                +                              <block type="text">
                +                                <field name="TEXT">Discovery</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="procedures_callnoreturn" inline="true">
                +                            <mutation name="check number of calls">
                +                              <arg name="test name"></arg>
                +                            </mutation>
                +                            <value name="ARG0">
                +                              <block type="text">
                +                                <field name="TEXT">sublist # start order complex</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">number of calls</field>
                +                                <value name="VALUE">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">sublist # end complex</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="lists_getSublist">
                +                                        <mutation at1="true" at2="true"></mutation>
                +                                        <field name="WHERE1">FROM_END</field>
                +                                        <field name="WHERE2">FROM_END</field>
                +                                        <comment pinned="false" h="78" w="267">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                        <value name="LIST">
                +                                          <block type="procedures_callreturn">
                +                                            <mutation name="get space shuttles"></mutation>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT1">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">2</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT2">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">1</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="lists_create_with" inline="true">
                +                                        <mutation items="2"></mutation>
                +                                        <value name="ADD0">
                +                                          <block type="text">
                +                                            <field name="TEXT">Discovery</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ADD1">
                +                                          <block type="text">
                +                                            <field name="TEXT">Atlantis</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">sublist # end complex number of calls</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">number of calls</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set">
                +                                            <field name="VAR">number of calls</field>
                +                                            <value name="VALUE">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">sublist # end order complex</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="lists_getSublist">
                +                                                    <mutation at1="true" at2="true"></mutation>
                +                                                    <field name="WHERE1">FROM_END</field>
                +                                                    <field name="WHERE2">FROM_END</field>
                +                                                    <value name="LIST">
                +                                                      <block type="logic_ternary" inline="false">
                +                                                        <value name="IF">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="THEN">
                +                                                          <block type="procedures_callreturn">
                +                                                            <mutation name="get space shuttles"></mutation>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ELSE">
                +                                                          <block type="logic_null"></block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT1">
                +                                                      <block type="math_arithmetic">
                +                                                        <field name="OP">ADD</field>
                +                                                        <value name="A">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">2</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT2">
                +                                                      <block type="math_arithmetic">
                +                                                        <field name="OP">ADD</field>
                +                                                        <value name="A">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">1</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="lists_create_with" inline="true">
                +                                                    <mutation items="2"></mutation>
                +                                                    <value name="ADD0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Discovery</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD1">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Atlantis</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                    <mutation name="check number of calls">
                +                                                      <arg name="test name"></arg>
                +                                                    </mutation>
                +                                                    <value name="ARG0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">sublist # end order complex</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set">
                +                                                        <field name="VAR">number of calls</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">sublist first-last complex</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="lists_getSublist">
                +                                                                <mutation at1="false" at2="false"></mutation>
                +                                                                <field name="WHERE1">FIRST</field>
                +                                                                <field name="WHERE2">LAST</field>
                +                                                                <value name="LIST">
                +                                                                  <block type="procedures_callreturn">
                +                                                                    <mutation name="get space shuttles"></mutation>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">list</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                <mutation name="check number of calls">
                +                                                                  <arg name="test name"></arg>
                +                                                                </mutation>
                +                                                                <value name="ARG0">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">sublist first-last complex</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set">
                +                                                                    <field name="VAR">number of calls</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">0</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">sublist # #-end complex</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="lists_getSublist">
                +                                                                            <mutation at1="true" at2="true"></mutation>
                +                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                            <field name="WHERE2">FROM_END</field>
                +                                                                            <value name="LIST">
                +                                                                              <block type="procedures_callreturn">
                +                                                                                <mutation name="get space shuttles"></mutation>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT1">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">1</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT2">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">1</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="EXPECTED">
                +                                                                          <block type="lists_create_with" inline="true">
                +                                                                            <mutation items="3"></mutation>
                +                                                                            <value name="ADD0">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">Challenger</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ADD1">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">Discovery</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ADD2">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">Atlantis</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                            <mutation name="check number of calls">
                +                                                                              <arg name="test name"></arg>
                +                                                                            </mutation>
                +                                                                            <value name="ARG0">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">sublist # #-end complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set">
                +                                                                                <field name="VAR">number of calls</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">0</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                    <value name="MESSAGE">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">sublist #-end # complex</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ACTUAL">
                +                                                                                      <block type="lists_getSublist">
                +                                                                                        <mutation at1="true" at2="true"></mutation>
                +                                                                                        <field name="WHERE1">FROM_END</field>
                +                                                                                        <field name="WHERE2">FROM_START</field>
                +                                                                                        <value name="LIST">
                +                                                                                          <block type="procedures_callreturn">
                +                                                                                            <mutation name="get space shuttles"></mutation>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="AT1">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">2</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="AT2">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">3</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="EXPECTED">
                +                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                        <mutation items="2"></mutation>
                +                                                                                        <value name="ADD0">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">Discovery</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ADD1">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">Atlantis</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                        <mutation name="check number of calls">
                +                                                                                          <arg name="test name"></arg>
                +                                                                                        </mutation>
                +                                                                                        <value name="ARG0">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">sublist #-end # complex</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set">
                +                                                                                            <field name="VAR">number of calls</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">0</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                <value name="MESSAGE">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">sublist first # complex</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ACTUAL">
                +                                                                                                  <block type="lists_getSublist">
                +                                                                                                    <mutation at1="false" at2="true"></mutation>
                +                                                                                                    <field name="WHERE1">FIRST</field>
                +                                                                                                    <field name="WHERE2">FROM_START</field>
                +                                                                                                    <value name="LIST">
                +                                                                                                      <block type="procedures_callreturn">
                +                                                                                                        <mutation name="get space shuttles"></mutation>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="AT2">
                +                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                        <value name="INDEX">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">3</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="EXPECTED">
                +                                                                                                  <block type="lists_create_with" inline="true">
                +                                                                                                    <mutation items="4"></mutation>
                +                                                                                                    <value name="ADD0">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">Columbia</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ADD1">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">Challenger</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ADD2">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">Discovery</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ADD3">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">Atlantis</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                    <mutation name="check number of calls">
                +                                                                                                      <arg name="test name"></arg>
                +                                                                                                    </mutation>
                +                                                                                                    <value name="ARG0">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">sublist first # complex</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set">
                +                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">0</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                            <value name="MESSAGE">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">sublist first #-end complex</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ACTUAL">
                +                                                                                                              <block type="lists_getSublist">
                +                                                                                                                <mutation at1="false" at2="true"></mutation>
                +                                                                                                                <field name="WHERE1">FIRST</field>
                +                                                                                                                <field name="WHERE2">FROM_END</field>
                +                                                                                                                <value name="LIST">
                +                                                                                                                  <block type="procedures_callreturn">
                +                                                                                                                    <mutation name="get space shuttles"></mutation>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="AT2">
                +                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                    <value name="INDEX">
                +                                                                                                                      <block type="math_number">
                +                                                                                                                        <field name="NUM">3</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="EXPECTED">
                +                                                                                                              <block type="lists_create_with" inline="true">
                +                                                                                                                <mutation items="2"></mutation>
                +                                                                                                                <value name="ADD0">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">Columbia</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ADD1">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">Challenger</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                <mutation name="check number of calls">
                +                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                </mutation>
                +                                                                                                                <value name="ARG0">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">sublist first #-end complex</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set">
                +                                                                                                                    <field name="VAR">number of calls</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="math_number">
                +                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                                                        <value name="MESSAGE">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">sublist # last complex</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ACTUAL">
                +                                                                                                                          <block type="lists_getSublist">
                +                                                                                                                            <mutation at1="true" at2="false"></mutation>
                +                                                                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                                                                            <field name="WHERE2">LAST</field>
                +                                                                                                                            <value name="LIST">
                +                                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                                <mutation name="get space shuttles"></mutation>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="AT1">
                +                                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                                <value name="INDEX">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">3</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="EXPECTED">
                +                                                                                                                          <block type="lists_create_with" inline="true">
                +                                                                                                                            <mutation items="2"></mutation>
                +                                                                                                                            <value name="ADD0">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">Atlantis</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ADD1">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">Endeavour</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                            <mutation name="check number of calls">
                +                                                                                                                              <arg name="test name"></arg>
                +                                                                                                                            </mutation>
                +                                                                                                                            <value name="ARG0">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">sublist # last complex</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <next>
                +                                                                                                                              <block type="variables_set">
                +                                                                                                                                <field name="VAR">number of calls</field>
                +                                                                                                                                <value name="VALUE">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <next>
                +                                                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                                                    <value name="MESSAGE">
                +                                                                                                                                      <block type="text">
                +                                                                                                                                        <field name="TEXT">sublist #-end last simple</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="ACTUAL">
                +                                                                                                                                      <block type="lists_getSublist">
                +                                                                                                                                        <mutation at1="true" at2="false"></mutation>
                +                                                                                                                                        <field name="WHERE1">FROM_END</field>
                +                                                                                                                                        <field name="WHERE2">LAST</field>
                +                                                                                                                                        <value name="LIST">
                +                                                                                                                                          <block type="procedures_callreturn">
                +                                                                                                                                            <mutation name="get space shuttles"></mutation>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <value name="AT1">
                +                                                                                                                                          <block type="unittest_adjustindex">
                +                                                                                                                                            <value name="INDEX">
                +                                                                                                                                              <block type="math_number">
                +                                                                                                                                                <field name="NUM">3</field>
                +                                                                                                                                              </block>
                +                                                                                                                                            </value>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="EXPECTED">
                +                                                                                                                                      <block type="lists_create_with" inline="true">
                +                                                                                                                                        <mutation items="4"></mutation>
                +                                                                                                                                        <value name="ADD0">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">Challenger</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <value name="ADD1">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">Discovery</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <value name="ADD2">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">Atlantis</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <value name="ADD3">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">Endeavour</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <next>
                +                                                                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                        <mutation name="check number of calls">
                +                                                                                                                                          <arg name="test name"></arg>
                +                                                                                                                                        </mutation>
                +                                                                                                                                        <value name="ARG0">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">sublist #-end last simple</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <next>
                +                                                                                                                                          <block type="variables_set">
                +                                                                                                                                            <field name="VAR">number of calls</field>
                +                                                                                                                                            <value name="VALUE">
                +                                                                                                                                              <block type="math_number">
                +                                                                                                                                                <field name="NUM">0</field>
                +                                                                                                                                              </block>
                +                                                                                                                                            </value>
                +                                                                                                                                            <next>
                +                                                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                <value name="MESSAGE">
                +                                                                                                                                                  <block type="text">
                +                                                                                                                                                    <field name="TEXT">sublist all with # #-end complex</field>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <value name="ACTUAL">
                +                                                                                                                                                  <block type="lists_getSublist">
                +                                                                                                                                                    <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                    <field name="WHERE1">FROM_START</field>
                +                                                                                                                                                    <field name="WHERE2">FROM_END</field>
                +                                                                                                                                                    <value name="LIST">
                +                                                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                                                        <mutation name="get space shuttles"></mutation>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <value name="AT1">
                +                                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                                        <value name="INDEX">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <value name="AT2">
                +                                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                                        <value name="INDEX">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <value name="EXPECTED">
                +                                                                                                                                                  <block type="variables_get">
                +                                                                                                                                                    <field name="VAR">list</field>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <next>
                +                                                                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                    <mutation name="check number of calls">
                +                                                                                                                                                      <arg name="test name"></arg>
                +                                                                                                                                                    </mutation>
                +                                                                                                                                                    <value name="ARG0">
                +                                                                                                                                                      <block type="text">
                +                                                                                                                                                        <field name="TEXT">sublist all with # #-end complex</field>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <next>
                +                                                                                                                                                      <block type="variables_set">
                +                                                                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                                                                        <value name="VALUE">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                        <next>
                +                                                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                            <value name="MESSAGE">
                +                                                                                                                                                              <block type="text">
                +                                                                                                                                                                <field name="TEXT">sublist all with #-end # complex</field>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <value name="ACTUAL">
                +                                                                                                                                                              <block type="lists_getSublist">
                +                                                                                                                                                                <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                                <field name="WHERE1">FROM_END</field>
                +                                                                                                                                                                <field name="WHERE2">FROM_START</field>
                +                                                                                                                                                                <value name="LIST">
                +                                                                                                                                                                  <block type="procedures_callreturn">
                +                                                                                                                                                                    <mutation name="get space shuttles"></mutation>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <value name="AT1">
                +                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">4</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <value name="AT2">
                +                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">4</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <value name="EXPECTED">
                +                                                                                                                                                              <block type="variables_get">
                +                                                                                                                                                                <field name="VAR">list</field>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <next>
                +                                                                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                                <mutation name="check number of calls">
                +                                                                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                                                                </mutation>
                +                                                                                                                                                                <value name="ARG0">
                +                                                                                                                                                                  <block type="text">
                +                                                                                                                                                                    <field name="TEXT">sublist all with #-end # complex</field>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <next>
                +                                                                                                                                                                  <block type="variables_set">
                +                                                                                                                                                                    <field name="VAR">number of calls</field>
                +                                                                                                                                                                    <value name="VALUE">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                    <next>
                +                                                                                                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                                        <value name="MESSAGE">
                +                                                                                                                                                                          <block type="text">
                +                                                                                                                                                                            <field name="TEXT">sublist all with # #-end math complex</field>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <value name="ACTUAL">
                +                                                                                                                                                                          <block type="lists_getSublist">
                +                                                                                                                                                                            <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                                                                                                                            <field name="WHERE2">FROM_END</field>
                +                                                                                                                                                                            <comment pinned="false" h="96" w="315">Checks that the whole list is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where sublist uses [x:length - y] for # #-end.</comment>
                +                                                                                                                                                                            <value name="LIST">
                +                                                                                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                                                                                <mutation name="get space shuttles"></mutation>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                            <value name="AT1">
                +                                                                                                                                                                              <block type="math_arithmetic">
                +                                                                                                                                                                                <field name="OP">ADD</field>
                +                                                                                                                                                                                <value name="A">
                +                                                                                                                                                                                  <block type="math_number">
                +                                                                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                                <value name="B">
                +                                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                                      </block>
                +                                                                                                                                                                                    </value>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                            <value name="AT2">
                +                                                                                                                                                                              <block type="math_arithmetic">
                +                                                                                                                                                                                <field name="OP">ADD</field>
                +                                                                                                                                                                                <value name="A">
                +                                                                                                                                                                                  <block type="math_number">
                +                                                                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                                <value name="B">
                +                                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                                      </block>
                +                                                                                                                                                                                    </value>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <value name="EXPECTED">
                +                                                                                                                                                                          <block type="variables_get">
                +                                                                                                                                                                            <field name="VAR">list</field>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <next>
                +                                                                                                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                                            <mutation name="check number of calls">
                +                                                                                                                                                                              <arg name="test name"></arg>
                +                                                                                                                                                                            </mutation>
                +                                                                                                                                                                            <value name="ARG0">
                +                                                                                                                                                                              <block type="text">
                +                                                                                                                                                                                <field name="TEXT">sublist all with # #-end math complex</field>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </next>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </next>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </next>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </next>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </next>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </next>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </next>
                +                                                                                                                                              </block>
                +                                                                                                                                            </next>
                +                                                                                                                                          </block>
                +                                                                                                                                        </next>
                +                                                                                                                                      </block>
                +                                                                                                                                    </next>
                +                                                                                                                                  </block>
                +                                                                                                                                </next>
                +                                                                                                                              </block>
                +                                                                                                                            </next>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="18963">
                +    <field name="NAME">test join</field>
                +    <comment pinned="false" h="80" w="160">Tests the "join" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Vulcan</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">Klingon</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Borg</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">join</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_split">
                +                <mutation mode="JOIN"></mutation>
                +                <field name="MODE">JOIN</field>
                +                <value name="INPUT">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="DELIM">
                +                  <block type="text">
                +                    <field name="TEXT">,</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">Vulcan,Klingon,Borg</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">join order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_split">
                +                    <mutation mode="JOIN"></mutation>
                +                    <field name="MODE">JOIN</field>
                +                    <value name="INPUT">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="DELIM">
                +                      <block type="text">
                +                        <field name="TEXT">,</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">Vulcan,Klingon,Borg</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="19263">
                +    <field name="NAME">test split</field>
                +    <comment pinned="false" h="80" w="160">Tests the "split" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Vulcan,Klingon,Borg</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">split</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_split">
                +                <mutation mode="SPLIT"></mutation>
                +                <field name="MODE">SPLIT</field>
                +                <value name="INPUT">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +                <value name="DELIM">
                +                  <block type="text">
                +                    <field name="TEXT">,</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Vulcan</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">Klingon</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="text">
                +                    <field name="TEXT">Borg</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">split order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_split">
                +                    <mutation mode="SPLIT"></mutation>
                +                    <field name="MODE">SPLIT</field>
                +                    <value name="INPUT">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="DELIM">
                +                      <block type="text">
                +                        <field name="TEXT">,</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Vulcan</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Klingon</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">Borg</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="19563">
                +    <field name="NAME">test sort alphabetic</field>
                +    <comment pinned="false" h="80" w="160">Tests the "alphabetic sort" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Vulcan</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">klingon</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Borg</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">sort alphabetic ascending</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_sort">
                +                <field name="TYPE">TEXT</field>
                +                <field name="DIRECTION">1</field>
                +                <value name="LIST">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Borg</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">Vulcan</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="text">
                +                    <field name="TEXT">klingon</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">sort alphabetic ascending order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_sort">
                +                    <field name="TYPE">TEXT</field>
                +                    <field name="DIRECTION">1</field>
                +                    <value name="LIST">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Borg</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">Vulcan</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">klingon</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="19863">
                +    <field name="NAME">test sort ignoreCase</field>
                +    <comment pinned="false" h="80" w="160">Tests the "alphabetic sort ignore case" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="text">
                +                <field name="TEXT">Vulcan</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="text">
                +                <field name="TEXT">klingon</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="text">
                +                <field name="TEXT">Borg</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">sort ignore case ascending</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_sort">
                +                <field name="TYPE">IGNORE_CASE</field>
                +                <field name="DIRECTION">1</field>
                +                <value name="LIST">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Borg</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">klingon</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="text">
                +                    <field name="TEXT">Vulcan</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">sort ignore case ascending order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_sort">
                +                    <field name="TYPE">IGNORE_CASE</field>
                +                    <field name="DIRECTION">1</field>
                +                    <value name="LIST">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="text">
                +                        <field name="TEXT">Borg</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="text">
                +                        <field name="TEXT">klingon</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="text">
                +                        <field name="TEXT">Vulcan</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="20163">
                +    <field name="NAME">test sort numeric</field>
                +    <comment pinned="false" h="80" w="160">Tests the "numeric sort" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="3"></mutation>
                +            <value name="ADD0">
                +              <block type="math_number">
                +                <field name="NUM">8</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="math_number">
                +                <field name="NUM">18</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="math_number">
                +                <field name="NUM">-1</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">sort numeric descending</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_sort">
                +                <field name="TYPE">NUMERIC</field>
                +                <field name="DIRECTION">-1</field>
                +                <value name="LIST">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="math_number">
                +                    <field name="NUM">18</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="math_number">
                +                    <field name="NUM">8</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="math_number">
                +                    <field name="NUM">-1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">sort numeric descending order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="lists_sort">
                +                    <field name="TYPE">NUMERIC</field>
                +                    <field name="DIRECTION">-1</field>
                +                    <value name="LIST">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">list</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="math_number">
                +                        <field name="NUM">18</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="math_number">
                +                        <field name="NUM">8</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="math_number">
                +                        <field name="NUM">-1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="20463">
                +    <field name="NAME">test reverse</field>
                +    <comment pinned="false" h="80" w="160">Tests the "list reverse" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">list</field>
                +        <value name="VALUE">
                +          <block type="lists_create_with" inline="true">
                +            <mutation items="4"></mutation>
                +            <value name="ADD0">
                +              <block type="math_number">
                +                <field name="NUM">8</field>
                +              </block>
                +            </value>
                +            <value name="ADD1">
                +              <block type="math_number">
                +                <field name="NUM">18</field>
                +              </block>
                +            </value>
                +            <value name="ADD2">
                +              <block type="math_number">
                +                <field name="NUM">-1</field>
                +              </block>
                +            </value>
                +            <value name="ADD3">
                +              <block type="math_number">
                +                <field name="NUM">64</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">reverse a copy</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="lists_reverse">
                +                <value name="LIST">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="4"></mutation>
                +                <value name="ADD0">
                +                  <block type="math_number">
                +                    <field name="NUM">64</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="math_number">
                +                    <field name="NUM">-1</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="math_number">
                +                    <field name="NUM">18</field>
                +                  </block>
                +                </value>
                +                <value name="ADD3">
                +                  <block type="math_number">
                +                    <field name="NUM">8</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">reverse a copy original</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">list</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="4"></mutation>
                +                    <value name="ADD0">
                +                      <block type="math_number">
                +                        <field name="NUM">8</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="math_number">
                +                        <field name="NUM">18</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="math_number">
                +                        <field name="NUM">-1</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD3">
                +                      <block type="math_number">
                +                        <field name="NUM">64</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">list</field>
                +                    <value name="VALUE">
                +                      <block type="lists_create_empty"></block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">empty list</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="lists_reverse">
                +                            <value name="LIST">
                +                              <block type="variables_get">
                +                                <field name="VAR">list</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="lists_create_empty"></block>
                +                        </value>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/generators/logic.xml b/blockly/webif/static/blockly/tests/generators/logic.xml
                new file mode 100644
                index 000000000..9737fb812
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/logic.xml
                @@ -0,0 +1,1018 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="-13" y="-13">
                +    <statement name="DO">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">TRUE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">True</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="logic_boolean">
                +            <field name="BOOL">TRUE</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">FALSE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">False</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_boolean">
                +                <field name="BOOL">FALSE</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">Not true</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="logic_negate" inline="false">
                +                    <value name="BOOL">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">FALSE</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">FALSE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">Not false</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_negate" inline="false">
                +                        <value name="BOOL">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="procedures_callnoreturn">
                +                        <mutation name="test if"></mutation>
                +                        <next>
                +                          <block type="procedures_callnoreturn">
                +                            <mutation name="test ifelse"></mutation>
                +                            <next>
                +                              <block type="procedures_callnoreturn">
                +                                <mutation name="test equalities"></mutation>
                +                                <next>
                +                                  <block type="procedures_callnoreturn">
                +                                    <mutation name="test and"></mutation>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn">
                +                                        <mutation name="test or"></mutation>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn">
                +                                            <mutation name="test ternary"></mutation>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="387" y="-13">
                +    <field name="NAME">test if</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="controls_if" inline="false">
                +        <value name="IF0">
                +          <block type="logic_boolean">
                +            <field name="BOOL">FALSE</field>
                +          </block>
                +        </value>
                +        <statement name="DO0">
                +          <block type="unittest_fail">
                +            <field name="MESSAGE">if false</field>
                +          </block>
                +        </statement>
                +        <next>
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">ok</field>
                +            <value name="VALUE">
                +              <block type="logic_boolean">
                +                <field name="BOOL">FALSE</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="controls_if" inline="false">
                +                <value name="IF0">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +                <statement name="DO0">
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">ok</field>
                +                    <value name="VALUE">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">TRUE</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </statement>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">TRUE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">if true</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="variables_get">
                +                        <field name="VAR">ok</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="variables_set" inline="false">
                +                        <field name="VAR">ok</field>
                +                        <value name="VALUE">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="controls_if" inline="false">
                +                            <mutation else="1"></mutation>
                +                            <value name="IF0">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">FALSE</field>
                +                              </block>
                +                            </value>
                +                            <statement name="DO0">
                +                              <block type="unittest_fail">
                +                                <field name="MESSAGE">if/else false</field>
                +                              </block>
                +                            </statement>
                +                            <statement name="ELSE">
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">ok</field>
                +                                <value name="VALUE">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </statement>
                +                            <next>
                +                              <block type="unittest_assertvalue" inline="false">
                +                                <field name="EXPECTED">TRUE</field>
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">if/else false</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">ok</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="variables_set" inline="false">
                +                                    <field name="VAR">ok</field>
                +                                    <value name="VALUE">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">FALSE</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="controls_if" inline="false">
                +                                        <mutation else="1"></mutation>
                +                                        <value name="IF0">
                +                                          <block type="logic_boolean">
                +                                            <field name="BOOL">TRUE</field>
                +                                          </block>
                +                                        </value>
                +                                        <statement name="DO0">
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">ok</field>
                +                                            <value name="VALUE">
                +                                              <block type="logic_boolean">
                +                                                <field name="BOOL">TRUE</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </statement>
                +                                        <statement name="ELSE">
                +                                          <block type="unittest_fail">
                +                                            <field name="MESSAGE">if/else true</field>
                +                                          </block>
                +                                        </statement>
                +                                        <next>
                +                                          <block type="unittest_assertvalue" inline="false">
                +                                            <field name="EXPECTED">TRUE</field>
                +                                            <value name="MESSAGE">
                +                                              <block type="text">
                +                                                <field name="TEXT">if/else true</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ACTUAL">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">ok</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="variables_set" inline="false">
                +                                                <field name="VAR">ok</field>
                +                                                <value name="VALUE">
                +                                                  <block type="logic_boolean">
                +                                                    <field name="BOOL">FALSE</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="controls_if" inline="false">
                +                                                    <mutation elseif="2" else="1"></mutation>
                +                                                    <value name="IF0">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">FALSE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <statement name="DO0">
                +                                                      <block type="unittest_fail">
                +                                                        <field name="MESSAGE">elseif 1</field>
                +                                                      </block>
                +                                                    </statement>
                +                                                    <value name="IF1">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">TRUE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <statement name="DO1">
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">ok</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </statement>
                +                                                    <value name="IF2">
                +                                                      <block type="logic_boolean">
                +                                                        <field name="BOOL">TRUE</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <statement name="DO2">
                +                                                      <block type="unittest_fail">
                +                                                        <field name="MESSAGE">elseif 2</field>
                +                                                      </block>
                +                                                    </statement>
                +                                                    <statement name="ELSE">
                +                                                      <block type="unittest_fail">
                +                                                        <field name="MESSAGE">elseif 3</field>
                +                                                      </block>
                +                                                    </statement>
                +                                                    <next>
                +                                                      <block type="unittest_assertvalue" inline="false">
                +                                                        <field name="EXPECTED">TRUE</field>
                +                                                        <value name="MESSAGE">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">elseif 4</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ACTUAL">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">ok</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="712" y="-13">
                +    <field name="NAME">test ifelse</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">ok</field>
                +        <value name="VALUE">
                +          <block type="logic_boolean">
                +            <field name="BOOL">FALSE</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_ifelse">
                +            <value name="IF0">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +            <statement name="DO0">
                +              <block type="variables_set">
                +                <field name="VAR">ok</field>
                +                <value name="VALUE">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <statement name="ELSE">
                +              <block type="unittest_fail">
                +                <field name="MESSAGE">ifelse true</field>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertvalue">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">ifelse true</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">ok</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">ok</field>
                +                    <value name="VALUE">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">FALSE</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_ifelse">
                +                        <value name="IF0">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                        <statement name="DO0">
                +                          <block type="unittest_fail">
                +                            <field name="MESSAGE">ifelse false</field>
                +                          </block>
                +                        </statement>
                +                        <statement name="ELSE">
                +                          <block type="variables_set">
                +                            <field name="VAR">ok</field>
                +                            <value name="VALUE">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </statement>
                +                        <next>
                +                          <block type="unittest_assertvalue">
                +                            <field name="EXPECTED">TRUE</field>
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">ifelse false</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">ok</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-12" y="412">
                +    <field name="NAME">test equalities</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">TRUE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">Equal yes</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="logic_compare">
                +            <field name="OP">EQ</field>
                +            <value name="A">
                +              <block type="math_number">
                +                <field name="NUM">2</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="math_number">
                +                <field name="NUM">2</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">FALSE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">Equal no</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_compare">
                +                <field name="OP">EQ</field>
                +                <value name="A">
                +                  <block type="math_number">
                +                    <field name="NUM">3</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="math_number">
                +                    <field name="NUM">4</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">Not equal yes</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="logic_compare">
                +                    <field name="OP">NEQ</field>
                +                    <value name="A">
                +                      <block type="math_number">
                +                        <field name="NUM">5</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">6</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">FALSE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">Not equal no</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_compare">
                +                        <field name="OP">EQ</field>
                +                        <value name="A">
                +                          <block type="math_number">
                +                            <field name="NUM">3</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">4</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertvalue" inline="false">
                +                        <field name="EXPECTED">TRUE</field>
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">Smaller yes</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="logic_compare">
                +                            <field name="OP">LT</field>
                +                            <value name="A">
                +                              <block type="math_number">
                +                                <field name="NUM">5</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">6</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertvalue" inline="false">
                +                            <field name="EXPECTED">FALSE</field>
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">Smaller no</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="logic_compare">
                +                                <field name="OP">LT</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">7</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="math_number">
                +                                    <field name="NUM">7</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertvalue" inline="false">
                +                                <field name="EXPECTED">TRUE</field>
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">Greater yes</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="logic_compare">
                +                                    <field name="OP">GT</field>
                +                                    <value name="A">
                +                                      <block type="math_number">
                +                                        <field name="NUM">9</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="B">
                +                                      <block type="math_number">
                +                                        <field name="NUM">8</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertvalue" inline="false">
                +                                    <field name="EXPECTED">FALSE</field>
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">Greater no</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="logic_compare">
                +                                        <field name="OP">GT</field>
                +                                        <value name="A">
                +                                          <block type="math_number">
                +                                            <field name="NUM">10</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="B">
                +                                          <block type="math_number">
                +                                            <field name="NUM">10</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertvalue" inline="false">
                +                                        <field name="EXPECTED">TRUE</field>
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">Smaller-equal yes</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="logic_compare">
                +                                            <field name="OP">LTE</field>
                +                                            <value name="A">
                +                                              <block type="math_number">
                +                                                <field name="NUM">11</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">11</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="unittest_assertvalue" inline="false">
                +                                            <field name="EXPECTED">FALSE</field>
                +                                            <value name="MESSAGE">
                +                                              <block type="text">
                +                                                <field name="TEXT">Smaller-equal no</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ACTUAL">
                +                                              <block type="logic_compare">
                +                                                <field name="OP">LTE</field>
                +                                                <value name="A">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">13</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="B">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">12</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertvalue" inline="false">
                +                                                <field name="EXPECTED">TRUE</field>
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">Greater-equal yes</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="logic_compare">
                +                                                    <field name="OP">GTE</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">14</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">14</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertvalue" inline="false">
                +                                                    <field name="EXPECTED">FALSE</field>
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">Greater-equal no</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="logic_compare">
                +                                                        <field name="OP">GTE</field>
                +                                                        <value name="A">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">15</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">16</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="385" y="1208">
                +    <field name="NAME">test and</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">TRUE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">And true/true</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="logic_operation">
                +            <field name="OP">AND</field>
                +            <value name="A">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">FALSE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">And false/true</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_operation">
                +                <field name="OP">AND</field>
                +                <value name="A">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">FALSE</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">FALSE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">And true/false</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="logic_operation">
                +                    <field name="OP">AND</field>
                +                    <value name="A">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">TRUE</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">FALSE</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">FALSE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">And false/false</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_operation">
                +                        <field name="OP">AND</field>
                +                        <value name="A">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-13" y="1238">
                +    <field name="NAME">test or</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">TRUE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">Or true/true</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="logic_operation">
                +            <field name="OP">OR</field>
                +            <value name="A">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">TRUE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">Or false/true</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_operation">
                +                <field name="OP">OR</field>
                +                <value name="A">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">FALSE</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">TRUE</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">Or true/false</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="logic_operation">
                +                    <field name="OP">OR</field>
                +                    <value name="A">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">TRUE</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="logic_boolean">
                +                        <field name="BOOL">FALSE</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">FALSE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">Or false/false</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_operation">
                +                        <field name="OP">OR</field>
                +                        <value name="A">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">FALSE</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="-13" y="1563">
                +    <field name="NAME">test ternary</field>
                +    <comment pinned="false" h="80" w="160">Describe this function...</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">if true</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="logic_ternary" inline="true">
                +            <value name="IF">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +            <value name="THEN">
                +              <block type="math_number">
                +                <field name="NUM">42</field>
                +              </block>
                +            </value>
                +            <value name="ELSE">
                +              <block type="math_number">
                +                <field name="NUM">99</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">42</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">if true</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_ternary" inline="true">
                +                <value name="IF">
                +                  <block type="logic_boolean">
                +                    <field name="BOOL">FALSE</field>
                +                  </block>
                +                </value>
                +                <value name="THEN">
                +                  <block type="math_number">
                +                    <field name="NUM">42</field>
                +                  </block>
                +                </value>
                +                <value name="ELSE">
                +                  <block type="math_number">
                +                    <field name="NUM">99</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">99</field>
                +              </block>
                +            </value>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/generators/loops1.xml b/blockly/webif/static/blockly/tests/generators/loops1.xml
                new file mode 100644
                index 000000000..41dd3b633
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/loops1.xml
                @@ -0,0 +1,344 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="33" y="140">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test repeat"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test repeat_ext"></mutation>
                +            <next>
                +              <block type="procedures_callnoreturn">
                +                <mutation name="test while"></mutation>
                +                <next>
                +                  <block type="procedures_callnoreturn">
                +                    <mutation name="test foreach"></mutation>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="31" y="296">
                +    <mutation></mutation>
                +    <field name="NAME">test foreach</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">log</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_forEach" inline="false">
                +            <field name="VAR">x</field>
                +            <value name="LIST">
                +              <block type="lists_create_with" inline="false">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">a</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="text">
                +                    <field name="TEXT">b</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="text">
                +                    <field name="TEXT">c</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="text_append" inline="false">
                +                <field name="VAR">log</field>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">x</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">for loop</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">log</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">abc</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="30" y="624">
                +    <mutation></mutation>
                +    <field name="NAME">test while</field>
                +    <statement name="STACK">
                +      <block type="controls_whileUntil" inline="false">
                +        <field name="MODE">WHILE</field>
                +        <value name="BOOL">
                +          <block type="logic_boolean">
                +            <field name="BOOL">FALSE</field>
                +          </block>
                +        </value>
                +        <statement name="DO">
                +          <block type="unittest_fail">
                +             <field name="MESSAGE">while 0</field>
                +          </block>
                +        </statement>
                +        <next>
                +          <block type="controls_whileUntil" inline="false">
                +            <field name="MODE">UNTIL</field>
                +            <value name="BOOL">
                +              <block type="logic_boolean">
                +                <field name="BOOL">TRUE</field>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="unittest_fail">
                +                 <field name="MESSAGE">until 0</field>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="variables_set" inline="false">
                +                <field name="VAR">count</field>
                +                <value name="VALUE">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="controls_whileUntil" inline="false">
                +                    <field name="MODE">WHILE</field>
                +                    <value name="BOOL">
                +                      <block type="logic_compare">
                +                        <field name="OP">NEQ</field>
                +                        <value name="A">
                +                          <block type="variables_get">
                +                            <field name="VAR">count</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">10</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <statement name="DO">
                +                      <block type="math_change" inline="false">
                +                        <field name="VAR">count</field>
                +                        <value name="DELTA">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </statement>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                           <block type="text">
                +                             <field name="TEXT">while 10</field>
                +                           </block>
                +                         </value>
                +                        <value name="ACTUAL">
                +                          <block type="variables_get">
                +                            <field name="VAR">count</field>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">10</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="variables_set" inline="false">
                +                            <field name="VAR">count</field>
                +                            <value name="VALUE">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="controls_whileUntil" inline="false">
                +                                <field name="MODE">UNTIL</field>
                +                                <value name="BOOL">
                +                                  <block type="logic_compare">
                +                                    <field name="OP">EQ</field>
                +                                    <value name="A">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">count</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="B">
                +                                      <block type="math_number">
                +                                        <field name="NUM">10</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <statement name="DO">
                +                                  <block type="math_change" inline="false">
                +                                    <field name="VAR">count</field>
                +                                    <value name="DELTA">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </statement>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                       <block type="text">
                +                                         <field name="TEXT">until 10</field>
                +                                       </block>
                +                                     </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">count</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="math_number">
                +                                        <field name="NUM">10</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="397" y="448">
                +    <mutation></mutation>
                +    <field name="NAME">test repeat</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">count</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_repeat" inline="true">
                +            <field name="TIMES">10</field>
                +            <statement name="DO">
                +              <block type="math_change" inline="false">
                +                <field name="VAR">count</field>
                +                <value name="DELTA">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">repeat 10</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">count</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">10</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="397" y="668">
                +    <mutation></mutation>
                +    <field name="NAME">test repeat_ext</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">count</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_repeat_ext" inline="true">
                +            <value name="TIMES">
                +              <block type="math_number">
                +                <field name="NUM">10</field>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="math_change" inline="false">
                +                <field name="VAR">count</field>
                +                <value name="DELTA">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">repeat 10</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">count</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">10</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/generators/loops2.xml b/blockly/webif/static/blockly/tests/generators/loops2.xml
                new file mode 100644
                index 000000000..c35623a5d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/loops2.xml
                @@ -0,0 +1,890 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="66" y="-2">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test count"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test count by"></mutation>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="679" y="-10">
                +    <field name="NAME">test count by</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">log</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_for">
                +            <field name="VAR">x</field>
                +            <value name="FROM">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="math_number">
                +                <field name="NUM">8</field>
                +              </block>
                +            </value>
                +            <value name="BY">
                +              <block type="math_number">
                +                <field name="NUM">2</field>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="text_append" inline="false">
                +                <field name="VAR">log</field>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">x</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">count up ints</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">log</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">1357</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">log</field>
                +                    <value name="VALUE">
                +                      <block type="text">
                +                        <field name="TEXT"></field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_for">
                +                        <field name="VAR">x</field>
                +                        <value name="FROM">
                +                          <block type="math_number">
                +                            <field name="NUM">8</field>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                        <value name="BY">
                +                          <block type="math_number">
                +                            <field name="NUM">2</field>
                +                          </block>
                +                        </value>
                +                        <statement name="DO">
                +                          <block type="text_append" inline="false">
                +                            <field name="VAR">log</field>
                +                            <value name="TEXT">
                +                              <block type="variables_get">
                +                                <field name="VAR">x</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </statement>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                               <block type="text">
                +                                 <field name="TEXT">count down ints</field>
                +                               </block>
                +                             </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">log</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">8642</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">loglist</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_empty"></block>
                +                                </value>
                +                                <next>
                +                                  <block type="controls_for">
                +                                    <field name="VAR">x</field>
                +                                    <value name="FROM">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="math_number">
                +                                        <field name="NUM">8</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="BY">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1.5</field>
                +                                      </block>
                +                                    </value>
                +                                    <statement name="DO">
                +                                      <block type="lists_setIndex">
                +                                        <mutation at="false"></mutation>
                +                                        <field name="MODE">INSERT</field>
                +                                        <field name="WHERE">LAST</field>
                +                                        <value name="LIST">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">loglist</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="TO">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">x</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </statement>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                           <block type="text">
                +                                             <field name="TEXT">count with floats</field>
                +                                           </block>
                +                                         </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">loglist</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="false">
                +                                            <mutation items="5"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="math_number">
                +                                                <field name="NUM">1</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="math_number">
                +                                                <field name="NUM">2.5</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD2">
                +                                              <block type="math_number">
                +                                                <field name="NUM">4</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD3">
                +                                              <block type="math_number">
                +                                                <field name="NUM">5.5</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD4">
                +                                              <block type="math_number">
                +                                                <field name="NUM">7</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">loglist</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_empty"></block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="controls_for">
                +                                                <field name="VAR">x</field>
                +                                                <value name="FROM">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">ADD</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">1</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">0</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="TO">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">ADD</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">8</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">0</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="BY">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">MINUS</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">1</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">2</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <statement name="DO">
                +                                                  <block type="lists_setIndex">
                +                                                    <mutation at="false"></mutation>
                +                                                    <field name="MODE">INSERT</field>
                +                                                    <field name="WHERE">LAST</field>
                +                                                    <value name="LIST">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">loglist</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="TO">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">x</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </statement>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                       <block type="text">
                +                                                         <field name="TEXT">count up non-trivial ints</field>
                +                                                       </block>
                +                                                     </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">loglist</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="false">
                +                                                        <mutation items="8"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">1</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">2</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD2">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">3</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD3">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">4</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD4">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">5</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD5">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">6</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD6">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">7</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD7">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">8</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set" inline="false">
                +                                                        <field name="VAR">loglist</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="lists_create_empty"></block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="controls_for">
                +                                                            <field name="VAR">x</field>
                +                                                            <value name="FROM">
                +                                                              <block type="math_arithmetic">
                +                                                                <field name="OP">ADD</field>
                +                                                                <value name="A">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">8</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="B">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">0</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="TO">
                +                                                              <block type="math_arithmetic">
                +                                                                <field name="OP">ADD</field>
                +                                                                <value name="A">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">1</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="B">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">0</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="BY">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">2</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <statement name="DO">
                +                                                              <block type="lists_setIndex">
                +                                                                <mutation at="false"></mutation>
                +                                                                <field name="MODE">INSERT</field>
                +                                                                <field name="WHERE">LAST</field>
                +                                                                <value name="LIST">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">loglist</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="TO">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">x</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </statement>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                   <block type="text">
                +                                                                     <field name="TEXT">count down non-trivial ints</field>
                +                                                                   </block>
                +                                                                 </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">loglist</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="lists_create_with" inline="false">
                +                                                                    <mutation items="4"></mutation>
                +                                                                    <value name="ADD0">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">8</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="ADD1">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">6</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="ADD2">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">4</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="ADD3">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">2</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set" inline="false">
                +                                                                    <field name="VAR">loglist</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="lists_create_empty"></block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="controls_for">
                +                                                                        <field name="VAR">x</field>
                +                                                                        <value name="FROM">
                +                                                                          <block type="math_arithmetic">
                +                                                                            <field name="OP">ADD</field>
                +                                                                            <value name="A">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">5</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="B">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">0.5</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="TO">
                +                                                                          <block type="math_arithmetic">
                +                                                                            <field name="OP">ADD</field>
                +                                                                            <value name="A">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">1</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="B">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">0</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="BY">
                +                                                                          <block type="math_arithmetic">
                +                                                                            <field name="OP">ADD</field>
                +                                                                            <value name="A">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">1</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="B">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">0</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <statement name="DO">
                +                                                                          <block type="lists_setIndex">
                +                                                                            <mutation at="false"></mutation>
                +                                                                            <field name="MODE">INSERT</field>
                +                                                                            <field name="WHERE">LAST</field>
                +                                                                            <value name="LIST">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">loglist</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="TO">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">x</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </statement>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                            <value name="MESSAGE">
                +                                                                               <block type="text">
                +                                                                                 <field name="TEXT">count with floats</field>
                +                                                                               </block>
                +                                                                             </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="variables_get">
                +                                                                                <field name="VAR">loglist</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="EXPECTED">
                +                                                                              <block type="lists_create_with" inline="false">
                +                                                                                <mutation items="5"></mutation>
                +                                                                                <value name="ADD0">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">5.5</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ADD1">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">4.5</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ADD2">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">3.5</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ADD3">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">2.5</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ADD4">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">1.5</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="29" y="184">
                +    <field name="NAME">test count</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">log</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_for">
                +            <field name="VAR">x</field>
                +            <value name="FROM">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="math_number">
                +                <field name="NUM">8</field>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="text_append" inline="false">
                +                <field name="VAR">log</field>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">x</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">count up</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">log</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">12345678</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">log</field>
                +                    <value name="VALUE">
                +                      <block type="text">
                +                        <field name="TEXT"></field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_for">
                +                        <field name="VAR">x</field>
                +                        <value name="FROM">
                +                          <block type="math_number">
                +                            <field name="NUM">8</field>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                        <statement name="DO">
                +                          <block type="text_append" inline="false">
                +                            <field name="VAR">log</field>
                +                            <value name="TEXT">
                +                              <block type="variables_get">
                +                                <field name="VAR">x</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </statement>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                               <block type="text">
                +                                 <field name="TEXT">count down</field>
                +                               </block>
                +                             </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">log</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">87654321</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">loglist</field>
                +                                <value name="VALUE">
                +                                  <block type="lists_create_empty"></block>
                +                                </value>
                +                                <next>
                +                                  <block type="controls_for">
                +                                    <field name="VAR">x</field>
                +                                    <value name="FROM">
                +                                      <block type="math_arithmetic">
                +                                        <field name="OP">ADD</field>
                +                                        <value name="A">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="B">
                +                                          <block type="math_number">
                +                                            <field name="NUM">0</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="math_arithmetic">
                +                                        <field name="OP">ADD</field>
                +                                        <value name="A">
                +                                          <block type="math_number">
                +                                            <field name="NUM">4</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="B">
                +                                          <block type="math_number">
                +                                            <field name="NUM">0</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <statement name="DO">
                +                                      <block type="lists_setIndex">
                +                                        <mutation at="false"></mutation>
                +                                        <field name="MODE">INSERT</field>
                +                                        <field name="WHERE">LAST</field>
                +                                        <value name="LIST">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">loglist</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="TO">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">x</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </statement>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                           <block type="text">
                +                                             <field name="TEXT">count up non-trivial</field>
                +                                           </block>
                +                                         </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">loglist</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="lists_create_with" inline="false">
                +                                            <mutation items="4"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="math_number">
                +                                                <field name="NUM">1</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="math_number">
                +                                                <field name="NUM">2</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD2">
                +                                              <block type="math_number">
                +                                                <field name="NUM">3</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD3">
                +                                              <block type="math_number">
                +                                                <field name="NUM">4</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">loglist</field>
                +                                            <value name="VALUE">
                +                                              <block type="lists_create_empty"></block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="controls_for">
                +                                                <field name="VAR">x</field>
                +                                                <value name="FROM">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">ADD</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">3</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">1</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="TO">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">ADD</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">1</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">0</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <statement name="DO">
                +                                                  <block type="lists_setIndex">
                +                                                    <mutation at="false"></mutation>
                +                                                    <field name="MODE">INSERT</field>
                +                                                    <field name="WHERE">LAST</field>
                +                                                    <value name="LIST">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">loglist</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="TO">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">x</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </statement>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                       <block type="text">
                +                                                         <field name="TEXT">count down non-trivial</field>
                +                                                       </block>
                +                                                     </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">loglist</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="lists_create_with" inline="false">
                +                                                        <mutation items="4"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">4</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">3</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD2">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">2</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD3">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">1</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/generators/loops3.xml b/blockly/webif/static/blockly/tests/generators/loops3.xml
                new file mode 100644
                index 000000000..508b88729
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/loops3.xml
                @@ -0,0 +1,734 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="19" y="106">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test break"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test continue"></mutation>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="300">
                +    <field name="NAME">test continue</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">log</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="variables_set" inline="false">
                +            <field name="VAR">count</field>
                +            <value name="VALUE">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="controls_whileUntil" inline="false">
                +                <field name="MODE">WHILE</field>
                +                <value name="BOOL">
                +                  <block type="logic_compare">
                +                    <field name="OP">NEQ</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">count</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">8</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <statement name="DO">
                +                  <block type="math_change" inline="false">
                +                    <field name="VAR">count</field>
                +                    <value name="DELTA">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_if" inline="false">
                +                        <value name="IF0">
                +                          <block type="logic_compare">
                +                            <field name="OP">EQ</field>
                +                            <value name="A">
                +                              <block type="variables_get">
                +                                <field name="VAR">count</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">5</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <statement name="DO0">
                +                          <block type="controls_flow_statements">
                +                            <field name="FLOW">CONTINUE</field>
                +                          </block>
                +                        </statement>
                +                        <next>
                +                          <block type="text_append" inline="false">
                +                            <field name="VAR">log</field>
                +                            <value name="TEXT">
                +                              <block type="variables_get">
                +                                <field name="VAR">count</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </statement>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                       <block type="text">
                +                         <field name="TEXT">while continue</field>
                +                       </block>
                +                     </value>
                +                    <value name="ACTUAL">
                +                      <block type="variables_get">
                +                        <field name="VAR">log</field>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">1234678</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="variables_set" inline="false">
                +                        <field name="VAR">log</field>
                +                        <value name="VALUE">
                +                          <block type="text">
                +                            <field name="TEXT"></field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="variables_set" inline="false">
                +                            <field name="VAR">count</field>
                +                            <value name="VALUE">
                +                              <block type="math_number">
                +                                <field name="NUM">0</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="controls_whileUntil" inline="false">
                +                                <field name="MODE">UNTIL</field>
                +                                <value name="BOOL">
                +                                  <block type="logic_compare">
                +                                    <field name="OP">EQ</field>
                +                                    <value name="A">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">count</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="B">
                +                                      <block type="math_number">
                +                                        <field name="NUM">8</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <statement name="DO">
                +                                  <block type="math_change" inline="false">
                +                                    <field name="VAR">count</field>
                +                                    <value name="DELTA">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="controls_if" inline="false">
                +                                        <value name="IF0">
                +                                          <block type="logic_compare">
                +                                            <field name="OP">EQ</field>
                +                                            <value name="A">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">count</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">5</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <statement name="DO0">
                +                                          <block type="controls_flow_statements">
                +                                            <field name="FLOW">CONTINUE</field>
                +                                          </block>
                +                                        </statement>
                +                                        <next>
                +                                          <block type="text_append" inline="false">
                +                                            <field name="VAR">log</field>
                +                                            <value name="TEXT">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">count</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </statement>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                       <block type="text">
                +                                         <field name="TEXT">until continue</field>
                +                                       </block>
                +                                     </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">log</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">1234678</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="variables_set" inline="false">
                +                                        <field name="VAR">log</field>
                +                                        <value name="VALUE">
                +                                          <block type="text">
                +                                            <field name="TEXT"></field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="controls_for">
                +                                            <field name="VAR">x</field>
                +                                            <value name="FROM">
                +                                              <block type="math_number">
                +                                                <field name="NUM">1</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="TO">
                +                                              <block type="math_number">
                +                                                <field name="NUM">8</field>
                +                                              </block>
                +                                            </value>
                +                                            <statement name="DO">
                +                                              <block type="controls_if" inline="false">
                +                                                <value name="IF0">
                +                                                  <block type="logic_compare">
                +                                                    <field name="OP">EQ</field>
                +                                                    <value name="A">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">x</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">5</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <statement name="DO0">
                +                                                  <block type="controls_flow_statements">
                +                                                    <field name="FLOW">CONTINUE</field>
                +                                                  </block>
                +                                                </statement>
                +                                                <next>
                +                                                  <block type="text_append" inline="false">
                +                                                    <field name="VAR">log</field>
                +                                                    <value name="TEXT">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">x</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </statement>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                   <block type="text">
                +                                                     <field name="TEXT">count continue</field>
                +                                                   </block>
                +                                                 </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="variables_get">
                +                                                    <field name="VAR">log</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">1234678</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="variables_set" inline="false">
                +                                                    <field name="VAR">log</field>
                +                                                    <value name="VALUE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT"></field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="controls_forEach" inline="false">
                +                                                        <field name="VAR">x</field>
                +                                                        <value name="LIST">
                +                                                          <block type="lists_create_with" inline="false">
                +                                                            <mutation items="4"></mutation>
                +                                                            <value name="ADD0">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">a</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD1">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">b</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD2">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">c</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ADD3">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">d</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <statement name="DO">
                +                                                          <block type="controls_if" inline="false">
                +                                                            <value name="IF0">
                +                                                              <block type="logic_compare">
                +                                                                <field name="OP">EQ</field>
                +                                                                <value name="A">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">x</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="B">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">c</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <statement name="DO0">
                +                                                              <block type="controls_flow_statements">
                +                                                                <field name="FLOW">CONTINUE</field>
                +                                                              </block>
                +                                                            </statement>
                +                                                            <next>
                +                                                              <block type="text_append" inline="false">
                +                                                                <field name="VAR">log</field>
                +                                                                <value name="TEXT">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">x</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </statement>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                               <block type="text">
                +                                                                 <field name="TEXT">for continue</field>
                +                                                               </block>
                +                                                             </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">log</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">abd</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="600" y="300">
                +    <field name="NAME">test break</field>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">count</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="controls_whileUntil" inline="false">
                +            <field name="MODE">WHILE</field>
                +            <value name="BOOL">
                +              <block type="logic_compare">
                +                <field name="OP">NEQ</field>
                +                <value name="A">
                +                  <block type="variables_get">
                +                    <field name="VAR">count</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="math_number">
                +                    <field name="NUM">10</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <statement name="DO">
                +              <block type="controls_if" inline="false">
                +                <value name="IF0">
                +                  <block type="logic_compare">
                +                    <field name="OP">EQ</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">count</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">5</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <statement name="DO0">
                +                  <block type="controls_flow_statements">
                +                    <field name="FLOW">BREAK</field>
                +                  </block>
                +                </statement>
                +                <next>
                +                  <block type="math_change" inline="false">
                +                    <field name="VAR">count</field>
                +                    <value name="DELTA">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </statement>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                   <block type="text">
                +                     <field name="TEXT">while break</field>
                +                   </block>
                +                 </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">count</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">5</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">count</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="controls_whileUntil" inline="false">
                +                        <field name="MODE">UNTIL</field>
                +                        <value name="BOOL">
                +                          <block type="logic_compare">
                +                            <field name="OP">EQ</field>
                +                            <value name="A">
                +                              <block type="variables_get">
                +                                <field name="VAR">count</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">10</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <statement name="DO">
                +                          <block type="controls_if" inline="false">
                +                            <value name="IF0">
                +                              <block type="logic_compare">
                +                                <field name="OP">EQ</field>
                +                                <value name="A">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">count</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="math_number">
                +                                    <field name="NUM">5</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <statement name="DO0">
                +                              <block type="controls_flow_statements">
                +                                <field name="FLOW">BREAK</field>
                +                              </block>
                +                            </statement>
                +                            <next>
                +                              <block type="math_change" inline="false">
                +                                <field name="VAR">count</field>
                +                                <value name="DELTA">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </statement>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                               <block type="text">
                +                                 <field name="TEXT">until break</field>
                +                               </block>
                +                             </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">count</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="math_number">
                +                                <field name="NUM">5</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">log</field>
                +                                <value name="VALUE">
                +                                  <block type="text">
                +                                    <field name="TEXT"></field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="controls_for">
                +                                    <field name="VAR">x</field>
                +                                    <value name="FROM">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="math_number">
                +                                        <field name="NUM">8</field>
                +                                      </block>
                +                                    </value>
                +                                    <statement name="DO">
                +                                      <block type="controls_if" inline="false">
                +                                        <value name="IF0">
                +                                          <block type="logic_compare">
                +                                            <field name="OP">EQ</field>
                +                                            <value name="A">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">x</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">5</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <statement name="DO0">
                +                                          <block type="controls_flow_statements">
                +                                            <field name="FLOW">BREAK</field>
                +                                          </block>
                +                                        </statement>
                +                                        <next>
                +                                          <block type="text_append" inline="false">
                +                                            <field name="VAR">log</field>
                +                                            <value name="TEXT">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">x</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </statement>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                           <block type="text">
                +                                             <field name="TEXT">count break</field>
                +                                           </block>
                +                                         </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">log</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">1234</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set" inline="false">
                +                                            <field name="VAR">log</field>
                +                                            <value name="VALUE">
                +                                              <block type="text">
                +                                                <field name="TEXT"></field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="controls_forEach" inline="false">
                +                                                <field name="VAR">x</field>
                +                                                <value name="LIST">
                +                                                  <block type="lists_create_with" inline="false">
                +                                                    <mutation items="4"></mutation>
                +                                                    <value name="ADD0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">a</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD1">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">b</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD2">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">c</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD3">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">d</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <statement name="DO">
                +                                                  <block type="controls_if" inline="false">
                +                                                    <value name="IF0">
                +                                                      <block type="logic_compare">
                +                                                        <field name="OP">EQ</field>
                +                                                        <value name="A">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">x</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">c</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <statement name="DO0">
                +                                                      <block type="controls_flow_statements">
                +                                                        <field name="FLOW">BREAK</field>
                +                                                      </block>
                +                                                    </statement>
                +                                                    <next>
                +                                                      <block type="text_append" inline="false">
                +                                                        <field name="VAR">log</field>
                +                                                        <value name="TEXT">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">x</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </statement>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                       <block type="text">
                +                                                         <field name="TEXT">for break</field>
                +                                                       </block>
                +                                                     </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">log</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">ab</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/generators/math.xml b/blockly/webif/static/blockly/tests/generators/math.xml
                new file mode 100644
                index 000000000..9c1f644f8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/math.xml
                @@ -0,0 +1,1884 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="13" y="13">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test arithmetic"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test single"></mutation>
                +            <next>
                +              <block type="procedures_callnoreturn">
                +                <mutation name="test trig"></mutation>
                +                <next>
                +                  <block type="procedures_callnoreturn">
                +                    <mutation name="test constant"></mutation>
                +                    <next>
                +                      <block type="procedures_callnoreturn">
                +                        <mutation name="test change"></mutation>
                +                        <next>
                +                          <block type="procedures_callnoreturn">
                +                            <mutation name="test number properties"></mutation>
                +                            <next>
                +                              <block type="procedures_callnoreturn">
                +                                <mutation name="test round"></mutation>
                +                                <next>
                +                                  <block type="procedures_callnoreturn">
                +                                    <mutation name="test operations on list"></mutation>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn">
                +                                        <mutation name="test constraint"></mutation>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn">
                +                                            <mutation name="test mod"></mutation>
                +                                            <next>
                +                                              <block type="procedures_callnoreturn">
                +                                                <mutation name="test random integer"></mutation>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn">
                +                                                    <mutation name="test random fraction"></mutation>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="388">
                +    <field name="NAME">test single</field>
                +    <comment pinned="false" h="80" w="160">Tests the "single" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">sqrt</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_single" inline="false">
                +            <field name="OP">ROOT</field>
                +            <value name="NUM">
                +              <block type="math_number">
                +                <field name="NUM">25</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">5</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">abs</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_single" inline="false">
                +                <field name="OP">ABS</field>
                +                <value name="NUM">
                +                  <block type="math_number">
                +                    <field name="NUM">-25</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">25</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">negate</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_single" inline="false">
                +                    <field name="OP">NEG</field>
                +                    <value name="NUM">
                +                      <block type="math_number">
                +                        <field name="NUM">-25</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">25</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">ln</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_single" inline="false">
                +                        <field name="OP">LN</field>
                +                        <value name="NUM">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">log10</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_single" inline="false">
                +                            <field name="OP">LOG10</field>
                +                            <value name="NUM">
                +                              <block type="math_number">
                +                                <field name="NUM">100</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">2</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">exp</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="math_single" inline="false">
                +                                <field name="OP">EXP</field>
                +                                <value name="NUM">
                +                                  <block type="math_number">
                +                                    <field name="NUM">2</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="math_number">
                +                                <field name="NUM">7.38905609893065</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">power10</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="math_single" inline="false">
                +                                    <field name="OP">POW10</field>
                +                                    <value name="NUM">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="math_number">
                +                                    <field name="NUM">100</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1013">
                +    <field name="NAME">test arithmetic</field>
                +    <comment pinned="false" h="80" w="272">Tests the "arithmetic" block for all operations and checks parenthesis are properly generated for different orders.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">add</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_arithmetic">
                +            <field name="OP">ADD</field>
                +            <value name="A">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +            <value name="B">
                +              <block type="math_number">
                +                <field name="NUM">2</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">3</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">subtract</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_arithmetic">
                +                <field name="OP">MINUS</field>
                +                <value name="A">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="math_number">
                +                    <field name="NUM">2</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">-1</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">subtract order with add</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_arithmetic">
                +                    <field name="OP">MINUS</field>
                +                    <value name="A">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_arithmetic">
                +                        <field name="OP">ADD</field>
                +                        <value name="A">
                +                          <block type="math_number">
                +                            <field name="NUM">0</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">2</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">-1</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">subtract order with subtract</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_arithmetic">
                +                        <field name="OP">MINUS</field>
                +                        <value name="A">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_arithmetic">
                +                            <field name="OP">MINUS</field>
                +                            <value name="A">
                +                              <block type="math_number">
                +                                <field name="NUM">0</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">multiply</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_arithmetic">
                +                            <field name="OP">MULTIPLY</field>
                +                            <value name="A">
                +                              <block type="math_number">
                +                                <field name="NUM">4</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">2.5</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">10</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">multiply order</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">MULTIPLY</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">4</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="math_arithmetic">
                +                                    <field name="OP">ADD</field>
                +                                    <value name="A">
                +                                      <block type="math_number">
                +                                        <field name="NUM">0</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="B">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2.5</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="math_number">
                +                                <field name="NUM">10</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">divide</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="math_arithmetic">
                +                                    <field name="OP">DIVIDE</field>
                +                                    <value name="A">
                +                                      <block type="math_number">
                +                                        <field name="NUM">8.2</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="B">
                +                                      <block type="math_number">
                +                                        <field name="NUM">-5</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="math_number">
                +                                    <field name="NUM">-1.64</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">divide order</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="math_arithmetic">
                +                                        <field name="OP">DIVIDE</field>
                +                                        <value name="A">
                +                                          <block type="math_number">
                +                                            <field name="NUM">8.2</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="B">
                +                                          <block type="math_arithmetic">
                +                                            <field name="OP">ADD</field>
                +                                            <value name="A">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">-5</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="math_number">
                +                                        <field name="NUM">-1.64</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">power</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="math_arithmetic">
                +                                            <field name="OP">POWER</field>
                +                                            <value name="A">
                +                                              <block type="math_number">
                +                                                <field name="NUM">10</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">4</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="math_number">
                +                                            <field name="NUM">10000</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="unittest_assertequals" inline="false">
                +                                            <value name="MESSAGE">
                +                                              <block type="text">
                +                                                <field name="TEXT">power order</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ACTUAL">
                +                                              <block type="math_arithmetic">
                +                                                <field name="OP">POWER</field>
                +                                                <value name="A">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">10</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="B">
                +                                                  <block type="math_arithmetic">
                +                                                    <field name="OP">ADD</field>
                +                                                    <value name="A">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">0</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="B">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">4</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <value name="EXPECTED">
                +                                              <block type="math_number">
                +                                                <field name="NUM">10000</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="2013">
                +    <field name="NAME">test trig</field>
                +    <comment pinned="false" h="80" w="160">Tests the "trig" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">sin</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_trig" inline="false">
                +            <field name="OP">SIN</field>
                +            <value name="NUM">
                +              <block type="math_number">
                +                <field name="NUM">90</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">cos</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_trig" inline="false">
                +                <field name="OP">COS</field>
                +                <value name="NUM">
                +                  <block type="math_number">
                +                    <field name="NUM">180</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">-1</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">tan</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_trig" inline="false">
                +                    <field name="OP">TAN</field>
                +                    <value name="NUM">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">0</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">asin</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_trig" inline="false">
                +                        <field name="OP">ASIN</field>
                +                        <value name="NUM">
                +                          <block type="math_number">
                +                            <field name="NUM">-1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">-90</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">acos</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_trig" inline="false">
                +                            <field name="OP">ACOS</field>
                +                            <value name="NUM">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">0</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">atan</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="math_trig" inline="false">
                +                                <field name="OP">ATAN</field>
                +                                <value name="NUM">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="math_number">
                +                                <field name="NUM">45</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="2538">
                +    <field name="NAME">test constant</field>
                +    <comment pinned="false" h="80" w="160">Tests the "constant" blocks.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">const pi</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_round" inline="false">
                +            <field name="OP">ROUNDDOWN</field>
                +            <value name="NUM">
                +              <block type="math_arithmetic">
                +                <field name="OP">MULTIPLY</field>
                +                <value name="A">
                +                  <block type="math_constant">
                +                    <field name="CONSTANT">PI</field>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="math_number">
                +                    <field name="NUM">1000</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">3141</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">const e</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_round" inline="false">
                +                <field name="OP">ROUNDDOWN</field>
                +                <value name="NUM">
                +                  <block type="math_arithmetic">
                +                    <field name="OP">MULTIPLY</field>
                +                    <value name="A">
                +                      <block type="math_constant">
                +                        <field name="CONSTANT">E</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">1000</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">2718</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">const golden</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_round" inline="false">
                +                    <field name="OP">ROUNDDOWN</field>
                +                    <value name="NUM">
                +                      <block type="math_arithmetic">
                +                        <field name="OP">MULTIPLY</field>
                +                        <value name="A">
                +                          <block type="math_constant">
                +                            <field name="CONSTANT">GOLDEN_RATIO</field>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="math_number">
                +                            <field name="NUM">1000</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">1618</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">const sqrt 2</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_round" inline="false">
                +                        <field name="OP">ROUNDDOWN</field>
                +                        <value name="NUM">
                +                          <block type="math_arithmetic">
                +                            <field name="OP">MULTIPLY</field>
                +                            <value name="A">
                +                              <block type="math_constant">
                +                                <field name="CONSTANT">SQRT2</field>
                +                              </block>
                +                            </value>
                +                            <value name="B">
                +                              <block type="math_number">
                +                                <field name="NUM">1000</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">1414</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">const sqrt 0.5</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_round" inline="false">
                +                            <field name="OP">ROUNDDOWN</field>
                +                            <value name="NUM">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">MULTIPLY</field>
                +                                <value name="A">
                +                                  <block type="math_constant">
                +                                    <field name="CONSTANT">SQRT1_2</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1000</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">707</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertvalue" inline="false">
                +                            <field name="EXPECTED">TRUE</field>
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">const infinity</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="logic_compare">
                +                                <field name="OP">LT</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">9999</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="math_constant">
                +                                    <field name="CONSTANT">INFINITY</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="3113">
                +    <field name="NAME">test number properties</field>
                +    <comment pinned="false" h="80" w="160">Tests the "number property" blocks.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">TRUE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">even</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_number_property">
                +            <mutation divisor_input="false"></mutation>
                +            <field name="PROPERTY">EVEN</field>
                +            <value name="NUMBER_TO_CHECK">
                +              <block type="math_number">
                +                <field name="NUM">42</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">FALSE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">odd</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_number_property">
                +                <mutation divisor_input="false"></mutation>
                +                <field name="PROPERTY">ODD</field>
                +                <value name="NUMBER_TO_CHECK">
                +                  <block type="math_number">
                +                    <field name="NUM">42.1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">prime 5</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_number_property">
                +                    <mutation divisor_input="false"></mutation>
                +                    <field name="PROPERTY">PRIME</field>
                +                    <value name="NUMBER_TO_CHECK">
                +                      <block type="math_number">
                +                        <field name="NUM">5</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">FALSE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">prime 25</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_number_property">
                +                        <mutation divisor_input="false"></mutation>
                +                        <field name="PROPERTY">PRIME</field>
                +                        <value name="NUMBER_TO_CHECK">
                +                          <block type="math_number">
                +                            <field name="NUM">25</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertvalue" inline="false">
                +                        <field name="EXPECTED">FALSE</field>
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">prime negative</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_number_property">
                +                            <mutation divisor_input="false"></mutation>
                +                            <field name="PROPERTY">PRIME</field>
                +                            <value name="NUMBER_TO_CHECK">
                +                              <block type="math_number">
                +                                <field name="NUM">-31.1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertvalue" inline="false">
                +                            <field name="EXPECTED">FALSE</field>
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">whole</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="math_number_property">
                +                                <mutation divisor_input="false"></mutation>
                +                                <field name="PROPERTY">WHOLE</field>
                +                                <value name="NUMBER_TO_CHECK">
                +                                  <block type="math_constant">
                +                                    <field name="CONSTANT">PI</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertvalue" inline="false">
                +                                <field name="EXPECTED">TRUE</field>
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">positive</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="math_number_property">
                +                                    <mutation divisor_input="false"></mutation>
                +                                    <field name="PROPERTY">POSITIVE</field>
                +                                    <value name="NUMBER_TO_CHECK">
                +                                      <block type="math_constant">
                +                                        <field name="CONSTANT">INFINITY</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertvalue" inline="false">
                +                                    <field name="EXPECTED">TRUE</field>
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">negative</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="math_number_property">
                +                                        <mutation divisor_input="false"></mutation>
                +                                        <field name="PROPERTY">NEGATIVE</field>
                +                                        <value name="NUMBER_TO_CHECK">
                +                                          <block type="math_number">
                +                                            <field name="NUM">-42</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertvalue" inline="false">
                +                                        <field name="EXPECTED">TRUE</field>
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">divisible</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="math_number_property">
                +                                            <mutation divisor_input="true"></mutation>
                +                                            <field name="PROPERTY">DIVISIBLE_BY</field>
                +                                            <value name="NUMBER_TO_CHECK">
                +                                              <block type="math_number">
                +                                                <field name="NUM">42</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="DIVISOR">
                +                                              <block type="math_number">
                +                                                <field name="NUM">2</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="3738">
                +    <field name="NAME">test round</field>
                +    <comment pinned="false" h="80" w="160">Tests the "round" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">round</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_round" inline="false">
                +            <field name="OP">ROUND</field>
                +            <value name="NUM">
                +              <block type="math_number">
                +                <field name="NUM">42.42</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">42</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">round up</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_round" inline="false">
                +                <field name="OP">ROUNDUP</field>
                +                <value name="NUM">
                +                  <block type="math_number">
                +                    <field name="NUM">-42.42</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">-42</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">round down</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_round" inline="false">
                +                    <field name="OP">ROUNDDOWN</field>
                +                    <value name="NUM">
                +                      <block type="math_number">
                +                        <field name="NUM">42.42</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">42</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="4038">
                +    <field name="NAME">test change</field>
                +    <comment pinned="false" h="80" w="160">Tests the "change" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">varToChange</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="math_change" inline="false">
                +            <field name="VAR">varToChange</field>
                +            <value name="DELTA">
                +              <block type="math_number">
                +                <field name="NUM">42</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">change</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">varToChange</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">142</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="4238">
                +    <field name="NAME">test operations on list</field>
                +    <comment pinned="false" h="80" w="160">Tests the "list operation" blocks.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">sum</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_on_list" inline="false">
                +            <mutation op="SUM"></mutation>
                +            <field name="OP">SUM</field>
                +            <value name="LIST">
                +              <block type="lists_create_with" inline="true">
                +                <mutation items="3"></mutation>
                +                <value name="ADD0">
                +                  <block type="math_number">
                +                    <field name="NUM">3</field>
                +                  </block>
                +                </value>
                +                <value name="ADD1">
                +                  <block type="math_number">
                +                    <field name="NUM">4</field>
                +                  </block>
                +                </value>
                +                <value name="ADD2">
                +                  <block type="math_number">
                +                    <field name="NUM">5</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">12</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">min</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="math_on_list" inline="false">
                +                <mutation op="MIN"></mutation>
                +                <field name="OP">MIN</field>
                +                <value name="LIST">
                +                  <block type="lists_create_with" inline="true">
                +                    <mutation items="3"></mutation>
                +                    <value name="ADD0">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD1">
                +                      <block type="math_number">
                +                        <field name="NUM">4</field>
                +                      </block>
                +                    </value>
                +                    <value name="ADD2">
                +                      <block type="math_number">
                +                        <field name="NUM">5</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">3</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">max</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_on_list" inline="false">
                +                    <mutation op="MAX"></mutation>
                +                    <field name="OP">MAX</field>
                +                    <value name="LIST">
                +                      <block type="lists_create_with" inline="true">
                +                        <mutation items="3"></mutation>
                +                        <value name="ADD0">
                +                          <block type="math_number">
                +                            <field name="NUM">3</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="math_number">
                +                            <field name="NUM">4</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD2">
                +                          <block type="math_number">
                +                            <field name="NUM">5</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">5</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">average</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="math_on_list" inline="false">
                +                        <mutation op="AVERAGE"></mutation>
                +                        <field name="OP">AVERAGE</field>
                +                        <value name="LIST">
                +                          <block type="lists_create_with" inline="true">
                +                            <mutation items="3"></mutation>
                +                            <value name="ADD0">
                +                              <block type="math_number">
                +                                <field name="NUM">3</field>
                +                              </block>
                +                            </value>
                +                            <value name="ADD1">
                +                              <block type="math_number">
                +                                <field name="NUM">4</field>
                +                              </block>
                +                            </value>
                +                            <value name="ADD2">
                +                              <block type="math_number">
                +                                <field name="NUM">5</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">4</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">median</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="math_on_list" inline="false">
                +                            <mutation op="MEDIAN"></mutation>
                +                            <field name="OP">MEDIAN</field>
                +                            <value name="LIST">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="4"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="math_number">
                +                                    <field name="NUM">3</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="math_number">
                +                                    <field name="NUM">4</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD2">
                +                                  <block type="math_number">
                +                                    <field name="NUM">5</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD3">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">3.5</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">modes</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="math_on_list" inline="false">
                +                                <mutation op="MODE"></mutation>
                +                                <field name="OP">MODE</field>
                +                                <value name="LIST">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="math_number">
                +                                        <field name="NUM">3</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="math_number">
                +                                        <field name="NUM">4</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="math_number">
                +                                        <field name="NUM">3</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="lists_create_with" inline="true">
                +                                <mutation items="1"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="math_number">
                +                                    <field name="NUM">3</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">modes multiple</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="math_on_list" inline="false">
                +                                    <mutation op="MODE"></mutation>
                +                                    <field name="OP">MODE</field>
                +                                    <value name="LIST">
                +                                      <block type="lists_create_with" inline="true">
                +                                        <mutation items="5"></mutation>
                +                                        <value name="ADD0">
                +                                          <block type="math_number">
                +                                            <field name="NUM">3</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ADD1">
                +                                          <block type="math_number">
                +                                            <field name="NUM">4</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ADD2">
                +                                          <block type="math_number">
                +                                            <field name="NUM">3</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ADD3">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ADD4">
                +                                          <block type="math_number">
                +                                            <field name="NUM">4</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="lists_create_with" inline="true">
                +                                    <mutation items="2"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="math_number">
                +                                        <field name="NUM">3</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="math_number">
                +                                        <field name="NUM">4</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">standard dev</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="math_on_list" inline="false">
                +                                        <mutation op="STD_DEV"></mutation>
                +                                        <field name="OP">STD_DEV</field>
                +                                        <value name="LIST">
                +                                          <block type="lists_create_with" inline="true">
                +                                            <mutation items="3"></mutation>
                +                                            <value name="ADD0">
                +                                              <block type="math_number">
                +                                                <field name="NUM">3</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD1">
                +                                              <block type="math_number">
                +                                                <field name="NUM">3</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ADD2">
                +                                              <block type="math_number">
                +                                                <field name="NUM">3</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="math_number">
                +                                        <field name="NUM">0</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertvalue" inline="false">
                +                                        <field name="EXPECTED">TRUE</field>
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">random</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="logic_compare" inline="false">
                +                                            <field name="OP">GT</field>
                +                                            <value name="A">
                +                                              <block type="lists_indexOf" inline="false">
                +                                                <field name="END">FIRST</field>
                +                                                <value name="VALUE">
                +                                                  <block type="lists_create_with" inline="true">
                +                                                    <mutation items="3"></mutation>
                +                                                    <value name="ADD0">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">3</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD1">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">4</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ADD2">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">5</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="FIND">
                +                                                  <block type="math_on_list" inline="false">
                +                                                    <mutation op="RANDOM"></mutation>
                +                                                    <field name="OP">RANDOM</field>
                +                                                    <value name="LIST">
                +                                                      <block type="lists_create_with" inline="false">
                +                                                        <mutation items="3"></mutation>
                +                                                        <value name="ADD0">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">3</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD1">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">4</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ADD2">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">5</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="5213">
                +    <field name="NAME">test mod</field>
                +    <comment pinned="false" h="80" w="160">Tests the "mod" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">mod</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_modulo">
                +            <value name="DIVIDEND">
                +              <block type="math_number">
                +                <field name="NUM">42</field>
                +              </block>
                +            </value>
                +            <value name="DIVISOR">
                +              <block type="math_number">
                +                <field name="NUM">5</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">2</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="5363">
                +    <field name="NAME">test constraint</field>
                +    <comment pinned="false" h="80" w="160">Tests the "constrain" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">constraint</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="math_constrain">
                +            <value name="VALUE">
                +              <block type="math_number">
                +                <field name="NUM">100</field>
                +              </block>
                +            </value>
                +            <value name="LOW">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +            <value name="HIGH">
                +              <block type="math_number">
                +                <field name="NUM">42</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">42</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="5513">
                +    <field name="NAME">test random integer</field>
                +    <comment pinned="false" h="80" w="160">Tests the "random integer" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">rand</field>
                +        <value name="VALUE">
                +          <block type="math_random_int">
                +            <value name="FROM">
                +              <block type="math_number">
                +                <field name="NUM">5</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="math_number">
                +                <field name="NUM">10</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">TRUE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">randRange</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_operation">
                +                <field name="OP">AND</field>
                +                <value name="A">
                +                  <block type="logic_compare">
                +                    <field name="OP">GTE</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">rand</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">5</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="logic_compare">
                +                    <field name="OP">LTE</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">rand</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">10</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">randInteger</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="math_number_property">
                +                    <mutation divisor_input="false"></mutation>
                +                    <field name="PROPERTY">WHOLE</field>
                +                    <value name="NUMBER_TO_CHECK">
                +                      <block type="variables_get">
                +                        <field name="VAR">rand</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="5763">
                +    <field name="NAME">test random fraction</field>
                +    <comment pinned="false" h="80" w="160">Tests the "random fraction" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">rand</field>
                +        <value name="VALUE">
                +          <block type="math_random_float"></block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">TRUE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">randFloat</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="logic_operation">
                +                <field name="OP">AND</field>
                +                <value name="A">
                +                  <block type="logic_compare">
                +                    <field name="OP">GTE</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">rand</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="B">
                +                  <block type="logic_compare">
                +                    <field name="OP">LTE</field>
                +                    <value name="A">
                +                      <block type="variables_get">
                +                        <field name="VAR">rand</field>
                +                      </block>
                +                    </value>
                +                    <value name="B">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/generators/text.xml b/blockly/webif/static/blockly/tests/generators/text.xml
                new file mode 100644
                index 000000000..32887ec93
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/text.xml
                @@ -0,0 +1,4650 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="13" y="-63">
                +    <statement name="DO">
                +      <block type="procedures_callnoreturn">
                +        <mutation name="test length"></mutation>
                +        <next>
                +          <block type="procedures_callnoreturn">
                +            <mutation name="test empty"></mutation>
                +            <next>
                +              <block type="procedures_callnoreturn">
                +                <mutation name="test create"></mutation>
                +                <next>
                +                  <block type="procedures_callnoreturn">
                +                    <mutation name="test append"></mutation>
                +                    <next>
                +                      <block type="procedures_callnoreturn">
                +                        <mutation name="test find simple"></mutation>
                +                        <next>
                +                          <block type="procedures_callnoreturn">
                +                            <mutation name="test find complex"></mutation>
                +                            <next>
                +                              <block type="procedures_callnoreturn">
                +                                <mutation name="test get simple"></mutation>
                +                                <next>
                +                                  <block type="procedures_callnoreturn">
                +                                    <mutation name="test get complex"></mutation>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn">
                +                                        <mutation name="test substring simple"></mutation>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn">
                +                                            <mutation name="test substring complex"></mutation>
                +                                            <next>
                +                                              <block type="procedures_callnoreturn">
                +                                                <mutation name="test case"></mutation>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn">
                +                                                    <mutation name="test trim"></mutation>
                +                                                    <next>
                +                                                      <block type="procedures_callnoreturn">
                +                                                        <mutation name="test count"></mutation>
                +                                                        <next>
                +                                                          <block type="procedures_callnoreturn">
                +                                                            <mutation name="test reverse"></mutation>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn">
                +                                                                <mutation name="test replace"></mutation>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="388">
                +    <mutation>
                +      <arg name="test name"></arg>
                +    </mutation>
                +    <field name="NAME">check number of calls</field>
                +    <comment pinned="false" h="69" w="256">Checks that the number of calls is one in order to confirm that a function was only called once.</comment>
                +    <statement name="STACK">
                +      <block type="text_append">
                +        <field name="VAR">test name</field>
                +        <value name="TEXT">
                +          <block type="text">
                +            <field name="TEXT">number of calls</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals">
                +            <value name="MESSAGE">
                +              <block type="variables_get">
                +                <field name="VAR">test name</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="variables_get">
                +                <field name="VAR">number of calls</field>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">1</field>
                +              </block>
                +            </value>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="563">
                +    <field name="NAME">test create</field>
                +    <comment pinned="false" h="80" w="160">Tests the "create text with" block with varying number of inputs.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">no text</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="text_join" inline="false">
                +            <mutation items="0"></mutation>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">create single</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_join" inline="false">
                +                <mutation items="1"></mutation>
                +                <value name="ADD0">
                +                  <block type="text">
                +                    <field name="TEXT">Hello</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">Hello</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">create single number</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_join" inline="false">
                +                    <mutation items="1"></mutation>
                +                    <value name="ADD0">
                +                      <block type="math_number">
                +                        <field name="NUM">-1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">-1</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">create double text</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_join" inline="true">
                +                        <mutation items="2"></mutation>
                +                        <value name="ADD0">
                +                          <block type="text">
                +                            <field name="TEXT">K</field>
                +                          </block>
                +                        </value>
                +                        <value name="ADD1">
                +                          <block type="math_number">
                +                            <field name="NUM">9</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">K9</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">create double text numbers</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_join" inline="true">
                +                            <mutation items="2"></mutation>
                +                            <value name="ADD0">
                +                              <block type="math_number">
                +                                <field name="NUM">4</field>
                +                              </block>
                +                            </value>
                +                            <value name="ADD1">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">42</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">create triple</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_join" inline="true">
                +                                <mutation items="3"></mutation>
                +                                <value name="ADD0">
                +                                  <block type="math_number">
                +                                    <field name="NUM">1</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD1">
                +                                  <block type="math_number">
                +                                    <field name="NUM">2</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ADD2">
                +                                  <block type="math_number">
                +                                    <field name="NUM">3</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">123</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">create order</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_join" inline="false">
                +                                    <mutation items="3"></mutation>
                +                                    <value name="ADD0">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD1">
                +                                      <block type="logic_ternary" inline="true">
                +                                        <value name="IF">
                +                                          <block type="logic_boolean">
                +                                            <field name="BOOL">TRUE</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="THEN">
                +                                          <block type="math_number">
                +                                            <field name="NUM">0</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ELSE">
                +                                          <block type="logic_null"></block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ADD2">
                +                                      <block type="text">
                +                                        <field name="TEXT">M</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT">10M</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="1263">
                +    <mutation statements="false"></mutation>
                +    <field name="NAME">get empty</field>
                +    <comment pinned="false" h="80" w="160">Creates an empty string for use with the empty test.</comment>
                +    <value name="RETURN">
                +      <block type="text">
                +        <field name="TEXT"></field>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1338">
                +    <field name="NAME">test empty</field>
                +    <comment pinned="false" h="80" w="160">Tests the "is empty" block".</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertvalue" inline="false">
                +        <field name="EXPECTED">FALSE</field>
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">not empty</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="text_isEmpty" inline="true">
                +            <value name="VALUE">
                +              <block type="text">
                +                <field name="TEXT">Google</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertvalue" inline="false">
                +            <field name="EXPECTED">TRUE</field>
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">empty</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_isEmpty" inline="true">
                +                <value name="VALUE">
                +                  <block type="text">
                +                    <field name="TEXT"></field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertvalue" inline="false">
                +                <field name="EXPECTED">TRUE</field>
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">empty complex</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_isEmpty" inline="true">
                +                    <value name="VALUE">
                +                      <block type="procedures_callreturn">
                +                        <mutation name="get empty"></mutation>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">TRUE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">empty order</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_isEmpty" inline="true">
                +                        <value name="VALUE">
                +                          <block type="logic_ternary" inline="true">
                +                            <value name="IF">
                +                              <block type="logic_boolean">
                +                                <field name="BOOL">TRUE</field>
                +                              </block>
                +                            </value>
                +                            <value name="THEN">
                +                              <block type="text">
                +                                <field name="TEXT"></field>
                +                              </block>
                +                            </value>
                +                            <value name="ELSE">
                +                              <block type="logic_null"></block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1663">
                +    <field name="NAME">test length</field>
                +    <comment pinned="false" h="80" w="160">Tests the "length" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">zero length</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="text_length" inline="false">
                +            <value name="VALUE">
                +              <block type="text">
                +                <field name="TEXT"></field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">non-zero length</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_length" inline="false">
                +                <value name="VALUE">
                +                  <block type="text">
                +                    <field name="TEXT">Google</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">6</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">length order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_length" inline="false">
                +                    <value name="VALUE">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="text">
                +                            <field name="TEXT">car</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">3</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="1963">
                +    <field name="NAME">test append</field>
                +    <comment pinned="false" h="80" w="160">Tests the "append text" block with different types of parameters.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">item</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Miserable</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="text_append" inline="false">
                +            <field name="VAR">item</field>
                +            <value name="TEXT">
                +              <block type="text">
                +                <field name="TEXT">Failure</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">append text</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="variables_get">
                +                    <field name="VAR">item</field>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">MiserableFailure</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set" inline="false">
                +                    <field name="VAR">item</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">12</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="text_append" inline="false">
                +                        <field name="VAR">item</field>
                +                        <value name="TEXT">
                +                          <block type="math_number">
                +                            <field name="NUM">34</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">append number</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="variables_get">
                +                                <field name="VAR">item</field>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">1234</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set" inline="false">
                +                                <field name="VAR">item</field>
                +                                <value name="VALUE">
                +                                  <block type="text">
                +                                    <field name="TEXT">Something </field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="text_append" inline="false">
                +                                    <field name="VAR">item</field>
                +                                    <value name="TEXT">
                +                                      <block type="logic_ternary" inline="true">
                +                                        <value name="IF">
                +                                          <block type="logic_boolean">
                +                                            <field name="BOOL">TRUE</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="THEN">
                +                                          <block type="text">
                +                                            <field name="TEXT">Positive</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ELSE">
                +                                          <block type="logic_null"></block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">append order</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">item</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">Something Positive</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="2438">
                +    <field name="NAME">test find simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "find" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Banana</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">find first simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_indexOf">
                +                <field name="END">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +                <value name="FIND">
                +                  <block type="text">
                +                    <field name="TEXT">an</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="unittest_adjustindex">
                +                <value name="INDEX">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">find last simple</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_indexOf">
                +                    <field name="END">LAST</field>
                +                    <value name="VALUE">
                +                      <block type="variables_get">
                +                        <field name="VAR">text</field>
                +                      </block>
                +                    </value>
                +                    <value name="FIND">
                +                      <block type="text">
                +                        <field name="TEXT">an</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">3</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">find none simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_indexOf">
                +                        <field name="END">FIRST</field>
                +                        <value name="VALUE">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                        <value name="FIND">
                +                          <block type="text">
                +                            <field name="TEXT">Peel</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="unittest_adjustindex">
                +                        <value name="INDEX">
                +                          <block type="math_number">
                +                            <field name="NUM">-1</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="2838">
                +    <field name="NAME">get fruit</field>
                +    <comment pinned="false" h="80" w="160">Creates a string for use with the find test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="text">
                +        <field name="TEXT">Banana</field>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="2938">
                +    <field name="NAME">test find complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "find" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">number of calls</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">find first complex</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_indexOf">
                +                <field name="END">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="procedures_callreturn">
                +                    <mutation name="get fruit"></mutation>
                +                  </block>
                +                </value>
                +                <value name="FIND">
                +                  <block type="text">
                +                    <field name="TEXT">an</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="unittest_adjustindex">
                +                <value name="INDEX">
                +                  <block type="math_number">
                +                    <field name="NUM">1</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="procedures_callnoreturn" inline="true">
                +                <mutation name="check number of calls">
                +                  <arg name="test name"></arg>
                +                </mutation>
                +                <value name="ARG0">
                +                  <block type="text">
                +                    <field name="TEXT">find first complex</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">number of calls</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">find first order complex</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_indexOf">
                +                            <field name="END">FIRST</field>
                +                            <value name="VALUE">
                +                              <block type="logic_ternary" inline="true">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="procedures_callreturn">
                +                                    <mutation name="get fruit"></mutation>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="FIND">
                +                              <block type="text">
                +                                <field name="TEXT">an</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="procedures_callnoreturn" inline="true">
                +                            <mutation name="check number of calls">
                +                              <arg name="test name"></arg>
                +                            </mutation>
                +                            <value name="ARG0">
                +                              <block type="text">
                +                                <field name="TEXT">find first order complex</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">number of calls</field>
                +                                <value name="VALUE">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">find last complex</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_indexOf">
                +                                        <field name="END">LAST</field>
                +                                        <value name="VALUE">
                +                                          <block type="procedures_callreturn">
                +                                            <mutation name="get fruit"></mutation>
                +                                          </block>
                +                                        </value>
                +                                        <value name="FIND">
                +                                          <block type="text">
                +                                            <field name="TEXT">an</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">3</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn" inline="true">
                +                                        <mutation name="check number of calls">
                +                                          <arg name="test name"></arg>
                +                                        </mutation>
                +                                        <value name="ARG0">
                +                                          <block type="text">
                +                                            <field name="TEXT">find last complex</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set">
                +                                            <field name="VAR">number of calls</field>
                +                                            <value name="VALUE">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">find last order complex</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="text_indexOf">
                +                                                    <field name="END">LAST</field>
                +                                                    <value name="VALUE">
                +                                                      <block type="logic_ternary" inline="true">
                +                                                        <value name="IF">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="THEN">
                +                                                          <block type="procedures_callreturn">
                +                                                            <mutation name="get fruit"></mutation>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ELSE">
                +                                                          <block type="logic_null"></block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="FIND">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">an</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="unittest_adjustindex">
                +                                                    <value name="INDEX">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">3</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                    <mutation name="check number of calls">
                +                                                      <arg name="test name"></arg>
                +                                                    </mutation>
                +                                                    <value name="ARG0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">find last order complex</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set">
                +                                                        <field name="VAR">number of calls</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">find none complex</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="text_indexOf">
                +                                                                <field name="END">FIRST</field>
                +                                                                <value name="VALUE">
                +                                                                  <block type="procedures_callreturn">
                +                                                                    <mutation name="get fruit"></mutation>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="FIND">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">Peel</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="unittest_adjustindex">
                +                                                                <value name="INDEX">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">-1</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                <mutation name="check number of calls">
                +                                                                  <arg name="test name"></arg>
                +                                                                </mutation>
                +                                                                <value name="ARG0">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">find none complex</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set">
                +                                                                    <field name="VAR">number of calls</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">0</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">find none order complex</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="text_indexOf">
                +                                                                            <field name="END">FIRST</field>
                +                                                                            <value name="VALUE">
                +                                                                              <block type="logic_ternary" inline="true">
                +                                                                                <value name="IF">
                +                                                                                  <block type="logic_boolean">
                +                                                                                    <field name="BOOL">TRUE</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="THEN">
                +                                                                                  <block type="procedures_callreturn">
                +                                                                                    <mutation name="get fruit"></mutation>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="ELSE">
                +                                                                                  <block type="logic_null"></block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="FIND">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">Peel</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="EXPECTED">
                +                                                                          <block type="unittest_adjustindex">
                +                                                                            <value name="INDEX">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">-1</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                            <mutation name="check number of calls">
                +                                                                              <arg name="test name"></arg>
                +                                                                            </mutation>
                +                                                                            <value name="ARG0">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">find none order complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="4013">
                +    <field name="NAME">test get simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get letter" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Blockly</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">get first simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_charAt">
                +                <mutation at="false"></mutation>
                +                <field name="WHERE">FIRST</field>
                +                <value name="VALUE">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">B</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">get last simple</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_charAt">
                +                    <mutation at="false"></mutation>
                +                    <field name="WHERE">LAST</field>
                +                    <value name="VALUE">
                +                      <block type="variables_get">
                +                        <field name="VAR">text</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">y</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertvalue" inline="false">
                +                    <field name="EXPECTED">TRUE</field>
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">get random simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="logic_compare">
                +                        <field name="OP">GT</field>
                +                        <value name="A">
                +                          <block type="text_indexOf" inline="false">
                +                            <field name="END">FIRST</field>
                +                            <value name="VALUE">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                            <value name="FIND">
                +                              <block type="text_charAt">
                +                                <mutation at="false"></mutation>
                +                                <field name="WHERE">RANDOM</field>
                +                                <value name="VALUE">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="B">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">-1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">get # simple</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_charAt">
                +                            <mutation at="true"></mutation>
                +                            <field name="WHERE">FROM_START</field>
                +                            <value name="VALUE">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                            <value name="AT">
                +                              <block type="unittest_adjustindex">
                +                                <value name="INDEX">
                +                                  <block type="math_number">
                +                                    <field name="NUM">2</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">o</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">get # order simple</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_charAt">
                +                                <mutation at="true"></mutation>
                +                                <field name="WHERE">FROM_START</field>
                +                                <value name="VALUE">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                                <value name="AT">
                +                                  <block type="logic_ternary">
                +                                    <value name="IF">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="THEN">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">2</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ELSE">
                +                                      <block type="logic_null"></block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">o</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">get #-end simple</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_charAt">
                +                                    <mutation at="true"></mutation>
                +                                    <field name="WHERE">FROM_END</field>
                +                                    <value name="VALUE">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">text</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="AT">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">2</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT">k</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">get #-end order simple</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_charAt">
                +                                        <mutation at="true"></mutation>
                +                                        <field name="WHERE">FROM_END</field>
                +                                        <comment pinned="false" h="84" w="274">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                        <value name="VALUE">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">text</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT">
                +                                          <block type="math_arithmetic">
                +                                            <field name="OP">ADD</field>
                +                                            <value name="A">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="B">
                +                                              <block type="unittest_adjustindex">
                +                                                <value name="INDEX">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">2</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">k</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="4838">
                +    <field name="NAME">get Blockly</field>
                +    <comment pinned="false" h="80" w="160">Creates a string for use with the get test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="text">
                +        <field name="TEXT">Blockly</field>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="4938">
                +    <field name="NAME">test get complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get letter" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Blockly</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="variables_set">
                +            <field name="VAR">number of calls</field>
                +            <value name="VALUE">
                +              <block type="math_number">
                +                <field name="NUM">0</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">get first complex</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_charAt">
                +                    <mutation at="false"></mutation>
                +                    <field name="WHERE">FIRST</field>
                +                    <value name="VALUE">
                +                      <block type="procedures_callreturn">
                +                        <mutation name="get Blockly"></mutation>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">B</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="procedures_callnoreturn" inline="true">
                +                    <mutation name="check number of calls">
                +                      <arg name="test name"></arg>
                +                    </mutation>
                +                    <value name="ARG0">
                +                      <block type="text">
                +                        <field name="TEXT">get first complex</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="variables_set">
                +                        <field name="VAR">number of calls</field>
                +                        <value name="VALUE">
                +                          <block type="math_number">
                +                            <field name="NUM">0</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">get first order complex</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_charAt">
                +                                <mutation at="false"></mutation>
                +                                <field name="WHERE">FIRST</field>
                +                                <value name="VALUE">
                +                                  <block type="logic_ternary" inline="true">
                +                                    <value name="IF">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="THEN">
                +                                      <block type="procedures_callreturn">
                +                                        <mutation name="get Blockly"></mutation>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ELSE">
                +                                      <block type="logic_null"></block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">B</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="procedures_callnoreturn" inline="true">
                +                                <mutation name="check number of calls">
                +                                  <arg name="test name"></arg>
                +                                </mutation>
                +                                <value name="ARG0">
                +                                  <block type="text">
                +                                    <field name="TEXT">get first order complex</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="variables_set">
                +                                    <field name="VAR">number of calls</field>
                +                                    <value name="VALUE">
                +                                      <block type="math_number">
                +                                        <field name="NUM">0</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">get last complex</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="text_charAt">
                +                                            <mutation at="false"></mutation>
                +                                            <field name="WHERE">LAST</field>
                +                                            <value name="VALUE">
                +                                              <block type="procedures_callreturn">
                +                                                <mutation name="get Blockly"></mutation>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">y</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="procedures_callnoreturn" inline="true">
                +                                            <mutation name="check number of calls">
                +                                              <arg name="test name"></arg>
                +                                            </mutation>
                +                                            <value name="ARG0">
                +                                              <block type="text">
                +                                                <field name="TEXT">get last complex</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="variables_set">
                +                                                <field name="VAR">number of calls</field>
                +                                                <value name="VALUE">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">0</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">get last order complex</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="text_charAt">
                +                                                        <mutation at="false"></mutation>
                +                                                        <field name="WHERE">LAST</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="logic_ternary" inline="true">
                +                                                            <value name="IF">
                +                                                              <block type="logic_boolean">
                +                                                                <field name="BOOL">TRUE</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="THEN">
                +                                                              <block type="procedures_callreturn">
                +                                                                <mutation name="get Blockly"></mutation>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ELSE">
                +                                                              <block type="logic_null"></block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">y</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                        <mutation name="check number of calls">
                +                                                          <arg name="test name"></arg>
                +                                                        </mutation>
                +                                                        <value name="ARG0">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">get last order complex</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="variables_set">
                +                                                            <field name="VAR">number of calls</field>
                +                                                            <value name="VALUE">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">0</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertvalue" inline="false">
                +                                                                <field name="EXPECTED">TRUE</field>
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">get random complex</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="logic_compare">
                +                                                                    <field name="OP">GT</field>
                +                                                                    <value name="A">
                +                                                                      <block type="text_indexOf" inline="false">
                +                                                                        <field name="END">FIRST</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="variables_get">
                +                                                                            <field name="VAR">text</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="FIND">
                +                                                                          <block type="text_charAt">
                +                                                                            <mutation at="false"></mutation>
                +                                                                            <field name="WHERE">RANDOM</field>
                +                                                                            <value name="VALUE">
                +                                                                              <block type="procedures_callreturn">
                +                                                                                <mutation name="get Blockly"></mutation>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="B">
                +                                                                      <block type="unittest_adjustindex">
                +                                                                        <value name="INDEX">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">-1</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                    <mutation name="check number of calls">
                +                                                                      <arg name="test name"></arg>
                +                                                                    </mutation>
                +                                                                    <value name="ARG0">
                +                                                                      <block type="text">
                +                                                                        <field name="TEXT">get random complex</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="variables_set">
                +                                                                        <field name="VAR">number of calls</field>
                +                                                                        <value name="VALUE">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">0</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="unittest_assertvalue" inline="false">
                +                                                                            <field name="EXPECTED">TRUE</field>
                +                                                                            <value name="MESSAGE">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">get random order complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="ACTUAL">
                +                                                                              <block type="logic_compare">
                +                                                                                <field name="OP">GT</field>
                +                                                                                <value name="A">
                +                                                                                  <block type="text_indexOf" inline="false">
                +                                                                                    <field name="END">FIRST</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="variables_get">
                +                                                                                        <field name="VAR">text</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="FIND">
                +                                                                                      <block type="text_charAt">
                +                                                                                        <mutation at="false"></mutation>
                +                                                                                        <field name="WHERE">RANDOM</field>
                +                                                                                        <value name="VALUE">
                +                                                                                          <block type="logic_ternary" inline="false">
                +                                                                                            <value name="IF">
                +                                                                                              <block type="logic_boolean">
                +                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="THEN">
                +                                                                                              <block type="procedures_callreturn">
                +                                                                                                <mutation name="get Blockly"></mutation>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="ELSE">
                +                                                                                              <block type="logic_null"></block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <value name="B">
                +                                                                                  <block type="unittest_adjustindex">
                +                                                                                    <value name="INDEX">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">-1</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                <mutation name="check number of calls">
                +                                                                                  <arg name="test name"></arg>
                +                                                                                </mutation>
                +                                                                                <value name="ARG0">
                +                                                                                  <block type="text">
                +                                                                                    <field name="TEXT">get random order complex</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="variables_set">
                +                                                                                    <field name="VAR">number of calls</field>
                +                                                                                    <value name="VALUE">
                +                                                                                      <block type="math_number">
                +                                                                                        <field name="NUM">0</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                        <value name="MESSAGE">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">get # complex</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="ACTUAL">
                +                                                                                          <block type="text_charAt">
                +                                                                                            <mutation at="true"></mutation>
                +                                                                                            <field name="WHERE">FROM_START</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="procedures_callreturn">
                +                                                                                                <mutation name="get Blockly"></mutation>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <value name="AT">
                +                                                                                              <block type="unittest_adjustindex">
                +                                                                                                <value name="INDEX">
                +                                                                                                  <block type="math_number">
                +                                                                                                    <field name="NUM">2</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="EXPECTED">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">o</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                            <mutation name="check number of calls">
                +                                                                                              <arg name="test name"></arg>
                +                                                                                            </mutation>
                +                                                                                            <value name="ARG0">
                +                                                                                              <block type="text">
                +                                                                                                <field name="TEXT">get # complex</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="variables_set">
                +                                                                                                <field name="VAR">number of calls</field>
                +                                                                                                <value name="VALUE">
                +                                                                                                  <block type="math_number">
                +                                                                                                    <field name="NUM">0</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                    <value name="MESSAGE">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">get # order complex</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="ACTUAL">
                +                                                                                                      <block type="text_charAt">
                +                                                                                                        <mutation at="true"></mutation>
                +                                                                                                        <field name="WHERE">FROM_START</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="logic_ternary" inline="false">
                +                                                                                                            <value name="IF">
                +                                                                                                              <block type="logic_boolean">
                +                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="THEN">
                +                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                <mutation name="get Blockly"></mutation>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ELSE">
                +                                                                                                              <block type="logic_null"></block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <value name="AT">
                +                                                                                                          <block type="logic_ternary">
                +                                                                                                            <value name="IF">
                +                                                                                                              <block type="logic_boolean">
                +                                                                                                                <field name="BOOL">TRUE</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="THEN">
                +                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                <value name="INDEX">
                +                                                                                                                  <block type="math_number">
                +                                                                                                                    <field name="NUM">2</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ELSE">
                +                                                                                                              <block type="logic_null"></block>
                +                                                                                                            </value>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="EXPECTED">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">o</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                                        <mutation name="check number of calls">
                +                                                                                                          <arg name="test name"></arg>
                +                                                                                                        </mutation>
                +                                                                                                        <value name="ARG0">
                +                                                                                                          <block type="text">
                +                                                                                                            <field name="TEXT">get # order complex</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="variables_set">
                +                                                                                                            <field name="VAR">number of calls</field>
                +                                                                                                            <value name="VALUE">
                +                                                                                                              <block type="math_number">
                +                                                                                                                <field name="NUM">0</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                <value name="MESSAGE">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">get #-end complex</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="ACTUAL">
                +                                                                                                                  <block type="text_charAt">
                +                                                                                                                    <mutation at="true"></mutation>
                +                                                                                                                    <field name="WHERE">FROM_END</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                        <mutation name="get Blockly"></mutation>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <value name="AT">
                +                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                        <value name="INDEX">
                +                                                                                                                          <block type="math_number">
                +                                                                                                                            <field name="NUM">2</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="EXPECTED">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">k</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                    <mutation name="check number of calls">
                +                                                                                                                      <arg name="test name"></arg>
                +                                                                                                                    </mutation>
                +                                                                                                                    <value name="ARG0">
                +                                                                                                                      <block type="text">
                +                                                                                                                        <field name="TEXT">get #-end complex</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="variables_set">
                +                                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                                        <value name="VALUE">
                +                                                                                                                          <block type="math_number">
                +                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                            <value name="MESSAGE">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">get #-end order complex</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="ACTUAL">
                +                                                                                                                              <block type="text_charAt">
                +                                                                                                                                <mutation at="true"></mutation>
                +                                                                                                                                <field name="WHERE">FROM_END</field>
                +                                                                                                                                <comment pinned="false" h="83" w="258">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                                                                                                                <value name="VALUE">
                +                                                                                                                                  <block type="logic_ternary" inline="true">
                +                                                                                                                                    <value name="IF">
                +                                                                                                                                      <block type="logic_boolean">
                +                                                                                                                                        <field name="BOOL">TRUE</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="THEN">
                +                                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                                        <mutation name="get Blockly"></mutation>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="ELSE">
                +                                                                                                                                      <block type="logic_null"></block>
                +                                                                                                                                    </value>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <value name="AT">
                +                                                                                                                                  <block type="math_arithmetic">
                +                                                                                                                                    <field name="OP">ADD</field>
                +                                                                                                                                    <value name="A">
                +                                                                                                                                      <block type="math_number">
                +                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="B">
                +                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                        <value name="INDEX">
                +                                                                                                                                          <block type="math_number">
                +                                                                                                                                            <field name="NUM">2</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="EXPECTED">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">k</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <next>
                +                                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                <mutation name="check number of calls">
                +                                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                                </mutation>
                +                                                                                                                                <value name="ARG0">
                +                                                                                                                                  <block type="text">
                +                                                                                                                                    <field name="TEXT">get #-end order complex</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </next>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defreturn" x="13" y="6738">
                +    <field name="NAME">get numbers</field>
                +    <comment pinned="false" h="80" w="160">Creates a string for use with the substring test.</comment>
                +    <statement name="STACK">
                +      <block type="math_change">
                +        <field name="VAR">number of calls</field>
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +    </statement>
                +    <value name="RETURN">
                +      <block type="text">
                +        <field name="TEXT">123456789</field>
                +      </block>
                +    </value>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="6838">
                +    <field name="NAME">test substring simple</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get substring" block with a variable.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">123456789</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">substring # simple</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_getSubstring">
                +                <mutation at1="true" at2="true"></mutation>
                +                <field name="WHERE1">FROM_START</field>
                +                <field name="WHERE2">FROM_START</field>
                +                <value name="STRING">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +                <value name="AT1">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="AT2">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">23</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">substring # simple order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_getSubstring">
                +                    <mutation at1="true" at2="true"></mutation>
                +                    <field name="WHERE1">FROM_START</field>
                +                    <field name="WHERE2">FROM_START</field>
                +                    <value name="STRING">
                +                      <block type="variables_get">
                +                        <field name="VAR">text</field>
                +                      </block>
                +                    </value>
                +                    <value name="AT1">
                +                      <block type="logic_ternary">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="AT2">
                +                      <block type="logic_ternary">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">23</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">substring #-end simple</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_getSubstring">
                +                        <mutation at1="true" at2="true"></mutation>
                +                        <field name="WHERE1">FROM_END</field>
                +                        <field name="WHERE2">FROM_END</field>
                +                        <value name="STRING">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                        <value name="AT1">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">2</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="AT2">
                +                          <block type="unittest_adjustindex">
                +                            <value name="INDEX">
                +                              <block type="math_number">
                +                                <field name="NUM">1</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">78</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">substring #-end simple order</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_getSubstring">
                +                            <mutation at1="true" at2="true"></mutation>
                +                            <field name="WHERE1">FROM_END</field>
                +                            <field name="WHERE2">FROM_END</field>
                +                            <comment pinned="false" h="81" w="266">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                            <value name="STRING">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                            <value name="AT1">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">ADD</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT2">
                +                              <block type="math_arithmetic">
                +                                <field name="OP">ADD</field>
                +                                <value name="A">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <value name="B">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">78</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">substring first-last simple</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_getSubstring">
                +                                <mutation at1="false" at2="false"></mutation>
                +                                <field name="WHERE1">FIRST</field>
                +                                <field name="WHERE2">LAST</field>
                +                                <value name="STRING">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">substring # #-end simple</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_getSubstring">
                +                                    <mutation at1="true" at2="true"></mutation>
                +                                    <field name="WHERE1">FROM_START</field>
                +                                    <field name="WHERE2">FROM_END</field>
                +                                    <value name="STRING">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">text</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="AT1">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="AT2">
                +                                      <block type="unittest_adjustindex">
                +                                        <value name="INDEX">
                +                                          <block type="math_number">
                +                                            <field name="NUM">1</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT">2345678</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">substring #-end # simple</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_getSubstring">
                +                                        <mutation at1="true" at2="true"></mutation>
                +                                        <field name="WHERE1">FROM_END</field>
                +                                        <field name="WHERE2">FROM_START</field>
                +                                        <value name="STRING">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">text</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT1">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">6</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT2">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">3</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">34</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">substring first # simple</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="text_getSubstring">
                +                                            <mutation at1="false" at2="true"></mutation>
                +                                            <field name="WHERE1">FIRST</field>
                +                                            <field name="WHERE2">FROM_START</field>
                +                                            <value name="STRING">
                +                                              <block type="variables_get">
                +                                                <field name="VAR">text</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="AT2">
                +                                              <block type="unittest_adjustindex">
                +                                                <value name="INDEX">
                +                                                  <block type="math_number">
                +                                                    <field name="NUM">3</field>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">1234</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="unittest_assertequals" inline="false">
                +                                            <value name="MESSAGE">
                +                                              <block type="text">
                +                                                <field name="TEXT">substring first #-end simple</field>
                +                                              </block>
                +                                            </value>
                +                                            <value name="ACTUAL">
                +                                              <block type="text_getSubstring">
                +                                                <mutation at1="false" at2="true"></mutation>
                +                                                <field name="WHERE1">FIRST</field>
                +                                                <field name="WHERE2">FROM_END</field>
                +                                                <value name="STRING">
                +                                                  <block type="variables_get">
                +                                                    <field name="VAR">text</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="AT2">
                +                                                  <block type="unittest_adjustindex">
                +                                                    <value name="INDEX">
                +                                                      <block type="math_number">
                +                                                        <field name="NUM">1</field>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                            <value name="EXPECTED">
                +                                              <block type="text">
                +                                                <field name="TEXT">12345678</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">substring # last simple</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="text_getSubstring">
                +                                                    <mutation at1="true" at2="false"></mutation>
                +                                                    <field name="WHERE1">FROM_START</field>
                +                                                    <field name="WHERE2">LAST</field>
                +                                                    <value name="STRING">
                +                                                      <block type="variables_get">
                +                                                        <field name="VAR">text</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT1">
                +                                                      <block type="unittest_adjustindex">
                +                                                        <value name="INDEX">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">6</field>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">789</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="unittest_assertequals" inline="false">
                +                                                    <value name="MESSAGE">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">substring #-end last simple</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="ACTUAL">
                +                                                      <block type="text_getSubstring">
                +                                                        <mutation at1="true" at2="false"></mutation>
                +                                                        <field name="WHERE1">FROM_END</field>
                +                                                        <field name="WHERE2">LAST</field>
                +                                                        <value name="STRING">
                +                                                          <block type="variables_get">
                +                                                            <field name="VAR">text</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="AT1">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">2</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="EXPECTED">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">789</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="unittest_assertequals" inline="false">
                +                                                        <value name="MESSAGE">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">substring all with # #-end simple</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ACTUAL">
                +                                                          <block type="text_getSubstring">
                +                                                            <mutation at1="true" at2="true"></mutation>
                +                                                            <field name="WHERE1">FROM_START</field>
                +                                                            <field name="WHERE2">FROM_END</field>
                +                                                            <value name="STRING">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">text</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="AT1">
                +                                                              <block type="unittest_adjustindex">
                +                                                                <value name="INDEX">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">0</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="AT2">
                +                                                              <block type="unittest_adjustindex">
                +                                                                <value name="INDEX">
                +                                                                  <block type="math_number">
                +                                                                    <field name="NUM">0</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="EXPECTED">
                +                                                          <block type="text">
                +                                                            <field name="TEXT">123456789</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">substring all with #-end # simple</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="text_getSubstring">
                +                                                                <mutation at1="true" at2="true"></mutation>
                +                                                                <field name="WHERE1">FROM_END</field>
                +                                                                <field name="WHERE2">FROM_START</field>
                +                                                                <value name="STRING">
                +                                                                  <block type="variables_get">
                +                                                                    <field name="VAR">text</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="AT1">
                +                                                                  <block type="unittest_adjustindex">
                +                                                                    <value name="INDEX">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">8</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="AT2">
                +                                                                  <block type="unittest_adjustindex">
                +                                                                    <value name="INDEX">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">8</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">123456789</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="unittest_assertequals" inline="false">
                +                                                                <value name="MESSAGE">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">substring all with # #-end math simple</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="ACTUAL">
                +                                                                  <block type="text_getSubstring">
                +                                                                    <mutation at1="true" at2="true"></mutation>
                +                                                                    <field name="WHERE1">FROM_START</field>
                +                                                                    <field name="WHERE2">FROM_END</field>
                +                                                                    <comment pinned="false" h="94" w="320">Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end.</comment>
                +                                                                    <value name="STRING">
                +                                                                      <block type="variables_get">
                +                                                                        <field name="VAR">text</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="AT1">
                +                                                                      <block type="math_arithmetic">
                +                                                                        <field name="OP">ADD</field>
                +                                                                        <value name="A">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">0</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="B">
                +                                                                          <block type="unittest_adjustindex">
                +                                                                            <value name="INDEX">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">0</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <value name="AT2">
                +                                                                      <block type="math_arithmetic">
                +                                                                        <field name="OP">ADD</field>
                +                                                                        <value name="A">
                +                                                                          <block type="math_number">
                +                                                                            <field name="NUM">0</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="B">
                +                                                                          <block type="unittest_adjustindex">
                +                                                                            <value name="INDEX">
                +                                                                              <block type="math_number">
                +                                                                                <field name="NUM">0</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <value name="EXPECTED">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">123456789</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="8388">
                +    <field name="NAME">test substring complex</field>
                +    <comment pinned="false" h="80" w="160">Tests the "get substring" block with a function call.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">number of calls</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">substring # complex</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_getSubstring">
                +                <mutation at1="true" at2="true"></mutation>
                +                <field name="WHERE1">FROM_START</field>
                +                <field name="WHERE2">FROM_START</field>
                +                <value name="STRING">
                +                  <block type="procedures_callreturn">
                +                    <mutation name="get numbers"></mutation>
                +                  </block>
                +                </value>
                +                <value name="AT1">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">1</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="AT2">
                +                  <block type="unittest_adjustindex">
                +                    <value name="INDEX">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">23</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="procedures_callnoreturn" inline="true">
                +                <mutation name="check number of calls">
                +                  <arg name="test name"></arg>
                +                </mutation>
                +                <value name="ARG0">
                +                  <block type="text">
                +                    <field name="TEXT">substring # complex</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">number of calls</field>
                +                    <value name="VALUE">
                +                      <block type="math_number">
                +                        <field name="NUM">0</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">substring # complex order</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_getSubstring">
                +                            <mutation at1="true" at2="true"></mutation>
                +                            <field name="WHERE1">FROM_START</field>
                +                            <field name="WHERE2">FROM_START</field>
                +                            <value name="STRING">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="procedures_callreturn">
                +                                    <mutation name="get numbers"></mutation>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT1">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">1</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="AT2">
                +                              <block type="logic_ternary">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="unittest_adjustindex">
                +                                    <value name="INDEX">
                +                                      <block type="math_number">
                +                                        <field name="NUM">2</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">23</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="procedures_callnoreturn" inline="true">
                +                            <mutation name="check number of calls">
                +                              <arg name="test name"></arg>
                +                            </mutation>
                +                            <value name="ARG0">
                +                              <block type="text">
                +                                <field name="TEXT">substring # complex order</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">number of calls</field>
                +                                <value name="VALUE">
                +                                  <block type="math_number">
                +                                    <field name="NUM">0</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">substring #-end complex</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_getSubstring">
                +                                        <mutation at1="true" at2="true"></mutation>
                +                                        <field name="WHERE1">FROM_END</field>
                +                                        <field name="WHERE2">FROM_END</field>
                +                                        <comment pinned="false" h="83" w="259">The order for index for #-end is addition because this will catch errors in generators where most perform the operation ... - index.</comment>
                +                                        <value name="STRING">
                +                                          <block type="procedures_callreturn">
                +                                            <mutation name="get numbers"></mutation>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT1">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">2</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="AT2">
                +                                          <block type="unittest_adjustindex">
                +                                            <value name="INDEX">
                +                                              <block type="math_number">
                +                                                <field name="NUM">1</field>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">78</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="procedures_callnoreturn" inline="true">
                +                                        <mutation name="check number of calls">
                +                                          <arg name="test name"></arg>
                +                                        </mutation>
                +                                        <value name="ARG0">
                +                                          <block type="text">
                +                                            <field name="TEXT">substring #-end complex</field>
                +                                          </block>
                +                                        </value>
                +                                        <next>
                +                                          <block type="variables_set">
                +                                            <field name="VAR">number of calls</field>
                +                                            <value name="VALUE">
                +                                              <block type="math_number">
                +                                                <field name="NUM">0</field>
                +                                              </block>
                +                                            </value>
                +                                            <next>
                +                                              <block type="unittest_assertequals" inline="false">
                +                                                <value name="MESSAGE">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">substring #-end order order</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ACTUAL">
                +                                                  <block type="text_getSubstring">
                +                                                    <mutation at1="true" at2="true"></mutation>
                +                                                    <field name="WHERE1">FROM_END</field>
                +                                                    <field name="WHERE2">FROM_END</field>
                +                                                    <value name="STRING">
                +                                                      <block type="logic_ternary">
                +                                                        <value name="IF">
                +                                                          <block type="logic_boolean">
                +                                                            <field name="BOOL">TRUE</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="THEN">
                +                                                          <block type="procedures_callreturn">
                +                                                            <mutation name="get numbers"></mutation>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="ELSE">
                +                                                          <block type="logic_null"></block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT1">
                +                                                      <block type="math_arithmetic">
                +                                                        <field name="OP">ADD</field>
                +                                                        <value name="A">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">2</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                    <value name="AT2">
                +                                                      <block type="math_arithmetic">
                +                                                        <field name="OP">ADD</field>
                +                                                        <value name="A">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <value name="B">
                +                                                          <block type="unittest_adjustindex">
                +                                                            <value name="INDEX">
                +                                                              <block type="math_number">
                +                                                                <field name="NUM">1</field>
                +                                                              </block>
                +                                                            </value>
                +                                                          </block>
                +                                                        </value>
                +                                                      </block>
                +                                                    </value>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="EXPECTED">
                +                                                  <block type="text">
                +                                                    <field name="TEXT">78</field>
                +                                                  </block>
                +                                                </value>
                +                                                <next>
                +                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                    <mutation name="check number of calls">
                +                                                      <arg name="test name"></arg>
                +                                                    </mutation>
                +                                                    <value name="ARG0">
                +                                                      <block type="text">
                +                                                        <field name="TEXT">substring #-end order order</field>
                +                                                      </block>
                +                                                    </value>
                +                                                    <next>
                +                                                      <block type="variables_set">
                +                                                        <field name="VAR">number of calls</field>
                +                                                        <value name="VALUE">
                +                                                          <block type="math_number">
                +                                                            <field name="NUM">0</field>
                +                                                          </block>
                +                                                        </value>
                +                                                        <next>
                +                                                          <block type="unittest_assertequals" inline="false">
                +                                                            <value name="MESSAGE">
                +                                                              <block type="text">
                +                                                                <field name="TEXT">substring first-last</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="ACTUAL">
                +                                                              <block type="text_getSubstring">
                +                                                                <mutation at1="false" at2="false"></mutation>
                +                                                                <field name="WHERE1">FIRST</field>
                +                                                                <field name="WHERE2">LAST</field>
                +                                                                <value name="STRING">
                +                                                                  <block type="procedures_callreturn">
                +                                                                    <mutation name="get numbers"></mutation>
                +                                                                  </block>
                +                                                                </value>
                +                                                              </block>
                +                                                            </value>
                +                                                            <value name="EXPECTED">
                +                                                              <block type="variables_get">
                +                                                                <field name="VAR">text</field>
                +                                                              </block>
                +                                                            </value>
                +                                                            <next>
                +                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                <mutation name="check number of calls">
                +                                                                  <arg name="test name"></arg>
                +                                                                </mutation>
                +                                                                <value name="ARG0">
                +                                                                  <block type="text">
                +                                                                    <field name="TEXT">substring first-last</field>
                +                                                                  </block>
                +                                                                </value>
                +                                                                <next>
                +                                                                  <block type="variables_set">
                +                                                                    <field name="VAR">number of calls</field>
                +                                                                    <value name="VALUE">
                +                                                                      <block type="math_number">
                +                                                                        <field name="NUM">0</field>
                +                                                                      </block>
                +                                                                    </value>
                +                                                                    <next>
                +                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                        <value name="MESSAGE">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">substring # #-end complex</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="ACTUAL">
                +                                                                          <block type="text_getSubstring">
                +                                                                            <mutation at1="true" at2="true"></mutation>
                +                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                            <field name="WHERE2">FROM_END</field>
                +                                                                            <value name="STRING">
                +                                                                              <block type="procedures_callreturn">
                +                                                                                <mutation name="get numbers"></mutation>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT1">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">1</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <value name="AT2">
                +                                                                              <block type="unittest_adjustindex">
                +                                                                                <value name="INDEX">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">1</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <value name="EXPECTED">
                +                                                                          <block type="text">
                +                                                                            <field name="TEXT">2345678</field>
                +                                                                          </block>
                +                                                                        </value>
                +                                                                        <next>
                +                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                            <mutation name="check number of calls">
                +                                                                              <arg name="test name"></arg>
                +                                                                            </mutation>
                +                                                                            <value name="ARG0">
                +                                                                              <block type="text">
                +                                                                                <field name="TEXT">substring # #-end complex</field>
                +                                                                              </block>
                +                                                                            </value>
                +                                                                            <next>
                +                                                                              <block type="variables_set">
                +                                                                                <field name="VAR">number of calls</field>
                +                                                                                <value name="VALUE">
                +                                                                                  <block type="math_number">
                +                                                                                    <field name="NUM">0</field>
                +                                                                                  </block>
                +                                                                                </value>
                +                                                                                <next>
                +                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                    <value name="MESSAGE">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">substring #-end # complex</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="ACTUAL">
                +                                                                                      <block type="text_getSubstring">
                +                                                                                        <mutation at1="true" at2="true"></mutation>
                +                                                                                        <field name="WHERE1">FROM_END</field>
                +                                                                                        <field name="WHERE2">FROM_START</field>
                +                                                                                        <value name="STRING">
                +                                                                                          <block type="procedures_callreturn">
                +                                                                                            <mutation name="get numbers"></mutation>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="AT1">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">6</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <value name="AT2">
                +                                                                                          <block type="unittest_adjustindex">
                +                                                                                            <value name="INDEX">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">3</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <value name="EXPECTED">
                +                                                                                      <block type="text">
                +                                                                                        <field name="TEXT">34</field>
                +                                                                                      </block>
                +                                                                                    </value>
                +                                                                                    <next>
                +                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                        <mutation name="check number of calls">
                +                                                                                          <arg name="test name"></arg>
                +                                                                                        </mutation>
                +                                                                                        <value name="ARG0">
                +                                                                                          <block type="text">
                +                                                                                            <field name="TEXT">substring #-end # complex</field>
                +                                                                                          </block>
                +                                                                                        </value>
                +                                                                                        <next>
                +                                                                                          <block type="variables_set">
                +                                                                                            <field name="VAR">number of calls</field>
                +                                                                                            <value name="VALUE">
                +                                                                                              <block type="math_number">
                +                                                                                                <field name="NUM">0</field>
                +                                                                                              </block>
                +                                                                                            </value>
                +                                                                                            <next>
                +                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                <value name="MESSAGE">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">substring first # complex</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="ACTUAL">
                +                                                                                                  <block type="text_getSubstring">
                +                                                                                                    <mutation at1="false" at2="true"></mutation>
                +                                                                                                    <field name="WHERE1">FIRST</field>
                +                                                                                                    <field name="WHERE2">FROM_START</field>
                +                                                                                                    <value name="STRING">
                +                                                                                                      <block type="procedures_callreturn">
                +                                                                                                        <mutation name="get numbers"></mutation>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <value name="AT2">
                +                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                        <value name="INDEX">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">3</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <value name="EXPECTED">
                +                                                                                                  <block type="text">
                +                                                                                                    <field name="TEXT">1234</field>
                +                                                                                                  </block>
                +                                                                                                </value>
                +                                                                                                <next>
                +                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                    <mutation name="check number of calls">
                +                                                                                                      <arg name="test name"></arg>
                +                                                                                                    </mutation>
                +                                                                                                    <value name="ARG0">
                +                                                                                                      <block type="text">
                +                                                                                                        <field name="TEXT">substring first # complex</field>
                +                                                                                                      </block>
                +                                                                                                    </value>
                +                                                                                                    <next>
                +                                                                                                      <block type="variables_set">
                +                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                        <value name="VALUE">
                +                                                                                                          <block type="math_number">
                +                                                                                                            <field name="NUM">0</field>
                +                                                                                                          </block>
                +                                                                                                        </value>
                +                                                                                                        <next>
                +                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                            <value name="MESSAGE">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">substring first #-end complex</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="ACTUAL">
                +                                                                                                              <block type="text_getSubstring">
                +                                                                                                                <mutation at1="false" at2="true"></mutation>
                +                                                                                                                <field name="WHERE1">FIRST</field>
                +                                                                                                                <field name="WHERE2">FROM_END</field>
                +                                                                                                                <value name="STRING">
                +                                                                                                                  <block type="procedures_callreturn">
                +                                                                                                                    <mutation name="get numbers"></mutation>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <value name="AT2">
                +                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                    <value name="INDEX">
                +                                                                                                                      <block type="math_number">
                +                                                                                                                        <field name="NUM">1</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <value name="EXPECTED">
                +                                                                                                              <block type="text">
                +                                                                                                                <field name="TEXT">12345678</field>
                +                                                                                                              </block>
                +                                                                                                            </value>
                +                                                                                                            <next>
                +                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                <mutation name="check number of calls">
                +                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                </mutation>
                +                                                                                                                <value name="ARG0">
                +                                                                                                                  <block type="text">
                +                                                                                                                    <field name="TEXT">substring first #-end complex</field>
                +                                                                                                                  </block>
                +                                                                                                                </value>
                +                                                                                                                <next>
                +                                                                                                                  <block type="variables_set">
                +                                                                                                                    <field name="VAR">number of calls</field>
                +                                                                                                                    <value name="VALUE">
                +                                                                                                                      <block type="math_number">
                +                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                      </block>
                +                                                                                                                    </value>
                +                                                                                                                    <next>
                +                                                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                                                        <value name="MESSAGE">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">substring # last complex</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="ACTUAL">
                +                                                                                                                          <block type="text_getSubstring">
                +                                                                                                                            <mutation at1="true" at2="false"></mutation>
                +                                                                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                                                                            <field name="WHERE2">LAST</field>
                +                                                                                                                            <value name="STRING">
                +                                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                                <mutation name="get numbers"></mutation>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <value name="AT1">
                +                                                                                                                              <block type="unittest_adjustindex">
                +                                                                                                                                <value name="INDEX">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">6</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <value name="EXPECTED">
                +                                                                                                                          <block type="text">
                +                                                                                                                            <field name="TEXT">789</field>
                +                                                                                                                          </block>
                +                                                                                                                        </value>
                +                                                                                                                        <next>
                +                                                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                            <mutation name="check number of calls">
                +                                                                                                                              <arg name="test name"></arg>
                +                                                                                                                            </mutation>
                +                                                                                                                            <value name="ARG0">
                +                                                                                                                              <block type="text">
                +                                                                                                                                <field name="TEXT">substring # last complex</field>
                +                                                                                                                              </block>
                +                                                                                                                            </value>
                +                                                                                                                            <next>
                +                                                                                                                              <block type="variables_set">
                +                                                                                                                                <field name="VAR">number of calls</field>
                +                                                                                                                                <value name="VALUE">
                +                                                                                                                                  <block type="math_number">
                +                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                  </block>
                +                                                                                                                                </value>
                +                                                                                                                                <next>
                +                                                                                                                                  <block type="unittest_assertequals" inline="false">
                +                                                                                                                                    <value name="MESSAGE">
                +                                                                                                                                      <block type="text">
                +                                                                                                                                        <field name="TEXT">substring #-end last complex</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="ACTUAL">
                +                                                                                                                                      <block type="text_getSubstring">
                +                                                                                                                                        <mutation at1="true" at2="false"></mutation>
                +                                                                                                                                        <field name="WHERE1">FROM_END</field>
                +                                                                                                                                        <field name="WHERE2">LAST</field>
                +                                                                                                                                        <value name="STRING">
                +                                                                                                                                          <block type="procedures_callreturn">
                +                                                                                                                                            <mutation name="get numbers"></mutation>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <value name="AT1">
                +                                                                                                                                          <block type="unittest_adjustindex">
                +                                                                                                                                            <value name="INDEX">
                +                                                                                                                                              <block type="math_number">
                +                                                                                                                                                <field name="NUM">2</field>
                +                                                                                                                                              </block>
                +                                                                                                                                            </value>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <value name="EXPECTED">
                +                                                                                                                                      <block type="text">
                +                                                                                                                                        <field name="TEXT">789</field>
                +                                                                                                                                      </block>
                +                                                                                                                                    </value>
                +                                                                                                                                    <next>
                +                                                                                                                                      <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                        <mutation name="check number of calls">
                +                                                                                                                                          <arg name="test name"></arg>
                +                                                                                                                                        </mutation>
                +                                                                                                                                        <value name="ARG0">
                +                                                                                                                                          <block type="text">
                +                                                                                                                                            <field name="TEXT">substring #-end last complex</field>
                +                                                                                                                                          </block>
                +                                                                                                                                        </value>
                +                                                                                                                                        <next>
                +                                                                                                                                          <block type="variables_set">
                +                                                                                                                                            <field name="VAR">number of calls</field>
                +                                                                                                                                            <value name="VALUE">
                +                                                                                                                                              <block type="math_number">
                +                                                                                                                                                <field name="NUM">0</field>
                +                                                                                                                                              </block>
                +                                                                                                                                            </value>
                +                                                                                                                                            <next>
                +                                                                                                                                              <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                <value name="MESSAGE">
                +                                                                                                                                                  <block type="text">
                +                                                                                                                                                    <field name="TEXT">substring all with # #-end complex</field>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <value name="ACTUAL">
                +                                                                                                                                                  <block type="text_getSubstring">
                +                                                                                                                                                    <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                    <field name="WHERE1">FROM_START</field>
                +                                                                                                                                                    <field name="WHERE2">FROM_END</field>
                +                                                                                                                                                    <value name="STRING">
                +                                                                                                                                                      <block type="procedures_callreturn">
                +                                                                                                                                                        <mutation name="get numbers"></mutation>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <value name="AT1">
                +                                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                                        <value name="INDEX">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <value name="AT2">
                +                                                                                                                                                      <block type="unittest_adjustindex">
                +                                                                                                                                                        <value name="INDEX">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <value name="EXPECTED">
                +                                                                                                                                                  <block type="text">
                +                                                                                                                                                    <field name="TEXT">123456789</field>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </value>
                +                                                                                                                                                <next>
                +                                                                                                                                                  <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                    <mutation name="check number of calls">
                +                                                                                                                                                      <arg name="test name"></arg>
                +                                                                                                                                                    </mutation>
                +                                                                                                                                                    <value name="ARG0">
                +                                                                                                                                                      <block type="text">
                +                                                                                                                                                        <field name="TEXT">substring all with # #-end complex</field>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </value>
                +                                                                                                                                                    <next>
                +                                                                                                                                                      <block type="variables_set">
                +                                                                                                                                                        <field name="VAR">number of calls</field>
                +                                                                                                                                                        <value name="VALUE">
                +                                                                                                                                                          <block type="math_number">
                +                                                                                                                                                            <field name="NUM">0</field>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </value>
                +                                                                                                                                                        <next>
                +                                                                                                                                                          <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                            <value name="MESSAGE">
                +                                                                                                                                                              <block type="text">
                +                                                                                                                                                                <field name="TEXT">substring all with #-end # complex</field>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <value name="ACTUAL">
                +                                                                                                                                                              <block type="text_getSubstring">
                +                                                                                                                                                                <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                                <field name="WHERE1">FROM_END</field>
                +                                                                                                                                                                <field name="WHERE2">FROM_START</field>
                +                                                                                                                                                                <value name="STRING">
                +                                                                                                                                                                  <block type="procedures_callreturn">
                +                                                                                                                                                                    <mutation name="get numbers"></mutation>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <value name="AT1">
                +                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">8</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <value name="AT2">
                +                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">8</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <value name="EXPECTED">
                +                                                                                                                                                              <block type="text">
                +                                                                                                                                                                <field name="TEXT">123456789</field>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </value>
                +                                                                                                                                                            <next>
                +                                                                                                                                                              <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                                <mutation name="check number of calls">
                +                                                                                                                                                                  <arg name="test name"></arg>
                +                                                                                                                                                                </mutation>
                +                                                                                                                                                                <value name="ARG0">
                +                                                                                                                                                                  <block type="text">
                +                                                                                                                                                                    <field name="TEXT">substring all with #-end # complex</field>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </value>
                +                                                                                                                                                                <next>
                +                                                                                                                                                                  <block type="variables_set">
                +                                                                                                                                                                    <field name="VAR">number of calls</field>
                +                                                                                                                                                                    <value name="VALUE">
                +                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </value>
                +                                                                                                                                                                    <next>
                +                                                                                                                                                                      <block type="unittest_assertequals" inline="false">
                +                                                                                                                                                                        <value name="MESSAGE">
                +                                                                                                                                                                          <block type="text">
                +                                                                                                                                                                            <field name="TEXT">substring all with # #-end math complex</field>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <value name="ACTUAL">
                +                                                                                                                                                                          <block type="text_getSubstring">
                +                                                                                                                                                                            <mutation at1="true" at2="true"></mutation>
                +                                                                                                                                                                            <field name="WHERE1">FROM_START</field>
                +                                                                                                                                                                            <field name="WHERE2">FROM_END</field>
                +                                                                                                                                                                            <comment pinned="false" h="92" w="323">Checks that the whole string is properly retrieved even if the value for start and end is not a simple number. This is especially important in generators where substring uses [x:length - y] for # #-end.</comment>
                +                                                                                                                                                                            <value name="STRING">
                +                                                                                                                                                                              <block type="procedures_callreturn">
                +                                                                                                                                                                                <mutation name="get numbers"></mutation>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                            <value name="AT1">
                +                                                                                                                                                                              <block type="math_arithmetic">
                +                                                                                                                                                                                <field name="OP">ADD</field>
                +                                                                                                                                                                                <value name="A">
                +                                                                                                                                                                                  <block type="math_number">
                +                                                                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                                <value name="B">
                +                                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                                      </block>
                +                                                                                                                                                                                    </value>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                            <value name="AT2">
                +                                                                                                                                                                              <block type="math_arithmetic">
                +                                                                                                                                                                                <field name="OP">ADD</field>
                +                                                                                                                                                                                <value name="A">
                +                                                                                                                                                                                  <block type="math_number">
                +                                                                                                                                                                                    <field name="NUM">0</field>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                                <value name="B">
                +                                                                                                                                                                                  <block type="unittest_adjustindex">
                +                                                                                                                                                                                    <value name="INDEX">
                +                                                                                                                                                                                      <block type="math_number">
                +                                                                                                                                                                                        <field name="NUM">0</field>
                +                                                                                                                                                                                      </block>
                +                                                                                                                                                                                    </value>
                +                                                                                                                                                                                  </block>
                +                                                                                                                                                                                </value>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <value name="EXPECTED">
                +                                                                                                                                                                          <block type="text">
                +                                                                                                                                                                            <field name="TEXT">123456789</field>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </value>
                +                                                                                                                                                                        <next>
                +                                                                                                                                                                          <block type="procedures_callnoreturn" inline="true">
                +                                                                                                                                                                            <mutation name="check number of calls">
                +                                                                                                                                                                              <arg name="test name"></arg>
                +                                                                                                                                                                            </mutation>
                +                                                                                                                                                                            <value name="ARG0">
                +                                                                                                                                                                              <block type="text">
                +                                                                                                                                                                                <field name="TEXT">substring all with # #-end math complex</field>
                +                                                                                                                                                                              </block>
                +                                                                                                                                                                            </value>
                +                                                                                                                                                                          </block>
                +                                                                                                                                                                        </next>
                +                                                                                                                                                                      </block>
                +                                                                                                                                                                    </next>
                +                                                                                                                                                                  </block>
                +                                                                                                                                                                </next>
                +                                                                                                                                                              </block>
                +                                                                                                                                                            </next>
                +                                                                                                                                                          </block>
                +                                                                                                                                                        </next>
                +                                                                                                                                                      </block>
                +                                                                                                                                                    </next>
                +                                                                                                                                                  </block>
                +                                                                                                                                                </next>
                +                                                                                                                                              </block>
                +                                                                                                                                            </next>
                +                                                                                                                                          </block>
                +                                                                                                                                        </next>
                +                                                                                                                                      </block>
                +                                                                                                                                    </next>
                +                                                                                                                                  </block>
                +                                                                                                                                </next>
                +                                                                                                                              </block>
                +                                                                                                                            </next>
                +                                                                                                                          </block>
                +                                                                                                                        </next>
                +                                                                                                                      </block>
                +                                                                                                                    </next>
                +                                                                                                                  </block>
                +                                                                                                                </next>
                +                                                                                                              </block>
                +                                                                                                            </next>
                +                                                                                                          </block>
                +                                                                                                        </next>
                +                                                                                                      </block>
                +                                                                                                    </next>
                +                                                                                                  </block>
                +                                                                                                </next>
                +                                                                                              </block>
                +                                                                                            </next>
                +                                                                                          </block>
                +                                                                                        </next>
                +                                                                                      </block>
                +                                                                                    </next>
                +                                                                                  </block>
                +                                                                                </next>
                +                                                                              </block>
                +                                                                            </next>
                +                                                                          </block>
                +                                                                        </next>
                +                                                                      </block>
                +                                                                    </next>
                +                                                                  </block>
                +                                                                </next>
                +                                                              </block>
                +                                                            </next>
                +                                                          </block>
                +                                                        </next>
                +                                                      </block>
                +                                                    </next>
                +                                                  </block>
                +                                                </next>
                +                                              </block>
                +                                            </next>
                +                                          </block>
                +                                        </next>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="10838">
                +    <field name="NAME">test case</field>
                +    <comment pinned="false" h="80" w="160">Tests the "change casing" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">Hello World</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">uppercase</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_changeCase" inline="false">
                +                <field name="CASE">UPPERCASE</field>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">HELLO WORLD</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">uppercase order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_changeCase" inline="false">
                +                    <field name="CASE">UPPERCASE</field>
                +                    <value name="TEXT">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">HELLO WORLD</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="variables_set">
                +                    <field name="VAR">text</field>
                +                    <value name="VALUE">
                +                      <block type="text">
                +                        <field name="TEXT">Hello World</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">lowercase</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_changeCase" inline="false">
                +                            <field name="CASE">LOWERCASE</field>
                +                            <value name="TEXT">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">hello world</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">lowercase order</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_changeCase" inline="false">
                +                                <field name="CASE">LOWERCASE</field>
                +                                <value name="TEXT">
                +                                  <block type="logic_ternary" inline="true">
                +                                    <value name="IF">
                +                                      <block type="logic_boolean">
                +                                        <field name="BOOL">TRUE</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="THEN">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">text</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ELSE">
                +                                      <block type="logic_null"></block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">hello world</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="variables_set">
                +                                <field name="VAR">text</field>
                +                                <value name="VALUE">
                +                                  <block type="text">
                +                                    <field name="TEXT">heLLo WorlD</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">titlecase</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_changeCase" inline="false">
                +                                        <field name="CASE">TITLECASE</field>
                +                                        <value name="TEXT">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">text</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="text">
                +                                        <field name="TEXT">Hello World</field>
                +                                      </block>
                +                                    </value>
                +                                    <next>
                +                                      <block type="unittest_assertequals" inline="false">
                +                                        <value name="MESSAGE">
                +                                          <block type="text">
                +                                            <field name="TEXT">titlecase order</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ACTUAL">
                +                                          <block type="text_changeCase" inline="false">
                +                                            <field name="CASE">TITLECASE</field>
                +                                            <value name="TEXT">
                +                                              <block type="logic_ternary" inline="true">
                +                                                <value name="IF">
                +                                                  <block type="logic_boolean">
                +                                                    <field name="BOOL">TRUE</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="THEN">
                +                                                  <block type="variables_get">
                +                                                    <field name="VAR">text</field>
                +                                                  </block>
                +                                                </value>
                +                                                <value name="ELSE">
                +                                                  <block type="logic_null"></block>
                +                                                </value>
                +                                              </block>
                +                                            </value>
                +                                          </block>
                +                                        </value>
                +                                        <value name="EXPECTED">
                +                                          <block type="text">
                +                                            <field name="TEXT">Hello World</field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </next>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="11488">
                +    <field name="NAME">test trim</field>
                +    <comment pinned="false" h="80" w="160">Tests the "trim" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">   abc def   </field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">trim both</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_trim" inline="false">
                +                <field name="MODE">BOTH</field>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">abc def</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">trim both order</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_trim" inline="false">
                +                    <field name="MODE">BOTH</field>
                +                    <value name="TEXT">
                +                      <block type="logic_ternary" inline="true">
                +                        <value name="IF">
                +                          <block type="logic_boolean">
                +                            <field name="BOOL">TRUE</field>
                +                          </block>
                +                        </value>
                +                        <value name="THEN">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                        <value name="ELSE">
                +                          <block type="logic_null"></block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">abc def</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">trim left</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_trim" inline="false">
                +                        <field name="MODE">LEFT</field>
                +                        <value name="TEXT">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">abc def   </field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">trim left order</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_trim" inline="false">
                +                            <field name="MODE">LEFT</field>
                +                            <value name="TEXT">
                +                              <block type="logic_ternary" inline="true">
                +                                <value name="IF">
                +                                  <block type="logic_boolean">
                +                                    <field name="BOOL">TRUE</field>
                +                                  </block>
                +                                </value>
                +                                <value name="THEN">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ELSE">
                +                                  <block type="logic_null"></block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT">abc def   </field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">trim right</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_trim" inline="false">
                +                                <field name="MODE">RIGHT</field>
                +                                <value name="TEXT">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT">   abc def</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">trim right order</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_trim" inline="false">
                +                                    <field name="MODE">RIGHT</field>
                +                                    <value name="TEXT">
                +                                      <block type="logic_ternary" inline="true">
                +                                        <value name="IF">
                +                                          <block type="logic_boolean">
                +                                            <field name="BOOL">TRUE</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="THEN">
                +                                          <block type="variables_get">
                +                                            <field name="VAR">text</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="ELSE">
                +                                          <block type="logic_null"></block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT">   abc def</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="13" y="12088">
                +    <field name="NAME">test count</field>
                +    <comment pinned="false" h="80" w="160">Tests the "trim" block.</comment>
                +    <statement name="STACK">
                +      <block type="variables_set">
                +        <field name="VAR">text</field>
                +        <value name="VALUE">
                +          <block type="text">
                +            <field name="TEXT">woolloomooloo</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">len 1</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_count">
                +                <value name="SUB">
                +                  <block type="text">
                +                    <field name="TEXT">o</field>
                +                  </block>
                +                </value>
                +                <value name="TEXT">
                +                  <block type="variables_get">
                +                    <field name="VAR">text</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">8</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">len 2</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_count">
                +                    <value name="SUB">
                +                      <block type="text">
                +                        <field name="TEXT">oo</field>
                +                      </block>
                +                    </value>
                +                    <value name="TEXT">
                +                      <block type="variables_get">
                +                        <field name="VAR">text</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="math_number">
                +                    <field name="NUM">4</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">len 3</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_count">
                +                        <value name="SUB">
                +                          <block type="text">
                +                            <field name="TEXT">loo</field>
                +                          </block>
                +                        </value>
                +                        <value name="TEXT">
                +                          <block type="variables_get">
                +                            <field name="VAR">text</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">2</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">start</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_count">
                +                            <value name="SUB">
                +                              <block type="text">
                +                                <field name="TEXT">wool</field>
                +                              </block>
                +                            </value>
                +                            <value name="TEXT">
                +                              <block type="variables_get">
                +                                <field name="VAR">text</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="math_number">
                +                            <field name="NUM">1</field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">missing</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_count">
                +                                <value name="SUB">
                +                                  <block type="text">
                +                                    <field name="TEXT">chicken</field>
                +                                  </block>
                +                                </value>
                +                                <value name="TEXT">
                +                                  <block type="variables_get">
                +                                    <field name="VAR">text</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="math_number">
                +                                <field name="NUM">0</field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">empty needle</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_count">
                +                                    <value name="SUB">
                +                                      <block type="text">
                +                                        <field name="TEXT"></field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TEXT">
                +                                      <block type="variables_get">
                +                                        <field name="VAR">text</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="math_number">
                +                                    <field name="NUM">14</field>
                +                                  </block>
                +                                </value>
                +                                <next>
                +                                  <block type="unittest_assertequals" inline="false">
                +                                    <value name="MESSAGE">
                +                                      <block type="text">
                +                                        <field name="TEXT">empty source</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="ACTUAL">
                +                                      <block type="text_count">
                +                                        <value name="SUB">
                +                                          <block type="text">
                +                                            <field name="TEXT">chicken</field>
                +                                          </block>
                +                                        </value>
                +                                        <value name="TEXT">
                +                                          <block type="text">
                +                                            <field name="TEXT"></field>
                +                                          </block>
                +                                        </value>
                +                                      </block>
                +                                    </value>
                +                                    <value name="EXPECTED">
                +                                      <block type="math_number">
                +                                        <field name="NUM">0</field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </next>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="12" y="12812">
                +    <field name="NAME">test reverse</field>
                +    <comment pinned="false" h="80" w="160">Tests the "trim" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">empty string</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="text_reverse">
                +            <value name="TEXT">
                +              <block type="text">
                +                <field name="TEXT"></field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT"></field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">len 1</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_reverse">
                +                <value name="TEXT">
                +                  <block type="text">
                +                    <field name="TEXT">a</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">a</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">len 2</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_reverse">
                +                    <value name="TEXT">
                +                      <block type="text">
                +                        <field name="TEXT">ab</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">ba</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">longer</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_reverse">
                +                        <value name="TEXT">
                +                          <block type="text">
                +                            <field name="TEXT">woolloomooloo</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">ooloomoolloow</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="procedures_defnoreturn" x="12" y="13237">
                +    <field name="NAME">test replace</field>
                +    <comment pinned="false" h="80" w="160">Tests the "trim" block.</comment>
                +    <statement name="STACK">
                +      <block type="unittest_assertequals" inline="false">
                +        <value name="MESSAGE">
                +          <block type="text">
                +            <field name="TEXT">replace all instances 1</field>
                +          </block>
                +        </value>
                +        <value name="ACTUAL">
                +          <block type="text_replace">
                +            <value name="FROM">
                +              <block type="text">
                +                <field name="TEXT">oo</field>
                +              </block>
                +            </value>
                +            <value name="TO">
                +              <block type="text">
                +                <field name="TEXT">123</field>
                +              </block>
                +            </value>
                +            <value name="TEXT">
                +              <block type="text">
                +                <field name="TEXT">woolloomooloo</field>
                +              </block>
                +            </value>
                +          </block>
                +        </value>
                +        <value name="EXPECTED">
                +          <block type="text">
                +            <field name="TEXT">w123ll123m123l123</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +              <block type="text">
                +                <field name="TEXT">literal string replacement</field>
                +              </block>
                +            </value>
                +            <value name="ACTUAL">
                +              <block type="text_replace">
                +                <value name="FROM">
                +                  <block type="text">
                +                    <field name="TEXT">.oo</field>
                +                  </block>
                +                </value>
                +                <value name="TO">
                +                  <block type="text">
                +                    <field name="TEXT">X</field>
                +                  </block>
                +                </value>
                +                <value name="TEXT">
                +                  <block type="text">
                +                    <field name="TEXT">woolloomooloo</field>
                +                  </block>
                +                </value>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="text">
                +                <field name="TEXT">woolloomooloo</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="unittest_assertequals" inline="false">
                +                <value name="MESSAGE">
                +                  <block type="text">
                +                    <field name="TEXT">not found</field>
                +                  </block>
                +                </value>
                +                <value name="ACTUAL">
                +                  <block type="text_replace">
                +                    <value name="FROM">
                +                      <block type="text">
                +                        <field name="TEXT">abc</field>
                +                      </block>
                +                    </value>
                +                    <value name="TO">
                +                      <block type="text">
                +                        <field name="TEXT">X</field>
                +                      </block>
                +                    </value>
                +                    <value name="TEXT">
                +                      <block type="text">
                +                        <field name="TEXT">woolloomooloo</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </value>
                +                <value name="EXPECTED">
                +                  <block type="text">
                +                    <field name="TEXT">woolloomooloo</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                      <block type="text">
                +                        <field name="TEXT">empty replacement 1</field>
                +                      </block>
                +                    </value>
                +                    <value name="ACTUAL">
                +                      <block type="text_replace">
                +                        <value name="FROM">
                +                          <block type="text">
                +                            <field name="TEXT">o</field>
                +                          </block>
                +                        </value>
                +                        <value name="TO">
                +                          <block type="text">
                +                            <field name="TEXT"></field>
                +                          </block>
                +                        </value>
                +                        <value name="TEXT">
                +                          <block type="text">
                +                            <field name="TEXT">woolloomooloo</field>
                +                          </block>
                +                        </value>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="text">
                +                        <field name="TEXT">wllml</field>
                +                      </block>
                +                    </value>
                +                    <next>
                +                      <block type="unittest_assertequals" inline="false">
                +                        <value name="MESSAGE">
                +                          <block type="text">
                +                            <field name="TEXT">empty replacement 2</field>
                +                          </block>
                +                        </value>
                +                        <value name="ACTUAL">
                +                          <block type="text_replace">
                +                            <value name="FROM">
                +                              <block type="text">
                +                                <field name="TEXT">aaaaa</field>
                +                              </block>
                +                            </value>
                +                            <value name="TO">
                +                              <block type="text">
                +                                <field name="TEXT"></field>
                +                              </block>
                +                            </value>
                +                            <value name="TEXT">
                +                              <block type="text">
                +                                <field name="TEXT">aaaaa</field>
                +                              </block>
                +                            </value>
                +                          </block>
                +                        </value>
                +                        <value name="EXPECTED">
                +                          <block type="text">
                +                            <field name="TEXT"></field>
                +                          </block>
                +                        </value>
                +                        <next>
                +                          <block type="unittest_assertequals" inline="false">
                +                            <value name="MESSAGE">
                +                              <block type="text">
                +                                <field name="TEXT">empty replacement 3</field>
                +                              </block>
                +                            </value>
                +                            <value name="ACTUAL">
                +                              <block type="text_replace">
                +                                <value name="FROM">
                +                                  <block type="text">
                +                                    <field name="TEXT">a</field>
                +                                  </block>
                +                                </value>
                +                                <value name="TO">
                +                                  <block type="text">
                +                                    <field name="TEXT"></field>
                +                                  </block>
                +                                </value>
                +                                <value name="TEXT">
                +                                  <block type="text">
                +                                    <field name="TEXT">aaaaa</field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </value>
                +                            <value name="EXPECTED">
                +                              <block type="text">
                +                                <field name="TEXT"></field>
                +                              </block>
                +                            </value>
                +                            <next>
                +                              <block type="unittest_assertequals" inline="false">
                +                                <value name="MESSAGE">
                +                                  <block type="text">
                +                                    <field name="TEXT">empty source</field>
                +                                  </block>
                +                                </value>
                +                                <value name="ACTUAL">
                +                                  <block type="text_replace">
                +                                    <value name="FROM">
                +                                      <block type="text">
                +                                        <field name="TEXT">a</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TO">
                +                                      <block type="text">
                +                                        <field name="TEXT">chicken</field>
                +                                      </block>
                +                                    </value>
                +                                    <value name="TEXT">
                +                                      <block type="text">
                +                                        <field name="TEXT"></field>
                +                                      </block>
                +                                    </value>
                +                                  </block>
                +                                </value>
                +                                <value name="EXPECTED">
                +                                  <block type="text">
                +                                    <field name="TEXT"></field>
                +                                  </block>
                +                                </value>
                +                              </block>
                +                            </next>
                +                          </block>
                +                        </next>
                +                      </block>
                +                    </next>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +</xml>
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest.js b/blockly/webif/static/blockly/tests/generators/unittest.js
                new file mode 100644
                index 000000000..5c471d1b7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest.js
                @@ -0,0 +1,117 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Unit test blocks for Blockly.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Blocks['unittest_main'] = {
                +  // Container for unit tests.
                +  init: function() {
                +    this.setColour(65);
                +    this.appendDummyInput()
                +        .appendField('run tests');
                +    this.appendStatementInput('DO');
                +    this.setTooltip('Executes the enclosed unit tests,\n' +
                +                    'then prints a summary.');
                +  },
                +  getVars: function() {
                +    return ['unittestResults'];
                +  }
                +};
                +
                +Blockly.Blocks['unittest_assertequals'] = {
                +  // Asserts that a value equals another value.
                +  init: function() {
                +    this.setColour(65);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.appendValueInput('MESSAGE')
                +        .appendField('name')
                +        .setCheck('String');
                +    this.appendValueInput('ACTUAL')
                +        .appendField('actual');
                +    this.appendValueInput('EXPECTED')
                +        .appendField('expected');
                +    this.setTooltip('Tests that "actual == expected".');
                +  },
                +  getVars: function() {
                +    return ['unittestResults'];
                +  }
                +};
                +
                +Blockly.Blocks['unittest_assertvalue'] = {
                +  // Asserts that a value is true, false, or null.
                +  init: function() {
                +    this.setColour(65);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.appendValueInput('MESSAGE', 'test name')
                +        .appendField('name')
                +        .setCheck('String');
                +    this.appendValueInput('ACTUAL')
                +        .appendField('assert')
                +        .appendField(new Blockly.FieldDropdown(
                +        [['true', 'TRUE'], ['false', 'FALSE'], ['null', 'NULL']]), 'EXPECTED');
                +    this.setTooltip('Tests that the value is true, false, or null.');
                +  },
                +  getVars: function() {
                +    return ['unittestResults'];
                +  }
                +};
                +
                +Blockly.Blocks['unittest_fail'] = {
                +  // Always assert an error.
                +  init: function() {
                +    this.setColour(65);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.appendDummyInput()
                +        .appendField(new Blockly.FieldTextInput('test name'), 'MESSAGE')
                +        .appendField('fail');
                +    this.setTooltip('Records an error.');
                +  },
                +  getVars: function() {
                +    return ['unittestResults'];
                +  }
                +};
                +
                +Blockly.Blocks['unittest_adjustindex'] = {
                +  // Adjusts the indexing based on current setting.
                +  init: function() {
                +    this.jsonInit({
                +      "message0": "adjusted %1",
                +      "args0": [
                +        {
                +          "type": "input_value",
                +          "name": "INDEX",
                +          "check": "Number"
                +        }
                +      ],
                +      "inputsInline": true,
                +      "output": "Number",
                +      "colour": 65,
                +      "tooltip": "Adjusts the value based on whether generated code is using " +
                +          "zero or one based indexing."
                +    });
                +  }
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest_dart.js b/blockly/webif/static/blockly/tests/generators/unittest_dart.js
                new file mode 100644
                index 000000000..75b165df4
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest_dart.js
                @@ -0,0 +1,177 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Dart for unit test blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Dart['unittest_main'] = function(block) {
                +  // Container for unit tests.
                +  var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'unittest_report',
                +      [ 'String ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +        '  // Create test report.',
                +        '  List report = [];',
                +        '  StringBuffer summary = new StringBuffer();',
                +        '  int fails = 0;',
                +        '  for (int x = 0; x < ' + resultsVar + '.length; x++) {',
                +        '    if (' + resultsVar + '[x][0]) {',
                +        '      summary.write(".");',
                +        '    } else {',
                +        '      summary.write("F");',
                +        '      fails++;',
                +        '      report.add("");',
                +        '      report.add("FAIL: ${' + resultsVar + '[x][2]}");',
                +        '      report.add(' + resultsVar + '[x][1]);',
                +        '    }',
                +        '  }',
                +        '  report.insert(0, summary.toString());',
                +        '  report.add("");',
                +        '  report.add("Ran ${' + resultsVar + '.length} tests.");',
                +        '  report.add("");',
                +        '  if (fails != 0) {',
                +        '    report.add("FAILED (failures=$fails)");',
                +        '  } else {',
                +        '    report.add("OK");',
                +        '  }',
                +        '  return report.join("\\n");',
                +        '}']);
                +  // Setup global to hold test results.
                +  var code = resultsVar + ' = [];\n';
                +  // Run tests (unindented).
                +  code += Blockly.Dart.statementToCode(block, 'DO')
                +      .replace(/^  /, '').replace(/\n  /g, '\n');
                +  var reportVar = Blockly.Dart.variableDB_.getDistinctName(
                +      'report', Blockly.Variables.NAME_TYPE);
                +  code += 'String ' + reportVar + ' = ' + functionName + '();\n';
                +  // Destroy results.
                +  code += resultsVar + ' = null;\n';
                +  // Print the report to the console (that's where errors will go anyway).
                +  code += 'print(' + reportVar + ');\n';
                +  return code;
                +};
                +
                +Blockly.Dart['unittest_main'].defineAssert_ = function() {
                +  var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'unittest_assertequals',
                +      [ 'void ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(dynamic actual, dynamic expected, String message) {',
                +        '  // Asserts that a value equals another value.',
                +        '  if (' + resultsVar + ' == null) {',
                +        '    throw "Orphaned assert: ${message}";',
                +        '  }',
                +        '  bool equals(a, b) {',
                +        '    if (a == b) {',
                +        '      return true;',
                +        '    } else if (a is List && b is List) {',
                +        '      if (a.length != b.length) {',
                +        '        return false;',
                +        '      }',
                +        '      for (num i = 0; i < a.length; i++) {',
                +        '        if (!equals(a[i], b[i])) {',
                +        '          return false;',
                +        '        }',
                +        '      }',
                +        '      return true;',
                +        '    }',
                +        '    return false;',
                +        '  }',
                +        '  if (equals(actual, expected)) {',
                +        '    ' + resultsVar + '.add([true, "OK", message]);',
                +        '  } else {',
                +        '    ' + resultsVar + '.add([false, ' +
                +          '"Expected: $expected\\nActual: $actual", message]);',
                +        '  }',
                +        '}']);
                +  return functionName;
                +};
                +
                +Blockly.Dart['unittest_assertequals'] = function(block) {
                +  // Asserts that a value equals another value.
                +  var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
                +      Blockly.Dart.ORDER_NONE) || '';
                +  var actual = Blockly.Dart.valueToCode(block, 'ACTUAL',
                +      Blockly.Dart.ORDER_NONE) || 'null';
                +  var expected = Blockly.Dart.valueToCode(block, 'EXPECTED',
                +      Blockly.Dart.ORDER_NONE) || 'null';
                +  return Blockly.Dart['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.Dart['unittest_assertvalue'] = function(block) {
                +  // Asserts that a value is true, false, or null.
                +  var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
                +      Blockly.Dart.ORDER_NONE) || '';
                +  var actual = Blockly.Dart.valueToCode(block, 'ACTUAL',
                +      Blockly.Dart.ORDER_NONE) || 'null';
                +  var expected = block.getFieldValue('EXPECTED');
                +  if (expected == 'TRUE') {
                +    expected = 'true';
                +  } else if (expected == 'FALSE') {
                +    expected = 'false';
                +  } else if (expected == 'NULL') {
                +    expected = 'null';
                +  }
                +  return Blockly.Dart['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.Dart['unittest_fail'] = function(block) {
                +  // Always assert an error.
                +  var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var message = Blockly.Dart.valueToCode(block, 'MESSAGE',
                +      Blockly.Dart.ORDER_NONE) || '';
                +  var functionName = Blockly.Dart.provideFunction_(
                +      'unittest_fail',
                +      [ 'void ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(String message) {',
                +        '  // Always assert an error.',
                +        '  if (' + resultsVar + ' == null) {',
                +        '    throw "Orphaned assert fail: ${message}";',
                +        '  }',
                +        '  ' + resultsVar + '.add([false, "Fail.", message]);',
                +        '}']);
                +  return functionName + '(' + message + ');\n';
                +};
                +
                +Blockly.Dart['unittest_adjustindex'] = function(block) {
                +  var index = Blockly.Dart.valueToCode(block, 'INDEX',
                +      Blockly.Dart.ORDER_ADDITIVE) || '0';
                +  // Adjust index if using one-based indexing.
                +  if (block.workspace.options.oneBasedIndex) {
                +    if (Blockly.isNumber(index)) {
                +      // If the index is a naked number, adjust it right now.
                +      return [parseFloat(index) + 1, Blockly.Dart.ORDER_ATOMIC];
                +    } else {
                +      // If the index is dynamic, adjust it in code.
                +      index = index + ' + 1';
                +    }
                +  } else if (Blockly.isNumber(index)) {
                +    return [index, Blockly.Dart.ORDER_ATOMIC];
                +  }
                +  return [index, Blockly.Dart.ORDER_ADDITIVE];
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest_javascript.js b/blockly/webif/static/blockly/tests/generators/unittest_javascript.js
                new file mode 100644
                index 000000000..db9d62ff1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest_javascript.js
                @@ -0,0 +1,181 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating JavaScript for unit test blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.JavaScript['unittest_main'] = function(block) {
                +  // Container for unit tests.
                +  var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'unittest_report',
                +      [ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +        '  // Create test report.',
                +        '  var report = [];',
                +        '  var summary = [];',
                +        '  var fails = 0;',
                +        '  for (var i = 0; i < ' + resultsVar + '.length; i++) {',
                +        '    if (' + resultsVar + '[i][0]) {',
                +        '      summary.push(".");',
                +        '    } else {',
                +        '      summary.push("F");',
                +        '      fails++;',
                +        '      report.push("");',
                +        '      report.push("FAIL: " + ' + resultsVar + '[i][2]);',
                +        '      report.push(' + resultsVar + '[i][1]);',
                +        '    }',
                +        '  }',
                +        '  report.unshift(summary.join(""));',
                +        '  report.push("");',
                +        '  report.push("Number of tests run: " + ' + resultsVar +
                +              '.length);',
                +        '  report.push("");',
                +        '  if (fails) {',
                +        '    report.push("FAILED (failures=" + fails + ")");',
                +        '  } else {',
                +        '    report.push("OK");',
                +        '  }',
                +        '  return report.join("\\n");',
                +        '}']);
                +  // Setup global to hold test results.
                +  var code = resultsVar + ' = [];\n';
                +  // Run tests (unindented).
                +  code += Blockly.JavaScript.statementToCode(block, 'DO')
                +      .replace(/^  /, '').replace(/\n  /g, '\n');
                +  var reportVar = Blockly.JavaScript.variableDB_.getDistinctName(
                +      'report', Blockly.Variables.NAME_TYPE);
                +  code += 'var ' + reportVar + ' = ' + functionName + '();\n';
                +  // Destroy results.
                +  code += resultsVar + ' = null;\n';
                +  // Send the report to the console (that's where errors will go anyway).
                +  code += 'console.log(' + reportVar + ');\n';
                +  return code;
                +};
                +
                +Blockly.JavaScript['unittest_main'].defineAssert_ = function(block) {
                +  var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'assertEquals',
                +      [ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(actual, expected, message) {',
                +        '  // Asserts that a value equals another value.',
                +        '  if (!' + resultsVar + ') {',
                +        '    throw "Orphaned assert: " + message;',
                +        '  }',
                +        '  function equals(a, b) {',
                +        '    if (a === b) {',
                +        '      return true;',
                +        '    } else if ((typeof a == "number") && (typeof b == "number") &&',
                +        '        (a.toPrecision(15) == b.toPrecision(15))) {',
                +        '      return true;',
                +        '    } else if (a instanceof Array && b instanceof Array) {',
                +        '      if (a.length != b.length) {',
                +        '        return false;',
                +        '      }',
                +        '      for (var i = 0; i < a.length; i++) {',
                +        '        if (!equals(a[i], b[i])) {',
                +        '          return false;',
                +        '        }',
                +        '      }',
                +        '      return true;',
                +        '    }',
                +        '    return false;',
                +        '  }',
                +        '  if (equals(actual, expected)) {',
                +        '    ' + resultsVar + '.push([true, "OK", message]);',
                +        '  } else {',
                +        '    ' + resultsVar + '.push([false, ' +
                +          '"Expected: " + expected + "\\nActual: " + actual, message]);',
                +        '  }',
                +        '}']);
                +  return functionName;
                +};
                +
                +Blockly.JavaScript['unittest_assertequals'] = function(block) {
                +  // Asserts that a value equals another value.
                +  var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
                +      Blockly.JavaScript.ORDER_NONE) || '';
                +  var actual = Blockly.JavaScript.valueToCode(block, 'ACTUAL',
                +      Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  var expected = Blockly.JavaScript.valueToCode(block, 'EXPECTED',
                +      Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  return Blockly.JavaScript['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.JavaScript['unittest_assertvalue'] = function(block) {
                +  // Asserts that a value is true, false, or null.
                +  var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
                +      Blockly.JavaScript.ORDER_NONE) || '';
                +  var actual = Blockly.JavaScript.valueToCode(block, 'ACTUAL',
                +      Blockly.JavaScript.ORDER_COMMA) || 'null';
                +  var expected = block.getFieldValue('EXPECTED');
                +  if (expected == 'TRUE') {
                +    expected = 'true';
                +  } else if (expected == 'FALSE') {
                +    expected = 'false';
                +  } else if (expected == 'NULL') {
                +    expected = 'null';
                +  }
                +  return Blockly.JavaScript['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.JavaScript['unittest_fail'] = function(block) {
                +  // Always assert an error.
                +  var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE',
                +      Blockly.JavaScript.ORDER_NONE) || '';
                +  var functionName = Blockly.JavaScript.provideFunction_(
                +      'unittest_fail',
                +      [ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(message) {',
                +        '  // Always assert an error.',
                +        '  if (!' + resultsVar + ') {',
                +        '    throw "Orphaned assert fail: " + message;',
                +        '  }',
                +        '  ' + resultsVar + '.push([false, "Fail.", message]);',
                +        '}']);
                +  return functionName + '(' + message + ');\n';
                +};
                +
                +Blockly.JavaScript['unittest_adjustindex'] = function(block) {
                +  var index = Blockly.JavaScript.valueToCode(block, 'INDEX',
                +      Blockly.JavaScript.ORDER_ADDITION) || '0';
                +  // Adjust index if using one-based indexing.
                +  if (block.workspace.options.oneBasedIndex) {
                +    if (Blockly.isNumber(index)) {
                +      // If the index is a naked number, adjust it right now.
                +      return [parseFloat(index) + 1, Blockly.JavaScript.ORDER_ATOMIC];
                +    } else {
                +      // If the index is dynamic, adjust it in code.
                +      index = index + ' + 1';
                +    }
                +  } else if (Blockly.isNumber(index)) {
                +    return [index, Blockly.JavaScript.ORDER_ATOMIC];
                +  }
                +  return [index, Blockly.JavaScript.ORDER_ADDITION];
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest_lua.js b/blockly/webif/static/blockly/tests/generators/unittest_lua.js
                new file mode 100644
                index 000000000..d687b091b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest_lua.js
                @@ -0,0 +1,179 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Lua for unit test blocks.
                + * @author rodrigoq@google.com (Rodrigo Queiro)
                + */
                +'use strict';
                +
                +Blockly.Lua['unittest_main'] = function(block) {
                +  // Container for unit tests.
                +  var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'unittest_report',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '()',
                +       '  -- Create test report.',
                +       '  local report = {}',
                +       '  local summary = {}',
                +       '  local fails = 0',
                +       '  for _, v in pairs(' + resultsVar + ') do',
                +       '    if v["success"] then',
                +       '      table.insert(summary, ".")',
                +       '    else',
                +       '      table.insert(summary, "F")',
                +       '      fails = fails + 1',
                +       '      table.insert(report, "FAIL: " .. v["title"])',
                +       '      table.insert(report, v["log"])',
                +       '    end',
                +       '  end',
                +       '  table.insert(report, 1, table.concat(summary))',
                +       '  table.insert(report, "")',
                +       '  table.insert(report, "Number of tests run: " .. #' + resultsVar + ')',
                +       '  table.insert(report, "")',
                +       '  if fails > 0 then',
                +       '    table.insert(report, "FAILED (failures=" .. fails .. ")")',
                +       '  else',
                +       '    table.insert(report, "OK")',
                +       '  end',
                +       '  return table.concat(report, "\\n")',
                +       'end']);
                +  // Setup global to hold test results.
                +  var code = resultsVar + ' = {}\n';
                +  // Run tests (unindented).
                +  code += Blockly.Lua.statementToCode(block, 'DO')
                +      .replace(/^  /, '').replace(/\n  /g, '\n');
                +  var reportVar = Blockly.Lua.variableDB_.getDistinctName(
                +      'report', Blockly.Variables.NAME_TYPE);
                +  code += reportVar + ' = ' + functionName + '()\n';
                +  // Destroy results.
                +  code += resultsVar + ' = nil\n';
                +  // Print the report.
                +  code += 'print(' + reportVar + ')\n';
                +  return code;
                +};
                +
                +Blockly.Lua['unittest_main'].defineAssert_ = function(block) {
                +  var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'assertEquals',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
                +           '(actual, expected, message)',
                +       '  -- Asserts that a value equals another value.',
                +       '  assert(' + resultsVar + ' ~= nil, ' +
                +           '"Orphaned assert equals: " ..  message)',
                +       '  if type(actual) == "table" and type(expected) == "table" then',
                +       '    local lists_match = #actual == #expected',
                +       '    if lists_match then',
                +       '      for i, v1 in ipairs(actual) do',
                +       '        local v2 = expected[i]',
                +       '        if type(v1) == "number" and type(v2) == "number" then',
                +       '          if math.abs(v1 - v2) > 1e-9 then',
                +       '            lists_match = false',
                +       '          end',
                +       '        elseif v1 ~= v2 then',
                +       '          lists_match = false',
                +       '        end',
                +       '      end',
                +       '    end',
                +       '    if lists_match then',
                +       '      table.insert(' + resultsVar +
                +           ', {success=true, log="OK", title=message})',
                +       '      return',
                +       '    else',
                +       '      -- produce the non-matching strings for a human-readable error',
                +       '      expected = "{" .. table.concat(expected, ", ") .. "}"',
                +       '      actual = "{" .. table.concat(actual, ", ") .. "}"',
                +       '    end',
                +       '  end',
                +       '  if actual == expected or (type(actual) == "number" and ' +
                +          'type(expected) == "number" and math.abs(actual - expected) < ' +
                +          '1e-9) then ',
                +       '    table.insert(' + resultsVar +
                +           ', {success=true, log="OK", title=message})',
                +       '  else',
                +       '    table.insert(' + resultsVar + ', {success=false, ' +
                +           'log=string.format("Expected: %s\\nActual: %s"' +
                +               ', tostring(expected), tostring(actual)), title=message})',
                +       '  end',
                +       'end']);
                +  return functionName;
                +};
                +
                +Blockly.Lua['unittest_assertequals'] = function(block) {
                +  // Asserts that a value equals another value.
                +  var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
                +      Blockly.Lua.ORDER_NONE) || '';
                +  var actual = Blockly.Lua.valueToCode(block, 'ACTUAL',
                +      Blockly.Lua.ORDER_NONE) || 'nil';
                +  var expected = Blockly.Lua.valueToCode(block, 'EXPECTED',
                +      Blockly.Lua.ORDER_NONE) || 'nil';
                +  return Blockly.Lua['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ')\n';
                +};
                +
                +Blockly.Lua['unittest_assertvalue'] = function(block) {
                +  // Asserts that a value is true, false, or null.
                +  var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
                +      Blockly.Lua.ORDER_NONE) || '';
                +  var actual = Blockly.Lua.valueToCode(block, 'ACTUAL',
                +      Blockly.Lua.ORDER_NONE) || 'nil';
                +  var expected = block.getFieldValue('EXPECTED');
                +  if (expected == 'TRUE') {
                +    expected = 'true';
                +  } else if (expected == 'FALSE') {
                +    expected = 'false';
                +  } else if (expected == 'NULL') {
                +    expected = 'nil';
                +  }
                +  return Blockly.Lua.unittest_main.defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ')\n';
                +};
                +
                +Blockly.Lua['unittest_fail'] = function(block) {
                +  // Always assert an error.
                +  var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var message = Blockly.Lua.valueToCode(block, 'MESSAGE',
                +      Blockly.Lua.ORDER_NONE) || '';
                +  var functionName = Blockly.Lua.provideFunction_(
                +      'unittest_fail',
                +      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(message)',
                +       '  -- Always assert an error.',
                +       '  assert(' + resultsVar +
                +           ' ~= nil, "Orphaned assert fail: " .. message)',
                +       '  table.insert(' + resultsVar +
                +           ', {success=false, log="Fail.", title=message})',
                +       'end']);
                +  return functionName + '(' + message + ')\n';
                +};
                +
                +Blockly.Lua['unittest_adjustindex'] = function(block) {
                +  var index = Blockly.Lua.valueToCode(block, 'INDEX',
                +      Blockly.Lua.ORDER_ADDITIVE) || '0';
                +  if (Blockly.isNumber(index)) {
                +    // If the index is a naked number, adjust it right now.
                +    return [parseFloat(index) + 1, Blockly.Lua.ORDER_ATOMIC];
                +  }
                +  // If the index is dynamic, adjust it in code.
                +  return [index + ' + 1', Blockly.Lua.ORDER_ATOMIC];
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest_php.js b/blockly/webif/static/blockly/tests/generators/unittest_php.js
                new file mode 100644
                index 000000000..28e6b2799
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest_php.js
                @@ -0,0 +1,187 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating PHP for unit test blocks.
                + * @author daarond@gmail.com (Daaron Dwyer)
                + */
                +'use strict';
                +
                +Blockly.PHP['unittest_main'] = function(block) {
                +    // Container for unit tests.
                +    var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
                +        Blockly.Variables.NAME_TYPE);
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'unittest_report',
                +        [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {',
                +            'global ' + resultsVar + ';',
                +            '  // Create test report.',
                +            '  $report = array();',
                +            '  $summary = array();',
                +            '  $fails = 0;',
                +            '  for ($x = 0; $x < count(' + resultsVar + '); $x++) {',
                +            '    if (' + resultsVar + '[$x][0]) {',
                +            '      array_push($summary, ".");',
                +            '    } else {',
                +            '      array_push($summary, "F");',
                +            '      $fails++;',
                +            '      array_push($report,"");',
                +            '      array_push($report, "FAIL: " . ' + resultsVar + '[$x][2]);',
                +            '      array_push($report, ' + resultsVar + '[$x][1]);',
                +            '    }',
                +            '  }',
                +            '  array_unshift($report, implode("",$summary));',
                +            '  array_push($report, "");',
                +            '  array_push($report, "Number of tests run: " . count(' + resultsVar + '));',
                +            '  array_push($report, "");',
                +            '  if ($fails) {',
                +            '    array_push($report, "FAILED (failures=" . $fails + ")");',
                +            '  } else {',
                +            '    array_push($report, "OK");',
                +            '  }',
                +            '  return implode("\\n", $report);',
                +            '}']);
                +    // Setup global to hold test results.
                +    var code = resultsVar + ' = array();\n';
                +    // Run tests (unindented).
                +    code += Blockly.PHP.statementToCode(block, 'DO')
                +        .replace(/^  /, '').replace(/\n  /g, '\n');
                +    var reportVar = Blockly.PHP.variableDB_.getDistinctName(
                +        'report', Blockly.Variables.NAME_TYPE);
                +    code += reportVar + ' = ' + functionName + '();\n';
                +    // Destroy results.
                +    code += resultsVar + ' = null;\n';
                +    // Send the report to the console (that's where errors will go anyway).
                +    code += 'print(' + reportVar + ');\n';
                +    return code;
                +};
                +
                +Blockly.PHP['unittest_main'].defineAssert_ = function(block) {
                +    var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
                +        Blockly.Variables.NAME_TYPE);
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'assertEquals',
                +       ['  function equals($a, $b) {',
                +        '    if ($a === $b) {',
                +        '      return true;',
                +        '    } else if ((is_numeric($a)) && (is_numeric($b)) &&',
                +        '        (round($a,15) == round($b,15))) {',
                +        '      return true;',
                +        '    } else if (is_array($a) && is_array($b)) {',
                +        '      if (count($a) != count($b)) {',
                +        '        return false;',
                +        '      }',
                +        '      for ($i = 0; $i < count($a); $i++) {',
                +        '        if (!equals($a[$i], $b[$i])) {',
                +        '          return false;',
                +        '        }',
                +        '      }',
                +        '      return true;',
                +        '    }',
                +        '    return false;',
                +        '  }',
                +        'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +        '($actual, $expected, $message) {',
                +        'global ' + resultsVar + ';',
                +        '  // Asserts that a value equals another value.',
                +        '  if (!is_array(' + resultsVar + ')) {',
                +        '    throw new Exception("Orphaned assert: " . $message);',
                +        '  }',
                +        '  if (equals($actual, $expected)) {',
                +        '    array_push(' + resultsVar + ', [true, "OK", $message]);',
                +        '  } else {',
                +        '    $expected = is_array($expected) ? implode(" ", $expected) : ' +
                +            '$expected;',
                +        '    $actual = is_array($actual) ? implode(" ", $actual) : ' +
                +            '$actual;',
                +        '    array_push(' + resultsVar + ', [false, ' +
                +        '"Expected: " . $expected . "\\nActual: " . $actual, $message]);',
                +        '  }',
                +        '}']);
                +    return functionName;
                +};
                +
                +Blockly.PHP['unittest_assertequals'] = function(block) {
                +    // Asserts that a value equals another value.
                +    var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
                +      Blockly.PHP.ORDER_NONE) || '';
                +    var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
                +            Blockly.PHP.ORDER_COMMA) || 'null';
                +    var expected = Blockly.PHP.valueToCode(block, 'EXPECTED',
                +            Blockly.PHP.ORDER_COMMA) || 'null';
                +    return Blockly.PHP['unittest_main'].defineAssert_() +
                +        '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.PHP['unittest_assertvalue'] = function(block) {
                +    // Asserts that a value is true, false, or null.
                +    var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
                +      Blockly.PHP.ORDER_NONE) || '';
                +    var actual = Blockly.PHP.valueToCode(block, 'ACTUAL',
                +            Blockly.PHP.ORDER_COMMA) || 'null';
                +    var expected = block.getFieldValue('EXPECTED');
                +    if (expected == 'TRUE') {
                +        expected = 'true';
                +    } else if (expected == 'FALSE') {
                +        expected = 'false';
                +    } else if (expected == 'NULL') {
                +        expected = 'null';
                +    }
                +    return Blockly.PHP['unittest_main'].defineAssert_() +
                +        '(' + actual + ', ' + expected + ', ' + message + ');\n';
                +};
                +
                +Blockly.PHP['unittest_fail'] = function(block) {
                +    // Always assert an error.
                +    var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults',
                +        Blockly.Variables.NAME_TYPE);
                +    var message = Blockly.PHP.valueToCode(block, 'MESSAGE',
                +      Blockly.PHP.ORDER_NONE) || '';
                +    var functionName = Blockly.PHP.provideFunction_(
                +        'unittest_fail',
                +        [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ +
                +        '($message) {',
                +            'global ' + resultsVar + ';',
                +            '  // Always assert an error.',
                +            '  if (!' + resultsVar + ') {',
                +            '    throw new Exception("Orphaned assert fail: " . $message);',
                +            '  }',
                +            '  array_push(' + resultsVar + ', [false, "Fail.", $message]);',
                +            '}']);
                +    return functionName + '(' + message + ');\n';
                +};
                +
                +Blockly.PHP['unittest_adjustindex'] = function(block) {
                +  var index = Blockly.PHP.valueToCode(block, 'INDEX',
                +      Blockly.PHP.ORDER_ADDITION) || '0';
                +  // Adjust index if using one-based indexing.
                +  if (block.workspace.options.oneBasedIndex) {
                +    if (Blockly.isNumber(index)) {
                +      // If the index is a naked number, adjust it right now.
                +      return [parseFloat(index) + 1, Blockly.PHP.ORDER_ATOMIC];
                +    } else {
                +      // If the index is dynamic, adjust it in code.
                +      index = index + ' + 1';
                +    }
                +  } else if (Blockly.isNumber(index)) {
                +    return [index, Blockly.PHP.ORDER_ATOMIC];
                +  }
                +  return [index, Blockly.PHP.ORDER_ADDITION];
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/unittest_python.js b/blockly/webif/static/blockly/tests/generators/unittest_python.js
                new file mode 100644
                index 000000000..7fbe313b1
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/unittest_python.js
                @@ -0,0 +1,152 @@
                +/**
                + * @license
                + * Visual Blocks Language
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Generating Python for unit test blocks.
                + * @author fraser@google.com (Neil Fraser)
                + */
                +'use strict';
                +
                +Blockly.Python['unittest_main'] = function(block) {
                +  // Container for unit tests.
                +  var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Python.provideFunction_(
                +      'unittest_report',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '():',
                +       '  # Create test report.',
                +       '  report = []',
                +       '  summary = []',
                +       '  fails = 0',
                +       '  for (success, log, message) in ' + resultsVar + ':',
                +       '    if success:',
                +       '      summary.append(".")',
                +       '    else:',
                +       '      summary.append("F")',
                +       '      fails += 1',
                +       '      report.append("")',
                +       '      report.append("FAIL: " + message)',
                +       '      report.append(log)',
                +       '  report.insert(0, "".join(summary))',
                +       '  report.append("")',
                +       '  report.append("Number of tests run: %d" % len(' + resultsVar + '))',
                +       '  report.append("")',
                +       '  if fails:',
                +       '    report.append("FAILED (failures=%d)" % fails)',
                +       '  else:',
                +       '    report.append("OK")',
                +       '  return "\\n".join(report)']);
                +
                +  // Setup global to hold test results.
                +  var code = resultsVar + ' = []\n';
                +  // Run tests (unindented).
                +  code += Blockly.Python.statementToCode(block, 'DO')
                +      .replace(/^  /, '').replace(/\n  /g, '\n');
                +  var reportVar = Blockly.Python.variableDB_.getDistinctName(
                +      'report', Blockly.Variables.NAME_TYPE);
                +  code += reportVar + ' = ' + functionName + '()\n';
                +  // Destroy results.
                +  code += resultsVar + ' = None\n';
                +  // Print the report.
                +  code += 'print(' + reportVar + ')\n';
                +  return code;
                +};
                +
                +Blockly.Python['unittest_main'].defineAssert_ = function() {
                +  var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var functionName = Blockly.Python.provideFunction_(
                +      'assertEquals',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ +
                +          '(actual, expected, message):',
                +       '  # Asserts that a value equals another value.',
                +       '  if ' + resultsVar + ' == None:',
                +       '    raise Exception("Orphaned assert equals: " + message)',
                +       '  if actual == expected:',
                +       '    ' + resultsVar + '.append((True, "OK", message))',
                +       '  else:',
                +       '    ' + resultsVar + '.append((False, ' +
                +           '"Expected: %s\\nActual: %s" % (expected, actual), message))']);
                +  return functionName;
                +};
                +
                +Blockly.Python['unittest_assertequals'] = function(block) {
                +  // Asserts that a value equals another value.
                +  var message = Blockly.Python.valueToCode(block, 'MESSAGE',
                +      Blockly.Python.ORDER_NONE) || '';
                +  var actual = Blockly.Python.valueToCode(block, 'ACTUAL',
                +      Blockly.Python.ORDER_NONE) || 'None';
                +  var expected = Blockly.Python.valueToCode(block, 'EXPECTED',
                +      Blockly.Python.ORDER_NONE) || 'None';
                +  return Blockly.Python['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ')\n';
                +};
                +
                +Blockly.Python['unittest_assertvalue'] = function(block) {
                +  // Asserts that a value is true, false, or null.
                +  var message = Blockly.Python.valueToCode(block, 'MESSAGE',
                +      Blockly.Python.ORDER_NONE) || '';
                +  var actual = Blockly.Python.valueToCode(block, 'ACTUAL',
                +      Blockly.Python.ORDER_NONE) || 'None';
                +  var expected = block.getFieldValue('EXPECTED');
                +  if (expected == 'TRUE') {
                +    expected = 'True';
                +  } else if (expected == 'FALSE') {
                +    expected = 'False';
                +  } else if (expected == 'NULL') {
                +    expected = 'None';
                +  }
                +  return Blockly.Python['unittest_main'].defineAssert_() +
                +      '(' + actual + ', ' + expected + ', ' + message + ')\n';
                +};
                +
                +Blockly.Python['unittest_fail'] = function(block) {
                +  // Always assert an error.
                +  var resultsVar = Blockly.Python.variableDB_.getName('unittestResults',
                +      Blockly.Variables.NAME_TYPE);
                +  var message = Blockly.Python.valueToCode(block, 'MESSAGE',
                +      Blockly.Python.ORDER_NONE) || '';
                +  var functionName = Blockly.Python.provideFunction_(
                +      'fail',
                +      ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(message):',
                +       '  # Always assert an error.',
                +       '  if ' + resultsVar + ' == None:',
                +       '    raise Exception("Orphaned assert equals: " + message)',
                +       '  ' + resultsVar + '.append((False, "Fail.", message))']);
                +  return functionName + '(' + message + ')\n';
                +};
                +
                +Blockly.Python['unittest_adjustindex'] = function(block) {
                +  var index = Blockly.Python.valueToCode(block, 'INDEX',
                +      Blockly.Python.ORDER_ADDITIVE) || '0';
                +  // Adjust index if using one-based indexing.
                +  if (block.workspace.options.oneBasedIndex) {
                +    if (Blockly.isNumber(index)) {
                +      // If the index is a naked number, adjust it right now.
                +      return [parseFloat(index) + 1, Blockly.Python.ORDER_ATOMIC];
                +    } else {
                +      // If the index is dynamic, adjust it in code.
                +      index = index + ' + 1';
                +    }
                +  } else if (Blockly.isNumber(index)) {
                +    return [index, Blockly.Python.ORDER_ATOMIC];
                +  }
                +  return [index, Blockly.Python.ORDER_ADDITIVE];
                +};
                diff --git a/blockly/webif/static/blockly/tests/generators/variables.xml b/blockly/webif/static/blockly/tests/generators/variables.xml
                new file mode 100644
                index 000000000..a11d0a01a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/generators/variables.xml
                @@ -0,0 +1,66 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml">
                +  <block type="unittest_main" x="0" y="0">
                +    <statement name="DO">
                +      <block type="variables_set" inline="false">
                +        <field name="VAR">item</field>
                +        <value name="VALUE">
                +          <block type="math_number">
                +            <field name="NUM">123</field>
                +          </block>
                +        </value>
                +        <next>
                +          <block type="unittest_assertequals" inline="false">
                +            <value name="MESSAGE">
                +               <block type="text">
                +                 <field name="TEXT">variable</field>
                +               </block>
                +             </value>
                +            <value name="ACTUAL">
                +              <block type="variables_get">
                +                <field name="VAR">item</field>
                +              </block>
                +            </value>
                +            <value name="EXPECTED">
                +              <block type="math_number">
                +                <field name="NUM">123</field>
                +              </block>
                +            </value>
                +            <next>
                +              <block type="variables_set" inline="false">
                +                <field name="VAR">if</field>
                +                <value name="VALUE">
                +                  <block type="math_number">
                +                    <field name="NUM">123</field>
                +                  </block>
                +                </value>
                +                <next>
                +                  <block type="unittest_assertequals" inline="false">
                +                    <value name="MESSAGE">
                +                       <block type="text">
                +                         <field name="TEXT">reserved variable</field>
                +                       </block>
                +                     </value>
                +                    <value name="ACTUAL">
                +                      <block type="variables_get">
                +                        <field name="VAR">if</field>
                +                      </block>
                +                    </value>
                +                    <value name="EXPECTED">
                +                      <block type="math_number">
                +                        <field name="NUM">123</field>
                +                      </block>
                +                    </value>
                +                  </block>
                +                </next>
                +              </block>
                +            </next>
                +          </block>
                +        </next>
                +      </block>
                +    </statement>
                +  </block>
                +  <block type="variables_get" x="300" y="100">
                +    <field name="VAR">naked</field>
                +    <comment pinned="true" h="80" w="160">Intentionally non-connected variable.</comment>
                +  </block>
                +</xml>
                diff --git a/blockly/webif/static/blockly/tests/jsunit/connection_db_test.js b/blockly/webif/static/blockly/tests/jsunit/connection_db_test.js
                new file mode 100644
                index 000000000..558edf100
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/connection_db_test.js
                @@ -0,0 +1,307 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2015 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function verify_DB_(msg, expected, db) {
                +   var equal = (expected.length == db.length);
                +   if (equal) {
                +     for (var i = 0; i < expected.length; i++) {
                +       if (expected[i] != db[i]) {
                +         equal = false;
                +         break;
                +       }
                +     }
                +   }
                +   if (equal) {
                +     assertTrue(msg, true);
                +   } else {
                +     assertEquals(msg, expected, db);
                +   }
                +}
                +
                +function test_DB_addConnection() {
                +  var db = new Blockly.ConnectionDB();
                +  var o2 = {y_: 2, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o2);
                +  verify_DB_('Adding connection #2', [o2], db);
                +
                +  var o4 = {y_: 4, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o4);
                +  verify_DB_('Adding connection #4', [o2, o4], db);
                +
                +  var o1 = {y_: 1, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o1);
                +  verify_DB_('Adding connection #1', [o1, o2, o4], db);
                +
                +  var o3a = {y_: 3, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o3a);
                +  verify_DB_('Adding connection #3a', [o1, o2, o3a, o4], db);
                +
                +  var o3b = {y_: 3, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o3b);
                +  verify_DB_('Adding connection #3b', [o1, o2, o3b, o3a, o4], db);
                +}
                +
                +function test_DB_removeConnection() {
                +  var db = new Blockly.ConnectionDB();
                +  var o1 = {y_: 1, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  var o2 = {y_: 2, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  var o3a = {y_: 3, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  var o3b = {y_: 3, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  var o3c = {y_: 3, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  var o4 = {y_: 4, sourceBlock_: {},
                +      getSourceBlock: Blockly.Connection.prototype.getSourceBlock};
                +  db.addConnection(o1);
                +  db.addConnection(o2);
                +  db.addConnection(o3c);
                +  db.addConnection(o3b);
                +  db.addConnection(o3a);
                +  db.addConnection(o4);
                +  verify_DB_('Adding connections 1-4', [o1, o2, o3a, o3b, o3c, o4], db);
                +
                +  db.removeConnection_(o2);
                +  verify_DB_('Removing connection #2', [o1, o3a, o3b, o3c, o4], db);
                +
                +  db.removeConnection_(o4);
                +  verify_DB_('Removing connection #4', [o1, o3a, o3b, o3c], db);
                +
                +  db.removeConnection_(o1);
                +  verify_DB_('Removing connection #1', [o3a, o3b, o3c], db);
                +
                +  db.removeConnection_(o3a);
                +  verify_DB_('Removing connection #3a', [o3b, o3c], db);
                +
                +  db.removeConnection_(o3c);
                +  verify_DB_('Removing connection #3c', [o3b], db);
                +
                +  db.removeConnection_(o3b);
                +  verify_DB_('Removing connection #3b', [], db);
                +}
                +
                +function test_DB_getNeighbours() {
                +  var db = new Blockly.ConnectionDB();
                +
                +  // Search an empty list.
                +  assertEquals(helper_getNeighbours(db,
                +      10 /* x */, 10 /* y */, 100 /* radius */).length, 0);
                +
                +  // Set up some connections.
                +  for (var i = 0; i < 10; i++) {
                +    db.addConnection(helper_createConnection(0, i,
                +        Blockly.PREVIOUS_STATEMENT, null, true));
                +  }
                +
                +  // Test block belongs at beginning.
                +  var result = helper_getNeighbours(db, 0, 0, 4);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +    assertNotEquals(result.indexOf(db[i]), -1); // contains
                +  }
                +
                +  // Test block belongs at middle.
                +  result = helper_getNeighbours(db, 0, 4, 2);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +    assertNotEquals(result.indexOf(db[i + 2]), -1); // contains
                +  }
                +
                +  // Test block belongs at end.
                +  result = helper_getNeighbours(db, 0, 9, 4);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +    assertNotEquals(result.indexOf(db[i + 5]), -1); // contains
                +  }
                +
                +  // Test block has no neighbours due to being out of range in the x direction.
                +  result = helper_getNeighbours(db, 10, 9, 4);
                +  assertEquals(result.length, 0);
                +
                +  // Test block has no neighbours due to being out of range in the y direction.
                +  result = helper_getNeighbours(db, 0, 19, 4);
                +  assertEquals(result.length, 0);
                +
                +  // Test block has no neighbours due to being out of range diagonally.
                +  result = helper_getNeighbours(db, -2, -2, 2);
                +  assertEquals(result.length, 0);
                +}
                +
                +function test_DB_findPositionForConnection() {
                +  var db = new Blockly.ConnectionDB();
                +  db.addConnection(helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT,
                +      null, true));
                +  db.addConnection(helper_createConnection(0, 1, Blockly.PREVIOUS_STATEMENT,
                +      null, true));
                +  db.addConnection(helper_createConnection(0, 2, Blockly.PREVIOUS_STATEMENT,
                +      null, true));
                +  db.addConnection(helper_createConnection(0, 4, Blockly.PREVIOUS_STATEMENT,
                +      null, true));
                +  db.addConnection(helper_createConnection(0, 5, Blockly.PREVIOUS_STATEMENT,
                +      null, true));
                +
                +  assertEquals(5, db.length);
                +  var conn = helper_createConnection(0, 3, Blockly.PREVIOUS_STATEMENT, null,
                +      true);
                +  assertEquals(3, db.findPositionForConnection_(conn));
                +}
                +
                +function test_DB_findConnection() {
                +  var db = new Blockly.ConnectionDB();
                +  for (var i = 0; i < 10; i++) {
                +    db.addConnection(helper_createConnection(i, 0,
                +        Blockly.PREVIOUS_STATEMENT, null, true));
                +    db.addConnection(helper_createConnection(0, i,
                +        Blockly.PREVIOUS_STATEMENT, null, true));
                +  }
                +
                +  var conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null,
                +      true);
                +  db.addConnection(conn);
                +  assertEquals(conn, db[db.findConnection(conn)]);
                +
                +  conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null, true);
                +  assertEquals(-1, db.findConnection(conn));
                +}
                +
                +function test_DB_ordering() {
                +  var db = new Blockly.ConnectionDB();
                +  for (var i = 0; i < 10; i++) {
                +    db.addConnection(helper_createConnection(0, 9 - i,
                +        Blockly.PREVIOUS_STATEMENT), null, true);
                +  }
                +
                +  for (i = 0; i < 10; i++) {
                +      assertEquals(i, db[i].y_);
                +  }
                +
                +  // quasi-random
                +  var xCoords = [-29, -47, -77, 2, 43, 34, -59, -52, -90, -36, -91, 38, 87, -20,
                +      60, 4, -57, 65, -37, -81, 57, 58, -96, 1, 67, -79, 34, 93, -90, -99, -62,
                +      4, 11, -36, -51, -72, 3, -50, -24, -45, -92, -38, 37, 24, -47, -73, 79,
                +      -20, 99, 43, -10, -87, 19, 35, -62, -36, 49, 86, -24, -47, -89, 33, -44,
                +      25, -73, -91, 85, 6, 0, 89, -94, 36, -35, 84, -9, 96, -21, 52, 10, -95, 7,
                +      -67, -70, 62, 9, -40, -95, -9, -94, 55, 57, -96, 55, 8, -48, -57, -87, 81,
                +      23, 65];
                +  var yCoords = [-81, 82, 5, 47, 30, 57, -12, 28, 38, 92, -25, -20, 23, -51, 73,
                +      -90, 8, 28, -51, -15, 81, -60, -6, -16, 77, -62, -42, -24, 35, 95, -46,
                +      -7, 61, -16, 14, 91, 57, -38, 27, -39, 92, 47, -98, 11, -33, -72, 64, 38,
                +      -64, -88, -35, -59, -76, -94, 45, -25, -100, -95, 63, -97, 45, 98, 99, 34,
                +      27, 52, -18, -45, 66, -32, -38, 70, -73, -23, 5, -2, -13, -9, 48, 74, -97,
                +      -11, 35, -79, -16, -77, 83, -57, -53, 35, -44, 100, -27, -15, 5, 39, 33,
                +      -19, -20, -95];
                +  for (i = 0; i < xCoords.length; i++) {
                +    db.addConnection(helper_createConnection(xCoords[i], yCoords[i],
                +        Blockly.PREVIOUS_STATEMENT), null, true);
                +  }
                +
                +  for (i = 1; i < xCoords.length; i++) {
                +    assertTrue(db[i].y_ >= db[i - 1].y_);
                +  }
                +}
                +
                +function test_SearchForClosest() {
                +  var db = new Blockly.ConnectionDB();
                +  var sharedWorkspace = {id: "Shared workspace"};
                +
                +  // Search an empty list.
                +  assertEquals(null, helper_searchDB(db, 10 /* x */, 10 /* y */,
                +      100 /* radius */));
                +
                +  db.addConnection(helper_createConnection(100, 0, Blockly.PREVIOUS_STATEMENT,
                +      sharedWorkspace, true));
                +  assertEquals(null, helper_searchDB(db, 0, 0, 5, sharedWorkspace));
                +
                +  db = new Blockly.ConnectionDB();
                +  for (var i = 0; i < 10; i++) {
                +    var tempConn = helper_createConnection(0, i, Blockly.PREVIOUS_STATEMENT,
                +        sharedWorkspace, true);
                +    tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +    db.addConnection(tempConn);
                +  }
                +
                +  // Should be at 0, 9.
                +  var last = db[db.length - 1];
                +  // Correct connection is last in db; many connections in radius.
                +  assertEquals(last, helper_searchDB(db, 0, 10, 15, sharedWorkspace));
                +  // Nothing nearby.
                +  assertEquals(null, helper_searchDB(db, 100, 100, 3, sharedWorkspace));
                +  // First in db, exact match.
                +  assertEquals(db[0], helper_searchDB(db, 0, 0, 0, sharedWorkspace));
                +
                +  tempConn = helper_createConnection(6, 6, Blockly.PREVIOUS_STATEMENT,
                +      sharedWorkspace, true);
                +  tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +  db.addConnection(tempConn);
                +  tempConn = helper_createConnection(5, 5, Blockly.PREVIOUS_STATEMENT,
                +      sharedWorkspace, true);
                +  tempConn.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +  db.addConnection(tempConn);
                +
                +  var result = helper_searchDB(db, 4, 6, 3, sharedWorkspace);
                +  assertEquals(5, result.x_);
                +  assertEquals(5, result.y_);
                +}
                +
                +
                +function helper_getNeighbours(db, x, y, radius) {
                +  return db.getNeighbours(helper_createConnection(x, y, Blockly.NEXT_STATEMENT,
                +    null, true),
                +      radius);
                +}
                +
                +function helper_searchDB(db, x, y, radius, shared_workspace) {
                +  var tempConn = helper_createConnection(x, y,
                +      Blockly.NEXT_STATEMENT, shared_workspace, true);
                +  tempConn.sourceBlock_ = helper_makeSourceBlock(shared_workspace);
                +  var closest = db.searchForClosest(tempConn, radius, {x: 0, y: 0});
                +  return closest.connection;
                +}
                +
                +function helper_makeSourceBlock(sharedWorkspace) {
                +  return {workspace: sharedWorkspace,
                +    parentBlock_: null,
                +    getParent: function() { return null; },
                +    movable_: true,
                +    isMovable: function() { return true; },
                +    isShadow: function() { return false; }
                +  };
                +}
                +
                +function helper_createConnection(x, y, type, opt_shared_workspace,
                +    opt_rendered) {
                +  var workspace = opt_shared_workspace ? opt_shared_workspace : {};
                +  if (opt_rendered) {
                +    var conn = new Blockly.RenderedConnection({workspace: workspace}, type);
                +  } else {
                +    var conn = new Blockly.Connection({workspace: workspace}, type);
                +  }
                +  conn.x_ = x;
                +  conn.y_ = y;
                +  return conn;
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/jsunit/connection_test.js b/blockly/webif/static/blockly/tests/jsunit/connection_test.js
                new file mode 100644
                index 000000000..0d10e63ea
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/connection_test.js
                @@ -0,0 +1,324 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Tests for connection logic.
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +var input;
                +var output;
                +var previous;
                +var next;
                +
                +var dummyWorkspace;
                +
                +function connectionTest_setUp() {
                +  dummyWorkspace = {};
                +  function createDummyBlock() {
                +    return {
                +      workspace: dummyWorkspace,
                +      isShadow: function() {return false;}
                +    };
                +  }
                +  input = new Blockly.Connection(createDummyBlock(),
                +      Blockly.INPUT_VALUE);
                +  output = new Blockly.Connection(createDummyBlock(),
                +      Blockly.OUTPUT_VALUE);
                +  previous = new Blockly.Connection(createDummyBlock(),
                +      Blockly.PREVIOUS_STATEMENT);
                +  next = new Blockly.Connection(createDummyBlock(),
                +      Blockly.NEXT_STATEMENT);
                +}
                +
                +function connectionTest_tearDown() {
                +  input = null;
                +  output = null;
                +  previous = null;
                +  next = null;
                +  dummyWorkspace = null;
                +}
                +
                +var isMovableFn = function() { return true; };
                +/**
                + * These tests check that the reasons for failures to connect are consistent
                + * (internal view of error states).
                + */
                +function testCanConnectWithReason_TargetNull() {
                +  connectionTest_setUp();
                +
                +  assertEquals(Blockly.Connection.REASON_TARGET_NULL,
                +      input.canConnectWithReason_(null));
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCanConnectWithReason_Disconnect() {
                +  connectionTest_setUp();
                +
                +  var tempConnection = new Blockly.Connection({workspace: dummyWorkspace, isMovable: isMovableFn},
                +      Blockly.OUTPUT_VALUE);
                +  Blockly.Connection.connectReciprocally_(input, tempConnection);
                +  assertEquals(Blockly.Connection.CAN_CONNECT,
                +      input.canConnectWithReason_(output));
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCanConnectWithReason_DifferentWorkspaces() {
                +  connectionTest_setUp();
                +
                +  input = new Blockly.Connection({workspace: {}}, Blockly.INPUT_VALUE);
                +  output = new Blockly.Connection({workspace: dummyWorkspace},
                +      Blockly.OUTPUT_VALUE);
                +
                +  assertEquals(Blockly.Connection.REASON_DIFFERENT_WORKSPACES,
                +      input.canConnectWithReason_(output));
                +
                +  connectionTest_tearDown();
                +}
                +
                +
                +function testCanConnectWithReason_Self() {
                +  connectionTest_setUp();
                +
                +  var block = {type_: "test block"};
                +  input.sourceBlock_ = block;
                +  assertEquals(Blockly.Connection.REASON_SELF_CONNECTION,
                +      input.canConnectWithReason_(input));
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCanConnectWithReason_Type() {
                +  connectionTest_setUp();
                +
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      input.canConnectWithReason_(previous));
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      input.canConnectWithReason_(next));
                +
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      output.canConnectWithReason_(previous));
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      output.canConnectWithReason_(next));
                +
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      previous.canConnectWithReason_(input));
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      previous.canConnectWithReason_(output));
                +
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      next.canConnectWithReason_(input));
                +  assertEquals(Blockly.Connection.REASON_WRONG_TYPE,
                +      next.canConnectWithReason_(output));
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCanConnectWithReason_CanConnect() {
                +  connectionTest_setUp();
                +
                +  assertEquals(Blockly.Connection.CAN_CONNECT,
                +      previous.canConnectWithReason_(next));
                +  assertEquals(Blockly.Connection.CAN_CONNECT,
                +      next.canConnectWithReason_(previous));
                +  assertEquals(Blockly.Connection.CAN_CONNECT,
                +      input.canConnectWithReason_(output));
                +  assertEquals(Blockly.Connection.CAN_CONNECT,
                +      output.canConnectWithReason_(input));
                +
                +  connectionTest_tearDown();
                +}
                +
                +/**
                + * The next set of tests checks that exceptions are being thrown at the correct
                + * times (external view of errors).
                + */
                +function testCheckConnection_Self() {
                +  connectionTest_setUp();
                +  var block = {type_: "test block"};
                +  input.sourceBlock_ = block;
                +  try {
                +    input.checkConnection_(input);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypeInputPrev() {
                +  connectionTest_setUp();
                +  try {
                +    input.checkConnection_(previous);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypeInputNext() {
                +  connectionTest_setUp();
                +  try {
                +    input.checkConnection_(next);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypeOutputPrev() {
                +  connectionTest_setUp();
                +  try {
                +    output.checkConnection_(previous);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypePrevInput() {
                +  connectionTest_setUp();
                +  try {
                +    previous.checkConnection_(input);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypePrevOutput() {
                +  connectionTest_setUp();
                +  try {
                +    previous.checkConnection_(output);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypeNextInput() {
                +  connectionTest_setUp();
                +  try {
                +    next.checkConnection_(input);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function testCheckConnection_TypeNextOutput() {
                +  connectionTest_setUp();
                +  try {
                +    next.checkConnection_(output);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +
                +  connectionTest_tearDown();
                +}
                +
                +function test_isConnectionAllowed_Distance() {
                +  var sharedWorkspace = {};
                +  // Two connections of opposite types near each other.
                +  var one = helper_createConnection(5 /* x */, 10 /* y */,
                +      Blockly.INPUT_VALUE, null, true);
                +  one.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  var two = helper_createConnection(10 /* x */, 15 /* y */,
                +      Blockly.OUTPUT_VALUE, null, true);
                +  two.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  assertTrue(one.isConnectionAllowed(two, 20.0));
                +  // Move connections farther apart.
                +  two.x_ = 100;
                +  two.y_ = 100;
                +  assertFalse(one.isConnectionAllowed(two, 20.0));
                +}
                +
                +function test_isConnectionAllowed_Unrendered() {
                +  var sharedWorkspace = {};
                +
                +  var one = helper_createConnection(5 /* x */, 10 /* y */,
                +      Blockly.INPUT_VALUE);
                +  one.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  // Don't offer to connect an already connected left (male) value plug to
                +  // an available right (female) value plug.
                +  var two = helper_createConnection(0, 0, Blockly.OUTPUT_VALUE);
                +  two.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  assertTrue(one.isConnectionAllowed(two));
                +  var three = helper_createConnection(0, 0, Blockly.INPUT_VALUE);
                +  three.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  Blockly.Connection.connectReciprocally_(two, three);
                +  assertFalse(one.isConnectionAllowed(two));
                +
                +  // Don't connect two connections on the same block.
                +  two.sourceBlock_ = one.sourceBlock_;
                +  assertFalse(one.isConnectionAllowed(two));
                +}
                +
                +function test_isConnectionAllowed_NoNext() {
                +  var sharedWorkspace = {};
                +  var one = helper_createConnection(0, 0, Blockly.NEXT_STATEMENT);
                +  one.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +  one.sourceBlock_.nextConnection = one;
                +
                +  var two = helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT);
                +  two.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +
                +  assertTrue(two.isConnectionAllowed(one));
                +
                +  var three = helper_createConnection(0, 0, Blockly.PREVIOUS_STATEMENT);
                +  three.sourceBlock_ = helper_makeSourceBlock(sharedWorkspace);
                +  three.sourceBlock_.previousConnection = three;
                +  Blockly.Connection.connectReciprocally_(one, three);
                +
                +  // A terminal block is allowed to replace another terminal block.
                +  assertTrue(two.isConnectionAllowed(one));
                +}
                +
                +function testCheckConnection_Okay() {
                +  connectionTest_setUp();
                +  previous.checkConnection_(next);
                +  next.checkConnection_(previous);
                +  input.checkConnection_(output);
                +  output.checkConnection_(input);
                +
                +  connectionTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/db_test.js b/blockly/webif/static/blockly/tests/jsunit/db_test.js
                new file mode 100644
                index 000000000..45fc62a4b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/db_test.js
                @@ -0,0 +1,76 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2016 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function test_DB_getNeighbours() {
                +  var db = new Blockly.ConnectionDB();
                +
                +  // Search an empty list.
                +  assertEquals(helper_getNeighbours(db, 10 /* x */, 10 /* y */, 100 /* radius */).length, 0);
                +
                +  // Set up some connections.
                +  for (var i = 0; i < 10; i++) {
                +      db.addConnection_(helper_createConnection(0, i, Blockly.PREVIOUS_STATEMENT));
                +  }
                +
                +  // Test block belongs at beginning
                +  var result = helper_getNeighbours(db, 0, 0, 4);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +      assertNotEquals(result.indexOf(db[i]), -1); // contains
                +  }
                +
                +  // Test block belongs at middle
                +  result = helper_getNeighbours(db, 0, 4, 2);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +      assertNotEquals(result.indexOf(db[i + 2]), -1); // contains
                +  }
                +
                +  // Test block belongs at end
                +  result = helper_getNeighbours(db, 0, 9, 4);
                +  assertEquals(5, result.length);
                +  for (i = 0; i < result.length; i++) {
                +      assertNotEquals(result.indexOf(db[i + 5]), -1); // contains
                +  }
                +
                +  // Test block has no neighbours due to being out of range in the x direction
                +  result = helper_getNeighbours(db, 10, 9, 4);
                +  assertEquals(result.length, 0);
                +
                +  // Test block has no neighbours due to being out of range in the y direction
                +  result = helper_getNeighbours(db, 0, 19, 4);
                +  assertEquals(result.length, 0);
                +
                +  // Test block has no neighbours due to being out of range diagonally
                +  result = helper_getNeighbours(db, -2, -2, 2);
                +  assertEquals(result.length, 0);
                +}
                +
                +function helper_getNeighbours(db, x, y, radius) {
                +  return db.getNeighbours(helper_createConnection(x, y, Blockly.NEXT_STATEMENT), radius);
                +}
                +
                +function helper_createConnection(x, y, type) {
                +  var conn = new Blockly.Connection({workspace: {}}, type);
                +  conn.x_ = x;
                +  conn.y_ = y;
                +  return conn;
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/jsunit/event_test.js b/blockly/webif/static/blockly/tests/jsunit/event_test.js
                new file mode 100644
                index 000000000..c019515e9
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/event_test.js
                @@ -0,0 +1,394 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.Events
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +goog.require('goog.testing.MockControl');
                +
                +var mockControl_;
                +var workspace;
                +
                +function eventTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  mockControl_ = new goog.testing.MockControl();
                +}
                +
                +function eventTest_setUpWithMockBlocks() {
                +  eventTest_setUp();
                +  Blockly.defineBlocksWithJsonArray([{
                +    'type': 'field_variable_test_block',
                +    'message0': '%1',
                +    'args0': [
                +      {
                +        'type': 'field_variable',
                +        'name': 'VAR',
                +        'variable': 'item'
                +      }
                +    ],
                +  }]);
                +}
                +
                +function eventTest_tearDown() {
                +  mockControl_.$tearDown();
                +  workspace.dispose();
                +}
                +
                +function eventTest_tearDownWithMockBlocks() {
                +  eventTest_tearDown();
                +  delete Blockly.Blocks.field_variable_test_block;
                +}
                +
                +function test_abstract_constructor_block() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, '1');
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.Abstract(block);
                +  assertUndefined(event.varId);
                +  checkExactEventValues(event, {'blockId': '1', 'workspaceId': workspace.id,
                +    'group': '', 'recordUndo': true});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_abstract_constructor_variable() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, '1');
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.Abstract(variable);
                +  assertUndefined(event.blockId);
                +  checkExactEventValues(event, {'varId': 'id1',
                +    'workspaceId': workspace.id, 'group': '', 'recordUndo': true});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_abstract_constructor_null() {
                +  eventTest_setUpWithMockBlocks();
                +  var event = new Blockly.Events.Abstract(null);
                +  assertUndefined(event.blockId);
                +  assertUndefined(event.workspaceId);
                +  checkExactEventValues(event, {'group': '', 'recordUndo': true});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function checkCreateEventValues(event, block, ids, type) {
                +  var expected_xml = Blockly.Xml.domToText(Blockly.Xml.blockToDom(block));
                +  var result_xml = Blockly.Xml.domToText(event.xml);
                +  assertEquals(expected_xml, result_xml);
                +  isEqualArrays(ids, event.ids);
                +  assertEquals(type, event.type);
                +}
                +
                +function checkDeleteEventValues(event, block, ids, type) {
                +  var expected_xml = Blockly.Xml.domToText(Blockly.Xml.blockToDom(block));
                +  var result_xml = Blockly.Xml.domToText(event.oldXml);
                +  assertEquals(expected_xml, result_xml);
                +  isEqualArrays(ids, event.ids);
                +  assertEquals(type, event.type);
                +}
                +
                +function checkExactEventValues(event, values) {
                +  var keys = Object.keys(values);
                +  for (var i = 0, field; field = keys[i]; i++) {
                +    assertEquals(values[field], event[field]);
                +  }
                +}
                +
                +function test_create_constructor() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.Create(block);
                +  checkCreateEventValues(event, block, ['1'], 'create');
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockCreate_constructor() {
                +  // expect that blockCreate behaves the same as create.
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.BlockCreate(block);
                +  checkCreateEventValues(event, block, ['1'], 'create');
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_delete_constructor() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.Delete(block);
                +  checkDeleteEventValues(event, block, ['1'], 'delete');
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockDelete_constructor() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.BlockDelete(block);
                +  checkDeleteEventValues(event, block, ['1'], 'delete');
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_change_constructor() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.Change(block, 'field', 'VAR', 'item', 'item2');
                +  checkExactEventValues(event, {'element': 'field', 'name': 'VAR',
                +    'oldValue': 'item', 'newValue': 'item2', 'type': 'change'});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockChange_constructor() {
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var event = new Blockly.Events.BlockChange(block, 'field', 'VAR', 'item',
                +    'item2');
                +  checkExactEventValues(event, {'element': 'field', 'name': 'VAR',
                +    'oldValue': 'item', 'newValue': 'item2', 'type': 'change'});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_move_constructorCoordinate() {
                +  // Expect the oldCoordinate to be set.
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var coordinate = new goog.math.Coordinate(3,4);
                +  block1.xy_ = coordinate;
                +
                +  var event = new Blockly.Events.Move(block1);
                +  checkExactEventValues(event, {'oldCoordinate': coordinate,
                +    'type': 'move'});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_move_constructoroldParentId() {
                +  // Expect the oldParentId to be set but not the oldCoordinate to be set.
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var block2 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  block1.parentBlock_ = block2;
                +  block1.xy_ = new goog.math.Coordinate(3,4);
                +
                +  var event = new Blockly.Events.Move(block1);
                +  checkExactEventValues(event, {'oldCoordinate': undefined,
                +    'oldParentId': '2', 'type': 'move'});
                +  block1.parentBlock_ = null;
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockMove_constructorCoordinate() {
                +  // Expect the oldCoordinate to be set.
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var coordinate = new goog.math.Coordinate(3,4);
                +  block1.xy_ = coordinate;
                +
                +  var event = new Blockly.Events.BlockMove(block1);
                +  checkExactEventValues(event, {'oldCoordinate': coordinate,
                +    'type': 'move'});
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockMove_constructoroldParentId() {
                +  // Expect the oldParentId to be set but not the oldCoordinate to be set.
                +  eventTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  var block2 = new Blockly.Block(workspace, 'field_variable_test_block');
                +  block1.parentBlock_ = block2;
                +  block1.xy_ = new goog.math.Coordinate(3,4);
                +
                +  var event = new Blockly.Events.BlockMove(block1);
                +  checkExactEventValues(event, {'oldCoordinate': undefined,
                +    'oldParentId': '2', 'type': 'move'});
                +  block1.parentBlock_ = null;
                +  eventTest_tearDownWithMockBlocks();
                +}
                +
                +function test_varCreate_constructor() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarCreate(variable);
                +  checkExactEventValues(event, {'varName': 'name1', 'varType': 'type1',
                +    'type': 'var_create'});
                +  eventTest_tearDown();
                +}
                +
                +function test_varCreate_toJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarCreate(variable);
                +  var json = event.toJson();
                +  var expectedJson = ({type: "var_create", varId: "id1", varType: "type1",
                +    varName: "name1"});
                +
                +  assertEquals(JSON.stringify(expectedJson), JSON.stringify(json));
                +  eventTest_tearDown();
                +}
                +
                +function test_varCreate_fromJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarCreate(variable);
                +  var event2 = new Blockly.Events.VarCreate(null);
                +  var json = event.toJson();
                +  event2.fromJson(json);
                +
                +  assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson()));
                +  eventTest_tearDown();
                +}
                +
                +function test_varCreate_runForward() {
                +  eventTest_setUp();
                +  var json = {type: "var_create", varId: "id1", varType: "type1",
                +    varName: "name1"};
                +  var event = Blockly.Events.fromJson(json, workspace);
                +  assertNull(workspace.getVariableById('id1'));
                +  event.run(true);
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  eventTest_tearDown();
                +}
                +
                +function test_varCreate_runBackwards() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarCreate(variable);
                +  assertNotNull(workspace.getVariableById('id1'));
                +  event.run(false);
                +  assertNull(workspace.getVariableById('id1'));
                +  eventTest_tearDown();
                +}
                +
                +function test_varDelete_constructor() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarDelete(variable);
                +  checkExactEventValues(event, {'varName': 'name1', 'varType': 'type1',
                +    'varId':'id1', 'type': 'var_delete'});
                +  eventTest_tearDown();
                +}
                +
                +function test_varDelete_toJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarDelete(variable);
                +  var json = event.toJson();
                +  var expectedJson = ({type: "var_delete", varId: "id1", varType: "type1",
                +    varName: "name1"});
                +
                +  assertEquals(JSON.stringify(expectedJson), JSON.stringify(json));
                +  eventTest_tearDown();
                +}
                +
                +function test_varDelete_fromJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarDelete(variable);
                +  var event2 = new Blockly.Events.VarDelete(null);
                +  var json = event.toJson();
                +  event2.fromJson(json);
                +
                +  assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson()));
                +  eventTest_tearDown();
                +}
                +
                +function test_varDelete_runForwards() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarDelete(variable);
                +  assertNotNull(workspace.getVariableById('id1'));
                +  event.run(true);
                +  assertNull(workspace.getVariableById('id1'));
                +  eventTest_tearDown();
                +}
                +
                +function test_varDelete_runBackwards() {
                +  eventTest_setUp();
                +  var json = {type: "var_delete", varId: "id1", varType: "type1",
                +    varName: "name1"};
                +  var event = Blockly.Events.fromJson(json, workspace);
                +  assertNull(workspace.getVariableById('id1'));
                +  event.run(false);
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  eventTest_tearDown();
                +}
                +
                +function test_varRename_constructor() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarRename(variable, 'name2');
                +  checkExactEventValues(event, {'varId': 'id1', 'oldName': 'name1',
                +    'newName': 'name2', 'type': 'var_rename'});
                +  eventTest_tearDown();
                +}
                +
                +function test_varRename_toJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarRename(variable, 'name2');
                +  var json = event.toJson();
                +  var expectedJson = ({type: "var_rename", varId: "id1", oldName: "name1",
                +    newName: "name2"});
                +
                +  assertEquals(JSON.stringify(expectedJson), JSON.stringify(json));
                +  eventTest_tearDown();
                +}
                +
                +function test_varRename_fromJson() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarRename(variable, '');
                +  var event2 = new Blockly.Events.VarRename(null);
                +  var json = event.toJson();
                +  event2.fromJson(json);
                +
                +  assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson()));
                +  eventTest_tearDown();
                +}
                +
                +function test_varRename_runForward() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarRename(variable, 'name2');
                +  event.run(true);
                +  assertNull(workspace.getVariable('name1'));
                +  checkVariableValues(workspace, 'name2', 'type1', 'id1');
                +  eventTest_tearDown();
                +}
                +
                +function test_varBackard_runForward() {
                +  eventTest_setUp();
                +  var variable = workspace.createVariable('name1', 'type1', 'id1');
                +  var event = new Blockly.Events.VarRename(variable, 'name2');
                +  event.run(false);
                +  assertNull(workspace.getVariable('name2'));
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  eventTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/extensions_test.js b/blockly/webif/static/blockly/tests/jsunit/extensions_test.js
                new file mode 100644
                index 000000000..a72179113
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/extensions_test.js
                @@ -0,0 +1,657 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.Extensions
                + * @author Anm@anm.me (Andrew n marshall)
                + */
                +'use strict';
                +
                +function test_extension() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['extensions_test']);
                +
                +    var numCallsToBefore = 0;
                +    var numCallsToAfter = 0;
                +
                +    // Extension defined before the block type is defined.
                +    Blockly.Extensions.register('extensions_test_before', function () {
                +      numCallsToBefore++;
                +      this.extendedWithBefore = true;
                +    });
                +
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "extension_test_block",
                +      "message0": "extension_test_block",
                +      "extensions": ["extensions_test_before", "extensions_test_after"]
                +    }]);
                +
                +    // Extension defined after the block type (but before instantiation).
                +    Blockly.Extensions.register('extensions_test_after', function () {
                +      numCallsToAfter++;
                +      this.extendedWithAfter = true;
                +    });
                +
                +    assert(goog.isFunction(Blockly.Extensions.ALL_['extensions_test_before']));
                +    assert(goog.isFunction(Blockly.Extensions.ALL_['extensions_test_after']));
                +    assertEquals(0, numCallsToBefore);
                +    assertEquals(0, numCallsToAfter);
                +
                +    block = new Blockly.Block(workspace, 'extension_test_block');
                +
                +    assertEquals(1, numCallsToBefore);
                +    assertEquals(1, numCallsToAfter);
                +    assert(block.extendedWithBefore);
                +    assert(block.extendedWithAfter);
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +
                +    delete Blockly.Extensions.ALL_['extensions_test_before'];
                +    delete Blockly.Extensions.ALL_['extensions_test_after'];
                +    delete Blockly.Blocks['extension_test_block'];
                +  }
                +}
                +
                +function test_extension_missing() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  var exceptionWasThrown = false;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['missing_extension']);
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "missing_extension_block",
                +      "message0": "missing_extension_block",
                +      "extensions": ["missing_extension"]
                +    }]);
                +
                +    block = new Blockly.Block(workspace, 'missing_extension_block');
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +    delete Blockly.Blocks['missing_extension_block'];
                +  }
                +  assert(exceptionWasThrown);
                +}
                +
                +function test_extension_not_a_function() {
                +  var exceptionWasThrown = false;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['extension_just_a_string']);
                +    Blockly.Extensions.register('extension_just_a_string', 'extension_just_a_string');
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['extension_just_a_string'];
                +  }
                +  assert(exceptionWasThrown);
                +
                +  var exceptionWasThrown = false;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['extension_is_null']);
                +    Blockly.Extensions.register('extension_is_null', null);
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['extension_is_null'];
                +  }
                +  assert(exceptionWasThrown);
                +
                +  var exceptionWasThrown = false;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['extension_is_undefined']);
                +    Blockly.Extensions.register('extension_is_undefined');
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['extension_is_undefined'];
                +  }
                +  assert(exceptionWasThrown);
                +}
                +
                +function test_parent_tooltip_when_inline() {
                +  var defaultTooltip = "defaultTooltip";
                +  var parentTooltip = "parentTooltip";
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([
                +      {
                +        "type": "test_parent_tooltip_when_inline",
                +        "message0": "test_parent_tooltip_when_inline",
                +        "output": true,
                +        "tooltip": defaultTooltip,
                +        "extensions": ["parent_tooltip_when_inline"]
                +      },
                +      {
                +        "type": "test_parent",
                +        "message0": "%1",
                +        "args0": [
                +          {
                +            "type": "input_value",
                +            "name": "INPUT"
                +          }
                +        ],
                +        "tooltip": parentTooltip
                +      }
                +    ]);
                +
                +    block = new Blockly.Block(workspace, 'test_parent_tooltip_when_inline');
                +
                +    // Tooltip is dynamic after extension initialization.
                +    assert(goog.isFunction(block.tooltip));
                +    assertEquals(block.tooltip(), defaultTooltip);
                +
                +    // Tooltip is normal before connected to parent.
                +    var parent = new Blockly.Block(workspace, 'test_parent');
                +    assertEquals(parent.tooltip, parentTooltip);
                +    assertFalse(!!parent.inputsInline);
                +
                +    // Tooltip is normal when parent is not inline.
                +    parent.getInput('INPUT').connection.connect(block.outputConnection);
                +    assertEquals(block.getParent(), parent);
                +    assertEquals(block.tooltip(), defaultTooltip);
                +
                +    // Tooltip is parent's when parent is inline.
                +    parent.setInputsInline(true);
                +    assertEquals(block.tooltip(), parentTooltip);
                +
                +    // Tooltip revert when disconnected.
                +    parent.getInput('INPUT').connection.disconnect();
                +    assert(!block.getParent());
                +    assertEquals(block.tooltip(), defaultTooltip);
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +
                +    delete Blockly.Blocks['test_parent_tooltip_when_inline'];
                +    delete Blockly.Blocks['test_parent'];
                +  }
                +}
                +
                +function test_mixin_extension() {
                +  var TEST_MIXIN = {
                +    field: 'FIELD',
                +    method: function() {
                +      console.log('TEXT_MIXIN method()');
                +    }
                +  };
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['mixin_test']);
                +
                +    // Extension defined before the block type is defined.
                +    Blockly.Extensions.registerMixin('mixin_test', TEST_MIXIN);
                +    assert(goog.isFunction(Blockly.Extensions.ALL_['mixin_test']));
                +
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "test_block_mixin",
                +      "message0": "test_block_mixin",
                +      "extensions": ["mixin_test"]
                +    }]);
                +
                +    block = new Blockly.Block(workspace, 'test_block_mixin');
                +
                +    assertEquals(TEST_MIXIN.field, block.field);
                +    assertEquals(TEST_MIXIN.method, block.method);
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +
                +    delete Blockly.Extensions.ALL_['mixin_test'];
                +    delete Blockly.Blocks['test_block_mixin'];
                +  }
                +}
                +
                +function test_bad_mixin_overwrites_local_value() {
                +  var TEST_MIXIN_BAD_INPUTLIST = {
                +    inputList: 'bad inputList'  // Defined in constructor
                +  };
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['mixin_bad_inputList']);
                +
                +    // Extension defined before the block type is defined.
                +    Blockly.Extensions.registerMixin('mixin_bad_inputList', TEST_MIXIN_BAD_INPUTLIST);
                +    assert(goog.isFunction(Blockly.Extensions.ALL_['mixin_bad_inputList']));
                +
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "test_block_bad_inputList",
                +      "message0": "test_block_bad_inputList",
                +      "extensions": ["mixin_bad_inputList"]
                +    }]);
                +
                +    try {
                +      block = new Blockly.Block(workspace, 'test_block_bad_inputList');
                +    } catch (e) {
                +      // Expected Error
                +      assert(e.message.indexOf('inputList') >= 0);  // Reference the conflict
                +      return;
                +    }
                +    fail('Expected error when constructing block');
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +
                +    delete Blockly.Extensions.ALL_['mixin_bad_inputList'];
                +    delete Blockly.Blocks['test_block_bad_inputList'];
                +  }
                +}
                +
                +function test_bad_mixin_overwrites_prototype() {
                +  var TEST_MIXIN_BAD_COLOUR = {
                +    colour_: 'bad colour_' // Defined on prototype
                +  };
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    assertUndefined(Blockly.Extensions.ALL_['mixin_bad_colour_']);
                +
                +    // Extension defined before the block type is defined.
                +    Blockly.Extensions.registerMixin('mixin_bad_colour_', TEST_MIXIN_BAD_COLOUR);
                +    assert(goog.isFunction(Blockly.Extensions.ALL_['mixin_bad_colour_']));
                +
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "test_block_bad_colour",
                +      "message0": "test_block_bad_colour",
                +      "extensions": ["mixin_bad_colour_"]
                +    }]);
                +
                +    try {
                +      block = new Blockly.Block(workspace, 'test_block_bad_colour');
                +    } catch (e) {
                +      // Expected Error
                +      assert(e.message.indexOf('colour_') >= 0);  // Reference the conflict
                +      return;
                +    }
                +    fail('Expected error when constructing block');
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +
                +    delete Blockly.Extensions.ALL_['mixin_bad_colour_'];
                +    delete Blockly.Blocks['test_block_bad_colour'];
                +  }
                +}
                +
                +function test_mutator_mixin() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "mutator": "mutator_test"
                +    }]);
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    Blockly.Events.disable();
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        },
                +        compose: function() {
                +          return 'composeFn';
                +        },
                +        decompose: function() {
                +          return 'decomposeFn';
                +        }
                +      });
                +
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +
                +    // Make sure all of the functions were installed correctly.
                +    assertEquals(block.domToMutation(), 'domToMutationFn');
                +    assertEquals(block.mutationToDom(), 'mutationToDomFn');
                +    assertEquals(block.compose(), 'composeFn');
                +    assertEquals(block.decompose(), 'decomposeFn');
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +}
                +
                +function test_mutator_mixin_no_dialog() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "mutator": "mutator_test"
                +    }]);
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    Blockly.Events.disable();
                +    assertUndefined(Blockly.Extensions.ALL_['mutator_test']);
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        }
                +      });
                +
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +
                +    // Make sure all of the functions were installed correctly.
                +    assertEquals(block.domToMutation(), 'domToMutationFn');
                +    assertEquals(block.mutationToDom(), 'mutationToDomFn');
                +    assertFalse(block.hasOwnProperty('compose'));
                +    assertFalse(block.hasOwnProperty('decompose'));
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +}
                +
                +// Explicitly check all four things that could be missing.
                +function test_mutator_mixin_no_decompose_fails() {
                +  var exceptionWasThrown = false;
                +  try {
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        },
                +        compose: function() {
                +          return 'composeFn';
                +        }
                +      });
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_mutator_mixin_no_compose_fails() {
                +  var exceptionWasThrown = false;
                +  try {
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        },
                +        decompose: function() {
                +          return 'decomposeFn';
                +        }
                +      });
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_mutator_mixin_no_domToMutation_fails() {
                +  var exceptionWasThrown = false;
                +  try {
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        },
                +        compose: function() {
                +          return 'composeFn';
                +        },
                +        decompose: function() {
                +          return 'decomposeFn';
                +        }
                +      });
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_mutator_mixin_no_mutationToDom_fails() {
                +  var exceptionWasThrown = false;
                +  try {
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        compose: function() {
                +          return 'composeFn';
                +        },
                +        decompose: function() {
                +          return 'decomposeFn';
                +        }
                +      });
                +  } catch (e) {
                +    // Expected.
                +    exceptionWasThrown = true;
                +  } finally {
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_use_mutator_as_extension_fails() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  var exceptionWasThrown = false;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "extensions": ["mutator_test"]
                +    }]);
                +
                +    Blockly.Events.disable();
                +    assertUndefined(Blockly.Extensions.ALL_['mutator_test']);
                +    Blockly.Extensions.registerMutator('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        }
                +      });
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +  } catch (e) {
                +    // Expected
                +    exceptionWasThrown = true;
                +    // Should have failed on apply, not on register.
                +    assertNotNull(Blockly.Extensions.ALL_['mutator_test']);
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_use_mutator_mixin_as_extension_fails() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  var exceptionWasThrown = false;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "extensions": ["mutator_test"]
                +    }]);
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    Blockly.Events.disable();
                +    assertUndefined(Blockly.Extensions.ALL_['mutator_test']);
                +    Blockly.Extensions.registerMixin('mutator_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        }
                +      });
                +
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +  } catch (e) {
                +    // Expected
                +    exceptionWasThrown = true;
                +    // Should have failed on apply, not on register.
                +    assertNotNull(Blockly.Extensions.ALL_['mutator_test']);
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['mutator_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_use_extension_as_mutator_fails() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  var exceptionWasThrown = false;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "mutator": ["extensions_test"]
                +    }]);
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    Blockly.Events.disable();
                +    assertUndefined(Blockly.Extensions.ALL_['extensions_test']);
                +    Blockly.Extensions.register('extensions_test', function() {
                +      return 'extensions_test_fn';
                +    });
                +
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +  } catch (e) {
                +    // Expected
                +    exceptionWasThrown = true;
                +    // Should have failed on apply, not on register.
                +    assertNotNull(Blockly.Extensions.ALL_['extensions_test']);
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['extensions_test'];
                +  }
                +  assertTrue(exceptionWasThrown);
                +}
                +
                +function test_mutator_mixin_plus_function() {
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  var fnWasCalled = false;
                +
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": "mutator_test_block",
                +      "message0": "mutator_test_block",
                +      "mutator": ["extensions_test"]
                +    }]);
                +
                +    Blockly.Events.disable();
                +    assertUndefined(Blockly.Extensions.ALL_['extensions_test']);
                +    Blockly.Extensions.registerMutator('extensions_test',
                +      {
                +        domToMutation: function() {
                +          return 'domToMutationFn';
                +        },
                +        mutationToDom: function() {
                +          return 'mutationToDomFn';
                +        }
                +      },
                +      function() {
                +        fnWasCalled = true;
                +      }
                +    );
                +
                +    // Events code calls mutationToDom and expects it to give back a meaningful
                +    // value.
                +    block = new Blockly.Block(workspace, 'mutator_test_block');
                +  } finally {
                +    if (block) {
                +      block.dispose();
                +    }
                +    workspace.dispose();
                +    Blockly.Events.enable();
                +    delete Blockly.Extensions.ALL_['extensions_test'];
                +  }
                +  assertTrue(fnWasCalled);
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/field_angle_test.js b/blockly/webif/static/blockly/tests/jsunit/field_angle_test.js
                new file mode 100644
                index 000000000..e5646d96c
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/field_angle_test.js
                @@ -0,0 +1,39 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.FieldAngle
                + * @author Anm@anm.me (Andrew n marshall)
                + */
                +'use strict';
                +
                +function test_fieldangle_constructor() {
                +  assertEquals(new Blockly.FieldAngle().getValue(), '0');
                +  assertEquals(new Blockly.FieldAngle(null).getValue(), '0');
                +  assertEquals(new Blockly.FieldAngle(undefined).getValue(), '0');
                +  assertEquals(new Blockly.FieldAngle(1).getValue(), '1');
                +  assertEquals(new Blockly.FieldAngle(1.5).getValue(), '1.5');
                +  assertEquals(new Blockly.FieldAngle('2').getValue(), '2');
                +  assertEquals(new Blockly.FieldAngle('2.5').getValue(), '2.5');
                +
                +  // Bad values
                +  assertEquals(new Blockly.FieldAngle('bad').getValue(), '0');
                +  assertEquals(new Blockly.FieldAngle(NaN).getValue(), '0');
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/field_number_test.js b/blockly/webif/static/blockly/tests/jsunit/field_number_test.js
                new file mode 100644
                index 000000000..20f277036
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/field_number_test.js
                @@ -0,0 +1,63 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.FieldNumber
                + * @author Anm@anm.me (Andrew n marshall)
                + */
                +'use strict';
                +
                +function test_fieldnumber_constructor() {
                +  // No arguments
                +  var field = new Blockly.FieldNumber();
                +  assertEquals(field.getValue(), '0');
                +  assertEquals(field.min_, -Infinity);
                +  assertEquals(field.max_, Infinity);
                +  assertEquals(field.precision_, 0);
                +
                +  // Numeric values
                +  field = new Blockly.FieldNumber(1);
                +  assertEquals(field.getValue(), '1');
                +  field = new Blockly.FieldNumber(1.5);
                +  assertEquals(field.getValue(), '1.5');
                +
                +  // String value
                +  field = new Blockly.FieldNumber('2');
                +  assertEquals(field.getValue(), '2');
                +  field = new Blockly.FieldNumber('2.5');
                +  assertEquals(field.getValue(), '2.5');
                +
                +  // All values
                +  field = new Blockly.FieldNumber(
                +    /* value */ 0,
                +    /* min */ -128,
                +    /* max */ 127,
                +    /* precision */ 1);
                +  assertEquals(field.getValue(), '0');
                +  assertEquals(field.min_, -128);
                +  assertEquals(field.max_, 127);
                +  assertEquals(field.precision_, 1);
                +
                +  // Bad value defaults to '0'
                +  field = new Blockly.FieldNumber('bad');
                +  assertEquals(field.getValue(), '0');
                +  field = new Blockly.FieldNumber(NaN);
                +  assertEquals(field.getValue(), '0');
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/field_test.js b/blockly/webif/static/blockly/tests/jsunit/field_test.js
                new file mode 100644
                index 000000000..6a0faebc8
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/field_test.js
                @@ -0,0 +1,99 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.Field
                + * @author fenichel@google.com (Rachel Fenichel)
                + */
                +'use strict';
                +
                +function test_field_isEditable_simple() {
                +  var field = new Blockly.Field("Dummy text");
                +  // EDITABLE is true by default, but without a source block a field can't be
                +  // edited.
                +  assertFalse('Field without a block is not editable',
                +      field.isCurrentlyEditable());
                +}
                +
                +function test_field_isEditable_false() {
                +  // Setting EDITABLE to false doesn't matter.
                +  var field = new Blockly.Field("Dummy text");
                +  field.EDITABLE = false;
                +  assertFalse('Field without a block is not editable',
                +      field.isCurrentlyEditable());
                +}
                +
                +function test_field_isEditable_editableBlock() {
                +  var editableBlock = {
                +    isEditable: function() {
                +      return true;
                +    }
                +  };
                +
                +  var field = new Blockly.Field("Dummy text");
                +  field.sourceBlock_ = editableBlock;
                +
                +  assertTrue('Editable field with editable block is editable',
                +      field.isCurrentlyEditable());
                +}
                +
                +function test_field_isEditable_editableBlock_false() {
                +  var editableBlock = {
                +    isEditable: function() {
                +      return true;
                +    }
                +  };
                +
                +  var field = new Blockly.Field("Dummy text");
                +  field.sourceBlock_ = editableBlock;
                +  field.EDITABLE = false;
                +
                +  assertFalse('Non-editable field with editable block is not editable',
                +      field.isCurrentlyEditable());
                +}
                +
                +function test_field_isEditable_nonEditableBlock() {
                +  var nonEditableBlock = {
                +    isEditable: function() {
                +      return false;
                +    }
                +  };
                +
                +  var field = new Blockly.Field("Dummy text");
                +  field.sourceBlock_ = nonEditableBlock;
                +
                +  assertFalse('Editable field with non-editable block is not editable',
                +      field.isCurrentlyEditable());
                +}
                +
                +function test_field_isEditable_nonEditableBlock_false() {
                +  var nonEditableBlock = {
                +    isEditable: function() {
                +      return false;
                +    }
                +  };
                +
                +  var field = new Blockly.Field("Dummy text");
                +  field.sourceBlock_ = nonEditableBlock;
                +  field.EDITABLE = false;
                +
                +  assertFalse('Non-editable field with non-editable block is not editable',
                +      field.isCurrentlyEditable());
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/field_variable_test.js b/blockly/webif/static/blockly/tests/jsunit/field_variable_test.js
                new file mode 100644
                index 000000000..0ef296273
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/field_variable_test.js
                @@ -0,0 +1,243 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.FieldVariable
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +goog.require('goog.testing.MockControl');
                +
                +var workspace;
                +var mockControl_;
                +
                +function fieldVariableTestWithMocks_setUp() {
                +  workspace = new Blockly.Workspace();
                +  mockControl_ = new goog.testing.MockControl();
                +}
                +
                +function fieldVariableTestWithMocks_tearDown() {
                +  mockControl_.$tearDown();
                +  workspace.dispose();
                +}
                +
                +function fieldVariable_mockBlock(workspace) {
                +  return {'workspace': workspace, 'isShadow': function(){return false;}};
                +}
                +
                +function test_fieldVariable_Constructor() {
                +  workspace = new Blockly.Workspace();
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  assertEquals('name1', fieldVariable.getText());
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_setValueMatchId() {
                + // Expect the fieldVariable value to be set to variable name
                +  fieldVariableTestWithMocks_setUp();
                +  workspace.createVariable('name2', null, 'id2');
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var mockBlock = fieldVariable_mockBlock(workspace);
                +  fieldVariable.setSourceBlock(mockBlock);
                +  var event = new Blockly.Events.BlockChange(
                +        mockBlock, 'field', undefined, 'name1', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Events, 'fire', [event], null);
                +
                +  fieldVariable.setValue('id2');
                +  assertEquals('name2', fieldVariable.getText());
                +  assertEquals('id2', fieldVariable.value_);
                +  fieldVariableTestWithMocks_tearDown();
                +}
                +
                +function test_fieldVariable_setValueMatchName() {
                +  // Expect the fieldVariable value to be set to variable name
                +  fieldVariableTestWithMocks_setUp();
                +  workspace.createVariable('name2', null, 'id2');
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var mockBlock = fieldVariable_mockBlock(workspace);
                +  fieldVariable.setSourceBlock(mockBlock);
                +  var event = new Blockly.Events.BlockChange(
                +        mockBlock, 'field', undefined, 'name1', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Events, 'fire', [event], null);
                +
                +  fieldVariable.setValue('name2');
                +  assertEquals('name2', fieldVariable.getText());
                +  assertEquals('id2', fieldVariable.value_);
                +  fieldVariableTestWithMocks_tearDown();
                +}
                +
                +function test_fieldVariable_setValueNoVariable() {
                +  // Expect the fieldVariable value to be set to the passed in string. No error
                +  // should be thrown.
                +  fieldVariableTestWithMocks_setUp();
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var mockBlock = {'workspace': workspace,
                +    'isShadow': function(){return false;}};
                +  fieldVariable.setSourceBlock(mockBlock);
                +  var event = new Blockly.Events.BlockChange(
                +        mockBlock, 'field', undefined, 'name1', 'id1');
                +  setUpMockMethod(mockControl_, Blockly.Events, 'fire', [event], null);
                +
                +  fieldVariable.setValue('id1');
                +  assertEquals('id1', fieldVariable.getText());
                +  assertEquals('id1', fieldVariable.value_);
                +  fieldVariableTestWithMocks_tearDown();
                +}
                +
                +function test_fieldVariable_dropdownCreateVariablesExist() {
                +  // Expect that the dropdown options will contain the variables that exist.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', '', 'id1');
                +  workspace.createVariable('name2', '', 'id2');
                +  var result_options = Blockly.FieldVariable.dropdownCreate.call(
                +    {
                +      'sourceBlock_': {'workspace': workspace},
                +      'getText': function(){return 'name1';},
                +      'getVariableTypes_': function(){return [''];}
                +    });
                +  assertEquals(result_options.length, 3);
                +  isEqualArrays(result_options[0], ['name1', 'id1']);
                +  isEqualArrays(result_options[1], ['name2', 'id2']);
                +
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_dropdownCreateVariablesExist() {
                +  // Expect that the dropdown options will contain the variables that exist.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', '', 'id1');
                +  workspace.createVariable('name2', '', 'id2');
                +  var result_options = Blockly.FieldVariable.dropdownCreate.call(
                +    {
                +      'sourceBlock_': {'workspace': workspace},
                +      'getText': function(){return 'name1';},
                +      'getVariableTypes_': function(){return [''];}
                +    });
                +  assertEquals(result_options.length, 3);
                +  isEqualArrays(result_options[0], ['name1', 'id1']);
                +  isEqualArrays(result_options[1], ['name2', 'id2']);
                +
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_dropdownVariableAndTypeDoesNotExist() {
                +  // Expect a variable will be created for the selected option. Expect the
                +  // workspace variable map to contain the new variable once.
                +  fieldVariableTestWithMocks_setUp();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['id1', null]);
                +
                +  var result_options = Blockly.FieldVariable.dropdownCreate.call(
                +    {
                +      'sourceBlock_': {'workspace': workspace},
                +      'getText': function(){return 'name1';},
                +      'getVariableTypes_': function(){return [''];}
                +    });
                +
                +  // Check the options.
                +  assertEquals(2, result_options.length);
                +  isEqualArrays(result_options[0], ['name1', 'id1']);
                +  // Check the variable map.
                +  assertEquals(1, workspace.getAllVariables().length);
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +
                +  fieldVariableTestWithMocks_tearDown();
                +}
                +
                +function test_fieldVariable_dropdownVariableDoesNotExistTypeDoes() {
                +  // Expect a variable will be created for the selected option. Expect the
                +  // workspace variable map to contain the new variable once.
                +  fieldVariableTestWithMocks_setUp();
                +  workspace.createVariable('name1', '', 'id1');
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['id2', null]);
                +
                +  var result_options = Blockly.FieldVariable.dropdownCreate.call(
                +    {
                +      'sourceBlock_': {'workspace': workspace},
                +      'getText': function(){return 'name2';},
                +      'getVariableTypes_': function(){return [''];}
                +    });
                +
                +  assertEquals(3, result_options.length);
                +  isEqualArrays(result_options[0], ['name1', 'id1']);
                +  isEqualArrays(result_options[1], ['name2', 'id2']);
                +  assertEquals(2, workspace.variableMap_.getAllVariables().length);
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +
                +  fieldVariableTestWithMocks_tearDown();
                +}
                +
                +function test_fieldVariable_getVariableTypes_undefinedVariableTypes() {
                +  // Expect that since variableTypes is undefined, only type empty string
                +  // will be returned.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', 'type1');
                +  workspace.createVariable('name2', 'type2');
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var resultTypes = fieldVariable.getVariableTypes_();
                +  isEqualArrays(resultTypes, ['']);
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_getVariableTypes_givenVariableTypes() {
                +  // Expect that since variableTypes is undefined, only type empty string
                +  // will be returned.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', 'type1');
                +  workspace.createVariable('name2', 'type2');
                +  var fieldVariable = new Blockly.FieldVariable('name1', null, ['type1', 'type2']);
                +  var resultTypes = fieldVariable.getVariableTypes_();
                +  isEqualArrays(resultTypes, ['type1', 'type2']);
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_getVariableTypes_nullVariableTypes() {
                +  // Expect all variable types to be returned.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', 'type1');
                +  workspace.createVariable('name2', 'type2');
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var mockBlock = fieldVariable_mockBlock(workspace);
                +  fieldVariable.setSourceBlock(mockBlock);
                +  fieldVariable.variableTypes = null;
                +  var resultTypes = fieldVariable.getVariableTypes_();
                +  isEqualArrays(resultTypes, ['type1', 'type2']);
                +  workspace.dispose();
                +}
                +
                +function test_fieldVariable_getVariableTypes_emptyListVariableTypes() {
                +  // Expect an error to be thrown.
                +  workspace = new Blockly.Workspace();
                +  workspace.createVariable('name1', 'type1');
                +  workspace.createVariable('name2', 'type2');
                +  var fieldVariable = new Blockly.FieldVariable('name1');
                +  var mockBlock = fieldVariable_mockBlock(workspace);
                +  fieldVariable.setSourceBlock(mockBlock);
                +  fieldVariable.variableTypes = [];
                +  try {
                +    fieldVariable.getVariableTypes_();
                +  } catch (e) {
                +    //expected
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/generator_test.js b/blockly/webif/static/blockly/tests/jsunit/generator_test.js
                new file mode 100644
                index 000000000..069f1c5b3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/generator_test.js
                @@ -0,0 +1,28 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function test_prefix() {
                +  var generator = new Blockly.Generator('INTERCAL');
                +  assertEquals('Prefix nothing.', '', generator.prefixLines('', ''));
                +  assertEquals('Prefix a word.', '@Hello', generator.prefixLines('Hello', '@'));
                +  assertEquals('Prefix one line.', '12Hello\n', generator.prefixLines('Hello\n', '12'));
                +  assertEquals('Prefix two lines.', '***Hello\n***World\n', generator.prefixLines('Hello\nWorld\n', '***'));
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/gesture_test.js b/blockly/webif/static/blockly/tests/jsunit/gesture_test.js
                new file mode 100644
                index 000000000..19ba1864e
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/gesture_test.js
                @@ -0,0 +1,90 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for gesture.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +var e;
                +var workspace;
                +
                +
                +function gestureTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  e = {};
                +}
                +
                +function gestureTest_tearDown() {
                +  e = null;
                +  workspace.dispose();
                +}
                +
                +function test_gestureConstructor() {
                +  var gesture = new Blockly.Gesture(e, workspace);
                +  assertEquals(gesture.mostRecentEvent_, e);
                +  assertEquals(gesture.creatorWorkspace_, workspace);
                +}
                +
                +function test_gestureIsField_ClickInWorkspace() {
                +  gestureTest_setUp();
                +  var block = new Blockly.Block(workspace);
                +  var field = new Blockly.Field();
                +  field.setSourceBlock(block);
                +  var gesture = new Blockly.Gesture(e, workspace);
                +  gesture.setStartField(field);
                +
                +  var isFieldClick = gesture.isFieldClick_();
                +  assertEquals(isFieldClick, true);
                +  gestureTest_tearDown();
                +}
                +
                +function gestureIsFieldClick_InFlyoutHelper(flyout, expectedResult){
                +  // Assign workspace flyout
                +  workspace.flyout_ = flyout;
                +  // Create a Field inside of a Block
                +  var block = new Blockly.Block(workspace);
                +  var field = new Blockly.Field();
                +  field.setSourceBlock(block);
                +  // Create gesture from the flyout
                +  var gesture = new Blockly.Gesture(e, workspace.flyout_);
                +  // Populate gesture with click start information
                +  gesture.setStartField(field);
                +  gesture.setStartFlyout_(workspace.flyout_);
                +
                +  var isFieldClick = gesture.isFieldClick_();
                +  assertEquals(isFieldClick, expectedResult);
                +}
                +
                +function test_gestureIsFieldClick_AutoCloseFlyout() {
                +  gestureTest_setUp();
                +  var flyout = new Blockly.VerticalFlyout({});
                +  gestureIsFieldClick_InFlyoutHelper(flyout, false);
                +  gestureTest_tearDown();
                +}
                +
                +function test_gestureIsFieldClick_AlwaysOpenFlyout() {
                +  gestureTest_setUp();
                +  var flyout = new Blockly.VerticalFlyout({});
                +  flyout.autoClose = false;
                +  gestureIsFieldClick_InFlyoutHelper(flyout, true);
                +  gestureTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/index.html b/blockly/webif/static/blockly/tests/jsunit/index.html
                new file mode 100644
                index 000000000..940111ecb
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/index.html
                @@ -0,0 +1,32 @@
                +<!DOCTYPE html>
                +<html>
                +  <head>
                +    <meta charset="utf-8">
                +    <title>Unit Tests for Blockly</title>
                +    <script src="../../blockly_uncompressed.js"></script>
                +    <script>goog.require('goog.testing.jsunit');</script>
                +  </head>
                +  <body>
                +    <script src="test_utilities.js"></script>
                +    <script src="utils_test.js"></script>
                +    <script src="connection_test.js"></script>
                +    <script src="connection_db_test.js"></script>
                +    <script src="extensions_test.js"></script>
                +    <script src="event_test.js"></script>
                +    <script src="field_test.js"></script>
                +    <script src="field_angle_test.js"></script>
                +    <script src="field_number_test.js"></script>
                +    <script src="field_variable_test.js"></script>
                +    <script src="generator_test.js"></script>
                +    <script src="gesture_test.js"></script>
                +    <script src="input_test.js"></script>
                +    <script src="names_test.js"></script>
                +    <script src="workspace_test.js"></script>
                +    <script src="workspace_undo_redo_test.js"></script>
                +    <script src="xml_test.js"></script>
                +    <script src="json_test.js"></script>
                +    <script src="procedures_test.js"></script>
                +    <script src="variable_model_test.js"></script>
                +    <script src="variable_map_test.js"></script>
                +  </body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/jsunit/input_test.js b/blockly/webif/static/blockly/tests/jsunit/input_test.js
                new file mode 100644
                index 000000000..b80f44ab5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/input_test.js
                @@ -0,0 +1,202 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.Input
                + */
                +'use strict';
                +
                +function test_appendField_simple() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var field1 = new Blockly.FieldLabel('#1');
                +  var field2 = new Blockly.FieldLabel('#2');
                +
                +  // Preconditions
                +  assertEquals(0, input.fieldRow.length);
                +
                +  // Actual Tests
                +  input.appendField(field1, 'first');
                +  assertEquals(1, input.fieldRow.length);
                +  assertEquals(field1, input.fieldRow[0]);
                +  assertEquals('first', input.fieldRow[0].name);
                +  assertEquals(block, field1.sourceBlock_);
                +
                +  input.appendField(field2, 'second');
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(field2, input.fieldRow[1]);
                +  assertEquals('second', input.fieldRow[1].name);
                +  assertEquals(block, field2.sourceBlock_);
                +}
                +
                +function test_appendField_string() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var labelText = 'label';
                +
                +  // Preconditions
                +  assertEquals(0, input.fieldRow.length);
                +
                +  // Actual Tests
                +  input.appendField(labelText, 'name');
                +  assertEquals(1, input.fieldRow.length);
                +  assertEquals(Blockly.FieldLabel, input.fieldRow[0].constructor);
                +  assertEquals(labelText, input.fieldRow[0].getValue());
                +  assertEquals('name', input.fieldRow[0].name);
                +}
                +
                +function test_appendField_prefix() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var prefix = new Blockly.FieldLabel('prefix');
                +  var field = new Blockly.FieldLabel('field');
                +  field.prefixField = prefix;
                +
                +  // Preconditions
                +  assertEquals(0, input.fieldRow.length);
                +
                +  // Actual Tests
                +  input.appendField(field);
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(prefix, input.fieldRow[0]);
                +  assertEquals(field, input.fieldRow[1]);
                +}
                +
                +function test_appendField_suffix() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var suffix = new Blockly.FieldLabel('suffix');
                +  var field = new Blockly.FieldLabel('field');
                +  field.suffixField = suffix;
                +
                +  // Preconditions
                +  assertEquals(0, input.fieldRow.length);
                +
                +  // Actual Tests
                +  input.appendField(field);
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(field, input.fieldRow[0]);
                +  assertEquals(suffix, input.fieldRow[1]);
                +}
                +
                +function test_insertFieldAt_simple() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var before = new Blockly.FieldLabel('before');
                +  var after = new Blockly.FieldLabel('after');
                +  var between = new Blockly.FieldLabel('between');
                +  input.appendField(before);
                +  input.appendField(after);
                +
                +  // Preconditions
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(after, input.fieldRow[1]);
                +
                +  // Actual Tests
                +  input.insertFieldAt(1, between, 'name');
                +  assertEquals(3, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(between, input.fieldRow[1]);
                +  assertEquals('name', input.fieldRow[1].name);
                +  assertEquals(after, input.fieldRow[2]);
                +}
                +
                +function test_insertFieldAt_string() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var before = new Blockly.FieldLabel('before');
                +  var after = new Blockly.FieldLabel('after');
                +  var labelText = 'label';
                +  input.appendField(before);
                +  input.appendField(after);
                +
                +  // Preconditions
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(after, input.fieldRow[1]);
                +
                +  // Actual Tests
                +  input.insertFieldAt(1, labelText, 'name');
                +  assertEquals(3, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(Blockly.FieldLabel, input.fieldRow[1].constructor);
                +  assertEquals(labelText, input.fieldRow[1].getValue());
                +  assertEquals('name', input.fieldRow[1].name);
                +  assertEquals(after, input.fieldRow[2]);
                +}
                +
                +function test_insertFieldAt_prefix() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var before = new Blockly.FieldLabel('before');
                +  var after = new Blockly.FieldLabel('after');
                +  var prefix = new Blockly.FieldLabel('prefix');
                +  var between = new Blockly.FieldLabel('between');
                +  between.prefixField = prefix
                +  input.appendField(before);
                +  input.appendField(after);
                +
                +  // Preconditions
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(after, input.fieldRow[1]);
                +
                +  // Actual Tests
                +  input.insertFieldAt(1, between);
                +  assertEquals(4, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(prefix, input.fieldRow[1]);
                +  assertEquals(between, input.fieldRow[2]);
                +  assertEquals(after, input.fieldRow[3]);
                +}
                +
                +function test_insertFieldAt_prefix() {
                +  var ws = new Blockly.Workspace();
                +  var block = new Blockly.Block(ws);
                +  var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
                +  var before = new Blockly.FieldLabel('before');
                +  var after = new Blockly.FieldLabel('after');
                +  var suffix = new Blockly.FieldLabel('suffix');
                +  var between = new Blockly.FieldLabel('between');
                +  between.suffixField = suffix
                +  input.appendField(before);
                +  input.appendField(after);
                +
                +  // Preconditions
                +  assertEquals(2, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(after, input.fieldRow[1]);
                +
                +  // Actual Tests
                +  input.insertFieldAt(1, between);
                +  assertEquals(4, input.fieldRow.length);
                +  assertEquals(before, input.fieldRow[0]);
                +  assertEquals(between, input.fieldRow[1]);
                +  assertEquals(suffix, input.fieldRow[2]);
                +  assertEquals(after, input.fieldRow[3]);
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/blockly/tests/jsunit/json_test.js b/blockly/webif/static/blockly/tests/jsunit/json_test.js
                new file mode 100644
                index 000000000..7967cd2f6
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/json_test.js
                @@ -0,0 +1,260 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +/**  Ensure a block can be instantiated from a JSON definition.  */
                +function test_json_minimal() {
                +  var BLOCK_TYPE = 'test_json_minimal';
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(BLOCK_TYPE, block.type);
                +    // TODO: asserts
                +  } finally {
                +    block.dispose();
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +  }
                +}
                +
                +/**  Ensure message0 creates an input.  */
                +function test_json_message0() {
                +  var BLOCK_TYPE = 'test_json_message0';
                +  var MESSAGE0 = 'message0';
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE,
                +      "message0": MESSAGE0
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(1, block.inputList.length);
                +    assertEquals(1, block.inputList[0].fieldRow.length);
                +    var textField = block.inputList[0].fieldRow[0];
                +    assertEquals(Blockly.FieldLabel, textField.constructor);
                +    assertEquals(MESSAGE0, textField.getText());
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +  }
                +}
                +
                +/**  Ensure message1 creates a new input.  */
                +function test_json_message1() {
                +  var BLOCK_TYPE = 'test_json_message1';
                +  var MESSAGE0 = 'message0';
                +  var MESSAGE1 = 'message1';
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE,
                +      "message0": MESSAGE0,
                +      "message1": MESSAGE1
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(2, block.inputList.length);
                +
                +    assertEquals(1, block.inputList[0].fieldRow.length);
                +    var textField = block.inputList[0].fieldRow[0];
                +    assertEquals(Blockly.FieldLabel, textField.constructor);
                +    assertEquals(MESSAGE0, textField.getText());
                +
                +    assertEquals(1, block.inputList[1].fieldRow.length);
                +    var textField = block.inputList[1].fieldRow[0];
                +    assertEquals(Blockly.FieldLabel, textField.constructor);
                +    assertEquals(MESSAGE1, textField.getText());
                +  } finally {
                +    block && block.dispose();
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +  }
                +}
                +
                +/**  Ensure message string is dereferenced.  */
                +function test_json_message0_i18n() {
                +  var BLOCK_TYPE = 'test_json_message0_i18n';
                +  var MESSAGE0 = '%{BKY_MESSAGE}';
                +  var MESSAGE = 'message';
                +
                +  Blockly.Msg['MESSAGE'] = MESSAGE;
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE,
                +      "message0": MESSAGE0
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(1, block.inputList.length);
                +    assertEquals(1, block.inputList[0].fieldRow.length);
                +    var textField = block.inputList[0].fieldRow[0];
                +    assertEquals(Blockly.FieldLabel, textField.constructor);
                +    assertEquals(MESSAGE, textField.getText());
                +  } finally {
                +    block && block.dispose(); // Disposes of textField, too.
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +    delete Blockly.Msg['MESSAGE'];
                +  }
                +}
                +
                +function test_json_dropdown() {
                +  var BLOCK_TYPE = 'test_json_dropdown';
                +  var FIELD_NAME = 'FIELD_NAME';
                +  var LABEL0 = 'LABEL0';
                +  var VALUE0 = 'VALUE0';
                +  var LABEL1 = 'LABEL1';
                +  var VALUE1 = 'VALUE1';
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE,
                +      "message0": "%1",
                +      "args0": [
                +        {
                +          "type": "field_dropdown",
                +          "name": FIELD_NAME,
                +          "options": [
                +            [LABEL0, VALUE0],
                +            [LABEL1, VALUE1]
                +          ]
                +        }
                +      ]
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(1, block.inputList.length);
                +    assertEquals(1, block.inputList[0].fieldRow.length);
                +    var dropdown = block.inputList[0].fieldRow[0];
                +    assertEquals(dropdown, block.getField(FIELD_NAME));
                +    assertEquals(Blockly.FieldDropdown, dropdown.constructor);
                +    assertEquals(VALUE0, dropdown.getValue());
                +
                +    var options = dropdown.getOptions();
                +    assertEquals(LABEL0, options[0][0]);
                +    assertEquals(VALUE0, options[0][1]);
                +    assertEquals(LABEL1, options[1][0]);
                +    assertEquals(VALUE1, options[1][1]);
                +  } finally {
                +    block && block.dispose();  // Disposes of dropdown, too.
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +  }
                +}
                +
                +function test_json_dropdown_image() {
                +  var BLOCK_TYPE = 'test_json_dropdown';
                +  var FIELD_NAME = 'FIELD_NAME';
                +  var IMAGE1_ALT_TEXT = 'Localized message.';
                +  Blockly.Msg['ALT_TEXT'] = IMAGE1_ALT_TEXT;
                +  var IMAGE0 = {
                +    'width': 12,
                +    'height': 34,
                +    'src': 'http://image0.src',
                +    'alt': 'IMAGE0 alt text'
                +  };
                +  var VALUE0 = 'VALUE0';
                +  var IMAGE1 = {
                +    'width': 56,
                +    'height': 78,
                +    'src': 'http://image1.src',
                +    'alt': '%{BKY_ALT_TEXT}'
                +  };
                +  var VALUE1 = 'VALUE1';
                +  var IMAGE2 = {
                +    'width': 90,
                +    'height': 123,
                +    'src': 'http://image2.src'
                +  };
                +  var VALUE2 = 'VALUE2';
                +
                +  var workspace = new Blockly.Workspace();
                +  var block;
                +  try {
                +    Blockly.defineBlocksWithJsonArray([{
                +      "type": BLOCK_TYPE,
                +      "message0": "%1",
                +      "args0": [
                +        {
                +          "type": "field_dropdown",
                +          "name": FIELD_NAME,
                +          "options": [
                +            [IMAGE0, VALUE0],
                +            [IMAGE1, VALUE1],
                +            [IMAGE2, VALUE2]
                +          ]
                +        }
                +      ]
                +    }]);
                +
                +    block = new Blockly.Block(workspace, BLOCK_TYPE);
                +    assertEquals(1, block.inputList.length);
                +    assertEquals(1, block.inputList[0].fieldRow.length);
                +    var dropdown = block.inputList[0].fieldRow[0];
                +    assertEquals(dropdown, block.getField(FIELD_NAME));
                +    assertEquals(Blockly.FieldDropdown, dropdown.constructor);
                +    assertEquals(VALUE0, dropdown.getValue());
                +
                +    var options = dropdown.getOptions();
                +    var image0 = options[0][0];
                +    assertEquals(IMAGE0.width, image0.width);
                +    assertEquals(IMAGE0.height, image0.height);
                +    assertEquals(IMAGE0.src, image0.src);
                +    assertEquals(IMAGE0.alt, image0.alt);
                +    assertEquals(VALUE0, options[0][1]);
                +
                +    var image1 = options[1][0];
                +    assertEquals(IMAGE1.width, image1.width);
                +    assertEquals(IMAGE1.height, image1.height);
                +    assertEquals(IMAGE1.src, image1.src);
                +    assertEquals(IMAGE1.alt, IMAGE1_ALT_TEXT);  // Via Msg reference
                +    assertEquals(VALUE1, options[1][1]);
                +
                +    var image2 = options[2][0];
                +    assertEquals(IMAGE2.width, image2.width);
                +    assertEquals(IMAGE2.height, image2.height);
                +    assertEquals(IMAGE2.src, image2.src);
                +    assert(image2.alt == null);  // No alt specified.
                +    assertEquals(VALUE2, options[2][1]);
                +  } finally {
                +    block && block.dispose();  // Disposes of dropdown, too.
                +    workspace.dispose();
                +    delete Blockly.Blocks[BLOCK_TYPE];
                +    delete Blockly.Msg['ALTTEXT'];
                +  }
                +}
                +
                diff --git a/blockly/webif/static/blockly/tests/jsunit/names_test.js b/blockly/webif/static/blockly/tests/jsunit/names_test.js
                new file mode 100644
                index 000000000..8a4b008e5
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/names_test.js
                @@ -0,0 +1,62 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function test_safeName() {
                +  var varDB = new Blockly.Names('window,door');
                +  assertEquals('SafeName empty.', 'unnamed', varDB.safeName_(''));
                +  assertEquals('SafeName ok.', 'foobar', varDB.safeName_('foobar'));
                +  assertEquals('SafeName number start.', 'my_9lives',
                +               varDB.safeName_('9lives'));
                +  assertEquals('SafeName number end.', 'lives9', varDB.safeName_('lives9'));
                +  assertEquals('SafeName special chars.', '____', varDB.safeName_('!@#$'));
                +  assertEquals('SafeName reserved.', 'door', varDB.safeName_('door'));
                +}
                +
                +function test_getName() {
                +  var varDB = new Blockly.Names('window,door');
                +  assertEquals('Name add #1.', 'Foo_bar', varDB.getName('Foo.bar', 'var'));
                +  assertEquals('Name get #1.', 'Foo_bar', varDB.getName('Foo.bar', 'var'));
                +  assertEquals('Name add #2.', 'Foo_bar2', varDB.getName('Foo bar', 'var'));
                +  assertEquals('Name get #2.', 'Foo_bar2', varDB.getName('foo BAR', 'var'));
                +  assertEquals('Name add #3.', 'door2', varDB.getName('door', 'var'));
                +  assertEquals('Name add #4.', 'Foo_bar3', varDB.getName('Foo.bar', 'proc'));
                +  assertEquals('Name get #1b.', 'Foo_bar', varDB.getName('Foo.bar', 'var'));
                +  assertEquals('Name get #4.', 'Foo_bar3', varDB.getName('Foo.bar', 'proc'));
                +}
                +
                +function test_getDistinctName() {
                +  var varDB = new Blockly.Names('window,door');
                +  assertEquals('Name distinct #1.', 'Foo_bar',
                +               varDB.getDistinctName('Foo.bar', 'var'));
                +  assertEquals('Name distinct #2.', 'Foo_bar2',
                +               varDB.getDistinctName('Foo.bar', 'var'));
                +  assertEquals('Name distinct #3.', 'Foo_bar3',
                +               varDB.getDistinctName('Foo.bar', 'proc'));
                +  varDB.reset();
                +  assertEquals('Name distinct #4.', 'Foo_bar',
                +               varDB.getDistinctName('Foo.bar', 'var'));
                +}
                +
                +function test_nameEquals() {
                +  assertTrue('Name equals #1.', Blockly.Names.equals('Foo.bar', 'Foo.bar'));
                +  assertFalse('Name equals #2.', Blockly.Names.equals('Foo.bar', 'Foo_bar'));
                +  assertTrue('Name equals #3.', Blockly.Names.equals('Foo.bar', 'FOO.BAR'));
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/procedures_test.js b/blockly/webif/static/blockly/tests/jsunit/procedures_test.js
                new file mode 100644
                index 000000000..10003ec74
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/procedures_test.js
                @@ -0,0 +1,83 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for procedures.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +
                +var workspace;
                +
                +function proceduresTest_setUpWithMockBlocks() {
                +  workspace = new Blockly.Workspace();
                +  Blockly.defineBlocksWithJsonArray([{
                +    getProcedureDef: function() {
                +    },
                +    'type': 'procedure_mock_block',
                +    'message0': '%1',
                +    'args0': [
                +      {
                +        'type': 'field_variable',
                +        'name': 'NAME',
                +        'variable': 'item'
                +      }
                +    ],
                +  }]);
                +  Blockly.Blocks['procedure_mock_block'].getProcedureDef = function() {
                +    return [this.getFieldValue('NAME'), [], false];
                +  };
                +}
                +
                +function proceduresTest_tearDownWithMockBlocks() {
                +  workspace.dispose();
                +  delete Blockly.Blocks.procedures_mock_block;
                +}
                +
                +
                +function test_isNameUsed_NoBlocks() {
                +  workspace = new Blockly.Workspace();
                +  var result = Blockly.Procedures.isNameUsed('name1', workspace);
                +  assertFalse(result);
                +  workspace.dispose();
                +}
                +
                +function test_isNameUsed_False() {
                +  proceduresTest_setUpWithMockBlocks();
                +  var block = new Blockly.Block(workspace, 'procedure_mock_block');
                +  block.setFieldValue('name2', 'NAME');
                +
                +  var result = Blockly.Procedures.isNameUsed('name1', workspace);
                +  assertFalse(result);
                +  proceduresTest_tearDownWithMockBlocks();
                +}
                +
                +function test_isNameUsed_True() {
                +  proceduresTest_setUpWithMockBlocks();
                +  var block = new Blockly.Block(workspace, 'procedure_mock_block');
                +  block.setFieldValue('name1', 'NAME');
                +
                +  var result = Blockly.Procedures.isNameUsed('name1', workspace);
                +  assertTrue(result);
                +  proceduresTest_tearDownWithMockBlocks();
                +}
                +
                diff --git a/blockly/webif/static/blockly/tests/jsunit/test_runner.js b/blockly/webif/static/blockly/tests/jsunit/test_runner.js
                new file mode 100644
                index 000000000..bfd7c0bd3
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/test_runner.js
                @@ -0,0 +1,35 @@
                +var webdriverio = require('webdriverio');
                +var options = {
                +    desiredCapabilities: {
                +        browserName: 'chrome'
                +    }
                +};
                +
                +var path = process.cwd();
                +//TODO: change pause to waitunitl
                +var browser = webdriverio
                +    .remote(options)
                +    .init()
                +    .url("file://" + path + "/tests/jsunit/index.html").pause(5000);
                +
                +
                +browser
                +.getHTML('#closureTestRunnerLog')
                +.then(function(result) {
                +   // call js to parse html
                +   var regex = /[\d]+\spassed,\s([\d]+)\sfailed./i;
                +   var numOfFailure = regex.exec(result)[1];
                +  var regex2 = /Unit Tests for Blockly .*]/;
                +  var testStatus = regex2.exec(result)[0];
                +  console.log("============Blockly Unit Test Summary=================");
                +   console.log(testStatus);
                +   var regex3 = /\d+ passed,\s\d+ failed/;
                +   var detail = regex3.exec(result)[0];
                +   console.log(detail);
                +  console.log("============Blockly Unit Test Summary=================");
                +   if ( parseInt(numOfFailure) !== 0) {
                +     console.log(result);
                +     process.exit(1);
                +    }
                +})
                +.catch(function(err) { console.log(err); process.exit(1); });
                diff --git a/blockly/webif/static/blockly/tests/jsunit/test_utilities.js b/blockly/webif/static/blockly/tests/jsunit/test_utilities.js
                new file mode 100644
                index 000000000..6a80a3549
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/test_utilities.js
                @@ -0,0 +1,91 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Test utilities.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +
                +
                +/**
                + * Check that two arrays have the same content.
                + * @param {!Array.<string>} array1 The first array.
                + * @param {!Array.<string>} array2 The second array.
                + */
                +function isEqualArrays(array1, array2) {
                +  assertEquals(array1.length, array2.length);
                +  for (var i = 0; i < array1.length; i++) {
                +    assertEquals(array1[i], array2[i]);
                +  }
                +}
                +
                +/**
                + * Creates a controlled MethodMock. Sets the expected return values and
                + *     the parameters if any exist. Sets the method to replay.
                + * @param {!goog.testing.MockControl} mockControl Object that holds a set
                + *    of mocks for this test.
                + * @param {!Object} scope The scope of the method to be mocked out.
                + * @param {!string} funcName The name of the function we're going to mock.
                + * @param {Array<Object>} parameters The parameters to call the mock with.
                + * @param {Array<!Object>} return_values The values to return when called.
                + * @return {!goog.testing.MockInterface} The mocked method.
                + */
                +function setUpMockMethod(mockControl, scope, funcName, parameters,
                +	return_values) {
                +  var mockMethod = mockControl.createMethodMock(scope, funcName);
                +  if (return_values) {
                +    for (var i = 0, return_value; return_value = return_values[i]; i++) {
                +      if (parameters && i < parameters.length) {
                +        mockMethod(parameters[i]).$returns(return_value);
                +      }
                +      else {
                +        mockMethod().$returns(return_value);
                +      }
                +    }
                +  }
                +  // If there are no return values but there are parameters, we are only
                +  // recording specific method calls.
                +  else if (parameters) {
                +    for (var i = 0; i < parameters.length; i++) {
                +      mockMethod(parameters[i]);
                +    }
                +  }
                +  mockMethod.$replay();
                +  return mockMethod;
                +}
                +
                +/**
                + * Check if a variable with the given values exists.
                + * @param {Blockly.Workspace|Blockly.VariableMap} container The workspace  or
                + *     variableMap the checked variable belongs to.
                + * @param {!string} name The expected name of the variable.
                + * @param {!string} type The expected type of the variable.
                + * @param {!string} id The expected id of the variable.
                + */
                +function checkVariableValues(container, name, type, id) {
                +  var variable = container.getVariableById(id);
                +  assertNotUndefined(variable);
                +  assertEquals(name, variable.name);
                +  assertEquals(type, variable.type);
                +  assertEquals(id, variable.getId());
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/utils_test.js b/blockly/webif/static/blockly/tests/jsunit/utils_test.js
                new file mode 100644
                index 000000000..31ccfc187
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/utils_test.js
                @@ -0,0 +1,218 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2011 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function test_genUid() {
                +  var uuids = {};
                +  for (var i = 0; i < 1000; i++) {
                +    var uuid = Blockly.utils.genUid();
                +    assertFalse('UUID different: ' + uuid, uuid in uuids);
                +    uuids[uuid] = true;
                +  }
                +}
                +
                +function test_addClass() {
                +  var p = document.createElement('p');
                +  Blockly.utils.addClass(p, 'one');
                +  assertEquals('Adding "one"', 'one', p.className);
                +  Blockly.utils.addClass(p, 'one');
                +  assertEquals('Adding duplicate "one"', 'one', p.className);
                +  Blockly.utils.addClass(p, 'two');
                +  assertEquals('Adding "two"', 'one two', p.className);
                +  Blockly.utils.addClass(p, 'two');
                +  assertEquals('Adding duplicate "two"', 'one two', p.className);
                +  Blockly.utils.addClass(p, 'three');
                +  assertEquals('Adding "three"', 'one two three', p.className);
                +}
                +
                +function test_hasClass() {   
                +   var p = document.createElement('p');    
                +   p.className = ' one three  two three  ';    
                +   assertTrue('Has "one"', Blockly.utils.hasClass(p, 'one'));   
                +   assertTrue('Has "two"', Blockly.utils.hasClass(p, 'two'));   
                +   assertTrue('Has "three"', Blockly.utils.hasClass(p, 'three'));   
                +   assertFalse('Has no "four"', Blockly.utils.hasClass(p, 'four'));   
                +   assertFalse('Has no "t"', Blockly.utils.hasClass(p, 't'));   
                + }
                +
                +function test_removeClass() {
                +  var p = document.createElement('p');
                +  p.className = ' one three  two three  ';
                +  Blockly.utils.removeClass(p, 'two');
                +  assertEquals('Removing "two"', 'one three three', p.className);
                +  Blockly.utils.removeClass(p, 'four');
                +  assertEquals('Removing "four"', 'one three three', p.className);
                +  Blockly.utils.removeClass(p, 'three');
                +  assertEquals('Removing "three"', 'one', p.className);
                +  Blockly.utils.removeClass(p, 'ne');
                +  assertEquals('Removing "ne"', 'one', p.className);
                +  Blockly.utils.removeClass(p, 'one');
                +  assertEquals('Removing "one"', '', p.className);
                +  Blockly.utils.removeClass(p, 'zero');
                +  assertEquals('Removing "zero"', '', p.className);
                +}
                +
                +function test_shortestStringLength() {
                +  var len = Blockly.utils.shortestStringLength('one,two,three,four,five'.split(','));
                +  assertEquals('Length of "one"', 3, len);
                +  len = Blockly.utils.shortestStringLength('one,two,three,four,five,'.split(','));
                +  assertEquals('Length of ""', 0, len);
                +  len = Blockly.utils.shortestStringLength(['Hello World']);
                +  assertEquals('List of one', 11, len);
                +  len = Blockly.utils.shortestStringLength([]);
                +  assertEquals('Empty list', 0, len);
                +}
                +
                +function test_commonWordPrefix() {
                +  var len = Blockly.utils.commonWordPrefix('one,two,three,four,five'.split(','));
                +  assertEquals('No prefix', 0, len);
                +  len = Blockly.utils.commonWordPrefix('Xone,Xtwo,Xthree,Xfour,Xfive'.split(','));
                +  assertEquals('No word prefix', 0, len);
                +  len = Blockly.utils.commonWordPrefix('abc de,abc de,abc de,abc de'.split(','));
                +  assertEquals('Full equality', 6, len);
                +  len = Blockly.utils.commonWordPrefix('abc deX,abc deY'.split(','));
                +  assertEquals('One word prefix', 4, len);
                +  len = Blockly.utils.commonWordPrefix('abc de,abc deY'.split(','));
                +  assertEquals('Overflow no', 4, len);
                +  len = Blockly.utils.commonWordPrefix('abc de,abc de Y'.split(','));
                +  assertEquals('Overflow yes', 6, len);
                +  len = Blockly.utils.commonWordPrefix(['Hello World']);
                +  assertEquals('List of one', 11, len);
                +  len = Blockly.utils.commonWordPrefix([]);
                +  assertEquals('Empty list', 0, len);
                +  len = Blockly.utils.commonWordPrefix('turn&nbsp;left,turn&nbsp;right'.split(','));
                +  assertEquals('No prefix due to &amp;nbsp;', 0, len);
                +  len = Blockly.utils.commonWordPrefix('turn\u00A0left,turn\u00A0right'.split(','));
                +  assertEquals('No prefix due to \\u00A0', 0, len);
                +}
                +
                +function test_commonWordSuffix() {
                +  var len = Blockly.utils.commonWordSuffix('one,two,three,four,five'.split(','));
                +  assertEquals('No prefix', 0, len);
                +  len = Blockly.utils.commonWordSuffix('oneX,twoX,threeX,fourX,fiveX'.split(','));
                +  assertEquals('No word prefix', 0, len);
                +  len = Blockly.utils.commonWordSuffix('abc de,abc de,abc de,abc de'.split(','));
                +  assertEquals('Full equality', 6, len);
                +  len = Blockly.utils.commonWordSuffix('Xabc de,Yabc de'.split(','));
                +  assertEquals('One word prefix', 3, len);
                +  len = Blockly.utils.commonWordSuffix('abc de,Yabc de'.split(','));
                +  assertEquals('Overflow no', 3, len);
                +  len = Blockly.utils.commonWordSuffix('abc de,Y abc de'.split(','));
                +  assertEquals('Overflow yes', 6, len);
                +  len = Blockly.utils.commonWordSuffix(['Hello World']);
                +  assertEquals('List of one', 11, len);
                +  len = Blockly.utils.commonWordSuffix([]);
                +  assertEquals('Empty list', 0, len);
                +}
                +
                +function test_tokenizeInterpolation() {
                +  var tokens = Blockly.utils.tokenizeInterpolation('');
                +  assertArrayEquals('Null interpolation', [], tokens);
                +
                +  tokens = Blockly.utils.tokenizeInterpolation('Hello');
                +  assertArrayEquals('No interpolation', ['Hello'], tokens);
                +  
                +  tokens = Blockly.utils.tokenizeInterpolation('Hello%World');
                +  assertArrayEquals('Unescaped %.', ['Hello%World'], tokens);
                +  
                +  tokens = Blockly.utils.tokenizeInterpolation('Hello%%World');
                +  assertArrayEquals('Escaped %.', ['Hello%World'], tokens);
                +  
                +  tokens = Blockly.utils.tokenizeInterpolation('Hello %1 World');
                +  assertArrayEquals('Interpolation.', ['Hello ', 1, ' World'], tokens);
                +  
                +  tokens = Blockly.utils.tokenizeInterpolation('%123Hello%456World%789');
                +  assertArrayEquals('Interpolations.', [123, 'Hello', 456, 'World', 789], tokens);
                +  
                +  tokens = Blockly.utils.tokenizeInterpolation('%%%x%%0%00%01%');
                +  assertArrayEquals('Torture interpolations.', ['%%x%0', 0, 1, '%'], tokens);
                +
                +  Blockly.Msg = Blockly.Msg || {};
                +
                +  Blockly.Msg.STRING_REF = 'test string';
                +  tokens = Blockly.utils.tokenizeInterpolation('%{bky_string_ref}');
                +  assertArrayEquals('String table reference, lowercase', ['test string'], tokens);
                +  tokens = Blockly.utils.tokenizeInterpolation('%{BKY_STRING_REF}');
                +  assertArrayEquals('String table reference, uppercase', ['test string'], tokens);
                +
                +  Blockly.Msg.WITH_PARAM = 'before %1 after';
                +  tokens = Blockly.utils.tokenizeInterpolation('%{bky_with_param}');
                +  assertArrayEquals('String table reference, with parameter', ['before ', 1, ' after'], tokens);
                +
                +  Blockly.Msg.RECURSE = 'before %{bky_string_ref} after';
                +  tokens = Blockly.utils.tokenizeInterpolation('%{bky_recurse}');
                +  assertArrayEquals('String table reference, with subreference', ['before test string after'], tokens);
                +
                +  // Error cases...
                +  tokens = Blockly.utils.tokenizeInterpolation('%{bky_undefined}');
                +  assertArrayEquals('Undefined string table reference', ['%{bky_undefined}'], tokens);
                +
                +  Blockly.Msg['1'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{1} after');
                +  assertArrayEquals('Invalid initial digit in string table reference', ['before %{1} after'], tokens);
                +
                +  Blockly.Msg['TWO WORDS'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{two words} after');
                +  assertArrayEquals('Invalid character in string table reference: space', ['before %{two words} after'], tokens);
                +
                +  Blockly.Msg['TWO-WORDS'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{two-words} after');
                +  assertArrayEquals('Invalid character in string table reference: dash', ['before %{two-words} after'], tokens);
                +
                +  Blockly.Msg['TWO.WORDS'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{two.words} after');
                +  assertArrayEquals('Invalid character in string table reference: period', ['before %{two.words} after'], tokens);
                +
                +  Blockly.Msg['AB&C'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{ab&c} after');
                +  assertArrayEquals('Invalid character in string table reference: &', ['before %{ab&c} after'], tokens);
                +
                +  Blockly.Msg['UNCLOSED'] = 'Will not match';
                +  tokens = Blockly.utils.tokenizeInterpolation('before %{unclosed');
                +  assertArrayEquals('String table reference, with parameter', ['before %{unclosed'], tokens);
                +}
                +
                +function test_replaceMessageReferences() {
                +  Blockly.Msg = Blockly.Msg || {};
                +  Blockly.Msg.STRING_REF = 'test string';
                +
                +  var resultString = Blockly.utils.replaceMessageReferences('');
                +  assertEquals('Empty string produces empty string', '', resultString);
                +
                +  resultString = Blockly.utils.replaceMessageReferences('%{bky_string_ref}');
                +  assertEquals('Message ref dereferenced.', 'test string', resultString);
                +  resultString = Blockly.utils.replaceMessageReferences('before %{bky_string_ref} after');
                +  assertEquals('Message ref dereferenced.', 'before test string after', resultString);
                +
                +  resultString = Blockly.utils.replaceMessageReferences('%1');
                +  assertEquals('Interpolation tokens ignored.', '%1', resultString);
                +  resultString = Blockly.utils.replaceMessageReferences('%1 %2');
                +  assertEquals('Interpolation tokens ignored.', '%1 %2', resultString);
                +  resultString = Blockly.utils.replaceMessageReferences('before %1 after');
                +  assertEquals('Interpolation tokens ignored.', 'before %1 after', resultString);
                +
                +  resultString = Blockly.utils.replaceMessageReferences('%%');
                +  assertEquals('Escaped %', '%', resultString);
                +  resultString = Blockly.utils.replaceMessageReferences('%%{bky_string_ref}');
                +  assertEquals('Escaped %', '%{bky_string_ref}', resultString);
                +
                +  resultString = Blockly.utils.replaceMessageReferences('%a');
                +  assertEquals('Unrecognized % escape code treated as literal', '%a', resultString);
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/variable_map_test.js b/blockly/webif/static/blockly/tests/jsunit/variable_map_test.js
                new file mode 100644
                index 000000000..023377b14
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/variable_map_test.js
                @@ -0,0 +1,274 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for variable map.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +goog.require('goog.testing.MockControl');
                +
                +var variable_map;
                +var mockControl_;
                +var workspace;
                +
                +function variableMapTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  variable_map = new Blockly.VariableMap(workspace);
                +  mockControl_ = new goog.testing.MockControl();
                +}
                +
                +function variableMapTest_tearDown() {
                +  workspace.dispose();
                +  mockControl_.$tearDown();
                +  variable_map = null;
                +}
                +
                +function test_getVariable_Trivial() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
                +  var var_2 = variable_map.createVariable('name2', 'type1', 'id2');
                +  var var_3 = variable_map.createVariable('name3', 'type2', 'id3');
                +  var result_1 = variable_map.getVariable('name1');
                +  var result_2 = variable_map.getVariable('name2');
                +  var result_3 = variable_map.getVariable('name3');
                +
                +  assertEquals(var_1, result_1);
                +  assertEquals(var_2, result_2);
                +  assertEquals(var_3, result_3);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariable_NotFound() {
                +  variableMapTest_setUp();
                +  var result = variable_map.getVariable('name1');
                +  assertNull(result);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariableById_Trivial() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
                +  var var_2 = variable_map.createVariable('name2', 'type1', 'id2');
                +  var var_3 = variable_map.createVariable('name3', 'type2', 'id3');
                +  var result_1 = variable_map.getVariableById('id1');
                +  var result_2 = variable_map.getVariableById('id2');
                +  var result_3 = variable_map.getVariableById('id3');
                +
                +  assertEquals(var_1, result_1);
                +  assertEquals(var_2, result_2);
                +  assertEquals(var_3, result_3);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariableById_NotFound() {
                +  variableMapTest_setUp();
                +  var result = variable_map.getVariableById('id1');
                +  assertNull(result);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableTrivial() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +  checkVariableValues(variable_map, 'name1', 'type1', 'id1');
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableAlreadyExists() {
                +  // Expect that when the variable already exists, the variableMap_ is unchanged.
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +
                +  // Assert there is only one variable in the variable_map.
                +  var keys = Object.keys(variable_map.variableMap_);
                +  assertEquals(1, keys.length);
                +  var varMapLength = variable_map.variableMap_[keys[0]].length;
                +  assertEquals(1, varMapLength);
                +
                +  variable_map.createVariable('name1');
                +  checkVariableValues(variable_map, 'name1', 'type1', 'id1');
                +  // Check that the size of the variableMap_ did not change.
                +  keys = Object.keys(variable_map.variableMap_);
                +  assertEquals(1, keys.length);
                +  varMapLength = variable_map.variableMap_[keys[0]].length;
                +  assertEquals(1, varMapLength);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableNullAndUndefinedType() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', null, 'id1');
                +  variable_map.createVariable('name2', undefined, 'id2');
                +
                +  checkVariableValues(variable_map, 'name1', '', 'id1');
                +  checkVariableValues(variable_map, 'name2', '', 'id2');
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableNullId() {
                +  variableMapTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  try {
                +    variable_map.createVariable('name1', 'type1', null);
                +    checkVariableValues(variable_map, 'name1', 'type1', '1');
                +  }
                +  finally {
                +    variableMapTest_tearDown();
                +  }
                +}
                +
                +function test_createVariableUndefinedId() {
                +  variableMapTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
                +  try {
                +    variable_map.createVariable('name1', 'type1', undefined);
                +    checkVariableValues(variable_map, 'name1', 'type1', '1');
                +  }
                +  finally {
                +    variableMapTest_tearDown();
                +  }
                +}
                +
                +function test_createVariableIdAlreadyExists() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +  try {
                +    variable_map.createVariable('name2', 'type2', 'id1');
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableMismatchedIdAndType() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +  try {
                +    variable_map.createVariable('name1', 'type2', 'id1');
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +  try {
                +    variable_map.createVariable('name1', 'type1', 'id2');
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +  variableMapTest_tearDown();
                +}
                +
                +function test_createVariableTwoSameTypes() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +  variable_map.createVariable('name2', 'type1', 'id2');
                +
                +  checkVariableValues(variable_map, 'name1', 'type1', 'id1');
                +  checkVariableValues(variable_map, 'name2', 'type1', 'id2');
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariablesOfType_Trivial() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
                +  var var_2 = variable_map.createVariable('name2', 'type1', 'id2');
                +  variable_map.createVariable('name3', 'type2', 'id3');
                +  variable_map.createVariable('name4', 'type3', 'id4');
                +  var result_array_1 = variable_map.getVariablesOfType('type1');
                +  var result_array_2 = variable_map.getVariablesOfType('type5');
                +  isEqualArrays([var_1, var_2], result_array_1);
                +  isEqualArrays([], result_array_2);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariablesOfType_Null() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', '', 'id1');
                +  var var_2 = variable_map.createVariable('name2', '', 'id2');
                +  var var_3 = variable_map.createVariable('name3', '', 'id3');
                +  variable_map.createVariable('name4', 'type1', 'id4');
                +  var result_array = variable_map.getVariablesOfType(null);
                +  isEqualArrays([var_1, var_2, var_3], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariablesOfType_EmptyString() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', null, 'id1');
                +  var var_2 = variable_map.createVariable('name2', null, 'id2');
                +  var result_array = variable_map.getVariablesOfType('');
                +  isEqualArrays([var_1, var_2], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariablesOfType_Deleted() {
                +  variableMapTest_setUp();
                +  var variable = variable_map.createVariable('name1', null, 'id1');
                +  variable_map.deleteVariable(variable);
                +  var result_array = variable_map.getVariablesOfType('');
                +  isEqualArrays([], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariablesOfType_DoesNotExist() {
                +  variableMapTest_setUp();
                +  var result_array = variable_map.getVariablesOfType('type1');
                +  isEqualArrays([], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariableTypes_Trivial() {
                +  variableMapTest_setUp();
                +  variable_map.createVariable('name1', 'type1', 'id1');
                +  variable_map.createVariable('name2', 'type1', 'id2');
                +  variable_map.createVariable('name3', 'type2', 'id3');
                +  variable_map.createVariable('name4', 'type3', 'id4');
                +  var result_array = variable_map.getVariableTypes();
                +  isEqualArrays(['type1', 'type2', 'type3'], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getVariableTypes_None() {
                +  variableMapTest_setUp();
                +  var result_array = variable_map.getVariableTypes();
                +  isEqualArrays([], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getAllVariables_Trivial() {
                +  variableMapTest_setUp();
                +  var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
                +  var var_2 = variable_map.createVariable('name2', 'type1', 'id2');
                +  var var_3 = variable_map.createVariable('name3', 'type2', 'id3');
                +  var result_array = variable_map.getAllVariables();
                +  isEqualArrays([var_1, var_2, var_3], result_array);
                +  variableMapTest_tearDown();
                +}
                +
                +function test_getAllVariables_None() {
                +  variableMapTest_setUp();
                +  var result_array = variable_map.getAllVariables();
                +  isEqualArrays([], result_array);
                +  variableMapTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/variable_model_test.js b/blockly/webif/static/blockly/tests/jsunit/variable_model_test.js
                new file mode 100644
                index 000000000..3f22f287a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/variable_model_test.js
                @@ -0,0 +1,91 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Tests for variable model.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +var variable;
                +var workspace;
                +
                +function variableModelTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +}
                +
                +function variableModelTest_tearDown() {
                +  workspace.dispose();
                +  variable = null;
                +}
                +
                +/**
                + * These tests check the constructor of the variable model.
                + */
                +function testInit_Trivial() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test', 'test_type',
                +    'test_id');
                +  assertEquals('test', variable.name);
                +  assertEquals('test_type', variable.type);
                +  assertEquals('test_id', variable.id_);
                +  variableModelTest_tearDown();
                +}
                +
                +function testInit_NullType() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test', null, 'test_id');
                +  assertEquals('', variable.type);
                +  variableModelTest_tearDown();
                +}
                +
                +function testInit_UndefinedType() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test', undefined, 'test_id');
                +  assertEquals('', variable.type);
                +  variableModelTest_tearDown();
                +}
                +
                +function testInit_NullId() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test', 'test_type', null);
                +  assertEquals('test', variable.name);
                +  assertEquals('test_type', variable.type);
                +  assertNotNull(variable.id_);
                +  variableModelTest_tearDown();
                +}
                +
                +function testInit_UndefinedId() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test', 'test_type', undefined);
                +  assertEquals('test', variable.name);
                +  assertEquals('test_type', variable.type);
                +  assertNotNull(variable.id_);
                +  variableModelTest_tearDown();
                +}
                +
                +function testInit_OnlyNameProvided() {
                +  variableModelTest_setUp();
                +  variable = new Blockly.VariableModel(workspace, 'test');
                +  assertEquals('test', variable.name);
                +  assertEquals('', variable.type);
                +  assertNotNull(variable.id_);
                +  variableModelTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/workspace_test.js b/blockly/webif/static/blockly/tests/jsunit/workspace_test.js
                new file mode 100644
                index 000000000..17755f158
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/workspace_test.js
                @@ -0,0 +1,490 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +goog.require('goog.testing.MockControl');
                +
                +var workspace;
                +var mockControl_;
                +Blockly.defineBlocksWithJsonArray([{
                +  "type": "get_var_block",
                +  "message0": "%1",
                +  "args0": [
                +    {
                +      "type": "field_variable",
                +      "name": "VAR",
                +    }
                +  ]
                +}]);
                +
                +function workspaceTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  mockControl_ = new goog.testing.MockControl();
                +}
                +
                +function workspaceTest_tearDown() {
                +  mockControl_.$tearDown();
                +  workspace.dispose();
                +}
                +
                +/**
                + * Create a test get_var_block.
                + * @param {?string} variable_name The string to put into the variable field.
                + * @return {!Blockly.Block} The created block.
                + */
                +function createMockBlock(variable_name) {
                +  var block = new Blockly.Block(workspace, 'get_var_block');
                +  block.inputList[0].fieldRow[0].setValue(variable_name);
                +  return block;
                +}
                +
                +function test_emptyWorkspace() {
                +  workspaceTest_setUp();
                +  try {
                +    assertEquals('Empty workspace (1).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Empty workspace (2).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Empty workspace (3).', 0, workspace.getAllBlocks().length);
                +    workspace.clear();
                +    assertEquals('Empty workspace (4).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Empty workspace (5).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Empty workspace (6).', 0, workspace.getAllBlocks().length);
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_flatWorkspace() {
                +  workspaceTest_setUp();
                +  try {
                +    var blockA = workspace.newBlock('');
                +    assertEquals('One block workspace (1).', 1, workspace.getTopBlocks(true).length);
                +    assertEquals('One block workspace (2).', 1, workspace.getTopBlocks(false).length);
                +    assertEquals('One block workspace (3).', 1, workspace.getAllBlocks().length);
                +    var blockB = workspace.newBlock('');
                +    assertEquals('Two block workspace (1).', 2, workspace.getTopBlocks(true).length);
                +    assertEquals('Two block workspace (2).', 2, workspace.getTopBlocks(false).length);
                +    assertEquals('Two block workspace (3).', 2, workspace.getAllBlocks().length);
                +    blockA.dispose();
                +    assertEquals('One block workspace (4).', 1, workspace.getTopBlocks(true).length);
                +    assertEquals('One block workspace (5).', 1, workspace.getTopBlocks(false).length);
                +    assertEquals('One block workspace (6).', 1, workspace.getAllBlocks().length);
                +    workspace.clear();
                +    assertEquals('Cleared workspace (1).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Cleared workspace (2).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Cleared workspace (3).', 0, workspace.getAllBlocks().length);
                +  } finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_maxBlocksWorkspace() {
                +  workspaceTest_setUp();
                +  try {
                +    var blockA = workspace.newBlock('');
                +    var blockB = workspace.newBlock('');
                +    assertEquals('Infinite capacity.', Infinity, workspace.remainingCapacity());
                +    workspace.options.maxBlocks = 3;
                +    assertEquals('Three capacity.', 1, workspace.remainingCapacity());
                +    workspace.options.maxBlocks = 2;
                +    assertEquals('Two capacity.', 0, workspace.remainingCapacity());
                +    workspace.options.maxBlocks = 1;
                +    assertEquals('One capacity.', -1, workspace.remainingCapacity());
                +    workspace.options.maxBlocks = 0;
                +    assertEquals('Zero capacity.', -2, workspace.remainingCapacity());
                +    workspace.clear();
                +    assertEquals('Cleared capacity.', 0, workspace.remainingCapacity());
                +  } finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_getWorkspaceById() {
                +  var workspaceA = new Blockly.Workspace();
                +  var workspaceB = new Blockly.Workspace();
                +  try {
                +    assertEquals('Find workspaceA.', workspaceA,
                +        Blockly.Workspace.getById(workspaceA.id));
                +    assertEquals('Find workspaceB.', workspaceB,
                +        Blockly.Workspace.getById(workspaceB.id));
                +    assertEquals('No workspace found.', null,
                +        Blockly.Workspace.getById('I do not exist.'));
                +    workspaceA.dispose();
                +    assertEquals('Can\'t find workspaceA.', null,
                +        Blockly.Workspace.getById(workspaceA.id));
                +    assertEquals('WorkspaceB exists.', workspaceB,
                +        Blockly.Workspace.getById(workspaceB.id));
                +  } finally {
                +    workspaceB.dispose();
                +    workspaceA.dispose();
                +  }
                +}
                +
                +function test_getBlockById() {
                +  workspaceTest_setUp();
                +  try {
                +    var blockA = workspace.newBlock('');
                +    var blockB = workspace.newBlock('');
                +    assertEquals('Find blockA.', blockA, workspace.getBlockById(blockA.id));
                +    assertEquals('Find blockB.', blockB, workspace.getBlockById(blockB.id));
                +    assertEquals('No block found.', null,
                +        workspace.getBlockById('I do not exist.'));
                +    blockA.dispose();
                +    assertEquals('Can\'t find blockA.', null, workspace.getBlockById(blockA.id));
                +    assertEquals('BlockB exists.', blockB, workspace.getBlockById(blockB.id));
                +    workspace.clear();
                +    assertEquals('Can\'t find blockB.', null, workspace.getBlockById(blockB.id));
                +  } finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_deleteVariable_InternalTrivial() {
                +  workspaceTest_setUp();
                +  var var_1 = workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  createMockBlock('name1');
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +
                +  workspace.deleteVariableInternal_(var_1);
                +  var variable = workspace.getVariable('name1');
                +  var block_var_name = workspace.topBlocks_[0].getVars()[0];
                +  assertNull(variable);
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  assertEquals('name2', block_var_name);
                +  workspaceTest_tearDown();
                +}
                +
                +// TODO(marisaleung): Test the alert for deleting a variable that is a procedure.
                +
                +function test_updateVariableStore_TrivialNoClear() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
                +    [workspace], [['name1', 'name2']]);
                +
                +  try {
                +    workspace.updateVariableStore();
                +    checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +    checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_updateVariableStore_NameNotInvariableMap_NoClear() {
                +  workspaceTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
                +    [workspace], [['name1']]);
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +
                +  try {
                +    workspace.updateVariableStore();
                +    checkVariableValues(workspace, 'name1', '', '1');
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_updateVariableStore_ClearAndAllInUse() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
                +    [workspace], [['name1', 'name2']]);
                +
                +  try {
                +    workspace.updateVariableStore(true);
                +    checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +    checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_updateVariableStore_ClearAndOneInUse() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
                +    [workspace], [['name1']]);
                +
                +  try {
                +    workspace.updateVariableStore(true);
                +    checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +    var variabe = workspace.getVariable('name2');
                +    assertNull(variable);
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_addTopBlock_TrivialFlyoutIsTrue() {
                +  workspaceTest_setUp();
                +  workspace.isFlyout = true;
                +  var block = createMockBlock();
                +  workspace.removeTopBlock(block);
                +  setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables', [block],
                +    [['name1']]);
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +
                +  try {
                +    workspace.addTopBlock(block);
                +    checkVariableValues(workspace, 'name1', '', '1');
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_clear_Trivial() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
                +    null);
                +
                +  try {
                +    workspace.clear();
                +    var topBlocks_length = workspace.topBlocks_.length;
                +    var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
                +    assertEquals(0, topBlocks_length);
                +    assertEquals(0, varMapLength);
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_clear_NoVariables() {
                +  workspaceTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
                +    null);
                +
                +  try {
                +    workspace.clear();
                +    var topBlocks_length = workspace.topBlocks_.length;
                +    var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
                +    assertEquals(0, topBlocks_length);
                +    assertEquals(0, varMapLength);
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_renameVariable_NoBlocks() {
                +  // Expect 'renameVariable' to create new variable with newName.
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var newName = 'name2';
                +    // Mocked setGroup to ensure only one call to the mocked genUid.
                +  setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
                +    null);
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +
                +  try {
                +    workspace.renameVariable(oldName, newName);
                +    checkVariableValues(workspace, 'name2', '', '1');
                +    var variable = workspace.getVariable(oldName);
                +    assertNull(variable);
                +  }
                +  finally {
                +    workspaceTest_tearDown();
                +  }
                +}
                +
                +function test_renameVariable_SameNameNoBlocks() {
                +  // Expect 'renameVariable' to create new variable with newName.
                +  workspaceTest_setUp();
                +  var name = 'name1';
                +  workspace.createVariable(name, 'type1', 'id1');
                +
                +  workspace.renameVariable(name, name);
                +  checkVariableValues(workspace, name, 'type1', 'id1');
                +  workspaceTest_tearDown();
                +}
                +
                +function test_renameVariable_OnlyOldNameBlockExists() {
                +  // Expect 'renameVariable' to change oldName variable name to newName.
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var newName = 'name2';
                +  workspace.createVariable(oldName, 'type1', 'id1');
                +  createMockBlock(oldName);
                +
                +  workspace.renameVariable(oldName, newName);
                +  checkVariableValues(workspace, newName, 'type1', 'id1');
                +  var variable = workspace.getVariable(oldName);
                +  var block_var_name = workspace.topBlocks_[0].getVars()[0];
                +  assertNull(variable);
                +  assertEquals(newName, block_var_name);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_renameVariable_TwoVariablesSameType() {
                +  // Expect 'renameVariable' to change oldName variable name to newName.
                +  // Expect oldName block name to change to newName
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var newName = 'name2';
                +  workspace.createVariable(oldName, 'type1', 'id1');
                +  workspace.createVariable(newName, 'type1', 'id2');
                +  createMockBlock(oldName);
                +  createMockBlock(newName);
                +
                +  workspace.renameVariable(oldName, newName);
                +  checkVariableValues(workspace, newName, 'type1', 'id2');
                +  var variable = workspace.getVariable(oldName);
                +  var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
                +  var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
                +  assertNull(variable);
                +  assertEquals(newName, block_var_name_1);
                +  assertEquals(newName, block_var_name_2);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_renameVariable_TwoVariablesDifferentType() {
                +  // Expect triggered error because of different types
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var newName = 'name2';
                +  workspace.createVariable(oldName, 'type1', 'id1');
                +  workspace.createVariable(newName, 'type2', 'id2');
                +  createMockBlock(oldName);
                +  createMockBlock(newName);
                +
                +  try {
                +    workspace.renameVariable(oldName, newName);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  }
                +  checkVariableValues(workspace, oldName, 'type1', 'id1');
                +  checkVariableValues(workspace, newName, 'type2', 'id2');
                +  var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
                +  var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
                +  assertEquals(oldName, block_var_name_1);
                +  assertEquals(newName, block_var_name_2);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_renameVariable_OldCase() {
                +  // Expect triggered error because of different types
                +  workspaceTest_setUp();
                +  var oldCase = 'Name1';
                +  var newName = 'name1';
                +  workspace.createVariable(oldCase, 'type1', 'id1');
                +  createMockBlock(oldCase);
                +
                +  workspace.renameVariable(oldCase, newName);
                +  checkVariableValues(workspace, newName, 'type1', 'id1');
                +  var result_oldCase = workspace.getVariable(oldCase).name;
                +  assertNotEquals(oldCase, result_oldCase);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_renameVariable_TwoVariablesAndOldCase() {
                +  // Expect triggered error because of different types
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var oldCase = 'Name2';
                +  var newName = 'name2';
                +  workspace.createVariable(oldName, 'type1', 'id1');
                +  workspace.createVariable(oldCase, 'type1', 'id2');
                +  createMockBlock(oldName);
                +  createMockBlock(oldCase);
                +
                +  workspace.renameVariable(oldName, newName);
                +
                +  checkVariableValues(workspace, newName, 'type1', 'id2');
                +  var variable = workspace.getVariable(oldName);
                +  var result_oldCase = workspace.getVariable(oldCase).name;
                +  var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
                +  var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
                +  assertNull(variable);
                +  assertNotEquals(oldCase, result_oldCase);
                +  assertEquals(newName, block_var_name_1);
                +  assertEquals(newName, block_var_name_2);
                +  workspaceTest_tearDown();
                +}
                +
                +// Extra testing not required for renameVariableById. It calls renameVariable
                +// and that has extensive testing.
                +function test_renameVariableById_TwoVariablesSameType() {
                +  // Expect 'renameVariableById' to change oldName variable name to newName.
                +  // Expect oldName block name to change to newName
                +  workspaceTest_setUp();
                +  var oldName = 'name1';
                +  var newName = 'name2';
                +  workspace.createVariable(oldName, 'type1', 'id1');
                +  workspace.createVariable(newName, 'type1', 'id2');
                +  createMockBlock(oldName);
                +  createMockBlock(newName);
                +
                +  workspace.renameVariableById('id1', newName);
                +  checkVariableValues(workspace, newName, 'type1', 'id2');
                +  var variable = workspace.getVariable(oldName);
                +  var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
                +  var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
                +  assertNull(variable);
                +  assertEquals(newName, block_var_name_1);
                +  assertEquals(newName, block_var_name_2);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_deleteVariable_Trivial() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type1', 'id2');
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +
                +  workspace.deleteVariable('name1');
                +  checkVariableValues(workspace, 'name2', 'type1', 'id2');
                +  var variable = workspace.getVariable('name1');
                +  var block_var_name = workspace.topBlocks_[0].getVars()[0];
                +  assertNull(variable);
                +  assertEquals('name2', block_var_name);
                +  workspaceTest_tearDown();
                +}
                +
                +function test_deleteVariableById_Trivial() {
                +  workspaceTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type1', 'id2');
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +
                +  workspace.deleteVariableById('id1');
                +  checkVariableValues(workspace, 'name2', 'type1', 'id2');
                +  var variable = workspace.getVariable('name1');
                +  var block_var_name = workspace.topBlocks_[0].getVars()[0];
                +  assertNull(variable);
                +  assertEquals('name2', block_var_name);
                +  workspaceTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/workspace_undo_redo_test.js b/blockly/webif/static/blockly/tests/jsunit/workspace_undo_redo_test.js
                new file mode 100644
                index 000000000..33dc855d7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/workspace_undo_redo_test.js
                @@ -0,0 +1,417 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                + /**
                + * @fileoverview Tests for Blockly.Workspace.undo.
                + * @author marisaleung@google.com (Marisa Leung)
                + */
                +'use strict';
                +
                +goog.require('goog.events.EventHandler');
                +goog.require('goog.testing');
                +goog.require('goog.testing.events');
                +goog.require('goog.testing.MockControl');
                +
                +
                +var workspace;
                +var mockControl_;
                +var savedFireFunc = Blockly.Events.fire;
                +Blockly.defineBlocksWithJsonArray([{
                +  "type": "get_var_block",
                +  "message0": "%1",
                +  "args0": [
                +    {
                +      "type": "field_variable",
                +      "name": "VAR",
                +    }
                +  ]
                +}]);
                +
                +function temporary_fireEvent(event) {
                +  if (!Blockly.Events.isEnabled()) {
                +    return;
                +  }
                +  Blockly.Events.FIRE_QUEUE_.push(event);
                +  Blockly.Events.fireNow_();
                +}
                +
                +function undoRedoTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  mockControl_ = new goog.testing.MockControl();
                +  Blockly.Events.fire = temporary_fireEvent;
                +}
                +
                +function undoRedoTest_tearDown() {
                +  mockControl_.$tearDown();
                +  workspace.dispose();
                +  Blockly.Events.fire = savedFireFunc;
                +}
                +
                +/**
                + * Create a test get_var_block.
                + * @param {string} variableName The string to put into the variable field.
                + * @return {!Blockly.Block} The created block.
                + */
                +function createMockBlock(variableName) {
                +  var block = new Blockly.Block(workspace, 'get_var_block');
                +  block.inputList[0].fieldRow[0].setValue(variableName);
                +  return block;
                +}
                +
                +/**
                + * Check that the top block with the given index contains a variable with
                + *     the given name.
                + * @param {number} blockIndex The index of the top block.
                + * @param {string} name The expected name of the variable in the block.
                + */
                +function undoRedoTest_checkBlockVariableName(blockIndex, name) {
                +  var blockVarName = workspace.topBlocks_[blockIndex].getVars()[0];
                +  assertEquals(name, blockVarName);
                +}
                +
                +function createTwoVarsEmptyType() {
                +  workspace.createVariable('name1', '', 'id1');
                +  workspace.createVariable('name2', '', 'id2');
                +}
                +
                +function test_undoCreateVariable_Trivial() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  assertNull(workspace.getVariableById('id2'));
                +  workspace.undo();
                +  assertNull(workspace.getVariableById('id1'));
                +  assertNull(workspace.getVariableById('id2'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_redoAndUndoCreateVariable_Trivial() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +
                +  workspace.undo();
                +  workspace.undo(true);
                +
                +  // Expect that variable 'id2' is recreated
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +
                +  workspace.undo();
                +  workspace.undo();
                +  workspace.undo(true);
                +
                +  // Expect that variable 'id1' is recreated
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  assertNull(workspace.getVariableById('id2'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoDeleteVariable_NoBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id2');
                +
                +  workspace.undo();
                +  assertNull(workspace.getVariableById('id1'));
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoDeleteVariable_WithBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id2');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name2');
                +  assertNull(workspace.getVariableById('id1'));
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name2');
                +  undoRedoTest_checkBlockVariableName(1, 'name1');
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_redoAndUndoDeleteVariable_NoBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id2');
                +
                +  workspace.undo();
                +  workspace.undo(true);
                +  // Expect that both variables are deleted
                +  assertNull(workspace.getVariableById('id1'));
                +  assertNull(workspace.getVariableById('id2'));
                +
                +  workspace.undo();
                +  workspace.undo();
                +  workspace.undo(true);
                +  // Expect that variable 'id2' is recreated
                +  assertNull(workspace.getVariableById('id1'));
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_redoAndUndoDeleteVariable_WithBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id2');
                +
                +  workspace.undo();
                +  workspace.undo(true);
                +  // Expect that both variables are deleted
                +  assertEquals(0, workspace.topBlocks_.length);
                +  assertNull(workspace.getVariableById('id1'));
                +  assertNull(workspace.getVariableById('id2'));
                +
                +  workspace.undo();
                +  workspace.undo();
                +  workspace.undo(true);
                +  // Expect that variable 'id2' is recreated
                +  undoRedoTest_checkBlockVariableName(0, 'name2');
                +  assertNull(workspace.getVariableById('id1'));
                +  checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_redoAndUndoDeleteVariableTwice_NoBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id1');
                +
                +  // Check the undoStack only recorded one delete event.
                +  var undoStack = workspace.undoStack_;
                +  assertEquals('var_delete', undoStack[undoStack.length-1].type);
                +  assertNotEquals('var_delete', undoStack[undoStack.length-2].type);
                +
                +  // undo delete
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +
                +  // redo delete
                +  workspace.undo(true);
                +  assertNull(workspace.getVariableById('id1'));
                +
                +  // redo delete, nothing should happen
                +  workspace.undo(true);
                +  assertNull(workspace.getVariableById('id1'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_redoAndUndoDeleteVariableTwice_WithBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  createMockBlock('name1');
                +  workspace.deleteVariableById('id1');
                +  workspace.deleteVariableById('id1');
                +
                +  // Check the undoStack only recorded one delete event.
                +  var undoStack = workspace.undoStack_;
                +  assertEquals('var_delete', undoStack[undoStack.length-1].type);
                +  assertEquals('delete', undoStack[undoStack.length-2].type);
                +  assertNotEquals('var_delete', undoStack[undoStack.length-3].type);
                +
                +  // undo delete
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name1');
                +  checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +
                +  // redo delete
                +  workspace.undo(true);
                +  assertEquals(0, workspace.topBlocks_.length);
                +  assertNull(workspace.getVariableById('id1'));
                +
                +  // redo delete, nothing should happen
                +  workspace.undo(true);
                +  assertEquals(0, workspace.topBlocks_.length);
                +  assertNull(workspace.getVariableById('id1'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_NeitherVariableExists() {
                +  // Expect that a variable with the name, 'name2', and the generated UUID,
                +  // 'id2', to be created when rename is called. Undo removes this variable
                +  // and redo recreates it.
                +  undoRedoTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null,
                +    ['rename_group', 'id2', 'delete_group']);
                +  workspace.renameVariable('name1', 'name2');
                +
                +  workspace.undo();
                +  assertNull(workspace.getVariableById('id2'));
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_OneExists_NoBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', '', 'id1');
                +  workspace.renameVariable('name1', 'name2');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  assertNull(workspace.getVariable('name2'));
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'name2', '', 'id1');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_OneExists_WithBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', '', 'id1');
                +  createMockBlock('name1');
                +  workspace.renameVariable('name1', 'name2');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name1');
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  assertNull(workspace.getVariable('name2'));
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'name2', '', 'id1');
                +  undoRedoTest_checkBlockVariableName(0, 'name2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_BothExist_NoBlocks() {
                +  undoRedoTest_setUp();
                +  createTwoVarsEmptyType();
                +  workspace.renameVariable('name1', 'name2');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +  assertNull(workspace.getVariable('name1'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_BothExist_WithBlocks() {
                +  undoRedoTest_setUp();
                +  createTwoVarsEmptyType();
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +  workspace.renameVariable('name1', 'name2');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name1');
                +  undoRedoTest_checkBlockVariableName(1, 'name2');
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +
                +  workspace.undo(true);
                +  undoRedoTest_checkBlockVariableName(0, 'name2');
                +  undoRedoTest_checkBlockVariableName(1, 'name2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_BothExistCaseChange_NoBlocks() {
                +  undoRedoTest_setUp();
                +  createTwoVarsEmptyType();
                +  workspace.renameVariable('name1', 'Name2');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'Name2', '', 'id2');
                +  assertNull(workspace.getVariable('name1'));
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_BothExistCaseChange_WithBlocks() {
                +  undoRedoTest_setUp();
                +  createTwoVarsEmptyType();
                +  createMockBlock('name1');
                +  createMockBlock('name2');
                +  workspace.renameVariable('name1', 'Name2');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name1');
                +  undoRedoTest_checkBlockVariableName(1, 'name2');
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +  checkVariableValues(workspace, 'name2', '', 'id2');
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'Name2', '', 'id2');
                +  assertNull(workspace.getVariable('name1'));
                +  undoRedoTest_checkBlockVariableName(0, 'Name2');
                +  undoRedoTest_checkBlockVariableName(1, 'Name2');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_OnlyCaseChange_NoBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', '', 'id1');
                +  workspace.renameVariable('name1', 'Name1');
                +
                +  workspace.undo();
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'Name1', '', 'id1');
                +  undoRedoTest_tearDown();
                +}
                +
                +function test_undoRedoRenameVariable_OnlyCaseChange_WithBlocks() {
                +  undoRedoTest_setUp();
                +  workspace.createVariable('name1', '', 'id1');
                +  createMockBlock('name1');
                +  workspace.renameVariable('name1', 'Name1');
                +
                +  workspace.undo();
                +  undoRedoTest_checkBlockVariableName(0, 'name1');
                +  checkVariableValues(workspace, 'name1', '', 'id1');
                +
                +  workspace.undo(true);
                +  checkVariableValues(workspace, 'Name1', '', 'id1');
                +  undoRedoTest_checkBlockVariableName(0, 'Name1');
                +  undoRedoTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/jsunit/xml_test.js b/blockly/webif/static/blockly/tests/jsunit/xml_test.js
                new file mode 100644
                index 000000000..ea682dfb7
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/jsunit/xml_test.js
                @@ -0,0 +1,366 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2014 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +goog.require('goog.testing');
                +goog.require('goog.testing.MockControl');
                +
                +var mockControl_;
                +var workspace;
                +var XML_TEXT = ['<xml xmlns="http://www.w3.org/1999/xhtml">',
                +  '  <block type="controls_repeat_ext" inline="true" x="21" y="23">',
                +  '    <value name="TIMES">',
                +  '      <block type="math_number">',
                +  '        <field name="NUM">10</field>',
                +  '      </block>',
                +  '    </value>',
                +  '    <statement name="DO">',
                +  '      <block type="variables_set" inline="true">',
                +  '        <field name="VAR">item</field>',
                +  '        <value name="VALUE">',
                +  '          <block type="lists_create_empty"></block>',
                +  '        </value>',
                +  '        <next>',
                +  '          <block type="text_print" inline="false">',
                +  '            <value name="TEXT">',
                +  '              <block type="text">',
                +  '                <field name="TEXT">Hello</field>',
                +  '              </block>',
                +  '            </value>',
                +  '          </block>',
                +  '        </next>',
                +  '      </block>',
                +  '    </statement>',
                +  '  </block>',
                +  '</xml>'].join('\n');
                +
                +function xmlTest_setUp() {
                +  workspace = new Blockly.Workspace();
                +  mockControl_ = new goog.testing.MockControl();
                +}
                +
                +function xmlTest_setUpWithMockBlocks() {
                +  xmlTest_setUp();
                +  Blockly.defineBlocksWithJsonArray([{
                +    'type': 'field_variable_test_block',
                +    'message0': '%1',
                +    'args0': [
                +      {
                +        'type': 'field_variable',
                +        'name': 'VAR',
                +        'variable': 'item'
                +      }
                +    ],
                +  }]);
                +}
                +
                +function xmlTest_tearDown() {
                +  mockControl_.$tearDown();
                +  workspace.dispose();
                +}
                +
                +function xmlTest_tearDownWithMockBlocks() {
                +  xmlTest_tearDown();
                +  delete Blockly.Blocks.field_variable_test_block;
                +}
                +
                +/**
                + * Check the values of the non variable field dom.
                + * @param {!Element} fieldDom The xml dom of the non variable field.
                + * @param {!string} name The expected name of the variable.
                + * @param {!string} text The expected text of the variable.
                + */
                +function xmlTest_checkNonVariableField(fieldDom, name, text) {
                +  assertEquals(text, fieldDom.textContent);
                +  assertEquals(name, fieldDom.getAttribute('name'));
                +  assertNull(fieldDom.getAttribute('id'));
                +  assertNull(fieldDom.getAttribute('variableType'));
                +}
                +
                +/**
                + * Check the values of the variable field DOM.
                + * @param {!Element} fieldDom The xml dom of the variable field.
                + * @param {!string} name The expected name of the variable.
                + * @param {!string} type The expected type of the variable.
                + * @param {!string} id The expected id of the variable.
                + * @param {!string} text The expected text of the variable.
                + */
                +function xmlTest_checkVariableFieldDomValues(fieldDom, name, type, id, text) {
                +  assertEquals(name, fieldDom.getAttribute('name'));
                +  assertEquals(type, fieldDom.getAttribute('variableType'));
                +  assertEquals(id, fieldDom.getAttribute('id'));
                +  assertEquals(text, fieldDom.textContent);
                +}
                +
                +/**
                + * Check the values of the variable DOM.
                + * @param {!Element} variableDom The xml dom of the variable.
                + * @param {!string} type The expected type of the variable.
                + * @param {!string} id The expected id of the variable.
                + * @param {!string} text The expected text of the variable.
                + */
                +function xmlTest_checkVariableDomValues(variableDom, type, id, text) {
                +  assertEquals(type, variableDom.getAttribute('type'));
                +  assertEquals(id, variableDom.getAttribute('id'));
                +  assertEquals(text, variableDom.textContent);
                +}
                +
                +function test_textToDom() {
                +  var dom = Blockly.Xml.textToDom(XML_TEXT);
                +  assertEquals('XML tag', 'xml', dom.nodeName);
                +  assertEquals('Block tags', 6, dom.getElementsByTagName('block').length);
                +}
                +
                +function test_domToText() {
                +  var dom = Blockly.Xml.textToDom(XML_TEXT);
                +  var text = Blockly.Xml.domToText(dom);
                +  assertEquals('Round trip', XML_TEXT.replace(/\s+/g, ''),
                +      text.replace(/\s+/g, ''));
                +}
                +
                +function test_domToWorkspace_BackwardCompatibility() {
                +  // Expect that workspace still loads without serialized variables.
                +  xmlTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '1']);
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml>' +
                +        '  <block type="field_variable_test_block" id="block_id">' +
                +        '    <field name="VAR">name1</field>' +
                +        '  </block>' +
                +        '</xml>');
                +    Blockly.Xml.domToWorkspace(dom, workspace);
                +    assertEquals('Block count', 1, workspace.getAllBlocks().length);
                +    checkVariableValues(workspace, 'name1', '', '1');
                +  } finally {
                +    xmlTest_tearDownWithMockBlocks();
                +  }
                +}
                +
                +function test_domToWorkspace_VariablesAtTop() {
                +  // Expect that unused variables are preserved.
                +  xmlTest_setUpWithMockBlocks();
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml>' +
                +        '  <variables>' +
                +        '    <variable type="type1" id="id1">name1</variable>' +
                +        '    <variable type="type2" id="id2">name2</variable>' +
                +        '    <variable type="" id="id3">name3</variable>' +
                +        '  </variables>' +
                +        '  <block type="field_variable_test_block">' +
                +        '    <field name="VAR" id="id3" variableType="">name3</field>' +
                +        '  </block>' +
                +        '</xml>');
                +    Blockly.Xml.domToWorkspace(dom, workspace);
                +    assertEquals('Block count', 1, workspace.getAllBlocks().length);
                +    checkVariableValues(workspace, 'name1', 'type1', 'id1');
                +    checkVariableValues(workspace, 'name2', 'type2', 'id2');
                +    checkVariableValues(workspace, 'name3', '', 'id3');
                +  } finally {
                +    xmlTest_tearDownWithMockBlocks();
                +  }
                +}
                +
                +function test_domToWorkspace_VariablesAtTop_DuplicateVariablesTag() {
                +  // Expect thrown Error because of duplicate 'variables' tag
                +  xmlTest_setUpWithMockBlocks();
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml>' +
                +        '  <variables>' +
                +        '  </variables>' +
                +        '  <variables>' +
                +        '  </variables>' +
                +        '</xml>');
                +    Blockly.Xml.domToWorkspace(dom, workspace);
                +    fail();
                +  }
                +  catch (e) {
                +    // expected
                +  } finally {
                +    xmlTest_tearDownWithMockBlocks();
                +  }
                +}
                +
                +function test_domToWorkspace_VariablesAtTop_MissingType() {
                +  // Expect thrown error when a variable tag is missing the type attribute.
                +  workspace = new Blockly.Workspace();
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml>' +
                +        '  <variables>' +
                +        '    <variable id="id1">name1</variable>' +
                +        '  </variables>' +
                +        '  <block type="field_variable_test_block">' +
                +        '    <field name="VAR" id="id1" variableType="">name3</field>' +
                +        '  </block>' +
                +        '</xml>');
                +    Blockly.Xml.domToWorkspace(dom, workspace);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_domToWorkspace_VariablesAtTop_MismatchBlockType() {
                +  // Expect thrown error when the serialized type of a variable does not match
                +  // the type of a variable field that references it.
                +  xmlTest_setUpWithMockBlocks();
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml>' +
                +        '  <variables>' +
                +        '    <variable type="type1" id="id1">name1</variable>' +
                +        '  </variables>' +
                +        '  <block type="field_variable_test_block">' +
                +        '    <field name="VAR" id="id1" variableType="">name1</field>' +
                +        '  </block>' +
                +        '</xml>');
                +    Blockly.Xml.domToWorkspace(dom, workspace);
                +    fail();
                +  } catch (e) {
                +    // expected
                +  } finally {
                +    xmlTest_tearDownWithMockBlocks();
                +  }
                +}
                +
                +function test_domToPrettyText() {
                +  var dom = Blockly.Xml.textToDom(XML_TEXT);
                +  var text = Blockly.Xml.domToPrettyText(dom);
                +  assertEquals('Round trip', XML_TEXT.replace(/\s+/g, ''),
                +      text.replace(/\s+/g, ''));
                +}
                +
                +/**
                + * Tests the that appendDomToWorkspace works in a headless mode.
                + * Also see test_appendDomToWorkspace() in workspace_svg_test.js.
                + */
                +function test_appendDomToWorkspace() {
                +  Blockly.Blocks.test_block = {
                +    init: function() {
                +      this.jsonInit({
                +        message0: 'test',
                +      });
                +    }
                +  };
                +
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +        '<xml xmlns="http://www.w3.org/1999/xhtml">' +
                +        '  <block type="test_block" inline="true" x="21" y="23">' +
                +        '  </block>' +
                +        '</xml>');
                +    workspace = new Blockly.Workspace();
                +    Blockly.Xml.appendDomToWorkspace(dom, workspace);
                +    assertEquals('Block count', 1, workspace.getAllBlocks().length);
                +    var newBlockIds = Blockly.Xml.appendDomToWorkspace(dom, workspace);
                +    assertEquals('Block count', 2, workspace.getAllBlocks().length);
                +    assertEquals('Number of new block ids',1,newBlockIds.length);
                +  } finally {
                +    delete Blockly.Blocks.test_block;
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_blockToDom_fieldToDom_trivial() {
                +  xmlTest_setUpWithMockBlocks();
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  block.inputList[0].fieldRow[0].setValue('name1');
                +  var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
                +  xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', 'type1', 'id1',
                +    'name1');
                +  xmlTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockToDom_fieldToDom_defaultCase() {
                +  xmlTest_setUpWithMockBlocks();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '1']);
                +  workspace.createVariable('name1');
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  block.inputList[0].fieldRow[0].setValue('name1');
                +  var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
                +  // Expect type is '' and id is '1' since we don't specify type and id.
                +  xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', '', '1', 'name1');
                +  xmlTest_tearDownWithMockBlocks();
                +}
                +
                +function test_blockToDom_fieldToDom_notAFieldVariable() {
                +  Blockly.defineBlocksWithJsonArray([{
                +    "type": "field_angle_test_block",
                +    "message0": "%1",
                +    "args0": [
                +      {
                +        "type": "field_angle",
                +        "name": "VAR",
                +        "angle": 90
                +      }
                +    ],
                +  }]);
                +  xmlTest_setUpWithMockBlocks();
                +  var block = new Blockly.Block(workspace, 'field_angle_test_block');
                +  var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
                +  xmlTest_checkNonVariableField(resultFieldDom, 'VAR', '90');
                +  delete Blockly.Blocks.field_angle_block;
                +  xmlTest_tearDownWithMockBlocks();
                +}
                +
                +function test_variablesToDom_oneVariable() {
                +  xmlTest_setUp();
                +  setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
                +
                +  workspace.createVariable('name1');
                +  var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables());
                +  assertEquals(1, resultDom.children.length);
                +  var resultVariableDom = resultDom.children[0];
                +  assertEquals('name1', resultVariableDom.textContent);
                +  assertEquals('', resultVariableDom.getAttribute('type'));
                +  assertEquals('1', resultVariableDom.getAttribute('id'));
                +  xmlTest_tearDown();
                +}
                +
                +function test_variablesToDom_twoVariables_oneBlock() {
                +  xmlTest_setUpWithMockBlocks();
                +
                +  workspace.createVariable('name1', 'type1', 'id1');
                +  workspace.createVariable('name2', 'type2', 'id2');
                +  var block = new Blockly.Block(workspace, 'field_variable_test_block');
                +  block.inputList[0].fieldRow[0].setValue('name1');
                +
                +  var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables());
                +  assertEquals(2, resultDom.children.length);
                +  xmlTest_checkVariableDomValues(resultDom.children[0], 'type1', 'id1',
                +      'name1');
                +  xmlTest_checkVariableDomValues(resultDom.children[1], 'type2', 'id2',
                +      'name2');
                +  xmlTest_tearDownWithMockBlocks();
                +}
                +
                +function test_variablesToDom_noVariables() {
                +  xmlTest_setUp();
                +  workspace.createVariable('name1');
                +  var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables());
                +  assertEquals(1, resultDom.children.length);
                +  xmlTest_tearDown();
                +}
                diff --git a/blockly/webif/static/blockly/tests/multi_playground.html b/blockly/webif/static/blockly/tests/multi_playground.html
                new file mode 100644
                index 000000000..ae1a6580d
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/multi_playground.html
                @@ -0,0 +1,462 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +<meta charset="utf-8">
                +<title>Multi-toolbox Playground</title>
                +<script src="../blockly_uncompressed.js"></script>
                +<script src="../msg/messages.js"></script>
                +<script src="../blocks/logic.js"></script>
                +<script src="../blocks/loops.js"></script>
                +<script src="../blocks/math.js"></script>
                +<script src="../blocks/text.js"></script>
                +<script src="../blocks/lists.js"></script>
                +<script src="../blocks/colour.js"></script>
                +<script src="../blocks/variables.js"></script>
                +<script src="../blocks/procedures.js"></script>
                +<script>
                +'use strict';
                +var options = {
                +  comments: true,
                +  collapse: true,
                +  disable: true,
                +  maxBlocks: Infinity,
                +  media: '../media/',
                +  oneBasedIndex: true,
                +  readOnly: false,
                +  //rtl: false,
                +  scrollbars: true,
                +  trashcan: true,
                +  //toolbox: null,
                +  //horizontalLayout: false,
                +  //toolboxPosition: 'start',
                +  zoom: {
                +    controls: true,
                +    wheel: false,
                +    startScale: 1.0,
                +    maxScale: 4,
                +    minScale: 0.25,
                +    scaleSpeed: 1.1
                +  }
                +};
                +
                +function start() {
                +  var match = location.search.match(/toolbox=([^&]+)/);
                +  var toolbox =
                +      document.getElementById('toolbox-' + (match ? match[1] : 'categories'));
                +  document.forms.options.elements.toolbox.selectedIndex =
                +      Number(toolbox.getElementsByTagName('category').length == 0);
                +  startBlocklyInstance('VertStartLTR', false, false, 'start', toolbox);
                +  startBlocklyInstance('VertStartRTL', true, false, 'start', toolbox);
                +
                +  startBlocklyInstance('VertEndLTR', false, false, 'end', toolbox);
                +  startBlocklyInstance('VertEndRTL', true, false, 'end', toolbox);
                +
                +  startBlocklyInstance('HorizontalStartLTR', false, true, 'start', toolbox);
                +  startBlocklyInstance('HorizontalStartRTL', true, true, 'start', toolbox);
                +
                +  startBlocklyInstance('HorizontalEndLTR', false, true, 'end', toolbox);
                +  startBlocklyInstance('HorizontalEndRTL', true, true, 'end', toolbox);
                +}
                +
                +function startBlocklyInstance(suffix, rtl, horizontalLayout, position,
                +    toolbox) {
                +  options.rtl = rtl;
                +  options.toolbox = toolbox;
                +  options.horizontalLayout = horizontalLayout;
                +  options.toolboxPosition = position;
                +  Blockly.inject('blocklyDiv' + suffix, options);
                +}
                +</script>
                +
                +<style>
                +html, body {
                +  height: 100%;
                +}
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +}
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +
                +#octaweb {
                +  width: 100%;
                +}
                +#octaweb th {
                +  padding-top: 1em;
                +  width: 50%;
                +}
                +#octaweb td {
                +  width: 50%;
                +}
                +#octaweb td >div {
                +  height: 480px;
                +  width: 100%;
                +}
                +</style>
                +</head>
                +<body onload="start()">
                +  <h1>Blockly Multi Playground</h1>
                +
                +  <form id="options">
                +    <select name="toolbox" onchange="document.forms.options.submit()">
                +      <option value="categories">Categories</option>
                +      <option value="simple">Simple</option>
                +    </select>
                +  </form>
                +
                +  <table id="octaweb">
                +    <tr>
                +      <th>LTR, Vertical, Start</th>
                +      <th>RTL, Vertical, Start</th>
                +    </tr>
                +    <tr>
                +      <td><div id="blocklyDivVertStartLTR"></div></td>
                +      <td><div id="blocklyDivVertStartRTL"></div></td>
                +    </tr>
                +    <tr>
                +      <th>LTR, Vertical, End</th>
                +      <th>RTL, Vertical, End</th>
                +    </tr>
                +    <tr>
                +      <td><div id="blocklyDivVertEndLTR"></div></td>
                +      <td><div id="blocklyDivVertEndRTL"></div></td>
                +    </tr>
                +    <tr>
                +      <th>LTR, Horizontal, Start</th>
                +      <th>RTL, Horizontal, Start</th>
                +    </tr>
                +    <tr>
                +      <td><div id="blocklyDivHorizontalStartLTR"></div></td>
                +      <td><div id="blocklyDivHorizontalStartRTL"></div></td>
                +    </tr>
                +    <tr>
                +      <th>LTR, Horizontal, End</th>
                +      <th>RTL, Horizontal, End</th>
                +    </tr>
                +    <tr>
                +      <td><div id="blocklyDivHorizontalEndLTR"></div></td>
                +      <td><div id="blocklyDivHorizontalEndRTL"></div></td>
                +    </tr>
                +  </table>
                +
                +  <xml id="toolbox-simple" style="display: none">
                +    <block type="controls_if"></block>
                +    <block type="logic_compare"></block>
                +    <!-- <block type="control_repeat"></block> -->
                +    <block type="logic_operation"></block>
                +    <block type="controls_repeat_ext">
                +      <value name="TIMES">
                +        <shadow type="math_number">
                +          <field name="NUM">10</field>
                +        </shadow>
                +      </value>
                +    </block>
                +    <block type="logic_operation"></block>
                +    <block type="logic_negate"></block>
                +    <block type="logic_boolean"></block>
                +    <block type="logic_null" disabled="true"></block>
                +    <block type="logic_ternary"></block>
                +  </xml>
                +
                +  <xml id="toolbox-categories" style="display: none">
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null" disabled="true"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_repeat" disabled="true"></block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +        <value name="BY">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number" gap="32"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT"></field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <shadow type="text">
                +            <field name="TEXT">,</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_sort"></block>
                +    </category>
                +    <category name="Colour" colour="20">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +        <value name="GREEN">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="BLUE">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </shadow>
                +        </value>
                +        <value name="COLOUR2">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </shadow>
                +        </value>
                +        <value name="RATIO">
                +          <shadow type="math_number">
                +            <field name="NUM">0.5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +  </xml>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/playground.html b/blockly/webif/static/blockly/tests/playground.html
                new file mode 100644
                index 000000000..f062bf542
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/playground.html
                @@ -0,0 +1,742 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +<meta charset="utf-8">
                +<title>Blockly Playground</title>
                +<script src="../blockly_uncompressed.js"></script>
                +<script src="../generators/javascript.js"></script>
                +<script src="../generators/javascript/logic.js"></script>
                +<script src="../generators/javascript/loops.js"></script>
                +<script src="../generators/javascript/math.js"></script>
                +<script src="../generators/javascript/text.js"></script>
                +<script src="../generators/javascript/lists.js"></script>
                +<script src="../generators/javascript/colour.js"></script>
                +<script src="../generators/javascript/variables.js"></script>
                +<script src="../generators/javascript/procedures.js"></script>
                +<script src="../generators/python.js"></script>
                +<script src="../generators/python/logic.js"></script>
                +<script src="../generators/python/loops.js"></script>
                +<script src="../generators/python/math.js"></script>
                +<script src="../generators/python/text.js"></script>
                +<script src="../generators/python/lists.js"></script>
                +<script src="../generators/python/colour.js"></script>
                +<script src="../generators/python/variables.js"></script>
                +<script src="../generators/python/procedures.js"></script>
                +<script src="../generators/php.js"></script>
                +<script src="../generators/php/logic.js"></script>
                +<script src="../generators/php/loops.js"></script>
                +<script src="../generators/php/math.js"></script>
                +<script src="../generators/php/text.js"></script>
                +<script src="../generators/php/lists.js"></script>
                +<script src="../generators/php/colour.js"></script>
                +<script src="../generators/php/variables.js"></script>
                +<script src="../generators/php/procedures.js"></script>
                +<script src="../generators/lua.js"></script>
                +<script src="../generators/lua/logic.js"></script>
                +<script src="../generators/lua/loops.js"></script>
                +<script src="../generators/lua/math.js"></script>
                +<script src="../generators/lua/text.js"></script>
                +<script src="../generators/lua/lists.js"></script>
                +<script src="../generators/lua/colour.js"></script>
                +<script src="../generators/lua/variables.js"></script>
                +<script src="../generators/lua/procedures.js"></script>
                +<script src="../generators/dart.js"></script>
                +<script src="../generators/dart/logic.js"></script>
                +<script src="../generators/dart/loops.js"></script>
                +<script src="../generators/dart/math.js"></script>
                +<script src="../generators/dart/text.js"></script>
                +<script src="../generators/dart/lists.js"></script>
                +<script src="../generators/dart/colour.js"></script>
                +<script src="../generators/dart/variables.js"></script>
                +<script src="../generators/dart/procedures.js"></script>
                +<script src="../msg/messages.js"></script>
                +<script src="../blocks/logic.js"></script>
                +<script src="../blocks/loops.js"></script>
                +<script src="../blocks/math.js"></script>
                +<script src="../blocks/text.js"></script>
                +<script src="../blocks/lists.js"></script>
                +<script src="../blocks/colour.js"></script>
                +<script src="../blocks/variables.js"></script>
                +<script src="../blocks/procedures.js"></script>
                +<script>
                +'use strict';
                +var workspace = null;
                +var fakeDragStack = [];
                +
                +function start() {
                +  setBackgroundColor();
                +
                +  // Parse the URL arguments.
                +  var match = location.search.match(/dir=([^&]+)/);
                +  var rtl = match && match[1] == 'rtl';
                +  document.forms.options.elements.dir.selectedIndex = Number(rtl);
                +  var toolbox = getToolboxElement();
                +  document.forms.options.elements.toolbox.selectedIndex =
                +      Number(toolbox.getElementsByTagName('category').length == 0);
                +  match = location.search.match(/side=([^&]+)/);
                +  var side = match ? match[1] : 'start';
                +  document.forms.options.elements.side.value = side;
                +  // Create main workspace.
                +  workspace = Blockly.inject('blocklyDiv',
                +          {comments: true,
                +           collapse: true,
                +           disable: true,
                +           grid:
                +             {spacing: 25,
                +              length: 3,
                +              colour: '#ccc',
                +              snap: true},
                +           horizontalLayout: side == 'top' || side == 'bottom',
                +           maxBlocks: Infinity,
                +           media: '../media/',
                +           oneBasedIndex: true,
                +           readOnly: false,
                +           rtl: rtl,
                +           scrollbars: true,
                +           toolbox: toolbox,
                +           toolboxPosition: side == 'top' || side == 'start' ? 'start' : 'end',
                +           zoom:
                +             {controls: true,
                +              wheel: true,
                +              startScale: 1.0,
                +              maxScale: 4,
                +              minScale: .25,
                +              scaleSpeed: 1.1}
                +          });
                +  // Restore previously displayed text.
                +  if (sessionStorage) {
                +    var text = sessionStorage.getItem('textarea');
                +    if (text) {
                +      document.getElementById('importExport').value = text;
                +    }
                +    // Restore event logging state.
                +    var state = sessionStorage.getItem('logEvents');
                +    logEvents(Boolean(Number(state)));
                +  } else {
                +    // MSIE 11 does not support sessionStorage on file:// URLs.
                +    logEvents(false);
                +  }
                +  taChange();
                +}
                +
                +function setBackgroundColor() {
                +  var lilac = '#d6d6ff';
                +
                +  var currentPage = window.location.href;
                +  var regexFile = /^file[\S]*$/;
                +
                +  if (regexFile.test(currentPage)) {
                +    document.getElementsByTagName('body')[0].style.backgroundColor = lilac;
                +  }
                +}
                +
                +function getToolboxElement() {
                +  var match = location.search.match(/toolbox=([^&]+)/);
                +  return document.getElementById('toolbox-' + (match ? match[1] : 'categories'));
                +}
                +
                +function toXml() {
                +  var output = document.getElementById('importExport');
                +  var xml = Blockly.Xml.workspaceToDom(workspace);
                +  output.value = Blockly.Xml.domToPrettyText(xml);
                +  output.focus();
                +  output.select();
                +  taChange();
                +}
                +
                +function fromXml() {
                +  var input = document.getElementById('importExport');
                +  var xml = Blockly.Xml.textToDom(input.value);
                +  Blockly.Xml.domToWorkspace(xml, workspace);
                +  taChange();
                +}
                +
                +function toCode(lang) {
                +  var output = document.getElementById('importExport');
                +  output.value = Blockly[lang].workspaceToCode(workspace);
                +  taChange();
                +}
                +
                +// Disable the "Import from XML" button if the XML is invalid.
                +// Preserve text between page reloads.
                +function taChange() {
                +  var textarea = document.getElementById('importExport');
                +  if (sessionStorage) {
                +    sessionStorage.setItem('textarea', textarea.value);
                +  }
                +  var valid = true;
                +  try {
                +    Blockly.Xml.textToDom(textarea.value);
                +  } catch (e) {
                +    valid = false;
                +  }
                +  document.getElementById('import').disabled = !valid;
                +}
                +
                +function logEvents(state) {
                +  var checkbox = document.getElementById('logCheck');
                +  checkbox.checked = state;
                +  if (sessionStorage) {
                +    sessionStorage.setItem('logEvents', Number(state));
                +  }
                +  if (state) {
                +    workspace.addChangeListener(logger);
                +  } else {
                +    workspace.removeChangeListener(logger);
                +  }
                +}
                +
                +function logger(e) {
                +  console.log(e);
                +}
                +
                +function airstrike(n) {
                +  var prototypes = [];
                +  var toolbox = getToolboxElement();
                +  var blocks = toolbox.getElementsByTagName('block');
                +  for (var i = 0, block; block = blocks[i]; i++) {
                +    prototypes.push(block.getAttribute('type'));
                +  }
                +  for (var i = 0; i < n; i++) {
                +    var prototype = prototypes[Math.floor(Math.random() * prototypes.length)];
                +    var block = workspace.newBlock(prototype);
                +    block.initSvg();
                +    block.getSvgRoot().setAttribute('transform', 'translate(' +
                +        Math.round(Math.random() * 450 + 40) + ', ' +
                +        Math.round(Math.random() * 600 + 40) + ')');
                +    block.render();
                +  }
                +}
                +
                +function fakeDrag(id, dx, dy, opt_workspace) {
                +  var ws = opt_workspace || Blockly.getMainWorkspace();
                +  var blockToDrag = ws.getBlockById(id);
                +
                +  if (!blockToDrag) {
                +    fakeDragWrapper();
                +    return;
                +  }
                +  var blockTop = blockToDrag.svgGroup_.getBoundingClientRect().top;
                +  var blockLeft = blockToDrag.svgGroup_.getBoundingClientRect().left;
                +
                +  // Click somewhere on the block.
                +  var mouseDownEvent = new MouseEvent('mousedown',
                +      {clientX: blockLeft + 5, clientY: blockTop + 5});
                +  blockToDrag.onMouseDown_(mouseDownEvent);
                +
                +  // Throw in a move for good measure.
                +  setTimeout(
                +    function() {
                +      var mouseMoveEvent = new MouseEvent('mousemove',
                +          {clientX: blockLeft + dx,
                +          clientY: blockTop + dy});
                +      blockToDrag.onMouseMove_(mouseMoveEvent);
                +
                +      // Drop at dx, dy.
                +      setTimeout(
                +        function() {
                +          var mouseUpEvent = new MouseEvent('mouseup',
                +              {clientX: blockLeft + dx,
                +              clientY: blockTop + dy});
                +          blockToDrag.onMouseUp_(mouseUpEvent);
                +
                +          setTimeout(fakeDragWrapper(), 100);
                +        }, 100);
                +    }, 100);
                +};
                +
                +function fakeDragWrapper() {
                +  var dragInfo = fakeDragStack.pop();
                +  if (dragInfo) {
                +    fakeDrag(dragInfo.id, dragInfo.dx, dragInfo.dy, dragInfo.workspace);
                +  }
                +}
                +
                +function fakeManyDrags() {
                +  var blockList = workspace.getAllBlocks();
                +  for (var i = 0; i < 2 * blockList.length; i++) {
                +    fakeDragStack.push(
                +      {
                +        id: blockList[Math.round(Math.random() * (blockList.length - 1))].id,
                +        // Move some blocks up and to the left, but mostly down and to the right.
                +        dx: Math.round((Math.random() - 0.25) * 200),
                +        dy: Math.round((Math.random() - 0.25) * 200),
                +        workspace: workspace
                +      });
                +  }
                +  fakeDragWrapper();
                +}
                +
                +function spaghetti(n) {
                +  var xml = spaghettiXml;
                +  for(var i = 0; i < n; i++) {
                +    xml = xml.replace(/(<(statement|next)( name="DO0")?>)<\//g,
                +        '$1' + spaghettiXml + '</');
                +  }
                +  xml = '<xml xmlns="http://www.w3.org/1999/xhtml">' + xml + '</xml>';
                +  var dom = Blockly.Xml.textToDom(xml);
                +  console.time('Spaghetti domToWorkspace');
                +  Blockly.Xml.domToWorkspace(dom, workspace);
                +  console.timeEnd('Spaghetti domToWorkspace');
                +}
                +var spaghettiXml = [
                +  '  <block type="controls_if">',
                +  '    <value name="IF0">',
                +  '      <block type="logic_compare">',
                +  '        <field name="OP">EQ</field>',
                +  '        <value name="A">',
                +  '          <block type="math_arithmetic">',
                +  '            <field name="OP">MULTIPLY</field>',
                +  '            <value name="A">',
                +  '              <block type="math_number">',
                +  '                <field name="NUM">6</field>',
                +  '              </block>',
                +  '            </value>',
                +  '            <value name="B">',
                +  '              <block type="math_number">',
                +  '                <field name="NUM">7</field>',
                +  '              </block>',
                +  '            </value>',
                +  '          </block>',
                +  '        </value>',
                +  '        <value name="B">',
                +  '          <block type="math_number">',
                +  '            <field name="NUM">42</field>',
                +  '          </block>',
                +  '        </value>',
                +  '      </block>',
                +  '    </value>',
                +  '    <statement name="DO0"></statement>',
                +  '    <next></next>',
                +  '  </block>'].join('\n');
                +
                +</script>
                +
                +<style>
                +html, body {
                +  height: 100%;
                +}
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  overflow: hidden;
                +}
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +#blocklyDiv {
                +  float: right;
                +  height: 95%;
                +  width: 70%;
                +}
                +#importExport {
                +  font-family: monospace;
                +}
                +
                +.ioLabel>.blocklyFlyoutLabelText {
                +  font-style: italic;
                +}
                +
                +</style>
                +</head>
                +<body onload="start()">
                +
                +  <div id="blocklyDiv"></div>
                +
                +  <h1>Blockly Playground</h1>
                +
                +  <p><a href="javascript:void(workspace.setVisible(true))">Show</a>
                +   - <a href="javascript:void(workspace.setVisible(false))">Hide</a></p>
                +
                +  <form id="options">
                +    <select name="dir" onchange="document.forms.options.submit()">
                +      <option value="ltr">LTR</option>
                +      <option value="rtl">RTL</option>
                +    </select>
                +    <select name="toolbox" onchange="document.forms.options.submit()">
                +      <option value="categories">Categories</option>
                +      <option value="simple">Simple</option>
                +    </select>
                +    <select name="side" onchange="document.forms.options.submit()">
                +      <option value="start">Start</option>
                +      <option value="end">End</option>
                +      <option value="top">Top</option>
                +      <option value="bottom">Bottom</option>
                +    </select>
                +  </form>
                +
                +  <p>
                +    <input type="button" value="Export to XML" onclick="toXml()">
                +    &nbsp;
                +    <input type="button" value="Import from XML" onclick="fromXml()" id="import">
                +    <br>
                +    <input type="button" value="To JavaScript" onclick="toCode('JavaScript')">
                +    &nbsp;
                +    <input type="button" value="To Python" onclick="toCode('Python')">
                +    &nbsp;
                +    <input type="button" value="To PHP" onclick="toCode('PHP')">
                +    &nbsp;
                +    <input type="button" value="To Lua" onclick="toCode('Lua')">
                +    &nbsp;
                +    <input type="button" value="To Dart" onclick="toCode('Dart')">
                +    <br>
                +    <textarea id="importExport" style="width: 26%; height: 12em"
                +      onchange="taChange();" onkeyup="taChange()"></textarea>
                +  </p>
                +
                +  <p>
                +    Stress test: &nbsp;
                +    <input type="button" value="Airstrike!" onclick="airstrike(100)">
                +    <input type="button" value="Spaghetti!" onclick="spaghetti(8)">
                +    <input type="button" value="Fake some drags!" onclick="fakeManyDrags()">
                +  </p>
                +  <p>
                +    Log events: &nbsp;
                +    <input type="checkbox" onclick="logEvents(this.checked)" id="logCheck">
                +  </p>
                +
                +  <xml id="toolbox-simple" style="display: none">
                +    <block type="controls_ifelse"></block>
                +    <block type="logic_compare"></block>
                +    <!-- <block type="control_repeat"></block> -->
                +    <block type="logic_operation"></block>
                +    <block type="controls_repeat_ext">
                +      <value name="TIMES">
                +        <shadow type="math_number">
                +          <field name="NUM">10</field>
                +        </shadow>
                +      </value>
                +    </block>
                +    <block type="logic_operation"></block>
                +    <block type="logic_negate"></block>
                +    <block type="logic_boolean"></block>
                +    <block type="logic_null" disabled="true"></block>
                +    <block type="logic_ternary"></block>
                +  </xml>
                +
                +  <xml id="toolbox-categories" style="display: none">
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null" disabled="true"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_repeat" disabled="true"></block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +        <value name="BY">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number" gap="32"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT"></field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_count">
                +        <value name="SUB">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_replace">
                +        <value name="FROM">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_reverse">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <label text="Input/Output:" web-class="ioLabel"></label>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <shadow type="text">
                +            <field name="TEXT">,</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_sort"></block>
                +      <block type="lists_reverse"></block>
                +    </category>
                +    <category name="Colour" colour="20">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +        <value name="GREEN">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="BLUE">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </shadow>
                +        </value>
                +        <value name="COLOUR2">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </shadow>
                +        </value>
                +        <value name="RATIO">
                +          <shadow type="math_number">
                +            <field name="NUM">0.5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +  </xml>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/workspace_svg/index.html b/blockly/webif/static/blockly/tests/workspace_svg/index.html
                new file mode 100644
                index 000000000..65890169a
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/workspace_svg/index.html
                @@ -0,0 +1,399 @@
                +<!DOCTYPE html>
                +<html>
                +<head>
                +<meta charset="utf-8">
                +<title>Blockly Workspace SVG testing</title>
                +<script src="../../blockly_uncompressed.js"></script>
                +<script>goog.require('goog.testing.jsunit');</script>
                +<script src="../../msg/messages.js"></script>
                +<script src="../../blocks/logic.js"></script>
                +<script src="../../blocks/loops.js"></script>
                +<script src="../../blocks/math.js"></script>
                +<script src="../../blocks/text.js"></script>
                +<script src="../../blocks/lists.js"></script>
                +<script src="../../blocks/colour.js"></script>
                +<script src="../../blocks/variables.js"></script>
                +<script src="../../blocks/procedures.js"></script>
                +<script>
                +'use strict';
                +</script>
                +
                +<style>
                +html, body {
                +  height: 100%;
                +}
                +body {
                +  background-color: #fff;
                +  font-family: sans-serif;
                +  overflow: hidden;
                +}
                +h1 {
                +  font-weight: normal;
                +  font-size: 140%;
                +}
                +#blocklyDiv {
                +  float: right;
                +  height: 95%;
                +  width: 70%;
                +}
                +#importExport {
                +  font-family: monospace;
                +}
                +
                +.ioLabel>.blocklyFlyoutLabelText {
                +  font-style: italic;
                +}
                +
                +</style>
                +</head>
                +<body>
                +
                +  <div id="blocklyDiv"></div>
                +
                +  <h1>Blockly Workspace testing</h1>
                +  <script src="workspace_svg_test.js"></script>
                +
                +  <xml id="toolbox-simple" style="display: none">
                +    <block type="controls_ifelse"></block>
                +    <block type="logic_compare"></block>
                +    <!-- <block type="control_repeat"></block> -->
                +    <block type="logic_operation"></block>
                +    <block type="controls_repeat_ext">
                +      <value name="TIMES">
                +        <shadow type="math_number">
                +          <field name="NUM">10</field>
                +        </shadow>
                +      </value>
                +    </block>
                +    <block type="logic_operation"></block>
                +    <block type="logic_negate"></block>
                +    <block type="logic_boolean"></block>
                +    <block type="logic_null" disabled="true"></block>
                +    <block type="logic_ternary"></block>
                +  </xml>
                +
                +  <xml id="toolbox-categories" style="display: none">
                +    <category name="Logic" colour="210">
                +      <block type="controls_if"></block>
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null" disabled="true"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +    <category name="Loops" colour="120">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_repeat" disabled="true"></block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +        <value name="BY">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +    </category>
                +    <category name="Math" colour="230">
                +      <block type="math_number" gap="32"></block>
                +      <block type="math_arithmetic">
                +        <value name="A">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="B">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_single">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">9</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_trig">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">45</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property">
                +        <value name="NUMBER_TO_CHECK">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_round">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">3.1</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo">
                +        <value name="DIVIDEND">
                +          <shadow type="math_number">
                +            <field name="NUM">64</field>
                +          </shadow>
                +        </value>
                +        <value name="DIVISOR">
                +          <shadow type="math_number">
                +            <field name="NUM">10</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_constrain">
                +        <value name="VALUE">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="LOW">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="HIGH">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <shadow type="math_number">
                +            <field name="NUM">1</field>
                +          </shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +    <category name="Text" colour="160">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_length">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_isEmpty">
                +        <value name="VALUE">
                +          <shadow type="text">
                +            <field name="TEXT"></field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +        <value name="FIND">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR">text</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_trim">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_count">
                +        <value name="SUB">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_replace">
                +        <value name="FROM">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TO">
                +          <shadow type="text"></shadow>
                +        </value>
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <block type="text_reverse">
                +        <value name="TEXT">
                +          <shadow type="text"></shadow>
                +        </value>
                +      </block>
                +      <label text="Input/Output:" web-class="ioLabel"></label>
                +      <block type="text_print">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <shadow type="text">
                +            <field name="TEXT">abc</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Lists" colour="260">
                +      <block type="lists_create_with">
                +        <mutation items="0"></mutation>
                +      </block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <shadow type="math_number">
                +            <field name="NUM">5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR">list</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_split">
                +        <value name="DELIM">
                +          <shadow type="text">
                +            <field name="TEXT">,</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="lists_sort"></block>
                +      <block type="lists_reverse"></block>
                +    </category>
                +    <category name="Colour" colour="20">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <shadow type="math_number">
                +            <field name="NUM">100</field>
                +          </shadow>
                +        </value>
                +        <value name="GREEN">
                +          <shadow type="math_number">
                +            <field name="NUM">50</field>
                +          </shadow>
                +        </value>
                +        <value name="BLUE">
                +          <shadow type="math_number">
                +            <field name="NUM">0</field>
                +          </shadow>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </shadow>
                +        </value>
                +        <value name="COLOUR2">
                +          <shadow type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </shadow>
                +        </value>
                +        <value name="RATIO">
                +          <shadow type="math_number">
                +            <field name="NUM">0.5</field>
                +          </shadow>
                +        </value>
                +      </block>
                +    </category>
                +    <sep></sep>
                +    <category name="Variables" colour="330" custom="VARIABLE"></category>
                +    <category name="Functions" colour="290" custom="PROCEDURE"></category>
                +  </xml>
                +</body>
                +</html>
                diff --git a/blockly/webif/static/blockly/tests/workspace_svg/workspace_svg_test.js b/blockly/webif/static/blockly/tests/workspace_svg/workspace_svg_test.js
                new file mode 100644
                index 000000000..f5d924f5b
                --- /dev/null
                +++ b/blockly/webif/static/blockly/tests/workspace_svg/workspace_svg_test.js
                @@ -0,0 +1,95 @@
                +/**
                + * @license
                + * Blockly Tests
                + *
                + * Copyright 2017 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +'use strict';
                +
                +function helper_createWorkspaceWithToolbox() {
                +  var toolbox = document.getElementById('toolbox-categories');
                +  return Blockly.inject('blocklyDiv', {toolbox: toolbox});
                +}
                +
                +function test_createWorkspace() {
                +  var workspace = helper_createWorkspaceWithToolbox();
                +  workspace.dispose();
                +}
                +
                +function test_emptyWorkspace() {
                +  var workspace = helper_createWorkspaceWithToolbox();
                +  try {
                +    assertEquals('Empty workspace (1).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Empty workspace (2).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Empty workspace (3).', 0, workspace.getAllBlocks().length);
                +    workspace.clear();
                +    assertEquals('Empty workspace (4).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Empty workspace (5).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Empty workspace (6).', 0, workspace.getAllBlocks().length);
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                +
                +function test_flatWorkspace() {
                +  var workspace = helper_createWorkspaceWithToolbox();
                +  var blockA, blockB;
                +  try {
                +    blockA = workspace.newBlock('');
                +    assertEquals('One block workspace (1).', 1, workspace.getTopBlocks(true).length);
                +    assertEquals('One block workspace (2).', 1, workspace.getTopBlocks(false).length);
                +    assertEquals('One block workspace (3).', 1, workspace.getAllBlocks().length);
                +    blockB = workspace.newBlock('');
                +    assertEquals('Two block workspace (1).', 2, workspace.getTopBlocks(true).length);
                +    assertEquals('Two block workspace (2).', 2, workspace.getTopBlocks(false).length);
                +    assertEquals('Two block workspace (3).', 2, workspace.getAllBlocks().length);
                +    blockA.dispose();
                +    assertEquals('One block workspace (4).', 1, workspace.getTopBlocks(true).length);
                +    assertEquals('One block workspace (5).', 1, workspace.getTopBlocks(false).length);
                +    assertEquals('One block workspace (6).', 1, workspace.getAllBlocks().length);
                +    workspace.clear();
                +    assertEquals('Cleared workspace (1).', 0, workspace.getTopBlocks(true).length);
                +    assertEquals('Cleared workspace (2).', 0, workspace.getTopBlocks(false).length);
                +    assertEquals('Cleared workspace (3).', 0, workspace.getAllBlocks().length);
                +  } finally {
                +    blockB && blockB.dispose();
                +    blockA && blockA.dispose();
                +    workspace.dispose();
                +  }
                +}
                +
                +/** Tests the alignment of appendDomToWorkspace with WorkspaceSvg. */
                +function test_appendDomToWorkspace() {
                +  var workspace = helper_createWorkspaceWithToolbox();
                +  try {
                +    var dom = Blockly.Xml.textToDom(
                +      '<xml xmlns="http://www.w3.org/1999/xhtml">' +
                +      '  <block type="math_random_float" inline="true" x="21" y="23">' +
                +      '  </block>' +
                +      '</xml>');
                +    Blockly.Xml.appendDomToWorkspace(dom, workspace);
                +    assertEquals('Block count', 1, workspace.getAllBlocks().length);
                +    Blockly.Xml.appendDomToWorkspace(dom, workspace);
                +    assertEquals('Block count', 2, workspace.getAllBlocks().length);
                +    var blocks =  workspace.getAllBlocks();
                +    assertEquals('Block 1 position x',21,blocks[0].getRelativeToSurfaceXY().x);
                +    assertEquals('Block 1 position y',23,blocks[0].getRelativeToSurfaceXY().y);
                +    assertEquals('Block 2 position x',21,blocks[1].getRelativeToSurfaceXY().x);
                +    assertEquals('Block 2 position y',23 + blocks[0].getHeightWidth().height + Blockly.BlockSvg.SEP_SPACE_Y,blocks[1].getRelativeToSurfaceXY().y);
                +  } finally {
                +    workspace.dispose();
                +  }
                +}
                diff --git a/blockly/webif/static/css/bootstrap-reload.css b/blockly/webif/static/css/bootstrap-reload.css
                new file mode 100644
                index 000000000..0fd748a6d
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-reload.css
                @@ -0,0 +1,20 @@
                +.panel-refresh {
                + 	min-height:250px;
                + 	position:relative;
                +}
                + 
                +.refresh-container {
                +	 position:absolute;
                +	 top:0;
                +	 right:0;
                +	 background:rgba(0, 0, 0, 0.5);
                +	 width:100%;
                +	 height:100%;
                +	 display: none;
                +	 text-align:center;
                +	 z-index:4;
                +}
                +.refresh-spinner {
                +	 padding: 30px;
                +	 opacity: 0.8;
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap-theme.css b/blockly/webif/static/css/bootstrap-theme.css
                new file mode 100644
                index 000000000..31d888266
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-theme.css
                @@ -0,0 +1,587 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + */
                +.btn-default,
                +.btn-primary,
                +.btn-success,
                +.btn-info,
                +.btn-warning,
                +.btn-danger {
                +  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
                +  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
                +}
                +.btn-default:active,
                +.btn-primary:active,
                +.btn-success:active,
                +.btn-info:active,
                +.btn-warning:active,
                +.btn-danger:active,
                +.btn-default.active,
                +.btn-primary.active,
                +.btn-success.active,
                +.btn-info.active,
                +.btn-warning.active,
                +.btn-danger.active {
                +  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +}
                +.btn-default.disabled,
                +.btn-primary.disabled,
                +.btn-success.disabled,
                +.btn-info.disabled,
                +.btn-warning.disabled,
                +.btn-danger.disabled,
                +.btn-default[disabled],
                +.btn-primary[disabled],
                +.btn-success[disabled],
                +.btn-info[disabled],
                +.btn-warning[disabled],
                +.btn-danger[disabled],
                +fieldset[disabled] .btn-default,
                +fieldset[disabled] .btn-primary,
                +fieldset[disabled] .btn-success,
                +fieldset[disabled] .btn-info,
                +fieldset[disabled] .btn-warning,
                +fieldset[disabled] .btn-danger {
                +  -webkit-box-shadow: none;
                +          box-shadow: none;
                +}
                +.btn-default .badge,
                +.btn-primary .badge,
                +.btn-success .badge,
                +.btn-info .badge,
                +.btn-warning .badge,
                +.btn-danger .badge {
                +  text-shadow: none;
                +}
                +.btn:active,
                +.btn.active {
                +  background-image: none;
                +}
                +.btn-default {
                +  text-shadow: 0 1px 0 #fff;
                +  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
                +  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
                +  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #dbdbdb;
                +  border-color: #ccc;
                +}
                +.btn-default:hover,
                +.btn-default:focus {
                +  background-color: #e0e0e0;
                +  background-position: 0 -15px;
                +}
                +.btn-default:active,
                +.btn-default.active {
                +  background-color: #e0e0e0;
                +  border-color: #dbdbdb;
                +}
                +.btn-default.disabled,
                +.btn-default[disabled],
                +fieldset[disabled] .btn-default,
                +.btn-default.disabled:hover,
                +.btn-default[disabled]:hover,
                +fieldset[disabled] .btn-default:hover,
                +.btn-default.disabled:focus,
                +.btn-default[disabled]:focus,
                +fieldset[disabled] .btn-default:focus,
                +.btn-default.disabled.focus,
                +.btn-default[disabled].focus,
                +fieldset[disabled] .btn-default.focus,
                +.btn-default.disabled:active,
                +.btn-default[disabled]:active,
                +fieldset[disabled] .btn-default:active,
                +.btn-default.disabled.active,
                +.btn-default[disabled].active,
                +fieldset[disabled] .btn-default.active {
                +  background-color: #e0e0e0;
                +  background-image: none;
                +}
                +.btn-primary {
                +  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
                +  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
                +  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #245580;
                +}
                +.btn-primary:hover,
                +.btn-primary:focus {
                +  background-color: #265a88;
                +  background-position: 0 -15px;
                +}
                +.btn-primary:active,
                +.btn-primary.active {
                +  background-color: #265a88;
                +  border-color: #245580;
                +}
                +.btn-primary.disabled,
                +.btn-primary[disabled],
                +fieldset[disabled] .btn-primary,
                +.btn-primary.disabled:hover,
                +.btn-primary[disabled]:hover,
                +fieldset[disabled] .btn-primary:hover,
                +.btn-primary.disabled:focus,
                +.btn-primary[disabled]:focus,
                +fieldset[disabled] .btn-primary:focus,
                +.btn-primary.disabled.focus,
                +.btn-primary[disabled].focus,
                +fieldset[disabled] .btn-primary.focus,
                +.btn-primary.disabled:active,
                +.btn-primary[disabled]:active,
                +fieldset[disabled] .btn-primary:active,
                +.btn-primary.disabled.active,
                +.btn-primary[disabled].active,
                +fieldset[disabled] .btn-primary.active {
                +  background-color: #265a88;
                +  background-image: none;
                +}
                +.btn-success {
                +  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
                +  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
                +  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #3e8f3e;
                +}
                +.btn-success:hover,
                +.btn-success:focus {
                +  background-color: #419641;
                +  background-position: 0 -15px;
                +}
                +.btn-success:active,
                +.btn-success.active {
                +  background-color: #419641;
                +  border-color: #3e8f3e;
                +}
                +.btn-success.disabled,
                +.btn-success[disabled],
                +fieldset[disabled] .btn-success,
                +.btn-success.disabled:hover,
                +.btn-success[disabled]:hover,
                +fieldset[disabled] .btn-success:hover,
                +.btn-success.disabled:focus,
                +.btn-success[disabled]:focus,
                +fieldset[disabled] .btn-success:focus,
                +.btn-success.disabled.focus,
                +.btn-success[disabled].focus,
                +fieldset[disabled] .btn-success.focus,
                +.btn-success.disabled:active,
                +.btn-success[disabled]:active,
                +fieldset[disabled] .btn-success:active,
                +.btn-success.disabled.active,
                +.btn-success[disabled].active,
                +fieldset[disabled] .btn-success.active {
                +  background-color: #419641;
                +  background-image: none;
                +}
                +.btn-info {
                +  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
                +  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
                +  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #28a4c9;
                +}
                +.btn-info:hover,
                +.btn-info:focus {
                +  background-color: #2aabd2;
                +  background-position: 0 -15px;
                +}
                +.btn-info:active,
                +.btn-info.active {
                +  background-color: #2aabd2;
                +  border-color: #28a4c9;
                +}
                +.btn-info.disabled,
                +.btn-info[disabled],
                +fieldset[disabled] .btn-info,
                +.btn-info.disabled:hover,
                +.btn-info[disabled]:hover,
                +fieldset[disabled] .btn-info:hover,
                +.btn-info.disabled:focus,
                +.btn-info[disabled]:focus,
                +fieldset[disabled] .btn-info:focus,
                +.btn-info.disabled.focus,
                +.btn-info[disabled].focus,
                +fieldset[disabled] .btn-info.focus,
                +.btn-info.disabled:active,
                +.btn-info[disabled]:active,
                +fieldset[disabled] .btn-info:active,
                +.btn-info.disabled.active,
                +.btn-info[disabled].active,
                +fieldset[disabled] .btn-info.active {
                +  background-color: #2aabd2;
                +  background-image: none;
                +}
                +.btn-warning {
                +  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
                +  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
                +  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #e38d13;
                +}
                +.btn-warning:hover,
                +.btn-warning:focus {
                +  background-color: #eb9316;
                +  background-position: 0 -15px;
                +}
                +.btn-warning:active,
                +.btn-warning.active {
                +  background-color: #eb9316;
                +  border-color: #e38d13;
                +}
                +.btn-warning.disabled,
                +.btn-warning[disabled],
                +fieldset[disabled] .btn-warning,
                +.btn-warning.disabled:hover,
                +.btn-warning[disabled]:hover,
                +fieldset[disabled] .btn-warning:hover,
                +.btn-warning.disabled:focus,
                +.btn-warning[disabled]:focus,
                +fieldset[disabled] .btn-warning:focus,
                +.btn-warning.disabled.focus,
                +.btn-warning[disabled].focus,
                +fieldset[disabled] .btn-warning.focus,
                +.btn-warning.disabled:active,
                +.btn-warning[disabled]:active,
                +fieldset[disabled] .btn-warning:active,
                +.btn-warning.disabled.active,
                +.btn-warning[disabled].active,
                +fieldset[disabled] .btn-warning.active {
                +  background-color: #eb9316;
                +  background-image: none;
                +}
                +.btn-danger {
                +  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
                +  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
                +  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-color: #b92c28;
                +}
                +.btn-danger:hover,
                +.btn-danger:focus {
                +  background-color: #c12e2a;
                +  background-position: 0 -15px;
                +}
                +.btn-danger:active,
                +.btn-danger.active {
                +  background-color: #c12e2a;
                +  border-color: #b92c28;
                +}
                +.btn-danger.disabled,
                +.btn-danger[disabled],
                +fieldset[disabled] .btn-danger,
                +.btn-danger.disabled:hover,
                +.btn-danger[disabled]:hover,
                +fieldset[disabled] .btn-danger:hover,
                +.btn-danger.disabled:focus,
                +.btn-danger[disabled]:focus,
                +fieldset[disabled] .btn-danger:focus,
                +.btn-danger.disabled.focus,
                +.btn-danger[disabled].focus,
                +fieldset[disabled] .btn-danger.focus,
                +.btn-danger.disabled:active,
                +.btn-danger[disabled]:active,
                +fieldset[disabled] .btn-danger:active,
                +.btn-danger.disabled.active,
                +.btn-danger[disabled].active,
                +fieldset[disabled] .btn-danger.active {
                +  background-color: #c12e2a;
                +  background-image: none;
                +}
                +.thumbnail,
                +.img-thumbnail {
                +  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
                +          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
                +}
                +.dropdown-menu > li > a:hover,
                +.dropdown-menu > li > a:focus {
                +  background-color: #e8e8e8;
                +  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
                +  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
                +  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.dropdown-menu > .active > a,
                +.dropdown-menu > .active > a:hover,
                +.dropdown-menu > .active > a:focus {
                +  background-color: #2e6da4;
                +  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
                +  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.navbar-default {
                +  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
                +  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
                +  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-radius: 4px;
                +  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
                +}
                +.navbar-default .navbar-nav > .open > a,
                +.navbar-default .navbar-nav > .active > a {
                +  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
                +  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
                +  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
                +  background-repeat: repeat-x;
                +  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
                +}
                +.navbar-brand,
                +.navbar-nav > li > a {
                +  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
                +}
                +.navbar-inverse {
                +  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
                +  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
                +  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +  background-repeat: repeat-x;
                +  border-radius: 4px;
                +}
                +.navbar-inverse .navbar-nav > .open > a,
                +.navbar-inverse .navbar-nav > .active > a {
                +  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
                +  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
                +  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
                +  background-repeat: repeat-x;
                +  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
                +          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
                +}
                +.navbar-inverse .navbar-brand,
                +.navbar-inverse .navbar-nav > li > a {
                +  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
                +}
                +.navbar-static-top,
                +.navbar-fixed-top,
                +.navbar-fixed-bottom {
                +  border-radius: 0;
                +}
                +@media (max-width: 767px) {
                +  .navbar .navbar-nav .open .dropdown-menu > .active > a,
                +  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
                +  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
                +    color: #fff;
                +    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
                +    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
                +    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
                +    background-repeat: repeat-x;
                +  }
                +}
                +.alert {
                +  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
                +  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
                +          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
                +}
                +.alert-success {
                +  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
                +  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
                +  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #b2dba1;
                +}
                +.alert-info {
                +  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
                +  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
                +  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #9acfea;
                +}
                +.alert-warning {
                +  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
                +  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
                +  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #f5e79e;
                +}
                +.alert-danger {
                +  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
                +  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
                +  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #dca7a7;
                +}
                +.progress {
                +  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
                +  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
                +  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar {
                +  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
                +  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
                +  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar-success {
                +  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
                +  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
                +  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar-info {
                +  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
                +  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
                +  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar-warning {
                +  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
                +  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
                +  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar-danger {
                +  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
                +  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
                +  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.progress-bar-striped {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +}
                +.list-group {
                +  border-radius: 4px;
                +  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
                +          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
                +}
                +.list-group-item.active,
                +.list-group-item.active:hover,
                +.list-group-item.active:focus {
                +  text-shadow: 0 -1px 0 #286090;
                +  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
                +  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
                +  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #2b669a;
                +}
                +.list-group-item.active .badge,
                +.list-group-item.active:hover .badge,
                +.list-group-item.active:focus .badge {
                +  text-shadow: none;
                +}
                +.panel {
                +  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
                +          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
                +}
                +.panel-default > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
                +  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
                +  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.panel-primary > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
                +  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.panel-success > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
                +  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
                +  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.panel-info > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
                +  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
                +  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.panel-warning > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
                +  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
                +  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.panel-danger > .panel-heading {
                +  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
                +  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
                +  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
                +  background-repeat: repeat-x;
                +}
                +.well {
                +  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
                +  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
                +  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
                +  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
                +  background-repeat: repeat-x;
                +  border-color: #dcdcdc;
                +  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
                +          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
                +}
                +/*# sourceMappingURL=bootstrap-theme.css.map */
                diff --git a/blockly/webif/static/css/bootstrap-theme.css.map b/blockly/webif/static/css/bootstrap-theme.css.map
                new file mode 100644
                index 000000000..d876f60fb
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-theme.css.map
                @@ -0,0 +1 @@
                +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n  text-shadow: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n.btn-default {\n  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  text-shadow: 0 1px 0 #fff;\n  border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #e0e0e0;\n  background-image: none;\n}\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #265a88;\n  background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #265a88;\n  border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #265a88;\n  background-image: none;\n}\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #419641;\n  background-image: none;\n}\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #2aabd2;\n  background-image: none;\n}\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #eb9316;\n  background-image: none;\n}\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #c12e2a;\n  background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-color: #2e6da4;\n}\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n  background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n  background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n@media (max-width: 767px) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  }\n}\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n  border-color: #b2dba1;\n}\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n  border-color: #9acfea;\n}\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n  border-color: #f5e79e;\n}\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n  border-color: #dca7a7;\n}\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #286090;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n  border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n  text-shadow: none;\n}\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  border-color: #dcdcdc;\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  // Reset the shadow\n  &:active,\n  &.active {\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    .box-shadow(none);\n  }\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n  background-repeat: repeat-x;\n  border-color: darken(@btn-color, 14%);\n\n  &:hover,\n  &:focus  {\n    background-color: darken(@btn-color, 12%);\n    background-position: 0 -15px;\n  }\n\n  &:active,\n  &.active {\n    background-color: darken(@btn-color, 12%);\n    border-color: darken(@btn-color, 14%);\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &.focus,\n    &:active,\n    &.active {\n      background-color: darken(@btn-color, 12%);\n      background-image: none;\n    }\n  }\n}\n\n// Common styles\n.btn {\n  // Remove the gradient for the pressed/active state\n  &:active,\n  &.active {\n    background-image: none;\n  }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info    { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger  { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n  background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n  background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n  border-radius: @navbar-border-radius;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n  }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n  border-radius: @navbar-border-radius;\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n  }\n\n  .navbar-brand,\n  .navbar-nav > li > a {\n    text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n  }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a {\n    &,\n    &:hover,\n    &:focus {\n      color: #fff;\n      #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n    }\n  }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n  text-shadow: 0 1px 0 rgba(255,255,255,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n  .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n  border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success    { .alert-styles(@alert-success-bg); }\n.alert-info       { .alert-styles(@alert-info-bg); }\n.alert-warning    { .alert-styles(@alert-warning-bg); }\n.alert-danger     { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar            { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n  #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n  border-radius: @border-radius-base;\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n  border-color: darken(@list-group-active-border, 7.5%);\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n  .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n  border-color: darken(@well-bg, 10%);\n  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap-theme.min.css b/blockly/webif/static/css/bootstrap-theme.min.css
                new file mode 100644
                index 000000000..5e3940195
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-theme.min.css
                @@ -0,0 +1,6 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
                +/*# sourceMappingURL=bootstrap-theme.min.css.map */
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap-theme.min.css.map b/blockly/webif/static/css/bootstrap-theme.min.css.map
                new file mode 100644
                index 000000000..94813e900
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-theme.min.css.map
                @@ -0,0 +1 @@
                +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  // Reset the shadow\n  &:active,\n  &.active {\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    .box-shadow(none);\n  }\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n  background-repeat: repeat-x;\n  border-color: darken(@btn-color, 14%);\n\n  &:hover,\n  &:focus  {\n    background-color: darken(@btn-color, 12%);\n    background-position: 0 -15px;\n  }\n\n  &:active,\n  &.active {\n    background-color: darken(@btn-color, 12%);\n    border-color: darken(@btn-color, 14%);\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &.focus,\n    &:active,\n    &.active {\n      background-color: darken(@btn-color, 12%);\n      background-image: none;\n    }\n  }\n}\n\n// Common styles\n.btn {\n  // Remove the gradient for the pressed/active state\n  &:active,\n  &.active {\n    background-image: none;\n  }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info    { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger  { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n  background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n  background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n  border-radius: @navbar-border-radius;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n  }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n  border-radius: @navbar-border-radius;\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n  }\n\n  .navbar-brand,\n  .navbar-nav > li > a {\n    text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n  }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a {\n    &,\n    &:hover,\n    &:focus {\n      color: #fff;\n      #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n    }\n  }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n  text-shadow: 0 1px 0 rgba(255,255,255,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n  .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n  border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success    { .alert-styles(@alert-success-bg); }\n.alert-info       { .alert-styles(@alert-info-bg); }\n.alert-warning    { .alert-styles(@alert-warning-bg); }\n.alert-danger     { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar            { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n  #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n  border-radius: @border-radius-base;\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n  border-color: darken(@list-group-active-border, 7.5%);\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n  .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n  border-color: darken(@well-bg, 10%);\n  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap-treeview.css b/blockly/webif/static/css/bootstrap-treeview.css
                new file mode 100644
                index 000000000..23c6cf066
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-treeview.css
                @@ -0,0 +1,37 @@
                +/* =========================================================
                + * bootstrap-treeview.css v1.2.0
                + * =========================================================
                + * Copyright 2013 Jonathan Miles 
                + * Project URL : http://www.jondmiles.com/bootstrap-treeview
                + *	
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + * http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + * ========================================================= */
                +
                +.treeview .list-group-item {
                +	cursor: pointer;
                +}
                +
                +.treeview span.indent {
                +	margin-left: 10px;
                +	margin-right: 10px;
                +}
                +
                +.treeview span.icon {
                +	width: 12px;
                +	margin-right: 5px;
                +}
                +
                +.treeview .node-disabled {
                +	color: silver;
                +	cursor: not-allowed;
                +}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap-treeview.min.css b/blockly/webif/static/css/bootstrap-treeview.min.css
                new file mode 100644
                index 000000000..57a348a87
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap-treeview.min.css
                @@ -0,0 +1 @@
                +.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap.css b/blockly/webif/static/css/bootstrap.css
                new file mode 100644
                index 000000000..6167622ce
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap.css
                @@ -0,0 +1,6757 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + */
                +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
                +html {
                +  font-family: sans-serif;
                +  -webkit-text-size-adjust: 100%;
                +      -ms-text-size-adjust: 100%;
                +}
                +body {
                +  margin: 0;
                +}
                +article,
                +aside,
                +details,
                +figcaption,
                +figure,
                +footer,
                +header,
                +hgroup,
                +main,
                +menu,
                +nav,
                +section,
                +summary {
                +  display: block;
                +}
                +audio,
                +canvas,
                +progress,
                +video {
                +  display: inline-block;
                +  vertical-align: baseline;
                +}
                +audio:not([controls]) {
                +  display: none;
                +  height: 0;
                +}
                +[hidden],
                +template {
                +  display: none;
                +}
                +a {
                +  background-color: transparent;
                +}
                +a:active,
                +a:hover {
                +  outline: 0;
                +}
                +abbr[title] {
                +  border-bottom: 1px dotted;
                +}
                +b,
                +strong {
                +  font-weight: bold;
                +}
                +dfn {
                +  font-style: italic;
                +}
                +h1 {
                +  margin: .67em 0;
                +  font-size: 2em;
                +}
                +mark {
                +  color: #000;
                +  background: #ff0;
                +}
                +small {
                +  font-size: 80%;
                +}
                +sub,
                +sup {
                +  position: relative;
                +  font-size: 75%;
                +  line-height: 0;
                +  vertical-align: baseline;
                +}
                +sup {
                +  top: -.5em;
                +}
                +sub {
                +  bottom: -.25em;
                +}
                +img {
                +  border: 0;
                +}
                +svg:not(:root) {
                +  overflow: hidden;
                +}
                +figure {
                +  margin: 1em 40px;
                +}
                +hr {
                +  height: 0;
                +  -webkit-box-sizing: content-box;
                +     -moz-box-sizing: content-box;
                +          box-sizing: content-box;
                +}
                +pre {
                +  overflow: auto;
                +}
                +code,
                +kbd,
                +pre,
                +samp {
                +  font-family: monospace, monospace;
                +  font-size: 1em;
                +}
                +button,
                +input,
                +optgroup,
                +select,
                +textarea {
                +  margin: 0;
                +  font: inherit;
                +  color: inherit;
                +}
                +button {
                +  overflow: visible;
                +}
                +button,
                +select {
                +  text-transform: none;
                +}
                +button,
                +html input[type="button"],
                +input[type="reset"],
                +input[type="submit"] {
                +  -webkit-appearance: button;
                +  cursor: pointer;
                +}
                +button[disabled],
                +html input[disabled] {
                +  cursor: default;
                +}
                +button::-moz-focus-inner,
                +input::-moz-focus-inner {
                +  padding: 0;
                +  border: 0;
                +}
                +input {
                +  line-height: normal;
                +}
                +input[type="checkbox"],
                +input[type="radio"] {
                +  -webkit-box-sizing: border-box;
                +     -moz-box-sizing: border-box;
                +          box-sizing: border-box;
                +  padding: 0;
                +}
                +input[type="number"]::-webkit-inner-spin-button,
                +input[type="number"]::-webkit-outer-spin-button {
                +  height: auto;
                +}
                +input[type="search"] {
                +  -webkit-box-sizing: content-box;
                +     -moz-box-sizing: content-box;
                +          box-sizing: content-box;
                +  -webkit-appearance: textfield;
                +}
                +input[type="search"]::-webkit-search-cancel-button,
                +input[type="search"]::-webkit-search-decoration {
                +  -webkit-appearance: none;
                +}
                +fieldset {
                +  padding: .35em .625em .75em;
                +  margin: 0 2px;
                +  border: 1px solid #c0c0c0;
                +}
                +legend {
                +  padding: 0;
                +  border: 0;
                +}
                +textarea {
                +  overflow: auto;
                +}
                +optgroup {
                +  font-weight: bold;
                +}
                +table {
                +  border-spacing: 0;
                +  border-collapse: collapse;
                +}
                +td,
                +th {
                +  padding: 0;
                +}
                +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
                +@media print {
                +  *,
                +  *:before,
                +  *:after {
                +    color: #000 !important;
                +    text-shadow: none !important;
                +    background: transparent !important;
                +    -webkit-box-shadow: none !important;
                +            box-shadow: none !important;
                +  }
                +  a,
                +  a:visited {
                +    text-decoration: underline;
                +  }
                +  a[href]:after {
                +    content: " (" attr(href) ")";
                +  }
                +  abbr[title]:after {
                +    content: " (" attr(title) ")";
                +  }
                +  a[href^="#"]:after,
                +  a[href^="javascript:"]:after {
                +    content: "";
                +  }
                +  pre,
                +  blockquote {
                +    border: 1px solid #999;
                +
                +    page-break-inside: avoid;
                +  }
                +  thead {
                +    display: table-header-group;
                +  }
                +  tr,
                +  img {
                +    page-break-inside: avoid;
                +  }
                +  img {
                +    max-width: 100% !important;
                +  }
                +  p,
                +  h2,
                +  h3 {
                +    orphans: 3;
                +    widows: 3;
                +  }
                +  h2,
                +  h3 {
                +    page-break-after: avoid;
                +  }
                +  .navbar {
                +    display: none;
                +  }
                +  .btn > .caret,
                +  .dropup > .btn > .caret {
                +    border-top-color: #000 !important;
                +  }
                +  .label {
                +    border: 1px solid #000;
                +  }
                +  .table {
                +    border-collapse: collapse !important;
                +  }
                +  .table td,
                +  .table th {
                +    background-color: #fff !important;
                +  }
                +  .table-bordered th,
                +  .table-bordered td {
                +    border: 1px solid #ddd !important;
                +  }
                +}
                +@font-face {
                +  font-family: 'Glyphicons Halflings';
                +
                +  src: url('../fonts/glyphicons-halflings-regular.eot');
                +  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
                +}
                +.glyphicon {
                +  position: relative;
                +  top: 1px;
                +  display: inline-block;
                +  font-family: 'Glyphicons Halflings';
                +  font-style: normal;
                +  font-weight: normal;
                +  line-height: 1;
                +
                +  -webkit-font-smoothing: antialiased;
                +  -moz-osx-font-smoothing: grayscale;
                +}
                +.glyphicon-asterisk:before {
                +  content: "\002a";
                +}
                +.glyphicon-plus:before {
                +  content: "\002b";
                +}
                +.glyphicon-euro:before,
                +.glyphicon-eur:before {
                +  content: "\20ac";
                +}
                +.glyphicon-minus:before {
                +  content: "\2212";
                +}
                +.glyphicon-cloud:before {
                +  content: "\2601";
                +}
                +.glyphicon-envelope:before {
                +  content: "\2709";
                +}
                +.glyphicon-pencil:before {
                +  content: "\270f";
                +}
                +.glyphicon-glass:before {
                +  content: "\e001";
                +}
                +.glyphicon-music:before {
                +  content: "\e002";
                +}
                +.glyphicon-search:before {
                +  content: "\e003";
                +}
                +.glyphicon-heart:before {
                +  content: "\e005";
                +}
                +.glyphicon-star:before {
                +  content: "\e006";
                +}
                +.glyphicon-star-empty:before {
                +  content: "\e007";
                +}
                +.glyphicon-user:before {
                +  content: "\e008";
                +}
                +.glyphicon-film:before {
                +  content: "\e009";
                +}
                +.glyphicon-th-large:before {
                +  content: "\e010";
                +}
                +.glyphicon-th:before {
                +  content: "\e011";
                +}
                +.glyphicon-th-list:before {
                +  content: "\e012";
                +}
                +.glyphicon-ok:before {
                +  content: "\e013";
                +}
                +.glyphicon-remove:before {
                +  content: "\e014";
                +}
                +.glyphicon-zoom-in:before {
                +  content: "\e015";
                +}
                +.glyphicon-zoom-out:before {
                +  content: "\e016";
                +}
                +.glyphicon-off:before {
                +  content: "\e017";
                +}
                +.glyphicon-signal:before {
                +  content: "\e018";
                +}
                +.glyphicon-cog:before {
                +  content: "\e019";
                +}
                +.glyphicon-trash:before {
                +  content: "\e020";
                +}
                +.glyphicon-home:before {
                +  content: "\e021";
                +}
                +.glyphicon-file:before {
                +  content: "\e022";
                +}
                +.glyphicon-time:before {
                +  content: "\e023";
                +}
                +.glyphicon-road:before {
                +  content: "\e024";
                +}
                +.glyphicon-download-alt:before {
                +  content: "\e025";
                +}
                +.glyphicon-download:before {
                +  content: "\e026";
                +}
                +.glyphicon-upload:before {
                +  content: "\e027";
                +}
                +.glyphicon-inbox:before {
                +  content: "\e028";
                +}
                +.glyphicon-play-circle:before {
                +  content: "\e029";
                +}
                +.glyphicon-repeat:before {
                +  content: "\e030";
                +}
                +.glyphicon-refresh:before {
                +  content: "\e031";
                +}
                +.glyphicon-list-alt:before {
                +  content: "\e032";
                +}
                +.glyphicon-lock:before {
                +  content: "\e033";
                +}
                +.glyphicon-flag:before {
                +  content: "\e034";
                +}
                +.glyphicon-headphones:before {
                +  content: "\e035";
                +}
                +.glyphicon-volume-off:before {
                +  content: "\e036";
                +}
                +.glyphicon-volume-down:before {
                +  content: "\e037";
                +}
                +.glyphicon-volume-up:before {
                +  content: "\e038";
                +}
                +.glyphicon-qrcode:before {
                +  content: "\e039";
                +}
                +.glyphicon-barcode:before {
                +  content: "\e040";
                +}
                +.glyphicon-tag:before {
                +  content: "\e041";
                +}
                +.glyphicon-tags:before {
                +  content: "\e042";
                +}
                +.glyphicon-book:before {
                +  content: "\e043";
                +}
                +.glyphicon-bookmark:before {
                +  content: "\e044";
                +}
                +.glyphicon-print:before {
                +  content: "\e045";
                +}
                +.glyphicon-camera:before {
                +  content: "\e046";
                +}
                +.glyphicon-font:before {
                +  content: "\e047";
                +}
                +.glyphicon-bold:before {
                +  content: "\e048";
                +}
                +.glyphicon-italic:before {
                +  content: "\e049";
                +}
                +.glyphicon-text-height:before {
                +  content: "\e050";
                +}
                +.glyphicon-text-width:before {
                +  content: "\e051";
                +}
                +.glyphicon-align-left:before {
                +  content: "\e052";
                +}
                +.glyphicon-align-center:before {
                +  content: "\e053";
                +}
                +.glyphicon-align-right:before {
                +  content: "\e054";
                +}
                +.glyphicon-align-justify:before {
                +  content: "\e055";
                +}
                +.glyphicon-list:before {
                +  content: "\e056";
                +}
                +.glyphicon-indent-left:before {
                +  content: "\e057";
                +}
                +.glyphicon-indent-right:before {
                +  content: "\e058";
                +}
                +.glyphicon-facetime-video:before {
                +  content: "\e059";
                +}
                +.glyphicon-picture:before {
                +  content: "\e060";
                +}
                +.glyphicon-map-marker:before {
                +  content: "\e062";
                +}
                +.glyphicon-adjust:before {
                +  content: "\e063";
                +}
                +.glyphicon-tint:before {
                +  content: "\e064";
                +}
                +.glyphicon-edit:before {
                +  content: "\e065";
                +}
                +.glyphicon-share:before {
                +  content: "\e066";
                +}
                +.glyphicon-check:before {
                +  content: "\e067";
                +}
                +.glyphicon-move:before {
                +  content: "\e068";
                +}
                +.glyphicon-step-backward:before {
                +  content: "\e069";
                +}
                +.glyphicon-fast-backward:before {
                +  content: "\e070";
                +}
                +.glyphicon-backward:before {
                +  content: "\e071";
                +}
                +.glyphicon-play:before {
                +  content: "\e072";
                +}
                +.glyphicon-pause:before {
                +  content: "\e073";
                +}
                +.glyphicon-stop:before {
                +  content: "\e074";
                +}
                +.glyphicon-forward:before {
                +  content: "\e075";
                +}
                +.glyphicon-fast-forward:before {
                +  content: "\e076";
                +}
                +.glyphicon-step-forward:before {
                +  content: "\e077";
                +}
                +.glyphicon-eject:before {
                +  content: "\e078";
                +}
                +.glyphicon-chevron-left:before {
                +  content: "\e079";
                +}
                +.glyphicon-chevron-right:before {
                +  content: "\e080";
                +}
                +.glyphicon-plus-sign:before {
                +  content: "\e081";
                +}
                +.glyphicon-minus-sign:before {
                +  content: "\e082";
                +}
                +.glyphicon-remove-sign:before {
                +  content: "\e083";
                +}
                +.glyphicon-ok-sign:before {
                +  content: "\e084";
                +}
                +.glyphicon-question-sign:before {
                +  content: "\e085";
                +}
                +.glyphicon-info-sign:before {
                +  content: "\e086";
                +}
                +.glyphicon-screenshot:before {
                +  content: "\e087";
                +}
                +.glyphicon-remove-circle:before {
                +  content: "\e088";
                +}
                +.glyphicon-ok-circle:before {
                +  content: "\e089";
                +}
                +.glyphicon-ban-circle:before {
                +  content: "\e090";
                +}
                +.glyphicon-arrow-left:before {
                +  content: "\e091";
                +}
                +.glyphicon-arrow-right:before {
                +  content: "\e092";
                +}
                +.glyphicon-arrow-up:before {
                +  content: "\e093";
                +}
                +.glyphicon-arrow-down:before {
                +  content: "\e094";
                +}
                +.glyphicon-share-alt:before {
                +  content: "\e095";
                +}
                +.glyphicon-resize-full:before {
                +  content: "\e096";
                +}
                +.glyphicon-resize-small:before {
                +  content: "\e097";
                +}
                +.glyphicon-exclamation-sign:before {
                +  content: "\e101";
                +}
                +.glyphicon-gift:before {
                +  content: "\e102";
                +}
                +.glyphicon-leaf:before {
                +  content: "\e103";
                +}
                +.glyphicon-fire:before {
                +  content: "\e104";
                +}
                +.glyphicon-eye-open:before {
                +  content: "\e105";
                +}
                +.glyphicon-eye-close:before {
                +  content: "\e106";
                +}
                +.glyphicon-warning-sign:before {
                +  content: "\e107";
                +}
                +.glyphicon-plane:before {
                +  content: "\e108";
                +}
                +.glyphicon-calendar:before {
                +  content: "\e109";
                +}
                +.glyphicon-random:before {
                +  content: "\e110";
                +}
                +.glyphicon-comment:before {
                +  content: "\e111";
                +}
                +.glyphicon-magnet:before {
                +  content: "\e112";
                +}
                +.glyphicon-chevron-up:before {
                +  content: "\e113";
                +}
                +.glyphicon-chevron-down:before {
                +  content: "\e114";
                +}
                +.glyphicon-retweet:before {
                +  content: "\e115";
                +}
                +.glyphicon-shopping-cart:before {
                +  content: "\e116";
                +}
                +.glyphicon-folder-close:before {
                +  content: "\e117";
                +}
                +.glyphicon-folder-open:before {
                +  content: "\e118";
                +}
                +.glyphicon-resize-vertical:before {
                +  content: "\e119";
                +}
                +.glyphicon-resize-horizontal:before {
                +  content: "\e120";
                +}
                +.glyphicon-hdd:before {
                +  content: "\e121";
                +}
                +.glyphicon-bullhorn:before {
                +  content: "\e122";
                +}
                +.glyphicon-bell:before {
                +  content: "\e123";
                +}
                +.glyphicon-certificate:before {
                +  content: "\e124";
                +}
                +.glyphicon-thumbs-up:before {
                +  content: "\e125";
                +}
                +.glyphicon-thumbs-down:before {
                +  content: "\e126";
                +}
                +.glyphicon-hand-right:before {
                +  content: "\e127";
                +}
                +.glyphicon-hand-left:before {
                +  content: "\e128";
                +}
                +.glyphicon-hand-up:before {
                +  content: "\e129";
                +}
                +.glyphicon-hand-down:before {
                +  content: "\e130";
                +}
                +.glyphicon-circle-arrow-right:before {
                +  content: "\e131";
                +}
                +.glyphicon-circle-arrow-left:before {
                +  content: "\e132";
                +}
                +.glyphicon-circle-arrow-up:before {
                +  content: "\e133";
                +}
                +.glyphicon-circle-arrow-down:before {
                +  content: "\e134";
                +}
                +.glyphicon-globe:before {
                +  content: "\e135";
                +}
                +.glyphicon-wrench:before {
                +  content: "\e136";
                +}
                +.glyphicon-tasks:before {
                +  content: "\e137";
                +}
                +.glyphicon-filter:before {
                +  content: "\e138";
                +}
                +.glyphicon-briefcase:before {
                +  content: "\e139";
                +}
                +.glyphicon-fullscreen:before {
                +  content: "\e140";
                +}
                +.glyphicon-dashboard:before {
                +  content: "\e141";
                +}
                +.glyphicon-paperclip:before {
                +  content: "\e142";
                +}
                +.glyphicon-heart-empty:before {
                +  content: "\e143";
                +}
                +.glyphicon-link:before {
                +  content: "\e144";
                +}
                +.glyphicon-phone:before {
                +  content: "\e145";
                +}
                +.glyphicon-pushpin:before {
                +  content: "\e146";
                +}
                +.glyphicon-usd:before {
                +  content: "\e148";
                +}
                +.glyphicon-gbp:before {
                +  content: "\e149";
                +}
                +.glyphicon-sort:before {
                +  content: "\e150";
                +}
                +.glyphicon-sort-by-alphabet:before {
                +  content: "\e151";
                +}
                +.glyphicon-sort-by-alphabet-alt:before {
                +  content: "\e152";
                +}
                +.glyphicon-sort-by-order:before {
                +  content: "\e153";
                +}
                +.glyphicon-sort-by-order-alt:before {
                +  content: "\e154";
                +}
                +.glyphicon-sort-by-attributes:before {
                +  content: "\e155";
                +}
                +.glyphicon-sort-by-attributes-alt:before {
                +  content: "\e156";
                +}
                +.glyphicon-unchecked:before {
                +  content: "\e157";
                +}
                +.glyphicon-expand:before {
                +  content: "\e158";
                +}
                +.glyphicon-collapse-down:before {
                +  content: "\e159";
                +}
                +.glyphicon-collapse-up:before {
                +  content: "\e160";
                +}
                +.glyphicon-log-in:before {
                +  content: "\e161";
                +}
                +.glyphicon-flash:before {
                +  content: "\e162";
                +}
                +.glyphicon-log-out:before {
                +  content: "\e163";
                +}
                +.glyphicon-new-window:before {
                +  content: "\e164";
                +}
                +.glyphicon-record:before {
                +  content: "\e165";
                +}
                +.glyphicon-save:before {
                +  content: "\e166";
                +}
                +.glyphicon-open:before {
                +  content: "\e167";
                +}
                +.glyphicon-saved:before {
                +  content: "\e168";
                +}
                +.glyphicon-import:before {
                +  content: "\e169";
                +}
                +.glyphicon-export:before {
                +  content: "\e170";
                +}
                +.glyphicon-send:before {
                +  content: "\e171";
                +}
                +.glyphicon-floppy-disk:before {
                +  content: "\e172";
                +}
                +.glyphicon-floppy-saved:before {
                +  content: "\e173";
                +}
                +.glyphicon-floppy-remove:before {
                +  content: "\e174";
                +}
                +.glyphicon-floppy-save:before {
                +  content: "\e175";
                +}
                +.glyphicon-floppy-open:before {
                +  content: "\e176";
                +}
                +.glyphicon-credit-card:before {
                +  content: "\e177";
                +}
                +.glyphicon-transfer:before {
                +  content: "\e178";
                +}
                +.glyphicon-cutlery:before {
                +  content: "\e179";
                +}
                +.glyphicon-header:before {
                +  content: "\e180";
                +}
                +.glyphicon-compressed:before {
                +  content: "\e181";
                +}
                +.glyphicon-earphone:before {
                +  content: "\e182";
                +}
                +.glyphicon-phone-alt:before {
                +  content: "\e183";
                +}
                +.glyphicon-tower:before {
                +  content: "\e184";
                +}
                +.glyphicon-stats:before {
                +  content: "\e185";
                +}
                +.glyphicon-sd-video:before {
                +  content: "\e186";
                +}
                +.glyphicon-hd-video:before {
                +  content: "\e187";
                +}
                +.glyphicon-subtitles:before {
                +  content: "\e188";
                +}
                +.glyphicon-sound-stereo:before {
                +  content: "\e189";
                +}
                +.glyphicon-sound-dolby:before {
                +  content: "\e190";
                +}
                +.glyphicon-sound-5-1:before {
                +  content: "\e191";
                +}
                +.glyphicon-sound-6-1:before {
                +  content: "\e192";
                +}
                +.glyphicon-sound-7-1:before {
                +  content: "\e193";
                +}
                +.glyphicon-copyright-mark:before {
                +  content: "\e194";
                +}
                +.glyphicon-registration-mark:before {
                +  content: "\e195";
                +}
                +.glyphicon-cloud-download:before {
                +  content: "\e197";
                +}
                +.glyphicon-cloud-upload:before {
                +  content: "\e198";
                +}
                +.glyphicon-tree-conifer:before {
                +  content: "\e199";
                +}
                +.glyphicon-tree-deciduous:before {
                +  content: "\e200";
                +}
                +.glyphicon-cd:before {
                +  content: "\e201";
                +}
                +.glyphicon-save-file:before {
                +  content: "\e202";
                +}
                +.glyphicon-open-file:before {
                +  content: "\e203";
                +}
                +.glyphicon-level-up:before {
                +  content: "\e204";
                +}
                +.glyphicon-copy:before {
                +  content: "\e205";
                +}
                +.glyphicon-paste:before {
                +  content: "\e206";
                +}
                +.glyphicon-alert:before {
                +  content: "\e209";
                +}
                +.glyphicon-equalizer:before {
                +  content: "\e210";
                +}
                +.glyphicon-king:before {
                +  content: "\e211";
                +}
                +.glyphicon-queen:before {
                +  content: "\e212";
                +}
                +.glyphicon-pawn:before {
                +  content: "\e213";
                +}
                +.glyphicon-bishop:before {
                +  content: "\e214";
                +}
                +.glyphicon-knight:before {
                +  content: "\e215";
                +}
                +.glyphicon-baby-formula:before {
                +  content: "\e216";
                +}
                +.glyphicon-tent:before {
                +  content: "\26fa";
                +}
                +.glyphicon-blackboard:before {
                +  content: "\e218";
                +}
                +.glyphicon-bed:before {
                +  content: "\e219";
                +}
                +.glyphicon-apple:before {
                +  content: "\f8ff";
                +}
                +.glyphicon-erase:before {
                +  content: "\e221";
                +}
                +.glyphicon-hourglass:before {
                +  content: "\231b";
                +}
                +.glyphicon-lamp:before {
                +  content: "\e223";
                +}
                +.glyphicon-duplicate:before {
                +  content: "\e224";
                +}
                +.glyphicon-piggy-bank:before {
                +  content: "\e225";
                +}
                +.glyphicon-scissors:before {
                +  content: "\e226";
                +}
                +.glyphicon-bitcoin:before {
                +  content: "\e227";
                +}
                +.glyphicon-btc:before {
                +  content: "\e227";
                +}
                +.glyphicon-xbt:before {
                +  content: "\e227";
                +}
                +.glyphicon-yen:before {
                +  content: "\00a5";
                +}
                +.glyphicon-jpy:before {
                +  content: "\00a5";
                +}
                +.glyphicon-ruble:before {
                +  content: "\20bd";
                +}
                +.glyphicon-rub:before {
                +  content: "\20bd";
                +}
                +.glyphicon-scale:before {
                +  content: "\e230";
                +}
                +.glyphicon-ice-lolly:before {
                +  content: "\e231";
                +}
                +.glyphicon-ice-lolly-tasted:before {
                +  content: "\e232";
                +}
                +.glyphicon-education:before {
                +  content: "\e233";
                +}
                +.glyphicon-option-horizontal:before {
                +  content: "\e234";
                +}
                +.glyphicon-option-vertical:before {
                +  content: "\e235";
                +}
                +.glyphicon-menu-hamburger:before {
                +  content: "\e236";
                +}
                +.glyphicon-modal-window:before {
                +  content: "\e237";
                +}
                +.glyphicon-oil:before {
                +  content: "\e238";
                +}
                +.glyphicon-grain:before {
                +  content: "\e239";
                +}
                +.glyphicon-sunglasses:before {
                +  content: "\e240";
                +}
                +.glyphicon-text-size:before {
                +  content: "\e241";
                +}
                +.glyphicon-text-color:before {
                +  content: "\e242";
                +}
                +.glyphicon-text-background:before {
                +  content: "\e243";
                +}
                +.glyphicon-object-align-top:before {
                +  content: "\e244";
                +}
                +.glyphicon-object-align-bottom:before {
                +  content: "\e245";
                +}
                +.glyphicon-object-align-horizontal:before {
                +  content: "\e246";
                +}
                +.glyphicon-object-align-left:before {
                +  content: "\e247";
                +}
                +.glyphicon-object-align-vertical:before {
                +  content: "\e248";
                +}
                +.glyphicon-object-align-right:before {
                +  content: "\e249";
                +}
                +.glyphicon-triangle-right:before {
                +  content: "\e250";
                +}
                +.glyphicon-triangle-left:before {
                +  content: "\e251";
                +}
                +.glyphicon-triangle-bottom:before {
                +  content: "\e252";
                +}
                +.glyphicon-triangle-top:before {
                +  content: "\e253";
                +}
                +.glyphicon-console:before {
                +  content: "\e254";
                +}
                +.glyphicon-superscript:before {
                +  content: "\e255";
                +}
                +.glyphicon-subscript:before {
                +  content: "\e256";
                +}
                +.glyphicon-menu-left:before {
                +  content: "\e257";
                +}
                +.glyphicon-menu-right:before {
                +  content: "\e258";
                +}
                +.glyphicon-menu-down:before {
                +  content: "\e259";
                +}
                +.glyphicon-menu-up:before {
                +  content: "\e260";
                +}
                +* {
                +  -webkit-box-sizing: border-box;
                +     -moz-box-sizing: border-box;
                +          box-sizing: border-box;
                +}
                +*:before,
                +*:after {
                +  -webkit-box-sizing: border-box;
                +     -moz-box-sizing: border-box;
                +          box-sizing: border-box;
                +}
                +html {
                +  font-size: 10px;
                +
                +  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
                +}
                +body {
                +  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                +  font-size: 14px;
                +  line-height: 1.42857143;
                +  color: #333;
                +  background-color: #fff;
                +}
                +input,
                +button,
                +select,
                +textarea {
                +  font-family: inherit;
                +  font-size: inherit;
                +  line-height: inherit;
                +}
                +a {
                +  color: #337ab7;
                +  text-decoration: none;
                +}
                +a:hover,
                +a:focus {
                +  color: #23527c;
                +  text-decoration: underline;
                +}
                +a:focus {
                +  outline: 5px auto -webkit-focus-ring-color;
                +  outline-offset: -2px;
                +}
                +figure {
                +  margin: 0;
                +}
                +img {
                +  vertical-align: middle;
                +}
                +.img-responsive,
                +.thumbnail > img,
                +.thumbnail a > img,
                +.carousel-inner > .item > img,
                +.carousel-inner > .item > a > img {
                +  display: block;
                +  max-width: 100%;
                +  height: auto;
                +}
                +.img-rounded {
                +  border-radius: 6px;
                +}
                +.img-thumbnail {
                +  display: inline-block;
                +  max-width: 100%;
                +  height: auto;
                +  padding: 4px;
                +  line-height: 1.42857143;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +  border-radius: 4px;
                +  -webkit-transition: all .2s ease-in-out;
                +       -o-transition: all .2s ease-in-out;
                +          transition: all .2s ease-in-out;
                +}
                +.img-circle {
                +  border-radius: 50%;
                +}
                +hr {
                +  margin-top: 20px;
                +  margin-bottom: 20px;
                +  border: 0;
                +  border-top: 1px solid #eee;
                +}
                +.sr-only {
                +  position: absolute;
                +  width: 1px;
                +  height: 1px;
                +  padding: 0;
                +  margin: -1px;
                +  overflow: hidden;
                +  clip: rect(0, 0, 0, 0);
                +  border: 0;
                +}
                +.sr-only-focusable:active,
                +.sr-only-focusable:focus {
                +  position: static;
                +  width: auto;
                +  height: auto;
                +  margin: 0;
                +  overflow: visible;
                +  clip: auto;
                +}
                +[role="button"] {
                +  cursor: pointer;
                +}
                +h1,
                +h2,
                +h3,
                +h4,
                +h5,
                +h6,
                +.h1,
                +.h2,
                +.h3,
                +.h4,
                +.h5,
                +.h6 {
                +  font-family: inherit;
                +  font-weight: 500;
                +  line-height: 1.1;
                +  color: inherit;
                +}
                +h1 small,
                +h2 small,
                +h3 small,
                +h4 small,
                +h5 small,
                +h6 small,
                +.h1 small,
                +.h2 small,
                +.h3 small,
                +.h4 small,
                +.h5 small,
                +.h6 small,
                +h1 .small,
                +h2 .small,
                +h3 .small,
                +h4 .small,
                +h5 .small,
                +h6 .small,
                +.h1 .small,
                +.h2 .small,
                +.h3 .small,
                +.h4 .small,
                +.h5 .small,
                +.h6 .small {
                +  font-weight: normal;
                +  line-height: 1;
                +  color: #777;
                +}
                +h1,
                +.h1,
                +h2,
                +.h2,
                +h3,
                +.h3 {
                +  margin-top: 20px;
                +  margin-bottom: 10px;
                +}
                +h1 small,
                +.h1 small,
                +h2 small,
                +.h2 small,
                +h3 small,
                +.h3 small,
                +h1 .small,
                +.h1 .small,
                +h2 .small,
                +.h2 .small,
                +h3 .small,
                +.h3 .small {
                +  font-size: 65%;
                +}
                +h4,
                +.h4,
                +h5,
                +.h5,
                +h6,
                +.h6 {
                +  margin-top: 10px;
                +  margin-bottom: 10px;
                +}
                +h4 small,
                +.h4 small,
                +h5 small,
                +.h5 small,
                +h6 small,
                +.h6 small,
                +h4 .small,
                +.h4 .small,
                +h5 .small,
                +.h5 .small,
                +h6 .small,
                +.h6 .small {
                +  font-size: 75%;
                +}
                +h1,
                +.h1 {
                +  font-size: 36px;
                +}
                +h2,
                +.h2 {
                +  font-size: 30px;
                +}
                +h3,
                +.h3 {
                +  font-size: 24px;
                +}
                +h4,
                +.h4 {
                +  font-size: 18px;
                +}
                +h5,
                +.h5 {
                +  font-size: 14px;
                +}
                +h6,
                +.h6 {
                +  font-size: 12px;
                +}
                +p {
                +  margin: 0 0 10px;
                +}
                +.lead {
                +  margin-bottom: 20px;
                +  font-size: 16px;
                +  font-weight: 300;
                +  line-height: 1.4;
                +}
                +@media (min-width: 768px) {
                +  .lead {
                +    font-size: 21px;
                +  }
                +}
                +small,
                +.small {
                +  font-size: 85%;
                +}
                +mark,
                +.mark {
                +  padding: .2em;
                +  background-color: #fcf8e3;
                +}
                +.text-left {
                +  text-align: left;
                +}
                +.text-right {
                +  text-align: right;
                +}
                +.text-center {
                +  text-align: center;
                +}
                +.text-justify {
                +  text-align: justify;
                +}
                +.text-nowrap {
                +  white-space: nowrap;
                +}
                +.text-lowercase {
                +  text-transform: lowercase;
                +}
                +.text-uppercase {
                +  text-transform: uppercase;
                +}
                +.text-capitalize {
                +  text-transform: capitalize;
                +}
                +.text-muted {
                +  color: #777;
                +}
                +.text-primary {
                +  color: #337ab7;
                +}
                +a.text-primary:hover,
                +a.text-primary:focus {
                +  color: #286090;
                +}
                +.text-success {
                +  color: #3c763d;
                +}
                +a.text-success:hover,
                +a.text-success:focus {
                +  color: #2b542c;
                +}
                +.text-info {
                +  color: #31708f;
                +}
                +a.text-info:hover,
                +a.text-info:focus {
                +  color: #245269;
                +}
                +.text-warning {
                +  color: #8a6d3b;
                +}
                +a.text-warning:hover,
                +a.text-warning:focus {
                +  color: #66512c;
                +}
                +.text-danger {
                +  color: #a94442;
                +}
                +a.text-danger:hover,
                +a.text-danger:focus {
                +  color: #843534;
                +}
                +.bg-primary {
                +  color: #fff;
                +  background-color: #337ab7;
                +}
                +a.bg-primary:hover,
                +a.bg-primary:focus {
                +  background-color: #286090;
                +}
                +.bg-success {
                +  background-color: #dff0d8;
                +}
                +a.bg-success:hover,
                +a.bg-success:focus {
                +  background-color: #c1e2b3;
                +}
                +.bg-info {
                +  background-color: #d9edf7;
                +}
                +a.bg-info:hover,
                +a.bg-info:focus {
                +  background-color: #afd9ee;
                +}
                +.bg-warning {
                +  background-color: #fcf8e3;
                +}
                +a.bg-warning:hover,
                +a.bg-warning:focus {
                +  background-color: #f7ecb5;
                +}
                +.bg-danger {
                +  background-color: #f2dede;
                +}
                +a.bg-danger:hover,
                +a.bg-danger:focus {
                +  background-color: #e4b9b9;
                +}
                +.page-header {
                +  padding-bottom: 9px;
                +  margin: 40px 0 20px;
                +  border-bottom: 1px solid #eee;
                +}
                +ul,
                +ol {
                +  margin-top: 0;
                +  margin-bottom: 10px;
                +}
                +ul ul,
                +ol ul,
                +ul ol,
                +ol ol {
                +  margin-bottom: 0;
                +}
                +.list-unstyled {
                +  padding-left: 0;
                +  list-style: none;
                +}
                +.list-inline {
                +  padding-left: 0;
                +  margin-left: -5px;
                +  list-style: none;
                +}
                +.list-inline > li {
                +  display: inline-block;
                +  padding-right: 5px;
                +  padding-left: 5px;
                +}
                +dl {
                +  margin-top: 0;
                +  margin-bottom: 20px;
                +}
                +dt,
                +dd {
                +  line-height: 1.42857143;
                +}
                +dt {
                +  font-weight: bold;
                +}
                +dd {
                +  margin-left: 0;
                +}
                +@media (min-width: 768px) {
                +  .dl-horizontal dt {
                +    float: left;
                +    width: 160px;
                +    overflow: hidden;
                +    clear: left;
                +    text-align: right;
                +    text-overflow: ellipsis;
                +    white-space: nowrap;
                +  }
                +  .dl-horizontal dd {
                +    margin-left: 180px;
                +  }
                +}
                +abbr[title],
                +abbr[data-original-title] {
                +  cursor: help;
                +  border-bottom: 1px dotted #777;
                +}
                +.initialism {
                +  font-size: 90%;
                +  text-transform: uppercase;
                +}
                +blockquote {
                +  padding: 10px 20px;
                +  margin: 0 0 20px;
                +  font-size: 17.5px;
                +  border-left: 5px solid #eee;
                +}
                +blockquote p:last-child,
                +blockquote ul:last-child,
                +blockquote ol:last-child {
                +  margin-bottom: 0;
                +}
                +blockquote footer,
                +blockquote small,
                +blockquote .small {
                +  display: block;
                +  font-size: 80%;
                +  line-height: 1.42857143;
                +  color: #777;
                +}
                +blockquote footer:before,
                +blockquote small:before,
                +blockquote .small:before {
                +  content: '\2014 \00A0';
                +}
                +.blockquote-reverse,
                +blockquote.pull-right {
                +  padding-right: 15px;
                +  padding-left: 0;
                +  text-align: right;
                +  border-right: 5px solid #eee;
                +  border-left: 0;
                +}
                +.blockquote-reverse footer:before,
                +blockquote.pull-right footer:before,
                +.blockquote-reverse small:before,
                +blockquote.pull-right small:before,
                +.blockquote-reverse .small:before,
                +blockquote.pull-right .small:before {
                +  content: '';
                +}
                +.blockquote-reverse footer:after,
                +blockquote.pull-right footer:after,
                +.blockquote-reverse small:after,
                +blockquote.pull-right small:after,
                +.blockquote-reverse .small:after,
                +blockquote.pull-right .small:after {
                +  content: '\00A0 \2014';
                +}
                +address {
                +  margin-bottom: 20px;
                +  font-style: normal;
                +  line-height: 1.42857143;
                +}
                +code,
                +kbd,
                +pre,
                +samp {
                +  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
                +}
                +code {
                +  padding: 2px 4px;
                +  font-size: 90%;
                +  color: #c7254e;
                +  background-color: #f9f2f4;
                +  border-radius: 4px;
                +}
                +kbd {
                +  padding: 2px 4px;
                +  font-size: 90%;
                +  color: #fff;
                +  background-color: #333;
                +  border-radius: 3px;
                +  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
                +          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
                +}
                +kbd kbd {
                +  padding: 0;
                +  font-size: 100%;
                +  font-weight: bold;
                +  -webkit-box-shadow: none;
                +          box-shadow: none;
                +}
                +pre {
                +  display: block;
                +  padding: 9.5px;
                +  margin: 0 0 10px;
                +  font-size: 13px;
                +  line-height: 1.42857143;
                +  color: #333;
                +  word-break: break-all;
                +  word-wrap: break-word;
                +  background-color: #f5f5f5;
                +  border: 1px solid #ccc;
                +  border-radius: 4px;
                +}
                +pre code {
                +  padding: 0;
                +  font-size: inherit;
                +  color: inherit;
                +  white-space: pre-wrap;
                +  background-color: transparent;
                +  border-radius: 0;
                +}
                +.pre-scrollable {
                +  max-height: 340px;
                +  overflow-y: scroll;
                +}
                +.container {
                +  padding-right: 15px;
                +  padding-left: 15px;
                +  margin-right: auto;
                +  margin-left: auto;
                +}
                +@media (min-width: 768px) {
                +  .container {
                +    width: 750px;
                +  }
                +}
                +@media (min-width: 992px) {
                +  .container {
                +    width: 970px;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .container {
                +    width: 1170px;
                +  }
                +}
                +.container-fluid {
                +  padding-right: 15px;
                +  padding-left: 15px;
                +  margin-right: auto;
                +  margin-left: auto;
                +}
                +.row {
                +  margin-right: -15px;
                +  margin-left: -15px;
                +}
                +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
                +  position: relative;
                +  min-height: 1px;
                +  padding-right: 15px;
                +  padding-left: 15px;
                +}
                +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
                +  float: left;
                +}
                +.col-xs-12 {
                +  width: 100%;
                +}
                +.col-xs-11 {
                +  width: 91.66666667%;
                +}
                +.col-xs-10 {
                +  width: 83.33333333%;
                +}
                +.col-xs-9 {
                +  width: 75%;
                +}
                +.col-xs-8 {
                +  width: 66.66666667%;
                +}
                +.col-xs-7 {
                +  width: 58.33333333%;
                +}
                +.col-xs-6 {
                +  width: 50%;
                +}
                +.col-xs-5 {
                +  width: 41.66666667%;
                +}
                +.col-xs-4 {
                +  width: 33.33333333%;
                +}
                +.col-xs-3 {
                +  width: 25%;
                +}
                +.col-xs-2 {
                +  width: 16.66666667%;
                +}
                +.col-xs-1 {
                +  width: 8.33333333%;
                +}
                +.col-xs-pull-12 {
                +  right: 100%;
                +}
                +.col-xs-pull-11 {
                +  right: 91.66666667%;
                +}
                +.col-xs-pull-10 {
                +  right: 83.33333333%;
                +}
                +.col-xs-pull-9 {
                +  right: 75%;
                +}
                +.col-xs-pull-8 {
                +  right: 66.66666667%;
                +}
                +.col-xs-pull-7 {
                +  right: 58.33333333%;
                +}
                +.col-xs-pull-6 {
                +  right: 50%;
                +}
                +.col-xs-pull-5 {
                +  right: 41.66666667%;
                +}
                +.col-xs-pull-4 {
                +  right: 33.33333333%;
                +}
                +.col-xs-pull-3 {
                +  right: 25%;
                +}
                +.col-xs-pull-2 {
                +  right: 16.66666667%;
                +}
                +.col-xs-pull-1 {
                +  right: 8.33333333%;
                +}
                +.col-xs-pull-0 {
                +  right: auto;
                +}
                +.col-xs-push-12 {
                +  left: 100%;
                +}
                +.col-xs-push-11 {
                +  left: 91.66666667%;
                +}
                +.col-xs-push-10 {
                +  left: 83.33333333%;
                +}
                +.col-xs-push-9 {
                +  left: 75%;
                +}
                +.col-xs-push-8 {
                +  left: 66.66666667%;
                +}
                +.col-xs-push-7 {
                +  left: 58.33333333%;
                +}
                +.col-xs-push-6 {
                +  left: 50%;
                +}
                +.col-xs-push-5 {
                +  left: 41.66666667%;
                +}
                +.col-xs-push-4 {
                +  left: 33.33333333%;
                +}
                +.col-xs-push-3 {
                +  left: 25%;
                +}
                +.col-xs-push-2 {
                +  left: 16.66666667%;
                +}
                +.col-xs-push-1 {
                +  left: 8.33333333%;
                +}
                +.col-xs-push-0 {
                +  left: auto;
                +}
                +.col-xs-offset-12 {
                +  margin-left: 100%;
                +}
                +.col-xs-offset-11 {
                +  margin-left: 91.66666667%;
                +}
                +.col-xs-offset-10 {
                +  margin-left: 83.33333333%;
                +}
                +.col-xs-offset-9 {
                +  margin-left: 75%;
                +}
                +.col-xs-offset-8 {
                +  margin-left: 66.66666667%;
                +}
                +.col-xs-offset-7 {
                +  margin-left: 58.33333333%;
                +}
                +.col-xs-offset-6 {
                +  margin-left: 50%;
                +}
                +.col-xs-offset-5 {
                +  margin-left: 41.66666667%;
                +}
                +.col-xs-offset-4 {
                +  margin-left: 33.33333333%;
                +}
                +.col-xs-offset-3 {
                +  margin-left: 25%;
                +}
                +.col-xs-offset-2 {
                +  margin-left: 16.66666667%;
                +}
                +.col-xs-offset-1 {
                +  margin-left: 8.33333333%;
                +}
                +.col-xs-offset-0 {
                +  margin-left: 0;
                +}
                +@media (min-width: 768px) {
                +  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
                +    float: left;
                +  }
                +  .col-sm-12 {
                +    width: 100%;
                +  }
                +  .col-sm-11 {
                +    width: 91.66666667%;
                +  }
                +  .col-sm-10 {
                +    width: 83.33333333%;
                +  }
                +  .col-sm-9 {
                +    width: 75%;
                +  }
                +  .col-sm-8 {
                +    width: 66.66666667%;
                +  }
                +  .col-sm-7 {
                +    width: 58.33333333%;
                +  }
                +  .col-sm-6 {
                +    width: 50%;
                +  }
                +  .col-sm-5 {
                +    width: 41.66666667%;
                +  }
                +  .col-sm-4 {
                +    width: 33.33333333%;
                +  }
                +  .col-sm-3 {
                +    width: 25%;
                +  }
                +  .col-sm-2 {
                +    width: 16.66666667%;
                +  }
                +  .col-sm-1 {
                +    width: 8.33333333%;
                +  }
                +  .col-sm-pull-12 {
                +    right: 100%;
                +  }
                +  .col-sm-pull-11 {
                +    right: 91.66666667%;
                +  }
                +  .col-sm-pull-10 {
                +    right: 83.33333333%;
                +  }
                +  .col-sm-pull-9 {
                +    right: 75%;
                +  }
                +  .col-sm-pull-8 {
                +    right: 66.66666667%;
                +  }
                +  .col-sm-pull-7 {
                +    right: 58.33333333%;
                +  }
                +  .col-sm-pull-6 {
                +    right: 50%;
                +  }
                +  .col-sm-pull-5 {
                +    right: 41.66666667%;
                +  }
                +  .col-sm-pull-4 {
                +    right: 33.33333333%;
                +  }
                +  .col-sm-pull-3 {
                +    right: 25%;
                +  }
                +  .col-sm-pull-2 {
                +    right: 16.66666667%;
                +  }
                +  .col-sm-pull-1 {
                +    right: 8.33333333%;
                +  }
                +  .col-sm-pull-0 {
                +    right: auto;
                +  }
                +  .col-sm-push-12 {
                +    left: 100%;
                +  }
                +  .col-sm-push-11 {
                +    left: 91.66666667%;
                +  }
                +  .col-sm-push-10 {
                +    left: 83.33333333%;
                +  }
                +  .col-sm-push-9 {
                +    left: 75%;
                +  }
                +  .col-sm-push-8 {
                +    left: 66.66666667%;
                +  }
                +  .col-sm-push-7 {
                +    left: 58.33333333%;
                +  }
                +  .col-sm-push-6 {
                +    left: 50%;
                +  }
                +  .col-sm-push-5 {
                +    left: 41.66666667%;
                +  }
                +  .col-sm-push-4 {
                +    left: 33.33333333%;
                +  }
                +  .col-sm-push-3 {
                +    left: 25%;
                +  }
                +  .col-sm-push-2 {
                +    left: 16.66666667%;
                +  }
                +  .col-sm-push-1 {
                +    left: 8.33333333%;
                +  }
                +  .col-sm-push-0 {
                +    left: auto;
                +  }
                +  .col-sm-offset-12 {
                +    margin-left: 100%;
                +  }
                +  .col-sm-offset-11 {
                +    margin-left: 91.66666667%;
                +  }
                +  .col-sm-offset-10 {
                +    margin-left: 83.33333333%;
                +  }
                +  .col-sm-offset-9 {
                +    margin-left: 75%;
                +  }
                +  .col-sm-offset-8 {
                +    margin-left: 66.66666667%;
                +  }
                +  .col-sm-offset-7 {
                +    margin-left: 58.33333333%;
                +  }
                +  .col-sm-offset-6 {
                +    margin-left: 50%;
                +  }
                +  .col-sm-offset-5 {
                +    margin-left: 41.66666667%;
                +  }
                +  .col-sm-offset-4 {
                +    margin-left: 33.33333333%;
                +  }
                +  .col-sm-offset-3 {
                +    margin-left: 25%;
                +  }
                +  .col-sm-offset-2 {
                +    margin-left: 16.66666667%;
                +  }
                +  .col-sm-offset-1 {
                +    margin-left: 8.33333333%;
                +  }
                +  .col-sm-offset-0 {
                +    margin-left: 0;
                +  }
                +}
                +@media (min-width: 992px) {
                +  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
                +    float: left;
                +  }
                +  .col-md-12 {
                +    width: 100%;
                +  }
                +  .col-md-11 {
                +    width: 91.66666667%;
                +  }
                +  .col-md-10 {
                +    width: 83.33333333%;
                +  }
                +  .col-md-9 {
                +    width: 75%;
                +  }
                +  .col-md-8 {
                +    width: 66.66666667%;
                +  }
                +  .col-md-7 {
                +    width: 58.33333333%;
                +  }
                +  .col-md-6 {
                +    width: 50%;
                +  }
                +  .col-md-5 {
                +    width: 41.66666667%;
                +  }
                +  .col-md-4 {
                +    width: 33.33333333%;
                +  }
                +  .col-md-3 {
                +    width: 25%;
                +  }
                +  .col-md-2 {
                +    width: 16.66666667%;
                +  }
                +  .col-md-1 {
                +    width: 8.33333333%;
                +  }
                +  .col-md-pull-12 {
                +    right: 100%;
                +  }
                +  .col-md-pull-11 {
                +    right: 91.66666667%;
                +  }
                +  .col-md-pull-10 {
                +    right: 83.33333333%;
                +  }
                +  .col-md-pull-9 {
                +    right: 75%;
                +  }
                +  .col-md-pull-8 {
                +    right: 66.66666667%;
                +  }
                +  .col-md-pull-7 {
                +    right: 58.33333333%;
                +  }
                +  .col-md-pull-6 {
                +    right: 50%;
                +  }
                +  .col-md-pull-5 {
                +    right: 41.66666667%;
                +  }
                +  .col-md-pull-4 {
                +    right: 33.33333333%;
                +  }
                +  .col-md-pull-3 {
                +    right: 25%;
                +  }
                +  .col-md-pull-2 {
                +    right: 16.66666667%;
                +  }
                +  .col-md-pull-1 {
                +    right: 8.33333333%;
                +  }
                +  .col-md-pull-0 {
                +    right: auto;
                +  }
                +  .col-md-push-12 {
                +    left: 100%;
                +  }
                +  .col-md-push-11 {
                +    left: 91.66666667%;
                +  }
                +  .col-md-push-10 {
                +    left: 83.33333333%;
                +  }
                +  .col-md-push-9 {
                +    left: 75%;
                +  }
                +  .col-md-push-8 {
                +    left: 66.66666667%;
                +  }
                +  .col-md-push-7 {
                +    left: 58.33333333%;
                +  }
                +  .col-md-push-6 {
                +    left: 50%;
                +  }
                +  .col-md-push-5 {
                +    left: 41.66666667%;
                +  }
                +  .col-md-push-4 {
                +    left: 33.33333333%;
                +  }
                +  .col-md-push-3 {
                +    left: 25%;
                +  }
                +  .col-md-push-2 {
                +    left: 16.66666667%;
                +  }
                +  .col-md-push-1 {
                +    left: 8.33333333%;
                +  }
                +  .col-md-push-0 {
                +    left: auto;
                +  }
                +  .col-md-offset-12 {
                +    margin-left: 100%;
                +  }
                +  .col-md-offset-11 {
                +    margin-left: 91.66666667%;
                +  }
                +  .col-md-offset-10 {
                +    margin-left: 83.33333333%;
                +  }
                +  .col-md-offset-9 {
                +    margin-left: 75%;
                +  }
                +  .col-md-offset-8 {
                +    margin-left: 66.66666667%;
                +  }
                +  .col-md-offset-7 {
                +    margin-left: 58.33333333%;
                +  }
                +  .col-md-offset-6 {
                +    margin-left: 50%;
                +  }
                +  .col-md-offset-5 {
                +    margin-left: 41.66666667%;
                +  }
                +  .col-md-offset-4 {
                +    margin-left: 33.33333333%;
                +  }
                +  .col-md-offset-3 {
                +    margin-left: 25%;
                +  }
                +  .col-md-offset-2 {
                +    margin-left: 16.66666667%;
                +  }
                +  .col-md-offset-1 {
                +    margin-left: 8.33333333%;
                +  }
                +  .col-md-offset-0 {
                +    margin-left: 0;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
                +    float: left;
                +  }
                +  .col-lg-12 {
                +    width: 100%;
                +  }
                +  .col-lg-11 {
                +    width: 91.66666667%;
                +  }
                +  .col-lg-10 {
                +    width: 83.33333333%;
                +  }
                +  .col-lg-9 {
                +    width: 75%;
                +  }
                +  .col-lg-8 {
                +    width: 66.66666667%;
                +  }
                +  .col-lg-7 {
                +    width: 58.33333333%;
                +  }
                +  .col-lg-6 {
                +    width: 50%;
                +  }
                +  .col-lg-5 {
                +    width: 41.66666667%;
                +  }
                +  .col-lg-4 {
                +    width: 33.33333333%;
                +  }
                +  .col-lg-3 {
                +    width: 25%;
                +  }
                +  .col-lg-2 {
                +    width: 16.66666667%;
                +  }
                +  .col-lg-1 {
                +    width: 8.33333333%;
                +  }
                +  .col-lg-pull-12 {
                +    right: 100%;
                +  }
                +  .col-lg-pull-11 {
                +    right: 91.66666667%;
                +  }
                +  .col-lg-pull-10 {
                +    right: 83.33333333%;
                +  }
                +  .col-lg-pull-9 {
                +    right: 75%;
                +  }
                +  .col-lg-pull-8 {
                +    right: 66.66666667%;
                +  }
                +  .col-lg-pull-7 {
                +    right: 58.33333333%;
                +  }
                +  .col-lg-pull-6 {
                +    right: 50%;
                +  }
                +  .col-lg-pull-5 {
                +    right: 41.66666667%;
                +  }
                +  .col-lg-pull-4 {
                +    right: 33.33333333%;
                +  }
                +  .col-lg-pull-3 {
                +    right: 25%;
                +  }
                +  .col-lg-pull-2 {
                +    right: 16.66666667%;
                +  }
                +  .col-lg-pull-1 {
                +    right: 8.33333333%;
                +  }
                +  .col-lg-pull-0 {
                +    right: auto;
                +  }
                +  .col-lg-push-12 {
                +    left: 100%;
                +  }
                +  .col-lg-push-11 {
                +    left: 91.66666667%;
                +  }
                +  .col-lg-push-10 {
                +    left: 83.33333333%;
                +  }
                +  .col-lg-push-9 {
                +    left: 75%;
                +  }
                +  .col-lg-push-8 {
                +    left: 66.66666667%;
                +  }
                +  .col-lg-push-7 {
                +    left: 58.33333333%;
                +  }
                +  .col-lg-push-6 {
                +    left: 50%;
                +  }
                +  .col-lg-push-5 {
                +    left: 41.66666667%;
                +  }
                +  .col-lg-push-4 {
                +    left: 33.33333333%;
                +  }
                +  .col-lg-push-3 {
                +    left: 25%;
                +  }
                +  .col-lg-push-2 {
                +    left: 16.66666667%;
                +  }
                +  .col-lg-push-1 {
                +    left: 8.33333333%;
                +  }
                +  .col-lg-push-0 {
                +    left: auto;
                +  }
                +  .col-lg-offset-12 {
                +    margin-left: 100%;
                +  }
                +  .col-lg-offset-11 {
                +    margin-left: 91.66666667%;
                +  }
                +  .col-lg-offset-10 {
                +    margin-left: 83.33333333%;
                +  }
                +  .col-lg-offset-9 {
                +    margin-left: 75%;
                +  }
                +  .col-lg-offset-8 {
                +    margin-left: 66.66666667%;
                +  }
                +  .col-lg-offset-7 {
                +    margin-left: 58.33333333%;
                +  }
                +  .col-lg-offset-6 {
                +    margin-left: 50%;
                +  }
                +  .col-lg-offset-5 {
                +    margin-left: 41.66666667%;
                +  }
                +  .col-lg-offset-4 {
                +    margin-left: 33.33333333%;
                +  }
                +  .col-lg-offset-3 {
                +    margin-left: 25%;
                +  }
                +  .col-lg-offset-2 {
                +    margin-left: 16.66666667%;
                +  }
                +  .col-lg-offset-1 {
                +    margin-left: 8.33333333%;
                +  }
                +  .col-lg-offset-0 {
                +    margin-left: 0;
                +  }
                +}
                +table {
                +  background-color: transparent;
                +}
                +caption {
                +  padding-top: 8px;
                +  padding-bottom: 8px;
                +  color: #777;
                +  text-align: left;
                +}
                +th {
                +  text-align: left;
                +}
                +.table {
                +  width: 100%;
                +  max-width: 100%;
                +  margin-bottom: 20px;
                +}
                +.table > thead > tr > th,
                +.table > tbody > tr > th,
                +.table > tfoot > tr > th,
                +.table > thead > tr > td,
                +.table > tbody > tr > td,
                +.table > tfoot > tr > td {
                +  padding: 8px;
                +  line-height: 1.42857143;
                +  vertical-align: top;
                +  border-top: 1px solid #ddd;
                +}
                +.table > thead > tr > th {
                +  vertical-align: bottom;
                +  border-bottom: 2px solid #ddd;
                +}
                +.table > caption + thead > tr:first-child > th,
                +.table > colgroup + thead > tr:first-child > th,
                +.table > thead:first-child > tr:first-child > th,
                +.table > caption + thead > tr:first-child > td,
                +.table > colgroup + thead > tr:first-child > td,
                +.table > thead:first-child > tr:first-child > td {
                +  border-top: 0;
                +}
                +.table > tbody + tbody {
                +  border-top: 2px solid #ddd;
                +}
                +.table .table {
                +  background-color: #fff;
                +}
                +.table-condensed > thead > tr > th,
                +.table-condensed > tbody > tr > th,
                +.table-condensed > tfoot > tr > th,
                +.table-condensed > thead > tr > td,
                +.table-condensed > tbody > tr > td,
                +.table-condensed > tfoot > tr > td {
                +  padding: 5px;
                +}
                +.table-bordered {
                +  border: 1px solid #ddd;
                +}
                +.table-bordered > thead > tr > th,
                +.table-bordered > tbody > tr > th,
                +.table-bordered > tfoot > tr > th,
                +.table-bordered > thead > tr > td,
                +.table-bordered > tbody > tr > td,
                +.table-bordered > tfoot > tr > td {
                +  border: 1px solid #ddd;
                +}
                +.table-bordered > thead > tr > th,
                +.table-bordered > thead > tr > td {
                +  border-bottom-width: 2px;
                +}
                +.table-striped > tbody > tr:nth-of-type(odd) {
                +  background-color: #f9f9f9;
                +}
                +.table-hover > tbody > tr:hover {
                +  background-color: #f5f5f5;
                +}
                +table col[class*="col-"] {
                +  position: static;
                +  display: table-column;
                +  float: none;
                +}
                +table td[class*="col-"],
                +table th[class*="col-"] {
                +  position: static;
                +  display: table-cell;
                +  float: none;
                +}
                +.table > thead > tr > td.active,
                +.table > tbody > tr > td.active,
                +.table > tfoot > tr > td.active,
                +.table > thead > tr > th.active,
                +.table > tbody > tr > th.active,
                +.table > tfoot > tr > th.active,
                +.table > thead > tr.active > td,
                +.table > tbody > tr.active > td,
                +.table > tfoot > tr.active > td,
                +.table > thead > tr.active > th,
                +.table > tbody > tr.active > th,
                +.table > tfoot > tr.active > th {
                +  background-color: #f5f5f5;
                +}
                +.table-hover > tbody > tr > td.active:hover,
                +.table-hover > tbody > tr > th.active:hover,
                +.table-hover > tbody > tr.active:hover > td,
                +.table-hover > tbody > tr:hover > .active,
                +.table-hover > tbody > tr.active:hover > th {
                +  background-color: #e8e8e8;
                +}
                +.table > thead > tr > td.success,
                +.table > tbody > tr > td.success,
                +.table > tfoot > tr > td.success,
                +.table > thead > tr > th.success,
                +.table > tbody > tr > th.success,
                +.table > tfoot > tr > th.success,
                +.table > thead > tr.success > td,
                +.table > tbody > tr.success > td,
                +.table > tfoot > tr.success > td,
                +.table > thead > tr.success > th,
                +.table > tbody > tr.success > th,
                +.table > tfoot > tr.success > th {
                +  background-color: #dff0d8;
                +}
                +.table-hover > tbody > tr > td.success:hover,
                +.table-hover > tbody > tr > th.success:hover,
                +.table-hover > tbody > tr.success:hover > td,
                +.table-hover > tbody > tr:hover > .success,
                +.table-hover > tbody > tr.success:hover > th {
                +  background-color: #d0e9c6;
                +}
                +.table > thead > tr > td.info,
                +.table > tbody > tr > td.info,
                +.table > tfoot > tr > td.info,
                +.table > thead > tr > th.info,
                +.table > tbody > tr > th.info,
                +.table > tfoot > tr > th.info,
                +.table > thead > tr.info > td,
                +.table > tbody > tr.info > td,
                +.table > tfoot > tr.info > td,
                +.table > thead > tr.info > th,
                +.table > tbody > tr.info > th,
                +.table > tfoot > tr.info > th {
                +  background-color: #d9edf7;
                +}
                +.table-hover > tbody > tr > td.info:hover,
                +.table-hover > tbody > tr > th.info:hover,
                +.table-hover > tbody > tr.info:hover > td,
                +.table-hover > tbody > tr:hover > .info,
                +.table-hover > tbody > tr.info:hover > th {
                +  background-color: #c4e3f3;
                +}
                +.table > thead > tr > td.warning,
                +.table > tbody > tr > td.warning,
                +.table > tfoot > tr > td.warning,
                +.table > thead > tr > th.warning,
                +.table > tbody > tr > th.warning,
                +.table > tfoot > tr > th.warning,
                +.table > thead > tr.warning > td,
                +.table > tbody > tr.warning > td,
                +.table > tfoot > tr.warning > td,
                +.table > thead > tr.warning > th,
                +.table > tbody > tr.warning > th,
                +.table > tfoot > tr.warning > th {
                +  background-color: #fcf8e3;
                +}
                +.table-hover > tbody > tr > td.warning:hover,
                +.table-hover > tbody > tr > th.warning:hover,
                +.table-hover > tbody > tr.warning:hover > td,
                +.table-hover > tbody > tr:hover > .warning,
                +.table-hover > tbody > tr.warning:hover > th {
                +  background-color: #faf2cc;
                +}
                +.table > thead > tr > td.danger,
                +.table > tbody > tr > td.danger,
                +.table > tfoot > tr > td.danger,
                +.table > thead > tr > th.danger,
                +.table > tbody > tr > th.danger,
                +.table > tfoot > tr > th.danger,
                +.table > thead > tr.danger > td,
                +.table > tbody > tr.danger > td,
                +.table > tfoot > tr.danger > td,
                +.table > thead > tr.danger > th,
                +.table > tbody > tr.danger > th,
                +.table > tfoot > tr.danger > th {
                +  background-color: #f2dede;
                +}
                +.table-hover > tbody > tr > td.danger:hover,
                +.table-hover > tbody > tr > th.danger:hover,
                +.table-hover > tbody > tr.danger:hover > td,
                +.table-hover > tbody > tr:hover > .danger,
                +.table-hover > tbody > tr.danger:hover > th {
                +  background-color: #ebcccc;
                +}
                +.table-responsive {
                +  min-height: .01%;
                +  overflow-x: auto;
                +}
                +@media screen and (max-width: 767px) {
                +  .table-responsive {
                +    width: 100%;
                +    margin-bottom: 15px;
                +    overflow-y: hidden;
                +    -ms-overflow-style: -ms-autohiding-scrollbar;
                +    border: 1px solid #ddd;
                +  }
                +  .table-responsive > .table {
                +    margin-bottom: 0;
                +  }
                +  .table-responsive > .table > thead > tr > th,
                +  .table-responsive > .table > tbody > tr > th,
                +  .table-responsive > .table > tfoot > tr > th,
                +  .table-responsive > .table > thead > tr > td,
                +  .table-responsive > .table > tbody > tr > td,
                +  .table-responsive > .table > tfoot > tr > td {
                +    white-space: nowrap;
                +  }
                +  .table-responsive > .table-bordered {
                +    border: 0;
                +  }
                +  .table-responsive > .table-bordered > thead > tr > th:first-child,
                +  .table-responsive > .table-bordered > tbody > tr > th:first-child,
                +  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
                +  .table-responsive > .table-bordered > thead > tr > td:first-child,
                +  .table-responsive > .table-bordered > tbody > tr > td:first-child,
                +  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
                +    border-left: 0;
                +  }
                +  .table-responsive > .table-bordered > thead > tr > th:last-child,
                +  .table-responsive > .table-bordered > tbody > tr > th:last-child,
                +  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
                +  .table-responsive > .table-bordered > thead > tr > td:last-child,
                +  .table-responsive > .table-bordered > tbody > tr > td:last-child,
                +  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
                +    border-right: 0;
                +  }
                +  .table-responsive > .table-bordered > tbody > tr:last-child > th,
                +  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
                +  .table-responsive > .table-bordered > tbody > tr:last-child > td,
                +  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
                +    border-bottom: 0;
                +  }
                +}
                +fieldset {
                +  min-width: 0;
                +  padding: 0;
                +  margin: 0;
                +  border: 0;
                +}
                +legend {
                +  display: block;
                +  width: 100%;
                +  padding: 0;
                +  margin-bottom: 20px;
                +  font-size: 21px;
                +  line-height: inherit;
                +  color: #333;
                +  border: 0;
                +  border-bottom: 1px solid #e5e5e5;
                +}
                +label {
                +  display: inline-block;
                +  max-width: 100%;
                +  margin-bottom: 5px;
                +  font-weight: bold;
                +}
                +input[type="search"] {
                +  -webkit-box-sizing: border-box;
                +     -moz-box-sizing: border-box;
                +          box-sizing: border-box;
                +}
                +input[type="radio"],
                +input[type="checkbox"] {
                +  margin: 4px 0 0;
                +  margin-top: 1px \9;
                +  line-height: normal;
                +}
                +input[type="file"] {
                +  display: block;
                +}
                +input[type="range"] {
                +  display: block;
                +  width: 100%;
                +}
                +select[multiple],
                +select[size] {
                +  height: auto;
                +}
                +input[type="file"]:focus,
                +input[type="radio"]:focus,
                +input[type="checkbox"]:focus {
                +  outline: 5px auto -webkit-focus-ring-color;
                +  outline-offset: -2px;
                +}
                +output {
                +  display: block;
                +  padding-top: 7px;
                +  font-size: 14px;
                +  line-height: 1.42857143;
                +  color: #555;
                +}
                +.form-control {
                +  display: block;
                +  width: 100%;
                +  height: 34px;
                +  padding: 6px 12px;
                +  font-size: 14px;
                +  line-height: 1.42857143;
                +  color: #555;
                +  background-color: #fff;
                +  background-image: none;
                +  border: 1px solid #ccc;
                +  border-radius: 4px;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
                +       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
                +          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
                +}
                +.form-control:focus {
                +  border-color: #66afe9;
                +  outline: 0;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
                +          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
                +}
                +.form-control::-moz-placeholder {
                +  color: #999;
                +  opacity: 1;
                +}
                +.form-control:-ms-input-placeholder {
                +  color: #999;
                +}
                +.form-control::-webkit-input-placeholder {
                +  color: #999;
                +}
                +.form-control::-ms-expand {
                +  background-color: transparent;
                +  border: 0;
                +}
                +.form-control[disabled],
                +.form-control[readonly],
                +fieldset[disabled] .form-control {
                +  background-color: #eee;
                +  opacity: 1;
                +}
                +.form-control[disabled],
                +fieldset[disabled] .form-control {
                +  cursor: not-allowed;
                +}
                +textarea.form-control {
                +  height: auto;
                +}
                +input[type="search"] {
                +  -webkit-appearance: none;
                +}
                +@media screen and (-webkit-min-device-pixel-ratio: 0) {
                +  input[type="date"].form-control,
                +  input[type="time"].form-control,
                +  input[type="datetime-local"].form-control,
                +  input[type="month"].form-control {
                +    line-height: 34px;
                +  }
                +  input[type="date"].input-sm,
                +  input[type="time"].input-sm,
                +  input[type="datetime-local"].input-sm,
                +  input[type="month"].input-sm,
                +  .input-group-sm input[type="date"],
                +  .input-group-sm input[type="time"],
                +  .input-group-sm input[type="datetime-local"],
                +  .input-group-sm input[type="month"] {
                +    line-height: 30px;
                +  }
                +  input[type="date"].input-lg,
                +  input[type="time"].input-lg,
                +  input[type="datetime-local"].input-lg,
                +  input[type="month"].input-lg,
                +  .input-group-lg input[type="date"],
                +  .input-group-lg input[type="time"],
                +  .input-group-lg input[type="datetime-local"],
                +  .input-group-lg input[type="month"] {
                +    line-height: 46px;
                +  }
                +}
                +.form-group {
                +  margin-bottom: 15px;
                +}
                +.radio,
                +.checkbox {
                +  position: relative;
                +  display: block;
                +  margin-top: 10px;
                +  margin-bottom: 10px;
                +}
                +.radio label,
                +.checkbox label {
                +  min-height: 20px;
                +  padding-left: 20px;
                +  margin-bottom: 0;
                +  font-weight: normal;
                +  cursor: pointer;
                +}
                +.radio input[type="radio"],
                +.radio-inline input[type="radio"],
                +.checkbox input[type="checkbox"],
                +.checkbox-inline input[type="checkbox"] {
                +  position: absolute;
                +  margin-top: 4px \9;
                +  margin-left: -20px;
                +}
                +.radio + .radio,
                +.checkbox + .checkbox {
                +  margin-top: -5px;
                +}
                +.radio-inline,
                +.checkbox-inline {
                +  position: relative;
                +  display: inline-block;
                +  padding-left: 20px;
                +  margin-bottom: 0;
                +  font-weight: normal;
                +  vertical-align: middle;
                +  cursor: pointer;
                +}
                +.radio-inline + .radio-inline,
                +.checkbox-inline + .checkbox-inline {
                +  margin-top: 0;
                +  margin-left: 10px;
                +}
                +input[type="radio"][disabled],
                +input[type="checkbox"][disabled],
                +input[type="radio"].disabled,
                +input[type="checkbox"].disabled,
                +fieldset[disabled] input[type="radio"],
                +fieldset[disabled] input[type="checkbox"] {
                +  cursor: not-allowed;
                +}
                +.radio-inline.disabled,
                +.checkbox-inline.disabled,
                +fieldset[disabled] .radio-inline,
                +fieldset[disabled] .checkbox-inline {
                +  cursor: not-allowed;
                +}
                +.radio.disabled label,
                +.checkbox.disabled label,
                +fieldset[disabled] .radio label,
                +fieldset[disabled] .checkbox label {
                +  cursor: not-allowed;
                +}
                +.form-control-static {
                +  min-height: 34px;
                +  padding-top: 7px;
                +  padding-bottom: 7px;
                +  margin-bottom: 0;
                +}
                +.form-control-static.input-lg,
                +.form-control-static.input-sm {
                +  padding-right: 0;
                +  padding-left: 0;
                +}
                +.input-sm {
                +  height: 30px;
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +  border-radius: 3px;
                +}
                +select.input-sm {
                +  height: 30px;
                +  line-height: 30px;
                +}
                +textarea.input-sm,
                +select[multiple].input-sm {
                +  height: auto;
                +}
                +.form-group-sm .form-control {
                +  height: 30px;
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +  border-radius: 3px;
                +}
                +.form-group-sm select.form-control {
                +  height: 30px;
                +  line-height: 30px;
                +}
                +.form-group-sm textarea.form-control,
                +.form-group-sm select[multiple].form-control {
                +  height: auto;
                +}
                +.form-group-sm .form-control-static {
                +  height: 30px;
                +  min-height: 32px;
                +  padding: 6px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +}
                +.input-lg {
                +  height: 46px;
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +  border-radius: 6px;
                +}
                +select.input-lg {
                +  height: 46px;
                +  line-height: 46px;
                +}
                +textarea.input-lg,
                +select[multiple].input-lg {
                +  height: auto;
                +}
                +.form-group-lg .form-control {
                +  height: 46px;
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +  border-radius: 6px;
                +}
                +.form-group-lg select.form-control {
                +  height: 46px;
                +  line-height: 46px;
                +}
                +.form-group-lg textarea.form-control,
                +.form-group-lg select[multiple].form-control {
                +  height: auto;
                +}
                +.form-group-lg .form-control-static {
                +  height: 46px;
                +  min-height: 38px;
                +  padding: 11px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +}
                +.has-feedback {
                +  position: relative;
                +}
                +.has-feedback .form-control {
                +  padding-right: 42.5px;
                +}
                +.form-control-feedback {
                +  position: absolute;
                +  top: 0;
                +  right: 0;
                +  z-index: 2;
                +  display: block;
                +  width: 34px;
                +  height: 34px;
                +  line-height: 34px;
                +  text-align: center;
                +  pointer-events: none;
                +}
                +.input-lg + .form-control-feedback,
                +.input-group-lg + .form-control-feedback,
                +.form-group-lg .form-control + .form-control-feedback {
                +  width: 46px;
                +  height: 46px;
                +  line-height: 46px;
                +}
                +.input-sm + .form-control-feedback,
                +.input-group-sm + .form-control-feedback,
                +.form-group-sm .form-control + .form-control-feedback {
                +  width: 30px;
                +  height: 30px;
                +  line-height: 30px;
                +}
                +.has-success .help-block,
                +.has-success .control-label,
                +.has-success .radio,
                +.has-success .checkbox,
                +.has-success .radio-inline,
                +.has-success .checkbox-inline,
                +.has-success.radio label,
                +.has-success.checkbox label,
                +.has-success.radio-inline label,
                +.has-success.checkbox-inline label {
                +  color: #3c763d;
                +}
                +.has-success .form-control {
                +  border-color: #3c763d;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +}
                +.has-success .form-control:focus {
                +  border-color: #2b542c;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
                +}
                +.has-success .input-group-addon {
                +  color: #3c763d;
                +  background-color: #dff0d8;
                +  border-color: #3c763d;
                +}
                +.has-success .form-control-feedback {
                +  color: #3c763d;
                +}
                +.has-warning .help-block,
                +.has-warning .control-label,
                +.has-warning .radio,
                +.has-warning .checkbox,
                +.has-warning .radio-inline,
                +.has-warning .checkbox-inline,
                +.has-warning.radio label,
                +.has-warning.checkbox label,
                +.has-warning.radio-inline label,
                +.has-warning.checkbox-inline label {
                +  color: #8a6d3b;
                +}
                +.has-warning .form-control {
                +  border-color: #8a6d3b;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +}
                +.has-warning .form-control:focus {
                +  border-color: #66512c;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
                +}
                +.has-warning .input-group-addon {
                +  color: #8a6d3b;
                +  background-color: #fcf8e3;
                +  border-color: #8a6d3b;
                +}
                +.has-warning .form-control-feedback {
                +  color: #8a6d3b;
                +}
                +.has-error .help-block,
                +.has-error .control-label,
                +.has-error .radio,
                +.has-error .checkbox,
                +.has-error .radio-inline,
                +.has-error .checkbox-inline,
                +.has-error.radio label,
                +.has-error.checkbox label,
                +.has-error.radio-inline label,
                +.has-error.checkbox-inline label {
                +  color: #a94442;
                +}
                +.has-error .form-control {
                +  border-color: #a94442;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                +}
                +.has-error .form-control:focus {
                +  border-color: #843534;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
                +}
                +.has-error .input-group-addon {
                +  color: #a94442;
                +  background-color: #f2dede;
                +  border-color: #a94442;
                +}
                +.has-error .form-control-feedback {
                +  color: #a94442;
                +}
                +.has-feedback label ~ .form-control-feedback {
                +  top: 25px;
                +}
                +.has-feedback label.sr-only ~ .form-control-feedback {
                +  top: 0;
                +}
                +.help-block {
                +  display: block;
                +  margin-top: 5px;
                +  margin-bottom: 10px;
                +  color: #737373;
                +}
                +@media (min-width: 768px) {
                +  .form-inline .form-group {
                +    display: inline-block;
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .form-inline .form-control {
                +    display: inline-block;
                +    width: auto;
                +    vertical-align: middle;
                +  }
                +  .form-inline .form-control-static {
                +    display: inline-block;
                +  }
                +  .form-inline .input-group {
                +    display: inline-table;
                +    vertical-align: middle;
                +  }
                +  .form-inline .input-group .input-group-addon,
                +  .form-inline .input-group .input-group-btn,
                +  .form-inline .input-group .form-control {
                +    width: auto;
                +  }
                +  .form-inline .input-group > .form-control {
                +    width: 100%;
                +  }
                +  .form-inline .control-label {
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .form-inline .radio,
                +  .form-inline .checkbox {
                +    display: inline-block;
                +    margin-top: 0;
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .form-inline .radio label,
                +  .form-inline .checkbox label {
                +    padding-left: 0;
                +  }
                +  .form-inline .radio input[type="radio"],
                +  .form-inline .checkbox input[type="checkbox"] {
                +    position: relative;
                +    margin-left: 0;
                +  }
                +  .form-inline .has-feedback .form-control-feedback {
                +    top: 0;
                +  }
                +}
                +.form-horizontal .radio,
                +.form-horizontal .checkbox,
                +.form-horizontal .radio-inline,
                +.form-horizontal .checkbox-inline {
                +  padding-top: 7px;
                +  margin-top: 0;
                +  margin-bottom: 0;
                +}
                +.form-horizontal .radio,
                +.form-horizontal .checkbox {
                +  min-height: 27px;
                +}
                +.form-horizontal .form-group {
                +  margin-right: -15px;
                +  margin-left: -15px;
                +}
                +@media (min-width: 768px) {
                +  .form-horizontal .control-label {
                +    padding-top: 7px;
                +    margin-bottom: 0;
                +    text-align: right;
                +  }
                +}
                +.form-horizontal .has-feedback .form-control-feedback {
                +  right: 15px;
                +}
                +@media (min-width: 768px) {
                +  .form-horizontal .form-group-lg .control-label {
                +    padding-top: 11px;
                +    font-size: 18px;
                +  }
                +}
                +@media (min-width: 768px) {
                +  .form-horizontal .form-group-sm .control-label {
                +    padding-top: 6px;
                +    font-size: 12px;
                +  }
                +}
                +.btn {
                +  display: inline-block;
                +  padding: 6px 12px;
                +  margin-bottom: 0;
                +  font-size: 14px;
                +  font-weight: normal;
                +  line-height: 1.42857143;
                +  text-align: center;
                +  white-space: nowrap;
                +  vertical-align: middle;
                +  -ms-touch-action: manipulation;
                +      touch-action: manipulation;
                +  cursor: pointer;
                +  -webkit-user-select: none;
                +     -moz-user-select: none;
                +      -ms-user-select: none;
                +          user-select: none;
                +  background-image: none;
                +  border: 1px solid transparent;
                +  border-radius: 4px;
                +}
                +.btn:focus,
                +.btn:active:focus,
                +.btn.active:focus,
                +.btn.focus,
                +.btn:active.focus,
                +.btn.active.focus {
                +  outline: 5px auto -webkit-focus-ring-color;
                +  outline-offset: -2px;
                +}
                +.btn:hover,
                +.btn:focus,
                +.btn.focus {
                +  color: #333;
                +  text-decoration: none;
                +}
                +.btn:active,
                +.btn.active {
                +  background-image: none;
                +  outline: 0;
                +  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +}
                +.btn.disabled,
                +.btn[disabled],
                +fieldset[disabled] .btn {
                +  cursor: not-allowed;
                +  filter: alpha(opacity=65);
                +  -webkit-box-shadow: none;
                +          box-shadow: none;
                +  opacity: .65;
                +}
                +a.btn.disabled,
                +fieldset[disabled] a.btn {
                +  pointer-events: none;
                +}
                +.btn-default {
                +  color: #333;
                +  background-color: #fff;
                +  border-color: #ccc;
                +}
                +.btn-default:focus,
                +.btn-default.focus {
                +  color: #333;
                +  background-color: #e6e6e6;
                +  border-color: #8c8c8c;
                +}
                +.btn-default:hover {
                +  color: #333;
                +  background-color: #e6e6e6;
                +  border-color: #adadad;
                +}
                +.btn-default:active,
                +.btn-default.active,
                +.open > .dropdown-toggle.btn-default {
                +  color: #333;
                +  background-color: #e6e6e6;
                +  border-color: #adadad;
                +}
                +.btn-default:active:hover,
                +.btn-default.active:hover,
                +.open > .dropdown-toggle.btn-default:hover,
                +.btn-default:active:focus,
                +.btn-default.active:focus,
                +.open > .dropdown-toggle.btn-default:focus,
                +.btn-default:active.focus,
                +.btn-default.active.focus,
                +.open > .dropdown-toggle.btn-default.focus {
                +  color: #333;
                +  background-color: #d4d4d4;
                +  border-color: #8c8c8c;
                +}
                +.btn-default:active,
                +.btn-default.active,
                +.open > .dropdown-toggle.btn-default {
                +  background-image: none;
                +}
                +.btn-default.disabled:hover,
                +.btn-default[disabled]:hover,
                +fieldset[disabled] .btn-default:hover,
                +.btn-default.disabled:focus,
                +.btn-default[disabled]:focus,
                +fieldset[disabled] .btn-default:focus,
                +.btn-default.disabled.focus,
                +.btn-default[disabled].focus,
                +fieldset[disabled] .btn-default.focus {
                +  background-color: #fff;
                +  border-color: #ccc;
                +}
                +.btn-default .badge {
                +  color: #fff;
                +  background-color: #333;
                +}
                +.btn-primary {
                +  color: #fff;
                +  background-color: #337ab7;
                +  border-color: #2e6da4;
                +}
                +.btn-primary:focus,
                +.btn-primary.focus {
                +  color: #fff;
                +  background-color: #286090;
                +  border-color: #122b40;
                +}
                +.btn-primary:hover {
                +  color: #fff;
                +  background-color: #286090;
                +  border-color: #204d74;
                +}
                +.btn-primary:active,
                +.btn-primary.active,
                +.open > .dropdown-toggle.btn-primary {
                +  color: #fff;
                +  background-color: #286090;
                +  border-color: #204d74;
                +}
                +.btn-primary:active:hover,
                +.btn-primary.active:hover,
                +.open > .dropdown-toggle.btn-primary:hover,
                +.btn-primary:active:focus,
                +.btn-primary.active:focus,
                +.open > .dropdown-toggle.btn-primary:focus,
                +.btn-primary:active.focus,
                +.btn-primary.active.focus,
                +.open > .dropdown-toggle.btn-primary.focus {
                +  color: #fff;
                +  background-color: #204d74;
                +  border-color: #122b40;
                +}
                +.btn-primary:active,
                +.btn-primary.active,
                +.open > .dropdown-toggle.btn-primary {
                +  background-image: none;
                +}
                +.btn-primary.disabled:hover,
                +.btn-primary[disabled]:hover,
                +fieldset[disabled] .btn-primary:hover,
                +.btn-primary.disabled:focus,
                +.btn-primary[disabled]:focus,
                +fieldset[disabled] .btn-primary:focus,
                +.btn-primary.disabled.focus,
                +.btn-primary[disabled].focus,
                +fieldset[disabled] .btn-primary.focus {
                +  background-color: #337ab7;
                +  border-color: #2e6da4;
                +}
                +.btn-primary .badge {
                +  color: #337ab7;
                +  background-color: #fff;
                +}
                +.btn-success {
                +  color: #fff;
                +  background-color: #5cb85c;
                +  border-color: #4cae4c;
                +}
                +.btn-success:focus,
                +.btn-success.focus {
                +  color: #fff;
                +  background-color: #449d44;
                +  border-color: #255625;
                +}
                +.btn-success:hover {
                +  color: #fff;
                +  background-color: #449d44;
                +  border-color: #398439;
                +}
                +.btn-success:active,
                +.btn-success.active,
                +.open > .dropdown-toggle.btn-success {
                +  color: #fff;
                +  background-color: #449d44;
                +  border-color: #398439;
                +}
                +.btn-success:active:hover,
                +.btn-success.active:hover,
                +.open > .dropdown-toggle.btn-success:hover,
                +.btn-success:active:focus,
                +.btn-success.active:focus,
                +.open > .dropdown-toggle.btn-success:focus,
                +.btn-success:active.focus,
                +.btn-success.active.focus,
                +.open > .dropdown-toggle.btn-success.focus {
                +  color: #fff;
                +  background-color: #398439;
                +  border-color: #255625;
                +}
                +.btn-success:active,
                +.btn-success.active,
                +.open > .dropdown-toggle.btn-success {
                +  background-image: none;
                +}
                +.btn-success.disabled:hover,
                +.btn-success[disabled]:hover,
                +fieldset[disabled] .btn-success:hover,
                +.btn-success.disabled:focus,
                +.btn-success[disabled]:focus,
                +fieldset[disabled] .btn-success:focus,
                +.btn-success.disabled.focus,
                +.btn-success[disabled].focus,
                +fieldset[disabled] .btn-success.focus {
                +  background-color: #5cb85c;
                +  border-color: #4cae4c;
                +}
                +.btn-success .badge {
                +  color: #5cb85c;
                +  background-color: #fff;
                +}
                +.btn-info {
                +  color: #fff;
                +  background-color: #5bc0de;
                +  border-color: #46b8da;
                +}
                +.btn-info:focus,
                +.btn-info.focus {
                +  color: #fff;
                +  background-color: #31b0d5;
                +  border-color: #1b6d85;
                +}
                +.btn-info:hover {
                +  color: #fff;
                +  background-color: #31b0d5;
                +  border-color: #269abc;
                +}
                +.btn-info:active,
                +.btn-info.active,
                +.open > .dropdown-toggle.btn-info {
                +  color: #fff;
                +  background-color: #31b0d5;
                +  border-color: #269abc;
                +}
                +.btn-info:active:hover,
                +.btn-info.active:hover,
                +.open > .dropdown-toggle.btn-info:hover,
                +.btn-info:active:focus,
                +.btn-info.active:focus,
                +.open > .dropdown-toggle.btn-info:focus,
                +.btn-info:active.focus,
                +.btn-info.active.focus,
                +.open > .dropdown-toggle.btn-info.focus {
                +  color: #fff;
                +  background-color: #269abc;
                +  border-color: #1b6d85;
                +}
                +.btn-info:active,
                +.btn-info.active,
                +.open > .dropdown-toggle.btn-info {
                +  background-image: none;
                +}
                +.btn-info.disabled:hover,
                +.btn-info[disabled]:hover,
                +fieldset[disabled] .btn-info:hover,
                +.btn-info.disabled:focus,
                +.btn-info[disabled]:focus,
                +fieldset[disabled] .btn-info:focus,
                +.btn-info.disabled.focus,
                +.btn-info[disabled].focus,
                +fieldset[disabled] .btn-info.focus {
                +  background-color: #5bc0de;
                +  border-color: #46b8da;
                +}
                +.btn-info .badge {
                +  color: #5bc0de;
                +  background-color: #fff;
                +}
                +.btn-warning {
                +  color: #fff;
                +  background-color: #f0ad4e;
                +  border-color: #eea236;
                +}
                +.btn-warning:focus,
                +.btn-warning.focus {
                +  color: #fff;
                +  background-color: #ec971f;
                +  border-color: #985f0d;
                +}
                +.btn-warning:hover {
                +  color: #fff;
                +  background-color: #ec971f;
                +  border-color: #d58512;
                +}
                +.btn-warning:active,
                +.btn-warning.active,
                +.open > .dropdown-toggle.btn-warning {
                +  color: #fff;
                +  background-color: #ec971f;
                +  border-color: #d58512;
                +}
                +.btn-warning:active:hover,
                +.btn-warning.active:hover,
                +.open > .dropdown-toggle.btn-warning:hover,
                +.btn-warning:active:focus,
                +.btn-warning.active:focus,
                +.open > .dropdown-toggle.btn-warning:focus,
                +.btn-warning:active.focus,
                +.btn-warning.active.focus,
                +.open > .dropdown-toggle.btn-warning.focus {
                +  color: #fff;
                +  background-color: #d58512;
                +  border-color: #985f0d;
                +}
                +.btn-warning:active,
                +.btn-warning.active,
                +.open > .dropdown-toggle.btn-warning {
                +  background-image: none;
                +}
                +.btn-warning.disabled:hover,
                +.btn-warning[disabled]:hover,
                +fieldset[disabled] .btn-warning:hover,
                +.btn-warning.disabled:focus,
                +.btn-warning[disabled]:focus,
                +fieldset[disabled] .btn-warning:focus,
                +.btn-warning.disabled.focus,
                +.btn-warning[disabled].focus,
                +fieldset[disabled] .btn-warning.focus {
                +  background-color: #f0ad4e;
                +  border-color: #eea236;
                +}
                +.btn-warning .badge {
                +  color: #f0ad4e;
                +  background-color: #fff;
                +}
                +.btn-danger {
                +  color: #fff;
                +  background-color: #d9534f;
                +  border-color: #d43f3a;
                +}
                +.btn-danger:focus,
                +.btn-danger.focus {
                +  color: #fff;
                +  background-color: #c9302c;
                +  border-color: #761c19;
                +}
                +.btn-danger:hover {
                +  color: #fff;
                +  background-color: #c9302c;
                +  border-color: #ac2925;
                +}
                +.btn-danger:active,
                +.btn-danger.active,
                +.open > .dropdown-toggle.btn-danger {
                +  color: #fff;
                +  background-color: #c9302c;
                +  border-color: #ac2925;
                +}
                +.btn-danger:active:hover,
                +.btn-danger.active:hover,
                +.open > .dropdown-toggle.btn-danger:hover,
                +.btn-danger:active:focus,
                +.btn-danger.active:focus,
                +.open > .dropdown-toggle.btn-danger:focus,
                +.btn-danger:active.focus,
                +.btn-danger.active.focus,
                +.open > .dropdown-toggle.btn-danger.focus {
                +  color: #fff;
                +  background-color: #ac2925;
                +  border-color: #761c19;
                +}
                +.btn-danger:active,
                +.btn-danger.active,
                +.open > .dropdown-toggle.btn-danger {
                +  background-image: none;
                +}
                +.btn-danger.disabled:hover,
                +.btn-danger[disabled]:hover,
                +fieldset[disabled] .btn-danger:hover,
                +.btn-danger.disabled:focus,
                +.btn-danger[disabled]:focus,
                +fieldset[disabled] .btn-danger:focus,
                +.btn-danger.disabled.focus,
                +.btn-danger[disabled].focus,
                +fieldset[disabled] .btn-danger.focus {
                +  background-color: #d9534f;
                +  border-color: #d43f3a;
                +}
                +.btn-danger .badge {
                +  color: #d9534f;
                +  background-color: #fff;
                +}
                +.btn-link {
                +  font-weight: normal;
                +  color: #337ab7;
                +  border-radius: 0;
                +}
                +.btn-link,
                +.btn-link:active,
                +.btn-link.active,
                +.btn-link[disabled],
                +fieldset[disabled] .btn-link {
                +  background-color: transparent;
                +  -webkit-box-shadow: none;
                +          box-shadow: none;
                +}
                +.btn-link,
                +.btn-link:hover,
                +.btn-link:focus,
                +.btn-link:active {
                +  border-color: transparent;
                +}
                +.btn-link:hover,
                +.btn-link:focus {
                +  color: #23527c;
                +  text-decoration: underline;
                +  background-color: transparent;
                +}
                +.btn-link[disabled]:hover,
                +fieldset[disabled] .btn-link:hover,
                +.btn-link[disabled]:focus,
                +fieldset[disabled] .btn-link:focus {
                +  color: #777;
                +  text-decoration: none;
                +}
                +.btn-lg,
                +.btn-group-lg > .btn {
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +  border-radius: 6px;
                +}
                +.btn-sm,
                +.btn-group-sm > .btn {
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +  border-radius: 3px;
                +}
                +.btn-xs,
                +.btn-group-xs > .btn {
                +  padding: 1px 5px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +  border-radius: 3px;
                +}
                +.btn-block {
                +  display: block;
                +  width: 100%;
                +}
                +.btn-block + .btn-block {
                +  margin-top: 5px;
                +}
                +input[type="submit"].btn-block,
                +input[type="reset"].btn-block,
                +input[type="button"].btn-block {
                +  width: 100%;
                +}
                +.fade {
                +  opacity: 0;
                +  -webkit-transition: opacity .15s linear;
                +       -o-transition: opacity .15s linear;
                +          transition: opacity .15s linear;
                +}
                +.fade.in {
                +  opacity: 1;
                +}
                +.collapse {
                +  display: none;
                +}
                +.collapse.in {
                +  display: block;
                +}
                +tr.collapse.in {
                +  display: table-row;
                +}
                +tbody.collapse.in {
                +  display: table-row-group;
                +}
                +.collapsing {
                +  position: relative;
                +  height: 0;
                +  overflow: hidden;
                +  -webkit-transition-timing-function: ease;
                +       -o-transition-timing-function: ease;
                +          transition-timing-function: ease;
                +  -webkit-transition-duration: .35s;
                +       -o-transition-duration: .35s;
                +          transition-duration: .35s;
                +  -webkit-transition-property: height, visibility;
                +       -o-transition-property: height, visibility;
                +          transition-property: height, visibility;
                +}
                +.caret {
                +  display: inline-block;
                +  width: 0;
                +  height: 0;
                +  margin-left: 2px;
                +  vertical-align: middle;
                +  border-top: 4px dashed;
                +  border-top: 4px solid \9;
                +  border-right: 4px solid transparent;
                +  border-left: 4px solid transparent;
                +}
                +.dropup,
                +.dropdown {
                +  position: relative;
                +}
                +.dropdown-toggle:focus {
                +  outline: 0;
                +}
                +.dropdown-menu {
                +  position: absolute;
                +  top: 100%;
                +  left: 0;
                +  z-index: 1000;
                +  display: none;
                +  float: left;
                +  min-width: 160px;
                +  padding: 5px 0;
                +  margin: 2px 0 0;
                +  font-size: 14px;
                +  text-align: left;
                +  list-style: none;
                +  background-color: #fff;
                +  -webkit-background-clip: padding-box;
                +          background-clip: padding-box;
                +  border: 1px solid #ccc;
                +  border: 1px solid rgba(0, 0, 0, .15);
                +  border-radius: 4px;
                +  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
                +          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
                +}
                +.dropdown-menu.pull-right {
                +  right: 0;
                +  left: auto;
                +}
                +.dropdown-menu .divider {
                +  height: 1px;
                +  margin: 9px 0;
                +  overflow: hidden;
                +  background-color: #e5e5e5;
                +}
                +.dropdown-menu > li > a {
                +  display: block;
                +  padding: 3px 20px;
                +  clear: both;
                +  font-weight: normal;
                +  line-height: 1.42857143;
                +  color: #333;
                +  white-space: nowrap;
                +}
                +.dropdown-menu > li > a:hover,
                +.dropdown-menu > li > a:focus {
                +  color: #262626;
                +  text-decoration: none;
                +  background-color: #f5f5f5;
                +}
                +.dropdown-menu > .active > a,
                +.dropdown-menu > .active > a:hover,
                +.dropdown-menu > .active > a:focus {
                +  color: #fff;
                +  text-decoration: none;
                +  background-color: #337ab7;
                +  outline: 0;
                +}
                +.dropdown-menu > .disabled > a,
                +.dropdown-menu > .disabled > a:hover,
                +.dropdown-menu > .disabled > a:focus {
                +  color: #777;
                +}
                +.dropdown-menu > .disabled > a:hover,
                +.dropdown-menu > .disabled > a:focus {
                +  text-decoration: none;
                +  cursor: not-allowed;
                +  background-color: transparent;
                +  background-image: none;
                +  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
                +}
                +.open > .dropdown-menu {
                +  display: block;
                +}
                +.open > a {
                +  outline: 0;
                +}
                +.dropdown-menu-right {
                +  right: 0;
                +  left: auto;
                +}
                +.dropdown-menu-left {
                +  right: auto;
                +  left: 0;
                +}
                +.dropdown-header {
                +  display: block;
                +  padding: 3px 20px;
                +  font-size: 12px;
                +  line-height: 1.42857143;
                +  color: #777;
                +  white-space: nowrap;
                +}
                +.dropdown-backdrop {
                +  position: fixed;
                +  top: 0;
                +  right: 0;
                +  bottom: 0;
                +  left: 0;
                +  z-index: 990;
                +}
                +.pull-right > .dropdown-menu {
                +  right: 0;
                +  left: auto;
                +}
                +.dropup .caret,
                +.navbar-fixed-bottom .dropdown .caret {
                +  content: "";
                +  border-top: 0;
                +  border-bottom: 4px dashed;
                +  border-bottom: 4px solid \9;
                +}
                +.dropup .dropdown-menu,
                +.navbar-fixed-bottom .dropdown .dropdown-menu {
                +  top: auto;
                +  bottom: 100%;
                +  margin-bottom: 2px;
                +}
                +@media (min-width: 768px) {
                +  .navbar-right .dropdown-menu {
                +    right: 0;
                +    left: auto;
                +  }
                +  .navbar-right .dropdown-menu-left {
                +    right: auto;
                +    left: 0;
                +  }
                +}
                +.btn-group,
                +.btn-group-vertical {
                +  position: relative;
                +  display: inline-block;
                +  vertical-align: middle;
                +}
                +.btn-group > .btn,
                +.btn-group-vertical > .btn {
                +  position: relative;
                +  float: left;
                +}
                +.btn-group > .btn:hover,
                +.btn-group-vertical > .btn:hover,
                +.btn-group > .btn:focus,
                +.btn-group-vertical > .btn:focus,
                +.btn-group > .btn:active,
                +.btn-group-vertical > .btn:active,
                +.btn-group > .btn.active,
                +.btn-group-vertical > .btn.active {
                +  z-index: 2;
                +}
                +.btn-group .btn + .btn,
                +.btn-group .btn + .btn-group,
                +.btn-group .btn-group + .btn,
                +.btn-group .btn-group + .btn-group {
                +  margin-left: -1px;
                +}
                +.btn-toolbar {
                +  margin-left: -5px;
                +}
                +.btn-toolbar .btn,
                +.btn-toolbar .btn-group,
                +.btn-toolbar .input-group {
                +  float: left;
                +}
                +.btn-toolbar > .btn,
                +.btn-toolbar > .btn-group,
                +.btn-toolbar > .input-group {
                +  margin-left: 5px;
                +}
                +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
                +  border-radius: 0;
                +}
                +.btn-group > .btn:first-child {
                +  margin-left: 0;
                +}
                +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
                +  border-top-right-radius: 0;
                +  border-bottom-right-radius: 0;
                +}
                +.btn-group > .btn:last-child:not(:first-child),
                +.btn-group > .dropdown-toggle:not(:first-child) {
                +  border-top-left-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.btn-group > .btn-group {
                +  float: left;
                +}
                +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
                +  border-radius: 0;
                +}
                +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
                +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
                +  border-top-right-radius: 0;
                +  border-bottom-right-radius: 0;
                +}
                +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
                +  border-top-left-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.btn-group .dropdown-toggle:active,
                +.btn-group.open .dropdown-toggle {
                +  outline: 0;
                +}
                +.btn-group > .btn + .dropdown-toggle {
                +  padding-right: 8px;
                +  padding-left: 8px;
                +}
                +.btn-group > .btn-lg + .dropdown-toggle {
                +  padding-right: 12px;
                +  padding-left: 12px;
                +}
                +.btn-group.open .dropdown-toggle {
                +  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
                +}
                +.btn-group.open .dropdown-toggle.btn-link {
                +  -webkit-box-shadow: none;
                +          box-shadow: none;
                +}
                +.btn .caret {
                +  margin-left: 0;
                +}
                +.btn-lg .caret {
                +  border-width: 5px 5px 0;
                +  border-bottom-width: 0;
                +}
                +.dropup .btn-lg .caret {
                +  border-width: 0 5px 5px;
                +}
                +.btn-group-vertical > .btn,
                +.btn-group-vertical > .btn-group,
                +.btn-group-vertical > .btn-group > .btn {
                +  display: block;
                +  float: none;
                +  width: 100%;
                +  max-width: 100%;
                +}
                +.btn-group-vertical > .btn-group > .btn {
                +  float: none;
                +}
                +.btn-group-vertical > .btn + .btn,
                +.btn-group-vertical > .btn + .btn-group,
                +.btn-group-vertical > .btn-group + .btn,
                +.btn-group-vertical > .btn-group + .btn-group {
                +  margin-top: -1px;
                +  margin-left: 0;
                +}
                +.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
                +  border-radius: 0;
                +}
                +.btn-group-vertical > .btn:first-child:not(:last-child) {
                +  border-top-left-radius: 4px;
                +  border-top-right-radius: 4px;
                +  border-bottom-right-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.btn-group-vertical > .btn:last-child:not(:first-child) {
                +  border-top-left-radius: 0;
                +  border-top-right-radius: 0;
                +  border-bottom-right-radius: 4px;
                +  border-bottom-left-radius: 4px;
                +}
                +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
                +  border-radius: 0;
                +}
                +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
                +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
                +  border-bottom-right-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
                +  border-top-left-radius: 0;
                +  border-top-right-radius: 0;
                +}
                +.btn-group-justified {
                +  display: table;
                +  width: 100%;
                +  table-layout: fixed;
                +  border-collapse: separate;
                +}
                +.btn-group-justified > .btn,
                +.btn-group-justified > .btn-group {
                +  display: table-cell;
                +  float: none;
                +  width: 1%;
                +}
                +.btn-group-justified > .btn-group .btn {
                +  width: 100%;
                +}
                +.btn-group-justified > .btn-group .dropdown-menu {
                +  left: auto;
                +}
                +[data-toggle="buttons"] > .btn input[type="radio"],
                +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
                +[data-toggle="buttons"] > .btn input[type="checkbox"],
                +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
                +  position: absolute;
                +  clip: rect(0, 0, 0, 0);
                +  pointer-events: none;
                +}
                +.input-group {
                +  position: relative;
                +  display: table;
                +  border-collapse: separate;
                +}
                +.input-group[class*="col-"] {
                +  float: none;
                +  padding-right: 0;
                +  padding-left: 0;
                +}
                +.input-group .form-control {
                +  position: relative;
                +  z-index: 2;
                +  float: left;
                +  width: 100%;
                +  margin-bottom: 0;
                +}
                +.input-group .form-control:focus {
                +  z-index: 3;
                +}
                +.input-group-lg > .form-control,
                +.input-group-lg > .input-group-addon,
                +.input-group-lg > .input-group-btn > .btn {
                +  height: 46px;
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +  border-radius: 6px;
                +}
                +select.input-group-lg > .form-control,
                +select.input-group-lg > .input-group-addon,
                +select.input-group-lg > .input-group-btn > .btn {
                +  height: 46px;
                +  line-height: 46px;
                +}
                +textarea.input-group-lg > .form-control,
                +textarea.input-group-lg > .input-group-addon,
                +textarea.input-group-lg > .input-group-btn > .btn,
                +select[multiple].input-group-lg > .form-control,
                +select[multiple].input-group-lg > .input-group-addon,
                +select[multiple].input-group-lg > .input-group-btn > .btn {
                +  height: auto;
                +}
                +.input-group-sm > .form-control,
                +.input-group-sm > .input-group-addon,
                +.input-group-sm > .input-group-btn > .btn {
                +  height: 30px;
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +  border-radius: 3px;
                +}
                +select.input-group-sm > .form-control,
                +select.input-group-sm > .input-group-addon,
                +select.input-group-sm > .input-group-btn > .btn {
                +  height: 30px;
                +  line-height: 30px;
                +}
                +textarea.input-group-sm > .form-control,
                +textarea.input-group-sm > .input-group-addon,
                +textarea.input-group-sm > .input-group-btn > .btn,
                +select[multiple].input-group-sm > .form-control,
                +select[multiple].input-group-sm > .input-group-addon,
                +select[multiple].input-group-sm > .input-group-btn > .btn {
                +  height: auto;
                +}
                +.input-group-addon,
                +.input-group-btn,
                +.input-group .form-control {
                +  display: table-cell;
                +}
                +.input-group-addon:not(:first-child):not(:last-child),
                +.input-group-btn:not(:first-child):not(:last-child),
                +.input-group .form-control:not(:first-child):not(:last-child) {
                +  border-radius: 0;
                +}
                +.input-group-addon,
                +.input-group-btn {
                +  width: 1%;
                +  white-space: nowrap;
                +  vertical-align: middle;
                +}
                +.input-group-addon {
                +  padding: 6px 12px;
                +  font-size: 14px;
                +  font-weight: normal;
                +  line-height: 1;
                +  color: #555;
                +  text-align: center;
                +  background-color: #eee;
                +  border: 1px solid #ccc;
                +  border-radius: 4px;
                +}
                +.input-group-addon.input-sm {
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  border-radius: 3px;
                +}
                +.input-group-addon.input-lg {
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  border-radius: 6px;
                +}
                +.input-group-addon input[type="radio"],
                +.input-group-addon input[type="checkbox"] {
                +  margin-top: 0;
                +}
                +.input-group .form-control:first-child,
                +.input-group-addon:first-child,
                +.input-group-btn:first-child > .btn,
                +.input-group-btn:first-child > .btn-group > .btn,
                +.input-group-btn:first-child > .dropdown-toggle,
                +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
                +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
                +  border-top-right-radius: 0;
                +  border-bottom-right-radius: 0;
                +}
                +.input-group-addon:first-child {
                +  border-right: 0;
                +}
                +.input-group .form-control:last-child,
                +.input-group-addon:last-child,
                +.input-group-btn:last-child > .btn,
                +.input-group-btn:last-child > .btn-group > .btn,
                +.input-group-btn:last-child > .dropdown-toggle,
                +.input-group-btn:first-child > .btn:not(:first-child),
                +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
                +  border-top-left-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.input-group-addon:last-child {
                +  border-left: 0;
                +}
                +.input-group-btn {
                +  position: relative;
                +  font-size: 0;
                +  white-space: nowrap;
                +}
                +.input-group-btn > .btn {
                +  position: relative;
                +}
                +.input-group-btn > .btn + .btn {
                +  margin-left: -1px;
                +}
                +.input-group-btn > .btn:hover,
                +.input-group-btn > .btn:focus,
                +.input-group-btn > .btn:active {
                +  z-index: 2;
                +}
                +.input-group-btn:first-child > .btn,
                +.input-group-btn:first-child > .btn-group {
                +  margin-right: -1px;
                +}
                +.input-group-btn:last-child > .btn,
                +.input-group-btn:last-child > .btn-group {
                +  z-index: 2;
                +  margin-left: -1px;
                +}
                +.nav {
                +  padding-left: 0;
                +  margin-bottom: 0;
                +  list-style: none;
                +}
                +.nav > li {
                +  position: relative;
                +  display: block;
                +}
                +.nav > li > a {
                +  position: relative;
                +  display: block;
                +  padding: 10px 15px;
                +}
                +.nav > li > a:hover,
                +.nav > li > a:focus {
                +  text-decoration: none;
                +  background-color: #eee;
                +}
                +.nav > li.disabled > a {
                +  color: #777;
                +}
                +.nav > li.disabled > a:hover,
                +.nav > li.disabled > a:focus {
                +  color: #777;
                +  text-decoration: none;
                +  cursor: not-allowed;
                +  background-color: transparent;
                +}
                +.nav .open > a,
                +.nav .open > a:hover,
                +.nav .open > a:focus {
                +  background-color: #eee;
                +  border-color: #337ab7;
                +}
                +.nav .nav-divider {
                +  height: 1px;
                +  margin: 9px 0;
                +  overflow: hidden;
                +  background-color: #e5e5e5;
                +}
                +.nav > li > a > img {
                +  max-width: none;
                +}
                +.nav-tabs {
                +  border-bottom: 1px solid #ddd;
                +}
                +.nav-tabs > li {
                +  float: left;
                +  margin-bottom: -1px;
                +}
                +.nav-tabs > li > a {
                +  margin-right: 2px;
                +  line-height: 1.42857143;
                +  border: 1px solid transparent;
                +  border-radius: 4px 4px 0 0;
                +}
                +.nav-tabs > li > a:hover {
                +  border-color: #eee #eee #ddd;
                +}
                +.nav-tabs > li.active > a,
                +.nav-tabs > li.active > a:hover,
                +.nav-tabs > li.active > a:focus {
                +  color: #555;
                +  cursor: default;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +  border-bottom-color: transparent;
                +}
                +.nav-tabs.nav-justified {
                +  width: 100%;
                +  border-bottom: 0;
                +}
                +.nav-tabs.nav-justified > li {
                +  float: none;
                +}
                +.nav-tabs.nav-justified > li > a {
                +  margin-bottom: 5px;
                +  text-align: center;
                +}
                +.nav-tabs.nav-justified > .dropdown .dropdown-menu {
                +  top: auto;
                +  left: auto;
                +}
                +@media (min-width: 768px) {
                +  .nav-tabs.nav-justified > li {
                +    display: table-cell;
                +    width: 1%;
                +  }
                +  .nav-tabs.nav-justified > li > a {
                +    margin-bottom: 0;
                +  }
                +}
                +.nav-tabs.nav-justified > li > a {
                +  margin-right: 0;
                +  border-radius: 4px;
                +}
                +.nav-tabs.nav-justified > .active > a,
                +.nav-tabs.nav-justified > .active > a:hover,
                +.nav-tabs.nav-justified > .active > a:focus {
                +  border: 1px solid #ddd;
                +}
                +@media (min-width: 768px) {
                +  .nav-tabs.nav-justified > li > a {
                +    border-bottom: 1px solid #ddd;
                +    border-radius: 4px 4px 0 0;
                +  }
                +  .nav-tabs.nav-justified > .active > a,
                +  .nav-tabs.nav-justified > .active > a:hover,
                +  .nav-tabs.nav-justified > .active > a:focus {
                +    border-bottom-color: #fff;
                +  }
                +}
                +.nav-pills > li {
                +  float: left;
                +}
                +.nav-pills > li > a {
                +  border-radius: 4px;
                +}
                +.nav-pills > li + li {
                +  margin-left: 2px;
                +}
                +.nav-pills > li.active > a,
                +.nav-pills > li.active > a:hover,
                +.nav-pills > li.active > a:focus {
                +  color: #fff;
                +  background-color: #337ab7;
                +}
                +.nav-stacked > li {
                +  float: none;
                +}
                +.nav-stacked > li + li {
                +  margin-top: 2px;
                +  margin-left: 0;
                +}
                +.nav-justified {
                +  width: 100%;
                +}
                +.nav-justified > li {
                +  float: none;
                +}
                +.nav-justified > li > a {
                +  margin-bottom: 5px;
                +  text-align: center;
                +}
                +.nav-justified > .dropdown .dropdown-menu {
                +  top: auto;
                +  left: auto;
                +}
                +@media (min-width: 768px) {
                +  .nav-justified > li {
                +    display: table-cell;
                +    width: 1%;
                +  }
                +  .nav-justified > li > a {
                +    margin-bottom: 0;
                +  }
                +}
                +.nav-tabs-justified {
                +  border-bottom: 0;
                +}
                +.nav-tabs-justified > li > a {
                +  margin-right: 0;
                +  border-radius: 4px;
                +}
                +.nav-tabs-justified > .active > a,
                +.nav-tabs-justified > .active > a:hover,
                +.nav-tabs-justified > .active > a:focus {
                +  border: 1px solid #ddd;
                +}
                +@media (min-width: 768px) {
                +  .nav-tabs-justified > li > a {
                +    border-bottom: 1px solid #ddd;
                +    border-radius: 4px 4px 0 0;
                +  }
                +  .nav-tabs-justified > .active > a,
                +  .nav-tabs-justified > .active > a:hover,
                +  .nav-tabs-justified > .active > a:focus {
                +    border-bottom-color: #fff;
                +  }
                +}
                +.tab-content > .tab-pane {
                +  display: none;
                +}
                +.tab-content > .active {
                +  display: block;
                +}
                +.nav-tabs .dropdown-menu {
                +  margin-top: -1px;
                +  border-top-left-radius: 0;
                +  border-top-right-radius: 0;
                +}
                +.navbar {
                +  position: relative;
                +  min-height: 50px;
                +  margin-bottom: 20px;
                +  border: 1px solid transparent;
                +}
                +@media (min-width: 768px) {
                +  .navbar {
                +    border-radius: 4px;
                +  }
                +}
                +@media (min-width: 768px) {
                +  .navbar-header {
                +    float: left;
                +  }
                +}
                +.navbar-collapse {
                +  padding-right: 15px;
                +  padding-left: 15px;
                +  overflow-x: visible;
                +  -webkit-overflow-scrolling: touch;
                +  border-top: 1px solid transparent;
                +  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
                +          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
                +}
                +.navbar-collapse.in {
                +  overflow-y: auto;
                +}
                +@media (min-width: 768px) {
                +  .navbar-collapse {
                +    width: auto;
                +    border-top: 0;
                +    -webkit-box-shadow: none;
                +            box-shadow: none;
                +  }
                +  .navbar-collapse.collapse {
                +    display: block !important;
                +    height: auto !important;
                +    padding-bottom: 0;
                +    overflow: visible !important;
                +  }
                +  .navbar-collapse.in {
                +    overflow-y: visible;
                +  }
                +  .navbar-fixed-top .navbar-collapse,
                +  .navbar-static-top .navbar-collapse,
                +  .navbar-fixed-bottom .navbar-collapse {
                +    padding-right: 0;
                +    padding-left: 0;
                +  }
                +}
                +.navbar-fixed-top .navbar-collapse,
                +.navbar-fixed-bottom .navbar-collapse {
                +  max-height: 340px;
                +}
                +@media (max-device-width: 480px) and (orientation: landscape) {
                +  .navbar-fixed-top .navbar-collapse,
                +  .navbar-fixed-bottom .navbar-collapse {
                +    max-height: 200px;
                +  }
                +}
                +.container > .navbar-header,
                +.container-fluid > .navbar-header,
                +.container > .navbar-collapse,
                +.container-fluid > .navbar-collapse {
                +  margin-right: -15px;
                +  margin-left: -15px;
                +}
                +@media (min-width: 768px) {
                +  .container > .navbar-header,
                +  .container-fluid > .navbar-header,
                +  .container > .navbar-collapse,
                +  .container-fluid > .navbar-collapse {
                +    margin-right: 0;
                +    margin-left: 0;
                +  }
                +}
                +.navbar-static-top {
                +  z-index: 1000;
                +  border-width: 0 0 1px;
                +}
                +@media (min-width: 768px) {
                +  .navbar-static-top {
                +    border-radius: 0;
                +  }
                +}
                +.navbar-fixed-top,
                +.navbar-fixed-bottom {
                +  position: fixed;
                +  right: 0;
                +  left: 0;
                +  z-index: 1030;
                +}
                +@media (min-width: 768px) {
                +  .navbar-fixed-top,
                +  .navbar-fixed-bottom {
                +    border-radius: 0;
                +  }
                +}
                +.navbar-fixed-top {
                +  top: 0;
                +  border-width: 0 0 1px;
                +}
                +.navbar-fixed-bottom {
                +  bottom: 0;
                +  margin-bottom: 0;
                +  border-width: 1px 0 0;
                +}
                +.navbar-brand {
                +  float: left;
                +  height: 50px;
                +  padding: 15px 15px;
                +  font-size: 18px;
                +  line-height: 20px;
                +}
                +.navbar-brand:hover,
                +.navbar-brand:focus {
                +  text-decoration: none;
                +}
                +.navbar-brand > img {
                +  display: block;
                +}
                +@media (min-width: 768px) {
                +  .navbar > .container .navbar-brand,
                +  .navbar > .container-fluid .navbar-brand {
                +    margin-left: -15px;
                +  }
                +}
                +.navbar-toggle {
                +  position: relative;
                +  float: right;
                +  padding: 9px 10px;
                +  margin-top: 8px;
                +  margin-right: 15px;
                +  margin-bottom: 8px;
                +  background-color: transparent;
                +  background-image: none;
                +  border: 1px solid transparent;
                +  border-radius: 4px;
                +}
                +.navbar-toggle:focus {
                +  outline: 0;
                +}
                +.navbar-toggle .icon-bar {
                +  display: block;
                +  width: 22px;
                +  height: 2px;
                +  border-radius: 1px;
                +}
                +.navbar-toggle .icon-bar + .icon-bar {
                +  margin-top: 4px;
                +}
                +@media (min-width: 768px) {
                +  .navbar-toggle {
                +    display: none;
                +  }
                +}
                +.navbar-nav {
                +  margin: 7.5px -15px;
                +}
                +.navbar-nav > li > a {
                +  padding-top: 10px;
                +  padding-bottom: 10px;
                +  line-height: 20px;
                +}
                +@media (max-width: 767px) {
                +  .navbar-nav .open .dropdown-menu {
                +    position: static;
                +    float: none;
                +    width: auto;
                +    margin-top: 0;
                +    background-color: transparent;
                +    border: 0;
                +    -webkit-box-shadow: none;
                +            box-shadow: none;
                +  }
                +  .navbar-nav .open .dropdown-menu > li > a,
                +  .navbar-nav .open .dropdown-menu .dropdown-header {
                +    padding: 5px 15px 5px 25px;
                +  }
                +  .navbar-nav .open .dropdown-menu > li > a {
                +    line-height: 20px;
                +  }
                +  .navbar-nav .open .dropdown-menu > li > a:hover,
                +  .navbar-nav .open .dropdown-menu > li > a:focus {
                +    background-image: none;
                +  }
                +}
                +@media (min-width: 768px) {
                +  .navbar-nav {
                +    float: left;
                +    margin: 0;
                +  }
                +  .navbar-nav > li {
                +    float: left;
                +  }
                +  .navbar-nav > li > a {
                +    padding-top: 15px;
                +    padding-bottom: 15px;
                +  }
                +}
                +.navbar-form {
                +  padding: 10px 15px;
                +  margin-top: 8px;
                +  margin-right: -15px;
                +  margin-bottom: 8px;
                +  margin-left: -15px;
                +  border-top: 1px solid transparent;
                +  border-bottom: 1px solid transparent;
                +  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
                +          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
                +}
                +@media (min-width: 768px) {
                +  .navbar-form .form-group {
                +    display: inline-block;
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .navbar-form .form-control {
                +    display: inline-block;
                +    width: auto;
                +    vertical-align: middle;
                +  }
                +  .navbar-form .form-control-static {
                +    display: inline-block;
                +  }
                +  .navbar-form .input-group {
                +    display: inline-table;
                +    vertical-align: middle;
                +  }
                +  .navbar-form .input-group .input-group-addon,
                +  .navbar-form .input-group .input-group-btn,
                +  .navbar-form .input-group .form-control {
                +    width: auto;
                +  }
                +  .navbar-form .input-group > .form-control {
                +    width: 100%;
                +  }
                +  .navbar-form .control-label {
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .navbar-form .radio,
                +  .navbar-form .checkbox {
                +    display: inline-block;
                +    margin-top: 0;
                +    margin-bottom: 0;
                +    vertical-align: middle;
                +  }
                +  .navbar-form .radio label,
                +  .navbar-form .checkbox label {
                +    padding-left: 0;
                +  }
                +  .navbar-form .radio input[type="radio"],
                +  .navbar-form .checkbox input[type="checkbox"] {
                +    position: relative;
                +    margin-left: 0;
                +  }
                +  .navbar-form .has-feedback .form-control-feedback {
                +    top: 0;
                +  }
                +}
                +@media (max-width: 767px) {
                +  .navbar-form .form-group {
                +    margin-bottom: 5px;
                +  }
                +  .navbar-form .form-group:last-child {
                +    margin-bottom: 0;
                +  }
                +}
                +@media (min-width: 768px) {
                +  .navbar-form {
                +    width: auto;
                +    padding-top: 0;
                +    padding-bottom: 0;
                +    margin-right: 0;
                +    margin-left: 0;
                +    border: 0;
                +    -webkit-box-shadow: none;
                +            box-shadow: none;
                +  }
                +}
                +.navbar-nav > li > .dropdown-menu {
                +  margin-top: 0;
                +  border-top-left-radius: 0;
                +  border-top-right-radius: 0;
                +}
                +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
                +  margin-bottom: 0;
                +  border-top-left-radius: 4px;
                +  border-top-right-radius: 4px;
                +  border-bottom-right-radius: 0;
                +  border-bottom-left-radius: 0;
                +}
                +.navbar-btn {
                +  margin-top: 8px;
                +  margin-bottom: 8px;
                +}
                +.navbar-btn.btn-sm {
                +  margin-top: 10px;
                +  margin-bottom: 10px;
                +}
                +.navbar-btn.btn-xs {
                +  margin-top: 14px;
                +  margin-bottom: 14px;
                +}
                +.navbar-text {
                +  margin-top: 15px;
                +  margin-bottom: 15px;
                +}
                +@media (min-width: 768px) {
                +  .navbar-text {
                +    float: left;
                +    margin-right: 15px;
                +    margin-left: 15px;
                +  }
                +}
                +@media (min-width: 768px) {
                +  .navbar-left {
                +    float: left !important;
                +  }
                +  .navbar-right {
                +    float: right !important;
                +    margin-right: -15px;
                +  }
                +  .navbar-right ~ .navbar-right {
                +    margin-right: 0;
                +  }
                +}
                +.navbar-default {
                +  background-color: #f8f8f8;
                +  border-color: #e7e7e7;
                +}
                +.navbar-default .navbar-brand {
                +  color: #777;
                +}
                +.navbar-default .navbar-brand:hover,
                +.navbar-default .navbar-brand:focus {
                +  color: #5e5e5e;
                +  background-color: transparent;
                +}
                +.navbar-default .navbar-text {
                +  color: #777;
                +}
                +.navbar-default .navbar-nav > li > a {
                +  color: #777;
                +}
                +.navbar-default .navbar-nav > li > a:hover,
                +.navbar-default .navbar-nav > li > a:focus {
                +  color: #333;
                +  background-color: transparent;
                +}
                +.navbar-default .navbar-nav > .active > a,
                +.navbar-default .navbar-nav > .active > a:hover,
                +.navbar-default .navbar-nav > .active > a:focus {
                +  color: #555;
                +  background-color: #e7e7e7;
                +}
                +.navbar-default .navbar-nav > .disabled > a,
                +.navbar-default .navbar-nav > .disabled > a:hover,
                +.navbar-default .navbar-nav > .disabled > a:focus {
                +  color: #ccc;
                +  background-color: transparent;
                +}
                +.navbar-default .navbar-toggle {
                +  border-color: #ddd;
                +}
                +.navbar-default .navbar-toggle:hover,
                +.navbar-default .navbar-toggle:focus {
                +  background-color: #ddd;
                +}
                +.navbar-default .navbar-toggle .icon-bar {
                +  background-color: #888;
                +}
                +.navbar-default .navbar-collapse,
                +.navbar-default .navbar-form {
                +  border-color: #e7e7e7;
                +}
                +.navbar-default .navbar-nav > .open > a,
                +.navbar-default .navbar-nav > .open > a:hover,
                +.navbar-default .navbar-nav > .open > a:focus {
                +  color: #555;
                +  background-color: #e7e7e7;
                +}
                +@media (max-width: 767px) {
                +  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
                +    color: #777;
                +  }
                +  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
                +  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
                +    color: #333;
                +    background-color: transparent;
                +  }
                +  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
                +  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
                +  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
                +    color: #555;
                +    background-color: #e7e7e7;
                +  }
                +  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
                +  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
                +  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
                +    color: #ccc;
                +    background-color: transparent;
                +  }
                +}
                +.navbar-default .navbar-link {
                +  color: #777;
                +}
                +.navbar-default .navbar-link:hover {
                +  color: #333;
                +}
                +.navbar-default .btn-link {
                +  color: #777;
                +}
                +.navbar-default .btn-link:hover,
                +.navbar-default .btn-link:focus {
                +  color: #333;
                +}
                +.navbar-default .btn-link[disabled]:hover,
                +fieldset[disabled] .navbar-default .btn-link:hover,
                +.navbar-default .btn-link[disabled]:focus,
                +fieldset[disabled] .navbar-default .btn-link:focus {
                +  color: #ccc;
                +}
                +.navbar-inverse {
                +  background-color: #222;
                +  border-color: #080808;
                +}
                +.navbar-inverse .navbar-brand {
                +  color: #9d9d9d;
                +}
                +.navbar-inverse .navbar-brand:hover,
                +.navbar-inverse .navbar-brand:focus {
                +  color: #fff;
                +  background-color: transparent;
                +}
                +.navbar-inverse .navbar-text {
                +  color: #9d9d9d;
                +}
                +.navbar-inverse .navbar-nav > li > a {
                +  color: #9d9d9d;
                +}
                +.navbar-inverse .navbar-nav > li > a:hover,
                +.navbar-inverse .navbar-nav > li > a:focus {
                +  color: #fff;
                +  background-color: transparent;
                +}
                +.navbar-inverse .navbar-nav > .active > a,
                +.navbar-inverse .navbar-nav > .active > a:hover,
                +.navbar-inverse .navbar-nav > .active > a:focus {
                +  color: #fff;
                +  background-color: #080808;
                +}
                +.navbar-inverse .navbar-nav > .disabled > a,
                +.navbar-inverse .navbar-nav > .disabled > a:hover,
                +.navbar-inverse .navbar-nav > .disabled > a:focus {
                +  color: #444;
                +  background-color: transparent;
                +}
                +.navbar-inverse .navbar-toggle {
                +  border-color: #333;
                +}
                +.navbar-inverse .navbar-toggle:hover,
                +.navbar-inverse .navbar-toggle:focus {
                +  background-color: #333;
                +}
                +.navbar-inverse .navbar-toggle .icon-bar {
                +  background-color: #fff;
                +}
                +.navbar-inverse .navbar-collapse,
                +.navbar-inverse .navbar-form {
                +  border-color: #101010;
                +}
                +.navbar-inverse .navbar-nav > .open > a,
                +.navbar-inverse .navbar-nav > .open > a:hover,
                +.navbar-inverse .navbar-nav > .open > a:focus {
                +  color: #fff;
                +  background-color: #080808;
                +}
                +@media (max-width: 767px) {
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
                +    border-color: #080808;
                +  }
                +  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
                +    background-color: #080808;
                +  }
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
                +    color: #9d9d9d;
                +  }
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
                +    color: #fff;
                +    background-color: transparent;
                +  }
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
                +    color: #fff;
                +    background-color: #080808;
                +  }
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
                +  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
                +    color: #444;
                +    background-color: transparent;
                +  }
                +}
                +.navbar-inverse .navbar-link {
                +  color: #9d9d9d;
                +}
                +.navbar-inverse .navbar-link:hover {
                +  color: #fff;
                +}
                +.navbar-inverse .btn-link {
                +  color: #9d9d9d;
                +}
                +.navbar-inverse .btn-link:hover,
                +.navbar-inverse .btn-link:focus {
                +  color: #fff;
                +}
                +.navbar-inverse .btn-link[disabled]:hover,
                +fieldset[disabled] .navbar-inverse .btn-link:hover,
                +.navbar-inverse .btn-link[disabled]:focus,
                +fieldset[disabled] .navbar-inverse .btn-link:focus {
                +  color: #444;
                +}
                +.breadcrumb {
                +  padding: 8px 15px;
                +  margin-bottom: 20px;
                +  list-style: none;
                +  background-color: #f5f5f5;
                +  border-radius: 4px;
                +}
                +.breadcrumb > li {
                +  display: inline-block;
                +}
                +.breadcrumb > li + li:before {
                +  padding: 0 5px;
                +  color: #ccc;
                +  content: "/\00a0";
                +}
                +.breadcrumb > .active {
                +  color: #777;
                +}
                +.pagination {
                +  display: inline-block;
                +  padding-left: 0;
                +  margin: 20px 0;
                +  border-radius: 4px;
                +}
                +.pagination > li {
                +  display: inline;
                +}
                +.pagination > li > a,
                +.pagination > li > span {
                +  position: relative;
                +  float: left;
                +  padding: 6px 12px;
                +  margin-left: -1px;
                +  line-height: 1.42857143;
                +  color: #337ab7;
                +  text-decoration: none;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +}
                +.pagination > li:first-child > a,
                +.pagination > li:first-child > span {
                +  margin-left: 0;
                +  border-top-left-radius: 4px;
                +  border-bottom-left-radius: 4px;
                +}
                +.pagination > li:last-child > a,
                +.pagination > li:last-child > span {
                +  border-top-right-radius: 4px;
                +  border-bottom-right-radius: 4px;
                +}
                +.pagination > li > a:hover,
                +.pagination > li > span:hover,
                +.pagination > li > a:focus,
                +.pagination > li > span:focus {
                +  z-index: 2;
                +  color: #23527c;
                +  background-color: #eee;
                +  border-color: #ddd;
                +}
                +.pagination > .active > a,
                +.pagination > .active > span,
                +.pagination > .active > a:hover,
                +.pagination > .active > span:hover,
                +.pagination > .active > a:focus,
                +.pagination > .active > span:focus {
                +  z-index: 3;
                +  color: #fff;
                +  cursor: default;
                +  background-color: #337ab7;
                +  border-color: #337ab7;
                +}
                +.pagination > .disabled > span,
                +.pagination > .disabled > span:hover,
                +.pagination > .disabled > span:focus,
                +.pagination > .disabled > a,
                +.pagination > .disabled > a:hover,
                +.pagination > .disabled > a:focus {
                +  color: #777;
                +  cursor: not-allowed;
                +  background-color: #fff;
                +  border-color: #ddd;
                +}
                +.pagination-lg > li > a,
                +.pagination-lg > li > span {
                +  padding: 10px 16px;
                +  font-size: 18px;
                +  line-height: 1.3333333;
                +}
                +.pagination-lg > li:first-child > a,
                +.pagination-lg > li:first-child > span {
                +  border-top-left-radius: 6px;
                +  border-bottom-left-radius: 6px;
                +}
                +.pagination-lg > li:last-child > a,
                +.pagination-lg > li:last-child > span {
                +  border-top-right-radius: 6px;
                +  border-bottom-right-radius: 6px;
                +}
                +.pagination-sm > li > a,
                +.pagination-sm > li > span {
                +  padding: 5px 10px;
                +  font-size: 12px;
                +  line-height: 1.5;
                +}
                +.pagination-sm > li:first-child > a,
                +.pagination-sm > li:first-child > span {
                +  border-top-left-radius: 3px;
                +  border-bottom-left-radius: 3px;
                +}
                +.pagination-sm > li:last-child > a,
                +.pagination-sm > li:last-child > span {
                +  border-top-right-radius: 3px;
                +  border-bottom-right-radius: 3px;
                +}
                +.pager {
                +  padding-left: 0;
                +  margin: 20px 0;
                +  text-align: center;
                +  list-style: none;
                +}
                +.pager li {
                +  display: inline;
                +}
                +.pager li > a,
                +.pager li > span {
                +  display: inline-block;
                +  padding: 5px 14px;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +  border-radius: 15px;
                +}
                +.pager li > a:hover,
                +.pager li > a:focus {
                +  text-decoration: none;
                +  background-color: #eee;
                +}
                +.pager .next > a,
                +.pager .next > span {
                +  float: right;
                +}
                +.pager .previous > a,
                +.pager .previous > span {
                +  float: left;
                +}
                +.pager .disabled > a,
                +.pager .disabled > a:hover,
                +.pager .disabled > a:focus,
                +.pager .disabled > span {
                +  color: #777;
                +  cursor: not-allowed;
                +  background-color: #fff;
                +}
                +.label {
                +  display: inline;
                +  padding: .2em .6em .3em;
                +  font-size: 75%;
                +  font-weight: bold;
                +  line-height: 1;
                +  color: #fff;
                +  text-align: center;
                +  white-space: nowrap;
                +  vertical-align: baseline;
                +  border-radius: .25em;
                +}
                +a.label:hover,
                +a.label:focus {
                +  color: #fff;
                +  text-decoration: none;
                +  cursor: pointer;
                +}
                +.label:empty {
                +  display: none;
                +}
                +.btn .label {
                +  position: relative;
                +  top: -1px;
                +}
                +.label-default {
                +  background-color: #777;
                +}
                +.label-default[href]:hover,
                +.label-default[href]:focus {
                +  background-color: #5e5e5e;
                +}
                +.label-primary {
                +  background-color: #337ab7;
                +}
                +.label-primary[href]:hover,
                +.label-primary[href]:focus {
                +  background-color: #286090;
                +}
                +.label-success {
                +  background-color: #5cb85c;
                +}
                +.label-success[href]:hover,
                +.label-success[href]:focus {
                +  background-color: #449d44;
                +}
                +.label-info {
                +  background-color: #5bc0de;
                +}
                +.label-info[href]:hover,
                +.label-info[href]:focus {
                +  background-color: #31b0d5;
                +}
                +.label-warning {
                +  background-color: #f0ad4e;
                +}
                +.label-warning[href]:hover,
                +.label-warning[href]:focus {
                +  background-color: #ec971f;
                +}
                +.label-danger {
                +  background-color: #d9534f;
                +}
                +.label-danger[href]:hover,
                +.label-danger[href]:focus {
                +  background-color: #c9302c;
                +}
                +.badge {
                +  display: inline-block;
                +  min-width: 10px;
                +  padding: 3px 7px;
                +  font-size: 12px;
                +  font-weight: bold;
                +  line-height: 1;
                +  color: #fff;
                +  text-align: center;
                +  white-space: nowrap;
                +  vertical-align: middle;
                +  background-color: #777;
                +  border-radius: 10px;
                +}
                +.badge:empty {
                +  display: none;
                +}
                +.btn .badge {
                +  position: relative;
                +  top: -1px;
                +}
                +.btn-xs .badge,
                +.btn-group-xs > .btn .badge {
                +  top: 0;
                +  padding: 1px 5px;
                +}
                +a.badge:hover,
                +a.badge:focus {
                +  color: #fff;
                +  text-decoration: none;
                +  cursor: pointer;
                +}
                +.list-group-item.active > .badge,
                +.nav-pills > .active > a > .badge {
                +  color: #337ab7;
                +  background-color: #fff;
                +}
                +.list-group-item > .badge {
                +  float: right;
                +}
                +.list-group-item > .badge + .badge {
                +  margin-right: 5px;
                +}
                +.nav-pills > li > a > .badge {
                +  margin-left: 3px;
                +}
                +.jumbotron {
                +  padding-top: 30px;
                +  padding-bottom: 30px;
                +  margin-bottom: 30px;
                +  color: inherit;
                +  background-color: #eee;
                +}
                +.jumbotron h1,
                +.jumbotron .h1 {
                +  color: inherit;
                +}
                +.jumbotron p {
                +  margin-bottom: 15px;
                +  font-size: 21px;
                +  font-weight: 200;
                +}
                +.jumbotron > hr {
                +  border-top-color: #d5d5d5;
                +}
                +.container .jumbotron,
                +.container-fluid .jumbotron {
                +  padding-right: 15px;
                +  padding-left: 15px;
                +  border-radius: 6px;
                +}
                +.jumbotron .container {
                +  max-width: 100%;
                +}
                +@media screen and (min-width: 768px) {
                +  .jumbotron {
                +    padding-top: 48px;
                +    padding-bottom: 48px;
                +  }
                +  .container .jumbotron,
                +  .container-fluid .jumbotron {
                +    padding-right: 60px;
                +    padding-left: 60px;
                +  }
                +  .jumbotron h1,
                +  .jumbotron .h1 {
                +    font-size: 63px;
                +  }
                +}
                +.thumbnail {
                +  display: block;
                +  padding: 4px;
                +  margin-bottom: 20px;
                +  line-height: 1.42857143;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +  border-radius: 4px;
                +  -webkit-transition: border .2s ease-in-out;
                +       -o-transition: border .2s ease-in-out;
                +          transition: border .2s ease-in-out;
                +}
                +.thumbnail > img,
                +.thumbnail a > img {
                +  margin-right: auto;
                +  margin-left: auto;
                +}
                +a.thumbnail:hover,
                +a.thumbnail:focus,
                +a.thumbnail.active {
                +  border-color: #337ab7;
                +}
                +.thumbnail .caption {
                +  padding: 9px;
                +  color: #333;
                +}
                +.alert {
                +  padding: 15px;
                +  margin-bottom: 20px;
                +  border: 1px solid transparent;
                +  border-radius: 4px;
                +}
                +.alert h4 {
                +  margin-top: 0;
                +  color: inherit;
                +}
                +.alert .alert-link {
                +  font-weight: bold;
                +}
                +.alert > p,
                +.alert > ul {
                +  margin-bottom: 0;
                +}
                +.alert > p + p {
                +  margin-top: 5px;
                +}
                +.alert-dismissable,
                +.alert-dismissible {
                +  padding-right: 35px;
                +}
                +.alert-dismissable .close,
                +.alert-dismissible .close {
                +  position: relative;
                +  top: -2px;
                +  right: -21px;
                +  color: inherit;
                +}
                +.alert-success {
                +  color: #3c763d;
                +  background-color: #dff0d8;
                +  border-color: #d6e9c6;
                +}
                +.alert-success hr {
                +  border-top-color: #c9e2b3;
                +}
                +.alert-success .alert-link {
                +  color: #2b542c;
                +}
                +.alert-info {
                +  color: #31708f;
                +  background-color: #d9edf7;
                +  border-color: #bce8f1;
                +}
                +.alert-info hr {
                +  border-top-color: #a6e1ec;
                +}
                +.alert-info .alert-link {
                +  color: #245269;
                +}
                +.alert-warning {
                +  color: #8a6d3b;
                +  background-color: #fcf8e3;
                +  border-color: #faebcc;
                +}
                +.alert-warning hr {
                +  border-top-color: #f7e1b5;
                +}
                +.alert-warning .alert-link {
                +  color: #66512c;
                +}
                +.alert-danger {
                +  color: #a94442;
                +  background-color: #f2dede;
                +  border-color: #ebccd1;
                +}
                +.alert-danger hr {
                +  border-top-color: #e4b9c0;
                +}
                +.alert-danger .alert-link {
                +  color: #843534;
                +}
                +@-webkit-keyframes progress-bar-stripes {
                +  from {
                +    background-position: 40px 0;
                +  }
                +  to {
                +    background-position: 0 0;
                +  }
                +}
                +@-o-keyframes progress-bar-stripes {
                +  from {
                +    background-position: 40px 0;
                +  }
                +  to {
                +    background-position: 0 0;
                +  }
                +}
                +@keyframes progress-bar-stripes {
                +  from {
                +    background-position: 40px 0;
                +  }
                +  to {
                +    background-position: 0 0;
                +  }
                +}
                +.progress {
                +  height: 20px;
                +  margin-bottom: 20px;
                +  overflow: hidden;
                +  background-color: #f5f5f5;
                +  border-radius: 4px;
                +  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
                +          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
                +}
                +.progress-bar {
                +  float: left;
                +  width: 0;
                +  height: 100%;
                +  font-size: 12px;
                +  line-height: 20px;
                +  color: #fff;
                +  text-align: center;
                +  background-color: #337ab7;
                +  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
                +          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
                +  -webkit-transition: width .6s ease;
                +       -o-transition: width .6s ease;
                +          transition: width .6s ease;
                +}
                +.progress-striped .progress-bar,
                +.progress-bar-striped {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  -webkit-background-size: 40px 40px;
                +          background-size: 40px 40px;
                +}
                +.progress.active .progress-bar,
                +.progress-bar.active {
                +  -webkit-animation: progress-bar-stripes 2s linear infinite;
                +       -o-animation: progress-bar-stripes 2s linear infinite;
                +          animation: progress-bar-stripes 2s linear infinite;
                +}
                +.progress-bar-success {
                +  background-color: #5cb85c;
                +}
                +.progress-striped .progress-bar-success {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +}
                +.progress-bar-info {
                +  background-color: #5bc0de;
                +}
                +.progress-striped .progress-bar-info {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +}
                +.progress-bar-warning {
                +  background-color: #f0ad4e;
                +}
                +.progress-striped .progress-bar-warning {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +}
                +.progress-bar-danger {
                +  background-color: #d9534f;
                +}
                +.progress-striped .progress-bar-danger {
                +  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
                +}
                +.media {
                +  margin-top: 15px;
                +}
                +.media:first-child {
                +  margin-top: 0;
                +}
                +.media,
                +.media-body {
                +  overflow: hidden;
                +  zoom: 1;
                +}
                +.media-body {
                +  width: 10000px;
                +}
                +.media-object {
                +  display: block;
                +}
                +.media-object.img-thumbnail {
                +  max-width: none;
                +}
                +.media-right,
                +.media > .pull-right {
                +  padding-left: 10px;
                +}
                +.media-left,
                +.media > .pull-left {
                +  padding-right: 10px;
                +}
                +.media-left,
                +.media-right,
                +.media-body {
                +  display: table-cell;
                +  vertical-align: top;
                +}
                +.media-middle {
                +  vertical-align: middle;
                +}
                +.media-bottom {
                +  vertical-align: bottom;
                +}
                +.media-heading {
                +  margin-top: 0;
                +  margin-bottom: 5px;
                +}
                +.media-list {
                +  padding-left: 0;
                +  list-style: none;
                +}
                +.list-group {
                +  padding-left: 0;
                +  margin-bottom: 20px;
                +}
                +.list-group-item {
                +  position: relative;
                +  display: block;
                +  padding: 10px 15px;
                +  margin-bottom: -1px;
                +  background-color: #fff;
                +  border: 1px solid #ddd;
                +}
                +.list-group-item:first-child {
                +  border-top-left-radius: 4px;
                +  border-top-right-radius: 4px;
                +}
                +.list-group-item:last-child {
                +  margin-bottom: 0;
                +  border-bottom-right-radius: 4px;
                +  border-bottom-left-radius: 4px;
                +}
                +a.list-group-item,
                +button.list-group-item {
                +  color: #555;
                +}
                +a.list-group-item .list-group-item-heading,
                +button.list-group-item .list-group-item-heading {
                +  color: #333;
                +}
                +a.list-group-item:hover,
                +button.list-group-item:hover,
                +a.list-group-item:focus,
                +button.list-group-item:focus {
                +  color: #555;
                +  text-decoration: none;
                +  background-color: #f5f5f5;
                +}
                +button.list-group-item {
                +  width: 100%;
                +  text-align: left;
                +}
                +.list-group-item.disabled,
                +.list-group-item.disabled:hover,
                +.list-group-item.disabled:focus {
                +  color: #777;
                +  cursor: not-allowed;
                +  background-color: #eee;
                +}
                +.list-group-item.disabled .list-group-item-heading,
                +.list-group-item.disabled:hover .list-group-item-heading,
                +.list-group-item.disabled:focus .list-group-item-heading {
                +  color: inherit;
                +}
                +.list-group-item.disabled .list-group-item-text,
                +.list-group-item.disabled:hover .list-group-item-text,
                +.list-group-item.disabled:focus .list-group-item-text {
                +  color: #777;
                +}
                +.list-group-item.active,
                +.list-group-item.active:hover,
                +.list-group-item.active:focus {
                +  z-index: 2;
                +  color: #fff;
                +  background-color: #337ab7;
                +  border-color: #337ab7;
                +}
                +.list-group-item.active .list-group-item-heading,
                +.list-group-item.active:hover .list-group-item-heading,
                +.list-group-item.active:focus .list-group-item-heading,
                +.list-group-item.active .list-group-item-heading > small,
                +.list-group-item.active:hover .list-group-item-heading > small,
                +.list-group-item.active:focus .list-group-item-heading > small,
                +.list-group-item.active .list-group-item-heading > .small,
                +.list-group-item.active:hover .list-group-item-heading > .small,
                +.list-group-item.active:focus .list-group-item-heading > .small {
                +  color: inherit;
                +}
                +.list-group-item.active .list-group-item-text,
                +.list-group-item.active:hover .list-group-item-text,
                +.list-group-item.active:focus .list-group-item-text {
                +  color: #c7ddef;
                +}
                +.list-group-item-success {
                +  color: #3c763d;
                +  background-color: #dff0d8;
                +}
                +a.list-group-item-success,
                +button.list-group-item-success {
                +  color: #3c763d;
                +}
                +a.list-group-item-success .list-group-item-heading,
                +button.list-group-item-success .list-group-item-heading {
                +  color: inherit;
                +}
                +a.list-group-item-success:hover,
                +button.list-group-item-success:hover,
                +a.list-group-item-success:focus,
                +button.list-group-item-success:focus {
                +  color: #3c763d;
                +  background-color: #d0e9c6;
                +}
                +a.list-group-item-success.active,
                +button.list-group-item-success.active,
                +a.list-group-item-success.active:hover,
                +button.list-group-item-success.active:hover,
                +a.list-group-item-success.active:focus,
                +button.list-group-item-success.active:focus {
                +  color: #fff;
                +  background-color: #3c763d;
                +  border-color: #3c763d;
                +}
                +.list-group-item-info {
                +  color: #31708f;
                +  background-color: #d9edf7;
                +}
                +a.list-group-item-info,
                +button.list-group-item-info {
                +  color: #31708f;
                +}
                +a.list-group-item-info .list-group-item-heading,
                +button.list-group-item-info .list-group-item-heading {
                +  color: inherit;
                +}
                +a.list-group-item-info:hover,
                +button.list-group-item-info:hover,
                +a.list-group-item-info:focus,
                +button.list-group-item-info:focus {
                +  color: #31708f;
                +  background-color: #c4e3f3;
                +}
                +a.list-group-item-info.active,
                +button.list-group-item-info.active,
                +a.list-group-item-info.active:hover,
                +button.list-group-item-info.active:hover,
                +a.list-group-item-info.active:focus,
                +button.list-group-item-info.active:focus {
                +  color: #fff;
                +  background-color: #31708f;
                +  border-color: #31708f;
                +}
                +.list-group-item-warning {
                +  color: #8a6d3b;
                +  background-color: #fcf8e3;
                +}
                +a.list-group-item-warning,
                +button.list-group-item-warning {
                +  color: #8a6d3b;
                +}
                +a.list-group-item-warning .list-group-item-heading,
                +button.list-group-item-warning .list-group-item-heading {
                +  color: inherit;
                +}
                +a.list-group-item-warning:hover,
                +button.list-group-item-warning:hover,
                +a.list-group-item-warning:focus,
                +button.list-group-item-warning:focus {
                +  color: #8a6d3b;
                +  background-color: #faf2cc;
                +}
                +a.list-group-item-warning.active,
                +button.list-group-item-warning.active,
                +a.list-group-item-warning.active:hover,
                +button.list-group-item-warning.active:hover,
                +a.list-group-item-warning.active:focus,
                +button.list-group-item-warning.active:focus {
                +  color: #fff;
                +  background-color: #8a6d3b;
                +  border-color: #8a6d3b;
                +}
                +.list-group-item-danger {
                +  color: #a94442;
                +  background-color: #f2dede;
                +}
                +a.list-group-item-danger,
                +button.list-group-item-danger {
                +  color: #a94442;
                +}
                +a.list-group-item-danger .list-group-item-heading,
                +button.list-group-item-danger .list-group-item-heading {
                +  color: inherit;
                +}
                +a.list-group-item-danger:hover,
                +button.list-group-item-danger:hover,
                +a.list-group-item-danger:focus,
                +button.list-group-item-danger:focus {
                +  color: #a94442;
                +  background-color: #ebcccc;
                +}
                +a.list-group-item-danger.active,
                +button.list-group-item-danger.active,
                +a.list-group-item-danger.active:hover,
                +button.list-group-item-danger.active:hover,
                +a.list-group-item-danger.active:focus,
                +button.list-group-item-danger.active:focus {
                +  color: #fff;
                +  background-color: #a94442;
                +  border-color: #a94442;
                +}
                +.list-group-item-heading {
                +  margin-top: 0;
                +  margin-bottom: 5px;
                +}
                +.list-group-item-text {
                +  margin-bottom: 0;
                +  line-height: 1.3;
                +}
                +.panel {
                +  margin-bottom: 20px;
                +  background-color: #fff;
                +  border: 1px solid transparent;
                +  border-radius: 4px;
                +  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
                +          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
                +}
                +.panel-body {
                +  padding: 15px;
                +}
                +.panel-heading {
                +  padding: 10px 15px;
                +  border-bottom: 1px solid transparent;
                +  border-top-left-radius: 3px;
                +  border-top-right-radius: 3px;
                +}
                +.panel-heading > .dropdown .dropdown-toggle {
                +  color: inherit;
                +}
                +.panel-title {
                +  margin-top: 0;
                +  margin-bottom: 0;
                +  font-size: 16px;
                +  color: inherit;
                +}
                +.panel-title > a,
                +.panel-title > small,
                +.panel-title > .small,
                +.panel-title > small > a,
                +.panel-title > .small > a {
                +  color: inherit;
                +}
                +.panel-footer {
                +  padding: 10px 15px;
                +  background-color: #f5f5f5;
                +  border-top: 1px solid #ddd;
                +  border-bottom-right-radius: 3px;
                +  border-bottom-left-radius: 3px;
                +}
                +.panel > .list-group,
                +.panel > .panel-collapse > .list-group {
                +  margin-bottom: 0;
                +}
                +.panel > .list-group .list-group-item,
                +.panel > .panel-collapse > .list-group .list-group-item {
                +  border-width: 1px 0;
                +  border-radius: 0;
                +}
                +.panel > .list-group:first-child .list-group-item:first-child,
                +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
                +  border-top: 0;
                +  border-top-left-radius: 3px;
                +  border-top-right-radius: 3px;
                +}
                +.panel > .list-group:last-child .list-group-item:last-child,
                +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
                +  border-bottom: 0;
                +  border-bottom-right-radius: 3px;
                +  border-bottom-left-radius: 3px;
                +}
                +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
                +  border-top-left-radius: 0;
                +  border-top-right-radius: 0;
                +}
                +.panel-heading + .list-group .list-group-item:first-child {
                +  border-top-width: 0;
                +}
                +.list-group + .panel-footer {
                +  border-top-width: 0;
                +}
                +.panel > .table,
                +.panel > .table-responsive > .table,
                +.panel > .panel-collapse > .table {
                +  margin-bottom: 0;
                +}
                +.panel > .table caption,
                +.panel > .table-responsive > .table caption,
                +.panel > .panel-collapse > .table caption {
                +  padding-right: 15px;
                +  padding-left: 15px;
                +}
                +.panel > .table:first-child,
                +.panel > .table-responsive:first-child > .table:first-child {
                +  border-top-left-radius: 3px;
                +  border-top-right-radius: 3px;
                +}
                +.panel > .table:first-child > thead:first-child > tr:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
                +.panel > .table:first-child > tbody:first-child > tr:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
                +  border-top-left-radius: 3px;
                +  border-top-right-radius: 3px;
                +}
                +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
                +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
                +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
                +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
                +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
                +  border-top-left-radius: 3px;
                +}
                +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
                +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
                +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
                +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
                +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
                +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
                +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
                +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
                +  border-top-right-radius: 3px;
                +}
                +.panel > .table:last-child,
                +.panel > .table-responsive:last-child > .table:last-child {
                +  border-bottom-right-radius: 3px;
                +  border-bottom-left-radius: 3px;
                +}
                +.panel > .table:last-child > tbody:last-child > tr:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
                +.panel > .table:last-child > tfoot:last-child > tr:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
                +  border-bottom-right-radius: 3px;
                +  border-bottom-left-radius: 3px;
                +}
                +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
                +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
                +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
                +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
                +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
                +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
                +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
                +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
                +  border-bottom-left-radius: 3px;
                +}
                +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
                +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
                +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
                +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
                +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
                +  border-bottom-right-radius: 3px;
                +}
                +.panel > .panel-body + .table,
                +.panel > .panel-body + .table-responsive,
                +.panel > .table + .panel-body,
                +.panel > .table-responsive + .panel-body {
                +  border-top: 1px solid #ddd;
                +}
                +.panel > .table > tbody:first-child > tr:first-child th,
                +.panel > .table > tbody:first-child > tr:first-child td {
                +  border-top: 0;
                +}
                +.panel > .table-bordered,
                +.panel > .table-responsive > .table-bordered {
                +  border: 0;
                +}
                +.panel > .table-bordered > thead > tr > th:first-child,
                +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
                +.panel > .table-bordered > tbody > tr > th:first-child,
                +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
                +.panel > .table-bordered > tfoot > tr > th:first-child,
                +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
                +.panel > .table-bordered > thead > tr > td:first-child,
                +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
                +.panel > .table-bordered > tbody > tr > td:first-child,
                +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
                +.panel > .table-bordered > tfoot > tr > td:first-child,
                +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
                +  border-left: 0;
                +}
                +.panel > .table-bordered > thead > tr > th:last-child,
                +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
                +.panel > .table-bordered > tbody > tr > th:last-child,
                +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
                +.panel > .table-bordered > tfoot > tr > th:last-child,
                +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
                +.panel > .table-bordered > thead > tr > td:last-child,
                +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
                +.panel > .table-bordered > tbody > tr > td:last-child,
                +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
                +.panel > .table-bordered > tfoot > tr > td:last-child,
                +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
                +  border-right: 0;
                +}
                +.panel > .table-bordered > thead > tr:first-child > td,
                +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
                +.panel > .table-bordered > tbody > tr:first-child > td,
                +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
                +.panel > .table-bordered > thead > tr:first-child > th,
                +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
                +.panel > .table-bordered > tbody > tr:first-child > th,
                +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
                +  border-bottom: 0;
                +}
                +.panel > .table-bordered > tbody > tr:last-child > td,
                +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
                +.panel > .table-bordered > tfoot > tr:last-child > td,
                +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
                +.panel > .table-bordered > tbody > tr:last-child > th,
                +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
                +.panel > .table-bordered > tfoot > tr:last-child > th,
                +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
                +  border-bottom: 0;
                +}
                +.panel > .table-responsive {
                +  margin-bottom: 0;
                +  border: 0;
                +}
                +.panel-group {
                +  margin-bottom: 20px;
                +}
                +.panel-group .panel {
                +  margin-bottom: 0;
                +  border-radius: 4px;
                +}
                +.panel-group .panel + .panel {
                +  margin-top: 5px;
                +}
                +.panel-group .panel-heading {
                +  border-bottom: 0;
                +}
                +.panel-group .panel-heading + .panel-collapse > .panel-body,
                +.panel-group .panel-heading + .panel-collapse > .list-group {
                +  border-top: 1px solid #ddd;
                +}
                +.panel-group .panel-footer {
                +  border-top: 0;
                +}
                +.panel-group .panel-footer + .panel-collapse .panel-body {
                +  border-bottom: 1px solid #ddd;
                +}
                +.panel-default {
                +  border-color: #ddd;
                +}
                +.panel-default > .panel-heading {
                +  color: #333;
                +  background-color: #f5f5f5;
                +  border-color: #ddd;
                +}
                +.panel-default > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #ddd;
                +}
                +.panel-default > .panel-heading .badge {
                +  color: #f5f5f5;
                +  background-color: #333;
                +}
                +.panel-default > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #ddd;
                +}
                +.panel-primary {
                +  border-color: #337ab7;
                +}
                +.panel-primary > .panel-heading {
                +  color: #fff;
                +  background-color: #337ab7;
                +  border-color: #337ab7;
                +}
                +.panel-primary > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #337ab7;
                +}
                +.panel-primary > .panel-heading .badge {
                +  color: #337ab7;
                +  background-color: #fff;
                +}
                +.panel-primary > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #337ab7;
                +}
                +.panel-success {
                +  border-color: #d6e9c6;
                +}
                +.panel-success > .panel-heading {
                +  color: #3c763d;
                +  background-color: #dff0d8;
                +  border-color: #d6e9c6;
                +}
                +.panel-success > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #d6e9c6;
                +}
                +.panel-success > .panel-heading .badge {
                +  color: #dff0d8;
                +  background-color: #3c763d;
                +}
                +.panel-success > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #d6e9c6;
                +}
                +.panel-info {
                +  border-color: #bce8f1;
                +}
                +.panel-info > .panel-heading {
                +  color: #31708f;
                +  background-color: #d9edf7;
                +  border-color: #bce8f1;
                +}
                +.panel-info > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #bce8f1;
                +}
                +.panel-info > .panel-heading .badge {
                +  color: #d9edf7;
                +  background-color: #31708f;
                +}
                +.panel-info > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #bce8f1;
                +}
                +.panel-warning {
                +  border-color: #faebcc;
                +}
                +.panel-warning > .panel-heading {
                +  color: #8a6d3b;
                +  background-color: #fcf8e3;
                +  border-color: #faebcc;
                +}
                +.panel-warning > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #faebcc;
                +}
                +.panel-warning > .panel-heading .badge {
                +  color: #fcf8e3;
                +  background-color: #8a6d3b;
                +}
                +.panel-warning > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #faebcc;
                +}
                +.panel-danger {
                +  border-color: #ebccd1;
                +}
                +.panel-danger > .panel-heading {
                +  color: #a94442;
                +  background-color: #f2dede;
                +  border-color: #ebccd1;
                +}
                +.panel-danger > .panel-heading + .panel-collapse > .panel-body {
                +  border-top-color: #ebccd1;
                +}
                +.panel-danger > .panel-heading .badge {
                +  color: #f2dede;
                +  background-color: #a94442;
                +}
                +.panel-danger > .panel-footer + .panel-collapse > .panel-body {
                +  border-bottom-color: #ebccd1;
                +}
                +.embed-responsive {
                +  position: relative;
                +  display: block;
                +  height: 0;
                +  padding: 0;
                +  overflow: hidden;
                +}
                +.embed-responsive .embed-responsive-item,
                +.embed-responsive iframe,
                +.embed-responsive embed,
                +.embed-responsive object,
                +.embed-responsive video {
                +  position: absolute;
                +  top: 0;
                +  bottom: 0;
                +  left: 0;
                +  width: 100%;
                +  height: 100%;
                +  border: 0;
                +}
                +.embed-responsive-16by9 {
                +  padding-bottom: 56.25%;
                +}
                +.embed-responsive-4by3 {
                +  padding-bottom: 75%;
                +}
                +.well {
                +  min-height: 20px;
                +  padding: 19px;
                +  margin-bottom: 20px;
                +  background-color: #f5f5f5;
                +  border: 1px solid #e3e3e3;
                +  border-radius: 4px;
                +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
                +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
                +}
                +.well blockquote {
                +  border-color: #ddd;
                +  border-color: rgba(0, 0, 0, .15);
                +}
                +.well-lg {
                +  padding: 24px;
                +  border-radius: 6px;
                +}
                +.well-sm {
                +  padding: 9px;
                +  border-radius: 3px;
                +}
                +.close {
                +  float: right;
                +  font-size: 21px;
                +  font-weight: bold;
                +  line-height: 1;
                +  color: #000;
                +  text-shadow: 0 1px 0 #fff;
                +  filter: alpha(opacity=20);
                +  opacity: .2;
                +}
                +.close:hover,
                +.close:focus {
                +  color: #000;
                +  text-decoration: none;
                +  cursor: pointer;
                +  filter: alpha(opacity=50);
                +  opacity: .5;
                +}
                +button.close {
                +  -webkit-appearance: none;
                +  padding: 0;
                +  cursor: pointer;
                +  background: transparent;
                +  border: 0;
                +}
                +.modal-open {
                +  overflow: hidden;
                +}
                +.modal {
                +  position: fixed;
                +  top: 0;
                +  right: 0;
                +  bottom: 0;
                +  left: 0;
                +  z-index: 1050;
                +  display: none;
                +  overflow: hidden;
                +  -webkit-overflow-scrolling: touch;
                +  outline: 0;
                +}
                +.modal.fade .modal-dialog {
                +  -webkit-transition: -webkit-transform .3s ease-out;
                +       -o-transition:      -o-transform .3s ease-out;
                +          transition:         transform .3s ease-out;
                +  -webkit-transform: translate(0, -25%);
                +      -ms-transform: translate(0, -25%);
                +       -o-transform: translate(0, -25%);
                +          transform: translate(0, -25%);
                +}
                +.modal.in .modal-dialog {
                +  -webkit-transform: translate(0, 0);
                +      -ms-transform: translate(0, 0);
                +       -o-transform: translate(0, 0);
                +          transform: translate(0, 0);
                +}
                +.modal-open .modal {
                +  overflow-x: hidden;
                +  overflow-y: auto;
                +}
                +.modal-dialog {
                +  position: relative;
                +  width: auto;
                +  margin: 10px;
                +}
                +.modal-content {
                +  position: relative;
                +  background-color: #fff;
                +  -webkit-background-clip: padding-box;
                +          background-clip: padding-box;
                +  border: 1px solid #999;
                +  border: 1px solid rgba(0, 0, 0, .2);
                +  border-radius: 6px;
                +  outline: 0;
                +  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
                +          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
                +}
                +.modal-backdrop {
                +  position: fixed;
                +  top: 0;
                +  right: 0;
                +  bottom: 0;
                +  left: 0;
                +  z-index: 1040;
                +  background-color: #000;
                +}
                +.modal-backdrop.fade {
                +  filter: alpha(opacity=0);
                +  opacity: 0;
                +}
                +.modal-backdrop.in {
                +  filter: alpha(opacity=50);
                +  opacity: .5;
                +}
                +.modal-header {
                +  padding: 15px;
                +  border-bottom: 1px solid #e5e5e5;
                +}
                +.modal-header .close {
                +  margin-top: -2px;
                +}
                +.modal-title {
                +  margin: 0;
                +  line-height: 1.42857143;
                +}
                +.modal-body {
                +  position: relative;
                +  padding: 15px;
                +}
                +.modal-footer {
                +  padding: 15px;
                +  text-align: right;
                +  border-top: 1px solid #e5e5e5;
                +}
                +.modal-footer .btn + .btn {
                +  margin-bottom: 0;
                +  margin-left: 5px;
                +}
                +.modal-footer .btn-group .btn + .btn {
                +  margin-left: -1px;
                +}
                +.modal-footer .btn-block + .btn-block {
                +  margin-left: 0;
                +}
                +.modal-scrollbar-measure {
                +  position: absolute;
                +  top: -9999px;
                +  width: 50px;
                +  height: 50px;
                +  overflow: scroll;
                +}
                +@media (min-width: 768px) {
                +  .modal-dialog {
                +    width: 600px;
                +    margin: 30px auto;
                +  }
                +  .modal-content {
                +    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
                +            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
                +  }
                +  .modal-sm {
                +    width: 300px;
                +  }
                +}
                +@media (min-width: 992px) {
                +  .modal-lg {
                +    width: 900px;
                +  }
                +}
                +.tooltip {
                +  position: absolute;
                +  z-index: 1070;
                +  display: block;
                +  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                +  font-size: 12px;
                +  font-style: normal;
                +  font-weight: normal;
                +  line-height: 1.42857143;
                +  text-align: left;
                +  text-align: start;
                +  text-decoration: none;
                +  text-shadow: none;
                +  text-transform: none;
                +  letter-spacing: normal;
                +  word-break: normal;
                +  word-spacing: normal;
                +  word-wrap: normal;
                +  white-space: normal;
                +  filter: alpha(opacity=0);
                +  opacity: 0;
                +
                +  line-break: auto;
                +}
                +.tooltip.in {
                +  filter: alpha(opacity=90);
                +  opacity: .9;
                +}
                +.tooltip.top {
                +  padding: 5px 0;
                +  margin-top: -3px;
                +}
                +.tooltip.right {
                +  padding: 0 5px;
                +  margin-left: 3px;
                +}
                +.tooltip.bottom {
                +  padding: 5px 0;
                +  margin-top: 3px;
                +}
                +.tooltip.left {
                +  padding: 0 5px;
                +  margin-left: -3px;
                +}
                +.tooltip-inner {
                +  max-width: 200px;
                +  padding: 3px 8px;
                +  color: #fff;
                +  text-align: center;
                +  background-color: #000;
                +  border-radius: 4px;
                +}
                +.tooltip-arrow {
                +  position: absolute;
                +  width: 0;
                +  height: 0;
                +  border-color: transparent;
                +  border-style: solid;
                +}
                +.tooltip.top .tooltip-arrow {
                +  bottom: 0;
                +  left: 50%;
                +  margin-left: -5px;
                +  border-width: 5px 5px 0;
                +  border-top-color: #000;
                +}
                +.tooltip.top-left .tooltip-arrow {
                +  right: 5px;
                +  bottom: 0;
                +  margin-bottom: -5px;
                +  border-width: 5px 5px 0;
                +  border-top-color: #000;
                +}
                +.tooltip.top-right .tooltip-arrow {
                +  bottom: 0;
                +  left: 5px;
                +  margin-bottom: -5px;
                +  border-width: 5px 5px 0;
                +  border-top-color: #000;
                +}
                +.tooltip.right .tooltip-arrow {
                +  top: 50%;
                +  left: 0;
                +  margin-top: -5px;
                +  border-width: 5px 5px 5px 0;
                +  border-right-color: #000;
                +}
                +.tooltip.left .tooltip-arrow {
                +  top: 50%;
                +  right: 0;
                +  margin-top: -5px;
                +  border-width: 5px 0 5px 5px;
                +  border-left-color: #000;
                +}
                +.tooltip.bottom .tooltip-arrow {
                +  top: 0;
                +  left: 50%;
                +  margin-left: -5px;
                +  border-width: 0 5px 5px;
                +  border-bottom-color: #000;
                +}
                +.tooltip.bottom-left .tooltip-arrow {
                +  top: 0;
                +  right: 5px;
                +  margin-top: -5px;
                +  border-width: 0 5px 5px;
                +  border-bottom-color: #000;
                +}
                +.tooltip.bottom-right .tooltip-arrow {
                +  top: 0;
                +  left: 5px;
                +  margin-top: -5px;
                +  border-width: 0 5px 5px;
                +  border-bottom-color: #000;
                +}
                +.popover {
                +  position: absolute;
                +  top: 0;
                +  left: 0;
                +  z-index: 1060;
                +  display: none;
                +  max-width: 276px;
                +  padding: 1px;
                +  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                +  font-size: 14px;
                +  font-style: normal;
                +  font-weight: normal;
                +  line-height: 1.42857143;
                +  text-align: left;
                +  text-align: start;
                +  text-decoration: none;
                +  text-shadow: none;
                +  text-transform: none;
                +  letter-spacing: normal;
                +  word-break: normal;
                +  word-spacing: normal;
                +  word-wrap: normal;
                +  white-space: normal;
                +  background-color: #fff;
                +  -webkit-background-clip: padding-box;
                +          background-clip: padding-box;
                +  border: 1px solid #ccc;
                +  border: 1px solid rgba(0, 0, 0, .2);
                +  border-radius: 6px;
                +  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
                +          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
                +
                +  line-break: auto;
                +}
                +.popover.top {
                +  margin-top: -10px;
                +}
                +.popover.right {
                +  margin-left: 10px;
                +}
                +.popover.bottom {
                +  margin-top: 10px;
                +}
                +.popover.left {
                +  margin-left: -10px;
                +}
                +.popover-title {
                +  padding: 8px 14px;
                +  margin: 0;
                +  font-size: 14px;
                +  background-color: #f7f7f7;
                +  border-bottom: 1px solid #ebebeb;
                +  border-radius: 5px 5px 0 0;
                +}
                +.popover-content {
                +  padding: 9px 14px;
                +}
                +.popover > .arrow,
                +.popover > .arrow:after {
                +  position: absolute;
                +  display: block;
                +  width: 0;
                +  height: 0;
                +  border-color: transparent;
                +  border-style: solid;
                +}
                +.popover > .arrow {
                +  border-width: 11px;
                +}
                +.popover > .arrow:after {
                +  content: "";
                +  border-width: 10px;
                +}
                +.popover.top > .arrow {
                +  bottom: -11px;
                +  left: 50%;
                +  margin-left: -11px;
                +  border-top-color: #999;
                +  border-top-color: rgba(0, 0, 0, .25);
                +  border-bottom-width: 0;
                +}
                +.popover.top > .arrow:after {
                +  bottom: 1px;
                +  margin-left: -10px;
                +  content: " ";
                +  border-top-color: #fff;
                +  border-bottom-width: 0;
                +}
                +.popover.right > .arrow {
                +  top: 50%;
                +  left: -11px;
                +  margin-top: -11px;
                +  border-right-color: #999;
                +  border-right-color: rgba(0, 0, 0, .25);
                +  border-left-width: 0;
                +}
                +.popover.right > .arrow:after {
                +  bottom: -10px;
                +  left: 1px;
                +  content: " ";
                +  border-right-color: #fff;
                +  border-left-width: 0;
                +}
                +.popover.bottom > .arrow {
                +  top: -11px;
                +  left: 50%;
                +  margin-left: -11px;
                +  border-top-width: 0;
                +  border-bottom-color: #999;
                +  border-bottom-color: rgba(0, 0, 0, .25);
                +}
                +.popover.bottom > .arrow:after {
                +  top: 1px;
                +  margin-left: -10px;
                +  content: " ";
                +  border-top-width: 0;
                +  border-bottom-color: #fff;
                +}
                +.popover.left > .arrow {
                +  top: 50%;
                +  right: -11px;
                +  margin-top: -11px;
                +  border-right-width: 0;
                +  border-left-color: #999;
                +  border-left-color: rgba(0, 0, 0, .25);
                +}
                +.popover.left > .arrow:after {
                +  right: 1px;
                +  bottom: -10px;
                +  content: " ";
                +  border-right-width: 0;
                +  border-left-color: #fff;
                +}
                +.carousel {
                +  position: relative;
                +}
                +.carousel-inner {
                +  position: relative;
                +  width: 100%;
                +  overflow: hidden;
                +}
                +.carousel-inner > .item {
                +  position: relative;
                +  display: none;
                +  -webkit-transition: .6s ease-in-out left;
                +       -o-transition: .6s ease-in-out left;
                +          transition: .6s ease-in-out left;
                +}
                +.carousel-inner > .item > img,
                +.carousel-inner > .item > a > img {
                +  line-height: 1;
                +}
                +@media all and (transform-3d), (-webkit-transform-3d) {
                +  .carousel-inner > .item {
                +    -webkit-transition: -webkit-transform .6s ease-in-out;
                +         -o-transition:      -o-transform .6s ease-in-out;
                +            transition:         transform .6s ease-in-out;
                +
                +    -webkit-backface-visibility: hidden;
                +            backface-visibility: hidden;
                +    -webkit-perspective: 1000px;
                +            perspective: 1000px;
                +  }
                +  .carousel-inner > .item.next,
                +  .carousel-inner > .item.active.right {
                +    left: 0;
                +    -webkit-transform: translate3d(100%, 0, 0);
                +            transform: translate3d(100%, 0, 0);
                +  }
                +  .carousel-inner > .item.prev,
                +  .carousel-inner > .item.active.left {
                +    left: 0;
                +    -webkit-transform: translate3d(-100%, 0, 0);
                +            transform: translate3d(-100%, 0, 0);
                +  }
                +  .carousel-inner > .item.next.left,
                +  .carousel-inner > .item.prev.right,
                +  .carousel-inner > .item.active {
                +    left: 0;
                +    -webkit-transform: translate3d(0, 0, 0);
                +            transform: translate3d(0, 0, 0);
                +  }
                +}
                +.carousel-inner > .active,
                +.carousel-inner > .next,
                +.carousel-inner > .prev {
                +  display: block;
                +}
                +.carousel-inner > .active {
                +  left: 0;
                +}
                +.carousel-inner > .next,
                +.carousel-inner > .prev {
                +  position: absolute;
                +  top: 0;
                +  width: 100%;
                +}
                +.carousel-inner > .next {
                +  left: 100%;
                +}
                +.carousel-inner > .prev {
                +  left: -100%;
                +}
                +.carousel-inner > .next.left,
                +.carousel-inner > .prev.right {
                +  left: 0;
                +}
                +.carousel-inner > .active.left {
                +  left: -100%;
                +}
                +.carousel-inner > .active.right {
                +  left: 100%;
                +}
                +.carousel-control {
                +  position: absolute;
                +  top: 0;
                +  bottom: 0;
                +  left: 0;
                +  width: 15%;
                +  font-size: 20px;
                +  color: #fff;
                +  text-align: center;
                +  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
                +  background-color: rgba(0, 0, 0, 0);
                +  filter: alpha(opacity=50);
                +  opacity: .5;
                +}
                +.carousel-control.left {
                +  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
                +  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
                +  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
                +  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
                +  background-repeat: repeat-x;
                +}
                +.carousel-control.right {
                +  right: 0;
                +  left: auto;
                +  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
                +  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
                +  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
                +  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
                +  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
                +  background-repeat: repeat-x;
                +}
                +.carousel-control:hover,
                +.carousel-control:focus {
                +  color: #fff;
                +  text-decoration: none;
                +  filter: alpha(opacity=90);
                +  outline: 0;
                +  opacity: .9;
                +}
                +.carousel-control .icon-prev,
                +.carousel-control .icon-next,
                +.carousel-control .glyphicon-chevron-left,
                +.carousel-control .glyphicon-chevron-right {
                +  position: absolute;
                +  top: 50%;
                +  z-index: 5;
                +  display: inline-block;
                +  margin-top: -10px;
                +}
                +.carousel-control .icon-prev,
                +.carousel-control .glyphicon-chevron-left {
                +  left: 50%;
                +  margin-left: -10px;
                +}
                +.carousel-control .icon-next,
                +.carousel-control .glyphicon-chevron-right {
                +  right: 50%;
                +  margin-right: -10px;
                +}
                +.carousel-control .icon-prev,
                +.carousel-control .icon-next {
                +  width: 20px;
                +  height: 20px;
                +  font-family: serif;
                +  line-height: 1;
                +}
                +.carousel-control .icon-prev:before {
                +  content: '\2039';
                +}
                +.carousel-control .icon-next:before {
                +  content: '\203a';
                +}
                +.carousel-indicators {
                +  position: absolute;
                +  bottom: 10px;
                +  left: 50%;
                +  z-index: 15;
                +  width: 60%;
                +  padding-left: 0;
                +  margin-left: -30%;
                +  text-align: center;
                +  list-style: none;
                +}
                +.carousel-indicators li {
                +  display: inline-block;
                +  width: 10px;
                +  height: 10px;
                +  margin: 1px;
                +  text-indent: -999px;
                +  cursor: pointer;
                +  background-color: #000 \9;
                +  background-color: rgba(0, 0, 0, 0);
                +  border: 1px solid #fff;
                +  border-radius: 10px;
                +}
                +.carousel-indicators .active {
                +  width: 12px;
                +  height: 12px;
                +  margin: 0;
                +  background-color: #fff;
                +}
                +.carousel-caption {
                +  position: absolute;
                +  right: 15%;
                +  bottom: 20px;
                +  left: 15%;
                +  z-index: 10;
                +  padding-top: 20px;
                +  padding-bottom: 20px;
                +  color: #fff;
                +  text-align: center;
                +  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
                +}
                +.carousel-caption .btn {
                +  text-shadow: none;
                +}
                +@media screen and (min-width: 768px) {
                +  .carousel-control .glyphicon-chevron-left,
                +  .carousel-control .glyphicon-chevron-right,
                +  .carousel-control .icon-prev,
                +  .carousel-control .icon-next {
                +    width: 30px;
                +    height: 30px;
                +    margin-top: -10px;
                +    font-size: 30px;
                +  }
                +  .carousel-control .glyphicon-chevron-left,
                +  .carousel-control .icon-prev {
                +    margin-left: -10px;
                +  }
                +  .carousel-control .glyphicon-chevron-right,
                +  .carousel-control .icon-next {
                +    margin-right: -10px;
                +  }
                +  .carousel-caption {
                +    right: 20%;
                +    left: 20%;
                +    padding-bottom: 30px;
                +  }
                +  .carousel-indicators {
                +    bottom: 20px;
                +  }
                +}
                +.clearfix:before,
                +.clearfix:after,
                +.dl-horizontal dd:before,
                +.dl-horizontal dd:after,
                +.container:before,
                +.container:after,
                +.container-fluid:before,
                +.container-fluid:after,
                +.row:before,
                +.row:after,
                +.form-horizontal .form-group:before,
                +.form-horizontal .form-group:after,
                +.btn-toolbar:before,
                +.btn-toolbar:after,
                +.btn-group-vertical > .btn-group:before,
                +.btn-group-vertical > .btn-group:after,
                +.nav:before,
                +.nav:after,
                +.navbar:before,
                +.navbar:after,
                +.navbar-header:before,
                +.navbar-header:after,
                +.navbar-collapse:before,
                +.navbar-collapse:after,
                +.pager:before,
                +.pager:after,
                +.panel-body:before,
                +.panel-body:after,
                +.modal-header:before,
                +.modal-header:after,
                +.modal-footer:before,
                +.modal-footer:after {
                +  display: table;
                +  content: " ";
                +}
                +.clearfix:after,
                +.dl-horizontal dd:after,
                +.container:after,
                +.container-fluid:after,
                +.row:after,
                +.form-horizontal .form-group:after,
                +.btn-toolbar:after,
                +.btn-group-vertical > .btn-group:after,
                +.nav:after,
                +.navbar:after,
                +.navbar-header:after,
                +.navbar-collapse:after,
                +.pager:after,
                +.panel-body:after,
                +.modal-header:after,
                +.modal-footer:after {
                +  clear: both;
                +}
                +.center-block {
                +  display: block;
                +  margin-right: auto;
                +  margin-left: auto;
                +}
                +.pull-right {
                +  float: right !important;
                +}
                +.pull-left {
                +  float: left !important;
                +}
                +.hide {
                +  display: none !important;
                +}
                +.show {
                +  display: block !important;
                +}
                +.invisible {
                +  visibility: hidden;
                +}
                +.text-hide {
                +  font: 0/0 a;
                +  color: transparent;
                +  text-shadow: none;
                +  background-color: transparent;
                +  border: 0;
                +}
                +.hidden {
                +  display: none !important;
                +}
                +.affix {
                +  position: fixed;
                +}
                +@-ms-viewport {
                +  width: device-width;
                +}
                +.visible-xs,
                +.visible-sm,
                +.visible-md,
                +.visible-lg {
                +  display: none !important;
                +}
                +.visible-xs-block,
                +.visible-xs-inline,
                +.visible-xs-inline-block,
                +.visible-sm-block,
                +.visible-sm-inline,
                +.visible-sm-inline-block,
                +.visible-md-block,
                +.visible-md-inline,
                +.visible-md-inline-block,
                +.visible-lg-block,
                +.visible-lg-inline,
                +.visible-lg-inline-block {
                +  display: none !important;
                +}
                +@media (max-width: 767px) {
                +  .visible-xs {
                +    display: block !important;
                +  }
                +  table.visible-xs {
                +    display: table !important;
                +  }
                +  tr.visible-xs {
                +    display: table-row !important;
                +  }
                +  th.visible-xs,
                +  td.visible-xs {
                +    display: table-cell !important;
                +  }
                +}
                +@media (max-width: 767px) {
                +  .visible-xs-block {
                +    display: block !important;
                +  }
                +}
                +@media (max-width: 767px) {
                +  .visible-xs-inline {
                +    display: inline !important;
                +  }
                +}
                +@media (max-width: 767px) {
                +  .visible-xs-inline-block {
                +    display: inline-block !important;
                +  }
                +}
                +@media (min-width: 768px) and (max-width: 991px) {
                +  .visible-sm {
                +    display: block !important;
                +  }
                +  table.visible-sm {
                +    display: table !important;
                +  }
                +  tr.visible-sm {
                +    display: table-row !important;
                +  }
                +  th.visible-sm,
                +  td.visible-sm {
                +    display: table-cell !important;
                +  }
                +}
                +@media (min-width: 768px) and (max-width: 991px) {
                +  .visible-sm-block {
                +    display: block !important;
                +  }
                +}
                +@media (min-width: 768px) and (max-width: 991px) {
                +  .visible-sm-inline {
                +    display: inline !important;
                +  }
                +}
                +@media (min-width: 768px) and (max-width: 991px) {
                +  .visible-sm-inline-block {
                +    display: inline-block !important;
                +  }
                +}
                +@media (min-width: 992px) and (max-width: 1199px) {
                +  .visible-md {
                +    display: block !important;
                +  }
                +  table.visible-md {
                +    display: table !important;
                +  }
                +  tr.visible-md {
                +    display: table-row !important;
                +  }
                +  th.visible-md,
                +  td.visible-md {
                +    display: table-cell !important;
                +  }
                +}
                +@media (min-width: 992px) and (max-width: 1199px) {
                +  .visible-md-block {
                +    display: block !important;
                +  }
                +}
                +@media (min-width: 992px) and (max-width: 1199px) {
                +  .visible-md-inline {
                +    display: inline !important;
                +  }
                +}
                +@media (min-width: 992px) and (max-width: 1199px) {
                +  .visible-md-inline-block {
                +    display: inline-block !important;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .visible-lg {
                +    display: block !important;
                +  }
                +  table.visible-lg {
                +    display: table !important;
                +  }
                +  tr.visible-lg {
                +    display: table-row !important;
                +  }
                +  th.visible-lg,
                +  td.visible-lg {
                +    display: table-cell !important;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .visible-lg-block {
                +    display: block !important;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .visible-lg-inline {
                +    display: inline !important;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .visible-lg-inline-block {
                +    display: inline-block !important;
                +  }
                +}
                +@media (max-width: 767px) {
                +  .hidden-xs {
                +    display: none !important;
                +  }
                +}
                +@media (min-width: 768px) and (max-width: 991px) {
                +  .hidden-sm {
                +    display: none !important;
                +  }
                +}
                +@media (min-width: 992px) and (max-width: 1199px) {
                +  .hidden-md {
                +    display: none !important;
                +  }
                +}
                +@media (min-width: 1200px) {
                +  .hidden-lg {
                +    display: none !important;
                +  }
                +}
                +.visible-print {
                +  display: none !important;
                +}
                +@media print {
                +  .visible-print {
                +    display: block !important;
                +  }
                +  table.visible-print {
                +    display: table !important;
                +  }
                +  tr.visible-print {
                +    display: table-row !important;
                +  }
                +  th.visible-print,
                +  td.visible-print {
                +    display: table-cell !important;
                +  }
                +}
                +.visible-print-block {
                +  display: none !important;
                +}
                +@media print {
                +  .visible-print-block {
                +    display: block !important;
                +  }
                +}
                +.visible-print-inline {
                +  display: none !important;
                +}
                +@media print {
                +  .visible-print-inline {
                +    display: inline !important;
                +  }
                +}
                +.visible-print-inline-block {
                +  display: none !important;
                +}
                +@media print {
                +  .visible-print-inline-block {
                +    display: inline-block !important;
                +  }
                +}
                +@media print {
                +  .hidden-print {
                +    display: none !important;
                +  }
                +}
                +/*# sourceMappingURL=bootstrap.css.map */
                diff --git a/blockly/webif/static/css/bootstrap.css.map b/blockly/webif/static/css/bootstrap.css.map
                new file mode 100644
                index 000000000..f010c82d1
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap.css.map
                @@ -0,0 +1 @@
                +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,4EAA4E;ACG5E;EACE,wBAAA;EACA,2BAAA;EACA,+BAAA;CDDD;ACQD;EACE,UAAA;CDND;ACmBD;;;;;;;;;;;;;EAaE,eAAA;CDjBD;ACyBD;;;;EAIE,sBAAA;EACA,yBAAA;CDvBD;AC+BD;EACE,cAAA;EACA,UAAA;CD7BD;ACqCD;;EAEE,cAAA;CDnCD;AC6CD;EACE,8BAAA;CD3CD;ACmDD;;EAEE,WAAA;CDjDD;AC2DD;EACE,0BAAA;CDzDD;ACgED;;EAEE,kBAAA;CD9DD;ACqED;EACE,mBAAA;CDnED;AC2ED;EACE,eAAA;EACA,iBAAA;CDzED;ACgFD;EACE,iBAAA;EACA,YAAA;CD9ED;ACqFD;EACE,eAAA;CDnFD;AC0FD;;EAEE,eAAA;EACA,eAAA;EACA,mBAAA;EACA,yBAAA;CDxFD;AC2FD;EACE,YAAA;CDzFD;AC4FD;EACE,gBAAA;CD1FD;ACoGD;EACE,UAAA;CDlGD;ACyGD;EACE,iBAAA;CDvGD;ACiHD;EACE,iBAAA;CD/GD;ACsHD;EACE,gCAAA;KAAA,6BAAA;UAAA,wBAAA;EACA,UAAA;CDpHD;AC2HD;EACE,eAAA;CDzHD;ACgID;;;;EAIE,kCAAA;EACA,eAAA;CD9HD;ACgJD;;;;;EAKE,eAAA;EACA,cAAA;EACA,UAAA;CD9ID;ACqJD;EACE,kBAAA;CDnJD;AC6JD;;EAEE,qBAAA;CD3JD;ACsKD;;;;EAIE,2BAAA;EACA,gBAAA;CDpKD;AC2KD;;EAEE,gBAAA;CDzKD;ACgLD;;EAEE,UAAA;EACA,WAAA;CD9KD;ACsLD;EACE,oBAAA;CDpLD;AC+LD;;EAEE,+BAAA;KAAA,4BAAA;UAAA,uBAAA;EACA,WAAA;CD7LD;ACsMD;;EAEE,aAAA;CDpMD;AC4MD;EACE,8BAAA;EACA,gCAAA;KAAA,6BAAA;UAAA,wBAAA;CD1MD;ACmND;;EAEE,yBAAA;CDjND;ACwND;EACE,0BAAA;EACA,cAAA;EACA,+BAAA;CDtND;AC8ND;EACE,UAAA;EACA,WAAA;CD5ND;ACmOD;EACE,eAAA;CDjOD;ACyOD;EACE,kBAAA;CDvOD;ACiPD;EACE,0BAAA;EACA,kBAAA;CD/OD;ACkPD;;EAEE,WAAA;CDhPD;AACD,qFAAqF;AElFrF;EA7FI;;;IAGI,mCAAA;IACA,uBAAA;IACA,oCAAA;YAAA,4BAAA;IACA,6BAAA;GFkLL;EE/KC;;IAEI,2BAAA;GFiLL;EE9KC;IACI,6BAAA;GFgLL;EE7KC;IACI,8BAAA;GF+KL;EE1KC;;IAEI,YAAA;GF4KL;EEzKC;;IAEI,uBAAA;IACA,yBAAA;GF2KL;EExKC;IACI,4BAAA;GF0KL;EEvKC;;IAEI,yBAAA;GFyKL;EEtKC;IACI,2BAAA;GFwKL;EErKC;;;IAGI,WAAA;IACA,UAAA;GFuKL;EEpKC;;IAEI,wBAAA;GFsKL;EEhKC;IACI,cAAA;GFkKL;EEhKC;;IAGQ,kCAAA;GFiKT;EE9JC;IACI,uBAAA;GFgKL;EE7JC;IACI,qCAAA;GF+JL;EEhKC;;IAKQ,kCAAA;GF+JT;EE5JC;;IAGQ,kCAAA;GF6JT;CACF;AGnPD;EACE,oCAAA;EACA,sDAAA;EACA,gYAAA;CHqPD;AG7OD;EACE,mBAAA;EACA,SAAA;EACA,sBAAA;EACA,oCAAA;EACA,mBAAA;EACA,oBAAA;EACA,eAAA;EACA,oCAAA;EACA,mCAAA;CH+OD;AG3OmC;EAAW,iBAAA;CH8O9C;AG7OmC;EAAW,iBAAA;CHgP9C;AG9OmC;;EAAW,iBAAA;CHkP9C;AGjPmC;EAAW,iBAAA;CHoP9C;AGnPmC;EAAW,iBAAA;CHsP9C;AGrPmC;EAAW,iBAAA;CHwP9C;AGvPmC;EAAW,iBAAA;CH0P9C;AGzPmC;EAAW,iBAAA;CH4P9C;AG3PmC;EAAW,iBAAA;CH8P9C;AG7PmC;EAAW,iBAAA;CHgQ9C;AG/PmC;EAAW,iBAAA;CHkQ9C;AGjQmC;EAAW,iBAAA;CHoQ9C;AGnQmC;EAAW,iBAAA;CHsQ9C;AGrQmC;EAAW,iBAAA;CHwQ9C;AGvQmC;EAAW,iBAAA;CH0Q9C;AGzQmC;EAAW,iBAAA;CH4Q9C;AG3QmC;EAAW,iBAAA;CH8Q9C;AG7QmC;EAAW,iBAAA;CHgR9C;AG/QmC;EAAW,iBAAA;CHkR9C;AGjRmC;EAAW,iBAAA;CHoR9C;AGnRmC;EAAW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;EAAW,iBAAA;CH4tB9C;AG3tBmC;EAAW,iBAAA;CH8tB9C;AG7tBmC;EAAW,iBAAA;CHguB9C;AG/tBmC;EAAW,iBAAA;CHkuB9C;AGjuBmC;EAAW,iBAAA;CHouB9C;AGnuBmC;EAAW,iBAAA;CHsuB9C;AGruBmC;EAAW,iBAAA;CHwuB9C;AGvuBmC;EAAW,iBAAA;CH0uB9C;AGzuBmC;EAAW,iBAAA;CH4uB9C;AG3uBmC;EAAW,iBAAA;CH8uB9C;AG7uBmC;EAAW,iBAAA;CHgvB9C;AIthCD;ECgEE,+BAAA;EACG,4BAAA;EACK,uBAAA;CLy9BT;AIxhCD;;EC6DE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL+9BT;AIthCD;EACE,gBAAA;EACA,8CAAA;CJwhCD;AIrhCD;EACE,4DAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;CJuhCD;AInhCD;;;;EAIE,qBAAA;EACA,mBAAA;EACA,qBAAA;CJqhCD;AI/gCD;EACE,eAAA;EACA,sBAAA;CJihCD;AI/gCC;;EAEE,eAAA;EACA,2BAAA;CJihCH;AI9gCC;EEnDA,2CAAA;EACA,qBAAA;CNokCD;AIvgCD;EACE,UAAA;CJygCD;AIngCD;EACE,uBAAA;CJqgCD;AIjgCD;;;;;EGvEE,eAAA;EACA,gBAAA;EACA,aAAA;CP+kCD;AIrgCD;EACE,mBAAA;CJugCD;AIjgCD;EACE,aAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EC6FA,yCAAA;EACK,oCAAA;EACG,iCAAA;EEvLR,sBAAA;EACA,gBAAA;EACA,aAAA;CP+lCD;AIjgCD;EACE,mBAAA;CJmgCD;AI7/BD;EACE,iBAAA;EACA,oBAAA;EACA,UAAA;EACA,8BAAA;CJ+/BD;AIv/BD;EACE,mBAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,WAAA;EACA,iBAAA;EACA,uBAAA;EACA,UAAA;CJy/BD;AIj/BC;;EAEE,iBAAA;EACA,YAAA;EACA,aAAA;EACA,UAAA;EACA,kBAAA;EACA,WAAA;CJm/BH;AIx+BD;EACE,gBAAA;CJ0+BD;AQjoCD;;;;;;;;;;;;EAEE,qBAAA;EACA,iBAAA;EACA,iBAAA;EACA,eAAA;CR6oCD;AQlpCD;;;;;;;;;;;;;;;;;;;;;;;;EASI,oBAAA;EACA,eAAA;EACA,eAAA;CRmqCH;AQ/pCD;;;;;;EAGE,iBAAA;EACA,oBAAA;CRoqCD;AQxqCD;;;;;;;;;;;;EAQI,eAAA;CR8qCH;AQ3qCD;;;;;;EAGE,iBAAA;EACA,oBAAA;CRgrCD;AQprCD;;;;;;;;;;;;EAQI,eAAA;CR0rCH;AQtrCD;;EAAU,gBAAA;CR0rCT;AQzrCD;;EAAU,gBAAA;CR6rCT;AQ5rCD;;EAAU,gBAAA;CRgsCT;AQ/rCD;;EAAU,gBAAA;CRmsCT;AQlsCD;;EAAU,gBAAA;CRssCT;AQrsCD;;EAAU,gBAAA;CRysCT;AQnsCD;EACE,iBAAA;CRqsCD;AQlsCD;EACE,oBAAA;EACA,gBAAA;EACA,iBAAA;EACA,iBAAA;CRosCD;AQ/rCD;EAwOA;IA1OI,gBAAA;GRqsCD;CACF;AQ7rCD;;EAEE,eAAA;CR+rCD;AQ5rCD;;EAEE,0BAAA;EACA,cAAA;CR8rCD;AQ1rCD;EAAuB,iBAAA;CR6rCtB;AQ5rCD;EAAuB,kBAAA;CR+rCtB;AQ9rCD;EAAuB,mBAAA;CRisCtB;AQhsCD;EAAuB,oBAAA;CRmsCtB;AQlsCD;EAAuB,oBAAA;CRqsCtB;AQlsCD;EAAuB,0BAAA;CRqsCtB;AQpsCD;EAAuB,0BAAA;CRusCtB;AQtsCD;EAAuB,2BAAA;CRysCtB;AQtsCD;EACE,eAAA;CRwsCD;AQtsCD;ECrGE,eAAA;CT8yCD;AS7yCC;;EAEE,eAAA;CT+yCH;AQ1sCD;ECxGE,eAAA;CTqzCD;ASpzCC;;EAEE,eAAA;CTszCH;AQ9sCD;EC3GE,eAAA;CT4zCD;AS3zCC;;EAEE,eAAA;CT6zCH;AQltCD;EC9GE,eAAA;CTm0CD;ASl0CC;;EAEE,eAAA;CTo0CH;AQttCD;ECjHE,eAAA;CT00CD;ASz0CC;;EAEE,eAAA;CT20CH;AQttCD;EAGE,YAAA;EE3HA,0BAAA;CVk1CD;AUj1CC;;EAEE,0BAAA;CVm1CH;AQxtCD;EE9HE,0BAAA;CVy1CD;AUx1CC;;EAEE,0BAAA;CV01CH;AQ5tCD;EEjIE,0BAAA;CVg2CD;AU/1CC;;EAEE,0BAAA;CVi2CH;AQhuCD;EEpIE,0BAAA;CVu2CD;AUt2CC;;EAEE,0BAAA;CVw2CH;AQpuCD;EEvIE,0BAAA;CV82CD;AU72CC;;EAEE,0BAAA;CV+2CH;AQnuCD;EACE,oBAAA;EACA,oBAAA;EACA,iCAAA;CRquCD;AQ7tCD;;EAEE,cAAA;EACA,oBAAA;CR+tCD;AQluCD;;;;EAMI,iBAAA;CRkuCH;AQ3tCD;EACE,gBAAA;EACA,iBAAA;CR6tCD;AQztCD;EALE,gBAAA;EACA,iBAAA;EAMA,kBAAA;CR4tCD;AQ9tCD;EAKI,sBAAA;EACA,kBAAA;EACA,mBAAA;CR4tCH;AQvtCD;EACE,cAAA;EACA,oBAAA;CRytCD;AQvtCD;;EAEE,wBAAA;CRytCD;AQvtCD;EACE,kBAAA;CRytCD;AQvtCD;EACE,eAAA;CRytCD;AQhsCD;EA6EA;IAvFM,YAAA;IACA,aAAA;IACA,YAAA;IACA,kBAAA;IGtNJ,iBAAA;IACA,wBAAA;IACA,oBAAA;GXq6CC;EQ7nCH;IAhFM,mBAAA;GRgtCH;CACF;AQvsCD;;EAGE,aAAA;EACA,kCAAA;CRwsCD;AQtsCD;EACE,eAAA;EA9IqB,0BAAA;CRu1CtB;AQpsCD;EACE,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,+BAAA;CRssCD;AQjsCG;;;EACE,iBAAA;CRqsCL;AQ/sCD;;;EAmBI,eAAA;EACA,eAAA;EACA,wBAAA;EACA,eAAA;CRisCH;AQ/rCG;;;EACE,uBAAA;CRmsCL;AQ3rCD;;EAEE,oBAAA;EACA,gBAAA;EACA,gCAAA;EACA,eAAA;EACA,kBAAA;CR6rCD;AQvrCG;;;;;;EAAW,YAAA;CR+rCd;AQ9rCG;;;;;;EACE,uBAAA;CRqsCL;AQ/rCD;EACE,oBAAA;EACA,mBAAA;EACA,wBAAA;CRisCD;AYv+CD;;;;EAIE,+DAAA;CZy+CD;AYr+CD;EACE,iBAAA;EACA,eAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CZu+CD;AYn+CD;EACE,iBAAA;EACA,eAAA;EACA,YAAA;EACA,uBAAA;EACA,mBAAA;EACA,uDAAA;UAAA,+CAAA;CZq+CD;AY3+CD;EASI,WAAA;EACA,gBAAA;EACA,kBAAA;EACA,yBAAA;UAAA,iBAAA;CZq+CH;AYh+CD;EACE,eAAA;EACA,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,sBAAA;EACA,sBAAA;EACA,eAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;CZk+CD;AY7+CD;EAeI,WAAA;EACA,mBAAA;EACA,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,iBAAA;CZi+CH;AY59CD;EACE,kBAAA;EACA,mBAAA;CZ89CD;AaxhDD;ECHE,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,oBAAA;Cd8hDD;AaxhDC;EAqEF;IAvEI,aAAA;Gb8hDD;CACF;Aa1hDC;EAkEF;IApEI,aAAA;GbgiDD;CACF;Aa5hDD;EA+DA;IAjEI,cAAA;GbkiDD;CACF;AazhDD;ECvBE,mBAAA;EACA,kBAAA;EACA,mBAAA;EACA,oBAAA;CdmjDD;AathDD;ECvBE,mBAAA;EACA,oBAAA;CdgjDD;AehjDG;EACE,mBAAA;EAEA,gBAAA;EAEA,mBAAA;EACA,oBAAA;CfgjDL;AehiDG;EACE,YAAA;CfkiDL;Ae3hDC;EACE,YAAA;Cf6hDH;Ae9hDC;EACE,oBAAA;CfgiDH;AejiDC;EACE,oBAAA;CfmiDH;AepiDC;EACE,WAAA;CfsiDH;AeviDC;EACE,oBAAA;CfyiDH;Ae1iDC;EACE,oBAAA;Cf4iDH;Ae7iDC;EACE,WAAA;Cf+iDH;AehjDC;EACE,oBAAA;CfkjDH;AenjDC;EACE,oBAAA;CfqjDH;AetjDC;EACE,WAAA;CfwjDH;AezjDC;EACE,oBAAA;Cf2jDH;Ae5jDC;EACE,mBAAA;Cf8jDH;AehjDC;EACE,YAAA;CfkjDH;AenjDC;EACE,oBAAA;CfqjDH;AetjDC;EACE,oBAAA;CfwjDH;AezjDC;EACE,WAAA;Cf2jDH;Ae5jDC;EACE,oBAAA;Cf8jDH;Ae/jDC;EACE,oBAAA;CfikDH;AelkDC;EACE,WAAA;CfokDH;AerkDC;EACE,oBAAA;CfukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBAAA;EACA,oBAAA;ChBqrED;AgBxrED;;;;;;EAWQ,aAAA;EACA,wBAAA;EACA,oBAAA;EACA,2BAAA;ChBqrEP;AgBnsED;EAoBI,uBAAA;EACA,8BAAA;ChBkrEH;AgBvsED;;;;;;EA8BQ,cAAA;ChBirEP;AgB/sED;EAoCI,2BAAA;ChB8qEH;AgBltED;EAyCI,uBAAA;ChB4qEH;AgBrqED;;;;;;EAOQ,aAAA;ChBsqEP;AgB3pED;EACE,uBAAA;ChB6pED;AgB9pED;;;;;;EAQQ,uBAAA;ChB8pEP;AgBtqED;;EAeM,yBAAA;ChB2pEL;AgBjpED;EAEI,0BAAA;ChBkpEH;AgBzoED;EAEI,0BAAA;ChB0oEH;AgBjoED;EACE,iBAAA;EACA,YAAA;EACA,sBAAA;ChBmoED;AgB9nEG;;EACE,iBAAA;EACA,YAAA;EACA,oBAAA;ChBioEL;AiB7wEC;;;;;;;;;;;;EAOI,0BAAA;CjBoxEL;AiB9wEC;;;;;EAMI,0BAAA;CjB+wEL;AiBlyEC;;;;;;;;;;;;EAOI,0BAAA;CjByyEL;AiBnyEC;;;;;EAMI,0BAAA;CjBoyEL;AiBvzEC;;;;;;;;;;;;EAOI,0BAAA;CjB8zEL;AiBxzEC;;;;;EAMI,0BAAA;CjByzEL;AiB50EC;;;;;;;;;;;;EAOI,0BAAA;CjBm1EL;AiB70EC;;;;;EAMI,0BAAA;CjB80EL;AiBj2EC;;;;;;;;;;;;EAOI,0BAAA;CjBw2EL;AiBl2EC;;;;;EAMI,0BAAA;CjBm2EL;AgBjtED;EACE,iBAAA;EACA,kBAAA;ChBmtED;AgBtpED;EACA;IA3DI,YAAA;IACA,oBAAA;IACA,mBAAA;IACA,6CAAA;IACA,uBAAA;GhBotED;EgB7pEH;IAnDM,iBAAA;GhBmtEH;EgBhqEH;;;;;;IA1CY,oBAAA;GhBktET;EgBxqEH;IAlCM,UAAA;GhB6sEH;EgB3qEH;;;;;;IAzBY,eAAA;GhB4sET;EgBnrEH;;;;;;IArBY,gBAAA;GhBgtET;EgB3rEH;;;;IARY,iBAAA;GhBysET;CACF;AkBn6ED;EACE,WAAA;EACA,UAAA;EACA,UAAA;EAIA,aAAA;ClBk6ED;AkB/5ED;EACE,eAAA;EACA,YAAA;EACA,WAAA;EACA,oBAAA;EACA,gBAAA;EACA,qBAAA;EACA,eAAA;EACA,UAAA;EACA,iCAAA;ClBi6ED;AkB95ED;EACE,sBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;ClBg6ED;AkBr5ED;Eb4BE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL43ET;AkBr5ED;;EAEE,gBAAA;EACA,mBAAA;EACA,oBAAA;ClBu5ED;AkBp5ED;EACE,eAAA;ClBs5ED;AkBl5ED;EACE,eAAA;EACA,YAAA;ClBo5ED;AkBh5ED;;EAEE,aAAA;ClBk5ED;AkB94ED;;;EZrEE,2CAAA;EACA,qBAAA;CNw9ED;AkB74ED;EACE,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;ClB+4ED;AkBr3ED;EACE,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EbxDA,yDAAA;EACQ,iDAAA;EAyHR,uFAAA;EACK,0EAAA;EACG,uEAAA;CLwzET;AmBh8EC;EACE,sBAAA;EACA,WAAA;EdUF,uFAAA;EACQ,+EAAA;CLy7ET;AKx5EC;EACE,YAAA;EACA,WAAA;CL05EH;AKx5EC;EAA0B,YAAA;CL25E3B;AK15EC;EAAgC,YAAA;CL65EjC;AkBj4EC;EACE,UAAA;EACA,8BAAA;ClBm4EH;AkB33EC;;;EAGE,0BAAA;EACA,WAAA;ClB63EH;AkB13EC;;EAEE,oBAAA;ClB43EH;AkBx3EC;EACE,aAAA;ClB03EH;AkB92ED;EACE,yBAAA;ClBg3ED;AkBx0ED;EAtBI;;;;IACE,kBAAA;GlBo2EH;EkBj2EC;;;;;;;;IAEE,kBAAA;GlBy2EH;EkBt2EC;;;;;;;;IAEE,kBAAA;GlB82EH;CACF;AkBp2ED;EACE,oBAAA;ClBs2ED;AkB91ED;;EAEE,mBAAA;EACA,eAAA;EACA,iBAAA;EACA,oBAAA;ClBg2ED;AkBr2ED;;EAQI,iBAAA;EACA,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,gBAAA;ClBi2EH;AkB91ED;;;;EAIE,mBAAA;EACA,mBAAA;EACA,mBAAA;ClBg2ED;AkB71ED;;EAEE,iBAAA;ClB+1ED;AkB31ED;;EAEE,mBAAA;EACA,sBAAA;EACA,mBAAA;EACA,iBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;ClB61ED;AkB31ED;;EAEE,cAAA;EACA,kBAAA;ClB61ED;AkBp1EC;;;;;;EAGE,oBAAA;ClBy1EH;AkBn1EC;;;;EAEE,oBAAA;ClBu1EH;AkBj1EC;;;;EAGI,oBAAA;ClBo1EL;AkBz0ED;EAEE,iBAAA;EACA,oBAAA;EAEA,iBAAA;EACA,iBAAA;ClBy0ED;AkBv0EC;;EAEE,gBAAA;EACA,iBAAA;ClBy0EH;AkB5zED;ECnQE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnBkkFD;AmBhkFC;EACE,aAAA;EACA,kBAAA;CnBkkFH;AmB/jFC;;EAEE,aAAA;CnBikFH;AkBx0ED;EAEI,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;ClBy0EH;AkB/0ED;EASI,aAAA;EACA,kBAAA;ClBy0EH;AkBn1ED;;EAcI,aAAA;ClBy0EH;AkBv1ED;EAiBI,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;ClBy0EH;AkBr0ED;EC/RE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBumFD;AmBrmFC;EACE,aAAA;EACA,kBAAA;CnBumFH;AmBpmFC;;EAEE,aAAA;CnBsmFH;AkBj1ED;EAEI,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ClBk1EH;AkBx1ED;EASI,aAAA;EACA,kBAAA;ClBk1EH;AkB51ED;;EAcI,aAAA;ClBk1EH;AkBh2ED;EAiBI,aAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;ClBk1EH;AkBz0ED;EAEE,mBAAA;ClB00ED;AkB50ED;EAMI,sBAAA;ClBy0EH;AkBr0ED;EACE,mBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,mBAAA;EACA,qBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBn0ED;;;;;;;;;;EC1ZI,eAAA;CnByuFH;AkB/0ED;ECtZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CL0rFT;AmBxuFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL+rFT;AkBz1ED;EC5YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBwuFH;AkB91ED;ECtYI,eAAA;CnBuuFH;AkB91ED;;;;;;;;;;EC7ZI,eAAA;CnBuwFH;AkB12ED;ECzZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLwtFT;AmBtwFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL6tFT;AkBp3ED;EC/YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBswFH;AkBz3ED;ECzYI,eAAA;CnBqwFH;AkBz3ED;;;;;;;;;;EChaI,eAAA;CnBqyFH;AkBr4ED;EC5ZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLsvFT;AmBpyFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL2vFT;AkB/4ED;EClZI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBoyFH;AkBp5ED;EC5YI,eAAA;CnBmyFH;AkBh5EC;EACE,UAAA;ClBk5EH;AkBh5EC;EACE,OAAA;ClBk5EH;AkBx4ED;EACE,eAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;ClB04ED;AkBvzED;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBy3EH;EkBrvEH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBu3EH;EkB1vEH;IAxHM,sBAAA;GlBq3EH;EkB7vEH;IApHM,sBAAA;IACA,uBAAA;GlBo3EH;EkBjwEH;;;IA9GQ,YAAA;GlBo3EL;EkBtwEH;IAxGM,YAAA;GlBi3EH;EkBzwEH;IApGM,iBAAA;IACA,uBAAA;GlBg3EH;EkB7wEH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB62EH;EkBpxEH;;IAtFQ,gBAAA;GlB82EL;EkBxxEH;;IAjFM,mBAAA;IACA,eAAA;GlB62EH;EkB7xEH;IA3EM,OAAA;GlB22EH;CACF;AkBj2ED;;;;EASI,cAAA;EACA,iBAAA;EACA,iBAAA;ClB81EH;AkBz2ED;;EAiBI,iBAAA;ClB41EH;AkB72ED;EJthBE,mBAAA;EACA,oBAAA;Cds4FD;AkB10EC;EAyBF;IAnCM,kBAAA;IACA,iBAAA;IACA,iBAAA;GlBw1EH;CACF;AkBx3ED;EAwCI,YAAA;ClBm1EH;AkBr0EC;EAUF;IAdQ,kBAAA;IACA,gBAAA;GlB60EL;CACF;AkBn0EC;EAEF;IANQ,iBAAA;IACA,gBAAA;GlB20EL;CACF;AoBp6FD;EACE,sBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,uBAAA;EACA,+BAAA;MAAA,2BAAA;EACA,gBAAA;EACA,uBAAA;EACA,8BAAA;EACA,oBAAA;EC0CA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,mBAAA;EhB+JA,0BAAA;EACG,uBAAA;EACC,sBAAA;EACI,kBAAA;CL+tFT;AoBv6FG;;;;;;EdnBF,2CAAA;EACA,qBAAA;CNk8FD;AoB16FC;;;EAGE,YAAA;EACA,sBAAA;CpB46FH;AoBz6FC;;EAEE,WAAA;EACA,uBAAA;Ef2BF,yDAAA;EACQ,iDAAA;CLi5FT;AoBz6FC;;;EAGE,oBAAA;EE7CF,cAAA;EAGA,0BAAA;EjB8DA,yBAAA;EACQ,iBAAA;CL05FT;AoBz6FG;;EAEE,qBAAA;CpB26FL;AoBl6FD;EC3DE,YAAA;EACA,uBAAA;EACA,mBAAA;CrBg+FD;AqB99FC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBs+FT;AqBn+FC;;;EAGE,uBAAA;CrBq+FH;AqBh+FG;;;;;;;;;EAGE,uBAAA;EACI,mBAAA;CrBw+FT;AoBv9FD;ECZI,YAAA;EACA,uBAAA;CrBs+FH;AoBx9FD;EC9DE,YAAA;EACA,0BAAA;EACA,sBAAA;CrByhGD;AqBvhGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB+hGT;AqB5hGC;;;EAGE,uBAAA;CrB8hGH;AqBzhGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBiiGT;AoB7gGD;ECfI,eAAA;EACA,uBAAA;CrB+hGH;AoB7gGD;EClEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBklGD;AqBhlGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBwlGT;AqBrlGC;;;EAGE,uBAAA;CrBulGH;AqBllGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB0lGT;AoBlkGD;ECnBI,eAAA;EACA,uBAAA;CrBwlGH;AoBlkGD;ECtEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB2oGD;AqBzoGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBipGT;AqB9oGC;;;EAGE,uBAAA;CrBgpGH;AqB3oGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBmpGT;AoBvnGD;ECvBI,eAAA;EACA,uBAAA;CrBipGH;AoBvnGD;EC1EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBosGD;AqBlsGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB0sGT;AqBvsGC;;;EAGE,uBAAA;CrBysGH;AqBpsGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB4sGT;AoB5qGD;EC3BI,eAAA;EACA,uBAAA;CrB0sGH;AoB5qGD;EC9EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB6vGD;AqB3vGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBmwGT;AqBhwGC;;;EAGE,uBAAA;CrBkwGH;AqB7vGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBqwGT;AoBjuGD;EC/BI,eAAA;EACA,uBAAA;CrBmwGH;AoB5tGD;EACE,eAAA;EACA,oBAAA;EACA,iBAAA;CpB8tGD;AoB5tGC;;;;;EAKE,8BAAA;EfnCF,yBAAA;EACQ,iBAAA;CLkwGT;AoB7tGC;;;;EAIE,0BAAA;CpB+tGH;AoB7tGC;;EAEE,eAAA;EACA,2BAAA;EACA,8BAAA;CpB+tGH;AoB3tGG;;;;EAEE,eAAA;EACA,sBAAA;CpB+tGL;AoBttGD;;ECxEE,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CrBkyGD;AoBztGD;;EC5EE,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrByyGD;AoB5tGD;;EChFE,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrBgzGD;AoB3tGD;EACE,eAAA;EACA,YAAA;CpB6tGD;AoBztGD;EACE,gBAAA;CpB2tGD;AoBptGC;;;EACE,YAAA;CpBwtGH;AuBl3GD;EACE,WAAA;ElBoLA,yCAAA;EACK,oCAAA;EACG,iCAAA;CLisGT;AuBr3GC;EACE,WAAA;CvBu3GH;AuBn3GD;EACE,cAAA;CvBq3GD;AuBn3GC;EAAY,eAAA;CvBs3Gb;AuBr3GC;EAAY,mBAAA;CvBw3Gb;AuBv3GC;EAAY,yBAAA;CvB03Gb;AuBv3GD;EACE,mBAAA;EACA,UAAA;EACA,iBAAA;ElBuKA,gDAAA;EACQ,2CAAA;KAAA,wCAAA;EAOR,mCAAA;EACQ,8BAAA;KAAA,2BAAA;EAGR,yCAAA;EACQ,oCAAA;KAAA,iCAAA;CL2sGT;AwBr5GD;EACE,sBAAA;EACA,SAAA;EACA,UAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,yBAAA;EACA,oCAAA;EACA,mCAAA;CxBu5GD;AwBn5GD;;EAEE,mBAAA;CxBq5GD;AwBj5GD;EACE,WAAA;CxBm5GD;AwB/4GD;EACE,mBAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,sCAAA;EACA,mBAAA;EnBsBA,oDAAA;EACQ,4CAAA;EmBrBR,qCAAA;UAAA,6BAAA;CxBk5GD;AwB74GC;EACE,SAAA;EACA,WAAA;CxB+4GH;AwBx6GD;ECzBE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBo8GD;AwB96GD;EAmCI,eAAA;EACA,kBAAA;EACA,YAAA;EACA,oBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxB84GH;AwBx4GC;;EAEE,sBAAA;EACA,eAAA;EACA,0BAAA;CxB04GH;AwBp4GC;;;EAGE,YAAA;EACA,sBAAA;EACA,WAAA;EACA,0BAAA;CxBs4GH;AwB73GC;;;EAGE,eAAA;CxB+3GH;AwB33GC;;EAEE,sBAAA;EACA,8BAAA;EACA,uBAAA;EE3GF,oEAAA;EF6GE,oBAAA;CxB63GH;AwBx3GD;EAGI,eAAA;CxBw3GH;AwB33GD;EAQI,WAAA;CxBs3GH;AwB92GD;EACE,WAAA;EACA,SAAA;CxBg3GD;AwBx2GD;EACE,QAAA;EACA,YAAA;CxB02GD;AwBt2GD;EACE,eAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxBw2GD;AwBp2GD;EACE,gBAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,aAAA;CxBs2GD;AwBl2GD;EACE,SAAA;EACA,WAAA;CxBo2GD;AwB51GD;;EAII,cAAA;EACA,0BAAA;EACA,4BAAA;EACA,YAAA;CxB41GH;AwBn2GD;;EAWI,UAAA;EACA,aAAA;EACA,mBAAA;CxB41GH;AwBv0GD;EAXE;IApEA,WAAA;IACA,SAAA;GxB05GC;EwBv1GD;IA1DA,QAAA;IACA,YAAA;GxBo5GC;CACF;A2BpiHD;;EAEE,mBAAA;EACA,sBAAA;EACA,uBAAA;C3BsiHD;A2B1iHD;;EAMI,mBAAA;EACA,YAAA;C3BwiHH;A2BtiHG;;;;;;;;EAIE,WAAA;C3B4iHL;A2BtiHD;;;;EAKI,kBAAA;C3BuiHH;A2BliHD;EACE,kBAAA;C3BoiHD;A2BriHD;;;EAOI,YAAA;C3BmiHH;A2B1iHD;;;EAYI,iBAAA;C3BmiHH;A2B/hHD;EACE,iBAAA;C3BiiHD;A2B7hHD;EACE,eAAA;C3B+hHD;A2B9hHC;EClDA,8BAAA;EACG,2BAAA;C5BmlHJ;A2B7hHD;;EC/CE,6BAAA;EACG,0BAAA;C5BglHJ;A2B5hHD;EACE,YAAA;C3B8hHD;A2B5hHD;EACE,iBAAA;C3B8hHD;A2B5hHD;;ECnEE,8BAAA;EACG,2BAAA;C5BmmHJ;A2B3hHD;ECjEE,6BAAA;EACG,0BAAA;C5B+lHJ;A2B1hHD;;EAEE,WAAA;C3B4hHD;A2B3gHD;EACE,kBAAA;EACA,mBAAA;C3B6gHD;A2B3gHD;EACE,mBAAA;EACA,oBAAA;C3B6gHD;A2BxgHD;EtB/CE,yDAAA;EACQ,iDAAA;CL0jHT;A2BxgHC;EtBnDA,yBAAA;EACQ,iBAAA;CL8jHT;A2BrgHD;EACE,eAAA;C3BugHD;A2BpgHD;EACE,wBAAA;EACA,uBAAA;C3BsgHD;A2BngHD;EACE,wBAAA;C3BqgHD;A2B9/GD;;;EAII,eAAA;EACA,YAAA;EACA,YAAA;EACA,gBAAA;C3B+/GH;A2BtgHD;EAcM,YAAA;C3B2/GL;A2BzgHD;;;;EAsBI,iBAAA;EACA,eAAA;C3By/GH;A2Bp/GC;EACE,iBAAA;C3Bs/GH;A2Bp/GC;EC3KA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5B4pHF;A2Bt/GC;EC/KA,2BAAA;EACC,0BAAA;EAOD,gCAAA;EACC,+BAAA;C5BkqHF;A2Bv/GD;EACE,iBAAA;C3By/GD;A2Bv/GD;;EC/KE,8BAAA;EACC,6BAAA;C5B0qHF;A2Bt/GD;EC7LE,2BAAA;EACC,0BAAA;C5BsrHF;A2Bl/GD;EACE,eAAA;EACA,YAAA;EACA,oBAAA;EACA,0BAAA;C3Bo/GD;A2Bx/GD;;EAOI,YAAA;EACA,oBAAA;EACA,UAAA;C3Bq/GH;A2B9/GD;EAYI,YAAA;C3Bq/GH;A2BjgHD;EAgBI,WAAA;C3Bo/GH;A2Bn+GD;;;;EAKM,mBAAA;EACA,uBAAA;EACA,qBAAA;C3Bo+GL;A6B9sHD;EACE,mBAAA;EACA,eAAA;EACA,0BAAA;C7BgtHD;A6B7sHC;EACE,YAAA;EACA,gBAAA;EACA,iBAAA;C7B+sHH;A6BxtHD;EAeI,mBAAA;EACA,WAAA;EAKA,YAAA;EAEA,YAAA;EACA,iBAAA;C7BusHH;A6BrsHG;EACE,WAAA;C7BusHL;A6B7rHD;;;EV0BE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBwqHD;AmBtqHC;;;EACE,aAAA;EACA,kBAAA;CnB0qHH;AmBvqHC;;;;;;EAEE,aAAA;CnB6qHH;A6B/sHD;;;EVqBE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnB+rHD;AmB7rHC;;;EACE,aAAA;EACA,kBAAA;CnBisHH;AmB9rHC;;;;;;EAEE,aAAA;CnBosHH;A6B7tHD;;;EAGE,oBAAA;C7B+tHD;A6B7tHC;;;EACE,iBAAA;C7BiuHH;A6B7tHD;;EAEE,UAAA;EACA,oBAAA;EACA,uBAAA;C7B+tHD;A6B1tHD;EACE,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;EACA,eAAA;EACA,mBAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;C7B4tHD;A6BztHC;EACE,kBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6BztHC;EACE,mBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6B/uHD;;EA0BI,cAAA;C7BytHH;A6BptHD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;C5Bi0HJ;A6BrtHD;EACE,gBAAA;C7ButHD;A6BrtHD;;;;;;;EDxGE,6BAAA;EACG,0BAAA;C5Bs0HJ;A6BttHD;EACE,eAAA;C7BwtHD;A6BntHD;EACE,mBAAA;EAGA,aAAA;EACA,oBAAA;C7BmtHD;A6BxtHD;EAUI,mBAAA;C7BitHH;A6B3tHD;EAYM,kBAAA;C7BktHL;A6B/sHG;;;EAGE,WAAA;C7BitHL;A6B5sHC;;EAGI,mBAAA;C7B6sHL;A6B1sHC;;EAGI,WAAA;EACA,kBAAA;C7B2sHL;A8B12HD;EACE,iBAAA;EACA,gBAAA;EACA,iBAAA;C9B42HD;A8B/2HD;EAOI,mBAAA;EACA,eAAA;C9B22HH;A8Bn3HD;EAWM,mBAAA;EACA,eAAA;EACA,mBAAA;C9B22HL;A8B12HK;;EAEE,sBAAA;EACA,0BAAA;C9B42HP;A8Bv2HG;EACE,eAAA;C9By2HL;A8Bv2HK;;EAEE,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,oBAAA;C9By2HP;A8Bl2HG;;;EAGE,0BAAA;EACA,sBAAA;C9Bo2HL;A8B74HD;ELHE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBm5HD;A8Bn5HD;EA0DI,gBAAA;C9B41HH;A8Bn1HD;EACE,8BAAA;C9Bq1HD;A8Bt1HD;EAGI,YAAA;EAEA,oBAAA;C9Bq1HH;A8B11HD;EASM,kBAAA;EACA,wBAAA;EACA,8BAAA;EACA,2BAAA;C9Bo1HL;A8Bn1HK;EACE,mCAAA;C9Bq1HP;A8B/0HK;;;EAGE,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,iCAAA;EACA,gBAAA;C9Bi1HP;A8B50HC;EAqDA,YAAA;EA8BA,iBAAA;C9B6vHD;A8Bh1HC;EAwDE,YAAA;C9B2xHH;A8Bn1HC;EA0DI,mBAAA;EACA,mBAAA;C9B4xHL;A8Bv1HC;EAgEE,UAAA;EACA,WAAA;C9B0xHH;A8B9wHD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9ByxHH;E8BztHH;IA9DQ,iBAAA;G9B0xHL;CACF;A8Bp2HC;EAuFE,gBAAA;EACA,mBAAA;C9BgxHH;A8Bx2HC;;;EA8FE,uBAAA;C9B+wHH;A8BjwHD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9B8wHH;E8B3uHH;;;IA9BM,0BAAA;G9B8wHH;CACF;A8B/2HD;EAEI,YAAA;C9Bg3HH;A8Bl3HD;EAMM,mBAAA;C9B+2HL;A8Br3HD;EASM,iBAAA;C9B+2HL;A8B12HK;;;EAGE,YAAA;EACA,0BAAA;C9B42HP;A8Bp2HD;EAEI,YAAA;C9Bq2HH;A8Bv2HD;EAIM,gBAAA;EACA,eAAA;C9Bs2HL;A8B11HD;EACE,YAAA;C9B41HD;A8B71HD;EAII,YAAA;C9B41HH;A8Bh2HD;EAMM,mBAAA;EACA,mBAAA;C9B61HL;A8Bp2HD;EAYI,UAAA;EACA,WAAA;C9B21HH;A8B/0HD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9B01HH;E8B1xHH;IA9DQ,iBAAA;G9B21HL;CACF;A8Bn1HD;EACE,iBAAA;C9Bq1HD;A8Bt1HD;EAKI,gBAAA;EACA,mBAAA;C9Bo1HH;A8B11HD;;;EAYI,uBAAA;C9Bm1HH;A8Br0HD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9Bk1HH;E8B/yHH;;;IA9BM,0BAAA;G9Bk1HH;CACF;A8Bz0HD;EAEI,cAAA;C9B00HH;A8B50HD;EAKI,eAAA;C9B00HH;A8Bj0HD;EAEE,iBAAA;EF3OA,2BAAA;EACC,0BAAA;C5B8iIF;A+BxiID;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,8BAAA;C/B0iID;A+BliID;EA8nBA;IAhoBI,mBAAA;G/BwiID;CACF;A+BzhID;EAgnBA;IAlnBI,YAAA;G/B+hID;CACF;A+BjhID;EACE,oBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,2DAAA;UAAA,mDAAA;EAEA,kCAAA;C/BkhID;A+BhhIC;EACE,iBAAA;C/BkhIH;A+Bt/HD;EA6jBA;IArlBI,YAAA;IACA,cAAA;IACA,yBAAA;YAAA,iBAAA;G/BkhID;E+BhhIC;IACE,0BAAA;IACA,wBAAA;IACA,kBAAA;IACA,6BAAA;G/BkhIH;E+B/gIC;IACE,oBAAA;G/BihIH;E+B5gIC;;;IAGE,gBAAA;IACA,iBAAA;G/B8gIH;CACF;A+B1gID;;EAGI,kBAAA;C/B2gIH;A+BtgIC;EAmjBF;;IArjBM,kBAAA;G/B6gIH;CACF;A+BpgID;;;;EAII,oBAAA;EACA,mBAAA;C/BsgIH;A+BhgIC;EAgiBF;;;;IAniBM,gBAAA;IACA,eAAA;G/B0gIH;CACF;A+B9/HD;EACE,cAAA;EACA,sBAAA;C/BggID;A+B3/HD;EA8gBA;IAhhBI,iBAAA;G/BigID;CACF;A+B7/HD;;EAEE,gBAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;C/B+/HD;A+Bz/HD;EAggBA;;IAlgBI,iBAAA;G/BggID;CACF;A+B9/HD;EACE,OAAA;EACA,sBAAA;C/BggID;A+B9/HD;EACE,UAAA;EACA,iBAAA;EACA,sBAAA;C/BggID;A+B1/HD;EACE,YAAA;EACA,mBAAA;EACA,gBAAA;EACA,kBAAA;EACA,aAAA;C/B4/HD;A+B1/HC;;EAEE,sBAAA;C/B4/HH;A+BrgID;EAaI,eAAA;C/B2/HH;A+Bl/HD;EALI;;IAEE,mBAAA;G/B0/HH;CACF;A+Bh/HD;EACE,mBAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;EC9LA,gBAAA;EACA,mBAAA;ED+LA,8BAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;C/Bm/HD;A+B/+HC;EACE,WAAA;C/Bi/HH;A+B//HD;EAmBI,eAAA;EACA,YAAA;EACA,YAAA;EACA,mBAAA;C/B++HH;A+BrgID;EAyBI,gBAAA;C/B++HH;A+Bz+HD;EAqbA;IAvbI,cAAA;G/B++HD;CACF;A+Bt+HD;EACE,oBAAA;C/Bw+HD;A+Bz+HD;EAII,kBAAA;EACA,qBAAA;EACA,kBAAA;C/Bw+HH;A+B58HC;EA2YF;IAjaM,iBAAA;IACA,YAAA;IACA,YAAA;IACA,cAAA;IACA,8BAAA;IACA,UAAA;IACA,yBAAA;YAAA,iBAAA;G/Bs+HH;E+B3kHH;;IAxZQ,2BAAA;G/Bu+HL;E+B/kHH;IArZQ,kBAAA;G/Bu+HL;E+Bt+HK;;IAEE,uBAAA;G/Bw+HP;CACF;A+Bt9HD;EA+XA;IA1YI,YAAA;IACA,UAAA;G/Bq+HD;E+B5lHH;IAtYM,YAAA;G/Bq+HH;E+B/lHH;IApYQ,kBAAA;IACA,qBAAA;G/Bs+HL;CACF;A+B39HD;EACE,mBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,qCAAA;E1B9NA,6FAAA;EACQ,qFAAA;E2B/DR,gBAAA;EACA,mBAAA;ChC4vID;AkBtuHD;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBwyHH;EkBpqHH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBsyHH;EkBzqHH;IAxHM,sBAAA;GlBoyHH;EkB5qHH;IApHM,sBAAA;IACA,uBAAA;GlBmyHH;EkBhrHH;;;IA9GQ,YAAA;GlBmyHL;EkBrrHH;IAxGM,YAAA;GlBgyHH;EkBxrHH;IApGM,iBAAA;IACA,uBAAA;GlB+xHH;EkB5rHH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB4xHH;EkBnsHH;;IAtFQ,gBAAA;GlB6xHL;EkBvsHH;;IAjFM,mBAAA;IACA,eAAA;GlB4xHH;EkB5sHH;IA3EM,OAAA;GlB0xHH;CACF;A+BpgIC;EAmWF;IAzWM,mBAAA;G/B8gIH;E+B5gIG;IACE,iBAAA;G/B8gIL;CACF;A+B7/HD;EAoVA;IA5VI,YAAA;IACA,UAAA;IACA,eAAA;IACA,gBAAA;IACA,eAAA;IACA,kBAAA;I1BzPF,yBAAA;IACQ,iBAAA;GLmwIP;CACF;A+BngID;EACE,cAAA;EHpUA,2BAAA;EACC,0BAAA;C5B00IF;A+BngID;EACE,iBAAA;EHzUA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5By0IF;A+B//HD;EChVE,gBAAA;EACA,mBAAA;ChCk1ID;A+BhgIC;ECnVA,iBAAA;EACA,oBAAA;ChCs1ID;A+BjgIC;ECtVA,iBAAA;EACA,oBAAA;ChC01ID;A+B3/HD;EChWE,iBAAA;EACA,oBAAA;ChC81ID;A+Bv/HD;EAsSA;IA1SI,YAAA;IACA,kBAAA;IACA,mBAAA;G/B+/HD;CACF;A+Bl+HD;EAhBE;IExWA,uBAAA;GjC81IC;E+Br/HD;IE5WA,wBAAA;IF8WE,oBAAA;G/Bu/HD;E+Bz/HD;IAKI,gBAAA;G/Bu/HH;CACF;A+B9+HD;EACE,0BAAA;EACA,sBAAA;C/Bg/HD;A+Bl/HD;EAKI,YAAA;C/Bg/HH;A+B/+HG;;EAEE,eAAA;EACA,8BAAA;C/Bi/HL;A+B1/HD;EAcI,YAAA;C/B++HH;A+B7/HD;EAmBM,YAAA;C/B6+HL;A+B3+HK;;EAEE,YAAA;EACA,8BAAA;C/B6+HP;A+Bz+HK;;;EAGE,YAAA;EACA,0BAAA;C/B2+HP;A+Bv+HK;;;EAGE,YAAA;EACA,8BAAA;C/By+HP;A+BjhID;EA8CI,mBAAA;C/Bs+HH;A+Br+HG;;EAEE,uBAAA;C/Bu+HL;A+BxhID;EAoDM,uBAAA;C/Bu+HL;A+B3hID;;EA0DI,sBAAA;C/Bq+HH;A+B99HK;;;EAGE,0BAAA;EACA,YAAA;C/Bg+HP;A+B/7HC;EAoKF;IA7LU,YAAA;G/B49HP;E+B39HO;;IAEE,YAAA;IACA,8BAAA;G/B69HT;E+Bz9HO;;;IAGE,YAAA;IACA,0BAAA;G/B29HT;E+Bv9HO;;;IAGE,YAAA;IACA,8BAAA;G/By9HT;CACF;A+B3jID;EA8GI,YAAA;C/Bg9HH;A+B/8HG;EACE,YAAA;C/Bi9HL;A+BjkID;EAqHI,YAAA;C/B+8HH;A+B98HG;;EAEE,YAAA;C/Bg9HL;A+B58HK;;;;EAEE,YAAA;C/Bg9HP;A+Bx8HD;EACE,uBAAA;EACA,sBAAA;C/B08HD;A+B58HD;EAKI,eAAA;C/B08HH;A+Bz8HG;;EAEE,YAAA;EACA,8BAAA;C/B28HL;A+Bp9HD;EAcI,eAAA;C/By8HH;A+Bv9HD;EAmBM,eAAA;C/Bu8HL;A+Br8HK;;EAEE,YAAA;EACA,8BAAA;C/Bu8HP;A+Bn8HK;;;EAGE,YAAA;EACA,0BAAA;C/Bq8HP;A+Bj8HK;;;EAGE,YAAA;EACA,8BAAA;C/Bm8HP;A+B3+HD;EA+CI,mBAAA;C/B+7HH;A+B97HG;;EAEE,uBAAA;C/Bg8HL;A+Bl/HD;EAqDM,uBAAA;C/Bg8HL;A+Br/HD;;EA2DI,sBAAA;C/B87HH;A+Bx7HK;;;EAGE,0BAAA;EACA,YAAA;C/B07HP;A+Bn5HC;EAwBF;IAvDU,sBAAA;G/Bs7HP;E+B/3HH;IApDU,0BAAA;G/Bs7HP;E+Bl4HH;IAjDU,eAAA;G/Bs7HP;E+Br7HO;;IAEE,YAAA;IACA,8BAAA;G/Bu7HT;E+Bn7HO;;;IAGE,YAAA;IACA,0BAAA;G/Bq7HT;E+Bj7HO;;;IAGE,YAAA;IACA,8BAAA;G/Bm7HT;CACF;A+B3hID;EA+GI,eAAA;C/B+6HH;A+B96HG;EACE,YAAA;C/Bg7HL;A+BjiID;EAsHI,eAAA;C/B86HH;A+B76HG;;EAEE,YAAA;C/B+6HL;A+B36HK;;;;EAEE,YAAA;C/B+6HP;AkCzjJD;EACE,kBAAA;EACA,oBAAA;EACA,iBAAA;EACA,0BAAA;EACA,mBAAA;ClC2jJD;AkChkJD;EAQI,sBAAA;ClC2jJH;AkCnkJD;EAWM,kBAAA;EACA,eAAA;EACA,YAAA;ClC2jJL;AkCxkJD;EAkBI,eAAA;ClCyjJH;AmC7kJD;EACE,sBAAA;EACA,gBAAA;EACA,eAAA;EACA,mBAAA;CnC+kJD;AmCnlJD;EAOI,gBAAA;CnC+kJH;AmCtlJD;;EAUM,mBAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,sBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,kBAAA;CnCglJL;AmC9kJG;;EAGI,eAAA;EPXN,+BAAA;EACG,4BAAA;C5B2lJJ;AmC7kJG;;EPvBF,gCAAA;EACG,6BAAA;C5BwmJJ;AmCxkJG;;;;EAEE,WAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CnC4kJL;AmCtkJG;;;;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;EACA,gBAAA;CnC2kJL;AmCloJD;;;;;;EAkEM,eAAA;EACA,uBAAA;EACA,mBAAA;EACA,oBAAA;CnCwkJL;AmC/jJD;;EC3EM,mBAAA;EACA,gBAAA;EACA,uBAAA;CpC8oJL;AoC5oJG;;ERKF,+BAAA;EACG,4BAAA;C5B2oJJ;AoC3oJG;;ERTF,gCAAA;EACG,6BAAA;C5BwpJJ;AmC1kJD;;EChFM,kBAAA;EACA,gBAAA;EACA,iBAAA;CpC8pJL;AoC5pJG;;ERKF,+BAAA;EACG,4BAAA;C5B2pJJ;AoC3pJG;;ERTF,gCAAA;EACG,6BAAA;C5BwqJJ;AqC3qJD;EACE,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,mBAAA;CrC6qJD;AqCjrJD;EAOI,gBAAA;CrC6qJH;AqCprJD;;EAUM,sBAAA;EACA,kBAAA;EACA,uBAAA;EACA,uBAAA;EACA,oBAAA;CrC8qJL;AqC5rJD;;EAmBM,sBAAA;EACA,0BAAA;CrC6qJL;AqCjsJD;;EA2BM,aAAA;CrC0qJL;AqCrsJD;;EAkCM,YAAA;CrCuqJL;AqCzsJD;;;;EA2CM,eAAA;EACA,uBAAA;EACA,oBAAA;CrCoqJL;AsCltJD;EACE,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,mBAAA;EACA,oBAAA;EACA,yBAAA;EACA,qBAAA;CtCotJD;AsChtJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CtCktJL;AsC7sJC;EACE,cAAA;CtC+sJH;AsC3sJC;EACE,mBAAA;EACA,UAAA;CtC6sJH;AsCtsJD;ECtCE,0BAAA;CvC+uJD;AuC5uJG;;EAEE,0BAAA;CvC8uJL;AsCzsJD;EC1CE,0BAAA;CvCsvJD;AuCnvJG;;EAEE,0BAAA;CvCqvJL;AsC5sJD;EC9CE,0BAAA;CvC6vJD;AuC1vJG;;EAEE,0BAAA;CvC4vJL;AsC/sJD;EClDE,0BAAA;CvCowJD;AuCjwJG;;EAEE,0BAAA;CvCmwJL;AsCltJD;ECtDE,0BAAA;CvC2wJD;AuCxwJG;;EAEE,0BAAA;CvC0wJL;AsCrtJD;EC1DE,0BAAA;CvCkxJD;AuC/wJG;;EAEE,0BAAA;CvCixJL;AwCnxJD;EACE,sBAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,eAAA;EACA,uBAAA;EACA,oBAAA;EACA,mBAAA;EACA,0BAAA;EACA,oBAAA;CxCqxJD;AwClxJC;EACE,cAAA;CxCoxJH;AwChxJC;EACE,mBAAA;EACA,UAAA;CxCkxJH;AwC/wJC;;EAEE,OAAA;EACA,iBAAA;CxCixJH;AwC5wJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CxC8wJL;AwCzwJC;;EAEE,eAAA;EACA,uBAAA;CxC2wJH;AwCxwJC;EACE,aAAA;CxC0wJH;AwCvwJC;EACE,kBAAA;CxCywJH;AwCtwJC;EACE,iBAAA;CxCwwJH;AyCl0JD;EACE,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,eAAA;EACA,0BAAA;CzCo0JD;AyCz0JD;;EASI,eAAA;CzCo0JH;AyC70JD;EAaI,oBAAA;EACA,gBAAA;EACA,iBAAA;CzCm0JH;AyCl1JD;EAmBI,0BAAA;CzCk0JH;AyC/zJC;;EAEE,mBAAA;EACA,mBAAA;EACA,oBAAA;CzCi0JH;AyC31JD;EA8BI,gBAAA;CzCg0JH;AyC9yJD;EACA;IAfI,kBAAA;IACA,qBAAA;GzCg0JD;EyC9zJC;;IAEE,mBAAA;IACA,oBAAA;GzCg0JH;EyCvzJH;;IAJM,gBAAA;GzC+zJH;CACF;A0C52JD;EACE,eAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;ErCiLA,4CAAA;EACK,uCAAA;EACG,oCAAA;CL8rJT;A0Cx3JD;;EAaI,kBAAA;EACA,mBAAA;C1C+2JH;A0C32JC;;;EAGE,sBAAA;C1C62JH;A0Cl4JD;EA0BI,aAAA;EACA,eAAA;C1C22JH;A2Cp4JD;EACE,cAAA;EACA,oBAAA;EACA,8BAAA;EACA,mBAAA;C3Cs4JD;A2C14JD;EAQI,cAAA;EAEA,eAAA;C3Co4JH;A2C94JD;EAeI,kBAAA;C3Ck4JH;A2Cj5JD;;EAqBI,iBAAA;C3Cg4JH;A2Cr5JD;EAyBI,gBAAA;C3C+3JH;A2Cv3JD;;EAEE,oBAAA;C3Cy3JD;A2C33JD;;EAMI,mBAAA;EACA,UAAA;EACA,aAAA;EACA,eAAA;C3Cy3JH;A2Cj3JD;ECvDE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C26JD;A2Ct3JD;EClDI,0BAAA;C5C26JH;A2Cz3JD;EC/CI,eAAA;C5C26JH;A2Cx3JD;EC3DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Cs7JD;A2C73JD;ECtDI,0BAAA;C5Cs7JH;A2Ch4JD;ECnDI,eAAA;C5Cs7JH;A2C/3JD;EC/DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Ci8JD;A2Cp4JD;EC1DI,0BAAA;C5Ci8JH;A2Cv4JD;ECvDI,eAAA;C5Ci8JH;A2Ct4JD;ECnEE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C48JD;A2C34JD;EC9DI,0BAAA;C5C48JH;A2C94JD;EC3DI,eAAA;C5C48JH;A6C98JD;EACE;IAAQ,4BAAA;G7Ci9JP;E6Ch9JD;IAAQ,yBAAA;G7Cm9JP;CACF;A6Ch9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6Cx9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6C98JD;EACE,iBAAA;EACA,aAAA;EACA,oBAAA;EACA,0BAAA;EACA,mBAAA;ExCsCA,uDAAA;EACQ,+CAAA;CL26JT;A6C78JD;EACE,YAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,mBAAA;EACA,0BAAA;ExCyBA,uDAAA;EACQ,+CAAA;EAyHR,oCAAA;EACK,+BAAA;EACG,4BAAA;CL+zJT;A6C18JD;;ECCI,8MAAA;EACA,yMAAA;EACA,sMAAA;EDAF,mCAAA;UAAA,2BAAA;C7C88JD;A6Cv8JD;;ExC5CE,2DAAA;EACK,sDAAA;EACG,mDAAA;CLu/JT;A6Cp8JD;EErEE,0BAAA;C/C4gKD;A+CzgKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C49JH;A6Cx8JD;EEzEE,0BAAA;C/CohKD;A+CjhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co+JH;A6C58JD;EE7EE,0BAAA;C/C4hKD;A+CzhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C4+JH;A6Ch9JD;EEjFE,0BAAA;C/CoiKD;A+CjiKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co/JH;AgD5iKD;EAEE,iBAAA;ChD6iKD;AgD3iKC;EACE,cAAA;ChD6iKH;AgDziKD;;EAEE,QAAA;EACA,iBAAA;ChD2iKD;AgDxiKD;EACE,eAAA;ChD0iKD;AgDviKD;EACE,eAAA;ChDyiKD;AgDtiKC;EACE,gBAAA;ChDwiKH;AgDpiKD;;EAEE,mBAAA;ChDsiKD;AgDniKD;;EAEE,oBAAA;ChDqiKD;AgDliKD;;;EAGE,oBAAA;EACA,oBAAA;ChDoiKD;AgDjiKD;EACE,uBAAA;ChDmiKD;AgDhiKD;EACE,uBAAA;ChDkiKD;AgD9hKD;EACE,cAAA;EACA,mBAAA;ChDgiKD;AgD1hKD;EACE,gBAAA;EACA,iBAAA;ChD4hKD;AiDnlKD;EAEE,oBAAA;EACA,gBAAA;CjDolKD;AiD5kKD;EACE,mBAAA;EACA,eAAA;EACA,mBAAA;EAEA,oBAAA;EACA,uBAAA;EACA,uBAAA;CjD6kKD;AiD1kKC;ErB3BA,6BAAA;EACC,4BAAA;C5BwmKF;AiD3kKC;EACE,iBAAA;ErBvBF,gCAAA;EACC,+BAAA;C5BqmKF;AiDpkKD;;EAEE,YAAA;CjDskKD;AiDxkKD;;EAKI,YAAA;CjDukKH;AiDnkKC;;;;EAEE,sBAAA;EACA,YAAA;EACA,0BAAA;CjDukKH;AiDnkKD;EACE,YAAA;EACA,iBAAA;CjDqkKD;AiDhkKC;;;EAGE,0BAAA;EACA,eAAA;EACA,oBAAA;CjDkkKH;AiDvkKC;;;EASI,eAAA;CjDmkKL;AiD5kKC;;;EAYI,eAAA;CjDqkKL;AiDhkKC;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;CjDkkKH;AiDxkKC;;;;;;;;;EAYI,eAAA;CjDukKL;AiDnlKC;;;EAeI,eAAA;CjDykKL;AkD3qKC;EACE,eAAA;EACA,0BAAA;ClD6qKH;AkD3qKG;;EAEE,eAAA;ClD6qKL;AkD/qKG;;EAKI,eAAA;ClD8qKP;AkD3qKK;;;;EAEE,eAAA;EACA,0BAAA;ClD+qKP;AkD7qKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDkrKP;AkDxsKC;EACE,eAAA;EACA,0BAAA;ClD0sKH;AkDxsKG;;EAEE,eAAA;ClD0sKL;AkD5sKG;;EAKI,eAAA;ClD2sKP;AkDxsKK;;;;EAEE,eAAA;EACA,0BAAA;ClD4sKP;AkD1sKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD+sKP;AkDruKC;EACE,eAAA;EACA,0BAAA;ClDuuKH;AkDruKG;;EAEE,eAAA;ClDuuKL;AkDzuKG;;EAKI,eAAA;ClDwuKP;AkDruKK;;;;EAEE,eAAA;EACA,0BAAA;ClDyuKP;AkDvuKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD4uKP;AkDlwKC;EACE,eAAA;EACA,0BAAA;ClDowKH;AkDlwKG;;EAEE,eAAA;ClDowKL;AkDtwKG;;EAKI,eAAA;ClDqwKP;AkDlwKK;;;;EAEE,eAAA;EACA,0BAAA;ClDswKP;AkDpwKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDywKP;AiDxqKD;EACE,cAAA;EACA,mBAAA;CjD0qKD;AiDxqKD;EACE,iBAAA;EACA,iBAAA;CjD0qKD;AmDpyKD;EACE,oBAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;E9C0DA,kDAAA;EACQ,0CAAA;CL6uKT;AmDnyKD;EACE,cAAA;CnDqyKD;AmDhyKD;EACE,mBAAA;EACA,qCAAA;EvBpBA,6BAAA;EACC,4BAAA;C5BuzKF;AmDtyKD;EAMI,eAAA;CnDmyKH;AmD9xKD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;CnDgyKD;AmDpyKD;;;;;EAWI,eAAA;CnDgyKH;AmD3xKD;EACE,mBAAA;EACA,0BAAA;EACA,2BAAA;EvBxCA,gCAAA;EACC,+BAAA;C5Bs0KF;AmDrxKD;;EAGI,iBAAA;CnDsxKH;AmDzxKD;;EAMM,oBAAA;EACA,iBAAA;CnDuxKL;AmDnxKG;;EAEI,cAAA;EvBvEN,6BAAA;EACC,4BAAA;C5B61KF;AmDjxKG;;EAEI,iBAAA;EvBvEN,gCAAA;EACC,+BAAA;C5B21KF;AmD1yKD;EvB1DE,2BAAA;EACC,0BAAA;C5Bu2KF;AmD7wKD;EAEI,oBAAA;CnD8wKH;AmD3wKD;EACE,oBAAA;CnD6wKD;AmDrwKD;;;EAII,iBAAA;CnDswKH;AmD1wKD;;;EAOM,mBAAA;EACA,oBAAA;CnDwwKL;AmDhxKD;;EvBzGE,6BAAA;EACC,4BAAA;C5B63KF;AmDrxKD;;;;EAmBQ,4BAAA;EACA,6BAAA;CnDwwKP;AmD5xKD;;;;;;;;EAwBU,4BAAA;CnD8wKT;AmDtyKD;;;;;;;;EA4BU,6BAAA;CnDoxKT;AmDhzKD;;EvBjGE,gCAAA;EACC,+BAAA;C5Bq5KF;AmDrzKD;;;;EAyCQ,+BAAA;EACA,gCAAA;CnDkxKP;AmD5zKD;;;;;;;;EA8CU,+BAAA;CnDwxKT;AmDt0KD;;;;;;;;EAkDU,gCAAA;CnD8xKT;AmDh1KD;;;;EA2DI,2BAAA;CnD2xKH;AmDt1KD;;EA+DI,cAAA;CnD2xKH;AmD11KD;;EAmEI,UAAA;CnD2xKH;AmD91KD;;;;;;;;;;;;EA0EU,eAAA;CnDkyKT;AmD52KD;;;;;;;;;;;;EA8EU,gBAAA;CnD4yKT;AmD13KD;;;;;;;;EAuFU,iBAAA;CnD6yKT;AmDp4KD;;;;;;;;EAgGU,iBAAA;CnD8yKT;AmD94KD;EAsGI,UAAA;EACA,iBAAA;CnD2yKH;AmDjyKD;EACE,oBAAA;CnDmyKD;AmDpyKD;EAKI,iBAAA;EACA,mBAAA;CnDkyKH;AmDxyKD;EASM,gBAAA;CnDkyKL;AmD3yKD;EAcI,iBAAA;CnDgyKH;AmD9yKD;;EAkBM,2BAAA;CnDgyKL;AmDlzKD;EAuBI,cAAA;CnD8xKH;AmDrzKD;EAyBM,8BAAA;CnD+xKL;AmDxxKD;EC1PE,mBAAA;CpDqhLD;AoDnhLC;EACE,eAAA;EACA,0BAAA;EACA,mBAAA;CpDqhLH;AoDxhLC;EAMI,uBAAA;CpDqhLL;AoD3hLC;EASI,eAAA;EACA,0BAAA;CpDqhLL;AoDlhLC;EAEI,0BAAA;CpDmhLL;AmDvyKD;EC7PE,sBAAA;CpDuiLD;AoDriLC;EACE,YAAA;EACA,0BAAA;EACA,sBAAA;CpDuiLH;AoD1iLC;EAMI,0BAAA;CpDuiLL;AoD7iLC;EASI,eAAA;EACA,uBAAA;CpDuiLL;AoDpiLC;EAEI,6BAAA;CpDqiLL;AmDtzKD;EChQE,sBAAA;CpDyjLD;AoDvjLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpDyjLH;AoD5jLC;EAMI,0BAAA;CpDyjLL;AoD/jLC;EASI,eAAA;EACA,0BAAA;CpDyjLL;AoDtjLC;EAEI,6BAAA;CpDujLL;AmDr0KD;ECnQE,sBAAA;CpD2kLD;AoDzkLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD2kLH;AoD9kLC;EAMI,0BAAA;CpD2kLL;AoDjlLC;EASI,eAAA;EACA,0BAAA;CpD2kLL;AoDxkLC;EAEI,6BAAA;CpDykLL;AmDp1KD;ECtQE,sBAAA;CpD6lLD;AoD3lLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD6lLH;AoDhmLC;EAMI,0BAAA;CpD6lLL;AoDnmLC;EASI,eAAA;EACA,0BAAA;CpD6lLL;AoD1lLC;EAEI,6BAAA;CpD2lLL;AmDn2KD;ECzQE,sBAAA;CpD+mLD;AoD7mLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD+mLH;AoDlnLC;EAMI,0BAAA;CpD+mLL;AoDrnLC;EASI,eAAA;EACA,0BAAA;CpD+mLL;AoD5mLC;EAEI,6BAAA;CpD6mLL;AqD7nLD;EACE,mBAAA;EACA,eAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;CrD+nLD;AqDpoLD;;;;;EAYI,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;CrD+nLH;AqD1nLD;EACE,uBAAA;CrD4nLD;AqDxnLD;EACE,oBAAA;CrD0nLD;AsDrpLD;EACE,iBAAA;EACA,cAAA;EACA,oBAAA;EACA,0BAAA;EACA,0BAAA;EACA,mBAAA;EjDwDA,wDAAA;EACQ,gDAAA;CLgmLT;AsD/pLD;EASI,mBAAA;EACA,kCAAA;CtDypLH;AsDppLD;EACE,cAAA;EACA,mBAAA;CtDspLD;AsDppLD;EACE,aAAA;EACA,mBAAA;CtDspLD;AuD5qLD;EACE,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,0BAAA;EjCRA,aAAA;EAGA,0BAAA;CtBqrLD;AuD7qLC;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;EjCfF,aAAA;EAGA,0BAAA;CtB6rLD;AuDzqLC;EACE,WAAA;EACA,gBAAA;EACA,wBAAA;EACA,UAAA;EACA,yBAAA;CvD2qLH;AwDhsLD;EACE,iBAAA;CxDksLD;AwD9rLD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,kCAAA;EAIA,WAAA;CxD6rLD;AwD1rLC;EnD+GA,sCAAA;EACI,kCAAA;EACC,iCAAA;EACG,8BAAA;EAkER,oDAAA;EAEK,0CAAA;EACG,oCAAA;CL6gLT;AwDhsLC;EnD2GA,mCAAA;EACI,+BAAA;EACC,8BAAA;EACG,2BAAA;CLwlLT;AwDpsLD;EACE,mBAAA;EACA,iBAAA;CxDssLD;AwDlsLD;EACE,mBAAA;EACA,YAAA;EACA,aAAA;CxDosLD;AwDhsLD;EACE,mBAAA;EACA,uBAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EnDaA,iDAAA;EACQ,yCAAA;EmDZR,qCAAA;UAAA,6BAAA;EAEA,WAAA;CxDksLD;AwD9rLD;EACE,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,uBAAA;CxDgsLD;AwD9rLC;ElCrEA,WAAA;EAGA,yBAAA;CtBowLD;AwDjsLC;ElCtEA,aAAA;EAGA,0BAAA;CtBwwLD;AwDhsLD;EACE,cAAA;EACA,iCAAA;CxDksLD;AwD9rLD;EACE,iBAAA;CxDgsLD;AwD5rLD;EACE,UAAA;EACA,wBAAA;CxD8rLD;AwDzrLD;EACE,mBAAA;EACA,cAAA;CxD2rLD;AwDvrLD;EACE,cAAA;EACA,kBAAA;EACA,8BAAA;CxDyrLD;AwD5rLD;EAQI,iBAAA;EACA,iBAAA;CxDurLH;AwDhsLD;EAaI,kBAAA;CxDsrLH;AwDnsLD;EAiBI,eAAA;CxDqrLH;AwDhrLD;EACE,mBAAA;EACA,aAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;CxDkrLD;AwDhqLD;EAZE;IACE,aAAA;IACA,kBAAA;GxD+qLD;EwD7qLD;InDvEA,kDAAA;IACQ,0CAAA;GLuvLP;EwD5qLD;IAAY,aAAA;GxD+qLX;CACF;AwD1qLD;EAFE;IAAY,aAAA;GxDgrLX;CACF;AyD/zLD;EACE,mBAAA;EACA,cAAA;EACA,eAAA;ECRA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;EDHA,gBAAA;EnCVA,WAAA;EAGA,yBAAA;CtBs1LD;AyD30LC;EnCdA,aAAA;EAGA,0BAAA;CtB01LD;AyD90LC;EAAW,iBAAA;EAAmB,eAAA;CzDk1L/B;AyDj1LC;EAAW,iBAAA;EAAmB,eAAA;CzDq1L/B;AyDp1LC;EAAW,gBAAA;EAAmB,eAAA;CzDw1L/B;AyDv1LC;EAAW,kBAAA;EAAmB,eAAA;CzD21L/B;AyDv1LD;EACE,iBAAA;EACA,iBAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,mBAAA;CzDy1LD;AyDr1LD;EACE,mBAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;CzDu1LD;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,QAAA;EACA,iBAAA;EACA,4BAAA;EACA,yBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,SAAA;EACA,iBAAA;EACA,4BAAA;EACA,wBAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,WAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;A2Dl7LD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EDXA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;ECAA,gBAAA;EAEA,uBAAA;EACA,qCAAA;UAAA,6BAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EtD8CA,kDAAA;EACQ,0CAAA;CLk5LT;A2D77LC;EAAY,kBAAA;C3Dg8Lb;A2D/7LC;EAAY,kBAAA;C3Dk8Lb;A2Dj8LC;EAAY,iBAAA;C3Do8Lb;A2Dn8LC;EAAY,mBAAA;C3Ds8Lb;A2Dn8LD;EACE,UAAA;EACA,kBAAA;EACA,gBAAA;EACA,0BAAA;EACA,iCAAA;EACA,2BAAA;C3Dq8LD;A2Dl8LD;EACE,kBAAA;C3Do8LD;A2D57LC;;EAEE,mBAAA;EACA,eAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;C3D87LH;A2D37LD;EACE,mBAAA;C3D67LD;A2D37LD;EACE,mBAAA;EACA,YAAA;C3D67LD;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,0BAAA;EACA,sCAAA;EACA,cAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,uBAAA;C3D47LL;A2Dz7LC;EACE,SAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,4BAAA;EACA,wCAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,UAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;C3D47LL;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,oBAAA;EACA,6BAAA;EACA,yCAAA;EACA,WAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,SAAA;EACA,mBAAA;EACA,oBAAA;EACA,0BAAA;C3D47LL;A2Dx7LC;EACE,SAAA;EACA,aAAA;EACA,kBAAA;EACA,sBAAA;EACA,2BAAA;EACA,uCAAA;C3D07LH;A2Dz7LG;EACE,aAAA;EACA,WAAA;EACA,sBAAA;EACA,wBAAA;EACA,cAAA;C3D27LL;A4DpjMD;EACE,mBAAA;C5DsjMD;A4DnjMD;EACE,mBAAA;EACA,iBAAA;EACA,YAAA;C5DqjMD;A4DxjMD;EAMI,cAAA;EACA,mBAAA;EvD6KF,0CAAA;EACK,qCAAA;EACG,kCAAA;CLy4LT;A4D/jMD;;EAcM,eAAA;C5DqjML;A4D3hMC;EA4NF;IvD3DE,uDAAA;IAEK,6CAAA;IACG,uCAAA;IA7JR,oCAAA;IAEQ,4BAAA;IA+GR,4BAAA;IAEQ,oBAAA;GL86LP;E4DzjMG;;IvDmHJ,2CAAA;IACQ,mCAAA;IuDjHF,QAAA;G5D4jML;E4D1jMG;;IvD8GJ,4CAAA;IACQ,oCAAA;IuD5GF,QAAA;G5D6jML;E4D3jMG;;;IvDyGJ,wCAAA;IACQ,gCAAA;IuDtGF,QAAA;G5D8jML;CACF;A4DpmMD;;;EA6CI,eAAA;C5D4jMH;A4DzmMD;EAiDI,QAAA;C5D2jMH;A4D5mMD;;EAsDI,mBAAA;EACA,OAAA;EACA,YAAA;C5D0jMH;A4DlnMD;EA4DI,WAAA;C5DyjMH;A4DrnMD;EA+DI,YAAA;C5DyjMH;A4DxnMD;;EAmEI,QAAA;C5DyjMH;A4D5nMD;EAuEI,YAAA;C5DwjMH;A4D/nMD;EA0EI,WAAA;C5DwjMH;A4DhjMD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EtC9FA,aAAA;EAGA,0BAAA;EsC6FA,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;EACA,mCAAA;C5DmjMD;A4D9iMC;EdnGE,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9CopMH;A4DljMC;EACE,WAAA;EACA,SAAA;EdxGA,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9C6pMH;A4DpjMC;;EAEE,WAAA;EACA,YAAA;EACA,sBAAA;EtCvHF,aAAA;EAGA,0BAAA;CtB4qMD;A4DtlMD;;;;EAuCI,mBAAA;EACA,SAAA;EACA,kBAAA;EACA,WAAA;EACA,sBAAA;C5DqjMH;A4DhmMD;;EA+CI,UAAA;EACA,mBAAA;C5DqjMH;A4DrmMD;;EAoDI,WAAA;EACA,oBAAA;C5DqjMH;A4D1mMD;;EAyDI,YAAA;EACA,aAAA;EACA,eAAA;EACA,mBAAA;C5DqjMH;A4DhjMG;EACE,iBAAA;C5DkjML;A4D9iMG;EACE,iBAAA;C5DgjML;A4DtiMD;EACE,mBAAA;EACA,aAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;C5DwiMD;A4DjjMD;EAYI,sBAAA;EACA,YAAA;EACA,aAAA;EACA,YAAA;EACA,oBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;EAWA,0BAAA;EACA,mCAAA;C5D8hMH;A4D7jMD;EAkCI,UAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;C5D8hMH;A4DvhMD;EACE,mBAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;C5DyhMD;A4DxhMC;EACE,kBAAA;C5D0hMH;A4Dj/LD;EAhCE;;;;IAKI,YAAA;IACA,aAAA;IACA,kBAAA;IACA,gBAAA;G5DmhMH;E4D3hMD;;IAYI,mBAAA;G5DmhMH;E4D/hMD;;IAgBI,oBAAA;G5DmhMH;E4D9gMD;IACE,UAAA;IACA,WAAA;IACA,qBAAA;G5DghMD;E4D5gMD;IACE,aAAA;G5D8gMD;CACF;A6D7wMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,aAAA;EACA,eAAA;C7D6yMH;A6D3yMC;;;;;;;;;;;;;;;;EACE,YAAA;C7D4zMH;AiCp0MD;E6BRE,eAAA;EACA,kBAAA;EACA,mBAAA;C9D+0MD;AiCt0MD;EACE,wBAAA;CjCw0MD;AiCt0MD;EACE,uBAAA;CjCw0MD;AiCh0MD;EACE,yBAAA;CjCk0MD;AiCh0MD;EACE,0BAAA;CjCk0MD;AiCh0MD;EACE,mBAAA;CjCk0MD;AiCh0MD;E8BzBE,YAAA;EACA,mBAAA;EACA,kBAAA;EACA,8BAAA;EACA,UAAA;C/D41MD;AiC9zMD;EACE,yBAAA;CjCg0MD;AiCzzMD;EACE,gBAAA;CjC2zMD;AgE51MD;EACE,oBAAA;ChE81MD;AgEx1MD;;;;ECdE,yBAAA;CjE42MD;AgEv1MD;;;;;;;;;;;;EAYE,yBAAA;ChEy1MD;AgEl1MD;EA6IA;IC7LE,0BAAA;GjEs4MC;EiEr4MD;IAAU,0BAAA;GjEw4MT;EiEv4MD;IAAU,8BAAA;GjE04MT;EiEz4MD;;IACU,+BAAA;GjE44MT;CACF;AgE51MD;EAwIA;IA1II,0BAAA;GhEk2MD;CACF;AgE51MD;EAmIA;IArII,2BAAA;GhEk2MD;CACF;AgE51MD;EA8HA;IAhII,iCAAA;GhEk2MD;CACF;AgE31MD;EAwHA;IC7LE,0BAAA;GjEo6MC;EiEn6MD;IAAU,0BAAA;GjEs6MT;EiEr6MD;IAAU,8BAAA;GjEw6MT;EiEv6MD;;IACU,+BAAA;GjE06MT;CACF;AgEr2MD;EAmHA;IArHI,0BAAA;GhE22MD;CACF;AgEr2MD;EA8GA;IAhHI,2BAAA;GhE22MD;CACF;AgEr2MD;EAyGA;IA3GI,iCAAA;GhE22MD;CACF;AgEp2MD;EAmGA;IC7LE,0BAAA;GjEk8MC;EiEj8MD;IAAU,0BAAA;GjEo8MT;EiEn8MD;IAAU,8BAAA;GjEs8MT;EiEr8MD;;IACU,+BAAA;GjEw8MT;CACF;AgE92MD;EA8FA;IAhGI,0BAAA;GhEo3MD;CACF;AgE92MD;EAyFA;IA3FI,2BAAA;GhEo3MD;CACF;AgE92MD;EAoFA;IAtFI,iCAAA;GhEo3MD;CACF;AgE72MD;EA8EA;IC7LE,0BAAA;GjEg+MC;EiE/9MD;IAAU,0BAAA;GjEk+MT;EiEj+MD;IAAU,8BAAA;GjEo+MT;EiEn+MD;;IACU,+BAAA;GjEs+MT;CACF;AgEv3MD;EAyEA;IA3EI,0BAAA;GhE63MD;CACF;AgEv3MD;EAoEA;IAtEI,2BAAA;GhE63MD;CACF;AgEv3MD;EA+DA;IAjEI,iCAAA;GhE63MD;CACF;AgEt3MD;EAyDA;ICrLE,yBAAA;GjEs/MC;CACF;AgEt3MD;EAoDA;ICrLE,yBAAA;GjE2/MC;CACF;AgEt3MD;EA+CA;ICrLE,yBAAA;GjEggNC;CACF;AgEt3MD;EA0CA;ICrLE,yBAAA;GjEqgNC;CACF;AgEn3MD;ECnJE,yBAAA;CjEygND;AgEh3MD;EA4BA;IC7LE,0BAAA;GjEqhNC;EiEphND;IAAU,0BAAA;GjEuhNT;EiEthND;IAAU,8BAAA;GjEyhNT;EiExhND;;IACU,+BAAA;GjE2hNT;CACF;AgE93MD;EACE,yBAAA;ChEg4MD;AgE33MD;EAqBA;IAvBI,0BAAA;GhEi4MD;CACF;AgE/3MD;EACE,yBAAA;ChEi4MD;AgE53MD;EAcA;IAhBI,2BAAA;GhEk4MD;CACF;AgEh4MD;EACE,yBAAA;ChEk4MD;AgE73MD;EAOA;IATI,iCAAA;GhEm4MD;CACF;AgE53MD;EACA;ICrLE,yBAAA;GjEojNC;CACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\nmark {\n  background: #ff0;\n  color: #000;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\nsup {\n  top: -0.5em;\n}\nsub {\n  bottom: -0.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  box-sizing: content-box;\n  height: 0;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit;\n  font: inherit;\n  margin: 0;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n  border: 0;\n  padding: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    background: transparent !important;\n    color: #000 !important;\n    box-shadow: none !important;\n    text-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  background-color: #fcf8e3;\n  padding: .2em;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n  margin-left: -5px;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-left: 5px;\n  padding-right: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    clear: left;\n    text-align: right;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n  text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: #333333;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.row {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0%;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0%;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  min-width: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  border: 0;\n  background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eeeeee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n  min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  border-color: #3c763d;\n  background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  border-color: #8a6d3b;\n  background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  border-color: #a94442;\n  background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  margin-top: 0;\n  margin-bottom: 0;\n  padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    text-align: right;\n    margin-bottom: 0;\n    padding-top: 7px;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  margin-bottom: 0;\n  font-weight: normal;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none;\n  border: 1px solid transparent;\n  white-space: nowrap;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  border-radius: 4px;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  outline: 0;\n  background-image: none;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  color: #337ab7;\n  font-weight: normal;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n  -o-transition: opacity 0.15s linear;\n  transition: opacity 0.15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-property: height, visibility;\n  transition-property: height, visibility;\n  -webkit-transition-duration: 0.35s;\n  transition-duration: 0.35s;\n  -webkit-transition-timing-function: ease;\n  transition-timing-function: ease;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  font-size: 14px;\n  text-align: left;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  text-decoration: none;\n  color: #262626;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  cursor: not-allowed;\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  left: auto;\n  right: 0;\n}\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n  content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    left: auto;\n    right: 0;\n  }\n  .navbar-right .dropdown-menu-left {\n    left: 0;\n    right: auto;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  float: none;\n  display: table-cell;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group .form-control:focus {\n  z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555555;\n  text-align: center;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  margin-bottom: 0;\n  padding-left: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n  color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777777;\n  text-decoration: none;\n  background-color: transparent;\n  cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eeeeee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n  cursor: default;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: 15px;\n  padding-left: 15px;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n  -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n  height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: 15px;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  margin-left: -15px;\n  margin-right: -15px;\n  padding: 10px 15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-left: 15px;\n    margin-right: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  background-color: #e7e7e7;\n  color: #555;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  background-color: #080808;\n  color: #fff;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  content: \"/\\00a0\";\n  padding: 0 5px;\n  color: #ccc;\n}\n.breadcrumb > .active {\n  color: #777777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  line-height: 1.42857143;\n  text-decoration: none;\n  color: #337ab7;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-bottom-right-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 2;\n  color: #23527c;\n  background-color: #eeeeee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 3;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n  cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777777;\n  background-color: #fff;\n  border-color: #ddd;\n  cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-bottom-right-radius: 6px;\n  border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  list-style: none;\n  text-align: center;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777777;\n  background-color: #fff;\n  cursor: not-allowed;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  color: #fff;\n  line-height: 1;\n  vertical-align: middle;\n  white-space: nowrap;\n  text-align: center;\n  background-color: #777777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-left: 60px;\n    padding-right: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border 0.2s ease-in-out;\n  -o-transition: border 0.2s ease-in-out;\n  transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-left: auto;\n  margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n  color: #3c763d;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n  color: #31708f;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n  color: #8a6d3b;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  background-color: #f2dede;\n  border-color: #ebccd1;\n  color: #a94442;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  overflow: hidden;\n  height: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n  -o-transition: width 0.6s ease;\n  transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n  -o-animation: progress-bar-stripes 2s linear infinite;\n  animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  zoom: 1;\n  overflow: hidden;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  margin-bottom: 20px;\n  padding-left: 0;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  text-decoration: none;\n  color: #555;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  background-color: #eeeeee;\n  color: #777777;\n  cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-left-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  border: 0;\n  margin-bottom: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  height: 100%;\n  width: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transform: translate(0, -25%);\n  -ms-transform: translate(0, -25%);\n  -o-transform: translate(0, -25%);\n  transform: translate(0, -25%);\n  -webkit-transition: -webkit-transform 0.3s ease-out;\n  -moz-transition: -moz-transform 0.3s ease-out;\n  -o-transition: -o-transform 0.3s ease-out;\n  transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n  -ms-transform: translate(0, 0);\n  -o-transform: translate(0, 0);\n  transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  background-clip: padding-box;\n  outline: 0;\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-left: 5px;\n  margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  font-size: 12px;\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.tooltip.in {\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.tooltip.top {\n  margin-top: -3px;\n  padding: 5px 0;\n}\n.tooltip.right {\n  margin-left: 3px;\n  padding: 0 5px;\n}\n.tooltip.bottom {\n  margin-top: 3px;\n  padding: 5px 0;\n}\n.tooltip.left {\n  margin-left: -3px;\n  padding: 0 5px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  bottom: 0;\n  right: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  font-size: 14px;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  margin: 0;\n  padding: 8px 14px;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n.popover.top > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-width: 0;\n  border-top-color: #999999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  bottom: -11px;\n}\n.popover.top > .arrow:after {\n  content: \" \";\n  bottom: 1px;\n  margin-left: -10px;\n  border-bottom-width: 0;\n  border-top-color: #fff;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-left-width: 0;\n  border-right-color: #999999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n  content: \" \";\n  left: 1px;\n  bottom: -10px;\n  border-left-width: 0;\n  border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  top: -11px;\n}\n.popover.bottom > .arrow:after {\n  content: \" \";\n  top: 1px;\n  margin-left: -10px;\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n  content: \" \";\n  right: 1px;\n  border-right-width: 0;\n  border-left-color: #fff;\n  bottom: -10px;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n}\n.carousel-inner > .item {\n  display: none;\n  position: relative;\n  -webkit-transition: 0.6s ease-in-out left;\n  -o-transition: 0.6s ease-in-out left;\n  transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform 0.6s ease-in-out;\n    -moz-transition: -moz-transform 0.6s ease-in-out;\n    -o-transition: -o-transform 0.6s ease-in-out;\n    transition: transform 0.6s ease-in-out;\n    -webkit-backface-visibility: hidden;\n    -moz-backface-visibility: hidden;\n    backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n    -moz-perspective: 1000px;\n    perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    -webkit-transform: translate3d(100%, 0, 0);\n    transform: translate3d(100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    -webkit-transform: translate3d(-100%, 0, 0);\n    transform: translate3d(-100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    -webkit-transform: translate3d(0, 0, 0);\n    transform: translate3d(0, 0, 0);\n    left: 0;\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: 15%;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n  background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n  left: auto;\n  right: 0;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  outline: 0;\n  color: #fff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  margin-top: -10px;\n  z-index: 5;\n  display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  line-height: 1;\n  font-family: serif;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  border: 1px solid #fff;\n  border-radius: 10px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n  margin: 0;\n  width: 12px;\n  height: 12px;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  content: \" \";\n  display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n//    without disabling user zoom.\n//\n\nhtml {\n  font-family: sans-serif; // 1\n  -ms-text-size-adjust: 100%; // 2\n  -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n  margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; // 1\n  vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n  background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n  outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n  font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n  font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n  border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n  margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n  box-sizing: content-box;\n  height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n  overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n//    Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; // 1\n  font: inherit; // 2\n  margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n  overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n//    and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n//    `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n  cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n  line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; // 1\n  padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; // 1\n  box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n  border: 0; // 1\n  padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n  overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n  font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n    *,\n    *:before,\n    *:after {\n        background: transparent !important;\n        color: #000 !important; // Black prints faster: h5bp.com/s\n        box-shadow: none !important;\n        text-shadow: none !important;\n    }\n\n    a,\n    a:visited {\n        text-decoration: underline;\n    }\n\n    a[href]:after {\n        content: \" (\" attr(href) \")\";\n    }\n\n    abbr[title]:after {\n        content: \" (\" attr(title) \")\";\n    }\n\n    // Don't show links that are fragment identifiers,\n    // or use the `javascript:` pseudo protocol\n    a[href^=\"#\"]:after,\n    a[href^=\"javascript:\"]:after {\n        content: \"\";\n    }\n\n    pre,\n    blockquote {\n        border: 1px solid #999;\n        page-break-inside: avoid;\n    }\n\n    thead {\n        display: table-header-group; // h5bp.com/t\n    }\n\n    tr,\n    img {\n        page-break-inside: avoid;\n    }\n\n    img {\n        max-width: 100% !important;\n    }\n\n    p,\n    h2,\n    h3 {\n        orphans: 3;\n        widows: 3;\n    }\n\n    h2,\n    h3 {\n        page-break-after: avoid;\n    }\n\n    // Bootstrap specific changes start\n\n    // Bootstrap components\n    .navbar {\n        display: none;\n    }\n    .btn,\n    .dropup > .btn {\n        > .caret {\n            border-top-color: #000 !important;\n        }\n    }\n    .label {\n        border: 1px solid #000;\n    }\n\n    .table {\n        border-collapse: collapse !important;\n\n        td,\n        th {\n            background-color: #fff !important;\n        }\n    }\n    .table-bordered {\n        th,\n        td {\n            border: 1px solid #ddd !important;\n        }\n    }\n\n    // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('@{icon-font-path}@{icon-font-name}.eot');\n  src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n       url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n       url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n       url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n       url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\002a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur                    { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n.glyphicon-cd                     { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file              { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file              { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up               { &:before { content: \"\\e204\"; } }\n.glyphicon-copy                   { &:before { content: \"\\e205\"; } }\n.glyphicon-paste                  { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door                   { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key                    { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert                  { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer              { &:before { content: \"\\e210\"; } }\n.glyphicon-king                   { &:before { content: \"\\e211\"; } }\n.glyphicon-queen                  { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn                   { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop                 { &:before { content: \"\\e214\"; } }\n.glyphicon-knight                 { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula           { &:before { content: \"\\e216\"; } }\n.glyphicon-tent                   { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard             { &:before { content: \"\\e218\"; } }\n.glyphicon-bed                    { &:before { content: \"\\e219\"; } }\n.glyphicon-apple                  { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase                  { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass              { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp                   { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate              { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank             { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors               { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin                { &:before { content: \"\\e227\"; } }\n.glyphicon-btc                    { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt                    { &:before { content: \"\\e227\"; } }\n.glyphicon-yen                    { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy                    { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble                  { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub                    { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale                  { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly              { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted       { &:before { content: \"\\e232\"; } }\n.glyphicon-education              { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal      { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical        { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger         { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window           { &:before { content: \"\\e237\"; } }\n.glyphicon-oil                    { &:before { content: \"\\e238\"; } }\n.glyphicon-grain                  { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses             { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size              { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color             { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background        { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top       { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom    { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left      { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical  { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right     { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right         { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left          { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom        { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top           { &:before { content: \"\\e253\"; } }\n.glyphicon-console                { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript            { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript              { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left              { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right             { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down              { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up                { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n  .box-sizing(border-box);\n}\n*:before,\n*:after {\n  .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @text-color;\n  background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n\n// Links\n\na {\n  color: @link-color;\n  text-decoration: none;\n\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: @link-hover-decoration;\n  }\n\n  &:focus {\n    .tab-focus();\n  }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n  margin: 0;\n}\n\n\n// Images\n\nimg {\n  vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n  .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n  border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n  padding: @thumbnail-padding;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  // Keep them at most 100% wide\n  .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n  border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n  margin-top:    @line-height-computed;\n  margin-bottom: @line-height-computed;\n  border: 0;\n  border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n  cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n  // WebKit-specific. Other browsers will keep their default outline style.\n  // (Initially tried to also force default via `outline: initial`,\n  // but that seems to erroneously remove the outline in Firefox altogether.)\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 300;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n  font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n  background-color: @state-warning-bg;\n  padding: .2em;\n}\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n.text-nowrap         { white-space: nowrap; }\n\n// Transformation\n.text-lowercase      { text-transform: lowercase; }\n.text-uppercase      { text-transform: uppercase; }\n.text-capitalize     { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n  margin-left: -5px;\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n  dd {\n    &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n  }\n\n  @media (min-width: @dl-horizontal-breakpoint) {\n    dt {\n      float: left;\n      width: (@dl-horizontal-offset - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @dl-horizontal-offset;\n    }\n  }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: @blockquote-font-size;\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n  color: @color;\n  a&:hover,\n  a&:focus {\n    color: darken(@color, 10%);\n  }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n  background-color: @color;\n  a&:hover,\n  a&:focus {\n    background-color: darken(@color, 10%);\n  }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n  kbd {\n    padding: 0;\n    font-size: 100%;\n    font-weight: bold;\n    box-shadow: none;\n  }\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  floor((@gutter / 2));\n  padding-right: ceil((@gutter / 2));\n  &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  ceil((@gutter / -2));\n  margin-right: floor((@gutter / -2));\n  &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n  margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n  left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n  right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  ceil((@grid-gutter-width / 2));\n      padding-right: floor((@grid-gutter-width / 2));\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n  .col(@index) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n  .col-@{class}-push-0 {\n    left: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n  .col-@{class}-pull-0 {\n    right: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n  .calc-grid-column(@index, @class, @type);\n  // next iteration\n  .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n  .float-grid-columns(@class);\n  .loop-grid-columns(@grid-columns, @class, width);\n  .loop-grid-columns(@grid-columns, @class, pull);\n  .loop-grid-columns(@grid-columns, @class, push);\n  .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  background-color: @table-bg;\n}\ncaption {\n  padding-top: @table-cell-padding;\n  padding-bottom: @table-cell-padding;\n  color: @text-muted;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-of-type(odd) {\n    background-color: @table-bg-accent;\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    background-color: @table-bg-hover;\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n  @media screen and (max-width: @screen-xs-max) {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table > thead > tr,\n  .table > tbody > tr,\n  .table > tfoot > tr {\n    > td.@{state},\n    > th.@{state},\n    &.@{state} > td,\n    &.@{state} > th {\n      background-color: @background;\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody > tr {\n    > td.@{state}:hover,\n    > th.@{state}:hover,\n    &.@{state}:hover > td,\n    &:hover > .@{state},\n    &.@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; // IE8-9\n  line-height: normal;\n}\n\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Unstyle the caret on `<select>`s in IE10+.\n  &::-ms-expand {\n    border: 0;\n    background-color: transparent;\n  }\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n  }\n\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 9.3, iOS doesn't support `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"],\n  input[type=\"time\"],\n  input[type=\"datetime-local\"],\n  input[type=\"month\"] {\n    &.form-control {\n      line-height: @input-height-base;\n    }\n\n    &.input-sm,\n    .input-group-sm & {\n      line-height: @input-height-small;\n    }\n\n    &.input-lg,\n    .input-group-lg & {\n      line-height: @input-height-large;\n    }\n  }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n\n  label {\n    min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n    padding-left: 20px;\n    margin-bottom: 0;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  &[disabled],\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n  &.disabled,\n  fieldset[disabled] & {\n    label {\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  // Size it appropriately next to real form controls\n  padding-top: (@padding-base-vertical + 1);\n  padding-bottom: (@padding-base-vertical + 1);\n  // Remove default margin from `p`\n  margin-bottom: 0;\n  min-height: (@line-height-computed + @font-size-base);\n\n  &.input-lg,\n  &.input-sm {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n  .form-control {\n    height: @input-height-small;\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    line-height: @line-height-small;\n    border-radius: @input-border-radius-small;\n  }\n  select.form-control {\n    height: @input-height-small;\n    line-height: @input-height-small;\n  }\n  textarea.form-control,\n  select[multiple].form-control {\n    height: auto;\n  }\n  .form-control-static {\n    height: @input-height-small;\n    min-height: (@line-height-computed + @font-size-small);\n    padding: (@padding-small-vertical + 1) @padding-small-horizontal;\n    font-size: @font-size-small;\n    line-height: @line-height-small;\n  }\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n  .form-control {\n    height: @input-height-large;\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    line-height: @line-height-large;\n    border-radius: @input-border-radius-large;\n  }\n  select.form-control {\n    height: @input-height-large;\n    line-height: @input-height-large;\n  }\n  textarea.form-control,\n  select[multiple].form-control {\n    height: auto;\n  }\n  .form-control-static {\n    height: @input-height-large;\n    min-height: (@line-height-computed + @font-size-large);\n    padding: (@padding-large-vertical + 1) @padding-large-horizontal;\n    font-size: @font-size-large;\n    line-height: @line-height-large;\n  }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2; // Ensure icon is above input groups\n  display: block;\n  width: @input-height-base;\n  height: @input-height-base;\n  line-height: @input-height-base;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: @input-height-large;\n  height: @input-height-large;\n  line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: @input-height-small;\n  height: @input-height-small;\n  line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n  & ~ .form-control-feedback {\n    top: (@line-height-computed + 5); // Height of the `label` and its margin\n  }\n  &.sr-only ~ .form-control-feedback {\n    top: 0;\n  }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n\n    // Make static controls behave like regular ones\n    .form-control-static {\n      display: inline-block;\n    }\n\n    .input-group {\n      display: inline-table;\n      vertical-align: middle;\n\n      .input-group-addon,\n      .input-group-btn,\n      .form-control {\n        width: auto;\n      }\n    }\n\n    // Input groups need that 100% width though\n    .input-group > .form-control {\n      width: 100%;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match.\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      vertical-align: middle;\n\n      label {\n        padding-left: 0;\n      }\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      position: relative;\n      margin-left: 0;\n    }\n\n    // Re-override the feedback icon.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of radios and checkboxes\n  //\n  // Labels also get some reset styles, but that is scoped to a media query below.\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  // Reset spacing and right align labels, but scope to media queries so that\n  // labels on narrow viewports stack the same as a default form example.\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n      margin-bottom: 0;\n      padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    right: floor((@grid-gutter-width / 2));\n  }\n\n  // Form group sizes\n  //\n  // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n  // inputs and labels within a `.form-group`.\n  .form-group-lg {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: (@padding-large-vertical + 1);\n        font-size: @font-size-large;\n      }\n    }\n  }\n  .form-group-sm {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: (@padding-small-vertical + 1);\n        font-size: @font-size-small;\n      }\n    }\n  }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline,\n  &.radio label,\n  &.checkbox label,\n  &.radio-inline label,\n  &.checkbox-inline label  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n  // Optional feedback icon\n  .form-control-feedback {\n    color: @text-color;\n  }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n  .user-select(none);\n\n  &,\n  &:active,\n  &.active {\n    &:focus,\n    &.focus {\n      .tab-focus();\n    }\n  }\n\n  &:hover,\n  &:focus,\n  &.focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n    .opacity(.65);\n    .box-shadow(none);\n  }\n\n  a& {\n    &.disabled,\n    fieldset[disabled] & {\n      pointer-events: none; // Future-proof disabling of clicks on `<a>` elements\n    }\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &.active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: @link-hover-decoration;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:focus,\n  &.focus {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 25%);\n  }\n  &:hover {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 12%);\n\n    &:hover,\n    &:focus,\n    &.focus {\n      color: @color;\n      background-color: darken(@background, 17%);\n          border-color: darken(@border, 25%);\n    }\n  }\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus,\n    &.focus {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: @color;\n  }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n\n  &.in      { display: block; }\n  tr&.in    { display: table-row; }\n  tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition-property(~\"height, visibility\");\n  .transition-duration(.35s);\n  .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base dashed;\n  border-top:   @caret-width-base solid ~\"\\9\"; // IE8\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n\n  // Nuke hover/focus effects\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: @cursor-disabled;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n  white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base dashed;\n    border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 2px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn,\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    .border-top-radius(@btn-border-radius-base);\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    .border-top-radius(0);\n    .border-bottom-radius(@btn-border-radius-base);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n\n  > .btn-group .dropdown-menu {\n    left: auto;\n  }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n  > .btn,\n  > .btn-group > .btn {\n    input[type=\"radio\"],\n    input[type=\"checkbox\"] {\n      position: absolute;\n      clip: rect(0,0,0,0);\n      pointer-events: none;\n    }\n  }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // Ensure that the input is always above the *appended* addon button for\n    // proper border colors.\n    position: relative;\n    z-index: 2;\n\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n\n    &:focus {\n      z-index: 3;\n    }\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @input-border-radius;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @input-border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @input-border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      z-index: 2;\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: @cursor-disabled;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n    > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  .navbar-collapse {\n    max-height: @navbar-collapse-max-height;\n\n    @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n      max-height: 200px;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: -@navbar-padding-horizontal;\n    margin-left:  -@navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @navbar-height;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  > img {\n    display: block;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: 0;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n  }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n\n      &:last-child {\n        margin-bottom: 0;\n      }\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  .border-top-radius(@navbar-border-radius);\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right {\n    .pull-right();\n    margin-right: -@navbar-padding-horizontal;\n\n    ~ .navbar-right {\n      margin-right: 0;\n    }\n  }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-default-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n      }\n    }\n  }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-inverse-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n      }\n    }\n  }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 3;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n      line-height: @line-height;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n  background-color: @color;\n\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: middle;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n\n  .btn-xs &,\n  .btn-group-xs > .btn & {\n    top: 0;\n    padding: 1px 5px;\n  }\n\n  // Hover state, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @badge-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Account for badges in navs\n  .list-group-item.active > &,\n  .nav-pills > .active > a > & {\n    color: @badge-active-color;\n    background-color: @badge-active-bg;\n  }\n\n  .list-group-item > & {\n    float: right;\n  }\n\n  .list-group-item > & + & {\n    margin-right: 5px;\n  }\n\n  .nav-pills > li > a > & {\n    margin-left: 3px;\n  }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding-top:    @jumbotron-padding;\n  padding-bottom: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  > hr {\n    border-top-color: darken(@jumbotron-bg, 10%);\n  }\n\n  .container &,\n  .container-fluid & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n    padding-left:  (@grid-gutter-width / 2);\n    padding-right: (@grid-gutter-width / 2);\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container &,\n    .container-fluid & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: @jumbotron-heading-font-size;\n    }\n  }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(border .2s ease-in-out);\n\n  > img,\n  a > img {\n    &:extend(.img-responsive);\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n  padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @progress-border-radius;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n  background-color: @color;\n\n  // Deprecated parent class requirement as of v3.2.0\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n",".media {\n  // Proper spacing between instances of .media\n  margin-top: 15px;\n\n  &:first-child {\n    margin-top: 0;\n  }\n}\n\n.media,\n.media-body {\n  zoom: 1;\n  overflow: hidden;\n}\n\n.media-body {\n  width: 10000px;\n}\n\n.media-object {\n  display: block;\n\n  // Fix collapse in webkit from max-width: 100% and display: table-cell.\n  &.img-thumbnail {\n    max-width: none;\n  }\n}\n\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n\n.media-middle {\n  vertical-align: middle;\n}\n\n.media-bottom {\n  vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  // No need to set list-style: none; since .list-group-item is block level\n  margin-bottom: 20px;\n  padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  // Place the border on the list items and negative margin up for better styling\n  margin-bottom: -1px;\n  background-color: @list-group-bg;\n  border: 1px solid @list-group-border;\n\n  // Round the first and last items\n  &:first-child {\n    .border-top-radius(@list-group-border-radius);\n  }\n  &:last-child {\n    margin-bottom: 0;\n    .border-bottom-radius(@list-group-border-radius);\n  }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n  color: @list-group-link-color;\n\n  .list-group-item-heading {\n    color: @list-group-link-heading-color;\n  }\n\n  // Hover state\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @list-group-link-hover-color;\n    background-color: @list-group-hover-bg;\n  }\n}\n\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n\n.list-group-item {\n  // Disabled state\n  &.disabled,\n  &.disabled:hover,\n  &.disabled:focus {\n    background-color: @list-group-disabled-bg;\n    color: @list-group-disabled-color;\n    cursor: @cursor-disabled;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-disabled-text-color;\n    }\n  }\n\n  // Active class on item itself, not parent\n  &.active,\n  &.active:hover,\n  &.active:focus {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: @list-group-active-color;\n    background-color: @list-group-active-bg;\n    border-color: @list-group-active-border;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading,\n    .list-group-item-heading > small,\n    .list-group-item-heading > .small {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-active-text-color;\n    }\n  }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n  .list-group-item-@{state} {\n    color: @color;\n    background-color: @background;\n\n    a&,\n    button& {\n      color: @color;\n\n      .list-group-item-heading {\n        color: inherit;\n      }\n\n      &:hover,\n      &:focus {\n        color: @color;\n        background-color: darken(@background, 5%);\n      }\n      &.active,\n      &.active:hover,\n      &.active:focus {\n        color: #fff;\n        background-color: @color;\n        border-color: @color;\n      }\n    }\n  }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: @line-height-computed;\n  background-color: @panel-bg;\n  border: 1px solid transparent;\n  border-radius: @panel-border-radius;\n  .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n  padding: @panel-body-padding;\n  &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n  padding: @panel-heading-padding;\n  border-bottom: 1px solid transparent;\n  .border-top-radius((@panel-border-radius - 1));\n\n  > .dropdown .dropdown-toggle {\n    color: inherit;\n  }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: ceil((@font-size-base * 1.125));\n  color: inherit;\n\n  > a,\n  > small,\n  > .small,\n  > small > a,\n  > .small > a {\n    color: inherit;\n  }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n  padding: @panel-footer-padding;\n  background-color: @panel-footer-bg;\n  border-top: 1px solid @panel-inner-border;\n  .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n  > .list-group,\n  > .panel-collapse > .list-group {\n    margin-bottom: 0;\n\n    .list-group-item {\n      border-width: 1px 0;\n      border-radius: 0;\n    }\n\n    // Add border top radius for first one\n    &:first-child {\n      .list-group-item:first-child {\n        border-top: 0;\n        .border-top-radius((@panel-border-radius - 1));\n      }\n    }\n\n    // Add border bottom radius for last one\n    &:last-child {\n      .list-group-item:last-child {\n        border-bottom: 0;\n        .border-bottom-radius((@panel-border-radius - 1));\n      }\n    }\n  }\n  > .panel-heading + .panel-collapse > .list-group {\n    .list-group-item:first-child {\n      .border-top-radius(0);\n    }\n  }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n  .list-group-item:first-child {\n    border-top-width: 0;\n  }\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n  > .table,\n  > .table-responsive > .table,\n  > .panel-collapse > .table {\n    margin-bottom: 0;\n\n    caption {\n      padding-left: @panel-body-padding;\n      padding-right: @panel-body-padding;\n    }\n  }\n  // Add border top radius for first one\n  > .table:first-child,\n  > .table-responsive:first-child > .table:first-child {\n    .border-top-radius((@panel-border-radius - 1));\n\n    > thead:first-child,\n    > tbody:first-child {\n      > tr:first-child {\n        border-top-left-radius: (@panel-border-radius - 1);\n        border-top-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-top-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-top-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  // Add border bottom radius for last one\n  > .table:last-child,\n  > .table-responsive:last-child > .table:last-child {\n    .border-bottom-radius((@panel-border-radius - 1));\n\n    > tbody:last-child,\n    > tfoot:last-child {\n      > tr:last-child {\n        border-bottom-left-radius: (@panel-border-radius - 1);\n        border-bottom-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-bottom-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-bottom-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  > .panel-body + .table,\n  > .panel-body + .table-responsive,\n  > .table + .panel-body,\n  > .table-responsive + .panel-body {\n    border-top: 1px solid @table-border-color;\n  }\n  > .table > tbody:first-child > tr:first-child th,\n  > .table > tbody:first-child > tr:first-child td {\n    border-top: 0;\n  }\n  > .table-bordered,\n  > .table-responsive > .table-bordered {\n    border: 0;\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th:first-child,\n        > td:first-child {\n          border-left: 0;\n        }\n        > th:last-child,\n        > td:last-child {\n          border-right: 0;\n        }\n      }\n    }\n    > thead,\n    > tbody {\n      > tr:first-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n    > tbody,\n    > tfoot {\n      > tr:last-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n  }\n  > .table-responsive {\n    border: 0;\n    margin-bottom: 0;\n  }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n  margin-bottom: @line-height-computed;\n\n  // Tighten up margin so it's only between panels\n  .panel {\n    margin-bottom: 0;\n    border-radius: @panel-border-radius;\n\n    + .panel {\n      margin-top: 5px;\n    }\n  }\n\n  .panel-heading {\n    border-bottom: 0;\n\n    + .panel-collapse > .panel-body,\n    + .panel-collapse > .list-group {\n      border-top: 1px solid @panel-inner-border;\n    }\n  }\n\n  .panel-footer {\n    border-top: 0;\n    + .panel-collapse .panel-body {\n      border-bottom: 1px solid @panel-inner-border;\n    }\n  }\n}\n\n\n// Contextual variations\n.panel-default {\n  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse > .panel-body {\n      border-top-color: @border;\n    }\n    .badge {\n      color: @heading-bg-color;\n      background-color: @heading-text-color;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse > .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n\n  .embed-responsive-item,\n  iframe,\n  embed,\n  object,\n  video {\n    position: absolute;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    height: 100%;\n    width: 100%;\n    border: 0;\n  }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: @well-bg;\n  border: 1px solid @well-border;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n  blockquote {\n    border-color: #ddd;\n    border-color: rgba(0,0,0,.15);\n  }\n}\n\n// Sizes\n.well-lg {\n  padding: 24px;\n  border-radius: @border-radius-large;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: (@font-size-base * 1.5);\n  font-weight: @close-font-weight;\n  line-height: 1;\n  color: @close-color;\n  text-shadow: @close-text-shadow;\n  .opacity(.2);\n\n  &:hover,\n  &:focus {\n    color: @close-color;\n    text-decoration: none;\n    cursor: pointer;\n    .opacity(.5);\n  }\n\n  // Additional properties for button version\n  // iOS requires the button element instead of an anchor tag.\n  // If you want the anchor version, it requires `href=\"#\"`.\n  // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n  button& {\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n  }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal;\n  -webkit-overflow-scrolling: touch;\n\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~\"0.3s ease-out\");\n  }\n  &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal-background;\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  padding: @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-group .btn + .btn {\n    margin-left: -1px;\n  }\n  // and override it for block buttons as well\n  .btn-block + .btn-block {\n    margin-left: 0;\n  }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    width: @modal-md;\n    margin: 30px auto;\n  }\n  .modal-content {\n    .box-shadow(0 5px 15px rgba(0,0,0,.5));\n  }\n\n  // Modal sizes\n  .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n  .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  z-index: @zindex-tooltip;\n  display: block;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  .reset-text();\n  font-size: @font-size-small;\n\n  .opacity(0);\n\n  &.in     { .opacity(@tooltip-opacity); }\n  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }\n  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }\n  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }\n  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: @tooltip-max-width;\n  padding: 3px 8px;\n  color: @tooltip-color;\n  text-align: center;\n  background-color: @tooltip-bg;\n  border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n  &.top .tooltip-arrow {\n    bottom: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-left .tooltip-arrow {\n    bottom: 0;\n    right: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-right .tooltip-arrow {\n    bottom: 0;\n    left: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.right .tooltip-arrow {\n    top: 50%;\n    left: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-right-color: @tooltip-arrow-color;\n  }\n  &.left .tooltip-arrow {\n    top: 50%;\n    right: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-left-color: @tooltip-arrow-color;\n  }\n  &.bottom .tooltip-arrow {\n    top: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-left .tooltip-arrow {\n    top: 0;\n    right: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-right .tooltip-arrow {\n    top: 0;\n    left: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n}\n",".reset-text() {\n  font-family: @font-family-base;\n  // We deliberately do NOT reset font-size.\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: @line-height-base;\n  text-align: left; // Fallback for where `start` is not supported\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: @zindex-popover;\n  display: none;\n  max-width: @popover-max-width;\n  padding: 1px;\n  // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  .reset-text();\n  font-size: @font-size-base;\n\n  background-color: @popover-bg;\n  background-clip: padding-box;\n  border: 1px solid @popover-fallback-border-color;\n  border: 1px solid @popover-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n  // Offset the popover to account for the popover arrow\n  &.top     { margin-top: -@popover-arrow-width; }\n  &.right   { margin-left: @popover-arrow-width; }\n  &.bottom  { margin-top: @popover-arrow-width; }\n  &.left    { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n  margin: 0; // reset heading margin\n  padding: 8px 14px;\n  font-size: @font-size-base;\n  background-color: @popover-title-bg;\n  border-bottom: 1px solid darken(@popover-title-bg, 5%);\n  border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n  &,\n  &:after {\n    position: absolute;\n    display: block;\n    width: 0;\n    height: 0;\n    border-color: transparent;\n    border-style: solid;\n  }\n}\n.popover > .arrow {\n  border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n  border-width: @popover-arrow-width;\n  content: \"\";\n}\n\n.popover {\n  &.top > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-bottom-width: 0;\n    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-top-color: @popover-arrow-outer-color;\n    bottom: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      bottom: 1px;\n      margin-left: -@popover-arrow-width;\n      border-bottom-width: 0;\n      border-top-color: @popover-arrow-color;\n    }\n  }\n  &.right > .arrow {\n    top: 50%;\n    left: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-left-width: 0;\n    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-right-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      left: 1px;\n      bottom: -@popover-arrow-width;\n      border-left-width: 0;\n      border-right-color: @popover-arrow-color;\n    }\n  }\n  &.bottom > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-top-width: 0;\n    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-bottom-color: @popover-arrow-outer-color;\n    top: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      top: 1px;\n      margin-left: -@popover-arrow-width;\n      border-top-width: 0;\n      border-bottom-color: @popover-arrow-color;\n    }\n  }\n\n  &.left > .arrow {\n    top: 50%;\n    right: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-right-width: 0;\n    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-left-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      right: 1px;\n      border-right-width: 0;\n      border-left-color: @popover-arrow-color;\n      bottom: -@popover-arrow-width;\n    }\n  }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      &:extend(.img-responsive);\n      line-height: 1;\n    }\n\n    // WebKit CSS3 transforms for supported devices\n    @media all and (transform-3d), (-webkit-transform-3d) {\n      .transition-transform(~'0.6s ease-in-out');\n      .backface-visibility(~'hidden');\n      .perspective(1000px);\n\n      &.next,\n      &.active.right {\n        .translate3d(100%, 0, 0);\n        left: 0;\n      }\n      &.prev,\n      &.active.left {\n        .translate3d(-100%, 0, 0);\n        left: 0;\n      }\n      &.next.left,\n      &.prev.right,\n      &.active {\n        .translate3d(0, 0, 0);\n        left: 0;\n      }\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev {\n    display: block;\n  }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: 0;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    margin-top: -10px;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n    margin-left: -10px;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n    margin-right: -10px;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    line-height: 1;\n    font-family: serif;\n  }\n\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicon-chevron-left,\n    .glyphicon-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: (@carousel-control-font-size * 1.5);\n      height: (@carousel-control-font-size * 1.5);\n      margin-top: (@carousel-control-font-size / -2);\n      font-size: (@carousel-control-font-size * 1.5);\n    }\n    .glyphicon-chevron-left,\n    .icon-prev {\n      margin-left: (@carousel-control-font-size / -2);\n    }\n    .glyphicon-chevron-right,\n    .icon-next {\n      margin-right: (@carousel-control-font-size / -2);\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n","// Center-align a block level element\n\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n  width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n\n.visible-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-visibility();\n  }\n}\n.visible-xs-block {\n  @media (max-width: @screen-xs-max) {\n    display: block !important;\n  }\n}\n.visible-xs-inline {\n  @media (max-width: @screen-xs-max) {\n    display: inline !important;\n  }\n}\n.visible-xs-inline-block {\n  @media (max-width: @screen-xs-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-visibility();\n  }\n}\n.visible-sm-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: block !important;\n  }\n}\n.visible-sm-inline {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline !important;\n  }\n}\n.visible-sm-inline-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-visibility();\n  }\n}\n.visible-md-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: block !important;\n  }\n}\n.visible-md-inline {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline !important;\n  }\n}\n.visible-md-inline-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-visibility();\n  }\n}\n.visible-lg-block {\n  @media (min-width: @screen-lg-min) {\n    display: block !important;\n  }\n}\n.visible-lg-inline {\n  @media (min-width: @screen-lg-min) {\n    display: inline !important;\n  }\n}\n.visible-lg-inline-block {\n  @media (min-width: @screen-lg-min) {\n    display: inline-block !important;\n  }\n}\n\n.hidden-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-invisibility();\n  }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n  .responsive-invisibility();\n\n  @media print {\n    .responsive-visibility();\n  }\n}\n.visible-print-block {\n  display: none !important;\n\n  @media print {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n\n  @media print {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n\n  @media print {\n    display: inline-block !important;\n  }\n}\n\n.hidden-print {\n  @media print {\n    .responsive-invisibility();\n  }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table !important; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n  display: none !important;\n}\n"]}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap.min.css b/blockly/webif/static/css/bootstrap.min.css
                new file mode 100644
                index 000000000..ed3905e0e
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap.min.css
                @@ -0,0 +1,6 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
                +/*# sourceMappingURL=bootstrap.min.css.map */
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/bootstrap.min.css.map b/blockly/webif/static/css/bootstrap.min.css.map
                new file mode 100644
                index 000000000..6c7fa40b9
                --- /dev/null
                +++ b/blockly/webif/static/css/bootstrap.min.css.map
                @@ -0,0 +1 @@
                +{"version":3,"sources":["less/normalize.less","less/print.less","bootstrap.css","dist/css/bootstrap.css","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":";;;;4EAQA,KACE,YAAA,WACA,yBAAA,KACA,qBAAA,KAOF,KACE,OAAA,EAaF,QAAA,MAAA,QAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,KAAA,IAAA,QAAA,QAaE,QAAA,MAQF,MAAA,OAAA,SAAA,MAIE,QAAA,aACA,eAAA,SAQF,sBACE,QAAA,KACA,OAAA,EAQF,SAAA,SAEE,QAAA,KAUF,EACE,iBAAA,YAQF,SAAA,QAEE,QAAA,EAUF,YACE,cAAA,IAAA,OAOF,EAAA,OAEE,YAAA,IAOF,IACE,WAAA,OAQF,GACE,OAAA,MAAA,EACA,UAAA,IAOF,KACE,MAAA,KACA,WAAA,KAOF,MACE,UAAA,IAOF,IAAA,IAEE,SAAA,SACA,UAAA,IACA,YAAA,EACA,eAAA,SAGF,IACE,IAAA,MAGF,IACE,OAAA,OAUF,IACE,OAAA,EAOF,eACE,SAAA,OAUF,OACE,OAAA,IAAA,KAOF,GACE,OAAA,EAAA,mBAAA,YAAA,gBAAA,YACA,WAAA,YAOF,IACE,SAAA,KAOF,KAAA,IAAA,IAAA,KAIE,YAAA,UAAA,UACA,UAAA,IAkBF,OAAA,MAAA,SAAA,OAAA,SAKE,OAAA,EACA,KAAA,QACA,MAAA,QAOF,OACE,SAAA,QAUF,OAAA,OAEE,eAAA,KAWF,OAAA,wBAAA,kBAAA,mBAIE,mBAAA,OACA,OAAA,QAOF,iBAAA,qBAEE,OAAA,QAOF,yBAAA,wBAEE,QAAA,EACA,OAAA,EAQF,MACE,YAAA,OAWF,qBAAA,kBAEE,mBAAA,WAAA,gBAAA,WAAA,WAAA,WACA,QAAA,EASF,8CAAA,8CAEE,OAAA,KAQF,mBACE,mBAAA,YACA,gBAAA,YAAA,WAAA,YAAA,mBAAA,UASF,iDAAA,8CAEE,mBAAA,KAOF,SACE,QAAA,MAAA,OAAA,MACA,OAAA,EAAA,IACA,OAAA,IAAA,MAAA,OAQF,OACE,QAAA,EACA,OAAA,EAOF,SACE,SAAA,KAQF,SACE,YAAA,IAUF,MACE,eAAA,EACA,gBAAA,SAGF,GAAA,GAEE,QAAA,uFCjUF,aA7FI,EAAA,OAAA,QAGI,MAAA,eACA,YAAA,eACA,WAAA,cAAA,mBAAA,eACA,WAAA,eAGJ,EAAA,UAEI,gBAAA,UAGJ,cACI,QAAA,KAAA,WAAA,IAGJ,kBACI,QAAA,KAAA,YAAA,IAKJ,6BAAA,mBAEI,QAAA,GAGJ,WAAA,IAEI,OAAA,IAAA,MAAA,KC4KL,kBAAA,MDvKK,MC0KL,QAAA,mBDrKK,IE8KN,GDLC,kBAAA,MDrKK,ICwKL,UAAA,eCUD,GF5KM,GE2KN,EF1KM,QAAA,ECuKL,OAAA,ECSD,GF3KM,GCsKL,iBAAA,MD/JK,QCkKL,QAAA,KCSD,YFtKU,oBCiKT,iBAAA,eD7JK,OCgKL,OAAA,IAAA,MAAA,KD5JK,OC+JL,gBAAA,mBCSD,UFpKU,UC+JT,iBAAA,eDzJS,mBEkKV,mBDLC,OAAA,IAAA,MAAA,gBEjPD,WACA,YAAA,uBFsPD,IAAA,+CE7OC,IAAK,sDAAuD,4BAA6B,iDAAkD,gBAAiB,gDAAiD,eAAgB,+CAAgD,mBAAoB,2EAA4E,cAE7W,WACA,SAAA,SACA,IAAA,IACA,QAAA,aACA,YAAA,uBACA,WAAA,OACA,YAAA,IACA,YAAA,EAIkC,uBAAA,YAAW,wBAAA,UACX,2BAAW,QAAA,QAEX,uBDuPlC,QAAS,QCtPyB,sBFiPnC,uBEjP8C,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,qBAAW,QAAA,QACX,0BAAW,QAAA,QACX,qBAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,sBAAW,QAAA,QACX,yBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,+BAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,gCAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,gCAAW,QAAA,QACX,gCAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,0BAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,mCAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,sBAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,0BAAW,QAAA,QACX,4BAAW,QAAA,QACX,qCAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,mCAAW,QAAA,QACX,uCAAW,QAAA,QACX,gCAAW,QAAA,QACX,oCAAW,QAAA,QACX,qCAAW,QAAA,QACX,yCAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,iCAAW,QAAA,QACX,oCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,qBAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QASX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,+BAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,mCAAW,QAAA,QACX,4BAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,kCAAW,QAAA,QACX,mCAAW,QAAA,QACX,sCAAW,QAAA,QACX,0CAAW,QAAA,QACX,oCAAW,QAAA,QACX,wCAAW,QAAA,QACX,qCAAW,QAAA,QACX,iCAAW,QAAA,QACX,gCAAW,QAAA,QACX,kCAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QCtS/C,0BCgEE,QAAA,QHi+BF,EDNC,mBAAA,WGxhCI,gBAAiB,WFiiCZ,WAAY,WGl+BZ,OADL,QJg+BJ,mBAAA,WGthCI,gBAAiB,WACpB,WAAA,WHyhCD,KGrhCC,UAAW,KAEX,4BAAA,cAEA,KACA,YAAA,iBAAA,UAAA,MAAA,WHuhCD,UAAA,KGnhCC,YAAa,WF4hCb,MAAO,KACP,iBAAkB,KExhClB,OADA,MAEA,OHqhCD,SG/gCC,YAAa,QACb,UAAA,QACA,YAAA,QAEA,EFwhCA,MAAO,QEthCL,gBAAA,KAIF,QH8gCD,QKjkCC,MAAA,QACA,gBAAA,UF6DF,QACE,QAAA,IAAA,KAAA,yBHygCD,eAAA,KGlgCC,OHqgCD,OAAA,ECSD,IACE,eAAgB,ODDjB,4BM/kCC,0BLklCF,gBKnlCE,iBADA,eH4EA,QAAS,MACT,UAAA,KHugCD,OAAA,KGhgCC,aACA,cAAA,IAEA,eACA,QAAA,aC6FA,UAAA,KACK,OAAA,KACG,QAAA,IEvLR,YAAA,WACA,iBAAA,KACA,OAAA,IAAA,MAAA,KN+lCD,cAAA,IGjgCC,mBAAoB,IAAI,IAAI,YAC5B,cAAA,IAAA,IAAA,YHmgCD,WAAA,IAAA,IAAA,YG5/BC,YACA,cAAA,IAEA,GH+/BD,WAAA,KGv/BC,cAAe,KACf,OAAA,EACA,WAAA,IAAA,MAAA,KAEA,SACA,SAAA,SACA,MAAA,IACA,OAAA,IACA,QAAA,EHy/BD,OAAA,KGj/BC,SAAA,OF0/BA,KAAM,cEx/BJ,OAAA,EAEA,0BACA,yBACA,SAAA,OACA,MAAA,KHm/BH,OAAA,KGx+BC,OAAQ,EACR,SAAA,QH0+BD,KAAA,KCSD,cACE,OAAQ,QAQV,IACA,IMlpCE,IACA,IACA,IACA,INwoCF,GACA,GACA,GACA,GACA,GACA,GDAC,YAAA,QOlpCC,YAAa,IN2pCb,YAAa,IACb,MAAO,QAoBT,WAZA,UAaA,WAZA,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UDMC,WCLD,UACA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SMppCE,YAAa,INwqCb,YAAa,EACb,MAAO,KAGT,IMxqCE,IAJF,IN2qCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UM5qCA,WN8qCA,UACA,UANA,SM5qCI,UN8qCJ,SM3qCA,UN6qCA,SAQE,UAAW,IAGb,IMprCE,IAJF,INurCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UMvrCA,WNyrCA,UACA,UANA,SMxrCI,UN0rCJ,SMtrCA,UNwrCA,SMxrCU,UAAA,IACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KAOR,IADF,GPssCC,UAAA,KCSD,EMzsCE,OAAA,EAAA,EAAA,KAEA,MPosCD,cAAA,KO/rCC,UAAW,KAwOX,YAAa,IA1OX,YAAA,IPssCH,yBO7rCC,MNssCE,UAAW,MMjsCf,OAAA,MAEE,UAAA,IAKF,MP0rCC,KO1rCsB,QAAA,KP6rCtB,iBAAA,QO5rCsB,WP+rCtB,WAAA,KO9rCsB,YPisCtB,WAAA,MOhsCsB,aPmsCtB,WAAA,OOlsCsB,cPqsCtB,WAAA,QOlsCsB,aPqsCtB,YAAA,OOpsCsB,gBPusCtB,eAAA,UOtsCsB,gBPysCtB,eAAA,UOrsCC,iBPwsCD,eAAA,WQ3yCC,YR8yCD,MAAA,KCSD,cOpzCI,MAAA,QAHF,qBDwGF,qBP6sCC,MAAA,QCSD,cO3zCI,MAAA,QAHF,qBD2GF,qBPitCC,MAAA,QCSD,WOl0CI,MAAA,QAHF,kBD8GF,kBPqtCC,MAAA,QCSD,cOz0CI,MAAA,QAHF,qBDiHF,qBPytCC,MAAA,QCSD,aOh1CI,MAAA,QDwHF,oBAHF,oBExHE,MAAA,QACA,YR01CA,MAAO,KQx1CL,iBAAA,QAHF,mBF8HF,mBP2tCC,iBAAA,QCSD,YQ/1CI,iBAAA,QAHF,mBFiIF,mBP+tCC,iBAAA,QCSD,SQt2CI,iBAAA,QAHF,gBFoIF,gBPmuCC,iBAAA,QCSD,YQ72CI,iBAAA,QAHF,mBFuIF,mBPuuCC,iBAAA,QCSD,WQp3CI,iBAAA,QF6IF,kBADF,kBAEE,iBAAA,QPsuCD,aO7tCC,eAAgB,INsuChB,OAAQ,KAAK,EAAE,KMpuCf,cAAA,IAAA,MAAA,KAFF,GPkuCC,GCSC,WAAY,EACZ,cAAe,KM9tCf,MP0tCD,MO3tCD,MAPI,MASF,cAAA,EAIF,eALE,aAAA,EACA,WAAA,KPkuCD,aO9tCC,aAAc,EAKZ,YAAA,KACA,WAAA,KP6tCH,gBOvtCC,QAAS,aACT,cAAA,IACA,aAAA,IAEF,GNguCE,WAAY,EM9tCZ,cAAA,KAGA,GADF,GP0tCC,YAAA,WOttCC,GPytCD,YAAA,IOnnCD,GAvFM,YAAA,EAEA,yBACA,kBGtNJ,MAAA,KACA,MAAA,MACA,SAAA,OVq6CC,MAAA,KO7nCC,WAAY,MAhFV,cAAA,SPgtCH,YAAA,OOtsCD,kBNgtCE,YAAa,OM1sCjB,0BPssCC,YOrsCC,OAAA,KA9IqB,cAAA,IAAA,OAAA,KAmJvB,YACE,UAAA,IACA,eAAA,UAEA,WPssCD,QAAA,KAAA,KOjsCG,OAAA,EAAA,EAAA,KN0sCF,UAAW,OACX,YAAa,IAAI,MAAM,KMptCzB,yBP+sCC,wBO/sCD,yBNytCE,cAAe,EMnsCb,kBAFA,kBACA,iBPksCH,QAAA,MO/rCG,UAAA,INwsCF,YAAa,WACb,MAAO,KMhsCT,yBP2rCC,yBO3rCD,wBAEE,QAAA,cAEA,oBACA,sBACA,cAAA,KP6rCD,aAAA,EOvrCG,WAAA,MNgsCF,aAAc,IAAI,MAAM,KACxB,YAAa,EMhsCX,kCNksCJ,kCMnsCe,iCACX,oCNmsCJ,oCDLC,mCCUC,QAAS,GMjsCX,iCNmsCA,iCMzsCM,gCAOJ,mCNmsCF,mCDLC,kCO7rCC,QAAA,cPksCD,QWv+CC,cAAe,KVg/Cf,WAAY,OACZ,YAAa,WU7+Cb,KXy+CD,IWr+CD,IACE,KACA,YAAA,MAAA,OAAA,SAAA,cAAA,UAEA,KACA,QAAA,IAAA,IXu+CD,UAAA,IWn+CC,MAAO,QACP,iBAAA,QACA,cAAA,IAEA,IACA,QAAA,IAAA,IACA,UAAA,IV4+CA,MU5+CA,KXq+CD,iBAAA,KW3+CC,cAAe,IASb,mBAAA,MAAA,EAAA,KAAA,EAAA,gBACA,WAAA,MAAA,EAAA,KAAA,EAAA,gBAEA,QV6+CF,QU7+CE,EXq+CH,UAAA,KWh+CC,YAAa,IACb,mBAAA,KACA,WAAA,KAEA,IACA,QAAA,MACA,QAAA,MACA,OAAA,EAAA,EAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,WAAA,UXk+CD,UAAA,WW7+CC,iBAAkB,QAehB,OAAA,IAAA,MAAA,KACA,cAAA,IAEA,SACA,QAAA,EACA,UAAA,QXi+CH,MAAA,QW59CC,YAAa,SACb,iBAAA,YACA,cAAA,EC1DF,gBCHE,WAAA,MACA,WAAA,OAEA,Wb8hDD,cAAA,KYxhDC,aAAA,KAqEA,aAAc,KAvEZ,YAAA,KZ+hDH,yBY1hDC,WAkEE,MAAO,OZ69CV,yBY5hDC,WA+DE,MAAO,OZk+CV,0BYzhDC,WCvBA,MAAA,QAGA,iBbmjDD,cAAA,KYthDC,aAAc,KCvBd,aAAA,KACA,YAAA,KCAE,KACE,aAAA,MAEA,YAAA,MAGA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UdgjDL,SAAA,SchiDG,WAAA,IACE,cAAA,KdkiDL,aAAA,Kc1hDG,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud6hDH,MAAA,Kc7hDG,WdgiDH,MAAA,KchiDG,WdmiDH,MAAA,acniDG,WdsiDH,MAAA,actiDG,UdyiDH,MAAA,IcziDG,Ud4iDH,MAAA,ac5iDG,Ud+iDH,MAAA,ac/iDG,UdkjDH,MAAA,IcljDG,UdqjDH,MAAA,acrjDG,UdwjDH,MAAA,acxjDG,Ud2jDH,MAAA,Ic3jDG,Ud8jDH,MAAA,ac/iDG,UdkjDH,MAAA,YcljDG,gBdqjDH,MAAA,KcrjDG,gBdwjDH,MAAA,acxjDG,gBd2jDH,MAAA,ac3jDG,ed8jDH,MAAA,Ic9jDG,edikDH,MAAA,acjkDG,edokDH,MAAA,acpkDG,edukDH,MAAA,IcvkDG,ed0kDH,MAAA,ac1kDG,ed6kDH,MAAA,ac7kDG,edglDH,MAAA,IchlDG,edmlDH,MAAA,ac9kDG,edilDH,MAAA,YchmDG,edmmDH,MAAA,KcnmDG,gBdsmDH,KAAA,KctmDG,gBdymDH,KAAA,aczmDG,gBd4mDH,KAAA,ac5mDG,ed+mDH,KAAA,Ic/mDG,edknDH,KAAA,aclnDG,edqnDH,KAAA,acrnDG,edwnDH,KAAA,IcxnDG,ed2nDH,KAAA,ac3nDG,ed8nDH,KAAA,ac9nDG,edioDH,KAAA,IcjoDG,edooDH,KAAA,ac/nDG,edkoDH,KAAA,YcnnDG,edsnDH,KAAA,KctnDG,kBdynDH,YAAA,KcznDG,kBd4nDH,YAAA,ac5nDG,kBd+nDH,YAAA,ac/nDG,iBdkoDH,YAAA,IcloDG,iBdqoDH,YAAA,acroDG,iBdwoDH,YAAA,acxoDG,iBd2oDH,YAAA,Ic3oDG,iBd8oDH,YAAA,ac9oDG,iBdipDH,YAAA,acjpDG,iBdopDH,YAAA,IcppDG,iBdupDH,YAAA,acvpDG,iBd0pDH,YAAA,Yc5rDG,iBACE,YAAA,EAOJ,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud0rDD,MAAA,Kc1rDC,Wd6rDD,MAAA,Kc7rDC,WdgsDD,MAAA,achsDC,WdmsDD,MAAA,acnsDC,UdssDD,MAAA,IctsDC,UdysDD,MAAA,aczsDC,Ud4sDD,MAAA,ac5sDC,Ud+sDD,MAAA,Ic/sDC,UdktDD,MAAA,acltDC,UdqtDD,MAAA,acrtDC,UdwtDD,MAAA,IcxtDC,Ud2tDD,MAAA,ac5sDC,Ud+sDD,MAAA,Yc/sDC,gBdktDD,MAAA,KcltDC,gBdqtDD,MAAA,acrtDC,gBdwtDD,MAAA,acxtDC,ed2tDD,MAAA,Ic3tDC,ed8tDD,MAAA,ac9tDC,ediuDD,MAAA,acjuDC,edouDD,MAAA,IcpuDC,eduuDD,MAAA,acvuDC,ed0uDD,MAAA,ac1uDC,ed6uDD,MAAA,Ic7uDC,edgvDD,MAAA,ac3uDC,ed8uDD,MAAA,Yc7vDC,edgwDD,MAAA,KchwDC,gBdmwDD,KAAA,KcnwDC,gBdswDD,KAAA,actwDC,gBdywDD,KAAA,aczwDC,ed4wDD,KAAA,Ic5wDC,ed+wDD,KAAA,ac/wDC,edkxDD,KAAA,aclxDC,edqxDD,KAAA,IcrxDC,edwxDD,KAAA,acxxDC,ed2xDD,KAAA,ac3xDC,ed8xDD,KAAA,Ic9xDC,ediyDD,KAAA,ac5xDC,ed+xDD,KAAA,YchxDC,edmxDD,KAAA,KcnxDC,kBdsxDD,YAAA,KctxDC,kBdyxDD,YAAA,aczxDC,kBd4xDD,YAAA,ac5xDC,iBd+xDD,YAAA,Ic/xDC,iBdkyDD,YAAA,aclyDC,iBdqyDD,YAAA,acryDC,iBdwyDD,YAAA,IcxyDC,iBd2yDD,YAAA,ac3yDC,iBd8yDD,YAAA,ac9yDC,iBdizDD,YAAA,IcjzDC,iBdozDD,YAAA,acpzDC,iBduzDD,YAAA,YY9yDD,iBE3CE,YAAA,GAQF,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Udw1DD,MAAA,Kcx1DC,Wd21DD,MAAA,Kc31DC,Wd81DD,MAAA,ac91DC,Wdi2DD,MAAA,acj2DC,Udo2DD,MAAA,Icp2DC,Udu2DD,MAAA,acv2DC,Ud02DD,MAAA,ac12DC,Ud62DD,MAAA,Ic72DC,Udg3DD,MAAA,ach3DC,Udm3DD,MAAA,acn3DC,Uds3DD,MAAA,Ict3DC,Udy3DD,MAAA,ac12DC,Ud62DD,MAAA,Yc72DC,gBdg3DD,MAAA,Kch3DC,gBdm3DD,MAAA,acn3DC,gBds3DD,MAAA,act3DC,edy3DD,MAAA,Icz3DC,ed43DD,MAAA,ac53DC,ed+3DD,MAAA,ac/3DC,edk4DD,MAAA,Icl4DC,edq4DD,MAAA,acr4DC,edw4DD,MAAA,acx4DC,ed24DD,MAAA,Ic34DC,ed84DD,MAAA,acz4DC,ed44DD,MAAA,Yc35DC,ed85DD,MAAA,Kc95DC,gBdi6DD,KAAA,Kcj6DC,gBdo6DD,KAAA,acp6DC,gBdu6DD,KAAA,acv6DC,ed06DD,KAAA,Ic16DC,ed66DD,KAAA,ac76DC,edg7DD,KAAA,ach7DC,edm7DD,KAAA,Icn7DC,eds7DD,KAAA,act7DC,edy7DD,KAAA,acz7DC,ed47DD,KAAA,Ic57DC,ed+7DD,KAAA,ac17DC,ed67DD,KAAA,Yc96DC,edi7DD,KAAA,Kcj7DC,kBdo7DD,YAAA,Kcp7DC,kBdu7DD,YAAA,acv7DC,kBd07DD,YAAA,ac17DC,iBd67DD,YAAA,Ic77DC,iBdg8DD,YAAA,ach8DC,iBdm8DD,YAAA,acn8DC,iBds8DD,YAAA,Ict8DC,iBdy8DD,YAAA,acz8DC,iBd48DD,YAAA,ac58DC,iBd+8DD,YAAA,Ic/8DC,iBdk9DD,YAAA,acl9DC,iBdq9DD,YAAA,YYz8DD,iBE9CE,YAAA,GAQF,0BACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Uds/DD,MAAA,Kct/DC,Wdy/DD,MAAA,Kcz/DC,Wd4/DD,MAAA,ac5/DC,Wd+/DD,MAAA,ac//DC,UdkgED,MAAA,IclgEC,UdqgED,MAAA,acrgEC,UdwgED,MAAA,acxgEC,Ud2gED,MAAA,Ic3gEC,Ud8gED,MAAA,ac9gEC,UdihED,MAAA,acjhEC,UdohED,MAAA,IcphEC,UduhED,MAAA,acxgEC,Ud2gED,MAAA,Yc3gEC,gBd8gED,MAAA,Kc9gEC,gBdihED,MAAA,acjhEC,gBdohED,MAAA,acphEC,eduhED,MAAA,IcvhEC,ed0hED,MAAA,ac1hEC,ed6hED,MAAA,ac7hEC,edgiED,MAAA,IchiEC,edmiED,MAAA,acniEC,edsiED,MAAA,actiEC,edyiED,MAAA,IcziEC,ed4iED,MAAA,acviEC,ed0iED,MAAA,YczjEC,ed4jED,MAAA,Kc5jEC,gBd+jED,KAAA,Kc/jEC,gBdkkED,KAAA,aclkEC,gBdqkED,KAAA,acrkEC,edwkED,KAAA,IcxkEC,ed2kED,KAAA,ac3kEC,ed8kED,KAAA,ac9kEC,edilED,KAAA,IcjlEC,edolED,KAAA,acplEC,edulED,KAAA,acvlEC,ed0lED,KAAA,Ic1lEC,ed6lED,KAAA,acxlEC,ed2lED,KAAA,Yc5kEC,ed+kED,KAAA,Kc/kEC,kBdklED,YAAA,KcllEC,kBdqlED,YAAA,acrlEC,kBdwlED,YAAA,acxlEC,iBd2lED,YAAA,Ic3lEC,iBd8lED,YAAA,ac9lEC,iBdimED,YAAA,acjmEC,iBdomED,YAAA,IcpmEC,iBdumED,YAAA,acvmEC,iBd0mED,YAAA,ac1mEC,iBd6mED,YAAA,Ic7mEC,iBdgnED,YAAA,achnEC,iBdmnED,YAAA,YetrED,iBACA,YAAA,GAGA,MACA,iBAAA,YAEA,QfyrED,YAAA,IevrEC,eAAgB,IAChB,MAAA,KfyrED,WAAA,KelrEC,GACA,WAAA,KfsrED,OexrEC,MAAO,KdmsEP,UAAW,KACX,cAAe,KcvrET,mBd0rER,mBczrEQ,mBAHA,mBACA,mBd0rER,mBDHC,QAAA,IensEC,YAAa,WAoBX,eAAA,IACA,WAAA,IAAA,MAAA,KArBJ,mBdktEE,eAAgB,OAChB,cAAe,IAAI,MAAM,KDJ1B,uCCMD,uCcrtEA,wCdstEA,wCclrEI,2CANI,2CforEP,WAAA,EezqEG,mBf4qEH,WAAA,IAAA,MAAA,KCWD,cACE,iBAAkB,Kc/pEpB,6BdkqEA,6BcjqEE,6BAZM,6BfsqEP,6BCMD,6BDHC,QAAA,ICWD,gBACE,OAAQ,IAAI,MAAM,Kc1qEpB,4Bd6qEA,4Bc7qEA,4BAQQ,4Bf8pEP,4BCMD,4Bc7pEM,OAAA,IAAA,MAAA,KAYF,4BAFJ,4BfopEC,oBAAA,IevoEG,yCf0oEH,iBAAA,QehoEC,4BACA,iBAAA,QfooED,uBe9nEG,SAAA,OdyoEF,QAAS,acxoEL,MAAA,KAEA,sBfioEL,sBgB7wEC,SAAA,OfwxEA,QAAS,WACT,MAAO,KAST,0BerxEE,0Bf+wEF,0BAGA,0BexxEM,0BAMJ,0BfgxEF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCgBlyEC,sCAAA,oCfyyEF,sCetxEM,sCf2xEJ,iBAAkB,QASpB,2Be1yEE,2BfoyEF,2BAGA,2Be7yEM,2BAMJ,2BfqyEF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBvzEC,uCAAA,qCf8zEF,uCe3yEM,uCfgzEJ,iBAAkB,QASpB,wBe/zEE,wBfyzEF,wBAGA,wBel0EM,wBAMJ,wBf0zEF,wBAGA,wBACA,wBDNC,wBCAD,wBAGA,wBASE,iBAAkB,QDLnB,oCgB50EC,oCAAA,kCfm1EF,oCeh0EM,oCfq0EJ,iBAAkB,QASpB,2Bep1EE,2Bf80EF,2BAGA,2Bev1EM,2BAMJ,2Bf+0EF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBj2EC,uCAAA,qCfw2EF,uCer1EM,uCf01EJ,iBAAkB,QASpB,0Bez2EE,0Bfm2EF,0BAGA,0Be52EM,0BAMJ,0Bfo2EF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCehtEC,sCADF,oCdwtEA,sCe12EM,sCDoJJ,iBAAA,QA6DF,kBACE,WAAY,KA3DV,WAAA,KAEA,oCACA,kBACA,MAAA,KfotED,cAAA,Ke7pEC,WAAY,OAnDV,mBAAA,yBfmtEH,OAAA,IAAA,MAAA,KCWD,yBACE,cAAe,Ec5qEjB,qCd+qEA,qCcjtEI,qCARM,qCfktET,qCCMD,qCDHC,YAAA,OCWD,kCACE,OAAQ,EcvrEV,0Dd0rEA,0Dc1rEA,0DAzBU,0Df4sET,0DCMD,0DAME,YAAa,Ec/rEf,yDdksEA,yDclsEA,yDArBU,yDfgtET,yDCMD,yDAME,aAAc,EDLjB,yDe1sEW,yDEzNV,yDjBk6EC,yDiBj6ED,cAAA,GAMA,SjBk6ED,UAAA,EiB/5EC,QAAS,EACT,OAAA,EACA,OAAA,EAEA,OACA,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,KACA,UAAA,KjBi6ED,YAAA,QiB95EC,MAAO,KACP,OAAA,EACA,cAAA,IAAA,MAAA,QAEA,MjBg6ED,QAAA,aiBr5EC,UAAW,Kb4BX,cAAA,IACG,YAAA,IJ63EJ,mBiBr5EC,mBAAoB,WhBg6EjB,gBAAiB,WgB95EpB,WAAA,WjBy5ED,qBiBv5EC,kBAGA,OAAQ,IAAI,EAAE,EACd,WAAA,MjBs5ED,YAAA,OiBj5EC,iBACA,QAAA,MAIF,kBhB25EE,QAAS,MgBz5ET,MAAA,KAIF,iBAAA,ahB05EE,OAAQ,KI99ER,uBY2EF,2BjB64EC,wBiB54EC,QAAA,IAAA,KAAA,yBACA,eAAA,KAEA,OACA,QAAA,MjB+4ED,YAAA,IiBr3EC,UAAW,KACX,YAAA,WACA,MAAA,KAEA,cACA,QAAA,MACA,MAAA,KACA,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KbxDA,iBAAA,KACQ,iBAAA,KAyHR,OAAA,IAAA,MAAA,KACK,cAAA,IACG,mBAAA,MAAA,EAAA,IAAA,IAAA,iBJwzET,WAAA,MAAA,EAAA,IAAA,IAAA,iBkBh8EC,mBAAA,aAAA,YAAA,KAAA,mBAAA,YAAA,KACE,cAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KACA,WAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KdWM,oBJy7ET,aAAA,QIx5EC,QAAA,EACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBAEF,gCAA0B,MAAA,KJ25E3B,QAAA,EI15EiC,oCJ65EjC,MAAA,KiBh4EG,yCACA,MAAA,KAQF,0BhBs4EA,iBAAkB,YAClB,OAAQ,EgBn4EN,wBjB63EH,wBiB13EC,iChBq4EA,iBAAkB,KgBn4EhB,QAAA,EAIF,wBACE,iCjB03EH,OAAA,YiB72EC,sBjBg3ED,OAAA,KiB91EG,mBhB02EF,mBAAoB,KAEtB,qDgB32EM,8BjBo2EH,8BiBj2EC,wCAAA,+BhB62EA,YAAa,KgB32EX,iCjBy2EH,iCiBt2EC,2CAAA,kChB02EF,0BACA,0BACA,oCACA,2BAKE,YAAa,KgBh3EX,iCjB82EH,iCACF,2CiBp2EC,kChBu2EA,0BACA,0BACA,oCACA,2BgBz2EA,YAAA,MhBi3EF,YgBv2EE,cAAA,KAGA,UADA,OjBi2ED,SAAA,SiBr2EC,QAAS,MhBg3ET,WAAY,KgBx2EV,cAAA,KAGA,gBADA,aAEA,WAAA,KjBi2EH,aAAA,KiB91EC,cAAe,EhBy2Ef,YAAa,IACb,OAAQ,QgBp2ER,+BjBg2ED,sCiBl2EC,yBACA,gCAIA,SAAU,ShBw2EV,WAAY,MgBt2EZ,YAAA,MAIF,oBAAA,cAEE,WAAA,KAGA,iBADA,cAEA,SAAA,SACA,QAAA,aACA,aAAA,KjB61ED,cAAA,EiB31EC,YAAa,IhBs2Eb,eAAgB,OgBp2EhB,OAAA,QAUA,kCjBo1ED,4BCWC,WAAY,EACZ,YAAa,KgBv1Eb,wCAAA,qCjBm1ED,8BCOD,+BgBh2EI,2BhB+1EJ,4BAME,OAAQ,YDNT,0BiBv1EG,uBAMF,oCAAA,iChB61EA,OAAQ,YDNT,yBiBp1EK,sBAaJ,mCAFF,gCAGE,OAAA,YAGA,qBjBy0ED,WAAA,KiBv0EC,YAAA,IhBk1EA,eAAgB,IgBh1Ed,cAAA,EjB00EH,8BiB5zED,8BCnQE,cAAA,EACA,aAAA,EAEA,UACA,OAAA,KlBkkFD,QAAA,IAAA,KkBhkFC,UAAA,KACE,YAAA,IACA,cAAA,IAGF,gBjB0kFA,OAAQ,KiBxkFN,YAAA,KD2PA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBy0EH,QAAA,IAAA,KiB/0EC,UAAW,KAST,YAAA,IACA,cAAA,IAVJ,mChB81EE,OAAQ,KgBh1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBy0EH,WAAA,KiBr0EC,QAAS,IAAI,KC/Rb,UAAA,KACA,YAAA,IAEA,UACA,OAAA,KlBumFD,QAAA,KAAA,KkBrmFC,UAAA,KACE,YAAA,UACA,cAAA,IAGF,gBjB+mFA,OAAQ,KiB7mFN,YAAA,KDuRA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBk1EH,QAAA,KAAA,KiBx1EC,UAAW,KAST,YAAA,UACA,cAAA,IAVJ,mChBu2EE,OAAQ,KgBz1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBk1EH,WAAA,KiBz0EC,QAAS,KAAK,KAEd,UAAA,KjB00ED,YAAA,UiBt0EG,cjBy0EH,SAAA,SiBp0EC,4BACA,cAAA,OAEA,uBACA,SAAA,SACA,IAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,MACA,MAAA,KjBu0ED,OAAA,KiBr0EC,YAAa,KhBg1Eb,WAAY,OACZ,eAAgB,KDLjB,oDiBv0EC,uCADA,iCAGA,MAAO,KhBg1EP,OAAQ,KACR,YAAa,KDLd,oDiBv0EC,uCADA,iCAKA,MAAO,KhB80EP,OAAQ,KACR,YAAa,KAKf,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBruFG,mCAJA,yBD0ZJ,gCbvWE,MAAA,QJ2rFD,2BkBxuFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJgsFD,iCiBz1EC,aAAc,QC5YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlByuFH,gCiB91EC,MAAO,QCtYL,iBAAA,QlBuuFH,aAAA,QCWD,oCACE,MAAO,QAKT,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBnwFG,mCAJA,yBD6ZJ,gCb1WE,MAAA,QJytFD,2BkBtwFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ8tFD,iCiBp3EC,aAAc,QC/YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBuwFH,gCiBz3EC,MAAO,QCzYL,iBAAA,QlBqwFH,aAAA,QCWD,oCACE,MAAO,QAKT,qBAEA,4BAJA,0BADA,uBAEA,kBAEA,yBDNC,0BkBjyFG,iCAJA,uBDgaJ,8Bb7WE,MAAA,QJuvFD,yBkBpyFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ4vFD,+BiB/4EC,aAAc,QClZZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBqyFH,8BiBp5EC,MAAO,QC5YL,iBAAA,QlBmyFH,aAAA,QiB/4EG,kCjBk5EH,MAAA,QiB/4EG,2CjBk5EH,IAAA,KiBv4EC,mDACA,IAAA,EAEA,YjB04ED,QAAA,MiBvzEC,WAAY,IAwEZ,cAAe,KAtIX,MAAA,QAEA,yBjBy3EH,yBiBrvEC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBw3EH,2BiB1vEC,QAAS,aAxHP,MAAA,KjBq3EH,eAAA,OiBj3EG,kCACA,QAAA,aAmHJ,0BhB4wEE,QAAS,aACT,eAAgB,OgBr3Ed,wCjB82EH,6CiBtwED,2CjBywEC,MAAA,KiB72EG,wCACA,MAAA,KAmGJ,4BhBwxEE,cAAe,EgBp3Eb,eAAA,OAGA,uBADA,oBjB82EH,QAAA,aiBpxEC,WAAY,EhB+xEZ,cAAe,EgBr3EX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB6xEC,sCiBx2EG,SAAA,SjB22EH,YAAA,EiBh2ED,kDhB42EE,IAAK,GgBl2EL,2BjB+1EH,kCiBh2EG,wBAEA,+BAXF,YAAa,IhBo3Eb,WAAY,EgBn2EV,cAAA,EJviBF,2BIshBF,wBJrhBE,WAAA,KI4jBA,6BAyBA,aAAc,MAnCV,YAAA,MAEA,yBjBw1EH,gCACF,YAAA,IiBx3EG,cAAe,EAwCf,WAAA,OAwBJ,sDAdQ,MAAA,KjB80EL,yBACF,+CiBn0EC,YAAA,KAEE,UAAW,MjBs0EZ,yBACF,+CmBp6FG,YAAa,IACf,UAAA,MAGA,KACA,QAAA,aACA,QAAA,IAAA,KAAA,cAAA,EACA,UAAA,KACA,YAAA,IACA,YAAA,WACA,WAAA,OC0CA,YAAA,OACA,eAAA,OACA,iBAAA,aACA,aAAA,ahB+JA,OAAA,QACG,oBAAA,KACC,iBAAA,KACI,gBAAA,KJ+tFT,YAAA,KmBv6FG,iBAAA,KlBm7FF,OAAQ,IAAI,MAAM,YAClB,cAAe,IkB96Ff,kBdzBA,kBACA,WLk8FD,kBCOD,kBADA,WAME,QAAS,IAAI,KAAK,yBAClB,eAAgB,KkBh7FhB,WnBy6FD,WmB56FG,WlBw7FF,MAAO,KkBn7FL,gBAAA,Kf6BM,YADR,YJk5FD,iBAAA,KmBz6FC,QAAA,ElBq7FA,mBAAoB,MAAM,EAAE,IAAI,IAAI,iBAC5B,WAAY,MAAM,EAAE,IAAI,IAAI,iBoBh+FpC,cAGA,ejB8DA,wBACQ,OAAA,YJ05FT,OAAA,kBmBz6FG,mBAAA,KlBq7FM,WAAY,KkBn7FhB,QAAA,IASN,eC3DE,yBACA,eAAA,KpBi+FD,aoB99FC,MAAA,KnB0+FA,iBAAkB,KmBx+FhB,aAAA,KpBk+FH,mBoBh+FO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBi+FH,mBoB99FC,MAAA,KnB0+FA,iBAAkB,QAClB,aAAc,QmBt+FR,oBADJ,oBpBi+FH,mCoB99FG,MAAA,KnB0+FF,iBAAkB,QAClB,aAAc,QmBt+FN,0BnB4+FV,0BAHA,0BmB1+FM,0BnB4+FN,0BAHA,0BDFC,yCoBx+FK,yCnB4+FN,yCmBv+FE,MAAA,KnB++FA,iBAAkB,QAClB,aAAc,QmBx+FZ,oBpBg+FH,oBoBh+FG,mCnB6+FF,iBAAkB,KmBz+FV,4BnB8+FV,4BAHA,4BDHC,6BCOD,6BAHA,6BkB39FA,sCClBM,sCnB8+FN,sCmBx+FI,iBAAA,KACA,aAAA,KDcJ,oBC9DE,MAAA,KACA,iBAAA,KpB0hGD,aoBvhGC,MAAA,KnBmiGA,iBAAkB,QmBjiGhB,aAAA,QpB2hGH,mBoBzhGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB0hGH,mBoBvhGC,MAAA,KnBmiGA,iBAAkB,QAClB,aAAc,QmB/hGR,oBADJ,oBpB0hGH,mCoBvhGG,MAAA,KnBmiGF,iBAAkB,QAClB,aAAc,QmB/hGN,0BnBqiGV,0BAHA,0BmBniGM,0BnBqiGN,0BAHA,0BDFC,yCoBjiGK,yCnBqiGN,yCmBhiGE,MAAA,KnBwiGA,iBAAkB,QAClB,aAAc,QmBjiGZ,oBpByhGH,oBoBzhGG,mCnBsiGF,iBAAkB,KmBliGV,4BnBuiGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBjhGA,sCCrBM,sCnBuiGN,sCmBjiGI,iBAAA,QACA,aAAA,QDkBJ,oBClEE,MAAA,QACA,iBAAA,KpBmlGD,aoBhlGC,MAAA,KnB4lGA,iBAAkB,QmB1lGhB,aAAA,QpBolGH,mBoBllGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBmlGH,mBoBhlGC,MAAA,KnB4lGA,iBAAkB,QAClB,aAAc,QmBxlGR,oBADJ,oBpBmlGH,mCoBhlGG,MAAA,KnB4lGF,iBAAkB,QAClB,aAAc,QmBxlGN,0BnB8lGV,0BAHA,0BmB5lGM,0BnB8lGN,0BAHA,0BDFC,yCoB1lGK,yCnB8lGN,yCmBzlGE,MAAA,KnBimGA,iBAAkB,QAClB,aAAc,QmB1lGZ,oBpBklGH,oBoBllGG,mCnB+lGF,iBAAkB,KmB3lGV,4BnBgmGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBtkGA,sCCzBM,sCnBgmGN,sCmB1lGI,iBAAA,QACA,aAAA,QDsBJ,oBCtEE,MAAA,QACA,iBAAA,KpB4oGD,UoBzoGC,MAAA,KnBqpGA,iBAAkB,QmBnpGhB,aAAA,QpB6oGH,gBoB3oGO,gBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB4oGH,gBoBzoGC,MAAA,KnBqpGA,iBAAkB,QAClB,aAAc,QmBjpGR,iBADJ,iBpB4oGH,gCoBzoGG,MAAA,KnBqpGF,iBAAkB,QAClB,aAAc,QmBjpGN,uBnBupGV,uBAHA,uBmBrpGM,uBnBupGN,uBAHA,uBDFC,sCoBnpGK,sCnBupGN,sCmBlpGE,MAAA,KnB0pGA,iBAAkB,QAClB,aAAc,QmBnpGZ,iBpB2oGH,iBoB3oGG,gCnBwpGF,iBAAkB,KmBppGV,yBnBypGV,yBAHA,yBDHC,0BCOD,0BAHA,0BkB3nGA,mCC7BM,mCnBypGN,mCmBnpGI,iBAAA,QACA,aAAA,QD0BJ,iBC1EE,MAAA,QACA,iBAAA,KpBqsGD,aoBlsGC,MAAA,KnB8sGA,iBAAkB,QmB5sGhB,aAAA,QpBssGH,mBoBpsGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBqsGH,mBoBlsGC,MAAA,KnB8sGA,iBAAkB,QAClB,aAAc,QmB1sGR,oBADJ,oBpBqsGH,mCoBlsGG,MAAA,KnB8sGF,iBAAkB,QAClB,aAAc,QmB1sGN,0BnBgtGV,0BAHA,0BmB9sGM,0BnBgtGN,0BAHA,0BDFC,yCoB5sGK,yCnBgtGN,yCmB3sGE,MAAA,KnBmtGA,iBAAkB,QAClB,aAAc,QmB5sGZ,oBpBosGH,oBoBpsGG,mCnBitGF,iBAAkB,KmB7sGV,4BnBktGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBhrGA,sCCjCM,sCnBktGN,sCmB5sGI,iBAAA,QACA,aAAA,QD8BJ,oBC9EE,MAAA,QACA,iBAAA,KpB8vGD,YoB3vGC,MAAA,KnBuwGA,iBAAkB,QmBrwGhB,aAAA,QpB+vGH,kBoB7vGO,kBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB8vGH,kBoB3vGC,MAAA,KnBuwGA,iBAAkB,QAClB,aAAc,QmBnwGR,mBADJ,mBpB8vGH,kCoB3vGG,MAAA,KnBuwGF,iBAAkB,QAClB,aAAc,QmBnwGN,yBnBywGV,yBAHA,yBmBvwGM,yBnBywGN,yBAHA,yBDFC,wCoBrwGK,wCnBywGN,wCmBpwGE,MAAA,KnB4wGA,iBAAkB,QAClB,aAAc,QmBrwGZ,mBpB6vGH,mBoB7vGG,kCnB0wGF,iBAAkB,KmBtwGV,2BnB2wGV,2BAHA,2BDHC,4BCOD,4BAHA,4BkBruGA,qCCrCM,qCnB2wGN,qCmBrwGI,iBAAA,QACA,aAAA,QDuCJ,mBACE,MAAA,QACA,iBAAA,KnB+tGD,UmB5tGC,YAAA,IlBwuGA,MAAO,QACP,cAAe,EAEjB,UGzwGE,iBemCE,iBflCM,oBJkwGT,6BmB7tGC,iBAAA,YlByuGA,mBAAoB,KACZ,WAAY,KkBtuGlB,UAEF,iBAAA,gBnB6tGD,gBmB3tGG,aAAA,YnBiuGH,gBmB/tGG,gBAIA,MAAA,QlBuuGF,gBAAiB,UACjB,iBAAkB,YDNnB,0BmBhuGK,0BAUN,mCATM,mClB2uGJ,MAAO,KmB1yGP,gBAAA,KAGA,mBADA,QpBmyGD,QAAA,KAAA,KmBztGC,UAAW,KlBquGX,YAAa,UmBjzGb,cAAA,IAGA,mBADA,QpB0yGD,QAAA,IAAA,KmB5tGC,UAAW,KlBwuGX,YAAa,ImBxzGb,cAAA,IAGA,mBADA,QpBizGD,QAAA,IAAA,ImB3tGC,UAAW,KACX,YAAA,IACA,cAAA,IAIF,WACE,QAAA,MnB2tGD,MAAA,KCYD,sBACE,WAAY,IqBz3GZ,6BADF,4BtBk3GC,6BI7rGC,MAAA,KAEQ,MJisGT,QAAA,EsBr3GC,mBAAA,QAAA,KAAA,OACE,cAAA,QAAA,KAAA,OtBu3GH,WAAA,QAAA,KAAA,OsBl3GC,StBq3GD,QAAA,EsBn3Ga,UtBs3Gb,QAAA,KsBr3Ga,atBw3Gb,QAAA,MsBv3Ga,etB03Gb,QAAA,UsBt3GC,kBACA,QAAA,gBlBwKA,YACQ,SAAA,SAAA,OAAA,EAOR,SAAA,OACQ,mCAAA,KAAA,8BAAA,KAGR,2BAAA,KACQ,4BAAA,KAAA,uBAAA,KJ2sGT,oBAAA,KuBr5GC,4BAA6B,OAAQ,WACrC,uBAAA,OAAA,WACA,oBAAA,OAAA,WAEA,OACA,QAAA,aACA,MAAA,EACA,OAAA,EACA,YAAA,IACA,eAAA,OvBu5GD,WAAA,IAAA,OuBn5GC,WAAY,IAAI,QtBk6GhB,aAAc,IAAI,MAAM,YsBh6GxB,YAAA,IAAA,MAAA,YAKA,UADF,QvBo5GC,SAAA,SuB94GC,uBACA,QAAA,EAEA,eACA,SAAA,SACA,IAAA,KACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,MAAA,KACA,UAAA,MACA,QAAA,IAAA,EACA,OAAA,IAAA,EAAA,EACA,UAAA,KACA,WAAA,KACA,WAAA,KnBsBA,iBAAA,KACQ,wBAAA,YmBrBR,gBAAA,YtB+5GA,OsB/5GA,IAAA,MAAA,KvBk5GD,OAAA,IAAA,MAAA,gBuB74GC,cAAA,IACE,mBAAA,EAAA,IAAA,KAAA,iBACA,WAAA,EAAA,IAAA,KAAA,iBAzBJ,0BCzBE,MAAA,EACA,KAAA,KAEA,wBxBo8GD,OAAA,IuB96GC,OAAQ,IAAI,EAmCV,SAAA,OACA,iBAAA,QAEA,oBACA,QAAA,MACA,QAAA,IAAA,KACA,MAAA,KvB84GH,YAAA,IuBx4GC,YAAA,WtBw5GA,MAAO,KsBt5GL,YAAA,OvB44GH,0BuB14GG,0BAMF,MAAA,QtBo5GA,gBAAiB,KACjB,iBAAkB,QsBj5GhB,yBAEA,+BADA,+BvBu4GH,MAAA,KuB73GC,gBAAA,KtB64GA,iBAAkB,QAClB,QAAS,EDZV,2BuB33GC,iCAAA,iCAEE,MAAA,KEzGF,iCF2GE,iCAEA,gBAAA,KvB63GH,OAAA,YuBx3GC,iBAAkB,YAGhB,iBAAA,KvBw3GH,OAAA,0DuBn3GG,qBvBs3GH,QAAA,MuB72GC,QACA,QAAA,EAQF,qBACE,MAAA,EACA,KAAA,KAIF,oBACE,MAAA,KACA,KAAA,EAEA,iBACA,QAAA,MACA,QAAA,IAAA,KvBw2GD,UAAA,KuBp2GC,YAAa,WACb,MAAA,KACA,YAAA,OAEA,mBACA,SAAA,MACA,IAAA,EvBs2GD,MAAA,EuBl2GC,OAAQ,EACR,KAAA,EACA,QAAA,IAQF,2BtB42GE,MAAO,EsBx2GL,KAAA,KAEA,eACA,sCvB41GH,QAAA,GuBn2GC,WAAY,EtBm3GZ,cAAe,IAAI,OsBx2GjB,cAAA,IAAA,QAEA,uBvB41GH,8CuBv0GC,IAAK,KAXL,OAAA,KApEA,cAAA,IvB25GC,yBuBv1GD,6BA1DA,MAAA,EACA,KAAA,KvBq5GD,kC0BpiHG,MAAO,KzBojHP,KAAM,GyBhjHR,W1BsiHD,oB0B1iHC,SAAU,SzB0jHV,QAAS,ayBpjHP,eAAA,OAGA,yB1BsiHH,gBCgBC,SAAU,SACV,MAAO,KyB7iHT,gC1BsiHC,gCCYD,+BAFA,+ByBhjHA,uBANM,uBzBujHN,sBAFA,sBAQE,QAAS,EyBljHP,qB1BuiHH,2B0BliHD,2BACE,iC1BoiHD,YAAA,KCgBD,aACE,YAAa,KDZd,kB0B1iHD,wBAAA,0BzB2jHE,MAAO,KDZR,kB0B/hHD,wBACE,0B1BiiHD,YAAA,I0B5hHC,yE1B+hHD,cAAA,E2BhlHC,4BACG,YAAA,EDsDL,mEzB6iHE,wBAAyB,E0B5lHzB,2BAAA,E3BilHD,6C0B5hHD,8CACE,uBAAA,E1B8hHD,0BAAA,E0B3hHC,sB1B8hHD,MAAA,KCgBD,8D0B/mHE,cAAA,E3BomHD,mE0B3hHD,oECjEE,wBAAA,EACG,2BAAA,EDqEL,oEzB0iHE,uBAAwB,EyBxiHxB,0BAAA,EAiBF,mCACE,iCACA,QAAA,EAEF,iCACE,cAAA,IACA,aAAA,IAKF,oCtB/CE,cAAA,KACQ,aAAA,KsBkDR,iCtBnDA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBsByDV,0CACE,mBAAA,K1BugHD,WAAA,K0BngHC,YACA,YAAA,EAGF,eACE,aAAA,IAAA,IAAA,E1BqgHD,oBAAA,ECgBD,uBACE,aAAc,EAAE,IAAI,IyB1gHlB,yBACA,+BACA,oC1B+/GH,QAAA,M0BtgHC,MAAO,KAcH,MAAA,K1B2/GL,UAAA,KCgBD,oCACE,MAAO,KyBpgHL,8BACA,oC1By/GH,oC0Bp/GC,0CACE,WAAA,K1Bs/GH,YAAA,E2B/pHC,4DACC,cAAA,EAQA,sD3B4pHF,uBAAA,I0Bt/GC,wBAAA,IC/KA,2BAAA,EACC,0BAAA,EAQA,sD3BkqHF,uBAAA,E0Bv/GC,wBAAyB,EACzB,2BAAA,I1By/GD,0BAAA,ICgBD,uE0BtrHE,cAAA,E3B2qHD,4E0Bt/GD,6EC7LE,2BAAA,EACC,0BAAA,EDoMH,6EACE,uBAAA,EACA,wBAAA,EAEA,qB1Bo/GD,QAAA,M0Bx/GC,MAAO,KzBwgHP,aAAc,MyBjgHZ,gBAAA,SAEA,0B1Bq/GH,gC0B9/GC,QAAS,WAYP,MAAA,K1Bq/GH,MAAA,G0Bj/GG,qC1Bo/GH,MAAA,KCgBD,+CACE,KAAM,KyB7+GF,gDAFA,6C1Bs+GL,2D0Br+GK,wDEzOJ,SAAU,SACV,KAAA,cACA,eAAA,K5BitHD,a4B7sHC,SAAA,SACE,QAAA,MACA,gBAAA,S5BgtHH,0B4BxtHC,MAAO,KAeL,cAAA,EACA,aAAA,EAOA,2BACA,SAAA,S5BusHH,QAAA,E4BrsHG,MAAA,KACE,MAAA,K5BusHL,cAAA,ECgBD,iCACE,QAAS,EiBnrHT,8BACA,mCACA,sCACA,OAAA,KlBwqHD,QAAA,KAAA,KkBtqHC,UAAA,KjBsrHA,YAAa,UACb,cAAe,IiBrrHb,oClB0qHH,yCkBvqHC,4CjBurHA,OAAQ,KACR,YAAa,KDTd,8C4B/sHD,mDAAA,sD3B0tHA,sCACA,2CiBzrHI,8CjB8rHF,OAAQ,KiB1sHR,8BACA,mCACA,sCACA,OAAA,KlB+rHD,QAAA,IAAA,KkB7rHC,UAAA,KjB6sHA,YAAa,IACb,cAAe,IiB5sHb,oClBisHH,yCkB9rHC,4CjB8sHA,OAAQ,KACR,YAAa,KDTd,8C4B7tHD,mDAAA,sD3BwuHA,sCACA,2CiBhtHI,8CjBqtHF,OAAQ,K2BzuHR,2B5B6tHD,mB4B7tHC,iB3B8uHA,QAAS,W2BzuHX,8D5B6tHC,sD4B7tHD,oDAEE,cAAA,EAEA,mB5B+tHD,iB4B1tHC,MAAO,GACP,YAAA,OACA,eAAA,OAEA,mBACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,K5B4tHD,WAAA,O4BztHC,iBAAA,KACE,OAAA,IAAA,MAAA,KACA,cAAA,I5B4tHH,4B4BztHC,QAAA,IAAA,KACE,UAAA,KACA,cAAA,I5B4tHH,4B4B/uHC,QAAS,KAAK,K3B+vHd,UAAW,K2BruHT,cAAA,IAKJ,wCAAA,qC3BquHE,WAAY,EAEd,uCACA,+BACA,kC0B70HE,6CACG,8CC4GL,6D5BqtHC,wE4BptHC,wBAAA,E5ButHD,2BAAA,ECgBD,+BACE,aAAc,EAEhB,sCACA,8B2BhuHA,+D5BstHC,oDCWD,iC0Bl1HE,4CACG,6CCiHH,uBAAA,E5BwtHD,0BAAA,E4BltHC,8BAGA,YAAA,E5BotHD,iB4BxtHC,SAAU,SAUR,UAAA,E5BitHH,YAAA,O4B/sHK,sB5BktHL,SAAA,SCgBD,2BACE,YAAa,K2BxtHb,6BAAA,4B5B4sHD,4B4BzsHK,QAAA,EAGJ,kCAAA,wCAGI,aAAA,K5B4sHL,iC6B12HD,uCACE,QAAA,EACA,YAAA,K7B62HD,K6B/2HC,aAAc,EAOZ,cAAA,EACA,WAAA,KARJ,QAWM,SAAA,SACA,QAAA,M7B42HL,U6B12HK,SAAA,S5B03HJ,QAAS,M4Bx3HH,QAAA,KAAA,KAMJ,gB7Bu2HH,gB6Bt2HK,gBAAA,K7By2HL,iBAAA,KCgBD,mB4Br3HQ,MAAA,KAGA,yBADA,yB7B02HP,MAAA,K6Bl2HG,gBAAA,K5Bk3HF,OAAQ,YACR,iBAAkB,Y4B/2Hd,aAzCN,mB7B64HC,mBwBh5HC,iBAAA,KACA,aAAA,QAEA,kBxBm5HD,OAAA,I6Bn5HC,OAAQ,IAAI,EA0DV,SAAA,O7B41HH,iBAAA,Q6Bl1HC,c7Bq1HD,UAAA,K6Bn1HG,UAEA,cAAA,IAAA,MAAA,KALJ,aASM,MAAA,KACA,cAAA,KAEA,e7Bo1HL,aAAA,I6Bn1HK,YAAA,WACE,OAAA,IAAA,MAAA,Y7Bq1HP,cAAA,IAAA,IAAA,EAAA,ECgBD,qBACE,aAAc,KAAK,KAAK,K4B51HlB,sBAEA,4BADA,4BAEA,MAAA,K7Bi1HP,OAAA,Q6B50HC,iBAAA,KAqDA,OAAA,IAAA,MAAA,KA8BA,oBAAA,YAnFA,wBAwDE,MAAA,K7B2xHH,cAAA,E6BzxHK,2BACA,MAAA,KA3DJ,6BAgEE,cAAA,IACA,WAAA,OAYJ,iDA0DE,IAAK,KAjED,KAAA,K7B0xHH,yB6BztHD,2BA9DM,QAAA,W7B0xHL,MAAA,G6Bn2HD,6BAuFE,cAAA,GAvFF,6B5Bw3HA,aAAc,EACd,cAAe,IDZhB,kC6BtuHD,wCA3BA,wCATM,OAAA,IAAA,MAAA,K7B+wHH,yB6B3uHD,6B5B2vHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,kC6B92HD,wC7B+2HD,wC6B72HG,oBAAA,MAIE,c7B+2HL,MAAA,K6B52HK,gB7B+2HL,cAAA,ICgBD,iBACE,YAAa,I4Bv3HP,uBAQR,6B7Bo2HC,6B6Bl2HG,MAAA,K7Bq2HH,iBAAA,Q6Bn2HK,gBACA,MAAA,KAYN,mBACE,WAAA,I7B41HD,YAAA,E6Bz1HG,e7B41HH,MAAA,K6B11HK,kBACA,MAAA,KAPN,oBAYI,cAAA,IACA,WAAA,OAYJ,wCA0DE,IAAK,KAjED,KAAA,K7B21HH,yB6B1xHD,kBA9DM,QAAA,W7B21HL,MAAA,G6Bl1HD,oBACA,cAAA,GAIE,oBACA,cAAA,EANJ,yB5B02HE,aAAc,EACd,cAAe,IDZhB,8B6B1yHD,oCA3BA,oCATM,OAAA,IAAA,MAAA,K7Bm1HH,yB6B/yHD,yB5B+zHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,8B6Bx0HD,oC7By0HD,oC6Bv0HG,oBAAA,MAGA,uB7B00HH,QAAA,K6B/zHC,qBF3OA,QAAA,M3B+iID,yB8BxiIC,WAAY,KACZ,uBAAA,EACA,wBAAA,EAEA,Q9B0iID,SAAA,S8BliIC,WAAY,KA8nBZ,cAAe,KAhoBb,OAAA,IAAA,MAAA,Y9ByiIH,yB8BzhIC,QAgnBE,cAAe,K9B86GlB,yB8BjhIC,eACA,MAAA,MAGA,iBACA,cAAA,KAAA,aAAA,KAEA,WAAA,Q9BkhID,2BAAA,M8BhhIC,WAAA,IAAA,MAAA,YACE,mBAAA,MAAA,EAAA,IAAA,EAAA,qB9BkhIH,WAAA,MAAA,EAAA,IAAA,EAAA,qB8Bz7GD,oBArlBI,WAAA,KAEA,yBAAA,iB9BkhID,MAAA,K8BhhIC,WAAA,EACE,mBAAA,KACA,WAAA,KAEA,0B9BkhIH,QAAA,gB8B/gIC,OAAA,eACE,eAAA,E9BihIH,SAAA,kBCkBD,oBACE,WAAY,QDZf,sC8B/gIK,mC9B8gIH,oC8BzgIC,cAAe,E7B4hIf,aAAc,G6Bj+GlB,sCAnjBE,mC7ByhIA,WAAY,MDdX,4D8BngID,sC9BogID,mCCkBG,WAAY,O6B3gId,kCANE,gC9BsgIH,4B8BvgIG,0BAuiBF,aAAc,M7Bm/Gd,YAAa,MAEf,yBDZC,kC8B3gIK,gC9B0gIH,4B8B3gIG,0BAcF,aAAc,EAChB,YAAA,GAMF,mBA8gBE,QAAS,KAhhBP,aAAA,EAAA,EAAA,I9BkgIH,yB8B7/HC,mB7B+gIE,cAAe,G6B1gIjB,qBADA,kB9BggID,SAAA,M8Bz/HC,MAAO,EAggBP,KAAM,E7B4gHN,QAAS,KDdR,yB8B7/HD,qB9B8/HD,kB8B7/HC,cAAA,GAGF,kBACE,IAAA,EACA,aAAA,EAAA,EAAA,I9BigID,qB8B1/HC,OAAQ,EACR,cAAA,EACA,aAAA,IAAA,EAAA,EAEA,cACA,MAAA,K9B4/HD,OAAA,K8B1/HC,QAAA,KAAA,K7B4gIA,UAAW,K6B1gIT,YAAA,KAIA,oBAbJ,oB9BwgIC,gBAAA,K8Bv/HG,kB7B0gIF,QAAS,MDdR,yBACF,iC8Bh/HC,uCACA,YAAA,OAGA,eC9LA,SAAA,SACA,MAAA,MD+LA,QAAA,IAAA,KACA,WAAA,IACA,aAAA,KACA,cAAA,I9Bm/HD,iBAAA,Y8B/+HC,iBAAA,KACE,OAAA,IAAA,MAAA,Y9Bi/HH,cAAA,I8B5+HG,qBACA,QAAA,EAEA,yB9B++HH,QAAA,M8BrgIC,MAAO,KAyBL,OAAA,I9B++HH,cAAA,I8BpjHD,mCAvbI,WAAA,I9Bg/HH,yB8Bt+HC,eACA,QAAA,MAGE,YACA,OAAA,MAAA,M9By+HH,iB8B58HC,YAAA,KA2YA,eAAgB,KAjaZ,YAAA,KAEA,yBACA,iCACA,SAAA,OACA,MAAA,KACA,MAAA,KAAA,WAAA,E9Bs+HH,iBAAA,Y8B3kHC,OAAQ,E7B8lHR,mBAAoB,K6Bt/HhB,WAAA,KAGA,kDAqZN,sC9BklHC,QAAA,IAAA,KAAA,IAAA,KCmBD,sC6Bv/HQ,YAAA,KAmBR,4C9Bs9HD,4C8BvlHG,iBAAkB,M9B4lHnB,yB8B5lHD,YAtYI,MAAA,K9Bq+HH,OAAA,E8Bn+HK,eACA,MAAA,K9Bu+HP,iB8B39HG,YAAa,KACf,eAAA,MAGA,aACA,QAAA,KAAA,K1B9NA,WAAA,IACQ,aAAA,M2B/DR,cAAA,IACA,YAAA,M/B4vID,WAAA,IAAA,MAAA,YiBtuHC,cAAe,IAAI,MAAM,YAwEzB,mBAAoB,MAAM,EAAE,IAAI,EAAE,qBAAyB,EAAE,IAAI,EAAE,qBAtI/D,WAAA,MAAA,EAAA,IAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,qBAEA,yBjBwyHH,yBiBpqHC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBuyHH,2BiBzqHC,QAAS,aAxHP,MAAA,KjBoyHH,eAAA,OiBhyHG,kCACA,QAAA,aAmHJ,0BhBmsHE,QAAS,aACT,eAAgB,OgB5yHd,wCjB6xHH,6CiBrrHD,2CjBwrHC,MAAA,KiB5xHG,wCACA,MAAA,KAmGJ,4BhB+sHE,cAAe,EgB3yHb,eAAA,OAGA,uBADA,oBjB6xHH,QAAA,aiBnsHC,WAAY,EhBstHZ,cAAe,EgB5yHX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB4sHC,sCiBvxHG,SAAA,SjB0xHH,YAAA,E8BngID,kDAmWE,IAAK,GAvWH,yBACE,yB9B8gIL,cAAA,I8B5/HD,oCAoVE,cAAe,GA1Vf,yBACA,aACA,MAAA,KACA,YAAA,E1BzPF,eAAA,EACQ,aAAA,EJmwIP,YAAA,EACF,OAAA,E8BngIG,mBAAoB,KACtB,WAAA,M9BugID,8B8BngIC,WAAY,EACZ,uBAAA,EHzUA,wBAAA,EAQA,mDACC,cAAA,E3By0IF,uBAAA,I8B//HC,wBAAyB,IChVzB,2BAAA,EACA,0BAAA,EDkVA,YCnVA,WAAA,IACA,cAAA,IDqVA,mBCtVA,WAAA,KACA,cAAA,KD+VF,mBChWE,WAAA,KACA,cAAA,KDuWF,aAsSE,WAAY,KA1SV,cAAA,KAEA,yB9B+/HD,aACF,MAAA,K8Bl+HG,aAAc,KAhBhB,YAAA,MACA,yBE5WA,aF8WE,MAAA,eAFF,cAKI,MAAA,gB9Bu/HH,aAAA,M8B7+HD,4BACA,aAAA,GADF,gBAKI,iBAAA,Q9Bg/HH,aAAA,QCmBD,8B6BhgIM,MAAA,KARN,oC9B0/HC,oC8B5+HG,MAAA,Q9B++HH,iBAAA,Y8B1+HK,6B9B6+HL,MAAA,KCmBD,iC6B5/HQ,MAAA,KAKF,uC9By+HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bz/HZ,sCAIF,4C9Bu+HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bv/HZ,wCAxCR,8C9BihIC,8C8Bn+HG,MAAA,K9Bs+HH,iBAAA,YCmBD,+B6Bt/HM,aAAA,KAGA,qCApDN,qC9B2hIC,iBAAA,KCmBD,yC6Bp/HI,iBAAA,KAOE,iCAAA,6B7Bk/HJ,aAAc,Q6B9+HR,oCAiCN,0C9B+7HD,0C8B3xHC,MAAO,KA7LC,iBAAA,QACA,yB7B8+HR,sD6B5+HU,MAAA,KAKF,4D9By9HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bz+HV,2DAIF,iE9Bu9HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bv+HV,6D9B09HX,mEADE,mE8B1jIC,MAAO,KA8GP,iBAAA,aAEE,6B9Bi9HL,MAAA,K8B58HG,mC9B+8HH,MAAA,KCmBD,0B6B/9HM,MAAA,KAIA,gCAAA,gC7Bg+HJ,MAAO,K6Bt9HT,0CARQ,0CASN,mD9Bu8HD,mD8Bt8HC,MAAA,KAFF,gBAKI,iBAAA,K9B08HH,aAAA,QCmBD,8B6B19HM,MAAA,QARN,oC9Bo9HC,oC8Bt8HG,MAAA,K9By8HH,iBAAA,Y8Bp8HK,6B9Bu8HL,MAAA,QCmBD,iC6Bt9HQ,MAAA,QAKF,uC9Bm8HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bn9HZ,sCAIF,4C9Bi8HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bj9HZ,wCAxCR,8C9B2+HC,8C8B57HG,MAAA,K9B+7HH,iBAAA,YCmBD,+B6B/8HM,aAAA,KAGA,qCArDN,qC9Bq/HC,iBAAA,KCmBD,yC6B78HI,iBAAA,KAME,iCAAA,6B7B48HJ,aAAc,Q6Bx8HR,oCAuCN,0C9Bm5HD,0C8B33HC,MAAO,KAvDC,iBAAA,QAuDV,yBApDU,kE9Bs7HP,aAAA,Q8Bn7HO,0D9Bs7HP,iBAAA,QCmBD,sD6Bt8HU,MAAA,QAKF,4D9Bm7HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bn8HV,2DAIF,iE9Bi7HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bj8HV,6D9Bo7HX,mEADE,mE8B1hIC,MAAO,KA+GP,iBAAA,aAEE,6B9Bg7HL,MAAA,Q8B36HG,mC9B86HH,MAAA,KCmBD,0B6B97HM,MAAA,QAIA,gCAAA,gC7B+7HJ,MAAO,KgCvkJT,0CH0oBQ,0CGzoBN,mDjCwjJD,mDiCvjJC,MAAA,KAEA,YACA,QAAA,IAAA,KjC2jJD,cAAA,KiChkJC,WAAY,KAQV,iBAAA,QjC2jJH,cAAA,IiCxjJK,eACA,QAAA,ajC4jJL,yBiCxkJC,QAAS,EAAE,IAkBT,MAAA,KjCyjJH,QAAA,SkC5kJC,oBACA,MAAA,KAEA,YlC+kJD,QAAA,akCnlJC,aAAc,EAOZ,OAAA,KAAA,ElC+kJH,cAAA,ICmBD,eiC/lJM,QAAA,OAEA,iBACA,oBACA,SAAA,SACA,MAAA,KACA,QAAA,IAAA,KACA,YAAA,KACA,YAAA,WlCglJL,MAAA,QkC9kJG,gBAAA,KjCimJF,iBAAkB,KiC9lJZ,OAAA,IAAA,MAAA,KPVH,6B3B2lJJ,gCkC7kJG,YAAA,EjCgmJF,uBAAwB,I0BvnJxB,0BAAA,I3BymJD,4BkCxkJG,+BjC2lJF,wBAAyB,IACzB,2BAA4B,IiCxlJxB,uBAFA,uBAGA,0BAFA,0BlC8kJL,QAAA,EkCtkJG,MAAA,QjCylJF,iBAAkB,KAClB,aAAc,KAEhB,sBiCvlJM,4BAFA,4BjC0lJN,yBiCvlJM,+BAFA,+BAGA,QAAA,ElC2kJL,MAAA,KkCloJC,OAAQ,QjCqpJR,iBAAkB,QAClB,aAAc,QiCnlJV,wBAEA,8BADA,8BjColJN,2BiCtlJM,iCjCulJN,iCDZC,MAAA,KkC/jJC,OAAQ,YjCklJR,iBAAkB,KkC7pJd,aAAA,KAEA,oBnC8oJL,uBmC5oJG,QAAA,KAAA,KlC+pJF,UAAW,K0B1pJX,YAAA,U3B4oJD,gCmC3oJG,mClC8pJF,uBAAwB,I0BvqJxB,0BAAA,I3BypJD,+BkC1kJD,kCjC6lJE,wBAAyB,IkC7qJrB,2BAAA,IAEA,oBnC8pJL,uBmC5pJG,QAAA,IAAA,KlC+qJF,UAAW,K0B1qJX,YAAA,I3B4pJD,gCmC3pJG,mClC8qJF,uBAAwB,I0BvrJxB,0BAAA,I3ByqJD,+BoC3qJD,kCACE,wBAAA,IACA,2BAAA,IAEA,OpC6qJD,aAAA,EoCjrJC,OAAQ,KAAK,EAOX,WAAA,OpC6qJH,WAAA,KCmBD,UmC7rJM,QAAA,OAEA,YACA,eACA,QAAA,apC8qJL,QAAA,IAAA,KoC5rJC,iBAAkB,KnC+sJlB,OAAQ,IAAI,MAAM,KmC5rJd,cAAA,KAnBN,kBpCisJC,kBCmBC,gBAAiB,KmCzrJb,iBAAA,KA3BN,eAAA,kBAkCM,MAAA,MAlCN,mBAAA,sBnC6tJE,MAAO,KmClrJH,mBAEA,yBADA,yBpCqqJL,sBqCltJC,MAAO,KACP,OAAA,YACA,iBAAA,KAEA,OACA,QAAA,OACA,QAAA,KAAA,KAAA,KACA,UAAA,IACA,YAAA,IACA,YAAA,EACA,MAAA,KrCotJD,WAAA,OqChtJG,YAAA,OpCmuJF,eAAgB,SoCjuJZ,cAAA,MrCotJL,cqCltJK,cAKJ,MAAA,KACE,gBAAA,KrC+sJH,OAAA,QqC1sJG,aACA,QAAA,KAOJ,YCtCE,SAAA,StC+uJD,IAAA,KCmBD,eqC7vJM,iBAAA,KALJ,2BD0CF,2BrC4sJC,iBAAA,QCmBD,eqCpwJM,iBAAA,QALJ,2BD8CF,2BrC+sJC,iBAAA,QCmBD,eqC3wJM,iBAAA,QALJ,2BDkDF,2BrCktJC,iBAAA,QCmBD,YqClxJM,iBAAA,QALJ,wBDsDF,wBrCqtJC,iBAAA,QCmBD,eqCzxJM,iBAAA,QALJ,2BD0DF,2BrCwtJC,iBAAA,QCmBD,cqChyJM,iBAAA,QCDJ,0BADF,0BAEE,iBAAA,QAEA,OACA,QAAA,aACA,UAAA,KACA,QAAA,IAAA,IACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OvCqxJD,YAAA,OuClxJC,eAAA,OACE,iBAAA,KvCoxJH,cAAA,KuC/wJG,aACA,QAAA,KAGF,YtCkyJA,SAAU,SsChyJR,IAAA,KAMA,0BvC4wJH,eCmBC,IAAK,EsC7xJD,QAAA,IAAA,IvCgxJL,cuC9wJK,cAKJ,MAAA,KtC4xJA,gBAAiB,KsC1xJf,OAAA,QvC4wJH,+BuCxwJC,4BACE,MAAA,QvC0wJH,iBAAA,KuCtwJG,wBvCywJH,MAAA,MuCrwJG,+BvCwwJH,aAAA,IwCj0JC,uBACA,YAAA,IAEA,WACA,YAAA,KxCo0JD,eAAA,KwCz0JC,cAAe,KvC41Jf,MAAO,QuCn1JL,iBAAA,KAIA,eAbJ,cAcI,MAAA,QxCo0JH,awCl1JC,cAAe,KAmBb,UAAA,KxCk0JH,YAAA,ICmBD,cuCh1JI,iBAAA,QAEA,sBxCi0JH,4BwC31JC,cAAe,KA8Bb,aAAA,KxCg0JH,cAAA,IwC7yJD,sBAfI,UAAA,KxCi0JD,oCwC9zJC,WvCi1JA,YAAa,KuC/0JX,eAAA,KxCi0JH,sBwCvzJD,4BvC00JE,cAAe,KuC90Jb,aAAA,KC5CJ,ezC42JD,cyC32JC,UAAA,MAGA,WACA,QAAA,MACA,QAAA,IACA,cAAA,KrCiLA,YAAA,WACK,iBAAA,KACG,OAAA,IAAA,MAAA,KJ8rJT,cAAA,IyCx3JC,mBAAoB,OAAO,IAAI,YxC24J1B,cAAe,OAAO,IAAI,YwC93J7B,WAAA,OAAA,IAAA,YAKF,iBzC22JD,eCmBC,aAAc,KACd,YAAa,KwCv3JX,mBA1BJ,kBzCk4JC,kByCv2JG,aAAA,QCzBJ,oBACE,QAAA,IACA,MAAA,KAEA,O1Cs4JD,QAAA,K0C14JC,cAAe,KAQb,OAAA,IAAA,MAAA,YAEA,cAAA,IAVJ,UAeI,WAAA,E1Ck4JH,MAAA,QCmBD,mByC/4JI,YAAA,IArBJ,SAyBI,U1C+3JH,cAAA,ECmBD,WyCx4JE,WAAA,IAFF,mBAAA,mBAMI,cAAA,KAEA,0BACA,0B1Cy3JH,SAAA,S0Cj3JC,IAAK,KCvDL,MAAA,MACA,MAAA,Q3C46JD,e0Ct3JC,MAAO,QClDL,iBAAA,Q3C26JH,aAAA,Q2Cx6JG,kB3C26JH,iBAAA,Q2Cn7JC,2BACA,MAAA,Q3Cu7JD,Y0C73JC,MAAO,QCtDL,iBAAA,Q3Cs7JH,aAAA,Q2Cn7JG,e3Cs7JH,iBAAA,Q2C97JC,wBACA,MAAA,Q3Ck8JD,e0Cp4JC,MAAO,QC1DL,iBAAA,Q3Ci8JH,aAAA,Q2C97JG,kB3Ci8JH,iBAAA,Q2Cz8JC,2BACA,MAAA,Q3C68JD,c0C34JC,MAAO,QC9DL,iBAAA,Q3C48JH,aAAA,Q2Cz8JG,iB3C48JH,iBAAA,Q4C78JC,0BAAQ,MAAA,QACR,wCAAQ,K5Cm9JP,oBAAA,KAAA,E4C/8JD,GACA,oBAAA,EAAA,GACA,mCAAQ,K5Cq9JP,oBAAA,KAAA,E4Cv9JD,GACA,oBAAA,EAAA,GACA,gCAAQ,K5Cq9JP,oBAAA,KAAA,E4C78JD,GACA,oBAAA,EAAA,GAGA,UACA,OAAA,KxCsCA,cAAA,KACQ,SAAA,OJ26JT,iBAAA,Q4C78JC,cAAe,IACf,mBAAA,MAAA,EAAA,IAAA,IAAA,eACA,WAAA,MAAA,EAAA,IAAA,IAAA,eAEA,cACA,MAAA,KACA,MAAA,EACA,OAAA,KACA,UAAA,KxCyBA,YAAA,KACQ,MAAA,KAyHR,WAAA,OACK,iBAAA,QACG,mBAAA,MAAA,EAAA,KAAA,EAAA,gBJ+zJT,WAAA,MAAA,EAAA,KAAA,EAAA,gB4C18JC,mBAAoB,MAAM,IAAI,K3Cq+JzB,cAAe,MAAM,IAAI,K4Cp+J5B,WAAA,MAAA,IAAA,KDEF,sBCAE,gCDAF,iBAAA,yK5C88JD,iBAAA,oK4Cv8JC,iBAAiB,iK3Cm+JjB,wBAAyB,KAAK,KG/gK9B,gBAAA,KAAA,KJy/JD,qBIv/JS,+BwCmDR,kBAAmB,qBAAqB,GAAG,OAAO,SErElD,aAAA,qBAAA,GAAA,OAAA,S9C4gKD,UAAA,qBAAA,GAAA,OAAA,S6Cz9JG,sBACA,iBAAA,Q7C69JH,wC4Cx8JC,iBAAkB,yKEzElB,iBAAA,oK9CohKD,iBAAA,iK6Cj+JG,mBACA,iBAAA,Q7Cq+JH,qC4C58JC,iBAAkB,yKE7ElB,iBAAA,oK9C4hKD,iBAAA,iK6Cz+JG,sBACA,iBAAA,Q7C6+JH,wC4Ch9JC,iBAAkB,yKEjFlB,iBAAA,oK9CoiKD,iBAAA,iK6Cj/JG,qBACA,iBAAA,Q7Cq/JH,uC+C5iKC,iBAAkB,yKAElB,iBAAA,oK/C6iKD,iBAAA,iK+C1iKG,O/C6iKH,WAAA,KC4BD,mB8CnkKE,WAAA,E/C4iKD,O+CxiKD,YACE,SAAA,O/C0iKD,KAAA,E+CtiKC,Y/CyiKD,MAAA,Q+CriKG,c/CwiKH,QAAA,MC4BD,4B8C9jKE,UAAA,KAGF,aAAA,mBAEE,aAAA,KAGF,YAAA,kB9C+jKE,cAAe,K8CxjKjB,YAHE,Y/CoiKD,a+ChiKC,QAAA,W/CmiKD,eAAA,I+C/hKC,c/CkiKD,eAAA,O+C7hKC,cACA,eAAA,OAMF,eACE,WAAA,EACA,cAAA,ICvDF,YAEE,aAAA,EACA,WAAA,KAQF,YACE,aAAA,EACA,cAAA,KAGA,iBACA,SAAA,SACA,QAAA,MhD6kKD,QAAA,KAAA,KgD1kKC,cAAA,KrB3BA,iBAAA,KACC,OAAA,IAAA,MAAA,KqB6BD,6BACE,uBAAA,IrBvBF,wBAAA,I3BsmKD,4BgDpkKC,cAAe,E/CgmKf,2BAA4B,I+C9lK5B,0BAAA,IAFF,kBAAA,uBAKI,MAAA,KAIF,2CAAA,gD/CgmKA,MAAO,K+C5lKL,wBAFA,wBhDykKH,6BgDxkKG,6BAKF,MAAO,KACP,gBAAA,KACA,iBAAA,QAKA,uB/C4lKA,MAAO,KACP,WAAY,K+CzlKV,0BhDmkKH,gCgDlkKG,gCALF,MAAA,K/CmmKA,OAAQ,YACR,iBAAkB,KDxBnB,mDgD5kKC,yDAAA,yD/CymKA,MAAO,QDxBR,gDgDhkKC,sDAAA,sD/C6lKA,MAAO,K+CzlKL,wBAEA,8BADA,8BhDmkKH,QAAA,EgDxkKC,MAAA,K/ComKA,iBAAkB,QAClB,aAAc,QAEhB,iDDpBC,wDCuBD,uDADA,uD+CzmKE,8DAYI,6D/C4lKN,uD+CxmKE,8D/C2mKF,6DAKE,MAAO,QDxBR,8CiD1qKG,oDADF,oDAEE,MAAA,QAEA,yBhDusKF,MAAO,QgDrsKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDwsKJ,MAAO,QDtBR,gCiDhrKO,gCAGF,qCAFE,qChD2sKN,MAAO,QACP,iBAAkB,QAEpB,iCgDvsKQ,uCAFA,uChD0sKR,sCDtBC,4CiDnrKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,sBhDouKF,MAAO,QgDluKH,iBAAA,QAFF,uBAAA,4BAKI,MAAA,QAGF,gDAAA,qDhDquKJ,MAAO,QDtBR,6BiD7sKO,6BAGF,kCAFE,kChDwuKN,MAAO,QACP,iBAAkB,QAEpB,8BgDpuKQ,oCAFA,oChDuuKR,mCDtBC,yCiDhtKO,yCArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,yBhDiwKF,MAAO,QgD/vKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDkwKJ,MAAO,QDtBR,gCiD1uKO,gCAGF,qCAFE,qChDqwKN,MAAO,QACP,iBAAkB,QAEpB,iCgDjwKQ,uCAFA,uChDowKR,sCDtBC,4CiD7uKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,wBhD8xKF,MAAO,QgD5xKH,iBAAA,QAFF,yBAAA,8BAKI,MAAA,QAGF,kDAAA,uDhD+xKJ,MAAO,QDtBR,+BiDvwKO,+BAGF,oCAFE,oChDkyKN,MAAO,QACP,iBAAkB,QAEpB,gCgD9xKQ,sCAFA,sChDiyKR,qCDtBC,2CiD1wKO,2CDkGN,MAAO,KACP,iBAAA,QACA,aAAA,QAEF,yBACE,WAAA,EACA,cAAA,IE1HF,sBACE,cAAA,EACA,YAAA,IAEA,O9C0DA,cAAA,KACQ,iBAAA,KJ6uKT,OAAA,IAAA,MAAA,YkDnyKC,cAAe,IACf,mBAAA,EAAA,IAAA,IAAA,gBlDqyKD,WAAA,EAAA,IAAA,IAAA,gBkD/xKC,YACA,QAAA,KvBnBC,e3BuzKF,QAAA,KAAA,KkDtyKC,cAAe,IAAI,MAAM,YAMvB,uBAAA,IlDmyKH,wBAAA,IkD7xKC,0CACA,MAAA,QAEA,alDgyKD,WAAA,EkDpyKC,cAAe,EjDg0Kf,UAAW,KACX,MAAO,QDtBR,oBkD1xKC,sBjDkzKF,eiDxzKI,mBAKJ,qBAEE,MAAA,QvBvCA,cACC,QAAA,KAAA,K3Bs0KF,iBAAA,QkDrxKC,WAAY,IAAI,MAAM,KjDizKtB,2BAA4B,IiD9yK1B,0BAAA,IAHJ,mBAAA,mCAMM,cAAA,ElDwxKL,oCkDnxKG,oDjD+yKF,aAAc,IAAI,EiD7yKZ,cAAA,EvBtEL,4D3B61KF,4EkDjxKG,WAAA,EjD6yKF,uBAAwB,IiD3yKlB,wBAAA,IvBtEL,0D3B21KF,0EkD1yKC,cAAe,EvB1Df,2BAAA,IACC,0BAAA,IuB0FH,+EAEI,uBAAA,ElD8wKH,wBAAA,EkD1wKC,wDlD6wKD,iBAAA,EC4BD,0BACE,iBAAkB,EiDlyKpB,8BlD0wKC,ckD1wKD,gCjDuyKE,cAAe,EiDvyKjB,sCAQM,sBlDwwKL,wCC4BC,cAAe,K0Br5Kf,aAAA,KuByGF,wDlDqxKC,0BC4BC,uBAAwB,IACxB,wBAAyB,IiDlzK3B,yFAoBQ,yFlDwwKP,2DkDzwKO,2DjDqyKN,uBAAwB,IACxB,wBAAyB,IAK3B,wGiD9zKA,wGjD4zKA,wGDtBC,wGCuBD,0EiD7zKA,0EjD2zKA,0EiDnyKU,0EjD2yKR,uBAAwB,IAK1B,uGiDx0KA,uGjDs0KA,uGDtBC,uGCuBD,yEiDv0KA,yEjDq0KA,yEiDzyKU,yEvB7HR,wBAAA,IuBiGF,sDlDqzKC,yBC4BC,2BAA4B,IAC5B,0BAA2B,IiDxyKrB,qFA1CR,qFAyCQ,wDlDmxKP,wDC4BC,2BAA4B,IAC5B,0BAA2B,IAG7B,oGDtBC,oGCwBD,oGiD91KA,oGjD21KA,uEiD7yKU,uEjD+yKV,uEiD71KA,uEjDm2KE,0BAA2B,IAG7B,mGDtBC,mGCwBD,mGiDx2KA,mGjDq2KA,sEiDnzKU,sEjDqzKV,sEiDv2KA,sEjD62KE,2BAA4B,IiDlzK1B,0BlD2xKH,qCkDt1KD,0BAAA,qCA+DI,WAAA,IAAA,MAAA,KA/DJ,kDAAA,kDAmEI,WAAA,EAnEJ,uBAAA,yCjD23KE,OAAQ,EiDjzKA,+CjDqzKV,+CiD/3KA,+CjDi4KA,+CAEA,+CANA,+CDjBC,iECoBD,iEiDh4KA,iEjDk4KA,iEAEA,iEANA,iEAWE,YAAa,EiD3zKL,8CjD+zKV,8CiD74KA,8CjD+4KA,8CAEA,8CANA,8CDjBC,gECoBD,gEiD94KA,gEjDg5KA,gEAEA,gEANA,gEAWE,aAAc,EAIhB,+CiD35KA,+CjDy5KA,+CiDl0KU,+CjDq0KV,iEiD55KA,iEjD05KA,iEDtBC,iEC6BC,cAAe,EAEjB,8CiDn0KU,8CjDq0KV,8CiDr6KA,8CjDo6KA,gEDtBC,gECwBD,gEiDh0KI,gEACA,cAAA,EAUJ,yBACE,cAAA,ElDmyKD,OAAA,EkD/xKG,aACA,cAAA,KANJ,oBASM,cAAA,ElDkyKL,cAAA,IkD7xKG,2BlDgyKH,WAAA,IC4BD,4BiDxzKM,cAAA,EAKF,wDAvBJ,wDlDqzKC,WAAA,IAAA,MAAA,KkD5xKK,2BlD+xKL,WAAA,EmDlhLC,uDnDqhLD,cAAA,IAAA,MAAA,KmDlhLG,eACA,aAAA,KnDshLH,8BmDxhLC,MAAA,KAMI,iBAAA,QnDqhLL,aAAA,KmDlhLK,0DACA,iBAAA,KAGJ,qCAEI,MAAA,QnDmhLL,iBAAA,KmDpiLC,yDnDuiLD,oBAAA,KmDpiLG,eACA,aAAA,QnDwiLH,8BmD1iLC,MAAA,KAMI,iBAAA,QnDuiLL,aAAA,QmDpiLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDqiLL,iBAAA,KmDtjLC,yDnDyjLD,oBAAA,QmDtjLG,eACA,aAAA,QnD0jLH,8BmD5jLC,MAAA,QAMI,iBAAA,QnDyjLL,aAAA,QmDtjLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDujLL,iBAAA,QmDxkLC,yDnD2kLD,oBAAA,QmDxkLG,YACA,aAAA,QnD4kLH,2BmD9kLC,MAAA,QAMI,iBAAA,QnD2kLL,aAAA,QmDxkLK,uDACA,iBAAA,QAGJ,kCAEI,MAAA,QnDykLL,iBAAA,QmD1lLC,sDnD6lLD,oBAAA,QmD1lLG,eACA,aAAA,QnD8lLH,8BmDhmLC,MAAA,QAMI,iBAAA,QnD6lLL,aAAA,QmD1lLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnD2lLL,iBAAA,QmD5mLC,yDnD+mLD,oBAAA,QmD5mLG,cACA,aAAA,QnDgnLH,6BmDlnLC,MAAA,QAMI,iBAAA,QnD+mLL,aAAA,QmD5mLK,yDACA,iBAAA,QAGJ,oCAEI,MAAA,QnD6mLL,iBAAA,QoD5nLC,wDACA,oBAAA,QAEA,kBACA,SAAA,SpD+nLD,QAAA,MoDpoLC,OAAQ,EnDgqLR,QAAS,EACT,SAAU,OAEZ,yCmDtpLI,wBADA,yBAEA,yBACA,wBACA,SAAA,SACA,IAAA,EACA,OAAA,EpD+nLH,KAAA,EoD1nLC,MAAO,KACP,OAAA,KpD4nLD,OAAA,EoDvnLC,wBpD0nLD,eAAA,OqDppLC,uBACA,eAAA,IAEA,MACA,WAAA,KACA,QAAA,KjDwDA,cAAA,KACQ,iBAAA,QJgmLT,OAAA,IAAA,MAAA,QqD/pLC,cAAe,IASb,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACA,WAAA,MAAA,EAAA,IAAA,IAAA,gBAKJ,iBACE,aAAA,KACA,aAAA,gBAEF,SACE,QAAA,KACA,cAAA,ICtBF,SACE,QAAA,IACA,cAAA,IAEA,OACA,MAAA,MACA,UAAA,KjCRA,YAAA,IAGA,YAAA,ErBqrLD,MAAA,KsD7qLC,YAAA,EAAA,IAAA,EAAA,KrDysLA,OAAQ,kBqDvsLN,QAAA,GjCbF,aiCeE,ajCZF,MAAA,KrB6rLD,gBAAA,KsDzqLC,OAAA,QACE,OAAA,kBACA,QAAA,GAEA,aACA,mBAAA,KtD2qLH,QAAA,EuDhsLC,OAAQ,QACR,WAAA,IvDksLD,OAAA,EuD7rLC,YACA,SAAA,OAEA,OACA,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EAIA,QAAA,KvD6rLD,QAAA,KuD1rLC,SAAA,OnD+GA,2BAAA,MACI,QAAA,EAEI,0BAkER,mBAAA,kBAAA,IAAA,SAEK,cAAA,aAAA,IAAA,SACG,WAAA,UAAA,IAAA,SJ6gLT,kBAAA,kBuDhsLC,cAAA,kBnD2GA,aAAA,kBACI,UAAA,kBAEI,wBJwlLT,kBAAA,euDpsLK,cAAe,eACnB,aAAA,eACA,UAAA,eAIF,mBACE,WAAA,OACA,WAAA,KvDqsLD,cuDhsLC,SAAU,SACV,MAAA,KACA,OAAA,KAEA,eACA,SAAA,SnDaA,iBAAA,KACQ,wBAAA,YmDZR,gBAAA,YtD4tLA,OsD5tLA,IAAA,MAAA,KAEA,OAAA,IAAA,MAAA,evDksLD,cAAA,IuD9rLC,QAAS,EACT,mBAAA,EAAA,IAAA,IAAA,eACA,WAAA,EAAA,IAAA,IAAA,eAEA,gBACA,SAAA,MACA,IAAA,EACA,MAAA,EvDgsLD,OAAA,EuD9rLC,KAAA,ElCrEA,QAAA,KAGA,iBAAA,KkCmEA,qBlCtEA,OAAA,iBAGA,QAAA,EkCwEF,mBACE,OAAA,kBACA,QAAA,GAIF,cACE,QAAA,KvDgsLD,cAAA,IAAA,MAAA,QuD3rLC,qBACA,WAAA,KAKF,aACE,OAAA,EACA,YAAA,WAIF,YACE,SAAA,SACA,QAAA,KvD0rLD,cuD5rLC,QAAS,KAQP,WAAA,MACA,WAAA,IAAA,MAAA,QATJ,wBAaI,cAAA,EvDsrLH,YAAA,IuDlrLG,mCvDqrLH,YAAA,KuD/qLC,oCACA,YAAA,EAEA,yBACA,SAAA,SvDkrLD,IAAA,QuDhqLC,MAAO,KAZP,OAAA,KACE,SAAA,OvDgrLD,yBuD7qLD,cnDvEA,MAAA,MACQ,OAAA,KAAA,KmD2ER,eAAY,mBAAA,EAAA,IAAA,KAAA,evD+qLX,WAAA,EAAA,IAAA,KAAA,euDzqLD,UAFA,MAAA,OvDirLD,yBwD/zLC,UACA,MAAA,OCNA,SAEA,SAAA,SACA,QAAA,KACA,QAAA,MACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KACA,eAAA,ODHA,WAAA,OnCVA,aAAA,OAGA,UAAA,OrBs1LD,YAAA,OwD30LC,OAAA,iBnCdA,QAAA,ErB61LD,WAAA,KwD90LY,YAAmB,OAAA,kBxDk1L/B,QAAA,GwDj1LY,aAAmB,QAAA,IAAA,ExDq1L/B,WAAA,KwDp1LY,eAAmB,QAAA,EAAA,IxDw1L/B,YAAA,IwDv1LY,gBAAmB,QAAA,IAAA,ExD21L/B,WAAA,IwDt1LC,cACA,QAAA,EAAA,IACA,YAAA,KAEA,eACA,UAAA,MxDy1LD,QAAA,IAAA,IwDr1LC,MAAO,KACP,WAAA,OACA,iBAAA,KACA,cAAA,IAEA,exDu1LD,SAAA,SwDn1LC,MAAA,EACE,OAAA,EACA,aAAA,YACA,aAAA,MAEA,4BxDq1LH,OAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,iCxDq1LH,MAAA,IwDn1LC,OAAA,EACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,kCxDq1LH,OAAA,EwDn1LC,KAAA,IACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,8BxDq1LH,IAAA,IwDn1LC,KAAA,EACE,WAAA,KACA,aAAA,IAAA,IAAA,IAAA,EACA,mBAAA,KAEA,6BxDq1LH,IAAA,IwDn1LC,MAAA,EACE,WAAA,KACA,aAAA,IAAA,EAAA,IAAA,IACA,kBAAA,KAEA,+BxDq1LH,IAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,oCxDq1LH,IAAA,EwDn1LC,MAAA,IACE,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,qCxDq1LH,IAAA,E0Dl7LC,KAAM,IACN,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,SACA,SAAA,SACA,IAAA,EDXA,KAAA,EAEA,QAAA,KACA,QAAA,KACA,UAAA,MACA,QAAA,IACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KCAA,eAAA,OAEA,WAAA,OACA,aAAA,OAAA,UAAA,OACA,YAAA,OACA,iBAAA,KACA,wBAAA,YtD8CA,gBAAA,YACQ,OAAA,IAAA,MAAA,KJk5LT,OAAA,IAAA,MAAA,e0D77LC,cAAA,IAAY,mBAAA,EAAA,IAAA,KAAA,e1Dg8Lb,WAAA,EAAA,IAAA,KAAA,e0D/7La,WAAA,KACZ,aAAY,WAAA,MACZ,eAAY,YAAA,KAGd,gBACE,WAAA,KAEA,cACA,YAAA,MAEA,e1Dq8LD,QAAA,IAAA,K0Dl8LC,OAAQ,EACR,UAAA,K1Do8LD,iBAAA,Q0D57LC,cAAA,IAAA,MAAA,QzDy9LA,cAAe,IAAI,IAAI,EAAE,EyDt9LvB,iBACA,QAAA,IAAA,KAEA,gBACA,sB1D87LH,SAAA,S0D37LC,QAAS,MACT,MAAA,E1D67LD,OAAA,E0D37LC,aAAc,YACd,aAAA,M1D87LD,gB0Dz7LC,aAAA,KAEE,sBACA,QAAA,GACA,aAAA,KAEA,oB1D27LH,OAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,KACA,iBAAA,gBACA,oBAAA,E1D67LL,0B0Dz7LC,OAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,KACA,oBAAA,EAEA,sB1D27LH,IAAA,I0D17LG,KAAA,MACE,WAAA,MACA,mBAAA,KACA,mBAAA,gBACA,kBAAA,E1D67LL,4B0Dz7LC,OAAA,MACE,KAAA,IACA,QAAA,IACA,mBAAA,KACA,kBAAA,EAEA,uB1D27LH,IAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,EACA,oBAAA,KACA,oBAAA,gB1D67LL,6B0Dx7LC,IAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,EACA,oBAAA,KAEA,qB1D07LH,IAAA,I0Dz7LG,MAAA,MACE,WAAA,MACA,mBAAA,EACA,kBAAA,KACA,kBAAA,gB1D47LL,2B2DpjMC,MAAO,IACP,OAAA,M3DsjMD,QAAA,I2DnjMC,mBAAoB,EACpB,kBAAA,KAEA,U3DqjMD,SAAA,S2DljMG,gBACA,SAAA,SvD6KF,MAAA,KACK,SAAA,OJ04LN,sB2D/jMC,SAAU,S1D4lMV,QAAS,K0D9kML,mBAAA,IAAA,YAAA,K3DqjML,cAAA,IAAA,YAAA,K2D3hMC,WAAA,IAAA,YAAA,KvDmKK,4BAFL,0BAGQ,YAAA,EA3JA,qDA+GR,sBAEQ,mBAAA,kBAAA,IAAA,YJ86LP,cAAA,aAAA,IAAA,Y2DzjMG,WAAA,UAAA,IAAA,YvDmHJ,4BAAA,OACQ,oBAAA,OuDjHF,oBAAA,O3D4jML,YAAA,OI58LD,mCHs+LA,2BGr+LQ,KAAA,EuD5GF,kBAAA,sB3D6jML,UAAA,sBC2BD,kCADA,2BG5+LA,KAAA,EACQ,kBAAA,uBuDtGF,UAAA,uBArCN,6B3DomMD,gC2DpmMC,iC1D+nME,KAAM,E0DllMN,kBAAA,mB3D4jMH,UAAA,oBAGA,wB2D5mMD,sBAAA,sBAsDI,QAAA,MAEA,wB3D0jMH,KAAA,E2DtjMG,sB3DyjMH,sB2DrnMC,SAAU,SA+DR,IAAA,E3DyjMH,MAAA,KC0BD,sB0D/kMI,KAAA,KAnEJ,sBAuEI,KAAA,MAvEJ,2BA0EI,4B3DwjMH,KAAA,E2D/iMC,6BACA,KAAA,MAEA,8BACA,KAAA,KtC3FA,kBsC6FA,SAAA,SACA,IAAA,EACA,OAAA,EACA,KAAA,EACA,MAAA,I3DmjMD,UAAA,K2D9iMC,MAAA,KdnGE,WAAA,OACA,YAAA,EAAA,IAAA,IAAA,eACA,iBAAA,cAAA,OAAA,kBACA,QAAA,G7CqpMH,uB2DljMC,iBAAA,sEACE,iBAAA,iEACA,iBAAA,uFdxGA,iBAAA,kEACA,OAAA,+GACA,kBAAA,SACA,wBACA,MAAA,E7C6pMH,KAAA,K2DpjMC,iBAAA,sE1DglMA,iBAAiB,iE0D9kMf,iBAAA,uFACA,iBAAA,kEACA,OAAA,+GtCvHF,kBAAA,SsCyFF,wB3DslMC,wBC4BC,MAAO,KACP,gBAAiB,KACjB,OAAQ,kB0D7kMN,QAAA,EACA,QAAA,G3DwjMH,0C2DhmMD,2CA2CI,6BADA,6B1DklMF,SAAU,S0D7kMR,IAAA,IACA,QAAA,E3DqjMH,QAAA,a2DrmMC,WAAY,MAqDV,0CADA,6B3DsjMH,KAAA,I2D1mMC,YAAa,MA0DX,2CADA,6BAEA,MAAA,IACA,aAAA,MAME,6BADF,6B3DmjMH,MAAA,K2D9iMG,OAAA,KACE,YAAA,M3DgjML,YAAA,E2DriMC,oCACA,QAAA,QAEA,oCACA,QAAA,QAEA,qBACA,SAAA,SACA,OAAA,K3DwiMD,KAAA,I2DjjMC,QAAS,GAYP,MAAA,IACA,aAAA,EACA,YAAA,KACA,WAAA,OACA,WAAA,KAEA,wBACA,QAAA,aAWA,MAAA,KACA,OAAA,K3D8hMH,OAAA,I2D7jMC,YAAa,OAkCX,OAAA,QACA,iBAAA,OACA,iBAAA,cACA,OAAA,IAAA,MAAA,K3D8hMH,cAAA,K2DthMC,6BACA,MAAA,KACA,OAAA,KACA,OAAA,EACA,iBAAA,KAEA,kBACA,SAAA,SACA,MAAA,IACA,OAAA,K3DyhMD,KAAA,I2DxhMC,QAAA,GACE,YAAA,K3D0hMH,eAAA,K2Dj/LC,MAAO,KAhCP,WAAA,O1D8iMA,YAAa,EAAE,IAAI,IAAI,eAEzB,uB0D3iMM,YAAA,KAEA,oCACA,0C3DmhMH,2C2D3hMD,6BAAA,6BAYI,MAAA,K3DmhMH,OAAA,K2D/hMD,WAAA,M1D2jME,UAAW,KDxBZ,0C2D9gMD,6BACE,YAAA,MAEA,2C3DghMD,6B2D5gMD,aAAA,M3D+gMC,kBACF,MAAA,I4D7wMC,KAAA,I3DyyME,eAAgB,KAElB,qBACE,OAAQ,MAkBZ,qCADA,sCADA,mBADA,oBAXA,gBADA,iBAOA,uBADA,wBADA,iBADA,kBADA,wBADA,yBASA,mCADA,oC2DpzME,oBAAA,qBAAA,oBAAA,qB3D2zMF,WADA,YAOA,uBADA,wBADA,qBADA,sBADA,cADA,e2D/zMI,a3Dq0MJ,cDvBC,kB4D7yMG,mB3DqzMJ,WADA,YAwBE,QAAS,MACT,QAAS,IASX,qCADA,mBANA,gBAGA,uBADA,iBADA,wBAIA,mCDhBC,oB6D/0MC,oB5Dk2MF,W+B51MA,uBhCo0MC,qB4D5zMG,cChBF,aACA,kB5D+1MF,W+Br1ME,MAAO,KhCy0MR,cgCt0MC,QAAS,MACT,aAAA,KhCw0MD,YAAA,KgC/zMC,YhCk0MD,MAAA,gBgC/zMC,WhCk0MD,MAAA,egC/zMC,MhCk0MD,QAAA,e8Dz1MC,MACA,QAAA,gBAEA,WACA,WAAA,O9B8BF,WACE,KAAA,EAAA,EAAA,EhCg0MD,MAAA,YgCzzMC,YAAa,KACb,iBAAA,YhC2zMD,OAAA,E+D31MC,Q/D81MD,QAAA,eC4BD,OACE,SAAU,M+Dn4MV,chE42MD,MAAA,aC+BD,YADA,YADA,YADA,YAIE,QAAS,e+Dp5MT,kBhEs4MC,mBgEr4MD,yBhEi4MD,kB+Dl1MD,mBA6IA,yB9D4tMA,kBACA,mB8Dj3ME,yB9D62MF,kBACA,mBACA,yB+Dv5MY,QAAA,eACV,yBAAU,YhE04MT,QAAA,gBC4BD,iB+Dp6MU,QAAA,gBhE64MX,c+D51MG,QAAS,oB/Dg2MV,c+Dl2MC,c/Dm2MH,QAAA,sB+D91MG,yB/Dk2MD,kBACF,QAAA,iB+D91MG,yB/Dk2MD,mBACF,QAAA,kBgEh6MC,yBhEo6MC,yBgEn6MD,QAAA,wBACA,+CAAU,YhEw6MT,QAAA,gBC4BD,iB+Dl8MU,QAAA,gBhE26MX,c+Dr2MG,QAAS,oB/Dy2MV,c+D32MC,c/D42MH,QAAA,sB+Dv2MG,+C/D22MD,kBACF,QAAA,iB+Dv2MG,+C/D22MD,mBACF,QAAA,kBgE97MC,+ChEk8MC,yBgEj8MD,QAAA,wBACA,gDAAU,YhEs8MT,QAAA,gBC4BD,iB+Dh+MU,QAAA,gBhEy8MX,c+D92MG,QAAS,oB/Dk3MV,c+Dp3MC,c/Dq3MH,QAAA,sB+Dh3MG,gD/Do3MD,kBACF,QAAA,iB+Dh3MG,gD/Do3MD,mBACF,QAAA,kBgE59MC,gDhEg+MC,yBgE/9MD,QAAA,wBACA,0BAAU,YhEo+MT,QAAA,gBC4BD,iB+D9/MU,QAAA,gBhEu+MX,c+Dv3MG,QAAS,oB/D23MV,c+D73MC,c/D83MH,QAAA,sB+Dz3MG,0B/D63MD,kBACF,QAAA,iB+Dz3MG,0B/D63MD,mBACF,QAAA,kBgEl/MC,0BhEs/MC,yBACF,QAAA,wBgEv/MC,yBhE2/MC,WACF,QAAA,gBgE5/MC,+ChEggNC,WACF,QAAA,gBgEjgNC,gDhEqgNC,WACF,QAAA,gBAGA,0B+Dh3MC,WA4BE,QAAS,gBC5LX,eAAU,QAAA,eACV,aAAU,ehEyhNT,QAAA,gBC4BD,oB+DnjNU,QAAA,gBhE4hNX,iB+D93MG,QAAS,oBAMX,iB/D23MD,iB+Dt2MG,QAAS,sB/D22MZ,qB+D/3MC,QAAS,e/Dk4MV,a+D53MC,qBAcE,QAAS,iB/Dm3MZ,sB+Dh4MC,QAAS,e/Dm4MV,a+D73MC,sBAOE,QAAS,kB/D23MZ,4B+D53MC,QAAS,eCpLT,ahEojNC,4BACF,QAAA,wBC6BD,aACE,cACE,QAAS","sourcesContent":["/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n//    without disabling user zoom.\n//\n\nhtml {\n  font-family: sans-serif; // 1\n  -ms-text-size-adjust: 100%; // 2\n  -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n  margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; // 1\n  vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n  background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n  outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n  font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n  font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n  border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n  margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n  box-sizing: content-box;\n  height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n  overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n//    Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; // 1\n  font: inherit; // 2\n  margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n  overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n//    and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n//    `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n  cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n  line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; // 1\n  padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; // 1\n  box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n  border: 0; // 1\n  padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n  overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n  font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n    *,\n    *:before,\n    *:after {\n        background: transparent !important;\n        color: #000 !important; // Black prints faster: h5bp.com/s\n        box-shadow: none !important;\n        text-shadow: none !important;\n    }\n\n    a,\n    a:visited {\n        text-decoration: underline;\n    }\n\n    a[href]:after {\n        content: \" (\" attr(href) \")\";\n    }\n\n    abbr[title]:after {\n        content: \" (\" attr(title) \")\";\n    }\n\n    // Don't show links that are fragment identifiers,\n    // or use the `javascript:` pseudo protocol\n    a[href^=\"#\"]:after,\n    a[href^=\"javascript:\"]:after {\n        content: \"\";\n    }\n\n    pre,\n    blockquote {\n        border: 1px solid #999;\n        page-break-inside: avoid;\n    }\n\n    thead {\n        display: table-header-group; // h5bp.com/t\n    }\n\n    tr,\n    img {\n        page-break-inside: avoid;\n    }\n\n    img {\n        max-width: 100% !important;\n    }\n\n    p,\n    h2,\n    h3 {\n        orphans: 3;\n        widows: 3;\n    }\n\n    h2,\n    h3 {\n        page-break-after: avoid;\n    }\n\n    // Bootstrap specific changes start\n\n    // Bootstrap components\n    .navbar {\n        display: none;\n    }\n    .btn,\n    .dropup > .btn {\n        > .caret {\n            border-top-color: #000 !important;\n        }\n    }\n    .label {\n        border: 1px solid #000;\n    }\n\n    .table {\n        border-collapse: collapse !important;\n\n        td,\n        th {\n            background-color: #fff !important;\n        }\n    }\n    .table-bordered {\n        th,\n        td {\n            border: 1px solid #ddd !important;\n        }\n    }\n\n    // Bootstrap specific changes end\n}\n","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\nmark {\n  background: #ff0;\n  color: #000;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\nsup {\n  top: -0.5em;\n}\nsub {\n  bottom: -0.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  box-sizing: content-box;\n  height: 0;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit;\n  font: inherit;\n  margin: 0;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n  border: 0;\n  padding: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    background: transparent !important;\n    color: #000 !important;\n    box-shadow: none !important;\n    text-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  background-color: #fcf8e3;\n  padding: .2em;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n  margin-left: -5px;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-left: 5px;\n  padding-right: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    clear: left;\n    text-align: right;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n  text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: #333333;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.row {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0%;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0%;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  min-width: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  border: 0;\n  background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eeeeee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n  min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  border-color: #3c763d;\n  background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  border-color: #8a6d3b;\n  background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  border-color: #a94442;\n  background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  margin-top: 0;\n  margin-bottom: 0;\n  padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    text-align: right;\n    margin-bottom: 0;\n    padding-top: 7px;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  margin-bottom: 0;\n  font-weight: normal;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none;\n  border: 1px solid transparent;\n  white-space: nowrap;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  border-radius: 4px;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  outline: 0;\n  background-image: none;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  color: #337ab7;\n  font-weight: normal;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n  -o-transition: opacity 0.15s linear;\n  transition: opacity 0.15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-property: height, visibility;\n  transition-property: height, visibility;\n  -webkit-transition-duration: 0.35s;\n  transition-duration: 0.35s;\n  -webkit-transition-timing-function: ease;\n  transition-timing-function: ease;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  font-size: 14px;\n  text-align: left;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  text-decoration: none;\n  color: #262626;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  cursor: not-allowed;\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  left: auto;\n  right: 0;\n}\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n  content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    left: auto;\n    right: 0;\n  }\n  .navbar-right .dropdown-menu-left {\n    left: 0;\n    right: auto;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  float: none;\n  display: table-cell;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group .form-control:focus {\n  z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555555;\n  text-align: center;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  margin-bottom: 0;\n  padding-left: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n  color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777777;\n  text-decoration: none;\n  background-color: transparent;\n  cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eeeeee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n  cursor: default;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: 15px;\n  padding-left: 15px;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n  -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n  height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: 15px;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  margin-left: -15px;\n  margin-right: -15px;\n  padding: 10px 15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-left: 15px;\n    margin-right: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  background-color: #e7e7e7;\n  color: #555;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  background-color: #080808;\n  color: #fff;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  content: \"/\\00a0\";\n  padding: 0 5px;\n  color: #ccc;\n}\n.breadcrumb > .active {\n  color: #777777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  line-height: 1.42857143;\n  text-decoration: none;\n  color: #337ab7;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-bottom-right-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 2;\n  color: #23527c;\n  background-color: #eeeeee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 3;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n  cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777777;\n  background-color: #fff;\n  border-color: #ddd;\n  cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-bottom-right-radius: 6px;\n  border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  list-style: none;\n  text-align: center;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777777;\n  background-color: #fff;\n  cursor: not-allowed;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  color: #fff;\n  line-height: 1;\n  vertical-align: middle;\n  white-space: nowrap;\n  text-align: center;\n  background-color: #777777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-left: 60px;\n    padding-right: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border 0.2s ease-in-out;\n  -o-transition: border 0.2s ease-in-out;\n  transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-left: auto;\n  margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n  color: #3c763d;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n  color: #31708f;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n  color: #8a6d3b;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  background-color: #f2dede;\n  border-color: #ebccd1;\n  color: #a94442;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  overflow: hidden;\n  height: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n  -o-transition: width 0.6s ease;\n  transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n  -o-animation: progress-bar-stripes 2s linear infinite;\n  animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  zoom: 1;\n  overflow: hidden;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  margin-bottom: 20px;\n  padding-left: 0;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  text-decoration: none;\n  color: #555;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  background-color: #eeeeee;\n  color: #777777;\n  cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-left-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  border: 0;\n  margin-bottom: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  height: 100%;\n  width: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transform: translate(0, -25%);\n  -ms-transform: translate(0, -25%);\n  -o-transform: translate(0, -25%);\n  transform: translate(0, -25%);\n  -webkit-transition: -webkit-transform 0.3s ease-out;\n  -moz-transition: -moz-transform 0.3s ease-out;\n  -o-transition: -o-transform 0.3s ease-out;\n  transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n  -ms-transform: translate(0, 0);\n  -o-transform: translate(0, 0);\n  transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  background-clip: padding-box;\n  outline: 0;\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-left: 5px;\n  margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  font-size: 12px;\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.tooltip.in {\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.tooltip.top {\n  margin-top: -3px;\n  padding: 5px 0;\n}\n.tooltip.right {\n  margin-left: 3px;\n  padding: 0 5px;\n}\n.tooltip.bottom {\n  margin-top: 3px;\n  padding: 5px 0;\n}\n.tooltip.left {\n  margin-left: -3px;\n  padding: 0 5px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  bottom: 0;\n  right: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  font-size: 14px;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  margin: 0;\n  padding: 8px 14px;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n.popover.top > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-width: 0;\n  border-top-color: #999999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  bottom: -11px;\n}\n.popover.top > .arrow:after {\n  content: \" \";\n  bottom: 1px;\n  margin-left: -10px;\n  border-bottom-width: 0;\n  border-top-color: #fff;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-left-width: 0;\n  border-right-color: #999999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n  content: \" \";\n  left: 1px;\n  bottom: -10px;\n  border-left-width: 0;\n  border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  top: -11px;\n}\n.popover.bottom > .arrow:after {\n  content: \" \";\n  top: 1px;\n  margin-left: -10px;\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n  content: \" \";\n  right: 1px;\n  border-right-width: 0;\n  border-left-color: #fff;\n  bottom: -10px;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n}\n.carousel-inner > .item {\n  display: none;\n  position: relative;\n  -webkit-transition: 0.6s ease-in-out left;\n  -o-transition: 0.6s ease-in-out left;\n  transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform 0.6s ease-in-out;\n    -moz-transition: -moz-transform 0.6s ease-in-out;\n    -o-transition: -o-transform 0.6s ease-in-out;\n    transition: transform 0.6s ease-in-out;\n    -webkit-backface-visibility: hidden;\n    -moz-backface-visibility: hidden;\n    backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n    -moz-perspective: 1000px;\n    perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    -webkit-transform: translate3d(100%, 0, 0);\n    transform: translate3d(100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    -webkit-transform: translate3d(-100%, 0, 0);\n    transform: translate3d(-100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    -webkit-transform: translate3d(0, 0, 0);\n    transform: translate3d(0, 0, 0);\n    left: 0;\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: 15%;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n  background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n  left: auto;\n  right: 0;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  outline: 0;\n  color: #fff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  margin-top: -10px;\n  z-index: 5;\n  display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  line-height: 1;\n  font-family: serif;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  border: 1px solid #fff;\n  border-radius: 10px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n  margin: 0;\n  width: 12px;\n  height: 12px;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  content: \" \";\n  display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  background-color: transparent;\n  border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group .form-control:focus {\n  z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 2;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 3;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  padding-right: 15px;\n  padding-left: 15px;\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  background-color: rgba(0, 0, 0, 0);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('@{icon-font-path}@{icon-font-name}.eot');\n  src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n       url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n       url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n       url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n       url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\002a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur                    { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n.glyphicon-cd                     { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file              { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file              { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up               { &:before { content: \"\\e204\"; } }\n.glyphicon-copy                   { &:before { content: \"\\e205\"; } }\n.glyphicon-paste                  { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door                   { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key                    { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert                  { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer              { &:before { content: \"\\e210\"; } }\n.glyphicon-king                   { &:before { content: \"\\e211\"; } }\n.glyphicon-queen                  { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn                   { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop                 { &:before { content: \"\\e214\"; } }\n.glyphicon-knight                 { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula           { &:before { content: \"\\e216\"; } }\n.glyphicon-tent                   { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard             { &:before { content: \"\\e218\"; } }\n.glyphicon-bed                    { &:before { content: \"\\e219\"; } }\n.glyphicon-apple                  { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase                  { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass              { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp                   { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate              { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank             { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors               { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin                { &:before { content: \"\\e227\"; } }\n.glyphicon-btc                    { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt                    { &:before { content: \"\\e227\"; } }\n.glyphicon-yen                    { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy                    { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble                  { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub                    { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale                  { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly              { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted       { &:before { content: \"\\e232\"; } }\n.glyphicon-education              { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal      { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical        { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger         { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window           { &:before { content: \"\\e237\"; } }\n.glyphicon-oil                    { &:before { content: \"\\e238\"; } }\n.glyphicon-grain                  { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses             { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size              { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color             { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background        { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top       { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom    { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left      { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical  { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right     { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right         { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left          { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom        { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top           { &:before { content: \"\\e253\"; } }\n.glyphicon-console                { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript            { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript              { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left              { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right             { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down              { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up                { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n  .box-sizing(border-box);\n}\n*:before,\n*:after {\n  .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @text-color;\n  background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n\n// Links\n\na {\n  color: @link-color;\n  text-decoration: none;\n\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: @link-hover-decoration;\n  }\n\n  &:focus {\n    .tab-focus();\n  }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n  margin: 0;\n}\n\n\n// Images\n\nimg {\n  vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n  .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n  border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n  padding: @thumbnail-padding;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  // Keep them at most 100% wide\n  .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n  border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n  margin-top:    @line-height-computed;\n  margin-bottom: @line-height-computed;\n  border: 0;\n  border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n  cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n  // WebKit-specific. Other browsers will keep their default outline style.\n  // (Initially tried to also force default via `outline: initial`,\n  // but that seems to erroneously remove the outline in Firefox altogether.)\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 300;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n  font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n  background-color: @state-warning-bg;\n  padding: .2em;\n}\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n.text-nowrap         { white-space: nowrap; }\n\n// Transformation\n.text-lowercase      { text-transform: lowercase; }\n.text-uppercase      { text-transform: uppercase; }\n.text-capitalize     { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n  margin-left: -5px;\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n  dd {\n    &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n  }\n\n  @media (min-width: @dl-horizontal-breakpoint) {\n    dt {\n      float: left;\n      width: (@dl-horizontal-offset - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @dl-horizontal-offset;\n    }\n  }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: @blockquote-font-size;\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n  color: @color;\n  a&:hover,\n  a&:focus {\n    color: darken(@color, 10%);\n  }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n  background-color: @color;\n  a&:hover,\n  a&:focus {\n    background-color: darken(@color, 10%);\n  }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n  kbd {\n    padding: 0;\n    font-size: 100%;\n    font-weight: bold;\n    box-shadow: none;\n  }\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  floor((@gutter / 2));\n  padding-right: ceil((@gutter / 2));\n  &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  ceil((@gutter / -2));\n  margin-right: floor((@gutter / -2));\n  &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n  margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n  left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n  right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  ceil((@grid-gutter-width / 2));\n      padding-right: floor((@grid-gutter-width / 2));\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n  .col(@index) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n  .col-@{class}-push-0 {\n    left: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n  .col-@{class}-pull-0 {\n    right: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n  .calc-grid-column(@index, @class, @type);\n  // next iteration\n  .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n  .float-grid-columns(@class);\n  .loop-grid-columns(@grid-columns, @class, width);\n  .loop-grid-columns(@grid-columns, @class, pull);\n  .loop-grid-columns(@grid-columns, @class, push);\n  .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  background-color: @table-bg;\n}\ncaption {\n  padding-top: @table-cell-padding;\n  padding-bottom: @table-cell-padding;\n  color: @text-muted;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-of-type(odd) {\n    background-color: @table-bg-accent;\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    background-color: @table-bg-hover;\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n  @media screen and (max-width: @screen-xs-max) {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table > thead > tr,\n  .table > tbody > tr,\n  .table > tfoot > tr {\n    > td.@{state},\n    > th.@{state},\n    &.@{state} > td,\n    &.@{state} > th {\n      background-color: @background;\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody > tr {\n    > td.@{state}:hover,\n    > th.@{state}:hover,\n    &.@{state}:hover > td,\n    &:hover > .@{state},\n    &.@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; // IE8-9\n  line-height: normal;\n}\n\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Unstyle the caret on `<select>`s in IE10+.\n  &::-ms-expand {\n    border: 0;\n    background-color: transparent;\n  }\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n  }\n\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 9.3, iOS doesn't support `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"],\n  input[type=\"time\"],\n  input[type=\"datetime-local\"],\n  input[type=\"month\"] {\n    &.form-control {\n      line-height: @input-height-base;\n    }\n\n    &.input-sm,\n    .input-group-sm & {\n      line-height: @input-height-small;\n    }\n\n    &.input-lg,\n    .input-group-lg & {\n      line-height: @input-height-large;\n    }\n  }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n\n  label {\n    min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n    padding-left: 20px;\n    margin-bottom: 0;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  &[disabled],\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n  &.disabled,\n  fieldset[disabled] & {\n    label {\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  // Size it appropriately next to real form controls\n  padding-top: (@padding-base-vertical + 1);\n  padding-bottom: (@padding-base-vertical + 1);\n  // Remove default margin from `p`\n  margin-bottom: 0;\n  min-height: (@line-height-computed + @font-size-base);\n\n  &.input-lg,\n  &.input-sm {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n  .form-control {\n    height: @input-height-small;\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    line-height: @line-height-small;\n    border-radius: @input-border-radius-small;\n  }\n  select.form-control {\n    height: @input-height-small;\n    line-height: @input-height-small;\n  }\n  textarea.form-control,\n  select[multiple].form-control {\n    height: auto;\n  }\n  .form-control-static {\n    height: @input-height-small;\n    min-height: (@line-height-computed + @font-size-small);\n    padding: (@padding-small-vertical + 1) @padding-small-horizontal;\n    font-size: @font-size-small;\n    line-height: @line-height-small;\n  }\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n  .form-control {\n    height: @input-height-large;\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    line-height: @line-height-large;\n    border-radius: @input-border-radius-large;\n  }\n  select.form-control {\n    height: @input-height-large;\n    line-height: @input-height-large;\n  }\n  textarea.form-control,\n  select[multiple].form-control {\n    height: auto;\n  }\n  .form-control-static {\n    height: @input-height-large;\n    min-height: (@line-height-computed + @font-size-large);\n    padding: (@padding-large-vertical + 1) @padding-large-horizontal;\n    font-size: @font-size-large;\n    line-height: @line-height-large;\n  }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2; // Ensure icon is above input groups\n  display: block;\n  width: @input-height-base;\n  height: @input-height-base;\n  line-height: @input-height-base;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: @input-height-large;\n  height: @input-height-large;\n  line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: @input-height-small;\n  height: @input-height-small;\n  line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n  & ~ .form-control-feedback {\n    top: (@line-height-computed + 5); // Height of the `label` and its margin\n  }\n  &.sr-only ~ .form-control-feedback {\n    top: 0;\n  }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n\n    // Make static controls behave like regular ones\n    .form-control-static {\n      display: inline-block;\n    }\n\n    .input-group {\n      display: inline-table;\n      vertical-align: middle;\n\n      .input-group-addon,\n      .input-group-btn,\n      .form-control {\n        width: auto;\n      }\n    }\n\n    // Input groups need that 100% width though\n    .input-group > .form-control {\n      width: 100%;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match.\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      vertical-align: middle;\n\n      label {\n        padding-left: 0;\n      }\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      position: relative;\n      margin-left: 0;\n    }\n\n    // Re-override the feedback icon.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of radios and checkboxes\n  //\n  // Labels also get some reset styles, but that is scoped to a media query below.\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  // Reset spacing and right align labels, but scope to media queries so that\n  // labels on narrow viewports stack the same as a default form example.\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n      margin-bottom: 0;\n      padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    right: floor((@grid-gutter-width / 2));\n  }\n\n  // Form group sizes\n  //\n  // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n  // inputs and labels within a `.form-group`.\n  .form-group-lg {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: (@padding-large-vertical + 1);\n        font-size: @font-size-large;\n      }\n    }\n  }\n  .form-group-sm {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: (@padding-small-vertical + 1);\n        font-size: @font-size-small;\n      }\n    }\n  }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline,\n  &.radio label,\n  &.checkbox label,\n  &.radio-inline label,\n  &.checkbox-inline label  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n  // Optional feedback icon\n  .form-control-feedback {\n    color: @text-color;\n  }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n  .user-select(none);\n\n  &,\n  &:active,\n  &.active {\n    &:focus,\n    &.focus {\n      .tab-focus();\n    }\n  }\n\n  &:hover,\n  &:focus,\n  &.focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n    .opacity(.65);\n    .box-shadow(none);\n  }\n\n  a& {\n    &.disabled,\n    fieldset[disabled] & {\n      pointer-events: none; // Future-proof disabling of clicks on `<a>` elements\n    }\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &.active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: @link-hover-decoration;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:focus,\n  &.focus {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 25%);\n  }\n  &:hover {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 12%);\n\n    &:hover,\n    &:focus,\n    &.focus {\n      color: @color;\n      background-color: darken(@background, 17%);\n          border-color: darken(@border, 25%);\n    }\n  }\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus,\n    &.focus {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: @color;\n  }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n\n  &.in      { display: block; }\n  tr&.in    { display: table-row; }\n  tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition-property(~\"height, visibility\");\n  .transition-duration(.35s);\n  .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base dashed;\n  border-top:   @caret-width-base solid ~\"\\9\"; // IE8\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n\n  // Nuke hover/focus effects\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: @cursor-disabled;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n  white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base dashed;\n    border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 2px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn,\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    .border-top-radius(@btn-border-radius-base);\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    .border-top-radius(0);\n    .border-bottom-radius(@btn-border-radius-base);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n\n  > .btn-group .dropdown-menu {\n    left: auto;\n  }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n  > .btn,\n  > .btn-group > .btn {\n    input[type=\"radio\"],\n    input[type=\"checkbox\"] {\n      position: absolute;\n      clip: rect(0,0,0,0);\n      pointer-events: none;\n    }\n  }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // Ensure that the input is always above the *appended* addon button for\n    // proper border colors.\n    position: relative;\n    z-index: 2;\n\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n\n    &:focus {\n      z-index: 3;\n    }\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @input-border-radius;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @input-border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @input-border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      z-index: 2;\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: @cursor-disabled;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n    > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  .navbar-collapse {\n    max-height: @navbar-collapse-max-height;\n\n    @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n      max-height: 200px;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: -@navbar-padding-horizontal;\n    margin-left:  -@navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @navbar-height;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  > img {\n    display: block;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: 0;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n  }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n\n      &:last-child {\n        margin-bottom: 0;\n      }\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  .border-top-radius(@navbar-border-radius);\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right {\n    .pull-right();\n    margin-right: -@navbar-padding-horizontal;\n\n    ~ .navbar-right {\n      margin-right: 0;\n    }\n  }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-default-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n      }\n    }\n  }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-inverse-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n      }\n    }\n  }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 3;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n      line-height: @line-height;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n  background-color: @color;\n\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: middle;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n\n  .btn-xs &,\n  .btn-group-xs > .btn & {\n    top: 0;\n    padding: 1px 5px;\n  }\n\n  // Hover state, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @badge-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Account for badges in navs\n  .list-group-item.active > &,\n  .nav-pills > .active > a > & {\n    color: @badge-active-color;\n    background-color: @badge-active-bg;\n  }\n\n  .list-group-item > & {\n    float: right;\n  }\n\n  .list-group-item > & + & {\n    margin-right: 5px;\n  }\n\n  .nav-pills > li > a > & {\n    margin-left: 3px;\n  }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding-top:    @jumbotron-padding;\n  padding-bottom: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  > hr {\n    border-top-color: darken(@jumbotron-bg, 10%);\n  }\n\n  .container &,\n  .container-fluid & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n    padding-left:  (@grid-gutter-width / 2);\n    padding-right: (@grid-gutter-width / 2);\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container &,\n    .container-fluid & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: @jumbotron-heading-font-size;\n    }\n  }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(border .2s ease-in-out);\n\n  > img,\n  a > img {\n    &:extend(.img-responsive);\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n  padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @progress-border-radius;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n  background-color: @color;\n\n  // Deprecated parent class requirement as of v3.2.0\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n",".media {\n  // Proper spacing between instances of .media\n  margin-top: 15px;\n\n  &:first-child {\n    margin-top: 0;\n  }\n}\n\n.media,\n.media-body {\n  zoom: 1;\n  overflow: hidden;\n}\n\n.media-body {\n  width: 10000px;\n}\n\n.media-object {\n  display: block;\n\n  // Fix collapse in webkit from max-width: 100% and display: table-cell.\n  &.img-thumbnail {\n    max-width: none;\n  }\n}\n\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n\n.media-middle {\n  vertical-align: middle;\n}\n\n.media-bottom {\n  vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  // No need to set list-style: none; since .list-group-item is block level\n  margin-bottom: 20px;\n  padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  // Place the border on the list items and negative margin up for better styling\n  margin-bottom: -1px;\n  background-color: @list-group-bg;\n  border: 1px solid @list-group-border;\n\n  // Round the first and last items\n  &:first-child {\n    .border-top-radius(@list-group-border-radius);\n  }\n  &:last-child {\n    margin-bottom: 0;\n    .border-bottom-radius(@list-group-border-radius);\n  }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n  color: @list-group-link-color;\n\n  .list-group-item-heading {\n    color: @list-group-link-heading-color;\n  }\n\n  // Hover state\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @list-group-link-hover-color;\n    background-color: @list-group-hover-bg;\n  }\n}\n\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n\n.list-group-item {\n  // Disabled state\n  &.disabled,\n  &.disabled:hover,\n  &.disabled:focus {\n    background-color: @list-group-disabled-bg;\n    color: @list-group-disabled-color;\n    cursor: @cursor-disabled;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-disabled-text-color;\n    }\n  }\n\n  // Active class on item itself, not parent\n  &.active,\n  &.active:hover,\n  &.active:focus {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: @list-group-active-color;\n    background-color: @list-group-active-bg;\n    border-color: @list-group-active-border;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading,\n    .list-group-item-heading > small,\n    .list-group-item-heading > .small {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-active-text-color;\n    }\n  }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n  .list-group-item-@{state} {\n    color: @color;\n    background-color: @background;\n\n    a&,\n    button& {\n      color: @color;\n\n      .list-group-item-heading {\n        color: inherit;\n      }\n\n      &:hover,\n      &:focus {\n        color: @color;\n        background-color: darken(@background, 5%);\n      }\n      &.active,\n      &.active:hover,\n      &.active:focus {\n        color: #fff;\n        background-color: @color;\n        border-color: @color;\n      }\n    }\n  }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: @line-height-computed;\n  background-color: @panel-bg;\n  border: 1px solid transparent;\n  border-radius: @panel-border-radius;\n  .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n  padding: @panel-body-padding;\n  &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n  padding: @panel-heading-padding;\n  border-bottom: 1px solid transparent;\n  .border-top-radius((@panel-border-radius - 1));\n\n  > .dropdown .dropdown-toggle {\n    color: inherit;\n  }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: ceil((@font-size-base * 1.125));\n  color: inherit;\n\n  > a,\n  > small,\n  > .small,\n  > small > a,\n  > .small > a {\n    color: inherit;\n  }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n  padding: @panel-footer-padding;\n  background-color: @panel-footer-bg;\n  border-top: 1px solid @panel-inner-border;\n  .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n  > .list-group,\n  > .panel-collapse > .list-group {\n    margin-bottom: 0;\n\n    .list-group-item {\n      border-width: 1px 0;\n      border-radius: 0;\n    }\n\n    // Add border top radius for first one\n    &:first-child {\n      .list-group-item:first-child {\n        border-top: 0;\n        .border-top-radius((@panel-border-radius - 1));\n      }\n    }\n\n    // Add border bottom radius for last one\n    &:last-child {\n      .list-group-item:last-child {\n        border-bottom: 0;\n        .border-bottom-radius((@panel-border-radius - 1));\n      }\n    }\n  }\n  > .panel-heading + .panel-collapse > .list-group {\n    .list-group-item:first-child {\n      .border-top-radius(0);\n    }\n  }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n  .list-group-item:first-child {\n    border-top-width: 0;\n  }\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n  > .table,\n  > .table-responsive > .table,\n  > .panel-collapse > .table {\n    margin-bottom: 0;\n\n    caption {\n      padding-left: @panel-body-padding;\n      padding-right: @panel-body-padding;\n    }\n  }\n  // Add border top radius for first one\n  > .table:first-child,\n  > .table-responsive:first-child > .table:first-child {\n    .border-top-radius((@panel-border-radius - 1));\n\n    > thead:first-child,\n    > tbody:first-child {\n      > tr:first-child {\n        border-top-left-radius: (@panel-border-radius - 1);\n        border-top-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-top-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-top-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  // Add border bottom radius for last one\n  > .table:last-child,\n  > .table-responsive:last-child > .table:last-child {\n    .border-bottom-radius((@panel-border-radius - 1));\n\n    > tbody:last-child,\n    > tfoot:last-child {\n      > tr:last-child {\n        border-bottom-left-radius: (@panel-border-radius - 1);\n        border-bottom-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-bottom-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-bottom-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  > .panel-body + .table,\n  > .panel-body + .table-responsive,\n  > .table + .panel-body,\n  > .table-responsive + .panel-body {\n    border-top: 1px solid @table-border-color;\n  }\n  > .table > tbody:first-child > tr:first-child th,\n  > .table > tbody:first-child > tr:first-child td {\n    border-top: 0;\n  }\n  > .table-bordered,\n  > .table-responsive > .table-bordered {\n    border: 0;\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th:first-child,\n        > td:first-child {\n          border-left: 0;\n        }\n        > th:last-child,\n        > td:last-child {\n          border-right: 0;\n        }\n      }\n    }\n    > thead,\n    > tbody {\n      > tr:first-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n    > tbody,\n    > tfoot {\n      > tr:last-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n  }\n  > .table-responsive {\n    border: 0;\n    margin-bottom: 0;\n  }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n  margin-bottom: @line-height-computed;\n\n  // Tighten up margin so it's only between panels\n  .panel {\n    margin-bottom: 0;\n    border-radius: @panel-border-radius;\n\n    + .panel {\n      margin-top: 5px;\n    }\n  }\n\n  .panel-heading {\n    border-bottom: 0;\n\n    + .panel-collapse > .panel-body,\n    + .panel-collapse > .list-group {\n      border-top: 1px solid @panel-inner-border;\n    }\n  }\n\n  .panel-footer {\n    border-top: 0;\n    + .panel-collapse .panel-body {\n      border-bottom: 1px solid @panel-inner-border;\n    }\n  }\n}\n\n\n// Contextual variations\n.panel-default {\n  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse > .panel-body {\n      border-top-color: @border;\n    }\n    .badge {\n      color: @heading-bg-color;\n      background-color: @heading-text-color;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse > .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n\n  .embed-responsive-item,\n  iframe,\n  embed,\n  object,\n  video {\n    position: absolute;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    height: 100%;\n    width: 100%;\n    border: 0;\n  }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: @well-bg;\n  border: 1px solid @well-border;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n  blockquote {\n    border-color: #ddd;\n    border-color: rgba(0,0,0,.15);\n  }\n}\n\n// Sizes\n.well-lg {\n  padding: 24px;\n  border-radius: @border-radius-large;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: (@font-size-base * 1.5);\n  font-weight: @close-font-weight;\n  line-height: 1;\n  color: @close-color;\n  text-shadow: @close-text-shadow;\n  .opacity(.2);\n\n  &:hover,\n  &:focus {\n    color: @close-color;\n    text-decoration: none;\n    cursor: pointer;\n    .opacity(.5);\n  }\n\n  // Additional properties for button version\n  // iOS requires the button element instead of an anchor tag.\n  // If you want the anchor version, it requires `href=\"#\"`.\n  // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n  button& {\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n  }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal;\n  -webkit-overflow-scrolling: touch;\n\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~\"0.3s ease-out\");\n  }\n  &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal-background;\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  padding: @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-group .btn + .btn {\n    margin-left: -1px;\n  }\n  // and override it for block buttons as well\n  .btn-block + .btn-block {\n    margin-left: 0;\n  }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    width: @modal-md;\n    margin: 30px auto;\n  }\n  .modal-content {\n    .box-shadow(0 5px 15px rgba(0,0,0,.5));\n  }\n\n  // Modal sizes\n  .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n  .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  z-index: @zindex-tooltip;\n  display: block;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  .reset-text();\n  font-size: @font-size-small;\n\n  .opacity(0);\n\n  &.in     { .opacity(@tooltip-opacity); }\n  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }\n  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }\n  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }\n  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: @tooltip-max-width;\n  padding: 3px 8px;\n  color: @tooltip-color;\n  text-align: center;\n  background-color: @tooltip-bg;\n  border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n  &.top .tooltip-arrow {\n    bottom: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-left .tooltip-arrow {\n    bottom: 0;\n    right: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-right .tooltip-arrow {\n    bottom: 0;\n    left: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.right .tooltip-arrow {\n    top: 50%;\n    left: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-right-color: @tooltip-arrow-color;\n  }\n  &.left .tooltip-arrow {\n    top: 50%;\n    right: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-left-color: @tooltip-arrow-color;\n  }\n  &.bottom .tooltip-arrow {\n    top: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-left .tooltip-arrow {\n    top: 0;\n    right: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-right .tooltip-arrow {\n    top: 0;\n    left: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n}\n",".reset-text() {\n  font-family: @font-family-base;\n  // We deliberately do NOT reset font-size.\n  font-style: normal;\n  font-weight: normal;\n  letter-spacing: normal;\n  line-break: auto;\n  line-height: @line-height-base;\n  text-align: left; // Fallback for where `start` is not supported\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  white-space: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: @zindex-popover;\n  display: none;\n  max-width: @popover-max-width;\n  padding: 1px;\n  // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  .reset-text();\n  font-size: @font-size-base;\n\n  background-color: @popover-bg;\n  background-clip: padding-box;\n  border: 1px solid @popover-fallback-border-color;\n  border: 1px solid @popover-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n  // Offset the popover to account for the popover arrow\n  &.top     { margin-top: -@popover-arrow-width; }\n  &.right   { margin-left: @popover-arrow-width; }\n  &.bottom  { margin-top: @popover-arrow-width; }\n  &.left    { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n  margin: 0; // reset heading margin\n  padding: 8px 14px;\n  font-size: @font-size-base;\n  background-color: @popover-title-bg;\n  border-bottom: 1px solid darken(@popover-title-bg, 5%);\n  border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n  &,\n  &:after {\n    position: absolute;\n    display: block;\n    width: 0;\n    height: 0;\n    border-color: transparent;\n    border-style: solid;\n  }\n}\n.popover > .arrow {\n  border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n  border-width: @popover-arrow-width;\n  content: \"\";\n}\n\n.popover {\n  &.top > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-bottom-width: 0;\n    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-top-color: @popover-arrow-outer-color;\n    bottom: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      bottom: 1px;\n      margin-left: -@popover-arrow-width;\n      border-bottom-width: 0;\n      border-top-color: @popover-arrow-color;\n    }\n  }\n  &.right > .arrow {\n    top: 50%;\n    left: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-left-width: 0;\n    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-right-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      left: 1px;\n      bottom: -@popover-arrow-width;\n      border-left-width: 0;\n      border-right-color: @popover-arrow-color;\n    }\n  }\n  &.bottom > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-top-width: 0;\n    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-bottom-color: @popover-arrow-outer-color;\n    top: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      top: 1px;\n      margin-left: -@popover-arrow-width;\n      border-top-width: 0;\n      border-bottom-color: @popover-arrow-color;\n    }\n  }\n\n  &.left > .arrow {\n    top: 50%;\n    right: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-right-width: 0;\n    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-left-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      right: 1px;\n      border-right-width: 0;\n      border-left-color: @popover-arrow-color;\n      bottom: -@popover-arrow-width;\n    }\n  }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      &:extend(.img-responsive);\n      line-height: 1;\n    }\n\n    // WebKit CSS3 transforms for supported devices\n    @media all and (transform-3d), (-webkit-transform-3d) {\n      .transition-transform(~'0.6s ease-in-out');\n      .backface-visibility(~'hidden');\n      .perspective(1000px);\n\n      &.next,\n      &.active.right {\n        .translate3d(100%, 0, 0);\n        left: 0;\n      }\n      &.prev,\n      &.active.left {\n        .translate3d(-100%, 0, 0);\n        left: 0;\n      }\n      &.next.left,\n      &.prev.right,\n      &.active {\n        .translate3d(0, 0, 0);\n        left: 0;\n      }\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev {\n    display: block;\n  }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: 0;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    margin-top: -10px;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n    margin-left: -10px;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n    margin-right: -10px;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    line-height: 1;\n    font-family: serif;\n  }\n\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicon-chevron-left,\n    .glyphicon-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: (@carousel-control-font-size * 1.5);\n      height: (@carousel-control-font-size * 1.5);\n      margin-top: (@carousel-control-font-size / -2);\n      font-size: (@carousel-control-font-size * 1.5);\n    }\n    .glyphicon-chevron-left,\n    .icon-prev {\n      margin-left: (@carousel-control-font-size / -2);\n    }\n    .glyphicon-chevron-right,\n    .icon-next {\n      margin-right: (@carousel-control-font-size / -2);\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n","// Center-align a block level element\n\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n  width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n\n.visible-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-visibility();\n  }\n}\n.visible-xs-block {\n  @media (max-width: @screen-xs-max) {\n    display: block !important;\n  }\n}\n.visible-xs-inline {\n  @media (max-width: @screen-xs-max) {\n    display: inline !important;\n  }\n}\n.visible-xs-inline-block {\n  @media (max-width: @screen-xs-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-visibility();\n  }\n}\n.visible-sm-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: block !important;\n  }\n}\n.visible-sm-inline {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline !important;\n  }\n}\n.visible-sm-inline-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-visibility();\n  }\n}\n.visible-md-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: block !important;\n  }\n}\n.visible-md-inline {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline !important;\n  }\n}\n.visible-md-inline-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-visibility();\n  }\n}\n.visible-lg-block {\n  @media (min-width: @screen-lg-min) {\n    display: block !important;\n  }\n}\n.visible-lg-inline {\n  @media (min-width: @screen-lg-min) {\n    display: inline !important;\n  }\n}\n.visible-lg-inline-block {\n  @media (min-width: @screen-lg-min) {\n    display: inline-block !important;\n  }\n}\n\n.hidden-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-invisibility();\n  }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n  .responsive-invisibility();\n\n  @media print {\n    .responsive-visibility();\n  }\n}\n.visible-print-block {\n  display: none !important;\n\n  @media print {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n\n  @media print {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n\n  @media print {\n    display: inline-block !important;\n  }\n}\n\n.hidden-print {\n  @media print {\n    .responsive-invisibility();\n  }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table !important; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n  display: none !important;\n}\n"]}
                \ No newline at end of file
                diff --git a/blockly/webif/static/css/font-awesome.css b/blockly/webif/static/css/font-awesome.css
                new file mode 100644
                index 000000000..ee906a819
                --- /dev/null
                +++ b/blockly/webif/static/css/font-awesome.css
                @@ -0,0 +1,2337 @@
                +/*!
                + *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
                + *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
                + */
                +/* FONT PATH
                + * -------------------------- */
                +@font-face {
                +  font-family: 'FontAwesome';
                +  src: url('../fonts/fontawesome-webfont.eot?v=4.7.0');
                +  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
                +  font-weight: normal;
                +  font-style: normal;
                +}
                +.fa {
                +  display: inline-block;
                +  font: normal normal normal 14px/1 FontAwesome;
                +  font-size: inherit;
                +  text-rendering: auto;
                +  -webkit-font-smoothing: antialiased;
                +  -moz-osx-font-smoothing: grayscale;
                +}
                +/* makes the font 33% larger relative to the icon container */
                +.fa-lg {
                +  font-size: 1.33333333em;
                +  line-height: 0.75em;
                +  vertical-align: -15%;
                +}
                +.fa-2x {
                +  font-size: 2em;
                +}
                +.fa-3x {
                +  font-size: 3em;
                +}
                +.fa-4x {
                +  font-size: 4em;
                +}
                +.fa-5x {
                +  font-size: 5em;
                +}
                +.fa-fw {
                +  width: 1.28571429em;
                +  text-align: center;
                +}
                +.fa-ul {
                +  padding-left: 0;
                +  margin-left: 2.14285714em;
                +  list-style-type: none;
                +}
                +.fa-ul > li {
                +  position: relative;
                +}
                +.fa-li {
                +  position: absolute;
                +  left: -2.14285714em;
                +  width: 2.14285714em;
                +  top: 0.14285714em;
                +  text-align: center;
                +}
                +.fa-li.fa-lg {
                +  left: -1.85714286em;
                +}
                +.fa-border {
                +  padding: .2em .25em .15em;
                +  border: solid 0.08em #eeeeee;
                +  border-radius: .1em;
                +}
                +.fa-pull-left {
                +  float: left;
                +}
                +.fa-pull-right {
                +  float: right;
                +}
                +.fa.fa-pull-left {
                +  margin-right: .3em;
                +}
                +.fa.fa-pull-right {
                +  margin-left: .3em;
                +}
                +/* Deprecated as of 4.4.0 */
                +.pull-right {
                +  float: right;
                +}
                +.pull-left {
                +  float: left;
                +}
                +.fa.pull-left {
                +  margin-right: .3em;
                +}
                +.fa.pull-right {
                +  margin-left: .3em;
                +}
                +.fa-spin {
                +  -webkit-animation: fa-spin 2s infinite linear;
                +  animation: fa-spin 2s infinite linear;
                +}
                +.fa-pulse {
                +  -webkit-animation: fa-spin 1s infinite steps(8);
                +  animation: fa-spin 1s infinite steps(8);
                +}
                +@-webkit-keyframes fa-spin {
                +  0% {
                +    -webkit-transform: rotate(0deg);
                +    transform: rotate(0deg);
                +  }
                +  100% {
                +    -webkit-transform: rotate(359deg);
                +    transform: rotate(359deg);
                +  }
                +}
                +@keyframes fa-spin {
                +  0% {
                +    -webkit-transform: rotate(0deg);
                +    transform: rotate(0deg);
                +  }
                +  100% {
                +    -webkit-transform: rotate(359deg);
                +    transform: rotate(359deg);
                +  }
                +}
                +.fa-rotate-90 {
                +  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
                +  -webkit-transform: rotate(90deg);
                +  -ms-transform: rotate(90deg);
                +  transform: rotate(90deg);
                +}
                +.fa-rotate-180 {
                +  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
                +  -webkit-transform: rotate(180deg);
                +  -ms-transform: rotate(180deg);
                +  transform: rotate(180deg);
                +}
                +.fa-rotate-270 {
                +  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
                +  -webkit-transform: rotate(270deg);
                +  -ms-transform: rotate(270deg);
                +  transform: rotate(270deg);
                +}
                +.fa-flip-horizontal {
                +  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
                +  -webkit-transform: scale(-1, 1);
                +  -ms-transform: scale(-1, 1);
                +  transform: scale(-1, 1);
                +}
                +.fa-flip-vertical {
                +  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
                +  -webkit-transform: scale(1, -1);
                +  -ms-transform: scale(1, -1);
                +  transform: scale(1, -1);
                +}
                +:root .fa-rotate-90,
                +:root .fa-rotate-180,
                +:root .fa-rotate-270,
                +:root .fa-flip-horizontal,
                +:root .fa-flip-vertical {
                +  filter: none;
                +}
                +.fa-stack {
                +  position: relative;
                +  display: inline-block;
                +  width: 2em;
                +  height: 2em;
                +  line-height: 2em;
                +  vertical-align: middle;
                +}
                +.fa-stack-1x,
                +.fa-stack-2x {
                +  position: absolute;
                +  left: 0;
                +  width: 100%;
                +  text-align: center;
                +}
                +.fa-stack-1x {
                +  line-height: inherit;
                +}
                +.fa-stack-2x {
                +  font-size: 2em;
                +}
                +.fa-inverse {
                +  color: #ffffff;
                +}
                +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
                +   readers do not read off random characters that represent icons */
                +.fa-glass:before {
                +  content: "\f000";
                +}
                +.fa-music:before {
                +  content: "\f001";
                +}
                +.fa-search:before {
                +  content: "\f002";
                +}
                +.fa-envelope-o:before {
                +  content: "\f003";
                +}
                +.fa-heart:before {
                +  content: "\f004";
                +}
                +.fa-star:before {
                +  content: "\f005";
                +}
                +.fa-star-o:before {
                +  content: "\f006";
                +}
                +.fa-user:before {
                +  content: "\f007";
                +}
                +.fa-film:before {
                +  content: "\f008";
                +}
                +.fa-th-large:before {
                +  content: "\f009";
                +}
                +.fa-th:before {
                +  content: "\f00a";
                +}
                +.fa-th-list:before {
                +  content: "\f00b";
                +}
                +.fa-check:before {
                +  content: "\f00c";
                +}
                +.fa-remove:before,
                +.fa-close:before,
                +.fa-times:before {
                +  content: "\f00d";
                +}
                +.fa-search-plus:before {
                +  content: "\f00e";
                +}
                +.fa-search-minus:before {
                +  content: "\f010";
                +}
                +.fa-power-off:before {
                +  content: "\f011";
                +}
                +.fa-signal:before {
                +  content: "\f012";
                +}
                +.fa-gear:before,
                +.fa-cog:before {
                +  content: "\f013";
                +}
                +.fa-trash-o:before {
                +  content: "\f014";
                +}
                +.fa-home:before {
                +  content: "\f015";
                +}
                +.fa-file-o:before {
                +  content: "\f016";
                +}
                +.fa-clock-o:before {
                +  content: "\f017";
                +}
                +.fa-road:before {
                +  content: "\f018";
                +}
                +.fa-download:before {
                +  content: "\f019";
                +}
                +.fa-arrow-circle-o-down:before {
                +  content: "\f01a";
                +}
                +.fa-arrow-circle-o-up:before {
                +  content: "\f01b";
                +}
                +.fa-inbox:before {
                +  content: "\f01c";
                +}
                +.fa-play-circle-o:before {
                +  content: "\f01d";
                +}
                +.fa-rotate-right:before,
                +.fa-repeat:before {
                +  content: "\f01e";
                +}
                +.fa-refresh:before {
                +  content: "\f021";
                +}
                +.fa-list-alt:before {
                +  content: "\f022";
                +}
                +.fa-lock:before {
                +  content: "\f023";
                +}
                +.fa-flag:before {
                +  content: "\f024";
                +}
                +.fa-headphones:before {
                +  content: "\f025";
                +}
                +.fa-volume-off:before {
                +  content: "\f026";
                +}
                +.fa-volume-down:before {
                +  content: "\f027";
                +}
                +.fa-volume-up:before {
                +  content: "\f028";
                +}
                +.fa-qrcode:before {
                +  content: "\f029";
                +}
                +.fa-barcode:before {
                +  content: "\f02a";
                +}
                +.fa-tag:before {
                +  content: "\f02b";
                +}
                +.fa-tags:before {
                +  content: "\f02c";
                +}
                +.fa-book:before {
                +  content: "\f02d";
                +}
                +.fa-bookmark:before {
                +  content: "\f02e";
                +}
                +.fa-print:before {
                +  content: "\f02f";
                +}
                +.fa-camera:before {
                +  content: "\f030";
                +}
                +.fa-font:before {
                +  content: "\f031";
                +}
                +.fa-bold:before {
                +  content: "\f032";
                +}
                +.fa-italic:before {
                +  content: "\f033";
                +}
                +.fa-text-height:before {
                +  content: "\f034";
                +}
                +.fa-text-width:before {
                +  content: "\f035";
                +}
                +.fa-align-left:before {
                +  content: "\f036";
                +}
                +.fa-align-center:before {
                +  content: "\f037";
                +}
                +.fa-align-right:before {
                +  content: "\f038";
                +}
                +.fa-align-justify:before {
                +  content: "\f039";
                +}
                +.fa-list:before {
                +  content: "\f03a";
                +}
                +.fa-dedent:before,
                +.fa-outdent:before {
                +  content: "\f03b";
                +}
                +.fa-indent:before {
                +  content: "\f03c";
                +}
                +.fa-video-camera:before {
                +  content: "\f03d";
                +}
                +.fa-photo:before,
                +.fa-image:before,
                +.fa-picture-o:before {
                +  content: "\f03e";
                +}
                +.fa-pencil:before {
                +  content: "\f040";
                +}
                +.fa-map-marker:before {
                +  content: "\f041";
                +}
                +.fa-adjust:before {
                +  content: "\f042";
                +}
                +.fa-tint:before {
                +  content: "\f043";
                +}
                +.fa-edit:before,
                +.fa-pencil-square-o:before {
                +  content: "\f044";
                +}
                +.fa-share-square-o:before {
                +  content: "\f045";
                +}
                +.fa-check-square-o:before {
                +  content: "\f046";
                +}
                +.fa-arrows:before {
                +  content: "\f047";
                +}
                +.fa-step-backward:before {
                +  content: "\f048";
                +}
                +.fa-fast-backward:before {
                +  content: "\f049";
                +}
                +.fa-backward:before {
                +  content: "\f04a";
                +}
                +.fa-play:before {
                +  content: "\f04b";
                +}
                +.fa-pause:before {
                +  content: "\f04c";
                +}
                +.fa-stop:before {
                +  content: "\f04d";
                +}
                +.fa-forward:before {
                +  content: "\f04e";
                +}
                +.fa-fast-forward:before {
                +  content: "\f050";
                +}
                +.fa-step-forward:before {
                +  content: "\f051";
                +}
                +.fa-eject:before {
                +  content: "\f052";
                +}
                +.fa-chevron-left:before {
                +  content: "\f053";
                +}
                +.fa-chevron-right:before {
                +  content: "\f054";
                +}
                +.fa-plus-circle:before {
                +  content: "\f055";
                +}
                +.fa-minus-circle:before {
                +  content: "\f056";
                +}
                +.fa-times-circle:before {
                +  content: "\f057";
                +}
                +.fa-check-circle:before {
                +  content: "\f058";
                +}
                +.fa-question-circle:before {
                +  content: "\f059";
                +}
                +.fa-info-circle:before {
                +  content: "\f05a";
                +}
                +.fa-crosshairs:before {
                +  content: "\f05b";
                +}
                +.fa-times-circle-o:before {
                +  content: "\f05c";
                +}
                +.fa-check-circle-o:before {
                +  content: "\f05d";
                +}
                +.fa-ban:before {
                +  content: "\f05e";
                +}
                +.fa-arrow-left:before {
                +  content: "\f060";
                +}
                +.fa-arrow-right:before {
                +  content: "\f061";
                +}
                +.fa-arrow-up:before {
                +  content: "\f062";
                +}
                +.fa-arrow-down:before {
                +  content: "\f063";
                +}
                +.fa-mail-forward:before,
                +.fa-share:before {
                +  content: "\f064";
                +}
                +.fa-expand:before {
                +  content: "\f065";
                +}
                +.fa-compress:before {
                +  content: "\f066";
                +}
                +.fa-plus:before {
                +  content: "\f067";
                +}
                +.fa-minus:before {
                +  content: "\f068";
                +}
                +.fa-asterisk:before {
                +  content: "\f069";
                +}
                +.fa-exclamation-circle:before {
                +  content: "\f06a";
                +}
                +.fa-gift:before {
                +  content: "\f06b";
                +}
                +.fa-leaf:before {
                +  content: "\f06c";
                +}
                +.fa-fire:before {
                +  content: "\f06d";
                +}
                +.fa-eye:before {
                +  content: "\f06e";
                +}
                +.fa-eye-slash:before {
                +  content: "\f070";
                +}
                +.fa-warning:before,
                +.fa-exclamation-triangle:before {
                +  content: "\f071";
                +}
                +.fa-plane:before {
                +  content: "\f072";
                +}
                +.fa-calendar:before {
                +  content: "\f073";
                +}
                +.fa-random:before {
                +  content: "\f074";
                +}
                +.fa-comment:before {
                +  content: "\f075";
                +}
                +.fa-magnet:before {
                +  content: "\f076";
                +}
                +.fa-chevron-up:before {
                +  content: "\f077";
                +}
                +.fa-chevron-down:before {
                +  content: "\f078";
                +}
                +.fa-retweet:before {
                +  content: "\f079";
                +}
                +.fa-shopping-cart:before {
                +  content: "\f07a";
                +}
                +.fa-folder:before {
                +  content: "\f07b";
                +}
                +.fa-folder-open:before {
                +  content: "\f07c";
                +}
                +.fa-arrows-v:before {
                +  content: "\f07d";
                +}
                +.fa-arrows-h:before {
                +  content: "\f07e";
                +}
                +.fa-bar-chart-o:before,
                +.fa-bar-chart:before {
                +  content: "\f080";
                +}
                +.fa-twitter-square:before {
                +  content: "\f081";
                +}
                +.fa-facebook-square:before {
                +  content: "\f082";
                +}
                +.fa-camera-retro:before {
                +  content: "\f083";
                +}
                +.fa-key:before {
                +  content: "\f084";
                +}
                +.fa-gears:before,
                +.fa-cogs:before {
                +  content: "\f085";
                +}
                +.fa-comments:before {
                +  content: "\f086";
                +}
                +.fa-thumbs-o-up:before {
                +  content: "\f087";
                +}
                +.fa-thumbs-o-down:before {
                +  content: "\f088";
                +}
                +.fa-star-half:before {
                +  content: "\f089";
                +}
                +.fa-heart-o:before {
                +  content: "\f08a";
                +}
                +.fa-sign-out:before {
                +  content: "\f08b";
                +}
                +.fa-linkedin-square:before {
                +  content: "\f08c";
                +}
                +.fa-thumb-tack:before {
                +  content: "\f08d";
                +}
                +.fa-external-link:before {
                +  content: "\f08e";
                +}
                +.fa-sign-in:before {
                +  content: "\f090";
                +}
                +.fa-trophy:before {
                +  content: "\f091";
                +}
                +.fa-github-square:before {
                +  content: "\f092";
                +}
                +.fa-upload:before {
                +  content: "\f093";
                +}
                +.fa-lemon-o:before {
                +  content: "\f094";
                +}
                +.fa-phone:before {
                +  content: "\f095";
                +}
                +.fa-square-o:before {
                +  content: "\f096";
                +}
                +.fa-bookmark-o:before {
                +  content: "\f097";
                +}
                +.fa-phone-square:before {
                +  content: "\f098";
                +}
                +.fa-twitter:before {
                +  content: "\f099";
                +}
                +.fa-facebook-f:before,
                +.fa-facebook:before {
                +  content: "\f09a";
                +}
                +.fa-github:before {
                +  content: "\f09b";
                +}
                +.fa-unlock:before {
                +  content: "\f09c";
                +}
                +.fa-credit-card:before {
                +  content: "\f09d";
                +}
                +.fa-feed:before,
                +.fa-rss:before {
                +  content: "\f09e";
                +}
                +.fa-hdd-o:before {
                +  content: "\f0a0";
                +}
                +.fa-bullhorn:before {
                +  content: "\f0a1";
                +}
                +.fa-bell:before {
                +  content: "\f0f3";
                +}
                +.fa-certificate:before {
                +  content: "\f0a3";
                +}
                +.fa-hand-o-right:before {
                +  content: "\f0a4";
                +}
                +.fa-hand-o-left:before {
                +  content: "\f0a5";
                +}
                +.fa-hand-o-up:before {
                +  content: "\f0a6";
                +}
                +.fa-hand-o-down:before {
                +  content: "\f0a7";
                +}
                +.fa-arrow-circle-left:before {
                +  content: "\f0a8";
                +}
                +.fa-arrow-circle-right:before {
                +  content: "\f0a9";
                +}
                +.fa-arrow-circle-up:before {
                +  content: "\f0aa";
                +}
                +.fa-arrow-circle-down:before {
                +  content: "\f0ab";
                +}
                +.fa-globe:before {
                +  content: "\f0ac";
                +}
                +.fa-wrench:before {
                +  content: "\f0ad";
                +}
                +.fa-tasks:before {
                +  content: "\f0ae";
                +}
                +.fa-filter:before {
                +  content: "\f0b0";
                +}
                +.fa-briefcase:before {
                +  content: "\f0b1";
                +}
                +.fa-arrows-alt:before {
                +  content: "\f0b2";
                +}
                +.fa-group:before,
                +.fa-users:before {
                +  content: "\f0c0";
                +}
                +.fa-chain:before,
                +.fa-link:before {
                +  content: "\f0c1";
                +}
                +.fa-cloud:before {
                +  content: "\f0c2";
                +}
                +.fa-flask:before {
                +  content: "\f0c3";
                +}
                +.fa-cut:before,
                +.fa-scissors:before {
                +  content: "\f0c4";
                +}
                +.fa-copy:before,
                +.fa-files-o:before {
                +  content: "\f0c5";
                +}
                +.fa-paperclip:before {
                +  content: "\f0c6";
                +}
                +.fa-save:before,
                +.fa-floppy-o:before {
                +  content: "\f0c7";
                +}
                +.fa-square:before {
                +  content: "\f0c8";
                +}
                +.fa-navicon:before,
                +.fa-reorder:before,
                +.fa-bars:before {
                +  content: "\f0c9";
                +}
                +.fa-list-ul:before {
                +  content: "\f0ca";
                +}
                +.fa-list-ol:before {
                +  content: "\f0cb";
                +}
                +.fa-strikethrough:before {
                +  content: "\f0cc";
                +}
                +.fa-underline:before {
                +  content: "\f0cd";
                +}
                +.fa-table:before {
                +  content: "\f0ce";
                +}
                +.fa-magic:before {
                +  content: "\f0d0";
                +}
                +.fa-truck:before {
                +  content: "\f0d1";
                +}
                +.fa-pinterest:before {
                +  content: "\f0d2";
                +}
                +.fa-pinterest-square:before {
                +  content: "\f0d3";
                +}
                +.fa-google-plus-square:before {
                +  content: "\f0d4";
                +}
                +.fa-google-plus:before {
                +  content: "\f0d5";
                +}
                +.fa-money:before {
                +  content: "\f0d6";
                +}
                +.fa-caret-down:before {
                +  content: "\f0d7";
                +}
                +.fa-caret-up:before {
                +  content: "\f0d8";
                +}
                +.fa-caret-left:before {
                +  content: "\f0d9";
                +}
                +.fa-caret-right:before {
                +  content: "\f0da";
                +}
                +.fa-columns:before {
                +  content: "\f0db";
                +}
                +.fa-unsorted:before,
                +.fa-sort:before {
                +  content: "\f0dc";
                +}
                +.fa-sort-down:before,
                +.fa-sort-desc:before {
                +  content: "\f0dd";
                +}
                +.fa-sort-up:before,
                +.fa-sort-asc:before {
                +  content: "\f0de";
                +}
                +.fa-envelope:before {
                +  content: "\f0e0";
                +}
                +.fa-linkedin:before {
                +  content: "\f0e1";
                +}
                +.fa-rotate-left:before,
                +.fa-undo:before {
                +  content: "\f0e2";
                +}
                +.fa-legal:before,
                +.fa-gavel:before {
                +  content: "\f0e3";
                +}
                +.fa-dashboard:before,
                +.fa-tachometer:before {
                +  content: "\f0e4";
                +}
                +.fa-comment-o:before {
                +  content: "\f0e5";
                +}
                +.fa-comments-o:before {
                +  content: "\f0e6";
                +}
                +.fa-flash:before,
                +.fa-bolt:before {
                +  content: "\f0e7";
                +}
                +.fa-sitemap:before {
                +  content: "\f0e8";
                +}
                +.fa-umbrella:before {
                +  content: "\f0e9";
                +}
                +.fa-paste:before,
                +.fa-clipboard:before {
                +  content: "\f0ea";
                +}
                +.fa-lightbulb-o:before {
                +  content: "\f0eb";
                +}
                +.fa-exchange:before {
                +  content: "\f0ec";
                +}
                +.fa-cloud-download:before {
                +  content: "\f0ed";
                +}
                +.fa-cloud-upload:before {
                +  content: "\f0ee";
                +}
                +.fa-user-md:before {
                +  content: "\f0f0";
                +}
                +.fa-stethoscope:before {
                +  content: "\f0f1";
                +}
                +.fa-suitcase:before {
                +  content: "\f0f2";
                +}
                +.fa-bell-o:before {
                +  content: "\f0a2";
                +}
                +.fa-coffee:before {
                +  content: "\f0f4";
                +}
                +.fa-cutlery:before {
                +  content: "\f0f5";
                +}
                +.fa-file-text-o:before {
                +  content: "\f0f6";
                +}
                +.fa-building-o:before {
                +  content: "\f0f7";
                +}
                +.fa-hospital-o:before {
                +  content: "\f0f8";
                +}
                +.fa-ambulance:before {
                +  content: "\f0f9";
                +}
                +.fa-medkit:before {
                +  content: "\f0fa";
                +}
                +.fa-fighter-jet:before {
                +  content: "\f0fb";
                +}
                +.fa-beer:before {
                +  content: "\f0fc";
                +}
                +.fa-h-square:before {
                +  content: "\f0fd";
                +}
                +.fa-plus-square:before {
                +  content: "\f0fe";
                +}
                +.fa-angle-double-left:before {
                +  content: "\f100";
                +}
                +.fa-angle-double-right:before {
                +  content: "\f101";
                +}
                +.fa-angle-double-up:before {
                +  content: "\f102";
                +}
                +.fa-angle-double-down:before {
                +  content: "\f103";
                +}
                +.fa-angle-left:before {
                +  content: "\f104";
                +}
                +.fa-angle-right:before {
                +  content: "\f105";
                +}
                +.fa-angle-up:before {
                +  content: "\f106";
                +}
                +.fa-angle-down:before {
                +  content: "\f107";
                +}
                +.fa-desktop:before {
                +  content: "\f108";
                +}
                +.fa-laptop:before {
                +  content: "\f109";
                +}
                +.fa-tablet:before {
                +  content: "\f10a";
                +}
                +.fa-mobile-phone:before,
                +.fa-mobile:before {
                +  content: "\f10b";
                +}
                +.fa-circle-o:before {
                +  content: "\f10c";
                +}
                +.fa-quote-left:before {
                +  content: "\f10d";
                +}
                +.fa-quote-right:before {
                +  content: "\f10e";
                +}
                +.fa-spinner:before {
                +  content: "\f110";
                +}
                +.fa-circle:before {
                +  content: "\f111";
                +}
                +.fa-mail-reply:before,
                +.fa-reply:before {
                +  content: "\f112";
                +}
                +.fa-github-alt:before {
                +  content: "\f113";
                +}
                +.fa-folder-o:before {
                +  content: "\f114";
                +}
                +.fa-folder-open-o:before {
                +  content: "\f115";
                +}
                +.fa-smile-o:before {
                +  content: "\f118";
                +}
                +.fa-frown-o:before {
                +  content: "\f119";
                +}
                +.fa-meh-o:before {
                +  content: "\f11a";
                +}
                +.fa-gamepad:before {
                +  content: "\f11b";
                +}
                +.fa-keyboard-o:before {
                +  content: "\f11c";
                +}
                +.fa-flag-o:before {
                +  content: "\f11d";
                +}
                +.fa-flag-checkered:before {
                +  content: "\f11e";
                +}
                +.fa-terminal:before {
                +  content: "\f120";
                +}
                +.fa-code:before {
                +  content: "\f121";
                +}
                +.fa-mail-reply-all:before,
                +.fa-reply-all:before {
                +  content: "\f122";
                +}
                +.fa-star-half-empty:before,
                +.fa-star-half-full:before,
                +.fa-star-half-o:before {
                +  content: "\f123";
                +}
                +.fa-location-arrow:before {
                +  content: "\f124";
                +}
                +.fa-crop:before {
                +  content: "\f125";
                +}
                +.fa-code-fork:before {
                +  content: "\f126";
                +}
                +.fa-unlink:before,
                +.fa-chain-broken:before {
                +  content: "\f127";
                +}
                +.fa-question:before {
                +  content: "\f128";
                +}
                +.fa-info:before {
                +  content: "\f129";
                +}
                +.fa-exclamation:before {
                +  content: "\f12a";
                +}
                +.fa-superscript:before {
                +  content: "\f12b";
                +}
                +.fa-subscript:before {
                +  content: "\f12c";
                +}
                +.fa-eraser:before {
                +  content: "\f12d";
                +}
                +.fa-puzzle-piece:before {
                +  content: "\f12e";
                +}
                +.fa-microphone:before {
                +  content: "\f130";
                +}
                +.fa-microphone-slash:before {
                +  content: "\f131";
                +}
                +.fa-shield:before {
                +  content: "\f132";
                +}
                +.fa-calendar-o:before {
                +  content: "\f133";
                +}
                +.fa-fire-extinguisher:before {
                +  content: "\f134";
                +}
                +.fa-rocket:before {
                +  content: "\f135";
                +}
                +.fa-maxcdn:before {
                +  content: "\f136";
                +}
                +.fa-chevron-circle-left:before {
                +  content: "\f137";
                +}
                +.fa-chevron-circle-right:before {
                +  content: "\f138";
                +}
                +.fa-chevron-circle-up:before {
                +  content: "\f139";
                +}
                +.fa-chevron-circle-down:before {
                +  content: "\f13a";
                +}
                +.fa-html5:before {
                +  content: "\f13b";
                +}
                +.fa-css3:before {
                +  content: "\f13c";
                +}
                +.fa-anchor:before {
                +  content: "\f13d";
                +}
                +.fa-unlock-alt:before {
                +  content: "\f13e";
                +}
                +.fa-bullseye:before {
                +  content: "\f140";
                +}
                +.fa-ellipsis-h:before {
                +  content: "\f141";
                +}
                +.fa-ellipsis-v:before {
                +  content: "\f142";
                +}
                +.fa-rss-square:before {
                +  content: "\f143";
                +}
                +.fa-play-circle:before {
                +  content: "\f144";
                +}
                +.fa-ticket:before {
                +  content: "\f145";
                +}
                +.fa-minus-square:before {
                +  content: "\f146";
                +}
                +.fa-minus-square-o:before {
                +  content: "\f147";
                +}
                +.fa-level-up:before {
                +  content: "\f148";
                +}
                +.fa-level-down:before {
                +  content: "\f149";
                +}
                +.fa-check-square:before {
                +  content: "\f14a";
                +}
                +.fa-pencil-square:before {
                +  content: "\f14b";
                +}
                +.fa-external-link-square:before {
                +  content: "\f14c";
                +}
                +.fa-share-square:before {
                +  content: "\f14d";
                +}
                +.fa-compass:before {
                +  content: "\f14e";
                +}
                +.fa-toggle-down:before,
                +.fa-caret-square-o-down:before {
                +  content: "\f150";
                +}
                +.fa-toggle-up:before,
                +.fa-caret-square-o-up:before {
                +  content: "\f151";
                +}
                +.fa-toggle-right:before,
                +.fa-caret-square-o-right:before {
                +  content: "\f152";
                +}
                +.fa-euro:before,
                +.fa-eur:before {
                +  content: "\f153";
                +}
                +.fa-gbp:before {
                +  content: "\f154";
                +}
                +.fa-dollar:before,
                +.fa-usd:before {
                +  content: "\f155";
                +}
                +.fa-rupee:before,
                +.fa-inr:before {
                +  content: "\f156";
                +}
                +.fa-cny:before,
                +.fa-rmb:before,
                +.fa-yen:before,
                +.fa-jpy:before {
                +  content: "\f157";
                +}
                +.fa-ruble:before,
                +.fa-rouble:before,
                +.fa-rub:before {
                +  content: "\f158";
                +}
                +.fa-won:before,
                +.fa-krw:before {
                +  content: "\f159";
                +}
                +.fa-bitcoin:before,
                +.fa-btc:before {
                +  content: "\f15a";
                +}
                +.fa-file:before {
                +  content: "\f15b";
                +}
                +.fa-file-text:before {
                +  content: "\f15c";
                +}
                +.fa-sort-alpha-asc:before {
                +  content: "\f15d";
                +}
                +.fa-sort-alpha-desc:before {
                +  content: "\f15e";
                +}
                +.fa-sort-amount-asc:before {
                +  content: "\f160";
                +}
                +.fa-sort-amount-desc:before {
                +  content: "\f161";
                +}
                +.fa-sort-numeric-asc:before {
                +  content: "\f162";
                +}
                +.fa-sort-numeric-desc:before {
                +  content: "\f163";
                +}
                +.fa-thumbs-up:before {
                +  content: "\f164";
                +}
                +.fa-thumbs-down:before {
                +  content: "\f165";
                +}
                +.fa-youtube-square:before {
                +  content: "\f166";
                +}
                +.fa-youtube:before {
                +  content: "\f167";
                +}
                +.fa-xing:before {
                +  content: "\f168";
                +}
                +.fa-xing-square:before {
                +  content: "\f169";
                +}
                +.fa-youtube-play:before {
                +  content: "\f16a";
                +}
                +.fa-dropbox:before {
                +  content: "\f16b";
                +}
                +.fa-stack-overflow:before {
                +  content: "\f16c";
                +}
                +.fa-instagram:before {
                +  content: "\f16d";
                +}
                +.fa-flickr:before {
                +  content: "\f16e";
                +}
                +.fa-adn:before {
                +  content: "\f170";
                +}
                +.fa-bitbucket:before {
                +  content: "\f171";
                +}
                +.fa-bitbucket-square:before {
                +  content: "\f172";
                +}
                +.fa-tumblr:before {
                +  content: "\f173";
                +}
                +.fa-tumblr-square:before {
                +  content: "\f174";
                +}
                +.fa-long-arrow-down:before {
                +  content: "\f175";
                +}
                +.fa-long-arrow-up:before {
                +  content: "\f176";
                +}
                +.fa-long-arrow-left:before {
                +  content: "\f177";
                +}
                +.fa-long-arrow-right:before {
                +  content: "\f178";
                +}
                +.fa-apple:before {
                +  content: "\f179";
                +}
                +.fa-windows:before {
                +  content: "\f17a";
                +}
                +.fa-android:before {
                +  content: "\f17b";
                +}
                +.fa-linux:before {
                +  content: "\f17c";
                +}
                +.fa-dribbble:before {
                +  content: "\f17d";
                +}
                +.fa-skype:before {
                +  content: "\f17e";
                +}
                +.fa-foursquare:before {
                +  content: "\f180";
                +}
                +.fa-trello:before {
                +  content: "\f181";
                +}
                +.fa-female:before {
                +  content: "\f182";
                +}
                +.fa-male:before {
                +  content: "\f183";
                +}
                +.fa-gittip:before,
                +.fa-gratipay:before {
                +  content: "\f184";
                +}
                +.fa-sun-o:before {
                +  content: "\f185";
                +}
                +.fa-moon-o:before {
                +  content: "\f186";
                +}
                +.fa-archive:before {
                +  content: "\f187";
                +}
                +.fa-bug:before {
                +  content: "\f188";
                +}
                +.fa-vk:before {
                +  content: "\f189";
                +}
                +.fa-weibo:before {
                +  content: "\f18a";
                +}
                +.fa-renren:before {
                +  content: "\f18b";
                +}
                +.fa-pagelines:before {
                +  content: "\f18c";
                +}
                +.fa-stack-exchange:before {
                +  content: "\f18d";
                +}
                +.fa-arrow-circle-o-right:before {
                +  content: "\f18e";
                +}
                +.fa-arrow-circle-o-left:before {
                +  content: "\f190";
                +}
                +.fa-toggle-left:before,
                +.fa-caret-square-o-left:before {
                +  content: "\f191";
                +}
                +.fa-dot-circle-o:before {
                +  content: "\f192";
                +}
                +.fa-wheelchair:before {
                +  content: "\f193";
                +}
                +.fa-vimeo-square:before {
                +  content: "\f194";
                +}
                +.fa-turkish-lira:before,
                +.fa-try:before {
                +  content: "\f195";
                +}
                +.fa-plus-square-o:before {
                +  content: "\f196";
                +}
                +.fa-space-shuttle:before {
                +  content: "\f197";
                +}
                +.fa-slack:before {
                +  content: "\f198";
                +}
                +.fa-envelope-square:before {
                +  content: "\f199";
                +}
                +.fa-wordpress:before {
                +  content: "\f19a";
                +}
                +.fa-openid:before {
                +  content: "\f19b";
                +}
                +.fa-institution:before,
                +.fa-bank:before,
                +.fa-university:before {
                +  content: "\f19c";
                +}
                +.fa-mortar-board:before,
                +.fa-graduation-cap:before {
                +  content: "\f19d";
                +}
                +.fa-yahoo:before {
                +  content: "\f19e";
                +}
                +.fa-google:before {
                +  content: "\f1a0";
                +}
                +.fa-reddit:before {
                +  content: "\f1a1";
                +}
                +.fa-reddit-square:before {
                +  content: "\f1a2";
                +}
                +.fa-stumbleupon-circle:before {
                +  content: "\f1a3";
                +}
                +.fa-stumbleupon:before {
                +  content: "\f1a4";
                +}
                +.fa-delicious:before {
                +  content: "\f1a5";
                +}
                +.fa-digg:before {
                +  content: "\f1a6";
                +}
                +.fa-pied-piper-pp:before {
                +  content: "\f1a7";
                +}
                +.fa-pied-piper-alt:before {
                +  content: "\f1a8";
                +}
                +.fa-drupal:before {
                +  content: "\f1a9";
                +}
                +.fa-joomla:before {
                +  content: "\f1aa";
                +}
                +.fa-language:before {
                +  content: "\f1ab";
                +}
                +.fa-fax:before {
                +  content: "\f1ac";
                +}
                +.fa-building:before {
                +  content: "\f1ad";
                +}
                +.fa-child:before {
                +  content: "\f1ae";
                +}
                +.fa-paw:before {
                +  content: "\f1b0";
                +}
                +.fa-spoon:before {
                +  content: "\f1b1";
                +}
                +.fa-cube:before {
                +  content: "\f1b2";
                +}
                +.fa-cubes:before {
                +  content: "\f1b3";
                +}
                +.fa-behance:before {
                +  content: "\f1b4";
                +}
                +.fa-behance-square:before {
                +  content: "\f1b5";
                +}
                +.fa-steam:before {
                +  content: "\f1b6";
                +}
                +.fa-steam-square:before {
                +  content: "\f1b7";
                +}
                +.fa-recycle:before {
                +  content: "\f1b8";
                +}
                +.fa-automobile:before,
                +.fa-car:before {
                +  content: "\f1b9";
                +}
                +.fa-cab:before,
                +.fa-taxi:before {
                +  content: "\f1ba";
                +}
                +.fa-tree:before {
                +  content: "\f1bb";
                +}
                +.fa-spotify:before {
                +  content: "\f1bc";
                +}
                +.fa-deviantart:before {
                +  content: "\f1bd";
                +}
                +.fa-soundcloud:before {
                +  content: "\f1be";
                +}
                +.fa-database:before {
                +  content: "\f1c0";
                +}
                +.fa-file-pdf-o:before {
                +  content: "\f1c1";
                +}
                +.fa-file-word-o:before {
                +  content: "\f1c2";
                +}
                +.fa-file-excel-o:before {
                +  content: "\f1c3";
                +}
                +.fa-file-powerpoint-o:before {
                +  content: "\f1c4";
                +}
                +.fa-file-photo-o:before,
                +.fa-file-picture-o:before,
                +.fa-file-image-o:before {
                +  content: "\f1c5";
                +}
                +.fa-file-zip-o:before,
                +.fa-file-archive-o:before {
                +  content: "\f1c6";
                +}
                +.fa-file-sound-o:before,
                +.fa-file-audio-o:before {
                +  content: "\f1c7";
                +}
                +.fa-file-movie-o:before,
                +.fa-file-video-o:before {
                +  content: "\f1c8";
                +}
                +.fa-file-code-o:before {
                +  content: "\f1c9";
                +}
                +.fa-vine:before {
                +  content: "\f1ca";
                +}
                +.fa-codepen:before {
                +  content: "\f1cb";
                +}
                +.fa-jsfiddle:before {
                +  content: "\f1cc";
                +}
                +.fa-life-bouy:before,
                +.fa-life-buoy:before,
                +.fa-life-saver:before,
                +.fa-support:before,
                +.fa-life-ring:before {
                +  content: "\f1cd";
                +}
                +.fa-circle-o-notch:before {
                +  content: "\f1ce";
                +}
                +.fa-ra:before,
                +.fa-resistance:before,
                +.fa-rebel:before {
                +  content: "\f1d0";
                +}
                +.fa-ge:before,
                +.fa-empire:before {
                +  content: "\f1d1";
                +}
                +.fa-git-square:before {
                +  content: "\f1d2";
                +}
                +.fa-git:before {
                +  content: "\f1d3";
                +}
                +.fa-y-combinator-square:before,
                +.fa-yc-square:before,
                +.fa-hacker-news:before {
                +  content: "\f1d4";
                +}
                +.fa-tencent-weibo:before {
                +  content: "\f1d5";
                +}
                +.fa-qq:before {
                +  content: "\f1d6";
                +}
                +.fa-wechat:before,
                +.fa-weixin:before {
                +  content: "\f1d7";
                +}
                +.fa-send:before,
                +.fa-paper-plane:before {
                +  content: "\f1d8";
                +}
                +.fa-send-o:before,
                +.fa-paper-plane-o:before {
                +  content: "\f1d9";
                +}
                +.fa-history:before {
                +  content: "\f1da";
                +}
                +.fa-circle-thin:before {
                +  content: "\f1db";
                +}
                +.fa-header:before {
                +  content: "\f1dc";
                +}
                +.fa-paragraph:before {
                +  content: "\f1dd";
                +}
                +.fa-sliders:before {
                +  content: "\f1de";
                +}
                +.fa-share-alt:before {
                +  content: "\f1e0";
                +}
                +.fa-share-alt-square:before {
                +  content: "\f1e1";
                +}
                +.fa-bomb:before {
                +  content: "\f1e2";
                +}
                +.fa-soccer-ball-o:before,
                +.fa-futbol-o:before {
                +  content: "\f1e3";
                +}
                +.fa-tty:before {
                +  content: "\f1e4";
                +}
                +.fa-binoculars:before {
                +  content: "\f1e5";
                +}
                +.fa-plug:before {
                +  content: "\f1e6";
                +}
                +.fa-slideshare:before {
                +  content: "\f1e7";
                +}
                +.fa-twitch:before {
                +  content: "\f1e8";
                +}
                +.fa-yelp:before {
                +  content: "\f1e9";
                +}
                +.fa-newspaper-o:before {
                +  content: "\f1ea";
                +}
                +.fa-wifi:before {
                +  content: "\f1eb";
                +}
                +.fa-calculator:before {
                +  content: "\f1ec";
                +}
                +.fa-paypal:before {
                +  content: "\f1ed";
                +}
                +.fa-google-wallet:before {
                +  content: "\f1ee";
                +}
                +.fa-cc-visa:before {
                +  content: "\f1f0";
                +}
                +.fa-cc-mastercard:before {
                +  content: "\f1f1";
                +}
                +.fa-cc-discover:before {
                +  content: "\f1f2";
                +}
                +.fa-cc-amex:before {
                +  content: "\f1f3";
                +}
                +.fa-cc-paypal:before {
                +  content: "\f1f4";
                +}
                +.fa-cc-stripe:before {
                +  content: "\f1f5";
                +}
                +.fa-bell-slash:before {
                +  content: "\f1f6";
                +}
                +.fa-bell-slash-o:before {
                +  content: "\f1f7";
                +}
                +.fa-trash:before {
                +  content: "\f1f8";
                +}
                +.fa-copyright:before {
                +  content: "\f1f9";
                +}
                +.fa-at:before {
                +  content: "\f1fa";
                +}
                +.fa-eyedropper:before {
                +  content: "\f1fb";
                +}
                +.fa-paint-brush:before {
                +  content: "\f1fc";
                +}
                +.fa-birthday-cake:before {
                +  content: "\f1fd";
                +}
                +.fa-area-chart:before {
                +  content: "\f1fe";
                +}
                +.fa-pie-chart:before {
                +  content: "\f200";
                +}
                +.fa-line-chart:before {
                +  content: "\f201";
                +}
                +.fa-lastfm:before {
                +  content: "\f202";
                +}
                +.fa-lastfm-square:before {
                +  content: "\f203";
                +}
                +.fa-toggle-off:before {
                +  content: "\f204";
                +}
                +.fa-toggle-on:before {
                +  content: "\f205";
                +}
                +.fa-bicycle:before {
                +  content: "\f206";
                +}
                +.fa-bus:before {
                +  content: "\f207";
                +}
                +.fa-ioxhost:before {
                +  content: "\f208";
                +}
                +.fa-angellist:before {
                +  content: "\f209";
                +}
                +.fa-cc:before {
                +  content: "\f20a";
                +}
                +.fa-shekel:before,
                +.fa-sheqel:before,
                +.fa-ils:before {
                +  content: "\f20b";
                +}
                +.fa-meanpath:before {
                +  content: "\f20c";
                +}
                +.fa-buysellads:before {
                +  content: "\f20d";
                +}
                +.fa-connectdevelop:before {
                +  content: "\f20e";
                +}
                +.fa-dashcube:before {
                +  content: "\f210";
                +}
                +.fa-forumbee:before {
                +  content: "\f211";
                +}
                +.fa-leanpub:before {
                +  content: "\f212";
                +}
                +.fa-sellsy:before {
                +  content: "\f213";
                +}
                +.fa-shirtsinbulk:before {
                +  content: "\f214";
                +}
                +.fa-simplybuilt:before {
                +  content: "\f215";
                +}
                +.fa-skyatlas:before {
                +  content: "\f216";
                +}
                +.fa-cart-plus:before {
                +  content: "\f217";
                +}
                +.fa-cart-arrow-down:before {
                +  content: "\f218";
                +}
                +.fa-diamond:before {
                +  content: "\f219";
                +}
                +.fa-ship:before {
                +  content: "\f21a";
                +}
                +.fa-user-secret:before {
                +  content: "\f21b";
                +}
                +.fa-motorcycle:before {
                +  content: "\f21c";
                +}
                +.fa-street-view:before {
                +  content: "\f21d";
                +}
                +.fa-heartbeat:before {
                +  content: "\f21e";
                +}
                +.fa-venus:before {
                +  content: "\f221";
                +}
                +.fa-mars:before {
                +  content: "\f222";
                +}
                +.fa-mercury:before {
                +  content: "\f223";
                +}
                +.fa-intersex:before,
                +.fa-transgender:before {
                +  content: "\f224";
                +}
                +.fa-transgender-alt:before {
                +  content: "\f225";
                +}
                +.fa-venus-double:before {
                +  content: "\f226";
                +}
                +.fa-mars-double:before {
                +  content: "\f227";
                +}
                +.fa-venus-mars:before {
                +  content: "\f228";
                +}
                +.fa-mars-stroke:before {
                +  content: "\f229";
                +}
                +.fa-mars-stroke-v:before {
                +  content: "\f22a";
                +}
                +.fa-mars-stroke-h:before {
                +  content: "\f22b";
                +}
                +.fa-neuter:before {
                +  content: "\f22c";
                +}
                +.fa-genderless:before {
                +  content: "\f22d";
                +}
                +.fa-facebook-official:before {
                +  content: "\f230";
                +}
                +.fa-pinterest-p:before {
                +  content: "\f231";
                +}
                +.fa-whatsapp:before {
                +  content: "\f232";
                +}
                +.fa-server:before {
                +  content: "\f233";
                +}
                +.fa-user-plus:before {
                +  content: "\f234";
                +}
                +.fa-user-times:before {
                +  content: "\f235";
                +}
                +.fa-hotel:before,
                +.fa-bed:before {
                +  content: "\f236";
                +}
                +.fa-viacoin:before {
                +  content: "\f237";
                +}
                +.fa-train:before {
                +  content: "\f238";
                +}
                +.fa-subway:before {
                +  content: "\f239";
                +}
                +.fa-medium:before {
                +  content: "\f23a";
                +}
                +.fa-yc:before,
                +.fa-y-combinator:before {
                +  content: "\f23b";
                +}
                +.fa-optin-monster:before {
                +  content: "\f23c";
                +}
                +.fa-opencart:before {
                +  content: "\f23d";
                +}
                +.fa-expeditedssl:before {
                +  content: "\f23e";
                +}
                +.fa-battery-4:before,
                +.fa-battery:before,
                +.fa-battery-full:before {
                +  content: "\f240";
                +}
                +.fa-battery-3:before,
                +.fa-battery-three-quarters:before {
                +  content: "\f241";
                +}
                +.fa-battery-2:before,
                +.fa-battery-half:before {
                +  content: "\f242";
                +}
                +.fa-battery-1:before,
                +.fa-battery-quarter:before {
                +  content: "\f243";
                +}
                +.fa-battery-0:before,
                +.fa-battery-empty:before {
                +  content: "\f244";
                +}
                +.fa-mouse-pointer:before {
                +  content: "\f245";
                +}
                +.fa-i-cursor:before {
                +  content: "\f246";
                +}
                +.fa-object-group:before {
                +  content: "\f247";
                +}
                +.fa-object-ungroup:before {
                +  content: "\f248";
                +}
                +.fa-sticky-note:before {
                +  content: "\f249";
                +}
                +.fa-sticky-note-o:before {
                +  content: "\f24a";
                +}
                +.fa-cc-jcb:before {
                +  content: "\f24b";
                +}
                +.fa-cc-diners-club:before {
                +  content: "\f24c";
                +}
                +.fa-clone:before {
                +  content: "\f24d";
                +}
                +.fa-balance-scale:before {
                +  content: "\f24e";
                +}
                +.fa-hourglass-o:before {
                +  content: "\f250";
                +}
                +.fa-hourglass-1:before,
                +.fa-hourglass-start:before {
                +  content: "\f251";
                +}
                +.fa-hourglass-2:before,
                +.fa-hourglass-half:before {
                +  content: "\f252";
                +}
                +.fa-hourglass-3:before,
                +.fa-hourglass-end:before {
                +  content: "\f253";
                +}
                +.fa-hourglass:before {
                +  content: "\f254";
                +}
                +.fa-hand-grab-o:before,
                +.fa-hand-rock-o:before {
                +  content: "\f255";
                +}
                +.fa-hand-stop-o:before,
                +.fa-hand-paper-o:before {
                +  content: "\f256";
                +}
                +.fa-hand-scissors-o:before {
                +  content: "\f257";
                +}
                +.fa-hand-lizard-o:before {
                +  content: "\f258";
                +}
                +.fa-hand-spock-o:before {
                +  content: "\f259";
                +}
                +.fa-hand-pointer-o:before {
                +  content: "\f25a";
                +}
                +.fa-hand-peace-o:before {
                +  content: "\f25b";
                +}
                +.fa-trademark:before {
                +  content: "\f25c";
                +}
                +.fa-registered:before {
                +  content: "\f25d";
                +}
                +.fa-creative-commons:before {
                +  content: "\f25e";
                +}
                +.fa-gg:before {
                +  content: "\f260";
                +}
                +.fa-gg-circle:before {
                +  content: "\f261";
                +}
                +.fa-tripadvisor:before {
                +  content: "\f262";
                +}
                +.fa-odnoklassniki:before {
                +  content: "\f263";
                +}
                +.fa-odnoklassniki-square:before {
                +  content: "\f264";
                +}
                +.fa-get-pocket:before {
                +  content: "\f265";
                +}
                +.fa-wikipedia-w:before {
                +  content: "\f266";
                +}
                +.fa-safari:before {
                +  content: "\f267";
                +}
                +.fa-chrome:before {
                +  content: "\f268";
                +}
                +.fa-firefox:before {
                +  content: "\f269";
                +}
                +.fa-opera:before {
                +  content: "\f26a";
                +}
                +.fa-internet-explorer:before {
                +  content: "\f26b";
                +}
                +.fa-tv:before,
                +.fa-television:before {
                +  content: "\f26c";
                +}
                +.fa-contao:before {
                +  content: "\f26d";
                +}
                +.fa-500px:before {
                +  content: "\f26e";
                +}
                +.fa-amazon:before {
                +  content: "\f270";
                +}
                +.fa-calendar-plus-o:before {
                +  content: "\f271";
                +}
                +.fa-calendar-minus-o:before {
                +  content: "\f272";
                +}
                +.fa-calendar-times-o:before {
                +  content: "\f273";
                +}
                +.fa-calendar-check-o:before {
                +  content: "\f274";
                +}
                +.fa-industry:before {
                +  content: "\f275";
                +}
                +.fa-map-pin:before {
                +  content: "\f276";
                +}
                +.fa-map-signs:before {
                +  content: "\f277";
                +}
                +.fa-map-o:before {
                +  content: "\f278";
                +}
                +.fa-map:before {
                +  content: "\f279";
                +}
                +.fa-commenting:before {
                +  content: "\f27a";
                +}
                +.fa-commenting-o:before {
                +  content: "\f27b";
                +}
                +.fa-houzz:before {
                +  content: "\f27c";
                +}
                +.fa-vimeo:before {
                +  content: "\f27d";
                +}
                +.fa-black-tie:before {
                +  content: "\f27e";
                +}
                +.fa-fonticons:before {
                +  content: "\f280";
                +}
                +.fa-reddit-alien:before {
                +  content: "\f281";
                +}
                +.fa-edge:before {
                +  content: "\f282";
                +}
                +.fa-credit-card-alt:before {
                +  content: "\f283";
                +}
                +.fa-codiepie:before {
                +  content: "\f284";
                +}
                +.fa-modx:before {
                +  content: "\f285";
                +}
                +.fa-fort-awesome:before {
                +  content: "\f286";
                +}
                +.fa-usb:before {
                +  content: "\f287";
                +}
                +.fa-product-hunt:before {
                +  content: "\f288";
                +}
                +.fa-mixcloud:before {
                +  content: "\f289";
                +}
                +.fa-scribd:before {
                +  content: "\f28a";
                +}
                +.fa-pause-circle:before {
                +  content: "\f28b";
                +}
                +.fa-pause-circle-o:before {
                +  content: "\f28c";
                +}
                +.fa-stop-circle:before {
                +  content: "\f28d";
                +}
                +.fa-stop-circle-o:before {
                +  content: "\f28e";
                +}
                +.fa-shopping-bag:before {
                +  content: "\f290";
                +}
                +.fa-shopping-basket:before {
                +  content: "\f291";
                +}
                +.fa-hashtag:before {
                +  content: "\f292";
                +}
                +.fa-bluetooth:before {
                +  content: "\f293";
                +}
                +.fa-bluetooth-b:before {
                +  content: "\f294";
                +}
                +.fa-percent:before {
                +  content: "\f295";
                +}
                +.fa-gitlab:before {
                +  content: "\f296";
                +}
                +.fa-wpbeginner:before {
                +  content: "\f297";
                +}
                +.fa-wpforms:before {
                +  content: "\f298";
                +}
                +.fa-envira:before {
                +  content: "\f299";
                +}
                +.fa-universal-access:before {
                +  content: "\f29a";
                +}
                +.fa-wheelchair-alt:before {
                +  content: "\f29b";
                +}
                +.fa-question-circle-o:before {
                +  content: "\f29c";
                +}
                +.fa-blind:before {
                +  content: "\f29d";
                +}
                +.fa-audio-description:before {
                +  content: "\f29e";
                +}
                +.fa-volume-control-phone:before {
                +  content: "\f2a0";
                +}
                +.fa-braille:before {
                +  content: "\f2a1";
                +}
                +.fa-assistive-listening-systems:before {
                +  content: "\f2a2";
                +}
                +.fa-asl-interpreting:before,
                +.fa-american-sign-language-interpreting:before {
                +  content: "\f2a3";
                +}
                +.fa-deafness:before,
                +.fa-hard-of-hearing:before,
                +.fa-deaf:before {
                +  content: "\f2a4";
                +}
                +.fa-glide:before {
                +  content: "\f2a5";
                +}
                +.fa-glide-g:before {
                +  content: "\f2a6";
                +}
                +.fa-signing:before,
                +.fa-sign-language:before {
                +  content: "\f2a7";
                +}
                +.fa-low-vision:before {
                +  content: "\f2a8";
                +}
                +.fa-viadeo:before {
                +  content: "\f2a9";
                +}
                +.fa-viadeo-square:before {
                +  content: "\f2aa";
                +}
                +.fa-snapchat:before {
                +  content: "\f2ab";
                +}
                +.fa-snapchat-ghost:before {
                +  content: "\f2ac";
                +}
                +.fa-snapchat-square:before {
                +  content: "\f2ad";
                +}
                +.fa-pied-piper:before {
                +  content: "\f2ae";
                +}
                +.fa-first-order:before {
                +  content: "\f2b0";
                +}
                +.fa-yoast:before {
                +  content: "\f2b1";
                +}
                +.fa-themeisle:before {
                +  content: "\f2b2";
                +}
                +.fa-google-plus-circle:before,
                +.fa-google-plus-official:before {
                +  content: "\f2b3";
                +}
                +.fa-fa:before,
                +.fa-font-awesome:before {
                +  content: "\f2b4";
                +}
                +.fa-handshake-o:before {
                +  content: "\f2b5";
                +}
                +.fa-envelope-open:before {
                +  content: "\f2b6";
                +}
                +.fa-envelope-open-o:before {
                +  content: "\f2b7";
                +}
                +.fa-linode:before {
                +  content: "\f2b8";
                +}
                +.fa-address-book:before {
                +  content: "\f2b9";
                +}
                +.fa-address-book-o:before {
                +  content: "\f2ba";
                +}
                +.fa-vcard:before,
                +.fa-address-card:before {
                +  content: "\f2bb";
                +}
                +.fa-vcard-o:before,
                +.fa-address-card-o:before {
                +  content: "\f2bc";
                +}
                +.fa-user-circle:before {
                +  content: "\f2bd";
                +}
                +.fa-user-circle-o:before {
                +  content: "\f2be";
                +}
                +.fa-user-o:before {
                +  content: "\f2c0";
                +}
                +.fa-id-badge:before {
                +  content: "\f2c1";
                +}
                +.fa-drivers-license:before,
                +.fa-id-card:before {
                +  content: "\f2c2";
                +}
                +.fa-drivers-license-o:before,
                +.fa-id-card-o:before {
                +  content: "\f2c3";
                +}
                +.fa-quora:before {
                +  content: "\f2c4";
                +}
                +.fa-free-code-camp:before {
                +  content: "\f2c5";
                +}
                +.fa-telegram:before {
                +  content: "\f2c6";
                +}
                +.fa-thermometer-4:before,
                +.fa-thermometer:before,
                +.fa-thermometer-full:before {
                +  content: "\f2c7";
                +}
                +.fa-thermometer-3:before,
                +.fa-thermometer-three-quarters:before {
                +  content: "\f2c8";
                +}
                +.fa-thermometer-2:before,
                +.fa-thermometer-half:before {
                +  content: "\f2c9";
                +}
                +.fa-thermometer-1:before,
                +.fa-thermometer-quarter:before {
                +  content: "\f2ca";
                +}
                +.fa-thermometer-0:before,
                +.fa-thermometer-empty:before {
                +  content: "\f2cb";
                +}
                +.fa-shower:before {
                +  content: "\f2cc";
                +}
                +.fa-bathtub:before,
                +.fa-s15:before,
                +.fa-bath:before {
                +  content: "\f2cd";
                +}
                +.fa-podcast:before {
                +  content: "\f2ce";
                +}
                +.fa-window-maximize:before {
                +  content: "\f2d0";
                +}
                +.fa-window-minimize:before {
                +  content: "\f2d1";
                +}
                +.fa-window-restore:before {
                +  content: "\f2d2";
                +}
                +.fa-times-rectangle:before,
                +.fa-window-close:before {
                +  content: "\f2d3";
                +}
                +.fa-times-rectangle-o:before,
                +.fa-window-close-o:before {
                +  content: "\f2d4";
                +}
                +.fa-bandcamp:before {
                +  content: "\f2d5";
                +}
                +.fa-grav:before {
                +  content: "\f2d6";
                +}
                +.fa-etsy:before {
                +  content: "\f2d7";
                +}
                +.fa-imdb:before {
                +  content: "\f2d8";
                +}
                +.fa-ravelry:before {
                +  content: "\f2d9";
                +}
                +.fa-eercast:before {
                +  content: "\f2da";
                +}
                +.fa-microchip:before {
                +  content: "\f2db";
                +}
                +.fa-snowflake-o:before {
                +  content: "\f2dc";
                +}
                +.fa-superpowers:before {
                +  content: "\f2dd";
                +}
                +.fa-wpexplorer:before {
                +  content: "\f2de";
                +}
                +.fa-meetup:before {
                +  content: "\f2e0";
                +}
                +.sr-only {
                +  position: absolute;
                +  width: 1px;
                +  height: 1px;
                +  padding: 0;
                +  margin: -1px;
                +  overflow: hidden;
                +  clip: rect(0, 0, 0, 0);
                +  border: 0;
                +}
                +.sr-only-focusable:active,
                +.sr-only-focusable:focus {
                +  position: static;
                +  width: auto;
                +  height: auto;
                +  margin: 0;
                +  overflow: visible;
                +  clip: auto;
                +}
                diff --git a/blockly/webif/static/css/font-awesome.min.css b/blockly/webif/static/css/font-awesome.min.css
                new file mode 100644
                index 000000000..540440ce8
                --- /dev/null
                +++ b/blockly/webif/static/css/font-awesome.min.css
                @@ -0,0 +1,4 @@
                +/*!
                + *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
                + *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
                + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
                diff --git a/blockly/webif/static/fonts/FontAwesome.otf b/blockly/webif/static/fonts/FontAwesome.otf
                new file mode 100644
                index 000000000..401ec0f36
                Binary files /dev/null and b/blockly/webif/static/fonts/FontAwesome.otf differ
                diff --git a/blockly/webif/static/fonts/fontawesome-webfont.eot b/blockly/webif/static/fonts/fontawesome-webfont.eot
                new file mode 100644
                index 000000000..e9f60ca95
                Binary files /dev/null and b/blockly/webif/static/fonts/fontawesome-webfont.eot differ
                diff --git a/blockly/webif/static/fonts/fontawesome-webfont.svg b/blockly/webif/static/fonts/fontawesome-webfont.svg
                new file mode 100644
                index 000000000..855c845e5
                --- /dev/null
                +++ b/blockly/webif/static/fonts/fontawesome-webfont.svg
                @@ -0,0 +1,2671 @@
                +<?xml version="1.0" standalone="no"?>
                +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
                +<svg>
                +<metadata>
                +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
                + By ,,,
                +Copyright Dave Gandy 2016. All rights reserved.
                +</metadata>
                +<defs>
                +<font id="FontAwesome" horiz-adv-x="1536" >
                +  <font-face 
                +    font-family="FontAwesome"
                +    font-weight="400"
                +    font-stretch="normal"
                +    units-per-em="1792"
                +    panose-1="0 0 0 0 0 0 0 0 0 0"
                +    ascent="1536"
                +    descent="-256"
                +    bbox="-1.02083 -256.962 2304.6 1537.02"
                +    underline-thickness="0"
                +    underline-position="0"
                +    unicode-range="U+0020-F500"
                +  />
                +<missing-glyph horiz-adv-x="896" 
                +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
                +    <glyph glyph-name=".notdef" horiz-adv-x="896" 
                +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
                +    <glyph glyph-name=".null" horiz-adv-x="0" 
                + />
                +    <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" 
                + />
                +    <glyph glyph-name="space" unicode=" " horiz-adv-x="448" 
                + />
                +    <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" 
                +d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
                +    <glyph glyph-name="music" unicode="&#xf001;" 
                +d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89
                +t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" 
                +d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5
                +t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
                +    <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" 
                +d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13
                +t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z
                +M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" 
                +d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600
                +q-18 -18 -44 -18z" />
                +    <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" 
                +d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455
                +l502 -73q56 -9 56 -46z" />
                +    <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" 
                +d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500
                +l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
                +    <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" 
                +d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5
                +t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
                +    <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" 
                +d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128
                +q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45
                +t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128
                +q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19
                +t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" 
                +d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38
                +h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" 
                +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320
                +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
                +h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192
                +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" 
                +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960
                +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
                +h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" 
                +d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
                +    <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" 
                +d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68
                +t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
                +    <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" 
                +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224
                +q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5
                +t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
                +    <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" 
                +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z
                +M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z
                +" />
                +    <glyph glyph-name="off" unicode="&#xf011;" 
                +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5
                +t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
                +    <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" 
                +d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
                +v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="cog" unicode="&#xf013;" 
                +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38
                +q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13
                +l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22
                +q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
                +    <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" 
                +d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576
                +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832
                +q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" 
                +d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5
                +l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
                +    <glyph glyph-name="file_alt" unicode="&#xf016;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +" />
                +    <glyph glyph-name="time" unicode="&#xf017;" 
                +d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" 
                +d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256
                +q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
                +    <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" 
                +d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136
                +q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
                +    <glyph glyph-name="download" unicode="&#xf01a;" 
                +d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273
                +t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="upload" unicode="&#xf01b;" 
                +d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198
                +t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="inbox" unicode="&#xf01c;" 
                +d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552
                +q25 -61 25 -123z" />
                +    <glyph glyph-name="play_circle" unicode="&#xf01d;" 
                +d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="repeat" unicode="&#xf01e;" 
                +d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9
                +l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
                +    <glyph glyph-name="refresh" unicode="&#xf021;" 
                +d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117
                +q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5
                +q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
                +    <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" 
                +d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z
                +M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5
                +t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47
                +t47 -113z" />
                +    <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" 
                +d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" 
                +d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48
                +t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" 
                +d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78
                +t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5
                +t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
                +    <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" 
                +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
                +    <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" 
                +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
                +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
                +    <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" 
                +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
                +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5
                +t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289
                +t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
                +    <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" 
                +d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z
                +M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
                +    <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" 
                +d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z
                +M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
                +    <glyph glyph-name="tag" unicode="&#xf02b;" 
                +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
                +l715 -714q37 -39 37 -91z" />
                +    <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" 
                +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
                +l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
                +    <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" 
                +d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23
                +q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906
                +q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5
                +t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
                +    <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" 
                +d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
                +    <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" 
                +d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68
                +v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
                +    <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" 
                +d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136
                +q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" 
                +d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57
                +q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5
                +q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
                +    <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" 
                +d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142
                +q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5
                +t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5
                +t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
                +    <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" 
                +d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5
                +q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
                +    <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" 
                +d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2
                +t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5
                +q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
                +q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
                +    <glyph glyph-name="text_width" unicode="&#xf035;" 
                +d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1
                +t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
                +q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5
                +t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49
                +t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
                +    <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" 
                +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45
                +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" 
                +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19
                +h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" 
                +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
                +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" 
                +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
                +t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" 
                +d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5
                +t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344
                +q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
                +t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192
                +q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
                +    <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" 
                +d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
                +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
                +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
                +    <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" 
                +d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
                +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
                +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
                +    <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" 
                +d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5
                +q39 -17 39 -59z" />
                +    <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" 
                +d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216
                +q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="pencil" unicode="&#xf040;" 
                +d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38
                +q53 0 91 -38l235 -234q37 -39 37 -91z" />
                +    <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" 
                +d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
                +    <glyph glyph-name="adjust" unicode="&#xf042;" 
                +d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" 
                +d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362
                +q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
                +    <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" 
                +d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
                +q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92
                +l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
                +    <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" 
                +d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832
                +q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5
                +t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
                +    <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" 
                +d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832
                +q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110
                +q24 -24 24 -57t-24 -57z" />
                +    <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" 
                +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45
                +t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
                +    <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" 
                +d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" />
                +    <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" 
                +d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710
                +q19 19 32 13t13 -32v-710q4 10 13 19z" />
                +    <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" 
                +d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" />
                +    <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" 
                +d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
                +    <glyph glyph-name="pause" unicode="&#xf04c;" 
                +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="stop" unicode="&#xf04d;" 
                +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" 
                +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
                +    <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" 
                +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710
                +q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
                +    <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" 
                +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" />
                +    <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" 
                +d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
                +    <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" 
                +d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
                +    <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" 
                +d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
                +    <glyph glyph-name="plus_sign" unicode="&#xf055;" 
                +d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5
                +t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="minus_sign" unicode="&#xf056;" 
                +d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
                +t103 -385.5z" />
                +    <glyph glyph-name="remove_sign" unicode="&#xf057;" 
                +d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19
                +q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="ok_sign" unicode="&#xf058;" 
                +d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
                +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="question_sign" unicode="&#xf059;" 
                +d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59
                +q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
                +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="info_sign" unicode="&#xf05a;" 
                +d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23
                +t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="screenshot" unicode="&#xf05b;" 
                +d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109
                +q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143
                +q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="remove_circle" unicode="&#xf05c;" 
                +d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
                +l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5
                +t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="ok_circle" unicode="&#xf05d;" 
                +d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198
                +t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="ban_circle" unicode="&#xf05e;" 
                +d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61
                +t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
                +    <glyph glyph-name="arrow_left" unicode="&#xf060;" 
                +d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5
                +t32.5 -90.5z" />
                +    <glyph glyph-name="arrow_right" unicode="&#xf061;" 
                +d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
                +    <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" 
                +d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651
                +q37 -39 37 -91z" />
                +    <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" 
                +d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
                +    <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" 
                +d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22
                +t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
                +    <glyph glyph-name="resize_full" unicode="&#xf065;" 
                +d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332
                +q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="resize_small" unicode="&#xf066;" 
                +d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45
                +t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
                +    <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" 
                +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" 
                +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" 
                +d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154
                +q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
                +    <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192
                +q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
                +    <glyph glyph-name="gift" unicode="&#xf06b;" 
                +d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320
                +q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5
                +t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" 
                +d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268
                +q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5
                +t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
                +    <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" 
                +d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1
                +q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
                +    <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" 
                +d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5
                +t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
                +    <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" 
                +d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9
                +q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5
                +q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z
                +" />
                +    <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" 
                +d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185
                +q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
                +    <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" 
                +d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9
                +q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
                +    <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" 
                +d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z
                +M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64
                +q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47
                +h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" 
                +d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1
                +t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5
                +v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111
                +t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
                +    <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" 
                +d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281
                +q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
                +    <glyph glyph-name="magnet" unicode="&#xf076;" 
                +d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384
                +q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" 
                +d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
                +    <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" 
                +d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
                +    <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" 
                +d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21
                +zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z
                +" />
                +    <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" 
                +d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45
                +t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" 
                +d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
                +    <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" 
                +d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5
                +t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
                +    <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" 
                +d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
                +    <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" 
                +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
                +    <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" 
                +d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
                +    <glyph glyph-name="twitter_sign" unicode="&#xf081;" 
                +d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4
                +q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5
                +t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="facebook_sign" unicode="&#xf082;" 
                +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960
                +q0 119 84.5 203.5t203.5 84.5h960z" />
                +    <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" 
                +d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5
                +t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280
                +q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
                +    <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" 
                +d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26
                +l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5
                +t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
                +    <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" 
                +d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5
                +t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5
                +l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7
                +l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31
                +q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20
                +t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68
                +q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70
                +q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
                +    <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" 
                +d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224
                +q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7
                +q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
                +    <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" 
                +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5
                +t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769
                +q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128
                +q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
                +    <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" 
                +d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5
                +t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z
                +M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5
                +h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" />
                +    <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" 
                +d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
                +    <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" 
                +d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559
                +q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5
                +q224 0 351 -124t127 -344z" />
                +    <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" 
                +d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704
                +q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
                +    <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" 
                +d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5
                +q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" 
                +d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38
                +t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
                +    <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" 
                +d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320
                +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="signin" unicode="&#xf090;" 
                +d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5
                +q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" 
                +d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91
                +t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96
                +q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="github_sign" unicode="&#xf092;" 
                +d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4
                +q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4
                +t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16
                +q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" 
                +d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92
                +t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
                +    <glyph glyph-name="lemon" unicode="&#xf094;" 
                +d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5
                +q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44
                +q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5
                +q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" />
                +    <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" 
                +d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186
                +q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14
                +t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
                +    <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" 
                +d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
                +q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" 
                +d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289
                +q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
                +    <glyph glyph-name="phone_sign" unicode="&#xf098;" 
                +d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5
                +t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5
                +t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z
                +" />
                +    <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" 
                +d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41
                +q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
                +    <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" 
                +d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
                +    <glyph glyph-name="github" unicode="&#xf09b;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24
                +q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5
                +t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12
                +q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z
                +M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" />
                +    <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" 
                +d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5
                +t316.5 -131.5t131.5 -316.5z" />
                +    <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" 
                +d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608
                +q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
                +    <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" 
                +d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5
                +t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294
                +q187 -186 294 -425.5t120 -501.5z" />
                +    <glyph glyph-name="hdd" unicode="&#xf0a0;" 
                +d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5
                +h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75
                +l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
                +    <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" 
                +d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5
                +t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
                +    <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" 
                +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z
                +M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5
                +t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
                +    <glyph glyph-name="certificate" unicode="&#xf0a3;" 
                +d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70
                +l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70
                +l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
                +    <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" 
                +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106
                +q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43
                +q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5
                +t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
                +    <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" 
                +d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5
                +t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z
                +M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67
                +q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
                +    <glyph glyph-name="hand_up" unicode="&#xf0a6;" 
                +d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576
                +q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5
                +t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76
                +q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
                +    <glyph glyph-name="hand_down" unicode="&#xf0a7;" 
                +d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33
                +t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580
                +q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100
                +q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
                +    <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" 
                +d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" 
                +d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" 
                +d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" 
                +d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="globe" unicode="&#xf0ac;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11
                +q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5
                +q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5
                +q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5
                +t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3
                +q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25
                +q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5
                +t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5
                +t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21
                +q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5
                +q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3
                +q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5
                +t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5
                +q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7
                +q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
                +    <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" 
                +d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5
                +t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
                +    <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" 
                +d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19
                +t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" 
                +d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
                +    <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" 
                +d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68
                +t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="fullscreen" unicode="&#xf0b2;" 
                +d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144
                +l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z
                +" />
                +    <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" 
                +d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5
                +t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75
                +t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5
                +t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
                +    <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" 
                +d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26
                +l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15
                +t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207
                +q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
                +    <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" 
                +d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z
                +" />
                +    <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" 
                +d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
                +    <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" 
                +d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84
                +q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148
                +q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108
                +q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6
                +q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
                +    <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" 
                +d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299
                +h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
                +    <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" 
                +d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181
                +l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235
                +z" />
                +    <glyph glyph-name="save" unicode="&#xf0c7;" 
                +d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5
                +h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
                +    <glyph glyph-name="sign_blank" unicode="&#xf0c8;" 
                +d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="reorder" unicode="&#xf0c9;" 
                +d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45
                +t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" 
                +d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
                +t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z
                +M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
                +    <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" 
                +d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362
                +q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5
                +t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216
                +q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
                +    <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" 
                +d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6
                +l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23
                +l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
                +    <glyph glyph-name="underline" unicode="&#xf0cd;" 
                +d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47
                +q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41
                +q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472
                +q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
                +    <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" 
                +d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23
                +v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192
                +q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192
                +q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113
                +z" />
                +    <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" 
                +d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276
                +l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
                +    <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" 
                +d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5
                +t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38
                +t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="pinterest" unicode="&#xf0d2;" 
                +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134
                +q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33
                +q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" 
                +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5
                +t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5
                +t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
                +    <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" 
                +d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585
                +h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" 
                +d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62
                +q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" />
                +    <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" 
                +d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384
                +v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" 
                +d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" 
                +d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
                +    <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" 
                +d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
                +    <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" 
                +d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
                +    <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" 
                +d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" 
                +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
                +    <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" 
                +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" 
                +d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
                +    <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" 
                +d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123
                +q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
                +    <glyph glyph-name="linkedin" unicode="&#xf0e1;" 
                +d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329
                +q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
                +    <glyph glyph-name="undo" unicode="&#xf0e2;" 
                +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
                +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
                +    <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" 
                +d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5
                +t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14
                +q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28
                +q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
                +    <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" 
                +d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5
                +t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5
                +t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29
                +q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" 
                +d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640
                +q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5
                +t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
                +    <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" 
                +d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257
                +t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5
                +t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129
                +q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
                +    <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" 
                +d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
                +    <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" 
                +d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320
                +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68
                +z" />
                +    <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" 
                +d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97
                +q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69
                +q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
                +    <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" 
                +d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28
                +h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
                +    <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" 
                +d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134
                +q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47
                +q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5
                +t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
                +    <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" 
                +d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9
                +q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
                +    <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" 
                +d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
                +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
                +    <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" 
                +d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
                +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
                +    <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" 
                +d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56
                +t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68
                +t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
                +t271.5 -112.5t112.5 -271.5z" />
                +    <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" 
                +d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48
                +t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252
                +t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
                +    <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" 
                +d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66
                +t66 -158z" />
                +    <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" 
                +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5
                +t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
                +    <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" 
                +d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45
                +t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
                +    <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" 
                +d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45
                +t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704
                +q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
                +    <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" 
                +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" 
                +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
                +M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5
                +t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320
                +v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" 
                +d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5
                +t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152
                +q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" 
                +d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32
                +q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
                +    <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" 
                +d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96
                +q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" />
                +    <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" 
                +d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
                +    <glyph glyph-name="h_sign" unicode="&#xf0fd;" 
                +d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="f0fe" unicode="&#xf0fe;" 
                +d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" 
                +d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
                +t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
                +    <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" 
                +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23
                +l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
                +    <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" 
                +d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393
                +q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
                +    <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" 
                +d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
                +t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
                +    <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" 
                +d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
                +    <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" 
                +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
                +    <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" 
                +d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
                +    <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" 
                +d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
                +    <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" 
                +d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19
                +t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" 
                +d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z
                +M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
                +    <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" 
                +d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832
                +q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" 
                +d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136
                +q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="circle_blank" unicode="&#xf10c;" 
                +d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103
                +t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" 
                +d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z
                +M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
                +    <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" 
                +d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216
                +v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
                +    <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" 
                +d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5
                +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z
                +M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5
                +q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
                +    <glyph glyph-name="circle" unicode="&#xf111;" 
                +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" 
                +d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19
                +l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
                +    <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" 
                +d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320
                +q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86
                +t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218
                +q0 -87 -27 -168q136 -160 136 -398z" />
                +    <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" 
                +d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320
                +q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
                +    <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" 
                +d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68
                +v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z
                +" />
                +    <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="smile" unicode="&#xf118;" 
                +d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
                +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5
                +t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="frown" unicode="&#xf119;" 
                +d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
                +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204
                +t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="meh" unicode="&#xf11a;" 
                +d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
                +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" 
                +d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
                +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150
                +t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
                +    <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" 
                +d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16
                +h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16
                +h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96
                +q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896
                +h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
                +    <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" 
                +d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9
                +h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102
                +q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
                +    <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" 
                +d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2
                +q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266
                +q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8
                +q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
                +    <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" 
                +d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9
                +t9 -23z" />
                +    <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" 
                +d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5
                +l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
                +    <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" 
                +d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1
                +q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
                +    <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" 
                +d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5
                +l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
                +    <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" 
                +d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
                +    <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" 
                +d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23
                +v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" 
                +d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5
                +q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497
                +q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
                +    <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" 
                +d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320
                +q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18
                +l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9
                +t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
                +    <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" 
                +d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5
                +t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
                +    <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" 
                +d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192
                +q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" 
                +d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
                +    <glyph glyph-name="superscript" unicode="&#xf12b;" 
                +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
                +M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5
                +t-65.5 -51.5t-30.5 -63h232v80h126z" />
                +    <glyph glyph-name="subscript" unicode="&#xf12c;" 
                +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
                +M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73
                +h232v80h126z" />
                +    <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" 
                +d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
                +    <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" 
                +d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5
                +t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89
                +q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117
                +q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
                +    <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" 
                +d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5
                +t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
                +    <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" 
                +d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128
                +q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23
                +t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
                +    <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" 
                +d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150
                +t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" 
                +d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
                +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" 
                +d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800
                +q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113
                +q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
                +    <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" 
                +d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1
                +q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
                +    <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" 
                +d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
                +    <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" 
                +d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
                +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" 
                +d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
                +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" 
                +d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
                +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" 
                +d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
                +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" 
                +d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
                +    <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" 
                +d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
                +    <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" 
                +d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352
                +q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19
                +t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" 
                +d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181
                +v-320h736z" />
                +    <glyph glyph-name="bullseye" unicode="&#xf140;" 
                +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150
                +t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
                +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" 
                +d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192
                +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" 
                +d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192
                +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
                +    <glyph glyph-name="_303" unicode="&#xf143;" 
                +d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128
                +q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="play_sign" unicode="&#xf144;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56
                +q16 -8 32 -8q17 0 32 9z" />
                +    <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" 
                +d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136
                +t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
                +    <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" 
                +d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
                +t84.5 -203.5z" />
                +    <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" 
                +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5
                +t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" 
                +d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
                +    <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" 
                +d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
                +    <glyph glyph-name="check_sign" unicode="&#xf14a;" 
                +d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5
                +t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="edit_sign" unicode="&#xf14b;" 
                +d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120
                +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_312" unicode="&#xf14c;" 
                +d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960
                +q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="share_sign" unicode="&#xf14d;" 
                +d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5
                +t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="compass" unicode="&#xf14e;" 
                +d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
                +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="collapse" unicode="&#xf150;" 
                +d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120
                +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="collapse_top" unicode="&#xf151;" 
                +d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_317" unicode="&#xf152;" 
                +d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5
                +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" 
                +d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9
                +t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26
                +l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
                +    <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" 
                +d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7
                +q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
                +    <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" 
                +d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43
                +t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5
                +t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50
                +t53 -63.5t31.5 -76.5t13 -94z" />
                +    <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" 
                +d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102
                +q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" 
                +d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61
                +l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
                +    <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" 
                +d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128
                +q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
                +    <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" 
                +d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23
                +t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28
                +q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" 
                +d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164
                +l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30
                +t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
                +    <glyph glyph-name="file" unicode="&#xf15b;" 
                +d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
                +    <glyph glyph-name="file_text" unicode="&#xf15c;" 
                +d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704
                +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
                +    <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" 
                +d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23
                +v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162
                +l230 -662h70z" />
                +    <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" 
                +d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150
                +v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248
                +v119h121z" />
                +    <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" 
                +d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832
                +q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256
                +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" 
                +d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192
                +q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832
                +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="sort_by_order" unicode="&#xf162;" 
                +d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23
                +zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5
                +t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
                +    <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" 
                +d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9
                +t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13
                +q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
                +    <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" 
                +d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76
                +q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5
                +t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
                +    <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" 
                +d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135
                +t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121
                +t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
                +    <glyph glyph-name="youtube_sign" unicode="&#xf166;" 
                +d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15
                +q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38
                +q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5
                +q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38
                +q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5
                +h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="youtube" unicode="&#xf167;" 
                +d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73
                +q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51
                +q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99
                +q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51
                +q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
                +    <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" 
                +d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942
                +q25 45 64 45h241q22 0 31 -15z" />
                +    <glyph glyph-name="xing_sign" unicode="&#xf169;" 
                +d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1
                +l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" 
                +d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5
                +l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136
                +q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" />
                +    <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" 
                +d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
                +    <glyph glyph-name="stackexchange" unicode="&#xf16c;" 
                +d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" />
                +    <glyph glyph-name="instagram" unicode="&#xf16d;" 
                +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270
                +q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5
                +t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317
                +q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" />
                +    <glyph glyph-name="flickr" unicode="&#xf16e;" 
                +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150
                +t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
                +    <glyph glyph-name="adn" unicode="&#xf170;" 
                +d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" 
                +d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22
                +t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18
                +t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5
                +t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
                +    <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" 
                +d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5
                +t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z
                +M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120
                +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" 
                +d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14
                +q78 2 134 29z" />
                +    <glyph glyph-name="tumblr_sign" unicode="&#xf174;" 
                +d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z
                +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" 
                +d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
                +    <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" 
                +d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
                +    <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" 
                +d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" 
                +d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
                +    <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" 
                +d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65
                +q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
                +    <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" 
                +d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
                +    <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" 
                +d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30
                +t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5
                +h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
                +    <glyph glyph-name="linux" unicode="&#xf17c;" 
                +d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z
                +M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7
                +q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15
                +q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5
                +t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19
                +q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63
                +q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92
                +q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152
                +q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4
                +t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5
                +t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43
                +q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49
                +t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54
                +q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5
                +t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5
                +t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
                +    <glyph glyph-name="dribble" unicode="&#xf17d;" 
                +d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81
                +t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19
                +q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6
                +t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="skype" unicode="&#xf17e;" 
                +d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5
                +t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5
                +q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80
                +q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
                +    <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" 
                +d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z
                +M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324
                +l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
                +    <glyph glyph-name="trello" unicode="&#xf181;" 
                +d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408
                +q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" 
                +d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43
                +q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
                +    <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" 
                +d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z
                +M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
                +    <glyph glyph-name="gittip" unicode="&#xf184;" 
                +d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
                +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" 
                +d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4
                +l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94
                +q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
                +    <glyph glyph-name="_366" unicode="&#xf186;" 
                +d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61
                +t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
                +    <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" 
                +d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536
                +q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" 
                +d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207
                +q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19
                +t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
                +    <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" 
                +d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58
                +t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6
                +q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24
                +q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2
                +q39 5 64 -2.5t31 -16.5z" />
                +    <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" 
                +d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12
                +q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422
                +q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178
                +q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z
                +M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
                +    <glyph glyph-name="renren" unicode="&#xf18b;" 
                +d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495
                +q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
                +    <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" 
                +d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5
                +t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56
                +t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5
                +t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
                +    <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" 
                +d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z
                +" />
                +    <glyph glyph-name="_374" unicode="&#xf18e;" 
                +d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
                +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" 
                +d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
                +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_376" unicode="&#xf191;" 
                +d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z
                +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" 
                +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5
                +t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" 
                +d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128
                +q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
                +    <glyph glyph-name="vimeo_square" unicode="&#xf194;" 
                +d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179
                +q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" 
                +d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160
                +q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" 
                +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832
                +q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" 
                +d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40
                +t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29
                +q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
                +    <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" 
                +d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9
                +q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102
                +t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
                +    <glyph glyph-name="_384" unicode="&#xf199;" 
                +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69
                +q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13
                +t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
                +    <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" 
                +d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5
                +t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21
                +t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286
                +t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273
                +t273 -182.5t331.5 -68z" />
                +    <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" 
                +d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
                +    <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" 
                +d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64
                +q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
                +    <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" 
                +d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433
                +q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
                +    <glyph glyph-name="_389" unicode="&#xf19e;" 
                +d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0
                +q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
                +    <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" 
                +d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5
                +t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" />
                +    <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" 
                +d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26
                +t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37
                +q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191
                +t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="_392" unicode="&#xf1a2;" 
                +d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54
                +q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83
                +q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
                +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_393" unicode="&#xf1a3;" 
                +d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150
                +v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103
                +t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" 
                +d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328
                +v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
                +    <glyph glyph-name="_395" unicode="&#xf1a5;" 
                +d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
                +t84.5 -203.5z" />
                +    <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" 
                +d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123
                +v-369h123z" />
                +    <glyph glyph-name="_397" unicode="&#xf1a7;" 
                +d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101
                +v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
                +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" 
                +d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14
                +q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24
                +q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33
                +q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5
                +t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43
                +q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5
                +t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13
                +t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
                +    <glyph glyph-name="_399" unicode="&#xf1a9;" 
                +d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10
                +q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14
                +q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14
                +t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44
                +q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
                +    <glyph glyph-name="_400" unicode="&#xf1aa;" 
                +d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z
                +M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5
                +t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5
                +q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126
                +t135.5 51q85 0 145 -60.5t60 -145.5z" />
                +    <glyph glyph-name="f1ab" unicode="&#xf1ab;" 
                +d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5
                +q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28
                +q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z
                +M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11
                +q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5
                +q20 0 20 -21v-418z" />
                +    <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" 
                +d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48
                +l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23
                +t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128
                +q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128
                +q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
                +    <glyph glyph-name="_403" unicode="&#xf1ad;" 
                +d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9
                +t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64
                +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
                +q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9
                +t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64
                +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
                +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9
                +t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
                +    <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" 
                +d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152
                +q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
                +    <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" 
                +d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5
                +q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819
                +q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5
                +t100.5 134t141.5 55.5z" />
                +    <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" 
                +d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
                +    <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" 
                +d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z
                +" />
                +    <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" 
                +d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67
                +t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70
                +v-400l434 -186q36 -16 57 -48t21 -70z" />
                +    <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" 
                +d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658
                +q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204
                +q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
                +    <glyph glyph-name="_410" unicode="&#xf1b5;" 
                +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5
                +t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217
                +t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
                +    <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" 
                +d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5
                +q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89
                +q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
                +    <glyph glyph-name="_412" unicode="&#xf1b7;" 
                +d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5
                +q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5
                +q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z
                +" />
                +    <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" 
                +d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188
                +l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5
                +t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1
                +q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
                +    <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" 
                +d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384
                +q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5
                +l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
                +    <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" 
                +d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5
                +t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z
                +M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
                +    <glyph glyph-name="_416" unicode="&#xf1bb;" 
                +d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384
                +q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
                +    <glyph glyph-name="_417" unicode="&#xf1bc;" 
                +d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64
                +q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37
                +q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" 
                +d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
                +    <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" 
                +d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11
                +q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245
                +q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785
                +l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242
                +q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236
                +q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786
                +q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
                +    <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" 
                +d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127
                +t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5
                +t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
                +    <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197
                +q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8
                +q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
                +    <glyph glyph-name="_422" unicode="&#xf1c2;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5
                +t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" />
                +    <glyph glyph-name="_423" unicode="&#xf1c3;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107
                +h-290v-107h68l189 -272l-194 -283h-68z" />
                +    <glyph glyph-name="_424" unicode="&#xf1c4;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
                +    <glyph glyph-name="_425" unicode="&#xf1c5;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
                +    <glyph glyph-name="_426" unicode="&#xf1c6;" 
                +d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400
                +v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79
                +q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
                +    <glyph glyph-name="_427" unicode="&#xf1c7;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5
                +q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
                +    <glyph glyph-name="_428" unicode="&#xf1c8;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
                +    <glyph glyph-name="_429" unicode="&#xf1c9;" 
                +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
                +M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243
                +l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
                +    <glyph glyph-name="_430" unicode="&#xf1ca;" 
                +d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406
                +q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
                +    <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" 
                +d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546
                +q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
                +    <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" 
                +d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94
                +q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55
                +t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" />
                +    <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" 
                +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194
                +q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5
                +t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
                +    <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" 
                +d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5
                +t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" />
                +    <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" 
                +d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41
                +t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170
                +t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136
                +q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
                +    <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" 
                +d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251
                +l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162
                +q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33
                +q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5
                +t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
                +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" 
                +d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85
                +q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392
                +q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072
                +q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" 
                +d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58
                +q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47
                +q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171
                +v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
                +    <glyph glyph-name="_439" unicode="&#xf1d4;" 
                +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" 
                +d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5
                +t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153
                +t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
                +    <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" 
                +d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5
                +q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20
                +t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5
                +t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
                +    <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" 
                +d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25
                +q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5
                +q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109
                +q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
                +    <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" 
                +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
                +    <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" 
                +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137
                +l863 639l-478 -797z" />
                +    <glyph glyph-name="_445" unicode="&#xf1da;" 
                +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
                +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23
                +t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="_446" unicode="&#xf1db;" 
                +d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
                +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" 
                +d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15
                +t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2
                +t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160
                +q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5
                +q0 -26 -12 -48t-36 -22z" />
                +    <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" 
                +d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179
                +q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
                +    <glyph glyph-name="_449" unicode="&#xf1de;" 
                +d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256
                +q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
                +    <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" 
                +d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5
                +t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
                +    <glyph glyph-name="_451" unicode="&#xf1e1;" 
                +d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5
                +t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" 
                +d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5
                +t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91
                +q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9
                +t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
                +    <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" 
                +d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323
                +l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
                +    <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" 
                +d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
                +v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192
                +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23
                +zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5
                +t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
                +    <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" 
                +d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z
                +M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" 
                +d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234
                +l401 400q38 37 91 37t90 -37z" />
                +    <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" 
                +d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5
                +t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z
                +M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7
                +t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
                +    <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" 
                +d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
                +    <glyph glyph-name="_459" unicode="&#xf1e9;" 
                +d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36
                +q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5
                +t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87
                +q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
                +    <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" 
                +d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19
                +t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
                +    <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" 
                +d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121
                +q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z
                +M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
                +    <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" 
                +d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
                +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5
                +t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5
                +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
                +M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38
                +h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_463" unicode="&#xf1ed;" 
                +d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246
                +q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598
                +q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
                +    <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" 
                +d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640
                +q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" />
                +    <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" 
                +d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27
                +q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128
                +q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" 
                +d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249
                +q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z
                +M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32
                +h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4
                +q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75
                +q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14
                +q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22
                +q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12
                +q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122
                +h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5
                +t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" 
                +d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42
                +q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604
                +v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569
                +q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73
                +t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
                +    <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" 
                +d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z
                +M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260
                +l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279
                +v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040
                +q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168
                +q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5
                +t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21
                +h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5
                +t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
                +    <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" 
                +d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16
                +t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76
                +q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59
                +t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489
                +l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66
                +q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" 
                +d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109
                +q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118
                +q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151
                +q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31
                +q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" 
                +d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5
                +l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5
                +l418 363q10 8 23.5 7t21.5 -11z" />
                +    <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" 
                +d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128
                +q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161
                +q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
                +    <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" 
                +d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704
                +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167
                +q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="_474" unicode="&#xf1f9;" 
                +d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5
                +t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5
                +t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_475" unicode="&#xf1fa;" 
                +d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53
                +q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24
                +t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61
                +t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
                +    <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" 
                +d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10
                +t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
                +    <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" 
                +d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5
                +t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
                +    <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" 
                +d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5
                +t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38
                +t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448
                +h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5
                +q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
                +    <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" 
                +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
                +    <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" 
                +d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" 
                +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9
                +t9 -23z" />
                +    <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" 
                +d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20
                +q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50
                +t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1
                +q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
                +    <glyph glyph-name="_483" unicode="&#xf203;" 
                +d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73
                +q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110
                +q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960
                +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" 
                +d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5
                +t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5
                +t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
                +    <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" 
                +d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5
                +t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
                +    <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" 
                +d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94
                +q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469
                +q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400
                +q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
                +    <glyph glyph-name="_487" unicode="&#xf207;" 
                +d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5
                +h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
                +t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
                +    <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" 
                +d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327
                +q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5
                +q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
                +    <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" 
                +d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119
                +t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5
                +t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14
                +q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88
                +q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5
                +t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
                +    <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" 
                +d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206
                +q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307
                +t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14
                +t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
                +    <glyph glyph-name="_491" unicode="&#xf20b;" 
                +d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5
                +t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="_492" unicode="&#xf20c;" 
                +d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55
                +q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410
                +q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
                +    <glyph glyph-name="_493" unicode="&#xf20d;" 
                +d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
                +    <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" 
                +d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335
                +q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5
                +q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438
                +h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66
                +l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946
                +l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82
                +zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
                +    <glyph glyph-name="f210" unicode="&#xf210;" 
                +d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
                +    <glyph glyph-name="_496" unicode="&#xf211;" 
                +d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384
                +q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
                +    <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" 
                +d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021
                +q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25
                +q209 0 374 -102q172 107 374 102z" />
                +    <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" 
                +d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101
                +q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284
                +q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
                +    <glyph glyph-name="_499" unicode="&#xf214;" 
                +d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34
                +l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114
                +v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z
                +M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378
                +v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51
                +h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5
                +t-43 -34t-16.5 -53.5z" />
                +    <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" 
                +d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832
                +q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
                +    <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" 
                +d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5
                +t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113
                +t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5
                +q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
                +    <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" 
                +d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
                +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
                +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" 
                +d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
                +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
                +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" 
                +d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20
                +l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
                +    <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" 
                +d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
                +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83
                +q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314
                +v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
                +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
                +    <glyph glyph-name="_506" unicode="&#xf21b;" 
                +d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14
                +t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5
                +q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31
                +t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
                +    <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" 
                +d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5
                +t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105
                +l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226
                +t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
                +    <glyph glyph-name="_508" unicode="&#xf21d;" 
                +d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12
                +q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384
                +q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5
                +t158.5 -65.5t65.5 -158.5z" />
                +    <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" 
                +d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221
                +q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124
                +t127 -344z" />
                +    <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" 
                +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292
                +q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
                +    <glyph glyph-name="_511" unicode="&#xf222;" 
                +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5
                +q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" 
                +d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5
                +t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
                +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_513" unicode="&#xf224;" 
                +d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
                +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
                +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" 
                +d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
                +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9
                +t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5
                +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" 
                +d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23
                +t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391
                +q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391
                +q0 -226 -154 -391q103 -57 218 -57z" />
                +    <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" 
                +d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230
                +q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9
                +t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128
                +q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
                +    <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" 
                +d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23
                +t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9
                +t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5
                +t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
                +    <glyph glyph-name="_518" unicode="&#xf229;" 
                +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5
                +t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
                +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" 
                +d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22
                +t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5
                +t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" 
                +d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5
                +t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5
                +t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" 
                +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5
                +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
                +    <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" 
                +d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123
                +t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
                +    <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="_525" unicode="&#xf230;" 
                +d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
                +    <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" 
                +d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5
                +l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5
                +q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
                +    <glyph glyph-name="_527" unicode="&#xf232;" 
                +d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5
                +t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233
                +l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
                +    <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" 
                +d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216
                +q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
                +    <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" 
                +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5
                +t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5
                +t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
                +    <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" 
                +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136
                +q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69
                +t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
                +    <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" 
                +d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704
                +q-26 0 -45 -19t-19 -45v-384h1152z" />
                +    <glyph glyph-name="_532" unicode="&#xf237;" 
                +d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
                +    <glyph glyph-name="_533" unicode="&#xf238;" 
                +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56
                +t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
                +    <glyph glyph-name="_534" unicode="&#xf239;" 
                +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47
                +t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
                +    <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" 
                +d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116
                +q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" />
                +    <glyph glyph-name="_536" unicode="&#xf23b;" 
                +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
                +    <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" 
                +d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5
                +q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5
                +q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42
                +q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37
                +q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5
                +q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139
                +q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8
                +t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132
                +q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132
                +q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z
                +M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86
                +t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103
                +q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4
                +l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130
                +t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150
                +q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12
                +q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" />
                +    <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" 
                +d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5
                +t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5
                +t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" />
                +    <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" 
                +d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348
                +t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23
                +t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96
                +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512
                +q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" />
                +    <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" 
                +d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113
                +v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" />
                +    <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" 
                +d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
                +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
                +    <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" 
                +d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
                +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
                +    <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" 
                +d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
                +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
                +    <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" 
                +d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23
                +v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
                +    <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" 
                +d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" />
                +    <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" 
                +d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" />
                +    <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" 
                +d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128
                +h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
                +    <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" 
                +d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256
                +v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
                +    <glyph glyph-name="_549" unicode="&#xf249;" 
                +d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" />
                +    <glyph glyph-name="_550" unicode="&#xf24a;" 
                +d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68
                +z" />
                +    <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" 
                +d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5
                +t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88
                +t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90
                +t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" 
                +d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294
                +t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z
                +M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" 
                +d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113
                +zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" 
                +d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64
                +q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91
                +t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5
                +t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" />
                +    <glyph glyph-name="_555" unicode="&#xf250;" 
                +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
                +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5
                +t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
                +    <glyph glyph-name="_556" unicode="&#xf251;" 
                +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
                +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" />
                +    <glyph glyph-name="_557" unicode="&#xf252;" 
                +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
                +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" />
                +    <glyph glyph-name="_558" unicode="&#xf253;" 
                +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
                +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196
                +h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
                +    <glyph glyph-name="_559" unicode="&#xf254;" 
                +d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87
                +t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9
                +h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" />
                +    <glyph glyph-name="_560" unicode="&#xf255;" 
                +d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25
                +q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27
                +t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21
                +q72 69 174 69z" />
                +    <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" 
                +d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33
                +t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52
                +h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" />
                +    <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" 
                +d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668
                +q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17
                +t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5
                +t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5
                +q0 -42 -23 -78t-61 -53l-310 -141h91z" />
                +    <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" 
                +d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32
                +q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68
                +q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" />
                +    <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" 
                +d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79
                +t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24
                +q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26
                +l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" />
                +    <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" 
                +d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5
                +q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5
                +v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32
                +v-384h32z" />
                +    <glyph glyph-name="_566" unicode="&#xf25b;" 
                +d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181
                +v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46
                +q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5
                +q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308
                +q0 -53 37.5 -90.5t90.5 -37.5h668z" />
                +    <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" 
                +d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5
                +t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141
                +q13 0 22 -8.5t10 -20.5z" />
                +    <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" 
                +d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109
                +t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640
                +q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" 
                +d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78
                +q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5
                +t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376
                +q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191
                +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" />
                +    <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" 
                +d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
                +    <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" 
                +d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191
                +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" 
                +d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57
                +t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197
                +t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5
                +t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5
                +t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5
                +q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" />
                +    <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" 
                +d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5
                +t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94
                +q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" />
                +    <glyph glyph-name="_574" unicode="&#xf264;" 
                +d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32
                +q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5
                +zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" 
                +d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33
                +l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" />
                +    <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" 
                +d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540
                +q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81
                +l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" />
                +    <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" 
                +d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640
                +q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5
                +t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5
                +t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5
                +t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191
                +t191 -286t71 -348z" />
                +    <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" 
                +d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962
                +q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" />
                +    <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" 
                +d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5
                +q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5
                +q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" />
                +    <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" 
                +d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339
                +q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z
                +" />
                +    <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" 
                +d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606
                +q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z
                +M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" />
                +    <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" 
                +d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23
                +v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" 
                +d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34
                +h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100
                +q-68 175 -180 287z" />
                +    <glyph glyph-name="_584" unicode="&#xf26e;" 
                +d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6
                +q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13
                +q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249
                +q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183
                +q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46
                +t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" />
                +    <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" 
                +d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z
                +M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30
                +q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57
                +t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133
                +q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" />
                +    <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" 
                +d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9
                +h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224
                +v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" />
                +    <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" 
                +d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23
                +t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47
                +t47 -113v-96h128q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" 
                +d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z
                +M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
                +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" 
                +d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23
                +t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47
                +t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
                +    <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" 
                +d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" />
                +    <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" 
                +d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249
                +q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" />
                +    <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" 
                +d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768
                +q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" />
                +    <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" 
                +d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173
                +v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" />
                +    <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" 
                +d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472
                +q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" />
                +    <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" 
                +d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5
                +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37
                +t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
                +    <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" 
                +d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5
                +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5
                +t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51
                +t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" />
                +    <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" 
                +d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" />
                +    <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" 
                +d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246
                +q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" />
                +    <glyph glyph-name="f27e" unicode="&#xf27e;" 
                +d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" />
                +    <glyph glyph-name="uniF280" unicode="&#xf280;" 
                +d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72
                +h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275
                +l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" />
                +    <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" 
                +d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5
                +l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44
                +t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106
                +q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" />
                +    <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" 
                +d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53
                +q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" />
                +    <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" 
                +d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" />
                +    <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" 
                +d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308
                +t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20
                +t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" />
                +    <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" 
                +d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" />
                +    <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" 
                +d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96
                +q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5
                +q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96
                +q16 0 16 -16z" />
                +    <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" 
                +d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96
                +q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5
                +t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" />
                +    <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" 
                +d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348
                +t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" 
                +d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22
                +q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5
                +q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13
                +q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" />
                +    <glyph glyph-name="_610" unicode="&#xf28a;" 
                +d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83
                +t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20
                +q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5
                +t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" />
                +    <glyph glyph-name="_611" unicode="&#xf28b;" 
                +d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103
                +t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_612" unicode="&#xf28c;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
                +t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" />
                +    <glyph glyph-name="_613" unicode="&#xf28d;" 
                +d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
                +t103 -385.5z" />
                +    <glyph glyph-name="_614" unicode="&#xf28e;" 
                +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
                +t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" />
                +    <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" 
                +d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5
                +t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
                +    <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" 
                +d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5
                +t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416
                +q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441
                +h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" />
                +    <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" 
                +d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12
                +q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311
                +q15 0 25 -12q9 -12 6 -28z" />
                +    <glyph glyph-name="_618" unicode="&#xf293;" 
                +d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5
                +t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" />
                +    <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" 
                +d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
                +    <glyph glyph-name="_620" unicode="&#xf295;" 
                +d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5
                +t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
                +t271.5 -112.5t112.5 -271.5z" />
                +    <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" 
                +d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" />
                +    <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" 
                +d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111
                +q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" />
                +    <glyph glyph-name="_623" unicode="&#xf298;" 
                +d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14
                +t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" />
                +    <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" 
                +d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57
                +q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285
                +q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" />
                +    <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" 
                +d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42
                +q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
                +M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298
                +t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="_626" unicode="&#xf29b;" 
                +d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300
                +l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z
                +M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" />
                +    <glyph glyph-name="_627" unicode="&#xf29c;" 
                +d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5
                +t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5
                +t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5
                +t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" 
                +d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457
                +q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521
                +q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661
                +q3 -1 7 1t7 4l3 2q11 9 11 17z" />
                +    <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" 
                +d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10
                +t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5
                +t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5
                +h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96
                +t9.5 -70.5z" />
                +    <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" 
                +d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5
                +q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127
                +l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272
                +t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249
                +q-18 -19 -45 -19z" />
                +    <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" 
                +d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352
                +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864
                +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136
                +t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56
                +t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56
                +t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136
                +t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" />
                +    <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" 
                +d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z
                +M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72
                +t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45
                +t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4
                +q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" />
                +    <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" 
                +d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55
                +q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5
                +q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101
                +q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35
                +q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5
                +q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" />
                +    <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" 
                +d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19
                +t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74
                +t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233
                +l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" />
                +    <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" 
                +d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2
                +q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10
                +q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5
                +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" 
                +d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5
                +l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5
                +q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9
                +q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" />
                +    <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" 
                +d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37
                +t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38
                +l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148
                +q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26
                +l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" />
                +    <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" 
                +d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5
                +q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841
                +q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5
                +q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" />
                +    <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" 
                +d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5
                +q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z
                +M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" />
                +    <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" 
                +d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z
                +M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5
                +q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
                +t84.5 -203.5z" />
                +    <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" 
                +d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114
                +q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5
                +t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
                +t103 -385.5z" />
                +    <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" 
                +d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35
                +q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5
                +t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" />
                +    <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" 
                +d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115
                +q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15
                +t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960
                +q119 0 203.5 -84.5t84.5 -203.5z" />
                +    <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" 
                +d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7
                +q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158
                +q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" />
                +    <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" 
                +d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104
                +q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108
                +l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z
                +M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
                +    <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" 
                +d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5
                +t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" />
                +    <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" 
                +d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5
                +t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114
                +q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50
                +q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5
                +t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46
                +q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5
                +q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177
                +t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" />
                +    <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" 
                +d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110
                +h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
                +    <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" 
                +d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5
                +q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" 
                +d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66
                +l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180
                +q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z
                +M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421
                +q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" />
                +    <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" 
                +d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107
                +t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39
                +q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" />
                +    <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" 
                +d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5
                +l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5
                +h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94
                +q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" />
                +    <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" 
                +d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465
                +l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161
                +q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74
                +q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" />
                +    <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" 
                +d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576
                +q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216
                +q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" />
                +    <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" 
                +d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5
                +t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96
                +q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216
                +q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" />
                +    <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" 
                +d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z
                +M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568
                +q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9
                +h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" 
                +d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925
                +q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568
                +q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5
                +t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113
                +t113 47h1728q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" 
                +d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5
                +t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" 
                +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61
                +t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" />
                +    <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" 
                +d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5
                +t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145
                +q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" />
                +    <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" 
                +d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5
                +t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352
                +q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" 
                +d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56
                +t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23
                +v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728
                +q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" 
                +d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z
                +M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64
                +q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47
                +h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" 
                +d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117
                +q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5
                +t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" />
                +    <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" 
                +d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21
                +t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46
                +t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54
                +t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29
                +q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5
                +t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314
                +q2 -42 2 -64z" />
                +    <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" 
                +d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
                +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" 
                +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
                +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
                +v128h192z" />
                +    <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" 
                +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
                +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
                +v128h192z" />
                +    <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" 
                +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
                +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
                +v128h192z" />
                +    <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" 
                +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
                +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
                +v128h192z" />
                +    <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" 
                +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z
                +M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" />
                +    <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" 
                +d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41
                +t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19
                +t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768
                +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19
                +t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384
                +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" />
                +    <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" 
                +d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9
                +t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9
                +t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42
                +q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9
                +t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23
                +t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" />
                +    <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" 
                +d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5
                +t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70
                +q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20
                +q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5
                +t72.5 -263.5z" />
                +    <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" 
                +d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" 
                +d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" 
                +d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47
                +t47 -113z" />
                +    <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" 
                +d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10
                +l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" 
                +d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
                +l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" 
                +d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" 
                +d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12
                +t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5
                +t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5
                +q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5
                +q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34
                +q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5
                +t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" 
                +d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89
                +q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5
                +t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" />
                +    <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" 
                +d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7
                +t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5
                +h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113
                +v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" />
                +    <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" 
                +d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584
                +q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5
                +q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15
                +q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82
                +q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104
                +t302 11t306.5 -97q220 -115 333 -336t87 -474z" />
                +    <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" 
                +d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178
                +q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199
                +t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297
                +t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208
                +t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" />
                +    <glyph glyph-name="uniF2DB" unicode="&#xf2db;" 
                +d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16
                +q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28
                +t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32
                +q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16
                +h48q16 0 16 -16z" />
                +    <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" 
                +d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45
                +t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33
                +q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313
                +l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106
                +q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" />
                +    <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" 
                +d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321
                +q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" />
                +    <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" 
                +d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62
                +t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71
                +t286 -191t191 -286t71 -348z" />
                +    <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" 
                +d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3
                +t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53
                +q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5
                +q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5
                +t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5
                +q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z
                +M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21
                +q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16
                +q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" />
                +    <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" 
                + />
                +    <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" 
                + />
                +  </font>
                +</defs></svg>
                diff --git a/blockly/webif/static/fonts/fontawesome-webfont.ttf b/blockly/webif/static/fonts/fontawesome-webfont.ttf
                new file mode 100644
                index 000000000..35acda2fa
                Binary files /dev/null and b/blockly/webif/static/fonts/fontawesome-webfont.ttf differ
                diff --git a/blockly/webif/static/fonts/fontawesome-webfont.woff b/blockly/webif/static/fonts/fontawesome-webfont.woff
                new file mode 100644
                index 000000000..400014a4b
                Binary files /dev/null and b/blockly/webif/static/fonts/fontawesome-webfont.woff differ
                diff --git a/blockly/webif/static/fonts/fontawesome-webfont.woff2 b/blockly/webif/static/fonts/fontawesome-webfont.woff2
                new file mode 100644
                index 000000000..4d13fc604
                Binary files /dev/null and b/blockly/webif/static/fonts/fontawesome-webfont.woff2 differ
                diff --git a/blockly/webif/static/fonts/glyphicons-halflings-regular.eot b/blockly/webif/static/fonts/glyphicons-halflings-regular.eot
                new file mode 100644
                index 000000000..b93a4953f
                Binary files /dev/null and b/blockly/webif/static/fonts/glyphicons-halflings-regular.eot differ
                diff --git a/blockly/webif/static/fonts/glyphicons-halflings-regular.svg b/blockly/webif/static/fonts/glyphicons-halflings-regular.svg
                new file mode 100644
                index 000000000..94fb5490a
                --- /dev/null
                +++ b/blockly/webif/static/fonts/glyphicons-halflings-regular.svg
                @@ -0,0 +1,288 @@
                +<?xml version="1.0" standalone="no"?>
                +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
                +<svg xmlns="http://www.w3.org/2000/svg">
                +<metadata></metadata>
                +<defs>
                +<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
                +<font-face units-per-em="1200" ascent="960" descent="-240" />
                +<missing-glyph horiz-adv-x="500" />
                +<glyph horiz-adv-x="0" />
                +<glyph horiz-adv-x="400" />
                +<glyph unicode=" " />
                +<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
                +<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xa0;" />
                +<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
                +<glyph unicode="&#x2000;" horiz-adv-x="650" />
                +<glyph unicode="&#x2001;" horiz-adv-x="1300" />
                +<glyph unicode="&#x2002;" horiz-adv-x="650" />
                +<glyph unicode="&#x2003;" horiz-adv-x="1300" />
                +<glyph unicode="&#x2004;" horiz-adv-x="433" />
                +<glyph unicode="&#x2005;" horiz-adv-x="325" />
                +<glyph unicode="&#x2006;" horiz-adv-x="216" />
                +<glyph unicode="&#x2007;" horiz-adv-x="216" />
                +<glyph unicode="&#x2008;" horiz-adv-x="162" />
                +<glyph unicode="&#x2009;" horiz-adv-x="260" />
                +<glyph unicode="&#x200a;" horiz-adv-x="72" />
                +<glyph unicode="&#x202f;" horiz-adv-x="260" />
                +<glyph unicode="&#x205f;" horiz-adv-x="325" />
                +<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
                +<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
                +<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
                +<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
                +<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
                +<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
                +<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
                +<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
                +<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
                +<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
                +<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
                +<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
                +<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
                +<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
                +<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
                +<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
                +<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
                +<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
                +<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
                +<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
                +<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
                +<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
                +<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
                +<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
                +<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
                +<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
                +<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
                +<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
                +<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
                +<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
                +<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
                +<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
                +<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
                +<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
                +<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
                +<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
                +<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
                +<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
                +<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
                +<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
                +<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
                +<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
                +<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
                +<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
                +<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
                +<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
                +<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
                +<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
                +<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
                +<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
                +<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
                +<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
                +<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
                +<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
                +<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
                +<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
                +<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
                +<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
                +<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
                +<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
                +<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
                +<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
                +<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
                +<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
                +<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
                +<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
                +<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
                +<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
                +<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
                +<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
                +<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
                +<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
                +<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
                +<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
                +<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
                +<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
                +<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
                +<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
                +<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
                +<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
                +<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
                +<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
                +<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
                +<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
                +<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
                +<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
                +<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
                +<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
                +<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
                +<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
                +<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
                +<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
                +<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
                +<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
                +<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
                +<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
                +<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
                +<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
                +<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
                +<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
                +<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
                +<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
                +<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
                +<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
                +<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
                +<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
                +<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
                +<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
                +<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
                +<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
                +<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
                +<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
                +<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
                +<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
                +<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
                +<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
                +<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
                +<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
                +<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
                +<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
                +<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
                +<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
                +<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
                +<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
                +<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
                +<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
                +<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
                +<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
                +<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
                +<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
                +<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
                +<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
                +<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
                +<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
                +<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
                +<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
                +<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
                +<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
                +<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
                +<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
                +<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
                +<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
                +<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
                +<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
                +<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
                +<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
                +<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
                +<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
                +<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
                +<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
                +<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
                +<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
                +<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
                +<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
                +<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
                +<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
                +<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
                +<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
                +<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
                +<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
                +<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
                +<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
                +<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
                +<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
                +<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
                +<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
                +<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
                +<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
                +<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
                +<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
                +<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
                +<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
                +<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
                +<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
                +<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
                +<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
                +<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
                +<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
                +<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
                +<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
                +<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
                +<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
                +<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
                +<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
                +<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
                +<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
                +<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
                +<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
                +<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
                +<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
                +<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
                +<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
                +<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
                +<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
                +<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
                +<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
                +<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
                +<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
                +<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
                +<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
                +<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
                +<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
                +<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
                +<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
                +<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
                +<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
                +<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
                +<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
                +<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
                +<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
                +<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
                +<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
                +<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
                +<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
                +<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
                +<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
                +<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
                +<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
                +<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
                +</font>
                +</defs></svg> 
                \ No newline at end of file
                diff --git a/blockly/webif/static/fonts/glyphicons-halflings-regular.ttf b/blockly/webif/static/fonts/glyphicons-halflings-regular.ttf
                new file mode 100644
                index 000000000..1413fc609
                Binary files /dev/null and b/blockly/webif/static/fonts/glyphicons-halflings-regular.ttf differ
                diff --git a/blockly/webif/static/fonts/glyphicons-halflings-regular.woff b/blockly/webif/static/fonts/glyphicons-halflings-regular.woff
                new file mode 100644
                index 000000000..9e612858f
                Binary files /dev/null and b/blockly/webif/static/fonts/glyphicons-halflings-regular.woff differ
                diff --git a/blockly/webif/static/fonts/glyphicons-halflings-regular.woff2 b/blockly/webif/static/fonts/glyphicons-halflings-regular.woff2
                new file mode 100644
                index 000000000..64539b54c
                Binary files /dev/null and b/blockly/webif/static/fonts/glyphicons-halflings-regular.woff2 differ
                diff --git a/blockly/webif/static/img/favicon.ico b/blockly/webif/static/img/favicon.ico
                new file mode 100644
                index 000000000..8a22cecf1
                Binary files /dev/null and b/blockly/webif/static/img/favicon.ico differ
                diff --git a/blockly/webif/static/img/logo_big.png b/blockly/webif/static/img/logo_big.png
                new file mode 100644
                index 000000000..93865a18e
                Binary files /dev/null and b/blockly/webif/static/img/logo_big.png differ
                diff --git a/blockly/webif/static/img/logo_long.png b/blockly/webif/static/img/logo_long.png
                new file mode 100644
                index 000000000..07c44b49a
                Binary files /dev/null and b/blockly/webif/static/img/logo_long.png differ
                diff --git a/blockly/webif/static/img/logo_small_120x120.png b/blockly/webif/static/img/logo_small_120x120.png
                new file mode 100644
                index 000000000..e9e28e3d6
                Binary files /dev/null and b/blockly/webif/static/img/logo_small_120x120.png differ
                diff --git a/blockly/webif/static/img/logo_small_152x152.png b/blockly/webif/static/img/logo_small_152x152.png
                new file mode 100644
                index 000000000..30111c6fc
                Binary files /dev/null and b/blockly/webif/static/img/logo_small_152x152.png differ
                diff --git a/blockly/webif/static/img/logo_small_32x32.png b/blockly/webif/static/img/logo_small_32x32.png
                new file mode 100644
                index 000000000..7c1fde81d
                Binary files /dev/null and b/blockly/webif/static/img/logo_small_32x32.png differ
                diff --git a/blockly/webif/static/img/logo_small_76x76.png b/blockly/webif/static/img/logo_small_76x76.png
                new file mode 100644
                index 000000000..c3034528b
                Binary files /dev/null and b/blockly/webif/static/img/logo_small_76x76.png differ
                diff --git a/blockly/webif/static/js/backend.js b/blockly/webif/static/js/backend.js
                new file mode 100644
                index 000000000..e69de29bb
                diff --git a/blockly/webif/static/js/bootstrap-reload.js b/blockly/webif/static/js/bootstrap-reload.js
                new file mode 100644
                index 000000000..ac42b6f3c
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap-reload.js
                @@ -0,0 +1,68 @@
                +(function( $, window, document, undefined ) {
                +	var Reload = function(elem, options) {
                +		this.$elem = $(elem);
                +		this.options = options;
                +	};
                +
                +	Reload.prototype.defaults = {
                +		time: 3000,
                +		autoReload: false,
                +		//beforeReload: function(){},
                +		//afterReload: function(){},
                +		parameterString: '',
                +		parseData: function(){}
                +	};
                +
                +	Reload.prototype.init = function() {
                +		var self = this;
                +
                +		// Set the configuration parameters
                +		self.config = $.extend({},self.defaults,self.options);
                +
                +		// Set the container for refresh animation
                +		self.config.refreshContainer = $(self.config.refreshContainer) || self.$elem.find('.refresh-container');
                +
                +		// Set the container to update the data with
                +		self.config.dataContainer = $(self.config.dataContainer) || self.$elem.find('.data-container');
                +
                +		self.$elem.find('.fa-refresh').click(self.reload());
                +		self.$elem.find('.fa-refresh').off('click');
                +		self.$elem.find('.fa-refresh').on('click', function() {
                +            self.reload()
                +        });
                +
                +		if(self.config.autoReload) {
                +			setInterval(self.reload,self.config.time);
                +			_self.$elem.find('.fa-refresh').addClass('fa-spin');
                +		}
                +
                +		return self;
                +	};
                +
                +	Reload.prototype.reload = function(){
                +		var _self = this;
                +        _self.$elem.find('.fa-refresh').addClass('fa-spin');
                +		_self.config.refreshContainer.fadeIn('fast');
                +  		// Send the AJAX request to fetch the data
                +  		$.getJSON(_self.$elem.data('url')+_self.config.parameterString, function(result) {
                +		    _self.config.parseData(result);
                +		    if(_self.config.autoReload) {
                +		        _self.config.refreshContainer.fadeOut("done", function() {});
                +		    } else {
                +                _self.config.refreshContainer.fadeOut("done", function() {_self.$elem.find('.fa-refresh').removeClass('fa-spin');});
                +		    }
                +		});
                +	};
                +
                +	// Register the plugin to JQuery
                +	$.fn.reload = function(options) {
                +		this.each(function() {
                +			var $this, reload;
                +			$this = $(this);
                +			reload = new Reload(this, options);
                +			return reload.init();
                +
                +		});
                +	};
                +
                +})( window.jQuery, window, document );
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/bootstrap-reload.min.js b/blockly/webif/static/js/bootstrap-reload.min.js
                new file mode 100644
                index 000000000..dab077a3c
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap-reload.min.js
                @@ -0,0 +1 @@
                +!function(e,n,i,a){var t=function(n,i){this.$elem=e(n),this.options=i};t.prototype.defaults={time:3e3,autoReload:!1,parameterString:"",parseData:function(){}},t.prototype.init=function(){var n=this;return n.config=e.extend({},n.defaults,n.options),n.config.refreshContainer=e(n.config.refreshContainer)||n.$elem.find(".refresh-container"),n.config.dataContainer=e(n.config.dataContainer)||n.$elem.find(".data-container"),n.$elem.find(".fa-refresh").click(n.reload()),n.$elem.find(".fa-refresh").off("click"),n.$elem.find(".fa-refresh").on("click",function(){n.reload()}),n.config.autoReload&&(setInterval(n.reload,n.config.time),_self.$elem.find(".fa-refresh").addClass("fa-spin")),n},t.prototype.reload=function(){var n=this;n.$elem.find(".fa-refresh").addClass("fa-spin"),n.config.refreshContainer.fadeIn("fast"),e.getJSON(n.$elem.data("url")+n.config.parameterString,function(e){n.config.parseData(e),n.config.autoReload?n.config.refreshContainer.fadeOut("done",function(){}):n.config.refreshContainer.fadeOut("done",function(){n.$elem.find(".fa-refresh").removeClass("fa-spin")})})},e.fn.reload=function(n){this.each(function(){var i,a;return i=e(this),a=new t(this,n),a.init()})}}(window.jQuery,window,document);
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/bootstrap-treeview.js b/blockly/webif/static/js/bootstrap-treeview.js
                new file mode 100644
                index 000000000..7a82a2eeb
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap-treeview.js
                @@ -0,0 +1,1249 @@
                +/* =========================================================
                + * bootstrap-treeview.js v1.2.0
                + * =========================================================
                + * Copyright 2013 Jonathan Miles
                + * Project URL : http://www.jondmiles.com/bootstrap-treeview
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + * http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + * ========================================================= */
                +
                +;(function ($, window, document, undefined) {
                +
                +	/*global jQuery, console*/
                +
                +	'use strict';
                +
                +	var pluginName = 'treeview';
                +
                +	var _default = {};
                +
                +	_default.settings = {
                +
                +		injectStyle: true,
                +
                +		levels: 2,
                +
                +		expandIcon: 'glyphicon glyphicon-plus',
                +		collapseIcon: 'glyphicon glyphicon-minus',
                +		emptyIcon: 'glyphicon',
                +		nodeIcon: '',
                +		selectedIcon: '',
                +		checkedIcon: 'glyphicon glyphicon-check',
                +		uncheckedIcon: 'glyphicon glyphicon-unchecked',
                +
                +		color: undefined, // '#000000',
                +		backColor: undefined, // '#FFFFFF',
                +		borderColor: undefined, // '#dddddd',
                +		onhoverColor: '#F5F5F5',
                +		selectedColor: '#FFFFFF',
                +		selectedBackColor: '#428bca',
                +		searchResultColor: '#D9534F',
                +		searchResultBackColor: undefined, //'#FFFFFF',
                +
                +		enableLinks: false,
                +		highlightSelected: true,
                +		highlightSearchResults: true,
                +		showBorder: true,
                +		showIcon: true,
                +		showCheckbox: false,
                +		showTags: false,
                +		multiSelect: false,
                +
                +		// Event handlers
                +		onNodeChecked: undefined,
                +		onNodeCollapsed: undefined,
                +		onNodeDisabled: undefined,
                +		onNodeEnabled: undefined,
                +		onNodeExpanded: undefined,
                +		onNodeSelected: undefined,
                +		onNodeUnchecked: undefined,
                +		onNodeUnselected: undefined,
                +		onSearchComplete: undefined,
                +		onSearchCleared: undefined
                +	};
                +
                +	_default.options = {
                +		silent: false,
                +		ignoreChildren: false
                +	};
                +
                +	_default.searchOptions = {
                +		ignoreCase: true,
                +		exactMatch: false,
                +		revealResults: true
                +	};
                +
                +	var Tree = function (element, options) {
                +
                +		this.$element = $(element);
                +		this.elementId = element.id;
                +		this.styleId = this.elementId + '-style';
                +
                +		this.init(options);
                +
                +		return {
                +
                +			// Options (public access)
                +			options: this.options,
                +
                +			// Initialize / destroy methods
                +			init: $.proxy(this.init, this),
                +			remove: $.proxy(this.remove, this),
                +
                +			// Get methods
                +			getNode: $.proxy(this.getNode, this),
                +			getParent: $.proxy(this.getParent, this),
                +			getSiblings: $.proxy(this.getSiblings, this),
                +			getSelected: $.proxy(this.getSelected, this),
                +			getUnselected: $.proxy(this.getUnselected, this),
                +			getExpanded: $.proxy(this.getExpanded, this),
                +			getCollapsed: $.proxy(this.getCollapsed, this),
                +			getChecked: $.proxy(this.getChecked, this),
                +			getUnchecked: $.proxy(this.getUnchecked, this),
                +			getDisabled: $.proxy(this.getDisabled, this),
                +			getEnabled: $.proxy(this.getEnabled, this),
                +
                +			// Select methods
                +			selectNode: $.proxy(this.selectNode, this),
                +			unselectNode: $.proxy(this.unselectNode, this),
                +			toggleNodeSelected: $.proxy(this.toggleNodeSelected, this),
                +
                +			// Expand / collapse methods
                +			collapseAll: $.proxy(this.collapseAll, this),
                +			collapseNode: $.proxy(this.collapseNode, this),
                +			expandAll: $.proxy(this.expandAll, this),
                +			expandNode: $.proxy(this.expandNode, this),
                +			toggleNodeExpanded: $.proxy(this.toggleNodeExpanded, this),
                +			revealNode: $.proxy(this.revealNode, this),
                +
                +			// Expand / collapse methods
                +			checkAll: $.proxy(this.checkAll, this),
                +			checkNode: $.proxy(this.checkNode, this),
                +			uncheckAll: $.proxy(this.uncheckAll, this),
                +			uncheckNode: $.proxy(this.uncheckNode, this),
                +			toggleNodeChecked: $.proxy(this.toggleNodeChecked, this),
                +
                +			// Disable / enable methods
                +			disableAll: $.proxy(this.disableAll, this),
                +			disableNode: $.proxy(this.disableNode, this),
                +			enableAll: $.proxy(this.enableAll, this),
                +			enableNode: $.proxy(this.enableNode, this),
                +			toggleNodeDisabled: $.proxy(this.toggleNodeDisabled, this),
                +
                +			// Search methods
                +			search: $.proxy(this.search, this),
                +			clearSearch: $.proxy(this.clearSearch, this)
                +		};
                +	};
                +
                +	Tree.prototype.init = function (options) {
                +
                +		this.tree = [];
                +		this.nodes = [];
                +
                +		if (options.data) {
                +			if (typeof options.data === 'string') {
                +				options.data = $.parseJSON(options.data);
                +			}
                +			this.tree = $.extend(true, [], options.data);
                +			delete options.data;
                +		}
                +		this.options = $.extend({}, _default.settings, options);
                +
                +		this.destroy();
                +		this.subscribeEvents();
                +		this.setInitialStates({ nodes: this.tree }, 0);
                +		this.render();
                +	};
                +
                +	Tree.prototype.remove = function () {
                +		this.destroy();
                +		$.removeData(this, pluginName);
                +		$('#' + this.styleId).remove();
                +	};
                +
                +	Tree.prototype.destroy = function () {
                +
                +		if (!this.initialized) return;
                +
                +		this.$wrapper.remove();
                +		this.$wrapper = null;
                +
                +		// Switch off events
                +		this.unsubscribeEvents();
                +
                +		// Reset this.initialized flag
                +		this.initialized = false;
                +	};
                +
                +	Tree.prototype.unsubscribeEvents = function () {
                +
                +		this.$element.off('click');
                +		this.$element.off('nodeChecked');
                +		this.$element.off('nodeCollapsed');
                +		this.$element.off('nodeDisabled');
                +		this.$element.off('nodeEnabled');
                +		this.$element.off('nodeExpanded');
                +		this.$element.off('nodeSelected');
                +		this.$element.off('nodeUnchecked');
                +		this.$element.off('nodeUnselected');
                +		this.$element.off('searchComplete');
                +		this.$element.off('searchCleared');
                +	};
                +
                +	Tree.prototype.subscribeEvents = function () {
                +
                +		this.unsubscribeEvents();
                +
                +		this.$element.on('click', $.proxy(this.clickHandler, this));
                +
                +		if (typeof (this.options.onNodeChecked) === 'function') {
                +			this.$element.on('nodeChecked', this.options.onNodeChecked);
                +		}
                +
                +		if (typeof (this.options.onNodeCollapsed) === 'function') {
                +			this.$element.on('nodeCollapsed', this.options.onNodeCollapsed);
                +		}
                +
                +		if (typeof (this.options.onNodeDisabled) === 'function') {
                +			this.$element.on('nodeDisabled', this.options.onNodeDisabled);
                +		}
                +
                +		if (typeof (this.options.onNodeEnabled) === 'function') {
                +			this.$element.on('nodeEnabled', this.options.onNodeEnabled);
                +		}
                +
                +		if (typeof (this.options.onNodeExpanded) === 'function') {
                +			this.$element.on('nodeExpanded', this.options.onNodeExpanded);
                +		}
                +
                +		if (typeof (this.options.onNodeSelected) === 'function') {
                +			this.$element.on('nodeSelected', this.options.onNodeSelected);
                +		}
                +
                +		if (typeof (this.options.onNodeUnchecked) === 'function') {
                +			this.$element.on('nodeUnchecked', this.options.onNodeUnchecked);
                +		}
                +
                +		if (typeof (this.options.onNodeUnselected) === 'function') {
                +			this.$element.on('nodeUnselected', this.options.onNodeUnselected);
                +		}
                +
                +		if (typeof (this.options.onSearchComplete) === 'function') {
                +			this.$element.on('searchComplete', this.options.onSearchComplete);
                +		}
                +
                +		if (typeof (this.options.onSearchCleared) === 'function') {
                +			this.$element.on('searchCleared', this.options.onSearchCleared);
                +		}
                +	};
                +
                +	/*
                +		Recurse the tree structure and ensure all nodes have
                +		valid initial states.  User defined states will be preserved.
                +		For performance we also take this opportunity to
                +		index nodes in a flattened structure
                +	*/
                +	Tree.prototype.setInitialStates = function (node, level) {
                +
                +		if (!node.nodes) return;
                +		level += 1;
                +
                +		var parent = node;
                +		var _this = this;
                +		$.each(node.nodes, function checkStates(index, node) {
                +
                +			// nodeId : unique, incremental identifier
                +			node.nodeId = _this.nodes.length;
                +
                +			// parentId : transversing up the tree
                +			node.parentId = parent.nodeId;
                +
                +			// if not provided set selectable default value
                +			if (!node.hasOwnProperty('selectable')) {
                +				node.selectable = true;
                +			}
                +
                +			// where provided we should preserve states
                +			node.state = node.state || {};
                +
                +			// set checked state; unless set always false
                +			if (!node.state.hasOwnProperty('checked')) {
                +				node.state.checked = false;
                +			}
                +
                +			// set enabled state; unless set always false
                +			if (!node.state.hasOwnProperty('disabled')) {
                +				node.state.disabled = false;
                +			}
                +
                +			// set expanded state; if not provided based on levels
                +			if (!node.state.hasOwnProperty('expanded')) {
                +				if (!node.state.disabled &&
                +						(level < _this.options.levels) &&
                +						(node.nodes && node.nodes.length > 0)) {
                +					node.state.expanded = true;
                +				}
                +				else {
                +					node.state.expanded = false;
                +				}
                +			}
                +
                +			// set selected state; unless set always false
                +			if (!node.state.hasOwnProperty('selected')) {
                +				node.state.selected = false;
                +			}
                +
                +			// index nodes in a flattened structure for use later
                +			_this.nodes.push(node);
                +
                +			// recurse child nodes and transverse the tree
                +			if (node.nodes) {
                +				_this.setInitialStates(node, level);
                +			}
                +		});
                +	};
                +
                +	Tree.prototype.clickHandler = function (event) {
                +
                +		if (!this.options.enableLinks) event.preventDefault();
                +
                +		var target = $(event.target);
                +		var node = this.findNode(target);
                +		if (!node || node.state.disabled) return;
                +		
                +		var classList = target.attr('class') ? target.attr('class').split(' ') : [];
                +		if ((classList.indexOf('expand-icon') !== -1)) {
                +
                +			this.toggleExpandedState(node, _default.options);
                +			this.render();
                +		}
                +		else if ((classList.indexOf('check-icon') !== -1)) {
                +			
                +			this.toggleCheckedState(node, _default.options);
                +			this.render();
                +		}
                +		else {
                +			
                +			if (node.selectable) {
                +				this.toggleSelectedState(node, _default.options);
                +			} else {
                +				this.toggleExpandedState(node, _default.options);
                +			}
                +
                +			this.render();
                +		}
                +	};
                +
                +	// Looks up the DOM for the closest parent list item to retrieve the
                +	// data attribute nodeid, which is used to lookup the node in the flattened structure.
                +	Tree.prototype.findNode = function (target) {
                +
                +		var nodeId = target.closest('li.list-group-item').attr('data-nodeid');
                +		var node = this.nodes[nodeId];
                +
                +		if (!node) {
                +			console.log('Error: node does not exist');
                +		}
                +		return node;
                +	};
                +
                +	Tree.prototype.toggleExpandedState = function (node, options) {
                +		if (!node) return;
                +		this.setExpandedState(node, !node.state.expanded, options);
                +	};
                +
                +	Tree.prototype.setExpandedState = function (node, state, options) {
                +
                +		if (state === node.state.expanded) return;
                +
                +		if (state && node.nodes) {
                +
                +			// Expand a node
                +			node.state.expanded = true;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeExpanded', $.extend(true, {}, node));
                +			}
                +		}
                +		else if (!state) {
                +
                +			// Collapse a node
                +			node.state.expanded = false;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeCollapsed', $.extend(true, {}, node));
                +			}
                +
                +			// Collapse child nodes
                +			if (node.nodes && !options.ignoreChildren) {
                +				$.each(node.nodes, $.proxy(function (index, node) {
                +					this.setExpandedState(node, false, options);
                +				}, this));
                +			}
                +		}
                +	};
                +
                +	Tree.prototype.toggleSelectedState = function (node, options) {
                +		if (!node) return;
                +		this.setSelectedState(node, !node.state.selected, options);
                +	};
                +
                +	Tree.prototype.setSelectedState = function (node, state, options) {
                +
                +		if (state === node.state.selected) return;
                +
                +		if (state) {
                +
                +			// If multiSelect false, unselect previously selected
                +			if (!this.options.multiSelect) {
                +				$.each(this.findNodes('true', 'g', 'state.selected'), $.proxy(function (index, node) {
                +					this.setSelectedState(node, false, options);
                +				}, this));
                +			}
                +
                +			// Continue selecting node
                +			node.state.selected = true;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeSelected', $.extend(true, {}, node));
                +			}
                +		}
                +		else {
                +
                +			// Unselect node
                +			node.state.selected = false;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeUnselected', $.extend(true, {}, node));
                +			}
                +		}
                +	};
                +
                +	Tree.prototype.toggleCheckedState = function (node, options) {
                +		if (!node) return;
                +		this.setCheckedState(node, !node.state.checked, options);
                +	};
                +
                +	Tree.prototype.setCheckedState = function (node, state, options) {
                +
                +		if (state === node.state.checked) return;
                +
                +		if (state) {
                +
                +			// Check node
                +			node.state.checked = true;
                +
                +			if (!options.silent) {
                +				this.$element.trigger('nodeChecked', $.extend(true, {}, node));
                +			}
                +		}
                +		else {
                +
                +			// Uncheck node
                +			node.state.checked = false;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeUnchecked', $.extend(true, {}, node));
                +			}
                +		}
                +	};
                +
                +	Tree.prototype.setDisabledState = function (node, state, options) {
                +
                +		if (state === node.state.disabled) return;
                +
                +		if (state) {
                +
                +			// Disable node
                +			node.state.disabled = true;
                +
                +			// Disable all other states
                +			this.setExpandedState(node, false, options);
                +			this.setSelectedState(node, false, options);
                +			this.setCheckedState(node, false, options);
                +
                +			if (!options.silent) {
                +				this.$element.trigger('nodeDisabled', $.extend(true, {}, node));
                +			}
                +		}
                +		else {
                +
                +			// Enabled node
                +			node.state.disabled = false;
                +			if (!options.silent) {
                +				this.$element.trigger('nodeEnabled', $.extend(true, {}, node));
                +			}
                +		}
                +	};
                +
                +	Tree.prototype.render = function () {
                +
                +		if (!this.initialized) {
                +
                +			// Setup first time only components
                +			this.$element.addClass(pluginName);
                +			this.$wrapper = $(this.template.list);
                +
                +			this.injectStyle();
                +
                +			this.initialized = true;
                +		}
                +
                +		this.$element.empty().append(this.$wrapper.empty());
                +
                +		// Build tree
                +		this.buildTree(this.tree, 0);
                +	};
                +
                +	// Starting from the root node, and recursing down the
                +	// structure we build the tree one node at a time
                +	Tree.prototype.buildTree = function (nodes, level) {
                +
                +		if (!nodes) return;
                +		level += 1;
                +
                +		var _this = this;
                +		$.each(nodes, function addNodes(id, node) {
                +
                +			var treeItem = $(_this.template.item)
                +				.addClass('node-' + _this.elementId)
                +				.addClass(node.state.checked ? 'node-checked' : '')
                +				.addClass(node.state.disabled ? 'node-disabled': '')
                +				.addClass(node.state.selected ? 'node-selected' : '')
                +				.addClass(node.searchResult ? 'search-result' : '') 
                +				.attr('data-nodeid', node.nodeId)
                +				.attr('style', _this.buildStyleOverride(node));
                +
                +			// Add indent/spacer to mimic tree structure
                +			for (var i = 0; i < (level - 1); i++) {
                +				treeItem.append(_this.template.indent);
                +			}
                +
                +			// Add expand, collapse or empty spacer icons
                +			var classList = [];
                +			if (node.nodes) {
                +				classList.push('expand-icon');
                +				if (node.state.expanded) {
                +					classList.push(_this.options.collapseIcon);
                +				}
                +				else {
                +					classList.push(_this.options.expandIcon);
                +				}
                +			}
                +			else {
                +				classList.push(_this.options.emptyIcon);
                +			}
                +
                +			treeItem
                +				.append($(_this.template.icon)
                +					.addClass(classList.join(' '))
                +				);
                +
                +
                +			// Add node icon
                +			if (_this.options.showIcon) {
                +				
                +				var classList = ['node-icon'];
                +
                +				classList.push(node.icon || _this.options.nodeIcon);
                +				if (node.state.selected) {
                +					classList.pop();
                +					classList.push(node.selectedIcon || _this.options.selectedIcon || 
                +									node.icon || _this.options.nodeIcon);
                +				}
                +
                +				treeItem
                +					.append($(_this.template.icon)
                +						.addClass(classList.join(' '))
                +					);
                +			}
                +
                +			// Add check / unchecked icon
                +			if (_this.options.showCheckbox) {
                +
                +				var classList = ['check-icon'];
                +				if (node.state.checked) {
                +					classList.push(_this.options.checkedIcon); 
                +				}
                +				else {
                +					classList.push(_this.options.uncheckedIcon);
                +				}
                +
                +				treeItem
                +					.append($(_this.template.icon)
                +						.addClass(classList.join(' '))
                +					);
                +			}
                +
                +			// Add text
                +			if (_this.options.enableLinks) {
                +				// Add hyperlink
                +				treeItem
                +					.append($(_this.template.link)
                +						.attr('href', node.href)
                +						.append(node.text)
                +					);
                +			}
                +			else {
                +				// otherwise just text
                +				treeItem
                +					.append(node.text);
                +			}
                +
                +			// Add tags as badges
                +			if (_this.options.showTags && node.tags) {
                +				$.each(node.tags, function addTag(id, tag) {
                +					treeItem
                +						.append($(_this.template.badge)
                +							.append(tag)
                +						);
                +				});
                +			}
                +
                +			// Add item to the tree
                +			_this.$wrapper.append(treeItem);
                +
                +			// Recursively add child ndoes
                +			if (node.nodes && node.state.expanded && !node.state.disabled) {
                +				return _this.buildTree(node.nodes, level);
                +			}
                +		});
                +	};
                +
                +	// Define any node level style override for
                +	// 1. selectedNode
                +	// 2. node|data assigned color overrides
                +	Tree.prototype.buildStyleOverride = function (node) {
                +
                +		if (node.state.disabled) return '';
                +
                +		var color = node.color;
                +		var backColor = node.backColor;
                +
                +		if (this.options.highlightSelected && node.state.selected) {
                +			if (this.options.selectedColor) {
                +				color = this.options.selectedColor;
                +			}
                +			if (this.options.selectedBackColor) {
                +				backColor = this.options.selectedBackColor;
                +			}
                +		}
                +
                +		if (this.options.highlightSearchResults && node.searchResult && !node.state.disabled) {
                +			if (this.options.searchResultColor) {
                +				color = this.options.searchResultColor;
                +			}
                +			if (this.options.searchResultBackColor) {
                +				backColor = this.options.searchResultBackColor;
                +			}
                +		}
                +
                +		return 'color:' + color +
                +			';background-color:' + backColor + ';';
                +	};
                +
                +	// Add inline style into head
                +	Tree.prototype.injectStyle = function () {
                +
                +		if (this.options.injectStyle && !document.getElementById(this.styleId)) {
                +			$('<style type="text/css" id="' + this.styleId + '"> ' + this.buildStyle() + ' </style>').appendTo('head');
                +		}
                +	};
                +
                +	// Construct trees style based on user options
                +	Tree.prototype.buildStyle = function () {
                +
                +		var style = '.node-' + this.elementId + '{';
                +
                +		if (this.options.color) {
                +			style += 'color:' + this.options.color + ';';
                +		}
                +
                +		if (this.options.backColor) {
                +			style += 'background-color:' + this.options.backColor + ';';
                +		}
                +
                +		if (!this.options.showBorder) {
                +			style += 'border:none;';
                +		}
                +		else if (this.options.borderColor) {
                +			style += 'border:1px solid ' + this.options.borderColor + ';';
                +		}
                +		style += '}';
                +
                +		if (this.options.onhoverColor) {
                +			style += '.node-' + this.elementId + ':not(.node-disabled):hover{' +
                +				'background-color:' + this.options.onhoverColor + ';' +
                +			'}';
                +		}
                +
                +		return this.css + style;
                +	};
                +
                +	Tree.prototype.template = {
                +		list: '<ul class="list-group"></ul>',
                +		item: '<li class="list-group-item"></li>',
                +		indent: '<span class="indent"></span>',
                +		icon: '<span class="icon"></span>',
                +		link: '<a href="#" style="color:inherit;"></a>',
                +		badge: '<span class="badge"></span>'
                +	};
                +
                +	Tree.prototype.css = '.treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}'
                +
                +
                +	/**
                +		Returns a single node object that matches the given node id.
                +		@param {Number} nodeId - A node's unique identifier
                +		@return {Object} node - Matching node
                +	*/
                +	Tree.prototype.getNode = function (nodeId) {
                +		return this.nodes[nodeId];
                +	};
                +
                +	/**
                +		Returns the parent node of a given node, if valid otherwise returns undefined.
                +		@param {Object|Number} identifier - A valid node or node id
                +		@returns {Object} node - The parent node
                +	*/
                +	Tree.prototype.getParent = function (identifier) {
                +		var node = this.identifyNode(identifier);
                +		return this.nodes[node.parentId];
                +	};
                +
                +	/**
                +		Returns an array of sibling nodes for a given node, if valid otherwise returns undefined.
                +		@param {Object|Number} identifier - A valid node or node id
                +		@returns {Array} nodes - Sibling nodes
                +	*/
                +	Tree.prototype.getSiblings = function (identifier) {
                +		var node = this.identifyNode(identifier);
                +		var parent = this.getParent(node);
                +		var nodes = parent ? parent.nodes : this.tree;
                +		return nodes.filter(function (obj) {
                +				return obj.nodeId !== node.nodeId;
                +			});
                +	};
                +
                +	/**
                +		Returns an array of selected nodes.
                +		@returns {Array} nodes - Selected nodes
                +	*/
                +	Tree.prototype.getSelected = function () {
                +		return this.findNodes('true', 'g', 'state.selected');
                +	};
                +
                +	/**
                +		Returns an array of unselected nodes.
                +		@returns {Array} nodes - Unselected nodes
                +	*/
                +	Tree.prototype.getUnselected = function () {
                +		return this.findNodes('false', 'g', 'state.selected');
                +	};
                +
                +	/**
                +		Returns an array of expanded nodes.
                +		@returns {Array} nodes - Expanded nodes
                +	*/
                +	Tree.prototype.getExpanded = function () {
                +		return this.findNodes('true', 'g', 'state.expanded');
                +	};
                +
                +	/**
                +		Returns an array of collapsed nodes.
                +		@returns {Array} nodes - Collapsed nodes
                +	*/
                +	Tree.prototype.getCollapsed = function () {
                +		return this.findNodes('false', 'g', 'state.expanded');
                +	};
                +
                +	/**
                +		Returns an array of checked nodes.
                +		@returns {Array} nodes - Checked nodes
                +	*/
                +	Tree.prototype.getChecked = function () {
                +		return this.findNodes('true', 'g', 'state.checked');
                +	};
                +
                +	/**
                +		Returns an array of unchecked nodes.
                +		@returns {Array} nodes - Unchecked nodes
                +	*/
                +	Tree.prototype.getUnchecked = function () {
                +		return this.findNodes('false', 'g', 'state.checked');
                +	};
                +
                +	/**
                +		Returns an array of disabled nodes.
                +		@returns {Array} nodes - Disabled nodes
                +	*/
                +	Tree.prototype.getDisabled = function () {
                +		return this.findNodes('true', 'g', 'state.disabled');
                +	};
                +
                +	/**
                +		Returns an array of enabled nodes.
                +		@returns {Array} nodes - Enabled nodes
                +	*/
                +	Tree.prototype.getEnabled = function () {
                +		return this.findNodes('false', 'g', 'state.disabled');
                +	};
                +
                +
                +	/**
                +		Set a node state to selected
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.selectNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setSelectedState(node, true, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Set a node state to unselected
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.unselectNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setSelectedState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Toggles a node selected state; selecting if unselected, unselecting if selected.
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.toggleNodeSelected = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.toggleSelectedState(node, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +
                +	/**
                +		Collapse all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.collapseAll = function (options) {
                +		var identifiers = this.findNodes('true', 'g', 'state.expanded');
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setExpandedState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Collapse a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.collapseNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setExpandedState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Expand all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.expandAll = function (options) {
                +		options = $.extend({}, _default.options, options);
                +
                +		if (options && options.levels) {
                +			this.expandLevels(this.tree, options.levels, options);
                +		}
                +		else {
                +			var identifiers = this.findNodes('false', 'g', 'state.expanded');
                +			this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +				this.setExpandedState(node, true, options);
                +			}, this));
                +		}
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Expand a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.expandNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setExpandedState(node, true, options);
                +			if (node.nodes && (options && options.levels)) {
                +				this.expandLevels(node.nodes, options.levels-1, options);
                +			}
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	Tree.prototype.expandLevels = function (nodes, level, options) {
                +		options = $.extend({}, _default.options, options);
                +
                +		$.each(nodes, $.proxy(function (index, node) {
                +			this.setExpandedState(node, (level > 0) ? true : false, options);
                +			if (node.nodes) {
                +				this.expandLevels(node.nodes, level-1, options);
                +			}
                +		}, this));
                +	};
                +
                +	/**
                +		Reveals a given tree node, expanding the tree from node to root.
                +		@param {Object|Number|Array} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.revealNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			var parentNode = this.getParent(node);
                +			while (parentNode) {
                +				this.setExpandedState(parentNode, true, options);
                +				parentNode = this.getParent(parentNode);
                +			};
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Toggles a nodes expanded state; collapsing if expanded, expanding if collapsed.
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.toggleNodeExpanded = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.toggleExpandedState(node, options);
                +		}, this));
                +		
                +		this.render();
                +	};
                +
                +
                +	/**
                +		Check all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.checkAll = function (options) {
                +		var identifiers = this.findNodes('false', 'g', 'state.checked');
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setCheckedState(node, true, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Check a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.checkNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setCheckedState(node, true, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Uncheck all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.uncheckAll = function (options) {
                +		var identifiers = this.findNodes('true', 'g', 'state.checked');
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setCheckedState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Uncheck a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.uncheckNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setCheckedState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Toggles a nodes checked state; checking if unchecked, unchecking if checked.
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.toggleNodeChecked = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.toggleCheckedState(node, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +
                +	/**
                +		Disable all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.disableAll = function (options) {
                +		var identifiers = this.findNodes('false', 'g', 'state.disabled');
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setDisabledState(node, true, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Disable a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.disableNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setDisabledState(node, true, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Enable all tree nodes
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.enableAll = function (options) {
                +		var identifiers = this.findNodes('true', 'g', 'state.disabled');
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setDisabledState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Enable a given tree node
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.enableNode = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setDisabledState(node, false, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +	/**
                +		Toggles a nodes disabled state; disabling is enabled, enabling if disabled.
                +		@param {Object|Number} identifiers - A valid node, node id or array of node identifiers
                +		@param {optional Object} options
                +	*/
                +	Tree.prototype.toggleNodeDisabled = function (identifiers, options) {
                +		this.forEachIdentifier(identifiers, options, $.proxy(function (node, options) {
                +			this.setDisabledState(node, !node.state.disabled, options);
                +		}, this));
                +
                +		this.render();
                +	};
                +
                +
                +	/**
                +		Common code for processing multiple identifiers
                +	*/
                +	Tree.prototype.forEachIdentifier = function (identifiers, options, callback) {
                +
                +		options = $.extend({}, _default.options, options);
                +
                +		if (!(identifiers instanceof Array)) {
                +			identifiers = [identifiers];
                +		}
                +
                +		$.each(identifiers, $.proxy(function (index, identifier) {
                +			callback(this.identifyNode(identifier), options);
                +		}, this));	
                +	};
                +
                +	/*
                +		Identifies a node from either a node id or object
                +	*/
                +	Tree.prototype.identifyNode = function (identifier) {
                +		return ((typeof identifier) === 'number') ?
                +						this.nodes[identifier] :
                +						identifier;
                +	};
                +
                +	/**
                +		Searches the tree for nodes (text) that match given criteria
                +		@param {String} pattern - A given string to match against
                +		@param {optional Object} options - Search criteria options
                +		@return {Array} nodes - Matching nodes
                +	*/
                +	Tree.prototype.search = function (pattern, options) {
                +		options = $.extend({}, _default.searchOptions, options);
                +
                +		this.clearSearch({ render: false });
                +
                +		var results = [];
                +		if (pattern && pattern.length > 0) {
                +
                +			if (options.exactMatch) {
                +				pattern = '^' + pattern + '$';
                +			}
                +
                +			var modifier = 'g';
                +			if (options.ignoreCase) {
                +				modifier += 'i';
                +			}
                +
                +			results = this.findNodes(pattern, modifier);
                +
                +			// Add searchResult property to all matching nodes
                +			// This will be used to apply custom styles
                +			// and when identifying result to be cleared
                +			$.each(results, function (index, node) {
                +				node.searchResult = true;
                +			})
                +		}
                +
                +		// If revealResults, then render is triggered from revealNode
                +		// otherwise we just call render.
                +		if (options.revealResults) {
                +			this.revealNode(results);
                +		}
                +		else {
                +			this.render();
                +		}
                +
                +		this.$element.trigger('searchComplete', $.extend(true, {}, results));
                +
                +		return results;
                +	};
                +
                +	/**
                +		Clears previous search results
                +	*/
                +	Tree.prototype.clearSearch = function (options) {
                +
                +		options = $.extend({}, { render: true }, options);
                +
                +		var results = $.each(this.findNodes('true', 'g', 'searchResult'), function (index, node) {
                +			node.searchResult = false;
                +		});
                +
                +		if (options.render) {
                +			this.render();	
                +		}
                +		
                +		this.$element.trigger('searchCleared', $.extend(true, {}, results));
                +	};
                +
                +	/**
                +		Find nodes that match a given criteria
                +		@param {String} pattern - A given string to match against
                +		@param {optional String} modifier - Valid RegEx modifiers
                +		@param {optional String} attribute - Attribute to compare pattern against
                +		@return {Array} nodes - Nodes that match your criteria
                +	*/
                +	Tree.prototype.findNodes = function (pattern, modifier, attribute) {
                +
                +		modifier = modifier || 'g';
                +		attribute = attribute || 'text';
                +
                +		var _this = this;
                +		return $.grep(this.nodes, function (node) {
                +			var val = _this.getNodeValue(node, attribute);
                +			if (typeof val === 'string') {
                +				return val.match(new RegExp(pattern, modifier));
                +			}
                +		});
                +	};
                +
                +	/**
                +		Recursive find for retrieving nested attributes values
                +		All values are return as strings, unless invalid
                +		@param {Object} obj - Typically a node, could be any object
                +		@param {String} attr - Identifies an object property using dot notation
                +		@return {String} value - Matching attributes string representation
                +	*/
                +	Tree.prototype.getNodeValue = function (obj, attr) {
                +		var index = attr.indexOf('.');
                +		if (index > 0) {
                +			var _obj = obj[attr.substring(0, index)];
                +			var _attr = attr.substring(index + 1, attr.length);
                +			return this.getNodeValue(_obj, _attr);
                +		}
                +		else {
                +			if (obj.hasOwnProperty(attr)) {
                +				return obj[attr].toString();
                +			}
                +			else {
                +				return undefined;
                +			}
                +		}
                +	};
                +
                +	var logError = function (message) {
                +		if (window.console) {
                +			window.console.error(message);
                +		}
                +	};
                +
                +	// Prevent against multiple instantiations,
                +	// handle updates and method calls
                +	$.fn[pluginName] = function (options, args) {
                +
                +		var result;
                +
                +		this.each(function () {
                +			var _this = $.data(this, pluginName);
                +			if (typeof options === 'string') {
                +				if (!_this) {
                +					logError('Not initialized, can not call method : ' + options);
                +				}
                +				else if (!$.isFunction(_this[options]) || options.charAt(0) === '_') {
                +					logError('No such method : ' + options);
                +				}
                +				else {
                +					if (!(args instanceof Array)) {
                +						args = [ args ];
                +					}
                +					result = _this[options].apply(_this, args);
                +				}
                +			}
                +			else if (typeof options === 'boolean') {
                +				result = _this;
                +			}
                +			else {
                +				$.data(this, pluginName, new Tree(this, $.extend(true, {}, options)));
                +			}
                +		});
                +
                +		return result || this;
                +	};
                +
                +})(jQuery, window, document);
                diff --git a/blockly/webif/static/js/bootstrap-treeview.min.js b/blockly/webif/static/js/bootstrap-treeview.min.js
                new file mode 100644
                index 000000000..9e2803815
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap-treeview.min.js
                @@ -0,0 +1 @@
                +!function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c<e.options.levels&&b.nodes&&b.nodes.length>0?b.state.expanded=!0:b.state.expanded=!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this.render()):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):(d.selectable?this.toggleSelectedState(d,f.options):this.toggleExpandedState(d,f.options),this.render())}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){this.initialized||(this.$element.addClass(e),this.$wrapper=a(this.template.list),this.injectStyle(),this.initialized=!0),this.$element.empty().append(this.$wrapper.empty()),this.buildTree(this.tree,0)},g.prototype.buildTree=function(b,c){if(b){c+=1;var d=this;a.each(b,function(b,e){for(var f=a(d.template.item).addClass("node-"+d.elementId).addClass(e.state.checked?"node-checked":"").addClass(e.state.disabled?"node-disabled":"").addClass(e.state.selected?"node-selected":"").addClass(e.searchResult?"search-result":"").attr("data-nodeid",e.nodeId).attr("style",d.buildStyleOverride(e)),g=0;c-1>g;g++)f.append(d.template.indent);var h=[];if(e.nodes?(h.push("expand-icon"),h.push(e.state.expanded?d.options.collapseIcon:d.options.expandIcon)):h.push(d.options.emptyIcon),f.append(a(d.template.icon).addClass(h.join(" "))),d.options.showIcon){var h=["node-icon"];h.push(e.icon||d.options.nodeIcon),e.state.selected&&(h.pop(),h.push(e.selectedIcon||d.options.selectedIcon||e.icon||d.options.nodeIcon)),f.append(a(d.template.icon).addClass(h.join(" ")))}if(d.options.showCheckbox){var h=["check-icon"];h.push(e.state.checked?d.options.checkedIcon:d.options.uncheckedIcon),f.append(a(d.template.icon).addClass(h.join(" ")))}return f.append(d.options.enableLinks?a(d.template.link).attr("href",e.href).append(e.text):e.text),d.options.showTags&&e.tags&&a.each(e.tags,function(b,c){f.append(a(d.template.badge).append(c))}),d.$wrapper.append(f),e.nodes&&e.state.expanded&&!e.state.disabled?d.buildTree(e.nodes,c):void 0})}},g.prototype.buildStyleOverride=function(a){if(a.state.disabled)return"";var b=a.color,c=a.backColor;return this.options.highlightSelected&&a.state.selected&&(this.options.selectedColor&&(b=this.options.selectedColor),this.options.selectedBackColor&&(c=this.options.selectedBackColor)),this.options.highlightSearchResults&&a.searchResult&&!a.state.disabled&&(this.options.searchResultColor&&(b=this.options.searchResultColor),this.options.searchResultBackColor&&(c=this.options.searchResultBackColor)),"color:"+b+";background-color:"+c+";"},g.prototype.injectStyle=function(){this.options.injectStyle&&!c.getElementById(this.styleId)&&a('<style type="text/css" id="'+this.styleId+'"> '+this.buildStyle()+" </style>").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={list:'<ul class="list-group"></ul>',item:'<li class="list-group-item"></li>',indent:'<span class="indent"></span>',icon:'<span class="icon"></span>',link:'<a href="#" style="color:inherit;"></a>',badge:'<span class="badge"></span>'},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){var c=this.findNodes("true","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.expandAll=function(b){if(b=a.extend({},f.options,b),b&&b.levels)this.expandLevels(this.tree,b.levels,b);else{var c=this.findNodes("false","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!0,b)},this))}this.render()},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&b&&b.levels&&this.expandLevels(a.nodes,b.levels-1,b)},this)),this.render()},g.prototype.expandLevels=function(b,c,d){d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this.expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c=this.getParent(a);c;)this.setExpandedState(c,!0,b),c=this.getParent(c)},this)),this.render()},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b)},this)),this.render()},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document);
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/bootstrap.js b/blockly/webif/static/js/bootstrap.js
                new file mode 100644
                index 000000000..8a2e99a53
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap.js
                @@ -0,0 +1,2377 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under the MIT license
                + */
                +
                +if (typeof jQuery === 'undefined') {
                +  throw new Error('Bootstrap\'s JavaScript requires jQuery')
                +}
                +
                ++function ($) {
                +  'use strict';
                +  var version = $.fn.jquery.split(' ')[0].split('.')
                +  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
                +    throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
                +  }
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: transition.js v3.3.7
                + * http://getbootstrap.com/javascript/#transitions
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
                +  // ============================================================
                +
                +  function transitionEnd() {
                +    var el = document.createElement('bootstrap')
                +
                +    var transEndEventNames = {
                +      WebkitTransition : 'webkitTransitionEnd',
                +      MozTransition    : 'transitionend',
                +      OTransition      : 'oTransitionEnd otransitionend',
                +      transition       : 'transitionend'
                +    }
                +
                +    for (var name in transEndEventNames) {
                +      if (el.style[name] !== undefined) {
                +        return { end: transEndEventNames[name] }
                +      }
                +    }
                +
                +    return false // explicit for ie8 (  ._.)
                +  }
                +
                +  // http://blog.alexmaccaw.com/css-transitions
                +  $.fn.emulateTransitionEnd = function (duration) {
                +    var called = false
                +    var $el = this
                +    $(this).one('bsTransitionEnd', function () { called = true })
                +    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
                +    setTimeout(callback, duration)
                +    return this
                +  }
                +
                +  $(function () {
                +    $.support.transition = transitionEnd()
                +
                +    if (!$.support.transition) return
                +
                +    $.event.special.bsTransitionEnd = {
                +      bindType: $.support.transition.end,
                +      delegateType: $.support.transition.end,
                +      handle: function (e) {
                +        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
                +      }
                +    }
                +  })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: alert.js v3.3.7
                + * http://getbootstrap.com/javascript/#alerts
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // ALERT CLASS DEFINITION
                +  // ======================
                +
                +  var dismiss = '[data-dismiss="alert"]'
                +  var Alert   = function (el) {
                +    $(el).on('click', dismiss, this.close)
                +  }
                +
                +  Alert.VERSION = '3.3.7'
                +
                +  Alert.TRANSITION_DURATION = 150
                +
                +  Alert.prototype.close = function (e) {
                +    var $this    = $(this)
                +    var selector = $this.attr('data-target')
                +
                +    if (!selector) {
                +      selector = $this.attr('href')
                +      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
                +    }
                +
                +    var $parent = $(selector === '#' ? [] : selector)
                +
                +    if (e) e.preventDefault()
                +
                +    if (!$parent.length) {
                +      $parent = $this.closest('.alert')
                +    }
                +
                +    $parent.trigger(e = $.Event('close.bs.alert'))
                +
                +    if (e.isDefaultPrevented()) return
                +
                +    $parent.removeClass('in')
                +
                +    function removeElement() {
                +      // detach from parent, fire event then clean up data
                +      $parent.detach().trigger('closed.bs.alert').remove()
                +    }
                +
                +    $.support.transition && $parent.hasClass('fade') ?
                +      $parent
                +        .one('bsTransitionEnd', removeElement)
                +        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
                +      removeElement()
                +  }
                +
                +
                +  // ALERT PLUGIN DEFINITION
                +  // =======================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this = $(this)
                +      var data  = $this.data('bs.alert')
                +
                +      if (!data) $this.data('bs.alert', (data = new Alert(this)))
                +      if (typeof option == 'string') data[option].call($this)
                +    })
                +  }
                +
                +  var old = $.fn.alert
                +
                +  $.fn.alert             = Plugin
                +  $.fn.alert.Constructor = Alert
                +
                +
                +  // ALERT NO CONFLICT
                +  // =================
                +
                +  $.fn.alert.noConflict = function () {
                +    $.fn.alert = old
                +    return this
                +  }
                +
                +
                +  // ALERT DATA-API
                +  // ==============
                +
                +  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: button.js v3.3.7
                + * http://getbootstrap.com/javascript/#buttons
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // BUTTON PUBLIC CLASS DEFINITION
                +  // ==============================
                +
                +  var Button = function (element, options) {
                +    this.$element  = $(element)
                +    this.options   = $.extend({}, Button.DEFAULTS, options)
                +    this.isLoading = false
                +  }
                +
                +  Button.VERSION  = '3.3.7'
                +
                +  Button.DEFAULTS = {
                +    loadingText: 'loading...'
                +  }
                +
                +  Button.prototype.setState = function (state) {
                +    var d    = 'disabled'
                +    var $el  = this.$element
                +    var val  = $el.is('input') ? 'val' : 'html'
                +    var data = $el.data()
                +
                +    state += 'Text'
                +
                +    if (data.resetText == null) $el.data('resetText', $el[val]())
                +
                +    // push to event loop to allow forms to submit
                +    setTimeout($.proxy(function () {
                +      $el[val](data[state] == null ? this.options[state] : data[state])
                +
                +      if (state == 'loadingText') {
                +        this.isLoading = true
                +        $el.addClass(d).attr(d, d).prop(d, true)
                +      } else if (this.isLoading) {
                +        this.isLoading = false
                +        $el.removeClass(d).removeAttr(d).prop(d, false)
                +      }
                +    }, this), 0)
                +  }
                +
                +  Button.prototype.toggle = function () {
                +    var changed = true
                +    var $parent = this.$element.closest('[data-toggle="buttons"]')
                +
                +    if ($parent.length) {
                +      var $input = this.$element.find('input')
                +      if ($input.prop('type') == 'radio') {
                +        if ($input.prop('checked')) changed = false
                +        $parent.find('.active').removeClass('active')
                +        this.$element.addClass('active')
                +      } else if ($input.prop('type') == 'checkbox') {
                +        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
                +        this.$element.toggleClass('active')
                +      }
                +      $input.prop('checked', this.$element.hasClass('active'))
                +      if (changed) $input.trigger('change')
                +    } else {
                +      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
                +      this.$element.toggleClass('active')
                +    }
                +  }
                +
                +
                +  // BUTTON PLUGIN DEFINITION
                +  // ========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.button')
                +      var options = typeof option == 'object' && option
                +
                +      if (!data) $this.data('bs.button', (data = new Button(this, options)))
                +
                +      if (option == 'toggle') data.toggle()
                +      else if (option) data.setState(option)
                +    })
                +  }
                +
                +  var old = $.fn.button
                +
                +  $.fn.button             = Plugin
                +  $.fn.button.Constructor = Button
                +
                +
                +  // BUTTON NO CONFLICT
                +  // ==================
                +
                +  $.fn.button.noConflict = function () {
                +    $.fn.button = old
                +    return this
                +  }
                +
                +
                +  // BUTTON DATA-API
                +  // ===============
                +
                +  $(document)
                +    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
                +      var $btn = $(e.target).closest('.btn')
                +      Plugin.call($btn, 'toggle')
                +      if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
                +        // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
                +        e.preventDefault()
                +        // The target component still receive the focus
                +        if ($btn.is('input,button')) $btn.trigger('focus')
                +        else $btn.find('input:visible,button:visible').first().trigger('focus')
                +      }
                +    })
                +    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
                +      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
                +    })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: carousel.js v3.3.7
                + * http://getbootstrap.com/javascript/#carousel
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // CAROUSEL CLASS DEFINITION
                +  // =========================
                +
                +  var Carousel = function (element, options) {
                +    this.$element    = $(element)
                +    this.$indicators = this.$element.find('.carousel-indicators')
                +    this.options     = options
                +    this.paused      = null
                +    this.sliding     = null
                +    this.interval    = null
                +    this.$active     = null
                +    this.$items      = null
                +
                +    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
                +
                +    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
                +      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
                +      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
                +  }
                +
                +  Carousel.VERSION  = '3.3.7'
                +
                +  Carousel.TRANSITION_DURATION = 600
                +
                +  Carousel.DEFAULTS = {
                +    interval: 5000,
                +    pause: 'hover',
                +    wrap: true,
                +    keyboard: true
                +  }
                +
                +  Carousel.prototype.keydown = function (e) {
                +    if (/input|textarea/i.test(e.target.tagName)) return
                +    switch (e.which) {
                +      case 37: this.prev(); break
                +      case 39: this.next(); break
                +      default: return
                +    }
                +
                +    e.preventDefault()
                +  }
                +
                +  Carousel.prototype.cycle = function (e) {
                +    e || (this.paused = false)
                +
                +    this.interval && clearInterval(this.interval)
                +
                +    this.options.interval
                +      && !this.paused
                +      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
                +
                +    return this
                +  }
                +
                +  Carousel.prototype.getItemIndex = function (item) {
                +    this.$items = item.parent().children('.item')
                +    return this.$items.index(item || this.$active)
                +  }
                +
                +  Carousel.prototype.getItemForDirection = function (direction, active) {
                +    var activeIndex = this.getItemIndex(active)
                +    var willWrap = (direction == 'prev' && activeIndex === 0)
                +                || (direction == 'next' && activeIndex == (this.$items.length - 1))
                +    if (willWrap && !this.options.wrap) return active
                +    var delta = direction == 'prev' ? -1 : 1
                +    var itemIndex = (activeIndex + delta) % this.$items.length
                +    return this.$items.eq(itemIndex)
                +  }
                +
                +  Carousel.prototype.to = function (pos) {
                +    var that        = this
                +    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
                +
                +    if (pos > (this.$items.length - 1) || pos < 0) return
                +
                +    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
                +    if (activeIndex == pos) return this.pause().cycle()
                +
                +    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
                +  }
                +
                +  Carousel.prototype.pause = function (e) {
                +    e || (this.paused = true)
                +
                +    if (this.$element.find('.next, .prev').length && $.support.transition) {
                +      this.$element.trigger($.support.transition.end)
                +      this.cycle(true)
                +    }
                +
                +    this.interval = clearInterval(this.interval)
                +
                +    return this
                +  }
                +
                +  Carousel.prototype.next = function () {
                +    if (this.sliding) return
                +    return this.slide('next')
                +  }
                +
                +  Carousel.prototype.prev = function () {
                +    if (this.sliding) return
                +    return this.slide('prev')
                +  }
                +
                +  Carousel.prototype.slide = function (type, next) {
                +    var $active   = this.$element.find('.item.active')
                +    var $next     = next || this.getItemForDirection(type, $active)
                +    var isCycling = this.interval
                +    var direction = type == 'next' ? 'left' : 'right'
                +    var that      = this
                +
                +    if ($next.hasClass('active')) return (this.sliding = false)
                +
                +    var relatedTarget = $next[0]
                +    var slideEvent = $.Event('slide.bs.carousel', {
                +      relatedTarget: relatedTarget,
                +      direction: direction
                +    })
                +    this.$element.trigger(slideEvent)
                +    if (slideEvent.isDefaultPrevented()) return
                +
                +    this.sliding = true
                +
                +    isCycling && this.pause()
                +
                +    if (this.$indicators.length) {
                +      this.$indicators.find('.active').removeClass('active')
                +      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
                +      $nextIndicator && $nextIndicator.addClass('active')
                +    }
                +
                +    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
                +    if ($.support.transition && this.$element.hasClass('slide')) {
                +      $next.addClass(type)
                +      $next[0].offsetWidth // force reflow
                +      $active.addClass(direction)
                +      $next.addClass(direction)
                +      $active
                +        .one('bsTransitionEnd', function () {
                +          $next.removeClass([type, direction].join(' ')).addClass('active')
                +          $active.removeClass(['active', direction].join(' '))
                +          that.sliding = false
                +          setTimeout(function () {
                +            that.$element.trigger(slidEvent)
                +          }, 0)
                +        })
                +        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
                +    } else {
                +      $active.removeClass('active')
                +      $next.addClass('active')
                +      this.sliding = false
                +      this.$element.trigger(slidEvent)
                +    }
                +
                +    isCycling && this.cycle()
                +
                +    return this
                +  }
                +
                +
                +  // CAROUSEL PLUGIN DEFINITION
                +  // ==========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.carousel')
                +      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
                +      var action  = typeof option == 'string' ? option : options.slide
                +
                +      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
                +      if (typeof option == 'number') data.to(option)
                +      else if (action) data[action]()
                +      else if (options.interval) data.pause().cycle()
                +    })
                +  }
                +
                +  var old = $.fn.carousel
                +
                +  $.fn.carousel             = Plugin
                +  $.fn.carousel.Constructor = Carousel
                +
                +
                +  // CAROUSEL NO CONFLICT
                +  // ====================
                +
                +  $.fn.carousel.noConflict = function () {
                +    $.fn.carousel = old
                +    return this
                +  }
                +
                +
                +  // CAROUSEL DATA-API
                +  // =================
                +
                +  var clickHandler = function (e) {
                +    var href
                +    var $this   = $(this)
                +    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
                +    if (!$target.hasClass('carousel')) return
                +    var options = $.extend({}, $target.data(), $this.data())
                +    var slideIndex = $this.attr('data-slide-to')
                +    if (slideIndex) options.interval = false
                +
                +    Plugin.call($target, options)
                +
                +    if (slideIndex) {
                +      $target.data('bs.carousel').to(slideIndex)
                +    }
                +
                +    e.preventDefault()
                +  }
                +
                +  $(document)
                +    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
                +    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
                +
                +  $(window).on('load', function () {
                +    $('[data-ride="carousel"]').each(function () {
                +      var $carousel = $(this)
                +      Plugin.call($carousel, $carousel.data())
                +    })
                +  })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: collapse.js v3.3.7
                + * http://getbootstrap.com/javascript/#collapse
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +/* jshint latedef: false */
                +
                ++function ($) {
                +  'use strict';
                +
                +  // COLLAPSE PUBLIC CLASS DEFINITION
                +  // ================================
                +
                +  var Collapse = function (element, options) {
                +    this.$element      = $(element)
                +    this.options       = $.extend({}, Collapse.DEFAULTS, options)
                +    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
                +                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
                +    this.transitioning = null
                +
                +    if (this.options.parent) {
                +      this.$parent = this.getParent()
                +    } else {
                +      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
                +    }
                +
                +    if (this.options.toggle) this.toggle()
                +  }
                +
                +  Collapse.VERSION  = '3.3.7'
                +
                +  Collapse.TRANSITION_DURATION = 350
                +
                +  Collapse.DEFAULTS = {
                +    toggle: true
                +  }
                +
                +  Collapse.prototype.dimension = function () {
                +    var hasWidth = this.$element.hasClass('width')
                +    return hasWidth ? 'width' : 'height'
                +  }
                +
                +  Collapse.prototype.show = function () {
                +    if (this.transitioning || this.$element.hasClass('in')) return
                +
                +    var activesData
                +    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
                +
                +    if (actives && actives.length) {
                +      activesData = actives.data('bs.collapse')
                +      if (activesData && activesData.transitioning) return
                +    }
                +
                +    var startEvent = $.Event('show.bs.collapse')
                +    this.$element.trigger(startEvent)
                +    if (startEvent.isDefaultPrevented()) return
                +
                +    if (actives && actives.length) {
                +      Plugin.call(actives, 'hide')
                +      activesData || actives.data('bs.collapse', null)
                +    }
                +
                +    var dimension = this.dimension()
                +
                +    this.$element
                +      .removeClass('collapse')
                +      .addClass('collapsing')[dimension](0)
                +      .attr('aria-expanded', true)
                +
                +    this.$trigger
                +      .removeClass('collapsed')
                +      .attr('aria-expanded', true)
                +
                +    this.transitioning = 1
                +
                +    var complete = function () {
                +      this.$element
                +        .removeClass('collapsing')
                +        .addClass('collapse in')[dimension]('')
                +      this.transitioning = 0
                +      this.$element
                +        .trigger('shown.bs.collapse')
                +    }
                +
                +    if (!$.support.transition) return complete.call(this)
                +
                +    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
                +
                +    this.$element
                +      .one('bsTransitionEnd', $.proxy(complete, this))
                +      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
                +  }
                +
                +  Collapse.prototype.hide = function () {
                +    if (this.transitioning || !this.$element.hasClass('in')) return
                +
                +    var startEvent = $.Event('hide.bs.collapse')
                +    this.$element.trigger(startEvent)
                +    if (startEvent.isDefaultPrevented()) return
                +
                +    var dimension = this.dimension()
                +
                +    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
                +
                +    this.$element
                +      .addClass('collapsing')
                +      .removeClass('collapse in')
                +      .attr('aria-expanded', false)
                +
                +    this.$trigger
                +      .addClass('collapsed')
                +      .attr('aria-expanded', false)
                +
                +    this.transitioning = 1
                +
                +    var complete = function () {
                +      this.transitioning = 0
                +      this.$element
                +        .removeClass('collapsing')
                +        .addClass('collapse')
                +        .trigger('hidden.bs.collapse')
                +    }
                +
                +    if (!$.support.transition) return complete.call(this)
                +
                +    this.$element
                +      [dimension](0)
                +      .one('bsTransitionEnd', $.proxy(complete, this))
                +      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
                +  }
                +
                +  Collapse.prototype.toggle = function () {
                +    this[this.$element.hasClass('in') ? 'hide' : 'show']()
                +  }
                +
                +  Collapse.prototype.getParent = function () {
                +    return $(this.options.parent)
                +      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
                +      .each($.proxy(function (i, element) {
                +        var $element = $(element)
                +        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
                +      }, this))
                +      .end()
                +  }
                +
                +  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
                +    var isOpen = $element.hasClass('in')
                +
                +    $element.attr('aria-expanded', isOpen)
                +    $trigger
                +      .toggleClass('collapsed', !isOpen)
                +      .attr('aria-expanded', isOpen)
                +  }
                +
                +  function getTargetFromTrigger($trigger) {
                +    var href
                +    var target = $trigger.attr('data-target')
                +      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
                +
                +    return $(target)
                +  }
                +
                +
                +  // COLLAPSE PLUGIN DEFINITION
                +  // ==========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.collapse')
                +      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
                +
                +      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
                +      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.collapse
                +
                +  $.fn.collapse             = Plugin
                +  $.fn.collapse.Constructor = Collapse
                +
                +
                +  // COLLAPSE NO CONFLICT
                +  // ====================
                +
                +  $.fn.collapse.noConflict = function () {
                +    $.fn.collapse = old
                +    return this
                +  }
                +
                +
                +  // COLLAPSE DATA-API
                +  // =================
                +
                +  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
                +    var $this   = $(this)
                +
                +    if (!$this.attr('data-target')) e.preventDefault()
                +
                +    var $target = getTargetFromTrigger($this)
                +    var data    = $target.data('bs.collapse')
                +    var option  = data ? 'toggle' : $this.data()
                +
                +    Plugin.call($target, option)
                +  })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: dropdown.js v3.3.7
                + * http://getbootstrap.com/javascript/#dropdowns
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // DROPDOWN CLASS DEFINITION
                +  // =========================
                +
                +  var backdrop = '.dropdown-backdrop'
                +  var toggle   = '[data-toggle="dropdown"]'
                +  var Dropdown = function (element) {
                +    $(element).on('click.bs.dropdown', this.toggle)
                +  }
                +
                +  Dropdown.VERSION = '3.3.7'
                +
                +  function getParent($this) {
                +    var selector = $this.attr('data-target')
                +
                +    if (!selector) {
                +      selector = $this.attr('href')
                +      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
                +    }
                +
                +    var $parent = selector && $(selector)
                +
                +    return $parent && $parent.length ? $parent : $this.parent()
                +  }
                +
                +  function clearMenus(e) {
                +    if (e && e.which === 3) return
                +    $(backdrop).remove()
                +    $(toggle).each(function () {
                +      var $this         = $(this)
                +      var $parent       = getParent($this)
                +      var relatedTarget = { relatedTarget: this }
                +
                +      if (!$parent.hasClass('open')) return
                +
                +      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
                +
                +      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
                +
                +      if (e.isDefaultPrevented()) return
                +
                +      $this.attr('aria-expanded', 'false')
                +      $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
                +    })
                +  }
                +
                +  Dropdown.prototype.toggle = function (e) {
                +    var $this = $(this)
                +
                +    if ($this.is('.disabled, :disabled')) return
                +
                +    var $parent  = getParent($this)
                +    var isActive = $parent.hasClass('open')
                +
                +    clearMenus()
                +
                +    if (!isActive) {
                +      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
                +        // if mobile we use a backdrop because click events don't delegate
                +        $(document.createElement('div'))
                +          .addClass('dropdown-backdrop')
                +          .insertAfter($(this))
                +          .on('click', clearMenus)
                +      }
                +
                +      var relatedTarget = { relatedTarget: this }
                +      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
                +
                +      if (e.isDefaultPrevented()) return
                +
                +      $this
                +        .trigger('focus')
                +        .attr('aria-expanded', 'true')
                +
                +      $parent
                +        .toggleClass('open')
                +        .trigger($.Event('shown.bs.dropdown', relatedTarget))
                +    }
                +
                +    return false
                +  }
                +
                +  Dropdown.prototype.keydown = function (e) {
                +    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
                +
                +    var $this = $(this)
                +
                +    e.preventDefault()
                +    e.stopPropagation()
                +
                +    if ($this.is('.disabled, :disabled')) return
                +
                +    var $parent  = getParent($this)
                +    var isActive = $parent.hasClass('open')
                +
                +    if (!isActive && e.which != 27 || isActive && e.which == 27) {
                +      if (e.which == 27) $parent.find(toggle).trigger('focus')
                +      return $this.trigger('click')
                +    }
                +
                +    var desc = ' li:not(.disabled):visible a'
                +    var $items = $parent.find('.dropdown-menu' + desc)
                +
                +    if (!$items.length) return
                +
                +    var index = $items.index(e.target)
                +
                +    if (e.which == 38 && index > 0)                 index--         // up
                +    if (e.which == 40 && index < $items.length - 1) index++         // down
                +    if (!~index)                                    index = 0
                +
                +    $items.eq(index).trigger('focus')
                +  }
                +
                +
                +  // DROPDOWN PLUGIN DEFINITION
                +  // ==========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this = $(this)
                +      var data  = $this.data('bs.dropdown')
                +
                +      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
                +      if (typeof option == 'string') data[option].call($this)
                +    })
                +  }
                +
                +  var old = $.fn.dropdown
                +
                +  $.fn.dropdown             = Plugin
                +  $.fn.dropdown.Constructor = Dropdown
                +
                +
                +  // DROPDOWN NO CONFLICT
                +  // ====================
                +
                +  $.fn.dropdown.noConflict = function () {
                +    $.fn.dropdown = old
                +    return this
                +  }
                +
                +
                +  // APPLY TO STANDARD DROPDOWN ELEMENTS
                +  // ===================================
                +
                +  $(document)
                +    .on('click.bs.dropdown.data-api', clearMenus)
                +    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
                +    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
                +    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
                +    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: modal.js v3.3.7
                + * http://getbootstrap.com/javascript/#modals
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // MODAL CLASS DEFINITION
                +  // ======================
                +
                +  var Modal = function (element, options) {
                +    this.options             = options
                +    this.$body               = $(document.body)
                +    this.$element            = $(element)
                +    this.$dialog             = this.$element.find('.modal-dialog')
                +    this.$backdrop           = null
                +    this.isShown             = null
                +    this.originalBodyPad     = null
                +    this.scrollbarWidth      = 0
                +    this.ignoreBackdropClick = false
                +
                +    if (this.options.remote) {
                +      this.$element
                +        .find('.modal-content')
                +        .load(this.options.remote, $.proxy(function () {
                +          this.$element.trigger('loaded.bs.modal')
                +        }, this))
                +    }
                +  }
                +
                +  Modal.VERSION  = '3.3.7'
                +
                +  Modal.TRANSITION_DURATION = 300
                +  Modal.BACKDROP_TRANSITION_DURATION = 150
                +
                +  Modal.DEFAULTS = {
                +    backdrop: true,
                +    keyboard: true,
                +    show: true
                +  }
                +
                +  Modal.prototype.toggle = function (_relatedTarget) {
                +    return this.isShown ? this.hide() : this.show(_relatedTarget)
                +  }
                +
                +  Modal.prototype.show = function (_relatedTarget) {
                +    var that = this
                +    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
                +
                +    this.$element.trigger(e)
                +
                +    if (this.isShown || e.isDefaultPrevented()) return
                +
                +    this.isShown = true
                +
                +    this.checkScrollbar()
                +    this.setScrollbar()
                +    this.$body.addClass('modal-open')
                +
                +    this.escape()
                +    this.resize()
                +
                +    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
                +
                +    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
                +      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
                +        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
                +      })
                +    })
                +
                +    this.backdrop(function () {
                +      var transition = $.support.transition && that.$element.hasClass('fade')
                +
                +      if (!that.$element.parent().length) {
                +        that.$element.appendTo(that.$body) // don't move modals dom position
                +      }
                +
                +      that.$element
                +        .show()
                +        .scrollTop(0)
                +
                +      that.adjustDialog()
                +
                +      if (transition) {
                +        that.$element[0].offsetWidth // force reflow
                +      }
                +
                +      that.$element.addClass('in')
                +
                +      that.enforceFocus()
                +
                +      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
                +
                +      transition ?
                +        that.$dialog // wait for modal to slide in
                +          .one('bsTransitionEnd', function () {
                +            that.$element.trigger('focus').trigger(e)
                +          })
                +          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
                +        that.$element.trigger('focus').trigger(e)
                +    })
                +  }
                +
                +  Modal.prototype.hide = function (e) {
                +    if (e) e.preventDefault()
                +
                +    e = $.Event('hide.bs.modal')
                +
                +    this.$element.trigger(e)
                +
                +    if (!this.isShown || e.isDefaultPrevented()) return
                +
                +    this.isShown = false
                +
                +    this.escape()
                +    this.resize()
                +
                +    $(document).off('focusin.bs.modal')
                +
                +    this.$element
                +      .removeClass('in')
                +      .off('click.dismiss.bs.modal')
                +      .off('mouseup.dismiss.bs.modal')
                +
                +    this.$dialog.off('mousedown.dismiss.bs.modal')
                +
                +    $.support.transition && this.$element.hasClass('fade') ?
                +      this.$element
                +        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
                +        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
                +      this.hideModal()
                +  }
                +
                +  Modal.prototype.enforceFocus = function () {
                +    $(document)
                +      .off('focusin.bs.modal') // guard against infinite focus loop
                +      .on('focusin.bs.modal', $.proxy(function (e) {
                +        if (document !== e.target &&
                +            this.$element[0] !== e.target &&
                +            !this.$element.has(e.target).length) {
                +          this.$element.trigger('focus')
                +        }
                +      }, this))
                +  }
                +
                +  Modal.prototype.escape = function () {
                +    if (this.isShown && this.options.keyboard) {
                +      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
                +        e.which == 27 && this.hide()
                +      }, this))
                +    } else if (!this.isShown) {
                +      this.$element.off('keydown.dismiss.bs.modal')
                +    }
                +  }
                +
                +  Modal.prototype.resize = function () {
                +    if (this.isShown) {
                +      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
                +    } else {
                +      $(window).off('resize.bs.modal')
                +    }
                +  }
                +
                +  Modal.prototype.hideModal = function () {
                +    var that = this
                +    this.$element.hide()
                +    this.backdrop(function () {
                +      that.$body.removeClass('modal-open')
                +      that.resetAdjustments()
                +      that.resetScrollbar()
                +      that.$element.trigger('hidden.bs.modal')
                +    })
                +  }
                +
                +  Modal.prototype.removeBackdrop = function () {
                +    this.$backdrop && this.$backdrop.remove()
                +    this.$backdrop = null
                +  }
                +
                +  Modal.prototype.backdrop = function (callback) {
                +    var that = this
                +    var animate = this.$element.hasClass('fade') ? 'fade' : ''
                +
                +    if (this.isShown && this.options.backdrop) {
                +      var doAnimate = $.support.transition && animate
                +
                +      this.$backdrop = $(document.createElement('div'))
                +        .addClass('modal-backdrop ' + animate)
                +        .appendTo(this.$body)
                +
                +      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
                +        if (this.ignoreBackdropClick) {
                +          this.ignoreBackdropClick = false
                +          return
                +        }
                +        if (e.target !== e.currentTarget) return
                +        this.options.backdrop == 'static'
                +          ? this.$element[0].focus()
                +          : this.hide()
                +      }, this))
                +
                +      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
                +
                +      this.$backdrop.addClass('in')
                +
                +      if (!callback) return
                +
                +      doAnimate ?
                +        this.$backdrop
                +          .one('bsTransitionEnd', callback)
                +          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
                +        callback()
                +
                +    } else if (!this.isShown && this.$backdrop) {
                +      this.$backdrop.removeClass('in')
                +
                +      var callbackRemove = function () {
                +        that.removeBackdrop()
                +        callback && callback()
                +      }
                +      $.support.transition && this.$element.hasClass('fade') ?
                +        this.$backdrop
                +          .one('bsTransitionEnd', callbackRemove)
                +          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
                +        callbackRemove()
                +
                +    } else if (callback) {
                +      callback()
                +    }
                +  }
                +
                +  // these following methods are used to handle overflowing modals
                +
                +  Modal.prototype.handleUpdate = function () {
                +    this.adjustDialog()
                +  }
                +
                +  Modal.prototype.adjustDialog = function () {
                +    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
                +
                +    this.$element.css({
                +      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
                +      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
                +    })
                +  }
                +
                +  Modal.prototype.resetAdjustments = function () {
                +    this.$element.css({
                +      paddingLeft: '',
                +      paddingRight: ''
                +    })
                +  }
                +
                +  Modal.prototype.checkScrollbar = function () {
                +    var fullWindowWidth = window.innerWidth
                +    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
                +      var documentElementRect = document.documentElement.getBoundingClientRect()
                +      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
                +    }
                +    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
                +    this.scrollbarWidth = this.measureScrollbar()
                +  }
                +
                +  Modal.prototype.setScrollbar = function () {
                +    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
                +    this.originalBodyPad = document.body.style.paddingRight || ''
                +    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
                +  }
                +
                +  Modal.prototype.resetScrollbar = function () {
                +    this.$body.css('padding-right', this.originalBodyPad)
                +  }
                +
                +  Modal.prototype.measureScrollbar = function () { // thx walsh
                +    var scrollDiv = document.createElement('div')
                +    scrollDiv.className = 'modal-scrollbar-measure'
                +    this.$body.append(scrollDiv)
                +    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
                +    this.$body[0].removeChild(scrollDiv)
                +    return scrollbarWidth
                +  }
                +
                +
                +  // MODAL PLUGIN DEFINITION
                +  // =======================
                +
                +  function Plugin(option, _relatedTarget) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.modal')
                +      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
                +
                +      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
                +      if (typeof option == 'string') data[option](_relatedTarget)
                +      else if (options.show) data.show(_relatedTarget)
                +    })
                +  }
                +
                +  var old = $.fn.modal
                +
                +  $.fn.modal             = Plugin
                +  $.fn.modal.Constructor = Modal
                +
                +
                +  // MODAL NO CONFLICT
                +  // =================
                +
                +  $.fn.modal.noConflict = function () {
                +    $.fn.modal = old
                +    return this
                +  }
                +
                +
                +  // MODAL DATA-API
                +  // ==============
                +
                +  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
                +    var $this   = $(this)
                +    var href    = $this.attr('href')
                +    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
                +    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
                +
                +    if ($this.is('a')) e.preventDefault()
                +
                +    $target.one('show.bs.modal', function (showEvent) {
                +      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
                +      $target.one('hidden.bs.modal', function () {
                +        $this.is(':visible') && $this.trigger('focus')
                +      })
                +    })
                +    Plugin.call($target, option, this)
                +  })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: tooltip.js v3.3.7
                + * http://getbootstrap.com/javascript/#tooltip
                + * Inspired by the original jQuery.tipsy by Jason Frame
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // TOOLTIP PUBLIC CLASS DEFINITION
                +  // ===============================
                +
                +  var Tooltip = function (element, options) {
                +    this.type       = null
                +    this.options    = null
                +    this.enabled    = null
                +    this.timeout    = null
                +    this.hoverState = null
                +    this.$element   = null
                +    this.inState    = null
                +
                +    this.init('tooltip', element, options)
                +  }
                +
                +  Tooltip.VERSION  = '3.3.7'
                +
                +  Tooltip.TRANSITION_DURATION = 150
                +
                +  Tooltip.DEFAULTS = {
                +    animation: true,
                +    placement: 'top',
                +    selector: false,
                +    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
                +    trigger: 'hover focus',
                +    title: '',
                +    delay: 0,
                +    html: false,
                +    container: false,
                +    viewport: {
                +      selector: 'body',
                +      padding: 0
                +    }
                +  }
                +
                +  Tooltip.prototype.init = function (type, element, options) {
                +    this.enabled   = true
                +    this.type      = type
                +    this.$element  = $(element)
                +    this.options   = this.getOptions(options)
                +    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
                +    this.inState   = { click: false, hover: false, focus: false }
                +
                +    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
                +      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
                +    }
                +
                +    var triggers = this.options.trigger.split(' ')
                +
                +    for (var i = triggers.length; i--;) {
                +      var trigger = triggers[i]
                +
                +      if (trigger == 'click') {
                +        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
                +      } else if (trigger != 'manual') {
                +        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
                +        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
                +
                +        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
                +        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
                +      }
                +    }
                +
                +    this.options.selector ?
                +      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
                +      this.fixTitle()
                +  }
                +
                +  Tooltip.prototype.getDefaults = function () {
                +    return Tooltip.DEFAULTS
                +  }
                +
                +  Tooltip.prototype.getOptions = function (options) {
                +    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
                +
                +    if (options.delay && typeof options.delay == 'number') {
                +      options.delay = {
                +        show: options.delay,
                +        hide: options.delay
                +      }
                +    }
                +
                +    return options
                +  }
                +
                +  Tooltip.prototype.getDelegateOptions = function () {
                +    var options  = {}
                +    var defaults = this.getDefaults()
                +
                +    this._options && $.each(this._options, function (key, value) {
                +      if (defaults[key] != value) options[key] = value
                +    })
                +
                +    return options
                +  }
                +
                +  Tooltip.prototype.enter = function (obj) {
                +    var self = obj instanceof this.constructor ?
                +      obj : $(obj.currentTarget).data('bs.' + this.type)
                +
                +    if (!self) {
                +      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
                +      $(obj.currentTarget).data('bs.' + this.type, self)
                +    }
                +
                +    if (obj instanceof $.Event) {
                +      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
                +    }
                +
                +    if (self.tip().hasClass('in') || self.hoverState == 'in') {
                +      self.hoverState = 'in'
                +      return
                +    }
                +
                +    clearTimeout(self.timeout)
                +
                +    self.hoverState = 'in'
                +
                +    if (!self.options.delay || !self.options.delay.show) return self.show()
                +
                +    self.timeout = setTimeout(function () {
                +      if (self.hoverState == 'in') self.show()
                +    }, self.options.delay.show)
                +  }
                +
                +  Tooltip.prototype.isInStateTrue = function () {
                +    for (var key in this.inState) {
                +      if (this.inState[key]) return true
                +    }
                +
                +    return false
                +  }
                +
                +  Tooltip.prototype.leave = function (obj) {
                +    var self = obj instanceof this.constructor ?
                +      obj : $(obj.currentTarget).data('bs.' + this.type)
                +
                +    if (!self) {
                +      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
                +      $(obj.currentTarget).data('bs.' + this.type, self)
                +    }
                +
                +    if (obj instanceof $.Event) {
                +      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
                +    }
                +
                +    if (self.isInStateTrue()) return
                +
                +    clearTimeout(self.timeout)
                +
                +    self.hoverState = 'out'
                +
                +    if (!self.options.delay || !self.options.delay.hide) return self.hide()
                +
                +    self.timeout = setTimeout(function () {
                +      if (self.hoverState == 'out') self.hide()
                +    }, self.options.delay.hide)
                +  }
                +
                +  Tooltip.prototype.show = function () {
                +    var e = $.Event('show.bs.' + this.type)
                +
                +    if (this.hasContent() && this.enabled) {
                +      this.$element.trigger(e)
                +
                +      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
                +      if (e.isDefaultPrevented() || !inDom) return
                +      var that = this
                +
                +      var $tip = this.tip()
                +
                +      var tipId = this.getUID(this.type)
                +
                +      this.setContent()
                +      $tip.attr('id', tipId)
                +      this.$element.attr('aria-describedby', tipId)
                +
                +      if (this.options.animation) $tip.addClass('fade')
                +
                +      var placement = typeof this.options.placement == 'function' ?
                +        this.options.placement.call(this, $tip[0], this.$element[0]) :
                +        this.options.placement
                +
                +      var autoToken = /\s?auto?\s?/i
                +      var autoPlace = autoToken.test(placement)
                +      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
                +
                +      $tip
                +        .detach()
                +        .css({ top: 0, left: 0, display: 'block' })
                +        .addClass(placement)
                +        .data('bs.' + this.type, this)
                +
                +      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
                +      this.$element.trigger('inserted.bs.' + this.type)
                +
                +      var pos          = this.getPosition()
                +      var actualWidth  = $tip[0].offsetWidth
                +      var actualHeight = $tip[0].offsetHeight
                +
                +      if (autoPlace) {
                +        var orgPlacement = placement
                +        var viewportDim = this.getPosition(this.$viewport)
                +
                +        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
                +                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
                +                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
                +                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
                +                    placement
                +
                +        $tip
                +          .removeClass(orgPlacement)
                +          .addClass(placement)
                +      }
                +
                +      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
                +
                +      this.applyPlacement(calculatedOffset, placement)
                +
                +      var complete = function () {
                +        var prevHoverState = that.hoverState
                +        that.$element.trigger('shown.bs.' + that.type)
                +        that.hoverState = null
                +
                +        if (prevHoverState == 'out') that.leave(that)
                +      }
                +
                +      $.support.transition && this.$tip.hasClass('fade') ?
                +        $tip
                +          .one('bsTransitionEnd', complete)
                +          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
                +        complete()
                +    }
                +  }
                +
                +  Tooltip.prototype.applyPlacement = function (offset, placement) {
                +    var $tip   = this.tip()
                +    var width  = $tip[0].offsetWidth
                +    var height = $tip[0].offsetHeight
                +
                +    // manually read margins because getBoundingClientRect includes difference
                +    var marginTop = parseInt($tip.css('margin-top'), 10)
                +    var marginLeft = parseInt($tip.css('margin-left'), 10)
                +
                +    // we must check for NaN for ie 8/9
                +    if (isNaN(marginTop))  marginTop  = 0
                +    if (isNaN(marginLeft)) marginLeft = 0
                +
                +    offset.top  += marginTop
                +    offset.left += marginLeft
                +
                +    // $.fn.offset doesn't round pixel values
                +    // so we use setOffset directly with our own function B-0
                +    $.offset.setOffset($tip[0], $.extend({
                +      using: function (props) {
                +        $tip.css({
                +          top: Math.round(props.top),
                +          left: Math.round(props.left)
                +        })
                +      }
                +    }, offset), 0)
                +
                +    $tip.addClass('in')
                +
                +    // check to see if placing tip in new offset caused the tip to resize itself
                +    var actualWidth  = $tip[0].offsetWidth
                +    var actualHeight = $tip[0].offsetHeight
                +
                +    if (placement == 'top' && actualHeight != height) {
                +      offset.top = offset.top + height - actualHeight
                +    }
                +
                +    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
                +
                +    if (delta.left) offset.left += delta.left
                +    else offset.top += delta.top
                +
                +    var isVertical          = /top|bottom/.test(placement)
                +    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
                +    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
                +
                +    $tip.offset(offset)
                +    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
                +  }
                +
                +  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
                +    this.arrow()
                +      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
                +      .css(isVertical ? 'top' : 'left', '')
                +  }
                +
                +  Tooltip.prototype.setContent = function () {
                +    var $tip  = this.tip()
                +    var title = this.getTitle()
                +
                +    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
                +    $tip.removeClass('fade in top bottom left right')
                +  }
                +
                +  Tooltip.prototype.hide = function (callback) {
                +    var that = this
                +    var $tip = $(this.$tip)
                +    var e    = $.Event('hide.bs.' + this.type)
                +
                +    function complete() {
                +      if (that.hoverState != 'in') $tip.detach()
                +      if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
                +        that.$element
                +          .removeAttr('aria-describedby')
                +          .trigger('hidden.bs.' + that.type)
                +      }
                +      callback && callback()
                +    }
                +
                +    this.$element.trigger(e)
                +
                +    if (e.isDefaultPrevented()) return
                +
                +    $tip.removeClass('in')
                +
                +    $.support.transition && $tip.hasClass('fade') ?
                +      $tip
                +        .one('bsTransitionEnd', complete)
                +        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
                +      complete()
                +
                +    this.hoverState = null
                +
                +    return this
                +  }
                +
                +  Tooltip.prototype.fixTitle = function () {
                +    var $e = this.$element
                +    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
                +      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
                +    }
                +  }
                +
                +  Tooltip.prototype.hasContent = function () {
                +    return this.getTitle()
                +  }
                +
                +  Tooltip.prototype.getPosition = function ($element) {
                +    $element   = $element || this.$element
                +
                +    var el     = $element[0]
                +    var isBody = el.tagName == 'BODY'
                +
                +    var elRect    = el.getBoundingClientRect()
                +    if (elRect.width == null) {
                +      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
                +      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
                +    }
                +    var isSvg = window.SVGElement && el instanceof window.SVGElement
                +    // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
                +    // See https://github.com/twbs/bootstrap/issues/20280
                +    var elOffset  = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
                +    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
                +    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
                +
                +    return $.extend({}, elRect, scroll, outerDims, elOffset)
                +  }
                +
                +  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
                +    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
                +           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
                +           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
                +        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
                +
                +  }
                +
                +  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
                +    var delta = { top: 0, left: 0 }
                +    if (!this.$viewport) return delta
                +
                +    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
                +    var viewportDimensions = this.getPosition(this.$viewport)
                +
                +    if (/right|left/.test(placement)) {
                +      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
                +      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
                +      if (topEdgeOffset < viewportDimensions.top) { // top overflow
                +        delta.top = viewportDimensions.top - topEdgeOffset
                +      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
                +        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
                +      }
                +    } else {
                +      var leftEdgeOffset  = pos.left - viewportPadding
                +      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
                +      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
                +        delta.left = viewportDimensions.left - leftEdgeOffset
                +      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
                +        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
                +      }
                +    }
                +
                +    return delta
                +  }
                +
                +  Tooltip.prototype.getTitle = function () {
                +    var title
                +    var $e = this.$element
                +    var o  = this.options
                +
                +    title = $e.attr('data-original-title')
                +      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
                +
                +    return title
                +  }
                +
                +  Tooltip.prototype.getUID = function (prefix) {
                +    do prefix += ~~(Math.random() * 1000000)
                +    while (document.getElementById(prefix))
                +    return prefix
                +  }
                +
                +  Tooltip.prototype.tip = function () {
                +    if (!this.$tip) {
                +      this.$tip = $(this.options.template)
                +      if (this.$tip.length != 1) {
                +        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
                +      }
                +    }
                +    return this.$tip
                +  }
                +
                +  Tooltip.prototype.arrow = function () {
                +    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
                +  }
                +
                +  Tooltip.prototype.enable = function () {
                +    this.enabled = true
                +  }
                +
                +  Tooltip.prototype.disable = function () {
                +    this.enabled = false
                +  }
                +
                +  Tooltip.prototype.toggleEnabled = function () {
                +    this.enabled = !this.enabled
                +  }
                +
                +  Tooltip.prototype.toggle = function (e) {
                +    var self = this
                +    if (e) {
                +      self = $(e.currentTarget).data('bs.' + this.type)
                +      if (!self) {
                +        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
                +        $(e.currentTarget).data('bs.' + this.type, self)
                +      }
                +    }
                +
                +    if (e) {
                +      self.inState.click = !self.inState.click
                +      if (self.isInStateTrue()) self.enter(self)
                +      else self.leave(self)
                +    } else {
                +      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
                +    }
                +  }
                +
                +  Tooltip.prototype.destroy = function () {
                +    var that = this
                +    clearTimeout(this.timeout)
                +    this.hide(function () {
                +      that.$element.off('.' + that.type).removeData('bs.' + that.type)
                +      if (that.$tip) {
                +        that.$tip.detach()
                +      }
                +      that.$tip = null
                +      that.$arrow = null
                +      that.$viewport = null
                +      that.$element = null
                +    })
                +  }
                +
                +
                +  // TOOLTIP PLUGIN DEFINITION
                +  // =========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.tooltip')
                +      var options = typeof option == 'object' && option
                +
                +      if (!data && /destroy|hide/.test(option)) return
                +      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.tooltip
                +
                +  $.fn.tooltip             = Plugin
                +  $.fn.tooltip.Constructor = Tooltip
                +
                +
                +  // TOOLTIP NO CONFLICT
                +  // ===================
                +
                +  $.fn.tooltip.noConflict = function () {
                +    $.fn.tooltip = old
                +    return this
                +  }
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: popover.js v3.3.7
                + * http://getbootstrap.com/javascript/#popovers
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // POPOVER PUBLIC CLASS DEFINITION
                +  // ===============================
                +
                +  var Popover = function (element, options) {
                +    this.init('popover', element, options)
                +  }
                +
                +  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
                +
                +  Popover.VERSION  = '3.3.7'
                +
                +  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
                +    placement: 'right',
                +    trigger: 'click',
                +    content: '',
                +    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
                +  })
                +
                +
                +  // NOTE: POPOVER EXTENDS tooltip.js
                +  // ================================
                +
                +  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
                +
                +  Popover.prototype.constructor = Popover
                +
                +  Popover.prototype.getDefaults = function () {
                +    return Popover.DEFAULTS
                +  }
                +
                +  Popover.prototype.setContent = function () {
                +    var $tip    = this.tip()
                +    var title   = this.getTitle()
                +    var content = this.getContent()
                +
                +    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
                +    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
                +      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
                +    ](content)
                +
                +    $tip.removeClass('fade top bottom left right in')
                +
                +    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
                +    // this manually by checking the contents.
                +    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
                +  }
                +
                +  Popover.prototype.hasContent = function () {
                +    return this.getTitle() || this.getContent()
                +  }
                +
                +  Popover.prototype.getContent = function () {
                +    var $e = this.$element
                +    var o  = this.options
                +
                +    return $e.attr('data-content')
                +      || (typeof o.content == 'function' ?
                +            o.content.call($e[0]) :
                +            o.content)
                +  }
                +
                +  Popover.prototype.arrow = function () {
                +    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
                +  }
                +
                +
                +  // POPOVER PLUGIN DEFINITION
                +  // =========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.popover')
                +      var options = typeof option == 'object' && option
                +
                +      if (!data && /destroy|hide/.test(option)) return
                +      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.popover
                +
                +  $.fn.popover             = Plugin
                +  $.fn.popover.Constructor = Popover
                +
                +
                +  // POPOVER NO CONFLICT
                +  // ===================
                +
                +  $.fn.popover.noConflict = function () {
                +    $.fn.popover = old
                +    return this
                +  }
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: scrollspy.js v3.3.7
                + * http://getbootstrap.com/javascript/#scrollspy
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // SCROLLSPY CLASS DEFINITION
                +  // ==========================
                +
                +  function ScrollSpy(element, options) {
                +    this.$body          = $(document.body)
                +    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
                +    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
                +    this.selector       = (this.options.target || '') + ' .nav li > a'
                +    this.offsets        = []
                +    this.targets        = []
                +    this.activeTarget   = null
                +    this.scrollHeight   = 0
                +
                +    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
                +    this.refresh()
                +    this.process()
                +  }
                +
                +  ScrollSpy.VERSION  = '3.3.7'
                +
                +  ScrollSpy.DEFAULTS = {
                +    offset: 10
                +  }
                +
                +  ScrollSpy.prototype.getScrollHeight = function () {
                +    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
                +  }
                +
                +  ScrollSpy.prototype.refresh = function () {
                +    var that          = this
                +    var offsetMethod  = 'offset'
                +    var offsetBase    = 0
                +
                +    this.offsets      = []
                +    this.targets      = []
                +    this.scrollHeight = this.getScrollHeight()
                +
                +    if (!$.isWindow(this.$scrollElement[0])) {
                +      offsetMethod = 'position'
                +      offsetBase   = this.$scrollElement.scrollTop()
                +    }
                +
                +    this.$body
                +      .find(this.selector)
                +      .map(function () {
                +        var $el   = $(this)
                +        var href  = $el.data('target') || $el.attr('href')
                +        var $href = /^#./.test(href) && $(href)
                +
                +        return ($href
                +          && $href.length
                +          && $href.is(':visible')
                +          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
                +      })
                +      .sort(function (a, b) { return a[0] - b[0] })
                +      .each(function () {
                +        that.offsets.push(this[0])
                +        that.targets.push(this[1])
                +      })
                +  }
                +
                +  ScrollSpy.prototype.process = function () {
                +    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
                +    var scrollHeight = this.getScrollHeight()
                +    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
                +    var offsets      = this.offsets
                +    var targets      = this.targets
                +    var activeTarget = this.activeTarget
                +    var i
                +
                +    if (this.scrollHeight != scrollHeight) {
                +      this.refresh()
                +    }
                +
                +    if (scrollTop >= maxScroll) {
                +      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
                +    }
                +
                +    if (activeTarget && scrollTop < offsets[0]) {
                +      this.activeTarget = null
                +      return this.clear()
                +    }
                +
                +    for (i = offsets.length; i--;) {
                +      activeTarget != targets[i]
                +        && scrollTop >= offsets[i]
                +        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
                +        && this.activate(targets[i])
                +    }
                +  }
                +
                +  ScrollSpy.prototype.activate = function (target) {
                +    this.activeTarget = target
                +
                +    this.clear()
                +
                +    var selector = this.selector +
                +      '[data-target="' + target + '"],' +
                +      this.selector + '[href="' + target + '"]'
                +
                +    var active = $(selector)
                +      .parents('li')
                +      .addClass('active')
                +
                +    if (active.parent('.dropdown-menu').length) {
                +      active = active
                +        .closest('li.dropdown')
                +        .addClass('active')
                +    }
                +
                +    active.trigger('activate.bs.scrollspy')
                +  }
                +
                +  ScrollSpy.prototype.clear = function () {
                +    $(this.selector)
                +      .parentsUntil(this.options.target, '.active')
                +      .removeClass('active')
                +  }
                +
                +
                +  // SCROLLSPY PLUGIN DEFINITION
                +  // ===========================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.scrollspy')
                +      var options = typeof option == 'object' && option
                +
                +      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.scrollspy
                +
                +  $.fn.scrollspy             = Plugin
                +  $.fn.scrollspy.Constructor = ScrollSpy
                +
                +
                +  // SCROLLSPY NO CONFLICT
                +  // =====================
                +
                +  $.fn.scrollspy.noConflict = function () {
                +    $.fn.scrollspy = old
                +    return this
                +  }
                +
                +
                +  // SCROLLSPY DATA-API
                +  // ==================
                +
                +  $(window).on('load.bs.scrollspy.data-api', function () {
                +    $('[data-spy="scroll"]').each(function () {
                +      var $spy = $(this)
                +      Plugin.call($spy, $spy.data())
                +    })
                +  })
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: tab.js v3.3.7
                + * http://getbootstrap.com/javascript/#tabs
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // TAB CLASS DEFINITION
                +  // ====================
                +
                +  var Tab = function (element) {
                +    // jscs:disable requireDollarBeforejQueryAssignment
                +    this.element = $(element)
                +    // jscs:enable requireDollarBeforejQueryAssignment
                +  }
                +
                +  Tab.VERSION = '3.3.7'
                +
                +  Tab.TRANSITION_DURATION = 150
                +
                +  Tab.prototype.show = function () {
                +    var $this    = this.element
                +    var $ul      = $this.closest('ul:not(.dropdown-menu)')
                +    var selector = $this.data('target')
                +
                +    if (!selector) {
                +      selector = $this.attr('href')
                +      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
                +    }
                +
                +    if ($this.parent('li').hasClass('active')) return
                +
                +    var $previous = $ul.find('.active:last a')
                +    var hideEvent = $.Event('hide.bs.tab', {
                +      relatedTarget: $this[0]
                +    })
                +    var showEvent = $.Event('show.bs.tab', {
                +      relatedTarget: $previous[0]
                +    })
                +
                +    $previous.trigger(hideEvent)
                +    $this.trigger(showEvent)
                +
                +    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
                +
                +    var $target = $(selector)
                +
                +    this.activate($this.closest('li'), $ul)
                +    this.activate($target, $target.parent(), function () {
                +      $previous.trigger({
                +        type: 'hidden.bs.tab',
                +        relatedTarget: $this[0]
                +      })
                +      $this.trigger({
                +        type: 'shown.bs.tab',
                +        relatedTarget: $previous[0]
                +      })
                +    })
                +  }
                +
                +  Tab.prototype.activate = function (element, container, callback) {
                +    var $active    = container.find('> .active')
                +    var transition = callback
                +      && $.support.transition
                +      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
                +
                +    function next() {
                +      $active
                +        .removeClass('active')
                +        .find('> .dropdown-menu > .active')
                +          .removeClass('active')
                +        .end()
                +        .find('[data-toggle="tab"]')
                +          .attr('aria-expanded', false)
                +
                +      element
                +        .addClass('active')
                +        .find('[data-toggle="tab"]')
                +          .attr('aria-expanded', true)
                +
                +      if (transition) {
                +        element[0].offsetWidth // reflow for transition
                +        element.addClass('in')
                +      } else {
                +        element.removeClass('fade')
                +      }
                +
                +      if (element.parent('.dropdown-menu').length) {
                +        element
                +          .closest('li.dropdown')
                +            .addClass('active')
                +          .end()
                +          .find('[data-toggle="tab"]')
                +            .attr('aria-expanded', true)
                +      }
                +
                +      callback && callback()
                +    }
                +
                +    $active.length && transition ?
                +      $active
                +        .one('bsTransitionEnd', next)
                +        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
                +      next()
                +
                +    $active.removeClass('in')
                +  }
                +
                +
                +  // TAB PLUGIN DEFINITION
                +  // =====================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this = $(this)
                +      var data  = $this.data('bs.tab')
                +
                +      if (!data) $this.data('bs.tab', (data = new Tab(this)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.tab
                +
                +  $.fn.tab             = Plugin
                +  $.fn.tab.Constructor = Tab
                +
                +
                +  // TAB NO CONFLICT
                +  // ===============
                +
                +  $.fn.tab.noConflict = function () {
                +    $.fn.tab = old
                +    return this
                +  }
                +
                +
                +  // TAB DATA-API
                +  // ============
                +
                +  var clickHandler = function (e) {
                +    e.preventDefault()
                +    Plugin.call($(this), 'show')
                +  }
                +
                +  $(document)
                +    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
                +    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
                +
                +}(jQuery);
                +
                +/* ========================================================================
                + * Bootstrap: affix.js v3.3.7
                + * http://getbootstrap.com/javascript/#affix
                + * ========================================================================
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
                + * ======================================================================== */
                +
                +
                ++function ($) {
                +  'use strict';
                +
                +  // AFFIX CLASS DEFINITION
                +  // ======================
                +
                +  var Affix = function (element, options) {
                +    this.options = $.extend({}, Affix.DEFAULTS, options)
                +
                +    this.$target = $(this.options.target)
                +      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
                +      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
                +
                +    this.$element     = $(element)
                +    this.affixed      = null
                +    this.unpin        = null
                +    this.pinnedOffset = null
                +
                +    this.checkPosition()
                +  }
                +
                +  Affix.VERSION  = '3.3.7'
                +
                +  Affix.RESET    = 'affix affix-top affix-bottom'
                +
                +  Affix.DEFAULTS = {
                +    offset: 0,
                +    target: window
                +  }
                +
                +  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
                +    var scrollTop    = this.$target.scrollTop()
                +    var position     = this.$element.offset()
                +    var targetHeight = this.$target.height()
                +
                +    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
                +
                +    if (this.affixed == 'bottom') {
                +      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
                +      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
                +    }
                +
                +    var initializing   = this.affixed == null
                +    var colliderTop    = initializing ? scrollTop : position.top
                +    var colliderHeight = initializing ? targetHeight : height
                +
                +    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
                +    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
                +
                +    return false
                +  }
                +
                +  Affix.prototype.getPinnedOffset = function () {
                +    if (this.pinnedOffset) return this.pinnedOffset
                +    this.$element.removeClass(Affix.RESET).addClass('affix')
                +    var scrollTop = this.$target.scrollTop()
                +    var position  = this.$element.offset()
                +    return (this.pinnedOffset = position.top - scrollTop)
                +  }
                +
                +  Affix.prototype.checkPositionWithEventLoop = function () {
                +    setTimeout($.proxy(this.checkPosition, this), 1)
                +  }
                +
                +  Affix.prototype.checkPosition = function () {
                +    if (!this.$element.is(':visible')) return
                +
                +    var height       = this.$element.height()
                +    var offset       = this.options.offset
                +    var offsetTop    = offset.top
                +    var offsetBottom = offset.bottom
                +    var scrollHeight = Math.max($(document).height(), $(document.body).height())
                +
                +    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
                +    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
                +    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
                +
                +    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
                +
                +    if (this.affixed != affix) {
                +      if (this.unpin != null) this.$element.css('top', '')
                +
                +      var affixType = 'affix' + (affix ? '-' + affix : '')
                +      var e         = $.Event(affixType + '.bs.affix')
                +
                +      this.$element.trigger(e)
                +
                +      if (e.isDefaultPrevented()) return
                +
                +      this.affixed = affix
                +      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
                +
                +      this.$element
                +        .removeClass(Affix.RESET)
                +        .addClass(affixType)
                +        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
                +    }
                +
                +    if (affix == 'bottom') {
                +      this.$element.offset({
                +        top: scrollHeight - height - offsetBottom
                +      })
                +    }
                +  }
                +
                +
                +  // AFFIX PLUGIN DEFINITION
                +  // =======================
                +
                +  function Plugin(option) {
                +    return this.each(function () {
                +      var $this   = $(this)
                +      var data    = $this.data('bs.affix')
                +      var options = typeof option == 'object' && option
                +
                +      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
                +      if (typeof option == 'string') data[option]()
                +    })
                +  }
                +
                +  var old = $.fn.affix
                +
                +  $.fn.affix             = Plugin
                +  $.fn.affix.Constructor = Affix
                +
                +
                +  // AFFIX NO CONFLICT
                +  // =================
                +
                +  $.fn.affix.noConflict = function () {
                +    $.fn.affix = old
                +    return this
                +  }
                +
                +
                +  // AFFIX DATA-API
                +  // ==============
                +
                +  $(window).on('load', function () {
                +    $('[data-spy="affix"]').each(function () {
                +      var $spy = $(this)
                +      var data = $spy.data()
                +
                +      data.offset = data.offset || {}
                +
                +      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
                +      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
                +
                +      Plugin.call($spy, data)
                +    })
                +  })
                +
                +}(jQuery);
                diff --git a/blockly/webif/static/js/bootstrap.min.js b/blockly/webif/static/js/bootstrap.min.js
                new file mode 100644
                index 000000000..9bcd2fcca
                --- /dev/null
                +++ b/blockly/webif/static/js/bootstrap.min.js
                @@ -0,0 +1,7 @@
                +/*!
                + * Bootstrap v3.3.7 (http://getbootstrap.com)
                + * Copyright 2011-2016 Twitter, Inc.
                + * Licensed under the MIT license
                + */
                +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
                +this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/google-prettify/lang-aea.js b/blockly/webif/static/js/google-prettify/lang-aea.js
                new file mode 100644
                index 000000000..784ebb29c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-aea.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Onno Hommes.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
                +null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-agc.js b/blockly/webif/static/js/google-prettify/lang-agc.js
                new file mode 100644
                index 000000000..784ebb29c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-agc.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Onno Hommes.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
                +null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-apollo.js b/blockly/webif/static/js/google-prettify/lang-apollo.js
                new file mode 100644
                index 000000000..784ebb29c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-apollo.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Onno Hommes.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
                +null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["apollo","agc","aea"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-basic.js b/blockly/webif/static/js/google-prettify/lang-basic.js
                new file mode 100644
                index 000000000..2d6151dc7
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-basic.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2013 Peter Kofler
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:"(?:[^\\"\r\n]|\\.)*(?:"|$))/,null,'"'],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["com",/^REM[^\r\n]*/,null],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,null],["pln",/^[A-Z][A-Z0-9]?(?:\$|%)?/i,null],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?/i,
                +null,"0123456789"],["pun",/^.[^\s\w\.$%"]*/,null]]),["basic","cbm"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-cbm.js b/blockly/webif/static/js/google-prettify/lang-cbm.js
                new file mode 100644
                index 000000000..2d6151dc7
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-cbm.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2013 Peter Kofler
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:"(?:[^\\"\r\n]|\\.)*(?:"|$))/,null,'"'],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["com",/^REM[^\r\n]*/,null],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,null],["pln",/^[A-Z][A-Z0-9]?(?:\$|%)?/i,null],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?/i,
                +null,"0123456789"],["pun",/^.[^\s\w\.$%"]*/,null]]),["basic","cbm"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-cl.js b/blockly/webif/static/js/google-prettify/lang-cl.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-cl.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-clj.js b/blockly/webif/static/js/google-prettify/lang-clj.js
                new file mode 100644
                index 000000000..d1173b1e1
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-clj.js
                @@ -0,0 +1,17 @@
                +/*
                + Copyright (C) 2011 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[\(\{\[]+/,null,"([{"],["clo",/^[\)\}\]]+/,null,")]}"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,
                +null],["typ",/^:[0-9a-zA-Z\-]+/]]),["clj"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-css.js b/blockly/webif/static/js/google-prettify/lang-css.js
                new file mode 100644
                index 000000000..90d175da0
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-css.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[["str",/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],["str",/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']+)\)/i],["kwd",/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],
                +["com",/^(?:\x3c!--|--\x3e)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#(?:[0-9a-f]{3}){1,2}\b/i],["pln",/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],["pun",/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^\)\"\']+/]]),["css-str"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-dart.js b/blockly/webif/static/js/google-prettify/lang-dart.js
                new file mode 100644
                index 000000000..da142a4e4
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-dart.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2013 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"]],[["com",/^#!(?:.*)/],["kwd",/^\b(?:import|library|part of|part|as|show|hide)\b/i],["com",/^\/\/(?:.*)/],["com",/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],["kwd",/^\b(?:class|interface)\b/i],["kwd",/^\b(?:assert|async|await|break|case|catch|continue|default|do|else|finally|for|if|in|is|new|return|super|switch|sync|this|throw|try|while)\b/i],["kwd",/^\b(?:abstract|const|extends|factory|final|get|implements|native|operator|set|static|typedef|var)\b/i],
                +["typ",/^\b(?:bool|double|Dynamic|int|num|Object|String|void)\b/i],["kwd",/^\b(?:false|null|true)\b/i],["str",/^r?[\']{3}[\s|\S]*?[^\\][\']{3}/],["str",/^r?[\"]{3}[\s|\S]*?[^\\][\"]{3}/],["str",/^r?\'(\'|(?:[^\n\r\f])*?[^\\]\')/],["str",/^r?\"(\"|(?:[^\n\r\f])*?[^\\]\")/],["typ",/^[A-Z]\w*/],["pln",/^[a-z_$][a-z0-9_]*/i],["pun",/^[~!%^&*+=|?:<>/-]/],["lit",/^\b0x[0-9a-f]+/i],["lit",/^\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i],["lit",
                +/^\b\.\d+(?:e[+-]?\d+)?/i],["pun",/^[(){}\[\],.;]/]]),["dart"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-el.js b/blockly/webif/static/js/google-prettify/lang-el.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-el.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-erl.js b/blockly/webif/static/js/google-prettify/lang-erl.js
                new file mode 100644
                index 000000000..e7da9b041
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-erl.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2013 Andrew Allen
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\x0B\x0C\r ]+/,null,"\t\n\x0B\f\r "],["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["lit",/^[a-z][a-zA-Z0-9_]*/],["lit",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])+\'?/,null,"'"],["lit",/^\?[^ \t\n({]+/,null,"?"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\n]*/],["kwd",/^(?:module|attributes|do|let|in|letrec|apply|call|primop|case|of|end|when|fun|try|catch|receive|after|char|integer|float,atom,string,var)\b/],
                +["kwd",/^-[a-z_]+/],["typ",/^[A-Z_][a-zA-Z0-9_]*/],["pun",/^[.,;]/]]),["erlang","erl"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-erlang.js b/blockly/webif/static/js/google-prettify/lang-erlang.js
                new file mode 100644
                index 000000000..e7da9b041
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-erlang.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2013 Andrew Allen
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\x0B\x0C\r ]+/,null,"\t\n\x0B\f\r "],["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["lit",/^[a-z][a-zA-Z0-9_]*/],["lit",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])+\'?/,null,"'"],["lit",/^\?[^ \t\n({]+/,null,"?"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\n]*/],["kwd",/^(?:module|attributes|do|let|in|letrec|apply|call|primop|case|of|end|when|fun|try|catch|receive|after|char|integer|float,atom,string,var)\b/],
                +["kwd",/^-[a-z_]+/],["typ",/^[A-Z_][a-zA-Z0-9_]*/],["pun",/^[.,;]/]]),["erlang","erl"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-fs.js b/blockly/webif/static/js/google-prettify/lang-fs.js
                new file mode 100644
                index 000000000..c012a3ff4
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-fs.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])(?:\'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
                +["lit",/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^(?:[a-z_][\w']*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],["pun",/^[^\t\n\r \xA0\"\'\w]+/]]),["fs","ml"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-go.js b/blockly/webif/static/js/google-prettify/lang-go.js
                new file mode 100644
                index 000000000..1f6934a4f
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-go.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2010 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["pln",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])+(?:\'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\r\n]*|\/\*[\s\S]*?\*\/)/],["pln",/^(?:[^\/\"\'`]|\/(?![\/\*]))+/i]]),["go"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-hs.js b/blockly/webif/static/js/google-prettify/lang-hs.js
                new file mode 100644
                index 000000000..2002221e5
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-hs.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\x0B\x0C\r ]+/,null,"\t\n\x0B\f\r "],["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,
                +null],["pln",/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],["pun",/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),["hs"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-lasso.js b/blockly/webif/static/js/google-prettify/lang-lasso.js
                new file mode 100644
                index 000000000..415ca6777
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lasso.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2013 Eric Knibbe
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\`[^\`]*(?:\`|$)/,null,"`"],["lit",/^0x[\da-f]+|\d+/i,null,"0123456789"],["atn",/^#\d+|[#$][a-z_][\w.]*|#![ \S]+lasso9\b/i,null,"#$"]],[["tag",/^[[\]]|<\?(?:lasso(?:script)?|=)|\?>|noprocess\b|no_square_brackets\b/i],["com",/^\/\/[^\r\n]*|\/\*[\s\S]*?\*\//],
                +["atn",/^-(?!infinity)[a-z_][\w.]*|\.\s*'[a-z_][\w.]*'/i],["lit",/^\d*\.\d+(?:e[-+]?\d+)?|infinity\b|NaN\b/i],["atv",/^::\s*[a-z_][\w.]*/i],["lit",/^(?:true|false|none|minimal|full|all|void|and|or|not|bw|nbw|ew|new|cn|ncn|lt|lte|gt|gte|eq|neq|rx|nrx|ft)\b/i],["kwd",/^(?:error_code|error_msg|error_pop|error_push|error_reset|cache|database_names|database_schemanames|database_tablenames|define_tag|define_type|email_batch|encode_set|html_comment|handle|handle_error|header|if|inline|iterate|ljax_target|link|link_currentaction|link_currentgroup|link_currentrecord|link_detail|link_firstgroup|link_firstrecord|link_lastgroup|link_lastrecord|link_nextgroup|link_nextrecord|link_prevgroup|link_prevrecord|log|loop|namespace_using|output_none|portal|private|protect|records|referer|referrer|repeating|resultset|rows|search_args|search_arguments|select|sort_args|sort_arguments|thread_atomic|value_list|while|abort|case|else|if_empty|if_false|if_null|if_true|loop_abort|loop_continue|loop_count|params|params_up|return|return_value|run_children|soap_definetag|soap_lastrequest|soap_lastresponse|tag_name|ascending|average|by|define|descending|do|equals|frozen|group|handle_failure|import|in|into|join|let|match|max|min|on|order|parent|protected|provide|public|require|returnhome|skip|split_thread|sum|take|thread|to|trait|type|where|with|yield|yieldhome)\b/i],
                +["typ",/^(?:array|date|decimal|duration|integer|map|pair|string|tag|xml|null|boolean|bytes|keyword|list|locale|queue|set|stack|staticarray|local|var|variable|global|data|self|inherited|currentcapture|givenblock)\b|^\.\.?/i],["pln",/^[a-z_][\w.]*(?:=\s*(?=\())?/i],["pun",/^:=|[-+*\/%=<>&|!?\\]/]]),["lasso","ls","lassoscript"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-lassoscript.js b/blockly/webif/static/js/google-prettify/lang-lassoscript.js
                new file mode 100644
                index 000000000..415ca6777
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lassoscript.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2013 Eric Knibbe
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\`[^\`]*(?:\`|$)/,null,"`"],["lit",/^0x[\da-f]+|\d+/i,null,"0123456789"],["atn",/^#\d+|[#$][a-z_][\w.]*|#![ \S]+lasso9\b/i,null,"#$"]],[["tag",/^[[\]]|<\?(?:lasso(?:script)?|=)|\?>|noprocess\b|no_square_brackets\b/i],["com",/^\/\/[^\r\n]*|\/\*[\s\S]*?\*\//],
                +["atn",/^-(?!infinity)[a-z_][\w.]*|\.\s*'[a-z_][\w.]*'/i],["lit",/^\d*\.\d+(?:e[-+]?\d+)?|infinity\b|NaN\b/i],["atv",/^::\s*[a-z_][\w.]*/i],["lit",/^(?:true|false|none|minimal|full|all|void|and|or|not|bw|nbw|ew|new|cn|ncn|lt|lte|gt|gte|eq|neq|rx|nrx|ft)\b/i],["kwd",/^(?:error_code|error_msg|error_pop|error_push|error_reset|cache|database_names|database_schemanames|database_tablenames|define_tag|define_type|email_batch|encode_set|html_comment|handle|handle_error|header|if|inline|iterate|ljax_target|link|link_currentaction|link_currentgroup|link_currentrecord|link_detail|link_firstgroup|link_firstrecord|link_lastgroup|link_lastrecord|link_nextgroup|link_nextrecord|link_prevgroup|link_prevrecord|log|loop|namespace_using|output_none|portal|private|protect|records|referer|referrer|repeating|resultset|rows|search_args|search_arguments|select|sort_args|sort_arguments|thread_atomic|value_list|while|abort|case|else|if_empty|if_false|if_null|if_true|loop_abort|loop_continue|loop_count|params|params_up|return|return_value|run_children|soap_definetag|soap_lastrequest|soap_lastresponse|tag_name|ascending|average|by|define|descending|do|equals|frozen|group|handle_failure|import|in|into|join|let|match|max|min|on|order|parent|protected|provide|public|require|returnhome|skip|split_thread|sum|take|thread|to|trait|type|where|with|yield|yieldhome)\b/i],
                +["typ",/^(?:array|date|decimal|duration|integer|map|pair|string|tag|xml|null|boolean|bytes|keyword|list|locale|queue|set|stack|staticarray|local|var|variable|global|data|self|inherited|currentcapture|givenblock)\b|^\.\.?/i],["pln",/^[a-z_][\w.]*(?:=\s*(?=\())?/i],["pun",/^:=|[-+*\/%=<>&|!?\\]/]]),["lasso","ls","lassoscript"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-latex.js b/blockly/webif/static/js/google-prettify/lang-latex.js
                new file mode 100644
                index 000000000..efc758cd9
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-latex.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2011 Martin S.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\r\n]*/,null,"%"]],[["kwd",/^\\[a-zA-Z@]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[{}()\[\]=]+/]]),["latex","tex"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-lgt.js b/blockly/webif/static/js/google-prettify/lang-lgt.js
                new file mode 100644
                index 000000000..2959d759c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lgt.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2014 Paulo Moura
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["lit",/^[a-z][a-zA-Z0-9_]*/],["lit",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])+\'?/,null,"'"],["lit",/^(?:0'.|0b[0-1]+|0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\r\n]*/,null,"%"],["com",/^\/\*[\s\S]*?\*\//],["kwd",/^\s*:-\s(c(a(lls|tegory)|oinductive)|p(ublic|r(ot(ocol|ected)|ivate))|e(l(if|se)|n(coding|sure_loaded)|xport)|i(f|n(clude|itialization|fo))|alias|d(ynamic|iscontiguous)|m(eta_(non_terminal|predicate)|od(e|ule)|ultifile)|reexport|s(et_(logtalk|prolog)_flag|ynchronized)|o(bject|p)|use(s|_module))/],
                +["kwd",/^\s*:-\s(e(lse|nd(if|_(category|object|protocol)))|built_in|dynamic|synchronized|threaded)/],["typ",/^[A-Z_][a-zA-Z0-9_]*/],["pun",/^[.,;{}:^<>=\\/+*?#!-]/]]),["logtalk","lgt"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-lisp.js b/blockly/webif/static/js/google-prettify/lang-lisp.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lisp.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-ll.js b/blockly/webif/static/js/google-prettify/lang-ll.js
                new file mode 100644
                index 000000000..7604d9625
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-ll.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2013 Nikhil Dabas
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^!?\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["com",/^;[^\r\n]*/,null,";"]],[["pln",/^[%@!](?:[-a-zA-Z$._][-a-zA-Z$._0-9]*|\d+)/],["kwd",/^[A-Za-z_][0-9A-Za-z_]*/,null],["lit",/^\d+\.\d+/],["lit",/^(?:\d+|0[xX][a-fA-F0-9]+)/],["pun",/^[()\[\]{},=*<>:]|\.\.\.$/]]),["llvm","ll"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-llvm.js b/blockly/webif/static/js/google-prettify/lang-llvm.js
                new file mode 100644
                index 000000000..7604d9625
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-llvm.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2013 Nikhil Dabas
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^!?\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["com",/^;[^\r\n]*/,null,";"]],[["pln",/^[%@!](?:[-a-zA-Z$._][-a-zA-Z$._0-9]*|\d+)/],["kwd",/^[A-Za-z_][0-9A-Za-z_]*/,null],["lit",/^\d+\.\d+/],["lit",/^(?:\d+|0[xX][a-fA-F0-9]+)/],["pun",/^[()\[\]{},=*<>:]|\.\.\.$/]]),["llvm","ll"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-logtalk.js b/blockly/webif/static/js/google-prettify/lang-logtalk.js
                new file mode 100644
                index 000000000..2959d759c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-logtalk.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2014 Paulo Moura
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'"'],["lit",/^[a-z][a-zA-Z0-9_]*/],["lit",/^\'(?:[^\'\\\n\x0C\r]|\\[^&])+\'?/,null,"'"],["lit",/^(?:0'.|0b[0-1]+|0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\r\n]*/,null,"%"],["com",/^\/\*[\s\S]*?\*\//],["kwd",/^\s*:-\s(c(a(lls|tegory)|oinductive)|p(ublic|r(ot(ocol|ected)|ivate))|e(l(if|se)|n(coding|sure_loaded)|xport)|i(f|n(clude|itialization|fo))|alias|d(ynamic|iscontiguous)|m(eta_(non_terminal|predicate)|od(e|ule)|ultifile)|reexport|s(et_(logtalk|prolog)_flag|ynchronized)|o(bject|p)|use(s|_module))/],
                +["kwd",/^\s*:-\s(e(lse|nd(if|_(category|object|protocol)))|built_in|dynamic|synchronized|threaded)/],["typ",/^[A-Z_][a-zA-Z0-9_]*/],["pun",/^[.,;{}:^<>=\\/+*?#!-]/]]),["logtalk","lgt"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-ls.js b/blockly/webif/static/js/google-prettify/lang-ls.js
                new file mode 100644
                index 000000000..415ca6777
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-ls.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2013 Eric Knibbe
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\`[^\`]*(?:\`|$)/,null,"`"],["lit",/^0x[\da-f]+|\d+/i,null,"0123456789"],["atn",/^#\d+|[#$][a-z_][\w.]*|#![ \S]+lasso9\b/i,null,"#$"]],[["tag",/^[[\]]|<\?(?:lasso(?:script)?|=)|\?>|noprocess\b|no_square_brackets\b/i],["com",/^\/\/[^\r\n]*|\/\*[\s\S]*?\*\//],
                +["atn",/^-(?!infinity)[a-z_][\w.]*|\.\s*'[a-z_][\w.]*'/i],["lit",/^\d*\.\d+(?:e[-+]?\d+)?|infinity\b|NaN\b/i],["atv",/^::\s*[a-z_][\w.]*/i],["lit",/^(?:true|false|none|minimal|full|all|void|and|or|not|bw|nbw|ew|new|cn|ncn|lt|lte|gt|gte|eq|neq|rx|nrx|ft)\b/i],["kwd",/^(?:error_code|error_msg|error_pop|error_push|error_reset|cache|database_names|database_schemanames|database_tablenames|define_tag|define_type|email_batch|encode_set|html_comment|handle|handle_error|header|if|inline|iterate|ljax_target|link|link_currentaction|link_currentgroup|link_currentrecord|link_detail|link_firstgroup|link_firstrecord|link_lastgroup|link_lastrecord|link_nextgroup|link_nextrecord|link_prevgroup|link_prevrecord|log|loop|namespace_using|output_none|portal|private|protect|records|referer|referrer|repeating|resultset|rows|search_args|search_arguments|select|sort_args|sort_arguments|thread_atomic|value_list|while|abort|case|else|if_empty|if_false|if_null|if_true|loop_abort|loop_continue|loop_count|params|params_up|return|return_value|run_children|soap_definetag|soap_lastrequest|soap_lastresponse|tag_name|ascending|average|by|define|descending|do|equals|frozen|group|handle_failure|import|in|into|join|let|match|max|min|on|order|parent|protected|provide|public|require|returnhome|skip|split_thread|sum|take|thread|to|trait|type|where|with|yield|yieldhome)\b/i],
                +["typ",/^(?:array|date|decimal|duration|integer|map|pair|string|tag|xml|null|boolean|bytes|keyword|list|locale|queue|set|stack|staticarray|local|var|variable|global|data|self|inherited|currentcapture|givenblock)\b|^\.\.?/i],["pln",/^[a-z_][\w.]*(?:=\s*(?=\())?/i],["pun",/^:=|[-+*\/%=<>&|!?\\]/]]),["lasso","ls","lassoscript"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-lsp.js b/blockly/webif/static/js/google-prettify/lang-lsp.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lsp.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-lua.js b/blockly/webif/static/js/google-prettify/lang-lua.js
                new file mode 100644
                index 000000000..afb2901e4
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-lua.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],["str",/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],
                +["pln",/^[a-z_]\w*/i],["pun",/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),["lua"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-matlab.js b/blockly/webif/static/js/google-prettify/lang-matlab.js
                new file mode 100644
                index 000000000..a0522a5a7
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-matlab.js
                @@ -0,0 +1,29 @@
                +/*
                +
                + Copyright (c) 2013 by Amro <amroamroamro@gmail.com>
                +
                + 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.
                +*/
                +var a=window.PR,b=[[a.PR_PLAIN,/^[ \t\r\n\v\f\xA0]+/,null," \t\r\n\x0B\f\u00a0"],[a.PR_COMMENT,/^%\{[^%]*%+(?:[^\}%][^%]*%+)*\}/,null],[a.PR_COMMENT,/^%[^\r\n]*/,null,"%"],["syscmd",/^![^\r\n]*/,null,"!"]],c=[["linecont",/^\.\.\.\s*[\r\n]/,null],["err",/^\?\?\? [^\r\n]*/,null],["wrn",/^Warning: [^\r\n]*/,null],["codeoutput",/^>>\s+/,null],["codeoutput",/^octave:\d+>\s+/,null],["lang-matlab-operators",/^((?:[a-zA-Z][a-zA-Z0-9_]*(?:\.[a-zA-Z][a-zA-Z0-9_]*)*|\)|\]|\}|\.)')/,null],["lang-matlab-identifiers",
                +/^([a-zA-Z][a-zA-Z0-9_]*(?:\.[a-zA-Z][a-zA-Z0-9_]*)*)(?!')/,null],[a.PR_STRING,/^'(?:[^']|'')*'/,null],[a.PR_LITERAL,/^[+\-]?\.?\d+(?:\.\d*)?(?:[Ee][+\-]?\d+)?[ij]?/,null],[a.PR_TAG,/^(?:\{|\}|\(|\)|\[|\])/,null],[a.PR_PUNCTUATION,/^(?:<|>|=|~|@|&|;|,|:|!|\-|\+|\*|\^|\.|\||\\|\/)/,null]],d=[["lang-matlab-identifiers",/^([a-zA-Z][a-zA-Z0-9_]*(?:\.[a-zA-Z][a-zA-Z0-9_]*)*)/,null],[a.PR_TAG,/^(?:\{|\}|\(|\)|\[|\])/,null],[a.PR_PUNCTUATION,/^(?:<|>|=|~|@|&|;|,|:|!|\-|\+|\*|\^|\.|\||\\|\/)/,null],["transpose",
                +/^'/,null]];
                +a.registerLangHandler(a.createSimpleLexer([],[[a.PR_KEYWORD,/^\b(?:break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while)\b/,null],["const",/^\b(?:true|false|inf|Inf|nan|NaN|eps|pi|ans|nargin|nargout|varargin|varargout)\b/,null],[a.PR_TYPE,/^\b(?:cell|struct|char|double|single|logical|u?int(?:8|16|32|64)|sparse)\b/,null],["fun",/^\b(?:abs|accumarray|acos(?:d|h)?|acot(?:d|h)?|acsc(?:d|h)?|actxcontrol(?:list|select)?|actxGetRunningServer|actxserver|addlistener|addpath|addpref|addtodate|airy|align|alim|all|allchild|alpha|alphamap|amd|ancestor|and|angle|annotation|any|area|arrayfun|asec(?:d|h)?|asin(?:d|h)?|assert|assignin|atan(?:2|d|h)?|audiodevinfo|audioplayer|audiorecorder|aufinfo|auread|autumn|auwrite|avifile|aviinfo|aviread|axes|axis|balance|bar(?:3|3h|h)?|base2dec|beep|BeginInvoke|bench|bessel(?:h|i|j|k|y)|beta|betainc|betaincinv|betaln|bicg|bicgstab|bicgstabl|bin2dec|bitand|bitcmp|bitget|bitmax|bitnot|bitor|bitset|bitshift|bitxor|blanks|blkdiag|bone|box|brighten|brush|bsxfun|builddocsearchdb|builtin|bvp4c|bvp5c|bvpget|bvpinit|bvpset|bvpxtend|calendar|calllib|callSoapService|camdolly|cameratoolbar|camlight|camlookat|camorbit|campan|campos|camproj|camroll|camtarget|camup|camva|camzoom|cart2pol|cart2sph|cast|cat|caxis|cd|cdf2rdf|cdfepoch|cdfinfo|cdflib(?:.(?:close|closeVar|computeEpoch|computeEpoch16|create|createAttr|createVar|delete|deleteAttr|deleteAttrEntry|deleteAttrgEntry|deleteVar|deleteVarRecords|epoch16Breakdown|epochBreakdown|getAttrEntry|getAttrgEntry|getAttrMaxEntry|getAttrMaxgEntry|getAttrName|getAttrNum|getAttrScope|getCacheSize|getChecksum|getCompression|getCompressionCacheSize|getConstantNames|getConstantValue|getCopyright|getFileBackward|getFormat|getLibraryCopyright|getLibraryVersion|getMajority|getName|getNumAttrEntries|getNumAttrgEntries|getNumAttributes|getNumgAttributes|getReadOnlyMode|getStageCacheSize|getValidate|getVarAllocRecords|getVarBlockingFactor|getVarCacheSize|getVarCompression|getVarData|getVarMaxAllocRecNum|getVarMaxWrittenRecNum|getVarName|getVarNum|getVarNumRecsWritten|getVarPadValue|getVarRecordData|getVarReservePercent|getVarsMaxWrittenRecNum|getVarSparseRecords|getVersion|hyperGetVarData|hyperPutVarData|inquire|inquireAttr|inquireAttrEntry|inquireAttrgEntry|inquireVar|open|putAttrEntry|putAttrgEntry|putVarData|putVarRecordData|renameAttr|renameVar|setCacheSize|setChecksum|setCompression|setCompressionCacheSize|setFileBackward|setFormat|setMajority|setReadOnlyMode|setStageCacheSize|setValidate|setVarAllocBlockRecords|setVarBlockingFactor|setVarCacheSize|setVarCompression|setVarInitialRecs|setVarPadValue|SetVarReservePercent|setVarsCacheSize|setVarSparseRecords))?|cdfread|cdfwrite|ceil|cell2mat|cell2struct|celldisp|cellfun|cellplot|cellstr|cgs|checkcode|checkin|checkout|chol|cholinc|cholupdate|circshift|cla|clabel|class|clc|clear|clearvars|clf|clipboard|clock|close|closereq|cmopts|cmpermute|cmunique|colamd|colon|colorbar|colordef|colormap|colormapeditor|colperm|Combine|comet|comet3|commandhistory|commandwindow|compan|compass|complex|computer|cond|condeig|condest|coneplot|conj|containers.Map|contour(?:3|c|f|slice)?|contrast|conv|conv2|convhull|convhulln|convn|cool|copper|copyfile|copyobj|corrcoef|cos(?:d|h)?|cot(?:d|h)?|cov|cplxpair|cputime|createClassFromWsdl|createSoapMessage|cross|csc(?:d|h)?|csvread|csvwrite|ctranspose|cumprod|cumsum|cumtrapz|curl|customverctrl|cylinder|daqread|daspect|datacursormode|datatipinfo|date|datenum|datestr|datetick|datevec|dbclear|dbcont|dbdown|dblquad|dbmex|dbquit|dbstack|dbstatus|dbstep|dbstop|dbtype|dbup|dde23|ddeget|ddesd|ddeset|deal|deblank|dec2base|dec2bin|dec2hex|decic|deconv|del2|delaunay|delaunay3|delaunayn|DelaunayTri|delete|demo|depdir|depfun|det|detrend|deval|diag|dialog|diary|diff|diffuse|dir|disp|display|dither|divergence|dlmread|dlmwrite|dmperm|doc|docsearch|dos|dot|dragrect|drawnow|dsearch|dsearchn|dynamicprops|echo|echodemo|edit|eig|eigs|ellipj|ellipke|ellipsoid|empty|enableNETfromNetworkDrive|enableservice|EndInvoke|enumeration|eomday|eq|erf|erfc|erfcinv|erfcx|erfinv|error|errorbar|errordlg|etime|etree|etreeplot|eval|evalc|evalin|event.(?:EventData|listener|PropertyEvent|proplistener)|exifread|exist|exit|exp|expint|expm|expm1|export2wsdlg|eye|ezcontour|ezcontourf|ezmesh|ezmeshc|ezplot|ezplot3|ezpolar|ezsurf|ezsurfc|factor|factorial|fclose|feather|feature|feof|ferror|feval|fft|fft2|fftn|fftshift|fftw|fgetl|fgets|fieldnames|figure|figurepalette|fileattrib|filebrowser|filemarker|fileparts|fileread|filesep|fill|fill3|filter|filter2|find|findall|findfigs|findobj|findstr|finish|fitsdisp|fitsinfo|fitsread|fitswrite|fix|flag|flipdim|fliplr|flipud|floor|flow|fminbnd|fminsearch|fopen|format|fplot|fprintf|frame2im|fread|freqspace|frewind|fscanf|fseek|ftell|FTP|full|fullfile|func2str|functions|funm|fwrite|fzero|gallery|gamma|gammainc|gammaincinv|gammaln|gca|gcbf|gcbo|gcd|gcf|gco|ge|genpath|genvarname|get|getappdata|getenv|getfield|getframe|getpixelposition|getpref|ginput|gmres|gplot|grabcode|gradient|gray|graymon|grid|griddata(?:3|n)?|griddedInterpolant|gsvd|gt|gtext|guidata|guide|guihandles|gunzip|gzip|h5create|h5disp|h5info|h5read|h5readatt|h5write|h5writeatt|hadamard|handle|hankel|hdf|hdf5|hdf5info|hdf5read|hdf5write|hdfinfo|hdfread|hdftool|help|helpbrowser|helpdesk|helpdlg|helpwin|hess|hex2dec|hex2num|hgexport|hggroup|hgload|hgsave|hgsetget|hgtransform|hidden|hilb|hist|histc|hold|home|horzcat|hostid|hot|hsv|hsv2rgb|hypot|ichol|idivide|ifft|ifft2|ifftn|ifftshift|ilu|im2frame|im2java|imag|image|imagesc|imapprox|imfinfo|imformats|import|importdata|imread|imwrite|ind2rgb|ind2sub|inferiorto|info|inline|inmem|inpolygon|input|inputdlg|inputname|inputParser|inspect|instrcallback|instrfind|instrfindall|int2str|integral(?:2|3)?|interp(?:1|1q|2|3|ft|n)|interpstreamspeed|intersect|intmax|intmin|inv|invhilb|ipermute|isa|isappdata|iscell|iscellstr|ischar|iscolumn|isdir|isempty|isequal|isequaln|isequalwithequalnans|isfield|isfinite|isfloat|isglobal|ishandle|ishghandle|ishold|isinf|isinteger|isjava|iskeyword|isletter|islogical|ismac|ismatrix|ismember|ismethod|isnan|isnumeric|isobject|isocaps|isocolors|isonormals|isosurface|ispc|ispref|isprime|isprop|isreal|isrow|isscalar|issorted|isspace|issparse|isstr|isstrprop|isstruct|isstudent|isunix|isvarname|isvector|javaaddpath|javaArray|javachk|javaclasspath|javacomponent|javaMethod|javaMethodEDT|javaObject|javaObjectEDT|javarmpath|jet|keyboard|kron|lasterr|lasterror|lastwarn|lcm|ldivide|ldl|le|legend|legendre|length|libfunctions|libfunctionsview|libisloaded|libpointer|libstruct|license|light|lightangle|lighting|lin2mu|line|lines|linkaxes|linkdata|linkprop|linsolve|linspace|listdlg|listfonts|load|loadlibrary|loadobj|log|log10|log1p|log2|loglog|logm|logspace|lookfor|lower|ls|lscov|lsqnonneg|lsqr|lt|lu|luinc|magic|makehgtform|mat2cell|mat2str|material|matfile|matlab.io.MatFile|matlab.mixin.(?:Copyable|Heterogeneous(?:.getDefaultScalarElement)?)|matlabrc|matlabroot|max|maxNumCompThreads|mean|median|membrane|memmapfile|memory|menu|mesh|meshc|meshgrid|meshz|meta.(?:class(?:.fromName)?|DynamicProperty|EnumeratedValue|event|MetaData|method|package(?:.(?:fromName|getAllPackages))?|property)|metaclass|methods|methodsview|mex(?:.getCompilerConfigurations)?|MException|mexext|mfilename|min|minres|minus|mislocked|mkdir|mkpp|mldivide|mlint|mlintrpt|mlock|mmfileinfo|mmreader|mod|mode|more|move|movefile|movegui|movie|movie2avi|mpower|mrdivide|msgbox|mtimes|mu2lin|multibandread|multibandwrite|munlock|namelengthmax|nargchk|narginchk|nargoutchk|native2unicode|nccreate|ncdisp|nchoosek|ncinfo|ncread|ncreadatt|ncwrite|ncwriteatt|ncwriteschema|ndgrid|ndims|ne|NET(?:.(?:addAssembly|Assembly|convertArray|createArray|createGeneric|disableAutoRelease|enableAutoRelease|GenericClass|invokeGenericMethod|NetException|setStaticProperty))?|netcdf.(?:abort|close|copyAtt|create|defDim|defGrp|defVar|defVarChunking|defVarDeflate|defVarFill|defVarFletcher32|delAtt|endDef|getAtt|getChunkCache|getConstant|getConstantNames|getVar|inq|inqAtt|inqAttID|inqAttName|inqDim|inqDimID|inqDimIDs|inqFormat|inqGrpName|inqGrpNameFull|inqGrpParent|inqGrps|inqLibVers|inqNcid|inqUnlimDims|inqVar|inqVarChunking|inqVarDeflate|inqVarFill|inqVarFletcher32|inqVarID|inqVarIDs|open|putAtt|putVar|reDef|renameAtt|renameDim|renameVar|setChunkCache|setDefaultFormat|setFill|sync)|newplot|nextpow2|nnz|noanimate|nonzeros|norm|normest|not|notebook|now|nthroot|null|num2cell|num2hex|num2str|numel|nzmax|ode(?:113|15i|15s|23|23s|23t|23tb|45)|odeget|odeset|odextend|onCleanup|ones|open|openfig|opengl|openvar|optimget|optimset|or|ordeig|orderfields|ordqz|ordschur|orient|orth|pack|padecoef|pagesetupdlg|pan|pareto|parseSoapResponse|pascal|patch|path|path2rc|pathsep|pathtool|pause|pbaspect|pcg|pchip|pcode|pcolor|pdepe|pdeval|peaks|perl|perms|permute|pie|pink|pinv|planerot|playshow|plot|plot3|plotbrowser|plotedit|plotmatrix|plottools|plotyy|plus|pol2cart|polar|poly|polyarea|polyder|polyeig|polyfit|polyint|polyval|polyvalm|pow2|power|ppval|prefdir|preferences|primes|print|printdlg|printopt|printpreview|prod|profile|profsave|propedit|propertyeditor|psi|publish|PutCharArray|PutFullMatrix|PutWorkspaceData|pwd|qhull|qmr|qr|qrdelete|qrinsert|qrupdate|quad|quad2d|quadgk|quadl|quadv|questdlg|quit|quiver|quiver3|qz|rand|randi|randn|randperm|RandStream(?:.(?:create|getDefaultStream|getGlobalStream|list|setDefaultStream|setGlobalStream))?|rank|rat|rats|rbbox|rcond|rdivide|readasync|real|reallog|realmax|realmin|realpow|realsqrt|record|rectangle|rectint|recycle|reducepatch|reducevolume|refresh|refreshdata|regexp|regexpi|regexprep|regexptranslate|rehash|rem|Remove|RemoveAll|repmat|reset|reshape|residue|restoredefaultpath|rethrow|rgb2hsv|rgb2ind|rgbplot|ribbon|rmappdata|rmdir|rmfield|rmpath|rmpref|rng|roots|rose|rosser|rot90|rotate|rotate3d|round|rref|rsf2csf|run|save|saveas|saveobj|savepath|scatter|scatter3|schur|sec|secd|sech|selectmoveresize|semilogx|semilogy|sendmail|serial|set|setappdata|setdiff|setenv|setfield|setpixelposition|setpref|setstr|setxor|shading|shg|shiftdim|showplottool|shrinkfaces|sign|sin(?:d|h)?|size|slice|smooth3|snapnow|sort|sortrows|sound|soundsc|spalloc|spaugment|spconvert|spdiags|specular|speye|spfun|sph2cart|sphere|spinmap|spline|spones|spparms|sprand|sprandn|sprandsym|sprank|spring|sprintf|spy|sqrt|sqrtm|squeeze|ss2tf|sscanf|stairs|startup|std|stem|stem3|stopasync|str2double|str2func|str2mat|str2num|strcat|strcmp|strcmpi|stream2|stream3|streamline|streamparticles|streamribbon|streamslice|streamtube|strfind|strjust|strmatch|strncmp|strncmpi|strread|strrep|strtok|strtrim|struct2cell|structfun|strvcat|sub2ind|subplot|subsasgn|subsindex|subspace|subsref|substruct|subvolume|sum|summer|superclasses|superiorto|support|surf|surf2patch|surface|surfc|surfl|surfnorm|svd|svds|swapbytes|symamd|symbfact|symmlq|symrcm|symvar|system|tan(?:d|h)?|tar|tempdir|tempname|tetramesh|texlabel|text|textread|textscan|textwrap|tfqmr|throw|tic|Tiff(?:.(?:getTagNames|getVersion))?|timer|timerfind|timerfindall|times|timeseries|title|toc|todatenum|toeplitz|toolboxdir|trace|transpose|trapz|treelayout|treeplot|tril|trimesh|triplequad|triplot|TriRep|TriScatteredInterp|trisurf|triu|tscollection|tsearch|tsearchn|tstool|type|typecast|uibuttongroup|uicontextmenu|uicontrol|uigetdir|uigetfile|uigetpref|uiimport|uimenu|uiopen|uipanel|uipushtool|uiputfile|uiresume|uisave|uisetcolor|uisetfont|uisetpref|uistack|uitable|uitoggletool|uitoolbar|uiwait|uminus|undocheckout|unicode2native|union|unique|unix|unloadlibrary|unmesh|unmkpp|untar|unwrap|unzip|uplus|upper|urlread|urlwrite|usejava|userpath|validateattributes|validatestring|vander|var|vectorize|ver|verctrl|verLessThan|version|vertcat|VideoReader(?:.isPlatformSupported)?|VideoWriter(?:.getProfiles)?|view|viewmtx|visdiff|volumebounds|voronoi|voronoin|wait|waitbar|waitfor|waitforbuttonpress|warndlg|warning|waterfall|wavfinfo|wavplay|wavread|wavrecord|wavwrite|web|weekday|what|whatsnew|which|whitebg|who|whos|wilkinson|winopen|winqueryreg|winter|wk1finfo|wk1read|wk1write|workspace|xlabel|xlim|xlsfinfo|xlsread|xlswrite|xmlread|xmlwrite|xor|xslt|ylabel|ylim|zeros|zip|zlabel|zlim|zoom)\b/,null],
                +["fun_tbx",/^\b(?:addedvarplot|andrewsplot|anova(?:1|2|n)|ansaribradley|aoctool|barttest|bbdesign|beta(?:cdf|fit|inv|like|pdf|rnd|stat)|bino(?:cdf|fit|inv|pdf|rnd|stat)|biplot|bootci|bootstrp|boxplot|candexch|candgen|canoncorr|capability|capaplot|caseread|casewrite|categorical|ccdesign|cdfplot|chi2(?:cdf|gof|inv|pdf|rnd|stat)|cholcov|Classification(?:BaggedEnsemble|Discriminant(?:.(?:fit|make|template))?|Ensemble|KNN(?:.(?:fit|template))?|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|template))?)|classify|classregtree|cluster|clusterdata|cmdscale|combnk|Compact(?:Classification(?:Discriminant|Ensemble|Tree)|Regression(?:Ensemble|Tree)|TreeBagger)|confusionmat|controlchart|controlrules|cophenet|copula(?:cdf|fit|param|pdf|rnd|stat)|cordexch|corr|corrcov|coxphfit|createns|crosstab|crossval|cvpartition|datasample|dataset|daugment|dcovary|dendrogram|dfittool|disttool|dummyvar|dwtest|ecdf|ecdfhist|ev(?:cdf|fit|inv|like|pdf|rnd|stat)|ExhaustiveSearcher|exp(?:cdf|fit|inv|like|pdf|rnd|stat)|factoran|fcdf|ff2n|finv|fitdist|fitensemble|fpdf|fracfact|fracfactgen|friedman|frnd|fstat|fsurfht|fullfact|gagerr|gam(?:cdf|fit|inv|like|pdf|rnd|stat)|GeneralizedLinearModel(?:.fit)?|geo(?:cdf|inv|mean|pdf|rnd|stat)|gev(?:cdf|fit|inv|like|pdf|rnd|stat)|gline|glmfit|glmval|glyphplot|gmdistribution(?:.fit)?|gname|gp(?:cdf|fit|inv|like|pdf|rnd|stat)|gplotmatrix|grp2idx|grpstats|gscatter|haltonset|harmmean|hist3|histfit|hmm(?:decode|estimate|generate|train|viterbi)|hougen|hyge(?:cdf|inv|pdf|rnd|stat)|icdf|inconsistent|interactionplot|invpred|iqr|iwishrnd|jackknife|jbtest|johnsrnd|KDTreeSearcher|kmeans|knnsearch|kruskalwallis|ksdensity|kstest|kstest2|kurtosis|lasso|lassoglm|lassoPlot|leverage|lhsdesign|lhsnorm|lillietest|LinearModel(?:.fit)?|linhyptest|linkage|logn(?:cdf|fit|inv|like|pdf|rnd|stat)|lsline|mad|mahal|maineffectsplot|manova1|manovacluster|mdscale|mhsample|mle|mlecov|mnpdf|mnrfit|mnrnd|mnrval|moment|multcompare|multivarichart|mvn(?:cdf|pdf|rnd)|mvregress|mvregresslike|mvt(?:cdf|pdf|rnd)|NaiveBayes(?:.fit)?|nan(?:cov|max|mean|median|min|std|sum|var)|nbin(?:cdf|fit|inv|pdf|rnd|stat)|ncf(?:cdf|inv|pdf|rnd|stat)|nct(?:cdf|inv|pdf|rnd|stat)|ncx2(?:cdf|inv|pdf|rnd|stat)|NeighborSearcher|nlinfit|nlintool|nlmefit|nlmefitsa|nlparci|nlpredci|nnmf|nominal|NonLinearModel(?:.fit)?|norm(?:cdf|fit|inv|like|pdf|rnd|stat)|normplot|normspec|ordinal|outlierMeasure|parallelcoords|paretotails|partialcorr|pcacov|pcares|pdf|pdist|pdist2|pearsrnd|perfcurve|perms|piecewisedistribution|plsregress|poiss(?:cdf|fit|inv|pdf|rnd|tat)|polyconf|polytool|prctile|princomp|ProbDist(?:Kernel|Parametric|UnivKernel|UnivParam)?|probplot|procrustes|qqplot|qrandset|qrandstream|quantile|randg|random|randsample|randtool|range|rangesearch|ranksum|rayl(?:cdf|fit|inv|pdf|rnd|stat)|rcoplot|refcurve|refline|regress|Regression(?:BaggedEnsemble|Ensemble|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|template))?)|regstats|relieff|ridge|robustdemo|robustfit|rotatefactors|rowexch|rsmdemo|rstool|runstest|sampsizepwr|scatterhist|sequentialfs|signrank|signtest|silhouette|skewness|slicesample|sobolset|squareform|statget|statset|stepwise|stepwisefit|surfht|tabulate|tblread|tblwrite|tcdf|tdfread|tiedrank|tinv|tpdf|TreeBagger|treedisp|treefit|treeprune|treetest|treeval|trimmean|trnd|tstat|ttest|ttest2|unid(?:cdf|inv|pdf|rnd|stat)|unif(?:cdf|inv|it|pdf|rnd|stat)|vartest(?:2|n)?|wbl(?:cdf|fit|inv|like|pdf|rnd|stat)|wblplot|wishrnd|x2fx|xptread|zscore|ztest)\b/,
                +null],["fun_tbx",/^\b(?:adapthisteq|analyze75info|analyze75read|applycform|applylut|axes2pix|bestblk|blockproc|bwarea|bwareaopen|bwboundaries|bwconncomp|bwconvhull|bwdist|bwdistgeodesic|bweuler|bwhitmiss|bwlabel|bwlabeln|bwmorph|bwpack|bwperim|bwselect|bwtraceboundary|bwulterode|bwunpack|checkerboard|col2im|colfilt|conndef|convmtx2|corner|cornermetric|corr2|cp2tform|cpcorr|cpselect|cpstruct2pairs|dct2|dctmtx|deconvblind|deconvlucy|deconvreg|deconvwnr|decorrstretch|demosaic|dicom(?:anon|dict|info|lookup|read|uid|write)|edge|edgetaper|entropy|entropyfilt|fan2para|fanbeam|findbounds|fliptform|freqz2|fsamp2|fspecial|ftrans2|fwind1|fwind2|getheight|getimage|getimagemodel|getline|getneighbors|getnhood|getpts|getrangefromclass|getrect|getsequence|gray2ind|graycomatrix|graycoprops|graydist|grayslice|graythresh|hdrread|hdrwrite|histeq|hough|houghlines|houghpeaks|iccfind|iccread|iccroot|iccwrite|idct2|ifanbeam|im2bw|im2col|im2double|im2int16|im2java2d|im2single|im2uint16|im2uint8|imabsdiff|imadd|imadjust|ImageAdapter|imageinfo|imagemodel|imapplymatrix|imattributes|imbothat|imclearborder|imclose|imcolormaptool|imcomplement|imcontour|imcontrast|imcrop|imdilate|imdisplayrange|imdistline|imdivide|imellipse|imerode|imextendedmax|imextendedmin|imfill|imfilter|imfindcircles|imfreehand|imfuse|imgca|imgcf|imgetfile|imhandles|imhist|imhmax|imhmin|imimposemin|imlincomb|imline|immagbox|immovie|immultiply|imnoise|imopen|imoverview|imoverviewpanel|impixel|impixelinfo|impixelinfoval|impixelregion|impixelregionpanel|implay|impoint|impoly|impositionrect|improfile|imputfile|impyramid|imreconstruct|imrect|imregconfig|imregionalmax|imregionalmin|imregister|imresize|imroi|imrotate|imsave|imscrollpanel|imshow|imshowpair|imsubtract|imtool|imtophat|imtransform|imview|ind2gray|ind2rgb|interfileinfo|interfileread|intlut|ippl|iptaddcallback|iptcheckconn|iptcheckhandle|iptcheckinput|iptcheckmap|iptchecknargin|iptcheckstrs|iptdemos|iptgetapi|iptGetPointerBehavior|iptgetpref|ipticondir|iptnum2ordinal|iptPointerManager|iptprefs|iptremovecallback|iptSetPointerBehavior|iptsetpref|iptwindowalign|iradon|isbw|isflat|isgray|isicc|isind|isnitf|isrgb|isrset|lab2double|lab2uint16|lab2uint8|label2rgb|labelmatrix|makecform|makeConstrainToRectFcn|makehdr|makelut|makeresampler|maketform|mat2gray|mean2|medfilt2|montage|nitfinfo|nitfread|nlfilter|normxcorr2|ntsc2rgb|openrset|ordfilt2|otf2psf|padarray|para2fan|phantom|poly2mask|psf2otf|qtdecomp|qtgetblk|qtsetblk|radon|rangefilt|reflect|regionprops|registration.metric.(?:MattesMutualInformation|MeanSquares)|registration.optimizer.(?:OnePlusOneEvolutionary|RegularStepGradientDescent)|rgb2gray|rgb2ntsc|rgb2ycbcr|roicolor|roifill|roifilt2|roipoly|rsetwrite|std2|stdfilt|strel|stretchlim|subimage|tformarray|tformfwd|tforminv|tonemap|translate|truesize|uintlut|viscircles|warp|watershed|whitepoint|wiener2|xyz2double|xyz2uint16|ycbcr2rgb)\b/,
                +null],["fun_tbx",/^\b(?:bintprog|color|fgoalattain|fminbnd|fmincon|fminimax|fminsearch|fminunc|fseminf|fsolve|fzero|fzmult|gangstr|ktrlink|linprog|lsqcurvefit|lsqlin|lsqnonlin|lsqnonneg|optimget|optimset|optimtool|quadprog)\b/,null],["ident",/^[a-zA-Z][a-zA-Z0-9_]*(?:\.[a-zA-Z][a-zA-Z0-9_]*)*/,null]]),["matlab-identifiers"]);a.registerLangHandler(a.createSimpleLexer([],d),["matlab-operators"]);a.registerLangHandler(a.createSimpleLexer(b,c),["matlab"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-ml.js b/blockly/webif/static/js/google-prettify/lang-ml.js
                new file mode 100644
                index 000000000..c012a3ff4
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-ml.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])(?:\'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
                +["lit",/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^(?:[a-z_][\w']*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],["pun",/^[^\t\n\r \xA0\"\'\w]+/]]),["fs","ml"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-mumps.js b/blockly/webif/static/js/google-prettify/lang-mumps.js
                new file mode 100644
                index 000000000..6d5125891
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-mumps.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2011 Kitware Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"]|\\.)*")/,null,'"']],[["com",/^;[^\r\n]*/,null,";"],["dec",/^(?:\$(?:D|DEVICE|EC|ECODE|ES|ESTACK|ET|ETRAP|H|HOROLOG|I|IO|J|JOB|K|KEY|P|PRINCIPAL|Q|QUIT|ST|STACK|S|STORAGE|SY|SYSTEM|T|TEST|TL|TLEVEL|TR|TRESTART|X|Y|Z[A-Z]*|A|ASCII|C|CHAR|D|DATA|E|EXTRACT|F|FIND|FN|FNUMBER|G|GET|J|JUSTIFY|L|LENGTH|NA|NAME|O|ORDER|P|PIECE|QL|QLENGTH|QS|QSUBSCRIPT|Q|QUERY|R|RANDOM|RE|REVERSE|S|SELECT|ST|STACK|T|TEXT|TR|TRANSLATE|NaN))\b/i,
                +null],["kwd",/^(?:[^\$]B|BREAK|C|CLOSE|D|DO|E|ELSE|F|FOR|G|GOTO|H|HALT|H|HANG|I|IF|J|JOB|K|KILL|L|LOCK|M|MERGE|N|NEW|O|OPEN|Q|QUIT|R|READ|S|SET|TC|TCOMMIT|TRE|TRESTART|TRO|TROLLBACK|TS|TSTART|U|USE|V|VIEW|W|WRITE|X|XECUTE)\b/i,null],["lit",/^[+-]?(?:(?:\.\d+|\d+(?:\.\d*)?)(?:E[+\-]?\d+)?)/i],["pln",/^[a-z][a-zA-Z0-9]*/i],["pun",/^[^\w\t\n\r\xA0\"\$;%\^]|_/]]),["mumps"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-n.js b/blockly/webif/static/js/google-prettify/lang-n.js
                new file mode 100644
                index 000000000..9b3910c9a
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-n.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2011 Zimin A.V.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*\'|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null],["str",/^<#(?:[^#>])*(?:#>|$)/,null],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null],["com",/^\/\/[^\r\n]*/,
                +null],["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/,
                +null],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,null],["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^@[A-Z]+[a-z][A-Za-z_$@0-9]*/,null],["pln",/^'?[A-Za-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pun",/^.[^\s\w\.$@\'\"\`\/\#]*/,null]]),["n","nemerle"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-nemerle.js b/blockly/webif/static/js/google-prettify/lang-nemerle.js
                new file mode 100644
                index 000000000..9b3910c9a
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-nemerle.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2011 Zimin A.V.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*\'|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null],["str",/^<#(?:[^#>])*(?:#>|$)/,null],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null],["com",/^\/\/[^\r\n]*/,
                +null],["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/,
                +null],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,null],["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^@[A-Z]+[a-z][A-Za-z_$@0-9]*/,null],["pln",/^'?[A-Za-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pun",/^.[^\s\w\.$@\'\"\`\/\#]*/,null]]),["n","nemerle"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-pascal.js b/blockly/webif/static/js/google-prettify/lang-pascal.js
                new file mode 100644
                index 000000000..c76a11cfa
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-pascal.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2013 Peter Kofler
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$))/,null,"'"],["pln",/^\s+/,null," \r\n\t\u00a0"]],[["com",/^\(\*[\s\S]*?(?:\*\)|$)|^\{[\s\S]*?(?:\}|$)/,null],["kwd",/^(?:ABSOLUTE|AND|ARRAY|ASM|ASSEMBLER|BEGIN|CASE|CONST|CONSTRUCTOR|DESTRUCTOR|DIV|DO|DOWNTO|ELSE|END|EXTERNAL|FOR|FORWARD|FUNCTION|GOTO|IF|IMPLEMENTATION|IN|INLINE|INTERFACE|INTERRUPT|LABEL|MOD|NOT|OBJECT|OF|OR|PACKED|PROCEDURE|PROGRAM|RECORD|REPEAT|SET|SHL|SHR|THEN|TO|TYPE|UNIT|UNTIL|USES|VAR|VIRTUAL|WHILE|WITH|XOR)\b/i,
                +null],["lit",/^(?:true|false|self|nil)/i,null],["pln",/^[a-z][a-z0-9]*/i,null],["lit",/^(?:\$[a-f0-9]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?)/i,null,"0123456789"],["pun",/^.[^\s\w\.$@\'\/]*/,null]]),["pascal"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-proto.js b/blockly/webif/static/js/google-prettify/lang-proto.js
                new file mode 100644
                index 000000000..3215ff6d9
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-proto.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2006 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-r.js b/blockly/webif/static/js/google-prettify/lang-r.js
                new file mode 100644
                index 000000000..6ce16e8a1
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-r.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2012 Jeffrey B. Arnold
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![A-Za-z0-9_.])/],["lit",/^0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?/],["lit",/^[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|[0-9]+))(?![A-Za-z0-9_.])/],
                +["pun",/^(?:<<?-|->>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|\*|\+|\^|\/|!|%.*?%|=|~|\$|@|:{1,3}|[\[\](){};,?])/],["pln",/^(?:[A-Za-z]+[A-Za-z0-9_.]*|\.[a-zA-Z_][0-9a-zA-Z\._]*)(?![A-Za-z0-9_.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-rd.js b/blockly/webif/static/js/google-prettify/lang-rd.js
                new file mode 100644
                index 000000000..113141c90
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-rd.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2012 Jeffrey Arnold
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\r\n]*/,null,"%"]],[["lit",/^\\(?:cr|l?dots|R|tab)\b/],["kwd",/^\\[a-zA-Z@]+/],["kwd",/^#(?:ifn?def|endif)/],["pln",/^\\[{}]/],["pun",/^[{}()\[\]]+/]]),["Rd","rd"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-rkt.js b/blockly/webif/static/js/google-prettify/lang-rkt.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-rkt.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-rust.js b/blockly/webif/static/js/google-prettify/lang-rust.js
                new file mode 100644
                index 000000000..43856778d
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-rust.js
                @@ -0,0 +1,20 @@
                +/*
                +
                + Copyright (C) 2015 Chris Morgan
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([],[["pln",/^[\t\n\r \xA0]+/],["com",/^\/\/.*/],["com",/^\/\*[\s\S]*?(?:\*\/|$)/],["str",/^b"(?:[^\\]|\\(?:.|x[\da-fA-F]{2}))*?"/],["str",/^"(?:[^\\]|\\(?:.|x[\da-fA-F]{2}|u\{\[\da-fA-F]{1,6}\}))*?"/],["str",/^b?r(#*)\"[\s\S]*?\"\1/],["str",/^b'([^\\]|\\(.|x[\da-fA-F]{2}))'/],["str",/^'([^\\]|\\(.|x[\da-fA-F]{2}|u\{[\da-fA-F]{1,6}\}))'/],["tag",/^'\w+?\b/],["kwd",/^(?:match|if|else|as|break|box|continue|extern|fn|for|in|if|impl|let|loop|pub|return|super|unsafe|where|while|use|mod|trait|struct|enum|type|move|mut|ref|static|const|crate)\b/],
                +["kwd",/^(?:alignof|become|do|offsetof|priv|pure|sizeof|typeof|unsized|yield|abstract|virtual|final|override|macro)\b/],["typ",/^(?:[iu](8|16|32|64|size)|char|bool|f32|f64|str|Self)\b/],["typ",/^(?:Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b/],["lit",/^(self|true|false|null)\b/],
                +["lit",/^\d[0-9_]*(?:[iu](?:size|8|16|32|64))?/],["lit",/^0x[a-fA-F0-9_]+(?:[iu](?:size|8|16|32|64))?/],["lit",/^0o[0-7_]+(?:[iu](?:size|8|16|32|64))?/],["lit",/^0b[01_]+(?:[iu](?:size|8|16|32|64))?/],["lit",/^\d[0-9_]*\.(?![^\s\d.])/],["lit",/^\d[0-9_]*(?:\.\d[0-9_]*)(?:[eE][+-]?[0-9_]+)?(?:f32|f64)?/],["lit",/^\d[0-9_]*(?:\.\d[0-9_]*)?(?:[eE][+-]?[0-9_]+)(?:f32|f64)?/],["lit",/^\d[0-9_]*(?:\.\d[0-9_]*)?(?:[eE][+-]?[0-9_]+)?(?:f32|f64)/],
                +["atn",/^[a-z_]\w*!/i],["pln",/^[a-z_]\w*/i],["atv",/^#!?\[[\s\S]*?\]/],["pun",/^[+\-/*=^&|!<>%[\](){}?:.,;]/],["pln",/./]]),["rust"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-s.js b/blockly/webif/static/js/google-prettify/lang-s.js
                new file mode 100644
                index 000000000..6ce16e8a1
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-s.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2012 Jeffrey B. Arnold
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![A-Za-z0-9_.])/],["lit",/^0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?/],["lit",/^[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|[0-9]+))(?![A-Za-z0-9_.])/],
                +["pun",/^(?:<<?-|->>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|\*|\+|\^|\/|!|%.*?%|=|~|\$|@|:{1,3}|[\[\](){};,?])/],["pln",/^(?:[A-Za-z]+[A-Za-z0-9_.]*|\.[a-zA-Z_][0-9a-zA-Z\._]*)(?![A-Za-z0-9_.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-scala.js b/blockly/webif/static/js/google-prettify/lang-scala.js
                new file mode 100644
                index 000000000..3347dd608
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-scala.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2010 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:(?:""(?:""?(?!")|[^\\"]|\\.)*"{0,3})|(?:[^"\r\n\\]|\\.)*"?))/,null,'"'],["lit",/^`(?:[^\r\n\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&()*+,\-:;<=>?@\[\\\]^{|}~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\r\n\\']|\\(?:'|[^\r\n']+))'/],["lit",/^'[a-zA-Z_$][\w$]*(?!['$\w])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/],
                +["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:(?:0(?:[0-7]+|X[0-9A-F]+))L?|(?:(?:0|[1-9][0-9]*)(?:(?:\.[0-9]+)?(?:E[+\-]?[0-9]+)?F?|L?))|\\.[0-9]+(?:E[+\-]?[0-9]+)?F?)/i],["typ",/^[$_]*[A-Z][_$A-Z0-9]*[a-z][\w$]*/],["pln",/^[$a-zA-Z_][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-scm.js b/blockly/webif/static/js/google-prettify/lang-scm.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-scm.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-splus.js b/blockly/webif/static/js/google-prettify/lang-splus.js
                new file mode 100644
                index 000000000..6ce16e8a1
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-splus.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2012 Jeffrey B. Arnold
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"'],["str",/^\'(?:[^\'\\]|\\[\s\S])*(?:\'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![A-Za-z0-9_.])/],["lit",/^0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?/],["lit",/^[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|[0-9]+))(?![A-Za-z0-9_.])/],
                +["pun",/^(?:<<?-|->>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|\*|\+|\^|\/|!|%.*?%|=|~|\$|@|:{1,3}|[\[\](){};,?])/],["pln",/^(?:[A-Za-z]+[A-Za-z0-9_.]*|\.[a-zA-Z_][0-9a-zA-Z\._]*)(?![A-Za-z0-9_.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-sql.js b/blockly/webif/static/js/google-prettify/lang-sql.js
                new file mode 100644
                index 000000000..a7d292cb3
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-sql.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],["kwd",/^(?:ADD|ALL|ALTER|AND|ANY|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONNECT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOLLOWING|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|MATCH|MATCHED|MERGE|NATURAL|NATIONAL|NOCHECK|NONCLUSTERED|NOCYCLE|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PARTITION|PERCENT|PIVOT|PLAN|PRECEDING|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|ROWS?|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|START|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNBOUNDED|UNION|UNIQUE|UNPIVOT|UPDATE|UPDATETEXT|USE|USER|USING|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WITHIN|WRITETEXT|XML)(?=[^\w-]|$)/i,
                +null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^[a-z_][\w-]*/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-ss.js b/blockly/webif/static/js/google-prettify/lang-ss.js
                new file mode 100644
                index 000000000..2f18c967e
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-ss.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2008 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,null,"("],["clo",/^\)+/,null,")"],["com",/^;[^\r\n]*/,null,";"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,
                +null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),"cl el lisp lsp scm ss rkt".split(" "));
                diff --git a/blockly/webif/static/js/google-prettify/lang-swift.js b/blockly/webif/static/js/google-prettify/lang-swift.js
                new file mode 100644
                index 000000000..eb5c31439
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-swift.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2015 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \n\r\t\v\f\0]+/,null," \n\r\t\v\f\x00"],["str",/^"(?:[^"\\]|(?:\\.)|(?:\\\((?:[^"\\)]|\\.)*\)))*"/,null,'"']],[["lit",/^(?:(?:0x[\da-fA-F][\da-fA-F_]*\.[\da-fA-F][\da-fA-F_]*[pP]?)|(?:\d[\d_]*\.\d[\d_]*[eE]?))[+-]?\d[\d_]*/,null],["lit",/^-?(?:(?:0(?:(?:b[01][01_]*)|(?:o[0-7][0-7_]*)|(?:x[\da-fA-F][\da-fA-F_]*)))|(?:\d[\d_]*))/,null],["lit",/^(?:true|false|nil)\b/,null],["kwd",/^\b(?:__COLUMN__|__FILE__|__FUNCTION__|__LINE__|#available|#else|#elseif|#endif|#if|#line|arch|arm|arm64|associativity|as|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|dynamicType|else|enum|extension|fallthrough|final|for|func|get|guard|import|indirect|infix|init|inout|internal|i386|if|in|iOS|iOSApplicationExtension|is|lazy|left|let|mutating|none|nonmutating|operator|optional|OSX|OSXApplicationExtension|override|postfix|precedence|prefix|private|protocol|Protocol|public|required|rethrows|return|right|safe|self|set|static|struct|subscript|super|switch|throw|try|Type|typealias|unowned|unsafe|var|weak|watchOS|while|willSet|x86_64)\b/,
                +null],["com",/^\/\/.*?[\n\r]/,null],["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null],["pun",/^<<=|<=|<<|>>=|>=|>>|===|==|\.\.\.|&&=|\.\.<|!==|!=|&=|~=|~|\(|\)|\[|\]|{|}|@|#|;|\.|,|:|\|\|=|\?\?|\|\||&&|&\*|&\+|&-|&=|\+=|-=|\/=|\*=|\^=|%=|\|=|->|`|==|\+\+|--|\/|\+|!|\*|%|<|>|&|\||\^|\?|=|-|_/,null],["typ",/^\b(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null]]),["swift"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-tcl.js b/blockly/webif/static/js/google-prettify/lang-tcl.js
                new file mode 100644
                index 000000000..1d75c3f04
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-tcl.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2012 Pyrios
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\{+/,null,"{"],["clo",/^\}+/,null,"}"],["com",/^#[^\r\n]*/,null,"#"],["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/,null,'"']],[["kwd",/^(?:after|append|apply|array|break|case|catch|continue|error|eval|exec|exit|expr|for|foreach|if|incr|info|proc|return|set|switch|trace|uplevel|upvar|while)\b/,null],["lit",/^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i],
                +["lit",/^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/],["pln",/^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i],["pun",/^[^\w\t\n\r \xA0()\"\\\';]+/]]),["tcl"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-tex.js b/blockly/webif/static/js/google-prettify/lang-tex.js
                new file mode 100644
                index 000000000..efc758cd9
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-tex.js
                @@ -0,0 +1,17 @@
                +/*
                +
                + Copyright (C) 2011 Martin S.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\r\n]*/,null,"%"]],[["kwd",/^\\[a-zA-Z@]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[{}()\[\]=]+/]]),["latex","tex"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-vb.js b/blockly/webif/static/js/google-prettify/lang-vb.js
                new file mode 100644
                index 000000000..e34086fec
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-vb.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2009 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0\u2028\u2029]+/,null,"\t\n\r \u00a0\u2028\u2029"],["str",/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'"\u201c\u201d'],["com",/^[\'\u2018\u2019](?:_(?:\r\n?|[^\r]?)|[^\r\n_\u2028\u2029])*/,null,"'\u2018\u2019"]],[["kwd",/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,
                +null],["com",/^REM\b[^\r\n\u2028\u2029]*/i],["lit",/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*(?:\[[%&@!#]+\])?|\[(?:[a-z]|_\w)\w*\])/i],["pun",/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],["pun",/^(?:\[|\])/]]),["vb",
                +"vbs"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-vbs.js b/blockly/webif/static/js/google-prettify/lang-vbs.js
                new file mode 100644
                index 000000000..e34086fec
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-vbs.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2009 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0\u2028\u2029]+/,null,"\t\n\r \u00a0\u2028\u2029"],["str",/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'"\u201c\u201d'],["com",/^[\'\u2018\u2019](?:_(?:\r\n?|[^\r]?)|[^\r\n_\u2028\u2029])*/,null,"'\u2018\u2019"]],[["kwd",/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,
                +null],["com",/^REM\b[^\r\n\u2028\u2029]*/i],["lit",/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*(?:\[[%&@!#]+\])?|\[(?:[a-z]|_\w)\w*\])/i],["pun",/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],["pun",/^(?:\[|\])/]]),["vb",
                +"vbs"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-vhd.js b/blockly/webif/static/js/google-prettify/lang-vhd.js
                new file mode 100644
                index 000000000..f67a4a390
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-vhd.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2010 benoit@ryder.fr
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[BOX]?"(?:[^\"]|"")*"|'.')/i],["com",/^--[^\r\n]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
                +null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^\'(?:ACTIVE|ASCENDING|BASE|DELAYED|DRIVING|DRIVING_VALUE|EVENT|HIGH|IMAGE|INSTANCE_NAME|LAST_ACTIVE|LAST_EVENT|LAST_VALUE|LEFT|LEFTOF|LENGTH|LOW|PATH_NAME|POS|PRED|QUIET|RANGE|REVERSE_RANGE|RIGHT|RIGHTOF|SIMPLE_NAME|STABLE|SUCC|TRANSACTION|VAL|VALUE)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w\\.]+#(?:[+\-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:E[+\-]?\d+(?:_\d+)*)?)/i],
                +["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0\-\"\']*/]]),["vhdl","vhd"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-vhdl.js b/blockly/webif/static/js/google-prettify/lang-vhdl.js
                new file mode 100644
                index 000000000..f67a4a390
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-vhdl.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2010 benoit@ryder.fr
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[BOX]?"(?:[^\"]|"")*"|'.')/i],["com",/^--[^\r\n]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
                +null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^\'(?:ACTIVE|ASCENDING|BASE|DELAYED|DRIVING|DRIVING_VALUE|EVENT|HIGH|IMAGE|INSTANCE_NAME|LAST_ACTIVE|LAST_EVENT|LAST_VALUE|LEFT|LEFTOF|LENGTH|LOW|PATH_NAME|POS|PRED|QUIET|RANGE|REVERSE_RANGE|RIGHT|RIGHTOF|SIMPLE_NAME|STABLE|SUCC|TRANSACTION|VAL|VALUE)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w\\.]+#(?:[+\-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:E[+\-]?\d+(?:_\d+)*)?)/i],
                +["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0\-\"\']*/]]),["vhdl","vhd"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-wiki.js b/blockly/webif/static/js/google-prettify/lang-wiki.js
                new file mode 100644
                index 000000000..d03fccd2c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-wiki.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2009 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t \xA0a-gi-z0-9]+/,null,"\t \u00a0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[=*~\^\[\]]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\b/],["lang-",/^\{\{\{([\s\S]+?)\}\}\}/],["lang-",/^`([^\r\n`]+)`/],["str",/^https?:\/\/[^\/?#\s]*(?:\/[^?#\s]*)?(?:\?[^#\s]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\s\S])[^#=*~^A-Zh\{`\[\r\n]*/]]),["wiki"]);
                +PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-xq.js b/blockly/webif/static/js/google-prettify/lang-xq.js
                new file mode 100644
                index 000000000..a6d85372d
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-xq.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2011 Patrick Wied
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["var pln",/^\$[A-Za-z0-9_\-]+/,null,"$"]],[["pln",/^[\s=][<>][\s=]/],["lit",/^\@[\w-]+/],["tag",/^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["com",/^\(:[\s\S]*?:\)/],["pln",/^[\/\{\};,\[\]\(\)]$/],["str",/^(?:\"(?:[^\"\\\{]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\\{]|\\[\s\S])*(?:\'|$))/,null,"\"'"],["kwd",/^(?:xquery|where|version|variable|union|typeswitch|treat|to|then|text|stable|sortby|some|self|schema|satisfies|returns|return|ref|processing-instruction|preceding-sibling|preceding|precedes|parent|only|of|node|namespace|module|let|item|intersect|instance|in|import|if|function|for|follows|following-sibling|following|external|except|every|else|element|descending|descendant-or-self|descendant|define|default|declare|comment|child|cast|case|before|attribute|assert|ascending|as|ancestor-or-self|ancestor|after|eq|order|by|or|and|schema-element|document-node|node|at)\b/],
                +["typ",/^(?:xs:yearMonthDuration|xs:unsignedLong|xs:time|xs:string|xs:short|xs:QName|xs:Name|xs:long|xs:integer|xs:int|xs:gYearMonth|xs:gYear|xs:gMonthDay|xs:gDay|xs:float|xs:duration|xs:double|xs:decimal|xs:dayTimeDuration|xs:dateTime|xs:date|xs:byte|xs:boolean|xs:anyURI|xf:yearMonthDuration)\b/,null],["fun pln",/^(?:xp:dereference|xinc:node-expand|xinc:link-references|xinc:link-expand|xhtml:restructure|xhtml:clean|xhtml:add-lists|xdmp:zip-manifest|xdmp:zip-get|xdmp:zip-create|xdmp:xquery-version|xdmp:word-convert|xdmp:with-namespaces|xdmp:version|xdmp:value|xdmp:user-roles|xdmp:user-last-login|xdmp:user|xdmp:url-encode|xdmp:url-decode|xdmp:uri-is-file|xdmp:uri-format|xdmp:uri-content-type|xdmp:unquote|xdmp:unpath|xdmp:triggers-database|xdmp:trace|xdmp:to-json|xdmp:tidy|xdmp:subbinary|xdmp:strftime|xdmp:spawn-in|xdmp:spawn|xdmp:sleep|xdmp:shutdown|xdmp:set-session-field|xdmp:set-response-encoding|xdmp:set-response-content-type|xdmp:set-response-code|xdmp:set-request-time-limit|xdmp:set|xdmp:servers|xdmp:server-status|xdmp:server-name|xdmp:server|xdmp:security-database|xdmp:security-assert|xdmp:schema-database|xdmp:save|xdmp:role-roles|xdmp:role|xdmp:rethrow|xdmp:restart|xdmp:request-timestamp|xdmp:request-status|xdmp:request-cancel|xdmp:request|xdmp:redirect-response|xdmp:random|xdmp:quote|xdmp:query-trace|xdmp:query-meters|xdmp:product-edition|xdmp:privilege-roles|xdmp:privilege|xdmp:pretty-print|xdmp:powerpoint-convert|xdmp:platform|xdmp:permission|xdmp:pdf-convert|xdmp:path|xdmp:octal-to-integer|xdmp:node-uri|xdmp:node-replace|xdmp:node-kind|xdmp:node-insert-child|xdmp:node-insert-before|xdmp:node-insert-after|xdmp:node-delete|xdmp:node-database|xdmp:mul64|xdmp:modules-root|xdmp:modules-database|xdmp:merging|xdmp:merge-cancel|xdmp:merge|xdmp:md5|xdmp:logout|xdmp:login|xdmp:log-level|xdmp:log|xdmp:lock-release|xdmp:lock-acquire|xdmp:load|xdmp:invoke-in|xdmp:invoke|xdmp:integer-to-octal|xdmp:integer-to-hex|xdmp:http-put|xdmp:http-post|xdmp:http-options|xdmp:http-head|xdmp:http-get|xdmp:http-delete|xdmp:hosts|xdmp:host-status|xdmp:host-name|xdmp:host|xdmp:hex-to-integer|xdmp:hash64|xdmp:hash32|xdmp:has-privilege|xdmp:groups|xdmp:group-serves|xdmp:group-servers|xdmp:group-name|xdmp:group-hosts|xdmp:group|xdmp:get-session-field-names|xdmp:get-session-field|xdmp:get-response-encoding|xdmp:get-response-code|xdmp:get-request-username|xdmp:get-request-user|xdmp:get-request-url|xdmp:get-request-protocol|xdmp:get-request-path|xdmp:get-request-method|xdmp:get-request-header-names|xdmp:get-request-header|xdmp:get-request-field-names|xdmp:get-request-field-filename|xdmp:get-request-field-content-type|xdmp:get-request-field|xdmp:get-request-client-certificate|xdmp:get-request-client-address|xdmp:get-request-body|xdmp:get-current-user|xdmp:get-current-roles|xdmp:get|xdmp:function-name|xdmp:function-module|xdmp:function|xdmp:from-json|xdmp:forests|xdmp:forest-status|xdmp:forest-restore|xdmp:forest-restart|xdmp:forest-name|xdmp:forest-delete|xdmp:forest-databases|xdmp:forest-counts|xdmp:forest-clear|xdmp:forest-backup|xdmp:forest|xdmp:filesystem-file|xdmp:filesystem-directory|xdmp:exists|xdmp:excel-convert|xdmp:eval-in|xdmp:eval|xdmp:estimate|xdmp:email|xdmp:element-content-type|xdmp:elapsed-time|xdmp:document-set-quality|xdmp:document-set-property|xdmp:document-set-properties|xdmp:document-set-permissions|xdmp:document-set-collections|xdmp:document-remove-properties|xdmp:document-remove-permissions|xdmp:document-remove-collections|xdmp:document-properties|xdmp:document-locks|xdmp:document-load|xdmp:document-insert|xdmp:document-get-quality|xdmp:document-get-properties|xdmp:document-get-permissions|xdmp:document-get-collections|xdmp:document-get|xdmp:document-forest|xdmp:document-delete|xdmp:document-add-properties|xdmp:document-add-permissions|xdmp:document-add-collections|xdmp:directory-properties|xdmp:directory-locks|xdmp:directory-delete|xdmp:directory-create|xdmp:directory|xdmp:diacritic-less|xdmp:describe|xdmp:default-permissions|xdmp:default-collections|xdmp:databases|xdmp:database-restore-validate|xdmp:database-restore-status|xdmp:database-restore-cancel|xdmp:database-restore|xdmp:database-name|xdmp:database-forests|xdmp:database-backup-validate|xdmp:database-backup-status|xdmp:database-backup-purge|xdmp:database-backup-cancel|xdmp:database-backup|xdmp:database|xdmp:collection-properties|xdmp:collection-locks|xdmp:collection-delete|xdmp:collation-canonical-uri|xdmp:castable-as|xdmp:can-grant-roles|xdmp:base64-encode|xdmp:base64-decode|xdmp:architecture|xdmp:apply|xdmp:amp-roles|xdmp:amp|xdmp:add64|xdmp:add-response-header|xdmp:access|trgr:trigger-set-recursive|trgr:trigger-set-permissions|trgr:trigger-set-name|trgr:trigger-set-module|trgr:trigger-set-event|trgr:trigger-set-description|trgr:trigger-remove-permissions|trgr:trigger-module|trgr:trigger-get-permissions|trgr:trigger-enable|trgr:trigger-disable|trgr:trigger-database-online-event|trgr:trigger-data-event|trgr:trigger-add-permissions|trgr:remove-trigger|trgr:property-content|trgr:pre-commit|trgr:post-commit|trgr:get-trigger-by-id|trgr:get-trigger|trgr:document-scope|trgr:document-content|trgr:directory-scope|trgr:create-trigger|trgr:collection-scope|trgr:any-property-content|thsr:set-entry|thsr:remove-term|thsr:remove-synonym|thsr:remove-entry|thsr:query-lookup|thsr:lookup|thsr:load|thsr:insert|thsr:expand|thsr:add-synonym|spell:suggest-detailed|spell:suggest|spell:remove-word|spell:make-dictionary|spell:load|spell:levenshtein-distance|spell:is-correct|spell:insert|spell:double-metaphone|spell:add-word|sec:users-collection|sec:user-set-roles|sec:user-set-password|sec:user-set-name|sec:user-set-description|sec:user-set-default-permissions|sec:user-set-default-collections|sec:user-remove-roles|sec:user-privileges|sec:user-get-roles|sec:user-get-description|sec:user-get-default-permissions|sec:user-get-default-collections|sec:user-doc-permissions|sec:user-doc-collections|sec:user-add-roles|sec:unprotect-collection|sec:uid-for-name|sec:set-realm|sec:security-version|sec:security-namespace|sec:security-installed|sec:security-collection|sec:roles-collection|sec:role-set-roles|sec:role-set-name|sec:role-set-description|sec:role-set-default-permissions|sec:role-set-default-collections|sec:role-remove-roles|sec:role-privileges|sec:role-get-roles|sec:role-get-description|sec:role-get-default-permissions|sec:role-get-default-collections|sec:role-doc-permissions|sec:role-doc-collections|sec:role-add-roles|sec:remove-user|sec:remove-role-from-users|sec:remove-role-from-role|sec:remove-role-from-privileges|sec:remove-role-from-amps|sec:remove-role|sec:remove-privilege|sec:remove-amp|sec:protect-collection|sec:privileges-collection|sec:privilege-set-roles|sec:privilege-set-name|sec:privilege-remove-roles|sec:privilege-get-roles|sec:privilege-add-roles|sec:priv-doc-permissions|sec:priv-doc-collections|sec:get-user-names|sec:get-unique-elem-id|sec:get-role-names|sec:get-role-ids|sec:get-privilege|sec:get-distinct-permissions|sec:get-collection|sec:get-amp|sec:create-user-with-role|sec:create-user|sec:create-role|sec:create-privilege|sec:create-amp|sec:collections-collection|sec:collection-set-permissions|sec:collection-remove-permissions|sec:collection-get-permissions|sec:collection-add-permissions|sec:check-admin|sec:amps-collection|sec:amp-set-roles|sec:amp-remove-roles|sec:amp-get-roles|sec:amp-doc-permissions|sec:amp-doc-collections|sec:amp-add-roles|search:unparse|search:suggest|search:snippet|search:search|search:resolve-nodes|search:resolve|search:remove-constraint|search:parse|search:get-default-options|search:estimate|search:check-options|prof:value|prof:reset|prof:report|prof:invoke|prof:eval|prof:enable|prof:disable|prof:allowed|ppt:clean|pki:template-set-request|pki:template-set-name|pki:template-set-key-type|pki:template-set-key-options|pki:template-set-description|pki:template-in-use|pki:template-get-version|pki:template-get-request|pki:template-get-name|pki:template-get-key-type|pki:template-get-key-options|pki:template-get-id|pki:template-get-description|pki:need-certificate|pki:is-temporary|pki:insert-trusted-certificates|pki:insert-template|pki:insert-signed-certificates|pki:insert-certificate-revocation-list|pki:get-trusted-certificate-ids|pki:get-template-ids|pki:get-template-certificate-authority|pki:get-template-by-name|pki:get-template|pki:get-pending-certificate-requests-xml|pki:get-pending-certificate-requests-pem|pki:get-pending-certificate-request|pki:get-certificates-for-template-xml|pki:get-certificates-for-template|pki:get-certificates|pki:get-certificate-xml|pki:get-certificate-pem|pki:get-certificate|pki:generate-temporary-certificate-if-necessary|pki:generate-temporary-certificate|pki:generate-template-certificate-authority|pki:generate-certificate-request|pki:delete-template|pki:delete-certificate|pki:create-template|pdf:make-toc|pdf:insert-toc-headers|pdf:get-toc|pdf:clean|p:status-transition|p:state-transition|p:remove|p:pipelines|p:insert|p:get-by-id|p:get|p:execute|p:create|p:condition|p:collection|p:action|ooxml:runs-merge|ooxml:package-uris|ooxml:package-parts-insert|ooxml:package-parts|msword:clean|mcgm:polygon|mcgm:point|mcgm:geospatial-query-from-elements|mcgm:geospatial-query|mcgm:circle|math:tanh|math:tan|math:sqrt|math:sinh|math:sin|math:pow|math:modf|math:log10|math:log|math:ldexp|math:frexp|math:fmod|math:floor|math:fabs|math:exp|math:cosh|math:cos|math:ceil|math:atan2|math:atan|math:asin|math:acos|map:put|map:map|map:keys|map:get|map:delete|map:count|map:clear|lnk:to|lnk:remove|lnk:insert|lnk:get|lnk:from|lnk:create|kml:polygon|kml:point|kml:interior-polygon|kml:geospatial-query-from-elements|kml:geospatial-query|kml:circle|kml:box|gml:polygon|gml:point|gml:interior-polygon|gml:geospatial-query-from-elements|gml:geospatial-query|gml:circle|gml:box|georss:point|georss:geospatial-query|georss:circle|geo:polygon|geo:point|geo:interior-polygon|geo:geospatial-query-from-elements|geo:geospatial-query|geo:circle|geo:box|fn:zero-or-one|fn:years-from-duration|fn:year-from-dateTime|fn:year-from-date|fn:upper-case|fn:unordered|fn:true|fn:translate|fn:trace|fn:tokenize|fn:timezone-from-time|fn:timezone-from-dateTime|fn:timezone-from-date|fn:sum|fn:subtract-dateTimes-yielding-yearMonthDuration|fn:subtract-dateTimes-yielding-dayTimeDuration|fn:substring-before|fn:substring-after|fn:substring|fn:subsequence|fn:string-to-codepoints|fn:string-pad|fn:string-length|fn:string-join|fn:string|fn:static-base-uri|fn:starts-with|fn:seconds-from-time|fn:seconds-from-duration|fn:seconds-from-dateTime|fn:round-half-to-even|fn:round|fn:root|fn:reverse|fn:resolve-uri|fn:resolve-QName|fn:replace|fn:remove|fn:QName|fn:prefix-from-QName|fn:position|fn:one-or-more|fn:number|fn:not|fn:normalize-unicode|fn:normalize-space|fn:node-name|fn:node-kind|fn:nilled|fn:namespace-uri-from-QName|fn:namespace-uri-for-prefix|fn:namespace-uri|fn:name|fn:months-from-duration|fn:month-from-dateTime|fn:month-from-date|fn:minutes-from-time|fn:minutes-from-duration|fn:minutes-from-dateTime|fn:min|fn:max|fn:matches|fn:lower-case|fn:local-name-from-QName|fn:local-name|fn:last|fn:lang|fn:iri-to-uri|fn:insert-before|fn:index-of|fn:in-scope-prefixes|fn:implicit-timezone|fn:idref|fn:id|fn:hours-from-time|fn:hours-from-duration|fn:hours-from-dateTime|fn:floor|fn:false|fn:expanded-QName|fn:exists|fn:exactly-one|fn:escape-uri|fn:escape-html-uri|fn:error|fn:ends-with|fn:encode-for-uri|fn:empty|fn:document-uri|fn:doc-available|fn:doc|fn:distinct-values|fn:distinct-nodes|fn:default-collation|fn:deep-equal|fn:days-from-duration|fn:day-from-dateTime|fn:day-from-date|fn:data|fn:current-time|fn:current-dateTime|fn:current-date|fn:count|fn:contains|fn:concat|fn:compare|fn:collection|fn:codepoints-to-string|fn:codepoint-equal|fn:ceiling|fn:boolean|fn:base-uri|fn:avg|fn:adjust-time-to-timezone|fn:adjust-dateTime-to-timezone|fn:adjust-date-to-timezone|fn:abs|feed:unsubscribe|feed:subscription|feed:subscribe|feed:request|feed:item|feed:description|excel:clean|entity:enrich|dom:set-pipelines|dom:set-permissions|dom:set-name|dom:set-evaluation-context|dom:set-domain-scope|dom:set-description|dom:remove-pipeline|dom:remove-permissions|dom:remove|dom:get|dom:evaluation-context|dom:domains|dom:domain-scope|dom:create|dom:configuration-set-restart-user|dom:configuration-set-permissions|dom:configuration-set-evaluation-context|dom:configuration-set-default-domain|dom:configuration-get|dom:configuration-create|dom:collection|dom:add-pipeline|dom:add-permissions|dls:retention-rules|dls:retention-rule-remove|dls:retention-rule-insert|dls:retention-rule|dls:purge|dls:node-expand|dls:link-references|dls:link-expand|dls:documents-query|dls:document-versions-query|dls:document-version-uri|dls:document-version-query|dls:document-version-delete|dls:document-version-as-of|dls:document-version|dls:document-update|dls:document-unmanage|dls:document-set-quality|dls:document-set-property|dls:document-set-properties|dls:document-set-permissions|dls:document-set-collections|dls:document-retention-rules|dls:document-remove-properties|dls:document-remove-permissions|dls:document-remove-collections|dls:document-purge|dls:document-manage|dls:document-is-managed|dls:document-insert-and-manage|dls:document-include-query|dls:document-history|dls:document-get-permissions|dls:document-extract-part|dls:document-delete|dls:document-checkout-status|dls:document-checkout|dls:document-checkin|dls:document-add-properties|dls:document-add-permissions|dls:document-add-collections|dls:break-checkout|dls:author-query|dls:as-of-query|dbk:convert|dbg:wait|dbg:value|dbg:stopped|dbg:stop|dbg:step|dbg:status|dbg:stack|dbg:out|dbg:next|dbg:line|dbg:invoke|dbg:function|dbg:finish|dbg:expr|dbg:eval|dbg:disconnect|dbg:detach|dbg:continue|dbg:connect|dbg:clear|dbg:breakpoints|dbg:break|dbg:attached|dbg:attach|cvt:save-converted-documents|cvt:part-uri|cvt:destination-uri|cvt:basepath|cvt:basename|cts:words|cts:word-query-weight|cts:word-query-text|cts:word-query-options|cts:word-query|cts:word-match|cts:walk|cts:uris|cts:uri-match|cts:train|cts:tokenize|cts:thresholds|cts:stem|cts:similar-query-weight|cts:similar-query-nodes|cts:similar-query|cts:shortest-distance|cts:search|cts:score|cts:reverse-query-weight|cts:reverse-query-nodes|cts:reverse-query|cts:remainder|cts:registered-query-weight|cts:registered-query-options|cts:registered-query-ids|cts:registered-query|cts:register|cts:query|cts:quality|cts:properties-query-query|cts:properties-query|cts:polygon-vertices|cts:polygon|cts:point-longitude|cts:point-latitude|cts:point|cts:or-query-queries|cts:or-query|cts:not-query-weight|cts:not-query-query|cts:not-query|cts:near-query-weight|cts:near-query-queries|cts:near-query-options|cts:near-query-distance|cts:near-query|cts:highlight|cts:geospatial-co-occurrences|cts:frequency|cts:fitness|cts:field-words|cts:field-word-query-weight|cts:field-word-query-text|cts:field-word-query-options|cts:field-word-query-field-name|cts:field-word-query|cts:field-word-match|cts:entity-highlight|cts:element-words|cts:element-word-query-weight|cts:element-word-query-text|cts:element-word-query-options|cts:element-word-query-element-name|cts:element-word-query|cts:element-word-match|cts:element-values|cts:element-value-ranges|cts:element-value-query-weight|cts:element-value-query-text|cts:element-value-query-options|cts:element-value-query-element-name|cts:element-value-query|cts:element-value-match|cts:element-value-geospatial-co-occurrences|cts:element-value-co-occurrences|cts:element-range-query-weight|cts:element-range-query-value|cts:element-range-query-options|cts:element-range-query-operator|cts:element-range-query-element-name|cts:element-range-query|cts:element-query-query|cts:element-query-element-name|cts:element-query|cts:element-pair-geospatial-values|cts:element-pair-geospatial-value-match|cts:element-pair-geospatial-query-weight|cts:element-pair-geospatial-query-region|cts:element-pair-geospatial-query-options|cts:element-pair-geospatial-query-longitude-name|cts:element-pair-geospatial-query-latitude-name|cts:element-pair-geospatial-query-element-name|cts:element-pair-geospatial-query|cts:element-pair-geospatial-boxes|cts:element-geospatial-values|cts:element-geospatial-value-match|cts:element-geospatial-query-weight|cts:element-geospatial-query-region|cts:element-geospatial-query-options|cts:element-geospatial-query-element-name|cts:element-geospatial-query|cts:element-geospatial-boxes|cts:element-child-geospatial-values|cts:element-child-geospatial-value-match|cts:element-child-geospatial-query-weight|cts:element-child-geospatial-query-region|cts:element-child-geospatial-query-options|cts:element-child-geospatial-query-element-name|cts:element-child-geospatial-query-child-name|cts:element-child-geospatial-query|cts:element-child-geospatial-boxes|cts:element-attribute-words|cts:element-attribute-word-query-weight|cts:element-attribute-word-query-text|cts:element-attribute-word-query-options|cts:element-attribute-word-query-element-name|cts:element-attribute-word-query-attribute-name|cts:element-attribute-word-query|cts:element-attribute-word-match|cts:element-attribute-values|cts:element-attribute-value-ranges|cts:element-attribute-value-query-weight|cts:element-attribute-value-query-text|cts:element-attribute-value-query-options|cts:element-attribute-value-query-element-name|cts:element-attribute-value-query-attribute-name|cts:element-attribute-value-query|cts:element-attribute-value-match|cts:element-attribute-value-geospatial-co-occurrences|cts:element-attribute-value-co-occurrences|cts:element-attribute-range-query-weight|cts:element-attribute-range-query-value|cts:element-attribute-range-query-options|cts:element-attribute-range-query-operator|cts:element-attribute-range-query-element-name|cts:element-attribute-range-query-attribute-name|cts:element-attribute-range-query|cts:element-attribute-pair-geospatial-values|cts:element-attribute-pair-geospatial-value-match|cts:element-attribute-pair-geospatial-query-weight|cts:element-attribute-pair-geospatial-query-region|cts:element-attribute-pair-geospatial-query-options|cts:element-attribute-pair-geospatial-query-longitude-name|cts:element-attribute-pair-geospatial-query-latitude-name|cts:element-attribute-pair-geospatial-query-element-name|cts:element-attribute-pair-geospatial-query|cts:element-attribute-pair-geospatial-boxes|cts:document-query-uris|cts:document-query|cts:distance|cts:directory-query-uris|cts:directory-query-depth|cts:directory-query|cts:destination|cts:deregister|cts:contains|cts:confidence|cts:collections|cts:collection-query-uris|cts:collection-query|cts:collection-match|cts:classify|cts:circle-radius|cts:circle-center|cts:circle|cts:box-west|cts:box-south|cts:box-north|cts:box-east|cts:box|cts:bearing|cts:arc-intersection|cts:and-query-queries|cts:and-query-options|cts:and-query|cts:and-not-query-positive-query|cts:and-not-query-negative-query|cts:and-not-query|css:get|css:convert|cpf:success|cpf:failure|cpf:document-set-state|cpf:document-set-processing-status|cpf:document-set-last-updated|cpf:document-set-error|cpf:document-get-state|cpf:document-get-processing-status|cpf:document-get-last-updated|cpf:document-get-error|cpf:check-transition|alert:spawn-matching-actions|alert:rule-user-id-query|alert:rule-set-user-id|alert:rule-set-query|alert:rule-set-options|alert:rule-set-name|alert:rule-set-description|alert:rule-set-action|alert:rule-remove|alert:rule-name-query|alert:rule-insert|alert:rule-id-query|alert:rule-get-user-id|alert:rule-get-query|alert:rule-get-options|alert:rule-get-name|alert:rule-get-id|alert:rule-get-description|alert:rule-get-action|alert:rule-action-query|alert:remove-triggers|alert:make-rule|alert:make-log-action|alert:make-config|alert:make-action|alert:invoke-matching-actions|alert:get-my-rules|alert:get-all-rules|alert:get-actions|alert:find-matching-rules|alert:create-triggers|alert:config-set-uri|alert:config-set-trigger-ids|alert:config-set-options|alert:config-set-name|alert:config-set-description|alert:config-set-cpf-domain-names|alert:config-set-cpf-domain-ids|alert:config-insert|alert:config-get-uri|alert:config-get-trigger-ids|alert:config-get-options|alert:config-get-name|alert:config-get-id|alert:config-get-description|alert:config-get-cpf-domain-names|alert:config-get-cpf-domain-ids|alert:config-get|alert:config-delete|alert:action-set-options|alert:action-set-name|alert:action-set-module-root|alert:action-set-module-db|alert:action-set-module|alert:action-set-description|alert:action-remove|alert:action-insert|alert:action-get-options|alert:action-get-name|alert:action-get-module-root|alert:action-get-module-db|alert:action-get-module|alert:action-get-description|zero-or-one|years-from-duration|year-from-dateTime|year-from-date|upper-case|unordered|true|translate|trace|tokenize|timezone-from-time|timezone-from-dateTime|timezone-from-date|sum|subtract-dateTimes-yielding-yearMonthDuration|subtract-dateTimes-yielding-dayTimeDuration|substring-before|substring-after|substring|subsequence|string-to-codepoints|string-pad|string-length|string-join|string|static-base-uri|starts-with|seconds-from-time|seconds-from-duration|seconds-from-dateTime|round-half-to-even|round|root|reverse|resolve-uri|resolve-QName|replace|remove|QName|prefix-from-QName|position|one-or-more|number|not|normalize-unicode|normalize-space|node-name|node-kind|nilled|namespace-uri-from-QName|namespace-uri-for-prefix|namespace-uri|name|months-from-duration|month-from-dateTime|month-from-date|minutes-from-time|minutes-from-duration|minutes-from-dateTime|min|max|matches|lower-case|local-name-from-QName|local-name|last|lang|iri-to-uri|insert-before|index-of|in-scope-prefixes|implicit-timezone|idref|id|hours-from-time|hours-from-duration|hours-from-dateTime|floor|false|expanded-QName|exists|exactly-one|escape-uri|escape-html-uri|error|ends-with|encode-for-uri|empty|document-uri|doc-available|doc|distinct-values|distinct-nodes|default-collation|deep-equal|days-from-duration|day-from-dateTime|day-from-date|data|current-time|current-dateTime|current-date|count|contains|concat|compare|collection|codepoints-to-string|codepoint-equal|ceiling|boolean|base-uri|avg|adjust-time-to-timezone|adjust-dateTime-to-timezone|adjust-date-to-timezone|abs)\b/],
                +["pln",/^[A-Za-z0-9_\-\:]+/],["pln",/^[\t\n\r \xA0]+/]]),["xq","xquery"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-xquery.js b/blockly/webif/static/js/google-prettify/lang-xquery.js
                new file mode 100644
                index 000000000..a6d85372d
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-xquery.js
                @@ -0,0 +1,19 @@
                +/*
                +
                + Copyright (C) 2011 Patrick Wied
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["var pln",/^\$[A-Za-z0-9_\-]+/,null,"$"]],[["pln",/^[\s=][<>][\s=]/],["lit",/^\@[\w-]+/],["tag",/^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["com",/^\(:[\s\S]*?:\)/],["pln",/^[\/\{\};,\[\]\(\)]$/],["str",/^(?:\"(?:[^\"\\\{]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\\{]|\\[\s\S])*(?:\'|$))/,null,"\"'"],["kwd",/^(?:xquery|where|version|variable|union|typeswitch|treat|to|then|text|stable|sortby|some|self|schema|satisfies|returns|return|ref|processing-instruction|preceding-sibling|preceding|precedes|parent|only|of|node|namespace|module|let|item|intersect|instance|in|import|if|function|for|follows|following-sibling|following|external|except|every|else|element|descending|descendant-or-self|descendant|define|default|declare|comment|child|cast|case|before|attribute|assert|ascending|as|ancestor-or-self|ancestor|after|eq|order|by|or|and|schema-element|document-node|node|at)\b/],
                +["typ",/^(?:xs:yearMonthDuration|xs:unsignedLong|xs:time|xs:string|xs:short|xs:QName|xs:Name|xs:long|xs:integer|xs:int|xs:gYearMonth|xs:gYear|xs:gMonthDay|xs:gDay|xs:float|xs:duration|xs:double|xs:decimal|xs:dayTimeDuration|xs:dateTime|xs:date|xs:byte|xs:boolean|xs:anyURI|xf:yearMonthDuration)\b/,null],["fun pln",/^(?:xp:dereference|xinc:node-expand|xinc:link-references|xinc:link-expand|xhtml:restructure|xhtml:clean|xhtml:add-lists|xdmp:zip-manifest|xdmp:zip-get|xdmp:zip-create|xdmp:xquery-version|xdmp:word-convert|xdmp:with-namespaces|xdmp:version|xdmp:value|xdmp:user-roles|xdmp:user-last-login|xdmp:user|xdmp:url-encode|xdmp:url-decode|xdmp:uri-is-file|xdmp:uri-format|xdmp:uri-content-type|xdmp:unquote|xdmp:unpath|xdmp:triggers-database|xdmp:trace|xdmp:to-json|xdmp:tidy|xdmp:subbinary|xdmp:strftime|xdmp:spawn-in|xdmp:spawn|xdmp:sleep|xdmp:shutdown|xdmp:set-session-field|xdmp:set-response-encoding|xdmp:set-response-content-type|xdmp:set-response-code|xdmp:set-request-time-limit|xdmp:set|xdmp:servers|xdmp:server-status|xdmp:server-name|xdmp:server|xdmp:security-database|xdmp:security-assert|xdmp:schema-database|xdmp:save|xdmp:role-roles|xdmp:role|xdmp:rethrow|xdmp:restart|xdmp:request-timestamp|xdmp:request-status|xdmp:request-cancel|xdmp:request|xdmp:redirect-response|xdmp:random|xdmp:quote|xdmp:query-trace|xdmp:query-meters|xdmp:product-edition|xdmp:privilege-roles|xdmp:privilege|xdmp:pretty-print|xdmp:powerpoint-convert|xdmp:platform|xdmp:permission|xdmp:pdf-convert|xdmp:path|xdmp:octal-to-integer|xdmp:node-uri|xdmp:node-replace|xdmp:node-kind|xdmp:node-insert-child|xdmp:node-insert-before|xdmp:node-insert-after|xdmp:node-delete|xdmp:node-database|xdmp:mul64|xdmp:modules-root|xdmp:modules-database|xdmp:merging|xdmp:merge-cancel|xdmp:merge|xdmp:md5|xdmp:logout|xdmp:login|xdmp:log-level|xdmp:log|xdmp:lock-release|xdmp:lock-acquire|xdmp:load|xdmp:invoke-in|xdmp:invoke|xdmp:integer-to-octal|xdmp:integer-to-hex|xdmp:http-put|xdmp:http-post|xdmp:http-options|xdmp:http-head|xdmp:http-get|xdmp:http-delete|xdmp:hosts|xdmp:host-status|xdmp:host-name|xdmp:host|xdmp:hex-to-integer|xdmp:hash64|xdmp:hash32|xdmp:has-privilege|xdmp:groups|xdmp:group-serves|xdmp:group-servers|xdmp:group-name|xdmp:group-hosts|xdmp:group|xdmp:get-session-field-names|xdmp:get-session-field|xdmp:get-response-encoding|xdmp:get-response-code|xdmp:get-request-username|xdmp:get-request-user|xdmp:get-request-url|xdmp:get-request-protocol|xdmp:get-request-path|xdmp:get-request-method|xdmp:get-request-header-names|xdmp:get-request-header|xdmp:get-request-field-names|xdmp:get-request-field-filename|xdmp:get-request-field-content-type|xdmp:get-request-field|xdmp:get-request-client-certificate|xdmp:get-request-client-address|xdmp:get-request-body|xdmp:get-current-user|xdmp:get-current-roles|xdmp:get|xdmp:function-name|xdmp:function-module|xdmp:function|xdmp:from-json|xdmp:forests|xdmp:forest-status|xdmp:forest-restore|xdmp:forest-restart|xdmp:forest-name|xdmp:forest-delete|xdmp:forest-databases|xdmp:forest-counts|xdmp:forest-clear|xdmp:forest-backup|xdmp:forest|xdmp:filesystem-file|xdmp:filesystem-directory|xdmp:exists|xdmp:excel-convert|xdmp:eval-in|xdmp:eval|xdmp:estimate|xdmp:email|xdmp:element-content-type|xdmp:elapsed-time|xdmp:document-set-quality|xdmp:document-set-property|xdmp:document-set-properties|xdmp:document-set-permissions|xdmp:document-set-collections|xdmp:document-remove-properties|xdmp:document-remove-permissions|xdmp:document-remove-collections|xdmp:document-properties|xdmp:document-locks|xdmp:document-load|xdmp:document-insert|xdmp:document-get-quality|xdmp:document-get-properties|xdmp:document-get-permissions|xdmp:document-get-collections|xdmp:document-get|xdmp:document-forest|xdmp:document-delete|xdmp:document-add-properties|xdmp:document-add-permissions|xdmp:document-add-collections|xdmp:directory-properties|xdmp:directory-locks|xdmp:directory-delete|xdmp:directory-create|xdmp:directory|xdmp:diacritic-less|xdmp:describe|xdmp:default-permissions|xdmp:default-collections|xdmp:databases|xdmp:database-restore-validate|xdmp:database-restore-status|xdmp:database-restore-cancel|xdmp:database-restore|xdmp:database-name|xdmp:database-forests|xdmp:database-backup-validate|xdmp:database-backup-status|xdmp:database-backup-purge|xdmp:database-backup-cancel|xdmp:database-backup|xdmp:database|xdmp:collection-properties|xdmp:collection-locks|xdmp:collection-delete|xdmp:collation-canonical-uri|xdmp:castable-as|xdmp:can-grant-roles|xdmp:base64-encode|xdmp:base64-decode|xdmp:architecture|xdmp:apply|xdmp:amp-roles|xdmp:amp|xdmp:add64|xdmp:add-response-header|xdmp:access|trgr:trigger-set-recursive|trgr:trigger-set-permissions|trgr:trigger-set-name|trgr:trigger-set-module|trgr:trigger-set-event|trgr:trigger-set-description|trgr:trigger-remove-permissions|trgr:trigger-module|trgr:trigger-get-permissions|trgr:trigger-enable|trgr:trigger-disable|trgr:trigger-database-online-event|trgr:trigger-data-event|trgr:trigger-add-permissions|trgr:remove-trigger|trgr:property-content|trgr:pre-commit|trgr:post-commit|trgr:get-trigger-by-id|trgr:get-trigger|trgr:document-scope|trgr:document-content|trgr:directory-scope|trgr:create-trigger|trgr:collection-scope|trgr:any-property-content|thsr:set-entry|thsr:remove-term|thsr:remove-synonym|thsr:remove-entry|thsr:query-lookup|thsr:lookup|thsr:load|thsr:insert|thsr:expand|thsr:add-synonym|spell:suggest-detailed|spell:suggest|spell:remove-word|spell:make-dictionary|spell:load|spell:levenshtein-distance|spell:is-correct|spell:insert|spell:double-metaphone|spell:add-word|sec:users-collection|sec:user-set-roles|sec:user-set-password|sec:user-set-name|sec:user-set-description|sec:user-set-default-permissions|sec:user-set-default-collections|sec:user-remove-roles|sec:user-privileges|sec:user-get-roles|sec:user-get-description|sec:user-get-default-permissions|sec:user-get-default-collections|sec:user-doc-permissions|sec:user-doc-collections|sec:user-add-roles|sec:unprotect-collection|sec:uid-for-name|sec:set-realm|sec:security-version|sec:security-namespace|sec:security-installed|sec:security-collection|sec:roles-collection|sec:role-set-roles|sec:role-set-name|sec:role-set-description|sec:role-set-default-permissions|sec:role-set-default-collections|sec:role-remove-roles|sec:role-privileges|sec:role-get-roles|sec:role-get-description|sec:role-get-default-permissions|sec:role-get-default-collections|sec:role-doc-permissions|sec:role-doc-collections|sec:role-add-roles|sec:remove-user|sec:remove-role-from-users|sec:remove-role-from-role|sec:remove-role-from-privileges|sec:remove-role-from-amps|sec:remove-role|sec:remove-privilege|sec:remove-amp|sec:protect-collection|sec:privileges-collection|sec:privilege-set-roles|sec:privilege-set-name|sec:privilege-remove-roles|sec:privilege-get-roles|sec:privilege-add-roles|sec:priv-doc-permissions|sec:priv-doc-collections|sec:get-user-names|sec:get-unique-elem-id|sec:get-role-names|sec:get-role-ids|sec:get-privilege|sec:get-distinct-permissions|sec:get-collection|sec:get-amp|sec:create-user-with-role|sec:create-user|sec:create-role|sec:create-privilege|sec:create-amp|sec:collections-collection|sec:collection-set-permissions|sec:collection-remove-permissions|sec:collection-get-permissions|sec:collection-add-permissions|sec:check-admin|sec:amps-collection|sec:amp-set-roles|sec:amp-remove-roles|sec:amp-get-roles|sec:amp-doc-permissions|sec:amp-doc-collections|sec:amp-add-roles|search:unparse|search:suggest|search:snippet|search:search|search:resolve-nodes|search:resolve|search:remove-constraint|search:parse|search:get-default-options|search:estimate|search:check-options|prof:value|prof:reset|prof:report|prof:invoke|prof:eval|prof:enable|prof:disable|prof:allowed|ppt:clean|pki:template-set-request|pki:template-set-name|pki:template-set-key-type|pki:template-set-key-options|pki:template-set-description|pki:template-in-use|pki:template-get-version|pki:template-get-request|pki:template-get-name|pki:template-get-key-type|pki:template-get-key-options|pki:template-get-id|pki:template-get-description|pki:need-certificate|pki:is-temporary|pki:insert-trusted-certificates|pki:insert-template|pki:insert-signed-certificates|pki:insert-certificate-revocation-list|pki:get-trusted-certificate-ids|pki:get-template-ids|pki:get-template-certificate-authority|pki:get-template-by-name|pki:get-template|pki:get-pending-certificate-requests-xml|pki:get-pending-certificate-requests-pem|pki:get-pending-certificate-request|pki:get-certificates-for-template-xml|pki:get-certificates-for-template|pki:get-certificates|pki:get-certificate-xml|pki:get-certificate-pem|pki:get-certificate|pki:generate-temporary-certificate-if-necessary|pki:generate-temporary-certificate|pki:generate-template-certificate-authority|pki:generate-certificate-request|pki:delete-template|pki:delete-certificate|pki:create-template|pdf:make-toc|pdf:insert-toc-headers|pdf:get-toc|pdf:clean|p:status-transition|p:state-transition|p:remove|p:pipelines|p:insert|p:get-by-id|p:get|p:execute|p:create|p:condition|p:collection|p:action|ooxml:runs-merge|ooxml:package-uris|ooxml:package-parts-insert|ooxml:package-parts|msword:clean|mcgm:polygon|mcgm:point|mcgm:geospatial-query-from-elements|mcgm:geospatial-query|mcgm:circle|math:tanh|math:tan|math:sqrt|math:sinh|math:sin|math:pow|math:modf|math:log10|math:log|math:ldexp|math:frexp|math:fmod|math:floor|math:fabs|math:exp|math:cosh|math:cos|math:ceil|math:atan2|math:atan|math:asin|math:acos|map:put|map:map|map:keys|map:get|map:delete|map:count|map:clear|lnk:to|lnk:remove|lnk:insert|lnk:get|lnk:from|lnk:create|kml:polygon|kml:point|kml:interior-polygon|kml:geospatial-query-from-elements|kml:geospatial-query|kml:circle|kml:box|gml:polygon|gml:point|gml:interior-polygon|gml:geospatial-query-from-elements|gml:geospatial-query|gml:circle|gml:box|georss:point|georss:geospatial-query|georss:circle|geo:polygon|geo:point|geo:interior-polygon|geo:geospatial-query-from-elements|geo:geospatial-query|geo:circle|geo:box|fn:zero-or-one|fn:years-from-duration|fn:year-from-dateTime|fn:year-from-date|fn:upper-case|fn:unordered|fn:true|fn:translate|fn:trace|fn:tokenize|fn:timezone-from-time|fn:timezone-from-dateTime|fn:timezone-from-date|fn:sum|fn:subtract-dateTimes-yielding-yearMonthDuration|fn:subtract-dateTimes-yielding-dayTimeDuration|fn:substring-before|fn:substring-after|fn:substring|fn:subsequence|fn:string-to-codepoints|fn:string-pad|fn:string-length|fn:string-join|fn:string|fn:static-base-uri|fn:starts-with|fn:seconds-from-time|fn:seconds-from-duration|fn:seconds-from-dateTime|fn:round-half-to-even|fn:round|fn:root|fn:reverse|fn:resolve-uri|fn:resolve-QName|fn:replace|fn:remove|fn:QName|fn:prefix-from-QName|fn:position|fn:one-or-more|fn:number|fn:not|fn:normalize-unicode|fn:normalize-space|fn:node-name|fn:node-kind|fn:nilled|fn:namespace-uri-from-QName|fn:namespace-uri-for-prefix|fn:namespace-uri|fn:name|fn:months-from-duration|fn:month-from-dateTime|fn:month-from-date|fn:minutes-from-time|fn:minutes-from-duration|fn:minutes-from-dateTime|fn:min|fn:max|fn:matches|fn:lower-case|fn:local-name-from-QName|fn:local-name|fn:last|fn:lang|fn:iri-to-uri|fn:insert-before|fn:index-of|fn:in-scope-prefixes|fn:implicit-timezone|fn:idref|fn:id|fn:hours-from-time|fn:hours-from-duration|fn:hours-from-dateTime|fn:floor|fn:false|fn:expanded-QName|fn:exists|fn:exactly-one|fn:escape-uri|fn:escape-html-uri|fn:error|fn:ends-with|fn:encode-for-uri|fn:empty|fn:document-uri|fn:doc-available|fn:doc|fn:distinct-values|fn:distinct-nodes|fn:default-collation|fn:deep-equal|fn:days-from-duration|fn:day-from-dateTime|fn:day-from-date|fn:data|fn:current-time|fn:current-dateTime|fn:current-date|fn:count|fn:contains|fn:concat|fn:compare|fn:collection|fn:codepoints-to-string|fn:codepoint-equal|fn:ceiling|fn:boolean|fn:base-uri|fn:avg|fn:adjust-time-to-timezone|fn:adjust-dateTime-to-timezone|fn:adjust-date-to-timezone|fn:abs|feed:unsubscribe|feed:subscription|feed:subscribe|feed:request|feed:item|feed:description|excel:clean|entity:enrich|dom:set-pipelines|dom:set-permissions|dom:set-name|dom:set-evaluation-context|dom:set-domain-scope|dom:set-description|dom:remove-pipeline|dom:remove-permissions|dom:remove|dom:get|dom:evaluation-context|dom:domains|dom:domain-scope|dom:create|dom:configuration-set-restart-user|dom:configuration-set-permissions|dom:configuration-set-evaluation-context|dom:configuration-set-default-domain|dom:configuration-get|dom:configuration-create|dom:collection|dom:add-pipeline|dom:add-permissions|dls:retention-rules|dls:retention-rule-remove|dls:retention-rule-insert|dls:retention-rule|dls:purge|dls:node-expand|dls:link-references|dls:link-expand|dls:documents-query|dls:document-versions-query|dls:document-version-uri|dls:document-version-query|dls:document-version-delete|dls:document-version-as-of|dls:document-version|dls:document-update|dls:document-unmanage|dls:document-set-quality|dls:document-set-property|dls:document-set-properties|dls:document-set-permissions|dls:document-set-collections|dls:document-retention-rules|dls:document-remove-properties|dls:document-remove-permissions|dls:document-remove-collections|dls:document-purge|dls:document-manage|dls:document-is-managed|dls:document-insert-and-manage|dls:document-include-query|dls:document-history|dls:document-get-permissions|dls:document-extract-part|dls:document-delete|dls:document-checkout-status|dls:document-checkout|dls:document-checkin|dls:document-add-properties|dls:document-add-permissions|dls:document-add-collections|dls:break-checkout|dls:author-query|dls:as-of-query|dbk:convert|dbg:wait|dbg:value|dbg:stopped|dbg:stop|dbg:step|dbg:status|dbg:stack|dbg:out|dbg:next|dbg:line|dbg:invoke|dbg:function|dbg:finish|dbg:expr|dbg:eval|dbg:disconnect|dbg:detach|dbg:continue|dbg:connect|dbg:clear|dbg:breakpoints|dbg:break|dbg:attached|dbg:attach|cvt:save-converted-documents|cvt:part-uri|cvt:destination-uri|cvt:basepath|cvt:basename|cts:words|cts:word-query-weight|cts:word-query-text|cts:word-query-options|cts:word-query|cts:word-match|cts:walk|cts:uris|cts:uri-match|cts:train|cts:tokenize|cts:thresholds|cts:stem|cts:similar-query-weight|cts:similar-query-nodes|cts:similar-query|cts:shortest-distance|cts:search|cts:score|cts:reverse-query-weight|cts:reverse-query-nodes|cts:reverse-query|cts:remainder|cts:registered-query-weight|cts:registered-query-options|cts:registered-query-ids|cts:registered-query|cts:register|cts:query|cts:quality|cts:properties-query-query|cts:properties-query|cts:polygon-vertices|cts:polygon|cts:point-longitude|cts:point-latitude|cts:point|cts:or-query-queries|cts:or-query|cts:not-query-weight|cts:not-query-query|cts:not-query|cts:near-query-weight|cts:near-query-queries|cts:near-query-options|cts:near-query-distance|cts:near-query|cts:highlight|cts:geospatial-co-occurrences|cts:frequency|cts:fitness|cts:field-words|cts:field-word-query-weight|cts:field-word-query-text|cts:field-word-query-options|cts:field-word-query-field-name|cts:field-word-query|cts:field-word-match|cts:entity-highlight|cts:element-words|cts:element-word-query-weight|cts:element-word-query-text|cts:element-word-query-options|cts:element-word-query-element-name|cts:element-word-query|cts:element-word-match|cts:element-values|cts:element-value-ranges|cts:element-value-query-weight|cts:element-value-query-text|cts:element-value-query-options|cts:element-value-query-element-name|cts:element-value-query|cts:element-value-match|cts:element-value-geospatial-co-occurrences|cts:element-value-co-occurrences|cts:element-range-query-weight|cts:element-range-query-value|cts:element-range-query-options|cts:element-range-query-operator|cts:element-range-query-element-name|cts:element-range-query|cts:element-query-query|cts:element-query-element-name|cts:element-query|cts:element-pair-geospatial-values|cts:element-pair-geospatial-value-match|cts:element-pair-geospatial-query-weight|cts:element-pair-geospatial-query-region|cts:element-pair-geospatial-query-options|cts:element-pair-geospatial-query-longitude-name|cts:element-pair-geospatial-query-latitude-name|cts:element-pair-geospatial-query-element-name|cts:element-pair-geospatial-query|cts:element-pair-geospatial-boxes|cts:element-geospatial-values|cts:element-geospatial-value-match|cts:element-geospatial-query-weight|cts:element-geospatial-query-region|cts:element-geospatial-query-options|cts:element-geospatial-query-element-name|cts:element-geospatial-query|cts:element-geospatial-boxes|cts:element-child-geospatial-values|cts:element-child-geospatial-value-match|cts:element-child-geospatial-query-weight|cts:element-child-geospatial-query-region|cts:element-child-geospatial-query-options|cts:element-child-geospatial-query-element-name|cts:element-child-geospatial-query-child-name|cts:element-child-geospatial-query|cts:element-child-geospatial-boxes|cts:element-attribute-words|cts:element-attribute-word-query-weight|cts:element-attribute-word-query-text|cts:element-attribute-word-query-options|cts:element-attribute-word-query-element-name|cts:element-attribute-word-query-attribute-name|cts:element-attribute-word-query|cts:element-attribute-word-match|cts:element-attribute-values|cts:element-attribute-value-ranges|cts:element-attribute-value-query-weight|cts:element-attribute-value-query-text|cts:element-attribute-value-query-options|cts:element-attribute-value-query-element-name|cts:element-attribute-value-query-attribute-name|cts:element-attribute-value-query|cts:element-attribute-value-match|cts:element-attribute-value-geospatial-co-occurrences|cts:element-attribute-value-co-occurrences|cts:element-attribute-range-query-weight|cts:element-attribute-range-query-value|cts:element-attribute-range-query-options|cts:element-attribute-range-query-operator|cts:element-attribute-range-query-element-name|cts:element-attribute-range-query-attribute-name|cts:element-attribute-range-query|cts:element-attribute-pair-geospatial-values|cts:element-attribute-pair-geospatial-value-match|cts:element-attribute-pair-geospatial-query-weight|cts:element-attribute-pair-geospatial-query-region|cts:element-attribute-pair-geospatial-query-options|cts:element-attribute-pair-geospatial-query-longitude-name|cts:element-attribute-pair-geospatial-query-latitude-name|cts:element-attribute-pair-geospatial-query-element-name|cts:element-attribute-pair-geospatial-query|cts:element-attribute-pair-geospatial-boxes|cts:document-query-uris|cts:document-query|cts:distance|cts:directory-query-uris|cts:directory-query-depth|cts:directory-query|cts:destination|cts:deregister|cts:contains|cts:confidence|cts:collections|cts:collection-query-uris|cts:collection-query|cts:collection-match|cts:classify|cts:circle-radius|cts:circle-center|cts:circle|cts:box-west|cts:box-south|cts:box-north|cts:box-east|cts:box|cts:bearing|cts:arc-intersection|cts:and-query-queries|cts:and-query-options|cts:and-query|cts:and-not-query-positive-query|cts:and-not-query-negative-query|cts:and-not-query|css:get|css:convert|cpf:success|cpf:failure|cpf:document-set-state|cpf:document-set-processing-status|cpf:document-set-last-updated|cpf:document-set-error|cpf:document-get-state|cpf:document-get-processing-status|cpf:document-get-last-updated|cpf:document-get-error|cpf:check-transition|alert:spawn-matching-actions|alert:rule-user-id-query|alert:rule-set-user-id|alert:rule-set-query|alert:rule-set-options|alert:rule-set-name|alert:rule-set-description|alert:rule-set-action|alert:rule-remove|alert:rule-name-query|alert:rule-insert|alert:rule-id-query|alert:rule-get-user-id|alert:rule-get-query|alert:rule-get-options|alert:rule-get-name|alert:rule-get-id|alert:rule-get-description|alert:rule-get-action|alert:rule-action-query|alert:remove-triggers|alert:make-rule|alert:make-log-action|alert:make-config|alert:make-action|alert:invoke-matching-actions|alert:get-my-rules|alert:get-all-rules|alert:get-actions|alert:find-matching-rules|alert:create-triggers|alert:config-set-uri|alert:config-set-trigger-ids|alert:config-set-options|alert:config-set-name|alert:config-set-description|alert:config-set-cpf-domain-names|alert:config-set-cpf-domain-ids|alert:config-insert|alert:config-get-uri|alert:config-get-trigger-ids|alert:config-get-options|alert:config-get-name|alert:config-get-id|alert:config-get-description|alert:config-get-cpf-domain-names|alert:config-get-cpf-domain-ids|alert:config-get|alert:config-delete|alert:action-set-options|alert:action-set-name|alert:action-set-module-root|alert:action-set-module-db|alert:action-set-module|alert:action-set-description|alert:action-remove|alert:action-insert|alert:action-get-options|alert:action-get-name|alert:action-get-module-root|alert:action-get-module-db|alert:action-get-module|alert:action-get-description|zero-or-one|years-from-duration|year-from-dateTime|year-from-date|upper-case|unordered|true|translate|trace|tokenize|timezone-from-time|timezone-from-dateTime|timezone-from-date|sum|subtract-dateTimes-yielding-yearMonthDuration|subtract-dateTimes-yielding-dayTimeDuration|substring-before|substring-after|substring|subsequence|string-to-codepoints|string-pad|string-length|string-join|string|static-base-uri|starts-with|seconds-from-time|seconds-from-duration|seconds-from-dateTime|round-half-to-even|round|root|reverse|resolve-uri|resolve-QName|replace|remove|QName|prefix-from-QName|position|one-or-more|number|not|normalize-unicode|normalize-space|node-name|node-kind|nilled|namespace-uri-from-QName|namespace-uri-for-prefix|namespace-uri|name|months-from-duration|month-from-dateTime|month-from-date|minutes-from-time|minutes-from-duration|minutes-from-dateTime|min|max|matches|lower-case|local-name-from-QName|local-name|last|lang|iri-to-uri|insert-before|index-of|in-scope-prefixes|implicit-timezone|idref|id|hours-from-time|hours-from-duration|hours-from-dateTime|floor|false|expanded-QName|exists|exactly-one|escape-uri|escape-html-uri|error|ends-with|encode-for-uri|empty|document-uri|doc-available|doc|distinct-values|distinct-nodes|default-collation|deep-equal|days-from-duration|day-from-dateTime|day-from-date|data|current-time|current-dateTime|current-date|count|contains|concat|compare|collection|codepoints-to-string|codepoint-equal|ceiling|boolean|base-uri|avg|adjust-time-to-timezone|adjust-dateTime-to-timezone|adjust-date-to-timezone|abs)\b/],
                +["pln",/^[A-Za-z0-9_\-\:]+/],["pln",/^[\t\n\r \xA0]+/]]),["xq","xquery"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-yaml.js b/blockly/webif/static/js/google-prettify/lang-yaml.js
                new file mode 100644
                index 000000000..a2b4b079c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-yaml.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2015 ribrdb @ code.google.com
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:|>?]+/,null,":|>?"],["dec",/^%(?:YAML|TAG)[^#\r\n]+/,null,"%"],["typ",/^[&]\S+/,null,"&"],["typ",/^!\S*/,null,"!"],["str",/^"(?:[^\\"]|\\.)*(?:"|$)/,null,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,null,"'"],["com",/^#[^\r\n]*/,null,"#"],["pln",/^\s+/,null," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\r\n]|$)/],["pun",/^-/],["kwd",/^[\w-]+:[ \r\n]/],["pln",
                +/^\w+/]]),["yaml","yml"]);
                diff --git a/blockly/webif/static/js/google-prettify/lang-yml.js b/blockly/webif/static/js/google-prettify/lang-yml.js
                new file mode 100644
                index 000000000..a2b4b079c
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/lang-yml.js
                @@ -0,0 +1,18 @@
                +/*
                +
                + Copyright (C) 2015 ribrdb @ code.google.com
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +    http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:|>?]+/,null,":|>?"],["dec",/^%(?:YAML|TAG)[^#\r\n]+/,null,"%"],["typ",/^[&]\S+/,null,"&"],["typ",/^!\S*/,null,"!"],["str",/^"(?:[^\\"]|\\.)*(?:"|$)/,null,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,null,"'"],["com",/^#[^\r\n]*/,null,"#"],["pln",/^\s+/,null," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\r\n]|$)/],["pun",/^-/],["kwd",/^[\w-]+:[ \r\n]/],["pln",
                +/^\w+/]]),["yaml","yml"]);
                diff --git a/blockly/webif/static/js/google-prettify/prettify.css b/blockly/webif/static/js/google-prettify/prettify.css
                new file mode 100644
                index 000000000..d44b3a228
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/prettify.css
                @@ -0,0 +1 @@
                +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/google-prettify/prettify.js b/blockly/webif/static/js/google-prettify/prettify.js
                new file mode 100644
                index 000000000..3b74b5bda
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/prettify.js
                @@ -0,0 +1,46 @@
                +!function(){/*
                +
                + Copyright (C) 2006 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +window.PR_SHOULD_USE_CONTINUATION=!0;
                +(function(){function T(a){function d(e){var b=e.charCodeAt(0);if(92!==b)return b;var a=e.charAt(1);return(b=w[a])?b:"0"<=a&&"7">=a?parseInt(e.substring(1),8):"u"===a||"x"===a?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[0-9A-Fa-f]{4}|\\x[0-9A-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\s\S]|-|[^-\\]/g);e=
                +[];var a="^"===b[0],c=["["];a&&c.push("^");for(var a=a?1:0,g=b.length;a<g;++a){var h=b[a];if(/\\[bdsw]/i.test(h))c.push(h);else{var h=d(h),k;a+2<g&&"-"===b[a+1]?(k=d(b[a+2]),a+=2):k=h;e.push([h,k]);65>k||122<h||(65>k||90<h||e.push([Math.max(65,h)|32,Math.min(k,90)|32]),97>k||122<h||e.push([Math.max(97,h)&-33,Math.min(k,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});b=[];g=[];for(a=0;a<e.length;++a)h=e[a],h[0]<=g[1]+1?g[1]=Math.max(g[1],h[1]):b.push(g=h);for(a=0;a<b.length;++a)h=b[a],
                +c.push(f(h[0])),h[1]>h[0]&&(h[1]+1>h[0]&&c.push("-"),c.push(f(h[1])));c.push("]");return c.join("")}function v(e){for(var a=e.source.match(/(?:\[(?:[^\x5C\x5D]|\\[\s\S])*\]|\\u[A-Fa-f0-9]{4}|\\x[A-Fa-f0-9]{2}|\\[0-9]+|\\[^ux0-9]|\(\?[:!=]|[\(\)\^]|[^\x5B\x5C\(\)\^]+)/g),c=a.length,d=[],g=0,h=0;g<c;++g){var k=a[g];"("===k?++h:"\\"===k.charAt(0)&&(k=+k.substring(1))&&(k<=h?d[k]=-1:a[g]=f(k))}for(g=1;g<d.length;++g)-1===d[g]&&(d[g]=++A);for(h=g=0;g<c;++g)k=a[g],"("===k?(++h,d[h]||(a[g]="(?:")):"\\"===
                +k.charAt(0)&&(k=+k.substring(1))&&k<=h&&(a[g]="\\"+d[k]);for(g=0;g<c;++g)"^"===a[g]&&"^"!==a[g+1]&&(a[g]="");if(e.ignoreCase&&n)for(g=0;g<c;++g)k=a[g],e=k.charAt(0),2<=k.length&&"["===e?a[g]=b(k):"\\"!==e&&(a[g]=k.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var A=0,n=!1,l=!1,m=0,c=a.length;m<c;++m){var p=a[m];if(p.ignoreCase)l=!0;else if(/[a-z]/i.test(p.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){n=!0;
                +l=!1;break}}for(var w={b:8,t:9,n:10,v:11,f:12,r:13},r=[],m=0,c=a.length;m<c;++m){p=a[m];if(p.global||p.multiline)throw Error(""+p);r.push("(?:"+v(p)+")")}return new RegExp(r.join("|"),l?"gi":"g")}function U(a,d){function f(a){var c=a.nodeType;if(1==c){if(!b.test(a.className)){for(c=a.firstChild;c;c=c.nextSibling)f(c);c=a.nodeName.toLowerCase();if("br"===c||"li"===c)v[l]="\n",n[l<<1]=A++,n[l++<<1|1]=a}}else if(3==c||4==c)c=a.nodeValue,c.length&&(c=d?c.replace(/\r\n?/g,"\n"):c.replace(/[ \t\r\n]+/g,
                +" "),v[l]=c,n[l<<1]=A,A+=c.length,n[l++<<1|1]=a)}var b=/(?:^|\s)nocode(?:\s|$)/,v=[],A=0,n=[],l=0;f(a);return{a:v.join("").replace(/\n$/,""),c:n}}function J(a,d,f,b,v){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},b(a),v.push.apply(v,a.g))}function V(a){for(var d=void 0,f=a.firstChild;f;f=f.nextSibling)var b=f.nodeType,d=1===b?d?a:f:3===b?W.test(f.nodeValue)?a:d:d;return d===a?void 0:d}function G(a,d){function f(a){for(var l=a.i,m=a.h,c=[l,"pln"],p=0,w=a.a.match(v)||[],r={},e=0,t=w.length;e<
                +t;++e){var z=w[e],q=r[z],g=void 0,h;if("string"===typeof q)h=!1;else{var k=b[z.charAt(0)];if(k)g=z.match(k[1]),q=k[0];else{for(h=0;h<A;++h)if(k=d[h],g=z.match(k[1])){q=k[0];break}g||(q="pln")}!(h=5<=q.length&&"lang-"===q.substring(0,5))||g&&"string"===typeof g[1]||(h=!1,q="src");h||(r[z]=q)}k=p;p+=z.length;if(h){h=g[1];var B=z.indexOf(h),D=B+h.length;g[2]&&(D=z.length-g[2].length,B=D-h.length);q=q.substring(5);J(m,l+k,z.substring(0,B),f,c);J(m,l+k+B,h,K(q,h),c);J(m,l+k+D,z.substring(D),f,c)}else c.push(l+
                +k,q)}a.g=c}var b={},v;(function(){for(var f=a.concat(d),l=[],m={},c=0,p=f.length;c<p;++c){var w=f[c],r=w[3];if(r)for(var e=r.length;0<=--e;)b[r.charAt(e)]=w;w=w[1];r=""+w;m.hasOwnProperty(r)||(l.push(w),m[r]=null)}l.push(/[\0-\uffff]/);v=T(l)})();var A=d.length;return f}function y(a){var d=[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                +null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var b=a.hashComments;b&&(a.cStyleComments?(1<b?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
                +null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(b=a.regexLiterals){var v=(b=1<b?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+
                +("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+v+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+v+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&f.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&f.push(["kwd",new RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,
                +null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(b),null]);return G(d,f)}function L(a,d,f){function b(a){var c=a.nodeType;if(1==c&&!A.test(a.className))if("br"===a.nodeName)v(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((3==c||4==c)&&f){var d=a.nodeValue,q=d.match(n);q&&(c=d.substring(0,q.index),a.nodeValue=c,(d=d.substring(q.index+q[0].length))&&
                +a.parentNode.insertBefore(l.createTextNode(d),a.nextSibling),v(a),c||a.parentNode.removeChild(a))}}function v(a){function b(a,c){var d=c?a.cloneNode(!1):a,k=a.parentNode;if(k){var k=b(k,1),e=a.nextSibling;k.appendChild(d);for(var f=e;f;f=e)e=f.nextSibling,k.appendChild(f)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=b(a.nextSibling,0);for(var d;(d=a.parentNode)&&1===d.nodeType;)a=d;c.push(a)}for(var A=/(?:^|\s)nocode(?:\s|$)/,n=/\r\n?|\n/,l=a.ownerDocument,m=l.createElement("li");a.firstChild;)m.appendChild(a.firstChild);
                +for(var c=[m],p=0;p<c.length;++p)b(c[p]);d===(d|0)&&c[0].setAttribute("value",d);var w=l.createElement("ol");w.className="linenums";d=Math.max(0,d-1|0)||0;for(var p=0,r=c.length;p<r;++p)m=c[p],m.className="L"+(p+d)%10,m.firstChild||m.appendChild(l.createTextNode("\u00a0")),w.appendChild(m);a.appendChild(w)}function t(a,d){for(var f=d.length;0<=--f;){var b=d[f];I.hasOwnProperty(b)?E.console&&console.warn("cannot override language handler %s",b):I[b]=a}}function K(a,d){a&&I.hasOwnProperty(a)||(a=/^\s*</.test(d)?
                +"default-markup":"default-code");return I[a]}function M(a){var d=a.j;try{var f=U(a.h,a.l),b=f.a;a.a=b;a.c=f.c;a.i=0;K(d,b)(a);var v=/\bMSIE\s(\d+)/.exec(navigator.userAgent),v=v&&8>=+v[1],d=/\n/g,A=a.a,n=A.length,f=0,l=a.c,m=l.length,b=0,c=a.g,p=c.length,w=0;c[p]=n;var r,e;for(e=r=0;e<p;)c[e]!==c[e+2]?(c[r++]=c[e++],c[r++]=c[e++]):e+=2;p=r;for(e=r=0;e<p;){for(var t=c[e],z=c[e+1],q=e+2;q+2<=p&&c[q+1]===z;)q+=2;c[r++]=t;c[r++]=z;e=q}c.length=r;var g=a.h;a="";g&&(a=g.style.display,g.style.display="none");
                +try{for(;b<m;){var h=l[b+2]||n,k=c[w+2]||n,q=Math.min(h,k),B=l[b+1],D;if(1!==B.nodeType&&(D=A.substring(f,q))){v&&(D=D.replace(d,"\r"));B.nodeValue=D;var N=B.ownerDocument,u=N.createElement("span");u.className=c[w+1];var y=B.parentNode;y.replaceChild(u,B);u.appendChild(B);f<h&&(l[b+1]=B=N.createTextNode(A.substring(q,h)),y.insertBefore(B,u.nextSibling))}f=q;f>=h&&(b+=2);f>=k&&(w+=2)}}finally{g&&(g.style.display=a)}}catch(x){E.console&&console.log(x&&x.stack||x)}}var E=window,C=["break,continue,do,else,for,if,return,while"],
                +F=[[C,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],H=[F,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],
                +O=[F,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],P=[F,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],
                +F=[F,"abstract,async,await,constructor,debugger,enum,eval,export,function,get,implements,instanceof,interface,let,null,set,undefined,var,with,yield,Infinity,NaN"],Q=[C,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],R=[C,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],C=[C,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],
                +S=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,W=/\S/,X=y({keywords:[H,P,O,F,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",Q,R,C],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),I={};t(X,["default-code"]);t(G([],[["pln",/^[^<?]+/],["dec",
                +/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));t(G([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,
                +"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);t(G([],[["atv",/^[\s\S]+/]]),["uq.val"]);t(y({keywords:H,
                +hashComments:!0,cStyleComments:!0,types:S}),"c cc cpp cxx cyc m".split(" "));t(y({keywords:"null,true,false"}),["json"]);t(y({keywords:P,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:S}),["cs"]);t(y({keywords:O,cStyleComments:!0}),["java"]);t(y({keywords:C,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);t(y({keywords:Q,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);t(y({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",
                +hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);t(y({keywords:R,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);t(y({keywords:F,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);t(y({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,
                +regexLiterals:!0}),["coffee"]);t(G([],[["str",/^[\s\S]+/]]),["regex"]);var Y=E.PR={createSimpleLexer:G,registerLangHandler:t,sourceDecorator:y,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:E.prettyPrintOne=function(a,d,f){f=f||!1;d=d||null;var b=document.createElement("div");b.innerHTML="<pre>"+a+"</pre>";
                +b=b.firstChild;f&&L(b,f,!0);M({j:d,m:f,h:b,l:1,a:null,i:null,c:null,g:null});return b.innerHTML},prettyPrint:E.prettyPrint=function(a,d){function f(){for(var b=E.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;p<t.length&&c.now()<b;p++){for(var d=t[p],l=g,m=d;m=m.previousSibling;){var n=m.nodeType,u=(7===n||8===n)&&m.nodeValue;if(u?!/^\??prettify\b/.test(u):3!==n||/\S/.test(m.nodeValue))break;if(u){l={};u.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){l[b]=c});break}}m=d.className;if((l!==g||r.test(m))&&
                +!e.test(m)){n=!1;for(u=d.parentNode;u;u=u.parentNode)if(q.test(u.tagName)&&u.className&&r.test(u.className)){n=!0;break}if(!n){d.className+=" prettyprinted";n=l.lang;if(!n){var n=m.match(w),C;!n&&(C=V(d))&&z.test(C.tagName)&&(n=C.className.match(w));n&&(n=n[1])}if(y.test(d.tagName))u=1;else var u=d.currentStyle,x=v.defaultView,u=(u=u?u.whiteSpace:x&&x.getComputedStyle?x.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===u.substring(0,3);x=l.linenums;(x="true"===x||+x)||(x=(x=m.match(/\blinenums\b(?::(\d+))?/))?
                +x[1]&&x[1].length?+x[1]:!0:!1);x&&L(d,x,u);M({j:n,h:d,m:x,l:u,a:null,i:null,c:null,g:null})}}}p<t.length?E.setTimeout(f,250):"function"===typeof a&&a()}for(var b=d||document.body,v=b.ownerDocument||document,b=[b.getElementsByTagName("pre"),b.getElementsByTagName("code"),b.getElementsByTagName("xmp")],t=[],n=0;n<b.length;++n)for(var l=0,m=b[n].length;l<m;++l)t.push(b[n][l]);var b=null,c=Date;c.now||(c={now:function(){return+new Date}});var p=0,w=/\blang(?:uage)?-([\w.]+)(?!\S)/,r=/\bprettyprint\b/,
                +e=/\bprettyprinted\b/,y=/pre|xmp/i,z=/^code$/i,q=/^(?:pre|code|xmp)$/i,g={};f()}},H=E.define;"function"===typeof H&&H.amd&&H("google-code-prettify",[],function(){return Y})})();}()
                diff --git a/blockly/webif/static/js/google-prettify/run_prettify.js b/blockly/webif/static/js/google-prettify/run_prettify.js
                new file mode 100644
                index 000000000..0085a4ad5
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/run_prettify.js
                @@ -0,0 +1,63 @@
                +!function(){/*
                +
                + Copyright (C) 2013 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +
                + Copyright (C) 2006 Google Inc.
                +
                + Licensed under the Apache License, Version 2.0 (the "License");
                + you may not use this file except in compliance with the License.
                + You may obtain a copy of the License at
                +
                +      http://www.apache.org/licenses/LICENSE-2.0
                +
                + Unless required by applicable law or agreed to in writing, software
                + distributed under the License is distributed on an "AS IS" BASIS,
                + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + See the License for the specific language governing permissions and
                + limitations under the License.
                +*/
                +(function(){function ba(g){function k(){try{M.doScroll("left")}catch(g){t.setTimeout(k,50);return}z("poll")}function z(k){if("readystatechange"!=k.type||"complete"==A.readyState)("load"==k.type?t:A)[B](p+k.type,z,!1),!q&&(q=!0)&&g.call(t,k.type||k)}var Y=A.addEventListener,q=!1,C=!0,x=Y?"addEventListener":"attachEvent",B=Y?"removeEventListener":"detachEvent",p=Y?"":"on";if("complete"==A.readyState)g.call(t,"lazy");else{if(A.createEventObject&&M.doScroll){try{C=!t.frameElement}catch(da){}C&&k()}A[x](p+
                +"DOMContentLoaded",z,!1);A[x](p+"readystatechange",z,!1);t[x](p+"load",z,!1)}}function U(){V&&ba(function(){var g=N.length;ca(g?function(){for(var k=0;k<g;++k)(function(g){t.setTimeout(function(){t.exports[N[g]].apply(t,arguments)},0)})(k)}:void 0)})}for(var t=window,A=document,M=A.documentElement,O=A.head||A.getElementsByTagName("head")[0]||M,B="",F=A.getElementsByTagName("script"),q=F.length;0<=--q;){var P=F[q],Z=P.src.match(/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(Z){B=Z[1]||"";P.parentNode.removeChild(P);
                +break}}var V=!0,H=[],Q=[],N=[];B.replace(/[?&]([^&=]+)=([^&]+)/g,function(g,k,z){z=decodeURIComponent(z);k=decodeURIComponent(k);"autorun"==k?V=!/^[0fn]/i.test(z):"lang"==k?H.push(z):"skin"==k?Q.push(z):"callback"==k&&N.push(z)});q=0;for(B=H.length;q<B;++q)(function(){var g=A.createElement("script");g.onload=g.onerror=g.onreadystatechange=function(){!g||g.readyState&&!/loaded|complete/.test(g.readyState)||(g.onerror=g.onload=g.onreadystatechange=null,--T,T||t.setTimeout(U,0),g.parentNode&&g.parentNode.removeChild(g),
                +g=null)};g.type="text/javascript";g.src="https://cdn.rawgit.com/google/code-prettify/master/loader/lang-"+encodeURIComponent(H[q])+".js";O.insertBefore(g,O.firstChild)})(H[q]);for(var T=H.length,F=[],q=0,B=Q.length;q<B;++q)F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/skins/"+encodeURIComponent(Q[q])+".css");F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/prettify.css");(function(g){function k(q){if(q!==z){var t=A.createElement("link");t.rel="stylesheet";t.type=
                +"text/css";q+1<z&&(t.error=t.onerror=function(){k(q+1)});t.href=g[q];O.appendChild(t)}}var z=g.length;k(0)})(F);var ca=function(){window.PR_SHOULD_USE_CONTINUATION=!0;var g;(function(){function k(a){function d(e){var b=e.charCodeAt(0);if(92!==b)return b;var a=e.charAt(1);return(b=W[a])?b:"0"<=a&&"7">=a?parseInt(e.substring(1),8):"u"===a||"x"===a?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===
                +e||"]"===e||"^"===e?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[0-9A-Fa-f]{4}|\\x[0-9A-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\s\S]|-|[^-\\]/g);e=[];var a="^"===b[0],c=["["];a&&c.push("^");for(var a=a?1:0,h=b.length;a<h;++a){var l=b[a];if(/\\[bdsw]/i.test(l))c.push(l);else{var l=d(l),n;a+2<h&&"-"===b[a+1]?(n=d(b[a+2]),a+=2):n=l;e.push([l,n]);65>n||122<l||(65>n||90<l||e.push([Math.max(65,l)|32,Math.min(n,90)|32]),97>n||122<l||e.push([Math.max(97,l)&-33,Math.min(n,122)&-33]))}}e.sort(function(e,
                +a){return e[0]-a[0]||a[1]-e[1]});b=[];h=[];for(a=0;a<e.length;++a)l=e[a],l[0]<=h[1]+1?h[1]=Math.max(h[1],l[1]):b.push(h=l);for(a=0;a<b.length;++a)l=b[a],c.push(f(l[0])),l[1]>l[0]&&(l[1]+1>l[0]&&c.push("-"),c.push(f(l[1])));c.push("]");return c.join("")}function g(e){for(var a=e.source.match(/(?:\[(?:[^\x5C\x5D]|\\[\s\S])*\]|\\u[A-Fa-f0-9]{4}|\\x[A-Fa-f0-9]{2}|\\[0-9]+|\\[^ux0-9]|\(\?[:!=]|[\(\)\^]|[^\x5B\x5C\(\)\^]+)/g),c=a.length,d=[],h=0,l=0;h<c;++h){var n=a[h];"("===n?++l:"\\"===n.charAt(0)&&(n=
                ++n.substring(1))&&(n<=l?d[n]=-1:a[h]=f(n))}for(h=1;h<d.length;++h)-1===d[h]&&(d[h]=++k);for(l=h=0;h<c;++h)n=a[h],"("===n?(++l,d[l]||(a[h]="(?:")):"\\"===n.charAt(0)&&(n=+n.substring(1))&&n<=l&&(a[h]="\\"+d[n]);for(h=0;h<c;++h)"^"===a[h]&&"^"!==a[h+1]&&(a[h]="");if(e.ignoreCase&&I)for(h=0;h<c;++h)n=a[h],e=n.charAt(0),2<=n.length&&"["===e?a[h]=b(n):"\\"!==e&&(a[h]=n.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var k=0,I=!1,
                +m=!1,J=0,c=a.length;J<c;++J){var r=a[J];if(r.ignoreCase)m=!0;else if(/[a-z]/i.test(r.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){I=!0;m=!1;break}}for(var W={b:8,t:9,n:10,v:11,f:12,r:13},u=[],J=0,c=a.length;J<c;++J){r=a[J];if(r.global||r.multiline)throw Error(""+r);u.push("(?:"+g(r)+")")}return new RegExp(u.join("|"),m?"gi":"g")}function q(a,d){function f(a){var c=a.nodeType;if(1==c){if(!b.test(a.className)){for(c=a.firstChild;c;c=c.nextSibling)f(c);c=a.nodeName.toLowerCase();if("br"===
                +c||"li"===c)g[m]="\n",I[m<<1]=k++,I[m++<<1|1]=a}}else if(3==c||4==c)c=a.nodeValue,c.length&&(c=d?c.replace(/\r\n?/g,"\n"):c.replace(/[ \t\r\n]+/g," "),g[m]=c,I[m<<1]=k,k+=c.length,I[m++<<1|1]=a)}var b=/(?:^|\s)nocode(?:\s|$)/,g=[],k=0,I=[],m=0;f(a);return{a:g.join("").replace(/\n$/,""),c:I}}function t(a,d,f,b,g){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},b(a),g.push.apply(g,a.g))}function A(a){for(var d=void 0,f=a.firstChild;f;f=f.nextSibling)var b=f.nodeType,d=1===b?d?a:f:3===b?T.test(f.nodeValue)?
                +a:d:d;return d===a?void 0:d}function C(a,d){function f(a){for(var m=a.i,k=a.h,c=[m,"pln"],r=0,W=a.a.match(g)||[],u={},e=0,q=W.length;e<q;++e){var D=W[e],w=u[D],h=void 0,l;if("string"===typeof w)l=!1;else{var n=b[D.charAt(0)];if(n)h=D.match(n[1]),w=n[0];else{for(l=0;l<p;++l)if(n=d[l],h=D.match(n[1])){w=n[0];break}h||(w="pln")}!(l=5<=w.length&&"lang-"===w.substring(0,5))||h&&"string"===typeof h[1]||(l=!1,w="src");l||(u[D]=w)}n=r;r+=D.length;if(l){l=h[1];var E=D.indexOf(l),G=E+l.length;h[2]&&(G=D.length-
                +h[2].length,E=G-l.length);w=w.substring(5);t(k,m+n,D.substring(0,E),f,c);t(k,m+n+E,l,F(w,l),c);t(k,m+n+G,D.substring(G),f,c)}else c.push(m+n,w)}a.g=c}var b={},g;(function(){for(var f=a.concat(d),m=[],p={},c=0,r=f.length;c<r;++c){var q=f[c],u=q[3];if(u)for(var e=u.length;0<=--e;)b[u.charAt(e)]=q;q=q[1];u=""+q;p.hasOwnProperty(u)||(m.push(q),p[u]=null)}m.push(/[\0-\uffff]/);g=k(m)})();var p=d.length;return f}function x(a){var d=[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
                +null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var b=a.hashComments;b&&(a.cStyleComments?(1<b?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
                +null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(b=a.regexLiterals){var g=(b=1<b?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+
                +("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&f.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&f.push(["kwd",new RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,
                +null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(b),null]);return C(d,f)}function B(a,d,f){function b(a){var c=a.nodeType;if(1==c&&!k.test(a.className))if("br"===a.nodeName)g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((3==c||4==c)&&f){var d=a.nodeValue,p=d.match(q);p&&(c=d.substring(0,p.index),a.nodeValue=c,(d=d.substring(p.index+p[0].length))&&
                +a.parentNode.insertBefore(m.createTextNode(d),a.nextSibling),g(a),c||a.parentNode.removeChild(a))}}function g(a){function b(a,c){var d=c?a.cloneNode(!1):a,n=a.parentNode;if(n){var n=b(n,1),e=a.nextSibling;n.appendChild(d);for(var f=e;f;f=e)e=f.nextSibling,n.appendChild(f)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=b(a.nextSibling,0);for(var d;(d=a.parentNode)&&1===d.nodeType;)a=d;c.push(a)}for(var k=/(?:^|\s)nocode(?:\s|$)/,q=/\r\n?|\n/,m=a.ownerDocument,p=m.createElement("li");a.firstChild;)p.appendChild(a.firstChild);
                +for(var c=[p],r=0;r<c.length;++r)b(c[r]);d===(d|0)&&c[0].setAttribute("value",d);var t=m.createElement("ol");t.className="linenums";d=Math.max(0,d-1|0)||0;for(var r=0,u=c.length;r<u;++r)p=c[r],p.className="L"+(r+d)%10,p.firstChild||p.appendChild(m.createTextNode("\u00a0")),t.appendChild(p);a.appendChild(t)}function p(a,d){for(var f=d.length;0<=--f;){var b=d[f];X.hasOwnProperty(b)?R.console&&console.warn("cannot override language handler %s",b):X[b]=a}}function F(a,d){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(d)?
                +"default-markup":"default-code");return X[a]}function H(a){var d=a.j;try{var f=q(a.h,a.l),b=f.a;a.a=b;a.c=f.c;a.i=0;F(d,b)(a);var g=/\bMSIE\s(\d+)/.exec(navigator.userAgent),g=g&&8>=+g[1],d=/\n/g,p=a.a,k=p.length,f=0,m=a.c,t=m.length,b=0,c=a.g,r=c.length,x=0;c[r]=k;var u,e;for(e=u=0;e<r;)c[e]!==c[e+2]?(c[u++]=c[e++],c[u++]=c[e++]):e+=2;r=u;for(e=u=0;e<r;){for(var A=c[e],D=c[e+1],w=e+2;w+2<=r&&c[w+1]===D;)w+=2;c[u++]=A;c[u++]=D;e=w}c.length=u;var h=a.h;a="";h&&(a=h.style.display,h.style.display="none");
                +try{for(;b<t;){var l=m[b+2]||k,n=c[x+2]||k,w=Math.min(l,n),E=m[b+1],G;if(1!==E.nodeType&&(G=p.substring(f,w))){g&&(G=G.replace(d,"\r"));E.nodeValue=G;var aa=E.ownerDocument,v=aa.createElement("span");v.className=c[x+1];var B=E.parentNode;B.replaceChild(v,E);v.appendChild(E);f<l&&(m[b+1]=E=aa.createTextNode(p.substring(w,l)),B.insertBefore(E,v.nextSibling))}f=w;f>=l&&(b+=2);f>=n&&(x+=2)}}finally{h&&(h.style.display=a)}}catch(y){R.console&&console.log(y&&y.stack||y)}}var R=window,K=["break,continue,do,else,for,if,return,while"],
                +L=[[K,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],S=[L,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],
                +M=[L,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],N=[L,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],
                +L=[L,"abstract,async,await,constructor,debugger,enum,eval,export,function,get,implements,instanceof,interface,let,null,set,undefined,var,with,yield,Infinity,NaN"],O=[K,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],P=[K,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],K=[K,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],
                +Q=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,T=/\S/,U=x({keywords:[S,N,M,L,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",O,P,K],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),X={};p(U,["default-code"]);p(C([],[["pln",/^[^<?]+/],["dec",
                +/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));p(C([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,
                +"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);p(C([],[["atv",/^[\s\S]+/]]),["uq.val"]);p(x({keywords:S,
                +hashComments:!0,cStyleComments:!0,types:Q}),"c cc cpp cxx cyc m".split(" "));p(x({keywords:"null,true,false"}),["json"]);p(x({keywords:N,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:Q}),["cs"]);p(x({keywords:M,cStyleComments:!0}),["java"]);p(x({keywords:K,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);p(x({keywords:O,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);p(x({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",
                +hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);p(x({keywords:P,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);p(x({keywords:L,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);p(x({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,
                +regexLiterals:!0}),["coffee"]);p(C([],[["str",/^[\s\S]+/]]),["regex"]);var V=R.PR={createSimpleLexer:C,registerLangHandler:p,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var b=document.createElement("div");b.innerHTML="<pre>"+a+"</pre>";b=b.firstChild;
                +f&&B(b,f,!0);H({j:d,m:f,h:b,l:1,a:null,i:null,c:null,g:null});return b.innerHTML},prettyPrint:g=g=function(a,d){function f(){for(var b=R.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;r<p.length&&c.now()<b;r++){for(var d=p[r],k=h,q=d;q=q.previousSibling;){var m=q.nodeType,v=(7===m||8===m)&&q.nodeValue;if(v?!/^\??prettify\b/.test(v):3!==m||/\S/.test(q.nodeValue))break;if(v){k={};v.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){k[b]=c});break}}q=d.className;if((k!==h||u.test(q))&&!e.test(q)){m=!1;
                +for(v=d.parentNode;v;v=v.parentNode)if(w.test(v.tagName)&&v.className&&u.test(v.className)){m=!0;break}if(!m){d.className+=" prettyprinted";m=k.lang;if(!m){var m=q.match(t),C;!m&&(C=A(d))&&z.test(C.tagName)&&(m=C.className.match(t));m&&(m=m[1])}if(x.test(d.tagName))v=1;else var v=d.currentStyle,y=g.defaultView,v=(v=v?v.whiteSpace:y&&y.getComputedStyle?y.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===v.substring(0,3);y=k.linenums;(y="true"===y||+y)||(y=(y=q.match(/\blinenums\b(?::(\d+))?/))?
                +y[1]&&y[1].length?+y[1]:!0:!1);y&&B(d,y,v);H({j:m,h:d,m:y,l:v,a:null,i:null,c:null,g:null})}}}r<p.length?R.setTimeout(f,250):"function"===typeof a&&a()}for(var b=d||document.body,g=b.ownerDocument||document,b=[b.getElementsByTagName("pre"),b.getElementsByTagName("code"),b.getElementsByTagName("xmp")],p=[],k=0;k<b.length;++k)for(var m=0,q=b[k].length;m<q;++m)p.push(b[k][m]);var b=null,c=Date;c.now||(c={now:function(){return+new Date}});var r=0,t=/\blang(?:uage)?-([\w.]+)(?!\S)/,u=/\bprettyprint\b/,
                +e=/\bprettyprinted\b/,x=/pre|xmp/i,z=/^code$/i,w=/^(?:pre|code|xmp)$/i,h={};f()}},S=R.define;"function"===typeof S&&S.amd&&S("google-code-prettify",[],function(){return V})})();return g}();T||t.setTimeout(U,0)})();}()
                diff --git a/blockly/webif/static/js/google-prettify/skins/desert.css b/blockly/webif/static/js/google-prettify/skins/desert.css
                new file mode 100644
                index 000000000..951cd3241
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/skins/desert.css
                @@ -0,0 +1 @@
                +pre.prettyprint{display:block;background-color:#333}pre .nocode{background-color:none;color:#000}pre .str{color:#ffa0a0}pre .kwd{color:#f0e68c;font-weight:bold}pre .com{color:#87ceeb}pre .typ{color:#98fb98}pre .lit{color:#cd5c5c}pre .pun{color:#fff}pre .pln{color:#fff}pre .tag{color:#f0e68c;font-weight:bold}pre .atn{color:#bdb76b;font-weight:bold}pre .atv{color:#ffa0a0}pre .dec{color:#98fb98}ol.linenums{margin-top:0;margin-bottom:0;color:#aeaeae}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}@media print{pre.prettyprint{background-color:none}pre .str,code .str{color:#060}pre .kwd,code .kwd{color:#006;font-weight:bold}pre .com,code .com{color:#600;font-style:italic}pre .typ,code .typ{color:#404;font-weight:bold}pre .lit,code .lit{color:#044}pre .pun,code .pun{color:#440}pre .pln,code .pln{color:#000}pre .tag,code .tag{color:#006;font-weight:bold}pre .atn,code .atn{color:#404}pre .atv,code .atv{color:#060}}
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/google-prettify/skins/doxy.css b/blockly/webif/static/js/google-prettify/skins/doxy.css
                new file mode 100644
                index 000000000..6bb723517
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/skins/doxy.css
                @@ -0,0 +1 @@
                +pre .str,code .str{color:#fec243}pre .kwd,code .kwd{color:#8470ff}pre .com,code .com{color:#32cd32;font-style:italic}pre .typ,code .typ{color:#6ecbcc}pre .lit,code .lit{color:#d06}pre .pun,code .pun{color:#8b8970}pre .pln,code .pln{color:#f0f0f0}pre .tag,code .tag{color:#9c9cff}pre .htm,code .htm{color:#dda0dd}pre .xsl,code .xsl{color:#d0a0d0}pre .atn,code .atn{color:#46eeee;font-weight:normal}pre .atv,code .atv{color:#eeb4b4}pre .dec,code .dec{color:#3387cc}a{text-decoration:none}pre.prettyprint,code.prettyprint{font-family:'Droid Sans Mono','CPMono_v07 Bold','Droid Sans';font-weight:bold;font-size:9pt;background-color:#0f0f0f;-moz-border-radius:8px;-webkit-border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;-khtml-border-radius:8px;border-radius:8px}pre.prettyprint{width:95%;margin:1em auto;padding:1em;white-space:pre-wrap}pre.prettyprint a,code.prettyprint a{text-decoration:none}ol.linenums{margin-top:0;margin-bottom:0;color:#8b8970}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}@media print{pre.prettyprint,code.prettyprint{background-color:#fff}pre .str,code .str{color:#088}pre .kwd,code .kwd{color:#006;font-weight:bold}pre .com,code .com{color:#oc3;font-style:italic}pre .typ,code .typ{color:#404;font-weight:bold}pre .lit,code .lit{color:#044}pre .pun,code .pun{color:#440}pre .pln,code .pln{color:#000}pre .tag,code .tag{color:#b66ff7;font-weight:bold}pre .htm,code .htm{color:#606;font-weight:bold}pre .xsl,code .xsl{color:#606;font-weight:bold}pre .atn,code .atn{color:#c71585;font-weight:normal}pre .atv,code .atv{color:#088;font-weight:normal}}
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/google-prettify/skins/sons-of-obsidian.css b/blockly/webif/static/js/google-prettify/skins/sons-of-obsidian.css
                new file mode 100644
                index 000000000..36c3585eb
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/skins/sons-of-obsidian.css
                @@ -0,0 +1 @@
                +.str{color:#ec7600}.kwd{color:#93c763}.com{color:#66747b}.typ{color:#678cb1}.lit{color:#facd22}.pun{color:#f1f2f3}.pln{color:#f1f2f3}.tag{color:#8ac763}.atn{color:#e0e2e4}.atv{color:#ec7600}.dec{color:purple}pre.prettyprint{border:0 solid #888}ol.linenums{margin-top:0;margin-bottom:0}.prettyprint{background:#000}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{color:#555;list-style-type:decimal}li.L1,li.L3,li.L5,li.L7,li.L9{background:#111}@media print{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun{color:#440}.pln{color:#000}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/google-prettify/skins/sunburst.css b/blockly/webif/static/js/google-prettify/skins/sunburst.css
                new file mode 100644
                index 000000000..c1be3de0b
                --- /dev/null
                +++ b/blockly/webif/static/js/google-prettify/skins/sunburst.css
                @@ -0,0 +1 @@
                +pre .str,code .str{color:#65b042}pre .kwd,code .kwd{color:#e28964}pre .com,code .com{color:#aeaeae;font-style:italic}pre .typ,code .typ{color:#89bdff}pre .lit,code .lit{color:#3387cc}pre .pun,code .pun{color:#fff}pre .pln,code .pln{color:#fff}pre .tag,code .tag{color:#89bdff}pre .atn,code .atn{color:#bdb76b}pre .atv,code .atv{color:#65b042}pre .dec,code .dec{color:#3387cc}pre.prettyprint,code.prettyprint{background-color:#000;border-radius:8px}pre.prettyprint{width:95%;margin:1em auto;padding:1em;white-space:pre-wrap}ol.linenums{margin-top:0;margin-bottom:0;color:#aeaeae}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}@media print{pre .str,code .str{color:#060}pre .kwd,code .kwd{color:#006;font-weight:bold}pre .com,code .com{color:#600;font-style:italic}pre .typ,code .typ{color:#404;font-weight:bold}pre .lit,code .lit{color:#044}pre .pun,code .pun{color:#440}pre .pln,code .pln{color:#000}pre .tag,code .tag{color:#006;font-weight:bold}pre .atn,code .atn{color:#404}pre .atv,code .atv{color:#060}}
                \ No newline at end of file
                diff --git a/blockly/webif/static/js/jquery-3.2.1.js b/blockly/webif/static/js/jquery-3.2.1.js
                new file mode 100644
                index 000000000..d2d8ca479
                --- /dev/null
                +++ b/blockly/webif/static/js/jquery-3.2.1.js
                @@ -0,0 +1,10253 @@
                +/*!
                + * jQuery JavaScript Library v3.2.1
                + * https://jquery.com/
                + *
                + * Includes Sizzle.js
                + * https://sizzlejs.com/
                + *
                + * Copyright JS Foundation and other contributors
                + * Released under the MIT license
                + * https://jquery.org/license
                + *
                + * Date: 2017-03-20T18:59Z
                + */
                +( function( global, factory ) {
                +
                +	"use strict";
                +
                +	if ( typeof module === "object" && typeof module.exports === "object" ) {
                +
                +		// For CommonJS and CommonJS-like environments where a proper `window`
                +		// is present, execute the factory and get jQuery.
                +		// For environments that do not have a `window` with a `document`
                +		// (such as Node.js), expose a factory as module.exports.
                +		// This accentuates the need for the creation of a real `window`.
                +		// e.g. var jQuery = require("jquery")(window);
                +		// See ticket #14549 for more info.
                +		module.exports = global.document ?
                +			factory( global, true ) :
                +			function( w ) {
                +				if ( !w.document ) {
                +					throw new Error( "jQuery requires a window with a document" );
                +				}
                +				return factory( w );
                +			};
                +	} else {
                +		factory( global );
                +	}
                +
                +// Pass this if window is not defined yet
                +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
                +
                +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
                +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
                +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
                +// enough that all such attempts are guarded in a try block.
                +"use strict";
                +
                +var arr = [];
                +
                +var document = window.document;
                +
                +var getProto = Object.getPrototypeOf;
                +
                +var slice = arr.slice;
                +
                +var concat = arr.concat;
                +
                +var push = arr.push;
                +
                +var indexOf = arr.indexOf;
                +
                +var class2type = {};
                +
                +var toString = class2type.toString;
                +
                +var hasOwn = class2type.hasOwnProperty;
                +
                +var fnToString = hasOwn.toString;
                +
                +var ObjectFunctionString = fnToString.call( Object );
                +
                +var support = {};
                +
                +
                +
                +	function DOMEval( code, doc ) {
                +		doc = doc || document;
                +
                +		var script = doc.createElement( "script" );
                +
                +		script.text = code;
                +		doc.head.appendChild( script ).parentNode.removeChild( script );
                +	}
                +/* global Symbol */
                +// Defining this global in .eslintrc.json would create a danger of using the global
                +// unguarded in another place, it seems safer to define global only for this module
                +
                +
                +
                +var
                +	version = "3.2.1",
                +
                +	// Define a local copy of jQuery
                +	jQuery = function( selector, context ) {
                +
                +		// The jQuery object is actually just the init constructor 'enhanced'
                +		// Need init if jQuery is called (just allow error to be thrown if not included)
                +		return new jQuery.fn.init( selector, context );
                +	},
                +
                +	// Support: Android <=4.0 only
                +	// Make sure we trim BOM and NBSP
                +	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
                +
                +	// Matches dashed string for camelizing
                +	rmsPrefix = /^-ms-/,
                +	rdashAlpha = /-([a-z])/g,
                +
                +	// Used by jQuery.camelCase as callback to replace()
                +	fcamelCase = function( all, letter ) {
                +		return letter.toUpperCase();
                +	};
                +
                +jQuery.fn = jQuery.prototype = {
                +
                +	// The current version of jQuery being used
                +	jquery: version,
                +
                +	constructor: jQuery,
                +
                +	// The default length of a jQuery object is 0
                +	length: 0,
                +
                +	toArray: function() {
                +		return slice.call( this );
                +	},
                +
                +	// Get the Nth element in the matched element set OR
                +	// Get the whole matched element set as a clean array
                +	get: function( num ) {
                +
                +		// Return all the elements in a clean array
                +		if ( num == null ) {
                +			return slice.call( this );
                +		}
                +
                +		// Return just the one element from the set
                +		return num < 0 ? this[ num + this.length ] : this[ num ];
                +	},
                +
                +	// Take an array of elements and push it onto the stack
                +	// (returning the new matched element set)
                +	pushStack: function( elems ) {
                +
                +		// Build a new jQuery matched element set
                +		var ret = jQuery.merge( this.constructor(), elems );
                +
                +		// Add the old object onto the stack (as a reference)
                +		ret.prevObject = this;
                +
                +		// Return the newly-formed element set
                +		return ret;
                +	},
                +
                +	// Execute a callback for every element in the matched set.
                +	each: function( callback ) {
                +		return jQuery.each( this, callback );
                +	},
                +
                +	map: function( callback ) {
                +		return this.pushStack( jQuery.map( this, function( elem, i ) {
                +			return callback.call( elem, i, elem );
                +		} ) );
                +	},
                +
                +	slice: function() {
                +		return this.pushStack( slice.apply( this, arguments ) );
                +	},
                +
                +	first: function() {
                +		return this.eq( 0 );
                +	},
                +
                +	last: function() {
                +		return this.eq( -1 );
                +	},
                +
                +	eq: function( i ) {
                +		var len = this.length,
                +			j = +i + ( i < 0 ? len : 0 );
                +		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
                +	},
                +
                +	end: function() {
                +		return this.prevObject || this.constructor();
                +	},
                +
                +	// For internal use only.
                +	// Behaves like an Array's method, not like a jQuery method.
                +	push: push,
                +	sort: arr.sort,
                +	splice: arr.splice
                +};
                +
                +jQuery.extend = jQuery.fn.extend = function() {
                +	var options, name, src, copy, copyIsArray, clone,
                +		target = arguments[ 0 ] || {},
                +		i = 1,
                +		length = arguments.length,
                +		deep = false;
                +
                +	// Handle a deep copy situation
                +	if ( typeof target === "boolean" ) {
                +		deep = target;
                +
                +		// Skip the boolean and the target
                +		target = arguments[ i ] || {};
                +		i++;
                +	}
                +
                +	// Handle case when target is a string or something (possible in deep copy)
                +	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
                +		target = {};
                +	}
                +
                +	// Extend jQuery itself if only one argument is passed
                +	if ( i === length ) {
                +		target = this;
                +		i--;
                +	}
                +
                +	for ( ; i < length; i++ ) {
                +
                +		// Only deal with non-null/undefined values
                +		if ( ( options = arguments[ i ] ) != null ) {
                +
                +			// Extend the base object
                +			for ( name in options ) {
                +				src = target[ name ];
                +				copy = options[ name ];
                +
                +				// Prevent never-ending loop
                +				if ( target === copy ) {
                +					continue;
                +				}
                +
                +				// Recurse if we're merging plain objects or arrays
                +				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                +					( copyIsArray = Array.isArray( copy ) ) ) ) {
                +
                +					if ( copyIsArray ) {
                +						copyIsArray = false;
                +						clone = src && Array.isArray( src ) ? src : [];
                +
                +					} else {
                +						clone = src && jQuery.isPlainObject( src ) ? src : {};
                +					}
                +
                +					// Never move original objects, clone them
                +					target[ name ] = jQuery.extend( deep, clone, copy );
                +
                +				// Don't bring in undefined values
                +				} else if ( copy !== undefined ) {
                +					target[ name ] = copy;
                +				}
                +			}
                +		}
                +	}
                +
                +	// Return the modified object
                +	return target;
                +};
                +
                +jQuery.extend( {
                +
                +	// Unique for each copy of jQuery on the page
                +	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
                +
                +	// Assume jQuery is ready without the ready module
                +	isReady: true,
                +
                +	error: function( msg ) {
                +		throw new Error( msg );
                +	},
                +
                +	noop: function() {},
                +
                +	isFunction: function( obj ) {
                +		return jQuery.type( obj ) === "function";
                +	},
                +
                +	isWindow: function( obj ) {
                +		return obj != null && obj === obj.window;
                +	},
                +
                +	isNumeric: function( obj ) {
                +
                +		// As of jQuery 3.0, isNumeric is limited to
                +		// strings and numbers (primitives or objects)
                +		// that can be coerced to finite numbers (gh-2662)
                +		var type = jQuery.type( obj );
                +		return ( type === "number" || type === "string" ) &&
                +
                +			// parseFloat NaNs numeric-cast false positives ("")
                +			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
                +			// subtraction forces infinities to NaN
                +			!isNaN( obj - parseFloat( obj ) );
                +	},
                +
                +	isPlainObject: function( obj ) {
                +		var proto, Ctor;
                +
                +		// Detect obvious negatives
                +		// Use toString instead of jQuery.type to catch host objects
                +		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
                +			return false;
                +		}
                +
                +		proto = getProto( obj );
                +
                +		// Objects with no prototype (e.g., `Object.create( null )`) are plain
                +		if ( !proto ) {
                +			return true;
                +		}
                +
                +		// Objects with prototype are plain iff they were constructed by a global Object function
                +		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
                +		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
                +	},
                +
                +	isEmptyObject: function( obj ) {
                +
                +		/* eslint-disable no-unused-vars */
                +		// See https://github.com/eslint/eslint/issues/6125
                +		var name;
                +
                +		for ( name in obj ) {
                +			return false;
                +		}
                +		return true;
                +	},
                +
                +	type: function( obj ) {
                +		if ( obj == null ) {
                +			return obj + "";
                +		}
                +
                +		// Support: Android <=2.3 only (functionish RegExp)
                +		return typeof obj === "object" || typeof obj === "function" ?
                +			class2type[ toString.call( obj ) ] || "object" :
                +			typeof obj;
                +	},
                +
                +	// Evaluates a script in a global context
                +	globalEval: function( code ) {
                +		DOMEval( code );
                +	},
                +
                +	// Convert dashed to camelCase; used by the css and data modules
                +	// Support: IE <=9 - 11, Edge 12 - 13
                +	// Microsoft forgot to hump their vendor prefix (#9572)
                +	camelCase: function( string ) {
                +		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
                +	},
                +
                +	each: function( obj, callback ) {
                +		var length, i = 0;
                +
                +		if ( isArrayLike( obj ) ) {
                +			length = obj.length;
                +			for ( ; i < length; i++ ) {
                +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                +					break;
                +				}
                +			}
                +		} else {
                +			for ( i in obj ) {
                +				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                +					break;
                +				}
                +			}
                +		}
                +
                +		return obj;
                +	},
                +
                +	// Support: Android <=4.0 only
                +	trim: function( text ) {
                +		return text == null ?
                +			"" :
                +			( text + "" ).replace( rtrim, "" );
                +	},
                +
                +	// results is for internal usage only
                +	makeArray: function( arr, results ) {
                +		var ret = results || [];
                +
                +		if ( arr != null ) {
                +			if ( isArrayLike( Object( arr ) ) ) {
                +				jQuery.merge( ret,
                +					typeof arr === "string" ?
                +					[ arr ] : arr
                +				);
                +			} else {
                +				push.call( ret, arr );
                +			}
                +		}
                +
                +		return ret;
                +	},
                +
                +	inArray: function( elem, arr, i ) {
                +		return arr == null ? -1 : indexOf.call( arr, elem, i );
                +	},
                +
                +	// Support: Android <=4.0 only, PhantomJS 1 only
                +	// push.apply(_, arraylike) throws on ancient WebKit
                +	merge: function( first, second ) {
                +		var len = +second.length,
                +			j = 0,
                +			i = first.length;
                +
                +		for ( ; j < len; j++ ) {
                +			first[ i++ ] = second[ j ];
                +		}
                +
                +		first.length = i;
                +
                +		return first;
                +	},
                +
                +	grep: function( elems, callback, invert ) {
                +		var callbackInverse,
                +			matches = [],
                +			i = 0,
                +			length = elems.length,
                +			callbackExpect = !invert;
                +
                +		// Go through the array, only saving the items
                +		// that pass the validator function
                +		for ( ; i < length; i++ ) {
                +			callbackInverse = !callback( elems[ i ], i );
                +			if ( callbackInverse !== callbackExpect ) {
                +				matches.push( elems[ i ] );
                +			}
                +		}
                +
                +		return matches;
                +	},
                +
                +	// arg is for internal usage only
                +	map: function( elems, callback, arg ) {
                +		var length, value,
                +			i = 0,
                +			ret = [];
                +
                +		// Go through the array, translating each of the items to their new values
                +		if ( isArrayLike( elems ) ) {
                +			length = elems.length;
                +			for ( ; i < length; i++ ) {
                +				value = callback( elems[ i ], i, arg );
                +
                +				if ( value != null ) {
                +					ret.push( value );
                +				}
                +			}
                +
                +		// Go through every key on the object,
                +		} else {
                +			for ( i in elems ) {
                +				value = callback( elems[ i ], i, arg );
                +
                +				if ( value != null ) {
                +					ret.push( value );
                +				}
                +			}
                +		}
                +
                +		// Flatten any nested arrays
                +		return concat.apply( [], ret );
                +	},
                +
                +	// A global GUID counter for objects
                +	guid: 1,
                +
                +	// Bind a function to a context, optionally partially applying any
                +	// arguments.
                +	proxy: function( fn, context ) {
                +		var tmp, args, proxy;
                +
                +		if ( typeof context === "string" ) {
                +			tmp = fn[ context ];
                +			context = fn;
                +			fn = tmp;
                +		}
                +
                +		// Quick check to determine if target is callable, in the spec
                +		// this throws a TypeError, but we will just return undefined.
                +		if ( !jQuery.isFunction( fn ) ) {
                +			return undefined;
                +		}
                +
                +		// Simulated bind
                +		args = slice.call( arguments, 2 );
                +		proxy = function() {
                +			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
                +		};
                +
                +		// Set the guid of unique handler to the same of original handler, so it can be removed
                +		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
                +
                +		return proxy;
                +	},
                +
                +	now: Date.now,
                +
                +	// jQuery.support is not used in Core but other projects attach their
                +	// properties to it so it needs to exist.
                +	support: support
                +} );
                +
                +if ( typeof Symbol === "function" ) {
                +	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
                +}
                +
                +// Populate the class2type map
                +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
                +function( i, name ) {
                +	class2type[ "[object " + name + "]" ] = name.toLowerCase();
                +} );
                +
                +function isArrayLike( obj ) {
                +
                +	// Support: real iOS 8.2 only (not reproducible in simulator)
                +	// `in` check used to prevent JIT error (gh-2145)
                +	// hasOwn isn't used here due to false negatives
                +	// regarding Nodelist length in IE
                +	var length = !!obj && "length" in obj && obj.length,
                +		type = jQuery.type( obj );
                +
                +	if ( type === "function" || jQuery.isWindow( obj ) ) {
                +		return false;
                +	}
                +
                +	return type === "array" || length === 0 ||
                +		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
                +}
                +var Sizzle =
                +/*!
                + * Sizzle CSS Selector Engine v2.3.3
                + * https://sizzlejs.com/
                + *
                + * Copyright jQuery Foundation and other contributors
                + * Released under the MIT license
                + * http://jquery.org/license
                + *
                + * Date: 2016-08-08
                + */
                +(function( window ) {
                +
                +var i,
                +	support,
                +	Expr,
                +	getText,
                +	isXML,
                +	tokenize,
                +	compile,
                +	select,
                +	outermostContext,
                +	sortInput,
                +	hasDuplicate,
                +
                +	// Local document vars
                +	setDocument,
                +	document,
                +	docElem,
                +	documentIsHTML,
                +	rbuggyQSA,
                +	rbuggyMatches,
                +	matches,
                +	contains,
                +
                +	// Instance-specific data
                +	expando = "sizzle" + 1 * new Date(),
                +	preferredDoc = window.document,
                +	dirruns = 0,
                +	done = 0,
                +	classCache = createCache(),
                +	tokenCache = createCache(),
                +	compilerCache = createCache(),
                +	sortOrder = function( a, b ) {
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +		}
                +		return 0;
                +	},
                +
                +	// Instance methods
                +	hasOwn = ({}).hasOwnProperty,
                +	arr = [],
                +	pop = arr.pop,
                +	push_native = arr.push,
                +	push = arr.push,
                +	slice = arr.slice,
                +	// Use a stripped-down indexOf as it's faster than native
                +	// https://jsperf.com/thor-indexof-vs-for/5
                +	indexOf = function( list, elem ) {
                +		var i = 0,
                +			len = list.length;
                +		for ( ; i < len; i++ ) {
                +			if ( list[i] === elem ) {
                +				return i;
                +			}
                +		}
                +		return -1;
                +	},
                +
                +	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                +
                +	// Regular expressions
                +
                +	// http://www.w3.org/TR/css3-selectors/#whitespace
                +	whitespace = "[\\x20\\t\\r\\n\\f]",
                +
                +	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
                +	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
                +
                +	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
                +	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
                +		// Operator (capture 2)
                +		"*([*^$|!~]?=)" + whitespace +
                +		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
                +		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
                +		"*\\]",
                +
                +	pseudos = ":(" + identifier + ")(?:\\((" +
                +		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
                +		// 1. quoted (capture 3; capture 4 or capture 5)
                +		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
                +		// 2. simple (capture 6)
                +		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
                +		// 3. anything else (capture 2)
                +		".*" +
                +		")\\)|)",
                +
                +	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
                +	rwhitespace = new RegExp( whitespace + "+", "g" ),
                +	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
                +
                +	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
                +	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
                +
                +	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
                +
                +	rpseudo = new RegExp( pseudos ),
                +	ridentifier = new RegExp( "^" + identifier + "$" ),
                +
                +	matchExpr = {
                +		"ID": new RegExp( "^#(" + identifier + ")" ),
                +		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
                +		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
                +		"ATTR": new RegExp( "^" + attributes ),
                +		"PSEUDO": new RegExp( "^" + pseudos ),
                +		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
                +			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
                +			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
                +		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
                +		// For use in libraries implementing .is()
                +		// We use this for POS matching in `select`
                +		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
                +			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
                +	},
                +
                +	rinputs = /^(?:input|select|textarea|button)$/i,
                +	rheader = /^h\d$/i,
                +
                +	rnative = /^[^{]+\{\s*\[native \w/,
                +
                +	// Easily-parseable/retrievable ID or TAG or CLASS selectors
                +	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                +
                +	rsibling = /[+~]/,
                +
                +	// CSS escapes
                +	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
                +	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
                +	funescape = function( _, escaped, escapedWhitespace ) {
                +		var high = "0x" + escaped - 0x10000;
                +		// NaN means non-codepoint
                +		// Support: Firefox<24
                +		// Workaround erroneous numeric interpretation of +"0x"
                +		return high !== high || escapedWhitespace ?
                +			escaped :
                +			high < 0 ?
                +				// BMP codepoint
                +				String.fromCharCode( high + 0x10000 ) :
                +				// Supplemental Plane codepoint (surrogate pair)
                +				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
                +	},
                +
                +	// CSS string/identifier serialization
                +	// https://drafts.csswg.org/cssom/#common-serializing-idioms
                +	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
                +	fcssescape = function( ch, asCodePoint ) {
                +		if ( asCodePoint ) {
                +
                +			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
                +			if ( ch === "\0" ) {
                +				return "\uFFFD";
                +			}
                +
                +			// Control characters and (dependent upon position) numbers get escaped as code points
                +			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
                +		}
                +
                +		// Other potentially-special ASCII characters get backslash-escaped
                +		return "\\" + ch;
                +	},
                +
                +	// Used for iframes
                +	// See setDocument()
                +	// Removing the function wrapper causes a "Permission Denied"
                +	// error in IE
                +	unloadHandler = function() {
                +		setDocument();
                +	},
                +
                +	disabledAncestor = addCombinator(
                +		function( elem ) {
                +			return elem.disabled === true && ("form" in elem || "label" in elem);
                +		},
                +		{ dir: "parentNode", next: "legend" }
                +	);
                +
                +// Optimize for push.apply( _, NodeList )
                +try {
                +	push.apply(
                +		(arr = slice.call( preferredDoc.childNodes )),
                +		preferredDoc.childNodes
                +	);
                +	// Support: Android<4.0
                +	// Detect silently failing push.apply
                +	arr[ preferredDoc.childNodes.length ].nodeType;
                +} catch ( e ) {
                +	push = { apply: arr.length ?
                +
                +		// Leverage slice if possible
                +		function( target, els ) {
                +			push_native.apply( target, slice.call(els) );
                +		} :
                +
                +		// Support: IE<9
                +		// Otherwise append directly
                +		function( target, els ) {
                +			var j = target.length,
                +				i = 0;
                +			// Can't trust NodeList.length
                +			while ( (target[j++] = els[i++]) ) {}
                +			target.length = j - 1;
                +		}
                +	};
                +}
                +
                +function Sizzle( selector, context, results, seed ) {
                +	var m, i, elem, nid, match, groups, newSelector,
                +		newContext = context && context.ownerDocument,
                +
                +		// nodeType defaults to 9, since context defaults to document
                +		nodeType = context ? context.nodeType : 9;
                +
                +	results = results || [];
                +
                +	// Return early from calls with invalid selector or context
                +	if ( typeof selector !== "string" || !selector ||
                +		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
                +
                +		return results;
                +	}
                +
                +	// Try to shortcut find operations (as opposed to filters) in HTML documents
                +	if ( !seed ) {
                +
                +		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
                +			setDocument( context );
                +		}
                +		context = context || document;
                +
                +		if ( documentIsHTML ) {
                +
                +			// If the selector is sufficiently simple, try using a "get*By*" DOM method
                +			// (excepting DocumentFragment context, where the methods don't exist)
                +			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
                +
                +				// ID selector
                +				if ( (m = match[1]) ) {
                +
                +					// Document context
                +					if ( nodeType === 9 ) {
                +						if ( (elem = context.getElementById( m )) ) {
                +
                +							// Support: IE, Opera, Webkit
                +							// TODO: identify versions
                +							// getElementById can match elements by name instead of ID
                +							if ( elem.id === m ) {
                +								results.push( elem );
                +								return results;
                +							}
                +						} else {
                +							return results;
                +						}
                +
                +					// Element context
                +					} else {
                +
                +						// Support: IE, Opera, Webkit
                +						// TODO: identify versions
                +						// getElementById can match elements by name instead of ID
                +						if ( newContext && (elem = newContext.getElementById( m )) &&
                +							contains( context, elem ) &&
                +							elem.id === m ) {
                +
                +							results.push( elem );
                +							return results;
                +						}
                +					}
                +
                +				// Type selector
                +				} else if ( match[2] ) {
                +					push.apply( results, context.getElementsByTagName( selector ) );
                +					return results;
                +
                +				// Class selector
                +				} else if ( (m = match[3]) && support.getElementsByClassName &&
                +					context.getElementsByClassName ) {
                +
                +					push.apply( results, context.getElementsByClassName( m ) );
                +					return results;
                +				}
                +			}
                +
                +			// Take advantage of querySelectorAll
                +			if ( support.qsa &&
                +				!compilerCache[ selector + " " ] &&
                +				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
                +
                +				if ( nodeType !== 1 ) {
                +					newContext = context;
                +					newSelector = selector;
                +
                +				// qSA looks outside Element context, which is not what we want
                +				// Thanks to Andrew Dupont for this workaround technique
                +				// Support: IE <=8
                +				// Exclude object elements
                +				} else if ( context.nodeName.toLowerCase() !== "object" ) {
                +
                +					// Capture the context ID, setting it first if necessary
                +					if ( (nid = context.getAttribute( "id" )) ) {
                +						nid = nid.replace( rcssescape, fcssescape );
                +					} else {
                +						context.setAttribute( "id", (nid = expando) );
                +					}
                +
                +					// Prefix every selector in the list
                +					groups = tokenize( selector );
                +					i = groups.length;
                +					while ( i-- ) {
                +						groups[i] = "#" + nid + " " + toSelector( groups[i] );
                +					}
                +					newSelector = groups.join( "," );
                +
                +					// Expand context for sibling selectors
                +					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
                +						context;
                +				}
                +
                +				if ( newSelector ) {
                +					try {
                +						push.apply( results,
                +							newContext.querySelectorAll( newSelector )
                +						);
                +						return results;
                +					} catch ( qsaError ) {
                +					} finally {
                +						if ( nid === expando ) {
                +							context.removeAttribute( "id" );
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	// All others
                +	return select( selector.replace( rtrim, "$1" ), context, results, seed );
                +}
                +
                +/**
                + * Create key-value caches of limited size
                + * @returns {function(string, object)} Returns the Object data after storing it on itself with
                + *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
                + *	deleting the oldest entry
                + */
                +function createCache() {
                +	var keys = [];
                +
                +	function cache( key, value ) {
                +		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
                +		if ( keys.push( key + " " ) > Expr.cacheLength ) {
                +			// Only keep the most recent entries
                +			delete cache[ keys.shift() ];
                +		}
                +		return (cache[ key + " " ] = value);
                +	}
                +	return cache;
                +}
                +
                +/**
                + * Mark a function for special use by Sizzle
                + * @param {Function} fn The function to mark
                + */
                +function markFunction( fn ) {
                +	fn[ expando ] = true;
                +	return fn;
                +}
                +
                +/**
                + * Support testing using an element
                + * @param {Function} fn Passed the created element and returns a boolean result
                + */
                +function assert( fn ) {
                +	var el = document.createElement("fieldset");
                +
                +	try {
                +		return !!fn( el );
                +	} catch (e) {
                +		return false;
                +	} finally {
                +		// Remove from its parent by default
                +		if ( el.parentNode ) {
                +			el.parentNode.removeChild( el );
                +		}
                +		// release memory in IE
                +		el = null;
                +	}
                +}
                +
                +/**
                + * Adds the same handler for all of the specified attrs
                + * @param {String} attrs Pipe-separated list of attributes
                + * @param {Function} handler The method that will be applied
                + */
                +function addHandle( attrs, handler ) {
                +	var arr = attrs.split("|"),
                +		i = arr.length;
                +
                +	while ( i-- ) {
                +		Expr.attrHandle[ arr[i] ] = handler;
                +	}
                +}
                +
                +/**
                + * Checks document order of two siblings
                + * @param {Element} a
                + * @param {Element} b
                + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
                + */
                +function siblingCheck( a, b ) {
                +	var cur = b && a,
                +		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
                +			a.sourceIndex - b.sourceIndex;
                +
                +	// Use IE sourceIndex if available on both nodes
                +	if ( diff ) {
                +		return diff;
                +	}
                +
                +	// Check if b follows a
                +	if ( cur ) {
                +		while ( (cur = cur.nextSibling) ) {
                +			if ( cur === b ) {
                +				return -1;
                +			}
                +		}
                +	}
                +
                +	return a ? 1 : -1;
                +}
                +
                +/**
                + * Returns a function to use in pseudos for input types
                + * @param {String} type
                + */
                +function createInputPseudo( type ) {
                +	return function( elem ) {
                +		var name = elem.nodeName.toLowerCase();
                +		return name === "input" && elem.type === type;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for buttons
                + * @param {String} type
                + */
                +function createButtonPseudo( type ) {
                +	return function( elem ) {
                +		var name = elem.nodeName.toLowerCase();
                +		return (name === "input" || name === "button") && elem.type === type;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for :enabled/:disabled
                + * @param {Boolean} disabled true for :disabled; false for :enabled
                + */
                +function createDisabledPseudo( disabled ) {
                +
                +	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
                +	return function( elem ) {
                +
                +		// Only certain elements can match :enabled or :disabled
                +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
                +		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
                +		if ( "form" in elem ) {
                +
                +			// Check for inherited disabledness on relevant non-disabled elements:
                +			// * listed form-associated elements in a disabled fieldset
                +			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
                +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
                +			// * option elements in a disabled optgroup
                +			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
                +			// All such elements have a "form" property.
                +			if ( elem.parentNode && elem.disabled === false ) {
                +
                +				// Option elements defer to a parent optgroup if present
                +				if ( "label" in elem ) {
                +					if ( "label" in elem.parentNode ) {
                +						return elem.parentNode.disabled === disabled;
                +					} else {
                +						return elem.disabled === disabled;
                +					}
                +				}
                +
                +				// Support: IE 6 - 11
                +				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
                +				return elem.isDisabled === disabled ||
                +
                +					// Where there is no isDisabled, check manually
                +					/* jshint -W018 */
                +					elem.isDisabled !== !disabled &&
                +						disabledAncestor( elem ) === disabled;
                +			}
                +
                +			return elem.disabled === disabled;
                +
                +		// Try to winnow out elements that can't be disabled before trusting the disabled property.
                +		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
                +		// even exist on them, let alone have a boolean value.
                +		} else if ( "label" in elem ) {
                +			return elem.disabled === disabled;
                +		}
                +
                +		// Remaining elements are neither :enabled nor :disabled
                +		return false;
                +	};
                +}
                +
                +/**
                + * Returns a function to use in pseudos for positionals
                + * @param {Function} fn
                + */
                +function createPositionalPseudo( fn ) {
                +	return markFunction(function( argument ) {
                +		argument = +argument;
                +		return markFunction(function( seed, matches ) {
                +			var j,
                +				matchIndexes = fn( [], seed.length, argument ),
                +				i = matchIndexes.length;
                +
                +			// Match elements found at the specified indexes
                +			while ( i-- ) {
                +				if ( seed[ (j = matchIndexes[i]) ] ) {
                +					seed[j] = !(matches[j] = seed[j]);
                +				}
                +			}
                +		});
                +	});
                +}
                +
                +/**
                + * Checks a node for validity as a Sizzle context
                + * @param {Element|Object=} context
                + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
                + */
                +function testContext( context ) {
                +	return context && typeof context.getElementsByTagName !== "undefined" && context;
                +}
                +
                +// Expose support vars for convenience
                +support = Sizzle.support = {};
                +
                +/**
                + * Detects XML nodes
                + * @param {Element|Object} elem An element or a document
                + * @returns {Boolean} True iff elem is a non-HTML XML node
                + */
                +isXML = Sizzle.isXML = function( elem ) {
                +	// documentElement is verified for cases where it doesn't yet exist
                +	// (such as loading iframes in IE - #4833)
                +	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
                +	return documentElement ? documentElement.nodeName !== "HTML" : false;
                +};
                +
                +/**
                + * Sets document-related variables once based on the current document
                + * @param {Element|Object} [doc] An element or document object to use to set the document
                + * @returns {Object} Returns the current document
                + */
                +setDocument = Sizzle.setDocument = function( node ) {
                +	var hasCompare, subWindow,
                +		doc = node ? node.ownerDocument || node : preferredDoc;
                +
                +	// Return early if doc is invalid or already selected
                +	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
                +		return document;
                +	}
                +
                +	// Update global variables
                +	document = doc;
                +	docElem = document.documentElement;
                +	documentIsHTML = !isXML( document );
                +
                +	// Support: IE 9-11, Edge
                +	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
                +	if ( preferredDoc !== document &&
                +		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
                +
                +		// Support: IE 11, Edge
                +		if ( subWindow.addEventListener ) {
                +			subWindow.addEventListener( "unload", unloadHandler, false );
                +
                +		// Support: IE 9 - 10 only
                +		} else if ( subWindow.attachEvent ) {
                +			subWindow.attachEvent( "onunload", unloadHandler );
                +		}
                +	}
                +
                +	/* Attributes
                +	---------------------------------------------------------------------- */
                +
                +	// Support: IE<8
                +	// Verify that getAttribute really returns attributes and not properties
                +	// (excepting IE8 booleans)
                +	support.attributes = assert(function( el ) {
                +		el.className = "i";
                +		return !el.getAttribute("className");
                +	});
                +
                +	/* getElement(s)By*
                +	---------------------------------------------------------------------- */
                +
                +	// Check if getElementsByTagName("*") returns only elements
                +	support.getElementsByTagName = assert(function( el ) {
                +		el.appendChild( document.createComment("") );
                +		return !el.getElementsByTagName("*").length;
                +	});
                +
                +	// Support: IE<9
                +	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
                +
                +	// Support: IE<10
                +	// Check if getElementById returns elements by name
                +	// The broken getElementById methods don't pick up programmatically-set names,
                +	// so use a roundabout getElementsByName test
                +	support.getById = assert(function( el ) {
                +		docElem.appendChild( el ).id = expando;
                +		return !document.getElementsByName || !document.getElementsByName( expando ).length;
                +	});
                +
                +	// ID filter and find
                +	if ( support.getById ) {
                +		Expr.filter["ID"] = function( id ) {
                +			var attrId = id.replace( runescape, funescape );
                +			return function( elem ) {
                +				return elem.getAttribute("id") === attrId;
                +			};
                +		};
                +		Expr.find["ID"] = function( id, context ) {
                +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
                +				var elem = context.getElementById( id );
                +				return elem ? [ elem ] : [];
                +			}
                +		};
                +	} else {
                +		Expr.filter["ID"] =  function( id ) {
                +			var attrId = id.replace( runescape, funescape );
                +			return function( elem ) {
                +				var node = typeof elem.getAttributeNode !== "undefined" &&
                +					elem.getAttributeNode("id");
                +				return node && node.value === attrId;
                +			};
                +		};
                +
                +		// Support: IE 6 - 7 only
                +		// getElementById is not reliable as a find shortcut
                +		Expr.find["ID"] = function( id, context ) {
                +			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
                +				var node, i, elems,
                +					elem = context.getElementById( id );
                +
                +				if ( elem ) {
                +
                +					// Verify the id attribute
                +					node = elem.getAttributeNode("id");
                +					if ( node && node.value === id ) {
                +						return [ elem ];
                +					}
                +
                +					// Fall back on getElementsByName
                +					elems = context.getElementsByName( id );
                +					i = 0;
                +					while ( (elem = elems[i++]) ) {
                +						node = elem.getAttributeNode("id");
                +						if ( node && node.value === id ) {
                +							return [ elem ];
                +						}
                +					}
                +				}
                +
                +				return [];
                +			}
                +		};
                +	}
                +
                +	// Tag
                +	Expr.find["TAG"] = support.getElementsByTagName ?
                +		function( tag, context ) {
                +			if ( typeof context.getElementsByTagName !== "undefined" ) {
                +				return context.getElementsByTagName( tag );
                +
                +			// DocumentFragment nodes don't have gEBTN
                +			} else if ( support.qsa ) {
                +				return context.querySelectorAll( tag );
                +			}
                +		} :
                +
                +		function( tag, context ) {
                +			var elem,
                +				tmp = [],
                +				i = 0,
                +				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
                +				results = context.getElementsByTagName( tag );
                +
                +			// Filter out possible comments
                +			if ( tag === "*" ) {
                +				while ( (elem = results[i++]) ) {
                +					if ( elem.nodeType === 1 ) {
                +						tmp.push( elem );
                +					}
                +				}
                +
                +				return tmp;
                +			}
                +			return results;
                +		};
                +
                +	// Class
                +	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
                +		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
                +			return context.getElementsByClassName( className );
                +		}
                +	};
                +
                +	/* QSA/matchesSelector
                +	---------------------------------------------------------------------- */
                +
                +	// QSA and matchesSelector support
                +
                +	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
                +	rbuggyMatches = [];
                +
                +	// qSa(:focus) reports false when true (Chrome 21)
                +	// We allow this because of a bug in IE8/9 that throws an error
                +	// whenever `document.activeElement` is accessed on an iframe
                +	// So, we allow :focus to pass through QSA all the time to avoid the IE error
                +	// See https://bugs.jquery.com/ticket/13378
                +	rbuggyQSA = [];
                +
                +	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
                +		// Build QSA regex
                +		// Regex strategy adopted from Diego Perini
                +		assert(function( el ) {
                +			// Select is set to empty string on purpose
                +			// This is to test IE's treatment of not explicitly
                +			// setting a boolean content attribute,
                +			// since its presence should be enough
                +			// https://bugs.jquery.com/ticket/12359
                +			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
                +				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
                +				"<option selected=''></option></select>";
                +
                +			// Support: IE8, Opera 11-12.16
                +			// Nothing should be selected when empty strings follow ^= or $= or *=
                +			// The test attribute must be unknown in Opera but "safe" for WinRT
                +			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
                +			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
                +				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
                +			}
                +
                +			// Support: IE8
                +			// Boolean attributes and "value" are not treated correctly
                +			if ( !el.querySelectorAll("[selected]").length ) {
                +				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
                +			}
                +
                +			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
                +			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
                +				rbuggyQSA.push("~=");
                +			}
                +
                +			// Webkit/Opera - :checked should return selected option elements
                +			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                +			// IE8 throws error here and will not see later tests
                +			if ( !el.querySelectorAll(":checked").length ) {
                +				rbuggyQSA.push(":checked");
                +			}
                +
                +			// Support: Safari 8+, iOS 8+
                +			// https://bugs.webkit.org/show_bug.cgi?id=136851
                +			// In-page `selector#id sibling-combinator selector` fails
                +			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
                +				rbuggyQSA.push(".#.+[+~]");
                +			}
                +		});
                +
                +		assert(function( el ) {
                +			el.innerHTML = "<a href='' disabled='disabled'></a>" +
                +				"<select disabled='disabled'><option/></select>";
                +
                +			// Support: Windows 8 Native Apps
                +			// The type and name attributes are restricted during .innerHTML assignment
                +			var input = document.createElement("input");
                +			input.setAttribute( "type", "hidden" );
                +			el.appendChild( input ).setAttribute( "name", "D" );
                +
                +			// Support: IE8
                +			// Enforce case-sensitivity of name attribute
                +			if ( el.querySelectorAll("[name=d]").length ) {
                +				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
                +			}
                +
                +			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
                +			// IE8 throws error here and will not see later tests
                +			if ( el.querySelectorAll(":enabled").length !== 2 ) {
                +				rbuggyQSA.push( ":enabled", ":disabled" );
                +			}
                +
                +			// Support: IE9-11+
                +			// IE's :disabled selector does not pick up the children of disabled fieldsets
                +			docElem.appendChild( el ).disabled = true;
                +			if ( el.querySelectorAll(":disabled").length !== 2 ) {
                +				rbuggyQSA.push( ":enabled", ":disabled" );
                +			}
                +
                +			// Opera 10-11 does not throw on post-comma invalid pseudos
                +			el.querySelectorAll("*,:x");
                +			rbuggyQSA.push(",.*:");
                +		});
                +	}
                +
                +	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
                +		docElem.webkitMatchesSelector ||
                +		docElem.mozMatchesSelector ||
                +		docElem.oMatchesSelector ||
                +		docElem.msMatchesSelector) )) ) {
                +
                +		assert(function( el ) {
                +			// Check to see if it's possible to do matchesSelector
                +			// on a disconnected node (IE 9)
                +			support.disconnectedMatch = matches.call( el, "*" );
                +
                +			// This should fail with an exception
                +			// Gecko does not error, returns false instead
                +			matches.call( el, "[s!='']:x" );
                +			rbuggyMatches.push( "!=", pseudos );
                +		});
                +	}
                +
                +	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
                +	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
                +
                +	/* Contains
                +	---------------------------------------------------------------------- */
                +	hasCompare = rnative.test( docElem.compareDocumentPosition );
                +
                +	// Element contains another
                +	// Purposefully self-exclusive
                +	// As in, an element does not contain itself
                +	contains = hasCompare || rnative.test( docElem.contains ) ?
                +		function( a, b ) {
                +			var adown = a.nodeType === 9 ? a.documentElement : a,
                +				bup = b && b.parentNode;
                +			return a === bup || !!( bup && bup.nodeType === 1 && (
                +				adown.contains ?
                +					adown.contains( bup ) :
                +					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
                +			));
                +		} :
                +		function( a, b ) {
                +			if ( b ) {
                +				while ( (b = b.parentNode) ) {
                +					if ( b === a ) {
                +						return true;
                +					}
                +				}
                +			}
                +			return false;
                +		};
                +
                +	/* Sorting
                +	---------------------------------------------------------------------- */
                +
                +	// Document order sorting
                +	sortOrder = hasCompare ?
                +	function( a, b ) {
                +
                +		// Flag for duplicate removal
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +			return 0;
                +		}
                +
                +		// Sort on method existence if only one input has compareDocumentPosition
                +		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
                +		if ( compare ) {
                +			return compare;
                +		}
                +
                +		// Calculate position if both inputs belong to the same document
                +		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
                +			a.compareDocumentPosition( b ) :
                +
                +			// Otherwise we know they are disconnected
                +			1;
                +
                +		// Disconnected nodes
                +		if ( compare & 1 ||
                +			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
                +
                +			// Choose the first element that is related to our preferred document
                +			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
                +				return -1;
                +			}
                +			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
                +				return 1;
                +			}
                +
                +			// Maintain original order
                +			return sortInput ?
                +				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
                +				0;
                +		}
                +
                +		return compare & 4 ? -1 : 1;
                +	} :
                +	function( a, b ) {
                +		// Exit early if the nodes are identical
                +		if ( a === b ) {
                +			hasDuplicate = true;
                +			return 0;
                +		}
                +
                +		var cur,
                +			i = 0,
                +			aup = a.parentNode,
                +			bup = b.parentNode,
                +			ap = [ a ],
                +			bp = [ b ];
                +
                +		// Parentless nodes are either documents or disconnected
                +		if ( !aup || !bup ) {
                +			return a === document ? -1 :
                +				b === document ? 1 :
                +				aup ? -1 :
                +				bup ? 1 :
                +				sortInput ?
                +				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
                +				0;
                +
                +		// If the nodes are siblings, we can do a quick check
                +		} else if ( aup === bup ) {
                +			return siblingCheck( a, b );
                +		}
                +
                +		// Otherwise we need full lists of their ancestors for comparison
                +		cur = a;
                +		while ( (cur = cur.parentNode) ) {
                +			ap.unshift( cur );
                +		}
                +		cur = b;
                +		while ( (cur = cur.parentNode) ) {
                +			bp.unshift( cur );
                +		}
                +
                +		// Walk down the tree looking for a discrepancy
                +		while ( ap[i] === bp[i] ) {
                +			i++;
                +		}
                +
                +		return i ?
                +			// Do a sibling check if the nodes have a common ancestor
                +			siblingCheck( ap[i], bp[i] ) :
                +
                +			// Otherwise nodes in our document sort first
                +			ap[i] === preferredDoc ? -1 :
                +			bp[i] === preferredDoc ? 1 :
                +			0;
                +	};
                +
                +	return document;
                +};
                +
                +Sizzle.matches = function( expr, elements ) {
                +	return Sizzle( expr, null, null, elements );
                +};
                +
                +Sizzle.matchesSelector = function( elem, expr ) {
                +	// Set document vars if needed
                +	if ( ( elem.ownerDocument || elem ) !== document ) {
                +		setDocument( elem );
                +	}
                +
                +	// Make sure that attribute selectors are quoted
                +	expr = expr.replace( rattributeQuotes, "='$1']" );
                +
                +	if ( support.matchesSelector && documentIsHTML &&
                +		!compilerCache[ expr + " " ] &&
                +		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
                +		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
                +
                +		try {
                +			var ret = matches.call( elem, expr );
                +
                +			// IE 9's matchesSelector returns false on disconnected nodes
                +			if ( ret || support.disconnectedMatch ||
                +					// As well, disconnected nodes are said to be in a document
                +					// fragment in IE 9
                +					elem.document && elem.document.nodeType !== 11 ) {
                +				return ret;
                +			}
                +		} catch (e) {}
                +	}
                +
                +	return Sizzle( expr, document, null, [ elem ] ).length > 0;
                +};
                +
                +Sizzle.contains = function( context, elem ) {
                +	// Set document vars if needed
                +	if ( ( context.ownerDocument || context ) !== document ) {
                +		setDocument( context );
                +	}
                +	return contains( context, elem );
                +};
                +
                +Sizzle.attr = function( elem, name ) {
                +	// Set document vars if needed
                +	if ( ( elem.ownerDocument || elem ) !== document ) {
                +		setDocument( elem );
                +	}
                +
                +	var fn = Expr.attrHandle[ name.toLowerCase() ],
                +		// Don't get fooled by Object.prototype properties (jQuery #13807)
                +		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
                +			fn( elem, name, !documentIsHTML ) :
                +			undefined;
                +
                +	return val !== undefined ?
                +		val :
                +		support.attributes || !documentIsHTML ?
                +			elem.getAttribute( name ) :
                +			(val = elem.getAttributeNode(name)) && val.specified ?
                +				val.value :
                +				null;
                +};
                +
                +Sizzle.escape = function( sel ) {
                +	return (sel + "").replace( rcssescape, fcssescape );
                +};
                +
                +Sizzle.error = function( msg ) {
                +	throw new Error( "Syntax error, unrecognized expression: " + msg );
                +};
                +
                +/**
                + * Document sorting and removing duplicates
                + * @param {ArrayLike} results
                + */
                +Sizzle.uniqueSort = function( results ) {
                +	var elem,
                +		duplicates = [],
                +		j = 0,
                +		i = 0;
                +
                +	// Unless we *know* we can detect duplicates, assume their presence
                +	hasDuplicate = !support.detectDuplicates;
                +	sortInput = !support.sortStable && results.slice( 0 );
                +	results.sort( sortOrder );
                +
                +	if ( hasDuplicate ) {
                +		while ( (elem = results[i++]) ) {
                +			if ( elem === results[ i ] ) {
                +				j = duplicates.push( i );
                +			}
                +		}
                +		while ( j-- ) {
                +			results.splice( duplicates[ j ], 1 );
                +		}
                +	}
                +
                +	// Clear input after sorting to release objects
                +	// See https://github.com/jquery/sizzle/pull/225
                +	sortInput = null;
                +
                +	return results;
                +};
                +
                +/**
                + * Utility function for retrieving the text value of an array of DOM nodes
                + * @param {Array|Element} elem
                + */
                +getText = Sizzle.getText = function( elem ) {
                +	var node,
                +		ret = "",
                +		i = 0,
                +		nodeType = elem.nodeType;
                +
                +	if ( !nodeType ) {
                +		// If no nodeType, this is expected to be an array
                +		while ( (node = elem[i++]) ) {
                +			// Do not traverse comment nodes
                +			ret += getText( node );
                +		}
                +	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
                +		// Use textContent for elements
                +		// innerText usage removed for consistency of new lines (jQuery #11153)
                +		if ( typeof elem.textContent === "string" ) {
                +			return elem.textContent;
                +		} else {
                +			// Traverse its children
                +			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                +				ret += getText( elem );
                +			}
                +		}
                +	} else if ( nodeType === 3 || nodeType === 4 ) {
                +		return elem.nodeValue;
                +	}
                +	// Do not include comment or processing instruction nodes
                +
                +	return ret;
                +};
                +
                +Expr = Sizzle.selectors = {
                +
                +	// Can be adjusted by the user
                +	cacheLength: 50,
                +
                +	createPseudo: markFunction,
                +
                +	match: matchExpr,
                +
                +	attrHandle: {},
                +
                +	find: {},
                +
                +	relative: {
                +		">": { dir: "parentNode", first: true },
                +		" ": { dir: "parentNode" },
                +		"+": { dir: "previousSibling", first: true },
                +		"~": { dir: "previousSibling" }
                +	},
                +
                +	preFilter: {
                +		"ATTR": function( match ) {
                +			match[1] = match[1].replace( runescape, funescape );
                +
                +			// Move the given value to match[3] whether quoted or unquoted
                +			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
                +
                +			if ( match[2] === "~=" ) {
                +				match[3] = " " + match[3] + " ";
                +			}
                +
                +			return match.slice( 0, 4 );
                +		},
                +
                +		"CHILD": function( match ) {
                +			/* matches from matchExpr["CHILD"]
                +				1 type (only|nth|...)
                +				2 what (child|of-type)
                +				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
                +				4 xn-component of xn+y argument ([+-]?\d*n|)
                +				5 sign of xn-component
                +				6 x of xn-component
                +				7 sign of y-component
                +				8 y of y-component
                +			*/
                +			match[1] = match[1].toLowerCase();
                +
                +			if ( match[1].slice( 0, 3 ) === "nth" ) {
                +				// nth-* requires argument
                +				if ( !match[3] ) {
                +					Sizzle.error( match[0] );
                +				}
                +
                +				// numeric x and y parameters for Expr.filter.CHILD
                +				// remember that false/true cast respectively to 0/1
                +				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
                +				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
                +
                +			// other types prohibit arguments
                +			} else if ( match[3] ) {
                +				Sizzle.error( match[0] );
                +			}
                +
                +			return match;
                +		},
                +
                +		"PSEUDO": function( match ) {
                +			var excess,
                +				unquoted = !match[6] && match[2];
                +
                +			if ( matchExpr["CHILD"].test( match[0] ) ) {
                +				return null;
                +			}
                +
                +			// Accept quoted arguments as-is
                +			if ( match[3] ) {
                +				match[2] = match[4] || match[5] || "";
                +
                +			// Strip excess characters from unquoted arguments
                +			} else if ( unquoted && rpseudo.test( unquoted ) &&
                +				// Get excess from tokenize (recursively)
                +				(excess = tokenize( unquoted, true )) &&
                +				// advance to the next closing parenthesis
                +				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
                +
                +				// excess is a negative index
                +				match[0] = match[0].slice( 0, excess );
                +				match[2] = unquoted.slice( 0, excess );
                +			}
                +
                +			// Return only captures needed by the pseudo filter method (type and argument)
                +			return match.slice( 0, 3 );
                +		}
                +	},
                +
                +	filter: {
                +
                +		"TAG": function( nodeNameSelector ) {
                +			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
                +			return nodeNameSelector === "*" ?
                +				function() { return true; } :
                +				function( elem ) {
                +					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
                +				};
                +		},
                +
                +		"CLASS": function( className ) {
                +			var pattern = classCache[ className + " " ];
                +
                +			return pattern ||
                +				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
                +				classCache( className, function( elem ) {
                +					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
                +				});
                +		},
                +
                +		"ATTR": function( name, operator, check ) {
                +			return function( elem ) {
                +				var result = Sizzle.attr( elem, name );
                +
                +				if ( result == null ) {
                +					return operator === "!=";
                +				}
                +				if ( !operator ) {
                +					return true;
                +				}
                +
                +				result += "";
                +
                +				return operator === "=" ? result === check :
                +					operator === "!=" ? result !== check :
                +					operator === "^=" ? check && result.indexOf( check ) === 0 :
                +					operator === "*=" ? check && result.indexOf( check ) > -1 :
                +					operator === "$=" ? check && result.slice( -check.length ) === check :
                +					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
                +					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
                +					false;
                +			};
                +		},
                +
                +		"CHILD": function( type, what, argument, first, last ) {
                +			var simple = type.slice( 0, 3 ) !== "nth",
                +				forward = type.slice( -4 ) !== "last",
                +				ofType = what === "of-type";
                +
                +			return first === 1 && last === 0 ?
                +
                +				// Shortcut for :nth-*(n)
                +				function( elem ) {
                +					return !!elem.parentNode;
                +				} :
                +
                +				function( elem, context, xml ) {
                +					var cache, uniqueCache, outerCache, node, nodeIndex, start,
                +						dir = simple !== forward ? "nextSibling" : "previousSibling",
                +						parent = elem.parentNode,
                +						name = ofType && elem.nodeName.toLowerCase(),
                +						useCache = !xml && !ofType,
                +						diff = false;
                +
                +					if ( parent ) {
                +
                +						// :(first|last|only)-(child|of-type)
                +						if ( simple ) {
                +							while ( dir ) {
                +								node = elem;
                +								while ( (node = node[ dir ]) ) {
                +									if ( ofType ?
                +										node.nodeName.toLowerCase() === name :
                +										node.nodeType === 1 ) {
                +
                +										return false;
                +									}
                +								}
                +								// Reverse direction for :only-* (if we haven't yet done so)
                +								start = dir = type === "only" && !start && "nextSibling";
                +							}
                +							return true;
                +						}
                +
                +						start = [ forward ? parent.firstChild : parent.lastChild ];
                +
                +						// non-xml :nth-child(...) stores cache data on `parent`
                +						if ( forward && useCache ) {
                +
                +							// Seek `elem` from a previously-cached index
                +
                +							// ...in a gzip-friendly way
                +							node = parent;
                +							outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +							// Support: IE <9 only
                +							// Defend against cloned attroperties (jQuery gh-1709)
                +							uniqueCache = outerCache[ node.uniqueID ] ||
                +								(outerCache[ node.uniqueID ] = {});
                +
                +							cache = uniqueCache[ type ] || [];
                +							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                +							diff = nodeIndex && cache[ 2 ];
                +							node = nodeIndex && parent.childNodes[ nodeIndex ];
                +
                +							while ( (node = ++nodeIndex && node && node[ dir ] ||
                +
                +								// Fallback to seeking `elem` from the start
                +								(diff = nodeIndex = 0) || start.pop()) ) {
                +
                +								// When found, cache indexes on `parent` and break
                +								if ( node.nodeType === 1 && ++diff && node === elem ) {
                +									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
                +									break;
                +								}
                +							}
                +
                +						} else {
                +							// Use previously-cached element index if available
                +							if ( useCache ) {
                +								// ...in a gzip-friendly way
                +								node = elem;
                +								outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +								// Support: IE <9 only
                +								// Defend against cloned attroperties (jQuery gh-1709)
                +								uniqueCache = outerCache[ node.uniqueID ] ||
                +									(outerCache[ node.uniqueID ] = {});
                +
                +								cache = uniqueCache[ type ] || [];
                +								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                +								diff = nodeIndex;
                +							}
                +
                +							// xml :nth-child(...)
                +							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
                +							if ( diff === false ) {
                +								// Use the same loop as above to seek `elem` from the start
                +								while ( (node = ++nodeIndex && node && node[ dir ] ||
                +									(diff = nodeIndex = 0) || start.pop()) ) {
                +
                +									if ( ( ofType ?
                +										node.nodeName.toLowerCase() === name :
                +										node.nodeType === 1 ) &&
                +										++diff ) {
                +
                +										// Cache the index of each encountered element
                +										if ( useCache ) {
                +											outerCache = node[ expando ] || (node[ expando ] = {});
                +
                +											// Support: IE <9 only
                +											// Defend against cloned attroperties (jQuery gh-1709)
                +											uniqueCache = outerCache[ node.uniqueID ] ||
                +												(outerCache[ node.uniqueID ] = {});
                +
                +											uniqueCache[ type ] = [ dirruns, diff ];
                +										}
                +
                +										if ( node === elem ) {
                +											break;
                +										}
                +									}
                +								}
                +							}
                +						}
                +
                +						// Incorporate the offset, then check against cycle size
                +						diff -= last;
                +						return diff === first || ( diff % first === 0 && diff / first >= 0 );
                +					}
                +				};
                +		},
                +
                +		"PSEUDO": function( pseudo, argument ) {
                +			// pseudo-class names are case-insensitive
                +			// http://www.w3.org/TR/selectors/#pseudo-classes
                +			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
                +			// Remember that setFilters inherits from pseudos
                +			var args,
                +				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                +					Sizzle.error( "unsupported pseudo: " + pseudo );
                +
                +			// The user may use createPseudo to indicate that
                +			// arguments are needed to create the filter function
                +			// just as Sizzle does
                +			if ( fn[ expando ] ) {
                +				return fn( argument );
                +			}
                +
                +			// But maintain support for old signatures
                +			if ( fn.length > 1 ) {
                +				args = [ pseudo, pseudo, "", argument ];
                +				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                +					markFunction(function( seed, matches ) {
                +						var idx,
                +							matched = fn( seed, argument ),
                +							i = matched.length;
                +						while ( i-- ) {
                +							idx = indexOf( seed, matched[i] );
                +							seed[ idx ] = !( matches[ idx ] = matched[i] );
                +						}
                +					}) :
                +					function( elem ) {
                +						return fn( elem, 0, args );
                +					};
                +			}
                +
                +			return fn;
                +		}
                +	},
                +
                +	pseudos: {
                +		// Potentially complex pseudos
                +		"not": markFunction(function( selector ) {
                +			// Trim the selector passed to compile
                +			// to avoid treating leading and trailing
                +			// spaces as combinators
                +			var input = [],
                +				results = [],
                +				matcher = compile( selector.replace( rtrim, "$1" ) );
                +
                +			return matcher[ expando ] ?
                +				markFunction(function( seed, matches, context, xml ) {
                +					var elem,
                +						unmatched = matcher( seed, null, xml, [] ),
                +						i = seed.length;
                +
                +					// Match elements unmatched by `matcher`
                +					while ( i-- ) {
                +						if ( (elem = unmatched[i]) ) {
                +							seed[i] = !(matches[i] = elem);
                +						}
                +					}
                +				}) :
                +				function( elem, context, xml ) {
                +					input[0] = elem;
                +					matcher( input, null, xml, results );
                +					// Don't keep the element (issue #299)
                +					input[0] = null;
                +					return !results.pop();
                +				};
                +		}),
                +
                +		"has": markFunction(function( selector ) {
                +			return function( elem ) {
                +				return Sizzle( selector, elem ).length > 0;
                +			};
                +		}),
                +
                +		"contains": markFunction(function( text ) {
                +			text = text.replace( runescape, funescape );
                +			return function( elem ) {
                +				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
                +			};
                +		}),
                +
                +		// "Whether an element is represented by a :lang() selector
                +		// is based solely on the element's language value
                +		// being equal to the identifier C,
                +		// or beginning with the identifier C immediately followed by "-".
                +		// The matching of C against the element's language value is performed case-insensitively.
                +		// The identifier C does not have to be a valid language name."
                +		// http://www.w3.org/TR/selectors/#lang-pseudo
                +		"lang": markFunction( function( lang ) {
                +			// lang value must be a valid identifier
                +			if ( !ridentifier.test(lang || "") ) {
                +				Sizzle.error( "unsupported lang: " + lang );
                +			}
                +			lang = lang.replace( runescape, funescape ).toLowerCase();
                +			return function( elem ) {
                +				var elemLang;
                +				do {
                +					if ( (elemLang = documentIsHTML ?
                +						elem.lang :
                +						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
                +
                +						elemLang = elemLang.toLowerCase();
                +						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
                +					}
                +				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
                +				return false;
                +			};
                +		}),
                +
                +		// Miscellaneous
                +		"target": function( elem ) {
                +			var hash = window.location && window.location.hash;
                +			return hash && hash.slice( 1 ) === elem.id;
                +		},
                +
                +		"root": function( elem ) {
                +			return elem === docElem;
                +		},
                +
                +		"focus": function( elem ) {
                +			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
                +		},
                +
                +		// Boolean properties
                +		"enabled": createDisabledPseudo( false ),
                +		"disabled": createDisabledPseudo( true ),
                +
                +		"checked": function( elem ) {
                +			// In CSS3, :checked should return both checked and selected elements
                +			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                +			var nodeName = elem.nodeName.toLowerCase();
                +			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
                +		},
                +
                +		"selected": function( elem ) {
                +			// Accessing this property makes selected-by-default
                +			// options in Safari work properly
                +			if ( elem.parentNode ) {
                +				elem.parentNode.selectedIndex;
                +			}
                +
                +			return elem.selected === true;
                +		},
                +
                +		// Contents
                +		"empty": function( elem ) {
                +			// http://www.w3.org/TR/selectors/#empty-pseudo
                +			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
                +			//   but not by others (comment: 8; processing instruction: 7; etc.)
                +			// nodeType < 6 works because attributes (2) do not appear as children
                +			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                +				if ( elem.nodeType < 6 ) {
                +					return false;
                +				}
                +			}
                +			return true;
                +		},
                +
                +		"parent": function( elem ) {
                +			return !Expr.pseudos["empty"]( elem );
                +		},
                +
                +		// Element/input types
                +		"header": function( elem ) {
                +			return rheader.test( elem.nodeName );
                +		},
                +
                +		"input": function( elem ) {
                +			return rinputs.test( elem.nodeName );
                +		},
                +
                +		"button": function( elem ) {
                +			var name = elem.nodeName.toLowerCase();
                +			return name === "input" && elem.type === "button" || name === "button";
                +		},
                +
                +		"text": function( elem ) {
                +			var attr;
                +			return elem.nodeName.toLowerCase() === "input" &&
                +				elem.type === "text" &&
                +
                +				// Support: IE<8
                +				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
                +				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
                +		},
                +
                +		// Position-in-collection
                +		"first": createPositionalPseudo(function() {
                +			return [ 0 ];
                +		}),
                +
                +		"last": createPositionalPseudo(function( matchIndexes, length ) {
                +			return [ length - 1 ];
                +		}),
                +
                +		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			return [ argument < 0 ? argument + length : argument ];
                +		}),
                +
                +		"even": createPositionalPseudo(function( matchIndexes, length ) {
                +			var i = 0;
                +			for ( ; i < length; i += 2 ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"odd": createPositionalPseudo(function( matchIndexes, length ) {
                +			var i = 1;
                +			for ( ; i < length; i += 2 ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			var i = argument < 0 ? argument + length : argument;
                +			for ( ; --i >= 0; ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		}),
                +
                +		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                +			var i = argument < 0 ? argument + length : argument;
                +			for ( ; ++i < length; ) {
                +				matchIndexes.push( i );
                +			}
                +			return matchIndexes;
                +		})
                +	}
                +};
                +
                +Expr.pseudos["nth"] = Expr.pseudos["eq"];
                +
                +// Add button/input type pseudos
                +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
                +	Expr.pseudos[ i ] = createInputPseudo( i );
                +}
                +for ( i in { submit: true, reset: true } ) {
                +	Expr.pseudos[ i ] = createButtonPseudo( i );
                +}
                +
                +// Easy API for creating new setFilters
                +function setFilters() {}
                +setFilters.prototype = Expr.filters = Expr.pseudos;
                +Expr.setFilters = new setFilters();
                +
                +tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
                +	var matched, match, tokens, type,
                +		soFar, groups, preFilters,
                +		cached = tokenCache[ selector + " " ];
                +
                +	if ( cached ) {
                +		return parseOnly ? 0 : cached.slice( 0 );
                +	}
                +
                +	soFar = selector;
                +	groups = [];
                +	preFilters = Expr.preFilter;
                +
                +	while ( soFar ) {
                +
                +		// Comma and first run
                +		if ( !matched || (match = rcomma.exec( soFar )) ) {
                +			if ( match ) {
                +				// Don't consume trailing commas as valid
                +				soFar = soFar.slice( match[0].length ) || soFar;
                +			}
                +			groups.push( (tokens = []) );
                +		}
                +
                +		matched = false;
                +
                +		// Combinators
                +		if ( (match = rcombinators.exec( soFar )) ) {
                +			matched = match.shift();
                +			tokens.push({
                +				value: matched,
                +				// Cast descendant combinators to space
                +				type: match[0].replace( rtrim, " " )
                +			});
                +			soFar = soFar.slice( matched.length );
                +		}
                +
                +		// Filters
                +		for ( type in Expr.filter ) {
                +			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
                +				(match = preFilters[ type ]( match ))) ) {
                +				matched = match.shift();
                +				tokens.push({
                +					value: matched,
                +					type: type,
                +					matches: match
                +				});
                +				soFar = soFar.slice( matched.length );
                +			}
                +		}
                +
                +		if ( !matched ) {
                +			break;
                +		}
                +	}
                +
                +	// Return the length of the invalid excess
                +	// if we're just parsing
                +	// Otherwise, throw an error or return tokens
                +	return parseOnly ?
                +		soFar.length :
                +		soFar ?
                +			Sizzle.error( selector ) :
                +			// Cache the tokens
                +			tokenCache( selector, groups ).slice( 0 );
                +};
                +
                +function toSelector( tokens ) {
                +	var i = 0,
                +		len = tokens.length,
                +		selector = "";
                +	for ( ; i < len; i++ ) {
                +		selector += tokens[i].value;
                +	}
                +	return selector;
                +}
                +
                +function addCombinator( matcher, combinator, base ) {
                +	var dir = combinator.dir,
                +		skip = combinator.next,
                +		key = skip || dir,
                +		checkNonElements = base && key === "parentNode",
                +		doneName = done++;
                +
                +	return combinator.first ?
                +		// Check against closest ancestor/preceding element
                +		function( elem, context, xml ) {
                +			while ( (elem = elem[ dir ]) ) {
                +				if ( elem.nodeType === 1 || checkNonElements ) {
                +					return matcher( elem, context, xml );
                +				}
                +			}
                +			return false;
                +		} :
                +
                +		// Check against all ancestor/preceding elements
                +		function( elem, context, xml ) {
                +			var oldCache, uniqueCache, outerCache,
                +				newCache = [ dirruns, doneName ];
                +
                +			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
                +			if ( xml ) {
                +				while ( (elem = elem[ dir ]) ) {
                +					if ( elem.nodeType === 1 || checkNonElements ) {
                +						if ( matcher( elem, context, xml ) ) {
                +							return true;
                +						}
                +					}
                +				}
                +			} else {
                +				while ( (elem = elem[ dir ]) ) {
                +					if ( elem.nodeType === 1 || checkNonElements ) {
                +						outerCache = elem[ expando ] || (elem[ expando ] = {});
                +
                +						// Support: IE <9 only
                +						// Defend against cloned attroperties (jQuery gh-1709)
                +						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
                +
                +						if ( skip && skip === elem.nodeName.toLowerCase() ) {
                +							elem = elem[ dir ] || elem;
                +						} else if ( (oldCache = uniqueCache[ key ]) &&
                +							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
                +
                +							// Assign to newCache so results back-propagate to previous elements
                +							return (newCache[ 2 ] = oldCache[ 2 ]);
                +						} else {
                +							// Reuse newcache so results back-propagate to previous elements
                +							uniqueCache[ key ] = newCache;
                +
                +							// A match means we're done; a fail means we have to keep checking
                +							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
                +								return true;
                +							}
                +						}
                +					}
                +				}
                +			}
                +			return false;
                +		};
                +}
                +
                +function elementMatcher( matchers ) {
                +	return matchers.length > 1 ?
                +		function( elem, context, xml ) {
                +			var i = matchers.length;
                +			while ( i-- ) {
                +				if ( !matchers[i]( elem, context, xml ) ) {
                +					return false;
                +				}
                +			}
                +			return true;
                +		} :
                +		matchers[0];
                +}
                +
                +function multipleContexts( selector, contexts, results ) {
                +	var i = 0,
                +		len = contexts.length;
                +	for ( ; i < len; i++ ) {
                +		Sizzle( selector, contexts[i], results );
                +	}
                +	return results;
                +}
                +
                +function condense( unmatched, map, filter, context, xml ) {
                +	var elem,
                +		newUnmatched = [],
                +		i = 0,
                +		len = unmatched.length,
                +		mapped = map != null;
                +
                +	for ( ; i < len; i++ ) {
                +		if ( (elem = unmatched[i]) ) {
                +			if ( !filter || filter( elem, context, xml ) ) {
                +				newUnmatched.push( elem );
                +				if ( mapped ) {
                +					map.push( i );
                +				}
                +			}
                +		}
                +	}
                +
                +	return newUnmatched;
                +}
                +
                +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
                +	if ( postFilter && !postFilter[ expando ] ) {
                +		postFilter = setMatcher( postFilter );
                +	}
                +	if ( postFinder && !postFinder[ expando ] ) {
                +		postFinder = setMatcher( postFinder, postSelector );
                +	}
                +	return markFunction(function( seed, results, context, xml ) {
                +		var temp, i, elem,
                +			preMap = [],
                +			postMap = [],
                +			preexisting = results.length,
                +
                +			// Get initial elements from seed or context
                +			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
                +
                +			// Prefilter to get matcher input, preserving a map for seed-results synchronization
                +			matcherIn = preFilter && ( seed || !selector ) ?
                +				condense( elems, preMap, preFilter, context, xml ) :
                +				elems,
                +
                +			matcherOut = matcher ?
                +				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
                +				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
                +
                +					// ...intermediate processing is necessary
                +					[] :
                +
                +					// ...otherwise use results directly
                +					results :
                +				matcherIn;
                +
                +		// Find primary matches
                +		if ( matcher ) {
                +			matcher( matcherIn, matcherOut, context, xml );
                +		}
                +
                +		// Apply postFilter
                +		if ( postFilter ) {
                +			temp = condense( matcherOut, postMap );
                +			postFilter( temp, [], context, xml );
                +
                +			// Un-match failing elements by moving them back to matcherIn
                +			i = temp.length;
                +			while ( i-- ) {
                +				if ( (elem = temp[i]) ) {
                +					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
                +				}
                +			}
                +		}
                +
                +		if ( seed ) {
                +			if ( postFinder || preFilter ) {
                +				if ( postFinder ) {
                +					// Get the final matcherOut by condensing this intermediate into postFinder contexts
                +					temp = [];
                +					i = matcherOut.length;
                +					while ( i-- ) {
                +						if ( (elem = matcherOut[i]) ) {
                +							// Restore matcherIn since elem is not yet a final match
                +							temp.push( (matcherIn[i] = elem) );
                +						}
                +					}
                +					postFinder( null, (matcherOut = []), temp, xml );
                +				}
                +
                +				// Move matched elements from seed to results to keep them synchronized
                +				i = matcherOut.length;
                +				while ( i-- ) {
                +					if ( (elem = matcherOut[i]) &&
                +						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
                +
                +						seed[temp] = !(results[temp] = elem);
                +					}
                +				}
                +			}
                +
                +		// Add elements to results, through postFinder if defined
                +		} else {
                +			matcherOut = condense(
                +				matcherOut === results ?
                +					matcherOut.splice( preexisting, matcherOut.length ) :
                +					matcherOut
                +			);
                +			if ( postFinder ) {
                +				postFinder( null, results, matcherOut, xml );
                +			} else {
                +				push.apply( results, matcherOut );
                +			}
                +		}
                +	});
                +}
                +
                +function matcherFromTokens( tokens ) {
                +	var checkContext, matcher, j,
                +		len = tokens.length,
                +		leadingRelative = Expr.relative[ tokens[0].type ],
                +		implicitRelative = leadingRelative || Expr.relative[" "],
                +		i = leadingRelative ? 1 : 0,
                +
                +		// The foundational matcher ensures that elements are reachable from top-level context(s)
                +		matchContext = addCombinator( function( elem ) {
                +			return elem === checkContext;
                +		}, implicitRelative, true ),
                +		matchAnyContext = addCombinator( function( elem ) {
                +			return indexOf( checkContext, elem ) > -1;
                +		}, implicitRelative, true ),
                +		matchers = [ function( elem, context, xml ) {
                +			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
                +				(checkContext = context).nodeType ?
                +					matchContext( elem, context, xml ) :
                +					matchAnyContext( elem, context, xml ) );
                +			// Avoid hanging onto element (issue #299)
                +			checkContext = null;
                +			return ret;
                +		} ];
                +
                +	for ( ; i < len; i++ ) {
                +		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
                +			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
                +		} else {
                +			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
                +
                +			// Return special upon seeing a positional matcher
                +			if ( matcher[ expando ] ) {
                +				// Find the next relative operator (if any) for proper handling
                +				j = ++i;
                +				for ( ; j < len; j++ ) {
                +					if ( Expr.relative[ tokens[j].type ] ) {
                +						break;
                +					}
                +				}
                +				return setMatcher(
                +					i > 1 && elementMatcher( matchers ),
                +					i > 1 && toSelector(
                +						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
                +						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
                +					).replace( rtrim, "$1" ),
                +					matcher,
                +					i < j && matcherFromTokens( tokens.slice( i, j ) ),
                +					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
                +					j < len && toSelector( tokens )
                +				);
                +			}
                +			matchers.push( matcher );
                +		}
                +	}
                +
                +	return elementMatcher( matchers );
                +}
                +
                +function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
                +	var bySet = setMatchers.length > 0,
                +		byElement = elementMatchers.length > 0,
                +		superMatcher = function( seed, context, xml, results, outermost ) {
                +			var elem, j, matcher,
                +				matchedCount = 0,
                +				i = "0",
                +				unmatched = seed && [],
                +				setMatched = [],
                +				contextBackup = outermostContext,
                +				// We must always have either seed elements or outermost context
                +				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
                +				// Use integer dirruns iff this is the outermost matcher
                +				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
                +				len = elems.length;
                +
                +			if ( outermost ) {
                +				outermostContext = context === document || context || outermost;
                +			}
                +
                +			// Add elements passing elementMatchers directly to results
                +			// Support: IE<9, Safari
                +			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
                +			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
                +				if ( byElement && elem ) {
                +					j = 0;
                +					if ( !context && elem.ownerDocument !== document ) {
                +						setDocument( elem );
                +						xml = !documentIsHTML;
                +					}
                +					while ( (matcher = elementMatchers[j++]) ) {
                +						if ( matcher( elem, context || document, xml) ) {
                +							results.push( elem );
                +							break;
                +						}
                +					}
                +					if ( outermost ) {
                +						dirruns = dirrunsUnique;
                +					}
                +				}
                +
                +				// Track unmatched elements for set filters
                +				if ( bySet ) {
                +					// They will have gone through all possible matchers
                +					if ( (elem = !matcher && elem) ) {
                +						matchedCount--;
                +					}
                +
                +					// Lengthen the array for every element, matched or not
                +					if ( seed ) {
                +						unmatched.push( elem );
                +					}
                +				}
                +			}
                +
                +			// `i` is now the count of elements visited above, and adding it to `matchedCount`
                +			// makes the latter nonnegative.
                +			matchedCount += i;
                +
                +			// Apply set filters to unmatched elements
                +			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
                +			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
                +			// no element matchers and no seed.
                +			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
                +			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
                +			// numerically zero.
                +			if ( bySet && i !== matchedCount ) {
                +				j = 0;
                +				while ( (matcher = setMatchers[j++]) ) {
                +					matcher( unmatched, setMatched, context, xml );
                +				}
                +
                +				if ( seed ) {
                +					// Reintegrate element matches to eliminate the need for sorting
                +					if ( matchedCount > 0 ) {
                +						while ( i-- ) {
                +							if ( !(unmatched[i] || setMatched[i]) ) {
                +								setMatched[i] = pop.call( results );
                +							}
                +						}
                +					}
                +
                +					// Discard index placeholder values to get only actual matches
                +					setMatched = condense( setMatched );
                +				}
                +
                +				// Add matches to results
                +				push.apply( results, setMatched );
                +
                +				// Seedless set matches succeeding multiple successful matchers stipulate sorting
                +				if ( outermost && !seed && setMatched.length > 0 &&
                +					( matchedCount + setMatchers.length ) > 1 ) {
                +
                +					Sizzle.uniqueSort( results );
                +				}
                +			}
                +
                +			// Override manipulation of globals by nested matchers
                +			if ( outermost ) {
                +				dirruns = dirrunsUnique;
                +				outermostContext = contextBackup;
                +			}
                +
                +			return unmatched;
                +		};
                +
                +	return bySet ?
                +		markFunction( superMatcher ) :
                +		superMatcher;
                +}
                +
                +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
                +	var i,
                +		setMatchers = [],
                +		elementMatchers = [],
                +		cached = compilerCache[ selector + " " ];
                +
                +	if ( !cached ) {
                +		// Generate a function of recursive functions that can be used to check each element
                +		if ( !match ) {
                +			match = tokenize( selector );
                +		}
                +		i = match.length;
                +		while ( i-- ) {
                +			cached = matcherFromTokens( match[i] );
                +			if ( cached[ expando ] ) {
                +				setMatchers.push( cached );
                +			} else {
                +				elementMatchers.push( cached );
                +			}
                +		}
                +
                +		// Cache the compiled function
                +		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
                +
                +		// Save selector and tokenization
                +		cached.selector = selector;
                +	}
                +	return cached;
                +};
                +
                +/**
                + * A low-level selection function that works with Sizzle's compiled
                + *  selector functions
                + * @param {String|Function} selector A selector or a pre-compiled
                + *  selector function built with Sizzle.compile
                + * @param {Element} context
                + * @param {Array} [results]
                + * @param {Array} [seed] A set of elements to match against
                + */
                +select = Sizzle.select = function( selector, context, results, seed ) {
                +	var i, tokens, token, type, find,
                +		compiled = typeof selector === "function" && selector,
                +		match = !seed && tokenize( (selector = compiled.selector || selector) );
                +
                +	results = results || [];
                +
                +	// Try to minimize operations if there is only one selector in the list and no seed
                +	// (the latter of which guarantees us context)
                +	if ( match.length === 1 ) {
                +
                +		// Reduce context if the leading compound selector is an ID
                +		tokens = match[0] = match[0].slice( 0 );
                +		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
                +				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
                +
                +			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
                +			if ( !context ) {
                +				return results;
                +
                +			// Precompiled matchers will still verify ancestry, so step up a level
                +			} else if ( compiled ) {
                +				context = context.parentNode;
                +			}
                +
                +			selector = selector.slice( tokens.shift().value.length );
                +		}
                +
                +		// Fetch a seed set for right-to-left matching
                +		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
                +		while ( i-- ) {
                +			token = tokens[i];
                +
                +			// Abort if we hit a combinator
                +			if ( Expr.relative[ (type = token.type) ] ) {
                +				break;
                +			}
                +			if ( (find = Expr.find[ type ]) ) {
                +				// Search, expanding context for leading sibling combinators
                +				if ( (seed = find(
                +					token.matches[0].replace( runescape, funescape ),
                +					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
                +				)) ) {
                +
                +					// If seed is empty or no tokens remain, we can return early
                +					tokens.splice( i, 1 );
                +					selector = seed.length && toSelector( tokens );
                +					if ( !selector ) {
                +						push.apply( results, seed );
                +						return results;
                +					}
                +
                +					break;
                +				}
                +			}
                +		}
                +	}
                +
                +	// Compile and execute a filtering function if one is not provided
                +	// Provide `match` to avoid retokenization if we modified the selector above
                +	( compiled || compile( selector, match ) )(
                +		seed,
                +		context,
                +		!documentIsHTML,
                +		results,
                +		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
                +	);
                +	return results;
                +};
                +
                +// One-time assignments
                +
                +// Sort stability
                +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
                +
                +// Support: Chrome 14-35+
                +// Always assume duplicates if they aren't passed to the comparison function
                +support.detectDuplicates = !!hasDuplicate;
                +
                +// Initialize against the default document
                +setDocument();
                +
                +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
                +// Detached nodes confoundingly follow *each other*
                +support.sortDetached = assert(function( el ) {
                +	// Should return 1, but returns 4 (following)
                +	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
                +});
                +
                +// Support: IE<8
                +// Prevent attribute/property "interpolation"
                +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
                +if ( !assert(function( el ) {
                +	el.innerHTML = "<a href='#'></a>";
                +	return el.firstChild.getAttribute("href") === "#" ;
                +}) ) {
                +	addHandle( "type|href|height|width", function( elem, name, isXML ) {
                +		if ( !isXML ) {
                +			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
                +		}
                +	});
                +}
                +
                +// Support: IE<9
                +// Use defaultValue in place of getAttribute("value")
                +if ( !support.attributes || !assert(function( el ) {
                +	el.innerHTML = "<input/>";
                +	el.firstChild.setAttribute( "value", "" );
                +	return el.firstChild.getAttribute( "value" ) === "";
                +}) ) {
                +	addHandle( "value", function( elem, name, isXML ) {
                +		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
                +			return elem.defaultValue;
                +		}
                +	});
                +}
                +
                +// Support: IE<9
                +// Use getAttributeNode to fetch booleans when getAttribute lies
                +if ( !assert(function( el ) {
                +	return el.getAttribute("disabled") == null;
                +}) ) {
                +	addHandle( booleans, function( elem, name, isXML ) {
                +		var val;
                +		if ( !isXML ) {
                +			return elem[ name ] === true ? name.toLowerCase() :
                +					(val = elem.getAttributeNode( name )) && val.specified ?
                +					val.value :
                +				null;
                +		}
                +	});
                +}
                +
                +return Sizzle;
                +
                +})( window );
                +
                +
                +
                +jQuery.find = Sizzle;
                +jQuery.expr = Sizzle.selectors;
                +
                +// Deprecated
                +jQuery.expr[ ":" ] = jQuery.expr.pseudos;
                +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
                +jQuery.text = Sizzle.getText;
                +jQuery.isXMLDoc = Sizzle.isXML;
                +jQuery.contains = Sizzle.contains;
                +jQuery.escapeSelector = Sizzle.escape;
                +
                +
                +
                +
                +var dir = function( elem, dir, until ) {
                +	var matched = [],
                +		truncate = until !== undefined;
                +
                +	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
                +		if ( elem.nodeType === 1 ) {
                +			if ( truncate && jQuery( elem ).is( until ) ) {
                +				break;
                +			}
                +			matched.push( elem );
                +		}
                +	}
                +	return matched;
                +};
                +
                +
                +var siblings = function( n, elem ) {
                +	var matched = [];
                +
                +	for ( ; n; n = n.nextSibling ) {
                +		if ( n.nodeType === 1 && n !== elem ) {
                +			matched.push( n );
                +		}
                +	}
                +
                +	return matched;
                +};
                +
                +
                +var rneedsContext = jQuery.expr.match.needsContext;
                +
                +
                +
                +function nodeName( elem, name ) {
                +
                +  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
                +
                +};
                +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
                +
                +
                +
                +var risSimple = /^.[^:#\[\.,]*$/;
                +
                +// Implement the identical functionality for filter and not
                +function winnow( elements, qualifier, not ) {
                +	if ( jQuery.isFunction( qualifier ) ) {
                +		return jQuery.grep( elements, function( elem, i ) {
                +			return !!qualifier.call( elem, i, elem ) !== not;
                +		} );
                +	}
                +
                +	// Single element
                +	if ( qualifier.nodeType ) {
                +		return jQuery.grep( elements, function( elem ) {
                +			return ( elem === qualifier ) !== not;
                +		} );
                +	}
                +
                +	// Arraylike of elements (jQuery, arguments, Array)
                +	if ( typeof qualifier !== "string" ) {
                +		return jQuery.grep( elements, function( elem ) {
                +			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
                +		} );
                +	}
                +
                +	// Simple selector that can be filtered directly, removing non-Elements
                +	if ( risSimple.test( qualifier ) ) {
                +		return jQuery.filter( qualifier, elements, not );
                +	}
                +
                +	// Complex selector, compare the two sets, removing non-Elements
                +	qualifier = jQuery.filter( qualifier, elements );
                +	return jQuery.grep( elements, function( elem ) {
                +		return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
                +	} );
                +}
                +
                +jQuery.filter = function( expr, elems, not ) {
                +	var elem = elems[ 0 ];
                +
                +	if ( not ) {
                +		expr = ":not(" + expr + ")";
                +	}
                +
                +	if ( elems.length === 1 && elem.nodeType === 1 ) {
                +		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
                +	}
                +
                +	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
                +		return elem.nodeType === 1;
                +	} ) );
                +};
                +
                +jQuery.fn.extend( {
                +	find: function( selector ) {
                +		var i, ret,
                +			len = this.length,
                +			self = this;
                +
                +		if ( typeof selector !== "string" ) {
                +			return this.pushStack( jQuery( selector ).filter( function() {
                +				for ( i = 0; i < len; i++ ) {
                +					if ( jQuery.contains( self[ i ], this ) ) {
                +						return true;
                +					}
                +				}
                +			} ) );
                +		}
                +
                +		ret = this.pushStack( [] );
                +
                +		for ( i = 0; i < len; i++ ) {
                +			jQuery.find( selector, self[ i ], ret );
                +		}
                +
                +		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
                +	},
                +	filter: function( selector ) {
                +		return this.pushStack( winnow( this, selector || [], false ) );
                +	},
                +	not: function( selector ) {
                +		return this.pushStack( winnow( this, selector || [], true ) );
                +	},
                +	is: function( selector ) {
                +		return !!winnow(
                +			this,
                +
                +			// If this is a positional/relative selector, check membership in the returned set
                +			// so $("p:first").is("p:last") won't return true for a doc with two "p".
                +			typeof selector === "string" && rneedsContext.test( selector ) ?
                +				jQuery( selector ) :
                +				selector || [],
                +			false
                +		).length;
                +	}
                +} );
                +
                +
                +// Initialize a jQuery object
                +
                +
                +// A central reference to the root jQuery(document)
                +var rootjQuery,
                +
                +	// A simple way to check for HTML strings
                +	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
                +	// Strict HTML recognition (#11290: must start with <)
                +	// Shortcut simple #id case for speed
                +	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
                +
                +	init = jQuery.fn.init = function( selector, context, root ) {
                +		var match, elem;
                +
                +		// HANDLE: $(""), $(null), $(undefined), $(false)
                +		if ( !selector ) {
                +			return this;
                +		}
                +
                +		// Method init() accepts an alternate rootjQuery
                +		// so migrate can support jQuery.sub (gh-2101)
                +		root = root || rootjQuery;
                +
                +		// Handle HTML strings
                +		if ( typeof selector === "string" ) {
                +			if ( selector[ 0 ] === "<" &&
                +				selector[ selector.length - 1 ] === ">" &&
                +				selector.length >= 3 ) {
                +
                +				// Assume that strings that start and end with <> are HTML and skip the regex check
                +				match = [ null, selector, null ];
                +
                +			} else {
                +				match = rquickExpr.exec( selector );
                +			}
                +
                +			// Match html or make sure no context is specified for #id
                +			if ( match && ( match[ 1 ] || !context ) ) {
                +
                +				// HANDLE: $(html) -> $(array)
                +				if ( match[ 1 ] ) {
                +					context = context instanceof jQuery ? context[ 0 ] : context;
                +
                +					// Option to run scripts is true for back-compat
                +					// Intentionally let the error be thrown if parseHTML is not present
                +					jQuery.merge( this, jQuery.parseHTML(
                +						match[ 1 ],
                +						context && context.nodeType ? context.ownerDocument || context : document,
                +						true
                +					) );
                +
                +					// HANDLE: $(html, props)
                +					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
                +						for ( match in context ) {
                +
                +							// Properties of context are called as methods if possible
                +							if ( jQuery.isFunction( this[ match ] ) ) {
                +								this[ match ]( context[ match ] );
                +
                +							// ...and otherwise set as attributes
                +							} else {
                +								this.attr( match, context[ match ] );
                +							}
                +						}
                +					}
                +
                +					return this;
                +
                +				// HANDLE: $(#id)
                +				} else {
                +					elem = document.getElementById( match[ 2 ] );
                +
                +					if ( elem ) {
                +
                +						// Inject the element directly into the jQuery object
                +						this[ 0 ] = elem;
                +						this.length = 1;
                +					}
                +					return this;
                +				}
                +
                +			// HANDLE: $(expr, $(...))
                +			} else if ( !context || context.jquery ) {
                +				return ( context || root ).find( selector );
                +
                +			// HANDLE: $(expr, context)
                +			// (which is just equivalent to: $(context).find(expr)
                +			} else {
                +				return this.constructor( context ).find( selector );
                +			}
                +
                +		// HANDLE: $(DOMElement)
                +		} else if ( selector.nodeType ) {
                +			this[ 0 ] = selector;
                +			this.length = 1;
                +			return this;
                +
                +		// HANDLE: $(function)
                +		// Shortcut for document ready
                +		} else if ( jQuery.isFunction( selector ) ) {
                +			return root.ready !== undefined ?
                +				root.ready( selector ) :
                +
                +				// Execute immediately if ready is not present
                +				selector( jQuery );
                +		}
                +
                +		return jQuery.makeArray( selector, this );
                +	};
                +
                +// Give the init function the jQuery prototype for later instantiation
                +init.prototype = jQuery.fn;
                +
                +// Initialize central reference
                +rootjQuery = jQuery( document );
                +
                +
                +var rparentsprev = /^(?:parents|prev(?:Until|All))/,
                +
                +	// Methods guaranteed to produce a unique set when starting from a unique set
                +	guaranteedUnique = {
                +		children: true,
                +		contents: true,
                +		next: true,
                +		prev: true
                +	};
                +
                +jQuery.fn.extend( {
                +	has: function( target ) {
                +		var targets = jQuery( target, this ),
                +			l = targets.length;
                +
                +		return this.filter( function() {
                +			var i = 0;
                +			for ( ; i < l; i++ ) {
                +				if ( jQuery.contains( this, targets[ i ] ) ) {
                +					return true;
                +				}
                +			}
                +		} );
                +	},
                +
                +	closest: function( selectors, context ) {
                +		var cur,
                +			i = 0,
                +			l = this.length,
                +			matched = [],
                +			targets = typeof selectors !== "string" && jQuery( selectors );
                +
                +		// Positional selectors never match, since there's no _selection_ context
                +		if ( !rneedsContext.test( selectors ) ) {
                +			for ( ; i < l; i++ ) {
                +				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
                +
                +					// Always skip document fragments
                +					if ( cur.nodeType < 11 && ( targets ?
                +						targets.index( cur ) > -1 :
                +
                +						// Don't pass non-elements to Sizzle
                +						cur.nodeType === 1 &&
                +							jQuery.find.matchesSelector( cur, selectors ) ) ) {
                +
                +						matched.push( cur );
                +						break;
                +					}
                +				}
                +			}
                +		}
                +
                +		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
                +	},
                +
                +	// Determine the position of an element within the set
                +	index: function( elem ) {
                +
                +		// No argument, return index in parent
                +		if ( !elem ) {
                +			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
                +		}
                +
                +		// Index in selector
                +		if ( typeof elem === "string" ) {
                +			return indexOf.call( jQuery( elem ), this[ 0 ] );
                +		}
                +
                +		// Locate the position of the desired element
                +		return indexOf.call( this,
                +
                +			// If it receives a jQuery object, the first element is used
                +			elem.jquery ? elem[ 0 ] : elem
                +		);
                +	},
                +
                +	add: function( selector, context ) {
                +		return this.pushStack(
                +			jQuery.uniqueSort(
                +				jQuery.merge( this.get(), jQuery( selector, context ) )
                +			)
                +		);
                +	},
                +
                +	addBack: function( selector ) {
                +		return this.add( selector == null ?
                +			this.prevObject : this.prevObject.filter( selector )
                +		);
                +	}
                +} );
                +
                +function sibling( cur, dir ) {
                +	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
                +	return cur;
                +}
                +
                +jQuery.each( {
                +	parent: function( elem ) {
                +		var parent = elem.parentNode;
                +		return parent && parent.nodeType !== 11 ? parent : null;
                +	},
                +	parents: function( elem ) {
                +		return dir( elem, "parentNode" );
                +	},
                +	parentsUntil: function( elem, i, until ) {
                +		return dir( elem, "parentNode", until );
                +	},
                +	next: function( elem ) {
                +		return sibling( elem, "nextSibling" );
                +	},
                +	prev: function( elem ) {
                +		return sibling( elem, "previousSibling" );
                +	},
                +	nextAll: function( elem ) {
                +		return dir( elem, "nextSibling" );
                +	},
                +	prevAll: function( elem ) {
                +		return dir( elem, "previousSibling" );
                +	},
                +	nextUntil: function( elem, i, until ) {
                +		return dir( elem, "nextSibling", until );
                +	},
                +	prevUntil: function( elem, i, until ) {
                +		return dir( elem, "previousSibling", until );
                +	},
                +	siblings: function( elem ) {
                +		return siblings( ( elem.parentNode || {} ).firstChild, elem );
                +	},
                +	children: function( elem ) {
                +		return siblings( elem.firstChild );
                +	},
                +	contents: function( elem ) {
                +        if ( nodeName( elem, "iframe" ) ) {
                +            return elem.contentDocument;
                +        }
                +
                +        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
                +        // Treat the template element as a regular one in browsers that
                +        // don't support it.
                +        if ( nodeName( elem, "template" ) ) {
                +            elem = elem.content || elem;
                +        }
                +
                +        return jQuery.merge( [], elem.childNodes );
                +	}
                +}, function( name, fn ) {
                +	jQuery.fn[ name ] = function( until, selector ) {
                +		var matched = jQuery.map( this, fn, until );
                +
                +		if ( name.slice( -5 ) !== "Until" ) {
                +			selector = until;
                +		}
                +
                +		if ( selector && typeof selector === "string" ) {
                +			matched = jQuery.filter( selector, matched );
                +		}
                +
                +		if ( this.length > 1 ) {
                +
                +			// Remove duplicates
                +			if ( !guaranteedUnique[ name ] ) {
                +				jQuery.uniqueSort( matched );
                +			}
                +
                +			// Reverse order for parents* and prev-derivatives
                +			if ( rparentsprev.test( name ) ) {
                +				matched.reverse();
                +			}
                +		}
                +
                +		return this.pushStack( matched );
                +	};
                +} );
                +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
                +
                +
                +
                +// Convert String-formatted options into Object-formatted ones
                +function createOptions( options ) {
                +	var object = {};
                +	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
                +		object[ flag ] = true;
                +	} );
                +	return object;
                +}
                +
                +/*
                + * Create a callback list using the following parameters:
                + *
                + *	options: an optional list of space-separated options that will change how
                + *			the callback list behaves or a more traditional option object
                + *
                + * By default a callback list will act like an event callback list and can be
                + * "fired" multiple times.
                + *
                + * Possible options:
                + *
                + *	once:			will ensure the callback list can only be fired once (like a Deferred)
                + *
                + *	memory:			will keep track of previous values and will call any callback added
                + *					after the list has been fired right away with the latest "memorized"
                + *					values (like a Deferred)
                + *
                + *	unique:			will ensure a callback can only be added once (no duplicate in the list)
                + *
                + *	stopOnFalse:	interrupt callings when a callback returns false
                + *
                + */
                +jQuery.Callbacks = function( options ) {
                +
                +	// Convert options from String-formatted to Object-formatted if needed
                +	// (we check in cache first)
                +	options = typeof options === "string" ?
                +		createOptions( options ) :
                +		jQuery.extend( {}, options );
                +
                +	var // Flag to know if list is currently firing
                +		firing,
                +
                +		// Last fire value for non-forgettable lists
                +		memory,
                +
                +		// Flag to know if list was already fired
                +		fired,
                +
                +		// Flag to prevent firing
                +		locked,
                +
                +		// Actual callback list
                +		list = [],
                +
                +		// Queue of execution data for repeatable lists
                +		queue = [],
                +
                +		// Index of currently firing callback (modified by add/remove as needed)
                +		firingIndex = -1,
                +
                +		// Fire callbacks
                +		fire = function() {
                +
                +			// Enforce single-firing
                +			locked = locked || options.once;
                +
                +			// Execute callbacks for all pending executions,
                +			// respecting firingIndex overrides and runtime changes
                +			fired = firing = true;
                +			for ( ; queue.length; firingIndex = -1 ) {
                +				memory = queue.shift();
                +				while ( ++firingIndex < list.length ) {
                +
                +					// Run callback and check for early termination
                +					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
                +						options.stopOnFalse ) {
                +
                +						// Jump to end and forget the data so .add doesn't re-fire
                +						firingIndex = list.length;
                +						memory = false;
                +					}
                +				}
                +			}
                +
                +			// Forget the data if we're done with it
                +			if ( !options.memory ) {
                +				memory = false;
                +			}
                +
                +			firing = false;
                +
                +			// Clean up if we're done firing for good
                +			if ( locked ) {
                +
                +				// Keep an empty list if we have data for future add calls
                +				if ( memory ) {
                +					list = [];
                +
                +				// Otherwise, this object is spent
                +				} else {
                +					list = "";
                +				}
                +			}
                +		},
                +
                +		// Actual Callbacks object
                +		self = {
                +
                +			// Add a callback or a collection of callbacks to the list
                +			add: function() {
                +				if ( list ) {
                +
                +					// If we have memory from a past run, we should fire after adding
                +					if ( memory && !firing ) {
                +						firingIndex = list.length - 1;
                +						queue.push( memory );
                +					}
                +
                +					( function add( args ) {
                +						jQuery.each( args, function( _, arg ) {
                +							if ( jQuery.isFunction( arg ) ) {
                +								if ( !options.unique || !self.has( arg ) ) {
                +									list.push( arg );
                +								}
                +							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
                +
                +								// Inspect recursively
                +								add( arg );
                +							}
                +						} );
                +					} )( arguments );
                +
                +					if ( memory && !firing ) {
                +						fire();
                +					}
                +				}
                +				return this;
                +			},
                +
                +			// Remove a callback from the list
                +			remove: function() {
                +				jQuery.each( arguments, function( _, arg ) {
                +					var index;
                +					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                +						list.splice( index, 1 );
                +
                +						// Handle firing indexes
                +						if ( index <= firingIndex ) {
                +							firingIndex--;
                +						}
                +					}
                +				} );
                +				return this;
                +			},
                +
                +			// Check if a given callback is in the list.
                +			// If no argument is given, return whether or not list has callbacks attached.
                +			has: function( fn ) {
                +				return fn ?
                +					jQuery.inArray( fn, list ) > -1 :
                +					list.length > 0;
                +			},
                +
                +			// Remove all callbacks from the list
                +			empty: function() {
                +				if ( list ) {
                +					list = [];
                +				}
                +				return this;
                +			},
                +
                +			// Disable .fire and .add
                +			// Abort any current/pending executions
                +			// Clear all callbacks and values
                +			disable: function() {
                +				locked = queue = [];
                +				list = memory = "";
                +				return this;
                +			},
                +			disabled: function() {
                +				return !list;
                +			},
                +
                +			// Disable .fire
                +			// Also disable .add unless we have memory (since it would have no effect)
                +			// Abort any pending executions
                +			lock: function() {
                +				locked = queue = [];
                +				if ( !memory && !firing ) {
                +					list = memory = "";
                +				}
                +				return this;
                +			},
                +			locked: function() {
                +				return !!locked;
                +			},
                +
                +			// Call all callbacks with the given context and arguments
                +			fireWith: function( context, args ) {
                +				if ( !locked ) {
                +					args = args || [];
                +					args = [ context, args.slice ? args.slice() : args ];
                +					queue.push( args );
                +					if ( !firing ) {
                +						fire();
                +					}
                +				}
                +				return this;
                +			},
                +
                +			// Call all the callbacks with the given arguments
                +			fire: function() {
                +				self.fireWith( this, arguments );
                +				return this;
                +			},
                +
                +			// To know if the callbacks have already been called at least once
                +			fired: function() {
                +				return !!fired;
                +			}
                +		};
                +
                +	return self;
                +};
                +
                +
                +function Identity( v ) {
                +	return v;
                +}
                +function Thrower( ex ) {
                +	throw ex;
                +}
                +
                +function adoptValue( value, resolve, reject, noValue ) {
                +	var method;
                +
                +	try {
                +
                +		// Check for promise aspect first to privilege synchronous behavior
                +		if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
                +			method.call( value ).done( resolve ).fail( reject );
                +
                +		// Other thenables
                +		} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
                +			method.call( value, resolve, reject );
                +
                +		// Other non-thenables
                +		} else {
                +
                +			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
                +			// * false: [ value ].slice( 0 ) => resolve( value )
                +			// * true: [ value ].slice( 1 ) => resolve()
                +			resolve.apply( undefined, [ value ].slice( noValue ) );
                +		}
                +
                +	// For Promises/A+, convert exceptions into rejections
                +	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
                +	// Deferred#then to conditionally suppress rejection.
                +	} catch ( value ) {
                +
                +		// Support: Android 4.0 only
                +		// Strict mode functions invoked without .call/.apply get global-object context
                +		reject.apply( undefined, [ value ] );
                +	}
                +}
                +
                +jQuery.extend( {
                +
                +	Deferred: function( func ) {
                +		var tuples = [
                +
                +				// action, add listener, callbacks,
                +				// ... .then handlers, argument index, [final state]
                +				[ "notify", "progress", jQuery.Callbacks( "memory" ),
                +					jQuery.Callbacks( "memory" ), 2 ],
                +				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
                +					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
                +				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
                +					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
                +			],
                +			state = "pending",
                +			promise = {
                +				state: function() {
                +					return state;
                +				},
                +				always: function() {
                +					deferred.done( arguments ).fail( arguments );
                +					return this;
                +				},
                +				"catch": function( fn ) {
                +					return promise.then( null, fn );
                +				},
                +
                +				// Keep pipe for back-compat
                +				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
                +					var fns = arguments;
                +
                +					return jQuery.Deferred( function( newDefer ) {
                +						jQuery.each( tuples, function( i, tuple ) {
                +
                +							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
                +							var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
                +
                +							// deferred.progress(function() { bind to newDefer or newDefer.notify })
                +							// deferred.done(function() { bind to newDefer or newDefer.resolve })
                +							// deferred.fail(function() { bind to newDefer or newDefer.reject })
                +							deferred[ tuple[ 1 ] ]( function() {
                +								var returned = fn && fn.apply( this, arguments );
                +								if ( returned && jQuery.isFunction( returned.promise ) ) {
                +									returned.promise()
                +										.progress( newDefer.notify )
                +										.done( newDefer.resolve )
                +										.fail( newDefer.reject );
                +								} else {
                +									newDefer[ tuple[ 0 ] + "With" ](
                +										this,
                +										fn ? [ returned ] : arguments
                +									);
                +								}
                +							} );
                +						} );
                +						fns = null;
                +					} ).promise();
                +				},
                +				then: function( onFulfilled, onRejected, onProgress ) {
                +					var maxDepth = 0;
                +					function resolve( depth, deferred, handler, special ) {
                +						return function() {
                +							var that = this,
                +								args = arguments,
                +								mightThrow = function() {
                +									var returned, then;
                +
                +									// Support: Promises/A+ section 2.3.3.3.3
                +									// https://promisesaplus.com/#point-59
                +									// Ignore double-resolution attempts
                +									if ( depth < maxDepth ) {
                +										return;
                +									}
                +
                +									returned = handler.apply( that, args );
                +
                +									// Support: Promises/A+ section 2.3.1
                +									// https://promisesaplus.com/#point-48
                +									if ( returned === deferred.promise() ) {
                +										throw new TypeError( "Thenable self-resolution" );
                +									}
                +
                +									// Support: Promises/A+ sections 2.3.3.1, 3.5
                +									// https://promisesaplus.com/#point-54
                +									// https://promisesaplus.com/#point-75
                +									// Retrieve `then` only once
                +									then = returned &&
                +
                +										// Support: Promises/A+ section 2.3.4
                +										// https://promisesaplus.com/#point-64
                +										// Only check objects and functions for thenability
                +										( typeof returned === "object" ||
                +											typeof returned === "function" ) &&
                +										returned.then;
                +
                +									// Handle a returned thenable
                +									if ( jQuery.isFunction( then ) ) {
                +
                +										// Special processors (notify) just wait for resolution
                +										if ( special ) {
                +											then.call(
                +												returned,
                +												resolve( maxDepth, deferred, Identity, special ),
                +												resolve( maxDepth, deferred, Thrower, special )
                +											);
                +
                +										// Normal processors (resolve) also hook into progress
                +										} else {
                +
                +											// ...and disregard older resolution values
                +											maxDepth++;
                +
                +											then.call(
                +												returned,
                +												resolve( maxDepth, deferred, Identity, special ),
                +												resolve( maxDepth, deferred, Thrower, special ),
                +												resolve( maxDepth, deferred, Identity,
                +													deferred.notifyWith )
                +											);
                +										}
                +
                +									// Handle all other returned values
                +									} else {
                +
                +										// Only substitute handlers pass on context
                +										// and multiple values (non-spec behavior)
                +										if ( handler !== Identity ) {
                +											that = undefined;
                +											args = [ returned ];
                +										}
                +
                +										// Process the value(s)
                +										// Default process is resolve
                +										( special || deferred.resolveWith )( that, args );
                +									}
                +								},
                +
                +								// Only normal processors (resolve) catch and reject exceptions
                +								process = special ?
                +									mightThrow :
                +									function() {
                +										try {
                +											mightThrow();
                +										} catch ( e ) {
                +
                +											if ( jQuery.Deferred.exceptionHook ) {
                +												jQuery.Deferred.exceptionHook( e,
                +													process.stackTrace );
                +											}
                +
                +											// Support: Promises/A+ section 2.3.3.3.4.1
                +											// https://promisesaplus.com/#point-61
                +											// Ignore post-resolution exceptions
                +											if ( depth + 1 >= maxDepth ) {
                +
                +												// Only substitute handlers pass on context
                +												// and multiple values (non-spec behavior)
                +												if ( handler !== Thrower ) {
                +													that = undefined;
                +													args = [ e ];
                +												}
                +
                +												deferred.rejectWith( that, args );
                +											}
                +										}
                +									};
                +
                +							// Support: Promises/A+ section 2.3.3.3.1
                +							// https://promisesaplus.com/#point-57
                +							// Re-resolve promises immediately to dodge false rejection from
                +							// subsequent errors
                +							if ( depth ) {
                +								process();
                +							} else {
                +
                +								// Call an optional hook to record the stack, in case of exception
                +								// since it's otherwise lost when execution goes async
                +								if ( jQuery.Deferred.getStackHook ) {
                +									process.stackTrace = jQuery.Deferred.getStackHook();
                +								}
                +								window.setTimeout( process );
                +							}
                +						};
                +					}
                +
                +					return jQuery.Deferred( function( newDefer ) {
                +
                +						// progress_handlers.add( ... )
                +						tuples[ 0 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onProgress ) ?
                +									onProgress :
                +									Identity,
                +								newDefer.notifyWith
                +							)
                +						);
                +
                +						// fulfilled_handlers.add( ... )
                +						tuples[ 1 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onFulfilled ) ?
                +									onFulfilled :
                +									Identity
                +							)
                +						);
                +
                +						// rejected_handlers.add( ... )
                +						tuples[ 2 ][ 3 ].add(
                +							resolve(
                +								0,
                +								newDefer,
                +								jQuery.isFunction( onRejected ) ?
                +									onRejected :
                +									Thrower
                +							)
                +						);
                +					} ).promise();
                +				},
                +
                +				// Get a promise for this deferred
                +				// If obj is provided, the promise aspect is added to the object
                +				promise: function( obj ) {
                +					return obj != null ? jQuery.extend( obj, promise ) : promise;
                +				}
                +			},
                +			deferred = {};
                +
                +		// Add list-specific methods
                +		jQuery.each( tuples, function( i, tuple ) {
                +			var list = tuple[ 2 ],
                +				stateString = tuple[ 5 ];
                +
                +			// promise.progress = list.add
                +			// promise.done = list.add
                +			// promise.fail = list.add
                +			promise[ tuple[ 1 ] ] = list.add;
                +
                +			// Handle state
                +			if ( stateString ) {
                +				list.add(
                +					function() {
                +
                +						// state = "resolved" (i.e., fulfilled)
                +						// state = "rejected"
                +						state = stateString;
                +					},
                +
                +					// rejected_callbacks.disable
                +					// fulfilled_callbacks.disable
                +					tuples[ 3 - i ][ 2 ].disable,
                +
                +					// progress_callbacks.lock
                +					tuples[ 0 ][ 2 ].lock
                +				);
                +			}
                +
                +			// progress_handlers.fire
                +			// fulfilled_handlers.fire
                +			// rejected_handlers.fire
                +			list.add( tuple[ 3 ].fire );
                +
                +			// deferred.notify = function() { deferred.notifyWith(...) }
                +			// deferred.resolve = function() { deferred.resolveWith(...) }
                +			// deferred.reject = function() { deferred.rejectWith(...) }
                +			deferred[ tuple[ 0 ] ] = function() {
                +				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
                +				return this;
                +			};
                +
                +			// deferred.notifyWith = list.fireWith
                +			// deferred.resolveWith = list.fireWith
                +			// deferred.rejectWith = list.fireWith
                +			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
                +		} );
                +
                +		// Make the deferred a promise
                +		promise.promise( deferred );
                +
                +		// Call given func if any
                +		if ( func ) {
                +			func.call( deferred, deferred );
                +		}
                +
                +		// All done!
                +		return deferred;
                +	},
                +
                +	// Deferred helper
                +	when: function( singleValue ) {
                +		var
                +
                +			// count of uncompleted subordinates
                +			remaining = arguments.length,
                +
                +			// count of unprocessed arguments
                +			i = remaining,
                +
                +			// subordinate fulfillment data
                +			resolveContexts = Array( i ),
                +			resolveValues = slice.call( arguments ),
                +
                +			// the master Deferred
                +			master = jQuery.Deferred(),
                +
                +			// subordinate callback factory
                +			updateFunc = function( i ) {
                +				return function( value ) {
                +					resolveContexts[ i ] = this;
                +					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
                +					if ( !( --remaining ) ) {
                +						master.resolveWith( resolveContexts, resolveValues );
                +					}
                +				};
                +			};
                +
                +		// Single- and empty arguments are adopted like Promise.resolve
                +		if ( remaining <= 1 ) {
                +			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
                +				!remaining );
                +
                +			// Use .then() to unwrap secondary thenables (cf. gh-3000)
                +			if ( master.state() === "pending" ||
                +				jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
                +
                +				return master.then();
                +			}
                +		}
                +
                +		// Multiple arguments are aggregated like Promise.all array elements
                +		while ( i-- ) {
                +			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
                +		}
                +
                +		return master.promise();
                +	}
                +} );
                +
                +
                +// These usually indicate a programmer mistake during development,
                +// warn about them ASAP rather than swallowing them by default.
                +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
                +
                +jQuery.Deferred.exceptionHook = function( error, stack ) {
                +
                +	// Support: IE 8 - 9 only
                +	// Console exists when dev tools are open, which can happen at any time
                +	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
                +		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
                +	}
                +};
                +
                +
                +
                +
                +jQuery.readyException = function( error ) {
                +	window.setTimeout( function() {
                +		throw error;
                +	} );
                +};
                +
                +
                +
                +
                +// The deferred used on DOM ready
                +var readyList = jQuery.Deferred();
                +
                +jQuery.fn.ready = function( fn ) {
                +
                +	readyList
                +		.then( fn )
                +
                +		// Wrap jQuery.readyException in a function so that the lookup
                +		// happens at the time of error handling instead of callback
                +		// registration.
                +		.catch( function( error ) {
                +			jQuery.readyException( error );
                +		} );
                +
                +	return this;
                +};
                +
                +jQuery.extend( {
                +
                +	// Is the DOM ready to be used? Set to true once it occurs.
                +	isReady: false,
                +
                +	// A counter to track how many items to wait for before
                +	// the ready event fires. See #6781
                +	readyWait: 1,
                +
                +	// Handle when the DOM is ready
                +	ready: function( wait ) {
                +
                +		// Abort if there are pending holds or we're already ready
                +		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
                +			return;
                +		}
                +
                +		// Remember that the DOM is ready
                +		jQuery.isReady = true;
                +
                +		// If a normal DOM Ready event fired, decrement, and wait if need be
                +		if ( wait !== true && --jQuery.readyWait > 0 ) {
                +			return;
                +		}
                +
                +		// If there are functions bound, to execute
                +		readyList.resolveWith( document, [ jQuery ] );
                +	}
                +} );
                +
                +jQuery.ready.then = readyList.then;
                +
                +// The ready event handler and self cleanup method
                +function completed() {
                +	document.removeEventListener( "DOMContentLoaded", completed );
                +	window.removeEventListener( "load", completed );
                +	jQuery.ready();
                +}
                +
                +// Catch cases where $(document).ready() is called
                +// after the browser event has already occurred.
                +// Support: IE <=9 - 10 only
                +// Older IE sometimes signals "interactive" too soon
                +if ( document.readyState === "complete" ||
                +	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
                +
                +	// Handle it asynchronously to allow scripts the opportunity to delay ready
                +	window.setTimeout( jQuery.ready );
                +
                +} else {
                +
                +	// Use the handy event callback
                +	document.addEventListener( "DOMContentLoaded", completed );
                +
                +	// A fallback to window.onload, that will always work
                +	window.addEventListener( "load", completed );
                +}
                +
                +
                +
                +
                +// Multifunctional method to get and set values of a collection
                +// The value/s can optionally be executed if it's a function
                +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
                +	var i = 0,
                +		len = elems.length,
                +		bulk = key == null;
                +
                +	// Sets many values
                +	if ( jQuery.type( key ) === "object" ) {
                +		chainable = true;
                +		for ( i in key ) {
                +			access( elems, fn, i, key[ i ], true, emptyGet, raw );
                +		}
                +
                +	// Sets one value
                +	} else if ( value !== undefined ) {
                +		chainable = true;
                +
                +		if ( !jQuery.isFunction( value ) ) {
                +			raw = true;
                +		}
                +
                +		if ( bulk ) {
                +
                +			// Bulk operations run against the entire set
                +			if ( raw ) {
                +				fn.call( elems, value );
                +				fn = null;
                +
                +			// ...except when executing function values
                +			} else {
                +				bulk = fn;
                +				fn = function( elem, key, value ) {
                +					return bulk.call( jQuery( elem ), value );
                +				};
                +			}
                +		}
                +
                +		if ( fn ) {
                +			for ( ; i < len; i++ ) {
                +				fn(
                +					elems[ i ], key, raw ?
                +					value :
                +					value.call( elems[ i ], i, fn( elems[ i ], key ) )
                +				);
                +			}
                +		}
                +	}
                +
                +	if ( chainable ) {
                +		return elems;
                +	}
                +
                +	// Gets
                +	if ( bulk ) {
                +		return fn.call( elems );
                +	}
                +
                +	return len ? fn( elems[ 0 ], key ) : emptyGet;
                +};
                +var acceptData = function( owner ) {
                +
                +	// Accepts only:
                +	//  - Node
                +	//    - Node.ELEMENT_NODE
                +	//    - Node.DOCUMENT_NODE
                +	//  - Object
                +	//    - Any
                +	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
                +};
                +
                +
                +
                +
                +function Data() {
                +	this.expando = jQuery.expando + Data.uid++;
                +}
                +
                +Data.uid = 1;
                +
                +Data.prototype = {
                +
                +	cache: function( owner ) {
                +
                +		// Check if the owner object already has a cache
                +		var value = owner[ this.expando ];
                +
                +		// If not, create one
                +		if ( !value ) {
                +			value = {};
                +
                +			// We can accept data for non-element nodes in modern browsers,
                +			// but we should not, see #8335.
                +			// Always return an empty object.
                +			if ( acceptData( owner ) ) {
                +
                +				// If it is a node unlikely to be stringify-ed or looped over
                +				// use plain assignment
                +				if ( owner.nodeType ) {
                +					owner[ this.expando ] = value;
                +
                +				// Otherwise secure it in a non-enumerable property
                +				// configurable must be true to allow the property to be
                +				// deleted when data is removed
                +				} else {
                +					Object.defineProperty( owner, this.expando, {
                +						value: value,
                +						configurable: true
                +					} );
                +				}
                +			}
                +		}
                +
                +		return value;
                +	},
                +	set: function( owner, data, value ) {
                +		var prop,
                +			cache = this.cache( owner );
                +
                +		// Handle: [ owner, key, value ] args
                +		// Always use camelCase key (gh-2257)
                +		if ( typeof data === "string" ) {
                +			cache[ jQuery.camelCase( data ) ] = value;
                +
                +		// Handle: [ owner, { properties } ] args
                +		} else {
                +
                +			// Copy the properties one-by-one to the cache object
                +			for ( prop in data ) {
                +				cache[ jQuery.camelCase( prop ) ] = data[ prop ];
                +			}
                +		}
                +		return cache;
                +	},
                +	get: function( owner, key ) {
                +		return key === undefined ?
                +			this.cache( owner ) :
                +
                +			// Always use camelCase key (gh-2257)
                +			owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
                +	},
                +	access: function( owner, key, value ) {
                +
                +		// In cases where either:
                +		//
                +		//   1. No key was specified
                +		//   2. A string key was specified, but no value provided
                +		//
                +		// Take the "read" path and allow the get method to determine
                +		// which value to return, respectively either:
                +		//
                +		//   1. The entire cache object
                +		//   2. The data stored at the key
                +		//
                +		if ( key === undefined ||
                +				( ( key && typeof key === "string" ) && value === undefined ) ) {
                +
                +			return this.get( owner, key );
                +		}
                +
                +		// When the key is not a string, or both a key and value
                +		// are specified, set or extend (existing objects) with either:
                +		//
                +		//   1. An object of properties
                +		//   2. A key and value
                +		//
                +		this.set( owner, key, value );
                +
                +		// Since the "set" path can have two possible entry points
                +		// return the expected data based on which path was taken[*]
                +		return value !== undefined ? value : key;
                +	},
                +	remove: function( owner, key ) {
                +		var i,
                +			cache = owner[ this.expando ];
                +
                +		if ( cache === undefined ) {
                +			return;
                +		}
                +
                +		if ( key !== undefined ) {
                +
                +			// Support array or space separated string of keys
                +			if ( Array.isArray( key ) ) {
                +
                +				// If key is an array of keys...
                +				// We always set camelCase keys, so remove that.
                +				key = key.map( jQuery.camelCase );
                +			} else {
                +				key = jQuery.camelCase( key );
                +
                +				// If a key with the spaces exists, use it.
                +				// Otherwise, create an array by matching non-whitespace
                +				key = key in cache ?
                +					[ key ] :
                +					( key.match( rnothtmlwhite ) || [] );
                +			}
                +
                +			i = key.length;
                +
                +			while ( i-- ) {
                +				delete cache[ key[ i ] ];
                +			}
                +		}
                +
                +		// Remove the expando if there's no more data
                +		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
                +
                +			// Support: Chrome <=35 - 45
                +			// Webkit & Blink performance suffers when deleting properties
                +			// from DOM nodes, so set to undefined instead
                +			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
                +			if ( owner.nodeType ) {
                +				owner[ this.expando ] = undefined;
                +			} else {
                +				delete owner[ this.expando ];
                +			}
                +		}
                +	},
                +	hasData: function( owner ) {
                +		var cache = owner[ this.expando ];
                +		return cache !== undefined && !jQuery.isEmptyObject( cache );
                +	}
                +};
                +var dataPriv = new Data();
                +
                +var dataUser = new Data();
                +
                +
                +
                +//	Implementation Summary
                +//
                +//	1. Enforce API surface and semantic compatibility with 1.9.x branch
                +//	2. Improve the module's maintainability by reducing the storage
                +//		paths to a single mechanism.
                +//	3. Use the same single mechanism to support "private" and "user" data.
                +//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
                +//	5. Avoid exposing implementation details on user objects (eg. expando properties)
                +//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
                +
                +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
                +	rmultiDash = /[A-Z]/g;
                +
                +function getData( data ) {
                +	if ( data === "true" ) {
                +		return true;
                +	}
                +
                +	if ( data === "false" ) {
                +		return false;
                +	}
                +
                +	if ( data === "null" ) {
                +		return null;
                +	}
                +
                +	// Only convert to a number if it doesn't change the string
                +	if ( data === +data + "" ) {
                +		return +data;
                +	}
                +
                +	if ( rbrace.test( data ) ) {
                +		return JSON.parse( data );
                +	}
                +
                +	return data;
                +}
                +
                +function dataAttr( elem, key, data ) {
                +	var name;
                +
                +	// If nothing was found internally, try to fetch any
                +	// data from the HTML5 data-* attribute
                +	if ( data === undefined && elem.nodeType === 1 ) {
                +		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
                +		data = elem.getAttribute( name );
                +
                +		if ( typeof data === "string" ) {
                +			try {
                +				data = getData( data );
                +			} catch ( e ) {}
                +
                +			// Make sure we set the data so it isn't changed later
                +			dataUser.set( elem, key, data );
                +		} else {
                +			data = undefined;
                +		}
                +	}
                +	return data;
                +}
                +
                +jQuery.extend( {
                +	hasData: function( elem ) {
                +		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
                +	},
                +
                +	data: function( elem, name, data ) {
                +		return dataUser.access( elem, name, data );
                +	},
                +
                +	removeData: function( elem, name ) {
                +		dataUser.remove( elem, name );
                +	},
                +
                +	// TODO: Now that all calls to _data and _removeData have been replaced
                +	// with direct calls to dataPriv methods, these can be deprecated.
                +	_data: function( elem, name, data ) {
                +		return dataPriv.access( elem, name, data );
                +	},
                +
                +	_removeData: function( elem, name ) {
                +		dataPriv.remove( elem, name );
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	data: function( key, value ) {
                +		var i, name, data,
                +			elem = this[ 0 ],
                +			attrs = elem && elem.attributes;
                +
                +		// Gets all values
                +		if ( key === undefined ) {
                +			if ( this.length ) {
                +				data = dataUser.get( elem );
                +
                +				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
                +					i = attrs.length;
                +					while ( i-- ) {
                +
                +						// Support: IE 11 only
                +						// The attrs elements can be null (#14894)
                +						if ( attrs[ i ] ) {
                +							name = attrs[ i ].name;
                +							if ( name.indexOf( "data-" ) === 0 ) {
                +								name = jQuery.camelCase( name.slice( 5 ) );
                +								dataAttr( elem, name, data[ name ] );
                +							}
                +						}
                +					}
                +					dataPriv.set( elem, "hasDataAttrs", true );
                +				}
                +			}
                +
                +			return data;
                +		}
                +
                +		// Sets multiple values
                +		if ( typeof key === "object" ) {
                +			return this.each( function() {
                +				dataUser.set( this, key );
                +			} );
                +		}
                +
                +		return access( this, function( value ) {
                +			var data;
                +
                +			// The calling jQuery object (element matches) is not empty
                +			// (and therefore has an element appears at this[ 0 ]) and the
                +			// `value` parameter was not undefined. An empty jQuery object
                +			// will result in `undefined` for elem = this[ 0 ] which will
                +			// throw an exception if an attempt to read a data cache is made.
                +			if ( elem && value === undefined ) {
                +
                +				// Attempt to get data from the cache
                +				// The key will always be camelCased in Data
                +				data = dataUser.get( elem, key );
                +				if ( data !== undefined ) {
                +					return data;
                +				}
                +
                +				// Attempt to "discover" the data in
                +				// HTML5 custom data-* attrs
                +				data = dataAttr( elem, key );
                +				if ( data !== undefined ) {
                +					return data;
                +				}
                +
                +				// We tried really hard, but the data doesn't exist.
                +				return;
                +			}
                +
                +			// Set the data...
                +			this.each( function() {
                +
                +				// We always store the camelCased key
                +				dataUser.set( this, key, value );
                +			} );
                +		}, null, value, arguments.length > 1, null, true );
                +	},
                +
                +	removeData: function( key ) {
                +		return this.each( function() {
                +			dataUser.remove( this, key );
                +		} );
                +	}
                +} );
                +
                +
                +jQuery.extend( {
                +	queue: function( elem, type, data ) {
                +		var queue;
                +
                +		if ( elem ) {
                +			type = ( type || "fx" ) + "queue";
                +			queue = dataPriv.get( elem, type );
                +
                +			// Speed up dequeue by getting out quickly if this is just a lookup
                +			if ( data ) {
                +				if ( !queue || Array.isArray( data ) ) {
                +					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
                +				} else {
                +					queue.push( data );
                +				}
                +			}
                +			return queue || [];
                +		}
                +	},
                +
                +	dequeue: function( elem, type ) {
                +		type = type || "fx";
                +
                +		var queue = jQuery.queue( elem, type ),
                +			startLength = queue.length,
                +			fn = queue.shift(),
                +			hooks = jQuery._queueHooks( elem, type ),
                +			next = function() {
                +				jQuery.dequeue( elem, type );
                +			};
                +
                +		// If the fx queue is dequeued, always remove the progress sentinel
                +		if ( fn === "inprogress" ) {
                +			fn = queue.shift();
                +			startLength--;
                +		}
                +
                +		if ( fn ) {
                +
                +			// Add a progress sentinel to prevent the fx queue from being
                +			// automatically dequeued
                +			if ( type === "fx" ) {
                +				queue.unshift( "inprogress" );
                +			}
                +
                +			// Clear up the last queue stop function
                +			delete hooks.stop;
                +			fn.call( elem, next, hooks );
                +		}
                +
                +		if ( !startLength && hooks ) {
                +			hooks.empty.fire();
                +		}
                +	},
                +
                +	// Not public - generate a queueHooks object, or return the current one
                +	_queueHooks: function( elem, type ) {
                +		var key = type + "queueHooks";
                +		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
                +			empty: jQuery.Callbacks( "once memory" ).add( function() {
                +				dataPriv.remove( elem, [ type + "queue", key ] );
                +			} )
                +		} );
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	queue: function( type, data ) {
                +		var setter = 2;
                +
                +		if ( typeof type !== "string" ) {
                +			data = type;
                +			type = "fx";
                +			setter--;
                +		}
                +
                +		if ( arguments.length < setter ) {
                +			return jQuery.queue( this[ 0 ], type );
                +		}
                +
                +		return data === undefined ?
                +			this :
                +			this.each( function() {
                +				var queue = jQuery.queue( this, type, data );
                +
                +				// Ensure a hooks for this queue
                +				jQuery._queueHooks( this, type );
                +
                +				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
                +					jQuery.dequeue( this, type );
                +				}
                +			} );
                +	},
                +	dequeue: function( type ) {
                +		return this.each( function() {
                +			jQuery.dequeue( this, type );
                +		} );
                +	},
                +	clearQueue: function( type ) {
                +		return this.queue( type || "fx", [] );
                +	},
                +
                +	// Get a promise resolved when queues of a certain type
                +	// are emptied (fx is the type by default)
                +	promise: function( type, obj ) {
                +		var tmp,
                +			count = 1,
                +			defer = jQuery.Deferred(),
                +			elements = this,
                +			i = this.length,
                +			resolve = function() {
                +				if ( !( --count ) ) {
                +					defer.resolveWith( elements, [ elements ] );
                +				}
                +			};
                +
                +		if ( typeof type !== "string" ) {
                +			obj = type;
                +			type = undefined;
                +		}
                +		type = type || "fx";
                +
                +		while ( i-- ) {
                +			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
                +			if ( tmp && tmp.empty ) {
                +				count++;
                +				tmp.empty.add( resolve );
                +			}
                +		}
                +		resolve();
                +		return defer.promise( obj );
                +	}
                +} );
                +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
                +
                +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
                +
                +
                +var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
                +
                +var isHiddenWithinTree = function( elem, el ) {
                +
                +		// isHiddenWithinTree might be called from jQuery#filter function;
                +		// in that case, element will be second argument
                +		elem = el || elem;
                +
                +		// Inline style trumps all
                +		return elem.style.display === "none" ||
                +			elem.style.display === "" &&
                +
                +			// Otherwise, check computed style
                +			// Support: Firefox <=43 - 45
                +			// Disconnected elements can have computed display: none, so first confirm that elem is
                +			// in the document.
                +			jQuery.contains( elem.ownerDocument, elem ) &&
                +
                +			jQuery.css( elem, "display" ) === "none";
                +	};
                +
                +var swap = function( elem, options, callback, args ) {
                +	var ret, name,
                +		old = {};
                +
                +	// Remember the old values, and insert the new ones
                +	for ( name in options ) {
                +		old[ name ] = elem.style[ name ];
                +		elem.style[ name ] = options[ name ];
                +	}
                +
                +	ret = callback.apply( elem, args || [] );
                +
                +	// Revert the old values
                +	for ( name in options ) {
                +		elem.style[ name ] = old[ name ];
                +	}
                +
                +	return ret;
                +};
                +
                +
                +
                +
                +function adjustCSS( elem, prop, valueParts, tween ) {
                +	var adjusted,
                +		scale = 1,
                +		maxIterations = 20,
                +		currentValue = tween ?
                +			function() {
                +				return tween.cur();
                +			} :
                +			function() {
                +				return jQuery.css( elem, prop, "" );
                +			},
                +		initial = currentValue(),
                +		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
                +
                +		// Starting value computation is required for potential unit mismatches
                +		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
                +			rcssNum.exec( jQuery.css( elem, prop ) );
                +
                +	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
                +
                +		// Trust units reported by jQuery.css
                +		unit = unit || initialInUnit[ 3 ];
                +
                +		// Make sure we update the tween properties later on
                +		valueParts = valueParts || [];
                +
                +		// Iteratively approximate from a nonzero starting point
                +		initialInUnit = +initial || 1;
                +
                +		do {
                +
                +			// If previous iteration zeroed out, double until we get *something*.
                +			// Use string for doubling so we don't accidentally see scale as unchanged below
                +			scale = scale || ".5";
                +
                +			// Adjust and apply
                +			initialInUnit = initialInUnit / scale;
                +			jQuery.style( elem, prop, initialInUnit + unit );
                +
                +		// Update scale, tolerating zero or NaN from tween.cur()
                +		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
                +		} while (
                +			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
                +		);
                +	}
                +
                +	if ( valueParts ) {
                +		initialInUnit = +initialInUnit || +initial || 0;
                +
                +		// Apply relative offset (+=/-=) if specified
                +		adjusted = valueParts[ 1 ] ?
                +			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
                +			+valueParts[ 2 ];
                +		if ( tween ) {
                +			tween.unit = unit;
                +			tween.start = initialInUnit;
                +			tween.end = adjusted;
                +		}
                +	}
                +	return adjusted;
                +}
                +
                +
                +var defaultDisplayMap = {};
                +
                +function getDefaultDisplay( elem ) {
                +	var temp,
                +		doc = elem.ownerDocument,
                +		nodeName = elem.nodeName,
                +		display = defaultDisplayMap[ nodeName ];
                +
                +	if ( display ) {
                +		return display;
                +	}
                +
                +	temp = doc.body.appendChild( doc.createElement( nodeName ) );
                +	display = jQuery.css( temp, "display" );
                +
                +	temp.parentNode.removeChild( temp );
                +
                +	if ( display === "none" ) {
                +		display = "block";
                +	}
                +	defaultDisplayMap[ nodeName ] = display;
                +
                +	return display;
                +}
                +
                +function showHide( elements, show ) {
                +	var display, elem,
                +		values = [],
                +		index = 0,
                +		length = elements.length;
                +
                +	// Determine new display value for elements that need to change
                +	for ( ; index < length; index++ ) {
                +		elem = elements[ index ];
                +		if ( !elem.style ) {
                +			continue;
                +		}
                +
                +		display = elem.style.display;
                +		if ( show ) {
                +
                +			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
                +			// check is required in this first loop unless we have a nonempty display value (either
                +			// inline or about-to-be-restored)
                +			if ( display === "none" ) {
                +				values[ index ] = dataPriv.get( elem, "display" ) || null;
                +				if ( !values[ index ] ) {
                +					elem.style.display = "";
                +				}
                +			}
                +			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
                +				values[ index ] = getDefaultDisplay( elem );
                +			}
                +		} else {
                +			if ( display !== "none" ) {
                +				values[ index ] = "none";
                +
                +				// Remember what we're overwriting
                +				dataPriv.set( elem, "display", display );
                +			}
                +		}
                +	}
                +
                +	// Set the display of the elements in a second loop to avoid constant reflow
                +	for ( index = 0; index < length; index++ ) {
                +		if ( values[ index ] != null ) {
                +			elements[ index ].style.display = values[ index ];
                +		}
                +	}
                +
                +	return elements;
                +}
                +
                +jQuery.fn.extend( {
                +	show: function() {
                +		return showHide( this, true );
                +	},
                +	hide: function() {
                +		return showHide( this );
                +	},
                +	toggle: function( state ) {
                +		if ( typeof state === "boolean" ) {
                +			return state ? this.show() : this.hide();
                +		}
                +
                +		return this.each( function() {
                +			if ( isHiddenWithinTree( this ) ) {
                +				jQuery( this ).show();
                +			} else {
                +				jQuery( this ).hide();
                +			}
                +		} );
                +	}
                +} );
                +var rcheckableType = ( /^(?:checkbox|radio)$/i );
                +
                +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
                +
                +var rscriptType = ( /^$|\/(?:java|ecma)script/i );
                +
                +
                +
                +// We have to close these tags to support XHTML (#13200)
                +var wrapMap = {
                +
                +	// Support: IE <=9 only
                +	option: [ 1, "<select multiple='multiple'>", "</select>" ],
                +
                +	// XHTML parsers do not magically insert elements in the
                +	// same way that tag soup parsers do. So we cannot shorten
                +	// this by omitting <tbody> or other required elements.
                +	thead: [ 1, "<table>", "</table>" ],
                +	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
                +	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
                +	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
                +
                +	_default: [ 0, "", "" ]
                +};
                +
                +// Support: IE <=9 only
                +wrapMap.optgroup = wrapMap.option;
                +
                +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
                +wrapMap.th = wrapMap.td;
                +
                +
                +function getAll( context, tag ) {
                +
                +	// Support: IE <=9 - 11 only
                +	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
                +	var ret;
                +
                +	if ( typeof context.getElementsByTagName !== "undefined" ) {
                +		ret = context.getElementsByTagName( tag || "*" );
                +
                +	} else if ( typeof context.querySelectorAll !== "undefined" ) {
                +		ret = context.querySelectorAll( tag || "*" );
                +
                +	} else {
                +		ret = [];
                +	}
                +
                +	if ( tag === undefined || tag && nodeName( context, tag ) ) {
                +		return jQuery.merge( [ context ], ret );
                +	}
                +
                +	return ret;
                +}
                +
                +
                +// Mark scripts as having already been evaluated
                +function setGlobalEval( elems, refElements ) {
                +	var i = 0,
                +		l = elems.length;
                +
                +	for ( ; i < l; i++ ) {
                +		dataPriv.set(
                +			elems[ i ],
                +			"globalEval",
                +			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
                +		);
                +	}
                +}
                +
                +
                +var rhtml = /<|&#?\w+;/;
                +
                +function buildFragment( elems, context, scripts, selection, ignored ) {
                +	var elem, tmp, tag, wrap, contains, j,
                +		fragment = context.createDocumentFragment(),
                +		nodes = [],
                +		i = 0,
                +		l = elems.length;
                +
                +	for ( ; i < l; i++ ) {
                +		elem = elems[ i ];
                +
                +		if ( elem || elem === 0 ) {
                +
                +			// Add nodes directly
                +			if ( jQuery.type( elem ) === "object" ) {
                +
                +				// Support: Android <=4.0 only, PhantomJS 1 only
                +				// push.apply(_, arraylike) throws on ancient WebKit
                +				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
                +
                +			// Convert non-html into a text node
                +			} else if ( !rhtml.test( elem ) ) {
                +				nodes.push( context.createTextNode( elem ) );
                +
                +			// Convert html into DOM nodes
                +			} else {
                +				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
                +
                +				// Deserialize a standard representation
                +				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
                +				wrap = wrapMap[ tag ] || wrapMap._default;
                +				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
                +
                +				// Descend through wrappers to the right content
                +				j = wrap[ 0 ];
                +				while ( j-- ) {
                +					tmp = tmp.lastChild;
                +				}
                +
                +				// Support: Android <=4.0 only, PhantomJS 1 only
                +				// push.apply(_, arraylike) throws on ancient WebKit
                +				jQuery.merge( nodes, tmp.childNodes );
                +
                +				// Remember the top-level container
                +				tmp = fragment.firstChild;
                +
                +				// Ensure the created nodes are orphaned (#12392)
                +				tmp.textContent = "";
                +			}
                +		}
                +	}
                +
                +	// Remove wrapper from fragment
                +	fragment.textContent = "";
                +
                +	i = 0;
                +	while ( ( elem = nodes[ i++ ] ) ) {
                +
                +		// Skip elements already in the context collection (trac-4087)
                +		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
                +			if ( ignored ) {
                +				ignored.push( elem );
                +			}
                +			continue;
                +		}
                +
                +		contains = jQuery.contains( elem.ownerDocument, elem );
                +
                +		// Append to fragment
                +		tmp = getAll( fragment.appendChild( elem ), "script" );
                +
                +		// Preserve script evaluation history
                +		if ( contains ) {
                +			setGlobalEval( tmp );
                +		}
                +
                +		// Capture executables
                +		if ( scripts ) {
                +			j = 0;
                +			while ( ( elem = tmp[ j++ ] ) ) {
                +				if ( rscriptType.test( elem.type || "" ) ) {
                +					scripts.push( elem );
                +				}
                +			}
                +		}
                +	}
                +
                +	return fragment;
                +}
                +
                +
                +( function() {
                +	var fragment = document.createDocumentFragment(),
                +		div = fragment.appendChild( document.createElement( "div" ) ),
                +		input = document.createElement( "input" );
                +
                +	// Support: Android 4.0 - 4.3 only
                +	// Check state lost if the name is set (#11217)
                +	// Support: Windows Web Apps (WWA)
                +	// `name` and `type` must use .setAttribute for WWA (#14901)
                +	input.setAttribute( "type", "radio" );
                +	input.setAttribute( "checked", "checked" );
                +	input.setAttribute( "name", "t" );
                +
                +	div.appendChild( input );
                +
                +	// Support: Android <=4.1 only
                +	// Older WebKit doesn't clone checked state correctly in fragments
                +	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
                +
                +	// Support: IE <=11 only
                +	// Make sure textarea (and checkbox) defaultValue is properly cloned
                +	div.innerHTML = "<textarea>x</textarea>";
                +	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
                +} )();
                +var documentElement = document.documentElement;
                +
                +
                +
                +var
                +	rkeyEvent = /^key/,
                +	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
                +	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
                +
                +function returnTrue() {
                +	return true;
                +}
                +
                +function returnFalse() {
                +	return false;
                +}
                +
                +// Support: IE <=9 only
                +// See #13393 for more info
                +function safeActiveElement() {
                +	try {
                +		return document.activeElement;
                +	} catch ( err ) { }
                +}
                +
                +function on( elem, types, selector, data, fn, one ) {
                +	var origFn, type;
                +
                +	// Types can be a map of types/handlers
                +	if ( typeof types === "object" ) {
                +
                +		// ( types-Object, selector, data )
                +		if ( typeof selector !== "string" ) {
                +
                +			// ( types-Object, data )
                +			data = data || selector;
                +			selector = undefined;
                +		}
                +		for ( type in types ) {
                +			on( elem, type, selector, data, types[ type ], one );
                +		}
                +		return elem;
                +	}
                +
                +	if ( data == null && fn == null ) {
                +
                +		// ( types, fn )
                +		fn = selector;
                +		data = selector = undefined;
                +	} else if ( fn == null ) {
                +		if ( typeof selector === "string" ) {
                +
                +			// ( types, selector, fn )
                +			fn = data;
                +			data = undefined;
                +		} else {
                +
                +			// ( types, data, fn )
                +			fn = data;
                +			data = selector;
                +			selector = undefined;
                +		}
                +	}
                +	if ( fn === false ) {
                +		fn = returnFalse;
                +	} else if ( !fn ) {
                +		return elem;
                +	}
                +
                +	if ( one === 1 ) {
                +		origFn = fn;
                +		fn = function( event ) {
                +
                +			// Can use an empty set, since event contains the info
                +			jQuery().off( event );
                +			return origFn.apply( this, arguments );
                +		};
                +
                +		// Use same guid so caller can remove using origFn
                +		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
                +	}
                +	return elem.each( function() {
                +		jQuery.event.add( this, types, fn, data, selector );
                +	} );
                +}
                +
                +/*
                + * Helper functions for managing events -- not part of the public interface.
                + * Props to Dean Edwards' addEvent library for many of the ideas.
                + */
                +jQuery.event = {
                +
                +	global: {},
                +
                +	add: function( elem, types, handler, data, selector ) {
                +
                +		var handleObjIn, eventHandle, tmp,
                +			events, t, handleObj,
                +			special, handlers, type, namespaces, origType,
                +			elemData = dataPriv.get( elem );
                +
                +		// Don't attach events to noData or text/comment nodes (but allow plain objects)
                +		if ( !elemData ) {
                +			return;
                +		}
                +
                +		// Caller can pass in an object of custom data in lieu of the handler
                +		if ( handler.handler ) {
                +			handleObjIn = handler;
                +			handler = handleObjIn.handler;
                +			selector = handleObjIn.selector;
                +		}
                +
                +		// Ensure that invalid selectors throw exceptions at attach time
                +		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
                +		if ( selector ) {
                +			jQuery.find.matchesSelector( documentElement, selector );
                +		}
                +
                +		// Make sure that the handler has a unique ID, used to find/remove it later
                +		if ( !handler.guid ) {
                +			handler.guid = jQuery.guid++;
                +		}
                +
                +		// Init the element's event structure and main handler, if this is the first
                +		if ( !( events = elemData.events ) ) {
                +			events = elemData.events = {};
                +		}
                +		if ( !( eventHandle = elemData.handle ) ) {
                +			eventHandle = elemData.handle = function( e ) {
                +
                +				// Discard the second event of a jQuery.event.trigger() and
                +				// when an event is called after a page has unloaded
                +				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
                +					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
                +			};
                +		}
                +
                +		// Handle multiple events separated by a space
                +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                +		t = types.length;
                +		while ( t-- ) {
                +			tmp = rtypenamespace.exec( types[ t ] ) || [];
                +			type = origType = tmp[ 1 ];
                +			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
                +
                +			// There *must* be a type, no attaching namespace-only handlers
                +			if ( !type ) {
                +				continue;
                +			}
                +
                +			// If event changes its type, use the special event handlers for the changed type
                +			special = jQuery.event.special[ type ] || {};
                +
                +			// If selector defined, determine special event api type, otherwise given type
                +			type = ( selector ? special.delegateType : special.bindType ) || type;
                +
                +			// Update special based on newly reset type
                +			special = jQuery.event.special[ type ] || {};
                +
                +			// handleObj is passed to all event handlers
                +			handleObj = jQuery.extend( {
                +				type: type,
                +				origType: origType,
                +				data: data,
                +				handler: handler,
                +				guid: handler.guid,
                +				selector: selector,
                +				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                +				namespace: namespaces.join( "." )
                +			}, handleObjIn );
                +
                +			// Init the event handler queue if we're the first
                +			if ( !( handlers = events[ type ] ) ) {
                +				handlers = events[ type ] = [];
                +				handlers.delegateCount = 0;
                +
                +				// Only use addEventListener if the special events handler returns false
                +				if ( !special.setup ||
                +					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                +
                +					if ( elem.addEventListener ) {
                +						elem.addEventListener( type, eventHandle );
                +					}
                +				}
                +			}
                +
                +			if ( special.add ) {
                +				special.add.call( elem, handleObj );
                +
                +				if ( !handleObj.handler.guid ) {
                +					handleObj.handler.guid = handler.guid;
                +				}
                +			}
                +
                +			// Add to the element's handler list, delegates in front
                +			if ( selector ) {
                +				handlers.splice( handlers.delegateCount++, 0, handleObj );
                +			} else {
                +				handlers.push( handleObj );
                +			}
                +
                +			// Keep track of which events have ever been used, for event optimization
                +			jQuery.event.global[ type ] = true;
                +		}
                +
                +	},
                +
                +	// Detach an event or set of events from an element
                +	remove: function( elem, types, handler, selector, mappedTypes ) {
                +
                +		var j, origCount, tmp,
                +			events, t, handleObj,
                +			special, handlers, type, namespaces, origType,
                +			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
                +
                +		if ( !elemData || !( events = elemData.events ) ) {
                +			return;
                +		}
                +
                +		// Once for each type.namespace in types; type may be omitted
                +		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                +		t = types.length;
                +		while ( t-- ) {
                +			tmp = rtypenamespace.exec( types[ t ] ) || [];
                +			type = origType = tmp[ 1 ];
                +			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
                +
                +			// Unbind all events (on this namespace, if provided) for the element
                +			if ( !type ) {
                +				for ( type in events ) {
                +					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
                +				}
                +				continue;
                +			}
                +
                +			special = jQuery.event.special[ type ] || {};
                +			type = ( selector ? special.delegateType : special.bindType ) || type;
                +			handlers = events[ type ] || [];
                +			tmp = tmp[ 2 ] &&
                +				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
                +
                +			// Remove matching events
                +			origCount = j = handlers.length;
                +			while ( j-- ) {
                +				handleObj = handlers[ j ];
                +
                +				if ( ( mappedTypes || origType === handleObj.origType ) &&
                +					( !handler || handler.guid === handleObj.guid ) &&
                +					( !tmp || tmp.test( handleObj.namespace ) ) &&
                +					( !selector || selector === handleObj.selector ||
                +						selector === "**" && handleObj.selector ) ) {
                +					handlers.splice( j, 1 );
                +
                +					if ( handleObj.selector ) {
                +						handlers.delegateCount--;
                +					}
                +					if ( special.remove ) {
                +						special.remove.call( elem, handleObj );
                +					}
                +				}
                +			}
                +
                +			// Remove generic event handler if we removed something and no more handlers exist
                +			// (avoids potential for endless recursion during removal of special event handlers)
                +			if ( origCount && !handlers.length ) {
                +				if ( !special.teardown ||
                +					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
                +
                +					jQuery.removeEvent( elem, type, elemData.handle );
                +				}
                +
                +				delete events[ type ];
                +			}
                +		}
                +
                +		// Remove data and the expando if it's no longer used
                +		if ( jQuery.isEmptyObject( events ) ) {
                +			dataPriv.remove( elem, "handle events" );
                +		}
                +	},
                +
                +	dispatch: function( nativeEvent ) {
                +
                +		// Make a writable jQuery.Event from the native event object
                +		var event = jQuery.event.fix( nativeEvent );
                +
                +		var i, j, ret, matched, handleObj, handlerQueue,
                +			args = new Array( arguments.length ),
                +			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
                +			special = jQuery.event.special[ event.type ] || {};
                +
                +		// Use the fix-ed jQuery.Event rather than the (read-only) native event
                +		args[ 0 ] = event;
                +
                +		for ( i = 1; i < arguments.length; i++ ) {
                +			args[ i ] = arguments[ i ];
                +		}
                +
                +		event.delegateTarget = this;
                +
                +		// Call the preDispatch hook for the mapped type, and let it bail if desired
                +		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
                +			return;
                +		}
                +
                +		// Determine handlers
                +		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
                +
                +		// Run delegates first; they may want to stop propagation beneath us
                +		i = 0;
                +		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
                +			event.currentTarget = matched.elem;
                +
                +			j = 0;
                +			while ( ( handleObj = matched.handlers[ j++ ] ) &&
                +				!event.isImmediatePropagationStopped() ) {
                +
                +				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
                +				// a subset or equal to those in the bound event (both can have no namespace).
                +				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
                +
                +					event.handleObj = handleObj;
                +					event.data = handleObj.data;
                +
                +					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
                +						handleObj.handler ).apply( matched.elem, args );
                +
                +					if ( ret !== undefined ) {
                +						if ( ( event.result = ret ) === false ) {
                +							event.preventDefault();
                +							event.stopPropagation();
                +						}
                +					}
                +				}
                +			}
                +		}
                +
                +		// Call the postDispatch hook for the mapped type
                +		if ( special.postDispatch ) {
                +			special.postDispatch.call( this, event );
                +		}
                +
                +		return event.result;
                +	},
                +
                +	handlers: function( event, handlers ) {
                +		var i, handleObj, sel, matchedHandlers, matchedSelectors,
                +			handlerQueue = [],
                +			delegateCount = handlers.delegateCount,
                +			cur = event.target;
                +
                +		// Find delegate handlers
                +		if ( delegateCount &&
                +
                +			// Support: IE <=9
                +			// Black-hole SVG <use> instance trees (trac-13180)
                +			cur.nodeType &&
                +
                +			// Support: Firefox <=42
                +			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
                +			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
                +			// Support: IE 11 only
                +			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
                +			!( event.type === "click" && event.button >= 1 ) ) {
                +
                +			for ( ; cur !== this; cur = cur.parentNode || this ) {
                +
                +				// Don't check non-elements (#13208)
                +				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
                +				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
                +					matchedHandlers = [];
                +					matchedSelectors = {};
                +					for ( i = 0; i < delegateCount; i++ ) {
                +						handleObj = handlers[ i ];
                +
                +						// Don't conflict with Object.prototype properties (#13203)
                +						sel = handleObj.selector + " ";
                +
                +						if ( matchedSelectors[ sel ] === undefined ) {
                +							matchedSelectors[ sel ] = handleObj.needsContext ?
                +								jQuery( sel, this ).index( cur ) > -1 :
                +								jQuery.find( sel, this, null, [ cur ] ).length;
                +						}
                +						if ( matchedSelectors[ sel ] ) {
                +							matchedHandlers.push( handleObj );
                +						}
                +					}
                +					if ( matchedHandlers.length ) {
                +						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
                +					}
                +				}
                +			}
                +		}
                +
                +		// Add the remaining (directly-bound) handlers
                +		cur = this;
                +		if ( delegateCount < handlers.length ) {
                +			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
                +		}
                +
                +		return handlerQueue;
                +	},
                +
                +	addProp: function( name, hook ) {
                +		Object.defineProperty( jQuery.Event.prototype, name, {
                +			enumerable: true,
                +			configurable: true,
                +
                +			get: jQuery.isFunction( hook ) ?
                +				function() {
                +					if ( this.originalEvent ) {
                +							return hook( this.originalEvent );
                +					}
                +				} :
                +				function() {
                +					if ( this.originalEvent ) {
                +							return this.originalEvent[ name ];
                +					}
                +				},
                +
                +			set: function( value ) {
                +				Object.defineProperty( this, name, {
                +					enumerable: true,
                +					configurable: true,
                +					writable: true,
                +					value: value
                +				} );
                +			}
                +		} );
                +	},
                +
                +	fix: function( originalEvent ) {
                +		return originalEvent[ jQuery.expando ] ?
                +			originalEvent :
                +			new jQuery.Event( originalEvent );
                +	},
                +
                +	special: {
                +		load: {
                +
                +			// Prevent triggered image.load events from bubbling to window.load
                +			noBubble: true
                +		},
                +		focus: {
                +
                +			// Fire native event if possible so blur/focus sequence is correct
                +			trigger: function() {
                +				if ( this !== safeActiveElement() && this.focus ) {
                +					this.focus();
                +					return false;
                +				}
                +			},
                +			delegateType: "focusin"
                +		},
                +		blur: {
                +			trigger: function() {
                +				if ( this === safeActiveElement() && this.blur ) {
                +					this.blur();
                +					return false;
                +				}
                +			},
                +			delegateType: "focusout"
                +		},
                +		click: {
                +
                +			// For checkbox, fire native event so checked state will be right
                +			trigger: function() {
                +				if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
                +					this.click();
                +					return false;
                +				}
                +			},
                +
                +			// For cross-browser consistency, don't fire native .click() on links
                +			_default: function( event ) {
                +				return nodeName( event.target, "a" );
                +			}
                +		},
                +
                +		beforeunload: {
                +			postDispatch: function( event ) {
                +
                +				// Support: Firefox 20+
                +				// Firefox doesn't alert if the returnValue field is not set.
                +				if ( event.result !== undefined && event.originalEvent ) {
                +					event.originalEvent.returnValue = event.result;
                +				}
                +			}
                +		}
                +	}
                +};
                +
                +jQuery.removeEvent = function( elem, type, handle ) {
                +
                +	// This "if" is needed for plain objects
                +	if ( elem.removeEventListener ) {
                +		elem.removeEventListener( type, handle );
                +	}
                +};
                +
                +jQuery.Event = function( src, props ) {
                +
                +	// Allow instantiation without the 'new' keyword
                +	if ( !( this instanceof jQuery.Event ) ) {
                +		return new jQuery.Event( src, props );
                +	}
                +
                +	// Event object
                +	if ( src && src.type ) {
                +		this.originalEvent = src;
                +		this.type = src.type;
                +
                +		// Events bubbling up the document may have been marked as prevented
                +		// by a handler lower down the tree; reflect the correct value.
                +		this.isDefaultPrevented = src.defaultPrevented ||
                +				src.defaultPrevented === undefined &&
                +
                +				// Support: Android <=2.3 only
                +				src.returnValue === false ?
                +			returnTrue :
                +			returnFalse;
                +
                +		// Create target properties
                +		// Support: Safari <=6 - 7 only
                +		// Target should not be a text node (#504, #13143)
                +		this.target = ( src.target && src.target.nodeType === 3 ) ?
                +			src.target.parentNode :
                +			src.target;
                +
                +		this.currentTarget = src.currentTarget;
                +		this.relatedTarget = src.relatedTarget;
                +
                +	// Event type
                +	} else {
                +		this.type = src;
                +	}
                +
                +	// Put explicitly provided properties onto the event object
                +	if ( props ) {
                +		jQuery.extend( this, props );
                +	}
                +
                +	// Create a timestamp if incoming event doesn't have one
                +	this.timeStamp = src && src.timeStamp || jQuery.now();
                +
                +	// Mark it as fixed
                +	this[ jQuery.expando ] = true;
                +};
                +
                +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
                +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
                +jQuery.Event.prototype = {
                +	constructor: jQuery.Event,
                +	isDefaultPrevented: returnFalse,
                +	isPropagationStopped: returnFalse,
                +	isImmediatePropagationStopped: returnFalse,
                +	isSimulated: false,
                +
                +	preventDefault: function() {
                +		var e = this.originalEvent;
                +
                +		this.isDefaultPrevented = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.preventDefault();
                +		}
                +	},
                +	stopPropagation: function() {
                +		var e = this.originalEvent;
                +
                +		this.isPropagationStopped = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.stopPropagation();
                +		}
                +	},
                +	stopImmediatePropagation: function() {
                +		var e = this.originalEvent;
                +
                +		this.isImmediatePropagationStopped = returnTrue;
                +
                +		if ( e && !this.isSimulated ) {
                +			e.stopImmediatePropagation();
                +		}
                +
                +		this.stopPropagation();
                +	}
                +};
                +
                +// Includes all common event props including KeyEvent and MouseEvent specific props
                +jQuery.each( {
                +	altKey: true,
                +	bubbles: true,
                +	cancelable: true,
                +	changedTouches: true,
                +	ctrlKey: true,
                +	detail: true,
                +	eventPhase: true,
                +	metaKey: true,
                +	pageX: true,
                +	pageY: true,
                +	shiftKey: true,
                +	view: true,
                +	"char": true,
                +	charCode: true,
                +	key: true,
                +	keyCode: true,
                +	button: true,
                +	buttons: true,
                +	clientX: true,
                +	clientY: true,
                +	offsetX: true,
                +	offsetY: true,
                +	pointerId: true,
                +	pointerType: true,
                +	screenX: true,
                +	screenY: true,
                +	targetTouches: true,
                +	toElement: true,
                +	touches: true,
                +
                +	which: function( event ) {
                +		var button = event.button;
                +
                +		// Add which for key events
                +		if ( event.which == null && rkeyEvent.test( event.type ) ) {
                +			return event.charCode != null ? event.charCode : event.keyCode;
                +		}
                +
                +		// Add which for click: 1 === left; 2 === middle; 3 === right
                +		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
                +			if ( button & 1 ) {
                +				return 1;
                +			}
                +
                +			if ( button & 2 ) {
                +				return 3;
                +			}
                +
                +			if ( button & 4 ) {
                +				return 2;
                +			}
                +
                +			return 0;
                +		}
                +
                +		return event.which;
                +	}
                +}, jQuery.event.addProp );
                +
                +// Create mouseenter/leave events using mouseover/out and event-time checks
                +// so that event delegation works in jQuery.
                +// Do the same for pointerenter/pointerleave and pointerover/pointerout
                +//
                +// Support: Safari 7 only
                +// Safari sends mouseenter too often; see:
                +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
                +// for the description of the bug (it existed in older Chrome versions as well).
                +jQuery.each( {
                +	mouseenter: "mouseover",
                +	mouseleave: "mouseout",
                +	pointerenter: "pointerover",
                +	pointerleave: "pointerout"
                +}, function( orig, fix ) {
                +	jQuery.event.special[ orig ] = {
                +		delegateType: fix,
                +		bindType: fix,
                +
                +		handle: function( event ) {
                +			var ret,
                +				target = this,
                +				related = event.relatedTarget,
                +				handleObj = event.handleObj;
                +
                +			// For mouseenter/leave call the handler if related is outside the target.
                +			// NB: No relatedTarget if the mouse left/entered the browser window
                +			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
                +				event.type = handleObj.origType;
                +				ret = handleObj.handler.apply( this, arguments );
                +				event.type = fix;
                +			}
                +			return ret;
                +		}
                +	};
                +} );
                +
                +jQuery.fn.extend( {
                +
                +	on: function( types, selector, data, fn ) {
                +		return on( this, types, selector, data, fn );
                +	},
                +	one: function( types, selector, data, fn ) {
                +		return on( this, types, selector, data, fn, 1 );
                +	},
                +	off: function( types, selector, fn ) {
                +		var handleObj, type;
                +		if ( types && types.preventDefault && types.handleObj ) {
                +
                +			// ( event )  dispatched jQuery.Event
                +			handleObj = types.handleObj;
                +			jQuery( types.delegateTarget ).off(
                +				handleObj.namespace ?
                +					handleObj.origType + "." + handleObj.namespace :
                +					handleObj.origType,
                +				handleObj.selector,
                +				handleObj.handler
                +			);
                +			return this;
                +		}
                +		if ( typeof types === "object" ) {
                +
                +			// ( types-object [, selector] )
                +			for ( type in types ) {
                +				this.off( type, selector, types[ type ] );
                +			}
                +			return this;
                +		}
                +		if ( selector === false || typeof selector === "function" ) {
                +
                +			// ( types [, fn] )
                +			fn = selector;
                +			selector = undefined;
                +		}
                +		if ( fn === false ) {
                +			fn = returnFalse;
                +		}
                +		return this.each( function() {
                +			jQuery.event.remove( this, types, fn, selector );
                +		} );
                +	}
                +} );
                +
                +
                +var
                +
                +	/* eslint-disable max-len */
                +
                +	// See https://github.com/eslint/eslint/issues/3229
                +	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
                +
                +	/* eslint-enable */
                +
                +	// Support: IE <=10 - 11, Edge 12 - 13
                +	// In IE/Edge using regex groups here causes severe slowdowns.
                +	// See https://connect.microsoft.com/IE/feedback/details/1736512/
                +	rnoInnerhtml = /<script|<style|<link/i,
                +
                +	// checked="checked" or checked
                +	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
                +	rscriptTypeMasked = /^true\/(.*)/,
                +	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
                +
                +// Prefer a tbody over its parent table for containing new rows
                +function manipulationTarget( elem, content ) {
                +	if ( nodeName( elem, "table" ) &&
                +		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
                +
                +		return jQuery( ">tbody", elem )[ 0 ] || elem;
                +	}
                +
                +	return elem;
                +}
                +
                +// Replace/restore the type attribute of script elements for safe DOM manipulation
                +function disableScript( elem ) {
                +	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
                +	return elem;
                +}
                +function restoreScript( elem ) {
                +	var match = rscriptTypeMasked.exec( elem.type );
                +
                +	if ( match ) {
                +		elem.type = match[ 1 ];
                +	} else {
                +		elem.removeAttribute( "type" );
                +	}
                +
                +	return elem;
                +}
                +
                +function cloneCopyEvent( src, dest ) {
                +	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
                +
                +	if ( dest.nodeType !== 1 ) {
                +		return;
                +	}
                +
                +	// 1. Copy private data: events, handlers, etc.
                +	if ( dataPriv.hasData( src ) ) {
                +		pdataOld = dataPriv.access( src );
                +		pdataCur = dataPriv.set( dest, pdataOld );
                +		events = pdataOld.events;
                +
                +		if ( events ) {
                +			delete pdataCur.handle;
                +			pdataCur.events = {};
                +
                +			for ( type in events ) {
                +				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
                +					jQuery.event.add( dest, type, events[ type ][ i ] );
                +				}
                +			}
                +		}
                +	}
                +
                +	// 2. Copy user data
                +	if ( dataUser.hasData( src ) ) {
                +		udataOld = dataUser.access( src );
                +		udataCur = jQuery.extend( {}, udataOld );
                +
                +		dataUser.set( dest, udataCur );
                +	}
                +}
                +
                +// Fix IE bugs, see support tests
                +function fixInput( src, dest ) {
                +	var nodeName = dest.nodeName.toLowerCase();
                +
                +	// Fails to persist the checked state of a cloned checkbox or radio button.
                +	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
                +		dest.checked = src.checked;
                +
                +	// Fails to return the selected option to the default selected state when cloning options
                +	} else if ( nodeName === "input" || nodeName === "textarea" ) {
                +		dest.defaultValue = src.defaultValue;
                +	}
                +}
                +
                +function domManip( collection, args, callback, ignored ) {
                +
                +	// Flatten any nested arrays
                +	args = concat.apply( [], args );
                +
                +	var fragment, first, scripts, hasScripts, node, doc,
                +		i = 0,
                +		l = collection.length,
                +		iNoClone = l - 1,
                +		value = args[ 0 ],
                +		isFunction = jQuery.isFunction( value );
                +
                +	// We can't cloneNode fragments that contain checked, in WebKit
                +	if ( isFunction ||
                +			( l > 1 && typeof value === "string" &&
                +				!support.checkClone && rchecked.test( value ) ) ) {
                +		return collection.each( function( index ) {
                +			var self = collection.eq( index );
                +			if ( isFunction ) {
                +				args[ 0 ] = value.call( this, index, self.html() );
                +			}
                +			domManip( self, args, callback, ignored );
                +		} );
                +	}
                +
                +	if ( l ) {
                +		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
                +		first = fragment.firstChild;
                +
                +		if ( fragment.childNodes.length === 1 ) {
                +			fragment = first;
                +		}
                +
                +		// Require either new content or an interest in ignored elements to invoke the callback
                +		if ( first || ignored ) {
                +			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
                +			hasScripts = scripts.length;
                +
                +			// Use the original fragment for the last item
                +			// instead of the first because it can end up
                +			// being emptied incorrectly in certain situations (#8070).
                +			for ( ; i < l; i++ ) {
                +				node = fragment;
                +
                +				if ( i !== iNoClone ) {
                +					node = jQuery.clone( node, true, true );
                +
                +					// Keep references to cloned scripts for later restoration
                +					if ( hasScripts ) {
                +
                +						// Support: Android <=4.0 only, PhantomJS 1 only
                +						// push.apply(_, arraylike) throws on ancient WebKit
                +						jQuery.merge( scripts, getAll( node, "script" ) );
                +					}
                +				}
                +
                +				callback.call( collection[ i ], node, i );
                +			}
                +
                +			if ( hasScripts ) {
                +				doc = scripts[ scripts.length - 1 ].ownerDocument;
                +
                +				// Reenable scripts
                +				jQuery.map( scripts, restoreScript );
                +
                +				// Evaluate executable scripts on first document insertion
                +				for ( i = 0; i < hasScripts; i++ ) {
                +					node = scripts[ i ];
                +					if ( rscriptType.test( node.type || "" ) &&
                +						!dataPriv.access( node, "globalEval" ) &&
                +						jQuery.contains( doc, node ) ) {
                +
                +						if ( node.src ) {
                +
                +							// Optional AJAX dependency, but won't run scripts if not present
                +							if ( jQuery._evalUrl ) {
                +								jQuery._evalUrl( node.src );
                +							}
                +						} else {
                +							DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	return collection;
                +}
                +
                +function remove( elem, selector, keepData ) {
                +	var node,
                +		nodes = selector ? jQuery.filter( selector, elem ) : elem,
                +		i = 0;
                +
                +	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
                +		if ( !keepData && node.nodeType === 1 ) {
                +			jQuery.cleanData( getAll( node ) );
                +		}
                +
                +		if ( node.parentNode ) {
                +			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
                +				setGlobalEval( getAll( node, "script" ) );
                +			}
                +			node.parentNode.removeChild( node );
                +		}
                +	}
                +
                +	return elem;
                +}
                +
                +jQuery.extend( {
                +	htmlPrefilter: function( html ) {
                +		return html.replace( rxhtmlTag, "<$1></$2>" );
                +	},
                +
                +	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
                +		var i, l, srcElements, destElements,
                +			clone = elem.cloneNode( true ),
                +			inPage = jQuery.contains( elem.ownerDocument, elem );
                +
                +		// Fix IE cloning issues
                +		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
                +				!jQuery.isXMLDoc( elem ) ) {
                +
                +			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
                +			destElements = getAll( clone );
                +			srcElements = getAll( elem );
                +
                +			for ( i = 0, l = srcElements.length; i < l; i++ ) {
                +				fixInput( srcElements[ i ], destElements[ i ] );
                +			}
                +		}
                +
                +		// Copy the events from the original to the clone
                +		if ( dataAndEvents ) {
                +			if ( deepDataAndEvents ) {
                +				srcElements = srcElements || getAll( elem );
                +				destElements = destElements || getAll( clone );
                +
                +				for ( i = 0, l = srcElements.length; i < l; i++ ) {
                +					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
                +				}
                +			} else {
                +				cloneCopyEvent( elem, clone );
                +			}
                +		}
                +
                +		// Preserve script evaluation history
                +		destElements = getAll( clone, "script" );
                +		if ( destElements.length > 0 ) {
                +			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
                +		}
                +
                +		// Return the cloned set
                +		return clone;
                +	},
                +
                +	cleanData: function( elems ) {
                +		var data, elem, type,
                +			special = jQuery.event.special,
                +			i = 0;
                +
                +		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
                +			if ( acceptData( elem ) ) {
                +				if ( ( data = elem[ dataPriv.expando ] ) ) {
                +					if ( data.events ) {
                +						for ( type in data.events ) {
                +							if ( special[ type ] ) {
                +								jQuery.event.remove( elem, type );
                +
                +							// This is a shortcut to avoid jQuery.event.remove's overhead
                +							} else {
                +								jQuery.removeEvent( elem, type, data.handle );
                +							}
                +						}
                +					}
                +
                +					// Support: Chrome <=35 - 45+
                +					// Assign undefined instead of using delete, see Data#remove
                +					elem[ dataPriv.expando ] = undefined;
                +				}
                +				if ( elem[ dataUser.expando ] ) {
                +
                +					// Support: Chrome <=35 - 45+
                +					// Assign undefined instead of using delete, see Data#remove
                +					elem[ dataUser.expando ] = undefined;
                +				}
                +			}
                +		}
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	detach: function( selector ) {
                +		return remove( this, selector, true );
                +	},
                +
                +	remove: function( selector ) {
                +		return remove( this, selector );
                +	},
                +
                +	text: function( value ) {
                +		return access( this, function( value ) {
                +			return value === undefined ?
                +				jQuery.text( this ) :
                +				this.empty().each( function() {
                +					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +						this.textContent = value;
                +					}
                +				} );
                +		}, null, value, arguments.length );
                +	},
                +
                +	append: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +				var target = manipulationTarget( this, elem );
                +				target.appendChild( elem );
                +			}
                +		} );
                +	},
                +
                +	prepend: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
                +				var target = manipulationTarget( this, elem );
                +				target.insertBefore( elem, target.firstChild );
                +			}
                +		} );
                +	},
                +
                +	before: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.parentNode ) {
                +				this.parentNode.insertBefore( elem, this );
                +			}
                +		} );
                +	},
                +
                +	after: function() {
                +		return domManip( this, arguments, function( elem ) {
                +			if ( this.parentNode ) {
                +				this.parentNode.insertBefore( elem, this.nextSibling );
                +			}
                +		} );
                +	},
                +
                +	empty: function() {
                +		var elem,
                +			i = 0;
                +
                +		for ( ; ( elem = this[ i ] ) != null; i++ ) {
                +			if ( elem.nodeType === 1 ) {
                +
                +				// Prevent memory leaks
                +				jQuery.cleanData( getAll( elem, false ) );
                +
                +				// Remove any remaining nodes
                +				elem.textContent = "";
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	clone: function( dataAndEvents, deepDataAndEvents ) {
                +		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                +		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
                +
                +		return this.map( function() {
                +			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                +		} );
                +	},
                +
                +	html: function( value ) {
                +		return access( this, function( value ) {
                +			var elem = this[ 0 ] || {},
                +				i = 0,
                +				l = this.length;
                +
                +			if ( value === undefined && elem.nodeType === 1 ) {
                +				return elem.innerHTML;
                +			}
                +
                +			// See if we can take a shortcut and just use innerHTML
                +			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
                +				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
                +
                +				value = jQuery.htmlPrefilter( value );
                +
                +				try {
                +					for ( ; i < l; i++ ) {
                +						elem = this[ i ] || {};
                +
                +						// Remove element nodes and prevent memory leaks
                +						if ( elem.nodeType === 1 ) {
                +							jQuery.cleanData( getAll( elem, false ) );
                +							elem.innerHTML = value;
                +						}
                +					}
                +
                +					elem = 0;
                +
                +				// If using innerHTML throws an exception, use the fallback method
                +				} catch ( e ) {}
                +			}
                +
                +			if ( elem ) {
                +				this.empty().append( value );
                +			}
                +		}, null, value, arguments.length );
                +	},
                +
                +	replaceWith: function() {
                +		var ignored = [];
                +
                +		// Make the changes, replacing each non-ignored context element with the new content
                +		return domManip( this, arguments, function( elem ) {
                +			var parent = this.parentNode;
                +
                +			if ( jQuery.inArray( this, ignored ) < 0 ) {
                +				jQuery.cleanData( getAll( this ) );
                +				if ( parent ) {
                +					parent.replaceChild( elem, this );
                +				}
                +			}
                +
                +		// Force callback invocation
                +		}, ignored );
                +	}
                +} );
                +
                +jQuery.each( {
                +	appendTo: "append",
                +	prependTo: "prepend",
                +	insertBefore: "before",
                +	insertAfter: "after",
                +	replaceAll: "replaceWith"
                +}, function( name, original ) {
                +	jQuery.fn[ name ] = function( selector ) {
                +		var elems,
                +			ret = [],
                +			insert = jQuery( selector ),
                +			last = insert.length - 1,
                +			i = 0;
                +
                +		for ( ; i <= last; i++ ) {
                +			elems = i === last ? this : this.clone( true );
                +			jQuery( insert[ i ] )[ original ]( elems );
                +
                +			// Support: Android <=4.0 only, PhantomJS 1 only
                +			// .get() because push.apply(_, arraylike) throws on ancient WebKit
                +			push.apply( ret, elems.get() );
                +		}
                +
                +		return this.pushStack( ret );
                +	};
                +} );
                +var rmargin = ( /^margin/ );
                +
                +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
                +
                +var getStyles = function( elem ) {
                +
                +		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
                +		// IE throws on elements created in popups
                +		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
                +		var view = elem.ownerDocument.defaultView;
                +
                +		if ( !view || !view.opener ) {
                +			view = window;
                +		}
                +
                +		return view.getComputedStyle( elem );
                +	};
                +
                +
                +
                +( function() {
                +
                +	// Executing both pixelPosition & boxSizingReliable tests require only one layout
                +	// so they're executed at the same time to save the second computation.
                +	function computeStyleTests() {
                +
                +		// This is a singleton, we need to execute it only once
                +		if ( !div ) {
                +			return;
                +		}
                +
                +		div.style.cssText =
                +			"box-sizing:border-box;" +
                +			"position:relative;display:block;" +
                +			"margin:auto;border:1px;padding:1px;" +
                +			"top:1%;width:50%";
                +		div.innerHTML = "";
                +		documentElement.appendChild( container );
                +
                +		var divStyle = window.getComputedStyle( div );
                +		pixelPositionVal = divStyle.top !== "1%";
                +
                +		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
                +		reliableMarginLeftVal = divStyle.marginLeft === "2px";
                +		boxSizingReliableVal = divStyle.width === "4px";
                +
                +		// Support: Android 4.0 - 4.3 only
                +		// Some styles come back with percentage values, even though they shouldn't
                +		div.style.marginRight = "50%";
                +		pixelMarginRightVal = divStyle.marginRight === "4px";
                +
                +		documentElement.removeChild( container );
                +
                +		// Nullify the div so it wouldn't be stored in the memory and
                +		// it will also be a sign that checks already performed
                +		div = null;
                +	}
                +
                +	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
                +		container = document.createElement( "div" ),
                +		div = document.createElement( "div" );
                +
                +	// Finish early in limited (non-browser) environments
                +	if ( !div.style ) {
                +		return;
                +	}
                +
                +	// Support: IE <=9 - 11 only
                +	// Style of cloned element affects source element cloned (#8908)
                +	div.style.backgroundClip = "content-box";
                +	div.cloneNode( true ).style.backgroundClip = "";
                +	support.clearCloneStyle = div.style.backgroundClip === "content-box";
                +
                +	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
                +		"padding:0;margin-top:1px;position:absolute";
                +	container.appendChild( div );
                +
                +	jQuery.extend( support, {
                +		pixelPosition: function() {
                +			computeStyleTests();
                +			return pixelPositionVal;
                +		},
                +		boxSizingReliable: function() {
                +			computeStyleTests();
                +			return boxSizingReliableVal;
                +		},
                +		pixelMarginRight: function() {
                +			computeStyleTests();
                +			return pixelMarginRightVal;
                +		},
                +		reliableMarginLeft: function() {
                +			computeStyleTests();
                +			return reliableMarginLeftVal;
                +		}
                +	} );
                +} )();
                +
                +
                +function curCSS( elem, name, computed ) {
                +	var width, minWidth, maxWidth, ret,
                +
                +		// Support: Firefox 51+
                +		// Retrieving style before computed somehow
                +		// fixes an issue with getting wrong values
                +		// on detached elements
                +		style = elem.style;
                +
                +	computed = computed || getStyles( elem );
                +
                +	// getPropertyValue is needed for:
                +	//   .css('filter') (IE 9 only, #12537)
                +	//   .css('--customProperty) (#3144)
                +	if ( computed ) {
                +		ret = computed.getPropertyValue( name ) || computed[ name ];
                +
                +		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
                +			ret = jQuery.style( elem, name );
                +		}
                +
                +		// A tribute to the "awesome hack by Dean Edwards"
                +		// Android Browser returns percentage for some values,
                +		// but width seems to be reliably pixels.
                +		// This is against the CSSOM draft spec:
                +		// https://drafts.csswg.org/cssom/#resolved-values
                +		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
                +
                +			// Remember the original values
                +			width = style.width;
                +			minWidth = style.minWidth;
                +			maxWidth = style.maxWidth;
                +
                +			// Put in the new values to get a computed value out
                +			style.minWidth = style.maxWidth = style.width = ret;
                +			ret = computed.width;
                +
                +			// Revert the changed values
                +			style.width = width;
                +			style.minWidth = minWidth;
                +			style.maxWidth = maxWidth;
                +		}
                +	}
                +
                +	return ret !== undefined ?
                +
                +		// Support: IE <=9 - 11 only
                +		// IE returns zIndex value as an integer.
                +		ret + "" :
                +		ret;
                +}
                +
                +
                +function addGetHookIf( conditionFn, hookFn ) {
                +
                +	// Define the hook, we'll check on the first run if it's really needed.
                +	return {
                +		get: function() {
                +			if ( conditionFn() ) {
                +
                +				// Hook not needed (or it's not possible to use it due
                +				// to missing dependency), remove it.
                +				delete this.get;
                +				return;
                +			}
                +
                +			// Hook needed; redefine it so that the support test is not executed again.
                +			return ( this.get = hookFn ).apply( this, arguments );
                +		}
                +	};
                +}
                +
                +
                +var
                +
                +	// Swappable if display is none or starts with table
                +	// except "table", "table-cell", or "table-caption"
                +	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
                +	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
                +	rcustomProp = /^--/,
                +	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
                +	cssNormalTransform = {
                +		letterSpacing: "0",
                +		fontWeight: "400"
                +	},
                +
                +	cssPrefixes = [ "Webkit", "Moz", "ms" ],
                +	emptyStyle = document.createElement( "div" ).style;
                +
                +// Return a css property mapped to a potentially vendor prefixed property
                +function vendorPropName( name ) {
                +
                +	// Shortcut for names that are not vendor prefixed
                +	if ( name in emptyStyle ) {
                +		return name;
                +	}
                +
                +	// Check for vendor prefixed names
                +	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
                +		i = cssPrefixes.length;
                +
                +	while ( i-- ) {
                +		name = cssPrefixes[ i ] + capName;
                +		if ( name in emptyStyle ) {
                +			return name;
                +		}
                +	}
                +}
                +
                +// Return a property mapped along what jQuery.cssProps suggests or to
                +// a vendor prefixed property.
                +function finalPropName( name ) {
                +	var ret = jQuery.cssProps[ name ];
                +	if ( !ret ) {
                +		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
                +	}
                +	return ret;
                +}
                +
                +function setPositiveNumber( elem, value, subtract ) {
                +
                +	// Any relative (+/-) values have already been
                +	// normalized at this point
                +	var matches = rcssNum.exec( value );
                +	return matches ?
                +
                +		// Guard against undefined "subtract", e.g., when used as in cssHooks
                +		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
                +		value;
                +}
                +
                +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
                +	var i,
                +		val = 0;
                +
                +	// If we already have the right measurement, avoid augmentation
                +	if ( extra === ( isBorderBox ? "border" : "content" ) ) {
                +		i = 4;
                +
                +	// Otherwise initialize for horizontal or vertical properties
                +	} else {
                +		i = name === "width" ? 1 : 0;
                +	}
                +
                +	for ( ; i < 4; i += 2 ) {
                +
                +		// Both box models exclude margin, so add it if we want it
                +		if ( extra === "margin" ) {
                +			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
                +		}
                +
                +		if ( isBorderBox ) {
                +
                +			// border-box includes padding, so remove it if we want content
                +			if ( extra === "content" ) {
                +				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
                +			}
                +
                +			// At this point, extra isn't border nor margin, so remove border
                +			if ( extra !== "margin" ) {
                +				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
                +			}
                +		} else {
                +
                +			// At this point, extra isn't content, so add padding
                +			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
                +
                +			// At this point, extra isn't content nor padding, so add border
                +			if ( extra !== "padding" ) {
                +				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
                +			}
                +		}
                +	}
                +
                +	return val;
                +}
                +
                +function getWidthOrHeight( elem, name, extra ) {
                +
                +	// Start with computed style
                +	var valueIsBorderBox,
                +		styles = getStyles( elem ),
                +		val = curCSS( elem, name, styles ),
                +		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
                +
                +	// Computed unit is not pixels. Stop here and return.
                +	if ( rnumnonpx.test( val ) ) {
                +		return val;
                +	}
                +
                +	// Check for style in case a browser which returns unreliable values
                +	// for getComputedStyle silently falls back to the reliable elem.style
                +	valueIsBorderBox = isBorderBox &&
                +		( support.boxSizingReliable() || val === elem.style[ name ] );
                +
                +	// Fall back to offsetWidth/Height when value is "auto"
                +	// This happens for inline elements with no explicit setting (gh-3571)
                +	if ( val === "auto" ) {
                +		val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
                +	}
                +
                +	// Normalize "", auto, and prepare for extra
                +	val = parseFloat( val ) || 0;
                +
                +	// Use the active box-sizing model to add/subtract irrelevant styles
                +	return ( val +
                +		augmentWidthOrHeight(
                +			elem,
                +			name,
                +			extra || ( isBorderBox ? "border" : "content" ),
                +			valueIsBorderBox,
                +			styles
                +		)
                +	) + "px";
                +}
                +
                +jQuery.extend( {
                +
                +	// Add in style property hooks for overriding the default
                +	// behavior of getting and setting a style property
                +	cssHooks: {
                +		opacity: {
                +			get: function( elem, computed ) {
                +				if ( computed ) {
                +
                +					// We should always get a number back from opacity
                +					var ret = curCSS( elem, "opacity" );
                +					return ret === "" ? "1" : ret;
                +				}
                +			}
                +		}
                +	},
                +
                +	// Don't automatically add "px" to these possibly-unitless properties
                +	cssNumber: {
                +		"animationIterationCount": true,
                +		"columnCount": true,
                +		"fillOpacity": true,
                +		"flexGrow": true,
                +		"flexShrink": true,
                +		"fontWeight": true,
                +		"lineHeight": true,
                +		"opacity": true,
                +		"order": true,
                +		"orphans": true,
                +		"widows": true,
                +		"zIndex": true,
                +		"zoom": true
                +	},
                +
                +	// Add in properties whose names you wish to fix before
                +	// setting or getting the value
                +	cssProps: {
                +		"float": "cssFloat"
                +	},
                +
                +	// Get and set the style property on a DOM Node
                +	style: function( elem, name, value, extra ) {
                +
                +		// Don't set styles on text and comment nodes
                +		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
                +			return;
                +		}
                +
                +		// Make sure that we're working with the right name
                +		var ret, type, hooks,
                +			origName = jQuery.camelCase( name ),
                +			isCustomProp = rcustomProp.test( name ),
                +			style = elem.style;
                +
                +		// Make sure that we're working with the right name. We don't
                +		// want to query the value if it is a CSS custom property
                +		// since they are user-defined.
                +		if ( !isCustomProp ) {
                +			name = finalPropName( origName );
                +		}
                +
                +		// Gets hook for the prefixed version, then unprefixed version
                +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
                +
                +		// Check if we're setting a value
                +		if ( value !== undefined ) {
                +			type = typeof value;
                +
                +			// Convert "+=" or "-=" to relative numbers (#7345)
                +			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
                +				value = adjustCSS( elem, name, ret );
                +
                +				// Fixes bug #9237
                +				type = "number";
                +			}
                +
                +			// Make sure that null and NaN values aren't set (#7116)
                +			if ( value == null || value !== value ) {
                +				return;
                +			}
                +
                +			// If a number was passed in, add the unit (except for certain CSS properties)
                +			if ( type === "number" ) {
                +				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
                +			}
                +
                +			// background-* props affect original clone's values
                +			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
                +				style[ name ] = "inherit";
                +			}
                +
                +			// If a hook was provided, use that value, otherwise just set the specified value
                +			if ( !hooks || !( "set" in hooks ) ||
                +				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
                +
                +				if ( isCustomProp ) {
                +					style.setProperty( name, value );
                +				} else {
                +					style[ name ] = value;
                +				}
                +			}
                +
                +		} else {
                +
                +			// If a hook was provided get the non-computed value from there
                +			if ( hooks && "get" in hooks &&
                +				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
                +
                +				return ret;
                +			}
                +
                +			// Otherwise just get the value from the style object
                +			return style[ name ];
                +		}
                +	},
                +
                +	css: function( elem, name, extra, styles ) {
                +		var val, num, hooks,
                +			origName = jQuery.camelCase( name ),
                +			isCustomProp = rcustomProp.test( name );
                +
                +		// Make sure that we're working with the right name. We don't
                +		// want to modify the value if it is a CSS custom property
                +		// since they are user-defined.
                +		if ( !isCustomProp ) {
                +			name = finalPropName( origName );
                +		}
                +
                +		// Try prefixed name followed by the unprefixed name
                +		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
                +
                +		// If a hook was provided get the computed value from there
                +		if ( hooks && "get" in hooks ) {
                +			val = hooks.get( elem, true, extra );
                +		}
                +
                +		// Otherwise, if a way to get the computed value exists, use that
                +		if ( val === undefined ) {
                +			val = curCSS( elem, name, styles );
                +		}
                +
                +		// Convert "normal" to computed value
                +		if ( val === "normal" && name in cssNormalTransform ) {
                +			val = cssNormalTransform[ name ];
                +		}
                +
                +		// Make numeric if forced or a qualifier was provided and val looks numeric
                +		if ( extra === "" || extra ) {
                +			num = parseFloat( val );
                +			return extra === true || isFinite( num ) ? num || 0 : val;
                +		}
                +
                +		return val;
                +	}
                +} );
                +
                +jQuery.each( [ "height", "width" ], function( i, name ) {
                +	jQuery.cssHooks[ name ] = {
                +		get: function( elem, computed, extra ) {
                +			if ( computed ) {
                +
                +				// Certain elements can have dimension info if we invisibly show them
                +				// but it must have a current display style that would benefit
                +				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
                +
                +					// Support: Safari 8+
                +					// Table columns in Safari have non-zero offsetWidth & zero
                +					// getBoundingClientRect().width unless display is changed.
                +					// Support: IE <=11 only
                +					// Running getBoundingClientRect on a disconnected node
                +					// in IE throws an error.
                +					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
                +						swap( elem, cssShow, function() {
                +							return getWidthOrHeight( elem, name, extra );
                +						} ) :
                +						getWidthOrHeight( elem, name, extra );
                +			}
                +		},
                +
                +		set: function( elem, value, extra ) {
                +			var matches,
                +				styles = extra && getStyles( elem ),
                +				subtract = extra && augmentWidthOrHeight(
                +					elem,
                +					name,
                +					extra,
                +					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
                +					styles
                +				);
                +
                +			// Convert to pixels if value adjustment is needed
                +			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
                +				( matches[ 3 ] || "px" ) !== "px" ) {
                +
                +				elem.style[ name ] = value;
                +				value = jQuery.css( elem, name );
                +			}
                +
                +			return setPositiveNumber( elem, value, subtract );
                +		}
                +	};
                +} );
                +
                +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
                +	function( elem, computed ) {
                +		if ( computed ) {
                +			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
                +				elem.getBoundingClientRect().left -
                +					swap( elem, { marginLeft: 0 }, function() {
                +						return elem.getBoundingClientRect().left;
                +					} )
                +				) + "px";
                +		}
                +	}
                +);
                +
                +// These hooks are used by animate to expand properties
                +jQuery.each( {
                +	margin: "",
                +	padding: "",
                +	border: "Width"
                +}, function( prefix, suffix ) {
                +	jQuery.cssHooks[ prefix + suffix ] = {
                +		expand: function( value ) {
                +			var i = 0,
                +				expanded = {},
                +
                +				// Assumes a single number if not a string
                +				parts = typeof value === "string" ? value.split( " " ) : [ value ];
                +
                +			for ( ; i < 4; i++ ) {
                +				expanded[ prefix + cssExpand[ i ] + suffix ] =
                +					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
                +			}
                +
                +			return expanded;
                +		}
                +	};
                +
                +	if ( !rmargin.test( prefix ) ) {
                +		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
                +	}
                +} );
                +
                +jQuery.fn.extend( {
                +	css: function( name, value ) {
                +		return access( this, function( elem, name, value ) {
                +			var styles, len,
                +				map = {},
                +				i = 0;
                +
                +			if ( Array.isArray( name ) ) {
                +				styles = getStyles( elem );
                +				len = name.length;
                +
                +				for ( ; i < len; i++ ) {
                +					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
                +				}
                +
                +				return map;
                +			}
                +
                +			return value !== undefined ?
                +				jQuery.style( elem, name, value ) :
                +				jQuery.css( elem, name );
                +		}, name, value, arguments.length > 1 );
                +	}
                +} );
                +
                +
                +function Tween( elem, options, prop, end, easing ) {
                +	return new Tween.prototype.init( elem, options, prop, end, easing );
                +}
                +jQuery.Tween = Tween;
                +
                +Tween.prototype = {
                +	constructor: Tween,
                +	init: function( elem, options, prop, end, easing, unit ) {
                +		this.elem = elem;
                +		this.prop = prop;
                +		this.easing = easing || jQuery.easing._default;
                +		this.options = options;
                +		this.start = this.now = this.cur();
                +		this.end = end;
                +		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
                +	},
                +	cur: function() {
                +		var hooks = Tween.propHooks[ this.prop ];
                +
                +		return hooks && hooks.get ?
                +			hooks.get( this ) :
                +			Tween.propHooks._default.get( this );
                +	},
                +	run: function( percent ) {
                +		var eased,
                +			hooks = Tween.propHooks[ this.prop ];
                +
                +		if ( this.options.duration ) {
                +			this.pos = eased = jQuery.easing[ this.easing ](
                +				percent, this.options.duration * percent, 0, 1, this.options.duration
                +			);
                +		} else {
                +			this.pos = eased = percent;
                +		}
                +		this.now = ( this.end - this.start ) * eased + this.start;
                +
                +		if ( this.options.step ) {
                +			this.options.step.call( this.elem, this.now, this );
                +		}
                +
                +		if ( hooks && hooks.set ) {
                +			hooks.set( this );
                +		} else {
                +			Tween.propHooks._default.set( this );
                +		}
                +		return this;
                +	}
                +};
                +
                +Tween.prototype.init.prototype = Tween.prototype;
                +
                +Tween.propHooks = {
                +	_default: {
                +		get: function( tween ) {
                +			var result;
                +
                +			// Use a property on the element directly when it is not a DOM element,
                +			// or when there is no matching style property that exists.
                +			if ( tween.elem.nodeType !== 1 ||
                +				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
                +				return tween.elem[ tween.prop ];
                +			}
                +
                +			// Passing an empty string as a 3rd parameter to .css will automatically
                +			// attempt a parseFloat and fallback to a string if the parse fails.
                +			// Simple values such as "10px" are parsed to Float;
                +			// complex values such as "rotate(1rad)" are returned as-is.
                +			result = jQuery.css( tween.elem, tween.prop, "" );
                +
                +			// Empty strings, null, undefined and "auto" are converted to 0.
                +			return !result || result === "auto" ? 0 : result;
                +		},
                +		set: function( tween ) {
                +
                +			// Use step hook for back compat.
                +			// Use cssHook if its there.
                +			// Use .style if available and use plain properties where available.
                +			if ( jQuery.fx.step[ tween.prop ] ) {
                +				jQuery.fx.step[ tween.prop ]( tween );
                +			} else if ( tween.elem.nodeType === 1 &&
                +				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
                +					jQuery.cssHooks[ tween.prop ] ) ) {
                +				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
                +			} else {
                +				tween.elem[ tween.prop ] = tween.now;
                +			}
                +		}
                +	}
                +};
                +
                +// Support: IE <=9 only
                +// Panic based approach to setting things on disconnected nodes
                +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
                +	set: function( tween ) {
                +		if ( tween.elem.nodeType && tween.elem.parentNode ) {
                +			tween.elem[ tween.prop ] = tween.now;
                +		}
                +	}
                +};
                +
                +jQuery.easing = {
                +	linear: function( p ) {
                +		return p;
                +	},
                +	swing: function( p ) {
                +		return 0.5 - Math.cos( p * Math.PI ) / 2;
                +	},
                +	_default: "swing"
                +};
                +
                +jQuery.fx = Tween.prototype.init;
                +
                +// Back compat <1.8 extension point
                +jQuery.fx.step = {};
                +
                +
                +
                +
                +var
                +	fxNow, inProgress,
                +	rfxtypes = /^(?:toggle|show|hide)$/,
                +	rrun = /queueHooks$/;
                +
                +function schedule() {
                +	if ( inProgress ) {
                +		if ( document.hidden === false && window.requestAnimationFrame ) {
                +			window.requestAnimationFrame( schedule );
                +		} else {
                +			window.setTimeout( schedule, jQuery.fx.interval );
                +		}
                +
                +		jQuery.fx.tick();
                +	}
                +}
                +
                +// Animations created synchronously will run synchronously
                +function createFxNow() {
                +	window.setTimeout( function() {
                +		fxNow = undefined;
                +	} );
                +	return ( fxNow = jQuery.now() );
                +}
                +
                +// Generate parameters to create a standard animation
                +function genFx( type, includeWidth ) {
                +	var which,
                +		i = 0,
                +		attrs = { height: type };
                +
                +	// If we include width, step value is 1 to do all cssExpand values,
                +	// otherwise step value is 2 to skip over Left and Right
                +	includeWidth = includeWidth ? 1 : 0;
                +	for ( ; i < 4; i += 2 - includeWidth ) {
                +		which = cssExpand[ i ];
                +		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
                +	}
                +
                +	if ( includeWidth ) {
                +		attrs.opacity = attrs.width = type;
                +	}
                +
                +	return attrs;
                +}
                +
                +function createTween( value, prop, animation ) {
                +	var tween,
                +		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
                +		index = 0,
                +		length = collection.length;
                +	for ( ; index < length; index++ ) {
                +		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
                +
                +			// We're done with this property
                +			return tween;
                +		}
                +	}
                +}
                +
                +function defaultPrefilter( elem, props, opts ) {
                +	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
                +		isBox = "width" in props || "height" in props,
                +		anim = this,
                +		orig = {},
                +		style = elem.style,
                +		hidden = elem.nodeType && isHiddenWithinTree( elem ),
                +		dataShow = dataPriv.get( elem, "fxshow" );
                +
                +	// Queue-skipping animations hijack the fx hooks
                +	if ( !opts.queue ) {
                +		hooks = jQuery._queueHooks( elem, "fx" );
                +		if ( hooks.unqueued == null ) {
                +			hooks.unqueued = 0;
                +			oldfire = hooks.empty.fire;
                +			hooks.empty.fire = function() {
                +				if ( !hooks.unqueued ) {
                +					oldfire();
                +				}
                +			};
                +		}
                +		hooks.unqueued++;
                +
                +		anim.always( function() {
                +
                +			// Ensure the complete handler is called before this completes
                +			anim.always( function() {
                +				hooks.unqueued--;
                +				if ( !jQuery.queue( elem, "fx" ).length ) {
                +					hooks.empty.fire();
                +				}
                +			} );
                +		} );
                +	}
                +
                +	// Detect show/hide animations
                +	for ( prop in props ) {
                +		value = props[ prop ];
                +		if ( rfxtypes.test( value ) ) {
                +			delete props[ prop ];
                +			toggle = toggle || value === "toggle";
                +			if ( value === ( hidden ? "hide" : "show" ) ) {
                +
                +				// Pretend to be hidden if this is a "show" and
                +				// there is still data from a stopped show/hide
                +				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
                +					hidden = true;
                +
                +				// Ignore all other no-op show/hide data
                +				} else {
                +					continue;
                +				}
                +			}
                +			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
                +		}
                +	}
                +
                +	// Bail out if this is a no-op like .hide().hide()
                +	propTween = !jQuery.isEmptyObject( props );
                +	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
                +		return;
                +	}
                +
                +	// Restrict "overflow" and "display" styles during box animations
                +	if ( isBox && elem.nodeType === 1 ) {
                +
                +		// Support: IE <=9 - 11, Edge 12 - 13
                +		// Record all 3 overflow attributes because IE does not infer the shorthand
                +		// from identically-valued overflowX and overflowY
                +		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
                +
                +		// Identify a display type, preferring old show/hide data over the CSS cascade
                +		restoreDisplay = dataShow && dataShow.display;
                +		if ( restoreDisplay == null ) {
                +			restoreDisplay = dataPriv.get( elem, "display" );
                +		}
                +		display = jQuery.css( elem, "display" );
                +		if ( display === "none" ) {
                +			if ( restoreDisplay ) {
                +				display = restoreDisplay;
                +			} else {
                +
                +				// Get nonempty value(s) by temporarily forcing visibility
                +				showHide( [ elem ], true );
                +				restoreDisplay = elem.style.display || restoreDisplay;
                +				display = jQuery.css( elem, "display" );
                +				showHide( [ elem ] );
                +			}
                +		}
                +
                +		// Animate inline elements as inline-block
                +		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
                +			if ( jQuery.css( elem, "float" ) === "none" ) {
                +
                +				// Restore the original display value at the end of pure show/hide animations
                +				if ( !propTween ) {
                +					anim.done( function() {
                +						style.display = restoreDisplay;
                +					} );
                +					if ( restoreDisplay == null ) {
                +						display = style.display;
                +						restoreDisplay = display === "none" ? "" : display;
                +					}
                +				}
                +				style.display = "inline-block";
                +			}
                +		}
                +	}
                +
                +	if ( opts.overflow ) {
                +		style.overflow = "hidden";
                +		anim.always( function() {
                +			style.overflow = opts.overflow[ 0 ];
                +			style.overflowX = opts.overflow[ 1 ];
                +			style.overflowY = opts.overflow[ 2 ];
                +		} );
                +	}
                +
                +	// Implement show/hide animations
                +	propTween = false;
                +	for ( prop in orig ) {
                +
                +		// General show/hide setup for this element animation
                +		if ( !propTween ) {
                +			if ( dataShow ) {
                +				if ( "hidden" in dataShow ) {
                +					hidden = dataShow.hidden;
                +				}
                +			} else {
                +				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
                +			}
                +
                +			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
                +			if ( toggle ) {
                +				dataShow.hidden = !hidden;
                +			}
                +
                +			// Show elements before animating them
                +			if ( hidden ) {
                +				showHide( [ elem ], true );
                +			}
                +
                +			/* eslint-disable no-loop-func */
                +
                +			anim.done( function() {
                +
                +			/* eslint-enable no-loop-func */
                +
                +				// The final step of a "hide" animation is actually hiding the element
                +				if ( !hidden ) {
                +					showHide( [ elem ] );
                +				}
                +				dataPriv.remove( elem, "fxshow" );
                +				for ( prop in orig ) {
                +					jQuery.style( elem, prop, orig[ prop ] );
                +				}
                +			} );
                +		}
                +
                +		// Per-property setup
                +		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
                +		if ( !( prop in dataShow ) ) {
                +			dataShow[ prop ] = propTween.start;
                +			if ( hidden ) {
                +				propTween.end = propTween.start;
                +				propTween.start = 0;
                +			}
                +		}
                +	}
                +}
                +
                +function propFilter( props, specialEasing ) {
                +	var index, name, easing, value, hooks;
                +
                +	// camelCase, specialEasing and expand cssHook pass
                +	for ( index in props ) {
                +		name = jQuery.camelCase( index );
                +		easing = specialEasing[ name ];
                +		value = props[ index ];
                +		if ( Array.isArray( value ) ) {
                +			easing = value[ 1 ];
                +			value = props[ index ] = value[ 0 ];
                +		}
                +
                +		if ( index !== name ) {
                +			props[ name ] = value;
                +			delete props[ index ];
                +		}
                +
                +		hooks = jQuery.cssHooks[ name ];
                +		if ( hooks && "expand" in hooks ) {
                +			value = hooks.expand( value );
                +			delete props[ name ];
                +
                +			// Not quite $.extend, this won't overwrite existing keys.
                +			// Reusing 'index' because we have the correct "name"
                +			for ( index in value ) {
                +				if ( !( index in props ) ) {
                +					props[ index ] = value[ index ];
                +					specialEasing[ index ] = easing;
                +				}
                +			}
                +		} else {
                +			specialEasing[ name ] = easing;
                +		}
                +	}
                +}
                +
                +function Animation( elem, properties, options ) {
                +	var result,
                +		stopped,
                +		index = 0,
                +		length = Animation.prefilters.length,
                +		deferred = jQuery.Deferred().always( function() {
                +
                +			// Don't match elem in the :animated selector
                +			delete tick.elem;
                +		} ),
                +		tick = function() {
                +			if ( stopped ) {
                +				return false;
                +			}
                +			var currentTime = fxNow || createFxNow(),
                +				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
                +
                +				// Support: Android 2.3 only
                +				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
                +				temp = remaining / animation.duration || 0,
                +				percent = 1 - temp,
                +				index = 0,
                +				length = animation.tweens.length;
                +
                +			for ( ; index < length; index++ ) {
                +				animation.tweens[ index ].run( percent );
                +			}
                +
                +			deferred.notifyWith( elem, [ animation, percent, remaining ] );
                +
                +			// If there's more to do, yield
                +			if ( percent < 1 && length ) {
                +				return remaining;
                +			}
                +
                +			// If this was an empty animation, synthesize a final progress notification
                +			if ( !length ) {
                +				deferred.notifyWith( elem, [ animation, 1, 0 ] );
                +			}
                +
                +			// Resolve the animation and report its conclusion
                +			deferred.resolveWith( elem, [ animation ] );
                +			return false;
                +		},
                +		animation = deferred.promise( {
                +			elem: elem,
                +			props: jQuery.extend( {}, properties ),
                +			opts: jQuery.extend( true, {
                +				specialEasing: {},
                +				easing: jQuery.easing._default
                +			}, options ),
                +			originalProperties: properties,
                +			originalOptions: options,
                +			startTime: fxNow || createFxNow(),
                +			duration: options.duration,
                +			tweens: [],
                +			createTween: function( prop, end ) {
                +				var tween = jQuery.Tween( elem, animation.opts, prop, end,
                +						animation.opts.specialEasing[ prop ] || animation.opts.easing );
                +				animation.tweens.push( tween );
                +				return tween;
                +			},
                +			stop: function( gotoEnd ) {
                +				var index = 0,
                +
                +					// If we are going to the end, we want to run all the tweens
                +					// otherwise we skip this part
                +					length = gotoEnd ? animation.tweens.length : 0;
                +				if ( stopped ) {
                +					return this;
                +				}
                +				stopped = true;
                +				for ( ; index < length; index++ ) {
                +					animation.tweens[ index ].run( 1 );
                +				}
                +
                +				// Resolve when we played the last frame; otherwise, reject
                +				if ( gotoEnd ) {
                +					deferred.notifyWith( elem, [ animation, 1, 0 ] );
                +					deferred.resolveWith( elem, [ animation, gotoEnd ] );
                +				} else {
                +					deferred.rejectWith( elem, [ animation, gotoEnd ] );
                +				}
                +				return this;
                +			}
                +		} ),
                +		props = animation.props;
                +
                +	propFilter( props, animation.opts.specialEasing );
                +
                +	for ( ; index < length; index++ ) {
                +		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
                +		if ( result ) {
                +			if ( jQuery.isFunction( result.stop ) ) {
                +				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
                +					jQuery.proxy( result.stop, result );
                +			}
                +			return result;
                +		}
                +	}
                +
                +	jQuery.map( props, createTween, animation );
                +
                +	if ( jQuery.isFunction( animation.opts.start ) ) {
                +		animation.opts.start.call( elem, animation );
                +	}
                +
                +	// Attach callbacks from options
                +	animation
                +		.progress( animation.opts.progress )
                +		.done( animation.opts.done, animation.opts.complete )
                +		.fail( animation.opts.fail )
                +		.always( animation.opts.always );
                +
                +	jQuery.fx.timer(
                +		jQuery.extend( tick, {
                +			elem: elem,
                +			anim: animation,
                +			queue: animation.opts.queue
                +		} )
                +	);
                +
                +	return animation;
                +}
                +
                +jQuery.Animation = jQuery.extend( Animation, {
                +
                +	tweeners: {
                +		"*": [ function( prop, value ) {
                +			var tween = this.createTween( prop, value );
                +			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
                +			return tween;
                +		} ]
                +	},
                +
                +	tweener: function( props, callback ) {
                +		if ( jQuery.isFunction( props ) ) {
                +			callback = props;
                +			props = [ "*" ];
                +		} else {
                +			props = props.match( rnothtmlwhite );
                +		}
                +
                +		var prop,
                +			index = 0,
                +			length = props.length;
                +
                +		for ( ; index < length; index++ ) {
                +			prop = props[ index ];
                +			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
                +			Animation.tweeners[ prop ].unshift( callback );
                +		}
                +	},
                +
                +	prefilters: [ defaultPrefilter ],
                +
                +	prefilter: function( callback, prepend ) {
                +		if ( prepend ) {
                +			Animation.prefilters.unshift( callback );
                +		} else {
                +			Animation.prefilters.push( callback );
                +		}
                +	}
                +} );
                +
                +jQuery.speed = function( speed, easing, fn ) {
                +	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
                +		complete: fn || !fn && easing ||
                +			jQuery.isFunction( speed ) && speed,
                +		duration: speed,
                +		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
                +	};
                +
                +	// Go to the end state if fx are off
                +	if ( jQuery.fx.off ) {
                +		opt.duration = 0;
                +
                +	} else {
                +		if ( typeof opt.duration !== "number" ) {
                +			if ( opt.duration in jQuery.fx.speeds ) {
                +				opt.duration = jQuery.fx.speeds[ opt.duration ];
                +
                +			} else {
                +				opt.duration = jQuery.fx.speeds._default;
                +			}
                +		}
                +	}
                +
                +	// Normalize opt.queue - true/undefined/null -> "fx"
                +	if ( opt.queue == null || opt.queue === true ) {
                +		opt.queue = "fx";
                +	}
                +
                +	// Queueing
                +	opt.old = opt.complete;
                +
                +	opt.complete = function() {
                +		if ( jQuery.isFunction( opt.old ) ) {
                +			opt.old.call( this );
                +		}
                +
                +		if ( opt.queue ) {
                +			jQuery.dequeue( this, opt.queue );
                +		}
                +	};
                +
                +	return opt;
                +};
                +
                +jQuery.fn.extend( {
                +	fadeTo: function( speed, to, easing, callback ) {
                +
                +		// Show any hidden elements after setting opacity to 0
                +		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
                +
                +			// Animate to the value specified
                +			.end().animate( { opacity: to }, speed, easing, callback );
                +	},
                +	animate: function( prop, speed, easing, callback ) {
                +		var empty = jQuery.isEmptyObject( prop ),
                +			optall = jQuery.speed( speed, easing, callback ),
                +			doAnimation = function() {
                +
                +				// Operate on a copy of prop so per-property easing won't be lost
                +				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
                +
                +				// Empty animations, or finishing resolves immediately
                +				if ( empty || dataPriv.get( this, "finish" ) ) {
                +					anim.stop( true );
                +				}
                +			};
                +			doAnimation.finish = doAnimation;
                +
                +		return empty || optall.queue === false ?
                +			this.each( doAnimation ) :
                +			this.queue( optall.queue, doAnimation );
                +	},
                +	stop: function( type, clearQueue, gotoEnd ) {
                +		var stopQueue = function( hooks ) {
                +			var stop = hooks.stop;
                +			delete hooks.stop;
                +			stop( gotoEnd );
                +		};
                +
                +		if ( typeof type !== "string" ) {
                +			gotoEnd = clearQueue;
                +			clearQueue = type;
                +			type = undefined;
                +		}
                +		if ( clearQueue && type !== false ) {
                +			this.queue( type || "fx", [] );
                +		}
                +
                +		return this.each( function() {
                +			var dequeue = true,
                +				index = type != null && type + "queueHooks",
                +				timers = jQuery.timers,
                +				data = dataPriv.get( this );
                +
                +			if ( index ) {
                +				if ( data[ index ] && data[ index ].stop ) {
                +					stopQueue( data[ index ] );
                +				}
                +			} else {
                +				for ( index in data ) {
                +					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
                +						stopQueue( data[ index ] );
                +					}
                +				}
                +			}
                +
                +			for ( index = timers.length; index--; ) {
                +				if ( timers[ index ].elem === this &&
                +					( type == null || timers[ index ].queue === type ) ) {
                +
                +					timers[ index ].anim.stop( gotoEnd );
                +					dequeue = false;
                +					timers.splice( index, 1 );
                +				}
                +			}
                +
                +			// Start the next in the queue if the last step wasn't forced.
                +			// Timers currently will call their complete callbacks, which
                +			// will dequeue but only if they were gotoEnd.
                +			if ( dequeue || !gotoEnd ) {
                +				jQuery.dequeue( this, type );
                +			}
                +		} );
                +	},
                +	finish: function( type ) {
                +		if ( type !== false ) {
                +			type = type || "fx";
                +		}
                +		return this.each( function() {
                +			var index,
                +				data = dataPriv.get( this ),
                +				queue = data[ type + "queue" ],
                +				hooks = data[ type + "queueHooks" ],
                +				timers = jQuery.timers,
                +				length = queue ? queue.length : 0;
                +
                +			// Enable finishing flag on private data
                +			data.finish = true;
                +
                +			// Empty the queue first
                +			jQuery.queue( this, type, [] );
                +
                +			if ( hooks && hooks.stop ) {
                +				hooks.stop.call( this, true );
                +			}
                +
                +			// Look for any active animations, and finish them
                +			for ( index = timers.length; index--; ) {
                +				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
                +					timers[ index ].anim.stop( true );
                +					timers.splice( index, 1 );
                +				}
                +			}
                +
                +			// Look for any animations in the old queue and finish them
                +			for ( index = 0; index < length; index++ ) {
                +				if ( queue[ index ] && queue[ index ].finish ) {
                +					queue[ index ].finish.call( this );
                +				}
                +			}
                +
                +			// Turn off finishing flag
                +			delete data.finish;
                +		} );
                +	}
                +} );
                +
                +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
                +	var cssFn = jQuery.fn[ name ];
                +	jQuery.fn[ name ] = function( speed, easing, callback ) {
                +		return speed == null || typeof speed === "boolean" ?
                +			cssFn.apply( this, arguments ) :
                +			this.animate( genFx( name, true ), speed, easing, callback );
                +	};
                +} );
                +
                +// Generate shortcuts for custom animations
                +jQuery.each( {
                +	slideDown: genFx( "show" ),
                +	slideUp: genFx( "hide" ),
                +	slideToggle: genFx( "toggle" ),
                +	fadeIn: { opacity: "show" },
                +	fadeOut: { opacity: "hide" },
                +	fadeToggle: { opacity: "toggle" }
                +}, function( name, props ) {
                +	jQuery.fn[ name ] = function( speed, easing, callback ) {
                +		return this.animate( props, speed, easing, callback );
                +	};
                +} );
                +
                +jQuery.timers = [];
                +jQuery.fx.tick = function() {
                +	var timer,
                +		i = 0,
                +		timers = jQuery.timers;
                +
                +	fxNow = jQuery.now();
                +
                +	for ( ; i < timers.length; i++ ) {
                +		timer = timers[ i ];
                +
                +		// Run the timer and safely remove it when done (allowing for external removal)
                +		if ( !timer() && timers[ i ] === timer ) {
                +			timers.splice( i--, 1 );
                +		}
                +	}
                +
                +	if ( !timers.length ) {
                +		jQuery.fx.stop();
                +	}
                +	fxNow = undefined;
                +};
                +
                +jQuery.fx.timer = function( timer ) {
                +	jQuery.timers.push( timer );
                +	jQuery.fx.start();
                +};
                +
                +jQuery.fx.interval = 13;
                +jQuery.fx.start = function() {
                +	if ( inProgress ) {
                +		return;
                +	}
                +
                +	inProgress = true;
                +	schedule();
                +};
                +
                +jQuery.fx.stop = function() {
                +	inProgress = null;
                +};
                +
                +jQuery.fx.speeds = {
                +	slow: 600,
                +	fast: 200,
                +
                +	// Default speed
                +	_default: 400
                +};
                +
                +
                +// Based off of the plugin by Clint Helfers, with permission.
                +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
                +jQuery.fn.delay = function( time, type ) {
                +	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
                +	type = type || "fx";
                +
                +	return this.queue( type, function( next, hooks ) {
                +		var timeout = window.setTimeout( next, time );
                +		hooks.stop = function() {
                +			window.clearTimeout( timeout );
                +		};
                +	} );
                +};
                +
                +
                +( function() {
                +	var input = document.createElement( "input" ),
                +		select = document.createElement( "select" ),
                +		opt = select.appendChild( document.createElement( "option" ) );
                +
                +	input.type = "checkbox";
                +
                +	// Support: Android <=4.3 only
                +	// Default value for a checkbox should be "on"
                +	support.checkOn = input.value !== "";
                +
                +	// Support: IE <=11 only
                +	// Must access selectedIndex to make default options select
                +	support.optSelected = opt.selected;
                +
                +	// Support: IE <=11 only
                +	// An input loses its value after becoming a radio
                +	input = document.createElement( "input" );
                +	input.value = "t";
                +	input.type = "radio";
                +	support.radioValue = input.value === "t";
                +} )();
                +
                +
                +var boolHook,
                +	attrHandle = jQuery.expr.attrHandle;
                +
                +jQuery.fn.extend( {
                +	attr: function( name, value ) {
                +		return access( this, jQuery.attr, name, value, arguments.length > 1 );
                +	},
                +
                +	removeAttr: function( name ) {
                +		return this.each( function() {
                +			jQuery.removeAttr( this, name );
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	attr: function( elem, name, value ) {
                +		var ret, hooks,
                +			nType = elem.nodeType;
                +
                +		// Don't get/set attributes on text, comment and attribute nodes
                +		if ( nType === 3 || nType === 8 || nType === 2 ) {
                +			return;
                +		}
                +
                +		// Fallback to prop when attributes are not supported
                +		if ( typeof elem.getAttribute === "undefined" ) {
                +			return jQuery.prop( elem, name, value );
                +		}
                +
                +		// Attribute hooks are determined by the lowercase version
                +		// Grab necessary hook if one is defined
                +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
                +			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
                +				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
                +		}
                +
                +		if ( value !== undefined ) {
                +			if ( value === null ) {
                +				jQuery.removeAttr( elem, name );
                +				return;
                +			}
                +
                +			if ( hooks && "set" in hooks &&
                +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                +				return ret;
                +			}
                +
                +			elem.setAttribute( name, value + "" );
                +			return value;
                +		}
                +
                +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
                +			return ret;
                +		}
                +
                +		ret = jQuery.find.attr( elem, name );
                +
                +		// Non-existent attributes return null, we normalize to undefined
                +		return ret == null ? undefined : ret;
                +	},
                +
                +	attrHooks: {
                +		type: {
                +			set: function( elem, value ) {
                +				if ( !support.radioValue && value === "radio" &&
                +					nodeName( elem, "input" ) ) {
                +					var val = elem.value;
                +					elem.setAttribute( "type", value );
                +					if ( val ) {
                +						elem.value = val;
                +					}
                +					return value;
                +				}
                +			}
                +		}
                +	},
                +
                +	removeAttr: function( elem, value ) {
                +		var name,
                +			i = 0,
                +
                +			// Attribute names can contain non-HTML whitespace characters
                +			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
                +			attrNames = value && value.match( rnothtmlwhite );
                +
                +		if ( attrNames && elem.nodeType === 1 ) {
                +			while ( ( name = attrNames[ i++ ] ) ) {
                +				elem.removeAttribute( name );
                +			}
                +		}
                +	}
                +} );
                +
                +// Hooks for boolean attributes
                +boolHook = {
                +	set: function( elem, value, name ) {
                +		if ( value === false ) {
                +
                +			// Remove boolean attributes when set to false
                +			jQuery.removeAttr( elem, name );
                +		} else {
                +			elem.setAttribute( name, name );
                +		}
                +		return name;
                +	}
                +};
                +
                +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
                +	var getter = attrHandle[ name ] || jQuery.find.attr;
                +
                +	attrHandle[ name ] = function( elem, name, isXML ) {
                +		var ret, handle,
                +			lowercaseName = name.toLowerCase();
                +
                +		if ( !isXML ) {
                +
                +			// Avoid an infinite loop by temporarily removing this function from the getter
                +			handle = attrHandle[ lowercaseName ];
                +			attrHandle[ lowercaseName ] = ret;
                +			ret = getter( elem, name, isXML ) != null ?
                +				lowercaseName :
                +				null;
                +			attrHandle[ lowercaseName ] = handle;
                +		}
                +		return ret;
                +	};
                +} );
                +
                +
                +
                +
                +var rfocusable = /^(?:input|select|textarea|button)$/i,
                +	rclickable = /^(?:a|area)$/i;
                +
                +jQuery.fn.extend( {
                +	prop: function( name, value ) {
                +		return access( this, jQuery.prop, name, value, arguments.length > 1 );
                +	},
                +
                +	removeProp: function( name ) {
                +		return this.each( function() {
                +			delete this[ jQuery.propFix[ name ] || name ];
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	prop: function( elem, name, value ) {
                +		var ret, hooks,
                +			nType = elem.nodeType;
                +
                +		// Don't get/set properties on text, comment and attribute nodes
                +		if ( nType === 3 || nType === 8 || nType === 2 ) {
                +			return;
                +		}
                +
                +		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
                +
                +			// Fix name and attach hooks
                +			name = jQuery.propFix[ name ] || name;
                +			hooks = jQuery.propHooks[ name ];
                +		}
                +
                +		if ( value !== undefined ) {
                +			if ( hooks && "set" in hooks &&
                +				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                +				return ret;
                +			}
                +
                +			return ( elem[ name ] = value );
                +		}
                +
                +		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
                +			return ret;
                +		}
                +
                +		return elem[ name ];
                +	},
                +
                +	propHooks: {
                +		tabIndex: {
                +			get: function( elem ) {
                +
                +				// Support: IE <=9 - 11 only
                +				// elem.tabIndex doesn't always return the
                +				// correct value when it hasn't been explicitly set
                +				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
                +				// Use proper attribute retrieval(#12072)
                +				var tabindex = jQuery.find.attr( elem, "tabindex" );
                +
                +				if ( tabindex ) {
                +					return parseInt( tabindex, 10 );
                +				}
                +
                +				if (
                +					rfocusable.test( elem.nodeName ) ||
                +					rclickable.test( elem.nodeName ) &&
                +					elem.href
                +				) {
                +					return 0;
                +				}
                +
                +				return -1;
                +			}
                +		}
                +	},
                +
                +	propFix: {
                +		"for": "htmlFor",
                +		"class": "className"
                +	}
                +} );
                +
                +// Support: IE <=11 only
                +// Accessing the selectedIndex property
                +// forces the browser to respect setting selected
                +// on the option
                +// The getter ensures a default option is selected
                +// when in an optgroup
                +// eslint rule "no-unused-expressions" is disabled for this code
                +// since it considers such accessions noop
                +if ( !support.optSelected ) {
                +	jQuery.propHooks.selected = {
                +		get: function( elem ) {
                +
                +			/* eslint no-unused-expressions: "off" */
                +
                +			var parent = elem.parentNode;
                +			if ( parent && parent.parentNode ) {
                +				parent.parentNode.selectedIndex;
                +			}
                +			return null;
                +		},
                +		set: function( elem ) {
                +
                +			/* eslint no-unused-expressions: "off" */
                +
                +			var parent = elem.parentNode;
                +			if ( parent ) {
                +				parent.selectedIndex;
                +
                +				if ( parent.parentNode ) {
                +					parent.parentNode.selectedIndex;
                +				}
                +			}
                +		}
                +	};
                +}
                +
                +jQuery.each( [
                +	"tabIndex",
                +	"readOnly",
                +	"maxLength",
                +	"cellSpacing",
                +	"cellPadding",
                +	"rowSpan",
                +	"colSpan",
                +	"useMap",
                +	"frameBorder",
                +	"contentEditable"
                +], function() {
                +	jQuery.propFix[ this.toLowerCase() ] = this;
                +} );
                +
                +
                +
                +
                +	// Strip and collapse whitespace according to HTML spec
                +	// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
                +	function stripAndCollapse( value ) {
                +		var tokens = value.match( rnothtmlwhite ) || [];
                +		return tokens.join( " " );
                +	}
                +
                +
                +function getClass( elem ) {
                +	return elem.getAttribute && elem.getAttribute( "class" ) || "";
                +}
                +
                +jQuery.fn.extend( {
                +	addClass: function( value ) {
                +		var classes, elem, cur, curValue, clazz, j, finalValue,
                +			i = 0;
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( j ) {
                +				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
                +			} );
                +		}
                +
                +		if ( typeof value === "string" && value ) {
                +			classes = value.match( rnothtmlwhite ) || [];
                +
                +			while ( ( elem = this[ i++ ] ) ) {
                +				curValue = getClass( elem );
                +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
                +
                +				if ( cur ) {
                +					j = 0;
                +					while ( ( clazz = classes[ j++ ] ) ) {
                +						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
                +							cur += clazz + " ";
                +						}
                +					}
                +
                +					// Only assign if different to avoid unneeded rendering.
                +					finalValue = stripAndCollapse( cur );
                +					if ( curValue !== finalValue ) {
                +						elem.setAttribute( "class", finalValue );
                +					}
                +				}
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	removeClass: function( value ) {
                +		var classes, elem, cur, curValue, clazz, j, finalValue,
                +			i = 0;
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( j ) {
                +				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
                +			} );
                +		}
                +
                +		if ( !arguments.length ) {
                +			return this.attr( "class", "" );
                +		}
                +
                +		if ( typeof value === "string" && value ) {
                +			classes = value.match( rnothtmlwhite ) || [];
                +
                +			while ( ( elem = this[ i++ ] ) ) {
                +				curValue = getClass( elem );
                +
                +				// This expression is here for better compressibility (see addClass)
                +				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
                +
                +				if ( cur ) {
                +					j = 0;
                +					while ( ( clazz = classes[ j++ ] ) ) {
                +
                +						// Remove *all* instances
                +						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
                +							cur = cur.replace( " " + clazz + " ", " " );
                +						}
                +					}
                +
                +					// Only assign if different to avoid unneeded rendering.
                +					finalValue = stripAndCollapse( cur );
                +					if ( curValue !== finalValue ) {
                +						elem.setAttribute( "class", finalValue );
                +					}
                +				}
                +			}
                +		}
                +
                +		return this;
                +	},
                +
                +	toggleClass: function( value, stateVal ) {
                +		var type = typeof value;
                +
                +		if ( typeof stateVal === "boolean" && type === "string" ) {
                +			return stateVal ? this.addClass( value ) : this.removeClass( value );
                +		}
                +
                +		if ( jQuery.isFunction( value ) ) {
                +			return this.each( function( i ) {
                +				jQuery( this ).toggleClass(
                +					value.call( this, i, getClass( this ), stateVal ),
                +					stateVal
                +				);
                +			} );
                +		}
                +
                +		return this.each( function() {
                +			var className, i, self, classNames;
                +
                +			if ( type === "string" ) {
                +
                +				// Toggle individual class names
                +				i = 0;
                +				self = jQuery( this );
                +				classNames = value.match( rnothtmlwhite ) || [];
                +
                +				while ( ( className = classNames[ i++ ] ) ) {
                +
                +					// Check each className given, space separated list
                +					if ( self.hasClass( className ) ) {
                +						self.removeClass( className );
                +					} else {
                +						self.addClass( className );
                +					}
                +				}
                +
                +			// Toggle whole class name
                +			} else if ( value === undefined || type === "boolean" ) {
                +				className = getClass( this );
                +				if ( className ) {
                +
                +					// Store className if set
                +					dataPriv.set( this, "__className__", className );
                +				}
                +
                +				// If the element has a class name or if we're passed `false`,
                +				// then remove the whole classname (if there was one, the above saved it).
                +				// Otherwise bring back whatever was previously saved (if anything),
                +				// falling back to the empty string if nothing was stored.
                +				if ( this.setAttribute ) {
                +					this.setAttribute( "class",
                +						className || value === false ?
                +						"" :
                +						dataPriv.get( this, "__className__" ) || ""
                +					);
                +				}
                +			}
                +		} );
                +	},
                +
                +	hasClass: function( selector ) {
                +		var className, elem,
                +			i = 0;
                +
                +		className = " " + selector + " ";
                +		while ( ( elem = this[ i++ ] ) ) {
                +			if ( elem.nodeType === 1 &&
                +				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
                +					return true;
                +			}
                +		}
                +
                +		return false;
                +	}
                +} );
                +
                +
                +
                +
                +var rreturn = /\r/g;
                +
                +jQuery.fn.extend( {
                +	val: function( value ) {
                +		var hooks, ret, isFunction,
                +			elem = this[ 0 ];
                +
                +		if ( !arguments.length ) {
                +			if ( elem ) {
                +				hooks = jQuery.valHooks[ elem.type ] ||
                +					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
                +
                +				if ( hooks &&
                +					"get" in hooks &&
                +					( ret = hooks.get( elem, "value" ) ) !== undefined
                +				) {
                +					return ret;
                +				}
                +
                +				ret = elem.value;
                +
                +				// Handle most common string cases
                +				if ( typeof ret === "string" ) {
                +					return ret.replace( rreturn, "" );
                +				}
                +
                +				// Handle cases where value is null/undef or number
                +				return ret == null ? "" : ret;
                +			}
                +
                +			return;
                +		}
                +
                +		isFunction = jQuery.isFunction( value );
                +
                +		return this.each( function( i ) {
                +			var val;
                +
                +			if ( this.nodeType !== 1 ) {
                +				return;
                +			}
                +
                +			if ( isFunction ) {
                +				val = value.call( this, i, jQuery( this ).val() );
                +			} else {
                +				val = value;
                +			}
                +
                +			// Treat null/undefined as ""; convert numbers to string
                +			if ( val == null ) {
                +				val = "";
                +
                +			} else if ( typeof val === "number" ) {
                +				val += "";
                +
                +			} else if ( Array.isArray( val ) ) {
                +				val = jQuery.map( val, function( value ) {
                +					return value == null ? "" : value + "";
                +				} );
                +			}
                +
                +			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
                +
                +			// If set returns undefined, fall back to normal setting
                +			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
                +				this.value = val;
                +			}
                +		} );
                +	}
                +} );
                +
                +jQuery.extend( {
                +	valHooks: {
                +		option: {
                +			get: function( elem ) {
                +
                +				var val = jQuery.find.attr( elem, "value" );
                +				return val != null ?
                +					val :
                +
                +					// Support: IE <=10 - 11 only
                +					// option.text throws exceptions (#14686, #14858)
                +					// Strip and collapse whitespace
                +					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
                +					stripAndCollapse( jQuery.text( elem ) );
                +			}
                +		},
                +		select: {
                +			get: function( elem ) {
                +				var value, option, i,
                +					options = elem.options,
                +					index = elem.selectedIndex,
                +					one = elem.type === "select-one",
                +					values = one ? null : [],
                +					max = one ? index + 1 : options.length;
                +
                +				if ( index < 0 ) {
                +					i = max;
                +
                +				} else {
                +					i = one ? index : 0;
                +				}
                +
                +				// Loop through all the selected options
                +				for ( ; i < max; i++ ) {
                +					option = options[ i ];
                +
                +					// Support: IE <=9 only
                +					// IE8-9 doesn't update selected after form reset (#2551)
                +					if ( ( option.selected || i === index ) &&
                +
                +							// Don't return options that are disabled or in a disabled optgroup
                +							!option.disabled &&
                +							( !option.parentNode.disabled ||
                +								!nodeName( option.parentNode, "optgroup" ) ) ) {
                +
                +						// Get the specific value for the option
                +						value = jQuery( option ).val();
                +
                +						// We don't need an array for one selects
                +						if ( one ) {
                +							return value;
                +						}
                +
                +						// Multi-Selects return an array
                +						values.push( value );
                +					}
                +				}
                +
                +				return values;
                +			},
                +
                +			set: function( elem, value ) {
                +				var optionSet, option,
                +					options = elem.options,
                +					values = jQuery.makeArray( value ),
                +					i = options.length;
                +
                +				while ( i-- ) {
                +					option = options[ i ];
                +
                +					/* eslint-disable no-cond-assign */
                +
                +					if ( option.selected =
                +						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
                +					) {
                +						optionSet = true;
                +					}
                +
                +					/* eslint-enable no-cond-assign */
                +				}
                +
                +				// Force browsers to behave consistently when non-matching value is set
                +				if ( !optionSet ) {
                +					elem.selectedIndex = -1;
                +				}
                +				return values;
                +			}
                +		}
                +	}
                +} );
                +
                +// Radios and checkboxes getter/setter
                +jQuery.each( [ "radio", "checkbox" ], function() {
                +	jQuery.valHooks[ this ] = {
                +		set: function( elem, value ) {
                +			if ( Array.isArray( value ) ) {
                +				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
                +			}
                +		}
                +	};
                +	if ( !support.checkOn ) {
                +		jQuery.valHooks[ this ].get = function( elem ) {
                +			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +// Return jQuery for attributes-only inclusion
                +
                +
                +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
                +
                +jQuery.extend( jQuery.event, {
                +
                +	trigger: function( event, data, elem, onlyHandlers ) {
                +
                +		var i, cur, tmp, bubbleType, ontype, handle, special,
                +			eventPath = [ elem || document ],
                +			type = hasOwn.call( event, "type" ) ? event.type : event,
                +			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
                +
                +		cur = tmp = elem = elem || document;
                +
                +		// Don't do events on text and comment nodes
                +		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
                +			return;
                +		}
                +
                +		// focus/blur morphs to focusin/out; ensure we're not firing them right now
                +		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
                +			return;
                +		}
                +
                +		if ( type.indexOf( "." ) > -1 ) {
                +
                +			// Namespaced trigger; create a regexp to match event type in handle()
                +			namespaces = type.split( "." );
                +			type = namespaces.shift();
                +			namespaces.sort();
                +		}
                +		ontype = type.indexOf( ":" ) < 0 && "on" + type;
                +
                +		// Caller can pass in a jQuery.Event object, Object, or just an event type string
                +		event = event[ jQuery.expando ] ?
                +			event :
                +			new jQuery.Event( type, typeof event === "object" && event );
                +
                +		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
                +		event.isTrigger = onlyHandlers ? 2 : 3;
                +		event.namespace = namespaces.join( "." );
                +		event.rnamespace = event.namespace ?
                +			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
                +			null;
                +
                +		// Clean up the event in case it is being reused
                +		event.result = undefined;
                +		if ( !event.target ) {
                +			event.target = elem;
                +		}
                +
                +		// Clone any incoming data and prepend the event, creating the handler arg list
                +		data = data == null ?
                +			[ event ] :
                +			jQuery.makeArray( data, [ event ] );
                +
                +		// Allow special events to draw outside the lines
                +		special = jQuery.event.special[ type ] || {};
                +		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
                +			return;
                +		}
                +
                +		// Determine event propagation path in advance, per W3C events spec (#9951)
                +		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
                +		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
                +
                +			bubbleType = special.delegateType || type;
                +			if ( !rfocusMorph.test( bubbleType + type ) ) {
                +				cur = cur.parentNode;
                +			}
                +			for ( ; cur; cur = cur.parentNode ) {
                +				eventPath.push( cur );
                +				tmp = cur;
                +			}
                +
                +			// Only add window if we got to document (e.g., not plain obj or detached DOM)
                +			if ( tmp === ( elem.ownerDocument || document ) ) {
                +				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
                +			}
                +		}
                +
                +		// Fire handlers on the event path
                +		i = 0;
                +		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
                +
                +			event.type = i > 1 ?
                +				bubbleType :
                +				special.bindType || type;
                +
                +			// jQuery handler
                +			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
                +				dataPriv.get( cur, "handle" );
                +			if ( handle ) {
                +				handle.apply( cur, data );
                +			}
                +
                +			// Native handler
                +			handle = ontype && cur[ ontype ];
                +			if ( handle && handle.apply && acceptData( cur ) ) {
                +				event.result = handle.apply( cur, data );
                +				if ( event.result === false ) {
                +					event.preventDefault();
                +				}
                +			}
                +		}
                +		event.type = type;
                +
                +		// If nobody prevented the default action, do it now
                +		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
                +
                +			if ( ( !special._default ||
                +				special._default.apply( eventPath.pop(), data ) === false ) &&
                +				acceptData( elem ) ) {
                +
                +				// Call a native DOM method on the target with the same name as the event.
                +				// Don't do default actions on window, that's where global variables be (#6170)
                +				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
                +
                +					// Don't re-trigger an onFOO event when we call its FOO() method
                +					tmp = elem[ ontype ];
                +
                +					if ( tmp ) {
                +						elem[ ontype ] = null;
                +					}
                +
                +					// Prevent re-triggering of the same event, since we already bubbled it above
                +					jQuery.event.triggered = type;
                +					elem[ type ]();
                +					jQuery.event.triggered = undefined;
                +
                +					if ( tmp ) {
                +						elem[ ontype ] = tmp;
                +					}
                +				}
                +			}
                +		}
                +
                +		return event.result;
                +	},
                +
                +	// Piggyback on a donor event to simulate a different one
                +	// Used only for `focus(in | out)` events
                +	simulate: function( type, elem, event ) {
                +		var e = jQuery.extend(
                +			new jQuery.Event(),
                +			event,
                +			{
                +				type: type,
                +				isSimulated: true
                +			}
                +		);
                +
                +		jQuery.event.trigger( e, null, elem );
                +	}
                +
                +} );
                +
                +jQuery.fn.extend( {
                +
                +	trigger: function( type, data ) {
                +		return this.each( function() {
                +			jQuery.event.trigger( type, data, this );
                +		} );
                +	},
                +	triggerHandler: function( type, data ) {
                +		var elem = this[ 0 ];
                +		if ( elem ) {
                +			return jQuery.event.trigger( type, data, elem, true );
                +		}
                +	}
                +} );
                +
                +
                +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
                +	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
                +	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
                +	function( i, name ) {
                +
                +	// Handle event binding
                +	jQuery.fn[ name ] = function( data, fn ) {
                +		return arguments.length > 0 ?
                +			this.on( name, null, data, fn ) :
                +			this.trigger( name );
                +	};
                +} );
                +
                +jQuery.fn.extend( {
                +	hover: function( fnOver, fnOut ) {
                +		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
                +	}
                +} );
                +
                +
                +
                +
                +support.focusin = "onfocusin" in window;
                +
                +
                +// Support: Firefox <=44
                +// Firefox doesn't have focus(in | out) events
                +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
                +//
                +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
                +// focus(in | out) events fire after focus & blur events,
                +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
                +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
                +if ( !support.focusin ) {
                +	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
                +
                +		// Attach a single capturing handler on the document while someone wants focusin/focusout
                +		var handler = function( event ) {
                +			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
                +		};
                +
                +		jQuery.event.special[ fix ] = {
                +			setup: function() {
                +				var doc = this.ownerDocument || this,
                +					attaches = dataPriv.access( doc, fix );
                +
                +				if ( !attaches ) {
                +					doc.addEventListener( orig, handler, true );
                +				}
                +				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
                +			},
                +			teardown: function() {
                +				var doc = this.ownerDocument || this,
                +					attaches = dataPriv.access( doc, fix ) - 1;
                +
                +				if ( !attaches ) {
                +					doc.removeEventListener( orig, handler, true );
                +					dataPriv.remove( doc, fix );
                +
                +				} else {
                +					dataPriv.access( doc, fix, attaches );
                +				}
                +			}
                +		};
                +	} );
                +}
                +var location = window.location;
                +
                +var nonce = jQuery.now();
                +
                +var rquery = ( /\?/ );
                +
                +
                +
                +// Cross-browser xml parsing
                +jQuery.parseXML = function( data ) {
                +	var xml;
                +	if ( !data || typeof data !== "string" ) {
                +		return null;
                +	}
                +
                +	// Support: IE 9 - 11 only
                +	// IE throws on parseFromString with invalid input.
                +	try {
                +		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
                +	} catch ( e ) {
                +		xml = undefined;
                +	}
                +
                +	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
                +		jQuery.error( "Invalid XML: " + data );
                +	}
                +	return xml;
                +};
                +
                +
                +var
                +	rbracket = /\[\]$/,
                +	rCRLF = /\r?\n/g,
                +	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
                +	rsubmittable = /^(?:input|select|textarea|keygen)/i;
                +
                +function buildParams( prefix, obj, traditional, add ) {
                +	var name;
                +
                +	if ( Array.isArray( obj ) ) {
                +
                +		// Serialize array item.
                +		jQuery.each( obj, function( i, v ) {
                +			if ( traditional || rbracket.test( prefix ) ) {
                +
                +				// Treat each array item as a scalar.
                +				add( prefix, v );
                +
                +			} else {
                +
                +				// Item is non-scalar (array or object), encode its numeric index.
                +				buildParams(
                +					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
                +					v,
                +					traditional,
                +					add
                +				);
                +			}
                +		} );
                +
                +	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
                +
                +		// Serialize object item.
                +		for ( name in obj ) {
                +			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
                +		}
                +
                +	} else {
                +
                +		// Serialize scalar item.
                +		add( prefix, obj );
                +	}
                +}
                +
                +// Serialize an array of form elements or a set of
                +// key/values into a query string
                +jQuery.param = function( a, traditional ) {
                +	var prefix,
                +		s = [],
                +		add = function( key, valueOrFunction ) {
                +
                +			// If value is a function, invoke it and use its return value
                +			var value = jQuery.isFunction( valueOrFunction ) ?
                +				valueOrFunction() :
                +				valueOrFunction;
                +
                +			s[ s.length ] = encodeURIComponent( key ) + "=" +
                +				encodeURIComponent( value == null ? "" : value );
                +		};
                +
                +	// If an array was passed in, assume that it is an array of form elements.
                +	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                +
                +		// Serialize the form elements
                +		jQuery.each( a, function() {
                +			add( this.name, this.value );
                +		} );
                +
                +	} else {
                +
                +		// If traditional, encode the "old" way (the way 1.3.2 or older
                +		// did it), otherwise encode params recursively.
                +		for ( prefix in a ) {
                +			buildParams( prefix, a[ prefix ], traditional, add );
                +		}
                +	}
                +
                +	// Return the resulting serialization
                +	return s.join( "&" );
                +};
                +
                +jQuery.fn.extend( {
                +	serialize: function() {
                +		return jQuery.param( this.serializeArray() );
                +	},
                +	serializeArray: function() {
                +		return this.map( function() {
                +
                +			// Can add propHook for "elements" to filter or add form elements
                +			var elements = jQuery.prop( this, "elements" );
                +			return elements ? jQuery.makeArray( elements ) : this;
                +		} )
                +		.filter( function() {
                +			var type = this.type;
                +
                +			// Use .is( ":disabled" ) so that fieldset[disabled] works
                +			return this.name && !jQuery( this ).is( ":disabled" ) &&
                +				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
                +				( this.checked || !rcheckableType.test( type ) );
                +		} )
                +		.map( function( i, elem ) {
                +			var val = jQuery( this ).val();
                +
                +			if ( val == null ) {
                +				return null;
                +			}
                +
                +			if ( Array.isArray( val ) ) {
                +				return jQuery.map( val, function( val ) {
                +					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                +				} );
                +			}
                +
                +			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                +		} ).get();
                +	}
                +} );
                +
                +
                +var
                +	r20 = /%20/g,
                +	rhash = /#.*$/,
                +	rantiCache = /([?&])_=[^&]*/,
                +	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
                +
                +	// #7653, #8125, #8152: local protocol detection
                +	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
                +	rnoContent = /^(?:GET|HEAD)$/,
                +	rprotocol = /^\/\//,
                +
                +	/* Prefilters
                +	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
                +	 * 2) These are called:
                +	 *    - BEFORE asking for a transport
                +	 *    - AFTER param serialization (s.data is a string if s.processData is true)
                +	 * 3) key is the dataType
                +	 * 4) the catchall symbol "*" can be used
                +	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
                +	 */
                +	prefilters = {},
                +
                +	/* Transports bindings
                +	 * 1) key is the dataType
                +	 * 2) the catchall symbol "*" can be used
                +	 * 3) selection will start with transport dataType and THEN go to "*" if needed
                +	 */
                +	transports = {},
                +
                +	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
                +	allTypes = "*/".concat( "*" ),
                +
                +	// Anchor tag for parsing the document origin
                +	originAnchor = document.createElement( "a" );
                +	originAnchor.href = location.href;
                +
                +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
                +function addToPrefiltersOrTransports( structure ) {
                +
                +	// dataTypeExpression is optional and defaults to "*"
                +	return function( dataTypeExpression, func ) {
                +
                +		if ( typeof dataTypeExpression !== "string" ) {
                +			func = dataTypeExpression;
                +			dataTypeExpression = "*";
                +		}
                +
                +		var dataType,
                +			i = 0,
                +			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
                +
                +		if ( jQuery.isFunction( func ) ) {
                +
                +			// For each dataType in the dataTypeExpression
                +			while ( ( dataType = dataTypes[ i++ ] ) ) {
                +
                +				// Prepend if requested
                +				if ( dataType[ 0 ] === "+" ) {
                +					dataType = dataType.slice( 1 ) || "*";
                +					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
                +
                +				// Otherwise append
                +				} else {
                +					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
                +				}
                +			}
                +		}
                +	};
                +}
                +
                +// Base inspection function for prefilters and transports
                +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
                +
                +	var inspected = {},
                +		seekingTransport = ( structure === transports );
                +
                +	function inspect( dataType ) {
                +		var selected;
                +		inspected[ dataType ] = true;
                +		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
                +			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
                +			if ( typeof dataTypeOrTransport === "string" &&
                +				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
                +
                +				options.dataTypes.unshift( dataTypeOrTransport );
                +				inspect( dataTypeOrTransport );
                +				return false;
                +			} else if ( seekingTransport ) {
                +				return !( selected = dataTypeOrTransport );
                +			}
                +		} );
                +		return selected;
                +	}
                +
                +	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
                +}
                +
                +// A special extend for ajax options
                +// that takes "flat" options (not to be deep extended)
                +// Fixes #9887
                +function ajaxExtend( target, src ) {
                +	var key, deep,
                +		flatOptions = jQuery.ajaxSettings.flatOptions || {};
                +
                +	for ( key in src ) {
                +		if ( src[ key ] !== undefined ) {
                +			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
                +		}
                +	}
                +	if ( deep ) {
                +		jQuery.extend( true, target, deep );
                +	}
                +
                +	return target;
                +}
                +
                +/* Handles responses to an ajax request:
                + * - finds the right dataType (mediates between content-type and expected dataType)
                + * - returns the corresponding response
                + */
                +function ajaxHandleResponses( s, jqXHR, responses ) {
                +
                +	var ct, type, finalDataType, firstDataType,
                +		contents = s.contents,
                +		dataTypes = s.dataTypes;
                +
                +	// Remove auto dataType and get content-type in the process
                +	while ( dataTypes[ 0 ] === "*" ) {
                +		dataTypes.shift();
                +		if ( ct === undefined ) {
                +			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
                +		}
                +	}
                +
                +	// Check if we're dealing with a known content-type
                +	if ( ct ) {
                +		for ( type in contents ) {
                +			if ( contents[ type ] && contents[ type ].test( ct ) ) {
                +				dataTypes.unshift( type );
                +				break;
                +			}
                +		}
                +	}
                +
                +	// Check to see if we have a response for the expected dataType
                +	if ( dataTypes[ 0 ] in responses ) {
                +		finalDataType = dataTypes[ 0 ];
                +	} else {
                +
                +		// Try convertible dataTypes
                +		for ( type in responses ) {
                +			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
                +				finalDataType = type;
                +				break;
                +			}
                +			if ( !firstDataType ) {
                +				firstDataType = type;
                +			}
                +		}
                +
                +		// Or just use first one
                +		finalDataType = finalDataType || firstDataType;
                +	}
                +
                +	// If we found a dataType
                +	// We add the dataType to the list if needed
                +	// and return the corresponding response
                +	if ( finalDataType ) {
                +		if ( finalDataType !== dataTypes[ 0 ] ) {
                +			dataTypes.unshift( finalDataType );
                +		}
                +		return responses[ finalDataType ];
                +	}
                +}
                +
                +/* Chain conversions given the request and the original response
                + * Also sets the responseXXX fields on the jqXHR instance
                + */
                +function ajaxConvert( s, response, jqXHR, isSuccess ) {
                +	var conv2, current, conv, tmp, prev,
                +		converters = {},
                +
                +		// Work with a copy of dataTypes in case we need to modify it for conversion
                +		dataTypes = s.dataTypes.slice();
                +
                +	// Create converters map with lowercased keys
                +	if ( dataTypes[ 1 ] ) {
                +		for ( conv in s.converters ) {
                +			converters[ conv.toLowerCase() ] = s.converters[ conv ];
                +		}
                +	}
                +
                +	current = dataTypes.shift();
                +
                +	// Convert to each sequential dataType
                +	while ( current ) {
                +
                +		if ( s.responseFields[ current ] ) {
                +			jqXHR[ s.responseFields[ current ] ] = response;
                +		}
                +
                +		// Apply the dataFilter if provided
                +		if ( !prev && isSuccess && s.dataFilter ) {
                +			response = s.dataFilter( response, s.dataType );
                +		}
                +
                +		prev = current;
                +		current = dataTypes.shift();
                +
                +		if ( current ) {
                +
                +			// There's only work to do if current dataType is non-auto
                +			if ( current === "*" ) {
                +
                +				current = prev;
                +
                +			// Convert response if prev dataType is non-auto and differs from current
                +			} else if ( prev !== "*" && prev !== current ) {
                +
                +				// Seek a direct converter
                +				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
                +
                +				// If none found, seek a pair
                +				if ( !conv ) {
                +					for ( conv2 in converters ) {
                +
                +						// If conv2 outputs current
                +						tmp = conv2.split( " " );
                +						if ( tmp[ 1 ] === current ) {
                +
                +							// If prev can be converted to accepted input
                +							conv = converters[ prev + " " + tmp[ 0 ] ] ||
                +								converters[ "* " + tmp[ 0 ] ];
                +							if ( conv ) {
                +
                +								// Condense equivalence converters
                +								if ( conv === true ) {
                +									conv = converters[ conv2 ];
                +
                +								// Otherwise, insert the intermediate dataType
                +								} else if ( converters[ conv2 ] !== true ) {
                +									current = tmp[ 0 ];
                +									dataTypes.unshift( tmp[ 1 ] );
                +								}
                +								break;
                +							}
                +						}
                +					}
                +				}
                +
                +				// Apply converter (if not an equivalence)
                +				if ( conv !== true ) {
                +
                +					// Unless errors are allowed to bubble, catch and return them
                +					if ( conv && s.throws ) {
                +						response = conv( response );
                +					} else {
                +						try {
                +							response = conv( response );
                +						} catch ( e ) {
                +							return {
                +								state: "parsererror",
                +								error: conv ? e : "No conversion from " + prev + " to " + current
                +							};
                +						}
                +					}
                +				}
                +			}
                +		}
                +	}
                +
                +	return { state: "success", data: response };
                +}
                +
                +jQuery.extend( {
                +
                +	// Counter for holding the number of active queries
                +	active: 0,
                +
                +	// Last-Modified header cache for next request
                +	lastModified: {},
                +	etag: {},
                +
                +	ajaxSettings: {
                +		url: location.href,
                +		type: "GET",
                +		isLocal: rlocalProtocol.test( location.protocol ),
                +		global: true,
                +		processData: true,
                +		async: true,
                +		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                +
                +		/*
                +		timeout: 0,
                +		data: null,
                +		dataType: null,
                +		username: null,
                +		password: null,
                +		cache: null,
                +		throws: false,
                +		traditional: false,
                +		headers: {},
                +		*/
                +
                +		accepts: {
                +			"*": allTypes,
                +			text: "text/plain",
                +			html: "text/html",
                +			xml: "application/xml, text/xml",
                +			json: "application/json, text/javascript"
                +		},
                +
                +		contents: {
                +			xml: /\bxml\b/,
                +			html: /\bhtml/,
                +			json: /\bjson\b/
                +		},
                +
                +		responseFields: {
                +			xml: "responseXML",
                +			text: "responseText",
                +			json: "responseJSON"
                +		},
                +
                +		// Data converters
                +		// Keys separate source (or catchall "*") and destination types with a single space
                +		converters: {
                +
                +			// Convert anything to text
                +			"* text": String,
                +
                +			// Text to html (true = no transformation)
                +			"text html": true,
                +
                +			// Evaluate text as a json expression
                +			"text json": JSON.parse,
                +
                +			// Parse text as xml
                +			"text xml": jQuery.parseXML
                +		},
                +
                +		// For options that shouldn't be deep extended:
                +		// you can add your own custom options here if
                +		// and when you create one that shouldn't be
                +		// deep extended (see ajaxExtend)
                +		flatOptions: {
                +			url: true,
                +			context: true
                +		}
                +	},
                +
                +	// Creates a full fledged settings object into target
                +	// with both ajaxSettings and settings fields.
                +	// If target is omitted, writes into ajaxSettings.
                +	ajaxSetup: function( target, settings ) {
                +		return settings ?
                +
                +			// Building a settings object
                +			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
                +
                +			// Extending ajaxSettings
                +			ajaxExtend( jQuery.ajaxSettings, target );
                +	},
                +
                +	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
                +	ajaxTransport: addToPrefiltersOrTransports( transports ),
                +
                +	// Main method
                +	ajax: function( url, options ) {
                +
                +		// If url is an object, simulate pre-1.5 signature
                +		if ( typeof url === "object" ) {
                +			options = url;
                +			url = undefined;
                +		}
                +
                +		// Force options to be an object
                +		options = options || {};
                +
                +		var transport,
                +
                +			// URL without anti-cache param
                +			cacheURL,
                +
                +			// Response headers
                +			responseHeadersString,
                +			responseHeaders,
                +
                +			// timeout handle
                +			timeoutTimer,
                +
                +			// Url cleanup var
                +			urlAnchor,
                +
                +			// Request state (becomes false upon send and true upon completion)
                +			completed,
                +
                +			// To know if global events are to be dispatched
                +			fireGlobals,
                +
                +			// Loop variable
                +			i,
                +
                +			// uncached part of the url
                +			uncached,
                +
                +			// Create the final options object
                +			s = jQuery.ajaxSetup( {}, options ),
                +
                +			// Callbacks context
                +			callbackContext = s.context || s,
                +
                +			// Context for global events is callbackContext if it is a DOM node or jQuery collection
                +			globalEventContext = s.context &&
                +				( callbackContext.nodeType || callbackContext.jquery ) ?
                +					jQuery( callbackContext ) :
                +					jQuery.event,
                +
                +			// Deferreds
                +			deferred = jQuery.Deferred(),
                +			completeDeferred = jQuery.Callbacks( "once memory" ),
                +
                +			// Status-dependent callbacks
                +			statusCode = s.statusCode || {},
                +
                +			// Headers (they are sent all at once)
                +			requestHeaders = {},
                +			requestHeadersNames = {},
                +
                +			// Default abort message
                +			strAbort = "canceled",
                +
                +			// Fake xhr
                +			jqXHR = {
                +				readyState: 0,
                +
                +				// Builds headers hashtable if needed
                +				getResponseHeader: function( key ) {
                +					var match;
                +					if ( completed ) {
                +						if ( !responseHeaders ) {
                +							responseHeaders = {};
                +							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
                +								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
                +							}
                +						}
                +						match = responseHeaders[ key.toLowerCase() ];
                +					}
                +					return match == null ? null : match;
                +				},
                +
                +				// Raw string
                +				getAllResponseHeaders: function() {
                +					return completed ? responseHeadersString : null;
                +				},
                +
                +				// Caches the header
                +				setRequestHeader: function( name, value ) {
                +					if ( completed == null ) {
                +						name = requestHeadersNames[ name.toLowerCase() ] =
                +							requestHeadersNames[ name.toLowerCase() ] || name;
                +						requestHeaders[ name ] = value;
                +					}
                +					return this;
                +				},
                +
                +				// Overrides response content-type header
                +				overrideMimeType: function( type ) {
                +					if ( completed == null ) {
                +						s.mimeType = type;
                +					}
                +					return this;
                +				},
                +
                +				// Status-dependent callbacks
                +				statusCode: function( map ) {
                +					var code;
                +					if ( map ) {
                +						if ( completed ) {
                +
                +							// Execute the appropriate callbacks
                +							jqXHR.always( map[ jqXHR.status ] );
                +						} else {
                +
                +							// Lazy-add the new callbacks in a way that preserves old ones
                +							for ( code in map ) {
                +								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
                +							}
                +						}
                +					}
                +					return this;
                +				},
                +
                +				// Cancel the request
                +				abort: function( statusText ) {
                +					var finalText = statusText || strAbort;
                +					if ( transport ) {
                +						transport.abort( finalText );
                +					}
                +					done( 0, finalText );
                +					return this;
                +				}
                +			};
                +
                +		// Attach deferreds
                +		deferred.promise( jqXHR );
                +
                +		// Add protocol if not provided (prefilters might expect it)
                +		// Handle falsy url in the settings object (#10093: consistency with old signature)
                +		// We also use the url parameter if available
                +		s.url = ( ( url || s.url || location.href ) + "" )
                +			.replace( rprotocol, location.protocol + "//" );
                +
                +		// Alias method option to type as per ticket #12004
                +		s.type = options.method || options.type || s.method || s.type;
                +
                +		// Extract dataTypes list
                +		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
                +
                +		// A cross-domain request is in order when the origin doesn't match the current origin.
                +		if ( s.crossDomain == null ) {
                +			urlAnchor = document.createElement( "a" );
                +
                +			// Support: IE <=8 - 11, Edge 12 - 13
                +			// IE throws exception on accessing the href property if url is malformed,
                +			// e.g. http://example.com:80x/
                +			try {
                +				urlAnchor.href = s.url;
                +
                +				// Support: IE <=8 - 11 only
                +				// Anchor's host property isn't correctly set when s.url is relative
                +				urlAnchor.href = urlAnchor.href;
                +				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
                +					urlAnchor.protocol + "//" + urlAnchor.host;
                +			} catch ( e ) {
                +
                +				// If there is an error parsing the URL, assume it is crossDomain,
                +				// it can be rejected by the transport if it is invalid
                +				s.crossDomain = true;
                +			}
                +		}
                +
                +		// Convert data if not already a string
                +		if ( s.data && s.processData && typeof s.data !== "string" ) {
                +			s.data = jQuery.param( s.data, s.traditional );
                +		}
                +
                +		// Apply prefilters
                +		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
                +
                +		// If request was aborted inside a prefilter, stop there
                +		if ( completed ) {
                +			return jqXHR;
                +		}
                +
                +		// We can fire global events as of now if asked to
                +		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
                +		fireGlobals = jQuery.event && s.global;
                +
                +		// Watch for a new set of requests
                +		if ( fireGlobals && jQuery.active++ === 0 ) {
                +			jQuery.event.trigger( "ajaxStart" );
                +		}
                +
                +		// Uppercase the type
                +		s.type = s.type.toUpperCase();
                +
                +		// Determine if request has content
                +		s.hasContent = !rnoContent.test( s.type );
                +
                +		// Save the URL in case we're toying with the If-Modified-Since
                +		// and/or If-None-Match header later on
                +		// Remove hash to simplify url manipulation
                +		cacheURL = s.url.replace( rhash, "" );
                +
                +		// More options handling for requests with no content
                +		if ( !s.hasContent ) {
                +
                +			// Remember the hash so we can put it back
                +			uncached = s.url.slice( cacheURL.length );
                +
                +			// If data is available, append data to url
                +			if ( s.data ) {
                +				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
                +
                +				// #9682: remove data so that it's not used in an eventual retry
                +				delete s.data;
                +			}
                +
                +			// Add or update anti-cache param if needed
                +			if ( s.cache === false ) {
                +				cacheURL = cacheURL.replace( rantiCache, "$1" );
                +				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
                +			}
                +
                +			// Put hash and anti-cache on the URL that will be requested (gh-1732)
                +			s.url = cacheURL + uncached;
                +
                +		// Change '%20' to '+' if this is encoded form body content (gh-2658)
                +		} else if ( s.data && s.processData &&
                +			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
                +			s.data = s.data.replace( r20, "+" );
                +		}
                +
                +		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                +		if ( s.ifModified ) {
                +			if ( jQuery.lastModified[ cacheURL ] ) {
                +				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
                +			}
                +			if ( jQuery.etag[ cacheURL ] ) {
                +				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
                +			}
                +		}
                +
                +		// Set the correct header, if data is being sent
                +		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
                +			jqXHR.setRequestHeader( "Content-Type", s.contentType );
                +		}
                +
                +		// Set the Accepts header for the server, depending on the dataType
                +		jqXHR.setRequestHeader(
                +			"Accept",
                +			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
                +				s.accepts[ s.dataTypes[ 0 ] ] +
                +					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
                +				s.accepts[ "*" ]
                +		);
                +
                +		// Check for headers option
                +		for ( i in s.headers ) {
                +			jqXHR.setRequestHeader( i, s.headers[ i ] );
                +		}
                +
                +		// Allow custom headers/mimetypes and early abort
                +		if ( s.beforeSend &&
                +			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
                +
                +			// Abort if not done already and return
                +			return jqXHR.abort();
                +		}
                +
                +		// Aborting is no longer a cancellation
                +		strAbort = "abort";
                +
                +		// Install callbacks on deferreds
                +		completeDeferred.add( s.complete );
                +		jqXHR.done( s.success );
                +		jqXHR.fail( s.error );
                +
                +		// Get transport
                +		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
                +
                +		// If no transport, we auto-abort
                +		if ( !transport ) {
                +			done( -1, "No Transport" );
                +		} else {
                +			jqXHR.readyState = 1;
                +
                +			// Send global event
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
                +			}
                +
                +			// If request was aborted inside ajaxSend, stop there
                +			if ( completed ) {
                +				return jqXHR;
                +			}
                +
                +			// Timeout
                +			if ( s.async && s.timeout > 0 ) {
                +				timeoutTimer = window.setTimeout( function() {
                +					jqXHR.abort( "timeout" );
                +				}, s.timeout );
                +			}
                +
                +			try {
                +				completed = false;
                +				transport.send( requestHeaders, done );
                +			} catch ( e ) {
                +
                +				// Rethrow post-completion exceptions
                +				if ( completed ) {
                +					throw e;
                +				}
                +
                +				// Propagate others as results
                +				done( -1, e );
                +			}
                +		}
                +
                +		// Callback for when everything is done
                +		function done( status, nativeStatusText, responses, headers ) {
                +			var isSuccess, success, error, response, modified,
                +				statusText = nativeStatusText;
                +
                +			// Ignore repeat invocations
                +			if ( completed ) {
                +				return;
                +			}
                +
                +			completed = true;
                +
                +			// Clear timeout if it exists
                +			if ( timeoutTimer ) {
                +				window.clearTimeout( timeoutTimer );
                +			}
                +
                +			// Dereference transport for early garbage collection
                +			// (no matter how long the jqXHR object will be used)
                +			transport = undefined;
                +
                +			// Cache response headers
                +			responseHeadersString = headers || "";
                +
                +			// Set readyState
                +			jqXHR.readyState = status > 0 ? 4 : 0;
                +
                +			// Determine if successful
                +			isSuccess = status >= 200 && status < 300 || status === 304;
                +
                +			// Get response data
                +			if ( responses ) {
                +				response = ajaxHandleResponses( s, jqXHR, responses );
                +			}
                +
                +			// Convert no matter what (that way responseXXX fields are always set)
                +			response = ajaxConvert( s, response, jqXHR, isSuccess );
                +
                +			// If successful, handle type chaining
                +			if ( isSuccess ) {
                +
                +				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                +				if ( s.ifModified ) {
                +					modified = jqXHR.getResponseHeader( "Last-Modified" );
                +					if ( modified ) {
                +						jQuery.lastModified[ cacheURL ] = modified;
                +					}
                +					modified = jqXHR.getResponseHeader( "etag" );
                +					if ( modified ) {
                +						jQuery.etag[ cacheURL ] = modified;
                +					}
                +				}
                +
                +				// if no content
                +				if ( status === 204 || s.type === "HEAD" ) {
                +					statusText = "nocontent";
                +
                +				// if not modified
                +				} else if ( status === 304 ) {
                +					statusText = "notmodified";
                +
                +				// If we have data, let's convert it
                +				} else {
                +					statusText = response.state;
                +					success = response.data;
                +					error = response.error;
                +					isSuccess = !error;
                +				}
                +			} else {
                +
                +				// Extract error from statusText and normalize for non-aborts
                +				error = statusText;
                +				if ( status || !statusText ) {
                +					statusText = "error";
                +					if ( status < 0 ) {
                +						status = 0;
                +					}
                +				}
                +			}
                +
                +			// Set data for the fake xhr object
                +			jqXHR.status = status;
                +			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
                +
                +			// Success/Error
                +			if ( isSuccess ) {
                +				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
                +			} else {
                +				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
                +			}
                +
                +			// Status-dependent callbacks
                +			jqXHR.statusCode( statusCode );
                +			statusCode = undefined;
                +
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
                +					[ jqXHR, s, isSuccess ? success : error ] );
                +			}
                +
                +			// Complete
                +			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
                +
                +			if ( fireGlobals ) {
                +				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
                +
                +				// Handle the global AJAX counter
                +				if ( !( --jQuery.active ) ) {
                +					jQuery.event.trigger( "ajaxStop" );
                +				}
                +			}
                +		}
                +
                +		return jqXHR;
                +	},
                +
                +	getJSON: function( url, data, callback ) {
                +		return jQuery.get( url, data, callback, "json" );
                +	},
                +
                +	getScript: function( url, callback ) {
                +		return jQuery.get( url, undefined, callback, "script" );
                +	}
                +} );
                +
                +jQuery.each( [ "get", "post" ], function( i, method ) {
                +	jQuery[ method ] = function( url, data, callback, type ) {
                +
                +		// Shift arguments if data argument was omitted
                +		if ( jQuery.isFunction( data ) ) {
                +			type = type || callback;
                +			callback = data;
                +			data = undefined;
                +		}
                +
                +		// The url can be an options object (which then must have .url)
                +		return jQuery.ajax( jQuery.extend( {
                +			url: url,
                +			type: method,
                +			dataType: type,
                +			data: data,
                +			success: callback
                +		}, jQuery.isPlainObject( url ) && url ) );
                +	};
                +} );
                +
                +
                +jQuery._evalUrl = function( url ) {
                +	return jQuery.ajax( {
                +		url: url,
                +
                +		// Make this explicit, since user can override this through ajaxSetup (#11264)
                +		type: "GET",
                +		dataType: "script",
                +		cache: true,
                +		async: false,
                +		global: false,
                +		"throws": true
                +	} );
                +};
                +
                +
                +jQuery.fn.extend( {
                +	wrapAll: function( html ) {
                +		var wrap;
                +
                +		if ( this[ 0 ] ) {
                +			if ( jQuery.isFunction( html ) ) {
                +				html = html.call( this[ 0 ] );
                +			}
                +
                +			// The elements to wrap the target around
                +			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
                +
                +			if ( this[ 0 ].parentNode ) {
                +				wrap.insertBefore( this[ 0 ] );
                +			}
                +
                +			wrap.map( function() {
                +				var elem = this;
                +
                +				while ( elem.firstElementChild ) {
                +					elem = elem.firstElementChild;
                +				}
                +
                +				return elem;
                +			} ).append( this );
                +		}
                +
                +		return this;
                +	},
                +
                +	wrapInner: function( html ) {
                +		if ( jQuery.isFunction( html ) ) {
                +			return this.each( function( i ) {
                +				jQuery( this ).wrapInner( html.call( this, i ) );
                +			} );
                +		}
                +
                +		return this.each( function() {
                +			var self = jQuery( this ),
                +				contents = self.contents();
                +
                +			if ( contents.length ) {
                +				contents.wrapAll( html );
                +
                +			} else {
                +				self.append( html );
                +			}
                +		} );
                +	},
                +
                +	wrap: function( html ) {
                +		var isFunction = jQuery.isFunction( html );
                +
                +		return this.each( function( i ) {
                +			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
                +		} );
                +	},
                +
                +	unwrap: function( selector ) {
                +		this.parent( selector ).not( "body" ).each( function() {
                +			jQuery( this ).replaceWith( this.childNodes );
                +		} );
                +		return this;
                +	}
                +} );
                +
                +
                +jQuery.expr.pseudos.hidden = function( elem ) {
                +	return !jQuery.expr.pseudos.visible( elem );
                +};
                +jQuery.expr.pseudos.visible = function( elem ) {
                +	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
                +};
                +
                +
                +
                +
                +jQuery.ajaxSettings.xhr = function() {
                +	try {
                +		return new window.XMLHttpRequest();
                +	} catch ( e ) {}
                +};
                +
                +var xhrSuccessStatus = {
                +
                +		// File protocol always yields status code 0, assume 200
                +		0: 200,
                +
                +		// Support: IE <=9 only
                +		// #1450: sometimes IE returns 1223 when it should be 204
                +		1223: 204
                +	},
                +	xhrSupported = jQuery.ajaxSettings.xhr();
                +
                +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
                +support.ajax = xhrSupported = !!xhrSupported;
                +
                +jQuery.ajaxTransport( function( options ) {
                +	var callback, errorCallback;
                +
                +	// Cross domain only allowed if supported through XMLHttpRequest
                +	if ( support.cors || xhrSupported && !options.crossDomain ) {
                +		return {
                +			send: function( headers, complete ) {
                +				var i,
                +					xhr = options.xhr();
                +
                +				xhr.open(
                +					options.type,
                +					options.url,
                +					options.async,
                +					options.username,
                +					options.password
                +				);
                +
                +				// Apply custom fields if provided
                +				if ( options.xhrFields ) {
                +					for ( i in options.xhrFields ) {
                +						xhr[ i ] = options.xhrFields[ i ];
                +					}
                +				}
                +
                +				// Override mime type if needed
                +				if ( options.mimeType && xhr.overrideMimeType ) {
                +					xhr.overrideMimeType( options.mimeType );
                +				}
                +
                +				// X-Requested-With header
                +				// For cross-domain requests, seeing as conditions for a preflight are
                +				// akin to a jigsaw puzzle, we simply never set it to be sure.
                +				// (it can always be set on a per-request basis or even using ajaxSetup)
                +				// For same-domain requests, won't change header if already provided.
                +				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
                +					headers[ "X-Requested-With" ] = "XMLHttpRequest";
                +				}
                +
                +				// Set headers
                +				for ( i in headers ) {
                +					xhr.setRequestHeader( i, headers[ i ] );
                +				}
                +
                +				// Callback
                +				callback = function( type ) {
                +					return function() {
                +						if ( callback ) {
                +							callback = errorCallback = xhr.onload =
                +								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
                +
                +							if ( type === "abort" ) {
                +								xhr.abort();
                +							} else if ( type === "error" ) {
                +
                +								// Support: IE <=9 only
                +								// On a manual native abort, IE9 throws
                +								// errors on any property access that is not readyState
                +								if ( typeof xhr.status !== "number" ) {
                +									complete( 0, "error" );
                +								} else {
                +									complete(
                +
                +										// File: protocol always yields status 0; see #8605, #14207
                +										xhr.status,
                +										xhr.statusText
                +									);
                +								}
                +							} else {
                +								complete(
                +									xhrSuccessStatus[ xhr.status ] || xhr.status,
                +									xhr.statusText,
                +
                +									// Support: IE <=9 only
                +									// IE9 has no XHR2 but throws on binary (trac-11426)
                +									// For XHR2 non-text, let the caller handle it (gh-2498)
                +									( xhr.responseType || "text" ) !== "text"  ||
                +									typeof xhr.responseText !== "string" ?
                +										{ binary: xhr.response } :
                +										{ text: xhr.responseText },
                +									xhr.getAllResponseHeaders()
                +								);
                +							}
                +						}
                +					};
                +				};
                +
                +				// Listen to events
                +				xhr.onload = callback();
                +				errorCallback = xhr.onerror = callback( "error" );
                +
                +				// Support: IE 9 only
                +				// Use onreadystatechange to replace onabort
                +				// to handle uncaught aborts
                +				if ( xhr.onabort !== undefined ) {
                +					xhr.onabort = errorCallback;
                +				} else {
                +					xhr.onreadystatechange = function() {
                +
                +						// Check readyState before timeout as it changes
                +						if ( xhr.readyState === 4 ) {
                +
                +							// Allow onerror to be called first,
                +							// but that will not handle a native abort
                +							// Also, save errorCallback to a variable
                +							// as xhr.onerror cannot be accessed
                +							window.setTimeout( function() {
                +								if ( callback ) {
                +									errorCallback();
                +								}
                +							} );
                +						}
                +					};
                +				}
                +
                +				// Create the abort callback
                +				callback = callback( "abort" );
                +
                +				try {
                +
                +					// Do send the request (this may raise an exception)
                +					xhr.send( options.hasContent && options.data || null );
                +				} catch ( e ) {
                +
                +					// #14683: Only rethrow if this hasn't been notified as an error yet
                +					if ( callback ) {
                +						throw e;
                +					}
                +				}
                +			},
                +
                +			abort: function() {
                +				if ( callback ) {
                +					callback();
                +				}
                +			}
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
                +jQuery.ajaxPrefilter( function( s ) {
                +	if ( s.crossDomain ) {
                +		s.contents.script = false;
                +	}
                +} );
                +
                +// Install script dataType
                +jQuery.ajaxSetup( {
                +	accepts: {
                +		script: "text/javascript, application/javascript, " +
                +			"application/ecmascript, application/x-ecmascript"
                +	},
                +	contents: {
                +		script: /\b(?:java|ecma)script\b/
                +	},
                +	converters: {
                +		"text script": function( text ) {
                +			jQuery.globalEval( text );
                +			return text;
                +		}
                +	}
                +} );
                +
                +// Handle cache's special case and crossDomain
                +jQuery.ajaxPrefilter( "script", function( s ) {
                +	if ( s.cache === undefined ) {
                +		s.cache = false;
                +	}
                +	if ( s.crossDomain ) {
                +		s.type = "GET";
                +	}
                +} );
                +
                +// Bind script tag hack transport
                +jQuery.ajaxTransport( "script", function( s ) {
                +
                +	// This transport only deals with cross domain requests
                +	if ( s.crossDomain ) {
                +		var script, callback;
                +		return {
                +			send: function( _, complete ) {
                +				script = jQuery( "<script>" ).prop( {
                +					charset: s.scriptCharset,
                +					src: s.url
                +				} ).on(
                +					"load error",
                +					callback = function( evt ) {
                +						script.remove();
                +						callback = null;
                +						if ( evt ) {
                +							complete( evt.type === "error" ? 404 : 200, evt.type );
                +						}
                +					}
                +				);
                +
                +				// Use native DOM manipulation to avoid our domManip AJAX trickery
                +				document.head.appendChild( script[ 0 ] );
                +			},
                +			abort: function() {
                +				if ( callback ) {
                +					callback();
                +				}
                +			}
                +		};
                +	}
                +} );
                +
                +
                +
                +
                +var oldCallbacks = [],
                +	rjsonp = /(=)\?(?=&|$)|\?\?/;
                +
                +// Default jsonp settings
                +jQuery.ajaxSetup( {
                +	jsonp: "callback",
                +	jsonpCallback: function() {
                +		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
                +		this[ callback ] = true;
                +		return callback;
                +	}
                +} );
                +
                +// Detect, normalize options and install callbacks for jsonp requests
                +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
                +
                +	var callbackName, overwritten, responseContainer,
                +		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
                +			"url" :
                +			typeof s.data === "string" &&
                +				( s.contentType || "" )
                +					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
                +				rjsonp.test( s.data ) && "data"
                +		);
                +
                +	// Handle iff the expected data type is "jsonp" or we have a parameter to set
                +	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
                +
                +		// Get callback name, remembering preexisting value associated with it
                +		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
                +			s.jsonpCallback() :
                +			s.jsonpCallback;
                +
                +		// Insert callback into url or form data
                +		if ( jsonProp ) {
                +			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
                +		} else if ( s.jsonp !== false ) {
                +			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
                +		}
                +
                +		// Use data converter to retrieve json after script execution
                +		s.converters[ "script json" ] = function() {
                +			if ( !responseContainer ) {
                +				jQuery.error( callbackName + " was not called" );
                +			}
                +			return responseContainer[ 0 ];
                +		};
                +
                +		// Force json dataType
                +		s.dataTypes[ 0 ] = "json";
                +
                +		// Install callback
                +		overwritten = window[ callbackName ];
                +		window[ callbackName ] = function() {
                +			responseContainer = arguments;
                +		};
                +
                +		// Clean-up function (fires after converters)
                +		jqXHR.always( function() {
                +
                +			// If previous value didn't exist - remove it
                +			if ( overwritten === undefined ) {
                +				jQuery( window ).removeProp( callbackName );
                +
                +			// Otherwise restore preexisting value
                +			} else {
                +				window[ callbackName ] = overwritten;
                +			}
                +
                +			// Save back as free
                +			if ( s[ callbackName ] ) {
                +
                +				// Make sure that re-using the options doesn't screw things around
                +				s.jsonpCallback = originalSettings.jsonpCallback;
                +
                +				// Save the callback name for future use
                +				oldCallbacks.push( callbackName );
                +			}
                +
                +			// Call if it was a function and we have a response
                +			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
                +				overwritten( responseContainer[ 0 ] );
                +			}
                +
                +			responseContainer = overwritten = undefined;
                +		} );
                +
                +		// Delegate to script
                +		return "script";
                +	}
                +} );
                +
                +
                +
                +
                +// Support: Safari 8 only
                +// In Safari 8 documents created via document.implementation.createHTMLDocument
                +// collapse sibling forms: the second one becomes a child of the first one.
                +// Because of that, this security measure has to be disabled in Safari 8.
                +// https://bugs.webkit.org/show_bug.cgi?id=137337
                +support.createHTMLDocument = ( function() {
                +	var body = document.implementation.createHTMLDocument( "" ).body;
                +	body.innerHTML = "<form></form><form></form>";
                +	return body.childNodes.length === 2;
                +} )();
                +
                +
                +// Argument "data" should be string of html
                +// context (optional): If specified, the fragment will be created in this context,
                +// defaults to document
                +// keepScripts (optional): If true, will include scripts passed in the html string
                +jQuery.parseHTML = function( data, context, keepScripts ) {
                +	if ( typeof data !== "string" ) {
                +		return [];
                +	}
                +	if ( typeof context === "boolean" ) {
                +		keepScripts = context;
                +		context = false;
                +	}
                +
                +	var base, parsed, scripts;
                +
                +	if ( !context ) {
                +
                +		// Stop scripts or inline event handlers from being executed immediately
                +		// by using document.implementation
                +		if ( support.createHTMLDocument ) {
                +			context = document.implementation.createHTMLDocument( "" );
                +
                +			// Set the base href for the created document
                +			// so any parsed elements with URLs
                +			// are based on the document's URL (gh-2965)
                +			base = context.createElement( "base" );
                +			base.href = document.location.href;
                +			context.head.appendChild( base );
                +		} else {
                +			context = document;
                +		}
                +	}
                +
                +	parsed = rsingleTag.exec( data );
                +	scripts = !keepScripts && [];
                +
                +	// Single tag
                +	if ( parsed ) {
                +		return [ context.createElement( parsed[ 1 ] ) ];
                +	}
                +
                +	parsed = buildFragment( [ data ], context, scripts );
                +
                +	if ( scripts && scripts.length ) {
                +		jQuery( scripts ).remove();
                +	}
                +
                +	return jQuery.merge( [], parsed.childNodes );
                +};
                +
                +
                +/**
                + * Load a url into a page
                + */
                +jQuery.fn.load = function( url, params, callback ) {
                +	var selector, type, response,
                +		self = this,
                +		off = url.indexOf( " " );
                +
                +	if ( off > -1 ) {
                +		selector = stripAndCollapse( url.slice( off ) );
                +		url = url.slice( 0, off );
                +	}
                +
                +	// If it's a function
                +	if ( jQuery.isFunction( params ) ) {
                +
                +		// We assume that it's the callback
                +		callback = params;
                +		params = undefined;
                +
                +	// Otherwise, build a param string
                +	} else if ( params && typeof params === "object" ) {
                +		type = "POST";
                +	}
                +
                +	// If we have elements to modify, make the request
                +	if ( self.length > 0 ) {
                +		jQuery.ajax( {
                +			url: url,
                +
                +			// If "type" variable is undefined, then "GET" method will be used.
                +			// Make value of this field explicit since
                +			// user can override it through ajaxSetup method
                +			type: type || "GET",
                +			dataType: "html",
                +			data: params
                +		} ).done( function( responseText ) {
                +
                +			// Save response for use in complete callback
                +			response = arguments;
                +
                +			self.html( selector ?
                +
                +				// If a selector was specified, locate the right elements in a dummy div
                +				// Exclude scripts to avoid IE 'Permission Denied' errors
                +				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
                +
                +				// Otherwise use the full result
                +				responseText );
                +
                +		// If the request succeeds, this function gets "data", "status", "jqXHR"
                +		// but they are ignored because response was set above.
                +		// If it fails, this function gets "jqXHR", "status", "error"
                +		} ).always( callback && function( jqXHR, status ) {
                +			self.each( function() {
                +				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
                +			} );
                +		} );
                +	}
                +
                +	return this;
                +};
                +
                +
                +
                +
                +// Attach a bunch of functions for handling common AJAX events
                +jQuery.each( [
                +	"ajaxStart",
                +	"ajaxStop",
                +	"ajaxComplete",
                +	"ajaxError",
                +	"ajaxSuccess",
                +	"ajaxSend"
                +], function( i, type ) {
                +	jQuery.fn[ type ] = function( fn ) {
                +		return this.on( type, fn );
                +	};
                +} );
                +
                +
                +
                +
                +jQuery.expr.pseudos.animated = function( elem ) {
                +	return jQuery.grep( jQuery.timers, function( fn ) {
                +		return elem === fn.elem;
                +	} ).length;
                +};
                +
                +
                +
                +
                +jQuery.offset = {
                +	setOffset: function( elem, options, i ) {
                +		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
                +			position = jQuery.css( elem, "position" ),
                +			curElem = jQuery( elem ),
                +			props = {};
                +
                +		// Set position first, in-case top/left are set even on static elem
                +		if ( position === "static" ) {
                +			elem.style.position = "relative";
                +		}
                +
                +		curOffset = curElem.offset();
                +		curCSSTop = jQuery.css( elem, "top" );
                +		curCSSLeft = jQuery.css( elem, "left" );
                +		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
                +			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
                +
                +		// Need to be able to calculate position if either
                +		// top or left is auto and position is either absolute or fixed
                +		if ( calculatePosition ) {
                +			curPosition = curElem.position();
                +			curTop = curPosition.top;
                +			curLeft = curPosition.left;
                +
                +		} else {
                +			curTop = parseFloat( curCSSTop ) || 0;
                +			curLeft = parseFloat( curCSSLeft ) || 0;
                +		}
                +
                +		if ( jQuery.isFunction( options ) ) {
                +
                +			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
                +			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
                +		}
                +
                +		if ( options.top != null ) {
                +			props.top = ( options.top - curOffset.top ) + curTop;
                +		}
                +		if ( options.left != null ) {
                +			props.left = ( options.left - curOffset.left ) + curLeft;
                +		}
                +
                +		if ( "using" in options ) {
                +			options.using.call( elem, props );
                +
                +		} else {
                +			curElem.css( props );
                +		}
                +	}
                +};
                +
                +jQuery.fn.extend( {
                +	offset: function( options ) {
                +
                +		// Preserve chaining for setter
                +		if ( arguments.length ) {
                +			return options === undefined ?
                +				this :
                +				this.each( function( i ) {
                +					jQuery.offset.setOffset( this, options, i );
                +				} );
                +		}
                +
                +		var doc, docElem, rect, win,
                +			elem = this[ 0 ];
                +
                +		if ( !elem ) {
                +			return;
                +		}
                +
                +		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
                +		// Support: IE <=11 only
                +		// Running getBoundingClientRect on a
                +		// disconnected node in IE throws an error
                +		if ( !elem.getClientRects().length ) {
                +			return { top: 0, left: 0 };
                +		}
                +
                +		rect = elem.getBoundingClientRect();
                +
                +		doc = elem.ownerDocument;
                +		docElem = doc.documentElement;
                +		win = doc.defaultView;
                +
                +		return {
                +			top: rect.top + win.pageYOffset - docElem.clientTop,
                +			left: rect.left + win.pageXOffset - docElem.clientLeft
                +		};
                +	},
                +
                +	position: function() {
                +		if ( !this[ 0 ] ) {
                +			return;
                +		}
                +
                +		var offsetParent, offset,
                +			elem = this[ 0 ],
                +			parentOffset = { top: 0, left: 0 };
                +
                +		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
                +		// because it is its only offset parent
                +		if ( jQuery.css( elem, "position" ) === "fixed" ) {
                +
                +			// Assume getBoundingClientRect is there when computed position is fixed
                +			offset = elem.getBoundingClientRect();
                +
                +		} else {
                +
                +			// Get *real* offsetParent
                +			offsetParent = this.offsetParent();
                +
                +			// Get correct offsets
                +			offset = this.offset();
                +			if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
                +				parentOffset = offsetParent.offset();
                +			}
                +
                +			// Add offsetParent borders
                +			parentOffset = {
                +				top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
                +				left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
                +			};
                +		}
                +
                +		// Subtract parent offsets and element margins
                +		return {
                +			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
                +			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
                +		};
                +	},
                +
                +	// This method will return documentElement in the following cases:
                +	// 1) For the element inside the iframe without offsetParent, this method will return
                +	//    documentElement of the parent window
                +	// 2) For the hidden or detached element
                +	// 3) For body or html element, i.e. in case of the html node - it will return itself
                +	//
                +	// but those exceptions were never presented as a real life use-cases
                +	// and might be considered as more preferable results.
                +	//
                +	// This logic, however, is not guaranteed and can change at any point in the future
                +	offsetParent: function() {
                +		return this.map( function() {
                +			var offsetParent = this.offsetParent;
                +
                +			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
                +				offsetParent = offsetParent.offsetParent;
                +			}
                +
                +			return offsetParent || documentElement;
                +		} );
                +	}
                +} );
                +
                +// Create scrollLeft and scrollTop methods
                +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
                +	var top = "pageYOffset" === prop;
                +
                +	jQuery.fn[ method ] = function( val ) {
                +		return access( this, function( elem, method, val ) {
                +
                +			// Coalesce documents and windows
                +			var win;
                +			if ( jQuery.isWindow( elem ) ) {
                +				win = elem;
                +			} else if ( elem.nodeType === 9 ) {
                +				win = elem.defaultView;
                +			}
                +
                +			if ( val === undefined ) {
                +				return win ? win[ prop ] : elem[ method ];
                +			}
                +
                +			if ( win ) {
                +				win.scrollTo(
                +					!top ? val : win.pageXOffset,
                +					top ? val : win.pageYOffset
                +				);
                +
                +			} else {
                +				elem[ method ] = val;
                +			}
                +		}, method, val, arguments.length );
                +	};
                +} );
                +
                +// Support: Safari <=7 - 9.1, Chrome <=37 - 49
                +// Add the top/left cssHooks using jQuery.fn.position
                +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
                +// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
                +// getComputedStyle returns percent when specified for top/left/bottom/right;
                +// rather than make the css module depend on the offset module, just check for it here
                +jQuery.each( [ "top", "left" ], function( i, prop ) {
                +	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
                +		function( elem, computed ) {
                +			if ( computed ) {
                +				computed = curCSS( elem, prop );
                +
                +				// If curCSS returns percentage, fallback to offset
                +				return rnumnonpx.test( computed ) ?
                +					jQuery( elem ).position()[ prop ] + "px" :
                +					computed;
                +			}
                +		}
                +	);
                +} );
                +
                +
                +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
                +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
                +	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
                +		function( defaultExtra, funcName ) {
                +
                +		// Margin is only for outerHeight, outerWidth
                +		jQuery.fn[ funcName ] = function( margin, value ) {
                +			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
                +				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
                +
                +			return access( this, function( elem, type, value ) {
                +				var doc;
                +
                +				if ( jQuery.isWindow( elem ) ) {
                +
                +					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
                +					return funcName.indexOf( "outer" ) === 0 ?
                +						elem[ "inner" + name ] :
                +						elem.document.documentElement[ "client" + name ];
                +				}
                +
                +				// Get document width or height
                +				if ( elem.nodeType === 9 ) {
                +					doc = elem.documentElement;
                +
                +					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
                +					// whichever is greatest
                +					return Math.max(
                +						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
                +						elem.body[ "offset" + name ], doc[ "offset" + name ],
                +						doc[ "client" + name ]
                +					);
                +				}
                +
                +				return value === undefined ?
                +
                +					// Get width or height on the element, requesting but not forcing parseFloat
                +					jQuery.css( elem, type, extra ) :
                +
                +					// Set width or height on the element
                +					jQuery.style( elem, type, value, extra );
                +			}, type, chainable ? margin : undefined, chainable );
                +		};
                +	} );
                +} );
                +
                +
                +jQuery.fn.extend( {
                +
                +	bind: function( types, data, fn ) {
                +		return this.on( types, null, data, fn );
                +	},
                +	unbind: function( types, fn ) {
                +		return this.off( types, null, fn );
                +	},
                +
                +	delegate: function( selector, types, data, fn ) {
                +		return this.on( types, selector, data, fn );
                +	},
                +	undelegate: function( selector, types, fn ) {
                +
                +		// ( namespace ) or ( selector, types [, fn] )
                +		return arguments.length === 1 ?
                +			this.off( selector, "**" ) :
                +			this.off( types, selector || "**", fn );
                +	}
                +} );
                +
                +jQuery.holdReady = function( hold ) {
                +	if ( hold ) {
                +		jQuery.readyWait++;
                +	} else {
                +		jQuery.ready( true );
                +	}
                +};
                +jQuery.isArray = Array.isArray;
                +jQuery.parseJSON = JSON.parse;
                +jQuery.nodeName = nodeName;
                +
                +
                +
                +
                +// Register as a named AMD module, since jQuery can be concatenated with other
                +// files that may use define, but not via a proper concatenation script that
                +// understands anonymous AMD modules. A named AMD is safest and most robust
                +// way to register. Lowercase jquery is used because AMD module names are
                +// derived from file names, and jQuery is normally delivered in a lowercase
                +// file name. Do this after creating the global so that if an AMD module wants
                +// to call noConflict to hide this version of jQuery, it will work.
                +
                +// Note that for maximum portability, libraries that are not jQuery should
                +// declare themselves as anonymous modules, and avoid setting a global if an
                +// AMD loader is present. jQuery is a special case. For more information, see
                +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
                +
                +if ( typeof define === "function" && define.amd ) {
                +	define( "jquery", [], function() {
                +		return jQuery;
                +	} );
                +}
                +
                +
                +
                +
                +var
                +
                +	// Map over jQuery in case of overwrite
                +	_jQuery = window.jQuery,
                +
                +	// Map over the $ in case of overwrite
                +	_$ = window.$;
                +
                +jQuery.noConflict = function( deep ) {
                +	if ( window.$ === jQuery ) {
                +		window.$ = _$;
                +	}
                +
                +	if ( deep && window.jQuery === jQuery ) {
                +		window.jQuery = _jQuery;
                +	}
                +
                +	return jQuery;
                +};
                +
                +// Expose jQuery and $ identifiers, even in AMD
                +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
                +// and CommonJS for browser emulators (#13566)
                +if ( !noGlobal ) {
                +	window.jQuery = window.$ = jQuery;
                +}
                +
                +
                +
                +
                +return jQuery;
                +} );
                diff --git a/blockly/webif/static/js/jquery-3.2.1.min.js b/blockly/webif/static/js/jquery-3.2.1.min.js
                new file mode 100644
                index 000000000..644d35e27
                --- /dev/null
                +++ b/blockly/webif/static/js/jquery-3.2.1.min.js
                @@ -0,0 +1,4 @@
                +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
                +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
                +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),
                +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r});
                diff --git a/blockly/webif/static/js/logics_blockly_code.js b/blockly/webif/static/js/logics_blockly_code.js
                new file mode 100644
                index 000000000..b383fd016
                --- /dev/null
                +++ b/blockly/webif/static/js/logics_blockly_code.js
                @@ -0,0 +1,254 @@
                +/**
                + * Create a namespace for the application.
                + */
                +var Code = {};
                +
                +/**
                + * Blockly's main workspace.
                + * @type {Blockly.WorkspaceSvg}
                + */
                +Code.workspace = null;
                +
                +/**
                + * List of tab names.
                + * @private
                + */
                +Code.TABS_ = ['blocks', 'python'];
                +
                +Code.selected = 'blocks';
                +
                +
                +
                +/**
                + * Restore code blocks from file on SmartHomeNG server
                + *
                + */
                +Code.loadBlocks = function() {
                +//  $.ajaxSetup({ cache: false });
                +  var request = $.ajax({url: 'blockly_load_logic', data : {'uniq_param' : (new Date()).getTime()}, dataType: 'text'});
                +  // we get the XML representation of all the blockly logics from the backend
                +  request.done(function(response)
                +  {
                +   	//alert('LoadBlocks - Request success: ' + response);
                +    var xml = Blockly.Xml.textToDom(response);
                +    Blockly.Xml.domToWorkspace(xml, Code.workspace);
                +    //Code.workspace.clear();
                +    Code.renderContent()
                +  });
                +  request.fail(function(jqXHR, txtStat) 
                +  {alert('LoadBlocks - Request failed: ' + txtStat);});
                +};
                +
                +
                +/**
                + * Populate the Python pane with content generated from the blocks, when selected.
                + */
                +Code.renderContent = function() {
                +	//if (Code.selected == 'python') {
                +		var content = document.getElementById('content_python');
                +		pycode = Blockly.Python.workspaceToCode(Code.workspace);
                +		content.textContent = pycode;
                +		if (typeof prettyPrintOne == 'function') {
                +		  pycode = content.innerHTML;
                +		  pycode = prettyPrintOne(pycode, 'py', true);
                +		  content.innerHTML = pycode;
                +		}
                +	//}
                +};
                +
                +Code.wait = function (ms){
                +   var start = new Date().getTime();
                +   var end = start;
                +   while(end < start + ms) {
                +     end = new Date().getTime();
                +  }
                +}
                +
                +/**
                + * Save XML and PYTHON code to file on SmartHomeNG server.
                + */
                +Code.saveBlocks = function() {
                +  var logicname = "";
                +  var topblock = Code.workspace.getTopBlocks()[0];
                +  if (topblock.data == "sh_logic_main") {
                +      logicname = Code.workspace.getTopBlocks()[0].getFieldValue('LOGIC_NAME')
                +  };
                +  //Code.workspace;
                +  var pycode = Blockly.Python.workspaceToCode(Code.workspace);
                +  var xmldom = Blockly.Xml.workspaceToDom(Code.workspace);
                +  var xmltxt = Blockly.Xml.domToText(xmldom);
                +
                +  $.ajax({  url: "blockly_save_logic",
                +            type: "POST",
                +            async: false,
                +            data: {xml: xmltxt, py: pycode, name: logicname },
                +            success: function(response) {
                +                alert(SaveBlocks - response +' ?');
                +            //    $("#test").html(response);
                +            }
                +        });
                +};
                +
                +
                +/**
                + * Discard all blocks from the workspace.
                + */
                +Code.discardBlocks = function() {
                +	var count = Code.workspace.getAllBlocks().length;
                +	if (count < 2 ||
                +	  	window.confirm(Blockly.Msg.DELETE_ALL_BLOCKS.replace('%1', count))) {
                +		Code.workspace.clear();
                +		Code.renderContent(); // ?
                +	}
                +};
                +
                +
                +/**
                + * Initialize Blockly.  Called on page load.
                + */
                +Code.init = function() {
                +
                +	var container = document.getElementById('content_area');
                +	var onresize = function(e) {
                +		var bBox = Code.getBBox_(container);
                +		for (var i = 0; i < Code.TABS_.length; i++) {
                +			var el = document.getElementById('content_' + Code.TABS_[i]);
                +			el.style.top = bBox.y + 'px';
                +			el.style.left = bBox.x + 'px';
                +			// Height and width need to be set, read back, then set again to
                +			// compensate for scrollbars.
                +			el.style.height = bBox.height + 'px';
                +			el.style.height = (2 * bBox.height - el.offsetHeight) + 'px';
                +			el.style.width = bBox.width + 'px';
                +			el.style.width = (2 * bBox.width - el.offsetWidth) + 'px';
                +		}
                +		// Make the 'Blocks' tab line up with the toolbox.
                +		if (Code.workspace && Code.workspace.toolbox_.width) {
                +			document.getElementById('tab_blocks').style.minWidth =
                +				(Code.workspace.toolbox_.width ) + 'px';
                +				// Account for the 19 pixel margin and on each side.
                +		}
                +	};
                +	window.addEventListener('resize', onresize, false);
                +	
                +	var toolboxtxt = document.getElementById('toolbox').outerHTML;
                +	var toolboxXml = Blockly.Xml.textToDom(toolboxtxt);
                +	
                +	Code.workspace = Blockly.inject('content_blocks',
                +	  {grid:
                +	      {spacing: 25,
                +	       length: 3,
                +	       colour: '#ccc',
                +	       snap: true},
                +	   media: 'static/blockly/media/',
                +	   //rtl: rtl,
                +	   toolbox: toolboxXml,
                +	   zoom:
                +	       {controls: true,
                +	        wheel: true}
                +	  });
                +	
                +	//window.setTimeout(Code.loadBlocks, 0);
                +	Code.loadBlocks();
                +	
                +	Code.tabClick(Code.selected);
                +	
                +	Code.bindClick('tab_blocks', function(name_) {return function() {Code.tabClick(name_);};}('blocks'));
                +	Code.bindClick('tab_python', function(name_) {return function() {Code.tabClick(name_);};}('python'));
                +	
                +	onresize();
                +	Blockly.svgResize(Code.workspace);
                +	
                +	// Lazy-load the syntax-highlighting.
                +	Code.importPrettify();
                +	window.setTimeout(Code.importPrettify, 1);
                +};
                +
                +/**
                + * Bind a function to a button's click event.
                + * On touch enabled browsers, ontouchend is treated as equivalent to onclick.
                + * @param {!Element|string} el Button element or ID thereof.
                + * @param {!Function} func Event handler to bind.
                + */
                +Code.bindClick = function(el, func) {
                +  if (typeof el == 'string') {
                +    el = document.getElementById(el);
                +  }
                +  el.addEventListener('click', func, true);
                +  el.addEventListener('touchend', func, true);
                +};
                +
                +
                +/**
                + * Switch the visible pane when a tab is clicked.
                + * @param {string} clickedName Name of tab clicked.
                + */
                +Code.tabClick = function(clickedName) {
                +
                +  if (document.getElementById('tab_blocks').className == 'tabon') {
                +    Code.workspace.setVisible(false);
                +  }
                +
                +  if (clickedName == 'blocks') {
                +	document.getElementById('tab_python').className = 'taboff';
                +	document.getElementById('tab_blocks').className = 'tabon';
                +	document.getElementById('content_python').style.visibility = 'hidden';
                +	document.getElementById('content_blocks').style.visibility = 'visible';
                +    Code.workspace.setVisible(true);
                +  } else {
                +	document.getElementById('tab_blocks').className = 'taboff';
                +	document.getElementById('tab_python').className = 'tabon';
                +	document.getElementById('content_blocks').style.visibility = 'hidden';
                +	document.getElementById('content_python').style.visibility = 'visible';
                +  }
                +
                +  Code.renderContent();
                +  Blockly.svgResize(Code.workspace);
                +};
                +
                +/**
                + * Load the Prettify CSS and JavaScript.
                + */
                +Code.importPrettify = function() {
                +  //<link rel="stylesheet" href="../prettify.css">
                +  //<script src="../prettify.js"></script>
                +  var link = document.createElement('link');
                +  link.setAttribute('rel', 'stylesheet');
                +  link.setAttribute('href', 'static/js/google-prettify/prettify.css');
                +  document.head.appendChild(link);
                +  var script = document.createElement('script');
                +  script.setAttribute('src', 'static/js/google-prettify/prettify.js');
                +  document.head.appendChild(script);
                +};
                +
                +
                +/**
                + * Compute the absolute coordinates and dimensions of an HTML element.
                + * @param {!Element} element Element to match.
                + * @return {!Object} Contains height, width, x, and y properties.
                + * @private
                + */
                +Code.getBBox_ = function(element) {
                +  var height = element.offsetHeight;
                +  var width = element.offsetWidth;
                +  var x = 0;
                +  var y = 0;
                +  do {
                +    x += element.offsetLeft;
                +    y += element.offsetTop;
                +    element = element.offsetParent;
                +  } while (element);
                +  return {
                +    height: height,
                +    width: width,
                +    x: x,
                +    y: y
                +  };
                +};
                +
                +
                +/**
                + *  Init on window load
                + * */
                +window.addEventListener('load', Code.init);
                +
                diff --git a/blockly/webif/static/js/npm.js b/blockly/webif/static/js/npm.js
                new file mode 100644
                index 000000000..bf6aa8060
                --- /dev/null
                +++ b/blockly/webif/static/js/npm.js
                @@ -0,0 +1,13 @@
                +// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
                +require('../../js/transition.js')
                +require('../../js/alert.js')
                +require('../../js/button.js')
                +require('../../js/carousel.js')
                +require('../../js/collapse.js')
                +require('../../js/dropdown.js')
                +require('../../js/modal.js')
                +require('../../js/tooltip.js')
                +require('../../js/popover.js')
                +require('../../js/scrollspy.js')
                +require('../../js/tab.js')
                +require('../../js/affix.js')
                \ No newline at end of file
                diff --git a/blockly/webif/static/shblocks/sh_items.js b/blockly/webif/static/shblocks/sh_items.js
                new file mode 100644
                index 000000000..9c65b0d1b
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_items.js
                @@ -0,0 +1,211 @@
                +/**
                + * @license
                + * Visual Blocks Editor for smarthome.py
                + *
                + * Copyright 2015 Dirk Wallmeier
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Variable blocks for Blockly.
                + * @author DW
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.sh_items');
                +
                +goog.require('Blockly.Blocks');
                +
                +Blockly.Blocks['sh_item_obj'] = {
                +  init: function() {
                +    var hiddenFieldPath = new Blockly.FieldTextInput("Path");
                +    hiddenFieldPath.setVisible(false);	  
                +    var hiddenFieldType = new Blockly.FieldTextInput("Type");
                +    hiddenFieldType.setVisible(false);
                +    var fixedFieldName = new Blockly.FieldTextInput("Name");
                +    this.appendDummyInput()
                +        //.appendField("Item: ")
                +        .appendField(fixedFieldName, "N")
                +        .appendField(hiddenFieldPath, "P")
                +        .appendField(hiddenFieldType, "T")
                +    this.setOutput(true, "shItemType");
                +    this.setColour(210);
                +    this.setTooltip(this.getFieldValue('P'));
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setEditable(false);   
                +  }
                +};
                +
                +Blockly.Python['sh_item_obj'] = function(block) {
                +  var iName = block.getFieldValue('N');
                +  var iPath = block.getFieldValue('P');
                +  
                +  // TODO: Assemble Python into code variable.
                +  var code = 'sh.return_item("' + iPath + '")';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +  //return code;
                +};
                +
                +
                +
                +/*Blockly.Blocks['sh_item'] = {
                +  /**
                +   * Block for item
                +   * @this Blockly.Block
                +   * /
                +  init: function() {
                +    var itemlist = new Blockly.FieldTextInput('0');
                +    itemlist.setVisible(false);
                +    var dropdown = new Blockly.FieldDropdown( function () {
                +                              var il = new Array();
                +                              il = itemlist.getValue();
                +                              if (il != '0') { il = eval("(function(){return " + il + ";})()");};
                +                              return il;
                +                             } );
                +    this.setColour(340);
                +    this.appendDummyInput()
                +        .appendField(itemlist, 'ITEMLIST')
                +        .appendField('Item')
                +        .appendField(dropdown, 'ITEM');
                +    this.setOutput(true, "SHITEM");
                +    this.setTooltip('Gibt ein Item Objekt zurück.');
                +  },
                +};
                +
                +Blockly.Python['sh_item'] = function(block) {
                +  // Variable getter.
                +  var code = 'sh.' + block.getFieldValue('ITEM');
                +  return [code, Blockly.Python.ORDER_ATOMIC];
                +};
                +*/
                +
                +Blockly.Blocks['sh_item_get'] = {
                +  /**
                +   * Block for item getter. -> this is a "Sensor"
                +   * @this Blockly.Block
                +   */
                +    init: function() {
                +        this.setHelpUrl('');
                +        this.setColour(260);
                +        this.appendValueInput("ITEMOBJECT")
                +            .setCheck("shItemType")
                +            .appendField("Wert von");
                +        this.setInputsInline(true);
                +        this.setOutput(true);
                +        this.setTooltip('Gibt den Wert des Items zurück.');
                +    }
                +};
                +
                +Blockly.Python['sh_item_get'] = function(block) {
                +    var itemobj = Blockly.Python.valueToCode(block, 'ITEMOBJECT', Blockly.Python.ORDER_ATOMIC) || 'item';
                +    var code = itemobj + '()';
                +    //return [code, Blockly.Python.ORDER_NONE];
                +    return code;
                +};
                +
                +
                +Blockly.Blocks['sh_item_set'] = {
                +  /**
                +   * Block for item setter.
                +   * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#7wv5ve
                +   */
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(260);
                +    this.appendValueInput("ITEMOJECT")
                +        .setCheck("shItemType")
                +        .appendField("setze");
                +    this.appendValueInput("VALUE")
                +        .appendField("auf den Wert");
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('');
                +  }
                +};
                +
                +Blockly.Python['sh_item_set'] = function(block) {
                +  var itemobject = Blockly.Python.valueToCode(block, 'ITEMOJECT', Blockly.Python.ORDER_ATOMIC) || 'item';
                +  var value = Blockly.Python.valueToCode(block, 'VALUE', Blockly.Python.ORDER_ATOMIC) || '0';
                +  // TODO: Assemble Python into code variable.
                +  //var code = '...';
                +  var code = itemobject + '(' + value + ')\n';
                +  //return [code, Blockly.Python.ORDER_FUNCTION_CALL];
                +  return code;
                +};
                +
                +
                +
                +Blockly.Blocks['sh_item_attr'] = {
                +  init: function() {
                +    var attrlist = new Blockly.FieldTextInput('0');
                +    attrlist.setVisible(false);
                +    var dropdown = new Blockly.FieldDropdown( function () {
                +                              var al = new Array();
                +                              al = attrlist.getValue();
                +                              if (al != '0') { al = eval("(function(){return " + al + ";})()");};
                +                              return al;
                +                             } );
                +    this.appendDummyInput()
                +        .appendField("Attribut")
                +        .appendField(dropdown, "ATTR")
                +        .appendField("von Item");
                +    this.appendValueInput("ITEM")
                +        .setCheck("shItemType");
                +    this.setInputsInline(true);
                +    this.setOutput(true, null);
                +    this.setColour(120);
                +    this.setTooltip('');
                +    this.setHelpUrl('http://www.example.com/');
                +  }
                +};
                +
                +Blockly.Python['sh_item_attr'] = function(block) {
                +  var dropdown_attr = block.getFieldValue('ATTR');
                +  var value_item = Blockly.Python.valueToCode(block, 'ITEM', Blockly.Python.ORDER_ATOMIC);
                +  // TODO: Assemble Python into code variable.
                +  var code = '...';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +Blockly.Blocks['sh_item_hasattr'] = {
                +  init: function() {
                +    this.appendDummyInput()
                +        .appendField("das Item");
                +    this.appendValueInput("ITEM")
                +        .setCheck("shItemType");
                +    this.appendDummyInput()
                +        .appendField("hat das Atribut")
                +        .appendField(new Blockly.FieldTextInput("default"), "ATTR");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "Boolean");
                +    this.setColour(120);
                +    this.setTooltip('');
                +    this.setHelpUrl('http://www.example.com/');
                +  }
                +};
                +
                +Blockly.Python['sh_item_hasattr'] = function(block) {
                +  var value_item = Blockly.Python.valueToCode(block, 'ITEM', Blockly.Python.ORDER_ATOMIC);
                +  var text_attr = block.getFieldValue('ATTR');
                +  // TODO: Assemble Python into code variable.
                +  var code = '...';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  var code = 'sh.iHasAttr(' + value_item + ', ' + text_attr +' )';
                +    return [code, Blockly.Python.ORDER_NONE];
                +
                +};
                \ No newline at end of file
                diff --git a/blockly/webif/static/shblocks/sh_logic.js b/blockly/webif/static/shblocks/sh_logic.js
                new file mode 100644
                index 000000000..1444635e7
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_logic.js
                @@ -0,0 +1,117 @@
                +/**
                + * @license
                +            <block type="shlogic_by"></block>
                +            <block type="shlogic_source"></block>
                +            <block type="shlogic_dest"></block>
                +            <block type="shlogic_trigger"></block>
                + */
                +'use strict';
                +goog.provide('Blockly.Blocks.sh_logic');
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#ojesy8
                + */
                +Blockly.Blocks['shlogic_by'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Auslöser (trigger['by'])");
                +    this.setOutput(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shlogic_by'] = function(block) {
                +  var code = "trigger['by']";
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#umj2u6
                + */
                +Blockly.Blocks['shlogic_value'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Auslöser (trigger['value'])");
                +    this.setOutput(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shlogic_value'] = function(block) {
                +  var code = "trigger['value']";
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#p3ajqk
                + */
                +Blockly.Blocks['shlogic_source'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Auslöser (trigger['Source'])");
                +    this.setOutput(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shlogic_source'] = function(block) {
                +  var code = "trigger['source']";
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#8jdhtt
                + */
                +Blockly.Blocks['shlogic_dest'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Auslöser (trigger['Dest'])");
                +    this.setOutput(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shlogic_dest'] = function(block) {
                +  var code = "trigger['dest']";
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#r74ibg
                + */
                +/**
                +Blockly.Blocks['shlogic_trigger'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("diese Logik auslösen um ");
                +    this.appendValueInput("DATETIME");
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shlogic_trigger'] = function(block) {
                +  var value_datetime = Blockly.Python.valueToCode(block, 'DATETIME', Blockly.Python.ORDER_ATOMIC);
                +  // TODO: Assemble Python into code variable.
                +  var code = '...';
                +  return code;
                +};
                + */
                + 
                diff --git a/blockly/webif/static/shblocks/sh_logics.js b/blockly/webif/static/shblocks/sh_logics.js
                new file mode 100755
                index 000000000..f24a433c8
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_logics.js
                @@ -0,0 +1,477 @@
                +/**
                + * @license
                + * Visual Blocks Editor
                + *
                + * Copyright 2012 Google Inc.
                + * https://developers.google.com/blockly/
                + *
                + * Licensed under the Apache License, Version 2.0 (the "License");
                + * you may not use this file except in compliance with the License.
                + * You may obtain a copy of the License at
                + *
                + *   http://www.apache.org/licenses/LICENSE-2.0
                + *
                + * Unless required by applicable law or agreed to in writing, software
                + * distributed under the License is distributed on an "AS IS" BASIS,
                + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                + * See the License for the specific language governing permissions and
                + * limitations under the License.
                + */
                +
                +/**
                + * @fileoverview Logic blocks for Blockly.
                + * @author q.neutron@gmail.com (Quynh Neutron)
                + */
                +'use strict';
                +
                +goog.provide('Blockly.Blocks.sh_trigger');
                +
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * Logic main block
                + */
                +Blockly.Blocks['sh_logic_main'] = {
                +  /**
                +   * Block for if/elseif/else condition.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +/**
                +    Blockly.HSV_SATURATION = 0.45; 
                +    Blockly.HSV_VALUE = 0.65;
                + */
                +    this.setColour(125);
                +    this.appendValueInput("LOGIC")
                +        .setCheck("shItemType")
                +        .setAlign(Blockly.ALIGN_LEFT)
                +        .appendField("Logik")
                +        .appendField(new Blockly.FieldTextInput("new_logic"), 'LOGIC_NAME')
                +        .appendField('(Dateiname zum speichern ohne Extension)');
                +    this.appendStatementInput('DO');
                +//    this.appendStatementInput('DO')
                +//        .appendField('starte');
                +    this.appendDummyInput()
                +        .appendField(new Blockly.FieldCheckbox("TRUE"), "ACTIVE")
                +        .appendField(new Blockly.FieldTextInput("Kommentar"), "COMMENT");
                +        
                +    this.setPreviousStatement(false);
                +    this.setNextStatement(false);
                +    this.setTooltip('Block wird ausgeführt, sobald sich der Wert des Triggers ändert.');
                +    }
                +};
                +
                +
                +function GetTriggerComment(trigger_block)
                +{
                +  var comment = '';
                +  var trigger_comment = trigger_block.getFieldValue('COMMENT');
                +  if (trigger_comment != 'Kommentar') {
                +    comment += trigger_comment;
                +  };    
                +  return comment.trim();
                +};
                +
                +function GetTrigger(trigger_block)
                +{
                +  var trigger = '';
                +  var trigger_id = trigger_block.getFieldValue('NAME');
                +  if (trigger_block.data == 'sh_trigger_cycle') {
                +    var trigger_id= trigger_block.getFieldValue('NAME');
                +    trigger += '    cycle: ' + trigger_block.getFieldValue('TRIG_CYCLE');
                +  };
                +  if (trigger_block.data == 'sh_trigger_item') {
                +    var trigger_id= trigger_block.getFieldValue('NAME');
                +    var itemcode = Blockly.Python.valueToCode(trigger_block, 'TRIG_ITEM', Blockly.Python.ORDER_ATOMIC);
                +    var itemid = itemcode.split('"')[1] 
                +    trigger += '    watch_item: ' + itemid;
                +  };
                +  if (trigger_block.data == 'sh_trigger_sun') {
                +    var offset    = trigger_block.getFieldValue('OFFSET');
                +    var plusminus = trigger_block.getFieldValue('PLUSMINUS');
                +    var sun       = trigger_block.getFieldValue('SUN');
                +    trigger += '    crontab: ' + sun + plusminus + offset;
                +  };
                +  if (trigger_block.data == 'sh_trigger_daily') {
                +//    var trigger_id= trigger_block.getFieldValue('NAME');
                +    var hh = trigger_block.getFieldValue('HH');
                +    var mm = trigger_block.getFieldValue('MM');
                +    trigger += '    crontab: ' + + mm + ' ' + hh + ' * *';
                +  };
                +  if (trigger_block.data == 'sh_trigger_init') {
                +    trigger += '    crontab: init';
                +  };
                +  if (trigger_id != '' && trigger_id != 'trigger_id')
                +  {
                +    trigger += ' = ' + trigger_id
                +  };
                +  return trigger;
                +};
                +
                +function GetMultiTriggers(trigger_block)
                +{
                +  var cr_list = [];
                +  var crc_list = [];
                +  var wi_list = [];
                +  var wic_list = [];
                +  var contab_triggers = ['sh_trigger_sun', 'sh_trigger_daily', 'sh_trigger_init'];
                +  var next_block = trigger_block;
                +  
                +  while (next_block != null) {
                +    if (next_block.data != '')
                +    {
                +      if (contab_triggers.indexOf(next_block.data) > -1)
                +      {
                +        var trigger = GetTrigger(next_block);
                +        if (trigger.trim() != '') {
                +          cr_list.push(trigger.split(':')[1].trim());
                +        };
                +        crc_list.push(GetTriggerComment(next_block));
                +      };
                +      if (next_block.data == 'sh_trigger_item')
                +      {
                +        var trigger = GetTrigger(next_block);
                +        if (trigger.trim() != '') {
                +          wi_list.push(trigger.split(':')[1].trim());
                +        };
                +        wic_list.push(GetTriggerComment(next_block));
                +      };
                +    };
                +    var next_block = next_block.getNextBlock();
                +  };
                +  return [cr_list, crc_list, wi_list, wic_list];
                +};
                +
                +function NextLevel(trigger_block, logicname, ignore_crontab, ignore_watchitem)
                +{
                +  var tr_insert = ''
                +  var tr_comment = ''
                +  if (trigger_block != null) {
                +    if (trigger_block.data != null) {
                +      var comment = GetTriggerComment(trigger_block)
                +      var trigger = GetTrigger(trigger_block);
                +      if (ignore_crontab && (trigger.trim().substring(0,8) == 'crontab:'))
                +      {
                +        trigger = '';
                +      };
                +      if (ignore_watchitem && (trigger.trim().substring(0,11) == 'watch_item:'))
                +      {
                +        trigger = '';
                +      };
                +      if (trigger.trim() != '') {
                +        tr_insert += '#trigger#'+logicname+'#filename: '+logicname+'.py#' + trigger.trim() + '#' + comment + '\n';
                +        var line = trigger;
                +        if (comment != '') {
                +          line = line.padEnd(50) + ' # ' + comment
                +        };
                +        tr_comment += line + '\n';
                +      };
                +      
                +      var next_block = trigger_block.getNextBlock();
                +      var next = NextLevel(next_block, logicname, ignore_crontab, ignore_watchitem);
                +      tr_insert += next[0];
                +      tr_comment += next[1];
                +    };
                +    return [tr_insert, tr_comment];
                +  };
                +};
                +
                +Blockly.Python['sh_logic_main'] = function(block)
                +{
                +  this.data = 'sh_logic_main'
                +  var trigger_block = block.getChildren();
                +  var triggerid = Blockly.Python.variableDB_.getDistinctName('trigger_id', Blockly.Variables.NAME_TYPE);
                +  var itemcode = Blockly.Python.valueToCode(block, 'TRIG_ITEM', Blockly.Python.ORDER_ATOMIC);
                +  var itemid = itemcode.split('"')[1] 
                +  //var item = block.getFieldValue('TRIG_ITEM');
                +  var branch = Blockly.Python.statementToCode(block, 'DO') ;
                +  //var branch = Blockly.Python.statementToCode(block, 'DO') || '  pass\n';
                +  var checkbox_active = (block.getFieldValue('ACTIVE') == 'TRUE') ? 'True' : 'False';
                +  var text_comment = block.getFieldValue('COMMENT');
                +
                +  var triggerid = block.getFieldValue('NAME');
                +  var itemcode = Blockly.Python.valueToCode(block, 'TRIG_ITEM', Blockly.Python.ORDER_ATOMIC);
                +  var itemid = itemcode.split('"')[1] 
                +
                +  var code = '';
                +  var trigger = '';
                +  var logicname = block.getFieldValue('LOGIC_NAME').toLowerCase().replace(" ", "_");
                +  block.setFieldValue(logicname, 'LOGIC_NAME');
                +
                +  var active = block.getFieldValue('ACTIVE');
                +  if (active == 'TRUE') {
                +    active = 'True';
                +  } else {
                +    active = 'False';
                +  };
                +
                +  if (text_comment.length > 0) {
                +    code += '#comment#'+logicname+'#filename: '+logicname+'.py#active: ' + active + '#' + text_comment + '\n';
                +  };
                +
                +  var tr_list = GetMultiTriggers(trigger_block[0]);
                +  var tr_crontab_list = tr_list[0];
                +  var tr_crontabc_list = tr_list[1];
                +  var tr_watchitem_list = tr_list[2];
                +  var tr_watchitemc_list = tr_list[3];
                +
                +  if (trigger_block.length > 0) {
                +    var next = NextLevel(trigger_block[0], logicname, (tr_crontab_list.length > 1), (tr_watchitem_list.length > 1));
                +    code += next[0];
                +  };
                +
                +  if (tr_crontab_list.length > 1)
                +  {
                +    var tr_list = '';
                +    var co_list = '';
                +    for (var t in tr_crontab_list) {
                +      if (t > 0) {
                +        tr_list += ',';
                +        co_list += ',';
                +      };
                +      tr_list += "'"+tr_crontab_list[t]+"'";
                +      co_list += "'"+tr_crontabc_list[t]+"'";
                +    };
                +    code += '#trigger#'+logicname+'#filename: '+logicname+'.py#crontab: [' + tr_list + ']#[' + co_list + ']\n';
                +  };
                +  
                +  if (tr_watchitem_list.length > 1)
                +  {
                +    var tr_list = '';
                +    var co_list = '';
                +    for (var t in tr_watchitem_list) {
                +      if (t > 0) {
                +        tr_list += ',';
                +        co_list += ',';
                +      };
                +      tr_list += "'"+tr_watchitem_list[t]+"'";
                +      co_list += "'"+tr_watchitemc_list[t]+"'";
                +    };
                +    code += '#trigger#'+logicname+'#filename: '+logicname+'.py#watch_item: [' + tr_list + ']#[' + co_list + ']\n';
                +  };
                +  
                +  code += '"""\n' + 'Logic '+ logicname + '.py\n';
                +  code += '\n' + text_comment + '\n';
                +  
                +  code += "\nTHIS FILE WAS GENERATED FROM A BLOCKY LOGIC WORKSHEET - DON'T EDIT THIS FILE, use the Blockly plugin instead !\n" 
                +  if (next[1] != '') {
                +    var trigger_comment = trigger_block[0].getFieldValue('COMMENT');
                +    code += '\nto be configured in /etc/logic.yaml:\n';
                +    code += "\n"+logicname+":\n";
                +    var line = "    filename: "+logicname+".py"
                +    if (text_comment != '') {
                +      line = line.padEnd(50) + ' # ' + text_comment
                +    };
                +    code += line + '\n';
                +    code += next[1];
                +  };
                +  
                +  if (tr_watchitem_list.length > 1)
                +  {
                +    code += '    watch_item:\n'
                +    for (var t in tr_watchitem_list) {
                +      code += '     - ' + tr_watchitem_list[t] + '\n';
                +    };
                +  };
                +  if (tr_crontab_list.length > 1)
                +  {
                +    code += '    crontab:\n'
                +    for (var t in tr_crontab_list) {
                +      code += '     - ' + tr_crontab_list[t] + '\n';
                +    };
                +  };
                +  code += '"""\n';
                +
                +  code += "logic_active = "+ active +"\n";
                +  code += "if (logic_active == True):\n";
                +  //code += "  logger.info('ITEM TRIGGER id: \{\}, value: \{\}'.format(logic.name, trigger['value'] )) \n";
                +  code += branch;
                +  return code + "\n\n";
                +};
                +
                +
                +/**
                + * Trigger die Logic bei Änderung des Items
                + */
                +Blockly.Blocks['sh_trigger_item'] = {
                +  /**
                +   * Block for if/elseif/else condition.
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.data = 'sh_trigger_item'
                +    this.setColour(190);
                +    this.appendValueInput("TRIG_ITEM")
                +        .setCheck("shItemType")
                +        .setAlign(Blockly.ALIGN_LEFT)
                +        .appendField("Trigger: Auslösen bei Änderung von");
                +//    this.appendStatementInput('DO')
                +//        .appendField('starte');
                +//    this.appendDummyInput()
                +//        .appendField(new Blockly.FieldCheckbox("TRUE"), "ACTIVE")
                +    this.appendDummyInput()
                +        .appendField("als Trigger")
                +        .appendField(new Blockly.FieldTextInput("trigger_id"), "NAME");
                +    this.appendDummyInput()
                +        .appendField("Kommentar")
                +        .appendField(new Blockly.FieldTextInput(""), "COMMENT");
                +        
                +    this.setInputsInline(false);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Block wird ausgeführt, sobald sich der Wert des Triggers ändert.');
                +    }
                +};
                +
                +Blockly.Python['sh_trigger_item'] = function(block)
                +{
                +  var code = '';
                +  return code;
                +};
                +
                +
                +/**
                + * Trigger ... alle x sec.
                + */
                +Blockly.Blocks['sh_trigger_cycle'] = {
                +  /**
                +   * Block for
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.data = 'sh_trigger_cycle';
                +    this.setColour(190);
                +    this.appendDummyInput()
                +        .appendField('Trigger: alle')
                +//        .appendField(new Blockly.FieldTextInput('60',
                +//            Blockly.FieldTextInput.nonnegativeIntegerValidator), 'TRIG_CYCLE')
                +        .appendField(new Blockly.FieldNumber(60, 0), 'TRIG_CYCLE')
                +        .appendField('Sekunden auslösen')
                +//    this.appendDummyInput()
                +        .appendField("als Trigger")
                +        .appendField(new Blockly.FieldTextInput("trigger_id"), "NAME");
                +    this.appendDummyInput()
                +        .appendField("Kommentar")
                +        .appendField(new Blockly.FieldTextInput(""), "COMMENT");
                +    this.setInputsInline(false);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Block wird nach vorgegebener Zeit wiederholt ausgeführt.');
                +    }
                +};
                +
                +Blockly.Python['sh_trigger_cycle'] = function(block) {
                +  var code = ''
                +  return code;
                +};
                +
                +/**
                + * Trigger vor/nach Sonnen-Auf-/Untergang.
                + */
                +Blockly.Blocks['sh_trigger_sun'] = {
                +  /**
                +   * Block for
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.data = 'sh_trigger_sun';
                +    this.setColour(190);
                +    this.appendDummyInput()
                +        .appendField('Trigger (crontab): Auslösen')
                +//        .appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.nonnegativeIntegerValidator), 'OFFSET')
                +        .appendField(new Blockly.FieldNumber(0, 0), 'OFFSET')
                +        .appendField('Minuten')
                +        .appendField(new Blockly.FieldDropdown( [['vor', '-'], ['nach', '+']] ), 'PLUSMINUS')
                +        .appendField('Sonnen-')
                +        .appendField(new Blockly.FieldDropdown( [['Aufgang', 'sunrise'], ['Untergang', 'sunset']] ), 'SUN')
                +        .appendField("als Trigger")
                +        .appendField(new Blockly.FieldTextInput("trigger_id"), "NAME");
                +    this.appendDummyInput()
                +        .appendField("Kommentar")
                +        .appendField(new Blockly.FieldTextInput(""), "COMMENT");
                +    this.setInputsInline(false);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Block wird vor/nach Sonnenaufgang/Sonnenuntergang ausgeführt.');
                +    }
                +};
                +
                +Blockly.Python['sh_trigger_sun'] = function(block)
                +{
                +  var code = '';
                +  return code;
                +};
                +
                +
                +/**
                + * Trigger taeglich um HH:MM Uhr
                + */
                +Blockly.Blocks['sh_trigger_daily'] = {
                +  /**
                +   * Block for
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.data = 'sh_trigger_daily';
                +    this.setColour(190);
                +    this.appendDummyInput()
                +        .appendField('Trigger (crontab): Jeden Tag ')
                +        .appendField('um')
                +//        .appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.nonnegativeIntegerValidator), 'HH')
                +        .appendField(new Blockly.FieldNumber(0, 0), 'HH')
                +        .appendField(':')
                +//        .appendField(new Blockly.FieldTextInput('0', Blockly.FieldTextInput.nonnegativeIntegerValidator), 'MM')
                +        .appendField(new Blockly.FieldNumber(0, 0), 'MM')
                +        .appendField('Uhr')
                +//    this.appendDummyInput()
                +//        .appendField(new Blockly.FieldCheckbox("TRUE"), "ACTIVE");
                +        .appendField("als Trigger")
                +        .appendField(new Blockly.FieldTextInput("trigger_id"), "NAME");
                +    this.appendDummyInput()
                +        .appendField("Kommentar")
                +        .appendField(new Blockly.FieldTextInput(""), "COMMENT");
                +    this.setInputsInline(false);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Block wird täglich zur gegebenen Stunde ausgeführt.');
                +    }
                +};
                +
                +Blockly.Python['sh_trigger_daily'] = function(block)
                +{
                +  var code = '';
                +  return code;
                +};
                +
                +
                +/**
                + * Trigger bei Initialisierung auslösen
                + */
                +Blockly.Blocks['sh_trigger_init'] = {
                +  /**
                +   * Block for
                +   * @this Blockly.Block
                +   */
                +  init: function() {
                +    this.data = 'sh_trigger_init';
                +    this.setColour(190);
                +    this.appendDummyInput()
                +        .appendField('Trigger (crontab): Bei Initialisierung auslosen, ')
                +        .appendField("als Trigger")
                +        .appendField(new Blockly.FieldTextInput("Init"), "NAME");
                +    this.appendDummyInput()
                +        .appendField("Kommentar")
                +        .appendField(new Blockly.FieldTextInput(""), "COMMENT");
                +    this.setInputsInline(false);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('Block wird bei der Initialisierung ausgeführt.');
                +    }
                +};
                +
                +Blockly.Python['sh_trigger_init'] = function(block)
                +{
                +  var code = '';
                +  return code;
                +};
                diff --git a/blockly/webif/static/shblocks/sh_notify.js b/blockly/webif/static/shblocks/sh_notify.js
                new file mode 100644
                index 000000000..c0ff51f44
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_notify.js
                @@ -0,0 +1,95 @@
                +/**
                + * @license
                +            <block type="shnotify_email"></block>
                +            <block type="shnotify_prowl"></block>
                +            <block type="shnotify_nma"></block>
                +            <block type="shnotify_pushbullit"></block>
                + */
                +'use strict';
                +goog.provide('Blockly.Blocks.sh_logic');
                +goog.require('Blockly.Blocks');
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#c2zkf2
                + */
                +Blockly.Blocks['shnotify_email'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("eine eMail senden an")
                +        .appendField(new Blockly.FieldTextInput("mail@smarthome.py"), "TO")
                +        .appendField("mit Betreff")
                +        .appendField(new Blockly.FieldTextInput("Nachricht von SmartHome"), "SUBJECT")
                +        .appendField("und Text:");
                +    this.appendValueInput("TEXT")
                +        .setCheck("String");
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shnotify_email'] = function(block) {
                +  var to = block.getFieldValue('TO');
                +  var subject = block.getFieldValue('SUBJECT');
                +  var text = Blockly.Python.valueToCode(block, 'TO', Blockly.Python.ORDER_ATOMIC);
                +  // TODO: Assemble Python into code variable.
                +  var code = 'if sh.mail: sh.mail('+to+', '+subject+', '+text+')';
                +  return code;
                +};
                +
                +
                +Blockly.Blocks['shnotify_prowl'] = {
                +  /**
                +   * Block for
                +   */
                +  init: function() {
                +    this.setColour(340);
                +    this.appendDummyInput().appendField('Sende Nachricht mit PROWL:');
                +  },
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#ptwi98
                + */
                +Blockly.Blocks['shnotify_nma'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("eine NMA Nachricht senden")
                +        .appendField("mit Betreff")
                +        .appendField(new Blockly.FieldTextInput("Nachricht von SmartHome"), "SUBJECT")
                +        .appendField("und Text:");
                +    this.appendValueInput("TEXT")
                +        .setCheck("String");
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shnotify_nma'] = function(block) {
                +  var text_subject = block.getFieldValue('SUBJECT');
                +  var value_text = Blockly.Python.valueToCode(block, 'TEXT', Blockly.Python.ORDER_ATOMIC);
                +  // TODO: Assemble Python into code variable.
                +  var code = '...';
                +  return code;
                +};
                +
                +
                +/**
                + * https://
                + */
                +Blockly.Blocks['shnotify_pushbullit'] = {
                +  /**
                +   * Block for
                +   */
                +  init: function() {
                +    this.setColour(340);
                +    this.appendDummyInput().appendField('Sende Nachricht mit Pushbullit:');
                +  },
                +};
                +
                diff --git a/blockly/webif/static/shblocks/sh_time.js b/blockly/webif/static/shblocks/sh_time.js
                new file mode 100644
                index 000000000..58018d5c9
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_time.js
                @@ -0,0 +1,122 @@
                +/**
                + * @license
                +            <block type="shtime_now"></block>
                +            <block type="shtime_time"></block>
                +            <block type="shtime_sun"></block>
                +            <block type="shtime_moon"></block>
                +            <block type="shtime_auto"></block>
                + */
                +'use strict';
                +goog.provide('Blockly.Blocks.sh_logic');
                +goog.require('Blockly.Blocks');
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#dngzfj
                + */
                +Blockly.Blocks['shtime_now'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Zeit: jetzt");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "DateTime");
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtime_now'] = function(block) {
                +  var code = 'sh.now()';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#rvch7e
                + */
                +Blockly.Blocks['shtime_time'] = {
                +  init: function() {
                +    var hh_mmValidator = function(text) {
                +          if(text === null) {
                +            return null;
                +          }
                +          text = text.replace(/O/ig, '0');
                +          text = text.replace(/,/g, ':');
                +          var hh_mm = text.split(':');
                +          if (hh_mm.length !== 2) {
                +            return null;
                +          }
                +          return String('00'+hh_mm[0]).slice(-2) + ':' + String('00'+hh_mm[1]).slice(-2);
                +    };
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField(new Blockly.FieldTextInput("12:00", hh_mmValidator ), "TIME")
                +        .appendField("Uhr");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "DateTime");
                +    this.setTooltip('');
                +  }
                +};
                +
                +Blockly.Python['shtime_time'] = function(block) {
                +  var text_time = block.getFieldValue('TIME');
                +  var code = 'datetime.strptime("'+text_time+'", "%H:%M")';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5yobn6
                + */
                +Blockly.Blocks['shtime_sunpos'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(300);
                +    this.appendValueInput("DELTA")
                +        .appendField(new Blockly.FieldDropdown([["Azimut Winkel des Sonnenstands", "0"],
                +                                                ["Altitude Winkel des Sonnenstands", "1"]]),
                +                                                 "AA")
                +        .appendField(new Blockly.FieldDropdown([["+", "+"],
                +                                                ["-", "-"]]), "PM");
                +    this.appendDummyInput()
                +        .appendField("Minuten");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "Number");
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtime_sunpos'] = function(block) {
                +  var delta = Blockly.Python.valueToCode(block, 'DELTA', Blockly.Python.ORDER_ATOMIC);
                +  var aa = block.getFieldValue('AA');
                +  var pm = block.getFieldValue('PM');
                +  if (delta === '') { pm = ''; };
                +  var code = 'sh.sun.pos('+pm+delta+')['+aa+']';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +
                +Blockly.Blocks['shtime_moon'] = {
                +  /**
                +   * Block for
                +   */
                +  init: function() {
                +    this.setColour(340);
                +    this.appendDummyInput().appendField('Mond:');
                +  },
                +};
                +
                +Blockly.Blocks['shtime_auto'] = {
                +  /**
                +   * Block for
                +   */
                +  init: function() {
                +    this.setColour(340);
                +    this.appendDummyInput().appendField('Autotimer:');
                +  },
                +};
                +
                diff --git a/blockly/webif/static/shblocks/sh_tools.js b/blockly/webif/static/shblocks/sh_tools.js
                new file mode 100644
                index 000000000..0854e3d38
                --- /dev/null
                +++ b/blockly/webif/static/shblocks/sh_tools.js
                @@ -0,0 +1,115 @@
                +/**
                + * @license
                +            <block type="shtools_logger"></block>
                +            <block type="shtools_dewpoint"></block>
                +            <block type="shtools_fetchurl"></block>
                + */
                +'use strict';
                +goog.provide('Blockly.Blocks.sh_tools');
                +goog.require('Blockly.Blocks');
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#prgbjr
                + */
                +Blockly.Blocks['shtools_logger'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(45);
                +    this.appendDummyInput()
                +        .appendField("schreibe ins Log");
                +    this.appendValueInput("LOGTEXT")
                +        .setCheck("String");
                +    this.appendDummyInput()
                +        .appendField("mit log-level")
                +        .appendField(new Blockly.FieldDropdown([["debug", "DEBUG"], ["info", "INFO"], ["warning", "WARNING"], ["error", "ERROR"], ["critical", "CRITICAL"]]), "LOGLEVEL");
                +    this.setInputsInline(true);
                +    this.setPreviousStatement(true);
                +    this.setNextStatement(true);
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtools_logger'] = function(block) {
                +  var loglevel = block.getFieldValue('LOGLEVEL').toLowerCase();
                +  var logtext =  Blockly.Python.valueToCode(block, 'LOGTEXT', Blockly.Python.ORDER_NONE) || '\'\'';
                +  var code = "logger." + loglevel + "(" + logtext + ")\n";
                +  return code;
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#ipzxr2
                + */
                +Blockly.Blocks['shtools_dewpoint'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("Taupunkt bei")
                +    this.appendValueInput("TEMP")
                +        .appendField("C Temeratur und ")
                +    this.appendValueInput("HUM")
                +        .appendField("% rel.Feuchtigkeit");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "Number");
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtools_dewpoint'] = function(block) {
                +  var value_hum = Blockly.Python.valueToCode(block, 'HUM', Blockly.Python.ORDER_ATOMIC);
                +  var value_temp = Blockly.Python.valueToCode(block, 'TEMP', Blockly.Python.ORDER_ATOMIC);
                +  var code = 'sh.tools.dewpoint(' + value_temp + ', ' + value_hum + ')';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#onut2y
                + */
                +Blockly.Blocks['shtools_fetchurl'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("open URL")
                +        .appendField(new Blockly.FieldTextInput("http://"), "URL");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "String");
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtools_fetchurl'] = function(block) {
                +  var text_url = block.getFieldValue('URL');
                +  var code = 'sh.tools.fetch_url("' + text_url + '")' ;
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                +/**
                + * https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#eqhv9d
                + */
                +Blockly.Blocks['shtools_fetchurl2'] = {
                +  init: function() {
                +    this.setHelpUrl('http://www.example.com/');
                +    this.setColour(210);
                +    this.appendDummyInput()
                +        .appendField("open URL")
                +        .appendField(new Blockly.FieldTextInput("http://"), "URL")
                +        .appendField(" mit username")
                +        .appendField(new Blockly.FieldTextInput(""), "USER")
                +        .appendField(": password")
                +        .appendField(new Blockly.FieldTextInput(""), "PASSWORD");
                +    this.setInputsInline(true);
                +    this.setOutput(true, "String");
                +    this.setTooltip('');
                +  }
                +};
                +Blockly.Python['shtools_fetchurl2'] = function(block) {
                +  var text_url = block.getFieldValue('URL');
                +  var text_user = block.getFieldValue('USER');
                +  var text_password = block.getFieldValue('PASSWORD');
                +  var code = 'sh.tools.fetch_url("' + text_url + '", "' + text_user + '", "' + text_password + '")';
                +  // TODO: Change ORDER_NONE to the correct strength.
                +  return [code, Blockly.Python.ORDER_NONE];
                +};
                +
                diff --git a/blockly/webif/templates/base.html b/blockly/webif/templates/base.html
                new file mode 100644
                index 000000000..f7c3a123d
                --- /dev/null
                +++ b/blockly/webif/templates/base.html
                @@ -0,0 +1,62 @@
                +{% block doc -%}
                +<!DOCTYPE html>
                +<html{% block html_attribs %}
                +<meta http-equiv="cache-control" content="max-age=0" />
                +<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />
                +<meta http-equiv="expires" content="-1" />
                +<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
                +<meta http-equiv="pragma" content="no-cache" />
                +<meta name="abstract" content="{{ timestamp }}">
                +{% endblock html_attribs %}
                +{%- block html %}
                +  <head>
                +    {%- block head %}
                +    <title>{% block title %}{% endblock title %}</title>
                +
                +    {%- block metas %}
                +    <meta name="viewport" content="width=1200">
                +    {#
                +    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                +	<meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1,width=device-width">
                +	#}
                +    {%- endblock metas %}
                +
                +    {%- block styles %}
                +    <!-- Bootstrap
                +    <link href="{ {bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')} }" rel="stylesheet">
                +    -->
                +    <link rel="icon" href="static/img/favicon.ico" type="image/png">
                +    <link rel="apple-touch-icon" href="static/img/logo_small_32x32">
                +    <link rel="apple-touch-icon" sizes="76x76" href="static/img/logo_small_76x76.png">
                +    <link rel="apple-touch-icon" sizes="120x120" href="static/img/logo_small_120x120.png">
                +    <link rel="apple-touch-icon" sizes="152x152" href="static/img/logo_small_152x152.png">
                +    <link rel="apple-touch-startup-image" href="static/img/logo_big.png"> 
                +
                +    <link rel="stylesheet" href="static/css/font-awesome.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap-treeview.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="static/css/bootstrap-reload.css" type="text/css"/>
                +    {%- endblock styles %}
                +    {% block scripts %}
                +    <!-- <script src="static/jquery.js"></script> -->
                +    <script src="static/js/jquery-3.2.1.min.js"></script>
                +    <script src="static/js/bootstrap.min.js"></script>
                +    <script src="static/js/bootstrap-treeview.min.js"></script>
                +    <script src="static/js/bootstrap-reload.js"></script>
                +    <script src="static/js/google-prettify/run_prettify.js"></script>
                +    <script src="static/js/backend.js"></script>
                +    {%- endblock scripts %}
                +    {%- endblock head %}
                +  </head>
                +  <body{% block body_attribs %}{% endblock body_attribs %}>
                +    {% block body -%}
                +    {% block navbar %}
                +    {%- endblock navbar %}
                +    {% block content -%}
                +    {%- endblock content %}
                +
                +    {%- endblock body %}
                +  </body>
                +{%- endblock html %}
                +</html>
                +{% endblock doc -%}
                diff --git a/blockly/webif/templates/blockly.html b/blockly/webif/templates/blockly.html
                new file mode 100644
                index 000000000..c4515a851
                --- /dev/null
                +++ b/blockly/webif/templates/blockly.html
                @@ -0,0 +1,108 @@
                +<!DOCTYPE html>
                +
                +{% extends "base.html" %}
                +
                +{% block content %}
                +
                +{% include "logics_blockly_toolbox.html" %}
                +
                +<style>
                +li.L0, li.L1, li.L2, li.L3,
                +li.L5, li.L6, li.L7, li.L8
                +{ list-style-type: decimal !important }
                +</style>
                +
                +<script type="text/javascript" language="javascript">
                +
                +function closeEditor() {
                +  $.ajax({  url: "blockly_close_editor",
                +            type: "POST",
                +            data: { content: '' },
                +        })
                +    myWait(500);
                +    window.close();
                +};
                +
                +myWait = function (ms){
                +   var start = new Date().getTime();
                +   var end = start;
                +   while(end < start + ms) {
                +     end = new Date().getTime();
                +  }
                +}
                +
                +</script>
                +
                +  <table width="99%" height="91%">
                +    <tr>
                +      <td>
                +        <h1>Blockly {{ _('Logik-Editor') }} {{ _('für SmartHomeNG') }}
                +        </h1>
                +      </td>
                +    </tr>
                +
                +    <tr>
                +      <td colspan=1>
                +        <table width="100%">
                +          <tr id="tabRow" height="1em">
                +            <td id="tab_blocks" class="tabon">Blocks</td>
                +            <td class="tabmin">&nbsp;</td>
                +            <td id="tab_python" class="taboff">Python</td>
                +            <!--<td class="tabmin">&nbsp;</td>
                +            <td id="tab_xml" class="taboff">XML</td>-->
                +            <td class="tabmax">
                +		<form name="input" action="index.html" method="POST" enctype="multipart/form-data">
                +		{% if cmd != 'edit' and cmd != 'new' %}
                +			<button onclick="function() {$.ajax({'url': 'logics_blockly_start'})}" class="btn btn-default btn-xs">{{ _('Aktivieren','button') }}</button>
                +			<button onclick="function() {$.ajax({'url': 'logics_blockly_stop'})}" class="btn btn-default btn-xs">{{ _('Beenden','button') }}</button>
                +			<button onclick="Code.saveBlocks()" class="btn btn-default btn-xs">{{ _('Blöcke speichern','button') }}</button>
                +			<button onclick="Code.loadBlocks()" class="btn btn-default btn-xs">{{ _('Änderungen verwerfen','button') }}</button>
                +			<button onclick="Code.discardBlocks()" class="btn btn-default btn-xs">{{ _('Leeren','button') }}</button>
                +			<button onclick="javascript:window.close()" class="btn btn-default btn-xs">{{ _('Schließen','button') }}</button>
                +		{% else %}
                +			<button onclick="Code.saveBlocks(); closeEditor()" class="btn btn-default btn-xs">{{ _('Speichern & schließen','button') }}</button>
                +			<button onclick="Code.saveBlocks()" class="btn btn-default btn-xs">{{ _('Speichern','button') }}</button>
                +			<!--
                +			<button onclick="Code.loadBlocks(); window.history.back()" class="btn btn-default btn-xs">{{ _('Änderungen verwerfen','button') }}</button>
                +			-->
                +			<button onclick="closeEditor()" class="btn btn-default btn-xs">{{ _('Verwerfen','button') }}</button>
                +		{% endif %}
                +      <!--
                +      <input name="close" value="{{ _('Schließen','button') }}" type="submit" class="btn btn-default btn-xs">
                +      -->
                +		</form>
                +        	</td>
                +			</tr>
                +		</table>
                +	</td>
                +	</tr>
                +    <tr>
                +      <td height="99%" colspan=1 id="content_area">
                +      </td>
                +    </tr>
                +  </table>
                +  <div id="content_blocks" class="content"></div>
                +  <pre id="content_python" class="content"></pre>
                +  <textarea id="content_xml" class="content" wrap="off"></textarea>
                +  
                +
                +<!-- BLOCKLY Script Editor -->
                +<link rel="stylesheet" href="static/blockly/demos/code/style.css">
                +
                +<!-- BLOCKLY Script Editor -->
                +<script src="static/blockly/blockly_compressed.js"></script>
                +<script src="static/blockly/blocks_compressed.js"></script>
                +<script src="static/blockly/python_compressed.js"></script>
                +<script src="static/blockly/msg/js/de.js"></script>
                +<script src="static/blockly/msg/js/en.js"></script>
                +
                +<script type="text/javascript" src="static/shblocks/sh_items.js"></script>
                +<script type="text/javascript" src="static/shblocks/sh_logics.js"></script>
                +<script type="text/javascript" src="static/shblocks/sh_logic.js"></script>
                +<script type="text/javascript" src="static/shblocks/sh_notify.js"></script>
                +<script type="text/javascript" src="static/shblocks/sh_tools.js"></script>
                +<script type="text/javascript" src="static/shblocks/sh_time.js"></script>
                +
                +<script src="static/js/logics_blockly_code.js"></script>
                +
                +{% endblock %}
                diff --git a/blockly/webif/templates/logics_blockly_toolbox.html b/blockly/webif/templates/logics_blockly_toolbox.html
                new file mode 100644
                index 000000000..d4bd96f42
                --- /dev/null
                +++ b/blockly/webif/templates/logics_blockly_toolbox.html
                @@ -0,0 +1,287 @@
                + <xml id="toolbox" style="display: none">
                +    <category name="SmartHomeNG Logic">
                +      <block type="sh_logic_main"></block>
                +      <block type="sh_trigger_item">
                +          <value name="TRIG_ITEM"></value>
                +      </block>
                +      <block type="sh_trigger_cycle"></block>
                +      <block type="sh_trigger_sun"></block>
                +      <block type="sh_trigger_daily"></block>
                +      <block type="sh_trigger_init"></block>
                +
                +      <block type="shlogic_by"></block>
                +      <block type="shlogic_value"></block>
                +      <block type="shlogic_source"></block>
                +      <block type="shlogic_dest"></block>
                +    </category>
                +
                +    <category name="SmartHomeNG Items">
                +        <block type="sh_item_get"></block>
                +        <block type="sh_item_set"></block>
                +        <block type="sh_item_hasattr"></block>
                +        <block type="sh_item_attr"></block>
                +    {{ dyn_sh_toolbox }}
                +    </category>
                +
                +      <category name="SmartHomeNG Library">
                +<!--
                +        <category name="Logic">
                +            <block type="shlogic_by"></block>
                +            <block type="shlogic_source"></block>
                +            <block type="shlogic_dest"></block>
                +            <block type="shlogic_trigger"></block>
                +        </category>
                +-->
                +        <category name="Time">
                +            <block type="shtime_now"></block>
                +            <block type="shtime_time"></block>
                +            <block type="shtime_sunpos"></block>
                +            <block type="shtime_moon"></block>
                +            <block type="shtime_auto"></block>
                +        </category>
                +        <category name="Tools">
                +            <block type="shtools_logger">
                +                <value name="LOGTEXT">
                +                    <block type="text"></block>
                +                </value>
                +            </block>
                +            <block type="shtools_dewpoint">
                +                <value name="HUM">
                +                  <block type="math_number">
                +                    <field name="NUM">50</field>
                +                  </block>
                +                </value>
                +                <value name="TEMP">
                +                  <block type="math_number">
                +                    <field name="NUM">23</field>
                +                  </block>
                +                </value>
                +            </block>
                +            <block type="shtools_fetchurl"></block>
                +            <block type="shtools_fetchurl2"></block>
                +        </category>
                +        <category name="Notification">
                +            <block type="shnotify_email"></block>
                +            <block type="shnotify_prowl"></block>
                +            <block type="shnotify_nma"></block>
                +            <block type="shnotify_pushbullit"></block>
                +        </category>
                +    </category>
                +<sep></sep>
                +<category name="Logic">
                +    <category name="If">
                +        <block type="controls_if"></block>
                +        <block type="controls_if">
                +          <mutation else="1"></mutation>
                +        </block>
                +        <block type="controls_if">
                +          <mutation elseif="1" else="1"></mutation>
                +        </block>
                +    </category>
                +    <category name="Boolean">
                +      <block type="logic_compare"></block>
                +      <block type="logic_operation"></block>
                +      <block type="logic_negate"></block>
                +      <block type="logic_boolean"></block>
                +      <block type="logic_null"></block>
                +      <block type="logic_ternary"></block>
                +    </category>
                +  </category>
                +  <category name="Loops">
                +      <block type="controls_repeat_ext">
                +        <value name="TIMES">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_whileUntil"></block>
                +      <block type="controls_for">
                +        <field name="VAR">i</field>
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">10</field>
                +          </block>
                +        </value>
                +        <value name="BY">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="controls_forEach"></block>
                +      <block type="controls_flow_statements"></block>
                +  </category>
                +  <category name="Math">
                +      <block type="math_number"></block>
                +      <block type="math_arithmetic"></block>
                +      <block type="math_single"></block>
                +      <block type="math_trig"></block>
                +      <block type="math_constant"></block>
                +      <block type="math_number_property"></block>
                +      <block type="math_change">
                +        <value name="DELTA">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_round"></block>
                +      <block type="math_on_list"></block>
                +      <block type="math_modulo"></block>
                +      <block type="math_constrain">
                +        <value name="LOW">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="HIGH">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_int">
                +        <value name="FROM">
                +          <block type="math_number">
                +            <field name="NUM">1</field>
                +          </block>
                +        </value>
                +        <value name="TO">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="math_random_float"></block>
                +    </category>
                +
                +    <category name="Text">
                +      <block type="text"></block>
                +      <block type="text_join"></block>
                +      <block type="text_append">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +      <block type="text_length"></block>
                +      <block type="text_isEmpty"></block>
                +      <block type="text_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR" class="textVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_charAt">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR" class="textVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_getSubstring">
                +        <value name="STRING">
                +          <block type="variables_get">
                +            <field name="VAR" class="textVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="text_changeCase"></block>
                +      <block type="text_trim"></block>
                +      <block type="text_print"></block>
                +      <block type="text_prompt_ext">
                +        <value name="TEXT">
                +          <block type="text"></block>
                +        </value>
                +      </block>
                +    </category>
                +
                +    <category name="Lists">
                +      <block type="lists_create_empty"></block>
                +      <block type="lists_create_with"></block>
                +      <block type="lists_repeat">
                +        <value name="NUM">
                +          <block type="math_number">
                +            <field name="NUM">5</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_length"></block>
                +      <block type="lists_isEmpty"></block>
                +      <block type="lists_indexOf">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR" class="listVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getIndex">
                +        <value name="VALUE">
                +          <block type="variables_get">
                +            <field name="VAR" class="listVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_setIndex">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR" class="listVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="lists_getSublist">
                +        <value name="LIST">
                +          <block type="variables_get">
                +            <field name="VAR" class="listVar">...</field>
                +          </block>
                +        </value>
                +      </block>
                +    </category>
                +
                +    <category name="Colour">
                +      <block type="colour_picker"></block>
                +      <block type="colour_random"></block>
                +      <block type="colour_rgb">
                +        <value name="RED">
                +          <block type="math_number">
                +            <field name="NUM">100</field>
                +          </block>
                +        </value>
                +        <value name="GREEN">
                +          <block type="math_number">
                +            <field name="NUM">50</field>
                +          </block>
                +        </value>
                +        <value name="BLUE">
                +          <block type="math_number">
                +            <field name="NUM">0</field>
                +          </block>
                +        </value>
                +      </block>
                +      <block type="colour_blend">
                +        <value name="COLOUR1">
                +          <block type="colour_picker">
                +            <field name="COLOUR">#ff0000</field>
                +          </block>
                +        </value>
                +        <value name="COLOUR2">
                +          <block type="colour_picker">
                +            <field name="COLOUR">#3333ff</field>
                +          </block>
                +        </value>
                +        <value name="RATIO">
                +          <block type="math_number">
                +            <field name="NUM">0.5</field>
                +          </block>
                +        </value>
                +      </block>
                +    </category>
                +    <category name="Variables" custom="VARIABLE"></category>
                +    <category name="Functions" custom="PROCEDURE"></category>
                +  </xml>
                diff --git a/blockly/webif/templates/new.blockly b/blockly/webif/templates/new.blockly
                new file mode 100755
                index 000000000..95b741298
                --- /dev/null
                +++ b/blockly/webif/templates/new.blockly
                @@ -0,0 +1 @@
                +<xml xmlns="http://www.w3.org/1999/xhtml"><block type="sh_logic_main" id="yJ,/r2c}j_py}8)^mnbT" x="88" y="213"><field name="LOGIC_NAME">new</field><field name="ACTIVE">FALSE</field><field name="COMMENT">Vorlage für eine neue Logik</field><data>sh_logic_main</data><statement name="DO"><block type="sh_trigger_init" id="8|1!xi.4.REpSuf=(*{J"><field name="NAME">Init</field><field name="COMMENT">Trigger Beispiel: Bei der Initialisierung auslösen</field><data>sh_trigger_init</data><next><block type="shtools_logger" id="a8*1qul2)(Q):S/A9K5N"><field name="LOGLEVEL">WARNING</field><value name="LOGTEXT"><block type="text" id="^~^9|6:*L9rnepuCM%Ol"><field name="TEXT">Beispiel: Logeintrag der Logik</field></block></value></block></next></block></statement></block></xml>
                \ No newline at end of file
                diff --git a/boxcar/plugin.yaml b/boxcar/plugin.yaml
                new file mode 100755
                index 000000000..f672b10a8
                --- /dev/null
                +++ b/boxcar/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                       # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Boxcar Notification Service'
                +        en: 'Boxcar Notification Service'
                +    maintainer: mode2k
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Boxcar               # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/buderus/README.md b/buderus/README.md
                index 94737d80f..af8c91836 100644
                --- a/buderus/README.md
                +++ b/buderus/README.md
                @@ -1,4 +1,4 @@
                -# smarthome-buderus
                +# buderus
                 
                 Plugin to control Buderus boilers using an additional Logamatic web KM200 module. Logamatic web KM50 and KM300 modules should also be supported.
                 
                diff --git a/buderus/plugin.yaml b/buderus/plugin.yaml
                new file mode 100755
                index 000000000..e4c91d9a3
                --- /dev/null
                +++ b/buderus/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Steuerung von Buderus Heizkesseln über ein Logamatic web KM200 Modul (noch in der Entwicklung), **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: rthill
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Buderus             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/cli/README.md b/cli/README.md
                index 57f9e09d7..a4f217681 100644
                --- a/cli/README.md
                +++ b/cli/README.md
                @@ -37,27 +37,30 @@ Telnet to the configured IP adress and port.
                 
                 Enter ``help`` for a list of available commands.
                 
                +You can enter ``help [commandgroup]`` to see only commands belonging to that group (and global commands). Commandgroups are ``item``, ``logic``, ``log`` and ``scheduler``. 
                +
                 command | function
                 --- | ---
                -``cl [log]`` | clean (memory) log
                -``dl [logic]`` | dl logic: disables logic
                -``dump [item]`` | dump details about given item
                -``el [logic]`` | el logic: enables logic
                -``la`` | list all items (with values)
                -``ld [log]`` | log dump of (memory) log
                -``lo`` | list all logics and next execution time
                -``ls`` | list the first level items
                -``ls [item]`` | list item and every child item (with values)
                -``lt`` | list current thread names
                -``rl [logic]`` | reload logic
                -``rr [logic]`` | reload and run logic
                +``if`` | list the first level items
                +``if [item]`` | list item and every child item (with values)
                +``ii [item]`` | dump detail-information about a given item - command alias: dump
                +``il`` | list all items (with values) - command alias: la
                +``iup`` | alias for iupdate
                +``iupdate [item] = [value]`` | update the item with value - command alias: update
                +``ld [logic]`` | disables logic - command alias: dl
                +``le [logic]`` | enables logic - command alias: el
                +``li [logic]`` | dump details about a given logic (new in v1.4)
                +``ll`` | list all logics and next execution time - command alias: lo
                +``lr [logic]`` | reload a logic - command alias: rl
                +``lrr [logic]`` | reload and run a logic - command alias: rr
                +``lt [logic]`` | trigger a logic - command alias: tr
                +``logc [log]`` | clean (memory) log
                +``logd [log]`` | log dump of (memory) log
                 ``rt`` | return runtime
                 ``si [task]`` | show details for given task
                 ``sl`` | list all scheduler tasks by name
                 ``st`` | list all scheduler tasks by execution time
                -``tr [logic]`` | trigger logic
                -``up`` | alias for update
                -``update [item] = [value]`` | update the specified item with the specified value
                +``tl`` | list current thread names
                 ``quit`` | quit the session
                 ``q`` | alias for quit
                 
                diff --git a/cli/__init__.py b/cli/__init__.py
                index f7eedac0e..0a2a5ef64 100755
                --- a/cli/__init__.py
                +++ b/cli/__init__.py
                @@ -1,28 +1,31 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                 #########################################################################
                -#  Copyright 2012-2013 Marcus Popp                         marcus@popp.mx
                -#            2016      Thomas Ernst
                +# Copyright 2017-       Martin Sinn                         m.sinn@gmx.de
                +#           2016        Thomas Ernst
                +#           2012-2013   Marcus Popp                        marcus@popp.mx
                 #########################################################################
                -#  This file is part of SmartHomeNG.
                +#  Commandline Interface for SmartHomeNG
                 #
                -#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  This plugin is free software: you can redistribute it and/or modify
                 #  it under the terms of the GNU General Public License as published by
                 #  the Free Software Foundation, either version 3 of the License, or
                 #  (at your option) any later version.
                 #
                -#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  This plugin is distributed in the hope that it will be useful,
                 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
                 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                 #  GNU General Public License for more details.
                 #
                 #  You should have received a copy of the GNU General Public License
                -#  along with SmartHomeNG.  If not, see <http://www.gnu.org/licenses/>.
                +#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                 #########################################################################
                 
                 import logging
                 import threading
                +
                 import lib.connection
                +from lib.logic import Logics
                 from lib.model.smartplugin import SmartPlugin
                 from lib.utils import Utils
                 
                @@ -139,7 +142,7 @@ def __echo_off(self):
                             data = self.socket.recv(3)
                             self.socket.setblocking(0)
                             if data != bytearray([0xFF, 0xFD, 0x01]):  # IAC DO ECHO
                -                logger.error("Error at 'echo off': Sent b'\\xff\\xfb\\x01 , Expected reply b'\\xff\\xfd\\x01, received {0}".format(data))
                +                self.logger.error("Error at 'echo off': Sent b'\\xff\\xfb\\x01 , Expected reply b'\\xff\\xfd\\x01, received {0}".format(data))
                                 self.push("'echo off' failed. Bye")
                                 self.close()
                         except Exception as e:
                @@ -159,7 +162,7 @@ def __echo_on(self):
                             data = self.socket.recv(3)
                             self.socket.setblocking(0)
                             if data != bytearray([0xFF, 0xFE, 0x01]):  # IAC DONT ECHO
                -                logger.error("Error at 'echo on': Sent b'\\xff\\xfc\\x01 , Expected reply b'\\xff\\xfe\\x01, received {0}".format(data))
                +                self.logger.error("Error at 'echo on': Sent b'\\xff\\xfc\\x01 , Expected reply b'\\xff\\xfe\\x01, received {0}".format(data))
                                 self.push("'echo off' failed. Bye")
                                 self.close()
                         except Exception as e:
                @@ -169,13 +172,13 @@ def __echo_on(self):
                 
                     def __push_command_prompt(self):
                         """Push command prompt to client"""
                -        self.push("> ")
                +        self.push("CLI > ")
                         self.__prompt_type = 'command'
                 
                 
                 class CLI(lib.connection.Server, SmartPlugin):
                -    ALLOW_MULTIINSTANCE = False
                -    PLUGIN_VERSION = '1.3.0'
                +
                +    PLUGIN_VERSION = '1.4.0'     # is checked against version in plugin.yaml
                 
                     def __init__(self, smarthome, update='False', ip='127.0.0.1', port=2323, hashed_password=''):
                         """
                @@ -203,6 +206,7 @@ def __init__(self, smarthome, update='False', ip='127.0.0.1', port=2323, hashed_
                         self.commands = CLICommands(self.sh, self.updates_allowed)
                         self.alive = False
                 
                +
                     def handle_connection(self):
                         """
                         Handle incoming connection
                @@ -249,6 +253,8 @@ class CLICommands:
                     Class containing handling for CLI commands as well as a basic set of commands
                     """
                 
                +    logics = None
                +
                     def __init__(self, smarthome, updates_allowed=False):
                         """
                         Constructor
                @@ -261,35 +267,54 @@ def __init__(self, smarthome, updates_allowed=False):
                         self._commands = {}
                 
                         # Add basic commands
                -        self.add_command('cl', self._cli_cl, 'cl [log]: clean (memory) log')
                -        self.add_command('la', self._cli_la, 'la: list all items (with values)')
                -        self.add_command('update', self._cli_update, 'update [item] = [value]: update the specified item with the specified value')
                -        self.add_command('up', self._cli_update, 'up: alias for update')
                -        self.add_command('ls', self._cli_ls, 'ls: list the first level items\nls [item]: list item and every child item (with values)')
                -        self.add_command('lo', self._cli_lo, 'lo: list all logics and next execution time')
                -        self.add_command('lt', self._cli_lt, 'lt: list current thread names')
                -        self.add_command('tr', self._cli_tr, 'tr [logic]: trigger logic')
                -        self.add_command('rl', self._cli_rl, 'rl [logic]: reload logic')
                -        self.add_command('rr', self._cli_rr, 'rr [logic]: reload and run logic')
                -        self.add_command('rt', self._cli_rt, 'rt: return runtime')
                -        self.add_command('dump', self._cli_dump, 'dump [item]: dump details about given item')
                -        self.add_command('help', self._cli_help, None)
                -        self.add_command('h', self._cli_help, None)
                -        self.add_command('sl', self._cli_sl, 'sl: list all scheduler tasks by name')
                -        self.add_command('st', self._cli_sl, 'st: list all scheduler tasks by execution time')
                -        self.add_command('si', self._cli_si, 'si [task]: show details for given task')
                -        self.add_command('ld', self._cli_ld, 'ld [log]: log dump of (memory) log')
                -        self.add_command('el', self._cli_el, 'el [logic]: enables logic')
                -        self.add_command('dl', self._cli_dl, 'dl [logic]: disables logic')
                -
                -    def add_command(self, command, function, usage):
                +        self.add_command('il', self._cli_il, 'item', 'il: list all items (with values) - command alias: la')
                +        self.add_command('la', self._cli_il, 'item', None)
                +        self.add_command('dump', self._cli_ii, 'item', None)
                +        self.add_command('if', self._cli_if, 'item', 'if: list the first level items\nif [item]: list item and every child item (with values)')
                +        self.add_command('ii', self._cli_ii, 'item', 'ii [item]: dump detail-information about a given item - command alias: dump')
                +
                +        self.add_command('iupdate', self._cli_iupdate, 'item', 'iupdate [item] = [value]: update the item with value - command alias: update')
                +        self.add_command('update', self._cli_iupdate, 'item', None)
                +        self.add_command('iup', self._cli_iupdate, 'item', 'iup: alias for iupdate - command alias: up')
                +        self.add_command('up', self._cli_iupdate, 'item',  None)
                +
                +        self.add_command('logc', self._cli_logc, 'log', 'logc [log]: clean (memory) log')
                +        self.add_command('logd', self._cli_logd, 'log', 'logd [log]: log dump of (memory) log')
                +
                +        self.add_command('ll', self._cli_ll, 'logic', 'll: list all logics and next execution time - command alias: lo')
                +        self.add_command('lo', self._cli_ll, 'logic', None)   # old command
                +        self.add_command('li', self._cli_dumpl, 'logic', 'li [logic]: logic information - dump details about given logic')
                +        self.add_command('dumpl', self._cli_dumpl, 'logic', None)
                +        self.add_command('ld', self._cli_ld, 'logic', 'ld [logic]: disables logic - command alias: dl')
                +        self.add_command('dl', self._cli_ld, 'logic', None)   # old command
                +        self.add_command('le', self._cli_le, 'logic', 'le [logic]: enables logic - command alias: el')
                +        self.add_command('el', self._cli_le, 'logic', None)   # old command
                +        self.add_command('lr', self._cli_lr, 'logic', 'lr [logic]: reload a logic - command alias: rl')
                +        self.add_command('rl', self._cli_lr, 'logic', None)
                +        self.add_command('lrr', self._cli_lrr, 'logic', 'lrr [logic]: reload and run a logic - command alias: rr')
                +        self.add_command('rr', self._cli_lrr, 'logic', None)
                +        self.add_command('lt', self._cli_lt, 'logic', 'lt [logic]: trigger a logic - command alias: tr')
                +        self.add_command('tr', self._cli_lt, 'logic', None)
                +        
                +        self.add_command('sl', self._cli_sl, 'scheduler', 'sl: list all scheduler tasks by name')
                +        self.add_command('st', self._cli_sl, 'scheduler', 'st: list all scheduler tasks by execution time')
                +        self.add_command('si', self._cli_si, 'scheduler', 'si [task]: show details for given scheduler task')
                +
                +        self.add_command('tl', self._cli_tl, '???', 'tl: list current thread names')
                +        self.add_command('rt', self._cli_rt, '???', 'rt: return runtime')
                +        self.add_command('help', self._cli_help2, '-', 'help [group]: show help for group of commands [item, log, logic, scheduler]' )
                +        self.add_command('h', self._cli_help2, '-', 'h: alias for help')
                +
                +    def add_command(self, command, function, group, usage):
                         """
                         Add command to list
                         :param command: Command to add
                         :param function: Function to execute for command
                         :param usage: Usage string for help-command
                         """
                -        self._commands[command] = {'function': function, 'usage': usage}
                +        if command in self._commands:
                +            self.logger.error("add_command: Trying to redefine an already existing command with {} ({})".format(command, str(usage)))
                +        self._commands[command] = {'function': function, 'group': group, 'usage': usage}
                 
                     def remove_command(self, command):
                         """
                @@ -311,6 +336,8 @@ def execute(self, handler, cmd, source):
                         :param source: Call source
                         :return: TRUE: Command found and handled, FALSE: Unknown command, nothing done
                         """
                +        if self.logics is None:
                +            self.logics = Logics.get_instance()
                         for command, data in self._commands.items():
                             if cmd == command or cmd.startswith(command + " "):
                                 try:
                @@ -323,9 +350,9 @@ def execute(self, handler, cmd, source):
                         return False
                 
                     # noinspection PyUnusedLocal
                -    def _cli_tr(self, handler, parameter, source):
                +    def _cli_lt(self, handler, parameter, source):
                         """
                -        CLI command "tr" - Trigger logic
                +        CLI command "lt" - Trigger logic
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                @@ -335,34 +362,45 @@ def _cli_tr(self, handler, parameter, source):
                             return
                         if parameter is None or parameter == "":
                             handler.push("Please name logic to trigger\n")
                -        elif parameter in self.sh.return_logics():
                -            self.sh.trigger(parameter, by='CLI')
                +        elif parameter in self.logics.return_loaded_logics():
                +            self.logics.trigger_logic(parameter, by='CLI')
                             handler.push("Logic '{0}' triggered.\n".format(parameter))
                         else:
                             handler.push("Logic '{0}' not found.\n".format(parameter))
                 
                -    def _cli_el(self, handler, parameter, source):
                +    def _cli_dumpl(self, handler, parameter, source):
                +        if parameter in self.logics.return_loaded_logics():
                +            info = self.logics.get_logic_info(parameter, ordered=True)
                +#            handler.push("Logic {} ".format(info['name']))
                +            handler.push("{\n")
                +            for key in info:
                +                handler.push("  {}: {}\n".format(key, info[key]))
                +            handler.push("}\n")
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(parameter))
                +
                +    def _cli_le(self, handler, parameter, source):
                         if not self.updates_allowed:
                -            handler.push("Logic triggering is not allowed.\n")
                +            handler.push("Logic enabling is not allowed.\n")
                             return
                -        if parameter in self.sh.return_logics():
                -            self.sh.return_logic(parameter).enable()
                +        if parameter in self.logics.return_loaded_logics():
                +            self.logics.return_logic(parameter).enable()
                         else:
                             handler.push("Logic '{0}' not found.\n".format(parameter))
                 
                -    def _cli_dl(self, handler, parameter, source):
                +    def _cli_ld(self, handler, parameter, source):
                         if not self.updates_allowed:
                -            handler.push("Logic triggering is not allowed.\n")
                +            handler.push("Logic disabling is not allowed.\n")
                             return
                -        if parameter in self.sh.return_logics():
                -            self.sh.return_logic(parameter).disable()
                +        if parameter in self.logics.return_loaded_logics():
                +            self.logics.return_logic(parameter).disable()
                         else:
                             handler.push("Logic '{0}' not found.\n".format(parameter))
                 
                     # noinspection PyUnusedLocal
                -    def _cli_rl(self, handler, parameter, source):
                +    def _cli_lr(self, handler, parameter, source):
                         """
                -        CLI command "rl" - Reload logic
                +        CLI command "lr" - Reload logic
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                @@ -372,17 +410,16 @@ def _cli_rl(self, handler, parameter, source):
                             return
                         if parameter is None or parameter == "":
                             handler.push("Please name logic to reload\n")
                -        elif parameter in self.sh.return_logics():
                -            logic = self.sh.return_logic(parameter)
                -            logic.generate_bytecode()
                +        elif parameter in self.logics.return_loaded_logics():
                +            self.logics.load_logic(parameter)
                             handler.push("Logic '{0}' reloaded.\n".format(parameter))
                         else:
                             handler.push("Logic '{0}' not found.\n".format(parameter))
                 
                     # noinspection PyUnusedLocal
                -    def _cli_rr(self, handler, parameter, source):
                +    def _cli_lrr(self, handler, parameter, source):
                         """
                -        CLI command "rr" - Reload and trigger logic
                +        CLI command "lrr" - Reload and trigger logic
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                @@ -392,28 +429,26 @@ def _cli_rr(self, handler, parameter, source):
                             return
                         if parameter is None or parameter == "":
                             handler.push("Please name logic to reload and trigger")
                -        elif parameter in self.sh.return_logics():
                -            logic = self.sh.return_logic(parameter)
                -            logic.generate_bytecode()
                -            logic.trigger(by='CLI')
                +        elif parameter in self.logics.return_loaded_logics():
                +            self.logics.load_logic(parameter)
                +            self.logics.trigger_logic(parameter, by='CLI')
                             handler.push("Logic '{0}' reloaded and triggered.\n".format(parameter))
                         else:
                             handler.push("Logic '{0}' not found.\n".format(name))
                 
                     # noinspection PyUnusedLocal
                -    def _cli_lo(self, handler, parameter, source):
                +    def _cli_ll(self, handler, parameter, source):
                         """
                -        CLI command "lo" - List logics
                +        CLI command "ll" - List logics
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                         """
                         handler.push("Logics:\n")
                -        for logic in sorted(self.sh.return_logics()):
                +        for logic in sorted(self.logics.return_loaded_logics()):
                             data = []
                -            lo = self.sh.return_logic(logic)
                             nt = self.sh.scheduler.return_next(logic)
                -            if lo.enabled == False:
                +            if self.logics.is_logic_enabled(logic) == False:
                                 data.append("disabled")
                             if nt is not None:
                                 data.append("scheduled for {0}".format(nt.strftime('%Y-%m-%d %H:%M:%S%z')))
                @@ -422,17 +457,63 @@ def _cli_lo(self, handler, parameter, source):
                                 handler.push(" ({0})".format(", ".join(data)))
                             handler.push("\n")
                 
                +
                +    def thread_sum(self, name, count):
                +        thread = dict()
                +        if count > 0:
                +            thread['name'] = name
                +            thread['sort'] = str(thread['name']).lower()
                +            thread['id'] = "(" + str(count) + " threads" + ")"
                +            thread['alive'] = True
                +        return thread
                +
                     # noinspection PyUnusedLocal,PyMethodMayBeStatic
                -    def _cli_lt(self, handler, parameter, source):
                +    def _cli_tl(self, handler, parameter, source):
                         """
                -        CLI command "lt" - list all threads with names
                +        CLI command "tl" - list all threads with names
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                         """
                -        handler.push("{0} Threads:\n".format(threading.activeCount()))
                +        threads_count = 0
                +        cp_threads = 0
                +        http_threads = 0
                +        idle_threads = 0
                +        for thread in threading.enumerate():
                +            if thread.name.find("CP Server") == 0:
                +                cp_threads += 1
                +            if thread.name.find("HTTPServer") == 0:
                +                http_threads +=1
                +            if thread.name.find("idle") == 0:
                +                idle_threads +=1
                +
                +        threads = []
                         for t in threading.enumerate():
                -            handler.push("{0}\n".format(t.name))
                +            if t.name.find("CP Server") != 0 and t.name.find("HTTPServer") != 0 and t.name.find("idle") != 0:
                +                thread = dict()
                +                thread['name'] = t.name
                +                thread['sort'] = str(t.name).lower()
                +                thread['id'] = ''    # t.ident
                +                thread['alive'] = t.is_alive()
                +                threads.append(thread)
                +                threads_count += 1
                +
                +        if cp_threads > 0:
                +            threads.append(self.thread_sum("CP Server", cp_threads))
                +            threads_count += cp_threads
                +        if http_threads > 0:
                +            threads.append(self.thread_sum("HTTPServer", http_threads))
                +            threads_count += http_threads
                +        if idle_threads > 0:
                +            threads.append(self.thread_sum("idle", idle_threads))
                +            threads_count += idle_threads
                +        
                +        threads_sorted = sorted(threads, key=lambda k: k['sort'])
                +
                +        handler.push("{0} Threads:\n".format(threads_count))
                +        for t in threads_sorted:
                +            handler.push("{:<30}     {}\n".format(t['name'], t['id']))
                +
                 
                     # noinspection PyUnusedLocal
                     def _cli_rt(self, handler, parameter, source):
                @@ -445,9 +526,9 @@ def _cli_rt(self, handler, parameter, source):
                         handler.push("Runtime: {}\n".format(self.sh.runtime()))
                 
                     # noinspection PyUnusedLocal
                -    def _cli_ls(self, handler, parameter, source):
                +    def _cli_if(self, handler, parameter, source):
                         """
                -        CLI command "ls" - list first level items
                +        CLI command "if" - list first level items
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                @@ -486,7 +567,7 @@ def _cli_ls_int(self, handler, parameter, match=True):
                                 handler.push("Could not find path: {}\n".format(parameter))
                 
                     # noinspection PyUnusedLocal
                -    def _cli_dump(self, handler, parameter, source):
                +    def _cli_ii(self, handler, parameter, source):
                         """
                         CLI command "dump" - dump item(s)
                         :param handler: CLIHandler instance
                @@ -503,24 +584,24 @@ def _cli_dump(self, handler, parameter, source):
                                 if hasattr(item, 'id') and item._type:
                                     handler.push("Item {} ".format(item.id()))
                                     handler.push("{\n")
                -                    handler.push("  type = {}\n".format(item.type()))
                -                    handler.push("  value = {}\n".format(item()))
                -                    handler.push("  age = {}\n".format(item.age()))
                -                    handler.push("  last_change = {}\n".format(item.last_change()))
                -                    handler.push("  changed_by = {}\n".format(item.changed_by()))
                -                    handler.push("  previous_value = {}\n".format(item.prev_value()))
                -                    handler.push("  previous_age = {}\n".format(item.prev_age()))
                -                    handler.push("  previous_change = {}\n".format(item.prev_change()))
                +                    handler.push("  type: {}\n".format(item.type()))
                +                    handler.push("  value: {}\n".format(item()))
                +                    handler.push("  age: {}\n".format(item.age()))
                +                    handler.push("  last_change: {}\n".format(item.last_change()))
                +                    handler.push("  changed_by: {}\n".format(item.changed_by()))
                +                    handler.push("  previous_value: {}\n".format(item.prev_value()))
                +                    handler.push("  previous_age: {}\n".format(item.prev_age()))
                +                    handler.push("  previous_change: {}\n".format(item.prev_change()))
                                     if hasattr(item, 'conf'):
                -                        handler.push("  config = {\n")
                +                        handler.push("  config: {\n")
                                         for name in item.conf:
                -                            handler.push("    {} = {}\n".format(name, item.conf[name]))
                +                            handler.push("    {}: {}\n".format(name, item.conf[name]))
                                         handler.push("  }\n")
                -                    handler.push("  logics = [\n")
                +                    handler.push("  logics: [\n")
                                     for trigger in item.get_logic_triggers():
                                         handler.push("    {}\n".format(trigger))
                                     handler.push("  ]\n")
                -                    handler.push("  triggers = [\n")
                +                    handler.push("  triggers: [\n")
                                     for trigger in item.get_method_triggers():
                                         handler.push("    {}\n".format(trigger))
                                     handler.push("  ]\n")
                @@ -529,7 +610,7 @@ def _cli_dump(self, handler, parameter, source):
                             handler.push("Nothing found\n")
                 
                     # noinspection PyUnusedLocal
                -    def _cli_help(self, handler, parameter, source):
                +    def _cli_help2(self, handler, parameter, source):
                         """
                         CLI command "help" - show available commands
                         :param handler: CLIHandler instance
                @@ -537,13 +618,24 @@ def _cli_help(self, handler, parameter, source):
                         :param source: Source
                         """
                         for command, data in sorted(self._commands.items()):
                -            if data['usage'] is not None:
                +            if parameter == '' or data['group'] == parameter:
                +                if data['usage'] is not None:
                +                    handler.push(data['usage'] + '\n')
                +        if parameter != '':
                +            if not parameter in ['item', 'log', 'logic', 'scheduler']:
                +                handler.push('help: Unknown group\n\n')
                +                data = self._commands['help']
                                 handler.push(data['usage'] + '\n')
                -        handler.push('quit: quit the session\n')
                -        handler.push('q: alias for quit\n')
                +            else:
                +                handler.push('\n')
                +            for command, data in sorted(self._commands.items()):
                +                if data['group'] == '???':
                +                    if data['usage'] is not None:
                +                        handler.push(data['usage'] + '\n')
                +        handler.push('quit, q: quit the session\n')
                 
                     # noinspection PyUnusedLocal
                -    def _cli_cl(self, handler, parameter, source):
                +    def _cli_logc(self, handler, parameter, source):
                         """
                         CLI command "cl" - clear (memory) log
                         :param handler: CLIHandler instance
                @@ -564,9 +656,9 @@ def _cli_cl(self, handler, parameter, source):
                             log.clean(self.sh.now())
                 
                     # noinspection PyUnusedLocal
                -    def _cli_la(self, handler, parameter, source):
                +    def _cli_il(self, handler, parameter, source):
                         """
                -        CLI command "la" - list all items
                +        CLI command "il" - list all items
                         :param handler: CLIHandler instance
                         :param parameter: Parameters used to call the command
                         :param source: Source
                @@ -578,7 +670,7 @@ def _cli_la(self, handler, parameter, source):
                             else:
                                 handler.push("{0}\n".format(item.id()))
                 
                -    def _cli_update(self, handler, parameter, source):
                +    def _cli_iupdate(self, handler, parameter, source):
                         """
                         CLI command "update" - update item value
                         :param handler: CLIHandler instance
                @@ -606,7 +698,7 @@ def _cli_update(self, handler, parameter, source):
                 
                     # noinspection PyUnusedLocal
                     def _cli_sl(self, handler, parameter, source):
                -        logics = sorted(self.sh.return_logics())
                +        logics = sorted(self.logics.return_loaded_logics())
                         tasks = []
                         for name in sorted(self.sh.scheduler):
                             nt = self.sh.scheduler.return_next(name)
                @@ -620,7 +712,7 @@ def _cli_sl(self, handler, parameter, source):
                 
                     # noinspection PyUnusedLocal
                     def _cli_st(self, handler, parameter, source):
                -        logics = sorted(self.sh.return_logics())
                +        logics = sorted(self.logics.return_loaded_logics())
                         tasks = []
                         for name in sorted(self.sh.scheduler):
                             nt = self.sh.scheduler.return_next(name)
                @@ -643,14 +735,14 @@ def _cli_si(self, handler, parameter, source):
                             handler.push("Scheduler task '{}' not found\n".format(parameter))
                         else:
                             task = self.sh.scheduler._scheduler[parameter]
                -            handler.push("Task {}".format(parameter))
                +            handler.push("Task {}\n".format(parameter))
                             handler.push("{\n")
                             for key in task:
                                 handler.push("  {} = {}\n".format(key, task[key]))
                             handler.push("}\n")
                 
                     # noinspection PyUnusedLocal
                -    def _cli_ld(self, handler, parameter, source):
                +    def _cli_logd(self, handler, parameter, source):
                         if parameter is None or parameter == "":
                             log = self.sh.log
                         else:
                diff --git a/cli/_pv_1_3_0/README.md b/cli/_pv_1_3_0/README.md
                new file mode 100755
                index 000000000..32ce491ac
                --- /dev/null
                +++ b/cli/_pv_1_3_0/README.md
                @@ -0,0 +1,67 @@
                +# CLI v1.3.0 (up to shNG v1.3)
                +
                +## Configuration
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +
                +```
                +[cli]
                +    class_name = CLI
                +    class_path = plugins.cli
                +    #ip = 127.0.0.1
                +    #port = 2323
                +    #update = false
                +    #hashed_password = 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d
                +```
                +
                +```
                +cli:
                +    class_name: CLI
                +    class_path: plugins.cli
                +    # ip = 127.0.0.1
                +    # port = 2323
                +    # update = false
                +    # hashed_password = 1245a9633edf47b7091f37c4d294b5be5a9936c81c5359b16d1c4833729965663f1943ef240959c53803fedef7ac19bd59c66ad7e7092d7dbf155ce45884607d
                +```
                +
                +This plugin listens for a telnet connection.
                +
                +``ip = `` used network interface, e.g. 127.0.0.1 (localhost, default) or listen on all network interfaces: 0.0.0.0
                +``port =`` used network port, default 2323
                +``update =`` restrict the access of the items to read only (false, default) or allows read/write access (true)
                +``hashed_password = `` password that needs to be entered on login. SHA-512 hashed. Value shown above is "very_secure_password"
                +
                +## Usage
                +
                +Telnet to the configured IP adress and port. 
                +
                +Enter ``help`` for a list of available commands.
                +
                +command | function
                +--- | ---
                +``cl [log]`` | clean (memory) log
                +``dl [logic]`` | dl logic: disables logic
                +``dump [item]`` | dump details about given item
                +``el [logic]`` | el logic: enables logic
                +``la`` | list all items (with values)
                +``ld [log]`` | log dump of (memory) log
                +``lo`` | list all logics and next execution time
                +``ls`` | list the first level items
                +``ls [item]`` | list item and every child item (with values)
                +``lt`` | list current thread names
                +``rl [logic]`` | reload logic
                +``rr [logic]`` | reload and run logic
                +``rt`` | return runtime
                +``si [task]`` | show details for given task
                +``sl`` | list all scheduler tasks by name
                +``st`` | list all scheduler tasks by execution time
                +``tr [logic]`` | trigger logic
                +``up`` | alias for update
                +``update [item] = [value]`` | update the specified item with the specified value
                +``quit`` | quit the session
                +``q`` | alias for quit
                +
                +Plugins may append additional commands. They will be listed with the "help" command, too.
                +
                +### Example:
                +``up office.light = On`` to update an item named _office.light_ to value _On_
                diff --git a/cli/_pv_1_3_0/__init__.py b/cli/_pv_1_3_0/__init__.py
                new file mode 100755
                index 000000000..f7eedac0e
                --- /dev/null
                +++ b/cli/_pv_1_3_0/__init__.py
                @@ -0,0 +1,669 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2012-2013 Marcus Popp                         marcus@popp.mx
                +#            2016      Thomas Ernst
                +#########################################################################
                +#  This file is part of SmartHomeNG.
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG.  If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import logging
                +import threading
                +import lib.connection
                +from lib.model.smartplugin import SmartPlugin
                +from lib.utils import Utils
                +
                +
                +class CLIHandler(lib.connection.Stream):
                +    terminator = '\n'.encode()
                +
                +    def __init__(self, smarthome, sock, source, updates, hashed_password, commands):
                +        """
                +        Constructor
                +        :param smarthome: SmartHomeNG instance
                +        :param sock: Socket
                +        :param source: Source
                +        :param updates: Flag: Updates allowed
                +        :param hashed_password: Hashed password that is required to logon
                +        :param commands: CLICommands instance containing available commands
                +        """
                +        lib.connection.Stream.__init__(self, sock, source)
                +        self.logger = logging.getLogger(__name__)
                +        self.source = source
                +        self.updates_allowed = updates
                +        self.sh = smarthome
                +        self.hashed_password = hashed_password
                +        self.commands = commands
                +        self.__prompt_type = ''
                +        self.push("SmartHomeNG v{0}\n".format(self.sh.version))
                +
                +        if hashed_password is None:
                +            self.__push_helpmessage()
                +            self.__push_command_prompt()
                +        else:
                +            self.__push_password_prompt()
                +
                +    def push(self, data):
                +        """
                +        Send data to client
                +        :param data: String to send
                +        """
                +        self.send(data.encode())
                +
                +    def found_terminator(self, data):
                +        """
                +        Received data and found terminator (newline) in data
                +        :param data: Received data up to terminator
                +        """
                +        # Call process methods based on prompt type
                +        cmd = data.decode().strip()
                +        if self.__prompt_type == 'password':
                +            self.__process_password(cmd)
                +        elif self.__prompt_type == 'command':
                +            self.__process_command(cmd)
                +
                +    def __process_password(self, cmd):
                +        """
                +        Process entered password
                +        :param cmd: entered password
                +        """
                +        self.__push_password_finished()
                +        if Utils.check_hashed_password(cmd, self.hashed_password):
                +            self.logger.debug("CLI: {0} Authorization succeeded".format(self.source))
                +            self.__push_helpmessage()
                +            self.__push_command_prompt()
                +            return
                +        else:
                +            self.logger.debug("CLI: {0} Authorization failed".format(self.source))
                +            self.push("Authorization failed. Bye\n")
                +            self.close()
                +            return
                +
                +    def __process_command(self, cmd):
                +        """
                +        Process entered command
                +        :param cmd: entered command
                +        """
                +        if cmd in ('quit', 'q', 'exit', 'x'):
                +            self.push('bye\n')
                +            self.close()
                +            return
                +        else:
                +            if not self.commands.execute(self, cmd, self.source):
                +                self.push("Unknown command.\n")
                +                self.__push_helpmessage()
                +            self.__push_command_prompt()
                +
                +    def __push_helpmessage(self):
                +        """Push help message to client"""
                +        self.push("Enter 'help' for a list of available commands.\n")
                +
                +    def __push_password_prompt(self):
                +        """
                +        Push 'echo off' and password prompt to client.
                +        """
                +        self.__echo_off()
                +        self.push("Password: ")
                +        self.__prompt_type = 'password'
                +
                +    def __push_password_finished(self):
                +        """
                +        Push 'echo on' and newline to client
                +        :return:
                +        """
                +        self.__echo_on()
                +        self.push("\n")
                +
                +    def __echo_off(self):
                +        """
                +        Send 'IAC WILL ECHO' to client, telling the client that we will echo.
                +        Check that reply is 'IAC DO ECHO', meaning that the client has understood.
                +        As we are not echoing entered text will be invisible
                +        """
                +        try:
                +            self.socket.settimeout(2)
                +            self.send(bytearray([0xFF, 0xFB, 0x01]))  # IAC WILL ECHO
                +            data = self.socket.recv(3)
                +            self.socket.setblocking(0)
                +            if data != bytearray([0xFF, 0xFD, 0x01]):  # IAC DO ECHO
                +                logger.error("Error at 'echo off': Sent b'\\xff\\xfb\\x01 , Expected reply b'\\xff\\xfd\\x01, received {0}".format(data))
                +                self.push("'echo off' failed. Bye")
                +                self.close()
                +        except Exception as e:
                +            self.push("\nException at 'echo off'. See log for details.")
                +            self.logger.exception(e)
                +            self.close()
                +
                +    def __echo_on(self):
                +        """
                +        Send 'IAC WONT ECHO' to client, telling the client that we wont echo.
                +        Check that reply is 'IAC DONT ECHO', meaning that the client has understood.
                +        Now the client should be echoing and we do not have to care about this
                +        """
                +        try:
                +            self.socket.settimeout(2)
                +            self.send(bytearray([0xFF, 0xFC, 0x01]))  # IAC WONT ECHO
                +            data = self.socket.recv(3)
                +            self.socket.setblocking(0)
                +            if data != bytearray([0xFF, 0xFE, 0x01]):  # IAC DONT ECHO
                +                logger.error("Error at 'echo on': Sent b'\\xff\\xfc\\x01 , Expected reply b'\\xff\\xfe\\x01, received {0}".format(data))
                +                self.push("'echo off' failed. Bye")
                +                self.close()
                +        except Exception as e:
                +            self.push("\nException at 'echo on'. See log for details.")
                +            self.logger.exception(e)
                +            self.close()
                +
                +    def __push_command_prompt(self):
                +        """Push command prompt to client"""
                +        self.push("> ")
                +        self.__prompt_type = 'command'
                +
                +
                +class CLI(lib.connection.Server, SmartPlugin):
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.3.0'
                +
                +    def __init__(self, smarthome, update='False', ip='127.0.0.1', port=2323, hashed_password=''):
                +        """
                +        Constructor
                +        :param smarthome: smarthomeNG instance
                +        :param update: Flag: Updates allowed
                +        :param ip: IP to bind on
                +        :param port: Port to bind on
                +        :param hashed_password: Hashed password that is required to logon
                +        """
                +        self.logger = logging.getLogger(__name__)
                +
                +        if hashed_password is None or hashed_password == '':
                +            self.logger.warning("CLI: You should set a password for this plugin.")
                +            hashed_password = None
                +        elif hashed_password.lower() == 'none':
                +            hashed_password = None
                +        elif not Utils.is_hash(hashed_password):
                +            self.logger.error("CLI: Value given for 'hashed_password' is not a valid hash value. Login will not be possible")
                +
                +        lib.connection.Server.__init__(self, ip, port)
                +        self.sh = smarthome
                +        self.updates_allowed = Utils.to_bool(update)
                +        self.hashed_password = hashed_password
                +        self.commands = CLICommands(self.sh, self.updates_allowed)
                +        self.alive = False
                +
                +    def handle_connection(self):
                +        """
                +        Handle incoming connection
                +        """
                +        sock, address = self.accept()
                +        if sock is None:
                +            return
                +        self.logger.debug("{}: incoming connection from {} to {}".format(self._name, address, self.address))
                +        CLIHandler(self.sh, sock, address, self.updates_allowed, self.hashed_password, self.commands)
                +
                +    def run(self):
                +        """
                +        Called by SmartHomeNG to start plugin
                +        """
                +        self.alive = True
                +
                +    def stop(self):
                +        """
                +        Called by SmarthomeNG to stop plugin
                +        """
                +        self.alive = False
                +        self.close()
                +
                +    def add_command(self, command, function, usage):
                +        """
                +        Add command to list of available commands
                +        :param command: Command to add
                +        :param function: Function to execute for command
                +        :param usage: Usage string for help-command
                +        """
                +        self.commands.add_command(command, function, usage)
                +
                +    def remove_command(self, command):
                +        """
                +        Remove a command from the list of available commands
                +        :param command: Command to remove
                +        :return: True: command found and removed, False: command not found
                +        """
                +        return self.commands.remove_command(command)
                +
                +
                +class CLICommands:
                +    """
                +    Class containing handling for CLI commands as well as a basic set of commands
                +    """
                +
                +    def __init__(self, smarthome, updates_allowed=False):
                +        """
                +        Constructor
                +        :param smarthome: sh.py instance
                +        :param updates_allowed: bool True: basic commands may do updates, False: basic commands may not do updates
                +        """
                +        self.sh = smarthome
                +        self.logger = logging.getLogger(__name__)
                +        self.updates_allowed = updates_allowed
                +        self._commands = {}
                +
                +        # Add basic commands
                +        self.add_command('cl', self._cli_cl, 'cl [log]: clean (memory) log')
                +        self.add_command('la', self._cli_la, 'la: list all items (with values)')
                +        self.add_command('update', self._cli_update, 'update [item] = [value]: update the specified item with the specified value')
                +        self.add_command('up', self._cli_update, 'up: alias for update')
                +        self.add_command('ls', self._cli_ls, 'ls: list the first level items\nls [item]: list item and every child item (with values)')
                +        self.add_command('lo', self._cli_lo, 'lo: list all logics and next execution time')
                +        self.add_command('lt', self._cli_lt, 'lt: list current thread names')
                +        self.add_command('tr', self._cli_tr, 'tr [logic]: trigger logic')
                +        self.add_command('rl', self._cli_rl, 'rl [logic]: reload logic')
                +        self.add_command('rr', self._cli_rr, 'rr [logic]: reload and run logic')
                +        self.add_command('rt', self._cli_rt, 'rt: return runtime')
                +        self.add_command('dump', self._cli_dump, 'dump [item]: dump details about given item')
                +        self.add_command('help', self._cli_help, None)
                +        self.add_command('h', self._cli_help, None)
                +        self.add_command('sl', self._cli_sl, 'sl: list all scheduler tasks by name')
                +        self.add_command('st', self._cli_sl, 'st: list all scheduler tasks by execution time')
                +        self.add_command('si', self._cli_si, 'si [task]: show details for given task')
                +        self.add_command('ld', self._cli_ld, 'ld [log]: log dump of (memory) log')
                +        self.add_command('el', self._cli_el, 'el [logic]: enables logic')
                +        self.add_command('dl', self._cli_dl, 'dl [logic]: disables logic')
                +
                +    def add_command(self, command, function, usage):
                +        """
                +        Add command to list
                +        :param command: Command to add
                +        :param function: Function to execute for command
                +        :param usage: Usage string for help-command
                +        """
                +        self._commands[command] = {'function': function, 'usage': usage}
                +
                +    def remove_command(self, command):
                +        """
                +        Remove a command from the list
                +        :param command: Command to remove
                +        :return: True: command found and removed, False: command not found
                +        """
                +        if command in self._commands:
                +            del self._commands[command]
                +            return True
                +        else:
                +            return False
                +
                +    def execute(self, handler, cmd, source):
                +        """
                +        Execute an arbitrary command
                +        :param handler: CLIHandler to use for reply
                +        :param cmd: Received command
                +        :param source: Call source
                +        :return: TRUE: Command found and handled, FALSE: Unknown command, nothing done
                +        """
                +        for command, data in self._commands.items():
                +            if cmd == command or cmd.startswith(command + " "):
                +                try:
                +                    data['function'](handler, cmd.lstrip(command).strip(), source)
                +                except Exception as e:
                +                    self.logger.exception(e)
                +                    handler.push("Exception \"{0}\" occured when executing command \"{1}\".\n".format(e, command))
                +                    handler.push("See smarthomeNG log for details\n")
                +                return True
                +        return False
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_tr(self, handler, parameter, source):
                +        """
                +        CLI command "tr" - Trigger logic
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if not self.updates_allowed:
                +            handler.push("Logic triggering is not allowed.\n")
                +            return
                +        if parameter is None or parameter == "":
                +            handler.push("Please name logic to trigger\n")
                +        elif parameter in self.sh.return_logics():
                +            self.sh.trigger(parameter, by='CLI')
                +            handler.push("Logic '{0}' triggered.\n".format(parameter))
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(parameter))
                +
                +    def _cli_el(self, handler, parameter, source):
                +        if not self.updates_allowed:
                +            handler.push("Logic triggering is not allowed.\n")
                +            return
                +        if parameter in self.sh.return_logics():
                +            self.sh.return_logic(parameter).enable()
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(parameter))
                +
                +    def _cli_dl(self, handler, parameter, source):
                +        if not self.updates_allowed:
                +            handler.push("Logic triggering is not allowed.\n")
                +            return
                +        if parameter in self.sh.return_logics():
                +            self.sh.return_logic(parameter).disable()
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(parameter))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_rl(self, handler, parameter, source):
                +        """
                +        CLI command "rl" - Reload logic
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if not self.updates_allowed:
                +            handler.push("Logic triggering is not allowed.\n")
                +            return
                +        if parameter is None or parameter == "":
                +            handler.push("Please name logic to reload\n")
                +        elif parameter in self.sh.return_logics():
                +            logic = self.sh.return_logic(parameter)
                +            logic.generate_bytecode()
                +            handler.push("Logic '{0}' reloaded.\n".format(parameter))
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(parameter))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_rr(self, handler, parameter, source):
                +        """
                +        CLI command "rr" - Reload and trigger logic
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if not self.updates_allowed:
                +            handler.push("Logic triggering is not allowed.\n")
                +            return
                +        if parameter is None or parameter == "":
                +            handler.push("Please name logic to reload and trigger")
                +        elif parameter in self.sh.return_logics():
                +            logic = self.sh.return_logic(parameter)
                +            logic.generate_bytecode()
                +            logic.trigger(by='CLI')
                +            handler.push("Logic '{0}' reloaded and triggered.\n".format(parameter))
                +        else:
                +            handler.push("Logic '{0}' not found.\n".format(name))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_lo(self, handler, parameter, source):
                +        """
                +        CLI command "lo" - List logics
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        handler.push("Logics:\n")
                +        for logic in sorted(self.sh.return_logics()):
                +            data = []
                +            lo = self.sh.return_logic(logic)
                +            nt = self.sh.scheduler.return_next(logic)
                +            if lo.enabled == False:
                +                data.append("disabled")
                +            if nt is not None:
                +                data.append("scheduled for {0}".format(nt.strftime('%Y-%m-%d %H:%M:%S%z')))
                +            handler.push("{0}".format(logic))
                +            if len(data):
                +                handler.push(" ({0})".format(", ".join(data)))
                +            handler.push("\n")
                +
                +    # noinspection PyUnusedLocal,PyMethodMayBeStatic
                +    def _cli_lt(self, handler, parameter, source):
                +        """
                +        CLI command "lt" - list all threads with names
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        handler.push("{0} Threads:\n".format(threading.activeCount()))
                +        for t in threading.enumerate():
                +            handler.push("{0}\n".format(t.name))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_rt(self, handler, parameter, source):
                +        """
                +        CLI command "rt" - show runtime
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        handler.push("Runtime: {}\n".format(self.sh.runtime()))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_ls(self, handler, parameter, source):
                +        """
                +        CLI command "ls" - list first level items
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        handler.push("Items:\n======\n")
                +        self._cli_ls_int(handler, parameter, '*' in parameter or ':' in parameter)
                +
                +    def _cli_ls_int(self, handler, parameter, match=True):
                +        """
                +        Internal processing for command "ls"
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param match: True: use match_items to select items, False: single item given
                +        """
                +        if not parameter:
                +            for item in self.sh:
                +                handler.push("{0}\n".format(item.id()))
                +        else:
                +            if match:
                +                items = self.sh.match_items(parameter)
                +                childs = False
                +            else:
                +                items = [self.sh.return_item(parameter)]
                +                childs = True
                +            if len(items):
                +                for item in items:
                +                    if hasattr(item, 'id'):
                +                        if item.type():
                +                            handler.push("{0} = {1}\n".format(item.id(), item()))
                +                        else:
                +                            handler.push("{}\n".format(item.id()))
                +                        if childs:
                +                            for child in item:
                +                                self._cli_ls_int(handler, child.id())
                +            else:
                +                handler.push("Could not find path: {}\n".format(parameter))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_dump(self, handler, parameter, source):
                +        """
                +        CLI command "dump" - dump item(s)
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if '*' in parameter or ':' in parameter:
                +            items = self.sh.match_items(parameter)
                +        else:
                +            items = [self.sh.return_item(parameter)]
                +        if len(items):
                +            for item in items:
                +                # noinspection PyProtectedMember
                +                if hasattr(item, 'id') and item._type:
                +                    handler.push("Item {} ".format(item.id()))
                +                    handler.push("{\n")
                +                    handler.push("  type = {}\n".format(item.type()))
                +                    handler.push("  value = {}\n".format(item()))
                +                    handler.push("  age = {}\n".format(item.age()))
                +                    handler.push("  last_change = {}\n".format(item.last_change()))
                +                    handler.push("  changed_by = {}\n".format(item.changed_by()))
                +                    handler.push("  previous_value = {}\n".format(item.prev_value()))
                +                    handler.push("  previous_age = {}\n".format(item.prev_age()))
                +                    handler.push("  previous_change = {}\n".format(item.prev_change()))
                +                    if hasattr(item, 'conf'):
                +                        handler.push("  config = {\n")
                +                        for name in item.conf:
                +                            handler.push("    {} = {}\n".format(name, item.conf[name]))
                +                        handler.push("  }\n")
                +                    handler.push("  logics = [\n")
                +                    for trigger in item.get_logic_triggers():
                +                        handler.push("    {}\n".format(trigger))
                +                    handler.push("  ]\n")
                +                    handler.push("  triggers = [\n")
                +                    for trigger in item.get_method_triggers():
                +                        handler.push("    {}\n".format(trigger))
                +                    handler.push("  ]\n")
                +                    handler.push("}\n")
                +        else:
                +            handler.push("Nothing found\n")
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_help(self, handler, parameter, source):
                +        """
                +        CLI command "help" - show available commands
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        for command, data in sorted(self._commands.items()):
                +            if data['usage'] is not None:
                +                handler.push(data['usage'] + '\n')
                +        handler.push('quit: quit the session\n')
                +        handler.push('q: alias for quit\n')
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_cl(self, handler, parameter, source):
                +        """
                +        CLI command "cl" - clear (memory) log
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if parameter is None or parameter == "":
                +            log = self.sh.log
                +        else:
                +            logs = self.sh.return_logs()
                +            if parameter not in logs:
                +                handler.push("Log '{0}' does not exist\n".format(parameter))
                +                log = None
                +            else:
                +                log = logs[parameter]
                +
                +        if log is not None:
                +            log.clean(self.sh.now())
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_la(self, handler, parameter, source):
                +        """
                +        CLI command "la" - list all items
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        handler.push("Items:\n======\n")
                +        for item in self.sh.return_items():
                +            if item.type():
                +                handler.push("{0} = {1}\n".format(item.id(), item()))
                +            else:
                +                handler.push("{0}\n".format(item.id()))
                +
                +    def _cli_update(self, handler, parameter, source):
                +        """
                +        CLI command "update" - update item value
                +        :param handler: CLIHandler instance
                +        :param parameter: Parameters used to call the command
                +        :param source: Source
                +        """
                +        if not self.updates_allowed:
                +            handler.push("Updating items is not allowed.\n")
                +            return
                +        path, sep, value = parameter.partition('=')
                +        path = path.strip()
                +        value = value.strip()
                +        if not value:
                +            handler.push("You have to specify an item value. Syntax: up item = value\n")
                +            return
                +        items = self.sh.match_items(path)
                +        if len(items):
                +            for item in items:
                +                if not item.type():
                +                    handler.push("Could not find item with a valid type specified: '{0}'\n".format(path))
                +                    return
                +                item(value, 'CLI', source)
                +        else:
                +            handler.push("Could not find any item with given pattern: '{0}'\n".format(path))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_sl(self, handler, parameter, source):
                +        logics = sorted(self.sh.return_logics())
                +        tasks = []
                +        for name in sorted(self.sh.scheduler):
                +            nt = self.sh.scheduler.return_next(name)
                +            if name not in logics and nt is not None:
                +                task = {'nt': nt, 'name': name}
                +                tasks.append(task)
                +
                +        handler.push("{} scheduler tasks:\n".format(len(tasks)))
                +        for task in tasks:
                +            handler.push("{0} (scheduled for {1})\n".format(task['name'], task['nt'].strftime('%Y-%m-%d %H:%M:%S%z')))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_st(self, handler, parameter, source):
                +        logics = sorted(self.sh.return_logics())
                +        tasks = []
                +        for name in sorted(self.sh.scheduler):
                +            nt = self.sh.scheduler.return_next(name)
                +            if name not in logics and nt is not None:
                +                task = {'nt': nt, 'name': name}
                +                p = len(tasks)
                +                for i in range(0, len(tasks)):
                +                    if nt < tasks[i]['nt']:
                +                        p = i
                +                        break
                +                tasks.insert(p, task)
                +
                +        handler.push("{} scheduler tasks by time:\n".format(len(tasks)))
                +        for task in tasks:
                +            handler.push("{0} {1}\n".format(task['nt'].strftime('%Y-%m-%d %H:%M:%S%z'), task['name']))
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_si(self, handler, parameter, source):
                +        if parameter not in self.sh.scheduler._scheduler:
                +            handler.push("Scheduler task '{}' not found\n".format(parameter))
                +        else:
                +            task = self.sh.scheduler._scheduler[parameter]
                +            handler.push("Task {}".format(parameter))
                +            handler.push("{\n")
                +            for key in task:
                +                handler.push("  {} = {}\n".format(key, task[key]))
                +            handler.push("}\n")
                +
                +    # noinspection PyUnusedLocal
                +    def _cli_ld(self, handler, parameter, source):
                +        if parameter is None or parameter == "":
                +            log = self.sh.log
                +        else:
                +            logs = self.sh.return_logs()
                +            if parameter not in logs:
                +                handler.push("Log '{0}' does not exist\n".format(parameter))
                +                log = None
                +            else:
                +                log = logs[parameter]
                +
                +        if log is not None:
                +            handler.push("Log dump of '{0}':\n".format(log._name))
                +            for entry in log.last(10):
                +                values = [str(value) for value in entry]
                +                handler.push(str(values))
                +                handler.push("\n")
                diff --git a/cli/_pv_1_3_0/plugin.yaml b/cli/_pv_1_3_0/plugin.yaml
                new file mode 100755
                index 000000000..8eb3f228b
                --- /dev/null
                +++ b/cli/_pv_1_3_0/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    subtype: core                 # plugin subtype (if applicable)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Command Line Interface für SmartHomeNG - Letzte Version, die das Logics-API nicht benötigt, funktioniert bis SmartHomeNG v1.3'
                +        en: 'Commandline interface for SmartHomeNG - Last version not depending on the logics-API, works up to SmartHomeNG v1.3'
                +    maintainer: cmalo (mknx)
                +    tester: onkelandy, Sandman60, ohinckel
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +    sh_maxversion: 1.3c            # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: CLI                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/cli/plugin.yaml b/cli/plugin.yaml
                new file mode 100755
                index 000000000..641fe6653
                --- /dev/null
                +++ b/cli/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    subtype: core                 # plugin subtype (if applicable)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Command Line Interface für SmartHomeNG - Funktioniert mit SmartHomeNG v1.4 und höher'
                +        en: 'Commandline interface for SmartHomeNG - Works with SmartHomeNG v1.4 and up'
                +    maintainer: msinn
                +    tester: onkelandy, Sandman60, ohinckel
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.4.0                 # Plugin version
                +    sh_minversion: 1.3b            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: CLI                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/co2meter/README.md b/co2meter/README.md
                new file mode 100644
                index 000000000..d6d3453a8
                --- /dev/null
                +++ b/co2meter/README.md
                @@ -0,0 +1,47 @@
                +# CO2Meter
                +
                +## Description
                +
                +The CO2Meter Plugin allows to access a Dostmann TFA Dostmann AirCO2ntrol device via its raw USB data.
                +
                +## Requirements
                +
                +There are no requirements for this plugin.
                +
                +Forum thread to the plugin: https://knx-user-forum.de/forum/supportforen/smarthome-py/1165010-supportthread-f%C3%BCr-das-co2meter-plugin
                +
                +The code was adapted from the CO2Meter project Copyright 2017 by Michael Heinemann under MIT License 
                +(https://github.com/heinemml/CO2Meter/).
                +
                +## Configuration
                +
                +### plugin.yaml
                +```yaml
                +co2meter:
                +    class_name: CO2Meter
                +    class_path: plugins.co2meter
                +    device: '/dev/hidraw0'
                +    time_sleep: 5
                +```
                +#### Attributes
                +  * `device`: Path to raw usb data (optional, default: /dev/hidraw0)
                +  * `time_sleep`: Seconds to wait after each request (optional, default: 5)
                +  
                +### items.yaml
                +
                +#### co2meter_data_type
                +This attribute defines supported values of the co2 meter. Full set of tested values see example below.
                +
                +#### Example
                +```yaml
                +co2:
                +
                +    temperature:
                +        type: num
                +        co2meter_data_type: temperature
                + 
                +    co2:
                +        type: num
                +        co2meter_data_type: co2
                +```
                +
                diff --git a/co2meter/__init__.py b/co2meter/__init__.py
                new file mode 100644
                index 000000000..ea2e0ba64
                --- /dev/null
                +++ b/co2meter/__init__.py
                @@ -0,0 +1,201 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Original CO2Meter project Copyright 2017 by Michael Heinemann
                +#  under MIT License (https://github.com/heinemml/CO2Meter/)
                +#  Adaptions as SmartHomeNG Plugin Copyright 2017 Marc René Frieß
                +#########################################################################
                +#
                +# This file is part of SmartHomeNG.
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                +#
                +#########################################################################
                +
                +import logging
                +import sys
                +import fcntl
                +import threading
                +import weakref
                +import time
                +
                +from lib.model.smartplugin import SmartPlugin
                +
                +
                +class CO2Meter(SmartPlugin):
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = "1.3.0.1"
                +
                +    CO2METER_CO2 = 0x50
                +    CO2METER_TEMP = 0x42
                +    CO2METER_HUM = 0x44
                +    HIDIOCSFEATURE_9 = 0xC0094806
                +
                +    _key = [0xc4, 0xc6, 0xc0, 0x92, 0x40, 0x23, 0xdc, 0x96]
                +    _device = ""
                +    _values = {}
                +    _file = ""
                +    _running = True
                +
                +    def __init__(self, smarthome, device="/dev/hidraw0", time_sleep=5):
                +        """
                +        Initalizes the plugin. The parameters described for this method are pulled from the entry in plugin.conf.
                +
                +        :param smarthome:  The instance of the smarthome object, save it for later references
                +        :param device: Path where the raw usb data is retreived from (default: /dev/hidraw0)
                +        :param time_sleep: The time in seconds to sleep after a multicast was received
                +        """
                +        self._sh = smarthome
                +        self.logger = logging.getLogger(__name__)
                +        self._items = {}
                +        self._time_sleep = int(time_sleep)
                +
                +        self._device = device
                +        self._file = open(device, "a+b", 0)
                +
                +        set_report = [0] + self._key
                +        fcntl.ioctl(self._file, self.HIDIOCSFEATURE_9, bytearray(set_report))
                +
                +        thread = threading.Thread(target=self._co2_worker, name="CO2Meter_READ", args=(weakref.ref(self),))
                +        thread.daemon = True
                +        thread.start()
                +
                +    def run(self):
                +        """
                +        Run method for the plugin
                +        """
                +        self.alive = True
                +
                +        while self.alive:
                +            data = self.get_data()
                +            self.logger.debug(data)
                +            if 'temperature' in self._items:
                +                self._items['temperature'](data['temperature'])
                +            if 'co2' in self._items:
                +                self._items['co2'](data['co2'])
                +            if 'humidity' in self._items:
                +                self._items['humidity'](data['humidity'])
                +            time.sleep(self._time_sleep)
                +
                +    def stop(self):
                +        """
                +        Stop method for the plugin
                +        """
                +        self._running = False
                +        self.alive = False
                +
                +    def parse_item(self, item):
                +        """
                +        Default plugin parse_item method. Is called when the plugin is initialized.
                +        Selects each item corresponding to its attribute keywords and adds it to an internal array
                +
                +        :param item: The item to process.
                +        """
                +        if self.has_iattr(item.conf, 'co2meter_data_type'):
                +            self._items[self.get_iattr_value(item.conf, 'co2meter_data_type')] = item
                +    
                +    def _co2_worker(self, weak_self):
                +        while True:
                +            self = weak_self()
                +            if self is None:
                +                break
                +            self._read_data()
                +
                +            if not self._running:
                +                break
                +            del self
                +
                +    def _read_data(self):
                +        try:
                +            result = self._file.read(8)
                +            data = list(result)
                +
                +            decrypted = self._decrypt(data)
                +            if decrypted[4] != 0x0d or (sum(decrypted[:3]) & 0xff) != decrypted[3]:
                +                self.logger.debug(self._hd(data), " => ", self._hd(decrypted), "Checksum error")
                +            else:
                +                operation = decrypted[0]
                +                val = decrypted[1] << 8 | decrypted[2]
                +                self._values[operation] = val
                +        except:
                +            self._running = False
                +
                +
                +    def _decrypt(self, data):
                +        cstate = [0x48, 0x74, 0x65, 0x6D, 0x70, 0x39, 0x39, 0x65]
                +        shuffle = [2, 4, 0, 7, 1, 6, 5, 3]
                +
                +        phase1 = [0] * 8
                +        for i, j in enumerate(shuffle):
                +            phase1[j] = data[i]
                +
                +        phase2 = [0] * 8
                +        for i in range(8):
                +            phase2[i] = phase1[i] ^ self._key[i]
                +
                +        phase3 = [0] * 8
                +        for i in range(8):
                +            phase3[i] = ((phase2[i] >> 3) | (phase2[(i-1+8)%8] << 5)) & 0xff
                +
                +        ctmp = [0] * 8
                +        for i in range(8):
                +            ctmp[i] = ((cstate[i] >> 4) | (cstate[i]<<4)) & 0xff
                +
                +        out = [0] * 8
                +        for i in range(8):
                +            out[i] = (0x100 + phase3[i] - ctmp[i]) & 0xff
                +
                +        return out
                +
                +    @staticmethod
                +    def _hd(data):
                +        return " ".join("%02X" % e for e in data)
                +
                +
                +    def get_co2(self):
                +        if not self._running:
                +            raise IOError("worker thread couldn't read data")
                +        result = {}
                +        if self.CO2METER_CO2 in self._values:
                +            result = {'co2': self._values[self.CO2METER_CO2]}
                +
                +        return result
                +
                +
                +    def get_temperature(self):
                +        if not self._running:
                +            raise IOError("worker thread couldn't read data")
                +        result = {}
                +        if self.CO2METER_TEMP in self._values:
                +            result = {'temperature': (self._values[self.CO2METER_TEMP]/16.0-273.15)}
                +
                +        return result
                +
                +
                +    def get_humidity(self): # not implemented by all devices
                +        if not self._running:
                +            raise IOError("worker thread couldn't read data")
                +        result = {}
                +        if self.CO2METER_HUM in self._values:
                +            result = {'humidity': (self._values[self.CO2METER_HUM]/100.0)}
                +        return result
                +
                +
                +    def get_data(self):
                +        result = {}
                +        result.update(self.get_co2())
                +        result.update(self.get_temperature())
                +        result.update(self.get_humidity())
                +
                +        return result
                diff --git a/co2meter/plugin.yaml b/co2meter/plugin.yaml
                new file mode 100644
                index 000000000..f4aa5c556
                --- /dev/null
                +++ b/co2meter/plugin.yaml
                @@ -0,0 +1,43 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Über das CO2Meter Plugin können Daten aus dem Dostmann TFA AirCO2ntrol CO2 Messgerät via USB abgerufen werden.'
                +        en: 'The CO2Meter Plugin allows to access a Dostmann TFA Dostmann AirCO2ntrol device via its raw USB data.'
                +    maintainer: psilo909
                +    tester:
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1165010-supportthread-f%C3%BCr-das-co2meter-plugin
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: CO2Meter            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    device:
                +        type: str
                +        mandatory: False
                +        description:
                +            de: 'Pfad zu den rohen USB Daten (optional, default: /dev/hidraw0)'
                +            en: 'Path to raw usb data (optional, default: /dev/hidraw0)'
                +
                +    time_sleep:
                +        type: str
                +        mandatory: False
                +        description:
                +            de: 'Wartezeit in Sekundento nach jeder Datenanfrage (optional, default: 5)'
                +            en: 'Seconds to wait after each request (optional, default: 5)'
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    co2meter_data_type:
                +        type: str
                +        mandatory: True
                +        description:
                +            de: 'Der auszulesende Datentyp, "temperature" oder "co2"'
                +            en: 'The data type to read: "temperature" or "co2"'
                diff --git a/comfoair/README.md b/comfoair/README.md
                old mode 100644
                new mode 100755
                index 65895cffe..82a0715dd
                --- a/comfoair/README.md
                +++ b/comfoair/README.md
                @@ -19,7 +19,7 @@ This plugin has no requirements or dependencies.
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated) / .yaml
                 
                 ```
                 [comfoair]
                @@ -31,6 +31,16 @@ This plugin has no requirements or dependencies.
                     #serialport = /dev/ttyUSB0  # Enable this if you want to use a serial connection
                 ```
                 
                +```
                +comfoair:
                +    class_name: ComfoAir
                +    class_path: plugins.comfoair
                +    kwltype: comfoair350       # Currently supported: comfoair350 and comfoair500
                +    host: 192.168.123.6        # Provide host and port if you want to use TCP connection (for a TCP to serial converter)
                +    port: 5555                 # Port
                +    #serialport: /dev/ttyUSB0  # Enable this if you want to use a serial connection
                +```
                +
                 ### items.conf
                 
                 The plugin is completely flexible in which commands you use and when you want the read out which parameters.
                @@ -89,6 +99,7 @@ e.g. comfoair_trigger_afterwrite = 10 # seconds
                 Here you can find a sample configuration using the ComfoAir 350 commands:
                 
                 ```
                +# .conf (deprecated)
                 [kwl]
                     [[level]]
                         type = num
                @@ -221,8 +232,148 @@ Here you can find a sample configuration using the ComfoAir 350 commands:
                         type = num
                         eval = (sh.kwl.temp.supplyair() - sh.kwl.temp.freshair()) / (sh.kwl.temp.extractair() - sh.kwl.temp.exhaustair()) * 100
                         eval_trigger = kwl.temp.supplyair | kwl.temp.freshair | kwl.temp.extractair | kwl.temp.exhaustair
                +```
                 
                 ```
                +# .yaml
                +kwl:
                +    level:
                +        type: num
                +        comfoair_send: WriteVentilationLevel
                +        comfoair_read: ReadCurrentVentilationLevel
                +        comfoair_read_afterwrite: 1 # seconds
                +        comfoair_trigger: ReadSupplyAirRPM
                +        comfoair_trigger_afterwrite: 6 # seconds
                +        comfoair_init: true
                +        sqlite: yes
                +    extractair:
                +        rpm:
                +            type: num
                +            comfoair_read: ReadExtractAirRPM
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +        level:
                +            type: num
                +            comfoair_read: ReadExtractAirPercentage
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +    supplyair:
                +        rpm:
                +            type: num
                +            comfoair_read: ReadSupplyAirRPM
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +        level:
                +            type: num
                +            comfoair_read: ReadSupplyAirPercentage
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +    filter:
                +        reset:
                +            type: bool
                +            comfoair_send: WriteFilterReset
                +    temp:
                +        comfort:
                +            type: num
                +            comfoair_send: WriteComfortTemperature
                +            comfoair_read: ReadComfortTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +        freshair:
                +            type: num
                +            comfoair_read: ReadFreshAirTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +            sqlite: yes
                +        supplyair:
                +            type: num
                +            comfoair_read: ReadSupplyAirTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +            sqlite: yes
                +        extractair:
                +            type: num
                +            comfoair_read: ReadExtractAirTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +            sqlite: yes
                +        exhaustair:
                +            type: num
                +            comfoair_read: ReadExhaustAirTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +            sqlite: yes
                +        preheater:
                +            type: num
                +            comfoair_read: ReadPreHeatingTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +        groundheat:
                +            type: num
                +            comfoair_read: ReadGroundHeatTemperature
                +            comfoair_read_cycle: 60 # seconds
                +            comfoair_init: true
                +    bypass:
                +        type: num
                +        comfoair_read: ReadBypassPercentage
                +        comfoair_read_cycle: 600 # seconds
                +        comfoair_init: true
                +    preheater:
                +        type: num
                +        comfoair_read: ReadPreHeatingStatus
                +        comfoair_read_cycle: 600 # seconds
                +        comfoair_init: true
                +    operatinghours:
                +        away:
                +            type: num
                +            comfoair_read: ReadOperatingHoursAway
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        low:
                +            type: num
                +            comfoair_read: ReadOperatingHoursLow
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        medium:
                +            type: num
                +            comfoair_read: ReadOperatingHoursMedium
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        high:
                +            type: num
                +            comfoair_read: ReadOperatingHoursHigh
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        antifreeze:
                +            type: num
                +            comfoair_read: ReadOperatingHoursAntiFreeze
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        preheater:
                +            type: num
                +            comfoair_read: ReadOperatingHoursPreHeating
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        bypass:
                +            type: num
                +            comfoair_read: ReadOperatingHoursBypass
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +        filter:
                +            type: num
                +            comfoair_read: ReadOperatingHoursFilter
                +            comfoair_read_cycle: 3600 # seconds
                +            comfoair_init: true
                +    heatpreparationratio:
                +        type: num
                +        eval: (sh.kwl.temp.supplyair() - sh.kwl.temp.freshair()) / (sh.kwl.temp.extractair() - sh.kwl.temp.exhaustair()) * 100
                +        eval_trigger:
                +          - kwl.temp.supplyair
                +          - kwl.temp.freshair
                +          - kwl.temp.extractair
                +          - kwl.temp.exhaustair
                +```
                +
                 
                 ### logic.conf
                 Currently there is no logic configuration for this plugin.
                diff --git a/comfoair/__init__.py b/comfoair/__init__.py
                index 896db882d..85ef47b3a 100755
                --- a/comfoair/__init__.py
                +++ b/comfoair/__init__.py
                @@ -26,11 +26,16 @@
                 import threading
                 from . import commands
                 
                -logger = logging.getLogger('ComfoAir')
                +from lib.model.smartplugin import SmartPlugin
                 
                -class ComfoAir():
                +
                +class ComfoAir(SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.3.0'
                 
                     def __init__(self, smarthome, host=None, port=0, serialport=None, kwltype='comfoair350'):
                +        self.logger = logging.getLogger('ComfoAir')
                         self.connected = False
                         self._sh = smarthome
                         self._params = {}
                @@ -157,8 +162,8 @@ def read_bytes_serial(self, length):
                  
                     def parse_item(self, item):
                         # Process the read config
                -        if 'comfoair_read' in item.conf:
                -            commandname = item.conf['comfoair_read']
                +        if self.has_iattr(item.conf, 'comfoair_read'):
                +            commandname = self.get_iattr_value(item.conf, 'comfoair_read')
                             if (commandname == None or commandname not in self._commandset):
                                 self.log_err('Item {} contains invalid read command \'{}\'!'.format(item, commandname))
                                 return None
                @@ -175,15 +180,15 @@ def parse_item(self, item):
                                 self._params[commandcode]['items'].append(item)
                 
                             # Allow items to be automatically initiated on startup
                -            if ('comfoair_init' in item.conf and item.conf['comfoair_init'] == 'true'):
                +            if (self.has_iattr(item.conf, 'comfoair_init') and self.get_iattr_value(item.conf, 'comfoair_init') == 'true'):
                                 self.log_info('Item {} is initialized on startup.'.format(item))
                                 # Only add the item to the initial commands if it is not cyclic. Cyclic commands get called on init because this is the first cycle...
                -                if not commandcode in self._init_cmds and 'comfoair_read_cycle' not in item.conf:
                +                if not commandcode in self._init_cmds and not self.has_iattr(item.conf, 'comfoair_read_cycle'):
                                     self._init_cmds.append(commandcode)
                 
                             # Allow items to be cyclically updated
                -            if ('comfoair_read_cycle' in item.conf):
                -                cycle = int(item.conf['comfoair_read_cycle'])
                +            if (self.has_iattr(item.conf, 'comfoair_read_cycle')):
                +                cycle = int(self.get_iattr_value(item.conf, 'comfoair_read_cycle'))
                                 self.log_info('Item {} should read cyclic every {} seconds.'.format(item, cycle))
                 
                                 if not commandcode in self._cyclic_cmds:
                @@ -194,8 +199,8 @@ def parse_item(self, item):
                                         self._cyclic_cmds[commandcode]['cycle'] = cycle
                 
                         # Process the send config
                -        if 'comfoair_send' in item.conf:
                -            commandname = item.conf['comfoair_send']
                +        if self.has_iattr(item.conf, 'comfoair_send'):
                +            commandname = self.get_iattr_value(item.conf, 'comfoair_send')
                             if commandname == None:
                                 return None
                             elif commandname not in self._commandset:
                @@ -211,8 +216,8 @@ def parse_logic(self, logic):
                         pass
                 
                     def update_item(self, item, caller=None, source=None, dest=None):
                -        if caller != 'ComfoAir' and 'comfoair_send' in item.conf:
                -            commandname = item.conf['comfoair_send']
                +        if caller != 'ComfoAir' and self.has_iattr(item.conf, 'comfoair_send'):
                +            commandname = self.get_iattr_value(item.conf, 'comfoair_send')
                 
                             if type(item) != int:
                                 value = int(item())
                @@ -223,9 +228,9 @@ def update_item(self, item, caller=None, source=None, dest=None):
                             self.send_command(commandname, value)
                 
                             # If a read command should be sent after write
                -            if 'comfoair_read' in item.conf and 'comfoair_read_afterwrite' in item.conf:
                -                readcommandname = item.conf['comfoair_read']
                -                readafterwrite = item.conf['comfoair_read_afterwrite']
                +            if self.has_iattr(item.conf, 'comfoair_read') and self.has_iattr(item.conf, 'comfoair_read_afterwrite'):
                +                readcommandname = self.get_iattr_value(item.conf, 'comfoair_read')
                +                readafterwrite = self.get_iattr_value(item.conf, 'comfoair_read_afterwrite')
                                 self.log_debug('Attempting read after write for item {}, command {}, delay {}'.format(item, readcommandname, readafterwrite))
                                 if readcommandname is not None and readafterwrite is not None:
                                     aw = float(readafterwrite)
                @@ -233,14 +238,14 @@ def update_item(self, item, caller=None, source=None, dest=None):
                                     self.send_command(readcommandname)
                             
                             # If commands should be triggered after this write        
                -            if 'comfoair_trigger' in item.conf:
                -                trigger = item.conf['comfoair_trigger']
                +            if self.has_iattr_value(item.conf, 'comfoair_trigger'):
                +                trigger = self.get_iattr_value(item.conf, 'comfoair_trigger')
                                 if trigger == None:
                                     self.log_err('Item {} contains invalid trigger command list \'{}\'!'.format(item, trigger))
                                 else:
                                     tdelay = 5 # default delay
                -                    if 'comfoair_trigger_afterwrite' in item.conf:
                -                        tdelay = float(item.conf['comfoair_trigger_afterwrite'])
                +                    if self.has_iattr(item.conf, 'comfoair_trigger_afterwrite'):
                +                        tdelay = float(self.get_iattr_value(item.conf, 'comfoair_trigger_afterwrite'))
                                     if type(trigger) != list:
                                         trigger = [trigger] 
                                     for triggername in trigger:
                @@ -492,13 +497,13 @@ def calc_checksum(self, packetpart):
                         return (sum(packetpart) + 173) % 256
                     
                     def log_debug(self, text):    
                -        logger.debug('ComfoAir: {}'.format(text))    
                +        self.logger.debug('ComfoAir: {}'.format(text))
                 
                     def log_info(self, text):    
                -        logger.info('ComfoAir: {}'.format(text))    
                +        self.logger.info('ComfoAir: {}'.format(text))
                 
                     def log_err(self, text):    
                -        logger.error('ComfoAir: {}'.format(text))    
                +        self.logger.error('ComfoAir: {}'.format(text))
                     
                     def int2bytes(self, value, length):
                         # Limit value to the passed byte length
                diff --git a/comfoair/plugin.yaml b/comfoair/plugin.yaml
                new file mode 100755
                index 000000000..c2c6e72c5
                --- /dev/null
                +++ b/comfoair/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für Zehnder ComfoAir 350 & 500 KWL'
                +        en: ''
                +    maintainer: '? (SvStefan)'
                +    tester: ohinckel
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Comfoair-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/31291-neues-plugin-comfoair-kwl-wohnraumlüftung-zehnder-paul-wernig
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: ComfoAir             # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/dashbutton/plugin.yaml b/dashbutton/plugin.yaml
                new file mode 100755
                index 000000000..d1225dfbd
                --- /dev/null
                +++ b/dashbutton/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Amazon Dashbutton plugin, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: pfischi
                +    tester: psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1005266-plugin-amazon-dashbutton
                +
                +    version: 1.3.0.3               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Dashbutton          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/database/README.md b/database/README.md
                index d398dfaa2..3bb68ce8a 100755
                --- a/database/README.md
                +++ b/database/README.md
                @@ -26,6 +26,7 @@ The `log` table contains the following columns:
                 
                   * Column `time` - the unix timestamp in microseconds of value
                   * Column `item_id` - the reference to the unique ID in `item` table
                +  * Column `duration` - the duration in microseconds
                   * Column `val_str` - the string value if type is `str`
                   * Column `val_num` - the number value if type is `num`
                   * Column `val_bool` - the boolean value if type is `bool` or `num`
                @@ -132,9 +133,12 @@ for the specified function and timeframe.
                 Supported functions are:
                 
                    * `avg`: for the average value
                +   * `count`: for the amount of values not "0" (more examples: `count>10`, `count<10`, `count=10`)
                    * `max`: for the maximum value
                    * `min`: for the minimum value
                    * `on`: percentage (as float from 0.00 to 1.00) where the value has been greater than 0.
                +   * `sum`: for the summarized value
                +   * `raw`: for the raw values
                 
                 For the timeframe you have to specify a start point and a optional end point. By default it ends 'now'.
                 The time point could be specified with `<number><interval>`, where interval could be:
                @@ -163,6 +167,20 @@ sh.outside.temperature.series('min', '1d', count=10)  # returns 10 minimum value
                 sh.outside.temperature.series('avg', '2w', '1w')  # returns the average values of the week before last week
                 </pre>
                 
                +Additionally to the aggregation function a finalizer function can be specified when
                +fetching series to apply to the results before returning them. Specify the function
                +as prefix to the actual aggregation function (e.g. "diff:avg").
                +
                +Supported finalizer functions are:
                +
                +   * `diff`: return the differences between values
                +
                +e.g.
                +<pre>
                +sh.outside.temperature.series('diff:avg', '2w', '1w')  # returns the differences between average values
                +</pre>
                +
                +
                 ### sh.item.dbplugin
                 This property returns the associated `database` plugin instance. See the list of method below
                 to know what you can do with this instance.
                diff --git a/database/__init__.py b/database/__init__.py
                index 64d1a5110..665f8fa12 100755
                --- a/database/__init__.py
                +++ b/database/__init__.py
                @@ -88,9 +88,7 @@ def __init__(self, smarthome, driver, connect, prefix="", cycle=60):
                 
                     def parse_item(self, item):
                         if self.has_iattr(item.conf, 'database'):
                -            self._buffer_lock.acquire()
                -            self._buffer[item] = []
                -            self._buffer_lock.release()
                +            self._buffer_insert(item, [])
                             item.series = functools.partial(self._series, item=item.id())
                             item.db = functools.partial(self._single, item=item.id())
                             item.dbplugin = self
                @@ -109,9 +107,7 @@ def parse_item(self, item):
                                         prev_change = self._fetchone('SELECT MAX(time) from {log} WHERE item_id = :id', {'id':cache[COL_ITEM_ID]}, cur=cur)
                                         if value is not None and prev_change is not None:
                                             item.set(value, 'Database', prev_change=self._datetime(prev_change[0]), last_change=last_change)
                -                        self._buffer_lock.acquire()
                -                        self._buffer[item].append((last_change_ts, None, value))
                -                        self._buffer_lock.release()
                +                        self._buffer_insert(item, [(last_change_ts, None, value)])
                                 except Exception as e:
                                     self.logger.error("Reading cache value from database for {} failed: {}".format(item.id(), e))
                                 cur.close()
                @@ -306,27 +302,20 @@ def _dump(self, finalize=False, items=None):
                             self._buffer_lock.release()
                 
                         for item in items:
                -            self._buffer_lock.acquire()
                -            tuples = self._buffer[item]
                -            self._buffer[item] = self._buffer[item][len(tuples):]
                -            self._buffer_lock.release()
                +            tuples = self._buffer_remove(item)
                 
                             if len(tuples) or finalize:
                 
                                 # Test connectivity
                                 if self._db.verify(5) == 0:
                +                    self._buffer_insert(item, tuples)
                                     self.logger.error("Database: Connection not recovered, skipping dump");
                                     self._dump_lock.release()
                                     return
                 
                                 # Can't lock, restore data
                                 if not self._db.lock(300):
                -                    self._buffer_lock.acquire()
                -                    if item in self._buffer:
                -                        self._buffer[item] = tuples + self._buffer[item]
                -                    else:
                -                        self._buffer[item] = tuples
                -                    self._buffer_lock.release()
                +                    self._buffer_insert(item, tuples)
                                     if finalize:
                                         self.logger.error("Database: can't dump {} items due to fail to acquire lock!".format(len(self._buffer)))
                                     else:
                @@ -381,23 +370,73 @@ def _dump(self, finalize=False, items=None):
                         self.logger.debug('Dump completed')
                         self._dump_lock.release()
                 
                +    def _buffer_remove(self, item):
                +        self._buffer_lock.acquire()
                +        tuples = self._buffer[item]
                +        self._buffer[item] = self._buffer[item][len(tuples):]
                +        self._buffer_lock.release()
                +        return tuples
                +
                +    def _buffer_insert(self, item, tuples):
                +        self._buffer_lock.acquire()
                +        if item in self._buffer:
                +            self._buffer[item] = tuples + self._buffer[item]
                +        else:
                +            self._buffer[item] = tuples
                +        self._buffer_lock.release()
                +        return tuples
                +
                +    def _expression(self, func):
                +        expression = {'params' : {'op':'!=', 'value':'0'}, 'finalizer' : None}
                +        if ':' in func:
                +            expression['finalizer'] = func[:func.index(":")]
                +            func = func[func.index(":")+1:]
                +        if func is 'count' or func.startswith('count'):
                +            parts = re.match('(count)((<>|!=|<|=|>)(\d+))?', func)
                +            func = 'count'
                +            self.logger.debug(parts)
                +            self.logger.debug(parts.groups())
                +            self.logger.debug(parts.group(3))
                +            self.logger.debug(parts.group(4))
                +            if parts and parts.group(3) is not None:
                +                expression['params']['op'] = parts.group(3)
                +            if parts and parts.group(4) is not None:
                +                expression['params']['value'] = parts.group(4)
                +        return func, expression
                +
                +    def _finalize(self, func, tuples):
                +        if func == 'diff':
                +            final_tuples = []
                +            for i in range(1, len(tuples)-1):
                +                final_tuples.append((tuples[i][0], tuples[i][1] - tuples[i-1][1]))
                +            return final_tuples
                +        else:
                +            return tuples
                +
                     def _series(self, func, start, end='now', count=100, ratio=1, update=False, step=None, sid=None, item=None):
                         init = not update
                         if sid is None:
                             sid = item + '|' + func + '|' + str(start) + '|' + str(end)  + '|' + str(count)
                +        func, expression = self._expression(func)
                         queries = {
                             'avg' : 'MIN(time), ROUND(AVG(val_num * duration) / AVG(duration), 2)',
                             'avg.order' : 'ORDER BY time ASC',
                +            'count' : 'MIN(time), SUM(CASE WHEN val_num{op}{value} THEN 1 ELSE 0 END)'.format(**expression['params']),
                             'min' : 'MIN(time), MIN(val_num)',
                             'max' : 'MIN(time), MAX(val_num)',
                             'on'  : 'MIN(time), ROUND(SUM(val_bool * duration) / SUM(duration), 2)',
                -            'on.order' : 'ORDER BY time ASC'
                +            'on.order' : 'ORDER BY time ASC',
                +            'sum' : 'MIN(time), SUM(val_num)',
                +            'raw' : 'time, val_num',
                +            'raw.order' : 'ORDER BY time ASC',
                +            'raw.group' : ''
                         }
                         if func not in queries:
                             raise NotImplementedError
                 
                         order = '' if func+'.order' not in queries else queries[func+'.order']
                -        logs = self._fetch_log(item, queries[func], start, end, step=step, count=count, group="GROUP BY ROUND(time / :step)", order=order)
                +        group = 'GROUP BY ROUND(time / :step)' if func+'.group' not in queries else queries[func+'.group']
                +        logs = self._fetch_log(item, queries[func], start, end, step=step, count=count, group=group, order=order)
                         tuples = logs['tuples']
                         if tuples:
                             if logs['istart'] > tuples[0][0]:
                @@ -416,6 +455,9 @@ def _series(self, func, start, end='now', count=100, ratio=1, update=False, step
                             if init:
                                 tuples.append((logs['iend'], value))
                 
                +        if expression['finalizer']:
                +            tuples = self._finalize(expression['finalizer'], tuples)
                +
                         return {
                             'cmd': 'series', 'series': tuples, 'sid': sid,
                             'params' : {'update': True, 'item': item, 'func': func, 'start': logs['iend'], 'end': end, 'step': logs['step'], 'sid': sid},
                @@ -423,16 +465,23 @@ def _series(self, func, start, end='now', count=100, ratio=1, update=False, step
                         }
                 
                     def _single(self, func, start, end='now', item=None):
                +        func, expression = self._expression(func)
                         queries = {
                             'avg' : 'ROUND(AVG(val_num * duration) / AVG(duration), 2)',
                +            'count' : 'SUM(CASE WHEN val_num{op}{value} THEN 1 ELSE 0 END)'.format(**expression['params']),
                             'min' : 'MIN(val_num)',
                             'max' : 'MAX(val_num)',
                -            'on'  : 'ROUND(SUM(val_bool * duration) / SUM(duration), 2)'
                +            'on'  : 'ROUND(SUM(val_bool * duration) / SUM(duration), 2)',
                +            'sum' : 'SUM(val_num)',
                +            'raw' : 'val_num',
                +            'raw.order' : 'ORDER BY time DESC',
                +            'raw.group' : ''
                         }
                         if func not in queries:
                             self.logger.warning("Unknown export function: {0}".format(func))
                             return
                -        logs = self._fetch_log(item, queries[func], start, end)
                +        order = '' if func+'.order' not in queries else queries[func+'.order']
                +        logs = self._fetch_log(item, queries[func], start, end, order=order)
                         if logs['tuples'] is None:
                             return
                         return logs['tuples'][0][0]
                diff --git a/database/plugin.yaml b/database/plugin.yaml
                new file mode 100755
                index 000000000..872ef6215
                --- /dev/null
                +++ b/database/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Database plugin, **seit SmartHomeNG v1.3**'
                +        en: 'Database plugin, **since SmartHomeNG v1.3**'
                +    maintainer: ohinckel
                +    tester: psilo909, onkelandy, brandst
                +    keywords: database
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Database            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/database/tests/test_basic.py b/database/tests/test_basic.py
                index 77a3d69b7..439e44d74 100644
                --- a/database/tests/test_basic.py
                +++ b/database/tests/test_basic.py
                @@ -179,10 +179,10 @@ def test_dump_log(self):
                         plugin.dump(name)
                         self.assertLines(
                           "item_id;item_name;time;duration;val_str;val_num;val_bool;changed;time_date;changed_date\n"
                -          "1;main.num;0;3600;;10.0;1;0;1970-01-01 01:00:00;1970-01-01 01:00:00\n"
                -          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 01:00:03.600000;1970-01-01 01:00:03.600000\n"
                -          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 01:00:07.200000;1970-01-01 01:00:07.200000\n"
                -          "1;main.num;10800;3600;;10.0;1;10800;1970-01-01 01:00:10.800000;1970-01-01 01:00:10.800000\n",
                +          "1;main.num;0;3600;;10.0;1;0;1970-01-01 00:00:00;1970-01-01 00:00:00\n"
                +          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 00:00:03.600000;1970-01-01 00:00:03.600000\n"
                +          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 00:00:07.200000;1970-01-01 00:00:07.200000\n"
                +          "1;main.num;10800;3600;;10.0;1;10800;1970-01-01 00:00:10.800000;1970-01-01 00:00:10.800000\n",
                           self.read_tmpfile(name)
                         )
                 
                @@ -197,7 +197,7 @@ def test_dump_log_partial_time(self):
                         plugin.dump(name, time=3600)
                         self.assertLines(
                           "item_id;item_name;time;duration;val_str;val_num;val_bool;changed;time_date;changed_date\n"
                -          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 01:00:03.600000;1970-01-01 01:00:03.600000\n",
                +          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 00:00:03.600000;1970-01-01 00:00:03.600000\n",
                           self.read_tmpfile(name)
                         )
                 
                @@ -212,8 +212,8 @@ def test_dump_log_partial_time_range(self):
                         plugin.dump(name, time_start=3600, time_end=7200)
                         self.assertLines(
                           "item_id;item_name;time;duration;val_str;val_num;val_bool;changed;time_date;changed_date\n"
                -          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 01:00:03.600000;1970-01-01 01:00:03.600000\n"
                -          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 01:00:07.200000;1970-01-01 01:00:07.200000\n",
                +          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 00:00:03.600000;1970-01-01 00:00:03.600000\n"
                +          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 00:00:07.200000;1970-01-01 00:00:07.200000\n",
                           self.read_tmpfile(name)
                         )
                 
                @@ -228,7 +228,7 @@ def test_dump_log_partial_changed(self):
                         plugin.dump(name, changed=3600)
                         self.assertLines(
                           "item_id;item_name;time;duration;val_str;val_num;val_bool;changed;time_date;changed_date\n"
                -          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 01:00:03.600000;1970-01-01 01:00:03.600000\n",
                +          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 00:00:03.600000;1970-01-01 00:00:03.600000\n",
                           self.read_tmpfile(name)
                         )
                 
                @@ -243,8 +243,8 @@ def test_dump_log_partial_changed_range(self):
                         plugin.dump(name, changed_start=3600, changed_end=7200)
                         self.assertLines(
                           "item_id;item_name;time;duration;val_str;val_num;val_bool;changed;time_date;changed_date\n"
                -          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 01:00:03.600000;1970-01-01 01:00:03.600000\n"
                -          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 01:00:07.200000;1970-01-01 01:00:07.200000\n",
                +          "1;main.num;3600;3600;;20.0;1;3600;1970-01-01 00:00:03.600000;1970-01-01 00:00:03.600000\n"
                +          "1;main.num;7200;3600;;15.0;1;7200;1970-01-01 00:00:07.200000;1970-01-01 00:00:07.200000\n",
                           self.read_tmpfile(name)
                         )
                 
                diff --git a/database/tests/test_series.py b/database/tests/test_series.py
                index f039e17d5..23de1d059 100644
                --- a/database/tests/test_series.py
                +++ b/database/tests/test_series.py
                @@ -1,3 +1,4 @@
                +import pytest
                 
                 from plugins.database import Database
                 from plugins.database.tests.base import TestDatabaseBase
                @@ -29,7 +30,6 @@ def test_series_now_no_log_now_returns_last_item_value_when_before_start(self):
                         self.assertSeriesCount(2, res)
                         self.assertSeries([(item_change_ts/TestDatabaseBase.TIME_FACTOR, 0.0), (res['series'][1][0]/TestDatabaseBase.TIME_FACTOR,0.0)], res)
                 
                -
                     def test_series_avg(self):
                         """ Test AVG selection with no aggregation and last value copied to end.
                         """
                @@ -41,6 +41,21 @@ def test_series_avg(self):
                         res = plugin._series('avg', start=self.t(0), end=self.t(12), item='main.num')
                         self.assertSeries([(1, 10), (11, 20), (12, 20)], res)
                 
                +    def test_series_avg_diff(self):
                +        """ Test DIFF:AVG selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20),
                +          (21, 10, 30),
                +          (31, 10, 40),
                +          (41, 10, 50),
                +          (51, 10, 60)
                +        ])
                +        res = plugin._series('diff:avg', start=self.t(0), end=self.t(52), item='main.num')
                +        self.assertSeries([(11, 10.0), (21, 10.0), (31, 10.0), (41, 10.0), (51, 10.0)], res)
                +
                     def test_series_min(self):
                         """ Test MIN selection with no aggregation and last value copied to end.
                         """
                @@ -63,6 +78,72 @@ def test_series_max(self):
                         res = plugin._series('max', start=self.t(0), end=self.t(12), item='main.num')
                         self.assertSeries([(1, 10), (11, 20), (12, 20)], res)
                 
                +    def test_series_sum(self):
                +        """ Test SUM selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('sum', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 10), (11, 20), (12, 20)], res)
                +
                +    def test_series_count(self):
                +        """ Test COUNT selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('count', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 1), (11, 1), (12, 1)], res)
                +
                +    def test_series_count_eq_10(self):
                +        """ Test COUNT selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('count=10', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 1), (11, 0), (12, 0)], res)
                +
                +    def test_series_count_gt_10(self):
                +        """ Test COUNT selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('count>10', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 0), (11, 1), (12, 1)], res)
                +
                +    def test_series_count_lt_20(self):
                +        """ Test COUNT selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('count<20', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 1), (11, 0), (12, 0)], res)
                +
                +    def test_series_val(self):
                +        """ Test VAL selection with no aggregation and last value copied to end.
                +        """
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          ( 1, 10, 10),
                +          (11, 10, 20)
                +        ])
                +        res = plugin._series('sum', start=self.t(0), end=self.t(12), item='main.num')
                +        self.assertSeries([(1, 10), (11, 20), (12, 20)], res)
                +
                     def test_series_avg_aggregation(self):
                         """ Test AVG selection with aggregation and last value copied to end.
                         """
                @@ -111,6 +192,35 @@ def test_series_max_aggregation(self):
                         res = plugin._series('max', start=self.t(10), end=self.t(50), item='main.num', count=5)
                         self.assertSeries([(10, 100.0), (16, 40.0), (24, 100.0), (32, 80.0), (40, 80.0), (48, 100.0), (50, 100.0)], res)
                 
                +    def test_series_sum_aggregation(self):
                +        """ Test SUM selection with aggregation and last value copied to end.
                +        """
                +        values = self.log_slice(0, 1,
                +            self.log_slice_values_delta( 10, 100,  10),
                +            self.log_slice_values_delta(100,  10, -10),
                +            self.log_slice_values_delta( 10, 100,  10),
                +            self.log_slice_values_delta(100,  10, -10),
                +            self.log_slice_values_delta( 10, 100,  10),
                +            self.log_slice_values_delta(100,  10, -10),
                +        )
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', values)
                +        res = plugin._series('sum', start=self.t(10), end=self.t(50), item='main.num', count=5)
                +        self.assertSeries([(10, 550.0), (16, 200.0), (24, 640.0), (32, 360.0), (40, 360.0), (48, 290.0), (50, 290.0)], res)
                +
                +    def test_series_raw_aggregation(self):
                +        """ Test RAW selection with aggregation and last value copied to end.
                +        """
                +        values = self.log_slice(0, 1,
                +            self.log_slice_values_delta( 10, 100,  10),
                +            self.log_slice_values_delta(100,  10, -10)
                +        )
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', values)
                +        res = plugin._series('raw', start=self.t(10), end=self.t(50), item='main.num', count=5)
                +        self.assertSeries([(10, 100.0), (10, 100.0), (11, 90.0), (12, 80.0), (13, 70.0), (14, 60.0), (15, 50.0), (16, 40.0), (17, 30.0), (18, 20.0), (19, 10.0), (50, 10.0)], res)
                +
                +    @pytest.mark.skip(reason="series does not return last value currently")
                     def test_series_returns_last_value_outside_range(self):
                         """ Return last value instead of given
                         """
                @@ -124,6 +234,7 @@ def test_series_returns_last_value_outside_range(self):
                         )
                         plugin = self.plugin()
                         self.create_log(plugin, 'main.num', values)
                +        self.dump_log(plugin, 'main.num')
                         res = plugin._series('avg', start=self.t(60), end=self.t(70), item='main.num', count=5)
                -        self.assertSeries([(10, 100.0), (16, 40.0), (24, 100.0), (32, 80.0), (40, 80.0), (48, 100.0), (50, 100.0)], res)
                +        self.assertSeries([(60, 10.0), (70, 10.0)], res)
                 
                diff --git a/database/tests/test_single.py b/database/tests/test_single.py
                index 1fd34ded2..80e678937 100644
                --- a/database/tests/test_single.py
                +++ b/database/tests/test_single.py
                @@ -37,6 +37,60 @@ def test_single_max(self):
                         res = plugin._single('max', start=self.t(0), end='now', item='main.num')
                         self.assertSingle(20, res)
                 
                +    def test_single_sum(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('sum', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(30, res)
                +
                +    def test_single_count(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('count', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(2, res)
                +
                +    def test_single_count_eq_10(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('count=10', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(1, res)
                +
                +    def test_single_count_gt_10(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('count>10', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(1, res)
                +
                +    def test_single_count_lt_20(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('count<20', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(1, res)
                +
                +    def test_single_raw(self):
                +        plugin = self.plugin()
                +        self.create_log(plugin, 'main.num', [
                +          (1, 2, 10),
                +          (2, 3, 20)
                +        ])
                +        res = plugin._single('raw', start=self.t(0), end='now', item='main.num')
                +        self.assertSingle(20, res)
                +
                     def test_single_on(self):
                         plugin = self.plugin()
                         self.create_log(plugin, 'main.num', [
                diff --git a/datalog/README.md b/datalog/README.md
                old mode 100644
                new mode 100755
                index bbbff8e22..62d343fd8
                --- a/datalog/README.md
                +++ b/datalog/README.md
                @@ -12,35 +12,48 @@ No special hardware required.
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated) / .yaml
                 
                 The plugin can be configured using the following settings:
                 
                 ```
                 [datalog]
                -   class_name = DataLog
                -   class_path = plugins.datalog
                -#   path = var/log/data
                -#   filepatterns = default:{log}-{year}-{month}-{day}.csv | yearly:{log}-{year}.csv
                -#   logpatterns = csv:{time};{item};{value}\n
                -#   cycle = 300
                +    class_name = DataLog
                +    class_path = plugins.datalog
                +#    path = var/log/data
                +#    filepatterns = default:{log}-{year}-{month}-{day}.csv | yearly:{log}-{year}.csv
                +#    logpatterns = csv:{time};{item};{value}\n
                +#    cycle = 300
                +```
                +
                +```
                +datalog:
                +    class_name: DataLog
                +    class_path: plugins.datalog
                +#    path: var/log/data
                +#    filepatterns:
                +#      - default:{log}-{year}-{month}-{day}.csv
                +#      - yearly:{log}-{year}.csv
                +#    logpatterns:
                +#      - csv:{time};{item};{value}\n
                +#    cycle: 300
                 ```
                 
                -This will setup the logs `default` and `yearly`, which is using the configured
                -patter to build the target file name (key-value pairs). The `default` log is
                +This will setup the logs `default` and `yearly`, which are using the configured
                +pattern to build the target file name (key-value pairs). The `default` log is
                 configured automatically if you do not specify any file patterns.
                 
                -Additionally the patterns to use to log the data into the files is configured
                -also configured there. The key-value pairs are specifying the file extension
                +Additionally the patterns to use to log the data into the files is also
                +configured there. The key-value pairs are specifying the file extension
                 and the log pattern to use. In this example all log files having the extension
                 `.csv` will be logged using the configured pattern. This is also the default
                -if you do not specify any log patterns. in the configuration.
                +if you do not specify any log patterns in the configuration.
                 
                 Both settings can make use of some placeholders (see below).
                 
                -The path paramter can be used to log into a different path intead of the default
                -path and the cycle parameter defines the interval to use to dump the data
                -into the log files, which defaults to 300 seconds.
                +The path parameter can be used to log into a different path instead of the
                +default path and the cycle parameter defines the interval to use to dump the
                +data into the log files, which defaults to 300 seconds.
                 
                 Placeholders which can be used in the `logpatterns` option:
                 
                @@ -49,15 +62,37 @@ Placeholders which can be used in the `logpatterns` option:
                    * `item` - the id of the item
                    * `value` - the value of items
                 
                -### items.conf
                +Example:
                +
                +```
                +# .conf (deprecated)
                +[datalog]
                +   class_name = DataLog
                +   class_path = plugins.datalog
                +   filepatterns = default:{log}-{year}-{month}-{day}.csv | custom:{log}-{year}-{month}-{day}.txt
                +   logpatterns = csv:{time};{item};{value}\n
                +```
                +
                +```
                +# .yaml
                +datalog:
                +   class_name = DataLog
                +   class_path = plugins.datalog
                +   filepatterns = default:{log}-{year}-{month}-{day}.csv | custom:{log}-{year}-{month}-{day}.txt
                +   logpatterns = csv:{time};{item};{value}\n
                +  
                +```
                +
                +In this example the `default` log file will use the configured log pattern. The
                +`custom` log file is completely ignored, since no pattern is configured.
                 
                -#### path
                +#### path attribute
                 
                 Specifies the path to log into. The default value is `var/log/data` which can
                 be changed by using this option. All log files will be logged into this directory.
                 It's not possible to configure different log paths for different log files.
                 
                -#### filepatterns
                +#### filepatterns attribute
                 
                 This specifies a list of file patterns, which is used to build the target files
                 to log data into. It's using a key-value pair syntax, which means you can
                @@ -70,7 +105,7 @@ Placeholders which can be used in the `filepatterns` option:
                    * `month` - the current month
                    * `day` - the current day
                 
                -#### logpatterns
                +#### logpatterns attribute
                 
                 The log pattners setting configured the format in which the data will be
                 logged into the log files. It's using a key-value pair syntax, which means
                @@ -79,24 +114,13 @@ you can configure multiple log patterns.
                 A log pattern is used for logging when a file pattern is configured, where
                 the extension (part behind the last `.`) matches the key.
                 
                -Example:
                -```
                -[datalog]
                -   class_name = DataLog
                -   class_path = plugins.datalog
                -   filepatterns = default:{log}-{year}-{month}-{day}.csv | custom:{log}-{year}-{month}-{day}.txt
                -   logpatterns = csv:{time};{item};{value}\n
                -```
                -
                -In this example the `default` log file will use the configured log pattern. The
                -`custom` log file is completely ignored, since no pattern is configured.
                 
                -#### Example
                +### items.conf
                 
                 Example configuration using the plugin configuration on top of the page.
                 
                 ```
                -# items/my.conf
                +# .conf (deprecated)
                 [some]
                     [[item1]]
                         type = str
                @@ -109,6 +133,22 @@ Example configuration using the plugin configuration on top of the page.
                         datalog = custom
                 ```
                 
                +```
                +# .yaml
                +some:
                +    item1:
                +        type: str
                +        datalog: default
                +    item2:
                +        type: num
                +        datalog:
                +          - default
                +          - custom
                +    item3:
                +        type: num
                +        datalog: custom
                +```
                +
                 This will log the items
                 
                    * `some.item1` to the `default` log
                diff --git a/datalog/__init__.py b/datalog/__init__.py
                index a9ab7c40d..cf30ec878 100755
                --- a/datalog/__init__.py
                +++ b/datalog/__init__.py
                @@ -1,8 +1,8 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                -#
                -# Copyright 2013 KNX-User-Forum e.V.            http://knx-user-forum.de/
                -#
                +#########################################################################
                +#  Copyright 2013-     Oliver Hinckel                  github@ollisnet.de
                +#########################################################################
                 #  This file is part of SmartHomeNG.    https://github.com/smarthomeNG//
                 #
                 #  SmartHomeNG is free software: you can redistribute it and/or modify
                @@ -17,13 +17,20 @@
                 #
                 #  You should have received a copy of the GNU General Public License
                 #  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                -#
                +#########################################################################
                 
                 import logging
                 import time
                 import threading
                 
                -class DataLog():
                +from lib.model.smartplugin import SmartPlugin
                +
                +
                +class DataLog(SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = True
                +    PLUGIN_VERSION = '1.3.0'
                +
                     filepatterns = {}
                     logpatterns = {}
                     cycle = 0
                @@ -64,7 +71,7 @@ def __init__(self, smarthome, path="var/log/data", filepatterns={ "default" : "{
                             ext = newfilepatterns[log].split('.')[-1]
                             if ext in newlogpatterns:
                                 self.filepatterns[log] = newfilepatterns[log]
                -                self.logpatterns[log] = logpatterns[ext]
                +                self.logpatterns[log] = newlogpatterns[ext]
                             else:
                                 self.logger.warn('DataLog: Ignoring log "{}", log pattern missing!'.format(log))
                 
                @@ -86,11 +93,12 @@ def stop(self):
                         self._dump()
                 
                     def parse_item(self, item):
                -        if 'datalog' in item.conf:
                -            if type(item.conf['datalog']) is list:
                -                logs = item.conf['datalog']
                +        if self.has_iattr(item.conf, 'datalog'):
                +            datalog = self.get_iattr_value(item.conf, 'datalog')
                +            if type(datalog) is list:
                +                logs = datalog
                             else:
                -                logs = [item.conf['datalog']]
                +                logs = [datalog]
                 
                             found = False
                             for log in logs:
                @@ -147,7 +155,7 @@ def _dump(self):
                                             handles[filename] = open(self.path + '/' + filename, 'a')
                 
                                         data = entry
                -                        data['stamp'] = data['time'].time();
                +                        data['stamp'] = data['time'].timestamp();
                                         handles[filename].write(logpattern.format(**data))
                 
                                 except Exception as e:
                @@ -156,4 +164,4 @@ def _dump(self):
                         for filename in handles:
                             handles[filename].close()
                 
                -            self.logger.debug('Dump done!')
                \ No newline at end of file
                +            self.logger.debug('Dump done!')
                diff --git a/datalog/plugin.yaml b/datalog/plugin.yaml
                new file mode 100755
                index 000000000..32f726213
                --- /dev/null
                +++ b/datalog/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Loggen von Daten in ein anderes Logfile als das Standard Log'
                +        en: ''
                +    maintainer: ohinckel
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: DataLog              # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/jointspace/README.md b/deprecated_plugins/jointspace/README.md
                similarity index 100%
                rename from jointspace/README.md
                rename to deprecated_plugins/jointspace/README.md
                diff --git a/jointspace/__init__.py b/deprecated_plugins/jointspace/__init__.py
                similarity index 100%
                rename from jointspace/__init__.py
                rename to deprecated_plugins/jointspace/__init__.py
                diff --git a/deprecated_plugins/jointspace/plugin.yaml b/deprecated_plugins/jointspace/plugin.yaml
                new file mode 100755
                index 000000000..b07862638
                --- /dev/null
                +++ b/deprecated_plugins/jointspace/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für Philips 37PFL9604H/12 TV. Sollte mit allen Philips TVs ab 2010 funktionieren'
                +        en: ''
                +    maintainer: Foxi352
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.1.2                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Jointspace          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/dlms/__init__.py b/dlms/__init__.py
                index 307622ee3..54d75f728 100644
                --- a/dlms/__init__.py
                +++ b/dlms/__init__.py
                @@ -35,29 +35,43 @@
                 import datetime
                 
                 if __name__ == '__main__':
                +    # just needed for standalone mode
                     class SmartPlugin():
                         pass
                +    import os
                +    import sys
                +    BASE = os.path.sep.join(os.path.realpath(__file__).split(os.path.sep)[:-3])
                +    sys.path.insert(0, BASE)    
                +    from lib.utils import Utils
                 else:
                +    # just needed for plugin mode
                     from lib.model.smartplugin import SmartPlugin
                -        
                +    from lib.utils import Utils
                +
                 import time
                 import serial
                 import re
                 from threading import Semaphore
                 
                 """
                -This module implements the questioning of a smartmeter using the DLMS protocol
                -#   Character Format: (1 start bit, 7 data bits, 1 parity bit, 1 stop bit) even parity 
                -#   for protocol mode A - D
                -#   in protocol mode E 1 start bit, 8 data bits, 1 stop bit is allowed, see Annex E of IEC62056-21
                -#   but mode E is not supported and implemented
                -#   Abbreviations
                -#   COSEM   COmpanion Specification for Energy Metering
                -#   OBIS    OBject Identification System                (see iec62056-61{ed1.0}en_obis_protocol.pdf)
                +This module implements the query of a smartmeter using the DLMS protocol.
                +
                +
                +The Character Format for protocol mode A - D is defined as 1 start bit, 7 data bits, 1 parity bit, 1 stop bit and even parity 
                +In protocol mode E it is defined as 1 start bit, 8 data bits, 1 stop bit is allowed, see Annex E of IEC62056-21
                +For this plugin the protocol mode E is neither implemented nor supported.
                +
                +Abbreviations
                +-------------
                +COSEM
                +   COmpanion Specification for Energy Metering
                +
                +OBIS
                +   OBject Identification System (see iec62056-61{ed1.0}en_obis_protocol.pdf)
                 """
                 
                 class DLMS(SmartPlugin):
                -    PLUGIN_VERSION = "1.2.5"
                +    PLUGIN_VERSION = "1.2.6"
                     ALLOW_MULTIINSTANCE = False
                     """
                     This class provides a Plugin for SmarthomeNG.py which reads out a smartmeter.
                @@ -72,37 +86,37 @@ class DLMS(SmartPlugin):
                     ITEM_TAG = [
                         'dlms_obis_code',           # a single code in form of '1-1:1.8.1'
                         'dlms_obis_readout']        # complete readout from smartmeter, if you want to examine codes yourself in a logic
                -    
                +
                     def __init__(self, smarthome, serialport, baudrate="auto", update_cycle="60", instance = 0, device_address = b'', timeout = 2, use_checksum = True, reset_baudrate = True, no_waiting = False ):
                         """
                -        This function initializes the DLMS plugin
                +        Initializes the DLMS plugin
                         :param serialport: 
                         """
                         self.logger = logging.getLogger(__name__)
                         self.logger.debug("init dlms")
                -            
                +
                         self._sh = smarthome                                    # save a reference to the smarthome object
                -        self._serialport = serialport                           
                +        self._serialport = serialport
                         self._update_cycle = int(update_cycle)                  # the frequency in seconds how often the device should be accessed
                         self._instance = instance                               # the instance of the plugin for questioning multiple smartmeter
                         self._device_address = device_address                   # there is a possibility of using a named device.
                                                                                 # normally this will be empty since only one meter will be attached
                                                                                 # to one serial interface but the standard allows for it and we honor that.
                -        self.timeout = timeout  
                +        self.timeout = timeout
                         self._sema = Semaphore()                                # implement a semaphore to avoid multiple calls of the query function
                         self._min_cycle_time = 0                                # we measure the time for the value query and add some security value of 10 seconds
                -            
                +
                         self.dlms_obis_code_items = []                          # this is a list of items to be updated
                         self.dlms_obis_codes = []                               # this is a list of codes that are to be parsed
                -        
                +
                         self.dlms_obis_readout_items = []                       # this is a list of items that receive the full readout
                - 
                - 		# obsolete parameters, kept for compatability with previous versions       
                -        self._use_checksum = smarthome.string2bool(use_checksum)
                -        self._reset_baudrate = smarthome.string2bool(reset_baudrate)
                -        self._no_waiting = smarthome.string2bool(no_waiting)
                 
                -		
                + 		# obsolete parameters, kept for compatability with previous versions
                +        self._use_checksum = Utils.to_bool(use_checksum)
                +        self._reset_baudrate = Utils.to_bool(reset_baudrate)
                +        self._no_waiting = Utils.to_bool(no_waiting)
                +
                +
                         self.logger.debug("Instance {} of DLMS configured to use serialport '{}' with update cycle {} seconds".format( self._instance if self._instance else 0,self._serialport, self._update_cycle))
                         if __name__ == '__main__':
                             self.alive = True
                @@ -210,10 +224,10 @@ def _update_values_callback(self):
                         else:
                             self.logger.warning("update is alrady running, maybe it really takes very long or you should use longer "
                                                 "query interval time")
                -    
                +
                     def _query_smartmeter(self):
                         """
                -        This function will 
                +        This function will
                         1. open a serial communication line to the smartmeter
                         2. sends a request for info
                         3. parses the devices first (and maybe second) answer for capabilities of the device
                @@ -232,7 +246,7 @@ def _query_smartmeter(self):
                         Request_Message = b"/?"+self._device_address+b"!\r\n"
                 
                         # open the serial communication
                -        # about timeout: time tr between sending a request and an answer needs to be 
                +        # about timeout: time tr between sending a request and an answer needs to be
                         # 200ms < tr < 1500ms for protocol mode A or B
                         # inter character time must be smaller than 1500 ms
                         # The time between the reception of a message and the transmission of an answer is:
                @@ -276,7 +290,7 @@ def _query_smartmeter(self):
                 
                         self.logger.debug("Time to open serial port {}: {}".format(self._serialport,self.format_time(time.time()- runtime)))
                         runtime = time.time()
                -        
                +
                         try:
                             self.logger.debug("Reset input buffer from serial port '{}'".format(self._serialport))
                             dlms_serial.reset_input_buffer()    # replaced dlms_serial.flushInput()
                @@ -291,7 +305,7 @@ def _query_smartmeter(self):
                             return
                 
                         self.logger.debug("Time to send first request to smartmeter: {}".format(self.format_time(time.time()- runtime)))
                -        
                +
                         # now get first response
                         response = self._read_data_block_from_serial(dlms_serial)
                         if response is None:
                @@ -300,7 +314,7 @@ def _query_smartmeter(self):
                         self.logger.debug("Time to receive an answer: {}".format(self.format_time(time.time()- runtime)))
                         runtime = time.time()
                 
                -        # We need to examine the read response here for an echo of the _Request_Message 
                +        # We need to examine the read response here for an echo of the _Request_Message
                         # some meters answer if appropriate meter is available for answering with an echo of the request Message
                         if response == Request_Message:
                             self.logger.debug("Request Message was echoed, need to read the identification message".format(response))
                @@ -317,7 +331,7 @@ def _query_smartmeter(self):
                 
                         Identification_Message = response
                         self.logger.debug("Identification Message is {}".format(Identification_Message))
                -        
                +
                         if (len(Identification_Message) < 5):
                             self.logger.warning("malformed identification message {}".format(Identification_Message))
                             return
                @@ -327,12 +341,17 @@ def _query_smartmeter(self):
                                                 "aborting".format(Identification_Message[0]))
                             return
                 
                -        # different smartmeters allow for different protocol modes. 
                -        # the protocol mode decides whether the communication is fixed to a certain baudrate or might be speed up.
                -        # some meters do initiate a protocol by themselves with a fixed speed of 2400 baud e.g. Mode D
                +        """
                +        Different smartmeters allow for different protocol modes. 
                +        The protocol mode decides whether the communication is fixed to a certain baudrate or might be speed up.
                +        Some meters do initiate a protocol by themselves with a fixed speed of 2400 baud e.g. Mode D
                +        """
                         Protocol_Mode = 'A'
                 
                -        # always stays at the same speed, Protocol indicator can be anything except for A-I, 0-9, /, ?
                +        """
                +        The communication of the plugin always stays at the same speed, 
                +		Protocol indicator can be anything except for A-I, 0-9, /, ?
                +        """
                         Baudrates_Protocol_Mode_A = 300
                         Baudrates_Protocol_Mode_B = { 'A': 600, 'B': 1200, 'C': 2400, 'D': 4800, 'E': 9600, 'F': 19200,
                                                       'G': "reserved", 'H': "reserved", 'I': "reserved" }
                @@ -342,7 +361,7 @@ def _query_smartmeter(self):
                         # always '3' but it is always initiated by the metering device so it can't be encountered here
                         Baudrates_Protocol_Mode_D = { '3' : 2400}
                         #Baudrates_Protocol_Mode_E is the same as Mode_C
                -        
                +
                         Baudrate_identification = chr(Identification_Message[4])
                         if Baudrate_identification in Baudrates_Protocol_Mode_B:
                             NewBaudrate = Baudrates_Protocol_Mode_B[Baudrate_identification]
                @@ -358,11 +377,11 @@ def _query_smartmeter(self):
                                           "max Baudrate available is {} Bd".format(Baudrate_identification, Protocol_Mode, NewBaudrate))
                 
                         # for protocol C or E we now send an acknowledge and include the new baudrate parameter
                -        # maybe todo 
                +        # maybe todo
                         # we could implement here a baudrate that is fixed to somewhat lower speed if we need to
                         # read out a smartmeter with broken communication
                         Acknowledge = b'\x060' + Baudrate_identification.encode() + b'0\r\n'
                -        
                +
                         if Protocol_Mode == 'C':
                             # the speed change in communication is initiated from the reading device
                             time.sleep(wait_before_acknowledge)
                @@ -375,7 +394,7 @@ def _query_smartmeter(self):
                                 return
                             time.sleep(wait_after_acknowledge)
                             dlms_serial.flush()                 # replaced dlms_serial.drainOutput()
                -            dlms_serial.reset_input_buffer()    # replaced dlms_serial.flushInput()            
                +            dlms_serial.reset_input_buffer()    # replaced dlms_serial.flushInput()
                             if (NewBaudrate != InitialBaudrate):
                                 # change request to set higher baudrate
                                 dlms_serial.baudrate = NewBaudrate
                @@ -386,7 +405,7 @@ def _query_smartmeter(self):
                             self.logger.debug("Using protocol mode C, smartmeter and reader will switch to {} Baud".format(NewBaudrate))
                             time.sleep(wait_after_acknowledge)
                             dlms_serial.flush()                 # replaced dlms_serial.drainOutput()
                -            dlms_serial.reset_input_buffer()    # replaced dlms_serial.flushInput()            
                +            dlms_serial.reset_input_buffer()    # replaced dlms_serial.flushInput()
                             if (NewBaudrate != InitialBaudrate):
                                 # change request to set higher baudrate
                                 dlms_serial.baudrate = NewBaudrate
                @@ -406,29 +425,30 @@ def _query_smartmeter(self):
                         self.logger.debug("Whole communication with "
                                           "smartmeter took {}".format(self.format_time(time.time() - starttime)))
                 
                -        # data block in repsonse may be capsuled within STX and ETX to provide error checking
                -        # thus the response will contain a sequence of
                -        # STX Datablock ! CR LF ETX BCC
                -        # which means we need at least 6 characters in response where Datablock is empty
                -
                -        STX = 0x02
                -        ETX = 0x03
                -        BCC = 0x00  # Block check Character
                -
                -        if (len(response) > 5) and (response[0] == STX) or (response[-2] == ETX):
                -            # perform checks (start with STX, end with ETX, checksum match)
                -            self.logger.debug("calculating checksum over data response")
                -            checksum = 0
                -            for i in response[1:]:
                -                checksum ^= i
                -            if checksum != BCC:
                -                self.logger.warning("checksum/protocol error: response={} "
                -                                    "checksum={}".format(' '.join(hex(i) for i in response), checksum))
                -                return
                +        if self._use_checksum:
                +            # data block in repsonse may be capsuled within STX and ETX to provide error checking
                +            # thus the response will contain a sequence of
                +            # STX Datablock ! CR LF ETX BCC
                +            # which means we need at least 6 characters in response where Datablock is empty
                +
                +            STX = 0x02
                +            ETX = 0x03
                +            BCC = 0x00  # Block check Character
                +
                +            if (len(response) > 5) and (response[0] == STX) or (response[-2] == ETX):
                +                # perform checks (start with STX, end with ETX, checksum match)
                +                self.logger.debug("calculating checksum over data response")
                +                checksum = 0
                +                for i in response[1:]:
                +                    checksum ^= i
                +                if checksum != BCC:
                +                    self.logger.warning("checksum/protocol error: response={} "
                +                                        "checksum={}".format(' '.join(hex(i) for i in response), checksum))
                +                    return
                +                else:
                +                    self.logger.debug("checksum over data response was ok")
                             else:
                -                self.logger.debug("checksum over data response was ok")
                -        else:
                -            self.logger.warning("STX - ETX not found")
                +                self.logger.warning("STX - ETX not found")
                 
                         if len(response) > 5:
                             result = str(response[1:-4], 'ascii')
                @@ -446,7 +466,7 @@ def _query_smartmeter(self):
                 
                         if suggested_cycle > self._min_cycle_time:
                             self._min_cycle_time = suggested_cycle
                -           
                +
                         return result
                 
                     def _to_datetime_ZST10(self, text):
                @@ -507,7 +527,7 @@ def _to_date_D6(self, text):
                             month = int(text[2:4])
                             day = int(text[4:6])
                             return datetime.date(year,month,day)
                -            
                +
                     def _to_time_Z4(self, text):
                         """
                         this function converts a string of form "hhmm" into a datetime.time object
                @@ -524,7 +544,7 @@ def _to_time_Z4(self, text):
                             hour = int(text[0:2])
                             minute = int(text[2:4])
                             return datetime.time(hour,minute)
                -            
                +
                     def _to_time_Z6(self, text):
                         """
                         this function converts a string of form "hhmmss" into a datetime.time object
                @@ -542,7 +562,7 @@ def _to_time_Z6(self, text):
                             minute = int(text[2:4])
                             second = int(text[4:6])
                             return datetime.time(hour,minute,second)
                -            
                +
                     def _convert_value( self, v, converter = 'str'):
                         """
                         This function converts the OBIS value to a user chosen value
                @@ -553,7 +573,7 @@ def _convert_value( self, v, converter = 'str'):
                 
                         if converter == 'str' or len(converter) == 0:
                             return v
                -            
                +
                         if converter == 'float':
                             try:
                                 return float(v)
                @@ -569,42 +589,42 @@ def _convert_value( self, v, converter = 'str'):
                                 return None
                 
                         if converter == 'ZST10':
                -            if len(v) == 10 and v.isdigit(): 
                +            if len(v) == 10 and v.isdigit():
                                 # this is a date!
                                 v = self._to_datetime_ZST10(v)
                -                return v 
                +                return v
                             else:
                                 self.logger.error("Could not convert from '{}' to a Datetime".format(v))
                 
                         if converter == 'ZST12':
                -            if len(v) == 12 and v.isdigit(): 
                +            if len(v) == 12 and v.isdigit():
                                 # this is a date!
                                 v = self._to_datetime_ZST12(v)
                -                return v 
                +                return v
                             else:
                                 self.logger.error("Could not convert from '{}' to a Datetime".format(v))
                 
                         if converter == 'D6':
                -            if len(v) == 6 and v.isdigit(): 
                +            if len(v) == 6 and v.isdigit():
                                 # this is a date!
                                 v = self._to_date_D6(v)
                -                return v 
                +                return v
                             else:
                                 self.logger.error("Could not convert from '{}' to a Datetime".format(v))
                 
                         if converter == 'Z6':
                -            if len(v) == 6 and v.isdigit(): 
                +            if len(v) == 6 and v.isdigit():
                                 # this is a date!
                                 v = self._to_time_Z6(v)
                -                return v 
                +                return v
                             else:
                                 self.logger.error("Could not convert from '{}' to a Datetime".format(v))
                 
                         if converter == 'Z4':
                -            if len(v) == 4 and v.isdigit(): 
                +            if len(v) == 4 and v.isdigit():
                                 # this is a date!
                                 v = self._to_time_Z4(v)
                -                return v 
                +                return v
                             else:
                                 self.logger.error("Could not convert from '{}' to a Datetime".format(v))
                 
                @@ -622,10 +642,14 @@ def _convert_value( self, v, converter = 'str'):
                         return v
                 
                     def _update_dlms_obis_readout_items(self, textblock):
                +        """
                +        Sets all items with attribute to the full readout text given in textblock
                +        :param textblock: the result of the latest query
                +        """
                         if __name__ != '__main__':
                             for item in self.dlms_obis_readout_items:
                                 item(textblock, 'DLMS')
                -    
                +
                 
                     def _is_obis_code_wanted( self, code):
                         """
                @@ -641,7 +665,7 @@ def _is_obis_code_wanted( self, code):
                         #self.logger.debug("OBIS Code '{}' is not interesting...".format(code))
                         return False
                 
                -        
                +
                     def _update_items( self, Code, Values):
                         """
                         this function takes the OBIS Code as text and accepts a list of dictionaries with Values
                @@ -673,20 +697,22 @@ def _update_items( self, Code, Values):
                                         except KeyError as e:
                                             self.logger.warning("Key error '{}' while setting item {} for Obis Code {} to "
                                                                 "Key '{}' in '{}'".format(str(e), item, Code, Key, Values[Index]))
                -    
                +
                     def _update_values(self, readout):
                         """
                -        this function will take the readout from smart meter with one OBIS code per line, then splits up the line
                -        into OBIS code itself and all values behind that will start encapsulated in parentheses
                -        if the OBIS code was included in one of the items attributes then the values will be parsed and assigned
                -        to the corresponding item
                +        Takes the readout from smart meter with one OBIS code per line, 
                +        splits up the line into OBIS code itself and all values behind that will start encapsulated in parentheses
                +
                +        If the OBIS code was included in one of the items attributes then the values will be parsed and assigned
                +        to the corresponding item.
                +        
                         :param readout: readout from smart meter with one OBIS code per line
                         :return: nothing
                         """
                 
                         # update all items marked for a full readout
                         self._update_dlms_obis_readout_items(readout)
                -        
                +
                         for line in re.split('\r\n', readout):
                             # '!' as single OBIS code line means 'end of data'
                             if line.startswith("!"):
                @@ -698,7 +724,7 @@ def _update_values(self, readout):
                             if len(line) == 0:
                                 self.logger.error("An empty line was encountered!")
                                 break
                -                
                +
                             # Now check if we can split between values and OBIS code
                             arguments = line.split('(')
                             if len(arguments)==1:
                @@ -743,16 +769,16 @@ def _update_values(self, readout):
                     usage = """
                     Usage:
                     ----------------------------------------------------------------------------------------------------
                -    
                +
                     There are two ways to use this module:
                     1. You can use it as a plugin for SmartHomeNG
                -    2. You can use it standalone from the command line. 
                +    2. You can use it standalone from the command line.
                        This way you can test your serial link to the smartmeter and
                        sniff the output for which values you want to have in your item structure lately
                 
                        You need to give the interface to query as first parameter, e.g. /dev/dlms0
                        If you like to receive verbose information just append '-v' to the latter as well.
                -       
                +
                     """
                     logging.getLogger().setLevel( logging.DEBUG )
                     ch = logging.StreamHandler()
                @@ -764,16 +790,16 @@ def _update_values(self, readout):
                     # add the handlers to the logger
                     logging.getLogger().addHandler(ch)
                     serial_to_use = ""
                -    
                +
                     if len(sys.argv) > 1:
                         serial_to_use = sys.argv[1]
                     else:
                         print(usage)
                         exit()
                -        
                +
                     print("This is DLMS Plugin running in standalone mode")
                     print("==============================================")
                -        
                +
                     dlms_plugin = DLMS(None, serial_to_use )
                     result = dlms_plugin._query_smartmeter()
                     if result is None:
                diff --git a/dlms/plugin.yaml b/dlms/plugin.yaml
                new file mode 100644
                index 000000000..cc6445b21
                --- /dev/null
                +++ b/dlms/plugin.yaml
                @@ -0,0 +1,87 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für Smartmeter, die DLMS (Device Language Message Specification, IEC 62056-21) nutzen und OBIS codes liefern'
                +        en: 'Support for smartmeter using DLMS (Device Language Message Specification, IEC 62056-21) and delivering OBIS codes'
                +    maintainer: bmxp (JuMi2006)
                +#    tester:                        # Who tests this plugin?
                +    keywords: dlms obis smartmeter
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/DLMS-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.2.5                 # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: DLMS                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    instance: 
                +        type: foo
                +        default: 0
                +        description:
                +            de: 'Serieller Port an dem der Smartmeter angeschlossen ist'
                +            en: 'serial port at which the smartmeter is attached'
                +    serialport:
                +        type: str
                +        description:
                +            de: 'Serieller Port an dem der Smartmeter angeschlossen ist'
                +            en: 'serial port at which the smartmeter is attached'
                +    baudrate:
                +        type: int
                +        default: 0
                +        description:
                +            de: 'Baudrate bei der die Kommunikation erfolgen soll'
                +            en: 'Baudrate at which the communikation should take place'
                +    update_cycle:
                +        type: int
                +        description:
                +            de: 'Zeitlicher Abstand zwischen zwei Abfragen des Smartmeters'
                +            en: 'Time between two queries of smartmeter'
                +        default: 60
                +    device_address:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'interne Unteradresse des Smartmeters'
                +            en: 'internal subadress of smartmeter'
                +    timeout:
                +        type: int
                +        default: 2
                +        description:
                +            de: 'Timeout nach dem der Lesevorgang automatisch beendet wird'
                +            en: 'timeout for automatic abortion of readout'
                +    use_checksum: 
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Wenn gesetzt und Wahr, wird eine Prüfsumme über die ausgelesenen Daten gebildet'
                +            en: 'if true the a checksum will be calculated of the readout result'
                +    reset_baudrate: 
                +        type: bool
                +        default: True
                +        description:
                +            de: 'derzeit nicht genutzt'
                +            en: 'not used currently'
                +    no_waiting:
                +        type: bool
                +        default: False
                +        description:
                +            de: 'derzeit nicht genutzt'
                +            en: 'not used currently'
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    dlms_obis_code: 
                +        type: str
                +        description:
                +            de: 'muß noch beschrieben werden'
                +            en: 'needs some description'
                +    dlms_obis_readout: 
                +        type: str
                +        description:
                +            de: 'In Items mit diesem Attribut wird der komplette Auslesepuffer abgelegt für eigene Untersuchungen'
                +            en: 'in items with this attribut the complete readout will be set for examination with own logics'
                diff --git a/dmx/plugin.yaml b/dmx/plugin.yaml
                new file mode 100755
                index 000000000..db746a596
                --- /dev/null
                +++ b/dmx/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützt die DMX Interfaces NanoDMX und DMXking (RS-232)'
                +        en: ''
                +    maintainer: '? (mknx)'
                +#    tester: efgh                   # Who tests this plugin?
                +    keywords: dmx
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: DMX                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/drexelundweiss/plugin.yaml b/drexelundweiss/plugin.yaml
                new file mode 100755
                index 000000000..f43960bd0
                --- /dev/null
                +++ b/drexelundweiss/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützt Drexel & Weiss USB Devices'
                +        en: ''
                +    maintainer: '?'
                +    tester: onkelandy, brandst
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/34582-drexel-weiss-plugin
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: DuW                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/dwd/plugin.yaml b/dwd/plugin.yaml
                new file mode 100755
                index 000000000..426ce65f7
                --- /dev/null
                +++ b/dwd/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung des FTP Servers des Deutschen Wetterdienstes'
                +        en: ''
                +    maintainer: psilo909
                +    tester: cmalo
                +    keywords: weather
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/DWD        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/34390-dwd-plugin
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: DWD                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/easymeter/plugin.yaml b/easymeter/plugin.yaml
                new file mode 100755
                index 000000000..855e90b4d
                --- /dev/null
                +++ b/easymeter/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Easymeter Q3D Unterstützung'
                +        en: ''
                +    maintainer: '?'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: easymeter            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/ebus/plugin.yaml b/ebus/plugin.yaml
                new file mode 100755
                index 000000000..ce847fba2
                --- /dev/null
                +++ b/ebus/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützt eBus Heizungen (Vailant, Wolf, Kromschroeder)'
                +        en: ''
                +    maintainer: '?'
                +    tester: Sandman60
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: eBus                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/ecmd/plugin.yaml b/ecmd/plugin.yaml
                new file mode 100755
                index 000000000..1bcdd46e9
                --- /dev/null
                +++ b/ecmd/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung eines AVRMicrocontrollers. Das Protokoll gibt Zugriff auf 1wire Sensoren DS1820'
                +        en: ''
                +    maintainer: '? (Dirk Wallmeier)'
                +#    tester: efgh                   # Who tests this plugin?
                +    keywords: 1wire onewire
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: ECMD                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/elro/plugin.yaml b/elro/plugin.yaml
                new file mode 100755
                index 000000000..589bb4c2b
                --- /dev/null
                +++ b/elro/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützt elro-basierter Remote-Control-Switches'
                +        en: ''
                +    maintainer: '? (Brootux)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Elro                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/enigma2/__init__.py b/enigma2/__init__.py
                index 24ecc697c..a432f73a8 100644
                --- a/enigma2/__init__.py
                +++ b/enigma2/__init__.py
                @@ -124,7 +124,7 @@ class Enigma2(SmartPlugin):
                     Main class of the Plugin. Does all plugin specific stuff and provides the update functions for the Enigma2Device
                     """
                     ALLOW_MULTIINSTANCE = True
                -    PLUGIN_VERSION = "1.1.11"
                +    PLUGIN_VERSION = "1.4.11"
                 
                     _url_suffix_map = dict([('about', '/web/about'),
                                             ('deviceinfo', '/web/deviceinfo'),
                @@ -183,8 +183,10 @@ def run(self):
                         """
                         Run method for the plugin
                         """
                -        self._sh.scheduler.add(__name__, self._update_loop, cycle=self._cycle)
                -        self._sh.scheduler.add(__name__ + "_fast", self._update_loop_fast, cycle=self._fast_cycle)
                +#        self._sh.scheduler.add(__name__, self._update_loop, cycle=self._cycle)
                +#        self._sh.scheduler.add(__name__ + "_fast", self._update_loop_fast, cycle=self._fast_cycle)
                +        self.scheduler_add('update', self._update_loop, cycle=self._cycle)
                +        self.scheduler_add('update_fast', self._update_loop_fast, cycle=self._fast_cycle)
                         self.alive = True
                 
                     def stop(self):
                diff --git a/enigma2/plugin.yaml b/enigma2/plugin.yaml
                new file mode 100755
                index 000000000..61f1efdb1
                --- /dev/null
                +++ b/enigma2/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Plugin zur Einbindung von Enigma2 kompatiblen Sat-Receivern mit openwebif'
                +        en: ''
                +    maintainer: psilo909
                +    tester: Sandman60, cmalo
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/943871-enigma2-plugin
                +
                +    version: 1.4.11                # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Enigma2             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/enigma2/sv_widgets/widget_enigma2.html b/enigma2/sv_widgets/widget_enigma2.html
                index bf0ef2603..793be5e4f 100755
                --- a/enigma2/sv_widgets/widget_enigma2.html
                +++ b/enigma2/sv_widgets/widget_enigma2.html
                @@ -1,3 +1,9 @@
                +<?php
                +define ('const_path_system', dirname(__FILE__).'/');
                +define ('const_path', substr(const_path_system, 0, -4));
                +require_once const_path.'version-info.php';
                +?>
                +
                 /**
                  * Enigma2 ConfigurationInfo Widget
                  * 
                @@ -35,6 +41,7 @@
                 {% endmacro %}
                 
                 
                +
                 /**
                  * Enigma2 ConfigurationInfo Widget (for standardconfiguration)
                  *
                @@ -133,6 +140,35 @@
                 {% endmacro %}
                 
                 
                +/**
                + * Enigma2 StatusInfo Widget (only channel and program)
                + *
                + * This widget can be used, if the items for the enigma2 box are defined  
                + * following the naming conventions as defined in the README of the plugin
                + * 
                + * @param       unique id for this widget 
                + * @param       the gad/item for the receiver (parent item of the enigma2 item definition tree)
                + *
                + */
                +
                +{% macro status_channel(id, gad_box) %}
                +	{% import "basic.html" as basic %}
                +	{% set uid = uid(page, id) %}
                +
                +	<div id="{{ uid }}">
                +		<table width=90%> 
                +			<tr><td align=left style="padding-left: 15px;">Sender:</td> <td align=right> {{ basic.value(id~'2servicename', gad_box~'.current.servicename') }} </td></tr>
                +			<tr><td align=left style="padding-left: 15px;"><strong>Sendung</strong></td></tr>
                +			<tr><td colspan="2" align=left style="padding-left: 30px;"> {{ basic.value(id~'2eventtitle', gad_box~'.current.eventtitle') }} </td></tr>
                +			<tr><td colspan="2" align=left style="padding-left: 30px;"> {{ basic.value(id~'2eventdesc', gad_box~'.current.eventdescription') }} </td></tr>
                +		</table>
                +
                +	</div>
                +
                +{% endmacro %}
                +
                +
                +
                 /**
                  * Enigma2 Remote Widget
                  * 
                @@ -145,6 +181,12 @@
                 	{% import "basic.html" as basic %}
                 	{% set uid = uid(page, id) %}
                 	
                +	{% if config_version == 2.9 %}
                +        {% set icon_path = '' %}
                +	{% else %}
                +        {% set icon_path = 'widgets/sh_widgets/' %}
                +	{% endif %}
                +
                 	<div id="{{ uid }}">
                 		<table width="100%">
                 			<tr>
                @@ -240,13 +282,13 @@
                 			<tr>
                 				<td align="middle" width="70%">
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.GREEN', gad_boxremote~'.GREEN', ' Green ', 'widgets/sh_widgets/control_centr_arrow_up_left_green_fill.png', '', gad_size) }}
                +					 {{ basic.button(id~'.GREEN', gad_boxremote~'.GREEN', ' Green ', icon_path~'control_centr_arrow_up_left_green_fill.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                 					{{ basic.button(id~'.UpTV', gad_boxremote~'.UP', 'rauf', icon0~'control_centr_arrow_up.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.YELLOW', gad_boxremote~'.YELLOW', ' Yellow ', 'widgets/sh_widgets/control_centr_arrow_up_right_yellow_fill.png', '', gad_size) }}
                +					 {{ basic.button(id~'.YELLOW', gad_boxremote~'.YELLOW', ' Yellow ', icon_path~'control_centr_arrow_up_right_yellow_fill.png', '', gad_size) }}
                 					</span>
                 				</td>
                 			</tr>
                @@ -306,13 +348,13 @@
                 			<tr>
                 				<td align="middle" width="70%">
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.RED', gad_boxremote~'.RED', 'Red', 'widgets/sh_widgets/control_centr_arrow_down_left_red_fill.png', '', gad_size) }}
                +					 {{ basic.button(id~'.RED', gad_boxremote~'.RED', 'Red', icon_path~'control_centr_arrow_down_left_red_fill.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                 					{{ basic.button(id~'.DOWN', gad_boxremote~'.DOWN', 'runter', icon0~'control_centr_arrow_down.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.BLUE', gad_boxremote~'.BLUE', ' Blue ', 'widgets/sh_widgets/control_centr_arrow_down_right_blue_fill.png', '', gad_size) }}
                +					 {{ basic.button(id~'.BLUE', gad_boxremote~'.BLUE', ' Blue ', icon_path~'control_centr_arrow_down_right_blue_fill.png', '', gad_size) }}
                 					</span>
                 				</td>
                 			</tr>
                @@ -355,16 +397,16 @@
                 			  <td align="middle" width="70%">
                 				<span data-role="controlgroup" data-type="horizontal">
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.RED', gad_boxremote~'.RED', 'Red', 'widgets/sh_widgets/circle_red.png', '', gad_size) }}
                +					 {{ basic.button(id~'.RED', gad_boxremote~'.RED', 'Red', icon_path~'circle_red.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.GREEN', gad_boxremote~'.GREEN', ' Green ', 'widgets/sh_widgets/circle_green2.png', '', gad_size) }}
                +					 {{ basic.button(id~'.GREEN', gad_boxremote~'.GREEN', ' Green ', icon_path~'circle_green2.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.YELLOW', gad_boxremote~'.YELLOW', ' Yellow ', 'widgets/sh_widgets/circle_yellow.png', '', gad_size) }}
                +					 {{ basic.button(id~'.YELLOW', gad_boxremote~'.YELLOW', ' Yellow ', icon_path~'circle_yellow.png', '', gad_size) }}
                 					</span>
                 					<span data-role="controlgroup" data-type="horizontal">
                -					 {{ basic.button(id~'.BLUE', gad_boxremote~'.BLUE', ' Blue ', 'widgets/sh_widgets/circle_blue.png', '', gad_size) }}
                +					 {{ basic.button(id~'.BLUE', gad_boxremote~'.BLUE', ' Blue ', icon_path~'circle_blue.png', '', gad_size) }}
                 					</span>
                 				</span>
                 			  </td>
                diff --git a/enocean/README.md b/enocean/README.md
                index 435cdcd38..d5680b418 100644
                --- a/enocean/README.md
                +++ b/enocean/README.md
                @@ -28,11 +28,11 @@ With the specification of the BaseID, 128 different transmit IDs are available,
                 
                 ### Getting ID of an EnOcean device
                 
                -1.) reboot the pi or restart the smarthome (sudo reboot; sudo systemctl restart smarthome)
                -2.) wait some time for comming up of the service
                -3.) have a look into the log file an look for ``enocean: Base ID = 0xYYYYZZZZ``
                -4.) now you have the right BaseID and you can place it into the plugin.conf-first
                -5.) alternating you will also find the ChipID in the log-file
                +1. reboot the pi or restart the smarthome (sudo reboot; sudo systemctl restart smarthome)
                +2. wait some time for comming up of the service
                +3. have a look into the log file an look for ``enocean: Base ID = 0xYYYYZZZZ``
                +4. now you have the right BaseID and you can place it into the plugin.conf-first
                +5. alternating you will also find the ChipID in the log-file
                 
                 The following example is for a rocker/switch with two rocker (EEP F6_02_01 or F6_02_02).
                 
                @@ -71,12 +71,14 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                         enocean_rx_id = 0180924D
                         enocean_rx_eep = A5_02_05
                         enocean_rx_key = TMP
                +    
                     [[Door]]
                         enocean_rx_id = 01234567
                         enocean_rx_eep = D5_00_01
                         [[[status]]]
                             type = bool
                             enocean_rx_key = STATUS
                +    
                     [[FT55switch]]
                         enocean_rx_id = 012345AA
                         enocean_rx_eep = F6_02_03
                @@ -86,6 +88,17 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                             [[[down]]]
                                 type = bool
                                 enocean_rx_key = BI
                +    
                +    [[Brightness_Sensor]]
                +        name = brightness_sensor_east
                +        remark = Eltako FAH60
                +        type = num
                +        enocean_rx_id = 01A51DE6
                +        enocean_rx_eep = A5_06_01
                +        enocean_rx_key = BRI
                +        visu_acl = rw
                +        sqlite = yes
                +    
                     [[dimmer1]]
                         enocean_rx_id = 00112233
                         enocean_rx_eep = A5_11_04
                @@ -100,18 +113,21 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                                 enocean_tx_eep = A5_38_08_03
                                 enocean_tx_id_offset = 1
                                 ref_level = 80
                +    
                     [[handle]]
                         enocean_rx_id = 01234567
                         enocean_rx_eep = F6_10_00
                         [[[status]]]
                             type = num
                             enocean_rx_key = STATUS
                +    
                     [[actor1]]
                         enocean_rx_id = FFAABBCC
                         enocean_rx_eep = A5_12_01
                         [[[power]]]
                             type = num
                             enocean_rx_key = VALUE
                +    
                     [[actor1B]]
                         enocean_rx_id = FFAABBCD
                         enocean_rx_eep = F6_02_03
                @@ -120,6 +136,32 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                             enocean_rx_key = B
                             enocean_tx_eep = A5_38_08_01
                             enocean_tx_id_offset = 2
                +    
                +    [[actorD2]]
                +        enocean_rx_id = FFDB7381
                +        enocean_rx_eep = D2_01_07
                +        [[[move]]]
                +            type=bool
                +            enocean_rx_key = STAT
                +            enocean_tx_eep = D2_01_07
                +            enocean_pulsewidth = 0.1  // optional; turn off after 0.1 sed
                +            enocean_tx_id_offset = 1  
                +    
                +    [[awning]]
                +        enocean_rx_id = 0500E508
                +        enocean_rx_eep = F6_02_03
                +        [[[move]]]
                +            enocean_tx_eep = A5_3F_7F
                +            enocean_rtime = 60  // move awning for 60sec
                +            type = num
                +            visu = yes
                +        [[[stat]]]
                +            enocean_rx_key = B
                +            enforce_updates = on
                +            cache = on
                +            type = bool
                +            visu = yes
                +    
                     [[rocker]]
                         enocean_rx_id = 0029894A
                         enocean_rx_eep = F6_02_01
                @@ -145,6 +187,7 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                             enocean_rocker_sequence = **released within 0.4, pressed within 0.4**
                             knx_dpt = 1
                             knx_send = 3/0/62
                +    
                     [[brightness_sensor]]
                         enocean_rx_id = 01234567
                         enocean_rx_eep = A5_08_01
                @@ -154,6 +197,7 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                         [[[movement]]]
                             type = bool
                             enocean_rx_key = MOV
                +    
                     [[temperature_sensor]]
                         enocean_rx_id = 01234567
                         enocean_rx_eep = A5_04_02
                @@ -166,6 +210,190 @@ An Enocean item must specify at minimum an ``enocean_rx_id`` (Enocean Identifica
                         [[[power_status]]]
                             type = num
                             enocean_rx_key = ENG
                +    
                +    [[sunblind]]
                +        enocean_rx_id = 0500xxxx
                +        enocean_rx_eep = F6_02_03
                +        [[[move]]]
                +            enocean_tx_eep = A5_3F_7F
                +            enocean_rtime = 60
                +            type = num
                +        [[[status]]]
                +            name = blind retrated
                +            enocean_rx_key = B
                +            enforce_updates = on
                +            cache = on
                +            type = bool
                +```
                +
                +#### Example item.yaml
                +
                +```
                +Enocean_Item:
                +    Outside_Temperature:
                +        type: num
                +        enocean_rx_id: 0180924D
                +        enocean_rx_eep: A5_02_05
                +        enocean_rx_key: TMP
                +    
                +    Door:
                +        enocean_rx_id: 01234567
                +        enocean_rx_eep: D5_00_01
                +        status:
                +            type: bool
                +            enocean_rx_key: STATUS
                +    
                +    FT55switch
                +        enocean_rx_id: 012345AA
                +        enocean_rx_eep: F6_02_03
                +            up:
                +                type: bool
                +                enocean_rx_key: BO
                +            down:
                +                type: bool
                +                enocean_rx_key: BI
                +    
                +    Brightness_Sensor:
                +                name: brightness_sensor_east
                +                remark: Eltako FAH60
                +                type: num
                +                enocean_rx_id: 01A51DE6
                +                enocean_rx_eep: A5_06_01
                +                enocean_rx_key: BRI
                +                visu_acl: rw
                +                sqlite: 'yes'
                +    
                +    dimmer1:
                +        enocean_rx_id: 00112233
                +        enocean_rx_eep: A5_11_04
                +        light:
                +            type: bool
                +            enocean_rx_key: STAT
                +            enocean_tx_eep: A5_38_08_02
                +            enocean_tx_id_offset: 1
                +            level:
                +                type: num
                +                enocean_rx_key: D
                +                enocean_tx_eep: A5_38_08_03
                +                enocean_tx_id_offset: 1
                +                ref_level: 80
                +    
                +    handle:
                +        enocean_rx_id: 01234567
                +        enocean_rx_eep: F6_10_00
                +        status:
                +            type: num
                +            enocean_rx_key: STATUS
                +    
                +    actor1:
                +        enocean_rx_id: FFAABBCC
                +        enocean_rx_eep: A5_12_01
                +        power:
                +            type: num
                +            enocean_rx_key: VALUE
                +    
                +    actor1B:
                +        enocean_rx_id: FFAABBCD
                +        enocean_rx_eep: F6_02_03
                +        light:
                +            type: bool
                +            enocean_rx_key: B
                +            enocean_tx_eep: A5_38_08_01
                +            enocean_tx_id_offset: 2
                +    
                +    actorD2:
                +        enocean_rx_id: FFDB7381
                +        enocean_rx_eep: D2_01_07
                +        move:
                +            type=bool
                +            enocean_rx_key: STAT
                +            enocean_tx_eep: D2_01_07
                +            enocean_pulsewidth: 0.1  // optional; turn off after 0.1 sed
                +            enocean_tx_id_offset: 1  
                +    
                +    awning:
                +        enocean_rx_id: 0500E508
                +        enocean_rx_eep: F6_02_03
                +        move:
                +            enocean_tx_eep: A5_3F_7F
                +            enocean_rtime: 60  // move awning for 60sec
                +            type: num
                +            visu: yes
                +        
                +        stat:
                +            enocean_rx_key: B
                +            enforce_updates: on
                +            cache: on
                +            type: bool
                +            visu: yes
                +    
                +    rocker:
                +        enocean_rx_id: 0029894A
                +        enocean_rx_eep: F6_02_01
                +        short_800ms_directly_to_knx:
                +            type: bool
                +            enocean_rx_key: AI
                +            enocean_rocker_action: **toggle**
                +            enocean_rocker_sequence: released **within** 0.8
                +            knx_dpt: 1
                +            knx_send: 3/0/60
                +        
                +        long_800ms_directly_to_knx:
                +            type: bool
                +            enocean_rx_key: AI
                +            enocean_rocker_action: toggle
                +            enocean_rocker_sequence: released **after** 0.8
                +            knx_dpt: 1
                +            knx_send: 3/0/61
                +        
                +        rocker_double_800ms_to_knx_send_1:
                +            type: bool
                +            enforce_updates: true
                +            enocean_rx_key: AI
                +            enocean_rocker_action: **set**
                +            enocean_rocker_sequence: **released within 0.4, pressed within 0.4**
                +            knx_dpt: 1
                +            knx_send: 3/0/62
                +    
                +    brightness_sensor:
                +        enocean_rx_id: 01234567
                +        enocean_rx_eep: A5_08_01
                +        lux:
                +            type: num
                +            enocean_rx_key: BRI
                +        
                +        movement:
                +            type: bool
                +            enocean_rx_key: MOV
                +    
                +    temperature_sensor:
                +        enocean_rx_id: 01234567
                +        enocean_rx_eep: A5_04_02
                +        temperature:
                +            type: num
                +            enocean_rx_key: TMP
                +        
                +        humidity:
                +            type: num
                +            enocean_rx_key: HUM
                +        
                +        power_status:
                +            type: num
                +            enocean_rx_key: ENG
                +    sunblind:
                +        enocean_rx_id: 0500xxxx
                +        enocean_rx_eep: F6_02_03
                +        move:
                +            enocean_tx_eep: A5_3F_7F
                +            enocean_rtime: 60
                +            type: num
                +        
                +        status:
                +            name: blind retrated
                +            enocean_rx_key: B
                +            enforce_updates: on
                +            cache: on
                +            type: bool
                 ```
                 
                 ### Add new listening enocean devices
                @@ -178,17 +406,18 @@ The following status EEPs are supported:
                 ```
                 * A5_02_01 - A5_02_0B	Temperature Sensors (40°C overall range, various starting offsets, 1/6°C resolution)
                 * A5_02_10 - A5_02_1B	Temperature Sensors (80°C overall range, various starting offsets, 1/3°C resolution)
                -* A5_02_20		                High Precision Temperature Sensor (ranges -10*C to +41.2°C, 1/20°C resolution)
                -* A5_02_30				High Precision Temperature Sensor (ranges -40*C to +62.3°C, 1/10°C resolution)
                -* A5_04_02				Energy (optional), humidity and temperature sensor
                -* A5_08_01				Brightness and movement sensor
                -* A5_11_04				Dimmer status feedback
                -* A5_12_01				Power Measurement
                -* D5_00_01				Door/Window Contact, e.g. Eltako FTK, FTKB
                -* F6_02_01				2-Button-Rocker
                -* F6_02_02				2-Button-Rocker
                -* F6_02_03				2-Button-Rocker, Status feedback from manual buttons on different actors, e.g. Eltako FT55, FSUD-230, FSVA-230V or Gira switches.
                -* F6_10_00				Mechanical Handle (value: 0(closed), 1(open), 2(tilted)
                +* A5_02_20		High Precision Temperature Sensor (ranges -10*C to +41.2°C, 1/20°C resolution)
                +* A5_02_30		High Precision Temperature Sensor (ranges -40*C to +62.3°C, 1/10°C resolution)
                +* A5_04_02		Energy (optional), humidity and temperature sensor
                +* A5_08_01		Brightness and movement sensor
                +* A5_11_04		Dimmer status feedback
                +* A5_12_01		Power Measurement
                +* D2_01_07		Simple electronic switch
                +* D5_00_01		Door/Window Contact, e.g. Eltako FTK, FTKB
                +* F6_02_01		2-Button-Rocker
                +* F6_02_02		2-Button-Rocker
                +* F6_02_03		2-Button-Rocker, Status feedback from manual buttons on different actors, e.g. Eltako FT55, FSUD-230, FSVA-230V, FSB61NP-230V or Gira switches.
                +* F6_10_00		Mechanical Handle (value: 0(closed), 1(open), 2(tilted)
                 ```
                 A complete list of available EEPs is documented at [EnOcean Alliance](http://www.enocean-alliance.org/eep/)
                 
                @@ -196,10 +425,11 @@ A complete list of available EEPs is documented at [EnOcean Alliance](http://www
                 ### Send commands: Tx EEPs
                 
                 ```
                -* A5_38_08_01			Regular switch actor command (on/off)
                -* A5_38_08_02			Dimmer command with fix on off command (on: 100, off:0)
                -* A5_38_08_03			Dimmer command with specified dim level (0-100)
                -* A5_3F_7F			Universal actuator command 
                +* A5_38_08_01		Regular switch actor command (on/off)
                +* A5_38_08_02		Dimmer command with fix on off command (on: 100, off:0)
                +* A5_38_08_03		Dimmer command with specified dim level (0-100)
                +* A5_3F_7F		Universal actuator command, e.g. blind control
                +* D2_01_07		Simple electronic switch
                 ```
                 
                 The optional ref_level parameter defines default dim value when dimmer is switched on via on command.
                @@ -217,17 +447,28 @@ cd /usr/local/smarthome/bin
                 sudo systemctl stop smarthome
                 sudo ./smarthome.py -i
                 ```
                -	
                -Then use one of the following learn-in command methods, depending on your enocean device:
                 
                +Then use one of the following learn-in commands, depending on your enocean device:
                +
                +```python
                +sh.enocean.send_learn_protocol(id_offset, device)
                +```
                +With device are different actuators defined:
                +
                +- 10: Eltako Switch FSR61
                +- 20: Eltako FSUD-230V
                +- 21: Eltako FHK61SSR dim device (EEP A5-38-08)
                +- 22: Eltako FRGBW71L RGB dim devices (EEP 07-3F-7F)
                +- 30: Radiator Valve
                +- 40: Eltako shutter actors FSB61NP-230V, FSB14, FSB61, FSB71
                +
                +Examples are:
                 ```python
                -sh.enocean.send_learn_dim(ID_Offset)
                -sh.enocean.send_learn_rgbw_dim(ID_Offset)
                -sh.enocean.send_learn_switch(ID_Offset)
                -sh.enocean.send_learn_actuator(ID_Offset) , e.g. for Eltako FSB61NP-230V 
                +sh.enocean.send_learn_protocol() or sh.enocean.send_learn_protocol(0,10)
                +sh.enocean.send_learn_protocol(id_offset,20)
                 ```
                 
                -where ID_Offset, range (0-127), specifies the sending ID offset with respect to the BaseID.
                +Where id_offset, range (0-127), specifies the sending ID offset with respect to the BaseID.
                 Later, the ID offset is specified in the <item.conf> for every outgoing send command, see example below.
                 
                 Use different ID offsets for different groups of actors.
                @@ -241,4 +482,4 @@ When activated on Enocean device the device will send a ``D4`` teach in request.
                 To do so enable the UTE learnmode prior to the activation on the device: Start smarthome with the interactive console - see above. ``sh.enocean.start_UTE_learnmode(ID_Offset)``
                 The device will be teached in and the learn mode will be ended automatically
                 
                -Docu v 1.4a
                +Docu v 1.5
                diff --git a/enocean/__init__.py b/enocean/__init__.py
                index c09a206ed..08cb9a2bb 100644
                --- a/enocean/__init__.py
                +++ b/enocean/__init__.py
                @@ -1,772 +1,854 @@
                -#!/usr/bin/env python3
                -# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                -#########################################################################
                -#  Copyright 2013-2014 Robert Budde                   robert@ing-budde.de
                -#  Copyright 2014 Alexander Schwithal                 aschwith
                -#########################################################################
                -#  Enocean plugin for SmartHomeNG.      https://github.com/smarthomeNG//
                -#
                -#  This plugin is free software: you can redistribute it and/or modify
                -#  it under the terms of the GNU General Public License as published by
                -#  the Free Software Foundation, either version 3 of the License, or
                -#  (at your option) any later version.
                -#
                -#  This plugin is distributed in the hope that it will be useful,
                -#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                -#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                -#  GNU General Public License for more details.
                -#
                -#  You should have received a copy of the GNU General Public License
                -#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                -#########################################################################
                -
                -import serial
                -import os
                -import sys
                -import logging
                -import struct
                -import time
                -import threading
                -from . import eep_parser
                -from lib.model.smartplugin import SmartPlugin
                -
                -FCSTAB = [
                -    0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
                -    0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
                -    0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
                -    0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
                -    0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
                -    0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
                -    0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
                -    0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
                -    0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
                -    0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
                -    0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
                -    0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
                -    0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
                -    0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
                -    0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
                -    0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
                -    0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
                -    0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
                -    0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
                -    0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
                -    0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
                -    0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
                -    0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
                -    0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
                -    0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
                -    0x76, 0x71, 0x78, 0x7f, 0x6A, 0x6d, 0x64, 0x63,
                -    0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
                -    0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
                -    0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
                -    0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8D, 0x84, 0x83,
                -    0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
                -    0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
                -    ]
                -
                -################################
                -### --- Packet Sync Byte --- ###
                -################################
                -PACKET_SYNC_BYTE              = 0x55   # PACKET SYNC BYTE
                -
                -
                -############################
                -### --- Packet Types --- ###
                -############################
                -
                -PACKET_TYPE_RADIO             = 0x01   # RADIO ERP1
                -PACKET_TYPE_RESPONSE          = 0x02   # RESPONSE
                -PACKET_TYPE_RADIO_SUB_TEL     = 0x03   # RADIO_SUB_TEL
                -PACKET_TYPE_EVENT             = 0x04   # EVENT
                -PACKET_TYPE_COMMON_COMMAND    = 0x05   # COMMON COMMAND
                -PACKET_TYPE_SMART_ACK_COMMAND = 0x06   # SMART ACK COMMAND
                -PACKET_REMOTE_MAN_COMMAND     = 0x07   # REMOTE MANAGEMENT COMMAND
                -PACKET_TYPE_RADIO_MESSAGE     = 0x09   # RADIO MESSAGE
                -PACKET_TYPE_RADIO_ERP2        = 0x0A   # RADIO ERP2
                -PACKET_TYPE_RADIO_802_15_4    = 0x10   # RADIO_802_15_4
                -PACKET_TYPE_COMMAND_2_4       = 0x11   # COMMAND_2_4
                -
                -
                -############################################
                -### --- List of Common Command Codes --- ###
                -############################################
                -
                -CO_WR_SLEEP                     = 0x01     # Order to enter in energy saving mode
                -CO_WR_RESET                     = 0x02     # Order to reset the device
                -CO_RD_VERSION                   = 0x03     # Read the device (SW) version /(HW) version, chip ID etc.
                -CO_RD_SYS_LOG                   = 0x04     # Read system log from device databank
                -CO_WR_SYS_LOG                   = 0x05     # Reset System log from device databank
                -CO_WR_BIST                      = 0x06     # Perform built in self test
                -CO_WR_IDBASE                    = 0x07     # Write ID range base number
                -CO_RD_IDBASE                    = 0x08     # Read ID range base number
                -CO_WR_REPEATER                  = 0x09     # Write Repeater Level off,1,2
                -CO_RD_REPEATER                  = 0x0A     # Read Repeater Level off,1,2
                -CO_WR_FILTER_ADD                = 0x0B     # Add filter to filter list
                -CO_WR_FILTER_DEL                = 0x0C     # Delete filter from filter list
                -CO_WR_FILTER_DEL_ALL            = 0x0D     # Delete all filter
                -CO_WR_FILTER_ENABLE             = 0x0E     # Enable/Disable supplied filters
                -CO_RD_FILTER                    = 0x0F     # Read supplied filters
                -CO_WR_WAIT_MATURITY             = 0x10     # Waiting till end of maturity time before received radio telegrams will transmitted
                -CO_WR_SUBTEL                    = 0x11     # Enable/Disable transmitting additional subtelegram info
                -CO_WR_MEM                       = 0x12     # Write x bytes of the Flash, XRAM, RAM0 …
                -CO_RD_MEM                       = 0x13     # Read x bytes of the Flash, XRAM, RAM0 ….
                -CO_RD_MEM_ADDRESS               = 0x14     # Feedback about the used address and length of the configarea and the Smart Ack Table
                -CO_RD_SECURITY                  = 0x15     # Read own security information (level, key)
                -CO_WR_SECURITY                  = 0x16     # Write own security information (level, key)
                -CO_WR_LEARNMODE                 = 0x17     # Function: Enables or disables learn mode of Controller.
                -CO_RD_LEARNMODE                 = 0x18     # Function: Reads the learn-mode state of Controller.
                -CO_WR_SECUREDEVICE_ADD          = 0x19     # Add a secure device
                -CO_WR_SECUREDEVICE_DEL          = 0x1A     # Delete a secure device
                -CO_RD_SECUREDEVICE_BY_INDEX     = 0x1B     # Read secure device by index
                -CO_WR_MODE                      = 0x1C     # Sets the gateway transceiver mode
                -CO_RD_NUMSECUREDEVICES          = 0x1D     # Read number of taught in secure devices
                -CO_RD_SECUREDEVICE_BY_ID        = 0x1E     # Read secure device by ID
                -CO_WR_SECUREDEVICE_ADD_PSK      = 0x1F     # Add Pre-shared key for inbound secure device
                -CO_WR_SECUREDEVICE_SENDTEACHIN  = 0x20     # Send secure Teach-In message
                -CO_WR_TEMPORARY_RLC_WINDOW      = 0x21     # Set the temporary rolling-code window for every taught-in devic
                -CO_RD_SECUREDEVICE_PSK          = 0x22     # Read PSK
                -CO_RD_DUTYCYCLE_LIMIT           = 0x23     # Read parameters of actual duty cycle limit
                -CO_SET_BAUDRATE                 = 0x24     # Modifies the baud rate of the EnOcean device
                -CO_GET_FREQUENCY_INFO           = 0x25     # Reads Frequency and protocol of the Device
                -CO_GET_STEPCODE                 = 0x27     # Reads Hardware Step code and Revision of the Device
                -
                -
                -###################################
                -### --- List of Event Codes --- ###
                -###################################
                -
                -SA_RECLAIM_NOT_SUCCESSFUL  = 0x01      # Informs the backbone of a Smart Ack Client to not successful reclaim.
                -SA_CONFIRM_LEARN           = 0x02      # Used for SMACK to confirm/discard learn in/out
                -SA_LEARN_ACK               = 0x03      # Inform backbone about result of learn request
                -CO_READY                   = 0x04      # Inform backbone about the readiness for operation
                -CO_EVENT_SECUREDEVICES     = 0x05      # Informs about a secure device
                -CO_DUTYCYCLE_LIMIT         = 0x06      # Informs about duty cycle limit
                -CO_TRANSMIT_FAILED         = 0x07      # Informs that the device was not able to send a telegram.
                -
                -
                -###########################################
                -###  --- Smart Acknowledge Defines: --- ###
                -###########################################
                -
                -SA_WR_LEARNMODE        = 0x01          # Set/Reset Smart Ack learn mode
                -SA_RD_LEARNMODE        = 0x02          # Get Smart Ack learn mode state
                -SA_WR_LEARNCONFIRM     = 0x03          # Used for Smart Ack to add or delete a mailbox of a client
                -SA_WR_CLIENTLEARNRQ    = 0x04          # Send Smart Ack Learn request (Client)
                -SA_WR_RESET            = 0x05          # Send reset command to a Smart Ack client
                -SA_RD_LEARNEDCLIENTS   = 0x06          # Get Smart Ack learned sensors / mailboxes
                -SA_WR_RECLAIMS         = 0x07          # Set number of reclaim attempts
                -SA_WR_POSTMASTER       = 0x08          # Activate/Deactivate Post master functionality
                -
                -SENT_RADIO_PACKET              = 0xFF
                -SENT_ENCAPSULATED_RADIO_PACKET = 0xA6
                -
                -class EnOcean(SmartPlugin):
                -    PLUGIN_VERSION = "1.3.3"
                -    ALLOW_MULTIINSTANCE = False
                -    
                -    def __init__(self, smarthome, serialport, tx_id=''):
                -        self._sh = smarthome
                -        self.port = serialport
                -        self.logger = logging.getLogger(__name__)
                -        if (len(tx_id) < 8):
                -            self.tx_id = 0
                -            self.logger.warning('enocean: No valid enocean stick ID configured. Transmitting is not supported')
                -        else:
                -            self.tx_id = int(tx_id, 16)
                -            self.logger.info('enocean: Stick TX ID configured via plugin.conf to: {0}'.format(tx_id))
                -        self._tcm = serial.Serial(serialport, 57600, timeout=0.5)
                -        self._cmd_lock = threading.Lock()
                -        self._response_lock = threading.Condition()
                -        self._rx_items = {}
                -        self._block_ext_out_msg = False
                -        self.eep_parser = eep_parser.EEP_Parser()
                -
                -    def eval_telegram(self, sender_id, data, opt):
                -        for item in self._items:
                -            # validate id for item id:
                -            if item.conf['enocean_id'] == sender_id:
                -                #print ("validated {0} for {1}".format(sender_id,item))
                -                #print ("try to get value for: {0} and {1}".format(item.conf['enocean_rorg'][0],item.conf['enocean_rorg'][1]))
                -                rorg = item.conf['enocean_rorg']
                -                eval_value = item.conf['enocean_value']
                -                if rorg in RADIO_PAYLOAD_VALUE:  # check if RORG exists
                -                    pl = eval(RADIO_PAYLOAD_VALUE[rorg]['payload_idx'])
                -                    #could be nicer
                -                    for entity in RADIO_PAYLOAD_VALUE:
                -                        if (rorg == entity) and (eval_value in RADIO_PAYLOAD_VALUE[rorg]['entities']):
                -                            value_dict = RADIO_PAYLOAD_VALUE[rorg]['entities']
                -                            value = eval(RADIO_PAYLOAD_VALUE[rorg]['entities'][eval_value])
                -                            self.logger.debug("Resulting value: {0} for {1}".format(value, item))
                -                            if value:  # not sure about this
                -                                item(value, 'EnOcean', 'RADIO')
                -
                -    def _process_packet_type_event(self, data, optional):
                -        event_code = data[0]
                -        if(event_code == SA_RECLAIM_NOT_SUCCESSFUL):
                -            self.logger.error("enocean: SA reclaim was not successful")
                -        elif(event_code == SA_CONFIRM_LEARN):
                -            self.logger.info("enocean: Requesting how to handle confirm/discard learn in/out")
                -        elif(event_code == SA_LEARN_ACK):
                -            self.logger.info("enocean: SA lern acknowledged")
                -        elif(event_code == CO_READY):
                -            self.logger.info("enocean: Controller is ready for operation")
                -        elif(event_code == CO_TRANSMIT_FAILED):
                -            self.logger.error("enocean: Telegram transmission failed")
                -        elif(event_code == CO_DUTYCYCLE_LIMIT):
                -            self.logger.warning("enocean: Duty cycle limit reached")
                -        elif(event_code == CO_EVENT_SECUREDEVICES):
                -            self.logger.info("enocean: secure device event packet received")
                -        else:
                -            self.logger.warning("enocean: unknown event packet received")
                -
                -    def _rocker_sequence(self, item, sender_id, sequence):
                -        try:
                -            for step in sequence:
                -                event, relation, delay = step.split()             
                -                #self.logger.debug("waiting for {} {} {}".format(event, relation, delay))
                -                if item._enocean_rs_events[event.upper()].wait(float(delay)) != (relation.upper() == "WITHIN"):
                -                    self.logger.debug("NOT {} - aborting sequence!".format(step))
                -                    return
                -                else:
                -                    self.logger.debug("{}".format(step))
                -                    item._enocean_rs_events[event.upper()].clear()
                -                    continue          
                -            value = True
                -            if 'enocean_rocker_action' in item.conf:
                -                if item.conf['enocean_rocker_action'].upper() == "UNSET":
                -                    value = False
                -                elif item.conf['enocean_rocker_action'].upper() == "TOGGLE":
                -                    value = not item()
                -            item(value, 'EnOcean', "{:08X}".format(sender_id))
                -        except Exception as e:
                -            self.logger.error("enocean: error handling enocean_rocker_sequence \"{}\" - {}".format(sequence, e))        
                -
                -    def _process_packet_type_radio(self, data, optional):
                -        #self.logger.warning("enocean: processing radio message with data = [{}] / optional = [{}]".format(', '.join(['0x%02x' % b for b in data]), ', '.join(['0x%02x' % b for b in optional])))
                -
                -        choice = data[0]
                -        payload = data[1:-5]
                -        sender_id = int.from_bytes(data[-5:-1], byteorder='big', signed=False)
                -        status = data[-1]
                -        repeater_cnt = status & 0x0F
                -        self.logger.info("enocean: radio message: choice = {:02x} / payload = [{}] / sender_id = {:08X} / status = {} / repeat = {}".format(choice, ', '.join(['0x%02x' % b for b in payload]), sender_id, status, repeater_cnt))
                -
                -        if (len(optional) == 7):
                -            subtelnum = optional[0]
                -            dest_id = int.from_bytes(optional[1:5], byteorder='big', signed=False)
                -            dBm = -optional[5]
                -            SecurityLevel = optional[6]
                -            self.logger.debug("enocean: radio message with additional info: subtelnum = {} / dest_id = {:08X} / signal = {}dBm / SecurityLevel = {}".format(subtelnum, dest_id, dBm, SecurityLevel))
                -            if (choice == 0xD4) and (self.UTE_listen == True):
                -                self.logger.info("call send_UTE_response")
                -                self._send_UTE_response(data, optional)
                -        if sender_id in self._rx_items:
                -            self.logger.debug("enocean: Sender ID found in item list")
                -            # iterate over all eep known for this id and get list of associated items
                -            for eep,items in self._rx_items[sender_id].items():
                -                # check if choice matches first byte in eep (this seems to be the only way to find right eep for this particular packet)
                -                if eep.startswith("{:02X}".format(choice)):
                -                    # call parser for particular eep - returns dictionary with key-value pairs
                -                    results = self.eep_parser.Parse(eep, payload, status)
                -                    #self.logger.debug("enocean: radio message results = {}".format(results))
                -                    for item in items:
                -                        rx_key = item.conf['enocean_rx_key'].upper()
                -                        if rx_key in results:
                -                            if 'enocean_rocker_sequence' in item.conf:
                -                                try:   
                -                                    if hasattr(item, '_enocean_rs_thread') and item._enocean_rs_thread.isAlive():
                -                                        if results[rx_key]:
                -                                            self.logger.debug("sending pressed event")
                -                                            item._enocean_rs_events["PRESSED"].set()
                -                                        else:
                -                                            self.logger.debug("sending released event")
                -                                            item._enocean_rs_events["RELEASED"].set()
                -                                    elif results[rx_key]:
                -                                        item._enocean_rs_events = {'PRESSED': threading.Event(), 'RELEASED': threading.Event()}
                -                                        item._enocean_rs_thread = threading.Thread(target=self._rocker_sequence, name="enocean-rs", args=(item, sender_id, item.conf['enocean_rocker_sequence'].split(','), ))
                -                                        #self.logger.info("starting enocean_rocker_sequence thread")
                -                                        item._enocean_rs_thread.daemon = True
                -                                        item._enocean_rs_thread.start()
                -                                except Exception as e:
                -                                    self.logger.error("enocean: error handling enocean_rocker_sequence - {}".format(e))
                -                            else:
                -                                item(results[rx_key], 'EnOcean', "{:08X}".format(sender_id))
                -        elif (sender_id <= self.tx_id + 127) and (sender_id >= self.tx_id):
                -            self.logger.debug("enocean: Received repeated enocean stick message")
                -        else:
                -            self.logger.info("unknown ID = {:08X}".format(sender_id))
                -
                -
                -    def _process_packet_type_smart_ack_command(self, data, optional):
                -        self.logger.warning("enocean: smart acknowledge command 0x06 received but not supported at the moment")
                -
                -
                -    def _process_packet_type_response(self, data, optional):
                -        RETURN_CODES = ['OK', 'ERROR', 'NOT SUPPORTED', 'WRONG PARAM', 'OPERATION DENIED']
                -        if (self._last_cmd_code == SENT_RADIO_PACKET) and (len(data) == 1):
                -            self.logger.debug("enocean: sending command returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_RESET) and (len(data) == 1):
                -            self.logger.info("enocean: Reset returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_LEARNMODE) and (len(data) == 1):
                -            self.logger.info("enocean: Write LearnMode returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_VERSION):
                -            if (data[0] == 0) and (len(data) == 33):
                -                self.logger.info("enocean: Chip ID = 0x{} / Chip Version = 0x{}".format(''.join(['%02x' % b for b in data[9:13]]), ''.join(['%02x' % b for b in data[13:17]])))
                -                self.logger.info("enocean: APP version = {} / API version = {} / App description = {}".format('.'.join(['%d' % b for b in data[1:5]]), '.'.join(['%d' % b for b in data[5:9]]), ''.join(['%c' % b for b in data[17:33]])))
                -            elif (data[0] == 0) and (len(data) == 0):
                -                self.logger.error("enocean: Reading version: No answer")
                -            else:
                -                self.logger.error("enocean: Reading version returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_IDBASE):
                -            if (data[0] == 0) and (len(data) == 5):
                -                self.logger.info("enocean: Base ID = 0x{}".format(''.join(['%02x' % b for b in data[1:5]])))
                -                if (self.tx_id == 0):
                -                    self.tx_id = int.from_bytes(data[1:5], byteorder='big', signed=False)
                -                    self.logger.info("enocean: Transmit ID set set automatically by reading chips BaseID")
                -                if (len(optional) == 1):
                -                    self.logger.info("enocean: Remaining write cycles for Base ID = {}".format(optional[0]))
                -            elif (data[0] == 0) and (len(data) == 0):
                -                self.logger.error("enocean: Reading Base ID: No answer")
                -            else:
                -                self.logger.error("enocean: Reading Base ID returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_BIST):
                -            if (data[0] == 0) and (len(data) == 2):
                -                if (data[1] == 0):
                -                    self.logger.info("enocean: built in self test result: All OK")
                -                else:
                -                    self.logger.info("enocean: built in self test result: Problem, code = {}".format(data[1]))
                -            elif (data[0] == 0) and (len(data) == 0):
                -                self.logger.error("enocean: Doing built in self test: No answer")
                -            else:
                -                self.logger.error("enocean: Doing built in self test returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_LEARNMODE):
                -            if (data[0] == 0) and (len(data) == 2):
                -                self.logger.info("enocean: Reading LearnMode = 0x{}".format(''.join(['%02x' % b for b in data[1]])))
                -                if (len(optional) == 1):
                -                    self.logger.info("enocean: learn channel = {}".format(optional[0]))
                -            elif (data[0] == 0) and (len(data) == 0):
                -                self.logger.error("enocean: Reading LearnMode: No answer")
                -        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_NUMSECUREDEVICES):
                -            if (data[0] == 0) and (len(data) == 2):
                -                self.logger.info("enocean: Number of taught in devices = 0x{}".format(''.join(['%02x' % b for b in data[1]])))
                -            elif (data[0] == 0) and (len(data) == 0):
                -                self.logger.error("enocean: Reading NUMSECUREDEVICES: No answer")
                -            elif (data[0] == 2) and (len(data) == 1):
                -                self.logger.error("enocean: Reading NUMSECUREDEVICES: Command not supported")
                -            else:
                -                self.logger.error("enocean: Reading NUMSECUREDEVICES: Unknown error")
                -        elif (self._last_packet_type == PACKET_TYPE_SMART_ACK_COMMAND) and (self._last_cmd_code == SA_WR_LEARNMODE):
                -            self.logger.info("enocean: Setting SmartAck mode returned code = {}".format(RETURN_CODES[data[0]]))
                -        elif (self._last_packet_type == PACKET_TYPE_SMART_ACK_COMMAND) and (self._last_cmd_code == SA_RD_LEARNEDCLIENTS):
                -            if (data[0] == 0):
                -                self.logger.info("enocean: Number of smart acknowledge mailboxes = {}".format( int((len(data)-1)/9) ))
                -            else:
                -                self.logger.error("enocean: Requesting SmartAck mailboxes returned code = {}".format(RETURN_CODES[data[0]]))
                -        else:
                -            self.logger.error("enocean: processing unexpected response with return code = {} / data = [{}] / optional = [{}]".format(RETURN_CODES[data[0]], ', '.join(['0x%02x' % b for b in data]), ', '.join(['0x%02x' % b for b in optional])))
                -        self._response_lock.acquire()
                -        self._response_lock.notify()
                -        self._response_lock.release()
                -
                -    def _startup(self):
                -        # request one time information
                -        self.logger.info("enocean: resetting device")
                -        self._send_common_command(CO_WR_RESET)
                -        self.logger.info("enocean: requesting id-base")
                -        self._send_common_command(CO_RD_IDBASE)
                -        self.logger.info("enocean: requesting version information")
                -        self._send_common_command(CO_RD_VERSION)
                -        self.logger.debug("enocean: ending connect-thread")
                -
                -    def run(self):
                -        self.alive = True
                -        self.UTE_listen = False
                -        #self.learn_id = 0
                -        t = threading.Thread(target=self._startup, name="enocean-startup")
                -        t.daemon = True
                -        t.start()
                -        msg = []
                -        while self.alive:
                -            readin = self._tcm.read(1000)
                -            if readin:
                -                msg += readin
                -                #self.logger.debug("enocean: data received")
                -                # check if header is complete (6bytes including sync)
                -                # 0x55 (SYNC) + 4bytes (HEADER) + 1byte(HEADER-CRC)
                -                while (len(msg) >= 6):
                -                    #check header for CRC
                -                    if (msg[0] == PACKET_SYNC_BYTE) and (self._calc_crc8(msg[1:5]) == msg[5]):
                -                        # header bytes: sync; length of data (2); optional length; packet type; crc
                -                        data_length = (msg[1] << 8) + msg[2]
                -                        opt_length = msg[3]
                -                        packet_type = msg[4]
                -                        msg_length = data_length + opt_length + 7
                -                        self.logger.debug("enocean: received header with data_length = {} / opt_length = 0x{:02x} / type = {}".format(data_length, opt_length, packet_type))
                -
                -                        # break if msg is not yet complete:
                -                        if (len(msg) < msg_length):
                -                            break
                -
                -                        # msg complete
                -                        if (self._calc_crc8(msg[6:msg_length - 1]) == msg[msg_length - 1]):
                -                            self.logger.debug("enocean: accepted package with type = 0x{:02x} / len = {} / data = [{}]!".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                -                            data = msg[6:msg_length - (opt_length + 1)]
                -                            optional = msg[(6 + data_length):msg_length - 1]
                -                            if (packet_type == PACKET_TYPE_RADIO):
                -                                self._process_packet_type_radio(data, optional)
                -                            elif (packet_type == PACKET_TYPE_SMART_ACK_COMMAND):
                -                                self._process_packet_type_smart_ack_command(data, optional)
                -                            elif (packet_type == PACKET_TYPE_RESPONSE):
                -                                self._process_packet_type_response(data, optional)
                -                            elif (packet_type == PACKET_TYPE_EVENT):
                -                                self._process_packet_type_event(data, optional)
                -                            else:
                -                                self.logger.error("enocean: received packet with unknown type = 0x{:02x} - len = {} / data = [{}]".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                -                        else:
                -                            self.logger.error("enocean: crc error - dumping packet with type = 0x{:02x} / len = {} / data = [{}]!".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                -                        msg = msg[msg_length:]
                -                    else:
                -                        #self.logger.warning("enocean: consuming [0x{:02x}] from input buffer!".format(msg[0]))
                -                        msg.pop(0)
                -
                -    def stop(self):
                -        self.alive = False
                -        self.logger.info("enocean: Thread stopped")
                -        
                -    def start_UTE_learnmode(self, id_offset=0):
                -        self.UTE_listen = True
                -        self.learn_id = id_offset
                -        self.logger.info("enocean: Listeining for UTE package ('D4')")
                -
                -    def _send_UTE_response(self, data, optional):
                -        choice = data[0]
                -        #payload = data[1:-5]
                -        #sender_id = int.from_bytes(data[-5:-1], byteorder='big', signed=False)
                -        #status = data[-1]
                -        #repeater_cnt = status & 0x0F
                -        SubTel = 0x03
                -        db = 0xFF
                -        Secu = 0x0
                -        self._send_radio_packet(self.learn_id, choice, [0x91, payload[1], payload[2], payload[3], payload[4], payload[5], payload[6]],[SubTel, data[-5], data[-4], data[-3], data[-2], db, Secu] )#payload[0] = 0x91: EEP Teach-in response, Request accepted, teach-in successful, bidirectional
                -        self.UTE_listen = False
                -        self.logger.info("enocean: sending UTE response and end listening")
                -    def parse_item(self, item):
                -        if 'enocean_rx_key' in item.conf:
                -            # look for info from the most specific info to the broadest (key->eep->id) - one id might use multiple eep might define multiple keys
                -            eep_item = item
                -            while (not 'enocean_rx_eep' in eep_item.conf):
                -                eep_item = eep_item.return_parent()
                -                if (eep_item is self._sh):
                -                    self.logger.error("enocean: could not find enocean_rx_eep for item {}".format(item))
                -                    return None
                -            id_item = eep_item
                -            while (not 'enocean_rx_id' in id_item.conf):
                -                id_item = id_item.return_parent()
                -                if (id_item is self._sh):
                -                    self.logger.error("enocean: could not find enocean_rx_id for item {}".format(item))
                -                    return None
                -
                -            rx_key = item.conf['enocean_rx_key'].upper()
                -            rx_eep = eep_item.conf['enocean_rx_eep'].upper()
                -            rx_id = int(id_item.conf['enocean_rx_id'],16)
                -
                -            # check if there is a function to parse payload
                -            if not self.eep_parser.CanParse(rx_eep):
                -                return None
                -
                -            if (rx_key in ['A0', 'A1', 'B0', 'B1']):
                -                self.logger.warning("enocean: key \"{}\" does not match EEP - \"0\" (Zero, number) should be \"O\" (letter) (same for \"1\" and \"I\") - will be accepted for now".format(rx_key))
                -                rx_key = rx_key.replace('0', 'O').replace("1", 'I')
                -
                -            if (not rx_id in self._rx_items):
                -                self._rx_items[rx_id] = {rx_eep: [item]}
                -            elif (not rx_eep in self._rx_items[rx_id]):
                -                self._rx_items[rx_id][rx_eep] = [item]
                -            elif (not item in self._rx_items[rx_id][rx_eep]):
                -                self._rx_items[rx_id][rx_eep].append(item)
                -
                -            self.logger.info("enocean: item {} listens to id {:08X} with eep {} key {}".format(item, rx_id, rx_eep, rx_key))
                -            #self.logger.info("enocean: self._rx_items = {}".format(self._rx_items))
                -            return self.update_item
                -
                -    def update_item(self, item, caller=None, source=None, dest=None):
                -        if caller != 'EnOcean':
                -            self.logger.debug('enocean: item updated externally')
                -            if self._block_ext_out_msg:
                -                self.logger.debug('enocean: sending manually blocked by user. Aborting')
                -                return
                -            if 'enocean_tx_eep' in item.conf:
                -                if isinstance(item.conf['enocean_tx_eep'], str):
                -                    tx_eep = item.conf['enocean_tx_eep']
                -                    self.logger.debug('enocean: item has tx_eep')
                -                    id_offset = 0
                -                    if 'enocean_tx_id_offset' in item.conf and (isinstance(item.conf['enocean_tx_id_offset'], str)):
                -                        self.logger.debug('enocean: item has valid enocean_tx_id_offset')
                -                        id_offset = int(item.conf['enocean_tx_id_offset'])
                -                    #Identify send command based on tx_eep coding:
                -                    if(tx_eep == 'A5_20_04'):
                -                        self.send_radiator_valve(id_offset)
                -                        self.logger.debug('enocean: sent A5_20_04 radiator valve command')
                -                    elif(tx_eep == 'A5_38_08_02'):
                -                        self.logger.debug('enocean: item is A5_38_08_02 type')
                -                        if not item():
                -                            self.send_dim(id_offset, 0, 0)
                -                            self.logger.debug('enocean: sent off command')
                -                        else:
                -                            if 'ref_level' in item.level.conf:
                -                                dim_value = int(item.level.conf['ref_level'])
                -                                self.logger.debug('enocean: ref_level found')
                -                            else:
                -                                dim_value = 100
                -                                self.logger.debug('enocean: no ref_level found. Setting to default 100')
                -                            self.send_dim(id_offset, dim_value, 0)
                -                            self.logger.debug('enocean: sent dim on command')
                -                    elif(tx_eep == 'A5_38_08_03'):
                -                        self.logger.debug('enocean: item is A5_38_08_03 type')
                -                        self.send_dim(id_offset, item(), 0)
                -                        self.logger.debug('enocean: sent dim command')
                -                    elif(tx_eep == 'A5_38_08_01'):
                -                        self.logger.debug('enocean: item is A5_38_08_01 type')
                -                        self.send_switch(id_offset, item(), 0)
                -                        self.logger.debug('enocean: sent switch command')
                -                    elif(tx_eep == '07_3F_7F'):
                -                        self.logger.debug('enocean: item is 07_3F_7F type')
                -                        self.send_rgbw_dim(id_offset, item(), 0)
                -                        self.logger.debug('enocean: sent RGBW dim command')
                -                    elif(tx_eep == 'A5_3F_7F'):
                -                        self.logger.debug('enocean: item is A5_3F_7F type')
                -                        self.send_actuator_cmd(id_offset, item())
                -                        self.logger.debug('enocean: sent actuator command')
                -                    else:
                -                        self.logger.error('enocean: error: Unknown tx eep command')
                -                else:
                -                    self.logger.error('enocean: tx_eep is not a string value')
                -            else:
                -                self.logger.debug('enocean: item has no tx_eep value')
                -
                -    def read_num_securedivices(self):
                -        self._send_common_command(CO_RD_NUMSECUREDEVICES)
                -        self.logger.info("enocean: Read number of secured devices")
                -
                -    def enter_learn_mode(self, onoff=1):
                -        if (onoff == 1):
                -            self._send_common_command(CO_WR_LEARNMODE, [0x01, 0x00, 0x00, 0x00, 0x00],[0xFF])
                -            self.logger.info("enocean: entering learning mode")
                -        else:
                -            self._send_common_command(CO_WR_LEARNMODE, [0x00, 0x00, 0x00, 0x00, 0x00],[0xFF])
                -            self.logger.info("enocean: leaving learning mode")
                -
                -    #This function enables/disables the controller's smart acknowledge mode
                -    def set_smart_ack_learn_mode(self, onoff=1):
                -        if (onoff == 1):
                -            self._send_smart_ack_command(SA_WR_LEARNMODE, [0x01, 0x00, 0x00, 0x00, 0x00, 0x00])
                -            self.logger.info("enocean: enabling smart acknowledge learning mode")
                -        else:
                -            self._send_smart_ack_command(SA_WR_LEARNMODE, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
                -            self.logger.info("enocean: disabling smart acknowledge learning mode")
                -
                -    # Request all taught in smart acknowledge devices that have a mailbox
                -    def get_smart_ack_devices(self):
                -        self._send_smart_ack_command(SA_RD_LEARNEDCLIENTS)
                -        self.logger.info("enocean: Requesting all available smart acknowledge mailboxes")
                -
                -
                -    def reset_stick(self):
                -        self.logger.info("enocean: resetting device")
                -        self._send_common_command(CO_WR_RESET)
                -
                -    def block_external_out_messages(self, block=True):
                -        if block:
                -            self.logger.info("enocean: Blocking of external out messages activated")
                -            self._block_ext_out_msg = True
                -        elif not block:
                -            self.logger.info("enocean: Blocking of external out messages deactivated")
                -            self._block_ext_out_msg = False
                -        else:
                -            self.logger.info("enocean: invalid argument. Must be True/False")
                -
                -    def send_bit(self):
                -        self.logger.info("enocean: trigger Built-In Self Test telegram")
                -        self._send_common_command(CO_WR_BIST)
                -
                -    def version(self):
                -        self.logger.info("enocean: request stick version")
                -        self._send_common_command(CO_RD_VERSION)
                -
                -    def _send_packet(self, packet_type, data=[], optional=[]):
                -        length_optional = len(optional)
                -        if length_optional > 255:
                -            self.logger.error("enocean: optional too long ({} bytes, 255 allowed)".format(length_optional))
                -            return
                -        length_data = len(data)
                -        if length_data > 65535:
                -            self.logger.error("enocean: data too long ({} bytes, 65535 allowed)".format(length_data))
                -            return
                -
                -        packet = bytearray([PACKET_SYNC_BYTE])
                -        packet += length_data.to_bytes(2, byteorder='big') + bytes([length_optional, packet_type])
                -        packet += bytes([self._calc_crc8(packet[1:5])])
                -        packet += bytes(data + optional)
                -        packet += bytes([self._calc_crc8(packet[6:])])
                -        self.logger.debug("enocean: sending packet with len = {} / data = [{}]!".format(len(packet), ', '.join(['0x%02x' % b for b in packet])))
                -        self._tcm.write(packet)
                -
                -    def _send_smart_ack_command(self, _code, data=[]):
                -        self._cmd_lock.acquire()
                -        self._last_cmd_code = _code
                -        self._last_packet_type = PACKET_TYPE_SMART_ACK_COMMAND
                -        self._send_packet(PACKET_TYPE_SMART_ACK_COMMAND, [_code] + data)
                -        self._response_lock.acquire()
                -        # wait 5sec for response
                -        self._response_lock.wait(5)
                -        self._response_lock.release()
                -        self._cmd_lock.release()
                -
                -    def _send_common_command(self, _code, data=[], optional=[]):
                -        self._cmd_lock.acquire()
                -        self._last_cmd_code = _code
                -        self._last_packet_type = PACKET_TYPE_COMMON_COMMAND
                -        self._send_packet(PACKET_TYPE_COMMON_COMMAND, [_code] + data, optional)
                -        self._response_lock.acquire()
                -        # wait 5sec for response
                -        self._response_lock.wait(5)
                -        self._response_lock.release()
                -        self._cmd_lock.release()
                -
                -    def _send_radio_packet(self, id_offset, _code, data=[], optional=[]):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: invalid base ID offset range. (Is {}, must be [0 127])".format(id_offset))
                -            return
                -        self._cmd_lock.acquire()
                -        self._last_cmd_code = SENT_RADIO_PACKET
                -        self._send_packet(PACKET_TYPE_RADIO, [_code] + data + list((self.tx_id + id_offset).to_bytes(4, byteorder='big')) + [0x00], optional)
                -        self._response_lock.acquire()
                -        # wait 5sec for response
                -        self._response_lock.wait(5)
                -        self._response_lock.release()
                -        self._cmd_lock.release()
                -
                -    def send_radiator_valve(self,item, id_offset=0):
                -        self.logger.debug("enocean: sending valve command A5_20_04")
                -        temperature = item
                -        #define default values:
                -        MC  = 1 #off
                -        WUC = 3 # 120 seconds
                -        BLC = 0 # unlocked
                -        LRNB = 1# data
                -        DSO = 0 # 0 degree
                -        valve_position = 50
                -
                -        for sibling in get_children(item.parent):
                -            if hasattr(sibling, "MC"):
                -                MC = sibling()
                -            if hasattr(sibling, "WUC"):
                -                WUC = sibling()
                -            if hasattr(sibling, "BLC"):
                -                BLC = sibling()
                -            if hasattr(sibling, "LRNB"):
                -                LRNB = sibling()
                -            if hasattr(sibling, "DSO"):
                -                DSO = sibling()
                -            if hasattr(sibling, "VALVE_POSITION"):
                -                valve_position = sibling()
                -        TSP = int((temperature -10)*255/30)
                -        status =  0 + (MC << 1) + (WUC << 2) 
                -        status2 = (BLC << 5) + (LRNB << 4) + (DSO << 2) 
                -        self._send_radio_packet(id_offset, 0xA5, [valve_position, TSP, status , status2])
                -
                -    def send_learn_radiator_valve(self, id_offset=0):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                -            return
                -        self.logger.info("enocean: sending learn telegram for radiator valve")
                -        self._send_radio_packet(id_offset, 0xA5, [0x00, 0x00, 0x00, 0x00])
                -
                -
                -    def send_dim(self,id_offset=0, dim=0, dimspeed=0):
                -        if (dimspeed < 0) or (dimspeed > 255):
                -            self.logger.error("enocean: sending dim command A5_38_08: invalid range of dimspeed")
                -            return
                -        self.logger.debug("enocean: sending dim command A5_38_08")
                -        if (dim == 0):
                -            self._send_radio_packet(id_offset, 0xA5, [0x02, 0x00, int(dimspeed), 0x08])
                -        elif (dim > 0) and (dim <= 100):
                -            self._send_radio_packet(id_offset, 0xA5, [0x02, int(dim), int(dimspeed), 0x09])
                -        else:
                -            self.logger.error("enocean: sending command A5_38_08: invalid dim value")
                -
                -    def send_actuator_cmd(self,id_offset=0, command=0):
                -        pass
                -
                -
                -    def send_rgbw_dim(self,id_offset=0, color='red', dim=0, dimspeed=0):
                -        if(color == str(red)):
                -            color_hex_code = 0x10
                -        elif(color == str(green)):
                -            color_hex_code = 0x11
                -        elif(color == str(blue)):
                -            color_hex_code = 0x12
                -        elif(color == str(white)):
                -            color_hex_code = 0x13
                -        else:
                -            self.logger.error("enocean: sending rgbw dim command: invalid color")
                -            return
                -        if (dim < 0) or (dim > 1023):
                -            self.logger.error("enocean: sending rgb dim command: invalid dim value range. Only 10 bit allowed")
                -            return
                -        self._send_radio_packet(id_offset, 0x07, [ list(dim.to_bytes(2, byteorder='big')), color_hex_code, 0x0F])
                -        self.logger.debug("enocean: sent dim command 07_3F_7F")
                -
                -
                -    def send_switch(self,id_offset=0, on=0, block=0):
                -        if (block < 0) and (block > 1):
                -            self.logger.error("enocean: sending switch command A5_38_08: invalid range of block (0,1)")
                -            return
                -        self.logger.debug("enocean: sending switch command A5_38_08")
                -        if (on == 0):
                -            self._send_radio_packet(id_offset, 0xA5, [0x01, 0x00, 0x00, 0x08])
                -        elif (on == 1) and (block == 0):
                -            self._send_radio_packet(id_offset, 0xA5, [0x01, 0x00, 0x00, 0x09])
                -        else:
                -            self.logger.error("enocean: sending command A5_38_08: error")
                -
                -    def send_learn_dim(self, id_offset=0):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                -            return
                -        self.logger.info("enocean: sending learn telegram for dim command")
                -        self._send_radio_packet(id_offset, 0xA5, [0x02, 0x00, 0x00, 0x00])
                -
                -    def send_learn_rgbw_dim(self, id_offset=0):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                -            return
                -        self.logger.info("enocean: sending learn telegram for rgbw dim command")
                -        self._send_radio_packet(id_offset, 0x07, [0xFF, 0xF8, 0x0D, 0x87])
                -
                -    def send_learn_switch(self, id_offset=0):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                -            return
                -        self.logger.info("enocean: sending learn telegram for switch command")
                -        self._send_radio_packet(id_offset, 0xA5, [0x01, 0x00, 0x00, 0x00])
                -
                -    def send_learn_actuator(self, id_offset=0):
                -        if (id_offset < 0) or (id_offset > 127):
                -            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                -            return
                -        self.logger.info("enocean: sending learn telegram for actuator")
                -        self._send_radio_packet(id_offset, 0xA5, [0xFF, 0xF8, 0x0D, 0x80])
                -
                -#################################
                -### --- START - Calc CRC8 --- ###
                -#################################
                -    def _calc_crc8(self, msg, crc=0):
                -        for i in msg:
                -            crc = FCSTAB[crc ^ i]
                -        return crc
                -
                -###############################
                -### --- END - Calc CRC8 --- ###
                -###############################
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2013-2014 Robert Budde                   robert@ing-budde.de
                +#  Copyright 2014 Alexander Schwithal                 aschwith
                +#########################################################################
                +#  Enocean plugin for SmartHomeNG.      https://github.com/smarthomeNG//
                +#
                +#  This plugin is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  This plugin is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import serial
                +import os
                +import sys
                +import logging
                +import struct
                +import time
                +import threading
                +from . import eep_parser
                +from lib.model.smartplugin import SmartPlugin
                +
                +FCSTAB = [
                +    0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
                +    0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
                +    0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
                +    0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
                +    0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
                +    0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
                +    0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
                +    0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
                +    0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
                +    0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
                +    0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
                +    0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
                +    0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
                +    0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
                +    0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
                +    0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
                +    0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
                +    0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
                +    0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
                +    0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
                +    0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
                +    0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
                +    0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
                +    0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
                +    0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
                +    0x76, 0x71, 0x78, 0x7f, 0x6A, 0x6d, 0x64, 0x63,
                +    0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
                +    0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
                +    0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
                +    0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8D, 0x84, 0x83,
                +    0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
                +    0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
                +    ]
                +
                +################################
                +### --- Packet Sync Byte --- ###
                +################################
                +PACKET_SYNC_BYTE              = 0x55   # PACKET SYNC BYTE
                +
                +
                +############################
                +### --- Packet Types --- ###
                +############################
                +
                +PACKET_TYPE_RADIO             = 0x01   # RADIO ERP1
                +PACKET_TYPE_RESPONSE          = 0x02   # RESPONSE
                +PACKET_TYPE_RADIO_SUB_TEL     = 0x03   # RADIO_SUB_TEL
                +PACKET_TYPE_EVENT             = 0x04   # EVENT
                +PACKET_TYPE_COMMON_COMMAND    = 0x05   # COMMON COMMAND
                +PACKET_TYPE_SMART_ACK_COMMAND = 0x06   # SMART ACK COMMAND
                +PACKET_REMOTE_MAN_COMMAND     = 0x07   # REMOTE MANAGEMENT COMMAND
                +PACKET_TYPE_RADIO_MESSAGE     = 0x09   # RADIO MESSAGE
                +PACKET_TYPE_RADIO_ERP2        = 0x0A   # RADIO ERP2
                +PACKET_TYPE_RADIO_802_15_4    = 0x10   # RADIO_802_15_4
                +PACKET_TYPE_COMMAND_2_4       = 0x11   # COMMAND_2_4
                +
                +
                +############################################
                +### --- List of Common Command Codes --- ###
                +############################################
                +
                +CO_WR_SLEEP                     = 0x01     # Order to enter in energy saving mode
                +CO_WR_RESET                     = 0x02     # Order to reset the device
                +CO_RD_VERSION                   = 0x03     # Read the device (SW) version /(HW) version, chip ID etc.
                +CO_RD_SYS_LOG                   = 0x04     # Read system log from device databank
                +CO_WR_SYS_LOG                   = 0x05     # Reset System log from device databank
                +CO_WR_BIST                      = 0x06     # Perform built in self test
                +CO_WR_IDBASE                    = 0x07     # Write ID range base number
                +CO_RD_IDBASE                    = 0x08     # Read ID range base number
                +CO_WR_REPEATER                  = 0x09     # Write Repeater Level off,1,2
                +CO_RD_REPEATER                  = 0x0A     # Read Repeater Level off,1,2
                +CO_WR_FILTER_ADD                = 0x0B     # Add filter to filter list
                +CO_WR_FILTER_DEL                = 0x0C     # Delete filter from filter list
                +CO_WR_FILTER_DEL_ALL            = 0x0D     # Delete all filter
                +CO_WR_FILTER_ENABLE             = 0x0E     # Enable/Disable supplied filters
                +CO_RD_FILTER                    = 0x0F     # Read supplied filters
                +CO_WR_WAIT_MATURITY             = 0x10     # Waiting till end of maturity time before received radio telegrams will transmitted
                +CO_WR_SUBTEL                    = 0x11     # Enable/Disable transmitting additional subtelegram info
                +CO_WR_MEM                       = 0x12     # Write x bytes of the Flash, XRAM, RAM0 …
                +CO_RD_MEM                       = 0x13     # Read x bytes of the Flash, XRAM, RAM0 ….
                +CO_RD_MEM_ADDRESS               = 0x14     # Feedback about the used address and length of the configarea and the Smart Ack Table
                +CO_RD_SECURITY                  = 0x15     # Read own security information (level, key)
                +CO_WR_SECURITY                  = 0x16     # Write own security information (level, key)
                +CO_WR_LEARNMODE                 = 0x17     # Function: Enables or disables learn mode of Controller.
                +CO_RD_LEARNMODE                 = 0x18     # Function: Reads the learn-mode state of Controller.
                +CO_WR_SECUREDEVICE_ADD          = 0x19     # Add a secure device
                +CO_WR_SECUREDEVICE_DEL          = 0x1A     # Delete a secure device
                +CO_RD_SECUREDEVICE_BY_INDEX     = 0x1B     # Read secure device by index
                +CO_WR_MODE                      = 0x1C     # Sets the gateway transceiver mode
                +CO_RD_NUMSECUREDEVICES          = 0x1D     # Read number of taught in secure devices
                +CO_RD_SECUREDEVICE_BY_ID        = 0x1E     # Read secure device by ID
                +CO_WR_SECUREDEVICE_ADD_PSK      = 0x1F     # Add Pre-shared key for inbound secure device
                +CO_WR_SECUREDEVICE_SENDTEACHIN  = 0x20     # Send secure Teach-In message
                +CO_WR_TEMPORARY_RLC_WINDOW      = 0x21     # Set the temporary rolling-code window for every taught-in devic
                +CO_RD_SECUREDEVICE_PSK          = 0x22     # Read PSK
                +CO_RD_DUTYCYCLE_LIMIT           = 0x23     # Read parameters of actual duty cycle limit
                +CO_SET_BAUDRATE                 = 0x24     # Modifies the baud rate of the EnOcean device
                +CO_GET_FREQUENCY_INFO           = 0x25     # Reads Frequency and protocol of the Device
                +CO_GET_STEPCODE                 = 0x27     # Reads Hardware Step code and Revision of the Device
                +
                +
                +###################################
                +### --- List of Event Codes --- ###
                +###################################
                +
                +SA_RECLAIM_NOT_SUCCESSFUL  = 0x01      # Informs the backbone of a Smart Ack Client to not successful reclaim.
                +SA_CONFIRM_LEARN           = 0x02      # Used for SMACK to confirm/discard learn in/out
                +SA_LEARN_ACK               = 0x03      # Inform backbone about result of learn request
                +CO_READY                   = 0x04      # Inform backbone about the readiness for operation
                +CO_EVENT_SECUREDEVICES     = 0x05      # Informs about a secure device
                +CO_DUTYCYCLE_LIMIT         = 0x06      # Informs about duty cycle limit
                +CO_TRANSMIT_FAILED         = 0x07      # Informs that the device was not able to send a telegram.
                +
                +
                +###########################################
                +###  --- Smart Acknowledge Defines: --- ###
                +###########################################
                +
                +SA_WR_LEARNMODE        = 0x01          # Set/Reset Smart Ack learn mode
                +SA_RD_LEARNMODE        = 0x02          # Get Smart Ack learn mode state
                +SA_WR_LEARNCONFIRM     = 0x03          # Used for Smart Ack to add or delete a mailbox of a client
                +SA_WR_CLIENTLEARNRQ    = 0x04          # Send Smart Ack Learn request (Client)
                +SA_WR_RESET            = 0x05          # Send reset command to a Smart Ack client
                +SA_RD_LEARNEDCLIENTS   = 0x06          # Get Smart Ack learned sensors / mailboxes
                +SA_WR_RECLAIMS         = 0x07          # Set number of reclaim attempts
                +SA_WR_POSTMASTER       = 0x08          # Activate/Deactivate Post master functionality
                +
                +SENT_RADIO_PACKET              = 0xFF
                +SENT_ENCAPSULATED_RADIO_PACKET = 0xA6
                +
                +class EnOcean(SmartPlugin):
                +    PLUGIN_VERSION = "1.3.3"
                +    ALLOW_MULTIINSTANCE = False
                +    
                +    def __init__(self, smarthome, serialport, tx_id=''):
                +        self._sh = smarthome
                +        self.port = serialport
                +        self.logger = logging.getLogger(__name__)
                +        if (len(tx_id) < 8):
                +            self.tx_id = 0
                +            self.logger.warning('enocean: No valid enocean stick ID configured. Transmitting is not supported')
                +        else:
                +            self.tx_id = int(tx_id, 16)
                +            self.logger.info('enocean: Stick TX ID configured via plugin.conf to: {0}'.format(tx_id))
                +        self._tcm = serial.Serial(serialport, 57600, timeout=0.5)
                +        self._cmd_lock = threading.Lock()
                +        self._response_lock = threading.Condition()
                +        self._rx_items = {}
                +        self._block_ext_out_msg = False
                +        self.eep_parser = eep_parser.EEP_Parser()
                +
                +    def eval_telegram(self, sender_id, data, opt):
                +        for item in self._items:
                +            # validate id for item id:
                +            if item.conf['enocean_id'] == sender_id:
                +                #print ("validated {0} for {1}".format(sender_id,item))
                +                #print ("try to get value for: {0} and {1}".format(item.conf['enocean_rorg'][0],item.conf['enocean_rorg'][1]))
                +                rorg = item.conf['enocean_rorg']
                +                eval_value = item.conf['enocean_value']
                +                if rorg in RADIO_PAYLOAD_VALUE:  # check if RORG exists
                +                    pl = eval(RADIO_PAYLOAD_VALUE[rorg]['payload_idx'])
                +                    #could be nicer
                +                    for entity in RADIO_PAYLOAD_VALUE:
                +                        if (rorg == entity) and (eval_value in RADIO_PAYLOAD_VALUE[rorg]['entities']):
                +                            value_dict = RADIO_PAYLOAD_VALUE[rorg]['entities']
                +                            value = eval(RADIO_PAYLOAD_VALUE[rorg]['entities'][eval_value])
                +                            self.logger.debug("Resulting value: {0} for {1}".format(value, item))
                +                            if value:  # not sure about this
                +                                item(value, 'EnOcean', 'RADIO')
                +
                +    def _process_packet_type_event(self, data, optional):
                +        event_code = data[0]
                +        if(event_code == SA_RECLAIM_NOT_SUCCESSFUL):
                +            self.logger.error("enocean: SA reclaim was not successful")
                +        elif(event_code == SA_CONFIRM_LEARN):
                +            self.logger.info("enocean: Requesting how to handle confirm/discard learn in/out")
                +        elif(event_code == SA_LEARN_ACK):
                +            self.logger.info("enocean: SA lern acknowledged")
                +        elif(event_code == CO_READY):
                +            self.logger.info("enocean: Controller is ready for operation")
                +        elif(event_code == CO_TRANSMIT_FAILED):
                +            self.logger.error("enocean: Telegram transmission failed")
                +        elif(event_code == CO_DUTYCYCLE_LIMIT):
                +            self.logger.warning("enocean: Duty cycle limit reached")
                +        elif(event_code == CO_EVENT_SECUREDEVICES):
                +            self.logger.info("enocean: secure device event packet received")
                +        else:
                +            self.logger.warning("enocean: unknown event packet received")
                +
                +    def _rocker_sequence(self, item, sender_id, sequence):
                +        try:
                +            for step in sequence:
                +                event, relation, delay = step.split()             
                +                #self.logger.debug("waiting for {} {} {}".format(event, relation, delay))
                +                if item._enocean_rs_events[event.upper()].wait(float(delay)) != (relation.upper() == "WITHIN"):
                +                    self.logger.debug("NOT {} - aborting sequence!".format(step))
                +                    return
                +                else:
                +                    self.logger.debug("{}".format(step))
                +                    item._enocean_rs_events[event.upper()].clear()
                +                    continue          
                +            value = True
                +            if 'enocean_rocker_action' in item.conf:
                +                if item.conf['enocean_rocker_action'].upper() == "UNSET":
                +                    value = False
                +                elif item.conf['enocean_rocker_action'].upper() == "TOGGLE":
                +                    value = not item()
                +            item(value, 'EnOcean', "{:08X}".format(sender_id))
                +        except Exception as e:
                +            self.logger.error("enocean: error handling enocean_rocker_sequence \"{}\" - {}".format(sequence, e))        
                +
                +    def _process_packet_type_radio(self, data, optional):
                +        #self.logger.warning("enocean: processing radio message with data = [{}] / optional = [{}]".format(', '.join(['0x%02x' % b for b in data]), ', '.join(['0x%02x' % b for b in optional])))
                +
                +        choice = data[0]
                +        payload = data[1:-5]
                +        sender_id = int.from_bytes(data[-5:-1], byteorder='big', signed=False)
                +        status = data[-1]
                +        repeater_cnt = status & 0x0F
                +        self.logger.info("enocean: radio message: choice = {:02x} / payload = [{}] / sender_id = {:08X} / status = {} / repeat = {}".format(choice, ', '.join(['0x%02x' % b for b in payload]), sender_id, status, repeater_cnt))
                +
                +        if (len(optional) == 7):
                +            subtelnum = optional[0]
                +            dest_id = int.from_bytes(optional[1:5], byteorder='big', signed=False)
                +            dBm = -optional[5]
                +            SecurityLevel = optional[6]
                +            self.logger.debug("enocean: radio message with additional info: subtelnum = {} / dest_id = {:08X} / signal = {}dBm / SecurityLevel = {}".format(subtelnum, dest_id, dBm, SecurityLevel))
                +            if (choice == 0xD4) and (self.UTE_listen == True):
                +                self.logger.info("call send_UTE_response")
                +                self._send_UTE_response(data, optional)
                +        if sender_id in self._rx_items:
                +            self.logger.debug("enocean: Sender ID found in item list")
                +            # iterate over all eep known for this id and get list of associated items
                +            for eep,items in self._rx_items[sender_id].items():
                +                # check if choice matches first byte in eep (this seems to be the only way to find right eep for this particular packet)
                +                if eep.startswith("{:02X}".format(choice)):
                +                    # call parser for particular eep - returns dictionary with key-value pairs
                +                    results = self.eep_parser.Parse(eep, payload, status)
                +                    #self.logger.debug("enocean: radio message results = {}".format(results))
                +                    for item in items:
                +                        rx_key = item.conf['enocean_rx_key'].upper()
                +                        if rx_key in results:
                +                            if 'enocean_rocker_sequence' in item.conf:
                +                                try:   
                +                                    if hasattr(item, '_enocean_rs_thread') and item._enocean_rs_thread.isAlive():
                +                                        if results[rx_key]:
                +                                            self.logger.debug("sending pressed event")
                +                                            item._enocean_rs_events["PRESSED"].set()
                +                                        else:
                +                                            self.logger.debug("sending released event")
                +                                            item._enocean_rs_events["RELEASED"].set()
                +                                    elif results[rx_key]:
                +                                        item._enocean_rs_events = {'PRESSED': threading.Event(), 'RELEASED': threading.Event()}
                +                                        item._enocean_rs_thread = threading.Thread(target=self._rocker_sequence, name="enocean-rs", args=(item, sender_id, item.conf['enocean_rocker_sequence'].split(','), ))
                +                                        #self.logger.info("starting enocean_rocker_sequence thread")
                +                                        item._enocean_rs_thread.daemon = True
                +                                        item._enocean_rs_thread.start()
                +                                except Exception as e:
                +                                    self.logger.error("enocean: error handling enocean_rocker_sequence - {}".format(e))
                +                            else:
                +                                item(results[rx_key], 'EnOcean', "{:08X}".format(sender_id))
                +        elif (sender_id <= self.tx_id + 127) and (sender_id >= self.tx_id):
                +            self.logger.debug("enocean: Received repeated enocean stick message")
                +        else:
                +            self.logger.info("unknown ID = {:08X}".format(sender_id))
                +
                +
                +    def _process_packet_type_smart_ack_command(self, data, optional):
                +        self.logger.warning("enocean: smart acknowledge command 0x06 received but not supported at the moment")
                +
                +
                +    def _process_packet_type_response(self, data, optional):
                +        RETURN_CODES = ['OK', 'ERROR', 'NOT SUPPORTED', 'WRONG PARAM', 'OPERATION DENIED']
                +        if (self._last_cmd_code == SENT_RADIO_PACKET) and (len(data) == 1):
                +            self.logger.debug("enocean: sending command returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_RESET) and (len(data) == 1):
                +            self.logger.info("enocean: Reset returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_LEARNMODE) and (len(data) == 1):
                +            self.logger.info("enocean: Write LearnMode returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_VERSION):
                +            if (data[0] == 0) and (len(data) == 33):
                +                self.logger.info("enocean: Chip ID = 0x{} / Chip Version = 0x{}".format(''.join(['%02x' % b for b in data[9:13]]), ''.join(['%02x' % b for b in data[13:17]])))
                +                self.logger.info("enocean: APP version = {} / API version = {} / App description = {}".format('.'.join(['%d' % b for b in data[1:5]]), '.'.join(['%d' % b for b in data[5:9]]), ''.join(['%c' % b for b in data[17:33]])))
                +            elif (data[0] == 0) and (len(data) == 0):
                +                self.logger.error("enocean: Reading version: No answer")
                +            else:
                +                self.logger.error("enocean: Reading version returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_IDBASE):
                +            if (data[0] == 0) and (len(data) == 5):
                +                self.logger.info("enocean: Base ID = 0x{}".format(''.join(['%02x' % b for b in data[1:5]])))
                +                if (self.tx_id == 0):
                +                    self.tx_id = int.from_bytes(data[1:5], byteorder='big', signed=False)
                +                    self.logger.info("enocean: Transmit ID set set automatically by reading chips BaseID")
                +                if (len(optional) == 1):
                +                    self.logger.info("enocean: Remaining write cycles for Base ID = {}".format(optional[0]))
                +            elif (data[0] == 0) and (len(data) == 0):
                +                self.logger.error("enocean: Reading Base ID: No answer")
                +            else:
                +                self.logger.error("enocean: Reading Base ID returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_WR_BIST):
                +            if (data[0] == 0) and (len(data) == 2):
                +                if (data[1] == 0):
                +                    self.logger.info("enocean: built in self test result: All OK")
                +                else:
                +                    self.logger.info("enocean: built in self test result: Problem, code = {}".format(data[1]))
                +            elif (data[0] == 0) and (len(data) == 0):
                +                self.logger.error("enocean: Doing built in self test: No answer")
                +            else:
                +                self.logger.error("enocean: Doing built in self test returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_LEARNMODE):
                +            if (data[0] == 0) and (len(data) == 2):
                +                self.logger.info("enocean: Reading LearnMode = 0x{}".format(''.join(['%02x' % b for b in data[1]])))
                +                if (len(optional) == 1):
                +                    self.logger.info("enocean: learn channel = {}".format(optional[0]))
                +            elif (data[0] == 0) and (len(data) == 0):
                +                self.logger.error("enocean: Reading LearnMode: No answer")
                +        elif (self._last_packet_type == PACKET_TYPE_COMMON_COMMAND) and (self._last_cmd_code == CO_RD_NUMSECUREDEVICES):
                +            if (data[0] == 0) and (len(data) == 2):
                +                self.logger.info("enocean: Number of taught in devices = 0x{}".format(''.join(['%02x' % b for b in data[1]])))
                +            elif (data[0] == 0) and (len(data) == 0):
                +                self.logger.error("enocean: Reading NUMSECUREDEVICES: No answer")
                +            elif (data[0] == 2) and (len(data) == 1):
                +                self.logger.error("enocean: Reading NUMSECUREDEVICES: Command not supported")
                +            else:
                +                self.logger.error("enocean: Reading NUMSECUREDEVICES: Unknown error")
                +        elif (self._last_packet_type == PACKET_TYPE_SMART_ACK_COMMAND) and (self._last_cmd_code == SA_WR_LEARNMODE):
                +            self.logger.info("enocean: Setting SmartAck mode returned code = {}".format(RETURN_CODES[data[0]]))
                +        elif (self._last_packet_type == PACKET_TYPE_SMART_ACK_COMMAND) and (self._last_cmd_code == SA_RD_LEARNEDCLIENTS):
                +            if (data[0] == 0):
                +                self.logger.info("enocean: Number of smart acknowledge mailboxes = {}".format( int((len(data)-1)/9) ))
                +            else:
                +                self.logger.error("enocean: Requesting SmartAck mailboxes returned code = {}".format(RETURN_CODES[data[0]]))
                +        else:
                +            self.logger.error("enocean: processing unexpected response with return code = {} / data = [{}] / optional = [{}]".format(RETURN_CODES[data[0]], ', '.join(['0x%02x' % b for b in data]), ', '.join(['0x%02x' % b for b in optional])))
                +        self._response_lock.acquire()
                +        self._response_lock.notify()
                +        self._response_lock.release()
                +
                +    def _startup(self):
                +        # request one time information
                +        self.logger.info("enocean: resetting device")
                +        self._send_common_command(CO_WR_RESET)
                +        self.logger.info("enocean: requesting id-base")
                +        self._send_common_command(CO_RD_IDBASE)
                +        self.logger.info("enocean: requesting version information")
                +        self._send_common_command(CO_RD_VERSION)
                +        self.logger.debug("enocean: ending connect-thread")
                +
                +    def run(self):
                +        self.alive = True
                +        self.UTE_listen = False
                +        #self.learn_id = 0
                +        t = threading.Thread(target=self._startup, name="enocean-startup")
                +        t.daemon = True
                +        t.start()
                +        msg = []
                +        while self.alive:
                +            readin = self._tcm.read(1000)
                +            if readin:
                +                msg += readin
                +                #self.logger.debug("enocean: data received")
                +                # check if header is complete (6bytes including sync)
                +                # 0x55 (SYNC) + 4bytes (HEADER) + 1byte(HEADER-CRC)
                +                while (len(msg) >= 6):
                +                    #check header for CRC
                +                    if (msg[0] == PACKET_SYNC_BYTE) and (self._calc_crc8(msg[1:5]) == msg[5]):
                +                        # header bytes: sync; length of data (2); optional length; packet type; crc
                +                        data_length = (msg[1] << 8) + msg[2]
                +                        opt_length = msg[3]
                +                        packet_type = msg[4]
                +                        msg_length = data_length + opt_length + 7
                +                        self.logger.debug("enocean: received header with data_length = {} / opt_length = 0x{:02x} / type = {}".format(data_length, opt_length, packet_type))
                +
                +                        # break if msg is not yet complete:
                +                        if (len(msg) < msg_length):
                +                            break
                +
                +                        # msg complete
                +                        if (self._calc_crc8(msg[6:msg_length - 1]) == msg[msg_length - 1]):
                +                            self.logger.debug("enocean: accepted package with type = 0x{:02x} / len = {} / data = [{}]!".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                +                            data = msg[6:msg_length - (opt_length + 1)]
                +                            optional = msg[(6 + data_length):msg_length - 1]
                +                            if (packet_type == PACKET_TYPE_RADIO):
                +                                self._process_packet_type_radio(data, optional)
                +                            elif (packet_type == PACKET_TYPE_SMART_ACK_COMMAND):
                +                                self._process_packet_type_smart_ack_command(data, optional)
                +                            elif (packet_type == PACKET_TYPE_RESPONSE):
                +                                self._process_packet_type_response(data, optional)
                +                            elif (packet_type == PACKET_TYPE_EVENT):
                +                                self._process_packet_type_event(data, optional)
                +                            else:
                +                                self.logger.error("enocean: received packet with unknown type = 0x{:02x} - len = {} / data = [{}]".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                +                        else:
                +                            self.logger.error("enocean: crc error - dumping packet with type = 0x{:02x} / len = {} / data = [{}]!".format(packet_type, msg_length, ', '.join(['0x%02x' % b for b in msg])))
                +                        msg = msg[msg_length:]
                +                    else:
                +                        #self.logger.warning("enocean: consuming [0x{:02x}] from input buffer!".format(msg[0]))
                +                        msg.pop(0)
                +
                +    def stop(self):
                +        self.alive = False
                +        self.logger.info("enocean: Thread stopped")
                +
                +        
                +    def _send_UTE_response(self, data, optional):
                +        choice = data[0]
                +        payload = data[1:-5]
                +        #sender_id = int.from_bytes(data[-5:-1], byteorder='big', signed=False)
                +        #status = data[-1]
                +        #repeater_cnt = status & 0x0F
                +        SubTel = 0x03
                +        db = 0xFF
                +        Secu = 0x0
                +
                +        self._send_radio_packet(self.learn_id, choice, [0x91, payload[1], payload[2], payload[3], payload[4], payload[5], payload[6]],[SubTel, data[-5], data[-4], data[-3], data[-2], db, Secu] )#payload[0] = 0x91: EEP Teach-in response, Request accepted, teach-in successful, bidirectional
                +        self.UTE_listen = False
                +        self.logger.info("enocean: sending UTE response and end listening")
                +
                +    def parse_item(self, item):
                +        if 'enocean_rx_key' in item.conf:
                +            # look for info from the most specific info to the broadest (key->eep->id) - one id might use multiple eep might define multiple keys
                +            eep_item = item
                +            while (not 'enocean_rx_eep' in eep_item.conf):
                +                eep_item = eep_item.return_parent()
                +                if (eep_item is self._sh):
                +                    self.logger.error("enocean: could not find enocean_rx_eep for item {}".format(item))
                +                    return None
                +            id_item = eep_item
                +            while (not 'enocean_rx_id' in id_item.conf):
                +                id_item = id_item.return_parent()
                +                if (id_item is self._sh):
                +                    self.logger.error("enocean: could not find enocean_rx_id for item {}".format(item))
                +                    return None
                +
                +            rx_key = item.conf['enocean_rx_key'].upper()
                +            rx_eep = eep_item.conf['enocean_rx_eep'].upper()
                +            rx_id = int(id_item.conf['enocean_rx_id'],16)
                +
                +            # check if there is a function to parse payload
                +            if not self.eep_parser.CanParse(rx_eep):
                +                return None
                +
                +            if (rx_key in ['A0', 'A1', 'B0', 'B1']):
                +                self.logger.warning("enocean: key \"{}\" does not match EEP - \"0\" (Zero, number) should be \"O\" (letter) (same for \"1\" and \"I\") - will be accepted for now".format(rx_key))
                +                rx_key = rx_key.replace('0', 'O').replace("1", 'I')
                +
                +            if (not rx_id in self._rx_items):
                +                self._rx_items[rx_id] = {rx_eep: [item]}
                +            elif (not rx_eep in self._rx_items[rx_id]):
                +                self._rx_items[rx_id][rx_eep] = [item]
                +            elif (not item in self._rx_items[rx_id][rx_eep]):
                +                self._rx_items[rx_id][rx_eep].append(item)
                +
                +            self.logger.info("enocean: item {} listens to id {:08X} with eep {} key {}".format(item, rx_id, rx_eep, rx_key))
                +            #self.logger.info("enocean: self._rx_items = {}".format(self._rx_items))
                +            return self.update_item
                +
                +    def update_item(self, item, caller=None, source=None, dest=None):
                +        if caller != 'EnOcean':
                +            self.logger.debug('enocean: item updated externally')
                +            if self._block_ext_out_msg:
                +                self.logger.debug('enocean: sending manually blocked by user. Aborting')
                +                return
                +            if 'enocean_tx_eep' in item.conf:
                +                if isinstance(item.conf['enocean_tx_eep'], str):
                +                    tx_eep = item.conf['enocean_tx_eep']
                +                    self.logger.debug('enocean: item has tx_eep')
                +                    id_offset = 0
                +                    if 'enocean_tx_id_offset' in item.conf and (isinstance(item.conf['enocean_tx_id_offset'], str)):
                +                        self.logger.debug('enocean: item has valid enocean_tx_id_offset')
                +                        id_offset = int(item.conf['enocean_tx_id_offset'])
                +                    #Identify send command based on tx_eep coding:
                +                    if(tx_eep == 'A5_20_04'):
                +                        self.send_radiator_valve(id_offset)
                +                        self.logger.debug('enocean: sent A5_20_04 radiator valve command')
                +                    elif(tx_eep == 'A5_38_08_02'):
                +                        self.logger.debug('enocean: item is A5_38_08_02 type')
                +                        if not item():
                +                            self.send_dim(id_offset, 0, 0)
                +                            self.logger.debug('enocean: sent off command')
                +                        else:
                +                            if 'ref_level' in item.level.conf:
                +                                dim_value = int(item.level.conf['ref_level'])
                +                                self.logger.debug('enocean: ref_level found')
                +                            else:
                +                                dim_value = 100
                +                                self.logger.debug('enocean: no ref_level found. Setting to default 100')
                +                            self.send_dim(id_offset, dim_value, 0)
                +                            self.logger.debug('enocean: sent dim on command')
                +                    elif(tx_eep == 'A5_38_08_03'):
                +                        self.logger.debug('enocean: item is A5_38_08_03 type')
                +                        self.send_dim(id_offset, item(), 0)
                +                        self.logger.debug('enocean: sent dim command')
                +                    elif(tx_eep == 'D2_01_07'):
                +                        if 'enocean_rx_id' in item.conf:
                +                            rx_id = int(item.conf['enocean_rx_id'],16)
                +                            self.logger.debug('enocean:  enocean_rx_id found')
                +                        else:
                +                            rx_id=0
                +                            self.logger.debug('enocean:  NO enocean_rx_id found')
                +                        if 'enocean_pulsewidth' in item.conf:
                +                            pulsew = float(item.conf['enocean_pulsewidth'])
                +                            self.logger.debug('enocean:  pulsewidth found')
                +                        else:
                +                            pulsew=0
                +                            self.logger.debug('enocean:  NO pulsewidth found')
                +                        self.logger.debug('enocean: item is D2_01_07_01 type')
                +                        self.send_switch_D2(id_offset, rx_id, pulsew, item())
                +                        self.logger.debug('enocean: sent switch command for D2 VLD')
                +                    elif(tx_eep == 'A5_38_08_01'):
                +                        self.logger.debug('enocean: item is A5_38_08_01 type')
                +                        self.send_switch(id_offset, item(), 0)
                +                        self.logger.debug('enocean: sent switch command')
                +                    elif(tx_eep == '07_3F_7F'):
                +                        self.logger.debug('enocean: item is 07_3F_7F type')
                +                        self.send_rgbw_dim(id_offset, item(), 0)
                +                        self.logger.debug('enocean: sent RGBW dim command')
                +                    elif(tx_eep == 'A5_3F_7F'):
                +                        rtime=5
                +                        if 'enocean_rtime' in item.conf:
                +                            rtime = int(item.conf['enocean_rtime'])
                +                            self.logger.debug('enocean:  actuator runtime specified.')
                +                        self.logger.debug('enocean: item is A5_3F_7F type')
                +                        self.send_generic_actuator_cmd(id_offset, rtime, item())
                +                        self.logger.debug('enocean: sent actuator command')
                +                    else:
                +                        self.logger.error('enocean: error: Unknown tx eep command')
                +                else:
                +                    self.logger.error('enocean: tx_eep is not a string value')
                +            else:
                +                self.logger.debug('enocean: item has no tx_eep value')
                +
                +    def read_num_securedivices(self):
                +        self._send_common_command(CO_RD_NUMSECUREDEVICES)
                +        self.logger.info("enocean: Read number of secured devices")
                +
                +
                +        # Request all taught in smart acknowledge devices that have a mailbox
                +    def get_smart_ack_devices(self):
                +        self._send_smart_ack_command(SA_RD_LEARNEDCLIENTS)
                +        self.logger.info("enocean: Requesting all available smart acknowledge mailboxes")
                +
                +
                +    def reset_stick(self):
                +        self.logger.info("enocean: resetting device")
                +        self._send_common_command(CO_WR_RESET)
                +
                +    def block_external_out_messages(self, block=True):
                +        if block:
                +            self.logger.info("enocean: Blocking of external out messages activated")
                +            self._block_ext_out_msg = True
                +        elif not block:
                +            self.logger.info("enocean: Blocking of external out messages deactivated")
                +            self._block_ext_out_msg = False
                +        else:
                +            self.logger.info("enocean: invalid argument. Must be True/False")
                +
                +    def send_bit(self):
                +        self.logger.info("enocean: trigger Built-In Self Test telegram")
                +        self._send_common_command(CO_WR_BIST)
                +
                +    def version(self):
                +        self.logger.info("enocean: request stick version")
                +        self._send_common_command(CO_RD_VERSION)
                +
                +    def _send_packet(self, packet_type, data=[], optional=[]):
                +        length_optional = len(optional)
                +        if length_optional > 255:
                +            self.logger.error("enocean: optional too long ({} bytes, 255 allowed)".format(length_optional))
                +            return
                +        length_data = len(data)
                +        if length_data > 65535:
                +            self.logger.error("enocean: data too long ({} bytes, 65535 allowed)".format(length_data))
                +            return
                +
                +        packet = bytearray([PACKET_SYNC_BYTE])
                +        packet += length_data.to_bytes(2, byteorder='big') + bytes([length_optional, packet_type])
                +        packet += bytes([self._calc_crc8(packet[1:5])])
                +        packet += bytes(data + optional)
                +        packet += bytes([self._calc_crc8(packet[6:])])
                +        self.logger.info("enocean: sending packet with len = {} / data = [{}]!".format(len(packet), ', '.join(['0x%02x' % b for b in packet])))
                +        self._tcm.write(packet)
                +
                +    def _send_smart_ack_command(self, _code, data=[]):
                +        self._cmd_lock.acquire()
                +        self._last_cmd_code = _code
                +        self._last_packet_type = PACKET_TYPE_SMART_ACK_COMMAND
                +        self._send_packet(PACKET_TYPE_SMART_ACK_COMMAND, [_code] + data)
                +        self._response_lock.acquire()
                +        # wait 5sec for response
                +        self._response_lock.wait(5)
                +        self._response_lock.release()
                +        self._cmd_lock.release()
                +
                +    def _send_common_command(self, _code, data=[], optional=[]):
                +        self._cmd_lock.acquire()
                +        self._last_cmd_code = _code
                +        self._last_packet_type = PACKET_TYPE_COMMON_COMMAND
                +        self._send_packet(PACKET_TYPE_COMMON_COMMAND, [_code] + data, optional)
                +        self._response_lock.acquire()
                +        # wait 5sec for response
                +        self._response_lock.wait(5)
                +        self._response_lock.release()
                +        self._cmd_lock.release()
                +
                +    def _send_radio_packet(self, id_offset, _code, data=[], optional=[]):
                +        if (id_offset < 0) or (id_offset > 127):
                +            self.logger.error("enocean: invalid base ID offset range. (Is {}, must be [0 127])".format(id_offset))
                +            return
                +        self._cmd_lock.acquire()
                +        self._last_cmd_code = SENT_RADIO_PACKET
                +        self._send_packet(PACKET_TYPE_RADIO, [_code] + data + list((self.tx_id + id_offset).to_bytes(4, byteorder='big')) + [0x00], optional)
                +        self._response_lock.acquire()
                +        # wait 5sec for response
                +        self._response_lock.wait(5)
                +        self._response_lock.release()
                +        self._cmd_lock.release()
                +
                +    def send_radiator_valve(self,item, id_offset=0):
                +        self.logger.debug("enocean: sending valve command A5_20_04")
                +        temperature = item
                +        #define default values:
                +        MC  = 1 #off
                +        WUC = 3 # 120 seconds
                +        BLC = 0 # unlocked
                +        LRNB = 1# data
                +        DSO = 0 # 0 degree
                +        valve_position = 50
                +
                +        for sibling in get_children(item.parent):
                +            if hasattr(sibling, "MC"):
                +                MC = sibling()
                +            if hasattr(sibling, "WUC"):
                +                WUC = sibling()
                +            if hasattr(sibling, "BLC"):
                +                BLC = sibling()
                +            if hasattr(sibling, "LRNB"):
                +                LRNB = sibling()
                +            if hasattr(sibling, "DSO"):
                +                DSO = sibling()
                +            if hasattr(sibling, "VALVE_POSITION"):
                +                valve_position = sibling()
                +        TSP = int((temperature -10)*255/30)
                +        status =  0 + (MC << 1) + (WUC << 2) 
                +        status2 = (BLC << 5) + (LRNB << 4) + (DSO << 2) 
                +        self._send_radio_packet(id_offset, 0xA5, [valve_position, TSP, status , status2])
                +
                +
                +    def send_dim(self,id_offset=0, dim=0, dimspeed=0):
                +        if (dimspeed < 0) or (dimspeed > 255):
                +            self.logger.error("enocean: sending dim command A5_38_08: invalid range of dimspeed")
                +            return
                +        self.logger.debug("enocean: sending dim command A5_38_08")
                +        if (dim == 0):
                +            self._send_radio_packet(id_offset, 0xA5, [0x02, 0x00, int(dimspeed), 0x08])
                +        elif (dim > 0) and (dim <= 100):
                +            self._send_radio_packet(id_offset, 0xA5, [0x02, int(dim), int(dimspeed), 0x09])
                +        else:
                +            self.logger.error("enocean: sending command A5_38_08: invalid dim value")
                +
                +    def send_rgbw_dim(self,id_offset=0, color='red', dim=0, dimspeed=0):
                +        if(color == str(red)):
                +            color_hex_code = 0x10
                +        elif(color == str(green)):
                +            color_hex_code = 0x11
                +        elif(color == str(blue)):
                +            color_hex_code = 0x12
                +        elif(color == str(white)):
                +            color_hex_code = 0x13
                +        else:
                +            self.logger.error("enocean: sending rgbw dim command: invalid color")
                +            return
                +        if (dim < 0) or (dim > 1023):
                +            self.logger.error("enocean: sending rgb dim command: invalid dim value range. Only 10 bit allowed")
                +            return
                +        self._send_radio_packet(id_offset, 0x07, [ list(dim.to_bytes(2, byteorder='big')), color_hex_code, 0x0F])
                +        self.logger.debug("enocean: sent dim command 07_3F_7F")
                +
                +    def send_generic_actuator_cmd(self,id_offset=0, rtime=0, command=0):
                +        if (rtime < 0) or (rtime > 255):
                +            self.logger.error("enocean: sending switch command A5_3F_7F: invalid runtime range (0-255)")
                +            return
                +        if(command == 0):
                +            command_hex_code = 0x00
                +        elif(command == 1):
                +            command_hex_code = 0x01
                +        elif(command == 2):
                +            command_hex_code = 0x02
                +        else:
                +            self.logger.error("enocean: sending actuator command failed: invalid command" + command)
                +            return
                +        self._send_radio_packet(id_offset, 0xA5, [0x00, rtime, command_hex_code, 0x0c])
                +        self.logger.debug("enocean: sending actuator command A5_3F_7F")
                +
                +    def send_switch(self,id_offset=0, on=0, block=0):
                +        if (block < 0) and (block > 1):
                +            self.logger.error("enocean: sending switch command A5_38_08: invalid range of block (0,1)")
                +            return
                +        self.logger.debug("enocean: sending switch command A5_38_08")
                +        if (on == 0):
                +            self._send_radio_packet(id_offset, 0xA5, [0x01, 0x00, 0x00, 0x08])
                +        elif (on == 1) and (block == 0):
                +            self._send_radio_packet(id_offset, 0xA5, [0x01, 0x00, 0x00, 0x09])
                +        else:
                +            self.logger.error("enocean: sending command A5_38_08: error")
                +
                +
                +    def send_switch_D2(self, id_offset=0, rx_id=0, pulsew=0, on=0):
                +        if (id_offset < 0) or (id_offset > 127):
                +            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                +            return
                +        if (rx_id < 0) or (rx_id > 0xFFFFFFFF):
                +            self.logger.error("enocean: ID offset out of range (0-127). Aborting.")
                +            return
                +        SubTel = 0x03
                +        db = 0xFF
                +        Secu = 0x0
                +        #self._send_radio_packet(id_offset, 0xD2, [0x01, 0x1E, 0x01],[0x03, 0xFF, 0xBA, 0xD0, 0x00, 0xFF, 0x0])
                +        self.logger.info("enocean: sending switch command D2_01_07")
                +        if (on == 0):
                +            self._send_radio_packet(id_offset, 0xD2, [0x01, 0x1E, 0x00],[0x03, rx_id, 0xFF, 0x0])
                +        elif (on == 1):
                +            self._send_radio_packet(id_offset, 0xD2, [0x01, 0x1E, 0x01],[0x03, rx_id, 0xFF, 0x0])
                +            if (pulsew  > 0):
                +                time.sleep(pulsew)
                +                self._send_radio_packet(id_offset, 0xD2, [0x01, 0x1E, 0x00],[0x03, rx_id, 0xFF, 0x0])
                +        else:
                +            self.logger.error("enocean: sending command D2_01_07: error")
                +        
                +
                +####################################################
                +### --- START - Definitions of Learn Methods --- ###
                +####################################################
                +    def send_learn_protocol(self, id_offset=0, device=10):
                +        # define RORG
                +        rorg = 0xA5
                +        
                +        # check offset range between 0 and 127
                +        if (id_offset < 0) or (id_offset > 127):
                +            self.logger.error('enocean: ID offset with value = {} out of range (0-127). Aborting.'.format(id_offset))
                +            return None
                +        # device range 10 - 19 --> Learn protocol for switch actuators
                +        elif (device == 10):
                +            # Prepare Data for Eltako switch FSR61
                +            payload = [0xE0, 0x40, 0x0D, 0x80]
                +            self.logger.info('enocean: sending learn telegram for switch command with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        # device range 20 - 29 --> Learn protocol for dim actuators
                +        elif (device == 20):
                +            # Only for Eltako FSUD-230V
                +            payload = [0x02, 0x00, 0x00, 0x00]
                +            self.logger.info('enocean: sending learn telegram for dim command with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        elif (device == 21):
                +            # For Eltako FHK61SSR dim device (EEP A5-38-08)
                +            payload = [0xE0, 0x40, 0x0D, 0x80]
                +            self.logger.info('enocean: sending learn telegram for dim command with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        elif (device == 22):
                +            # For Eltako FRGBW71L RGB dim devices (EEP 07-3F-7F)
                +            payload = [0xFF, 0xF8, 0x0D, 0x87]
                +            self.logger.info('enocean: sending learn telegram for rgbw dim command with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        # device range 30 - 39 --> Learn protocol for radiator valves
                +        elif (device == 30):
                +            # Radiator Valve
                +            payload = [0x00, 0x00, 0x00, 0x00]
                +            self.logger.info('enocean: sending learn telegram for radiator valve with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        # device range 40 - 49 --> Learn protocol for other actuators
                +        elif (device == 40):
                +            # Eltako shutter actor FSB14, FSB61, FSB71
                +             payload = [0xFF, 0xF8, 0x0D, 0x80]
                +             self.logger.info('enocean: sending learn telegram for actuator with [Device], [ID-Offset], [RORG], [payload] / [{}], [{:#04x}], [{:#04x}], [{}]'.format(device, id_offset, rorg, ', '.join('{:#04x}'.format(x) for x in payload)))
                +        else:
                +            self.logger.error('enocean: sending learn telegram with invalid device! Device {} actually not defined!'.format(device))
                +            return None
                +        # Send radio package
                +        self._send_radio_packet(id_offset, rorg, payload)
                +        return None
                +
                +
                +    def start_UTE_learnmode(self, id_offset=0):
                +        self.UTE_listen = True
                +        self.learn_id = id_offset
                +        self.logger.info("enocean: Listeining for UTE package ('D4')")
                +        
                +        
                +    def enter_learn_mode(self, onoff=1):
                +        if (onoff == 1):
                +            self._send_common_command(CO_WR_LEARNMODE, [0x01, 0x00, 0x00, 0x00, 0x00],[0xFF])
                +            self.logger.info("enocean: entering learning mode")
                +            return None
                +        else:
                +            self._send_common_command(CO_WR_LEARNMODE, [0x00, 0x00, 0x00, 0x00, 0x00],[0xFF])
                +            self.logger.info("enocean: leaving learning mode")
                +            return None
                +
                +            
                +    # This function enables/disables the controller's smart acknowledge mode
                +    def set_smart_ack_learn_mode(self, onoff=1):
                +        if (onoff == 1):
                +            self._send_smart_ack_command(SA_WR_LEARNMODE, [0x01, 0x00, 0x00, 0x00, 0x00, 0x00])
                +            self.logger.info("enocean: enabling smart acknowledge learning mode")
                +            return None
                +        else:
                +            self._send_smart_ack_command(SA_WR_LEARNMODE, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
                +            self.logger.info("enocean: disabling smart acknowledge learning mode")
                +            return None
                +
                +##################################################
                +### --- END - Definitions of Learn Methods --- ###
                +##################################################
                +
                +
                +#################################
                +### --- START - Calc CRC8 --- ###
                +#################################
                +    def _calc_crc8(self, msg, crc=0):
                +        for i in msg:
                +            crc = FCSTAB[crc ^ i]
                +        return crc
                +
                +###############################
                +### --- END - Calc CRC8 --- ###
                +###############################
                diff --git a/enocean/eep_parser.py b/enocean/eep_parser.py
                index 1e737cf8d..24d913ce8 100644
                --- a/enocean/eep_parser.py
                +++ b/enocean/eep_parser.py
                @@ -13,11 +13,14 @@ def CanParse(self, eep):
                         return found
                 
                     def Parse(self, eep, payload, status):
                -        #self.logger.debug('enocean: parser called with eep={} / payload={} / status={}'.format(eep, payload, status))
                +        #self.logger.debug('enocean: parser called with eep = {} / payload = {} / status = {}'.format(eep, ', '.join(hex(x) for x in payload), hex(status)))
                         results = getattr(self, "_parse_eep_" + eep)(payload, status)
                         #self.logger.info('enocean: parser returns {}'.format(results))
                         return results
                 
                +#####################################################
                +### --- Definitions for RORG =  A5 / ORG = 07 --- ###
                +#####################################################
                     def _parse_eep_A5_02_01(self, payload, status):
                         return {'TMP': (0 - (payload[2] * 40 / 255))}
                 
                @@ -100,45 +103,69 @@ def _parse_eep_A5_04_01(self, payload, status):
                         return result
                 
                     def _parse_eep_A5_04_02(self, payload, status):
                -        # Energy (optional), humidity and temperature, for example eltako FBH65TFB, RORG = 0x07
                +        # Energy (optional), humidity and temperature, for example eltako FBH65TFB
                         result = {}
                -        result['ENG'] = 0.47 + (payload[0] * 1.5 / 66)       # voltage of energy buffer in Volts
                -        result['HUM'] = (payload[1] / 250.0 * 100)           # relative humidity in percent
                -        result['TMP'] = -20.0 + (payload[2] / 250.0 * 80.0)  # temperature in degree Celsius from -20.0 degC - 60degC
                +        # voltage of energy buffer in Volts
                +        result['ENG'] = 0.47 + (payload[0] * 1.5 / 66)
                +        # relative humidity in percent
                +        result['HUM'] = (payload[1] / 250.0 * 100)
                +        # temperature in degree Celsius from -20.0 degC - 60degC
                +        result['TMP'] = -20.0 + (payload[2] / 250.0 * 80.0)
                +        return result
                +        
                +    def _parse_eep_A5_06_01(self, payload, status):
                +        # Brightness sensor, for example Eltako FAH60
                +        self.logger.debug('enocean: parsing A5_06_01: Brightness sensor')
                +        result = {}
                +        # Calculation of brightness in lux
                +        if (payload[3] == 0x0F) and (payload[1] > 0x00) and (payload[1] <= 0xFF):
                +            # If Data-Messege AND DataByte 2 is between: 0x00 = 300 lux and 0xFF = 30.000 lux
                +            result['BRI'] = round(((payload[1] / 255.0 * (30000 - 300)) + 300), 2)
                +        elif (payload[3] == 0x0F) and (payload[1] == 0x00):
                +            # If Data-Messege AND DataByte 2: 0x00 then read DataByte 3
                +            result['BRI'] = (payload[0])
                +        else:
                +            # No Data Message
                +            result['BRI'] = (-1)
                +        # only trigger the logger info when 'BRI' > 0
                +        if (result['BRI'] > 0):
                +            self.logger.info('enocean: brightness: {0}'.format(result['BRI']))
                         return result
                 
                     def _parse_eep_A5_08_01(self, payload, status):
                -        # Brightness and movement sensor, for example eltako FBH65TFB, RORG = 0x07
                -        #logger.debug("enocean: parsing A5_08_01: Movement sensor")
                +        # Brightness and movement sensor, for example eltako FBH65TFB
                +        self.logger.debug("enocean: parsing A5_08_01: Movement sensor")
                         result = {}
                         result['BRI'] = (payload[1] / 255.0 * 2048)          # brightness in lux
                         result['MOV'] = not ((payload[3] & 0x02) == 0x02)    # movement
                -        #logger.debug("enocean: movement: {0}, brightness: {1}".format(result['MOV'],result['BRI']))
                -        #logger.debug("enocean: movement data byte0: {0}".format(payload[3]))
                +        #self.logger.debug("enocean: movement: {0}, brightness: {1}".format(result['MOV'],result['BRI']))
                +        #self.logger.debug("enocean: movement data byte0: {0}".format(payload[3]))
                         return result
                 
                     def _parse_eep_A5_11_04(self, payload, status):
                -        #4 Byte communication (4BS) Telegramm, RORG = A5 = ORG = 0x07
                +        # 4 Byte communication (4BS) Telegramm
                         # For example dim status feedback from eltako FSUD-230 actor.
                -        #Data_byte3 = 0x02
                -        #Data_byte2 = Dimmwert in % von 0-100 dez.
                -        #Data_byte1 = 0x00
                -        #Data_byte0 = 0x08 = Dimmer aus, 0x09 = Dimmer an
                -        #logger.debug("enocean: processing A5_11_04: Dimmer Status on/off")
                +        # Data_byte3 = 0x02
                +        # Data_byte2 = Dimmwert in % von 0-100 dez.
                +        # Data_byte1 = 0x00
                +        # Data_byte0 = 0x08 = Dimmer aus, 0x09 = Dimmer an
                +        self.logger.debug("enocean: processing A5_11_04: Dimmer Status on/off")
                         results = {}
                -        #if !( (payload[0] == 0x02) and (payload[2] == 0x00)):
                -        #    logger.error("enocean: error in processing A5_11_04: static byte missmatch")
                +        # if !( (payload[0] == 0x02) and (payload[2] == 0x00)):
                +        #    self.logger.error("enocean: error in processing A5_11_04: static byte missmatch")
                         #    return results
                         results['D'] = payload[1]
                -        if (payload[3] == 0x08):               # Dimmer is off
                +        if (payload[3] == 0x08):
                +            # Dimmer is off
                             results['STAT'] = 0
                -        elif (payload[3] == 0x09):             # Dimmer is on
                +        elif (payload[3] == 0x09):
                +            # Dimmer is on
                             results['STAT'] = 1
                         return results
                 
                     def _parse_eep_A5_12_01(self, payload, status):
                -        # Status command from switche actor with powermeter, for example eltako FSVA-230, RORG = 0x07
                -        #logger.debug("enocean: processing A5_12_01")
                +        # Status command from switche actor with powermeter, for example eltako FSVA-230
                +        self.logger.debug("enocean: processing A5_12_01")
                         results = {}
                         status = payload[3]
                         value = (payload[0] << 16) + (payload[1] << 8) + payload[2]
                @@ -146,22 +173,25 @@ def _parse_eep_A5_12_01(self, payload, status):
                         return results
                 
                     def _parse_eep_A5_20_04(self, payload, status):
                -        # Status command from heating radiator valve, for example Hora smartdrive MX, RORG = 0x07
                -        #logger.debug("enocean: processing A5_20_04")
                +        # Status command from heating radiator valve, for example Hora smartdrive MX
                +        self.logger.debug("enocean: processing A5_20_04")
                         results = {}
                         status_byte = payload[3]
                -        TS = ((status_byte & 1 << 6) == 1 << 6) #1: temperature setpoint, 0: feed temperature
                -        FL = ((status_byte & 1 << 7) == 1 << 7) #1: failure, 0: normal
                -        BLS= ((status_byte& 1 << 5) == 1 << 5)  #1: locked, 0: unlocked
                +        #1: temperature setpoint, 0: feed temperature
                +        TS = ((status_byte & 1 << 6) == 1 << 6)
                +        #1: failure, 0: normal
                +        FL = ((status_byte & 1 << 7) == 1 << 7)
                +        #1: locked, 0: unlocked
                +        BLS= ((status_byte& 1 << 5) == 1 << 5)
                         results['BLS'] = BLS
                         # current valve position 0-100%
                         results['CP'] = payload[0]
                -        #Current feet temperature or setpoint
                +        # Current feet temperature or setpoint
                         if(TS == 1):
                             results['TS'] = 10 + (payload[1]/255*20)
                         else:
                            results['FT'] = 20 + (payload[1]/255*60)
                -        #Current room temperature or failure code
                +        # Current room temperature or failure code
                         if (FL == 0): 
                             results['TMP'] = 10 + (payload[2]/255*20)
                         else: 
                @@ -181,21 +211,45 @@ def _parse_eep_A5_38_08(self, payload, status):
                         return results
                 
                     def _parse_eep_A5_3F_7F(self, payload, status):
                -        #logger.debug("enocean: processing A5_3F_7F")
                +        self.logger.debug("enocean: processing A5_3F_7F")
                         results = {'DI_3': (payload[3] & 1 << 3) == 1 << 3, 'DI_2': (payload[3] & 1 << 2) == 1 << 2, 'DI_1': (payload[3] & 1 << 1) == 1 << 1, 'DI_0': (payload[3] & 1 << 0) == 1 << 0}
                         results['AD_0'] = (((payload[1] & 0x03) << 8) + payload[2]) * 1.8 / pow(2, 10)
                         results['AD_1'] = (payload[1] >> 2) * 1.8 / pow(2, 6)
                         results['AD_2'] = payload[0] * 1.8 / pow(2, 8)
                         return results
                 
                +#####################################################
                +### --- Definitions for RORG = D2  / ORG = D2 --- ###
                +#####################################################
                +    def _parse_eep_D2_01_07(self, payload, status):
                +        # self.logger.debug("enocean: processing D2_01_07: VLD Switch")
                +        results = {}
                +        # self.logger.info('enocean: D2 Switch Feedback  0:{} 1:{} 2:{}').format(payload[0],payload[1],payload[2])
                +        if (payload[2] == 0x80):
                +            # Switch is off
                +            results['STAT'] = 0
                +            self.logger.debug('enocean: D2 Switch off')
                +        elif (payload[2] == 0xe4):
                +            # Switch is on
                +            results['STAT'] = 1
                +            self.logger.debug('enocean: D2 Switch on')
                +        return results
                +
                +
                +####################################################
                +### --- Definitions for RORG = D5 / ORG = 06 --- ###
                +####################################################
                     def _parse_eep_D5_00_01(self, payload, status):
                -        #ORG = 0x06
                -        #Window/Door Contact Sensor, for example Eltako FTK, FTKB
                -        #logger.debug("enocean: processing D5_00_01: Door contact")
                +        # Window/Door Contact Sensor, for example Eltako FTK, FTKB
                +        self.logger.debug("enocean: processing D5_00_01: Door contact")
                         return {'STATUS': (payload[0] & 0x01) == 0x01}
                 
                +
                +####################################################
                +### --- Definitions for RORG = F6 / ORG = 05 --- ###
                +####################################################
                     def _parse_eep_F6_02_01(self, payload, status):
                -        #logger.debug("enocean: processing F6_02_01: Rocker Switch, 2 Rocker, Light and Blind Control - Application Style 1")
                +        self.logger.debug("enocean: processing F6_02_01: Rocker Switch, 2 Rocker, Light and Blind Control - Application Style 1")
                         results = {}
                         R1 = (payload[0] & 0xE0) >> 5
                         EB = (payload[0] & (1<<4) == (1<<4))
                @@ -216,21 +270,21 @@ def _parse_eep_F6_02_01(self, payload, status):
                         return results
                 
                     def _parse_eep_F6_02_02(self, payload, status):
                -        #logger.debug("enocean: processing F6_02_02: Rocker Switch, 2 Rocker, Light and Blind Control - Application Style 2")
                +        self.logger.debug("enocean: processing F6_02_02: Rocker Switch, 2 Rocker, Light and Blind Control - Application Style 2")
                         return self._parse_eep_F6_02_01(payload, status)
                 
                     def _parse_eep_F6_02_03(self, payload, status):
                -        #Repeated switch communication(RPS) Telegramm, RORG = F6 = ORG = 0x05
                +        # Repeated switch communication(RPS) Telegramm
                         # Status command from bidirectional actors, for example eltako FSUD-230, FSVA-230V or switches (for example Gira)
                -        #logger.debug("enocean: processing F6_02_03: Rocker Switch, 2 Rocker")
                +        #self.logger.debug("enocean: processing F6_02_03: Rocker Switch, 2 Rocker")
                         results = {}
                -        #Button A1: Dimm light down
                +        # Button A1: Dimm light down
                         results['AI'] = (payload[0]) == 0x10
                -        #Button A0: Dimm light up
                +        # Button A0: Dimm light up
                         results['AO'] = (payload[0]) == 0x30
                -        #Button B1: Dimm light down
                +        # Button B1: Dimm light down
                         results['BI'] = (payload[0]) == 0x50
                -        #Button B0: Dimm light up
                +        # Button B0: Dimm light up
                         results['BO'] = (payload[0]) == 0x70
                         if (payload[0] == 0x70):
                             results['B'] = True
                @@ -240,10 +294,13 @@ def _parse_eep_F6_02_03(self, payload, status):
                             results['A'] = True
                         elif (payload[0] == 0x10):
                             results['A'] = False
                +        # special extension for ELTAKO FSB61NP-230V status message compatibility:
                +        elif (payload[0] == 0x02): 
                +            results['B'] = False
                         return results
                 
                     def _parse_eep_F6_10_00(self, payload, status):
                -        #logger.debug("enocean: processing F6_10_00: Mechanical Handle")
                +        self.logger.debug("enocean: processing F6_10_00: Mechanical Handle")
                         results = {}
                         if (payload[0] == 0xF0):
                             results['STATUS'] = 0
                diff --git a/enocean/plugin.yaml b/enocean/plugin.yaml
                new file mode 100755
                index 000000000..70207db65
                --- /dev/null
                +++ b/enocean/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Enocean Unterstützung'
                +        en: ''
                +    maintainer: '? (Robert Budde / aschwith)'
                +#    tester:                        # Who tests this plugin?
                +    keywords: enocean
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.3                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: EnOcean             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/eta_pu/plugin.yaml b/eta_pu/plugin.yaml
                new file mode 100755
                index 000000000..98cdad3be
                --- /dev/null
                +++ b/eta_pu/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung der REST-Schnittstelle von ETA Heizungen'
                +        en: ''
                +    maintainer: '? (Brootux)'
                +    tester: 'psilo909, ?'
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: ETA_PU              # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/gpio/plugin.yaml b/gpio/plugin.yaml
                new file mode 100755
                index 000000000..9c6f42548
                --- /dev/null
                +++ b/gpio/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'GPIO Unterstützung für Rasberry Pi, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: onkelandy
                +    tester: cmalo, ohinckel
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.0.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Raspi_GPIO          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/harmony/README.md b/harmony/README.md
                index b4895f524..091c2b211 100644
                --- a/harmony/README.md
                +++ b/harmony/README.md
                @@ -191,7 +191,7 @@ the attribute ```harmony_item = current_activity_id```
                 
                 ```
                 [MyItem]
                -    type = num
                +    type = str
                     enforce_updates = true
                     harmony_item = current_activity_name
                 ```
                @@ -229,4 +229,4 @@ Harmony Hub activity 'Power Off' is triggered
                 
                 This command starts the Harmony Hub activity with the id 12345123 (e.g. 'start movie scene'). After a delay of 2 
                 seconds, the input channel of the AV receiver is switched to SAT/Cbl. 0.3 seconds later, a '3' is triggered and 
                -committed with a 'Select' command.
                \ No newline at end of file
                +committed with a 'Select' command.
                diff --git a/harmony/plugin.yaml b/harmony/plugin.yaml
                new file mode 100755
                index 000000000..8f49815b3
                --- /dev/null
                +++ b/harmony/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Harmony Hub plugin, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: pfischi
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1046500-harmony-hub-plugin
                +
                +    version: 1.3.0.5               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Harmony             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/helios/plugin.yaml b/helios/plugin.yaml
                new file mode 100755
                index 000000000..31ad29d46
                --- /dev/null
                +++ b/helios/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Helios EC x00 Pro / Vallox SE KWL Plugin (Modellserien bis 2014)'
                +        en: ''
                +    maintainer: mtiews, Tom-Bom-badil
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +    documentation: https://github.com/Tom-Bom-badil/helios/wiki        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/40092-erweiterung-helios-vallox-plugin
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: HeliosBase          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/homematic/README.md b/homematic/README.md
                index 4170dc924..3a2fa621a 100644
                --- a/homematic/README.md
                +++ b/homematic/README.md
                @@ -13,7 +13,8 @@ Homematic Hardware Gateway
                     class_name = Homematic
                     class_path = plugins.homematic
                     host = 192.168.50.250
                -    port = 2001
                +    # port = 2001
                +    # cycle = 60
                 ```
                 
                 ## items.conf
                @@ -25,3 +26,21 @@ Homematic Hardware Gateway
                         hm_address = JEQ0017982
                         hm_type = switch
                 ```
                +
                +### hm_type
                +
                +Possible values
                +
                +- for switches:
                +
                +  - switch
                +  - 2ch_switch
                +
                +- for raffstores:
                +
                +  - pos
                +  - stop
                +  - move
                +
                +
                +
                diff --git a/homematic/__init__.py b/homematic/__init__.py
                index 8e8905d26..96c561918 100644
                --- a/homematic/__init__.py
                +++ b/homematic/__init__.py
                @@ -27,20 +27,35 @@
                 import xmlrpc.server
                 import xmlrpc.client
                 
                +
                 class Homematic():
                 
                -    def __init__(self, smarthome, host='0.0.0.0', port='2001'):
                +    def __init__(self, smarthome, host='0.0.0.0', port='2001', cycle='60'):
                         self.logger = logging.getLogger(__name__)
                         self.sh = smarthome
                         self.host = host
                         self.port = port
                +        self._cycle = int(cycle)
                         self.korrektur = 0
                -    
                +
                +
                     def run(self):
                +        """
                +        Run method for the plugin
                +        """
                +        self.sh.scheduler.add(__name__, self._update_loop, cycle=self._cycle)
                +#        self.scheduler_add('update', self._update_loop, cycle=self._cycle)
                +        self.alive = True
                +
                +
                +    def _update_loop(self):
                +        """
                +        Starts the update loop for all known items.
                +        """
                         server_url = 'http://' + self.host + ':' + self.port + '/'
                         self.server = xmlrpc.client.ServerProxy(server_url)
                         self.load_status()
                -        self.alive = True
                +
                 
                     def load_status(self):
                         for hm_devices in self.sh.find_items('hm_type'):
                diff --git a/homematic/plugin.yaml b/homematic/plugin.yaml
                new file mode 100755
                index 000000000..4e9db5dd8
                --- /dev/null
                +++ b/homematic/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Steuerung von Buderus Heizkesseln über ein Logamatic web KM200 Modul (noch in der Entwicklung)'
                +        en: ''
                +    maintainer: rthill             # Who maintains this plugin?
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Homematic            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/hue/__init__.py b/hue/__init__.py
                index 646e7f224..1b6bf7145 100755
                --- a/hue/__init__.py
                +++ b/hue/__init__.py
                @@ -1,9 +1,25 @@
                 #!/usr/bin/env python3
                -# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +# -*- coding: utf8 -*-
                +#########################################################################
                +# Copyright 2017-       Martin Sinn                         m.sinn@gmx.de
                +# Copyright 2014-2016   Michael Würtenberger             
                +#########################################################################
                +#  Philips Hue plugin for SmartHomeNG
                 #
                -#  Copyright (C) 2014,2015,2016 Michael Würtenberger
                +#  This plugin is free software: you can redistribute it and/or modify
                +#  it under the terms of the Apache License APL2.0 as published by
                +#  the Apache Software Foundation.
                 #
                -#  Version 1.83 developNG
                +#  This plugin is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  Apache License for more details.
                +#
                +#  You should have received a copy of the Apache Software License along
                +#  with this plugin. If not, see <https://www.apache.org/licenses/>.
                +#########################################################################
                +
                +
                 #
                 #  Erstanlage mit ersten Tests
                 #  Basiert auf den Ueberlegungen des verhandenen Hue Plugins.
                @@ -20,7 +36,7 @@
                 #
                 #  Library for RGB / CIE1931 coversion ported from Bryan Johnson's JavaScript implementation:
                 #  https://github.com/bjohnso5/hue-hacking
                -#  extension to use differen triangle points depending of the type of the hue system
                +#  extension to use different triangle points depending of the type of the hue system
                 # 
                 
                 import logging
                @@ -30,54 +46,50 @@
                 import http.client
                 import time
                 import threading
                +
                 from lib.tools import Tools
                +from lib.model.smartplugin import SmartPlugin
                +from lib.utils import Utils
                 
                 XY = namedtuple('XY', ['x', 'y'])
                -logger = logging.getLogger('HUE:')
                 client = Tools()
                 
                -class HUE():
                +class HUE(SmartPlugin):
                +
                +    PLUGIN_VERSION = "1.4.2"
                 
                     def __init__(self, smarthome, hue_ip = '', hue_user = '', hue_port = '80', cycle_lamps = '10', cycle_bridges = '60', default_transitionTime = '0.4'):
                 
                -        # parameter zu übergabe aus der konfiguration pulgin.conf
                -        self._sh = smarthome
                -        # parmeter übernehmen, aufteilen
                -        if type(hue_ip) == 'list':
                -            self._hue_ip = hue_ip
                -            self._hue_user = hue_user
                -            self._hue_port = hue_port
                -        else:
                -            self._hue_ip = [hue_ip]
                -            self._hue_user = [hue_user]
                -            self._hue_port = [hue_port]
                +        self.logger = logging.getLogger(__name__)
                +
                +#        self.logger.warning("self._parameters = {}".format(str(self._parameters)))
                +        # parameter zu übergabe aus der konfiguration plugin.conf
                +        self._hue_ip = self.get_parameter_value('hue_ip')
                +        self._hue_user = self.get_parameter_value('hue_user')
                +        self._hue_port = self.get_parameter_value('hue_port')
                +#        self.logger.warning("self._hue_ip = {}, self._hue_user = {}, self._hue_port = {}".format(self._hue_ip, self._hue_user, self._hue_port))
                +
                         # verabreitung der parameter aus der plugin.conf
                         self._numberHueBridges = len(self._hue_ip)
                +
                         if len(self._hue_port) != self._numberHueBridges or len(self._hue_user) != self._numberHueBridges:
                -            logger.error('HUE: Error in plugin.conf: if you specify more than 1 bridge, all parameters hue_ip, hue_user and hue_port have to be defined')
                -            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +            self.logger.error('Error in plugin.conf: if you specify more than 1 bridge, all parameters hue_ip, hue_user and hue_port have to be defined')
                +            self._init_complete = False
                +            return
                         if '' in self._hue_user:
                -            logger.error('HUE: Error in plugin.conf: you have to specify all hue_user')
                -            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                -        if '' in self._hue_ip:
                -            logger.error('HUE: Error in plugin.conf: you have to specify all hue_ip')
                -            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +            self.logger.error('Error in plugin.conf: you have to specify all hue_user')
                +            self._init_complete = False
                +            return
                         if '' in self._hue_port:
                -            logger.error('HUE: Error in plugin.conf: you have to specify all hue_port')
                -            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                -        self._cycle_lampsGroups = int(cycle_lamps)
                -        if self._cycle_lampsGroups < 5:
                -            # beschränkung der wiederholrate 
                -            self._cycle_lampsGroups = 5
                -        self._cycle_bridges = int(cycle_bridges)
                -        if self._cycle_bridges < 10:
                -            # beschränkung der wiederholrate 
                -            self._cycle_bridges = 10
                -        self._hueDefaultTransitionTime = float(default_transitionTime)
                -        if self._hueDefaultTransitionTime < 0:
                -            # beschränkung der wiederholrate 
                -            logger.warning('HUE: Error in plugin.conf: the default_transitionTime parameter cannot be negative. It is set to 0')
                -            self._hueDefaultTransitionTime = 0
                +            self.logger.error('Error in plugin.conf: you have to specify all hue_port')
                +            self._init_complete = False
                +            return
                +
                +        self._cycle_lampsGroups = self.get_parameter_value('cycle_lamps')
                +        self._cycle_bridges = self.get_parameter_value('cycle_bridges')
                +        self._hueDefaultTransitionTime = self.get_parameter_value('default_transitionTime')
                +
                +
                         # variablen zur steuerung des plugins
                         # hier werden alle bekannte items für lampen eingetragen
                         self._sendLampItems = {}
                @@ -128,11 +140,11 @@ def __init__(self, smarthome, hue_ip = '', hue_user = '', hue_port = '80', cycle
                         self.Blue =[XY(0.168, 0.041), XY(0.139, 0.081), XY(0.0, 0.0)]
                         # Konfigurationen zur laufzeit
                         # scheduler für das polling des status der lampen über die hue bridge
                -        self._sh.scheduler.add('hue-update-lamps', self._update_lamps, cycle = self._cycle_lampsGroups)
                +        self.scheduler_add('update-lamps', self._update_lamps, cycle = self._cycle_lampsGroups)
                         # scheduler für das polling des status der lampen über die hue bridge
                -        self._sh.scheduler.add('hue-update-groups', self._update_groups, cycle = self._cycle_lampsGroups)
                +        self.scheduler_add('update-groups', self._update_groups, cycle = self._cycle_lampsGroups)
                         # scheduler für das polling des status der hue bridge
                -        self._sh.scheduler.add('hue-update-bridges', self._update_bridges, cycle = self._cycle_bridges)
                +        self.scheduler_add('update-bridges', self._update_bridges, cycle = self._cycle_bridges)
                 
                     ### following the library parts of the rewritten topics
                     def crossProduct(self, p1, p2):
                @@ -214,18 +226,18 @@ def _find_item_attribute(self, item, attribute, attributeDefault, attributeLimit
                             if (itemSearch is self._sh):
                                 # wir sind am root knoten angekommen und haben nichts gefunden !
                                 if attribute == 'hue_bridge_id' and self._numberHueBridges > 1:
                -                    logger.warning('HUE: _find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                +                    self.logger.warning('_find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                                 elif attribute == 'hue_lamp_type':
                -                    logger.warning('HUE: _find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                +                    self.logger.warning('_find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                                 elif attribute == 'hue_lamp_id':
                -                    logger.error('HUE: _find_item_attribute: could not find [{0}] for item [{1}], an value has to be defined'.format(attribute, item))
                -                    raise Exception('HUE: Plugin stopped due to missing hue_lamp_id in item.conf')
                +                    self.logger.error('_find_item_attribute: could not find [{0}] for item [{1}], an value has to be defined'.format(attribute, item))
                +                    raise Exception('Plugin stopped due to missing hue_lamp_id in item.conf')
                                 # wenn nicht gefunden, dann wird der standardwert zurückgegeben
                                 return str(attributeDefault)
                         itemAttribute = int(itemSearch.conf[attribute])
                         if itemAttribute >= attributeLimit:
                             itemAttribute = attributeLimit
                -            logger.warning('HUE: _find_item_attribute: attribute [{0}] exceeds upper limit and set to default in item [{1}]'.format(attribute,item))
                +            self.logger.warning('_find_item_attribute: attribute [{0}] exceeds upper limit and set to default in item [{1}]'.format(attribute,item))
                         return str(itemAttribute)
                     
                     def parse_item(self, item):
                @@ -237,10 +249,10 @@ def parse_item(self, item):
                         if 'hue_dim_max' in item.conf:
                             if not 'hue_dim_step' in item.conf:
                                 item.conf['hue_dim_step'] = '25'
                -                logger.warning('HUE: dimmenDPT3: no hue_dim_step defined in item [{0}] using default 25'.format(item))
                +                self.logger.warning('dimmenDPT3: no hue_dim_step defined in item [{0}] using default 25'.format(item))
                             if not 'hue_dim_time' in item.conf:
                                 item.conf['hue_dim_time'] = '1'
                -                logger.warning('HUE: dimmenDPT3: no hue_dim_time defined in item [{0}] using default 1'.format(item))
                +                self.logger.warning('dimmenDPT3: no hue_dim_time defined in item [{0}] using default 1'.format(item))
                             return self.dimmenDPT3
                 
                         if 'hue_listen' in item.conf:
                @@ -257,7 +269,7 @@ def parse_item(self, item):
                                 if not hueIndex in self._listenLampItems:
                                     self._listenLampItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in lamp item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                +                    self.logger.warning('parse_item: in lamp item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                             elif hueListenCommand in self._listenBridgeKeys:
                                 # hier brauche ich nur eine hue_bridge_id
                                 hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                @@ -266,9 +278,9 @@ def parse_item(self, item):
                                 if not hueIndex in self._listenBridgeItems:
                                     self._listenBridgeItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in bridge item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                +                    self.logger.warning('parse_item: in bridge item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                             else:
                -                logger.error('HUE: parse_item: command hue_listen = {0} not defined in item [{1}]'.format(hueListenCommand,item))
                +                self.logger.error('parse_item: command hue_listen = {0} not defined in item [{1}]'.format(hueListenCommand,item))
                 
                         # für die groups brauchen wir eine eigenes listen attribut, weil die kommandos gleich denen der lampen sind damit schwer nur unterscheidbar
                         if 'hue_listen_group' in item.conf:
                @@ -283,7 +295,7 @@ def parse_item(self, item):
                                 if not hueIndex in self._listenGroupItems:
                                     self._listenGroupItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in group item [{0}] command hue_listen_group = {1} is duplicated to item  [{2}]'.format(item,hueListenGroupCommand,self._listenGroupItems[hueIndex]))
                +                    self.logger.warning('parse_item: in group item [{0}] command hue_listen_group = {1} is duplicated to item  [{2}]'.format(item,hueListenGroupCommand,self._listenGroupItems[hueIndex]))
                         
                         if 'hue_send' in item.conf:
                             hueSendCommand = item.conf['hue_send']
                @@ -299,7 +311,7 @@ def parse_item(self, item):
                                 if not hueIndex in self._sendLampItems:
                                     self._sendLampItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in lamp item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                +                    self.logger.warning('parse_item: in lamp item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                                 return self.update_lamp_item
                             elif hueSendCommand in self._sendBridgeKeys:
                                 # hier brauche ich nur eine hue_bridge_id
                @@ -309,10 +321,10 @@ def parse_item(self, item):
                                 if not hueIndex in self._sendBridgeItems:
                                     self._sendBridgeItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in bridge item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                +                    self.logger.warning('parse_item: in bridge item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                                 return self.update_bridge_item
                             else:
                -                logger.error('HUE: parse_item: command hue_send = {0} not defined in item [{1}]'.format(hueSendCommand,item))
                +                self.logger.error('parse_item: command hue_send = {0} not defined in item [{1}]'.format(hueSendCommand,item))
                 
                         # für die groups brauchen wir eine eigenes listen attribut, weil die kommandos gleich denen der lampen sind damit schwer nur unterscheidbar
                         if 'hue_send_group' in item.conf:
                @@ -327,7 +339,7 @@ def parse_item(self, item):
                                 if not hueIndex in self._sendGroupItems:
                                     self._sendGroupItems[hueIndex] = item
                                 else:
                -                    logger.warning('HUE: parse_item: in group item [{0}] command hue_send_group = {1} is duplicated to item  [{2}]'.format(item,hueSendGroupCommand,self._sendGroupItems[hueIndex]))
                +                    self.logger.warning('parse_item: in group item [{0}] command hue_send_group = {1} is duplicated to item  [{2}]'.format(item,hueSendGroupCommand,self._sendGroupItems[hueIndex]))
                                 return self.update_group_item
                 
                     def _limit_range_int(self, value, minValue, maxValue):
                @@ -362,7 +374,7 @@ def update_lamp_item(self, item, caller=None, source=None, dest=None):
                             if hueIndex + '.on' in self._sendLampItems:
                                 hueLampIsOn = self._sendLampItems[(hueIndex + '.on')]()
                             else:
                -                logger.warning('HUE: update_lamp_item: no item for on/off defined for bridge {0} lampe {1}'.format(hueBridgeId, hueLampId))
                +                self.logger.warning('update_lamp_item: no item for on/off defined for bridge {0} lampe {1}'.format(hueBridgeId, hueLampId))
                                 hueLampIsOn = False
                                 
                             # test aus die wertgrenzen, die die bridge verstehen kann
                @@ -393,7 +405,7 @@ def update_lamp_item(self, item, caller=None, source=None, dest=None):
                                     else:
                                         # ansonst wird nur eingeschaltet
                                         self._set_lamp_state(hueBridgeId, hueLampId, {'on': True , 'transitiontime': hueTransitionTime})
                -                        logger.info('HUE: update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                +                        self.logger.info('update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                                 else:
                                     # anderer befehl gegeben
                                     if hueSend in self._rgbKeys:
                @@ -408,7 +420,7 @@ def update_lamp_item(self, item, caller=None, source=None, dest=None):
                                             # und jetzt der wert setzen
                                             self._set_lamp_state(hueBridgeId, hueLampId, {'xy': xyPoint, 'transitiontime': hueTransitionTime})
                                         else:
                -                            logger.warning('HUE: update_lamp_item: on or more of the col... items around item [{0}] is not defined'.format(item))
                +                            self.logger.warning('update_lamp_item: on or more of the col... items around item [{0}] is not defined'.format(item))
                                     else:
                                         # standardbefehle
                                         self._set_lamp_state(hueBridgeId, hueLampId, {hueSend: value, 'transitiontime': hueTransitionTime})
                @@ -448,7 +460,7 @@ def update_group_item(self, item, caller=None, source=None, dest=None):
                             if hueIndex + '.on' in self._sendGroupItems:
                                 hueGroupIsOn = self._sendGroupItems[(hueIndex + '.on')]()
                             else:
                -                logger.warning('HUE: update_group_item: no item for on/off defined for bridge {0} group {1}'.format(hueBridgeId, hueGroupId))
                +                self.logger.warning('update_group_item: no item for on/off defined for bridge {0} group {1}'.format(hueBridgeId, hueGroupId))
                                 hueGroupIsOn = False
                                 
                             # test aus die wertgrenzen, die die bridge verstehen kann
                @@ -473,7 +485,7 @@ def update_group_item(self, item, caller=None, source=None, dest=None):
                                     else:
                                         # ansonst wird nur eingeschaltet
                                         self._set_group_state(hueBridgeId, hueGroupId, {'on': True , 'transitiontime': hueTransitionTime})
                -                        logger.info('HUE: update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                +                        self.logger.info('update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                                 else:
                                     # standardbefehle
                                     self._set_group_state(hueBridgeId, hueGroupId, {hueSendGroup: value, 'transitiontime': hueTransitionTime})
                @@ -546,13 +558,9 @@ def  _get_web_content(self, hueBridgeId='0', path='', method='GET', body=None):
                             errorItem = self._listenBridgeItems[hueBridgeId + '.' + 'errorstatus']
                         else:
                             errorItem = None
                -            logger.info('HUE: _get_web_content '+hueBridgeId)
                +            self.logger.info('_get_web_content '+hueBridgeId)
                         # dann der aufruf kompatibel, aber inhaltlich nicht identisch fetch_url aus lib.tools, daher erst eimal das fehlerobjekt nicht mehr da
                -        try:
                -            response = client.fetch_url(url, None, None, 2, 0, method, body, errorItem)
                -        except Exception as e:
                -            response = None
                -            logger.error('HUE: _get_web_content: Error: {0} (bridge available?)'.format(e))
                +        response = client.fetch_url(url, None, None, 2, 0, method, body, errorItem)
                         if response:
                             # und jetzt der anteil der decodierung, der nicht in der fetch_url drin ist
                             # lesen, decodieren nach utf-8 (ist pflicht nach der api definition philips) und in ein python objekt umwandeln
                @@ -563,9 +571,9 @@ def  _get_web_content(self, hueBridgeId='0', path='', method='GET', body=None):
                                 error = returnValues[0]["error"]
                                 description = error['description']
                                 if error['type'] == 1:
                -                    logger.error('HUE: _request: Error: {0} (Need to specify correct hue user?)'.format(description))
                +                    self.logger.error('_request: Error: {0} (Need to specify correct hue user?)'.format(description))
                                 else:
                -                    logger.error('HUE: _request: Error: {0}'.format(description))
                +                    self.logger.error('_request: Error: {0}'.format(description))
                                 return None
                             return returnValues
                         else:
                @@ -603,7 +611,7 @@ def _set_lamp_state(self, hueBridgeId, hueLampId, state):
                                                     value = int(hueObjectReturnStringValue)
                                                 self._listenLampItems[returnItem](value, 'HUE')
                                 else:
                -                    logger.warning('HUE: hue_set_lamp_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                +                    self.logger.warning('hue_set_lamp_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                         self._hueLock.release()
                 
                     def _set_group_state(self, hueBridgeId, hueGroupId , state):
                @@ -620,7 +628,7 @@ def _set_group_state(self, hueBridgeId, hueGroupId , state):
                                 if hueObjectStatus == 'success':
                                     pass
                                 else:
                -                    logger.warning('HUE: _set_group_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                +                    self.logger.warning('_set_group_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                         self._hueLock.release()
                 
                     def _update_lamps(self):
                @@ -765,9 +773,9 @@ def get_config(self, hueBridgeId='0'):
                         # mit dem die szenen gesetzt worden sind, um ihn dann als user für das plugin einzusetzen
                         # und jetzt alle szenen
                         returnValues = self._get_webcontent(hueBridgeId, '/scenes')
                -        logger.warning('HUE: get_config: Scenes {0}'.format(returnValues))
                +        self.logger.warning('get_config: Scenes {0}'.format(returnValues))
                         returnValues = self._get_webcontent(hueBridgeId, '/groups')
                -        logger.warning('HUE: get_config: Groups {0}'.format(returnValues))
                +        self.logger.warning('get_config: Groups {0}'.format(returnValues))
                         return returnValues
                 
                     def authorizeuser(self, hueBridgeId='0'):
                @@ -778,11 +786,11 @@ def authorizeuser(self, hueBridgeId='0'):
                         resp = con.getresponse()
                         con.close()
                         if resp.status != 200:
                -            logger.error('HUE: authorize: Authenticate request failed')
                +            self.logger.error('authorize: Authenticate request failed')
                             return "Authenticate request failed"
                         resp = resp.read()
                -        logger.debug(resp)
                +        self.logger.debug(resp)
                         resp = json.loads(resp)
                -        logger.debug(resp)
                +        self.logger.debug(resp)
                         return resp
                 
                diff --git a/hue/_pv_1_1_83/README.md b/hue/_pv_1_1_83/README.md
                new file mode 100755
                index 000000000..2d1e885d0
                --- /dev/null
                +++ b/hue/_pv_1_1_83/README.md
                @@ -0,0 +1,595 @@
                +# Phillips HUE v1.1.83 classic (up to shNG v1.3)
                +
                +### New development of Hue plugin for use in smarthome.py (C) Michael Würtenberger 2014, 2015, 2016
                +version 1.83 developNG
                +Development Repo and examples for smartvisu widget under https://github.com/mworion/hue.git
                +
                +## Supported Hardware
                +Philips hue bridge, multiple bridges allowed
                +
                +## Configuration
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +
                +Typical configuration for 3 bridges
                +
                +```
                +[HUE]
                +    class_name = HUE
                +    class_path = plugins.hue
                +    hue_user = 38f625a739562a8bd261ab9c7f5e62c8|38f625a739562a8bd261ab9c7f5e62c8|38f625a739562a8bd261ab9c7f5e62c8
                +    hue_ip = 192.168.2.2|192.168.2.3|192.168.2.4
                +    hue_port = 80|80|80
                +    cycle_lamps = 3
                +    cycle_bridges = 30
                +    default_transitionTime = 0.4
                +```
                +
                +```
                +HUE:
                +    class_name: HUE
                +    class_path: plugins.hue
                +    hue_user:
                +      - 38f625a739562a8bd261ab9c7f5e62c8
                +      - 38f625a739562a8bd261ab9c7f5e62c8
                +      - 38f625a739562a8bd261ab9c7f5e62c8
                +    hue_ip:
                +      - 192.168.2.2
                +      - 192.168.2.3
                +      - 192.168.2.4
                +    hue_port:
                +      - '80'
                +      - '80'
                +      - '80'
                +    cycle_lamps: 3
                +    cycle_bridges: 30
                +    default_transitionTime: '0.4'
                +```
                +
                +Minimal configuration for single bridge an default settings
                +
                +```
                +[HUE]
                +    class_name = HUE
                +    class_path = plugins.hue
                +    hue_user = 38f625a739562a8bd261ab9c7f5e62c8
                +    hue_ip = 192.168.2.2
                +```
                +
                +```
                +HUE:
                +    class_name: HUE
                +    class_path: plugins.hue
                +    hue_user: 38f625a739562a8bd261ab9c7f5e62c8
                +    hue_ip: 192.168.2.2
                +```
                +
                +#### hue_user
                +A user name for the hue bridge. Usually this is a hash value of 32 hexadecimal digits.
                +If you would like to use more than on bridge, you have to specify all ip addresses, ports and users accordingly.
                +All users are separated with pipe ('|') !
                +If the user/hash is not yet authorized, you can use sh.hue.authorizeuser() (via interactive shell or via logic)
                +to authorize it. The link button must be pressed before.
                +
                +#### hue_ip
                +IP or host name of the hue bridge. There is no default, please us a valid ip address.
                +If you would like to use more than on bridge, you have to specify all ip addresses, ports and users accordingly.
                +All ip's are separated with pipe ('|') !
                +
                +#### hue_port
                +Port number of the hue bridge. 
                +Default 80. Normally there is no need to change that.
                +If you would like to use more than on bridge, you have to specify all ip addresses, ports and users accordingly.
                +All ports are separated with pipe ('|') !
                +
                +#### cycle_lamps
                +Cycle in seconds to how often update the state of the lights in smarthome.
                +Default value is 10 seconds.
                +Note: The hue bridge has no notification feature. Therefore changes can only be detected via polling.
                +
                +#### cycle_bridges
                +Cycle in seconds to how often update the state of the bridges in smarthome.
                +Default value is 60 seconds
                +Note: The hue bridge has no notification feature. Therefore changes can only be detected via polling.
                +
                +#### default_transitionTime
                +Time in seconds how fast check states of the lamps are changed through the bridge itself. If you don't set a value in the item, this value
                +is used.
                +Note: The hue bridge has no notification feature. Therefore changes can only be detected via polling.
                +
                +### items.conf (deprecated) / items.yaml
                +
                +#### hue_bridge_id (formerly hue_bridge !)
                +
                +Specify the number of the hue_bridge_id. Via this parameter the right hue connection is established.
                +The numbers start with 0. There must be no missing number in between !
                +
                +#### hue_lamp_id (formerly hue_id)
                +Specify the lamp id. Via this parameter the right lamp on the hue connection is established.
                +The numbers are the corresponding numbers of the lamp Id in the bridge. They normally start with 0. There must be a
                +hue_bridge_id attached to this item as well. If not, a default value of 0 will be set.
                +
                +#### hue_group_id
                +Specify the group id. Via this parameter the right group on the hue connection is established.
                +The numbers are the corresponding numbers of the lgroup Id in the bridge. They normally start with 1. There must be a
                +hue_bridge_id attached to this item as well. If not, a default value of 1 will be set.
                +
                +#### hue_lamp_type
                +Specify the lamp type because of different color garamut parameters
                +Default would be 0 if not defined. There are currently two groups of lamps:
                +Group 0 consists of hue bulb lamps, there hue_lamp_type = 0
                +Group 1 consists of LivingColors Bloom, Aura and Iris lamps, there hue_lamp_type = 1
                +
                +### Commands and Parameters supported
                +Please refer to the specs of the API 1.4 of the hue at http://www.developers.meethue.com/documentation/lights-api.
                +Readable means you can set a hue_listen attribute in a item with the corresponding name
                +Writable means you can set a hue_send attribute in a item with the corresponding name
                +
                +#### Lights API (Light state)
                +All Attributes for the Light state (besides 'on') can only be set, if the light is on!
                +
                +```
                +Attribute            Type   Range                           Readable    Writable
                +'on'                 bool   False / True                    yes         yes
                +'bri'                num    0-255                           yes         yes
                +'hue'                num    0-65535                         yes         yes
                +'sat'                num    0-255                           yes         yes
                +'ct'                 num    153 - 500                       yes         yes
                +'alert'              str    'none' or 'select' or 'lselect' yes         yes
                +'effect'             str    'none' or 'colorloop'           yes         yes
                +'reachable'          bool   False / True                    yes         no
                +'hue_transitionTime' num    0-65535                         no          yes
                +'col_r'              num    0-255                           no          yes
                +'col_g'              num    0-255                           no          yes
                +'col_b'              num    0-255                           no          yes
                +```
                +
                +Instead of implementing the 'xy' state attribute, 'col_r', 'col_g' and 'col_b' have been implemented to allow the color control directly from a SmartVISU widget (e.g. Colordisc).
                +
                +For a basic control of the the lights you only need to implement the first 4 to 5 attributes of the Lights API ('on', 'bri', 'hue', 'sat' and 'ct').  The rest of the attributes is only needed, if you want to do MORE. 
                + 
                +#### Lights API (Lamp attributes)
                +
                +```
                +Attribute            Type   Range                           Readable    Writable
                +'type'               str    text                            yes         no
                +'name'               str    text                            yes         no
                +'modelid'            str    text                            yes         no
                +'swversion'          str    text                            yes         no
                +```
                +
                +#### Groups API
                +
                +```
                +Attribute            Type   Range                           Readable    Writable
                +'scene'              str    scene name in bridge            no          yes
                +```
                +
                +#### Configuration API (Bridge related)
                +```
                +Attribute            Type   Range                           Readable    Writable
                +'bridge_name'        str    text                            yes         no
                +'swupdate'           dict   object                          yes         no
                +'whitelist'          dict   object                          yes         no
                +'apiversion'         str    text                            yes         no
                +'bridge_swversion'   str    text                            yes         no
                +'linkbutton'         bool   False / True                    yes         no
                +
                +'ipaddress'          str    text                            yes         no
                +'mac'                str    text                            yes         no
                +'netmask'            str    text                            yes         no
                +'gateway'            str    text                            yes         no
                +'dhcp'               bool   False / True                    yes         no
                +
                +'portalservices'     bool   False / True                    yes         no
                +'portalconnection'   str    text                            yes         no
                +'portalstate'        dict   object                          yes         no
                +
                +'UTC'                str    text                            yes         no
                +'localtime'          str    text                            yes         no
                +'timezone'           str    text                            yes         no
                +
                +'zigbeechannel'      num    1-13                            yes         no
                +'errorstatus'        bool   False / True                    yes         no
                +```
                +
                +#### Configuration API (Plugin related)
                +```
                +Attribute            Type   Range                           Readable    Writable
                +'errorstatus'        bool   False / True                    yes         no
                +```
                +
                +### hue_listen = errorstatus
                +errorstatus represents the status of the link between sm.hy plugin and bridge. A status True reflects and error state in the communication.
                +
                +### hue_send
                +Specifies the writable attribute which is send to the lamp when this item is altered.
                +In addition to hue_send an hue_lamp_id and hue_bridge_id (optional for one bridge) has to be set. 
                +
                +
                +### hue_listen
                +Specifies the readable attribute which is updated on a scheduled timer from the lamps and bridges.
                +In addition to hue_send an hue_lamp_id and hue_bridge_id (optional for one bridge) has to be set. 
                +
                +### hue_transitionTime
                +This parameter specifies the time, which the lamp take to reach the a newly set value. This is done by interpolation of the values inside the lamp. 
                +This parameter is optional. If not set the time default is 0.1 second.
                +In addition to hue_send an hue_lamp_id and hue_bridge_id has to be set. This could be done in upper layers. If it's missing the parameter is removed.
                +
                +### Using DPT3 dimming
                +If you would like to use a DPT3 dimmer, you have to specify a subitem to the dimmed hue item. To this subitem you link the knx DPT3 part. 
                +You can control the dimming via some parameters, which have to be specified in this subitem.
                +
                +DPT3 dimming could be use with every item which has the type = num (even if it's not hue related !) 
                +
                +If you are using the DPT3 dimmer, please take into account that there is a lower limit of timing. 
                +A lower value than 0.2 seconds should be avoided, regarding the performance of the overall system. 
                +Nevertheless to get nice and smooth results of dimming, please set the parameters of hue_transitionTime and hue_dim_time equally. 
                +In that case, the lamp interpolates the transition as quick as the steps of the dimmer function happen.
                +If the lamp is set to off (e.g. attribute 'on' = False), changes could be not written to the lamp. 
                +Warnings in the log will appear. The lamp doesn't support this behaviour. In case of starting dimming the brightness of the lamp, the
                +plugin automatically sets the lamp on and starts dimming with the last value.     
                +
                +### hue_dim_max
                +Parameter which determines the maximum of the dimmer range. Without this parameter DPT3 dimming will not work.
                +
                +### hue_dim_step
                +Parameter which determines the step size.
                +In addition to hue_dim_max this parameter has to be set. If not a warning will be written and a default value of 25 will be set.
                +
                +### hue_dim_time
                +Parameter which determines the time, the dimmer takes for making on step.
                +In addition to hue_dim_max this parameter has to be set. If not a warning will be written and a default value of 1 will be set.
                +
                +### Example
                +
                +items/test.conf (deprecated)
                +```
                +[keller]
                +    [[hue]]
                +        # if hue_lamp_id and hue_bridge_id is not set, it is searched in a higher layer
                +        hue_lamp_id = 1
                +        hue_bridge_id = 0
                +        hue_lamp_type = 0
                +        [[[bridge_name]]]
                +            type = str
                +            hue_listen = bridge_name
                +        [[[zigbeechannel]]]
                +            type = num
                +            hue_listen = zigbeechannel
                +        [[[mac]]]
                +            type = str
                +            hue_listen = mac
                +        [[[dhcp]]]
                +            type = bool
                +            hue_listen = dhcp
                +        [[[ipaddress]]]
                +            type = str
                +            hue_listen = ipaddress
                +        [[[netmask]]]
                +            type = str
                +            hue_listen = netmask
                +        [[[gateway]]]
                +            type = str
                +            hue_listen = gateway
                +        [[[utc]]]
                +            type = str
                +            hue_listen = UTC
                +        [[[localtime]]]
                +            type = str
                +            hue_listen = localtime
                +        [[[timezone]]]
                +            type = str
                +            hue_listen = timezone
                +        [[[whitelist]]]
                +            type = dict
                +            hue_listen = whitelist
                +        [[[bridge_swversion]]]
                +            type = str
                +            hue_listen = bridge_swversion
                +        [[[apiversion]]]
                +            type = str
                +            hue_listen = apiversion
                +        [[[swupdate]]]
                +            type = dict
                +            hue_listen = swupdate
                +        [[[linkbutton]]]
                +            type = bool
                +            hue_listen = linkbutton
                +        [[[portalservices]]]
                +            type = bool
                +            hue_listen = portalservices
                +        [[[portalconnection]]]
                +            type = str
                +            hue_listen = portalconnection
                +        [[[portalstate]]]
                +            type = dict
                +            hue_listen = portalstate
                +        [[[power]]]
                +            type = bool
                +            hue_send = on
                +            hue_listen = on
                +            knx_dpt = 1
                +            knx_cache = 8/0/1
                +        [[[reachable]]]
                +            type = bool
                +            hue_listen = reachable
                +        [[[ct]]]
                +            type = num
                +            hue_send = ct
                +            hue_listen = ct
                +        [[[scene]]]
                +            type = str
                +            hue_send = scene
                +            enforce_updates = true
                +        [[[bri]]]
                +            type = num
                +            cache = on
                +            hue_send = bri
                +            hue_listen = bri
                +            hue_transitionTime = 0.2
                +            [[[[dim]]]]
                +                type = list
                +                knx_dpt = 3
                +                knx_listen = 8/0/2
                +                hue_dim_max = 255
                +                hue_dim_step = 10
                +                hue_dim_time = 0.2
                +        [[[sat]]]
                +            type = num
                +            cache = on
                +            hue_send = sat
                +            hue_listen = sat
                +        [[[col_r]]]
                +            type = num
                +            cache = on
                +            hue_send = col_r
                +        [[[col_g]]]
                +            type = num
                +            cache = on
                +            hue_send = col_g
                +        [[[col_b]]]
                +            type = num
                +            cache = on
                +            hue_send = col_b
                +        [[[hue]]]
                +            type = num
                +            cache = on
                +            hue_send = hue
                +            hue_listen = hue
                +            hue_transitionTime = 0.2
                +            [[[[dim]]]]
                +                type = list
                +                knx_dpt = 3
                +                knx_listen = 8/0/12
                +                hue_dim_max = 65535
                +                hue_dim_step = 2000
                +                hue_dim_time = 0.2
                +        [[[effect]]]
                +            type = str
                +            hue_send = effect
                +            hue_listen = effect
                +        [[[alert]]]
                +            type = str
                +            hue_send = alert
                +            hue_listen = alert
                +        [[[modeltype]]]
                +            type = str
                +            hue_listen = type
                +        [[[lampname]]]
                +            type = str
                +            hue_listen = name
                +        [[[modelid]]]
                +            type = str
                +            hue_listen = modelid
                +        [[[swversion]]]
                +            type = str
                +            hue_listen = swversion
                +```
                +
                +items/test.yaml
                +
                +```
                +keller:
                +
                +    hue:
                +        # if hue_lamp_id and hue_bridge_id is not set, it is searched in a higher layer
                +        hue_lamp_id: 1
                +        hue_bridge_id: 0
                +        hue_lamp_type: 0
                +
                +        bridge_name:
                +            type: str
                +            hue_listen: bridge_name
                +
                +        zigbeechannel:
                +            type: num
                +            hue_listen: zigbeechannel
                +
                +        mac:
                +            type: str
                +            hue_listen: mac
                +
                +        dhcp:
                +            type: bool
                +            hue_listen: dhcp
                +
                +        ipaddress:
                +            type: str
                +            hue_listen: ipaddress
                +
                +        netmask:
                +            type: str
                +            hue_listen: netmask
                +
                +        gateway:
                +            type: str
                +            hue_listen: gateway
                +
                +        utc:
                +            type: str
                +            hue_listen: UTC
                +
                +        localtime:
                +            type: str
                +            hue_listen: localtime
                +
                +        timezone:
                +            type: str
                +            hue_listen: timezone
                +
                +        whitelist:
                +            type: dict
                +            hue_listen: whitelist
                +
                +        bridge_swversion:
                +            type: str
                +            hue_listen: bridge_swversion
                +
                +        apiversion:
                +            type: str
                +            hue_listen: apiversion
                +
                +        swupdate:
                +            type: dict
                +            hue_listen: swupdate
                +
                +        linkbutton:
                +            type: bool
                +            hue_listen: linkbutton
                +
                +        portalservices:
                +            type: bool
                +            hue_listen: portalservices
                +
                +        portalconnection:
                +            type: str
                +            hue_listen: portalconnection
                +
                +        portalstate:
                +            type: dict
                +            hue_listen: portalstate
                +
                +        power:
                +            type: bool
                +            hue_send: 'on'
                +            hue_listen: 'on'
                +            knx_dpt: 1
                +            knx_cache: 8/0/1
                +
                +        reachable:
                +            type: bool
                +            hue_listen: reachable
                +
                +        ct:
                +            type: num
                +            hue_send: ct
                +            hue_listen: ct
                +
                +        scene:
                +            type: str
                +            hue_send: scene
                +            enforce_updates: 'true'
                +
                +        bri:
                +            type: num
                +            cache: 'on'
                +            hue_send: bri
                +            hue_listen: bri
                +            hue_transitionTime: '0.2'
                +
                +            dim:
                +                type: list
                +                knx_dpt: 3
                +                knx_listen: 8/0/2
                +                hue_dim_max: 255
                +                hue_dim_step: 10
                +                hue_dim_time: '0.2'
                +
                +        sat:
                +            type: num
                +            cache: 'on'
                +            hue_send: sat
                +            hue_listen: sat
                +
                +        col_r:
                +            type: num
                +            cache: 'on'
                +            hue_send: col_r
                +
                +        col_g:
                +            type: num
                +            cache: 'on'
                +            hue_send: col_g
                +
                +        col_b:
                +            type: num
                +            cache: 'on'
                +            hue_send: col_b
                +
                +        hue:
                +            type: num
                +            cache: 'on'
                +            hue_send: hue
                +            hue_listen: hue
                +            hue_transitionTime: '0.2'
                +
                +            dim:
                +                type: list
                +                knx_dpt: 3
                +                knx_listen: 8/0/12
                +                hue_dim_max: 65535
                +                hue_dim_step: 2000
                +                hue_dim_time: '0.2'
                +
                +        effect:
                +            type: str
                +            hue_send: effect
                +            hue_listen: effect
                +
                +        alert:
                +            type: str
                +            hue_send: alert
                +            hue_listen: alert
                +
                +        modeltype:
                +            type: str
                +            hue_listen: type
                +
                +        lampname:
                +            type: str
                +            hue_listen: name
                +
                +        modelid:
                +            type: str
                +            hue_listen: modelid
                +
                +        swversion:
                +            type: str
                +            hue_listen: swversion
                +```
                +
                +Please note that knx_cache is wrong in the old example for [[[dim]]], the right setting is knx_listen
                +
                +### logic.conf (deprecated) / logic.yaml
                +No logic attributes.
                +
                +## Methods
                +
                +### get_config()
                +Drops the list of stored scenes in the bridge.
                +Parameter the bridge id as string!
                +```
                +sh.hue.get_config(hue_bridge_id)
                +```
                +
                +### authorizeuser()
                +
                +Authorizes the user configured by hue_user config property. You have to press the link button.
                +
                +```
                +sh.hue.authorizeuser()
                +```
                +
                +
                +
                diff --git a/hue/_pv_1_1_83/__init__.py b/hue/_pv_1_1_83/__init__.py
                new file mode 100755
                index 000000000..422c4a0cd
                --- /dev/null
                +++ b/hue/_pv_1_1_83/__init__.py
                @@ -0,0 +1,779 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#
                +#  Copyright (C) 2014,2015,2016 Michael Würtenberger
                +#
                +#  Version 1.83 developNG
                +#
                +#  Erstanlage mit ersten Tests
                +#  Basiert auf den Ueberlegungen des verhandenen Hue Plugins.
                +#  Die Parametrierung des Plugings in der plugin.conf und die authorize() Methode wurden zur
                +#  Wahrung der Kompatibilitaet uebernommen
                +# 
                +#  Umsetzung rgb mit aufgenommen, basiert auf der einwegumrechnung von
                +#  https://github.com/benknight/hue-python-rgb-converter 
                +#
                +#  Basiert aus der API 1.11 der Philips hue API spezifikation, die man unter
                +#  http://www.developers.meethue.com/documentation/lights-api finden kann
                +#
                +#  APL2.0
                +#
                +#  Library for RGB / CIE1931 coversion ported from Bryan Johnson's JavaScript implementation:
                +#  https://github.com/bjohnso5/hue-hacking
                +#  extension to use differen triangle points depending of the type of the hue system
                +# 
                +
                +import logging
                +import json
                +import math
                +from collections import namedtuple
                +import http.client
                +import time
                +import threading
                +from lib.tools import Tools
                +
                +XY = namedtuple('XY', ['x', 'y'])
                +logger = logging.getLogger('HUE:')
                +client = Tools()
                +
                +class HUE():
                +
                +    def __init__(self, smarthome, hue_ip = '', hue_user = '', hue_port = '80', cycle_lamps = '10', cycle_bridges = '60', default_transitionTime = '0.4'):
                +
                +        # parameter zu übergabe aus der konfiguration pulgin.conf
                +        self._sh = smarthome
                +        # parmeter übernehmen, aufteilen und leerzeichen herausnehmen
                +        self._hue_ip = [hue_ip]
                +        self._hue_user = [hue_user]
                +        self._hue_port = [hue_port]
                +        # verabreitung der parameter aus der plugin.conf
                +        self._numberHueBridges = len(self._hue_ip)
                +        if len(self._hue_port) != self._numberHueBridges or len(self._hue_user) != self._numberHueBridges:
                +            logger.error('HUE: Error in plugin.conf: if you specify more than 1 bridge, all parameters hue_ip, hue_user and hue_port have to be defined')
                +            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +        if '' in self._hue_user:
                +            logger.error('HUE: Error in plugin.conf: you have to specify all hue_user')
                +            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +        if '' in self._hue_ip:
                +            logger.error('HUE: Error in plugin.conf: you have to specify all hue_ip')
                +            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +        if '' in self._hue_port:
                +            logger.error('HUE: Error in plugin.conf: you have to specify all hue_port')
                +            raise Exception('HUE: Plugin stopped due to configuration fault in plugin.conf') 
                +        self._cycle_lampsGroups = int(cycle_lamps)
                +        if self._cycle_lampsGroups < 5:
                +            # beschränkung der wiederholrate 
                +            self._cycle_lampsGroups = 5
                +        self._cycle_bridges = int(cycle_bridges)
                +        if self._cycle_bridges < 10:
                +            # beschränkung der wiederholrate 
                +            self._cycle_bridges = 10
                +        self._hueDefaultTransitionTime = float(default_transitionTime)
                +        if self._hueDefaultTransitionTime < 0:
                +            # beschränkung der wiederholrate 
                +            logger.warning('HUE: Error in plugin.conf: the default_transitionTime parameter cannot be negative. It is set to 0')
                +            self._hueDefaultTransitionTime = 0
                +        # variablen zur steuerung des plugins
                +        # hier werden alle bekannte items für lampen eingetragen
                +        self._sendLampItems = {}
                +        self._listenLampItems = {}
                +        # hier werden alle bekannte items für lampen eingetragen
                +        self._sendGroupItems = {}
                +        self._listenGroupItems = {}
                +        # hier werden alle bekannte items für die hues eingetragen
                +        self._sendBridgeItems = {}
                +        self._listenBridgeItems = {}
                +        # locks für die absicherung
                +        self._hueLock = threading.Lock()
                +        # hier ist die liste der einträge, für die der status auf listen gesetzt werden kann
                +        self._listenLampKeys = ['on', 'bri', 'sat', 'hue', 'reachable', 'effect', 'alert', 'type', 'name', 'modelid', 'uniqueid', 'manufacturername', 'swversion', 'ct']
                +        # hier ist die liste der einträge, für die der status auf senden gesetzt werden kann
                +        self._sendLampKeys = ['on', 'bri', 'bri_inc', 'sat','sat_inc', 'hue', 'hue_inc', 'effect', 'alert', 'col_r', 'col_g', 'col_b', 'ct', 'ct_inc']
                +        # hier ist die liste der einträge, für die der status auf listen gesetzt werden kann
                +        self._listenGroupKeys = ['on', 'bri', 'sat', 'hue', 'reachable', 'effect', 'alert', 'type', 'name', 'ct']
                +        # hier ist die liste der einträge, für die der status auf senden gesetzt werden kann
                +        self._sendGroupKeys = ['on', 'bri','bri_inc', 'sat' ,'sat_inc', 'hue', 'hue_inc', 'effect', 'alert', 'ct', 'ct_inc']
                +        # hier ist die liste der einträge, für die der status auf listen gesetzt werden kann
                +        self._listenBridgeKeys = ['bridge_name', 'zigbeechannel', 'mac', 'dhcp', 'ipaddress', 'netmask', 'gateway', 'UTC', 'localtime', 'timezone', 'bridge_swversion', 'apiversion', 'swupdate', 'linkbutton', 'portalservices', 'portalconnection', 'portalstate', 'whitelist','errorstatus']
                +        # hier ist die liste der einträge, für die der status auf senden gesetzt werden kann
                +        self._sendBridgeKeys = ['scene']
                +        # hier ist die liste der einträge, für die ein dimmer DPT3 gesetzt werden kann
                +        self._dimmKeys = ['bri', 'sat', 'hue']
                +        # hier ist die liste der einträge, für rgb gesetzt werden kann
                +        self._rgbKeys = ['col_r', 'col_g', 'col_b']
                +        # hier ist die liste der einträge, für string
                +        self._stringKeys = ['effect', 'alert', 'type', 'name', 'modelid', 'uniqueid', 'manufacturername', 'swversion', 'bridge_name', 'mac', 'ipaddress', 'netmask', 'gateway', 'UTC', 'localtime', 'timezone', 'bridge_swversion', 'apiversion', 'portalconnection']
                +        # hier ist die liste der einträge, für string
                +        self._boolKeys = ['on', 'reachable', 'linkbutton', 'portalservices', 'dhcp']
                +        # hier ist die liste der einträge, für string
                +        self._dictKeys = ['portalstate', 'swupdate', 'whitelist']
                +        # hier ist die liste der einträge, für wertebereich 0-255
                +        self._rangeInteger8 = ['bri', 'sat', 'col_r', 'col_g', 'col_b']
                +        # hier ist die liste der einträge, für wertebereich -254 bis 254
                +        self._rangeSignedInteger8 = ['bri_inc', 'sat_inc']
                +        # hier ist die liste der einträge, für wertebereich 0 bis 65535
                +        self._rangeInteger16 = ['hue']
                +        # hier ist die liste der einträge, für wertebereich -65534 bis 65534
                +        self._rangeSignedInteger16 = ['hue_inc','ct_inc']
                +        # konfiguration farbumrechnung. es gibt im Moment 2 lampentypgruppen:
                +        # hue bulb the corners index 0 [0] für LivingColors Bloom, Aura and Iris index 1 [1]
                +        self._numberHueLampTypes=3
                +        self.Red = [XY(0.674, 0.322), XY(0.703, 0.296), XY(1.0, 0.0)]
                +        self.Lime =[XY(0.408, 0.517), XY(0.214, 0.709), XY(0.703, 1.0)]
                +        self.Blue =[XY(0.168, 0.041), XY(0.139, 0.081), XY(0.0, 0.0)]
                +        # Konfigurationen zur laufzeit
                +        # scheduler für das polling des status der lampen über die hue bridge
                +        self._sh.scheduler.add('hue-update-lamps', self._update_lamps, cycle = self._cycle_lampsGroups)
                +        # scheduler für das polling des status der lampen über die hue bridge
                +        self._sh.scheduler.add('hue-update-groups', self._update_groups, cycle = self._cycle_lampsGroups)
                +        # scheduler für das polling des status der hue bridge
                +        self._sh.scheduler.add('hue-update-bridges', self._update_bridges, cycle = self._cycle_bridges)
                +
                +    ### following the library parts of the rewritten topics
                +    def crossProduct(self, p1, p2):
                +        return (p1.x * p2.y - p1.y * p2.x)
                +    def checkPointInLampsReach(self, p, lampType):
                +        v1 = XY(self.Lime[lampType].x - self.Red[lampType].x, self.Lime[lampType].y - self.Red[lampType].y)
                +        v2 = XY(self.Blue[lampType].x - self.Red[lampType].x, self.Blue[lampType].y - self.Red[lampType].y)
                +        q = XY(p.x - self.Red[lampType].x, p.y - self.Red[lampType].y)
                +        s = self.crossProduct(q, v2) / self.crossProduct(v1, v2)
                +        t = self.crossProduct(v1, q) / self.crossProduct(v1, v2)
                +        return (s >= 0.0) and (t >= 0.0) and (s + t <= 1.0)
                +    def getClosestPointToLine(self, A, B, P):
                +        AP = XY(P.x - A.x, P.y - A.y)
                +        AB = XY(B.x - A.x, B.y - A.y)
                +        ab2 = AB.x * AB.x + AB.y * AB.y
                +        ap_ab = AP.x * AB.x + AP.y * AB.y
                +        t = ap_ab / ab2
                +        if t < 0.0:
                +            t = 0.0
                +        elif t > 1.0:
                +            t = 1.0
                +        return XY(A.x + AB.x * t, A.y + AB.y * t)
                +    def getClosestPointToPoint(self, xyPoint, lampType):
                +        pAB = self.getClosestPointToLine(self.Red[lampType], self.Lime[lampType], xyPoint)
                +        pAC = self.getClosestPointToLine(self.Blue[lampType], self.Red[lampType], xyPoint)
                +        pBC = self.getClosestPointToLine(self.Lime[lampType], self.Blue[lampType], xyPoint)
                +        dAB = self.getDistanceBetweenTwoPoints(xyPoint, pAB)
                +        dAC = self.getDistanceBetweenTwoPoints(xyPoint, pAC)
                +        dBC = self.getDistanceBetweenTwoPoints(xyPoint, pBC)
                +        lowest = dAB
                +        closestPoint = pAB
                +        if (dAC < lowest):
                +            lowest = dAC
                +            closestPoint = pAC
                +        if (dBC < lowest):
                +            lowest = dBC
                +            closestPoint = pBC
                +        cx = closestPoint.x
                +        cy = closestPoint.y
                +        return XY(cx, cy)
                +    def getDistanceBetweenTwoPoints(self, one, two):
                +        dx = one.x - two.x
                +        dy = one.y - two.y
                +        return math.sqrt(dx * dx + dy * dy) 
                +    def getXYPointFromRGB(self, red, green, blue, lampType):
                +        r = ((red + 0.055) / (1.0 + 0.055))**2.4 if (red > 0.04045) else (red / 12.92)
                +        g = ((green + 0.055) / (1.0 + 0.055))**2.4 if (green > 0.04045) else (green / 12.92)
                +        b = ((blue + 0.055) / (1.0 + 0.055))**2.4 if (blue > 0.04045) else (blue / 12.92)
                +        X = r * 0.4360747 + g * 0.3850649 + b * 0.0930804
                +        Y = r * 0.2225045 + g * 0.7168786 + b * 0.0406169
                +        Z = r * 0.0139322 + g * 0.0971045 + b * 0.7141733
                +        if X + Y + Z == 0:
                +            cx = cy = 0
                +        else:
                +            cx = X / (X + Y + Z)
                +            cy = Y / (X + Y + Z)
                +        xyPoint = XY(cx, cy)
                +        inReachOfLamps = self.checkPointInLampsReach(xyPoint, lampType)
                +        if not inReachOfLamps:
                +            xyPoint = self.getClosestPointToPoint(xyPoint, lampType)
                +        return [xyPoint.x, xyPoint.y]
                +    ### end of library files
                +    
                +    def run(self):
                +        self.alive = True
                +        # if you want to create child threads, do not make them daemon = True!
                +        # They will not shutdown properly. (It's a python bug)
                +
                +    def stop(self):
                +        self.alive = False
                +        
                +    def _find_item_attribute(self, item, attribute, attributeDefault, attributeLimit=99):
                +        # zwischenspeichern für die loggerausgabe
                +        itemSearch = item
                +        # schleife bis ich ganz oben angekommen bin
                +        while (not attribute in itemSearch.conf):
                +            # eine Stufe in den ebenen nach oben
                +            itemSearch = itemSearch.return_parent()                    
                +            if (itemSearch is self._sh):
                +                # wir sind am root knoten angekommen und haben nichts gefunden !
                +                if attribute == 'hue_bridge_id' and self._numberHueBridges > 1:
                +                    logger.warning('HUE: _find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                +                elif attribute == 'hue_lamp_type':
                +                    logger.warning('HUE: _find_item_attribute: could not find [{0}] for item [{1}], setting defined default value {2}'.format(attribute, item, attributeDefault))
                +                elif attribute == 'hue_lamp_id':
                +                    logger.error('HUE: _find_item_attribute: could not find [{0}] for item [{1}], an value has to be defined'.format(attribute, item))
                +                    raise Exception('HUE: Plugin stopped due to missing hue_lamp_id in item.conf')
                +                # wenn nicht gefunden, dann wird der standardwert zurückgegeben
                +                return str(attributeDefault)
                +        itemAttribute = int(itemSearch.conf[attribute])
                +        if itemAttribute >= attributeLimit:
                +            itemAttribute = attributeLimit
                +            logger.warning('HUE: _find_item_attribute: attribute [{0}] exceeds upper limit and set to default in item [{1}]'.format(attribute,item))
                +        return str(itemAttribute)
                +    
                +    def parse_item(self, item):
                +        # alle konfigurationsfehler sollten in der parsing routinge abgefangen werden
                +        # fehlende parameter werden mit eine fehlermeldung versehen und auf default werte gesetzt
                +        # sowie anschliessend in die objektstruktur dynamisch eingepflegt. Damit haben die Auswerte
                +        # routinen keinen sonderfall mehr abzudecken !
                +        # zunächst einmal die installation der dimmroutine
                +        if 'hue_dim_max' in item.conf:
                +            if not 'hue_dim_step' in item.conf:
                +                item.conf['hue_dim_step'] = '25'
                +                logger.warning('HUE: dimmenDPT3: no hue_dim_step defined in item [{0}] using default 25'.format(item))
                +            if not 'hue_dim_time' in item.conf:
                +                item.conf['hue_dim_time'] = '1'
                +                logger.warning('HUE: dimmenDPT3: no hue_dim_time defined in item [{0}] using default 1'.format(item))
                +            return self.dimmenDPT3
                +
                +        if 'hue_listen' in item.conf:
                +            hueListenCommand = item.conf['hue_listen']
                +            if hueListenCommand in self._listenLampKeys:
                +                # wir haben ein sendekommando für die lampen. dafür brauchen wir die bridge und die lampen id
                +                hueLampId = self._find_item_attribute(item, 'hue_lamp_id', 1)
                +                hueLampType = self._find_item_attribute(item, 'hue_lamp_type', 0, self._numberHueLampTypes)
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_lamp_id'] = hueLampId
                +                item.conf['hue_lamp_type'] = hueLampType
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueLampId + '.' + hueListenCommand
                +                if not hueIndex in self._listenLampItems:
                +                    self._listenLampItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in lamp item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                +            elif hueListenCommand in self._listenBridgeKeys:
                +                # hier brauche ich nur eine hue_bridge_id
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueListenCommand
                +                if not hueIndex in self._listenBridgeItems:
                +                    self._listenBridgeItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in bridge item [{0}] command hue_listen = {1} is duplicated to item  [{2}]'.format(item,hueListenCommand,self._listenLampItems[hueIndex]))
                +            else:
                +                logger.error('HUE: parse_item: command hue_listen = {0} not defined in item [{1}]'.format(hueListenCommand,item))
                +
                +        # für die groups brauchen wir eine eigenes listen attribut, weil die kommandos gleich denen der lampen sind damit schwer nur unterscheidbar
                +        if 'hue_listen_group' in item.conf:
                +            hueListenGroupCommand = item.conf['hue_listen_group']
                +            if hueListenGroupCommand in self._listenGroupKeys:
                +                # wir haben ein sendekommando für die lampen. dafür brauchen wir die bridge und die lampen id
                +                hueGroupId = self._find_item_attribute(item, 'hue_group_id', 1)
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_group_id'] = hueGroupId
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueGroupId + '.' + hueListenGroupCommand
                +                if not hueIndex in self._listenGroupItems:
                +                    self._listenGroupItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in group item [{0}] command hue_listen_group = {1} is duplicated to item  [{2}]'.format(item,hueListenGroupCommand,self._listenGroupItems[hueIndex]))
                +        
                +        if 'hue_send' in item.conf:
                +            hueSendCommand = item.conf['hue_send']
                +            if hueSendCommand in self._sendLampKeys:
                +                # wir haben ein sendekommando für die lampen. dafür brauchen wir die bridge und die lampen id
                +                hueLampId = self._find_item_attribute(item, 'hue_lamp_id', 1)
                +                hueLampType = self._find_item_attribute(item, 'hue_lamp_type', 0, self._numberHueLampTypes)
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_lamp_id'] = hueLampId
                +                item.conf['hue_lamp_type'] = hueLampType
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueLampId + '.' + hueSendCommand
                +                if not hueIndex in self._sendLampItems:
                +                    self._sendLampItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in lamp item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                +                return self.update_lamp_item
                +            elif hueSendCommand in self._sendBridgeKeys:
                +                # hier brauche ich nur eine hue_bridge_id
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueSendCommand
                +                if not hueIndex in self._sendBridgeItems:
                +                    self._sendBridgeItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in bridge item [{0}] command hue_send = {1} is duplicated to item  [{2}]'.format(item,hueSendCommand,self._sendLampItems[hueIndex]))
                +                return self.update_bridge_item
                +            else:
                +                logger.error('HUE: parse_item: command hue_send = {0} not defined in item [{1}]'.format(hueSendCommand,item))
                +
                +        # für die groups brauchen wir eine eigenes listen attribut, weil die kommandos gleich denen der lampen sind damit schwer nur unterscheidbar
                +        if 'hue_send_group' in item.conf:
                +            hueSendGroupCommand = item.conf['hue_send_group']
                +            if hueSendGroupCommand in self._sendGroupKeys:
                +                # wir haben ein sendekommando für die lampen. dafür brauchen wir die bridge und die group id
                +                hueGroupId = self._find_item_attribute(item, 'hue_group_id', 1)
                +                hueBridgeId = self._find_item_attribute(item, 'hue_bridge_id', 0, self._numberHueBridges)
                +                item.conf['hue_group_id'] = hueGroupId
                +                item.conf['hue_bridge_id'] = hueBridgeId
                +                hueIndex = hueBridgeId + '.' + hueGroupId + '.' + hueSendGroupCommand
                +                if not hueIndex in self._sendGroupItems:
                +                    self._sendGroupItems[hueIndex] = item
                +                else:
                +                    logger.warning('HUE: parse_item: in group item [{0}] command hue_send_group = {1} is duplicated to item  [{2}]'.format(item,hueSendGroupCommand,self._sendGroupItems[hueIndex]))
                +                return self.update_group_item
                +
                +    def _limit_range_int(self, value, minValue, maxValue):
                +        # kurze routine zur wertebegrenzung
                +        if value >= maxValue:
                +            value = int(maxValue)
                +        elif value < minValue:
                +            value = int(minValue)
                +        else:
                +            value = int(value)
                +        return value
                +   
                +    def update_lamp_item(self, item, caller=None, source=None, dest=None):
                +        # methode, die bei einer änderung des items ausgerufen wird wenn die änderung von aussen kommt, dann wird diese abgearbeitet
                +        # im konkreten fall heisst das, dass der aktuelle status der betroffene lampe komplett zusammengestellt wird
                +        # und anschliessen neu über die hue bridge gesetzt wird.
                +        if caller != 'HUE':
                +            # lokale speicherung in variablen, damit funktionen nicht immer aufgerufen werden (performance)
                +            value = item()
                +            hueBridgeId = item.conf['hue_bridge_id']
                +            hueLampId = item.conf['hue_lamp_id']
                +            hueLampType = item.conf['hue_lamp_type']
                +            hueSend = item.conf['hue_send']
                +            if 'hue_transitionTime' in item.conf:
                +                hueTransitionTime = int(float(item.conf['hue_transitionTime']) * 10)
                +            else:
                +                hueTransitionTime = int(self._hueDefaultTransitionTime * 10)
                +
                +            # index ist immer bridge_id + lamp_id + hue_send
                +            hueIndex = hueBridgeId + '.' + hueLampId
                +            
                +            if hueIndex + '.on' in self._sendLampItems:
                +                hueLampIsOn = self._sendLampItems[(hueIndex + '.on')]()
                +            else:
                +                logger.warning('HUE: update_lamp_item: no item for on/off defined for bridge {0} lampe {1}'.format(hueBridgeId, hueLampId))
                +                hueLampIsOn = False
                +                
                +            # test aus die wertgrenzen, die die bridge verstehen kann
                +            if hueSend in self._rangeInteger8:
                +                # werte dürfen zwischen 0 und 255 liegen
                +                value = self._limit_range_int(value, 0, 255)    
                +            if hueSend in self._rangeSignedInteger8:
                +                # werte dürfen zwischen -254 und 254 liegen
                +                value = self._limit_range_int(value, -254, 254)    
                +            if hueSend in self._rangeInteger16:
                +                # hue darf zwischen 0 und 65535 liegen
                +                value = self._limit_range_int(value, 0, 65535)    
                +            if hueSend in self._rangeSignedInteger16:
                +                # hue darf zwischen -65534 und 65534 liegen
                +                value = self._limit_range_int(value, -65534, 65534)    
                +            if hueSend == 'ct':
                +                # ct darf zwischen 153 und 500 liegen
                +                value = self._limit_range_int(value, 153, 500)
                +                
                +            if hueLampIsOn:
                +                # lampe ist an (status in sh). dann können alle befehle gesendet werden
                +                if hueSend == 'on':
                +                    # wenn der status in sh true ist, aber mit dem befehl on, dann muss die lampe auf der hue seite erst eingeschaltet werden
                +                    if hueIndex + '.bri' in self._sendLampItems:
                +                        # wenn eingeschaltet wird und ein bri item vorhanden ist, dann wird auch die hellgkeit
                +                        # mit gesetzt, weil die lmape das im ausgeschalteten zustand vergisst.
                +                        self._set_lamp_state(hueBridgeId, hueLampId, {'on': True, 'bri': int(self._sendLampItems[(hueIndex + '.bri')]()) , 'transitiontime': hueTransitionTime})
                +                    else:
                +                        # ansonst wird nur eingeschaltet
                +                        self._set_lamp_state(hueBridgeId, hueLampId, {'on': True , 'transitiontime': hueTransitionTime})
                +                        logger.info('HUE: update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                +                else:
                +                    # anderer befehl gegeben
                +                    if hueSend in self._rgbKeys:
                +                        # besonderheit ist der befehl für die rgb variante, da hier alle werte herausgesucht werden müssen
                +                        if ((hueIndex + '.col_r') in self._sendLampItems) and ((hueIndex + '.col_g') in self._sendLampItems) and ((hueIndex + '.col_b') in self._sendLampItems):
                +                            # wertebereiche der anderen klären bri darf zwischen 0 und 255 liegen
                +                            value_r = self._limit_range_int(self._sendLampItems[(hueIndex + '.col_r')](), 0, 255)    
                +                            value_g = self._limit_range_int(self._sendLampItems[(hueIndex + '.col_g')](), 0, 255)    
                +                            value_b = self._limit_range_int(self._sendLampItems[(hueIndex + '.col_b')](), 0, 255)    
                +
                +                            xyPoint = self.getXYPointFromRGB(value_r, value_g, value_b, int(hueLampType))
                +                            # und jetzt der wert setzen
                +                            self._set_lamp_state(hueBridgeId, hueLampId, {'xy': xyPoint, 'transitiontime': hueTransitionTime})
                +                        else:
                +                            logger.warning('HUE: update_lamp_item: on or more of the col... items around item [{0}] is not defined'.format(item))
                +                    else:
                +                        # standardbefehle
                +                        self._set_lamp_state(hueBridgeId, hueLampId, {hueSend: value, 'transitiontime': hueTransitionTime})
                +            else:
                +                # lampe ist im status bei sh aus. in diesem zustand sollten keine befehle gesendet werden
                +                if hueSend == 'on':
                +                    # sonderfall, wenn der status die transition erst ausgeöst hat, dann muss die lampe
                +                    # auf der hue seite erst ausgeschaltet werden
                +                    self._set_lamp_state(hueBridgeId, hueLampId, {'on': False , 'transitiontime': hueTransitionTime})
                +                else:
                +                    # die lampe kann auch über das senden bri angemacht werden
                +                    if hueSend == 'bri':
                +                        # jetzt wird die lampe eingeschaltet und der wert von bri auf den letzten wert gesetzt
                +                        self._set_lamp_state(hueBridgeId, hueLampId, {'on': True , 'bri': value, 'transitiontime': hueTransitionTime})
                +                    else:
                +                        # ansonsten wird kein befehl abgesetzt !
                +                        pass
                +
                +    def update_group_item(self, item, caller=None, source=None, dest=None):
                +        # methode, die bei einer änderung des items ausgerufen wird wenn die änderung von aussen kommt, dann wird diese abgearbeitet
                +        # im konkreten fall heisst das, dass der aktuelle status der betroffene lampe komplett zusammengestellt wird
                +        # und anschliessen neu über die hue bridge gesetzt wird.
                +        if caller != 'HUE':
                +            # lokale speicherung in variablen, damit funktionen nicht immer aufgerufen werden (performance)
                +            value = item()
                +            hueBridgeId = item.conf['hue_bridge_id']
                +            hueGroupId = item.conf['hue_group_id']
                +            hueSendGroup = item.conf['hue_send_group']
                +            if 'hue_transitionTime' in item.conf:
                +                hueTransitionTime = int(float(item.conf['hue_transitionTime']) * 10)
                +            else:
                +                hueTransitionTime = int(self._hueDefaultTransitionTime * 10)
                +
                +            # index ist immer bridge_id + lamp_id + hue_send
                +            hueIndex = hueBridgeId + '.' + hueGroupId
                +            
                +            if hueIndex + '.on' in self._sendGroupItems:
                +                hueGroupIsOn = self._sendGroupItems[(hueIndex + '.on')]()
                +            else:
                +                logger.warning('HUE: update_group_item: no item for on/off defined for bridge {0} group {1}'.format(hueBridgeId, hueGroupId))
                +                hueGroupIsOn = False
                +                
                +            # test aus die wertgrenzen, die die bridge verstehen kann
                +            if hueSendGroup in self._rangeInteger8:
                +                # werte dürfen zwischen 0 und 255 liegen
                +                value = self._limit_range_int(value, 0, 255)    
                +            if hueSendGroup in self._rangeInteger16:
                +                # hue darf zwischen 0 und 65535 liegen
                +                value = self._limit_range_int(value, 0, 65535)    
                +            if hueSendGroup == 'ct':
                +                # hue darf zwischen 0 und 65535 liegen
                +                value = self._limit_range_int(value, 153, 500)
                +                
                +            if hueGroupIsOn:
                +                # lampe ist an (status in sh). dann können alle befehle gesendet werden
                +                if hueSendGroup == 'on':
                +                    # wenn der status in sh true ist, aber mit dem befehl on, dann muss die lampe auf der hue seite erst eingeschaltet werden
                +                    if hueIndex + '.bri' in self._sendLampItems:
                +                        # wenn eingeschaltet wird und ein bri item vorhanden ist, dann wird auch die hellgkeit
                +                        # mit gesetzt, weil die gruppe das im ausgeschalteten zustand vergisst.
                +                        self._set_group_state(hueBridgeId, hueGroupId, {'on': True, 'bri': int(self._sendLampItems[(hueIndex + '.bri')]()) , 'transitiontime': hueTransitionTime})
                +                    else:
                +                        # ansonst wird nur eingeschaltet
                +                        self._set_group_state(hueBridgeId, hueGroupId, {'on': True , 'transitiontime': hueTransitionTime})
                +                        logger.info('HUE: update_lamp_item: no bri item defined for restoring the brightness after swiching on again')                        
                +                else:
                +                    # standardbefehle
                +                    self._set_group_state(hueBridgeId, hueGroupId, {hueSendGroup: value, 'transitiontime': hueTransitionTime})
                +            else:
                +                # lampe ist im status bei sh aus. in diesem zustand sollten keine befehle gesendet werden
                +                if hueSendGroup == 'on':
                +                    # sonderfall, wenn der status die transition erst ausgeöst hat, dann muss die gruppe
                +                    # auf der hue seite erst ausgeschaltet werden
                +                    self._set_group_state(hueBridgeId, hueGroupId, {'on': False , 'transitiontime': hueTransitionTime})
                +                else:
                +                    # die lampe kann auch über das senden bri angemacht werden
                +                    if hueSendGroup == 'bri':
                +                        # jetzt wird die gruppe eingeschaltet und der wert von bri auf den letzten wert gesetzt
                +                        self._set_group_state(hueBridgeId, hueGroupId, {'on': True , 'bri': value, 'transitiontime': hueTransitionTime})
                +                    else:
                +                        # ansonsten wird kein befehl abgesetzt !
                +                        pass                           
                +                           
                +    def update_bridge_item(self, item, caller=None, source=None, dest=None):
                +        # methode, die bei einer änderung des items ausgerufen wird
                +        # wenn die änderung von aussen kommt, dann wird diese abgearbeitet
                +        # im konkreten fall heisst das, dass der aktuelle status der betroffene lampe komplett zusammengestellt wird
                +        # und anschliessen neu über die hue bridge gesetzt wird.
                +        if caller != 'HUE':
                +            # lokale speicherung in variablen, damit funktionen nicht immer aufgerufen werden (performance)
                +            value = item()
                +            hueBridgeId = item.conf['hue_bridge_id']
                +            hueSend = item.conf['hue_send']
                +            # test aus die wertgrenzen, die die bridge verstehen kann
                +            if hueSend in self._rangeInteger8:
                +                # werte dürfen zwischen 0 und 255 liegen
                +                value = self._limit_range_int(value, 0, 255)    
                +            if hueSend in self._rangeInteger16:
                +                # hue darf zwischen 0 und 65535 liegen
                +                value = self._limit_range_int(value, 0, 65535)    
                +            self._set_group_state(hueBridgeId, '0', {hueSend: value})
                +                                   
                +    def dimmenDPT3(self, item, caller=None, source=None, dest=None):
                +        # das ist die methode, die die DPT3 dimmnachrichten auf die dimmbaren hue items mapped
                +        # fallunterscheidung dimmen oder stop
                +        if caller != 'HUE':
                +            # auswertung der list werte für die KNX daten
                +            # [1] steht für das dimmen
                +            # [0] für die richtung
                +            # es wird die fading funtion verwendet
                +            valueMax = float(item.conf['hue_dim_max'])
                +            valueDimStep = float(item.conf['hue_dim_step'])
                +            valueDimTime = float(item.conf['hue_dim_time'])
                +            if item()[1] == 1:
                +                # dimmen
                +                if item()[0] == 1:
                +                    # hoch
                +                    item.return_parent().fade(valueMax, valueDimStep, valueDimTime)
                +                else:
                +                    # runter
                +                    item.return_parent().fade(0, valueDimStep, valueDimTime)
                +            else:
                +                # stop, indem man einen wert setzt. da es nicht der gleiche wert sein darf, erst einmal +1, dann -1
                +                # das ist aus meiner sicht noch ein fehler in item.py
                +                item.return_parent()(int(item.return_parent()() + 1), 'HUE_FADE')
                +                item.return_parent()(int(item.return_parent()() - 1), 'HUE_FADE')
                +                
                +    def  _get_web_content(self, hueBridgeId='0', path='', method='GET', body=None):
                +        # in dieser routine erfolgt der umbau und die speziellen themen zur auswertung der verbindung, die speziell für das plugin ist
                +        # der rest sollte standard in der routine fetch_url() enthalten sein. leider fehlt dort aber die auswertung der fehllerconditions
                +        # erst einmal die komplette url
                +        url = 'http://' + self._hue_ip[int(hueBridgeId)] + '/api/' + self._hue_user[int(hueBridgeId)] + path
                +        # setzen des fehlerstatus items
                +        if hueBridgeId + '.' + 'errorstatus' in self._listenBridgeItems:
                +            errorItem = self._listenBridgeItems[hueBridgeId + '.' + 'errorstatus']
                +        else:
                +            errorItem = None
                +            logger.info('HUE: _get_web_content '+hueBridgeId)
                +        # dann der aufruf kompatibel, aber inhaltlich nicht identisch fetch_url aus lib.tools, daher erst eimal das fehlerobjekt nicht mehr da
                +        response = client.fetch_url(url, None, None, 2, 0, method, body, errorItem)
                +        if response:
                +            # und jetzt der anteil der decodierung, der nicht in der fetch_url drin ist
                +            # lesen, decodieren nach utf-8 (ist pflicht nach der api definition philips) und in ein python objekt umwandeln
                +            responseJson = response.decode('utf-8')
                +            returnValues = json.loads(responseJson)
                +            # fehlerauswertung der rückmeldung, muss noch vervollständigt werden
                +            if isinstance(returnValues, list) and returnValues[0].get('error', None):
                +                error = returnValues[0]["error"]
                +                description = error['description']
                +                if error['type'] == 1:
                +                    logger.error('HUE: _request: Error: {0} (Need to specify correct hue user?)'.format(description))
                +                else:
                +                    logger.error('HUE: _request: Error: {0}'.format(description))
                +                return None
                +            return returnValues
                +        else:
                +            return None
                +
                +    def _set_lamp_state(self, hueBridgeId, hueLampId, state):
                +        # hier erfolgt das setzen des status einer lampe
                +        # hier kommt der PUT request, um die stati an die hue bridge zu übertragen
                +        self._hueLock.acquire()
                +        returnValues = self._get_web_content(hueBridgeId, '/lights/%s/state' % hueLampId, 'PUT', json.dumps(state))
                +        if returnValues == None:
                +            self._hueLock.release()
                +            return
                +        # der aufruf liefert eine bestätigung zurück, was den numgesetzt werden konnte
                +        for hueObject in returnValues:
                +            for hueObjectStatus, hueObjectReturnString in hueObject.items():
                +                if hueObjectStatus == 'success':
                +                    for hueObjectReturnStringPath, hueObjectReturnStringValue in hueObjectReturnString.items():
                +                        hueObjectReturnStringPathItem = hueObjectReturnStringPath.split('/')[4]
                +                        # hier werden jetzt die bestätigten werte aus der rückübertragung im item gesetzt
                +                        # wir gehen durch alle listen items, um die zuordnung zu machen
                +                        for returnItem in self._listenLampItems:
                +                            # wenn ein listen item angelegt wurde und dafür ein status zurückkam
                +                            # verglichen wird mit dem referenzkey, der weiter oben aus lampid und state gebaut wurde
                +                            if returnItem == (hueBridgeId + '.' + hueLampId + '.' + hueObjectReturnStringPathItem):
                +                                # dafür wir der reale wert der hue bridge gesetzt
                +                                if hueObjectReturnStringPathItem in self._boolKeys:
                +                                    # typecast auf bool
                +                                    value = bool(hueObjectReturnStringValue)
                +                                elif hueObjectReturnStringPathItem in self._stringKeys:
                +                                    # typecast auf string
                +                                    value = str(hueObjectReturnStringValue)
                +                                else:
                +                                    # sonst ist es int
                +                                    value = int(hueObjectReturnStringValue)
                +                                self._listenLampItems[returnItem](value, 'HUE')
                +                else:
                +                    logger.warning('HUE: hue_set_lamp_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                +        self._hueLock.release()
                +
                +    def _set_group_state(self, hueBridgeId, hueGroupId , state):
                +        # hier erfolgt das setzen des status einer gruppe im Moment ist nur der abruf einer szene implementiert
                +        # hier kommt der PUT request, um die stati an die hue bridge zu übertragen
                +        self._hueLock.acquire()
                +        returnValues = self._get_web_content(hueBridgeId, '/groups/%s/action' % hueGroupId, 'PUT', json.dumps(state))
                +        if returnValues == None:
                +            self._hueLock.release()
                +            return
                +        # der aufruf liefert eine bestätigung zurück, was den numgesetzt werden konnte
                +        for hueObject in returnValues:
                +            for hueObjectStatus, hueObjectReturnString in hueObject.items():
                +                if hueObjectStatus == 'success':
                +                    pass
                +                else:
                +                    logger.warning('HUE: _set_group_state - hueObjectStatus no success:: {0}: {1} command state {2}'.format(hueObjectStatus, hueObjectReturnString, state))
                +        self._hueLock.release()
                +
                +    def _update_lamps(self):
                +        # mache ich mit der API get all lights
                +        # hier kommt der PUT request, um die stati an die hue bridge zu übertragen beispiel:
                +        numberBridgeId = 0
                +        while numberBridgeId < self._numberHueBridges:
                +            hueBridgeId = str(numberBridgeId)
                +            self._hueLock.acquire()
                +            returnValues = self._get_web_content(hueBridgeId, '/lights')
                +            if returnValues == None:
                +                self._hueLock.release()
                +                return
                +            # schleife über alle gefundenen lampen
                +            for hueLampId, hueLampIdValues in returnValues.items():
                +                # schleife über alle rückmeldungen der lampen.
                +                # jetzt muss ich etwas tricksen, da die states eine ebene tiefer als die restlichen infos der lampe liegen
                +                # in den items ist das aber eine flache hierachie. um nur eine schleife darüber zu haben, baue ich mir ein
                +                # entsprechendes dict zusammen. 'state' ist zwar doppelt drin, stört aber nicht, da auch auf unterer ebene.
                +                dictOptimized = hueLampIdValues['state'].copy()
                +                dictOptimized.update(returnValues[hueLampId].items())
                +                # jetzt kann der durchlauf beginnen
                +                for hueObjectItem, hueObjectItemValue in dictOptimized.items():
                +                    # nachdem alle objekte und werte auf die gleiche ebene gebracht wurden, beginnt die zuordnung
                +                    # vor hier an werden die ganzen listen items durchgesehen und die werte aus der rückmeldung zugeordnet
                +                    for returnItem in self._listenLampItems:
                +                        # wenn ein listen item angelegt wurde und dafür ein status zurückkam
                +                        # verglichen wird mit dem referenzkey, der weiter oben aus lampid und state gebaut wurde
                +                        if returnItem == (hueBridgeId + '.' + hueLampId + '.' + hueObjectItem):
                +                            # dafür wir der reale wert der hue bridge gesetzt
                +                            if hueObjectItem in self._boolKeys:
                +                                value = bool(hueObjectItemValue)
                +                            elif hueObjectItem in self._stringKeys:
                +                                value = str(hueObjectItemValue)
                +                            else:
                +                                value = int(hueObjectItemValue)
                +                            # wenn der wert gerade im fading ist, dann nicht überschreiben, sonst bleibt es stehen !
                +                            if not self._listenLampItems[returnItem]._fading:
                +                                # es werden nur die Einträge zurückgeschrieben, falls die Lampe nich im fading betrieb ist
                +                                if hueObjectItem == 'bri':
                +                                    # bei brightness gibt es eine fallunterscheidung
                +                                    if hueBridgeId + '.' + hueLampId + '.on' in self._listenLampItems:
                +                                        # geht aber nur, wenn ein solches item vorhanden ist
                +                                        if self._listenLampItems[(hueBridgeId + '.' + hueLampId + '.on')]():
                +                                            # die brightness darf nur bei lamp = on zurückgeschrieben werden, den bei aus ist sie immer 0
                +                                            self._listenLampItems[returnItem](value, 'HUE')
                +                                else:
                +                                    # bei allen anderen kann zurückgeschrieben werden
                +                                    self._listenLampItems[returnItem](value, 'HUE')
                +            self._hueLock.release()
                +            numberBridgeId = numberBridgeId + 1
                +
                +    def _update_groups(self):
                +        # mache ich mit der API get all groups
                +        # hier kommt der PUT request, um die stati an die hue bridge zu übertragen beispiel:
                +        numberBridgeId = 0
                +        while numberBridgeId < self._numberHueBridges:
                +            hueBridgeId = str(numberBridgeId)
                +            self._hueLock.acquire()
                +            returnValues = self._get_web_content(hueBridgeId, '/groups')
                +            if returnValues == None:
                +                self._hueLock.release()
                +                return
                +            # schleife über alle gefundenen lampen
                +            for hueGroupId, hueGroupIdValues in returnValues.items():
                +                # schleife über alle rückmeldungen der lampen.
                +                # jetzt muss ich etwas tricksen, da die states eine ebene tiefer als die restlichen infos der lampe liegen
                +                # in den items ist das aber eine flache hierachie. um nur eine schleife darüber zu haben, baue ich mir ein
                +                # entsprechendes dict zusammen. 'state' ist zwar doppelt drin, stört aber nicht, da auch auf unterer ebene.
                +                if 'state' in hueGroupIdValues:
                +                    dictOptimized = hueGroupIdValues['state'].copy()
                +                    dictOptimized.update(returnValues[hueGroupId].items())
                +                    # jetzt kann der durchlauf beginnen
                +                    for hueObjectItem, hueObjectItemValue in dictOptimized.items():
                +                        # nachdem alle objekte und werte auf die gleiche ebene gebracht wurden, beginnt die zuordnung
                +                        # vor hier an werden die ganzen listen items durchgesehen und die werte aus der rückmeldung zugeordnet
                +                        for returnItem in self._listenGroupItems:
                +                            # wenn ein listen item angelegt wurde und dafür ein status zurückkam
                +                            # verglichen wird mit dem referenzkey, der weiter oben aus lampid und state gebaut wurde
                +                            if returnItem == (hueBridgeId + '.' + hueGroupId + '.' + hueObjectItem):
                +                                # dafür wir der reale wert der hue bridge gesetzt
                +                                if hueObjectItem in self._boolKeys:
                +                                    value = bool(hueObjectItemValue)
                +                                elif hueObjectItem in self._stringKeys:
                +                                    value = str(hueObjectItemValue)
                +                                else:
                +                                    value = int(hueObjectItemValue)
                +                                # wenn der wert gerade im fading ist, dann nicht überschreiben, sonst bleibt es stehen !
                +                                if not self._listenGroupItems[returnItem]._fading:
                +                                    # es werden nur die Einträge zurückgeschrieben, falls die Lampe nich im fading betrieb ist
                +                                    if hueObjectItem == 'bri':
                +                                        # bei brightness gibt es eine fallunterscheidung
                +                                        if hueBridgeId + '.' + hueGroupId + '.on' in self._listenGroupItems:
                +                                            # geht aber nur, wenn ein solches item vorhanden ist
                +                                            if self._listenGroupItems[(hueBridgeId + '.' + hueGroupId + '.on')]():
                +                                                # die brightness darf nur bei lamp = on zurückgeschrieben werden, den bei aus ist sie immer 0
                +                                                self._listenGroupItems[returnItem](value, 'HUE')
                +                                    else:
                +                                        # bei allen anderen kann zurückgeschrieben werden
                +                                        self._listenLampItems[returnItem](value, 'HUE')
                +            self._hueLock.release()
                +            numberBridgeId = numberBridgeId + 1
                +
                +    def _update_bridges(self):
                +        # der datenabruf besteht aus dem befehl get configuration bridge
                +        numberBridgeId = 0
                +        while numberBridgeId < self._numberHueBridges:
                +            hueBridgeId = str(numberBridgeId)
                +            self._hueLock.acquire()
                +            returnValues = self._get_web_content(hueBridgeId, '/config')
                +            if returnValues == None:
                +                self._hueLock.release()
                +                return
                +            # schleife über alle gefundenen lampen
                +            for hueObjectItem, hueObjectItemValue in returnValues.items():
                +                # nachdem alle objekte und werte auf die gleiche ebene gebracht wurden, beginnt die zuordnung
                +                # vor hier an werden die ganzen listen items durchgesehen und die werte aus der rückmeldung zugeordnet
                +                for returnItem in self._listenBridgeItems:
                +                    # wenn ein listen item angelegt wurde und dafür ein status zurückkam
                +                    # verglichen wird mit dem referenzkey, der weiter oben aus lampid und state gebaut wurde
                +                    if hueObjectItem == 'swversion':
                +                        hueObjectItem = 'bridge_swversion'
                +                    if hueObjectItem == 'name':
                +                        hueObjectItem = 'bridge_name'
                +                    if returnItem == (hueBridgeId + '.' + hueObjectItem):
                +                        # dafür wir der reale wert der hue bridge gesetzt
                +                        if hueObjectItem in self._boolKeys:
                +                            value = bool(hueObjectItemValue)
                +                        elif hueObjectItem in self._stringKeys:
                +                            value = str(hueObjectItemValue)
                +                        elif hueObjectItem in self._dictKeys:
                +                            value = dict(hueObjectItemValue)
                +                        else:
                +                            value = int(hueObjectItemValue)
                +                        # wenn der wert gerade im fading ist, dann nicht überschreiben, sonst bleibt es stehen !
                +                        self._listenBridgeItems[returnItem](value, 'HUE')
                +            self._hueLock.release()
                +            numberBridgeId = numberBridgeId + 1
                +
                +    def get_config(self, hueBridgeId='0'):
                +        # hier eine interaktive routing für di ecli, um den user herauszubekommen, 
                +        # mit dem die szenen gesetzt worden sind, um ihn dann als user für das plugin einzusetzen
                +        # und jetzt alle szenen
                +        returnValues = self._get_webcontent(hueBridgeId, '/scenes')
                +        logger.warning('HUE: get_config: Scenes {0}'.format(returnValues))
                +        returnValues = self._get_webcontent(hueBridgeId, '/groups')
                +        logger.warning('HUE: get_config: Groups {0}'.format(returnValues))
                +        return returnValues
                +
                +    def authorizeuser(self, hueBridgeId='0'):
                +        data = json.dumps(
                +            {"devicetype": "smarthome", "username": self._hue_user[int(hueBridgeId)]})
                +        con = http.client.HTTPConnection(self._hue_ip[int(hueBridgeId)])
                +        con.request("POST", "/api", data)
                +        resp = con.getresponse()
                +        con.close()
                +        if resp.status != 200:
                +            logger.error('HUE: authorize: Authenticate request failed')
                +            return "Authenticate request failed"
                +        resp = resp.read()
                +        logger.debug(resp)
                +        resp = json.loads(resp)
                +        logger.debug(resp)
                +        return resp
                +
                diff --git a/hue/_pv_1_1_83/plugin.yaml b/hue/_pv_1_1_83/plugin.yaml
                new file mode 100755
                index 000000000..ca58b5f89
                --- /dev/null
                +++ b/hue/_pv_1_1_83/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung einer oder mehrerer Philips HUE Bridges'
                +        en: ''
                +    maintainer: mworion
                +    tester: Sandman60
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/41379-philips-hue-plugin-neu-v1-0-released
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: HUE                  # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/hue/_pv_1_1_83/sv_widgets/widget_hue.html b/hue/_pv_1_1_83/sv_widgets/widget_hue.html
                new file mode 100755
                index 000000000..551df639f
                --- /dev/null
                +++ b/hue/_pv_1_1_83/sv_widgets/widget_hue.html
                @@ -0,0 +1,120 @@
                +/**
                + * Hue Widget
                + * (c) 2015 Michael Würtenberger
                + * 
                + * @param       unique id for this widget
                + * @param       the gad/item for the power (optional)
                + * @param       the gad/item for the volume (optional)
                + * @param       the gad/item for the mute (optional)
                + * @param       the gad/item for the song title (optional)
                + * @param       the gad/item to set surround mode (optional)
                + * @param       the gad/item to set input (optional)
                + *
                + */
                +{% macro control(id,g_power,g_reach,g_r,g_g,g_b,g_alert,g_effect,g_bri,g_sat,g_hue) %}
                +{% import "basic.html" as basic %}
                +
                +<table height="90%" width="90%" align="center">
                +	<tr>
                +		<td width="15%" align="center">
                +			{{basic.dual(id~'power',g_power)}}
                +		</td>
                +		<td width="15%" align="center">
                +			{{basic.symbol(id~'reachon',g_reach,'',icon1~'it_wifi.png','1')}}
                +			{{basic.symbol(id~'reachoff',g_reach,'',icon0~'it_wifi.png','0')}}
                +		</td>
                +		<td width="15%" align="center">
                +			{{basic.rgb(id~'rgb',g_r,g_g,g_b,0,255,'',8)}}
                +		</td>
                +		<td width="25%" align="center">
                +			Alert:{{basic.dual(id~'alert',g_alert,icon1~'audio_pause.png', icon1~'audio_play.png', 'lselect','none')}}
                +		</td>
                +		<td width="25%" align="center">
                +			Effect:{{basic.dual(id~'effect',g_effect,icon1~'audio_pause.png', icon1~'audio_play.png', 'colorloop',	'none')}}
                +		</td>
                +	</tr>
                +</table>
                +<table height="90%" width="90%" align="center">
                +	<tr>
                +		<td width="15%" align="left">
                +		Helligkeit
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'bri',g_bri,0,255,5)}}
                +		</td>
                +	</tr>
                +	<tr>
                +		<td width="15%" align="left">
                +			Sättigung
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'sat',g_sat,0,255,5)}}
                +		</td>
                +	</tr>
                +	<tr>
                +		<td width="15%" align="left">
                +			Farbe
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'hue',g_hue,0,65535,500)}}
                +		</td>
                +	</tr>
                +</table>
                +{% endmacro %}
                +
                +/**
                + * Hue Widget
                + * (c) 2015 Michael Würtenberger
                + * 
                + * @param       unique id for this widget
                + * @param       the gad/item for the power (optional)
                + * @param       the gad/item for the volume (optional)
                + * @param       the gad/item for the mute (optional)
                + * @param       the gad/item for the song title (optional)
                + * @param       the gad/item to set surround mode (optional)
                + * @param       the gad/item to set input (optional)
                + *
                + */
                +{% macro control_group(id,g_power,g_alert,g_effect,g_bri,g_sat,g_hue) %}
                +{% import "basic.html" as basic %}
                +
                +<table height="90%" width="90%" align="center">
                +	<tr>
                +		<td width="15%" align="center">
                +			{{basic.dual(id~'power',g_power)}}
                +		</td>
                +		<td width="25%" align="center">
                +			Alert:{{basic.dual(id~'alert',g_alert,icon1~'audio_pause.png', icon1~'audio_play.png', 'lselect','none')}}
                +		</td>
                +		<td width="25%" align="center">
                +			Effect:{{basic.dual(id~'effect',g_effect,icon1~'audio_pause.png', icon1~'audio_play.png', 'colorloop',	'none')}}
                +		</td>
                +	</tr>
                +</table>
                +<table height="90%" width="90%" align="center">
                +	<tr>
                +		<td width="15%" align="left">
                +		Helligkeit
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'bri',g_bri,0,255,5)}}
                +		</td>
                +	</tr>
                +	<tr>
                +		<td width="15%" align="left">
                +			Sättigung
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'sat',g_sat,0,255,5)}}
                +		</td>
                +	</tr>
                +	<tr>
                +		<td width="15%" align="left">
                +			Farbe
                +		</td>
                +		<td width="85%">
                +			{{basic.slider(id~'hue',g_hue,0,65535,500)}}
                +		</td>
                +	</tr>
                +</table>
                +{% endmacro %}
                \ No newline at end of file
                diff --git a/hue/plugin.yaml b/hue/plugin.yaml
                new file mode 100755
                index 000000000..987d2626e
                --- /dev/null
                +++ b/hue/plugin.yaml
                @@ -0,0 +1,70 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung einer oder mehrerer Philips HUE Bridges'
                +        en: 'Gateway for connection to one or more Philips HUE bridges'
                +    maintainer: mworion, msinn
                +    tester: Sandman60
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/41379-philips-hue-plugin-neu-v1-0-released
                +
                +    version: 1.4.2                 # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False
                +    classname: HUE                  # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +
                +    hue_ip:
                +        type: list(ip)
                +        description:
                +            de: 'IP Adresse der Philips HUE Bridge'
                +            en: 'ip address of the Philips HUE bridge'
                +        mandatory: True
                +        
                +    hue_port:
                +        type: list(int)
                +        default: 80
                +        valid_min: 0
                +        description:
                +            de: 'Port für die the Philips HUE Bridge'
                +            en: 'Port on the Philips HUE bridge'
                +    
                +    hue_user:
                +        type: list(str)
                +        description:
                +            de: 'User um sich an der Philips HUE Bridge anzumelden'
                +            en: 'User to login to the Philips HUE bridge'
                +   
                +    cycle_lamps:
                +        type: int
                +        default: 10
                +        valid_min: 5
                +        description:
                +            de: 'Abfrage-Zyklus für Leuchten Updates'
                +            en: 'Cycle time for update of lamps'
                +    
                +    cycle_bridges:
                +        type: int
                +        default: 60
                +        valid_min: 10
                +        description:
                +            de: 'Abfrage-Zyklus für Bridge Updates'
                +            en: 'Cycle time for update of bridges'
                +    
                +    default_transitionTime:
                +        type: float
                +        default: 0.4
                +        valid_min: 0
                +        description:
                +            de: 'Zeitraum zwischen den den Checks der Leuchten durch die HUE Bridge selbst'
                +            en: 'Time in seconds how fast check states of the lamps are changed through the bridge itself'
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/hue/sv_widgets/widget_hue.html b/hue/sv_widgets/widget_hue.html
                index 551df639f..04a713e39 100755
                --- a/hue/sv_widgets/widget_hue.html
                +++ b/hue/sv_widgets/widget_hue.html
                @@ -34,7 +34,7 @@
                 		</td>
                 	</tr>
                 </table>
                -<table height="90%" width="90%" align="center">
                +<table height="85%" width="90%" align="center">
                 	<tr>
                 		<td width="15%" align="left">
                 		Helligkeit
                @@ -117,4 +117,4 @@
                 		</td>
                 	</tr>
                 </table>
                -{% endmacro %}
                \ No newline at end of file
                +{% endmacro %}
                diff --git a/iaqstick/plugin.yaml b/iaqstick/plugin.yaml
                new file mode 100755
                index 000000000..af2d22697
                --- /dev/null
                +++ b/iaqstick/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für Applied Sensor iAQ Stick und Voltcraft CO-20'
                +        en: ''
                +    maintainer: '? (Robert Budde )'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: iAQ_Stick            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/ical/plugin.yaml b/ical/plugin.yaml
                new file mode 100755
                index 000000000..05eb35b45
                --- /dev/null
                +++ b/ical/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Ermöglicht die Verwendung von Kalendern (ICS)'
                +        en: ''
                +    maintainer: cmalo (mknx)
                +    tester: ohinckel
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: iCal                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/influxdata/README.md b/influxdata/README.md
                index 51c71130e..14c993b29 100644
                --- a/influxdata/README.md
                +++ b/influxdata/README.md
                @@ -1,4 +1,4 @@
                -# smarthome-influxdata
                +# influxdata
                 Plugin to store data from smarthome.py in InfluxData TSDB i.e. for graphing with Grafana or Chronograf.
                 This plugin uses InfluxData UDP line protocol for non-blocking execution.
                 
                diff --git a/influxdata/plugin.yaml b/influxdata/plugin.yaml
                new file mode 100755
                index 000000000..ef20d46d7
                --- /dev/null
                +++ b/influxdata/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Ermöglicht Speicherung von Daten in InfluxData TSDB z.B. zur Erzeugung von Graphen mit Grafana oder Chronograf (Plugin aus 2016)'
                +        en: ''
                +    maintainer: rthill
                +    tester: brandst
                +    keywords: database
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Installation-Influx-Grafana        # url of documentation (wiki) page
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: InfluxData          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/influxdb/plugin.yaml b/influxdb/plugin.yaml
                new file mode 100755
                index 000000000..3ea25887d
                --- /dev/null
                +++ b/influxdb/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Ermöglicht Speicherung von Item Werten in einer InfluxData time-series Datenbank (Plugin aus 2017)'
                +        en: ''
                +    maintainer: Kai Meder
                +#    tester:                        # Who tests this plugin?
                +    keywords: database
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Installation-Influx-Grafana        # url of documentation (wiki) page
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: InfluxDB            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/intercom_2n/plugin.yaml b/intercom_2n/plugin.yaml
                new file mode 100755
                index 000000000..9f693aad0
                --- /dev/null
                +++ b/intercom_2n/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Integration von 2N SIP-Türsprechanlagen'
                +        en: ''
                +    maintainer: pfischi
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1030539-plugin-2n-intercom
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Intercom2n          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/intercom_2n/requirements.txt b/intercom_2n/requirements.txt
                index a5e10409a..648060e1e 100644
                --- a/intercom_2n/requirements.txt
                +++ b/intercom_2n/requirements.txt
                @@ -1 +1,2 @@
                -requests>=2.9.1
                \ No newline at end of file
                +requests>=2.9.1;python_version>'3.2'
                +requests==2.5.1;python_version=='3.2'
                diff --git a/join/plugin.yaml b/join/plugin.yaml
                new file mode 100755
                index 000000000..8880ebb8c
                --- /dev/null
                +++ b/join/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Ermöglicht die Verwendung der Join API'
                +        en: ''
                +    maintainer: Knx_fan
                +    tester: psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1113523-neues-plugin-join-tts-sms-phonecall-notification-uvm
                +
                +    version: 1.4.1.0               # Plugin version
                +    sh_minversion: 1.3a            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Join                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/kathrein/plugin.yaml b/kathrein/plugin.yaml
                new file mode 100755
                index 000000000..be424bb4b
                --- /dev/null
                +++ b/kathrein/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Kathrein Receiver'
                +        en: ''
                +    maintainer: '? (Johannes Mayr)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Kathrein            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/knx/README.md b/knx/README.md
                index bc8e46a3f..1616ea602 100644
                --- a/knx/README.md
                +++ b/knx/README.md
                @@ -84,30 +84,31 @@ The DPT has to match the type of the item!
                 
                 The following datapoint types are supported:
                 
                -| DPT                 | Data                  | Type            | Values
                -| ------------------- | --------------------- | --------------- | ---------------------------------------------------------------------------
                -| 1                   | 1 bit                 | bool            | True or False
                -| 2                   | 2 bit                 | list            | \[0, 0\] - \[1, 1\]
                -| 3                   | 4 bit                 | list            | \[0, 0\] - \[1, 7\]
                -| 4.002               | 8 bit                 | str             | 1 character (8859\_1) e.g. ‘c’
                -| 5                   | 8 bit                 | num             | 0 - 255
                -| 5.001               | 8 bit                 | num             | 0 - 100
                -| 6                   | 8 bit                 | num             | -128 - 127
                -| 7                   | 2 byte                | num             | 0 - 65535
                -| 8                   | 2 byte                | num             | -32768 - 32767
                -| 9                   | 2 byte                | num             | -671088,64 - 670760,96
                -| 10                  | 3 byte                | foo             | datetime.time
                -| 11                  | 3 byte                | foo             | datetime.date
                -| 12                  | 4 byte                | num             | 0 - 4294967295
                -| 13                  | 4 byte                | num             | -2147483648 - 2147483647
                -| 14                  | 4 byte                | num             | 4-Octet Float Value IEEE 754
                -| 16                  | 14 byte               | str             | 14 characters (ASCII)
                -| 16.001              | 14 byte               | str             | 14 characters (8859\_1)
                -| 17                  | 8 bit                 | num             | Scene: 0 - 63
                -| 20                  | 8 bit                 | num             | HVAC: 0 - 255
                -| 24                  | var                   | str             | unlimited string (8859\_1)
                -| 232                 | 3 byte                | list            | RGB: \[0, 0, 0\] - \[255, 255, 255\]
                -
                +```
                +|  DPT        |  Data         |  Type    |  Values
                +| ----------- | ------------- | -------- | ----------------------------------
                +|  1          |  1 bit        |  bool    |  True or False
                +|  2          |  2 bit        |  list    |  [0, 0] - [1, 1]
                +|  3          |  4 bit        |  list    |  [0, 0] - [1, 7]
                +|  4.002      |  8 bit        |  str     |  1 character (8859_1) e.g. ‘c’
                +|  5          |  8 bit        |  num     |  0 - 255
                +|  5.001      |  8 bit        |  num     |  0 - 100
                +|  6          |  8 bit        |  num     |  -128 - 127
                +|  7          |  2 byte       |  num     |  0 - 65535
                +|  8          |  2 byte       |  num     |  -32768 - 32767
                +|  9          |  2 byte       |  num     |  -671088,64 - 670760,96
                +|  10         |  3 byte       |  foo     |  datetime.time
                +|  11         |  3 byte       |  foo     |  datetime.date
                +|  12         |  4 byte       |  num     |  0 - 4294967295
                +|  13         |  4 byte       |  num     |  -2147483648 - 2147483647
                +|  14         |  4 byte       |  num     |  4-Octet Float Value IEEE 754
                +|  16         |  14 byte      |  str     |  14 characters (ASCII)
                +|  16.001     |  14 byte      |  str     |  14 characters (8859_1)
                +|  17         |  8 bit        |  num     |  Scene: 0 - 63
                +|  20         |  8 bit        |  num     |  HVAC: 0 - 255
                +|  24         |  var          |  str     |  unlimited string (8859_1)
                +|  232        |  3 byte       |  list    |  RGB: [0, 0, 0] - [255, 255, 255]
                +```
                 
                 
                 If you are missing one, open a bug report or drop me a message in the knx user forum.
                diff --git a/knx/__init__.py b/knx/__init__.py
                index d29614cbf..32157f2a8 100644
                --- a/knx/__init__.py
                +++ b/knx/__init__.py
                @@ -206,12 +206,12 @@ def _poll(self, **kwargs):
                             self.groupread(kwargs['ga'])
                         else:
                             self.logger.warning('KNX[{0}]: problem polling {1}, no known ga'.format(self.get_instance_name(), item))
                -        
                +
                         if 'interval' in kwargs and 'ga' in kwargs:
                             ga = kwargs['ga']
                             interval = int(kwargs['interval'])
                -            next = self._sh.now() + timedelta(seconds = interval)
                -            self._sh.scheduler.add('KNX[{0}] poll {1}'.format(self.get_instance_name(), item), self._poll,
                +            next = self._sh.now() + timedelta(seconds=interval)
                +            self._sh.scheduler.add('KNX poll {}'.format(item), self._poll,
                                                    value={'instance': self.get_instance_name(), ITEM: item, 'ga': ga, 'interval': interval},
                                                    next=next)
                 
                @@ -477,24 +477,23 @@ def parse_item(self, item):
                             return self.update_item
                 
                         if self.has_iattr(item.conf, KNX_POLL):
                -            #
                -            # Todo: 
                -            # - knx_poll = ga | poll_time
                -            # - use the instance aware function self.get_iattr_value instead of intem.conf[...]
                -            #
                -            if self.has_iattr(item.conf, KNX_LISTEN):
                -                knx_listen = item.conf[KNX_LISTEN]
                -                poll_interval = int(item.conf[KNX_POLL])
                +            knx_poll = self.get_iattr_value(item.conf, KNX_POLL)
                +            if isinstance(knx_poll, str):
                +                knx_poll = [knx_poll, ]
                +            if len(knx_poll) == 2:
                +                poll_ga = knx_poll[0]
                +                poll_interval = knx_poll[1]
                +
                                 self.logger.info(
                -                    "KNX[{0}]: Item {1} is polled on GA {2} every {3} seconds".format(self.get_instance_name(), item, knx_listen,
                +                    "KNX[{0}]: Item {1} is polled on GA {2} every {3} seconds".format(self.get_instance_name(), item, poll_ga,
                                                                                                       poll_interval))
                                 randomwait = random.randrange(15)
                                 next = self._sh.now() + timedelta(seconds=poll_interval + randomwait)
                -                self._sh.scheduler.add('KNX[{0}] poll {1}'.format(self.get_instance_name(), item), self._poll,
                -                                       value={ITEM: item, 'ga': knx_listen, 'interval': poll_interval}, next=next)
                +                self._sh.scheduler.add('KNX poll {}'.format(item), self._poll,
                +                                       value={ITEM: item, 'ga': poll_ga, 'interval': poll_interval}, next=next)
                             else:
                                 self.logger.warning(
                -                    "KNX[{0}]: Ignoring knx_poll for item {1}: please add a knx_listen GA to poll.".format(
                +                    "KNX[{0}]: Ignoring knx_poll for item {1}: We need two parameters, one for the GA and one for the polling interval.".format(
                                         self.get_instance_name(), item))
                                 pass
                 
                @@ -574,13 +573,13 @@ def update_item(self, item, caller=None, source=None, dest=None):
                     - adresses that do not react upon requests
                     - adresses that can't satisfy cache requests
                     """
                -    def enable_stats(sef):
                +    def enable_stats(self):
                         """
                         Enables the tracking of KNX telegrams during runtime of SmartHomeNG
                         """
                         self.enable_stats = True
                 
                -    def disable_stats(sef):
                +    def disable_stats(self):
                         """
                         Disables the tracking of KNX telegrams during runtime of SmartHomeNG
                         It might be a good idea to clear your stats afterwards with clear_stats()
                diff --git a/knx/plugin.yaml b/knx/plugin.yaml
                new file mode 100755
                index 000000000..fbfafdf54
                --- /dev/null
                +++ b/knx/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Anbindung von KNX Bussystemen via EIBD/KNXD'
                +        en: ''
                +    maintainer: cmalo
                +    tester: psilo909, onkelandy, Sandman60, brandst
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.4                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: KNX                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/kostal/README.md b/kostal/README.md
                index dc4d239a3..f651ea3ec 100644
                --- a/kostal/README.md
                +++ b/kostal/README.md
                @@ -1,7 +1,7 @@
                 # KOSTAL
                 
                -Version: 1.3.1.2
                -=======
                +### Version: 1.3.1.2
                +
                 ## Requirements
                 Kostal Inverter
                 
                diff --git a/kostal/plugin.yaml b/kostal/plugin.yaml
                new file mode 100755
                index 000000000..f89771cfb
                --- /dev/null
                +++ b/kostal/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung eines KOSTAL-Wechselrichters'
                +        en: ''
                +    maintainer: ohinckel
                +    tester: ohinckel, datenschuft
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.1.2               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Kostal              # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/lirc/README.md b/lirc/README.md
                new file mode 100644
                index 000000000..ec859d4fb
                --- /dev/null
                +++ b/lirc/README.md
                @@ -0,0 +1,120 @@
                +# lirc
                +
                +Sends commands to lircd that sends IR-signals to any device that has an IR-interface.
                +
                +## Requirements
                +
                +At least a running and listening lircd with an IR-transmitter, optional an IR-receiver (for learning remotes) and the remote configuration
                +file of your remote control. You can create this file by learning your remote with irrecord or use an existing file from the remotes database.
                +
                +For more information about lircd and the remotes database see http://www.lirc.org/html/lircd.html and http://lirc-remotes.sourceforge.net/
                +
                +
                +## Configuration
                +
                +### plugin.yaml
                +
                +```
                +lirc1:
                +    class_name: LIRC
                +    class_path: plugins.lirc
                +    instance: "livingroom"
                +    lirc_Host: "127.0.0.1"
                +#    lirc_Port: 6610
                +
                +lirc2:
                +    class_name: LIRC
                +    class_path: plugins.lirc
                +    instance: "hifisystem"
                +    lirc_host: "192.168.1.10"
                +#    lirc_port: 6610
                +```
                +
                +#### instance
                +This attribute is mandatory. You have to provide an unique identifier for every instance. That identifier will be used to relate the items to the
                +correct lircd.
                +
                +#### lirc_host
                +This attribute is mandatory. You have to provide the IP adress or the hostname of the lircd.
                +
                +#### lirc_port
                +You could specify a port to connect to. By default port 8765 is used.
                +
                +
                +### items.yaml
                +
                +If the value of an item configured in items.yaml is set or updated the plugin will send an command to lircd to send the related lirc_key n times
                +whereby n means the value that has been assigned to the item. The plugin will reset the item to 0.
                +e.g. DVDLIVINGROOM_POWER is set to 5  => lircd will send 5x POWER via IR
                +     DVDLIVINGROOM_POWER is set to 1  => lircd will send 1x POWER via IR
                +
                +
                +```
                +LIRC:
                +    REMOTE_DVDLIVINGROOM:
                +        DVDLIVINGROOM_POWER:
                +            type: num
                +            lirc_remote@instancename: "PHILIPSDVD"
                +            lirc_key@instancename: "POWER"
                +```
                +
                +#### lirc_remote@instancename
                +The name of the remote. This name has to match the name of the remote in lircd.
                +Add @instancename to assign the item to an specific instance configured in plugin.yaml
                +
                +#### lirc_key@instancename
                +The name of the key on the given remote. This name has to match the name of the key in lircd.
                +Add @instancename to assign the item to an specific instance configured in plugin.yaml
                +
                +#### Example
                +```
                +LIRC:
                +    REMOTE_DVDLIVINGROOM:
                +        DVDLIVINGROOM_POWER:
                +            type: num
                +            lirc_remote@livingroom: "PHILIPSDVD"
                +            lirc_key@livingroom: "POWER"
                +
                +    REMOTE_RADIOOFFICE:
                +        TEVION_RCD9211_POWER:
                +            type: num
                +            lirc_remote@hifisystem: "TEVION_RCD9211"
                +            lirc_key@hifisystem: "POWER"
                +        TEVION_RCD9211_FUNCTION:
                +            type: num
                +            lirc_remote@hifisystem: "TEVION_RCD9211"
                +            lirc_key@hifisystem: "FUNCTION"
                +        TEVION_RCD9211_VOLUP:
                +            type: num
                +            lirc_remote@hifisystem: "TEVION_RCD9211"
                +            lirc_key@hifisystem: "VOLUP"
                +        TEVION_RCD9211_VOLDOWN:
                +            type: num
                +            lirc_remote@hifisystem: "TEVION_RCD9211"
                +            lirc_key@hifisystem: "VOLDOWN"
                +```
                +
                +## Logging
                +
                +You can configure the logger to see specific outputs of the plugin. That's helpfull when setting up the plugin. To see e.g. the debug-outputs of
                +the plugin you have to configure the logging.yaml file. 
                +
                +
                +```
                +loggers:
                +    plugins.lirc:
                +       level: DEBUG
                +```
                +
                +That configured loglevel is used for all instances of the plugin. All output lines of the plulgin have a prefix to identify which instance gave the output.
                +e.g. 
                +
                +the output of the instance livingroom:
                +```
                +1970-01-01  00:00:00 INFO     Connections  lirc_livingroom: connected to lircd 0.9.4c on 127.0.0.1:8765
                +```
                +
                +the output of the instance hifisystem:
                +```
                +1970-01-01  00:00:00 INFO     Connections  lirc_hifisystem: connected to lircd 0.9.4c on 192.168.1.10:8765
                +```
                diff --git a/lirc/__init__.py b/lirc/__init__.py
                new file mode 100644
                index 000000000..a28e1ed6e
                --- /dev/null
                +++ b/lirc/__init__.py
                @@ -0,0 +1,160 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2017 Nino Coric                       mail2n.coric@gmail.com
                +#########################################################################
                +#  This file is part of SmartHomeNG.   
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                +#
                +#########################################################################
                +
                +import threading
                +import logging
                +import lib.connection
                +
                +from lib.model.smartplugin import SmartPlugin
                +
                +REMOTE_ATTRS = ['lirc_remote', 'lirc_key']
                +class LIRC(lib.connection.Client,SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = True
                +    PLUGIN_VERSION = "1.3.1"
                +
                +    def __init__(self, sh, lirc_Host, lirc_Port=8765):
                +        self.instance = self.get_instance_name()
                +        self.logger = logging.getLogger(__name__)
                +        self.lircHost = lirc_Host
                +        self.lircPort = lirc_Port
                +        lib.connection.Client.__init__(self, self.lircHost, self.lircPort, monitor=True)
                +        self._sh = sh
                +        self._cmd_lock = threading.Lock()
                +        self._reply_lock = threading.Condition()
                +        self.terminator = b'\n'
                +
                +        self.lircd_version = ''
                +        self._responseStr = None
                +        self._parseLine = 0
                +        self._error = False
                +
                +    def loggercmd (self, logstr, level):
                +        if not logstr:
                +            return
                +        logstr = 'lirc_' + self.instance + ': ' + logstr
                +        if level == 'i' or level == 'info':
                +            self.logger.info(logstr)
                +        elif level == 'w' or level == 'warning':
                +            self.logger.warning(logstr)
                +        elif level == 'd' or level == 'debug':
                +            self.logger.debug(logstr)
                +        else:
                +            self.logger.error(logstr)
                +
                +    def run(self):
                +        self.alive = True
                +
                +    def stop(self):
                +        self.alive = False
                +        self._reply_lock.acquire()
                +        self._reply_lock.notify()
                +        self._reply_lock.release()
                +        self.close()
                +
                +    def parse_item(self, item):
                +        if self.has_iattr(item.conf, REMOTE_ATTRS[0]) and \
                +           self.has_iattr(item.conf, REMOTE_ATTRS[1]):
                +                self.loggercmd("{}: callback assigned".format(item),'d')
                +                return self.update_item
                +        return None
                +
                +    def handle_connect(self):
                +        self.found_terminator = self.parse_response
                +        self.request_version()
                +
                +    def parse_response(self, data):
                +        data = data.decode()
                +        if data.startswith('BEGIN'):
                +            return None
                +        elif data.startswith('END'):
                +            self._parseLine = 0
                +            self._reply_lock.acquire()
                +            self._reply_lock.notify()
                +            self._reply_lock.release()
                +            return None
                +        if self._parseLine >= 0:
                +            self._parseLine += 1
                +            if self._parseLine == 1:
                +                self._responseStr = str(data) + '\n'
                +            elif self._parseLine == 2:
                +                if data.startswith('ERROR'):
                +                    self._error = True
                +                else:
                +                    self._error = False
                +            elif self._parseLine == 3:
                +                pass #ignore field DATA
                +            elif self._parseLine == 4:
                +                pass #ignore field n
                +            else:
                +                self._responseStr += str(data) + '\n'
                +
                +    def update_item(self, item, caller=None, source=None, dest=None):
                +        val = item()
                +        if val == 0:
                +            return None
                +        item(0)
                +        if val < 0:
                +            self.loggercmd("ignoring invalid value {}".format(val),'w')
                +        else:
                +            remote = self.get_iattr_value(item.conf,REMOTE_ATTRS[0])
                +            key = self.get_iattr_value(item.conf,REMOTE_ATTRS[1])
                +            self.loggercmd("update_item, val: {}".format(val),'d')
                +            self.loggercmd("remote: {}".format(remote),'d')
                +            self.loggercmd("key: {}".format(key),'d')
                +            command = "SEND_ONCE {} {} {}".format(remote,key,val)
                +            self.loggercmd("command: {}".format(command),'d')
                +            self._send(command)
                +
                +    def request_version(self):
                +        self.lircd_version = self._send("VERSION")
                +        if self.lircd_version:
                +            self.loggercmd("connected to lircd {} on {}:{}".format( \
                +            self.lircd_version.replace("VERSION\n","").replace("\n",""), \
                +            self.lircHost,self.lircPort),'i')
                +            return True
                +        else:
                +            self.loggercmd("lircd Version not detectable",'e')
                +            return False
                +
                +    def _send(self, command, reply=True):
                +        if not self.connected:
                +            return
                +        self._responseStr = None
                +        self._cmd_lock.acquire()
                +        self.loggercmd("send command: {}".format(command),'d')
                +        self._reply_lock.acquire()
                +        self.send((command + '\n').encode())
                +        if reply:
                +            self._reply_lock.wait(1)
                +        self._reply_lock.release()
                +        self._cmd_lock.release()
                +        if self._error:
                +            self.loggercmd("error from lircd: {}".format(self._responseStr),'e')
                +            self._error = False
                +        self.loggercmd("response: {}".format(self._responseStr),'d')
                +        return self._responseStr
                +
                +if __name__ == '__main__':
                +    myplugin = LIRC('smarthome-dummy')
                +    logging.basicConfig(level=logging.DEBUG, format='%(relativeCreated)6d %(threadName)s %(message)s')
                +    myplugin._send('VERSION')
                diff --git a/lirc/plugin.yaml b/lirc/plugin.yaml
                new file mode 100644
                index 000000000..3319c44fb
                --- /dev/null
                +++ b/lirc/plugin.yaml
                @@ -0,0 +1,43 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                  # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Sendet Kommandos an lircd das wiederum IR-Signale an Geräte mit IR-Schnittstelle versendet'
                +        en: 'Sends commands to lircd that sends IR-signals to any device that has an IR-interface'
                +    maintainer: E3EAT
                +    tester: Onkelandy
                +    keywords: infrared
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/lirc/....md
                +#    support:
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: LIRC                # class containing the plugin
                +
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +
                +    instance:
                +        type: str
                +        mandatory: True
                +        description:
                +            de: 'Name der Plugin Instanz (SmartHomeNG Standard-Parameter). Die Angabe ist notwendig um den passenden lircd zu ermitteln wenn ein Befehl versendet werden soll.'
                +            en: 'Name of the plugin instance (SmartHomeNG standard parameter). This is mandatory to identify the matching lircd for a pending command.'
                +
                +    lirc_host:
                +        type: str
                +        mandatory: True
                +        description:
                +            de: 'IP oder Hostname des lircd'
                +            en: 'IP or hostname of the lircd'
                +
                +    lirc_port:
                +        type: int
                +        default: 8765
                +        description:
                +            de: 'Der Port auf dem lircd lauscht.'
                +            en: 'The port that is used by lircd.'
                diff --git a/logo/plugin.yaml b/logo/plugin.yaml
                new file mode 100755
                index 000000000..e47458e64
                --- /dev/null
                +++ b/logo/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Ansteuerung einer Siemens LOGO PLC'
                +        en: ''
                +    maintainer: '?'
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.2.3                 # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: LOGO                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/luxtronic2/README.md b/luxtronic2/README.md
                index 750e775a0..738e33b9b 100644
                --- a/luxtronic2/README.md
                +++ b/luxtronic2/README.md
                @@ -5,7 +5,7 @@ This plugin has no requirements or dependencies.
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated) / .yaml
                 
                 ```
                 [luxtronic2]
                @@ -15,6 +15,14 @@ This plugin has no requirements or dependencies.
                     # port = 8888
                 ```
                 
                +```
                +luxtronic2:
                +    class_name: Luxtronic2
                +    class_path: plugins.luxtronic2
                +    host: 192.168.0.123
                +    # port: 8888
                +```
                +
                 #### Attributes
                   * `host`: specifies the hostname of your heating server.
                   * `port`: if you want to use a nonstandard port.
                @@ -48,6 +56,7 @@ Defines a mapping to a attribute (read-only). All attribute values are bytes (nu
                 Defines a mapping to a calculated value (read-only). All calculated values are integer (numbers).
                 
                 ```
                +#.conf (deprecated)
                 [heating]
                     [[temp_outside]]
                         type = num
                @@ -60,6 +69,20 @@ Defines a mapping to a calculated value (read-only). All calculated values are i
                         lux2 = 119
                 ```
                 
                +```
                +#.yaml
                +heating:
                +    temp_outside:
                +        type: num
                +        lux2: 10
                +    state_numeric:
                +        type: num
                +        lux2_c: 119
                +    state:
                +        type: str
                +        lux2: 119
                +```
                +
                 ### logic.conf
                 
                 Currently there is no logic configuration for this plugin.
                diff --git a/luxtronic2/__init__.py b/luxtronic2/__init__.py
                index 29666db16..25da83f5b 100755
                --- a/luxtronic2/__init__.py
                +++ b/luxtronic2/__init__.py
                @@ -1,9 +1,11 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                -#
                -# Copyright 2012-2013 KNX-User-Forum e.V.       http://knx-user-forum.de/
                -#
                -#  This file is part of SmartHomeNG.    https://github.com/smarthomeNG//
                +#########################################################################
                +#  Copyright 2012-2013 KNX-User-Forum e.V.      http://knx-user-forum.de/
                +#########################################################################
                +#  This file is part of SmartHomeNG
                +#  https://github.com/smarthomeNG/smarthome
                +#  http://knx-user-forum.de/
                 #
                 #  SmartHomeNG is free software: you can redistribute it and/or modify
                 #  it under the terms of the GNU General Public License as published by
                @@ -12,12 +14,12 @@
                 #
                 #  SmartHomeNG is distributed in the hope that it will be useful,
                 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
                -#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                 #  GNU General Public License for more details.
                 #
                 #  You should have received a copy of the GNU General Public License
                 #  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                -#
                +#########################################################################
                 
                 import sys
                 import logging
                @@ -26,16 +28,20 @@
                 import struct
                 import time
                 
                -logger = logging.getLogger('')
                +from lib.model.smartplugin import SmartPlugin
                 
                 
                 class luxex(Exception):
                     pass
                 
                 
                -class LuxBase():
                +class LuxBase(SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.3.0'
                 
                     def __init__(self, host, port=8888):
                +        self.logger = logging.getLogger(__name__)
                         self.host = host
                         self.port = int(port)
                         self._sock = False
                @@ -74,13 +80,13 @@ def connect(self):
                         except Exception as e:
                             self._connection_attempts -= 1
                             if self._connection_attempts <= 0:
                -                logger.error(
                +                self.logger.error(
                                     'Luxtronic2: could not connect to {0}:{1}: {2}'.format(self.host, self.port, e))
                                 self._connection_attempts = self._connection_errorlog
                             return
                         finally:
                             self._lock.release()
                -        logger.info(
                +        self.logger.info(
                             'Luxtronic2: connected to {0}:{1}'.format(self.host, self.port))
                         self.is_connected = True
                         self._connection_attempts = 0
                @@ -138,11 +144,11 @@ def set_param(self, param, value):
                         fields = ['cmd', 'param']
                         answer = dict(list(zip(fields, answer)))
                         if answer['cmd'] == 3002 and answer['param'] == param:
                -            logger.debug(
                +            self.logger.debug(
                                 "Luxtronic2: value {0} for parameter {1} stored".format(value, param))
                             return True
                         else:
                -            logger.warning(
                +            self.logger.warning(
                                 "Luxtronic2: value {0} for parameter {1} not stored".format(value, param))
                             return False
                 
                @@ -169,7 +175,7 @@ def refresh_parameters(self):
                             return False
                         else:
                             self._lock.release()
                -            logger.warning("Luxtronic2: failed to retrieve parameters")
                +            self.logger.warning("Luxtronic2: failed to retrieve parameters")
                             return False
                 
                     def refresh_attributes(self):
                @@ -195,7 +201,7 @@ def refresh_attributes(self):
                             return False
                         else:
                             self._lock.release()
                -            logger.warning("Luxtronic2: failed to retrieve attributes")
                +            self.logger.warning("Luxtronic2: failed to retrieve attributes")
                             return False
                 
                     def refresh_calculated(self):
                @@ -221,7 +227,7 @@ def refresh_calculated(self):
                             return 0
                         else:
                             self._lock.release()
                -            logger.warning("Luxtronic2: failed to retrieve calculated")
                +            self.logger.warning("Luxtronic2: failed to retrieve calculated")
                             return 0
                 
                 
                @@ -272,7 +278,7 @@ def _refresh(self):
                                 if val is not None:
                                     self._decoded[d](self._decode(d, val), 'Luxtronic2')
                         cycletime = time.time() - start
                -        logger.debug("cycle takes {0} seconds".format(cycletime))
                +        self.logger.debug("cycle takes {0} seconds".format(cycletime))
                 
                     def _decode(self, identifier, value):
                         if identifier == 119:
                @@ -328,27 +334,27 @@ def _decode(self, identifier, value):
                         return value
                 
                     def parse_item(self, item):
                -        if 'lux2' in item.conf:
                -            d = item.conf['lux2']
                +        if self.has_iattr(item.conf, 'lux2'):
                +            d = self.get_iattr_value(item.conf, 'lux2')
                             d = int(d)
                             self._decoded[d] = item
                -        if 'lux2_a' in item.conf:
                -            a = item.conf['lux2_a']
                +        if self.has_iattr(item.conf, 'lux2_a'):
                +            a = self.get_iattr_value(item.conf, 'lux2_a')
                             a = int(a)
                             self._attribute[a] = item
                -        if 'lux2_c' in item.conf:
                -            c = item.conf['lux2_c']
                +        if self.has_iattr(item.conf, 'lux2_c'):
                +            c = self.get_iattr_value(item.conf, 'lux2_c')
                             c = int(c)
                             self._calculated[c] = item
                -        if 'lux2_p' in item.conf:
                -            p = item.conf['lux2_p']
                +        if self.has_iattr(item.conf, 'lux2_p'):
                +            p = self.get_iattr_value(item.conf, 'lux2_p')
                             p = int(p)
                             self._parameter[p] = item
                             return self.update_item
                 
                     def update_item(self, item, caller=None, source=None, dest=None):
                         if caller != 'Luxtronic2':
                -            self.set_param(item.conf['lux2_p'], item())
                +            self.set_param(self.get_iattr_value(item.conf, 'lux2_p'), item())
                 
                 
                 def main():
                diff --git a/luxtronic2/plugin.yaml b/luxtronic2/plugin.yaml
                new file mode 100755
                index 000000000..050078cdf
                --- /dev/null
                +++ b/luxtronic2/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Integration von Systemen die eine Luxtronic-Steuerung haben (z.B Heizungen)'
                +        en: ''
                +    maintainer: '? (2ndsky)'
                +    tester: ohinckel
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: LuxBase              # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/mail/plugin.yaml b/mail/plugin.yaml
                new file mode 100755
                index 000000000..5b160443f
                --- /dev/null
                +++ b/mail/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Integration von E-Mail-Accounts'
                +        en: ''
                +    maintainer: cmalo (mknx)
                +    tester: psilo909, onkelandy, Sandman60
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SMTP                # class containing the plugin
                +#    classname: IMAP                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/memlog/README.md b/memlog/README.md
                old mode 100644
                new mode 100755
                index c515ec5ab..bc945267e
                --- a/memlog/README.md
                +++ b/memlog/README.md
                @@ -9,18 +9,36 @@ No special requirements.
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated) / yaml
                 
                 Use the plugin configuration to configure the in-memory logs.
                 
                 ```
                 [memlog]
                -   class_name = MemLog
                -   class_path = plugins.memlog
                -   name = alert
                -#   mappings = time | thread | level | message
                -#   maxlen = 50
                -#   items = first.item.now | second.item.thread.info | third.item.level | fourth.item.msg
                +    class_name = MemLog
                +    class_path = plugins.memlog
                +    name = alert
                +#    mappings = time | thread | level | message
                +#    maxlen = 50
                +#    items = first.item.now | second.item.thread.info | third.item.level | fourth.item.msg
                +```
                +
                +```
                +memlog:
                +    class_name: MemLog
                +    class_path: plugins.memlog
                +    name: alert
                +    mappings:
                +      - time
                +      - thread
                +      - level
                +      - message
                +#    maxlen: 50
                +#    items
                +#      - first.item.now
                +#      - second.item.thread.info
                +#      - third.item.level
                +#      - fourth.item.msg
                 ```
                 
                 This will register a in-memory log with the name "alert". This can be used to attach 
                @@ -48,8 +66,8 @@ Defines the maximum amount of log entries in the in-memory log.
                 Each time an item is updated using the `memlog` configuration setting, a log entry will
                 be written using the list of items configured in this attribute as log values.
                 
                -When this is not configured, the default mapping values will be used the the associated
                -item`s value will be logged.
                +When this is not configured, the default mapping values will be used the associated
                +item's value will be logged.
                 
                 ### items.conf
                 
                @@ -65,14 +83,21 @@ the log. Everything is logged with 'INFO' level.
                 Simple item logging:
                 
                 ```
                -# items/my.conf
                -
                +# .conf (deprecated)
                 [some]
                     [[item]]
                         type = str
                         memlog = alert
                 ```
                 
                +```
                +# .yaml
                +some:
                +    item:
                +        type: str
                +        memlog: alert
                +```
                +
                 ### logic.conf
                 
                 #### memlog
                @@ -86,13 +111,14 @@ Defines the message to be logged. It configures a string which may contain place
                 which got replaced by using the `format()` function.
                 
                 The following placeholders or object can be used in the message string:
                -* logic - the logic object, e.g. logic.name for the logic's name
                -* plugin - the memlog plugin instance object
                -* by - the string containing the origin of logic trigger
                -* source - the source
                -* dest - thedestination
                +* `logic` - the logic object, e.g. logic.name for the logic's name
                +* `plugin` - the memlog plugin instance object
                +* `by` - the string containing the origin of logic trigger
                +* `source` - the source
                +* `dest` - the destination
                 
                -The logic and plugin should always be available, the rest depends on the logic invocation/trigger.
                +The `logic` and `plugin` placeholders are always available, the rest depends on the
                +logic invocation/trigger.
                 
                 Example:
                 
                @@ -106,7 +132,7 @@ The `memlog()` method name is the plugin name which is used in the plugin config
                 If you use another name, you need to use this name as method name too.
                 
                 ### memlog(entry)
                -This log the given list of elements of `entry` parameter. The lsit should have the same amount
                +This log the given list of elements of `entry` parameter. The list should have the same amount
                 of items you used in the mapping parameter (see also the default for this value).
                 
                 `sh.memlog((self._sh.now(), threading.current_thread().name, 'INFO', 'Some information'))`
                diff --git a/memlog/__init__.py b/memlog/__init__.py
                index b39691738..7a07552c1 100755
                --- a/memlog/__init__.py
                +++ b/memlog/__init__.py
                @@ -1,7 +1,7 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                 #########################################################################
                -# Copyright 2013 KNX-User-Forum e.V.            http://knx-user-forum.de/
                +#  Copyright 2013-     Oliver Hinckel                  github@ollisnet.de
                 #########################################################################
                 #  This file is part of SmartHomeNG.    https://github.com/smarthomeNG//
                 #
                @@ -25,9 +25,14 @@
                 import time
                 import lib.log
                 
                +from lib.model.smartplugin import SmartPlugin
                 
                 
                -class MemLog():
                +class MemLog(SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.3.0'
                +
                     _log = None
                     _items = {}
                 
                @@ -45,7 +50,7 @@ def stop(self):
                         self.alive = False
                 
                     def parse_item(self, item):
                -        if 'memlog' in item.conf and item.conf['memlog'] == self.name:
                +        if self.has_iattr(item.conf, 'memlog') and self.get_iattr_value(item.conf, 'memlog') == self.name:
                             return self.update_item
                         else:
                             return None
                @@ -66,7 +71,7 @@ def __call__(self, param1=None, param2=None):
                 
                     def update_item(self, item, caller=None, source=None, dest=None):
                         if caller != 'MemLog':
                -            if item.conf['memlog'] == self.name:
                +            if self.get_iattr_value(item.conf, 'memlog') == self.name:
                                 if len(self._items) == 0:
                                     logvalues = [item()]
                                 else:
                diff --git a/memlog/plugin.yaml b/memlog/plugin.yaml
                new file mode 100755
                index 000000000..ca9aa7f62
                --- /dev/null
                +++ b/memlog/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Speicher Logeinträge im Speicher zur Anzeige in der VISU'
                +        en: ''
                +    maintainer: ohinckel
                +    tester: cmalo
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: MemLog               # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/milight/plugin.yaml b/milight/plugin.yaml
                new file mode 100755
                index 000000000..2b62f42b9
                --- /dev/null
                +++ b/milight/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung von MiLight Leuchtmitteln'
                +        en: ''
                +    maintainer: '? (Stephan Schaade)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: milight              # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/mlgw/README.md b/mlgw/README.md
                index 870486044..9c9d2e5f0 100644
                --- a/mlgw/README.md
                +++ b/mlgw/README.md
                @@ -43,7 +43,7 @@ This plugin need a Bang & Olufsen Masterlink Gateway and can connect to it via T
                 
                 ```
                 [mlgw]
                -    class_name = mlgw
                +    class_name = Mlgw
                     class_path = plugins.mlgw
                 #    host = 'mlgw.local'
                 #    port = 9000
                diff --git a/mlgw/__init__.py b/mlgw/__init__.py
                index 09b982cd5..e76acc0a0 100644
                --- a/mlgw/__init__.py
                +++ b/mlgw/__init__.py
                @@ -522,11 +522,12 @@ class mlgwlistener(threading.Thread):
                     #
                     def __init__( self, mymlgwbase ): 
                         self.logger = logging.getLogger(__name__)
                -        threading.Thread.__init__(self)
                +        self._mythread = threading.Thread.__init__(self)
                         self.name = 'mlgwListener'
                         self._mlgwbase = mymlgwbase
                         self._mlgwbase._mysocket.settimeout(5)
                 
                +         
                     ## Run thread
                     #  @param self The object pointer.
                     #
                @@ -658,6 +659,7 @@ def processtelegram( self ):
                     #  @param self The object pointer.
                     #
                     def stop( self ):
                +#        self._mythread.join()
                         pass
                         
                         
                @@ -665,7 +667,7 @@ def stop( self ):
                 
                 ## Class mlgw: Implements the plugin for smarthome.py
                 #
                -class mlgw(SmartPlugin):
                +class Mlgw(SmartPlugin):
                     ALLOW_MULTIINSTANCE = False
                     PLUGIN_VERSION='1.1.1'
                 
                diff --git a/mlgw/plugin.yaml b/mlgw/plugin.yaml
                new file mode 100755
                index 000000000..75c28d113
                --- /dev/null
                +++ b/mlgw/plugin.yaml
                @@ -0,0 +1,109 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Bang & Olufsen Masterlink Gateway'
                +        en: 'Bang & Olufsen Masterlink Gateway'
                +    maintainer: msinn
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Mlgw                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    host:
                +        type: ip
                +        default: 'mlgw.local'
                +        description:
                +            de: 'IP Adresse bzw. Hostname des Masterlink Gateways'
                +            en: 'ip address or hostname of the masterlink gateway'
                +        
                +    port:
                +        type: int
                +        default: 9000
                +        valid_min: 0
                +        description:
                +            de: 'Port Nummer des Masterlink Gateways'
                +            en: 'port number of the masterlink gateway'
                +        
                +    username:
                +        type: str
                +        default: 'mlgw'
                +        description:
                +            de: 'Username für das Login'
                +            en: 'Username for the login'
                +        
                +    password:
                +        type: str
                +        default: 'mlgw'
                +        description:
                +            de: 'Passwort für das Login'
                +            en: 'Password for the login'
                +        
                +    rooms:
                +        type: list
                +        default: []
                +        description:
                +            de: 'Liste der Räume'
                +            en: 'List of rooms'
                +        
                +    mlns:
                +        type: str
                +        default: []
                +        description:
                +            de: 'Liste der MLNs'
                +            en: 'List of MLNs'
                +        
                +    log_mlgwtelegrams:
                +        type: int
                +        default: 0
                +        valid_min: 0
                +        valid_max: 4
                +        description:
                +            de: 'Loglevel für die mlgw Telegramme'
                +            en: 'Loglevel for mlgw telegrams'
                +        
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    mlgw_send:
                +        type: str
                +        default: []
                +        description:
                +            de: 'Kommando welches gesendet werden soll'
                +            en: 'Command to be sent'
                +        
                +    mlgw_mln:
                +        type: str
                +        default: []
                +        description:
                +            de: 'MLN an die das Kommando gesendet werden soll'
                +            en: 'Destination MLN for the command'
                +        
                +    mlgw_listen:
                +        type: str
                +        default: []
                +        description:
                +            de: 'Befehlstyp auf den gehört werden soll (LIGHT/COMMAND)'
                +            en: 'Type of command (LIGHT/COMMAND)'
                +        
                +    mlgw_room:
                +        type: str
                +        default: []
                +        description:
                +            de: 'Raum aus dem der Befehl kommt'
                +            en: 'Room where the command is originating from'
                +        
                +    mlgw_cmd:
                +        type: str
                +        default: []
                +        description:
                +            de: 'Befehl auf den reagiert werden soll'
                +            en: 'Command to listen for'
                +
                diff --git a/mpd/README.md b/mpd/README.md
                index a75af9434..c24d45a32 100644
                --- a/mpd/README.md
                +++ b/mpd/README.md
                @@ -6,7 +6,7 @@ You only need one or more Music Player Daemons (MPD).
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated) / plugin.yaml
                 
                 ```
                 [mpd]
                @@ -14,7 +14,13 @@ You only need one or more Music Player Daemons (MPD).
                     class_path = plugins.mpd
                 ```
                 
                -### items.conf
                +```yaml
                +mpd:
                +    class_name: MPD
                +    class_path: plugins.mpd
                +```
                +
                +### items.conf (deprecated) / items.yaml
                 
                 You could see a full featured item configuration at the end of this file.
                 
                @@ -37,8 +43,36 @@ You could see a full featured item configuration at the end of this file.
                             type = bool
                             mpd_file = http://jungletrain.net/64kbps.m3u
                             enforce_updates = yes
                +        [[[heavy]]]
                +            type = bool
                +            mpd_localplaylist = heavymetal # will play the playlist heavymetal.m3u in the MPD's playlist directory
                +            enforce_updates = yes
                 ```
                 
                +```yaml
                +living:
                +    type: bool
                +    mpd:
                +        type: str
                +        mpd_host: 127.0.0.1
                +        mpd_port: 6600
                +        state:
                +            type: str
                +            mpd_listen: state
                +            mpd_send: value  # sends the item value. e.g. sh.dev.mpd.state('play') will send 'play'
                +        volume:
                +            type: num
                +            mpd_listen: volume
                +            mpd_send: volume
                +        jungle:
                +            type: bool
                +            mpd_file: http://jungletrain.net/64kbps.m3u
                +            enforce_updates: yes
                +        heavy:
                +            type: bool
                +            mpd_localplaylist: heavymetal # will play the playlist heavymetal.m3u in the MPD's playlist directory
                +            enforce_updates: yes
                +```
                 
                 #### mpd_host
                 This attribute is mandatory. You have to provide the IP address or host name of a MPD system.
                @@ -86,7 +120,8 @@ The following `mpd_send` attributes could be defined to send changes to the syst
                 #### mpd_file
                 You could specify a file, directory or URL which will be played if the value of this item change.
                 
                -
                +#### mpd_localplaylist
                +You could specify a local playlist file which will be played if the value of this item change.
                 
                 ## Functions
                 
                @@ -100,8 +135,7 @@ Plays the specified file, directory or URL.
                 ### add(file)
                 Adding the specified file, directory or URL to the playlist.
                 
                -
                -## Example item.conf
                +## Example item.conf (deprecated) / item.yaml
                 ```
                 [living]
                     [[mpd]]
                @@ -157,8 +191,13 @@ Adding the specified file, directory or URL to the playlist.
                             type = str
                             mpd_file = value  # plays the item value
                             enforce_updates = yes
                +        [[[heavy]]]
                +            type = bool
                +            mpd_localplaylist = heavymetal # will play the playlist heavymetal.m3u in the MPD's playlist directory
                +            enforce_updates = yes
                +
                 [office]
                -    [[mp2]]
                +    [[mpd2]]
                         type = str
                         mpd_host = 127.0.0.1
                         mpd_port = 6601
                @@ -177,3 +216,83 @@ Adding the specified file, directory or URL to the playlist.
                             type = str
                             mpd_listen = track
                 ```
                +```yaml
                +living:
                +    mpd:
                +        type: str
                +        mpd_host: 127.0.0.1
                +        mpd_port: 6600
                +        state:
                +            type: str
                +            mpd_listen: state
                +            mpd_send: value  # sends the item value. e.g. sh.dev.mpd.state('play') will send 'play'
                +        volume:
                +            type: num
                +            mpd_listen: volume
                +            mpd_send: volume
                +        play: # any call of dev.mpd.play will send 'play'
                +            type: bool
                +            # knx_listen ....
                +            mpd_send: play
                +            enforce_updates: yes
                +#       time:
                +#          type: num
                +#          mpd_listen: time
                +        total:
                +            type: num
                +            mpd_listen: total
                +        percent:
                +            type: num
                +            mpd_listen: percent
                +        repeat:
                +            type: bool
                +            mpd_listen: repeat
                +            mpd_send: repeat
                +        title:
                +            type: str
                +            mpd_listen: title
                +        album:
                +            type: str
                +            mpd_listen: album
                +        artist:
                +            type: str
                +            mpd_listen: artist
                +        name:
                +            type: str
                +            mpd_listen: name
                +        track:
                +            type: str
                +            mpd_listen: track
                +        rick:
                +            type: bool
                +            mpd_file: http://rick.net/roll.m3u
                +            enforce_updates: yes
                +        url:
                +            type: str
                +            mpd_file: value  # plays the item value
                +            enforce_updates: yes
                +        heavy:
                +            type: bool
                +            mpd_localplaylist: heavymetal # will play the playlist heavymetal.m3u in the MPD's playlist directory
                +            enforce_updates: yes
                +
                +office:
                +    mpd2:
                +        type: str
                +        mpd_host: 127.0.0.1
                +        mpd_port: 6601
                +        state:
                +            type: str
                +            mpd_listen: state
                +            mpd_send: value
                +        volume:
                +            type: num
                +            mpd_listen: volume
                +            mpd_send: volume
                +        name:
                +            type: str
                +            mpd_listen: name
                +        track:
                +            type: str
                +            mpd_listen: track
                +```
                diff --git a/mpd/__init__.py b/mpd/__init__.py
                index 922327c96..87cec5af7 100755
                --- a/mpd/__init__.py
                +++ b/mpd/__init__.py
                @@ -93,6 +93,8 @@ def __init__(self, smarthome, item):
                                 child.add_method_trigger(self._send_command)
                         for child in self._sh.find_children(item, 'mpd_file'):
                             child.add_method_trigger(self._play_file)
                +        for child in self._sh.find_children(item, 'mpd_localplaylist'):
                +            child.add_method_trigger(self._play_localplaylist)
                         # adding item methods
                         item.command = self.command
                         item.play_file = self.play_file
                @@ -110,6 +112,11 @@ def play_file(self, url):
                             self._send("add {0}".format(url), False)
                         self._send('play', False)
                 
                +    def play_localplaylist(self, file):
                +        self._send('clear', False)
                +        self._send('load ' + file, False)
                +        self._send('play', False)
                +
                     def add_file(self, url):
                         play = self._parse_url(url)
                         if play != []:
                @@ -122,6 +129,13 @@ def _play_file(self, item, caller=None, source=None, dest=None):
                             else:
                                 self.play_file(item.conf['mpd_file'])
                 
                +    def _play_localplaylist(self, item, caller=None, source=None, dest=None):
                +        if caller != 'MPD':
                +            if item.conf['mpd_localplaylist'] == 'value':
                +                self.play_localplaylist(item())
                +            else:
                +                self.play_localplaylist(item.conf['mpd_localplaylist'])
                +
                     def _parse_url(self, url):
                         name, sep, ext = url.rpartition('.')
                         ext = ext.lower()
                diff --git a/mpd/plugin.yaml b/mpd/plugin.yaml
                new file mode 100755
                index 000000000..e573d827a
                --- /dev/null
                +++ b/mpd/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Music Player Deamon (MPD) Unterstützung'
                +        en: 'Music Player Deamon (MPD) support'
                +    maintainer: '? (mknx)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mpd/README.md # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: MPD                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/mqtt/README.md b/mqtt/README.md
                index 91b88fa96..107e66ef7 100644
                --- a/mqtt/README.md
                +++ b/mqtt/README.md
                @@ -1,6 +1,6 @@
                 # MQTT
                 
                -#### Version 1.3.3
                +#### Version 1.3.4
                 
                 This plugin implements the the functionality for SmartHomeNG to act as a MQTT client.
                 
                @@ -15,6 +15,10 @@ Support is provided trough the support thread within the smarthomeNG forum: [Sup
                 
                 ## Change History
                 
                +### Changes since version 1.3.3
                +
                +- Fixed error not initializing subscriptions for items, if the broker was slow to respond on connect
                +
                 ### Changes since version 1.3.2
                 
                 - Fixed error with empty last_will_topic
                @@ -38,7 +42,7 @@ This plugin needs the following following software to be installed and running:
                 - A MQTT broker for communication with other MQTT clients. The broker may be running on the hardware SmartHomeNG is running on, or on another hardware that can be reached via TCP/IP. The open souce broker [Mosquitto](https://mosquitto.org) is a good choice. 
                 
                 ### Using Mosquitto Broker on Raspberry Pi
                -If want to run the broker on a Raspberry Pi you should be aware, that the broker on the raspbian repository is quite old. You should add the morquito.org repository as a trusted site to your **`apt-get`** to get a recent version of mosquitto installed.
                +If want to run the broker on a Raspberry Pi you should be aware, that the broker on the raspbian repository is quite old. You should add the mosquitto.org repository as a trusted site to your **`apt-get`** to get a recent version of mosquitto installed.
                 
                 
                 ## Configuration
                diff --git a/mqtt/__init__.py b/mqtt/__init__.py
                index 8992e4db9..48776db45 100644
                --- a/mqtt/__init__.py
                +++ b/mqtt/__init__.py
                @@ -35,7 +35,9 @@
                 # - Broker disconnect erkennen
                 
                 import logging
                -from lib.model.smartplugin import SmartPlugin
                +#from lib.model.smartplugin import SmartPlugin
                +#from lib.model.smartplugin import SPLogger
                +from lib.model.smartplugin import *
                 
                 from lib.utils import Utils
                 import json
                @@ -53,11 +55,11 @@ class Mqtt(SmartPlugin):
                     
                     ALLOW_MULTIINSTANCE = True
                     
                -    PLUGIN_VERSION = "1.3.3"
                +    PLUGIN_VERSION = "1.3c.4"
                 
                     __plugif_CallbackTopics = {}         # for plugin interface
                     __plugif_Sub = None
                -    
                +        
                     
                     def __init__(self, sh, 
                             host='127.0.0.1', port='1883', qos='1',
                @@ -86,6 +88,11 @@ def __init__(self, sh,
                         :param ca_certs:           .
                         :param acl:                Default Access-Control, can be overwritten in item definition
                         """
                +#        self.logger = SmartPluginLogger(__name__, self)
                +#        self.logger = SmartPluginLogger("mqtt", self)
                +        self.logger = logging.getLogger(__name__)
                +#        self.logger = logging.getLogger().getChild("child-mqtt")
                +        
                         # attention:
                         # if your plugin runs standalone, sh will likely be None so do not rely on it later or check it within your code
                         
                @@ -101,8 +108,6 @@ def __init__(self, sh,
                         if self.at_instance_name != '':
                             self.at_instance_name = '@'+self.at_instance_name
                 
                -        self.logIdentifier = ('MQTT '+self.at_instance_name).strip()
                -
                         self._connected = False
                         
                         # check parameters specified in plugin.yaml
                @@ -111,14 +116,14 @@ def __init__(self, sh,
                         try:
                             host = socket.gethostbyname( host )
                         except Exception as e:
                -            self.logger.error(self.logIdentifier+": Error resolving '%s': %s" % (host, e))
                +            self.logger.error(self.get_loginstance()+"Error resolving '%s': %s" % (host, e))
                             return
                 
                         if Utils.is_ip(host):
                             self.broker_ip = host
                         else:
                             self.broker_ip = ''
                -            self.logger.error(self.logIdentifier+': Invalid ip address for broker specified, plugin not starting')
                +            self.logger.error(self.get_loginstance()+'Invalid ip address for broker specified, plugin not starting')
                             return
                         if self.broker_ip == self.broker_hostname:
                             self.broker_hostname = ''
                @@ -127,19 +132,19 @@ def __init__(self, sh,
                             self.broker_port = int(port)
                         else:
                             self.broker_port = 1883
                -            self.logger.error(self.logIdentifier+": Invalid port number for broker specified, plugin trying standard port '{}'".format(str(self.broker_port)))
                +            self.logger.error(self.get_loginstance()+"Invalid port number for broker specified, plugin trying standard port '{}'".format(str(self.broker_port)))
                             
                         self.qos = -1
                         if Utils.is_int(qos):
                             self.qos = int(qos)
                         if not (self.qos in [0, 1, 2]):
                             self.qos = 1
                -            self.logger.error(self.logIdentifier+": Invalid value specified for default quality-of-service, using standard '{}'".format(str(self.qos)))
                +            self.logger.error(self.get_loginstance()+"Invalid value specified for default quality-of-service, using standard '{}'".format(str(self.qos)))
                 
                         self.acl = acl.lower()
                         if not (self.acl in ['none','pub','sub','pubsub']):
                             self.acl ='none'
                -            self.logger.error(self.logIdentifier+": Invalid value specified for default acess-control, using standard '{}'".format(self.acl))
                +            self.logger.error(self.get_loginstance()+"Invalid value specified for default acess-control, using standard '{}'".format(self.acl))
                 
                         if (last_will_topic != '') and (last_will_topic [-1] == '/'):
                             last_will_topic = last_will_topic[:-1]
                @@ -179,6 +184,11 @@ def run(self):
                         if (self.birth_topic != '') and (self.birth_payload != ''):
                             self._client.publish(self.birth_topic, self.birth_payload, self.qos, retain=True)
                         self._client.loop_start()
                +        # set the name of the paho thread for this plugin instance
                +        try:
                +            self._client._thread.name = "paho_" + self.get_fullname()
                +        except:
                +            self.logger.warning(self.get_loginstance()+"Unable to set name for paho thread")
                         for topic in self.inittopics:
                             item = self.inittopics[topic]
                             self.update_item(item)
                @@ -188,6 +198,7 @@ def stop(self):
                         """
                         Stop method for the plugin
                         """
                +        self._client.loop_stop()
                         self.DisconnectFromBroker()
                         self.alive = False
                 
                @@ -217,16 +228,16 @@ def parse_item(self, item):
                         
                         # check other mqtt attributes, if a topic attribute has been specified
                         if self.has_iattr(item.conf, 'mqtt_topic_in') or self.has_iattr(item.conf, 'mqtt_topic_out'):
                -            self.logger.info(self.logIdentifier+": parsing item: {0}".format(item.id()))
                +            self.logger.debug(self.get_loginstance()+"parsing item: {0}".format(item.id()))
                         
                             # checking attribute 'mqtt_qos'
                             if self.has_iattr(item.conf, 'mqtt_qos'):
                -                self.logger.debug(self.logIdentifier+": Setting QoS '{}' for item '{}'".format( str(self.get_iattr_value(item.conf, 'mqtt_qos')), str(item) ))
                +                self.logger.debug(self.get_loginstance()+"Setting QoS '{}' for item '{}'".format( str(self.get_iattr_value(item.conf, 'mqtt_qos')), str(item) ))
                                 qos = -1
                                 if Utils.is_int(self.get_iattr_value(item.conf, 'mqtt_qos')):
                                     qos = int(self.get_iattr_value(item.conf, 'mqtt_qos'))
                                 if not (qos in [0, 1, 2]):
                -                    self.logger.warning(self.logIdentifier+": Item '{}' invalid value specified for mqtt_qos, using plugin's default".format(item.id()))
                +                    self.logger.warning(self.get_loginstance()+"Item '{}' invalid value specified for mqtt_qos, using plugin's default".format(item.id()))
                                     qos = self.qos
                                 self.set_attr_value(item.conf, 'mqtt_qos', str(qos))
                             	
                @@ -236,24 +247,24 @@ def parse_item(self, item):
                             else:
                                 self.set_attr_value(item.conf, 'mqtt_retain', 'False')
                             
                -            self.logger.debug(self.logIdentifier+" (parsing result): item.conf '{}'".format( str(item.conf) ))
                +            self.logger.debug(self.get_loginstance()+"(parsing result): item.conf '{}'".format( str(item.conf) ))
                                    
                         # subscribe to configured topics
                         if self.has_iattr(item.conf, 'mqtt_topic_in'):
                -            if self._connected:
                +            if self._connected or True:
                                 topic = self.get_iattr_value(item.conf, 'mqtt_topic_in')
                                 self.topics[topic] = item
                                 self._client.subscribe(topic, qos=self.get_qos_forTopic(item) )
                -                self.logger.info(self.logIdentifier+": Listening on topic '{}' for item '{}'".format( topic, item.id() ))
                +                self.logger.info(self.get_loginstance()+"Listening on topic '{}' for item '{}'".format( topic, item.id() ))
                         
                         if self.has_iattr(item.conf, 'mqtt_topic_out'):
                             # initialize topics if configured
                             topic = self.get_iattr_value(item.conf, 'mqtt_topic_out')
                             if self.has_iattr(item.conf, 'mqtt_topic_init'):
                                 self.inittopics[self.get_iattr_value(item.conf, 'mqtt_topic_init')] = item
                -                self.logger.info(self.logIdentifier+": Publishing and initialising topic '{}' for item '{}'".format( topic, item.id() ))
                +                self.logger.info(self.get_loginstance()+"Publishing and initialising topic '{}' for item '{}'".format( topic, item.id() ))
                             else:
                -                self.logger.info(self.logIdentifier+": Publishing topic '{}' for item '{}'".format( topic, item.id() ))
                +                self.logger.info(self.get_loginstance()+"Publishing topic '{}' for item '{}'".format( topic, item.id() ))
                 
                             return self.update_item
                 
                @@ -272,9 +283,9 @@ def parse_logic(self, logic):
                                     if (logic.conf['mqtt_payload_type'+self.at_instance_name]).lower() in ['str', 'num', 'bool', 'list', 'dict', 'scene']:
                                         self.logicpayloadtypes[topic] = (logic.conf['mqtt_payload_type'+self.at_instance_name]).lower()
                                     else:
                -                        self.logger.warning(self.logIdentifier+": Invalid payload-datatype specified for logic '{}', ignored".format( str(logic) ))            
                +                        self.logger.warning(self.get_loginstance()+"Invalid payload-datatype specified for logic '{}', ignored".format( str(logic) ))       
                                 self._client.subscribe(topic, qos=self.qos)
                -                self.logger.info(self.logIdentifier+": Listening on topic '{}' for logic '{}'".format( topic, str(logic) ))
                +                self.logger.info(self.get_loginstance()+"Listening on topic '{}' for logic '{}'".format( topic, str(logic) ))
                 
                 
                     def update_item(self, item, caller=None, source=None, dest=None):
                @@ -295,7 +306,7 @@ def update_item(self, item, caller=None, source=None, dest=None):
                                 retain = self.get_iattr_value(item.conf, 'mqtt_retain')
                                 if retain == None:
                                     retain = 'False'
                -                self.logger.info("Item '{}': Publishing topic '{}', payload '{}', QoS '{}', retain '{}'".format( item.id(), topic, str(item()), str(self.get_qos_forTopic(item)), retain ))
                +                self.logger.info(self.get_loginstance()+"Item '{}': Publishing topic '{}', payload '{}', QoS '{}', retain '{}'".format( item.id(), topic, str(item()), str(self.get_qos_forTopic(item)), retain ))
                                 self._client.publish(topic=topic, payload=str(item()), qos=self.get_qos_forTopic(item), retain=(retain=='True'))
                 
                 
                @@ -329,7 +340,7 @@ def cast_mqtt(self, datatype, raw_data):
                         elif datatype == 'foo':
                             data = raw_data
                         else:
                -            self.logger.warning(self.logIdentifier+": item '{}' - Casting to '{}' is not implemented".format(str(item._path), str(datatype)))
                +            self.logger.warning(self.get_loginstance()+"item '{}' - Casting to '{}' is not implemented".format(str(item._path), str(datatype)))
                             data = raw_data
                         return data
                 
                @@ -354,7 +365,7 @@ def ConnectToBroker(self):
                         clientname = os.uname()[1]
                         if self.get_instance_name() != '':
                             clientname = clientname + '.' + self.get_instance_name()
                -        self.logger.info(self.logIdentifier+": Connecting to broker. Starting mqtt client '{0}'".format(clientname))
                +        self.logger.info(self.get_loginstance()+"Connecting to broker. Starting mqtt client '{0}'".format(clientname))
                         self._client = mqtt.Client(clientname)
                 
                         # set testament, if configured
                @@ -370,7 +381,7 @@ def ConnectToBroker(self):
                         try:
                             self._client.connect(self.broker_ip, self.broker_port, 60)
                         except Exception as e:
                -            self.logger.error('Connection error:', e)
                +            self.logger.error(self.get_loginstance()+'Connection error:', e)
                 
                         self._client.on_message = self.on_mqtt_message
                         self._client.subscribe('$SYS/broker/version', qos=0 )
                @@ -381,11 +392,11 @@ def on_connect(self, mqttc, obj, flags, rc):
                         Connecting callback function
                         """
                         if rc == 0:
                -            self.logger.info(self.logIdentifier+": Connection returned result '{}' ".format( mqtt.connack_string(rc) ))
                +            self.logger.info(self.get_loginstance()+"Connection returned result '{}' ".format( mqtt.connack_string(rc) ))
                             self._connected = True
                             return
                             
                -        self.logger.warning(self.logIdentifier+": Connection returned result '{}': {}".format( str(rc), mqtt.connack_string(rc) ))
                +        self.logger.warning(self.get_loginstance()+"Connection returned result '{}': {}".format( str(rc), mqtt.connack_string(rc) ))
                         
                 
                     def DisconnectFromBroker(self):
                @@ -396,19 +407,19 @@ def DisconnectFromBroker(self):
                 
                         for topic in self.topics:
                             item = self.topics[topic]
                -            self.logger.debug(self.logIdentifier+": Unsubscribing topic '{}' for item '{}'".format( str(topic), str(item.id()) ))
                +            self.logger.debug(self.get_loginstance()+"Unsubscribing topic '{}' for item '{}'".format( str(topic), str(item.id()) ))
                             self._client.unsubscribe(topic)
                 
                         for topic in self.logictopics:
                             logic = self.logictopics[topic]
                -            self.logger.debug(self.logIdentifier+": Unsubscribing topic '{}' for logic '{}'".format( str(topic), str(logic.id()) ))
                +            self.logger.debug(self.get_loginstance()+"Unsubscribing topic '{}' for logic '{}'".format( str(topic), str(logic.id()) ))
                             self._client.unsubscribe(topic)
                 
                         if (self.last_will_topic != '') and (self.last_will_payload != ''):
                             if (self.birth_topic != '') and (self.birth_payload != ''):
                                 self._client.publish(self.last_will_topic, self.last_will_payload+' (shutdown)', self.qos, retain=True)
                                 
                -        self.logger.info(self.logIdentifier+": Stopping mqtt client '{}'. Disconnecting from broker.".format(self._client._client_id))
                +        self.logger.info(self.get_loginstance()+"Stopping mqtt client '{}'. Disconnecting from broker.".format(self._client._client_id))
                         self._client.loop_stop()
                         self._connected = False
                         self._client.disconnect()
                @@ -426,20 +437,20 @@ def on_mqtt_message(self, client, userdata, message):
                         item = self.topics.get(message.topic, None)
                         if item != None:
                             payload = self.cast_mqtt(item.type(), message.payload)
                -            self.logger.info(self.logIdentifier+": Received topic '{}', payload '{}' (type {}), QoS '{}', retain '{}' for item '{}'".format( message.topic, str(payload), item.type(), str(message.qos), str(message.retain), str(item.id()) ))
                +            self.logger.warning(self.get_loginstance()+"Received topic '{}', payload '{}' (type {}), QoS '{}', retain '{}' for item '{}'".format( message.topic, str(payload), item.type(), str(message.qos), str(message.retain), str(item.id()) ))
                             item(payload, 'MQTT')
                         logic = self.logictopics.get(message.topic, None)
                         if logic != None:
                             datatype = self.logicpayloadtypes.get(message.topic, 'foo')
                             payload = self.cast_mqtt(datatype, message.payload)
                -            self.logger.info(self.logIdentifier+": Received topic '{}', payload '{} (type {})', QoS '{}', retain '{}' for logic '{}'".format( message.topic, str(payload), datatype, str(message.qos), str(message.retain), str(logic) ))
                +            self.logger.info(self.get_loginstance()+"Received topic '{}', payload '{} (type {})', QoS '{}', retain '{}' for logic '{}'".format( message.topic, str(payload), datatype, str(message.qos), str(message.retain), str(logic) ))
                             logic.trigger('MQTT'+self.at_instance_name, message.topic, payload )
                         if (item == None) and (logic == None):
                             if message.topic == '$SYS/broker/version':
                                 self.log_brokerinfo(message.payload)
                                 # self._client.unsubscribe('$SYS/broker/version')
                             else:
                -                self.logger.error(self.logIdentifier+": Received topic '{}', payload '{}', QoS '{}, retain '{}'' WITHOUT matching item/logic".format( message.topic, message.payload, str(message.qos), str(message.retain) ))
                +                self.logger.error(self.get_loginstance()+"Received topic '{}', payload '{}', QoS '{}, retain '{}'' WITHOUT matching item/logic".format( message.topic, message.payload, str(message.qos), str(message.retain) ))
                 
                 
                     def log_brokerinfo(self, payload):
                @@ -451,7 +462,9 @@ def log_brokerinfo(self, payload):
                             address = str(self.broker_ip)+':'+str(self.broker_port)
                         else:
                             address = self.broker_hostname + ' (' + str(self.broker_ip)+':'+str(self.broker_port) + ')'
                -        self.logger.warning(self.logIdentifier+": Connected to broker '{}' at address {}".format( str(payload), address ))
                +        sn = self.get_shortname()
                +#        self.mqttlogger.warning("-{}: Connected to broker '{}' at address {}".format( sn, str(payload), address ))
                +        self.logger.info(self.get_loginstance()+"Connected to broker '{}' at address {}".format( str(payload), address ))
                 
                 
                     # ---------------------------------------------------------------------------------
                @@ -474,7 +487,7 @@ def publish_topic(self, plug, topic, payload, qos=None, retain=False):
                             return
                         if qos == None:
                             qos = self.qos
                -        self.logger.warning(self.logIdentifier+" (interface): Plugin '{}' is publishing topic '{}'".format( str(plug), str(topic) ))
                +        self.logger.warning(self.get_loginstance()+"(interface: Plugin '{}' is publishing topic '{}'".format( str(plug), str(topic) ))
                         self._client.publish(topic=topic, payload=payload, qos=qos, retain=retain)
                 
                 
                @@ -498,15 +511,15 @@ def subscription_callback(self, plug, sub, callback=None):
                             else:
                                 self.__plugif_Sub = sub
                         
                -            self.logger.warning(self.logIdentifier+" (interface): Plugin '{}' is registering a callback function for subscription of topics '{}'".format( str(plug), str(self.__plugif_Sub) ))
                +            self.logger.warning(self.get_loginstance()+"(interface): Plugin '{}' is registering a callback function for subscription of topics '{}'".format( str(plug), str(self.__plugif_Sub) ))
                             self._client.message_callback_add(self.__plugif_Sub, callback)
                         else:
                             if sub == '':
                -                self.logger.warning(self.logIdentifier+" (interface): Plugin '{}' is clearing the callback function for subscription of topics '{}'".format( str(plug), str(self.__plugif_Sub) ))
                +                self.logger.warning(self.get_loginstance()+"(interface): Plugin '{}' is clearing the callback function for subscription of topics '{}'".format( str(plug), str(self.__plugif_Sub) ))
                                 self._client.message_callback_remove(self.__plugif_Sub)
                                 self.__plugif_Sub = None
                             else:
                -                self.logger.error(self.logIdentifier+" (interface): Plugin '{}' is trying to register a second callback function (for subscription of topics '{}')".format( str(plug), str(self.__plugif_Sub) ))
                +                self.logger.error(self.get_loginstance()+"(interface): Plugin '{}' is trying to register a second callback function (for subscription of topics '{}')".format( str(plug), str(self.__plugif_Sub) ))
                 
                 
                     def subscribe_topic(self, plug, topic, qos=None):
                @@ -522,6 +535,6 @@ def subscribe_topic(self, plug, topic, qos=None):
                         if qos == None:
                             qos = self.qos
                         self._client.subscribe(topic, qos=qos)
                -        self.logger.info(self.logIdentifier+" (interface): Plugin '{}' is subscribing to topic '{}'".format( str(plug), str(topic) ))
                +        self.logger.info(self.get_loginstance()+"(interface): Plugin '{}' is subscribing to topic '{}'".format( str(plug), str(topic) ))
                 
                 
                diff --git a/mqtt/plugin.yaml b/mqtt/plugin.yaml
                old mode 100644
                new mode 100755
                index 8e98da55e..ad33ab89f
                --- a/mqtt/plugin.yaml
                +++ b/mqtt/plugin.yaml
                @@ -1,17 +1,175 @@
                +# Metadata for the Smart-Plugin
                 plugin:
                -    type: protocol              # plugin type (system, gateway, interface, protocol, cloud)
                -#    subtype: ...               # plugin subtype (if applicable)
                -    version: 1.3.3              # Plugin version
                -    keywords: iot               # keywords, where applicable
                -    sh_minversion: 1.3          # minimum shNG version to use this plugin
                -#   sh_maxversion:              # maximum shNG version to use this plugin (leave empty if latest)
                -    multi_instance: true        # plugin supports multi instance
                -    description: 'Implementierung eines MQTT Clients'    # description (one language only, german preferred)
                -#   description:               # Alternative: description in multiple languages
                -#       de: 'Abfrage der Daten des Wetterdienstes Wunderground.com'
                -#       en: 'Get weather data from wunderground.com'
                -   documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of wiki page
                -    maintainer: msinn           # Who maintains this plugin?
                -#   tester:                     # Who tests this plugin?
                +    # Global plugin attributes
                +    type: protocol                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Implementierung eines MQTT Clients. Umfassendere Implementierung des MQTT Protokolls, **seit SmartHomeNG v1.3**'
                +        en: 'Implementation of a MQTT client. Feature enriched implementation of the MQTT protocol, **since SmartHomeNG v1.3**'
                +    maintainer: msinn
                +#    tester:                        # Who tests this plugin?
                +    keywords: iot
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1089334-neues-mqtt-plugin
                 
                +    version: 1.3c.4                # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Mqtt                # class containing the plugin
                 
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +    host:
                +        type: ip
                +        default: '127.0.0.1'
                +        description:
                +            de: 'IP Adresse / Hostname des MQTT Brokers'
                +            en: 'ip address / hostname of the MQTT broker'
                +        
                +    port:
                +        type: int
                +        default: 1883
                +        valid_min: 0
                +        description:
                +            de: 'Port des MQTT Brokers'
                +            en: 'port of MQTT broker'
                +        
                +    qos:
                +        type: int
                +        default: 1
                +        valid_list:
                +          - 0
                +          - 1
                +          - 2
                +        description:
                +            de: 'Quality of Service'
                +            en: 'Quality of Service'
                +        
                +    last_will_topic:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Topic für Last-Will Telegramm'
                +            en: 'Topic for the last will telegram'
                +        
                +    last_will_payload:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Payload für Last-Will Telegramm'
                +            en: 'Payload for the last will telegram'
                +        
                +    birth_topic:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Topic für Birth Telegramm'
                +            en: 'Topic for the birth telegram'
                +        
                +    birth_payload:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Payload für Birth Telegramm'
                +            en: 'Payload for the birth telegram'
                +        
                +    publish_items:
                +        type: bool
                +        default: False
                +        description:
                +            de: 'Publiziere die Items'
                +            en: 'Publish Items'
                +        
                +    items_topic_prefix:
                +        type: str
                +        default: 'devices/shng'
                +        description:
                +            de: 'Prefix für die publizierten Items'
                +            en: 'Prefix for the published items'
                +    
                +    user:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Username für das Broker Login'
                +            en: 'Username for login to the broker'
                +        
                +    password:
                +        type: str
                +        default: ''
                +        description:
                +            de: 'Passwort für das Broker Login'
                +            en: 'Password for login to the broker'
                +        
                +#    tls:    # Not yet implemented
                +#        type: bool
                +#        default: False
                +#        description:
                +#            de: ''
                +#            en: ''
                +        
                +#    ca_certs:    # Not yet implemented
                +#        type: str
                +#        default: '/etc/'
                +#        description:
                +#            de: ''
                +#            en: ''
                +        
                +    acl:
                +        type: str
                +        default: 'none'
                +        valid_list:
                +          - 'none'
                +          - 'pub'
                +          - 'sub'
                +          - 'pubsub'
                +        description:
                +            de: 'Zugriffskontrolle (none/publish/subscribe)'
                +            en: 'Accesscontrol (none/publish/subscribe)'
                +        
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    mqtt_topic:
                +        type: str
                +        description:
                +            de: 'Topic für Senden und Empfangen'
                +            en: 'Topic for send and receive'
                +        
                +    mqtt_topic_in:
                +        type: str
                +        description:
                +            de: 'Topic für Empfangen'
                +            en: 'Topic for receive'
                +        
                +    mqtt_topic_out:
                +        type: str
                +        description:
                +            de: 'Topic für Senden'
                +            en: 'Topic for send'
                +        
                +    mqtt_topic_init:
                +        type: str
                +        description:
                +            de: 'Topic für Senden (Initial beim Start von SmartHomeNG senden)'
                +            en: 'Topic for send (send initially when starting up SmartHomeNG'
                +        
                +    mqtt_qos:
                +        type: int
                +        default: 1
                +        valid_list:
                +          - 0
                +          - 1
                +          - 2
                +        description:
                +            de: 'Quality of Service'
                +            en: 'Quality of Service'
                +        
                +    mqtt_retain:
                +        type: bool
                +        default: ''
                +        description:
                +            de: 'Retention Flag für gesendete Telegramme setzen'
                +            en: 'Set retention flag for sent telegrams'
                +        
                diff --git a/mqtt/requirements.txt b/mqtt/requirements.txt
                new file mode 100644
                index 000000000..c04d16960
                --- /dev/null
                +++ b/mqtt/requirements.txt
                @@ -0,0 +1 @@
                +paho-mqtt>=1.2.2
                diff --git a/mqtt_1_0/__init__.py b/mqtt_1_0/__init__.py
                old mode 100644
                new mode 100755
                diff --git a/mqtt_1_0/plugin.yaml b/mqtt_1_0/plugin.yaml
                new file mode 100755
                index 000000000..b67ccb642
                --- /dev/null
                +++ b/mqtt_1_0/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: protocol                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Implementierung eines MQTT Clients. - veraltet'
                +        en: 'Implementation of a MQTT client. - To be retired'
                +    maintainer: cmalo              # Who maintains this plugin?
                +#    tester: efgh                   # Who tests this plugin?
                +    keywords: iot
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Mqtt                # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/mvg_live/plugin.yaml b/mvg_live/plugin.yaml
                new file mode 100755
                index 000000000..12915fd65
                --- /dev/null
                +++ b/mvg_live/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Abfrage der Abfahrten in Stationen der Münchner Verkehrsbetriebe (MVG)'
                +        en: ''
                +    maintainer: psilo909
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1108867-neues-plugin-mvg_live
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: MVG_Live            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/netio230b/plugin.yaml b/netio230b/plugin.yaml
                new file mode 100755
                index 000000000..eadd4ecc8
                --- /dev/null
                +++ b/netio230b/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützt KOUKAAM NETIO230B Hardware, eine über Ethernet schaltbare 4-fach-Steckdose'
                +        en: ''
                +    maintainer: '?'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: NetIO230B           # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/network/README.md b/network/README.md
                index cdbb3b9fd..9415a4701 100644
                --- a/network/README.md
                +++ b/network/README.md
                @@ -26,14 +26,14 @@ Ports up to 1024 are _well defined ports_ and are normally reserved to the syste
                 nw:
                     class_name: Network
                     class_path: plugins.network
                -    # ip = 0.0.0.0
                -    # port = 2727
                +    # ip: 0.0.0.0
                +    # port: 2727
                     tcp: 'yes'
                     tcp_acl:
                       - 127.0.0.1
                       - 192.168.0.34
                -    # udp = no
                -    # udp_acl= *
                +    # udp: 'no'
                +    # udp_acl: '*'
                 ```
                 
                 ### Attributes
                diff --git a/network/plugin.yaml b/network/plugin.yaml
                new file mode 100755
                index 000000000..f49d00ec2
                --- /dev/null
                +++ b/network/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: protocol                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'UDP und TCP Protokoll Unterstützung'
                +        en: 'Support for the protocols UDP and TCP'
                +    maintainer: cmalo (mknx)
                +    tester: onkelandy, psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Network             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/nma/README.md b/nma/README.md
                index 1b16e2255..9ffba5c30 100644
                --- a/nma/README.md
                +++ b/nma/README.md
                @@ -1,4 +1,4 @@
                -# Notify My Android
                +# nma - Notify My Android
                 
                 ## Requirements
                 
                diff --git a/nma/plugin.yaml b/nma/plugin.yaml
                new file mode 100755
                index 000000000..fe9cce4f7
                --- /dev/null
                +++ b/nma/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Notify My Android Anbindung'
                +        en: ''
                +    maintainer: '?'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: NMA                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/nokia_health/README.md b/nokia_health/README.md
                new file mode 100644
                index 000000000..77e05763c
                --- /dev/null
                +++ b/nokia_health/README.md
                @@ -0,0 +1,92 @@
                +# Nokia Health
                +
                +Version 0.1
                +
                +## Description
                +
                +This plugin allows to retrieve data from the Nokia Health API (https://developer.health.nokia.com/api). Currently it 
                +only has support for "Withings WS-50 Smart Body Analyzer", a wifi capabale scale.
                +
                +Support Thread: https://knx-user-forum.de/forum/supportforen/smarthome-py/1141179-nokia-health-plugin
                +
                +## Requirements
                +
                +This plugin requires lib requests. You can install this lib with: 
                +
                +```bash
                +sudo pip3 install requests --upgrade
                +```
                +
                +You have to go through the registration and oauth process on https://developer.health.nokia.com/api.
                +You will need a temporary callback url!.
                +In the end after step 4, you see the 4 variables needed for the plugin to work in the URL the page is forwarding you to.
                +
                +## Configuration
                +
                +### plugin.yaml
                +```yaml
                +nokia_health:
                +    class_name: NokiaHealth
                +    class_path: plugins.nokia_health
                +    oauth_consumer_key: <your_oauth_consumer_key>
                +    oauth_nonce: <your_oauth_nonce>
                +    oauth_signature: <your_oauth_signature>
                +    oauth_token: <your_oath_token>
                +    userid: <your_userid>
                +    instance: nokia_health
                +```
                +
                +### items.yaml
                +
                +Please be aware that there are dependencies for the values. E.g. the body measurement index will only be calculated if a
                +height exists. From what i saw so far is, that the height is transmitted only one time, the first time the scale 
                +communicates with the Nokia servers. In case you miss it, set the item value manually!
                +
                +```yaml
                +body:
                +
                +    weight:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: weight
                + 
                +    height:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: height
                +  
                +    bmi:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: bmi
                +
                +    fat_ratio:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: fat_ratio
                +
                +    fat_free_mass:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: fat_free_mass
                +
                +    fat_mass_weight:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: fat_mass_weight
                +
                +    heart_pulse:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: heart_pulse
                +
                +    last_update:
                +        type: num
                +        visu_acl: ro
                +        nh_type@nokia_health: last_update
                +```
                +
                +## Functions
                +
                +### get_last_measure():
                +Gets the last measurement values.
                \ No newline at end of file
                diff --git a/nokia_health/__init__.py b/nokia_health/__init__.py
                new file mode 100644
                index 000000000..2eaf23371
                --- /dev/null
                +++ b/nokia_health/__init__.py
                @@ -0,0 +1,176 @@
                +#!/usr/bin/env python3
                +#
                +#########################################################################
                +#  Copyright 2017 Marc René Frieß                 rene.friess(a)gmail.com
                +#  Version 1.3.1
                +#########################################################################
                +#
                +#  This file is part of SmartHomeNG.
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                +#
                +#########################################################################
                +
                +import logging
                +import requests
                +from lib.model.smartplugin import SmartPlugin
                +
                +class NokiaHealth(SmartPlugin):
                +    ALLOW_MULTIINSTANCE = True
                +    PLUGIN_VERSION = "1.3.1"
                +    BASE_URL = "https://api.health.nokia.com/"
                +    ALLOWED_MEASURE_TYPES = [1, 4, 5, 6, 8, 11]
                +
                +    # see https://developer.health.nokia.com/api/doc
                +
                +    def __init__(self, smarthome, oauth_consumer_key, oauth_nonce, oauth_signature, oauth_token, userid, cycle=300):
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        self._oauth_consumer_key = oauth_consumer_key
                +        self._oauth_nonce = oauth_nonce
                +        self._oauth_signature = oauth_signature
                +        self._oauth_token = oauth_token
                +        self._userid = userid
                +        self._cycle = cycle
                +        self._items = {}
                +
                +    def run(self):
                +        self.alive = True
                +        self._sh.scheduler.add(__name__, self._update_loop, cycle=self._cycle)
                +
                +    def stop(self):
                +        self.alive = False
                +
                +    def _update_loop(self):
                +        """
                +        Starts the update loop for all known items.
                +        """
                +        self.logger.debug('Starting update loop for instance %s' % self.get_instance_name())
                +        if not self.alive:
                +            return
                +
                +        self._update()
                +
                +    def _update(self):
                +        """
                +        Updates information on diverse items
                +        """
                +        if 'last_update' not in self._items:
                +            self.logger.error("Cannot update measure values, last_update item is missing!")
                +            return
                +
                +        if 'weight' not in self._items:
                +            self.logger.error("Cannot update measure values, weight item is missing!")
                +            return
                +
                +        last_measure = self.get_last_measure()
                +
                +        if 'weight' in last_measure and self._items['last_update']() < last_measure['date']:
                +            self.logger.debug(last_measure)
                +            self._items['weight'](last_measure['weight'])
                +            self._items['last_update'](last_measure['date'])
                +            if 'height' in last_measure and 'height' in self._items:
                +                self._items['height'](last_measure['height'])
                +
                +            if 'height' in self._items and 'bmi' in self._items:
                +                if self._items['height']() > 0:
                +                    bmi = round(
                +                        last_measure['weight'] / ((self._items['height']()) * (self._items['height']())), 2)
                +                    self._items['bmi'](bmi)
                +                else:
                +                    self.logger.error(
                +                        "Cannot calculate BMI: height is 0, please set height (in m) for height item manually.")
                +            else:
                +                self.logger.error("Cannot calculate BMI: height and / or bmi item missing.")
                +
                +            if 'fat_ratio' in last_measure and 'fat_ratio' in self._items:
                +                self._items['fat_ratio'](last_measure['fat_ratio'])
                +
                +            if 'fat_free_mass' in last_measure and 'fat_free_mass' in self._items:
                +                self._items['fat_free_mass'](last_measure['fat_free_mass'])
                +
                +            if 'fat_mass_weight' in last_measure and 'fat_mass_weight' in self._items:
                +                self._items['fat_mass_weight'](last_measure['fat_mass_weight'])
                +
                +            if 'heart_pulse' in last_measure and 'heart_pulse' in self._items:
                +                self._items['heart_pulse'](last_measure['heart_pulse'])
                +        else:
                +            self.logger.debug("No update - no weight data or no new values since last update!")
                +
                +    def parse_item(self, item):
                +        """
                +        Default plugin parse_item method. Is called when the plugin is initialized. Selects each item corresponding to
                +        the Nokia Health identifier and adds it to an internal array
                +
                +        :param item: The item to process.
                +        """
                +        # items specific to call monitor
                +        if self.get_iattr_value(item.conf, 'nh_type') in ['weight', 'height', 'bmi', 'fat_ratio', 'fat_free_mass',
                +                                                          'fat_mass_weight', 'heart_pulse', 'last_update']:
                +            self._items[self.get_iattr_value(item.conf, 'nh_type')] = item
                +
                +    def get_last_measure(self):
                +        measure_url = self.BASE_URL + "measure?action=getmeas&oauth_consumer_key=%s&oauth_nonce=%s&oauth_signature=%s&oauth_signature_method=HMAC-SHA1&oauth_token=%s&oauth_version=1.0&userid=%s&limit=10" % (
                +            self._oauth_consumer_key, self._oauth_nonce, self._oauth_signature, self._oauth_token, self._userid)
                +        response = requests.get(measure_url)
                +        json = response.json()
                +
                +        result = {}
                +        if json['status'] == 0:
                +            body = json['body']
                +            measuregrps = body['measuregrps']
                +            date = measuregrps[0]['date']
                +            result['date'] = date
                +
                +            for mgrp in measuregrps:
                +                if date != mgrp['date']:
                +                    break
                +
                +                for m in mgrp['measures']:
                +                    if m['type'] in self.ALLOWED_MEASURE_TYPES:
                +                        if m['type'] == 1:
                +                            result['weight'] = m['value'] * pow(10, m['unit'])
                +                        elif m['type'] == 4:
                +                            result['height'] = m['value'] * pow(10, m['unit'])
                +                        elif m['type'] == 5:
                +                            result['fat_free_mass'] = m['value'] * pow(10, m['unit'])
                +                        elif m['type'] == 6:
                +                            result['fat_ratio'] = m['value'] * pow(10, m['unit'])
                +                        elif m['type'] == 8:
                +                            result['fat_mass_weight'] = m['value'] * pow(10, m['unit'])
                +                        elif m['type'] == 11:
                +                            result['heart_pulse'] = m['value'] * pow(10, m['unit'])
                +                    else:
                +                        self.logger.error('Measure Type %s currently not supported' % m['type'])
                +        else:
                +            self.logger.error('Status: %s' % json['status'])
                +
                +        return result
                +        # Status Codes:
                +        #  0 : Operation was successful
                +        # 247 : The userid provided is absent, or incorrect
                +        # 250 : The provided userid and/or Oauth credentials do not match
                +        # 283 : Token is invalid or doesn't exist
                +        # 286 : No such subscription was found
                +        # 293 : The callback URL is either absent or incorrect
                +        # 294 : No such subscription could be deleted
                +        # 304 : The comment is either absent or incorrect
                +        # 305 : Too many notifications are already set
                +        # 328: The user is deactivated
                +        # 342 : The signature (using Oauth) is invalid
                +        # 343 : Wrong Notification Callback Url don't exist
                +        # 601 : Too Many Request
                +        # 2554 : Wrong action or wrong webservice
                +        # 2555 : An unknown error occurred
                +        # 2556 : Service is not defined
                \ No newline at end of file
                diff --git a/nokia_health/plugin.yaml b/nokia_health/plugin.yaml
                new file mode 100644
                index 000000000..618c7bfeb
                --- /dev/null
                +++ b/nokia_health/plugin.yaml
                @@ -0,0 +1,23 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung der Nokia Health API'
                +        en: ''
                +    maintainer: 'psilo909'
                +    tester: 'psilo909'
                +    support: 'https://knx-user-forum.de/forum/supportforen/smarthome-py/1141179-nokia-health-plugin'
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: NokiaHealth         # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +
                diff --git a/nokia_health/requirements.txt b/nokia_health/requirements.txt
                new file mode 100644
                index 000000000..648060e1e
                --- /dev/null
                +++ b/nokia_health/requirements.txt
                @@ -0,0 +1,2 @@
                +requests>=2.9.1;python_version>'3.2'
                +requests==2.5.1;python_version=='3.2'
                diff --git a/nuki/plugin.yaml b/nuki/plugin.yaml
                new file mode 100755
                index 000000000..fe4c8810d
                --- /dev/null
                +++ b/nuki/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für ein Nuki Smart-Lock'
                +        en: ''
                +    maintainer: fuppy, pfischi
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1052437-nuki-smartlock-plugin-support-thread
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Nuki                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/nut/plugin.yaml b/nut/plugin.yaml
                new file mode 100755
                index 000000000..64670fe79
                --- /dev/null
                +++ b/nut/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung an eine UPS über den NUT deamon'
                +        en: ''
                +    maintainer: 4d4mu
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: NUT                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/odlinfo/plugin.yaml b/odlinfo/plugin.yaml
                new file mode 100755
                index 000000000..0b06b65d3
                --- /dev/null
                +++ b/odlinfo/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung der Datenschnittstelle des Bundesamts für Strahlenschutz, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: psilo909
                +    tester: Sandman60
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/986480-odlinfo-plugin-für-strahlungsdaten
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: ODLInfo             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/onewire/README.md b/onewire/README.md
                index d59d209a8..5407d8f19 100644
                --- a/onewire/README.md
                +++ b/onewire/README.md
                @@ -14,7 +14,7 @@ Hint2: You can also use a running owserver on another host.
                 
                 ## Configuration
                 
                -### plugin.conf
                +### plugin.conf (deprecated)
                 
                 ```
                 [ow]
                @@ -23,6 +23,15 @@ Hint2: You can also use a running owserver on another host.
                 #    host = 127.0.0.1
                 #    port = 4304
                 ```
                +### plugin.yaml
                +
                +```
                +ow:
                +    class_name: OneWire
                +    class_path: plugins.onewire
                +#    host: 127.0.0.1
                +#    port: 4304
                +```
                 
                 This plugins is looking by default for the owserver on 127.0.0.1 port 4304. You could change this in your plugin.conf.
                 
                @@ -32,7 +41,7 @@ Advanced options in plugin.conf. Please be careful.
                 * 'io_wait' = timeperiod between two requests of 1-wire I/O chip. Default 5 seconds.
                 * 'button_wait' = timeperiod between two requests of ibutton-busmaster. Default 0.5 seconds.
                 
                -### items.conf
                +### Item config
                 
                 #### name
                 This is a name for the defined sensor information.
                @@ -73,6 +82,7 @@ Currently the following 1wire devices are tested by users:
                 * DATANAB DS2438 (rugged temp/hum)
                 * D2PC (dual I/O DS2406)
                 
                +#### item.conf example (deprecated)
                 ```
                 [test-1wire]
                     [[bm-ibutton]]
                @@ -120,6 +130,54 @@ Currently the following 1wire devices are tested by users:
                         ow_sensor = V
                 ```
                 
                +#### item.yaml example
                +```
                +test-1wire:
                +    bm-ibutton:
                +        name: ibutton busmaster to identify ibutton buses
                +        type: bool
                +        ow_addr: '81.75172D000000'
                +        ow_sensor: BM
                +    ib-guest:
                +        name: ibutton guest
                +        type: bool
                +        ow_addr: '01.787D58130000'
                +        ow_sensor: B
                +    temp_outside:
                +        name: temperature outside
                +        type: num
                +        ow_addr: '28.8DEAAA030000'
                +        # could be T, T9, T10, T11, T12
                +        ow_sensor: T
                +    lux_outside:
                +        name: lux / lightintensity outside
                +        type: num
                +        ow_addr: '26.8DD76B010000'
                +        ow_sensor: L
                +    humidity_outside:
                +        name: humidity outside
                +        type: num
                +        ow_addr: '26.8DD76B010000'
                +        ow_sensor: H
                +    input_water_leak:
                +        name: input water leak detection
                +        type: bool
                +        ow_addr: '3A.C6CC07000000'
                +        # could be IA, IB
                +        ow_sensor: IA
                +    output_led1:
                +        name: output led1 keys
                +        type: bool
                +        ow_addr: '3A.C6CC07000000'
                +        # could be OA, OB
                +        ow_sensor: OB
                +    voltage_sensor:
                +        name: voltage of the sensor input (0-10V)
                +        type: num
                +        ow_addr: '26.A9D76B010000'
                +        ow_sensor: V
                +```
                +
                 ## Functions
                 
                 ### ibutton_hook(ibutton, item)
                diff --git a/onewire/__init__.py b/onewire/__init__.py
                index b09879104..7546a27b8 100755
                --- a/onewire/__init__.py
                +++ b/onewire/__init__.py
                @@ -23,8 +23,7 @@
                 import socket
                 import threading
                 import time
                -
                -logger = logging.getLogger('')
                +from lib.model.smartplugin import SmartPlugin
                 
                 
                 class owex(Exception):
                @@ -35,9 +34,12 @@ class owexpath(Exception):
                     pass
                 
                 
                -class OwBase():
                +class OwBase(SmartPlugin):
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.3.1'
                 
                     def __init__(self, host='127.0.0.1', port=4304):
                +        self.logger = logging.getLogger(__name__)
                         self.host = host
                         self.port = int(port)
                         self._lock = threading.Lock()
                @@ -57,13 +59,13 @@ def connect(self):
                         except Exception as e:
                             self._connection_attempts -= 1
                             if self._connection_attempts <= 0:
                -                logger.error('1-Wire: could not connect to {0}:{1}: {2}'.format(self.host, self.port, e))
                +                self.logger.error('1-Wire: could not connect to {0}:{1}: {2}'.format(self.host, self.port, e))
                                 self._connection_attempts = self._connection_errorlog
                             self._lock.release()
                             return
                         else:
                             self.connected = True
                -            logger.info('1-Wire: connected to {0}:{1}'.format(self.host, self.port))
                +            self.logger.info('1-Wire: connected to {0}:{1}'.format(self.host, self.port))
                             self._connection_attempts = 0
                             self._lock.release()
                         try:
                @@ -182,7 +184,7 @@ def identify_sensor(self, path):
                             try:
                                 page3 = self.read(path + 'pages/page.3')  # .encode('hex').upper()
                             except Exception as e:
                -                logger.warning("1-Wire: sensor {0} problem reading page.3: {1}".format(addr, e))
                +                self.logger.warning("1-Wire: sensor {0} problem reading page.3: {1}".format(addr, e))
                                 return
                             try:
                                 vis = float(self.read(path + 'vis').decode())
                @@ -197,7 +199,7 @@ def identify_sensor(self, path):
                             except Exception:
                                 vdd = None
                             if vdd is not None:
                -                logger.debug("1-Wire: sensor {0} voltage: {1}".format(addr, vdd))
                +                self.logger.debug("1-Wire: sensor {0} voltage: {1}".format(addr, vdd))
                                 keys['VDD'] = 'VDD'
                             if page3[0] == 0x19:
                                 return keys
                @@ -211,7 +213,7 @@ def identify_sensor(self, path):
                                 keys['H'] = 'humidity'
                                 return keys
                             else:
                -                logger.info("1-Wire: unknown sensor {0} {1} page3: {2}".format(addr, typ, page3))
                +                self.logger.info("1-Wire: unknown sensor {0} {1} page3: {2}".format(addr, typ, page3))
                                 keys.update({'V': 'VAD', 'VDD': 'VDD'})
                                 return keys
                         elif typ == 'DS2401':  # iButton
                @@ -225,7 +227,7 @@ def identify_sensor(self, path):
                         elif typ == 'DS2408':  # I/O
                             return {'I0': 'sensed.0', 'I1': 'sensed.1', 'I2': 'sensed.2', 'I3': 'sensed.3', 'I4': 'sensed.4', 'I5': 'sensed.5', 'I6': 'sensed.6', 'I7': 'sensed.7', 'O0': 'PIO.0', 'O1': 'PIO.1', 'O2': 'PIO.2', 'O3': 'PIO.3', 'O4': 'PIO.4', 'O5': 'PIO.5', 'O6': 'PIO.6', 'O7': 'PIO.7'}
                         else:
                -            logger.info("1-Wire: unknown sensor {0} {1}".format(addr, typ))
                +            self.logger.info("1-Wire: unknown sensor {0} {1}".format(addr, typ))
                             return
                 
                 
                @@ -269,7 +271,7 @@ def run(self):
                         self._sh.scheduler.add('1w-sen', self._sensor_cycle, cycle=self._cycle, prio=5, offset=0)
                         #self._sh.scheduler.add('1w', self.wrapper('bus.1'), cycle=self._cycle, prio=5, offset=4)
                         if self._ibuttons != {} and self._ibutton_masters == {}:
                -            logger.info("1-Wire: iButtons specified but no dedicated iButton master. Using I/O cycle for the iButtons.")
                +            self.logger.info("1-Wire: iButtons specified but no dedicated iButton master. Using I/O cycle for the iButtons.")
                             for addr in self._ibuttons:
                                 for key in self._ibuttons[addr]:
                                     if key == 'B':
                @@ -294,12 +296,12 @@ def stop(self):
                 
                     def _io_loop(self):
                         threading.currentThread().name = '1w-io'
                -        logger.debug("1-Wire: Starting I/O detection")
                +        self.logger.debug("1-Wire: Starting I/O detection")
                         while self.alive:
                             # start = time.time()
                             self._io_cycle()
                             # cycletime = time.time() - start
                -            # logger.debug("cycle takes {0} seconds".format(cycletime))
                +            # self.logger.debug("cycle takes {0} seconds".format(cycletime))
                             time.sleep(self._io_wait)
                 
                     def _io_cycle(self):
                @@ -314,7 +316,7 @@ def _io_cycle(self):
                                 item = self._ios[addr][key]['item']
                                 path = self._ios[addr][key]['path']
                                 if path is None:
                -                    logger.debug("1-Wire: path not found for {0}".format(item.id()))
                +                    self.logger.debug("1-Wire: path not found for {0}".format(item.id()))
                                     continue
                                 try:
                                     if key == 'B':
                @@ -323,13 +325,13 @@ def _io_cycle(self):
                                     else:
                                         value = self._flip[self.read('/uncached' + path).decode()]
                                 except Exception:
                -                    logger.warning("1-Wire: problem reading {0}".format(addr))
                +                    self.logger.warning("1-Wire: problem reading {0}".format(addr))
                                     continue
                                 item(value, '1-Wire', path)
                 
                     def _ibutton_loop(self):
                         threading.currentThread().name = '1w-b'
                -        logger.debug("1-Wire: Starting iButton detection")
                +        self.logger.debug("1-Wire: Starting iButton detection")
                         while self.alive:
                             self._ibutton_cycle()
                             time.sleep(self._button_wait)
                @@ -380,16 +382,16 @@ def _sensor_cycle(self):
                                 item = self._sensors[addr][key]['item']
                                 path = self._sensors[addr][key]['path']
                                 if path is None:
                -                    logger.info("1-Wire: path not found for {0}".format(item.id()))
                +                    self.logger.info("1-Wire: path not found for {0}".format(item.id()))
                                     continue
                                 try:
                                     value = self.read('/uncached' + path).decode()
                                     if key.startswith('T') and value == '85.0000':
                -                        logger.info("1-Wire: problem reading {0}. Wiring problem?".format(addr))
                +                        self.logger.info("1-Wire: problem reading {0}. Wiring problem?".format(addr))
                                         continue
                                     value = float(value)
                                 except Exception as e:
                -                    logger.warning("1-Wire: problem reading {} {}: {}".format(addr, path, e))
                +                    self.logger.warning("1-Wire: problem reading {} {}: {}".format(addr, path, e))
                                     if not self.connected:
                                         return
                                     else:
                @@ -404,7 +406,7 @@ def _sensor_cycle(self):
                                     value = value * 310 + 450
                                 item(value, '1-Wire', path)
                         cycletime = time.time() - start
                -        logger.debug("1-Wire: sensor cycle takes {0} seconds".format(cycletime))
                +        self.logger.debug("1-Wire: sensor cycle takes {0} seconds".format(cycletime))
                 
                     def _discovery(self):
                         self._intruders = []  # reset intrusion detection
                @@ -415,7 +417,7 @@ def _discovery(self):
                         except Exception:
                             return
                         if type(listing) != list:
                -            logger.warning("1-Wire: listing '{0}' is not a list.".format(listing))
                +            self.logger.warning("1-Wire: listing '{0}' is not a list.".format(listing))
                             return
                         for path in listing:
                             if not self.alive:
                @@ -427,7 +429,7 @@ def _discovery(self):
                                 try:
                                     sensors = self.dir(path)
                                 except Exception as e:
                -                    logger.info("1-Wire: problem reading bus: {0}: {1}".format(bus, e))
                +                    self.logger.info("1-Wire: problem reading bus: {0}: {1}".format(bus, e))
                                     continue
                                 for sensor in sensors:
                                     addr = sensor.split("/")[-2]
                @@ -436,7 +438,7 @@ def _discovery(self):
                                         if keys is None:
                                             continue
                                         self._buses[bus].append(addr)
                -                        logger.info("1-Wire: {0} with sensors: {1}".format(addr, ', '.join(list(keys.keys()))))
                +                        self.logger.info("1-Wire: {0} with sensors: {1}".format(addr, ', '.join(list(keys.keys()))))
                                         if 'IA' in keys or 'IB' in keys or 'I0' in keys or 'I1' in keys or 'I2' in keys or 'I3' in keys or 'I4' in keys or 'I5' in keys or 'I6' in keys or 'I7' in keys:
                                             table = self._ios
                                         elif 'BM' in keys:
                @@ -451,7 +453,7 @@ def _discovery(self):
                                                     try:
                                                         self.write(sensor + keys['O' + ch], 0)
                                                     except Exception as e:
                -                                        logger.info("1-Wire: problem setting {0}{1} as input: {2}".format(sensor, keys['O' + ch], e))
                +                                        self.logger.info("1-Wire: problem setting {0}{1} as input: {2}".format(sensor, keys['O' + ch], e))
                                                     del(keys['O' + ch])
                                             for key in keys:
                                                 if key in table[addr]:
                @@ -461,17 +463,19 @@ def _discovery(self):
                                                     try:
                                                         self.write(table[addr][key]['path'], self._flip[table[addr][key]['item']()])
                                                     except Exception as e:
                -                                        logger.info("1-Wire: problem setting output {0}{1}: {2}".format(sensor, keys['O' + ch], e))
                +                                        self.logger.info("1-Wire: problem setting output {0}{1}: {2}".format(sensor, keys['O' + ch], e))
                         self._discovered = True
                 
                     def parse_item(self, item):
                         if 'ow_addr' not in item.conf:
                             return
                         if 'ow_sensor' not in item.conf:
                -            logger.warning("1-Wire: No ow_sensor for {0} defined".format(item.id()))
                +            self.logger.warning("1-Wire: No ow_sensor for {0} defined".format(item.id()))
                             return
                         addr = item.conf['ow_addr']
                         key = item.conf['ow_sensor']
                +        if len(addr) != 15:
                +            self.logger.warning("1-Wire: Wrong address size '{}' for item {}".format(addr, item))
                         if key in ['IA', 'IB', 'OA', 'OB', 'I0', 'I1', 'I2', 'I3', 'I4', 'I5', 'I6', 'I7', 'O0', 'O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7']:
                             table = self._ios
                         elif key == 'B':
                @@ -483,7 +487,7 @@ def parse_item(self, item):
                             table = self._sensors
                         if key not in self._supported:  # unknown key
                             path = '/' + addr + '/' + key
                -            logger.info("1-Wire: unknown sensor specified for {0} using path: {1}".format(item.id(), path))
                +            self.logger.info("1-Wire: unknown sensor specified for {0} using path: {1}".format(item.id(), path))
                         else:
                             path = None
                             if key == 'VOC':
                @@ -500,4 +504,4 @@ def update_item(self, item, caller=None, source=None, dest=None):
                         try:
                             self.write(item._ow_path['path'], self._flip[item()])
                         except Exception as e:
                -            logger.info("1-Wire: problem setting output {0}: {1}".format(item._ow_path['path'], e))
                +            self.logger.info("1-Wire: problem setting output {0}: {1}".format(item._ow_path['path'], e))
                diff --git a/onewire/plugin.yaml b/onewire/plugin.yaml
                new file mode 100755
                index 000000000..8b20689ee
                --- /dev/null
                +++ b/onewire/plugin.yaml
                @@ -0,0 +1,60 @@
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: '1-Wire Unterstützung über owserver'
                +        en: '1-Wire support via owserver'
                +        fr: 'Support de 1-Wire à travers owserver'
                +    maintainer: cmalo (mknx)
                +    keywords: 1wire onewire
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +    multi_instance: False
                +    classname: OneWire              # class containing the plugin
                +
                +parameters:
                +    host:
                +        type: str
                +        mandatory: False
                +        description:
                +            de: 'owserver Hostnamen oder IP Adresse'
                +            en: 'owserver hostname or ip address'
                +            fr: "Nom de l'hôte ou adresse IP de l'owserver"
                +
                +    port:
                +        type: int
                +        mandatory: False
                +        description:
                +            de: 'owserver Port'
                +            en: 'owserver port'
                +            fr: "Port de l'owserver"
                +    
                +item_attributes:
                +    name:
                +        type: str
                +        description:
                +            de: 'Name des Sensors'
                +            en: 'Sensor name'
                +            fr: 'Nom du capteur'
                +    
                +    type:
                +        type: str
                +        description:
                +            de: "Format der Sensordaten: 'num' oder 'bool'"
                +            en: "Sensor data format:  'num' or 'bool'"
                +            fr: "Format de données du capteur:  'num' ou 'bool'"
                +
                +    ow_addr:
                +        type: str
                +        description:
                +            de: 'Sensoradresse im Format xx.yyyyyyyyyyyy'
                +            en: 'Sensor address in xx.yyyyyyyyyyyy format'
                +            fr: 'Adresse du capteur au format xx.yyyyyyyyyyyy'
                +
                +    ow_sensor:
                +        type: str
                +        description:
                +            de: 'Sensortyp. Unterstützte Typen sind in der Plugin Readme zu finden'
                +            en: 'Sensor type. See plugin readme for supported types'
                +            fr: 'Type du capteur. Voir dans readme du plugin pour formats supportés'
                +
                diff --git a/openenergymonitor/plugin.yaml b/openenergymonitor/plugin.yaml
                new file mode 100755
                index 000000000..724470ad3
                --- /dev/null
                +++ b/openenergymonitor/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Upload von Werten zu einer OpenEnergyMonitor Instanz'
                +        en: ''
                +    maintainer: '? (ReneHezser)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: OpenEnergyMonitor   # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/operationlog/plugin.yaml b/operationlog/plugin.yaml
                new file mode 100755
                index 000000000..9b0f204d1
                --- /dev/null
                +++ b/operationlog/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Implementierung seperater Logs'
                +        en: ''
                +    maintainer: '? (JanT112)'
                +    tester: Sandman60, onkelandy
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: OperationLog        # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/plex/README.md b/plex/README.md
                index 4994b743f..6985b8a14 100644
                --- a/plex/README.md
                +++ b/plex/README.md
                @@ -1,4 +1,4 @@
                -# smarthome-plex
                +# plex
                 
                 Plugin to send push notifications to Plex clients like RasPlex.
                 I only have tested the plugin with RasPlex, the notification module should also be compatible with OpenElec, XBMC / Kodi Frodo and higher.
                diff --git a/plex/plugin.yaml b/plex/plugin.yaml
                new file mode 100755
                index 000000000..8ba992434
                --- /dev/null
                +++ b/plex/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Erlaubt das Senden von Notifications an Plex Clients (wie RasPlex), **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: rthill
                +#    tester:                        # Who tests this plugin?
                +    keywords: mediacenter
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Plex                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/pluggit/README.md b/pluggit/README.md
                index 6eeb9e6fd..16cae0ea2 100644
                --- a/pluggit/README.md
                +++ b/pluggit/README.md
                @@ -115,7 +115,7 @@ Example configuration which shows the current unit mode, the actual week program
                 
                 No logic related stuff implemented.
                 
                -# Methods
                +## Methods
                 
                 No methods provided currently.
                 
                diff --git a/pluggit/plugin.yaml b/pluggit/plugin.yaml
                new file mode 100755
                index 000000000..50c4183ac
                --- /dev/null
                +++ b/pluggit/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung einer KWL Pluggit AP310 über das Modbus Protokoll'
                +        en: ''
                +    maintainer: '? (Henning Behrend / ratzi82)'
                +#    tester:                        # Who tests this plugin?
                +    keywords: modbus
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.2.2                 # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Pluggit             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/prowl/plugin.yaml b/prowl/plugin.yaml
                new file mode 100755
                index 000000000..5a086046e
                --- /dev/null
                +++ b/prowl/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Prowl Unterstützung'
                +        en: ''
                +    maintainer: Foxi352 (mknx)
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Prowl               # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/pushbullet/__init__.py b/pushbullet/__init__.py
                index 3a49f90fd..60d429128 100755
                --- a/pushbullet/__init__.py
                +++ b/pushbullet/__init__.py
                @@ -20,7 +20,7 @@
                 #########################################################################
                 
                 import logging
                -
                +import sys
                 import json
                 import requests
                 import magic
                @@ -28,6 +28,7 @@
                 import re
                 from lib.model.smartplugin import SmartPlugin
                 
                +
                 class Pushbullet(SmartPlugin):
                     _apiurl = "https://api.pushbullet.com/v2/pushes"
                     _upload_apiurl = "https://api.pushbullet.com/v2/upload-request"
                @@ -53,7 +54,9 @@ def delete(self, pushid, apikey=None):
                             apikey = self._apikey
                 
                         try:
                -            response = requests.delete(self._apiurl + "/" + pushid, headers={"User-Agent": "SmartHomeNG", "Content-Type": "application/json"}, auth=(apikey,""))
                +            response = requests.delete(self._apiurl + "/" + pushid,
                +                                       headers={"User-Agent": "SmartHomeNG", "Content-Type": "application/json"},
                +                                       auth=(apikey, ""))
                             if self._is_response_ok(response):
                                 return response.json()
                 
                @@ -67,7 +70,8 @@ def note(self, title, body, deviceid=None, apikey=None):
                         return self._push(data={"type": "note", "title": title, "body": body}, deviceid=deviceid, apikey=apikey)
                 
                     def link(self, title, url, deviceid=None, apikey=None, body=None):
                -        return self._push(data={"type": "link", "title": title, "url": url, "body": body}, deviceid=deviceid, apikey=apikey)
                +        return self._push(data={"type": "link", "title": title, "url": url, "body": body}, deviceid=deviceid,
                +                          apikey=apikey)
                 
                     def address(self, name, address, deviceid=None, apikey=None):
                         return self._push(data={"type": "address", "name": name, "address": address}, deviceid=deviceid, apikey=apikey)
                @@ -89,17 +93,29 @@ def _upload_and_push_file(self, filepath, body=None, deviceid=None, apikey=None)
                             if apikey is None:
                                 apikey = self._apikey
                 
                -            upload_request_response = requests.post(self._upload_apiurl, data=json.dumps({"file_name": os.path.basename(filepath), "file_type": magic.from_file(filepath, mime=True).decode("UTF-8")}), headers=headers, auth=(apikey,""))
                +            if sys.version_info < (3, 5):
                +                upload_request_response = requests.post(self._upload_apiurl, data=json.dumps(
                +                    {"file_name": os.path.basename(filepath),
                +                     "file_type": magic.from_file(filepath, mime=True).decode("UTF-8")}), headers=headers,
                +                                                        auth=(apikey, ""))
                +            else:
                +                upload_request_response = requests.post(self._upload_apiurl, data=json.dumps(
                +                    {"file_name": os.path.basename(filepath), "file_type": magic.from_file(filepath, mime=True)}),
                +                                                        headers=headers, auth=(apikey, ""))
                 
                             if self._is_response_ok(upload_request_response):
                                 data = upload_request_response.json()
                -                upload_response = requests.post(data["upload_url"], data=data["data"], headers={"User-Agent": "SmartHomeNG"}, files={"file": open(filepath, "rb")})
                +                upload_response = requests.post(data["upload_url"], data=data["data"],
                +                                                headers={"User-Agent": "SmartHomeNG"},
                +                                                files={"file": open(filepath, "rb")})
                 
                                 if self._is_response_ok(upload_response):
                                     if body is None:
                                         body = ""
                 
                -                    return self._push(data={"type": "file", "file_name": data["file_name"], "file_type": data["file_type"], "file_url": data["file_url"], "body": body}, deviceid=deviceid, apikey=apikey)
                +                    return self._push(
                +                        data={"type": "file", "file_name": data["file_name"], "file_type": data["file_type"],
                +                              "file_url": data["file_url"], "body": body}, deviceid=deviceid, apikey=apikey)
                                 else:
                                     self.logger.error("Error while uploading file: {0}".format(upload_response.text))
                             else:
                @@ -122,7 +138,9 @@ def _push(self, data, deviceid=None, apikey=None):
                             data["device_iden"] = deviceid
                 
                         try:
                -            response = requests.post(self._apiurl, data=json.dumps(data), headers={"User-Agent": "SmartHomeNG", "Content-Type": "application/json"}, auth=(apikey,""))
                +            response = requests.post(self._apiurl, data=json.dumps(data),
                +                                     headers={"User-Agent": "SmartHomeNG", "Content-Type": "application/json"},
                +                                     auth=(apikey, ""))
                             if self._is_response_ok(response):
                                 return response.json()
                 
                @@ -155,4 +173,4 @@ def _is_response_ok(self, response):
                         if self._debug:
                             self.logger.warning("Response was: {}".format(response.text))
                 
                -        return False
                \ No newline at end of file
                +        return False
                diff --git a/pushbullet/plugin.yaml b/pushbullet/plugin.yaml
                new file mode 100755
                index 000000000..106254dc7
                --- /dev/null
                +++ b/pushbullet/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung des Pushbullet Service'
                +        en: ''
                +    maintainer: '? (lbernau)'
                +    tester: onkelandy, psilo909, Sandman60
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Pushbullet          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/pushover/README.md b/pushover/README.md
                new file mode 100755
                index 000000000..f9368627e
                --- /dev/null
                +++ b/pushover/README.md
                @@ -0,0 +1,85 @@
                +# Pushover  
                +
                +Pushover is one out of many push services, which is compatible with Android, IOS and Windows Clients. This plugin make it possible to push messages to your clients from SmartHomeNG.
                +  
                +## Requirements
                +  
                +### Python libraries  
                +* requests - [install instructions](http://docs.python-requests.org/en/latest/user/install/#install "http://docs.python-requests.org/en/latest/user/install/#install")
                +  
                +### Other  
                +* Pushover API-KEY - get it from [__here__](https://pushover.net/apps/ "https://pushover.net/apps/") for free, after registration.
                +  
                +---
                +## Changelog
                +
                +__2017-08-13__:
                +
                +* Initial version
                +  
                +---
                +## Configuration  
                +  
                +### plugin.conf (deprecated) / plugin.yaml
                +  
                +```
                +[po]
                +    class_name = Pushover
                +    class_path = plugins.pushover
                +    apiKey = <your-api-key>
                +    userKey = <your-user-key>
                +#   device = <your-device-string(optional)>
                +```
                +
                +```yaml
                +po:
                +    class_name: Pushover
                +    class_path: plugins.pushover
                +    apiKey: <your-api-key>
                +    userKey: <your-user-key>
                +#   device: <your-device-string(optional)>
                +```
                +
                +Description of the attributes:
                +  
                +* __apiKey__: set api-key globally of the sending application
                +* __userKey__: set user-key globally so it will be used as defaul receiving user - you can override this on each call
                +* __device__: set receiving device globally to filter the receive device - you can override this on each call - you can define multiple devices seperated by comma - this is optional - without all devices will receive messages
                +  
                +---    
                +## Usage:
                +  
                +### sh.po(title, message [, priority] [, retry] [, expire] [, sound] [, url] [, url_title] [, device] [, userKey] [, apiKey])
                +Send a message to your device.  
                +  
                +#### Parameters  
                +* __title__: The title of the message
                +* __message__:  The message - some html code possible, read https://pushover.net/api#html
                +* __priority__: Priority of the message - read https://pushover.net/api#priority
                +* __retry__: when Emergency priority set, this specifies how often (in seconds) the Pushover servers will send the same notification to the user - read https://pushover.net/api#priority
                +* __expire__: when Emergency priority set, this specifies how many seconds your notification will continue to be retried for (every retry seconds) - read https://pushover.net/api#priority
                +* __sound__: override a user's default tone choice on a per-notification basis - read https://pushover.net/api#sounds
                +* __url__: adds a supplementary URL that is not included in the message text, but available for the user to click on - read https://pushover.net/api#urls
                +* __url_title__: the title for the a supplementary URL - read https://pushover.net/api#urls
                +* __device__: defines and/or override the globally defined name of the receiving device
                +* __userKey__: defines and/or override the globally defined user-key of the receiving user
                +* __apiKey__: defines and/or override the globally defined api-key of the sending application
                +
                +All params can set to None (only message not), so they will not be set or in case of device, userKey and apiKey the global vars will be used.
                +  
                +#### Example
                +```python
                +
                +# send simple message, without title (this are the min. params you need, if you defined userKey and apiKey globally)
                +sh.po(None, "This is my test message.")
                +
                +# send simple message, with title
                +sh.po("Simple Test", "This is my test message.")
                +
                +# send a high priority message
                +sh.po("Warning", "Your door is not locked!", 1)
                +
                +# send simple message to device with id: e6653
                +sh.po("Simple Test", "This is my test message", None, None, None, None, None, None, "e6653")
                +
                +```
                diff --git a/pushover/__init__.py b/pushover/__init__.py
                new file mode 100755
                index 000000000..49c3cabde
                --- /dev/null
                +++ b/pushover/__init__.py
                @@ -0,0 +1,141 @@
                +#!/usr/bin/env python
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2017 Thomas Creutz                      thomas.creutz@gmx.de
                +#########################################################################
                +#  This file is part of SmartHomeNG
                +#  https://github.com/smarthomeNG/smarthome
                +#  http://knx-user-forum.de/
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import logging
                +from lib.model.smartplugin import SmartPlugin
                +
                +import time
                +import json
                +import requests
                +
                +class Pushover(SmartPlugin):
                +
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = "1.3.1.0"
                +
                +    _url = "https://api.pushover.net/1/messages.json"
                +
                +    def __init__(self, sh, apiKey=None, userKey=None, device=None):
                +        self._sh = sh
                +        self.logger = logging.getLogger(__name__)
                +        self._apiKey = apiKey
                +        self._userKey = userKey
                +        self._device = device
                +
                +    def run(self):
                +        pass
                +
                +    def stop(self):
                +        pass
                +
                +    def __call__(self, title=None, message='', priority=None, retry=None, expire=None, sound=None, url=None, url_title=None, device=None, userKey=None, apiKey=None):
                +        data = {}
                +        headers = {'User-Agent': "SmartHomeNG", 'Content-Type': "application/x-www-form-urlencoded"}
                +
                +        data['timestamp'] = int(time.time())
                +
                +        if title:
                +            data['title'] = title[:250].encode()
                +
                +        data['message'] = message[:1000].encode()
                +
                +        if priority:
                +            if isinstance(priority, int) and priority >= -2 and priority <= 2:
                +                data['priority'] = priority
                +
                +                if retry and priority == 2:
                +                    if isinstance(retry, int) and retry >= 30:
                +                        data['retry'] = retry
                +                    else:
                +                        data['retry'] = 30
                +                        self.logger.error("Pushover message retry need at least 30 secounds! I set it to 30!")
                +                elif not retry and priority == 2:
                +                    self.logger.error("Pushover message priority = 2 need retry to be set, degrade priority to 1!")
                +                    data['priority'] = 1
                +
                +                if expire and priority == 2:
                +                    if isinstance(expire, int) and expire > 10800:
                +                        data['expire'] = expire
                +                    else:
                +                        data['expire'] = 10800
                +                        self.logger.error("Pushover message expire need at most 10800 secounds! I set it to 10800.")
                +                elif not expire and priority == 2:
                +                    self.logger.error("Pushover message priority = 2 need expire to be set, degrade priority to 1!")
                +                    data['priority'] = 1
                +
                +                # delete not used vars
                +                if data['priority'] < 2:
                +                    if 'expire' in data:
                +                        del data['expire']
                +                    if 'retry' in data:
                +                        del data['retry']
                +
                +            else:
                +                self.logger.error("Pushover message priority need to be a number between -2 and 2!")
                +
                +        if sound:
                +            data['sound'] = sound
                +
                +        if url:
                +            data['url'] = url[:512]
                +            if url_title:
                +                data['url_title'] = url_title[:100]
                +
                +        if userKey:
                +            data['user'] = userKey
                +        elif self._userKey:
                +            data['user'] = self._userKey
                +        else:
                +            self.logger.error("Pushover needs a userKey")
                +            return
                +
                +        if apiKey:
                +            data['token'] = apiKey
                +        elif self._apiKey:
                +            data['token'] = self._apiKey
                +        else:
                +            self.logger.error("Pushover needs a apiKey")
                +            return
                +
                +        if device:
                +            data['device'] = device
                +        elif self._device:
                +            data['device'] = self._device
                +
                +        try:
                +            resp = requests.post(self._url, headers=headers, data=data)
                +
                +            # read json response on successful status 200 
                +            if (resp.status_code == 200):
                +                json_data = resp.json()
                +
                +            # process response
                +            if (resp.status_code == 200 and json_data['status'] == 1):
                +                self.logger.debug("Pushover returns: Notification successful submitted.")
                +            elif (resp.status_code == 429):
                +                self.logger.warning("Pushover returns: Message limits have been reached.")
                +            else:
                +                self.logger.warning("Pushover returns: {0} - {1}".format(resp.status_code, resp.text))
                +
                +        except Exception as e:
                +            self.logger.warning("Could not send Pushover notification: {0}. Error: {1}".format(event, e))
                diff --git a/pushover/requirements.txt b/pushover/requirements.txt
                new file mode 100644
                index 000000000..648060e1e
                --- /dev/null
                +++ b/pushover/requirements.txt
                @@ -0,0 +1,2 @@
                +requests>=2.9.1;python_version>'3.2'
                +requests==2.5.1;python_version=='3.2'
                diff --git a/raumfeld/plugin.yaml b/raumfeld/plugin.yaml
                new file mode 100755
                index 000000000..a2aa432ef
                --- /dev/null
                +++ b/raumfeld/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Prototyp einer einfachen Anbindung von Teufel Raumfeld'
                +        en: ''
                +    maintainer: '? (hholle)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Raumfeld            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/rcswitch/plugin.yaml b/rcswitch/plugin.yaml
                new file mode 100755
                index 000000000..3d508ecb0
                --- /dev/null
                +++ b/rcswitch/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Schalten von 433 MHz Funksteckdosen **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: dafra
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/39094-logic-und-howto-für-433mhz-steckdosen
                +
                +    version: 1.2.0.2               # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: RCswitch            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/roomba/plugin.yaml b/roomba/plugin.yaml
                new file mode 100755
                index 000000000..6bbd0a40b
                --- /dev/null
                +++ b/roomba/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung von iRobot Roomba Staubsaugern'
                +        en: ''
                +    maintainer: '? (Mirko Hirsch)'
                +    tester: Sandman60
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Roomba              # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/rrd/plugin.yaml b/rrd/plugin.yaml
                new file mode 100755
                index 000000000..bd3740ace
                --- /dev/null
                +++ b/rrd/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für RRD. Kann nicht zusammen mit dem sqlite Plugin genutzt werden.'
                +        en: ''
                +    maintainer: '? (mknx)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: RRD                 # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/rtr/plugin.yaml b/rtr/plugin.yaml
                new file mode 100755
                index 000000000..7ee72dbc3
                --- /dev/null
                +++ b/rtr/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Raum Temperatur Regler'
                +        en: ''
                +    maintainer: bmxp (TCr82)
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.2.3                 # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: RTR                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/russound/plugin.yaml b/russound/plugin.yaml
                new file mode 100755
                index 000000000..979e0d613
                --- /dev/null
                +++ b/russound/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung von Russound Audio Geräten'
                +        en: ''
                +    maintainer: '?'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Russound            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/simulation/README.md b/simulation/README.md
                index 320c30a1b..77364f2c0 100644
                --- a/simulation/README.md
                +++ b/simulation/README.md
                @@ -21,6 +21,7 @@ This plugins has no requirements.
                    class_name = Simulation
                    class_path = plugins.simulation
                    data_file = /usr/smarthome/var/db/simulation.txt
                +#   callers = KNX | Visu
                 ```
                 
                 ```yaml
                @@ -28,10 +29,20 @@ simulation:
                     class_name: Simulation
                     class_path: plugins.simulation
                     data_file: /usr/smarthome/var/db/simulation.txt
                +    # callers:
                +    #   - KNX
                +    #   - Visu
                 ```
                 
                 `data_file`: This is the file where all recorded events are stored.
                 
                +`callers`: Is an optional list of event sources for recording of events. When an item is changed, the change is done
                +by someone, e.g. knx for changes from the bus. The caller name is set by the plugin programmer and has to be
                +found out manually.
                +Only item changes with a caller in the list are recorded to the simulation file. In the example above e.g. uzsu is
                +ignored.
                +Be aware that the caller in the list has to be case sensitive. Otherwise it won't trigger.
                +
                 ### items.conf (deprecated) / items.yaml
                 
                  `sim = track` (.conf syntax)
                diff --git a/simulation/__init__.py b/simulation/__init__.py
                index 9e474b2aa..1783e695a 100644
                --- a/simulation/__init__.py
                +++ b/simulation/__init__.py
                @@ -31,8 +31,9 @@
                 #       Added release version to init message
                 #  0.4  Changed logging style
                 #       corrected serious bug in compare entry with NextDay
                +#  0.5  Added feature to select which caller is written to the simulation file 
                 #
                -#x#########################################################################
                +##########################################################################
                 
                 import logging
                 from datetime import datetime, timedelta
                @@ -41,14 +42,15 @@
                 class Simulation(SmartPlugin):
                 
                     ALLOW_MULTIINSTANCE = False
                -    PLUGIN_VERSION = "1.1.0.4"
                +    PLUGIN_VERSION = "1.1.0.5"
                 
                -    def __init__(self, smarthome,data_file):
                +    def __init__(self, smarthome, data_file, callers=None):
                         self.logger = logging.getLogger(__name__)
                -        self.logger.info('Init Simulation release 0.4')
                +        self.logger.info('Init Simulation release 0.5')
                         self._sh = smarthome
                         self._datafile=data_file
                         self.lastday=''
                +        self._callers=callers
                         smarthome.scheduler.add('midnight', self._midnight, cron='0 0 * *', prio=3)
                 
                     def run(self):
                @@ -91,7 +93,7 @@ def parse_logic(self, logic):
                 # Callback. Writes the event to the file
                 
                     def update_item(self, item, caller=None, source=None, dest=None):
                -        if (item.conf['sim'] == 'track') and (self.state()==2):
                +        if (item.conf['sim'] == 'track') and (self.state()==2) and (self._callers and caller in self._callers):
                             now = self._sh.now()
                             day=now.day
                             self.file.write(now.strftime('%a;%H:%M:%S'))
                diff --git a/simulation/plugin.yaml b/simulation/plugin.yaml
                new file mode 100755
                index 000000000..8faad4bac
                --- /dev/null
                +++ b/simulation/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Aufnahme und Abspielen von Aktionsreihenfolgen'
                +        en: ''
                +    maintainer: ggf. cmalo (?)
                +    tester: psilo909, Sandman60, cmalo
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.1.0.5               # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Simulation          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sma/__init__.py b/sma/__init__.py
                index 3e1cdfbd1..4855a8c32 100755
                --- a/sma/__init__.py
                +++ b/sma/__init__.py
                @@ -205,6 +205,9 @@ def __init__(self, smarthome, bt_addr, password="0000", update_cycle="60", allow
                         self._inv_bt_addr_le.reverse()
                         self._plugin_active_item = None
                 
                +        if not hasattr(socket, 'AF_BLUETOOTH'):
                +            raise Exception("Python socket module does not support Bluetooth - see README.md how to install")
                +
                     def _update_values(self):
                         #logger.warning("sma: signal strength = {}%%".format(self._inv_get_bt_signal_strength()))
                         self._cmd_lock.acquire()
                diff --git a/sma/plugin.yaml b/sma/plugin.yaml
                new file mode 100755
                index 000000000..fa80bf04e
                --- /dev/null
                +++ b/sma/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für SMA Inverter SunnyBoy 5000TL-21, Sunny Tripower 8000TL-10, Sunny Tripower 12000TL-10'
                +        en: ''
                +    maintainer: '? (Robert Budde)'
                +    tester: psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SMA                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sma_em/plugin.yaml b/sma_em/plugin.yaml
                new file mode 100755
                index 000000000..240937164
                --- /dev/null
                +++ b/sma_em/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface               # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Auslesen des SMA Energy Meter Netzwerk Multicasts'
                +        en: 'Access to data from SMA Energy Meter network multicast'
                +    maintainer: psilo909
                +    tester: psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SMA_EM              # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/smarttv/plugin.yaml b/smarttv/plugin.yaml
                new file mode 100755
                index 000000000..bc30dca3d
                --- /dev/null
                +++ b/smarttv/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbdindung (Remote Control) von SmartTV Geräten'
                +        en: ''
                +    maintainer: '? (2ndsky)'
                +    tester: psilo909
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.2                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: SmartTV             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/smawb/plugin.yaml b/smawb/plugin.yaml
                new file mode 100755
                index 000000000..a03b8e912
                --- /dev/null
                +++ b/smawb/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung einer oder mehrerer SMA-Sunny-WebBox(en)'
                +        en: ''
                +    maintainer: '? (Brootux)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: SMAWB               # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sml/plugin.yaml b/sml/plugin.yaml
                new file mode 100755
                index 000000000..ccc2c8d0a
                --- /dev/null
                +++ b/sml/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Auslesen von Stromzählern via SML-Protokoll'
                +        en: ''
                +    maintainer: ohinckel
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Sml                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/snom/plugin.yaml b/snom/plugin.yaml
                new file mode 100755
                index 000000000..7179a0431
                --- /dev/null
                +++ b/snom/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Telefonbuch Anbindung für Snom Telefone'
                +        en: ''
                +    maintainer: '? (mknx)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Snom                # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/solarlog/plugin.yaml b/solarlog/plugin.yaml
                new file mode 100755
                index 000000000..f209d7960
                --- /dev/null
                +++ b/solarlog/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Auslesen der Web-Seite eines SolarLog'
                +        en: ''
                +    maintainer: '? (2ndsky)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: SolarLog            # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sonos/README.md b/sonos/README.md
                index e6643dc3c..df3bd89b5 100644
                --- a/sonos/README.md
                +++ b/sonos/README.md
                @@ -19,8 +19,9 @@
                 ## <a name="req"></a>Requirements
                 
                 * SmarthomeNG v1.3 or newer
                -* Python3 libraries ```requests``` and ```xmltodict```
                +* Python3 libraries ```requests```, ```tinytag``` and ```xmltodict```
                 * available ```ping``` executable on the host system
                +* tested on Sonos software 8.1
                 
                 To install all necessary libraries for SmarthomeNG, you can run following bash command:
                 
                @@ -60,17 +61,28 @@ The first line of each entry is our UID (rincon_xxxxxxxxxxxxxx) we were looking
                 
                 ## <a name="sh"></a>Smarthome Integration
                 
                -Edit the file ```/usr/local/smarthome/etc/plugins.conf``` (might differ) and add the following entry:
                +Edit the file ```/usr/local/smarthome/etc/plugins.yaml``` (might differ) and add the following entry:
                 ```yaml
                -[sonos]
                -    class_name = Sonos
                -    class_path = plugins.sonos
                -    discover_cycle = 120 # can be omitted, default 120 seconds
                +
                +Sonos:
                +    class_name: Sonos
                +    class_path: plugins.sonos
                +    # tts: true                          # optional, default:  false
                +    # local_webservice_path: /tmp/tts    # optional, default:  empty. If 'tts' is enabled, this option is mandatory. 
                +                                         # All tts files will be stored here.
                +    # webservice_ip: 192.168.1.40        # optional, default:  automatic. You can set a specific ip address.
                +                                         # If you're using a docker container, you have to set the host 
                +                                         # ip address here.  
                +    # webservice_port: 23500             # optional, default:  23500
                +    # discover_cycle: 120                # optional, default:  120 (in seconds)
                +    # speaker_ips:                       # optional. You can set static IP addresses for your Sonos speaker. This
                +    #   - 192.168.1.10                   # will disable auto-discovery. This is useful if you're using a 
                +    #   - 192.168.1.77                   # containerized environment with restricted network access.
                 ```
                 
                 After that you have to create an item configuration file under ```/usr/local/smarthome/items```, e.g. ```sonos.yaml```.
                 You can use the full-featured example configuration in the example sub folder. Just change the [Sonos UID](#uid) to your
                -needs.
                +needs.<
                 
                 ### <a name="struc"></a>Item Structure 
                 The first thing to mention is that you don't have to implement all items / functions for a speaker. Choose your
                @@ -248,18 +260,18 @@ Loads a Sonos playlist by its name. The item ```sonos_playlists``` shows all ava
                 command can be executed on any speaker of a group.
                  
                 _child item_ ```start_after```:
                -If you add an child item (type ```bool```) with an attribute ```sonos_attrib = start_after``` you can control the 
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: start_after``` you can control the 
                 behaviour after the playlist was loaded. If you set this item to ```True```, the speaker starts playing
                 immediately, ```False``` otherwise. (see example item configuration). You can omit this child item, the default
                 setting is 'False'.
                 
                 _child item_ ```clear_queue```:
                -If you add an child item (type ```bool```) with an attribute ```sonos_attrib = clear_queue```, the Sonos queue will be 
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: clear_queue```, the Sonos queue will be 
                 cleared before loading the new playlist if you set this item to ```True```, ```False``` otherwise. (see example item 
                 configuration). You can omit this child item, the default setting is 'False'.
                 
                 _child item_ ```start_track```:
                -If you add an child item (type ```num```) with an attribute ```sonos_attrib = start_track```, you can define the track 
                +If you add an child item (type ```num```) with an attribute ```sonos_attrib: start_track```, you can define the track 
                 to start play from. First item in the queue is 0. You can omit this child item, the default setting is 0.
                 
                 #### loudness
                @@ -327,17 +339,56 @@ Sets / gets the play mode for a speaker. Allowed values are 'NORMAL', 'REPEAT_AL
                 'SHUFFLE_REPEAT_ONE', 'REPEAT_ONE'. This is a group command and effects all speakers in the group. This item is changed 
                 by Sonos events and should always be up-to-date.
                 
                +#### play_snippet
                +```write```
                +
                +Plays a snippet audio file by a given audio filename (e.g. 'alarm.mp3'). You have to set at least two parameters in the 
                +```plugin.yaml```: ```tts``` and the ```local_webservice_path``` to enable this feature. You have to save the audio file
                + to the value of parameter ```local_webservice_path```. Following audio formats should be supported: 'mp3', 'mp4', 'ogg', 'wav', 'aac' (tested
                + only with 'mp3'). This is a group command and effects all speakers in the group.
                +
                +_child item_ ```snippet_volume```:
                +If you add an child item (type ```num```) with an attribute ```sonos_attrib: snippet_volume``` you can set the volume 
                +for the audio snippet. This does not affect the normal ```volume``` and will be resetted to the normal ```volume``` 
                +level after the audio file was played. If a speaker group is in use, the volume level for each speaker is restored 
                +separately.
                +
                +_child item_ ```snippet_fade_in```:
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: snippet_fade_in``` the normal ```volume``` 
                +will be increased from 0 to the desired volume level after the audio file was played.
                +
                +#### play_tts
                +```write```
                +
                +Sets a message which will be parsed by the Google TTS API. You have to set at least two parameters in the 
                +```plugin.yaml```: ```tts``` and the ```local_webservice_path```. This is a group command and effects all speakers in 
                +the group.
                +
                +_child item_ ```tts_language```:
                +If you add an child item (type ```str```) with an attribute ```sonos_attrib: tts_language``` you set the TTS language.
                +Valid values are 'en', 'de', 'es', 'fr', 'it'. You can omit this child item, the default setting is 'de'.
                + 
                +_child item_ ```tts_volume```:
                +If you add an child item (type ```num```) with an attribute ```sonos_attrib: tts_volume``` you can set the volume for 
                +the TTS message. This does not affect the normal ```volume``` and will be resetted to the normal ```volume``` level 
                +after the TTS message was played. If a speaker group is in use, the volume level for each speaker is restored 
                +separately.
                +
                +_child item_ ```tts_fade_in```:
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: tts_fade_in``` the normal ```volume``` 
                +will be increased from 0 to the desired volume level after the TTS message was played.
                +
                 #### play_tunein
                 ```write```
                 
                 Plays a radio station by a give name. Keep in mind that Sonos searches for an appropiate radio station. If more than one
                -station was found, the first result will be used. 
                +station was found, the first result will be used. This is a group command and effects all speakers in the group. 
                 
                 _child item_ ```start_after```:
                -If you add an child item (type ```bool```) with an attribute ```sonos_attrib =start_after``` you can control the behaviour
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: start_after``` you can control the behaviour
                 after the radio station was added to the Sonos speaker. If you set this item to ```True```, the speaker starts playing
                 immediately, ```False``` otherwise. (see example item configuration). You can omit this child item, the default
                -setting is 'True'.
                +setting is 'True'. 
                 
                 #### play_url
                 ```write```
                @@ -345,10 +396,10 @@ setting is 'True'.
                 Plays a given url. 
                 
                 _child item_ ```start_after```:
                -If you add an child item (type ```bool```) with an attribute ```sonos_attrib =start_after``` you can control the behaviour
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: start_after``` you can control the behaviour
                 after the url was added to the Sonos speaker. If you set this item to ```True```, the speaker starts playing
                 immediately, ```False``` otherwise. (see example item configuration). You can omit this child item, the default
                -setting is 'True'.
                +setting is 'True'. This is a group command and effects all speakers in the group.
                 
                 #### previous
                 ```write``` ```visu```
                @@ -383,7 +434,7 @@ real-time. For each speaker discover cycle the item will be updated.
                 
                 Returns a list of Sonos playlists. These playlists can be loaded by the ```load_sonos_playlist``` item. 
                 
                -#### status_light**
                +#### status_light
                 ```read``` ```write```
                 
                 Sets / gets the status light indicator of a speaker. 'True' to turn the light on, 'False' to turn it off. The value is 
                @@ -459,7 +510,7 @@ Returns the UID of a Sonos speaker.
                 Unjoins a speaker from a group. 
                 
                 _child item_ ```start_after```:
                -If you add an child item (type ```bool```) with an attribute ```sonos_attrib =start_after``` you can control the 
                +If you add an child item (type ```bool```) with an attribute ```sonos_attrib: start_after``` you can control the 
                 behaviour after the speaker was unjoined from a group.. If you set this item to ```True```, the speaker starts playing
                 immediately, ```False``` otherwise. (see example item configuration). You can omit this child item, the default
                 setting is 'False'.
                @@ -503,7 +554,7 @@ step in seconds ```[sonos_dpt3_time]```. Both values can be omitted. In this cas
                 ```sonos_dpt3_step: 2``` and ```sonos_dpt3_step: 1```. The ```group_command``` and ```max_volume``` items will be 
                 considered.
                 
                -#### zone_group_members**
                +#### zone_group_members
                 ```read```
                 
                 Returns a list of all UIDs of the group the speaker is a member in. The list contains always the current speaker. This 
                @@ -709,9 +760,29 @@ becomes
                           type: num
                           sonos_send: volume
                 ```
                +### TTS and Snippet functionality
                +
                +If you want to use either the ```play_tts``` or ```play_snippet``` functionality, you have to enable the ```tts```
                +option for the Sonos plugin in your ```plugin.yaml```. In addition to that, you have to set a valid local path for the
                +```local_webservice_path``` option. A very simple Webservice will be started to serve Sonos requests.
                +
                +### Configure Speaker IPs manually
                +
                +You can set the IP addresses of your speakers statically to avoid using the internal discover function.
                +This can be useful if you're using Docker or Rkt and you don't want to allow UDP and/or Multicast packets.  
                +To do so, edit your ```etc/plugin.yaml``` and configure it like this:
                +
                +```yaml
                +Sonos:
                +    class_name: Sonos
                +    class_path: plugins.sonos
                +    speaker_ips:                       
                +      - 192.168.1.10                    
                +      - 192.168.1.77                   
                +```
                 
                 ### Debug on error
                 
                 You've any trouble to get the plugin working, start SmarthomeNG in debug mode and post the logfile with the error to
                 the [**support thread**](https://knx-user-forum.de/forum/supportforen/smarthome-py/25151-sonos-anbindung) in the 
                -KNX User Forum.
                \ No newline at end of file
                +KNX User Forum.
                diff --git a/sonos/__init__.py b/sonos/__init__.py
                index 1ddec665a..7144e9d2a 100755
                --- a/sonos/__init__.py
                +++ b/sonos/__init__.py
                @@ -1,7 +1,7 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                 #########################################################################
                -#  Copyright 2016 <AUTHOR>                                        <EMAIL>
                +#  Copyright 2016 pfischi                                               #
                 #########################################################################
                 #  This file is part of SmartHomeNG.   
                 #
                @@ -27,9 +27,17 @@
                 import os
                 import logging
                 import re
                +import socketserver
                 import subprocess
                 import threading
                +from http.server import HTTPServer, BaseHTTPRequestHandler
                 from queue import Empty
                +import sys
                +from urllib.parse import unquote
                +
                +import requests
                +from requests.utils import quote
                +from tinytag import TinyTag
                 
                 from plugins.sonos.soco.exceptions import SoCoUPnPException
                 from plugins.sonos.soco.music_services import MusicService
                @@ -38,12 +46,110 @@
                 from lib.model.smartplugin import SmartPlugin
                 from plugins.sonos.soco.data_structures import to_didl_string, DidlItem, DidlMusicTrack
                 from plugins.sonos.soco.events import event_listener
                +from plugins.sonos.soco.snapshot import Snapshot
                 from plugins.sonos.soco.xml import XML
                 import time
                 
                +from plugins.sonos.tts import gTTS
                +from plugins.sonos.utils import file_size, get_tts_local_file_path, get_free_diskspace, get_folder_size
                +
                 _create_speaker_lock = threading.Lock()  # make speaker object creation thread-safe
                 sonos_speaker = {}
                 
                +
                +class WebserviceHttpHandler(BaseHTTPRequestHandler):
                +    webroot = None
                +
                +    def __init__(self, request, client_address, server):
                +        self._logger = logging.getLogger('sonos')  # get a unique logger for the plugin and provide it internally
                +        super().__init__(request, client_address, server)
                +
                +    def _get_mime_type_by_filetype(self, file_path):
                +        try:
                +            mapping = {
                +                "audio/aac": "aac",
                +                "audio/mp4": "mp4",
                +                "audio/mpeg": "mp3",
                +                "audio/ogg": "ogg",
                +                "audio/wav": "wav",
                +            }
                +
                +            filename, extension = os.path.splitext(file_path)
                +            extension = extension.strip('.').lower()
                +
                +            for mime_type, key in mapping.items():
                +                if extension == key:
                +                    return mime_type
                +            raise Exception("Could not found mime-type for extension '{ext}'.".format(ext=extension))
                +
                +        except Exception as err:
                +            self._logger.warning(err)
                +            return None
                +
                +    def do_GET(self):
                +        try:
                +            if WebserviceHttpHandler.webroot is None:
                +                self.send_error(404, 'Service Not Enabled')
                +                return
                +
                +            file_name = unquote(self.path)
                +            # prevent path traversal
                +            file_name = os.path.normpath('/' + file_name).lstrip('/')
                +            file_path = os.path.join(WebserviceHttpHandler.webroot, file_name)
                +
                +            if not os.path.exists(file_path):
                +                self.send_error(404, 'File Not Found: %s' % self.path)
                +                return
                +
                +            # get registered mime-type
                +            mime_type = self._get_mime_type_by_filetype(file_path)
                +
                +            if mime_type is None:
                +                self.send_error(406, 'File With Unsupported Media-Type : %s' % self.path)
                +                return
                +
                +            client = "{ip}:{port}".format(ip=self.client_address[0], port=self.client_address[1])
                +            self._logger.debug("Webservice: delivering file '{path}' to client ip {client}.".format(path=file_path,
                +                                                                                                    client=client))
                +            file = open(file_path, 'rb').read()
                +            self.send_response(200)
                +            self.send_header('Content-Type', mime_type)
                +            self.send_header('Content-Length', sys.getsizeof(file))
                +            self.end_headers()
                +            self.wfile.write(file)
                +        except Exception as ex:
                +            self._logger.error("Error delivering file {file}".format(file=file_path))
                +            self._logger.error(ex)
                +        finally:
                +            self.connection.close()
                +
                +
                +class ThreadedHTTPServer(socketserver.ThreadingMixIn, HTTPServer):
                +    allow_reuse_address = True
                +
                +    def shutdown(self):
                +        self.socket.close()
                +        HTTPServer.shutdown(self)
                +
                +
                +class SimpleHttpServer:
                +    def __init__(self, ip, port, root_path):
                +        self.server = ThreadedHTTPServer((ip, port), WebserviceHttpHandler)
                +        self.thread = threading.Thread(target=self.server.serve_forever)
                +        self.thread.daemon = True
                +        WebserviceHttpHandler.webroot = root_path
                +
                +    def start(self):
                +        self.thread.start()
                +
                +    def waitForThread(self):
                +        self.thread.join()
                +
                +    def stop(self):
                +        self.server.shutdown()
                +        self.waitForThread()
                +
                +
                 class SubscriptionHandler(object):
                     def __init__(self, endpoint, service):
                         self._lock = threading.Lock()
                @@ -90,6 +196,7 @@ def is_subscribed(self):
                             return self._event.is_subscribed
                         return False
                 
                +
                 class Speaker(object):
                     def __init__(self, uid, logger):
                         self._logger = logger
                @@ -167,7 +274,7 @@ def __init__(self, uid, logger):
                         self.sonos_playlists_items = []
                         self._is_initialized = False
                         self.is_initialized_items = []
                -
                +        self._snippet_queue_lock = threading.Lock()
                         self.av_subscription = None
                         self.render_subscription = None
                         self.system_subscription = None
                @@ -938,7 +1045,7 @@ def set_volume(self, volume: int, group_command: bool = False, max_volume: int =
                             # check volume range
                             if volume < 0 or volume > 100:
                                 return
                -                # donot raise error here polluting the log file
                +                # don ot raise error here polluting the log file
                                 # dpt3 handling can trigger negative values
                                 # raise Exception('Sonos: Volume has to be an integer between 0 and 100.')
                 
                @@ -1547,7 +1654,6 @@ def current_track(self) -> int:
                             return False
                         return sonos_speaker[self.coordinator].current_track
                 
                -
                     @current_track.setter
                     def current_track(self, current_track: int) -> None:
                         """
                @@ -1970,6 +2076,105 @@ def sonos_playlists(self) -> None:
                         for item in self.sonos_playlists_items:
                             item(p_l, 'Sonos')
                 
                +    def _play_snippet(self, file_path: str, webservice_url: str, volume: int = -1, fade_in=False) -> None:
                +        if not self._check_property():
                +            return
                +        if not self.is_coordinator:
                +            sonos_speaker[self.coordinator]._play_snippet(file_path, webservice_url, volume, fade_in)
                +        else:
                +            with self._snippet_queue_lock:
                +                snap = None
                +                volumes = {}
                +                # save all volumes from zone_member
                +                for member in self.zone_group_members:
                +                    volumes[member] = sonos_speaker[member].volume
                +
                +                tag = TinyTag.get(file_path)
                +                duration = int(round(tag.duration))
                +                self._logger.debug("Sonos: TTS track duration: {duration}s".format(duration=duration))
                +                file_name = quote(os.path.split(file_path)[1])
                +                snippet_url = "{url}/{file}".format(url=webservice_url, file=file_name)
                +
                +                # was GoogleTTS the last track? do not snapshot
                +                last_station = self.radio_station.lower()
                +                if last_station != "snippet":
                +                    snap = Snapshot(self.soco)
                +                    snap.snapshot()
                +
                +                time.sleep(0.5)
                +                self.set_stop()
                +                if volume == -1:
                +                    volume = self.volume
                +
                +                self.set_volume(volume, True)
                +                self.soco.play_uri(snippet_url, title="snippet")
                +                time.sleep(duration)
                +                self.set_stop()
                +
                +                # Restore the Sonos device back to it's previous state
                +                if last_station != "snippet":
                +                    if snap is not None:
                +                        snap.restore()
                +                else:
                +                    self.radio_station = ""
                +                for member in self.zone_group_members:
                +                    if member in volumes:
                +                        if fade_in:
                +                            vol_to_ramp = volumes[member]
                +                            sonos_speaker[member].soco.volume = 0
                +                            sonos_speaker[member].soco.renderingControl.RampToVolume(
                +                                [('InstanceID', 0), ('Channel', 'Master'),
                +                                 ('RampType', 'SLEEP_TIMER_RAMP_TYPE'),
                +                                 ('DesiredVolume', vol_to_ramp),
                +                                 ('ResetVolumeAfter', False), ('ProgramURI', '')])
                +                        else:
                +                            sonos_speaker[member].set_volume(volumes[member], group_command=False)
                +
                +    def play_snippet(self, audio_file, local_webservice_path: str, webservice_url: str, volume: int = -1, fade_in=False) \
                +            -> None:
                +        if not self._check_property():
                +            return
                +        if not self.is_coordinator:
                +            sonos_speaker[self.coordinator].play_tts(audio_file, local_webservice_path, webservice_url, volume, fade_in)
                +        else:
                +            if "tinytag" not in sys.modules:
                +                self._logger.error("Sonos: TinyTag module not installed. Please install the module with 'sudo pip3 "
                +                                   "install tinytag'.")
                +                return
                +            file_path = os.path.join(local_webservice_path, audio_file)
                +
                +            if not os.path.exists(file_path):
                +                self._logger.error("Sonos: Snippet file '{file_path}' does not exists.".format(file_path=file_path))
                +                return
                +            self._play_snippet(file_path, webservice_url, volume, fade_in)
                +
                +    def play_tts(self, tts: str, tts_language: str, local_webservice_path: str, webservice_url: str, volume: int = -1,
                +                 fade_in=False) -> None:
                +        if not self._check_property():
                +            return
                +        if not self.is_coordinator:
                +            sonos_speaker[self.coordinator].play_tts(tts, tts_language, local_webservice_path, webservice_url,
                +                                                     volume, fade_in)
                +        else:
                +            if "tinytag" not in sys.modules:
                +                self._logger.error("Sonos: TinyTag module not installed. Please install the module with 'sudo pip3 "
                +                                   "install tinytag'.")
                +                return
                +            file_path = get_tts_local_file_path(local_webservice_path, tts, tts_language)
                +
                +            # only do a tts call if file not exists
                +            if not os.path.exists(file_path):
                +                tts = gTTS(tts, self._logger, tts_language)
                +                try:
                +                    tts.save(file_path)
                +                except Exception as err:
                +                    self._logger.error("Sonos: Could not obtain TTS file from Google. Error: {ex}".format(ex=err))
                +                    return
                +            else:
                +                self._logger.debug("Sonos: File {file} already exists. No TTS request necessary.".format(
                +                    file=file_path))
                +            self._play_snippet(file_path, webservice_url, volume, fade_in)
                +
                     def load_sonos_playlist(self, name: str, start: bool = False, clear_queue: bool = False, track: int = 0) -> None:
                         """
                         Loads a Sonos playlist.
                @@ -2004,25 +2209,108 @@ def load_sonos_playlist(self, name: str, start: bool = False, clear_queue: bool
                                     except SoCoUPnPException as ex:
                                         self._logger.warning("Sonos: {ex}".format(ex=ex))
                                         return
                -                    #  bug here? no event, we have to trigger it manually
                +                    # bug here? no event, we have to trigger it manually
                                     if start:
                                         self.play = True
                             except Exception as ex:
                                 self._logger.warning("Sonos: No Sonos playlist found with title '{title}'.".format(title=name))
                 
                +
                 class Sonos(SmartPlugin):
                     ALLOW_MULTIINSTANCE = False
                -    PLUGIN_VERSION = "1.3.1.0"
                +    PLUGIN_VERSION = "1.4.2"
                 
                -    def __init__(self, sh, discover_cycle=120):
                +    def __init__(self, sh, tts=False, local_webservice_path=None, discover_cycle="120",
                +                 webservice_ip=None, webservice_port=23500, speaker_ips=None, **kwargs):
                +        super().__init__(**kwargs)
                         self._sh = sh
                         self._logger = logging.getLogger('sonos')  # get a unique logger for the plugin and provide it internally
                         self.zero_zone = False  # sometime a discovery scan fails, so try it two times; we need to save the state
                         self._sonos_dpt3_step = 2  # default value for dpt3 volume step (step(s) per time period)
                         self._sonos_dpt3_time = 1  # default value for dpt3 volume time (time period per step in seconds)
                +        self._tts = self.to_bool(tts, default=False)
                +        self._local_webservice_path = local_webservice_path
                +
                +        get_param_func = getattr(self, "get_parameter_value", None)
                +        if callable(get_param_func):
                +            speaker_ips = self.get_parameter_value("speaker_ips")
                +        else:
                +            speaker_ips = re.findall(r'[0-9]+(?:\.[0-9]+){3}', speaker_ips)
                +
                +        self._speaker_ips = []
                +        if speaker_ips:
                +            self._logger.debug("Sonos: User-defined speaker IPs set. Auto-discover disabled.")
                +        # check user specified sonos speaker ips
                +        for ip in speaker_ips:
                +            if self.is_ip(ip):
                +                self._speaker_ips.append(ip)
                +            else:
                +                self._logger.warning("Sonos: Invalid Sonos speaker ip '{ip}'. Ignoring.".format(ip=ip))
                +
                +        # unique items in list
                +        self._speaker_ips = utils.unique_list(self._speaker_ips)
                +        auto_ip = utils.get_local_ip_address()
                +
                +        if webservice_ip is not None:
                +            if self.is_ip(webservice_ip):
                +                self._webservice_ip = webservice_ip
                +            else:
                +                self._logger.error("Sonos: Your webservice_ip parameter is invalid. '{ip}' is not a vaild ip address. "
                +                                   "Disabling TTS.".format(ip=webservice_ip))
                +                self._tts = False
                +        else:
                +            self._webservice_ip = auto_ip
                +
                +        if utils.is_valid_port(str(webservice_port)):
                +            self._webservice_port = int(webservice_port)
                +            if not utils.is_open_port(self._webservice_port):
                +                self._logger.error("Sonos: Your chosen webservice port {port} is already in use. "
                +                                   "TTS disabled!".format(port=self._webservice_port))
                +                self._tts = False
                +        else:
                +            self._logger.error("Sonos: Your webservice_port parameter is invalid. '{port}' is not within port range "
                +                               "1024-65535. TTS disabled!".format(port=webservice_port))
                +            self._tts = False
                 
                         discover_cycle_default = 120
                 
                +        if self._tts:
                +            if self._local_webservice_path:
                +                # check access rights
                +                try:
                +                    os.makedirs(self._local_webservice_path, exist_ok=True)
                +                    if os.path.exists(self._local_webservice_path):
                +                        self._logger.debug("Sonos: Local webservice path set to '{path}'".format(
                +                            path=self._local_webservice_path))
                +                        if os.access(self._local_webservice_path, os.W_OK):
                +                            self._logger.debug("Sonos: Write permissions ok for tts on path {path}".format(
                +                                path=self._local_webservice_path))
                +
                +                            free_diskspace = get_free_diskspace(self._local_webservice_path)
                +                            human_readable_diskspace = file_size(free_diskspace)
                +                            self._logger.debug("Sonos: Free diskspace: {disk}".format(disk=human_readable_diskspace))
                +
                +                            self._webservice_url = "http://{ip}:{port}".format(ip=self._webservice_ip,
                +                                                                               port=self._webservice_port)
                +                            self._logger.debug("Sonos: Starting webservice for TTS on {url}".format(
                +                                url=self._webservice_url))
                +                            self.webservice = SimpleHttpServer(self._webservice_ip, self._webservice_port,
                +                                                               self._local_webservice_path)
                +                            self.webservice.start()
                +                        else:
                +                            self._logger.warning(
                +                                "Sonos: Local webservice path '{path}' is not writeable for current user. "
                +                                "TTS disabled!".format(path=self._local_webservice_path))
                +                    else:
                +                        self._logger.warning("Sonos: Local webservice path '{path}' for TTS not exists. "
                +                                             "TTS disabled!".format(path=self._local_webservice_path))
                +                except OSError:
                +                    self._logger.warning("Sonos: Could not create local webserver path '{path}'. Wrong permissions? "
                +                                         "TTS disabled!".format(path=self._local_webservice_path))
                +            else:
                +                self._logger.debug("Sonos: Local webservice path for TTS has to be set. TTS disabled!")
                +        else:
                +            self._logger.debug("Sonos: TTS disabled")
                         try:
                             self._discover_cycle = int(discover_cycle)
                         except:
                @@ -2031,7 +2319,7 @@ def __init__(self, sh, discover_cycle=120):
                             ))
                             self._discover_cycle = discover_cycle_default
                 
                -        self._logger.info("Sonos: setting discover cycle to {val} seconds.".format(val=self._discover_cycle))
                +        self._logger.info("Sonos: Setting discover cycle to {val} seconds.".format(val=self._discover_cycle))
                 
                     def run(self):
                         self._logger.debug("Sonos: run method called")
                @@ -2118,12 +2406,12 @@ def parse_item(self, item: Item) -> object:
                             if not self.has_iattr(item.conf, 'sonos_dpt3_step'):
                                 item.conf['sonos_dpt3_step'] = self._sonos_dpt3_step
                                 self._logger.debug("Sonos: No sonos_dpt3_step defined, using default value {step}.".
                -                                     format(step=self._sonos_dpt3_step))
                +                                   format(step=self._sonos_dpt3_step))
                 
                             if not self.has_iattr(item.conf, 'sonos_dpt3_time'):
                                 item.conf['sonos_dpt3_time'] = self._sonos_dpt3_time
                                 self._logger.debug("Sonos: no sonos_dpt3_time defined, using default value {time}.".
                -                                     format(time=self._sonos_dpt3_time))
                +                                   format(time=self._sonos_dpt3_time))
                 
                             return self._handle_dpt3
                 
                @@ -2152,7 +2440,7 @@ def _handle_dpt3(self, item, caller=None, source=None, dest=None):
                                     volume_helper.fade(vol_max, vol_step, vol_time)
                                 else:
                                     # down
                -                    volume_helper.fade(0-vol_step, vol_step, vol_time)
                +                    volume_helper.fade(0 - vol_step, vol_step, vol_time)
                             else:
                                 volume_helper(int(volume_helper() + 1))
                                 volume_helper(int(volume_helper() - 1))
                @@ -2246,10 +2534,40 @@ def update_item(self, item: Item, caller: object = str, source: object = str, de
                                     clear_queue = self._resolve_child_command_bool(item, 'clear_queue')
                                     track = self._resolve_child_command_int(item, 'start_track')
                                     sonos_speaker[uid].load_sonos_playlist(item(), start, clear_queue, track)
                +                if command == 'play_tts':
                +                    if item() == "":
                +                        return
                +                    language = self._resolve_child_command_str(item, 'tts_language', 'de')
                +                    volume = self._resolve_child_command_int(item, 'tts_volume', -1)
                +                    fade_in = self._resolve_child_command_bool(item, 'tts_fade_in')
                +                    sonos_speaker[uid].play_tts(item(), language, self._local_webservice_path, self._webservice_url,
                +                                                volume, fade_in)
                +                if command == 'play_snippet':
                +                    if item() == "":
                +                        return
                +                    volume = self._resolve_child_command_int(item, 'snippet_volume', -1)
                +                    fade_in = self._resolve_child_command_bool(item, 'snippet_fade_in')
                +                    sonos_speaker[uid].play_snippet(item(), self._local_webservice_path, self._webservice_url, volume,
                +                                                    fade_in)
                +
                +    def _resolve_child_command_str(self, item: Item, child_command, default_value="") -> str:
                +        """
                +        Resolves a child command of type str for an item
                +        :type child_command: The sonos_attrib name for the child
                +        :type default_value: the default value, if the child not exists or an error occurred
                +        :param item: The item for which a child item is to be searched
                +        :rtype: str
                +        :return: String value of the child item or the given default value.
                +        """
                +        for child in item.return_children():
                +            if self.has_iattr(child.conf, 'sonos_attrib'):
                +                if self.get_iattr_value(child.conf, 'sonos_attrib') == child_command:
                +                    return child()
                +        return default_value
                 
                     def _resolve_child_command_bool(self, item: Item, child_command) -> bool:
                         """
                -        Resolves a child command for an item
                +        Resolves a child command of type bool for an item
                         :type child_command: The sonos_attrib name for the child
                         :param item: The item for which a child item is to be searched
                         :rtype: bool
                @@ -2261,23 +2579,24 @@ def _resolve_child_command_bool(self, item: Item, child_command) -> bool:
                                     return child()
                         return False
                 
                -    def _resolve_child_command_int(self, item: Item, child_command) -> int:
                +    def _resolve_child_command_int(self, item: Item, child_command, default_value=0) -> int:
                         """
                -        Resolves a child command for an item
                +        Resolves a child command of type int for an item
                +        :type default_value: the default value, if the child not exists or an error occurred
                         :type child_command: The sonos_attrib name for the child
                         :param item: The item for which a child item is to be searched
                         :rtype: int
                -        :return: value as int
                +        :return: value as int or if no item was found the given default value
                         """
                         try:
                             for child in item.return_children():
                                 if self.has_iattr(child.conf, 'sonos_attrib'):
                                     if self.get_iattr_value(child.conf, 'sonos_attrib') == child_command:
                                         return int(child())
                -            return 0
                +            return default_value
                         except:
                             self._logger.warning("Sonos: Could not cast value [{val}] to 'int', using default value '0'")
                -            return 0
                +            return default_value
                 
                     def _resolve_group_command(self, item: Item) -> bool:
                         """
                @@ -2339,11 +2658,18 @@ def _resolve_uid(self, item: Item) -> str:
                 
                     def _discover(self) -> None:
                         """
                -        Discover Sonos speaker in the network
                +        Discover Sonos speaker in the network. If the plugin parameter 'speaker_ips' no discover package is sent over
                +        the network.
                         :rtype: None
                         """
                         handled_speaker = {}
                -        zones = soco.discover(timeout=5)
                +
                +        zones = []
                +        if self._speaker_ips:
                +            for ip in self._speaker_ips:
                +                zones.append(SoCo(ip))
                +        else:
                +            zones = soco.discover(timeout=5)
                 
                         # 1. attempt: don't touch our speaker, return and wait for next interval
                         # 2. attempt: ok, no speaker found, go on
                @@ -2356,19 +2682,21 @@ def _discover(self) -> None:
                         self.zero_zone = False
                 
                         for zone in zones:
                -            uid = zone.uid.lower()
                -
                -            # don't trust the discover function, offline speakers can be cached
                -            # we try to ping the speaker
                -            with open(os.devnull, 'w') as DEVNULL:
                -                try:
                -                    subprocess.check_call(['ping', '-i', '0.2', '-c', '2', zone.ip_address],
                -                                          stdout=DEVNULL, stderr=DEVNULL, timeout=1)
                -                    is_up = True
                -                except subprocess.CalledProcessError:
                -                    is_up = False
                -                except subprocess.TimeoutExpired:
                -                    is_up = False
                +            if zone.uid is None:
                +                is_up = False
                +            else:
                +                uid = zone.uid.lower()
                +                # don't trust the discover function, offline speakers can be cached
                +                # we try to ping the speaker
                +                with open(os.devnull, 'w') as DEVNULL:
                +                    try:
                +                        subprocess.check_call(['ping', '-i', '0.2', '-c', '2', zone.ip_address],
                +                                              stdout=DEVNULL, stderr=DEVNULL, timeout=1)
                +                        is_up = True
                +                    except subprocess.CalledProcessError:
                +                        is_up = False
                +                    except subprocess.TimeoutExpired:
                +                        is_up = False
                 
                             if is_up:
                                 self._logger.debug("Sonos: Speaker found: {zone}, {uid}".format(zone=zone.ip_address, uid=uid))
                diff --git a/sonos/examples/sonos.yaml b/sonos/examples/sonos.yaml
                index 675b24301..858bdf182 100644
                --- a/sonos/examples/sonos.yaml
                +++ b/sonos/examples/sonos.yaml
                @@ -272,3 +272,34 @@ MySonos:
                       type: str
                       sonos_recv: uid
                 
                +    play_tts:
                +      type: str
                +      sonos_send: play_tts
                +      enforce_updates: True
                +
                +      tts_language:
                +        type: str
                +        sonos_attrib: tts_language
                +
                +      tts_volume:
                +        type: num
                +        sonos_attrib: tts_volume
                +
                +      tts_fade_in:
                +        type: bool
                +        sonos_attrib: tts_fade_in
                +
                +    play_snippet:
                +      type: str
                +      sonos_send: play_snippet
                +      enforce_updates: True
                +
                +      snippet_volume:
                +        type: num
                +        value: 25
                +        sonos_attrib: snippet_volume
                +
                +      snippet_fade_in:
                +        type: bool
                +        value: True
                +        sonos_attrib: snippet_fade_in
                \ No newline at end of file
                diff --git a/sonos/plugin.yaml b/sonos/plugin.yaml
                new file mode 100755
                index 000000000..233887ef5
                --- /dev/null
                +++ b/sonos/plugin.yaml
                @@ -0,0 +1,60 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +  # Global plugin attributes
                +  type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +  description:                  # Alternative: description in multiple languages
                +      de: 'Anbindung von Sonos Lautsprechern'
                +      en: ''
                +  maintainer: pfischi
                +  tester: pfischi
                +  keywords: Sonos sonos multimedia
                +  documentation: https://knx-user-forum.de/forum/supportforen/smarthome-py/35587-immer-aktuell-sonos-broker-und-sonos-plugin-howto        # url of documentation (wiki) page
                +  support: https://knx-user-forum.de/forum/supportforen/smarthome-py/25151-sonos-anbindung
                +
                +  version: 1.4.2                 # Plugin version
                +  sh_minversion: 1.3             # minimum shNG version to use this plugin
                +  multi_instance: False          # plugin supports multi instance
                +  classname: Sonos               # class containing the plugin
                +
                +parameters:
                +  tts:
                +    type: bool
                +    default: False
                +    description:
                +      de: "(optiona) Aktiviert die Google TTS Funktionalität."
                +      en: "(optional) Enables the Google TTS functionality"
                +
                +  local_webservice_path:
                +    type: str
                +    description:
                +      de: "(optional) In dieses Verzeichnis werden alle TTS-Dateien automatisch gespeichert. Is die Option 'tts' aktiviert, dann muss diese Option gesetzt sein."
                +      en: "(optional) All tts files will be stored here automatically. If 'tts' is enabled, this option is mandatory."
                +
                +  webservice_ip:
                +    type: str
                +    description:
                +      de: "(optional) Für TTS und die Audio-Snippet-Funktionalität wird ein simpler Webservice gestartet. Die IP-Adresse wird per default automatisch ermittelt, kann hier aber manuell gesetzt werden."
                +      en: "(optional) FOr the TTS and audio snippet functionality, a simple webservice is started. By default the IP is detected automatically and can be manually overridden here."
                +
                +  webservice_port:
                +    type: int
                +    default: 23500
                +    description:
                +      de: "(optional) Webservice-Port"
                +      en: "(optional) Webservice port"
                +
                +  speaker_ips:
                +    type: list
                +    description:
                +      de: "(optional) Die IPs der Lautsprecher können manuell gesetzt werden. Dies kann in einer Container-Umgebung (z.B Docker) mit eingeschränkten Netzwerkzugriff sinnvoll sein."
                +      en: "(optional) You can set static IP addresses for your Sonos speaker. This will disable auto-discovery. This is useful if you're using a containerized environment with restricted network access."
                +
                +  discover_cycle:
                +      type: int
                +      description:
                +        de: "Zeitintervall, in dem (erneut) nach (neuen) Lautsprechern im Netzwerk gesucht wird."
                +        en: "Time interval in which (again) searches are made for (new) speakers in the network."
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sonos/requirements.txt b/sonos/requirements.txt
                index c9da4d217..f7357a07e 100644
                --- a/sonos/requirements.txt
                +++ b/sonos/requirements.txt
                @@ -1,3 +1,4 @@
                 requests>=2.9.1;python_version>'3.2'
                 requests==2.5.1;python_version=='3.2'
                 xmltodict>=0.11.0
                +tinytag>=0.18.0
                diff --git a/sonos/tts.py b/sonos/tts.py
                new file mode 100644
                index 000000000..b5c1afc16
                --- /dev/null
                +++ b/sonos/tts.py
                @@ -0,0 +1,246 @@
                +# -*- coding: utf-8 -*-
                +import calendar
                +import math
                +import time
                +import requests
                +import re
                +
                +class Token:
                +    """ Token (Google Translate Token)
                +    Generate the current token key and allows generation of tokens (tk) with it
                +    Python version of `token-script.js` itself from translate.google.com
                +    """
                +
                +    SALT_1 = "+-a^+6"
                +    SALT_2 = "+-3^+b+-f"
                +
                +    def __init__(self):
                +        self.token_key = None
                +
                +    def calculate_token(self, text, seed=None):
                +        """ Calculate the request token (`tk`) of a string
                +        :param text: str The text to calculate a token for
                +        :param seed: str The seed to use. By default this is the number of hours since epoch
                +        """
                +
                +        if seed is None:
                +            seed = self._get_token_key()
                +
                +        [first_seed, second_seed] = seed.split(".")
                +
                +        try:
                +            d = bytearray(text.encode('UTF-8'))
                +        except UnicodeDecodeError:
                +            # This will probably only occur when d is actually a str containing UTF-8 chars, which means we don't need
                +            # to encode.
                +            d = bytearray(text)
                +
                +        a = int(first_seed)
                +        for value in d:
                +            a += value
                +            a = self._work_token(a, self.SALT_1)
                +        a = self._work_token(a, self.SALT_2)
                +        a ^= int(second_seed)
                +        if 0 > a:
                +            a = (a & 2147483647) + 2147483648
                +        a %= 1E6
                +        a = int(a)
                +        return str(a) + "." + str(a ^ int(first_seed))
                +
                +    def _get_token_key(self):
                +        if self.token_key is not None:
                +            return self.token_key
                +
                +        timestamp = calendar.timegm(time.gmtime())
                +        hours = int(math.floor(timestamp / 3600))
                +
                +        response = requests.get("https://translate.google.com/")
                +        line = response.text.split('\n')[-1]
                +
                +        tkk_expr = re.search(".*?(TKK=.*?;)W.*?", line).group(1)
                +        a = re.search("a\\\\x3d(-?\d+);", tkk_expr).group(1)
                +        b = re.search("b\\\\x3d(-?\d+);", tkk_expr).group(1)
                +
                +        result = str(hours) + "." + str(int(a) + int(b))
                +        self.token_key = result
                +        return result
                +
                +    """ Functions used by the token calculation algorithm """
                +
                +    def _rshift(self, val, n):
                +        return val >> n if val >= 0 else (val + 0x100000000) >> n
                +
                +    def _work_token(self, a, seed):
                +        for i in range(0, len(seed) - 2, 3):
                +            char = seed[i + 2]
                +            d = ord(char[0]) - 87 if char >= "a" else int(char)
                +            d = self._rshift(a, d) if seed[i + 1] == "+" else a << d
                +            a = a + d & 4294967295 if seed[i] == "+" else a ^ d
                +        return a
                +
                +
                +class gTTS:
                +    """ gTTS (Google Text to Speech): an interface to Google's Text to Speech API """
                +
                +    GOOGLE_TTS_URL = 'https://translate.google.com/translate_tts'
                +    MAX_CHARS = 100  # Max characters the Google TTS API takes at a time
                +    LANGUAGES = {
                +        'af': 'Afrikaans',
                +        'sq': 'Albanian',
                +        'ar': 'Arabic',
                +        'hy': 'Armenian',
                +        'ca': 'Catalan',
                +        'zh': 'Chinese',
                +        'zh-cn': 'Chinese (Mandarin/China)',
                +        'zh-tw': 'Chinese (Mandarin/Taiwan)',
                +        'zh-yue': 'Chinese (Cantonese)',
                +        'hr': 'Croatian',
                +        'cs': 'Czech',
                +        'da': 'Danish',
                +        'nl': 'Dutch',
                +        'en': 'English',
                +        'en-au': 'English (Australia)',
                +        'en-uk': 'English (United Kingdom)',
                +        'en-us': 'English (United States)',
                +        'eo': 'Esperanto',
                +        'fi': 'Finnish',
                +        'fr': 'French',
                +        'de': 'German',
                +        'el': 'Greek',
                +        'ht': 'Haitian Creole',
                +        'hi': 'Hindi',
                +        'hu': 'Hungarian',
                +        'is': 'Icelandic',
                +        'id': 'Indonesian',
                +        'it': 'Italian',
                +        'ja': 'Japanese',
                +        'ko': 'Korean',
                +        'la': 'Latin',
                +        'lv': 'Latvian',
                +        'mk': 'Macedonian',
                +        'no': 'Norwegian',
                +        'pl': 'Polish',
                +        'pt': 'Portuguese',
                +        'pt-br': 'Portuguese (Brazil)',
                +        'ro': 'Romanian',
                +        'ru': 'Russian',
                +        'sr': 'Serbian',
                +        'sk': 'Slovak',
                +        'es': 'Spanish',
                +        'es-es': 'Spanish (Spain)',
                +        'es-us': 'Spanish (United States)',
                +        'sw': 'Swahili',
                +        'sv': 'Swedish',
                +        'ta': 'Tamil',
                +        'th': 'Thai',
                +        'tr': 'Turkish',
                +        'vi': 'Vietnamese',
                +        'cy': 'Welsh'
                +    }
                +
                +    def __init__(self, text, logger, lang='en'):
                +
                +        self._logger = logger
                +        if lang.lower() not in self.LANGUAGES:
                +            raise Exception('Language not supported: %s' % lang)
                +        else:
                +            self.lang = lang.lower()
                +
                +        if not text:
                +            raise Exception('No text to speak')
                +        else:
                +            self.text = text
                +
                +        # Split text in parts
                +        if len(text) <= self.MAX_CHARS:
                +            text_parts = [text]
                +        else:
                +            text_parts = self._tokenize(text, self.MAX_CHARS)
                +
                +            # Clean
                +
                +        def strip(x):
                +            return x.replace('\n', '').strip()
                +
                +        text_parts = [strip(x) for x in text_parts]
                +        text_parts = [x for x in text_parts if len(x) > 0]
                +        self.text_parts = text_parts
                +
                +        # Google Translate token
                +        self.token = Token()
                +
                +    def save(self, savefile):
                +        """ Do the Web request and save to `savefile` """
                +        with open(savefile, 'wb') as f:
                +            self._write_to_fp(f)
                +            f.close()
                +
                +    def stream_url(self):
                +        req = self._prepare_request()
                +        params = req.params
                +        prep_req = req.prepare()
                +        prep_req.prepare_url(req.url, params)
                +        return prep_req.url
                +
                +    def _prepare_request(self):
                +        """ Do the Web request and save to a file-like object """
                +        for idx, part in enumerate(self.text_parts):
                +            payload = {'ie': 'UTF-8',
                +                       'q': part,
                +                       'tl': self.lang,
                +                       'total': len(self.text_parts),
                +                       'idx': idx,
                +                       'client': 'tw-ob',
                +                       'textlen': len(part),
                +                       'tk': self.token.calculate_token(part)}
                +            headers = {
                +                "Referer": "http://translate.google.com/",
                +                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
                +                              "Chrome/47.0.2526.106 Safari/537.36"
                +            }
                +
                +            self._logger.debug("Sonos: GoogleTTS: headers parameter: {param}".format(param=headers))
                +            self._logger.debug("Sonos: GoogleTTS: request parameter: {param}".format(param=payload))
                +            return requests.Request(method='GET', url=self.GOOGLE_TTS_URL, headers=headers, params=payload)
                +
                +    def _write_to_fp(self, fp):
                +        try:
                +            prepared_request = self._prepare_request().prepare()
                +            s = requests.Session()
                +            r = s.send(prepared_request)
                +            self._logger.debug("Sonos: GoogleTTS: Headers: {}".format(r.request.headers))
                +            self._logger.debug("Sonos: GoogleTTS: Reponse: {}, Redirects: {}".format(r.status_code, r.history))
                +
                +            r.raise_for_status()
                +            for chunk in r.iter_content(chunk_size=1024):
                +                fp.write(chunk)
                +        except Exception as err:
                +            self._logger.error("Sonos: {err}".format(err=err))
                +            raise err
                +
                +    def _tokenize(self, text, max_size):
                +        """ Tokenizer on basic roman punctuation """
                +
                +        punc = "¡!()[]¿?.,;:—«»\n"
                +        punc_list = [re.escape(c) for c in punc]
                +        pattern = '|'.join(punc_list)
                +        parts = re.split(pattern, text)
                +
                +        min_parts = []
                +        for p in parts:
                +            min_parts += self._minimize(p, " ", max_size)
                +        return min_parts
                +
                +    def _minimize(self, thestring, delim, max_size):
                +        """ Recursive function that splits `thestring` in chunks
                +        of maximum `max_size` chars delimited by `delim`. Returns list. """
                +
                +        if len(thestring) > max_size:
                +            idx = thestring.rfind(delim, 0, max_size)
                +            return [thestring[:idx]] + self._minimize(thestring[idx:], delim, max_size)
                +        else:
                +            return [thestring]
                +
                +
                +if __name__ == "__main__":
                +    pass
                diff --git a/sonos/utils.py b/sonos/utils.py
                new file mode 100644
                index 000000000..1fc3d83ca
                --- /dev/null
                +++ b/sonos/utils.py
                @@ -0,0 +1,77 @@
                +import hashlib
                +import os
                +import socket
                +import re
                +from collections import Set
                +
                +
                +def is_valid_port(port):
                +    valid_port = re.compile(
                +        "^(102[4-9]|10[3-9]\d|1[1-9]\d{2}|[2-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$")
                +    if valid_port.match(port):
                +        return True
                +    return False
                +
                +
                +def unique_list(seq, idfun=None):
                +    # order preserving
                +    if idfun is None:
                +        def idfun(x): return x
                +    seen = {}
                +    result = []
                +    for item in seq:
                +        marker = idfun(item)
                +        # in old Python versions:
                +        # if seen.has_key(marker)
                +        # but in new ones:
                +        if marker in seen: continue
                +        seen[marker] = 1
                +        result.append(item)
                +    return result
                +
                +
                +def is_open_port(port):
                +    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                +    try:
                +        s.bind(("127.0.0.1", port))
                +    except socket.error:
                +        return False
                +    return True
                +
                +def get_local_ip_address():
                +    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                +    s.connect(("10.10.10.10", 80))
                +    return s.getsockname()[0]
                +
                +
                +def file_size(size):
                +    _suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
                +    # determine binary order in steps of size 10
                +    # (coerce to int, // still returns a float)
                +    from math import log2
                +    order = int(log2(size) / 10) if size else 0
                +    # format file size
                +    # (.4g results in rounded numbers for exact matches and max 3 decimals,
                +    # should never resort to exponent values)
                +    return '{:.4g} {}'.format(size / (1 << (order * 10)), _suffixes[order])
                +
                +
                +def get_free_diskspace(folder):
                +    statvfs = os.statvfs(folder)
                +    return statvfs.f_frsize * statvfs.f_bfree
                +
                +
                +def get_folder_size(folder):
                +    total_size = 0
                +    for dir_path, dir_names, file_names in os.walk(folder):
                +        for f in file_names:
                +            fp = os.path.join(dir_path, f)
                +            total_size += os.path.getsize(fp)
                +    return total_size
                +
                +
                +def get_tts_local_file_path(local_directory, tts_string, tts_language):
                +    m = hashlib.md5()
                +    m.update('{}_{}'.format(tts_language, tts_string).encode('utf-8'))
                +    file_name = '{}.mp3'.format(m.hexdigest())
                +    return os.path.join(local_directory, file_name)
                diff --git a/speech/README.md b/speech/README.md
                index 87d9e326a..31a8e229f 100644
                --- a/speech/README.md
                +++ b/speech/README.md
                @@ -1,4 +1,4 @@
                -# Speech_Parser
                +# Speech Parser
                 
                 ## Requirements
                 
                diff --git a/speech/plugin.yaml b/speech/plugin.yaml
                new file mode 100755
                index 000000000..7148754f9
                --- /dev/null
                +++ b/speech/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Sprach Parser'
                +        en: ''
                +    maintainer: '?'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Speech_Parser       # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sqlite/README.md b/sqlite/README.md
                index 384cf9479..0c09654e2 100644
                --- a/sqlite/README.md
                +++ b/sqlite/README.md
                @@ -1,4 +1,4 @@
                -# SQLite (für SmartVisu < 2.8)
                +# SQLite (for SmartVisu < 2.8)
                 
                 ## Configuration
                 
                diff --git a/sqlite/__init__.py b/sqlite/__init__.py
                index 923190ae4..5f32f4e85 100755
                --- a/sqlite/__init__.py
                +++ b/sqlite/__init__.py
                @@ -107,8 +107,10 @@ def __init__(self, smarthome, cycle=300, path=None):
                         year = 365 * day
                         self._frames = {'i': minute, 'h': hour, 'd': day, 'w': week, 'm': month, 'y': year}
                         self._times = {'i': minute, 'h': hour, 'd': day, 'w': week, 'm': month, 'y': year}
                -        smarthome.scheduler.add('SQLite pack', self._pack, cron='2 3 * *', prio=5)
                -        smarthome.scheduler.add('SQLite dump', self._dump, cycle=self._dump_cycle, offset=20, prio=5)
                +#        smarthome.scheduler.add('SQLite pack', self._pack, cron='2 3 * *', prio=5)
                +#        smarthome.scheduler.add('SQLite dump', self._dump, cycle=self._dump_cycle, offset=20, prio=5)
                +        self.scheduler_add('SQLite pack', self._pack, cron='2 3 * *', prio=5)
                +        self.scheduler_add('SQLite dump', self._dump, cycle=self._dump_cycle, offset=20, prio=5)
                 
                     def parse_item(self, item):
                         if 'history' in item.conf:  # XXX legacy history option remove sometime
                diff --git a/sqlite/plugin.yaml b/sqlite/plugin.yaml
                new file mode 100755
                index 000000000..cfe4581fb
                --- /dev/null
                +++ b/sqlite/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Integration einer SQLite Datenbank - kompatibel mit smartVISU 2.7'
                +        en: ''
                +    maintainer: '?'
                +#    tester:                        # Who tests this plugin?
                +    keywords: database
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.1.2               # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SQL                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/sqlite_visu2_8/README.md b/sqlite_visu2_8/README.md
                index e5ff76df9..b602ca63e 100644
                --- a/sqlite_visu2_8/README.md
                +++ b/sqlite_visu2_8/README.md
                @@ -1,4 +1,4 @@
                -# SQLite (für SmartVisu >= 2.8)
                +# SQLite (for SmartVisu >= 2.8)
                 
                 ## Configuration
                 
                diff --git a/sqlite_visu2_8/__init__.py b/sqlite_visu2_8/__init__.py
                index 5c5f007a3..15c4a66af 100755
                --- a/sqlite_visu2_8/__init__.py
                +++ b/sqlite_visu2_8/__init__.py
                @@ -104,7 +104,8 @@ def __init__(self, smarthome, cycle=300, path=None, dumpfile=False):
                         year = 365 * day
                         self._frames = {'i': minute, 'h': hour, 'd': day, 'w': week, 'm': month, 'y': year}
                         self._times = {'i': minute, 'h': hour, 'd': day, 'w': week, 'm': month, 'y': year}
                -        smarthome.scheduler.add('SQLite Maintain', self._maintain, cron='2 3 * *', prio=5)
                +#        smarthome.scheduler.add('SQLite Maintain', self._maintain, cron='2 3 * *', prio=5)
                +        self.scheduler_add('SQLite Maintain', self._maintain, cron='2 3 * *', prio=5)
                 
                     def remove_orphans(self):
                         current_items = [item.id() for item in self._buffer]
                diff --git a/sqlite_visu2_8/plugin.yaml b/sqlite_visu2_8/plugin.yaml
                new file mode 100755
                index 000000000..183b21923
                --- /dev/null
                +++ b/sqlite_visu2_8/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Integration einer SQLite Datenbank - zu verwenden für smartVISU 2.8'
                +        en: ''
                +    maintainer: '?'
                +#    tester:                        # Who tests this plugin?
                +    keywords: database
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SQL                 # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/squeezebox/plugin.yaml b/squeezebox/plugin.yaml
                new file mode 100755
                index 000000000..048d69e0f
                --- /dev/null
                +++ b/squeezebox/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Anbindung von Squeezebox Devices. Eine laufender Logitech Media Server wird benötigt.'
                +        en: ''
                +    maintainer: Robert
                +    tester: onkelandy, Sandman60, cmalo, brandst
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/28692-√-neues-plugin-logitech-squeezebox-anregungen
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Squeezebox          # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/systemair/plugin.yaml b/systemair/plugin.yaml
                new file mode 100755
                index 000000000..f90f1db20
                --- /dev/null
                +++ b/systemair/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für Systemair residential air units über Modbus.'
                +        en: ''
                +    maintainer: pfischi
                +#    tester:                        # Who tests this plugin?
                +    keywords: modbus
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/939623-systemair-modbus-plugin-zentrale-lüftungsanlage
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Systemair           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/systemair/requirements.txt b/systemair/requirements.txt
                index a7f9d3b32..52f1a8b6f 100644
                --- a/systemair/requirements.txt
                +++ b/systemair/requirements.txt
                @@ -1,2 +1,2 @@
                 minimalmodbus>=0.7
                -pyserial>=3.0.1
                +pyserial>=3.2.1
                diff --git a/tankerkoenig/plugin.yaml b/tankerkoenig/plugin.yaml
                new file mode 100755
                index 000000000..5294a3f18
                --- /dev/null
                +++ b/tankerkoenig/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Benzinpreise'
                +        en: ''
                +    maintainer: psilo909
                +    tester: Sandman60
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/tankerkoenig        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/938924-benzinpreis-plugin
                +
                +    version: 1.1.1                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: TankerKoenig        # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/telegram/plugin.yaml b/telegram/plugin.yaml
                new file mode 100755
                index 000000000..1bd84913d
                --- /dev/null
                +++ b/telegram/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung des Telegram Service'
                +        en: ''
                +    maintainer: gamade
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.1.3                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Telegram            # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/tellstick/__init.py__ b/tellstick/__init__.py
                similarity index 100%
                rename from tellstick/__init.py__
                rename to tellstick/__init__.py
                diff --git a/tellstick/plugin.yaml b/tellstick/plugin.yaml
                new file mode 100755
                index 000000000..e8110eda4
                --- /dev/null
                +++ b/tellstick/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: gateway                    # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung für TellStick und TellStick Duo RF Transmitter'
                +        en: ''
                +    maintainer: '? (Matthieu Gaigniere)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Tellstick           # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/traffic/plugin.yaml b/traffic/plugin.yaml
                new file mode 100755
                index 000000000..3bb6955ef
                --- /dev/null
                +++ b/traffic/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Abfrage der Reisezeit über die Google Directions API'
                +        en: ''
                +    maintainer: psilo909
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Traffic             # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/uzsu/plugin.yaml b/uzsu/plugin.yaml
                new file mode 100755
                index 000000000..00a946cfd
                --- /dev/null
                +++ b/uzsu/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Universelle Zeitschaltuhr'
                +        en: 'Universal time switch'
                +    maintainer: cmalo (Niko Will)
                +    tester: Sandman60, cmalo
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/UZSU-%28Universelle-Zeitschaltuhr%29        # url of documentation (wiki) page
                +
                +    version: 1.3.0                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: UZSU                # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/visu_smartvisu/README.md b/visu_smartvisu/README.md
                old mode 100644
                new mode 100755
                index 0cdfb2d27..efbd56cc1
                --- a/visu_smartvisu/README.md
                +++ b/visu_smartvisu/README.md
                @@ -1,4 +1,4 @@
                -# Visualisation plugin (smartVISU support)
                +# Visualisation (smartVISU support)
                 
                 ```
                 Copyright 2016- Martin Sinn                      m.sinn@gmx.de
                @@ -43,8 +43,8 @@ The configuration of the plugin itself is done in the file **`etc/plugin.conf`**
                 smartvisu:
                     class_name: SmartVisu
                     class_path: plugins.visu_smartvisu
                -    # smartvisu_dir = False
                -    # handle_widgets = True
                +    # smartvisu_dir: False
                +    # handle_widgets: True
                 ```
                 
                 #### visu_dir
                @@ -83,13 +83,13 @@ Valid values are:
                 |  **room**         |  The page appears in the room view of smartVISU         	  |  
                 | **seperator**     | Inserts a seperator between entries in the room navigation  |
                 | **overview**      | The page groups of different items together                 |  
                -
                +|                   |                                                             |
                 |  **category**     | The page appears in the category view of smartVISU          |  
                 | **cat_seperator** | Inserts a seperator between entries in the category         |  
                 |                   | navigation                                                  |
                 | **cat_overview**  | The page groups of different items together and is added    |
                 |	                | to the category navigation                                  |  
                -
                +|                   |                                                             |
                 |  **room_lite**    |  The page appears in a lite view of the visualization       |  
                 [values for **`sv_page`**]
                 
                @@ -281,4 +281,4 @@ You could specify the **`visu_acl`** attribute to every logic in your logic.conf
                 dialog:
                     filename: dialog.py
                     visu_acl: 'true'
                -```
                \ No newline at end of file
                +```
                diff --git a/visu_smartvisu/__init__.py b/visu_smartvisu/__init__.py
                index 548cdd707..afe5470b1 100755
                --- a/visu_smartvisu/__init__.py
                +++ b/visu_smartvisu/__init__.py
                @@ -40,8 +40,8 @@
                 #########################################################################
                 
                 class SmartVisu(SmartPlugin):
                -    PLUGIN_VERSION="1.3.2"
                -    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION="1.3.4"
                +    ALLOW_MULTIINSTANCE = True
                 
                 
                     def my_to_bool(self, value, attr='', default=False):
                @@ -67,19 +67,34 @@ def __init__(self, smarthome, smartvisu_dir='', generate_pages='True', overwrite
                             self.logger.error("smartVISU: Invalid value '"+str(visu_style)+"' configured for attribute visu_style in plugin.conf, using '"+str(self.visu_style)+"' instead")
                         self._handle_widgets = self.my_to_bool(handle_widgets, "handle_widgets", False)
                 
                +        self.smartvisu_version = self.get_smartvisu_version()
                +        if self.smartvisu_version == '':
                +            self.logger.error("Could not determine smartVISU version!")
                +#        else:
                +#            self.logger.log(logging.WARNING, "Handling for smartVISU v{} in directory {}".format(self.smartvisu_version, self.smartvisu_dir))
                +
                 
                     def run(self):
                         self.alive = True
                         if self.smartvisu_dir != '':
                -            if not os.path.isdir(self.smartvisu_dir + '/pages'):
                -                self.logger.error("Could not find valid smartVISU directory: {0}".format(self.smartvisu_dir))
                +            if not os.path.isdir(os.path.join(self.smartvisu_dir, 'pages')):
                +                self.logger.error("Could not find valid smartVISU directory: {}".format(self.smartvisu_dir))
                             else:
                -#                self.logger.warning("Starting smartVISU handling")
                +                self.logger.info("Starting smartVISU v{} handling".format(self.smartvisu_version))
                                 if self._handle_widgets:
                -                    sv_iwdg = SmartVisuInstallWidgets(self._sh, self.smartvisu_dir)
                +#                    self.logger.info("Widgets smartVISU v{} handling".format(self.smartvisu_version))
                +                    try:
                +                        sv_iwdg = SmartVisuInstallWidgets(self._sh, self.smartvisu_dir, self.smartvisu_version)
                +                    except Exception as e:
                +                        self.logger.exception("SmartVisuInstallWidgets v{}: Exception: {}".format(self.get_smartvisu_version(), e))
                +
                                 if self._generate_pages:
                -                    svgen = SmartVisuGenerator(self._sh, self.smartvisu_dir, self.overwrite_templates, self.visu_style)
                -#                self.logger.warning("Finished smartVISU handling")
                +#                    self.logger.info("Pages smartVISU v{} handling".format(self.smartvisu_version))
                +                    try:
                +                        svgen = SmartVisuGenerator(self._sh, self.smartvisu_dir, self.overwrite_templates, self.visu_style, self.smartvisu_version)
                +                    except Exception as e:
                +                        self.logger.exception("SmartVisuGenerator: Exception: {}".format(e))
                +                self.logger.info("Finished smartVISU v{} handling".format(self.smartvisu_version))
                 
                 
                     def stop(self):
                @@ -102,6 +117,26 @@ def update_item(self, item, caller=None, source=None, dest=None):
                         pass
                 
                 
                +    def get_smartvisu_version(self):
                +        """
                +        Determine which smartVISU version is installed in 'smartvisu_dir'
                +        
                +        :return: version
                +        :rtype: str
                +        """
                +        if os.path.isdir(os.path.join(self.smartvisu_dir, 'dropins')):
                +            return '2.9'
                +        if os.path.isfile(os.path.join(self.smartvisu_dir, 'version-info.php')):
                +            content = ''
                +            with open(os.path.join(self.smartvisu_dir, 'version-info.php'), 'r') as content_file:
                +                content = content_file.read()
                +            if content.find('2.8') > -1:
                +                return '2.8'
                +        if os.path.isdir(os.path.join(self.smartvisu_dir, 'pages')):
                +            return '2.7'
                +        return ''
                +        
                +
                 #########################################################################
                 #       Visu page generator
                 #########################################################################
                @@ -109,26 +144,30 @@ def update_item(self, item, caller=None, source=None, dest=None):
                 
                 class SmartVisuGenerator:
                 
                -    def __init__(self, smarthome, smartvisu_dir='', overwrite_templates='Yes', visu_style='std'):
                +    def __init__(self, smarthome, smartvisu_dir='', overwrite_templates='Yes', visu_style='std', smartvisu_version=''):
                         self.logger = logging.getLogger(__name__)
                         self._sh = smarthome
                         self.smartvisu_dir = smartvisu_dir
                +        self.smartvisu_version = smartvisu_version
                         self.overwrite_templates = overwrite_templates
                         self.visu_style = visu_style.lower()
                         if not self.visu_style in ['std','blk']:
                             self.visu_style = 'std'
                -            self.logger.warning("SmartVisuGenerator: visu_style '{0}' unknown, using visu_style '{1}'".format(visu_style, self.visu_style))
                +            self.logger.warning("SmartVisuGenerator: visu_style '{}' unknown, using visu_style '{1}'".format(visu_style, self.visu_style))
                 
                -        self.logger.log(logging.WARNING, "Generating pages for smartVISU")
                -
                -        self.outdir = self.smartvisu_dir + '/pages/smarthome'
                -        self.tpldir = self.smartvisu_dir + '/pages/base/tplNG'
                -        self.tmpdir = self.smartvisu_dir + '/temp'
                +        self.logger.info("Generating pages for smartVISU v{}".format(self.smartvisu_version))
                 
                +        self.outdir = os.path.join(self.smartvisu_dir, 'pages', 'smarthome')
                +        self.tpldir = os.path.join(self.smartvisu_dir, 'pages', 'base', 'tplNG')
                +        self.tmpdir = os.path.join(self.smartvisu_dir, 'temp')
                +        if self.smartvisu_version == '2.9':
                +            self.tpldir = os.path.join(self.smartvisu_dir, 'dropins')
                +        
                         self.thisplgdir = os.path.dirname(os.path.abspath(__file__))
                         self.copy_templates()
                         
                         self.pages()
                +        self.logger.info("Generating pages for smartVISU v{} End".format(self.smartvisu_version))
                 
                 
                     def handle_heading_attributes(self, room):
                @@ -154,8 +193,11 @@ def handle_heading_attributes(self, room):
                     def get_widgetblocksize(self, item):
                         """
                         Returns the blocksize for the block in which the item is to be displayed. 
                +
                         :param item: Item to be displayed
                +
                         :return: The set number ('1'..'3') as defined in smartVISUs css
                +        :rytpe: str
                         """
                         if 'sv_blocksize' in item.conf:
                             blocksize = item.conf['sv_blocksize']
                @@ -181,7 +223,9 @@ def room(self, room):
                 
                         :param room: Items (with room configuration)
                         :param tpldir: Directory where the template files are stored (within smartVISU)
                +        
                         :return: html code to be included in the visu file for the room
                +        :rtype: str
                         """
                         block_style = 'std' # 'std' or 'noh'
                         widgetblocktemplate = 'widgetblock_' + self.visu_style + '_' + block_style + '.html'
                @@ -308,6 +352,7 @@ def pages(self):
                 #########################################################################
                 
                     def parse_tpl(self, template, replace):
                +        self.logger.debug("try to parse template file '{0}'".format(template))
                         try:
                             with open(self.tpldir + '/' + template, 'r', encoding='utf-8') as f:
                                 tpl = f.read()
                @@ -374,25 +419,34 @@ def remove_oldpages(self):
                 #########################################################################
                 
                     def copy_templates(self):
                -        # copy widgets from the sv_widget(s) subdir of a plugin
                -        srcdir = self.thisplgdir + '/tplNG'
                +        srcdir = os.path.join(self.thisplgdir, 'tplNG')
                         if not os.path.isdir(srcdir):
                -            self.logger.warning("copy_templates: Could not find source directory {0}".format(srcdir))
                +            self.logger.warning("copy_templates: Could not find source directory {}".format(srcdir))
                             return
                 
                -        # create output directory
                -        try:
                -            os.mkdir(self.tpldir)
                -        except:
                -            pass
                +        if self.smartvisu_version == '2.9':
                +            for fn in os.listdir(srcdir):
                +                if (self.overwrite_templates) or (not os.path.isfile(os.path.join(self.tpldir, fn)) ):
                +                    self.logger.debug("copy_templates: Copying template '{}' from plugin to smartVISU v{}".format(fn, self.smartvisu_version))
                +                    shutil.copy2( os.path.join(srcdir, fn), self.tpldir )
                +
                +        else:
                +            # create output directory
                +            try:
                +                os.mkdir(self.tpldir)
                +            except:
                +                pass
                             
                -#        self.logger.warning("copy_templates: Copying templates from plugin-dir '{0}' to smartVISU-dir '{1}'".format(srcdir, self.tpldir))
                +#            self.logger.warning("copy_templates: Copying templates from plugin-dir '{0}' to smartVISU-dir '{1}'".format(srcdir, self.tpldir))
                         
                -        # Open file for twig import statements (for root.html)
                -        for fn in os.listdir(srcdir):
                -            if (self.overwrite_templates) or (not os.path.isfile(self.tpldir + '/' + fn) ):
                -                self.logger.info("copy_templates: Copying template '{0}' from plugin to smartVISU".format(fn))
                -                shutil.copy2( srcdir + '/' + fn, self.tpldir )
                +            # Open file for twig import statements (for root.html)
                +            for fn in os.listdir(srcdir):
                +                if (self.overwrite_templates) or (not os.path.isfile(os.path.join(self.tpldir, fn)) ):
                +                    self.logger.debug("copy_templates: Copying template '{}' from plugin to smartVISU v{}".format(fn, self.smartvisu_version))
                +                    try:
                +                        shutil.copy2( os.path.join(srcdir, fn), self.tpldir )
                +                    except Exception as e:
                +                        self.logger.error("Could not copy {0} from {1} to {2}".format(fn, srcdir, self.tpldir))
                         return
                 
                 
                @@ -403,20 +457,24 @@ def copy_templates(self):
                 
                 class SmartVisuInstallWidgets:
                 
                -    def __init__(self, smarthome, smartvisu_dir=''):
                +    def __init__(self, smarthome, smartvisu_dir='', smartvisu_version=''):
                         self.logger = logging.getLogger(__name__)
                         self._sh = smarthome
                         self.smartvisu_dir = smartvisu_dir
                -
                -        self.logger.log(logging.WARNING, "Installing widgets into smartVISU")
                +        self.smartvisu_version = smartvisu_version
                +        self.logger.info("Installing widgets into smartVISU v{}".format(self.smartvisu_version))
                         
                         # sv directories
                         self.shwdgdir = 'sh_widgets'
                         self.outdir = self.smartvisu_dir + '/widgets/' + self.shwdgdir
                         self.tmpdir = self.smartvisu_dir + '/temp'
                         self.pgbdir = self.smartvisu_dir + '/pages/base'          # pages/base directory
                +        if self.smartvisu_version == '2.9':
                +            self.outdir = os.path.join(self.smartvisu_dir, 'dropins/widgets')
                +            self.pgbdir = os.path.join(self.smartvisu_dir, 'dropins')
                +            self.icndir = os.path.join(self.smartvisu_dir, 'dropins/icons/ws')
                 
                -        self.logger.info("install_widgets: Installing from '{0}' to '{1}'".format(smarthome.base_dir, smartvisu_dir))
                +        self.logger.debug("install_widgets: Installing from '{0}' to '{1}'".format(smarthome.base_dir, smartvisu_dir))
                 
                         self.install_widgets(self._sh)
                 
                @@ -425,39 +483,52 @@ def install_widgets(self, smarthome):
                         if not self.remove_oldfiles():
                             return
                     
                -        # make a backup copy of root.html if it doesn't exist (for full integeration)
                -        if not os.path.isfile( self.pgbdir + '/root_master.html' ):
                -            self.logger.warning( "install_widgets: Creating a copy of root.html" )
                -            shutil.copy2( self.pgbdir + '/root.html', self.pgbdir + '/root_master.html' )
                -
                -        # read the unmodified root.html (from root_master.html)
                -        f_root = open(self.pgbdir + '/root_master.html', "r")
                -        root_contents = f_root.readlines()
                -        f_root.close()
                -        self.logger.debug( "root_contents: {0}".format(root_contents) )
                -
                -        # find insert points in original root.html
                -        iln_html = self.findinsertline( root_contents, '{% import "plot.html" as plot %}' )
                -        iln_js = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.js') %}" )
                -        iln_css = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.css') %}" )
                +        if self.smartvisu_version == '2.7' or self.smartvisu_version == '2.8':
                +            # make a backup copy of root.html if it doesn't exist (for full integeration)
                +            if not os.path.isfile( self.pgbdir + '/root_master.html' ):
                +                self.logger.warning( "install_widgets: Creating a copy of root.html" )
                +                try:
                +                    shutil.copy2( self.pgbdir + '/root.html', self.pgbdir + '/root_master.html' )
                +                except Exception as e:
                +                    self.logger.error("Could not copy {} from {} to {}".format('root.html', self.pgbdir, self.pgbdir + '/root_master.html'))
                +                    return
                +
                +            # read the unmodified root.html (from root_master.html)
                +            f_root = open(self.pgbdir + '/root_master.html', "r")
                +            root_contents = f_root.readlines()
                +            f_root.close()
                +            self.logger.debug( "root_contents: {0}".format(root_contents) )
                +
                +            # find insert points in original root.html
                +            iln_html = self.findinsertline( root_contents, '{% import "plot.html" as plot %}' )
                +            iln_js = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.js') %}" )
                +            iln_css = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.css') %}" )
                     
                         # copy widgets from plugin directories of configured plugins
                         # read plungin.conf
                         _conf = lib.config.parse(smarthome._plugin_conf)
                +        self.logger.debug( "install_widgets: _conf = {}".format(str(_conf)) )
                         mypluginlist = []
                         for plugin in _conf:
                -    #        self.logger.warning("install_widgets: Plugin class {0}, path {1}".format(_conf[plugin]['class_name'], _conf[plugin]['class_path']))
                -            plgdir = _conf[plugin]['class_path']
                +            self.logger.debug("install_widgets: Plugin section '{}', class_path = '{}', plugin_name = '{}'".format(plugin, str(_conf[plugin].get('class_path', '')), str(_conf[plugin].get('plugin_name', ''))))
                +            plgdir = _conf[plugin].get('class_path', '')
                +            if plgdir == '':
                +                plgdir = 'plugins.' + _conf[plugin].get('plugin_name', '')
                             if plgdir not in mypluginlist:
                                 # process each plugin only once
                                 mypluginlist.append( plgdir )
                -                self.copy_widgets( plgdir.replace('.', '/'), root_contents, iln_html, iln_js, iln_css )
                -        # write root.html with additions for widgets
                -        self.logger.info( "Adding import statements to root.html" )
                -        f_root = open(self.pgbdir + '/root.html', "w")
                -        root_contents = "".join(root_contents)
                -        f_root.write(root_contents)
                -        f_root.close()
                +                if self.smartvisu_version == '2.7' or self.smartvisu_version == '2.8':
                +                    self.copy_widgets( plgdir.replace('.', '/'), root_contents, iln_html, iln_js, iln_css )
                +                else:
                +                    self.copy_widgets( plgdir.replace('.', '/') )
                +
                +        if self.smartvisu_version == '2.7' or self.smartvisu_version == '2.8':
                +            # write root.html with additions for widgets
                +            self.logger.info( "Adding import statements to root.html" )
                +            f_root = open(self.pgbdir + '/root.html', "w")
                +            root_contents = "".join(root_contents)
                +            f_root.write(root_contents)
                +            f_root.close()
                 
                 
                 #########################################################################
                @@ -473,30 +544,46 @@ def findinsertline(self, root_contents, searchstring ):
                         return( iln )
                     
                 
                -    def copy_widgets(self, plgdir, root_contents, iln_html, iln_js, iln_css):
                +    def copy_widgets(self, plgdir, root_contents='', iln_html='', iln_js='', iln_css=''):
                         wdgdir = 'sv_widgets'
                         # copy widgets from the sv_widget(s) subdir of a plugin
                         srcdir = self._sh.base_dir + '/' + plgdir + '/' + wdgdir
                         if not os.path.isdir(srcdir):
                -            self.logger.debug("copy_widgets: Could not find source directory {0} in {1}".format(wdgdir, plgdir))
                +            self.logger.debug("copy_widgets: Could not find source directory {} in {}".format(wdgdir, plgdir))
                             return
                -        self.logger.debug("copy_widgets: Copying widgets from plugin '{0}'".format(srcdir))
                +        self.logger.debug("copy_widgets: Copying widgets from plugin '{}'".format(srcdir))
                 
                         # Open file for twig import statements (for root.html)
                         for fn in os.listdir(srcdir):
                             if (fn[-3:] != ".md"):
                -                self.logger.info("copy_widgets: Copying widget-file: {0}".format(fn))
                -                shutil.copy2( srcdir + '/' + fn, self.outdir )
                -                if (fn[0:7] == "widget_") and (fn[-5:] == ".html"):
                -                    self.logger.info("- Installing from '{0}': {1}".format(plgdir, '\t' + fn))
                -                    if iln_html != '':
                -                        self.create_htmlinclude(fn, fn[7:-5] , root_contents, iln_html)
                -                if (fn[0:7] == "widget_") and (fn[-3:] == ".js"):
                -                    if iln_js != '':
                -                        self.create_jsinclude(fn, fn[7:-3] , root_contents, iln_js)
                -                if (fn[0:7] == "widget_") and (fn[-4:] == ".css"):
                -                    if iln_css != '':
                -                        self.create_cssinclude(fn, fn[7:-4] , root_contents, iln_css)
                +                self.logger.info("copy_widgets (v{}): Copying widget-file: {} from {}".format(self.smartvisu_version, fn, plgdir))
                +                if self.smartvisu_version == '2.9':
                +                    if os.path.splitext(fn)[1] == '.png':
                +                        # copy icons to the icons directory
                +                        shutil.copy2( os.path.join(srcdir, fn), self.icndir )
                +                    else:
                +                        # the rest to the widgets directory & strip 'widgets_' from name
                +                        if fn.startswith('widget_'):
                +                            dn = fn[len('widget_'):]
                +                            shutil.copy2( os.path.join(srcdir, fn), os.path.join(self.outdir, dn) )
                +                        else:
                +                            shutil.copy2( os.path.join(srcdir, fn), self.outdir )
                +                            
                +                else:
                +                    # v2.7 & v2.8
                +                    shutil.copy2( srcdir + '/' + fn, self.outdir )
                +
                +                if self.smartvisu_version == '2.7' or self.smartvisu_version == '2.8':
                +                    if (fn[0:7] == "widget_") and (fn[-5:] == ".html"):
                +                        self.logger.info("- Installing for SV v{} from '{}': {}".format(self.smartvisu_version, plgdir, '\t' + fn))
                +                        if iln_html != '':
                +                            self.create_htmlinclude(fn, fn[7:-5] , root_contents, iln_html)
                +                    if (fn[0:7] == "widget_") and (fn[-3:] == ".js"):
                +                        if iln_js != '':
                +                            self.create_jsinclude(fn, fn[7:-3] , root_contents, iln_js)
                +                    if (fn[0:7] == "widget_") and (fn[-4:] == ".css"):
                +                        if iln_css != '':
                +                            self.create_cssinclude(fn, fn[7:-4] , root_contents, iln_css)
                         return
                         
                 
                @@ -551,7 +638,7 @@ def remove_oldfiles(self):
                                 self.logger.warning("Could not delete directory {0}: {1}".format(fp, e))
                             
                         # create destination directory for widgets
                -        self.logger.info("install_widgets: Creating  directory for widgets")
                +        self.logger.debug("install_widgets: Creating directory for widgets")
                         try:
                             os.mkdir(self.outdir)
                         except:
                @@ -562,7 +649,7 @@ def remove_oldfiles(self):
                             return False
                 
                         # remove old dynamic widget files
                -        self.logger.info("install_widgets: Removing old dynamic widget files")
                +        self.logger.debug("install_widgets: Removing old dynamic widget files")
                         for fn in os.listdir(self.outdir):
                             fp = os.path.join(self.outdir, fn)
                             try:
                diff --git a/visu_smartvisu/_pv_1_3_3/README.md b/visu_smartvisu/_pv_1_3_3/README.md
                new file mode 100755
                index 000000000..efbd56cc1
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/README.md
                @@ -0,0 +1,284 @@
                +# Visualisation (smartVISU support)
                +
                +```
                +Copyright 2016- Martin Sinn                      m.sinn@gmx.de
                +Copyright 2012-2013 Marcus Popp                  marcus@popp.mx
                +
                +This plugin is part of SmartHomeNG.
                +  
                +Visit:  https://github.com/smarthomeNG/
                +        https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +```
                +
                +This plugin does the smartVISU specific handling. It installs widgets from the plugin directories to smartVISU and it auto-generates pages for smartVISU.
                +
                +This plugin (**```visu_smartvisu```**) does not do the communication with the browser. The websocket protocol for the browser communication is implemented in **```visu_websocket```**.
                +
                +The plugins **```visu_websocket```** and **```visu_smartvisu```** replace the old visu plugin.
                +
                +
                +## Requirements
                +
                +None.
                +
                +**But**: For the visualization to work, the websocket protocol must be configured. This is done by configuring the visu_websocket plugin.
                +
                +
                +## Configuration
                +
                +The configuration of the plugin itself is done in the file **`etc/plugin.conf`**. The configuration of the visualization of the items is done by defining additional attributes of the item in the file **`items/*.conf`**.
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +
                +```
                +[smartvisu]
                +    class_name = SmartVisu
                +    class_path = plugins.visu_smartvisu
                +#    smartvisu_dir = False
                +#    handle_widgets = True
                +```
                +
                +```yaml
                +smartvisu:
                +    class_name: SmartVisu
                +    class_path: plugins.visu_smartvisu
                +    # smartvisu_dir: False
                +    # handle_widgets: True
                +```
                +
                +#### visu_dir
                +** Only used for **old visu** (not for smartVISU) **
                +
                +Directory in which the generated web pages of the old visa are stored.
                +
                +#### smartvisu_dir
                +You could generate pages for the smartVISU visualisation if you specify the **`smartvisu_dir`** which should be set to the root directory of your smartVISU installation.
                +
                +In the examples directory you could find a configuration with every supported element. `examples/items/smartvisu.conf` 
                +
                +#### handle_widgets
                +
                +By default, the visu plugin handles smartVISU widgets. If your run into problems, you can disable the widget handling by setting this attribute to **`False`**.
                +
                +Widgets that come with a plugin are stored in in a subdirectory to the plugin folder. These widgets are installed into smartVISU upon start of smarthomeNG. These widgets can be used in smartVISU without manually adding include startements to smartVISU.
                +
                +These widgets can be used in auto-generation of visu pages. Therefor they can be included in the **`sv_widget`** attribute of an item.
                +
                +
                +### items.conf
                +Most of the entries in item.conf are specific to smartVISU. These parameters beginn with **`sv_`**.
                +
                +#### visu_acl
                +Simply set the **`visu_acl`** attribute to something to allow read/write access to the item.
                +
                +
                +#### sv_page
                + Set **`sv_page`** to to one of the following values generate a page for this item. Every widget beneath this item will be included in the page.
                +
                +Valid values are:
                +
                +| value             | description                                                 |  
                +| :---------------- | :---------------------------------------------------------- |  
                +|  **room**         |  The page appears in the room view of smartVISU         	  |  
                +| **seperator**     | Inserts a seperator between entries in the room navigation  |
                +| **overview**      | The page groups of different items together                 |  
                +|                   |                                                             |
                +|  **category**     | The page appears in the category view of smartVISU          |  
                +| **cat_seperator** | Inserts a seperator between entries in the category         |  
                +|                   | navigation                                                  |
                +| **cat_overview**  | The page groups of different items together and is added    |
                +|	                | to the category navigation                                  |  
                +|                   |                                                             |
                +|  **room_lite**    |  The page appears in a lite view of the visualization       |  
                +[values for **`sv_page`**]
                +
                +--> Beschreibung für overview und separater vervollständigen
                +
                +#### sv_overview
                +If a page has defined **`sv_page`** as **`overview`**, it shows items of a specific type. The name/identifier of the type is defined by setting **`sv_overview`** to an unique name. For items to be displayed on this page, the items have to define  **`sv_item_type`** and set it to the value of **`sv_overview`**.
                +
                +#### sv_img
                +By setting **`sv_img`** you could assign an icon or picture for a page or widget.
                +
                +
                +#### sv_nav_aside
                +**`sv_nav_aside`** allows the specification of a widget, that is being displayed at the right side of the navigation bar for a room. (upper line)
                +
                +Relative item references are supported.
                +
                +
                +#### sv_nav_aside2
                +**`sv_nav_aside2`** allows the specification of a widget, that is being displayed at the right side of the navigation bar for a room. (lower line)
                +
                +Relative item references are supported.
                +
                +
                +#### sv_widget
                +**`sv_widget`** allows the specification of a widget. You could define multiple widgets. The widget(s) is/are shown by being encapsulated in a block of type 2 (Collapsable Block). 
                +
                +Relative item references are supported.
                +
                +
                +#### sv_widget2
                +**`sv_widget2`** allows the specification of a widget for widget blocks with two pages. You could define multiple widgets. The widget(s) is/are shown by being encapsulated in a block of type 2 (Collapsable Block) with multiple pages.
                +
                +Widget blocks with three pages are not supported yet. 
                +
                +Relative item references are supported.
                +
                +
                +#### sv_item_type
                +**`sv_item_type`** allows items to be displayed on an overview page.
                +
                +
                +#### sv_heading_left
                +**`sv_heading_left`** allows the specification of a widget, hat is being displayed at the top of a room-page. This widget is shown without being encapsulated in a block. The widget is aligned to to the left.
                +
                +For this setting to work, the files **heading.html** and **room.html** have to be installed in the **pages/base/tpl** directory of smartVISU.
                +
                +
                +#### sv_heading_center
                +**`sv_heading_center`** allows the specification of a widget, hat is being displayed at the top of a room-page. This widget is shown without being encapsulated in a block. The widget is aligned to to the center.
                +
                +For this setting to work, the files **heading.html** and **room.html** have to be installed in the **pages/base/tpl** directory of smartVISU.
                +
                +
                +#### sv_heading_right
                +**`sv_heading_right`** allows the specification of a widget, hat is being displayed at the top of a room-page. This widget is shown without being encapsulated in a block. The widget is aligned to to the right.
                +
                +For this setting to work, the files **heading.html** and **room.html** have to be installed in the **pages/base/tpl** directory of smartVISU.
                +
                +
                +If one of the **`sv_heading_...`** parameters is defined, heading.html from the template directory ?tpldir? is added to the page.
                +
                +--> tpldir = directory + '/pages/base/tpl'
                +--> directory = parameter to pages() in smartvisu.py -> self.smartvisu_dir
                +
                +#### Example (.conf and .yaml)
                +
                +```
                +[first]
                +    . . .
                +[menu_divider]
                +    sv_page = seperator
                +    name = Private area of the house
                +[second]
                +    [[sleeping]]
                +        name = Sleeping Room
                +        sv_page = room
                +        sv_img = scene_sleeping.png
                +        sv_nav_aside = {{ basic.float('sleep_temp_id', 'second.sleeping.temp', '°') }} 
                +        [[[light]]]
                +            name = Light
                +            type = bool
                +            visu_acl = rw
                +            sv_widget = &#123;&#123; device.dimmer('second.sleeping.light', 'Light', 'second.sleeping.light', 'second.sleeping.light.level') &#125;&#125;
                +            knx_dpt = 1
                +            knx_listen = 3/2/12
                +            knx_send = 3/2/12
                +            [[[[level]]]]
                +                type = num
                +                visu_acl = rw
                +                knx_dpt = 5
                +                knx_listen = 3/2/14
                +                knx_send = 3/2/14
                +```
                +
                +```yaml
                +first:
                + ...
                +menu_divider:
                +    sv_page: seperator
                +    name: Private area of the house
                +
                +second:
                +
                +    sleeping:
                +        name: Sleeping Room
                +        sv_page: room
                +        sv_img: scene_sleeping.png
                +        sv_nav_aside: "{{ basic.float('sleep_temp_id', 'second.sleeping.temp', '°') }}"
                +
                +        light:
                +            name: Light
                +            type: bool
                +            visu_acl: rw
                +            sv_widget: "&    ## 123;{ device.dimmer('second.sleeping.light', 'Light', 'second.sleeping.light', 'second.sleeping.light.level') }}"
                +            knx_dpt: 1
                +            knx_listen: 3/2/12
                +            knx_send: 3/2/12
                +
                +            level:
                +                type: num
                +                visu_acl: rw
                +                knx_dpt: 5
                +                knx_listen: 3/2/14
                +                knx_send: 3/2/14
                +```
                +
                +But instead of giving the widget distinct options you could use **`item`** as a keyword.
                +
                +The page generator will replace it with the current path. This way you could easily copy widget calls and don't type the item path every time.
                +
                +```
                +[second]
                +    [[sleeping]]
                +        name = Sleeping Room
                +        sv_page = room
                +        sv_img = scene_sleeping.png
                +        [[[light]]]
                +            name = Light
                +            type = bool
                +            visu_acl = rw
                +            sv_widget = &#123;&#123; device.dimmer('item', 'item.name', 'item', 'item.level') &#125;&#125;
                +            knx_dpt = 1
                +            knx_listen = 3/2/12
                +            knx_send = 3/2/12
                +            [[[[level]]]]
                +                type = num
                +                visu_acl = rw
                +                knx_dpt = 5
                +                knx_listen = 3/2/14
                +                knx_send = 3/2/14
                +```
                +
                +```yaml
                +second:
                +
                +    sleeping:
                +        name: Sleeping Room
                +        sv_page: room
                +        sv_img: scene_sleeping.png
                +
                +        light:
                +            name: Light
                +            type: bool
                +            visu_acl: rw
                +            sv_widget: "{{ device.dimmer('item', 'item.name', 'item', 'item.level') }}"
                +            knx_dpt: 1
                +            knx_listen: 3/2/12
                +            knx_send: 3/2/12
                +
                +            level:
                +                type: num
                +                visu_acl: rw
                +                knx_dpt: 5
                +                knx_listen: 3/2/14
                +                knx_send: 3/2/14
                +```
                +
                +### logic.conf (deprecated) / logic.yaml
                +You could specify the **`visu_acl`** attribute to every logic in your logic.conf. This way you could trigger the logic via the interface.
                +
                +```
                +[dialog]
                +    filename = 'dialog.py'
                +    visu_acl = true
                +```
                +
                +```yaml
                +dialog:
                +    filename: dialog.py
                +    visu_acl: 'true'
                +```
                diff --git a/visu_smartvisu/_pv_1_3_3/__init__.py b/visu_smartvisu/_pv_1_3_3/__init__.py
                new file mode 100755
                index 000000000..d4f44ae94
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/__init__.py
                @@ -0,0 +1,587 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2016- Martin Sinn                              m.sinn@gmx.de
                +#  Parts Copyright 2012-2013 Marcus Popp                   marcus@popp.mx
                +#########################################################################
                +#  This file is part of SmartHomeNG.  
                +#  Visit:  https://github.com/smarthomeNG/
                +#          https://knx-user-forum.de/forum/supportforen/smarthome-py
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import logging
                +import struct
                +
                +import os
                +import shutil
                +
                +import lib.config
                +from lib.model.smartplugin import SmartPlugin
                +
                +import sys
                +
                +# to do: copy tplNG files
                +# implement config parameter to copy/not to copy tplNG files (if dir exist in smartVISU)
                +
                +
                +#########################################################################
                +
                +class SmartVisu(SmartPlugin):
                +    PLUGIN_VERSION="1.3.3"
                +    ALLOW_MULTIINSTANCE = False
                +
                +
                +    def my_to_bool(self, value, attr='', default=False):
                +        try:
                +            result = self.to_bool(value)
                +        except:
                +            result = default
                +            self.logger.error("smartVISU: Invalid value '"+str(value)+"' configured for attribute "+attr+" in plugin.conf, using '"+str(result)+"' instead")
                +        return result
                +
                +
                +    def __init__(self, smarthome, smartvisu_dir='', generate_pages='True', overwrite_templates='Yes', visu_style = 'std', handle_widgets='True' ):
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        
                +        self.smartvisu_dir = str(smartvisu_dir)
                +        self._generate_pages = self.my_to_bool(generate_pages, 'generate_pages', True)
                +        self.overwrite_templates = self.my_to_bool(overwrite_templates, 'overwrite_templates', True)
                +        if visu_style.lower() in ['std','blk']:
                +            self.visu_style = visu_style.lower()
                +        else:
                +            self.visu_style = 'std'
                +            self.logger.error("smartVISU: Invalid value '"+str(visu_style)+"' configured for attribute visu_style in plugin.conf, using '"+str(self.visu_style)+"' instead")
                +        self._handle_widgets = self.my_to_bool(handle_widgets, "handle_widgets", False)
                +
                +
                +    def run(self):
                +        self.alive = True
                +        if self.smartvisu_dir != '':
                +            if not os.path.isdir(self.smartvisu_dir + '/pages'):
                +                self.logger.error("Could not find valid smartVISU directory: {0}".format(self.smartvisu_dir))
                +            else:
                +#                self.logger.warning("Starting smartVISU handling")
                +                if self._handle_widgets:
                +                    sv_iwdg = SmartVisuInstallWidgets(self._sh, self.smartvisu_dir)
                +
                +                if self._generate_pages:
                +                    svgen = SmartVisuGenerator(self._sh, self.smartvisu_dir, self.overwrite_templates, self.visu_style)
                +#                self.logger.warning("Finished smartVISU handling")
                +
                +
                +    def stop(self):
                +        self.alive = False
                +
                +
                +    def parse_item(self, item):
                +        # Relative path support (release 1.3 and up)
                +        item.expand_relativepathes('sv_widget', "'", "'")
                +        item.expand_relativepathes('sv_widget2', "'", "'")
                +        item.expand_relativepathes('sv_nav_aside', "'", "'")
                +        item.expand_relativepathes('sv_nav_aside2', "'", "'")
                +
                +
                +    def parse_logic(self, logic):
                +        pass
                +
                +
                +    def update_item(self, item, caller=None, source=None, dest=None):
                +        pass
                +
                +
                +#########################################################################
                +#       Visu page generator
                +#########################################################################
                +
                +
                +class SmartVisuGenerator:
                +
                +    def __init__(self, smarthome, smartvisu_dir='', overwrite_templates='Yes', visu_style='std'):
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        self.smartvisu_dir = smartvisu_dir
                +        self.overwrite_templates = overwrite_templates
                +        self.visu_style = visu_style.lower()
                +        if not self.visu_style in ['std','blk']:
                +            self.visu_style = 'std'
                +            self.logger.warning("SmartVisuGenerator: visu_style '{0}' unknown, using visu_style '{1}'".format(visu_style, self.visu_style))
                +
                +        self.logger.log(logging.INFO, "Generating pages for smartVISU")
                +
                +        self.outdir = self.smartvisu_dir + '/pages/smarthome'
                +        self.tpldir = self.smartvisu_dir + '/pages/base/tplNG'
                +        self.tmpdir = self.smartvisu_dir + '/temp'
                +
                +        self.thisplgdir = os.path.dirname(os.path.abspath(__file__))
                +        self.copy_templates()
                +        
                +        self.pages()
                +
                +
                +    def handle_heading_attributes(self, room):
                +        if 'sv_heading_right' in room.conf:
                +            heading_right = room.conf['sv_heading_right']
                +        else:
                +            heading_right = ''
                +        if 'sv_heading_center' in room.conf:
                +            heading_center = room.conf['sv_heading_center']
                +        else:
                +            heading_center = ''
                +        if 'sv_heading_left' in room.conf:
                +            heading_left = room.conf['sv_heading_left']
                +        else:
                +            heading_left = ''
                +        if heading_right != '' or heading_center != '' or heading_left != '':
                +            heading = self.parse_tpl('heading.html', [('{{ visu_heading_right }}', heading_right), ('{{ visu_heading_center }}', heading_center), ('{{ visu_heading_left }}', heading_left)])
                +        else:
                +            heading = ''
                +        return heading
                +
                +
                +    def get_widgetblocksize(self, item):
                +        """
                +        Returns the blocksize for the block in which the item is to be displayed. 
                +        :param item: Item to be displayed
                +        :return: The set number ('1'..'3') as defined in smartVISUs css
                +        """
                +        if 'sv_blocksize' in item.conf:
                +            blocksize = item.conf['sv_blocksize']
                +            if not blocksize in ['1','2','3']:
                +                blocksize = '2'
                +        else:
                +            blocksize = '2'
                +        return blocksize
                +        
                +        
                +    def get_attribute(self, attr, item):
                +        if attr in item.conf:
                +            attrvalue = item.conf[attr]
                +        else:
                +            attrvalue = ''
                +        return attrvalue
                +    
                +    
                +    def room(self, room):
                +        """
                +        Interpretation of the room-specific item-attributes. 
                +        This routine is called once per 'sv_page'.
                +
                +        :param room: Items (with room configuration)
                +        :param tpldir: Directory where the template files are stored (within smartVISU)
                +        :return: html code to be included in the visu file for the room
                +        """
                +        block_style = 'std' # 'std' or 'noh'
                +        widgetblocktemplate = 'widgetblock_' + self.visu_style + '_' + block_style + '.html'
                +        widgetblocktemplate2 = 'widgetblock2_' + self.visu_style + '_' + block_style + '.html'
                +        widgets = ''
                +
                +        rimg = self.get_attribute('sv_img', room)
                +        heading = self.handle_heading_attributes(room)
                +
                +        if 'sv_widget' in room.conf:
                +            items = [room]
                +        else:
                +            items = []
                +
                +        if (room.conf['sv_page'] == 'room') or (room.conf['sv_page'] == 'room_lite'):
                +            items.extend(self._sh.find_children(room, 'sv_widget'))
                +        elif room.conf['sv_page'] == 'category':
                +            items.extend(self._sh.find_children(room, 'sv_widget'))
                +        elif room.conf['sv_page'] == 'overview':
                +            items.extend(self._sh.find_items('sv_item_type'))
                +
                +        r = ''
                +        for item in items:
                +            if room.conf['sv_page'] == 'overview' and not item.conf['sv_item_type'] == room.conf['sv_overview']:
                +                continue
                +            if 'sv_img' in item.conf:
                +                img = item.conf['sv_img']
                +            else:
                +                img = ''
                +            if isinstance(item.conf['sv_widget'], list):
                +                self.logger.warning("room: sv_widget: IsList")
                +                for widget in item.conf['sv_widget']:
                +                    widgets += self.parse_tpl(widgetblocktemplate, [('{{ visu_name }}', str(item)), ('{{ visu_img }}', img), ('{{ visu_widget }}', widget), ('item.name', str(item)), ("'item", "'" + item.id())])
                +            else:
                +                widget = self.get_attribute('sv_widget', item)
                +                name1 = self.get_attribute('sv_name1', item)
                +                if name1 == '':
                +                    name1 = item
                +
                +                blocksize = self.get_widgetblocksize(item)
                +
                +                widget2 = self.get_attribute('sv_widget2', item)
                +                if widget2 == '':
                +                    widgets += self.parse_tpl(widgetblocktemplate, [('{{ visu_name }}', str(name1)), ('{{ blocksize }}', str(blocksize)), ('{{ visu_img }}', img), ('{{ visu_widget }}', widget), ('item.name', str(item)), ("'item", "'" + item.id())])
                +                else:
                +                    name2 = self.get_attribute('sv_name2', item)
                +                    widgets += self.parse_tpl(widgetblocktemplate2, [('{{ visu_name }}', str(name1)), ('{{ visu_name2 }}', str(name2)), ('{{ visu_img }}', img), ('{{ visu_widget }}', widget), ('{{ visu_widget2 }}', widget2), ('item.name', str(item)), ("'item", "'" + item.id())])
                +
                +            if room.conf['sv_page'] == 'room':
                +                r = self.parse_tpl('room.html', [('{{ visu_name }}', str(room)), ('{{ visu_widgets }}', widgets), ('{{ visu_img }}', rimg), ('{{ visu_heading }}', heading)])
                +            elif room.conf['sv_page'] == 'overview':
                +                r = self.parse_tpl('room.html', [('{{ visu_name }}', str(room)), ('{{ visu_widgets }}', widgets), ('{{ visu_img }}', rimg), ('{{ visu_heading }}', heading)])
                +            elif room.conf['sv_page'] == 'category':
                +                r = self.parse_tpl('category_page.html', [('{{ visu_name }}', str(room)), ('{{ visu_widgets }}', widgets), ('{{ visu_img }}', rimg), ('{{ visu_heading }}', heading)])
                +            elif room.conf['sv_page'] == 'room_lite':
                +                r = self.parse_tpl('roomlite.html', [('{{ visu_name }}', str(room)), ('{{ visu_widgets }}', widgets), ('{{ visu_img }}', rimg), ('{{ visu_heading }}', heading)])
                +        return r
                +
                +
                +    def pages(self):
                +        if not self.remove_oldpages():
                +            return
                +
                +        nav_lis = ''
                +        cat_lis = ''
                +        lite_lis = ''
                +                
                +        for item in self._sh.find_items('sv_page'):
                +            if item.conf['sv_page'] == 'seperator':
                +                nav_lis += self.parse_tpl('navi_sep.html', [('{{ name }}', str(item))])
                +                continue
                +            elif item.conf['sv_page'] == 'cat_seperator':
                +                cat_lis += self.parse_tpl('navi_sep.html', [('{{ name }}', str(item))])
                +                continue
                +            elif ((item.conf['sv_page'] == 'overview') or (item.conf['sv_page'] == 'cat_overview')) and (not 'sv_overview' in item.conf):
                +                self.logger.error("missing sv_overview for {0}".format(item.id()))
                +                continue
                +
                +            r = self.room(item)
                +
                +            img = self.get_attribute('sv_img', item)
                +
                +            if 'sv_nav_aside' in item.conf:
                +                if isinstance(item.conf['sv_nav_aside'], list):
                +                    nav_aside = ', '.join(item.conf['sv_nav_aside'])
                +                else:
                +                    nav_aside = item.conf['sv_nav_aside']
                +            else:
                +                nav_aside = ''
                +            if 'sv_nav_aside2' in item.conf:
                +                if isinstance(item.conf['sv_nav_aside2'], list):
                +                    nav_aside2 = ', '.join(item.conf['sv_nav_aside2'])
                +                else:
                +                    nav_aside2 = item.conf['sv_nav_aside2']
                +            else:
                +                nav_aside2 = ''
                +            if (item.conf['sv_page'] == 'category') or (item.conf['sv_page'] == 'cat_overview'):
                +                cat_lis += self.parse_tpl('navi.html', [('{{ visu_page }}', item.id()), ('{{ visu_name }}', str(item)), ('{{ visu_img }}', img), ('{{ visu_aside }}', nav_aside), ('{{ visu_aside2 }}', nav_aside2), ('item.name', str(item)), ("'item", "'" + item.id())])
                +            elif item.conf['sv_page'] == 'room':
                +                nav_lis += self.parse_tpl('navi.html', [('{{ visu_page }}', item.id()), ('{{ visu_name }}', str(item)), ('{{ visu_img }}', img), ('{{ visu_aside }}', nav_aside), ('{{ visu_aside2 }}', nav_aside2), ('item.name', str(item)), ("'item", "'" + item.id())])
                +            elif item.conf['sv_page'] == 'overview':
                +                nav_lis += self.parse_tpl('navi.html', [('{{ visu_page }}', item.id()), ('{{ visu_name }}', str(item)), ('{{ visu_img }}', img), ('{{ visu_aside }}', nav_aside), ('{{ visu_aside2 }}', nav_aside2), ('item.name', str(item)), ("'item", "'" + item.id())])
                +            elif item.conf['sv_page'] == 'room_lite':
                +                lite_lis += self.parse_tpl('navi.html', [('{{ visu_page }}', item.id()), ('{{ visu_name }}', str(item)), ('{{ visu_img }}', img), ('{{ visu_aside }}', nav_aside), ('{{ visu_aside2 }}', nav_aside2), ('item.name', str(item)), ("'item", "'" + item.id())])
                +            self.write_parseresult(item.id()+'.html', r)
                +
                +
                +        nav = self.parse_tpl('navigation.html', [('{{ visu_navis }}', nav_lis)])
                +        self.write_parseresult('room_nav.html', nav)
                +
                +        nav = self.parse_tpl('navigation.html', [('{{ visu_navis }}', cat_lis)])
                +        self.write_parseresult('category_nav.html', nav)
                +
                +        nav = self.parse_tpl('navigation.html', [('{{ visu_navis }}', lite_lis)])
                +        self.write_parseresult('roomlite_nav.html', nav)
                +
                +
                +        self.copy_tpl('rooms.html')
                +        self.copy_tpl('roomslite.html')
                +        self.copy_tpl('category.html')
                +        self.copy_tpl('index.html')
                +        
                +
                +#########################################################################
                +
                +    def parse_tpl(self, template, replace):
                +        self.logger.debug("try to parse template file '{0}'".format(template))
                +        try:
                +            with open(self.tpldir + '/' + template, 'r', encoding='utf-8') as f:
                +                tpl = f.read()
                +                tpl = tpl.lstrip('\ufeff')  # remove BOM
                +        except Exception as e:
                +            self.logger.error("Could not read template file '{0}': {1}".format(template, e))
                +            return ''
                +        for s, r in replace:
                +            tpl = tpl.replace(s, r)
                +        return tpl
                +
                +
                +    def write_parseresult(self, htmlfile, parseresult):
                +        try:
                +            with open(self.outdir + '/' + htmlfile, 'w') as f:
                +                f.write(parseresult)
                +        except Exception as e:
                +            self.logger.warning("Could not write to {0}/{1}: {2}".format(self.outdir, htmlfile, e))
                +
                +
                +    def copy_tpl(self, tplname, destname=''):
                +        if destname == '':
                +            destname = tplname
                +        try:
                +            shutil.copy(self.tpldir + '/' + tplname, self.outdir + '/' + destname)
                +        except Exception as e:
                +            self.logger.error("Could not copy {0} from {1} to {2}".format(tplname, tpldir, destdir))
                +
                +
                +#########################################################################
                +
                +    def remove_oldpages(self):
                +        if not os.path.isdir(self.tmpdir):
                +            self.logger.warning("Could not find directory: {0}".format(self.tmpdir))
                +            return False
                +        # clear temp directory
                +        for dn in os.listdir(self.tmpdir):
                +            if len(dn) != 2:  # only delete Twig temp files
                +                continue
                +            dp = os.path.join(self.tmpdir, dn)
                +            try:
                +                if os.path.isdir(dp):
                +                    shutil.rmtree(dp)
                +            except Exception as e:
                +                self.logger.warning("Could not delete directory {0}: {1}".format(dp, e))
                +        # create output directory
                +        try:
                +            os.mkdir(self.outdir)
                +        except:
                +            pass
                +        # remove old dynamic files
                +        if not os.path.isdir(self.outdir):
                +            self.logger.warning("Could not find/create directory: {0}".format(self.outdir))
                +            return False
                +        for fn in os.listdir(self.outdir):
                +            fp = os.path.join(self.outdir, fn)
                +            try:
                +                if os.path.isfile(fp):
                +                    os.unlink(fp)
                +            except Exception as e:
                +                self.logger.warning("Could not delete file {0}: {1}".format(fp, e))
                +        return True
                +
                +#########################################################################
                +
                +    def copy_templates(self):
                +        # copy widgets from the sv_widget(s) subdir of a plugin
                +        srcdir = self.thisplgdir + '/tplNG'
                +        if not os.path.isdir(srcdir):
                +            self.logger.warning("copy_templates: Could not find source directory {0}".format(srcdir))
                +            return
                +
                +        # create output directory
                +        try:
                +            os.mkdir(self.tpldir)
                +        except:
                +            pass
                +            
                +#        self.logger.warning("copy_templates: Copying templates from plugin-dir '{0}' to smartVISU-dir '{1}'".format(srcdir, self.tpldir))
                +        
                +        # Open file for twig import statements (for root.html)
                +        for fn in os.listdir(srcdir):
                +            if (self.overwrite_templates) or (not os.path.isfile(self.tpldir + '/' + fn) ):
                +                self.logger.debug("copy_templates: Copying template '{0}' from plugin to smartVISU".format(fn))
                +                try:
                +                    shutil.copy2( srcdir + '/' + fn, self.tpldir )
                +                except Exception as e:
                +                    self.logger.error("Could not copy {0} from {1} to {2}".format(fn, srcdir, self.tpldir))
                +        return
                +
                +
                +#########################################################################
                +#       Widget Handling
                +#########################################################################
                +
                +
                +class SmartVisuInstallWidgets:
                +
                +    def __init__(self, smarthome, smartvisu_dir=''):
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        self.smartvisu_dir = smartvisu_dir
                +
                +        self.logger.log(logging.INFO, "Installing widgets into smartVISU")
                +        
                +        # sv directories
                +        self.shwdgdir = 'sh_widgets'
                +        self.outdir = self.smartvisu_dir + '/widgets/' + self.shwdgdir
                +        self.tmpdir = self.smartvisu_dir + '/temp'
                +        self.pgbdir = self.smartvisu_dir + '/pages/base'          # pages/base directory
                +
                +        self.logger.debug("install_widgets: Installing from '{0}' to '{1}'".format(smarthome.base_dir, smartvisu_dir))
                +
                +        self.install_widgets(self._sh)
                +
                +
                +    def install_widgets(self, smarthome):
                +        if not self.remove_oldfiles():
                +            return
                +    
                +        # make a backup copy of root.html if it doesn't exist (for full integeration)
                +        if not os.path.isfile( self.pgbdir + '/root_master.html' ):
                +            self.logger.warning( "install_widgets: Creating a copy of root.html" )
                +            try:
                +                shutil.copy2( self.pgbdir + '/root.html', self.pgbdir + '/root_master.html' )
                +            except Exception as e:
                +                self.logger.error("Could not copy {0} from {1} to {2}".format('root.html', self.pgbdir, self.pgbdir + '/root_master.html'))
                +                return
                +
                +        # read the unmodified root.html (from root_master.html)
                +        f_root = open(self.pgbdir + '/root_master.html', "r")
                +        root_contents = f_root.readlines()
                +        f_root.close()
                +        self.logger.debug( "root_contents: {0}".format(root_contents) )
                +
                +        # find insert points in original root.html
                +        iln_html = self.findinsertline( root_contents, '{% import "plot.html" as plot %}' )
                +        iln_js = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.js') %}" )
                +        iln_css = self.findinsertline( root_contents, "{% if isfile('pages/'~config_pages~'/visu.css') %}" )
                +    
                +        # copy widgets from plugin directories of configured plugins
                +        # read plugin.conf
                +        _conf = lib.config.parse(smarthome._plugin_conf)
                +        self.logger.debug( "install_widgets: _conf = {0}".format(str(_conf)) )
                +        mypluginlist = []
                +        for plugin in _conf:
                +            self.logger.debug("install_widgets: Plugin section '{}', class_path = '{}', plugin_name = '{}'".format(plugin, str(_conf[plugin].get('class_path', '')), str(_conf[plugin].get('plugin_name', ''))))
                +            plgdir = _conf[plugin].get('class_path', '')
                +            if plgdir == '':
                +                plgdir = 'plugins.' + _conf[plugin].get('plugin_name', '')
                +            if plgdir not in mypluginlist:
                +                # process each plugin only once
                +                mypluginlist.append( plgdir )
                +                self.copy_widgets( plgdir.replace('.', '/'), root_contents, iln_html, iln_js, iln_css )
                +        # write root.html with additions for widgets
                +        self.logger.info( "Adding import statements to root.html" )
                +        f_root = open(self.pgbdir + '/root.html', "w")
                +        root_contents = "".join(root_contents)
                +        f_root.write(root_contents)
                +        f_root.close()
                +
                +
                +#########################################################################
                +
                +    def findinsertline(self, root_contents, searchstring ):
                +        # look for insert point in root.html: find and return line that contains the searchstring
                +        iln = ''
                +        for ln in root_contents:
                +            if ln.find( searchstring ) != -1:
                +                iln = ln
                +        if iln == '':
                +            self.logger.warning("findinsertline: No insert point for pattern {0}".format(searchstring))
                +        return( iln )
                +    
                +
                +    def copy_widgets(self, plgdir, root_contents, iln_html, iln_js, iln_css):
                +        wdgdir = 'sv_widgets'
                +        # copy widgets from the sv_widget(s) subdir of a plugin
                +        srcdir = self._sh.base_dir + '/' + plgdir + '/' + wdgdir
                +        if not os.path.isdir(srcdir):
                +            self.logger.debug("copy_widgets: Could not find source directory {0} in {1}".format(wdgdir, plgdir))
                +            return
                +        self.logger.debug("copy_widgets: Copying widgets from plugin '{0}'".format(srcdir))
                +
                +        # Open file for twig import statements (for root.html)
                +        for fn in os.listdir(srcdir):
                +            if (fn[-3:] != ".md"):
                +                self.logger.debug("copy_widgets: Copying widget-file: {0}".format(fn))
                +                shutil.copy2( srcdir + '/' + fn, self.outdir )
                +                if (fn[0:7] == "widget_") and (fn[-5:] == ".html"):
                +                    self.logger.info("- Installing from '{0}': {1}".format(plgdir, '\t' + fn))
                +                    if iln_html != '':
                +                        self.create_htmlinclude(fn, fn[7:-5] , root_contents, iln_html)
                +                if (fn[0:7] == "widget_") and (fn[-3:] == ".js"):
                +                    if iln_js != '':
                +                        self.create_jsinclude(fn, fn[7:-3] , root_contents, iln_js)
                +                if (fn[0:7] == "widget_") and (fn[-4:] == ".css"):
                +                    if iln_css != '':
                +                        self.create_cssinclude(fn, fn[7:-4] , root_contents, iln_css)
                +        return
                +        
                +
                +    def create_htmlinclude(self, filename, classname, root_contents, iln_html):
                +        insertln = root_contents.index(iln_html) +1
                +        # Insert widget statements to root_contents
                +        if insertln != 0:
                +            self.logger.debug( "create_htmlinclude: Inserting in root.html at line {0} after '{1}'".format(insertln, iln_html) )
                +            twig_statement = '\t{% import "' + self.shwdgdir + '/' + filename + '" as ' + classname + ' %}'
                +            root_contents.insert(insertln, twig_statement+'\n')
                +
                +
                +    def create_jsinclude(self, filename, classname, root_contents, iln_js):
                +        insertln = root_contents.index(iln_js)
                +        # Insert widget statements to root_contents
                +        if insertln > -1:
                +            self.logger.debug( "create_jsinclude: Inserting in root.html at line {0} before '{1}'".format(insertln, iln_js) )
                +            twig_statement1 = "\t{% if isfile('widgets/sh_widgets/" + filename + "') %}"
                +            twig_statement2 = '\t\t<script type="text/javascript" src="widgets/sh_widgets/widget_' + classname + '.js"></script>{% endif %}'
                +            self.logger.debug('create_jsinclude: {0}'.format(twig_statement1))
                +            self.logger.debug('create_jsinclude: {0}'.format(twig_statement2))
                +            root_contents.insert(insertln, twig_statement2+'\n')
                +            root_contents.insert(insertln, twig_statement1+'\n')
                +
                +
                +    def create_cssinclude(self, filename, classname, root_contents, iln_css):
                +        insertln = root_contents.index(iln_css)
                +        # Insert widget statements to root_contents
                +        if insertln > -1:
                +            self.logger.debug( "create_jsinclude: Inserting in root.html at line {0} before '{1}'".format(insertln, iln_css) )
                +            twig_statement1 = "\t{% if isfile('widgets/sh_widgets/" + filename + "') %}"
                +            twig_statement2 = '\t\t<link rel="stylesheet" type="text/css" href="widgets/sh_widgets/widget_' + classname + '.css" />{% endif %}'
                +            self.logger.debug('create_cssinclude: {0}'.format(twig_statement1))
                +            self.logger.debug('create_cssinclude: {0}'.format(twig_statement2))
                +            root_contents.insert(insertln, twig_statement2+'\n')
                +            root_contents.insert(insertln, twig_statement1+'\n')
                +
                +
                +    def remove_oldfiles(self):
                +        # clear temp directory
                +        if not os.path.isdir(self.tmpdir):
                +            self.logger.warning("Could not find temp directory: {0}".format(self.tmpdir))
                +            return False
                +        for fn in os.listdir(self.tmpdir):
                +            if len(fn) != 2:  # only delete Twig temp files
                +                continue
                +            fp = os.path.join(self.tmpdir, fn)
                +            try:
                +                if os.path.isdir(fp):
                +                    shutil.rmtree(fp)
                +            except Exception as e:
                +                self.logger.warning("Could not delete directory {0}: {1}".format(fp, e))
                +            
                +        # create destination directory for widgets
                +        self.logger.debug("install_widgets: Creating  directory for widgets")
                +        try:
                +            os.mkdir(self.outdir)
                +        except:
                +            pass
                +
                +        if not os.path.isdir(self.outdir):
                +            self.logger.warning("Could not find or create directory for sh widgets: {0}".format(self.outdir))
                +            return False
                +
                +        # remove old dynamic widget files
                +        self.logger.debug("install_widgets: Removing old dynamic widget files")
                +        for fn in os.listdir(self.outdir):
                +            fp = os.path.join(self.outdir, fn)
                +            try:
                +                if os.path.isfile(fp):
                +                    os.unlink(fp)
                +            except Exception as e:
                +                self.logger.warning("Could not delete file {0}: {1}".format(fp, e))
                +
                +        return True
                +
                diff --git a/visu_smartvisu/README_for_developers.md b/visu_smartvisu/_pv_1_3_3/developer_doc.md
                old mode 100644
                new mode 100755
                similarity index 97%
                rename from visu_smartvisu/README_for_developers.md
                rename to visu_smartvisu/_pv_1_3_3/developer_doc.md
                index 5e7d5b6e4..47b5450ba
                --- a/visu_smartvisu/README_for_developers.md
                +++ b/visu_smartvisu/_pv_1_3_3/developer_doc.md
                @@ -1,4 +1,6 @@
                -# Visualisation plugin (smartVISU support) - for developers
                +# visu_smartvisu
                +
                +## Visualisation plugin (smartVISU support) - for developers
                 
                 ```
                 Copyright 2012-2013 Marcus Popp                  marcus@popp.mx
                diff --git a/visu_smartvisu/_pv_1_3_3/plugin.yaml b/visu_smartvisu/_pv_1_3_3/plugin.yaml
                new file mode 100755
                index 000000000..320a631b8
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/plugin.yaml
                @@ -0,0 +1,139 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'smartVISU Unterstützung: Autogenerierung von Seiten; Widget Handling'
                +        en: 'Support for smartVISU: Automatic generation of pages; widget handling'
                +    maintainer: msinn
                +    tester: psilo909
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Visu_Unterstuetzung        # url of documentation (wiki) page
                +
                +    version: 1.3.3                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: SmartVisu           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    smartvisu_dir:
                +        type: str
                +        description:
                +            de: 'Basisverzeichnis der smartVISU. Nur wenn dieser Wert konfiguriert ist, kann das Plugin Seiten für die smartVISU generieren.'
                +            en: 'You could generate pages for the smartVISU visualisation if you specify the smartvisu_dir which should be set to the root directory of your smartVISU installation.'
                +  
                +    generate_pages:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Falls True, werden Seiten für smartVISU generiert'
                +            en: 'If True, pages for smartVISU are generated'
                +  
                +    overwrite_templates:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Sollen in der smartVISU bereits existierende Templates überschrieben werden?'
                +            en: 'Should templates already that already exist in smartVISU bi overwritten?'
                +  
                +    visu_style:
                +        type: str
                +        default: std
                +        valid_list:
                +          - std
                +          - blk
                +        description:
                +            de: 'Benutzer Style für die generierten Visualisierungs-Seiten'
                +            en: 'Style used for the generated visualization'
                +  
                +    handle_widgets:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Standardmäßig werden Widgets aus den Plugins in die smartVISU kopiert und eingebunden. Dieses kann verhindert werden, wenn dieser Parameter auf False gesetzt wird.'
                +            en: 'By default, the visu plugin handles smartVISU widgets. If your run into problems, you can disable the widget handling by setting this attribute to False.'
                +    
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +#    visu_acl:    # defined in visu_websocket
                +#        type: bool
                +#        description:
                +#            de: ''
                +#            en: ''
                +    
                +    sv_page:
                +        type: str
                +        valid_list:
                +          - room
                +          - seperator
                +          - overview
                +          - category
                +          - cat_seperator
                +          - room_lite
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_overview:
                +        type: str
                +        description:
                +            de: ''
                +            en: 'If a page has defined sv_page as overview, it shows items of a specific type. The name/identifier of the type is defined by setting sv_overview to an unique name. For items to be displayed on this page, the items have to define sv_item_type and set it to the value of sv_overview.'
                +    
                +    sv_item_type:
                +        type: str
                +        description:
                +            de: ''
                +            en: 'sv_item_type allows items to be displayed on an overview page.'
                +    
                +    sv_img:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_widget:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_widget2:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_nav_aside:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_nav_aside2:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_left:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_center:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_right:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_1.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_1.jpg
                new file mode 100755
                index 000000000..c143401ca
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_1.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_2.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_2.jpg
                new file mode 100755
                index 000000000..e262d959e
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_2.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_visu.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_visu.jpg
                new file mode 100755
                index 000000000..2be614012
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/blocktype_dual_visu.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/category_nav.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/category_nav.jpg
                new file mode 100755
                index 000000000..798ddf880
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/category_nav.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/divider.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/divider.jpg
                new file mode 100755
                index 000000000..75c12950b
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/divider.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/navigation.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/navigation.jpg
                new file mode 100755
                index 000000000..892f42c9f
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/navigation.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/navigation2.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/navigation2.jpg
                new file mode 100755
                index 000000000..a9ca86db0
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/navigation2.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/style_blk.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/style_blk.jpg
                new file mode 100755
                index 000000000..af6beeb63
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/style_blk.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/style_blk_visu.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/style_blk_visu.jpg
                new file mode 100755
                index 000000000..d4d75c58f
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/style_blk_visu.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/screenshots/style_std.jpg b/visu_smartvisu/_pv_1_3_3/screenshots/style_std.jpg
                new file mode 100755
                index 000000000..acdafdaf3
                Binary files /dev/null and b/visu_smartvisu/_pv_1_3_3/screenshots/style_std.jpg differ
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/category.html b/visu_smartvisu/_pv_1_3_3/tplNG/category.html
                new file mode 100755
                index 000000000..ee05bf9aa
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/category.html
                @@ -0,0 +1,15 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß 
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "index.html" %}
                +
                +{% block content %}
                +	{% include 'category_nav.html' %}
                +{% endblock %}
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/category_page.html b/visu_smartvisu/_pv_1_3_3/tplNG/category_page.html
                new file mode 100755
                index 000000000..dbfa50e10
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/category_page.html
                @@ -0,0 +1,24 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "category.html" %}
                +
                +{% block sidebar %}
                +	{% include 'category_nav.html' %}
                +{% endblock %}
                +
                +{% block content %}
                +
                +	<h1><img class="icon" src='{{ icon0 }}{{ visu_img }}' />{{ visu_name }}</h1>
                +
                +	{{ visu_heading }}
                +	{{ visu_widgets }}
                +
                +{% endblock %}
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/heading.html b/visu_smartvisu/_pv_1_3_3/tplNG/heading.html
                new file mode 100755
                index 000000000..dc892a2da
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/heading.html
                @@ -0,0 +1,15 @@
                +<div class="preblock">
                +	<table width="100%">
                +		<tr>
                +			<td align="left">
                +				{{ visu_heading_left }}
                +			</td>
                +			<td align="center">
                +				{{ visu_heading_center }}
                +			</td>
                +			<td align="right">
                +				{{ visu_heading_right }}
                +			</td>
                +		</tr>
                +	</table>
                +</div>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/index.html b/visu_smartvisu/_pv_1_3_3/tplNG/index.html
                new file mode 100755
                index 000000000..e107a1db3
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/index.html
                @@ -0,0 +1,41 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "base.html" %}
                +
                +{% block sidebar %}
                +
                +	{% import "lib.html" as lib %}
                +	{{ lib.updatecheck() }}
                +
                +	{% import "clock.html" as clock %}
                +	{{ clock.digiclock('clock') }}
                +
                +	<div class="center">
                +		{{ now|smartdate('l') }}, {{ now|smartdate() }}
                +	</div>
                +
                +	<hr>
                +
                +	{% import "weather.html" as weather %}
                +	{{ weather.current('weather') }}
                +
                +	<hr>
                +
                +	{{ weather.forecastweek('weather_forecast') }}
                +
                +	<hr>
                +
                +{% endblock %}
                +
                +{% block content %}
                +	{% include 'room_nav.html' %}
                +{% endblock %}
                +
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/navi.html b/visu_smartvisu/_pv_1_3_3/tplNG/navi.html
                new file mode 100755
                index 000000000..bd8383b81
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/navi.html
                @@ -0,0 +1,9 @@
                +<li data-icon="false">
                +	<a href="index.php?page={{ visu_page }}">
                +		<img class="icon" src="{{ icon0 }}{{ visu_img }}" />
                +
                +		<h3>{{ visu_name }}</h3>
                +		<div class="ui-li-aside">{{ visu_aside }}<br/>{{ visu_aside2 }}</div>
                +	</a>
                +</li>
                +    
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/navi_sep.html b/visu_smartvisu/_pv_1_3_3/tplNG/navi_sep.html
                new file mode 100755
                index 000000000..90d958247
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/navi_sep.html
                @@ -0,0 +1 @@
                +<li data-role="list-divider">{{ name }}</li>
                \ No newline at end of file
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/navigation.html b/visu_smartvisu/_pv_1_3_3/tplNG/navigation.html
                new file mode 100755
                index 000000000..f4ab2946c
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/navigation.html
                @@ -0,0 +1,5 @@
                +<ul data-role="listview" data-dividertheme="c">
                +
                +	{{ visu_navis }}
                +
                +</ul>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/room.html b/visu_smartvisu/_pv_1_3_3/tplNG/room.html
                new file mode 100755
                index 000000000..e408dd0b0
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/room.html
                @@ -0,0 +1,21 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "rooms.html" %}
                +
                +{% block content %}
                +
                +	<h1><img class="icon" src='{{ icon0 }}{{ visu_img }}' />{{ visu_name }}</h1>
                +
                +	{{ visu_heading }}
                +	{{ visu_widgets }}
                +
                +{% endblock %}
                +
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/roomlite.html b/visu_smartvisu/_pv_1_3_3/tplNG/roomlite.html
                new file mode 100755
                index 000000000..5c433346f
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/roomlite.html
                @@ -0,0 +1,21 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "roomslite.html" %}
                +
                +{% block content %}
                +
                +	<h1><img class="icon" src='{{ icon0 }}{{ visu_img }}' />{{ visu_name }}</h1>
                +
                +	{{ visu_heading }}
                +	{{ visu_widgets }}
                +
                +{% endblock %}
                +
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/rooms.html b/visu_smartvisu/_pv_1_3_3/tplNG/rooms.html
                new file mode 100755
                index 000000000..5b39a651e
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/rooms.html
                @@ -0,0 +1,21 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "base.html" %}
                +
                +{% block sidebar %}
                +	{% include 'room_nav.html' %}
                +{% endblock %}
                +
                +{% block content %}
                +
                +	Rooms
                +
                +{% endblock %}
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/roomslite.html b/visu_smartvisu/_pv_1_3_3/tplNG/roomslite.html
                new file mode 100755
                index 000000000..235d6a862
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/roomslite.html
                @@ -0,0 +1,21 @@
                +/**
                +* -----------------------------------------------------------------------------
                +* @package     smartVISU
                +* @author      Martin Gleiß
                +* @copyright   2012
                +* @license     GPL [http://www.gnu.de]
                +* -----------------------------------------------------------------------------
                +*/
                +
                +
                +{% extends "base.html" %}
                +
                +{% block sidebar %}
                +	{% include 'roomlite_nav.html' %}
                +{% endblock %}
                +
                +{% block content %}
                +
                +	Rooms
                +
                +{% endblock %}
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_blk_std.html b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_blk_std.html
                new file mode 100755
                index 000000000..5f0481e3b
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_blk_std.html
                @@ -0,0 +1,14 @@
                +<div class="block">
                +	<div class="set-2" data-role="collapsible-set" data-theme="a" data-content-theme="a" data-mini="true" data-iconpos="right">
                +
                +		<div data-role="collapsible" data-collapsed="false">
                +			<h3>{{ visu_name }}</h3>
                +			{{ visu_widget }}
                +		</div>
                +
                +		<div data-role="collapsible">
                +			<h3>{{ visu_name2 }}</h3>
                +			{{ visu_widget2 }}
                +		</div>
                +	</div>
                +</div>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_std_std.html b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_std_std.html
                new file mode 100755
                index 000000000..c57185aa8
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock2_std_std.html
                @@ -0,0 +1,14 @@
                +<div class="block">
                +	<div class="set-2" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true">
                +
                +		<div data-role="collapsible" data-collapsed="false">
                +			<h3>{{ visu_name }}</h3>
                +			{{ visu_widget }}
                +		</div>
                +
                +		<div data-role="collapsible">
                +			<h3>{{ visu_name2 }}</h3>
                +			{{ visu_widget2 }}
                +		</div>
                +	</div>
                +</div>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_noh.html b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_noh.html
                new file mode 100755
                index 000000000..1605e96ae
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_noh.html
                @@ -0,0 +1,9 @@
                +<div class="block">
                +	<div class="set-2" data-role="collapsible-set" data-theme="a" data-content-theme="a" data-mini="true" data-iconpos="right">
                +
                +		<div data-role="collapsible" data-collapsed="false">
                +			{{ visu_widget }}
                +		</div>
                +
                +	</div>
                +</div>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_std.html b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_std.html
                new file mode 100755
                index 000000000..d8977913e
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_blk_std.html
                @@ -0,0 +1,10 @@
                +<div class="block">
                +	<div class="set-{{ blocksize }}" data-role="collapsible-set" data-theme="a" data-content-theme="a" data-mini="true" data-iconpos="right">
                +
                +		<div data-role="collapsible" data-collapsed="false">
                +			<h3>{{ visu_name }}</h3>
                +			{{ visu_widget }}
                +		</div>
                +
                +	</div>
                +</div>
                diff --git a/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_std_std.html b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_std_std.html
                new file mode 100755
                index 000000000..1a0d27a36
                --- /dev/null
                +++ b/visu_smartvisu/_pv_1_3_3/tplNG/widgetblock_std_std.html
                @@ -0,0 +1,10 @@
                +<div class="block">
                +	<div class="set-{{ blocksize }}" data-role="collapsible-set" data-theme="c" data-content-theme="a" data-mini="true">
                +
                +		<div data-role="collapsible" data-collapsed="false">
                +			<h3>{{ visu_name }}</h3>
                +			{{ visu_widget }}
                +		</div>
                +
                +	</div>
                +</div>
                diff --git a/visu_smartvisu/developer_doc.md b/visu_smartvisu/developer_doc.md
                new file mode 100755
                index 000000000..47b5450ba
                --- /dev/null
                +++ b/visu_smartvisu/developer_doc.md
                @@ -0,0 +1,85 @@
                +# visu_smartvisu
                +
                +## Visualisation plugin (smartVISU support) - for developers
                +
                +```
                +Copyright 2012-2013 Marcus Popp                  marcus@popp.mx
                +Copyright 2016- Martin Sinn                      m.sinn@gmx.de
                +
                +This plugin is part of SmartHomeNG.
                +  
                +Visit:  https://github.com/smarthomeNG/
                +        https://knx-user-forum.de/forum/supportforen/smarthome-py
                +```
                +
                +This file gives **smarthomeNG** developers additional information about the smartvisu plugin. For information about the configuration of the plugin refer to **README.md**.
                +
                +This file describes the widget handling for smartVISU widgets and the autogeneration of smartVISU pages.
                +
                +
                +## Files of the Plugin
                +The plugin is made up by several files, which are described below.
                +
                +
                +### __ init __.py
                +Main file of the plugin.
                +
                +### sv_widgets subdirectory
                +This directory stores general-use widgets, which are not specific to a plugin. These plugins are installed together with widgets from different plugins.
                +
                +### tplNG subdirectory
                +This directory stores template files, that are used while auto-generating pages for smartVISU. The files in this directory are copied to the pages/base/tplNG directory, which is created.
                +
                +## Handling of smartVISU widgets
                +The visu plugin handles widgets, which a plugin developer delivers with the plugin he has written. For this to work, the attribute **`smartvisu_dir`** in the visu section of **`plugin.conf`** must be set to the base directory of smartVISU. 
                +
                +It handles widgets that define their own Javascript or css. The Javascript and css files must follow the same naming convention as the html file.
                +
                +### Add a widget to a plugin
                +A developer of a plugin can add widgets to the plugin. He has to create a directory named **sv_widgets** in his plugin directory and add the file(s) of the widget to that directory.
                +
                +All files in the **sv_widgets** directory are copied to the smartVISU installation.
                +
                +A widget html-file may contain multiple widgets.
                +
                +For further automatic integration the widget must follow a name convention. It must be named **`widget_<class>.html`**. Where **`<class>`** is the class name for the import statement in smartVISU. If this convention is followed, a statement in the form of 
                +
                +```
                +	{% import "widget_<class>.html" as <class> %}
                +```
                +is generated. 
                +
                +**Example**:
                +>For a file **`widget_hue.html`** the statement
                +
                +>```
                +	{% import "widget_hue.html" as hue %}
                +```
                +is generated.
                +The widgets in that file can be called by the directives
                +
                +```
                +	{{ hue.control( ... ) }}
                + or
                +	{{ hue.control_group( ... ) }}
                +```
                +
                +If a Javascript file would exist for the hue widget, it would have to have the name  **`widget_hue.js`**. To include this file in smartVISU, the following lines are added to root.html:
                +>
                +>```
                +{% if isfile('widgets/sh_widgets/widget_hue.js') %}
                +	<script type="text/javascript" src="widgets/sh_widgets/widget_hue.js"></script>{% endif %}
                +```
                +
                +The handling of a css file is analog to the Javascript handling.
                +
                +
                +### Modifications to smartVISU made by the visu plugin
                +For this functionality to work, smarthome.py must have write access to the smartVISU directory structure. The modifications to smartVISU are minimal invasive. The implementation may change, if smartVISU is forked.
                +
                +The visu plugin creates a directory named **_sh_widgets** in the **widgets** directory of smartVISU. All files copied from the different plugins are stored in this directory.
                +
                +On the first run the visu plugin creates a copy of the file **root.html** in the **pages/base** directory of smartVISU. The copied file is called **root_master.html**.
                +
                +On each start of smarthome.py the visu plugin creates a new version of **root.html**. The new version is made of the contents of **root_master.html** and the necessary statements are inserted.
                +
                diff --git a/visu_smartvisu/plugin.yaml b/visu_smartvisu/plugin.yaml
                new file mode 100755
                index 000000000..6d32d9969
                --- /dev/null
                +++ b/visu_smartvisu/plugin.yaml
                @@ -0,0 +1,139 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'smartVISU Unterstützung: Autogenerierung von Seiten; Widget Handling'
                +        en: 'Support for smartVISU: Automatic generation of pages; widget handling'
                +    maintainer: msinn
                +    tester: psilo909
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Visu_Unterstuetzung        # url of documentation (wiki) page
                +
                +    version: 1.3.4                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: SmartVisu           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    smartvisu_dir:
                +        type: str
                +        description:
                +            de: 'Basisverzeichnis der smartVISU. Nur wenn dieser Wert konfiguriert ist, kann das Plugin Seiten für die smartVISU generieren.'
                +            en: 'You could generate pages for the smartVISU visualisation if you specify the smartvisu_dir which should be set to the root directory of your smartVISU installation.'
                +  
                +    generate_pages:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Falls True, werden Seiten für smartVISU generiert'
                +            en: 'If True, pages for smartVISU are generated'
                +  
                +    overwrite_templates:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Sollen in der smartVISU bereits existierende Templates überschrieben werden?'
                +            en: 'Should templates already that already exist in smartVISU bi overwritten?'
                +  
                +    visu_style:
                +        type: str
                +        default: std
                +        valid_list:
                +          - std
                +          - blk
                +        description:
                +            de: 'Benutzer Style für die generierten Visualisierungs-Seiten'
                +            en: 'Style used for the generated visualization'
                +  
                +    handle_widgets:
                +        type: bool
                +        default: True
                +        description:
                +            de: 'Standardmäßig werden Widgets aus den Plugins in die smartVISU kopiert und eingebunden. Dieses kann verhindert werden, wenn dieser Parameter auf False gesetzt wird.'
                +            en: 'By default, the visu plugin handles smartVISU widgets. If your run into problems, you can disable the widget handling by setting this attribute to False.'
                +    
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +#    visu_acl:    # defined in visu_websocket
                +#        type: bool
                +#        description:
                +#            de: ''
                +#            en: ''
                +    
                +    sv_page:
                +        type: str
                +        valid_list:
                +          - room
                +          - seperator
                +          - overview
                +          - category
                +          - cat_seperator
                +          - room_lite
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_overview:
                +        type: str
                +        description:
                +            de: ''
                +            en: 'If a page has defined sv_page as overview, it shows items of a specific type. The name/identifier of the type is defined by setting sv_overview to an unique name. For items to be displayed on this page, the items have to define sv_item_type and set it to the value of sv_overview.'
                +    
                +    sv_item_type:
                +        type: str
                +        description:
                +            de: ''
                +            en: 'sv_item_type allows items to be displayed on an overview page.'
                +    
                +    sv_img:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_widget:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_widget2:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_nav_aside:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_nav_aside2:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_left:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_center:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                +    sv_heading_right:
                +        type: str
                +        description:
                +            de: ''
                +            en: ''
                +    
                diff --git a/visu_smartvisu/tplNG/category.html b/visu_smartvisu/tplNG/category.html
                old mode 100644
                new mode 100755
                index 59d23a1b2..ee05bf9aa
                --- a/visu_smartvisu/tplNG/category.html
                +++ b/visu_smartvisu/tplNG/category.html
                @@ -8,33 +8,8 @@
                 */
                 
                 
                -{% extends "base.html" %}
                -
                -{% block sidebar %}
                -	{% include 'category_nav.html' %}
                -{% endblock %}
                +{% extends "index.html" %}
                 
                 {% block content %}
                -
                -	Category Content
                -
                -	<h1><img class="icon" src='{{ icon0 }}time_manual_mode.svg' />Konfiurationen</h1>
                -	<a href="index.php?page=wohnung.config">Konfiguration</a>&nbsp;
                -	<a href="index.php?page=beschattung">Beschattung</a>&nbsp;
                -	<a href="index.php?page=beleuchtung">Beleuchtungsautomatik</a>&nbsp;
                -	<a href="index.php?page=wohnung.verteilung">Verteilung</a>&nbsp;
                -	<a href="index.php?page=mlgw">B&O Masterlink Gateway</a>&nbsp;
                -	<a href="index.php?page=beoremote">Lintronic - Beo4 Remote</a>&nbsp;
                -	<a href="index.php?page=sonos_bo">Sonos Musiksystgem</a>&nbsp;
                -	<br>
                -
                -	<h1><img class="icon" src='{{ icon0 }}time_manual_mode.svg' />Kategorien</h1>
                -	<a href="index.php?page=sun_moon">Sonne & Mond</a>&nbsp;
                -	<a href="index.php?page=wetter">Wetter (Wunderground)</a>&nbsp;
                -	<a href="index.php?page=wohnung.stati">Wohnungs-Helligkeiten</a>&nbsp;
                -	<a href="index.php?page=category_phone">Telefonliste</a>&nbsp;
                -	<a href="index.php?page=category_calendar">Terminkalender</a>&nbsp;
                -
                +	{% include 'category_nav.html' %}
                 {% endblock %}
                -
                -
                diff --git a/visu_smartvisu/tplNG/category_page.html b/visu_smartvisu/tplNG/category_page.html
                index e20c620a1..dbfa50e10 100755
                --- a/visu_smartvisu/tplNG/category_page.html
                +++ b/visu_smartvisu/tplNG/category_page.html
                @@ -10,6 +10,10 @@
                 
                 {% extends "category.html" %}
                 
                +{% block sidebar %}
                +	{% include 'category_nav.html' %}
                +{% endblock %}
                +
                 {% block content %}
                 
                 	<h1><img class="icon" src='{{ icon0 }}{{ visu_img }}' />{{ visu_name }}</h1>
                @@ -18,4 +22,3 @@ <h1><img class="icon" src='{{ icon0 }}{{ visu_img }}' />{{ visu_name }}</h1>
                 	{{ visu_widgets }}
                 
                 {% endblock %}
                -
                diff --git a/visu_websocket/README.md b/visu_websocket/README.md
                index 87106c415..066bb0c37 100644
                --- a/visu_websocket/README.md
                +++ b/visu_websocket/README.md
                @@ -1,4 +1,4 @@
                -# Visualisation plugin (Websocket Protocol)
                +# Visualisation (Websocket Protocol)
                 
                 ```
                  
                @@ -61,6 +61,9 @@ The version of the web socket protocol can be specified. By default the plugin u
                 #### acl
                 The plugin provides by default read only (**`ro`**) access to every item. By changing the **`acl`** attribute to **`rw`** you could modify this default behaviour to gain write access to the items in smarthomeNG.
                 
                +#### querydef
                +If set to True, the plugin can be queried by a websocket client (a visu) for the item- and logic-definitions.
                +
                 
                 ### items.conf (deprecated) / items.yaml
                 
                diff --git a/visu_websocket/__init__.py b/visu_websocket/__init__.py
                index ff2d76121..b6219b191 100755
                --- a/visu_websocket/__init__.py
                +++ b/visu_websocket/__init__.py
                @@ -1,8 +1,8 @@
                 #!/usr/bin/env python3
                 # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                 #########################################################################
                -#  Copyright 2012-2013 Marcus Popp                         marcus@popp.mx
                 #  Copyright 2016- Martin Sinn                              m.sinn@gmx.de
                +#  Copyright 2012-2013 Marcus Popp                         marcus@popp.mx
                 #########################################################################
                 #  This file is part of SmartHomeNG.  
                 #  Visit:  https://github.com/smarthomeNG/
                @@ -33,6 +33,8 @@
                 import struct
                 import threading
                 
                +import collections
                +
                 import lib.connection
                 from lib.model.smartplugin import SmartPlugin
                 
                @@ -41,65 +43,74 @@
                 
                 class WebSocket(SmartPlugin):
                     """
                -    Main class of the Plugin. Does the plugin specific stuff.
                +    Main class of the Plugin. Does all plugin specific stuff and provides
                +    the update functions for the items
                     """
                -    PLUGIN_VERSION = "1.1.3"
                -    ALLOW_MULTIINSTANCE = False
                -
                -    def my_to_bool(self, value, attr='', default=False):
                -        try:
                -            result = self.to_bool(value)
                -        except:
                -            result = default
                -            self.logger.error("WebSocket: Invalid value '"+str(value)+"' configured for attribute "+attr+" in plugin.conf, using '"+str(result)+"' instead")
                -        return result
                 
                +    PLUGIN_VERSION = "1.4.4"
                 
                -    def __init__(self, smarthome, ip='0.0.0.0', port=2424, tls='no', acl='ro', wsproto='3' ):
                -        self.logger = logging.getLogger(__name__)
                -        self._sh = smarthome
                 
                -#        if not self.is_ip(ip):
                -#            self.logger.error("WebSocket: Invalid value '"+str(ip)+"' configured for attribute ip in plugin.conf, using '"+str('0.0.0.0')+"' instead")
                -#            ip = '0.0.0.0'
                -
                -        if self.is_int(port):
                -        	self.port = int(port)
                -        else:
                -            self.port = 2424
                -            self.logger.error("WebSocket: Invalid value '"+str(port)+"' configured for attribute port in plugin.conf, using '"+str(self.port)+"' instead")
                +    def __init__(self, sh, *args, **kwargs):
                +#    def __init__(self, smarthome, ip='0.0.0.0', port=2424, tls='no', acl='ro', wsproto='3' ):
                +        """
                +        Initalizes the plugin. The parameters describe for this method are pulled from the entry in plugin.conf.
                 
                -        self.tls = self.my_to_bool(tls, 'tls', False)
                +        If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
                +        a reference to the sh object any more.
                +        
                +        The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are implemented
                +        to support oder plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values:
                +        use the SmartPlugin method `get_parameter_value(parameter_name)` instead. Anywhere within the Plugin you can get
                +        the configured (and checked) value for a parameter by calling `self.get_parameter_value(parameter_name)`. It
                +        returns the value in the datatype that is defined in the metadata.
                +        """
                +        self.logger = logging.getLogger(__name__)
                 
                -        if acl.lower() in ('true', 'yes', 'rw'):
                -            self._acl = 'rw'
                -        elif acl.lower() == 'ro': 
                -            self._acl = 'ro'
                -        else:
                -            self._acl = 'ro'
                -            self.logger.error("WebSocket: Invalid value '"+str(alc)+"' configured for attribute acl in plugin.conf, using '"+str(self.acl)+"' instead")
                +        # get the parameters for the plugin (as defined in metadata plugin.yaml):
                +        #   self.param1 = self.get_parameter_value('param1')
                +        self.ip = self.get_parameter_value('ip')
                +        self.port = self.get_parameter_value('port')
                +        self.tls = self.get_parameter_value('tls')
                +        self.acl = self.get_parameter_value('acl')
                +        self.wsproto = self.get_parameter_value('wsproto')
                +        self.querydef = self.get_parameter_value('querydef')
                 
                -        if self.is_int(wsproto):
                -        	proto = int(wsproto)
                -        else:
                -            proto = 3
                -            self.logger.error("WebSocket: Invalid value '"+str(wsproto)+"' configured for attribute wsproto in plugin.conf, using '"+str(proto)+"' instead")
                +        if self.acl in ('true', 'yes'):
                +            self.acl = 'rw'
                 
                -        self.websocket = _websocket(smarthome, ip, port, self.tls, proto)
                +        self.websocket = _websocket(self.get_sh(), self.ip, self.port, self.tls, self.wsproto, self.querydef)
                +        return
                         
                 
                     def run(self):
                +        """
                +        Run method for the plugin - called once to start the plugins processing
                +        """        
                         self.alive = True
                -        self._sh.scheduler.add('series', self.websocket._update_series, cycle=10, prio=5)
                +        self.scheduler_add('series', self.websocket._update_series, cycle=10, prio=5)
                +        return
                 
                 
                     def stop(self):
                +        """
                +        Stop method for the plugin
                +        """
                         self.alive = False
                         self.websocket.stop()
                +        return
                 
                 
                     def parse_item(self, item):
                -        acl = self._acl
                +        """
                +        Plugin's parse_item method. Is called for every item when the plugin is initialized.
                +        
                +        :param item:    The item to process.
                +        :return:        If the plugin needs to be informed of an items change you should return a call back function
                +                        like the function update_item down below. 
                +                        This means that when the items value is about to be updated, the call back function is called
                +                        with the item, caller, source and dest as arguments.
                +        """
                +        acl = self.acl
                         if 'visu_acl' in item.conf:
                             if item.conf['visu_acl'].lower() in ('true', 'yes', 'rw'):
                                 acl = 'rw'
                @@ -111,19 +122,43 @@ def parse_item(self, item):
                         return self.update_item
                 
                 
                +    def parse_logic(self, logic):
                +        """
                +        Plugin's parse_logic method
                +        """
                +#        if hasattr(logic, 'visu_acl'):
                +#            if logic.conf['visu_acl'].lower() in ('true', 'yes', 'rw'):
                +#                self.websocket.visu_logics[logic.name] = logic
                +        return
                +
                +
                     def update_item(self, item, caller=None, source=None, dest=None):
                +        """
                +        Write items values
                +        
                +        :param item: item to be updated towards the plugin
                +        :param caller: if given it represents the callers name
                +        :param source: if given it represents the source
                +        :param dest: if given it represents the dest
                +        """
                         self.websocket.update_item(item.id(), item(), source)
                +        return
                +        
                 
                     def url(self, url, clientip=''):
                +        """
                +        Tell the websocket client (visu) to load a specific url
                +        """
                         self.websocket.url(url, clientip)
                -		
                -    def parse_logic(self, logic):
                -        if hasattr(logic, 'visu_acl'):
                -            if logic.conf['visu_acl'].lower() in ('true', 'yes', 'rw'):
                -                self.websocket.visu_logics[logic.name] = logic
                -
                +        return
                 
                +		
                     def return_clients(self):
                +        """
                +        Returns connected clients
                +        
                +        :return: list of dicts with client information 
                +        """
                         for client in self.websocket.clients:
                             infos = {}
                             infos['addr'] = client.addr
                @@ -132,20 +167,10 @@ def return_clients(self):
                             infos['hostname'] = client.hostname
                             infos['browser'] = client.browser
                             infos['browserversion'] = client.browserversion
                -            if self.PLUGIN_VERSION == "1.1.2":
                -                yield client.addr			# v1.1.2
                -            else:
                -                # v1.1.3 and up
                -                yield infos
                -
                -#    def return_clients(self):
                -#        for client in self.websocket.clients:
                -#            if self.PLUGIN_VERSION == "1.1.2":
                -#                yield client.addr			# v1.1.2
                -#            else:
                -#                # v1.1.3 and up
                -#                yield client.addr, client.sw, client.swversion, client.hostname, client.browser, client.browserversion
                 
                +            yield infos
                +        return
                +        
                 
                 #########################################################################
                 
                @@ -154,13 +179,14 @@ class _websocket(lib.connection.Server):
                     Websocket specific class of the Plugin. Handles the websocket connections
                     """
                 
                -    def __init__(self, smarthome, ip, port, tls, wsproto ):
                +    def __init__(self, sh, ip, port, tls, wsproto, querydef ):
                         lib.connection.Server.__init__(self, ip, port)
                         self.logger = logging.getLogger(__name__)
                -        self._sh = smarthome
                +        self._sh = sh
                         self.tls = tls
                         self.proto = wsproto
                -        smarthome.add_event_listener(['log'], self._send_event)
                +        self.querydef = querydef
                +        self._sh.add_event_listener(['log'], self._send_event)
                         self.clients = []
                         self.visu_items = {}
                         self.visu_logics = {}
                @@ -168,9 +194,13 @@ def __init__(self, smarthome, ip, port, tls, wsproto ):
                         self.tls_crt = '/usr/local/smarthome/etc/home.crt'
                         self.tls_key = '/usr/local/smarthome/etc/home.key'
                         self.tls_ca = '/usr/local/smarthome/etc/ca.crt'
                +        return
                 
                 
                     def return_clients(self):
                +        """
                +        Returns connected websocket clients to the plugin
                +        """
                         for client in self.clients:
                             yield client.addr
                 
                @@ -189,7 +219,7 @@ def handle_connection(self):
                             except Exception as e:
                                 self.logger.exception(e)
                                 return
                -        client = websockethandler(self._sh, self, sock, address, self.visu_items, self.visu_logics, self.proto)
                +        client = websockethandler(self._sh, self, sock, address, self.visu_items, self.visu_logics, self.proto, self.querydef)
                         self.clients.append(client)
                 
                     def stop(self):
                @@ -253,7 +283,7 @@ class websockethandler(lib.connection.Stream):
                     Websocket handler class of the Plugin. Each instance handles one client connection
                     """
                 
                -    def __init__(self, smarthome, dispatcher, sock, addr, items, logics, proto=4):
                +    def __init__(self, smarthome, dispatcher, sock, addr, items, visu_logics, proto, querydef):
                         lib.connection.Stream.__init__(self, sock, addr)
                         self.terminator = b"\r\n\r\n"
                         self.logger = logging.getLogger(__name__)
                @@ -268,10 +298,11 @@ def __init__(self, smarthome, dispatcher, sock, addr, items, logics, proto=4):
                         self.items = items
                         self.rrd = False
                         self.log = False
                -        self.logs = smarthome.return_logs()
                +        self.logs = self._sh.return_logs()
                         self._series_lock = threading.Lock()
                -        self.logics = logics
                +        self.visu_logics = visu_logics
                         self.proto = proto
                +        self.querydef = querydef
                         self.logger.info("VISU: Websocket handler uses protocol version {0}".format(self.proto))
                         self.sw = ''
                         self.swversion = ''
                @@ -279,6 +310,11 @@ def __init__(self, smarthome, dispatcher, sock, addr, items, logics, proto=4):
                         self.browser = ''
                         self.browserversion = ''
                         
                +        # get access to the logics api
                +        from lib.logic import Logics
                +        self.logics = Logics.get_instance()
                +        return
                +        
                 
                     def send_event(self, event, data):
                         data = data.copy()  # don't filter the orignal data dict
                @@ -331,7 +367,15 @@ def update_series(self):
                     def difference(self, a, b):
                         return list(set(b).difference(set(a)))
                 
                +
                     def json_parse(self, data):
                +        """
                +        Parse the received request
                +        
                +        :param data: json data structure with the request
                +        :type data: json structure
                +        
                +        """
                         self.logger.debug("{0} sent {1}".format(self.addr, repr(data)))
                         try:
                             data = json.loads(data)
                @@ -339,6 +383,7 @@ def json_parse(self, data):
                             self.logger.debug("Problem decoding {0} from {1}: {2}".format(repr(data), self.addr, e))
                             return
                         command = data['cmd']
                +        
                         if command == 'item':
                             path = data['id']
                             value = data['val']
                @@ -349,6 +394,7 @@ def json_parse(self, data):
                                     self.logger.warning("Client {0} want to update read only item: {1}".format(self.addr, path))
                             else:
                                 self.logger.warning("Client {0} want to update invalid item: {1}".format(self.addr, path))
                +                
                         elif command == 'monitor':
                             if data['items'] == [None]:
                                 return
                @@ -358,31 +404,13 @@ def json_parse(self, data):
                                     items.append([path, self.items[path]['item']()])
                                 else:
                                     self.logger.warning("Client {0} requested invalid item: {1}".format(self.addr, path))
                -            self.logger.debug("VISU json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'item', 'items': items})))	# MSinn
                +            self.logger.debug("json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'item', 'items': items})))	# MSinn
                             self.json_send({'cmd': 'item', 'items': items})
                             self.monitor['item'] = data['items']
                -        elif command == 'ping':
                -            self.logger.debug("VISU json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'pong'})))
                -            self.json_send({'cmd': 'pong'})
                +            
                         elif command == 'logic':
                -            if 'name' not in data:
                -                return
                -            name = data['name']
                -            if name in self.logics:
                -                if 'val' in data:
                -                    value = data['val']
                -                    self.logger.info("Client {0} triggerd logic {1} with '{2}'".format(self.addr, name, value))
                -                    self.logics[name].trigger(by='Visu', value=value, source=self.addr)
                -                if 'enabled' in data:
                -                    if data['enabled']:
                -                        self.logger.info("Client {0} enabled logic {1}".format(self.addr, name))
                -                        self.logics[name].enable()
                -                    else:
                -                        self.logger.info("Client {0} disabled logic {1}".format(self.addr, name))
                -                        self.logics[name].disable()
                -            else:
                -#                self.logger.warning("VISU: Defined logics {0}".format(self.logics))
                -                self.logger.warning("Client {0} requested invalid logic: {1}".format(self.addr, name))
                +            self.request_logic(data)
                +
                         elif command == 'series':
                             path = data['item']
                             series = data['series']
                @@ -399,7 +427,6 @@ def json_parse(self, data):
                                 if hasattr(self.items[path]['item'], 'series'):
                                     try:
                                         reply = self.items[path]['item'].series(series, start, end, count)
                -#                        self.logger.warning("VISU json_parse: send to {0}: {1}".format(self.addr, reply))	# MSinn
                                     except Exception as e:
                                         self.logger.error("Problem fetching series for {0}: {1} - Wrong sqlite plugin?".format(path, e))
                                     else:
                @@ -415,6 +442,7 @@ def json_parse(self, data):
                                             self.logger.info("WebSocket: no entries for series {} {}".format(path, series))
                                 else:
                                     self.logger.warning("Client {0} requested invalid series: {1}.".format(self.addr, path))
                +                    
                         elif command == 'log':
                             self.log = True
                             name = data['name']
                @@ -427,6 +455,11 @@ def json_parse(self, data):
                                 self.logger.warning("Client {0} requested invalid log: {1}".format(self.addr, name))
                             if name not in self.monitor['log']:
                                 self.monitor['log'].append(name)
                +                
                +        elif command == 'ping':
                +            self.logger.debug("json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'pong'})))
                +            self.json_send({'cmd': 'pong'})
                +            
                         elif command == 'proto':  # protocol version
                             proto = data['ver']
                             if proto > self.proto:
                @@ -435,6 +468,7 @@ def json_parse(self, data):
                                 self.logger.warning("WebSocket: protocol mismatch. Update your client: {0}".format(self.addr))
                             self.json_send({'cmd': 'proto', 'ver': self.proto, 'time': self._sh.now()})
                 #            self.logger.warning("VISU json_parse: send to {0}: {1}".format(self.addr, "{'cmd': 'proto', 'ver': " + str(self.proto) + ", 'time': " + str(self._sh.now()) + "}"))
                +
                         elif command == 'identity':  # identify client
                             self.sw = data.get('sw','')
                             self.swversion = data.get('ver','')
                @@ -443,6 +477,107 @@ def json_parse(self, data):
                             self.browserversion = data.get('bver','')
                             self.logger.debug("VISU json_parse: received 'identify' from {0}: {1}".format(self.addr, data))
                 
                +        elif command == 'list_items':
                +            if self.querydef:
                +                path = data.get('path', '')
                +                response = self.request_list_items(path)
                +                self.json_send(response)
                +
                +        elif command == 'list_logics':
                +            if self.querydef:
                +                enabled = data.get('enabled', 0)
                +                response = self.request_list_logics((enabled==1))
                +                self.json_send(response)
                +
                +        else:
                +            self.json_send({'cmd': command, 'error': 'Unknown Command'})
                +        return
                +        
                +
                +    def request_list_items(self, path):
                +        """
                +        Build the requested list of logics
                +        """
                +        self.logger.info("Client {0} requested a list of defined items.".format(self.addr))
                +        myitems = []
                +        for i in self._sh.return_items():
                +            include = False
                +#            if i.get('visu_acl', '').lower() != 'no': 
                +            if (path == '') and (not '.' in i._path):
                +                include = True
                +            else:
                +                if i._path.startswith(path+'.'):
                +                    p = i._path[len(path+'.'):]
                +                    if not '.' in p:
                +                        include = True
                +            if include:
                +                myitem = collections.OrderedDict()
                +                myitem['path'] = i._path
                +                myitem['name'] = i._name
                +                myitem['type'] = i.type()
                +                myitems.append(myitem)
                +
                +        response = collections.OrderedDict([('cmd','list_items'), ('items',myitems)])
                +        self.logger.info("Requested a list of defined items: {}".format(response))
                +        return response
                +
                +
                +    def request_logic(self, data):
                +        """
                +        Request logic (trigger, enable, disable)
                +        """
                +        if 'name' not in data:
                +            return
                +        name = data['name']
                +        mylogic = self.logics.return_logic(name)
                +        if mylogic is not None:
                +            linfo = self.logics.get_logic_info(name)
                +            if linfo['visu_access']:
                +                if 'val' in data:
                +                    value = data['val']
                +                    self.logger.info("Client {0} triggerd logic {1} with '{2}'".format(self.addr, name, value))
                +                    mylogic.trigger(by='Visu', value=value, source=self.addr)
                +                if 'enabled' in data:
                +                    if data['enabled']:
                +                        self.logger.info("Client {0} enabled logic {1}".format(self.addr, name))
                +                        self.logics.enable_logic(name)
                +                        # non-persistant enable
                +                        #self.visu_logics[name].enable()
                +                    else:
                +                        self.logger.info("Client {0} disabled logic {1}".format(self.addr, name))
                +                        self.logics.disable_logic(name)
                +                        # non-persistant disable
                +                        #self.visu_logics[name].disable()
                +            else:
                +                self.logger.warning("Client {0} requested logic without visu-access: {1}".format(self.addr, name))
                +        else:
                +            self.logger.warning("Client {0} requested invalid logic: {1}".format(self.addr, name))
                +
                +
                +    def request_list_logics(self, enabled):
                +        """
                +        Build the requested list of logics
                +        """
                +        self.logger.info("Client {0} requested a list of defined logics.".format(self.addr))
                +        logiclist = []
                +        for l in self.logics.return_loaded_logics():
                +            linfo = self.logics.get_logic_info(l)
                +            if linfo['visu_access']:
                +                if linfo['userlogic']:
                +                    logic_def = collections.OrderedDict()
                +                    logic_def['name'] = l
                +                    logic_def['desc'] = linfo['description']
                +                    logic_def['enabled'] = 1
                +                    if not linfo['enabled']:
                +                        logic_def['enabled'] = 0
                +                    if (not enabled) or (logic_def['enabled'] == 1):
                +                        logiclist.append(logic_def)
                +        
                +        response = collections.OrderedDict([('cmd','list_logics'), ('logics',logiclist)])
                +        self.logger.info("Requested a list of defined logics: {}".format(response))
                +        return response
                +        
                +
                     def parse_header(self, data):
                         data = bytes(data)
                         for line in data.splitlines():
                @@ -515,7 +650,11 @@ def rfc6455_parse(self, data):
                                 payload[i] ^= key[i % 4]
                         else:
                             payload = data[header:]
                -        self.json_parse(payload.decode())
                +
                +        try:
                +            self.json_parse(payload.decode())
                +        except Exception as e:
                +            self.logger.exception("_websocket.json_parse exception: {}".format(e))
                         self.terminator = 8
                 
                     def rfc6455_send(self, data):
                @@ -546,7 +685,10 @@ def hixie76_send(self, data):
                         self.send(packet)
                 
                     def hixie76_parse(self, data):
                -        self.json_parse(data.decode().lstrip('\x00'))
                +        try:
                +            self.json_parse(data.decode().lstrip('\x00'))
                +        except Exception as e:
                +            self.logger.exception("_websocket.json_parse exception: {}".format(e))
                 
                     def hixie76_handshake(self, key3):
                         self.logger.debug("Hixie76 Handshake")
                diff --git a/visu_websocket/_pv_1_1_3/README.md b/visu_websocket/_pv_1_1_3/README.md
                new file mode 100755
                index 000000000..342195877
                --- /dev/null
                +++ b/visu_websocket/_pv_1_1_3/README.md
                @@ -0,0 +1,159 @@
                +# Visualisation plugin (Websocket Protocol)
                +
                +```
                + 
                +Copyright 2012-2013 Marcus Popp                  marcus@popp.mx
                +Copyright 2016- Martin Sinn                      m.sinn@gmx.de
                +
                +This plugin is part of SmartHomeNG.
                +  
                +Visit:  https://github.com/smarthomeNG/
                +        https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +```
                +
                +This plugin provides an WebSocket interface for the smartVISU visualisation framework.
                +Right now the WebSocket interface only supports unencrypted connections. Please use a internal network or VPN to connect to the service.
                +
                +## Requirements
                +smarthomeNG version above v1.1.
                +
                +## Configuration
                +The configuration of the plugin itself is done in the file **`etc/plugin.conf`**. The configuration of the visualization of the items is done by defining additional attributes of the item in the file **`items/*.conf`**.
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +<pre>
                +[visu]
                +    class_name = WebSocket
                +    class_path = plugins.visu_websocket
                +#    ip='0.0.0.0'
                +#    port=2424
                +#    tls = no
                +#    wsproto = 3
                +#    acl = ro
                +</pre>
                +
                +<pre>
                +visu:
                +    class_name: WebSocket
                +    class_path: plugins.visu_websocket
                +    # ip='0.0.0.0'
                +    # port=2424
                +    # tls = no
                +    # wsproto = 3
                +    # acl = ro
                +</pre>
                +
                +#### ip
                +This plugins listens by default on every IP address of the host.
                +
                +#### port
                +This plugins listens by default  on the TCP port 2424.
                +
                +#### tls
                +Encryption can be turned on by this parameter. 
                +
                +--> Details are documented later
                +
                +#### wsproto
                +The version of the web socket protocol can be specified. By default the plugin uses version 3. For smartVISU version > v2.7 the web socket protocol has to be set to 0 or 4 (depending on the time the v2.8 pre-release of smartVISU was checked out of github).
                +
                +#### acl
                +The plugin provides by default read only (**`ro`**) access to every item. By changing the **`acl`** attribute to **`rw`** you could modify this default behaviour to gain write access to the items in smarthomeNG.
                +
                +
                +### items.conf (deprecated) / items.yaml
                +
                +#### visu_acl
                +Simply set the **`visu_acl`** attribute to **`rw`** to allow read/write access to the specific item.
                +Other valid values are **`ro`** for readonly access and **`deny`** to disallow access to that item.
                +
                +#### Example
                +<pre>
                +[second]
                +    [[sleeping]]
                +        name = Sleeping Room
                +        [[[light]]]
                +            name = Light
                +            type = bool
                +            visu_acl = rw
                +            knx_dpt = 1
                +            knx_listen = 3/2/12
                +            knx_send = 3/2/12
                +            [[[[level]]]]
                +                type = num
                +                visu_acl = rw
                +                knx_dpt = 5
                +                knx_listen = 3/2/14
                +                knx_send = 3/2/14
                +</pre>
                +
                +<pre>
                +second:
                +
                +    sleeping:
                +        name: Sleeping Room
                +
                +        light:
                +            name: Light
                +            type: bool
                +            visu_acl: rw
                +            knx_dpt: 1
                +            knx_listen: 3/2/12
                +            knx_send: 3/2/12
                +
                +            level:
                +                type: num
                +                visu_acl: rw
                +                knx_dpt: 5
                +                knx_listen: 3/2/14
                +                knx_send: 3/2/14
                +</pre>
                +
                +### logic.conf (deprecated) / logic.yaml
                +You could specify the **`visu_acl`** attribute to every logic in your logic.conf. This way you could trigger the logic via the interface.
                +
                +<pre>
                +[dialog]
                +    filename = 'dialog.py'
                +    visu_acl = true
                +</pre>
                +
                +<pre>
                +dialog:
                +    filename: dialog.py
                +    visu_acl: 'true'
                +</pre>
                +
                +## Functions
                +
                +### url(url)
                +
                +--> This command works with **smartVISU 2.9** and up, for **smartVISU 2.8** a modified driver **`io_smarthome.py`** is needed.
                +
                +This function instructs the smartVISU clients to change to the specified url (visu page).
                +
                +Example:
                +
                +```
                +	sh.visu.url('index.php')
                +```
                +
                +This function call expects the visu_websocket plugin to be configured in a section named **`visu`** in the configuration file **`etc/plugin.yaml`** or **`etc/plugin.conf`**.
                +
                +It instructs all running visu clients to change to the main page.
                +
                +
                +### url(url, ip)
                +
                +--> This command works with **smartVISU 2.9** and up, for **smartVISU 2.8** a modified driver **`io_smarthome.py`** is needed.
                +
                +Function is the same as above, but only clients (browsers) running on a host with the specified ip address are instructed to change the page.
                +
                +Example:
                +
                +```
                +	sh.visu.url('index.php?page=apartement.living', '10.0.0.23')
                +```
                +
                +This command expects the visu_websocket plugin to be configured in a section named **`visu`** in the configuration file **`etc/plugin.yaml`** or **`etc/plugin.conf`**.
                diff --git a/visu_websocket/README_for_visu_developers.md b/visu_websocket/_pv_1_1_3/README_for_visu_developers.md
                old mode 100644
                new mode 100755
                similarity index 99%
                rename from visu_websocket/README_for_visu_developers.md
                rename to visu_websocket/_pv_1_1_3/README_for_visu_developers.md
                index 5ddd7f4a0..91152e3aa
                --- a/visu_websocket/README_for_visu_developers.md
                +++ b/visu_websocket/_pv_1_1_3/README_for_visu_developers.md
                @@ -271,4 +271,3 @@ The following command instructs smartVISU to change to the main page:
                 
                 The smartVISU client does not send an answer to the **`url`** command.
                 
                -
                diff --git a/visu_websocket/_pv_1_1_3/__init__.py b/visu_websocket/_pv_1_1_3/__init__.py
                new file mode 100755
                index 000000000..a1707c749
                --- /dev/null
                +++ b/visu_websocket/_pv_1_1_3/__init__.py
                @@ -0,0 +1,590 @@
                +#!/usr/bin/env python3
                +# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                +#########################################################################
                +#  Copyright 2012-2013 Marcus Popp                         marcus@popp.mx
                +#  Copyright 2016- Martin Sinn                              m.sinn@gmx.de
                +#########################################################################
                +#  This file is part of SmartHomeNG.  
                +#  Visit:  https://github.com/smarthomeNG/
                +#          https://knx-user-forum.de/forum/supportforen/smarthome-py
                +#
                +#  SmartHomeNG is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  SmartHomeNG is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +import base64
                +import datetime
                +import decimal
                +import hashlib
                +import json
                +import logging
                +import struct
                +import ssl
                +import struct
                +import threading
                +
                +import lib.connection
                +from lib.model.smartplugin import SmartPlugin
                +
                +
                +#########################################################################
                +
                +class WebSocket(SmartPlugin):
                +    """
                +    Main class of the Plugin. Does the plugin specific stuff.
                +    """
                +    PLUGIN_VERSION = "1.1.3"
                +    ALLOW_MULTIINSTANCE = False
                +
                +    def my_to_bool(self, value, attr='', default=False):
                +        try:
                +            result = self.to_bool(value)
                +        except:
                +            result = default
                +            self.logger.error("WebSocket: Invalid value '"+str(value)+"' configured for attribute "+attr+" in plugin.conf, using '"+str(result)+"' instead")
                +        return result
                +
                +
                +    def __init__(self, smarthome, ip='0.0.0.0', port=2424, tls='no', acl='ro', wsproto='3' ):
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +
                +#        if not self.is_ip(ip):
                +#            self.logger.error("WebSocket: Invalid value '"+str(ip)+"' configured for attribute ip in plugin.conf, using '"+str('0.0.0.0')+"' instead")
                +#            ip = '0.0.0.0'
                +
                +        if self.is_int(port):
                +        	self.port = int(port)
                +        else:
                +            self.port = 2424
                +            self.logger.error("WebSocket: Invalid value '"+str(port)+"' configured for attribute port in plugin.conf, using '"+str(self.port)+"' instead")
                +
                +        self.tls = self.my_to_bool(tls, 'tls', False)
                +
                +        if acl.lower() in ('true', 'yes', 'rw'):
                +            self._acl = 'rw'
                +        elif acl.lower() == 'ro': 
                +            self._acl = 'ro'
                +        else:
                +            self._acl = 'ro'
                +            self.logger.error("WebSocket: Invalid value '"+str(alc)+"' configured for attribute acl in plugin.conf, using '"+str(self.acl)+"' instead")
                +
                +        if self.is_int(wsproto):
                +        	proto = int(wsproto)
                +        else:
                +            proto = 3
                +            self.logger.error("WebSocket: Invalid value '"+str(wsproto)+"' configured for attribute wsproto in plugin.conf, using '"+str(proto)+"' instead")
                +
                +        self.websocket = _websocket(smarthome, ip, port, self.tls, proto)
                +        
                +
                +    def run(self):
                +        self.alive = True
                +        self._sh.scheduler.add('series', self.websocket._update_series, cycle=10, prio=5)
                +
                +
                +    def stop(self):
                +        self.alive = False
                +        self.websocket.stop()
                +
                +
                +    def parse_item(self, item):
                +        acl = self._acl
                +        if 'visu_acl' in item.conf:
                +            if item.conf['visu_acl'].lower() in ('true', 'yes', 'rw'):
                +                acl = 'rw'
                +            elif item.conf['visu_acl'].lower() in ('deny', 'no'):
                +                return
                +            else:
                +                acl = 'ro'
                +        self.websocket.visu_items[item.id()] = {'acl': acl, 'item': item}
                +        return self.update_item
                +
                +
                +    def update_item(self, item, caller=None, source=None, dest=None):
                +        self.websocket.update_item(item.id(), item(), source)
                +
                +    def url(self, url, clientip=''):
                +        self.websocket.url(url, clientip)
                +		
                +    def parse_logic(self, logic):
                +        if hasattr(logic, 'visu_acl'):
                +            if logic.conf['visu_acl'].lower() in ('true', 'yes', 'rw'):
                +                self.websocket.visu_logics[logic.name] = logic
                +
                +
                +    def return_clients(self):
                +        for client in self.websocket.clients:
                +            infos = {}
                +            infos['addr'] = client.addr
                +            infos['sw'] = client.sw
                +            infos['swversion'] = client.swversion
                +            infos['hostname'] = client.hostname
                +            infos['browser'] = client.browser
                +            infos['browserversion'] = client.browserversion
                +            if self.PLUGIN_VERSION == "1.1.2":
                +                yield client.addr			# v1.1.2
                +            else:
                +                # v1.1.3 and up
                +                yield infos
                +
                +#    def return_clients(self):
                +#        for client in self.websocket.clients:
                +#            if self.PLUGIN_VERSION == "1.1.2":
                +#                yield client.addr			# v1.1.2
                +#            else:
                +#                # v1.1.3 and up
                +#                yield client.addr, client.sw, client.swversion, client.hostname, client.browser, client.browserversion
                +
                +
                +#########################################################################
                +
                +class _websocket(lib.connection.Server):
                +    """
                +    Websocket specific class of the Plugin. Handles the websocket connections
                +    """
                +
                +    def __init__(self, smarthome, ip, port, tls, wsproto ):
                +        lib.connection.Server.__init__(self, ip, port)
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        self.tls = tls
                +        self.proto = wsproto
                +        smarthome.add_event_listener(['log'], self._send_event)
                +        self.clients = []
                +        self.visu_items = {}
                +        self.visu_logics = {}
                +
                +        self.tls_crt = '/usr/local/smarthome/etc/home.crt'
                +        self.tls_key = '/usr/local/smarthome/etc/home.key'
                +        self.tls_ca = '/usr/local/smarthome/etc/ca.crt'
                +
                +
                +    def return_clients(self):
                +        for client in self.clients:
                +            yield client.addr
                +
                +
                +    def handle_connection(self):
                +        sock, address = self.accept()
                +        if sock is None:
                +            return
                +        if self.tls:
                +            try:
                +                # cert_reqs=ssl.CERT_REQUIRED
                +                sock = ssl.wrap_socket(sock, server_side=True, cert_reqs=ssl.CERT_OPTIONAL, certfile=self.tls_crt, ca_certs=self.tls_ca, keyfile=self.tls_key, ssl_version=ssl.PROTOCOL_TLSv1)
                +                self.logger.debug('Client cert: {0}'.format(sock.getpeercert()))
                +                self.logger.debug('Cipher: {0}'.format(sock.cipher()))
                +#               print ssl.OPENSSL_VERSION
                +            except Exception as e:
                +                self.logger.exception(e)
                +                return
                +        client = websockethandler(self._sh, self, sock, address, self.visu_items, self.visu_logics, self.proto)
                +        self.clients.append(client)
                +
                +    def stop(self):
                +        for client in self.clients:
                +            try:
                +                client.close()
                +            except:
                +                pass
                +        self.close()
                +
                +    def update_item(self, item_name, item_value, source):
                +        data = {'cmd': 'item', 'items': [[item_name, item_value]]}
                +#        self.logger.warning("_websocket: update_item: data {0}".format(data))
                +        for client in list(self.clients):
                +            try:
                +                client.update(item_name, data, source)
                +            except:
                +                pass
                +
                +    def remove_client(self, client):
                +        self.clients.remove(client)
                +
                +
                +    def _send_event(self, event, data):
                +        for client in list(self.clients):
                +            try:
                +                client.send_event(event, data)
                +            except:
                +                pass
                +
                +    def _update_series(self):
                +        for client in list(self.clients):
                +            try:
                +                client.update_series()
                +            except Exception as e:
                +                self.logger.warning("_websocket / _update_series: cannot update client {0}, error {1}".format(client, e))
                +                pass
                +
                +    def dialog(self, header, content):
                +        for client in list(self.clients):
                +            try:
                +                client.json_send({'cmd': 'dialog', 'header': header, 'content': content})
                +            except:
                +                pass
                +
                +    def url(self, url, clientip=''):
                +        for client in list(self.clients):
                +            ip, _, port = client.addr.partition(':')
                +            if (clientip == '') or (clientip == ip):
                +                self.logger.debug("VISU: Websocket send url to ip={}, port={}".format(str(ip),str(port)))
                +                try:
                +                    client.json_send({'cmd': 'url', 'url': url})
                +                except:
                +                    pass
                +
                +
                +#########################################################################
                +
                +class websockethandler(lib.connection.Stream):
                +    """
                +    Websocket handler class of the Plugin. Each instance handles one client connection
                +    """
                +
                +    def __init__(self, smarthome, dispatcher, sock, addr, items, logics, proto=4):
                +        lib.connection.Stream.__init__(self, sock, addr)
                +        self.terminator = b"\r\n\r\n"
                +        self.logger = logging.getLogger(__name__)
                +        self._sh = smarthome
                +        self._dp = dispatcher
                +        self.found_terminator = self.parse_header
                +        self.addr = addr
                +        self.header = {}
                +        self.monitor = {'item': [], 'rrd': [], 'log': []}
                +        self.monitor_id = {'item': 'item', 'rrd': 'item', 'log': 'name'}
                +        self._update_series = {}
                +        self.items = items
                +        self.rrd = False
                +        self.log = False
                +        self.logs = smarthome.return_logs()
                +        self._series_lock = threading.Lock()
                +        self.logics = logics
                +        self.proto = proto
                +        self.logger.info("VISU: Websocket handler uses protocol version {0}".format(self.proto))
                +        self.sw = ''
                +        self.swversion = ''
                +        self.hostname = ''
                +        self.browser = ''
                +        self.browserversion = ''
                +        
                +
                +    def send_event(self, event, data):
                +        data = data.copy()  # don't filter the orignal data dict
                +        if event not in self.monitor:
                +            return
                +        if data[self.monitor_id[event]] in self.monitor[event]:
                +            data['cmd'] = event
                +#            self.logger.warning("VISU: send_event send to {0}: {1}".format(self.addr, data))
                +            self.json_send(data)
                +
                +    def json_send(self, data):
                +        self.logger.debug("Visu: DUMMY send to {0}: {1}".format(self.addr, data))
                +
                +    def handle_close(self):
                +        # remove circular references
                +        self._dp.remove_client(self)
                +        try:
                +            del(self.json_send, self.found_terminator)
                +        except:
                +            pass
                +
                +    def update(self, path, data, source):
                +        if path in self.monitor['item']:
                +            if self.addr != source:
                +#                self.logger.warning("VISU: update send to {0}: {1}, path={2}, source={3}".format(self.addr, data, path, source))
                +                self.json_send(data)
                +
                +    def update_series(self):
                +        now = self._sh.now()
                +        self._series_lock.acquire()
                +        remove = []
                +        for sid, series in self._update_series.items():
                +            if series['update'] < now:
                +                try:
                +                    reply = self.items[series['params']['item']]['item'].series(**series['params'])
                +                except Exception as e:
                +                    self.logger.exception("Problem updating series for {0}: {1}".format(series['params'], e))
                +                    remove.append(sid)
                +                    continue
                +                self._update_series[reply['sid']] = {'update': reply['update'], 'params': reply['params']}
                +                del(reply['update'])
                +                del(reply['params'])
                +                if reply['series'] is not None:
                +#                    self.logger.warning("Visu: update send to {0}: {1}".format(self.addr, reply))
                +                    self.json_send(reply)
                +        for sid in remove:
                +            del(self._update_series[sid])
                +        self._series_lock.release()
                +
                +    def difference(self, a, b):
                +        return list(set(b).difference(set(a)))
                +
                +    def json_parse(self, data):
                +        self.logger.debug("{0} sent {1}".format(self.addr, repr(data)))
                +        try:
                +            data = json.loads(data)
                +        except Exception as e:
                +            self.logger.debug("Problem decoding {0} from {1}: {2}".format(repr(data), self.addr, e))
                +            return
                +        command = data['cmd']
                +        if command == 'item':
                +            path = data['id']
                +            value = data['val']
                +            if path in self.items:
                +                if not self.items[path]['acl'] == 'ro':
                +                    self.items[path]['item'](value, 'Visu', self.addr)
                +                else:
                +                    self.logger.warning("Client {0} want to update read only item: {1}".format(self.addr, path))
                +            else:
                +                self.logger.warning("Client {0} want to update invalid item: {1}".format(self.addr, path))
                +        elif command == 'monitor':
                +            if data['items'] == [None]:
                +                return
                +            items = []
                +            for path in list(data['items']):
                +                if path in self.items:
                +                    items.append([path, self.items[path]['item']()])
                +                else:
                +                    self.logger.warning("Client {0} requested invalid item: {1}".format(self.addr, path))
                +            self.logger.debug("VISU json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'item', 'items': items})))	# MSinn
                +            self.json_send({'cmd': 'item', 'items': items})
                +            self.monitor['item'] = data['items']
                +        elif command == 'ping':
                +            self.logger.debug("VISU json_parse: send to {0}: {1}".format(self.addr, ({'cmd': 'pong'})))
                +            self.json_send({'cmd': 'pong'})
                +        elif command == 'logic':
                +            if 'name' not in data:
                +                return
                +            name = data['name']
                +            if name in self.logics:
                +                if 'val' in data:
                +                    value = data['val']
                +                    self.logger.info("Client {0} triggerd logic {1} with '{2}'".format(self.addr, name, value))
                +                    self.logics[name].trigger(by='Visu', value=value, source=self.addr)
                +                if 'enabled' in data:
                +                    if data['enabled']:
                +                        self.logger.info("Client {0} enabled logic {1}".format(self.addr, name))
                +                        self.logics[name].enable()
                +                    else:
                +                        self.logger.info("Client {0} disabled logic {1}".format(self.addr, name))
                +                        self.logics[name].disable()
                +            else:
                +#                self.logger.warning("VISU: Defined logics {0}".format(self.logics))
                +                self.logger.warning("Client {0} requested invalid logic: {1}".format(self.addr, name))
                +        elif command == 'series':
                +            path = data['item']
                +            series = data['series']
                +            start = data['start']
                +            if 'end' in data:
                +                end = data['end']
                +            else:
                +                end = 'now'
                +            if 'count' in data:
                +                count = data['count']
                +            else:
                +                count = 100
                +            if path in self.items:
                +                if hasattr(self.items[path]['item'], 'series'):
                +                    try:
                +                        reply = self.items[path]['item'].series(series, start, end, count)
                +#                        self.logger.warning("VISU json_parse: send to {0}: {1}".format(self.addr, reply))	# MSinn
                +                    except Exception as e:
                +                        self.logger.error("Problem fetching series for {0}: {1} - Wrong sqlite plugin?".format(path, e))
                +                    else:
                +                        if 'update' in reply:
                +                            self._series_lock.acquire()
                +                            self._update_series[reply['sid']] = {'update': reply['update'], 'params': reply['params']}
                +                            self._series_lock.release()
                +                            del(reply['update'])
                +                            del(reply['params'])
                +                        if reply['series'] is not None:
                +                            self.json_send(reply)
                +                        else:
                +                            self.logger.info("WebSocket: no entries for series {} {}".format(path, series))
                +                else:
                +                    self.logger.warning("Client {0} requested invalid series: {1}.".format(self.addr, path))
                +        elif command == 'log':
                +            self.log = True
                +            name = data['name']
                +            num = 10
                +            if 'max' in data:
                +                num = int(data['max'])
                +            if name in self.logs:
                +                self.json_send({'cmd': 'log', 'name': name, 'log': self.logs[name].export(num), 'init': 'y'})
                +            else:
                +                self.logger.warning("Client {0} requested invalid log: {1}".format(self.addr, name))
                +            if name not in self.monitor['log']:
                +                self.monitor['log'].append(name)
                +        elif command == 'proto':  # protocol version
                +            proto = data['ver']
                +            if proto > self.proto:
                +                self.logger.warning("WebSocket: protocol mismatch. SmartHomeNG protocol version={0}, visu protocol version={1}".format(self.proto, proto))
                +            elif proto < self.proto:
                +                self.logger.warning("WebSocket: protocol mismatch. Update your client: {0}".format(self.addr))
                +            self.json_send({'cmd': 'proto', 'ver': self.proto, 'time': self._sh.now()})
                +#            self.logger.warning("VISU json_parse: send to {0}: {1}".format(self.addr, "{'cmd': 'proto', 'ver': " + str(self.proto) + ", 'time': " + str(self._sh.now()) + "}"))
                +        elif command == 'identity':  # identify client
                +            self.sw = data.get('sw','')
                +            self.swversion = data.get('ver','')
                +            self.hostname = data.get('hostname','')
                +            self.browser = data.get('browser','')
                +            self.browserversion = data.get('bver','')
                +            self.logger.debug("VISU json_parse: received 'identify' from {0}: {1}".format(self.addr, data))
                +
                +    def parse_header(self, data):
                +        data = bytes(data)
                +        for line in data.splitlines():
                +            key, sep, value = line.partition(b': ')
                +            self.header[key] = value
                +        if b'Sec-WebSocket-Version' in self.header:
                +            if self.header[b'Sec-WebSocket-Version'] == b'13':
                +                self.rfc6455_handshake()
                +            else:
                +                self.handshake_failed()
                +        elif b'Sec-WebSocket-Key2' in self.header:
                +            self.found_terminator = self.hixie76_handshake
                +            self.terminator = 8
                +        else:
                +            self.handshake_failed()
                +
                +    def handshake_failed(self):
                +        self.logger.debug("Handshake for {0} with the following header failed! {1}".format(self.addr, repr(self.header)))
                +        self.close()
                +
                +    def set_bit(self, byte, bit):
                +        return byte | (1 << bit)
                +
                +    def bit_set(self, byte, bit):
                +        return not 0 == (byte & (1 << bit))
                +
                +    def rfc6455_handshake(self):
                +        self.logger.debug("rfc6455 Handshake")
                +        self.terminator = 8
                +        self.found_terminator = self.rfc6455_parse
                +        self.json_send = self.rfc6455_send
                +        key = self.header[b'Sec-WebSocket-Key'] + b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                +        key = base64.b64encode(hashlib.sha1(key).digest()).decode()
                +        self.send('HTTP/1.1 101 Switching Protocols\r\n'.encode())
                +        self.send('Upgrade: websocket\r\n'.encode())
                +        self.send('Connection: Upgrade\r\n'.encode())
                +        self.send('Sec-WebSocket-Accept: {0}\r\n'.format(key).encode())
                +        self.send('\r\n'.encode())
                +
                +    def rfc6455_parse(self, data):
                +        # fin = bit_set(data[0], 7)
                +        # rsv1 = bit_set(data[0], 6)
                +        # rsv2 = bit_set(data[0], 5)
                +        # rsv1 = bit_set(data[0], 4)
                +        opcode = data[0] & 0x0f
                +        if opcode == 8:
                +            self.logger.debug("WebSocket: closing connection to {0}.".format(self.addr))
                +            self.close()
                +            return
                +        header = 2
                +        masked = self.bit_set(data[1], 7)
                +        if masked:
                +            header += 4
                +        length = data[1] & 0x7f
                +        if length == 126:
                +            header += 2
                +            length = int.from_bytes(data[2:4], byteorder='big')
                +        elif length == 127:
                +            header += 8
                +            length = int.from_bytes(data[2:10], byteorder='big')
                +        read = header + length
                +        if len(data) < read:  # data too short, read more
                +            self.inbuffer = data + self.inbuffer
                +            self.terminator = read
                +            return
                +        if masked:
                +            key = data[header - 4:header]
                +            payload = bytearray(data[header:])
                +            for i in range(length):
                +                payload[i] ^= key[i % 4]
                +        else:
                +            payload = data[header:]
                +        self.json_parse(payload.decode())
                +        self.terminator = 8
                +
                +    def rfc6455_send(self, data):
                +        data = json.dumps(data, cls=JSONEncoder, separators=(',', ':'))
                +        header = bytearray(2)
                +        header[0] = self.set_bit(header[0], 0)  # opcode text
                +        header[0] = self.set_bit(header[0], 7)  # final
                +        length = len(data)
                +        if length < 126:
                +            header[1] = length
                +        elif length < ((1 << 16) - 1):
                +            header[1] = 126
                +            header += bytearray(length.to_bytes(2, byteorder='big'))
                +        elif length < ((1 << 64) - 1):
                +            header[1] = 127
                +            header += bytearray(length.to_bytes(8, byteorder='big'))
                +        else:
                +            self.logger.warning("data to big: {0}".format(data))
                +            return
                +        self.send(header + data.encode())
                +
                +    def hixie76_send(self, data):
                +        data = json.dumps(data, cls=JSONEncoder, separators=(',', ':'))
                +        packet = bytearray()
                +        packet.append(0x00)
                +        packet.extend(data.encode())
                +        packet.append(0xff)
                +        self.send(packet)
                +
                +    def hixie76_parse(self, data):
                +        self.json_parse(data.decode().lstrip('\x00'))
                +
                +    def hixie76_handshake(self, key3):
                +        self.logger.debug("Hixie76 Handshake")
                +        key1 = self.header[b'Sec-WebSocket-Key1'].decode()
                +        key2 = self.header[b'Sec-WebSocket-Key2'].decode()
                +        spaces1 = key1.count(" ")
                +        spaces2 = key2.count(" ")
                +        num1 = int("".join([c for c in key1 if c.isdigit()])) // spaces1
                +        num2 = int("".join([c for c in key2 if c.isdigit()])) // spaces2
                +        key = hashlib.md5()
                +        key.update(struct.pack('>II', num1, num2))
                +        key.update(key3)
                +        # send header
                +        self.send(b'HTTP/1.1 101 Web Socket Protocol Handshake\r\n')
                +        self.send(b'Upgrade: WebSocket\r\n')
                +        self.send(b'Connection: Upgrade\r\n')
                +        self.send(b"Sec-WebSocket-Origin: " + self.header[b'Origin'] + b"\r\n")
                +        self.send(b"Sec-WebSocket-Location: ws://" + self.header[b'Host'] + b"/\r\n\r\n")
                +        self.send(key.digest())
                +        self.found_terminator = self.hixie76_parse
                +        self.json_send = self.hixie76_send
                +        self.terminator = b"\xff"
                +
                +
                +#########################################################################
                +
                +class JSONEncoder(json.JSONEncoder):
                +
                +    def default(self, obj):
                +        if isinstance(obj, datetime.datetime):
                +            return obj.isoformat()
                +        elif isinstance(obj, datetime.date):
                +            return obj.isoformat()
                +        elif isinstance(obj, datetime.time):
                +            return obj.isoformat()
                +        elif isinstance(obj, datetime.timedelta):
                +            return int(obj.total_seconds())
                +        elif isinstance(obj, decimal.Decimal):
                +            return float(obj)
                +        return json.JSONEncoder.default(self, obj)
                +
                diff --git a/visu_websocket/_pv_1_1_3/plugin.yaml b/visu_websocket/_pv_1_1_3/plugin.yaml
                new file mode 100755
                index 000000000..eb51a0838
                --- /dev/null
                +++ b/visu_websocket/_pv_1_1_3/plugin.yaml
                @@ -0,0 +1,66 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Websocket Protokoll für Visus (smartVISU, etc.)'
                +        en: 'Support for a websocket protocol (for smartVISU, etc.)'
                +    maintainer: msinn
                +    tester: psilo909
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Visu_Unterstuetzung        # url of documentation (wiki) page
                +
                +    version: 1.1.3                 # Plugin version
                +    sh_minversion: 1.2             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: WebSocket           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    ip:
                +        type: ipv4
                +        default: '0.0.0.0'
                +        description:
                +            de: 'IP Adresse, falls nicht auf allen IPs des hosts gelauscht werden soll'
                +            en: 'ip address to use, if not listening on all ip addresses of the host'
                +    
                +    port:
                +        type: int
                +        default: 2424
                +        valid_min: 0
                +        description:
                +            de: 'Port der für den Websocket Zugriff verwendet wird'
                +            en: 'Port that is used for the websocket protocol'
                +    
                +    tls:
                +        type: bool
                +        default: False
                +        description:
                +            de: 'TLS benutzen? Falls auf True gesetzt, muss SmartHomeNGs /etc Directory die Zertifikat-Dateien home.crt, home.key und ca.crt enthalten'
                +            en: 'Use TLS? If set to True, SmartHomeNGs /etc directory must contain the certificate files: home.crt, home.key, ca.crt'
                +    
                +    acl:
                +        type: str
                +        default: ro
                +        valid_list:
                +          - rw
                +          - ro
                +          - deny
                +          - true
                +          - yes
                +          - no
                +        description:
                +            de: 'Erlaube den Zugriff über Websocket Protokoll (rw=Lesen/Schreiben, ro=Nur Lesen, deny=Kein Zugriff) - Voreinstellung für alle Items'
                +            en: 'Allow access through wbsocket protocol (rw=Read/Write, ro=Read Only, deny=Deny access) - Default for all items'
                +    
                +    wsproto:
                +        type: int
                +        default: 3
                +        valid_list:
                +          - 3
                +          - 4
                +        description:
                +            de: 'Verwendete Version des Websocket Protokolls'
                +            en: 'Used version of the websocket protocol'
                +    
                diff --git a/visu_websocket/developer_doc.md b/visu_websocket/developer_doc.md
                new file mode 100755
                index 000000000..657a0f595
                --- /dev/null
                +++ b/visu_websocket/developer_doc.md
                @@ -0,0 +1,333 @@
                +# visu_websocket
                +
                +## Visualisation plugin (Websocket Protocol) - for developers
                +
                +```
                + 
                +Copyright 2012-2013 Marcus Popp                  marcus@popp.mx
                +Copyright 2016- Martin Sinn                      m.sinn@gmx.de
                +
                +This plugin is part of SmartHomeNG.
                +  
                +Visit:  https://github.com/smarthomeNG/
                +        https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +```
                +
                +This file gives **smarthome.py** developers of visualization software additional information about the visu_websocket plugin. 
                +The following sections describe the implemented websocket protocol, that can be used my a visu to interface with smarthomeNG.
                +
                +For information about the configuration of the plugin refer to **README.md**.
                +
                +.
                +
                +## WebSocket Interface
                +
                +The visa plugin implements a WebSocket server. This section describes the implemented protocol. The messages of the protocol consist of data in json format. Following are the request commands which the visu plugin handles. 
                +
                +## Requests sent from the Visu to SmartHomeNG 
                +
                +### item
                +With the **`item`** command a client requests to change the value of an item. The example requests the item with the id "wohnung.buero.schreibtischleuchte.onoff" to be turned off:
                +
                +```
                +	{
                +	 "cmd":"item",
                +	 "id":"wohnung.buero.schreibtischleuchte.onoff",
                +	 "val":"0"
                +	}
                +```
                +
                +The plugin does not send an answer to the **`item`** command.
                +
                +
                +### monitor
                +With the **`monitor`** command a client requests the actual value of a list of items. The list of the requested item names has to be comma seperated. Take a look at the following example:
                +
                +```
                +	{
                +	 "cmd":"monitor",
                +	 "items":[
                +		"wohnung.hauswirtschaft.deckenlicht",
                +		"wohnung.hauswirtschaft.waschmaschine",
                +		"wohnung.hauswirtschaft.waschmaschine.status",
                +		"wohnung.hauswirtschaft.waschmaschine.ma",
                +		"wohnung.hauswirtschaft.trockner",
                +		"wohnung.hauswirtschaft.trockner.status",
                +		"wohnung.hauswirtschaft.trockner.ma",
                +	 ]
                +	}
                +```	 
                +
                +The plugin answers with a list of of pairs. Each pair consists of an item name and the corresponding value. This list is followed by the command-type which initiated this response. The answer to the request above could look like this:
                +
                +```
                +	{
                +	 'items': [
                +	 	['wohnung.hauswirtschaft.deckenlicht', False], 
                +	 	['wohnung.hauswirtschaft.waschmaschine', True], 
                +	 	['wohnung.hauswirtschaft.waschmaschine.status', 1], 
                +	 	['wohnung.hauswirtschaft.waschmaschine.ma', 37], 
                +	 	['wohnung.hauswirtschaft.trockner', True], 
                +	 	['wohnung.hauswirtschaft.trockner.status', 1], 
                +	 	['wohnung.hauswirtschaft.trockner.ma', 0], 
                +	 ], 
                +	 'cmd': 'item'
                +	}
                +	 	
                +```
                +
                +
                +Additionally, the plugin initiates an update routine, which sends updates for item values, if the item in smarthome.py has changed. For example:
                +
                +```
                +	{
                +	 'items': [
                +			['wohnung.hauswirtschaft.waschmaschine.ma', 36]
                +	 ], 
                +	 'cmd': 'item'
                +	}
                +```
                +
                +
                +### ping
                +With the **`ping`** command a client checks if the connection to the plugin is alive.
                +
                +```
                +	{"cmd":"ping"}
                +```
                +
                +The plugin answers with:
                +
                +```
                +	{"cmd":"pong"}
                +```
                +
                +
                +### logic
                +With the **`logic`** command a client requests a logic to be triggered. **`name`** is the name of the logic, as defined in **`etc/logic.conf`**. Furthermore, in **`etc/logic.conf`** the attribute **`visu_acl`** for that logic has to be set to **True**.
                +
                +```
                +	{"cmd":"logic",  "name":"az_licht",  "val":0}
                +```
                +
                +**Optional**: **enabled** can be used to disable or enable logics.
                +
                +Following information is passed to the logic via the trigger variable:
                +
                +```
                +	trigger[source] = <ip:port of the client (visu)>
                +	trigger[by]     = 'Visu'
                +	trigger[value]  = <value, as defined in the logic-command>
                +```
                +
                +The plugin does not send an answer to the **`logic`** command.
                +
                +
                +### series
                +With the **`series`** command a client requests a series of values for an item. The values which are requested are stored in a database using the sqlite plugin. The **`series`** command only returns data for items which are configured to store data via the **sqlite** plugin. 
                +
                +The series command is for instance used by SmartVISU to get data for the plot widget. The following example requests a series of the average values of the last 48 hours:
                +
                +```
                +	{
                +	 "cmd":"series",
                +	 "item":"wohnung.verteilung.zaehler.wirkleistung",
                +	 "series":"avg",
                +	 "start":"48h",
                +	 "end":"now",
                +	 "count":100
                +	}
                +```
                +
                +The attribute **`series`** defines which function is used to return the values for the series. The possible functions are **min**, **max**, **avg** and **sum**. These functions are implemented in the **sqlite** plugin v1.0. The new sqlite plugin (v2.8) implements the functions **min**, **max**, **avg** and **on**. **on** returns the percentage (as float from 0.00 to 1.00) where the value has been greater than 0.
                +
                +If the **`end`** attribute is ommitted, **"end":"now"** is assumed by the plugin.
                +If the **`count`** attribute is ommitted, **"count":100** is assumed by the plugin.
                +
                +The answer to the request above could look like this:
                + 
                +```
                +
                +	{
                +	 'series': [
                +	 	(1460636598495, 1831.97), 
                +	 	(1460637648422, 1458.14), 
                +	 	(1460639298307, 757.22), 
                +	 	(1460641098243, 577.38), 
                +	 	... (102 values in total)
                +	 	(1460802051217, 740.61), 
                +	 	(1460803884973, 637.61), 
                +	 	(1460805521319, 744.41), 
                +	 	(1460807229532, 718.03), 
                +	 	(1460808823757, 681.25), 
                +	 	(1460809294663, 681.25)
                +	 ], 
                +	 'cmd': 'series', 
                +	 'params': {
                +	 	'end': 'now', 
                +	 	'start': 1460809294663, 
                +	 	'update': True, 
                +	 	'item': 'wohnung.verteilung.zaehler.wirkleistung', 
                +	 	'step': 1728000.01, 
                +	 	'func': 'avg', 
                +	 	'sid': 'wohnung.verteilung.zaehler.wirkleistung|avg|48h|now'
                +	 }, 
                +	 'update': "2016-04-16T21:14:50.20.8227+02:00",
                +	 'sid': 'wohnung.verteilung.zaehler.wirkleistung|avg|48h|now'
                +	}
                +
                +```
                +
                +The plugin answers with a list of of pairs. Each pair consists of a timestamp and the corresponding value. This list is followed by the command-type which initiated this response and the parameters used to produce the series of data.
                +
                +The last two attributes define an identifier for this series and a time at which an update is sent by the plugin.
                +
                +Additionally, the plugin initiates an update routine, which sends updates for series values after a defined period of time. For example:
                +
                +```
                +	{
                +	 'series': [
                +	 	(1460810141323, 711.25), 
                +	 	(1460811024119, 711.25)
                +	 ], 
                +	 'cmd': 'series', 
                +	 'sid': 'wohnung.verteilung.zaehler.wirkleistung|avg|48h|now'
                +	}
                +```
                +
                +
                +### log
                +With the **`log`** command a client requests the last entries of a specified log. The example command requests the last 5 log entries of the core log:
                +
                +```
                +	{"cmd":"log","name":"env.core.log","max":"5"}
                +```
                +
                +The plugin answers with a message like this:
                +
                +
                +```
                +	{
                +	 "init":"y",
                +	 "cmd":"log",
                +	 "name":"env.core.log",
                +	 "log":[
                +	 	{"message":"VISU: WebSocketHandler uses protocol version 4","level":"WARNING","thread":"Main","time":"2016-04-16T15:53:21.354815+02:00"},
                +	 	{"message":"Using sonos section [sonos_bo], sonos_uid = RINCON_B8E93792D35401400","level":"WARNING","thread":"myradio","time":"2016-04-16T15:52:28.980100+02:00"},
                +	 	{"message":"Mondaufgang um 15:26:50 bei Azimuth 76.9 und Monduntergang um 04:39:55 bei Azimuth 285.5","level":"WARNING","thread":"mysunmoon","time":"2016-04-16T15:52:27.678330+02:00"},
                +	 	{"message":"No broker url given, assuming current ip and default broker port: http://10.0.0.182:12900","level":"WARNING","thread":"Main","time":"2016-04-16T15:52:14.006478+02:00"},
                +	 	{"message":"mlgw: Serial number of ML Gateway is 22804066","level":"WARNING","thread":"Main","time":"2016-04-16T15:52:13.869275+02:00"}
                +	 ]
                +	}
                +
                +```
                +
                +
                +### proto
                +With the **`proto`** command a client requests the WebSocket protocol version, it wants to use for communication:
                +
                +```
                +	{"cmd":"proto","ver":4}
                +```
                +
                +The plugin answers with the protocol version it supports. Additionally it sends the actual date time and timezone:
                +
                +
                +```
                +	{
                +	 "cmd": "proto", 
                +	 "ver": 4, 
                +	 "time":"2016-04-14T21:23:20.248227+02:00"
                +	}
                +```
                +
                +
                +### identity
                +--> This command is new with **SmartHomeNG 1.3**
                +
                +With the **`identity`** command a client sends information about itself to SmartHomeNG. The command should be issued right after opening a connection.
                +
                +The following example shows, what a smartVISU v2.7 running in a Safari Browser would send:
                +
                +```
                +	{
                +	 'cmd': 'identity',
                +	 'sw': 'smartVISU', 
                +	 'ver': 'v2.7', 
                +	 'browser': 'Safari', 
                +	 'bver': '9'
                +	}
                +```
                +
                +
                +### list_items
                +--> This command is new with **SmartHomeNG 1.4**
                +
                +With the **`list_items `** command a client requests the list of items that are defined in SmartHomeNG:
                +
                +```
                +	{"cmd":"list_items", "path":""}
                +```
                +
                +The plugin does not answer unless it has been configured with **querydef: True**.
                +
                +**path** defines the level for which item definitions are requested. if **path** is empty, the top level items are returned.
                +
                +The plugin answers with a dict containing the information about accessible items.
                +
                +```
                +	{
                +	 "cmd": "list_items", 
                +	 "items": [
                +	   {"path":"root.child", "name":"child", "type":"num"},
                +	   {"path":"root.another", "name":"another child", "type":"bool"}
                +	 ]
                +	}
                +```
                +
                +
                +### list_logics
                +--> This command is new with **SmartHomeNG 1.4**
                +
                +With the **`list_logics `** command a client requests the list of logics that can be triggered by the client:
                +
                +```
                +	{"cmd":"list_logics", "enabled":1}
                +```
                +
                +The plugin does not answer unless it has been configured with **querydef: True**.
                +
                +**enabled** is optional. As default, the request returns information for all loaded user logics. When **"enabled":1** is specified, only enabled user logics are being returned.
                +
                +The plugin answers with a dict containing the information about accessible logics. 
                +
                +```
                +	{
                +	 "cmd": "list_logics", 
                +	 "logics": [
                +	   {"name":"az_licht", "desc":"...", "enabled":1},
                +	   {"name":"gz_licht", "desc":"...", "enabled":0}
                +	 ]
                +	}
                +```
                +
                +
                +## Requests sent from SmartHomeNG to the Visu
                +
                +### url
                +--> This command is new with **SmartHomeNG 1.3**
                +
                +--> This command works with **smartVISU 2.9** and up, for **smartVISU 2.8** a modified driver **`io_smarthome.py`** is needed.
                +
                + **`url`**  is a command sent from the plugin to the smartVISU clients. With the **`url`** command the smartVISU client can be instructed to change to another page.
                +
                +The following command instructs smartVISU to change to the main page:
                +
                +```
                +	{"cmd":"url", "url": "index.php"}
                +```
                +
                +The smartVISU client does not send an answer to the **`url`** command.
                +
                +
                diff --git a/visu_websocket/plugin.yaml b/visu_websocket/plugin.yaml
                new file mode 100755
                index 000000000..c667fdffc
                --- /dev/null
                +++ b/visu_websocket/plugin.yaml
                @@ -0,0 +1,89 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: system                  # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Websocket Protokoll für Visus (smartVISU, etc.)'
                +        en: 'Support for a websocket protocol (for smartVISU, etc.)'
                +    maintainer: msinn
                +    tester: psilo909
                +#    keywords: iot xyz
                +    documentation: https://github.com/smarthomeNG/smarthome/wiki/Visu_Unterstuetzung        # url of documentation (wiki) page
                +
                +    version: 1.4.4                 # Plugin version
                +    sh_minversion: 1.3c            # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: WebSocket           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    ip:
                +        type: ipv4
                +        default: '0.0.0.0'
                +        description:
                +            de: 'IP Adresse, falls nicht auf allen IPs des hosts gelauscht werden soll'
                +            en: 'ip address to use, if not listening on all ip addresses of the host'
                +    
                +    port:
                +        type: int
                +        default: 2424
                +        valid_min: 0
                +        description:
                +            de: 'Port der für den Websocket Zugriff verwendet wird'
                +            en: 'Port that is used for the websocket protocol'
                +    
                +    tls:
                +        type: bool
                +        default: False
                +        description:
                +            de: 'TLS benutzen? Falls auf True gesetzt, muss SmartHomeNGs /etc Directory die Zertifikat-Dateien home.crt, home.key und ca.crt enthalten'
                +            en: 'Use TLS? If set to True, SmartHomeNGs /etc directory must contain the certificate files: home.crt, home.key, ca.crt'
                +    
                +    acl:
                +        type: str
                +        default: ro
                +        valid_list:
                +          - rw
                +          - ro
                +          - deny
                +          - true
                +          - yes
                +          - no
                +        description:
                +            de: 'Erlaube den Zugriff über Websocket Protokoll (rw=Lesen/Schreiben, ro=Nur Lesen, deny=Kein Zugriff) - Voreinstellung für alle Items'
                +            en: 'Allow access through wbsocket protocol (rw=Read/Write, ro=Read Only, deny=Deny access) - Default for all items'
                +    
                +    wsproto:
                +        type: int
                +        default: 4
                +        valid_list:
                +          - 3
                +          - 4
                +        description:
                +            de: 'Verwendete Version des Websocket Protokolls'
                +            en: 'Used version of the websocket protocol'
                +    
                +    querydef:
                +        type: bool
                +        default: False
                +        description:
                +            de: 'Wenn dieser Wert auf True gesetzt wird, ist es Websocket Clients möglich Item- und Logik Definitionen abzufragen'
                +            en: 'Websocket clients can query item- and logic definitions, if set to True'
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    visu_acl:
                +        type: str
                +        default: ro
                +        valid_list:
                +          - rw
                +          - ro
                +          - deny
                +          - true
                +          - yes
                +          - no
                +        description:
                +            de: 'Erlaube den Zugriff auf das Item über Websocket Protokoll (rw=Lesen/Schreiben, ro=Nur Lesen, deny=Kein Zugriff)'
                +            en: 'Allow access to the item through websocket protocol (rw=Read/Write, ro=Read Only, deny=Deny access)'
                +
                diff --git a/volkszaehler/plugin.yaml b/volkszaehler/plugin.yaml
                new file mode 100755
                index 000000000..1434ea9d3
                --- /dev/null
                +++ b/volkszaehler/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Auslesen von Energiemessern und Sensoren, die das S0 Protokoll unterstützen'
                +        en: ''
                +    maintainer: '? (st0ne)'
                +    tester: brandst
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: Volkszaehler        # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/vr100/plugin.yaml b/vr100/plugin.yaml
                new file mode 100755
                index 000000000..37b70c9fd
                --- /dev/null
                +++ b/vr100/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung eines Vorwerk Kobold VR100 Staubsaugers. Der Kobold muss mit einem Bluetooth Modul ausgerüstet sein'
                +        en: ''
                +    maintainer: '? (Robert Budde)'
                +#    tester: efgh                   # Who tests this plugin?
                +    keywords: bluetooth
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: VR100               # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/webservices/README.md b/webservices/README.md
                new file mode 100644
                index 000000000..d2adcc188
                --- /dev/null
                +++ b/webservices/README.md
                @@ -0,0 +1,158 @@
                +# WebServices plugin
                +
                +## Description
                +
                +This plugin makes use of the new SmartHomeNG module system. It provides a Webservice API based on REST and on a URL-based simple version and is
                +built upon CherryPy.
                +For REST, basic REST command such as PUT and GET are supported.
                +
                +Support-Thread für das Plugin: https://knx-user-forum.de/forum/supportforen/smarthome-py/1163886-support-thread-f%C3%BCr-das-webservices-plugin
                +
                +## Requirements
                +
                +This plugin requires CherryPy to be installed via pip.
                +It requires SmartHomeNG 1.4 or higher!
                +
                +## Configuration
                +
                +### etc/module.yaml
                +Basic configuration for the webservices plugin needs to be done in etc/module.yaml. Here the port, user, and plain text password (or alternatively hashed password) can be configured for the service interface in general.
                +The Hash for the password can be generated via the Backend plugin! If user and password are left empty, none are set. This may be e.g. suitable in case a reverse proxy is used.
                +
                +The webservice plugin is one functionality that builds upon the service layer configured in module.yaml, but there may be more in the future.
                +
                +```yaml
                +    servicesport: 8384
                +    service_user: serviceuser
                +    service_password: ''
                +    service_hashed_password: 'xxx'
                +```
                +
                +### plugin.conf (deprecated) / plugin.yaml
                +
                +```
                +[WebServices]
                +   class_name = WebServices
                +   class_path = plugins.webservices
                +   mode = all
                +```
                +
                +```yaml
                +WebServices:
                +    class_name: WebServices
                +    class_path: plugins.webservices
                +    mode: all
                +```
                +#### Attributes
                +  * `mode`: Optional mode for the plugin - "all" (default) means you can access all your items via the API. "set" means only defined item sets are accessible.
                +
                +### items.conf (deprecated) / items.yaml
                +
                +Currently access to all items is provided via the REST api in case the plugin is set via mode attribute to "all". In case that is not wanted, the attribute "webservices_set" can be used to group selected items to be accessible.
                +
                +```yaml
                +MyItem:
                +    type: str
                +    webservices_set: 'MySet1'
                +    webservices_data: 'val'
                +
                +MyItem2:
                +    type: num
                +    webservices_set:
                +     - 'MySet1'
                +     - 'MySet2'
                +    webservices_data: 'full'
                +```
                +
                +There are two item-attributes in items.yaml/items.conf that are specific to the webservices plugin. These parameters beginn with **`webservices_`**.
                +
                +#### webservices_set
                +
                +**`webservices_set`** contains a string description of the item set, the item shall be added to. A set can be requested as whole by the webservice api. An item can be added to several sets via a yaml list of set identifiers [as Strings].
                +
                +#### webservices_data
                +**`webservices_data`** is used to limit the returned values for an item. If the attribute value "val" is set, only the path name and the item value is returned. Otherwise, also all meta information is returned..
                +
                +## Usage
                +
                +### General: Error and Success Messages
                +
                +In case of an error (e.g. item is not found), the plugin returns an error formatted as JSON:
                +
                +{"Error": "No item with item path offifce.light found."}
                +
                +In case a request is successful, it returns a SUCCESS message as JSON.
                +
                +### Web-GUI (overview of services)
                +
                +A web gui with a list of all available items is provided via
                +http://<your_server_ip>:<your_backend_port>/ws_gui/
                +
                +### Simple Interface
                +
                +#### Get Value
                +
                +Gets the data of an item, enriched by meta data (if webservices_data is not set to "val"), as json object.
                +
                +http://<your_server_ip>:<your_services_port>/ws/items/<item_path>
                +
                +E.g. http://192.168.178.100:1234/ws/items/knx.gf.office.light
                +
                +returns:
                +
                +{"changed_by": "Cache", "enforce_updates": "False", "age": 1896.412548, "triggers": ["bound method KNX.update_item of plugins.knx.KNX", "bound method WebSocket.update_item of plugins.visu_websocket.WebSocket", "bound method Simulation.update_item of plugins.simulation.Simulation"], "last_change": "2017-12-02 06:53:56.310862+01:00", "autotimer": "False", "eval": "None", "value": true, "previous_age": "", "previous_value": true, "type": "bool", "config": {"alexa_actions": "turnOn turnOff", "alexa_name": "Lampe B\u00fcro", "knx_dpt": "1", "knx_init": "2/3/50", "knx_listen": "2/3/50", "knx_send": ["2/3/10"], "nw": "yes", "sim": "track", "visu_acl": "rw"}, "name": "knx.gf.office.light", "path": "knx.gf.office.light", "threshold": "False", "cache": "/python/smarthome/var/cache/knx.gf.office.light", "cycle": "", "last_update": "2017-12-02 06:53:56.310862+01:00", "previous_change": "2017-12-02 07:18:22.911165+01:00", "eval_trigger": "False", "crontab": "", "logics": ["LightCheckLogic"]}
                +
                +#### Set Value
                +
                +Sets a value of an item.
                +
                +http://<your_server_ip>:<your_services_port>/items/<item_path>/<value>
                +
                +E.g. http://192.168.178.100:1234/ws/items/office.light/0 or http://192.168.178.100:1234/ws/items/office.light/False turns off the light.
                +
                +#### Get Item Set
                +
                +Gets the data of an item set, enriched by meta data (if webservices_data is not set to "val"), as json object. The key for accessing the items is the item path.
                +
                +http://<your_server_ip>:<your_services_port>/ws/itemset/<set_name>
                +
                +### REST Compliant Interface
                +
                +#### HTTP GET (e.g. normal access to the URL)
                +
                +##### Reading an Item's Values
                +
                +Gets the value of an item, enriched by meta data, as json object. Here, also the REST Url is provided as URL field.
                +
                +http://<your_server_ip>:<your_services_port>/rest/items/<item_path>
                +
                +E.g. http://192.168.178.100:1234/rest/items/knx.gf.office.light
                +
                +returns:
                +
                +{"changed_by": "Cache", "enforce_updates": "False", "age": 1896.412548, "triggers": ["bound method KNX.update_item of plugins.knx.KNX", "bound method WebSocket.update_item of plugins.visu_websocket.WebSocket", "bound method Simulation.update_item of plugins.simulation.Simulation"], "last_change": "2017-12-02 06:53:56.310862+01:00", "autotimer": "False", "eval": "None", "value": true, "previous_age": "", "previous_value": true, "type": "bool", "config": {"alexa_actions": "turnOn turnOff", "alexa_name": "Lampe B\u00fcro", "knx_dpt": "1", "knx_init": "2/3/50", "knx_listen": "2/3/50", "knx_send": ["2/3/10"], "nw": "yes", "sim": "track", "visu_acl": "rw"}, "name": "knx.gf.office.light", "path": "knx.gf.office.light", "threshold": "False", "cache": "/python/smarthome/var/cache/knx.gf.office.light", "cycle": "", "last_update": "2017-12-02 06:53:56.310862+01:00", "previous_change": "2017-12-02 07:18:22.911165+01:00", "eval_trigger": "False", "crontab": "", "logics": ["LightCheckLogic"]}
                +
                +##### Item List
                +
                +The following URL prints out a list of all items, that can be requested or modified by the plugin (all str, num and bool items).
                +For each item, the detail information is also delivered.
                +
                +http://<your_server_ip>:<your_services_port>/rest/items/
                +
                +E.g. http://192.168.178.100:1234/rest/items/ returns the list of all available (str, num, bool) items. The key for accessing the items is the item path.
                +
                +##### Item Set
                +
                +Gets the data of an item set, enriched by meta data (if webservices_data is not set to "val"), as json object. The key for accessing the items is the item path.
                +
                +http://<your_server_ip>:<your_services_port>/rest/itemset/<set_name>
                +
                +#### HTTP PUT
                +
                +A HTTP PUT request to the URL sets a value of an item. Only num, bool and str item types are supported.
                +For bool items you can use int values 0 and 1, but also "yes", "no", "y", "n", "true", "false", "t", "f", "on", "off".
                +In case you send a string (or a string bool representation), take care it is provided in "...".
                +
                +http://<your_server_ip>:<your_services_port>/rest/items/<item_path>
                +
                +E.g. a PUT request with 0 as payload to http://192.168.178.100:1234/rest/items/office.light turns off the light.
                \ No newline at end of file
                diff --git a/webservices/__init__.py b/webservices/__init__.py
                new file mode 100644
                index 000000000..68a98f800
                --- /dev/null
                +++ b/webservices/__init__.py
                @@ -0,0 +1,445 @@
                +#!/usr/bin/env python3
                +# -*- coding: utf8 -*-
                +#########################################################################
                +# Copyright 2017        René Frieß                  rene.friess@gmail.com
                +#########################################################################
                +#  REST plugin for SmartHomeNG
                +#
                +#  This plugin is free software: you can redistribute it and/or modify
                +#  it under the terms of the GNU General Public License as published by
                +#  the Free Software Foundation, either version 3 of the License, or
                +#  (at your option) any later version.
                +#
                +#  This plugin is distributed in the hope that it will be useful,
                +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
                +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                +#  GNU General Public License for more details.
                +#
                +#  You should have received a copy of the GNU General Public License
                +#  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                +#########################################################################
                +
                +from lib.model.smartplugin import SmartPlugin
                +import logging
                +import cherrypy
                +from jinja2 import Environment, FileSystemLoader
                +import datetime
                +from collections import OrderedDict
                +import collections
                +import json
                +import html
                +import os
                +
                +
                +class WebServices(SmartPlugin):
                +    ALLOW_MULTIINSTANCE = False
                +    PLUGIN_VERSION = '1.4.0.1'
                +
                +    def __init__(self, smarthome, mode="all"):
                +        self.logger = logging.getLogger(__name__)
                +        self.logger.debug('Backend.__init__')
                +        self._sh = smarthome
                +        self._mode = mode
                +
                +        try:
                +            self.mod_http = self._sh.get_module('http')
                +        except:
                +            self.mod_http = None
                +        if self.mod_http is None:
                +            self.logger.error("Plugin '{}': Not initializing the web interface".format(self.get_shortname()))
                +            return
                +
                +        webif_dir = self.path_join(self.get_plugin_dir(), 'webif')
                +        config = {
                +            '/': {
                +                'tools.staticdir.root': webif_dir,
                +            },
                +            '/static': {
                +                'tools.staticdir.on': True,
                +                'tools.staticdir.dir': 'static'
                +            }
                +        }
                +
                +        # Register the REST interface as a cherrypy app
                +        self.mod_http.register_service(RESTWebServicesInterface(webif_dir, self),
                +                                       self.get_shortname(),
                +                                       config,
                +                                       self.get_classname(), self.get_instance_name(),
                +                                       description='WebService Plugin für SmartHomeNG (REST)',
                +                                       servicename='rest')
                +
                +        # Register the simple WebService interface as a cherrypy app
                +        self.mod_http.register_service(SimpleWebServiceInterface(webif_dir, self),
                +                                       self.get_shortname(),
                +                                       config,
                +                                       self.get_classname(), self.get_instance_name(),
                +                                       description='Webservice-Plugin für SmartHomeNG (simple)',
                +                                       servicename='ws')
                +
                +        # Register the web overview of the webservices interfaces as a cherrypy app
                +        self.mod_http.register_webif(WebGuiInterface(self),
                +                                     self.get_shortname(),
                +                                     config,
                +                                     self.get_classname(), self.get_instance_name(),
                +                                     description='Webservice-Plugin für SmartHomeNG (Frontend)',
                +                                     webifname='ws_gui')
                +
                +    def run(self):
                +        """
                +        Run method for the plugin
                +        """
                +        self.logger.debug("Plugin '{}': run method called".format(self.get_shortname()))
                +        self.alive = True
                +
                +    def stop(self):
                +        """
                +        Stop method for the plugin
                +        """
                +        self.logger.debug("Plugin '{}': stop method called".format(self.get_shortname()))
                +        self.alive = False
                +
                +
                +class WebGuiInterface:
                +    exposed = True
                +    env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)) + '/templates'))
                +
                +    def __init__(self, plugin):
                +        self.logger = logging.getLogger(__name__)
                +        self.plugin = plugin
                +
                +    def render_template(self, tmpl_name, **kwargs):
                +        tmpl = self.env.get_template(tmpl_name)
                +        return tmpl.render(smarthome=self.plugin._sh, **kwargs)
                +
                +    @cherrypy.expose
                +    def index(self):
                +        items_filtered = []
                +        item_sets = {}
                +        items_sorted = sorted(self.plugin._sh.return_items(), key=lambda k: str.lower(k['_path']), reverse=False)
                +        for item in items_sorted:
                +            if self.plugin._mode == 'all' or self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                if item.type() in ['str', 'bool', 'num']:
                +                    items_filtered.append(item)
                +                    if self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                        if isinstance(self.plugin.get_iattr_value(item.conf, 'webservices_set'), list):
                +                            for item_set in self.plugin.get_iattr_value(item.conf, 'webservices_set'):
                +                                if item_set not in item_sets:
                +                                    item_sets[item_set] = []
                +                                item_sets[item_set].append(item)
                +                        else:
                +                            item_set = self.plugin.get_iattr_value(item.conf, 'webservices_set')
                +                            if item_set not in item_sets:
                +                                item_sets[item_set] = []
                +                            item_sets[item_set].append(item)
                +
                +        return self.render_template('main.html', item_data=items_filtered,
                +                                    ip=self.plugin.mod_http.get_local_ip_address(),
                +                                    port=self.plugin.mod_http.get_local_port(),
                +                                    servicesport=self.plugin.mod_http.get_local_servicesport(),
                +                                    item_sets=item_sets)
                +
                +
                +class WebServiceInterface:
                +    exposed = True
                +    env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)) + '/templates'))
                +
                +    def __init__(self, webif_dir, plugin):
                +        self.webif_dir = webif_dir
                +        self.logger = logging.getLogger(__name__)
                +        self.plugin = plugin
                +
                +    def check_set(self, set_id, item_sets):
                +        if isinstance(item_sets, list):
                +            if set_id in item_sets:
                +                return True
                +            else:
                +                return False
                +        else:
                +            if set_id == item_sets:
                +                return True
                +            else:
                +                return False
                +
                +    def assemble_item_data(self, item, webservices_data='full'):
                +        if item is not None:
                +            if item.type() in ['str', 'bool', 'num']:
                +                if webservices_data == 'full':
                +                    prev_value = item.prev_value()
                +                    value = item._value
                +
                +                    if isinstance(prev_value, datetime.datetime):
                +                        prev_value = str(prev_value)
                +
                +                    cycle = ''
                +                    crontab = ''
                +                    for entry in self.plugin._sh.scheduler._scheduler:
                +                        if entry == item._path:
                +                            if self.plugin._sh.scheduler._scheduler[entry]['cycle']:
                +                                cycle = self.plugin._sh.scheduler._scheduler[entry]['cycle']
                +                            if self.plugin._sh.scheduler._scheduler[entry]['cron']:
                +                                crontab = str(self.plugin._sh.scheduler._scheduler[entry]['cron'])
                +                            break
                +
                +                    changed_by = item.changed_by()
                +                    if changed_by[-5:] == ':None':
                +                        changed_by = changed_by[:-5]
                +
                +                    item_conf_sorted = collections.OrderedDict(sorted(item.conf.items(), key=lambda t: str.lower(t[0])))
                +
                +                    if item.prev_age() < 0:
                +                        prev_age = ''
                +                    else:
                +                        prev_age = item.prev_age()
                +
                +                    logics = []
                +                    for trigger in item.get_logic_triggers():
                +                        logics.append(format(trigger))
                +                    triggers = []
                +                    for trigger in item.get_method_triggers():
                +                        trig = format(trigger)
                +                        trig = trig[1:len(trig) - 27]
                +                        triggers.append(format(trig.replace("<", "")))
                +
                +                    data_dict = {'path': item._path,
                +                                 'name': item._name,
                +                                 'type': item.type(),
                +                                 'value': value,
                +                                 'age': item.age(),
                +                                 'last_update': str(item.last_update()),
                +                                 'last_change': str(item.last_change()),
                +                                 'changed_by': changed_by,
                +                                 'previous_value': prev_value,
                +                                 'previous_age': prev_age,
                +                                 'previous_change': str(item.prev_change()),
                +                                 'enforce_updates': str(item._enforce_updates),
                +                                 'cache': str(item._cache),
                +                                 'eval': str(item._eval),
                +                                 'eval_trigger': str(item._eval_trigger),
                +                                 'cycle': str(cycle),
                +                                 'crontab': str(crontab),
                +                                 'autotimer': str(item._autotimer),
                +                                 'threshold': str(item._threshold),
                +                                 'config': item_conf_sorted,
                +                                 'logics': logics,
                +                                 'triggers': triggers
                +                                 }
                +                    return data_dict
                +                elif webservices_data == 'val':
                +                    return {'path': item._path, 'value': item._value}
                +            else:
                +                return None
                +
                +
                +class SimpleWebServiceInterface(WebServiceInterface):
                +    @cherrypy.expose
                +    @cherrypy.tools.json_in()
                +    @cherrypy.tools.json_out()
                +    def itemset(self, set_id=None):
                +        """
                +        REST function for items
                +        """
                +        if set_id is not None:
                +            self.logger.debug(cherrypy.request.method)
                +            if cherrypy.request.method not in 'GET':
                +                return {"Error": "%s requests not allowed for this URL" % cherrypy.request.method}
                +
                +            elif cherrypy.request.method == 'GET':
                +                items_sorted = sorted(self.plugin._sh.return_items(), key=lambda k: str.lower(k['_path']),
                +                                      reverse=False)
                +                items = {}
                +                for item in items_sorted:
                +                    if self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                        if self.check_set(set_id, self.plugin.get_iattr_value(item.conf, 'webservices_set')):
                +                            if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                                item_data = self.assemble_item_data(item, 'val')
                +                                items[item_data['path']] = item_data['value']
                +                            else:
                +                                item_data = self.assemble_item_data(item, 'full')
                +                                if item_data is not None:
                +                                    item_data['url'] = "http://%s:%s/ws/items/%s" % (
                +                                        self.plugin.mod_http.get_local_ip_address(),
                +                                        self.plugin.mod_http.get_local_port(), item._path)
                +                                    items[item._path] = item_data
                +                return items
                +        else:
                +            return {"Error": "No set-ID for item set is given."}
                +
                +    @cherrypy.expose
                +    @cherrypy.tools.json_out()
                +    def items(self, item_path=None, value=None):
                +        """
                +        Simpole WS functions for item
                +        """
                +        if item_path is None:
                +            self.logger.debug(cherrypy.request.method)
                +            if cherrypy.request.method not in 'GET':
                +                return {"Error": "%s requests not allowed for this URL" % cherrypy.request.method}
                +
                +            elif cherrypy.request.method == 'GET':
                +                items_sorted = sorted(self.plugin._sh.return_items(), key=lambda k: str.lower(k['_path']),
                +                                      reverse=False)
                +                items = {}
                +                for item in items_sorted:
                +                    if self.plugin._mode == 'all' or self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                        mode = "full"
                +                        if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                            mode = "val"
                +                        item_data = self.assemble_item_data(item, mode)
                +                        if item_data is not None:
                +                            if mode != "val":
                +                                item_data['url'] = "http://%s:%s/ws/items/%s" % (
                +                                    self.plugin.mod_http.get_local_ip_address(),
                +                                    self.plugin.mod_http.get_local_servicesport(), item._path)
                +                            items[item_data['path']] = item_data
                +                return items
                +        else:
                +            item = self.plugin._sh.return_item(item_path)
                +            if item is None:
                +                return {"Error": "No item with item path %s found." % item_path}
                +
                +            if self.plugin._mode == 'all' or self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                if item.type() in ['str', 'bool', 'num']:
                +                    if value is not None:
                +                        item(value)
                +                        return {"Success": "Item with item path %s set to %s." % (item_path, value)}
                +                    else:
                +                        mode = "full"
                +                        if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                            mode = "val"
                +                        item_data = self.assemble_item_data(item, mode)
                +                        if item_data is not None:
                +                            return item_data
                +                else:
                +                    return {"Error": "Item with path %s is type %s, only str, num and bool types are supported." %
                +                                     (item_path, item.type())}
                +            else:
                +                return {"Error": "Item with path %s not allowed for access via Webservice plugin." %
                +                                 item_path}
                +
                +
                +class RESTWebServicesInterface(WebServiceInterface):
                +    @cherrypy.expose
                +    @cherrypy.tools.json_in()
                +    @cherrypy.tools.json_out()
                +    def itemset(self, set_id=None):
                +        """
                +        REST function for items
                +        """
                +        if set_id is not None:
                +            self.logger.debug(cherrypy.request.method)
                +            if cherrypy.request.method not in 'GET':
                +                return {"Error": "%s requests not allowed for this URL" % cherrypy.request.method}
                +
                +            elif cherrypy.request.method == 'GET':
                +                items_sorted = sorted(self.plugin._sh.return_items(), key=lambda k: str.lower(k['_path']),
                +                                      reverse=False)
                +                items = {}
                +                for item in items_sorted:
                +                    if self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                        if self.check_set(set_id, self.plugin.get_iattr_value(item.conf, 'webservices_set')):
                +                            if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                                item_data = self.assemble_item_data(item, 'val')
                +                                items[item_data['path']] = item_data['value']
                +                            else:
                +                                item_data = self.assemble_item_data(item, 'full')
                +                                if item_data is not None:
                +                                    item_data['url'] = "http://%s:%s/rest/items/%s" % (
                +                                        self.plugin.mod_http.get_local_ip_address(),
                +                                        self.plugin.mod_http.get_local_port(), item._path)
                +                                    items[item_data['path']] = item_data
                +                return items
                +        else:
                +            return {"Error": "No set-ID for item set is given."}
                +
                +    @cherrypy.expose
                +    @cherrypy.tools.json_in()
                +    @cherrypy.tools.json_out()
                +    def items(self, item_path=None):
                +        """
                +        REST function for items
                +        """
                +        if item_path is None:
                +            self.logger.debug(cherrypy.request.method)
                +            if cherrypy.request.method not in 'GET':
                +                return {"Error": "%s requests not allowed for this URL" % cherrypy.request.method}
                +
                +            elif cherrypy.request.method == 'GET':
                +                items_sorted = sorted(self.plugin._sh.return_items(), key=lambda k: str.lower(k['_path']),
                +                                      reverse=False)
                +                items = {}
                +                for item in items_sorted:
                +                    if self.plugin._mode == 'all' or self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                        mode = "full"
                +                        if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                            mode = "val"
                +                        item_data = self.assemble_item_data(item, mode)
                +                        if item_data is not None:
                +                            if mode != 'val':
                +                                item_data['url'] = "http://%s:%s/rest/items/%s" % (
                +                                    self.plugin.mod_http.get_local_ip_address(),
                +                                    self.plugin.mod_http.get_local_port(), item._path)
                +                            items[item_data['path']] = item_data
                +                return items
                +        else:
                +            item = self.plugin._sh.return_item(item_path)
                +
                +            if item is None:
                +                return {"Error": "No item with item path %s found." % item_path}
                +
                +            if self.plugin._mode == 'all' or self.plugin.has_iattr(item.conf, 'webservices_set'):
                +                if cherrypy.request.method == 'PUT':
                +                    data = cherrypy.request.json
                +                    self.logger.error(data)
                +                    if 'num' in item.type():
                +                        if self.plugin.is_int(data) or self.plugin.is_float(data):
                +                            item(data)
                +                            self.logger.debug("Item with item path %s set to %s." % (item_path, data))
                +                        else:
                +                            return {"Error": "Item with item path %s is type num, value is %s." % (item_path, data)}
                +                    elif 'bool' in item.type():
                +                        if self.plugin.is_int(data):
                +                            if data == 0 or data == 1:
                +                                item(data)
                +                                self.logger.debug("Item with item path %s set to %s." % (item_path, data))
                +                            else:
                +                                return {
                +                                    "Error": "Item with item path %s is type bool, only 0 and 1 are accepted as integers, "
                +                                             "value is %s." % (
                +                                                 item_path,
                +                                                 data)}
                +                        else:
                +                            try:
                +                                data = self.plugin.to_bool(data)
                +                                item(data)
                +                                self.logger.debug("Item with item path %s set to %s." % (item_path, data))
                +                            except Exception as e:
                +                                return {"Error": "Item with item path %s is type bool, value is %s." % (item_path,
                +                                                                                                        data)}
                +                    elif 'str' in item.type():
                +                        item(data)
                +                        self.logger.debug("Item with item path %s set to %s." % (item_path, data))
                +                    else:
                +                        return {
                +                            "Error": "Only str, num and bool items are supported by the REST PUT interface. Item with item path %s is %s"
                +                                     % (
                +                                         item_path,
                +                                         item.type())}
                +
                +                elif cherrypy.request.method == 'GET':
                +                    mode = "full"
                +                    if self.plugin.get_iattr_value(item.conf, 'webservices_data') == 'val':
                +                        mode = "val"
                +                    item_data = self.assemble_item_data(item, mode)
                +                    if item_data is not None:
                +                        if mode != 'val':
                +                            item_data['url'] = "http://%s:%s/rest/items/%s" % (
                +                            self.plugin.mod_http.get_local_ip_address(),
                +                            self.plugin.mod_http.get_local_servicesport(),
                +                            item._path)
                +                        return item_data
                +                    else:
                +                        return {"Error": "Item with path %s is type %s, only str, num and bool types are supported." %
                +                                         (item_path, item.type())}
                +            else:
                +                return {"Error": "Item with path %s not allowed for access via Webservice plugin." %
                +                                 item_path}
                diff --git a/webservices/plugin.yaml b/webservices/plugin.yaml
                new file mode 100755
                index 000000000..71e8e455c
                --- /dev/null
                +++ b/webservices/plugin.yaml
                @@ -0,0 +1,41 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Implementierung eines Webservice interfaces'
                +        en: 'Implementation of a webservice interface'
                +    maintainer: psilo909
                +#    tester:                        # Who tests this plugin?
                +    keywords: REST, API, Webservice
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1163886-support-thread-f%C3%BCr-das-webservices-plugin
                +
                +    version: 1.4.0.1               # Plugin version
                +    sh_minversion: 1.3d            # minimum shNG version to use this plugin
                +#    sh_maxversion:                # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: WebServices         # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    mode:
                +        type: str
                +        mandatory: False
                +        description:
                +            de: 'Mode des Plugins: "all" wenn die Webservice-Schnittstelle alle Items der SmartHomeNG Instanz verfügbar machen soll (default). Ansonsten werden nur Items ausgeliefert, die einem Set via webservices_set zugeordnet sind.'
                +            en: 'Mode of the plugin: "all" if standard interface with all items shall be enabled (default if left empty). Otherwise only items are delivered via the interface that are added to a set via webservices_set attribute.'
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    webservices_set:
                +        type: str
                +        description:
                +            de: 'webservices_set (optional) enthält eine Zeichenkette, die zum Bündeln von Items in sets genutzt wird. Das Set steht unter http://<SmartHomeNG URL>;<WS Port>/[rest|ws]/itemset/<setname> bereit.'
                +            en: 'webservices_set (optional) contains a String, which is used to provide multiple item data via one webservice call. The set is available at http://<SmartHomeNG URL>;<WS Port>/[rest|ws]/itemset/<setname>.'
                +
                +    webservices_data:
                +        type: str
                +        description:
                +            de: 'webservices_data (optional) dient dazu, die Rückgabedaten von Items zu limitieren. Wird als Wert "val" eingegeben, so wird nur der Pfadname und der Wert zurückgegeben, sonst zusätzlich alle Metainformationen.'
                +            en: 'webservices_data (optional) is used, to limit the returned values for an item. If the attribute value "val" is set, only the path name and the item value is returned. Otherwise, also all meta information is returned.'
                diff --git a/webservices/templates/base.html b/webservices/templates/base.html
                new file mode 100644
                index 000000000..bc45227c8
                --- /dev/null
                +++ b/webservices/templates/base.html
                @@ -0,0 +1,55 @@
                +{% block doc -%}
                +<!DOCTYPE html>
                +<html{% block html_attribs %}{% endblock html_attribs %}>
                +{%- block html %}
                +  <head>
                +    {%- block head %}
                +    <title>{% block title %}{% endblock title %}</title>
                +
                +    {%- block metas %}
                +    <meta name="viewport" content="width=1200">
                +    {#
                +    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                +	<meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1,width=device-width">
                +	#}
                +    {%- endblock metas %}
                +
                +    {%- block styles %}
                +    <!-- Bootstrap
                +    <link href="{ {bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')} }" rel="stylesheet">
                +    -->
                +    <link rel="icon" href="../static/img/favicon.ico" type="image/png">
                +    <link rel="apple-touch-icon" href="../static/img/logo_small_32x32">
                +    <link rel="apple-touch-icon" sizes="76x76" href="../static/img/logo_small_76x76.png">
                +    <link rel="apple-touch-icon" sizes="120x120" href="../static/img/logo_small_120x120.png">
                +    <link rel="apple-touch-icon" sizes="152x152" href="../static/img/logo_small_152x152.png">
                +    <link rel="apple-touch-startup-image" href="../static/img/logo_big.png"> 
                +
                +    <link rel="stylesheet" href="../static/css/font-awesome.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="../static/css/bootstrap.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="../static/css/bootstrap-treeview.min.css" type="text/css"/>
                +    <link rel="stylesheet" href="../static/css/bootstrap-reload.css" type="text/css"/>
                +    {%- endblock styles %}
                +    {% block scripts %}
                +    <!-- <script src="../static/jquery.js"></script> -->
                +    <script src="../static/js/jquery-3.2.1.min.js"></script>
                +    <script src="../static/js/bootstrap.min.js"></script>
                +    <script src="../static/js/bootstrap-treeview.min.js"></script>
                +    <script src="../static/js/bootstrap-reload.js"></script>
                +    <script src="../static/js/google-prettify/run_prettify.js"></script>
                +    <script src="../static/js/backend.js"></script>
                +    {%- endblock scripts %}
                +    {%- endblock head %}
                +  </head>
                +  <body{% block body_attribs %}{% endblock body_attribs %}>
                +    {% block body -%}
                +    {% block navbar %}
                +    {%- endblock navbar %}
                +    {% block content -%}
                +    {%- endblock content %}
                +
                +    {%- endblock body %}
                +  </body>
                +{%- endblock html %}
                +</html>
                +{% endblock doc -%}
                diff --git a/webservices/templates/main.html b/webservices/templates/main.html
                new file mode 100644
                index 000000000..9910a4ec7
                --- /dev/null
                +++ b/webservices/templates/main.html
                @@ -0,0 +1,58 @@
                +<!DOCTYPE html>
                +{% extends "base.html" %}
                +{% block content %}
                +<div class="container">
                +    <div class="row">
                +        <div class="panel panel-default" style="padding: 20px;">
                +            <h1 class="margin-base-vertical">
                +            <img src="/static/img/logo_big.png" width="150" height="75">
                +            &nbsp; SmartHomeNG WebService Plugin</h1>
                +            <br/>
                +            <div style="width: 1600px;">
                +                The following items can be accessed by the REST and the Simple WebService interface:<br/><br/>
                +                <br/>
                +                <table>
                +                    <tr style="border-bottom: 1px solid grey;">
                +                        <th>
                +                            REST
                +                        </th>
                +                        <th>
                +                            Simple
                +                        </th>
                +                    </tr>
                +                    {% for key, value in item_sets.items() %}
                +                    <tr>
                +                        <td style="border-bottom: 1px solid #ccc; padding: 5px; font-weight:bold;"><a href="http://{{ip}}:{{servicesport}}/rest/itemset/{{key}}/">Item-Set: {{key}}</a></td>
                +                        <td style="border-bottom: 1px solid #ccc; padding: 5px; font-weight:bold;"><a href="http://{{ip}}:{{servicesport}}/ws/itemset/{{key}}/">Item-Set: {{key}}</a></td>
                +                    </tr>
                +                         {% for item in value %}
                +                            <tr>
                +                                <td>
                +                                    <a href="http://{{ip}}:{{servicesport}}/rest/items/{{item._path}}/">{{item._path}}</a>
                +                                </td>
                +                                <td>
                +                                    <a href="http://{{ip}}:{{servicesport}}/ws/items/{{item._path}}/">{{item._path}}</a>
                +                                </td>
                +                            </tr>
                +                         {% endfor %}
                +                    {% endfor %}
                +                    <tr>
                +                        <td style="border-bottom: 1px solid #ccc; padding: 5px; font-weight:bold;"><a href="http://{{ip}}:{{servicesport}}/rest/items/">All Accessible Items</a></td>
                +                        <td style="border-bottom: 1px solid #ccc; padding: 5px; font-weight:bold;"><a href="http://{{ip}}:{{servicesport}}/ws/items/">All Accessible Items</a></td>
                +                    </tr>
                +                    {% for item in item_data %}
                +                    <tr>
                +                        <td>
                +                            <a href="http://{{ip}}:{{servicesport}}/rest/items/{{item._path}}/">{{item._path}}</a>
                +                        </td>
                +                        <td>
                +                            <a href="http://{{ip}}:{{servicesport}}/ws/items/{{item._path}}/">{{item._path}}</a>
                +                        </td>
                +                    </tr>
                +                    {% endfor %}
                +                </table>
                +            </div>
                +        </div><!-- //main content -->
                +    </div><!-- //row -->
                +</div> <!-- //container -->
                +{% endblock %}
                \ No newline at end of file
                diff --git a/wettercom/plugin.yaml b/wettercom/plugin.yaml
                new file mode 100755
                index 000000000..e6dfe9489
                --- /dev/null
                +++ b/wettercom/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Integration von Wetter.COM'
                +        en: ''
                +    maintainer: '? (Jan N. Klug)'
                +    tester: psilo909
                +    keywords: weather
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.3.1                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: wettercom           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/wol/__init__.py b/wol/__init__.py
                old mode 100644
                new mode 100755
                diff --git a/wol/plugin.yaml b/wol/plugin.yaml
                new file mode 100755
                index 000000000..13dfbce9b
                --- /dev/null
                +++ b/wol/plugin.yaml
                @@ -0,0 +1,24 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: protocol                 # plugin type (gateway, interface, protocol, system, web)
                +    description:                  # Alternative: description in multiple languages
                +        de: 'Wake on LAN'
                +        en: 'Wake on LAN'
                +    maintainer: cmalo
                +#    tester:                        # Who tests this plugin?
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +    version: 1.1.2                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: WakeOnLan           # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/wunderground/__init__.py b/wunderground/__init__.py
                old mode 100644
                new mode 100755
                index 00237e80b..19b7d1723
                --- a/wunderground/__init__.py
                +++ b/wunderground/__init__.py
                @@ -46,10 +46,10 @@ class Wunderground(SmartPlugin):
                     """
                 
                     ALLOW_MULTIINSTANCE = True
                -    PLUGIN_VERSION='1.2.5'
                +    PLUGIN_VERSION='1.3.6'
                 
                 
                -    def __init__(self, sh, apikey='', language='de', location='', cycle='600', item_subtree='', log_start='False'):
                +    def __init__(self, sh, apikey='', language='de', location='', cycle='600', item_subtree=''):
                         """
                         Initalizes the plugin. The parameters described for this method are pulled from the entry in plugin.yaml.
                 
                @@ -64,9 +64,6 @@ def __init__(self, sh, apikey='', language='de', location='', cycle='600', item_
                         self.logger = logging.getLogger(__name__)
                         self.__sh = sh
                 
                -        if self.to_bool(log_start):
                -            self.logger.info("--------------------   Init Plugin: {0} {1}   --------------------".format(self.__class__.__name__, self.PLUGIN_VERSION))
                -
                         languagedict = {"de": "DL", "en": "EN", 'fr': "FR"}
                         self.apikey = str(apikey)
                         if self.apikey == '':
                @@ -128,10 +125,11 @@ def parse_item(self, item):
                                       can be sent to the knx with a knx write function within the knx plugin.
                 
                         """
                -        if 'wug_xmlstring' in item.conf:
                +        if 'wug_matchstring' in item.conf:
                +            return self.update_item
                +        elif 'wug_xmlstring' in item.conf:
                             # if config is still stored in wug_xmlstring, copy it to wug_matchstring
                             item.conf['wug_matchstring'] = item.conf['wug_xmlstring']
                -        if 'wug_matchstring' in item.conf:
                             return self.update_item
                         else:
                             return None
                @@ -199,6 +197,8 @@ def _check_result_value(self, item, val):
                 
                         # number has to be positive
                         if dt == 'positive':
                +            if val == '--':
                +                val = 0
                             if self.is_float(val):
                                 fval = float(val)
                                 if (fval <0):
                diff --git a/wunderground/plugin.yaml b/wunderground/plugin.yaml
                index bf75fcb8d..304b501bc 100644
                --- a/wunderground/plugin.yaml
                +++ b/wunderground/plugin.yaml
                @@ -1,17 +1,100 @@
                +# Metadata for the Smart-Plugin
                 plugin:
                -    type: cloud                 # plugin type (system, gateway, interface, protocol, cloud)
                -#    subtype: weather           # plugin subtype (if applicable)
                -    version: 1.2.4              # Plugin version
                -    keywords: weather           # keywords, where applicable
                -    sh_minversion: 1.2          # minimum shNG version to use this plugin
                -#   sh_maxversion:              # maximum shNG version to use this plugin (leave empty if latest)
                -    multi_instance: true        # plugin supports multi instance
                -    description: 'Abfrage der Daten des Wetterdienstes Wunderground.com'    # description (one language only, german preferred)
                -#   description:               # Alternative: description in multiple languages
                -#       de: 'Abfrage der Daten des Wetterdienstes Wunderground.com'
                -#       en: 'Get weather data from wunderground.com'
                -   documentation: https://github.com/smarthomeNG/plugins/blob/develop/wunderground/README.md        # url of wiki page
                -    maintainer: msinn           # Who maintains this plugin?
                -#   tester:                     # Who tests this plugin?
                +    # Global plugin attributes
                +    type: web                      # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Abfrage der Daten des Wetterdienstes Wunderground.com'
                +        en: 'Get weather data from wunderground.com'
                +    maintainer: msinn
                +#    tester:                        # Who tests this plugin?
                +    keywords: weather
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/959964-support-thread-für-das-backend-plugin
                 
                +    version: 1.3.6                 # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Wunderground        # class containing the plugin
                 
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    apikey:
                +        type: str
                +        mandatory: True
                +        description:
                +            de: 'Den bei Wunderground registrierten API Key eingeben'
                +            en: 'Enter you registered wunderground API key'
                +
                +    language:
                +        type: str
                +        default: 'de'
                +        description:
                +            de: 'Definiert die Sprache in der Wunderground Vorhersagedaten liefern soll (en: Englisch, de: Deutsch, fr: Französisch). Für weitere Sprachen bitte die von Wunderground definierten codes verwenden.'
                +            en: 'Defines the language for the forcast data (en: English, de: German, fr: French). For other languages use language codes defined by Wunderground.'
                +
                +    location:
                +        type: str
                +        mandatory: True
                +        description:
                +            de: 'Ort für den die Wetterinformationen angefordert werden sollen'
                +            en: 'The location for which you want weather information'
                +
                +    cycle:
                +        type: int
                +        default: 600
                +        description:
                +            de: 'Dieser Parameter muss normalerweise nicht angegeben werden. Er erlaubt es die Update-Frquenz anzupassen (Standard: alle 600 Sekunden). Mit dem Standardwert werden die Wetterdaten alle 10 Minuten aktualisiert. Das stellt sicher, dass die maximale Tagesmenge von 500 Requests für den gebührenfreien Account nicht überschritten werden, selbst wenn Wetter für zwei Orte oder für die smartVISU angefordert wird.'
                +            en: "This parameter usually doesn't have to be specified. It allows to change the update frequency (cycle every 600 seconds). As a standard, the plugin updates the weather data every 10 minutes. This ensures that the maximum of 500 requests for the free-of-charge- account are not maxed out, even if you use wunderground weather for two locations and/or smartVISU."
                +        
                +    item_subtree:
                +        type: str
                +        description:
                +            de: 'item_subtree definiert den Teilbaum der Items, welchen das wunderground plugin während der Updates nach dem wug_matchstring Attribut durchsuchen soll.'
                +            en: 'item_subtree defines the part of the item-tree which the wunderground plugin searches during data updates for the wug_matchstring attribute.
                +                If item_subtree is not defined or empty, the whole item-tree is searched, which creates unnecessary overhead vor SmartHomeNG.
                +                If you are going to configure multiple instances of the plugin to get the weather report for multiple locations, you have to specify the parameter, or you will get da data mix up.
                +                
                +                The subtrees defined by item_subtree for the different instances must not intersect!'
                +
                +#    instance:
                +#        type: str
                +#        description:
                +#            de: 'Name der Plugin Instanz (SmartHomeNG Standard-Parameter). Die Angabe ist notwendig, wenn Wetterdaten für mehrere Orte über mehrere Plugin-Instanzen abgefragt werden sollen.'
                +#            en: 'Name of the plugin instance (SmartHomeNG standard parameter). This is important if you define multiple weather locations using multiple instances of the wunderground plugin.'
                +
                +
                +
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                +    wug_matchstring:
                +        type: str
                +        description:
                +            de: 'wug_matchstring enthält eine Zeichenkette, die zum parsen der von Wunderground gesendeten Daten verwendet wird. Item Definitionen mit den üblicherweise verwendeten Mactchstrings sind in der README nachzulesen.'
                +            en: 'wug_matchstring contains a matchstring for parsing the data sent by wunderground. Item definitions with commonly used matchstrings can be found in the README file.'
                +
                +    wug_datatype:
                +        type: str
                +        description:
                +            de: 'wug_datatype kann genutzt werden, um fehlerhafte Daten herauszufiltern, die evtl. von Zeit zu Zeit von einer Wunderground Wetterstation gesendet werden. Diese fehlerhaften Werte werden dann nicht in das Item geschrieben. Dieses Attribut kann die Werte positive und percent annehmen.
                +                
                +                - positive: Filtert alle Werte kleiner 0 heraus.
                +                - percent: Filtert alle Werte heraus, die kleiner 0 oder größer als 100 sind.'
                +            en: 'wug_datatype is used to filter out wrong data that may be sent by a weatherstation from time to time. Those wrong values are filtered and not written to the item. This attribute can have the values positive and percent.
                +                
                +                - positive filters out all values less than 0.
                +                - percent filters out values less than 0 and values greater than 100.'
                +
                +#    value:
                +#        type: str
                +#        description:
                +#            de: 'Standardwert eines Items (SmartHomeNG standard Attribut). Der Standardwert wird genutzt, falls die gewählte Wetterstation für den entsprechenden Matchstring keine Werte sendet.'
                +#            en: 'Default value of the item (SmartHomeNG standard attribute). The default value is used, if the weather station you selected does not send data for the selected matchstring.'
                +
                +    wug_xmlstring:
                +        type: str
                +        description:
                +            de: 'Veraltet. Bitte stattdessen wug_matchstring verwenden.'
                +            en: 'Deprecated. Use wug_matchstring instead.'
                diff --git a/xbmc/__init__.py b/xbmc/__init__.py
                index 0785a7430..43b25dcfd 100755
                --- a/xbmc/__init__.py
                +++ b/xbmc/__init__.py
                @@ -54,7 +54,7 @@ class xbmc(lib.connection.Client):
                 
                     _notification_time = 10000
                     _listen_keys = ['volume', 'mute', 'title', 'media', 'state']
                -    _send_keys = {'volume': 'Application.SetVolume', 'mute': 'Application.SetMute'}
                +    _send_keys = {'volume': 'Application.SetVolume', 'mute': 'Application.SetMute', 'shutdown': 'System.Shutdown'}
                 
                     def __init__(self, smarthome, item):
                         if 'xbmc_port' in item.conf:
                @@ -104,12 +104,16 @@ def _send(self, method, params=None, id=None, wait=True):
                             if id > 100:
                                 self._id = 0
                         self._rid = id
                +
                +        if method == 'System.Shutdown':
                +            params = None
                +	
                         if params is not None:
                             data = {"jsonrpc": "2.0", "id": id, "method": method, 'params': params}
                         else:
                             data = {"jsonrpc": "2.0", "id": id, "method": method}
                         self._reply_lock.acquire()
                -        #logger.debug("XBMC sending: {0}".format(json.dumps(data, separators=(',', ':'))))
                +        logger.debug("XBMC sending: {0}".format(json.dumps(data, separators=(',', ':'))))
                         self.send((json.dumps(data, separators=(',', ':')) + '\r\n').encode())
                         if wait:
                             self._reply_lock.wait(2)
                @@ -125,7 +129,7 @@ def _set_item(self, key, value):
                 
                     def found_balance(self, data):
                         event = json.loads(data.decode())
                -        #logger.debug("XBMC receiving: {0}".format(event))
                +        logger.debug("XBMC receiving: {0}".format(event))
                         if 'id' in event:
                             if event['id'] == self._rid:
                                 self._rid = None
                diff --git a/xbmc/plugin.yaml b/xbmc/plugin.yaml
                new file mode 100755
                index 000000000..5ae0b65eb
                --- /dev/null
                +++ b/xbmc/plugin.yaml
                @@ -0,0 +1,26 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Anbindung von XBMC v12 (Frodo) oder neuer'
                +        en: ''
                +    maintainer: ggf. cmalo (mknx)
                +    tester: onkelandy
                +    keywords: mediacenter
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: XBMC                # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/xiaomi/plugin.yaml b/xiaomi/plugin.yaml
                new file mode 100755
                index 000000000..6afe8e658
                --- /dev/null
                +++ b/xiaomi/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Auslesen von Xiaomi Mi Flora Pflanzensensoren, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: psilo909
                +    tester: Sandman60
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +    support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1027133-plugin-xiaomi-mi-plant-flowers-tester-light-monitor
                +
                +    version: 1.3.0.1               # Plugin version
                +    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: True           # plugin supports multi instance
                +    classname: Xiaomi              # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/xmpp/__init__.py b/xmpp/__init__.py
                old mode 100644
                new mode 100755
                diff --git a/xmpp/plugin.yaml b/xmpp/plugin.yaml
                new file mode 100755
                index 000000000..65ca76e83
                --- /dev/null
                +++ b/xmpp/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the classic-plugin
                +plugin:
                +    # Global plugin attributes
                +    type: protocol                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Unterstützung des Extensible Messaging and Presence Protocol (XMPP). Unterstützt z.Zt. nur das Senden von Nachrichten'
                +        en: ''
                +    maintainer: '? (Skender Haxhimolla)'
                +#    tester: efgh                   # Who tests this plugin?
                +#    keywords: kwd1 kwd2            # keywords, where applicable
                +#    documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md        # url of documentation (wiki) page
                +
                +# Following entries are for Smart-Plugins:
                +#    version: 1.3.3                 # Plugin version
                +#    sh_minversion: 1.3             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +#    multi_instance: False
                +    classname: XMPP                # class containing the plugin
                +
                +#parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +#item_attributes:
                +    # Definition of item attributes defined by this plugin
                +    
                diff --git a/yamaha/plugin.yaml b/yamaha/plugin.yaml
                new file mode 100755
                index 000000000..f4fa2662f
                --- /dev/null
                +++ b/yamaha/plugin.yaml
                @@ -0,0 +1,25 @@
                +# Metadata for the Smart-Plugin
                +plugin:
                +    # Global plugin attributes
                +    type: interface                 # plugin type (gateway, interface, protocol, system, web)
                +    description:
                +        de: 'Plugin um Yamaha RX-V und RX-S Receiver zu kontrollieren, **seit SmartHomeNG v1.3**'
                +        en: ''
                +    maintainer: rthill
                +    tester: Sandman60
                +#    keywords: iot xyz
                +#    documentation: https://github.com/smarthomeNG/smarthome/wiki/CLI-Plugin        # url of documentation (wiki) page
                +#    support: https://knx-user-forum.de/forum/supportforen/smarthome-py
                +
                +    version: 1.0.0                 # Plugin version
                +    sh_minversion: 1.1             # minimum shNG version to use this plugin
                +#    sh_maxversion:                 # maximum shNG version to use this plugin (leave empty if latest)
                +    multi_instance: False          # plugin supports multi instance
                +    classname: Yamaha              # class containing the plugin
                +
                +parameters:
                +    # Definition of parameters to be configured in etc/plugin.yaml
                +    
                +item_attributes:
                +    # Definition of item attributes defined by this plugin
                +